made a copy

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/tags/DailyTag_20060529@418 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/edk2/EdkFatBinPkg/EdkFatBinPkg.spd b/edk2/EdkFatBinPkg/EdkFatBinPkg.spd
new file mode 100644
index 0000000..f53b697
--- /dev/null
+++ b/edk2/EdkFatBinPkg/EdkFatBinPkg.spd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <SpdHeader>

+    <PackageName>EdkFatBinPkg</PackageName>

+    <Guid>0fd7197b-9bde-44fe-a7e4-d2177a9922e5</Guid>

+    <Version>0.3</Version>

+    <Abstract>This is the Binary Package for the FAT dirver</Abstract>

+    <Description>This package provides FAT drivers which are not licensed under BSD.</Description>

+    <Copyright>Copyright (c) 2004,  Intel Corporation.</Copyright>

+    <License>

+      All rights reserved.

+      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.

+    </License>

+    <Created>2006-03-05 09:49</Created>

+    <Updated>2006-03-19 16:18</Updated>

+    <URL>http://www.TianoCore.org</URL>

+    <PackageType>BINARY</PackageType>

+    <ReadOnly>true</ReadOnly>

+    <RePackage>false</RePackage>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </SpdHeader>

+  <MsaFiles>

+    <MsaFile>

+      <Filename>Fat.msa</Filename>

+    </MsaFile>

+  </MsaFiles>

+</PackageSurfaceArea>

diff --git a/edk2/EdkFatBinPkg/Fat.mbd b/edk2/EdkFatBinPkg/Fat.mbd
new file mode 100644
index 0000000..ab6d270
--- /dev/null
+++ b/edk2/EdkFatBinPkg/Fat.mbd
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Fat</BaseName>

+    <Guid>5058F21C-BC34-11d4-BD18-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Description>This is the FAT 32 EFI/Tiano Driver

+</Description>

+    <Copyright>Copyright 2004, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 20:56</Created>

+    <Modified>2006-03-19 16:17</Modified>

+  </MbdHeader>

+  <BuildOptions>

+    <Option>copy ${SOURCE_DIR}\${PROCESSOR}\Fat.FFS ${BIN_DIR}\5058F21C-BC34-11d4-BD18-0080C73C8881-Fat.DXE  /y</Option>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkFatBinPkg/Fat.msa b/edk2/EdkFatBinPkg/Fat.msa
new file mode 100644
index 0000000..403f468
--- /dev/null
+++ b/edk2/EdkFatBinPkg/Fat.msa
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Fat</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>5058F21C-BC34-11d4-BD18-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Abstract>Make a FFS section for an FV that contains the FAT driver.*.FFS files are compressed FFS sections.</Abstract>

+    <Description>This is the FAT 32 EFI/Tiano Driver</Description>

+    <Copyright>Copyright 2004, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 20:56</Created>

+    <Updated>2006-03-19 16:17</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename Path="Ia32" FileType="FFS">Fat.FFS</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename Path="Ipf" FileType="FFS">Fat.FFS</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename Path="X64" FileType="FFS">Fat.FFS</Filename>

+    </Arch>

+  </SourceFiles>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <BuildOptions>

+    <Option>BUILD_TYPE=CUSTOM_BUILD</Option>

+  </BuildOptions>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkFatBinPkg/Fat_build.xml b/edk2/EdkFatBinPkg/Fat_build.xml
new file mode 100644
index 0000000..e99c13f
--- /dev/null
+++ b/edk2/EdkFatBinPkg/Fat_build.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="Fat" default="main" basedir="." >

+  <!-- Apply external ANT task -->

+  <taskdef resource="frameworktasks.tasks" /> 

+  <taskdef resource="cpptasks.tasks" /> 

+  <typedef resource="cpptasks.types" /> 

+  <taskdef resource="net/sf/antcontrib/antlib.xml" />

+  <property environment="env" />

+  <!-- All Properties --> 

+  <property name="BASE_NAME" value="Fat" /> 

+  

+  <!-- Default target --> 

+  <target name="main" depends="libraries, sourcefiles, sections, output" /> 

+  <!-- Compile all dependency Library instances. --> 

+  <target name="libraries" />

+

+  <target name="sourcefiles" />

+  

+  <target name="sections" />

+

+  <target name="output">

+    <copy file="${MODULE_DIR}\${ARCH}\${BASE_NAME}.FFS" 

+      tofile="${BIN_DIR}\${FILE_GUID}-${BASE_NAME}.DXE" />

+  </target>

+    

+</project>

diff --git a/edk2/EdkFatBinPkg/Ia32/Fat.FFS b/edk2/EdkFatBinPkg/Ia32/Fat.FFS
new file mode 100644
index 0000000..ccb9b66
--- /dev/null
+++ b/edk2/EdkFatBinPkg/Ia32/Fat.FFS
Binary files differ
diff --git a/edk2/EdkFatBinPkg/Ipf/Fat.FFS b/edk2/EdkFatBinPkg/Ipf/Fat.FFS
new file mode 100644
index 0000000..5989987
--- /dev/null
+++ b/edk2/EdkFatBinPkg/Ipf/Fat.FFS
Binary files differ
diff --git a/edk2/EdkFatBinPkg/X64/Fat.FFS b/edk2/EdkFatBinPkg/X64/Fat.FFS
new file mode 100644
index 0000000..fa76edc
--- /dev/null
+++ b/edk2/EdkFatBinPkg/X64/Fat.FFS
Binary files differ
diff --git a/edk2/EdkFatBinPkg/build.xml b/edk2/EdkFatBinPkg/build.xml
new file mode 100644
index 0000000..d26c5fd
--- /dev/null
+++ b/edk2/EdkFatBinPkg/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Fat"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="."/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Fat">

+      <GenBuild baseName="Fat" mbdFilename="${MODULE_DIR}/Fat.mbd" msaFilename="${MODULE_DIR}/Fat.msa"/>

+   </target>

+   <target depends="Fat_clean" name="clean"/>

+   <target depends="Fat_cleanall" name="cleanall"/>

+   <target name="Fat_clean">

+      <OutputDirSetup baseName="Fat" mbdFilename="${MODULE_DIR}/Fat.mbd" msaFilename="${MODULE_DIR}/Fat.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Fat_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Fat_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Fat_cleanall">

+      <OutputDirSetup baseName="Fat" mbdFilename="${MODULE_DIR}/Fat.mbd" msaFilename="${MODULE_DIR}/Fat.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Fat_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Fat_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Fat*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkFatBinPkg/genbuildfile.xml b/edk2/EdkFatBinPkg/genbuildfile.xml
new file mode 100644
index 0000000..4b60c0c
--- /dev/null
+++ b/edk2/EdkFatBinPkg/genbuildfile.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="workspace" basedir=".">

+  <taskdef resource="GenBuild.tasks" />

+  

+  <target name="workspace">

+    <bf recursive="true" />

+  </target>

+</project>

diff --git a/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.c b/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.c
new file mode 100644
index 0000000..f3eda07
--- /dev/null
+++ b/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.c
@@ -0,0 +1,47 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  HelloWorld.c

+

+Abstract:

+  

+  This driver supports platform security service

+

+--*/

+

+VOID

+Print (

+  IN CONST CHAR16  *Format,

+  ...

+  )

+{

+  CHAR16  PrintBuffer[0x100];

+  VA_LIST Marker;

+

+  VA_START (Marker, Format);

+  UnicodeVSPrint (PrintBuffer, sizeof (PrintBuffer), Format, Marker);

+  gST->ConOut->OutputString (gST->ConOut, PrintBuffer);

+  return;

+}

+

+EFI_STATUS

+EFIAPI

+UefiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+

+{

+  Print ((CHAR16 *)L"UEFI Hello World!\n");

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.mbd b/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.mbd
new file mode 100644
index 0000000..6d44bac
--- /dev/null
+++ b/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>HelloWorld</BaseName>

+    <Guid>6987936E-ED34-44db-AE97-1FA5E4ED2116</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-20 20:41</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDebugLibStdErr</Library>

+    <Library>BasePrintLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+    <Option>TARGET_BS_DRIVER=HelloWorld</Option>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.msa b/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.msa
new file mode 100644
index 0000000..a9950a6
--- /dev/null
+++ b/edk2/EdkModulePkg/Application/HelloWorld/HelloWorld.msa
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>HelloWorld</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>APPLICATION</ComponentType>

+    <Guid>6987936E-ED34-44db-AE97-1FA5E4ED2116</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for SecurityStub module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-20 20:41</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>HelloWorld.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>UefiMain</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Application/HelloWorld/build.xml b/edk2/EdkModulePkg/Application/HelloWorld/build.xml
new file mode 100644
index 0000000..19519f8
--- /dev/null
+++ b/edk2/EdkModulePkg/Application/HelloWorld/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="HelloWorld"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Application/HelloWorld"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="HelloWorld">

+      <GenBuild baseName="HelloWorld" mbdFilename="${MODULE_DIR}/HelloWorld.mbd" msaFilename="${MODULE_DIR}/HelloWorld.msa"/>

+   </target>

+   <target depends="HelloWorld_clean" name="clean"/>

+   <target depends="HelloWorld_cleanall" name="cleanall"/>

+   <target name="HelloWorld_clean">

+      <OutputDirSetup baseName="HelloWorld" mbdFilename="${MODULE_DIR}/HelloWorld.mbd" msaFilename="${MODULE_DIR}/HelloWorld.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/HelloWorld_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/HelloWorld_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="HelloWorld_cleanall">

+      <OutputDirSetup baseName="HelloWorld" mbdFilename="${MODULE_DIR}/HelloWorld.mbd" msaFilename="${MODULE_DIR}/HelloWorld.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/HelloWorld_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/HelloWorld_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**HelloWorld*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.c b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.c
new file mode 100644
index 0000000..6fe81d1
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.c
@@ -0,0 +1,2226 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    AtapiPassThru.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#include "AtapiPassThru.h"

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  );

+

+//

+// IDE registers' fixed address

+//

+static IDE_BASE_REGISTERS   gAtapiIoPortRegisters[2] = {

+  { 0x1f0, { 0x1f1 }, 0x1f2, 0x1f3, 0x1f4, 0x1f5, 0x1f6, { 0x1f7 }, { 0x3f6 }, 0x3f7, 0 },

+  { 0x170, { 0x171 }, 0x172, 0x173, 0x174, 0x175, 0x176, { 0x177 }, { 0x376 }, 0x377, 0 } 

+};

+

+static SCSI_COMMAND_SET     gEndTable = { 0xff, 0xff };

+

+//

+// This table contains all the supported ATAPI commands.

+//

+static SCSI_COMMAND_SET     gSupportedATAPICommands[] = {

+  { OP_INQUIRY,                     DataIn  },

+  { OP_LOAD_UNLOAD_CD,              NoData  },

+  { OP_MECHANISM_STATUS,            DataIn  },

+  { OP_MODE_SELECT_10,              DataOut },

+  { OP_MODE_SENSE_10,               DataIn  },

+  { OP_PAUSE_RESUME,                NoData  },

+  { OP_PLAY_AUDIO_10,               DataIn  },

+  { OP_PLAY_AUDIO_MSF,              DataIn  },

+  { OP_PLAY_CD,                     DataIn  },

+  { OP_PLAY_CD_MSF,                 DataIn  },

+  { OP_PREVENT_ALLOW_MEDIUM_REMOVAL,NoData  },

+  { OP_READ_10,                     DataIn  },

+  { OP_READ_12,                     DataIn  },

+  { OP_READ_CAPACITY,               DataIn  },

+  { OP_READ_CD,                     DataIn  },

+  { OP_READ_CD_MSF,                 DataIn  },

+  { OP_READ_HEADER,                 DataIn  },

+  { OP_READ_SUB_CHANNEL,            DataIn  },

+  { OP_READ_TOC,                    DataIn  },

+  { OP_REQUEST_SENSE,               DataIn  },

+  { OP_SCAN,                        NoData  },

+  { OP_SEEK_10,                     NoData  },

+  { OP_SET_CD_SPEED,                DataOut },

+  { OP_STOPPLAY_SCAN,               NoData  },

+  { OP_START_STOP_UNIT,             NoData  },

+  { OP_TEST_UNIT_READY,             NoData  },

+  { OP_FORMAT_UNIT,                 DataOut },

+  { OP_READ_FORMAT_CAPACITIES,      DataIn  },

+  { OP_VERIFY,                      DataOut },

+  { OP_WRITE_10,                    DataOut },

+  { OP_WRITE_12,                    DataOut },

+  { OP_WRITE_AND_VERIFY,            DataOut },

+  { 0xff,                           0xff    } 

+};

+

+static CHAR16               *gControllerNameString  = (CHAR16 *) L"ATAPI Controller";

+static CHAR16               *gAtapiChannelString    = (CHAR16 *) L"ATAPI Channel";

+

+EFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding = {

+  AtapiScsiPassThruDriverBindingSupported,

+  AtapiScsiPassThruDriverBindingStart,

+  AtapiScsiPassThruDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+    Supported.

+    

+  Arguments:

+    (Standard DriverBinding Protocol Supported() function)

+    

+  Returns:

+    EFI_STATUS

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  PCI_TYPE00          Pci;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Use the PCI I/O Protocol to see if Controller is a IDE Controller that

+  // can be managed by this driver.  Read the PCI Configuration Header

+  // for this device.

+  //

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint32,

+                        0,

+                        sizeof (Pci) / sizeof (UINT32),

+                        &Pci

+                        );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Pci.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE || Pci.Hdr.ClassCode[1] != PCI_CLASS_IDE) {

+

+    Status = EFI_UNSUPPORTED;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+    Create handles for IDE channels specified by RemainingDevicePath.

+    Install SCSI Pass Thru Protocol onto each created handle.

+  

+  Arguments:

+    (Standard DriverBinding Protocol Start() function)

+    

+  Returns:

+    EFI_STATUS

+    

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  PciIo = NULL;

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciIo->Attributes (

+                    PciIo,

+                    EfiPciIoAttributeOperationEnable,

+                    EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,

+                    NULL

+                    );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  //

+  // Create SCSI Pass Thru instance for the IDE channel.

+  //

+  Status = RegisterAtapiScsiPassThru (This, Controller, PciIo);

+

+Done:

+  if (EFI_ERROR (Status)) {

+    if (PciIo) {

+      PciIo->Attributes (

+              PciIo,

+              EfiPciIoAttributeOperationDisable,

+              EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,

+              NULL

+              );

+    }

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+  

+  Routine Description:

+    Stop.

+  

+  Arguments:

+    (Standard DriverBinding Protocol Stop() function)

+  

+  Returns:

+    EFI_STATUS

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                  Status;

+  EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiScsiPassThruProtocolGuid,

+                  (VOID **) &ScsiPassThru,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (ScsiPassThru);

+

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiScsiPassThruProtocolGuid,

+                  &AtapiScsiPrivate->ScsiPassThru

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Release Pci Io protocol on the controller handle.

+  //

+  AtapiScsiPrivate->PciIo->Attributes (

+                            AtapiScsiPrivate->PciIo,

+                            EfiPciIoAttributeOperationDisable,

+                            EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,

+                            NULL

+                            );

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->FreePool (AtapiScsiPrivate);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RegisterAtapiScsiPassThru (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                  Controller,

+  IN  EFI_PCI_IO_PROTOCOL         *PciIo

+  )

+/*++

+  

+  Routine Description:

+    Attaches SCSI Pass Thru Protocol for specified IDE channel.

+    

+  Arguments:

+    Controller:       Parent device handle to the IDE channel.    

+    PciIo:            PCI I/O protocol attached on the "Controller".                        

+  

+  Returns:

+    Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    PciIo - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  EFI_STATUS                Status;

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;

+  UINT64                    Attributes;

+

+  AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));

+  if (AtapiScsiPrivate == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Attributes = EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;

+  CopyMem (AtapiScsiPrivate->ChannelName, gAtapiChannelString, sizeof (gAtapiChannelString));

+

+  //

+  // Enable channel

+  //

+  PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSet, Attributes, NULL);

+

+  AtapiScsiPrivate->Signature = ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE;

+  AtapiScsiPrivate->Handle    = Controller;

+

+  //

+  // will reset the IoPort inside each API function.

+  //

+  AtapiScsiPrivate->IoPort  = gAtapiIoPortRegisters;

+  AtapiScsiPrivate->PciIo   = PciIo;

+

+  //

+  // initialize SCSI Pass Thru Protocol interface

+  //

+  AtapiScsiPrivate->ScsiPassThru.Mode             = &AtapiScsiPrivate->ScsiPassThruMode;

+  AtapiScsiPrivate->ScsiPassThru.PassThru         = AtapiScsiPassThruFunction;

+  AtapiScsiPrivate->ScsiPassThru.GetNextDevice    = AtapiScsiPassThruGetNextDevice;

+  AtapiScsiPrivate->ScsiPassThru.BuildDevicePath  = AtapiScsiPassThruBuildDevicePath;

+  AtapiScsiPrivate->ScsiPassThru.GetTargetLun     = AtapiScsiPassThruGetTargetLun;

+  AtapiScsiPrivate->ScsiPassThru.ResetChannel     = AtapiScsiPassThruResetChannel;

+  AtapiScsiPrivate->ScsiPassThru.ResetTarget      = AtapiScsiPassThruResetTarget;

+

+  //

+  // Set Mode

+  //

+  CopyMem (AtapiScsiPrivate->ControllerName, gControllerNameString, sizeof (gControllerNameString));

+

+  AtapiScsiPrivate->ScsiPassThruMode.ControllerName = AtapiScsiPrivate->ControllerName;

+  AtapiScsiPrivate->ScsiPassThruMode.ChannelName    = AtapiScsiPrivate->ChannelName;

+  AtapiScsiPrivate->ScsiPassThruMode.AdapterId      = 4;

+  //

+  // non-RAID SCSI controllers should set both physical and logical attributes

+  //

+  AtapiScsiPrivate->ScsiPassThruMode.Attributes = EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | 

+                                                  EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;

+  AtapiScsiPrivate->ScsiPassThruMode.IoAlign = 0;

+

+  //

+  // Initialize the LatestTargetId to 0xFFFFFFFF (for the GetNextDevice() call).

+  //

+  AtapiScsiPrivate->LatestTargetId  = 0xFFFFFFFF;

+  AtapiScsiPrivate->LatestLun       = 0;

+

+  Status = gBS->InstallProtocolInterface (

+                  &Controller,

+                  &gEfiScsiPassThruProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &AtapiScsiPrivate->ScsiPassThru

+                  );

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruFunction (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,

+  IN UINT32                                             Target,

+  IN UINT64                                             Lun,

+  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,

+  IN EFI_EVENT                                          Event OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.

+  

+  Arguments:

+    This:     The EFI_SCSI_PASS_THRU_PROTOCOL instance.

+    Target:   The Target ID of the ATAPI device to send the SCSI 

+              Request Packet. To ATAPI devices attached on an IDE

+              Channel, Target ID 0 indicates Master device;Target

+              ID 1 indicates Slave device.

+    Lun:      The LUN of the ATAPI device to send the SCSI Request

+              Packet. To the ATAPI device, Lun is always 0.

+    Packet:   The SCSI Request Packet to send to the ATAPI device 

+              specified by Target and Lun.

+    Event:    If non-blocking I/O is not supported then Event is ignored, 

+              and blocking I/O is performed.

+              If Event is NULL, then blocking I/O is performed.

+              If Event is not NULL and non blocking I/O is supported, 

+              then non-blocking I/O is performed, and Event will be signaled 

+              when the SCSI Request Packet completes.      

+    

+  Returns:  

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;

+  EFI_STATUS                Status;

+

+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);

+

+  //

+  // Target is not allowed beyond MAX_TARGET_ID

+  //

+  if (Target > MAX_TARGET_ID) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // check the data fields in Packet parameter.

+  //

+  Status = CheckSCSIRequestPacket (Packet);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // If Request Packet targets at the IDE channel itself,

+  // do nothing.

+  //

+  if (Target == This->Mode->AdapterId) {

+    Packet->TransferLength = 0;

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // According to Target ID, reset the Atapi I/O Register mapping

+  // (Target Id in [0,1] area, using gAtapiIoPortRegisters[0],

+  //  Target Id in [2,3] area, using gAtapiIoPortRegisters[1]

+  //

+  if ((Target / 2) == 0) {

+    AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[0];

+  } else {

+    AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[1];

+  }

+  

+  //

+  // the ATAPI SCSI interface does not support non-blocking I/O

+  // ignore the Event parameter

+  //

+  // Performs blocking I/O.

+  //

+  Status = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, Packet);

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruGetNextDevice (

+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN OUT UINT32                      *Target,

+  IN OUT UINT64                      *Lun

+  )

+/*++

+

+  Routine Description:

+    Used to retrieve the list of legal Target IDs for SCSI devices 

+    on a SCSI channel.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    Target                - On input, a pointer to the Target ID of a SCSI 

+                            device present on the SCSI channel.  On output, 

+                            a pointer to the Target ID of the next SCSI device

+                             present on a SCSI channel.  An input value of 

+                             0xFFFFFFFF retrieves the Target ID of the first 

+                             SCSI device present on a SCSI channel.

+    Lun                   - On input, a pointer to the LUN of a SCSI device

+                            present on the SCSI channel. On output, a pointer

+                            to the LUN of the next SCSI device present on 

+                            a SCSI channel.

+    

+  Returns:

+    EFI_SUCCESS           - The Target ID and Lun of the next SCSI device 

+                            on the SCSI channel was returned in Target and Lun.

+    EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.

+    EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not

+                            returned on a previous call to GetNextDevice().

+--*/

+{

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;

+

+  //

+  // Retrieve Device Private Data Structure.

+  //

+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);

+

+  //

+  // Check whether Target is valid.

+  //

+  if (Target == NULL || Lun == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((*Target != 0xFFFFFFFF) &&

+      ((*Target != AtapiScsiPrivate->LatestTargetId) ||

+      (*Lun != AtapiScsiPrivate->LatestLun))) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (*Target == MAX_TARGET_ID) {

+    return EFI_NOT_FOUND;

+  }

+

+  if (*Target == 0xFFFFFFFF) {

+    *Target = 0;

+  } else {

+    *Target = AtapiScsiPrivate->LatestTargetId + 1;

+  }

+

+  *Lun = 0;

+

+  //

+  // Update the LatestTargetId.

+  //

+  AtapiScsiPrivate->LatestTargetId  = *Target;

+  AtapiScsiPrivate->LatestLun       = *Lun;

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruBuildDevicePath (

+  IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN     UINT32                         Target,

+  IN     UINT64                         Lun,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath

+  )

+/*++

+

+  Routine Description:

+    Used to allocate and build a device path node for a SCSI device 

+    on a SCSI channel. Would not build device path for a SCSI Host Controller.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    Target                - The Target ID of the SCSI device for which

+                            a device path node is to be allocated and built.

+    Lun                   - The LUN of the SCSI device for which a device 

+                            path node is to be allocated and built.

+    DevicePath            - A pointer to a single device path node that 

+                            describes the SCSI device specified by 

+                            Target and Lun. This function is responsible 

+                            for allocating the buffer DevicePath with the boot

+                            service AllocatePool().  It is the caller's 

+                            responsibility to free DevicePath when the caller

+                            is finished with DevicePath.    

+  Returns:

+    EFI_SUCCESS           - The device path node that describes the SCSI device

+                            specified by Target and Lun was allocated and 

+                            returned in DevicePath.

+    EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does

+                            not exist on the SCSI channel.

+    EFI_INVALID_PARAMETER - DevicePath is NULL.

+    EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate 

+                            DevicePath.

+--*/

+{

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;

+  EFI_DEV_PATH              *Node;

+

+  //

+  // Retrieve Device Private Data Structure.

+  //

+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);

+

+  //

+  // Validate parameters passed in.

+  //

+  

+  if (DevicePath == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // can not build device path for the SCSI Host Controller.

+  //

+  if ((Target > (MAX_TARGET_ID - 1)) || (Lun != 0)) {

+    return EFI_NOT_FOUND;

+  }

+

+  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));

+  if (Node == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;

+  Node->DevPath.SubType = MSG_ATAPI_DP;

+  SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));

+

+  Node->Atapi.PrimarySecondary  = (UINT8) (Target / 2);

+  Node->Atapi.SlaveMaster       = (UINT8) (Target % 2);

+  Node->Atapi.Lun               = (UINT16) Lun;

+

+  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruGetTargetLun (

+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,

+  OUT UINT32                         *Target,

+  OUT UINT64                         *Lun

+  )

+/*++

+

+  Routine Description:

+    Used to translate a device path node to a Target ID and LUN.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    DevicePath            - A pointer to the device path node that 

+                            describes a SCSI device on the SCSI channel.

+    Target                - A pointer to the Target ID of a SCSI device 

+                            on the SCSI channel. 

+    Lun                   - A pointer to the LUN of a SCSI device on 

+                            the SCSI channel.    

+  Returns:

+    EFI_SUCCESS           - DevicePath was successfully translated to a 

+                            Target ID and LUN, and they were returned 

+                            in Target and Lun.

+    EFI_INVALID_PARAMETER - DevicePath is NULL.

+    EFI_INVALID_PARAMETER - Target is NULL.

+    EFI_INVALID_PARAMETER - Lun is NULL.

+    EFI_UNSUPPORTED       - This driver does not support the device path 

+                            node type in DevicePath.

+    EFI_NOT_FOUND         - A valid translation from DevicePath to a 

+                            Target ID and LUN does not exist.

+--*/

+{

+  EFI_DEV_PATH  *Node;

+

+  //

+  // Validate parameters passed in.

+  //

+  if (DevicePath == NULL || Target == NULL || Lun == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH

+  //

+  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||

+      (DevicePath->SubType != MSG_ATAPI_DP) ||

+      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Node    = (EFI_DEV_PATH *) DevicePath;

+

+  *Target = Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster;

+  *Lun    = Node->Atapi.Lun;

+

+  if (*Target > (MAX_TARGET_ID - 1) || *Lun != 0) {

+    return EFI_NOT_FOUND;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruResetChannel (

+  IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This

+  )

+/*++

+

+  Routine Description:

+    Resets a SCSI channel.This operation resets all the 

+    SCSI devices connected to the SCSI channel.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    

+  Returns:

+    EFI_SUCCESS           - The SCSI channel was reset.

+    EFI_UNSUPPORTED       - The SCSI channel does not support 

+                            a channel reset operation.

+    EFI_DEVICE_ERROR      - A device error occurred while 

+                            attempting to reset the SCSI channel.

+    EFI_TIMEOUT           - A timeout occurred while attempting 

+                            to reset the SCSI channel.

+--*/

+{

+  UINT8                     DeviceControlValue;

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;

+  UINT8                     Index;

+

+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);

+

+  //

+  // Reset both Primary channel and Secondary channel.

+  // so, the IoPort pointer must point to the right I/O Register group

+  //

+  for (Index = 0; Index < 2; Index++) {

+    //

+    // Reset

+    //

+    AtapiScsiPrivate->IoPort  = &gAtapiIoPortRegisters[Index];

+

+    DeviceControlValue        = 0;

+    //

+    // set SRST bit to initiate soft reset

+    //

+    DeviceControlValue |= SRST;

+    //

+    // disable Interrupt

+    //

+    DeviceControlValue |= bit (1);

+    WritePortB (

+      AtapiScsiPrivate->PciIo,

+      AtapiScsiPrivate->IoPort->Alt.DeviceControl,

+      DeviceControlValue

+      );

+

+    //

+    // Wait 10us

+    //

+    gBS->Stall (10);

+

+    //

+    // Clear SRST bit

+    // 0xfb:1111,1011

+    //

+    DeviceControlValue &= 0xfb;

+    

+    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);

+

+    //

+    // slave device needs at most 31s to clear BSY

+    //

+    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000) == EFI_TIMEOUT) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruResetTarget (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN UINT32                         Target,

+  IN UINT64                         Lun

+  )

+/*++

+

+  Routine Description:

+    Resets a SCSI device that is connected to a SCSI channel.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    Target                - The Target ID of the SCSI device to reset. 

+    Lun                   - The LUN of the SCSI device to reset.

+        

+  Returns:

+    EFI_SUCCESS           - The SCSI device specified by Target and 

+                            Lun was reset.

+    EFI_UNSUPPORTED       - The SCSI channel does not support a target

+                            reset operation.

+    EFI_INVALID_PARAMETER - Target or Lun are invalid.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting 

+                            to reset the SCSI device specified by Target 

+                            and Lun.

+    EFI_TIMEOUT           - A timeout occurred while attempting to reset 

+                            the SCSI device specified by Target and Lun.

+--*/

+{

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;

+  UINT8                     Command;

+  UINT8                     DeviceSelect;

+

+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);

+

+  if (Target > MAX_TARGET_ID) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Directly return EFI_SUCCESS if want to reset the host controller

+  //

+  if (Target == This->Mode->AdapterId) {

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // According to Target ID, reset the Atapi I/O Register mapping

+  // (Target Id in [0,1] area, using gAtapiIoPortRegisters[0],

+  //  Target Id in [2,3] area, using gAtapiIoPortRegisters[1]

+  //

+  if ((Target / 2) == 0) {

+    AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[0];

+  } else {

+    AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[1];

+  }

+  

+  //

+  // for ATAPI device, no need to wait DRDY ready after device selecting.

+  //

+  // bit7 and bit5 are both set to 1 for backward compatibility

+  //

+  DeviceSelect = (UINT8) (((bit (7) | bit (5)) | (Target << 4)));

+  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);

+

+  Command = ATAPI_SOFT_RESET_CMD;

+  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);

+

+  //

+  // BSY clear is the only status return to the host by the device

+  // when reset is complete.

+  // slave device needs at most 31s to clear BSY

+  //

+  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000))) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // stall 5 seconds to make the device status stable

+  //

+  gBS->Stall (5000000);

+

+  return EFI_SUCCESS;

+}

+

+    

+EFI_STATUS

+CheckSCSIRequestPacket (

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet

+  )

+/*++

+  

+  Checks the parameters in the SCSI Request Packet to make sure

+  they are valid for a SCSI Pass Thru request.

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    Packet - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  if (Packet == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!ValidCdbLength (Packet->CdbLength)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Packet->Cdb == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // Checks whether the request command is supported.

+  //

+  if (!IsCommandValid (Packet)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsCommandValid (

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet

+  )

+/*++

+  

+  Checks the requested SCSI command: 

+    Is it supported by this driver?

+    Is the Data transfer direction reasonable?

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    Packet - add argument and description to function comment

+{

+  UINT8 Index;

+  UINT8 *OpCode;

+

+  OpCode = (UINT8 *) (Packet->Cdb);

+

+  for (Index = 0; CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)); Index++) {

+

+    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {

+      //

+      // Check whether the requested Command is supported by this driver

+      //

+      if (Packet->DataDirection == DataIn) {

+        //

+        // Check whether the requested data direction conforms to

+        // what it should be.

+        //

+        if (gSupportedATAPICommands[Index].Direction == DataOut) {

+          return FALSE;

+        }

+      }

+

+      if (Packet->DataDirection == DataOut) {

+        //

+        // Check whether the requested data direction conforms to

+        // what it should be.

+        //

+        if (gSupportedATAPICommands[Index].Direction == DataIn) {

+          return FALSE;

+        }

+      }

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+SubmitBlockingIoCommand (

+  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,

+  UINT32                                    Target,

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet

+  )

+/*++

+

+Routine Description:

+    Performs blocking I/O request.

+    

+  Arguments:

+    AtapiScsiPrivate:   Private data structure for the specified channel.

+    Target:             The Target ID of the ATAPI device to send the SCSI 

+                        Request Packet. To ATAPI devices attached on an IDE

+                        Channel, Target ID 0 indicates Master device;Target

+                        ID 1 indicates Slave device.

+    Packet:             The SCSI Request Packet to send to the ATAPI device 

+                        specified by Target.

+  

+  Returns:

+  

+--*/

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+{

+  UINT8       PacketCommand[12];

+  UINT64      TimeoutInMicroSeconds;

+  EFI_STATUS  PacketCommandStatus;

+

+  //

+  // Fill ATAPI Command Packet according to CDB

+  //

+  ZeroMem (&PacketCommand, 12);

+  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);

+

+  //

+  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.

+  //

+  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);

+

+  //

+  // Submit ATAPI Command Packet

+  //

+  PacketCommandStatus = AtapiPacketCommand (

+                          AtapiScsiPrivate,

+                          Target,

+                          PacketCommand,

+                          Packet->DataBuffer,

+                          &(Packet->TransferLength),

+                          Packet->DataDirection,

+                          TimeoutInMicroSeconds

+                          );

+  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {

+    Packet->SenseDataLength = 0;

+    return PacketCommandStatus;

+  }

+  //

+  // Return SenseData if PacketCommandStatus matches

+  // the following return codes.

+  //

+  if ((PacketCommandStatus == EFI_WARN_BUFFER_TOO_SMALL) ||

+      (PacketCommandStatus == EFI_DEVICE_ERROR) ||

+      (PacketCommandStatus == EFI_TIMEOUT)) {

+    

+    //

+    // avoid submit request sense command continuously.

+    //

+    if (PacketCommand[0] == OP_REQUEST_SENSE) {

+      Packet->SenseDataLength = 0;

+      return PacketCommandStatus;

+    }

+

+    RequestSenseCommand (

+      AtapiScsiPrivate,

+      Target,

+      Packet->Timeout,

+      Packet->SenseData,

+      &Packet->SenseDataLength

+      );

+  }

+

+  return PacketCommandStatus;

+}

+

+EFI_STATUS

+RequestSenseCommand (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT32                      Target,

+  UINT64                      Timeout,

+  VOID                        *SenseData,

+  UINT8                       *SenseDataLength

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate  - TODO: add argument description

+  Target            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;

+  UINT8                                   Cdb[12];

+  EFI_STATUS                              Status;

+

+  ZeroMem (&Packet, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 12);

+

+  Cdb[0]                = OP_REQUEST_SENSE;

+  Cdb[4]                = (UINT8) (*SenseDataLength);

+

+  Packet.Timeout        = Timeout;

+  Packet.DataBuffer     = SenseData;

+  Packet.SenseData      = NULL;

+  Packet.Cdb            = Cdb;

+  Packet.TransferLength = *SenseDataLength;

+  Packet.CdbLength      = 12;

+  Packet.DataDirection  = DataIn;

+

+  Status                = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, &Packet);

+  *SenseDataLength      = (UINT8) (Packet.TransferLength);

+  return Status;

+}

+

+EFI_STATUS

+AtapiPacketCommand (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT32                      Target,

+  UINT8                       *PacketCommand,

+  VOID                        *Buffer,

+  UINT32                      *ByteCount,

+  DATA_DIRECTION              Direction,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+

+  Routine Description:

+    Submits ATAPI command packet to the specified ATAPI device.

+    

+  Arguments:

+    AtapiScsiPrivate:   Private data structure for the specified channel.

+    Target:             The Target ID of the ATAPI device to send the SCSI 

+                        Request Packet. To ATAPI devices attached on an IDE

+                        Channel, Target ID 0 indicates Master device;Target

+                        ID 1 indicates Slave device.

+    PacketCommand:      Points to the ATAPI command packet.

+    Buffer:             Points to the transferred data.

+    ByteCount:          When input,indicates the buffer size; when output,

+                        indicates the actually transferred data size.

+    Direction:          Indicates the data transfer direction. 

+    TimeoutInMicroSeconds:

+                        The timeout, in micro second units, to use for the 

+                        execution of this ATAPI command.

+                        A TimeoutInMicroSeconds value of 0 means that 

+                        this function will wait indefinitely for the ATAPI 

+                        command to execute.

+                        If TimeoutInMicroSeconds is greater than zero, then 

+                        this function will return EFI_TIMEOUT if the time 

+                        required to execute the ATAPI command is greater 

+                        than TimeoutInMicroSeconds.

+  

+  Returns:

+

+

+--*/

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    PacketCommand - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    Direction - add argument and description to function comment

+{

+

+  UINT16      *CommandIndex;

+  UINT8       Count;

+  EFI_STATUS  Status;

+

+  //

+  // Set all the command parameters by fill related registers.

+  // Before write to all the following registers, BSY and DRQ must be 0.

+  //

+  Status = StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);

+  if (EFI_ERROR (Status)) {

+    if (Status == EFI_ABORTED) {

+      Status = EFI_DEVICE_ERROR;

+    }

+

+    *ByteCount = 0;

+    return Status;

+  }

+  //

+  // Select device via Device/Head Register.

+  // "Target = 0" indicates device 0; "Target = 1" indicates device 1

+  //

+  WritePortB (

+    AtapiScsiPrivate->PciIo,

+    AtapiScsiPrivate->IoPort->Head,

+    (UINT8) ((Target << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)

+    );

+

+  //

+  // No OVL; No DMA (by setting feature register)

+  //

+  WritePortB (

+    AtapiScsiPrivate->PciIo,

+    AtapiScsiPrivate->IoPort->Reg1.Feature,

+    0x00

+    );

+

+  //

+  // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device

+  // determine how much data should be transfered.

+  //

+  WritePortB (

+    AtapiScsiPrivate->PciIo,

+    AtapiScsiPrivate->IoPort->CylinderLsb,

+    (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)

+    );

+  WritePortB (

+    AtapiScsiPrivate->PciIo,

+    AtapiScsiPrivate->IoPort->CylinderMsb,

+    (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)

+    );

+

+  //

+  //  DEFAULT_CTL:0x0a (0000,1010)

+  //  Disable interrupt

+  //

+  WritePortB (

+    AtapiScsiPrivate->PciIo,

+    AtapiScsiPrivate->IoPort->Alt.DeviceControl,

+    DEFAULT_CTL

+    );

+

+  //

+  // Send Packet command to inform device

+  // that the following data bytes are command packet.

+  //

+  WritePortB (

+    AtapiScsiPrivate->PciIo,

+    AtapiScsiPrivate->IoPort->Reg.Command,

+    PACKET_CMD

+    );

+

+  //

+  // Before data transfer, BSY should be 0 and DRQ should be 1.

+  // if they are not in specified time frame,

+  // retrieve Sense Key from Error Register before return.

+  //

+  Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);

+  if (EFI_ERROR (Status)) {

+    if (Status == EFI_ABORTED) {

+      Status = EFI_DEVICE_ERROR;

+    }

+

+    *ByteCount = 0;

+    return Status;

+  }

+

+  //

+  // Send out command packet

+  //

+  CommandIndex = (UINT16 *) PacketCommand;

+  for (Count = 0; Count < 6; Count++, CommandIndex++) {

+    WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *CommandIndex);

+  }

+

+  //

+  // call AtapiPassThruPioReadWriteData() function to get

+  // requested transfer data form device.

+  //

+  return AtapiPassThruPioReadWriteData (

+          AtapiScsiPrivate,

+          Buffer,

+          ByteCount,

+          Direction,

+          TimeoutInMicroSeconds

+          );

+}

+

+EFI_STATUS

+AtapiPassThruPioReadWriteData (

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,

+  UINT16                    *Buffer,

+  UINT32                    *ByteCount,

+  DATA_DIRECTION            Direction,

+  UINT64                    TimeoutInMicroSeconds

+  )

+/*++

+

+  Routine Description:

+    Performs data transfer between ATAPI device and host after the

+    ATAPI command packet is sent.

+    

+  Arguments:

+    AtapiScsiPrivate:   Private data structure for the specified channel.    

+    Buffer:             Points to the transferred data.

+    ByteCount:          When input,indicates the buffer size; when output,

+                        indicates the actually transferred data size.

+    Direction:          Indicates the data transfer direction. 

+    TimeoutInMicroSeconds:

+                        The timeout, in micro second units, to use for the 

+                        execution of this ATAPI command.

+                        A TimeoutInMicroSeconds value of 0 means that 

+                        this function will wait indefinitely for the ATAPI 

+                        command to execute.

+                        If TimeoutInMicroSeconds is greater than zero, then 

+                        this function will return EFI_TIMEOUT if the time 

+                        required to execute the ATAPI command is greater 

+                        than TimeoutInMicroSeconds.

+

+  Returns:

+

+

+--*/

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    Direction - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_WARN_BUFFER_TOO_SMALL - add return value to function comment

+{

+  UINT32      Index;

+  UINT32      RequiredWordCount;

+  UINT32      ActualWordCount;

+

+  UINT32      WordCount;

+  EFI_STATUS  Status;

+  UINT16      *ptrBuffer;

+

+  Status = EFI_SUCCESS;

+

+  //

+  // Non Data transfer request is also supported.

+  //

+  if (*ByteCount == 0 || Buffer == NULL) {

+    *ByteCount = 0;

+    if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds))) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  ptrBuffer         = Buffer;

+  RequiredWordCount = *ByteCount / 2;

+

+  //

+  // ActuralWordCount means the word count of data really transfered.

+  //

+  ActualWordCount = 0;

+

+  while (ActualWordCount < RequiredWordCount) {

+    //

+    // before each data transfer stream, the host should poll DRQ bit ready,

+    // which indicates device's ready for data transfer .

+    //

+    Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);

+    if (EFI_ERROR (Status)) {

+      *ByteCount = ActualWordCount * 2;

+

+      AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);

+

+      if (ActualWordCount == 0) {

+        return EFI_DEVICE_ERROR;

+      }

+      //

+      // ActualWordCount > 0

+      //

+      if (ActualWordCount < RequiredWordCount) {

+        return EFI_WARN_BUFFER_TOO_SMALL;

+      }

+    }

+    //

+    // get current data transfer size from Cylinder Registers.

+    //

+    WordCount =

+      (

+        (ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderMsb) << 8) |

+        ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderLsb)

+      ) & 0xffff;

+    WordCount /= 2;

+

+    //

+    // perform a series data In/Out.

+    //

+    for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) {

+

+      if (Direction == DataIn) {

+

+        *ptrBuffer = ReadPortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data);

+      } else {

+

+        WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *ptrBuffer);

+      }

+

+      ptrBuffer++;

+

+    }

+  }

+  //

+  // After data transfer is completed, normally, DRQ bit should clear.

+  //

+  StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);

+

+  //

+  // read status register to check whether error happens.

+  //

+  Status      = AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);

+

+  *ByteCount  = ActualWordCount * 2;

+

+  return Status;

+}

+

+

+UINT8

+ReadPortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port

+  )

+/*++

+  Read one byte from a specified I/O port.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    PciIo - add argument and description to function comment

+// TODO:    Port - add argument and description to function comment

+{

+  UINT8 Data;

+

+  Data = 0;

+  PciIo->Io.Read (

+              PciIo,

+              EfiPciIoWidthUint8,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+  return Data;

+}

+

+

+UINT16

+ReadPortW (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port

+  )

+/*++

+  Read one word from a specified I/O port.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    PciIo - add argument and description to function comment

+// TODO:    Port - add argument and description to function comment

+{

+  UINT16  Data;

+

+  Data = 0;

+  PciIo->Io.Read (

+              PciIo,

+              EfiPciIoWidthUint16,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+  return Data;

+}

+

+

+VOID

+WritePortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT8                 Data

+  )

+/*++

+  Write one byte to a specified I/O port.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    PciIo - add argument and description to function comment

+// TODO:    Port - add argument and description to function comment

+// TODO:    Data - add argument and description to function comment

+{

+

+  PciIo->Io.Write (

+              PciIo,

+              EfiPciIoWidthUint8,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+

+}

+

+

+VOID

+WritePortW (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT16                Data

+  )

+/*++

+  Write one word to a specified I/O port.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    PciIo - add argument and description to function comment

+// TODO:    Port - add argument and description to function comment

+// TODO:    Data - add argument and description to function comment

+{

+

+  PciIo->Io.Write (

+              PciIo,

+              EfiPciIoWidthUint16,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+}

+

+EFI_STATUS

+StatusDRQClear (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeoutInMicroSeconds

+  )

+/*++

+  Check whether DRQ is clear in the Status Register. (BSY must also be cleared)

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   StatusRegister;

+  UINT8   ErrRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+

+    StatusRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg.Status

+                      );

+

+    //

+    // wait for BSY == 0 and DRQ == 0

+    //

+    if ((StatusRegister & (DRQ | BSY)) == 0) {

+      break;

+    }

+    //

+    // check whether the command is aborted by the device

+    //

+    if ((StatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg1.Error

+                      );

+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {

+

+        return EFI_ABORTED;

+      }

+    }

+    //

+    //  Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AltStatusDRQClear (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeoutInMicroSeconds

+  )

+/*++

+  Check whether DRQ is clear in the Alternate Status Register. 

+  (BSY must also be cleared).

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   AltStatusRegister;

+  UINT8   ErrRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+

+    AltStatusRegister = ReadPortB (

+                          AtapiScsiPrivate->PciIo,

+                          AtapiScsiPrivate->IoPort->Alt.AltStatus

+                          );

+

+    //

+    // wait for BSY == 0 and DRQ == 0

+    //

+    if ((AltStatusRegister & (DRQ | BSY)) == 0) {

+      break;

+    }

+

+    if ((AltStatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg1.Error

+                      );

+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {

+

+        return EFI_ABORTED;

+      }

+    }

+    //

+    //  Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+StatusDRQReady (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeoutInMicroSeconds

+  )

+/*++

+  Check whether DRQ is ready in the Status Register. (BSY must also be cleared)

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   StatusRegister;

+  UINT8   ErrRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+    //

+    //  read Status Register will clear interrupt

+    //

+    StatusRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg.Status

+                      );

+

+    //

+    //  BSY==0,DRQ==1

+    //

+    if ((StatusRegister & (BSY | DRQ)) == DRQ) {

+      break;

+    }

+

+    if ((StatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg1.Error

+                      );

+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AltStatusDRQReady (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeoutInMicroSeconds

+  )

+/*++

+  Check whether DRQ is ready in the Alternate Status Register. 

+  (BSY must also be cleared)

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   AltStatusRegister;

+  UINT8   ErrRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+    //

+    //  read Status Register will clear interrupt

+    //

+    AltStatusRegister = ReadPortB (

+                          AtapiScsiPrivate->PciIo,

+                          AtapiScsiPrivate->IoPort->Alt.AltStatus

+                          );

+    //

+    //  BSY==0,DRQ==1

+    //

+    if ((AltStatusRegister & (BSY | DRQ)) == DRQ) {

+      break;

+    }

+

+    if ((AltStatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg1.Error

+                      );

+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+StatusWaitForBSYClear (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+  Check whether BSY is clear in the Status Register.

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   StatusRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+

+    StatusRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg.Status

+                      );

+    if ((StatusRegister & BSY) == 0x00) {

+      break;

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AltStatusWaitForBSYClear (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+  Check whether BSY is clear in the Alternate Status Register.

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   AltStatusRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+

+    AltStatusRegister = ReadPortB (

+                          AtapiScsiPrivate->PciIo,

+                          AtapiScsiPrivate->IoPort->Alt.AltStatus

+                          );

+    if ((AltStatusRegister & BSY) == 0x00) {

+      break;

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+StatusDRDYReady (

+  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,

+  UINT64                       TimeoutInMicroSeconds

+  )

+/*++

+  Check whether DRDY is ready in the Status Register. 

+  (BSY must also be cleared)

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   StatusRegister;

+  UINT8   ErrRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+    StatusRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg.Status

+                      );

+    //

+    //  BSY == 0 , DRDY == 1

+    //

+    if ((StatusRegister & (DRDY | BSY)) == DRDY) {

+      break;

+    }

+

+    if ((StatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg1.Error

+                      );

+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+    

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AltStatusDRDYReady (

+  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,

+  UINT64                       TimeoutInMicroSeconds

+  )

+/*++

+  Check whether DRDY is ready in the Alternate Status Register. 

+  (BSY must also be cleared)

+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for

+  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is 

+  elapsed.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    TimeoutInMicroSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Delay;

+  UINT8   AltStatusRegister;

+  UINT8   ErrRegister;

+

+  if (TimeoutInMicroSeconds == 0) {

+    Delay = 2;

+  } else {

+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;

+  }

+

+  do {

+    AltStatusRegister = ReadPortB (

+                          AtapiScsiPrivate->PciIo,

+                          AtapiScsiPrivate->IoPort->Alt.AltStatus

+                          );

+    //

+    //  BSY == 0 , DRDY == 1

+    //

+    if ((AltStatusRegister & (DRDY | BSY)) == DRDY) {

+      break;

+    }

+

+    if ((AltStatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrRegister = ReadPortB (

+                      AtapiScsiPrivate->PciIo,

+                      AtapiScsiPrivate->IoPort->Reg1.Error

+                      );

+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+    //

+    // Loop infinitely if not meeting expected condition

+    //

+    if (TimeoutInMicroSeconds == 0) {

+      Delay = 2;

+    }

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtapiPassThruCheckErrorStatus (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate

+  )

+/*++  

+  Check Error Register for Error Information. 

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    AtapiScsiPrivate - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  UINT8 StatusRegister;

+

+//#ifdef EFI_DEBUG

+

+  UINT8 ErrorRegister;

+

+//#endif

+

+  StatusRegister = ReadPortB (

+                    AtapiScsiPrivate->PciIo,

+                    AtapiScsiPrivate->IoPort->Reg.Status

+                    );

+  DEBUG_CODE (

+

+    if (StatusRegister & DWF) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",

+      StatusRegister)

+      );

+  }

+

+  if (StatusRegister & CORR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",

+      StatusRegister)

+      );

+  }

+

+  if (StatusRegister & ERR) {

+    ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);

+

+    if (ErrorRegister & BBK_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block Detected\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & UNC_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & MC_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & ABRT_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & TK0NF_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & AMNF_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",

+      ErrorRegister)

+      );

+  }

+

+  }

+  );

+

+  if ((StatusRegister & (ERR | DWF | CORR)) == 0) {

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_DEVICE_ERROR;

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.h b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.h
new file mode 100644
index 0000000..d705c65
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.h
@@ -0,0 +1,916 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    AtapiPassThru.h

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#ifndef _APT_H

+#define _APT_H

+

+

+#include <IndustryStandard/pci22.h>

+

+//

+// bit definition

+//

+#define bit(a)        1 << (a)

+

+#define MAX_TARGET_ID 4

+//

+// IDE Registers

+//

+typedef union {

+  UINT16  Command;        /* when write */

+  UINT16  Status;         /* when read */

+} IDE_CMD_OR_STATUS;

+

+typedef union {

+  UINT16  Error;          /* when read */

+  UINT16  Feature;        /* when write */

+} IDE_ERROR_OR_FEATURE;

+

+typedef union {

+  UINT16  AltStatus;      /* when read */

+  UINT16  DeviceControl;  /* when write */

+} IDE_AltStatus_OR_DeviceControl;

+

+//

+// IDE registers set

+//

+typedef struct {

+  UINT16                          Data;

+  IDE_ERROR_OR_FEATURE            Reg1;

+  UINT16                          SectorCount;

+  UINT16                          SectorNumber;

+  UINT16                          CylinderLsb;

+  UINT16                          CylinderMsb;

+  UINT16                          Head;

+  IDE_CMD_OR_STATUS               Reg;

+

+  IDE_AltStatus_OR_DeviceControl  Alt;

+  UINT16                          DriveAddress;

+

+  UINT16                          MasterSlave;

+} IDE_BASE_REGISTERS;

+

+#define ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE  EFI_SIGNATURE_32 ('a', 's', 'p', 't')

+

+typedef struct {

+  UINTN                       Signature;

+

+  EFI_HANDLE                  Handle;

+  EFI_SCSI_PASS_THRU_PROTOCOL ScsiPassThru;

+  EFI_SCSI_PASS_THRU_MODE     ScsiPassThruMode;

+  EFI_PCI_IO_PROTOCOL         *PciIo;

+

+  //

+  // Local Data goes here

+  //

+  IDE_BASE_REGISTERS          *IoPort;

+

+  CHAR16                      ControllerName[100];

+  CHAR16                      ChannelName[100];

+

+  UINT32                      LatestTargetId;

+  UINT64                      LatestLun;

+

+} ATAPI_SCSI_PASS_THRU_DEV;

+

+#define ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS(a) \

+  CR (a, \

+      ATAPI_SCSI_PASS_THRU_DEV, \

+      ScsiPassThru, \

+      ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \

+      )

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gAtapiScsiPassThruDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gAtapiScsiPassThruComponentName;

+

+//

+// ATAPI Command op code

+//

+#define OP_INQUIRY                      0x12

+#define OP_LOAD_UNLOAD_CD               0xa6

+#define OP_MECHANISM_STATUS             0xbd

+#define OP_MODE_SELECT_10               0x55

+#define OP_MODE_SENSE_10                0x5a

+#define OP_PAUSE_RESUME                 0x4b

+#define OP_PLAY_AUDIO_10                0x45

+#define OP_PLAY_AUDIO_MSF               0x47

+#define OP_PLAY_CD                      0xbc

+#define OP_PLAY_CD_MSF                  0xb4

+#define OP_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e

+#define OP_READ_10                      0x28

+#define OP_READ_12                      0xa8

+#define OP_READ_CAPACITY                0x25

+#define OP_READ_CD                      0xbe

+#define OP_READ_CD_MSF                  0xb9

+#define OP_READ_HEADER                  0x44

+#define OP_READ_SUB_CHANNEL             0x42

+#define OP_READ_TOC                     0x43

+#define OP_REQUEST_SENSE                0x03

+#define OP_SCAN                         0xba

+#define OP_SEEK_10                      0x2b

+#define OP_SET_CD_SPEED                 0xbb

+#define OP_STOPPLAY_SCAN                0x4e

+#define OP_START_STOP_UNIT              0x1b

+#define OP_TEST_UNIT_READY              0x00

+

+#define OP_FORMAT_UNIT                  0x04

+#define OP_READ_FORMAT_CAPACITIES       0x23

+#define OP_VERIFY                       0x2f

+#define OP_WRITE_10                     0x2a

+#define OP_WRITE_12                     0xaa

+#define OP_WRITE_AND_VERIFY             0x2e

+

+//

+// ATA Command

+//

+#define ATAPI_SOFT_RESET_CMD  0x08

+

+typedef enum {

+  DataIn  = 0,

+  DataOut = 1,

+  NoData  = 2,

+  End     = 0xff

+} DATA_DIRECTION;

+

+typedef struct {

+  UINT8           OpCode;

+  DATA_DIRECTION  Direction;

+} SCSI_COMMAND_SET;

+

+#define MAX_CHANNEL         2

+

+#define ValidCdbLength(Len) ((Len) == 6 || (Len) == 10 || (Len) == 12) ? 1 : 0

+

+//

+// IDE registers bit definitions

+//

+// ATA Err Reg bitmap

+//

+#define BBK_ERR   bit (7) /* Bad block detected */

+#define UNC_ERR   bit (6) /* Uncorrectable Data */

+#define MC_ERR    bit (5) /* Media Change */

+#define IDNF_ERR  bit (4) /* ID Not Found */

+#define MCR_ERR   bit (3) /* Media Change Requested */

+#define ABRT_ERR  bit (2) /* Aborted Command */

+#define TK0NF_ERR bit (1) /* Track 0 Not Found */

+#define AMNF_ERR  bit (0) /* Address Mark Not Found */

+

+//

+// ATAPI Err Reg bitmap

+//

+#define SENSE_KEY_ERR (bit (7) | bit (6) | bit (5) | bit (4))

+#define EOM_ERR bit (1) /* End of Media Detected */

+#define ILI_ERR bit (0) /* Illegal Length Indication */

+

+//

+// Device/Head Reg

+//

+#define LBA_MODE  bit (6)

+#define DEV       bit (4)

+#define HS3       bit (3)

+#define HS2       bit (2)

+#define HS1       bit (1)

+#define HS0       bit (0)

+#define CHS_MODE  (0)

+#define DRV0      (0)

+#define DRV1      (1)

+#define MST_DRV   DRV0

+#define SLV_DRV   DRV1

+

+//

+// Status Reg

+//

+#define BSY   bit (7) /* Controller Busy */

+#define DRDY  bit (6) /* Drive Ready */

+#define DWF   bit (5) /* Drive Write Fault */

+#define DSC   bit (4) /* Disk Seek Complete */

+#define DRQ   bit (3) /* Data Request */

+#define CORR  bit (2) /* Corrected Data */

+#define IDX   bit (1) /* Index */

+#define ERR   bit (0) /* Error */

+#define CHECK bit (0) /* Check bit for ATAPI Status Reg */

+

+//

+// Device Control Reg

+//

+#define SRST  bit (2) /* Software Reset */

+#define IEN_L bit (1) /* Interrupt Enable #*/

+

+//

+// ATAPI Feature Register

+//

+#define OVERLAP bit (1)

+#define DMA     bit (0)

+

+//

+// ATAPI Interrupt Reason Reson Reg (ATA Sector Count Register)

+//

+#define RELEASE     bit (2)

+#define IO          bit (1)

+#define CoD         bit (0)

+

+#define PACKET_CMD  0xA0

+

+#define DEFAULT_CMD (0xa0)

+//

+// default content of device control register, disable INT

+//

+#define DEFAULT_CTL           (0x0a)

+#define MAX_ATAPI_BYTE_COUNT  (0xfffe)

+

+//

+// function prototype

+//

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruDriverEntryPoint (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+ /*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RegisterAtapiScsiPassThru (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                  Controller,

+  IN  EFI_PCI_IO_PROTOCOL         *PciIo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Controller  - TODO: add argument description

+  PciIo       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruFunction (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,

+  IN UINT32                                             Target,

+  IN UINT64                                             Lun,

+  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,

+  IN EFI_EVENT                                          Event OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Target  - TODO: add argument description

+  Lun     - TODO: add argument description

+  Packet  - TODO: add argument description

+  Event   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruGetNextDevice (

+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN OUT UINT32                      *Target,

+  IN OUT UINT64                      *Lun

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Target  - TODO: add argument description

+  Lun     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruBuildDevicePath (

+  IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN     UINT32                         Target,

+  IN     UINT64                         Lun,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Target      - TODO: add argument description

+  Lun         - TODO: add argument description

+  DevicePath  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruGetTargetLun (

+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,

+  OUT UINT32                         *Target,

+  OUT UINT64                         *Lun

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  DevicePath  - TODO: add argument description

+  Target      - TODO: add argument description

+  Lun         - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruResetChannel (

+  IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruResetTarget (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,

+  IN UINT32                         Target,

+  IN UINT64                         Lun

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Target  - TODO: add argument description

+  Lun     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CheckSCSIRequestPacket (

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Packet  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SubmitBlockingIoCommand (

+  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,

+  UINT32                                    Target,

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate  - TODO: add argument description

+  Target            - TODO: add argument description

+  Packet            - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsCommandValid (

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet

+  )

+ /*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Packet  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RequestSenseCommand (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT32                      Target,

+  UINT64                      Timeout,

+  VOID                        *SenseData,

+  UINT8                       *SenseDataLength

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate  - TODO: add argument description

+  Target            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiPacketCommand (

+  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,

+  UINT32                                    Target,

+  UINT8                                     *PacketCommand,

+  VOID                                      *Buffer,

+  UINT32                                    *ByteCount,

+  DATA_DIRECTION                            Direction,

+  UINT64                                    TimeOutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  Target                - TODO: add argument description

+  PacketCommand         - TODO: add argument description

+  Buffer                - TODO: add argument description

+  ByteCount             - TODO: add argument description

+  Direction             - TODO: add argument description

+  TimeOutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+UINT8

+ReadPortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+UINT16

+ReadPortW (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+VOID

+WritePortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT8                 Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+VOID

+WritePortW (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT16                Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StatusDRQClear (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeOutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeOutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AltStatusDRQClear (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeOutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeOutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StatusDRQReady (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeOutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeOutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AltStatusDRQReady (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,

+  UINT64                          TimeOutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeOutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StatusWaitForBSYClear (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeoutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AltStatusWaitForBSYClear (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeoutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StatusDRDYReady (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeoutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AltStatusDRDYReady (

+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,

+  UINT64                      TimeoutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  TimeoutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiPassThruPioReadWriteData (

+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,

+  UINT16                    *Buffer,

+  UINT32                    *ByteCount,

+  DATA_DIRECTION            Direction,

+  UINT64                    TimeOutInMicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate      - TODO: add argument description

+  Buffer                - TODO: add argument description

+  ByteCount             - TODO: add argument description

+  Direction             - TODO: add argument description

+  TimeOutInMicroSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiPassThruCheckErrorStatus (

+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AtapiScsiPrivate  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.mbd b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.mbd
new file mode 100644
index 0000000..903a092
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>AtapiPassThru</BaseName>

+    <Guid>E49061CE-99A7-41d3-AB3A-36E5CFBAD63E</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.msa b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.msa
new file mode 100644
index 0000000..bfbd9cb
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.msa
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>AtapiPassThru</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>E49061CE-99A7-41d3-AB3A-36E5CFBAD63E</Guid>

+    <Version>0</Version>

+    <Abstract>Description file for the Atapi Passthru component.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>AtapiPassThru.h</Filename>

+    <Filename>AtapiPassThru.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">PciIo</Protocol>

+    <Protocol Usage="BY_START">ScsiPassThru</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gAtapiScsiPassThruDriverBinding</DriverBinding>

+      <ComponentName>gAtapiScsiPassThruComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/ComponentName.c
new file mode 100644
index 0000000..14658b0
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/ComponentName.c
@@ -0,0 +1,154 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+#include "AtapiPassThru.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gAtapiScsiPassThruComponentName = {

+  AtapiScsiPassThruComponentNameGetDriverName,

+  AtapiScsiPassThruComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mAtapiScsiPassThruDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"ATAPI SCSI Pass Thru Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gAtapiScsiPassThruComponentName.SupportedLanguages,

+          mAtapiScsiPassThruDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+AtapiScsiPassThruComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/build.xml
new file mode 100644
index 0000000..3d80c2c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/AtapiPassThru/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="AtapiPassThru"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Pci/AtapiPassThru/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="AtapiPassThru">

+      <GenBuild baseName="AtapiPassThru" mbdFilename="${MODULE_DIR}/AtapiPassThru.mbd" msaFilename="${MODULE_DIR}/AtapiPassThru.msa"/>

+   </target>

+   <target depends="AtapiPassThru_clean" name="clean"/>

+   <target depends="AtapiPassThru_cleanall" name="cleanall"/>

+   <target name="AtapiPassThru_clean">

+      <OutputDirSetup baseName="AtapiPassThru" mbdFilename="${MODULE_DIR}/AtapiPassThru.mbd" msaFilename="${MODULE_DIR}/AtapiPassThru.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/AtapiPassThru_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/AtapiPassThru_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="AtapiPassThru_cleanall">

+      <OutputDirSetup baseName="AtapiPassThru" mbdFilename="${MODULE_DIR}/AtapiPassThru.mbd" msaFilename="${MODULE_DIR}/AtapiPassThru.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/AtapiPassThru_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/AtapiPassThru_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**AtapiPassThru*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.c b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.c
new file mode 100644
index 0000000..91d6acc
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.c
@@ -0,0 +1,346 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CirrusLogic5430.c

+    

+Abstract:

+

+  Cirrus Logic 5430 Controller Driver.

+  This driver is a sample implementation of the UGA Draw Protocol for the

+  Cirrus Logic 5430 family of PCI video controllers.  This driver is only

+  usable in the EFI pre-boot environment.  This sample is intended to show

+  how the UGA Draw Protocol is able to function.  The UGA I/O Protocol is not

+  implemented in this sample.  A fully compliant EFI UGA driver requires both

+  the UGA Draw and the UGA I/O Protocol.  Please refer to Microsoft's

+  documentation on UGA for details on how to write a UGA driver that is able

+  to function both in the EFI pre-boot environment and from the OS runtime.

+

+Revision History:

+

+--*/

+

+//

+// Cirrus Logic 5430 Controller Driver

+//

+

+#include "CirrusLogic5430.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {

+  CirrusLogic5430ControllerDriverSupported,

+  CirrusLogic5430ControllerDriverStart,

+  CirrusLogic5430ControllerDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+    None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  PCI_TYPE00          Pci;

+

+  //

+  // Open the PCI I/O Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Read the PCI Configuration Header from the PCI Device

+  //

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint32,

+                        0,

+                        sizeof (Pci) / sizeof (UINT32),

+                        &Pci

+                        );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Status = EFI_UNSUPPORTED;

+  //

+  // See if the I/O enable is on.  Most systems only allow one VGA device to be turned on

+  // at a time, so see if this is one that is turned on.

+  //

+  //  if (((Pci.Hdr.Command & 0x01) == 0x01)) {

+  //

+  // See if this is a Cirrus Logic PCI controller

+  //

+  if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {

+    //

+    // See if this is a 5430 or a 5446 PCI controller

+    //

+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) {

+      Status = EFI_SUCCESS;

+    }

+

+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) {

+      Status = EFI_SUCCESS;

+    }

+

+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {

+      Status = EFI_SUCCESS;

+    }

+  }

+

+Done:

+  //

+  // Close the PCI I/O Protocol

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+    None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS                      Status;

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  //

+  // Allocate Private context data for UGA Draw inteface.

+  //

+  Private = NULL;

+  Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));

+  if (Private == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+

+  //

+  // Set up context record

+  //

+  Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;

+  Private->Handle     = Controller;

+

+  //

+  // Open PCI I/O Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Private->Handle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &Private->PciIo,

+                  This->DriverBindingHandle,

+                  Private->Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  Status = Private->PciIo->Attributes (

+                            Private->PciIo,

+                            EfiPciIoAttributeOperationEnable,

+                            EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,

+                            NULL

+                            );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  //

+  // Start the UGA Draw software stack.

+  //

+  Status = CirrusLogic5430UgaDrawConstructor (Private);

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  //

+  // Publish the UGA Draw interface to the world

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Private->Handle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &Private->UgaDraw,

+                  NULL

+                  );

+

+Error:

+  if (EFI_ERROR (Status)) {

+    if (Private) {

+      if (Private->PciIo) {

+        Private->PciIo->Attributes (

+                          Private->PciIo,

+                          EfiPciIoAttributeOperationDisable,

+                          EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,

+                          NULL

+                          );

+      }

+    }

+

+    //

+    // Close the PCI I/O Protocol

+    //

+    gBS->CloseProtocol (

+          Private->Handle,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Private->Handle

+          );

+    if (Private) {

+      gBS->FreePool (Private);

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN UINTN                          NumberOfChildren,

+  IN EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+    None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;

+  EFI_STATUS                      Status;

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    //

+    // If the UGA Draw interface does not exist the driver is not started

+    //

+    return Status;

+  }

+

+  //

+  // Get our private context information

+  //

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);

+

+  //

+  // Remove the UGA Draw interface from the system

+  //

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Private->Handle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &Private->UgaDraw,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Shutdown the hardware

+  //

+  CirrusLogic5430UgaDrawDestructor (Private);

+

+  Private->PciIo->Attributes (

+                    Private->PciIo,

+                    EfiPciIoAttributeOperationDisable,

+                    EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,

+                    NULL

+                    );

+

+  //

+  // Close the PCI I/O Protocol

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  //

+  // Free our instance data

+  //

+  gBS->FreePool (Private);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.h b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.h
new file mode 100644
index 0000000..79ca7e0
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.h
@@ -0,0 +1,254 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CirrusLogic5430.h

+    

+Abstract:

+

+  Cirrus Logic 5430 Controller Driver

+

+Revision History

+

+--*/

+

+//

+// Cirrus Logic 5430 Controller Driver

+//

+

+#ifndef _CIRRUS_LOGIC_5430_H_

+#define _CIRRUS_LOGIC_5430_H_

+

+

+#include <IndustryStandard/pci22.h>

+//

+// Cirrus Logic 5430 PCI Configuration Header values

+//

+#define CIRRUS_LOGIC_VENDOR_ID                0x1013

+#define CIRRUS_LOGIC_5430_DEVICE_ID           0x00a8

+#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0

+#define CIRRUS_LOGIC_5446_DEVICE_ID           0x00b8

+

+//

+// Cirrus Logic Graphical Mode Data

+//

+#define CIRRUS_LOGIC_5430_UGA_DRAW_MODE_COUNT 3

+

+typedef struct {

+  UINT32  HorizontalResolution;

+  UINT32  VerticalResolution;

+  UINT32  ColorDepth;

+  UINT32  RefreshRate;

+} CIRRUS_LOGIC_5430_UGA_DRAW_MODE_DATA;

+

+//

+// Cirrus Logic 5440 Private Data Structure

+//

+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('C', 'L', '5', '4')

+

+typedef struct {

+  UINT64                                Signature;

+  EFI_HANDLE                            Handle;

+  EFI_PCI_IO_PROTOCOL                   *PciIo;

+  EFI_UGA_DRAW_PROTOCOL                 UgaDraw;

+

+  //

+  // UGA Draw Private Data

+  //

+  BOOLEAN                               HardwareNeedsStarting;

+  UINTN                                 CurrentMode;

+  UINTN                                 MaxMode;

+  CIRRUS_LOGIC_5430_UGA_DRAW_MODE_DATA  ModeData[CIRRUS_LOGIC_5430_UGA_DRAW_MODE_COUNT];

+  UINT8                                 *LineBuffer;

+} CIRRUS_LOGIC_5430_PRIVATE_DATA;

+

+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS(a) \

+  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, UgaDraw, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gCirrusLogic5430DriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gCirrusLogic5430ComponentName;

+

+//

+// Io Registers defined by VGA

+//

+#define CRTC_ADDRESS_REGISTER   0x3d4

+#define CRTC_DATA_REGISTER      0x3d5

+#define SEQ_ADDRESS_REGISTER    0x3c4

+#define SEQ_DATA_REGISTER       0x3c5

+#define GRAPH_ADDRESS_REGISTER  0x3ce

+#define GRAPH_DATA_REGISTER     0x3cf

+#define ATT_ADDRESS_REGISTER    0x3c0

+#define MISC_OUTPUT_REGISTER    0x3c2

+#define INPUT_STATUS_1_REGISTER 0x3da

+#define DAC_PIXEL_MASK_REGISTER 0x3c6

+#define PALETTE_INDEX_REGISTER  0x3c8

+#define PALETTE_DATA_REGISTER   0x3c9

+

+//

+// UGA Draw Hardware abstraction internal worker functions

+//

+EFI_STATUS

+CirrusLogic5430UgaDrawConstructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CirrusLogic5430UgaDrawDestructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// EFI 1.1 driver model prototypes for Cirrus Logic 5430 UGA Draw

+//

+EFI_STATUS

+EFIAPI

+CirrusLogic5430DriverEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface

+//

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Controller          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Controller          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN UINTN                        NumberOfChildren,

+  IN EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Controller        - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.mbd b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.mbd
new file mode 100644
index 0000000..16bc289
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>CirrusLogic5430UgaDraw</BaseName>

+    <Guid>555F76EA-785F-40d7-9174-153C43636C68</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.msa b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.msa
new file mode 100644
index 0000000..c5d2879
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.msa
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>CirrusLogic5430UgaDraw</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>555F76EA-785F-40d7-9174-153C43636C68</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for CirrusLogic5430 module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>CirrusLogic5430.h</Filename>

+    <Filename>CirrusLogic5430.c</Filename>

+    <Filename>CirrusLogic5430UgaDraw.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">PciIo</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">UgaDraw</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gCirrusLogic5430DriverBinding</DriverBinding>

+      <ComponentName>gCirrusLogic5430ComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430UgaDraw.c b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430UgaDraw.c
new file mode 100644
index 0000000..c33918b
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430UgaDraw.c
@@ -0,0 +1,1036 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CirrusLogic5430UgaDraw.c

+

+Abstract:

+

+  This file produces the graphics abstration of UGA Draw. It is called by 

+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model. 

+  This file just does graphics.

+

+--*/

+

+#include "CirrusLogic5430.h"

+

+//

+// Video Mode structure

+//

+typedef struct {

+  UINT32  Width;

+  UINT32  Height;

+  UINT32  ColorDepth;

+  UINT32  RefreshRate;

+  UINT8   *CrtcSettings;

+  UINT16  *SeqSettings;

+  UINT8   MiscSetting;

+} CIRRUS_LOGIC_5430_VIDEO_MODES;

+

+//

+// Generic Attribute Controller Register Settings

+//

+static UINT8                          AttributeController[21] = {

+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 

+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 

+  0x41, 0x00, 0x0F, 0x00, 0x00

+};

+

+//

+// Generic Graphics Controller Register Settings

+//

+static UINT8 GraphicsController[9] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF

+};

+

+//

+// 640 x 480 x 256 color @ 60 Hertz

+//

+static UINT8                          Crtc_640_480_256_60[28] = {

+  0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,

+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+  0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,

+  0xff, 0x00, 0x00, 0x22

+};

+

+static UINT16                         Seq_640_480_256_60[15] = {

+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 

+  0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e

+};

+

+//

+// 800 x 600 x 256 color @ 60 Hertz

+//

+static UINT8                          Crtc_800_600_256_60[28] = {

+  0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, 

+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+  0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,

+  0xFF, 0x00, 0x00, 0x22

+};

+

+static UINT16                         Seq_800_600_256_60[15] = {

+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 

+  0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e

+};

+

+//

+// 1024 x 768 x 256 color @ 60 Hertz

+//

+static UINT8                          Crtc_1024_768_256_60[28] = {

+  0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, 

+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+  0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,

+  0xFF, 0x4A, 0x00, 0x22

+};

+

+static UINT16                         Seq_1024_768_256_60[15] = {

+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 

+  0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e

+};

+

+//

+// Table of supported video modes

+//

+static CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {

+  {  640, 480, 8, 60, Crtc_640_480_256_60,  Seq_640_480_256_60,  0xe3 },

+  {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef }, 

+  { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } 

+};

+

+//

+// Local Function Prototypes

+//

+VOID

+InitializeGraphicsMode (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData

+  );

+

+VOID

+SetPaletteColor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Index,

+  UINT8                           Red,

+  UINT8                           Green,

+  UINT8                           Blue

+  );

+

+VOID

+SetDefaultPalette (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  );

+

+STATIC

+VOID

+ClearScreen (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  );

+

+VOID

+DrawLogo (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  );

+

+VOID

+outb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT8                           Data

+  );

+

+VOID

+outw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT16                          Data

+  );

+

+UINT8

+inb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  );

+

+UINT16

+inw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  );

+

+//

+// UGA Draw Protocol Member Functions

+//

+EFI_STATUS

+EFIAPI

+CirrusLogic5430UgaDrawGetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL *This,

+  OUT UINT32                *HorizontalResolution,

+  OUT UINT32                *VerticalResolution,

+  OUT UINT32                *ColorDepth,

+  OUT UINT32                *RefreshRate

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  HorizontalResolution  - TODO: add argument description

+  VerticalResolution    - TODO: add argument description

+  ColorDepth            - TODO: add argument description

+  RefreshRate           - TODO: add argument description

+

+Returns:

+

+  EFI_NOT_STARTED - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);

+

+  if (Private->HardwareNeedsStarting) {

+    return EFI_NOT_STARTED;

+  }

+

+  if ((HorizontalResolution == NULL) ||

+      (VerticalResolution == NULL)   ||

+      (ColorDepth == NULL)           ||

+      (RefreshRate == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution;

+  *VerticalResolution   = Private->ModeData[Private->CurrentMode].VerticalResolution;

+  *ColorDepth           = Private->ModeData[Private->CurrentMode].ColorDepth;

+  *RefreshRate          = Private->ModeData[Private->CurrentMode].RefreshRate;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430UgaDrawSetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL *This,

+  IN  UINT32                HorizontalResolution,

+  IN  UINT32                VerticalResolution,

+  IN  UINT32                ColorDepth,

+  IN  UINT32                RefreshRate

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  HorizontalResolution  - TODO: add argument description

+  VerticalResolution    - TODO: add argument description

+  ColorDepth            - TODO: add argument description

+  RefreshRate           - TODO: add argument description

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_NOT_FOUND - TODO: Add description for return value

+

+--*/

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);

+

+  for (Index = 0; Index < Private->MaxMode; Index++) {

+

+    if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) {

+      continue;

+    }

+

+    if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {

+      continue;

+    }

+

+    if (ColorDepth != Private->ModeData[Index].ColorDepth) {

+      continue;

+    }

+

+    if (RefreshRate != Private->ModeData[Index].RefreshRate) {

+      continue;

+    }

+

+    if (Private->LineBuffer) {

+      gBS->FreePool (Private->LineBuffer);

+    }

+

+    Private->LineBuffer = NULL;

+    Private->LineBuffer = AllocatePool (HorizontalResolution);

+    if (Private->LineBuffer == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Index]);

+

+    Private->CurrentMode            = Index;

+

+    Private->HardwareNeedsStarting  = FALSE;

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430UgaDrawBlt (

+  IN  EFI_UGA_DRAW_PROTOCOL     *This,

+  IN  EFI_UGA_PIXEL             *BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION     BltOperation,

+  IN  UINTN                     SourceX,

+  IN  UINTN                     SourceY,

+  IN  UINTN                     DestinationX,

+  IN  UINTN                     DestinationY,

+  IN  UINTN                     Width,

+  IN  UINTN                     Height,

+  IN  UINTN                     Delta

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This          - TODO: add argument description

+  BltBuffer     - TODO: add argument description

+  BltOperation  - TODO: add argument description

+  SourceX       - TODO: add argument description

+  SourceY       - TODO: add argument description

+  DestinationX  - TODO: add argument description

+  DestinationY  - TODO: add argument description

+  Width         - TODO: add argument description

+  Height        - TODO: add argument description

+  Delta         - TODO: add argument description

+

+Returns:

+

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  EFI_TPL                         OriginalTPL;

+  UINTN                           DstY;

+  UINTN                           SrcY;

+  EFI_UGA_PIXEL                   *Blt;

+  UINTN                           X;

+  UINT8                           Pixel;

+  UINT32                          WidePixel;

+  UINTN                           ScreenWidth;

+  UINTN                           Offset;

+  UINTN                           SourceOffset;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);

+

+  if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Width == 0 || Height == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If Delta is zero, then the entire BltBuffer is being used, so Delta

+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,

+  // the number of bytes in each row can be computed.

+  //

+  if (Delta == 0) {

+    Delta = Width * sizeof (EFI_UGA_PIXEL);

+  }

+

+  //

+  // We need to fill the Virtual Screen buffer with the blt data.

+  // The virtual screen is upside down, as the first row is the bootom row of

+  // the image.

+  //

+

+  //

+  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters

+  // are valid for the operation and the current screen geometry.

+  //

+  if (BltOperation == EfiUgaVideoToBltBuffer) {

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+  } else {

+    //

+    // BltBuffer to Video: Source is BltBuffer, destination is Video

+    //

+    if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.

+  // We would not want a timer based event (Cursor, ...) to come in while we are

+  // doing this operation.

+  //

+  OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  switch (BltOperation) {

+  case EfiUgaVideoToBltBuffer:

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {

+

+      Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX;

+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+        Private->PciIo->Mem.Read (

+                              Private->PciIo,

+                              EfiPciIoWidthUint32,

+                              0,

+                              Offset,

+                              Width >> 2,

+                              Private->LineBuffer

+                              );

+      } else {

+        Private->PciIo->Mem.Read (

+                              Private->PciIo,

+                              EfiPciIoWidthUint8,

+                              0,

+                              Offset,

+                              Width,

+                              Private->LineBuffer

+                              );

+      }

+

+      for (X = 0; X < Width; X++) {

+        Blt         = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_UGA_PIXEL));

+

+        Blt->Red    = (UINT8) (Private->LineBuffer[X] & 0xe0);

+        Blt->Green  = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);

+        Blt->Blue   = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);

+      }

+    }

+    break;

+

+  case EfiUgaVideoToVideo:

+    //

+    // Perform hardware acceleration for Video to Video operations

+    //

+    ScreenWidth   = Private->ModeData[Private->CurrentMode].HorizontalResolution;

+    SourceOffset  = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX);

+    Offset        = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);

+

+    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);

+    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)

+      ;

+    break;

+

+  case EfiUgaVideoFill:

+    Blt       = BltBuffer;

+    Pixel     = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));

+    WidePixel = (Pixel << 8) | Pixel;

+    WidePixel = (WidePixel << 16) | WidePixel;

+

+    if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) {

+      Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution;

+      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthFillUint32,

+                              0,

+                              Offset,

+                              (Width * Height) >> 2,

+                              &WidePixel

+                              );

+      } else {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthFillUint8,

+                              0,

+                              Offset,

+                              Width * Height,

+                              &Pixel

+                              );

+      }

+    } else {

+      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {

+        Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;

+        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+          Private->PciIo->Mem.Write (

+                                Private->PciIo,

+                                EfiPciIoWidthFillUint32,

+                                0,

+                                Offset,

+                                Width >> 2,

+                                &WidePixel

+                                );

+        } else {

+          Private->PciIo->Mem.Write (

+                                Private->PciIo,

+                                EfiPciIoWidthFillUint8,

+                                0,

+                                Offset,

+                                Width,

+                                &Pixel

+                                );

+        }

+      }

+    }

+    break;

+

+  case EfiUgaBltBufferToVideo:

+    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {

+

+      for (X = 0; X < Width; X++) {

+        Blt                     = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_UGA_PIXEL));

+        Private->LineBuffer[X]  = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));

+      }

+

+      Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;

+

+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthUint32,

+                              0,

+                              Offset,

+                              Width >> 2,

+                              Private->LineBuffer

+                              );

+      } else {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthUint8,

+                              0,

+                              Offset,

+                              Width,

+                              Private->LineBuffer

+                              );

+      }

+    }

+    break;

+

+  default:

+    break;

+  }

+

+  gBS->RestoreTPL (OriginalTPL);

+

+  return EFI_SUCCESS;

+}

+

+//

+// Construction and Destruction functions

+//

+

+EFI_STATUS

+CirrusLogic5430UgaDrawConstructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Private - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  UINTN                 Index;

+

+  //

+  // Fill in Private->UgaDraw protocol

+  //

+  UgaDraw           = &Private->UgaDraw;

+

+  UgaDraw->GetMode  = CirrusLogic5430UgaDrawGetMode;

+  UgaDraw->SetMode  = CirrusLogic5430UgaDrawSetMode;

+  UgaDraw->Blt      = CirrusLogic5430UgaDrawBlt;

+

+  //

+  // Initialize the private data

+  //

+  Private->MaxMode      = CIRRUS_LOGIC_5430_UGA_DRAW_MODE_COUNT;

+  Private->CurrentMode  = 0;

+  for (Index = 0; Index < Private->MaxMode; Index++) {

+    Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;

+    Private->ModeData[Index].VerticalResolution   = CirrusLogic5430VideoModes[Index].Height;

+    Private->ModeData[Index].ColorDepth           = 32;

+    Private->ModeData[Index].RefreshRate          = CirrusLogic5430VideoModes[Index].RefreshRate;

+  }

+

+  Private->HardwareNeedsStarting  = TRUE;

+  Private->LineBuffer             = NULL;

+

+  //

+  // Initialize the hardware

+  //

+  UgaDraw->SetMode (

+            UgaDraw,

+            Private->ModeData[Private->CurrentMode].HorizontalResolution,

+            Private->ModeData[Private->CurrentMode].VerticalResolution,

+            Private->ModeData[Private->CurrentMode].ColorDepth,

+            Private->ModeData[Private->CurrentMode].RefreshRate

+            );

+  DrawLogo (Private);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CirrusLogic5430UgaDrawDestructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Private - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  return EFI_SUCCESS;

+}

+

+VOID

+outb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT8                           Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Address - TODO: add argument description

+  Data    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  Private->PciIo->Io.Write (

+                      Private->PciIo,

+                      EfiPciIoWidthUint8,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+}

+

+VOID

+outw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT16                          Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Address - TODO: add argument description

+  Data    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  Private->PciIo->Io.Write (

+                      Private->PciIo,

+                      EfiPciIoWidthUint16,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+}

+

+UINT8

+inb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Address - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT8 Data;

+

+  Private->PciIo->Io.Read (

+                      Private->PciIo,

+                      EfiPciIoWidthUint8,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+  return Data;

+}

+

+UINT16

+inw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Address - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT16  Data;

+

+  Private->PciIo->Io.Read (

+                      Private->PciIo,

+                      EfiPciIoWidthUint16,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+  return Data;

+}

+

+VOID

+SetPaletteColor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Index,

+  UINT8                           Red,

+  UINT8                           Green,

+  UINT8                           Blue

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Index   - TODO: add argument description

+  Red     - TODO: add argument description

+  Green   - TODO: add argument description

+  Blue    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);

+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));

+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));

+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));

+}

+

+VOID

+SetDefaultPalette (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINTN Index;

+  UINTN RedIndex;

+  UINTN GreenIndex;

+  UINTN BlueIndex;

+

+  Index = 0;

+  for (RedIndex = 0; RedIndex < 8; RedIndex++) {

+    for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {

+      for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {

+        SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));

+        Index++;

+      }

+    }

+  }

+}

+

+STATIC

+VOID

+ClearScreen (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT32  Color;

+

+  Color = 0;

+  Private->PciIo->Mem.Write (

+                        Private->PciIo,

+                        EfiPciIoWidthFillUint32,

+                        0,

+                        0,

+                        0x100000 >> 2,

+                        &Color

+                        );

+}

+

+VOID

+DrawLogo (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINTN Offset;

+  UINTN X;

+  UINTN Y;

+  UINTN ScreenWidth;

+  UINTN ScreenHeight;

+  UINT8 Color;

+

+  ScreenWidth   = Private->ModeData[Private->CurrentMode].HorizontalResolution;

+  ScreenHeight  = Private->ModeData[Private->CurrentMode].VerticalResolution;

+

+  Offset        = 0;

+  for (Y = 0; Y < ScreenHeight; Y++) {

+    for (X = 0; X < ScreenWidth; X++) {

+      Color                   = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight));

+      Private->LineBuffer[X]  = Color;

+    }

+

+    Private->PciIo->Mem.Write (

+                          Private->PciIo,

+                          EfiPciIoWidthUint32,

+                          0,

+                          Offset + (Y * ScreenWidth),

+                          ScreenWidth >> 2,

+                          Private->LineBuffer

+                          );

+  }

+}

+

+VOID

+InitializeGraphicsMode (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private   - TODO: add argument description

+  ModeData  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT8 Byte;

+  UINTN Index;

+

+  outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);

+  outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);

+

+  for (Index = 0; Index < 15; Index++) {

+    outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);

+  }

+

+  outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);

+  Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);

+  outb (Private, SEQ_DATA_REGISTER, Byte);

+

+  outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);

+  outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);

+  outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);

+

+  for (Index = 0; Index < 28; Index++) {

+    outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));

+  }

+

+  for (Index = 0; Index < 9; Index++) {

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));

+  }

+

+  inb (Private, INPUT_STATUS_1_REGISTER);

+

+  for (Index = 0; Index < 21; Index++) {

+    outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);

+    outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);

+  }

+

+  outb (Private, ATT_ADDRESS_REGISTER, 0x20);

+

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);

+  outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);

+

+  SetDefaultPalette (Private);

+  ClearScreen (Private);

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/ComponentName.c
new file mode 100644
index 0000000..5c10b6d
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/ComponentName.c
@@ -0,0 +1,222 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "CirrusLogic5430.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gCirrusLogic5430ComponentName = {

+  CirrusLogic5430ComponentNameGetDriverName,

+  CirrusLogic5430ComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mCirrusLogic5430DriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Cirrus Logic 5430 UGA Driver" },

+  { NULL , NULL }

+};

+

+static EFI_UNICODE_STRING_TABLE mCirrusLogic5430ControllerNameTable[] = {

+  { "eng", (CHAR16 *) L"Cirrus Logic 5430 PCI Adapter" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gCirrusLogic5430ComponentName.SupportedLanguages,

+          mCirrusLogic5430DriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;

+  EFI_STATUS                      Status;

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  EFI_PCI_IO_PROTOCOL             *PciIoProtocol;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Check Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIoProtocol,

+                  gCirrusLogic5430DriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiPciIoProtocolGuid,

+          gCirrusLogic5430DriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get the UGA Draw Protocol on Controller

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw,

+                  gCirrusLogic5430DriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get the Cirrus Logic 5430's Device structure

+  //

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);

+

+  return LookupUnicodeString (

+          Language,

+          gCirrusLogic5430ComponentName.SupportedLanguages,

+          mCirrusLogic5430ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/build.xml
new file mode 100644
index 0000000..fb6ce8c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="CirrusLogic5430UgaDraw"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Pci/CirrusLogic/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="CirrusLogic5430UgaDraw">

+      <GenBuild baseName="CirrusLogic5430UgaDraw" mbdFilename="${MODULE_DIR}/CirrusLogic5430.mbd" msaFilename="${MODULE_DIR}/CirrusLogic5430.msa"/>

+   </target>

+   <target depends="CirrusLogic5430UgaDraw_clean" name="clean"/>

+   <target depends="CirrusLogic5430UgaDraw_cleanall" name="cleanall"/>

+   <target name="CirrusLogic5430UgaDraw_clean">

+      <OutputDirSetup baseName="CirrusLogic5430UgaDraw" mbdFilename="${MODULE_DIR}/CirrusLogic5430.mbd" msaFilename="${MODULE_DIR}/CirrusLogic5430.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/CirrusLogic5430UgaDraw_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/CirrusLogic5430UgaDraw_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="CirrusLogic5430UgaDraw_cleanall">

+      <OutputDirSetup baseName="CirrusLogic5430UgaDraw" mbdFilename="${MODULE_DIR}/CirrusLogic5430.mbd" msaFilename="${MODULE_DIR}/CirrusLogic5430.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/CirrusLogic5430UgaDraw_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/CirrusLogic5430UgaDraw_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**CirrusLogic5430UgaDraw*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c
new file mode 100644
index 0000000..240a6b0
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.c
@@ -0,0 +1,224 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "idebus.h"

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gIDEBusComponentName = {

+  IDEBusComponentNameGetDriverName,

+  IDEBusComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mIDEBusDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"PCI IDE/ATAPI Bus Driver" },

+  { NULL , NULL }

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mIDEBusControllerNameTable[] = {

+  { "eng", (CHAR16 *) L"PCI IDE/ATAPI Controller" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+IDEBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gIDEBusComponentName.SupportedLanguages,

+          mIDEBusDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+IDEBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+  IDE_BLK_IO_DEV        *IdeBlkIoDevice;

+

+  //

+  // Get the controller context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiCallerIdGuid,

+                  NULL,

+                  gIDEBusDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (ChildHandle == NULL) {

+    return LookupUnicodeString (

+            Language,

+            gIDEBusComponentName.SupportedLanguages,

+            mIDEBusControllerNameTable,

+            ControllerName

+            );

+  }

+

+  //

+  // Get the child context

+  //

+  Status = gBS->OpenProtocol (

+                  ChildHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlockIo,

+                  gIDEBusDriverBinding.DriverBindingHandle,

+                  ChildHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlockIo);

+

+  return LookupUnicodeString (

+          Language,

+          gIDEBusComponentName.SupportedLanguages,

+          IdeBlkIoDevice->ControllerNameTable,

+          ControllerName

+          );

+}

+

+VOID

+AddName (

+  IN  IDE_BLK_IO_DEV               *IdeBlkIoDevicePtr

+  )

+/*++

+

+  Routine Description:

+    Add the component name for the IDE/ATAPI device

+

+  Arguments:

+    IdeBlkIoDevicePtr     - A pointer to the IDE_BLK_IO_DEV instance.

+

+  Returns:

+

+--*/

+{

+  UINTN   StringIndex;

+  CHAR16  ModelName[41];

+

+  //

+  // Add Component Name for the IDE/ATAPI device that was discovered.

+  //

+  IdeBlkIoDevicePtr->ControllerNameTable = NULL;

+  for (StringIndex = 0; StringIndex < 41; StringIndex++) {

+    ModelName[StringIndex] = IdeBlkIoDevicePtr->ModelName[StringIndex];

+  }

+

+  AddUnicodeString (

+    "eng",

+    gIDEBusComponentName.SupportedLanguages,

+    &IdeBlkIoDevicePtr->ControllerNameTable,

+    ModelName

+    );

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h
new file mode 100644
index 0000000..f6c3feb
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ComponentName.h
@@ -0,0 +1,118 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ComponentName.h

+

+Abstract:

+

+

+Revision History

+--*/

+

+#ifndef _IDE_BUS_COMPONENT_NAME_H

+#define _IDE_BUS_COMPONENT_NAME_H

+

+

+#ifndef EFI_SIZE_REDUCTION_APPLIED

+

+#define ADD_NAME(x) AddName ((x));

+

+extern EFI_COMPONENT_NAME_PROTOCOL  gIDEBusComponentName;

+

+#else

+

+#define ADD_NAME(x)

+

+#endif

+

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+IDEBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Language    - TODO: add argument description

+  DriverName  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  ControllerHandle  - TODO: add argument description

+  ChildHandle       - TODO: add argument description

+  Language          - TODO: add argument description

+  ControllerName    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+AddName (

+  IN  IDE_BLK_IO_DEV               *IdeBlkIoDevicePtr

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeBlkIoDevicePtr - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c
new file mode 100644
index 0000000..5a23a43
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverConfiguration.c
@@ -0,0 +1,378 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DriverConfiguration.c

+

+Abstract:

+

+--*/

+

+#include "idebus.h"

+

+CHAR16 *OptionString[4] = {

+  L"Enable Primary Master    (Y/N)? -->",

+  L"Enable Primary Slave     (Y/N)? -->",

+  L"Enable Secondary Master  (Y/N)? -->",

+  L"Enable Secondary Slave   (Y/N)? -->"

+};

+//

+// EFI Driver Configuration Functions

+//

+EFI_STATUS

+IDEBusDriverConfigurationSetOptions (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  CHAR8                                                  *Language,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  );

+

+EFI_STATUS

+IDEBusDriverConfigurationOptionsValid (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL               *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle  OPTIONAL

+  );

+

+EFI_STATUS

+IDEBusDriverConfigurationForceDefaults (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  UINT32                                                 DefaultType,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  );

+

+//

+// EFI Driver Configuration Protocol

+//

+EFI_DRIVER_CONFIGURATION_PROTOCOL gIDEBusDriverConfiguration = {

+  IDEBusDriverConfigurationSetOptions,

+  IDEBusDriverConfigurationOptionsValid,

+  IDEBusDriverConfigurationForceDefaults,

+  "eng"

+};

+

+EFI_STATUS

+GetResponse (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_ABORTED - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_NOT_FOUND - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS    Status;

+  EFI_INPUT_KEY Key;

+

+  while (TRUE) {

+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+    if (!EFI_ERROR (Status)) {

+      if (Key.ScanCode == SCAN_ESC) {

+        return EFI_ABORTED;

+      }

+

+      switch (Key.UnicodeChar) {

+

+      //

+      // fall through

+      //

+      case L'y':

+      case L'Y':

+        gST->ConOut->OutputString (gST->ConOut, L"Y\n");

+        return EFI_SUCCESS;

+

+      //

+      // fall through

+      //

+      case L'n':

+      case L'N':

+        gST->ConOut->OutputString (gST->ConOut, L"N\n");

+        return EFI_NOT_FOUND;

+      }

+

+    }

+  }

+}

+

+EFI_STATUS

+IDEBusDriverConfigurationSetOptions (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  CHAR8                                                  *Language,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  )

+/*++

+

+  Routine Description:

+    Allows the user to set controller specific options for a controller that a 

+    driver is currently managing.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL 

+                       instance.

+    ControllerHandle - The handle of the controller to set options on.

+    ChildHandle      - The handle of the child controller to set options on.  

+                       This is an optional parameter that may be NULL.  

+                       It will be NULL for device drivers, and for a bus drivers

+                       that wish to set options for the bus controller.  

+                       It will not be NULL for a bus driver that wishes to set 

+                       options for one of its child controllers.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier. This is the language of the user interface 

+                       that should be presented to the user, and it must match 

+                       one of the languages specified in SupportedLanguages.  

+                       The number of languages supported by a driver is up to 

+                       the driver writer.

+    ActionRequired   - A pointer to the action that the calling agent is 

+                       required to perform when this function returns.  

+                       See "Related Definitions" for a list of the actions that

+                       the calling agent is required to perform prior to 

+                       accessing ControllerHandle again.

+

+  Returns:

+    EFI_SUCCESS           - The driver specified by This successfully set the 

+                            configuration options for the controller specified 

+                            by ControllerHandle..

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a 

+                            valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ActionRequired is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support 

+                            setting configuration options for the controller 

+                            specified by ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+    EFI_DEVICE_ERROR      - A device error occurred while attempt to set the 

+                            configuration options for the controller specified 

+                            by ControllerHandle and ChildHandle.

+    EFI_OUT_RESOURCES     - There are not enough resources available to set the 

+                            configuration options for the controller specified 

+                            by ControllerHandle and ChildHandle.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       Value;

+  UINT8       NewValue;

+  UINTN       DataSize;

+  UINTN       Index;

+  UINT32      Attributes;

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  *ActionRequired = EfiDriverConfigurationActionNone;

+

+  DataSize        = sizeof (Value);

+  Status = gRT->GetVariable (

+                  L"Configuration",

+                  &gEfiCallerIdGuid,

+                  &Attributes,

+                  &DataSize,

+                  &Value

+                  );

+

+  gST->ConOut->OutputString (gST->ConOut, L"IDE Bus Driver Configuration\n");

+  gST->ConOut->OutputString (gST->ConOut, L"===============================\n");

+

+  NewValue = 0;

+  for (Index = 0; Index < 4; Index++) {

+    gST->ConOut->OutputString (gST->ConOut, OptionString[Index]);

+

+    Status = GetResponse ();

+    if (Status == EFI_ABORTED) {

+      return EFI_SUCCESS;

+    }

+

+    if (!EFI_ERROR (Status)) {

+      NewValue |= (UINT8) (1 << Index);

+    }

+  }

+

+  if (EFI_ERROR (Status) || (NewValue != Value)) {

+    gRT->SetVariable (

+          L"Configuration",

+          &gEfiCallerIdGuid,

+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,

+          sizeof (NewValue),

+          &NewValue

+          );

+

+    *ActionRequired = EfiDriverConfigurationActionRestartController;

+  } else {

+    *ActionRequired = EfiDriverConfigurationActionNone;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+IDEBusDriverConfigurationOptionsValid (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL               *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle  OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Tests to see if a controller's current configuration options are valid.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL 

+                       instance.

+    ControllerHandle - The handle of the controller to test if it's current 

+                       configuration options are valid.

+    ChildHandle      - The handle of the child controller to test if it's 

+                       current

+                       configuration options are valid.  This is an optional 

+                       parameter that may be NULL.  It will be NULL for device 

+                       drivers.  It will also be NULL for a bus drivers that 

+                       wish to test the configuration options for the bus 

+                       controller. It will not be NULL for a bus driver that 

+                       wishes to test configuration options for one of 

+                       its child controllers.

+

+  Returns:

+    EFI_SUCCESS           - The controller specified by ControllerHandle and 

+                            ChildHandle that is being managed by the driver 

+                            specified by This has a valid set of  configuration

+                            options.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_DEVICE_ERROR      - The controller specified by ControllerHandle and 

+                            ChildHandle that is being managed by the driver 

+                            specified by This has an invalid set of 

+                            configuration options.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       Value;

+  UINTN       DataSize;

+  UINT32      Attributes;

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  DataSize = sizeof (Value);

+  Status = gRT->GetVariable (

+                  L"Configuration",

+                  &gEfiCallerIdGuid,

+                  &Attributes,

+                  &DataSize,

+                  &Value

+                  );

+  if (EFI_ERROR (Status) || Value > 0x0f) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+IDEBusDriverConfigurationForceDefaults (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  UINT32                                                 DefaultType,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  )

+/*++

+

+  Routine Description:

+    Forces a driver to set the default configuration options for a controller.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL 

+                       instance.

+    ControllerHandle - The handle of the controller to force default 

+                       configuration options on.

+    ChildHandle      - The handle of the child controller to force default 

+                       configuration options on  This is an optional parameter 

+                       that may be NULL.  It will be NULL for device drivers.  

+                       It will also be NULL for a bus drivers that wish to 

+                       force default configuration options for the bus 

+                       controller.  It will not be NULL for a bus driver that 

+                       wishes to force default configuration options for one 

+                       of its child controllers.

+    DefaultType      - The type of default configuration options to force on 

+                       the controller specified by ControllerHandle and 

+                       ChildHandle.  See Table 9-1 for legal values.  

+                       A DefaultType of 0x00000000 must be supported 

+                       by this protocol.

+    ActionRequired   - A pointer to the action that the calling agent 

+                       is required to perform when this function returns.  

+                       

+

+  Returns:

+    EFI_SUCCESS           - The driver specified by This successfully forced 

+                            the default configuration options on the 

+                            controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a 

+                            valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ActionRequired is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support 

+                            forcing the default configuration options on 

+                            the controller specified by ControllerHandle 

+                            and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support 

+                            the configuration type specified by DefaultType.

+    EFI_DEVICE_ERROR      - A device error occurred while attempt to force 

+                            the default configuration options on the controller 

+                            specified by  ControllerHandle and ChildHandle.

+    EFI_OUT_RESOURCES     - There are not enough resources available to force 

+                            the default configuration options on the controller 

+                            specified by ControllerHandle and ChildHandle.

+

+--*/

+{

+  UINT8 Value;

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Value = 0x0f;

+  gRT->SetVariable (

+        L"Configuration",

+        &gEfiCallerIdGuid,

+        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,

+        sizeof (Value),

+        &Value

+        );

+  *ActionRequired = EfiDriverConfigurationActionRestartController;

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c
new file mode 100644
index 0000000..d3f2a8e
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/DriverDiagnostics.c
@@ -0,0 +1,225 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DriverDiagnostics.c

+

+Abstract:

+

+--*/

+

+#include "idebus.h"

+

+#define IDE_BUS_DIAGNOSTIC_ERROR  L"PCI IDE/ATAPI Driver Diagnostics Failed"

+

+//

+// EFI Driver Diagnostics Functions

+//

+EFI_STATUS

+IDEBusDriverDiagnosticsRunDiagnostics (

+  IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,

+  IN  EFI_HANDLE                                    ControllerHandle,

+  IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,

+  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,

+  IN  CHAR8                                         *Language,

+  OUT EFI_GUID                                      **ErrorType,

+  OUT UINTN                                         *BufferSize,

+  OUT CHAR16                                        **Buffer

+  );

+

+//

+// EFI Driver Diagnostics Protocol

+//

+EFI_DRIVER_DIAGNOSTICS_PROTOCOL gIDEBusDriverDiagnostics = {

+  IDEBusDriverDiagnosticsRunDiagnostics,

+  "eng"

+};

+

+EFI_STATUS

+IDEBusDriverDiagnosticsRunDiagnostics (

+  IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,

+  IN  EFI_HANDLE                                    ControllerHandle,

+  IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,

+  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,

+  IN  CHAR8                                         *Language,

+  OUT EFI_GUID                                      **ErrorType,

+  OUT UINTN                                         *BufferSize,

+  OUT CHAR16                                        **Buffer

+  )

+/*++

+

+  Routine Description:

+    Runs diagnostics on a controller.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL 

+                       instance.

+    ControllerHandle - The handle of the controller to run diagnostics on.

+    ChildHandle      - The handle of the child controller to run diagnostics on  

+                       This is an optional parameter that may be NULL.  It will 

+                       be NULL for device drivers.  It will also be NULL for a 

+                       bus drivers that wish to run diagnostics on the bus 

+                       controller.  It will not be NULL for a bus driver that 

+                       wishes to run diagnostics on one of its child 

+                       controllers.

+    DiagnosticType   - Indicates type of diagnostics to perform on the 

+                       controller specified by ControllerHandle and ChildHandle.

+                       See "Related Definitions" for the list of supported 

+                       types.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language in which the optional 

+                       error message should be returned in Buffer, and it must 

+                       match one of the languages specified in 

+                       SupportedLanguages. The number of languages supported by

+                       a driver is up to the driver writer.

+    ErrorType        - A GUID that defines the format of the data returned in 

+                       Buffer.  

+    BufferSize       - The size, in bytes, of the data returned in Buffer.  

+    Buffer           - A buffer that contains a Null-terminated Unicode string 

+                       plus some additional data whose format is defined by 

+                       ErrorType.  Buffer is allocated by this function with 

+                       AllocatePool(), and it is the caller's responsibility 

+                       to free it with a call to FreePool().  

+

+  Returns:

+    EFI_SUCCESS           - The controller specified by ControllerHandle and 

+                            ChildHandle passed the diagnostic.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ErrorType is NULL.

+    EFI_INVALID_PARAMETER - BufferType is NULL.

+    EFI_INVALID_PARAMETER - Buffer is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support 

+                            running diagnostics for the controller specified 

+                            by ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            type of diagnostic specified by DiagnosticType.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+    EFI_OUT_OF_RESOURCES  - There are not enough resources available to complete

+                            the diagnostics.

+    EFI_OUT_OF_RESOURCES  - There are not enough resources available to return

+                            the status information in ErrorType, BufferSize, 

+                            and Buffer.

+    EFI_DEVICE_ERROR      - The controller specified by ControllerHandle and 

+                            ChildHandle did not pass the diagnostic.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_PCI_IO_PROTOCOL   *PciIo;

+  EFI_BLOCK_IO_PROTOCOL *BlkIo;

+  IDE_BLK_IO_DEV        *IdeBlkIoDevice;

+  UINT32                VendorDeviceId;

+  VOID                  *BlockBuffer;

+

+  *ErrorType  = NULL;

+  *BufferSize = 0;

+

+  if (ChildHandle == NULL) {

+    Status = gBS->OpenProtocol (

+                    ControllerHandle,

+                    &gEfiCallerIdGuid,

+                    NULL,

+                    gIDEBusDriverBinding.DriverBindingHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      return EFI_UNSUPPORTED;

+    }

+

+    Status = gBS->OpenProtocol (

+                    ControllerHandle,

+                    &gEfiPciIoProtocolGuid,

+                    (VOID **) &PciIo,

+                    gIDEBusDriverBinding.DriverBindingHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Use services of PCI I/O Protocol to test the PCI IDE/ATAPI Controller

+    // The following test simply reads the Device ID and Vendor ID.

+    // It should never fail.  A real test would perform more advanced

+    // diagnostics.

+    //

+

+    Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &VendorDeviceId);

+    if (EFI_ERROR (Status) || VendorDeviceId == 0xffffffff) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    return EFI_SUCCESS;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ChildHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlkIo,

+                  gIDEBusDriverBinding.DriverBindingHandle,

+                  ChildHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);

+

+  //

+  // Use services available from IdeBlkIoDevice to test the IDE/ATAPI device

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  IdeBlkIoDevice->BlkMedia.BlockSize,

+                  (VOID **) &BlockBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = IdeBlkIoDevice->BlkIo.ReadBlocks (

+                                  &IdeBlkIoDevice->BlkIo,

+                                  IdeBlkIoDevice->BlkMedia.MediaId,

+                                  0,

+                                  IdeBlkIoDevice->BlkMedia.BlockSize,

+                                  BlockBuffer

+                                  );

+

+  if (EFI_ERROR (Status)) {

+    *ErrorType  = &gEfiCallerIdGuid;

+    *BufferSize = sizeof (IDE_BUS_DIAGNOSTIC_ERROR);

+

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    (UINTN) (*BufferSize),

+                    (VOID **) Buffer

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    EfiCopyMem (*Buffer, IDE_BUS_DIAGNOSTIC_ERROR, *BufferSize);

+

+    Status = EFI_DEVICE_ERROR;

+  }

+

+  gBS->FreePool (BlockBuffer);

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c
new file mode 100644
index 0000000..88e81c0
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c
@@ -0,0 +1,3690 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ata.c

+    

+Abstract: 

+    

+Revision History

+

+    2002-6: Add Atapi6 enhancement, support >120GB hard disk, including

+            update - ATAIdentity() func

+            update - AtaBlockIoReadBlocks() func

+            update - AtaBlockIoWriteBlocks() func

+            add    - AtaAtapi6Identify() func

+            add    - AtaReadSectorsExt() func

+            add    - AtaWriteSectorsExt() func

+            add    - AtaPioDataInExt() func

+            add    - AtaPioDataOutExt() func

+            

+--*/

+

+#include "idebus.h"

+

+

+EFI_STATUS

+AtaReadSectorsExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  OUT VOID        *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  );

+

+EFI_STATUS

+AtaWriteSectorsExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  );

+

+EFI_STATUS

+AtaPioDataInExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  OUT VOID        *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  EFI_LBA         StartLba,

+  IN  UINT16          SectorCount

+  );

+

+EFI_STATUS

+AtaPioDataOutExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  EFI_LBA         StartLba,

+  IN  UINT16          SectorCount

+  );

+

+EFI_STATUS

+ATAIdentify (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        ATAIdentify

+

+

+  Purpose: 

+        This function is called by DiscoverIdeDevice() during its device

+        identification. It sends out the ATA Identify Command to the 

+        specified device. Only ATA device responses to this command. If 

+        the command succeeds, it returns the Identify data structure which 

+        contains information about the device. This function extracts the 

+        information it needs to fill the IDE_BLK_IO_DEV data structure, 

+        including device type, media block size, media capacity, and etc.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure,used

+          to record all the information of the IDE device.

+

+

+  Returns:  

+        EFI_SUCCESS

+          Identify ATA device successfully.

+

+        EFI_DEVICE_ERROR

+          ATA Identify Device Command failed or device is not 

+          ATA device.

+

+

+  Notes:

+        parameter IdeDev will be updated in this function.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  EFI_STATUS        Status;

+  EFI_IDENTIFY_DATA *AtaIdentifyPointer;

+  UINT32            Capacity;

+  UINT8             DeviceSelect;

+

+  //

+  //  AtaIdentifyPointer is used for accommodating returned IDENTIFY data of

+  //  the ATA Identify command

+  //

+  AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));

+

+  //

+  //  use ATA PIO Data In protocol to send ATA Identify command

+  //  and receive data from device

+  //

+  DeviceSelect  = 0;

+  DeviceSelect  = (UINT8) ((IdeDev->Device) << 4);

+  Status = AtaPioDataIn (

+            IdeDev,

+            (VOID *) AtaIdentifyPointer,

+            sizeof (EFI_IDENTIFY_DATA),

+            IDENTIFY_DRIVE_CMD,

+            DeviceSelect,

+            0,

+            0,

+            0,

+            0

+            );

+  //

+  // If ATA Identify command succeeds, then according to the received

+  // IDENTIFY data,

+  // identify the device type ( ATA or not ).

+  // If ATA device, fill the information in IdeDev.

+  // If not ATA device, return IDE_DEVICE_ERROR

+  //

+  if (!EFI_ERROR (Status)) {

+

+    IdeDev->pIdData = AtaIdentifyPointer;

+

+    //

+    // Print ATA Module Name

+    //

+    PrintAtaModuleName (IdeDev);

+

+    //

+    // bit 15 of pAtaIdentify->config is used to identify whether device is

+    // ATA device or ATAPI device.

+    // if 0, means ATA device; if 1, means ATAPI device.

+    //

+    if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {

+      //

+      // Detect if support S.M.A.R.T. If yes, enable it as default

+      //

+      AtaSMARTSupport (IdeDev);

+

+      //

+      // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)

+      //

+      Status = AtaAtapi6Identify (IdeDev);

+      if (!EFI_ERROR (Status)) {

+        //

+        // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()

+        //

+        return EFI_SUCCESS;

+      }

+      //

+      // This is a hard disk <= 120GB capacity, treat it as normal hard disk

+      //

+      IdeDev->Type = IdeHardDisk;

+

+      //

+      // Block Media Information:

+      // Media->LogicalPartition , Media->WriteCaching will be filled

+      // in the DiscoverIdeDevcie() function.

+      //

+      IdeDev->BlkIo.Media->IoAlign        = 4;

+      IdeDev->BlkIo.Media->MediaId        = 1;

+      IdeDev->BlkIo.Media->RemovableMedia = FALSE;

+      IdeDev->BlkIo.Media->MediaPresent   = TRUE;

+      IdeDev->BlkIo.Media->ReadOnly       = FALSE;

+      IdeDev->BlkIo.Media->BlockSize      = 0x200;

+

+      //

+      // Calculate device capacity

+      //

+      Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |

+                  AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ;

+      IdeDev->BlkIo.Media->LastBlock = Capacity - 1;

+

+      return EFI_SUCCESS;

+

+    }

+  }

+

+  gBS->FreePool (AtaIdentifyPointer);

+  //

+  // Make sure the pIdData will not be freed again.

+  //

+  IdeDev->pIdData = NULL;

+

+  return EFI_DEVICE_ERROR;

+}

+

+

+EFI_STATUS

+AtaAtapi6Identify (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+  

+        AtaAtapi6Identify

+

+  Purpose: 

+  

+        This function is called by ATAIdentify() to identity whether this disk

+        supports ATA/ATAPI6 48bit addressing, ie support >120G capacity

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+  

+        EFI_SUCCESS     - The disk specified by IdeDev is a Atapi6 supported one

+                          and 48-bit addressing must be used

+

+        EFI_UNSUPPORTED - The disk dosn't not support Atapi6 or it supports but

+                          the capacity is below 120G, 48bit addressing is not 

+                          needed

+                          

+  Notes:

+

+       This function must be called after DEVICE_IDENTITY command has been 

+       successfully returned

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  UINT8             Index;

+  EFI_LBA           TmpLba;

+  EFI_LBA           Capacity;

+  EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;

+

+  if (IdeDev->pIdData == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Atapi6IdentifyStruct = IdeDev->pIdData;

+

+  if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & bit10) == 0) {

+    //

+    // The device dosn't support 48 bit addressing

+    //

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // 48 bit address feature set is supported, get maximum capacity

+  //

+  Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];

+  for (Index = 1; Index < 4; Index++) {

+    //

+    // Lower byte goes first: word[100] is the lowest word, word[103] is highest

+    //

+    TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];

+    Capacity |= LShiftU64 (TmpLba, 16 * Index);

+  }

+

+  if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {

+    //

+    // Capacity exceeds 120GB. 48-bit addressing is really needed

+    //

+    IdeDev->Type = Ide48bitAddressingHardDisk;

+

+    //

+    // Fill block media information:Media->LogicalPartition ,

+    // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.

+    //

+    IdeDev->BlkIo.Media->IoAlign        = 4;

+    IdeDev->BlkIo.Media->MediaId        = 1;

+    IdeDev->BlkIo.Media->RemovableMedia = FALSE;

+    IdeDev->BlkIo.Media->MediaPresent   = TRUE;

+    IdeDev->BlkIo.Media->ReadOnly       = FALSE;

+    IdeDev->BlkIo.Media->BlockSize      = 0x200;

+    IdeDev->BlkIo.Media->LastBlock      = Capacity - 1;

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+VOID

+PrintAtaModuleName (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        PrintAtaModuleName

+

+

+  Purpose: 

+        This function is called by ATAIdentify() or ATAPIIdentify()

+        to print device's module name. 

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        no returns.

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  if (IdeDev->pIdData == NULL) {

+    return ;

+  }

+

+  SwapStringChars (IdeDev->ModelName, IdeDev->pIdData->AtaData.ModelName, 40);

+  IdeDev->ModelName[40] = 0x00;

+}

+

+EFI_STATUS

+AtaPioDataIn (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Head,

+  IN  UINT8           SectorCount,

+  IN  UINT8           SectorNumber,

+  IN  UINT8           CylinderLsb,

+  IN  UINT8           CylinderMsb

+  )

+/*++

+  Name:

+        AtaPioDataIn

+

+

+  Purpose: 

+        This function is used to send out ATA commands conforms to the 

+        PIO Data In Protocol.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *Buffer

+          buffer contained data transferred from device to host.

+

+        UINT32      IN    ByteCount

+          data size in byte unit of the buffer.

+

+        UINT8     IN    AtaCommand

+          value of the Command Register

+

+        UINT8     IN    Head

+          value of the Head/Device Register

+

+        UINT8     IN    SectorCount

+          value of the Sector Count Register

+

+        UINT8     IN    SectorNumber

+          value of the Sector Number Register

+

+        UINT8     IN    CylinderLsb

+          value of the low byte of the Cylinder Register

+

+        UINT8     IN    CylinderMsb

+          value of the high byte of the Cylinder Register

+

+

+  Returns:  

+        EFI_SUCCESS

+          send out the ATA command and device send required

+          data successfully.

+

+        EFI_DEVICE_ERROR

+          command sent failed.

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    AtaCommand - add argument and description to function comment

+// TODO:    Head - add argument and description to function comment

+// TODO:    SectorCount - add argument and description to function comment

+// TODO:    SectorNumber - add argument and description to function comment

+// TODO:    CylinderLsb - add argument and description to function comment

+// TODO:    CylinderMsb - add argument and description to function comment

+{

+  UINTN       WordCount;

+  UINTN       Increment;

+  UINT16      *Buffer16;

+  EFI_STATUS  Status;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  //  e0:1110,0000-- bit7 and bit5 are reserved bits.

+  //           bit6 set means LBA mode

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)

+    );

+

+  //

+  // All ATAPI device's ATA commands can be issued regardless of the

+  // state of the DRDY

+  //

+  if (IdeDev->Type == IdeHardDisk) {

+

+    Status = DRDYReady (IdeDev, ATATIMEOUT);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+  //

+  // set all the command parameters

+  // Before write to all the following registers, BSY and DRQ must be 0.

+  //

+  Status = DRQClear2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (AtaCommand == SET_FEATURES_CMD) {

+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);

+  }

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);

+

+  //

+  // send command via Command Register

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  Buffer16 = (UINT16 *) Buffer;

+

+  //

+  // According to PIO data in protocol, host can perform a series of reads to

+  // the data register after each time device set DRQ ready;

+  // The data size of "a series of read" is command specific.

+  // For most ATA command, data size received from device will not exceed

+  // 1 sector, hence the data size for "a series of read" can be the whole data

+  // size of one command request.

+  // For ATA command such as Read Sector command, the data size of one ATA

+  // command request is often larger than 1 sector, according to the

+  // Read Sector command, the data size of "a series of read" is exactly 1

+  // sector.

+  // Here for simplification reason, we specify the data size for

+  // "a series of read" to 1 sector (256 words) if data size of one ATA command

+  // request is larger than 256 words.

+  //

+  Increment = 256;

+

+  //

+  // used to record bytes of currently transfered data

+  //

+  WordCount = 0;

+

+  while (WordCount < ByteCount / 2) {

+    //

+    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.

+    //

+    Status = DRQReady2 (IdeDev, ATATIMEOUT);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Status = CheckErrorStatus (IdeDev);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Get the byte count for one series of read

+    //

+    if ((WordCount + Increment) > ByteCount / 2) {

+      Increment = ByteCount / 2 - WordCount;

+    }

+

+    IDEReadPortWMultiple (

+      IdeDev->PciIo,

+      IdeDev->IoPort->Data,

+      Increment,

+      Buffer16

+      );

+

+    WordCount += Increment;

+    Buffer16 += Increment;

+

+  }

+

+  DRQClear (IdeDev, ATATIMEOUT);

+

+  return CheckErrorStatus (IdeDev);

+}

+

+EFI_STATUS

+AtaPioDataOut (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Head,

+  IN  UINT8           SectorCount,

+  IN  UINT8           SectorNumber,

+  IN  UINT8           CylinderLsb,

+  IN  UINT8           CylinderMsb

+  )

+/*++

+  Name:

+        AtaPioDataOut

+

+

+  Purpose: 

+        This function is used to send out ATA commands conforms to the 

+        PIO Data Out Protocol.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *Buffer

+          buffer contained data transferred from host to device.

+

+        UINT32      IN    ByteCount

+          data size in byte unit of the buffer.

+

+        UINT8     IN    AtaCommand

+          value of the Command Register

+

+        UINT8     IN    Head

+          value of the Head/Device Register

+

+        UINT8     IN    SectorCount

+          value of the Sector Count Register

+

+        UINT8     IN    SectorNumber

+          value of the Sector Number Register

+

+        UINT8     IN    CylinderLsb

+          value of the low byte of the Cylinder Register

+

+        UINT8     IN    CylinderMsb

+          value of the high byte of the Cylinder Register

+

+

+  Returns:  

+        EFI_SUCCESS

+          send out the ATA command and device received required

+          data successfully.

+

+        EFI_DEVICE_ERROR

+          command sent failed. 

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    AtaCommand - add argument and description to function comment

+// TODO:    Head - add argument and description to function comment

+// TODO:    SectorCount - add argument and description to function comment

+// TODO:    SectorNumber - add argument and description to function comment

+// TODO:    CylinderLsb - add argument and description to function comment

+// TODO:    CylinderMsb - add argument and description to function comment

+{

+  UINTN       WordCount;

+  UINTN       Increment;

+  UINT16      *Buffer16;

+  EFI_STATUS  Status;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // select device via Head/Device register.

+  // Before write Head/Device register, BSY and DRQ must be 0.

+  //

+  Status = DRQClear2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // e0:1110,0000-- bit7 and bit5 are reserved bits.

+  //          bit6 set means LBA mode

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)

+    );

+

+  Status = DRDYReady (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // set all the command parameters

+  // Before write to all the following registers, BSY and DRQ must be 0.

+  //

+  Status = DRQClear2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);

+

+  //

+  // send command via Command Register

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  Buffer16 = (UINT16 *) Buffer;

+

+  //

+  // According to PIO data out protocol, host can perform a series of

+  // writes to the data register after each time device set DRQ ready;

+  // The data size of "a series of read" is command specific.

+  // For most ATA command, data size written to device will not exceed 1 sector,

+  // hence the data size for "a series of write" can be the data size of one

+  // command request.

+  // For ATA command such as Write Sector command, the data size of one

+  // ATA command request is often larger than 1 sector, according to the

+  // Write Sector command, the data size of "a series of read" is exactly

+  // 1 sector.

+  // Here for simplification reason, we specify the data size for

+  // "a series of write" to 1 sector (256 words) if data size of one ATA command

+  // request is larger than 256 words.

+  //

+  Increment = 256;

+  WordCount = 0;

+

+  while (WordCount < ByteCount / 2) {

+    

+    //

+    // DRQReady2-- read Alternate Status Register to determine the DRQ bit

+    // data transfer can be performed only when DRQ is ready.

+    //

+    Status = DRQReady2 (IdeDev, ATATIMEOUT);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Status = CheckErrorStatus (IdeDev);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+   //

+   // Check the remaining byte count is less than 512 bytes

+   //

+   if ((WordCount + Increment) > ByteCount / 2) {

+      Increment = ByteCount / 2 - WordCount;

+    }

+    //

+    // perform a series of write without check DRQ ready

+    //

+    

+    IDEWritePortWMultiple (

+      IdeDev->PciIo,

+      IdeDev->IoPort->Data,

+      Increment,

+      Buffer16

+      );

+    WordCount += Increment;

+    Buffer16 += Increment;

+

+  }

+

+  DRQClear (IdeDev, ATATIMEOUT);

+

+  return CheckErrorStatus (IdeDev);

+}

+

+EFI_STATUS

+CheckErrorStatus (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        CheckErrorStatus

+

+

+  Purpose: 

+        This function is used to analyze the Status Register and print out 

+        some debug information and if there is ERR bit set in the Status

+        Register, the Error Register's value is also be parsed and print out.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          No err information in the Status Register.

+

+        EFI_DEVICE_ERROR

+          Any err information in the Status Register.

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  UINT8 StatusRegister;

+

+//#ifdef EFI_DEBUG

+

+  UINT8 ErrorRegister;

+

+//#endif

+

+  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+

+  DEBUG_CODE (

+

+    if (StatusRegister & DWF) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Write Fault\n",

+      StatusRegister)

+      );

+  }

+

+  if (StatusRegister & CORR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Corrected Data\n",

+      StatusRegister)

+      );

+  }

+

+  if (StatusRegister & ERR) {

+    ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+

+    if (ErrorRegister & BBK_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & UNC_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & MC_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Media Change\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & ABRT_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Abort\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & TK0NF_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",

+      ErrorRegister)

+      );

+  }

+

+  if (ErrorRegister & AMNF_ERR) {

+    DEBUG (

+      (EFI_D_BLKIO,

+      "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",

+      ErrorRegister)

+      );

+  }

+

+  }

+  );

+

+  if ((StatusRegister & (ERR | DWF | CORR)) == 0) {

+    return EFI_SUCCESS;

+  }

+

+  return EFI_DEVICE_ERROR;

+

+}

+

+EFI_STATUS

+AtaReadSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+        AtaReadSectors

+

+

+  Purpose: 

+        This function is called by the AtaBlkIoReadBlocks() to perform

+        reading from media in block unit.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the destination buffer for the data. 

+

+        EFI_LBA     IN    Lba

+          The starting logical block address to read from 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+        return status is fully dependent on the return status

+        of AtaPioDataIn() function.

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    Lba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  UINTN       BlocksRemaining;

+  UINT32      Lba32;

+  UINT8       Lba0;

+  UINT8       Lba1;

+  UINT8       Lba2;

+  UINT8       Lba3;

+  UINT8       AtaCommand;

+  UINT8       SectorCount8;

+  UINT16      SectorCount;

+  UINTN       ByteCount;

+  VOID        *Buffer;

+

+  Buffer = DataBuffer;

+

+  //

+  // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol

+  //

+  AtaCommand      = READ_SECTORS_CMD;

+

+  

+  BlocksRemaining = NumberOfBlocks;

+

+  Lba32           = (UINT32) Lba;

+

+  Status          = EFI_SUCCESS;

+

+  while (BlocksRemaining > 0) {

+    

+    //

+    // in ATA-3 spec, LBA is in 28 bit width

+    //

+    Lba0  = (UINT8) Lba32;

+    Lba1  = (UINT8) (Lba32 >> 8);

+    Lba2  = (UINT8) (Lba32 >> 16);

+    //

+    // low 4 bit of Lba3 stands for LBA bit24~bit27.

+    //

+    Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);

+

+    if (BlocksRemaining >= 0x100) {

+      

+      //

+      //  SectorCount8 is sent to Sector Count register, 0x00 means 256

+      //  sectors to be read

+      //

+      SectorCount8 = 0x00;

+      //

+      //  SectorCount is used to record the number of sectors to be read

+      //

+      SectorCount = 256;

+    } else {

+

+      SectorCount8  = (UINT8) BlocksRemaining;

+      SectorCount   = (UINT16) BlocksRemaining;

+    }

+

+    //

+    // ByteCount is the number of bytes that will be read

+    //

+    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);

+

+    //

+    // call AtaPioDataIn() to send Read Sector Command and receive data read

+    //

+    Status = AtaPioDataIn (

+              IdeDev,

+              Buffer,

+              (UINT32) ByteCount,

+              AtaCommand,

+              Lba3,

+              SectorCount8,

+              Lba0,

+              Lba1,

+              Lba2

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Lba32 += SectorCount;

+    Buffer = ((UINT8 *) Buffer + ByteCount);

+    BlocksRemaining -= SectorCount;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AtaWriteSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *BufferData,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+        AtaWriteSectors

+

+

+  Purpose: 

+        This function is called by the AtaBlkIoWriteBlocks() to perform

+        writing onto media in block unit.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure,used

+          to record all the information of the IDE device.

+

+        VOID      IN    *BufferData

+          A pointer to the source buffer for the data. 

+

+        EFI_LBA     IN    Lba

+          The starting logical block address to write onto 

+          the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+

+  Returns:  

+        return status is fully dependent on the return status

+        of AtaPioDataOut() function.

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    BufferData - add argument and description to function comment

+// TODO:    Lba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  UINTN       BlocksRemaining;

+  UINT32      Lba32;

+  UINT8       Lba0;

+  UINT8       Lba1;

+  UINT8       Lba2;

+  UINT8       Lba3;

+  UINT8       AtaCommand;

+  UINT8       SectorCount8;

+  UINT16      SectorCount;

+  UINTN       ByteCount;

+  VOID        *Buffer;

+

+  Buffer = BufferData;

+

+  //

+  // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol

+  //

+  AtaCommand      = WRITE_SECTORS_CMD;

+

+  BlocksRemaining = NumberOfBlocks;

+

+  Lba32           = (UINT32) Lba;

+

+  Status          = EFI_SUCCESS;

+

+  while (BlocksRemaining > 0) {

+

+    Lba0  = (UINT8) Lba32;

+    Lba1  = (UINT8) (Lba32 >> 8);

+    Lba2  = (UINT8) (Lba32 >> 16);

+    Lba3  = (UINT8) ((Lba32 >> 24) & 0x0f);

+

+    if (BlocksRemaining >= 0x100) {

+      

+      //

+      //  SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors

+      //  to be written

+      //

+      SectorCount8 = 0x00;

+      //

+      //  SectorCount is used to record the number of sectors to be written

+      //

+      SectorCount = 256;

+    } else {

+

+      SectorCount8  = (UINT8) BlocksRemaining;

+      SectorCount   = (UINT16) BlocksRemaining;

+    }

+

+    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);

+

+    Status = AtaPioDataOut (

+              IdeDev,

+              Buffer,

+              (UINT32) ByteCount,

+              AtaCommand,

+              Lba3,

+              SectorCount8,

+              Lba0,

+              Lba1,

+              Lba2

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Lba32 += SectorCount;

+    Buffer = ((UINT8 *) Buffer + ByteCount);

+    BlocksRemaining -= SectorCount;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AtaSoftReset (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        AtaSoftReset

+

+  Purpose: 

+        This function is used to implement the Soft Reset on the specified

+        device. But, the ATA Soft Reset mechanism is so strong a reset method 

+        that it will force resetting on both devices connected to the 

+        same cable.

+        It is called by IdeBlkIoReset(), a interface function of Block

+        I/O protocol.

+        This function can also be used by the ATAPI device to perform reset when

+        ATAPI Reset command is failed.

+            

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+  Returns:  

+        EFI_SUCCESS

+          Soft reset completes successfully.

+

+        EFI_DEVICE_ERROR

+          Any step during the reset process is failed.

+  Notes:

+        The registers initial values after ATA soft reset are different

+        to the ATA device and ATAPI device.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+

+  UINT8 DeviceControl;

+

+  DeviceControl = 0;

+  //

+  // set SRST bit to initiate soft reset

+  //

+  DeviceControl |= SRST;

+

+  //

+  // disable Interrupt

+  //

+  DeviceControl |= bit1;

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  gBS->Stall (10);

+

+  //

+  // Enable interrupt to support UDMA, and clear SRST bit

+  //

+  DeviceControl = 0;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  //

+  // slave device needs at most 31s to clear BSY

+  //

+  if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaBlkIoReadBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+  Name:

+      AtaBlkIoReadBlocks

+

+

+  Purpose: 

+      This function is the ATA implementation for ReadBlocks in the

+      Block I/O Protocol interface.

+

+

+  Parameters:

+      IDE_BLK_IO_DEV    IN    *IdeBlkIoDevice

+        Indicates the calling context.

+

+      UINT32      IN    MediaId

+        The media id that the read request is for.

+

+      EFI_LBA     IN    LBA

+        The starting logical block address to read from 

+        on the device.

+

+      UINTN     IN    BufferSize

+        The size of the Buffer in bytes. This must be a

+        multiple of the intrinsic block size of the device.

+

+      VOID      OUT   *Buffer

+        A pointer to the destination buffer for the data. 

+        The caller is responsible for either having implicit

+        or explicit ownership of the memory that data is read into.

+

+  Returns:  

+      EFI_SUCCESS 

+        Read Blocks successfully.

+

+      EFI_DEVICE_ERROR

+        Read Blocks failed.

+

+      EFI_NO_MEDIA

+        There is no media in the device.

+

+      EFI_MEDIA_CHANGE

+        The MediaId is not for the current media.

+

+      EFI_BAD_BUFFER_SIZE

+        The BufferSize parameter is not a multiple of the 

+        intrinsic block size of the device.

+

+      EFI_INVALID_PARAMETER

+        The read request contains LBAs that are not valid,

+        or the data buffer is not valid.

+

+  Notes:

+      If Read Block error because of device error, this function will call

+      AtaSoftReset() function to reset device.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeBlkIoDevice - add argument and description to function comment

+// TODO:    MediaId - add argument and description to function comment

+// TODO:    LBA - add argument and description to function comment

+// TODO:    BufferSize - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_MEDIA_CHANGED - add return value to function comment

+{

+  EFI_BLOCK_IO_MEDIA  *Media;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  EFI_STATUS          Status;

+

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferSize == 0) {

+    return EFI_SUCCESS;

+  }

+

+  Status = EFI_SUCCESS;

+

+  //

+  //  Get the intrinsic block size

+  //

+  Media           = IdeBlkIoDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (MediaId != Media->MediaId) {

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (!(Media->MediaPresent)) {

+    return EFI_NO_MEDIA;

+  }

+

+  if (LBA > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {

+    //

+    // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism

+    //

+    Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    if (EFI_ERROR (Status)) {

+      Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    }

+  } else {

+    //

+    // For ATA-3 compatible device, use ATA-3 read block mechanism

+    // Notice DMA operation can only handle 32bit address

+    //

+    if ((UINTN) Buffer <= 0xFFFFFFFF) {

+      Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    }

+

+    if (EFI_ERROR (Status) || ((UINTN) Buffer > 0xFFFFFFFF)) {

+      Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    }

+  }

+

+  if (EFI_ERROR (Status)) {

+    AtaSoftReset (IdeBlkIoDevice);

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+AtaBlkIoWriteBlocks (

+  IN  IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN  UINT32           MediaId,

+  IN  EFI_LBA          LBA,

+  IN  UINTN            BufferSize,

+  OUT VOID             *Buffer

+  )

+/*++

+  Name:

+        AtaBlkIoWriteBlocks

+

+

+  Purpose: 

+        This function is the ATA implementation for WriteBlocks in the

+        Block I/O Protocol interface.

+

+  Parameters:

+        IDE_BLK_IO_DEV   IN    *IdeBlkIoDevice

+          Indicates the calling context.

+

+        UINT32      IN    MediaId

+          The media id that the write request is for.

+

+        EFI_LBA     IN    LBA

+          The starting logical block address to write onto 

+          the device.

+

+        UINTN     IN    BufferSize

+          The size of the Buffer in bytes. This must be a

+          multiple of the intrinsic block size of the device.

+

+        VOID      OUT   *Buffer

+          A pointer to the source buffer for the data. 

+          The caller is responsible for either having implicit

+          or explicit ownership of the memory that data is 

+          written from.

+

+

+  Returns:  

+        EFI_SUCCESS 

+          Write Blocks successfully.

+

+        EFI_DEVICE_ERROR

+          Write Blocks failed.

+

+        EFI_NO_MEDIA

+          There is no media in the device.

+

+        EFI_MEDIA_CHANGE

+          The MediaId is not for the current media.

+

+        EFI_BAD_BUFFER_SIZE

+          The BufferSize parameter is not a multiple of the 

+          intrinsic block size of the device.

+

+        EFI_INVALID_PARAMETER

+          The write request contains LBAs that are not valid,

+          or the data buffer is not valid.

+

+  Notes:

+        If Write Block error because of device error, this function will call

+        AtaSoftReset() function to reset device.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeBlkIoDevice - add argument and description to function comment

+// TODO:    MediaId - add argument and description to function comment

+// TODO:    LBA - add argument and description to function comment

+// TODO:    BufferSize - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_MEDIA_CHANGED - add return value to function comment

+{

+

+  EFI_BLOCK_IO_MEDIA  *Media;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  EFI_STATUS          Status;

+

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferSize == 0) {

+    return EFI_SUCCESS;

+  }

+

+  Status = EFI_SUCCESS;

+

+  //

+  // Get the intrinsic block size

+  //

+  Media           = IdeBlkIoDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (MediaId != Media->MediaId) {

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (LBA > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {

+    //

+    // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism

+    //

+    Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    if (EFI_ERROR (Status)) {

+      Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    }

+  } else {

+    //

+    // For ATA-3 compatible device, use ATA-3 write block mechanism

+    //

+    Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    if (EFI_ERROR (Status) || ((UINTN) Buffer > 0xFFFFFFFF)) {

+      Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+    }

+  }

+

+  if (EFI_ERROR (Status)) {

+    AtaSoftReset (IdeBlkIoDevice);

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaReadSectorsExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+  

+        AtaReadSectorsExt

+

+  Purpose: 

+  

+        This function is called by the AtaBlkIoReadBlocks() to perform

+        reading from media in block unit. The function has been enhanced to 

+        support >120GB access and transfer at most 65536 blocks per command

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the destination buffer for the data. 

+

+        EFI_LBA     IN    StartLba

+          The starting logical block address to read from 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+  

+        return status is fully dependent on the return status

+        of AtaPioDataInExt() function.

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  UINTN       BlocksRemaining;

+  EFI_LBA     Lba64;

+  UINT8       AtaCommand;

+  UINT16      SectorCount;

+  UINT32      ByteCount;

+  VOID        *Buffer;

+

+  //

+  // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol

+  //

+  AtaCommand      = READ_SECTORS_EXT_CMD;

+  Buffer          = DataBuffer;

+  BlocksRemaining = NumberOfBlocks;

+  Lba64           = StartLba;

+  Status          = EFI_SUCCESS;

+

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining >= 0x10000) {

+      //

+      //  SectorCount is used to record the number of sectors to be read

+      //  Max 65536 sectors can be transfered at a time.

+      //

+      SectorCount = 0xffff;

+    } else {

+      SectorCount = (UINT16) BlocksRemaining;

+    }

+

+    //

+    // ByteCount is the number of bytes that will be read

+    //

+    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);

+

+    //

+    // call AtaPioDataInExt() to send Read Sector Command and receive data read

+    //

+    Status = AtaPioDataInExt (

+              IdeDev,

+              Buffer,

+              ByteCount,

+              AtaCommand,

+              Lba64,

+              SectorCount

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Lba64 += SectorCount;

+    Buffer = ((UINT8 *) Buffer + ByteCount);

+    BlocksRemaining -= SectorCount;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AtaWriteSectorsExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+  

+        AtaWriteSectorsExt

+

+  Purpose: 

+  

+        This function is called by the AtaBlkIoWriteBlocks() to perform

+        writing onto media in block unit. The function has been enhanced to 

+        support >120GB access and transfer at most 65536 blocks per command

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure,used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the source buffer for the data. 

+

+        EFI_LBA   IN    Lba

+          The starting logical block address to write onto 

+          the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+  

+        return status is fully dependent on the return status

+        of AtaPioDataOutExt() function.

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  EFI_LBA     Lba64;

+  UINTN       BlocksRemaining;

+  UINT8       AtaCommand;

+  UINT16      SectorCount;

+  UINT32      ByteCount;

+  VOID        *Buffer;

+

+  //

+  // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol

+  //

+  AtaCommand      = WRITE_SECTORS_EXT_CMD;

+  Lba64           = StartLba;

+  Buffer          = DataBuffer;

+  BlocksRemaining = NumberOfBlocks;

+

+  Status          = EFI_SUCCESS;

+

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining >= 0x10000) {

+      //

+      //  SectorCount is used to record the number of sectors to be written.

+      //  Max 65536 sectors can be transfered at a time.

+      //

+      SectorCount = 0xffff;

+    } else {

+      SectorCount = (UINT16) BlocksRemaining;

+    }

+

+    //

+    // ByteCount is the number of bytes that will be written

+    //

+    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);

+

+    //

+    // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command

+    //

+    Status = AtaPioDataOutExt (

+              IdeDev,

+              Buffer,

+              ByteCount,

+              AtaCommand,

+              Lba64,

+              SectorCount

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Lba64 += SectorCount;

+    Buffer = ((UINT8 *) Buffer + ByteCount);

+    BlocksRemaining -= SectorCount;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AtaPioDataInExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  OUT VOID        *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  EFI_LBA         StartLba,

+  IN  UINT16          SectorCount

+  )

+/*++

+  Name:

+  

+        AtaPioDataInExt

+

+  Purpose: 

+  

+        This function is used to send out ATA commands conforms to the 

+        PIO Data In Protocol, supporting ATA/ATAPI-6 standard

+

+        Comparing with ATA-3 data in protocol, we have two differents here:

+        1. Do NOT wait for DRQ clear before sending command into IDE device.(the

+           wait will frequently fail... cause writing function return error)

+           

+        2. Do NOT wait for DRQ clear after all data readed.(the wait greatly 

+           slow down writing performance by 100 times!)

+

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN  OUT     *Buffer

+          buffer contained data transferred from device to host.

+

+        UINT32    IN    ByteCount

+          data size in byte unit of the buffer.

+

+        UINT8     IN    AtaCommand

+          value of the Command Register

+

+        EFI_LBA   IN    StartLba

+          the start LBA of this transaction

+          

+        UINT16    IN    SectorCount

+          the count of sectors to be transfered

+

+  Returns:  

+  

+        EFI_SUCCESS

+          send out the ATA command and device send required

+          data successfully.

+

+        EFI_DEVICE_ERROR

+          command sent failed.

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    AtaCommand - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    SectorCount - add argument and description to function comment

+{

+  UINT8       DevSel;

+  UINT8       SectorCount8;

+  UINT8       LbaLow;

+  UINT8       LbaMid;

+  UINT8       LbaHigh;

+  UINTN       WordCount;

+  UINTN       Increment;

+  UINT16      *Buffer16;

+  EFI_STATUS  Status;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device, set bit6 as 1 to indicate LBA mode is used

+  //

+  DevSel = (UINT8) (IdeDev->Device << 4);

+  DevSel |= 0x40;

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    DevSel

+    );

+

+  //

+  // Wait for DRDY singnal asserting. ATAPI device needn't wait

+  //

+  if ( (IdeDev->Type == IdeHardDisk)  ||

+        (IdeDev->Type == Ide48bitAddressingHardDisk)) {

+

+    Status = DRDYReady (IdeDev, ATATIMEOUT);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  //

+  // Fill feature register if needed

+  //

+  if (AtaCommand == SET_FEATURES_CMD) {

+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);

+  }

+

+  //

+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.

+  //

+  SectorCount8 = (UINT8) (SectorCount >> 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  SectorCount8 = (UINT8) SectorCount;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  //

+  // Fill the start LBA registers, which are also two-byte FIFO

+  //

+  LbaLow  = (UINT8) RShiftU64 (StartLba, 24);

+  LbaMid  = (UINT8) RShiftU64 (StartLba, 32);

+  LbaHigh = (UINT8) RShiftU64 (StartLba, 40);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  LbaLow  = (UINT8) StartLba;

+  LbaMid  = (UINT8) RShiftU64 (StartLba, 8);

+  LbaHigh = (UINT8) RShiftU64 (StartLba, 16);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  //

+  // Send command via Command Register, invoking the processing of this command

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  Buffer16 = (UINT16 *) Buffer;

+

+  //

+  // According to PIO data in protocol, host can perform a series of reads to

+  // the data register after each time device set DRQ ready;

+  //

+  

+  //

+  // 256 words

+  //

+  Increment = 256;

+

+  //

+  // used to record bytes of currently transfered data

+  //

+  WordCount = 0;

+

+  while (WordCount < ByteCount / 2) {

+    //

+    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.

+    //

+    Status = DRQReady2 (IdeDev, ATATIMEOUT);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Status = CheckErrorStatus (IdeDev);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Get the byte count for one series of read

+    //

+    if ((WordCount + Increment) > ByteCount / 2) {

+      Increment = ByteCount / 2 - WordCount;

+    }

+

+    IDEReadPortWMultiple (

+      IdeDev->PciIo,

+      IdeDev->IoPort->Data,

+      Increment,

+      Buffer16

+      );

+

+    WordCount += Increment;

+    Buffer16 += Increment;

+

+  }

+

+  return CheckErrorStatus (IdeDev);

+}

+

+EFI_STATUS

+AtaPioDataOutExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  EFI_LBA         StartLba,

+  IN  UINT16          SectorCount

+  )

+/*++

+  Name:

+  

+        AtaPioDataOutExt

+

+  Purpose: 

+  

+        This function is used to send out ATA commands conforms to the 

+        PIO Data Out Protocol, supporting ATA/ATAPI-6 standard

+

+        Comparing with ATA-3 data out protocol, we have two differents here:

+        1. Do NOT wait for DRQ clear before sending command into IDE device.(the

+           wait will frequently fail... cause writing function return error)

+           

+        2. Do NOT wait for DRQ clear after all data readed.(the wait greatly 

+           slow down writing performance by 100 times!)

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *Buffer

+          buffer contained data transferred from host to device.

+

+        UINT32    IN    ByteCount

+          data size in byte unit of the buffer.

+

+        UINT8     IN    AtaCommand

+          value of the Command Register

+

+        EFI_LBA   IN    StartLba

+          the start LBA of this transaction

+          

+        UINT16    IN    SectorCount

+          the count of sectors to be transfered

+

+  Returns:  

+  

+        EFI_SUCCESS

+          send out the ATA command and device receive required

+          data successfully.

+

+        EFI_DEVICE_ERROR

+          command sent failed.

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    AtaCommand - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    SectorCount - add argument and description to function comment

+{

+  UINT8       DevSel;

+  UINT8       SectorCount8;

+  UINT8       LbaLow;

+  UINT8       LbaMid;

+  UINT8       LbaHigh;

+  UINTN       WordCount;

+  UINTN       Increment;

+  UINT16      *Buffer16;

+  EFI_STATUS  Status;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device. Set bit6 as 1 to indicate LBA mode is used

+  //

+  DevSel = (UINT8) (IdeDev->Device << 4);

+  DevSel |= 0x40;

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    DevSel

+    );

+

+  //

+  // Wait for DRDY singnal asserting.

+  //

+  Status = DRDYReady (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+     

+  //

+  // Fill feature register if needed

+  //

+  if (AtaCommand == SET_FEATURES_CMD) {

+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);

+  }

+

+  //

+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.

+  //

+  SectorCount8 = (UINT8) (SectorCount >> 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  SectorCount8 = (UINT8) SectorCount;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  //

+  // Fill the start LBA registers, which are also two-byte FIFO

+  //

+  LbaLow  = (UINT8) RShiftU64 (StartLba, 24);

+  LbaMid  = (UINT8) RShiftU64 (StartLba, 32);

+  LbaHigh = (UINT8) RShiftU64 (StartLba, 40);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  LbaLow  = (UINT8) StartLba;

+  LbaMid  = (UINT8) RShiftU64 (StartLba, 8);

+  LbaHigh = (UINT8) RShiftU64 (StartLba, 16);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  //

+  // Send command via Command Register, invoking the processing of this command

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  Buffer16 = (UINT16 *) Buffer;

+

+  //

+  // According to PIO Data Out protocol, host can perform a series of writes to

+  // the data register after each time device set DRQ ready;

+  //

+  Increment = 256;

+

+  //

+  // used to record bytes of currently transfered data

+  //

+  WordCount = 0;

+

+  while (WordCount < ByteCount / 2) {

+    //

+    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.

+    //

+    Status = DRQReady2 (IdeDev, ATATIMEOUT);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Status = CheckErrorStatus (IdeDev);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Write data into device by one series of writing to data register

+    //

+    if ((WordCount + Increment) > ByteCount / 2) {

+      Increment = ByteCount / 2 - WordCount;

+    }

+

+    IDEWritePortWMultiple (

+      IdeDev->PciIo,

+      IdeDev->IoPort->Data,

+      Increment,

+      Buffer16

+      );

+

+    WordCount += Increment;

+    Buffer16 += Increment;

+

+  }

+  //

+  // while

+  //

+

+  return CheckErrorStatus (IdeDev);

+}

+

+

+VOID

+AtaSMARTSupport (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:  

+        AtaSMARTSupport

+

+  Purpose: 

+

+        Enable SMART of the disk if supported

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure,used

+          to record all the information of the IDE device.

+

+  Returns:  

+  

+        NONE

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  EFI_STATUS        Status;

+  BOOLEAN           SMARTSupported;

+  UINT8             Device;

+  EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;

+  UINT8             DeviceSelect;

+  UINT8             LBAMid;

+  UINT8             LBAHigh;

+

+  //

+  // Detect if the device supports S.M.A.R.T.

+  //

+  if ((IdeDev->pIdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {

+    //

+    // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)

+    //

+    return ;

+  } else {

+    if ((IdeDev->pIdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {

+      //

+      // S.M.A.R.T is not supported by the device

+      //

+      SMARTSupported = FALSE;

+    } else {

+      SMARTSupported = TRUE;

+    }

+  }

+

+  if (!SMARTSupported) {

+    //

+    // Report nonsupport status code

+    //

+    REPORT_STATUS_CODE (

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)

+      );

+  } else {

+    //

+    // Enable this feature

+    //

+    REPORT_STATUS_CODE (

+      EFI_PROGRESS_CODE,

+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)

+      );

+

+    Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);

+    Status = AtaNonDataCommandIn (

+              IdeDev,

+              ATA_SMART_CMD,

+              Device,

+              ATA_SMART_ENABLE_OPERATION,

+              0,

+              0,

+              ATA_CONSTANT_4F,

+              ATA_CONSTANT_C2

+              );

+    //

+    // Detect if this feature is enabled

+    //

+    TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));

+

+    DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);

+    Status = AtaPioDataIn (

+              IdeDev,

+              (VOID *) TmpAtaIdentifyPointer,

+              sizeof (EFI_IDENTIFY_DATA),

+              IDENTIFY_DRIVE_CMD,

+              DeviceSelect,

+              0,

+              0,

+              0,

+              0

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (TmpAtaIdentifyPointer);

+      return ;

+    }

+

+    //

+    // Check if the feature is enabled

+    //

+    if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {

+      //

+      // Read status data

+      //

+      AtaNonDataCommandIn (

+        IdeDev,

+        ATA_SMART_CMD,

+        Device,

+        ATA_SMART_RETURN_STATUS,

+        0,

+        0,

+        ATA_CONSTANT_4F,

+        ATA_CONSTANT_C2

+        );

+      LBAMid  = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);

+      LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);

+

+      if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {

+        //

+        // The threshold exceeded condition is not detected by the device

+        //

+        REPORT_STATUS_CODE (

+              EFI_PROGRESS_CODE,

+              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)

+              );

+

+      } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {

+        //

+        // The threshold exceeded condition is  detected by the device

+        //

+        REPORT_STATUS_CODE (

+              EFI_PROGRESS_CODE,

+              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)

+              );

+      }

+

+    } else {

+      //

+      // Report disabled status code

+      //

+      REPORT_STATUS_CODE (

+            EFI_ERROR_CODE | EFI_ERROR_MINOR,

+            (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)

+            );

+    }

+

+    gBS->FreePool (TmpAtaIdentifyPointer);

+  }

+

+  return ;

+}

+

+EFI_STATUS

+AtaCommandIssueExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT16          Feature,

+  IN  UINT16          SectorCount,

+  IN  EFI_LBA         LbaAddress

+  )

+/*++

+

+Routine Description:

+

+  Send ATA Ext command into device with NON_DATA protocol

+

+Arguments:

+

+  IdeDev      - Standard IDE device private data structure

+  AtaCommand  - The ATA command to be sent

+  Device      - The value in Device register

+  Feature     - The value in Feature register

+  SectorCount - The value in SectorCount register 

+  LbaAddress - The LBA address in 48-bit mode

+

+Returns:

+

+  EFI_SUCCESS      - Reading succeed

+  EFI_DEVICE_ERROR - Error executing commands on this device 

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       SectorCount8;

+  UINT8       Feature8;

+  UINT8       LbaLow;

+  UINT8       LbaMid;

+  UINT8       LbaHigh;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0)

+    );

+

+  //

+  // ATA commands for ATA device must be issued when DRDY is set

+  //

+  Status = DRDYReady (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Pass parameter into device register block

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  //

+  // Fill the feature register, which is a two-byte FIFO. Need write twice.

+  //

+  Feature8 = (UINT8) (Feature >> 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);

+

+  Feature8 = (UINT8) Feature;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);

+

+  //

+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.

+  //

+  SectorCount8 = (UINT8) (SectorCount >> 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  SectorCount8 = (UINT8) SectorCount;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  //

+  // Fill the start LBA registers, which are also two-byte FIFO

+  //

+  LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  LbaLow = (UINT8) LbaAddress;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+

+  LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+

+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  //

+  // Work around for Segate 160G disk writing

+  //

+  gBS->Stall (1800);

+

+  //

+  // Send command via Command Register

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  //

+  // Stall at least 400ns

+  //

+  gBS->Stall (100);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaCommandIssue (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT16          Feature,

+  IN  UINT16          SectorCount,

+  IN  EFI_LBA         LbaAddress

+  )

+/*++

+

+Routine Description:

+

+  Send ATA Ext command into device with NON_DATA protocol

+

+Arguments:

+

+  IdeDev      - Standard IDE device private data structure

+  AtaCommand  - The ATA command to be sent

+  Device      - The value in Device register

+  Feature     - The value in Feature register

+  SectorCount - The value in SectorCount register 

+  LbaAddress - The LBA address in 48-bit mode

+

+Returns:

+

+  EFI_SUCCESS      - Reading succeed

+  EFI_DEVICE_ERROR - Error executing commands on this device 

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       SectorCount8;

+  UINT8       Feature8;

+  UINT8       Lba0;

+  UINT8       Lba1;

+  UINT8       Lba2;

+  UINT8       Lba3;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0)

+    );

+

+  //

+  // ATA commands for ATA device must be issued when DRDY is set

+  //

+  Status = DRDYReady (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Lba0  = (UINT8) LbaAddress;

+  Lba1  = (UINT8) RShiftU64 (LbaAddress, 8);

+  Lba2  = (UINT8) RShiftU64 (LbaAddress, 16);

+  Lba3  = (UINT8) RShiftU64 (LbaAddress, 24);

+  Device |= Lba3;

+

+  //

+  // Pass parameter into device register block

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  //

+  // Fill the feature register, which is a two-byte FIFO. Need write twice.

+  //

+  Feature8 = (UINT8) Feature;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);

+

+  //

+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.

+  //

+  SectorCount8 = (UINT8) SectorCount;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  //

+  // Fill the start LBA registers, which are also two-byte FIFO

+  //

+  

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);

+

+  //

+  // Send command via Command Register

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  //

+  // Stall at least 400ns

+  //

+  gBS->Stall (100);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaUdmaReadExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+  

+        AtaUdmaReadExt

+

+  Purpose: 

+  

+        This function is called by the AtaBlkIoReadBlocks() to perform

+        reading from media in block unit. The function has been enhanced to 

+        support >120GB access and transfer at most 65536 blocks per command

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the destination buffer for the data. 

+

+        EFI_LBA     IN    StartLba

+          The starting logical block address to read from 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+

+        The device status of UDMA operation. If the operation is 

+         successful, return EFI_SUCCESS.

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_DMA_PRD *PrdAddr;

+  IDE_DMA_PRD *UsedPrdAddr;

+  IDE_DMA_PRD *TempPrdAddr;

+  UINT8       RegisterValue;

+  UINT8       Device;

+  UINT64      IoPortForBmic;

+  UINT64      IoPortForBmis;

+  UINT64      IoPortForBmid;

+  EFI_STATUS  Status;

+  UINTN       PrdTableNum;

+  UINTN       ByteCount;

+  UINTN       ByteAvailable;

+  UINT8       *PrdBuffer;

+  UINTN       RemainBlockNum;

+  UINT8       DeviceControl;

+

+  //

+  // Channel and device differential. Select device.

+  //

+  Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);

+

+  //

+  // Enable interrupt to support UDMA and Select device

+  //

+  DeviceControl = 0;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  if (IdePrimary == IdeDev->Channel) {

+    IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;

+    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;

+    IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;

+  } else {

+    if (IdeSecondary == IdeDev->Channel) {

+      IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;

+      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;

+      IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;

+    } else {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  RemainBlockNum = NumberOfBlocks;

+  while (RemainBlockNum > 0) {

+

+    if (RemainBlockNum >= MAX_DMA_EXT_COMMAND_SECTORS) {

+      //

+      //  SectorCount is used to record the number of sectors to be read

+      //  Max 65536 sectors can be transfered at a time.

+      //

+      NumberOfBlocks = MAX_DMA_EXT_COMMAND_SECTORS;

+      RemainBlockNum -= MAX_DMA_EXT_COMMAND_SECTORS;

+    } else {

+      NumberOfBlocks  = (UINT16) RemainBlockNum;

+      RemainBlockNum  = 0;

+    }

+

+    //

+    // Calculate the number of PRD table to make sure the memory region

+    // not cross 64K boundary

+    //

+    ByteCount   = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    PrdTableNum = ((ByteCount >> 16) + 1) + 1;

+

+    //

+    // Build PRD table

+    //

+    PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));

+

+    //

+    // To make sure PRD is allocated in one 64K page

+    //

+    if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {

+      UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);

+    } else {

+      if ((UINTN) PrdAddr & 0x03) {

+        UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);

+      } else {

+        UsedPrdAddr = PrdAddr;

+      }

+    }

+

+    //

+    // Build the PRD table

+    //

+    PrdBuffer   = DataBuffer;

+    TempPrdAddr = UsedPrdAddr;

+    while (TRUE) {

+

+      ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);

+

+      if (ByteCount <= ByteAvailable) {

+        TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+        TempPrdAddr->ByteCount      = (UINT16) ByteCount;

+        TempPrdAddr->EndOfTable     = 0x8000;

+        break;

+      }

+

+      TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+      TempPrdAddr->ByteCount      = (UINT16) ByteAvailable;

+

+      ByteCount -= ByteAvailable;

+      PrdBuffer += ByteAvailable;

+      TempPrdAddr++;

+    }

+  

+    //

+    // Set the base address to BMID register

+    //

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint32,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmid,

+                        1,

+                        &UsedPrdAddr

+                        );

+

+    //

+    // Set BMIC register to identify the operation direction

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIC_nREAD;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Read BMIS register and clear ERROR and INTR bit

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIS_INTERRUPT | BMIS_ERROR;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Issue READ DMA EXT command

+    //

+    Status = AtaCommandIssueExt (

+              IdeDev,

+              READ_DMA_EXT_CMD,

+              Device,

+              0,

+              (UINT16) NumberOfBlocks,

+              StartLba

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (PrdAddr);

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIC_START;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Check the INTERRUPT and ERROR bit of BMIS

+    //

+    while (TRUE) {

+

+      IdeDev->PciIo->Io.Read (

+                          IdeDev->PciIo,

+                          EfiPciIoWidthUint8,

+                          EFI_PCI_IO_PASS_THROUGH_BAR,

+                          IoPortForBmis,

+                          1,

+                          &RegisterValue

+                          );

+      if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {

+        if (RegisterValue & BMIS_ERROR) {

+          gBS->FreePool (PrdAddr);

+          return EFI_DEVICE_ERROR;

+        }

+        break;

+      }

+

+      gBS->Stall (1000);

+    }

+

+    gBS->FreePool (PrdAddr);

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue &= ~((UINT8) BMIC_START);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    if (RegisterValue & BMIS_ERROR) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    StartLba += NumberOfBlocks;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaUdmaRead (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+  

+        AtaUdmaRead

+

+  Purpose: 

+  

+        This function is called by the AtaBlkIoReadBlocks() to perform

+        reading from media in block unit. The function has been enhanced to 

+        support >120GB access and transfer at most 65536 blocks per command

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the destination buffer for the data. 

+

+        EFI_LBA     IN    StartLba

+          The starting logical block address to read from 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+

+        The device status of UDMA operation. If the operation is 

+         successful, return EFI_SUCCESS.

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_DMA_PRD *PrdAddr;

+  IDE_DMA_PRD *UsedPrdAddr;

+  IDE_DMA_PRD *TempPrdAddr;

+  UINT8       RegisterValue;

+  UINT8       Device;

+  UINT64      IoPortForBmic;

+  UINT64      IoPortForBmis;

+  UINT64      IoPortForBmid;

+  EFI_STATUS  Status;

+  UINTN       PrdTableNum;

+  UINTN       ByteCount;

+  UINTN       ByteAvailable;

+  UINT8       *PrdBuffer;

+  UINTN       RemainBlockNum;

+  UINT8       DeviceControl;

+

+  //

+  // Channel and device differential

+  //

+  Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);

+

+  //

+  // Enable interrupt to support UDMA and Select device

+  //

+  DeviceControl = 0;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  if (IdePrimary == IdeDev->Channel) {

+    IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;

+    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;

+    IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;

+  } else {

+    if (IdeSecondary == IdeDev->Channel) {

+      IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;

+      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;

+      IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;

+    } else {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  RemainBlockNum = NumberOfBlocks;

+  while (RemainBlockNum > 0) {

+

+    if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {

+      //

+      //  SectorCount is used to record the number of sectors to be read

+      //  Max 256 sectors can be transfered at a time.

+      //

+      NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;

+      RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;

+    } else {

+      NumberOfBlocks  = (UINT16) RemainBlockNum;

+      RemainBlockNum  = 0;

+    }

+

+    //

+    // Calculate the number of PRD table to make sure the memory region

+    // not cross 64K boundary

+    //

+    ByteCount   = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    PrdTableNum = ((ByteCount >> 16) + 1) + 1;

+

+    //

+    // Build PRD table

+    //

+    PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));

+    //

+    // To make sure PRD is allocated in one 64K page

+    //

+    if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {

+      UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);

+    } else {

+      if ((UINTN) PrdAddr & 0x03) {

+        UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);

+      } else {

+        UsedPrdAddr = PrdAddr;

+      }

+    }

+

+    //

+    // Build the PRD table

+    //

+    PrdBuffer   = DataBuffer;

+    TempPrdAddr = UsedPrdAddr;

+    while (TRUE) {

+

+      ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);

+

+      if (ByteCount <= ByteAvailable) {

+        TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+        TempPrdAddr->ByteCount      = (UINT16) ByteCount;

+        TempPrdAddr->EndOfTable     = 0x8000;

+        break;

+      }

+

+      TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+      TempPrdAddr->ByteCount      = (UINT16) ByteAvailable;

+

+      ByteCount -= ByteAvailable;

+      PrdBuffer += ByteAvailable;

+      TempPrdAddr++;

+    }

+

+    //

+    // Set the base address to BMID register

+    //

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint32,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmid,

+                        1,

+                        &UsedPrdAddr

+                        );

+

+    //

+    // Set BMIC register to identify the operation direction

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIC_nREAD;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Read BMIS register and clear ERROR and INTR bit

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Issue READ DMA command

+    //

+    Status = AtaCommandIssue (

+              IdeDev,

+              READ_DMA_CMD,

+              Device,

+              0,

+              (UINT16) NumberOfBlocks,

+              StartLba

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (PrdAddr);

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIC_START;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Check the INTERRUPT and ERROR bit of BMIS

+    //

+    while (TRUE) {

+

+      IdeDev->PciIo->Io.Read (

+                          IdeDev->PciIo,

+                          EfiPciIoWidthUint8,

+                          EFI_PCI_IO_PASS_THROUGH_BAR,

+                          IoPortForBmis,

+                          1,

+                          &RegisterValue

+                          );

+      if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {

+        if (RegisterValue & BMIS_ERROR) {

+          gBS->FreePool (PrdAddr);

+          return EFI_DEVICE_ERROR;

+        }

+        break;

+      }

+

+      gBS->Stall (1000);

+    }

+

+    gBS->FreePool (PrdAddr);

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue &= ~((UINT8) BMIC_START);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    if (RegisterValue & BMIS_ERROR) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    StartLba += NumberOfBlocks;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaUdmaWriteExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+  

+        AtaUdmaWriteExt

+

+  Purpose: 

+  

+        This function is called by the AtaBlkIoWriteBlocks() to perform

+        writing to media in block unit. The function has been enhanced to 

+        support >120GB access and transfer at most 65536 blocks per command

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the source buffer for the data. 

+

+        EFI_LBA     IN    StartLba

+          The starting logical block address to write to 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+

+        The device status of UDMA operation. If the operation is 

+         successful, return EFI_SUCCESS.

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_DMA_PRD *PrdAddr;

+  IDE_DMA_PRD *UsedPrdAddr;

+  IDE_DMA_PRD *TempPrdAddr;

+  UINT8       RegisterValue;

+  UINT8       Device;

+  UINT64      IoPortForBmic;

+  UINT64      IoPortForBmis;

+  UINT64      IoPortForBmid;

+  EFI_STATUS  Status;

+  UINTN       PrdTableNum;

+  UINTN       ByteCount;

+  UINTN       ByteAvailable;

+  UINT8       *PrdBuffer;

+  UINTN       RemainBlockNum;

+  UINT8       DeviceControl;

+

+  //

+  // Channel and device differential

+  //

+  Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);

+

+  //

+  // Enable interrupt to support UDMA and Select device

+  //

+  DeviceControl = 0;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  if (IdePrimary == IdeDev->Channel) {

+    IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;

+    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;

+    IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;

+  } else {

+    if (IdeSecondary == IdeDev->Channel) {

+      IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;

+      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;

+      IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;

+    } else {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  RemainBlockNum = NumberOfBlocks;

+  while (RemainBlockNum > 0) {

+

+    if (RemainBlockNum >= MAX_DMA_EXT_COMMAND_SECTORS) {

+      //

+      //  SectorCount is used to record the number of sectors to be read

+      //  Max 65536 sectors can be transfered at a time.

+      //

+      NumberOfBlocks = MAX_DMA_EXT_COMMAND_SECTORS;

+      RemainBlockNum -= MAX_DMA_EXT_COMMAND_SECTORS;

+    } else {

+      NumberOfBlocks  = (UINT16) RemainBlockNum;

+      RemainBlockNum  = 0;

+    }

+

+    //

+    // Calculate the number of PRD table to make sure the memory region

+    // not cross 64K boundary

+    //

+    ByteCount   = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    PrdTableNum = ((ByteCount >> 16) + 1) + 1;

+

+    //

+    // Build PRD table

+    //

+    PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));

+    //

+    // To make sure PRD is allocated in one 64K page

+    //

+    if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {

+      UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);

+    } else {

+      if ((UINTN) PrdAddr & 0x03) {

+        UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);

+      } else {

+        UsedPrdAddr = PrdAddr;

+      }

+    }

+

+    //

+    // Build the PRD table

+    //

+    PrdBuffer   = DataBuffer;

+    TempPrdAddr = UsedPrdAddr;

+    while (TRUE) {

+

+      ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);

+

+      if (ByteCount <= ByteAvailable) {

+        TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+        TempPrdAddr->ByteCount      = (UINT16) ByteCount;

+        TempPrdAddr->EndOfTable     = 0x8000;

+        break;

+      }

+

+      TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+      TempPrdAddr->ByteCount      = (UINT16) ByteAvailable;

+

+      ByteCount -= ByteAvailable;

+      PrdBuffer += ByteAvailable;

+      TempPrdAddr++;

+    }

+  

+    //

+    // Set the base address to BMID register

+    //

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint32,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmid,

+                        1,

+                        &UsedPrdAddr

+                        );

+

+    //

+    // Set BMIC register to identify the operation direction

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+    //

+    // 0000 1000

+    //

+    RegisterValue &= ~((UINT8) BMIC_nREAD);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Read BMIS register and clear ERROR and INTR bit

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Issue WRITE DMA EXT command

+    //

+    Status = AtaCommandIssueExt (

+              IdeDev,

+              WRITE_DMA_EXT_CMD,

+              Device,

+              0,

+              (UINT16) NumberOfBlocks,

+              StartLba

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (PrdAddr);

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIC_START;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Check the INTERRUPT and ERROR bit of BMIS

+    //

+    while (TRUE) {

+

+      IdeDev->PciIo->Io.Read (

+                          IdeDev->PciIo,

+                          EfiPciIoWidthUint8,

+                          EFI_PCI_IO_PASS_THROUGH_BAR,

+                          IoPortForBmis,

+                          1,

+                          &RegisterValue

+                          );

+      if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {

+        if (RegisterValue & BMIS_ERROR) {

+          gBS->FreePool (PrdAddr);

+          return EFI_DEVICE_ERROR;

+        }

+        break;

+      }

+

+      gBS->Stall (1000);

+    }

+

+    gBS->FreePool (PrdAddr);

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue &= ~((UINT8) BMIC_START);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    StartLba += NumberOfBlocks;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaUdmaWrite (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+  

+        AtaUdmaWrite

+

+  Purpose: 

+  

+        This function is called by the AtaBlkIoWriteBlocks() to perform

+        writing to media in block unit. The function has been enhanced to 

+        support >120GB access and transfer at most 65536 blocks per command

+

+  Parameters:

+  

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *DataBuffer

+          A pointer to the source buffer for the data. 

+

+        EFI_LBA     IN    StartLba

+          The starting logical block address to write to 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+

+        The device status of UDMA operation. If the operation is 

+         successful, return EFI_SUCCESS.

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DataBuffer - add argument and description to function comment

+// TODO:    StartLba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_DMA_PRD *PrdAddr;

+  IDE_DMA_PRD *UsedPrdAddr;

+  IDE_DMA_PRD *TempPrdAddr;

+  UINT8       RegisterValue;

+  UINT8       Device;

+  UINT64      IoPortForBmic;

+  UINT64      IoPortForBmis;

+  UINT64      IoPortForBmid;

+  EFI_STATUS  Status;

+  UINTN       PrdTableNum;

+  UINTN       ByteCount;

+  UINTN       ByteAvailable;

+  UINT8       *PrdBuffer;

+  UINTN       RemainBlockNum;

+  UINT8       DeviceControl;

+

+  //

+  // Channel and device differential

+  //

+  Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);

+

+  //

+  // Enable interrupt to support UDMA

+  //

+  DeviceControl = 0;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  if (IdePrimary == IdeDev->Channel) {

+    IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;

+    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;

+    IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;

+  } else {

+    if (IdeSecondary == IdeDev->Channel) {

+      IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;

+      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;

+      IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;

+    } else {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  RemainBlockNum = NumberOfBlocks;

+  while (RemainBlockNum > 0) {

+

+    if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {

+      //

+      //  SectorCount is used to record the number of sectors to be read

+      //  Max 256 sectors can be transfered at a time.

+      //

+      NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;

+      RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;

+    } else {

+      NumberOfBlocks  = (UINT16) RemainBlockNum;

+      RemainBlockNum  = 0;

+    }

+

+    //

+    // Calculate the number of PRD table to make sure the memory region

+    // not cross 64K boundary

+    //

+    ByteCount   = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    PrdTableNum = ((ByteCount >> 16) + 1) + 1;

+

+    //

+    // Build PRD table

+    //

+    PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));

+

+    //

+    // To make sure PRD is allocated in one 64K page

+    //

+    if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {

+      UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);

+    } else {

+      if ((UINTN) PrdAddr & 0x03) {

+        UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);

+      } else {

+        UsedPrdAddr = PrdAddr;

+      }

+    }

+

+    //

+    // Build the PRD table

+    //

+    PrdBuffer   = DataBuffer;

+    TempPrdAddr = UsedPrdAddr;

+    while (TRUE) {

+

+      ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);

+

+      if (ByteCount <= ByteAvailable) {

+        TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+        TempPrdAddr->ByteCount      = (UINT16) ByteCount;

+        TempPrdAddr->EndOfTable     = 0x8000;

+        break;

+      }

+

+      TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);

+      TempPrdAddr->ByteCount      = (UINT16) ByteAvailable;

+

+      ByteCount -= ByteAvailable;

+      PrdBuffer += ByteAvailable;

+      TempPrdAddr++;

+    }

+  

+    //

+    // Set the base address to BMID register

+    //

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint32,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmid,

+                        1,

+                        &UsedPrdAddr

+                        );

+

+    //

+    // Set BMIC register to identify the operation direction

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+    //

+    // 0000 1000

+    //

+    RegisterValue &= ~((UINT8) BMIC_nREAD);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Read BMIS register and clear ERROR and INTR bit

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmis,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Issue WRITE DMA command

+    //

+    Status = AtaCommandIssue (

+              IdeDev,

+              WRITE_DMA_CMD,

+              Device,

+              0,

+              (UINT16) NumberOfBlocks,

+              StartLba

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (PrdAddr);

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue |= BMIC_START;

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    //

+    // Check the INTERRUPT and ERROR bit of BMIS

+    //

+    while (TRUE) {

+

+      IdeDev->PciIo->Io.Read (

+                          IdeDev->PciIo,

+                          EfiPciIoWidthUint8,

+                          EFI_PCI_IO_PASS_THROUGH_BAR,

+                          IoPortForBmis,

+                          1,

+                          &RegisterValue

+                          );

+      if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {

+        if (RegisterValue & BMIS_ERROR) {

+          gBS->FreePool (PrdAddr);

+          return EFI_DEVICE_ERROR;

+        }

+        break;

+      }

+

+      gBS->Stall (1000);

+    }

+

+    gBS->FreePool (PrdAddr);

+

+    //

+    // Set START bit of BMIC register

+    //

+    IdeDev->PciIo->Io.Read (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    RegisterValue &= ~((UINT8) BMIC_START);

+

+    IdeDev->PciIo->Io.Write (

+                        IdeDev->PciIo,

+                        EfiPciIoWidthUint8,

+                        EFI_PCI_IO_PASS_THROUGH_BAR,

+                        IoPortForBmic,

+                        1,

+                        &RegisterValue

+                        );

+

+    DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;

+    StartLba += NumberOfBlocks;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c
new file mode 100644
index 0000000..fa004e3
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c
@@ -0,0 +1,2591 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  atapi.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#include "idebus.h"

+

+STATIC

+EFI_STATUS

+LS120GetMediaStatus (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        LS120GetMediaStatus

+

+  Purpose: 

+        This function is used to get the current status of the media residing

+        in the LS-120 drive or ZIP drive. The media status is returned in the 

+        Error Status.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          The media status is achieved successfully and the media

+          can be read/written.             

+    

+        EFI_DEVICE_ERROR

+          Get Media Status Command is failed.

+

+        EFI_NO_MEDIA

+          There is no media in the drive.

+

+        EFI_WRITE_PROTECTED

+          The media is writing protected. 

+

+  Notes:                

+        This function must be called after the LS120EnableMediaStatus() 

+        with second parameter set to TRUE 

+        (means enable media status notification) is called.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  UINT8       DeviceSelect;

+  UINT8       StatusValue;

+  EFI_STATUS  EfiStatus;

+  //

+  // Poll Alternate Register for BSY clear within timeout.

+  //

+  EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (EfiStatus)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device via Device/Head Register.

+  //

+  DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);

+

+  //

+  // Poll Alternate Register for DRDY set within timeout.

+  // After device is selected, DRDY set indicates the device is ready to

+  // accept command.

+  //

+  EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (EfiStatus)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Get Media Status Command is sent

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA);

+

+  //

+  // BSY bit will clear after command is complete.

+  //

+  EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (EfiStatus)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // the media status is returned by the command in the ERROR register

+  //

+  StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+

+  if (StatusValue & bit1) {

+    return EFI_NO_MEDIA;

+  }

+

+  if (StatusValue & bit6) {

+    return EFI_WRITE_PROTECTED;

+  } else {

+    return EFI_SUCCESS;

+  }

+}

+

+STATIC

+EFI_STATUS

+LS120EnableMediaStatus (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  BOOLEAN         Enable

+  )

+/*++

+  Name:

+        LS120EnableMediaStatus

+

+  Purpose: 

+        This function is used to send Enable Media Status Notification Command

+        or Disable Media Status Notification Command.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        BOOLEAN     IN    Enable

+          a flag that indicates whether enable or disable media

+          status notification.

+

+  Returns:  

+        EFI_SUCCESS

+          If command completes successfully.

+

+        EFI_DEVICE_ERROR

+          If command failed.

+

+

+  Notes:                

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Enable - add argument and description to function comment

+{

+  UINT8       DeviceSelect;

+  EFI_STATUS  Status;

+

+  //

+  // Poll Alternate Register for BSY clear within timeout.

+  //

+  Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device via Device/Head Register.

+  //

+  DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);

+

+  //

+  // Poll Alternate Register for DRDY set within timeout.

+  // After device is selected, DRDY set indicates the device is ready to

+  // accept command.

+  //

+  Status = DRDYReady2 (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (Enable) {

+    //

+    // 0x95: Enable media status notification

+    //

+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95);

+  } else {

+    //

+    // 0x31: Disable media status notification

+    //

+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31);

+  }

+  //

+  // Set Feature Command is sent

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF);

+

+  //

+  // BSY bit will clear after command is complete.

+  //

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ATAPIIdentify (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        ATAPIIdentify

+

+

+  Purpose: 

+        This function is called by DiscoverIdeDevice() during its device

+        identification.

+

+        Its main purpose is to get enough information for the device media

+        to fill in the Media data structure of the Block I/O Protocol interface.

+

+        There are 5 steps to reach such objective:

+

+        1. Sends out the ATAPI Identify Command to the specified device. 

+           Only ATAPI device responses to this command. If the command succeeds,

+           it returns the Identify data structure which filled with information 

+           about the device. Since the ATAPI device contains removable media, 

+           the only meaningful information is the device module name.

+

+        2. Sends out ATAPI Inquiry Packet Command to the specified device.

+           This command will return inquiry data of the device, which contains

+           the device type information.

+

+        3. Allocate sense data space for future use. We don't detect the media

+           presence here to improvement boot performance, especially when CD 

+           media is present. The media detection will be performed just before

+           each BLK_IO read/write

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          Identify ATAPI device successfully.

+

+        EFI_DEVICE_ERROR

+          ATAPI Identify Device Command failed or device type 

+          is not supported by this IDE driver.

+

+  Notes:

+        Parameter "IdeDev" will be updated in this function.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  EFI_IDENTIFY_DATA *AtapiIdentifyPointer;

+  UINT8             DeviceSelect;

+  EFI_STATUS        Status;

+

+  //

+  // device select bit

+  //

+  DeviceSelect          = 0;

+  DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);

+

+  AtapiIdentifyPointer  = AllocatePool (sizeof (EFI_IDENTIFY_DATA));

+  if (AtapiIdentifyPointer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Send ATAPI Identify Command to get IDENTIFY data.

+  //

+  Status = AtaPioDataIn (

+            IdeDev,

+            (VOID *) AtapiIdentifyPointer,

+            sizeof (EFI_IDENTIFY_DATA),

+            ATAPI_IDENTIFY_DEVICE_CMD,

+            DeviceSelect,

+            0,

+            0,

+            0,

+            0

+            );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (AtapiIdentifyPointer);

+    return EFI_DEVICE_ERROR;

+  }

+

+  IdeDev->pIdData = AtapiIdentifyPointer;

+  PrintAtaModuleName (IdeDev);

+

+  //

+  // Send ATAPI Inquiry Packet Command to get INQUIRY data.

+  //

+  Status = AtapiInquiry (IdeDev);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (IdeDev->pIdData);

+    //

+    // Make sure the pIdData will not be freed again.

+    //

+    IdeDev->pIdData = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Get media removable info from INQUIRY data.

+  //

+  IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80);

+

+  //

+  // Identify device type via INQUIRY data.

+  //

+  switch (IdeDev->pInquiryData->peripheral_type & 0x1f) {

+

+  //

+  // Magnetic Disk

+  //

+  case 0x00:

+

+    //

+    // device is LS120 or ZIP drive.

+    //

+    IdeDev->Type = IdeMagnetic;

+

+    IdeDev->BlkIo.Media->MediaId      = 0;

+    //

+    // Give initial value

+    //

+    IdeDev->BlkIo.Media->MediaPresent = FALSE;

+

+    IdeDev->BlkIo.Media->LastBlock  = 0;

+    IdeDev->BlkIo.Media->BlockSize  = 0x200;

+    break;

+

+  //

+  // CD-ROM

+  //

+  case 0x05:

+

+    IdeDev->Type                      = IdeCdRom;

+    IdeDev->BlkIo.Media->MediaId      = 0;

+    //

+    // Give initial value

+    //

+    IdeDev->BlkIo.Media->MediaPresent = FALSE;

+

+    IdeDev->BlkIo.Media->LastBlock  = 0;

+    IdeDev->BlkIo.Media->BlockSize  = 0x800;

+    IdeDev->BlkIo.Media->ReadOnly   = TRUE;

+    break;

+

+  //

+  // Tape

+  //

+  case 0x01:

+

+  //

+  // WORM

+  //

+  case 0x04:

+  

+  //

+  // Optical

+  //

+  case 0x07:

+

+  default:

+    IdeDev->Type = IdeUnknown;

+    gBS->FreePool (IdeDev->pIdData);

+    gBS->FreePool (IdeDev->pInquiryData);

+    //

+    // Make sure the pIdData and pInquiryData will not be freed again.

+    //

+    IdeDev->pIdData       = NULL;

+    IdeDev->pInquiryData  = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // original sense data numbers

+  //

+  IdeDev->SenseDataNumber = 20;

+

+  IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (REQUEST_SENSE_DATA));

+  if (IdeDev->SenseData == NULL) {

+    gBS->FreePool (IdeDev->pIdData);

+    gBS->FreePool (IdeDev->pInquiryData);

+    //

+    // Make sure the pIdData and pInquiryData will not be freed again.

+    //

+    IdeDev->pIdData       = NULL;

+    IdeDev->pInquiryData  = NULL;

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtapiInquiry (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        AtapiInquiry

+

+  Purpose: 

+        Sends out ATAPI Inquiry Packet Command to the specified device.

+        This command will return INQUIRY data of the device.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          Inquiry command completes successfully.

+

+        EFI_DEVICE_ERROR

+          Inquiry command failed.

+  Notes:

+        Parameter "IdeDev" will be updated in this function.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  ATAPI_PACKET_COMMAND  Packet;

+  EFI_STATUS            Status;

+  INQUIRY_DATA          *InquiryData;

+

+  //

+  // prepare command packet for the ATAPI Inquiry Packet Command.

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.Inquiry.opcode             = INQUIRY;

+  Packet.Inquiry.page_code          = 0;

+  Packet.Inquiry.allocation_length  = sizeof (INQUIRY_DATA);

+

+  InquiryData                       = AllocatePool (sizeof (INQUIRY_DATA));

+  if (InquiryData == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Send command packet and get requested Inquiry data.

+  //

+  Status = AtapiPacketCommandIn (

+            IdeDev,

+            &Packet,

+            (UINT16 *) InquiryData,

+            sizeof (INQUIRY_DATA),

+            ATAPITIMEOUT

+            );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (InquiryData);

+    return EFI_DEVICE_ERROR;

+  }

+

+  IdeDev->pInquiryData = InquiryData;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtapiPacketCommandIn (

+  IN  IDE_BLK_IO_DEV        *IdeDev,

+  IN  ATAPI_PACKET_COMMAND  *Packet,

+  IN  UINT16                *Buffer,

+  IN  UINT32                ByteCount,

+  IN  UINTN                 TimeOut

+  )

+/*++

+  Name:

+        AtapiPacketCommandIn

+

+  Purpose: 

+        This function is used to send out ATAPI commands conforms to the 

+        Packet Command with PIO Data In Protocol.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        ATAPI_PACKET_COMMAND  IN  *Packet

+          pointer pointing to ATAPI_PACKET_COMMAND data structure

+          which contains the contents of the command.     

+              

+        UINT16      IN    *Buffer

+          buffer contained data transferred from device to host.

+

+        UINT32      IN    ByteCount

+          data size in byte unit of the buffer.

+

+        UINTN     IN    TimeOut

+          this parameter is used to specify the timeout 

+          value for the PioReadWriteData() function. 

+

+  Returns:  

+        EFI_SUCCESS

+          send out the ATAPI packet command successfully 

+          and device sends data successfully.

+

+        EFI_DEVICE_ERROR

+          the device failed to send data.                 

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Packet - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    TimeOut - add argument and description to function comment

+{

+  UINT16      *CommandIndex;

+  EFI_STATUS  Status;

+  UINT32      Count;

+

+  //

+  // Set all the command parameters by fill related registers.

+  // Before write to all the following registers, BSY and DRQ must be 0.

+  //

+  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Select device via Device/Head Register.

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | DEFAULT_CMD)  // DEFAULT_CMD: 0xa0 (1010,0000)

+    );

+

+  //

+  // No OVL; No DMA

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);

+

+  //

+  // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device

+  // determine how many data should be transferred.

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->CylinderLsb,

+    (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)

+    );

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->CylinderMsb,

+    (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)

+    );

+

+  //

+  //  DEFAULT_CTL:0x0a (0000,1010)

+  //  Disable interrupt

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DEFAULT_CTL);

+

+  //

+  // Send Packet command to inform device

+  // that the following data bytes are command packet.

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, PACKET_CMD);

+

+  Status = DRQReady (IdeDev, ATAPITIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Send out command packet

+  //

+  CommandIndex = Packet->Data16;

+  for (Count = 0; Count < 6; Count++, CommandIndex++) {

+

+    IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);

+    gBS->Stall (10);

+  }

+

+  //

+  // call PioReadWriteData() function to get

+  // requested transfer data form device.

+  //

+  return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);

+}

+

+EFI_STATUS

+AtapiPacketCommandOut (

+  IN  IDE_BLK_IO_DEV        *IdeDev,

+  IN  ATAPI_PACKET_COMMAND  *Packet,

+  IN  UINT16                *Buffer,

+  IN  UINT32                ByteCount,

+  IN  UINTN                 TimeOut

+  )

+/*++

+  Name:

+        AtapiPacketCommandOut

+

+  Purpose: 

+        This function is used to send out ATAPI commands conforms to the 

+        Packet Command with PIO Data Out Protocol.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        ATAPI_PACKET_COMMAND  IN  *Packet

+          pointer pointing to ATAPI_PACKET_COMMAND data structure

+          which contains the contents of the command.

+

+        VOID      IN    *Buffer

+          buffer contained data transferred from host to device.

+

+        UINT32      IN    ByteCount

+          data size in byte unit of the buffer.

+

+        UINTN     IN    TimeOut

+          this parameter is used to specify the timeout 

+          value for the PioReadWriteData() function. 

+

+  Returns:  

+        EFI_SUCCESS

+          send out the ATAPI packet command successfully 

+          and device received data successfully.

+

+        EFI_DEVICE_ERROR

+          the device failed to send data. 

+

+  Notes:

+  

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Packet - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    TimeOut - add argument and description to function comment

+{

+  UINT16      *CommandIndex;

+  EFI_STATUS  Status;

+  UINT32      Count;

+

+  //

+  // set all the command parameters

+  // Before write to all the following registers, BSY and DRQ must be 0.

+  //

+  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Select device via Device/Head Register.

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | DEFAULT_CMD)   // DEFAULT_CMD: 0xa0 (1010,0000)

+    );

+

+  //

+  // No OVL; No DMA

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);

+

+  //

+  // set the transfersize to MAX_ATAPI_BYTE_COUNT to

+  // let the device determine how many data should be transferred.

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->CylinderLsb,

+    (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)

+    );

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->CylinderMsb,

+    (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)

+    );

+

+  //

+  //  DEFAULT_CTL:0x0a (0000,1010)

+  //  Disable interrupt

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DEFAULT_CTL);

+

+  //

+  // Send Packet command to inform device

+  // that the following data bytes are command packet.

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, PACKET_CMD);

+

+  Status = DRQReady2 (IdeDev, ATAPITIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Send out command packet

+  //

+  CommandIndex = Packet->Data16;

+  for (Count = 0; Count < 6; Count++, CommandIndex++) {

+    IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);

+    gBS->Stall (10);

+  }

+

+  //

+  // call PioReadWriteData() function to send requested transfer data to device.

+  //

+  return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);

+}

+

+EFI_STATUS

+PioReadWriteData (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT16          *Buffer,

+  IN  UINT32          ByteCount,

+  IN  BOOLEAN         Read,

+  IN  UINTN           TimeOut

+  )

+/*++

+  Name:

+        PioReadWriteData

+

+  Purpose: 

+        This function is called by either AtapiPacketCommandIn() or 

+        AtapiPacketCommandOut(). It is used to transfer data between

+        host and device. The data direction is specified by the fourth

+        parameter.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *Buffer

+          buffer contained data transferred between host and device.

+

+        UINT32      IN    ByteCount

+          data size in byte unit of the buffer.

+

+        BOOLEAN     IN    Read

+          flag used to determine the data transfer direction.

+          Read equals 1, means data transferred from device to host;

+          Read equals 0, means data transferred from host to device.

+

+        UINTN     IN    TimeOut

+          timeout value for wait DRQ ready before each data 

+          stream's transfer.

+

+  Returns:  

+        EFI_SUCCESS

+          data is transferred successfully.  

+

+        EFI_DEVICE_ERROR

+          the device failed to transfer data.                 

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    ByteCount - add argument and description to function comment

+// TODO:    Read - add argument and description to function comment

+// TODO:    TimeOut - add argument and description to function comment

+{

+  //

+  // required transfer data in word unit.

+  //

+  UINT32      RequiredWordCount;

+

+  //

+  // actual transfer data in word unit.

+  //

+  UINT32      ActualWordCount;

+  UINT32      WordCount;

+  EFI_STATUS  Status;

+  UINT16      *PtrBuffer;

+

+  //

+  // containing status byte read from Status Register.

+  //

+  UINT8       StatusRegister;

+

+  //

+  // No data transfer is premitted.

+  //

+  if (ByteCount == 0) {

+    return EFI_SUCCESS;

+  }

+  //

+  // for performance, we assert the ByteCount is an even number

+  // which is actually a resonable assumption  

+  ASSERT((ByteCount%2) == 0);

+  

+  PtrBuffer         = Buffer;

+  RequiredWordCount = ByteCount / 2;

+  //

+  // ActuralWordCount means the word count of data really transferred.

+  //

+  ActualWordCount = 0;

+

+  while (ActualWordCount < RequiredWordCount) {

+    

+    //

+    // before each data transfer stream, the host should poll DRQ bit ready,

+    // to see whether indicates device is ready to transfer data.

+    //

+    Status = DRQReady2 (IdeDev, TimeOut);

+    if (EFI_ERROR (Status)) {

+      return CheckErrorStatus (IdeDev);

+    }

+    

+    //

+    // read Status Register will clear interrupt

+    //

+    StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+

+    //

+    // get current data transfer size from Cylinder Registers.

+    //

+    WordCount =

+      (

+        (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8) |

+        IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb)

+      ) & 0xffff;

+    WordCount /= 2;

+

+    WordCount = EFI_MIN (WordCount, (RequiredWordCount - ActualWordCount));

+

+    if (Read) {

+      IDEReadPortWMultiple (

+        IdeDev->PciIo,

+        IdeDev->IoPort->Data,

+        WordCount,

+        PtrBuffer

+        );

+    } else {

+      IDEWritePortWMultiple (

+        IdeDev->PciIo,

+        IdeDev->IoPort->Data,

+        WordCount,

+        PtrBuffer

+        );

+    }

+

+    PtrBuffer += WordCount;

+    ActualWordCount += WordCount;

+  }

+

+  //

+  // After data transfer is completed, normally, DRQ bit should clear.

+  //

+  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // read status register to check whether error happens.

+  //

+  return CheckErrorStatus (IdeDev);

+}

+

+EFI_STATUS

+AtapiTestUnitReady (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        AtapiTestUnitReady

+

+  Purpose: 

+        Sends out ATAPI Test Unit Ready Packet Command to the specified device

+        to find out whether device is accessible.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          device is accessible.

+

+        EFI_DEVICE_ERROR

+          device is not accessible.

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  ATAPI_PACKET_COMMAND  Packet;

+  EFI_STATUS            Status;

+

+  //

+  // fill command packet

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.TestUnitReady.opcode = TEST_UNIT_READY;

+

+  //

+  // send command packet

+  //

+  Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);

+  return Status;

+}

+

+EFI_STATUS

+AtapiRequestSense (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  OUT UINTN           *SenseCounts

+  )

+/*++

+  Name:

+        AtapiRequestSense

+

+  Purpose: 

+        Sends out ATAPI Request Sense Packet Command to the specified device.

+        This command will return all the current Sense data in the device. 

+        This function will pack all the Sense data in one single buffer.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINT16      OUT   **SenseBuffers

+          allocated in this function, and freed by the calling function.

+          This buffer is used to accommodate all the sense data returned 

+          by the device.

+

+        UINTN     OUT   *BufUnit

+          record the unit size of the sense data block in the SenseBuffers,

+

+        UINTN     OUT   *BufNumbers

+          record the number of units in the SenseBuffers.

+

+  Returns:  

+        EFI_SUCCESS

+          Request Sense command completes successfully.

+

+        EFI_DEVICE_ERROR

+          Request Sense command failed.

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    SenseCounts - add argument and description to function comment

+{

+  EFI_STATUS            Status;

+  REQUEST_SENSE_DATA    *Sense;

+  UINT16                *Ptr;

+  BOOLEAN               FetchSenseData;

+  ATAPI_PACKET_COMMAND  Packet;

+

+  *SenseCounts = 0;

+

+  ZeroMem (IdeDev->SenseData, sizeof (REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber));

+  //

+  // fill command packet for Request Sense Packet Command

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.RequestSence.opcode            = REQUEST_SENSE;

+  Packet.RequestSence.allocation_length = sizeof (REQUEST_SENSE_DATA);

+

+  //

+  // initialize pointer

+  //

+  Ptr = (UINT16 *) IdeDev->SenseData;

+  //

+  //  request sense data from device continuously until no sense data

+  //  exists in the device.

+  //

+  for (FetchSenseData = TRUE; FetchSenseData;) {

+

+    Sense = (REQUEST_SENSE_DATA *) Ptr;

+

+    //

+    // send out Request Sense Packet Command and get one Sense data form device

+    //

+    Status = AtapiPacketCommandIn (

+              IdeDev,

+              &Packet,

+              Ptr,

+              sizeof (REQUEST_SENSE_DATA),

+              ATAPITIMEOUT

+              );

+    //

+    // failed to get Sense data

+    //

+    if (EFI_ERROR (Status)) {

+      if (*SenseCounts == 0) {

+        return EFI_DEVICE_ERROR;

+      } else {

+        return EFI_SUCCESS;

+      }

+    }

+

+    (*SenseCounts)++;

+    //

+    // We limit MAX sense data count to 20 in order to avoid dead loop. Some

+    // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.

+    // In this case, dead loop occurs if we don't have a gatekeeper. 20 is

+    // supposed to be large enough for any ATAPI device.

+    //

+    if ((Sense->sense_key != SK_NO_SENSE) && ((*SenseCounts) < 20)) {

+      //

+      // Ptr is word-based pointer

+      //

+      Ptr += sizeof (REQUEST_SENSE_DATA) / 2;

+

+    } else {

+      //

+      // when no sense key, skip out the loop

+      //

+      FetchSenseData = FALSE;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtapiReadCapacity (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        AtapiReadCapacity

+

+  Purpose: 

+        Sends out ATAPI Read Capacity Packet Command to the specified device.

+        This command will return the information regarding the capacity of the

+        media in the device.

+

+        Current device status will impact device's response to the Read Capacity

+        Command. For example, if the device once reset, the Read Capacity

+        Command will fail. The Sense data record the current device status, so 

+        if the Read Capacity Command failed, the Sense data must be requested

+        and be analyzed to determine if the Read Capacity Command should retry.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          Read Capacity Command finally completes successfully.

+

+        EFI_DEVICE_ERROR

+          Read Capacity Command failed because of device error.

+

+  Notes:

+        parameter "IdeDev" will be updated in this function.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    EFI_NOT_READY - add return value to function comment

+{

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS                Status;

+  ATAPI_PACKET_COMMAND      Packet;

+

+  //

+  // used for capacity data returned from ATAPI device

+  //

+  READ_CAPACITY_DATA        Data;

+  READ_FORMAT_CAPACITY_DATA FormatData;

+

+  ZeroMem (&Data, sizeof (Data));

+  ZeroMem (&FormatData, sizeof (FormatData));

+

+  if (IdeDev->Type == IdeCdRom) {

+

+    ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+    Packet.Inquiry.opcode = READ_CAPACITY;

+    Status = AtapiPacketCommandIn (

+              IdeDev,

+              &Packet,

+              (UINT16 *) &Data,

+              sizeof (READ_CAPACITY_DATA),

+              ATAPITIMEOUT

+              );

+

+  } else {

+    //

+    // Type == IdeMagnetic

+    //

+    ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+    Packet.ReadFormatCapacity.opcode                = READ_FORMAT_CAPACITY;

+    Packet.ReadFormatCapacity.allocation_length_lo  = 12;

+    Status = AtapiPacketCommandIn (

+              IdeDev,

+              &Packet,

+              (UINT16 *) &FormatData,

+              sizeof (READ_FORMAT_CAPACITY_DATA),

+              ATAPITIMEOUT

+              );

+  }

+

+  if (!EFI_ERROR (Status)) {

+

+    if (IdeDev->Type == IdeCdRom) {

+

+      IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |

+        (Data.LastLba2 << 16) |

+        (Data.LastLba1 << 8) |

+        Data.LastLba0;

+

+      if (IdeDev->BlkIo.Media->LastBlock != 0) {

+

+        IdeDev->BlkIo.Media->BlockSize = (Data.BlockSize3 << 24) |

+          (Data.BlockSize2 << 16) |

+          (Data.BlockSize1 << 8) |

+          Data.BlockSize0;

+

+        IdeDev->BlkIo.Media->MediaPresent = TRUE;

+      } else {

+        IdeDev->BlkIo.Media->MediaPresent = FALSE;

+        return EFI_DEVICE_ERROR;

+      }

+

+      IdeDev->BlkIo.Media->ReadOnly = TRUE;

+

+      //

+      // Because the user data portion in the sector of the Data CD supported

+      // is always 0x800

+      //

+      IdeDev->BlkIo.Media->BlockSize = 0x800;

+    }

+

+    if (IdeDev->Type == IdeMagnetic) {

+

+      if (FormatData.DesCode == 3) {

+        IdeDev->BlkIo.Media->MediaPresent = FALSE;

+        IdeDev->BlkIo.Media->LastBlock    = 0;

+      } else {

+

+        IdeDev->BlkIo.Media->LastBlock =  (FormatData.LastLba3 << 24) |

+                                          (FormatData.LastLba2 << 16) | 

+                                          (FormatData.LastLba1 << 8)  |

+                                           FormatData.LastLba0;

+        if (IdeDev->BlkIo.Media->LastBlock != 0) {

+          IdeDev->BlkIo.Media->LastBlock--;

+

+          IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |

+            (FormatData.BlockSize1 << 8) |

+            FormatData.BlockSize0;

+

+          IdeDev->BlkIo.Media->MediaPresent = TRUE;

+        } else {

+          IdeDev->BlkIo.Media->MediaPresent = FALSE;

+          //

+          // Return EFI_NOT_READY operation succeeds but returned capacity is 0

+          //

+          return EFI_NOT_READY;

+        }

+

+        IdeDev->BlkIo.Media->BlockSize = 0x200;

+

+      }

+    }

+

+    return EFI_SUCCESS;

+

+  } else {

+

+    return EFI_DEVICE_ERROR;

+  }

+}

+

+EFI_STATUS

+AtapiDetectMedia (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  OUT BOOLEAN         *MediaChange

+  )

+/*++

+  Name:

+        AtapiDetectMedia

+

+  Purpose: 

+        Used before read/write blocks from/to ATAPI device media. 

+        Since ATAPI device media is removable, it is necessary to detect

+        whether media is present and get current present media's

+        information, and if media has been changed, Block I/O Protocol

+        need to be reinstalled.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        BOOLEAN         OUT   *MediaChange

+          return value that indicates if the media of the device has been

+          changed.

+

+  Returns:  

+        EFI_SUCCESS

+          media found successfully.

+

+        EFI_DEVICE_ERROR

+          any error encounters during media detection.

+          

+        EFI_NO_MEDIA

+          media not found.

+

+  Notes:

+        parameter IdeDev may be updated in this function.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    MediaChange - add argument and description to function comment

+{

+  EFI_STATUS          Status;

+  EFI_STATUS          ReadCapacityStatus;

+  EFI_BLOCK_IO_MEDIA  OldMediaInfo;

+  UINTN               SenseCounts;

+  UINTN               RetryIndex;

+  UINTN               RetryTimes;

+  UINTN               MaximumRetryTimes;

+  UINTN               ReadyWaitFactor;

+  BOOLEAN             NeedRetry;

+  //

+  // a flag used to determine whether need to perform Read Capacity command.

+  //

+  BOOLEAN             NeedReadCapacity;

+  BOOLEAN             WriteProtected;

+

+  //

+  // init

+  //

+  CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (OldMediaInfo));

+  // OldMediaInfo        = *(IdeDev->BlkIo.Media);

+  *MediaChange        = FALSE;

+  ReadCapacityStatus  = EFI_DEVICE_ERROR;

+

+  //

+  // if there is no media, or media is not changed,

+  // the request sense command will detect faster than read capacity command.

+  // read capacity command can be bypassed, thus improve performance.

+  //

+

+  //

+  // Test Unit Ready command is used to detect whether device is accessible,

+  // the device will produce corresponding Sense data.

+  //

+  for (RetryIndex = 0; RetryIndex < 2; RetryIndex++) {

+

+    Status = AtapiTestUnitReady (IdeDev);

+    if (!EFI_ERROR (Status)) {

+      //

+      // skip the loop if test unit command succeeds.

+      //

+      break;

+    }

+

+    Status = AtapiSoftReset (IdeDev);

+

+    if (EFI_ERROR (Status)) {

+      AtaSoftReset (IdeDev);

+    }

+  }

+

+  SenseCounts       = 0;

+  NeedReadCapacity  = TRUE;

+

+  //

+  // at most retry 5 times

+  //

+  MaximumRetryTimes = 5;

+  RetryTimes        = 1;

+

+  for (RetryIndex = 0; 

+       (RetryIndex < RetryTimes) && (RetryIndex < MaximumRetryTimes);

+       RetryIndex++) {

+

+    Status = AtapiRequestSense (IdeDev, &SenseCounts);

+

+    if (!EFI_ERROR (Status)) {

+      //

+      // if first time there is no Sense Key, no need to read capacity any more

+      //

+      if (!HaveSenseKey (IdeDev->SenseData, SenseCounts) &&

+          (IdeDev->BlkIo.Media->MediaPresent)) {

+

+        if (RetryIndex == 0) {

+          NeedReadCapacity = FALSE;

+        }

+

+      } else {

+        //

+        // No Media

+        //

+        if (IsNoMedia (IdeDev->SenseData, SenseCounts)) {

+          NeedReadCapacity                  = FALSE;

+          IdeDev->BlkIo.Media->MediaPresent = FALSE;

+          IdeDev->BlkIo.Media->LastBlock    = 0;

+        } else {

+          //

+          // Media Changed

+          //

+          if (IsMediaChange (IdeDev->SenseData, SenseCounts)) {

+            NeedReadCapacity = TRUE;

+            IdeDev->BlkIo.Media->MediaId++;

+          }

+          //

+          // Media Error

+          //

+          if (IsMediaError (IdeDev->SenseData, SenseCounts)) {

+            return EFI_DEVICE_ERROR;

+          }

+        }

+      }

+    } else {

+      //

+      // retry once more, if request sense command met errors.

+      //

+      RetryTimes++;

+    }

+  }

+

+  if (NeedReadCapacity) {

+    //

+    // at most retry 5 times

+    //

+    MaximumRetryTimes = 5;

+    //

+    // initial retry twice

+    //

+    RetryTimes        = 2;

+    ReadyWaitFactor = 2;

+

+    for (RetryIndex = 0;

+         (RetryIndex < RetryTimes) && (RetryIndex < MaximumRetryTimes);

+         RetryIndex++) {

+

+      ReadCapacityStatus  = AtapiReadCapacity (IdeDev);

+

+      SenseCounts         = 0;

+

+      if (!EFI_ERROR (ReadCapacityStatus)) {

+        //

+        // Read Capacity succeeded

+        //

+        break;

+

+      } else {

+

+        if (ReadCapacityStatus == EFI_NOT_READY) {

+          //

+          // If device not ready, wait here... waiting time increases by retry

+          // times.

+          //

+          gBS->Stall (ReadyWaitFactor * 2000 * STALL_1_MILLI_SECOND);

+          ReadyWaitFactor++;

+          //

+          // retry once more

+          //

+          RetryTimes++;

+          continue;

+        }

+        

+        //

+        // Other errors returned, requery sense data

+        //

+        Status = AtapiRequestSense (IdeDev, &SenseCounts);

+

+        //

+        // If Request Sense data failed, reset the device and retry.

+        //

+        if (EFI_ERROR (Status)) {

+

+          Status = AtapiSoftReset (IdeDev);

+

+          //

+          // if ATAPI soft reset fail,

+          // use stronger reset mechanism -- ATA soft reset.

+          //

+          if (EFI_ERROR (Status)) {

+            AtaSoftReset (IdeDev);

+          }

+          //

+          // retry once more

+          //

+          RetryTimes++;

+          continue;

+        }

+        

+        //

+        // No Media

+        //

+        if (IsNoMedia (IdeDev->SenseData, SenseCounts)) {

+

+          IdeDev->BlkIo.Media->MediaPresent = FALSE;

+          IdeDev->BlkIo.Media->LastBlock    = 0;

+          return EFI_NO_MEDIA;

+        }

+

+        if (IsMediaError (IdeDev->SenseData, SenseCounts)) {

+          return EFI_DEVICE_ERROR;

+        }

+        

+        //

+        // Media Changed

+        //

+        if (IsMediaChange (IdeDev->SenseData, SenseCounts)) {

+          IdeDev->BlkIo.Media->MediaId++;

+        }

+

+        if (!IsDriveReady (IdeDev->SenseData, SenseCounts, &NeedRetry)) {

+          

+          //

+          // Drive not ready: if NeedRetry, then retry once more;

+          // else return error

+          //

+          if (NeedRetry) {

+            //

+            // Stall 1 second to wait for drive becoming ready

+            //

+            gBS->Stall (1000 * STALL_1_MILLI_SECOND);

+            //

+            // reset retry variable to zero,

+            // to make it retry for "drive in progress of becoming ready".

+            //

+            RetryIndex = 0;

+            continue;

+          } else {

+            AtapiSoftReset (IdeDev);

+            return EFI_DEVICE_ERROR;

+          }

+        }

+        //

+        // if read capacity fail not for above reasons, retry once more

+        //

+        RetryTimes++;

+      }

+

+    }

+  

+    //

+    // tell whether the readcapacity process is successful or not in the end

+    //

+    if (EFI_ERROR (ReadCapacityStatus)) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  //

+  // the following code is to check the write-protected for LS120 media

+  //

+  if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) {

+

+    Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected);

+    if (!EFI_ERROR (Status)) {

+

+      if (WriteProtected) {

+

+        IdeDev->BlkIo.Media->ReadOnly = TRUE;

+      } else {

+

+        IdeDev->BlkIo.Media->ReadOnly = FALSE;

+      }

+

+    }

+  }

+

+  if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {

+    //

+    // Media change information got from the device

+    //

+    *MediaChange = TRUE;

+  }

+

+  if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {

+    *MediaChange = TRUE;

+    IdeDev->BlkIo.Media->MediaId += 1;

+  }

+

+  if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {

+    *MediaChange = TRUE;

+    IdeDev->BlkIo.Media->MediaId += 1;

+  }

+

+  if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {

+    *MediaChange = TRUE;

+    IdeDev->BlkIo.Media->MediaId += 1;

+  }

+

+  if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {

+    if (IdeDev->BlkIo.Media->MediaPresent) {

+      //

+      // when change from no media to media present, reset the MediaId to 1.

+      //

+      IdeDev->BlkIo.Media->MediaId = 1;

+    } else {

+      //

+      // when no media, reset the MediaId to zero.

+      //

+      IdeDev->BlkIo.Media->MediaId = 0;

+    }

+

+    *MediaChange = TRUE;

+  }

+

+  //

+  // if any change on current existing media,

+  // the Block I/O protocol need to be reinstalled.

+  //

+  if (*MediaChange) {

+    gBS->ReinstallProtocolInterface (

+          IdeDev->Handle,

+          &gEfiBlockIoProtocolGuid,

+          &IdeDev->BlkIo,

+          &IdeDev->BlkIo

+          );

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+AtapiReadSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+        AtapiReadSectors

+

+  Purpose: 

+        This function is called by the AtapiBlkIoReadBlocks() to perform

+        read from media in block unit.

+

+        The main command used to access media here is READ(10) Command. 

+        READ(10) Command requests that the ATAPI device media transfer 

+        specified data to the host. Data is transferred in block(sector) 

+        unit. The maximum number of blocks that can be transferred once is

+        65536. This is the main difference between READ(10) and READ(12) 

+        Command. The maximum number of blocks in READ(12) is 2 power 32.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *Buffer

+          A pointer to the destination buffer for the data. 

+

+        EFI_LBA     IN    Lba

+          The starting logical block address to read from 

+          on the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+        return status is fully dependent on the return status

+        of AtapiPacketCommandIn() function.

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    Lba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+{

+

+  ATAPI_PACKET_COMMAND  Packet;

+  READ10_CMD            *Read10Packet;

+  EFI_STATUS            Status;

+  UINTN                 BlocksRemaining;

+  UINT32                Lba32;

+  UINT32                BlockSize;

+  UINT32                ByteCount;

+  UINT16                SectorCount;

+  VOID                  *PtrBuffer;

+  UINT16                MaxBlock;

+  UINTN                 TimeOut;

+

+  //

+  // fill command packet for Read(10) command

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Read10Packet  = &Packet.Read10;

+  Lba32         = (UINT32) Lba;

+  PtrBuffer     = Buffer;

+

+  BlockSize     = IdeDev->BlkIo.Media->BlockSize;

+

+  //

+  // limit the data bytes that can be transferred by one Read(10) Command

+  //

+  MaxBlock        = (UINT16) (65536 / BlockSize);

+

+  BlocksRemaining = NumberOfBlocks;

+

+  Status          = EFI_SUCCESS;

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining <= MaxBlock) {

+

+      SectorCount = (UINT16) BlocksRemaining;

+    } else {

+

+      SectorCount = MaxBlock;

+    }

+

+    //

+    // fill the Packet data structure

+    //

+

+    Read10Packet->opcode = READ_10;

+

+    //

+    // Lba0 ~ Lba3 specify the start logical block address of the data transfer.

+    // Lba0 is MSB, Lba3 is LSB

+    //

+    Read10Packet->Lba3  = (UINT8) (Lba32 & 0xff);

+    Read10Packet->Lba2  = (UINT8) (Lba32 >> 8);

+    Read10Packet->Lba1  = (UINT8) (Lba32 >> 16);

+    Read10Packet->Lba0  = (UINT8) (Lba32 >> 24);

+

+    //

+    // TranLen0 ~ TranLen1 specify the transfer length in block unit.

+    // TranLen0 is MSB, TranLen is LSB

+    //

+    Read10Packet->TranLen1  = (UINT8) (SectorCount & 0xff);

+    Read10Packet->TranLen0  = (UINT8) (SectorCount >> 8);

+

+    ByteCount               = SectorCount * BlockSize;

+

+    if (IdeDev->Type == IdeCdRom) {

+      TimeOut = CDROMLONGTIMEOUT;

+    } else {

+      TimeOut = ATAPILONGTIMEOUT;

+    }

+

+    Status = AtapiPacketCommandIn (

+              IdeDev,

+              &Packet,

+              (UINT16 *) PtrBuffer,

+              ByteCount,

+              TimeOut

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Lba32 += SectorCount;

+    PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;

+    BlocksRemaining -= SectorCount;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AtapiWriteSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+  Name:

+        AtapiWriteSectors

+

+  Purpose: 

+        This function is called by the AtapiBlkIoWriteBlocks() to perform

+        write onto media in block unit.

+        The main command used to access media here is Write(10) Command. 

+        Write(10) Command requests that the ATAPI device media transfer 

+        specified data to the host. Data is transferred in block (sector) 

+        unit. The maximum number of blocks that can be transferred once is

+        65536. 

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        VOID      IN    *Buffer

+          A pointer to the source buffer for the data. 

+

+        EFI_LBA     IN    Lba

+          The starting logical block address to write onto 

+          the device media.

+

+        UINTN     IN    NumberOfBlocks

+          The number of transfer data blocks.

+

+  Returns:  

+        return status is fully dependent on the return status

+        of AtapiPacketCommandOut() function.

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    Lba - add argument and description to function comment

+// TODO:    NumberOfBlocks - add argument and description to function comment

+{

+

+  ATAPI_PACKET_COMMAND  Packet;

+  READ10_CMD            *Read10Packet;

+

+  EFI_STATUS            Status;

+  UINTN                 BlocksRemaining;

+  UINT32                Lba32;

+  UINT32                BlockSize;

+  UINT32                ByteCount;

+  UINT16                SectorCount;

+  VOID                  *PtrBuffer;

+  UINT16                MaxBlock;

+

+  //

+  // fill command packet for Write(10) command

+  // Write(10) command packet has the same data structure as

+  // Read(10) command packet,

+  // so here use the Read10Packet data structure

+  // for the Write(10) command packet.

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Read10Packet  = &Packet.Read10;

+

+  Lba32         = (UINT32) Lba;

+  PtrBuffer     = Buffer;

+

+  BlockSize     = IdeDev->BlkIo.Media->BlockSize;

+

+  //

+  // limit the data bytes that can be transferred by one Read(10) Command

+  //

+  MaxBlock        = (UINT16) (65536 / BlockSize);

+

+  BlocksRemaining = NumberOfBlocks;

+

+  Status          = EFI_SUCCESS;

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining >= MaxBlock) {

+      SectorCount = MaxBlock;

+    } else {

+      SectorCount = (UINT16) BlocksRemaining;

+    }

+  

+    //

+    // Command code is WRITE_10.

+    //

+    Read10Packet->opcode = WRITE_10;

+

+    //

+    // Lba0 ~ Lba3 specify the start logical block address of the data transfer.

+    // Lba0 is MSB, Lba3 is LSB

+    //

+    Read10Packet->Lba3  = (UINT8) (Lba32 & 0xff);

+    Read10Packet->Lba2  = (UINT8) (Lba32 >> 8);

+    Read10Packet->Lba1  = (UINT8) (Lba32 >> 16);

+    Read10Packet->Lba0  = (UINT8) (Lba32 >> 24);

+

+    //

+    // TranLen0 ~ TranLen1 specify the transfer length in block unit.

+    // TranLen0 is MSB, TranLen is LSB

+    //

+    Read10Packet->TranLen1  = (UINT8) (SectorCount & 0xff);

+    Read10Packet->TranLen0  = (UINT8) (SectorCount >> 8);

+

+    ByteCount               = SectorCount * BlockSize;

+

+    Status = AtapiPacketCommandOut (

+              IdeDev,

+              &Packet,

+              (UINT16 *) PtrBuffer,

+              ByteCount,

+              ATAPILONGTIMEOUT

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Lba32 += SectorCount;

+    PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize);

+    BlocksRemaining -= SectorCount;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AtapiSoftReset (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  Name:

+        AtapiSoftReset

+

+  Purpose: 

+        This function is used to implement the Soft Reset on the specified

+        ATAPI device. Different from the AtaSoftReset(), here reset is a ATA

+        Soft Reset Command special for ATAPI device, and it only take effects

+        on the specified ATAPI device, not on the whole IDE bus.

+        Since the ATAPI soft reset is needed when device is in exceptional

+        condition (such as BSY bit is always set ), I think the Soft Reset

+        command should be sent without waiting for the BSY clear and DRDY

+        set.

+        This function is called by IdeBlkIoReset(), 

+        a interface function of Block I/O protocol.

+

+            

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+  Returns:  

+        EFI_SUCCESS

+          Soft reset completes successfully.

+

+        EFI_DEVICE_ERROR

+          Any step during the reset process is failed.

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+{

+  UINT8       Command;

+  UINT8       DeviceSelect;

+  EFI_STATUS  Status;

+

+  //

+  // for ATAPI device, no need to wait DRDY ready after device selecting.

+  // (bit7 and bit5 are both set to 1 for backward compatibility)

+  //

+  DeviceSelect = (UINT8) (((bit7 | bit5) | (IdeDev->Device << 4)));

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);

+

+  Command = ATAPI_SOFT_RESET_CMD;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command);

+

+  //

+  // BSY cleared is the only status return to the host by the device

+  // when reset is completed.

+  // slave device needs at most 31s to clear BSY

+  //

+  Status = WaitForBSYClear (IdeDev, 31000);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // stall 5 seconds to make the device status stable

+  //

+  gBS->Stall (5000000);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtapiBlkIoReadBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+  Name:

+        AtapiBlkIoReadBlocks

+

+  Purpose: 

+        This function is the ATAPI implementation for ReadBlocks in the

+        Block I/O Protocol interface.

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeBlkIoDev

+          Indicates the calling context.

+

+        UINT32      IN    MediaId

+          The media id that the read request is for.

+

+        EFI_LBA     IN    LBA

+          The starting logical block address to read from 

+          on the device.

+

+        UINTN     IN    BufferSize

+          The size of the Buffer in bytes. This must be a

+          multiple of the intrinsic block size of the device.

+

+        VOID      OUT   *Buffer

+          A pointer to the destination buffer for the data. 

+          The caller is responsible for either having implicit

+          or explicit ownership of the memory that data is read into.

+

+  Returns:  

+        EFI_SUCCESS 

+          Read Blocks successfully.

+

+        EFI_DEVICE_ERROR

+          Read Blocks failed.

+

+        EFI_NO_MEDIA

+          There is no media in the device.

+

+        EFI_MEDIA_CHANGED

+          The MediaId is not for the current media.

+

+        EFI_BAD_BUFFER_SIZE

+          The BufferSize parameter is not a multiple of the 

+          intrinsic block size of the device.

+

+        EFI_INVALID_PARAMETER

+          The read request contains LBAs that are not valid,

+          or the data buffer is not valid.

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeBlkIoDevice - add argument and description to function comment

+// TODO:    MediaId - add argument and description to function comment

+// TODO:    LBA - add argument and description to function comment

+// TODO:    BufferSize - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+{

+  EFI_BLOCK_IO_MEDIA  *Media;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  EFI_STATUS          Status;

+

+  BOOLEAN             MediaChange;

+

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferSize == 0) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // ATAPI device media is removable, so it is a must

+  // to detect media first before read operation

+  //

+  MediaChange = FALSE;

+  Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);

+  if (EFI_ERROR (Status)) {

+

+    if (IdeBlkIoDevice->Cache != NULL) {

+      gBS->FreePool (IdeBlkIoDevice->Cache);

+      IdeBlkIoDevice->Cache = NULL;

+    }

+

+    return Status;

+  }

+  //

+  // Get the intrinsic block size

+  //

+  Media           = IdeBlkIoDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (!(Media->MediaPresent)) {

+

+    if (IdeBlkIoDevice->Cache != NULL) {

+      gBS->FreePool (IdeBlkIoDevice->Cache);

+      IdeBlkIoDevice->Cache = NULL;

+    }

+    return EFI_NO_MEDIA;

+

+  }

+

+  if ((MediaId != Media->MediaId) || MediaChange) {

+

+    if (IdeBlkIoDevice->Cache != NULL) {

+      gBS->FreePool (IdeBlkIoDevice->Cache);

+      IdeBlkIoDevice->Cache = NULL;

+    }

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (LBA > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // if all the parameters are valid, then perform read sectors command

+  // to transfer data from device to host.

+  //

+  Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // Read blocks succeeded

+  //

+  

+  //

+  // save the first block to the cache for performance

+  //

+  if (LBA == 0 && !IdeBlkIoDevice->Cache) {

+    IdeBlkIoDevice->Cache = AllocatePool (BlockSize);

+    if (IdeBlkIoDevice != NULL) {

+      CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);

+    }

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+AtapiBlkIoWriteBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+  Name:

+        AtapiBlkIoWriteBlocks

+

+  Purpose: 

+        This function is the ATAPI implementation for WriteBlocks in the

+        Block I/O Protocol interface.

+

+  Parameters:

+        EFI_BLOCK_IO  IN    *This

+          Indicates the calling context.

+

+        UINT32      IN    MediaId

+          The media id that the write request is for.

+

+        EFI_LBA     IN    LBA

+          The starting logical block address to write onto 

+          the device.

+

+        UINTN     IN    BufferSize

+          The size of the Buffer in bytes. This must be a

+          multiple of the intrinsic block size of the device.

+

+        VOID      OUT   *Buffer

+          A pointer to the source buffer for the data. 

+          The caller is responsible for either having implicit

+          or explicit ownership of the memory that data is 

+          written from.

+

+  Returns:  

+        EFI_SUCCESS 

+          Write Blocks successfully.

+

+        EFI_DEVICE_ERROR

+          Write Blocks failed.

+

+        EFI_NO_MEDIA

+          There is no media in the device.

+

+        EFI_MEDIA_CHANGE

+          The MediaId is not for the current media.

+

+        EFI_BAD_BUFFER_SIZE

+          The BufferSize parameter is not a multiple of the 

+          intrinsic block size of the device.

+

+        EFI_INVALID_PARAMETER

+          The write request contains LBAs that are not valid,

+          or the data buffer is not valid. 

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeBlkIoDevice - add argument and description to function comment

+// TODO:    MediaId - add argument and description to function comment

+// TODO:    LBA - add argument and description to function comment

+// TODO:    BufferSize - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_MEDIA_CHANGED - add return value to function comment

+// TODO:    EFI_WRITE_PROTECTED - add return value to function comment

+{

+

+  EFI_BLOCK_IO_MEDIA  *Media;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  EFI_STATUS          Status;

+  BOOLEAN             MediaChange;

+

+  if (LBA == 0 && IdeBlkIoDevice->Cache) {

+    gBS->FreePool (IdeBlkIoDevice->Cache);

+    IdeBlkIoDevice->Cache = NULL;

+  }

+

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferSize == 0) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // ATAPI device media is removable,

+  // so it is a must to detect media first before write operation

+  //

+  MediaChange = FALSE;

+  Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);

+  if (EFI_ERROR (Status)) {

+

+    if (LBA == 0 && IdeBlkIoDevice->Cache) {

+      gBS->FreePool (IdeBlkIoDevice->Cache);

+      IdeBlkIoDevice->Cache = NULL;

+    }

+    return Status;

+  }

+  

+  //

+  // Get the intrinsic block size

+  //

+  Media           = IdeBlkIoDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (!(Media->MediaPresent)) {

+

+    if (LBA == 0 && IdeBlkIoDevice->Cache) {

+      gBS->FreePool (IdeBlkIoDevice->Cache);

+      IdeBlkIoDevice->Cache = NULL;

+    }

+    return EFI_NO_MEDIA;

+  }

+

+  if ((MediaId != Media->MediaId) || MediaChange) {

+

+    if (LBA == 0 && IdeBlkIoDevice->Cache) {

+      gBS->FreePool (IdeBlkIoDevice->Cache);

+      IdeBlkIoDevice->Cache = NULL;

+    }

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if (Media->ReadOnly) {

+    return EFI_WRITE_PROTECTED;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (LBA > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // if all the parameters are valid,

+  // then perform write sectors command to transfer data from host to device.

+  //

+  Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+//

+// The following functions are a set of helper functions,

+// which are used to parse sense key returned by the device.

+//

+

+BOOLEAN

+IsNoMedia (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  REQUEST_SENSE_DATA  *SensePointer;

+  UINTN               Index;

+  BOOLEAN             NoMedia;

+

+  NoMedia       = FALSE;

+  SensePointer  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    //

+    // Sense Key is SK_NOT_READY (0x2),

+    // Additional Sense Code is ASC_NO_MEDIA (0x3A)

+    //

+    if ((SensePointer->sense_key == SK_NOT_READY) &&

+        (SensePointer->addnl_sense_code == ASC_NO_MEDIA)) {

+

+      NoMedia = TRUE;

+    }

+

+    SensePointer++;

+  }

+

+  return NoMedia;

+}

+

+BOOLEAN

+IsMediaError (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+  Name:

+        IsMediaError

+

+  Purpose: 

+        Test if the device meets a media error after media changed

+

+  Parameters:

+        EQUEST_SENSE_DATA   IN  *SenseData

+          pointer pointing to ATAPI device sense data list.

+        UINTN               IN  SenseCounts

+          sense data number of the list          

+

+  Returns:  

+        TRUE

+          Device meets a media error

+

+        FALSE

+          No media error

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    SenseData - add argument and description to function comment

+// TODO:    SenseCounts - add argument and description to function comment

+{

+  REQUEST_SENSE_DATA  *SensePointer;

+  UINTN               Index;

+  BOOLEAN             IsError;

+

+  IsError       = FALSE;

+  SensePointer  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    switch (SensePointer->sense_key) {

+

+    case SK_MEDIUM_ERROR:

+      //

+      // Sense Key is SK_MEDIUM_ERROR (0x3)

+      //

+      switch (SensePointer->addnl_sense_code) {

+      case ASC_MEDIA_ERR1:

+      case ASC_MEDIA_ERR2:

+      case ASC_MEDIA_ERR3:

+      case ASC_MEDIA_ERR4:

+        IsError = TRUE;

+        break;

+

+      default:

+        break;

+      }

+

+      break;

+

+    case SK_NOT_READY:

+      //

+      // Sense Key is SK_NOT_READY (0x2)

+      //

+      switch (SensePointer->addnl_sense_code) {

+      //

+      // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)

+      //

+      case ASC_MEDIA_UPSIDE_DOWN:

+        IsError = TRUE;

+        break;

+

+      default:

+        break;

+      }

+      break;

+

+    default:

+      break;

+    }

+

+    SensePointer++;

+  }

+

+  return IsError;

+}

+

+BOOLEAN

+IsMediaChange (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  REQUEST_SENSE_DATA  *SensePointer;

+  UINTN               Index;

+  BOOLEAN             IsMediaChange;

+

+  IsMediaChange = FALSE;

+  SensePointer  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    //

+    // Sense Key is SK_UNIT_ATTENTION (0x6)

+    //

+    if ((SensePointer->sense_key == SK_UNIT_ATTENTION) &&

+        (SensePointer->addnl_sense_code == ASC_MEDIA_CHANGE)) {

+

+      IsMediaChange = TRUE;

+    }

+

+    SensePointer++;

+  }

+

+  return IsMediaChange;

+}

+

+BOOLEAN

+IsDriveReady (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts,

+  OUT BOOLEAN               *NeedRetry

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+  NeedRetry   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  REQUEST_SENSE_DATA  *SensePointer;

+  UINTN               Index;

+  BOOLEAN             IsReady;

+

+  IsReady       = TRUE;

+  *NeedRetry    = FALSE;

+  SensePointer  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    switch (SensePointer->sense_key) {

+

+    case SK_NOT_READY:

+      //

+      // Sense Key is SK_NOT_READY (0x2)

+      //

+      switch (SensePointer->addnl_sense_code) {

+      case ASC_NOT_READY:

+        //

+        // Additional Sense Code is ASC_NOT_READY (0x4)

+        //

+        switch (SensePointer->addnl_sense_code_qualifier) {

+        case ASCQ_IN_PROGRESS:

+          //

+          // Additional Sense Code Qualifier is ASCQ_IN_PROGRESS (0x1)

+          //

+          IsReady     = FALSE;

+          *NeedRetry  = TRUE;

+          break;

+

+        default:

+          IsReady     = FALSE;

+          *NeedRetry  = FALSE;

+          break;

+        }

+        break;

+

+      default:

+        break;

+      }

+      break;

+

+    default:

+      break;

+    }

+

+    SensePointer++;

+  }

+

+  return IsReady;

+}

+

+BOOLEAN

+HaveSenseKey (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  BOOLEAN Have;

+

+  Have = TRUE;

+

+  //

+  // if first sense key in the Sense Data Array is SK_NO_SENSE,

+  // it indicates there is no more sense key in the Sense Data Array.

+  //

+  if (SenseData->sense_key == SK_NO_SENSE) {

+    Have = FALSE;

+  }

+

+  return Have;

+}

+

+EFI_STATUS

+IsLS120orZipWriteProtected (

+  IN  IDE_BLK_IO_DEV    *IdeDev,

+  OUT BOOLEAN           *WriteProtected

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  WriteProtected  - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  *WriteProtected = FALSE;

+

+  Status          = LS120EnableMediaStatus (IdeDev, TRUE);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // the Get Media Status Command is only valid

+  // if a Set Features/Enable Media Status Command has been priviously issued.

+  //

+  if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {

+

+    *WriteProtected = TRUE;

+  } else {

+

+    *WriteProtected = FALSE;

+  }

+

+  //

+  // After Get Media Status Command completes,

+  // Set Features/Disable Media Command should be sent.

+  //

+  Status = LS120EnableMediaStatus (IdeDev, FALSE);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/build.xml
new file mode 100644
index 0000000..5f6d829
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="IdeBus"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Pci/IdeBus/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="IdeBusLite">

+      <GenBuild baseName="IdeBusLite" mbdFilename="${MODULE_DIR}/idebusLite.mbd" msaFilename="${MODULE_DIR}/idebusLite.msa"/>

+   </target>

+   <target name="IdeBus">

+      <GenBuild baseName="IdeBus" mbdFilename="${MODULE_DIR}/idebus.mbd" msaFilename="${MODULE_DIR}/idebus.msa"/>

+   </target>

+   <target depends="IdeBus_clean" name="clean"/>

+   <target depends="IdeBus_cleanall" name="cleanall"/>

+   <target name="IdeBusLite_clean">

+      <OutputDirSetup baseName="IdeBusLite" mbdFilename="${MODULE_DIR}/idebusLite.mbd" msaFilename="${MODULE_DIR}/idebusLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/IdeBusLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/IdeBusLite_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="IdeBus_clean">

+      <OutputDirSetup baseName="IdeBus" mbdFilename="${MODULE_DIR}/idebus.mbd" msaFilename="${MODULE_DIR}/idebus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/IdeBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/IdeBus_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="IdeBusLite_cleanall">

+      <OutputDirSetup baseName="IdeBusLite" mbdFilename="${MODULE_DIR}/idebusLite.mbd" msaFilename="${MODULE_DIR}/idebusLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/IdeBusLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/IdeBusLite_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**IdeBusLite*"/>

+      </delete>

+   </target>

+   <target name="IdeBus_cleanall">

+      <OutputDirSetup baseName="IdeBus" mbdFilename="${MODULE_DIR}/idebus.mbd" msaFilename="${MODULE_DIR}/idebus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/IdeBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/IdeBus_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**IdeBus*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c
new file mode 100644
index 0000000..d318fd2
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.c
@@ -0,0 +1,1964 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ide.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#include "idebus.h"

+

+BOOLEAN SlaveDeviceExist  = FALSE;

+BOOLEAN MasterDeviceExist = FALSE;

+

+UINT8

+IDEReadPortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT8 Data;

+

+  Data = 0;

+  //

+  // perform 1-byte data read from register

+  //

+  PciIo->Io.Read (

+              PciIo,

+              EfiPciIoWidthUint8,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+  return Data;

+}

+

+VOID

+IDEReadPortWMultiple (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINTN                 Count,

+  IN  VOID                  *Buffer

+  )

+/*++

+

+Routine Description:

+  Reads multiple words of data from the IDE data port. 

+  Call the IO abstraction once to do the complete read,

+  not one word at a time

+  

+

+Arguments:

+  PciIo   - Pointer to the EFI_PCI_IO instance

+  Port    - IO port to read

+  Count   - No. of UINT16's to read

+  Buffer  - Pointer to the data buffer for read

+

+++*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Returns:'

+{

+  UINT16  *AlignedBuffer;

+  UINT16  *WorkingBuffer;

+  UINTN   Size;

+

+  //

+  // Prepare an 16-bit alligned working buffer. CpuIo will return failure and

+  // not perform actual I/O operations if buffer pointer passed in is not at

+  // natural boundary. The "Buffer" argument is passed in by user and may not

+  // at 16-bit natural boundary.

+  //

+  Size = sizeof (UINT16) * Count;

+

+  gBS->AllocatePool (

+        EfiBootServicesData,

+        Size + 1,

+        (VOID**)&WorkingBuffer

+        );

+

+  AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1)));

+

+  //

+  // Perform UINT16 data read from FIFO

+  //

+  PciIo->Io.Read (

+              PciIo,

+              EfiPciIoWidthFifoUint16,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              Count,

+              (UINT16*)AlignedBuffer

+              );

+

+  //

+  // Copy data to user buffer

+  //

+  CopyMem (Buffer, (UINT16*)AlignedBuffer, Size);

+  gBS->FreePool (WorkingBuffer);

+}

+

+VOID

+IDEWritePortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT8                 Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // perform 1-byte data write to register

+  //

+  PciIo->Io.Write (

+              PciIo,

+              EfiPciIoWidthUint8,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+

+}

+

+VOID

+IDEWritePortW (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT16                Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // perform 1-word data write to register

+  //

+  PciIo->Io.Write (

+              PciIo,

+              EfiPciIoWidthUint16,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              1,

+              &Data

+              );

+}

+

+VOID

+IDEWritePortWMultiple (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINTN                 Count,

+  IN  VOID                  *Buffer

+  )

+/*++

+

+Routine Description:

+  Write multiple words of data to the IDE data port. 

+  Call the IO abstraction once to do the complete read,

+  not one word at a time

+  

+

+Arguments:

+  PciIo   - Pointer to the EFI_PCI_IO instance

+  Port    - IO port to read

+  Count   - No. of UINT16's to read

+  Buffer  - Pointer to the data buffer for read

+

+++*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Returns:'

+{

+  UINT16  *AlignedBuffer;

+  UINT32  *WorkingBuffer;

+  UINTN   Size;

+

+  //

+  // Prepare an 16-bit alligned working buffer. CpuIo will return failure and

+  // not perform actual I/O operations if buffer pointer passed in is not at

+  // natural boundary. The "Buffer" argument is passed in by user and may not

+  // at 16-bit natural boundary.

+  //

+  Size = sizeof (UINT16) * Count;

+

+  gBS->AllocatePool (

+        EfiBootServicesData,

+        Size + 1,

+        (VOID **) &WorkingBuffer

+        );

+

+  AlignedBuffer = (UINT16 *) ((UINTN)(((UINTN) WorkingBuffer + 0x1) & (~0x1)));

+

+  //

+  // Copy data from user buffer to working buffer

+  //

+  CopyMem ((UINT16 *) AlignedBuffer, Buffer, Size);

+

+  //

+  // perform UINT16 data write to the FIFO

+  //

+  PciIo->Io.Write (

+              PciIo,

+              EfiPciIoWidthFifoUint16,

+              EFI_PCI_IO_PASS_THROUGH_BAR,

+              (UINT64) Port,

+              Count,

+              (UINT16 *) AlignedBuffer

+              );

+

+  gBS->FreePool (WorkingBuffer);

+}

+

+BOOLEAN

+BadIdeDeviceCheck (

+  IN IDE_BLK_IO_DEV *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  //  check whether all registers return 0xff,

+  //  if so, deem the channel is disabled.

+  //

+#ifdef EFI_DEBUG

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Data) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Head) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command) != 0xff) {

+    return FALSE;

+  }

+

+  if (IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus) != 0xff) {

+    return FALSE;

+  }

+

+  return TRUE;

+

+#else

+

+  return FALSE;

+

+#endif

+}

+

+//

+// GetIdeRegistersBaseAddr

+//

+EFI_STATUS

+GetIdeRegistersBaseAddr (

+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,

+  OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr

+  )

+/*++

+

+Routine Description:

+  Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,

+  use fixed addresses. In Native-PCI mode, get base addresses from BARs in

+  the PCI IDE controller's Configuration Space.

+  

+  The steps to get IDE IO port registers' base addresses for each channel 

+  as follows:

+

+  1. Examine the Programming Interface byte of the Class Code fields in PCI IDE 

+     controller's Configuration Space to determine the operating mode.

+     

+  2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.

+                 ___________________________________________

+                |           | Command Block | Control Block |

+                |  Channel  |   Registers   |   Registers   |

+                |___________|_______________|_______________|

+                |  Primary  |  1F0h - 1F7h  |  3F6h - 3F7h  |

+                |___________|_______________|_______________|

+                | Secondary |  170h - 177h  |  376h - 377h  |

+                |___________|_______________|_______________|

+        

+                  Table 1. Compatibility resource mappings

+        

+     b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs

+        in IDE controller's PCI Configuration Space, shown in the Table 2 below.

+               ___________________________________________________

+              |           |   Command Block   |   Control Block   |

+              |  Channel  |     Registers     |     Registers     |

+              |___________|___________________|___________________|

+              |  Primary  | BAR at offset 0x10| BAR at offset 0x14|

+              |___________|___________________|___________________|

+              | Secondary | BAR at offset 0x18| BAR at offset 0x1C|

+              |___________|___________________|___________________|

+      

+                        Table 2. BARs for Register Mapping

+        Note: Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for 

+              primary, 0374h for secondary. So 2 bytes extra offset should be 

+              added to the base addresses read from BARs.

+  

+  For more details, please refer to PCI IDE Controller Specification and Intel 

+  ICH4 Datasheet.

+  

+Arguments:

+  PciIo             - Pointer to the EFI_PCI_IO_PROTOCOL instance

+  IdeRegsBaseAddr   - Pointer to IDE_REGISTERS_BASE_ADDR to 

+                      receive IDE IO port registers' base addresses

+                      

+Returns:

+    

+--*/

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+  PCI_TYPE00  PciData;

+

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint8,

+                        0,

+                        sizeof (PciData),

+                        &PciData

+                        );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {

+    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  = 0x1f0;

+    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  = 0x3f6;

+    IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr     = 

+    (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));

+  } else {

+    //

+    // The BARs should be of IO type

+    //

+    if ((PciData.Device.Bar[0] & bit0) == 0 || 

+        (PciData.Device.Bar[1] & bit0) == 0) {

+      return EFI_UNSUPPORTED;

+    }

+

+    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  =

+    (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);

+    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  =

+    (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);

+    IdeRegsBaseAddr[IdePrimary].BusMasterBaseAddr     =

+    (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));

+  }

+

+  if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {

+    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  = 0x170;

+    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  = 0x376;

+    IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr     =

+    (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));

+  } else {

+    //

+    // The BARs should be of IO type

+    //

+    if ((PciData.Device.Bar[2] & bit0) == 0 ||

+        (PciData.Device.Bar[3] & bit0) == 0) {

+      return EFI_UNSUPPORTED;

+    }

+

+    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  =

+    (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);

+    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  =

+    (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);

+    IdeRegsBaseAddr[IdeSecondary].BusMasterBaseAddr     =

+    (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ReassignIdeResources (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+  This function is used to requery IDE resources. The IDE controller will 

+  probably switch between native and legacy modes during the EFI->CSM->OS 

+  transfer. We do this everytime before an BlkIo operation to ensure its

+  succeess.

+  

+Arguments:

+  IdeDev - The BLK_IO private data which specifies the IDE device

+  

+++*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Returns:'

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS              Status;

+  IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];

+  UINT16                  CommandBlockBaseAddr;

+  UINT16                  ControlBlockBaseAddr;

+

+  //

+  // Requery IDE IO port registers' base addresses in case of the switch of

+  // native and legacy modes

+  //

+  Status = GetIdeRegistersBaseAddr (IdeDev->PciIo, IdeRegsBaseAddr);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ZeroMem (IdeDev->IoPort, sizeof (IDE_BASE_REGISTERS));

+  CommandBlockBaseAddr                = IdeRegsBaseAddr[IdeDev->Channel].CommandBlockBaseAddr;

+  ControlBlockBaseAddr                = IdeRegsBaseAddr[IdeDev->Channel].ControlBlockBaseAddr;

+

+  IdeDev->IoPort->Data                = CommandBlockBaseAddr;

+  (*(UINT16 *) &IdeDev->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);

+  IdeDev->IoPort->SectorCount         = (UINT16) (CommandBlockBaseAddr + 0x02);

+  IdeDev->IoPort->SectorNumber        = (UINT16) (CommandBlockBaseAddr + 0x03);

+  IdeDev->IoPort->CylinderLsb         = (UINT16) (CommandBlockBaseAddr + 0x04);

+  IdeDev->IoPort->CylinderMsb         = (UINT16) (CommandBlockBaseAddr + 0x05);

+  IdeDev->IoPort->Head                = (UINT16) (CommandBlockBaseAddr + 0x06);

+

+  (*(UINT16 *) &IdeDev->IoPort->Reg)  = (UINT16) (CommandBlockBaseAddr + 0x07);

+  (*(UINT16 *) &IdeDev->IoPort->Alt)  = ControlBlockBaseAddr;

+  IdeDev->IoPort->DriveAddress        = (UINT16) (ControlBlockBaseAddr + 0x01);

+  IdeDev->IoPort->MasterSlave         = (UINT16) ((IdeDev->Device == IdeMaster) ? 1 : 0);

+

+  IdeDev->IoPort->BusMasterBaseAddr   = IdeRegsBaseAddr[IdeDev->Channel].BusMasterBaseAddr;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CheckPowerMode (

+  IDE_BLK_IO_DEV    *IdeDev

+  )

+/*++

+ Routine Description:

+ 

+  Read SATA registers to detect SATA disks

+

+ Arguments:

+

+  IdeDev - The BLK_IO private data which specifies the IDE device

+  

+++*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Returns:'

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  UINT8       ErrorRegister;

+  EFI_STATUS  Status;

+

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0)

+    );

+

+  //

+  // Wait 31 seconds for BSY clear. BSY should be in clear state if there exists

+  // a device (initial state). Normally, BSY is also in clear state if there is

+  // no device

+  //

+  Status = WaitForBSYClear (IdeDev, 31000);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // select device, read error register

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0)

+    );

+  Status        = DRDYReady (IdeDev, 200);

+

+  ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+  if ((ErrorRegister == 0x01) || (ErrorRegister == 0x81)) {

+    return EFI_SUCCESS;

+  } else {

+    return EFI_NOT_FOUND;

+  }

+}

+

+//

+// DiscoverIdeDevice

+//

+EFI_STATUS

+DiscoverIdeDevice (

+  IN IDE_BLK_IO_DEV *IdeDev

+  )

+/*++

+ Routine Description:

+ 

+  Detect if there is disk connected to this port

+

+ Arguments:

+

+  IdeDev - The BLK_IO private data which specifies the IDE device

+  

+++*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Returns:'

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+  BOOLEAN     SataFlag;

+

+  SataFlag = FALSE;

+  //

+  // This extra detection is for SATA disks

+  //

+  Status = CheckPowerMode (IdeDev);

+  if (Status == EFI_SUCCESS) {

+    SataFlag = TRUE;

+  }

+    

+  //

+  // If a channel has not been checked, check it now. Then set it to "checked" state

+  // After this step, all devices in this channel have been checked.

+  //

+  Status = DetectIDEController (IdeDev);

+

+  if ((EFI_ERROR (Status)) && !SataFlag) {

+    return EFI_NOT_FOUND;

+  }

+  

+  //

+  // Device exists. test if it is an ATA device

+  //

+  Status = ATAIdentify (IdeDev);

+  if (EFI_ERROR (Status)) {

+    //

+    // if not ATA device, test if it is an ATAPI device

+    //

+    Status = ATAPIIdentify (IdeDev);

+    if (EFI_ERROR (Status)) {

+      //

+      // if not ATAPI device either, return error.

+      //

+      return EFI_NOT_FOUND;

+    }

+  }

+

+  //

+  // Init Block I/O interface

+  //

+  IdeDev->BlkIo.Revision            = EFI_BLOCK_IO_PROTOCOL_REVISION;

+  IdeDev->BlkIo.Reset               = IDEBlkIoReset;

+  IdeDev->BlkIo.ReadBlocks          = IDEBlkIoReadBlocks;

+  IdeDev->BlkIo.WriteBlocks         = IDEBlkIoWriteBlocks;

+  IdeDev->BlkIo.FlushBlocks         = IDEBlkIoFlushBlocks;

+

+  IdeDev->BlkMedia.LogicalPartition = FALSE;

+  IdeDev->BlkMedia.WriteCaching     = FALSE;

+

+  //

+  // Init Disk Info interface

+  //

+  gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID));

+  IdeDev->DiskInfo.Inquiry    = IDEDiskInfoInquiry;

+  IdeDev->DiskInfo.Identify   = IDEDiskInfoIdentify;

+  IdeDev->DiskInfo.SenseData  = IDEDiskInfoSenseData;

+  IdeDev->DiskInfo.WhichIde   = IDEDiskInfoWhichIde;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DetectIDEController (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+  

+  Name: DetectIDEController

+

+

+  Purpose: 

+      This function is called by DiscoverIdeDevice(). It is used for detect 

+      whether the IDE device exists in the specified Channel as the specified 

+      Device Number.

+

+      There is two IDE channels: one is Primary Channel, the other is 

+      Secondary Channel.(Channel is the logical name for the physical "Cable".) 

+      Different channel has different register group.

+

+      On each IDE channel, at most two IDE devices attach, 

+      one is called Device 0 (Master device), the other is called Device 1 

+      (Slave device). The devices on the same channel co-use the same register 

+      group, so before sending out a command for a specified device via command 

+      register, it is a must to select the current device to accept the command 

+      by set the device number in the Head/Device Register.

+ 

+            

+  Parameters:

+      IDE_BLK_IO_DEV  IN    *IdeDev

+            pointer pointing to IDE_BLK_IO_DEV data structure, used

+            to record all the information of the IDE device.

+

+

+  Returns:    

+      TRUE      

+            successfully detects device.

+

+      FALSE

+            any failure during detection process will return this

+            value.

+

+

+  Notes:

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  EFI_STATUS  Status;

+  UINT8       ErrorReg;

+  UINT8       StatusReg;

+  UINT8       InitStatusReg;

+  EFI_STATUS  DeviceStatus;

+

+  //

+  // Slave device has been detected with master device.

+  //

+  if ((IdeDev->Device) == 1) {

+    if (SlaveDeviceExist) {

+      //

+      // If master not exists but slave exists, slave have to wait a while

+      //

+      if (!MasterDeviceExist) {

+        //

+        // if single slave can't be detected, add delay 4s here.

+        //

+        gBS->Stall (4000000);

+      }

+

+      return EFI_SUCCESS;

+    } else {

+      return EFI_NOT_FOUND;

+    }

+  }

+      

+  //

+  // Select slave device

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((1 << 4) | 0xe0)

+    );

+  gBS->Stall (100);

+

+  //

+  // Save the init slave status register

+  //

+  InitStatusReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+

+  //

+  // Select master back

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((0 << 4) | 0xe0)

+    );

+  gBS->Stall (100);

+  //

+  // Send ATA Device Execut Diagnostic command.

+  // This command should work no matter DRDY is ready or not

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0x90);

+

+  Status    = WaitForBSYClear (IdeDev, 3500);

+

+  ErrorReg  = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+

+  //

+  // Master Error register is 0x01. D0 passed, D1 passed or not present.

+  // Master Error register is 0x81. D0 passed, D1 failed. Return.

+  // Master Error register is other value. D0 failed, D1 passed or not present..

+  //

+  if (ErrorReg == 0x01) {

+    MasterDeviceExist = TRUE;

+    DeviceStatus      = EFI_SUCCESS;

+  } else if (ErrorReg == 0x81) {

+

+    MasterDeviceExist = TRUE;

+    DeviceStatus      = EFI_SUCCESS;

+    SlaveDeviceExist  = FALSE;

+

+    return DeviceStatus;

+  } else {

+    MasterDeviceExist = FALSE;

+    DeviceStatus      = EFI_NOT_FOUND;

+  }

+    

+  //

+  // Master Error register is not 0x81, Go on check Slave

+  //

+

+  //

+  // select slave

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((1 << 4) | 0xe0)

+    );

+

+  gBS->Stall (300);

+  ErrorReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+

+  //

+  // Slave Error register is not 0x01, D1 failed. Return.

+  //

+  if (ErrorReg != 0x01) {

+    SlaveDeviceExist = FALSE;

+    return DeviceStatus;

+  }

+

+  StatusReg = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+

+  //

+  // Most ATAPI devices don't set DRDY bit, so test with a slow but accurate

+  //   "ATAPI TEST UNIT READY" command

+  //

+  if (((StatusReg & DRDY) == 0) && ((InitStatusReg & DRDY) == 0)) {

+    Status = AtapiTestUnitReady (IdeDev);

+

+    //

+    // Still fail, Slave doesn't exist.

+    //

+    if (EFI_ERROR (Status)) {

+      SlaveDeviceExist = FALSE;

+      return DeviceStatus;

+    }

+  }

+

+  //

+  // Error reg is 0x01 and DRDY is ready,

+  //  or ATAPI test unit ready success,

+  //  or  init Slave status DRDY is ready

+  // Slave exists.

+  //

+  SlaveDeviceExist = TRUE;

+

+  return DeviceStatus;

+

+}

+

+EFI_STATUS

+DRQClear (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+  Name:   DRQClear

+

+

+  Purpose: 

+        This function is used to poll for the DRQ bit clear in the Status 

+        Register. DRQ is cleared when the device is finished transferring data. 

+        So this function is called after data transfer is finished.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+            pointer pointing to IDE_BLK_IO_DEV data structure, used

+            to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+            used to designate the timeout for the DRQ clear.

+

+  Returns:  

+        EFI_SUCCESS

+            DRQ bit clear within the time out.

+

+        EFI_TIMEOUT

+            DRQ bit not clear within the time out. 

+

+

+  Notes:

+        Read Status Register will clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+{

+  UINT32  Delay;

+  UINT8   StatusRegister;

+  UINT8   ErrorRegister;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+

+    StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+

+    //

+    // wait for BSY == 0 and DRQ == 0

+    //

+    if ((StatusRegister & (DRQ | BSY)) == 0) {

+      break;

+    }

+

+    if ((StatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+      if ((ErrorRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    //  Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    Delay--;

+

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DRQClear2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+  Name:   DRQClear2

+

+

+  Purpose: 

+        This function is used to poll for the DRQ bit clear in the Alternate 

+        Status Register. DRQ is cleared when the device is finished 

+        transferring data. So this function is called after data transfer

+        is finished.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+          used to designate the timeout for the DRQ clear.

+

+  Returns:  

+        EFI_SUCCESS

+          DRQ bit clear within the time out.

+

+        EFI_TIMEOUT

+          DRQ bit not clear within the time out. 

+

+

+  Notes:

+        Read Alternate Status Register will not clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+{

+  UINT32  Delay;

+  UINT8   AltRegister;

+  UINT8   ErrorRegister;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+

+    AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);

+

+    //

+    //  wait for BSY == 0 and DRQ == 0

+    //

+    if ((AltRegister & (DRQ | BSY)) == 0) {

+      break;

+    }

+

+    if ((AltRegister & (BSY | ERR)) == ERR) {

+

+      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+      if ((ErrorRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    Delay--;

+

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DRQReady (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+  Name:   DRQReady

+

+  

+  Purpose: 

+        This function is used to poll for the DRQ bit set in the 

+        Status Register.

+        DRQ is set when the device is ready to transfer data. So this function

+        is called after the command is sent to the device and before required 

+        data is transferred.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+            pointer pointing to IDE_BLK_IO_DEV data structure,used

+            to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+            used to designate the timeout for the DRQ ready.

+

+

+  Returns:  

+        EFI_SUCCESS

+            DRQ bit set within the time out.

+

+        EFI_TIMEOUT

+            DRQ bit not set within the time out.

+            

+        EFI_ABORTED

+            DRQ bit not set caused by the command abort.

+

+  Notes:

+        Read Status Register will clear interrupt status.

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+{

+  UINT32  Delay;

+  UINT8   StatusRegister;

+  UINT8   ErrorRegister;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+    //

+    //  read Status Register will clear interrupt

+    //

+    StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+

+    //

+    //  BSY==0,DRQ==1

+    //

+    if ((StatusRegister & (BSY | DRQ)) == DRQ) {

+      break;

+    }

+

+    if ((StatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+      if ((ErrorRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DRQReady2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+  Name:   DRQReady2

+

+

+  Purpose: 

+        This function is used to poll for the DRQ bit set in the 

+        Alternate Status Register. DRQ is set when the device is ready to 

+        transfer data. So this function is called after the command 

+        is sent to the device and before required data is transferred.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+          used to designate the timeout for the DRQ ready.

+

+  Returns:  

+        EFI_SUCCESS

+          DRQ bit set within the time out.

+

+        EFI_TIMEOUT

+          DRQ bit not set within the time out. 

+        

+        EFI_ABORTED

+            DRQ bit not set caused by the command abort.

+

+  Notes:

+        Read Alternate Status Register will not clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+{

+  UINT32  Delay;

+  UINT8   AltRegister;

+  UINT8   ErrorRegister;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+

+  do {

+    //

+    //  Read Alternate Status Register will not clear interrupt status

+    //

+    AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);

+    //

+    // BSY == 0 , DRQ == 1

+    //

+    if ((AltRegister & (BSY | DRQ)) == DRQ) {

+      break;

+    }

+

+    if ((AltRegister & (BSY | ERR)) == ERR) {

+

+      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+      if ((ErrorRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WaitForBSYClear (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+  Name:

+        WaitForBSYClear

+

+

+  Purpose: 

+        This function is used to poll for the BSY bit clear in the 

+        Status Register. BSY is clear when the device is not busy.

+        Every command must be sent after device is not busy.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+          used to designate the timeout for the DRQ ready.

+

+  Returns:  

+        EFI_SUCCESS

+          BSY bit clear within the time out.

+

+        EFI_TIMEOUT

+          BSY bit not clear within the time out. 

+

+

+  Notes:

+        Read Status Register will clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+{

+  UINT32  Delay;

+  UINT8   StatusRegister;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+

+    StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+    if ((StatusRegister & BSY) == 0x00) {

+      break;

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    Delay--;

+

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// WaitForBSYClear2

+//

+EFI_STATUS

+WaitForBSYClear2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+  Name:

+        WaitForBSYClear2

+

+

+  Purpose: 

+        This function is used to poll for the BSY bit clear in the 

+        Alternate Status Register. BSY is clear when the device is not busy.

+        Every command must be sent after device is not busy.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+          used to designate the timeout for the DRQ ready.

+

+  Returns:  

+        EFI_SUCCESS

+          BSY bit clear within the time out.

+

+        EFI_TIMEOUT

+          BSY bit not clear within the time out. 

+

+

+  Notes:

+        Read Alternate Status Register will not clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+{

+  UINT32  Delay;

+  UINT8   AltRegister;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+    AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);

+    if ((AltRegister & BSY) == 0x00) {

+      break;

+    }

+

+    gBS->Stall (30);

+

+    Delay--;

+

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// DRDYReady

+//

+EFI_STATUS

+DRDYReady (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           DelayInMilliSeconds

+  )

+/*++

+  Name:

+        DRDYReady

+

+

+  Purpose: 

+        This function is used to poll for the DRDY bit set in the 

+        Status Register. DRDY bit is set when the device is ready 

+        to accept command. Most ATA commands must be sent after 

+        DRDY set except the ATAPI Packet Command.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+          used to designate the timeout for the DRQ ready.

+

+  Returns:  

+        EFI_SUCCESS

+          DRDY bit set within the time out.

+

+        EFI_TIMEOUT

+          DRDY bit not set within the time out. 

+

+

+  Notes:

+        Read Status Register will clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DelayInMilliSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+{

+  UINT32  Delay;

+  UINT8   StatusRegister;

+  UINT8   ErrorRegister;

+

+  Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+    StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+    //

+    //  BSY == 0 , DRDY == 1

+    //

+    if ((StatusRegister & (DRDY | BSY)) == DRDY) {

+      break;

+    }

+

+    if ((StatusRegister & (BSY | ERR)) == ERR) {

+

+      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+      if ((ErrorRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    gBS->Stall (15);

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// DRDYReady2

+//

+EFI_STATUS

+DRDYReady2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           DelayInMilliSeconds

+  )

+/*++

+  Name:

+        DRDYReady2

+

+

+  Purpose: 

+        This function is used to poll for the DRDY bit set in the 

+        Alternate Status Register. DRDY bit is set when the device is ready 

+        to accept command. Most ATA commands must be sent after 

+        DRDY set except the ATAPI Packet Command.

+

+

+  Parameters:

+        IDE_BLK_IO_DEV  IN    *IdeDev

+          pointer pointing to IDE_BLK_IO_DEV data structure, used

+          to record all the information of the IDE device.

+

+        UINTN     IN    TimeoutInMilliSeconds

+          used to designate the timeout for the DRQ ready.

+

+  Returns:  

+        EFI_SUCCESS

+          DRDY bit set within the time out.

+

+        EFI_TIMEOUT

+          DRDY bit not set within the time out. 

+

+

+  Notes:

+        Read Alternate Status Register will clear interrupt status.

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    IdeDev - add argument and description to function comment

+// TODO:    DelayInMilliSeconds - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+{

+  UINT32  Delay;

+  UINT8   AltRegister;

+  UINT8   ErrorRegister;

+

+  Delay = (UINT32) (((DelayInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+    AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);

+    //

+    //  BSY == 0 , DRDY == 1

+    //

+    if ((AltRegister & (DRDY | BSY)) == DRDY) {

+      break;

+    }

+

+    if ((AltRegister & (BSY | ERR)) == ERR) {

+

+      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

+      if ((ErrorRegister & ABRT_ERR) == ABRT_ERR) {

+        return EFI_ABORTED;

+      }

+    }

+

+    gBS->Stall (30);

+

+    Delay--;

+  } while (Delay);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// SwapStringChars

+//

+VOID

+SwapStringChars (

+  IN CHAR8  *Destination,

+  IN CHAR8  *Source,

+  IN UINT32 Size

+  )

+/*++

+  Name:

+        SwapStringChars

+

+

+  Purpose: 

+        This function is a helper function used to change the char order in a 

+        string. It is designed specially for the PrintAtaModuleName() function.

+        After the IDE device is detected, the IDE driver gets the device module

+        name by sending ATA command called ATA Identify Command or ATAPI 

+        Identify Command to the specified IDE device. The module name returned 

+        is a string of ASCII characters: the first character is bit8--bit15 

+        of the first word, the second character is bit0--bit7 of the first word 

+        and so on. Thus the string can not be print directly before it is 

+        preprocessed by this func to change the order of characters in 

+        each word in the string.

+

+

+  Parameters:

+        CHAR8 IN    *Destination

+          Indicates the destination string.

+

+        CHAR8 IN    *Source

+          Indicates the source string.

+

+        UINT8 IN    Size

+          the length of the string

+

+

+  Returns:  

+        none

+

+  Notes:

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO:    Destination - add argument and description to function comment

+// TODO:    Source - add argument and description to function comment

+// TODO:    Size - add argument and description to function comment

+{

+  UINT32  Index;

+  CHAR8   Temp;

+

+  for (Index = 0; Index < Size; Index += 2) {

+

+    Temp                    = Source[Index + 1];

+    Destination[Index + 1]  = Source[Index];

+    Destination[Index]      = Temp;

+  }

+}

+

+//

+// ReleaseIdeResources

+//

+VOID

+ReleaseIdeResources (

+  IN  IDE_BLK_IO_DEV  *IdeBlkIoDevice

+  )

+/*++

+Routing Description:

+

+  Release resources of an IDE device before stopping it.

+

+Arguments:

+

+  IdeBlkIoDevice  --  Standard IDE device private data structure

+

+

+Returns:

+

+    NONE

+    

+---*/

+// TODO: function comment is missing 'Routine Description:'

+{

+  if (IdeBlkIoDevice == NULL) {

+    return ;

+  }

+

+  //

+  // Release all the resourses occupied by the IDE_BLK_IO_DEV

+  //

+  

+  if (IdeBlkIoDevice->SenseData != NULL) {

+    gBS->FreePool (IdeBlkIoDevice->SenseData);

+    IdeBlkIoDevice->SenseData = NULL;

+  }

+

+  if (IdeBlkIoDevice->Cache != NULL) {

+    gBS->FreePool (IdeBlkIoDevice->Cache);

+    IdeBlkIoDevice->Cache = NULL;

+  }

+

+  if (IdeBlkIoDevice->pIdData != NULL) {

+    gBS->FreePool (IdeBlkIoDevice->pIdData);

+    IdeBlkIoDevice->pIdData = NULL;

+  }

+

+  if (IdeBlkIoDevice->pInquiryData != NULL) {

+    gBS->FreePool (IdeBlkIoDevice->pInquiryData);

+    IdeBlkIoDevice->pInquiryData = NULL;

+  }

+

+  if (IdeBlkIoDevice->ControllerNameTable != NULL) {

+    FreeUnicodeStringTable (IdeBlkIoDevice->ControllerNameTable);

+    IdeBlkIoDevice->ControllerNameTable = NULL;

+  }

+

+  if (IdeBlkIoDevice->IoPort != NULL) {

+    gBS->FreePool (IdeBlkIoDevice->IoPort);

+  }

+

+  if (IdeBlkIoDevice->DevicePath != NULL) {

+    gBS->FreePool (IdeBlkIoDevice->DevicePath);

+  }

+

+  gBS->FreePool (IdeBlkIoDevice);

+  IdeBlkIoDevice = NULL;

+

+  return ;

+}

+

+//

+// SetDeviceTransferMode

+//

+EFI_STATUS

+SetDeviceTransferMode (

+  IN IDE_BLK_IO_DEV       *IdeDev,

+  IN ATA_TRANSFER_MODE    *TransferMode

+  )

+/*++

+Routing Description:

+

+  Set the calculated Best transfer mode to a detected device

+

+Arguments:

+

+  IdeDev       --  Standard IDE device private data structure

+  TransferMode --  The device transfer mode to be set

+

+Returns:

+

+    Set transfer mode Command execute status

+    

+---*/

+// TODO: function comment is missing 'Routine Description:'

+{

+  EFI_STATUS  Status;

+  UINT8       DeviceSelect;

+  UINT8       SectorCount;

+

+  DeviceSelect  = 0;

+  DeviceSelect  = (UINT8) ((IdeDev->Device) << 4);

+  SectorCount   = *((UINT8 *) TransferMode);

+

+  //

+  // Send SET FEATURE command (sub command 0x03) to set pio mode.

+  //

+  Status = AtaNonDataCommandIn (

+            IdeDev,

+            SET_FEATURES_CMD,

+            DeviceSelect,

+            0x03,

+            SectorCount,

+            0,

+            0,

+            0

+            );

+

+  return Status;

+}

+

+EFI_STATUS

+AtaNonDataCommandIn (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT8           Feature,

+  IN  UINT8           SectorCount,

+  IN  UINT8           LbaLow,

+  IN  UINT8           LbaMiddle,

+  IN  UINT8           LbaHigh

+  )

+/*++

+

+Routine Description:

+

+  Send ATA command into device with NON_DATA protocol

+

+Arguments:

+

+  IdeDev      - Standard IDE device private data structure

+  AtaCommand  - The ATA command to be sent

+  Device      - The value in Device register

+  Feature     - The value in Feature register

+  SectorCount - The value in SectorCount register 

+  LbaLow      - The value in LBA_LOW register

+  LbaMiddle   - The value in LBA_MIDDLE register

+  LbaHigh     - The value in LBA_HIGH register

+

+Returns:

+

+  EFI_SUCCESS      - Reading succeed

+  EFI_ABORTED      - Command failed

+  EFI_DEVICE_ERROR - Device status error

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       StatusRegister;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0)

+    );

+

+  //

+  // ATA commands for ATA device must be issued when DRDY is set

+  //

+  Status = DRDYReady (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Pass parameter into device register block

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  //

+  // Send command via Command Register

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  //

+  // Wait for command completion

+  //

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+  if ((StatusRegister & ERR) == ERR) {

+    //

+    // Failed to execute command, abort operation

+    //

+    return EFI_ABORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AtaNonDataCommandInExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT16          Feature,

+  IN  UINT16          SectorCount,

+  IN  EFI_LBA         LbaAddress

+  )

+/*++

+

+Routine Description:

+

+  Send ATA Ext command into device with NON_DATA protocol

+

+Arguments:

+

+  IdeDev      - Standard IDE device private data structure

+  AtaCommand  - The ATA command to be sent

+  Device      - The value in Device register

+  Feature     - The value in Feature register

+  SectorCount - The value in SectorCount register 

+  LbaAddress - The LBA address in 48-bit mode

+

+Returns:

+

+  EFI_SUCCESS      - Reading succeed

+  EFI_ABORTED      - Command failed

+  EFI_DEVICE_ERROR - Device status error

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       StatusRegister;

+  UINT8       SectorCount8;

+  UINT8       Feature8;

+  UINT8       LbaLow;

+  UINT8       LbaMid;

+  UINT8       LbaHigh;

+

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)

+  //

+  IDEWritePortB (

+    IdeDev->PciIo,

+    IdeDev->IoPort->Head,

+    (UINT8) ((IdeDev->Device << 4) | 0xe0)

+    );

+

+  //

+  // ATA commands for ATA device must be issued when DRDY is set

+  //

+  Status = DRDYReady (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Pass parameter into device register block

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);

+

+  //

+  // Fill the feature register, which is a two-byte FIFO. Need write twice.

+  //

+  Feature8 = (UINT8) (Feature >> 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);

+

+  Feature8 = (UINT8) Feature;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);

+

+  //

+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.

+  //

+  SectorCount8 = (UINT8) (SectorCount >> 8);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  SectorCount8 = (UINT8) SectorCount;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);

+

+  //

+  // Fill the start LBA registers, which are also two-byte FIFO

+  //

+  LbaLow  = (UINT8) RShiftU64 (LbaAddress, 24);

+  LbaMid  = (UINT8) RShiftU64 (LbaAddress, 32);

+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  LbaLow  = (UINT8) LbaAddress;

+  LbaMid  = (UINT8) RShiftU64 (LbaAddress, 8);

+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);

+

+  //

+  // Send command via Command Register

+  //

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);

+

+  //

+  // Wait for command completion

+  //

+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

+  if ((StatusRegister & ERR) == ERR) {

+    //

+    // Failed to execute command, abort operation

+    //

+    return EFI_ABORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// SetDriveParameters

+//

+EFI_STATUS

+SetDriveParameters (

+  IN IDE_BLK_IO_DEV       *IdeDev,

+  IN ATA_DRIVE_PARMS      *DriveParameters

+  )

+/*++

+Routine Description: 

+

+  Set drive parameters for devices not support PACKETS command

+

+Arguments:

+

+  IdeDev       --  Standard IDE device private data structure

+  DriveParameters --  The device parameters to be set into the disk

+

+Returns:

+

+  SetParameters Command execute status

+    

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       DeviceSelect;

+

+  DeviceSelect  = 0;

+  DeviceSelect  = (UINT8) ((IdeDev->Device) << 4);

+

+  //

+  // Send Init drive parameters

+  //

+  Status = AtaPioDataIn (

+            IdeDev,

+            NULL,

+            0,

+            INIT_DRIVE_PARAM_CMD,

+            (UINT8) (DeviceSelect + DriveParameters->Heads),

+            DriveParameters->Sector,

+            0,

+            0,

+            0

+            );

+

+  //

+  // Send Set Multiple parameters

+  //

+  Status = AtaPioDataIn (

+            IdeDev,

+            NULL,

+            0,

+            SET_MULTIPLE_MODE_CMD,

+            DeviceSelect,

+            DriveParameters->MultipleSector,

+            0,

+            0,

+            0

+            );

+

+  return Status;

+}

+

+EFI_STATUS

+EnableInterrupt (

+  IN IDE_BLK_IO_DEV       *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  UINT8 DeviceControl;

+

+  //

+  // Enable interrupt for DMA operation

+  //

+  DeviceControl = 0;

+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h
new file mode 100644
index 0000000..4c43ab9
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h
@@ -0,0 +1,1806 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ide.h

+

+Abstract:

+

+    Header file for IDE Bus Driver, containing the helper functions' 

+    entire prototype.

+

+Revision History

+

+    2002-6: Add Atapi6 enhancement, support >120GB hard disk, including

+            Add - IDEBlkIoReadBlocksExt() func definition

+            Add - IDEBlkIoWriteBlocksExt() func definition

+            

+++*/

+

+// TODO: fix comment to end with --*/

+#ifndef _IDE_H

+#define _IDE_H

+

+//

+// Helper functions Prototype

+//

+EFI_STATUS

+DeRegisterIdeDevice (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  EFI_HANDLE                     Handle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Controller  - TODO: add argument description

+  Handle      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EnableIdeDevice (

+  IN EFI_HANDLE                          Controller,

+  IN EFI_PCI_IO_PROTOCOL                 *PciIo,

+  IN EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath,

+  IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller          - TODO: add argument description

+  PciIo               - TODO: add argument description

+  ParentDevicePath    - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+UINT8

+IDEReadPortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+IDEReadPortWMultiple (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINTN                 Count,

+  OUT  VOID                 *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo   - TODO: add argument description

+  Port    - TODO: add argument description

+  Count   - TODO: add argument description

+  Buffer  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+IDEWritePortB (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT8                 Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+IDEWritePortW (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINT16                Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo - TODO: add argument description

+  Port  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+IDEWritePortWMultiple (

+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,

+  IN  UINT16                Port,

+  IN  UINTN                 Count,

+  IN  VOID                  *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo   - TODO: add argument description

+  Port    - TODO: add argument description

+  Count   - TODO: add argument description

+  Buffer  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetIdeRegistersBaseAddr (

+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,

+  OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo           - TODO: add argument description

+  IdeRegsBaseAddr - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ReassignIdeResources (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DiscoverIdeDevice (

+  IN IDE_BLK_IO_DEV *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DetectIDEController (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DRQClear (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev                - TODO: add argument description

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DRQClear2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev                - TODO: add argument description

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DRQReady (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev                - TODO: add argument description

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DRQReady2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev                - TODO: add argument description

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WaitForBSYClear (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev                - TODO: add argument description

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WaitForBSYClear2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev                - TODO: add argument description

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DRDYReady (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           DelayInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev              - TODO: add argument description

+  DelayInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DRDYReady2 (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINTN           DelayInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev              - TODO: add argument description

+  DelayInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+SwapStringChars (

+  IN CHAR8  *Destination,

+  IN CHAR8  *Source,

+  IN UINT32 Size

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Destination - TODO: add argument description

+  Source      - TODO: add argument description

+  Size        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+//  ATA device functions' prototype

+//

+EFI_STATUS

+ATAIdentify (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+PrintAtaModuleName (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaPioDataIn (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Head,

+  IN  UINT8           SectorCount,

+  IN  UINT8           SectorNumber,

+  IN  UINT8           CylinderLsb,

+  IN  UINT8           CylinderMsb

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev        - TODO: add argument description

+  Buffer        - TODO: add argument description

+  ByteCount     - TODO: add argument description

+  AtaCommand    - TODO: add argument description

+  Head          - TODO: add argument description

+  SectorCount   - TODO: add argument description

+  SectorNumber  - TODO: add argument description

+  CylinderLsb   - TODO: add argument description

+  CylinderMsb   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaPioDataOut (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Head,

+  IN  UINT8           SectorCount,

+  IN  UINT8           SectorNumber,

+  IN  UINT8           CylinderLsb,

+  IN  UINT8           CylinderMsb

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev        - TODO: add argument description

+  Buffer        - TODO: add argument description

+  ByteCount     - TODO: add argument description

+  AtaCommand    - TODO: add argument description

+  Head          - TODO: add argument description

+  SectorCount   - TODO: add argument description

+  SectorNumber  - TODO: add argument description

+  CylinderLsb   - TODO: add argument description

+  CylinderMsb   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CheckErrorStatus (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaReadSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaWriteSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *BufferData,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  BufferData      - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaSoftReset (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaBlkIoReadBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeBlkIoDevice  - TODO: add argument description

+  MediaId         - TODO: add argument description

+  LBA             - TODO: add argument description

+  BufferSize      - TODO: add argument description

+  Buffer          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaBlkIoWriteBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeBlkIoDevice  - TODO: add argument description

+  MediaId         - TODO: add argument description

+  LBA             - TODO: add argument description

+  BufferSize      - TODO: add argument description

+  Buffer          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// ATAPI device functions' prototype

+//

+EFI_STATUS

+ATAPIIdentify (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiInquiry (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiPacketCommandIn (

+  IN  IDE_BLK_IO_DEV        *IdeDev,

+  IN  ATAPI_PACKET_COMMAND  *Packet,

+  IN  UINT16                *Buffer,

+  IN  UINT32                ByteCount,

+  IN  UINTN                 TimeOut

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev    - TODO: add argument description

+  Packet    - TODO: add argument description

+  Buffer    - TODO: add argument description

+  ByteCount - TODO: add argument description

+  TimeOut   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiPacketCommandOut (

+  IN  IDE_BLK_IO_DEV        *IdeDev,

+  IN  ATAPI_PACKET_COMMAND  *Packet,

+  IN  UINT16                *Buffer,

+  IN  UINT32                ByteCount,

+  IN  UINTN                 TimeOut

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev    - TODO: add argument description

+  Packet    - TODO: add argument description

+  Buffer    - TODO: add argument description

+  ByteCount - TODO: add argument description

+  TimeOut   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PioReadWriteData (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT16          *Buffer,

+  IN  UINT32          ByteCount,

+  IN  BOOLEAN         Read,

+  IN  UINTN           TimeOut

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev    - TODO: add argument description

+  Buffer    - TODO: add argument description

+  ByteCount - TODO: add argument description

+  Read      - TODO: add argument description

+  TimeOut   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiTestUnitReady (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiRequestSense (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  OUT UINTN           *SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiReadCapacity (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiDetectMedia (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  OUT BOOLEAN         *MediaChange

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  MediaChange - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiReadSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  Buffer          - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiWriteSectors (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  EFI_LBA         Lba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  Buffer          - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiSoftReset (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiBlkIoReadBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeBlkIoDevice  - TODO: add argument description

+  MediaId         - TODO: add argument description

+  LBA             - TODO: add argument description

+  BufferSize      - TODO: add argument description

+  Buffer          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtapiBlkIoWriteBlocks (

+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,

+  IN UINT32           MediaId,

+  IN EFI_LBA          LBA,

+  IN UINTN            BufferSize,

+  OUT VOID            *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeBlkIoDevice  - TODO: add argument description

+  MediaId         - TODO: add argument description

+  LBA             - TODO: add argument description

+  BufferSize      - TODO: add argument description

+  Buffer          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsNoMedia (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsMediaError (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsMediaChange (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsDriveReady (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts,

+  OUT BOOLEAN               *NeedRetry

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+  NeedRetry   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+HaveSenseKey (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IsLS120orZipWriteProtected (

+  IN  IDE_BLK_IO_DEV    *IdeDev,

+  OUT BOOLEAN           *WriteProtected

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  WriteProtected  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+ReleaseIdeResources (

+  IN  IDE_BLK_IO_DEV  *IdeBlkIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeBlkIoDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SetDeviceTransferMode (

+  IN IDE_BLK_IO_DEV       *IdeDev,

+  IN ATA_TRANSFER_MODE    *TransferMode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev        - TODO: add argument description

+  TransferMode  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ReadNativeMaxAddress (

+  IN  IDE_BLK_IO_DEV                *IdeDev,

+  OUT EFI_LBA                       *NativeMaxAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev            - TODO: add argument description

+  NativeMaxAddress  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SetMaxAddress (

+  IN  IDE_BLK_IO_DEV                *IdeDev,

+  IN  EFI_LBA                       MaxAddress,

+  IN  BOOLEAN                       bVolatile

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  MaxAddress  - TODO: add argument description

+  bVolatile   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaNonDataCommandIn (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT8           Feature,

+  IN  UINT8           SectorCount,

+  IN  UINT8           LbaLow,

+  IN  UINT8           LbaMiddle,

+  IN  UINT8           LbaHigh

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  AtaCommand  - TODO: add argument description

+  Device      - TODO: add argument description

+  Feature     - TODO: add argument description

+  SectorCount - TODO: add argument description

+  LbaLow      - TODO: add argument description

+  LbaMiddle   - TODO: add argument description

+  LbaHigh     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaNonDataCommandInExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT16          Feature,

+  IN  UINT16          SectorCount,

+  IN  EFI_LBA         LbaAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  AtaCommand  - TODO: add argument description

+  Device      - TODO: add argument description

+  Feature     - TODO: add argument description

+  SectorCount - TODO: add argument description

+  LbaAddress  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaReadSectorsExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  StartLba        - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaWriteSectorsExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  StartLba        - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaUdmaReadExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  StartLba        - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaUdmaRead (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  StartLba        - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaUdmaWriteExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  StartLba        - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaUdmaWrite (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *DataBuffer,

+  IN  EFI_LBA         StartLba,

+  IN  UINTN           NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DataBuffer      - TODO: add argument description

+  StartLba        - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaCommandIssueExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT16          Feature,

+  IN  UINT16          SectorCount,

+  IN  EFI_LBA         LbaAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  AtaCommand  - TODO: add argument description

+  Device      - TODO: add argument description

+  Feature     - TODO: add argument description

+  SectorCount - TODO: add argument description

+  LbaAddress  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaCommandIssue (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  UINT8           AtaCommand,

+  IN  UINT8           Device,

+  IN  UINT16          Feature,

+  IN  UINT16          SectorCount,

+  IN  EFI_LBA         LbaAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  AtaCommand  - TODO: add argument description

+  Device      - TODO: add argument description

+  Feature     - TODO: add argument description

+  SectorCount - TODO: add argument description

+  LbaAddress  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaAtapi6Identify (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+VOID

+AtaSMARTSupport (

+  IN  IDE_BLK_IO_DEV  *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaPioDataInExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  OUT VOID        *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  EFI_LBA         StartLba,

+  IN  UINT16          SectorCount

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  Buffer      - TODO: add argument description

+  ByteCount   - TODO: add argument description

+  AtaCommand  - TODO: add argument description

+  StartLba    - TODO: add argument description

+  SectorCount - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AtaPioDataOutExt (

+  IN  IDE_BLK_IO_DEV  *IdeDev,

+  IN  VOID            *Buffer,

+  IN  UINT32          ByteCount,

+  IN  UINT8           AtaCommand,

+  IN  EFI_LBA         StartLba,

+  IN  UINT16          SectorCount

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev      - TODO: add argument description

+  Buffer      - TODO: add argument description

+  ByteCount   - TODO: add argument description

+  AtaCommand  - TODO: add argument description

+  StartLba    - TODO: add argument description

+  SectorCount - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SetDriveParameters (

+  IN IDE_BLK_IO_DEV       *IdeDev,

+  IN ATA_DRIVE_PARMS      *DriveParameters

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev          - TODO: add argument description

+  DriveParameters - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EnableInterrupt (

+  IN IDE_BLK_IO_DEV       *IdeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IdeDev  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c
new file mode 100644
index 0000000..4cf882e
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c
@@ -0,0 +1,1391 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  idebus.c

+    

+Abstract: 

+    

+

+Revision History

+  This module is modified from DXE\IDE module for Ide Contriller Init support

+

+--*/

+

+#include "idebus.h"

+

+#define PCI_CLASS_MASS_STORAGE  0x01

+#define PCI_SUB_CLASS_IDE       0x01

+

+

+//

+// IDE Bus Driver Binding Protocol Instance

+//

+EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {

+  IDEBusDriverBindingSupported,

+  IDEBusDriverBindingStart,

+  IDEBusDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+//

+// ***********************************************************************************

+// IDEBusDriverBindingSupported

+// ***********************************************************************************

+//

+EFI_STATUS

+EFIAPI

+IDEBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+Routine Description:

+  Register Driver Binding protocol for this driver.

+  

+Arguments:

+  This   -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.

+  ControllerHandle    -- The handle of the controller to test.

+  RemainingDevicePath -- A pointer to the remaining portion of a device path.

+

+Returns: 

+  EFI_SUCCESS - Driver loaded.

+  other       - Driver not loaded.

+--*/

+// TODO:    Controller - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;

+  EFI_DEV_PATH                      *Node;

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;

+

+  if (RemainingDevicePath != NULL) {

+    Node = (EFI_DEV_PATH *) RemainingDevicePath;

+    if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||

+        Node->DevPath.SubType != MSG_ATAPI_DP ||

+        DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+ 

+  //

+  // Clsoe protocol, don't use device path protocol in the .Support() function

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  //

+  // Verify the Ide Controller Init Protocol, which installed by the

+  // IdeController module.

+  // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't

+  //         open BY_DRIVER here) That's why we don't check pciio protocol

+  // Note 2: ide_init driver check ide controller's pci config space, so we dont

+  //         check here any more to save code size

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiIdeControllerInitProtocolGuid,

+                  (VOID **) &IdeInit,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // If protocols were opened normally, closed it

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiIdeControllerInitProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+//

+// ***********************************************************************************

+// IDEBusDriverBindingStart

+// ***********************************************************************************

+//

+EFI_STATUS

+EFIAPI

+IDEBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Start this driver on Controller by detecting all disks and installing 

+      BlockIo protocol on them.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to bind driver to.

+    RemainingDevicePath - Not used, always produce all possible children.

+

+  Returns:

+    EFI_SUCCESS         - This driver is added to ControllerHandle.

+    EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_STATUS                        SavedStatus;

+  EFI_PCI_IO_PROTOCOL               *PciIo;

+  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;

+  EFI_DEV_PATH                      *Node;

+  UINT8                             IdeChannel;

+  UINT8                             BeginningIdeChannel;

+  UINT8                             EndIdeChannel;

+  UINT8                             IdeDevice;

+  UINT8                             BeginningIdeDevice;

+  UINT8                             EndIdeDevice;

+  IDE_BLK_IO_DEV                    *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];

+  IDE_BLK_IO_DEV                    *IdeBlkIoDevicePtr;

+  IDE_REGISTERS_BASE_ADDR           IdeRegsBaseAddr[IdeMaxChannel];

+  ATA_TRANSFER_MODE                 TransferMode;

+  ATA_DRIVE_PARMS                   DriveParameters;

+  EFI_DEV_PATH                      NewNode;

+  UINT8                             ConfigurationOptions;

+  UINT16                            CommandBlockBaseAddr;

+  UINT16                            ControlBlockBaseAddr;

+  UINTN                             DataSize;

+  UINT32                            Attributes;

+  IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;

+

+  //

+  // Local variables declaration for IdeControllerInit support

+  //

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;

+  BOOLEAN                           EnumAll;

+  BOOLEAN                           ChannelEnabled;

+  UINT8                             ChannelCount;

+  UINT8                             MaxDevices;

+  EFI_IDENTIFY_DATA                 IdentifyData;

+  EFI_ATA_COLLECTIVE_MODE           *SupportedModes;

+

+  IdeBusDriverPrivateData = NULL;

+  SupportedModes          = NULL;

+

+  //

+  // Perform IdeBus initialization

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {

+    return Status;

+  }

+  

+  //

+  // Now open the IDE_CONTROLLER_INIT protocol. Step7.1

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiIdeControllerInitProtocolGuid,

+                  (VOID **) &IdeInit,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  //

+  // The following OpenProtocol function with _GET_PROTOCOL attribute and

+  // will not return EFI_ALREADY_STARTED, so save it for now

+  //

+  SavedStatus = Status;

+

+  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {

+    DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));

+    //

+    // open protocol is not SUCCESS or not ALREADY_STARTED, error exit

+    //

+    goto ErrorExit;

+  }

+

+  //

+  // Save Enumall and ChannelCount. Step7.2

+  //

+  EnumAll       = IdeInit->EnumAll;

+  ChannelCount  = IdeInit->ChannelCount;

+

+  //

+  // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL

+  // attribute will not return EFI_ALREADY_STARTED

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));

+    goto ErrorExit;

+  }

+

+  //

+  // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable

+  //

+  if (SavedStatus != EFI_ALREADY_STARTED) {

+    IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));

+    if (IdeBusDriverPrivateData == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto ErrorExit;

+    }

+

+    ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &Controller,

+                    &gEfiCallerIdGuid,

+                    IdeBusDriverPrivateData,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      goto ErrorExit;

+    }

+

+  } else {

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiCallerIdGuid,

+                    (VOID **) &IdeBusDriverPrivateData,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      IdeBusDriverPrivateData = NULL;

+      goto ErrorExit;

+    }

+  }

+

+  Status = PciIo->Attributes (

+                    PciIo,

+                    EfiPciIoAttributeOperationEnable,

+                    EFI_PCI_DEVICE_ENABLE,

+                    NULL

+                    );

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  //

+  // Read the environment variable that contains the IDEBus Driver's

+  // Config options that were set by the Driver Configuration Protocol

+  //

+  DataSize = sizeof (ConfigurationOptions);

+  Status = gRT->GetVariable (

+                  (CHAR16 *) L"Configuration",

+                  &gEfiCallerIdGuid,

+                  &Attributes,

+                  &DataSize,

+                  &ConfigurationOptions

+                  );

+  if (EFI_ERROR (Status)) {

+    ConfigurationOptions = 0x0f;

+  }

+

+  if (EnumAll) {

+    //

+    // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway

+    //

+    BeginningIdeChannel = IdePrimary;

+    EndIdeChannel       = IdeSecondary;

+    BeginningIdeDevice  = IdeMaster;

+    EndIdeDevice        = IdeSlave;

+  } else if (RemainingDevicePath == NULL) {

+    //

+    // RemainingDevicePath is NULL, scan IDE bus for each device;

+    //

+    BeginningIdeChannel = IdePrimary;

+    EndIdeChannel       = IdeSecondary;

+    BeginningIdeDevice  = IdeMaster;

+    //

+    // default, may be redefined by IdeInit

+    //

+    EndIdeDevice = IdeSlave;

+  } else {

+    //

+    // RemainingDevicePath is not NULL, only scan the specified device.

+    //

+    Node                = (EFI_DEV_PATH *) RemainingDevicePath;

+    BeginningIdeChannel = Node->Atapi.PrimarySecondary;

+    EndIdeChannel       = BeginningIdeChannel;

+    BeginningIdeDevice  = Node->Atapi.SlaveMaster;

+    EndIdeDevice        = BeginningIdeDevice;

+  }

+

+  //

+  // Obtain IDE IO port registers' base addresses

+  //

+  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  //

+  // Report status code: begin IdeBus initialization

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),

+    ParentDevicePath

+    );

+

+  //

+  // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol

+  //

+  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {

+

+    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);

+

+    //

+    // now obtain channel information fron IdeControllerInit protocol. Step9

+    //

+    Status = IdeInit->GetChannelInfo (

+                        IdeInit,

+                        IdeChannel,

+                        &ChannelEnabled,

+                        &MaxDevices

+                        );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));

+      continue;

+    }

+

+    if (!ChannelEnabled) {

+      continue;

+    }

+

+    EndIdeDevice = (UINT8) EFI_MIN ((MaxDevices - 1), EndIdeDevice);

+

+    //

+    // Now inform the IDE Controller Init Module. Sept10

+    //

+    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);

+

+    //

+    // No reset channel function implemented. Sept11

+    //

+    IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);

+

+    //

+    // Step13

+    //

+    IdeInit->NotifyPhase (

+              IdeInit,

+              EfiIdeBusBeforeDevicePresenceDetection,

+              IdeChannel

+              );

+    //

+    // -- 1st inner loop --- Master/Slave ------------  Step14

+    //

+    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {

+      //

+      // Check whether the configuration options allow this device

+      //

+      if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {

+        continue;

+      }

+      

+      //

+      // The device has been scanned in another Start(), No need to scan it again

+      // for perf optimization.

+      //

+      if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {

+        continue;

+      }

+      

+      //

+      // create child handle for the detected device.

+      //

+      IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));

+      if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {

+        continue;

+      }

+

+      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];

+

+      ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));

+

+      IdeBlkIoDevicePtr->Signature  = IDE_BLK_IO_DEV_SIGNATURE;

+      IdeBlkIoDevicePtr->Channel    = IdeChannel;

+      IdeBlkIoDevicePtr->Device     = IdeDevice;

+

+      //

+      // initialize Block IO interface's Media pointer

+      //

+      IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;

+

+      //

+      // Initialize IDE IO port addresses, including Command Block registers

+      // and Control Block registers

+      //

+      IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));

+      if (IdeBlkIoDevicePtr->IoPort == NULL) {

+        continue;

+      }

+

+      ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));

+      CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;

+      ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;

+

+      IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;

+      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);

+      IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);

+      IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);

+      IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);

+      IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);

+      IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);

+      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);

+

+      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;

+      IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);

+

+      IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);

+

+      IdeBlkIoDevicePtr->PciIo = PciIo;

+      IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;

+      IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;

+

+      //

+      // Discover device, now!

+      //

+      PERF_START (0, "DiscoverIdeDevice", "IDE", 0);

+      Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);

+      PERF_END (0, "DiscoverIdeDevice", "IDE", 0);

+

+      IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;

+      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;

+

+      if (!EFI_ERROR (Status)) {

+        //

+        // Set Device Path

+        //

+        ZeroMem (&NewNode, sizeof (NewNode));

+        NewNode.DevPath.Type    = MESSAGING_DEVICE_PATH;

+        NewNode.DevPath.SubType = MSG_ATAPI_DP;

+        SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));

+

+        NewNode.Atapi.PrimarySecondary  = (UINT8) IdeBlkIoDevicePtr->Channel;

+        NewNode.Atapi.SlaveMaster       = (UINT8) IdeBlkIoDevicePtr->Device;

+        NewNode.Atapi.Lun               = IdeBlkIoDevicePtr->Lun;

+        IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (

+                                          ParentDevicePath,

+                                          &NewNode.DevPath

+                                          );

+        if (IdeBlkIoDevicePtr->DevicePath == NULL) {

+          ReleaseIdeResources (IdeBlkIoDevicePtr);

+          continue;

+        }

+

+        //

+        // Submit identify data to IDE controller init driver

+        //

+        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));

+        // IdentifyData  = *IdeBlkIoDevicePtr->pIdData;

+        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;

+        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);

+      } else {

+        //

+        // Device detection failed

+        //

+        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;

+        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);

+        ReleaseIdeResources (IdeBlkIoDevicePtr);

+        IdeBlkIoDevicePtr = NULL;

+      }

+      //

+      // end of 1st inner loop ---

+      //

+    }

+    //

+    // end of 1st outer loop =========

+    //

+  }

+

+  //

+  // = 2nd outer loop == Primary/Secondary =================

+  //

+  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {

+

+    //

+    // -- 2nd inner loop --- Master/Slave --------

+    //

+    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {

+

+      if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {

+        continue;

+      }

+

+      if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {

+        continue;

+      }

+

+      Status = IdeInit->CalculateMode (

+                          IdeInit,

+                          IdeChannel,

+                          IdeDevice,

+                          &SupportedModes

+                          );

+      if (EFI_ERROR (Status)) {

+        DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));

+        continue;

+      }

+

+      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];

+

+      //

+      // Set best supported PIO mode on this IDE device

+      //

+      if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {

+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;

+      } else {

+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;

+      }

+

+      TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);

+

+      if (SupportedModes->ExtModeCount == 0){

+        Status                  = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

+

+        if (EFI_ERROR (Status)) {

+          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;

+          ReleaseIdeResources (IdeBlkIoDevicePtr);

+          IdeBlkIoDevicePtr = NULL;

+          continue;

+        }

+      }

+

+      //

+      // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't

+      // be set together. Only one DMA mode can be set to a device. If setting

+      // DMA mode operation fails, we can continue moving on because we only use

+      // PIO mode at boot time. DMA modes are used by certain kind of OS booting

+      //

+      if (SupportedModes->UdmaMode.Valid) {

+

+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;

+        TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);

+        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

+

+        if (EFI_ERROR (Status)) {

+          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;

+          ReleaseIdeResources (IdeBlkIoDevicePtr);

+          IdeBlkIoDevicePtr = NULL;

+          continue;

+        }

+

+        EnableInterrupt (IdeBlkIoDevicePtr);

+      } else if (SupportedModes->MultiWordDmaMode.Valid) {

+

+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;

+        TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;

+        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

+

+        if (EFI_ERROR (Status)) {

+          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;

+          ReleaseIdeResources (IdeBlkIoDevicePtr);

+          IdeBlkIoDevicePtr = NULL;

+          continue;

+        }

+

+        EnableInterrupt (IdeBlkIoDevicePtr);

+      }

+      //

+      // Init driver parameters

+      //

+      DriveParameters.Sector          = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;

+      DriveParameters.Heads           = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);

+      DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;

+      //

+      // Set Parameters for the device:

+      // 1) Init

+      // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command

+      //

+      if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {

+        Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);

+      }

+      

+      //

+      // Record PIO mode used in private data

+      //

+      IdeBlkIoDevicePtr->PioMode = SupportedModes->PioMode.Mode;

+

+      //

+      // Set IDE controller Timing Blocks in the PCI Configuration Space

+      //

+      IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);

+

+      //

+      // Add Component Name for the IDE/ATAPI device that was discovered.

+      //

+      IdeBlkIoDevicePtr->ControllerNameTable = NULL;

+      ADD_NAME (IdeBlkIoDevicePtr);

+

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &IdeBlkIoDevicePtr->Handle,

+                      &gEfiDevicePathProtocolGuid,

+                      IdeBlkIoDevicePtr->DevicePath,

+                      &gEfiBlockIoProtocolGuid,

+                      &IdeBlkIoDevicePtr->BlkIo,

+                      &gEfiDiskInfoProtocolGuid,

+                      &IdeBlkIoDevicePtr->DiskInfo,

+                      NULL

+                      );

+

+      if (EFI_ERROR (Status)) {

+        ReleaseIdeResources (IdeBlkIoDevicePtr);

+      }

+

+      gBS->OpenProtocol (

+            Controller,

+            &gEfiPciIoProtocolGuid,

+            (VOID **) &PciIo,

+            This->DriverBindingHandle,

+            IdeBlkIoDevicePtr->Handle,

+            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+            );

+

+      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;

+

+      //

+      // Report status code: device eanbled!

+      //

+      REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+        EFI_PROGRESS_CODE,

+        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),

+        IdeBlkIoDevicePtr->DevicePath

+        );

+      //

+      // end of 2nd inner loop ----

+      //

+    }

+    //

+    // end of 2nd outer loop ==========

+    //

+  }

+  

+  //

+  // All configurations done! Notify IdeController to do post initialization

+  // work such as saving IDE controller PCI settings for S3 resume

+  //

+  IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);

+

+  if (SupportedModes != NULL) {

+    gBS->FreePool (SupportedModes);

+  }

+

+  PERF_START (0, "Finish IDE detection", "IDE", 1);

+  PERF_END (0, "Finish IDE detection", "IDE", 0);

+

+  return EFI_SUCCESS;

+

+ErrorExit:

+

+  //

+  // Report error code: controller error

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_ERROR_CODE | EFI_ERROR_MINOR,

+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),

+    ParentDevicePath

+    );

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiIdeControllerInitProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->UninstallMultipleProtocolInterfaces (

+        Controller,

+        &gEfiCallerIdGuid,

+        IdeBusDriverPrivateData,

+        NULL

+        );

+

+  if (IdeBusDriverPrivateData != NULL) {

+    gBS->FreePool (IdeBusDriverPrivateData);

+  }

+

+  if (SupportedModes != NULL) {

+    gBS->FreePool (SupportedModes);

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+

+}

+

+//

+// ***********************************************************************************

+// IDEBusDriverBindingStop

+// ***********************************************************************************

+//

+EFI_STATUS

+EFIAPI

+IDEBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+  

+  Routine Description:

+    Stop this driver on Controller Handle. 

+

+  Arguments:

+    This              - Protocol instance pointer.

+    DeviceHandle      - Handle of device to stop driver on 

+    NumberOfChildren  - Not used

+    ChildHandleBuffer - Not used

+

+  Returns:

+    EFI_SUCCESS       - This driver is removed DeviceHandle

+    other             - This driver was not removed from this device

+  

+--*/

+// TODO:    Controller - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  EFI_STATUS                  Status;

+  EFI_PCI_IO_PROTOCOL         *PciIo;

+  BOOLEAN                     AllChildrenStopped;

+  UINTN                       Index;

+  IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;

+

+  IdeBusDriverPrivateData = NULL;

+

+  if (NumberOfChildren == 0) {

+

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiPciIoProtocolGuid,

+                    (VOID **) &PciIo,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+      PciIo->Attributes (

+              PciIo,

+              EfiPciIoAttributeOperationDisable,

+              EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,

+              NULL

+              );

+    }

+

+    gBS->OpenProtocol (

+          Controller,

+          &gEfiCallerIdGuid,

+          (VOID **) &IdeBusDriverPrivateData,

+          This->DriverBindingHandle,

+          Controller,

+          EFI_OPEN_PROTOCOL_GET_PROTOCOL

+          );

+

+    gBS->UninstallMultipleProtocolInterfaces (

+          Controller,

+          &gEfiCallerIdGuid,

+          IdeBusDriverPrivateData,

+          NULL

+          );

+

+    if (IdeBusDriverPrivateData != NULL) {

+      gBS->FreePool (IdeBusDriverPrivateData);

+    }

+    //

+    // Close the bus driver

+    //

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiIdeControllerInitProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    return EFI_SUCCESS;

+  }

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+

+    Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// ***********************************************************************************

+// DeRegisterIdeDevice

+// ***********************************************************************************

+//

+EFI_STATUS

+DeRegisterIdeDevice (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  EFI_HANDLE                     Handle

+  )

+/*++

+

+Routine Description:

+

+  Deregister an IDE device and free resources

+  

+Arguments:

+

+  This            - Protocol instance pointer.

+  Controller      - Ide device handle

+  Handle          - Handle of device to deregister driver on 

+  

+Returns:

+

+  EFI_STATUS

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS            Status;

+  EFI_BLOCK_IO_PROTOCOL *BlkIo;

+  IDE_BLK_IO_DEV        *IdeBlkIoDevice;

+  EFI_PCI_IO_PROTOCOL   *PciIo;

+  UINTN                 Index;

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlkIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);

+

+  //

+  // Report Status code: Device disabled

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),

+    IdeBlkIoDevice->DevicePath

+    );

+

+  //

+  // Close the child handle

+  //

+  Status = gBS->CloseProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  This->DriverBindingHandle,

+                  Handle

+                  );

+

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  IdeBlkIoDevice->DevicePath,

+                  &gEfiBlockIoProtocolGuid,

+                  &IdeBlkIoDevice->BlkIo,

+                  &gEfiDiskInfoProtocolGuid,

+                  &IdeBlkIoDevice->DiskInfo,

+                  NULL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->OpenProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          (VOID **) &PciIo,

+          This->DriverBindingHandle,

+          Handle,

+          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+          );

+    return Status;

+  }

+  

+  //

+  // Release allocated resources

+  //

+  Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;

+  IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;

+

+  ReleaseIdeResources (IdeBlkIoDevice);

+

+  return EFI_SUCCESS;

+}

+

+//

+// ***********************************************************************************

+// IDEBlkIoReset

+// ***********************************************************************************

+//

+EFI_STATUS

+EFIAPI

+IDEBlkIoReset (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  BOOLEAN                 ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ExtendedVerification - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;

+  EFI_STATUS      Status;

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);

+  //

+  // Requery IDE IO resources in case of the switch of native and legacy modes

+  //

+  ReassignIdeResources (IdeBlkIoDevice);

+

+  //

+  // for ATA device, using ATA reset method

+  //

+  if (IdeBlkIoDevice->Type == IdeHardDisk) {

+    return AtaSoftReset (IdeBlkIoDevice);

+  }

+

+  if (IdeBlkIoDevice->Type == IdeUnknown) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // for ATAPI device, using ATAPI reset method

+  //

+  Status = AtapiSoftReset (IdeBlkIoDevice);

+  if (ExtendedVerification) {

+    Status = AtaSoftReset (IdeBlkIoDevice);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+IDEBlkIoReadBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Read data from block io device

+  

+Arguments:

+

+  This            - Protocol instance pointer.

+  MediaId         - The media ID of the device

+  LBA             - Starting LBA address to read data

+  BufferSize      - The size of data to be read

+  Buffer          - Caller supplied buffer to save data

+  

+Returns:

+

+  read data status

+

+--*/

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);

+

+  //

+  // Requery IDE IO resources in case of the switch of native and legacy modes

+  //

+  ReassignIdeResources (IdeBlkIoDevice);

+

+  //

+  // For ATA compatible device, use ATA read block's mechanism

+  //

+  if (IdeBlkIoDevice->Type == IdeHardDisk ||

+      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {

+    return AtaBlkIoReadBlocks (

+            IdeBlkIoDevice,

+            MediaId,

+            LBA,

+            BufferSize,

+            Buffer

+            );

+  }

+

+  if (IdeBlkIoDevice->Type == IdeUnknown) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // for ATAPI device, using ATAPI read block's mechanism

+  //

+  return AtapiBlkIoReadBlocks (

+          IdeBlkIoDevice,

+          MediaId,

+          LBA,

+          BufferSize,

+          Buffer

+          );

+

+}

+

+EFI_STATUS

+EFIAPI

+IDEBlkIoWriteBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  IN  VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Write data to block io device

+  

+Arguments:

+

+  This            - Protocol instance pointer.

+  MediaId         - The media ID of the device

+  LBA             - Starting LBA address to write data

+  BufferSize      - The size of data to be written

+  Buffer          - Caller supplied buffer to save data

+  

+Returns:

+

+  write data status

+

+--*/

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);

+  //

+  // Requery IDE IO resources in case of the switch of native and legacy modes

+  //

+  ReassignIdeResources (IdeBlkIoDevice);

+

+  //

+  // for ATA device, using ATA write block's mechanism

+  //

+  if (IdeBlkIoDevice->Type == IdeHardDisk ||

+      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {        

+

+    return AtaBlkIoWriteBlocks (

+            IdeBlkIoDevice,

+            MediaId,

+            LBA,

+            BufferSize,

+            Buffer

+            );

+  }

+

+  if (IdeBlkIoDevice->Type == IdeUnknown) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // for ATAPI device, using ATAPI write block's mechanism

+  //

+  return AtapiBlkIoWriteBlocks (

+          IdeBlkIoDevice,

+          MediaId,

+          LBA,

+          BufferSize,

+          Buffer

+          );

+}

+

+//

+// ***********************************************************************************

+// IDEBlkIoFlushBlocks

+// ***********************************************************************************

+//

+EFI_STATUS

+EFIAPI

+IDEBlkIoFlushBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  //

+  // return directly

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoInquiry (

+  IN     EFI_DISK_INFO_PROTOCOL   *This,

+  IN OUT VOID                     *InquiryData,

+  IN OUT UINT32                   *InquiryDataSize

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Inquiry command to a drive in InquiryData.

+    Data format of Inquiry data is defined by the Interface GUID.

+

+  Arguments:

+    This        - Protocol instance pointer.

+    InquiryData - Results of Inquiry command to device

+    InquiryDataSize - Size of InquiryData in bytes.

+

+  Returns:

+    EFI_SUCCESS       - InquiryData valid

+    EFI_NOT_FOUND     - Device does not support this data class

+    EFI_DEVICE_ERROR  - Error reading InquiryData from device 

+    EFI_BUFFER_TOO_SMALL - IntquiryDataSize not big enough

+

+--*/

+{

+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);

+

+  if (*InquiryDataSize < sizeof (INQUIRY_DATA)) {

+    *InquiryDataSize = sizeof (INQUIRY_DATA);

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  if (IdeBlkIoDevice->pInquiryData == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (INQUIRY_DATA));

+  *InquiryDataSize = sizeof (INQUIRY_DATA);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoIdentify (

+  IN     EFI_DISK_INFO_PROTOCOL   *This,

+  IN OUT VOID                     *IdentifyData,

+  IN OUT UINT32                   *IdentifyDataSize

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Identify command to a drive in IdentifyData.

+    Data format of Identify data is defined by the Interface GUID.

+

+  Arguments:

+    This        - Protocol instance pointer.

+    IdentifyData - Results of Identify command to device

+    IdentifyDataSize - Size of IdentifyData in bytes.

+

+  Returns:

+    EFI_SUCCESS       - IdentifyData valid

+    EFI_NOT_FOUND     - Device does not support this data class

+    EFI_DEVICE_ERROR  - Error reading IdentifyData from device 

+    EFI_BUFFER_TOO_SMALL - IdentifyDataSize not big enough

+

+--*/

+{

+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;

+

+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);

+

+  if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {

+    *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  if (IdeBlkIoDevice->pIdData == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));

+  *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoSenseData (

+  IN     EFI_DISK_INFO_PROTOCOL   *This,

+  IN OUT VOID                     *SenseData,

+  IN OUT UINT32                   *SenseDataSize,

+  OUT    UINT8                    *SenseDataNumber

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Request Sense command to a drive in SenseData.

+    Data format of Sense data is defined by the Interface GUID.

+

+  Arguments:

+    This            - Protocol instance pointer.

+    SenseData       - Results of Request Sense command to device

+    SenseDataSize   - Size of SenseData in bytes.

+    SenseDataNumber - Type of SenseData

+

+  Returns:

+    EFI_SUCCESS       - InquiryData valid

+    EFI_NOT_FOUND     - Device does not support this data class

+    EFI_DEVICE_ERROR  - Error reading InquiryData from device 

+    EFI_BUFFER_TOO_SMALL - SenseDataSize not big enough

+

+--*/

+{

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoWhichIde (

+  IN  EFI_DISK_INFO_PROTOCOL   *This,

+  OUT UINT32                   *IdeChannel,

+  OUT UINT32                   *IdeDevice

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Request Sense command to a drive in SenseData.

+    Data format of Sense data is defined by the Interface GUID.

+

+  Arguments:

+    This        - Protocol instance pointer.

+    IdeChannel  - Primary or Secondary

+    IdeDevice   - Master or Slave

+

+  Returns:

+    EFI_SUCCESS       - IdeChannel and IdeDevice are valid

+    EFI_UNSUPPORTED   - This is not an IDE device

+

+--*/

+{

+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;

+

+  IdeBlkIoDevice  = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);

+  *IdeChannel     = IdeBlkIoDevice->Channel;

+  *IdeDevice      = IdeBlkIoDevice->Device;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h
new file mode 100644
index 0000000..428dffa
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h
@@ -0,0 +1,439 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    idebus.h

+

+Abstract:

+

+    Header file for IDE Bus Driver.

+

+Revision History

+++*/

+

+// TODO: fix comment to end with --*/

+#ifndef _IDE_BUS_H

+#define _IDE_BUS_H

+

+

+#include <IndustryStandard/pci22.h>

+#include "idedata.h"

+

+//

+// Extra Definition to porting

+//

+#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))

+

+#define MAX_IDE_DEVICE    4

+#define MAX_IDE_CHANNELS  2

+#define MAX_IDE_DRIVES    2

+

+typedef struct {

+  BOOLEAN HaveScannedDevice[MAX_IDE_DEVICE];

+  BOOLEAN DeviceFound[MAX_IDE_DEVICE];

+  BOOLEAN DeviceProcessed[MAX_IDE_DEVICE];

+} IDE_BUS_DRIVER_PRIVATE_DATA;

+

+#define IDE_BLK_IO_DEV_SIGNATURE  EFI_SIGNATURE_32 ('i', 'b', 'i', 'd')

+

+typedef struct {

+  UINT32                      Signature;

+

+  EFI_HANDLE                  Handle;

+  EFI_BLOCK_IO_PROTOCOL       BlkIo;

+  EFI_BLOCK_IO_MEDIA          BlkMedia;

+  EFI_DISK_INFO_PROTOCOL      DiskInfo;

+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;

+  EFI_PCI_IO_PROTOCOL         *PciIo;

+  IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;

+

+  //

+  // Local Data for IDE interface goes here

+  //

+  EFI_IDE_CHANNEL             Channel;

+  EFI_IDE_DEVICE              Device;

+  UINT16                      Lun;

+  IDE_DEVICE_TYPE             Type;

+

+  IDE_BASE_REGISTERS          *IoPort;

+  UINT16                      AtapiError;

+

+  INQUIRY_DATA                *pInquiryData;

+  EFI_IDENTIFY_DATA           *pIdData;

+  ATA_PIO_MODE                PioMode;

+  ATA_UDMA_MODE               UDma_Mode;

+  CHAR8                       ModelName[41];

+  REQUEST_SENSE_DATA          *SenseData;

+  UINT8                       SenseDataNumber;

+  UINT8                       *Cache;

+

+  EFI_UNICODE_STRING_TABLE    *ControllerNameTable;

+} IDE_BLK_IO_DEV;

+

+#include "ComponentName.h"

+

+#define IDE_BLOCK_IO_DEV_FROM_THIS(a)           CR (a, IDE_BLK_IO_DEV, BlkIo, IDE_BLK_IO_DEV_SIGNATURE)

+#define IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS(a) CR (a, IDE_BLK_IO_DEV, DiskInfo, IDE_BLK_IO_DEV_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gIDEBusDriverBinding;

+

+#include "ide.h"

+

+//

+// Prototypes

+// Driver model protocol interface

+//

+EFI_STATUS

+EFIAPI

+IDEBusControllerDriverEntryPoint (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Controller          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Controller          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL *This,

+  IN  EFI_HANDLE                  Controller,

+  IN  UINTN                       NumberOfChildren,

+  IN  EFI_HANDLE                  *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Controller        - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Block I/O Protocol Interface

+//

+EFI_STATUS

+EFIAPI

+IDEBlkIoReset (

+  IN  EFI_BLOCK_IO_PROTOCOL       *This,

+  IN  BOOLEAN                     ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBlkIoReadBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL       *This,

+  IN  UINT32                      MediaId,

+  IN  EFI_LBA                     LBA,

+  IN  UINTN                       BufferSize,

+  OUT VOID                        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  LBA         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBlkIoWriteBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL       *This,

+  IN  UINT32                      MediaId,

+  IN  EFI_LBA                     LBA,

+  IN  UINTN                       BufferSize,

+  IN  VOID                        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  LBA         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEBlkIoFlushBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL       *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IDERegisterDecodeEnableorDisable (

+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,

+  IN  BOOLEAN                     Enable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIo   - TODO: add argument description

+  Enable  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoInquiry (

+  IN EFI_DISK_INFO_PROTOCOL       *This,

+  IN OUT VOID                     *InquiryData,

+  IN OUT UINT32                   *IntquiryDataSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  InquiryData       - TODO: add argument description

+  IntquiryDataSize  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoIdentify (

+  IN EFI_DISK_INFO_PROTOCOL       *This,

+  IN OUT VOID                     *IdentifyData,

+  IN OUT UINT32                   *IdentifyDataSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  IdentifyData      - TODO: add argument description

+  IdentifyDataSize  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoSenseData (

+  IN EFI_DISK_INFO_PROTOCOL       *This,

+  IN OUT VOID                     *SenseData,

+  IN OUT UINT32                   *SenseDataSize,

+  OUT UINT8                       *SenseDataNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This            - TODO: add argument description

+  SenseData       - TODO: add argument description

+  SenseDataSize   - TODO: add argument description

+  SenseDataNumber - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+IDEDiskInfoWhichIde (

+  IN EFI_DISK_INFO_PROTOCOL       *This,

+  OUT UINT32                      *IdeChannel,

+  OUT UINT32                      *IdeDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  IdeChannel  - TODO: add argument description

+  IdeDevice   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.mbd b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.mbd
new file mode 100644
index 0000000..f6e3ba1
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>IdeBus</BaseName>

+    <Guid>69FD8E47-A161-4550-B01A-5594CEB2B2B2</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-22 16:27</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+    <Library>BasePerformanceLibNull</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa
new file mode 100644
index 0000000..c5f38ea
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.msa
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>IdeBus</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>69FD8E47-A161-4550-B01A-5594CEB2B2B2</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for PS2 keyboard module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-22 16:27</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>idebus.h</Filename>

+    <Filename>ide.h</Filename>

+    <Filename>idedata.h</Filename>

+    <Filename>idebus.c</Filename>

+    <Filename>ide.c</Filename>

+    <Filename>ata.c</Filename>

+    <Filename>atapi.c</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>ComponentName.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">PciIo</Protocol>

+    <Protocol Usage="TO_START">IdeControllerInit</Protocol>

+    <Protocol Usage="BY_START">BlockIo</Protocol>

+    <Protocol Usage="BY_START">DiskInfo</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable Usage="ALWAYS_CONSUMED">

+      <String>Configuration</String>

+      <Guid>0x69fd8e47, 0xa161, 0x4550, 0xb0, 0x1a, 0x55, 0x94, 0xce, 0xb2, 0xb2, 0xb2</Guid>

+    </Variable>

+  </Variables>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>DiskInfoIde</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gIDEBusDriverBinding</DriverBinding>

+      <ComponentName>gIDEBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebusLite.mbd b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebusLite.mbd
new file mode 100644
index 0000000..fa4bc33
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebusLite.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>IdeBusLite</BaseName>

+    <Guid>69FD8E47-A161-4550-B01A-5594CEB2B2B2</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibNull</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiDevicePathLib</Library>

+    <Library>BasePerformanceLibNull</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebusLite.msa b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebusLite.msa
new file mode 100644
index 0000000..800c5c2
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebusLite.msa
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>IdeBusLite</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>69FD8E47-A161-4550-B01A-5594CEB2B2B2</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for PS2 keyboard module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>idebus.h</Filename>

+    <Filename>ide.h</Filename>

+    <Filename>idedata.h</Filename>

+    <Filename>idebus.c</Filename>

+    <Filename>ide.c</Filename>

+    <Filename>ata.c</Filename>

+    <Filename>atapi.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">IdeControllerInit</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">BlockIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">DiskInfo</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>DiskInfoIde</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>DiskInfoScsi</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>DiskInfoUsb</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gIDEBusDriverBinding</DriverBinding>

+      <ComponentName>gIDEBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h
new file mode 100644
index 0000000..50b1f05
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h
@@ -0,0 +1,879 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    idedata.h

+

+Abstract:

+

+    Header file for IDE Bus Driver's Data Structures

+

+Revision History

+++*/

+

+// TODO: fix comment to end with --*/

+#ifndef _IDE_DATA_H

+#define _IDE_DATA_H

+

+//

+// bit definition

+//

+#define bit0  (1 << 0)

+#define bit1  (1 << 1)

+#define bit2  (1 << 2)

+#define bit3  (1 << 3)

+#define bit4  (1 << 4)

+#define bit5  (1 << 5)

+#define bit6  (1 << 6)

+#define bit7  (1 << 7)

+#define bit8  (1 << 8)

+#define bit9  (1 << 9)

+#define bit10 (1 << 10)

+#define bit11 (1 << 11)

+#define bit12 (1 << 12)

+#define bit13 (1 << 13)

+#define bit14 (1 << 14)

+#define bit15 (1 << 15)

+#define bit16 (1 << 16)

+#define bit17 (1 << 17)

+#define bit18 (1 << 18)

+#define bit19 (1 << 19)

+#define bit20 (1 << 20)

+#define bit21 (1 << 21)

+#define bit22 (1 << 22)

+#define bit23 (1 << 23)

+#define bit24 (1 << 24)

+#define bit25 (1 << 25)

+#define bit26 (1 << 26)

+#define bit27 (1 << 27)

+#define bit28 (1 << 28)

+#define bit29 (1 << 29)

+#define bit30 (1 << 30)

+#define bit31 (1 << 31)

+

+//

+// common constants

+//

+#define STALL_1_MILLI_SECOND  1000    // stall 1 ms

+#define STALL_1_SECOND        1000000 // stall 1 second

+typedef enum {

+  IdePrimary    = 0,

+  IdeSecondary  = 1,

+  IdeMaxChannel = 2

+} EFI_IDE_CHANNEL;

+

+typedef enum {

+  IdeMaster     = 0,

+  IdeSlave      = 1,

+  IdeMaxDevice  = 2

+} EFI_IDE_DEVICE;

+

+typedef enum {

+  IdeMagnetic,                        /* ZIP Drive or LS120 Floppy Drive */

+  IdeCdRom,                           /* ATAPI CDROM */

+  IdeHardDisk,                        /* Hard Disk */

+  Ide48bitAddressingHardDisk,         /* Hard Disk larger than 120GB */

+  IdeUnknown

+} IDE_DEVICE_TYPE;

+

+//

+// IDE Registers

+//

+typedef union {

+  UINT16  Command;        /* when write */

+  UINT16  Status;         /* when read */

+} IDE_CMD_OR_STATUS;

+

+typedef union {

+  UINT16  Error;          /* when read */

+  UINT16  Feature;        /* when write */

+} IDE_ERROR_OR_FEATURE;

+

+typedef union {

+  UINT16  AltStatus;      /* when read */

+  UINT16  DeviceControl;  /* when write */

+} IDE_AltStatus_OR_DeviceControl;

+

+//

+// IDE registers set

+//

+typedef struct {

+  UINT16                          Data;

+  IDE_ERROR_OR_FEATURE            Reg1;

+  UINT16                          SectorCount;

+  UINT16                          SectorNumber;

+  UINT16                          CylinderLsb;

+  UINT16                          CylinderMsb;

+  UINT16                          Head;

+  IDE_CMD_OR_STATUS               Reg;

+

+  IDE_AltStatus_OR_DeviceControl  Alt;

+  UINT16                          DriveAddress;

+

+  UINT16                          MasterSlave;

+  UINT16                          BusMasterBaseAddr;

+} IDE_BASE_REGISTERS;

+

+//

+// IDE registers' base addresses

+//

+typedef struct {

+  UINT16  CommandBlockBaseAddr;

+  UINT16  ControlBlockBaseAddr;

+  UINT16  BusMasterBaseAddr;

+} IDE_REGISTERS_BASE_ADDR;

+

+//

+// Bit definitions in Programming Interface byte of the Class Code field

+// in PCI IDE controller's Configuration Space

+//

+#define IDE_PRIMARY_OPERATING_MODE            bit0

+#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR    bit1

+#define IDE_SECONDARY_OPERATING_MODE          bit2

+#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR  bit3

+

+//

+// IDE registers bit definitions

+//

+

+//

+// Err Reg

+//

+#define BBK_ERR   bit7  /* Bad block detected */

+#define UNC_ERR   bit6  /* Uncorrectable Data */

+#define MC_ERR    bit5  /* Media Change */

+#define IDNF_ERR  bit4  /* ID Not Found */

+#define MCR_ERR   bit3  /* Media Change Requested */

+#define ABRT_ERR  bit2  /* Aborted Command */

+#define TK0NF_ERR bit1  /* Track 0 Not Found */

+#define AMNF_ERR  bit0  /* Address Mark Not Found */

+

+//

+// Device/Head Reg

+//

+#define LBA_MODE  bit6

+#define DEV       bit4

+#define HS3       bit3

+#define HS2       bit2

+#define HS1       bit1

+#define HS0       bit0

+#define CHS_MODE  (0)

+#define DRV0      (0)

+#define DRV1      (1)

+#define MST_DRV   DRV0

+#define SLV_DRV   DRV1

+

+//

+// Status Reg

+//

+#define BSY   bit7  /* Controller Busy */

+#define DRDY  bit6  /* Drive Ready */

+#define DWF   bit5  /* Drive Write Fault */

+#define DSC   bit4  /* Disk Seek Complete */

+#define DRQ   bit3  /* Data Request */

+#define CORR  bit2  /* Corrected Data */

+#define IDX   bit1  /* Index */

+#define ERR   bit0  /* Error */

+

+//

+// Device Control Reg

+//

+#define SRST  bit2  /* Software Reset */

+#define IEN_L bit1  /* Interrupt Enable #*/

+

+//

+// Bus Master Reg

+//

+#define BMIC_nREAD      bit3

+#define BMIC_START      bit0

+#define BMIS_INTERRUPT  bit2

+#define BMIS_ERROR      bit1

+

+#define BMICP_OFFSET    0x00

+#define BMISP_OFFSET    0x02

+#define BMIDP_OFFSET    0x04

+#define BMICS_OFFSET    0x08

+#define BMISS_OFFSET    0x0A

+#define BMIDS_OFFSET    0x0C

+

+//

+// Time Out Value For IDE Device Polling

+//

+

+//

+// ATATIMEOUT is used for waiting time out for ATA device

+//

+

+//

+// 1 second

+//

+#define ATATIMEOUT  1000  

+

+//

+// ATAPITIMEOUT is used for waiting operation

+// except read and write time out for ATAPI device

+//

+

+//

+// 1 second

+//

+#define ATAPITIMEOUT  1000 

+

+//

+// ATAPILONGTIMEOUT is used for waiting read and

+// write operation timeout for ATAPI device

+//

+

+//

+// 2 seconds

+//

+#define CDROMLONGTIMEOUT  2000  

+

+//

+// 5 seconds

+//

+#define ATAPILONGTIMEOUT  5000  

+

+//

+// ATA Commands Code

+//

+#define ATA_INITIALIZE_DEVICE 0x91

+

+//

+// Class 1

+//

+#define IDENTIFY_DRIVE_CMD          0xec

+#define READ_BUFFER_CMD             0xe4

+#define READ_SECTORS_CMD            0x20

+#define READ_SECTORS_WITH_RETRY_CMD 0x21

+#define READ_LONG_CMD               0x22

+#define READ_LONG_WITH_RETRY_CMD    0x23

+//

+// Class 1 - Atapi6 enhanced commands

+//

+#define READ_SECTORS_EXT_CMD  0x24

+

+//

+// Class 2

+//

+#define FORMAT_TRACK_CMD              0x50

+#define WRITE_BUFFER_CMD              0xe8

+#define WRITE_SECTORS_CMD             0x30

+#define WRITE_SECTORS_WITH_RETRY_CMD  0x31

+#define WRITE_LONG_CMD                0x32

+#define WRITE_LONG_WITH_RETRY_CMD     0x33

+#define WRITE_VERIFY_CMD              0x3c

+//

+// Class 2 - Atapi6 enhanced commands

+//

+#define WRITE_SECTORS_EXT_CMD 0x34

+

+//

+// Class 3

+//

+#define ACK_MEDIA_CHANGE_CMD        0xdb

+#define BOOT_POST_BOOT_CMD          0xdc

+#define BOOT_PRE_BOOT_CMD           0xdd

+#define CHECK_POWER_MODE_CMD        0x98

+#define CHECK_POWER_MODE_CMD_ALIAS  0xe5

+#define DOOR_LOCK_CMD               0xde

+#define DOOR_UNLOCK_CMD             0xdf

+#define EXEC_DRIVE_DIAG_CMD         0x90

+#define IDLE_CMD_ALIAS              0x97

+#define IDLE_CMD                    0xe3

+#define IDLE_IMMEDIATE_CMD          0x95

+#define IDLE_IMMEDIATE_CMD_ALIAS    0xe1

+#define INIT_DRIVE_PARAM_CMD        0x91

+#define RECALIBRATE_CMD             0x10  /* aliased to 1x */

+#define READ_DRIVE_STATE_CMD        0xe9

+#define SET_MULTIPLE_MODE_CMD       0xC6

+#define READ_DRIVE_STATE_CMD        0xe9

+#define READ_VERIFY_CMD             0x40

+#define READ_VERIFY_WITH_RETRY_CMD  0x41

+#define SEEK_CMD                    0x70  /* aliased to 7x */

+#define SET_FEATURES_CMD            0xef

+#define STANDBY_CMD                 0x96

+#define STANDBY_CMD_ALIAS           0xe2

+#define STANDBY_IMMEDIATE_CMD       0x94

+#define STANDBY_IMMEDIATE_CMD_ALIAS 0xe0

+

+//

+// Class 4

+//

+#define READ_DMA_CMD              0xc8

+#define READ_DMA_WITH_RETRY_CMD   0xc9

+#define READ_DMA_EXT_CMD          0x25

+#define WRITE_DMA_CMD             0xca

+#define WRITE_DMA_WITH_RETRY_CMD  0xcb

+#define WRITE_DMA_EXT_CMD         0x35

+

+//

+// Class 5

+//

+#define READ_MULTIPLE_CMD         0xc4

+#define REST_CMD                  0xe7

+#define RESTORE_DRIVE_STATE_CMD   0xea

+#define SET_SLEEP_MODE_CMD        0x99

+#define SET_SLEEP_MODE_CMD_ALIAS  0xe6

+#define WRITE_MULTIPLE_CMD        0xc5

+#define WRITE_SAME_CMD            0xe9

+

+//

+// Class 6 - Host protected area access feature set

+//

+#define READ_NATIVE_MAX_ADDRESS_CMD 0xf8

+#define SET_MAX_ADDRESS_CMD         0xf9

+

+//

+// Class 6 - ATA/ATAPI-6 enhanced commands

+//

+#define READ_NATIVE_MAX_ADDRESS_EXT_CMD 0x27

+#define SET_MAX_ADDRESS_CMD_EXT         0x37

+

+//

+// Class 6 - SET_MAX related sub command (in feature register)

+//

+#define PARTIES_SET_MAX_ADDRESS_SUB_CMD 0x00

+#define PARTIES_SET_PASSWORD_SUB_CMD    0x01

+#define PARTIES_LOCK_SUB_CMD            0x02

+#define PARTIES_UNLOCK_SUB_CMD          0x03

+#define PARTIES_FREEZE_SUB_CMD          0x04

+

+//

+// S.M.A.R.T

+//

+#define ATA_SMART_CMD               0xb0

+#define ATA_CONSTANT_C2             0xc2

+#define ATA_CONSTANT_4F             0x4f

+#define ATA_SMART_ENABLE_OPERATION  0xd8

+#define ATA_SMART_RETURN_STATUS     0xda

+

+//

+// Error codes for Exec Drive Diag

+//

+#define DRIV_DIAG_NO_ERROR          (0x01)

+#define DRIV_DIAG_FORMATTER_ERROR   (0x02)

+#define DRIV_DIAG_DATA_BUFFER_ERROR (0x03)

+#define DRIV_DIAG_ECC_CKT_ERRROR    (0x04)

+#define DRIV_DIAG_UP_ERROR          (0x05)

+#define DRIV_DIAG_SLAVE_DRV_ERROR   (0x80)  /* aliased to 0x8x */

+

+//

+// Codes for Format Track

+//

+#define FORMAT_GOOD_SECTOR            (0x00)

+#define FORMAT_SUSPEND_ALLOC          (0x01)

+#define FORMAT_REALLOC_SECTOR         (0x02)

+#define FORMAT_MARK_SECTOR_DEFECTIVE  (0x03)

+

+//

+// IDE_IDENTIFY bits

+// config bits :

+//

+#define ID_CONFIG_RESERVED0                             bit0

+#define ID_CONFIG_HARD_SECTORED_DRIVE                   bit1

+#define ID_CONFIG_SOFT_SECTORED_DRIVE                   bit2

+#define ID_CONFIG_NON_MFM                               bit3

+#define ID_CONFIG_15uS_HEAD_SWITCHING                   bit4

+#define ID_CONFIG_SPINDLE_MOTOR_CONTROL                 bit5

+#define ID_CONFIG_HARD_DRIVE                            bit6

+#define ID_CONFIG_CHANGEABLE_MEDIUM                     bit7

+#define ID_CONFIG_DATA_RATE_TO_5MHZ                     bit8

+#define ID_CONFIG_DATA_RATE_5_TO_10MHZ                  bit9

+#define ID_CONFIG_DATA_RATE_ABOVE_10MHZ                 bit10

+#define ID_CONFIG_MOTOR_SPEED_TOLERANCE_ABOVE_0_5_PERC  bit11

+#define ID_CONFIG_DATA_CLK_OFFSET_AVAIL                 bit12

+#define ID_CONFIG_TRACK_OFFSET_AVAIL                    bit13

+#define ID_CONFIG_SPEED_TOLERANCE_GAP_NECESSARY         bit14

+#define ID_CONFIG_RESERVED1                             bit15

+

+#define ID_DOUBLE_WORD_IO_POSSIBLE                      bit01

+#define ID_LBA_SUPPORTED                                bit9

+#define ID_DMA_SUPPORTED                                bit8

+

+#define SET_FEATURE_ENABLE_8BIT_TRANSFER                (0x01)

+#define SET_FEATURE_ENABLE_WRITE_CACHE                  (0x02)

+#define SET_FEATURE_TRANSFER_MODE                       (0x03)

+#define SET_FEATURE_WRITE_SAME_WRITE_SPECIFIC_AREA      (0x22)

+#define SET_FEATURE_DISABLE_RETRIES                     (0x33)

+//

+// for Read & Write Longs

+//

+#define SET_FEATURE_VENDOR_SPEC_ECC_LENGTH                          (0x44)

+#define SET_FEATURE_PLACE_NO_OF_CACHE_SEGMENTS_IN_SECTOR_NO_REG     (0x54)

+#define SET_FEATURE_DISABLE_READ_AHEAD                              (0x55)

+#define SET_FEATURE_MAINTAIN_PARAM_AFTER_RESET                      (0x66)

+#define SET_FEATURE_DISABLE_ECC                                     (0x77)

+#define SET_FEATURE_DISABLE_8BIT_TRANSFER                           (0x81)

+#define SET_FEATURE_DISABLE_WRITE_CACHE                             (0x82)

+#define SET_FEATURE_ENABLE_ECC                                      (0x88)

+#define SET_FEATURE_ENABLE_RETRIES                                  (0x99)

+#define SET_FEATURE_ENABLE_READ_AHEAD                               (0xaa)

+#define SET_FEATURE_SET_SECTOR_CNT_REG_AS_NO_OF_READ_AHEAD_SECTORS  (0xab)

+#define SET_FEATURE_ALLOW_REST_MODE                                 (0xac)

+//

+// for Read & Write Longs

+//

+#define SET_FEATURE_4BYTE_ECC                           (0xbb)

+#define SET_FEATURE_DEFALUT_FEATURES_ON_SOFTWARE_RESET  (0xcc)

+#define SET_FEATURE_WRITE_SAME_TO_WRITE_ENTIRE_MEDIUM   (0xdd)

+

+#define BLOCK_TRANSFER_MODE                             (0x00)

+#define SINGLE_WORD_DMA_TRANSFER_MODE                   (0x10)

+#define MULTI_WORD_DMA_TRANSFER_MODE                    (0x20)

+#define TRANSFER_MODE_MASK                              (0x07)  // 3 LSBs

+

+//

+// Drive 0 - Head 0

+//

+#define DEFAULT_DRIVE (0x00)

+#define DEFAULT_CMD   (0xa0)

+//

+// default content of device control register, disable INT

+//

+#define DEFAULT_CTL                 (0x0a)

+#define DEFAULT_IDE_BM_IO_BASE_ADR  (0xffa0)

+

+//

+// ATAPI6 related data structure definition

+//

+

+//

+// The maximum sectors count in 28 bit addressing mode

+//

+#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff

+

+//

+// Move the IDENTIFY section to DXE\Protocol\IdeControllerInit

+//

+

+//

+// ATAPI Command

+//

+#define ATAPI_SOFT_RESET_CMD      0x08

+#define ATAPI_PACKET_CMD          0xA0

+#define PACKET_CMD                0xA0

+#define ATAPI_IDENTIFY_DEVICE_CMD 0xA1

+#define ATAPI_SERVICE_CMD         0xA2

+

+//

+// ATAPI Packet Command

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1;

+  UINT8 reserved_2;

+  UINT8 reserved_3;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 reserved_8;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} TEST_UNIT_READY_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 4;

+  UINT8 lun : 4;

+  UINT8 page_code;

+  UINT8 reserved_3;

+  UINT8 allocation_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 reserved_8;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} INQUIRY_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 4;

+  UINT8 lun : 4;

+  UINT8 reserved_2;

+  UINT8 reserved_3;

+  UINT8 allocation_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 reserved_8;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} REQUEST_SENSE_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 4;

+  UINT8 lun : 4;

+  UINT8 page_code : 4;

+  UINT8 page_control : 4;

+  UINT8 reserved_3;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 parameter_list_length_hi;

+  UINT8 parameter_list_length_lo;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} MODE_SENSE_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 5;

+  UINT8 lun : 3;

+  UINT8 Lba0;

+  UINT8 Lba1;

+  UINT8 Lba2;

+  UINT8 Lba3;

+  UINT8 reserved_6;

+  UINT8 TranLen0;

+  UINT8 TranLen1;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} READ10_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1;

+  UINT8 reserved_2;

+  UINT8 reserved_3;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 allocation_length_hi;

+  UINT8 allocation_length_lo;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} READ_FORMAT_CAP_CMD;

+

+typedef union {

+  UINT16              Data16[6];

+  TEST_UNIT_READY_CMD TestUnitReady;

+  READ10_CMD          Read10;

+  REQUEST_SENSE_CMD   RequestSence;

+  INQUIRY_CMD         Inquiry;

+  MODE_SENSE_CMD      ModeSense;

+  READ_FORMAT_CAP_CMD ReadFormatCapacity;

+} ATAPI_PACKET_COMMAND;

+

+typedef struct {

+  UINT32  RegionBaseAddr;

+  UINT16  ByteCount;

+  UINT16  EndOfTable;

+} IDE_DMA_PRD;

+

+#define MAX_DMA_EXT_COMMAND_SECTORS 0x10000

+#define MAX_DMA_COMMAND_SECTORS     0x100

+

+#pragma pack()

+

+//

+// Packet Command Code

+//

+#define TEST_UNIT_READY             0x00

+#define REZERO                      0x01

+#define REQUEST_SENSE               0x03

+#define FORMAT_UNIT                 0x04

+#define REASSIGN_BLOCKS             0x07

+#define INQUIRY                     0x12

+#define START_STOP_UNIT             0x1B

+#define PREVENT_ALLOW_MEDIA_REMOVAL 0x1E

+#define READ_FORMAT_CAPACITY        0x23

+#define OLD_FORMAT_UNIT             0x24

+#define READ_CAPACITY               0x25

+#define READ_10                     0x28

+#define WRITE_10                    0x2A

+#define SEEK                        0x2B

+#define SEND_DIAGNOSTICS            0x3D

+#define WRITE_VERIFY                0x2E

+#define VERIFY                      0x2F

+#define READ_DEFECT_DATA            0x37

+#define WRITE_BUFFER                0x38

+#define READ_BUFFER                 0x3C

+#define READ_LONG                   0x3E

+#define WRITE_LONG                  0x3F

+#define MODE_SELECT                 0x55

+#define MODE_SENSE                  0x5A

+#define READ_12                     0xA8

+#define WRITE_12                    0xAA

+#define MAX_ATAPI_BYTE_COUNT        (0xfffe)

+

+//

+// Sense Key

+//

+#define REQUEST_SENSE_ERROR (0x70)

+#define SK_NO_SENSE         (0x0)

+#define SK_RECOVERY_ERROR   (0x1)

+#define SK_NOT_READY        (0x2)

+#define SK_MEDIUM_ERROR     (0x3)

+#define SK_HARDWARE_ERROR   (0x4)

+#define SK_ILLEGAL_REQUEST  (0x5)

+#define SK_UNIT_ATTENTION   (0x6)

+#define SK_DATA_PROTECT     (0x7)

+#define SK_BLANK_CHECK      (0x8)

+#define SK_VENDOR_SPECIFIC  (0x9)

+#define SK_RESERVED_A       (0xA)

+#define SK_ABORT            (0xB)

+#define SK_RESERVED_C       (0xC)

+#define SK_OVERFLOW         (0xD)

+#define SK_MISCOMPARE       (0xE)

+#define SK_RESERVED_F       (0xF)

+

+//

+// Additional Sense Codes

+//

+#define ASC_NOT_READY                   (0x04)

+#define ASC_MEDIA_ERR1                  (0x10)

+#define ASC_MEDIA_ERR2                  (0x11)

+#define ASC_MEDIA_ERR3                  (0x14)

+#define ASC_MEDIA_ERR4                  (0x30)

+#define ASC_MEDIA_UPSIDE_DOWN           (0x06)

+#define ASC_INVALID_CMD                 (0x20)

+#define ASC_LBA_OUT_OF_RANGE            (0x21)

+#define ASC_INVALID_FIELD               (0x24)

+#define ASC_WRITE_PROTECTED             (0x27)

+#define ASC_MEDIA_CHANGE                (0x28)

+#define ASC_RESET                       (0x29)  /* Power On Reset or Bus Reset occurred */

+#define ASC_ILLEGAL_FIELD               (0x26)

+#define ASC_NO_MEDIA                    (0x3A)

+#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK (0x64)

+

+//

+// Additional Sense Code Qualifier

+//

+#define ASCQ_IN_PROGRESS  (0x01)

+

+#define SETFEATURE        TRUE

+#define CLEARFEATURE      FALSE

+

+//

+//  ATAPI Data structure

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8 peripheral_type;

+  UINT8 RMB;

+  UINT8 version;

+  UINT8 response_data_format;

+  UINT8 addnl_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 vendor_info[8];

+  UINT8 product_id[12];

+  UINT8 eeprom_product_code[4];

+  UINT8 firmware_rev_level[4];

+  UINT8 firmware_sub_rev_level[1];

+  UINT8 reserved_37;

+  UINT8 reserved_38;

+  UINT8 reserved_39;

+  UINT8 max_capacity_hi;

+  UINT8 max_capacity_mid;

+  UINT8 max_capacity_lo;

+  UINT8 reserved_43_95[95 - 43 + 1];

+} INQUIRY_DATA;

+

+typedef struct {

+  UINT8 peripheral_type;

+  UINT8 RMB;

+  UINT8 version;

+  UINT8 response_data_format;

+  UINT8 addnl_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 vendor_info[8];

+  UINT8 product_id[16];

+  UINT8 product_revision_level[4];

+  UINT8 vendor_specific[20];

+  UINT8 reserved_56_95[40];

+} CDROM_INQUIRY_DATA;

+

+typedef struct {

+  UINT8 error_code : 7;

+  UINT8 valid : 1;

+  UINT8 reserved_1;

+  UINT8 sense_key : 4;

+  UINT8 reserved_21 : 1;

+  UINT8 ILI : 1;

+  UINT8 reserved_22 : 2;

+  UINT8 vendor_specific_3;

+  UINT8 vendor_specific_4;

+  UINT8 vendor_specific_5;

+  UINT8 vendor_specific_6;

+  UINT8 addnl_sense_length;           // n - 7

+  UINT8 vendor_specific_8;

+  UINT8 vendor_specific_9;

+  UINT8 vendor_specific_10;

+  UINT8 vendor_specific_11;

+  UINT8 addnl_sense_code;             // mandatory

+  UINT8 addnl_sense_code_qualifier;   // mandatory

+  UINT8 field_replaceable_unit_code;  // optional

+  UINT8 reserved_15;

+  UINT8 reserved_16;

+  UINT8 reserved_17;

+  //

+  // Followed by additional sense bytes     : FIXME

+  //

+} REQUEST_SENSE_DATA;

+

+typedef struct {

+  UINT8 LastLba3;

+  UINT8 LastLba2;

+  UINT8 LastLba1;

+  UINT8 LastLba0;

+  UINT8 BlockSize3;

+  UINT8 BlockSize2;

+  UINT8 BlockSize1;

+  UINT8 BlockSize0;

+} READ_CAPACITY_DATA;

+

+typedef struct {

+  UINT8 reserved_0;

+  UINT8 reserved_1;

+  UINT8 reserved_2;

+  UINT8 Capacity_Length;

+  UINT8 LastLba3;

+  UINT8 LastLba2;

+  UINT8 LastLba1;

+  UINT8 LastLba0;

+  UINT8 DesCode : 2;

+  UINT8 reserved_9 : 6;

+  UINT8 BlockSize2;

+  UINT8 BlockSize1;

+  UINT8 BlockSize0;

+} READ_FORMAT_CAPACITY_DATA;

+

+#pragma pack()

+

+//

+// PIO mode definition

+//

+typedef enum {

+  ATA_PIO_MODE_BELOW_2,

+  ATA_PIO_MODE_2,

+  ATA_PIO_MODE_3,

+  ATA_PIO_MODE_4

+} ATA_PIO_MODE;

+

+//

+// Multi word DMA definition

+//

+typedef enum {

+  ATA_MDMA_MODE_0,

+  ATA_MDMA_MODE_1,

+  ATA_MDMA_MODE_2

+} ATA_MDMA_MODE;

+

+//

+// UDMA mode definition

+//

+typedef enum {

+  ATA_UDMA_MODE_0,

+  ATA_UDMA_MODE_1,

+  ATA_UDMA_MODE_2,

+  ATA_UDMA_MODE_3,

+  ATA_UDMA_MODE_4,

+  ATA_UDMA_MODE_5

+} ATA_UDMA_MODE;

+

+#define ATA_MODE_CATEGORY_DEFAULT_PIO 0x00

+#define ATA_MODE_CATEGORY_FLOW_PIO    0x01

+#define ATA_MODE_CATEGORY_MDMA        0x04

+#define ATA_MODE_CATEGORY_UDMA        0x08

+

+#pragma pack(1)

+

+typedef struct {

+  UINT8 ModeNumber : 3;

+  UINT8 ModeCategory : 5;

+} ATA_TRANSFER_MODE;

+

+typedef struct {

+  UINT8 Sector;

+  UINT8 Heads;

+  UINT8 MultipleSector;

+} ATA_DRIVE_PARMS;

+

+#pragma pack()

+//

+// IORDY Sample Point field value

+//

+#define ISP_5_CLK 0

+#define ISP_4_CLK 1

+#define ISP_3_CLK 2

+#define ISP_2_CLK 3

+

+//

+// Recovery Time field value

+//

+#define RECVY_4_CLK 0

+#define RECVY_3_CLK 1

+#define RECVY_2_CLK 2

+#define RECVY_1_CLK 3

+

+//

+// Slave IDE Timing Register Enable

+//

+#define SITRE bit14

+

+//

+// DMA Timing Enable Only Select 1

+//

+#define DTE1  bit7

+

+//

+// Pre-fetch and Posting Enable Select 1

+//

+#define PPE1  bit6

+

+//

+// IORDY Sample Point Enable Select 1

+//

+#define IE1 bit5

+

+//

+// Fast Timing Bank Drive Select 1

+//

+#define TIME1 bit4

+

+//

+// DMA Timing Enable Only Select 0

+//

+#define DTE0  bit3

+

+//

+// Pre-fetch and Posting Enable Select 0

+//

+#define PPE0  bit2

+

+//

+// IOREY Sample Point Enable Select 0

+//

+#define IE0 bit1

+

+//

+// Fast Timing Bank Drive Select 0

+//

+#define TIME0 bit0

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c
new file mode 100644
index 0000000..b10ee93
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.c
@@ -0,0 +1,133 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "pcibus.h"

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gPciBusComponentName = {

+  PciBusComponentNameGetDriverName,

+  PciBusComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"PCI Bus Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+PciBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gPciBusComponentName.SupportedLanguages,

+          mPciBusDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+PciBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h
new file mode 100644
index 0000000..87d44c8
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/ComponentName.h
@@ -0,0 +1,91 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.h

+  

+Abstract:

+

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H

+#define _EFI_PCI_BUS_COMPONENT_NAME_H

+

+#ifndef EFI_SIZE_REDUCTION_APPLIED

+

+extern EFI_COMPONENT_NAME_PROTOCOL  gPciBusComponentName;

+

+#endif

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+PciBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Language    - TODO: add argument description

+  DriverName  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  ControllerHandle  - TODO: add argument description

+  ChildHandle       - TODO: add argument description

+  Language          - TODO: add argument description

+  ControllerName    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.mbd b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.mbd
new file mode 100644
index 0000000..eea4971
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>LightPciBusPciBus</BaseName>

+    <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiDevicePathLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.msa b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.msa
new file mode 100644
index 0000000..9482f11
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciBus.msa
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>LightPciBusPciBus</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for LightPciBus module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciBus.h</Filename>

+    <Filename>PciIo.h</Filename>

+    <Filename>PciCommand.h</Filename>

+    <Filename>PciDeviceSupport.h</Filename>

+    <Filename>PciResourceSupport.h</Filename>

+    <Filename>PciEnumerator.h</Filename>

+    <Filename>PciEnumeratorSupport.h</Filename>

+    <Filename>PciOptionRomSupport.h</Filename>

+    <Filename>PciRomTable.h</Filename>

+    <Filename>PciLib.h</Filename>

+    <Filename>PciRomTable.c</Filename>

+    <Filename>PciDriverOverride.h</Filename>

+    <Filename>PciPowerManagement.h</Filename>

+    <Filename>PciPowerManagement.c</Filename>

+    <Filename>PciDriverOverride.c</Filename>

+    <Filename>PciOptionRomSupport.c</Filename>

+    <Filename>PciEnumerator.c</Filename>

+    <Filename>PciEnumeratorSupport.c</Filename>

+    <Filename>PciResourceSupport.c</Filename>

+    <Filename>PciCommand.c</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>PciDeviceSupport.c</Filename>

+    <Filename>PciHotPlugSupport.c</Filename>

+    <Filename>pcibus.c</Filename>

+    <Filename>PciIo.c</Filename>

+    <Filename>LightPciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciRootBridgeIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">UgaIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciPlatform</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">BusSpecificDriverOverride</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugRequest</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">IncompatiblePciDeviceSupport</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugInit</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciHostBridgeResourceAllocation</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PciOptionRomTable</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PciHotplugDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeSpecificData</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPciBusDriverBinding</DriverBinding>

+      <ComponentName>gPciBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciLib.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciLib.c
new file mode 100644
index 0000000..28c8a79
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/LightPciLib.c
@@ -0,0 +1,881 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  LightPciLib.c

+  

+Abstract:

+

+  Light PCI Bus Driver Lib file

+  It abstracts some functions that can be different 

+  between light PCI bus driver and full PCI bus driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+

+//

+// Light PCI bus driver woundn't support hotplug device

+// So just return

+//

+VOID

+InstallHotPlugRequestProtocol (

+  IN EFI_STATUS *Status

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Status - add argument and description to function comment

+{

+  return ;

+}

+

+//

+// Light PCI bus driver woundn't support hotplug device

+// So just skip install this GUID

+//

+VOID

+InstallPciHotplugGuid (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+{

+  return ;

+}

+

+//

+// Light PCI bus driver woundn't support hotplug device

+// So just skip uninstall the GUID

+//

+VOID

+UninstallPciHotplugGuid (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+{

+  return ;

+}

+

+//

+// Light PCI bus driver woundn't support PCCard

+// So it needn't get the bar of CardBus

+//

+VOID

+GetBackPcCardBar (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  return ;

+}

+

+//

+// Light PCI bus driver woundn't support resource reallocation

+// So just return

+//

+EFI_STATUS

+RemoveRejectedPciDevices (

+  EFI_HANDLE        RootBridgeHandle,

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+  Bridge            - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+//

+// Light PCI bus driver woundn't support resource reallocation

+// Simplified the code

+//

+EFI_STATUS

+PciHostBridgeResourceAllocator (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE                   *RootBridgeDev;

+  EFI_HANDLE                      RootBridgeHandle;

+  VOID                            *AcpiConfig;

+  EFI_STATUS                      Status;

+  UINT64                          IoBase;

+  UINT64                          Mem32Base;

+  UINT64                          PMem32Base;

+  UINT64                          Mem64Base;

+  UINT64                          PMem64Base;

+  UINT64                          MaxOptionRomSize;

+  PCI_RESOURCE_NODE               *IoBridge;

+  PCI_RESOURCE_NODE               *Mem32Bridge;

+  PCI_RESOURCE_NODE               *PMem32Bridge;

+  PCI_RESOURCE_NODE               *Mem64Bridge;

+  PCI_RESOURCE_NODE               *PMem64Bridge;

+  PCI_RESOURCE_NODE               IoPool;

+  PCI_RESOURCE_NODE               Mem32Pool;

+  PCI_RESOURCE_NODE               PMem32Pool;

+  PCI_RESOURCE_NODE               Mem64Pool;

+  PCI_RESOURCE_NODE               PMem64Pool;

+  REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA  ExtendedData;

+

+  //

+  // Initialize resource pool

+  //

+  

+  InitializeResourcePool (&IoPool, PciBarTypeIo16);

+  InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);

+  InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);

+  InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);

+  InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);

+

+  RootBridgeDev     = NULL;

+  RootBridgeHandle  = 0;

+

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+    //

+    // Get RootBridg Device by handle

+    //

+    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_NOT_FOUND;

+    }

+

+    //

+    // Get host bridge handle for status report

+    //

+    ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;

+

+    //

+    // Create the entire system resource map from the information collected by

+    // enumerator. Several resource tree was created

+    //

+

+    IoBridge = CreateResourceNode (

+                RootBridgeDev,

+                0,

+                0xFFF,

+                0,

+                PciBarTypeIo16,

+                PciResUsageTypical

+                );

+

+    Mem32Bridge = CreateResourceNode (

+                    RootBridgeDev,

+                    0,

+                    0xFFFFF,

+                    0,

+                    PciBarTypeMem32,

+                    PciResUsageTypical

+                    );

+

+    PMem32Bridge = CreateResourceNode (

+                    RootBridgeDev,

+                    0,

+                    0xFFFFF,

+                    0,

+                    PciBarTypePMem32,

+                    PciResUsageTypical

+                    );

+

+    Mem64Bridge = CreateResourceNode (

+                    RootBridgeDev,

+                    0,

+                    0xFFFFF,

+                    0,

+                    PciBarTypeMem64,

+                    PciResUsageTypical

+                    );

+

+    PMem64Bridge = CreateResourceNode (

+                    RootBridgeDev,

+                    0,

+                    0xFFFFF,

+                    0,

+                    PciBarTypePMem64,

+                    PciResUsageTypical

+                    );

+

+    //

+    // Create resourcemap by going through all the devices subject to this root bridge

+    //

+    Status = CreateResourceMap (

+              RootBridgeDev,

+              IoBridge,

+              Mem32Bridge,

+              PMem32Bridge,

+              Mem64Bridge,

+              PMem64Bridge

+              );

+

+    //

+    // Get the max ROM size that the root bridge can process

+    //

+    RootBridgeDev->RomSize = Mem32Bridge->Length;

+

+    //

+    // Get Max Option Rom size for current root bridge

+    //

+    MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);

+

+    //

+    // Enlarger the mem32 resource to accomdate the option rom

+    // if the mem32 resource is not enough to hold the rom

+    //

+    if (MaxOptionRomSize > Mem32Bridge->Length) {

+

+      Mem32Bridge->Length     = MaxOptionRomSize;

+      RootBridgeDev->RomSize  = MaxOptionRomSize;

+

+      //

+      // Alignment should be adjusted as well

+      //

+      if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {

+        Mem32Bridge->Alignment = MaxOptionRomSize - 1;

+      }

+    }

+    

+    //

+    // Based on the all the resource tree, contruct ACPI resource node to

+    // submit the resource aperture to pci host bridge protocol

+    //

+    Status = ConstructAcpiResourceRequestor (

+              RootBridgeDev,

+              IoBridge,

+              Mem32Bridge,

+              PMem32Bridge,

+              Mem64Bridge,

+              PMem64Bridge,

+              &AcpiConfig

+              );

+

+    //

+    // Insert these resource nodes into the database

+    //

+    InsertResourceNode (&IoPool, IoBridge);

+    InsertResourceNode (&Mem32Pool, Mem32Bridge);

+    InsertResourceNode (&PMem32Pool, PMem32Bridge);

+    InsertResourceNode (&Mem64Pool, Mem64Bridge);

+    InsertResourceNode (&PMem64Pool, PMem64Bridge);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Submit the resource requirement

+      //

+      Status = PciResAlloc->SubmitResources (

+                              PciResAlloc,

+                              RootBridgeDev->Handle,

+                              AcpiConfig

+                              );

+    }

+    //

+    // Free acpi resource node

+    //

+    if (AcpiConfig) {

+      gBS->FreePool (AcpiConfig);

+    }

+

+    if (EFI_ERROR (Status)) {

+      //

+      // Destroy all the resource tree

+      //

+      DestroyResourceTree (&IoPool);

+      DestroyResourceTree (&Mem32Pool);

+      DestroyResourceTree (&PMem32Pool);

+      DestroyResourceTree (&Mem64Pool);

+      DestroyResourceTree (&PMem64Pool);

+      return Status;

+    }

+  }

+  //

+  // End while

+  //

+

+  //

+  // Notify pci bus driver starts to program the resource

+  //

+  Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);

+

+  if (EFI_ERROR (Status)) {

+    //

+    // Allocation failed, then return

+    //

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Raise the EFI_IOB_PCI_RES_ALLOC status code

+  //

+  REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+        EFI_PROGRESS_CODE,

+        EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,

+        (VOID *) &ExtendedData,

+        sizeof (ExtendedData)

+        );

+

+  //

+  // Notify pci bus driver starts to program the resource

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);

+

+  RootBridgeDev     = NULL;

+

+  RootBridgeHandle  = 0;

+

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+    //

+    // Get RootBridg Device by handle

+    //

+    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_NOT_FOUND;

+    }

+    

+    //

+    // Get acpi resource node for all the resource types

+    //

+    AcpiConfig = NULL;

+    Status = PciResAlloc->GetProposedResources (

+                            PciResAlloc,

+                            RootBridgeDev->Handle,

+                            &AcpiConfig

+                            );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Get the resource base by interpreting acpi resource node

+    //

+    //

+    GetResourceBase (

+      AcpiConfig,

+      &IoBase,

+      &Mem32Base,

+      &PMem32Base,

+      &Mem64Base,

+      &PMem64Base

+      );

+

+    //

+    // Process option rom for this root bridge

+    //

+    Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);

+

+    //

+    // Create the entire system resource map from the information collected by

+    // enumerator. Several resource tree was created

+    //

+    Status = GetResourceMap (

+              RootBridgeDev,

+              &IoBridge,

+              &Mem32Bridge,

+              &PMem32Bridge,

+              &Mem64Bridge,

+              &PMem64Bridge,

+              &IoPool,

+              &Mem32Pool,

+              &PMem32Pool,

+              &Mem64Pool,

+              &PMem64Pool

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Program IO resources

+    //

+    ProgramResource (

+      IoBase,

+      IoBridge

+      );

+

+    //

+    // Program Mem32 resources

+    //

+    ProgramResource (

+      Mem32Base,

+      Mem32Bridge

+      );

+

+    //

+    // Program PMem32 resources

+    //

+    ProgramResource (

+      PMem32Base,

+      PMem32Bridge

+      );

+

+    //

+    // Program Mem64 resources

+    //

+    ProgramResource (

+      Mem64Base,

+      Mem64Bridge

+      );

+

+    //

+    // Program PMem64 resources

+    //

+    ProgramResource (

+      PMem64Base,

+      PMem64Bridge

+      );

+

+    if (AcpiConfig != NULL) {

+      gBS->FreePool (AcpiConfig);

+    }

+  }

+

+  //

+  // Destroy all the resource tree

+  //

+  DestroyResourceTree (&IoPool);

+  DestroyResourceTree (&Mem32Pool);

+  DestroyResourceTree (&PMem32Pool);

+  DestroyResourceTree (&Mem64Pool);

+  DestroyResourceTree (&PMem64Pool);

+

+  //

+  // Notify the resource allocation phase is to end

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciScanBus (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber,

+  OUT UINT8                             *SubBusNumber,

+  OUT UINT8                             *PaddedBusRange

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to assign bus number to the given PCI bus system

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    StartBusNumber - add argument and description to function comment

+// TODO:    SubBusNumber - add argument and description to function comment

+// TODO:    PaddedBusRange - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                      Status;

+  PCI_TYPE00                      Pci;

+  UINT8                           Device;

+  UINT8                           Func;

+  UINT64                          Address;

+  UINTN                           SecondBus;

+  UINT16                          Register;

+  PCI_IO_DEVICE                   *PciDevice;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+  SecondBus       = 0;

+  Register        = 0;

+

+  ResetAllPpbBusReg (Bridge, StartBusNumber);

+

+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {

+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {

+

+      //

+      // Check to see whether a pci device is present

+      //

+      Status = PciDevicePresent (

+                PciRootBridgeIo,

+                &Pci,

+                StartBusNumber,

+                Device,

+                Func

+                );

+

+      if (!EFI_ERROR (Status)   && 

+          (IS_PCI_BRIDGE (&Pci) ||

+          IS_CARDBUS_BRIDGE (&Pci))) {

+

+        //

+        // Get the bridge information

+        //

+        Status = PciSearchDevice (

+                  Bridge,

+                  &Pci,

+                  StartBusNumber,

+                  Device,

+                  Func,

+                  &PciDevice

+                  );

+

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+

+        (*SubBusNumber)++;

+

+        SecondBus = (*SubBusNumber);

+

+        Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);

+

+        Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);

+

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint16,

+                                        Address,

+                                        1,

+                                        &Register

+                                        );

+

+        //

+        // Initialize SubBusNumber to SecondBus

+        //

+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint8,

+                                        Address,

+                                        1,

+                                        SubBusNumber

+                                        );

+        //

+        // If it is PPB, resursively search down this bridge

+        //

+        if (IS_PCI_BRIDGE (&Pci)) {

+          //

+          // Temporarily initialize SubBusNumber to maximum bus number to ensure the

+          // PCI configuration transaction to go through any PPB

+          //

+          Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+          Register  = 0xFF;

+          Status = PciRootBridgeIo->Pci.Write (

+                                          PciRootBridgeIo,

+                                          EfiPciWidthUint8,

+                                          Address,

+                                          1,

+                                          &Register

+                                          );

+

+          PreprocessController (

+            PciDevice,

+            PciDevice->BusNumber,

+            PciDevice->DeviceNumber,

+            PciDevice->FunctionNumber,

+            EfiPciBeforeChildBusEnumeration

+            );

+

+          Status = PciScanBus (

+                    PciDevice,

+                    (UINT8) (SecondBus),

+                    SubBusNumber,

+                    PaddedBusRange

+                    );

+

+          if (EFI_ERROR (Status)) {

+            return EFI_DEVICE_ERROR;

+          }

+        }

+

+        //

+        // Set the current maximum bus number under the PPB

+        //

+

+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint8,

+                                        Address,

+                                        1,

+                                        SubBusNumber

+                                        );

+

+      }

+

+      if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {

+

+        //

+        // Skip sub functions, this is not a multi function device

+        //

+

+        Func = PCI_MAX_FUNC;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// Light PCI bus driver woundn't support P2C

+// Return instead

+//

+EFI_STATUS

+PciHostBridgeP2CProcess (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  return EFI_SUCCESS;

+}

+

+//

+// Light PCI bus driver woundn't support hotplug device

+// Simplified the code

+//

+EFI_STATUS

+PciHostBridgeEnumerator (

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  This function is used to enumerate the entire host bridge 

+  in a given platform

+

+Arguments:

+

+  PciResAlloc              A pointer to the protocol to allocate resource.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_HANDLE                        RootBridgeHandle;

+  PCI_IO_DEVICE                     *RootBridgeDev;

+  EFI_STATUS                        Status;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;

+  UINT16                            MinBus;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

+

+  InitializeHotPlugSupport ();

+

+  //

+  // Notify the bus allocation phase is about to start

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);

+

+  RootBridgeHandle = NULL;

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // if a root bridge instance is found, create root bridge device for it

+    //

+

+    RootBridgeDev = CreateRootBridge (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    //

+    // Enumerate all the buses under this root bridge

+    //

+

+    Status = PciRootBridgeEnumerator (

+              PciResAlloc,

+              RootBridgeDev

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    DestroyRootBridge (RootBridgeDev);

+

+    //

+    // Error proccess here

+    //

+  }

+      

+  //

+  // Notify the bus allocation phase is to end

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);

+

+  //

+  // Notify the resource allocation phase is to start

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);

+

+  RootBridgeHandle = NULL;

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // if a root bridge instance is found, create root bridge device for it

+    //

+

+    RootBridgeDev = CreateRootBridge (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Status = StartManagingRootBridge (RootBridgeDev);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;

+    Status          = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Determine root bridge attribute by calling interface of Pcihostbridge

+    // protocol

+    //

+    DetermineRootBridgeAttributes (

+      PciResAlloc,

+      RootBridgeDev

+      );

+

+    //

+    // Collect all the resource information under this root bridge

+    // A database that records all the information about pci device subject to this

+    // root bridge will then be created

+    //

+    Status = PciPciDeviceInfoCollector (

+              RootBridgeDev,

+              (UINT8) MinBus

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    InsertRootBridge (RootBridgeDev);

+

+    //

+    // Record the hostbridge handle

+    //

+    AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.mbd b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.mbd
new file mode 100644
index 0000000..41543f7
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PciBus</BaseName>

+    <Guid>93B80004-9FB3-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa
new file mode 100644
index 0000000..1ec7426
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBus.msa
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PciBus</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>93B80004-9FB3-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for PciBus module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciBus.h</Filename>

+    <Filename>PciIo.h</Filename>

+    <Filename>PciCommand.h</Filename>

+    <Filename>PciDeviceSupport.h</Filename>

+    <Filename>PciResourceSupport.h</Filename>

+    <Filename>PciEnumerator.h</Filename>

+    <Filename>PciEnumeratorSupport.h</Filename>

+    <Filename>PciOptionRomSupport.h</Filename>

+    <Filename>PciRomTable.h</Filename>

+    <Filename>PciHotPlugSupport.h</Filename>

+    <Filename>PciLib.h</Filename>

+    <Filename>PciHotPlugSupport.c</Filename>

+    <Filename>PciRomTable.c</Filename>

+    <Filename>PciDriverOverride.h</Filename>

+    <Filename>PciPowerManagement.h</Filename>

+    <Filename>PciPowerManagement.c</Filename>

+    <Filename>PciDriverOverride.c</Filename>

+    <Filename>PciOptionRomSupport.c</Filename>

+    <Filename>PciEnumerator.c</Filename>

+    <Filename>PciEnumeratorSupport.c</Filename>

+    <Filename>PciResourceSupport.c</Filename>

+    <Filename>PciCommand.c</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>PciDeviceSupport.c</Filename>

+    <Filename>pcibus.c</Filename>

+    <Filename>PciIo.c</Filename>

+    <Filename>PciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">PciRootBridgeIo</Protocol>

+    <Protocol Usage="TO_START">PciPlatform</Protocol>

+    <Protocol Usage="TO_START">IncompatiblePciDeviceSupport</Protocol>

+    <Protocol Usage="TO_START">PciHostBridgeResourceAllocation</Protocol>

+    <Protocol Usage="TO_START">PciHotPlugInit</Protocol>

+    <Protocol Usage="TO_START">Decompress</Protocol>

+    <Protocol Usage="TO_START">LoadedImage</Protocol>

+    <Protocol Usage="TO_START">UgaIo</Protocol>

+    <Protocol Usage="BY_START">PciIo</Protocol>

+    <Protocol Usage="BY_START">BusSpecificDriverOverride</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">PciHotPlugRequest</Protocol>

+  </Protocols>

+  <SystemTables>

+    <SystemTable Usage="ALWAYS_CONSUMED">

+      <Entry>gEfiUgaIoProtocolGuid</Entry>

+    </SystemTable>

+    <SystemTable Usage="SOMETIMES_CONSUMED">

+      <Entry>gEfiPciOptionRomTableGuid</Entry>

+    </SystemTable>

+  </SystemTables>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>PciOptionRomTable</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>StatusCodeSpecificData</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="PRIVATE">

+      <C_Name>PciHotplugDevice</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPciBusDriverBinding</DriverBinding>

+      <ComponentName>gPciBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.mbd b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.mbd
new file mode 100644
index 0000000..c029652
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PciBusPciBusLite</BaseName>

+    <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiDevicePathLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.msa b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.msa
new file mode 100644
index 0000000..5d62942
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciBusLite.msa
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PciBusPciBusLite</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>C0734D12-7927-432b-986B-A7E3A35BA005</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for LightPciBus module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciBus.h</Filename>

+    <Filename>PciIo.h</Filename>

+    <Filename>PciCommand.h</Filename>

+    <Filename>PciDeviceSupport.h</Filename>

+    <Filename>PciResourceSupport.h</Filename>

+    <Filename>PciEnumerator.h</Filename>

+    <Filename>PciEnumeratorSupport.h</Filename>

+    <Filename>PciOptionRomSupport.h</Filename>

+    <Filename>PciRomTable.h</Filename>

+    <Filename>PciLib.h</Filename>

+    <Filename>PciRomTable.c</Filename>

+    <Filename>PciDriverOverride.h</Filename>

+    <Filename>PciPowerManagement.h</Filename>

+    <Filename>PciPowerManagement.c</Filename>

+    <Filename>PciDriverOverride.c</Filename>

+    <Filename>PciOptionRomSupport.c</Filename>

+    <Filename>PciEnumerator.c</Filename>

+    <Filename>PciEnumeratorSupport.c</Filename>

+    <Filename>PciResourceSupport.c</Filename>

+    <Filename>PciCommand.c</Filename>

+    <Filename>PciDeviceSupport.c</Filename>

+    <Filename>PciHotPlugSupport.c</Filename>

+    <Filename>pcibus.c</Filename>

+    <Filename>PciIo.c</Filename>

+    <Filename>LightPciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciRootBridgeIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">UgaIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciPlatform</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">BusSpecificDriverOverride</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugRequest</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">IncompatiblePciDeviceSupport</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciHotPlugInit</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">PciHostBridgeResourceAllocation</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PciOptionRomTable</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PciHotplugDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeSpecificData</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PciBusEntryPoint</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPciBusDriverBinding</DriverBinding>

+      <ComponentName>gPciBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c
new file mode 100644
index 0000000..f07c73f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.c
@@ -0,0 +1,207 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciCommand.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+

+EFI_STATUS

+PciOperateRegister (

+  IN  PCI_IO_DEVICE *PciIoDevice,

+  IN  UINT16        Command,

+  IN  UINT8         Offset,

+  IN  UINT8         Operation,

+  OUT UINT16        *PtrCommand

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Command - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Operation - add argument and description to function comment

+// TODO:    PtrCommand - add argument and description to function comment

+{

+  UINT16              OldCommand;

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  OldCommand  = 0;

+  PciIo       = &PciIoDevice->PciIo;

+

+  if (Operation != EFI_SET_REGISTER) {

+    Status = PciIo->Pci.Read (

+                          PciIo,

+                          EfiPciIoWidthUint16,

+                          Offset,

+                          1,

+                          &OldCommand

+                          );

+

+    if (Operation == EFI_GET_REGISTER) {

+      *PtrCommand = OldCommand;

+      return Status;

+    }

+  }

+

+  if (Operation == EFI_ENABLE_REGISTER) {

+    OldCommand |= Command;

+  } else if (Operation == EFI_DISABLE_REGISTER) {

+    OldCommand &= ~(Command);

+  } else {

+    OldCommand = Command;

+  }

+

+  return PciIo->Pci.Write (

+                      PciIo,

+                      EfiPciIoWidthUint16,

+                      Offset,

+                      1,

+                      &OldCommand

+                      );

+}

+

+BOOLEAN

+PciCapabilitySupport (

+  IN PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+{

+

+  if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+LocateCapabilityRegBlock (

+  IN PCI_IO_DEVICE  *PciIoDevice,

+  IN UINT8          CapId,

+  IN OUT UINT8      *Offset,

+  OUT UINT8         *NextRegBlock OPTIONAL

+  )

+/*++

+

+Routine Description:

+  Locate cap reg.

+

+Arguments:

+  PciIoDevice         - A pointer to the PCI_IO_DEVICE.

+  CapId               - The cap ID.

+  Offset              - A pointer to the offset.

+  NextRegBlock        - A pointer to the next block.

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  UINT8   CapabilityPtr;

+  UINT16  CapabilityEntry;

+  UINT8   CapabilityID;

+

+  //

+  // To check the cpability of this device supports

+  //

+  if (!PciCapabilitySupport (PciIoDevice)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (*Offset != 0) {

+    CapabilityPtr = *Offset;

+  } else {

+

+    CapabilityPtr = 0;

+    if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

+

+      PciIoDevice->PciIo.Pci.Read (

+                              &PciIoDevice->PciIo,

+                              EfiPciIoWidthUint8,

+                              EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,

+                              1,

+                              &CapabilityPtr

+                              );

+    } else {

+

+      PciIoDevice->PciIo.Pci.Read (

+                              &PciIoDevice->PciIo,

+                              EfiPciIoWidthUint8,

+                              EFI_PCI_CAPABILITY_PTR,

+                              1,

+                              &CapabilityPtr

+                              );

+    }

+  }

+

+  while (CapabilityPtr > 0x3F) {

+    //

+    // Mask it to DWORD alignment per PCI spec

+    //

+    CapabilityPtr &= 0xFC;

+    PciIoDevice->PciIo.Pci.Read (

+                            &PciIoDevice->PciIo,

+                            EfiPciIoWidthUint16,

+                            CapabilityPtr,

+                            1,

+                            &CapabilityEntry

+                            );

+

+    CapabilityID = (UINT8) CapabilityEntry;

+

+    if (CapabilityID == CapId) {

+      *Offset = CapabilityPtr;

+      if (NextRegBlock != NULL) {

+        *NextRegBlock = (UINT8) (CapabilityEntry >> 8);

+      }

+

+      return EFI_SUCCESS;

+    }

+

+    CapabilityPtr = (UINT8) (CapabilityEntry >> 8);

+  }

+

+  return EFI_NOT_FOUND;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h
new file mode 100644
index 0000000..56f632e
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h
@@ -0,0 +1,134 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    PciCommand.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_COMMAND_H

+#define _EFI_PCI_COMMAND_H

+

+#define EFI_GET_REGISTER      1

+#define EFI_SET_REGISTER      2

+#define EFI_ENABLE_REGISTER   3

+#define EFI_DISABLE_REGISTER  4

+

+EFI_STATUS

+PciOperateRegister (

+  IN  PCI_IO_DEVICE *PciIoDevice,

+  IN  UINT16        Command,

+  IN  UINT8         Offset,

+  IN  UINT8         Operation,

+  OUT UINT16        *PtrCommand

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  Command     - TODO: add argument description

+  Offset      - TODO: add argument description

+  Operation   - TODO: add argument description

+  PtrCommand  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+PciCapabilitySupport (

+  IN PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+LocateCapabilityRegBlock (

+  IN PCI_IO_DEVICE  *PciIoDevice,

+  IN UINT8          CapId,

+  IN OUT UINT8      *Offset,

+  OUT UINT8         *NextRegBlock OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice   - TODO: add argument description

+  CapId         - TODO: add argument description

+  Offset        - TODO: add argument description

+  NextRegBlock  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+#define PciReadCommandRegister(a,b) \

+        PciOperateRegister (a,0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b)

+

+#define PciSetCommandRegister(a,b) \

+        PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL)

+        

+#define PciEnableCommandRegister(a,b) \

+        PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL)

+        

+#define PciDisableCommandRegister(a,b) \

+        PciOperateRegister (a,b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL)

+

+#define PciReadBridgeControlRegister(a,b) \

+        PciOperateRegister (a,0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b)

+        

+#define PciSetBridgeControlRegister(a,b) \

+        PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL)

+

+#define PciEnableBridgeControlRegister(a,b) \

+        PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL)

+        

+#define PciDisableBridgeControlRegister(a,b) \

+        PciOperateRegister (a,b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL)

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c
new file mode 100644
index 0000000..54a7fe7
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c
@@ -0,0 +1,1345 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciDeviceSupport.c

+  

+Abstract:

+

+  This file provides routine to support Pci device node manipulation

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciDeviceSupport.h"

+

+//

+// This device structure is serviced as a header.

+// Its Next field points to the first root bridge device node

+//

+LIST_ENTRY  gPciDevicePool;

+

+EFI_STATUS

+InitializePciDevicePool (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialize the gPciDevicePool

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  InitializeListHead (&gPciDevicePool);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InsertRootBridge (

+  PCI_IO_DEVICE *RootBridge

+  )

+/*++

+

+Routine Description:

+

+  Insert a root bridge into PCI device pool

+

+Arguments:

+

+  RootBridge    - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  InsertTailList (&gPciDevicePool, &(RootBridge->Link));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InsertPciDevice (

+  PCI_IO_DEVICE *Bridge,

+  PCI_IO_DEVICE *PciDeviceNode

+  )

+/*++

+

+Routine Description:

+

+  This function is used to insert a PCI device node under

+  a bridge

+

+Arguments:

+  Bridge        - A pointer to the PCI_IO_DEVICE.

+  PciDeviceNode - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link));

+  PciDeviceNode->Parent = Bridge;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DestroyRootBridge (

+  IN PCI_IO_DEVICE *RootBridge

+  )

+/*++

+

+Routine Description:

+

+  

+Arguments:

+

+  RootBridge   - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  DestroyPciDeviceTree (RootBridge);

+

+  FreePciDevice (RootBridge);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FreePciDevice (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  Destroy a pci device node.

+  Also all direct or indirect allocated resource for this node will be freed.   

+

+Arguments:

+

+  PciIoDevice   - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  //

+  // Assume all children have been removed underneath this device

+  //

+  if (PciIoDevice->ResourcePaddingDescriptors != NULL) {

+    gBS->FreePool (PciIoDevice->ResourcePaddingDescriptors);

+  }

+

+  if (PciIoDevice->DevicePath != NULL) {

+    gBS->FreePool (PciIoDevice->DevicePath);

+  }

+

+  gBS->FreePool (PciIoDevice);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DestroyPciDeviceTree (

+  IN PCI_IO_DEVICE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  Destroy all the pci device node under the bridge.

+  Bridge itself is not included.

+

+Arguments:

+

+  Bridge   - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+

+  while (!IsListEmpty (&Bridge->ChildList)) {

+

+    CurrentLink = Bridge->ChildList.ForwardLink;

+

+    //

+    // Remove this node from the linked list

+    //

+    RemoveEntryList (CurrentLink);

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (!IsListEmpty (&Temp->ChildList)) {

+      DestroyPciDeviceTree (Temp);

+    }

+

+    FreePciDevice (Temp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DestroyRootBridgeByHandle (

+  EFI_HANDLE Controller

+  )

+/*++

+

+Routine Description:

+

+  Destroy all device nodes under the root bridge

+  specified by Controller. 

+  The root bridge itself is also included.

+

+Arguments:

+

+  Controller   - An efi handle.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+

+  CurrentLink = gPciDevicePool.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &gPciDevicePool) {

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (Temp->Handle == Controller) {

+

+      RemoveEntryList (CurrentLink);

+

+      DestroyPciDeviceTree (Temp);

+

+      FreePciDevice (Temp);

+

+      return EFI_SUCCESS;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+RegisterPciDevice (

+  IN  EFI_HANDLE                     Controller,

+  IN  PCI_IO_DEVICE                  *PciIoDevice,

+  OUT EFI_HANDLE                     *Handle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  This function is used to register the PCI device to the EFI,

+  create a handle for this PCI device,then attach apporpriate protocols

+  onto the handle.

+

+Arguments:

+

+  Controller    - An efi handle.

+  PciIoDevice   - A pointer to the PCI_IO_DEVICE.

+  Handle        - A pointer to a efi handle.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS          Status;

+  VOID                *PlatformOpRomBuffer;

+  UINTN               PlatformOpRomSize;

+  UINT8               PciExpressCapRegOffset;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  //

+  // Install the pciio protocol, device path protocol

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &PciIoDevice->Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  PciIoDevice->DevicePath,

+                  &gEfiPciIoProtocolGuid,

+                  &PciIoDevice->PciIo,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Detect if PCI Express Device

+  //

+  PciExpressCapRegOffset = 0;

+  Status = LocateCapabilityRegBlock (

+            PciIoDevice,

+            EFI_PCI_CAPABILITY_ID_PCIEXP,

+            &PciExpressCapRegOffset,

+            NULL

+            );

+  if (!EFI_ERROR (Status)) {

+    PciIoDevice->IsPciExp = TRUE;

+  }

+  

+  //

+  // Force Interrupt line to zero for cards that come up randomly

+  //

+  PciIo = &(PciIoDevice->PciIo);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);

+  //

+  // Process Platform OpRom

+  //

+  if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) {

+    PciIoDevice->AllOpRomProcessed = TRUE;

+

+    Status = gPciPlatformProtocol->GetPciRom (

+                                    gPciPlatformProtocol,

+                                    PciIoDevice->Handle,

+                                    &PlatformOpRomBuffer,

+                                    &PlatformOpRomSize

+                                    );

+

+    if (!EFI_ERROR (Status)) {

+

+      //

+      // Have Platform OpRom

+      //

+      PciIoDevice->RomSize        = PlatformOpRomSize;

+      PciIoDevice->PciIo.RomSize  = PlatformOpRomSize;

+      PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;

+

+      //

+      // Process Image

+      //

+      ProcessOpRomImage (PciIoDevice);

+    }

+  }

+

+  if (PciIoDevice->BusOverride) {

+    //

+    // Install BusSpecificDriverOverride Protocol

+    //

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &PciIoDevice->Handle,

+                    &gEfiBusSpecificDriverOverrideProtocolGuid,

+                    &PciIoDevice->PciDriverOverride,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->UninstallMultipleProtocolInterfaces (

+            &PciIoDevice->Handle,

+            &gEfiDevicePathProtocolGuid,

+            PciIoDevice->DevicePath,

+            &gEfiPciIoProtocolGuid,

+            &PciIoDevice->PciIo,

+            NULL

+            );

+

+      return Status;

+    }

+  }

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &(PciIoDevice->PciRootBridgeIo),

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  PciIoDevice->Handle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Install Pccard Hotplug GUID for Pccard device so that

+  // to notify CardBus driver to stop the device when de-register happens

+  //

+  InstallPciHotplugGuid (PciIoDevice);

+

+  if (Handle != NULL) {

+    *Handle = PciIoDevice->Handle;

+  }

+

+  //

+  // Indicate the pci device is registered

+  //

+  PciIoDevice->Registered = TRUE;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RemoveAllPciDeviceOnBridge (

+  EFI_HANDLE               RootBridgeHandle,

+  PCI_IO_DEVICE            *Bridge

+  )

+/*++

+

+Routine Description:

+

+  This function is used to remove the whole PCI devices from the bridge.

+  

+Arguments:

+

+  RootBridgeHandle   - An efi handle.

+  Bridge             - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+

+  while (!IsListEmpty (&Bridge->ChildList)) {

+

+    CurrentLink = Bridge->ChildList.ForwardLink;

+    Temp        = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    //

+    // Check if the current node has been deregistered before

+    // If it is not, then deregister it

+    //

+    if (Temp->Registered) {

+      DeRegisterPciDevice (RootBridgeHandle, Temp->Handle);

+    }

+    

+    //

+    // Remove this node from the linked list

+    //

+    RemoveEntryList (CurrentLink);

+

+    if (!IsListEmpty (&Temp->ChildList)) {

+      RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);

+    }

+

+    FreePciDevice (Temp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DeRegisterPciDevice (

+  IN  EFI_HANDLE                     Controller,

+  IN  EFI_HANDLE                     Handle

+  )

+/*++

+

+Routine Description:

+

+  This function is used to de-register the PCI device from the EFI,

+  That includes un-installing PciIo protocol from the specified PCI 

+  device handle.

+

+Arguments:

+

+  Controller   - An efi handle.

+  Handle       - An efi handle.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL             *PciIo;

+  EFI_STATUS                      Status;

+  PCI_IO_DEVICE                   *PciIoDevice;

+  PCI_IO_DEVICE                   *Node;

+  LIST_ENTRY                      *CurrentLink;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (!EFI_ERROR (Status)) {

+    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);

+

+    //

+    // If it is already de-registered

+    //

+    if (!PciIoDevice->Registered) {

+      return EFI_SUCCESS;

+    }

+

+    //

+    // If it is PPB, first de-register its children

+    //

+

+    if (!IsListEmpty (&PciIoDevice->ChildList)) {

+

+      CurrentLink = PciIoDevice->ChildList.ForwardLink;

+

+      while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {

+        Node    = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+        Status  = DeRegisterPciDevice (Controller, Node->Handle);

+

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+

+        CurrentLink = CurrentLink->ForwardLink;

+      }

+    }

+    //

+    // Uninstall Pccard Hotplug GUID for Pccard device

+    //

+    UninstallPciHotplugGuid (PciIoDevice);

+

+    //

+    // Close the child handle

+    //

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiPciRootBridgeIoProtocolGuid,

+                    gPciBusDriverBinding.DriverBindingHandle,

+                    Handle

+                    );

+

+    //

+    // Un-install the device path protocol and pci io protocol

+    //

+    if (PciIoDevice->BusOverride) {

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      Handle,

+                      &gEfiDevicePathProtocolGuid,

+                      PciIoDevice->DevicePath,

+                      &gEfiPciIoProtocolGuid,

+                      &PciIoDevice->PciIo,

+                      &gEfiBusSpecificDriverOverrideProtocolGuid,

+                      &PciIoDevice->PciDriverOverride,

+                      NULL

+                      );

+    } else {

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      Handle,

+                      &gEfiDevicePathProtocolGuid,

+                      PciIoDevice->DevicePath,

+                      &gEfiPciIoProtocolGuid,

+                      &PciIoDevice->PciIo,

+                      NULL

+                      );

+    }

+

+    if (EFI_ERROR (Status)) {

+      gBS->OpenProtocol (

+            Controller,

+            &gEfiPciRootBridgeIoProtocolGuid,

+            (VOID **) &PciRootBridgeIo,

+            gPciBusDriverBinding.DriverBindingHandle,

+            Handle,

+            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+            );

+      return Status;

+    }

+    

+    //

+    // The Device Driver should disable this device after disconnect

+    // so the Pci Bus driver will not touch this device any more.

+    // Restore the register field to the original value

+    //

+    PciIoDevice->Registered = FALSE;

+    PciIoDevice->Handle     = NULL;

+  } else {

+

+    //

+    // Handle may be closed before

+    //

+    return EFI_SUCCESS;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+StartPciDevicesOnBridge (

+  IN EFI_HANDLE                          Controller,

+  IN PCI_IO_DEVICE                       *RootBridge,

+  IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath,

+  IN OUT UINT8                           *NumberOfChildren,

+  IN OUT EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge

+

+Arguments:

+

+  Controller          - An efi handle.

+  RootBridge          - A pointer to the PCI_IO_DEVICE.

+  RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.

+  NumberOfChildren    - Children number.

+  ChildHandleBuffer   - A pointer to the child handle buffer.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_NOT_READY - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  PCI_IO_DEVICE             *Temp;

+  PCI_IO_DEVICE             *PciIoDevice;

+  EFI_DEV_PATH_PTR          Node;

+  EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;

+  EFI_STATUS                Status;

+  LIST_ENTRY                *CurrentLink;

+  UINT64                    Supports;

+

+  CurrentLink = RootBridge->ChildList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &RootBridge->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    if (RemainingDevicePath != NULL) {

+

+      Node.DevPath = RemainingDevicePath;

+

+      if (Node.Pci->Device != Temp->DeviceNumber || 

+          Node.Pci->Function != Temp->FunctionNumber) {

+        CurrentLink = CurrentLink->ForwardLink;

+        continue;

+      }

+

+      //

+      // Check if the device has been assigned with required resource

+      //

+      if (!Temp->Allocated) {

+        return EFI_NOT_READY;

+      }

+      

+      //

+      // Check if the current node has been registered before

+      // If it is not, register it

+      //

+      if (!Temp->Registered) {

+        PciIoDevice = Temp;

+

+        Status = RegisterPciDevice (

+                  Controller,

+                  PciIoDevice,

+                  NULL

+                  );

+

+      }

+

+      if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {

+        ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;

+        (*NumberOfChildren)++;

+      }

+      

+      //

+      // Get the next device path

+      //

+      CurrentDevicePath = EfiNextDevicePathNode (RemainingDevicePath);

+      if (EfiIsDevicePathEnd (CurrentDevicePath)) {

+        return EFI_SUCCESS;

+      }

+  

+      //

+      // If it is a PPB

+      //

+      if (!IsListEmpty (&Temp->ChildList)) {

+        Status = StartPciDevicesOnBridge (

+                  Controller,

+                  Temp,

+                  CurrentDevicePath,

+                  NumberOfChildren,

+                  ChildHandleBuffer

+                  );

+

+        Temp->PciIo.Attributes (

+                      &(Temp->PciIo),

+                      EfiPciIoAttributeOperationSupported,

+                      0,

+                      &Supports

+                      );

+        Supports &= EFI_PCI_DEVICE_ENABLE;

+        Temp->PciIo.Attributes (

+                      &(Temp->PciIo),

+                      EfiPciIoAttributeOperationEnable,

+                      Supports,

+                      NULL

+                      );

+

+        return Status;

+      } else {

+

+        //

+        // Currently, the PCI bus driver only support PCI-PCI bridge

+        //

+        return EFI_UNSUPPORTED;

+      }

+

+    } else {

+

+      //

+      // If remaining device path is NULL,

+      // try to enable all the pci devices under this bridge

+      //

+

+      if (!Temp->Registered && Temp->Allocated) {

+

+        PciIoDevice = Temp;

+

+        Status = RegisterPciDevice (

+                  Controller,

+                  PciIoDevice,

+                  NULL

+                  );

+

+      }

+

+      if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {

+        ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;

+        (*NumberOfChildren)++;

+      }

+

+      if (!IsListEmpty (&Temp->ChildList)) {

+        Status = StartPciDevicesOnBridge (

+                  Controller,

+                  Temp,

+                  RemainingDevicePath,

+                  NumberOfChildren,

+                  ChildHandleBuffer

+                  );

+

+        Temp->PciIo.Attributes (

+                      &(Temp->PciIo),

+                      EfiPciIoAttributeOperationSupported,

+                      0,

+                      &Supports

+                      );

+        Supports &= EFI_PCI_DEVICE_ENABLE;

+        Temp->PciIo.Attributes (

+                      &(Temp->PciIo),

+                      EfiPciIoAttributeOperationEnable,

+                      Supports,

+                      NULL

+                      );

+

+      }

+

+      CurrentLink = CurrentLink->ForwardLink;

+      continue;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+StartPciDevices (

+  IN EFI_HANDLE                         Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Start to manage the PCI device according to RemainingDevicePath

+  If RemainingDevicePath == NULL, the PCI bus driver will start 

+  to manage all the PCI devices it found previously

+

+Arguments:

+  Controller          - An efi handle.

+  RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_DEV_PATH_PTR  Node;

+  PCI_IO_DEVICE     *RootBridge;

+  LIST_ENTRY        *CurrentLink;

+

+  if (RemainingDevicePath != NULL) {

+

+    //

+    // Check if the RemainingDevicePath is valid

+    //

+    Node.DevPath = RemainingDevicePath;

+    if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||

+        ((Node.DevPath->SubType != HW_PCI_DP)         &&

+         (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))

+        ) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  CurrentLink = gPciDevicePool.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &gPciDevicePool) {

+

+    RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    //

+    // Locate the right root bridge to start

+    //

+    if (RootBridge->Handle == Controller) {

+      StartPciDevicesOnBridge (

+        Controller,

+        RootBridge,

+        RemainingDevicePath,

+        NULL,

+        NULL

+        );

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+PCI_IO_DEVICE *

+CreateRootBridge (

+  IN EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+  RootBridgeHandle   - An efi handle.

+

+Returns:

+

+  None

+

+--*/

+{

+

+  EFI_STATUS                      Status;

+  PCI_IO_DEVICE                   *Dev;

+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  Dev = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (PCI_IO_DEVICE),

+                  (VOID **) &Dev

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+

+  ZeroMem (Dev, sizeof (PCI_IO_DEVICE));

+  Dev->Signature  = PCI_IO_DEVICE_SIGNATURE;

+  Dev->Handle     = RootBridgeHandle;

+  InitializeListHead (&Dev->ChildList);

+

+  Status = gBS->OpenProtocol (

+                  RootBridgeHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  RootBridgeHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Dev);

+    return NULL;

+  }

+

+  //

+  // Record the root bridge parent device path

+  //

+  Dev->DevicePath = DuplicateDevicePath (ParentDevicePath);

+

+  //

+  // Get the pci root bridge io protocol

+  //

+  Status = gBS->OpenProtocol (

+                  RootBridgeHandle,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &PciRootBridgeIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  RootBridgeHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    FreePciDevice (Dev);

+    return NULL;

+  }

+

+  Dev->PciRootBridgeIo = PciRootBridgeIo;

+

+  //

+  // Initialize the PCI I/O instance structure

+  //

+  Status  = InitializePciIoInstance (Dev);

+  Status  = InitializePciDriverOverrideInstance (Dev);

+

+  //

+  // Initialize reserved resource list and

+  // option rom driver list

+  //

+  InitializeListHead (&Dev->ReservedResourceList);

+  InitializeListHead (&Dev->OptionRomDriverList);

+

+  return Dev;

+}

+

+PCI_IO_DEVICE *

+GetRootBridgeByHandle (

+  EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+  RootBridgeHandle    - An efi handle.

+

+Returns:

+

+  None

+

+--*/

+{

+  PCI_IO_DEVICE   *RootBridgeDev;

+  LIST_ENTRY      *CurrentLink;

+

+  CurrentLink = gPciDevicePool.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &gPciDevicePool) {

+

+    RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    if (RootBridgeDev->Handle == RootBridgeHandle) {

+      return RootBridgeDev;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return NULL;

+}

+

+BOOLEAN

+RootBridgeExisted (

+  IN EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+  This function searches if RootBridgeHandle has already existed

+  in current device pool.

+

+  If so, it means the given root bridge has been already enumerated.

+

+Arguments:

+

+  RootBridgeHandle   - An efi handle.

+

+Returns:

+

+  None

+

+--*/

+{

+  PCI_IO_DEVICE *Bridge;

+

+  Bridge = GetRootBridgeByHandle (RootBridgeHandle);

+

+  if (Bridge != NULL) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+PciDeviceExisted (

+  IN PCI_IO_DEVICE    *Bridge,

+  IN PCI_IO_DEVICE    *PciIoDevice

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+  Bridge       - A pointer to the PCI_IO_DEVICE.

+  PciIoDevice  - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+{

+

+  PCI_IO_DEVICE   *Temp;

+  LIST_ENTRY      *CurrentLink;

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (Temp == PciIoDevice) {

+      return TRUE;

+    }

+

+    if (!IsListEmpty (&Temp->ChildList)) {

+      if (PciDeviceExisted (Temp, PciIoDevice)) {

+        return TRUE;

+      }

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return FALSE;

+}

+

+PCI_IO_DEVICE *

+ActiveVGADeviceOnTheSameSegment (

+  IN PCI_IO_DEVICE        *VgaDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  VgaDevice    - A pointer to the PCI_IO_DEVICE.

+  

+Returns:

+

+  None

+

+--*/

+{

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+

+  CurrentLink = gPciDevicePool.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &gPciDevicePool) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {

+

+      Temp = ActiveVGADeviceOnTheRootBridge (Temp);

+

+      if (Temp != NULL) {

+        return Temp;

+      }

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return NULL;

+}

+

+PCI_IO_DEVICE *

+ActiveVGADeviceOnTheRootBridge (

+  IN PCI_IO_DEVICE        *RootBridge

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  RootBridge    - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+{

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+

+  CurrentLink = RootBridge->ChildList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &RootBridge->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (IS_PCI_VGA(&Temp->Pci) && 

+        (Temp->Attributes & (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO))) {

+      return Temp;

+    }

+

+    if (IS_PCI_BRIDGE (&Temp->Pci)) {

+

+      Temp = ActiveVGADeviceOnTheRootBridge (Temp);

+

+      if (Temp != NULL) {

+        return Temp;

+      }

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return NULL;

+}

+

+EFI_STATUS

+GetHpcPciAddress (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *HpcDevicePath,

+  OUT UINT64                           *PciAddress

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  PciRootBridgeIo       - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  HpcDevicePath         - A pointer to the EFI_DEVICE_PATH_PROTOCL.

+  PciAddress            - A pointer to the pci address.

+  

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;

+  EFI_DEV_PATH_PTR          Node;

+  LIST_ENTRY                *CurrentLink;

+  PCI_IO_DEVICE             *RootBridge;

+  EFI_STATUS                Status;

+

+  CurrentDevicePath = HpcDevicePath;

+

+  //

+  // Get the remaining device path for this PCI device, if it is a PCI device

+  //

+  while (!EfiIsDevicePathEnd (CurrentDevicePath)) {

+

+    Node.DevPath = CurrentDevicePath;

+

+    //

+    // Check if it is PCI device Path?

+    //

+    if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||

+        ((Node.DevPath->SubType != HW_PCI_DP)         &&

+         (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))) {

+      CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);

+      continue;

+    }

+

+    break;

+  }

+

+  //

+  // Check if it is not PCI device path

+  //

+  if (EfiIsDevicePathEnd (CurrentDevicePath)) {

+    return EFI_NOT_FOUND;

+  }

+

+  CurrentLink = gPciDevicePool.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &gPciDevicePool) {

+

+    RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    //

+    // Locate the right root bridge to start

+    //

+    if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) {

+      Status = GetHpcPciAddressFromRootBridge (

+                RootBridge,

+                CurrentDevicePath,

+                PciAddress

+                );

+      if (EFI_ERROR (Status)) {

+        return EFI_NOT_FOUND;

+      }

+

+      return EFI_SUCCESS;

+

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+GetHpcPciAddressFromRootBridge (

+  IN  PCI_IO_DEVICE                    *RootBridge,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *RemainingDevicePath,

+  OUT UINT64                           *PciAddress

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  PciRootBridgeIo       - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  HpcDevicePath         - A pointer to the EFI_DEVICE_PATH_PROTOCL.

+  PciAddress            - A pointer to the pci address.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    RootBridge - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_DEV_PATH_PTR          Node;

+  PCI_IO_DEVICE             *Temp;

+  EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;

+  LIST_ENTRY                *CurrentLink;

+  BOOLEAN                   MisMatch;

+

+  MisMatch          = FALSE;

+

+  CurrentDevicePath = RemainingDevicePath;

+  Node.DevPath      = CurrentDevicePath;

+  Temp              = NULL;

+

+  while (!EfiIsDevicePathEnd (CurrentDevicePath)) {

+

+    CurrentLink   = RootBridge->ChildList.ForwardLink;

+    Node.DevPath  = CurrentDevicePath;

+

+    while (CurrentLink && CurrentLink != &RootBridge->ChildList) {

+      Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+      if (Node.Pci->Device   == Temp->DeviceNumber &&

+          Node.Pci->Function == Temp->FunctionNumber) {

+        RootBridge = Temp;

+        break;

+      }

+

+      CurrentLink = CurrentLink->ForwardLink;

+    }

+

+    //

+    // Check if we find the bridge

+    //

+    if (CurrentLink == &RootBridge->ChildList) {

+

+      MisMatch = TRUE;

+      break;

+

+    }

+

+    CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);

+  }

+

+  if (MisMatch) {

+

+    CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);

+

+    if (EfiIsDevicePathEnd (CurrentDevicePath)) {

+      *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0);

+      return EFI_SUCCESS;

+    }

+

+    return EFI_NOT_FOUND;

+  }

+

+  *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);

+

+  return EFI_SUCCESS;

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h
new file mode 100644
index 0000000..374f4df
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.h
@@ -0,0 +1,477 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciDeviceSupport.h

+  

+Abstract:

+

+  

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_DEVICE_SUPPORT_H

+#define _EFI_PCI_DEVICE_SUPPORT_H

+

+EFI_STATUS

+InitializePciDevicePool (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InsertRootBridge (

+  PCI_IO_DEVICE *RootBridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InsertPciDevice (

+  PCI_IO_DEVICE *Bridge,

+  PCI_IO_DEVICE *PciDeviceNode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge        - TODO: add argument description

+  PciDeviceNode - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DestroyRootBridge (

+  IN PCI_IO_DEVICE *RootBridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DestroyPciDeviceTree (

+  IN PCI_IO_DEVICE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DestroyRootBridgeByHandle (

+  EFI_HANDLE Controller

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RegisterPciDevice (

+  IN  EFI_HANDLE                     Controller,

+  IN  PCI_IO_DEVICE                  *PciIoDevice,

+  OUT EFI_HANDLE                     *Handle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller  - TODO: add argument description

+  PciIoDevice - TODO: add argument description

+  Handle      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RemoveAllPciDeviceOnBridge (

+  EFI_HANDLE               RootBridgeHandle,

+  PCI_IO_DEVICE            *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+  Bridge            - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DeRegisterPciDevice (

+  IN  EFI_HANDLE                     Controller,

+  IN  EFI_HANDLE                     Handle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller  - TODO: add argument description

+  Handle      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StartPciDevicesOnBridge (

+  IN EFI_HANDLE                          Controller,

+  IN PCI_IO_DEVICE                       *RootBridge,

+  IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath,

+  IN OUT UINT8                           *NumberOfChildren,

+  IN OUT EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller          - TODO: add argument description

+  RootBridge          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+  NumberOfChildren    - TODO: add argument description

+  ChildHandleBuffer   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StartPciDevices (

+  IN EFI_HANDLE                         Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE *

+CreateRootBridge (

+  IN EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE *

+GetRootBridgeByHandle (

+  EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+RootBridgeExisted (

+  IN EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+PciDeviceExisted (

+  IN PCI_IO_DEVICE    *Bridge,

+  IN PCI_IO_DEVICE    *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge      - TODO: add argument description

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE *

+ActiveVGADeviceOnTheSameSegment (

+  IN PCI_IO_DEVICE        *VgaDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  VgaDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE *

+ActiveVGADeviceOnTheRootBridge (

+  IN PCI_IO_DEVICE        *RootBridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetHpcPciAddress (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *HpcDevicePath,

+  OUT UINT64                           *PciAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciRootBridgeIo - TODO: add argument description

+  HpcDevicePath   - TODO: add argument description

+  PciAddress      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetHpcPciAddressFromRootBridge (

+  IN  PCI_IO_DEVICE                    *RootBridge,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *RemainingDevicePath,

+  OUT UINT64                           *PciAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridge          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+  PciAddress          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+FreePciDevice (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c
new file mode 100644
index 0000000..76c5a20
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.c
@@ -0,0 +1,290 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciDriverOverride.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+

+EFI_STATUS

+InitializePciDriverOverrideInstance (

+  PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  Initializes a PCI Driver Override Instance

+

+Arguments:

+  

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PciIoDevice->PciDriverOverride.GetDriver = GetDriver;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GetDriver (

+  IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL              *This,

+  IN OUT EFI_HANDLE                                         *DriverImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Get a overriding driver image

+

+Arguments:

+  

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    DriverImageHandle - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  PCI_IO_DEVICE             *PciIoDevice;

+  LIST_ENTRY                *CurrentLink;

+  PCI_DRIVER_OVERRIDE_LIST  *Node;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);

+

+  CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {

+

+    Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);

+

+    if (*DriverImageHandle == NULL) {

+

+      *DriverImageHandle = Node->DriverImageHandle;

+      return EFI_SUCCESS;

+    }

+

+    if (*DriverImageHandle == Node->DriverImageHandle) {

+

+      if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||

+          CurrentLink->ForwardLink == NULL) {

+        return EFI_NOT_FOUND;

+      }

+

+      //

+      // Get next node

+      //

+      Node                = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);

+      *DriverImageHandle  = Node->DriverImageHandle;

+      return EFI_SUCCESS;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+EFI_STATUS

+AddDriver (

+  IN PCI_IO_DEVICE     *PciIoDevice,

+  IN EFI_HANDLE        DriverImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Add a overriding driver image

+

+Arguments:

+  

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    DriverImageHandle - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                    Status;

+  EFI_IMAGE_DOS_HEADER          *DosHdr;

+  EFI_IMAGE_NT_HEADERS          *PeHdr;

+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;

+  PCI_DRIVER_OVERRIDE_LIST      *Node;

+  EFI_DRIVER_OS_HANDOFF_HEADER  *DriverOsHandoffHeader;

+  EFI_DRIVER_OS_HANDOFF_HEADER  *NewDriverOsHandoffHeader;

+  EFI_DRIVER_OS_HANDOFF         *DriverOsHandoff;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  EFI_HANDLE                    DeviceHandle;

+  UINTN                         NumberOfEntries;

+  UINTN                         Size;

+  UINTN                         Index;

+

+  Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));

+  if (Node == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Node->Signature         = DRIVER_OVERRIDE_SIGNATURE;

+  Node->DriverImageHandle = DriverImageHandle;

+

+  InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));

+

+  PciIoDevice->BusOverride  = TRUE;

+

+  DosHdr                    = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;

+  if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    return EFI_SUCCESS;

+  }

+

+  PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);

+

+  if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {

+    return EFI_SUCCESS;

+  }

+

+  DriverOsHandoffHeader = NULL;

+  Status                = EfiGetSystemConfigurationTable (&gEfiUgaIoProtocolGuid, (VOID **) &DriverOsHandoffHeader);

+  if (!EFI_ERROR (Status) && DriverOsHandoffHeader != NULL) {

+    for (Index = 0; Index < DriverOsHandoffHeader->NumberOfEntries; Index++) {

+      DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)(DriverOsHandoffHeader)    + 

+                                                  DriverOsHandoffHeader->HeaderSize + 

+                                                  Index * DriverOsHandoffHeader->SizeOfEntries);

+      DevicePath  = DriverOsHandoff->DevicePath;

+      Status      = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);

+      if (!EFI_ERROR (Status) && DeviceHandle != NULL && IsDevicePathEnd (DevicePath)) {

+        if (DeviceHandle == PciIoDevice->Handle) {

+          return EFI_SUCCESS;

+        }

+      }

+    }

+

+    NumberOfEntries = DriverOsHandoffHeader->NumberOfEntries + 1;

+  } else {

+    NumberOfEntries = 1;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  sizeof (EFI_DRIVER_OS_HANDOFF_HEADER) + NumberOfEntries * sizeof (EFI_DRIVER_OS_HANDOFF),

+                  (VOID **) &NewDriverOsHandoffHeader

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (DriverOsHandoffHeader == NULL) {

+    NewDriverOsHandoffHeader->Version         = 0;

+    NewDriverOsHandoffHeader->HeaderSize      = sizeof (EFI_DRIVER_OS_HANDOFF_HEADER);

+    NewDriverOsHandoffHeader->SizeOfEntries   = sizeof (EFI_DRIVER_OS_HANDOFF);

+    NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;

+  } else {

+    gBS->CopyMem (

+          NewDriverOsHandoffHeader,

+          DriverOsHandoffHeader,

+          DriverOsHandoffHeader->HeaderSize + (NumberOfEntries - 1) * DriverOsHandoffHeader->SizeOfEntries

+          );

+    NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;

+  }

+

+  DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)NewDriverOsHandoffHeader      + 

+                                              NewDriverOsHandoffHeader->HeaderSize + 

+                                              (NumberOfEntries - 1) * NewDriverOsHandoffHeader->SizeOfEntries);

+

+  //

+  // Fill in the EFI_DRIVER_OS_HANDOFF structure

+  //

+  DriverOsHandoff->Type = EfiUgaDriverFromPciRom;

+

+  //

+  // Compute the size of the device path

+  //

+  Size = GetDevicePathSize (PciIoDevice->DevicePath);

+  if (Size == 0) {

+    DriverOsHandoff->DevicePath = NULL;

+  } else {

+

+    //

+    // Allocate space for duplicate device path

+    //

+    Status = gBS->AllocatePool (

+                    EfiRuntimeServicesData,

+                    Size,

+                    (VOID **) &DriverOsHandoff->DevicePath

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (NewDriverOsHandoffHeader);

+      return Status;

+    }

+

+    //

+    // Make copy of device path

+    //

+    CopyMem (DriverOsHandoff->DevicePath, PciIoDevice->DevicePath, Size);

+  }

+

+  DriverOsHandoff->PciRomSize = (UINT64) PciIoDevice->PciIo.RomSize;

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  (UINTN) DriverOsHandoff->PciRomSize,

+                  (VOID **) &DriverOsHandoff->PciRomImage

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (NewDriverOsHandoffHeader);

+    return Status;

+  }

+

+  gBS->CopyMem (

+        DriverOsHandoff->PciRomImage,

+        PciIoDevice->PciIo.RomImage,

+        (UINTN) DriverOsHandoff->PciRomSize

+        );

+

+  Status = gBS->InstallConfigurationTable (&gEfiUgaIoProtocolGuid, NewDriverOsHandoffHeader);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (DriverOsHandoffHeader != NULL) {

+    gBS->FreePool (DriverOsHandoffHeader);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h
new file mode 100644
index 0000000..5992df9
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDriverOverride.h
@@ -0,0 +1,108 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciDriverOverride.h

+  

+Abstract:

+

+  

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H

+#define _EFI_PCI_DRIVER_OVERRRIDE_H

+

+#define DRIVER_OVERRIDE_SIGNATURE EFI_SIGNATURE_32 ('d', 'r', 'o', 'v')

+

+typedef struct {

+  UINT32          Signature;

+  LIST_ENTRY      Link;

+  EFI_HANDLE      DriverImageHandle;

+} PCI_DRIVER_OVERRIDE_LIST;

+

+

+#define DRIVER_OVERRIDE_FROM_LINK(a) \

+  CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE)

+

+

+EFI_STATUS

+InitializePciDriverOverrideInstance (

+  PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AddDriver (

+  IN PCI_IO_DEVICE     *PciIoDevice,

+  IN EFI_HANDLE        DriverImageHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice       - TODO: add argument description

+  DriverImageHandle - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+GetDriver (

+  IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL              *This,

+  IN OUT EFI_HANDLE                                         *DriverImageHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  DriverImageHandle - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c
new file mode 100644
index 0000000..384e86f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.c
@@ -0,0 +1,2164 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciEnumerator.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciEnumerator.h"

+#include "PciResourceSupport.h"

+#include "PciOptionRomSupport.h"

+

+EFI_STATUS

+PciEnumerator (

+  IN EFI_HANDLE                    Controller

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to enumerate entire pci bus system 

+  in a given platform

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Controller - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  EFI_HANDLE                                        HostBridgeHandle;

+  EFI_STATUS                                        Status;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL                   *PciRootBridgeIo;

+

+  //

+  // If PCI bus has already done the full enumeration, never do it again

+  //

+  if (!gFullEnumeration) {

+    return PciEnumeratorLight (Controller);

+  }

+

+  //

+  // If this host bridge has been already enumerated, then return successfully

+  //

+  if (RootBridgeExisted (Controller)) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Get the rootbridge Io protocol to find the host bridge handle

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &PciRootBridgeIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get the host bridge handle

+  //

+  HostBridgeHandle = PciRootBridgeIo->ParentHandle;

+

+  //

+  // Get the pci host bridge resource allocation protocol

+  //

+  Status = gBS->OpenProtocol (

+                  HostBridgeHandle,

+                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,

+                  (VOID **) &PciResAlloc,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Notify the pci bus enumeration is about to begin

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);

+

+  //

+  // Start the bus allocation phase

+  //

+  Status = PciHostBridgeEnumerator (PciResAlloc);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+      

+  //

+  // Submit the resource request

+  //

+  Status = PciHostBridgeResourceAllocator (PciResAlloc);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Process P2C

+  //

+  Status = PciHostBridgeP2CProcess (PciResAlloc);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Process attributes for devices on this host bridge

+  //

+  Status = PciHostBridgeDeviceAttribute (PciResAlloc);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gFullEnumeration = FALSE;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciRootBridgeEnumerator (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc,

+  IN PCI_IO_DEVICE                                     *RootBridgeDev

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    RootBridgeDev - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;

+  UINT8                             SubBusNumber;

+  UINT8                             StartBusNumber;

+  UINT8                             PaddedBusRange;

+  EFI_HANDLE                        RootBridgeHandle;

+

+  SubBusNumber    = 0;

+  StartBusNumber  = 0;

+  PaddedBusRange  = 0;

+

+  //

+  // Get the root bridge handle

+  //

+  RootBridgeHandle = RootBridgeDev->Handle;

+

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,

+    RootBridgeDev->DevicePath

+    );

+

+  //

+  // Get the Bus information

+  //

+  Status = PciResAlloc->StartBusEnumeration (

+                          PciResAlloc,

+                          RootBridgeHandle,

+                          (VOID **) &pConfiguration

+                          );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get the bus number to start with

+  //

+  StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);

+

+  //

+  // Initialize the subordinate bus number

+  //

+  SubBusNumber = StartBusNumber;

+

+  //

+  // Assign bus number

+  //

+  Status = PciScanBus (

+            RootBridgeDev,

+            (UINT8) (pConfiguration->AddrRangeMin),

+            &SubBusNumber,

+            &PaddedBusRange

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+

+  //

+  // Assign max bus number scanned

+  //

+  pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;

+

+  //

+  // Set bus number

+  //

+  Status = PciResAlloc->SetBusNumbers (

+                          PciResAlloc,

+                          RootBridgeHandle,

+                          pConfiguration

+                          );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ProcessOptionRom (

+  IN PCI_IO_DEVICE *Bridge,

+  IN UINT64        RomBase,

+  IN UINT64        MaxLength

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to process option rom on a certain root bridge

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    RomBase - add argument and description to function comment

+// TODO:    MaxLength - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+  EFI_STATUS      Status;

+

+  //

+  // Go through bridges to reach all devices

+  //

+  CurrentLink = Bridge->ChildList.ForwardLink;

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    if (!IsListEmpty (&Temp->ChildList)) {

+      

+      //

+      // Go further to process the option rom under this bridge

+      //

+      Status = ProcessOptionRom (Temp, RomBase, MaxLength);

+    }

+

+    if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {

+     

+      //

+      // Load and process the option rom

+      //

+      Status = LoadOpRomImage (Temp, RomBase);

+      if (Status == EFI_SUCCESS) {

+        Status = ProcessOpRomImage (Temp);

+      }

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciAssignBusNumber (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber,

+  OUT UINT8                             *SubBusNumber

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to assign bus number to the given PCI bus system

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    StartBusNumber - add argument and description to function comment

+// TODO:    SubBusNumber - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                      Status;

+  PCI_TYPE00                      Pci;

+  UINT8                           Device;

+  UINT8                           Func;

+  UINT64                          Address;

+  UINTN                           SecondBus;

+  UINT16                          Register;

+  UINT8                           Register8;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+

+  SecondBus       = 0;

+  Register        = 0;

+

+  *SubBusNumber = StartBusNumber;

+

+  //

+  // First check to see whether the parent is ppb

+  //

+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {

+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {

+

+      //

+      // Check to see whether a pci device is present

+      //

+

+      Status = PciDevicePresent (

+                PciRootBridgeIo,

+                &Pci,

+                StartBusNumber,

+                Device,

+                Func

+                );

+

+      if (!EFI_ERROR (Status)   &&

+          (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {

+

+        //

+        // Reserved one bus for cardbus bridge

+        //

+        SecondBus = ++(*SubBusNumber);

+

+        Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);

+

+        Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);

+

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint16,

+                                        Address,

+                                        1,

+                                        &Register

+                                        );

+

+        //

+        // Initialize SubBusNumber to SecondBus

+        //

+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint8,

+                                        Address,

+                                        1,

+                                        SubBusNumber

+                                        );

+        //

+        // If it is PPB, resursively search down this bridge

+        //

+        if (IS_PCI_BRIDGE (&Pci)) {

+

+          Register8 = 0xFF;

+          Status = PciRootBridgeIo->Pci.Write (

+                                          PciRootBridgeIo,

+                                          EfiPciWidthUint8,

+                                          Address,

+                                          1,

+                                          &Register8

+                                          );

+

+          Status = PciAssignBusNumber (

+                    Bridge,

+                    (UINT8) (SecondBus),

+                    SubBusNumber

+                    );

+

+          if (EFI_ERROR (Status)) {

+            return EFI_DEVICE_ERROR;

+          }

+        }

+

+        //

+        // Set the current maximum bus number under the PPB

+        //

+

+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint8,

+                                        Address,

+                                        1,

+                                        SubBusNumber

+                                        );

+

+      }

+

+      if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {

+

+        //

+        // Skip sub functions, this is not a multi function device

+        //

+

+        Func = PCI_MAX_FUNC;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DetermineRootBridgeAttributes (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,

+  IN PCI_IO_DEVICE                                    *RootBridgeDev

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to determine the root bridge attribute by interfacing

+  the host bridge resource allocation protocol.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    RootBridgeDev - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64      Attributes;

+  EFI_STATUS  Status;

+  EFI_HANDLE  RootBridgeHandle;

+

+  Attributes        = 0;

+  RootBridgeHandle  = RootBridgeDev->Handle;

+

+  //

+  // Get root bridge attribute by calling into pci host bridge resource allocation protocol

+  //

+  Status = PciResAlloc->GetAllocAttributes (

+                          PciResAlloc,

+                          RootBridgeHandle,

+                          &Attributes

+                          );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Here is the point where PCI bus driver calls HOST bridge allocation protocol

+  // Currently we hardcoded for ea815

+  //

+  

+  if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {

+    RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;

+  }

+

+  if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {

+    RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;

+  }

+

+  RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;

+  RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;

+  RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;

+

+  return EFI_SUCCESS;

+}

+

+UINT64

+GetMaxOptionRomSize (

+  IN PCI_IO_DEVICE   *Bridge

+  )

+/*++

+

+Routine Description:

+  

+    Get Max Option Rom size on this bridge

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+{

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+  UINT64          MaxOptionRomSize;

+  UINT64          TempOptionRomSize;

+

+  MaxOptionRomSize = 0;

+

+  //

+  // Go through bridges to reach all devices

+  //

+  CurrentLink = Bridge->ChildList.ForwardLink;

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    if (!IsListEmpty (&Temp->ChildList)) {

+      

+      //

+      // Get max option rom size under this bridge

+      //

+      TempOptionRomSize = GetMaxOptionRomSize (Temp);

+

+      //

+      // Compare with the option rom size of the bridge

+      // Get the larger one

+      //

+      if (Temp->RomSize > TempOptionRomSize) {

+        TempOptionRomSize = Temp->RomSize;

+      }

+

+    } else {

+      

+      //

+      // For devices get the rom size directly

+      //

+      TempOptionRomSize = Temp->RomSize;

+    }

+    

+    //

+    // Get the largest rom size on this bridge

+    //

+    if (TempOptionRomSize > MaxOptionRomSize) {

+      MaxOptionRomSize = TempOptionRomSize;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return MaxOptionRomSize;

+}

+

+EFI_STATUS

+PciHostBridgeDeviceAttribute (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+  

+    Process attributes of devices on this host bridge

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_HANDLE    RootBridgeHandle;

+  PCI_IO_DEVICE *RootBridgeDev;

+  EFI_STATUS    Status;

+

+  RootBridgeHandle = NULL;

+

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // Get RootBridg Device by handle

+    //

+    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_NOT_FOUND;

+    }

+

+    //

+    // Set the attributes for devcies behind the Root Bridge

+    //

+    Status = DetermineDeviceAttribute (RootBridgeDev);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetResourceAllocationStatus (

+  VOID        *AcpiConfig,

+  OUT UINT64  *IoResStatus,

+  OUT UINT64  *Mem32ResStatus,

+  OUT UINT64  *PMem32ResStatus,

+  OUT UINT64  *Mem64ResStatus,

+  OUT UINT64  *PMem64ResStatus

+  )

+/*++

+

+Routine Description:

+  

+    Get resource allocation status from the ACPI pointer

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    AcpiConfig - add argument and description to function comment

+// TODO:    IoResStatus - add argument and description to function comment

+// TODO:    Mem32ResStatus - add argument and description to function comment

+// TODO:    PMem32ResStatus - add argument and description to function comment

+// TODO:    Mem64ResStatus - add argument and description to function comment

+// TODO:    PMem64ResStatus - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  UINT8                             *Temp;

+  UINT64                            ResStatus;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;

+

+  Temp = (UINT8 *) AcpiConfig;

+

+  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {

+

+    ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;

+    ResStatus = ptr->AddrTranslationOffset;

+

+    switch (ptr->ResType) {

+    case 0:

+      if (ptr->AddrSpaceGranularity == 32) {

+        if (ptr->SpecificFlag == 0x06) {

+          //

+          // Pmem32

+          //

+          *PMem32ResStatus = ResStatus;

+        } else {

+          //

+          // Mem32

+          //

+          *Mem32ResStatus = ResStatus;

+        }

+      }

+

+      if (ptr->AddrSpaceGranularity == 64) {

+        if (ptr->SpecificFlag == 0x06) {

+          //

+          // PMem64

+          //

+          *PMem64ResStatus = ResStatus;

+        } else {

+          //

+          // Mem64

+          //

+          *Mem64ResStatus = ResStatus;

+        }

+      }

+

+      break;

+

+    case 1:

+      //

+      // Io

+      //

+      *IoResStatus = ResStatus;

+      break;

+

+    default:

+      break;

+    }

+

+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RejectPciDevice (

+  IN PCI_IO_DEVICE       *PciDevice

+  )

+/*++

+

+Routine Description:

+  

+    Remove a PCI device from device pool and mark its bar

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+{

+  PCI_IO_DEVICE   *Bridge;

+  PCI_IO_DEVICE   *Temp;

+  LIST_ENTRY      *CurrentLink;

+

+  //

+  // Remove the padding resource from a bridge

+  //

+  if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \

+       PciDevice->ResourcePaddingDescriptors ) {

+    gBS->FreePool (PciDevice->ResourcePaddingDescriptors);

+    PciDevice->ResourcePaddingDescriptors = NULL;

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Skip RB and PPB

+  //

+  if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {

+    return EFI_ABORTED;

+  }

+

+  if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {

+    //

+    // Get the root bridge device

+    //

+    Bridge = PciDevice;

+    while (Bridge->Parent) {

+      Bridge = Bridge->Parent;

+    }

+

+    RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);

+

+    //

+    // Mark its bar

+    //

+    InitializeP2C (PciDevice);

+  }

+    

+  //

+  // Remove the device

+  //

+  Bridge      = PciDevice->Parent;

+  CurrentLink = Bridge->ChildList.ForwardLink;

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    if (Temp == PciDevice) {

+      InitializePciDevice (Temp);

+      RemoveEntryList (CurrentLink);

+      FreePciDevice (Temp);

+      return EFI_SUCCESS;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_ABORTED;

+}

+

+BOOLEAN

+IsRejectiveDevice (

+  IN  PCI_RESOURCE_NODE   *PciResNode

+  )

+/*++

+

+Routine Description:

+  

+    Determine whethter a PCI device can be rejected

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResNode - add argument and description to function comment

+{

+  PCI_IO_DEVICE *Temp;

+

+  Temp = PciResNode->PciDev;

+

+  //

+  // Ensure the device is present

+  //

+  if (!Temp) {

+    return FALSE;

+  }

+    

+  //

+  // PPB and RB should go ahead

+  //

+  if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {

+    return TRUE;

+  }

+

+  //

+  // Skip device on Bus0

+  //

+  if ((Temp->Parent) && (Temp->BusNumber == 0)) {

+    return FALSE;

+  }

+  

+  //

+  // Skip VGA

+  //

+  if (IS_PCI_VGA (&Temp->Pci)) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+PCI_RESOURCE_NODE *

+GetLargerConsumerDevice (

+  IN  PCI_RESOURCE_NODE   *PciResNode1,

+  IN  PCI_RESOURCE_NODE   *PciResNode2

+  )

+/*++

+

+Routine Description:

+  

+    Get the larger resource consumer

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResNode1 - add argument and description to function comment

+// TODO:    PciResNode2 - add argument and description to function comment

+{

+  if (!PciResNode2) {

+    return PciResNode1;

+  }

+

+  if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \

+       && (PciResNode2->ResourceUsage != PciResUsagePadding) )

+  {

+    return PciResNode1;

+  }

+

+  if (!PciResNode1) {

+    return PciResNode2;

+  }

+

+  if ((PciResNode1->Length) > (PciResNode2->Length)) {

+    return PciResNode1;

+  }

+

+  return PciResNode2;

+

+}

+

+PCI_RESOURCE_NODE *

+GetMaxResourceConsumerDevice (

+  IN  PCI_RESOURCE_NODE   *ResPool

+  )

+/*++

+

+Routine Description:

+  

+    Get the max resource consumer in the host resource pool 

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    ResPool - add argument and description to function comment

+{

+  PCI_RESOURCE_NODE *Temp;

+  LIST_ENTRY        *CurrentLink;

+  PCI_RESOURCE_NODE *PciResNode;

+  PCI_RESOURCE_NODE *PPBResNode;

+

+  PciResNode  = NULL;

+

+  CurrentLink = ResPool->ChildList.ForwardLink;

+  while (CurrentLink && CurrentLink != &ResPool->ChildList) {

+

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (!IsRejectiveDevice (Temp)) {

+      CurrentLink = CurrentLink->ForwardLink;

+      continue;

+    }

+

+    if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \

+          && (Temp->ResourceUsage != PciResUsagePadding))

+    {

+      PPBResNode  = GetMaxResourceConsumerDevice (Temp);

+      PciResNode  = GetLargerConsumerDevice (PciResNode, PPBResNode);

+    } else {

+      PciResNode = GetLargerConsumerDevice (PciResNode, Temp);

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return PciResNode;

+}

+

+EFI_STATUS

+PciHostBridgeAdjustAllocation (

+  IN  PCI_RESOURCE_NODE   *IoPool,

+  IN  PCI_RESOURCE_NODE   *Mem32Pool,

+  IN  PCI_RESOURCE_NODE   *PMem32Pool,

+  IN  PCI_RESOURCE_NODE   *Mem64Pool,

+  IN  PCI_RESOURCE_NODE   *PMem64Pool,

+  IN  UINT64              IoResStatus,

+  IN  UINT64              Mem32ResStatus,

+  IN  UINT64              PMem32ResStatus,

+  IN  UINT64              Mem64ResStatus,

+  IN  UINT64              PMem64ResStatus

+  )

+/*++

+

+Routine Description:

+  

+    Adjust host bridge allocation so as to reduce resource requirement

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    IoPool - add argument and description to function comment

+// TODO:    Mem32Pool - add argument and description to function comment

+// TODO:    PMem32Pool - add argument and description to function comment

+// TODO:    Mem64Pool - add argument and description to function comment

+// TODO:    PMem64Pool - add argument and description to function comment

+// TODO:    IoResStatus - add argument and description to function comment

+// TODO:    Mem32ResStatus - add argument and description to function comment

+// TODO:    PMem32ResStatus - add argument and description to function comment

+// TODO:    Mem64ResStatus - add argument and description to function comment

+// TODO:    PMem64ResStatus - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+{

+  BOOLEAN                               AllocationAjusted;

+  PCI_RESOURCE_NODE                     *PciResNode;

+  PCI_RESOURCE_NODE                     *ResPool[5];

+  PCI_IO_DEVICE                         *RemovedPciDev[5];

+  UINT64                                ResStatus[5];

+  UINTN                                 RemovedPciDevNum;

+  UINTN                                 DevIndex;

+  UINTN                                 ResType;

+  EFI_STATUS                            Status;

+  REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;

+

+  PciResNode = NULL;

+  ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));

+  RemovedPciDevNum  = 0;

+

+  ResPool[0]        = IoPool;

+  ResPool[1]        = Mem32Pool;

+  ResPool[2]        = PMem32Pool;

+  ResPool[3]        = Mem64Pool;

+  ResPool[4]        = PMem64Pool;

+

+  ResStatus[0]      = IoResStatus;

+  ResStatus[1]      = Mem32ResStatus;

+  ResStatus[2]      = PMem32ResStatus;

+  ResStatus[3]      = Mem64ResStatus;

+  ResStatus[4]      = PMem64ResStatus;

+

+  AllocationAjusted = FALSE;

+

+  for (ResType = 0; ResType < 5; ResType++) {

+

+    if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {

+      continue;

+    }

+

+    if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {

+      //

+      // Hostbridge hasn't this resource type

+      //

+      return EFI_ABORTED;

+    }

+    

+    //

+    // Hostbridge hasn't enough resource

+    //

+    PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);

+    if (!PciResNode) {

+      continue;

+    }

+    

+    //

+    // Check if the device has been removed before

+    //

+    for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {

+      if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {

+        continue;

+      }

+    }

+    

+    //

+    // Remove the device if it isn't in the array

+    //

+    Status = RejectPciDevice (PciResNode->PciDev);

+    if (Status == EFI_SUCCESS) {

+      

+      //

+      // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code

+      //

+      //

+      // Have no way to get ReqRes, AllocRes & Bar here

+      //

+      ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));

+      AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);

+      AllocFailExtendedData.DevicePath     = (UINT8 *) PciResNode->PciDev->DevicePath;

+      AllocFailExtendedData.Bar            = PciResNode->Bar;

+

+      REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+            EFI_PROGRESS_CODE,

+            EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,

+            (VOID *) &AllocFailExtendedData,

+            sizeof (AllocFailExtendedData)

+            );

+

+      //

+      // Add it to the array and indicate at least a device has been rejected

+      //

+      RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;

+      AllocationAjusted                 = TRUE;

+    }

+  }

+  //

+  // End for

+  //

+

+  if (AllocationAjusted) {

+    return EFI_SUCCESS;

+  } else {

+    return EFI_ABORTED;

+  }

+}

+

+EFI_STATUS

+ConstructAcpiResourceRequestor (

+  IN PCI_IO_DEVICE      *Bridge,

+  IN PCI_RESOURCE_NODE  *IoNode,

+  IN PCI_RESOURCE_NODE  *Mem32Node,

+  IN PCI_RESOURCE_NODE  *PMem32Node,

+  IN PCI_RESOURCE_NODE  *Mem64Node,

+  IN PCI_RESOURCE_NODE  *PMem64Node,

+  OUT VOID              **pConfig

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    IoNode - add argument and description to function comment

+// TODO:    Mem32Node - add argument and description to function comment

+// TODO:    PMem32Node - add argument and description to function comment

+// TODO:    Mem64Node - add argument and description to function comment

+// TODO:    PMem64Node - add argument and description to function comment

+// TODO:    pConfig - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT8                             NumConfig;

+  UINT8                             Aperture;

+  UINT8                             *Configuration;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;

+  EFI_ACPI_END_TAG_DESCRIPTOR       *PtrEnd;

+

+  NumConfig = 0;

+  Aperture  = 0;

+

+  *pConfig  = NULL;

+

+  //

+  // if there is io request, add to the io aperture

+  //

+  if (ResourceRequestExisted (IoNode)) {

+    NumConfig++;

+    Aperture |= 0x01;

+  }

+

+  //

+  // if there is mem32 request, add to the mem32 aperture

+  //

+  if (ResourceRequestExisted (Mem32Node)) {

+    NumConfig++;

+    Aperture |= 0x02;

+  }

+

+  //

+  // if there is pmem32 request, add to the pmem32 aperture

+  //

+  if (ResourceRequestExisted (PMem32Node)) {

+    NumConfig++;

+    Aperture |= 0x04;

+  }

+

+  //

+  // if there is mem64 request, add to the mem64 aperture

+  //

+  if (ResourceRequestExisted (Mem64Node)) {

+    NumConfig++;

+    Aperture |= 0x08;

+  }

+

+  //

+  // if there is pmem64 request, add to the pmem64 aperture

+  //

+  if (ResourceRequestExisted (PMem64Node)) {

+    NumConfig++;

+    Aperture |= 0x10;

+  }

+

+  if (NumConfig != 0) {

+

+    //

+    // If there is at least one type of resource request,

+    // allocate a acpi resource node

+    //

+    Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));

+    if (Configuration == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    ZeroMem (

+      Configuration,

+      sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)

+      );

+

+    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;

+

+    //

+    // Deal with io aperture

+    //

+    if (Aperture & 0x01) {

+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;

+      //

+      // Io

+      //

+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_IO;

+      //

+      // non ISA range

+      //

+      Ptr->SpecificFlag = 1;

+      Ptr->AddrLen      = IoNode->Length;

+      Ptr->AddrRangeMax = IoNode->Alignment;

+

+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    }

+    //

+    // Deal with mem32 aperture

+    //

+    if (Aperture & 0x02) {

+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;

+      //

+      // Mem

+      //

+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;

+      //

+      // Nonprefechable

+      //

+      Ptr->SpecificFlag = 0;

+      //

+      // 32 bit

+      //

+      Ptr->AddrSpaceGranularity = 32;

+      Ptr->AddrLen      = Mem32Node->Length;

+      Ptr->AddrRangeMax = Mem32Node->Alignment;

+

+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    }

+

+    //

+    // Deal with Pmem32 aperture

+    //

+    if (Aperture & 0x04) {

+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;

+      //

+      // Mem

+      //

+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;

+      //

+      // prefechable

+      //

+      Ptr->SpecificFlag = 0x6;

+      //

+      // 32 bit

+      //

+      Ptr->AddrSpaceGranularity = 32;

+      Ptr->AddrLen      = PMem32Node->Length;

+      Ptr->AddrRangeMax = PMem32Node->Alignment;

+

+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    }

+    //

+    // Deal with mem64 aperture

+    //

+    if (Aperture & 0x08) {

+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;

+      //

+      // Mem

+      //

+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;

+      //

+      // nonprefechable

+      //

+      Ptr->SpecificFlag = 0;

+      //

+      // 64 bit

+      //

+      Ptr->AddrSpaceGranularity = 64;

+      Ptr->AddrLen      = Mem64Node->Length;

+      Ptr->AddrRangeMax = Mem64Node->Alignment;

+

+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    }

+    //

+    // Deal with Pmem64 aperture

+    //

+    if (Aperture & 0x10) {

+      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;

+      //

+      // Mem

+      //

+      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;

+      //

+      // prefechable

+      //

+      Ptr->SpecificFlag = 0x06;

+      //

+      // 64 bit

+      //

+      Ptr->AddrSpaceGranularity = 64;

+      Ptr->AddrLen      = PMem64Node->Length;

+      Ptr->AddrRangeMax = PMem64Node->Alignment;

+

+      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    }

+

+    //

+    // put the checksum

+    //

+    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);

+

+    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;

+    PtrEnd->Checksum  = 0;

+

+  } else {

+

+    //

+    // If there is no resource request

+    //

+    Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));

+    if (Configuration == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));

+

+    Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);

+    Ptr->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+

+    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;

+    PtrEnd->Checksum  = 0;

+  }

+

+  *pConfig = Configuration;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetResourceBase (

+  IN VOID     *pConfig,

+  OUT UINT64  *IoBase,

+  OUT UINT64  *Mem32Base,

+  OUT UINT64  *PMem32Base,

+  OUT UINT64  *Mem64Base,

+  OUT UINT64  *PMem64Base

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    pConfig - add argument and description to function comment

+// TODO:    IoBase - add argument and description to function comment

+// TODO:    Mem32Base - add argument and description to function comment

+// TODO:    PMem32Base - add argument and description to function comment

+// TODO:    Mem64Base - add argument and description to function comment

+// TODO:    PMem64Base - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT8                             *Temp;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;

+  UINT64                            ResStatus;

+

+  *IoBase     = 0xFFFFFFFFFFFFFFFFULL;

+  *Mem32Base  = 0xFFFFFFFFFFFFFFFFULL;

+  *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;

+  *Mem64Base  = 0xFFFFFFFFFFFFFFFFULL;

+  *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;

+

+  Temp        = (UINT8 *) pConfig;

+

+  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {

+

+    Ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;

+    ResStatus = Ptr->AddrTranslationOffset;

+

+    if (ResStatus == EFI_RESOURCE_SATISFIED) {

+

+      switch (Ptr->ResType) {

+

+      //

+      // Memory type aperture

+      //

+      case 0:

+  

+        //

+        // Check to see the granularity

+        //

+        if (Ptr->AddrSpaceGranularity == 32) {

+          if (Ptr->SpecificFlag & 0x06) {

+            *PMem32Base = Ptr->AddrRangeMin;

+          } else {

+            *Mem32Base = Ptr->AddrRangeMin;

+          }

+        }

+

+        if (Ptr->AddrSpaceGranularity == 64) {

+          if (Ptr->SpecificFlag & 0x06) {

+            *PMem64Base = Ptr->AddrRangeMin;

+          } else {

+            *Mem64Base = Ptr->AddrRangeMin;

+          }

+        }

+        break;

+

+      case 1:

+

+        //

+        // Io type aperture

+        //

+        *IoBase = Ptr->AddrRangeMin;

+        break;

+

+      default:

+        break;

+

+      }

+      //

+      // End switch

+      //

+    }

+    //

+    // End for

+    //

+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciBridgeEnumerator (

+  IN PCI_IO_DEVICE                                     *BridgeDev

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    BridgeDev - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT8               SubBusNumber;

+  UINT8               StartBusNumber;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  EFI_STATUS          Status;

+

+  SubBusNumber    = 0;

+  StartBusNumber  = 0;

+  PciIo           = &(BridgeDev->PciIo);

+  Status          = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciAssignBusNumber (

+            BridgeDev,

+            StartBusNumber,

+            &SubBusNumber

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciBridgeResourceAllocator (BridgeDev);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = DetermineDeviceAttribute (BridgeDev);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+PciBridgeResourceAllocator (

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_RESOURCE_NODE *IoBridge;

+  PCI_RESOURCE_NODE *Mem32Bridge;

+  PCI_RESOURCE_NODE *PMem32Bridge;

+  PCI_RESOURCE_NODE *Mem64Bridge;

+  PCI_RESOURCE_NODE *PMem64Bridge;

+  UINT64            IoBase;

+  UINT64            Mem32Base;

+  UINT64            PMem32Base;

+  UINT64            Mem64Base;

+  UINT64            PMem64Base;

+  EFI_STATUS        Status;

+

+  IoBridge = CreateResourceNode (

+              Bridge,

+              0,

+              0xFFF,

+              0,

+              PciBarTypeIo16,

+              PciResUsageTypical

+              );

+

+  Mem32Bridge = CreateResourceNode (

+                  Bridge,

+                  0,

+                  0xFFFFF,

+                  0,

+                  PciBarTypeMem32,

+                  PciResUsageTypical

+                  );

+

+  PMem32Bridge = CreateResourceNode (

+                  Bridge,

+                  0,

+                  0xFFFFF,

+                  0,

+                  PciBarTypePMem32,

+                  PciResUsageTypical

+                  );

+

+  Mem64Bridge = CreateResourceNode (

+                  Bridge,

+                  0,

+                  0xFFFFF,

+                  0,

+                  PciBarTypeMem64,

+                  PciResUsageTypical

+                  );

+

+  PMem64Bridge = CreateResourceNode (

+                  Bridge,

+                  0,

+                  0xFFFFF,

+                  0,

+                  PciBarTypePMem64,

+                  PciResUsageTypical

+                  );

+

+  //

+  // Create resourcemap by going through all the devices subject to this root bridge

+  //

+  Status = CreateResourceMap (

+            Bridge,

+            IoBridge,

+            Mem32Bridge,

+            PMem32Bridge,

+            Mem64Bridge,

+            PMem64Bridge

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = GetResourceBaseFromBridge (

+            Bridge,

+            &IoBase,

+            &Mem32Base,

+            &PMem32Base,

+            &Mem64Base,

+            &PMem64Base

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Program IO resources

+  //

+  ProgramResource (

+    IoBase,

+    IoBridge

+    );

+

+  //

+  // Program Mem32 resources

+  //

+  ProgramResource (

+    Mem32Base,

+    Mem32Bridge

+    );

+

+  //

+  // Program PMem32 resources

+  //

+  ProgramResource (

+    PMem32Base,

+    PMem32Bridge

+    );

+

+  //

+  // Program Mem64 resources

+  //

+  ProgramResource (

+    Mem64Base,

+    Mem64Bridge

+    );

+

+  //

+  // Program PMem64 resources

+  //

+  ProgramResource (

+    PMem64Base,

+    PMem64Bridge

+    );

+

+  DestroyResourceTree (IoBridge);

+  DestroyResourceTree (Mem32Bridge);

+  DestroyResourceTree (PMem32Bridge);

+  DestroyResourceTree (PMem64Bridge);

+  DestroyResourceTree (Mem64Bridge);

+

+  gBS->FreePool (IoBridge);

+  gBS->FreePool (Mem32Bridge);

+  gBS->FreePool (PMem32Bridge);

+  gBS->FreePool (PMem64Bridge);

+  gBS->FreePool (Mem64Bridge);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetResourceBaseFromBridge (

+  IN  PCI_IO_DEVICE *Bridge,

+  OUT UINT64        *IoBase,

+  OUT UINT64        *Mem32Base,

+  OUT UINT64        *PMem32Base,

+  OUT UINT64        *Mem64Base,

+  OUT UINT64        *PMem64Base

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    IoBase - add argument and description to function comment

+// TODO:    Mem32Base - add argument and description to function comment

+// TODO:    PMem32Base - add argument and description to function comment

+// TODO:    Mem64Base - add argument and description to function comment

+// TODO:    PMem64Base - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  if (!Bridge->Allocated) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  *IoBase     = gAllOne;

+  *Mem32Base  = gAllOne;

+  *PMem32Base = gAllOne;

+  *Mem64Base  = gAllOne;

+  *PMem64Base = gAllOne;

+

+  if (IS_PCI_BRIDGE (&Bridge->Pci)) {

+

+    if (Bridge->PciBar[PPB_IO_RANGE].Length) {

+      *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;

+    }

+

+    if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {

+      *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;

+    }

+

+    if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {

+      *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;

+    }

+

+    if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {

+      *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;

+    } else {

+      *PMem64Base = gAllOne;

+    }

+

+  }

+

+  if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {

+    if (Bridge->PciBar[P2C_IO_1].Length) {

+      *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;

+    } else {

+      if (Bridge->PciBar[P2C_IO_2].Length) {

+        *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;

+      }

+    }

+

+    if (Bridge->PciBar[P2C_MEM_1].Length) {

+      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {

+        *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;

+      }

+

+      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {

+        *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;

+      }

+    }

+

+    if (Bridge->PciBar[P2C_MEM_2].Length) {

+      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {

+        *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;

+      }

+

+      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {

+        *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+NotifyPhase (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE       Phase

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    Phase - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_HANDLE                      HostBridgeHandle;

+  EFI_HANDLE                      RootBridgeHandle;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  EFI_STATUS                      Status;

+

+  HostBridgeHandle  = NULL;

+  RootBridgeHandle  = NULL;

+  if (gPciPlatformProtocol != NULL) {

+    //

+    // Get Host Bridge Handle.

+    //

+    PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);

+

+    //

+    // Get the rootbridge Io protocol to find the host bridge handle

+    //

+    Status = gBS->HandleProtocol (

+                    RootBridgeHandle,

+                    &gEfiPciRootBridgeIoProtocolGuid,

+                    (VOID **) &PciRootBridgeIo

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return EFI_NOT_FOUND;

+    }

+

+    HostBridgeHandle = PciRootBridgeIo->ParentHandle;

+

+    //

+    // Call PlatformPci::PhaseNotify() if the protocol is present.

+    //

+    gPciPlatformProtocol->PhaseNotify (

+                            gPciPlatformProtocol,

+                            HostBridgeHandle,

+                            Phase,

+                            ChipsetEntry

+                            );

+  }

+

+  Status = PciResAlloc->NotifyPhase (

+                          PciResAlloc,

+                          Phase

+                          );

+

+  if (gPciPlatformProtocol != NULL) {

+    //

+    // Call PlatformPci::PhaseNotify() if the protocol is present.

+    //

+    gPciPlatformProtocol->PhaseNotify (

+                            gPciPlatformProtocol,

+                            HostBridgeHandle,

+                            Phase,

+                            ChipsetExit

+                            );

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PreprocessController (

+  IN PCI_IO_DEVICE                                    *Bridge,

+  IN UINT8                                            Bus,

+  IN UINT8                                            Device,

+  IN UINT8                                            Func,

+  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Func - add argument and description to function comment

+// TODO:    Phase - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       RootBridgePciAddress;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;

+  EFI_HANDLE                                        RootBridgeHandle;

+  EFI_HANDLE                                        HostBridgeHandle;

+  EFI_STATUS                                        Status;

+

+  //

+  // Get the host bridge handle

+  //

+  HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;

+

+  //

+  // Get the pci host bridge resource allocation protocol

+  //

+  Status = gBS->OpenProtocol (

+                  HostBridgeHandle,

+                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,

+                  (VOID **) &PciResAlloc,

+                  NULL,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get Root Brige Handle

+  //

+  while (Bridge->Parent) {

+    Bridge = Bridge->Parent;

+  }

+

+  RootBridgeHandle                      = Bridge->Handle;

+

+  RootBridgePciAddress.Register         = 0;

+  RootBridgePciAddress.Function         = Func;

+  RootBridgePciAddress.Device           = Device;

+  RootBridgePciAddress.Bus              = Bus;

+  RootBridgePciAddress.ExtendedRegister = 0;

+

+  if (gPciPlatformProtocol != NULL) {

+    //

+    // Call PlatformPci::PrepController() if the protocol is present.

+    //

+    gPciPlatformProtocol->PlatformPrepController (

+                            gPciPlatformProtocol,

+                            HostBridgeHandle,

+                            RootBridgeHandle,

+                            RootBridgePciAddress,

+                            Phase,

+                            ChipsetEntry

+                            );

+  }

+

+  Status = PciResAlloc->PreprocessController (

+                          PciResAlloc,

+                          RootBridgeHandle,

+                          RootBridgePciAddress,

+                          Phase

+                          );

+

+  if (gPciPlatformProtocol != NULL) {

+    //

+    // Call PlatformPci::PrepController() if the protocol is present.

+    //

+    gPciPlatformProtocol->PlatformPrepController (

+                            gPciPlatformProtocol,

+                            HostBridgeHandle,

+                            RootBridgeHandle,

+                            RootBridgePciAddress,

+                            Phase,

+                            ChipsetExit

+                            );

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PciHotPlugRequestNotify (

+  IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,

+  IN EFI_PCI_HOTPLUG_OPERATION        Operation,

+  IN EFI_HANDLE                       Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL         * RemainingDevicePath OPTIONAL,

+  IN OUT UINT8                        *NumberOfChildren,

+  IN OUT EFI_HANDLE                   * ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  Hot plug request notify.

+  

+Arguments:

+

+  This                 - A pointer to the hot plug request protocol.

+  Operation            - The operation.

+  Controller           - A pointer to the controller.

+  RemainningDevicePath - A pointer to the device path.

+  NumberOfChildren     - A the number of child handle in the ChildHandleBuffer.

+  ChildHandleBuffer    - A pointer to the array contain the child handle.

+

+Returns:

+

+  Status code.

+

+--*/

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE       *Bridge;

+  PCI_IO_DEVICE       *Temp;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINTN               Index;

+  EFI_HANDLE          RootBridgeHandle;

+  EFI_STATUS          Status;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);

+

+  //

+  // Get root bridge handle

+  //

+  Temp = Bridge;

+  while (Temp->Parent) {

+    Temp = Temp->Parent;

+  }

+

+  RootBridgeHandle = Temp->Handle;

+

+  if (Operation == EfiPciHotPlugRequestAdd) {

+

+    if (NumberOfChildren != NULL) {

+      *NumberOfChildren = 0;

+    }

+

+    if (IsListEmpty (&Bridge->ChildList)) {

+

+      Status = PciBridgeEnumerator (Bridge);

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    }

+

+    Status = StartPciDevicesOnBridge (

+              RootBridgeHandle,

+              Bridge,

+              RemainingDevicePath,

+              NumberOfChildren,

+              ChildHandleBuffer

+              );

+

+    return EFI_SUCCESS;

+  }

+

+  if (Operation == EfiPciHotplugRequestRemove) {

+

+    if (*NumberOfChildren == 0) {

+      //

+      // Remove all devices on the bridge

+      //

+      Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);

+      return Status;

+

+    }

+

+    for (Index = 0; Index < *NumberOfChildren; Index++) {

+      //

+      // De register all the pci device

+      //

+      Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+    }

+    //

+    // End for

+    //

+    return EFI_SUCCESS;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+SearchHostBridgeHandle (

+  IN EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    RootBridgeHandle - add argument and description to function comment

+{

+  EFI_HANDLE                      HostBridgeHandle;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  UINTN                           Index;

+  EFI_STATUS                      Status;

+

+  //

+  // Get the rootbridge Io protocol to find the host bridge handle

+  //

+  Status = gBS->OpenProtocol (

+                  RootBridgeHandle,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &PciRootBridgeIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  RootBridgeHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  HostBridgeHandle = PciRootBridgeIo->ParentHandle;

+  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {

+    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+AddHostBridgeEnumerator (

+  IN EFI_HANDLE HostBridgeHandle

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    HostBridgeHandle - add argument and description to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_ABORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINTN Index;

+

+  if (!HostBridgeHandle) {

+    return EFI_ABORTED;

+  }

+

+  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {

+    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {

+      return EFI_ABORTED;

+    }

+  }

+

+  if (Index < PCI_MAX_HOST_BRIDGE_NUM) {

+    gPciHostBrigeHandles[Index] = HostBridgeHandle;

+    gPciHostBridgeNumber++;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h
new file mode 100644
index 0000000..e7667d5
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumerator.h
@@ -0,0 +1,628 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciEnumerator.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_ENUMERATOR_H

+#define _EFI_PCI_ENUMERATOR_H

+

+#include "PciResourceSupport.h"

+

+EFI_STATUS

+PciEnumerator (

+  IN EFI_HANDLE                    Controller

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciRootBridgeEnumerator (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc,

+  IN PCI_IO_DEVICE                                     *RootBridgeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc   - TODO: add argument description

+  RootBridgeDev - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProcessOptionRom (

+  IN PCI_IO_DEVICE *Bridge,

+  IN UINT64        RomBase,

+  IN UINT64        MaxLength

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge    - TODO: add argument description

+  RomBase   - TODO: add argument description

+  MaxLength - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciAssignBusNumber (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber,

+  OUT UINT8                             *SubBusNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge          - TODO: add argument description

+  StartBusNumber  - TODO: add argument description

+  SubBusNumber    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DetermineRootBridgeAttributes (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,

+  IN PCI_IO_DEVICE                                    *RootBridgeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc   - TODO: add argument description

+  RootBridgeDev - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+UINT64

+GetMaxOptionRomSize (

+  IN PCI_IO_DEVICE   *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciHostBridgeDeviceAttribute (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetResourceAllocationStatus (

+  VOID        *AcpiConfig,

+  OUT UINT64  *IoResStatus,

+  OUT UINT64  *Mem32ResStatus,

+  OUT UINT64  *PMem32ResStatus,

+  OUT UINT64  *Mem64ResStatus,

+  OUT UINT64  *PMem64ResStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AcpiConfig      - TODO: add argument description

+  IoResStatus     - TODO: add argument description

+  Mem32ResStatus  - TODO: add argument description

+  PMem32ResStatus - TODO: add argument description

+  Mem64ResStatus  - TODO: add argument description

+  PMem64ResStatus - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RejectPciDevice (

+  IN PCI_IO_DEVICE       *PciDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsRejectiveDevice (

+  IN  PCI_RESOURCE_NODE   *PciResNode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResNode  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_RESOURCE_NODE *

+GetLargerConsumerDevice (

+  IN  PCI_RESOURCE_NODE   *PciResNode1,

+  IN  PCI_RESOURCE_NODE   *PciResNode2

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResNode1 - TODO: add argument description

+  PciResNode2 - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_RESOURCE_NODE *

+GetMaxResourceConsumerDevice (

+  IN  PCI_RESOURCE_NODE   *ResPool

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ResPool - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciHostBridgeAdjustAllocation (

+  IN  PCI_RESOURCE_NODE   *IoPool,

+  IN  PCI_RESOURCE_NODE   *Mem32Pool,

+  IN  PCI_RESOURCE_NODE   *PMem32Pool,

+  IN  PCI_RESOURCE_NODE   *Mem64Pool,

+  IN  PCI_RESOURCE_NODE   *PMem64Pool,

+  IN  UINT64              IoResStatus,

+  IN  UINT64              Mem32ResStatus,

+  IN  UINT64              PMem32ResStatus,

+  IN  UINT64              Mem64ResStatus,

+  IN  UINT64              PMem64ResStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  IoPool          - TODO: add argument description

+  Mem32Pool       - TODO: add argument description

+  PMem32Pool      - TODO: add argument description

+  Mem64Pool       - TODO: add argument description

+  PMem64Pool      - TODO: add argument description

+  IoResStatus     - TODO: add argument description

+  Mem32ResStatus  - TODO: add argument description

+  PMem32ResStatus - TODO: add argument description

+  Mem64ResStatus  - TODO: add argument description

+  PMem64ResStatus - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ConstructAcpiResourceRequestor (

+  IN PCI_IO_DEVICE      *Bridge,

+  IN PCI_RESOURCE_NODE  *IoNode,

+  IN PCI_RESOURCE_NODE  *Mem32Node,

+  IN PCI_RESOURCE_NODE  *PMem32Node,

+  IN PCI_RESOURCE_NODE  *Mem64Node,

+  IN PCI_RESOURCE_NODE  *PMem64Node,

+  OUT VOID              **pConfig

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge      - TODO: add argument description

+  IoNode      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+  pConfig     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetResourceBase (

+  IN VOID     *pConfig,

+  OUT UINT64  *IoBase,

+  OUT UINT64  *Mem32Base,

+  OUT UINT64  *PMem32Base,

+  OUT UINT64  *Mem64Base,

+  OUT UINT64  *PMem64Base

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  pConfig     - TODO: add argument description

+  IoBase      - TODO: add argument description

+  Mem32Base   - TODO: add argument description

+  PMem32Base  - TODO: add argument description

+  Mem64Base   - TODO: add argument description

+  PMem64Base  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciBridgeEnumerator (

+  IN PCI_IO_DEVICE                                     *BridgeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  BridgeDev - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciBridgeResourceAllocator (

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetResourceBaseFromBridge (

+  IN  PCI_IO_DEVICE *Bridge,

+  OUT UINT64        *IoBase,

+  OUT UINT64        *Mem32Base,

+  OUT UINT64        *PMem32Base,

+  OUT UINT64        *Mem64Base,

+  OUT UINT64        *PMem64Base

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge      - TODO: add argument description

+  IoBase      - TODO: add argument description

+  Mem32Base   - TODO: add argument description

+  PMem32Base  - TODO: add argument description

+  Mem64Base   - TODO: add argument description

+  PMem64Base  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciHostBridgeP2CProcess (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+NotifyPhase (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE       Phase

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc - TODO: add argument description

+  Phase       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PreprocessController (

+  IN PCI_IO_DEVICE                                  *Bridge,

+  IN UINT8                                          Bus,

+  IN UINT8                                          Device,

+  IN UINT8                                          Func,

+  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  Bus     - TODO: add argument description

+  Device  - TODO: add argument description

+  Func    - TODO: add argument description

+  Phase   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciHotPlugRequestNotify (

+  IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,

+  IN EFI_PCI_HOTPLUG_OPERATION        Operation,

+  IN EFI_HANDLE                       Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL         * RemainingDevicePath OPTIONAL,

+  IN OUT UINT8                        *NumberOfChildren,

+  IN OUT EFI_HANDLE                   * ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Operation           - TODO: add argument description

+  Controller          - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+  NumberOfChildren    - TODO: add argument description

+  ChildHandleBuffer   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+SearchHostBridgeHandle (

+  IN EFI_HANDLE RootBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AddHostBridgeEnumerator (

+  IN EFI_HANDLE HostBridgeHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  HostBridgeHandle  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c
new file mode 100644
index 0000000..80bc7d4
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c
@@ -0,0 +1,2261 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciEnumeratorSupport.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciEnumeratorSupport.h"

+#include "PciCommand.h"

+#include "PciIo.h"

+

+EFI_STATUS

+PciDevicePresent (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  PCI_TYPE00                          *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to check whether the pci device is present

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciRootBridgeIo - add argument and description to function comment

+// TODO:    Pci - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Func - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  UINT64      Address;

+  EFI_STATUS  Status;

+

+  //

+  // Create PCI address map in terms of Bus, Device and Func

+  //

+  Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);

+

+  //

+  // Read the Vendor Id register

+  //

+  Status = PciRootBridgeIo->Pci.Read (

+                                  PciRootBridgeIo,

+                                  EfiPciWidthUint32,

+                                  Address,

+                                  1,

+                                  Pci

+                                  );

+

+  if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {

+

+    //

+    // Read the entire config header for the device

+    //

+

+    Status = PciRootBridgeIo->Pci.Read (

+                                    PciRootBridgeIo,

+                                    EfiPciWidthUint32,

+                                    Address,

+                                    sizeof (PCI_TYPE00) / sizeof (UINT32),

+                                    Pci

+                                    );

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+PciPciDeviceInfoCollector (

+  IN PCI_IO_DEVICE                      *Bridge,

+  UINT8                                 StartBusNumber

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    StartBusNumber - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS          Status;

+  PCI_TYPE00          Pci;

+  UINT8               Device;

+  UINT8               Func;

+  UINT8               SecBus;

+  PCI_IO_DEVICE       *PciIoDevice;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  Status  = EFI_SUCCESS;

+  SecBus  = 0;

+

+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {

+

+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {

+

+      //

+      // Check to see whether PCI device is present

+      //

+

+      Status = PciDevicePresent (

+                Bridge->PciRootBridgeIo,

+                &Pci,

+                (UINT8) StartBusNumber,

+                (UINT8) Device,

+                (UINT8) Func

+                );

+

+      if (!EFI_ERROR (Status)) {

+

+        //

+        // Call back to host bridge function

+        //

+        PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);

+

+        //

+        // Collect all the information about the PCI device discovered

+        //

+        Status = PciSearchDevice (

+                  Bridge,

+                  &Pci,

+                  (UINT8) StartBusNumber,

+                  Device,

+                  Func,

+                  &PciIoDevice

+                  );

+

+        //

+        // Recursively scan PCI busses on the other side of PCI-PCI bridges

+        //

+        //

+

+        if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {

+

+          //

+          // If it is PPB, we need to get the secondary bus to continue the enumeration

+          //

+          PciIo   = &(PciIoDevice->PciIo);

+

+          Status  = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);

+

+          if (EFI_ERROR (Status)) {

+            return Status;

+          }

+              

+          //

+          // Get resource padding for PPB

+          //

+          GetResourcePaddingPpb (PciIoDevice);

+

+          //

+          // Deep enumerate the next level bus

+          //

+          Status = PciPciDeviceInfoCollector (

+                    PciIoDevice,

+                    (UINT8) (SecBus)

+                    );

+

+        }

+

+        if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {

+

+          //

+          // Skip sub functions, this is not a multi function device

+          //

+          Func = PCI_MAX_FUNC;

+        }

+      }

+

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciSearchDevice (

+  IN  PCI_IO_DEVICE                         *Bridge,

+  IN  PCI_TYPE00                            *Pci,

+  IN  UINT8                                 Bus,

+  IN  UINT8                                 Device,

+  IN  UINT8                                 Func,

+  OUT PCI_IO_DEVICE                         **PciDevice

+  )

+/*++

+

+Routine Description:

+

+  Search required device.

+

+Arguments:

+

+  Bridge     - A pointer to the PCI_IO_DEVICE.

+  Pci        - A pointer to the PCI_TYPE00.

+  Bus        - Bus number.

+  Device     - Device number.

+  Func       - Function number.

+  PciDevice  - The Required pci device.

+

+Returns:

+

+  Status code.

+

+--*/

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = NULL;

+

+  if (!IS_PCI_BRIDGE (Pci)) {

+

+    if (IS_CARDBUS_BRIDGE (Pci)) {

+      PciIoDevice = GatherP2CInfo (

+                      Bridge,

+                      Pci,

+                      Bus,

+                      Device,

+                      Func

+                      );

+      if (gFullEnumeration) {

+        InitializeP2C (PciIoDevice);

+      }

+    } else {

+

+      //

+      // Create private data for Pci Device

+      //

+      PciIoDevice = GatherDeviceInfo (

+                      Bridge,

+                      Pci,

+                      Bus,

+                      Device,

+                      Func

+                      );

+

+    }

+

+  } else {

+

+    //

+    // Create private data for PPB

+    //

+    PciIoDevice = GatherPpbInfo (

+                    Bridge,

+                    Pci,

+                    Bus,

+                    Device,

+                    Func

+                    );

+

+    //

+    // Special initialization for PPB including making the PPB quiet

+    //

+    if (gFullEnumeration) {

+      InitializePpb (PciIoDevice);

+    }

+  }

+

+  if (!PciIoDevice) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Update the bar information for this PCI device so as to support some specific device

+  //

+  UpdatePciInfo (PciIoDevice);

+

+  if (PciIoDevice->DevicePath == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Detect this function has option rom

+  //

+  if (gFullEnumeration) {

+

+    if (!IS_CARDBUS_BRIDGE (Pci)) {

+

+      GetOpRomInfo (PciIoDevice);

+

+    }

+

+    ResetPowerManagementFeature (PciIoDevice);

+

+  }

+ 

+  //

+  // Insert it into a global tree for future reference

+  //

+  InsertPciDevice (Bridge, PciIoDevice);

+

+  //

+  // Determine PCI device attributes

+  //

+

+  if (PciDevice != NULL) {

+    *PciDevice = PciIoDevice;

+  }

+

+  return EFI_SUCCESS;

+}

+

+PCI_IO_DEVICE *

+GatherDeviceInfo (

+  IN PCI_IO_DEVICE                    *Bridge,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    Pci - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Func - add argument and description to function comment

+{

+  UINTN                           Offset;

+  UINTN                           BarIndex;

+  PCI_IO_DEVICE                   *PciIoDevice;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+  PciIoDevice = CreatePciIoDevice (

+                  PciRootBridgeIo,

+                  Pci,

+                  Bus,

+                  Device,

+                  Func

+                  );

+

+  if (!PciIoDevice) {

+    return NULL;

+  }

+

+  //

+  // Create a device path for this PCI device and store it into its private data

+  //

+  CreatePciDevicePath (

+    Bridge->DevicePath,

+    PciIoDevice

+    );

+

+  //

+  // If it is a full enumeration, disconnect the device in advance

+  //

+  if (gFullEnumeration) {

+

+    PciSetCommandRegister (PciIoDevice, 0);

+

+  }

+

+  //

+  // Start to parse the bars

+  //

+  for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {

+    Offset = PciParseBar (PciIoDevice, Offset, BarIndex);

+  }

+

+  return PciIoDevice;

+}

+

+PCI_IO_DEVICE *

+GatherPpbInfo (

+  IN PCI_IO_DEVICE                    *Bridge,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    Pci - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Func - add argument and description to function comment

+{

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  PCI_IO_DEVICE                   *PciIoDevice;

+  EFI_STATUS                      Status;

+  UINT32                          Value;

+  EFI_PCI_IO_PROTOCOL             *PciIo;

+  UINT8                           Temp;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+  PciIoDevice = CreatePciIoDevice (

+                  PciRootBridgeIo,

+                  Pci,

+                  Bus,

+                  Device,

+                  Func

+                  );

+

+  if (!PciIoDevice) {

+    return NULL;

+  }

+  

+  //

+  // Create a device path for this PCI device and store it into its private data

+  //

+  CreatePciDevicePath (

+    Bridge->DevicePath,

+    PciIoDevice

+    );

+

+  if (gFullEnumeration) {

+    PciSetCommandRegister (PciIoDevice, 0);

+

+    //

+    // Initalize the bridge control register

+    //

+    PciSetBridgeControlRegister (PciIoDevice, 0);

+

+  }

+

+  //

+  // PPB can have two BARs

+  //

+  if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) {

+    //

+    // Not 64-bit bar

+    //

+    PciParseBar (PciIoDevice, 0x14, PPB_BAR_1);

+  }

+

+  PciIo = &PciIoDevice->PciIo;

+

+  //

+  // Test whether it support 32 decode or not

+  //

+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);

+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);

+

+  if (Value) {

+    if (Value & 0x01) {

+      PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;

+    } else {

+      PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;

+    }

+  }

+

+  Status = BarExisted (

+            PciIoDevice,

+            0x24,

+            NULL,

+            NULL

+            );

+

+  //

+  // test if it supports 64 memory or not

+  //

+  if (!EFI_ERROR (Status)) {

+

+    Status = BarExisted (

+              PciIoDevice,

+              0x28,

+              NULL,

+              NULL

+              );

+

+    if (!EFI_ERROR (Status)) {

+      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;

+      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;

+    } else {

+      PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;

+    }

+  }

+

+  //

+  // Memory 32 code is required for ppb

+  //

+  PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;

+

+  GetResourcePaddingPpb (PciIoDevice);

+

+  return PciIoDevice;

+}

+

+PCI_IO_DEVICE *

+GatherP2CInfo (

+  IN PCI_IO_DEVICE                    *Bridge,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    Pci - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Func - add argument and description to function comment

+{

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  PCI_IO_DEVICE                   *PciIoDevice;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+  PciIoDevice = CreatePciIoDevice (

+                  PciRootBridgeIo,

+                  Pci,

+                  Bus,

+                  Device,

+                  Func

+                  );

+

+  if (!PciIoDevice) {

+    return NULL;

+  }

+

+  //

+  // Create a device path for this PCI device and store it into its private data

+  //

+  CreatePciDevicePath (

+    Bridge->DevicePath,

+    PciIoDevice

+    );

+

+  if (gFullEnumeration) {

+    PciSetCommandRegister (PciIoDevice, 0);

+

+    //

+    // Initalize the bridge control register

+    //

+    PciSetBridgeControlRegister (PciIoDevice, 0);

+

+  }

+  //

+  // P2C only has one bar that is in 0x10

+  //

+  PciParseBar (PciIoDevice, 0x10, P2C_BAR_0);

+

+  //

+  // Read PciBar information from the bar register

+  //

+  GetBackPcCardBar (PciIoDevice);

+  PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED  |

+                         EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |

+                         EFI_BRIDGE_IO32_DECODE_SUPPORTED;

+

+  return PciIoDevice;

+}

+

+EFI_DEVICE_PATH_PROTOCOL *

+CreatePciDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,

+  IN  PCI_IO_DEVICE            *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    ParentDevicePath - add argument and description to function comment

+// TODO:    PciIoDevice - add argument and description to function comment

+{

+

+  PCI_DEVICE_PATH PciNode;

+

+  //

+  // Create PCI device path

+  //

+  PciNode.Header.Type     = HARDWARE_DEVICE_PATH;

+  PciNode.Header.SubType  = HW_PCI_DP;

+  SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));

+

+  PciNode.Device          = PciIoDevice->DeviceNumber;

+  PciNode.Function        = PciIoDevice->FunctionNumber;

+  PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);

+

+  return PciIoDevice->DevicePath;

+}

+

+EFI_STATUS

+BarExisted (

+  IN PCI_IO_DEVICE *PciIoDevice,

+  IN UINTN         Offset,

+  OUT UINT32       *BarLengthValue,

+  OUT UINT32       *OriginalBarValue

+  )

+/*++

+

+Routine Description:

+

+  Check the bar is existed or not.

+

+Arguments:

+

+  PciIoDevice       - A pointer to the PCI_IO_DEVICE.

+  Offset            - The offset.

+  BarLengthValue    - The bar length value.

+  OriginalBarValue  - The original bar value.

+

+Returns:

+

+  EFI_NOT_FOUND     - The bar don't exist.

+  EFI_SUCCESS       - The bar exist.

+

+--*/

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINT32              OriginalValue;

+  UINT32              Value;

+  EFI_TPL             OldTpl;

+

+  PciIo = &PciIoDevice->PciIo;

+

+  //

+  // Preserve the original value

+  //

+

+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);

+

+  //

+  // Raise TPL to high level to disable timer interrupt while the BAR is probed

+  //

+  OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);

+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);

+

+  //

+  // Write back the original value

+  //

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);

+

+  //

+  // Restore TPL to its original level

+  //

+  gBS->RestoreTPL (OldTpl);

+

+  if (BarLengthValue != NULL) {

+    *BarLengthValue = Value;

+  }

+

+  if (OriginalBarValue != NULL) {

+    *OriginalBarValue = OriginalValue;

+  }

+

+  if (Value == 0) {

+    return EFI_NOT_FOUND;

+  } else {

+    return EFI_SUCCESS;

+  }

+}

+

+EFI_STATUS

+PciTestSupportedAttribute (

+  IN PCI_IO_DEVICE                      *PciIoDevice,

+  IN UINT16                             *Command,

+  IN UINT16                             *BridgeControl,

+  IN UINT16                             *OldCommand,

+  IN UINT16                             *OldBridgeControl

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Command - add argument and description to function comment

+// TODO:    BridgeControl - add argument and description to function comment

+// TODO:    OldCommand - add argument and description to function comment

+// TODO:    OldBridgeControl - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_TPL OldTpl;

+

+  //

+  // Preserve the original value

+  //

+  PciReadCommandRegister (PciIoDevice, OldCommand);

+

+  //

+  // Raise TPL to high level to disable timer interrupt while the BAR is probed

+  //

+  OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+

+  PciSetCommandRegister (PciIoDevice, *Command);

+  PciReadCommandRegister (PciIoDevice, Command);

+

+  //

+  // Write back the original value

+  //

+  PciSetCommandRegister (PciIoDevice, *OldCommand);

+

+  //

+  // Restore TPL to its original level

+  //

+  gBS->RestoreTPL (OldTpl);

+

+  if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

+    

+    //

+    // Preserve the original value

+    //

+    PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl);

+

+    //

+    // Raise TPL to high level to disable timer interrupt while the BAR is probed

+    //

+    OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+

+    PciSetBridgeControlRegister (PciIoDevice, *BridgeControl);

+    PciReadBridgeControlRegister (PciIoDevice, BridgeControl);

+

+    //

+    // Write back the original value

+    //

+    PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl);

+

+    //

+    // Restore TPL to its original level

+    //

+    gBS->RestoreTPL (OldTpl);

+

+  } else {

+    *OldBridgeControl = 0;

+    *BridgeControl    = 0;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciSetDeviceAttribute (

+  IN PCI_IO_DEVICE                      *PciIoDevice,

+  IN UINT16                             Command,

+  IN UINT16                             BridgeControl,

+  IN UINTN                              Option

+  )

+/*++

+

+  Routine Description:

+    Set the supported or current attributes of a PCI device    

+

+  Arguments:

+    PciIoDevice   - Structure pointer for PCI device.

+    Command       - Command register value.

+    BridgeControl - Bridge control value for PPB or P2C.

+    Option        - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.

+

+  Returns:    

+

+--*/

+

+/*++

+

+Routine Description:

+

+  

+

+Arguments:

+ 

+  

+Returns:

+  

+  EFI_SUCCESS   Always success

+  

+

+--*/

+{

+  UINT64  Attributes;

+

+  Attributes = 0;

+

+  if (Command & EFI_PCI_COMMAND_IO_SPACE) {

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;

+  }

+

+  if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;

+  }

+

+  if (Command & EFI_PCI_COMMAND_BUS_MASTER) {

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;

+  }

+

+  if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;

+  }

+

+  if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;

+  }

+

+  if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;

+  }

+

+  if (Option == EFI_SET_SUPPORTS) {

+

+    Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | 

+                  EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED        |

+                  EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE       |

+                  EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE      |

+                  EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         |

+                  EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;

+

+    if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {

+      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;

+      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;

+    }

+

+    if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

+      //

+      // For bridge, it should support IDE attributes

+      //

+      Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;

+      Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;

+    } else {

+

+      if (IS_PCI_IDE (&PciIoDevice->Pci)) {

+        Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;

+        Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;

+      }

+

+      if (IS_PCI_VGA (&PciIoDevice->Pci)) {

+        Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;

+        Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;

+      }

+    }

+

+    PciIoDevice->Supports = Attributes;

+    PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \

+                               EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \

+                               EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );

+

+  } else {

+    PciIoDevice->Attributes = Attributes;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetFastBackToBackSupport (

+  IN PCI_IO_DEVICE                      *PciIoDevice,

+  IN UINT8                              StatusIndex

+  )

+/*++

+

+Routine Description:

+ 

+  Determine if the device can support Fast Back to Back attribute

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    StatusIndex - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  EFI_STATUS          Status;

+  UINT32              StatusRegister;

+

+  //

+  // Read the status register

+  //

+  PciIo   = &PciIoDevice->PciIo;

+  Status  = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Check the Fast B2B bit

+  //

+  if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) {

+    return EFI_SUCCESS;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+

+}

+

+EFI_STATUS

+ProcessOptionRomLight (

+  IN PCI_IO_DEVICE                      *PciIoDevice

+  )

+/*++

+

+Routine Description:

+ 

+  Process the option ROM for all the children of the specified parent PCI device.

+  It can only be used after the first full Option ROM process.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE   *Temp;

+  LIST_ENTRY      *CurrentLink;

+

+  //

+  // For RootBridge, PPB , P2C, go recursively to traverse all its children

+  //

+  CurrentLink = PciIoDevice->ChildList.ForwardLink;

+  while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (!IsListEmpty (&Temp->ChildList)) {

+      ProcessOptionRomLight (Temp);

+    }

+

+    PciRomGetImageMapping (Temp);

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DetermineDeviceAttribute (

+  IN PCI_IO_DEVICE                      *PciIoDevice

+  )

+/*++

+

+Routine Description:

+ 

+  Determine the related attributes of all devices under a Root Bridge

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT16          Command;

+  UINT16          BridgeControl;

+  UINT16          OldCommand;

+  UINT16          OldBridgeControl;

+  BOOLEAN         FastB2BSupport;

+

+  /*

+  UINT8  IdePI;

+  EFI_PCI_IO_PROTOCOL   *PciIo;

+  */

+  PCI_IO_DEVICE   *Temp;

+  LIST_ENTRY      *CurrentLink;

+  EFI_STATUS      Status;

+

+  //

+  // For Root Bridge, just copy it by RootBridgeIo proctocol

+  // so as to keep consistent with the actual attribute

+  //

+  if (!PciIoDevice->Parent) {

+    Status = PciIoDevice->PciRootBridgeIo->GetAttributes (

+                                            PciIoDevice->PciRootBridgeIo,

+                                            &PciIoDevice->Supports,

+                                            &PciIoDevice->Attributes

+                                            );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  } else {

+  

+    //

+    // Set the attributes to be checked for common PCI devices and PPB or P2C

+    // Since some devices only support part of them, it is better to set the

+    // attribute according to its command or bridge control register

+    //

+    Command = EFI_PCI_COMMAND_IO_SPACE     |

+              EFI_PCI_COMMAND_MEMORY_SPACE |

+              EFI_PCI_COMMAND_BUS_MASTER   |

+              EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;

+

+    BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA;

+

+    //

+    // Test whether the device can support attributes above

+    //

+    PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl);

+

+    //

+    // Set the supported attributes for specified PCI device

+    //

+    PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS);

+

+    //

+    // Set the current attributes for specified PCI device

+    //

+    PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);

+

+    //

+    // Enable other supported attributes but not defined in PCI_IO_PROTOCOL

+    //

+    PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);

+

+    //

+    // Enable IDE native mode

+    //

+    /*

+    if (IS_PCI_IDE(&PciIoDevice->Pci)) {

+

+      PciIo = &PciIoDevice->PciIo;  

+

+      PciIo->Pci.Read (

+                              PciIo, 

+                              EfiPciIoWidthUint8, 

+                              0x09, 

+                              1, 

+                              &IdePI

+                              );

+      

+      //

+      // Set native mode if it can be supported

+      //      

+      IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);

+

+      PciIo->Pci.Write (

+                              PciIo, 

+                              EfiPciIoWidthUint8, 

+                              0x09, 

+                              1, 

+                              &IdePI

+                              );  

+    

+    }  

+    */

+  }

+

+  FastB2BSupport = TRUE;

+

+  //

+  // P2C can not support FB2B on the secondary side

+  //

+  if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

+    FastB2BSupport = FALSE;

+  }

+  

+  //

+  // For RootBridge, PPB , P2C, go recursively to traverse all its children

+  //

+  CurrentLink = PciIoDevice->ChildList.ForwardLink;

+  while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {

+

+    Temp    = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+    Status  = DetermineDeviceAttribute (Temp);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Detect Fast Bact to Bact support for the device under the bridge

+    //

+    Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);

+    if (FastB2BSupport && EFI_ERROR (Status)) {

+      FastB2BSupport = FALSE;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+  //

+  // Set or clear Fast Back to Back bit for the whole bridge

+  //

+  if (!IsListEmpty (&PciIoDevice->ChildList)) {

+

+    if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {

+

+      Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);

+

+      if (EFI_ERROR (Status) || (!FastB2BSupport)) {

+        FastB2BSupport = FALSE;

+        PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);

+      } else {

+        PciEnableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK);

+      }

+    }

+

+    CurrentLink = PciIoDevice->ChildList.ForwardLink;

+    while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {

+      Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+      if (FastB2BSupport) {

+        PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);

+      } else {

+        PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK);

+      }

+

+      CurrentLink = CurrentLink->ForwardLink;

+    }

+  }

+  //

+  // End for IsListEmpty

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UpdatePciInfo (

+  IN PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to update the bar information for those incompatible PCI device

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  UINTN                             BarIndex;

+  UINTN                             BarEndIndex;

+  BOOLEAN                           SetFlag;

+  VOID                              *Configuration;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;

+

+  Configuration = NULL;

+

+  //

+  // It can only be supported after the Incompatible PCI Device

+  // Support Protocol has been installed

+  //

+  if (gEfiIncompatiblePciDeviceSupport == NULL) {

+

+    Status = gBS->LocateProtocol (

+                    &gEfiIncompatiblePciDeviceSupportProtocolGuid,

+                    NULL,

+                    (VOID **) &gEfiIncompatiblePciDeviceSupport

+                    );

+    if (EFI_ERROR (Status)) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  

+  //

+  // Check whether the device belongs to incompatible devices or not

+  // If it is , then get its special requirement in the ACPI table

+  //

+  Status = gEfiIncompatiblePciDeviceSupport->CheckDevice (

+                                              gEfiIncompatiblePciDeviceSupport,

+                                              PciIoDevice->Pci.Hdr.VendorId,

+                                              PciIoDevice->Pci.Hdr.DeviceId,

+                                              PciIoDevice->Pci.Hdr.RevisionID,

+                                              PciIoDevice->Pci.Device.SubsystemVendorID,

+                                              PciIoDevice->Pci.Device.SubsystemID,

+                                              &Configuration

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Update PCI device information from the ACPI table

+  //

+  Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;

+

+  while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {

+

+    if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {

+      //

+      // The format is not support

+      //

+      break;

+    }

+

+    BarIndex    = (UINTN) Ptr->AddrTranslationOffset;

+    BarEndIndex = BarIndex;

+

+    //

+    // Update all the bars in the device

+    //

+    if (BarIndex == PCI_BAR_ALL) {

+      BarIndex    = 0;

+      BarEndIndex = PCI_MAX_BAR - 1;

+    }

+

+    if (BarIndex >= PCI_MAX_BAR) {

+      Ptr++;

+      continue;

+    }

+

+    for (; BarIndex <= BarEndIndex; BarIndex++) {

+      SetFlag = FALSE;

+      switch (Ptr->ResType) {

+      case ACPI_ADDRESS_SPACE_TYPE_MEM:

+          

+        //

+        // Make sure the bar is memory type

+        //

+        if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {

+          SetFlag = TRUE;

+        }

+        break;

+

+      case ACPI_ADDRESS_SPACE_TYPE_IO:

+          

+        //

+        // Make sure the bar is IO type

+        //

+        if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {

+          SetFlag = TRUE;

+        }

+        break;

+      }

+

+      if (SetFlag) {

+        

+        //

+        // Update the new alignment for the device

+        //

+        SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax);

+

+        //

+        // Update the new length for the device

+        //

+        if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {

+          PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;

+        }

+      }

+    }

+

+    Ptr++;

+  }

+

+  gBS->FreePool (Configuration);

+  return Status;

+

+}

+

+VOID

+SetNewAlign (

+  IN UINT64 *Alignment,

+  IN UINT64 NewAlignment

+  )

+/*++

+

+Routine Description:

+

+  This routine will update the alignment with the new alignment

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Alignment - add argument and description to function comment

+// TODO:    NewAlignment - add argument and description to function comment

+{

+  UINT64  OldAlignment;

+  UINTN   ShiftBit;

+

+  //

+  // The new alignment is the same as the original,

+  // so skip it

+  //

+  if (NewAlignment == PCI_BAR_OLD_ALIGN) {

+    return ;

+  }

+  //

+  // Check the validity of the parameter

+  //

+   if (NewAlignment != PCI_BAR_EVEN_ALIGN  && 

+       NewAlignment != PCI_BAR_SQUAD_ALIGN &&

+       NewAlignment != PCI_BAR_DQUAD_ALIGN ) {         

+    *Alignment = NewAlignment;

+    return ;

+  }

+

+  OldAlignment  = (*Alignment) + 1;

+  ShiftBit      = 0;

+

+  //

+  // Get the first non-zero hex value of the length

+  //

+  while ((OldAlignment & 0x0F) == 0x00) {

+    OldAlignment = RShiftU64 (OldAlignment, 4);

+    ShiftBit += 4;

+  }

+   

+  //

+  // Adjust the alignment to even, quad or double quad boundary

+  //

+  if (NewAlignment == PCI_BAR_EVEN_ALIGN) {

+    if (OldAlignment & 0x01) {

+      OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);

+    }

+  } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {

+    if (OldAlignment & 0x03) {

+      OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);

+    }

+  } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {

+    if (OldAlignment & 0x07) {

+      OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);

+    }

+  }

+   

+  //

+  // Update the old value

+  //

+  NewAlignment  = LShiftU64 (OldAlignment, ShiftBit) - 1;

+  *Alignment    = NewAlignment;

+

+  return ;

+}

+

+UINTN

+PciParseBar (

+  IN PCI_IO_DEVICE  *PciIoDevice,

+  IN UINTN          Offset,

+  IN UINTN          BarIndex

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+{

+  UINT32      Value;

+  UINT64      BarValue64;

+  UINT32      OriginalValue;

+  UINT32      Mask;

+  UINT32      Data;

+  UINT8       Index;

+  EFI_STATUS  Status;

+

+  OriginalValue = 0;

+  Value         = 0;

+  BarValue64    = 0;

+

+  Status = BarExisted (

+            PciIoDevice,

+            Offset,

+            &Value,

+            &OriginalValue

+            );

+

+  if (EFI_ERROR (Status)) {

+    PciIoDevice->PciBar[BarIndex].BaseAddress = 0;

+    PciIoDevice->PciBar[BarIndex].Length      = 0;

+    PciIoDevice->PciBar[BarIndex].Alignment   = 0;

+

+    //

+    // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway

+    //

+    PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;

+    return Offset + 4;

+  }

+

+  PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;

+  if (Value & 0x01) {

+    //

+    // Device I/Os

+    //

+    Mask = 0xfffffffc;

+

+    if (Value & 0xFFFF0000) {

+      //

+      // It is a IO32 bar

+      //

+      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeIo32;

+      PciIoDevice->PciBar[BarIndex].Length    = ((~(Value & Mask)) + 1);

+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;

+

+    } else {

+      //

+      // It is a IO16 bar

+      //

+      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeIo16;

+      PciIoDevice->PciBar[BarIndex].Length    = 0x0000FFFF & ((~(Value & Mask)) + 1);

+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;

+

+    }

+    //

+    // Workaround. Some platforms inplement IO bar with 0 length

+    // Need to treat it as no-bar

+    //

+    if (PciIoDevice->PciBar[BarIndex].Length == 0) {

+      PciIoDevice->PciBar[BarIndex].BarType = 0;

+    }

+

+    PciIoDevice->PciBar[BarIndex].Prefetchable  = FALSE;

+    PciIoDevice->PciBar[BarIndex].BaseAddress   = OriginalValue & Mask;

+

+  } else {

+

+    Mask  = 0xfffffff0;

+

+    PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;

+

+    switch (Value & 0x07) {

+

+    //

+    //memory space; anywhere in 32 bit address space

+    //

+    case 0x00:

+      if (Value & 0x08) {

+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;

+      } else {

+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;

+      }

+

+      PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;

+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;

+

+      break;

+

+    //

+    // memory space; anywhere in 64 bit address space

+    //

+    case 0x04:

+      if (Value & 0x08) {

+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;

+      } else {

+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;

+      }

+

+      //

+      // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar

+      // is regarded as an extension for the first bar. As a result

+      // the sizing will be conducted on combined 64 bit value

+      // Here just store the masked first 32bit value for future size

+      // calculation

+      //

+      PciIoDevice->PciBar[BarIndex].Length    = Value & Mask;

+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;

+

+      //

+      // Increment the offset to point to next DWORD

+      //

+      Offset += 4;

+

+      Status = BarExisted (

+                PciIoDevice,

+                Offset,

+                &Value,

+                &OriginalValue

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Offset + 4;

+      }

+

+      //

+      // Fix the length to support some spefic 64 bit BAR

+      //

+      Data  = Value;

+      Index = 0;

+      for (Data = Value; Data != 0; Data >>= 1) {

+      	Index ++;

+      }

+      Value |= ((UINT32)(-1) << Index); 

+

+      //

+      // Calculate the size of 64bit bar

+      //

+      PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);

+

+      PciIoDevice->PciBar[BarIndex].Length    = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);

+      PciIoDevice->PciBar[BarIndex].Length    = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;

+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;

+

+      break;

+

+    //

+    // reserved

+    //

+    default:

+      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeUnknown;

+      PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;

+      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;

+

+      break;

+    }

+  }

+  

+  //

+  // Check the length again so as to keep compatible with some special bars

+  //

+  if (PciIoDevice->PciBar[BarIndex].Length == 0) {

+    PciIoDevice->PciBar[BarIndex].BarType     = PciBarTypeUnknown;

+    PciIoDevice->PciBar[BarIndex].BaseAddress = 0;

+    PciIoDevice->PciBar[BarIndex].Alignment   = 0;

+  }

+  

+  //

+  // Increment number of bar

+  //

+  return Offset + 4;

+}

+

+EFI_STATUS

+InitializePciDevice (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+ 

+  This routine is used to initialize the bar of a PCI device

+  It can be called typically when a device is going to be rejected

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINT8               Offset;

+

+  PciIo = &(PciIoDevice->PciIo);

+

+  //

+  // Put all the resource apertures

+  // Resource base is set to all ones so as to indicate its resource

+  // has not been alloacted

+  //

+  for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {

+    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InitializePpb (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  PciIo = &(PciIoDevice->PciIo);

+

+  //

+  // Put all the resource apertures including IO16

+  // Io32, pMem32, pMem64 to quiescent state

+  // Resource base all ones, Resource limit all zeros

+  //

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);

+

+  //

+  // don't support use io32 as for now

+  //

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);

+

+  //

+  // Force Interrupt line to zero for cards that come up randomly

+  //

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InitializeP2C (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  PciIo = &(PciIoDevice->PciIo);

+

+  //

+  // Put all the resource apertures including IO16

+  // Io32, pMem32, pMem64 to quiescent state(

+  // Resource base all ones, Resource limit all zeros

+  //

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);

+

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);

+

+  //

+  // Force Interrupt line to zero for cards that come up randomly

+  //

+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero);

+  return EFI_SUCCESS;

+}

+

+PCI_IO_DEVICE *

+CreatePciIoDevice (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciRootBridgeIo - add argument and description to function comment

+// TODO:    Pci - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Func - add argument and description to function comment

+{

+

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = NULL;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (PCI_IO_DEVICE),

+                  (VOID **) &PciIoDevice

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+

+  ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));

+

+  PciIoDevice->Signature        = PCI_IO_DEVICE_SIGNATURE;

+  PciIoDevice->Handle           = NULL;

+  PciIoDevice->PciRootBridgeIo  = PciRootBridgeIo;

+  PciIoDevice->DevicePath       = NULL;

+  PciIoDevice->BusNumber        = Bus;

+  PciIoDevice->DeviceNumber     = Device;

+  PciIoDevice->FunctionNumber   = Func;

+  PciIoDevice->Decodes          = 0;

+  if (gFullEnumeration) {

+    PciIoDevice->Allocated = FALSE;

+  } else {

+    PciIoDevice->Allocated = TRUE;

+  }

+

+  PciIoDevice->Registered         = FALSE;

+  PciIoDevice->Attributes         = 0;

+  PciIoDevice->Supports           = 0;

+  PciIoDevice->BusOverride        = FALSE;

+  PciIoDevice->AllOpRomProcessed  = FALSE;

+

+  PciIoDevice->IsPciExp           = FALSE;

+

+  CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));

+

+  //

+  // Initialize the PCI I/O instance structure

+  //

+

+  Status  = InitializePciIoInstance (PciIoDevice);

+  Status  = InitializePciDriverOverrideInstance (PciIoDevice);

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (PciIoDevice);

+    return NULL;

+  }

+

+  //

+  // Initialize the reserved resource list

+  //

+  InitializeListHead (&PciIoDevice->ReservedResourceList);

+

+  //

+  // Initialize the driver list

+  //

+  InitializeListHead (&PciIoDevice->OptionRomDriverList);

+

+  //

+  // Initialize the child list

+  //

+  InitializeListHead (&PciIoDevice->ChildList);

+

+  return PciIoDevice;

+}

+

+EFI_STATUS

+PciEnumeratorLight (

+  IN EFI_HANDLE                    Controller

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to enumerate entire pci bus system 

+  in a given platform

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Controller - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  EFI_STATUS                        Status;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;

+  PCI_IO_DEVICE                     *RootBridgeDev;

+  UINT16                            MinBus;

+  UINT16                            MaxBus;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

+

+  MinBus      = 0;

+  MaxBus      = PCI_MAX_BUS;

+  Descriptors = NULL;

+

+  //

+  // If this host bridge has been already enumerated, then return successfully

+  //

+  if (RootBridgeExisted (Controller)) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Open pci root bridge io protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &PciRootBridgeIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {

+

+    //

+    // Create a device node for root bridge device with a NULL host bridge controller handle

+    //

+    RootBridgeDev = CreateRootBridge (Controller);

+

+    if (!RootBridgeDev) {

+      Descriptors++;

+      continue;

+    }

+    

+    //

+    // Record the root bridge io protocol

+    //

+    RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;

+

+    Status = PciPciDeviceInfoCollector (

+              RootBridgeDev,

+              (UINT8) MinBus

+              );

+

+    if (!EFI_ERROR (Status)) {

+      

+      //

+      // Remove those PCI devices which are rejected when full enumeration

+      //

+      RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);

+

+      //

+      // Process option rom light

+      //

+      ProcessOptionRomLight (RootBridgeDev);

+

+      //

+      // Determine attributes for all devices under this root bridge

+      //

+      DetermineDeviceAttribute (RootBridgeDev);

+

+      //

+      // If successfully, insert the node into device pool

+      //

+      InsertRootBridge (RootBridgeDev);

+    } else {

+

+      //

+      // If unsuccessly, destroy the entire node

+      //

+      DestroyRootBridge (RootBridgeDev);

+    }

+

+    Descriptors++;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciGetBusRange (

+  IN     EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,

+  OUT    UINT16                             *MinBus,

+  OUT    UINT16                             *MaxBus,

+  OUT    UINT16                             *BusRange

+  )

+/*++

+

+Routine Description:

+

+  Get the bus range.

+

+Arguments:

+

+  Descriptors     - A pointer to the address space descriptor.

+  MinBus          - The min bus.

+  MaxBus          - The max bus.

+  BusRange        - The bus range.

+  

+Returns:

+  

+  Status Code.

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+

+  while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {

+    if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {

+      if (MinBus != NULL) {

+        *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;

+      }

+

+      if (MaxBus != NULL) {

+        *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;

+      }

+

+      if (BusRange != NULL) {

+        *BusRange = (UINT16) (*Descriptors)->AddrLen;

+      }

+

+      return EFI_SUCCESS;

+    }

+

+    (*Descriptors)++;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+StartManagingRootBridge (

+  IN PCI_IO_DEVICE *RootBridgeDev

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    RootBridgeDev - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_HANDLE                      RootBridgeHandle;

+  EFI_STATUS                      Status;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  //

+  // Get the root bridge handle

+  //

+  RootBridgeHandle  = RootBridgeDev->Handle;

+  PciRootBridgeIo   = NULL;

+

+  //

+  // Get the pci root bridge io protocol

+  //

+  Status = gBS->OpenProtocol (

+                  RootBridgeHandle,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &PciRootBridgeIo,

+                  gPciBusDriverBinding.DriverBindingHandle,

+                  RootBridgeHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  //

+  // Store the PciRootBridgeIo protocol into root bridge private data

+  //

+  RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;

+

+  return EFI_SUCCESS;

+

+}

+

+BOOLEAN

+IsPciDeviceRejected (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  This routine can be used to check whether a PCI device should be rejected when light enumeration

+

+Arguments:

+

+Returns:

+

+  TRUE      This device should be rejected

+  FALSE     This device shouldn't be rejected

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  UINT32      TestValue;

+  UINT32      OldValue;

+  UINT32      Mask;

+  UINT8       BarOffset;

+

+  //

+  // PPB should be skip!

+  //

+  if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {

+    return FALSE;

+  }

+

+  if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

+    //

+    // Only test base registers for P2C

+    //

+    for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {

+

+      Mask    = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;

+      Status  = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);

+      if (EFI_ERROR (Status)) {

+        continue;

+      }

+

+      TestValue = TestValue & Mask;

+      if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {

+        //

+        // The bar isn't programed, so it should be rejected

+        //

+        return TRUE;

+      }

+    }

+

+    return FALSE;

+  }

+

+  for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) {

+    //

+    // Test PCI devices

+    //

+    Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    if (TestValue & 0x01) {

+      

+      //

+      // IO Bar

+      //

+      

+      Mask      = 0xFFFFFFFC;

+      TestValue = TestValue & Mask;

+      if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {

+        return TRUE;

+      }

+

+    } else {

+      

+      //

+      // Mem Bar

+      //

+      

+      Mask      = 0xFFFFFFF0;

+      TestValue = TestValue & Mask;

+

+      if ((TestValue & 0x07) == 0x04) {

+        

+        //

+        // Mem64 or PMem64

+        //

+        BarOffset += sizeof (UINT32);

+        if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {

+          

+          //

+          // Test its high 32-Bit BAR

+          //

+          

+          Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);

+          if (TestValue == OldValue) {

+            return TRUE;

+          }

+        }

+

+      } else {

+        

+        //

+        // Mem32 or PMem32

+        //

+        if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {

+          return TRUE;

+        }

+      }

+    }

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+ResetAllPpbBusReg (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge          - TODO: add argument description

+  StartBusNumber  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS                      Status;

+  PCI_TYPE00                      Pci;

+  UINT8                           Device;

+  UINT32                          Register;  

+  UINT8                           Func;

+  UINT64                          Address;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+

+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {

+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {

+

+      //

+      // Check to see whether a pci device is present

+      //

+      Status = PciDevicePresent (

+                PciRootBridgeIo,

+                &Pci,

+                StartBusNumber,

+                Device,

+                Func

+                );

+

+      if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {

+        Register  = 0;

+        Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);

+        Status   = PciRootBridgeIo->Pci.Read (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint32, 

+                                        Address,

+                                        1,

+                                        &Register

+                                        );

+        //

+        // Reset register 18h, 19h, 1Ah on PCI Bridge

+        //

+        Register &= 0xFF000000;

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint32, 

+                                        Address,

+                                        1,

+                                        &Register

+                                        );

+      }

+

+      if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {

+        //

+        // Skip sub functions, this is not a multi function device

+        //

+        Func = PCI_MAX_FUNC;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h
new file mode 100644
index 0000000..41d6efb
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.h
@@ -0,0 +1,598 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciEnumeratorSupport.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H

+#define _EFI_PCI_ENUMERATOR_SUPPORT_H

+

+EFI_STATUS

+PciDevicePresent (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  PCI_TYPE00                          *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciRootBridgeIo - TODO: add argument description

+  Pci             - TODO: add argument description

+  Bus             - TODO: add argument description

+  Device          - TODO: add argument description

+  Func            - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciPciDeviceInfoCollector (

+  IN PCI_IO_DEVICE                      *Bridge,

+  UINT8                                 StartBusNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge          - TODO: add argument description

+  StartBusNumber  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciSearchDevice (

+  IN PCI_IO_DEVICE                      *Bridge,

+  PCI_TYPE00                            *Pci,

+  UINT8                                 Bus,

+  UINT8                                 Device,

+  UINT8                                 Func,

+  PCI_IO_DEVICE                         **PciDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge    - TODO: add argument description

+  Pci       - TODO: add argument description

+  Bus       - TODO: add argument description

+  Device    - TODO: add argument description

+  Func      - TODO: add argument description

+  PciDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE             *

+GatherDeviceInfo (

+  IN PCI_IO_DEVICE                    *Bridge,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  Pci     - TODO: add argument description

+  Bus     - TODO: add argument description

+  Device  - TODO: add argument description

+  Func    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE             *

+GatherPpbInfo (

+  IN PCI_IO_DEVICE                    *Bridge,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  Pci     - TODO: add argument description

+  Bus     - TODO: add argument description

+  Device  - TODO: add argument description

+  Func    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE             *

+GatherP2CInfo (

+  IN PCI_IO_DEVICE                    *Bridge,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  Pci     - TODO: add argument description

+  Bus     - TODO: add argument description

+  Device  - TODO: add argument description

+  Func    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_DEVICE_PATH_PROTOCOL  *

+CreatePciDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,

+  IN  PCI_IO_DEVICE            *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ParentDevicePath  - TODO: add argument description

+  PciIoDevice       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+BarExisted (

+  IN PCI_IO_DEVICE *PciIoDevice,

+  IN UINTN         Offset,

+  OUT UINT32       *BarLengthValue,

+  OUT UINT32       *OriginalBarValue

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice       - TODO: add argument description

+  Offset            - TODO: add argument description

+  BarLengthValue    - TODO: add argument description

+  OriginalBarValue  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciTestSupportedAttribute (

+  IN PCI_IO_DEVICE                      *PciIoDevice,

+  IN UINT16                             *Command,

+  IN UINT16                             *BridgeControl,

+  IN UINT16                             *OldCommand,

+  IN UINT16                             *OldBridgeControl

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice       - TODO: add argument description

+  Command           - TODO: add argument description

+  BridgeControl     - TODO: add argument description

+  OldCommand        - TODO: add argument description

+  OldBridgeControl  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciSetDeviceAttribute (

+  IN PCI_IO_DEVICE                      *PciIoDevice,

+  IN UINT16                             Command,

+  IN UINT16                             BridgeControl,

+  IN UINTN                              Option

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice   - TODO: add argument description

+  Command       - TODO: add argument description

+  BridgeControl - TODO: add argument description

+  Option        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetFastBackToBackSupport (

+  IN PCI_IO_DEVICE                      *PciIoDevice,

+  IN UINT8                              StatusIndex

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  StatusIndex - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DetermineDeviceAttribute (

+  IN PCI_IO_DEVICE                      *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+UpdatePciInfo (

+  IN PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+SetNewAlign (

+  IN UINT64 *Alignment,

+  IN UINT64 NewAlignment

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Alignment     - TODO: add argument description

+  NewAlignment  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+UINTN

+PciParseBar (

+  IN PCI_IO_DEVICE  *PciIoDevice,

+  IN UINTN          Offset,

+  IN UINTN          BarIndex

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  Offset      - TODO: add argument description

+  BarIndex    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InitializePciDevice (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InitializePpb (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InitializeP2C (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_IO_DEVICE             *

+CreatePciIoDevice (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  IN PCI_TYPE00                       *Pci,

+  UINT8                               Bus,

+  UINT8                               Device,

+  UINT8                               Func

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciRootBridgeIo - TODO: add argument description

+  Pci             - TODO: add argument description

+  Bus             - TODO: add argument description

+  Device          - TODO: add argument description

+  Func            - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciEnumeratorLight (

+  IN EFI_HANDLE                    Controller

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Controller  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciGetBusRange (

+  IN     EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,

+  OUT    UINT16                             *MinBus,

+  OUT    UINT16                             *MaxBus,

+  OUT    UINT16                             *BusRange

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Descriptors - TODO: add argument description

+  MinBus      - TODO: add argument description

+  MaxBus      - TODO: add argument description

+  BusRange    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+StartManagingRootBridge (

+  IN PCI_IO_DEVICE *RootBridgeDev

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeDev - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsPciDeviceRejected (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c
new file mode 100644
index 0000000..8707487
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c
@@ -0,0 +1,462 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciHotPlugSupport.c

+  

+Abstract:

+

+  

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciHotPlugSupport.h"

+

+EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *gPciHotPlugInit;

+EFI_HPC_LOCATION                *gPciRootHpcPool;

+UINTN                           gPciRootHpcCount;

+ROOT_HPC_DATA                   *gPciRootHpcData;

+

+VOID

+EFIAPI

+PciHPCInitialized (

+  IN EFI_EVENT    Event,

+  IN VOID         *Context

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Event - add argument and description to function comment

+// TODO:    Context - add argument and description to function comment

+{

+  ROOT_HPC_DATA *HpcData;

+

+  HpcData               = (ROOT_HPC_DATA *) Context;

+  HpcData->Initialized  = TRUE;

+

+}

+

+BOOLEAN

+EfiCompareDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,

+  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    DevicePath1 - add argument and description to function comment

+// TODO:    DevicePath2 - add argument and description to function comment

+{

+  UINTN Size1;

+  UINTN Size2;

+

+  Size1 = GetDevicePathSize (DevicePath1);

+  Size2 = GetDevicePathSize (DevicePath2);

+

+  if (Size1 != Size2) {

+    return FALSE;

+  }

+

+  if (CompareMem (DevicePath1, DevicePath2, Size1)) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+EFI_STATUS

+InitializeHotPlugSupport (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS        Status;

+  EFI_HPC_LOCATION  *HpcList;

+  UINTN             HpcCount;

+

+  //

+  // Locate the PciHotPlugInit Protocol

+  // If it doesn't exist, that means there is no

+  // hot plug controller supported on the platform

+  // the PCI Bus driver is running on. HotPlug Support

+  // is an optional feature, so absence of the protocol

+  // won't incur the penalty

+  //

+  gPciHotPlugInit   = NULL;

+  gPciRootHpcPool   = NULL;

+  gPciRootHpcCount  = 0;

+  gPciRootHpcData   = NULL;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiPciHotPlugInitProtocolGuid,

+                  NULL,

+                  (VOID **) &gPciHotPlugInit

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gPciHotPlugInit->GetRootHpcList (

+                              gPciHotPlugInit,

+                              &HpcCount,

+                              &HpcList

+                              );

+

+  if (!EFI_ERROR (Status)) {

+

+    gPciRootHpcPool   = HpcList;

+    gPciRootHpcCount  = HpcCount;

+    gPciRootHpcData   = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount);

+    if (gPciRootHpcData == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsRootPciHotPlugBus (

+  IN EFI_DEVICE_PATH_PROTOCOL         *HpbDevicePath,

+  OUT UINTN                           *HpIndex

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  HpcDevicePath       - A pointer to the EFI_DEVICE_PATH_PROTOCOL.

+  HpIndex             - A pointer to the Index.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    HpbDevicePath - add argument and description to function comment

+{

+  UINTN Index;

+

+  for (Index = 0; Index < gPciRootHpcCount; Index++) {

+

+    if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) {

+

+      if (HpIndex != NULL) {

+        *HpIndex = Index;

+      }

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+IsRootPciHotPlugController (

+  IN EFI_DEVICE_PATH_PROTOCOL         *HpcDevicePath,

+  OUT UINTN                           *HpIndex

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  HpcDevicePath       - A pointer to the EFI_DEVICE_PATH_PROTOCOL.

+  HpIndex             - A pointer to the Index.

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Index;

+

+  for (Index = 0; Index < gPciRootHpcCount; Index++) {

+

+    if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) {

+

+      if (HpIndex != NULL) {

+        *HpIndex = Index;

+      }

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+CreateEventForHpc (

+  IN UINTN       HpIndex,

+  OUT EFI_EVENT  *Event

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    HpIndex - add argument and description to function comment

+// TODO:    Event - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  PciHPCInitialized,

+                  gPciRootHpcData + HpIndex,

+                  &((gPciRootHpcData + HpIndex)->Event)

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    *Event = (gPciRootHpcData + HpIndex)->Event;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+AllRootHPCInitialized (

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    TimeoutInMilliSeconds - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_TIMEOUT - add return value to function comment

+{

+  UINT32  Delay;

+  UINTN   Index;

+

+  Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);

+  do {

+

+    for (Index = 0; Index < gPciRootHpcCount; Index++) {

+

+      if (!gPciRootHpcData[Index].Initialized) {

+        break;

+      }

+    }

+

+    if (Index == gPciRootHpcCount) {

+      return EFI_SUCCESS;

+    }

+

+    //

+    // Stall for 30 us

+    //

+    gBS->Stall (30);

+

+    Delay--;

+

+  } while (Delay);

+

+  return EFI_TIMEOUT;

+}

+

+EFI_STATUS

+IsSHPC (

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+

+  EFI_STATUS  Status;

+  UINT8       Offset;

+

+  if (!PciIoDevice) {

+    return EFI_NOT_FOUND;

+  }

+

+  Offset = 0;

+  Status = LocateCapabilityRegBlock (

+            PciIoDevice,

+            EFI_PCI_CAPABILITY_ID_HOTPLUG,

+            &Offset,

+            NULL

+            );

+

+  //

+  // If the PPB has the hot plug controller build-in,

+  // then return TRUE;

+  //

+  if (!EFI_ERROR (Status)) {

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+GetResourcePaddingForHpb (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  EFI_HPC_STATE                     State;

+  UINT64                            PciAddress;

+  EFI_HPC_PADDING_ATTRIBUTES        Attributes;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

+

+  Status = IsPciHotPlugBus (PciIoDevice);

+

+  if (!EFI_ERROR (Status)) {

+    PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);

+    Status = gPciHotPlugInit->GetResourcePadding (

+                                gPciHotPlugInit,

+                                PciIoDevice->DevicePath,

+                                PciAddress,

+                                &State,

+                                (VOID **) &Descriptors,

+                                &Attributes

+                                );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) {

+      PciIoDevice->ResourcePaddingDescriptors = Descriptors;

+      PciIoDevice->PaddingAttributes          = Attributes;

+    }

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+IsPciHotPlugBus (

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  BOOLEAN     Result;

+  EFI_STATUS  Status;

+

+  Status = IsSHPC (PciIoDevice);

+

+  //

+  // If the PPB has the hot plug controller build-in,

+  // then return TRUE;

+  //

+  if (!EFI_ERROR (Status)) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Otherwise, see if it is a Root HPC

+  //

+  Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL);

+

+  if (Result) {

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h
new file mode 100644
index 0000000..df49eba
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.h
@@ -0,0 +1,269 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciHotPlugSupport.h

+  

+Abstract:

+

+  

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H

+#define _EFI_PCI_HOT_PLUG_SUPPORT_H

+

+//

+// stall 1 ms

+//

+#define STALL_1_MILLI_SECOND  1000    

+

+//

+// stall 1 second

+//

+#define STALL_1_SECOND        1000000 

+

+typedef struct {

+  EFI_EVENT Event;

+  BOOLEAN   Initialized;

+  VOID      *Padding;

+} ROOT_HPC_DATA;

+

+extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;

+extern EFI_HPC_LOCATION               *gPciRootHpcPool;

+extern UINTN                          gPciRootHpcCount;

+extern ROOT_HPC_DATA                  *gPciRootHpcData;

+

+VOID

+EFIAPI

+PciHPCInitialized (

+  IN EFI_EVENT    Event,

+  IN VOID         *Context

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Event   - TODO: add argument description

+  Context - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+EfiCompareDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,

+  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  DevicePath1 - TODO: add argument description

+  DevicePath2 - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InitializeHotPlugSupport (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IsPciHotPlugBus (

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsRootPciHotPlugBus (

+  IN EFI_DEVICE_PATH_PROTOCOL         *HpbDevicePath,

+  OUT UINTN                           *HpIndex

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  HpbDevicePath - TODO: add argument description

+  HpIndex       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsRootPciHotPlugController (

+  IN EFI_DEVICE_PATH_PROTOCOL         *HpcDevicePath,

+  OUT UINTN                           *HpIndex

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  HpcDevicePath - TODO: add argument description

+  HpIndex       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CreateEventForHpc (

+  IN UINTN       HpIndex,

+  OUT EFI_EVENT  *Event

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  HpIndex - TODO: add argument description

+  Event   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AllRootHPCInitialized (

+  IN  UINTN           TimeoutInMilliSeconds

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  TimeoutInMilliSeconds - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IsSHPC (

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetResourcePaddingForHpb (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c
new file mode 100644
index 0000000..28fbaca
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c
@@ -0,0 +1,1964 @@
+/*++

+ 

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciIo.c

+  

+Abstract:

+

+  PCI I/O Abstraction Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+

+//

+// Internal use only

+//

+STATIC

+EFI_STATUS

+ReportErrorStatusCode (

+  IN PCI_IO_DEVICE               *PciIoDevice,

+  IN EFI_STATUS_CODE_VALUE       Code

+  );

+

+//

+// PCI I/O Support Function Prototypes

+//

+//

+//

+// Pci Io Protocol Interface

+//

+static EFI_PCI_IO_PROTOCOL  PciIoInterface = {

+  PciIoPollMem,

+  PciIoPollIo,

+  {

+    PciIoMemRead,

+    PciIoMemWrite

+  },

+  {

+    PciIoIoRead,

+    PciIoIoWrite

+  },

+  {

+    PciIoConfigRead,

+    PciIoConfigWrite

+  },

+  PciIoCopyMem,

+  PciIoMap,

+  PciIoUnmap,

+  PciIoAllocateBuffer,

+  PciIoFreeBuffer,

+  PciIoFlush,

+  PciIoGetLocation,

+  PciIoAttributes,

+  PciIoGetBarAttributes,

+  PciIoSetBarAttributes,

+  0,

+  NULL

+};

+

+STATIC

+EFI_STATUS

+ReportErrorStatusCode (

+  IN PCI_IO_DEVICE               *PciIoDevice,

+  IN EFI_STATUS_CODE_VALUE       Code

+  )

+/*++

+

+Routine Description:

+

+  report a error Status code of PCI bus driver controller

+

+Arguments:

+  

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Code - add argument and description to function comment

+{

+  return REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+          EFI_ERROR_CODE | EFI_ERROR_MINOR,

+          Code,

+          PciIoDevice->DevicePath

+          );

+}

+

+EFI_STATUS

+InitializePciIoInstance (

+  PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  Initializes a PCI I/O Instance

+

+Arguments:

+  

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciIoVerifyBarAccess (

+  PCI_IO_DEVICE                   *PciIoDevice,

+  UINT8                           BarIndex,

+  PCI_BAR_TYPE                    Type,

+  IN EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN UINTN                        Count,

+  UINT64                          *Offset

+  )

+/*++

+

+Routine Description:

+

+  Verifies access to a PCI Base Address Register (BAR)

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Type - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // BarIndex 0-5 is legal

+  //

+  if (BarIndex >= PCI_MAX_BAR) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!CheckBarType (PciIoDevice, BarIndex, Type)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX

+  // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX

+  //

+  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {

+    Count = 1;

+  }

+

+  Width &= 0x03;

+

+  if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciIoVerifyConfigAccess (

+  PCI_IO_DEVICE                 *PciIoDevice,

+  IN EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN UINTN                      Count,

+  IN UINT64                     *Offset

+  )

+/*++

+

+Routine Description:

+

+  Verifies access to a PCI Config Header

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  ExtendOffset;

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX

+  //

+  Width &= 0x03;

+

+  if (PciIoDevice->IsPciExp) {

+    if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {

+      return EFI_UNSUPPORTED;

+    }

+

+    ExtendOffset  = LShiftU64 (*Offset, 32);

+    *Offset       = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);

+    *Offset       = (*Offset) | ExtendOffset;

+

+  } else {

+    if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {

+      return EFI_UNSUPPORTED;

+    }

+

+    *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoPollMem (

+  IN  EFI_PCI_IO_PROTOCOL        *This,

+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT8                      BarIndex,

+  IN  UINT64                     Offset,

+  IN  UINT64                     Mask,

+  IN  UINT64                     Value,

+  IN  UINT64                     Delay,

+  OUT UINT64                     *Result

+  )

+/*++

+

+Routine Description:

+

+  Poll PCI Memmory

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Mask - add argument and description to function comment

+// TODO:    Value - add argument and description to function comment

+// TODO:    Delay - add argument and description to function comment

+// TODO:    Result - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Width > EfiPciIoWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->PollMem (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                          Offset,

+                                          Mask,

+                                          Value,

+                                          Delay,

+                                          Result

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoPollIo (

+  IN  EFI_PCI_IO_PROTOCOL        *This,

+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT8                      BarIndex,

+  IN  UINT64                     Offset,

+  IN  UINT64                     Mask,

+  IN  UINT64                     Value,

+  IN  UINT64                     Delay,

+  OUT UINT64                     *Result

+  )

+/*++

+

+Routine Description:

+

+  Poll PCI IO

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Mask - add argument and description to function comment

+// TODO:    Value - add argument and description to function comment

+// TODO:    Delay - add argument and description to function comment

+// TODO:    Result - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Width > EfiPciIoWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->PollIo (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                          Offset,

+                                          Mask,

+                                          Value,

+                                          Delay,

+                                          Result

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoMemRead (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Performs a PCI Memory Read Cycle

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Mem.Read (

+                                              PciIoDevice->PciRootBridgeIo,

+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                              Offset,

+                                              Count,

+                                              Buffer

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoMemWrite (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Performs a PCI Memory Write Cycle

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Mem.Write (

+                                              PciIoDevice->PciRootBridgeIo,

+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                              Offset,

+                                              Count,

+                                              Buffer

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoIoRead (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Performs a PCI I/O Read Cycle

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Io.Read (

+                                              PciIoDevice->PciRootBridgeIo,

+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                              Offset,

+                                              Count,

+                                              Buffer

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoIoWrite (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Performs a PCI I/O Write Cycle

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Io.Write (

+                                              PciIoDevice->PciRootBridgeIo,

+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                              Offset,

+                                              Count,

+                                              Buffer

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoConfigRead (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT32                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Performs a PCI Configuration Read Cycle

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+  UINT64        Address;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  Address     = Offset;

+  Status      = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Pci.Read (

+                                              PciIoDevice->PciRootBridgeIo,

+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                              Address,

+                                              Count,

+                                              Buffer

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoConfigWrite (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT32                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Performs a PCI Configuration Write Cycle

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    Buffer - add argument and description to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+  UINT64        Address;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  Address     = Offset;

+  Status      = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Pci.Write (

+                                              PciIoDevice->PciRootBridgeIo,

+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                              Address,

+                                              Count,

+                                              Buffer

+                                              );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoCopyMem (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT8                        DestBarIndex,

+  IN     UINT64                       DestOffset,

+  IN     UINT8                        SrcBarIndex,

+  IN     UINT64                       SrcOffset,

+  IN     UINTN                        Count

+  )

+/*++

+

+Routine Description:

+

+  Copy PCI Memory

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Width - add argument and description to function comment

+// TODO:    DestBarIndex - add argument and description to function comment

+// TODO:    DestOffset - add argument and description to function comment

+// TODO:    SrcBarIndex - add argument and description to function comment

+// TODO:    SrcOffset - add argument and description to function comment

+// TODO:    Count - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Width == EfiPciIoWidthFifoUint8  ||

+      Width == EfiPciIoWidthFifoUint16 ||

+      Width == EfiPciIoWidthFifoUint32 ||

+      Width == EfiPciIoWidthFifoUint64 ||

+      Width == EfiPciIoWidthFillUint8  ||

+      Width == EfiPciIoWidthFillUint16 ||

+      Width == EfiPciIoWidthFillUint32 ||

+      Width == EfiPciIoWidthFillUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->CopyMem (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,

+                                          DestOffset,

+                                          SrcOffset,

+                                          Count

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoMap (

+  IN     EFI_PCI_IO_PROTOCOL            *This,

+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                           *HostAddress,

+  IN OUT UINTN                          *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,

+  OUT    VOID                           **Mapping

+  )

+/*++

+

+Routine Description:

+

+  Maps a memory region for DMA

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Operation - add argument and description to function comment

+// TODO:    HostAddress - add argument and description to function comment

+// TODO:    NumberOfBytes - add argument and description to function comment

+// TODO:    DeviceAddress - add argument and description to function comment

+// TODO:    Mapping - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {

+    Operation = Operation + EfiPciOperationBusMasterRead64;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->Map (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,

+                                          HostAddress,

+                                          NumberOfBytes,

+                                          DeviceAddress,

+                                          Mapping

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoUnmap (

+  IN  EFI_PCI_IO_PROTOCOL  *This,

+  IN  VOID                 *Mapping

+  )

+/*++

+

+Routine Description:

+

+  Unmaps a memory region for DMA

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Mapping - add argument and description to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  Status = PciIoDevice->PciRootBridgeIo->Unmap (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          Mapping

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoAllocateBuffer (

+  IN  EFI_PCI_IO_PROTOCOL   *This,

+  IN  EFI_ALLOCATE_TYPE     Type,

+  IN  EFI_MEMORY_TYPE       MemoryType,

+  IN  UINTN                 Pages,

+  OUT VOID                  **HostAddress,

+  IN  UINT64                Attributes

+  )

+/*++

+

+Routine Description:

+

+  Allocates a common buffer for DMA

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Type - add argument and description to function comment

+// TODO:    MemoryType - add argument and description to function comment

+// TODO:    Pages - add argument and description to function comment

+// TODO:    HostAddress - add argument and description to function comment

+// TODO:    Attributes - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  if (Attributes &

+      (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {

+    return EFI_UNSUPPORTED;

+  }

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {

+    Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;

+  }

+

+  Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          Type,

+                                          MemoryType,

+                                          Pages,

+                                          HostAddress,

+                                          Attributes

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoFreeBuffer (

+  IN  EFI_PCI_IO_PROTOCOL   *This,

+  IN  UINTN                 Pages,

+  IN  VOID                  *HostAddress

+  )

+/*++

+

+Routine Description:

+

+  Frees a common buffer 

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Pages - add argument and description to function comment

+// TODO:    HostAddress - add argument and description to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          Pages,

+                                          HostAddress

+                                          );

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoFlush (

+  IN  EFI_PCI_IO_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  Flushes a DMA buffer

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  Status = PciIoDevice->PciRootBridgeIo->Flush (

+                                           PciIoDevice->PciRootBridgeIo

+                                           );

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoGetLocation (

+  IN  EFI_PCI_IO_PROTOCOL  *This,

+  OUT UINTN                *Segment,

+  OUT UINTN                *Bus,

+  OUT UINTN                *Device,

+  OUT UINTN                *Function

+  )

+/*++

+

+Routine Description:

+

+  Gets a PCI device's current bus number, device number, and function number.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Segment - add argument and description to function comment

+// TODO:    Bus - add argument and description to function comment

+// TODO:    Device - add argument and description to function comment

+// TODO:    Function - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE *PciIoDevice;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Segment  = PciIoDevice->PciRootBridgeIo->SegmentNumber;

+  *Bus      = PciIoDevice->BusNumber;

+  *Device   = PciIoDevice->DeviceNumber;

+  *Function = PciIoDevice->FunctionNumber;

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+CheckBarType (

+  IN PCI_IO_DEVICE       *PciIoDevice,

+  UINT8                  BarIndex,

+  PCI_BAR_TYPE           BarType

+  )

+/*++

+

+Routine Description:

+

+  Sets a PCI controllers attributes on a resource range

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    BarType - add argument and description to function comment

+{

+  switch (BarType) {

+

+  case PciBarTypeMem:

+

+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32  &&

+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&

+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&

+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64    ) {

+      return FALSE;

+    }

+

+    return TRUE;

+

+  case PciBarTypeIo:

+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&

+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){

+      return FALSE;

+    }

+

+    return TRUE;

+

+  default:

+    break;

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+ModifyRootBridgeAttributes (

+  IN  PCI_IO_DEVICE                            *PciIoDevice,

+  IN  UINT64                                   Attributes,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation

+  )

+/*++

+

+Routine Description:

+

+  Set new attributes to a Root Bridge

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Attributes - add argument and description to function comment

+// TODO:    Operation - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64      PciRootBridgeSupports;

+  UINT64      PciRootBridgeAttributes;

+  UINT64      NewPciRootBridgeAttributes;

+  EFI_STATUS  Status;

+

+  //

+  // Get the current attributes of this PCI device's PCI Root Bridge

+  //

+  Status = PciIoDevice->PciRootBridgeIo->GetAttributes (

+                                          PciIoDevice->PciRootBridgeIo,

+                                          &PciRootBridgeSupports,

+                                          &PciRootBridgeAttributes

+                                          );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Record the new attribute of the Root Bridge

+  //

+  if (Operation == EfiPciIoAttributeOperationEnable) {

+    NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;

+  } else {

+    NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);

+  }

+ 

+  //

+  // Call the PCI Root Bridge to attempt to modify the attributes

+  //

+  if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {

+

+    Status = PciIoDevice->PciRootBridgeIo->SetAttributes (

+                                            PciIoDevice->PciRootBridgeIo,

+                                            NewPciRootBridgeAttributes,

+                                            NULL,

+                                            NULL

+                                            );

+    if (EFI_ERROR (Status)) {

+      //

+      // The PCI Root Bridge could not modify the attributes, so return the error.

+      //

+      return EFI_UNSUPPORTED;

+    }

+  }

+    

+  //

+  // Also update the attributes for this Root Bridge structure

+  //

+  PciIoDevice->Attributes = NewPciRootBridgeAttributes;

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+SupportPaletteSnoopAttributes (

+  IN  PCI_IO_DEVICE                            *PciIoDevice,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation

+  )

+/*++

+

+Routine Description:

+

+  Check whether this device can be enable/disable to snoop

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Operation - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE *Temp;

+  UINT16        VGACommand;

+

+  //

+  // Snoop attribute can be only modified by GFX

+  //

+  if (!IS_PCI_GFX (&PciIoDevice->Pci)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get the boot VGA on the same segement

+  //

+  Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);

+

+  if (!Temp) {

+    //

+    // If there is no VGA device on the segement, set

+    // this graphics card to decode the palette range

+    //

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // Check these two agents are on the same path

+  //

+  if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {

+    //

+    // they are not on the same path, so snoop can be enabled or disabled

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // Check if they are on the same bus

+  //

+  if (Temp->Parent == PciIoDevice->Parent) {

+

+    PciReadCommandRegister (Temp, &VGACommand);

+

+    //

+    // If they are on the same bus, either one can

+    // be set to snoop, the other set to decode

+    //

+    if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {

+      //

+      // VGA has set to snoop, so GFX can be only set to disable snoop

+      //

+      if (Operation == EfiPciIoAttributeOperationEnable) {

+        return EFI_UNSUPPORTED;

+      }

+    } else {

+      //

+      // VGA has disabled to snoop, so GFX can be only enabled

+      //

+      if (Operation == EfiPciIoAttributeOperationDisable) {

+        return EFI_UNSUPPORTED;

+      }

+    }

+

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // If they are on  the same path but on the different bus

+  // The first agent is set to snoop, the second one set to

+  // decode

+  //

+            

+  if (Temp->BusNumber > PciIoDevice->BusNumber) {

+    //

+    // GFX should be set to decode

+    //

+    if (Operation == EfiPciIoAttributeOperationDisable) {

+      PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);

+      Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;

+    } else {

+      return EFI_UNSUPPORTED;

+    }

+

+  } else {

+    //

+    // GFX should be set to snoop

+    //

+    if (Operation == EfiPciIoAttributeOperationEnable) {

+      PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);

+      Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);

+    } else {

+      return EFI_UNSUPPORTED;

+    }

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoAttributes (

+  IN EFI_PCI_IO_PROTOCOL                       * This,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,

+  IN  UINT64                                   Attributes,

+  OUT UINT64                                   *Result OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Operation - add argument and description to function comment

+// TODO:    Attributes - add argument and description to function comment

+// TODO:    Result - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS    Status;

+

+  PCI_IO_DEVICE *PciIoDevice;

+  PCI_IO_DEVICE *UpStreamBridge;

+  PCI_IO_DEVICE *Temp;

+

+  UINT64        Supports;

+  UINT64        UpStreamAttributes;

+  UINT16        BridgeControl;

+  UINT16        Command;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  switch (Operation) {

+  case EfiPciIoAttributeOperationGet:

+    if (Result == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    *Result = PciIoDevice->Attributes;

+    return EFI_SUCCESS;

+

+  case EfiPciIoAttributeOperationSupported:

+    if (Result == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    *Result = PciIoDevice->Supports;

+    return EFI_SUCCESS;

+

+  case EfiPciIoAttributeOperationSet:

+    Status = PciIoDevice->PciIo.Attributes (

+                                  &(PciIoDevice->PciIo),

+                                  EfiPciIoAttributeOperationEnable,

+                                  Attributes,

+                                  NULL

+                                  );

+    if (EFI_ERROR (Status)) {

+      return EFI_UNSUPPORTED;

+    }

+

+    Status = PciIoDevice->PciIo.Attributes (

+                                  &(PciIoDevice->PciIo),

+                                  EfiPciIoAttributeOperationDisable,

+                                  (~Attributes) & (PciIoDevice->Supports),

+                                  NULL

+                                  );

+    if (EFI_ERROR (Status)) {

+      return EFI_UNSUPPORTED;

+    }

+

+    return EFI_SUCCESS;

+

+  case EfiPciIoAttributeOperationEnable:

+  case EfiPciIoAttributeOperationDisable:

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Just a trick for ENABLE attribute

+  //

+  if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {

+    Attributes &= (PciIoDevice->Supports);

+

+    //

+    // Raise the EFI_P_PC_ENABLE Status code

+    //

+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+      EFI_PROGRESS_CODE,

+      EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,

+      PciIoDevice->DevicePath

+      );

+  }

+

+  //

+  // If no attributes can be supported, then return.

+  // Otherwise, set the attributes that it can support.

+  //

+  Supports = (PciIoDevice->Supports) & Attributes;

+  if (Supports != Attributes) {

+    return EFI_UNSUPPORTED;

+  }

+   

+  //

+  // For Root Bridge, just call RootBridgeIo to set attributes;

+  //

+  if (!PciIoDevice->Parent) {

+    Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);

+    return Status;

+  }

+

+  Command       = 0;

+  BridgeControl = 0;

+

+  //

+  // For PPB & P2C, set relevant attribute bits

+  //

+  if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

+

+    if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {

+      BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;

+    }

+

+    if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {

+      BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;

+    }

+

+    if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {

+      Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;

+    }

+

+  } else {

+    //

+    // Do with the attributes on VGA

+    //

+    if ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) || 

+        (IS_PCI_VGA(&PciIoDevice->Pci) && 

+         ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) || 

+          (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)))) {

+      //

+      // Check if a VGA has been enabled before enabling a new one

+      //

+      if (Operation == EfiPciIoAttributeOperationEnable) {

+        //

+        // Check if there have been an active VGA device on the same segment

+        //

+        Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);

+        if (Temp && Temp != PciIoDevice) {

+          //

+          // An active VGA has been detected, so can not enable another

+          //

+          return EFI_UNSUPPORTED;

+        }

+      }

+    }

+    

+    //

+    // Do with the attributes on GFX

+    //

+    if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {

+

+      if (Operation == EfiPciIoAttributeOperationEnable) {

+        //

+        // Check if snoop can be enabled in current configuration

+        //

+        Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);

+

+        if (EFI_ERROR (Status)) {

+        

+          //

+          // Enable operation is forbidden, so mask the bit in attributes

+          // so as to keep consistent with the actual Status

+          //

+          // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);

+          //

+          //

+          //

+          return EFI_UNSUPPORTED;

+

+        }

+      }

+

+      //

+      // It can be supported, so get ready to set the bit

+      //

+      Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;

+    }

+  }

+

+  if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {

+    Command |= EFI_PCI_COMMAND_IO_SPACE;

+  }

+

+  if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {

+    Command |= EFI_PCI_COMMAND_MEMORY_SPACE;

+  }

+

+  if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {

+    Command |= EFI_PCI_COMMAND_BUS_MASTER;

+  }

+  //

+  // The upstream bridge should be also set to revelant attribute

+  // expect for IO, Mem and BusMaster

+  //

+  UpStreamAttributes = Attributes & 

+                       (~(EFI_PCI_IO_ATTRIBUTE_IO     |

+                          EFI_PCI_IO_ATTRIBUTE_MEMORY |

+                          EFI_PCI_IO_ATTRIBUTE_BUS_MASTER

+                          )

+                        );

+  UpStreamBridge = PciIoDevice->Parent;

+

+  if (Operation == EfiPciIoAttributeOperationEnable) {

+    //

+    // Enable relevant attributes to command register and bridge control register

+    //

+    Status = PciEnableCommandRegister (PciIoDevice, Command);

+    if (BridgeControl) {

+      Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);

+    }

+

+    PciIoDevice->Attributes |= Attributes;

+

+    //

+    // Enable attributes of the upstream bridge

+    //

+    Status = UpStreamBridge->PciIo.Attributes (

+                                    &(UpStreamBridge->PciIo),

+                                    EfiPciIoAttributeOperationEnable,

+                                    UpStreamAttributes,

+                                    NULL

+                                    );

+  } else {

+    

+    //

+    // Disable relevant attributes to command register and bridge control register

+    //

+    Status = PciDisableCommandRegister (PciIoDevice, Command);

+    if (BridgeControl) {

+      Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);

+    }

+

+    PciIoDevice->Attributes &= (~Attributes);

+    Status = EFI_SUCCESS;

+

+  }

+

+  if (EFI_ERROR (Status)) {

+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoGetBarAttributes (

+  IN EFI_PCI_IO_PROTOCOL             * This,

+  IN  UINT8                          BarIndex,

+  OUT UINT64                         *Supports, OPTIONAL

+  OUT VOID                           **Resources OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Supports - add argument and description to function comment

+// TODO:    Resources - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  UINT8                             *Configuration;

+  UINT8                             NumConfig;

+  PCI_IO_DEVICE                     *PciIoDevice;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;

+  EFI_ACPI_END_TAG_DESCRIPTOR       *PtrEnd;

+

+  NumConfig   = 0;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  if (Supports == NULL && Resources == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BarIndex >= PCI_MAX_BAR) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // This driver does not support modifications to the WRITE_COMBINE or

+  // CACHED attributes for BAR ranges.

+  //

+  if (Supports != NULL) {

+    *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;

+  }

+

+  if (Resources != NULL) {

+

+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {

+      NumConfig = 1;

+    }

+

+    Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));

+    if (Configuration == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    ZeroMem (

+      Configuration,

+      sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)

+      );

+

+    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;

+

+    if (NumConfig == 1) {

+      Ptr->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;

+      Ptr->Len          = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;

+

+      Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;

+      Ptr->AddrLen      = PciIoDevice->PciBar[BarIndex].Length;

+      Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;

+

+      switch (PciIoDevice->PciBar[BarIndex].BarType) {

+      case PciBarTypeIo16:

+      case PciBarTypeIo32:

+        //

+        // Io

+        //

+        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;

+        break;

+

+      case PciBarTypeMem32:

+        //

+        // Mem

+        //

+        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;

+        //

+        // 32 bit

+        //

+        Ptr->AddrSpaceGranularity = 32;

+        break;

+

+      case PciBarTypePMem32:

+        //

+        // Mem

+        //

+        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;

+        //

+        // prefechable

+        //

+        Ptr->SpecificFlag = 0x6;

+        //

+        // 32 bit

+        //

+        Ptr->AddrSpaceGranularity = 32;

+        break;

+

+      case PciBarTypeMem64:

+        //

+        // Mem

+        //

+        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;

+        //

+        // 64 bit

+        //

+        Ptr->AddrSpaceGranularity = 64;

+        break;

+

+      case PciBarTypePMem64:

+        //

+        // Mem

+        //

+        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;

+        //

+        // prefechable

+        //

+        Ptr->SpecificFlag = 0x6;

+        //

+        // 64 bit

+        //

+        Ptr->AddrSpaceGranularity = 64;

+        break;

+

+      default:

+        break;

+      }

+

+      Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));

+    }

+    

+    //

+    // put the checksum

+    //

+    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);

+    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;

+    PtrEnd->Checksum  = 0;

+

+    *Resources        = Configuration;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PciIoSetBarAttributes (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     UINT64                       Attributes,

+  IN     UINT8                        BarIndex,

+  IN OUT UINT64                       *Offset,

+  IN OUT UINT64                       *Length

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Attributes - add argument and description to function comment

+// TODO:    BarIndex - add argument and description to function comment

+// TODO:    Offset - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS    Status;

+  PCI_IO_DEVICE *PciIoDevice;

+  UINT64        NonRelativeOffset;

+  UINT64        Supports;

+

+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);

+

+  //

+  // Make sure Offset and Length are not NULL

+  //

+  if (Offset == NULL || Length == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.

+  // If Attributes is not 0, then return EFI_UNSUPPORTED.

+  //

+  Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;

+

+  if (Attributes != (Attributes & Supports)) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Attributes must be supported.  Make sure the BAR range describd by BarIndex, Offset, and

+  // Length are valid for this PCI device.

+  //

+  NonRelativeOffset = *Offset;

+  Status = PciIoVerifyBarAccess (

+            PciIoDevice,

+            BarIndex,

+            PciBarTypeMem,

+            EfiPciIoWidthUint8,

+            (UINT32) *Length,

+            &NonRelativeOffset

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UpStreamBridgesAttributes (

+  IN  PCI_IO_DEVICE                            *PciIoDevice,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,

+  IN  UINT64                                   Attributes

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    Operation - add argument and description to function comment

+// TODO:    Attributes - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE       *Parent;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  Parent = PciIoDevice->Parent;

+

+  while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {

+

+    //

+    // Get the PciIo Protocol

+    //

+    PciIo = &Parent->PciIo;

+

+    PciIo->Attributes (PciIo, Operation, Attributes, NULL);

+

+    Parent = Parent->Parent;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+PciDevicesOnTheSamePath (

+  IN PCI_IO_DEVICE        *PciDevice1,

+  IN PCI_IO_DEVICE        *PciDevice2

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciDevice1 - add argument and description to function comment

+// TODO:    PciDevice2 - add argument and description to function comment

+{

+

+  if (PciDevice1->Parent == PciDevice2->Parent) {

+    return TRUE;

+  }

+

+  if (PciDevice1->BusNumber > PciDevice2->BusNumber) {

+    return PciDeviceExisted (PciDevice1->Parent, PciDevice2);

+  }

+

+  return PciDeviceExisted (PciDevice2->Parent, PciDevice1);

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h
new file mode 100644
index 0000000..5733f59
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.h
@@ -0,0 +1,773 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciIo.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_IO_PROTOCOL_H

+#define _EFI_PCI_IO_PROTOCOL_H

+

+EFI_STATUS

+InitializePciIoInstance (

+  PCI_IO_DEVICE  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciIoVerifyBarAccess (

+  PCI_IO_DEVICE                   *PciIoDevice,

+  UINT8                           BarIndex,

+  PCI_BAR_TYPE                    Type,

+  IN EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN UINTN                        Count,

+  UINT64                          *Offset

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  BarIndex    - TODO: add argument description

+  Type        - TODO: add argument description

+  Width       - TODO: add argument description

+  Count       - TODO: add argument description

+  Offset      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciIoVerifyConfigAccess (

+  PCI_IO_DEVICE                 *PciIoDevice,

+  IN EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN UINTN                      Count,

+  IN UINT64                     *Offset

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  Width       - TODO: add argument description

+  Count       - TODO: add argument description

+  Offset      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoPollMem (

+  IN  EFI_PCI_IO_PROTOCOL        *This,

+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT8                      BarIndex,

+  IN  UINT64                     Offset,

+  IN  UINT64                     Mask,

+  IN  UINT64                     Value,

+  IN  UINT64                     Delay,

+  OUT UINT64                     *Result

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Width     - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Offset    - TODO: add argument description

+  Mask      - TODO: add argument description

+  Value     - TODO: add argument description

+  Delay     - TODO: add argument description

+  Result    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoPollIo (

+  IN  EFI_PCI_IO_PROTOCOL        *This,

+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT8                      BarIndex,

+  IN  UINT64                     Offset,

+  IN  UINT64                     Mask,

+  IN  UINT64                     Value,

+  IN  UINT64                     Delay,

+  OUT UINT64                     *Result

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Width     - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Offset    - TODO: add argument description

+  Mask      - TODO: add argument description

+  Value     - TODO: add argument description

+  Delay     - TODO: add argument description

+  Result    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoMemRead (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Width     - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Offset    - TODO: add argument description

+  Count     - TODO: add argument description

+  Buffer    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoMemWrite (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Width     - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Offset    - TODO: add argument description

+  Count     - TODO: add argument description

+  Buffer    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoIoRead (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Width     - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Offset    - TODO: add argument description

+  Count     - TODO: add argument description

+  Buffer    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoIoWrite (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT8                      BarIndex,

+  IN     UINT64                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Width     - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Offset    - TODO: add argument description

+  Count     - TODO: add argument description

+  Buffer    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoConfigRead (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT32                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Width   - TODO: add argument description

+  Offset  - TODO: add argument description

+  Count   - TODO: add argument description

+  Buffer  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoConfigWrite (

+  IN     EFI_PCI_IO_PROTOCOL        *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT32                     Offset,

+  IN     UINTN                      Count,

+  IN OUT VOID                       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Width   - TODO: add argument description

+  Offset  - TODO: add argument description

+  Count   - TODO: add argument description

+  Buffer  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoCopyMem (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT8                        DestBarIndex,

+  IN     UINT64                       DestOffset,

+  IN     UINT8                        SrcBarIndex,

+  IN     UINT64                       SrcOffset,

+  IN     UINTN                        Count

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This          - TODO: add argument description

+  Width         - TODO: add argument description

+  DestBarIndex  - TODO: add argument description

+  DestOffset    - TODO: add argument description

+  SrcBarIndex   - TODO: add argument description

+  SrcOffset     - TODO: add argument description

+  Count         - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoMap (

+  IN     EFI_PCI_IO_PROTOCOL            *This,

+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                           *HostAddress,

+  IN OUT UINTN                          *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,

+  OUT    VOID                           **Mapping

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This          - TODO: add argument description

+  Operation     - TODO: add argument description

+  HostAddress   - TODO: add argument description

+  NumberOfBytes - TODO: add argument description

+  DeviceAddress - TODO: add argument description

+  Mapping       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoUnmap (

+  IN  EFI_PCI_IO_PROTOCOL  *This,

+  IN  VOID                 *Mapping

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Mapping - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoAllocateBuffer (

+  IN  EFI_PCI_IO_PROTOCOL   *This,

+  IN  EFI_ALLOCATE_TYPE     Type,

+  IN  EFI_MEMORY_TYPE       MemoryType,

+  IN  UINTN                 Pages,

+  OUT VOID                  **HostAddress,

+  IN  UINT64                Attributes

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Type        - TODO: add argument description

+  MemoryType  - TODO: add argument description

+  Pages       - TODO: add argument description

+  HostAddress - TODO: add argument description

+  Attributes  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoFreeBuffer (

+  IN  EFI_PCI_IO_PROTOCOL   *This,

+  IN  UINTN                 Pages,

+  IN  VOID                  *HostAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Pages       - TODO: add argument description

+  HostAddress - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoFlush (

+  IN  EFI_PCI_IO_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoGetLocation (

+  IN  EFI_PCI_IO_PROTOCOL  *This,

+  OUT UINTN                *Segment,

+  OUT UINTN                *Bus,

+  OUT UINTN                *Device,

+  OUT UINTN                *Function

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Segment   - TODO: add argument description

+  Bus       - TODO: add argument description

+  Device    - TODO: add argument description

+  Function  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+CheckBarType (

+  IN PCI_IO_DEVICE       *PciIoDevice,

+  UINT8                  BarIndex,

+  PCI_BAR_TYPE           BarType

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  BarIndex    - TODO: add argument description

+  BarType     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ModifyRootBridgeAttributes (

+  IN  PCI_IO_DEVICE                            *PciIoDevice,

+  IN  UINT64                                   Attributes,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  Attributes  - TODO: add argument description

+  Operation   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SupportPaletteSnoopAttributes (

+  IN  PCI_IO_DEVICE                            *PciIoDevice,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  Operation   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoAttributes (

+  IN EFI_PCI_IO_PROTOCOL                       * This,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,

+  IN  UINT64                                   Attributes,

+  OUT UINT64                                   *Result OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Operation   - TODO: add argument description

+  Attributes  - TODO: add argument description

+  Result      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoGetBarAttributes (

+  IN EFI_PCI_IO_PROTOCOL             * This,

+  IN  UINT8                          BarIndex,

+  OUT UINT64                         *Supports, OPTIONAL

+  OUT VOID                           **Resources OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  BarIndex  - TODO: add argument description

+  Supports  - TODO: add argument description

+  Resources - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PciIoSetBarAttributes (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     UINT64                       Attributes,

+  IN     UINT8                        BarIndex,

+  IN OUT UINT64                       *Offset,

+  IN OUT UINT64                       *Length

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  Attributes  - TODO: add argument description

+  BarIndex    - TODO: add argument description

+  Offset      - TODO: add argument description

+  Length      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+UpStreamBridgesAttributes (

+  IN  PCI_IO_DEVICE                            *PciIoDevice,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,

+  IN  UINT64                                   Attributes

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+  Operation   - TODO: add argument description

+  Attributes  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+PciDevicesOnTheSamePath (

+  IN PCI_IO_DEVICE        *PciDevice1,

+  IN PCI_IO_DEVICE        *PciDevice2

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDevice1  - TODO: add argument description

+  PciDevice2  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c
new file mode 100644
index 0000000..11a0c29
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c
@@ -0,0 +1,1398 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciLib.c 

+  

+Abstract:

+

+  PCI Bus Driver Lib file

+  It abstracts some functions that can be different 

+  between light PCI bus driver and full PCI bus driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+

+EFI_PCI_HOTPLUG_REQUEST_PROTOCOL gPciHotPlugRequest = {

+  PciHotPlugRequestNotify

+};

+

+

+VOID

+InstallHotPlugRequestProtocol (

+  IN EFI_STATUS *Status

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  Status   - A pointer to the status.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_HANDLE  Handle;

+

+  Handle = NULL;

+  *Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiPciHotPlugRequestProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &gPciHotPlugRequest

+                  );

+}

+

+VOID

+InstallPciHotplugGuid (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  PciIoDevice    -  A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  if (IS_CARDBUS_BRIDGE (&PciIoDevice->Parent->Pci)) {

+

+    Status = gBS->InstallProtocolInterface (

+                    &PciIoDevice->Handle,

+                    &gEfiPciHotplugDeviceGuid,

+                    EFI_NATIVE_INTERFACE,

+                    NULL

+                    );

+  }

+}

+

+VOID

+UninstallPciHotplugGuid (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  PciIoDevice    - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->OpenProtocol (

+                  PciIoDevice->Handle,

+                  &gEfiPciHotplugDeviceGuid,

+                  NULL,

+                  NULL,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // This may triger CardBus driver to stop for

+    // Pccard devices opened the GUID via BY_DRIVER

+    //

+    Status = gBS->UninstallProtocolInterface (

+                    PciIoDevice->Handle,

+                    &gEfiPciHotplugDeviceGuid,

+                    NULL

+                    );

+  }

+}

+

+VOID

+GetBackPcCardBar (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+  PciIoDevice      - A pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT32  Address;

+

+  //

+  // Read PciBar information from the bar register

+  //

+  if (!gFullEnumeration) {

+

+    Address = 0;

+    PciIoDevice->PciIo.Pci.Read (

+                            &(PciIoDevice->PciIo),

+                            EfiPciIoWidthUint32,

+                            0x1c,

+                            1,

+                            &Address

+                            );

+

+    (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress  = (UINT64) (Address);

+    (PciIoDevice->PciBar)[P2C_MEM_1].Length       = 0x2000000;

+    (PciIoDevice->PciBar)[P2C_MEM_1].BarType      = PciBarTypeMem32;

+

+    Address = 0;

+    PciIoDevice->PciIo.Pci.Read (

+                            &(PciIoDevice->PciIo),

+                            EfiPciIoWidthUint32,

+                            0x20,

+                            1,

+                            &Address

+                            );

+    (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress  = (UINT64) (Address);

+    (PciIoDevice->PciBar)[P2C_MEM_2].Length       = 0x2000000;

+    (PciIoDevice->PciBar)[P2C_MEM_2].BarType      = PciBarTypePMem32;

+

+    Address = 0;

+    PciIoDevice->PciIo.Pci.Read (

+                            &(PciIoDevice->PciIo),

+                            EfiPciIoWidthUint32,

+                            0x2c,

+                            1,

+                            &Address

+                            );

+    (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address);

+    (PciIoDevice->PciBar)[P2C_IO_1].Length      = 0x100;

+    (PciIoDevice->PciBar)[P2C_IO_1].BarType     = PciBarTypeIo16;

+

+    Address = 0;

+    PciIoDevice->PciIo.Pci.Read (

+                            &(PciIoDevice->PciIo),

+                            EfiPciIoWidthUint32,

+                            0x34,

+                            1,

+                            &Address

+                            );

+    (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address);

+    (PciIoDevice->PciBar)[P2C_IO_2].Length      = 0x100;

+    (PciIoDevice->PciBar)[P2C_IO_2].BarType     = PciBarTypeIo16;

+

+  }

+

+  if (gPciHotPlugInit != NULL) {

+    GetResourcePaddingForHpb (PciIoDevice);

+  }

+}

+

+EFI_STATUS

+RemoveRejectedPciDevices (

+  EFI_HANDLE        RootBridgeHandle,

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+  RootBridgeHandle   - An efi handle.

+  Bridge             - An pointer to the PCI_IO_DEVICE.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE   *Temp;

+  LIST_ENTRY      *CurrentLink;

+  LIST_ENTRY      *LastLink;

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (IS_PCI_BRIDGE (&Temp->Pci)) {

+      //

+      // Remove rejected devices recusively

+      //

+      RemoveRejectedPciDevices (RootBridgeHandle, Temp);

+    } else {

+      //

+      // Skip rejection for all PPBs, while detect rejection for others

+      //

+      if (IsPciDeviceRejected (Temp)) {

+                

+        //

+        // For P2C, remove all devices on it

+        //

+                

+        if (!IsListEmpty (&Temp->ChildList)) {

+          RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);

+        }

+        

+        //

+        // Finally remove itself

+        //

+        

+        LastLink = CurrentLink->BackLink;

+        RemoveEntryList (CurrentLink);

+        FreePciDevice (Temp);

+

+        CurrentLink = LastLink;

+      }

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciHostBridgeResourceAllocator (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  Host brige resource allocator.

+

+Arguments:

+

+  PciResAlloc  - A pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.

+

+Returns:

+

+  EFI Status.

+

+--*/

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE                         *RootBridgeDev;

+  EFI_HANDLE                            RootBridgeHandle;

+  VOID                                  *AcpiConfig;

+  EFI_STATUS                            Status;

+  UINT64                                IoBase;

+  UINT64                                Mem32Base;

+  UINT64                                PMem32Base;

+  UINT64                                Mem64Base;

+  UINT64                                PMem64Base;

+  UINT64                                IoResStatus;

+  UINT64                                Mem32ResStatus;

+  UINT64                                PMem32ResStatus;

+  UINT64                                Mem64ResStatus;

+  UINT64                                PMem64ResStatus;

+  UINT64                                MaxOptionRomSize;

+  PCI_RESOURCE_NODE                     *IoBridge;

+  PCI_RESOURCE_NODE                     *Mem32Bridge;

+  PCI_RESOURCE_NODE                     *PMem32Bridge;

+  PCI_RESOURCE_NODE                     *Mem64Bridge;

+  PCI_RESOURCE_NODE                     *PMem64Bridge;

+  PCI_RESOURCE_NODE                     IoPool;

+  PCI_RESOURCE_NODE                     Mem32Pool;

+  PCI_RESOURCE_NODE                     PMem32Pool;

+  PCI_RESOURCE_NODE                     Mem64Pool;

+  PCI_RESOURCE_NODE                     PMem64Pool;

+  BOOLEAN                               ReAllocate;

+  REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA        HandleExtendedData;

+  REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA  AllocFailExtendedData;

+

+  //

+  // Reallocate flag

+  //

+  ReAllocate = FALSE;

+

+  //

+  // It will try several times if the resource allocation fails

+  //

+  while (TRUE) {

+

+    //

+    // Initialize resource pool

+    //    

+    InitializeResourcePool (&IoPool, PciBarTypeIo16);

+    InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);

+    InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);

+    InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);

+    InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);

+

+    RootBridgeDev     = NULL;

+    RootBridgeHandle  = 0;

+

+    while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+      //

+      // Get RootBridg Device by handle

+      //

+      RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+

+      if (RootBridgeDev == NULL) {

+        return EFI_NOT_FOUND;

+      }

+

+      //

+      // Create the entire system resource map from the information collected by

+      // enumerator. Several resource tree was created

+      //

+

+      IoBridge = CreateResourceNode (

+                  RootBridgeDev,

+                  0,

+                  0xFFF,

+                  0,

+                  PciBarTypeIo16,

+                  PciResUsageTypical

+                  );

+

+      Mem32Bridge = CreateResourceNode (

+                      RootBridgeDev,

+                      0,

+                      0xFFFFF,

+                      0,

+                      PciBarTypeMem32,

+                      PciResUsageTypical

+                      );

+

+      PMem32Bridge = CreateResourceNode (

+                      RootBridgeDev,

+                      0,

+                      0xFFFFF,

+                      0,

+                      PciBarTypePMem32,

+                      PciResUsageTypical

+                      );

+

+      Mem64Bridge = CreateResourceNode (

+                      RootBridgeDev,

+                      0,

+                      0xFFFFF,

+                      0,

+                      PciBarTypeMem64,

+                      PciResUsageTypical

+                      );

+

+      PMem64Bridge = CreateResourceNode (

+                      RootBridgeDev,

+                      0,

+                      0xFFFFF,

+                      0,

+                      PciBarTypePMem64,

+                      PciResUsageTypical

+                      );

+

+      //

+      // Create resourcemap by going through all the devices subject to this root bridge

+      //

+      Status = CreateResourceMap (

+                RootBridgeDev,

+                IoBridge,

+                Mem32Bridge,

+                PMem32Bridge,

+                Mem64Bridge,

+                PMem64Bridge

+                );

+

+      //

+      // Get the max ROM size that the root bridge can process

+      //

+      RootBridgeDev->RomSize = Mem32Bridge->Length;

+

+      //

+      // Skip to enlarge the resource request during realloction

+      //

+      if (!ReAllocate) {

+        //

+        // Get Max Option Rom size for current root bridge

+        //

+        MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);

+

+        //

+        // Enlarger the mem32 resource to accomdate the option rom

+        // if the mem32 resource is not enough to hold the rom

+        //

+        if (MaxOptionRomSize > Mem32Bridge->Length) {

+

+          Mem32Bridge->Length     = MaxOptionRomSize;

+          RootBridgeDev->RomSize  = MaxOptionRomSize;

+

+          //

+          // Alignment should be adjusted as well

+          //

+          if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {

+            Mem32Bridge->Alignment = MaxOptionRomSize - 1;

+          }

+        }

+      }    

+      

+      //

+      // Based on the all the resource tree, contruct ACPI resource node to

+      // submit the resource aperture to pci host bridge protocol

+      //

+      Status = ConstructAcpiResourceRequestor (

+                RootBridgeDev,

+                IoBridge,

+                Mem32Bridge,

+                PMem32Bridge,

+                Mem64Bridge,

+                PMem64Bridge,

+                &AcpiConfig

+                );

+

+      //

+      // Insert these resource nodes into the database

+      //

+      InsertResourceNode (&IoPool, IoBridge);

+      InsertResourceNode (&Mem32Pool, Mem32Bridge);

+      InsertResourceNode (&PMem32Pool, PMem32Bridge);

+      InsertResourceNode (&Mem64Pool, Mem64Bridge);

+      InsertResourceNode (&PMem64Pool, PMem64Bridge);

+

+      if (Status == EFI_SUCCESS) {

+        //

+        // Submit the resource requirement

+        //

+        Status = PciResAlloc->SubmitResources (

+                                PciResAlloc,

+                                RootBridgeDev->Handle,

+                                AcpiConfig

+                                );

+      }

+

+      //

+      // Free acpi resource node

+      //

+      if (AcpiConfig != NULL) {

+        gBS->FreePool (AcpiConfig);

+      }

+

+      if (EFI_ERROR (Status)) {

+        //

+        // Destroy all the resource tree

+        //

+        DestroyResourceTree (&IoPool);

+        DestroyResourceTree (&Mem32Pool);

+        DestroyResourceTree (&PMem32Pool);

+        DestroyResourceTree (&Mem64Pool);

+        DestroyResourceTree (&PMem64Pool);

+        return Status;

+      }

+    }

+

+    //

+    // Notify pci bus driver starts to program the resource

+    //

+   

+    Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);

+

+    if (!EFI_ERROR (Status)) {

+      //

+      // Allocation succeed, then continue the following

+      //

+      break;

+    }

+      

+    //

+    // If the resource allocation is unsuccessful, free resources on bridge

+    //

+            

+    RootBridgeDev     = NULL;

+    RootBridgeHandle  = 0;

+

+    IoResStatus       = EFI_RESOURCE_SATISFIED;

+    Mem32ResStatus    = EFI_RESOURCE_SATISFIED;

+    PMem32ResStatus   = EFI_RESOURCE_SATISFIED;

+    Mem64ResStatus    = EFI_RESOURCE_SATISFIED;

+    PMem64ResStatus   = EFI_RESOURCE_SATISFIED;

+

+    while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+      //

+      // Get RootBridg Device by handle

+      //

+      RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+      if (RootBridgeDev == NULL) {

+        return EFI_NOT_FOUND;

+      }

+ 

+      //

+      // Get host bridge handle for status report

+      //

+      HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;

+

+      //

+      // Get acpi resource node for all the resource types

+      //

+      AcpiConfig = NULL;

+

+      Status = PciResAlloc->GetProposedResources (

+                              PciResAlloc,

+                              RootBridgeDev->Handle,

+                              &AcpiConfig

+                              );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      if (AcpiConfig != NULL) {

+        //

+        // Adjust resource allocation policy for each RB

+        //

+        GetResourceAllocationStatus (

+          AcpiConfig,

+          &IoResStatus,

+          &Mem32ResStatus,

+          &PMem32ResStatus,

+          &Mem64ResStatus,

+          &PMem64ResStatus

+          );

+        gBS->FreePool (AcpiConfig);

+      }

+    }

+    //

+    // End while

+    //

+

+    //

+    // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code

+    //

+    //

+    // It is very difficult to follow the spec here

+    // Device path , Bar index can not be get here

+    //

+    ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));

+

+    REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+          EFI_PROGRESS_CODE,

+          EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,

+          (VOID *) &AllocFailExtendedData,

+          sizeof (AllocFailExtendedData)

+          );

+

+    Status = PciHostBridgeAdjustAllocation (

+              &IoPool,

+              &Mem32Pool,

+              &PMem32Pool,

+              &Mem64Pool,

+              &PMem64Pool,

+              IoResStatus,

+              Mem32ResStatus,

+              PMem32ResStatus,

+              Mem64ResStatus,

+              PMem64ResStatus

+              );

+

+    //

+    // Destroy all the resource tree

+    //

+    DestroyResourceTree (&IoPool);

+    DestroyResourceTree (&Mem32Pool);

+    DestroyResourceTree (&PMem32Pool);

+    DestroyResourceTree (&Mem64Pool);

+    DestroyResourceTree (&PMem64Pool);

+

+    NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    ReAllocate = TRUE;

+

+  }

+  //

+  // End main while

+  //

+

+  //

+  // Raise the EFI_IOB_PCI_RES_ALLOC status code

+  //

+  REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+        EFI_PROGRESS_CODE,

+        EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,

+        (VOID *) &HandleExtendedData,

+        sizeof (HandleExtendedData)

+        );

+

+  //

+  // Notify pci bus driver starts to program the resource

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);

+

+  RootBridgeDev     = NULL;

+

+  RootBridgeHandle  = 0;

+

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // Get RootBridg Device by handle

+    //

+    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_NOT_FOUND;

+    }

+    

+    //

+    // Get acpi resource node for all the resource types

+    //

+    AcpiConfig = NULL;

+    Status = PciResAlloc->GetProposedResources (

+                            PciResAlloc,

+                            RootBridgeDev->Handle,

+                            &AcpiConfig

+                            );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Get the resource base by interpreting acpi resource node

+    //

+    //

+    GetResourceBase (

+      AcpiConfig,

+      &IoBase,

+      &Mem32Base,

+      &PMem32Base,

+      &Mem64Base,

+      &PMem64Base

+      );

+

+    //

+    // Process option rom for this root bridge

+    //

+    Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);

+

+    //

+    // Create the entire system resource map from the information collected by

+    // enumerator. Several resource tree was created

+    //

+    Status = GetResourceMap (

+              RootBridgeDev,

+              &IoBridge,

+              &Mem32Bridge,

+              &PMem32Bridge,

+              &Mem64Bridge,

+              &PMem64Bridge,

+              &IoPool,

+              &Mem32Pool,

+              &PMem32Pool,

+              &Mem64Pool,

+              &PMem64Pool

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Program IO resources

+    //

+    ProgramResource (

+      IoBase,

+      IoBridge

+      );

+

+    //

+    // Program Mem32 resources

+    //

+    ProgramResource (

+      Mem32Base,

+      Mem32Bridge

+      );

+

+    //

+    // Program PMem32 resources

+    //

+    ProgramResource (

+      PMem32Base,

+      PMem32Bridge

+      );

+

+    //

+    // Program Mem64 resources

+    //

+    ProgramResource (

+      Mem64Base,

+      Mem64Bridge

+      );

+

+    //

+    // Program PMem64 resources

+    //

+    ProgramResource (

+      PMem64Base,

+      PMem64Bridge

+      );

+

+    if (AcpiConfig != NULL) {

+      gBS->FreePool (AcpiConfig);

+    }

+  }

+

+  //

+  // Destroy all the resource tree

+  //

+  DestroyResourceTree (&IoPool);

+  DestroyResourceTree (&Mem32Pool);

+  DestroyResourceTree (&PMem32Pool);

+  DestroyResourceTree (&Mem64Pool);

+  DestroyResourceTree (&PMem64Pool);

+

+  //

+  // Notify the resource allocation phase is to end

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciScanBus (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber,

+  OUT UINT8                             *SubBusNumber,

+  OUT UINT8                             *PaddedBusRange

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to assign bus number to the given PCI bus system

+

+Arguments:

+

+  Bridge         - A pointer to the PCI_IO_DEVICE structure.

+  StartBusNumber - The start bus number.

+  SubBusNumber   - A pointer to the sub bus number.

+  PaddedBusRange - A pointer to the padded bus range.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  PCI_TYPE00                        Pci;

+  UINT8                             Device;

+  UINT8                             Func;

+  UINT64                            Address;

+  UINTN                             SecondBus;

+  UINT16                            Register;

+  UINTN                             HpIndex;

+  PCI_IO_DEVICE                     *PciDevice;

+  EFI_EVENT                         Event;

+  EFI_HPC_STATE                     State;

+  UINT64                            PciAddress;

+  EFI_HPC_PADDING_ATTRIBUTES        Attributes;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

+  UINT16                            BusRange;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;

+  BOOLEAN                           BusPadding;

+

+  PciRootBridgeIo = Bridge->PciRootBridgeIo;

+  SecondBus       = 0;

+  Register        = 0;

+  State           = 0;

+  Attributes      = 0;

+  BusRange        = 0;

+

+  ResetAllPpbBusReg (Bridge, StartBusNumber);

+

+  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {

+    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {

+

+      //

+      // Check to see whether a pci device is present

+      //

+      Status = PciDevicePresent (

+                PciRootBridgeIo,

+                &Pci,

+                StartBusNumber,

+                Device,

+                Func

+                );

+

+      if (EFI_ERROR (Status)) {

+        if (Func == 0) {

+          //

+          // Skip sub functions, this is not a multi function device

+          //

+          Func = PCI_MAX_FUNC;

+        }

+

+        continue;

+      }

+      

+      //

+      // Get the PCI device information

+      //

+      Status = PciSearchDevice (

+                Bridge,

+                &Pci,

+                StartBusNumber,

+                Device,

+                Func,

+                &PciDevice

+                );

+

+      ASSERT (!EFI_ERROR (Status));

+

+      PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);

+

+      if (!IS_PCI_BRIDGE (&Pci)) {

+        //

+        // PCI bridges will be called later

+        // Here just need for PCI device or PCI to cardbus controller

+        // EfiPciBeforeChildBusEnumeration for PCI Device Node

+        //

+        PreprocessController (

+            PciDevice,

+            PciDevice->BusNumber,

+            PciDevice->DeviceNumber,

+            PciDevice->FunctionNumber,

+            EfiPciBeforeChildBusEnumeration

+            );

+      }

+      

+      //

+      // For Pci Hotplug controller devcie only

+      //

+      if (gPciHotPlugInit != NULL) {

+        //

+        // Check if it is a Hotplug PCI controller

+        //

+        if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) {

+

+          if (!gPciRootHpcData[HpIndex].Initialized) {

+

+            Status = CreateEventForHpc (HpIndex, &Event);

+

+            ASSERT (!EFI_ERROR (Status));

+

+            Status = gPciHotPlugInit->InitializeRootHpc (

+                                        gPciHotPlugInit,

+                                        gPciRootHpcPool[HpIndex].HpcDevicePath,

+                                        PciAddress,

+                                        Event,

+                                        &State

+                                        );

+                                        

+            PreprocessController (

+              PciDevice,

+              PciDevice->BusNumber,

+              PciDevice->DeviceNumber,

+              PciDevice->FunctionNumber,

+              EfiPciBeforeChildBusEnumeration

+            );                                        

+            continue;

+          }

+        }

+      }

+

+      if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) {

+        //

+        // For PPB

+        // Get the bridge information

+        //

+        BusPadding = FALSE;

+        if (gPciHotPlugInit != NULL) {

+

+          if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {

+          

+            //

+            // If it is initialized, get the padded bus range

+            //

+            Status = gPciHotPlugInit->GetResourcePadding (

+                                        gPciHotPlugInit,

+                                        gPciRootHpcPool[HpIndex].HpbDevicePath,

+                                        PciAddress,

+                                        &State,

+                                        (VOID **) &Descriptors,

+                                        &Attributes

+                                        );

+

+            if (EFI_ERROR (Status)) {

+              return Status;

+            }

+

+            BusRange = 0;

+            Status = PciGetBusRange (

+                      &Descriptors,

+                      NULL,

+                      NULL,

+                      &BusRange

+                      );

+

+            gBS->FreePool (Descriptors);

+

+            if (EFI_ERROR (Status)) {

+              return Status;

+            }

+

+            BusPadding = TRUE;

+          }

+        }

+

+        (*SubBusNumber)++;

+        SecondBus = *SubBusNumber;

+

+        Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);

+        Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);

+

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint16,

+                                        Address,

+                                        1,

+                                        &Register

+                                        );

+

+

+        //

+        // If it is PPB, resursively search down this bridge

+        //

+        if (IS_PCI_BRIDGE (&Pci)) {

+          

+          //

+          // Initialize SubBusNumber to Maximum bus number

+          //

+          Register  = 0xFF;

+          Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+          Status = PciRootBridgeIo->Pci.Write (

+                                          PciRootBridgeIo,

+                                          EfiPciWidthUint8,

+                                          Address,

+                                          1,

+                                          &Register

+                                          );

+

+          //

+          // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige

+          //

+          PreprocessController (

+            PciDevice,

+            PciDevice->BusNumber,

+            PciDevice->DeviceNumber,

+            PciDevice->FunctionNumber,

+            EfiPciBeforeChildBusEnumeration

+            );

+

+          Status = PciScanBus (

+                    PciDevice,

+                    (UINT8) (SecondBus),

+                    SubBusNumber,

+                    PaddedBusRange

+                    );

+

+          if (EFI_ERROR (Status)) {

+            return EFI_DEVICE_ERROR;

+          }

+        }

+

+        if (BusPadding) {

+          //

+          // Ensure the device is enabled and initialized

+          //

+          if ((Attributes == EfiPaddingPciRootBridge) &&

+              (State & EFI_HPC_STATE_ENABLED)         &&

+              (State & EFI_HPC_STATE_INITIALIZED)     ) {

+            *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);

+          } else {

+            *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);

+          }

+        }

+

+        //

+        // Set the current maximum bus number under the PPB

+        //

+        Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);

+

+        Status = PciRootBridgeIo->Pci.Write (

+                                        PciRootBridgeIo,

+                                        EfiPciWidthUint8,

+                                        Address,

+                                        1,

+                                        SubBusNumber

+                                        );

+      }

+

+      if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {

+

+        //

+        // Skip sub functions, this is not a multi function device

+        //

+        Func = PCI_MAX_FUNC;

+      }

+

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciRootBridgeP2CProcess (

+  IN PCI_IO_DEVICE *Bridge

+  )

+/*++

+

+Routine Description:

+  

+    Process Option Rom on this host bridge

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  LIST_ENTRY      *CurrentLink;

+  PCI_IO_DEVICE   *Temp;

+  EFI_HPC_STATE   State;

+  UINT64          PciAddress;

+  EFI_STATUS      Status;

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {

+

+      if (gPciHotPlugInit && Temp->Allocated) {

+        

+        //

+        // Raise the EFI_IOB_PCI_HPC_INIT status code

+        //

+        REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+          EFI_PROGRESS_CODE,

+          EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_HPC_INIT,

+          Temp->DevicePath

+          );

+

+        PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);

+        Status = gPciHotPlugInit->InitializeRootHpc (

+                                    gPciHotPlugInit,

+                                    Temp->DevicePath,

+                                    PciAddress,

+                                    NULL,

+                                    &State

+                                    );

+

+        if (!EFI_ERROR (Status)) {

+          Status = PciBridgeEnumerator (Temp);

+

+          if (EFI_ERROR (Status)) {

+            return Status;

+          }

+        }

+

+        CurrentLink = CurrentLink->ForwardLink;

+        continue;

+

+      }

+    }

+

+    if (!IsListEmpty (&Temp->ChildList)) {

+      Status = PciRootBridgeP2CProcess (Temp);

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciHostBridgeP2CProcess (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciResAlloc - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_HANDLE    RootBridgeHandle;

+  PCI_IO_DEVICE *RootBridgeDev;

+  EFI_STATUS    Status;

+

+  RootBridgeHandle = NULL;

+

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // Get RootBridg Device by handle

+    //

+    RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_NOT_FOUND;

+    }

+

+    Status = PciRootBridgeP2CProcess (RootBridgeDev);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciHostBridgeEnumerator (

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  This function is used to enumerate the entire host bridge 

+  in a given platform

+

+Arguments:

+

+  PciResAlloc   - A pointer to the resource allocate protocol.

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_HANDLE                        RootBridgeHandle;

+  PCI_IO_DEVICE                     *RootBridgeDev;

+  EFI_STATUS                        Status;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;

+  UINT16                            MinBus;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

+

+  InitializeHotPlugSupport ();

+

+  //

+  // Notify the bus allocation phase is about to start

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);

+

+  RootBridgeHandle = NULL;

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // if a root bridge instance is found, create root bridge device for it

+    //

+

+    RootBridgeDev = CreateRootBridge (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    //

+    // Enumerate all the buses under this root bridge

+    //

+

+    Status = PciRootBridgeEnumerator (

+              PciResAlloc,

+              RootBridgeDev

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    DestroyRootBridge (RootBridgeDev);

+

+    //

+    // Error proccess here

+    //

+  }

+

+  //                                                            

+  // Notify the bus allocation phase is finished for the first time

+  //                                                            

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);

+    

+                  

+  if (gPciHotPlugInit != NULL) {

+    //

+    // Wait for all HPC initialized

+    //

+    Status = AllRootHPCInitialized (STALL_1_SECOND * 15);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Notify the bus allocation phase is about to start for the 2nd time

+    //

+    NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);

+  

+    RootBridgeHandle = NULL;

+    while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+      //

+      // if a root bridge instance is found, create root bridge device for it

+      //

+

+      RootBridgeDev = CreateRootBridge (RootBridgeHandle);

+

+      if (RootBridgeDev == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // Enumerate all the buses under this root bridge

+      //

+

+      Status = PciRootBridgeEnumerator (

+                PciResAlloc,

+                RootBridgeDev

+                );

+

+      DestroyRootBridge (RootBridgeDev);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    }

+      

+    //

+    // Notify the bus allocation phase is to end

+    //

+    NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);

+  }

+

+  //

+  // Notify the resource allocation phase is to start

+  //

+  NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);

+

+  RootBridgeHandle = NULL;

+  while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {

+

+    //

+    // if a root bridge instance is found, create root bridge device for it

+    //

+

+    RootBridgeDev = CreateRootBridge (RootBridgeHandle);

+

+    if (RootBridgeDev == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Status = StartManagingRootBridge (RootBridgeDev);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;

+    Status          = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Determine root bridge attribute by calling interface of Pcihostbridge

+    // protocol

+    //

+    DetermineRootBridgeAttributes (

+      PciResAlloc,

+      RootBridgeDev

+      );

+

+    //

+    // Collect all the resource information under this root bridge

+    // A database that records all the information about pci device subject to this

+    // root bridge will then be created

+    //

+    Status = PciPciDeviceInfoCollector (

+              RootBridgeDev,

+              (UINT8) MinBus

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    InsertRootBridge (RootBridgeDev);

+

+    //

+    // Record the hostbridge handle

+    //

+    AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h
new file mode 100644
index 0000000..1e89445
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.h
@@ -0,0 +1,247 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciLib.h

+  

+Abstract:

+

+  PCI Bus Driver Lib header file

+  It abstracts some functions that can be different 

+  between light PCI bus driver and full PCI bus driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_LIB_H

+#define _EFI_PCI_LIB_H

+

+VOID

+InstallHotPlugRequestProtocol (

+  IN  EFI_STATUS                    *Status

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Status  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+InstallPciHotplugGuid (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+UninstallPciHotplugGuid (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+GetBackPcCardBar (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RemoveRejectedPciDevices (

+  EFI_HANDLE        RootBridgeHandle,

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootBridgeHandle  - TODO: add argument description

+  Bridge            - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciHostBridgeResourceAllocator (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciScanBus (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber,

+  OUT UINT8                             *SubBusNumber,

+  OUT UINT8                             *PaddedBusRange

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge          - TODO: add argument description

+  StartBusNumber  - TODO: add argument description

+  SubBusNumber    - TODO: add argument description

+  PaddedBusRange  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciRootBridgeP2CProcess (

+  IN PCI_IO_DEVICE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciHostBridgeP2CProcess (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciHostBridgeEnumerator (

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciResAlloc - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c
new file mode 100644
index 0000000..5819fd6
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c
@@ -0,0 +1,543 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciOptionRomSupport.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciResourceSupport.h"

+

+EFI_STATUS

+GetOpRomInfo (

+  IN PCI_IO_DEVICE    *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT8                           RomBarIndex;

+  UINT32                          AllOnes;

+  UINT64                          Address;

+  EFI_STATUS                      Status;

+  UINT8                           Bus;

+  UINT8                           Device;

+  UINT8                           Function;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  Bus             = PciIoDevice->BusNumber;

+  Device          = PciIoDevice->DeviceNumber;

+  Function        = PciIoDevice->FunctionNumber;

+

+  PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;

+

+  //

+  // offset is 48 if is not ppb

+  //

+

+  //

+  // 0x30

+  //

+  RomBarIndex = PCI_DEVICE_ROMBAR;

+

+  if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {

+    //

+    // if is ppb

+    //

+

+    //

+    // 0x38

+    //

+    RomBarIndex = PCI_BRIDGE_ROMBAR;

+  }

+  //

+  // the bit0 is 0 to prevent the enabling of the Rom address decoder

+  //

+  AllOnes = 0xfffffffe;

+  Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);

+

+  Status = PciRootBridgeIo->Pci.Write (

+                                  PciRootBridgeIo,

+                                  EfiPciWidthUint32,

+                                  Address,

+                                  1,

+                                  &AllOnes

+                                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // read back

+  //

+  Status = PciRootBridgeIo->Pci.Read (

+                                  PciRootBridgeIo,

+                                  EfiPciWidthUint32,

+                                  Address,

+                                  1,

+                                  &AllOnes

+                                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  AllOnes &= 0xFFFFFFFC;

+  if ((AllOnes == 0) || (AllOnes == 0xFFFFFFFC)) {

+    return EFI_NOT_FOUND;

+  }

+

+  PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+LoadOpRomImage (

+  IN PCI_IO_DEVICE   *PciDevice,

+  IN UINT64          RomBase

+  )

+/*++

+

+Routine Description:

+ 

+    Load option rom image for specified PCI device

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    PciDevice - add argument and description to function comment

+// TODO:    RomBase - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  UINT8                     RomBarIndex;

+  UINT8                     Indicator;

+  UINT16                    OffsetPcir;

+  UINT32                    RomBarOffset;

+  UINT32                    RomBar;

+  UINT64                    Temp;

+  EFI_STATUS                retStatus;

+  BOOLEAN                   FirstCheck;

+  UINT8                     *Image;

+  PCI_EXPANSION_ROM_HEADER  *RomHeader;

+  PCI_DATA_STRUCTURE        *RomPcir;

+  UINT64                    RomSize;

+  UINT64                    RomImageSize;

+  UINT8                     *RomInMemory;

+

+  RomSize       = PciDevice->RomSize;

+

+  Indicator     = 0;

+  RomImageSize  = 0;

+  RomInMemory   = NULL;

+  Temp          = 0;

+

+  //

+  // Get the RomBarIndex

+  //

+

+  //

+  // 0x30

+  //

+  RomBarIndex = PCI_DEVICE_ROMBAR;

+  if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {

+    //

+    // if is ppb

+    //

+

+    //

+    // 0x38

+    //

+    RomBarIndex = PCI_BRIDGE_ROMBAR;

+  }

+  //

+  // Allocate memory for Rom header and PCIR

+  //

+  RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));

+  if (RomHeader == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));

+  if (RomPcir == NULL) {

+    gBS->FreePool (RomHeader);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  RomBar = (UINT32) RomBase;

+

+  //

+  // Enable RomBar

+  //

+  RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);

+

+  RomBarOffset  = RomBar;

+  retStatus     = EFI_NOT_FOUND;

+  FirstCheck    = TRUE;

+

+  do {

+    PciDevice->PciRootBridgeIo->Mem.Read (

+                                      PciDevice->PciRootBridgeIo,

+                                      EfiPciWidthUint8,

+                                      RomBarOffset,

+                                      sizeof (PCI_EXPANSION_ROM_HEADER),

+                                      (UINT8 *) RomHeader

+                                      );

+

+    if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {

+      RomBarOffset = RomBarOffset + 512;

+      if (FirstCheck) {

+        break;

+      } else {

+        RomImageSize = RomImageSize + 512;

+        continue;

+      }

+    }

+

+    FirstCheck  = FALSE;

+    OffsetPcir  = RomHeader->PcirOffset;

+    PciDevice->PciRootBridgeIo->Mem.Read (

+                                      PciDevice->PciRootBridgeIo,

+                                      EfiPciWidthUint8,

+                                      RomBarOffset + OffsetPcir,

+                                      sizeof (PCI_DATA_STRUCTURE),

+                                      (UINT8 *) RomPcir

+                                      );

+    Indicator     = RomPcir->Indicator;

+    RomImageSize  = RomImageSize + RomPcir->ImageLength * 512;

+    RomBarOffset  = RomBarOffset + RomPcir->ImageLength * 512;

+  } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));

+

+  if (RomImageSize > 0) {

+    retStatus = EFI_SUCCESS;

+    Image     = AllocatePool ((UINT32) RomImageSize);

+    if (Image == NULL) {

+      RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);

+      gBS->FreePool (RomHeader);

+      gBS->FreePool (RomPcir);

+      return EFI_OUT_OF_RESOURCES;

+    }

+    

+    //

+    // Copy Rom image into memory

+    //

+    PciDevice->PciRootBridgeIo->Mem.Read (

+                                      PciDevice->PciRootBridgeIo,

+                                      EfiPciWidthUint8,

+                                      RomBar,

+                                      (UINT32) RomImageSize,

+                                      Image

+                                      );

+    RomInMemory = Image;

+  }

+

+  RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);

+

+  PciDevice->PciIo.RomSize  = RomImageSize;

+  PciDevice->PciIo.RomImage = RomInMemory;

+

+  PciRomAddImageMapping (

+    NULL,

+    PciDevice->PciRootBridgeIo->SegmentNumber,

+    PciDevice->BusNumber,

+    PciDevice->DeviceNumber,

+    PciDevice->FunctionNumber,

+    (UINT64) (UINTN) PciDevice->PciIo.RomImage,

+    PciDevice->PciIo.RomSize

+    );

+

+  //

+  // Free allocated memory

+  //

+  gBS->FreePool (RomHeader);

+  gBS->FreePool (RomPcir);

+

+  return retStatus;

+}

+

+EFI_STATUS

+RomDecode (

+  IN PCI_IO_DEVICE   *PciDevice,

+  IN UINT8           RomBarIndex,

+  IN UINT32          RomBar,

+  IN BOOLEAN         Enable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    PciDevice - add argument and description to function comment

+// TODO:    RomBarIndex - add argument and description to function comment

+// TODO:    RomBar - add argument and description to function comment

+// TODO:    Enable - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT32              Value32;

+  UINT32              Offset;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+

+  PciIo = &PciDevice->PciIo;

+  if (Enable) {

+    //

+    // Clear all bars

+    //

+    for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {

+      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);

+    }

+    

+    //

+    // set the Rom base address: now is hardcode

+    // enable its decoder

+    //

+    Value32 = RomBar | 0x1;

+    PciIo->Pci.Write (

+                PciIo,

+                (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,

+                RomBarIndex,

+                1,

+                &Value32

+                );

+

+    //

+    // Programe all upstream bridge

+    //

+    ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE);

+

+    //

+    // Setting the memory space bit in the function's command register

+    //

+    PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);

+

+  } else {

+    

+    //

+    // disable command register decode to memory

+    //

+    PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);

+

+    //

+    // Destroy the programmed bar in all the upstream bridge.

+    //

+    ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE);

+

+    //

+    // disable rom decode

+    //

+    Value32 = 0xFFFFFFFE;

+    PciIo->Pci.Write (

+                PciIo,

+                (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,

+                RomBarIndex,

+                1,

+                &Value32

+                );

+

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+ProcessOpRomImage (

+  PCI_IO_DEVICE   *PciDevice

+  )

+/*++

+

+Routine Description:

+

+  Process the oprom image.

+  

+Arguments:

+  PciDevice       A pointer to a pci device.

+

+Returns:

+

+  EFI Status.

+  

+--*/

+{

+  UINT8                         Indicator;

+  UINT32                        ImageSize;

+  UINT16                        ImageOffset;

+  VOID                          *RomBar;

+  UINT8                         *RomBarOffset;

+  EFI_HANDLE                    ImageHandle;

+  EFI_STATUS                    Status;

+  EFI_STATUS                    retStatus;

+  BOOLEAN                       FirstCheck;

+  BOOLEAN                       SkipImage;

+  UINT32                        DestinationSize;

+  UINT32                        ScratchSize;

+  UINT8                         *Scratch;

+  VOID                          *ImageBuffer;

+  VOID                          *DecompressedImageBuffer;

+  UINT32                        ImageLength;

+  EFI_DECOMPRESS_PROTOCOL       *Decompress;

+  EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;

+  PCI_DATA_STRUCTURE            *Pcir;

+

+  Indicator = 0;

+

+  //

+  // Get the Address of the Rom image

+  //

+  RomBar        = PciDevice->PciIo.RomImage;

+  RomBarOffset  = (UINT8 *) RomBar;

+  retStatus     = EFI_NOT_FOUND;

+  FirstCheck    = TRUE;

+

+  do {

+    EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;

+    if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {

+      RomBarOffset = RomBarOffset + 512;

+      if (FirstCheck) {

+        break;

+      } else {

+        continue;

+      }

+    }

+

+    FirstCheck  = FALSE;

+    Pcir        = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);

+    ImageSize   = (UINT32) (Pcir->ImageLength * 512);

+    Indicator   = Pcir->Indicator;

+

+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && 

+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {

+

+      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)  ||

+          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {

+

+        ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;

+        ImageSize               = (UINT32) (EfiRomHeader->InitializationSize * 512);

+

+        ImageBuffer             = (VOID *) (RomBarOffset + ImageOffset);

+        ImageLength             = ImageSize - (UINT32)ImageOffset;

+        DecompressedImageBuffer = NULL;

+

+        //

+        // decompress here if needed

+        //

+        SkipImage = FALSE;

+        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {

+          SkipImage = TRUE;

+        }

+

+        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {

+          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);

+          if (EFI_ERROR (Status)) {

+            SkipImage = TRUE;

+          } else {

+            SkipImage = TRUE;

+            Status = Decompress->GetInfo (

+                                  Decompress,

+                                  ImageBuffer,

+                                  ImageLength,

+                                  &DestinationSize,

+                                  &ScratchSize

+                                  );

+            if (!EFI_ERROR (Status)) {

+              DecompressedImageBuffer = NULL;

+              DecompressedImageBuffer = AllocatePool (DestinationSize);

+              if (DecompressedImageBuffer != NULL) {

+                Scratch = AllocatePool (ScratchSize);

+                if (Scratch != NULL) {

+                  Status = Decompress->Decompress (

+                                        Decompress,

+                                        ImageBuffer,

+                                        ImageLength,

+                                        DecompressedImageBuffer,

+                                        DestinationSize,

+                                        Scratch,

+                                        ScratchSize

+                                        );

+                  if (!EFI_ERROR (Status)) {

+                    ImageBuffer = DecompressedImageBuffer;

+                    ImageLength = DestinationSize;

+                    SkipImage   = FALSE;

+                  }

+

+                  gBS->FreePool (Scratch);

+                }

+              }

+            }

+          }

+        }

+

+        if (!SkipImage) {

+          //

+          // load image and start image

+          //

+          Status = gBS->LoadImage (

+                          FALSE,

+                          gPciBusDriverBinding.DriverBindingHandle,

+                          PciDevice->Handle,

+                          ImageBuffer,

+                          ImageLength,

+                          &ImageHandle

+                          );

+          if (!EFI_ERROR (Status)) {

+            Status = gBS->StartImage (ImageHandle, NULL, NULL);

+            if (!EFI_ERROR (Status)) {

+              AddDriver (PciDevice, ImageHandle);

+              PciRomAddImageMapping (

+                ImageHandle,

+                PciDevice->PciRootBridgeIo->SegmentNumber,

+                PciDevice->BusNumber,

+                PciDevice->DeviceNumber,

+                PciDevice->FunctionNumber,

+                (UINT64) (UINTN) PciDevice->PciIo.RomImage,

+                PciDevice->PciIo.RomSize

+                );

+              retStatus = EFI_SUCCESS;

+            }

+          }

+        }

+

+        RomBarOffset = RomBarOffset + ImageSize;

+      } else {

+        RomBarOffset = RomBarOffset + ImageSize;

+      }

+    } else {

+      RomBarOffset = RomBarOffset + ImageSize;

+    }

+

+  } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));

+

+  return retStatus;

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h
new file mode 100644
index 0000000..2bb11bf
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.h
@@ -0,0 +1,119 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciOptionRomSupport.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_OP_ROM_SUPPORT_H

+#define _EFI_PCI_OP_ROM_SUPPORT_H

+

+EFI_STATUS

+GetOpRomInfo (

+  IN PCI_IO_DEVICE    *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+LoadOpRomImage (

+  IN PCI_IO_DEVICE   *PciDevice,

+  IN UINT64          RomBase

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDevice - TODO: add argument description

+  RomBase   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RomDecode (

+  IN PCI_IO_DEVICE   *PciDevice,

+  IN UINT8           RomBarIndex,

+  IN UINT32          RomBar,

+  IN BOOLEAN         Enable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDevice   - TODO: add argument description

+  RomBarIndex - TODO: add argument description

+  RomBar      - TODO: add argument description

+  Enable      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProcessOpRomImage (

+  PCI_IO_DEVICE   *PciDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c
new file mode 100644
index 0000000..f871c86
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.c
@@ -0,0 +1,83 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciPowerManagement.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+

+EFI_STATUS

+ResetPowerManagementFeature (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  This function is intended to turn off PWE assertion and

+  put the device to D0 state if the device supports

+  PCI Power Management.

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+  UINT8       PowerManagementRegBlock;

+  UINT16      PMCSR;

+

+  PowerManagementRegBlock = 0;

+

+  Status = LocateCapabilityRegBlock (

+            PciIoDevice,

+            EFI_PCI_CAPABILITY_ID_PMI,

+            &PowerManagementRegBlock,

+            NULL

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Turn off the PWE assertion and put the device into D0 State

+  //

+  PMCSR = 0x8000;

+

+  //

+  // Write PMCSR

+  //

+  PciIoDevice->PciIo.Pci.Write (

+                          &PciIoDevice->PciIo,

+                          EfiPciIoWidthUint16,

+                          PowerManagementRegBlock + 4,

+                          1,

+                          &PMCSR

+                          );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h
new file mode 100644
index 0000000..f33f7ab
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciPowerManagement.h
@@ -0,0 +1,48 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciPowerManagement.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_POWER_MANAGEMENT_H

+#define _EFI_PCI_POWER_MANAGEMENT_H

+

+EFI_STATUS

+ResetPowerManagementFeature (

+  IN PCI_IO_DEVICE *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c
new file mode 100644
index 0000000..8919b42
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.c
@@ -0,0 +1,2276 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciResourceSupport.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciResourceSupport.h"

+#include "PciCommand.h"

+

+EFI_STATUS

+SkipVGAAperture (

+  OUT UINT64   *Start,

+  IN  UINT64   Length

+  )

+/*++

+

+Routine Description:

+

+  The function is used to skip VGA range

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Start - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64  Original;

+  UINT64  Mask;

+  UINT64  StartOffset;

+  UINT64  LimitOffset;

+

+  //

+  // For legacy VGA, bit 10 to bit 15 is not decoded

+  //

+  Mask        = 0x3FF;

+

+  Original    = *Start;

+  StartOffset = Original & Mask;

+  LimitOffset = ((*Start) + Length - 1) & Mask;

+  if (LimitOffset >= VGABASE1) {

+    *Start = *Start - StartOffset + VGALIMIT2 + 1;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+SkipIsaAliasAperture (

+  OUT UINT64   *Start,

+  IN  UINT64   Length

+  )

+/*++

+

+Routine Description:

+

+  This function is used to skip ISA aliasing aperture

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Start - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  UINT64  Original;

+  UINT64  Mask;

+  UINT64  StartOffset;

+  UINT64  LimitOffset;

+

+  //

+  // For legacy ISA, bit 10 to bit 15 is not decoded

+  //

+  Mask        = 0x3FF;

+

+  Original    = *Start;

+  StartOffset = Original & Mask;

+  LimitOffset = ((*Start) + Length - 1) & Mask;

+

+  if (LimitOffset >= ISABASE) {

+    *Start = *Start - StartOffset + ISALIMIT + 1;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InsertResourceNode (

+  PCI_RESOURCE_NODE *Bridge,

+  PCI_RESOURCE_NODE *ResNode

+  )

+/*++

+

+Routine Description:

+

+  This function inserts a resource node into the resource list.

+  The resource list is sorted in descend order.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    ResNode - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  LIST_ENTRY        *CurrentLink;

+  PCI_RESOURCE_NODE *Temp;

+  UINT64            ResNodeAlignRest;

+  UINT64            TempAlignRest;

+

+  InsertHeadList (&Bridge->ChildList, &ResNode->Link);

+

+  CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink;

+  while (CurrentLink != &Bridge->ChildList) {

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (ResNode->Alignment > Temp->Alignment) {

+      break;

+    } else if (ResNode->Alignment == Temp->Alignment) {

+      ResNodeAlignRest  = ResNode->Length & ResNode->Alignment;

+      TempAlignRest     = Temp->Length & Temp->Alignment;

+      if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) {

+        break;

+      }

+    }

+

+    SwapListEntries (&ResNode->Link, CurrentLink);

+

+    CurrentLink = ResNode->Link.ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+MergeResourceTree (

+  PCI_RESOURCE_NODE *Dst,

+  PCI_RESOURCE_NODE *Res,

+  BOOLEAN           TypeMerge

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to merge two different resource tree in need of

+  resoure degradation. For example, if a upstream PPB doesn't support,

+  prefetchable memory decoding, the PCI bus driver will choose to call this function

+  to merge prefectchable memory resource list into normal memory list.

+

+  If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource

+  type.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Dst - add argument and description to function comment

+// TODO:    Res - add argument and description to function comment

+// TODO:    TypeMerge - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  LIST_ENTRY        *CurrentLink;

+  PCI_RESOURCE_NODE *Temp;

+

+  while (!IsListEmpty (&Res->ChildList)) {

+    CurrentLink = Res->ChildList.ForwardLink;

+

+    Temp        = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (TypeMerge) {

+      Temp->ResType = Dst->ResType;

+    }

+

+    RemoveEntryList (CurrentLink);

+    InsertResourceNode (Dst, Temp);

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CalculateApertureIo16 (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  This function is used to calculate the IO16 aperture

+  for a bridge.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  UINT64            Aperture;

+  LIST_ENTRY        *CurrentLink;

+  PCI_RESOURCE_NODE *Node;

+  UINT64            offset;

+

+  //

+  // Always assume there is ISA device and VGA device on the platform

+  // will be customized later

+  //

+  Aperture = 0;

+

+  if (!Bridge) {

+    return EFI_SUCCESS;

+  }

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  //

+  // Assume the bridge is aligned

+  //

+  while (CurrentLink != &Bridge->ChildList) {

+

+    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    //

+    // Consider the aperture alignment

+    //

+    offset = Aperture & (Node->Alignment);

+

+    if (offset) {

+

+      Aperture = Aperture + (Node->Alignment + 1) - offset;

+

+    }

+

+    //

+    // IsaEnable and VGAEnable can not be implemented now.

+    // If both of them are enabled, then the IO resource would

+    // become too limited to meet the requirement of most of devices.

+    //

+

+    Node->Offset = Aperture;

+

+    //

+    // Increment aperture by the length of node

+    //

+    Aperture += Node->Length;

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  //

+  // At last, adjust the aperture with the bridge's

+  // alignment

+  //

+  offset = Aperture & (Bridge->Alignment);

+

+  if (offset) {

+    Aperture = Aperture + (Bridge->Alignment + 1) - offset;

+  }

+

+  Bridge->Length = Aperture;

+  //

+  // At last, adjust the bridge's alignment to the first child's alignment

+  // if the bridge has at least one child

+  //

+  CurrentLink = Bridge->ChildList.ForwardLink;

+  if (CurrentLink != &Bridge->ChildList) {

+    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

+    if (Node->Alignment > Bridge->Alignment) {

+      Bridge->Alignment = Node->Alignment;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CalculateResourceAperture (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  This function is used to calculate the resource aperture

+  for a given bridge device

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT64            Aperture;

+  LIST_ENTRY        *CurrentLink;

+  PCI_RESOURCE_NODE *Node;

+

+  UINT64            offset;

+

+  Aperture = 0;

+

+  if (!Bridge) {

+    return EFI_SUCCESS;

+  }

+

+  if (Bridge->ResType == PciBarTypeIo16) {

+    return CalculateApertureIo16 (Bridge);

+  }

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  //

+  // Assume the bridge is aligned

+  //

+  while (CurrentLink != &Bridge->ChildList) {

+

+    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    //

+    // Apply padding resource if available

+    //

+        

+    offset = Aperture & (Node->Alignment);

+

+    if (offset) {

+

+      Aperture = Aperture + (Node->Alignment + 1) - offset;

+

+    }

+

+    //

+    // Recode current aperture as a offset

+    // this offset will be used in future real allocation

+    //

+    Node->Offset = Aperture;

+

+    //

+    // Increment aperture by the length of node

+    //

+    Aperture += Node->Length;

+

+    //

+    // Consider the aperture alignment

+    //

+    

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  //

+  // At last, adjust the aperture with the bridge's

+  // alignment

+  //

+  offset = Aperture & (Bridge->Alignment);

+  if (offset) {

+    Aperture = Aperture + (Bridge->Alignment + 1) - offset;

+  }

+

+  //

+  // If the bridge has already padded the resource and the

+  // amount of padded resource is larger, then keep the

+  // padded resource

+  //

+  if (Bridge->Length < Aperture) {

+    Bridge->Length = Aperture;

+  }

+  

+  //

+  // At last, adjust the bridge's alignment to the first child's alignment

+  // if the bridge has at least one child

+  //

+  CurrentLink = Bridge->ChildList.ForwardLink;

+  if (CurrentLink != &Bridge->ChildList) {

+    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

+    if (Node->Alignment > Bridge->Alignment) {

+      Bridge->Alignment = Node->Alignment;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetResourceFromDevice (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciDev - add argument and description to function comment

+// TODO:    IoNode - add argument and description to function comment

+// TODO:    Mem32Node - add argument and description to function comment

+// TODO:    PMem32Node - add argument and description to function comment

+// TODO:    Mem64Node - add argument and description to function comment

+// TODO:    PMem64Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  UINT8             Index;

+  PCI_RESOURCE_NODE *Node;

+  BOOLEAN           ResourceRequested;

+

+  Node              = NULL;

+  ResourceRequested = FALSE;

+

+  for (Index = 0; Index < PCI_MAX_BAR; Index++) {

+

+    switch ((PciDev->PciBar)[Index].BarType) {

+

+    case PciBarTypeMem32:

+

+      Node = CreateResourceNode (

+              PciDev,

+              (PciDev->PciBar)[Index].Length,

+              (PciDev->PciBar)[Index].Alignment,

+              Index,

+              PciBarTypeMem32,

+              PciResUsageTypical

+              );

+

+      InsertResourceNode (

+        Mem32Node,

+        Node

+        );

+

+      ResourceRequested = TRUE;

+      break;

+

+    case PciBarTypeMem64:

+

+      Node = CreateResourceNode (

+              PciDev,

+              (PciDev->PciBar)[Index].Length,

+              (PciDev->PciBar)[Index].Alignment,

+              Index,

+              PciBarTypeMem64,

+              PciResUsageTypical

+              );

+

+      InsertResourceNode (

+        Mem64Node,

+        Node

+        );

+

+      ResourceRequested = TRUE;

+      break;

+

+    case PciBarTypePMem64:

+

+      Node = CreateResourceNode (

+              PciDev,

+              (PciDev->PciBar)[Index].Length,

+              (PciDev->PciBar)[Index].Alignment,

+              Index,

+              PciBarTypePMem64,

+              PciResUsageTypical

+              );

+

+      InsertResourceNode (

+        PMem64Node,

+        Node

+        );

+

+      ResourceRequested = TRUE;

+      break;

+

+    case PciBarTypePMem32:

+

+      Node = CreateResourceNode (

+              PciDev,

+              (PciDev->PciBar)[Index].Length,

+              (PciDev->PciBar)[Index].Alignment,

+              Index,

+              PciBarTypePMem32,

+              PciResUsageTypical

+              );

+

+      InsertResourceNode (

+        PMem32Node,

+        Node

+        );

+      ResourceRequested = TRUE;

+      break;

+

+    case PciBarTypeIo16:

+    case PciBarTypeIo32:

+

+      Node = CreateResourceNode (

+              PciDev,

+              (PciDev->PciBar)[Index].Length,

+              (PciDev->PciBar)[Index].Alignment,

+              Index,

+              PciBarTypeIo16,

+              PciResUsageTypical

+              );

+

+      InsertResourceNode (

+        IoNode,

+        Node

+        );

+      ResourceRequested = TRUE;

+      break;

+

+    case PciBarTypeUnknown:

+      break;

+

+    default:

+      break;

+    }

+  }

+

+  //

+  // If there is no resource requested from this device,

+  // then we indicate this device has been allocated naturally.

+  //

+  if (!ResourceRequested) {

+    PciDev->Allocated = TRUE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+PCI_RESOURCE_NODE *

+CreateResourceNode (

+  IN PCI_IO_DEVICE         *PciDev,

+  IN UINT64                Length,

+  IN UINT64                Alignment,

+  IN UINT8                 Bar,

+  IN PCI_BAR_TYPE          ResType,

+  IN PCI_RESOURCE_USAGE    ResUsage

+  )

+/*++

+

+Routine Description:

+

+  This function is used to create a resource node

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciDev - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    Alignment - add argument and description to function comment

+// TODO:    Bar - add argument and description to function comment

+// TODO:    ResType - add argument and description to function comment

+// TODO:    ResUsage - add argument and description to function comment

+{

+  EFI_STATUS        Status;

+  PCI_RESOURCE_NODE *Node;

+

+  Status  = 0;

+  Node    = NULL;

+

+  Node    = AllocatePool (sizeof (PCI_RESOURCE_NODE));

+  if (Node == NULL) {

+    return NULL;

+  }

+

+  ZeroMem (Node, sizeof (PCI_RESOURCE_NODE));

+

+  Node->Signature     = PCI_RESOURCE_SIGNATURE;

+  Node->PciDev        = PciDev;

+  Node->Length        = Length;

+  Node->Alignment     = Alignment;

+  Node->Bar           = Bar;

+  Node->ResType       = ResType;

+  Node->Reserved      = FALSE;

+  Node->ResourceUsage = ResUsage;

+  InitializeListHead (&Node->ChildList);

+  return Node;

+}

+

+EFI_STATUS

+CreateResourceMap (

+  IN PCI_IO_DEVICE     *Bridge,

+  IN PCI_RESOURCE_NODE *IoNode,

+  IN PCI_RESOURCE_NODE *Mem32Node,

+  IN PCI_RESOURCE_NODE *PMem32Node,

+  IN PCI_RESOURCE_NODE *Mem64Node,

+  IN PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  This routine is used to extract resource request from

+  device node list.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    IoNode - add argument and description to function comment

+// TODO:    Mem32Node - add argument and description to function comment

+// TODO:    PMem32Node - add argument and description to function comment

+// TODO:    Mem64Node - add argument and description to function comment

+// TODO:    PMem64Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE     *Temp;

+  EFI_STATUS        Status;

+  PCI_RESOURCE_NODE *IoBridge;

+  PCI_RESOURCE_NODE *Mem32Bridge;

+  PCI_RESOURCE_NODE *PMem32Bridge;

+  PCI_RESOURCE_NODE *Mem64Bridge;

+  PCI_RESOURCE_NODE *PMem64Bridge;

+  LIST_ENTRY        *CurrentLink;

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  while (CurrentLink && CurrentLink != &Bridge->ChildList) {

+

+    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

+

+    //

+    // Create resource nodes for this device by scanning the

+    // Bar array in the device private data

+    // If the upstream bridge doesn't support this device,

+    // no any resource node will be created for this device

+    //

+    GetResourceFromDevice (

+      Temp,

+      IoNode,

+      Mem32Node,

+      PMem32Node,

+      Mem64Node,

+      PMem64Node

+      );

+

+    if (IS_PCI_BRIDGE (&Temp->Pci)) {

+

+      //

+      // If the device has children, create a bridge resource node for this PPB

+      // Note: For PPB, memory aperture is aligned with 1MB and IO aperture

+      // is aligned with 4KB

+      // This device is typically a bridge device like PPB and P2C

+      //

+      IoBridge = CreateResourceNode (

+                  Temp,

+                  0,

+                  0xFFF,

+                  PPB_IO_RANGE,

+                  PciBarTypeIo16,

+                  PciResUsageTypical

+                  ); //0x1000 aligned

+      

+      Mem32Bridge = CreateResourceNode (

+                      Temp,

+                      0,

+                      0xFFFFF,

+                      PPB_MEM32_RANGE,

+                      PciBarTypeMem32,

+                      PciResUsageTypical

+                      );

+

+      PMem32Bridge = CreateResourceNode (

+                      Temp,

+                      0,

+                      0xFFFFF,

+                      PPB_PMEM32_RANGE,

+                      PciBarTypePMem32,

+                      PciResUsageTypical

+                      );

+

+      Mem64Bridge = CreateResourceNode (

+                      Temp,

+                      0,

+                      0xFFFFF,

+                      PPB_MEM64_RANGE,

+                      PciBarTypeMem64,

+                      PciResUsageTypical

+                      );

+

+      PMem64Bridge = CreateResourceNode (

+                      Temp,

+                      0,

+                      0xFFFFF,

+                      PPB_PMEM64_RANGE,

+                      PciBarTypePMem64,

+                      PciResUsageTypical

+                      );

+

+      //

+      // Recursively create resouce map on this bridge

+      //

+      Status = CreateResourceMap (

+                Temp,

+                IoBridge,

+                Mem32Bridge,

+                PMem32Bridge,

+                Mem64Bridge,

+                PMem64Bridge

+                );

+

+      if (ResourceRequestExisted (IoBridge)) {

+        InsertResourceNode (

+          IoNode,

+          IoBridge

+          );

+      } else {

+        gBS->FreePool (IoBridge);

+        IoBridge = NULL;

+      }

+

+      //

+      // If there is node under this resource bridge,

+      // then calculate bridge's aperture of this type

+      // and insert it into the respective resource tree.

+      // If no, delete this resource bridge

+      //

+      if (ResourceRequestExisted (Mem32Bridge)) {

+        InsertResourceNode (

+          Mem32Node,

+          Mem32Bridge

+          );

+      } else {

+        gBS->FreePool (Mem32Bridge);

+        Mem32Bridge = NULL;

+      }

+

+      //

+      // If there is node under this resource bridge,

+      // then calculate bridge's aperture of this type

+      // and insert it into the respective resource tree.

+      // If no, delete this resource bridge

+      //

+      if (ResourceRequestExisted (PMem32Bridge)) {

+        InsertResourceNode (

+          PMem32Node,

+          PMem32Bridge

+          );

+      } else {

+        gBS->FreePool (PMem32Bridge);

+        PMem32Bridge = NULL;

+      }

+

+      //

+      // If there is node under this resource bridge,

+      // then calculate bridge's aperture of this type

+      // and insert it into the respective resource tree.

+      // If no, delete this resource bridge

+      //

+      if (ResourceRequestExisted (Mem64Bridge)) {

+        InsertResourceNode (

+          Mem64Node,

+          Mem64Bridge

+          );

+      } else {

+        gBS->FreePool (Mem64Bridge);

+        Mem64Bridge = NULL;

+      }

+

+      //

+      // If there is node under this resource bridge,

+      // then calculate bridge's aperture of this type

+      // and insert it into the respective resource tree.

+      // If no, delete this resource bridge

+      //

+      if (ResourceRequestExisted (PMem64Bridge)) {

+        InsertResourceNode (

+          PMem64Node,

+          PMem64Bridge

+          );

+      } else {

+        gBS->FreePool (PMem64Bridge);

+        PMem64Bridge = NULL;

+      }

+

+    }

+

+    //

+    // If it is P2C, apply hard coded resource padding

+    //

+    //

+    if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {

+      ResourcePaddingForCardBusBridge (

+        Temp,

+        IoNode,

+        Mem32Node,

+        PMem32Node,

+        Mem64Node,

+        PMem64Node

+        );

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+  //

+  //

+  // To do some platform specific resource padding ...

+  //

+  Status = ResourcePaddingPolicy (

+            Bridge,

+            IoNode,

+            Mem32Node,

+            PMem32Node,

+            Mem64Node,

+            PMem64Node

+            );

+

+  //

+  // Degrade resource if necessary

+  //

+  DegradeResource (

+    Bridge,

+    Mem32Node,

+    PMem32Node,

+    Mem64Node,

+    PMem64Node

+    );

+

+  //

+  // Calculate resource aperture for this bridge device

+  //

+  CalculateResourceAperture (Mem32Node);

+  CalculateResourceAperture (PMem32Node);

+  CalculateResourceAperture (Mem64Node);

+  CalculateResourceAperture (PMem64Node);

+  CalculateResourceAperture (IoNode);

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+ResourcePaddingPolicy (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  This function is used to do the resource padding for a specific platform

+

+Arguments:

+

+  PciDev        - A pointer to the PCI_IO_DEVICE structrue.    

+  IoNode        - A pointer to the PCI_RESOURCE_NODE structrue.

+  Mem32Node     - A pointer to the PCI_RESOURCE_NODE structrue.

+  PMem32Node    - A pointer to the PCI_RESOURCE_NODE structrue.

+  Mem64Node     - A pointer to the PCI_RESOURCE_NODE structrue.

+  PMem64Node    - A pointer to the PCI_RESOURCE_NODE structrue.

+

+Returns:

+  Status code

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  //

+  // Create padding resource node

+  //

+  if (PciDev->ResourcePaddingDescriptors != NULL) {

+    ApplyResourcePadding (

+      PciDev,

+      IoNode,

+      Mem32Node,

+      PMem32Node,

+      Mem64Node,

+      PMem64Node

+      );

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+DegradeResource (

+  IN PCI_IO_DEVICE     *Bridge,

+  IN PCI_RESOURCE_NODE *Mem32Node,

+  IN PCI_RESOURCE_NODE *PMem32Node,

+  IN PCI_RESOURCE_NODE *Mem64Node,

+  IN PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  This function is used to degrade resource if the upstream bridge 

+  doesn't support certain resource. Degradation path is 

+  PMEM64 -> MEM64  -> MEM32

+  PMEM64 -> PMEM32 -> MEM32

+  IO32   -> IO16

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    Mem32Node - add argument and description to function comment

+// TODO:    PMem32Node - add argument and description to function comment

+// TODO:    Mem64Node - add argument and description to function comment

+// TODO:    PMem64Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  //

+  // If bridge doesn't support Prefetchable

+  // memory64, degrade it to Mem64

+  //

+  if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {

+    MergeResourceTree (

+      PMem32Node,

+      PMem64Node,

+      TRUE

+      );

+  } else {

+    //

+    // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32

+    //

+    if (PMem32Node != NULL) {

+      MergeResourceTree (

+        PMem32Node,

+        PMem64Node,

+        TRUE

+        );

+    }

+  }

+

+

+  //

+  // If bridge doesn't support Mem64

+  // degrade it to mem32

+  //

+  if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {

+    MergeResourceTree (

+      Mem32Node,

+      Mem64Node,

+      TRUE

+      );

+  }

+

+  //

+  // If bridge doesn't support Pmem32

+  // degrade it to mem32

+  //

+  if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) {

+    MergeResourceTree (

+      Mem32Node,

+      PMem32Node,

+      TRUE

+      );

+  }

+

+  //

+  // if bridge supports combined Pmem Mem decoding

+  // merge these two type of resource

+  //

+  if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {

+    MergeResourceTree (

+      Mem32Node,

+      PMem32Node,

+      FALSE

+      );

+

+    MergeResourceTree (

+      Mem64Node,

+      PMem64Node,

+      FALSE

+      );

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+BridgeSupportResourceDecode (

+  IN PCI_IO_DEVICE *Bridge,

+  IN UINT32        Decode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  Decode  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  /*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+  if ((Bridge->Decodes) & Decode) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+ProgramResource (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  This function is used to program the resource allocated 

+  for each resource node

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Base - add argument and description to function comment

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  LIST_ENTRY        *CurrentLink;

+  PCI_RESOURCE_NODE *Node;

+  EFI_STATUS        Status;

+

+  if (Base == gAllOne) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  CurrentLink = Bridge->ChildList.ForwardLink;

+

+  while (CurrentLink != &Bridge->ChildList) {

+

+    Node = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) {

+

+      if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {

+        ProgramP2C (Base, Node);

+      } else {

+        ProgramBar (Base, Node);

+      }

+    } else {

+      Status = ProgramResource (Base + Node->Offset, Node);

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      ProgramPpbApperture (Base, Node);

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ProgramBar (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Node

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    Base - add argument and description to function comment

+// TODO:    Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINT64              Address;

+  UINT32              Address32;

+

+  Address = 0;

+  PciIo   = &(Node->PciDev->PciIo);

+

+  Address = Base + Node->Offset;

+

+  //

+  // Indicate pci bus driver has allocated

+  // resource for this device

+  // It might be a temporary solution here since

+  // pci device could have multiple bar

+  //

+  Node->PciDev->Allocated = TRUE;

+

+  switch ((Node->PciDev->PciBar[Node->Bar]).BarType) {

+

+  case PciBarTypeIo16:

+  case PciBarTypeIo32:

+  case PciBarTypeMem32:

+  case PciBarTypePMem32:

+

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                (Node->PciDev->PciBar[Node->Bar]).Offset,

+                1,

+                &Address

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+

+    break;

+

+  case PciBarTypeMem64:

+  case PciBarTypePMem64:

+

+    Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);

+

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                (Node->PciDev->PciBar[Node->Bar]).Offset,

+                1,

+                &Address32

+                );

+

+    Address32 = (UINT32) RShiftU64 (Address, 32);

+

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4),

+                1,

+                &Address32

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+

+    break;

+

+  default:

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ProgramPpbApperture (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Node

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    Base - add argument and description to function comment

+// TODO:    Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINT64              Address;

+  UINT32              Address32;

+

+  Address = 0;

+  //

+  // if no device south of this PPB, return anyway

+  // Apperture is set default in the initialization code

+  //

+  if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) {

+    //

+    // For padding resource node, just ignore when programming

+    //

+    return EFI_SUCCESS;

+  }

+

+  PciIo   = &(Node->PciDev->PciIo);

+  Address = Base + Node->Offset;

+

+  //

+  // Indicate the PPB resource has been allocated

+  //

+  Node->PciDev->Allocated = TRUE;

+

+  switch (Node->Bar) {

+

+  case PPB_BAR_0:

+  case PPB_BAR_1:

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                (Node->PciDev->PciBar[Node->Bar]).Offset,

+                1,

+                &Address

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+

+    break;

+

+  case PPB_IO_RANGE:

+

+    Address32 = ((UINT32) (Address)) >> 8;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint8,

+                0x1C,

+                1,

+                &Address32

+                );

+

+    Address32 >>= 8;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint16,

+                0x30,

+                1,

+                &Address32

+                );

+

+    Address32 = (UINT32) (Address + Node->Length - 1);

+    Address32 = ((UINT32) (Address32)) >> 8;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint8,

+                0x1D,

+                1,

+                &Address32

+                );

+

+    Address32 >>= 8;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint16,

+                0x32,

+                1,

+                &Address32

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    break;

+

+  case PPB_MEM32_RANGE:

+

+    Address32 = ((UINT32) (Address)) >> 16;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint16,

+                0x20,

+                1,

+                &Address32

+                );

+

+    Address32 = (UINT32) (Address + Node->Length - 1);

+    Address32 = ((UINT32) (Address32)) >> 16;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint16,

+                0x22,

+                1,

+                &Address32

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    break;

+

+  case PPB_PMEM32_RANGE:

+  case PPB_PMEM64_RANGE:

+

+    Address32 = ((UINT32) (Address)) >> 16;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint16,

+                0x24,

+                1,

+                &Address32

+                );

+

+    Address32 = (UINT32) (Address + Node->Length - 1);

+    Address32 = ((UINT32) (Address32)) >> 16;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint16,

+                0x26,

+                1,

+                &Address32

+                );

+

+    Address32 = (UINT32) RShiftU64 (Address, 32);

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x28,

+                1,

+                &Address32

+                );

+

+    Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32);

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x2C,

+                1,

+                &Address32

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    break;

+

+  default:

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ProgrameUpstreamBridgeForRom (

+  IN PCI_IO_DEVICE   *PciDevice,

+  IN UINT32          OptionRomBase,

+  IN BOOLEAN         Enable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    PciDevice - add argument and description to function comment

+// TODO:    OptionRomBase - add argument and description to function comment

+// TODO:    Enable - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_IO_DEVICE     *Parent;

+  PCI_RESOURCE_NODE Node;

+  //

+  // For root bridge, just return.

+  //

+  Parent = PciDevice->Parent;

+  ZeroMem (&Node, sizeof (Node));

+  while (Parent) {

+    if (!IS_PCI_BRIDGE (&Parent->Pci)) {

+      break;

+    }

+

+    Node.PciDev     = Parent;

+    Node.Length     = PciDevice->RomSize;

+    Node.Alignment  = 0;

+    Node.Bar        = PPB_MEM32_RANGE;

+    Node.ResType    = PciBarTypeMem32;

+    Node.Offset     = 0;

+

+    //

+    // Program PPB to only open a single <= 16<MB apperture

+    //

+    if (Enable) {

+      ProgramPpbApperture (OptionRomBase, &Node);

+      PciEnableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);

+    } else {

+      InitializePpb (Parent);

+      PciDisableCommandRegister (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);

+    }

+

+    Parent = Parent->Parent;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+ResourceRequestExisted (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  Bridge      - A pointer to the PCI_RESOURCE_NODE.

+

+Returns:

+

+  None

+

+--*/

+{

+  if (Bridge != NULL) {

+    if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+InitializeResourcePool (

+  PCI_RESOURCE_NODE   *ResourcePool,

+  PCI_BAR_TYPE        ResourceType

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    ResourcePool - add argument and description to function comment

+// TODO:    ResourceType - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE));

+  ResourcePool->ResType   = ResourceType;

+  ResourcePool->Signature = PCI_RESOURCE_SIGNATURE;

+  InitializeListHead (&ResourcePool->ChildList);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetResourceMap (

+  PCI_IO_DEVICE      *PciDev,

+  PCI_RESOURCE_NODE  **IoBridge,

+  PCI_RESOURCE_NODE  **Mem32Bridge,

+  PCI_RESOURCE_NODE  **PMem32Bridge,

+  PCI_RESOURCE_NODE  **Mem64Bridge,

+  PCI_RESOURCE_NODE  **PMem64Bridge,

+  PCI_RESOURCE_NODE  *IoPool,

+  PCI_RESOURCE_NODE  *Mem32Pool,

+  PCI_RESOURCE_NODE  *PMem32Pool,

+  PCI_RESOURCE_NODE  *Mem64Pool,

+  PCI_RESOURCE_NODE  *PMem64Pool

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciDev - add argument and description to function comment

+// TODO:    IoBridge - add argument and description to function comment

+// TODO:    Mem32Bridge - add argument and description to function comment

+// TODO:    PMem32Bridge - add argument and description to function comment

+// TODO:    Mem64Bridge - add argument and description to function comment

+// TODO:    PMem64Bridge - add argument and description to function comment

+// TODO:    IoPool - add argument and description to function comment

+// TODO:    Mem32Pool - add argument and description to function comment

+// TODO:    PMem32Pool - add argument and description to function comment

+// TODO:    Mem64Pool - add argument and description to function comment

+// TODO:    PMem64Pool - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  PCI_RESOURCE_NODE *Temp;

+  LIST_ENTRY        *CurrentLink;

+

+  CurrentLink = IoPool->ChildList.ForwardLink;

+

+  //

+  // Get Io resource map

+  //

+  while (CurrentLink != &IoPool->ChildList) {

+

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (Temp->PciDev == PciDev) {

+      *IoBridge = Temp;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  //

+  // Get Mem32 resource map

+  //

+  CurrentLink = Mem32Pool->ChildList.ForwardLink;

+

+  while (CurrentLink != &Mem32Pool->ChildList) {

+

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (Temp->PciDev == PciDev) {

+      *Mem32Bridge = Temp;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  //

+  // Get Pmem32 resource map

+  //

+  CurrentLink = PMem32Pool->ChildList.ForwardLink;

+

+  while (CurrentLink != &PMem32Pool->ChildList) {

+

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (Temp->PciDev == PciDev) {

+      *PMem32Bridge = Temp;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  //

+  // Get Mem64 resource map

+  //

+  CurrentLink = Mem64Pool->ChildList.ForwardLink;

+

+  while (CurrentLink != &Mem64Pool->ChildList) {

+

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (Temp->PciDev == PciDev) {

+      *Mem64Bridge = Temp;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  //

+  // Get Pmem64 resource map

+  //

+  CurrentLink = PMem64Pool->ChildList.ForwardLink;

+

+  while (CurrentLink != &PMem64Pool->ChildList) {

+

+    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    if (Temp->PciDev == PciDev) {

+      *PMem64Bridge = Temp;

+    }

+

+    CurrentLink = CurrentLink->ForwardLink;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DestroyResourceTree (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_RESOURCE_NODE *Temp;

+  LIST_ENTRY        *CurrentLink;

+

+  while (!IsListEmpty (&Bridge->ChildList)) {

+

+    CurrentLink = Bridge->ChildList.ForwardLink;

+

+    Temp        = RESOURCE_NODE_FROM_LINK (CurrentLink);

+

+    RemoveEntryList (CurrentLink);

+

+    if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) {

+      DestroyResourceTree (Temp);

+    }

+

+    gBS->FreePool (Temp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RecordReservedResource (

+  IN UINT64         Base,

+  IN UINT64         Length,

+  IN PCI_BAR_TYPE   ResType,

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Base - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    ResType - add argument and description to function comment

+// TODO:    Bridge - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_RESERVED_RESOURCE_LIST  *ReservedNode;

+

+  ReservedNode = AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST));

+  if (ReservedNode == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  ReservedNode->Signature     = RESERVED_RESOURCE_SIGNATURE;

+  ReservedNode->Node.Base     = Base;

+  ReservedNode->Node.Length   = Length;

+  ReservedNode->Node.ResType  = ResType;

+

+  InsertTailList (&Bridge->ReservedResourceList, &(ReservedNode->Link));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ResourcePaddingForCardBusBridge (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    PciDev - add argument and description to function comment

+// TODO:    IoNode - add argument and description to function comment

+// TODO:    Mem32Node - add argument and description to function comment

+// TODO:    PMem32Node - add argument and description to function comment

+// TODO:    Mem64Node - add argument and description to function comment

+// TODO:    PMem64Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  PCI_RESOURCE_NODE *Node;

+

+  Node = NULL;

+

+  //

+  // Memory Base/Limit Register 0

+  // Bar 1 denodes memory range 0

+  //

+  Node = CreateResourceNode (

+          PciDev,

+          0x2000000,

+          0x1ffffff,

+          1,

+          PciBarTypeMem32,

+          PciResUsagePadding

+          );

+

+  InsertResourceNode (

+    Mem32Node,

+    Node

+    );

+

+  //

+  // Memory Base/Limit Register 1

+  // Bar 2 denodes memory range1

+  //

+  Node = CreateResourceNode (

+          PciDev,

+          0x2000000,

+          0x1ffffff,

+          2,

+          PciBarTypePMem32,

+          PciResUsagePadding

+          );

+

+  InsertResourceNode (

+    PMem32Node,

+    Node

+    );

+

+  //

+  // Io Base/Limit

+  // Bar 3 denodes io range 0

+  //

+  Node = CreateResourceNode (

+          PciDev,

+          0x100,

+          0xff,

+          3,

+          PciBarTypeIo16,

+          PciResUsagePadding

+          );

+

+  InsertResourceNode (

+    IoNode,

+    Node

+    );

+

+  //

+  // Io Base/Limit

+  // Bar 4 denodes io range 0

+  //

+  Node = CreateResourceNode (

+          PciDev,

+          0x100,

+          0xff,

+          4,

+          PciBarTypeIo16,

+          PciResUsagePadding

+          );

+

+  InsertResourceNode (

+    IoNode,

+    Node

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ProgramP2C (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Node

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    Base - add argument and description to function comment

+// TODO:    Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINT64              Address;

+  UINT64              TempAddress;

+  UINT16              BridgeControl;

+

+  Address = 0;

+  PciIo   = &(Node->PciDev->PciIo);

+

+  Address = Base + Node->Offset;

+

+  //

+  // Indicate pci bus driver has allocated

+  // resource for this device

+  // It might be a temporary solution here since

+  // pci device could have multiple bar

+  //

+  Node->PciDev->Allocated = TRUE;

+

+  switch (Node->Bar) {

+

+  case P2C_BAR_0:

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                (Node->PciDev->PciBar[Node->Bar]).Offset,

+                1,

+                &Address

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    break;

+

+  case P2C_MEM_1:

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x1c,

+                1,

+                &Address

+                );

+

+    TempAddress = Address + Node->Length - 1;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x20,

+                1,

+                &TempAddress

+                );

+

+    if (Node->ResType == PciBarTypeMem32) {

+

+      //

+      // Set non-prefetchable bit

+      //

+      PciIo->Pci.Read (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+

+      BridgeControl &= 0xfeff;

+      PciIo->Pci.Write (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+

+    } else {

+

+      //

+      // Set pre-fetchable bit

+      //

+      PciIo->Pci.Read (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+

+      BridgeControl |= 0x0100;

+      PciIo->Pci.Write (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+    }

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;

+

+    break;

+

+  case P2C_MEM_2:

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x24,

+                1,

+                &Address

+                );

+

+    TempAddress = Address + Node->Length - 1;

+

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x28,

+                1,

+                &TempAddress

+                );

+

+    if (Node->ResType == PciBarTypeMem32) {

+

+      //

+      // Set non-prefetchable bit

+      //

+      PciIo->Pci.Read (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+

+      BridgeControl &= 0xfdff;

+      PciIo->Pci.Write (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+    } else {

+

+      //

+      // Set pre-fetchable bit

+      //

+      PciIo->Pci.Read (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+

+      BridgeControl |= 0x0200;

+      PciIo->Pci.Write (

+                  PciIo,

+                  EfiPciIoWidthUint16,

+                  0x3e,

+                  1,

+                  &BridgeControl

+                  );

+    }

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;

+    break;

+

+  case P2C_IO_1:

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x2c,

+                1,

+                &Address

+                );

+    TempAddress = Address + Node->Length - 1;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x30,

+                1,

+                &TempAddress

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;

+

+    break;

+

+  case P2C_IO_2:

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x34,

+                1,

+                &Address

+                );

+

+    TempAddress = Address + Node->Length - 1;

+    PciIo->Pci.Write (

+                PciIo,

+                EfiPciIoWidthUint32,

+                0x38,

+                1,

+                &TempAddress

+                );

+

+    Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;

+    Node->PciDev->PciBar[Node->Bar].Length      = Node->Length;

+    Node->PciDev->PciBar[Node->Bar].BarType     = Node->ResType;

+    break;

+

+  default:

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ApplyResourcePadding (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+  

+  None

+

+--*/

+// TODO:    PciDev - add argument and description to function comment

+// TODO:    IoNode - add argument and description to function comment

+// TODO:    Mem32Node - add argument and description to function comment

+// TODO:    PMem32Node - add argument and description to function comment

+// TODO:    Mem64Node - add argument and description to function comment

+// TODO:    PMem64Node - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;

+  PCI_RESOURCE_NODE                 *Node;

+  UINT8                             DummyBarIndex;

+

+  DummyBarIndex = 0;

+  Ptr           = PciDev->ResourcePaddingDescriptors;

+

+  while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) {

+

+    if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {

+      if (Ptr->AddrLen != 0) {

+

+        Node = CreateResourceNode (

+                PciDev,

+                Ptr->AddrLen,

+                Ptr->AddrRangeMax,

+                DummyBarIndex,

+                PciBarTypeIo16,

+                PciResUsagePadding

+                );

+        InsertResourceNode (

+          IoNode,

+          Node

+          );

+      }

+

+      Ptr++;

+      continue;

+    }

+

+    if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {

+

+      if (Ptr->AddrSpaceGranularity == 32) {

+

+        //

+        // prefechable

+        //

+        if (Ptr->SpecificFlag == 0x6) {

+          if (Ptr->AddrLen) {

+            Node = CreateResourceNode (

+                    PciDev,

+                    Ptr->AddrLen,

+                    Ptr->AddrRangeMax,

+                    DummyBarIndex,

+                    PciBarTypePMem32,

+                    PciResUsagePadding

+                    );

+            InsertResourceNode (

+              PMem32Node,

+              Node

+              );

+          }

+

+          Ptr++;

+          continue;

+        }

+

+        //

+        // Non-prefechable

+        //

+        if (Ptr->SpecificFlag == 0) {

+          if (Ptr->AddrLen) {

+            Node = CreateResourceNode (

+                    PciDev,

+                    Ptr->AddrLen,

+                    Ptr->AddrRangeMax,

+                    DummyBarIndex,

+                    PciBarTypeMem32,

+                    PciResUsagePadding

+                    );

+            InsertResourceNode (

+              Mem32Node,

+              Node

+              );

+          }

+

+          Ptr++;

+          continue;

+        }

+      }

+

+      if (Ptr->AddrSpaceGranularity == 64) {

+

+        //

+        // prefechable

+        //

+        if (Ptr->SpecificFlag == 0x6) {

+          if (Ptr->AddrLen) {

+            Node = CreateResourceNode (

+                    PciDev,

+                    Ptr->AddrLen,

+                    Ptr->AddrRangeMax,

+                    DummyBarIndex,

+                    PciBarTypePMem64,

+                    PciResUsagePadding

+                    );

+            InsertResourceNode (

+              PMem64Node,

+              Node

+              );

+          }

+

+          Ptr++;

+          continue;

+        }

+

+        //

+        // Non-prefechable

+        //

+        if (Ptr->SpecificFlag == 0) {

+          if (Ptr->AddrLen) {

+            Node = CreateResourceNode (

+                    PciDev,

+                    Ptr->AddrLen,

+                    Ptr->AddrRangeMax,

+                    DummyBarIndex,

+                    PciBarTypeMem64,

+                    PciResUsagePadding

+                    );

+            InsertResourceNode (

+              Mem64Node,

+              Node

+              );

+          }

+

+          Ptr++;

+          continue;

+        }

+      }

+    }

+

+    Ptr++;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// Light PCI bus driver woundn't support hotplug root device

+// So no need to pad resource for them

+//

+VOID

+GetResourcePaddingPpb (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  Get resource.

+

+Arguments:

+

+  PciIoDevice        A pointer to a pci device.

+

+Returns:

+

+  None

+

+--*/

+{

+  if (gPciHotPlugInit) {

+    if (PciIoDevice->ResourcePaddingDescriptors == NULL) {

+      GetResourcePaddingForHpb (PciIoDevice);

+    }

+  }

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h
new file mode 100644
index 0000000..61ec29f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciResourceSupport.h
@@ -0,0 +1,740 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciResourceSupport.h

+  

+Abstract:

+

+  

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_RESOURCE_SUPPORT_H

+#define _EFI_PCI_RESOURCE_SUPPORT_H

+

+#define RESERVED_RESOURCE_SIGNATURE EFI_SIGNATURE_32 ('r', 's', 'v', 'd')

+

+typedef struct {

+  UINT64        Base;

+  UINT64        Length;

+  PCI_BAR_TYPE  ResType;

+} PCI_RESERVED_RESOURCE_NODE;

+

+typedef struct {

+  UINT32                      Signature;

+  LIST_ENTRY                  Link;

+  PCI_RESERVED_RESOURCE_NODE  Node;

+} PCI_RESERVED_RESOURCE_LIST;

+

+#define RESOURCED_LIST_FROM_NODE(a) \

+  CR (a, PCI_RESERVED_RESOURCE_LIST, Node, RESERVED_RESOURCE_SIGNATURE)

+

+#define RESOURCED_LIST_FROM_LINK(a) \

+  CR (a, PCI_RESERVED_RESOURCE_LIST, Link, RESERVED_RESOURCE_SIGNATURE)

+

+typedef enum {

+  PciResUsageTypical            = 0,

+  PciResUsagePadding,

+  PciResUsageOptionRomProcessing

+} PCI_RESOURCE_USAGE;

+

+#define PCI_RESOURCE_SIGNATURE  EFI_SIGNATURE_32 ('p', 'c', 'r', 'c')

+

+typedef struct {

+  UINT32              Signature;

+  LIST_ENTRY          Link;

+  LIST_ENTRY          ChildList;

+  PCI_IO_DEVICE       *PciDev;

+  UINT64              Alignment;

+  UINT64              Offset;

+  UINT8               Bar;

+  PCI_BAR_TYPE        ResType;

+  UINT64              Length;

+  BOOLEAN             Reserved;

+  PCI_RESOURCE_USAGE  ResourceUsage;

+} PCI_RESOURCE_NODE;

+

+#define RESOURCE_NODE_FROM_LINK(a) \

+  CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE)

+

+EFI_STATUS

+SkipVGAAperture (

+  OUT UINT64   *Start,

+  IN  UINT64   Length

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Start   - TODO: add argument description

+  Length  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SkipIsaAliasAperture (

+  OUT UINT64   *Start,

+  IN  UINT64   Length

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Start   - TODO: add argument description

+  Length  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InsertResourceNode (

+  PCI_RESOURCE_NODE *Bridge,

+  PCI_RESOURCE_NODE *ResNode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  ResNode - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+MergeResourceTree (

+  PCI_RESOURCE_NODE *Dst,

+  PCI_RESOURCE_NODE *Res,

+  BOOLEAN           TypeMerge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Dst       - TODO: add argument description

+  Res       - TODO: add argument description

+  TypeMerge - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CalculateApertureIo16 (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CalculateResourceAperture (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetResourceFromDevice (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDev      - TODO: add argument description

+  IoNode      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+PCI_RESOURCE_NODE *

+CreateResourceNode (

+  IN PCI_IO_DEVICE         *PciDev,

+  IN UINT64                Length,

+  IN UINT64                Alignment,

+  IN UINT8                 Bar,

+  IN PCI_BAR_TYPE          ResType,

+  IN PCI_RESOURCE_USAGE    ResUsage

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDev    - TODO: add argument description

+  Length    - TODO: add argument description

+  Alignment - TODO: add argument description

+  Bar       - TODO: add argument description

+  ResType   - TODO: add argument description

+  ResUsage  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CreateResourceMap (

+  IN PCI_IO_DEVICE     *Bridge,

+  IN PCI_RESOURCE_NODE *IoNode,

+  IN PCI_RESOURCE_NODE *Mem32Node,

+  IN PCI_RESOURCE_NODE *PMem32Node,

+  IN PCI_RESOURCE_NODE *Mem64Node,

+  IN PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge      - TODO: add argument description

+  IoNode      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ResourcePaddingPolicy (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDev      - TODO: add argument description

+  IoNode      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DegradeResource (

+  IN PCI_IO_DEVICE     *Bridge,

+  IN PCI_RESOURCE_NODE *Mem32Node,

+  IN PCI_RESOURCE_NODE *PMem32Node,

+  IN PCI_RESOURCE_NODE *Mem64Node,

+  IN PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+BridgeSupportResourceDecode (

+  IN PCI_IO_DEVICE *Bridge,

+  IN UINT32        Decode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+  Decode  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProgramResource (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Base    - TODO: add argument description

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProgramBar (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Base  - TODO: add argument description

+  Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProgramPpbApperture (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Base  - TODO: add argument description

+  Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProgrameUpstreamBridgeForRom (

+  IN PCI_IO_DEVICE   *PciDevice,

+  IN UINT32          OptionRomBase,

+  IN BOOLEAN         Enable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDevice     - TODO: add argument description

+  OptionRomBase - TODO: add argument description

+  Enable        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ResourceRequestExisted (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+InitializeResourcePool (

+  PCI_RESOURCE_NODE   *ResourcePool,

+  PCI_BAR_TYPE        ResourceType

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ResourcePool  - TODO: add argument description

+  ResourceType  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetResourceMap (

+  PCI_IO_DEVICE      *PciDev,

+  PCI_RESOURCE_NODE  **IoBridge,

+  PCI_RESOURCE_NODE  **Mem32Bridge,

+  PCI_RESOURCE_NODE  **PMem32Bridge,

+  PCI_RESOURCE_NODE  **Mem64Bridge,

+  PCI_RESOURCE_NODE  **PMem64Bridge,

+  PCI_RESOURCE_NODE  *IoPool,

+  PCI_RESOURCE_NODE  *Mem32Pool,

+  PCI_RESOURCE_NODE  *PMem32Pool,

+  PCI_RESOURCE_NODE  *Mem64Pool,

+  PCI_RESOURCE_NODE  *PMem64Pool

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDev        - TODO: add argument description

+  IoBridge      - TODO: add argument description

+  Mem32Bridge   - TODO: add argument description

+  PMem32Bridge  - TODO: add argument description

+  Mem64Bridge   - TODO: add argument description

+  PMem64Bridge  - TODO: add argument description

+  IoPool        - TODO: add argument description

+  Mem32Pool     - TODO: add argument description

+  PMem32Pool    - TODO: add argument description

+  Mem64Pool     - TODO: add argument description

+  PMem64Pool    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DestroyResourceTree (

+  IN PCI_RESOURCE_NODE *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+RecordReservedResource (

+  IN UINT64         Base,

+  IN UINT64         Length,

+  IN PCI_BAR_TYPE   ResType,

+  IN PCI_IO_DEVICE  *Bridge

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Base    - TODO: add argument description

+  Length  - TODO: add argument description

+  ResType - TODO: add argument description

+  Bridge  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ResourcePaddingForCardBusBridge (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDev      - TODO: add argument description

+  IoNode      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ProgramP2C (

+  IN UINT64            Base,

+  IN PCI_RESOURCE_NODE *Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Base  - TODO: add argument description

+  Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ApplyResourcePadding (

+  PCI_IO_DEVICE     *PciDev,

+  PCI_RESOURCE_NODE *IoNode,

+  PCI_RESOURCE_NODE *Mem32Node,

+  PCI_RESOURCE_NODE *PMem32Node,

+  PCI_RESOURCE_NODE *Mem64Node,

+  PCI_RESOURCE_NODE *PMem64Node

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciDev      - TODO: add argument description

+  IoNode      - TODO: add argument description

+  Mem32Node   - TODO: add argument description

+  PMem32Node  - TODO: add argument description

+  Mem64Node   - TODO: add argument description

+  PMem64Node  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+GetResourcePaddingPpb (

+  IN  PCI_IO_DEVICE                  *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ResetAllPpbBusReg (

+  IN PCI_IO_DEVICE                      *Bridge,

+  IN UINT8                              StartBusNumber

+  )

+/*++

+

+Routine Description:

+

+  Reset bus register

+

+Arguments:

+

+  Bridge          - a pointer to the PCI_IO_DEVICE

+  StartBusNumber  - the number of bus

+

+Returns:

+

+  None

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c
new file mode 100644
index 0000000..a1e16a0
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c
@@ -0,0 +1,457 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciRomTable.c

+  

+Abstract:

+

+  Option Rom Support for PCI Bus Driver

+

+Revision History

+

+--*/

+

+#include "pcibus.h"

+#include "PciRomTable.h"

+

+typedef struct {

+  EFI_HANDLE  ImageHandle;

+  UINTN       Seg;

+  UINT8       Bus;

+  UINT8       Dev;

+  UINT8       Func;

+  UINT64      RomAddress;

+  UINT64      RomLength;

+} EFI_PCI_ROM_IMAGE_MAPPING;

+

+static UINTN                      mNumberOfPciRomImages     = 0;

+static UINTN                      mMaxNumberOfPciRomImages  = 0;

+static EFI_PCI_ROM_IMAGE_MAPPING  *mRomImageTable           = NULL;

+

+VOID

+PciRomAddImageMapping (

+  IN EFI_HANDLE  ImageHandle,

+  IN UINTN       Seg,

+  IN UINT8       Bus,

+  IN UINT8       Dev,

+  IN UINT8       Func,

+  IN UINT64      RomAddress,

+  IN UINT64      RomLength

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  Seg         - TODO: add argument description

+  Bus         - TODO: add argument description

+  Dev         - TODO: add argument description

+  Func        - TODO: add argument description

+  RomAddress  - TODO: add argument description

+  RomLength   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;

+

+  if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {

+

+    mMaxNumberOfPciRomImages += 0x20;

+

+    TempMapping = NULL;

+    TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));

+    if (TempMapping == NULL) {

+      return ;

+    }

+

+    CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));

+

+    if (mRomImageTable != NULL) {

+      gBS->FreePool (mRomImageTable);

+    }

+

+    mRomImageTable = TempMapping;

+  }

+

+  mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;

+  mRomImageTable[mNumberOfPciRomImages].Seg         = Seg;

+  mRomImageTable[mNumberOfPciRomImages].Bus         = Bus;

+  mRomImageTable[mNumberOfPciRomImages].Dev         = Dev;

+  mRomImageTable[mNumberOfPciRomImages].Func        = Func;

+  mRomImageTable[mNumberOfPciRomImages].RomAddress  = RomAddress;

+  mRomImageTable[mNumberOfPciRomImages].RomLength   = RomLength;

+  mNumberOfPciRomImages++;

+}

+

+VOID

+HexToString (

+  CHAR16  *String,

+  UINTN   Value,

+  UINTN   Digits

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  String  - TODO: add argument description

+  Value   - TODO: add argument description

+  Digits  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  for (; Digits > 0; Digits--, String++) {

+    *String = (CHAR16) ((Value >> (4 * (Digits - 1))) & 0x0f);

+    if (*String > 9) {

+      (*String) += ('A' - 10);

+    } else {

+      (*String) += '0';

+    }

+  }

+}

+EFI_STATUS

+PciRomLoadEfiDriversFromRomImage (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_PCI_OPTION_ROM_DESCRIPTOR  *PciOptionRomDescriptor

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    PciOptionRomDescriptor - add argument and description to function comment

+{

+  VOID                          *RomBar;

+  UINTN                         RomSize;

+  CHAR16                        *FileName;

+  EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;

+  PCI_DATA_STRUCTURE            *Pcir;

+  UINTN                         ImageIndex;

+  UINTN                         RomBarOffset;

+  UINT32                        ImageSize;

+  UINT16                        ImageOffset;

+  EFI_HANDLE                    ImageHandle;

+  EFI_STATUS                    Status;

+  EFI_STATUS                    retStatus;

+  EFI_DEVICE_PATH_PROTOCOL      *FilePath;

+  BOOLEAN                       SkipImage;

+  UINT32                        DestinationSize;

+  UINT32                        ScratchSize;

+  UINT8                         *Scratch;

+  VOID                          *ImageBuffer;

+  VOID                          *DecompressedImageBuffer;

+  UINT32                        ImageLength;

+  EFI_DECOMPRESS_PROTOCOL       *Decompress;

+

+  RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;

+  RomSize = (UINTN) PciOptionRomDescriptor->RomLength;

+  FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";

+

+  HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);

+  HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);

+  HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);

+  HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);

+

+  ImageIndex    = 0;

+  retStatus     = EFI_NOT_FOUND;

+  RomBarOffset  = (UINTN) RomBar;

+

+  do {

+

+    EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;

+

+    if (EfiRomHeader->Signature != 0xaa55) {

+      return retStatus;

+    }

+

+    Pcir      = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);

+    ImageSize = Pcir->ImageLength * 512;

+

+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&

+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {

+

+      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||

+          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {

+

+        ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;

+        ImageSize               = EfiRomHeader->InitializationSize * 512;

+

+        ImageBuffer             = (VOID *) (UINTN) (RomBarOffset + ImageOffset);

+        ImageLength             = ImageSize - ImageOffset;

+        DecompressedImageBuffer = NULL;

+

+        //

+        // decompress here if needed

+        //

+        SkipImage = FALSE;

+        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {

+          SkipImage = TRUE;

+        }

+

+        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {

+          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);

+          if (EFI_ERROR (Status)) {

+            SkipImage = TRUE;

+          } else {

+            SkipImage = TRUE;

+            Status = Decompress->GetInfo (

+                                  Decompress,

+                                  ImageBuffer,

+                                  ImageLength,

+                                  &DestinationSize,

+                                  &ScratchSize

+                                  );

+            if (!EFI_ERROR (Status)) {

+              DecompressedImageBuffer = NULL;

+              DecompressedImageBuffer = AllocatePool (DestinationSize);

+              if (DecompressedImageBuffer != NULL) {

+                Scratch = AllocatePool (ScratchSize);

+                if (Scratch != NULL) {

+                  Status = Decompress->Decompress (

+                                        Decompress,

+                                        ImageBuffer,

+                                        ImageLength,

+                                        DecompressedImageBuffer,

+                                        DestinationSize,

+                                        Scratch,

+                                        ScratchSize

+                                        );

+                  if (!EFI_ERROR (Status)) {

+                    ImageBuffer = DecompressedImageBuffer;

+                    ImageLength = DestinationSize;

+                    SkipImage   = FALSE;

+                  }

+

+                  gBS->FreePool (Scratch);

+                }

+              }

+            }

+          }

+        }

+

+        if (!SkipImage) {

+

+          //

+          // load image and start image

+          //

+

+          HexToString (&FileName[48], ImageIndex, 4);

+          FilePath = FileDevicePath (NULL, FileName);

+

+          Status = gBS->LoadImage (

+                          FALSE,

+                          This->ImageHandle,

+                          FilePath,

+                          ImageBuffer,

+                          ImageLength,

+                          &ImageHandle

+                          );

+          if (!EFI_ERROR (Status)) {

+            Status = gBS->StartImage (ImageHandle, NULL, NULL);

+            if (!EFI_ERROR (Status)) {

+              PciRomAddImageMapping (

+                ImageHandle,

+                PciOptionRomDescriptor->Seg,

+                PciOptionRomDescriptor->Bus,

+                PciOptionRomDescriptor->Dev,

+                PciOptionRomDescriptor->Func,

+                PciOptionRomDescriptor->RomAddress,

+                PciOptionRomDescriptor->RomLength

+                );

+              retStatus = Status;

+            }

+          }

+        }

+

+        if (DecompressedImageBuffer != NULL) {

+          gBS->FreePool (DecompressedImageBuffer);

+        }

+

+      }

+    }

+

+    RomBarOffset = RomBarOffset + ImageSize;

+    ImageIndex++;

+  } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));

+

+  return retStatus;

+}

+

+EFI_STATUS

+PciRomLoadEfiDriversFromOptionRomTable (

+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    PciRootBridgeIo - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  EFI_PCI_OPTION_ROM_TABLE          *PciOptionRomTable;

+  EFI_PCI_OPTION_ROM_DESCRIPTOR     *PciOptionRomDescriptor;

+  UINTN                             Index;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

+  UINT16                            MinBus;

+  UINT16                            MaxBus;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  Status = EFI_NOT_FOUND;

+

+  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {

+    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];

+    if (!PciOptionRomDescriptor->DontLoadEfiRom) {

+      if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {

+        Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+

+        PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);

+        if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {

+          Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);

+          PciOptionRomDescriptor->DontLoadEfiRom |= 2;

+        }

+      }

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+PciRomGetRomResourceFromPciOptionRomTable (

+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    PciRootBridgeIo - add argument and description to function comment

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                    Status;

+  EFI_PCI_OPTION_ROM_TABLE      *PciOptionRomTable;

+  EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;

+  UINTN                         Index;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {

+    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];

+    if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&

+        PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber         &&

+        PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber      &&

+        PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {

+

+      PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;

+      PciIoDevice->PciIo.RomSize  = (UINTN) PciOptionRomDescriptor->RomLength;

+    }

+  }

+

+  for (Index = 0; Index < mNumberOfPciRomImages; Index++) {

+    if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&

+        mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&

+        mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&

+        mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {

+

+      AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PciRomGetImageMapping (

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    PciIoDevice - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  UINTN                           Index;

+

+  PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;

+

+  for (Index = 0; Index < mNumberOfPciRomImages; Index++) {

+    if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&

+        mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&

+        mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&

+        mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {

+

+      if (mRomImageTable[Index].ImageHandle != NULL) {

+        AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);

+      } else {

+        PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress;

+        PciIoDevice->PciIo.RomSize  = (UINTN) mRomImageTable[Index].RomLength;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h
new file mode 100644
index 0000000..bb20c70
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.h
@@ -0,0 +1,107 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciRomTable.h

+  

+Abstract:

+

+  Option Rom Support for PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_ROM_TABLE_H

+#define _EFI_PCI_ROM_TABLE_H

+

+VOID

+PciRomAddImageMapping (

+  IN EFI_HANDLE  ImageHandle,

+  IN UINTN       Seg,

+  IN UINT8       Bus,

+  IN UINT8       Dev,

+  IN UINT8       Func,

+  IN UINT64      RomAddress,

+  IN UINT64      RomLength

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  Seg         - TODO: add argument description

+  Bus         - TODO: add argument description

+  Dev         - TODO: add argument description

+  Func        - TODO: add argument description

+  RomAddress  - TODO: add argument description

+  RomLength   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+EFI_STATUS

+PciRomGetRomResourceFromPciOptionRomTable (

+  IN EFI_DRIVER_BINDING_PROTOCOL      *This,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This            - TODO: add argument description

+  PciRootBridgeIo - TODO: add argument description

+  PciIoDevice     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+PciRomGetImageMapping (

+  PCI_IO_DEVICE                       *PciIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PciIoDevice - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/build.xml
new file mode 100644
index 0000000..579dc7f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/build.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PciBus"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Pci/PciBus/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PciBus">

+      <GenBuild baseName="PciBus" mbdFilename="${MODULE_DIR}/PciBus.mbd" msaFilename="${MODULE_DIR}/PciBus.msa"/>

+   </target>

+   <target name="LightPciBusPciBus">

+      <GenBuild baseName="LightPciBusPciBus" mbdFilename="${MODULE_DIR}/LightPciBus.mbd" msaFilename="${MODULE_DIR}/LightPciBus.msa"/>

+   </target>

+   <target name="PciBusPciBusLite">

+      <GenBuild baseName="PciBusPciBusLite" mbdFilename="${MODULE_DIR}/PciBusLite.mbd" msaFilename="${MODULE_DIR}/PciBusLite.msa"/>

+   </target>

+   <target depends="PciBus_clean" name="clean"/>

+   <target depends="PciBus_cleanall" name="cleanall"/>

+   <target name="PciBus_clean">

+      <OutputDirSetup baseName="PciBus" mbdFilename="${MODULE_DIR}/PciBus.mbd" msaFilename="${MODULE_DIR}/PciBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PciBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PciBus_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="LightPciBusPciBus_clean">

+      <OutputDirSetup baseName="LightPciBusPciBus" mbdFilename="${MODULE_DIR}/LightPciBus.mbd" msaFilename="${MODULE_DIR}/LightPciBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/LightPciBusPciBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/LightPciBusPciBus_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PciBusPciBusLite_clean">

+      <OutputDirSetup baseName="PciBusPciBusLite" mbdFilename="${MODULE_DIR}/PciBusLite.mbd" msaFilename="${MODULE_DIR}/PciBusLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PciBusPciBusLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PciBusPciBusLite_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PciBus_cleanall">

+      <OutputDirSetup baseName="PciBus" mbdFilename="${MODULE_DIR}/PciBus.mbd" msaFilename="${MODULE_DIR}/PciBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PciBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PciBus_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PciBus*"/>

+      </delete>

+   </target>

+   <target name="LightPciBusPciBus_cleanall">

+      <OutputDirSetup baseName="LightPciBusPciBus" mbdFilename="${MODULE_DIR}/LightPciBus.mbd" msaFilename="${MODULE_DIR}/LightPciBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/LightPciBusPciBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/LightPciBusPciBus_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**LightPciBusPciBus*"/>

+      </delete>

+   </target>

+   <target name="PciBusPciBusLite_cleanall">

+      <OutputDirSetup baseName="PciBusPciBusLite" mbdFilename="${MODULE_DIR}/PciBusLite.mbd" msaFilename="${MODULE_DIR}/PciBusLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PciBusPciBusLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PciBusPciBusLite_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PciBusPciBusLite*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c
new file mode 100644
index 0000000..ed56578
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.c
@@ -0,0 +1,375 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciBus.c

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+ 

+--*/

+

+#include "pcibus.h"

+

+//

+// PCI Bus Support Function Prototypes

+//

+

+EFI_STATUS

+EFIAPI

+PciBusEntryPoint (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+PciBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PciBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PciBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  );

+

+//

+// PCI Bus Driver Global Variables

+//

+

+EFI_DRIVER_BINDING_PROTOCOL                   gPciBusDriverBinding = {

+  PciBusDriverBindingSupported,

+  PciBusDriverBindingStart,

+  PciBusDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL  *gEfiIncompatiblePciDeviceSupport = NULL;

+EFI_HANDLE                                    gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];

+UINTN                                         gPciHostBridgeNumber;

+BOOLEAN                                       gFullEnumeration;

+UINT64                                        gAllOne   = 0xFFFFFFFFFFFFFFFFULL;

+UINT64                                        gAllZero  = 0;

+

+EFI_PCI_PLATFORM_PROTOCOL                     *gPciPlatformProtocol;

+

+//

+// PCI Bus Driver Support Functions

+//

+EFI_STATUS

+EFIAPI

+PciBusEntryPoint (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initialize the global variables

+  publish the driver binding protocol

+

+Arguments:

+

+  IN EFI_HANDLE     ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+

+Returns:

+

+  EFI_SUCCESS 

+  EFI_DEVICE_ERROR 

+

+--*/

+// TODO:    ImageHandle - add argument and description to function comment

+// TODO:    SystemTable - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+

+  InitializePciDevicePool ();

+

+  gFullEnumeration      = TRUE;

+

+  gPciHostBridgeNumber  = 0;

+

+  InstallHotPlugRequestProtocol (&Status);

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PciBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Check to see if pci bus driver supports the given controller

+

+Arguments:

+  

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS                      Status;

+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  EFI_DEV_PATH_PTR                Node;

+

+  if (RemainingDevicePath != NULL) {

+    Node.DevPath = RemainingDevicePath;

+    if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||

+        Node.DevPath->SubType != HW_PCI_DP         ||

+        DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  (VOID **) &PciRootBridgeIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciRootBridgeIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PciBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Start to management the controller passed in

+

+Arguments:

+  

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+

+Returns:

+ 

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiIncompatiblePciDeviceSupportProtocolGuid,

+                  NULL,

+                  (VOID **) &gEfiIncompatiblePciDeviceSupport

+                  );

+

+  //

+  // If PCI Platform protocol is available, get it now.

+  // If the platform implements this, it must be installed before BDS phase

+  //

+  gPciPlatformProtocol = NULL;

+  gBS->LocateProtocol (

+        &gEfiPciPlatformProtocolGuid,

+        NULL,

+        (VOID **) &gPciPlatformProtocol

+        );

+

+  gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));

+

+  //

+  // Enumerate the entire host bridge

+  // After enumeration, a database that records all the device information will be created

+  //

+  //

+  Status = PciEnumerator (Controller);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Enable PCI device specified by remaining device path. BDS or other driver can call the

+  // start more than once.

+  //

+  

+  StartPciDevices (Controller, RemainingDevicePath);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PciBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  Stop one or more children created at start of pci bus driver

+  if all the the children get closed, close the protocol

+

+Arguments:

+  

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+

+Returns:

+

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+  BOOLEAN     AllChildrenStopped;

+

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciRootBridgeIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    DestroyRootBridgeByHandle (

+      Controller

+      );

+

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Stop all the children

+  //

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+

+    //

+    // De register all the pci device

+    //

+    Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h
new file mode 100644
index 0000000..a18d12f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/PciBus/Dxe/pcibus.h
@@ -0,0 +1,243 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  pcibus.h

+  

+Abstract:

+

+  PCI Bus Driver

+

+Revision History

+

+--*/

+

+#ifndef _EFI_PCI_BUS_H

+#define _EFI_PCI_BUS_H

+

+

+#include <IndustryStandard/pci22.h>

+#include <IndustryStandard/Acpi.h>

+#include "ComponentName.h"

+

+//

+// Driver Produced Protocol Prototypes

+//

+

+#define VGABASE1  0x3B0

+#define VGALIMIT1 0x3BB

+

+#define VGABASE2  0x3C0

+#define VGALIMIT2 0x3DF

+

+#define ISABASE   0x100

+#define ISALIMIT  0x3FF

+

+typedef enum {

+  PciBarTypeUnknown = 0,

+  PciBarTypeIo16,

+  PciBarTypeIo32,

+  PciBarTypeMem32,

+  PciBarTypePMem32,

+  PciBarTypeMem64,

+  PciBarTypePMem64,

+  PciBarTypeIo,

+  PciBarTypeMem,

+  PciBarTypeMaxType

+} PCI_BAR_TYPE;

+

+typedef struct {

+  UINT64        BaseAddress;

+  UINT64        Length;

+  UINT64        Alignment;

+  PCI_BAR_TYPE  BarType;

+  BOOLEAN       Prefetchable;

+  UINT8         MemType;

+  UINT8         Offset;

+} PCI_BAR;

+

+#define PPB_BAR_0                             0

+#define PPB_BAR_1                             1

+#define PPB_IO_RANGE                          2

+#define PPB_MEM32_RANGE                       3

+#define PPB_PMEM32_RANGE                      4

+#define PPB_PMEM64_RANGE                      5

+#define PPB_MEM64_RANGE                       0xFF

+

+#define P2C_BAR_0                             0

+#define P2C_MEM_1                             1

+#define P2C_MEM_2                             2

+#define P2C_IO_1                              3

+#define P2C_IO_2                              4

+

+#define PCI_IO_DEVICE_SIGNATURE               EFI_SIGNATURE_32 ('p', 'c', 'i', 'o')

+

+#define EFI_BRIDGE_IO32_DECODE_SUPPORTED      0x0001

+#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED    0x0002

+#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED    0x0004

+#define EFI_BRIDGE_IO16_DECODE_SUPPORTED      0x0008

+#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010

+#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED     0x0020

+#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED     0x0040

+

+#define PCI_MAX_HOST_BRIDGE_NUM               0x0010

+//

+// Define resource status constant

+//

+#define EFI_RESOURCE_NONEXISTENT  0xFFFFFFFFFFFFFFFFULL

+#define EFI_RESOURCE_LESS         0xFFFFFFFFFFFFFFFEULL

+#define EFI_RESOURCE_SATISFIED    0x0000000000000000ULL

+

+//

+// Define option for attribute

+//

+#define EFI_SET_SUPPORTS    0

+#define EFI_SET_ATTRIBUTES  1

+

+typedef struct _PCI_IO_DEVICE {

+  UINT32                                    Signature;

+  EFI_HANDLE                                Handle;

+  EFI_PCI_IO_PROTOCOL                       PciIo;

+  LIST_ENTRY                                Link;

+

+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;

+  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *PciRootBridgeIo;

+

+  //

+  // PCI configuration space header type

+  //

+  PCI_TYPE00                                Pci;

+

+  //

+  // Bus number, Device number, Function number

+  //

+  UINT8                                     BusNumber;

+  UINT8                                     DeviceNumber;

+  UINT8                                     FunctionNumber;

+

+  //

+  // BAR for this PCI Device

+  //

+  PCI_BAR                                   PciBar[PCI_MAX_BAR];

+

+  //

+  // The bridge device this pci device is subject to

+  //

+  struct _PCI_IO_DEVICE                     *Parent;

+

+  //

+  // A linked list for children Pci Device if it is bridge device

+  //

+  LIST_ENTRY                                ChildList;

+

+  //

+  // TURE if the PCI bus driver creates the handle for this PCI device

+  //

+  BOOLEAN                                   Registered;

+

+  //

+  // TRUE if the PCI bus driver successfully allocates the resource required by

+  // this PCI device

+  //

+  BOOLEAN                                   Allocated;

+

+  //

+  // The attribute this PCI device currently set

+  //

+  UINT64                                    Attributes;

+

+  //

+  // The attributes this PCI device actually supports

+  //

+  UINT64                                    Supports;

+

+  //

+  // The resource decode the bridge supports

+  //

+  UINT32                                    Decodes;

+

+  //

+  // The OptionRom Size

+  //

+  UINT64                                    RomSize;

+

+  //

+  // The OptionRom Size

+  //

+  UINT64                                    RomBase;

+

+  //

+  // TRUE if all OpROM (in device or in platform specific position) have been processed

+  //

+  BOOLEAN                                   AllOpRomProcessed;

+

+  //

+  // TRUE if there is any EFI driver in the OptionRom

+  //

+  BOOLEAN                                   BusOverride;

+

+  //

+  //  A list tracking reserved resource on a bridge device

+  //

+  LIST_ENTRY                                ReservedResourceList;

+

+  //

+  // A list tracking image handle of platform specific overriding driver

+  //

+  LIST_ENTRY                                OptionRomDriverList;

+

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR         *ResourcePaddingDescriptors;

+  EFI_HPC_PADDING_ATTRIBUTES                PaddingAttributes;

+

+  BOOLEAN                                   IsPciExp;

+

+} PCI_IO_DEVICE;

+

+

+#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \

+  CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)

+

+#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \

+  CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)

+

+#define PCI_IO_DEVICE_FROM_LINK(a) \

+  CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport;

+extern EFI_DRIVER_BINDING_PROTOCOL                  gPciBusDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL                  gPciBusComponentName;

+extern LIST_ENTRY                                   gPciDevicePool;

+extern BOOLEAN                                      gFullEnumeration;

+extern UINTN                                        gPciHostBridgeNumber;

+extern EFI_HANDLE                                   gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];

+extern UINT64                                       gAllOne;

+extern UINT64                                       gAllZero;

+

+extern EFI_PCI_PLATFORM_PROTOCOL                    *gPciPlatformProtocol;

+

+#include "PciIo.h"

+#include "PciCommand.h"

+#include "PciDeviceSupport.h"

+#include "PciEnumerator.h"

+#include "PciEnumeratorSupport.h"

+#include "PciDriverOverride.h"

+#include "PciRomTable.h"

+#include "PciOptionRomSupport.h"

+#include "PciPowerManagement.h"

+#include "PciHotPlugSupport.h"

+#include "PciLib.h"

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/ComponentName.c
new file mode 100644
index 0000000..71d9339
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/ComponentName.c
@@ -0,0 +1,189 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "uhci.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UhciComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UhciComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_HANDLE                      ChildHandle, OPTIONAL

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gUhciComponentName = {

+  UhciComponentNameGetDriverName,

+  UhciComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mUhciDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Usb Uhci Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+UhciComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUhciComponentName.SupportedLanguages,

+          mUhciDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UhciComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_HANDLE                      ChildHandle, OPTIONAL

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS          Status;

+  USB_HC_DEV          *UhciDev;

+  EFI_USB_HC_PROTOCOL *UsbHc;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get the device context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbHcProtocolGuid,

+                  (VOID **) &UsbHc,

+                  gUhciDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UhciDev = USB_HC_DEV_FROM_THIS (UsbHc);

+

+  return LookupUnicodeString (

+          Language,

+          gUhciComponentName.SupportedLanguages,

+          UhciDev->ControllerNameTable,

+          ControllerName

+          );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.mbd b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.mbd
new file mode 100644
index 0000000..76d35e7
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Uhci</BaseName>

+    <Guid>2FB92EFA-2EE0-4bae-9EB6-7464125E1EF7</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa
new file mode 100644
index 0000000..9e5ca0a
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Uhci</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>2FB92EFA-2EE0-4bae-9EB6-7464125E1EF7</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Uhci module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>uhci.c</Filename>

+    <Filename>uhchlp.c</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>uhci.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">PciIo</Protocol>

+    <Protocol Usage="BY_START">UsbHc</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUhciDriverBinding</DriverBinding>

+      <ComponentName>gUhciComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/build.xml
new file mode 100644
index 0000000..dca737f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Uhci"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Pci/Uhci/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Uhci">

+      <GenBuild baseName="Uhci" mbdFilename="${MODULE_DIR}/Uhci.mbd" msaFilename="${MODULE_DIR}/Uhci.msa"/>

+   </target>

+   <target depends="Uhci_clean" name="clean"/>

+   <target depends="Uhci_cleanall" name="cleanall"/>

+   <target name="Uhci_clean">

+      <OutputDirSetup baseName="Uhci" mbdFilename="${MODULE_DIR}/Uhci.mbd" msaFilename="${MODULE_DIR}/Uhci.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Uhci_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Uhci_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Uhci_cleanall">

+      <OutputDirSetup baseName="Uhci" mbdFilename="${MODULE_DIR}/Uhci.mbd" msaFilename="${MODULE_DIR}/Uhci.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Uhci_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Uhci_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Uhci*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
new file mode 100644
index 0000000..62d58ee
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
@@ -0,0 +1,4237 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    UhcHlp.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#include "uhci.h"

+

+EFI_STATUS

+USBReadPortW (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  PortOffset,

+  IN OUT   UINT16                  *Data

+  )

+/*++

+

+Routine Description:

+

+  USBReadPort Word

+

+Arguments:

+

+  PciIo       - EFI_PCI_IO_PROTOCOL

+  PortOffset  - Port offset

+  Data        - Data to reutrn

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Perform 16bit Read in PCI IO Space

+  //

+  return PciIo->Io.Read (

+                    PciIo,

+                    EfiPciIoWidthUint16,

+                    USB_BAR_INDEX,

+                    (UINT64) PortOffset,

+                    1,

+                    Data

+                    );

+}

+

+EFI_STATUS

+USBReadPortDW (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  PortOffset,

+  IN OUT   UINT32                  *Data

+  )

+/*++

+

+Routine Description:

+

+  USBReadPort DWord

+

+Arguments:

+

+  PciIo       - EFI_PCI_IO_PROTOCOL

+  PortOffset  - Port offset

+  Data        - Data to reutrn

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Perform 32bit Read in PCI IO Space

+  //

+  return PciIo->Io.Read (

+                    PciIo,

+                    EfiPciIoWidthUint32,

+                    USB_BAR_INDEX,

+                    (UINT64) PortOffset,

+                    1,

+                    Data

+                    );

+}

+

+EFI_STATUS

+USBWritePortW (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  PortOffset,

+  IN UINT16                  Data

+  )

+/*++

+

+Routine Description:

+

+  USB Write Port Word

+

+Arguments:

+

+  PciIo       - EFI_PCI_IO_PROTOCOL

+  PortOffset  - Port offset

+  Data        - Data to write

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Perform 16bit Write in PCI IO Space

+  //

+  return PciIo->Io.Write (

+                    PciIo,

+                    EfiPciIoWidthUint16,

+                    USB_BAR_INDEX,

+                    (UINT64) PortOffset,

+                    1,

+                    &Data

+                    );

+}

+

+EFI_STATUS

+USBWritePortDW (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  PortOffset,

+  IN UINT32                  Data

+  )

+/*++

+

+Routine Description:

+

+  USB Write Port DWord

+

+Arguments:

+

+  PciIo       - EFI_PCI_IO_PROTOCOL

+  PortOffset  - Port offset

+  Data        - Data to write

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Perform 32bit Write in PCI IO Space

+  //

+  return PciIo->Io.Write (

+                    PciIo,

+                    EfiPciIoWidthUint32,

+                    USB_BAR_INDEX,

+                    (UINT64) PortOffset,

+                    1,

+                    &Data

+                    );

+}

+//

+//  USB register-base helper functions

+//

+EFI_STATUS

+WriteUHCCommandReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  CmdAddrOffset,

+  IN UINT16                  UsbCmd

+  )

+/*++

+

+Routine Description:

+

+  Write UHCI Command Register

+

+Arguments:

+

+  PciIo         - EFI_PCI_IO_PROTOCOL

+  CmdAddrOffset - Command address offset

+  UsbCmd        - Data to write

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Write to UHC's Command Register

+  //

+  return USBWritePortW (PciIo, CmdAddrOffset, UsbCmd);

+}

+

+EFI_STATUS

+ReadUHCCommandReg (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  CmdAddrOffset,

+  IN OUT   UINT16                  *Data

+  )

+/*++

+

+Routine Description:

+

+  Read UHCI Command Register

+

+Arguments:

+

+  PciIo         - EFI_PCI_IO_PROTOCOL

+  CmdAddrOffset - Command address offset

+  Data          - Data to return

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Read from UHC's Command Register

+  //

+  return USBReadPortW (PciIo, CmdAddrOffset, Data);

+}

+

+EFI_STATUS

+WriteUHCStatusReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusAddrOffset,

+  IN UINT16                  UsbSts

+  )

+/*++

+

+Routine Description:

+

+  Write UHCI Staus Register

+

+Arguments:

+

+  PciIo            - EFI_PCI_IO_PROTOCOL

+  StatusAddrOffset - Status address offset

+  UsbSts           - Data to write

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Write to UHC's Status Register

+  //

+  return USBWritePortW (PciIo, StatusAddrOffset, UsbSts);

+}

+

+EFI_STATUS

+ReadUHCStatusReg (

+  IN     EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN     UINT32                  StatusAddrOffset,

+  IN OUT UINT16                  *Data

+  )

+/*++

+

+Routine Description:

+

+  Read UHCI Staus Register

+

+Arguments:

+

+  PciIo            - EFI_PCI_IO_PROTOCOL

+  StatusAddrOffset - Status address offset

+  UsbSts           - Data to return

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Read from UHC's Status Register

+  //

+  return USBReadPortW (PciIo, StatusAddrOffset, Data);

+}

+

+

+EFI_STATUS

+ClearStatusReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusAddrOffset

+  )

+/*++

+

+Routine Description:

+

+  Clear the content of UHC's Status Register

+

+Arguments:

+

+  PciIo             - EFI_PCI_IO_PROTOCOL

+  StatusAddrOffset  - Status address offset

+  

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+ 

+  return WriteUHCStatusReg (PciIo, StatusAddrOffset, 0x003F);

+}

+

+EFI_STATUS

+ReadUHCFrameNumberReg (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  FrameNumAddrOffset,

+  IN OUT   UINT16                  *Data

+  )

+/*++

+

+Routine Description:

+

+  Read from UHC's Frame Number Register

+

+Arguments:

+

+  PciIo              - EFI_PCI_IO_PROTOCOL

+  FrameNumAddrOffset - Frame number register offset

+  Data               - Data to return 

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  

+  return USBReadPortW (PciIo, FrameNumAddrOffset, Data);

+}

+

+EFI_STATUS

+WriteUHCFrameListBaseReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FlBaseAddrOffset,

+  IN UINT32                  UsbFrameListBaseAddr

+  )

+/*++

+

+Routine Description:

+

+  Write to UHC's Frame List Base Register

+

+Arguments:

+

+  PciIo                - EFI_PCI_IO_PROTOCOL

+  FlBaseAddrOffset     - Frame Base address register

+  UsbFrameListBaseAddr - Address to write

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  

+  return USBWritePortDW (PciIo, FlBaseAddrOffset, UsbFrameListBaseAddr);

+}

+

+EFI_STATUS

+ReadRootPortReg (

+  IN     EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN     UINT32                  PortAddrOffset,

+  IN OUT UINT16                  *Data

+  )

+/*++

+

+Routine Description:

+

+  Read from UHC's Root Port Register

+

+Arguments:

+

+  PciIo           - EFI_PCI_IO_PROTOCOL

+  PortAddrOffset  - Port Addrress Offset,

+  Data            - Data to return

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+ 

+  return USBReadPortW (PciIo, PortAddrOffset, Data);

+}

+

+EFI_STATUS

+WriteRootPortReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  PortAddrOffset,

+  IN UINT16                  ControlBits

+  )

+/*++

+

+Routine Description:

+

+   Write to UHC's Root Port Register

+

+Arguments:

+

+  PciIo           - EFI_PCI_IO_PROTOCOL

+  PortAddrOffset  - Port Addrress Offset,

+  ControlBits     - Data to write

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+ 

+  return USBWritePortW (PciIo, PortAddrOffset, ControlBits);

+}

+

+

+

+EFI_STATUS

+WaitForUHCHalt (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusRegAddr,

+  IN UINTN                   Timeout

+  )

+/*++

+

+Routine Description:

+

+  Wait until UHCI halt or timeout

+

+Arguments:

+

+  PciIo         - EFI_PCI_IO_PROTOCOL

+  StatusRegAddr - Status Register Address

+  Timeout       - Time out value in us

+

+Returns:

+

+  EFI_DEVICE_ERROR - Unable to read the status register

+  EFI_TIMEOUT      - Time out

+  EFI_SUCCESS      - Success

+

+--*/

+{

+  UINTN       Delay;

+  EFI_STATUS  Status;

+  UINT16      HcStatus;

+

+  //

+  // Timeout is in us unit

+  //

+  Delay = (Timeout / 50) + 1;

+  do {

+    Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    if ((HcStatus & USBSTS_HCH) == USBSTS_HCH) {

+      break;

+    }

+    //

+    // Stall for 50 us

+    //

+    gBS->Stall (50);

+

+  } while (Delay--);

+

+  if (Delay == 0) {

+    return EFI_TIMEOUT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsStatusOK (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusRegAddr

+  )

+/*++

+

+Routine Description:

+

+  Judge whether the host controller operates well

+

+Arguments:

+

+  PciIo         - EFI_PCI_IO_PROTOCOL

+  StatusRegAddr - Status register address

+

+Returns:

+

+   TRUE  -  Status is good

+   FALSE -  Status is bad

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT16      HcStatus;

+  //

+  // Detect whether the interrupt is caused by fatal error.

+  // see "UHCI Design Guid".

+  //

+  Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  if (HcStatus & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+

+}

+

+

+BOOLEAN 

+IsHostSysOrProcessErr (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusRegAddr

+  )

+/*++

+

+Routine Description:

+

+  Judge the status is HostSys,ProcessErr error or good

+

+Arguments:

+

+  PciIo         - EFI_PCI_IO_PROTOCOL

+  StatusRegAddr - Status register address

+

+Returns:

+

+   TRUE  -  Status is good

+   FALSE -  Status is bad

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT16      HcStatus;

+  //

+  // Detect whether the interrupt is caused by serious error.

+  // see "UHCI Design Guid".

+  //

+  Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  if (HcStatus & (USBSTS_HSE | USBSTS_HCPE)) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+

+UINT16

+GetCurrentFrameNumber (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FrameNumAddrOffset

+  )

+/*++

+

+Routine Description:

+

+  Get Current Frame Number

+

+Arguments:

+

+  PciIo               - EFI_PCI_IO_PROTOCOL

+  FrameNumAddrOffset  - FrameNum register AddrOffset

+

+Returns:

+

+  Frame number 

+

+--*/

+{

+  //

+  // Gets value in the USB frame number register.

+  //

+  UINT16  FrameNumber;

+

+  ReadUHCFrameNumberReg (PciIo, FrameNumAddrOffset, &FrameNumber);

+

+  return (UINT16) (FrameNumber & 0x03FF);

+}

+

+EFI_STATUS

+SetFrameListBaseAddress (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FlBaseAddrReg,

+  IN UINT32                  Addr

+  )

+/*++

+

+Routine Description:

+

+  Set FrameListBase Address

+

+Arguments:

+

+  PciIo         - EFI_PCI_IO_PROTOCOL

+  FlBaseAddrReg - FrameListBase register

+  Addr          - Address to set

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  //

+  // Sets value in the USB Frame List Base Address register.

+  //

+  return WriteUHCFrameListBaseReg (PciIo, FlBaseAddrReg, (UINT32) (Addr & 0xFFFFF000));

+}

+

+VOID

+EnableMaxPacketSize (

+  IN USB_HC_DEV     *HcDev

+  )

+/*++

+

+Routine Description:

+

+  Enable Max Packet Size

+

+Arguments:

+

+  HcDev - USB_HC_DEV

+

+Returns:

+

+  VOID

+

+--*/

+{

+  UINT16      CommandContent;

+  EFI_STATUS  Status;

+

+  Status = ReadUHCCommandReg (

+            HcDev->PciIo,

+            (UINT32) (USBCMD),

+            &CommandContent

+            );

+

+  if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {

+    CommandContent |= USBCMD_MAXP;

+    WriteUHCCommandReg (

+      HcDev->PciIo,

+      (UINT32) (USBCMD),

+      CommandContent

+      );

+  }

+

+  return ;

+}

+

+EFI_STATUS

+CreateFrameList (

+  IN USB_HC_DEV     *HcDev,

+  IN UINT32         FlBaseAddrReg

+  )

+/*++

+

+Routine Description:

+

+  CreateFrameList

+

+Arguments:

+

+  HcDev         - USB_HC_DEV

+  FlBaseAddrReg - Frame List register

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory resources

+  EFI_UNSUPPORTED      - Map memory fail

+  EFI_SUCCESS          - Success

+

+--*/

+{

+  EFI_STATUS            Status;

+  VOID                  *CommonBuffer;

+  EFI_PHYSICAL_ADDRESS  MappedAddress;

+  VOID                  *Mapping;

+  UINTN                 BufferSizeInPages;

+  UINTN                 BufferSizeInBytes;

+

+  //

+  // The Frame List is a common buffer that will be

+  // accessed by both the cpu and the usb bus master

+  // at the same time.

+  // The Frame List ocupies 4K bytes,

+  // and must be aligned on 4-Kbyte boundaries.

+  //

+  BufferSizeInBytes = 4096;

+  BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);

+  Status = HcDev->PciIo->AllocateBuffer (

+                          HcDev->PciIo,

+                          AllocateAnyPages,

+                          EfiBootServicesData,

+                          BufferSizeInPages,

+                          &CommonBuffer,

+                          0

+                          );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = HcDev->PciIo->Map (

+                          HcDev->PciIo,

+                          EfiPciIoOperationBusMasterCommonBuffer,

+                          CommonBuffer,

+                          &BufferSizeInBytes,

+                          &MappedAddress,

+                          &Mapping

+                          );

+  if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {

+    HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);

+    return EFI_UNSUPPORTED;

+  }

+

+  HcDev->FrameListEntry   = (FRAMELIST_ENTRY *) ((UINTN) MappedAddress);

+

+  HcDev->FrameListMapping = Mapping;

+

+  InitFrameList (HcDev);

+

+  //

+  // Tell the Host Controller where the Frame List lies,

+  // by set the Frame List Base Address Register.

+  //

+  SetFrameListBaseAddress (

+    HcDev->PciIo,

+    FlBaseAddrReg,

+    (UINT32) ((UINTN) HcDev->FrameListEntry)

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FreeFrameListEntry (

+  IN USB_HC_DEV     *HcDev

+  )

+/*++

+

+Routine Description:

+

+  Free FrameList buffer

+

+Arguments:

+

+  HcDev - USB_HC_DEV

+

+Returns:

+

+  EFI_SUCCESS - success

+

+--*/

+{

+  //

+  // Unmap the common buffer for framelist entry,

+  // and free the common buffer.

+  // Uhci's frame list occupy 4k memory.

+  //

+  HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->FrameListMapping);

+  HcDev->PciIo->FreeBuffer (

+                  HcDev->PciIo,

+                  EFI_SIZE_TO_PAGES (4096),

+                  (VOID *) (HcDev->FrameListEntry)

+                  );

+  return EFI_SUCCESS;

+}

+

+VOID

+InitFrameList (

+  IN USB_HC_DEV     *HcDev

+  )

+/*++

+

+Routine Description:

+

+  Initialize FrameList

+

+Arguments:

+

+  HcDev - USB_HC_DEV

+

+Returns:

+   VOID

+

+--*/  

+{

+  FRAMELIST_ENTRY *FrameListPtr;

+  UINTN           Index;

+

+  //

+  // Validate each Frame List Entry

+  //

+  FrameListPtr = HcDev->FrameListEntry;

+  for (Index = 0; Index < 1024; Index++) {

+    FrameListPtr->FrameListPtrTerminate = 1;

+    FrameListPtr->FrameListPtr          = 0;

+    FrameListPtr->FrameListPtrQSelect   = 0;

+    FrameListPtr->FrameListRsvd         = 0;

+    FrameListPtr++;

+  }

+}

+//

+// //////////////////////////////////////////////////////////////

+//

+// QH TD related Helper Functions

+//

+////////////////////////////////////////////////////////////////

+//

+// functions for QH

+//

+EFI_STATUS

+AllocateQHStruct (

+  IN  USB_HC_DEV     *HcDev,

+  OUT QH_STRUCT      **ppQHStruct

+  )

+/*++

+

+Routine Description:

+

+  Allocate QH Struct

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  ppQHStruct  - QH_STRUCT content to return

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  *ppQHStruct = NULL;

+

+  //

+  // QH must align on 16 bytes alignment,

+  // since the memory allocated by UhciAllocatePool ()

+  // is aligned on 32 bytes, it is no need to adjust

+  // the allocated memory returned.

+  //

+  return UhciAllocatePool (HcDev, (UINT8 **) ppQHStruct, sizeof (QH_STRUCT));

+}

+

+

+EFI_STATUS

+CreateQH (

+  IN  USB_HC_DEV     *HcDev,

+  OUT QH_STRUCT      **pptrQH

+  )

+/*++

+

+Routine Description:

+

+  CreateQH

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  ppQHStruct  - QH_STRUCT content to return

+Returns:

+

+  EFI_SUCCESS          - Success

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // allocate align memory for QH_STRUCT

+  //

+  Status = AllocateQHStruct (HcDev, pptrQH);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // init each field of the QH_STRUCT

+  //

+  //

+  // Make QH ready

+  //

+  SetQHHorizontalValidorInvalid (*pptrQH, FALSE);

+  SetQHVerticalValidorInvalid   (*pptrQH, FALSE);

+

+  return EFI_SUCCESS;

+}

+

+VOID

+SetQHHorizontalLinkPtr (

+  IN QH_STRUCT     *PtrQH,

+  IN VOID          *ptrNext

+  )

+/*++

+

+Routine Description:

+

+  Set QH Horizontal Link Pointer

+

+Arguments:

+

+  PtrQH   - QH_STRUCT

+  ptrNext - Data to write 

+

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // Since the QH_STRUCT is aligned on 16-byte boundaries,

+  // Only the highest 28bit of the address is valid

+  // (take 32bit address as an example).

+  //

+  PtrQH->QH.QHHorizontalPtr = (UINT32) ((UINTN) ptrNext >> 4);

+}

+

+VOID *

+GetQHHorizontalLinkPtr (

+  IN QH_STRUCT     *PtrQH

+  )

+/*++

+

+Routine Description:

+

+  Get QH Horizontal Link Pointer

+

+Arguments:

+

+  PtrQH   - QH_STRUCT

+  

+

+Returns:

+

+  Data to return 

+

+--*/

+{

+  //

+  // Restore the 28bit address to 32bit address

+  // (take 32bit address as an example)

+  //

+  return (VOID *) ((UINTN) (PtrQH->QH.QHHorizontalPtr << 4));

+}

+

+VOID

+SetQHHorizontalQHorTDSelect (

+  IN QH_STRUCT     *PtrQH,

+  IN BOOLEAN       bQH

+  )

+/*++

+

+Routine Description:

+

+  Set QH Horizontal QH or TD 

+

+Arguments:

+

+  PtrQH - QH_STRUCT

+  bQH   - TRUE is QH FALSE is TD

+

+Returns:

+  VOID

+

+--*/

+{

+  //

+  // if QH is connected, the specified bit is set,

+  // if TD is connected, the specified bit is cleared.

+  //

+  PtrQH->QH.QHHorizontalQSelect = bQH ? 1 : 0;

+}

+

+

+VOID

+SetQHHorizontalValidorInvalid (

+  IN QH_STRUCT     *PtrQH,

+  IN BOOLEAN       bValid

+  )

+/*++

+

+Routine Description:

+

+  Set QH Horizontal Valid or Invalid

+

+Arguments:

+

+  PtrQH  - QH_STRUCT

+  bValid - TRUE is Valid FALSE is Invalid

+

+Returns:

+  VOID

+

+--*/

+{

+  //

+  // Valid means the horizontal link pointer is valid,

+  // else, it's invalid.

+  //

+  PtrQH->QH.QHHorizontalTerminate = bValid ? 0 : 1;

+}

+

+VOID

+SetQHVerticalLinkPtr (

+  IN QH_STRUCT     *PtrQH,

+  IN VOID          *ptrNext

+  )

+/*++

+

+Routine Description:

+

+  Set QH Vertical Link Pointer

+  

+Arguments:

+

+  PtrQH   - QH_STRUCT

+  ptrNext - Data to write

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // Since the QH_STRUCT is aligned on 16-byte boundaries,

+  // Only the highest 28bit of the address is valid

+  // (take 32bit address as an example).

+  //

+  PtrQH->QH.QHVerticalPtr = (UINT32) ((UINTN) ptrNext >> 4);

+}

+

+VOID *

+GetQHVerticalLinkPtr (

+  IN QH_STRUCT     *PtrQH

+  )

+/*++

+

+Routine Description:

+

+  Get QH Vertical Link Pointer

+  

+Arguments:

+

+  PtrQH   - QH_STRUCT

+ 

+Returns:

+

+   Data to return

+

+--*/

+{

+  //

+  // Restore the 28bit address to 32bit address

+  // (take 32bit address as an example)

+  //

+  return (VOID *) ((UINTN) (PtrQH->QH.QHVerticalPtr << 4));

+}

+

+VOID

+SetQHVerticalQHorTDSelect (

+  IN QH_STRUCT     *PtrQH,

+  IN BOOLEAN       bQH

+  )

+/*++

+

+Routine Description:

+

+  Set QH Vertical QH or TD

+

+Arguments:

+

+  PtrQH - QH_STRUCT

+  bQH   - TRUE is QH FALSE is TD

+

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // Set the specified bit if the Vertical Link Pointer pointing to a QH,

+  // Clear the specified bit if the Vertical Link Pointer pointing to a TD.

+  //

+  PtrQH->QH.QHVerticalQSelect = bQH ? 1 : 0;

+}

+

+BOOLEAN

+IsQHHorizontalQHSelect (

+  IN QH_STRUCT     *PtrQH

+  )

+/*++

+

+Routine Description:

+

+  Is QH Horizontal QH Select

+

+Arguments:

+

+  PtrQH - QH_STRUCT

+ 

+Returns:

+

+  TRUE  - QH

+  FALSE - TD

+

+--*/

+{

+  //

+  // Retrieve the information about whether the Horizontal Link Pointer

+  // pointing to a QH or TD.

+  //

+  return (BOOLEAN) (PtrQH->QH.QHHorizontalQSelect ? TRUE : FALSE);

+}

+

+VOID

+SetQHVerticalValidorInvalid (

+  IN QH_STRUCT     *PtrQH,

+  IN BOOLEAN       IsValid

+  )

+/*++

+

+Routine Description:

+

+  Set QH Vertical Valid or Invalid

+

+Arguments:

+

+  PtrQH   - QH_STRUCT

+  IsValid - TRUE is valid FALSE is invalid

+

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // If TRUE, indicates the Vertical Link Pointer field is valid,

+  // else, the field is invalid.

+  //

+  PtrQH->QH.QHVerticalTerminate = IsValid ? 0 : 1;

+}

+

+

+BOOLEAN

+GetQHVerticalValidorInvalid (

+  IN QH_STRUCT     *PtrQH

+  )

+/*++

+

+Routine Description:

+

+  Get QH Vertical Valid or Invalid

+

+Arguments:

+

+  PtrQH - QH_STRUCT

+

+Returns:

+

+  TRUE  - Valid

+  FALSE - Invalid

+

+--*/

+{

+  //

+  // If TRUE, indicates the Vertical Link Pointer field is valid,

+  // else, the field is invalid.

+  //

+  return (BOOLEAN) (!(PtrQH->QH.QHVerticalTerminate));

+}

+

+BOOLEAN

+GetQHHorizontalValidorInvalid (

+  IN QH_STRUCT     *PtrQH

+  )

+/*++

+

+Routine Description:

+

+  Get QH Horizontal Valid or Invalid

+

+Arguments:

+

+  PtrQH - QH_STRUCT

+

+Returns:

+

+  TRUE  - Valid

+  FALSE - Invalid

+

+--*/

+{

+  //

+  // If TRUE, meaning the Horizontal Link Pointer field is valid,

+  // else, the field is invalid.

+  //

+  return (BOOLEAN) (!(PtrQH->QH.QHHorizontalTerminate));

+}

+//

+// functions for TD

+//

+EFI_STATUS

+AllocateTDStruct (

+  IN  USB_HC_DEV     *HcDev,

+  OUT TD_STRUCT      **ppTDStruct

+  )

+/*++

+

+Routine Description:

+

+  Allocate TD Struct

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  ppTDStruct  - place to store TD_STRUCT pointer

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  *ppTDStruct = NULL;

+

+  //

+  // TD must align on 16 bytes alignment,

+  // since the memory allocated by UhciAllocatePool ()

+  // is aligned on 32 bytes, it is no need to adjust

+  // the allocated memory returned.

+  //

+  return UhciAllocatePool (

+          HcDev,

+          (UINT8 **) ppTDStruct,

+          sizeof (TD_STRUCT)

+          );

+}

+

+EFI_STATUS

+CreateTD (

+  IN  USB_HC_DEV     *HcDev,

+  OUT TD_STRUCT      **pptrTD

+  )

+/*++

+

+Routine Description:

+

+  Create TD

+

+Arguments:

+

+  HcDev   - USB_HC_DEV

+  pptrTD  - TD_STRUCT pointer to store

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate resources

+  EFI_SUCCESS          - Success

+

+--*/

+{

+  EFI_STATUS  Status;

+  //

+  // create memory for TD_STRUCT, and align the memory.

+  //

+  Status = AllocateTDStruct (HcDev, pptrTD);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Make TD ready.

+  //

+  SetTDLinkPtrValidorInvalid (*pptrTD, FALSE);

+

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GenSetupStageTD (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DevAddr,

+  IN  UINT8          Endpoint,

+  IN  BOOLEAN        bSlow,

+  IN  UINT8          *pDevReq,

+  IN  UINT8          RequestLen,

+  OUT TD_STRUCT      **ppTD

+  )

+/*++

+

+Routine Description:

+

+  Generate Setup Stage TD

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  DevAddr     - Device address

+  Endpoint    - Endpoint number 

+  bSlow       - Full speed or low speed

+  pDevReq     - Device request

+  RequestLen  - Request length

+  ppTD        - TD_STRUCT to return

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+  EFI_SUCCESS          - Success

+

+--*/

+{

+  EFI_STATUS  Status;

+  TD_STRUCT   *pTDStruct;

+

+  Status = CreateTD (HcDev, &pTDStruct);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetTDLinkPtr (pTDStruct, NULL);

+

+  //

+  // Depth first fashion

+  //

+  SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);

+

+  //

+  // initialize as the last TD in the QH context,

+  // this field will be updated in the TD linkage process.

+  //

+  SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);

+

+  //

+  // Disable Short Packet Detection by default

+  //

+  EnableorDisableTDShortPacket (pTDStruct, FALSE);

+

+  //

+  // Max error counter is 3, retry 3 times when error encountered.

+  //

+  SetTDControlErrorCounter (pTDStruct, 3);

+

+  //

+  // set device speed attribute

+  // (TRUE - Slow Device; FALSE - Full Speed Device)

+  //

+  SetTDLoworFullSpeedDevice (pTDStruct, bSlow);

+

+  //

+  // Non isochronous transfer TD

+  //

+  SetTDControlIsochronousorNot (pTDStruct, FALSE);

+

+  //

+  // Interrupt On Complete bit be set to zero,

+  // Disable IOC interrupt.

+  //

+  SetorClearTDControlIOC (pTDStruct, FALSE);

+

+  //

+  // Set TD Active bit

+  //

+  SetTDStatusActiveorInactive (pTDStruct, TRUE);

+

+  SetTDTokenMaxLength (pTDStruct, RequestLen);

+

+  SetTDTokenDataToggle0 (pTDStruct);

+

+  SetTDTokenEndPoint (pTDStruct, Endpoint);

+

+  SetTDTokenDeviceAddress (pTDStruct, DevAddr);

+

+  SetTDTokenPacketID (pTDStruct, SETUP_PACKET_ID);

+

+  pTDStruct->pTDBuffer      = (UINT8 *) pDevReq;

+  pTDStruct->TDBufferLength = RequestLen;

+  SetTDDataBuffer (pTDStruct);

+

+  *ppTD = pTDStruct;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GenDataTD (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DevAddr,

+  IN  UINT8          Endpoint,

+  IN  UINT8          *pData,

+  IN  UINT8          Len,

+  IN  UINT8          PktID,

+  IN  UINT8          Toggle,

+  IN  BOOLEAN        bSlow,

+  OUT TD_STRUCT      **ppTD

+  )

+/*++

+

+Routine Description:

+

+  Generate Data Stage TD

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  DevAddr     - Device address

+  Endpoint    - Endpoint number 

+  pData       - Data buffer 

+  Len         - Data length

+  PktID       - Packet ID

+  Toggle      - Data toggle value

+  bSlow       - Full speed or low speed

+  ppTD        - TD_STRUCT to return

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+  EFI_SUCCESS          - Success

+

+--*/

+{

+  TD_STRUCT   *pTDStruct;

+  EFI_STATUS  Status;

+

+  Status = CreateTD (HcDev, &pTDStruct);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetTDLinkPtr (pTDStruct, NULL);

+

+  //

+  // Depth first fashion

+  //

+  SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);

+

+  //

+  // Link pointer pointing to TD struct

+  //

+  SetTDLinkPtrQHorTDSelect (pTDStruct, FALSE);

+

+  //

+  // initialize as the last TD in the QH context,

+  // this field will be updated in the TD linkage process.

+  //

+  SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);

+

+  //

+  // Disable short packet detect

+  //

+  EnableorDisableTDShortPacket (pTDStruct, FALSE);

+  //

+  // Max error counter is 3

+  //

+  SetTDControlErrorCounter (pTDStruct, 3);

+

+  //

+  // set device speed attribute

+  // (TRUE - Slow Device; FALSE - Full Speed Device)

+  //

+  SetTDLoworFullSpeedDevice (pTDStruct, bSlow);

+

+  //

+  // Non isochronous transfer TD

+  //

+  SetTDControlIsochronousorNot (pTDStruct, FALSE);

+

+  //

+  // Disable Interrupt On Complete

+  // Disable IOC interrupt.

+  //

+  SetorClearTDControlIOC (pTDStruct, FALSE);

+

+  //

+  // Set Active bit

+  //

+  SetTDStatusActiveorInactive (pTDStruct, TRUE);

+

+  SetTDTokenMaxLength (pTDStruct, Len);

+

+  if (Toggle) {

+    SetTDTokenDataToggle1 (pTDStruct);

+  } else {

+    SetTDTokenDataToggle0 (pTDStruct);

+  }

+

+  SetTDTokenEndPoint (pTDStruct, Endpoint);

+

+  SetTDTokenDeviceAddress (pTDStruct, DevAddr);

+

+  SetTDTokenPacketID (pTDStruct, PktID);

+

+  pTDStruct->pTDBuffer      = (UINT8 *) pData;

+  pTDStruct->TDBufferLength = Len;

+  SetTDDataBuffer (pTDStruct);

+  *ppTD = pTDStruct;

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateStatusTD (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DevAddr,

+  IN  UINT8          Endpoint,

+  IN  UINT8          PktID,

+  IN  BOOLEAN        bSlow,

+  OUT TD_STRUCT      **ppTD

+  )

+/*++

+

+Routine Description:

+

+  Generate Status Stage TD

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  DevAddr     - Device address

+  Endpoint    - Endpoint number 

+  PktID       - Packet ID

+  bSlow       - Full speed or low speed

+  ppTD        - TD_STRUCT to return

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+  EFI_SUCCESS          - Success

+

+--*/

+{

+  TD_STRUCT   *ptrTDStruct;

+  EFI_STATUS  Status;

+

+  Status = CreateTD (HcDev, &ptrTDStruct);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetTDLinkPtr (ptrTDStruct, NULL);

+

+  //

+  // Depth first fashion

+  //

+  SetTDLinkPtrDepthorBreadth (ptrTDStruct, TRUE);

+

+  //

+  // initialize as the last TD in the QH context,

+  // this field will be updated in the TD linkage process.

+  //

+  SetTDLinkPtrValidorInvalid (ptrTDStruct, FALSE);

+

+  //

+  // Disable short packet detect

+  //

+  EnableorDisableTDShortPacket (ptrTDStruct, FALSE);

+

+  //

+  // Max error counter is 3

+  //

+  SetTDControlErrorCounter (ptrTDStruct, 3);

+

+  //

+  // set device speed attribute

+  // (TRUE - Slow Device; FALSE - Full Speed Device)

+  //

+  SetTDLoworFullSpeedDevice (ptrTDStruct, bSlow);

+

+  //

+  // Non isochronous transfer TD

+  //

+  SetTDControlIsochronousorNot (ptrTDStruct, FALSE);

+

+  //

+  // Disable Interrupt On Complete

+  // Disable IOC interrupt.

+  //

+  SetorClearTDControlIOC (ptrTDStruct, FALSE);

+

+  //

+  // Set TD Active bit

+  //

+  SetTDStatusActiveorInactive (ptrTDStruct, TRUE);

+

+  SetTDTokenMaxLength (ptrTDStruct, 0);

+

+  SetTDTokenDataToggle1 (ptrTDStruct);

+

+  SetTDTokenEndPoint (ptrTDStruct, Endpoint);

+

+  SetTDTokenDeviceAddress (ptrTDStruct, DevAddr);

+

+  SetTDTokenPacketID (ptrTDStruct, PktID);

+

+  ptrTDStruct->pTDBuffer      = NULL;

+  ptrTDStruct->TDBufferLength = 0;

+  SetTDDataBuffer (ptrTDStruct);

+

+  *ppTD = ptrTDStruct;

+

+  return EFI_SUCCESS;

+}

+

+

+VOID

+SetTDLinkPtrValidorInvalid (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bValid

+  )

+/*++

+

+Routine Description:

+

+  Set TD Link Pointer Valid or Invalid

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+  bValid      - TRUE is valid FALSE is invalid

+

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // Valid means the link pointer is valid,

+  // else, it's invalid.

+  //

+  ptrTDStruct->TDData.TDLinkPtrTerminate = (bValid ? 0 : 1);

+}

+

+VOID

+SetTDLinkPtrQHorTDSelect (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bQH

+  )

+/*++

+

+Routine Description:

+

+  Set TD Link Pointer QH or TD Select

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+  bQH         -  TRUE is QH FALSE is TD

+  

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // Indicate whether the Link Pointer pointing to a QH or TD

+  //

+  ptrTDStruct->TDData.TDLinkPtrQSelect = (bQH ? 1 : 0);

+}

+

+VOID

+SetTDLinkPtrDepthorBreadth (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bDepth

+  )

+/*++

+

+Routine Description:

+

+  Set TD Link Pointer depth or bread priority

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+  bDepth      -  TRUE is Depth  FALSE is Breadth

+  

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // If TRUE, indicating the host controller should process in depth first

+  // fashion,

+  // else, the host controller should process in breadth first fashion

+  //

+  ptrTDStruct->TDData.TDLinkPtrDepthSelect = (bDepth ? 1 : 0);

+}

+

+VOID

+SetTDLinkPtr (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN VOID          *ptrNext

+  )

+/*++

+

+Routine Description:

+

+  Set TD Link Pointer

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+  ptrNext     - Pointer to set

+  

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // Set TD Link Pointer. Since QH,TD align on 16-byte boundaries,

+  // only the highest 28 bits are valid. (if take 32bit address as an example)

+  //

+  ptrTDStruct->TDData.TDLinkPtr = (UINT32) ((UINTN) ptrNext >> 4);

+}

+

+VOID *

+GetTDLinkPtr (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+/*++

+

+Routine Description:

+

+  Get TD Link Pointer

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+   

+Returns:

+

+  Pointer to get

+

+--*/

+{

+  //

+  // Get TD Link Pointer. Restore it back to 32bit

+  // (if take 32bit address as an example)

+  //

+  return (VOID *) ((UINTN) (ptrTDStruct->TDData.TDLinkPtr << 4));

+}

+

+BOOLEAN

+IsTDLinkPtrQHOrTD (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+/*++

+

+Routine Description:

+

+  Is TD Link Pointer is QH Or TD

+

+Arguments:

+

+  ptrTDStruct - TODO: add argument description

+

+Returns:

+

+  TRUE  - QH

+  FALSE - TD 

+

+--*/

+{

+  //

+  // Get the information about whether the Link Pointer field pointing to

+  // a QH or a TD.

+  //

+  return (BOOLEAN) (ptrTDStruct->TDData.TDLinkPtrQSelect);

+}

+

+VOID

+EnableorDisableTDShortPacket (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bEnable

+  )

+/*++

+

+Routine Description:

+

+  Enable or Disable TD ShortPacket

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+  bEnable     - TRUE is Enanble FALSE is Disable

+

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // TRUE means enable short packet detection mechanism.

+  //

+  ptrTDStruct->TDData.TDStatusSPD = (bEnable ? 1 : 0);

+}

+

+VOID

+SetTDControlErrorCounter (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINT8         nMaxErrors

+  )

+/*++

+

+Routine Description:

+

+  Set TD Control ErrorCounter

+

+Arguments:

+

+  ptrTDStruct - TD_STRUCT

+  nMaxErrors  - Error counter number

+  

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // valid value of nMaxErrors is 0,1,2,3

+  //

+  if (nMaxErrors > 3) {

+    nMaxErrors = 3;

+  }

+

+  ptrTDStruct->TDData.TDStatusErr = nMaxErrors;

+}

+

+

+VOID

+SetTDLoworFullSpeedDevice (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bLowSpeedDevice

+  )

+{

+  //

+  // TRUE means the TD is targeting at a Low-speed device

+  //

+  ptrTDStruct->TDData.TDStatusLS = (bLowSpeedDevice ? 1 : 0);

+}

+

+VOID

+SetTDControlIsochronousorNot (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       IsIsochronous

+  )

+{

+  //

+  // TRUE means the TD belongs to Isochronous transfer type.

+  //

+  ptrTDStruct->TDData.TDStatusIOS = (IsIsochronous ? 1 : 0);

+}

+

+VOID

+SetorClearTDControlIOC (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       IsSet

+  )

+{

+  //

+  // If this bit is set, it indicates that the host controller should issue

+  // an interrupt on completion of the frame in which this TD is executed.

+  //

+  ptrTDStruct->TDData.TDStatusIOC = IsSet ? 1 : 0;

+}

+

+VOID

+SetTDStatusActiveorInactive (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       IsActive

+  )

+{

+  //

+  // If this bit is set, it indicates that the TD is active and can be

+  // executed.

+  //

+  if (IsActive) {

+    ptrTDStruct->TDData.TDStatus |= 0x80;

+  } else {

+    ptrTDStruct->TDData.TDStatus &= 0x7F;

+  }

+}

+

+UINT16

+SetTDTokenMaxLength (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINT16        MaximumLength

+  )

+{

+  //

+  // Specifies the maximum number of data bytes allowed for the transfer.

+  // the legal value extent is 0 ~ 0x500.

+  //

+  if (MaximumLength > 0x500) {

+    MaximumLength = 0x500;

+  }

+  ptrTDStruct->TDData.TDTokenMaxLen = MaximumLength - 1;

+

+  return MaximumLength;

+}

+

+VOID

+SetTDTokenDataToggle1 (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Set the data toggle bit to DATA1

+  //

+  ptrTDStruct->TDData.TDTokenDataToggle = 1;

+}

+

+VOID

+SetTDTokenDataToggle0 (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Set the data toggle bit to DATA0

+  //

+  ptrTDStruct->TDData.TDTokenDataToggle = 0;

+}

+

+UINT8

+GetTDTokenDataToggle (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Get the data toggle value.

+  //

+  return (UINT8) (ptrTDStruct->TDData.TDTokenDataToggle);

+}

+

+VOID

+SetTDTokenEndPoint (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINTN         EndPoint

+  )

+{

+  //

+  // Set EndPoint Number the TD is targeting at.

+  //

+  ptrTDStruct->TDData.TDTokenEndPt = (UINT8) EndPoint;

+}

+

+VOID

+SetTDTokenDeviceAddress (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINTN         DeviceAddress

+  )

+{

+  //

+  // Set Device Address the TD is targeting at.

+  //

+  ptrTDStruct->TDData.TDTokenDevAddr = (UINT8) DeviceAddress;

+}

+

+VOID

+SetTDTokenPacketID (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINT8         PID

+  )

+{

+  //

+  // Set the Packet Identification to be used for this transaction.

+  //

+  ptrTDStruct->TDData.TDTokenPID = PID;

+}

+

+VOID

+SetTDDataBuffer (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Set the beginning address of the data buffer that will be used

+  // during the transaction.

+  //

+  ptrTDStruct->TDData.TDBufferPtr = (UINT32) ((UINTN) (ptrTDStruct->pTDBuffer));

+}

+

+BOOLEAN

+IsTDStatusActive (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+

+  //

+  // Detect whether the TD is active.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x80);

+}

+

+BOOLEAN

+IsTDStatusStalled (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+

+  //

+  // Detect whether the device/endpoint addressed by this TD is stalled.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x40);

+}

+

+BOOLEAN

+IsTDStatusBufferError (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+  //

+  // Detect whether Data Buffer Error is happened.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x20);

+}

+

+BOOLEAN

+IsTDStatusBabbleError (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+

+  //

+  // Detect whether Babble Error is happened.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x10);

+}

+

+BOOLEAN

+IsTDStatusNAKReceived (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+

+  //

+  // Detect whether NAK is received.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x08);

+}

+

+BOOLEAN

+IsTDStatusCRCTimeOutError (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+

+  //

+  // Detect whether CRC/Time Out Error is encountered.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x04);

+}

+

+BOOLEAN

+IsTDStatusBitStuffError (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  UINT8 TDStatus;

+

+  //

+  // Detect whether Bitstuff Error is received.

+  //

+  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);

+  return (BOOLEAN) (TDStatus & 0x02);

+}

+

+UINT16

+GetTDStatusActualLength (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the actual number of bytes that were tansferred.

+  // the value is encoded as n-1. so return the decoded value.

+  //

+  return (UINT16) ((ptrTDStruct->TDData.TDStatusActualLength) + 1);

+}

+

+UINT16

+GetTDTokenMaxLength (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the maximum number of data bytes allowed for the trnasfer.

+  //

+  return (UINT16) ((ptrTDStruct->TDData.TDTokenMaxLen) + 1);

+}

+

+UINT8

+GetTDTokenEndPoint (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the endpoint number the transaction is targeting at.

+  //

+  return (UINT8) (ptrTDStruct->TDData.TDTokenEndPt);

+}

+

+UINT8

+GetTDTokenDeviceAddress (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the device address the transaction is targeting at.

+  //

+  return (UINT8) (ptrTDStruct->TDData.TDTokenDevAddr);

+}

+

+UINT8

+GetTDTokenPacketID (

+  IN  TD_STRUCT *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the Packet Identification information.

+  //

+  return (UINT8) (ptrTDStruct->TDData.TDTokenPID);

+}

+

+UINT8 *

+GetTDDataBuffer (

+  IN TD_STRUCT    *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the beginning address of the data buffer

+  // that involved in this transaction.

+  //

+  return ptrTDStruct->pTDBuffer;

+}

+

+BOOLEAN

+GetTDLinkPtrValidorInvalid (

+  IN TD_STRUCT     *ptrTDStruct

+  )

+{

+  //

+  // Retrieve the information of whether the Link Pointer field

+  // is valid or not.

+  //

+  if (ptrTDStruct->TDData.TDLinkPtrTerminate) {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+

+}

+

+UINTN

+CountTDsNumber (

+  IN TD_STRUCT     *PtrFirstTD

+  )

+{

+  UINTN     Number;

+  TD_STRUCT *ptr;

+  //

+  // Count the queued TDs number.

+  //

+  Number  = 0;

+  ptr     = PtrFirstTD;

+  while (ptr) {

+    ptr = (TD_STRUCT *) ptr->ptrNextTD;

+    Number++;

+  }

+

+  return Number;

+}

+

+

+

+VOID

+LinkTDToQH (

+  IN QH_STRUCT     *PtrQH,

+  IN TD_STRUCT     *PtrTD

+  )

+/*++

+

+Routine Description:

+

+  Link TD To QH

+

+Arguments:

+

+  PtrQH - QH_STRUCT

+  PtrTD - TD_STRUCT

+Returns:

+

+  VOID

+

+--*/

+{

+  if (PtrQH == NULL || PtrTD == NULL) {

+    return ;

+  }

+  //

+  //  Validate QH Vertical Ptr field

+  //

+  SetQHVerticalValidorInvalid (PtrQH, TRUE);

+

+  //

+  //  Vertical Ptr pointing to TD structure

+  //

+  SetQHVerticalQHorTDSelect (PtrQH, FALSE);

+

+  SetQHVerticalLinkPtr (PtrQH, (VOID *) PtrTD);

+

+  PtrQH->ptrDown = (VOID *) PtrTD;

+}

+

+VOID

+LinkTDToTD (

+  IN TD_STRUCT     *ptrPreTD,

+  IN TD_STRUCT     *PtrTD

+  )

+/*++

+

+Routine Description:

+

+  Link TD To TD

+

+Arguments:

+

+  ptrPreTD - Previous TD_STRUCT to be linked

+  PtrTD    - TD_STRUCT to link

+Returns:

+

+  VOID

+

+--*/

+{

+  if (ptrPreTD == NULL || PtrTD == NULL) {

+    return ;

+  }

+  //

+  // Depth first fashion

+  //

+  SetTDLinkPtrDepthorBreadth (ptrPreTD, TRUE);

+

+  //

+  // Link pointer pointing to TD struct

+  //

+  SetTDLinkPtrQHorTDSelect (ptrPreTD, FALSE);

+

+  //

+  // Validate the link pointer valid bit

+  //

+  SetTDLinkPtrValidorInvalid (ptrPreTD, TRUE);

+

+  SetTDLinkPtr (ptrPreTD, PtrTD);

+

+  ptrPreTD->ptrNextTD = (VOID *) PtrTD;

+}

+//

+// Transfer Schedule related Helper Functions

+//

+VOID

+SetorClearCurFrameListTerminate (

+  IN FRAMELIST_ENTRY     *pCurEntry,

+  IN BOOLEAN             IsSet

+  )

+{

+  //

+  // If TRUE, empty the frame. If FALSE, indicate the Pointer field is valid.

+  //

+  pCurEntry->FrameListPtrTerminate = (IsSet ? 1 : 0);

+}

+

+VOID

+SetCurFrameListQHorTD (

+  IN FRAMELIST_ENTRY     *pCurEntry,

+  IN BOOLEAN             IsQH

+  )

+{

+  //

+  // This bit indicates to the hardware whether the item referenced by the

+  // link pointer is a TD or a QH.

+  //

+  pCurEntry->FrameListPtrQSelect = (IsQH ? 1 : 0);

+}

+

+BOOLEAN

+IsCurFrameListQHorTD (

+  IN FRAMELIST_ENTRY     *pCurEntry

+  )

+{

+  //

+  // TRUE is QH

+  // FALSE is TD

+  //

+  return (BOOLEAN) (pCurEntry->FrameListPtrQSelect);

+}

+

+BOOLEAN

+GetCurFrameListTerminate (

+  IN FRAMELIST_ENTRY     *pCurEntry

+  )

+{

+  //

+  // TRUE means the frame is empty,

+  // FALSE means the link pointer field is valid.

+  //

+  return (BOOLEAN) (pCurEntry->FrameListPtrTerminate);

+}

+

+VOID

+SetCurFrameListPointer (

+  IN FRAMELIST_ENTRY     *pCurEntry,

+  IN UINT8               *ptr

+  )

+{

+  //

+  // Set the pointer field of the frame.

+  //

+  pCurEntry->FrameListPtr = (UINT32) ((UINTN) ptr >> 4);

+}

+

+VOID *

+GetCurFrameListPointer (

+  IN FRAMELIST_ENTRY     *pCurEntry

+  )

+{

+  //

+  // Get the link pointer of the frame.

+  //

+  return (VOID *) ((UINTN) (pCurEntry->FrameListPtr << 4));

+

+}

+

+VOID

+LinkQHToFrameList (

+  IN FRAMELIST_ENTRY     *pEntry,

+  IN UINT16              FrameListIndex,

+  IN QH_STRUCT           *PtrQH

+  )

+/*++

+

+Routine Description:

+

+  Link QH To Frame List

+

+Arguments:

+

+  pEntry           - FRAMELIST_ENTRY

+  FrameListIndex   - Frame List Index

+  PtrQH            - QH to link 

+Returns:

+

+  VOID

+

+--*/

+{

+  FRAMELIST_ENTRY *pCurFrame;

+  QH_STRUCT       *TempQH;

+  QH_STRUCT       *NextTempQH;

+  TD_STRUCT       *TempTD;

+  BOOLEAN         LINK;

+

+  //

+  // Get frame list entry that the link process will begin from.

+  //

+  pCurFrame = pEntry + FrameListIndex;

+

+  //

+  // if current frame is empty

+  // then link the specified QH directly to the Frame List.

+  //

+  if (GetCurFrameListTerminate (pCurFrame)) {

+    

+    //

+    // Link new QH to the frame list entry.

+    //

+    SetCurFrameListQHorTD (pCurFrame, TRUE);

+

+    SetCurFrameListPointer (pCurFrame, (UINT8 *) PtrQH);

+

+    //

+    // clear T bit in the Frame List, indicating that the frame list entry

+    // is no longer empty.

+    //

+    SetorClearCurFrameListTerminate (pCurFrame, FALSE);

+

+    return ;

+

+  } else {

+    //

+    // current frame list has link pointer

+    //

+    if (!IsCurFrameListQHorTD (pCurFrame)) {

+      //

+      //  a TD is linked to the framelist entry

+      //

+      TempTD = (TD_STRUCT *) GetCurFrameListPointer (pCurFrame);

+

+      while (GetTDLinkPtrValidorInvalid (TempTD)) {

+

+        if (IsTDLinkPtrQHOrTD (TempTD)) {

+          //

+          // QH linked next to the TD

+          //

+          break;

+        }

+

+        TempTD = (TD_STRUCT *) GetTDLinkPtr (TempTD);

+      }

+      

+      //

+      // either no ptr linked next to the TD or QH is linked next to the TD

+      //

+      if (!GetTDLinkPtrValidorInvalid (TempTD)) {

+        

+        //

+        // no ptr linked next to the TD

+        //

+        TempTD->ptrNextQH = PtrQH;

+        SetTDLinkPtrQHorTDSelect (TempTD, TRUE);

+        SetTDLinkPtr (TempTD, PtrQH);

+        SetTDLinkPtrValidorInvalid (TempTD, TRUE);

+        return ;

+

+      } else {

+        //

+        //  QH is linked next to the TD

+        //

+        TempQH = (QH_STRUCT *) GetTDLinkPtr (TempTD);

+      }

+    } else {

+      //

+      // a QH is linked to the framelist entry

+      //

+      TempQH = (QH_STRUCT *) GetCurFrameListPointer (pCurFrame);

+    }

+    

+    //

+    // Set up Flag

+    //

+    LINK = TRUE;

+

+    //

+    // Avoid the same qh repeated linking in one frame entry

+    //

+    if (TempQH == PtrQH) {

+      LINK = FALSE;

+      return ;

+    }

+    //

+    // if current QH has next QH connected

+    //

+    while (GetQHHorizontalValidorInvalid (TempQH)) {

+      //

+      // Get next QH pointer

+      //

+      NextTempQH = (QH_STRUCT *) GetQHHorizontalLinkPtr (TempQH);

+

+      //

+      // Bulk transfer qh may be self-linked,

+      // so, the code below is to aVOID dead-loop when meeting self-linked qh

+      //

+      if (NextTempQH == TempQH) {

+        LINK = FALSE;

+        break;

+      }

+

+      TempQH = NextTempQH;

+

+      //

+      // Avoid the same qh repeated linking in one frame entry

+      //

+      if (TempQH == PtrQH) {

+        LINK = FALSE;

+      }

+    }

+

+    if (LINK) {

+      TempQH->ptrNext = PtrQH;

+      SetQHHorizontalQHorTDSelect (TempQH, TRUE);

+      SetQHHorizontalLinkPtr (TempQH, PtrQH);

+      SetQHHorizontalValidorInvalid (TempQH, TRUE);

+    }

+

+    return ;

+  }

+}

+

+EFI_STATUS

+ExecuteControlTransfer (

+  IN  USB_HC_DEV     *HcDev,

+  IN  TD_STRUCT      *PtrTD,

+  IN  UINT32         wIndex,

+  OUT UINTN          *ActualLen,

+  IN  UINTN          TimeOut,

+  OUT UINT32         *TransferResult

+  )

+/*++

+

+Routine Description:

+

+  Execute Control Transfer

+

+Arguments:

+

+  HcDev            - USB_HC_DEV

+  PtrTD            - TD_STRUCT

+  wIndex           - No use

+  ActualLen        - Actual transfered Len 

+  TimeOut          - TimeOut value in milliseconds

+  TransferResult   - Transfer result

+Returns:

+

+  EFI_SUCCESS      - Sucess

+  EFI_DEVICE_ERROR - Error

+  

+

+--*/

+{

+  UINTN   ErrTDPos;

+  UINTN   Delay;

+  UINTN   RequiredLen;

+  BOOLEAN TransferFinished;

+

+  ErrTDPos        = 0;

+  *TransferResult = EFI_USB_NOERROR;

+  RequiredLen     = *ActualLen;

+  *ActualLen      = 0;

+

+  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;

+

+  do {

+    TransferFinished = CheckTDsResults (

+                         PtrTD,

+                         RequiredLen,

+                         TransferResult,

+                         &ErrTDPos,

+                         ActualLen

+                         );

+

+    if (TransferFinished) {

+      break;

+    }

+       

+    //

+    // TD is inactive, which means the control transfer is end.

+    //

+    if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {

+      break;

+    } 

+

+    gBS->Stall (50);

+

+  } while (Delay--);

+

+  if (*TransferResult != EFI_USB_NOERROR) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ExecBulkorSyncInterruptTransfer (

+  IN  USB_HC_DEV     *HcDev,

+  IN  TD_STRUCT      *PtrTD,

+  IN  UINT32         wIndex,

+  OUT UINTN          *ActualLen,

+  OUT UINT8          *DataToggle,

+  IN  UINTN          TimeOut,

+  OUT UINT32         *TransferResult

+  )

+/*++

+

+Routine Description:

+

+  Execute Bulk or SyncInterrupt Transfer

+

+Arguments:

+

+  HcDev            - USB_HC_DEV

+  PtrTD            - TD_STRUCT

+  wIndex           - No use

+  ActualLen        - Actual transfered Len 

+  DataToggle       - Data Toggle

+  TimeOut          - TimeOut value in milliseconds

+  TransferResult   - Transfer result

+Returns:

+

+  EFI_SUCCESS      - Sucess

+  EFI_DEVICE_ERROR - Error

+--*/

+{

+  UINTN   ErrTDPos;

+  UINTN   ScrollNum;

+  UINTN   Delay;

+  UINTN   RequiredLen;

+  BOOLEAN TransferFinished;

+

+  ErrTDPos        = 0;

+  *TransferResult = EFI_USB_NOERROR;

+  RequiredLen     = *ActualLen;

+  *ActualLen      = 0;

+

+  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;

+

+  do {

+

+    TransferFinished = CheckTDsResults (

+                         PtrTD,

+                         RequiredLen,

+                         TransferResult,

+                         &ErrTDPos,

+                         ActualLen

+                         );

+                        

+    if (TransferFinished) {

+      break;

+    }

+       

+    //

+    // TD is inactive, which means bulk or interrupt transfer's end.

+    //    

+    if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {

+      break;

+    }

+

+    gBS->Stall (50);

+

+  } while (Delay--);

+

+  //

+  // has error

+  //

+  if (*TransferResult != EFI_USB_NOERROR) {

+  

+    //

+    // scroll the Data Toggle back to the last success TD

+    //

+    ScrollNum = CountTDsNumber (PtrTD) - ErrTDPos;

+    if (ScrollNum & 0x1) {

+      *DataToggle ^= 1;

+    }

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+DelLinkSingleQH (

+  IN  USB_HC_DEV     *HcDev,

+  IN  QH_STRUCT      *PtrQH,

+  IN  UINT16         FrameListIndex,

+  IN  BOOLEAN        SearchOther,

+  IN  BOOLEAN        Delete

+  )

+/*++

+

+Routine Description:

+

+  Unlink from frame list and delete single QH

+Arguments:

+

+  HcDev            - USB_HC_DEV

+  PtrQH            - QH_STRUCT

+  FrameListIndex   - Frame List Index

+  SearchOther      - Search Other QH

+  Delete           - TRUE is to delete the QH

+Returns:

+  VOID

+--*/

+{

+  FRAMELIST_ENTRY *pCurFrame;

+  UINTN           Index;

+  UINTN           BeginFrame;

+  UINTN           EndFrame;

+  QH_STRUCT       *CurrentQH;

+  QH_STRUCT       *NextQH;

+  TD_STRUCT       *CurrentTD;

+  VOID            *PtrPreQH;

+  BOOLEAN         Found;

+

+  NextQH    = NULL;

+  PtrPreQH  = NULL;

+  Found     = FALSE;

+

+  if (PtrQH == NULL) {

+    return ;

+  }

+

+  if (SearchOther) {

+    BeginFrame  = 0;

+    EndFrame    = 1024;

+  } else {

+    BeginFrame  = FrameListIndex;

+    EndFrame    = FrameListIndex + 1;

+  }

+

+  for (Index = BeginFrame; Index < EndFrame; Index++) {

+

+    pCurFrame = HcDev->FrameListEntry + (Index & 0x3FF);

+

+    if (GetCurFrameListTerminate (pCurFrame)) {

+      //

+      // current frame list is empty,search next frame list entry

+      //

+      continue;

+    }

+

+    if (!IsCurFrameListQHorTD (pCurFrame)) {

+      //

+      // TD linked to current framelist

+      //

+      CurrentTD = (TD_STRUCT *) GetCurFrameListPointer (pCurFrame);

+

+      while (GetTDLinkPtrValidorInvalid (CurrentTD)) {

+

+        if (IsTDLinkPtrQHOrTD (CurrentTD)) {

+          //

+          // QH linked next to the TD,break while ()

+          //

+          break;

+        }

+

+        CurrentTD = (TD_STRUCT *) GetTDLinkPtr (CurrentTD);

+      }

+

+      if (!GetTDLinkPtrValidorInvalid (CurrentTD)) {

+        //

+        // no QH linked next to the last TD,

+        // search next frame list

+        //

+        continue;

+      }

+      

+      //

+      // a QH linked next to the last TD

+      //

+      CurrentQH = (QH_STRUCT *) GetTDLinkPtr (CurrentTD);

+

+      PtrPreQH  = CurrentTD;

+

+    } else {

+      //

+      // a QH linked to current framelist

+      //

+      CurrentQH = (QH_STRUCT *) GetCurFrameListPointer (pCurFrame);

+

+      PtrPreQH  = NULL;

+    }

+

+    if (CurrentQH == PtrQH) {

+

+      if (GetQHHorizontalValidorInvalid (PtrQH)) {

+        //

+        // there is QH connected after the QH found

+        //

+        //

+        // retrieve nex qh pointer of the qh found.

+        //

+        NextQH = GetQHHorizontalLinkPtr (PtrQH);

+      } else {

+        NextQH = NULL;

+      }

+

+      if (PtrPreQH) {

+        //

+        // QH linked to a TD struct

+        //

+        CurrentTD = (TD_STRUCT *) PtrPreQH;

+

+        SetTDLinkPtrValidorInvalid (CurrentTD, (BOOLEAN) ((NextQH == NULL) ? FALSE : TRUE));

+        SetTDLinkPtr (CurrentTD, NextQH);

+        CurrentTD->ptrNextQH = NextQH;

+

+      } else {

+        //

+        // QH linked directly to current framelist entry

+        //

+        SetorClearCurFrameListTerminate (pCurFrame, (BOOLEAN) ((NextQH == NULL) ? TRUE : FALSE));

+        SetCurFrameListPointer (pCurFrame, (UINT8 *) NextQH);

+      }

+

+      Found = TRUE;

+      //

+      // search next framelist entry

+      //

+      continue;

+    }

+

+    while (GetQHHorizontalValidorInvalid (CurrentQH)) {

+

+      PtrPreQH = CurrentQH;

+      //

+      // Get next horizontal linked QH

+      //

+      CurrentQH = (QH_STRUCT *) GetQHHorizontalLinkPtr (CurrentQH);

+      //

+      // the qh is found

+      //

+      if (CurrentQH == PtrQH) {

+        break;

+      }

+    }

+    

+    //

+    // search next frame list entry

+    //

+    if (CurrentQH != PtrQH) {

+      //

+      // Not find the QH

+      //

+      continue;

+    }

+    //

+    // find the specified qh, then delink it from

+    // the horizontal QH list in the frame entry.

+    //

+    

+    if (GetQHHorizontalValidorInvalid (PtrQH)) {

+      //

+      // there is QH connected after the QH found

+      //

+      //

+      // retrieve nex qh pointer of the qh found.

+      //

+      NextQH = GetQHHorizontalLinkPtr (PtrQH);

+

+    } else {

+      //

+      // NO QH connected after the QH found

+      //

+      NextQH = NULL;

+      //

+      // NULL the previous QH's link ptr and set Terminate field.

+      //

+      SetQHHorizontalValidorInvalid ((QH_STRUCT *) PtrPreQH, FALSE);

+    }

+

+    SetQHHorizontalLinkPtr ((QH_STRUCT *) PtrPreQH, NextQH);

+    ((QH_STRUCT *) PtrPreQH)->ptrNext = NextQH;

+

+    Found = TRUE;

+  }

+

+  if (Found && Delete) {

+    //

+    // free memory once used by the specific QH

+    //

+    UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+  }

+

+  return ;

+}

+

+

+VOID

+DeleteQueuedTDs (

+  IN USB_HC_DEV     *HcDev,

+  IN TD_STRUCT      *PtrFirstTD

+  )

+/*++

+Routine Description:

+

+  Delete Queued TDs

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  PtrFirstTD  - TD link list head

+

+Returns:

+  VOID

+

+--*/

+{

+  TD_STRUCT *Tptr1;

+  TD_STRUCT *Tptr2;

+

+  Tptr1 = PtrFirstTD;

+  //

+  // Delete all the TDs in a queue.

+  //

+  while (Tptr1) {

+

+    Tptr2 = Tptr1;

+

+    if (!GetTDLinkPtrValidorInvalid (Tptr2)) {

+      Tptr1 = NULL;

+    } else {

+

+      Tptr1 = GetTDLinkPtr (Tptr2);

+

+      //

+      // TD link to itself

+      //

+      if (Tptr1 == Tptr2) {

+        Tptr1 = NULL;

+      }

+    }

+

+    UhciFreePool (HcDev, (UINT8 *) Tptr2, sizeof (TD_STRUCT));

+  }

+

+  return ;

+}

+

+VOID

+InsertQHTDToINTList (

+  IN USB_HC_DEV                          *HcDev,

+  IN QH_STRUCT                           *PtrQH,

+  IN TD_STRUCT                           *PtrFirstTD,

+  IN UINT8                               DeviceAddress,

+  IN UINT8                               EndPointAddress,

+  IN UINT8                               DataToggle,

+  IN UINTN                               DataLength,

+  IN UINTN                               PollingInterval,

+  IN VOID                                *Mapping,

+  IN UINT8                               *DataBuffer,

+  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction,

+  IN VOID                                *Context

+  )

+/*++

+Routine Description:

+  Insert QH and TD To Interrupt List

+Arguments:

+

+  HcDev           - USB_HC_DEV

+  PtrQH           - QH_STRUCT

+  PtrFirstTD      - First TD_STRUCT

+  DeviceAddress   - Device Address

+  EndPointAddress - EndPoint Address

+  DataToggle      - Data Toggle

+  DataLength      - Data length 

+  PollingInterval - Polling Interval when inserted to frame list

+  Mapping         - Mapping alue  

+  DataBuffer      - Data buffer

+  CallBackFunction- CallBackFunction after interrupt transfeer

+  Context         - CallBackFunction Context passed as function parameter

+Returns:

+  EFI_SUCCESS            - Sucess

+  EFI_INVALID_PARAMETER  - Paremeter is error 

+

+--*/

+{

+  INTERRUPT_LIST  *Node;

+

+  Node = AllocatePool (sizeof (INTERRUPT_LIST));

+  if (Node == NULL) {

+    return ;

+  }

+  

+  //

+  // Fill Node field

+  //

+  Node->Signature     = INTERRUPT_LIST_SIGNATURE;

+  Node->DevAddr       = DeviceAddress;

+  Node->EndPoint      = EndPointAddress;

+  Node->PtrQH         = PtrQH;

+  Node->PtrFirstTD    = PtrFirstTD;

+  Node->DataToggle    = DataToggle;

+  Node->DataLen       = DataLength;

+  Node->PollInterval  = PollingInterval;

+  Node->Mapping       = Mapping;

+  //

+  // DataBuffer is allocated host memory, not mapped memory

+  //

+  Node->DataBuffer        = DataBuffer;

+  Node->InterruptCallBack = CallBackFunction;

+  Node->InterruptContext  = Context;

+

+  //

+  // insert the new interrupt transfer to the head of the list.

+  // The interrupt transfer's monitor function scans the whole list from head

+  // to tail. The new interrupt transfer MUST be added to the head of the list

+  // for the sake of error recovery.

+  //

+  InsertHeadList (&(HcDev->InterruptListHead), &(Node->Link));

+

+  return ;

+}

+

+

+EFI_STATUS

+DeleteAsyncINTQHTDs (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DeviceAddress,

+  IN  UINT8          EndPointAddress,

+  OUT UINT8          *DataToggle

+  )

+/*++

+Routine Description:

+

+  Delete Async INT QH and TDs

+Arguments:

+

+  HcDev           - USB_HC_DEV

+  DeviceAddress   - Device Address

+  EndPointAddress - EndPoint Address

+  DataToggle      - Data Toggle

+

+Returns:

+  EFI_SUCCESS            - Sucess

+  EFI_INVALID_PARAMETER  - Paremeter is error 

+

+--*/

+{

+  QH_STRUCT       *MatchQH;

+  QH_STRUCT       *ptrNextQH;

+  TD_STRUCT       *MatchTD;

+  LIST_ENTRY      *Link;

+  INTERRUPT_LIST  *MatchList;

+  INTERRUPT_LIST  *PtrList;

+  BOOLEAN         Found;

+

+  UINT32          Result;

+  UINTN           ErrTDPos;

+  UINTN           ActualLen;

+

+  MatchQH   = NULL;

+  MatchTD   = NULL;

+  MatchList = NULL;

+

+  //

+  // no interrupt transaction exists

+  //

+  if (IsListEmpty (&(HcDev->InterruptListHead))) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // find the correct QH-TD that need to delete

+  // (by matching Device address and EndPoint number to match QH-TD )

+  //

+  Found = FALSE;

+  Link  = &(HcDev->InterruptListHead);

+  do {

+

+    Link    = Link->ForwardLink;

+    PtrList = INTERRUPT_LIST_FROM_LINK (Link);

+

+    if ((PtrList->DevAddr == DeviceAddress) && ((PtrList->EndPoint & 0x0f) == (EndPointAddress & 0x0f))) {

+      MatchList = PtrList;

+

+      Found     = TRUE;

+      break;

+    }

+

+  } while (Link->ForwardLink != &(HcDev->InterruptListHead));

+

+  if (!Found) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // get current endpoint's data toggle bit and save.

+  //

+  ExecuteAsyncINTTDs (HcDev, MatchList, &Result, &ErrTDPos, &ActualLen);

+  UpdateAsyncINTQHTDs (MatchList, Result, (UINT32) ErrTDPos);

+  *DataToggle = MatchList->DataToggle;

+

+  MatchTD     = MatchList->PtrFirstTD;

+  MatchQH     = MatchList->PtrQH;

+  //

+  // find the first matching QH position in the FrameList

+  //

+  while (MatchQH) {

+

+    ptrNextQH = MatchQH->ptrNextIntQH;

+

+    //

+    // Search all the entries

+    //

+    DelLinkSingleQH (HcDev, MatchQH, 0, TRUE, TRUE);

+

+    MatchQH = ptrNextQH;

+  }

+  

+  //

+  // Call PciIo->Unmap() to unmap the busmaster read/write

+  //

+  HcDev->PciIo->Unmap (HcDev->PciIo, MatchList->Mapping);

+

+  //

+  // free host data buffer allocated,

+  // mapped data buffer is freed by Unmap

+  //

+  if (MatchList->DataBuffer != NULL) {

+    gBS->FreePool (MatchList->DataBuffer);

+  }

+  

+  //

+  // at last delete the TDs, to aVOID problems

+  //

+  DeleteQueuedTDs (HcDev, MatchTD);

+

+  //

+  // remove Match node from interrupt list

+  //

+  RemoveEntryList (&(MatchList->Link));

+  gBS->FreePool (MatchList);

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+CheckTDsResults (

+  IN  TD_STRUCT     *PtrTD,

+  IN  UINTN         RequiredLen,

+  OUT UINT32        *Result,

+  OUT UINTN         *ErrTDPos,

+  OUT UINTN         *ActualTransferSize

+  )

+/*++

+

+Routine Description:

+

+  Check TDs Results

+

+Arguments:

+

+  PtrTD               - TD_STRUCT to check

+  RequiredLen         - Required Len

+  Result              - Transfer result

+  ErrTDPos            - Error TD Position

+  ActualTransferSize  - Actual Transfer Size

+

+Returns:

+

+  TRUE  - Sucess

+  FALSE - Fail

+

+--*/

+{

+  UINTN Len;

+

+  *Result   = EFI_USB_NOERROR;

+  *ErrTDPos = 0;

+

+  //

+  // Init to zero.

+  //

+  *ActualTransferSize = 0;

+

+  while (PtrTD) {

+

+    if (IsTDStatusActive (PtrTD)) {

+      *Result |= EFI_USB_ERR_NOTEXECUTE;

+    }

+

+    if (IsTDStatusStalled (PtrTD)) {

+      *Result |= EFI_USB_ERR_STALL;

+    }

+

+    if (IsTDStatusBufferError (PtrTD)) {

+      *Result |= EFI_USB_ERR_BUFFER;

+    }

+

+    if (IsTDStatusBabbleError (PtrTD)) {

+      *Result |= EFI_USB_ERR_BABBLE;

+    }

+

+    if (IsTDStatusNAKReceived (PtrTD)) {

+      *Result |= EFI_USB_ERR_NAK;

+    }

+

+    if (IsTDStatusCRCTimeOutError (PtrTD)) {

+      *Result |= EFI_USB_ERR_TIMEOUT;

+    }

+

+    if (IsTDStatusBitStuffError (PtrTD)) {

+      *Result |= EFI_USB_ERR_BITSTUFF;

+    }

+   

+    //

+    // if any error encountered, stop processing the left TDs.

+    //

+    if (*Result) {

+      return FALSE;

+    }

+

+    Len = GetTDStatusActualLength (PtrTD) & 0x7FF;

+    *ActualTransferSize += Len;

+

+    if (*ActualTransferSize <= RequiredLen && Len < PtrTD->TDData.TDTokenMaxLen) {

+      //

+      // transter finished and actural length less than required length

+      //

+      goto Done;

+    }

+    //

+    // Accumulate actual transferred data length in each TD.

+    //

+    PtrTD = (TD_STRUCT *) (PtrTD->ptrNextTD);

+    //

+    // Record the first Error TD's position in the queue,

+    // this value is zero-based.

+    //

+    (*ErrTDPos)++;

+  }

+

+Done:

+  return TRUE;

+}

+

+

+VOID

+ExecuteAsyncINTTDs (

+  IN  USB_HC_DEV         *HcDev,

+  IN  INTERRUPT_LIST     *PtrList,

+  OUT UINT32             *Result,

+  OUT UINTN              *ErrTDPos,

+  OUT UINTN              *ActualLen

+  )

+/*++

+

+Routine Description:

+

+  Execute Async Interrupt TDs

+

+Arguments:

+

+  HcDev     - USB_HC_DEV

+  PtrList   - INTERRUPT_LIST

+  Result    - Transfer result

+  ErrTDPos  - Error TD Position

+  ActualTransferSize  - Actual Transfer Size

+  

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // *ErrTDPos is zero-based value, indicating the first error TD's position

+  // in the TDs' sequence.

+  // *ErrTDPos value is only valid when *Result is not equal NOERROR.

+  //

+  UINTN RequiredLen;

+

+  RequiredLen = *ActualLen;

+  CheckTDsResults (PtrList->PtrFirstTD, RequiredLen, Result, ErrTDPos, ActualLen);

+

+  return ;

+}

+

+

+VOID

+UpdateAsyncINTQHTDs (

+  IN INTERRUPT_LIST     *PtrList,

+  IN UINT32             Result,

+  IN UINT32             ErrTDPos

+  )

+/*++

+

+Routine Description:

+

+  Update Async Interrupt QH and TDs

+

+Arguments:

+

+  PtrList   - INTERRUPT_LIST

+  Result    - Transfer reslut

+  ErrTDPos  - Error TD Position

+

+Returns:

+

+  VOID

+

+--*/

+{

+  QH_STRUCT *PtrFirstQH;

+  QH_STRUCT *PtrQH;

+  TD_STRUCT *PtrFirstTD;

+  TD_STRUCT *PtrTD;

+  UINT8     DataToggle;

+  UINT32    Index;

+

+  PtrFirstQH  = PtrList->PtrQH;

+  PtrFirstTD  = PtrList->PtrFirstTD;

+

+  DataToggle  = 0;

+

+  if (Result == EFI_USB_NOERROR) {

+

+    PtrTD = PtrFirstTD;

+    while (PtrTD) {

+      DataToggle  = GetTDTokenDataToggle (PtrTD);

+      PtrTD       = PtrTD->ptrNextTD;

+    }

+    

+    //

+    // save current DataToggle value to interrupt list.

+    // this value is used for tracing the interrupt endpoint DataToggle.

+    // when this interrupt transfer is deleted, the last DataToggle is saved

+    //

+    PtrList->DataToggle = DataToggle;

+

+    PtrTD               = PtrFirstTD;

+

+    //

+    // Since DataToggle bit should toggle after each success transaction,

+    // the First TD's DataToggle bit will be updated to XOR of Last TD's

+    // DataToggle bit. If the First TD's DataToggle bit is not equal Last

+    // TD's DataToggle bit, that means it already be the XOR of Last TD's,

+    // so no update is needed.

+    //

+    if (DataToggle == GetTDTokenDataToggle (PtrFirstTD)) {

+      PtrTD = PtrFirstTD;

+      while (PtrTD) {

+

+        DataToggle ^= 1;

+        if (DataToggle) {

+          SetTDTokenDataToggle1 (PtrTD);

+        } else {

+          SetTDTokenDataToggle0 (PtrTD);

+        }

+

+        PtrTD = PtrTD->ptrNextTD;

+      }

+    }

+    //

+    // restore Link Pointer of QH to First TD

+    // (because QH's Link Pointer will change during TD execution)

+    //

+    PtrQH = PtrFirstQH;

+    while (PtrQH) {

+

+      LinkTDToQH (PtrQH, PtrFirstTD);

+      PtrQH = PtrQH->ptrNextIntQH;

+    }

+    

+    //

+    // set all the TDs active

+    //

+    PtrTD = PtrFirstTD;

+    while (PtrTD) {

+      SetTDStatusActiveorInactive (PtrTD, TRUE);

+      PtrTD = PtrTD->ptrNextTD;

+    }

+

+  } else if (((Result & EFI_USB_ERR_NOTEXECUTE) == EFI_USB_ERR_NOTEXECUTE) ||

+           ((Result & EFI_USB_ERR_NAK) == EFI_USB_ERR_NAK)

+          ) {

+    //

+    // no update

+    //

+  } else {

+    //

+    // Have Errors

+    //

+    PtrTD = PtrFirstTD;

+    //

+    // not first TD error

+    //

+    if (ErrTDPos != 0) {

+      //

+      // get the last success TD

+      //

+      for (Index = 1; Index < ErrTDPos; Index++) {

+        PtrTD = PtrTD->ptrNextTD;

+      }

+      //

+      // update Data Toggle in the interrupt list node

+      //

+      PtrList->DataToggle = GetTDTokenDataToggle (PtrTD);

+

+      //

+      // get the error TD

+      //

+      PtrTD = PtrTD->ptrNextTD;

+

+    } else {

+      PtrList->DataToggle = GetTDTokenDataToggle (PtrTD);

+    }

+    //

+    // do not restore the QH's vertical link pointer,

+    // let the callback function do the rest of error handling.

+    //

+  }

+

+  return ;

+}

+

+VOID

+ReleaseInterruptList (

+  IN USB_HC_DEV         *HcDev,

+  IN LIST_ENTRY         *ListHead

+  )

+/*++

+

+Routine Description:

+

+  Release Interrupt List

+Arguments:

+

+  HcDev     - USB_HC_DEV

+  ListHead  - List head

+

+Returns:

+

+  VOID

+

+--*/

+{

+  LIST_ENTRY      *Link;

+  LIST_ENTRY      *SavedLink;

+  INTERRUPT_LIST  *pNode;

+  TD_STRUCT       *PtrTD;

+  TD_STRUCT       *ptrNextTD;

+  QH_STRUCT       *PtrQH;

+  QH_STRUCT       *SavedQH;

+

+  if (ListHead == NULL) {

+    return ;

+  }

+

+  Link = ListHead;

+

+  //

+  // Free all the resources in the interrupt list

+  //

+  SavedLink = Link->ForwardLink;

+  while (!IsListEmpty (ListHead)) {

+

+    Link      = SavedLink;

+

+    SavedLink = Link->ForwardLink;

+

+    pNode     = INTERRUPT_LIST_FROM_LINK (Link);

+

+    RemoveEntryList (&pNode->Link);

+

+    SavedQH = pNode->PtrQH;

+    for (PtrQH = SavedQH; PtrQH != NULL; PtrQH = SavedQH) {

+      SavedQH = PtrQH->ptrNextIntQH;

+      UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+    }

+

+    PtrTD = pNode->PtrFirstTD;

+    while (PtrTD != NULL) {

+

+      ptrNextTD = PtrTD->ptrNextTD;

+      UhciFreePool (HcDev, (UINT8 *) PtrTD, sizeof (TD_STRUCT));

+      PtrTD = ptrNextTD;

+    }

+

+    gBS->FreePool (pNode);

+  }

+}

+

+

+EFI_STATUS

+InitializeMemoryManagement (

+  IN USB_HC_DEV     *HcDev

+  )

+/*++

+

+Routine Description:

+

+  Initialize Memory Management

+

+Arguments:

+

+  HcDev - USB_HC_DEV

+

+Returns:

+

+  EFI_SUCCESS -  Success

+--*/

+{

+  MEMORY_MANAGE_HEADER  *MemoryHeader;

+  EFI_STATUS            Status;

+  UINTN                 MemPages;

+

+  MemPages  = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;

+  Status    = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  HcDev->MemoryHeader = MemoryHeader;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CreateMemoryBlock (

+  IN  USB_HC_DEV               *HcDev,

+  OUT MEMORY_MANAGE_HEADER     **MemoryHeader,

+  IN  UINTN                    MemoryBlockSizeInPages

+  )

+/*++

+

+Routine Description:

+

+  Use PciIo->AllocateBuffer to allocate common buffer for the memory block,

+  and use PciIo->Map to map the common buffer for Bus Master Read/Write.

+

+

+Arguments:

+

+  HcDev        - USB_HC_DEV

+  MemoryHeader - MEMORY_MANAGE_HEADER to output

+  MemoryBlockSizeInPages - MemoryBlockSizeInPages

+Returns:

+

+  EFI_SUCCESS -  Success

+--*/

+{

+  EFI_STATUS            Status;

+  VOID                  *CommonBuffer;

+  EFI_PHYSICAL_ADDRESS  MappedAddress;

+  UINTN                 MemoryBlockSizeInBytes;

+  VOID                  *Mapping;

+

+  //

+  // Allocate memory for MemoryHeader

+  //

+  *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));

+  if (*MemoryHeader == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  (*MemoryHeader)->Next = NULL;

+

+  //

+  // set Memory block size

+  //

+  (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);

+

+  //

+  // each bit in Bit Array will manage 32 bytes memory in memory block

+  //

+  (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;

+

+  //

+  // Allocate memory for BitArray

+  //

+  (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);

+  if ((*MemoryHeader)->BitArrayPtr == NULL) {

+    gBS->FreePool (*MemoryHeader);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Memory Block uses MemoryBlockSizeInPages pages,

+  // and it is allocated as common buffer use.

+  //

+  Status = HcDev->PciIo->AllocateBuffer (

+                          HcDev->PciIo,

+                          AllocateAnyPages,

+                          EfiBootServicesData,

+                          MemoryBlockSizeInPages,

+                          &CommonBuffer,

+                          0

+                          );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool ((*MemoryHeader)->BitArrayPtr);

+    gBS->FreePool (*MemoryHeader);

+    return Status;

+  }

+

+  MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);

+  Status = HcDev->PciIo->Map (

+                          HcDev->PciIo,

+                          EfiPciIoOperationBusMasterCommonBuffer,

+                          CommonBuffer,

+                          &MemoryBlockSizeInBytes,

+                          &MappedAddress,

+                          &Mapping

+                          );

+  //

+  // if returned Mapped size is less than the size we request,do not support.

+  //

+  if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {

+    HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);

+    gBS->FreePool ((*MemoryHeader)->BitArrayPtr);

+    gBS->FreePool (*MemoryHeader);

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Set Memory block initial address

+  //

+  (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);

+  (*MemoryHeader)->Mapping        = Mapping;

+

+  ZeroMem (

+    (*MemoryHeader)->MemoryBlockPtr,

+    EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FreeMemoryHeader (

+  IN USB_HC_DEV               *HcDev,

+  IN MEMORY_MANAGE_HEADER     *MemoryHeader

+  )

+/*++

+

+Routine Description:

+

+  Free Memory Header

+

+Arguments:

+

+  HcDev         - USB_HC_DEV

+  MemoryHeader  - MemoryHeader to be freed

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+

+--*/

+{

+  if ((MemoryHeader == NULL) || (HcDev == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // unmap the common buffer used by the memory block

+  //

+  HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);

+

+  //

+  // free common buffer

+  //

+  HcDev->PciIo->FreeBuffer (

+                  HcDev->PciIo,

+                  EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),

+                  MemoryHeader->MemoryBlockPtr

+                  );

+  //

+  // free bit array

+  //

+  gBS->FreePool (MemoryHeader->BitArrayPtr);

+  //

+  // free memory header

+  //

+  gBS->FreePool (MemoryHeader);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UhciAllocatePool (

+  IN  USB_HC_DEV     *HcDev,

+  OUT UINT8          **Pool,

+  IN  UINTN          AllocSize

+  )

+/*++

+

+Routine Description:

+

+  Uhci Allocate Pool

+

+Arguments:

+

+  HcDev     - USB_HC_DEV

+  Pool      - Place to store pointer to the memory buffer

+  AllocSize - Alloc Size

+

+Returns:

+

+  EFI_SUCCESS - Success

+

+--*/

+{

+  MEMORY_MANAGE_HEADER  *MemoryHeader;

+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;

+  MEMORY_MANAGE_HEADER  *NewMemoryHeader;

+  UINTN                 RealAllocSize;

+  UINTN                 MemoryBlockSizeInPages;

+  EFI_STATUS            Status;

+

+  *Pool         = NULL;

+

+  MemoryHeader  = HcDev->MemoryHeader;

+  ASSERT (MemoryHeader != NULL);

+

+  //

+  // allocate unit is 32 bytes (align on 32 byte)

+  //

+  if (AllocSize & 0x1F) {

+    RealAllocSize = (AllocSize / 32 + 1) * 32;

+  } else {

+    RealAllocSize = AllocSize;

+  }

+  

+  //

+  // There may be linked MemoryHeaders.

+  // To allocate a free pool in Memory blocks,

+  // must search in the MemoryHeader link list

+  // until enough free pool is found.

+  //

+  Status = EFI_NOT_FOUND;

+  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;

+       TempHeaderPtr = TempHeaderPtr->Next) {

+

+    Status = AllocMemInMemoryBlock (

+              TempHeaderPtr,

+              (VOID **) Pool,

+              RealAllocSize / 32

+              );

+    if (!EFI_ERROR (Status)) {

+      ZeroMem (*Pool, AllocSize);

+      return EFI_SUCCESS;

+    }

+  }

+  

+  //

+  // There is no enough memory,

+  // Create a new Memory Block

+  //

+  

+  //

+  // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,

+  // just allocate a large enough memory block.

+  //

+  if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {

+    MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;

+  } else {

+    MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;

+  }

+

+  Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Link the new Memory Block to the Memory Header list

+  //

+  InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);

+

+  Status = AllocMemInMemoryBlock (

+            NewMemoryHeader,

+            (VOID **) Pool,

+            RealAllocSize / 32

+            );

+

+  if (!EFI_ERROR (Status)) {

+    ZeroMem (*Pool, AllocSize);

+  }

+

+  return Status;

+}

+

+VOID

+UhciFreePool (

+  IN USB_HC_DEV     *HcDev,

+  IN UINT8          *Pool,

+  IN UINTN          AllocSize

+  )

+/*++

+

+Routine Description:

+

+  Uhci Free Pool

+

+Arguments:

+

+  HcDev     - USB_HC_DEV

+  Pool      - Pool to free

+  AllocSize - Pool size

+

+Returns:

+

+  VOID

+

+--*/

+{

+  MEMORY_MANAGE_HEADER  *MemoryHeader;

+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;

+  UINTN                 StartBytePos;

+  UINTN                 Index;

+  UINT8                 StartBitPos;

+  UINT8                 Index2;

+  UINTN                 Count;

+  UINTN                 RealAllocSize;

+

+  MemoryHeader = HcDev->MemoryHeader;

+

+  //

+  // allocate unit is 32 byte (align on 32 byte)

+  //

+  if (AllocSize & 0x1F) {

+    RealAllocSize = (AllocSize / 32 + 1) * 32;

+  } else {

+    RealAllocSize = AllocSize;

+  }

+  //

+  // scan the memory header linked list for

+  // the asigned memory to free.

+  //

+  for (TempHeaderPtr = MemoryHeader;TempHeaderPtr != NULL;

+       TempHeaderPtr = TempHeaderPtr->Next) {

+

+    if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&

+        ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))

+        ) {

+      //

+      // Pool is in the Memory Block area,

+      // find the start byte and bit in the bit array

+      //

+      StartBytePos  = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;

+      StartBitPos   = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);

+

+      //

+      // reset associated bits in bit arry

+      //

+      for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {

+

+        TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));

+        Index2++;

+        if (Index2 == 8) {

+          Index += 1;

+          Index2 = 0;

+        }

+      }

+      //

+      // break the loop

+      //

+      break;

+    }

+  }

+  

+  //

+  // Release emptied memory blocks (only if the memory block is not

+  // the first one in the memory header list

+  //

+  for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {

+    //

+    // Debug

+    //

+    ASSERT (MemoryHeader->Next != NULL);

+

+    if (IsMemoryBlockEmptied (TempHeaderPtr)) {

+

+      DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);

+      //

+      // when the TempHeaderPtr is freed in FreeMemoryHeader(),

+      // the TempHeaderPtr is pointing to nonsense content.

+      //

+      FreeMemoryHeader (HcDev, TempHeaderPtr);

+      //

+      // reset the TempHeaderPtr, continue search for

+      // another empty memory block.

+      //

+      TempHeaderPtr = MemoryHeader->Next;

+      continue;

+    }

+

+    TempHeaderPtr = TempHeaderPtr->Next;

+  }

+}

+

+VOID

+InsertMemoryHeaderToList (

+  IN MEMORY_MANAGE_HEADER     *MemoryHeader,

+  IN MEMORY_MANAGE_HEADER     *NewMemoryHeader

+  )

+/*++

+

+Routine Description:

+

+  Insert Memory Header To List

+

+Arguments:

+

+  MemoryHeader    - MEMORY_MANAGE_HEADER

+  NewMemoryHeader - MEMORY_MANAGE_HEADER

+

+Returns:

+

+  VOID

+

+--*/

+{

+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;

+

+  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;

+       TempHeaderPtr = TempHeaderPtr->Next) {

+    if (TempHeaderPtr->Next == NULL) {

+      TempHeaderPtr->Next = NewMemoryHeader;

+      break;

+    }

+  }

+}

+

+EFI_STATUS

+AllocMemInMemoryBlock (

+  IN  MEMORY_MANAGE_HEADER     *MemoryHeader,

+  OUT VOID                     **Pool,

+  IN  UINTN                    NumberOfMemoryUnit

+  )

+/*++

+

+Routine Description:

+

+  Alloc Memory In MemoryBlock

+

+Arguments:

+

+  MemoryHeader        - MEMORY_MANAGE_HEADER

+  Pool                - Place to store pointer to memory

+  NumberOfMemoryUnit  - Number Of Memory Unit

+

+Returns:

+

+  EFI_NOT_FOUND  - Can't find the free memory 

+  EFI_SUCCESS    - Success

+

+--*/

+{

+  UINTN TempBytePos;

+  UINTN FoundBytePos;

+  UINT8 Index;

+  UINT8 FoundBitPos;

+  UINT8 ByteValue;

+  UINT8 BitValue;

+  UINTN NumberOfZeros;

+  UINTN Count;

+

+  FoundBytePos  = 0;

+  FoundBitPos   = 0;

+  ByteValue     = MemoryHeader->BitArrayPtr[0];

+  NumberOfZeros = 0;

+  Index         = 0;

+

+  for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {

+    

+    //

+    // Pop out BitValue from a byte in TempBytePos.

+    //

+    BitValue = (UINT8) (ByteValue & 0x1);

+    //

+    // right shift the byte

+    //

+    ByteValue /= 2;

+

+    if (BitValue == 0) {

+      //

+      // Found a free bit, the NumberOfZeros only record the number

+      // of those consecutive zeros

+      //

+      NumberOfZeros++;

+      //

+      // Found enough consecutive free space, break the loop

+      //

+      if (NumberOfZeros >= NumberOfMemoryUnit) {

+        break;

+      }

+    } else {

+      //

+      // Encountering a '1', meant the bit is ocupied.

+      //

+      if (NumberOfZeros >= NumberOfMemoryUnit) {

+        //

+        // Found enough consecutive free space,break the loop

+        //

+        break;

+      } else {

+        //

+        // the NumberOfZeros only record the number of those consecutive zeros,

+        // so reset the NumberOfZeros to 0 when encountering '1' before finding

+        // enough consecutive '0's

+        //

+        NumberOfZeros = 0;

+        //

+        // reset the (FoundBytePos,FoundBitPos) to the position of '1'

+        //

+        FoundBytePos  = TempBytePos;

+        FoundBitPos   = Index;

+      }

+    }

+    //

+    // step forward a bit

+    //

+    Index++;

+    if (Index == 8) {

+      //

+      // step forward a byte, getting the byte value,

+      // and reset the bit pos.

+      //

+      TempBytePos += 1;

+      ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];

+      Index     = 0;

+    }

+  }

+

+  if (NumberOfZeros < NumberOfMemoryUnit) {

+    return EFI_NOT_FOUND;

+  }

+  

+  //

+  // Found enough free space.

+  //

+  

+  //

+  // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:

+  //  1)(FoundBytePos,FoundBitPos) record the position

+  //    of the last '1' before the consecutive '0's, it must

+  //    be adjusted to the start position of the consecutive '0's.

+  //  2)the start address of the consecutive '0's is just the start of

+  //    the bitarray. so no need to adjust the values of

+  //    (FoundBytePos,FoundBitPos).

+  //

+  if ((MemoryHeader->BitArrayPtr[0] & bit (0)) != 0) {

+    FoundBitPos += 1;

+  }

+  

+  //

+  // Have the (FoundBytePos,FoundBitPos) make sense.

+  //

+  if (FoundBitPos > 7) {

+    FoundBytePos += 1;

+    FoundBitPos -= 8;

+  }

+  

+  //

+  // Set the memory as allocated

+  //

+  for (TempBytePos = FoundBytePos, Index = FoundBitPos,Count = 0;

+       Count < NumberOfMemoryUnit; Count ++) {

+

+    MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);

+    Index++;

+    if (Index == 8) {

+      TempBytePos += 1;

+      Index = 0;

+    }

+  }

+

+  *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsMemoryBlockEmptied (

+  IN MEMORY_MANAGE_HEADER     *MemoryHeaderPtr

+  )

+/*++

+

+Routine Description:

+

+  Is Memory Block Emptied

+

+Arguments:

+

+  MemoryHeaderPtr - MEMORY_MANAGE_HEADER

+

+Returns:

+

+  TRUE  - Empty

+  FALSE - Not Empty 

+

+--*/

+{

+  UINTN Index;

+

+  for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {

+    if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+VOID

+DelinkMemoryBlock (

+  IN MEMORY_MANAGE_HEADER     *FirstMemoryHeader,

+  IN MEMORY_MANAGE_HEADER     *NeedFreeMemoryHeader

+  )

+/*++

+

+Routine Description:

+

+  Delink Memory Block

+

+Arguments:

+

+  FirstMemoryHeader     - MEMORY_MANAGE_HEADER

+  NeedFreeMemoryHeader  - MEMORY_MANAGE_HEADER

+

+Returns:

+

+  VOID

+

+--*/

+{

+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;

+

+  if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {

+    return ;

+  }

+  for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL;

+       TempHeaderPtr = TempHeaderPtr->Next) {

+

+    if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {

+      //

+      // Link the before and after

+      //

+      TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;

+      break;

+    }

+  }

+}

+

+EFI_STATUS

+DelMemoryManagement (

+  IN USB_HC_DEV     *HcDev

+  )

+/*++

+

+Routine Description:

+

+  Delete Memory Management

+

+Arguments:

+

+  HcDev - USB_HC_DEV

+

+Returns:

+

+  EFI_SUCCESS - Success

+

+--*/

+{

+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;

+

+  for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {

+

+    DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);

+    //

+    // when the TempHeaderPtr is freed in FreeMemoryHeader(),

+    // the TempHeaderPtr is pointing to nonsense content.

+    //

+    FreeMemoryHeader (HcDev, TempHeaderPtr);

+    //

+    // reset the TempHeaderPtr,continue free another memory block.

+    //

+    TempHeaderPtr = HcDev->MemoryHeader->Next;

+  }

+

+  FreeMemoryHeader (HcDev, HcDev->MemoryHeader);

+

+  return EFI_SUCCESS;

+}

+

+

+VOID

+CleanUsbTransactions (

+  IN USB_HC_DEV     *HcDev

+  )

+{

+  //

+  // only asynchronous interrupt transfers are always alive on the bus

+  //

+  ReleaseInterruptList (HcDev, &(HcDev->InterruptListHead));

+}

+

+VOID

+TurnOffUSBEmulation (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo

+  )

+/*++

+  

+  Routine Description:

+    Disable USB Emulation

+  Arguments:

+    PciIo  -  EFI_PCI_IO_PROTOCOL

+  Returns:

+    VOID

+--*/

+{

+  UINT16  Command;

+

+  //

+  // Disable USB Emulation

+  //

+  Command = 0;

+  PciIo->Pci.Write (

+              PciIo,

+              EfiPciIoWidthUint16,

+              USB_EMULATION,

+              1,

+              &Command

+              );

+

+  return ;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c
new file mode 100644
index 0000000..1eba8be
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c
@@ -0,0 +1,3498 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    Uhci.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#include "uhci.h"

+

+//

+// Prototypes

+// Driver model protocol interface

+//

+

+EFI_STATUS

+EFIAPI

+UHCIDriverEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  );

+

+//

+// UHCI interface functions

+//

+

+EFI_STATUS

+EFIAPI

+UHCIReset (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT16                  Attributes

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIGetState (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  OUT EFI_USB_HC_STATE        *State

+  );

+

+EFI_STATUS

+EFIAPI

+UHCISetState (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  EFI_USB_HC_STATE        State

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIControlTransfer (

+  IN       EFI_USB_HC_PROTOCOL        *This,

+  IN       UINT8                      DeviceAddress,

+  IN       BOOLEAN                    IsSlowDevice,

+  IN       UINT8                      MaximumPacketLength,

+  IN       EFI_USB_DEVICE_REQUEST     *Request,

+  IN       EFI_USB_DATA_DIRECTION     TransferDirection,

+  IN OUT   VOID                       *Data, OPTIONAL

+  IN OUT   UINTN                      *DataLength, OPTIONAL

+  IN       UINTN                      TimeOut,

+  OUT      UINT32                     *TransferResult

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIBulkTransfer (

+  IN       EFI_USB_HC_PROTOCOL     *This,

+  IN       UINT8                   DeviceAddress,

+  IN       UINT8                   EndPointAddress,

+  IN       UINT8                   MaximumPacketLength,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN OUT   UINT8                   *DataToggle,

+  IN       UINTN                   TimeOut,

+  OUT      UINT32                  *TransferResult

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIAsyncInterruptTransfer (

+  IN       EFI_USB_HC_PROTOCOL                * This,

+  IN       UINT8                              DeviceAddress,

+  IN       UINT8                              EndPointAddress,

+  IN       BOOLEAN                            IsSlowDevice,

+  IN       UINT8                              MaxiumPacketLength,

+  IN       BOOLEAN                            IsNewTransfer,

+  IN OUT   UINT8                              *DataToggle,

+  IN       UINTN                              PollingInterval, OPTIONAL

+  IN       UINTN                              DataLength, OPTIONAL

+  IN       EFI_ASYNC_USB_TRANSFER_CALLBACK    CallBackFunction, OPTIONAL

+  IN       VOID                               *Context OPTIONAL

+  );

+

+EFI_STATUS

+EFIAPI

+UHCISyncInterruptTransfer (

+  IN       EFI_USB_HC_PROTOCOL     *This,

+  IN       UINT8                   DeviceAddress,

+  IN       UINT8                   EndPointAddress,

+  IN       BOOLEAN                 IsSlowDevice,

+  IN       UINT8                   MaximumPacketLength,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN OUT   UINT8                   *DataToggle,

+  IN       UINTN                   TimeOut,

+  OUT      UINT32                  *TransferResult

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIIsochronousTransfer (

+  IN       EFI_USB_HC_PROTOCOL     *This,

+  IN       UINT8                   DeviceAddress,

+  IN       UINT8                   EndPointAddress,

+  IN       UINT8                   MaximumPacketLength,

+  IN OUT   VOID                    *Data,

+  IN       UINTN                   DataLength,

+  OUT      UINT32                  *TransferResult

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIAsyncIsochronousTransfer (

+  IN       EFI_USB_HC_PROTOCOL                 * This,

+  IN       UINT8                               DeviceAddress,

+  IN       UINT8                               EndPointAddress,

+  IN       UINT8                               MaximumPacketLength,

+  IN OUT   VOID                                *Data,

+  IN       UINTN                               DataLength,

+  IN       EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,

+  IN       VOID                                *Context OPTIONAL

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIGetRootHubPortNumber (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  OUT UINT8                   *PortNumber

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIGetRootHubPortStatus (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                   PortNumber,

+  OUT EFI_USB_PORT_STATUS     *PortStatus

+  );

+

+EFI_STATUS

+EFIAPI

+UHCISetRootHubPortFeature (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                   PortNumber,

+  IN  EFI_USB_PORT_FEATURE    PortFeature

+  );

+

+EFI_STATUS

+EFIAPI

+UHCIClearRootHubPortFeature (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                   PortNumber,

+  IN  EFI_USB_PORT_FEATURE    PortFeature

+  );

+

+//

+// Asynchronous interrupt transfer monitor function

+//

+VOID

+EFIAPI

+MonitorInterruptTrans (

+  IN EFI_EVENT     Event,

+  IN VOID          *Context

+  );

+

+//

+// UHCI Driver Global Variables

+//

+EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {

+  UHCIDriverBindingSupported,

+  UHCIDriverBindingStart,

+  UHCIDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+UHCIDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    that has UsbHcProtocol installed will be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller,         - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS          OpenStatus;

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  USB_CLASSC          UsbClassCReg;

+

+  //

+  // Test whether there is PCI IO Protocol attached on the controller handle.

+  //

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiPciIoProtocolGuid,

+                      (VOID **) &PciIo,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+  if (EFI_ERROR (OpenStatus)) {

+    return OpenStatus;

+  }

+

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint8,

+                        CLASSC,

+                        sizeof (USB_CLASSC) / sizeof (UINT8),

+                        &UsbClassCReg

+                        );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Test whether the controller belongs to UHCI type

+  //

+  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL)         ||

+      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||

+      (UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)) {

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+EFIAPI

+UHCIDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Starting the Usb UHCI Driver

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+    EFI_DEVICE_ERROR    - This driver cannot be started due to device

+                          Error

+    EFI_OUT_OF_RESOURCES

+

+--*/

+{ 

+  EFI_STATUS              Status; 

+  UINTN                   FlBaseAddrReg; 

+  EFI_PCI_IO_PROTOCOL     *PciIo; 

+  USB_HC_DEV              *HcDev;

+  

+  HcDev = NULL;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Turn off USB emulation

+  //

+  TurnOffUSBEmulation (PciIo);

+

+  //

+  // Enable the USB Host Controller

+  //

+  Status = PciIo->Attributes (

+                    PciIo,

+                    EfiPciIoAttributeOperationEnable,

+                    EFI_PCI_DEVICE_ENABLE,

+                    NULL

+                    );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // allocate memory for UHC private data structure

+  //

+  HcDev = AllocateZeroPool (sizeof (USB_HC_DEV));

+  if (HcDev == NULL) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // init EFI_USB_HC_PROTOCOL protocol interface and install the protocol

+  //

+  HcDev->UsbHc.Reset                    = UHCIReset;

+  HcDev->UsbHc.GetState                 = UHCIGetState;

+  HcDev->UsbHc.SetState                 = UHCISetState;

+  HcDev->UsbHc.ControlTransfer          = UHCIControlTransfer;

+  HcDev->UsbHc.BulkTransfer             = UHCIBulkTransfer;

+  HcDev->UsbHc.AsyncInterruptTransfer   = UHCIAsyncInterruptTransfer;

+  HcDev->UsbHc.SyncInterruptTransfer    = UHCISyncInterruptTransfer;

+  HcDev->UsbHc.IsochronousTransfer      = UHCIIsochronousTransfer;

+  HcDev->UsbHc.AsyncIsochronousTransfer = UHCIAsyncIsochronousTransfer;

+  HcDev->UsbHc.GetRootHubPortNumber     = UHCIGetRootHubPortNumber;

+  HcDev->UsbHc.GetRootHubPortStatus     = UHCIGetRootHubPortStatus;

+  HcDev->UsbHc.SetRootHubPortFeature    = UHCISetRootHubPortFeature;

+  HcDev->UsbHc.ClearRootHubPortFeature  = UHCIClearRootHubPortFeature;

+

+  HcDev->UsbHc.MajorRevision            = 0x1;

+  HcDev->UsbHc.MinorRevision            = 0x1;

+

+  //

+  //  Init UHCI private data structures

+  //

+  HcDev->Signature  = USB_HC_DEV_SIGNATURE;

+  HcDev->PciIo      = PciIo;

+

+  FlBaseAddrReg     = USBFLBASEADD;

+

+  //

+  // Allocate and Init Host Controller's Frame List Entry

+  //

+  Status = CreateFrameList (HcDev, (UINT32) FlBaseAddrReg);

+  if (EFI_ERROR (Status)) {

+

+    if (HcDev != NULL) {

+      gBS->FreePool (HcDev);

+    }

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  //  Init interrupt list head in the HcDev structure.

+  //

+  InitializeListHead (&(HcDev->InterruptListHead));

+

+  //

+  //  Create timer for interrupt transfer result polling

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_NOTIFY,

+                  MonitorInterruptTrans,

+                  HcDev,

+                  &HcDev->InterruptTransTimer

+                  );

+  if (EFI_ERROR (Status)) {

+

+    FreeFrameListEntry (HcDev);

+

+    if (HcDev != NULL) {

+      gBS->FreePool (HcDev);

+    }

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Here set interrupt transfer polling timer in 50ms unit.

+  //

+  Status = gBS->SetTimer (

+                  HcDev->InterruptTransTimer,

+                  TimerPeriodic,

+                  INTERRUPT_POLLING_TIME

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (HcDev->InterruptTransTimer);

+

+    FreeFrameListEntry (HcDev);

+

+    if (HcDev != NULL) {

+      gBS->FreePool (HcDev);

+    }

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // QH,TD structures must in common buffer that will be

+  // accessed by both cpu and usb bus master at the same time.

+  // so, there must has memory management for QH,TD structures.

+  //

+  Status = InitializeMemoryManagement (HcDev);

+  if (EFI_ERROR (Status)) {

+  

+    gBS->CloseEvent (HcDev->InterruptTransTimer);

+    

+    FreeFrameListEntry (HcDev);

+

+    if (HcDev != NULL) {

+      gBS->FreePool (HcDev);

+    }

+

+    gBS->CloseProtocol (

+           Controller, 

+           &gEfiPciIoProtocolGuid, 

+           This->DriverBindingHandle,   

+           Controller

+           );

+    return Status;

+  }

+  

+  //

+  // Install Host Controller Protocol

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &Controller,

+                  &gEfiUsbHcProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &HcDev->UsbHc

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (HcDev->InterruptTransTimer);

+    FreeFrameListEntry (HcDev);

+    DelMemoryManagement (HcDev);

+

+    if (HcDev != NULL) {

+      gBS->FreePool (HcDev);

+    }

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+  

+  //

+  // component name protocol.

+  //

+  HcDev->ControllerNameTable = NULL;

+  AddUnicodeString (

+    "eng",

+    gUhciComponentName.SupportedLanguages,

+    &HcDev->ControllerNameTable,

+    (CHAR16 *) L"Usb Universal Host Controller"

+    );

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+UnInstallUHCInterface (

+  IN  EFI_HANDLE              Controller,

+  IN  EFI_USB_HC_PROTOCOL     *This

+  )

+/*++

+  Routine Description:

+    UnInstall UHCInterface

+  Arguments:

+    Controller        - Controller handle

+    This              - Protocol instance pointer.

+  Returns:

+    EFI_SUCCESS

+    others

+--*/

+{

+  USB_HC_DEV  *HcDev;

+

+  HcDev = USB_HC_DEV_FROM_THIS (This);

+

+  gBS->UninstallProtocolInterface (

+        Controller,

+        &gEfiUsbHcProtocolGuid,

+        &HcDev->UsbHc

+        );

+

+  //

+  // first stop USB Host Controller

+  //

+  This->SetState (This, EfiUsbHcStateHalt);

+

+  //

+  // Delete interrupt transfer polling timer

+  //

+  gBS->CloseEvent (HcDev->InterruptTransTimer);

+

+  //

+  // Delete all the asynchronous interrupt transfers in the interrupt list

+  // and free associated memory

+  //

+  ReleaseInterruptList (HcDev, &(HcDev->InterruptListHead));

+

+  //

+  // free Frame List Entry.

+  //

+  FreeFrameListEntry (HcDev);

+

+  //

+  // Free common buffer allocated for QH,TD structures

+  //

+  DelMemoryManagement (HcDev);

+

+  if (HcDev->ControllerNameTable) {

+    FreeUnicodeStringTable (HcDev->ControllerNameTable);

+  }

+  //

+  // Disable the USB Host Controller

+  //

+  HcDev->PciIo->Attributes (

+                  HcDev->PciIo,

+                  EfiPciIoAttributeOperationDisable,

+                  EFI_PCI_DEVICE_ENABLE,

+                  NULL

+                  );

+

+  gBS->FreePool (HcDev);

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+UHCIDriverBindingStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN UINTN                           NumberOfChildren,

+  IN EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    Controller        - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS

+    others

+

+--*/

+{

+  EFI_USB_HC_PROTOCOL *UsbHc;

+  EFI_STATUS          OpenStatus;

+

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiUsbHcProtocolGuid,

+                      (VOID **) &UsbHc,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                      );

+

+  //

+  // Test whether the Controller handler passed in is a valid

+  // Usb controller handle that should be supported, if not,

+  // return the error status directly

+  //

+  if (EFI_ERROR (OpenStatus)) {

+    return OpenStatus;

+  }

+  //

+  // free all the controller related memory and uninstall UHCI Protocol.

+  //

+  UnInstallUHCInterface (Controller, UsbHc);

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return EFI_SUCCESS;

+

+}

+

+

+EFI_STATUS

+EFIAPI

+UHCIReset (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN UINT16                  Attributes

+  )

+/*++

+  

+  Routine Description:

+    Provides software reset for the USB host controller.

+  

+  Arguments:

+  

+  This        A pointer to the EFI_USB_HC_PROTOCOL instance.  

+  

+  Attributes  A bit mask of the reset operation to perform. 

+              See below for a list of the supported bit mask values.

+  

+  #define EFI_USB_HC_RESET_GLOBAL           0x0001

+  #define EFI_USB_HC_RESET_HOST_CONTROLLER  0x0002

+

+  EFI_USB_HC_RESET_GLOBAL 

+        If this bit is set, a global reset signal will be sent to the USB bus.

+        This resets all of the USB bus logic, including the USB host 

+        controller hardware and all the devices attached on the USB bus.

+  EFI_USB_HC_RESET_HOST_CONTROLLER  

+        If this bit is set, the USB host controller hardware will be reset. 

+        No reset signal will be sent to the USB bus.

+  

+  Returns:

+    EFI_SUCCESS 

+        The reset operation succeeded.

+    EFI_INVALID_PARAMETER 

+        Attributes is not valid.

+    EFI_DEVICE_ERROR  

+        An error was encountered while attempting to perform 

+        the reset operation.

+--*/

+{

+  BOOLEAN     Match;

+  USB_HC_DEV  *HcDev;

+  UINT32      CommandRegAddr;

+  UINT32      FlBaseAddrReg;

+  UINT16      Command;

+  EFI_STATUS  Status;

+

+  Match           = FALSE;

+  HcDev           = USB_HC_DEV_FROM_THIS (This);

+

+  CommandRegAddr  = (UINT32) (USBCMD);

+  FlBaseAddrReg   = (UINT32) (USBFLBASEADD);

+

+  if ((Attributes & EFI_USB_HC_RESET_GLOBAL) != 0) {

+    Match = TRUE;

+    //

+    // set the Global Reset bit in the command register

+    //

+    Status = ReadUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              &Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Command |= USBCMD_GRESET;

+    Status = WriteUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // Wait 50ms for root port to let reset complete

+    // See UHCI spec page122 Reset signaling

+    //

+    gBS->Stall (ROOT_PORT_REST_TIME);

+

+    //

+    // Clear the Global Reset bit to zero.

+    //

+    Command &= ~USBCMD_GRESET;

+    Status = WriteUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // UHCI spec page120 reset recovery time

+    //

+    gBS->Stall (PORT_RESET_RECOVERY_TIME);

+  }

+

+  if ((Attributes & EFI_USB_HC_RESET_HOST_CONTROLLER) != 0) {

+    Match = TRUE;

+    //

+    // set Host Controller Reset bit to 1

+    //

+    Status = ReadUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              &Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Command |= USBCMD_HCRESET;

+    Status = WriteUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // this bit will be reset by Host Controller when reset is completed.

+    // wait 10ms to let reset complete

+    //

+    gBS->Stall (PORT_RESET_RECOVERY_TIME);

+  }

+

+  if (!Match) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // Delete all old transactions on the USB bus

+  //

+  CleanUsbTransactions (HcDev);

+

+  //

+  // Initialize Universal Host Controller's Frame List Data Structure

+  //

+  InitFrameList (HcDev);

+

+  //

+  // Reset may cause Frame List Base Address Register reset to zero,

+  // so set the original value back again.

+  //

+  SetFrameListBaseAddress (

+    HcDev->PciIo,

+    FlBaseAddrReg,

+    (UINT32) ((UINTN) HcDev->FrameListEntry)

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIGetState (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  OUT EFI_USB_HC_STATE        *State

+  )

+/*++

+  

+  Routine Description:

+    Retrieves current state of the USB host controller.

+  

+  Arguments:

+    

+    This      A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    State     A pointer to the EFI_USB_HC_STATE data structure that 

+              indicates current state of the USB host controller.  

+              Type EFI_USB_HC_STATE is defined below.

+              

+    typedef enum {

+      EfiUsbHcStateHalt,

+      EfiUsbHcStateOperational,

+      EfiUsbHcStateSuspend,

+      EfiUsbHcStateMaximum

+    } EFI_USB_HC_STATE;

+  

+  Returns:

+    EFI_SUCCESS 

+            The state information of the host controller was returned in State.

+    EFI_INVALID_PARAMETER 

+            State is NULL.

+    EFI_DEVICE_ERROR  

+            An error was encountered while attempting to retrieve the 

+            host controller's current state.  

+--*/

+{

+  USB_HC_DEV  *HcDev;

+  UINT32      CommandRegAddr;

+  UINT32      StatusRegAddr;

+  UINT16      UhcCommand;

+  UINT16      UhcStatus;

+  EFI_STATUS  Status;

+

+  if (State == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HcDev           = USB_HC_DEV_FROM_THIS (This);

+

+  CommandRegAddr  = (UINT32) (USBCMD);

+  StatusRegAddr   = (UINT32) (USBSTS);

+

+  Status = ReadUHCCommandReg (

+            HcDev->PciIo,

+            CommandRegAddr,

+            &UhcCommand

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = ReadUHCCommandReg (

+            HcDev->PciIo,

+            StatusRegAddr,

+            &UhcStatus

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (UhcCommand & USBCMD_EGSM) {

+    *State = EfiUsbHcStateSuspend;

+    return EFI_SUCCESS;

+  }

+

+  if ((UhcStatus & USBSTS_HCH) == 0) {

+    *State = EfiUsbHcStateOperational;

+  } else {

+    *State = EfiUsbHcStateHalt;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+UHCISetState (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN EFI_USB_HC_STATE        State

+  )

+/*++

+  

+  Routine Description:

+    Sets the USB host controller to a specific state.

+  

+  Arguments:

+    

+    This      A pointer to the EFI_USB_HC_PROTOCOL instance.

+

+    State     Indicates the state of the host controller that will be set.

+  

+  Returns:

+    EFI_SUCCESS 

+          The USB host controller was successfully placed in the state 

+          specified by State.

+    EFI_INVALID_PARAMETER 

+          State is invalid.

+    EFI_DEVICE_ERROR  

+          Failed to set the state specified by State due to device error.  

+--*/

+{

+  USB_HC_DEV        *HcDev;

+  UINT32            CommandRegAddr;

+  UINT32            StatusRegAddr;

+  UINT16            Command;

+  EFI_USB_HC_STATE  CurrentState;

+  EFI_STATUS        Status;

+

+  HcDev           = USB_HC_DEV_FROM_THIS (This);

+

+  CommandRegAddr  = (UINT32) (USBCMD);

+  StatusRegAddr   = (UINT32) (USBSTS);

+

+  Status          = UHCIGetState (This, &CurrentState);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (State) {

+

+  case EfiUsbHcStateHalt:

+    if (CurrentState == EfiUsbHcStateHalt) {

+      return EFI_SUCCESS;

+    }

+

+    Status = ReadUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              &Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Command &= ~USBCMD_RS;

+

+    Status = WriteUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    StatusRegAddr = (UINT32) (USBSTS);

+    //

+    // ensure the HC is in halt status after send the stop command

+    //

+    if (WaitForUHCHalt (HcDev->PciIo, StatusRegAddr, STALL_1_SECOND) == EFI_TIMEOUT) {

+      return EFI_DEVICE_ERROR;

+    }

+    break;

+

+  case EfiUsbHcStateOperational:

+    if (IsHostSysOrProcessErr (HcDev->PciIo, StatusRegAddr)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    switch (CurrentState) {

+

+    case EfiUsbHcStateOperational:

+      return EFI_SUCCESS;

+

+    case EfiUsbHcStateHalt:

+      //

+      // Set Run/Stop bit to 1.

+      //

+      Status = ReadUHCCommandReg (

+                HcDev->PciIo,

+                CommandRegAddr,

+                &Command

+                );

+      if (EFI_ERROR (Status)) {

+        return EFI_DEVICE_ERROR;

+      }

+

+      Command |= USBCMD_RS | USBCMD_MAXP;

+      Status = WriteUHCCommandReg (

+                HcDev->PciIo,

+                CommandRegAddr,

+                Command

+                );

+      if (EFI_ERROR (Status)) {

+        return EFI_DEVICE_ERROR;

+      }

+

+      break;

+

+    case EfiUsbHcStateSuspend:

+      Status = ReadUHCCommandReg (

+                HcDev->PciIo,

+                CommandRegAddr,

+                &Command

+                );

+      if (EFI_ERROR (Status)) {

+        return EFI_DEVICE_ERROR;

+      }

+      

+      //

+      // FGR(Force Global Resume) bit is 0

+      //

+      if ((Command | (~USBCMD_FGR)) != 0xFF) {

+        //

+        // Write FGR bit to 1

+        //

+        Command |= USBCMD_FGR;

+        WriteUHCCommandReg (

+          HcDev->PciIo,

+          CommandRegAddr,

+          Command

+          );

+      }

+      

+      //

+      // wait 20ms to let resume complete

+      // (20ms is specified by UHCI spec)

+      //

+      gBS->Stall (FORCE_GLOBAL_RESUME_TIME);

+

+      //

+      // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0

+      //

+      Command &= ~USBCMD_FGR;

+      Command &= ~USBCMD_EGSM;

+      Command |= USBCMD_RS;

+      WriteUHCCommandReg (

+        HcDev->PciIo,

+        CommandRegAddr,

+        Command

+        );

+      break;

+

+    default:

+      break;

+    }

+    break;

+

+  case EfiUsbHcStateSuspend:

+    if (CurrentState == EfiUsbHcStateSuspend) {

+      return EFI_SUCCESS;

+    }

+

+    Status = UHCISetState (This, EfiUsbHcStateHalt);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // Set Enter Global Suspend Mode bit to 1.

+    //

+    Status = ReadUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              &Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Command |= USBCMD_EGSM;

+    Status = WriteUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIGetRootHubPortNumber (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  OUT UINT8                   *PortNumber

+  )

+/*++

+  

+  Routine Description:

+    Retrieves the number of root hub ports.

+    

+  Arguments:

+  

+    This        A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    PortNumber  A pointer to the number of the root hub ports.

+  

+  Returns:

+    EFI_SUCCESS 

+          The port number was retrieved successfully.

+    EFI_INVALID_PARAMETER 

+          PortNumber is NULL.

+    EFI_DEVICE_ERROR  

+          An error was encountered while attempting to 

+          retrieve the port number.  

+--*/

+{

+  USB_HC_DEV  *HcDev;

+  UINT32      PSAddr;

+  UINT16      RHPortControl;

+  UINT32      Index;

+  EFI_STATUS  Status;

+

+  HcDev = USB_HC_DEV_FROM_THIS (This);

+

+  if (PortNumber == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *PortNumber = 0;

+

+  for (Index = 0; Index < 2; Index++) {

+    PSAddr = (UINT32) (USBPORTSC1 + Index * 2);

+    Status = ReadRootPortReg (

+              HcDev->PciIo,

+              PSAddr,

+              &RHPortControl

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // Port Register content is valid

+    //

+    if (RHPortControl != 0xff) {

+      (*PortNumber)++;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIGetRootHubPortStatus (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                   PortNumber,

+  OUT EFI_USB_PORT_STATUS     *PortStatus

+  )

+/*++

+  

+  Routine Description:

+    Retrieves the current status of a USB root hub port.

+  

+  Arguments:

+  

+    This        A pointer to the EFI_USB_HC_PROTOCOL.

+    

+    PortNumber  Specifies the root hub port from which the status 

+                is to be retrieved.  This value is zero-based. For example, 

+                if a root hub has two ports, then the first port is numbered 0,

+                and the second port is numbered 1.

+    

+    PortStatus  A pointer to the current port status bits and 

+                port status change bits.  

+  

+  Returns:

+    EFI_SUCCESS 

+        The status of the USB root hub port specified by PortNumber 

+        was returned in PortStatus.

+    EFI_INVALID_PARAMETER 

+        PortNumber is invalid. 

+    EFI_DEVICE_ERROR - Can't read register      

+--*/

+{

+  USB_HC_DEV  *HcDev;

+  UINT32      PSAddr;

+  UINT16      RHPortStatus;

+  UINT8       TotalPortNumber;

+  EFI_STATUS  Status;

+

+  if (PortStatus == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  UHCIGetRootHubPortNumber (This, &TotalPortNumber);

+  if (PortNumber >= TotalPortNumber) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HcDev   = USB_HC_DEV_FROM_THIS (This);

+  PSAddr  = (UINT32) (USBPORTSC1 + PortNumber * 2);

+

+  //

+  // Clear port status

+  //

+  PortStatus->PortStatus        = 0;

+  PortStatus->PortChangeStatus  = 0;

+

+  Status = ReadRootPortReg (

+            HcDev->PciIo,

+            PSAddr,

+            &RHPortStatus

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //    Fill Port Status bits

+  //

+  

+  //

+  // Current Connect Status

+  //

+  if (RHPortStatus & USBPORTSC_CCS) {

+    PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;

+  }

+  //

+  // Port Enabled/Disabled

+  //

+  if (RHPortStatus & USBPORTSC_PED) {

+    PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;

+  }

+  

+  //

+  // Port Suspend

+  //

+  if (RHPortStatus & USBPORTSC_SUSP) {

+    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;

+  }

+  

+  //

+  // Port Reset

+  //

+  if (RHPortStatus & USBPORTSC_PR) {

+    PortStatus->PortStatus |= USB_PORT_STAT_RESET;

+  }

+  

+  //

+  // Low Speed Device Attached

+  //

+  if (RHPortStatus & USBPORTSC_LSDA) {

+    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;

+  }

+  //

+  //   Fill Port Status Change bits

+  //

+  

+  //

+  // Connect Status Change

+  //

+  if (RHPortStatus & USBPORTSC_CSC) {

+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;

+  }

+  

+  //

+  // Port Enabled/Disabled Change

+  //

+  if (RHPortStatus & USBPORTSC_PEDC) {

+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCISetRootHubPortFeature (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                   PortNumber,

+  IN  EFI_USB_PORT_FEATURE    PortFeature

+  )

+/*++

+  

+  Routine Description:

+    Sets a feature for the specified root hub port.

+  

+  Arguments:

+  

+    This        A pointer to the EFI_USB_HC_PROTOCOL.

+    

+    PortNumber  Specifies the root hub port whose feature 

+                is requested to be set.

+    

+    PortFeature Indicates the feature selector associated 

+                with the feature set request. 

+  

+  Returns:

+    EFI_SUCCESS 

+        The feature specified by PortFeature was set for the 

+        USB root hub port specified by PortNumber.

+    EFI_INVALID_PARAMETER 

+        PortNumber is invalid or PortFeature is invalid.

+    EFI_DEVICE_ERROR

+        Can't read register

+--*/

+{

+  USB_HC_DEV  *HcDev;

+  UINT32      PSAddr;

+  UINT32      CommandRegAddr;

+  //

+  // root hub port status

+  //

+  UINT16      RHPortControl;

+  UINT16      Command;

+  UINT8       TotalPortNumber;

+  EFI_STATUS  Status;

+

+  UHCIGetRootHubPortNumber (This, &TotalPortNumber);

+  if (PortNumber >= TotalPortNumber) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HcDev           = USB_HC_DEV_FROM_THIS (This);

+

+  PSAddr          = (UINT32) (USBPORTSC1 + PortNumber * 2);

+  CommandRegAddr  = (UINT32) (USBCMD);

+

+  Status = ReadRootPortReg (

+            HcDev->PciIo,

+            PSAddr,

+            &RHPortControl

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (PortFeature) {

+

+  case EfiUsbPortSuspend:

+    Status = ReadUHCCommandReg (

+              HcDev->PciIo,

+              CommandRegAddr,

+              &Command

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (!(Command & USBCMD_EGSM)) {

+      //

+      // if global suspend is not active, can set port suspend

+      //

+      RHPortControl &= 0xfff5;

+      RHPortControl |= USBPORTSC_SUSP;

+    }

+    break;

+

+  case EfiUsbPortReset:

+    RHPortControl &= 0xfff5;

+    //

+    // Set the reset bit

+    //

+    RHPortControl |= USBPORTSC_PR;

+    break;

+

+  case EfiUsbPortPower:

+    break;

+

+  case EfiUsbPortEnable:

+    RHPortControl &= 0xfff5;

+    RHPortControl |= USBPORTSC_PED;

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+

+  WriteRootPortReg (

+    HcDev->PciIo,

+    PSAddr,

+    RHPortControl

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIClearRootHubPortFeature (

+  IN  EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                   PortNumber,

+  IN  EFI_USB_PORT_FEATURE    PortFeature

+  )

+/*++

+  

+  Routine Description:

+    Clears a feature for the specified root hub port.

+  

+  Arguments:

+  

+    This        A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    PortNumber  Specifies the root hub port whose feature 

+                is requested to be cleared.

+    

+    PortFeature Indicates the feature selector associated with the 

+                feature clear request.

+                  

+  Returns:

+    EFI_SUCCESS 

+        The feature specified by PortFeature was cleared for the 

+        USB root hub port specified by PortNumber.

+    EFI_INVALID_PARAMETER 

+        PortNumber is invalid or PortFeature is invalid.

+    EFI_DEVICE_ERROR

+        Can't read register

+--*/

+{

+  USB_HC_DEV  *HcDev;

+  UINT32      PSAddr;

+  UINT16      RHPortControl;

+  UINT8       TotalPortNumber;

+  EFI_STATUS  Status;

+

+  UHCIGetRootHubPortNumber (This, &TotalPortNumber);

+

+  if (PortNumber >= TotalPortNumber) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HcDev   = USB_HC_DEV_FROM_THIS (This);

+  PSAddr  = (UINT32) (USBPORTSC1 + PortNumber * 2);

+

+  Status = ReadRootPortReg (

+            HcDev->PciIo,

+            PSAddr,

+            &RHPortControl

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (PortFeature) {

+  //

+  // clear PORT_ENABLE feature means disable port.

+  //

+  case EfiUsbPortEnable:

+    RHPortControl &= 0xfff5;

+    RHPortControl &= ~USBPORTSC_PED;

+    break;

+

+  //

+  // clear PORT_SUSPEND feature means resume the port.

+  // (cause a resume on the specified port if in suspend mode)

+  //

+  case EfiUsbPortSuspend:

+    RHPortControl &= 0xfff5;

+    RHPortControl &= ~USBPORTSC_SUSP;

+    break;

+

+  //

+  // no operation

+  //

+  case EfiUsbPortPower:

+    break;

+

+  //

+  // clear PORT_RESET means clear the reset signal.

+  //

+  case EfiUsbPortReset:

+    RHPortControl &= 0xfff5;

+    RHPortControl &= ~USBPORTSC_PR;

+    break;

+

+  //

+  // clear connect status change

+  //

+  case EfiUsbPortConnectChange:

+    RHPortControl &= 0xfff5;

+    RHPortControl |= USBPORTSC_CSC;

+    break;

+

+  //

+  // clear enable/disable status change

+  //

+  case EfiUsbPortEnableChange:

+    RHPortControl &= 0xfff5;

+    RHPortControl |= USBPORTSC_PEDC;

+    break;

+

+  //

+  // root hub does not support this request

+  //

+  case EfiUsbPortSuspendChange:

+    break;

+

+  //

+  // root hub does not support this request

+  //

+  case EfiUsbPortOverCurrentChange:

+    break;

+

+  //

+  // root hub does not support this request

+  //

+  case EfiUsbPortResetChange:

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+

+  WriteRootPortReg (

+    HcDev->PciIo,

+    PSAddr,

+    RHPortControl

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIControlTransfer (

+  IN       EFI_USB_HC_PROTOCOL        *This,

+  IN       UINT8                      DeviceAddress,

+  IN       BOOLEAN                    IsSlowDevice,

+  IN       UINT8                      MaximumPacketLength,

+  IN       EFI_USB_DEVICE_REQUEST     *Request,

+  IN       EFI_USB_DATA_DIRECTION     TransferDirection,

+  IN OUT   VOID                       *Data, OPTIONAL

+  IN OUT   UINTN                      *DataLength, OPTIONAL

+  IN       UINTN                      TimeOut,

+  OUT      UINT32                     *TransferResult

+  )

+/*++

+  

+  Routine Description:

+    Submits control transfer to a target USB device.

+  

+  Arguments:

+    

+    This          A pointer to the EFI_USB_HC_PROTOCOL instance.

+

+    DeviceAddress Represents the address of the target device on the USB,

+                  which is assigned during USB enumeration.

+

+    IsSlowDevice  Indicates whether the target device is slow device 

+                  or full-speed device.

+    

+    MaximumPacketLength Indicates the maximum packet size that the 

+                        default control transfer endpoint is capable of 

+                        sending or receiving.

+    

+    Request       A pointer to the USB device request that will be sent 

+                  to the USB device. 

+    

+    TransferDirection Specifies the data direction for the transfer.

+                      There are three values available, DataIn, DataOut 

+                      and NoData.

+    

+    Data          A pointer to the buffer of data that will be transmitted 

+                  to USB device or received from USB device.

+    

+    DataLength    Indicates the size, in bytes, of the data buffer 

+                  specified by Data.

+    

+    TimeOut       Indicates the maximum time, in microseconds, 

+                  which the transfer is allowed to complete.

+    

+    TransferResult  A pointer to the detailed result information generated 

+                    by this control transfer.

+                    

+  Returns:

+    EFI_SUCCESS 

+        The control transfer was completed successfully.

+    EFI_OUT_OF_RESOURCES  

+        The control transfer could not be completed due to a lack of resources.

+    EFI_INVALID_PARAMETER 

+        Some parameters are invalid.

+    EFI_TIMEOUT 

+        The control transfer failed due to timeout.

+    EFI_DEVICE_ERROR  

+        The control transfer failed due to host controller or device error. 

+        Caller should check TranferResult for detailed error information.

+

+--*/

+{

+  USB_HC_DEV            *HcDev;

+  UINT32                StatusReg;

+  UINT32                FrameNumReg;

+  UINT8                 PktID;

+  QH_STRUCT             *PtrQH;

+  TD_STRUCT             *PtrTD;

+  TD_STRUCT             *PtrPreTD;

+  TD_STRUCT             *PtrSetupTD;

+  TD_STRUCT             *PtrStatusTD;

+  EFI_STATUS            Status;

+  UINTN                 Index;

+  UINTN                 DataLen;

+  UINT8                 *PtrDataSource;

+  UINT8                 *Ptr;

+  UINT8                 DataToggle;

+  UINT16                LoadFrameListIndex;

+  UINT8                 PktSize;

+

+  UINT8                 *RequestMappedAddress;

+  VOID                  *RequestMapping;

+  UINTN                 RequestLen;

+

+  EFI_PHYSICAL_ADDRESS  TempPtr;

+  VOID                  *Mapping;

+

+  TD_STRUCT             *PtrFirstDataTD;

+  TD_STRUCT             *ptrLastDataTD;

+  BOOLEAN               FirstTD;

+

+  FirstTD               = FALSE;

+  RequestMappedAddress  = NULL;

+  RequestMapping        = NULL;

+  Mapping               = NULL;

+  PtrFirstDataTD        = NULL;

+  ptrLastDataTD         = NULL;

+  PktID                 = INPUT_PACKET_ID;

+  Mapping               = NULL;

+  HcDev                 = USB_HC_DEV_FROM_THIS (This);

+  StatusReg             = (UINT32) (USBSTS);

+  FrameNumReg           = (UINT32) (USBFRNUM);

+  PtrPreTD              = NULL;

+  PtrTD                 = NULL;

+

+  //

+  // Parameters Checking

+  //

+  if (Request == NULL || TransferResult == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // if errors exist that cause host controller halt,

+  // then return EFI_DEVICE_ERROR.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    *TransferResult = EFI_USB_ERR_SYSTEM;

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // low speed usb devices are limited to only an eight-byte

+  // maximum data payload size

+  //

+  if (IsSlowDevice && (MaximumPacketLength != 8)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (MaximumPacketLength != 8  && 

+      MaximumPacketLength != 16 &&

+      MaximumPacketLength != 32 &&

+      MaximumPacketLength != 64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((TransferDirection != EfiUsbNoData) && (DataLength == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  switch (TransferDirection) {

+

+  case EfiUsbDataIn:

+    PktID         = INPUT_PACKET_ID;

+    PtrDataSource = Data;

+    DataLen       = *DataLength;

+

+    //

+    // map the source data buffer for bus master access.

+    // BusMasterWrite means cpu read

+    //

+    Status = HcDev->PciIo->Map (

+                            HcDev->PciIo,

+                            EfiPciIoOperationBusMasterWrite,

+                            PtrDataSource,

+                            &DataLen,

+                            &TempPtr,

+                            &Mapping

+                            );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Ptr = (UINT8 *) ((UINTN) TempPtr);

+    break;

+

+  case EfiUsbDataOut:

+    PktID         = OUTPUT_PACKET_ID;

+    PtrDataSource = Data;

+    DataLen       = *DataLength;

+

+    //

+    // map the source data buffer for bus master access.

+    // BusMasterRead means cpu write

+    //

+    Status = HcDev->PciIo->Map (

+                            HcDev->PciIo,

+                            EfiPciIoOperationBusMasterRead,

+                            PtrDataSource,

+                            &DataLen,

+                            &TempPtr,

+                            &Mapping

+                            );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Ptr = (UINT8 *) ((UINTN) TempPtr);

+    break;

+

+  //

+  // no data stage

+  //

+  case EfiUsbNoData:

+    if ((DataLength != NULL) && (*DataLength != 0)) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    PktID         = OUTPUT_PACKET_ID;

+    PtrDataSource = NULL;

+    DataLen       = 0;

+    Ptr           = NULL;

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = ClearStatusReg (HcDev->PciIo, StatusReg);

+  if (EFI_ERROR (Status)) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // create QH structure and init

+  //

+  Status = CreateQH (HcDev, &PtrQH);

+  if (EFI_ERROR (Status)) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+    return Status;

+  }

+  

+  //

+  // map the Request for bus master access.

+  // BusMasterRead means cpu write

+  //

+  RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);

+  Status = HcDev->PciIo->Map (

+                          HcDev->PciIo,

+                          EfiPciIoOperationBusMasterRead,

+                          (UINT8 *) Request,

+                          &RequestLen,

+                          &TempPtr,

+                          &RequestMapping

+                          );

+

+  if (EFI_ERROR (Status)) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+    UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+    return Status;

+  }

+

+  RequestMappedAddress = (UINT8 *) ((UINTN) TempPtr);

+

+  //

+  // generate Setup Stage TD

+  //

+  Status = GenSetupStageTD (

+            HcDev,

+            DeviceAddress,

+            0,

+            IsSlowDevice,

+            (UINT8 *) RequestMappedAddress,

+            sizeof (EFI_USB_DEVICE_REQUEST),

+            &PtrSetupTD

+            );

+

+  if (EFI_ERROR (Status)) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+    UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+    HcDev->PciIo->Unmap (HcDev->PciIo, RequestMapping);

+    return Status;

+  }

+  

+  //

+  //  Data Stage of Control Transfer

+  //

+  DataToggle  = 1;

+  FirstTD     = TRUE;

+  while (DataLen > 0) {

+    //

+    // create TD structures and link together

+    //

+    

+    //

+    // PktSize is the data load size that each TD carries.

+    //

+    PktSize = (UINT8) DataLen;

+    if (DataLen > MaximumPacketLength) {

+      PktSize = MaximumPacketLength;

+    }

+

+    Status = GenDataTD (

+              HcDev,

+              DeviceAddress,

+              0,

+              Ptr,

+              PktSize,

+              PktID,

+              DataToggle,

+              IsSlowDevice,

+              &PtrTD

+              );

+

+    if (EFI_ERROR (Status)) {

+      //

+      // free all resources occupied

+      //

+      HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+      UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+      HcDev->PciIo->Unmap (HcDev->PciIo, RequestMapping);

+      DeleteQueuedTDs (HcDev, PtrSetupTD);

+      DeleteQueuedTDs (HcDev, PtrFirstDataTD);

+      return Status;

+    }

+    

+    //

+    // Link two TDs in vertical depth

+    //

+    if (FirstTD) {

+      PtrFirstDataTD            = PtrTD;

+      PtrFirstDataTD->ptrNextTD = NULL;

+      FirstTD                   = FALSE;

+    } else {

+      LinkTDToTD (PtrPreTD, PtrTD);

+    }

+

+    PtrPreTD = PtrTD;

+

+    DataToggle ^= 1;

+    Ptr += PktSize;

+    DataLen -= PktSize;

+  }

+

+  ptrLastDataTD = PtrTD;

+

+  //

+  // Status Stage of Control Transfer

+  //

+  if (PktID == OUTPUT_PACKET_ID) {

+    PktID = INPUT_PACKET_ID;

+  } else {

+    PktID = OUTPUT_PACKET_ID;

+  }

+  

+  //

+  // create Status Stage TD structure

+  //

+  Status = CreateStatusTD (

+            HcDev,

+            DeviceAddress,

+            0,

+            PktID,

+            IsSlowDevice,

+            &PtrStatusTD

+            );

+

+  if (EFI_ERROR (Status)) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+    UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+    HcDev->PciIo->Unmap (HcDev->PciIo, RequestMapping);

+    DeleteQueuedTDs (HcDev, PtrSetupTD);

+    DeleteQueuedTDs (HcDev, PtrFirstDataTD);

+    return Status;

+  }

+

+  if (IsSlowDevice) {

+    //

+    // link setup TD structures to QH structure

+    //

+    LinkTDToQH (PtrQH, PtrSetupTD);

+

+    LoadFrameListIndex = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+

+    //

+    // link QH-TDs to total 100 frame list entry to speed up the execution.

+    //

+    for (Index = 0; Index < 100; Index++) {

+      LinkQHToFrameList (

+        HcDev->FrameListEntry,

+        (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+        PtrQH

+        );

+    }

+    //

+    // Poll QH-TDs execution and get result.

+    // detail status is returned

+    //

+    Status = ExecuteControlTransfer (

+               HcDev,

+               PtrSetupTD,

+               LoadFrameListIndex,

+               DataLength,

+               TimeOut,

+               TransferResult

+               );

+    //

+    // Remove Control Transfer QH-TDs structure from the frame list

+    // and update the pointers in the Frame List

+    // and other pointers in other related QH structures.

+    //

+    for (Index = 0; Index < 100; Index++) {

+      DelLinkSingleQH (

+        HcDev,

+        PtrQH,

+        (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+        FALSE,

+        FALSE

+        );

+    }

+    //

+    // delete setup stage TD; the QH is reserved for the next stages.

+    //

+    DeleteQueuedTDs (HcDev, PtrSetupTD);

+

+    //

+    // if setup stage error, return error

+    //

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+    //

+    // some control transfers do not have Data Stage

+    //

+    if (PtrFirstDataTD != NULL) {

+

+      LinkTDToQH (PtrQH, PtrFirstDataTD);

+      LoadFrameListIndex = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+

+      for (Index = 0; Index < 500; Index++) {

+        LinkQHToFrameList (

+          HcDev->FrameListEntry,

+          (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+          PtrQH

+          );

+      }

+

+      Status = ExecuteControlTransfer (

+                HcDev,

+                PtrFirstDataTD,

+                LoadFrameListIndex,

+                DataLength,

+                TimeOut,

+                TransferResult

+                );

+

+      for (Index = 0; Index < 500; Index++) {

+        DelLinkSingleQH (

+          HcDev,

+          PtrQH,

+          (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+          FALSE,

+          FALSE

+          );

+      }

+      //

+      // delete data stage TD; the QH is reserved for the next stage.

+      //

+      DeleteQueuedTDs (HcDev, PtrFirstDataTD);

+    }

+    //

+    // if data stage error, goto done and return error

+    //

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    LinkTDToQH (PtrQH, PtrStatusTD);

+    //

+    // get the frame list index that the QH-TDs will be linked to.

+    //

+    LoadFrameListIndex = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+

+    for (Index = 0; Index < 100; Index++) {

+      //

+      // put the QH-TDs directly or indirectly into the proper place

+      // in the Frame List

+      //

+      LinkQHToFrameList (

+        HcDev->FrameListEntry,

+        (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+        PtrQH

+        );

+    }

+    //

+    // Poll QH-TDs execution and get result.

+    // detail status is returned

+    //

+    Status = ExecuteControlTransfer (

+              HcDev,

+              PtrStatusTD,

+              LoadFrameListIndex,

+              DataLength,

+              TimeOut,

+              TransferResult

+              );

+

+    //

+    // Delete Control Transfer QH-TDs structure

+    // and update the pointers in the Frame List

+    // and other pointers in other related QH structures.

+    //

+    // TRUE means must search other framelistindex

+    //

+    for (Index = 0; Index < 100; Index++) {

+      DelLinkSingleQH (

+        HcDev,

+        PtrQH,

+        (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+        FALSE,

+        FALSE

+        );

+    }

+

+    DeleteQueuedTDs (HcDev, PtrStatusTD);

+

+  } else {

+    //

+    // link setup stage TD with data stage TD

+    //

+    PtrPreTD = PtrSetupTD;

+    if (PtrFirstDataTD != NULL) {

+      LinkTDToTD (PtrSetupTD, PtrFirstDataTD);

+      PtrPreTD = ptrLastDataTD;

+    }

+    //

+    // link status TD with previous TD

+    //

+    LinkTDToTD (PtrPreTD, PtrStatusTD);

+

+    //

+    // link QH with TD

+    //

+    LinkTDToQH (PtrQH, PtrSetupTD);

+

+    LoadFrameListIndex = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+    for (Index = 0; Index < 500; Index++) {

+      //

+      // put the QH-TDs directly or indirectly into the proper place

+      // in the Frame List

+      //

+      LinkQHToFrameList (

+        HcDev->FrameListEntry,

+        (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+        PtrQH

+        );

+    }

+    //

+    // Poll QH-TDs execution and get result.

+    // detail status is returned

+    //

+    Status = ExecuteControlTransfer (

+              HcDev,

+              PtrSetupTD,

+              LoadFrameListIndex,

+              DataLength,

+              TimeOut,

+              TransferResult

+              );

+    //

+    // Remove Control Transfer QH-TDs structure from the frame list

+    // and update the pointers in the Frame List

+    // and other pointers in other related QH structures.

+    //

+    for (Index = 0; Index < 500; Index++) {

+      DelLinkSingleQH (

+        HcDev,

+        PtrQH,

+        (UINT16) ((LoadFrameListIndex + Index) & 0x3FF),

+        FALSE,

+        FALSE

+        );

+    }

+

+    DeleteQueuedTDs (HcDev, PtrSetupTD);

+  }

+

+Done:

+

+  UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+

+  if (Mapping != NULL) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+  }

+

+  if (RequestMapping != NULL) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, RequestMapping);

+  }

+  //

+  // if has errors that cause host controller halt,

+  // then return EFI_DEVICE_ERROR directly.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    *TransferResult |= EFI_USB_ERR_SYSTEM;

+    return EFI_DEVICE_ERROR;

+  }

+

+  ClearStatusReg (HcDev->PciIo, StatusReg);

+  HcDev->PciIo->Flush (HcDev->PciIo);

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIBulkTransfer (

+  IN       EFI_USB_HC_PROTOCOL     *This,

+  IN       UINT8                   DeviceAddress,

+  IN       UINT8                   EndPointAddress,

+  IN       UINT8                   MaximumPacketLength,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN OUT   UINT8                   *DataToggle,

+  IN       UINTN                   TimeOut,

+  OUT      UINT32                  *TransferResult

+  )

+/*++

+  

+  Routine Description:

+    Submits bulk transfer to a bulk endpoint of a USB device.

+    

+  Arguments:

+    

+    This          A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    DeviceAddress Represents the address of the target device on the USB,

+                  which is assigned during USB enumeration.

+    EndPointAddress   The combination of an endpoint number and an 

+                      endpoint direction of the target USB device. 

+                      Each endpoint address supports data transfer in 

+                      one direction except the control endpoint 

+                      (whose default endpoint address is 0). 

+                      It is the caller's responsibility to make sure that 

+                      the EndPointAddress represents a bulk endpoint. 

+                      

+    MaximumPacketLength Indicates the maximum packet size the target endpoint

+                        is capable of sending or receiving.

+                        

+    Data          A pointer to the buffer of data that will be transmitted 

+                  to USB device or received from USB device.

+    DataLength    When input, indicates the size, in bytes, of the data buffer

+                  specified by Data. When output, indicates the actually 

+                  transferred data size.

+                  

+    DataToggle    A pointer to the data toggle value. On input, it indicates 

+                  the initial data toggle value the bulk transfer should adopt;

+                  on output, it is updated to indicate the data toggle value 

+                  of the subsequent bulk transfer. 

+                  

+    TimeOut       Indicates the maximum time, in microseconds, which the 

+                  transfer is allowed to complete.

+                  

+    TransferResult  A pointer to the detailed result information of the 

+                    bulk transfer.

+

+  Returns:

+    EFI_SUCCESS 

+        The bulk transfer was completed successfully.

+    EFI_OUT_OF_RESOURCES  

+        The bulk transfer could not be submitted due to lack of resource.

+    EFI_INVALID_PARAMETER 

+        Some parameters are invalid.

+    EFI_TIMEOUT 

+        The bulk transfer failed due to timeout.

+    EFI_DEVICE_ERROR  

+        The bulk transfer failed due to host controller or device error.

+        Caller should check TranferResult for detailed error information.

+

+--*/

+{

+  USB_HC_DEV              *HcDev;

+  UINT32                  StatusReg;

+  UINT32                  FrameNumReg;

+  UINTN                   DataLen;

+  QH_STRUCT               *PtrQH;

+  TD_STRUCT               *PtrFirstTD;

+  TD_STRUCT               *PtrTD;

+  TD_STRUCT               *PtrPreTD;

+  UINT16                  LoadFrameListIndex;

+  UINT16                  SavedFrameListIndex;

+  UINT8                   PktID;

+  UINT8                   *PtrDataSource;

+  UINT8                   *Ptr;

+  BOOLEAN                 IsFirstTD;

+  EFI_STATUS              Status;

+  UINT32                  Index;

+  UINT8                   PktSize;

+

+  EFI_USB_DATA_DIRECTION  TransferDirection;

+  //

+  //  Used to calculate how many entries are linked to the

+  //  specified bulk transfer QH-TDs

+  //

+  UINT32                  LinkTimes;

+

+  BOOLEAN                 ShortPacketEnable;

+  EFI_PHYSICAL_ADDRESS    TempPtr;

+  VOID                    *Mapping;

+

+  HcDev             = USB_HC_DEV_FROM_THIS (This);

+  StatusReg         = (UINT32) (USBSTS);

+  FrameNumReg       = (UINT32) (USBFRNUM);

+  PktID             = INPUT_PACKET_ID;

+  PtrTD             = NULL;

+  PtrFirstTD        = NULL;

+  PtrPreTD          = NULL;

+  LinkTimes         = 1;

+  DataLen           = 0;

+  Ptr               = NULL;

+  ShortPacketEnable = FALSE;

+  Mapping           = NULL;

+

+  //

+  // Parameters Checking

+  //

+  

+  if ((DataLength == NULL) ||

+      (Data == NULL)       ||

+      (TransferResult == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // if has errors that cause host controller halt,

+  // then return EFI_DEVICE_ERROR directly.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    *TransferResult = EFI_USB_ERR_SYSTEM;

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (*DataLength == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((*DataToggle != 1) && (*DataToggle != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (MaximumPacketLength != 8  &&

+      MaximumPacketLength != 16 &&

+      MaximumPacketLength != 32 &&

+      MaximumPacketLength != 64) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // Enable the maximum packet size (64bytes)

+  // that can be used for full speed bandwidth reclamation

+  // at the end of a frame.

+  //

+  EnableMaxPacketSize (HcDev);

+

+  Status = ClearStatusReg (HcDev->PciIo, StatusReg);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+ 

+  //

+  // construct QH and TD data structures,

+  // and link them together

+  //

+  if (EndPointAddress & 0x80) {

+    TransferDirection = EfiUsbDataIn;

+  } else {

+    TransferDirection = EfiUsbDataOut;

+  }

+

+  switch (TransferDirection) {

+

+  case EfiUsbDataIn:

+    ShortPacketEnable = TRUE;

+    PktID             = INPUT_PACKET_ID;

+    PtrDataSource     = Data;

+    DataLen           = *DataLength;

+

+    //

+    // BusMasterWrite means cpu read

+    //

+    Status = HcDev->PciIo->Map (

+                            HcDev->PciIo,

+                            EfiPciIoOperationBusMasterWrite,

+                            PtrDataSource,

+                            &DataLen,

+                            &TempPtr,

+                            &Mapping

+                            );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Ptr = (UINT8 *) ((UINTN) TempPtr);

+    break;

+

+  case EfiUsbDataOut:

+    PktID         = OUTPUT_PACKET_ID;

+    PtrDataSource = Data;

+    DataLen       = *DataLength;

+

+    //

+    // BusMasterRead means cpu write

+    //

+    Status = HcDev->PciIo->Map (

+                            HcDev->PciIo,

+                            EfiPciIoOperationBusMasterRead,

+                            PtrDataSource,

+                            &DataLen,

+                            &TempPtr,

+                            &Mapping

+                            );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Ptr = (UINT8 *) ((UINTN) TempPtr);

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  //  create QH structure and init

+  //

+  Status = CreateQH (HcDev, &PtrQH);

+  if (EFI_ERROR (Status)) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+    return Status;

+  }

+  

+  //

+  // i is used to calculate the total number of TDs.

+  //

+  Index     = 0;

+

+  IsFirstTD = TRUE;

+  while (DataLen > 0) {

+    

+    //

+    // create TD structures and link together

+    //

+    

+    PktSize = (UINT8) DataLen;

+    if (DataLen > MaximumPacketLength) {

+      PktSize = MaximumPacketLength;

+    }

+

+    Status = GenDataTD (

+              HcDev,

+              DeviceAddress,

+              EndPointAddress,

+              Ptr,

+              PktSize,

+              PktID,

+              *DataToggle,

+              FALSE,

+              &PtrTD

+              );

+

+    if (EFI_ERROR (Status)) {

+      HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+      UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+      DeleteQueuedTDs (HcDev, PtrFirstTD);

+      return Status;

+    }

+    

+    //

+    // Enable short packet detection.

+    // (default action is disabling short packet detection)

+    //

+    if (ShortPacketEnable) {

+      EnableorDisableTDShortPacket (PtrTD, TRUE);

+    }

+

+    if (IsFirstTD) {

+      PtrFirstTD            = PtrTD;

+      PtrFirstTD->ptrNextTD = NULL;

+      IsFirstTD             = FALSE;

+    } else {

+      //

+      // Link two TDs in vertical depth

+      //

+      LinkTDToTD (PtrPreTD, PtrTD);

+    }

+

+    Index++;

+

+    PtrPreTD = PtrTD;

+

+    *DataToggle ^= 1;

+    Ptr += PktSize;

+    DataLen -= PktSize;

+  }

+  

+  //

+  // link TD structures to QH structure

+  //

+  LinkTDToQH (PtrQH, PtrFirstTD);

+

+  //

+  // calculate how many entries are linked to the specified bulk transfer QH-TDs

+  // the below values are referred to the USB spec revision1.1.

+  //

+  switch (MaximumPacketLength) {

+  case 8:

+    LinkTimes = Index / 71 + 1;

+    break;

+

+  case 16:

+    LinkTimes = Index / 51 + 1;

+    break;

+

+  case 32:

+    LinkTimes = Index / 33 + 1;

+    break;

+

+  case 64:

+    LinkTimes = Index / 19 + 1;

+    break;

+  }

+

+  LinkTimes += 500;

+

+  //

+  // put QH-TDs into  Frame list

+  //

+  LoadFrameListIndex  = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+  SavedFrameListIndex = LoadFrameListIndex;

+

+  for (Index = 0; Index <= LinkTimes; Index++) {

+    

+    //

+    // put the QH-TD directly or indirectly into the proper place

+    // in the Frame List

+    //

+    LinkQHToFrameList (HcDev->FrameListEntry, LoadFrameListIndex, PtrQH);

+

+    LoadFrameListIndex += 1;

+    LoadFrameListIndex &= 0x3FF;

+  }

+

+  LoadFrameListIndex = SavedFrameListIndex;

+

+  //

+  // Execute QH-TD and get result

+  //

+  //

+  // detail status is put into the Result field in the pIRP

+  // the Data Toggle value is also re-updated to the value

+  // of the last successful TD

+  //

+  Status = ExecBulkorSyncInterruptTransfer (

+            HcDev,

+            PtrFirstTD,

+            LoadFrameListIndex,

+            DataLength,

+            DataToggle,

+            TimeOut,

+            TransferResult

+            );

+

+  //

+  // Delete Bulk transfer QH-TD structure

+  // and maitain the pointers in the Frame List

+  // and other pointers in related QH structure

+  //

+  // TRUE means must search other framelistindex

+  //

+  for (Index = 0; Index <= LinkTimes; Index++) {

+    DelLinkSingleQH (

+      HcDev,

+      PtrQH,

+      LoadFrameListIndex,

+      FALSE,

+      FALSE

+      );

+    LoadFrameListIndex += 1;

+    LoadFrameListIndex &= 0x3FF;

+  }

+

+  UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+

+  DeleteQueuedTDs (HcDev, PtrFirstTD);

+

+  if (Mapping != NULL) {

+    HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+  }

+  

+  //

+  // if has errors that cause host controller halt,

+  // then return EFI_DEVICE_ERROR directly.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    *TransferResult |= EFI_USB_ERR_SYSTEM;

+    return EFI_DEVICE_ERROR;

+  }

+

+  ClearStatusReg (HcDev->PciIo, StatusReg);

+

+  HcDev->PciIo->Flush (HcDev->PciIo);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIAsyncInterruptTransfer (

+  IN     EFI_USB_HC_PROTOCOL                * This,

+  IN     UINT8                              DeviceAddress,

+  IN     UINT8                              EndPointAddress,

+  IN     BOOLEAN                            IsSlowDevice,

+  IN     UINT8                              MaxiumPacketLength,

+  IN     BOOLEAN                            IsNewTransfer,

+  IN OUT UINT8                              *DataToggle,

+  IN     UINTN                              PollingInterval, OPTIONAL

+  IN     UINTN                              DataLength, OPTIONAL

+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    CallBackFunction, OPTIONAL

+  IN     VOID                               *Context OPTIONAL

+  )

+/*++

+  

+  Routine Description:

+    Submits an asynchronous interrupt transfer to an 

+    interrupt endpoint of a USB device.

+  

+  Arguments:

+    

+    This            A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    DeviceAddress   Represents the address of the target device on the USB,

+                    which is assigned during USB enumeration.

+                    

+    EndPointAddress The combination of an endpoint number and an endpoint 

+                    direction of the target USB device. Each endpoint address 

+                    supports data transfer in one direction except the 

+                    control endpoint (whose default endpoint address is 0). 

+                    It is the caller's responsibility to make sure that 

+                    the EndPointAddress represents an interrupt endpoint.

+                    

+    IsSlowDevice    Indicates whether the target device is slow device 

+                    or full-speed device.

+                    

+    MaxiumPacketLength  Indicates the maximum packet size the target endpoint

+                        is capable of sending or receiving.

+                        

+    IsNewTransfer   If TRUE, an asynchronous interrupt pipe is built between

+                    the host and the target interrupt endpoint. 

+                    If FALSE, the specified asynchronous interrupt pipe 

+                    is canceled.

+                    

+    DataToggle      A pointer to the data toggle value.  On input, it is valid 

+                    when IsNewTransfer is TRUE, and it indicates the initial 

+                    data toggle value the asynchronous interrupt transfer 

+                    should adopt.  

+                    On output, it is valid when IsNewTransfer is FALSE, 

+                    and it is updated to indicate the data toggle value of 

+                    the subsequent asynchronous interrupt transfer.

+                    

+    PollingInterval Indicates the interval, in milliseconds, that the 

+                    asynchronous interrupt transfer is polled.  

+                    This parameter is required when IsNewTransfer is TRUE.

+                    

+    DataLength      Indicates the length of data to be received at the 

+                    rate specified by PollingInterval from the target 

+                    asynchronous interrupt endpoint.  This parameter 

+                    is only required when IsNewTransfer is TRUE.

+                    

+    CallBackFunction  The Callback function.This function is called at the 

+                      rate specified by PollingInterval.This parameter is 

+                      only required when IsNewTransfer is TRUE.

+                      

+    Context         The context that is passed to the CallBackFunction.

+                    This is an optional parameter and may be NULL.

+  

+  Returns:

+    EFI_SUCCESS 

+        The asynchronous interrupt transfer request has been successfully 

+        submitted or canceled.

+    EFI_INVALID_PARAMETER 

+        Some parameters are invalid.

+    EFI_OUT_OF_RESOURCES  

+        The request could not be completed due to a lack of resources.  

+    EFI_DEVICE_ERROR

+        Can't read register

+--*/

+{

+  USB_HC_DEV            *HcDev;

+  UINT32                StatusReg;

+  UINT32                FrameNumReg;

+  UINTN                 DataLen;

+  QH_STRUCT             *ptrFirstQH;

+  QH_STRUCT             *PtrQH;

+  QH_STRUCT             *ptrPreQH;

+  TD_STRUCT             *PtrFirstTD;

+  TD_STRUCT             *PtrTD;

+  TD_STRUCT             *PtrPreTD;

+  UINT16                LoadFrameListIndex;

+  UINT16                Index;

+  UINT8                 PktID;

+  UINT8                 *Ptr;

+  UINT8                 *MappedPtr;

+  BOOLEAN               IsFirstTD;

+  BOOLEAN               IsFirstQH;

+  EFI_STATUS            Status;

+  BOOLEAN               ShortPacketEnable;

+  UINT8                 CurrentDataToggle;

+  EFI_PHYSICAL_ADDRESS  TempPtr;

+  VOID                  *Mapping;

+  UINT8                 PktSize;

+  QH_STRUCT             *TempQH;

+  EFI_TPL               OldTpl;

+

+  HcDev             = USB_HC_DEV_FROM_THIS (This);

+  StatusReg         = (UINT32) (USBSTS);

+  FrameNumReg       = (UINT32) (USBFRNUM);

+  Mapping           = NULL;

+  ShortPacketEnable = FALSE;

+

+  PktID             = INPUT_PACKET_ID;

+  PtrTD             = NULL;

+  PtrFirstTD        = NULL;

+  PtrPreTD          = NULL;

+  Ptr               = NULL;

+  PtrQH             = NULL;

+  ptrPreQH          = NULL;

+  ptrFirstQH        = NULL;

+

+  if ((EndPointAddress & 0x80) == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // delete Async interrupt transfer request

+  //

+  if (!IsNewTransfer) {

+

+    OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+    Status = DeleteAsyncINTQHTDs (

+              HcDev,

+              DeviceAddress,

+              EndPointAddress,

+              DataToggle

+              );

+

+    gBS->RestoreTPL (OldTpl);

+

+    return Status;

+  }

+  //

+  // if has errors that cause host controller halt,

+  // then return EFI_DEVICE_ERROR directly.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    return EFI_DEVICE_ERROR;

+  }

+

+  ClearStatusReg (HcDev->PciIo, StatusReg);

+

+  //

+  // submit Async interrupt transfer request

+  //

+  if (PollingInterval < 1 || PollingInterval > 255) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (DataLength == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((*DataToggle != 1) && (*DataToggle != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ShortPacketEnable = TRUE;

+  PktID             = INPUT_PACKET_ID;

+  DataLen           = DataLength;

+  Ptr               = AllocatePool (DataLen);

+  if (Ptr == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // BusMasterWrite means cpu read

+  //

+  Status = HcDev->PciIo->Map (

+                          HcDev->PciIo,

+                          EfiPciIoOperationBusMasterWrite,

+                          Ptr,

+                          &DataLen,

+                          &TempPtr,

+                          &Mapping

+                          );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Ptr);

+    return Status;

+  }

+

+  MappedPtr         = (UINT8 *) ((UINTN) TempPtr);

+

+  CurrentDataToggle = *DataToggle;

+

+  IsFirstTD         = TRUE;

+

+  while (DataLen > 0) {

+    //

+    // create TD structures and link together

+    //

+        

+    PktSize = (UINT8) DataLen;

+    if (DataLen > MaxiumPacketLength) {

+      PktSize = MaxiumPacketLength;

+    }

+

+    Status = GenDataTD (

+              HcDev,

+              DeviceAddress,

+              EndPointAddress,

+              MappedPtr,

+              PktSize,

+              PktID,

+              CurrentDataToggle,

+              IsSlowDevice,

+              &PtrTD

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (Ptr);

+      HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+      DeleteQueuedTDs (HcDev, PtrFirstTD);

+      return Status;

+    }

+    //

+    // Enable short packet detection.

+    //

+    if (ShortPacketEnable) {

+      EnableorDisableTDShortPacket (PtrTD, TRUE);

+    }

+

+    if (IsFirstTD) {

+      PtrFirstTD            = PtrTD;

+      PtrFirstTD->ptrNextTD = NULL;

+      IsFirstTD             = FALSE;

+    } else {

+      //

+      // Link two TDs in vertical depth

+      //

+      LinkTDToTD (PtrPreTD, PtrTD);

+    }

+

+    PtrPreTD = PtrTD;

+

+    CurrentDataToggle ^= 1;

+    MappedPtr += PktSize;

+    DataLen -= PktSize;

+  }

+  

+  //

+  // roll one value back

+  //

+  CurrentDataToggle ^= 1;

+

+  //

+  // create a list of QH structures and init,

+  // link TDs to all the QHs, and link all the QHs together using internal

+  // defined pointer of the QH_STRUCT.

+  //

+  IsFirstQH = TRUE;

+  ptrPreQH  = NULL;

+  for (Index = 0; Index < 1024;) {

+

+    Status = CreateQH (HcDev, &PtrQH);

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (Ptr);

+      HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+      DeleteQueuedTDs (HcDev, PtrFirstTD);

+      PtrQH = ptrFirstQH;

+      while (PtrQH) {

+        TempQH  = PtrQH;

+        PtrQH   = TempQH->ptrNextIntQH;

+        UhciFreePool (HcDev, (UINT8 *) TempQH, sizeof (QH_STRUCT));

+      }

+

+      return Status;

+    }

+    

+    //

+    // link TD structures to QH structure

+    //

+    LinkTDToQH (PtrQH, PtrFirstTD);

+

+    if (IsFirstQH) {

+      ptrFirstQH                = PtrQH;

+      ptrFirstQH->ptrNextIntQH  = NULL;

+      IsFirstQH                 = FALSE;

+    } else {

+      //

+      // link neighbor QH structures together

+      //

+      ptrPreQH->ptrNextIntQH = PtrQH;

+    }

+

+    ptrPreQH  = PtrQH;

+

+    Index     = (UINT16) (PollingInterval + Index);

+  }

+  //

+  // last QH in QH list should set its next QH pointer to NULL.

+  //

+  PtrQH->ptrNextIntQH = NULL;

+

+  //

+  // Save QH-TD structures in Interrupt transfer list,

+  // for monitor interrupt transfer execution routine use.

+  //

+  InsertQHTDToINTList (

+    HcDev,

+    ptrFirstQH,

+    PtrFirstTD,

+    DeviceAddress,

+    EndPointAddress,

+    CurrentDataToggle,

+    DataLength,

+    PollingInterval,

+    Mapping,

+    Ptr,

+    CallBackFunction,

+    Context

+    );

+

+  //

+  // put QHs-TDs into  Frame list

+  //

+  LoadFrameListIndex  = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+

+  PtrQH               = ptrFirstQH;

+

+  for (Index = LoadFrameListIndex; Index < (1024 + LoadFrameListIndex);) {

+      

+    //

+    // put the QH-TD directly or indirectly into the proper place

+    // in the Frame List

+    //

+    LinkQHToFrameList (HcDev->FrameListEntry, (UINT16) (Index & 0x3FF), PtrQH);

+

+    Index = (UINT16) (PollingInterval + Index);

+

+    PtrQH = PtrQH->ptrNextIntQH;

+  }

+

+  HcDev->PciIo->Flush (HcDev->PciIo);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UHCISyncInterruptTransfer (

+  IN       EFI_USB_HC_PROTOCOL     *This,

+  IN       UINT8                   DeviceAddress,

+  IN       UINT8                   EndPointAddress,

+  IN       BOOLEAN                 IsSlowDevice,

+  IN       UINT8                   MaximumPacketLength,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN OUT   UINT8                   *DataToggle,

+  IN       UINTN                   TimeOut,

+  OUT      UINT32                  *TransferResult

+  )

+/*++

+  

+  Routine Description:

+    Submits synchronous interrupt transfer to an interrupt endpoint 

+    of a USB device.

+  

+  Arguments:

+    

+    This            A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    DeviceAddress   Represents the address of the target device on the USB, 

+                    which is assigned during USB enumeration.

+                    

+    EndPointAddress   The combination of an endpoint number and an endpoint 

+                      direction of the target USB device. Each endpoint 

+                      address supports data transfer in one direction 

+                      except the control endpoint (whose default 

+                      endpoint address is 0). It is the caller's responsibility

+                      to make sure that the EndPointAddress represents 

+                      an interrupt endpoint. 

+                      

+    IsSlowDevice    Indicates whether the target device is slow device 

+                    or full-speed device.

+                    

+    MaximumPacketLength Indicates the maximum packet size the target endpoint 

+                        is capable of sending or receiving.

+                        

+    Data            A pointer to the buffer of data that will be transmitted 

+                    to USB device or received from USB device.

+                    

+    DataLength      On input, the size, in bytes, of the data buffer specified 

+                    by Data. On output, the number of bytes transferred.

+                    

+    DataToggle      A pointer to the data toggle value. On input, it indicates

+                    the initial data toggle value the synchronous interrupt 

+                    transfer should adopt; 

+                    on output, it is updated to indicate the data toggle value 

+                    of the subsequent synchronous interrupt transfer. 

+                    

+    TimeOut         Indicates the maximum time, in microseconds, which the 

+                    transfer is allowed to complete.

+                    

+    TransferResult  A pointer to the detailed result information from 

+                    the synchronous interrupt transfer.  

+

+  Returns:

+    EFI_SUCCESS 

+        The synchronous interrupt transfer was completed successfully.

+    EFI_OUT_OF_RESOURCES  

+        The synchronous interrupt transfer could not be submitted due 

+        to lack of resource.

+    EFI_INVALID_PARAMETER 

+        Some parameters are invalid.

+    EFI_TIMEOUT 

+        The synchronous interrupt transfer failed due to timeout.

+    EFI_DEVICE_ERROR  

+        The synchronous interrupt transfer failed due to host controller 

+        or device error. Caller should check TranferResult for detailed 

+        error information.  

+--*/

+{

+  USB_HC_DEV            *HcDev;

+  UINT32                StatusReg;

+  UINT32                FrameNumReg;

+  UINTN                 DataLen;

+  QH_STRUCT             *PtrQH;

+  TD_STRUCT             *PtrFirstTD;

+  TD_STRUCT             *PtrTD;

+  TD_STRUCT             *PtrPreTD;

+  UINT16                LoadFrameListIndex;

+  UINT16                SavedFrameListIndex;

+  UINT32                Index;

+  UINT32                LinkTimes;

+  UINT8                 PktID;

+  UINT8                 *PtrDataSource;

+  UINT8                 *Ptr;

+  BOOLEAN               IsFirstTD;

+  EFI_STATUS            Status;

+  BOOLEAN               ShortPacketEnable;

+  EFI_PHYSICAL_ADDRESS  TempPtr;

+  VOID                  *Mapping;

+  UINT8                 PktSize;

+

+  HcDev             = USB_HC_DEV_FROM_THIS (This);

+  StatusReg         = (UINT32) (USBSTS);

+  FrameNumReg       = (UINT32) (USBFRNUM);

+  ShortPacketEnable = FALSE;

+  Mapping           = NULL;

+  PktID             = INPUT_PACKET_ID;

+  PtrTD             = NULL;

+  PtrFirstTD        = NULL;

+  PtrPreTD          = NULL;

+  DataLen           = 0;

+  Ptr               = NULL;

+  Index             = 0;

+  LinkTimes         = 0;

+

+  //

+  // Parameters Checking

+  //

+  

+  if ((DataLength == NULL) ||

+      (Data == NULL)       ||

+      (TransferResult == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // if has errors that cause host controller halt,

+  // then return EFI_DEVICE_ERROR directly.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    *TransferResult = EFI_USB_ERR_SYSTEM;

+    return EFI_DEVICE_ERROR;

+  }

+

+  if ((EndPointAddress & 0x80) == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (*DataLength == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((*DataToggle != 1) && (*DataToggle != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (MaximumPacketLength > 64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (IsSlowDevice && (MaximumPacketLength > 8)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ClearStatusReg (HcDev->PciIo, StatusReg);

+

+  //

+  // submit Sync interrupt transfer request

+  //

+  ShortPacketEnable = TRUE;

+  PktID             = INPUT_PACKET_ID;

+  DataLen           = *DataLength;

+  PtrDataSource     = Data;

+

+  //

+  // create QH structure and init

+  //

+  Status = CreateQH (HcDev, &PtrQH);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // BusMasterWrite means cpu read

+  //

+  Status = HcDev->PciIo->Map (

+                           HcDev->PciIo,

+                           EfiPciIoOperationBusMasterWrite,

+                           PtrDataSource,

+                           &DataLen,

+                           &TempPtr,

+                           &Mapping

+                           );

+  if (EFI_ERROR (Status)) {

+    UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+    return Status;

+  }

+

+  Ptr       = (UINT8 *) ((UINTN) TempPtr);

+

+  IsFirstTD = TRUE;

+  while (DataLen > 0) {

+    //

+    // create TD structures and link together

+    //

+    PktSize = (UINT8) DataLen;

+    if (DataLen > MaximumPacketLength) {

+      PktSize = MaximumPacketLength;

+    }

+

+    Status = GenDataTD (

+               HcDev,

+               DeviceAddress,

+               EndPointAddress,

+               Ptr,

+               PktSize,

+               PktID,

+               *DataToggle,

+               IsSlowDevice,

+               &PtrTD

+               );

+    if (EFI_ERROR (Status)) {

+      UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+      HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+      DeleteQueuedTDs (HcDev, PtrFirstTD);

+      return Status;

+    }

+    //

+    // Enable short packet detection.

+    //

+    if (ShortPacketEnable) {

+      EnableorDisableTDShortPacket (PtrTD, TRUE);

+    }

+

+    if (IsFirstTD) {

+      PtrFirstTD            = PtrTD;

+      PtrFirstTD->ptrNextTD = NULL;

+      IsFirstTD             = FALSE;

+    } else {

+      //

+      // Link two TDs in vertical depth

+      //

+      LinkTDToTD (PtrPreTD, PtrTD);

+    }

+

+    Index++;

+

+    PtrPreTD = PtrTD;

+

+    *DataToggle ^= 1;

+    Ptr += PktSize;

+    DataLen -= PktSize;

+  }

+  

+  //

+  // link TD structures to QH structure

+  //

+  LinkTDToQH (PtrQH, PtrFirstTD);

+

+  switch (MaximumPacketLength) {

+  case 8:

+    LinkTimes = Index / 71 + 1;

+    break;

+

+  case 16:

+    LinkTimes = Index / 51 + 1;

+    break;

+

+  case 32:

+    LinkTimes = Index / 33 + 1;

+    break;

+

+  case 64:

+    LinkTimes = Index / 19 + 1;

+    break;

+  }

+

+  LinkTimes += 100;

+

+  LoadFrameListIndex  = (UINT16) ((GetCurrentFrameNumber (HcDev->PciIo, FrameNumReg)) & 0x3FF);

+  SavedFrameListIndex = LoadFrameListIndex;

+

+  for (Index = 0; Index < LinkTimes; Index++) {

+        

+    //

+    // put the QH-TD directly or indirectly into the proper place

+    // in the Frame List

+    //

+    LinkQHToFrameList (HcDev->FrameListEntry, LoadFrameListIndex, PtrQH);

+

+    LoadFrameListIndex += 1;

+    LoadFrameListIndex &= 0x3FF;

+  }

+

+  LoadFrameListIndex = SavedFrameListIndex;

+  //

+  // detail status is put into the Result field in the pIRP

+  // the Data Toggle value is also re-updated to the value

+  // of the last successful TD

+  //

+  Status = ExecBulkorSyncInterruptTransfer (

+             HcDev,

+             PtrFirstTD,

+             LoadFrameListIndex,

+             DataLength,

+             DataToggle,

+             TimeOut,

+             TransferResult

+             );

+  //

+  // Delete Sync Interrupt transfer QH-TD structure

+  // and maintain the pointers in the Frame List

+  // and other pointers in related QH structure

+  //

+  // TRUE means must search other framelistindex

+  //

+  for (Index = 0; Index <= LinkTimes; Index++) {

+    DelLinkSingleQH (

+      HcDev,

+      PtrQH,

+      LoadFrameListIndex,

+      FALSE,

+      FALSE

+      );

+    LoadFrameListIndex += 1;

+    LoadFrameListIndex &= 0x3FF;

+  }

+

+  UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));

+

+  DeleteQueuedTDs (HcDev, PtrFirstTD);

+

+  HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);

+

+  //

+  // if has errors that cause host controller halt,

+  // then return EFI_DEVICE_ERROR directly.

+  //

+  if (!IsStatusOK (HcDev->PciIo, StatusReg)) {

+

+    ClearStatusReg (HcDev->PciIo, StatusReg);

+    *TransferResult |= EFI_USB_ERR_SYSTEM;

+    return EFI_DEVICE_ERROR;

+  }

+

+  ClearStatusReg (HcDev->PciIo, StatusReg);

+

+  HcDev->PciIo->Flush (HcDev->PciIo);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+UHCIIsochronousTransfer (

+  IN       EFI_USB_HC_PROTOCOL     *This,

+  IN       UINT8                   DeviceAddress,

+  IN       UINT8                   EndPointAddress,

+  IN       UINT8                   MaximumPacketLength,

+  IN OUT   VOID                    *Data,

+  IN       UINTN                   DataLength,

+  OUT      UINT32                  *TransferResult

+  )

+/*++

+  

+  Routine Description:

+    Submits isochronous transfer to a target USB device.

+  

+  Arguments:

+    

+    This                - A pointer to the EFI_USB_HC_PROTOCOL instance.

+    DeviceAddress       - Represents the address of the target device on the USB,

+                           which is assigned during USB enumeration.

+    EndPointAddress     - End point address

+    MaximumPacketLength - Indicates the maximum packet size that the 

+                           default control transfer endpoint is capable of 

+                           sending or receiving.

+    Data                - A pointer to the buffer of data that will be transmitted 

+                           to USB device or received from USB device.

+    DataLength          - Indicates the size, in bytes, of the data buffer 

+                           specified by Data.

+    TransferResult      - A pointer to the detailed result information generated 

+                           by this control transfer.               

+  Returns:

+    EFI_UNSUPPORTED 

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EFIAPI

+UHCIAsyncIsochronousTransfer (

+  IN       EFI_USB_HC_PROTOCOL                 * This,

+  IN       UINT8                               DeviceAddress,

+  IN       UINT8                               EndPointAddress,

+  IN       UINT8                               MaximumPacketLength,

+  IN OUT   VOID                                *Data,

+  IN       UINTN                               DataLength,

+  IN       EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,

+  IN       VOID                                *Context OPTIONAL

+  )

+/*++

+  

+  Routine Description:

+    Submits Async isochronous transfer to a target USB device.

+  

+  Arguments:

+    

+    This                - A pointer to the EFI_USB_HC_PROTOCOL instance.

+    

+    DeviceAddress       - Represents the address of the target device on the USB,

+                           which is assigned during USB enumeration.

+

+    EndPointAddress     - End point address

+    

+    MaximumPacketLength - Indicates the maximum packet size that the 

+                           default control transfer endpoint is capable of 

+                           sending or receiving.

+       

+    Data                - A pointer to the buffer of data that will be transmitted 

+                           to USB device or received from USB device.

+    

+    IsochronousCallBack - When the transfer complete, the call back function will be called

+    

+    Context             - Pass to the call back function as parameter

+                    

+  Returns:

+    EFI_UNSUPPORTED 

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+VOID

+EFIAPI

+MonitorInterruptTrans (

+  IN EFI_EVENT     Event,

+  IN VOID          *Context

+  )

+/*++

+  Routine Description:

+    Interrupt transfer periodic check handler

+  Arguments:

+    Event  - Interrupt event

+    Contex - Pointer to USB_HC_DEV

+  Returns:

+    None

+--*/            

+{

+

+  USB_HC_DEV      *HcDev;

+  INTERRUPT_LIST  *PtrList;

+  LIST_ENTRY      *Link;

+  UINT32          Result;

+  VOID            *DataBuffer;

+  UINTN           DataLen;

+  UINTN           ActualLen;

+  UINTN           ErrTDPos;

+  UINT32          StatusAddr;

+  LIST_ENTRY      *NextLink;

+

+  HcDev       = (USB_HC_DEV *) Context;

+  StatusAddr  = (UINT32) (USBSTS);

+

+  //

+  // interrupt transfer list is empty, means that no interrupt transfer

+  // is submitted by far.

+  //

+  if (IsListEmpty (&(HcDev->InterruptListHead))) {

+    return ;

+  }

+

+  NextLink = HcDev->InterruptListHead.ForwardLink;

+  do {

+

+    Link      = NextLink;

+    NextLink  = Link->ForwardLink;

+

+    PtrList   = INTERRUPT_LIST_FROM_LINK (Link);

+

+    //

+    // get TD execution results.

+    // ErrTDPos is zero-based value indicating the first error TD's position

+    // in the TDs' list.

+    // This value is only valid when Result not equal NOERROR.

+    //

+    ExecuteAsyncINTTDs (

+      HcDev,

+      PtrList,

+      &Result,

+      &ErrTDPos,

+      &ActualLen

+      );

+

+    //

+    // interrupt transfer has not been executed yet.

+    //

+    if (((Result & EFI_USB_ERR_NAK) == EFI_USB_ERR_NAK) ||

+        ((Result & EFI_USB_ERR_NOTEXECUTE) == EFI_USB_ERR_NOTEXECUTE)) {

+      continue;

+    }

+    //

+    // get actual data length transferred data and its data length.

+    //

+    DataLen     = ActualLen;

+    DataBuffer  = AllocatePool (DataLen);

+    if (DataBuffer == NULL) {

+      return ;

+    }

+

+    CopyMem (

+      DataBuffer,

+      PtrList->PtrFirstTD->pTDBuffer,

+      DataLen

+      );

+

+    //

+    // only if interrupt endpoint responds

+    // and the interrupt transfer stops because of completion

+    // or error, then we will call callback function.

+    //

+    if (Result == EFI_USB_NOERROR) {

+      //

+      // add for real platform debug

+      //

+      if (PtrList->InterruptCallBack != NULL) {

+        (PtrList->InterruptCallBack) (

+                    DataBuffer,

+                    DataLen,

+                    PtrList->InterruptContext,

+                    Result

+                    );

+      }

+

+      if (DataBuffer) {

+        gBS->FreePool (DataBuffer);

+      }

+      

+      //

+      // update should done after data buffer got.

+      //

+      UpdateAsyncINTQHTDs (PtrList, Result, (UINT32) ErrTDPos);

+

+    } else {

+

+      DEBUG ((EFI_D_ERROR, "interrupt transfer error code is %x\n", Result));

+

+      if (DataBuffer) {

+        gBS->FreePool (DataBuffer);

+      }

+      //

+      // leave error recovery to its related device driver.

+      // A common case of the error recovery is to re-submit the interrupt

+      // transfer.

+      // When an interrupt transfer is re-submitted, its position in the linked

+      // list is changed. It is inserted to the head of the linked list, while

+      // this function scans the whole list from head to tail. Thus, the

+      // re-submitted interrupt transfer's callback function will not be called

+      // again in this round.

+      //

+      if (PtrList->InterruptCallBack != NULL) {

+        (PtrList->InterruptCallBack) (

+                    NULL,

+                    0,

+                    PtrList->InterruptContext,

+                    Result

+                    );

+      }

+    }

+  } while (NextLink != &(HcDev->InterruptListHead));

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h
new file mode 100644
index 0000000..d6f841b
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h
@@ -0,0 +1,1187 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    Uhci.h

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#ifndef _UHCI_H

+#define _UHCI_H

+

+/*

+ * Universal Host Controller Interface data structures and defines

+ */

+

+#include <IndustryStandard/pci22.h>

+

+#define EFI_D_UHCI  EFI_D_INFO

+

+//

+// stall time

+//

+#define STALL_1_MILLI_SECOND      1000

+#define STALL_1_SECOND            1000 * STALL_1_MILLI_SECOND

+

+#define FORCE_GLOBAL_RESUME_TIME  20 * STALL_1_MILLI_SECOND

+

+#define ROOT_PORT_REST_TIME       50 * STALL_1_MILLI_SECOND

+

+#define PORT_RESET_RECOVERY_TIME  10 * STALL_1_MILLI_SECOND

+

+//

+// 50 ms

+//

+#define INTERRUPT_POLLING_TIME  50 * 1000 * 10

+

+//

+// UHCI IO Space Address Register Register locates at

+// offset 20 ~ 23h of PCI Configuration Space (UHCI spec, Revision 1.1),

+// so, its BAR Index is 4.

+//

+#define USB_BAR_INDEX 4

+

+//

+// One memory block uses 1 page (common buffer for QH,TD use.)

+//

+#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1

+

+

+#define bit(a)                            1 << (a)

+

+//

+// ////////////////////////////////////////////////////////////////////////

+//

+//          Universal Host Controller Registers Definitions

+//

+//////////////////////////////////////////////////////////////////////////

+extern UINT16 USBBaseAddr;

+

+/* Command register */

+#define USBCMD          0       /* Command Register Offset 00-01h */

+#define USBCMD_RS       bit (0) /* Run/Stop */

+#define USBCMD_HCRESET  bit (1) /* Host reset */

+#define USBCMD_GRESET   bit (2) /* Global reset */

+#define USBCMD_EGSM     bit (3) /* Global Suspend Mode */

+#define USBCMD_FGR      bit (4) /* Force Global Resume */

+#define USBCMD_SWDBG    bit (5) /* SW Debug mode */

+#define USBCMD_CF       bit (6) /* Config Flag (sw only) */

+#define USBCMD_MAXP     bit (7) /* Max Packet (0 = 32, 1 = 64) */

+

+/* Status register */

+#define USBSTS        2       /* Status Register Offset 02-03h */

+#define USBSTS_USBINT bit (0) /* Interrupt due to IOC */

+#define USBSTS_ERROR  bit (1) /* Interrupt due to error */

+#define USBSTS_RD     bit (2) /* Resume Detect */

+#define USBSTS_HSE    bit (3) /* Host System Error*/

+#define USBSTS_HCPE   bit (4) /* Host Controller Process Error*/

+#define USBSTS_HCH    bit (5) /* HC Halted */

+

+/* Interrupt enable register */

+#define USBINTR         4       /* Interrupt Enable Register 04-05h */

+#define USBINTR_TIMEOUT bit (0) /* Timeout/CRC error enable */

+#define USBINTR_RESUME  bit (1) /* Resume interrupt enable */

+#define USBINTR_IOC     bit (2) /* Interrupt On Complete enable */

+#define USBINTR_SP      bit (3) /* Short packet interrupt enable */

+

+/* Frame Number Register Offset 06-08h */

+#define USBFRNUM  6

+

+/* Frame List Base Address Register Offset 08-0Bh */

+#define USBFLBASEADD  8

+

+/* Start of Frame Modify Register Offset 0Ch */

+#define USBSOF  0x0c

+

+/* USB port status and control registers */

+#define USBPORTSC1      0x10      /*Port 1 offset 10-11h */

+#define USBPORTSC2      0x12      /*Port 2 offset 12-13h */

+

+#define USBPORTSC_CCS   bit (0)   /* Current Connect Status*/

+#define USBPORTSC_CSC   bit (1)   /* Connect Status Change */

+#define USBPORTSC_PED   bit (2)   /* Port Enable / Disable */

+#define USBPORTSC_PEDC  bit (3)   /* Port Enable / Disable Change */

+#define USBPORTSC_LSL   bit (4)   /* Line Status Low bit*/

+#define USBPORTSC_LSH   bit (5)   /* Line Status High bit*/

+#define USBPORTSC_RD    bit (6)   /* Resume Detect */

+#define USBPORTSC_LSDA  bit (8)   /* Low Speed Device Attached */

+#define USBPORTSC_PR    bit (9)   /* Port Reset */

+#define USBPORTSC_SUSP  bit (12)  /* Suspend */

+

+/* PCI Configuration Registers for USB */

+

+//

+// Class Code Register offset

+//

+#define CLASSC  0x09

+//

+// USB IO Space Base Address Register offset

+//

+#define USBBASE 0x20

+

+//

+// USB legacy Support

+//

+#define USB_EMULATION 0xc0

+

+//

+// USB Base Class Code,Sub-Class Code and Programming Interface.

+//

+#define PCI_CLASSC_PI_UHCI  0x00

+

+#define SETUP_PACKET_ID     0x2D

+#define INPUT_PACKET_ID     0x69

+#define OUTPUT_PACKET_ID    0xE1

+#define ERROR_PACKET_ID     0x55

+

+//

+// ////////////////////////////////////////////////////////////////////////

+//

+//          USB Transfer Mechanism Data Structures

+//

+//////////////////////////////////////////////////////////////////////////

+#pragma pack(1)

+//

+// USB Class Code structure

+//

+typedef struct {

+  UINT8 PI;

+  UINT8 SubClassCode;

+  UINT8 BaseCode;

+} USB_CLASSC;

+

+typedef struct {

+  UINT32  QHHorizontalTerminate : 1;

+  UINT32  QHHorizontalQSelect : 1;

+  UINT32  QHHorizontalRsvd : 2;

+  UINT32  QHHorizontalPtr : 28;

+  UINT32  QHVerticalTerminate : 1;

+  UINT32  QHVerticalQSelect : 1;

+  UINT32  QHVerticalRsvd : 2;

+  UINT32  QHVerticalPtr : 28;

+} QUEUE_HEAD;

+

+typedef struct {

+  UINT32  TDLinkPtrTerminate : 1;

+  UINT32  TDLinkPtrQSelect : 1;

+  UINT32  TDLinkPtrDepthSelect : 1;

+  UINT32  TDLinkPtrRsvd : 1;

+  UINT32  TDLinkPtr : 28;

+  UINT32  TDStatusActualLength : 11;

+  UINT32  TDStatusRsvd : 5;

+  UINT32  TDStatus : 8;

+  UINT32  TDStatusIOC : 1;

+  UINT32  TDStatusIOS : 1;

+  UINT32  TDStatusLS : 1;

+  UINT32  TDStatusErr : 2;

+  UINT32  TDStatusSPD : 1;

+  UINT32  TDStatusRsvd2 : 2;

+  UINT32  TDTokenPID : 8;

+  UINT32  TDTokenDevAddr : 7;

+  UINT32  TDTokenEndPt : 4;

+  UINT32  TDTokenDataToggle : 1;

+  UINT32  TDTokenRsvd : 1;

+  UINT32  TDTokenMaxLen : 11;

+  UINT32  TDBufferPtr;

+} TD;

+

+#pragma pack()

+

+typedef struct {

+  QUEUE_HEAD  QH;

+  VOID        *ptrNext;

+  VOID        *ptrDown;

+  VOID        *ptrNextIntQH;  // for interrupt transfer's special use

+  VOID        *LoopPtr;

+} QH_STRUCT;

+

+typedef struct {

+  TD      TDData;

+  UINT8   *pTDBuffer;

+  VOID    *ptrNextTD;

+  VOID    *ptrNextQH;

+  UINT16  TDBufferLength;

+  UINT16  reserved;

+} TD_STRUCT;

+

+//

+// ////////////////////////////////////////////////////////////////////////

+//

+//          Universal Host Controller Device Data Structure

+//

+//////////////////////////////////////////////////////////////////////////

+#define USB_HC_DEV_FROM_THIS(a)   CR (a, USB_HC_DEV, UsbHc, USB_HC_DEV_SIGNATURE)

+

+#define USB_HC_DEV_SIGNATURE      EFI_SIGNATURE_32 ('u', 'h', 'c', 'i')

+#define INTERRUPT_LIST_SIGNATURE  EFI_SIGNATURE_32 ('i', 'n', 't', 's')

+typedef struct {

+  UINTN                           Signature;

+

+  LIST_ENTRY                      Link;

+  UINT8                           DevAddr;

+  UINT8                           EndPoint;

+  UINT8                           DataToggle;

+  UINT8                           Reserved[5];

+  TD_STRUCT                       *PtrFirstTD;

+  QH_STRUCT                       *PtrQH;

+  UINTN                           DataLen;

+  UINTN                           PollInterval;

+  VOID                            *Mapping;

+  UINT8                           *DataBuffer;  // allocated host memory, not mapped memory

+  EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack;

+  VOID                            *InterruptContext;

+} INTERRUPT_LIST;

+

+#define INTERRUPT_LIST_FROM_LINK(a) CR (a, INTERRUPT_LIST, Link, INTERRUPT_LIST_SIGNATURE)

+

+typedef struct {

+  UINT32  FrameListPtrTerminate : 1;

+  UINT32  FrameListPtrQSelect : 1;

+  UINT32  FrameListRsvd : 2;

+  UINT32  FrameListPtr : 28;

+

+} FRAMELIST_ENTRY;

+

+typedef struct _MEMORY_MANAGE_HEADER {

+  UINT8                         *BitArrayPtr;

+  UINTN                         BitArraySizeInBytes;

+  UINT8                         *MemoryBlockPtr;

+  UINTN                         MemoryBlockSizeInBytes;

+  VOID                          *Mapping;

+  struct _MEMORY_MANAGE_HEADER  *Next;

+} MEMORY_MANAGE_HEADER;

+

+typedef struct {

+  UINTN                     Signature;

+  EFI_USB_HC_PROTOCOL       UsbHc;

+  EFI_PCI_IO_PROTOCOL       *PciIo;

+

+  //

+  // local data

+  //

+  LIST_ENTRY                InterruptListHead;

+  FRAMELIST_ENTRY           *FrameListEntry;

+  VOID                      *FrameListMapping;

+  MEMORY_MANAGE_HEADER      *MemoryHeader;

+  EFI_EVENT                 InterruptTransTimer;

+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;

+

+} USB_HC_DEV;

+

+extern EFI_DRIVER_BINDING_PROTOCOL  gUhciDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gUhciComponentName;

+

+EFI_STATUS

+WriteUHCCommandReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  CmdAddrOffset,

+  IN UINT16                  UsbCmd

+  );

+

+EFI_STATUS

+ReadUHCCommandReg (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  CmdAddrOffset,

+  IN OUT   UINT16                  *Data

+  );

+

+EFI_STATUS

+WriteUHCStatusReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusAddrOffset,

+  IN UINT16                  UsbSts

+  );

+

+EFI_STATUS

+ReadUHCStatusReg (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  StatusAddrOffset,

+  IN OUT   UINT16                  *Data

+  );

+

+EFI_STATUS

+ClearStatusReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusAddrOffset

+  );

+

+EFI_STATUS

+ReadUHCFrameNumberReg (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  FrameNumAddrOffset,

+  IN OUT   UINT16                  *Data

+  );

+

+EFI_STATUS

+WriteUHCFrameListBaseReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FlBaseAddrOffset,

+  IN UINT32                  UsbFrameListBaseAddr

+  );

+

+EFI_STATUS

+ReadRootPortReg (

+  IN       EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN       UINT32                  PortAddrOffset,

+  IN OUT   UINT16                  *Data

+  );

+

+EFI_STATUS

+WriteRootPortReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  PortAddrOffset,

+  IN UINT16                  ControlBits

+  );

+

+EFI_STATUS

+WaitForUHCHalt (

+  IN EFI_PCI_IO_PROTOCOL      *PciIo,

+  IN UINT32                   StatusRegAddr,

+  IN UINTN                    Timeout

+  );

+

+BOOLEAN

+IsStatusOK (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusRegAddr

+  );

+

+BOOLEAN

+IsHostSysOrProcessErr (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  StatusRegAddr

+  );

+

+//

+// This routine programs the USB frame number register. We assume that the

+// HC schedule execution is stopped.

+//

+EFI_STATUS

+SetFrameNumberReg (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FRNUMAddr,

+  IN UINT16                  Index

+  );

+

+UINT16

+GetCurrentFrameNumber (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FRNUMAddr

+  );

+

+EFI_STATUS

+SetFrameListBaseAddress (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FLBASEADDRReg,

+  IN UINT32                  Addr

+  );

+

+UINT32

+GetFrameListBaseAddress (

+  IN EFI_PCI_IO_PROTOCOL     *PciIo,

+  IN UINT32                  FLBAddr

+  );

+

+EFI_STATUS

+CreateFrameList (

+  IN USB_HC_DEV     *HcDev,

+  IN UINT32         FLBASEADDRReg

+  );

+

+EFI_STATUS

+FreeFrameListEntry (

+  IN USB_HC_DEV     *UhcDev

+  );

+

+VOID

+InitFrameList (

+  IN USB_HC_DEV     *HcDev

+  );

+

+

+EFI_STATUS

+CreateQH (

+  IN  USB_HC_DEV     *HcDev,

+  OUT QH_STRUCT      **pptrQH

+  );

+

+VOID

+SetQHHorizontalLinkPtr (

+  IN QH_STRUCT     *ptrQH,

+  IN VOID          *ptrNext

+  );

+

+VOID *

+GetQHHorizontalLinkPtr (

+  IN QH_STRUCT     *ptrQH

+  );

+

+VOID

+SetQHHorizontalQHorTDSelect (

+  IN QH_STRUCT     *ptrQH,

+  IN BOOLEAN       bQH

+  );

+

+VOID

+SetQHHorizontalValidorInvalid (

+  IN QH_STRUCT     *ptrQH,

+  IN BOOLEAN       bValid

+  );

+

+VOID

+SetQHVerticalLinkPtr (

+  IN QH_STRUCT     *ptrQH,

+  IN VOID          *ptrNext

+  );

+

+VOID * 

+GetQHVerticalLinkPtr (

+  IN QH_STRUCT     *ptrQH

+  );

+

+VOID

+SetQHVerticalQHorTDSelect (

+  IN QH_STRUCT     *ptrQH,

+  IN BOOLEAN       bQH

+  );

+

+BOOLEAN

+IsQHHorizontalQHSelect (

+  IN QH_STRUCT     *ptrQH

+  );

+

+VOID

+SetQHVerticalValidorInvalid (

+  IN QH_STRUCT     *ptrQH,

+  IN BOOLEAN       bValid

+  );

+

+BOOLEAN

+GetQHVerticalValidorInvalid (

+  IN QH_STRUCT     *ptrQH

+  );

+

+EFI_STATUS

+AllocateTDStruct (

+  IN  USB_HC_DEV     *HcDev,

+  OUT TD_STRUCT      **ppTDStruct

+  );

+/*++

+

+Routine Description:

+

+  Allocate TD Struct

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  ppTDStruct  - place to store TD_STRUCT pointer

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+

+EFI_STATUS

+CreateTD (

+  IN  USB_HC_DEV     *HcDev,

+  OUT TD_STRUCT      **pptrTD

+  );

+/*++

+

+Routine Description:

+

+  Create TD

+

+Arguments:

+

+  HcDev   - USB_HC_DEV

+  pptrTD  - TD_STRUCT pointer to store

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate resources

+  EFI_SUCCESS          - Success

+

+--*/

+

+

+EFI_STATUS

+GenSetupStageTD (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DevAddr,

+  IN  UINT8          Endpoint,

+  IN  BOOLEAN        bSlow,

+  IN  UINT8          *pDevReq,

+  IN  UINT8          RequestLen,

+  OUT TD_STRUCT      **ppTD

+  );

+/*++

+

+Routine Description:

+

+  Generate Setup Stage TD

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  DevAddr     - Device address

+  Endpoint    - Endpoint number 

+  bSlow       - Full speed or low speed

+  pDevReq     - Device request

+  RequestLen  - Request length

+  ppTD        - TD_STRUCT to return

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+  EFI_SUCCESS          - Success

+

+--*/

+

+EFI_STATUS

+GenDataTD (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DevAddr,

+  IN  UINT8          Endpoint,

+  IN  UINT8          *pData,

+  IN  UINT8          Len,

+  IN  UINT8          PktID,

+  IN  UINT8          Toggle,

+  IN  BOOLEAN        bSlow,

+  OUT TD_STRUCT      **ppTD

+  );

+/*++

+

+Routine Description:

+

+  Generate Data Stage TD

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  DevAddr     - Device address

+  Endpoint    - Endpoint number 

+  pData       - Data buffer 

+  Len         - Data length

+  PktID       - Packet ID

+  Toggle      - Data toggle value

+  bSlow       - Full speed or low speed

+  ppTD        - TD_STRUCT to return

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+  EFI_SUCCESS          - Success

+

+--*/

+

+EFI_STATUS

+CreateStatusTD (

+  IN  USB_HC_DEV     *HcDev,

+  IN  UINT8          DevAddr,

+  IN  UINT8          Endpoint,

+  IN  UINT8          PktID,

+  IN  BOOLEAN        bSlow,

+  OUT TD_STRUCT      **ppTD

+  );

+/*++

+

+Routine Description:

+

+  Generate Setup Stage TD

+

+Arguments:

+

+  HcDev       - USB_HC_DEV

+  DevAddr     - Device address

+  Endpoint    - Endpoint number 

+  bSlow       - Full speed or low speed

+  pDevReq     - Device request

+  RequestLen  - Request length

+  ppTD        - TD_STRUCT to return

+Returns:

+

+  EFI_OUT_OF_RESOURCES - Can't allocate memory

+  EFI_SUCCESS          - Success

+

+--*/

+

+VOID

+SetTDLinkPtrValidorInvalid (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bValid

+  );

+

+VOID

+SetTDLinkPtrQHorTDSelect (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bQH

+  );

+

+VOID

+SetTDLinkPtrDepthorBreadth (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bDepth

+  );

+

+VOID

+SetTDLinkPtr (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN VOID          *ptrNext

+  );

+

+VOID *

+GetTDLinkPtr (

+  IN TD_STRUCT   *ptrTDStruct

+  );

+

+VOID

+EnableorDisableTDShortPacket (

+  IN TD_STRUCT   *ptrTDStruct,

+  IN BOOLEAN     bEnable

+  );

+

+VOID

+SetTDControlErrorCounter (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINT8         nMaxErrors

+  );

+

+VOID

+SetTDLoworFullSpeedDevice (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bLowSpeedDevice

+  );

+

+VOID

+SetTDControlIsochronousorNot (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bIsochronous

+  );

+

+VOID

+SetorClearTDControlIOC (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bSet

+  );

+

+VOID

+SetTDStatusActiveorInactive (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN BOOLEAN       bActive

+  );

+

+UINT16

+SetTDTokenMaxLength (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINT16        nMaxLen

+  );

+

+VOID

+SetTDTokenDataToggle1 (

+  IN TD_STRUCT    *ptrTDStruct

+  );

+

+VOID

+SetTDTokenDataToggle0 (

+  IN TD_STRUCT    *ptrTDStruct

+  );

+

+UINT8

+GetTDTokenDataToggle (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+VOID

+SetTDTokenEndPoint (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINTN         nEndPoint

+  );

+

+VOID

+SetTDTokenDeviceAddress (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINTN         nDevAddr

+  );

+

+VOID

+SetTDTokenPacketID (

+  IN TD_STRUCT     *ptrTDStruct,

+  IN UINT8         nPID

+  );

+

+VOID

+SetTDDataBuffer (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusActive (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusStalled (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusBufferError (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusBabbleError (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusNAKReceived (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusCRCTimeOutError (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+IsTDStatusBitStuffError (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINT16

+GetTDStatusActualLength (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINT16

+GetTDTokenMaxLength (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINT8

+GetTDTokenEndPoint (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINT8

+GetTDTokenDeviceAddress (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINT8

+GetTDTokenPacketID (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINT8 *

+GetTDDataBuffer (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+BOOLEAN

+GetTDLinkPtrValidorInvalid (

+  IN TD_STRUCT     *ptrTDStruct

+  );

+

+UINTN

+CountTDsNumber (

+  IN TD_STRUCT     *ptrFirstTD

+  );

+

+VOID

+LinkTDToQH (

+  IN QH_STRUCT     *ptrQH,

+  IN TD_STRUCT     *ptrTD

+  );

+

+VOID

+LinkTDToTD (

+  IN TD_STRUCT     *ptrPreTD,

+  IN TD_STRUCT     *ptrTD

+  );

+

+VOID

+SetorClearCurFrameListTerminate (

+  IN FRAMELIST_ENTRY     *pCurEntry,

+  IN BOOLEAN             bSet

+  );

+

+VOID

+SetCurFrameListQHorTD (

+  IN FRAMELIST_ENTRY        *pCurEntry,

+  IN BOOLEAN                bQH

+  );

+

+BOOLEAN

+GetCurFrameListTerminate (

+  IN FRAMELIST_ENTRY     *pCurEntry

+  );

+

+VOID

+SetCurFrameListPointer (

+  IN FRAMELIST_ENTRY     *pCurEntry,

+  IN UINT8               *ptr

+  );

+

+VOID *

+GetCurFrameListPointer (

+  IN FRAMELIST_ENTRY     *pCurEntry

+  );

+

+VOID

+LinkQHToFrameList (

+  IN FRAMELIST_ENTRY   *pEntry,

+  IN UINT16            FrameListIndex,

+  IN QH_STRUCT         *ptrQH

+  );

+/*++

+

+Routine Description:

+

+  Link QH To Frame List

+

+Arguments:

+

+  pEntry           - FRAMELIST_ENTRY

+  FrameListIndex   - Frame List Index

+  PtrQH            - QH to link 

+Returns:

+

+  VOID

+

+--*/

+VOID

+DeleteQHTDs (

+  IN FRAMELIST_ENTRY *pEntry,

+  IN QH_STRUCT       *ptrQH,

+  IN TD_STRUCT       *ptrFirstTD,

+  IN UINT16          FrameListIndex,

+  IN BOOLEAN         SearchOther

+  );

+

+VOID

+DelLinkSingleQH (

+  IN USB_HC_DEV      *HcDev,

+  IN QH_STRUCT       *ptrQH,

+  IN UINT16          FrameListIndex,

+  IN BOOLEAN         SearchOther,

+  IN BOOLEAN         Delete

+  );

+

+VOID

+DeleteQueuedTDs (

+  IN USB_HC_DEV      *HcDev,

+  IN TD_STRUCT       *ptrFirstTD

+  );

+

+VOID

+InsertQHTDToINTList (

+  IN USB_HC_DEV                        *HcDev,

+  IN QH_STRUCT                         *ptrQH,

+  IN TD_STRUCT                         *ptrFirstTD,

+  IN UINT8                             DeviceAddress,

+  IN UINT8                             EndPointAddress,

+  IN UINT8                             DataToggle,

+  IN UINTN                             DataLength,

+  IN UINTN                             PollingInterval,

+  IN VOID                              *Mapping,

+  IN UINT8                             *DataBuffer,

+  IN EFI_ASYNC_USB_TRANSFER_CALLBACK   CallBackFunction,

+  IN VOID                              *Context

+  );

+/*++

+Routine Description:

+  Insert QH and TD To Interrupt List

+Arguments:

+

+  HcDev           - USB_HC_DEV

+  PtrQH           - QH_STRUCT

+  PtrFirstTD      - First TD_STRUCT

+  DeviceAddress   - Device Address

+  EndPointAddress - EndPoint Address

+  DataToggle      - Data Toggle

+  DataLength      - Data length 

+  PollingInterval - Polling Interval when inserted to frame list

+  Mapping         - Mapping alue  

+  DataBuffer      - Data buffer

+  CallBackFunction- CallBackFunction after interrupt transfeer

+  Context         - CallBackFunction Context passed as function parameter

+Returns:

+  EFI_SUCCESS            - Sucess

+  EFI_INVALID_PARAMETER  - Paremeter is error 

+

+--*/

+

+EFI_STATUS

+DeleteAsyncINTQHTDs (

+  IN  USB_HC_DEV  *HcDev,

+  IN  UINT8       DeviceAddress,

+  IN  UINT8       EndPointAddress,

+  OUT UINT8       *DataToggle

+  );

+/*++

+Routine Description:

+

+  Delete Async INT QH and TDs

+Arguments:

+

+  HcDev           - USB_HC_DEV

+  DeviceAddress   - Device Address

+  EndPointAddress - EndPoint Address

+  DataToggle      - Data Toggle

+

+Returns:

+  EFI_SUCCESS            - Sucess

+  EFI_INVALID_PARAMETER  - Paremeter is error 

+

+--*/

+BOOLEAN

+CheckTDsResults (

+  IN  TD_STRUCT               *ptrTD,

+  IN  UINTN                   RequiredLen,

+  OUT UINT32                  *Result,

+  OUT UINTN                   *ErrTDPos,

+  OUT UINTN                   *ActualTransferSize

+  );

+/*++

+

+Routine Description:

+

+  Check TDs Results

+

+Arguments:

+

+  PtrTD               - TD_STRUCT to check

+  RequiredLen         - Required Len

+  Result              - Transfer result

+  ErrTDPos            - Error TD Position

+  ActualTransferSize  - Actual Transfer Size

+

+Returns:

+

+  TRUE  - Sucess

+  FALSE - Fail

+

+--*/

+VOID

+ExecuteAsyncINTTDs (

+  IN  USB_HC_DEV      *HcDev,

+  IN  INTERRUPT_LIST  *ptrList,

+  OUT UINT32          *Result,

+  OUT UINTN           *ErrTDPos,

+  OUT UINTN           *ActualLen

+  ) ;

+/*++

+

+Routine Description:

+

+  Execute Async Interrupt TDs

+

+Arguments:

+

+  HcDev     - USB_HC_DEV

+  PtrList   - INTERRUPT_LIST

+  Result    - Transfer result

+  ErrTDPos  - Error TD Position

+  ActualTransferSize  - Actual Transfer Size

+  

+Returns:

+

+  VOID

+

+--*/

+VOID

+UpdateAsyncINTQHTDs (

+  IN INTERRUPT_LIST  *ptrList,

+  IN UINT32          Result,

+  IN UINT32          ErrTDPos

+  );

+/*++

+

+Routine Description:

+

+  Update Async Interrupt QH and TDs

+

+Arguments:

+

+  PtrList   - INTERRUPT_LIST

+  Result    - Transfer reslut

+  ErrTDPos  - Error TD Position

+

+Returns:

+

+  VOID

+

+--*/

+VOID

+ReleaseInterruptList (

+  IN USB_HC_DEV      *HcDev,

+  IN LIST_ENTRY      *ListHead

+  );

+/*++

+

+Routine Description:

+

+  Release Interrupt List

+Arguments:

+

+  HcDev     - USB_HC_DEV

+  ListHead  - List head

+

+Returns:

+

+  VOID

+

+--*/

+EFI_STATUS

+ExecuteControlTransfer (

+  IN  USB_HC_DEV  *HcDev,

+  IN  TD_STRUCT   *ptrTD,

+  IN  UINT32      wIndex,

+  OUT UINTN       *ActualLen,

+  IN  UINTN       TimeOut,

+  OUT UINT32      *TransferResult

+  );

+/*++

+

+Routine Description:

+

+  Execute Control Transfer

+

+Arguments:

+

+  HcDev            - USB_HC_DEV

+  PtrTD            - TD_STRUCT

+  wIndex           - No use

+  ActualLen        - Actual transfered Len 

+  TimeOut          - TimeOut value in milliseconds

+  TransferResult   - Transfer result

+Returns:

+

+  EFI_SUCCESS      - Sucess

+  EFI_DEVICE_ERROR - Error

+  

+

+--*/

+EFI_STATUS

+ExecBulkorSyncInterruptTransfer (

+  IN  USB_HC_DEV  *HcDev,

+  IN  TD_STRUCT   *ptrTD,

+  IN  UINT32      wIndex,

+  OUT UINTN       *ActualLen,

+  OUT UINT8       *DataToggle,

+  IN  UINTN       TimeOut,

+  OUT UINT32      *TransferResult

+  );

+/*++

+

+Routine Description:

+

+  Execute Bulk or SyncInterrupt Transfer

+

+Arguments:

+

+  HcDev            - USB_HC_DEV

+  PtrTD            - TD_STRUCT

+  wIndex           - No use

+  ActualLen        - Actual transfered Len 

+  DataToggle       - Data Toggle

+  TimeOut          - TimeOut value in milliseconds

+  TransferResult   - Transfer result

+Returns:

+

+  EFI_SUCCESS      - Sucess

+  EFI_DEVICE_ERROR - Error

+--*/

+

+EFI_STATUS

+InitializeMemoryManagement (

+  IN USB_HC_DEV           *HcDev

+  );

+

+EFI_STATUS

+CreateMemoryBlock (

+  IN USB_HC_DEV            *HcDev,

+  IN MEMORY_MANAGE_HEADER  **MemoryHeader,

+  IN UINTN                 MemoryBlockSizeInPages

+  );

+

+EFI_STATUS

+FreeMemoryHeader (

+  IN USB_HC_DEV            *HcDev,

+  IN MEMORY_MANAGE_HEADER  *MemoryHeader

+  );

+

+EFI_STATUS

+UhciAllocatePool (

+  IN USB_HC_DEV      *UhcDev,

+  IN UINT8           **Pool,

+  IN UINTN           AllocSize

+  );

+

+VOID

+UhciFreePool (

+  IN USB_HC_DEV      *HcDev,

+  IN UINT8           *Pool,

+  IN UINTN           AllocSize

+  );

+

+VOID

+InsertMemoryHeaderToList (

+  IN MEMORY_MANAGE_HEADER  *MemoryHeader,

+  IN MEMORY_MANAGE_HEADER  *NewMemoryHeader

+  );

+

+EFI_STATUS

+AllocMemInMemoryBlock (

+  IN MEMORY_MANAGE_HEADER  *MemoryHeader,

+  IN VOID                  **Pool,

+  IN UINTN                 NumberOfMemoryUnit

+  );

+

+BOOLEAN

+IsMemoryBlockEmptied (

+  IN MEMORY_MANAGE_HEADER  *MemoryHeaderPtr

+  );

+

+VOID

+DelinkMemoryBlock (

+  IN MEMORY_MANAGE_HEADER    *FirstMemoryHeader,

+  IN MEMORY_MANAGE_HEADER    *FreeMemoryHeader

+  );

+

+EFI_STATUS

+DelMemoryManagement (

+  IN USB_HC_DEV      *HcDev

+  );

+

+VOID

+EnableMaxPacketSize (

+  IN USB_HC_DEV          *HcDev

+  );

+

+VOID

+CleanUsbTransactions (

+  IN USB_HC_DEV    *HcDev

+  );

+

+VOID

+TurnOffUSBEmulation (

+  IN EFI_PCI_IO_PROTOCOL  *PciIo

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Decode.c b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Decode.c
new file mode 100644
index 0000000..f851b9b
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Decode.c
@@ -0,0 +1,1661 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+    decode.c

+

+Abstract:

+

+Revision history:

+

+--*/

+

+// TODO: fix comment to add: Module Name: DECODE.C

+#include "undi32.h"

+

+

+#pragma data_seg("rtdata")

+

+//

+// Global variables defined outside this file

+//

+extern PXE_SW_UNDI  *pxe;     // !pxe structure

+extern PXE_SW_UNDI  *pxe_31;  // !pxe structure for 3.1 drivers

+extern UNDI32_DEV   *UNDI32DeviceList[MAX_NIC_INTERFACES];

+

+//

+// Global variables defined in this file

+//

+UNDI_CALL_TABLE api_table[PXE_OPCODE_LAST_VALID+1] = { \

+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0, (UINT16)(ANY_STATE),UNDI_GetState },\

+  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,0,(UINT16)(ANY_STATE),UNDI_Start },\

+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0,MUST_BE_STARTED,UNDI_Stop },\

+  {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_INIT_INFO),0,MUST_BE_STARTED, UNDI_GetInitInfo },\

+  {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_CONFIG_INFO),0,MUST_BE_STARTED, UNDI_GetConfigInfo },\

+  {sizeof(PXE_CPB_INITIALIZE),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),MUST_BE_STARTED,UNDI_Initialize },\

+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED,UNDI_Reset },\

+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0, MUST_BE_INITIALIZED,UNDI_Shutdown },\

+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED,UNDI_Interrupt },\

+  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_RecFilter },\

+  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_StnAddr },\

+  {PXE_CPBSIZE_NOT_USED, (UINT16)(DONT_CHECK), (UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Statistics },\

+  {sizeof(PXE_CPB_MCAST_IP_TO_MAC),sizeof(PXE_DB_MCAST_IP_TO_MAC), (UINT16)(DONT_CHECK),MUST_BE_INITIALIZED, UNDI_ip2mac },\

+  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_NVData },\

+  {PXE_CPBSIZE_NOT_USED,(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Status },\

+  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_FillHeader },\

+  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Transmit },\

+  {sizeof(PXE_CPB_RECEIVE),sizeof(PXE_DB_RECEIVE),0,MUST_BE_INITIALIZED, UNDI_Receive } \

+};

+

+//

+// end of global variables

+//

+

+VOID

+UNDI_GetState (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine determines the operational state of the UNDI.  It updates the state flags in the

+  Command Descriptor Block based on information derived from the AdapterInfo instance data.

+

+  To ensure the command has completed successfully, CdbPtr->StatCode will contain the result of

+  the command execution.

+

+  The CdbPtr->StatFlags will contain a STOPPED, STARTED, or INITIALIZED state once the command

+  has successfully completed.

+

+  Keep in mind the AdapterInfo->State is the active state of the adapter (based on software

+  interrogation), and the CdbPtr->StateFlags is the passed back information that is reflected

+  to the caller of the UNDI API.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  CdbPtr->StatFlags |= AdapterInfo->State;

+  return ;

+}

+

+VOID

+UNDI_Start (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to change the operational state of the UNDI from stopped to started.

+  It will do this as long as the adapter's state is PXE_STATFLAGS_GET_STATE_STOPPED, otherwise

+  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the

+  UNDI as having already been started.

+

+  This routine is modified to reflect the undi 1.1 specification changes. The

+  changes in the spec are mainly in the callback routines, the new spec adds

+  3 more callbacks and a unique id.

+  Since this UNDI supports both old and new undi specifications,

+  The NIC's data structure is filled in with the callback routines (depending

+  on the version) pointed to in the caller's CpbPtr.  This seeds the Delay,

+  Virt2Phys, Block, and Mem_IO for old and new versions and Map_Mem, UnMap_Mem

+  and Sync_Mem routines and a unique id variable for the new version.

+  This is the function which an external entity (SNP, O/S, etc) would call

+  to provide it's I/O abstraction to the UNDI.

+

+  It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STARTED.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_CPB_START_30  *CpbPtr;

+  PXE_CPB_START_31  *CpbPtr_31;

+

+  //

+  // check if it is already started.

+  //

+  if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_STOPPED) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_STARTED;

+    return ;

+  }

+

+  if (CdbPtr->CPBsize != sizeof(PXE_CPB_START_30) &&

+      CdbPtr->CPBsize != sizeof(PXE_CPB_START_31)) {

+

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  CpbPtr    = (PXE_CPB_START_30 *) (UINTN) (CdbPtr->CPBaddr);

+  CpbPtr_31 = (PXE_CPB_START_31 *) (UINTN) (CdbPtr->CPBaddr);

+

+  if (AdapterInfo->VersionFlag == 0x30) {

+    AdapterInfo->Delay_30     = (bsptr_30) (UINTN) CpbPtr->Delay;

+    AdapterInfo->Virt2Phys_30 = (virtphys_30) (UINTN) CpbPtr->Virt2Phys;

+    AdapterInfo->Block_30     = (block_30) (UINTN) CpbPtr->Block;

+    //

+    // patch for old buggy 3.0 code:

+    // In EFI1.0 undi used to provide the full (absolute) I/O address to the

+    // i/o calls and SNP used to provide a callback that used GlobalIoFncs and

+    // everything worked fine! In EFI 1.1, UNDI is not using the full

+    // i/o or memory address to access the device, The base values for the i/o

+    // and memory address is abstracted by the device specific PciIoFncs and

+    // UNDI only uses the offset values. Since UNDI3.0 cannot provide any

+    // identification to SNP, SNP cannot use nic specific PciIoFncs callback!

+    //

+    // To fix this and make undi3.0 work with SNP in EFI1.1 we

+    // use a TmpMemIo function that is defined in init.c

+    // This breaks the runtime driver feature of undi, but what to do

+    // if we have to provide the 3.0 compatibility (including the 3.0 bugs)

+    //

+    // This TmpMemIo function also takes a UniqueId parameter

+    // (as in undi3.1 design) and so initialize the UniqueId as well here

+    // Note: AdapterInfo->Mem_Io_30 is just filled for consistency with other

+    // parameters but never used, we only use Mem_Io field in the In/Out routines

+    // inside e100b.c.

+    //

+    AdapterInfo->Mem_Io_30  = (mem_io_30) (UINTN) CpbPtr->Mem_IO;

+    AdapterInfo->Mem_Io     = (mem_io) (UINTN) TmpMemIo;

+    AdapterInfo->Unique_ID  = (UINT64) (UINTN) AdapterInfo;

+

+  } else {

+    AdapterInfo->Delay      = (bsptr) (UINTN) CpbPtr_31->Delay;

+    AdapterInfo->Virt2Phys  = (virtphys) (UINTN) CpbPtr_31->Virt2Phys;

+    AdapterInfo->Block      = (block) (UINTN) CpbPtr_31->Block;

+    AdapterInfo->Mem_Io     = (mem_io) (UINTN) CpbPtr_31->Mem_IO;

+

+    AdapterInfo->Map_Mem    = (map_mem) (UINTN) CpbPtr_31->Map_Mem;

+    AdapterInfo->UnMap_Mem  = (unmap_mem) (UINTN) CpbPtr_31->UnMap_Mem;

+    AdapterInfo->Sync_Mem   = (sync_mem) (UINTN) CpbPtr_31->Sync_Mem;

+    AdapterInfo->Unique_ID  = CpbPtr_31->Unique_ID;

+  }

+

+  AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;

+

+  return ;

+}

+

+VOID

+UNDI_Stop (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to change the operational state of the UNDI from started to stopped.

+  It will not do this if the adapter's state is PXE_STATFLAGS_GET_STATE_INITIALIZED, otherwise

+  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the

+  UNDI as having already not been shut down.

+

+  The NIC's data structure will have the Delay, Virt2Phys, and Block, pointers zero'd out..

+

+  It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STOPPED.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_NOT_SHUTDOWN;

+    return ;

+  }

+

+  AdapterInfo->Delay_30     = 0;

+  AdapterInfo->Virt2Phys_30 = 0;

+  AdapterInfo->Block_30     = 0;

+

+  AdapterInfo->Delay        = 0;

+  AdapterInfo->Virt2Phys    = 0;

+  AdapterInfo->Block        = 0;

+

+  AdapterInfo->Map_Mem      = 0;

+  AdapterInfo->UnMap_Mem    = 0;

+  AdapterInfo->Sync_Mem     = 0;

+

+  AdapterInfo->State        = PXE_STATFLAGS_GET_STATE_STOPPED;

+

+  return ;

+}

+

+VOID

+UNDI_GetInitInfo (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to retrieve the initialization information that is needed by drivers and

+  applications to initialize the UNDI.  This will fill in data in the Data Block structure that is

+  pointed to by the caller's CdbPtr->DBaddr.  The fields filled in are as follows:

+

+  MemoryRequired, FrameDataLen, LinkSpeeds[0-3], NvCount, NvWidth, MediaHeaderLen, HWaddrLen,

+  MCastFilterCnt, TxBufCnt, TxBufSize, RxBufCnt, RxBufSize, IFtype, Duplex, and LoopBack.

+

+  In addition, the CdbPtr->StatFlags ORs in that this NIC supports cable detection.  (APRIORI knowledge)

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_DB_GET_INIT_INFO  *DbPtr;

+

+  DbPtr = (PXE_DB_GET_INIT_INFO *) (UINTN) (CdbPtr->DBaddr);

+

+  DbPtr->MemoryRequired = MEMORY_NEEDED;

+  DbPtr->FrameDataLen = PXE_MAX_TXRX_UNIT_ETHER;

+  DbPtr->LinkSpeeds[0] = 10;

+  DbPtr->LinkSpeeds[1] = 100;

+  DbPtr->LinkSpeeds[2] = DbPtr->LinkSpeeds[3] = 0;

+  DbPtr->NvCount = MAX_EEPROM_LEN;

+  DbPtr->NvWidth = 4;

+  DbPtr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;

+  DbPtr->HWaddrLen = PXE_HWADDR_LEN_ETHER;

+  DbPtr->MCastFilterCnt = MAX_MCAST_ADDRESS_CNT;

+

+  DbPtr->TxBufCnt = TX_BUFFER_COUNT;

+  DbPtr->TxBufSize = sizeof (TxCB);

+  DbPtr->RxBufCnt = RX_BUFFER_COUNT;

+  DbPtr->RxBufSize = sizeof (RxFD);

+

+  DbPtr->IFtype = PXE_IFTYPE_ETHERNET;

+  DbPtr->SupportedDuplexModes = PXE_DUPLEX_ENABLE_FULL_SUPPORTED |

+                  PXE_DUPLEX_FORCE_FULL_SUPPORTED;

+  DbPtr->SupportedLoopBackModes = PXE_LOOPBACK_INTERNAL_SUPPORTED |

+                    PXE_LOOPBACK_EXTERNAL_SUPPORTED;

+

+  CdbPtr->StatFlags |= PXE_STATFLAGS_CABLE_DETECT_SUPPORTED;

+  return ;

+}

+

+VOID

+UNDI_GetConfigInfo (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to retrieve the configuration information about the NIC being controlled by

+  this driver.  This will fill in data in the Data Block structure that is pointed to by the caller's CdbPtr->DBaddr.

+  The fields filled in are as follows:

+

+  DbPtr->pci.BusType, DbPtr->pci.Bus, DbPtr->pci.Device, and DbPtr->pci.

+

+  In addition, the DbPtr->pci.Config.Dword[0-63] grabs a copy of this NIC's PCI configuration space.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  UINT16                  Index;

+  PXE_DB_GET_CONFIG_INFO  *DbPtr;

+

+  DbPtr               = (PXE_DB_GET_CONFIG_INFO *) (UINTN) (CdbPtr->DBaddr);

+

+  DbPtr->pci.BusType  = PXE_BUSTYPE_PCI;

+  DbPtr->pci.Bus      = AdapterInfo->Bus;

+  DbPtr->pci.Device   = AdapterInfo->Device;

+  DbPtr->pci.Function = AdapterInfo->Function;

+

+  for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {

+    DbPtr->pci.Config.Dword[Index] = AdapterInfo->Config[Index];

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Initialize (

+  IN  PXE_CDB       *CdbPtr,

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine resets the network adapter and initializes the UNDI using the parameters supplied in

+  the CPB.  This command must be issued before the network adapter can be setup to transmit and

+  receive packets.

+

+  Once the memory requirements of the UNDI are obtained by using the GetInitInfo command, a block

+  of non-swappable memory may need to be allocated.  The address of this memory must be passed to

+  UNDI during the Initialize in the CPB.  This memory is used primarily for transmit and receive buffers.

+

+  The fields CableDetect, LinkSpeed, Duplex, LoopBack, MemoryPtr, and MemoryLength are set with information

+  that was passed in the CPB and the NIC is initialized.

+

+  If the NIC initialization fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED

+  Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_INITIALIZED showing the state of

+  the UNDI is now initialized.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_CPB_INITIALIZE  *CpbPtr;

+  PXE_DB_INITIALIZE   *DbPtr;

+

+  if ((CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) &&

+      (CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE)) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  //

+  // check if it is already initialized

+  //

+  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_INITIALIZED;

+    return ;

+  }

+

+  CpbPtr  = (PXE_CPB_INITIALIZE *) (UINTN) CdbPtr->CPBaddr;

+  DbPtr   = (PXE_DB_INITIALIZE *) (UINTN) CdbPtr->DBaddr;

+

+  if (CpbPtr->MemoryLength < (UINT32) MEMORY_NEEDED) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;

+    return ;

+  }

+

+  //

+  // default behaviour is to detect the cable, if the 3rd param is 1,

+  // do not do that

+  //

+  AdapterInfo->CableDetect = (UINT8) ((CdbPtr->OpFlags == (UINT16) PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE) ? (UINT8) 0 : (UINT8) 1);

+  AdapterInfo->LinkSpeedReq = (UINT16) CpbPtr->LinkSpeed;

+  AdapterInfo->DuplexReq    = CpbPtr->DuplexMode;

+  AdapterInfo->LoopBack     = CpbPtr->LoopBackMode;

+  AdapterInfo->MemoryPtr    = CpbPtr->MemoryAddr;

+  AdapterInfo->MemoryLength = CpbPtr->MemoryLength;

+

+  CdbPtr->StatCode          = (PXE_STATCODE) E100bInit (AdapterInfo);

+

+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+  } else {

+    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_INITIALIZED;

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Reset (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine resets the network adapter and initializes the UNDI using the parameters supplied in

+  the CPB.  The transmit and receive queues are emptied and any pending interrupts are cleared.

+

+  If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  if (CdbPtr->OpFlags != PXE_OPFLAGS_NOT_USED &&

+      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS &&

+      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_FILTERS ) {

+

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  CdbPtr->StatCode = (UINT16) E100bReset (AdapterInfo, CdbPtr->OpFlags);

+

+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+  }

+}

+

+VOID

+UNDI_Shutdown (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine resets the network adapter and leaves it in a safe state for another driver to

+  initialize.  Any pending transmits or receives are lost.  Receive filters and external

+  interrupt enables are disabled.  Once the UNDI has been shutdown, it can then be stopped

+  or initialized again.

+

+  If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED

+

+  Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_STARTED showing the state of

+  the NIC as being started.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  //

+  // do the shutdown stuff here

+  //

+  CdbPtr->StatCode = (UINT16) E100bShutdown (AdapterInfo);

+

+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+  } else {

+    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Interrupt (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine can be used to read and/or change the current external interrupt enable

+  settings.  Disabling an external interrupt enable prevents and external (hardware)

+  interrupt from being signaled by the network device.  Internally the interrupt events

+  can still be polled by using the UNDI_GetState command.

+

+  The resulting information on the interrupt state will be passed back in the CdbPtr->StatFlags.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  UINT8 IntMask;

+

+  IntMask = (UINT8)(UINTN)(CdbPtr->OpFlags & (PXE_OPFLAGS_INTERRUPT_RECEIVE |

+                                              PXE_OPFLAGS_INTERRUPT_TRANSMIT |

+                                              PXE_OPFLAGS_INTERRUPT_COMMAND |

+                                              PXE_OPFLAGS_INTERRUPT_SOFTWARE));

+

+  switch (CdbPtr->OpFlags & PXE_OPFLAGS_INTERRUPT_OPMASK) {

+  case PXE_OPFLAGS_INTERRUPT_READ:

+    break;

+

+  case PXE_OPFLAGS_INTERRUPT_ENABLE:

+    if (IntMask == 0) {

+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+      return ;

+    }

+

+    AdapterInfo->int_mask = IntMask;

+    E100bSetInterruptState (AdapterInfo);

+    break;

+

+  case PXE_OPFLAGS_INTERRUPT_DISABLE:

+    if (IntMask != 0) {

+      AdapterInfo->int_mask &= ~(IntMask);

+      E100bSetInterruptState (AdapterInfo);

+      break;

+    }

+

+  //

+  // else fall thru.

+  //

+  default:

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {

+    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_RECEIVE;

+

+  }

+

+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_TRANSMIT) != 0) {

+    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_TRANSMIT;

+

+  }

+

+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_COMMAND) != 0) {

+    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_COMMAND;

+

+  }

+

+  return ;

+}

+

+VOID

+UNDI_RecFilter (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to read and change receive filters and, if supported, read

+  and change multicast MAC address filter list.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  UINT16                  NewFilter;

+  UINT16                  OpFlags;

+  PXE_DB_RECEIVE_FILTERS  *DbPtr;

+  UINT8                   *MacAddr;

+  UINTN                   MacCount;

+  UINT16                  Index;

+  UINT16                  copy_len;

+  UINT8                   *ptr1;

+  UINT8                   *ptr2;

+  OpFlags   = CdbPtr->OpFlags;

+  NewFilter = (UINT16) (OpFlags & 0x1F);

+

+  switch (OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_OPMASK) {

+  case PXE_OPFLAGS_RECEIVE_FILTER_READ:

+

+    //

+    // not expecting a cpb, not expecting any filter bits

+    //

+    if ((NewFilter != 0) || (CdbPtr->CPBsize != 0)) {

+      goto BadCdb;

+

+    }

+

+    if ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) == 0) {

+      goto JustRead;

+

+    }

+

+    NewFilter |= AdapterInfo->Rx_Filter;

+    //

+    // all other flags are ignored except mcast_reset

+    //

+    break;

+

+  case PXE_OPFLAGS_RECEIVE_FILTER_ENABLE:

+    //

+    // there should be atleast one other filter bit set.

+    //

+    if (NewFilter == 0) {

+      //

+      // nothing to enable

+      //

+      goto BadCdb;

+    }

+

+    if (CdbPtr->CPBsize != 0) {

+      //

+      // this must be a multicast address list!

+      // don't accept the list unless selective_mcast is set

+      // don't accept confusing mcast settings with this

+      //

+      if (((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) == 0) ||

+          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||

+          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ||

+          ((CdbPtr->CPBsize % sizeof (PXE_MAC_ADDR)) != 0) ) {

+        goto BadCdb;

+      }

+

+      MacAddr   = (UINT8 *) ((UINTN) (CdbPtr->CPBaddr));

+      MacCount  = CdbPtr->CPBsize / sizeof (PXE_MAC_ADDR);

+

+      for (; MacCount-- != 0; MacAddr += sizeof (PXE_MAC_ADDR)) {

+        if (MacAddr[0] != 0x01 || MacAddr[1] != 0x00 || MacAddr[2] != 0x5E || (MacAddr[3] & 0x80) != 0) {

+          CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+          CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;

+          return ;

+        }

+      }

+    }

+

+    //

+    // check selective mcast case enable case

+    //

+    if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {

+      if (((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||

+          ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ) {

+        goto BadCdb;

+

+      }

+      //

+      // if no cpb, make sure we have an old list

+      //

+      if ((CdbPtr->CPBsize == 0) && (AdapterInfo->mcast_list.list_len == 0)) {

+        goto BadCdb;

+      }

+    }

+    //

+    // if you want to enable anything, you got to have unicast

+    // and you have what you already enabled!

+    //

+    NewFilter |= (PXE_OPFLAGS_RECEIVE_FILTER_UNICAST | AdapterInfo->Rx_Filter);

+

+    break;

+

+  case PXE_OPFLAGS_RECEIVE_FILTER_DISABLE:

+

+    //

+    // mcast list not expected, i.e. no cpb here!

+    //

+    if (CdbPtr->CPBsize != PXE_CPBSIZE_NOT_USED) {

+      goto BadCdb;

+    }

+

+    NewFilter = (UINT16) ((~(CdbPtr->OpFlags & 0x1F)) & AdapterInfo->Rx_Filter);

+

+    break;

+

+  default:

+    goto BadCdb;

+  }

+

+  if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) {

+    AdapterInfo->mcast_list.list_len = 0;

+    NewFilter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);

+  }

+

+  E100bSetfilter (AdapterInfo, NewFilter, CdbPtr->CPBaddr, CdbPtr->CPBsize);

+

+JustRead:

+  //

+  // give the current mcast list

+  //

+  if ((CdbPtr->DBsize != 0) && (AdapterInfo->mcast_list.list_len != 0)) {

+    //

+    // copy the mc list to db

+    //

+

+    DbPtr = (PXE_DB_RECEIVE_FILTERS *) (UINTN) CdbPtr->DBaddr;

+    ptr1  = (UINT8 *) (&DbPtr->MCastList[0]);

+

+    //

+    // DbPtr->mc_count = AdapterInfo->mcast_list.list_len;

+    //

+    copy_len = (UINT16) (AdapterInfo->mcast_list.list_len * PXE_MAC_LENGTH);

+

+    if (copy_len > CdbPtr->DBsize) {

+      copy_len = CdbPtr->DBsize;

+

+    }

+

+    ptr2 = (UINT8 *) (&AdapterInfo->mcast_list.mc_list[0]);

+    for (Index = 0; Index < copy_len; Index++) {

+      ptr1[Index] = ptr2[Index];

+    }

+  }

+  //

+  // give the stat flags here

+  //

+  if (AdapterInfo->Receive_Started) {

+    CdbPtr->StatFlags |= AdapterInfo->Rx_Filter;

+

+  }

+

+  return ;

+

+BadCdb:

+  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+}

+

+VOID

+UNDI_StnAddr (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to get the current station and broadcast MAC addresses, and to change the

+  current station MAC address.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_CPB_STATION_ADDRESS *CpbPtr;

+  PXE_DB_STATION_ADDRESS  *DbPtr;

+  UINT16                  Index;

+

+  if (CdbPtr->OpFlags == PXE_OPFLAGS_STATION_ADDRESS_RESET) {

+    //

+    // configure the permanent address.

+    // change the AdapterInfo->CurrentNodeAddress field.

+    //

+    if (CompareMem (

+          &AdapterInfo->CurrentNodeAddress[0],

+          &AdapterInfo->PermNodeAddress[0],

+          PXE_MAC_LENGTH

+          ) != 0) {

+      for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {

+        AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo->PermNodeAddress[Index];

+      }

+

+      E100bSetupIAAddr (AdapterInfo);

+    }

+  }

+

+  if (CdbPtr->CPBaddr != (UINT64) 0) {

+    CpbPtr = (PXE_CPB_STATION_ADDRESS *) (UINTN) (CdbPtr->CPBaddr);

+    //

+    // configure the new address

+    //

+    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {

+      AdapterInfo->CurrentNodeAddress[Index] = CpbPtr->StationAddr[Index];

+    }

+

+    E100bSetupIAAddr (AdapterInfo);

+  }

+

+  if (CdbPtr->DBaddr != (UINT64) 0) {

+    DbPtr = (PXE_DB_STATION_ADDRESS *) (UINTN) (CdbPtr->DBaddr);

+    //

+    // fill it with the new values

+    //

+    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {

+      DbPtr->StationAddr[Index]   = AdapterInfo->CurrentNodeAddress[Index];

+      DbPtr->BroadcastAddr[Index] = AdapterInfo->BroadcastNodeAddress[Index];

+      DbPtr->PermanentAddr[Index] = AdapterInfo->PermNodeAddress[Index];

+    }

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Statistics (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to read and clear the NIC traffic statistics.  This command is supported only

+  if the !PXE structure's Implementation flags say so.

+

+  Results will be parsed out in the following manner:

+  CdbPtr->DBaddr.Data[0]   R  Total Frames (Including frames with errors and dropped frames)

+  CdbPtr->DBaddr.Data[1]   R  Good Frames (All frames copied into receive buffer)

+  CdbPtr->DBaddr.Data[2]   R  Undersize Frames (Frames below minimum length for media <64 for ethernet)

+  CdbPtr->DBaddr.Data[4]   R  Dropped Frames (Frames that were dropped because receive buffers were full)

+  CdbPtr->DBaddr.Data[8]   R  CRC Error Frames (Frames with alignment or CRC errors)

+  CdbPtr->DBaddr.Data[A]   T  Total Frames (Including frames with errors and dropped frames)

+  CdbPtr->DBaddr.Data[B]   T  Good Frames (All frames copied into transmit buffer)

+  CdbPtr->DBaddr.Data[C]   T  Undersize Frames (Frames below minimum length for media <64 for ethernet)

+  CdbPtr->DBaddr.Data[E]   T  Dropped Frames (Frames that were dropped because of collisions)

+  CdbPtr->DBaddr.Data[14]  T  Total Collision Frames (Total collisions on this subnet)

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  if ((CdbPtr->OpFlags &~(PXE_OPFLAGS_STATISTICS_RESET)) != 0) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_STATISTICS_RESET) != 0) {

+    //

+    // Reset the statistics

+    //

+    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, 0, 0);

+  } else {

+    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, CdbPtr->DBaddr, CdbPtr->DBsize);

+  }

+

+  return ;

+}

+

+VOID

+UNDI_ip2mac (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to translate a multicast IP address to a multicast MAC address.

+

+  This results in a MAC address composed of 25 bits of fixed data with the upper 23 bits of the IP

+  address being appended to it.  Results passed back in the equivalent of CdbPtr->DBaddr->MAC[0-5].

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_CPB_MCAST_IP_TO_MAC *CpbPtr;

+  PXE_DB_MCAST_IP_TO_MAC  *DbPtr;

+  UINT8                   *TmpPtr;

+

+  CpbPtr  = (PXE_CPB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->CPBaddr;

+  DbPtr   = (PXE_DB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->DBaddr;

+

+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_MCAST_IPV6_TO_MAC) != 0) {

+    //

+    // for now this is not supported

+    //

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;

+    return ;

+  }

+

+  TmpPtr = (UINT8 *) (&CpbPtr->IP.IPv4);

+  //

+  // check if the ip given is a mcast IP

+  //

+  if ((TmpPtr[0] & 0xF0) != 0xE0) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;

+  }

+  //

+  // take the last 23 bits in IP.

+  // be very careful. accessing word on a non-word boundary will hang motherboard codenamed Big Sur

+  // casting the mac array (in the middle) to a UINT32 pointer and accessing

+  // the UINT32 content hung the system...

+  //

+  DbPtr->MAC[0] = 0x01;

+  DbPtr->MAC[1] = 0x00;

+  DbPtr->MAC[2] = 0x5e;

+  DbPtr->MAC[3] = (UINT8) (TmpPtr[1] & 0x7f);

+  DbPtr->MAC[4] = (UINT8) TmpPtr[2];

+  DbPtr->MAC[5] = (UINT8) TmpPtr[3];

+

+  return ;

+}

+

+VOID

+UNDI_NVData (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to read and write non-volatile storage on the NIC (if supported).  The NVRAM

+  could be EEPROM, FLASH, or battery backed RAM.

+

+  This is an optional function according to the UNDI specification  (or will be......)

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_DB_NVDATA *DbPtr;

+  UINT16        Index;

+

+  if ((CdbPtr->OpFlags == PXE_OPFLAGS_NVDATA_READ) != 0) {

+

+    if ((CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) != 0) {

+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+      return ;

+    }

+

+    DbPtr = (PXE_DB_NVDATA *) (UINTN) CdbPtr->DBaddr;

+

+    for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {

+      DbPtr->Data.Dword[Index] = AdapterInfo->NVData[Index];

+

+    }

+

+  } else {

+    //

+    // no write for now

+    //

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Status (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine returns the current interrupt status and/or the transmitted buffer addresses.

+  If the current interrupt status is returned, pending interrupts will be acknowledged by this

+  command.  Transmitted buffer addresses that are written to the DB are removed from the transmit

+  buffer queue.

+

+  Normally, this command would be polled with interrupts disabled.

+

+  The transmit buffers are returned in CdbPtr->DBaddr->TxBufer[0 - NumEntries].

+  The interrupt status is returned in CdbPtr->StatFlags.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_DB_GET_STATUS *DbPtr;

+  PXE_DB_GET_STATUS TmpGetStatus;

+  UINT16            Index;

+  UINT16            Status;

+  UINT16            NumEntries;

+  RxFD              *RxPtr;

+

+  //

+  // Fill in temporary GetStatus storage.

+  //

+  RxPtr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];

+

+  if ((RxPtr->cb_header.status & RX_COMPLETE) != 0) {

+    TmpGetStatus.RxFrameLen = RxPtr->ActualCount & 0x3fff;

+  } else {

+    TmpGetStatus.RxFrameLen = 0;

+  }

+

+  TmpGetStatus.reserved = 0;

+

+  //

+  // Fill in size of next available receive packet and

+  // reserved field in caller's DB storage.

+  //

+  DbPtr = (PXE_DB_GET_STATUS *) (UINTN) CdbPtr->DBaddr;

+

+  if (CdbPtr->DBsize > 0 && CdbPtr->DBsize < sizeof (UINT32) * 2) {

+    CopyMem (DbPtr, &TmpGetStatus, CdbPtr->DBsize);

+  } else {

+    CopyMem (DbPtr, &TmpGetStatus, sizeof (UINT32) * 2);

+  }

+

+  //

+  //

+  //

+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS) != 0) {

+    //

+    // DBsize of zero is invalid if Tx buffers are requested.

+    //

+    if (CdbPtr->DBsize == 0) {

+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+      return ;

+    }

+

+    //

+    // remember this b4 we overwrite

+    //

+    NumEntries = (UINT16) (CdbPtr->DBsize - sizeof (UINT64));

+

+    //

+    // We already filled in 2 UINT32s.

+    //

+    CdbPtr->DBsize = sizeof (UINT32) * 2;

+

+    //

+    // will claim any hanging free CBs

+    //

+    CheckCBList (AdapterInfo);

+

+    if (AdapterInfo->xmit_done_head == AdapterInfo->xmit_done_tail) {

+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;

+    } else {

+      for (Index = 0; NumEntries >= sizeof (UINT64); Index++, NumEntries -= sizeof (UINT64)) {

+        if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {

+          DbPtr->TxBuffer[Index]      = AdapterInfo->xmit_done[AdapterInfo->xmit_done_head];

+          AdapterInfo->xmit_done_head = next (AdapterInfo->xmit_done_head);

+          CdbPtr->DBsize += sizeof (UINT64);

+        } else {

+          break;

+        }

+      }

+    }

+

+    if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {

+      CdbPtr->StatFlags |= PXE_STATFLAGS_DB_WRITE_TRUNCATED;

+

+    }

+    //

+    // check for a receive buffer and give it's size in db

+    //

+  }

+  //

+  //

+  //

+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_INTERRUPT_STATUS) != 0) {

+

+    Status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);

+    AdapterInfo->Int_Status |= Status;

+

+    //

+    // acknoledge the interrupts

+    //

+    OutWord (AdapterInfo, (UINT16) (Status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus));

+

+    //

+    // report all the outstanding interrupts

+    //

+    Status = AdapterInfo->Int_Status;

+    if ((Status & SCB_STATUS_FR) != 0) {

+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;

+    }

+

+    if ((Status & SCB_STATUS_SWI) != 0) {

+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_SOFTWARE;

+    }

+  }

+

+  return ;

+}

+

+VOID

+UNDI_FillHeader (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to fill media header(s) in transmit packet(s).

+  Copies the MAC address into the media header whether it is dealing

+  with fragmented or non-fragmented packets.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_CPB_FILL_HEADER             *Cpb;

+  PXE_CPB_FILL_HEADER_FRAGMENTED  *Cpbf;

+  EtherHeader                     *MacHeader;

+  UINTN                           Index;

+

+  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED) != 0) {

+    Cpbf = (PXE_CPB_FILL_HEADER_FRAGMENTED *) (UINTN) CdbPtr->CPBaddr;

+

+    //

+    // assume 1st fragment is big enough for the mac header

+    //

+    if ((Cpbf->FragCnt == 0) || (Cpbf->FragDesc[0].FragLen < PXE_MAC_HEADER_LEN_ETHER)) {

+      //

+      // no buffers given

+      //

+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+      return ;

+    }

+

+    MacHeader = (EtherHeader *) (UINTN) Cpbf->FragDesc[0].FragAddr;

+    //

+    // we don't swap the protocol bytes

+    //

+    MacHeader->type = Cpbf->Protocol;

+

+    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+      MacHeader->dest_addr[Index] = Cpbf->DestAddr[Index];

+      MacHeader->src_addr[Index]  = Cpbf->SrcAddr[Index];

+    }

+  } else {

+    Cpb       = (PXE_CPB_FILL_HEADER *) (UINTN) CdbPtr->CPBaddr;

+

+    MacHeader = (EtherHeader *) (UINTN) Cpb->MediaHeader;

+    //

+    // we don't swap the protocol bytes

+    //

+    MacHeader->type = Cpb->Protocol;

+

+    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+      MacHeader->dest_addr[Index] = Cpb->DestAddr[Index];

+      MacHeader->src_addr[Index]  = Cpb->SrcAddr[Index];

+    }

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Transmit (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine is used to place a packet into the transmit queue.  The data buffers given to

+  this command are to be considered locked and the application or network driver loses

+  ownership of these buffers and must not free or relocate them until the ownership returns.

+

+  When the packets are transmitted, a transmit complete interrupt is generated (if interrupts

+  are disabled, the transmit interrupt status is still set and can be checked using the UNDI_Status

+  command.

+

+  Some implementations and adapters support transmitting multiple packets with one transmit

+  command.  If this feature is supported, the transmit CPBs can be linked in one transmit

+  command.

+

+  All UNDIs support fragmented frames, now all network devices or protocols do.  If a fragmented

+  frame CPB is given to UNDI and the network device does not support fragmented frames

+  (see !PXE.Implementation flag), the UNDI will have to copy the fragments into a local buffer

+  before transmitting.

+

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+

+  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  CdbPtr->StatCode = (PXE_STATCODE) E100bTransmit (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->OpFlags);

+

+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+  }

+

+  return ;

+}

+

+VOID

+UNDI_Receive (

+  IN  PXE_CDB           *CdbPtr,

+  IN  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  When the network adapter has received a frame, this command is used to copy the frame

+  into the driver/application storage location.  Once a frame has been copied, it is

+  removed from the receive queue.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+{

+  PXE_CPB_RECEIVE *cpbptr;

+

+  //

+  // check if RU has started...

+  //

+  if (!AdapterInfo->Receive_Started) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;

+    return ;

+  }

+

+  cpbptr            = (PXE_CPB_RECEIVE *) (UINTN) CdbPtr->CPBaddr;

+

+  CdbPtr->StatCode  = (UINT16) E100bReceive (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->DBaddr);

+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+

+  }

+

+  return ;

+}

+

+VOID

+UNDI_APIEntry_old (

+  IN  UINT64 cdb

+  )

+/*++

+

+Routine Description:

+  This is the main SW UNDI API entry using the older nii protocol.

+  The parameter passed in is a 64 bit flat model virtual

+  address of the cdb.  We then jump into the common routine for both old and

+  new nii protocol entries.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+// TODO:    cdb - add argument and description to function comment

+{

+  PXE_CDB           *CdbPtr;

+  NIC_DATA_INSTANCE *AdapterInfo;

+

+  if (cdb == (UINT64) 0) {

+    return ;

+

+  }

+

+  CdbPtr = (PXE_CDB *) (UINTN) cdb;

+

+  if (CdbPtr->IFnum >= pxe->IFcnt) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);

+  

+  //

+  // entering from older entry point

+  //

+  AdapterInfo->VersionFlag  = 0x30;

+  UNDI_APIEntry_Common (cdb);

+}

+

+VOID

+UNDI_APIEntry_new (

+  IN  UINT64 cdb

+  )

+/*++

+

+Routine Description:

+  This is the main SW UNDI API entry using the newer nii protocol.

+  The parameter passed in is a 64 bit flat model virtual

+  address of the cdb.  We then jump into the common routine for both old and

+  new nii protocol entries.

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+// TODO:    cdb - add argument and description to function comment

+{

+  PXE_CDB           *CdbPtr;

+  NIC_DATA_INSTANCE *AdapterInfo;

+

+  if (cdb == (UINT64) 0) {

+    return ;

+

+  }

+

+  CdbPtr = (PXE_CDB *) (UINTN) cdb;

+

+  if (CdbPtr->IFnum >= pxe_31->IFcnt) {

+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+    return ;

+  }

+

+  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);

+  //

+  // entering from older entry point

+  //

+  AdapterInfo->VersionFlag  = 0x31;

+  UNDI_APIEntry_Common (cdb);

+}

+

+VOID

+UNDI_APIEntry_Common (

+  IN  UINT64 cdb

+  )

+/*++

+

+Routine Description:

+  This is the common routine for both old and new entry point procedures.

+  The parameter passed in is a 64 bit flat model virtual

+  address of the cdb.  We then jump into the service routine pointed to by the

+  Api_Table[OpCode].

+

+Arguments:

+  CdbPtr            - Pointer to the command descriptor block.

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  None

+

+--*/

+// TODO:    cdb - add argument and description to function comment

+{

+  PXE_CDB           *CdbPtr;

+  NIC_DATA_INSTANCE *AdapterInfo;

+  UNDI_CALL_TABLE   *tab_ptr;

+

+  CdbPtr = (PXE_CDB *) (UINTN) cdb;

+

+  //

+  // check the OPCODE range

+  //

+  if ((CdbPtr->OpCode > PXE_OPCODE_LAST_VALID) ||

+      (CdbPtr->StatCode != PXE_STATCODE_INITIALIZE) ||

+      (CdbPtr->StatFlags != PXE_STATFLAGS_INITIALIZE) ||

+      (CdbPtr->IFnum >= pxe_31->IFcnt) ) {

+    goto badcdb;

+

+  }

+

+  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {

+    if (CdbPtr->CPBaddr != PXE_CPBADDR_NOT_USED) {

+      goto badcdb;

+    }

+  } else if (CdbPtr->CPBaddr == PXE_CPBADDR_NOT_USED) {

+    goto badcdb;

+  }

+

+  if (CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) {

+    if (CdbPtr->DBaddr != PXE_DBADDR_NOT_USED) {

+      goto badcdb;

+    }

+  } else if (CdbPtr->DBaddr == PXE_DBADDR_NOT_USED) {

+    goto badcdb;

+  }

+

+  //

+  // check if cpbsize and dbsize are as needed

+  // check if opflags are as expected

+  //

+  tab_ptr = &api_table[CdbPtr->OpCode];

+

+  if (tab_ptr->cpbsize != (UINT16) (DONT_CHECK) && tab_ptr->cpbsize != CdbPtr->CPBsize) {

+    goto badcdb;

+  }

+

+  if (tab_ptr->dbsize != (UINT16) (DONT_CHECK) && tab_ptr->dbsize != CdbPtr->DBsize) {

+    goto badcdb;

+  }

+

+  if (tab_ptr->opflags != (UINT16) (DONT_CHECK) && tab_ptr->opflags != CdbPtr->OpFlags) {

+    goto badcdb;

+

+  }

+

+  AdapterInfo = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);

+

+  //

+  // check if UNDI_State is valid for this call

+  //

+  if (tab_ptr->state != (UINT16) (-1)) {

+    //

+    // should atleast be started

+    //

+    if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_STOPPED) {

+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+      CdbPtr->StatCode  = PXE_STATCODE_NOT_STARTED;

+      return ;

+    }

+    //

+    // check if it should be initialized

+    //

+    if (tab_ptr->state == 2) {

+      if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {

+        CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;

+        CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+        return ;

+      }

+    }

+  }

+  //

+  // set the return variable for success case here

+  //

+  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;

+  CdbPtr->StatCode  = PXE_STATCODE_SUCCESS;

+

+  tab_ptr->api_ptr (CdbPtr, AdapterInfo);

+  return ;

+  //

+  // %% AVL - check for command linking

+  //

+badcdb:

+  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

+  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;

+  return ;

+}

+

+UINT8

+ChkSum (

+  IN  VOID   *Buffer,

+  IN  UINT16 Len

+  )

+/*++

+

+Routine Description:

+  This does an 8 bit check sum of the passed in buffer for Len bytes.

+  This is primarily used to update the check sum in the SW UNDI header.

+

+Arguments:

+  Buffer            - Pointer to the passed in buffer to check sum

+  Len               - Length of buffer to be check summed in bytes.

+

+Returns:

+  None

+

+--*/

+{

+  UINT8 Chksum;

+  INT8  *Bp;

+

+  Chksum = 0;

+  if ((Bp = Buffer) != NULL) {

+    while (Len--) {

+      Chksum = (UINT8) (Chksum +*Bp++);

+

+    }

+

+  }

+

+  return Chksum;

+}

+

+VOID

+PxeUpdate (

+  IN  NIC_DATA_INSTANCE *NicPtr,

+  IN PXE_SW_UNDI        *PxePtr

+  )

+/*++

+

+Routine Description:

+  When called with a null NicPtr, this routine decrements the number of NICs

+  this UNDI is supporting and removes the NIC_DATA_POINTER from the array.

+  Otherwise, it increments the number of NICs this UNDI is supported and

+  updates the pxe.Fudge to ensure a proper check sum results.

+

+Arguments:

+  NicPtr            - Pointer to the NIC data structure.

+

+Returns:

+  None

+

+--*/

+// TODO:    PxePtr - add argument and description to function comment

+{

+  if (NicPtr == NULL) {

+    if (PxePtr->IFcnt > 0) {

+      //

+      // number of NICs this undi supports

+      //

+      PxePtr->IFcnt--;

+    }

+

+    PxePtr->Fudge = (UINT8) (PxePtr->Fudge - ChkSum ((VOID *) PxePtr, PxePtr->Len));

+    return ;

+  }

+

+  //

+  // number of NICs this undi supports

+  //

+  PxePtr->IFcnt++;

+  PxePtr->Fudge = (UINT8) (PxePtr->Fudge - ChkSum ((VOID *) PxePtr, PxePtr->Len));

+

+  return ;

+}

+

+VOID

+PxeStructInit (

+  IN PXE_SW_UNDI *PxePtr,

+  IN UINTN       VersionFlag

+  )

+/*++

+

+Routine Description:

+  Initialize the !PXE structure

+

+Arguments:

+  RemainingDevicePath - Not used, always produce all possible children.

+

+Returns:

+  EFI_SUCCESS         - This driver is added to Controller.

+  other               - This driver does not support this device.

+

+--*/

+// TODO:    PxePtr - add argument and description to function comment

+// TODO:    VersionFlag - add argument and description to function comment

+{

+  //

+  // Initialize the !PXE structure

+  //

+  PxePtr->Signature = PXE_ROMID_SIGNATURE;

+  PxePtr->Len       = sizeof (PXE_SW_UNDI);

+  //

+  // cksum

+  //

+  PxePtr->Fudge     = 0;

+  //

+  // number of NICs this undi supports

+  //

+  PxePtr->IFcnt = 0;

+  PxePtr->Rev       = PXE_ROMID_REV;

+  PxePtr->MajorVer  = PXE_ROMID_MAJORVER;

+  PxePtr->MinorVer  = PXE_ROMID_MINORVER;

+  PxePtr->reserved1 = 0;

+

+  PxePtr->Implementation = PXE_ROMID_IMP_SW_VIRT_ADDR |

+    PXE_ROMID_IMP_FRAG_SUPPORTED |

+    PXE_ROMID_IMP_CMD_LINK_SUPPORTED |

+    PXE_ROMID_IMP_NVDATA_READ_ONLY |

+    PXE_ROMID_IMP_STATION_ADDR_SETTABLE |

+    PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |

+    PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |

+    PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |

+    PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED |

+    PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED |

+    PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED;

+

+  if (VersionFlag == 0x30) {

+    PxePtr->EntryPoint = (UINT64) UNDI_APIEntry_old;

+  } else {

+    PxePtr->EntryPoint  = (UINT64) UNDI_APIEntry_new;

+    PxePtr->MinorVer    = PXE_ROMID_MINORVER_31;

+  }

+

+  PxePtr->reserved2[0]  = 0;

+  PxePtr->reserved2[1]  = 0;

+  PxePtr->reserved2[2]  = 0;

+  PxePtr->BusCnt        = 1;

+  PxePtr->BusType[0]    = PXE_BUSTYPE_PCI;

+

+  PxePtr->Fudge         = (UINT8) (PxePtr->Fudge - ChkSum ((VOID *) PxePtr, PxePtr->Len));

+}

+

+#pragma data_seg()

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/E100b.c b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/E100b.c
new file mode 100644
index 0000000..5b69a46
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/E100b.c
@@ -0,0 +1,3772 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  

+ E100B.C

+

+Abstract:

+

+

+Revision History

+

+--*/

+

+#include "undi32.h"

+

+static UINT8 basic_config_cmd[22] = {

+                    22,        0x08,

+                    0,           0,

+                    0, (UINT8)0x80,

+                    0x32,        0x03,

+                    1,            0,

+                    0x2E,           0,

+                    0x60,           0,

+                    (UINT8)0xf2,        0x48,

+                    0,        0x40,

+                    (UINT8)0xf2, (UINT8)0x80, // 0x40=Force full-duplex 

+                    0x3f,       0x05,

+};

+

+//

+// How to wait for the command unit to accept a command.

+// Typically this takes 0 ticks.

+//

+#define wait_for_cmd_done(cmd_ioaddr) \

+{                      \

+  INT16 wait = 2000;              \

+  while ((InByte (AdapterInfo, cmd_ioaddr) != 0) && --wait >= 0)  \

+    DelayIt (AdapterInfo, 10);  \

+  if (wait == 0) \

+    DelayIt (AdapterInfo, 50);    \

+}

+

+UINT8

+InByte (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT32            Port

+  )

+/*++

+

+Routine Description:

+  This function calls the MemIo callback to read a byte from the device's

+  address space

+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)

+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 

+  to make undi3.0 a special case

+  

+Arguments:

+  Port              - Which port to read from.

+

+Returns:

+  Results           - The data read from the port.

+

+--*/

+// TODO:    AdapterInfo - add argument and description to function comment

+{

+  UINT8 Results;

+

+  (*AdapterInfo->Mem_Io) (

+    AdapterInfo->Unique_ID, 

+    PXE_MEM_READ, 

+    1, 

+    (UINT64)Port,

+    (UINT64) (UINTN) &Results

+    );

+  return Results;

+}

+

+UINT16

+InWord (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT32            Port

+  )

+/*++

+

+Routine Description:

+  This function calls the MemIo callback to read a word from the device's

+  address space

+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)

+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 

+  to make undi3.0 a special case

+

+Arguments:

+  Port              - Which port to read from.

+

+Returns:

+  Results           - The data read from the port.

+

+--*/

+// TODO:    AdapterInfo - add argument and description to function comment

+{

+  UINT16  Results;

+

+  (*AdapterInfo->Mem_Io) (

+    AdapterInfo->Unique_ID,

+    PXE_MEM_READ,

+    2,

+    (UINT64)Port,

+    (UINT64)(UINTN)&Results

+    );

+  return Results;

+}

+

+UINT32

+InLong (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT32            Port

+  )

+/*++

+

+Routine Description:

+  This function calls the MemIo callback to read a dword from the device's

+  address space

+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)

+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 

+  to make undi3.0 a special case

+

+Arguments:

+  Port              - Which port to read from.

+

+Returns:

+  Results           - The data read from the port.

+

+--*/

+// TODO:    AdapterInfo - add argument and description to function comment

+{

+  UINT32  Results;

+

+  (*AdapterInfo->Mem_Io) (

+    AdapterInfo->Unique_ID,

+    PXE_MEM_READ,

+    4,

+    (UINT64)Port,

+    (UINT64)(UINTN)&Results

+    );

+  return Results;

+}

+

+VOID

+OutByte (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT8             Data,

+  IN UINT32            Port

+  )

+/*++

+

+Routine Description:

+  This function calls the MemIo callback to write a byte from the device's

+  address space

+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)

+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 

+  to make undi3.0 a special case

+

+Arguments:

+  Data              - Data to write to Port.

+  Port              - Which port to write to.

+

+Returns:

+  none

+

+--*/

+// TODO:    AdapterInfo - add argument and description to function comment

+{

+  UINT8 Val;

+

+  Val = Data;

+  (*AdapterInfo->Mem_Io) (

+     AdapterInfo->Unique_ID,

+     PXE_MEM_WRITE,

+     1,

+     (UINT64)Port,

+     (UINT64)(UINTN)(UINTN)&Val

+     );

+  return ;

+}

+

+VOID

+OutWord (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT16            Data,

+  IN UINT32            Port

+  )

+/*++

+

+Routine Description:

+  This function calls the MemIo callback to write a word from the device's

+  address space

+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)

+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 

+  to make undi3.0 a special case

+

+Arguments:

+  Data              - Data to write to Port.

+  Port              - Which port to write to.

+

+Returns:

+  none

+

+--*/

+// TODO:    AdapterInfo - add argument and description to function comment

+{

+  UINT16  Val;

+

+  Val = Data;

+  (*AdapterInfo->Mem_Io) (

+     AdapterInfo->Unique_ID,

+     PXE_MEM_WRITE,

+     2,

+     (UINT64)Port,

+     (UINT64)(UINTN)&Val

+     );

+  return ;

+}

+

+VOID

+OutLong (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT32            Data,

+  IN UINT32            Port

+  )

+/*++

+

+Routine Description:

+  This function calls the MemIo callback to write a dword from the device's

+  address space

+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)

+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 

+  to make undi3.0 a special case

+

+Arguments:

+  Data              - Data to write to Port.

+  Port              - Which port to write to.

+

+Returns:

+  none

+

+--*/

+// TODO:    AdapterInfo - add argument and description to function comment

+{

+  UINT32  Val;

+

+  Val = Data;

+  (*AdapterInfo->Mem_Io) (

+     AdapterInfo->Unique_ID,

+     PXE_MEM_WRITE,

+     4,

+     (UINT64)Port,

+     (UINT64)(UINTN)&Val

+     );

+  return ;

+}

+

+UINTN

+MapIt (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT64            MemAddr,

+  IN UINT32            Size,

+  IN UINT32            Direction,

+  OUT UINT64           MappedAddr

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  MemAddr     - TODO: add argument description

+  Size        - TODO: add argument description

+  Direction   - TODO: add argument description

+  MappedAddr  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT64  *PhyAddr;

+

+  PhyAddr = (UINT64 *) (UINTN) MappedAddr;

+  //

+  // mapping is different for theold and new NII protocols

+  //

+  if (AdapterInfo->VersionFlag == 0x30) {

+    if (AdapterInfo->Virt2Phys_30 == (VOID *) NULL) {

+      *PhyAddr = (UINT64) AdapterInfo->MemoryPtr;

+    } else {

+      (*AdapterInfo->Virt2Phys_30) (MemAddr, (UINT64) (UINTN) PhyAddr);

+    }

+

+    if (*PhyAddr > FOUR_GIGABYTE) {

+      return PXE_STATCODE_INVALID_PARAMETER;

+    }

+  } else {

+    if (AdapterInfo->Map_Mem == (VOID *) NULL) {

+      //

+      // this UNDI cannot handle addresses beyond 4 GB without a map routine

+      //

+      if (MemAddr > FOUR_GIGABYTE) {

+        return PXE_STATCODE_INVALID_PARAMETER;

+      } else {

+        *PhyAddr = MemAddr;

+      }

+    } else {

+      (*AdapterInfo->Map_Mem) (

+        AdapterInfo->Unique_ID,

+        MemAddr,

+        Size,

+        Direction,

+        MappedAddr

+        );

+    }

+  }

+

+  return PXE_STATCODE_SUCCESS;

+}

+

+VOID

+UnMapIt (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT64            MemAddr,

+  IN UINT32            Size,

+  IN UINT32            Direction,

+  IN UINT64            MappedAddr

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  MemAddr     - TODO: add argument description

+  Size        - TODO: add argument description

+  Direction   - TODO: add argument description

+  MappedAddr  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  if (AdapterInfo->VersionFlag > 0x30) {

+    //

+    // no mapping service

+    //

+    if (AdapterInfo->UnMap_Mem != (VOID *) NULL) {

+      (*AdapterInfo->UnMap_Mem) (

+        AdapterInfo->Unique_ID,

+        MemAddr,

+        Size,

+        Direction,

+        MappedAddr

+        );

+

+    }

+  }

+

+  return ;

+}

+

+VOID

+DelayIt (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  UINT16               MicroSeconds

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+

+Returns:

+

+--*/

+// TODO:    MicroSeconds - add argument and description to function comment

+{

+  if (AdapterInfo->VersionFlag == 0x30) {

+    (*AdapterInfo->Delay_30) (MicroSeconds);

+  } else {

+    (*AdapterInfo->Delay) (AdapterInfo->Unique_ID, MicroSeconds);

+  }

+}

+

+VOID

+BlockIt (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  UINT32               flag

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+

+Returns:

+

+--*/

+// TODO:    flag - add argument and description to function comment

+{

+  if (AdapterInfo->VersionFlag == 0x30) {

+    (*AdapterInfo->Block_30) (flag);

+  } else {

+    (*AdapterInfo->Block) (AdapterInfo->Unique_ID, flag);

+  }

+}

+

+UINT8

+Load_Base_Regs (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // we will use the linear (flat) memory model and fill our base registers

+  // with 0's so that the entire physical address is our offset

+  //

+  //

+  // we reset the statistics totals here because this is where we are loading stats addr

+  //

+  AdapterInfo->RxTotals = 0;

+  AdapterInfo->TxTotals = 0;

+

+  //

+  // Load the statistics block address.

+  //

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+  OutLong (AdapterInfo, (UINT32) AdapterInfo->stat_phy_addr, AdapterInfo->ioaddr + SCBPointer);

+  OutByte (AdapterInfo, CU_STATSADDR, AdapterInfo->ioaddr + SCBCmd);

+  AdapterInfo->statistics->done_marker = 0;

+

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);

+  OutByte (AdapterInfo, RX_ADDR_LOAD, AdapterInfo->ioaddr + SCBCmd);

+

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);

+  OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);

+

+  return 0;

+}

+

+UINT8

+IssueCB (

+  NIC_DATA_INSTANCE *AdapterInfo,

+  TxCB              *cmd_ptr

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  cmd_ptr     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT16  status;

+

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+  //

+  // read the CU status, if it is idle, write the address of cb_ptr

+  // in the scbpointer and issue a cu_start,

+  // if it is suspended, remove the suspend bit in the previous command

+  // block and issue a resume

+  //

+  // Ensure that the CU Active Status bit is not on from previous CBs.

+  //

+  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);

+

+  //

+  // Skip acknowledging the interrupt if it is not already set

+  //

+

+  //

+  // ack only the cna the integer

+  //

+  if ((status & SCB_STATUS_CNA) != 0) {

+    OutWord (AdapterInfo, SCB_STATUS_CNA, AdapterInfo->ioaddr + SCBStatus);

+

+  }

+

+  if ((status & SCB_STATUS_CU_MASK) == SCB_STATUS_CU_IDLE) {

+    //

+    // give a cu_start

+    //

+    OutLong (AdapterInfo, cmd_ptr->PhysTCBAddress, AdapterInfo->ioaddr + SCBPointer);

+    OutByte (AdapterInfo, CU_START, AdapterInfo->ioaddr + SCBCmd);

+  } else {

+    //

+    // either active or suspended, give a resume

+    //

+

+    cmd_ptr->PrevTCBVirtualLinkPtr->cb_header.command &= ~(CmdSuspend | CmdIntr);

+    OutByte (AdapterInfo, CU_RESUME, AdapterInfo->ioaddr + SCBCmd);

+  }

+

+  return 0;

+}

+

+UINT8

+Configure (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // all command blocks are of TxCB format

+  //

+  TxCB  *cmd_ptr;

+  UINT8 *data_ptr;

+  INT16 Index;

+  UINT8 my_filter;

+

+  cmd_ptr   = GetFreeCB (AdapterInfo);

+  data_ptr  = (UINT8 *) (&cmd_ptr->PhysTBDArrayAddres);

+

+  //

+  // start the config data right after the command header

+  //

+  for (Index = 0; Index < sizeof (basic_config_cmd); Index++) {

+    data_ptr[Index] = basic_config_cmd[Index];

+  }

+

+  my_filter = (UINT8) ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS) ? 1 : 0);

+  my_filter |= (AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST) ? 0 : 2;

+

+  data_ptr[15] |= my_filter;

+  data_ptr[19]  = (UINT8) (AdapterInfo->Duplex ? 0xC0 : 0x80);

+  data_ptr[21]  = (UINT8) ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) ? 0x0D : 0x05);

+

+  //

+  // check if we have to use the AUI port instead

+  //

+  if ((AdapterInfo->PhyRecord[0] & 0x8000) != 0) {

+    data_ptr[15] |= 0x80;

+    data_ptr[8] = 0;

+  }

+

+  BlockIt (AdapterInfo, TRUE);

+  cmd_ptr->cb_header.command = CmdSuspend | CmdConfigure;

+

+  IssueCB (AdapterInfo, cmd_ptr);

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+  BlockIt (AdapterInfo, FALSE);

+

+  CommandWaitForCompletion (cmd_ptr, AdapterInfo);

+

+  //

+  // restore the cb values for tx

+  //

+  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;

+  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;

+  //

+  // fields beyond the immediatedata are assumed to be safe

+  // add the CB to the free list again

+  //

+  SetFreeCB (AdapterInfo, cmd_ptr);

+  return 0;

+}

+

+UINT8

+E100bSetupIAAddr (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // all command blocks are of TxCB format

+  //

+  TxCB    *cmd_ptr;

+  UINT16  *data_ptr;

+  UINT16  *eaddrs;

+

+  eaddrs    = (UINT16 *) AdapterInfo->CurrentNodeAddress;

+

+  cmd_ptr   = GetFreeCB (AdapterInfo);

+  data_ptr  = (UINT16 *) (&cmd_ptr->PhysTBDArrayAddres);

+

+  //

+  // AVOID a bug (?!) here by marking the command already completed.

+  //

+  cmd_ptr->cb_header.command  = (CmdSuspend | CmdIASetup);

+  cmd_ptr->cb_header.status   = 0;

+  data_ptr[0]                 = eaddrs[0];

+  data_ptr[1]                 = eaddrs[1];

+  data_ptr[2]                 = eaddrs[2];

+

+  BlockIt (AdapterInfo, TRUE);

+  IssueCB (AdapterInfo, cmd_ptr);

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+  BlockIt (AdapterInfo, FALSE);

+

+  CommandWaitForCompletion (cmd_ptr, AdapterInfo);

+

+  //

+  // restore the cb values for tx

+  //

+  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;

+  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;

+  //

+  // fields beyond the immediatedata are assumed to be safe

+  // add the CB to the free list again

+  //

+  SetFreeCB (AdapterInfo, cmd_ptr);

+  return 0;

+}

+

+VOID

+StopRU (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  Instructs the NIC to stop receiving packets.

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+Returns:

+

+--*/

+{

+  if (AdapterInfo->Receive_Started) {

+

+    //

+    // Todo: verify that we must wait for previous command completion.

+    //

+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+    //

+    // Disable interrupts, and stop the chip's Rx process.

+    //

+    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

+    OutWord (AdapterInfo, INT_MASK | RX_ABORT, AdapterInfo->ioaddr + SCBCmd);

+

+    AdapterInfo->Receive_Started = FALSE;

+  }

+

+  return ;

+}

+

+INT8

+StartRU (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  Instructs the NIC to start receiving packets.

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+Returns:

+  0                               - Successful

+  -1                              - Already Started

+--*/

+{

+

+  if (AdapterInfo->Receive_Started) {

+    //

+    // already started

+    //

+    return -1;

+  }

+

+  AdapterInfo->cur_rx_ind = 0;

+  AdapterInfo->Int_Status = 0;

+

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+  OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo->ioaddr + SCBPointer);

+  OutByte (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);

+

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+  AdapterInfo->Receive_Started = TRUE;

+  return 0;

+}

+

+UINTN

+E100bInit (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  Configures the chip.  This routine expects the NIC_DATA_INSTANCE structure to be filled in.

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+

+Returns:

+  0                               - Successful

+  PXE_STATCODE_NOT_ENOUGH_MEMORY  - Insufficient length of locked memory

+  other                           - Failure initializing chip

+--*/

+{

+  PCI_CONFIG_HEADER *CfgHdr;

+  UINTN             stat;

+  UINTN             rx_size;

+  UINTN             tx_size;

+

+  if (AdapterInfo->MemoryLength < MEMORY_NEEDED) {

+    return PXE_STATCODE_NOT_ENOUGH_MEMORY;

+  }

+

+  stat = MapIt (

+          AdapterInfo,

+          AdapterInfo->MemoryPtr,

+          AdapterInfo->MemoryLength,

+          TO_AND_FROM_DEVICE,

+          (UINT64)(UINTN) &AdapterInfo->Mapped_MemoryPtr

+          );

+

+  if (stat != 0) {

+    return stat;

+  }

+

+  CfgHdr = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);

+

+  //

+  // fill in the ioaddr, int... from the config space

+  //

+  AdapterInfo->int_num = CfgHdr->int_line;

+

+  //

+  // we don't need to validate integer number, what if they don't want to assign one?

+  // if (AdapterInfo->int_num == 0 || AdapterInfo->int_num == 0xff)

+  // return PXE_STATCODE_DEVICE_FAILURE;

+  //

+  AdapterInfo->ioaddr       = 0;

+  AdapterInfo->VendorID     = CfgHdr->VendorID;

+  AdapterInfo->DeviceID     = CfgHdr->DeviceID;

+  AdapterInfo->RevID        = CfgHdr->RevID;

+  AdapterInfo->SubVendorID  = CfgHdr->SubVendorID;

+  AdapterInfo->SubSystemID  = CfgHdr->SubSystemID;

+  AdapterInfo->flash_addr   = 0;

+

+  //

+  // Read the station address EEPROM before doing the reset.

+  // Perhaps this should even be done before accepting the device,

+  // then we wouldn't have a device name with which to report the error.

+  //

+  if (E100bReadEepromAndStationAddress (AdapterInfo) != 0) {

+    return PXE_STATCODE_DEVICE_FAILURE;

+

+  }

+  //

+  // ## calculate the buffer #s depending on memory given

+  // ## calculate the rx and tx ring pointers

+  //

+

+  AdapterInfo->TxBufCnt       = TX_BUFFER_COUNT;

+  AdapterInfo->RxBufCnt       = RX_BUFFER_COUNT;

+  rx_size                     = (AdapterInfo->RxBufCnt * sizeof (RxFD));

+  tx_size                     = (AdapterInfo->TxBufCnt * sizeof (TxCB));

+  AdapterInfo->rx_ring        = (RxFD *) (UINTN) (AdapterInfo->MemoryPtr);

+  AdapterInfo->tx_ring        = (TxCB *) (UINTN) (AdapterInfo->MemoryPtr + rx_size);

+  AdapterInfo->statistics     = (struct speedo_stats *) (UINTN) (AdapterInfo->MemoryPtr + rx_size + tx_size);

+

+  AdapterInfo->rx_phy_addr    = AdapterInfo->Mapped_MemoryPtr;

+  AdapterInfo->tx_phy_addr    = AdapterInfo->Mapped_MemoryPtr + rx_size;

+  AdapterInfo->stat_phy_addr  = AdapterInfo->tx_phy_addr + tx_size;

+  

+  //

+  // auto detect.

+  //

+  AdapterInfo->PhyAddress     = 0xFF;

+  AdapterInfo->Rx_Filter            = PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;

+  AdapterInfo->Receive_Started      = FALSE;

+  AdapterInfo->mcast_list.list_len  = 0;

+  return InitializeChip (AdapterInfo);

+}

+

+UINT8

+E100bSetInterruptState (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  Sets the interrupt state for the NIC.

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+Returns:

+  0                               - Successful

+--*/

+{

+  //

+  // don't set receive interrupt if receiver is disabled...

+  //

+  UINT16  cmd_word;

+

+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {

+    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);

+    cmd_word &= ~INT_MASK;

+    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);

+  } else {

+    //

+    // disable ints, should not be given for SW Int.

+    //

+    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

+  }

+

+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_SOFTWARE) != 0) {

+    //

+    // reset the bit in our mask, it is only one time!!

+    //

+    AdapterInfo->int_mask &= ~(PXE_OPFLAGS_INTERRUPT_SOFTWARE);

+    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);

+    cmd_word |= DRVR_INT;

+    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);

+  }

+

+  return 0;

+}

+//

+// we are not going to disable broadcast for the WOL's sake!

+//

+UINTN

+E100bSetfilter (

+  NIC_DATA_INSTANCE *AdapterInfo,

+  UINT16            new_filter,

+  UINT64            cpb,

+  UINT32            cpbsize

+  )

+/*++

+

+Routine Description:

+  Instructs the NIC to start receiving packets.

+

+Arguments:

+  AdapterInfo                     - Pointer to the NIC data structure information

+                                    which the UNDI driver is layering on..

+  new_filter                      -

+  cpb                             -

+  cpbsize                         -

+

+Returns:

+  0                               - Successful

+  -1                              - Already Started

+--*/

+{

+  PXE_CPB_RECEIVE_FILTERS *mc_list = (PXE_CPB_RECEIVE_FILTERS *) (UINTN)cpb;

+  UINT16                  cfg_flt;

+  UINT16                  old_filter;

+  UINT16                  Index;

+  UINT16                  Index2;

+  UINT16                  mc_count;

+  TxCB                    *cmd_ptr;

+  struct MC_CB_STRUCT     *data_ptr;

+  UINT16                  mc_byte_cnt;

+

+  old_filter  = AdapterInfo->Rx_Filter;

+

+  //

+  // only these bits need a change in the configuration

+  // actually change in bcast requires configure but we ignore that change

+  //

+  cfg_flt = PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS |

+            PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;

+

+  if ((old_filter & cfg_flt) != (new_filter & cfg_flt)) {

+    XmitWaitForCompletion (AdapterInfo);

+

+    if (AdapterInfo->Receive_Started) {

+      StopRU (AdapterInfo);

+    }

+

+    AdapterInfo->Rx_Filter = (UINT8) (new_filter | PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST);

+    Configure (AdapterInfo);

+  }

+

+  //

+  // check if mcast setting changed

+  //

+  if ( ((new_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) !=

+       (old_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) ) ||

+       (mc_list != NULL) ) {

+

+

+    if (mc_list != NULL) {

+      mc_count = AdapterInfo->mcast_list.list_len = (UINT16) (cpbsize / PXE_MAC_LENGTH);

+

+      for (Index = 0; (Index < mc_count && Index < MAX_MCAST_ADDRESS_CNT); Index++) {

+        for (Index2 = 0; Index2 < PXE_MAC_LENGTH; Index2++) {

+          AdapterInfo->mcast_list.mc_list[Index][Index2] = mc_list->MCastList[Index][Index2];

+        }

+      }

+    }

+

+    //

+    // are we setting the list or resetting??

+    //

+    if ((new_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {

+      //

+      // we are setting a new list!

+      //

+      mc_count = AdapterInfo->mcast_list.list_len;

+      //

+      // count should be the actual # of bytes in the list

+      // so multiply this with 6

+      //

+      mc_byte_cnt = (UINT16) ((mc_count << 2) + (mc_count << 1));

+      AdapterInfo->Rx_Filter |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;

+    } else {

+      //

+      // disabling the list in the NIC.

+      //

+      mc_byte_cnt = mc_count = 0;

+      AdapterInfo->Rx_Filter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);

+    }

+

+    //

+    // before issuing any new command!

+    //

+    XmitWaitForCompletion (AdapterInfo);

+

+    if (AdapterInfo->Receive_Started) {

+      StopRU (AdapterInfo);

+

+    }

+

+    cmd_ptr = GetFreeCB (AdapterInfo);

+    if (cmd_ptr == NULL) {

+      return PXE_STATCODE_QUEUE_FULL;

+    }

+    //

+    // fill the command structure and issue

+    //

+    data_ptr = (struct MC_CB_STRUCT *) (&cmd_ptr->PhysTBDArrayAddres);

+    //

+    // first 2 bytes are the count;

+    //

+    data_ptr->count = mc_byte_cnt;

+    for (Index = 0; Index < mc_count; Index++) {

+      for (Index2 = 0; Index2 < PXE_HWADDR_LEN_ETHER; Index2++) {

+        data_ptr->m_list[Index][Index2] = AdapterInfo->mcast_list.mc_list[Index][Index2];

+      }

+    }

+

+    cmd_ptr->cb_header.command  = CmdSuspend | CmdMulticastList;

+    cmd_ptr->cb_header.status   = 0;

+

+    BlockIt (AdapterInfo, TRUE);

+    IssueCB (AdapterInfo, cmd_ptr);

+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+    BlockIt (AdapterInfo, FALSE);

+

+    CommandWaitForCompletion (cmd_ptr, AdapterInfo);

+

+    cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;

+    cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;

+    //

+    // fields beyond the immediatedata are assumed to be safe

+    // add the CB to the free list again

+    //

+    SetFreeCB (AdapterInfo, cmd_ptr);

+  }

+

+  if (new_filter != 0) {

+    //

+    // enable unicast and start the RU

+    //

+    AdapterInfo->Rx_Filter |= (new_filter | PXE_OPFLAGS_RECEIVE_FILTER_UNICAST);

+    StartRU (AdapterInfo);

+  } else {

+    //

+    // may be disabling everything!

+    //

+    if (AdapterInfo->Receive_Started) {

+      StopRU (AdapterInfo);

+    }

+

+    AdapterInfo->Rx_Filter |= (~PXE_OPFLAGS_RECEIVE_FILTER_UNICAST);

+  }

+

+  return 0;

+}

+

+UINTN

+E100bTransmit (

+  NIC_DATA_INSTANCE *AdapterInfo,

+  UINT64            cpb,

+  UINT16            opflags

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  cpb         - TODO: add argument description

+  opflags     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  PXE_CPB_TRANSMIT_FRAGMENTS  *tx_ptr_f;

+  PXE_CPB_TRANSMIT            *tx_ptr_1;

+  TxCB                        *tcb_ptr;

+  UINT64                      Tmp_ptr;

+  UINTN                       stat;

+  INT32                       Index;

+  UINT16                      wait_sec;

+

+  tx_ptr_1  = (PXE_CPB_TRANSMIT *) (UINTN) cpb;

+  tx_ptr_f  = (PXE_CPB_TRANSMIT_FRAGMENTS *) (UINTN) cpb;

+

+  //

+  // stop reentrancy here

+  //

+  if (AdapterInfo->in_transmit) {

+    return PXE_STATCODE_BUSY;

+

+  }

+

+  AdapterInfo->in_transmit = TRUE;

+

+  //

+  // Prevent interrupts from changing the Tx ring from underneath us.

+  //

+  // Calculate the Tx descriptor entry.

+  //

+  if ((tcb_ptr = GetFreeCB (AdapterInfo)) == NULL) {

+    AdapterInfo->in_transmit = FALSE;

+    return PXE_STATCODE_QUEUE_FULL;

+  }

+

+  AdapterInfo->TxTotals++;

+

+  tcb_ptr->cb_header.command  = (CmdSuspend | CmdTx | CmdTxFlex);

+  tcb_ptr->cb_header.status   = 0;

+

+  //

+  // no immediate data, set EOF in the ByteCount

+  //

+  tcb_ptr->ByteCount = 0x8000;

+

+  //

+  // The data region is always in one buffer descriptor, Tx FIFO

+  // threshold of 256.

+  // 82557 multiplies the threashold value by 8, so give 256/8

+  //

+  tcb_ptr->Threshold = 32;

+  if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {

+

+    if (tx_ptr_f->FragCnt > MAX_XMIT_FRAGMENTS) {

+      SetFreeCB (AdapterInfo, tcb_ptr);

+      AdapterInfo->in_transmit = FALSE;

+      return PXE_STATCODE_INVALID_PARAMETER;

+    }

+

+    tcb_ptr->TBDCount = (UINT8) tx_ptr_f->FragCnt;

+

+    for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {

+      stat = MapIt (

+              AdapterInfo,

+              tx_ptr_f->FragDesc[Index].FragAddr,

+              tx_ptr_f->FragDesc[Index].FragLen,

+              TO_DEVICE,

+              (UINT64)(UINTN) &Tmp_ptr

+              );

+      if (stat != 0) {

+        SetFreeCB (AdapterInfo, tcb_ptr);

+        AdapterInfo->in_transmit = FALSE;

+        return PXE_STATCODE_INVALID_PARAMETER;

+      }

+

+      tcb_ptr->TBDArray[Index].phys_buf_addr  = (UINT32) Tmp_ptr;

+      tcb_ptr->TBDArray[Index].buf_len        = tx_ptr_f->FragDesc[Index].FragLen;

+    }

+

+    tcb_ptr->free_data_ptr = tx_ptr_f->FragDesc[0].FragAddr;

+

+  } else {

+    //

+    // non fragmented case

+    //

+    tcb_ptr->TBDCount = 1;

+    stat = MapIt (

+            AdapterInfo,

+            tx_ptr_1->FrameAddr,

+            tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,

+            TO_DEVICE,

+            (UINT64)(UINTN) &Tmp_ptr

+            );

+    if (stat != 0) {

+      SetFreeCB (AdapterInfo, tcb_ptr);

+      AdapterInfo->in_transmit = FALSE;

+      return PXE_STATCODE_INVALID_PARAMETER;

+    }

+

+    tcb_ptr->TBDArray[0].phys_buf_addr  = (UINT32) (Tmp_ptr);

+    tcb_ptr->TBDArray[0].buf_len        = tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen;

+    tcb_ptr->free_data_ptr              = tx_ptr_1->FrameAddr;

+  }

+

+  //

+  // must wait for previous command completion only if it was a non-transmit

+  //

+  BlockIt (AdapterInfo, TRUE);

+  IssueCB (AdapterInfo, tcb_ptr);

+  BlockIt (AdapterInfo, FALSE);

+

+  //

+  // see if we need to wait for completion here

+  //

+  if ((opflags & PXE_OPFLAGS_TRANSMIT_BLOCK) != 0) {

+    //

+    // don't wait for more than 1 second!!!

+    //

+    wait_sec = 1000;

+    while (tcb_ptr->cb_header.status == 0) {

+      DelayIt (AdapterInfo, 10);

+      wait_sec--;

+      if (wait_sec == 0) {

+        break;

+      }

+    }

+    //

+    // we need to un-map any mapped buffers here

+    //

+    if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {

+

+      for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {

+        Tmp_ptr = tcb_ptr->TBDArray[Index].phys_buf_addr;

+        UnMapIt (

+          AdapterInfo,

+          tx_ptr_f->FragDesc[Index].FragAddr,

+          tx_ptr_f->FragDesc[Index].FragLen,

+          TO_DEVICE,

+          (UINT64) Tmp_ptr

+          );

+      }

+    } else {

+      Tmp_ptr = tcb_ptr->TBDArray[0].phys_buf_addr;

+      UnMapIt (

+        AdapterInfo,

+        tx_ptr_1->FrameAddr,

+        tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,

+        TO_DEVICE,

+        (UINT64) Tmp_ptr

+        );

+    }

+

+    if (tcb_ptr->cb_header.status == 0) {

+      SetFreeCB (AdapterInfo, tcb_ptr);

+      AdapterInfo->in_transmit = FALSE;

+      return PXE_STATCODE_DEVICE_FAILURE;

+    }

+

+    SetFreeCB (AdapterInfo, tcb_ptr);

+  }

+  //

+  // CB will be set free later in get_status (or when we run out of xmit buffers

+  //

+  AdapterInfo->in_transmit = FALSE;

+

+  return 0;

+}

+

+UINTN

+E100bReceive (

+  NIC_DATA_INSTANCE *AdapterInfo,

+  UINT64            cpb,

+  UINT64            db

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  cpb         - TODO: add argument description

+  db          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  PXE_CPB_RECEIVE *rx_cpbptr;

+  PXE_DB_RECEIVE  *rx_dbptr;

+  RxFD            *rx_ptr;

+  INT32           status;

+  INT32           Index;

+  UINT16          pkt_len;

+  UINT16          ret_code;

+  PXE_FRAME_TYPE  pkt_type;

+  UINT16          Tmp_len;

+  EtherHeader     *hdr_ptr;

+  ret_code  = PXE_STATCODE_NO_DATA;

+  pkt_type  = PXE_FRAME_TYPE_NONE;

+  status    = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);

+  AdapterInfo->Int_Status |= status;

+  //

+  // acknoledge the interrupts

+  //

+  OutWord (AdapterInfo, (UINT16) (status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus));

+

+  //

+  // include the prev ints as well

+  //

+  status = AdapterInfo->Int_Status;

+  rx_cpbptr = (PXE_CPB_RECEIVE *) (UINTN) cpb;

+  rx_dbptr  = (PXE_DB_RECEIVE *) (UINTN) db;

+

+  rx_ptr    = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];

+

+  //

+  // be in a loop just in case (we may drop a pkt)

+  //

+  while ((status = rx_ptr->cb_header.status) & RX_COMPLETE) {

+

+    AdapterInfo->RxTotals++;

+    //

+    // If we own the next entry, it's a new packet. Send it up.

+    //

+    if (rx_ptr->forwarded) {

+      goto FreeRFD;

+

+    }

+

+    //

+    // discard bad frames

+    //

+

+    //

+    // crc, align, dma overrun, too short, receive error (v22 no coll)

+    //

+    if ((status & 0x0D90) != 0) {

+      goto FreeRFD;

+

+    }

+

+    //

+    // make sure the status is OK

+    //

+    if ((status & 0x02000) == 0) {

+      goto FreeRFD;

+    }

+

+    pkt_len = (UINT16) (rx_ptr->ActualCount & 0x3fff);

+

+    if (pkt_len != 0) {

+

+      Tmp_len = pkt_len;

+      if (pkt_len > rx_cpbptr->BufferLen) {

+        Tmp_len = (UINT16) rx_cpbptr->BufferLen;

+      }

+

+      CopyMem ((INT8 *) (UINTN) rx_cpbptr->BufferAddr, (INT8 *) &rx_ptr->RFDBuffer, Tmp_len);

+

+      hdr_ptr = (EtherHeader *) &rx_ptr->RFDBuffer;

+      //

+      // fill the CDB and break the loop

+      //

+

+      //

+      // includes header

+      //

+      rx_dbptr->FrameLen = pkt_len;

+      rx_dbptr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;

+

+      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+        if (hdr_ptr->dest_addr[Index] != AdapterInfo->CurrentNodeAddress[Index]) {

+          break;

+        }

+      }

+

+      if (Index >= PXE_HWADDR_LEN_ETHER) {

+        pkt_type = PXE_FRAME_TYPE_UNICAST;

+      } else {

+        for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+          if (hdr_ptr->dest_addr[Index] != AdapterInfo->BroadcastNodeAddress[Index]) {

+            break;

+          }

+        }

+

+        if (Index >= PXE_HWADDR_LEN_ETHER) {

+          pkt_type = PXE_FRAME_TYPE_BROADCAST;

+        } else {

+          if ((hdr_ptr->dest_addr[0] & 1) == 1) {

+            //

+            // mcast

+            //

+

+            pkt_type = PXE_FRAME_TYPE_MULTICAST;

+          } else {

+            pkt_type = PXE_FRAME_TYPE_PROMISCUOUS;

+          }

+        }

+      }

+

+      rx_dbptr->Type      = pkt_type;

+      rx_dbptr->Protocol  = hdr_ptr->type;

+

+      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+        rx_dbptr->SrcAddr[Index]  = hdr_ptr->src_addr[Index];

+        rx_dbptr->DestAddr[Index] = hdr_ptr->dest_addr[Index];

+      }

+

+      rx_ptr->forwarded = TRUE;

+      //

+      // success

+      //

+      ret_code          = 0;

+      Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);

+      AdapterInfo->cur_rx_ind++;

+      if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {

+        AdapterInfo->cur_rx_ind = 0;

+      }

+      break;

+    }

+

+FreeRFD:

+    Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);

+    AdapterInfo->cur_rx_ind++;

+    if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {

+      AdapterInfo->cur_rx_ind = 0;

+    }

+

+    rx_ptr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];

+  }

+

+  if (pkt_type == PXE_FRAME_TYPE_NONE) {

+    AdapterInfo->Int_Status &= (~SCB_STATUS_FR);

+  }

+

+  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);

+  if ((status & SCB_RUS_NO_RESOURCES) != 0) {

+    //

+    // start the receive unit here!

+    // leave all the filled frames,

+    //

+    SetupReceiveQueues (AdapterInfo);

+    OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo->ioaddr + SCBPointer);

+    OutWord (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);

+    AdapterInfo->cur_rx_ind = 0;

+  }

+

+  return ret_code;

+}

+

+INT16

+E100bReadEepromAndStationAddress (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  INT32   Index;

+  INT32   Index2;

+  UINT16  sum;

+  UINT16  eeprom_len;

+  UINT8   addr_len;

+  UINT16  *eedata;

+

+  eedata    = (UINT16 *) (&AdapterInfo->NVData[0]);

+

+  sum       = 0;

+  addr_len  = E100bGetEepromAddrLen (AdapterInfo);

+

+  //

+  // in words

+  //

+  AdapterInfo->NVData_Len = eeprom_len = (UINT16) (1 << addr_len);

+  for (Index2 = 0, Index = 0; Index < eeprom_len; Index++) {

+    UINT16  value;

+    value         = E100bReadEeprom (AdapterInfo, Index, addr_len);

+    eedata[Index] = value;

+    sum           = (UINT16) (sum + value);

+    if (Index < 3) {

+      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) value;

+      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) (value >> 8);

+    }

+  }

+

+  if (sum != 0xBABA) {

+    return -1;

+  }

+

+  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+    AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo->PermNodeAddress[Index];

+  }

+

+  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {

+    AdapterInfo->BroadcastNodeAddress[Index] = 0xff;

+  }

+

+  for (Index = PXE_HWADDR_LEN_ETHER; Index < PXE_MAC_LENGTH; Index++) {

+    AdapterInfo->CurrentNodeAddress[Index]    = 0;

+    AdapterInfo->PermNodeAddress[Index]       = 0;

+    AdapterInfo->BroadcastNodeAddress[Index]  = 0;

+  }

+

+  return 0;

+}

+

+//

+//  CBList is a circular linked list

+//  1) When all are free, Tail->next == Head and FreeCount == # allocated

+//  2) When none are free, Tail == Head and FreeCount == 0

+//  3) when one is free, Tail == Head and Freecount == 1

+//  4) First non-Free frame is always at Tail->next

+//

+UINT8

+SetupCBlink (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  TxCB  *head_ptr;

+  TxCB  *tail_ptr;

+  TxCB  *cur_ptr;

+  INT32 Index;

+  UINTN array_off;

+

+  cur_ptr   = &(AdapterInfo->tx_ring[0]);

+  array_off = (UINTN) (&cur_ptr->TBDArray) - (UINTN) cur_ptr;

+  for (Index = 0; Index < AdapterInfo->TxBufCnt; Index++) {

+    cur_ptr[Index].cb_header.status   = 0;

+    cur_ptr[Index].cb_header.command  = 0;

+

+    cur_ptr[Index].PhysTCBAddress     =

+    (UINT32) AdapterInfo->tx_phy_addr + (Index * sizeof (TxCB));

+

+    cur_ptr[Index].PhysArrayAddr      = (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);  

+    cur_ptr[Index].PhysTBDArrayAddres = (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);

+

+    cur_ptr->free_data_ptr = (UINT64) 0;

+

+    if (Index < AdapterInfo->TxBufCnt - 1) {

+      cur_ptr[Index].cb_header.link             = cur_ptr[Index].PhysTCBAddress + sizeof (TxCB);

+      cur_ptr[Index].NextTCBVirtualLinkPtr      = &cur_ptr[Index + 1];

+      cur_ptr[Index + 1].PrevTCBVirtualLinkPtr  = &cur_ptr[Index];

+    }

+  }

+

+  head_ptr                        = &cur_ptr[0];

+  tail_ptr                        = &cur_ptr[AdapterInfo->TxBufCnt - 1];

+  tail_ptr->cb_header.link        = head_ptr->PhysTCBAddress;

+  tail_ptr->NextTCBVirtualLinkPtr = head_ptr;

+  head_ptr->PrevTCBVirtualLinkPtr = tail_ptr;

+

+  AdapterInfo->FreeCBCount        = AdapterInfo->TxBufCnt;

+  AdapterInfo->FreeTxHeadPtr      = head_ptr;

+  //

+  // set tail of the free list, next to this would be either in use

+  // or the head itself

+  //

+  AdapterInfo->FreeTxTailPtr  = tail_ptr;

+

+  AdapterInfo->xmit_done_head = AdapterInfo->xmit_done_tail = 0;

+

+  return 0;

+}

+

+TxCB *

+GetFreeCB (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  TxCB  *free_cb_ptr;

+

+  //

+  // claim any hanging free CBs

+  //

+  if (AdapterInfo->FreeCBCount <= 1) {

+    CheckCBList (AdapterInfo);

+  }

+

+  //

+  // don't use up the last CB problem if the previous CB that the CU used

+  // becomes the last CB we submit because of the SUSPEND bit we set.

+  // the CU thinks it was never cleared.

+  //

+

+  if (AdapterInfo->FreeCBCount <= 1) {

+    return NULL;

+  }

+

+  BlockIt (AdapterInfo, TRUE);

+  free_cb_ptr                 = AdapterInfo->FreeTxHeadPtr;

+  AdapterInfo->FreeTxHeadPtr  = free_cb_ptr->NextTCBVirtualLinkPtr;

+  --AdapterInfo->FreeCBCount;

+  BlockIt (AdapterInfo, FALSE);

+  return free_cb_ptr;

+}

+

+VOID

+SetFreeCB (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN TxCB              *cb_ptr

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  cb_ptr      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // here we assume cb are returned in the order they are taken out

+  // and we link the newly freed cb at the tail of free cb list

+  //

+  cb_ptr->cb_header.status    = 0;

+  cb_ptr->free_data_ptr       = (UINT64) 0;

+

+  AdapterInfo->FreeTxTailPtr  = cb_ptr;

+  ++AdapterInfo->FreeCBCount;

+  return ;

+}

+

+UINT16

+next (

+  IN UINT16 ind

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ind - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT16  Tmp;

+

+  Tmp = (UINT16) (ind + 1);

+  if (Tmp >= (TX_BUFFER_COUNT << 1)) {

+    Tmp = 0;

+  }

+

+  return Tmp;

+}

+

+UINT16

+CheckCBList (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  TxCB    *Tmp_ptr;

+  UINT16  cnt;

+

+  cnt = 0;

+  while (1) {

+    Tmp_ptr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;

+    if ((Tmp_ptr->cb_header.status & CMD_STATUS_MASK) != 0) {

+      //

+      // check if Q is full

+      //

+      if (next (AdapterInfo->xmit_done_tail) != AdapterInfo->xmit_done_head) {

+        AdapterInfo->xmit_done[AdapterInfo->xmit_done_tail] = Tmp_ptr->free_data_ptr;

+

+        UnMapIt (

+          AdapterInfo,

+          Tmp_ptr->free_data_ptr,

+          Tmp_ptr->TBDArray[0].buf_len,

+          TO_DEVICE,

+          (UINT64) Tmp_ptr->TBDArray[0].phys_buf_addr

+          );

+

+        AdapterInfo->xmit_done_tail = next (AdapterInfo->xmit_done_tail);

+      }

+

+      SetFreeCB (AdapterInfo, Tmp_ptr);

+    } else {

+      break;

+    }

+  }

+

+  return cnt;

+}

+//

+// Description : Initialize the RFD list list by linking each element together

+//               in a circular list.  The simplified memory model is used.

+//               All data is in the RFD.  The RFDs are linked together and the

+//               last one points back to the first one.  When the current RFD

+//               is processed (frame received), its EL bit is set and the EL

+//               bit in the previous RXFD is cleared.

+//               Allocation done during INIT, this is making linked list.

+//

+UINT8

+SetupReceiveQueues (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  RxFD    *rx_ptr;

+  RxFD    *head_ptr;

+  RxFD    *tail_ptr;

+  UINT16  Index;

+

+  AdapterInfo->cur_rx_ind = 0;

+  rx_ptr                  = (&AdapterInfo->rx_ring[0]);

+

+  for (Index = 0; Index < AdapterInfo->RxBufCnt; Index++) {

+    rx_ptr[Index].cb_header.status  = 0;

+    rx_ptr[Index].cb_header.command = 0;

+    rx_ptr[Index].RFDSize           = RX_BUFFER_SIZE;

+    rx_ptr[Index].ActualCount       = 0;

+    //

+    // RBDs not used, simple memory model

+    //

+    rx_ptr[Index].rx_buf_addr       = (UINT32) (-1);

+

+    //

+    // RBDs not used, simple memory model

+    //

+    rx_ptr[Index].forwarded = FALSE;

+

+    //

+    // don't use Tmp_ptr if it is beyond the last one

+    //

+    if (Index < AdapterInfo->RxBufCnt - 1) {

+      rx_ptr[Index].cb_header.link = (UINT32) AdapterInfo->rx_phy_addr + ((Index + 1) * sizeof (RxFD));

+    }

+  }

+

+  head_ptr                    = (&AdapterInfo->rx_ring[0]);

+  tail_ptr                    = (&AdapterInfo->rx_ring[AdapterInfo->RxBufCnt - 1]);

+  tail_ptr->cb_header.link    = (UINT32) AdapterInfo->rx_phy_addr;

+

+  //

+  // set the EL bit

+  //

+  tail_ptr->cb_header.command = 0xC000;

+  AdapterInfo->RFDTailPtr = tail_ptr;

+  return 0;

+}

+

+VOID

+Recycle_RFD (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT16            rx_index

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  rx_index    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  RxFD  *rx_ptr;

+  RxFD  *tail_ptr;

+  //

+  // change the EL bit and change the AdapterInfo->RxTailPtr

+  // rx_ptr is assumed to be the head of the Q

+  // AdapterInfo->rx_forwarded[rx_index] = FALSE;

+  //

+  rx_ptr                    = &AdapterInfo->rx_ring[rx_index];

+  tail_ptr                  = AdapterInfo->RFDTailPtr;

+  //

+  // set el_bit and suspend bit

+  //

+  rx_ptr->cb_header.command = 0xc000;

+  rx_ptr->cb_header.status    = 0;

+  rx_ptr->ActualCount         = 0;

+  rx_ptr->forwarded           = FALSE;

+  AdapterInfo->RFDTailPtr     = rx_ptr;

+  //

+  // resetting the el_bit.

+  //

+  tail_ptr->cb_header.command = 0;

+  //

+  // check the receive unit, fix if there is any problem

+  //

+  return ;

+}

+//

+// Serial EEPROM section.

+//

+//  EEPROM_Ctrl bits.

+//

+#define EE_SHIFT_CLK  0x01  /* EEPROM shift clock. */

+#define EE_CS         0x02  /* EEPROM chip select. */

+#define EE_DI         0x04  /* EEPROM chip data in. */

+#define EE_WRITE_0    0x01

+#define EE_WRITE_1    0x05

+#define EE_DO         0x08  /* EEPROM chip data out. */

+#define EE_ENB        (0x4800 | EE_CS)

+

+//

+// Delay between EEPROM clock transitions.

+// This will actually work with no delay on 33Mhz PCI.

+//

+#define eeprom_delay(nanosec) DelayIt (AdapterInfo, nanosec);

+

+//

+// The EEPROM commands include the alway-set leading bit.

+//

+#define EE_WRITE_CMD  5 // 101b

+#define EE_READ_CMD   6 // 110b

+#define EE_ERASE_CMD  (7 << 6)

+

+VOID

+shift_bits_out (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT16            val,

+  IN UINT8             num_bits

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  val         - TODO: add argument description

+  num_bits    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  INT32   Index;

+  UINT8   Tmp;

+  UINT32  EEAddr;

+

+  EEAddr = AdapterInfo->ioaddr + SCBeeprom;

+

+  for (Index = num_bits; Index >= 0; Index--) {

+    INT16 dataval;

+

+    //

+    // will be 0 or 4

+    //

+    dataval = (INT16) ((val & (1 << Index)) ? EE_DI : 0);

+

+    //

+    // mask off the data_in bit

+    //

+    Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) &~EE_DI);

+    Tmp |= dataval;

+    OutByte (AdapterInfo, Tmp, EEAddr);

+    eeprom_delay (100);

+    //

+    // raise the eeprom clock

+    //

+    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);

+    eeprom_delay (150);

+    //

+    // lower the eeprom clock

+    //

+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);

+    eeprom_delay (150);

+  }

+}

+

+UINT16

+shift_bits_in (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT8   Tmp;

+  INT32   Index;

+  UINT16  retval;

+  UINT32  EEAddr;

+

+  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;

+

+  retval  = 0;

+  for (Index = 15; Index >= 0; Index--) {

+    //

+    // raise the clock

+    //

+

+    //

+    // mask off the data_in bit

+    //

+    Tmp = InByte (AdapterInfo, EEAddr);

+    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);

+    eeprom_delay (100);

+    Tmp     = InByte (AdapterInfo, EEAddr);

+    retval  = (UINT16) ((retval << 1) | ((Tmp & EE_DO) ? 1 : 0));

+    //

+    // lower the clock

+    //

+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);

+    eeprom_delay (100);

+  }

+

+  return retval;

+}

+

+BOOLEAN

+E100bSetEepromLockOut (

+  IN NIC_DATA_INSTANCE  *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine sets the EEPROM lockout bit to gain exclusive access to the

+  eeprom. the access bit is the most significant bit in the General Control

+  Register 2 in the SCB space.

+

+Arguments:

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  TRUE - if it got the access

+  FALSE - if it fails to get the exclusive access

+

+--*/

+{

+  UINTN wait;

+  UINT8 tmp;

+

+  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) || 

+      (AdapterInfo->RevID >= D102_REVID)) {

+

+    wait = 500;

+

+    while (wait--) {

+

+      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);

+      tmp |= GCR2_EEPROM_ACCESS_SEMAPHORE;

+      OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);

+

+      DelayIt (AdapterInfo, 50);

+      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);

+

+      if (tmp & GCR2_EEPROM_ACCESS_SEMAPHORE) {

+        return TRUE;

+      }

+    }

+

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+VOID

+E100bReSetEepromLockOut (

+  IN NIC_DATA_INSTANCE  *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  This routine Resets the EEPROM lockout bit to giveup access to the

+  eeprom. the access bit is the most significant bit in the General Control

+  Register 2 in the SCB space.

+

+Arguments:

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+ None

+ 

+--*/

+{

+  UINT8 tmp;

+

+  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) || 

+      (AdapterInfo->RevID >= D102_REVID)) {

+

+    tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);

+    tmp &= ~(GCR2_EEPROM_ACCESS_SEMAPHORE);

+    OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);

+

+    DelayIt (AdapterInfo, 50);

+  }

+}

+

+UINT16

+E100bReadEeprom (

+  IN NIC_DATA_INSTANCE  *AdapterInfo,

+  IN INT32              Location,

+  IN UINT8              AddrLen

+  )

+/*++

+

+Routine Description:

+  Using the NIC data structure information, read the EEPROM to get a Word of data for the MAC address.

+

+Arguments:

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+  Location          - Word offset into the MAC address to read.

+  AddrLen           - Number of bits of address length.

+

+Returns:

+  RetVal            - The word read from the EEPROM.

+

+--*/

+{

+  UINT16  RetVal;

+  UINT8   Tmp;

+

+  UINT32  EEAddr;

+  UINT16  ReadCmd;

+

+  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;

+  ReadCmd = (UINT16) (Location | (EE_READ_CMD << AddrLen));

+

+  RetVal  = 0;

+

+  //

+  // get exclusive access to the eeprom first!

+  //

+  E100bSetEepromLockOut (AdapterInfo);

+

+  //

+  // eeprom control reg bits: x,x,x,x,DO,DI,CS,SK

+  // to write the opcode+data value out one bit at a time in DI starting at msb

+  // and then out a 1 to sk, wait, out 0 to SK and wait

+  // repeat this for all the bits to be written

+  //

+

+  //

+  // 11110010b

+  //

+  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);

+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);

+

+  //

+  // 3 for the read opcode 110b

+  //

+  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + AddrLen));

+

+  //

+  // read the eeprom word one bit at a time

+  //

+  RetVal = shift_bits_in (AdapterInfo);

+

+  //

+  // Terminate the EEPROM access and leave eeprom in a clean state.

+  //

+  Tmp = InByte (AdapterInfo, EEAddr);

+  Tmp &= ~(EE_CS | EE_DI);

+  OutByte (AdapterInfo, Tmp, EEAddr);

+

+  //

+  // raise the clock and lower the eeprom shift clock

+  //

+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);

+  eeprom_delay (100);

+

+  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);

+  eeprom_delay (100);

+

+  //

+  // giveup access to the eeprom

+  //

+  E100bReSetEepromLockOut (AdapterInfo);

+

+  return RetVal;

+}

+

+UINT8

+E100bGetEepromAddrLen (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+  Using the NIC data structure information, read the EEPROM to determine how many bits of address length

+  this EEPROM is in Words.

+

+Arguments:

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+  RetVal            - The word read from the EEPROM.

+

+--*/

+{

+  UINT8   Tmp;

+  UINT8   AddrLen;

+  UINT32  EEAddr;

+  //

+  // assume 64word eeprom (so,6 bits of address_length)

+  //

+  UINT16  ReadCmd;

+

+  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;

+  ReadCmd = (EE_READ_CMD << 6);

+

+  //

+  // get exclusive access to the eeprom first!

+  //

+  E100bSetEepromLockOut (AdapterInfo);

+

+  //

+  // address we are trying to read is 0

+  // eeprom control reg bits: x,x,x,x,DO,,DI,,CS,SK

+  // to write the opcode+data value out one bit at a time in DI starting at msb

+  // and then out a 1 to sk, wait, out 0 to SK and wait

+  // repeat this for all the bits to be written

+  //

+  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);

+

+  //

+  // enable eeprom access

+  //

+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);

+

+  //

+  // 3 for opcode, 6 for the default address len

+  //

+  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + 6));

+

+  //

+  // (in case of a 64 word eeprom).

+  // read the "dummy zero" from EE_DO to say that the address we wrote

+  // (six 0s) is accepted, write more zeros (until 8) to get a "dummy zero"

+  //

+

+  //

+  // assume the smallest

+  //

+  AddrLen = 6;

+  Tmp     = InByte (AdapterInfo, EEAddr);

+  while ((AddrLen < 8) && ((Tmp & EE_DO) != 0)) {

+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_DI), EEAddr);

+    eeprom_delay (100);

+

+    //

+    // raise the eeprom clock

+    //

+    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);

+    eeprom_delay (150);

+

+    //

+    // lower the eeprom clock

+    //

+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);

+    eeprom_delay (150);

+    Tmp = InByte (AdapterInfo, EEAddr);

+    AddrLen++;

+  }

+

+  //

+  // read the eeprom word, even though we don't need this

+  //

+  shift_bits_in (AdapterInfo);

+

+  //

+  // Terminate the EEPROM access.

+  //

+  Tmp = InByte (AdapterInfo, EEAddr);

+  Tmp &= ~(EE_CS | EE_DI);

+  OutByte (AdapterInfo, Tmp, EEAddr);

+

+  //

+  // raise the clock and lower the eeprom shift clock

+  //

+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);

+  eeprom_delay (100);

+

+  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);

+  eeprom_delay (100);

+

+  //

+  // giveup access to the eeprom!

+  //

+  E100bReSetEepromLockOut (AdapterInfo);

+

+  return AddrLen;

+}

+

+UINTN

+E100bStatistics (

+  NIC_DATA_INSTANCE *AdapterInfo,

+  UINT64            DBaddr,

+  UINT16            DBsize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  DBaddr      - TODO: add argument description

+  DBsize      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  PXE_DB_STATISTICS db;

+  //

+  // wait upto one second (each wait is 100 micro s)

+  //

+  UINT32            Wait;

+  Wait = 10000;

+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+

+  //

+  // Clear statistics done marker.

+  //

+  AdapterInfo->statistics->done_marker = 0;

+

+  //

+  // Issue statistics dump (or dump w/ reset) command.

+  //

+  OutByte (

+    AdapterInfo,

+    (UINT8) (DBsize ? CU_SHOWSTATS : CU_DUMPSTATS),

+    (UINT32) (AdapterInfo->ioaddr + SCBCmd)

+    );

+

+  //

+  // Wait for command to complete.

+  //

+  // zero the db here just to chew up a little more time.

+  //

+

+  ZeroMem ((VOID *) &db, sizeof db);

+

+  while (Wait != 0) {

+    //

+    // Wait a bit before checking.

+    //

+

+    DelayIt (AdapterInfo, 100);

+

+    //

+    // Look for done marker at end of statistics.

+    //

+

+    switch (AdapterInfo->statistics->done_marker) {

+    case 0xA005:

+    case 0xA007:

+      break;

+

+    default:

+      Wait--;

+      continue;

+    }

+

+    //

+    // if we did not "continue" from the above switch, we are done,

+    //

+    break;

+  }

+

+  //

+  // If this is a reset, we are out of here!

+  //

+  if (DBsize == 0) {

+    return PXE_STATCODE_SUCCESS;

+  }

+

+  //

+  // Convert NIC statistics counter format to EFI/UNDI

+  // specification statistics counter format.

+  //

+

+  //

+  //                54 3210 fedc ba98 7654 3210

+  // db.Supported = 01 0000 0100 1101 0001 0111;

+  //

+  db.Supported = 0x104D17;

+

+  //

+  // Statistics from the NIC

+  //

+

+  db.Data[0x01] = AdapterInfo->statistics->rx_good_frames;

+

+  db.Data[0x02] = AdapterInfo->statistics->rx_runt_errs;

+

+  db.Data[0x08] = AdapterInfo->statistics->rx_crc_errs +

+                  AdapterInfo->statistics->rx_align_errs;

+

+  db.Data[0x04] = db.Data[0x02] + 

+                  db.Data[0x08] +

+                  AdapterInfo->statistics->rx_resource_errs +

+                  AdapterInfo->statistics->rx_overrun_errs;

+

+  db.Data[0x00] = db.Data[0x01] + db.Data[0x04];

+

+  db.Data[0x0B] = AdapterInfo->statistics->tx_good_frames;

+

+  db.Data[0x0E] = AdapterInfo->statistics->tx_coll16_errs +

+    AdapterInfo->statistics->tx_late_colls +

+    AdapterInfo->statistics->tx_underruns +

+    AdapterInfo->statistics->tx_one_colls +

+    AdapterInfo->statistics->tx_multi_colls;

+

+  db.Data[0x14] = AdapterInfo->statistics->tx_total_colls;

+

+  db.Data[0x0A] = db.Data[0x0B] +

+                  db.Data[0x0E] +

+                  AdapterInfo->statistics->tx_lost_carrier;

+

+  if (DBsize > sizeof db) {

+    DBsize = sizeof db;

+  }

+

+  CopyMem ((VOID *) (UINTN) DBaddr, (VOID *) &db, (UINTN) DBsize);

+

+  return PXE_STATCODE_SUCCESS;

+}

+

+UINTN

+E100bReset (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN INT32             OpFlags

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+  OpFlags     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+

+  UINT16  save_filter;

+  //

+  // disable the interrupts

+  //

+  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

+

+  //

+  // wait for the tx queue to complete

+  //

+  CheckCBList (AdapterInfo);

+

+  XmitWaitForCompletion (AdapterInfo);

+

+  if (AdapterInfo->Receive_Started) {

+    StopRU (AdapterInfo);

+  }

+

+  InitializeChip (AdapterInfo);

+

+  //

+  // check the opflags and restart receive filters

+  //

+  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_FILTERS) == 0) {

+

+    save_filter = AdapterInfo->Rx_Filter;

+    //

+    // if we give the filter same as Rx_Filter,

+    // this routine will not set mcast list (it thinks there is no change)

+    // to force it, we will reset that flag in the Rx_Filter

+    //

+    AdapterInfo->Rx_Filter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);

+    E100bSetfilter (AdapterInfo, save_filter, (UINT64) 0, (UINT32) 0);

+  }

+

+  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS) != 0) {

+    //

+    // disable the interrupts

+    //

+    AdapterInfo->int_mask = 0;

+  }

+  //

+  // else leave the interrupt in the pre-set state!!!

+  //

+  E100bSetInterruptState (AdapterInfo);

+

+  return 0;

+}

+

+UINTN

+E100bShutdown (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  //

+  // disable the interrupts

+  //

+  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

+

+  //

+  // stop the receive unit

+  //

+  if (AdapterInfo->Receive_Started) {

+    StopRU (AdapterInfo);

+  }

+

+  //

+  // wait for the tx queue to complete

+  //

+  CheckCBList (AdapterInfo);

+  if (AdapterInfo->FreeCBCount != AdapterInfo->TxBufCnt) {

+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+  }

+

+  //

+  // we do not want to reset the phy, it takes a long time to renegotiate the

+  // link after that (3-4 seconds)

+  //

+  InitializeChip (AdapterInfo);

+  SelectiveReset (AdapterInfo);

+  return 0;

+}

+

+VOID

+MdiWrite (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT8             RegAddress,

+  IN UINT8             PhyAddress,

+  IN UINT16            DataValue

+  )

+/*++

+

+Routine Description:

+ This routine will write a value to the specified MII register

+ of an external MDI compliant device (e.g. PHY 100).  The command will 

+ execute in polled mode.

+ 

+Arguments:

+  AdapterInfo - pointer to the structure that contains the NIC's context.

+  RegAddress - The MII register that we are writing to

+  PhyAddress - The MDI address of the Phy component.

+  DataValue - The value that we are writing to the MII register.

+

+Returns:

+ nothing  

+--*/

+{

+  UINT32  WriteCommand;

+

+  WriteCommand = ((UINT32) DataValue) |

+                 ((UINT32)(RegAddress << 16)) | 

+                 ((UINT32)(PhyAddress << 21)) |

+                 ((UINT32)(MDI_WRITE << 26));

+

+  //

+  // Issue the write command to the MDI control register.

+  //

+  OutLong (AdapterInfo, WriteCommand, AdapterInfo->ioaddr + SCBCtrlMDI);

+

+  //

+  // wait 20usec before checking status

+  //

+  DelayIt (AdapterInfo, 20);

+

+  //

+  // poll for the mdi write to complete

+  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) & 

+                    MDI_PHY_READY) == 0){

+    DelayIt (AdapterInfo, 20);

+  }

+}

+

+VOID

+MdiRead (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT8             RegAddress,

+  IN UINT8             PhyAddress,

+  IN OUT UINT16        *DataValue

+  )

+/*++

+

+Routine Description:

+ This routine will read a value from the specified MII register

+ of an external MDI compliant device (e.g. PHY 100), and return

+ it to the calling routine.  The command will execute in polled mode.

+ 

+Arguments:

+ AdapterInfo - pointer to the structure that contains the NIC's context.

+ RegAddress - The MII register that we are reading from

+ PhyAddress - The MDI address of the Phy component.

+ DataValue - pointer to the value that we read from the MII register.

+

+Returns:

+  

+--*/

+{

+  UINT32  ReadCommand;

+

+  ReadCommand = ((UINT32) (RegAddress << 16)) |

+                ((UINT32) (PhyAddress << 21)) |

+                ((UINT32) (MDI_READ << 26));

+

+  //

+  // Issue the read command to the MDI control register.

+  //

+  OutLong (AdapterInfo, ReadCommand, AdapterInfo->ioaddr + SCBCtrlMDI);

+

+  //

+  // wait 20usec before checking status

+  //

+  DelayIt (AdapterInfo, 20);

+

+  //

+  // poll for the mdi read to complete

+  //

+  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &

+          MDI_PHY_READY) == 0) {

+    DelayIt (AdapterInfo, 20);

+

+  }

+

+  *DataValue = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI);

+}

+

+VOID

+PhyReset (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+ This routine will reset the PHY that the adapter is currently

+ configured to use. 

+ 

+Arguments:

+  AdapterInfo - pointer to the structure that contains the NIC's context.

+

+Returns:

+  

+--*/

+{

+  UINT16  MdiControlReg;

+

+  MdiControlReg = (MDI_CR_AUTO_SELECT | 

+                  MDI_CR_RESTART_AUTO_NEG | 

+                  MDI_CR_RESET);

+

+  //

+  // Write the MDI control register with our new Phy configuration

+  //

+  MdiWrite (

+    AdapterInfo,

+    MDI_CONTROL_REG,

+    AdapterInfo->PhyAddress,

+    MdiControlReg

+    );

+

+  return ;

+}

+

+BOOLEAN

+PhyDetect (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+ This routine will detect what phy we are using, set the line

+              speed, FDX or HDX, and configure the phy if necessary.

+

+              The following combinations are supported:

+              - TX or T4 PHY alone at PHY address 1

+              - T4 or TX PHY at address 1 and MII PHY at address 0

+              - 82503 alone (10Base-T mode, no full duplex support)

+              - 82503 and MII PHY (TX or T4) at address 0

+

+              The sequence / priority of detection is as follows:

+              - PHY 1 with cable termination

+              - PHY 0 with cable termination

+              - PHY 1 (if found) without cable termination

+              - 503 interface

+

+              Additionally auto-negotiation capable (NWAY) and parallel

+              detection PHYs are supported. The flow-chart is described in

+              the 82557 software writer's manual.

+

+   NOTE:  1.  All PHY MDI registers are read in polled mode.

+          2.  The routines assume that the 82557 has been RESET and we have

+              obtained the virtual memory address of the CSR.

+          3.  PhyDetect will not RESET the PHY.

+          4.  If FORCEFDX is set, SPEED should also be set. The driver will

+              check the values for inconsistency with the detected PHY

+              technology.

+          5.  PHY 1 (the PHY on the adapter) may have an address in the range

+              1 through 31 inclusive. The driver will accept addresses in

+              this range.

+          6.  Driver ignores FORCEFDX and SPEED overrides if a 503 interface

+              is detected.

+ 

+Arguments:

+  AdapterInfo - pointer to the structure that contains the NIC's context.

+

+Returns:

+  TRUE - If a Phy was detected, and configured correctly.

+  FALSE - If a valid phy could not be detected and configured. 

+  

+--*/

+{

+  UINT16  *eedata;

+  UINT16  MdiControlReg;

+  UINT16  MdiStatusReg;

+  BOOLEAN FoundPhy1;

+  UINT8   ReNegotiateTime;

+

+  eedata          = (UINT16 *) (&AdapterInfo->NVData[0]);

+

+  FoundPhy1       = FALSE;

+  ReNegotiateTime = 35;

+  //

+  // EEPROM word [6] contains the Primary PHY record in which the least 3 bits

+  // indicate the PHY address

+  // and word [7] contains the secondary PHY record

+  //

+  AdapterInfo->PhyRecord[0] = eedata[6];

+  AdapterInfo->PhyRecord[1] = eedata[7];

+  AdapterInfo->PhyAddress   = (UINT8) (AdapterInfo->PhyRecord[0] & 7);

+

+  //

+  // Check for a phy address over-ride of 32 which indicates force use of 82503

+  // not detecting the link in this case

+  //

+  if (AdapterInfo->PhyAddress == 32) {

+    //

+    // 503 interface over-ride

+    // Record the current speed and duplex.  We will be in half duplex

+    // mode unless the user used the force full duplex over-ride.

+    //

+    AdapterInfo->LinkSpeed = 10;

+    return (TRUE);

+  }

+

+  //

+  // If the Phy Address is between 1-31 then we must first look for phy 1,

+  // at that address.

+  //

+  if ((AdapterInfo->PhyAddress > 0) && (AdapterInfo->PhyAddress < 32)) {

+

+    //

+    // Read the MDI control and status registers at phy 1

+    // and check if we found a valid phy

+    //

+    MdiRead (

+      AdapterInfo,

+      MDI_CONTROL_REG,

+      AdapterInfo->PhyAddress,

+      &MdiControlReg

+      );

+

+    MdiRead (

+      AdapterInfo,

+      MDI_STATUS_REG,

+      AdapterInfo->PhyAddress,

+      &MdiStatusReg

+      );

+

+    if (!((MdiControlReg == 0xffff) || 

+          ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {

+

+      //

+      // we have a valid phy1

+      // Read the status register again because of sticky bits

+      //

+      FoundPhy1 = TRUE;

+      MdiRead (

+        AdapterInfo,

+        MDI_STATUS_REG,

+        AdapterInfo->PhyAddress,

+        &MdiStatusReg

+        );

+

+      //

+      // If there is a valid link then use this Phy.

+      //

+      if (MdiStatusReg & MDI_SR_LINK_STATUS) {

+        return (SetupPhy(AdapterInfo));

+      }

+    }

+  }

+

+  //

+  // Next try to detect a PHY at address 0x00 because there was no Phy 1,

+  // or Phy 1 didn't have link, or we had a phy 0 over-ride

+  //

+

+  //

+  // Read the MDI control and status registers at phy 0

+  //

+  MdiRead (AdapterInfo, MDI_CONTROL_REG, 0, &MdiControlReg);

+  MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

+

+  //

+  // check if we found a valid phy 0

+  //

+  if (((MdiControlReg == 0xffff) ||

+       ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {

+

+    //

+    // we don't have a valid phy at address 0

+    // if phy address was forced to 0, then error out because we

+    // didn't find a phy at that address

+    //

+    if (AdapterInfo->PhyAddress == 0x0000) {

+      return (FALSE);

+    } else {

+      //

+      // at this point phy1 does not have link and there is no phy 0 at all

+      // if we are forced to detect the cable, error out here!

+      //

+      if (AdapterInfo->CableDetect != 0) {

+        return FALSE;

+

+      }

+

+      if (FoundPhy1) {

+        //

+        // no phy 0, but there is a phy 1 (no link I guess), so use phy 1

+        //

+        return SetupPhy (AdapterInfo);

+      } else {

+        //

+        // didn't find phy 0 or phy 1, so assume a 503 interface

+        //

+        AdapterInfo->PhyAddress = 32;

+

+        //

+        // Record the current speed and duplex.  We'll be in half duplex

+        // mode unless the user used the force full duplex over-ride.

+        //

+        AdapterInfo->LinkSpeed = 10;

+        return (TRUE);

+      }

+    }

+  } else {

+    //

+    // We have a valid phy at address 0.  If phy 0 has a link then we use

+    // phy 0.  If Phy 0 doesn't have a link then we use Phy 1 (no link)

+    // if phy 1 is present, or phy 0 if phy 1 is not present

+    // If phy 1 was present, then we must isolate phy 1 before we enable

+    // phy 0 to see if Phy 0 has a link.

+    //

+    if (FoundPhy1) {

+      //

+      // isolate phy 1

+      //

+      MdiWrite (

+        AdapterInfo,

+        MDI_CONTROL_REG,

+        AdapterInfo->PhyAddress,

+        MDI_CR_ISOLATE

+        );

+

+      //

+      // wait 100 microseconds for the phy to isolate.

+      //

+      DelayIt (AdapterInfo, 100);

+    }

+

+    //

+    // Since this Phy is at address 0, we must enable it.  So clear

+    // the isolate bit, and set the auto-speed select bit

+    //

+    MdiWrite (

+      AdapterInfo,

+      MDI_CONTROL_REG,

+      0,

+      MDI_CR_AUTO_SELECT

+      );

+

+    //

+    // wait 100 microseconds for the phy to be enabled.

+    //

+    DelayIt (AdapterInfo, 100);

+

+    //

+    // restart the auto-negotion process

+    //

+    MdiWrite (

+      AdapterInfo,

+      MDI_CONTROL_REG,

+      0,

+      MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT

+      );

+

+    //

+    // wait no more than 3.5 seconds for auto-negotiation to complete

+    //

+    while (ReNegotiateTime) {

+      //

+      // Read the status register twice because of sticky bits

+      //

+      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

+      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

+

+      if (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE) {

+        break;

+      }

+

+      DelayIt (AdapterInfo, 100);

+      ReNegotiateTime--;

+    }

+

+    //

+    // Read the status register again because of sticky bits

+    //

+    MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

+

+    //

+    // If the link was not set

+    //

+    if ((MdiStatusReg & MDI_SR_LINK_STATUS) == 0) {

+      //

+      // PHY1 does not have a link and phy 0 does not have a link

+      // do not proceed if we need to detect the link!

+      //

+      if (AdapterInfo->CableDetect != 0) {

+        return FALSE;

+      }

+

+      //

+      // the link wasn't set, so use phy 1 if phy 1 was present

+      //

+      if (FoundPhy1) {

+        //

+        // isolate phy 0

+        //

+        MdiWrite (AdapterInfo, MDI_CONTROL_REG, 0, MDI_CR_ISOLATE);

+

+        //

+        // wait 100 microseconds for the phy to isolate.

+        //

+        DelayIt (AdapterInfo, 100);

+

+        //

+        // Now re-enable PHY 1

+        //

+        MdiWrite (

+          AdapterInfo,

+          MDI_CONTROL_REG,

+          AdapterInfo->PhyAddress,

+          MDI_CR_AUTO_SELECT

+          );

+

+        //

+        // wait 100 microseconds for the phy to be enabled

+        //

+        DelayIt (AdapterInfo, 100);

+

+        //

+        // restart the auto-negotion process

+        //

+        MdiWrite (

+          AdapterInfo,

+          MDI_CONTROL_REG,

+          AdapterInfo->PhyAddress,

+          MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT

+          );

+

+        //

+        // Don't wait for it to complete (we didn't have link earlier)

+        //

+        return (SetupPhy (AdapterInfo));

+      }

+    }

+

+    //

+    // Definitely using Phy 0

+    //

+    AdapterInfo->PhyAddress = 0;

+    return (SetupPhy(AdapterInfo));

+  }

+}

+

+BOOLEAN

+SetupPhy (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+ This routine will setup phy 1 or phy 0 so that it is configured

+ to match a speed and duplex over-ride option.  If speed or

+ duplex mode is not explicitly specified in the registry, the

+ driver will skip the speed and duplex over-ride code, and

+ assume the adapter is automatically setting the line speed, and

+ the duplex mode.  At the end of this routine, any truly Phy

+ specific code will be executed (each Phy has its own quirks,

+ and some require that certain special bits are set).

+

+ NOTE:  The driver assumes that SPEED and FORCEFDX are specified at the

+        same time. If FORCEDPX is set without speed being set, the driver

+        will encouter a fatal error and log a message into the event viewer.

+

+Arguments:

+ AdapterInfo - pointer to the structure that contains the NIC's context.

+

+Returns:

+ TRUE - If the phy could be configured correctly

+ FALSE - If the phy couldn't be configured correctly, because an 

+         unsupported over-ride option was used

+  

+--*/

+{

+  UINT16  MdiControlReg;

+  UINT16  MdiStatusReg;

+  UINT16  MdiIdLowReg;

+  UINT16  MdiIdHighReg;

+  UINT16  MdiMiscReg;

+  UINT32  PhyId;

+  BOOLEAN ForcePhySetting;

+

+  ForcePhySetting = FALSE;

+

+  //

+  // If we are NOT forcing a setting for line speed or full duplex, then

+  // we won't force a link setting, and we'll jump down to the phy

+  // specific code.

+  //

+  if (((AdapterInfo->LinkSpeedReq) || (AdapterInfo->DuplexReq))) {

+    //

+    // Find out what kind of technology this Phy is capable of.

+    //

+    MdiRead (

+      AdapterInfo,

+      MDI_STATUS_REG,

+      AdapterInfo->PhyAddress,

+      &MdiStatusReg

+      );

+

+    //

+    // Read the MDI control register at our phy

+    //

+    MdiRead (

+      AdapterInfo,

+      MDI_CONTROL_REG,

+      AdapterInfo->PhyAddress,

+      &MdiControlReg

+      );

+

+    //

+    // Now check the validity of our forced option.  If the force option is

+    // valid, then force the setting.  If the force option is not valid,

+    // we'll set a flag indicating that we should error out.

+    //

+

+    //

+    // If speed is forced to 10mb

+    //

+    if (AdapterInfo->LinkSpeedReq == 10) {

+      //

+      // If half duplex is forced

+      //

+      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {

+        if (MdiStatusReg & MDI_SR_10T_HALF_DPX) {

+

+          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);

+          ForcePhySetting = TRUE;

+        }

+      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {

+

+        //

+        // If full duplex is forced

+        //

+        if (MdiStatusReg & MDI_SR_10T_FULL_DPX) {

+

+          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT);

+          MdiControlReg |= MDI_CR_FULL_HALF;

+          ForcePhySetting = TRUE;

+        }

+      } else {

+        //

+        // If auto duplex (we actually set phy to 1/2)

+        //

+        if (MdiStatusReg & (MDI_SR_10T_FULL_DPX | MDI_SR_10T_HALF_DPX)) {

+

+          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);

+          ForcePhySetting = TRUE;

+        }

+      }

+    }

+

+    //

+    // If speed is forced to 100mb

+    //

+    else if (AdapterInfo->LinkSpeedReq == 100) {

+      //

+      // If half duplex is forced

+      //

+      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {

+        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {

+

+          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);

+          MdiControlReg |= MDI_CR_10_100;

+          ForcePhySetting = TRUE;

+        }

+      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {

+        //

+        // If full duplex is forced

+        //

+        if (MdiStatusReg & MDI_SR_TX_FULL_DPX) {

+          MdiControlReg &= ~MDI_CR_AUTO_SELECT;

+          MdiControlReg |= (MDI_CR_10_100 | MDI_CR_FULL_HALF);

+          ForcePhySetting = TRUE;

+        }

+      } else {

+        //

+        // If auto duplex (we set phy to 1/2)

+        //

+        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {

+

+          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);

+          MdiControlReg |= MDI_CR_10_100;

+          ForcePhySetting = TRUE;

+        }

+      }

+    }

+

+    if (!ForcePhySetting) {

+      return (FALSE);

+    }

+

+    //

+    // Write the MDI control register with our new Phy configuration

+    //

+    MdiWrite (

+      AdapterInfo,

+      MDI_CONTROL_REG,

+      AdapterInfo->PhyAddress,

+      MdiControlReg

+      );

+

+    //

+    // wait 100 milliseconds for auto-negotiation to complete

+    //

+    DelayIt (AdapterInfo, 100);

+  }

+

+  //

+  // Find out specifically what Phy this is.  We do this because for certain

+  // phys there are specific bits that must be set so that the phy and the

+  // 82557 work together properly.

+  //

+

+  MdiRead (

+    AdapterInfo,

+    PHY_ID_REG_1,

+    AdapterInfo->PhyAddress,

+    &MdiIdLowReg

+    );

+  MdiRead (

+    AdapterInfo,

+    PHY_ID_REG_2,

+    AdapterInfo->PhyAddress,

+    &MdiIdHighReg

+    );

+

+  PhyId = ((UINT32) MdiIdLowReg | ((UINT32) MdiIdHighReg << 16));

+

+  //

+  // And out the revsion field of the Phy ID so that we'll be able to detect

+  // future revs of the same Phy.

+  //

+  PhyId &= PHY_MODEL_REV_ID_MASK;

+

+  //

+  // Handle the National TX

+  //

+  if (PhyId == PHY_NSC_TX) {

+

+    MdiRead (

+      AdapterInfo,

+      NSC_CONG_CONTROL_REG,

+      AdapterInfo->PhyAddress,

+      &MdiMiscReg

+      );

+

+    MdiMiscReg |= (NSC_TX_CONG_TXREADY | NSC_TX_CONG_F_CONNECT);

+

+#if CONGESTION_CONTROL

+    //

+    // If we are configured to do congestion control, then enable the

+    // congestion control bit in the National Phy

+    //

+    if (AdapterInfo->Congest) {

+      MdiMiscReg |= NSC_TX_CONG_ENABLE;

+    } else {

+      MdiMiscReg &= ~NSC_TX_CONG_ENABLE;

+    }

+#endif

+    MdiWrite (

+      AdapterInfo,

+      NSC_CONG_CONTROL_REG,

+      AdapterInfo->PhyAddress,

+      MdiMiscReg

+      );

+  }

+

+  FindPhySpeedAndDpx (AdapterInfo, PhyId);

+

+  //

+  // We put a hardware fix on to our adapters to work-around the PHY_100 errata

+  // described below.  The following code is only compiled in, if we wanted

+  // to attempt a software workaround to the PHY_100 A/B step problem.

+  //

+

+#if DO_PHY_100B_SOFTWARE_FIX

+  //

+  // Handle the Intel PHY_100 (A and B steps)

+  //

+  if ((PhyId == PHY_100_A) && (AdapterInfo->LinkSpeed == 100)) {

+    //

+    // The PHY_100 is very sensitive to collisions at 100mb, so increase

+    // the Adaptive IFS value with the intention of reducing the number of

+    // collisions that the adapter generates.

+    //

+    AdapterInfo->CurrentIFSValue  = 0x18;

+    AdapterInfo->AdaptiveIFS      = 0;

+  }

+#endif

+

+  return (TRUE);

+}

+

+VOID

+FindPhySpeedAndDpx (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT32            PhyId

+  )

+/*++

+

+Routine Description:

+ This routine will figure out what line speed and duplex mode

+ the PHY is currently using.

+

+Arguments:

+ AdapterInfo - pointer to the structure that contains the NIC's context.

+ PhyId - The ID of the PHY in question.

+

+Returns:

+  NOTHING

+--*/

+{

+  UINT16  MdiStatusReg;

+  UINT16  MdiMiscReg;

+  UINT16  MdiOwnAdReg;

+  UINT16  MdiLinkPartnerAdReg;

+

+  //

+  // If there was a speed and/or duplex override, then set our current

+  // value accordingly

+  //

+  AdapterInfo->LinkSpeed  = AdapterInfo->LinkSpeedReq;

+  AdapterInfo->Duplex = (UINT8) ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) ? 

+                        FULL_DUPLEX : HALF_DUPLEX);

+

+  //

+  // If speed and duplex were forced, then we know our current settings, so

+  // we'll just return.  Otherwise, we'll need to figure out what NWAY set

+  // us to.

+  //

+  if (AdapterInfo->LinkSpeed && AdapterInfo->Duplex) {

+    return ;

+

+  }

+  //

+  // If we didn't have a valid link, then we'll assume that our current

+  // speed is 10mb half-duplex.

+  //

+

+  //

+  // Read the status register twice because of sticky bits

+  //

+  MdiRead (

+    AdapterInfo,

+    MDI_STATUS_REG,

+    AdapterInfo->PhyAddress,

+    &MdiStatusReg

+    );

+  MdiRead (

+    AdapterInfo,

+    MDI_STATUS_REG,

+    AdapterInfo->PhyAddress,

+    &MdiStatusReg

+    );

+

+  //

+  // If there wasn't a valid link then use default speed & duplex

+  //

+  if (!(MdiStatusReg & MDI_SR_LINK_STATUS)) {

+

+    AdapterInfo->LinkSpeed  = 10;

+    AdapterInfo->Duplex     = HALF_DUPLEX;

+    return ;

+  }

+

+  //

+  // If this is an Intel PHY (a T4 PHY_100 or a TX PHY_TX), then read bits

+  // 1 and 0 of extended register 0, to get the current speed and duplex

+  // settings.

+  //

+  if ((PhyId == PHY_100_A) || (PhyId == PHY_100_C) || (PhyId == PHY_TX_ID)) {

+    //

+    // Read extended register 0

+    //

+    MdiRead (

+      AdapterInfo,

+      EXTENDED_REG_0,

+      AdapterInfo->PhyAddress,

+      &MdiMiscReg

+      );

+

+    //

+    // Get current speed setting

+    //

+    if (MdiMiscReg & PHY_100_ER0_SPEED_INDIC) {

+      AdapterInfo->LinkSpeed = 100;

+    } else {

+      AdapterInfo->LinkSpeed = 10;

+    }

+

+    //

+    // Get current duplex setting -- if bit is set then FDX is enabled

+    //

+    if (MdiMiscReg & PHY_100_ER0_FDX_INDIC) {

+      AdapterInfo->Duplex = FULL_DUPLEX;

+    } else {

+      AdapterInfo->Duplex = HALF_DUPLEX;

+    }

+

+    return ;

+  }

+  //

+  // Read our link partner's advertisement register

+  //

+  MdiRead (

+    AdapterInfo,

+    AUTO_NEG_LINK_PARTNER_REG,

+    AdapterInfo->PhyAddress,

+    &MdiLinkPartnerAdReg

+    );

+

+  //

+  // See if Auto-Negotiation was complete (bit 5, reg 1)

+  //

+  MdiRead (

+    AdapterInfo,

+    MDI_STATUS_REG,

+    AdapterInfo->PhyAddress,

+    &MdiStatusReg

+    );

+

+  //

+  // If a True NWAY connection was made, then we can detect speed/duplex by

+  // ANDing our adapter's advertised abilities with our link partner's

+  // advertised ablilities, and then assuming that the highest common

+  // denominator was chosed by NWAY.

+  //

+  if ((MdiLinkPartnerAdReg & NWAY_LP_ABILITY) && 

+      (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE)) {

+

+    //

+    // Read our advertisement register

+    //

+    MdiRead (

+      AdapterInfo,

+      AUTO_NEG_ADVERTISE_REG,

+      AdapterInfo->PhyAddress,

+      &MdiOwnAdReg

+      );

+

+    //

+    // AND the two advertisement registers together, and get rid of any

+    // extraneous bits.

+    //

+    MdiOwnAdReg &= (MdiLinkPartnerAdReg & NWAY_LP_ABILITY);

+

+    //

+    // Get speed setting

+    //

+    if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX | NWAY_AD_TX_FULL_DPX | NWAY_AD_T4_CAPABLE)) {

+      AdapterInfo->LinkSpeed = 100;

+    } else {

+      AdapterInfo->LinkSpeed = 10;

+    }

+

+    //

+    // Get duplex setting -- use priority resolution algorithm

+    //

+    if (MdiOwnAdReg & (NWAY_AD_T4_CAPABLE)) {

+      AdapterInfo->Duplex = HALF_DUPLEX;

+      return ;

+    } else if (MdiOwnAdReg & (NWAY_AD_TX_FULL_DPX)) {

+      AdapterInfo->Duplex = FULL_DUPLEX;

+      return ;

+    } else if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX)) {

+      AdapterInfo->Duplex = HALF_DUPLEX;

+      return ;

+    } else if (MdiOwnAdReg & (NWAY_AD_10T_FULL_DPX)) {

+      AdapterInfo->Duplex = FULL_DUPLEX;

+      return ;

+    } else {

+      AdapterInfo->Duplex = HALF_DUPLEX;

+      return ;

+    }

+  }

+

+  //

+  // If we are connected to a dumb (non-NWAY) repeater or hub, and the line

+  // speed was determined automatically by parallel detection, then we have

+  // no way of knowing exactly what speed the PHY is set to unless that PHY

+  // has a propietary register which indicates speed in this situation.  The

+  // NSC TX PHY does have such a register.  Also, since NWAY didn't establish

+  // the connection, the duplex setting should HALF duplex.

+  //

+  AdapterInfo->Duplex = HALF_DUPLEX;

+

+  if (PhyId == PHY_NSC_TX) {

+    //

+    // Read register 25 to get the SPEED_10 bit

+    //

+    MdiRead (

+      AdapterInfo,

+      NSC_SPEED_IND_REG,

+      AdapterInfo->PhyAddress,

+      &MdiMiscReg

+      );

+

+    //

+    // If bit 6 was set then we're at 10mb

+    //

+    if (MdiMiscReg & NSC_TX_SPD_INDC_SPEED) {

+      AdapterInfo->LinkSpeed = 10;

+    } else {

+      AdapterInfo->LinkSpeed = 100;

+    }

+  }

+

+  //

+  // If we don't know what line speed we are set at, then we'll default to

+  // 10mbs

+  //

+  else {

+    AdapterInfo->LinkSpeed = 10;

+  }

+}

+

+VOID

+XmitWaitForCompletion (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  TxCB  *TxPtr;

+

+  if (AdapterInfo->FreeCBCount == AdapterInfo->TxBufCnt) {

+    return ;

+  }

+

+  //

+  // used xmit cb list starts right after the free tail (ends before the

+  // free head ptr)

+  //

+  TxPtr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;

+  while (TxPtr != AdapterInfo->FreeTxHeadPtr) {

+    CommandWaitForCompletion (TxPtr, AdapterInfo);

+    SetFreeCB (AdapterInfo, TxPtr);

+    TxPtr = TxPtr->NextTCBVirtualLinkPtr;

+  }

+}

+

+INT8

+CommandWaitForCompletion (

+  TxCB              *cmd_ptr,

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  cmd_ptr     - TODO: add argument description

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  INT16 wait;

+  wait = 5000;

+  while ((cmd_ptr->cb_header.status == 0) && (--wait > 0)) {

+    DelayIt (AdapterInfo, 10);

+  }

+

+  if (cmd_ptr->cb_header.status == 0) {

+    return -1;

+  }

+

+  return 0;

+}

+

+INT8

+SoftwareReset (

+  NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT8   tco_stat;

+  UINT16  wait;

+

+  tco_stat = 0;

+

+  //

+  // Reset the chip: stop Tx and Rx processes and clear counters.

+  // This takes less than 10usec and will easily finish before the next

+  // action.

+  //

+

+  OutLong (AdapterInfo, PORT_RESET, AdapterInfo->ioaddr + SCBPort);

+  //

+  // wait for 5 milli seconds here!

+  //

+  DelayIt (AdapterInfo, 5000);

+  //

+  // TCO Errata work around for 559s only

+  // -----------------------------------------------------------------------------------

+  // TCO Workaround Code

+  //  haifa workaround

+  // -----------------------------------------------------------------------------------

+  //    1. Issue SW-RST ^^^ (already done above)

+  //    2. Issue a redundant Set CU Base CMD immediately

+  //       Do not set the General Pointer before the Set CU Base cycle

+  //       Do not check the SCB CMD before the Set CU Base cycle

+  //    3. Wait for the SCB-CMD to be cleared

+  //       this indicates the transition to post-driver

+  //    4. Poll the TCO-Req bit in the PMDR to be cleared

+  //       this indicates the tco activity has stopped for real

+  //    5. Proceed with the nominal Driver Init:

+  //       Actual Set CU & RU Base ...

+  //

+  // Check for ICH2 device ID.  If this is an ICH2,

+  // do the TCO workaround code.

+  //

+  if (AdapterInfo->VendorID == D102_DEVICE_ID ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_1 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_2 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_3 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_4 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_5 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_6 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_7 ||

+      AdapterInfo->VendorID == ICH3_DEVICE_ID_8 ||

+      AdapterInfo->RevID >= 8) {  // do the TCO fix

+    //

+    // donot load the scb pointer but just give load_cu cmd.

+    //

+    OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);

+    //

+    // wait for command to be accepted.

+    //

+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

+    //

+    // read PMDR register and check bit 1 in it to see if TCO is active

+    //

+

+    //

+    // wait for 5 milli seconds

+    //

+    wait = 5000;

+    while (wait) {

+      tco_stat = InByte (AdapterInfo, AdapterInfo->ioaddr + 0x1b);

+      if ((tco_stat & 2) == 0) {

+        //

+        // is the activity bit clear??

+        //

+        break;

+      }

+

+      wait--;

+      DelayIt (AdapterInfo, 1);

+    }

+

+    if ((tco_stat & 2) != 0) {

+      //

+      // not zero??

+      //

+      return -1;

+    }

+  }

+

+  return 0;

+}

+

+UINT8

+SelectiveReset (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT16  wait;

+  UINT32  stat;

+

+  wait  = 10;

+  stat  = 0;

+  OutLong (AdapterInfo, POR_SELECTIVE_RESET, AdapterInfo->ioaddr + SCBPort);

+  //

+  // wait for this to complete

+  //

+

+  //

+  // wait for 2 milli seconds here!

+  //

+  DelayIt (AdapterInfo, 2000);

+  while (wait > 0) {

+    wait--;

+    stat = InLong (AdapterInfo, AdapterInfo->ioaddr + SCBPort);

+    if (stat == 0) {

+      break;

+    }

+

+    //

+    // wait for 1 milli second

+    //

+    DelayIt (AdapterInfo, 1000);

+  }

+

+  if (stat != 0) {

+    return PXE_STATCODE_DEVICE_FAILURE;

+  }

+

+  return 0;

+}

+

+UINT16

+InitializeChip (

+  IN NIC_DATA_INSTANCE *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  AdapterInfo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT16  ret_val;

+  if (SoftwareReset (AdapterInfo) != 0) {

+    return PXE_STATCODE_DEVICE_FAILURE;

+  }

+

+  //

+  // disable interrupts

+  //

+  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

+

+  //

+  // Load the base registers with 0s (we will give the complete address as

+  // offset later when we issue any command

+  //

+  if ((ret_val = Load_Base_Regs (AdapterInfo)) != 0) {

+    return ret_val;

+  }

+

+  if ((ret_val = SetupCBlink (AdapterInfo)) != 0) {

+    return ret_val;

+  }

+

+  if ((ret_val = SetupReceiveQueues (AdapterInfo)) != 0) {

+    return ret_val;

+  }

+

+  //

+  // detect the PHY only if we need to detect the cable as requested by the

+  // initialize parameters

+  //

+  AdapterInfo->PhyAddress = 0xFF;

+

+  if (AdapterInfo->CableDetect != 0) {

+    if (!PhyDetect (AdapterInfo)) {

+      return PXE_STATCODE_DEVICE_FAILURE;

+    }

+  }

+

+  if ((ret_val = E100bSetupIAAddr (AdapterInfo)) != 0) {

+    return ret_val;

+  }

+

+  if ((ret_val = Configure (AdapterInfo)) != 0) {

+    return ret_val;

+  }

+

+  return 0;

+}

+

+#pragma data_seg()

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/E100b.h b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/E100b.h
new file mode 100644
index 0000000..3a4127c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/E100b.h
@@ -0,0 +1,668 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  E100B.H

+

+Abstract:

+

+

+Revision History

+

+--*/

+// pci config offsets:

+

+#define RX_BUFFER_COUNT 32

+#define TX_BUFFER_COUNT 32

+

+#define PCI_VENDOR_ID_INTEL 0x8086

+#define PCI_DEVICE_ID_INTEL_82557 0x1229

+#define D100_VENDOR_ID   0x8086

+#define D100_DEVICE_ID   0x1229

+#define D102_DEVICE_ID   0x2449

+

+#define ICH3_DEVICE_ID_1   0x1031

+#define ICH3_DEVICE_ID_2   0x1032

+#define ICH3_DEVICE_ID_3   0x1033

+#define ICH3_DEVICE_ID_4   0x1034

+#define ICH3_DEVICE_ID_5   0x1035

+#define ICH3_DEVICE_ID_6   0x1036

+#define ICH3_DEVICE_ID_7   0x1037

+#define ICH3_DEVICE_ID_8   0x1038

+

+#define SPEEDO_DEVICE_ID   0x1227

+#define SPLASH1_DEVICE_ID   0x1226

+

+

+// bit fields for the command

+#define PCI_COMMAND_MASTER  0x04  // bit 2

+#define PCI_COMMAND_IO    0x01  // bit 0

+#define PCI_COMMAND  0x04

+#define PCI_LATENCY_TIMER  0x0D

+

+#define ETHER_MAC_ADDR_LEN 6

+#ifdef AVL_XXX

+#define ETHER_HEADER_LEN 14

+// media interface type

+// #define INTERFACE_TYPE "

+

+// Hardware type values

+#define HW_ETHER_TYPE    1

+#define HW_EXPERIMENTAL_ETHER_TYPE 2

+#define HW_IEEE_TYPE    6

+#define HW_ARCNET_TYPE     7

+

+#endif  // AVL_XXX

+

+#define MAX_ETHERNET_PKT_SIZE 1514  // including eth header

+#define RX_BUFFER_SIZE 1536  // including crc and padding

+#define TX_BUFFER_SIZE 64

+#define ETH_MTU 1500  // does not include ethernet header length

+

+#define SPEEDO3_TOTAL_SIZE 0x20

+

+#pragma pack(1)

+

+typedef struct eth {

+  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];

+  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];

+  UINT16 type;

+} EtherHeader;

+

+#pragma pack(1)

+typedef struct CONFIG_HEADER {

+  UINT16 VendorID;

+  UINT16 DeviceID;

+  UINT16 Command;

+  UINT16 Status;

+  UINT16 RevID;

+  UINT16 ClassID;

+  UINT8  CacheLineSize;

+  UINT8  LatencyTimer;

+  UINT8  HeaderType;    // must be zero to impose this structure...

+  UINT8  BIST;  // built-in self test

+  UINT32 BaseAddressReg_0;  // memory mapped address

+  UINT32 BaseAddressReg_1;  //io mapped address, Base IO address

+  UINT32 BaseAddressReg_2;  // option rom address

+  UINT32 BaseAddressReg_3;

+  UINT32 BaseAddressReg_4;

+  UINT32 BaseAddressReg_5;

+  UINT32 CardBusCISPtr;

+  UINT16 SubVendorID;

+  UINT16 SubSystemID;

+  UINT32 ExpansionROMBaseAddr;

+  UINT8 CapabilitiesPtr;

+  UINT8 reserved1;

+  UINT16 Reserved2;

+  UINT32 Reserved3;

+  UINT8 int_line;

+  UINT8 int_pin;

+  UINT8 Min_gnt;

+  UINT8 Max_lat;

+} PCI_CONFIG_HEADER;

+#pragma pack()

+

+//-------------------------------------------------------------------------

+// Offsets to the various registers.

+//   All accesses need not be longword aligned. 

+//-------------------------------------------------------------------------

+enum speedo_offsets {

+  SCBStatus = 0, SCBCmd = 2,     // Rx/Command Unit command and status. 

+  SCBPointer = 4,                // General purpose pointer. 

+  SCBPort = 8,                   // Misc. commands and operands.  

+  SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control. 

+  SCBCtrlMDI = 16,               // MDI interface control. 

+  SCBEarlyRx = 20,               // Early receive byte count. 

+  SCBEarlyRxInt = 24, SCBFlowCtrlReg = 25, SCBPmdr = 27,

+  // offsets for general control registers (GCRs)

+  SCBGenCtrl = 28, SCBGenStatus = 29, SCBGenCtrl2 = 30, SCBRsvd = 31,

+};

+

+#define GCR2_EEPROM_ACCESS_SEMAPHORE 0x80 // bit offset into the gcr2

+

+//-------------------------------------------------------------------------

+// Action commands - Commands that can be put in a command list entry. 

+//-------------------------------------------------------------------------

+enum commands {

+  CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,

+  CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7,

+  CmdSuspend = 0x4000,    /* Suspend after completion. */

+  CmdIntr = 0x2000,      /* Interrupt after completion. */

+  CmdTxFlex = 0x0008,      /* Use "Flexible mode" for CmdTx command. */

+};

+

+//-------------------------------------------------------------------------

+// port commands

+//-------------------------------------------------------------------------

+#define PORT_RESET 0

+#define PORT_SELF_TEST 1

+#define POR_SELECTIVE_RESET 2

+#define PORT_DUMP_POINTER 2

+

+//-------------------------------------------------------------------------

+// SCB Command Word bit definitions

+//-------------------------------------------------------------------------

+//- CUC fields

+#define   CU_START    0x0010

+#define   CU_RESUME    0x0020

+#define   CU_STATSADDR  0x0040

+#define   CU_SHOWSTATS  0x0050  /* Dump statistics counters. */

+#define   CU_CMD_BASE  0x0060  /* Base address to add to add CU commands. */

+#define   CU_DUMPSTATS  0x0070  /* Dump then reset stats counters. */

+

+//- RUC fields

+#define   RX_START  0x0001

+#define   RX_RESUME  0x0002

+#define   RX_ABORT  0x0004

+#define   RX_ADDR_LOAD  0x0006  /* load ru_base_reg */

+#define   RX_RESUMENR  0x0007

+

+// Interrupt fields (assuming byte addressing)

+#define INT_MASK  0x0100

+#define DRVR_INT  0x0200    /* Driver generated interrupt. */

+

+//- CB Status Word

+#define CMD_STATUS_COMPLETE 0x8000

+#define RX_STATUS_COMPLETE 0x8000

+#define CMD_STATUS_MASK 0xF000

+

+//-------------------------------------------------------------------------

+//- SCB Status bits:

+// Interrupts are ACKed by writing to the upper 6 interrupt bits

+//-------------------------------------------------------------------------

+#define SCB_STATUS_MASK        0xFC00 // bits 2-7 - STATUS/ACK Mask

+#define SCB_STATUS_CX_TNO      0x8000 // BIT_15  - CX or TNO Interrupt

+#define SCB_STATUS_FR          0x4000 // BIT_14 - FR Interrupt

+#define SCB_STATUS_CNA         0x2000 // BIT_13 - CNA Interrupt

+#define SCB_STATUS_RNR         0x1000 // BIT_12  - RNR Interrupt

+#define SCB_STATUS_MDI         0x0800 // BIT_11  - MDI R/W Done Interrupt

+#define SCB_STATUS_SWI         0x0400 // BIT_10  - SWI Interrupt

+

+// CU STATUS: bits 6 & 7

+#define SCB_STATUS_CU_MASK     0x00C0 // bits 6 & 7

+#define SCB_STATUS_CU_IDLE     0x0000 // 00

+#define SCB_STATUS_CU_SUSPEND  0x0040 // 01

+#define SCB_STATUS_CU_ACTIVE   0x0080 // 10

+

+// RU STATUS: bits 2-5

+#define SCB_RUS_IDLE         0x0000

+#define SCB_RUS_SUSPENDED    0x0004  // bit 2

+#define SCB_RUS_NO_RESOURCES   0x0008 // bit 3

+#define SCB_RUS_READY       0x0010 // bit 4

+

+//-------------------------------------------------------------------------

+// Bit Mask definitions

+//-------------------------------------------------------------------------

+#define BIT_0       0x0001

+#define BIT_1       0x0002

+#define BIT_2       0x0004

+#define BIT_3       0x0008

+#define BIT_4       0x0010

+#define BIT_5       0x0020

+#define BIT_6       0x0040

+#define BIT_7       0x0080

+#define BIT_8       0x0100

+#define BIT_9       0x0200

+#define BIT_10      0x0400

+#define BIT_11      0x0800

+#define BIT_12      0x1000

+#define BIT_13      0x2000

+#define BIT_14      0x4000

+#define BIT_15      0x8000

+#define BIT_24      0x01000000

+#define BIT_28      0x10000000

+

+

+//-------------------------------------------------------------------------

+// MDI Control register bit definitions

+//-------------------------------------------------------------------------

+#define MDI_DATA_MASK           BIT_0_15        // MDI Data port

+#define MDI_REG_ADDR            BIT_16_20       // which MDI register to read/write

+#define MDI_PHY_ADDR            BIT_21_25       // which PHY to read/write

+#define MDI_PHY_OPCODE          BIT_26_27       // which PHY to read/write

+#define MDI_PHY_READY           BIT_28          // PHY is ready for another MDI cycle

+#define MDI_PHY_INT_ENABLE      BIT_29          // Assert INT at MDI cycle completion

+

+#define BIT_0_2     0x0007

+#define BIT_0_3     0x000F

+#define BIT_0_4     0x001F

+#define BIT_0_5     0x003F

+#define BIT_0_6     0x007F

+#define BIT_0_7     0x00FF

+#define BIT_0_8     0x01FF

+#define BIT_0_13    0x3FFF

+#define BIT_0_15    0xFFFF

+#define BIT_1_2     0x0006

+#define BIT_1_3     0x000E

+#define BIT_2_5     0x003C

+#define BIT_3_4     0x0018

+#define BIT_4_5     0x0030

+#define BIT_4_6     0x0070

+#define BIT_4_7     0x00F0

+#define BIT_5_7     0x00E0

+#define BIT_5_9     0x03E0 

+#define BIT_5_12    0x1FE0

+#define BIT_5_15    0xFFE0

+#define BIT_6_7     0x00c0

+#define BIT_7_11    0x0F80

+#define BIT_8_10    0x0700

+#define BIT_9_13    0x3E00

+#define BIT_12_15   0xF000

+

+#define BIT_16_20   0x001F0000

+#define BIT_21_25   0x03E00000

+#define BIT_26_27   0x0C000000

+

+//-------------------------------------------------------------------------

+// MDI Control register opcode definitions

+//-------------------------------------------------------------------------

+#define MDI_WRITE               1               // Phy Write

+#define MDI_READ                2               // Phy read

+

+//-------------------------------------------------------------------------

+// PHY 100 MDI Register/Bit Definitions

+//-------------------------------------------------------------------------

+// MDI register set

+#define MDI_CONTROL_REG             0x00        // MDI control register

+#define MDI_STATUS_REG              0x01        // MDI Status regiser

+#define PHY_ID_REG_1                0x02        // Phy indentification reg (word 1)

+#define PHY_ID_REG_2                0x03        // Phy indentification reg (word 2)

+#define AUTO_NEG_ADVERTISE_REG      0x04        // Auto-negotiation advertisement

+#define AUTO_NEG_LINK_PARTNER_REG   0x05        // Auto-negotiation link partner ability

+#define AUTO_NEG_EXPANSION_REG      0x06        // Auto-negotiation expansion

+#define AUTO_NEG_NEXT_PAGE_REG      0x07        // Auto-negotiation next page transmit

+#define EXTENDED_REG_0              0x10        // Extended reg 0 (Phy 100 modes)

+#define EXTENDED_REG_1              0x14        // Extended reg 1 (Phy 100 error indications)

+#define NSC_CONG_CONTROL_REG        0x17        // National (TX) congestion control

+#define NSC_SPEED_IND_REG           0x19        // National (TX) speed indication

+

+// MDI Control register bit definitions

+#define MDI_CR_COLL_TEST_ENABLE     BIT_7       // Collision test enable

+#define MDI_CR_FULL_HALF            BIT_8       // FDX =1, half duplex =0

+#define MDI_CR_RESTART_AUTO_NEG     BIT_9       // Restart auto negotiation

+#define MDI_CR_ISOLATE              BIT_10      // Isolate PHY from MII

+#define MDI_CR_POWER_DOWN           BIT_11      // Power down

+#define MDI_CR_AUTO_SELECT          BIT_12      // Auto speed select enable

+#define MDI_CR_10_100               BIT_13      // 0 = 10Mbs, 1 = 100Mbs

+#define MDI_CR_LOOPBACK             BIT_14      // 0 = normal, 1 = loopback

+#define MDI_CR_RESET                BIT_15      // 0 = normal, 1 = PHY reset

+

+// MDI Status register bit definitions

+#define MDI_SR_EXT_REG_CAPABLE      BIT_0       // Extended register capabilities

+#define MDI_SR_JABBER_DETECT        BIT_1       // Jabber detected

+#define MDI_SR_LINK_STATUS          BIT_2       // Link Status -- 1 = link

+#define MDI_SR_AUTO_SELECT_CAPABLE  BIT_3       // Auto speed select capable

+#define MDI_SR_REMOTE_FAULT_DETECT  BIT_4       // Remote fault detect

+#define MDI_SR_AUTO_NEG_COMPLETE    BIT_5       // Auto negotiation complete

+#define MDI_SR_10T_HALF_DPX         BIT_11      // 10BaseT Half Duplex capable

+#define MDI_SR_10T_FULL_DPX         BIT_12      // 10BaseT full duplex capable

+#define MDI_SR_TX_HALF_DPX          BIT_13      // TX Half Duplex capable

+#define MDI_SR_TX_FULL_DPX          BIT_14      // TX full duplex capable

+#define MDI_SR_T4_CAPABLE           BIT_15      // T4 capable

+

+// Auto-Negotiation advertisement register bit definitions

+#define NWAY_AD_SELCTOR_FIELD       BIT_0_4     // identifies supported protocol

+#define NWAY_AD_ABILITY             BIT_5_12    // technologies that are supported

+#define NWAY_AD_10T_HALF_DPX        BIT_5       // 10BaseT Half Duplex capable

+#define NWAY_AD_10T_FULL_DPX        BIT_6       // 10BaseT full duplex capable

+#define NWAY_AD_TX_HALF_DPX         BIT_7       // TX Half Duplex capable

+#define NWAY_AD_TX_FULL_DPX         BIT_8       // TX full duplex capable

+#define NWAY_AD_T4_CAPABLE          BIT_9       // T4 capable

+#define NWAY_AD_REMOTE_FAULT        BIT_13      // indicates local remote fault

+#define NWAY_AD_RESERVED            BIT_14      // reserved

+#define NWAY_AD_NEXT_PAGE           BIT_15      // Next page (not supported)

+

+// Auto-Negotiation link partner ability register bit definitions

+#define NWAY_LP_SELCTOR_FIELD       BIT_0_4     // identifies supported protocol

+#define NWAY_LP_ABILITY             BIT_5_9     // technologies that are supported

+#define NWAY_LP_REMOTE_FAULT        BIT_13      // indicates partner remote fault

+#define NWAY_LP_ACKNOWLEDGE         BIT_14      // acknowledge

+#define NWAY_LP_NEXT_PAGE           BIT_15      // Next page (not supported)

+

+// Auto-Negotiation expansion register bit definitions

+#define NWAY_EX_LP_NWAY             BIT_0       // link partner is NWAY

+#define NWAY_EX_PAGE_RECEIVED       BIT_1       // link code word received

+#define NWAY_EX_NEXT_PAGE_ABLE      BIT_2       // local is next page able

+#define NWAY_EX_LP_NEXT_PAGE_ABLE   BIT_3       // partner is next page able

+#define NWAY_EX_PARALLEL_DET_FLT    BIT_4       // parallel detection fault

+#define NWAY_EX_RESERVED            BIT_5_15    // reserved

+

+

+// PHY 100 Extended Register 0 bit definitions

+#define PHY_100_ER0_FDX_INDIC       BIT_0       // 1 = FDX, 0 = half duplex

+#define PHY_100_ER0_SPEED_INDIC     BIT_1       // 1 = 100mbs, 0= 10mbs

+#define PHY_100_ER0_WAKE_UP         BIT_2       // Wake up DAC

+#define PHY_100_ER0_RESERVED        BIT_3_4     // Reserved

+#define PHY_100_ER0_REV_CNTRL       BIT_5_7     // Revsion control (A step = 000)

+#define PHY_100_ER0_FORCE_FAIL      BIT_8       // Force Fail is enabled

+#define PHY_100_ER0_TEST            BIT_9_13    // Revsion control (A step = 000)

+#define PHY_100_ER0_LINKDIS         BIT_14      // Link integrity test is disabled

+#define PHY_100_ER0_JABDIS          BIT_15      // Jabber function is disabled

+

+

+// PHY 100 Extended Register 1 bit definitions

+#define PHY_100_ER1_RESERVED        BIT_0_8     // Reserved

+#define PHY_100_ER1_CH2_DET_ERR     BIT_9       // Channel 2 EOF detection error

+#define PHY_100_ER1_MANCH_CODE_ERR  BIT_10      // Manchester code error

+#define PHY_100_ER1_EOP_ERR         BIT_11      // EOP error

+#define PHY_100_ER1_BAD_CODE_ERR    BIT_12      // bad code error

+#define PHY_100_ER1_INV_CODE_ERR    BIT_13      // invalid code error

+#define PHY_100_ER1_DC_BAL_ERR      BIT_14      // DC balance error

+#define PHY_100_ER1_PAIR_SKEW_ERR   BIT_15      // Pair skew error

+

+// National Semiconductor TX phy congestion control register bit definitions

+#define NSC_TX_CONG_TXREADY         BIT_10      // Makes TxReady an input

+#define NSC_TX_CONG_ENABLE          BIT_8       // Enables congestion control

+#define NSC_TX_CONG_F_CONNECT       BIT_5       // Enables congestion control

+

+// National Semiconductor TX phy speed indication register bit definitions

+#define NSC_TX_SPD_INDC_SPEED       BIT_6       // 0 = 100mb, 1=10mb

+

+//-------------------------------------------------------------------------

+// Phy related constants

+//-------------------------------------------------------------------------

+#define PHY_503                 0

+#define PHY_100_A               0x000003E0

+#define PHY_100_C               0x035002A8

+#define PHY_TX_ID               0x015002A8

+#define PHY_NSC_TX              0x5c002000

+#define PHY_OTHER               0xFFFF

+

+#define PHY_MODEL_REV_ID_MASK   0xFFF0FFFF

+#define PARALLEL_DETECT         0

+#define N_WAY                   1

+

+#define RENEGOTIATE_TIME        35 // (3.5 Seconds)

+

+#define CONNECTOR_AUTO          0

+#define CONNECTOR_TPE           1

+#define CONNECTOR_MII           2

+

+//-------------------------------------------------------------------------

+

+/* The Speedo3 Rx and Tx frame/buffer descriptors. */

+#pragma pack(1)

+struct CB_Header {      /* A generic descriptor. */

+  UINT16 status;    /* Offset 0. */

+  UINT16 command;    /* Offset 2. */

+  UINT32 link;          /* struct descriptor *  */

+};

+

+/* transmit command block structure */

+#pragma pack(1)

+typedef struct s_TxCB {

+  struct CB_Header cb_header;

+  UINT32 PhysTBDArrayAddres;  /* address of an array that contains

+                physical TBD pointers */

+  UINT16 ByteCount;  /* immediate data count = 0 always */

+  UINT8 Threshold;

+  UINT8 TBDCount;

+  UINT8 ImmediateData[TX_BUFFER_SIZE];

+  /* following fields are not seen by the 82557 */

+  struct TBD {

+    UINT32 phys_buf_addr;

+    UINT32 buf_len;

+    } TBDArray[MAX_XMIT_FRAGMENTS];

+  UINT32 PhysArrayAddr;  /* in case the one in the header is lost */

+  UINT32 PhysTCBAddress;    /* for this TCB */

+  struct s_TxCB *NextTCBVirtualLinkPtr;

+  struct s_TxCB *PrevTCBVirtualLinkPtr;

+  UINT64 free_data_ptr;  // to be given to the upper layer when this xmit completes1

+}TxCB;

+

+/* The Speedo3 Rx and Tx buffer descriptors. */

+#pragma pack(1)

+typedef struct s_RxFD {          /* Receive frame descriptor. */

+  struct CB_Header cb_header;

+  UINT32 rx_buf_addr;      /* VOID * */

+  UINT16 ActualCount;

+  UINT16 RFDSize;

+  UINT8 RFDBuffer[RX_BUFFER_SIZE];

+  UINT8 forwarded;

+  UINT8 junk[3];

+}RxFD;

+

+/* Elements of the RxFD.status word. */

+#define RX_COMPLETE 0x8000

+#define RX_FRAME_OK 0x2000

+

+/* Elements of the dump_statistics block. This block must be lword aligned. */

+#pragma pack(1)

+struct speedo_stats {

+  UINT32 tx_good_frames;

+  UINT32 tx_coll16_errs;

+  UINT32 tx_late_colls;

+  UINT32 tx_underruns;

+  UINT32 tx_lost_carrier;

+  UINT32 tx_deferred;

+  UINT32 tx_one_colls;

+  UINT32 tx_multi_colls;

+  UINT32 tx_total_colls;

+  UINT32 rx_good_frames;

+  UINT32 rx_crc_errs;

+  UINT32 rx_align_errs;

+  UINT32 rx_resource_errs;

+  UINT32 rx_overrun_errs;

+  UINT32 rx_colls_errs;

+  UINT32 rx_runt_errs;

+  UINT32 done_marker;

+};

+#pragma pack()

+

+

+struct Krn_Mem{

+  RxFD rx_ring[RX_BUFFER_COUNT];

+  TxCB tx_ring[TX_BUFFER_COUNT];

+  struct speedo_stats statistics;

+};

+#define MEMORY_NEEDED  sizeof(struct Krn_Mem)

+

+/* The parameters for a CmdConfigure operation.

+   There are so many options that it would be difficult to document each bit.

+   We mostly use the default or recommended settings.

+*/

+

+/*

+ *--------------------------------------------------------------------------

+ * Configuration CB Parameter Bit Definitions

+ *--------------------------------------------------------------------------

+ */

+// - Byte 0  (Default Value = 16h)

+#define CFIG_BYTE_COUNT    0x16       // 22 Configuration Bytes

+

+//- Byte 1  (Default Value = 88h)

+#define CFIG_TXRX_FIFO_LIMIT  0x88

+

+//- Byte 2  (Default Value = 0)

+#define CFIG_ADAPTIVE_IFS    0

+

+//- Byte 3  (Default Value = 0, ALWAYS. This byte is RESERVED)

+#define CFIG_RESERVED        0

+

+//- Byte 4  (Default Value = 0. Default implies that Rx DMA cannot be

+//-          preempted).

+#define CFIG_RXDMA_BYTE_COUNT      0

+

+//- Byte 5  (Default Value = 80h. Default implies that Tx DMA cannot be

+//-          preempted. However, setting these counters is enabled.)

+#define CFIG_DMBC_ENABLE            0x80

+

+//- Byte 6  (Default Value = 33h. Late SCB enabled, No TNO interrupts,

+//-          CNA interrupts and do not save bad frames.)

+#define CFIG_LATE_SCB               1  // BIT 0

+#define CFIG_TNO_INTERRUPT          0x4  // BIT 2

+#define CFIG_CI_INTERRUPT           0x8  // BIT 3

+#define CFIG_SAVE_BAD_FRAMES        0x80  // BIT_7

+

+//- Byte 7  (Default Value = 7h. Discard short frames automatically and

+//-          attempt upto 3 retries on transmit.)

+#define CFIG_DISCARD_SHORTRX         0x00001

+#define CFIG_URUN_RETRY              BIT_1 OR BIT_2

+

+//- Byte 8  (Default Value = 1. Enable MII mode.)

+#define CFIG_503_MII              BIT_0

+

+//- Byte 9  (Default Value = 0, ALWAYS)

+

+//- Byte 10 (Default Value = 2Eh)

+#define CFIG_NSAI                   BIT_3

+#define CFIG_PREAMBLE_LENGTH         BIT_5      ;- Bit 5-4  = 1-0

+#define CFIG_NO_LOOPBACK             0

+#define CFIG_INTERNAL_LOOPBACK       BIT_6

+#define CFIG_EXT_LOOPBACK            BIT_7

+#define CFIG_EXT_PIN_LOOPBACK        BIT_6 OR BIT_7

+

+//- Byte 11 (Default Value = 0)

+#define CFIG_LINEAR_PRIORITY         0

+

+//- Byte 12 (Default Value = 60h)

+#define CFIG_LPRIORITY_MODE          0

+#define CFIG_IFS                     6          ;- 6 * 16 = 96

+

+//- Byte 13 (Default Value = 0, ALWAYS)

+

+//- Byte 14 (Default Value = 0F2h, ALWAYS)

+

+//- Byte 15 (Default Value = E8h)

+#define CFIG_PROMISCUOUS_MODE        BIT_0

+#define CFIG_BROADCAST_DISABLE       BIT_1

+#define CFIG_CRS_CDT                 BIT_7

+

+//- Byte 16 (Default Value = 0, ALWAYS)

+

+//- Byte 17 (Default Value = 40h, ALWAYS)

+

+//- Byte 18 (Default Value = F2h)

+#define CFIG_STRIPPING               BIT_0

+#define CFIG_PADDING                 BIT_1

+#define CFIG_RX_CRC_TRANSFER         BIT_2

+

+//- Byte 19 (Default Value = 80h)

+#define CFIG_FORCE_FDX               BIT_6

+#define CFIG_FDX_PIN_ENABLE          BIT_7

+

+//- Byte 20 (Default Value = 3Fh)

+#define CFIG_MULTI_IA                BIT_6

+

+//- Byte 21 (Default Value = 05)

+#define CFIG_MC_ALL                  BIT_3

+

+/*-----------------------------------------------------------------------*/

+#define D102_REVID 0x0b

+

+#define HALF_DUPLEX 1

+#define FULL_DUPLEX 2

+

+typedef struct s_data_instance {

+

+  UINT16 State;  // stopped, started or initialized

+  UINT16 Bus;

+  UINT8 Device;

+  UINT8 Function;

+  UINT16 VendorID;

+  UINT16 DeviceID;

+  UINT16 RevID;

+  UINT16 SubVendorID;

+  UINT16 SubSystemID;

+

+  UINT8 PermNodeAddress[PXE_MAC_LENGTH];

+  UINT8 CurrentNodeAddress[PXE_MAC_LENGTH];

+  UINT8 BroadcastNodeAddress[PXE_MAC_LENGTH];

+  UINT32 Config[MAX_PCI_CONFIG_LEN];

+  UINT32 NVData[MAX_EEPROM_LEN];

+

+  UINT32 ioaddr;

+  UINT32 flash_addr;

+

+  UINT16 LinkSpeed;     // actual link speed setting

+  UINT16 LinkSpeedReq;  // requested (forced) link speed

+  UINT8  DuplexReq;     // requested duplex

+  UINT8  Duplex;        // Duplex set

+  UINT8  CableDetect;   // 1 to detect and 0 not to detect the cable

+  UINT8  LoopBack;

+

+  UINT16 TxBufCnt;

+  UINT16 TxBufSize;

+  UINT16 RxBufCnt;

+  UINT16 RxBufSize;

+  UINT32 RxTotals;

+  UINT32 TxTotals;

+

+  UINT16 int_mask;

+  UINT16 Int_Status;

+  UINT16 PhyRecord[2];  // primary and secondary PHY record registers from eeprom

+  UINT8  PhyAddress;

+  UINT8  int_num;

+  UINT16 NVData_Len;

+  UINT32 MemoryLength;

+

+  RxFD *rx_ring;  // array of rx buffers

+  TxCB *tx_ring;  // array of tx buffers

+  struct speedo_stats *statistics;

+  TxCB *FreeTxHeadPtr;

+  TxCB *FreeTxTailPtr;

+  RxFD *RFDTailPtr;

+

+  UINT64 rx_phy_addr;  // physical addresses

+  UINT64 tx_phy_addr;

+  UINT64 stat_phy_addr;

+  UINT64 MemoryPtr;

+  UINT64 Mapped_MemoryPtr;

+

+  UINT64 xmit_done[TX_BUFFER_COUNT << 1]; // circular buffer

+  UINT16 xmit_done_head;  // index into the xmit_done array

+  UINT16 xmit_done_tail;  // where are we filling now (index into xmit_done)

+  UINT16 cur_rx_ind;  // current RX Q head index

+  UINT16 FreeCBCount;

+

+  BOOLEAN in_interrupt;

+  BOOLEAN in_transmit;

+  BOOLEAN Receive_Started;

+  UINT8 Rx_Filter;

+  UINT8 VersionFlag;  // UNDI30 or UNDI31??

+  UINT8 rsvd[3];

+  

+  struct mc{

+    UINT16 reserved [3]; // padding for this structure to make it 8 byte aligned

+    UINT16 list_len;

+    UINT8 mc_list[MAX_MCAST_ADDRESS_CNT][PXE_MAC_LENGTH]; // 8*32 is the size

+  } mcast_list;

+

+  UINT64 Unique_ID;

+

+  EFI_PCI_IO_PROTOCOL   *Io_Function;

+

+  VOID (*Delay_30)(UINTN);  // call back routine

+  VOID (*Virt2Phys_30)(UINT64 virtual_addr, UINT64 physical_ptr);  // call back routine

+  VOID (*Block_30)(UINT32 enable);  // call back routine

+  VOID (*Mem_Io_30)(UINT8 read_write, UINT8 len, UINT64 port, UINT64 buf_addr);

+  VOID (*Delay)(UINT64, UINTN);  // call back routine

+  VOID (*Virt2Phys)(UINT64 unq_id, UINT64 virtual_addr, UINT64 physical_ptr);  // call back routine

+  VOID (*Block)(UINT64 unq_id, UINT32 enable);  // call back routine

+  VOID (*Mem_Io)(UINT64 unq_id, UINT8 read_write, UINT8 len, UINT64 port,

+          UINT64 buf_addr);

+  VOID (*Map_Mem)(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,

+                   UINT32 Direction, UINT64 mapped_addr);

+  VOID (*UnMap_Mem)(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,

+            UINT32 Direction, UINT64 mapped_addr);

+  VOID (*Sync_Mem)(UINT64 unq_id, UINT64 virtual_addr,

+            UINT32 size, UINT32 Direction, UINT64 mapped_addr);

+} NIC_DATA_INSTANCE;

+

+#pragma pack(1)

+struct MC_CB_STRUCT{

+  UINT16 count;

+  UINT8 m_list[MAX_MCAST_ADDRESS_CNT][ETHER_MAC_ADDR_LEN];

+};

+#pragma pack()

+

+#define FOUR_GIGABYTE (UINT64)0x100000000ULL

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Init.c b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Init.c
new file mode 100644
index 0000000..70982cb
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Init.c
@@ -0,0 +1,1162 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    init.c

+

+Abstract:

+

+    Initialization functions for EFI UNDI32 driver

+

+Revision History

+

+--*/

+

+#include "undi32.h"

+

+//

+// Global Variables

+//

+PXE_SW_UNDI             *pxe = 0;     // 3.0 entry point

+PXE_SW_UNDI             *pxe_31 = 0;  // 3.1 entry

+UNDI32_DEV              *UNDI32DeviceList[MAX_NIC_INTERFACES];

+

+NII_TABLE               *UnidiDataPointer=NULL;    

+//

+// external Global Variables

+//

+extern UNDI_CALL_TABLE  api_table[];

+

+//

+// function prototypes

+//

+EFI_STATUS

+InstallConfigTable (

+  IN VOID

+  );

+

+EFI_STATUS

+EFIAPI

+InitializeUNDIDriver (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+VOID

+UNDI_notify_virtual (

+  EFI_EVENT event,

+  VOID      *context

+  );

+

+VOID

+EFIAPI

+UndiNotifyExitBs (

+  EFI_EVENT Event,

+  VOID      *Context

+  );

+

+EFI_STATUS

+EFIAPI

+UndiDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+UndiDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+UndiDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+EFI_STATUS

+AppendMac2DevPath (

+  IN OUT  EFI_DEVICE_PATH_PROTOCOL **DevPtr,

+  IN      EFI_DEVICE_PATH_PROTOCOL *BaseDevPtr,

+  IN      NIC_DATA_INSTANCE        *AdapterInfo

+  );

+//

+// end function prototypes

+//

+VOID

+EFIAPI

+UndiNotifyVirtual (

+  EFI_EVENT Event,

+  VOID      *Context

+  )

+/*++

+

+Routine Description:

+

+  When address mapping changes to virtual this should make the appropriate

+  address conversions.

+

+Arguments:

+

+  (Standard Event handler)

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Context - add argument and description to function comment

+{

+  UINT16  Index;

+  VOID    *Pxe31Pointer;

+

+  if (pxe_31 != NULL) {

+    Pxe31Pointer = (VOID *) pxe_31;

+

+    EfiConvertPointer (

+      EFI_OPTIONAL_POINTER,

+      (void **) &Pxe31Pointer

+      );

+

+    //

+    // UNDI32DeviceList is an array of pointers

+    //

+    for (Index = 0; Index < pxe_31->IFcnt; Index++) {

+      UNDI32DeviceList[Index]->NIIProtocol_31.ID = (UINT64) (UINTN) Pxe31Pointer;

+      EfiConvertPointer (

+        EFI_OPTIONAL_POINTER,

+        (void **) &(UNDI32DeviceList[Index])

+        );

+    }

+

+    EfiConvertPointer (

+      EFI_OPTIONAL_POINTER,

+      (void **) &(pxe_31->EntryPoint)

+      );

+    pxe_31 = Pxe31Pointer;

+  }

+

+  for (Index = 0; Index <= PXE_OPCODE_LAST_VALID; Index++) {

+    EfiConvertPointer (

+      EFI_OPTIONAL_POINTER,

+      (void **) &api_table[Index].api_ptr

+      );

+  }

+}

+

+VOID

+EFIAPI

+UndiNotifyExitBs (

+  EFI_EVENT Event,

+  VOID      *Context

+  )

+/*++

+

+Routine Description:

+

+  When EFI is shuting down the boot services, we need to install a 

+  configuration table for UNDI to work at runtime!

+

+Arguments:

+

+  (Standard Event handler)

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Context - add argument and description to function comment

+{

+  InstallConfigTable ();

+}

+//

+// UNDI Class Driver Global Variables

+//

+EFI_DRIVER_BINDING_PROTOCOL  gUndiDriverBinding = {

+  UndiDriverSupported,

+  UndiDriverStart,

+  UndiDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+InitializeUNDIDriver (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Register Driver Binding protocol for this driver.

+

+Arguments:

+

+  ImageHandle - Image Handle

+  

+  SystemTable - Pointer to system table

+

+Returns:

+

+  EFI_SUCCESS - Driver loaded.

+  

+  other       - Driver not loaded.

+

+--*/

+{

+  EFI_STATUS  Status;

+  EFI_EVENT   Event;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,

+                  EFI_TPL_NOTIFY,

+                  UndiNotifyExitBs,

+                  NULL,

+                  &Event

+                  );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+UndiDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Test to see if this driver supports ControllerHandle. Any ControllerHandle

+  than contains a  DevicePath, PciIo protocol, Class code of 2, Vendor ID of 0x8086,

+  and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID || ICH3_DEVICE_ID_1 ||

+  ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 || ICH3_DEVICE_ID_5 ||

+  ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be supported.

+

+Arguments:

+

+  This                - Protocol instance pointer.

+  

+  Controller          - Handle of device to test.

+  

+  RemainingDevicePath - Not used.

+

+Returns:

+

+  EFI_SUCCESS         - This driver supports this device.

+  

+  other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  PCI_TYPE00          Pci;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint8,

+                        0,

+                        sizeof (PCI_CONFIG_HEADER),

+                        &Pci

+                        );

+

+  if (!EFI_ERROR (Status)) {

+    Status = EFI_UNSUPPORTED;

+

+    if (Pci.Hdr.ClassCode[2] == 0x02 && Pci.Hdr.VendorId == PCI_VENDOR_ID_INTEL) {

+      switch (Pci.Hdr.DeviceId) {

+      case D100_DEVICE_ID:

+      case D102_DEVICE_ID:

+      case ICH3_DEVICE_ID_1:

+      case ICH3_DEVICE_ID_2:

+      case ICH3_DEVICE_ID_3:

+      case ICH3_DEVICE_ID_4:

+      case ICH3_DEVICE_ID_5:

+      case ICH3_DEVICE_ID_6:

+      case ICH3_DEVICE_ID_7:

+      case ICH3_DEVICE_ID_8:

+      case 0x1039:

+      case 0x103A:

+      case 0x103B:

+      case 0x103C:

+      case 0x103D:

+      case 0x103E:

+      case 0x1050:

+      case 0x1051:

+      case 0x1052:

+      case 0x1053:

+      case 0x1054:

+      case 0x1055:

+      case 0x1056:

+      case 0x1057:

+      case 0x1059:

+      case 0x1064:

+        Status = EFI_SUCCESS;

+      }

+    }

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+UndiDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Start this driver on Controller by opening PciIo and DevicePath protocol.

+  Initialize PXE structures, create a copy of the Controller Device Path with the

+  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol

+  on the newly created Device Path.

+

+Arguments:

+

+  This                - Protocol instance pointer.

+  

+  Controller          - Handle of device to work with.

+  

+  RemainingDevicePath - Not used, always produce all possible children.

+

+Returns:

+

+  EFI_SUCCESS         - This driver is added to Controller.

+  

+  other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *UndiDevicePath;

+  PCI_CONFIG_HEADER         *CfgHdr;

+  UNDI32_DEV                *UNDI32Device;

+  UINT16                    NewCommand;

+  UINT8                     *TmpPxePointer;

+  EFI_PCI_IO_PROTOCOL       *PciIoFncs;

+  UINTN                     Len;   

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIoFncs,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &UndiDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    return Status;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  sizeof (UNDI32_DEV),

+                  (VOID **) &UNDI32Device

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto UndiError;

+  }

+

+  ZeroMem ((CHAR8 *) UNDI32Device, sizeof (UNDI32_DEV));

+

+  //

+  // allocate and initialize both (old and new) the !pxe structures here,

+  // there should only be one copy of each of these structure for any number

+  // of NICs this undi supports. Also, these structures need to be on a

+  // paragraph boundary as per the spec. so, while allocating space for these,

+  // make sure that there is space for 2 !pxe structures (old and new) and a

+  // 32 bytes padding for alignment adjustment (in case)

+  //

+  TmpPxePointer = NULL;

+  if (pxe_31 == NULL) {

+    Status = gBS->AllocatePool (

+                    EfiRuntimeServicesData,

+                    (sizeof (PXE_SW_UNDI) + sizeof (PXE_SW_UNDI) + 32),

+                    (VOID **) &TmpPxePointer

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto UndiErrorDeleteDevice;

+    }

+

+    ZeroMem (

+      TmpPxePointer,

+      sizeof (PXE_SW_UNDI) + sizeof (PXE_SW_UNDI) + 32

+      );

+    //

+    // check for paragraph alignment here, assuming that the pointer is

+    // already 8 byte aligned.

+    //

+    if (((UINTN) TmpPxePointer & 0x0F) != 0) {

+      pxe_31 = (PXE_SW_UNDI *) ((UINTN) (TmpPxePointer + 8));

+    } else {

+      pxe_31 = (PXE_SW_UNDI *) TmpPxePointer;

+    }

+    //

+    // assuming that the sizeof pxe_31 is a 16 byte multiple

+    //

+    pxe = (PXE_SW_UNDI *) ((CHAR8 *) (pxe_31) + sizeof (PXE_SW_UNDI));

+

+    PxeStructInit (pxe, 0x30);

+    PxeStructInit (pxe_31, 0x31);

+  }

+

+  UNDI32Device->NIIProtocol.ID    = (UINT64) (UINTN) (pxe);

+  UNDI32Device->NIIProtocol_31.ID = (UINT64) (UINTN) (pxe_31);

+

+  Status = PciIoFncs->Attributes (

+                        PciIoFncs,

+                        EfiPciIoAttributeOperationEnable,

+                        EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,

+                        NULL

+                        );

+  //

+  // Read all the registers from device's PCI Configuration space

+  //

+  Status = PciIoFncs->Pci.Read (

+                            PciIoFncs,

+                            EfiPciIoWidthUint32,

+                            0,

+                            MAX_PCI_CONFIG_LEN,

+                            &UNDI32Device->NicInfo.Config

+                            );

+

+  CfgHdr = (PCI_CONFIG_HEADER *) &(UNDI32Device->NicInfo.Config[0]);

+

+  //

+  // make sure that this device is a PCI bus master

+  //

+

+  NewCommand = (UINT16) (CfgHdr->Command | PCI_COMMAND_MASTER | PCI_COMMAND_IO);

+  if (CfgHdr->Command != NewCommand) {

+    PciIoFncs->Pci.Write (

+                    PciIoFncs,

+                    EfiPciIoWidthUint16,

+                    PCI_COMMAND,

+                    1,

+                    &NewCommand

+                    );

+    CfgHdr->Command = NewCommand;

+  }

+

+  //

+  // make sure that the latency timer is at least 32

+  //

+  if (CfgHdr->LatencyTimer < 32) {

+    CfgHdr->LatencyTimer = 32;

+    PciIoFncs->Pci.Write (

+                    PciIoFncs,

+                    EfiPciIoWidthUint8,

+                    PCI_LATENCY_TIMER,

+                    1,

+                    &CfgHdr->LatencyTimer

+                    );

+  }

+  //

+  // the IfNum index for the current interface will be the total number

+  // of interfaces initialized so far

+  //

+  UNDI32Device->NIIProtocol.IfNum     = pxe->IFcnt;

+  UNDI32Device->NIIProtocol_31.IfNum  = pxe_31->IFcnt;

+

+  PxeUpdate (&UNDI32Device->NicInfo, pxe);

+  PxeUpdate (&UNDI32Device->NicInfo, pxe_31);

+

+  UNDI32Device->NicInfo.Io_Function                 = PciIoFncs;

+  UNDI32DeviceList[UNDI32Device->NIIProtocol.IfNum] = UNDI32Device;

+  UNDI32Device->Undi32BaseDevPath                   = UndiDevicePath;

+

+  Status = AppendMac2DevPath (

+            &UNDI32Device->Undi32DevPath,

+            UNDI32Device->Undi32BaseDevPath,

+            &UNDI32Device->NicInfo

+            );

+

+  if (Status != 0) {

+    goto UndiErrorDeletePxe;

+  }

+

+  UNDI32Device->Signature                     = UNDI_DEV_SIGNATURE;

+

+  UNDI32Device->NIIProtocol.Revision          = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;

+  UNDI32Device->NIIProtocol.Type              = EfiNetworkInterfaceUndi;

+  UNDI32Device->NIIProtocol.MajorVer          = PXE_ROMID_MAJORVER;

+  UNDI32Device->NIIProtocol.MinorVer          = PXE_ROMID_MINORVER;

+  UNDI32Device->NIIProtocol.ImageSize         = 0;

+  UNDI32Device->NIIProtocol.ImageAddr         = 0;

+  UNDI32Device->NIIProtocol.Ipv6Supported     = FALSE;

+

+  UNDI32Device->NIIProtocol.StringId[0]       = 'U';

+  UNDI32Device->NIIProtocol.StringId[1]       = 'N';

+  UNDI32Device->NIIProtocol.StringId[2]       = 'D';

+  UNDI32Device->NIIProtocol.StringId[3]       = 'I';

+

+  UNDI32Device->NIIProtocol_31.Revision       = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31;

+  UNDI32Device->NIIProtocol_31.Type           = EfiNetworkInterfaceUndi;

+  UNDI32Device->NIIProtocol_31.MajorVer       = PXE_ROMID_MAJORVER;

+  UNDI32Device->NIIProtocol_31.MinorVer       = PXE_ROMID_MINORVER_31;

+  UNDI32Device->NIIProtocol_31.ImageSize      = 0;

+  UNDI32Device->NIIProtocol_31.ImageAddr      = 0;

+  UNDI32Device->NIIProtocol_31.Ipv6Supported  = FALSE;

+

+  UNDI32Device->NIIProtocol_31.StringId[0]    = 'U';

+  UNDI32Device->NIIProtocol_31.StringId[1]    = 'N';

+  UNDI32Device->NIIProtocol_31.StringId[2]    = 'D';

+  UNDI32Device->NIIProtocol_31.StringId[3]    = 'I';

+

+  UNDI32Device->DeviceHandle                  = NULL;

+

+  //

+  // install both the 3.0 and 3.1 NII protocols.

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &UNDI32Device->DeviceHandle,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                  &UNDI32Device->NIIProtocol_31,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                  &UNDI32Device->NIIProtocol,

+                  &gEfiDevicePathProtocolGuid,

+                  UNDI32Device->Undi32DevPath,

+                  NULL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto UndiErrorDeleteDevicePath;

+  }

+

+  //

+  // if the table exists, free it and alloc again, or alloc it directly 

+  //

+  if (UnidiDataPointer != NULL) {

+  	Status = gBS->FreePool(UnidiDataPointer);

+  }

+  if (EFI_ERROR (Status)) {

+    goto UndiErrorDeleteDevicePath;

+  }

+

+  Len = (pxe_31->IFcnt * sizeof (NII_ENTRY)) + sizeof (UnidiDataPointer);

+  Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **) &UnidiDataPointer);

+

+  if (EFI_ERROR (Status)) {

+    goto UndiErrorAllocDataPointer;

+  }

+  

+  //

+  // Open For Child Device

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIoFncs,

+                  This->DriverBindingHandle,

+                  UNDI32Device->DeviceHandle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+

+  return EFI_SUCCESS;

+UndiErrorAllocDataPointer:

+  gBS->UninstallMultipleProtocolInterfaces (

+                  &UNDI32Device->DeviceHandle,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                  &UNDI32Device->NIIProtocol_31,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                  &UNDI32Device->NIIProtocol,

+                  &gEfiDevicePathProtocolGuid,

+                  UNDI32Device->Undi32DevPath,

+                  NULL

+                  );

+

+UndiErrorDeleteDevicePath:

+  UNDI32DeviceList[UNDI32Device->NIIProtocol.IfNum] = NULL;

+  gBS->FreePool (UNDI32Device->Undi32DevPath);

+

+UndiErrorDeletePxe:

+  PxeUpdate (NULL, pxe);

+  PxeUpdate (NULL, pxe_31);

+  if (TmpPxePointer != NULL) {

+    gBS->FreePool (TmpPxePointer);

+

+  }

+

+UndiErrorDeleteDevice:

+  gBS->FreePool (UNDI32Device);

+

+UndiError:

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+UndiDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and

+  closing the DevicePath and PciIo protocols on Controller.

+

+Arguments:

+  This              - Protocol instance pointer.

+  Controller        - Handle of device to stop driver on.

+  NumberOfChildren  - How many children need to be stopped.

+  ChildHandleBuffer - Not used.

+

+Returns:

+  EFI_SUCCESS       - This driver is removed Controller.

+  other             - This driver was not removed from this device.

+

+--*/

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  EFI_STATUS                                Status;

+  BOOLEAN                                   AllChildrenStopped;

+  UINTN                                     Index;

+  UNDI32_DEV                                *UNDI32Device;

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NIIProtocol;

+  EFI_PCI_IO_PROTOCOL                       *PciIo;

+

+  //

+  // Complete all outstanding transactions to Controller.

+  // Don't allow any new transaction to Controller to be started.

+  //

+  if (NumberOfChildren == 0) {

+

+    //

+    // Close the bus driver

+    //

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiDevicePathProtocolGuid,

+                    This->DriverBindingHandle,

+                    Controller

+                    );

+

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiPciIoProtocolGuid,

+                    This->DriverBindingHandle,

+                    Controller

+                    );

+

+    return Status;

+  }

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+

+    Status = gBS->OpenProtocol (

+                    ChildHandleBuffer[Index],

+                    &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                    (VOID **) &NIIProtocol,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+

+      UNDI32Device = UNDI_DEV_FROM_THIS (NIIProtocol);

+

+      Status = gBS->CloseProtocol (

+                      Controller,

+                      &gEfiPciIoProtocolGuid,

+                      This->DriverBindingHandle,

+                      ChildHandleBuffer[Index]

+                      );

+

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      ChildHandleBuffer[Index],

+                      &gEfiDevicePathProtocolGuid,

+                      UNDI32Device->Undi32DevPath,

+                      &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                      &UNDI32Device->NIIProtocol_31,

+                      &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                      &UNDI32Device->NIIProtocol,

+                      NULL

+                      );

+

+      if (EFI_ERROR (Status)) {

+        gBS->OpenProtocol (

+              Controller,

+              &gEfiPciIoProtocolGuid,

+              (VOID **) &PciIo,

+              This->DriverBindingHandle,

+              ChildHandleBuffer[Index],

+              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+              );

+      } else {

+        gBS->FreePool (UNDI32Device->Undi32DevPath);

+        gBS->FreePool (UNDI32Device);

+      }

+    }

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+VOID

+TmpDelay (

+  IN UINT64 UnqId,

+  IN UINTN  MicroSeconds

+  )

+/*++

+

+Routine Description:

+

+  Use the EFI boot services to produce a pause. This is also the routine which

+  gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can

+  do it's own pause.

+

+Arguments:

+

+  UnqId             - Runtime O/S routine might use this, this temp routine does not use it

+  

+  MicroSeconds      - Determines the length of pause.

+

+Returns:

+

+  none

+

+--*/

+{

+  gBS->Stall ((UINT32) MicroSeconds);

+}

+

+VOID

+TmpMemIo (

+  IN UINT64 UnqId,

+  IN UINT8  ReadWrite,

+  IN UINT8  Len,

+  IN UINT64 Port,

+  IN UINT64 BuffAddr

+  )

+/*++

+

+Routine Description:

+

+  Use the PCI IO abstraction to issue memory or I/O reads and writes.  This is also the routine which

+  gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.

+

+Arguments:

+

+  UnqId             - Runtime O/S routine may use this field, this temp routine does not.

+  

+  ReadWrite         - Determine if it is an I/O or Memory Read/Write Operation.

+  

+  Len               - Determines the width of the data operation.

+  

+  Port              - What port to Read/Write from.

+  

+  BuffAddr          - Address to read to or write from.

+

+Returns:

+

+  none

+

+--*/

+{

+  EFI_PCI_IO_PROTOCOL_WIDTH Width;

+  NIC_DATA_INSTANCE         *AdapterInfo;

+

+  Width       = 0;

+  AdapterInfo = (NIC_DATA_INSTANCE *) (UINTN) UnqId;

+  switch (Len) {

+  case 2:

+    Width = 1;

+    break;

+

+  case 4:

+    Width = 2;

+    break;

+

+  case 8:

+    Width = 3;

+    break;

+  }

+

+  switch (ReadWrite) {

+  case PXE_IO_READ:

+    AdapterInfo->Io_Function->Io.Read (

+                                  AdapterInfo->Io_Function,

+                                  Width,

+                                  1,

+                                  Port,

+                                  1,

+                                  (VOID *) (UINTN) (BuffAddr)

+                                  );

+    break;

+

+  case PXE_IO_WRITE:

+    AdapterInfo->Io_Function->Io.Write (

+                                  AdapterInfo->Io_Function,

+                                  Width,

+                                  1,

+                                  Port,

+                                  1,

+                                  (VOID *) (UINTN) (BuffAddr)

+                                  );

+    break;

+

+  case PXE_MEM_READ:

+    AdapterInfo->Io_Function->Mem.Read (

+                                    AdapterInfo->Io_Function,

+                                    Width,

+                                    0,

+                                    Port,

+                                    1,

+                                    (VOID *) (UINTN) (BuffAddr)

+                                    );

+    break;

+

+  case PXE_MEM_WRITE:

+    AdapterInfo->Io_Function->Mem.Write (

+                                    AdapterInfo->Io_Function,

+                                    Width,

+                                    0,

+                                    Port,

+                                    1,

+                                    (VOID *) (UINTN) (BuffAddr)

+                                    );

+    break;

+  }

+

+  return ;

+}

+

+EFI_STATUS

+AppendMac2DevPath (

+  IN OUT  EFI_DEVICE_PATH_PROTOCOL **DevPtr,

+  IN      EFI_DEVICE_PATH_PROTOCOL *BaseDevPtr,

+  IN      NIC_DATA_INSTANCE        *AdapterInfo

+  )

+/*++

+

+Routine Description:

+

+  Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space

+  for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)

+  and an added MAC node.

+

+Arguments:

+

+  DevPtr            - Pointer which will point to the newly created device path with the MAC node attached.

+  

+  BaseDevPtr        - Pointer to the device path which the UNDI device driver is latching on to.

+  

+  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

+

+Returns:

+

+  EFI_SUCCESS       - A MAC address was successfully appended to the Base Device Path.

+  

+  other             - Not enough resources available to create new Device Path node.

+

+--*/

+{

+  EFI_MAC_ADDRESS           MACAddress;

+  PCI_CONFIG_HEADER         *CfgHdr;

+  INT32                     Val;

+  INT32                     Index;

+  INT32                     Index2;

+  UINT8                     AddrLen;

+  MAC_ADDR_DEVICE_PATH      MacAddrNode;

+  EFI_DEVICE_PATH_PROTOCOL  *EndNode;

+  UINT8                     *DevicePtr;

+  UINT16                    TotalPathLen;

+  UINT16                    BasePathLen;

+  EFI_STATUS                Status;

+

+  //

+  // set the environment ready (similar to UNDI_Start call) so that we can

+  // execute the other UNDI_ calls to get the mac address

+  // we are using undi 3.1 style

+  //

+  AdapterInfo->Delay      = TmpDelay;

+  AdapterInfo->Virt2Phys  = (VOID *) 0;

+  AdapterInfo->Block      = (VOID *) 0;

+  AdapterInfo->Map_Mem    = (VOID *) 0;

+  AdapterInfo->UnMap_Mem  = (VOID *) 0;

+  AdapterInfo->Sync_Mem   = (VOID *) 0;

+  AdapterInfo->Mem_Io     = TmpMemIo;

+  //

+  // these tmp call-backs follow 3.1 undi style

+  // i.e. they have the unique_id parameter.

+  //

+  AdapterInfo->VersionFlag  = 0x31;

+  AdapterInfo->Unique_ID    = (UINT64) (UINTN) AdapterInfo;

+

+  //

+  // undi init portion

+  //

+  CfgHdr              = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);

+  AdapterInfo->ioaddr = 0;

+  AdapterInfo->RevID  = CfgHdr->RevID;

+

+  AddrLen             = E100bGetEepromAddrLen (AdapterInfo);

+

+  for (Index = 0, Index2 = 0; Index < 3; Index++) {

+    Val                       = E100bReadEeprom (AdapterInfo, Index, AddrLen);

+    MACAddress.Addr[Index2++] = (UINT8) Val;

+    MACAddress.Addr[Index2++] = (UINT8) (Val >> 8);

+  }

+

+  SetMem (MACAddress.Addr + Index2, sizeof (EFI_MAC_ADDRESS) - Index2, 0);

+  //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {

+  //  MACAddress.Addr[Index2] = 0;

+  //}

+  //

+  // stop undi

+  //

+  AdapterInfo->Delay  = (VOID *) 0;

+  AdapterInfo->Mem_Io = (VOID *) 0;

+

+  //

+  // fill the mac address node first

+  //

+  ZeroMem ((CHAR8 *) &MacAddrNode, sizeof MacAddrNode);

+  CopyMem (

+    (CHAR8 *) &MacAddrNode.MacAddress,

+    (CHAR8 *) &MACAddress,

+    sizeof (EFI_MAC_ADDRESS)

+    );

+

+  MacAddrNode.Header.Type       = MESSAGING_DEVICE_PATH;

+  MacAddrNode.Header.SubType    = MSG_MAC_ADDR_DP;

+  MacAddrNode.Header.Length[0]  = sizeof (MacAddrNode);

+  MacAddrNode.Header.Length[1]  = 0;

+

+  //

+  // find the size of the base dev path.

+  //

+  EndNode = BaseDevPtr;

+

+  while (!IsDevicePathEnd (EndNode)) {

+    EndNode = NextDevicePathNode (EndNode);

+  }

+

+  BasePathLen = (UINT16) ((UINTN) (EndNode) - (UINTN) (BaseDevPtr));

+

+  //

+  // create space for full dev path

+  //

+  TotalPathLen = (UINT16) (BasePathLen + sizeof (MacAddrNode) + sizeof (EFI_DEVICE_PATH_PROTOCOL));

+

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  TotalPathLen,

+                  (VOID **) &DevicePtr

+                  );

+

+  if (Status != EFI_SUCCESS) {

+    return Status;

+  }

+  //

+  // copy the base path, mac addr and end_dev_path nodes

+  //

+  *DevPtr = (EFI_DEVICE_PATH_PROTOCOL *) DevicePtr;

+  CopyMem (DevicePtr, (CHAR8 *) BaseDevPtr, BasePathLen);

+  DevicePtr += BasePathLen;

+  CopyMem (DevicePtr, (CHAR8 *) &MacAddrNode, sizeof (MacAddrNode));

+  DevicePtr += sizeof (MacAddrNode);

+  CopyMem (DevicePtr, (CHAR8 *) EndNode, sizeof (EFI_DEVICE_PATH_PROTOCOL));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InstallConfigTable (

+  IN VOID

+  )

+/*++

+

+Routine Description:

+

+  Install a GUID/Pointer pair into the system's configuration table.

+

+Arguments:

+

+  none

+

+Returns:

+

+  EFI_SUCCESS       - Install a GUID/Pointer pair into the system's configuration table.

+  

+  other             - Did not successfully install the GUID/Pointer pair into the configuration table.

+

+--*/

+// TODO:    VOID - add argument and description to function comment

+{

+  EFI_STATUS              Status;

+  EFI_CONFIGURATION_TABLE *CfgPtr;

+  NII_TABLE               *TmpData;

+  UINT16                  Index;

+  NII_TABLE               *UndiData;

+

+  if (pxe_31 == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  if(UnidiDataPointer == NULL) { 

+  	return EFI_SUCCESS;

+  }

+  

+  UndiData = (NII_TABLE *)UnidiDataPointer;  

+  

+  UndiData->NumEntries  = pxe_31->IFcnt;

+  UndiData->NextLink    = NULL;

+

+  for (Index = 0; Index < pxe_31->IFcnt; Index++) {

+    UndiData->NiiEntry[Index].InterfacePointer  = &UNDI32DeviceList[Index]->NIIProtocol_31;

+    UndiData->NiiEntry[Index].DevicePathPointer = UNDI32DeviceList[Index]->Undi32DevPath;

+  }

+

+  //

+  // see if there is an entry in the config table already

+  //

+  CfgPtr = gST->ConfigurationTable;

+

+  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {

+    Status = CompareGuid (

+              &CfgPtr->VendorGuid,

+              &gEfiNetworkInterfaceIdentifierProtocolGuid_31

+              );

+    if (Status != EFI_SUCCESS) {

+      break;

+    }

+

+    CfgPtr++;

+  }

+

+  if (Index < gST->NumberOfTableEntries) {

+    TmpData = (NII_TABLE *) CfgPtr->VendorTable;

+

+    //

+    // go to the last link

+    //

+    while (TmpData->NextLink != NULL) {

+      TmpData = TmpData->NextLink;

+    }

+

+    TmpData->NextLink = UndiData;

+

+    //

+    // 1st one in chain

+    //

+    UndiData = (NII_TABLE *) CfgPtr->VendorTable;

+  }

+

+  //

+  // create an entry in the configuration table for our GUID

+  //

+  Status = gBS->InstallConfigurationTable (

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                  UndiData

+                  );

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi.mbd b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi.mbd
new file mode 100644
index 0000000..d486d63
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi.mbd
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Undi</BaseName>

+    <Guid>A1f436EA-A127-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibNull</Library>

+    <Library>BasePrintLib</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Arch ArchType="IPF">

+      <Library>EdkDxeSalLib</Library>

+    </Arch>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi.msa b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi.msa
new file mode 100644
index 0000000..f68ca87
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi.msa
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Undi</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>A1f436EA-A127-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Init.c</Filename>

+    <Filename>Decode.c</Filename>

+    <Filename>E100b.c</Filename>

+    <Filename>E100b.h</Filename>

+    <Filename>Undi32.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">PciIo</Protocol>

+    <Protocol Usage="BY_START">NetworkInterfaceIdentifier</Protocol>

+    <Protocol Usage="BY_START">NetworkInterfaceIdentifier31</Protocol>

+  </Protocols>

+  <Events>

+    <CreateEvents>

+      <Event Usage="ALWAYS_CONSUMED" EventGroup="EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE">

+        <C_Name>gEfiEventVirtualAddressChangeGuid</C_Name>

+        <Guid>0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96</Guid>

+      </Event>

+      <Event Usage="ALWAYS_CONSUMED" EventGroup="EVENT_GROUP_EXIT_BOOT_SERVICES">

+        <C_Name>gEfiEventExitBootServicesGuid</C_Name>

+        <Guid>0x27abf055, 0xb1b8, 0x4c26, 0x80, 0x48, 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf</Guid>

+      </Event>

+    </CreateEvents>

+  </Events>

+  <SystemTables>

+    <SystemTable Usage="SOMETIMES_PRODUCED">

+      <Entry>gEfiNetworkInterfaceIdentifierProtocolGuid_31</Entry>

+    </SystemTable>

+  </SystemTables>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeUNDIDriver</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUndiDriverBinding</DriverBinding>

+    </Extern>

+    <Extern>

+      <SetVirtualAddressMapCallBack>UndiNotifyVirtual</SetVirtualAddressMapCallBack>

+      <ExitBootServicesCallBack></ExitBootServicesCallBack>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi32.h b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi32.h
new file mode 100644
index 0000000..73e1151
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/Undi32.h
@@ -0,0 +1,208 @@
+

+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    undi32.h

+

+Abstract:

+

+    EFI internal structures for the EFI UNDI driver

+

+

+

+Revision History

+

+--*/

+

+#ifndef _UNDI_32_H_

+#define _UNDI_32_H_

+

+

+#include "E100b.h"

+#include <IndustryStandard/pci22.h>

+

+#define MAX_NIC_INTERFACES 16

+

+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31 0x00010001

+#define PXE_ROMID_MINORVER_31 0x10

+#define PXE_STATFLAGS_DB_WRITE_TRUNCATED  0x2000

+

+//

+// UNDI_CALL_TABLE.state can have the following values

+//

+#define DONT_CHECK -1

+#define ANY_STATE -1

+#define MUST_BE_STARTED 1

+#define MUST_BE_INITIALIZED 2

+

+#define UNDI_DEV_SIGNATURE   EFI_SIGNATURE_32('u','n','d','i')

+#define UNDI_DEV_FROM_THIS(a) CR(a, UNDI32_DEV, NIIProtocol, UNDI_DEV_SIGNATURE)

+#define UNDI_DEV_FROM_NIC(a) CR(a, UNDI32_DEV, NicInfo, UNDI_DEV_SIGNATURE)

+

+typedef struct {

+  UINTN                                     Signature;

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL NIIProtocol;

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL NIIProtocol_31;

+  EFI_HANDLE                                DeviceHandle;

+  EFI_DEVICE_PATH_PROTOCOL                  *Undi32BaseDevPath;

+  EFI_DEVICE_PATH_PROTOCOL                  *Undi32DevPath;

+  NIC_DATA_INSTANCE                         NicInfo;

+} UNDI32_DEV;

+

+typedef struct {

+  UINT16 cpbsize;

+  UINT16 dbsize;

+  UINT16 opflags;

+  UINT16 state;

+  VOID (*api_ptr)();

+} UNDI_CALL_TABLE;

+

+typedef struct {

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *InterfacePointer;

+  EFI_DEVICE_PATH_PROTOCOL                  *DevicePathPointer;

+} NII_ENTRY;

+

+typedef struct NII_CONFIG_ENTRY {

+  UINT32                   NumEntries;

+  UINT32                   Reserved;              // padding for alignment

+  struct NII_CONFIG_ENTRY  *NextLink;

+  NII_ENTRY                NiiEntry[1];

+} NII_TABLE;

+

+typedef VOID (*ptr)(VOID);

+typedef VOID (*bsptr_30)(UINTN);

+typedef VOID (*virtphys_30)(UINT64, UINT64);

+typedef VOID (*block_30)(UINT32);

+typedef VOID (*mem_io_30)(UINT8, UINT8, UINT64, UINT64);

+

+typedef VOID (*bsptr)(UINT64, UINTN);

+typedef VOID (*virtphys)(UINT64, UINT64, UINT64);

+typedef VOID (*block)(UINT64, UINT32);

+typedef VOID (*mem_io)(UINT64, UINT8, UINT8, UINT64, UINT64);

+

+typedef VOID (*map_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);

+typedef VOID (*unmap_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);

+typedef VOID (*sync_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);

+

+//

+// functions defined in e100b.c

+//

+UINT8 InByte (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);

+UINT16 InWord (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);

+UINT32 InLong (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);

+VOID  OutByte (NIC_DATA_INSTANCE *AdapterInfo, UINT8 Data, UINT32 Port);

+VOID  OutWord (NIC_DATA_INSTANCE *AdapterInfo, UINT16 Data, UINT32 Port);

+VOID  OutLong (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Data, UINT32 Port);

+

+UINTN E100bInit (NIC_DATA_INSTANCE *AdapterInfo);

+UINTN E100bReset (NIC_DATA_INSTANCE *AdapterInfo, INT32 OpFlags);

+UINTN E100bShutdown (NIC_DATA_INSTANCE *AdapterInfo);

+UINTN E100bTransmit (NIC_DATA_INSTANCE *AdapterInfo, UINT64 cpb, UINT16 opflags);

+UINTN E100bReceive (NIC_DATA_INSTANCE *AdapterInfo, UINT64 cpb, UINT64 db);

+UINTN E100bSetfilter (NIC_DATA_INSTANCE *AdapterInfo, UINT16 New_filter,

+                      UINT64 cpb, UINT32 cpbsize);

+UINTN E100bStatistics(NIC_DATA_INSTANCE *AdapterInfo, UINT64 db, UINT16 dbsize);

+UINT8 E100bSetupIAAddr (NIC_DATA_INSTANCE *AdapterInfo);

+UINT8 E100bSetInterruptState (NIC_DATA_INSTANCE *AdapterInfo);

+

+UINT8 E100bGetEepromAddrLen (NIC_DATA_INSTANCE *AdapterInfo);

+UINT16 E100bReadEeprom (NIC_DATA_INSTANCE *AdapterInfo, INT32 Location, UINT8 address_len);

+INT16 E100bReadEepromAndStationAddress (NIC_DATA_INSTANCE *AdapterInfo);

+

+UINT16 next(UINT16);

+UINT8 SetupCBlink (NIC_DATA_INSTANCE *AdapterInfo);

+VOID SetFreeCB (NIC_DATA_INSTANCE *AdapterInfo,TxCB *);

+TxCB *GetFreeCB (NIC_DATA_INSTANCE *AdapterInfo);

+UINT16 CheckCBList (NIC_DATA_INSTANCE *AdapterInfo);

+

+UINT8 SelectiveReset (NIC_DATA_INSTANCE *AdapterInfo);

+UINT16 InitializeChip (NIC_DATA_INSTANCE *AdapterInfo);

+UINT8 SetupReceiveQueues (NIC_DATA_INSTANCE *AdapterInfo);

+VOID  Recycle_RFD (NIC_DATA_INSTANCE *AdapterInfo, UINT16);

+VOID XmitWaitForCompletion (NIC_DATA_INSTANCE *AdapterInfo);

+INT8 CommandWaitForCompletion (TxCB *cmd_ptr, NIC_DATA_INSTANCE *AdapterInfo);

+

+BOOLEAN PhyDetect (NIC_DATA_INSTANCE *AdapterInfo);

+VOID PhyReset (NIC_DATA_INSTANCE *AdapterInfo);

+VOID

+MdiWrite (

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT8 RegAddress, 

+  IN UINT8 PhyAddress,

+  IN UINT16 DataValue

+  );

+

+VOID

+MdiRead(

+  IN NIC_DATA_INSTANCE *AdapterInfo,

+  IN UINT8 RegAddress, 

+  IN UINT8 PhyAddress,

+  IN OUT UINT16 *DataValue

+  );

+

+BOOLEAN SetupPhy (NIC_DATA_INSTANCE *AdapterInfo);

+VOID FindPhySpeedAndDpx (NIC_DATA_INSTANCE *AdapterInfo, UINT32 PhyId);

+

+

+

+//

+// functions defined in init.c

+//

+VOID

+TmpDelay (

+  IN UINT64 UnqId,

+  IN UINTN MicroSeconds

+  );

+

+VOID

+TmpMemIo (

+  IN UINT64 UnqId,

+  IN UINT8 ReadWrite,

+  IN UINT8 Len,

+  IN UINT64 Port,

+  IN UINT64 BufAddr

+  );

+

+//

+// functions defined in decode.c

+//

+VOID UNDI_GetState();

+VOID UNDI_Start();

+VOID UNDI_Stop();

+VOID UNDI_GetInitInfo();

+VOID UNDI_GetConfigInfo();

+VOID UNDI_Initialize();

+VOID UNDI_Reset();

+VOID UNDI_Shutdown();

+VOID UNDI_Interrupt();

+VOID UNDI_RecFilter();

+VOID UNDI_StnAddr();

+VOID UNDI_Statistics();

+VOID UNDI_ip2mac();

+VOID UNDI_NVData();

+VOID UNDI_Status();

+VOID UNDI_FillHeader();

+VOID UNDI_Transmit();

+VOID UNDI_Receive();

+

+VOID UNDI_APIEntry_new(UINT64);

+VOID UNDI_APIEntry_old(UINT64);

+VOID UNDI_APIEntry_Common(UINT64);

+

+PXE_IPV4 convert_mcip(PXE_MAC_ADDR *);

+INT32 validate_mcip (PXE_MAC_ADDR *MCastAddr);

+

+VOID PxeStructInit (PXE_SW_UNDI *PxePtr, UINTN VersionFlag);

+VOID PxeUpdate (NIC_DATA_INSTANCE *NicPtr, PXE_SW_UNDI *PxePtr);

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/build.xml b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/build.xml
new file mode 100644
index 0000000..9f34e44
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Pci/Undi/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Undi"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Pci/Undi/RuntimeDxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Undi">

+      <GenBuild baseName="Undi" mbdFilename="${MODULE_DIR}/Undi.mbd" msaFilename="${MODULE_DIR}/Undi.msa"/>

+   </target>

+   <target depends="Undi_clean" name="clean"/>

+   <target depends="Undi_cleanall" name="cleanall"/>

+   <target name="Undi_clean">

+      <OutputDirSetup baseName="Undi" mbdFilename="${MODULE_DIR}/Undi.mbd" msaFilename="${MODULE_DIR}/Undi.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Undi_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Undi_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Undi_cleanall">

+      <OutputDirSetup baseName="Undi" mbdFilename="${MODULE_DIR}/Undi.mbd" msaFilename="${MODULE_DIR}/Undi.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Undi_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Undi_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Undi*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c
new file mode 100644
index 0000000..3f61c46
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c
@@ -0,0 +1,155 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "ScsiBus.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+ScsiBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+ScsiBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gScsiBusComponentName = {

+  ScsiBusComponentNameGetDriverName,

+  ScsiBusComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mScsiBusDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"SCSI Bus Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+ScsiBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gScsiBusComponentName.SupportedLanguages,

+          mScsiBusDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+ScsiBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c
new file mode 100644
index 0000000..866c796
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c
@@ -0,0 +1,751 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    scsibus.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+#include "ScsiBus.h"

+

+EFI_STATUS

+EFIAPI

+SCSIBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+SCSIBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+SCSIBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  );

+

+EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {

+  SCSIBusDriverBindingSupported,

+  SCSIBusDriverBindingStart,

+  SCSIBusDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+SCSIBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+  

+  Arguments:

+  

+  Returns:

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+

+  //

+  // If RemainingDevicePath is not NULL, it should verify that the first device

+  // path node in RemainingDevicePath is an ATAPI Device path node.

+  //

+  if (RemainingDevicePath != NULL) {

+    if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) ||

+        (RemainingDevicePath->SubType != MSG_ATAPI_DP) ||

+        (DevicePathNodeLength (RemainingDevicePath) != sizeof(ATAPI_DEVICE_PATH))) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  //

+  // check for the existence of SCSI Pass Thru Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiScsiPassThruProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+SCSIBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+  

+  Arguments:

+  

+  Returns:

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS                  Status;

+  EFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath;

+  EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;

+  UINT32                      StartPun;

+  UINT64                      StartLun;

+  UINT32                      Pun;

+  UINT64                      Lun;

+  BOOLEAN                     ScanOtherPuns;

+

+  StartPun  = 0;

+  StartLun  = 0;

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  //

+  // Consume SCSI Pass Thru protocol.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiScsiPassThruProtocolGuid,

+                  (VOID **) &ScsiPassThru,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+

+  if (RemainingDevicePath == NULL) {

+    StartPun  = 0xFFFFFFFF;

+    StartLun  = 0;

+  } else {

+    ScsiPassThru->GetTargetLun (ScsiPassThru, RemainingDevicePath, &StartPun, &StartLun);

+  }

+

+  for (Pun = StartPun, ScanOtherPuns = TRUE; ScanOtherPuns;) {

+

+    if (StartPun == 0xFFFFFFFF) {

+      //

+      // Remaining Device Path is NULL, scan all the possible Puns in the

+      // SCSI Channel.

+      //

+      Status = ScsiPassThru->GetNextDevice (ScsiPassThru, &Pun, &Lun);

+      if (EFI_ERROR (Status)) {

+        //

+        // no legal Pun and Lun found any more

+        //

+        break;

+      }

+    } else {

+      //

+      // Remaining Device Path is not NULL, only scan the specified Pun.

+      //

+      Pun           = StartPun;

+      Lun           = StartLun;

+      ScanOtherPuns = FALSE;

+    }

+    

+    //

+    // Avoid creating handle for the host adapter.

+    //

+    if (Pun == ScsiPassThru->Mode->AdapterId) {

+      continue;

+    }

+    

+    //

+    // Scan for the scsi device, if it attaches to the scsi bus,

+    // then create handle and install scsi i/o protocol.

+    //

+    Status = ScsiScanCreateDevice (This, Controller, Pun, Lun, ScsiPassThru, ParentDevicePath);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+SCSIBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+  

+  Routine Description:

+  

+  Arguments:

+  

+  Returns:

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                  Status;

+  BOOLEAN                     AllChildrenStopped;

+  UINTN                       Index;

+  EFI_SCSI_IO_PROTOCOL        *ScsiIo;

+  SCSI_IO_DEV                 *ScsiIoDevice;

+  EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;

+

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiScsiPassThruProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    return EFI_SUCCESS;

+  }

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+

+    Status = gBS->OpenProtocol (

+                    ChildHandleBuffer[Index],

+                    &gEfiScsiIoProtocolGuid,

+                    (VOID **) &ScsiIo,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+      continue;

+    }

+

+    ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (ScsiIo);

+    //

+    // Close the child handle

+    //

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiScsiPassThruProtocolGuid,

+                    This->DriverBindingHandle,

+                    ChildHandleBuffer[Index]

+                    );

+

+    Status = gBS->UninstallMultipleProtocolInterfaces (

+                    ChildHandleBuffer[Index],

+                    &gEfiDevicePathProtocolGuid,

+                    ScsiIoDevice->DevicePath,

+                    &gEfiScsiIoProtocolGuid,

+                    &ScsiIoDevice->ScsiIo,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+      gBS->OpenProtocol (

+            Controller,

+            &gEfiScsiPassThruProtocolGuid,

+            (VOID **) &ScsiPassThru,

+            This->DriverBindingHandle,

+            ChildHandleBuffer[Index],

+            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+            );

+    } else {

+      gBS->FreePool (ScsiIoDevice);

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiGetDeviceType (

+  IN  EFI_SCSI_IO_PROTOCOL     *This,

+  OUT UINT8                    *DeviceType

+  )

+/*++

+

+  Routine Description:

+    Retrieves the device type information of the SCSI Controller.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    DeviceType            - A pointer to the device type information

+                            retrieved from the SCSI Controller. 

+

+  Returns:

+    EFI_SUCCESS           - Retrieves the device type information successfully.

+    EFI_INVALID_PARAMETER - The DeviceType is NULL.

+--*/

+{

+  SCSI_IO_DEV *ScsiIoDevice;

+

+  if (DeviceType == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ScsiIoDevice  = SCSI_IO_DEV_FROM_THIS (This);

+  *DeviceType   = ScsiIoDevice->ScsiDeviceType;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiGetDeviceLocation (

+  IN  EFI_SCSI_IO_PROTOCOL    *This,

+  OUT UINT8                   **Target,

+  OUT UINT64                  *Lun

+  )

+/*++

+  Routine Description:

+    Retrieves the device location in the SCSI channel.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    Target                - A pointer to the Target ID of a SCSI device 

+                            on the SCSI channel. 

+    Lun                   - A pointer to the LUN of the SCSI device on 

+                            the SCSI channel.

+

+  Returns:

+    EFI_SUCCESS           - Retrieves the device location successfully.

+    EFI_INVALID_PARAMETER - The Target or Lun is NULL.

+--*/

+{

+  SCSI_IO_DEV *ScsiIoDevice;

+

+  if (Target == NULL || Lun == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ScsiIoDevice  = SCSI_IO_DEV_FROM_THIS (This);

+

+  *Target       = (UINT8 *) (UINTN) ScsiIoDevice->Pun;

+  *Lun          = ScsiIoDevice->Lun;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiResetBus (

+  IN  EFI_SCSI_IO_PROTOCOL     *This

+  )

+/*++

+

+  Routine Description:

+    Resets the SCSI Bus that the SCSI Controller is attached to.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS           - The SCSI bus is reset successfully.

+    EFI_DEVICE_ERROR      - Errors encountered when resetting the SCSI bus.

+    EFI_UNSUPPORTED       - The bus reset operation is not supported by the

+                            SCSI Host Controller.

+    EFI_TIMEOUT           - A timeout occurred while attempting to reset 

+                            the SCSI bus.

+--*/

+{

+  SCSI_IO_DEV *ScsiIoDevice;

+

+  ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);

+

+  return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);

+

+}

+

+EFI_STATUS

+EFIAPI

+ScsiResetDevice (

+  IN  EFI_SCSI_IO_PROTOCOL     *This

+  )

+/*++

+

+  Routine Description:

+    Resets the SCSI Controller that the device handle specifies.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    

+

+  Returns:

+    EFI_SUCCESS           - Reset the SCSI controller successfully.

+    EFI_DEVICE_ERROR      - Errors are encountered when resetting the

+                            SCSI Controller.

+    EFI_UNSUPPORTED       - The SCSI bus does not support a device 

+                            reset operation.

+    EFI_TIMEOUT           - A timeout occurred while attempting to 

+                            reset the SCSI Controller.

+--*/

+{

+  SCSI_IO_DEV *ScsiIoDevice;

+

+  ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);

+

+  return ScsiIoDevice->ScsiPassThru->ResetTarget (

+                                      ScsiIoDevice->ScsiPassThru,

+                                      ScsiIoDevice->Pun,

+                                      ScsiIoDevice->Lun

+                                      );

+}

+

+EFI_STATUS

+EFIAPI

+ScsiExecuteSCSICommand (

+  IN  EFI_SCSI_IO_PROTOCOL                         *This,

+  IN OUT  EFI_SCSI_IO_SCSI_REQUEST_PACKET          *Packet,

+  IN EFI_EVENT                                     Event  OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Sends a SCSI Request Packet to the SCSI Controller for execution.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    Packet                - The SCSI request packet to send to the SCSI 

+                            Controller specified by the device handle.

+    Event                 - If the SCSI bus where the SCSI device is attached

+                            does not support non-blocking I/O, then Event is 

+                            ignored, and blocking I/O is performed.  

+                            If Event is NULL, then blocking I/O is performed.

+                            If Event is not NULL and non-blocking I/O is 

+                            supported, then non-blocking I/O is performed,

+                            and Event will be signaled when the SCSI Request

+                            Packet completes.

+  Returns:

+    EFI_SUCCESS           - The SCSI Request Packet was sent by the host 

+                            successfully, and TransferLength bytes were 

+                            transferred to/from DataBuffer.See 

+                            HostAdapterStatus, TargetStatus, 

+                            SenseDataLength, and SenseData in that order

+                            for additional status information.

+    EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength. See HostAdapterStatus, 

+                            TargetStatus, SenseDataLength, and SenseData in 

+                            that order for additional status information.

+    EFI_NOT_READY         - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.The caller may retry again later.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet. See HostAdapterStatus, 

+                            TargetStatus, SenseDataLength, and SenseData in 

+                            that order for additional status information.

+    EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.  

+                            The SCSI Request Packet was not sent, so no 

+                            additional status information is available.

+    EFI_UNSUPPORTED       - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller). The SCSI Request Packet was not

+                            sent, so no additional status information is 

+                            available.

+    EFI_TIMEOUT           - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute. See HostAdapterStatus,

+                            TargetStatus, SenseDataLength, and SenseData in 

+                            that order for additional status information.

+--*/

+{

+  SCSI_IO_DEV                             *ScsiIoDevice;

+  EFI_STATUS                              Status;

+

+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *RequestPacket;

+

+  if (Packet == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ScsiIoDevice  = SCSI_IO_DEV_FROM_THIS (This);

+

+  RequestPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;

+

+  Status = ScsiIoDevice->ScsiPassThru->PassThru (

+                                        ScsiIoDevice->ScsiPassThru,

+                                        ScsiIoDevice->Pun,

+                                        ScsiIoDevice->Lun,

+                                        RequestPacket,

+                                        Event

+                                        );

+  return Status;

+}

+

+EFI_STATUS

+ScsiScanCreateDevice (

+  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  EFI_HANDLE                    Controller,

+  UINT32                        Pun,

+  UINT64                        Lun,

+  EFI_SCSI_PASS_THRU_PROTOCOL   *ScsiPassThru,

+  EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Controller        - TODO: add argument description

+  Pun               - TODO: add argument description

+  Lun               - TODO: add argument description

+  ScsiPassThru      - TODO: add argument description

+  ParentDevicePath  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_OUT_OF_RESOURCES - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS                Status;

+  SCSI_IO_DEV               *ScsiIoDevice;

+  EFI_DEVICE_PATH_PROTOCOL  *ScsiDevicePath;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (SCSI_IO_DEV),

+                  (VOID **) &ScsiIoDevice

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ZeroMem (ScsiIoDevice, sizeof (SCSI_IO_DEV));

+

+  ScsiIoDevice->Signature                 = SCSI_IO_DEV_SIGNATURE;

+  ScsiIoDevice->ScsiPassThru              = ScsiPassThru;

+  ScsiIoDevice->Pun                       = Pun;

+  ScsiIoDevice->Lun                       = Lun;

+

+  ScsiIoDevice->ScsiIo.GetDeviceType      = ScsiGetDeviceType;

+  ScsiIoDevice->ScsiIo.GetDeviceLocation  = ScsiGetDeviceLocation;

+  ScsiIoDevice->ScsiIo.ResetBus           = ScsiResetBus;

+  ScsiIoDevice->ScsiIo.ResetDevice        = ScsiResetDevice;

+  ScsiIoDevice->ScsiIo.ExecuteSCSICommand = ScsiExecuteSCSICommand;

+

+  if (!DiscoverScsiDevice (ScsiIoDevice)) {

+    gBS->FreePool (ScsiIoDevice);

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // Set Device Path

+  //

+  Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (

+                                        ScsiIoDevice->ScsiPassThru,

+                                        ScsiIoDevice->Pun,

+                                        ScsiIoDevice->Lun,

+                                        &ScsiDevicePath

+                                        );

+  if (Status == EFI_OUT_OF_RESOURCES) {

+    gBS->FreePool (ScsiIoDevice);

+    return Status;

+  }

+

+  ScsiIoDevice->DevicePath = AppendDevicePathNode (

+                              ParentDevicePath,

+                              ScsiDevicePath

+                              );

+  //

+  // The memory space for ScsiDevicePath is allocated in

+  // ScsiPassThru->BuildDevicePath() function; It is no longer used

+  // after EfiAppendDevicePathNode,so free the memory it occupies.

+  //

+  gBS->FreePool (ScsiDevicePath);

+

+  if (ScsiIoDevice->DevicePath == NULL) {

+    gBS->FreePool (ScsiIoDevice);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ScsiIoDevice->Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  ScsiIoDevice->DevicePath,

+                  &gEfiScsiIoProtocolGuid,

+                  &ScsiIoDevice->ScsiIo,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (ScsiIoDevice);

+  } else {

+    gBS->OpenProtocol (

+          Controller,

+          &gEfiScsiPassThruProtocolGuid,

+          (VOID **) &ScsiPassThru,

+          This->DriverBindingHandle,

+          ScsiIoDevice->Handle,

+          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+          );

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+DiscoverScsiDevice (

+  SCSI_IO_DEV   *ScsiIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIoDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_SCSI_INQUIRY_DATA InquiryData;

+  UINT32                InquiryDataLength;

+  EFI_SCSI_SENSE_DATA   SenseData;

+  UINT8                 SenseDataLength;

+  UINT8                 HostAdapterStatus;

+  UINT8                 TargetStatus;

+

+  HostAdapterStatus = 0;

+  TargetStatus      = 0;

+  //

+  // Using Inquiry command to scan for the device

+  //

+  InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);

+  SenseDataLength   = sizeof (EFI_SCSI_SENSE_DATA);

+

+  Status = SubmitInquiryCommand (

+            &ScsiIoDevice->ScsiIo,

+            EfiScsiStallSeconds (1),

+            (VOID *) &SenseData,

+            &SenseDataLength,

+            &HostAdapterStatus,

+            &TargetStatus,

+            (VOID *) &InquiryData,

+            &InquiryDataLength,

+            FALSE

+            );

+  if (EFI_ERROR (Status)) {

+    //

+    //    ParseSenseData (&SenseData,SenseDataLength);

+    //

+    return FALSE;

+  }

+  //

+  // Retrieved inquiry data successfully

+  //

+  if ((InquiryData.Peripheral_Qualifier != 0) &&

+      (InquiryData.Peripheral_Qualifier != 3)) {

+    return FALSE;

+  }

+

+  if (InquiryData.Peripheral_Qualifier == 3) {

+    if (InquiryData.Peripheral_Type != 0x1f) {

+      return FALSE;

+    }

+  }

+

+  if ((0x1e >= InquiryData.Peripheral_Type) && (InquiryData.Peripheral_Type >= 0xa)) {

+    return FALSE;

+  }

+  

+  //

+  // valid device type and peripheral qualifier combination.

+  //

+  ScsiIoDevice->ScsiDeviceType  = InquiryData.Peripheral_Type;

+  ScsiIoDevice->RemovableDevice = InquiryData.RMB;

+  if (InquiryData.Version == 0) {

+    ScsiIoDevice->ScsiVersion = 0;

+  } else {

+    //

+    // ANSI-approved version

+    //

+    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);

+  }

+

+  return TRUE;

+}

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h
new file mode 100644
index 0000000..f981871
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h
@@ -0,0 +1,266 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ScsiBus.h

+

+Abstract:

+

+    Header file for SCSI Bus Driver.

+

+Revision History

+++*/

+

+// TODO: fix comment to end with --*/

+#ifndef _SCSI_BUS_H

+#define _SCSI_BUS_H

+

+

+#include <IndustryStandard/scsi.h>

+//

+// 1000 * 1000 * 10

+//

+#define ONE_SECOND_TIMER      10000000  

+

+#define SCSI_IO_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'c', 'i', 'o')

+

+typedef struct {

+  UINT32                      Signature;

+

+  EFI_HANDLE                  Handle;

+  EFI_SCSI_IO_PROTOCOL        ScsiIo;

+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;

+  EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;

+

+  UINT32                      Pun;

+  UINT64                      Lun;

+  UINT8                       ScsiDeviceType;

+  UINT8                       ScsiVersion;

+  BOOLEAN                     RemovableDevice;

+} SCSI_IO_DEV;

+

+#define SCSI_IO_DEV_FROM_THIS(a)  CR (a, SCSI_IO_DEV, ScsiIo, SCSI_IO_DEV_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gScsiBusDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gScsiBusComponentName;

+

+EFI_STATUS

+EFIAPI

+ScsiGetDeviceType (

+  IN  EFI_SCSI_IO_PROTOCOL     *This,

+  OUT UINT8                    *DeviceType

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  DeviceType  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+ScsiResetBus (

+  IN  EFI_SCSI_IO_PROTOCOL     *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+ScsiResetDevice (

+  IN  EFI_SCSI_IO_PROTOCOL     *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+ScsiExecuteSCSICommand (

+  IN  EFI_SCSI_IO_PROTOCOL                 *This,

+  IN OUT  EFI_SCSI_IO_SCSI_REQUEST_PACKET  *CommandPacket,

+  IN  EFI_EVENT                            Event

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This          - TODO: add argument description

+  CommandPacket - TODO: add argument description

+  Event         - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiScanCreateDevice (

+  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  EFI_HANDLE                    Controller,

+  UINT32                        Pun,

+  UINT64                        Lun,

+  EFI_SCSI_PASS_THRU_PROTOCOL   *ScsiPassThru,

+  EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Controller        - TODO: add argument description

+  Pun               - TODO: add argument description

+  Lun               - TODO: add argument description

+  ScsiPassThru      - TODO: add argument description

+  ParentDevicePath  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+DiscoverScsiDevice (

+  SCSI_IO_DEV   *ScsiIoDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIoDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetLunList (

+  EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru,

+  UINT32                      Target,

+  UINT64                      **LunArray,

+  UINTN                       *NumberOfLuns

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiPassThru  - TODO: add argument description

+  Target        - TODO: add argument description

+  LunArray      - TODO: add argument description

+  NumberOfLuns  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiBusSubmitReportLunCommand (

+  EFI_SCSI_PASS_THRU_PROTOCOL   *ScsiPassThru,

+  UINT32                        Target,

+  UINTN                         AllocationLength,

+  VOID                          *Buffer,

+  EFI_SCSI_SENSE_DATA           *SenseData,

+  UINT8                         *SenseDataLength,

+  UINT8                         *HostAdapterStatus,

+  UINT8                         *TargetStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiPassThru      - TODO: add argument description

+  Target            - TODO: add argument description

+  AllocationLength  - TODO: add argument description

+  Buffer            - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd
new file mode 100644
index 0000000..0254903
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>ScsiBus</BaseName>

+    <Guid>0167CCC4-D0F7-4f21-A3EF-9E64B7CDCE8B</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkScsiLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa
new file mode 100644
index 0000000..9eba05c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>ScsiBus</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>0167CCC4-D0F7-4f21-A3EF-9E64B7CDCE8B</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Scsi Bus module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkScsiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ScsiBus.h</Filename>

+    <Filename>ScsiBus.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">ScsiPassThru</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="BY_START">ScsiIo</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gSCSIBusDriverBinding</DriverBinding>

+      <ComponentName>gScsiBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml
new file mode 100644
index 0000000..a132025
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="ScsiBus"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Scsi/ScsiBus/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="ScsiBus">

+      <GenBuild baseName="ScsiBus" mbdFilename="${MODULE_DIR}/ScsiBus.mbd" msaFilename="${MODULE_DIR}/ScsiBus.msa"/>

+   </target>

+   <target depends="ScsiBus_clean" name="clean"/>

+   <target depends="ScsiBus_cleanall" name="cleanall"/>

+   <target name="ScsiBus_clean">

+      <OutputDirSetup baseName="ScsiBus" mbdFilename="${MODULE_DIR}/ScsiBus.mbd" msaFilename="${MODULE_DIR}/ScsiBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ScsiBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ScsiBus_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="ScsiBus_cleanall">

+      <OutputDirSetup baseName="ScsiBus" mbdFilename="${MODULE_DIR}/ScsiBus.mbd" msaFilename="${MODULE_DIR}/ScsiBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ScsiBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ScsiBus_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**ScsiBus*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c
new file mode 100644
index 0000000..15f02d6
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c
@@ -0,0 +1,190 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "ScsiDisk.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+ScsiDiskComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+ScsiDiskComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gScsiDiskComponentName = {

+  ScsiDiskComponentNameGetDriverName,

+  ScsiDiskComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mScsiDiskDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Scsi Disk Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+ScsiDiskComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gScsiDiskComponentName.SupportedLanguages,

+          mScsiDiskDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+ScsiDiskComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS            Status;

+  SCSI_DISK_DEV         *ScsiDiskDevice;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the device context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlockIo,

+                  gScsiDiskDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (BlockIo);

+

+  return LookupUnicodeString (

+          Language,

+          gScsiDiskComponentName.SupportedLanguages,

+          ScsiDiskDevice->ControllerNameTable,

+          ControllerName

+          );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
new file mode 100644
index 0000000..006cc73
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
@@ -0,0 +1,2414 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ScsiDisk.c

+

+Abstract:

+

+--*/

+

+#include "ScsiDisk.h"

+

+EFI_STATUS

+EFIAPI

+ScsiDiskDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+ScsiDiskDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+ScsiDiskDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  );

+

+EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding = {

+  ScsiDiskDriverBindingSupported,

+  ScsiDiskDriverBindingStart,

+  ScsiDiskDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+ScsiDiskDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+  

+  Arguments:

+  

+  Returns:

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS            Status;

+  EFI_SCSI_IO_PROTOCOL  *ScsiIo;

+  UINT8                 DeviceType;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiScsiIoProtocolGuid,

+                  (VOID **) &ScsiIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ScsiIo->GetDeviceType (ScsiIo, &DeviceType);

+  if (!EFI_ERROR (Status)) {

+    if ((DeviceType == EFI_SCSI_TYPE_DISK) || (DeviceType == EFI_SCSI_TYPE_CDROM)) {

+      Status = EFI_SUCCESS;

+    } else {

+      Status = EFI_UNSUPPORTED;

+    }

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiScsiIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiDiskDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+  

+  Arguments:

+  

+  Returns:

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS            Status;

+  EFI_SCSI_IO_PROTOCOL  *ScsiIo;

+  SCSI_DISK_DEV         *ScsiDiskDevice;

+  BOOLEAN               Temp;

+  UINT8                 Index;

+  UINT8                 MaxRetry;

+  BOOLEAN               NeedRetry;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (SCSI_DISK_DEV),

+                  (VOID **) &ScsiDiskDevice

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ZeroMem (ScsiDiskDevice, sizeof (SCSI_DISK_DEV));

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiScsiIoProtocolGuid,

+                  (VOID **) &ScsiIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (ScsiDiskDevice);

+    return Status;

+  }

+

+  ScsiDiskDevice->Signature         = SCSI_DISK_DEV_SIGNATURE;

+  ScsiDiskDevice->ScsiIo            = ScsiIo;

+  ScsiDiskDevice->BlkIo.Media       = &ScsiDiskDevice->BlkIoMedia;

+  ScsiDiskDevice->BlkIo.Reset       = ScsiDiskReset;

+  ScsiDiskDevice->BlkIo.ReadBlocks  = ScsiDiskReadBlocks;

+  ScsiDiskDevice->BlkIo.WriteBlocks = ScsiDiskWriteBlocks;

+  ScsiDiskDevice->BlkIo.FlushBlocks = ScsiDiskFlushBlocks;

+  ScsiDiskDevice->Handle            = Controller;

+

+  ScsiIo->GetDeviceType (ScsiIo, &(ScsiDiskDevice->DeviceType));

+  switch (ScsiDiskDevice->DeviceType) {

+  case EFI_SCSI_TYPE_DISK:

+    ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;

+    break;

+

+  case EFI_SCSI_TYPE_CDROM:

+    ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;

+    break;

+  }

+  //

+  // The Sense Data Array's initial size is 6

+  //

+  ScsiDiskDevice->SenseDataNumber = 6;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber,

+                  (VOID **) &(ScsiDiskDevice->SenseData)

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiScsiIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    gBS->FreePool (ScsiDiskDevice);

+    return Status;

+  }

+

+  ZeroMem (

+    ScsiDiskDevice->SenseData,

+    sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber

+    );

+

+  //

+  // Retrive device information

+  //

+  MaxRetry = 2;

+  for (Index = 0; Index < MaxRetry; Index++) {

+    Status = ScsiDiskInquiryDevice (ScsiDiskDevice, &NeedRetry);

+    if (!EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (!NeedRetry) {

+      gBS->FreePool (ScsiDiskDevice->SenseData);

+      gBS->CloseProtocol (

+            Controller,

+            &gEfiScsiIoProtocolGuid,

+            This->DriverBindingHandle,

+            Controller

+            );

+      gBS->FreePool (ScsiDiskDevice);

+      return EFI_DEVICE_ERROR;

+    }

+  }

+  //

+  // The second parameter "TRUE" means must

+  // retrieve media capacity

+  //

+  Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp);

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &Controller,

+                    &gEfiBlockIoProtocolGuid,

+                    &ScsiDiskDevice->BlkIo,

+                    NULL

+                    );

+  }

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (ScsiDiskDevice->SenseData);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiScsiIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    gBS->FreePool (ScsiDiskDevice);

+    return Status;

+  }

+

+  ScsiDiskDevice->ControllerNameTable = NULL;

+  AddUnicodeString (

+    "eng",

+    gScsiDiskComponentName.SupportedLanguages,

+    &ScsiDiskDevice->ControllerNameTable,

+    (CHAR16 *) L"SCSI Disk Device"

+    );

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+EFIAPI

+ScsiDiskDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+  

+  Routine Description:

+  

+  Arguments:

+  

+  Returns:

+  

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Controller - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_BLOCK_IO_PROTOCOL *BlkIo;

+  SCSI_DISK_DEV         *ScsiDiskDevice;

+  EFI_STATUS            Status;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlkIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (BlkIo);

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiBlockIoProtocolGuid,

+                  &ScsiDiskDevice->BlkIo

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiScsiIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    ReleaseScsiDiskDeviceResources (ScsiDiskDevice);

+

+    return EFI_SUCCESS;

+  }

+  //

+  // errors met

+  //

+  return Status;

+}

+

+//

+// Block I/O Protocol Interface

+//

+

+EFI_STATUS

+EFIAPI

+ScsiDiskReset (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  BOOLEAN                 ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  SCSI_DISK_DEV *ScsiDiskDevice;

+  EFI_STATUS    Status;

+

+  ScsiDiskDevice  = SCSI_DISK_DEV_FROM_THIS (This);

+

+  Status          = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);

+

+  if (!ExtendedVerification) {

+    return Status;

+  }

+

+  Status = ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiDiskReadBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  LBA         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_NO_MEDIA - TODO: Add description for return value

+  EFI_MEDIA_CHANGED - TODO: Add description for return value

+  EFI_BAD_BUFFER_SIZE - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+

+--*/

+{

+  SCSI_DISK_DEV       *ScsiDiskDevice;

+  EFI_BLOCK_IO_MEDIA  *Media;

+  EFI_STATUS          Status;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  BOOLEAN             MediaChange;

+

+  MediaChange = FALSE;

+  if (!Buffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferSize == 0) {

+    return EFI_SUCCESS;

+  }

+

+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);

+

+  if (!IsDeviceFixed (ScsiDiskDevice)) {

+

+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (MediaChange) {

+      gBS->ReinstallProtocolInterface (

+            ScsiDiskDevice->Handle,

+            &gEfiBlockIoProtocolGuid,

+            &ScsiDiskDevice->BlkIo,

+            &ScsiDiskDevice->BlkIo

+            );

+    }

+  }

+  //

+  // Get the intrinsic block size

+  //

+  Media           = ScsiDiskDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (!(Media->MediaPresent)) {

+    return EFI_NO_MEDIA;

+  }

+

+  if (MediaId != Media->MediaId) {

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (LBA > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // if all the parameters are valid, then perform read sectors command

+  // to transfer data from device to host.

+  //

+  Status = ScsiDiskReadSectors (ScsiDiskDevice, Buffer, LBA, NumberOfBlocks);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiDiskWriteBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  IN  VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  LBA         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_NO_MEDIA - TODO: Add description for return value

+  EFI_MEDIA_CHANGED - TODO: Add description for return value

+  EFI_BAD_BUFFER_SIZE - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+

+--*/

+{

+  SCSI_DISK_DEV       *ScsiDiskDevice;

+  EFI_BLOCK_IO_MEDIA  *Media;

+  EFI_STATUS          Status;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  BOOLEAN             MediaChange;

+

+  MediaChange = FALSE;

+  if (!Buffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferSize == 0) {

+    return EFI_SUCCESS;

+  }

+

+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);

+

+  if (!IsDeviceFixed (ScsiDiskDevice)) {

+

+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (MediaChange) {

+      gBS->ReinstallProtocolInterface (

+            ScsiDiskDevice->Handle,

+            &gEfiBlockIoProtocolGuid,

+            &ScsiDiskDevice->BlkIo,

+            &ScsiDiskDevice->BlkIo

+            );

+    }

+  }

+  //

+  // Get the intrinsic block size

+  //

+  Media           = ScsiDiskDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (!(Media->MediaPresent)) {

+    return EFI_NO_MEDIA;

+  }

+

+  if (MediaId != Media->MediaId) {

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (LBA > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // if all the parameters are valid, then perform read sectors command

+  // to transfer data from device to host.

+  //

+  Status = ScsiDiskWriteSectors (ScsiDiskDevice, Buffer, LBA, NumberOfBlocks);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+ScsiDiskFlushBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  //

+  // return directly

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ScsiDiskDetectMedia (

+  SCSI_DISK_DEV   *ScsiDiskDevice,

+  BOOLEAN         MustReadCapacity,

+  BOOLEAN         *MediaChange

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  MustReadCapacity  - TODO: add argument description

+  MediaChange       - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_STATUS          ReadCapacityStatus;

+  EFI_SCSI_SENSE_DATA *SenseData;

+  UINTN               NumberOfSenseKeys;

+  BOOLEAN             NeedRetry;

+  BOOLEAN             NeedReadCapacity;

+  UINT8               Index;

+  UINT8               MaxRetry;

+  EFI_BLOCK_IO_MEDIA  OldMedia;

+  UINTN               Action;

+

+  Status              = EFI_SUCCESS;

+  ReadCapacityStatus  = EFI_SUCCESS;

+  SenseData           = NULL;

+  NumberOfSenseKeys   = 0;

+  NeedReadCapacity    = FALSE;

+  CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));

+  // OldMedia            = *(ScsiDiskDevice->BlkIo.Media);

+

+  *MediaChange        = FALSE;

+

+  MaxRetry            = 3;

+  for (Index = 0; Index < MaxRetry; Index++) {

+    Status = ScsiDiskTestUnitReady (

+              ScsiDiskDevice,

+              &NeedRetry,

+              &SenseData,

+              &NumberOfSenseKeys

+              );

+    if (!EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (!NeedRetry) {

+      return Status;

+    }

+  }

+

+  if ((Index == MaxRetry) && EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = DetectMediaParsingSenseKeys (

+            ScsiDiskDevice,

+            SenseData,

+            NumberOfSenseKeys,

+            &Action

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // ACTION_NO_ACTION: need not read capacity

+  // other action code: need read capacity

+  //

+  if (Action == ACTION_NO_ACTION) {

+    NeedReadCapacity = FALSE;

+  } else {

+    NeedReadCapacity = TRUE;

+  }

+  

+  //

+  // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,

+  // retrieve capacity via Read Capacity command

+  //

+  if (NeedReadCapacity || MustReadCapacity) {

+    

+    //

+    // retrieve media information

+    //

+    MaxRetry = 3;

+    for (Index = 0; Index < MaxRetry; Index++) {

+

+      ReadCapacityStatus = ScsiDiskReadCapacity (

+                            ScsiDiskDevice,

+                            &NeedRetry,

+                            &SenseData,

+                            &NumberOfSenseKeys

+                            );

+      if (EFI_ERROR (ReadCapacityStatus) && !NeedRetry) {

+        return EFI_DEVICE_ERROR;

+      }

+      //

+      // analyze sense key to action

+      //

+      Status = DetectMediaParsingSenseKeys (

+                ScsiDiskDevice,

+                SenseData,

+                NumberOfSenseKeys,

+                &Action

+                );

+      //

+      // if Status is error, it may indicate crisis error,

+      // so return without retry.

+      //

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      switch (Action) {

+      case ACTION_NO_ACTION:

+        //

+        // no retry

+        //

+        Index = MaxRetry;

+        break;

+

+      case ACTION_RETRY_COMMAND_LATER:

+        //

+        // retry the ReadCapacity later and continuously, until the condition

+        // no longer emerges.

+        // stall time is 100000us, or say 0.1 second.

+        //

+        gBS->Stall (100000);

+        Index = 0;

+        break;

+

+      default:

+        //

+        // other cases, just retry the command

+        //

+        break;

+      }

+    }

+

+    if ((Index == MaxRetry) && EFI_ERROR (ReadCapacityStatus)) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  if (ScsiDiskDevice->BlkIo.Media->MediaId != OldMedia.MediaId) {

+    //

+    // Media change information got from the device

+    //

+    *MediaChange = TRUE;

+  }

+

+  if (ScsiDiskDevice->BlkIo.Media->ReadOnly != OldMedia.ReadOnly) {

+    *MediaChange = TRUE;

+    ScsiDiskDevice->BlkIo.Media->MediaId += 1;

+  }

+

+  if (ScsiDiskDevice->BlkIo.Media->BlockSize != OldMedia.BlockSize) {

+    *MediaChange = TRUE;

+    ScsiDiskDevice->BlkIo.Media->MediaId += 1;

+  }

+

+  if (ScsiDiskDevice->BlkIo.Media->LastBlock != OldMedia.LastBlock) {

+    *MediaChange = TRUE;

+    ScsiDiskDevice->BlkIo.Media->MediaId += 1;

+  }

+

+  if (ScsiDiskDevice->BlkIo.Media->MediaPresent != OldMedia.MediaPresent) {

+    if (ScsiDiskDevice->BlkIo.Media->MediaPresent) {

+      //

+      // when change from no media to media present, reset the MediaId to 1.

+      //

+      ScsiDiskDevice->BlkIo.Media->MediaId = 1;

+    } else {

+      //

+      // when no media, reset the MediaId to zero.

+      //

+      ScsiDiskDevice->BlkIo.Media->MediaId = 0;

+    }

+

+    *MediaChange = TRUE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ScsiDiskInquiryDevice (

+  SCSI_DISK_DEV   *ScsiDiskDevice,

+  BOOLEAN         *NeedRetry

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  NeedRetry       - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+

+--*/

+{

+  UINT32              InquiryDataLength;

+  UINT8               SenseDataLength;

+  UINT8               HostAdapterStatus;

+  UINT8               TargetStatus;

+  EFI_SCSI_SENSE_DATA *SenseDataArray;

+  UINTN               NumberOfSenseKeys;

+  EFI_STATUS          Status;

+  UINT8               MaxRetry;

+  UINT8               Index;

+

+  InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);

+  SenseDataLength   = 0;

+

+  Status = SubmitInquiryCommand (

+            ScsiDiskDevice->ScsiIo,

+            EfiScsiStallSeconds (1),

+            NULL,

+            &SenseDataLength,

+            &HostAdapterStatus,

+            &TargetStatus,

+            (VOID *) &(ScsiDiskDevice->InquiryData),

+            &InquiryDataLength,

+            FALSE

+            );

+  switch (Status) {

+  //

+  // no need to check HostAdapterStatus and TargetStatus

+  //

+  case EFI_SUCCESS:

+  case EFI_WARN_BUFFER_TOO_SMALL:

+    ParseInquiryData (ScsiDiskDevice);

+    return EFI_SUCCESS;

+

+  case EFI_NOT_READY:

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_INVALID_PARAMETER:

+  case EFI_UNSUPPORTED:

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+

+  //

+  // go ahead to check HostAdapterStatus and TargetStatus

+  // (EFI_TIMEOUT, EFI_DEVICE_ERROR)

+  //

+  default:

+    break;

+  }

+

+  Status = CheckHostAdapterStatus (HostAdapterStatus);

+  switch (Status) {

+  case EFI_SUCCESS:

+    break;

+

+  case EFI_TIMEOUT:

+  case EFI_NOT_READY:

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_DEVICE_ERROR:

+    //

+    // reset the scsi channel

+    //

+    ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = CheckTargetStatus (TargetStatus);

+  switch (Status) {

+  case EFI_SUCCESS:

+    break;

+

+  case EFI_NOT_READY:

+    //

+    // reset the scsi device

+    //

+    ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_DEVICE_ERROR:

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // if goes here, meant SubmitInquiryCommand() failed.

+  // if ScsiDiskRequestSenseKeys() succeeds at last,

+  // better retry SubmitInquiryCommand(). (by setting *NeedRetry = TRUE)

+  //

+  MaxRetry = 3;

+  for (Index = 0; Index < MaxRetry; Index++) {

+

+    Status = ScsiDiskRequestSenseKeys (

+              ScsiDiskDevice,

+              NeedRetry,

+              &SenseDataArray,

+              &NumberOfSenseKeys,

+              TRUE

+              );

+    if (!EFI_ERROR (Status)) {

+      *NeedRetry = TRUE;

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (!*NeedRetry) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+  //

+  // ScsiDiskRequestSenseKeys() failed after several rounds of retry.

+  // set *NeedRetry = FALSE to avoid the outside caller try again.

+  //

+  *NeedRetry = FALSE;

+  return EFI_DEVICE_ERROR;

+}

+

+EFI_STATUS

+ScsiDiskTestUnitReady (

+  SCSI_DISK_DEV         *ScsiDiskDevice,

+  BOOLEAN               *NeedRetry,

+  EFI_SCSI_SENSE_DATA   **SenseDataArray,

+  UINTN                 *NumberOfSenseKeys

+  )

+// TODO: function comment should start with '/*++'

+/*

+  When Test Unit Ready command succeeds,

+  retrieve Sense Keys via Request Sense;

+  When Test Unit Ready command encounters any error caused by host adapter or

+  target, return error without retrieving Sense Keys.

+*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    ScsiDiskDevice - add argument and description to function comment

+// TODO:    NeedRetry - add argument and description to function comment

+// TODO:    SenseDataArray - add argument and description to function comment

+// TODO:    NumberOfSenseKeys - add argument and description to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  EFI_STATUS  Status;

+  UINT8       SenseDataLength;

+  UINT8       HostAdapterStatus;

+  UINT8       TargetStatus;

+  UINT8       Index;

+  UINT8       MaxRetry;

+

+  SenseDataLength     = 0;

+  *NumberOfSenseKeys  = 0;

+

+  //

+  // Parameter 3 and 4: do not require sense data, retrieve it when needed.

+  //

+  Status = SubmitTestUnitReadyCommand (

+            ScsiDiskDevice->ScsiIo,

+            EfiScsiStallSeconds (1),

+            NULL,

+            &SenseDataLength,

+            &HostAdapterStatus,

+            &TargetStatus

+            );

+  switch (Status) {

+  //

+  // no need to check HostAdapterStatus and TargetStatus

+  //

+  case EFI_NOT_READY:

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_INVALID_PARAMETER:

+  case EFI_UNSUPPORTED:

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+

+  //

+  // go ahead to check HostAdapterStatus and TargetStatus

+  //

+  default:

+    break;

+  }

+

+  Status = CheckHostAdapterStatus (HostAdapterStatus);

+  switch (Status) {

+  case EFI_SUCCESS:

+    break;

+

+  case EFI_TIMEOUT:

+  case EFI_NOT_READY:

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_DEVICE_ERROR:

+    //

+    // reset the scsi channel

+    //

+    ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = CheckTargetStatus (TargetStatus);

+  switch (Status) {

+  case EFI_SUCCESS:

+    break;

+

+  case EFI_NOT_READY:

+    //

+    // reset the scsi device

+    //

+    ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_DEVICE_ERROR:

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+  }

+

+  MaxRetry = 3;

+  for (Index = 0; Index < MaxRetry; Index++) {

+

+    Status = ScsiDiskRequestSenseKeys (

+              ScsiDiskDevice,

+              NeedRetry,

+              SenseDataArray,

+              NumberOfSenseKeys,

+              FALSE

+              );

+    if (!EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    }

+

+    if (!*NeedRetry) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+  //

+  // ScsiDiskRequestSenseKeys() failed after several rounds of retry.

+  // set *NeedRetry = FALSE to avoid the outside caller try again.

+  //

+  *NeedRetry = FALSE;

+  return EFI_DEVICE_ERROR;

+}

+

+EFI_STATUS

+DetectMediaParsingSenseKeys (

+  SCSI_DISK_DEV           *ScsiDiskDevice,

+  EFI_SCSI_SENSE_DATA     *SenseData,

+  UINTN                   NumberOfSenseKeys,

+  UINTN                   *Action

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  SenseData         - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  Action            - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  BOOLEAN RetryLater;

+

+  //

+  // Default is to read capacity, unless..

+  //

+  *Action = ACTION_READ_CAPACITY;

+

+  if (NumberOfSenseKeys == 0) {

+    *Action = ACTION_NO_ACTION;

+    return EFI_SUCCESS;

+  }

+

+  if (!ScsiDiskHaveSenseKey (SenseData, NumberOfSenseKeys)) {

+    //

+    // No Sense Key returned from last submitted command

+    //

+    *Action = ACTION_NO_ACTION;

+    return EFI_SUCCESS;

+  }

+

+  if (ScsiDiskIsNoMedia (SenseData, NumberOfSenseKeys)) {

+    ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;

+    ScsiDiskDevice->BlkIo.Media->LastBlock    = 0;

+    *Action = ACTION_NO_ACTION;

+    return EFI_SUCCESS;

+  }

+

+  if (ScsiDiskIsMediaChange (SenseData, NumberOfSenseKeys)) {

+    ScsiDiskDevice->BlkIo.Media->MediaId++;

+    return EFI_SUCCESS;

+  }

+

+  if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {

+    ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;

+    ScsiDiskDevice->BlkIo.Media->LastBlock    = 0;

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (!ScsiDiskIsDriveReady (SenseData, NumberOfSenseKeys, &RetryLater)) {

+    if (RetryLater) {

+      *Action = ACTION_RETRY_COMMAND_LATER;

+      return EFI_SUCCESS;

+    }

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ScsiDiskReadCapacity (

+  SCSI_DISK_DEV           *ScsiDiskDevice,

+  BOOLEAN                 *NeedRetry,

+  EFI_SCSI_SENSE_DATA     **SenseDataArray,

+  UINTN                   *NumberOfSenseKeys

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+

+--*/

+{

+  EFI_SCSI_DISK_CAPACITY_DATA CapacityData;

+  UINT32                      DataLength;

+  UINT8                       HostAdapterStatus;

+  UINT8                       TargetStatus;

+  EFI_STATUS                  CommandStatus;

+  EFI_STATUS                  Status;

+  UINT8                       Index;

+  UINT8                       MaxRetry;

+  UINT8                       SenseDataLength;

+

+  SenseDataLength = 0;

+  ZeroMem (&CapacityData, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));

+  DataLength          = sizeof (EFI_SCSI_DISK_CAPACITY_DATA);

+

+  *NumberOfSenseKeys  = 0;

+  *NeedRetry          = FALSE;

+  //

+  // submit Read Capacity Command. in this call,not request sense data

+  //

+  CommandStatus = SubmitReadCapacityCommand (

+                    ScsiDiskDevice->ScsiIo,

+                    EfiScsiStallSeconds (1),

+                    NULL,

+                    &SenseDataLength,

+                    &HostAdapterStatus,

+                    &TargetStatus,

+                    (VOID *) &CapacityData,

+                    &DataLength,

+                    FALSE

+                    );

+  switch (CommandStatus) {

+  //

+  // no need to check HostAdapterStatus and TargetStatus

+  //

+  case EFI_SUCCESS:

+    GetMediaInfo (ScsiDiskDevice, &CapacityData);

+    return EFI_SUCCESS;

+

+  case EFI_NOT_READY:

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_INVALID_PARAMETER:

+  case EFI_UNSUPPORTED:

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+

+  //

+  // go ahead to check HostAdapterStatus and TargetStatus

+  // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)

+  //

+  default:

+    break;

+  }

+

+  Status = CheckHostAdapterStatus (HostAdapterStatus);

+  switch (Status) {

+  case EFI_SUCCESS:

+    break;

+

+  case EFI_TIMEOUT:

+  case EFI_NOT_READY:

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_DEVICE_ERROR:

+    //

+    // reset the scsi channel

+    //

+    ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = CheckTargetStatus (TargetStatus);

+  switch (Status) {

+  case EFI_SUCCESS:

+    break;

+

+  case EFI_NOT_READY:

+    //

+    // reset the scsi device

+    //

+    ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);

+    *NeedRetry = TRUE;

+    return EFI_DEVICE_ERROR;

+

+  case EFI_DEVICE_ERROR:

+    *NeedRetry = FALSE;

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // if goes here, meant SubmitReadCapacityCommand() failed.

+  // if ScsiDiskRequestSenseKeys() succeeds at last,

+  // better retry SubmitReadCapacityCommand(). (by setting *NeedRetry = TRUE)

+  //

+  MaxRetry = 3;

+  for (Index = 0; Index < MaxRetry; Index++) {

+

+    Status = ScsiDiskRequestSenseKeys (

+              ScsiDiskDevice,

+              NeedRetry,

+              SenseDataArray,

+              NumberOfSenseKeys,

+              TRUE

+              );

+    if (!EFI_ERROR (Status)) {

+      *NeedRetry = TRUE;

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (!*NeedRetry) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+  //

+  // ScsiDiskRequestSenseKeys() failed after several rounds of retry.

+  // set *NeedRetry = FALSE to avoid the outside caller try again.

+  //

+  *NeedRetry = FALSE;

+  return EFI_DEVICE_ERROR;

+}

+

+EFI_STATUS

+CheckHostAdapterStatus (

+  UINT8   HostAdapterStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  HostAdapterStatus - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_TIMEOUT - TODO: Add description for return value

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  switch (HostAdapterStatus) {

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK:

+    return EFI_SUCCESS;

+

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND:

+    return EFI_TIMEOUT;

+

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET:

+    return EFI_NOT_READY;

+

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE:

+  case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_SUCCESS;

+  }

+}

+

+EFI_STATUS

+CheckTargetStatus (

+  UINT8   TargetStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  TargetStatus  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  switch (TargetStatus) {

+  case EFI_SCSI_IO_STATUS_TARGET_GOOD:

+  case EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION:

+  case EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET:

+    return EFI_SUCCESS;

+

+  case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE:

+  case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET:

+  case EFI_SCSI_IO_STATUS_TARGET_BUSY:

+  case EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED:

+  case EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL:

+    return EFI_NOT_READY;

+

+  case EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT:

+    return EFI_DEVICE_ERROR;

+    break;

+

+  default:

+    return EFI_SUCCESS;

+  }

+}

+

+EFI_STATUS

+ScsiDiskRequestSenseKeys (

+  SCSI_DISK_DEV           *ScsiDiskDevice,

+  BOOLEAN                 *NeedRetry,

+  EFI_SCSI_SENSE_DATA     **SenseDataArray,

+  UINTN                   *NumberOfSenseKeys,

+  BOOLEAN                 AskResetIfError

+  )

+// TODO: function comment should start with '/*++'

+/*

+  Retrieve all sense keys from the device.

+  When encountering error during the process,

+  if retrieve sense keys before error encounterred,

+  return the sense keys with return status set to EFI_SUCCESS,

+  and NeedRetry set to FALSE; otherwize, return the proper return

+  status.

+*/

+// TODO: function comment should end with '--*/'

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    ScsiDiskDevice - add argument and description to function comment

+// TODO:    NeedRetry - add argument and description to function comment

+// TODO:    SenseDataArray - add argument and description to function comment

+// TODO:    NumberOfSenseKeys - add argument and description to function comment

+// TODO:    AskResetIfError - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_SCSI_SENSE_DATA *PtrSenseData;

+  UINT8               SenseDataLength;

+  BOOLEAN             SenseReq;

+  EFI_STATUS          Status;

+  EFI_STATUS          FallStatus;

+  UINT8               HostAdapterStatus;

+  UINT8               TargetStatus;

+

+  FallStatus      = EFI_SUCCESS;

+  SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);

+

+  ZeroMem (

+    ScsiDiskDevice->SenseData,

+    sizeof (EFI_SCSI_SENSE_DATA) * (ScsiDiskDevice->SenseDataNumber)

+    );

+

+  *NumberOfSenseKeys  = 0;

+  *SenseDataArray     = ScsiDiskDevice->SenseData;

+  PtrSenseData        = ScsiDiskDevice->SenseData;

+

+  for (SenseReq = TRUE; SenseReq;) {

+

+    Status = SubmitRequestSenseCommand (

+              ScsiDiskDevice->ScsiIo,

+              EfiScsiStallSeconds (2),

+              PtrSenseData,

+              &SenseDataLength,

+              &HostAdapterStatus,

+              &TargetStatus

+              );

+    switch (Status) {

+

+    case EFI_SUCCESS:

+

+    //

+    // fall through

+    //

+    case EFI_WARN_BUFFER_TOO_SMALL:

+      FallStatus = EFI_SUCCESS;

+      break;

+

+    case EFI_TIMEOUT:

+

+    //

+    // fall through

+    //

+    case EFI_NOT_READY:

+      *NeedRetry  = TRUE;

+      FallStatus  = EFI_DEVICE_ERROR;

+      break;

+

+    case EFI_INVALID_PARAMETER:

+    case EFI_UNSUPPORTED:

+      *NeedRetry  = FALSE;

+      FallStatus  = EFI_DEVICE_ERROR;

+      break;

+

+    case EFI_DEVICE_ERROR:

+      if (AskResetIfError) {

+        ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);

+      }

+

+      FallStatus = EFI_DEVICE_ERROR;

+      break;

+    }

+

+    if (EFI_ERROR (FallStatus)) {

+      if (*NumberOfSenseKeys != 0) {

+        *NeedRetry = FALSE;

+        return EFI_SUCCESS;

+      } else {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+

+    (*NumberOfSenseKeys) += 1;

+

+    //

+    // no more sense key or number of sense keys exceeds predefined,

+    // skip the loop.

+    //

+    if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) || 

+        (*NumberOfSenseKeys == ScsiDiskDevice->SenseDataNumber)) {

+      SenseReq = FALSE;

+    }

+

+    PtrSenseData += 1;

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+GetMediaInfo (

+  SCSI_DISK_DEV                 *ScsiDiskDevice,

+  EFI_SCSI_DISK_CAPACITY_DATA   *Capacity

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  Capacity        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  ScsiDiskDevice->BlkIo.Media->LastBlock =  (Capacity->LastLba3 << 24) |

+                                            (Capacity->LastLba2 << 16) |

+                                            (Capacity->LastLba1 << 8)  |

+                                             Capacity->LastLba0;

+

+  ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;

+  ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity->BlockSize3 << 24) |

+                                           (Capacity->BlockSize2 << 16) | 

+                                           (Capacity->BlockSize1 << 8)  |

+                                            Capacity->BlockSize0;

+  if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {

+    ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;

+  }

+

+  if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_CDROM) {

+    ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;

+  }

+}

+

+VOID

+ParseInquiryData (

+  SCSI_DISK_DEV   *ScsiDiskDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  ScsiDiskDevice->FixedDevice               = (BOOLEAN) (ScsiDiskDevice->InquiryData.RMB ? 0 : 1);

+  ScsiDiskDevice->BlkIoMedia.RemovableMedia = (BOOLEAN) (!ScsiDiskDevice->FixedDevice);

+}

+

+EFI_STATUS

+ScsiDiskReadSectors (

+  SCSI_DISK_DEV     *ScsiDiskDevice,

+  VOID              *Buffer,

+  EFI_LBA           Lba,

+  UINTN             NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  Buffer          - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  UINTN               BlocksRemaining;

+  UINT32              Lba32;

+  UINT8               *PtrBuffer;

+  UINT32              BlockSize;

+  UINT32              ByteCount;

+  UINT32              MaxBlock;

+  UINT32              SectorCount;

+  UINT64              Timeout;

+  EFI_STATUS          Status;

+  UINT8               Index;

+  UINT8               MaxRetry;

+  BOOLEAN             NeedRetry;

+  EFI_SCSI_SENSE_DATA *SenseData;

+  UINT8               SenseDataLength;

+  UINTN               NumberOfSenseKeys;

+

+  SenseData         = NULL;

+  SenseDataLength   = 0;

+  NumberOfSenseKeys = 0;

+

+  Status            = EFI_SUCCESS;

+

+  BlocksRemaining   = NumberOfBlocks;

+  BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;

+  //

+  // limit the data bytes that can be transferred by one Read(10) Command

+  //

+  MaxBlock  = 65536;

+

+  PtrBuffer = Buffer;

+  Lba32     = (UINT32) Lba;

+

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining <= MaxBlock) {

+

+      SectorCount = (UINT16) BlocksRemaining;

+    } else {

+

+      SectorCount = MaxBlock;

+    }

+

+    ByteCount = SectorCount * BlockSize;

+    Timeout   = EfiScsiStallSeconds (2);

+

+    MaxRetry  = 2;

+    for (Index = 0; Index < MaxRetry; Index++) {

+

+      Status = ScsiDiskRead10 (

+                ScsiDiskDevice,

+                &NeedRetry,

+                &SenseData,

+                &NumberOfSenseKeys,

+                Timeout,

+                PtrBuffer,

+                &ByteCount,

+                Lba32,

+                SectorCount

+                );

+      if (!EFI_ERROR (Status)) {

+        break;

+      }

+

+      if (!NeedRetry) {

+        return EFI_DEVICE_ERROR;

+      }

+

+    }

+

+    if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    //

+    // actual transferred sectors

+    //

+    SectorCount = ByteCount / BlockSize;

+

+    Lba32 += SectorCount;

+    PtrBuffer = PtrBuffer + SectorCount * BlockSize;

+    BlocksRemaining -= SectorCount;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ScsiDiskWriteSectors (

+  SCSI_DISK_DEV     *ScsiDiskDevice,

+  VOID              *Buffer,

+  EFI_LBA           Lba,

+  UINTN             NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  Buffer          - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  UINTN               BlocksRemaining;

+  UINT32              Lba32;

+  UINT8               *PtrBuffer;

+  UINT32              BlockSize;

+  UINT32              ByteCount;

+  UINT32              MaxBlock;

+  UINT32              SectorCount;

+  UINT64              Timeout;

+  EFI_STATUS          Status;

+  UINT8               Index;

+  UINT8               MaxRetry;

+  BOOLEAN             NeedRetry;

+  EFI_SCSI_SENSE_DATA *SenseData;

+  UINT8               SenseDataLength;

+  UINTN               NumberOfSenseKeys;

+

+  SenseData         = NULL;

+  SenseDataLength   = 0;

+  NumberOfSenseKeys = 0;

+

+  Status            = EFI_SUCCESS;

+

+  BlocksRemaining   = NumberOfBlocks;

+  BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;

+  //

+  // limit the data bytes that can be transferred by one Write(10) Command

+  //

+  MaxBlock  = 65536;

+

+  PtrBuffer = Buffer;

+  Lba32     = (UINT32) Lba;

+

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining <= MaxBlock) {

+

+      SectorCount = (UINT16) BlocksRemaining;

+    } else {

+

+      SectorCount = MaxBlock;

+    }

+

+    ByteCount = SectorCount * BlockSize;

+    Timeout   = EfiScsiStallSeconds (2);

+    MaxRetry  = 2;

+    for (Index = 0; Index < MaxRetry; Index++) {

+      Status = ScsiDiskWrite10 (

+                ScsiDiskDevice,

+                &NeedRetry,

+                &SenseData,

+                &NumberOfSenseKeys,

+                Timeout,

+                PtrBuffer,

+                &ByteCount,

+                Lba32,

+                SectorCount

+                );

+      if (!EFI_ERROR (Status)) {

+        break;

+      }

+

+      if (!NeedRetry) {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+

+    if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // actual transferred sectors

+    //

+    SectorCount = ByteCount / BlockSize;

+

+    Lba32 += SectorCount;

+    PtrBuffer = PtrBuffer + SectorCount * BlockSize;

+    BlocksRemaining -= SectorCount;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ScsiDiskRead10 (

+  SCSI_DISK_DEV         *ScsiDiskDevice,

+  BOOLEAN               *NeedRetry,

+  EFI_SCSI_SENSE_DATA   **SenseDataArray,

+  UINTN                 *NumberOfSenseKeys,

+  UINT64                Timeout,

+  UINT8                 *DataBuffer,

+  UINT32                *DataLength,

+  UINT32                StartLba,

+  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  Timeout           - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  StartLba          - TODO: add argument description

+  SectorSize        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UINT8       SenseDataLength;

+  EFI_STATUS  Status;

+  UINT8       HostAdapterStatus;

+  UINT8       TargetStatus;

+

+  *NeedRetry          = FALSE;

+  *NumberOfSenseKeys  = 0;

+  SenseDataLength     = 0;

+  Status = SubmitRead10Command (

+            ScsiDiskDevice->ScsiIo,

+            Timeout,

+            NULL,

+            &SenseDataLength,

+            &HostAdapterStatus,

+            &TargetStatus,

+            DataBuffer,

+            DataLength,

+            StartLba,

+            SectorSize

+            );

+  return Status;

+}

+

+EFI_STATUS

+ScsiDiskWrite10 (

+  SCSI_DISK_DEV         *ScsiDiskDevice,

+  BOOLEAN               *NeedRetry,

+  EFI_SCSI_SENSE_DATA   **SenseDataArray,

+  UINTN                 *NumberOfSenseKeys,

+  UINT64                Timeout,

+  UINT8                 *DataBuffer,

+  UINT32                *DataLength,

+  UINT32                StartLba,

+  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  Timeout           - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  StartLba          - TODO: add argument description

+  SectorSize        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       SenseDataLength;

+  UINT8       HostAdapterStatus;

+  UINT8       TargetStatus;

+

+  *NeedRetry          = FALSE;

+  *NumberOfSenseKeys  = 0;

+  SenseDataLength     = 0;

+  Status = SubmitWrite10Command (

+            ScsiDiskDevice->ScsiIo,

+            Timeout,

+            NULL,

+            &SenseDataLength,

+            &HostAdapterStatus,

+            &TargetStatus,

+            DataBuffer,

+            DataLength,

+            StartLba,

+            SectorSize

+            );

+  return Status;

+}

+

+BOOLEAN

+ScsiDiskIsNoMedia (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsNoMedia;

+

+  IsNoMedia = FALSE;

+  SensePtr  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    //

+    // Sense Key is EFI_SCSI_SK_NOT_READY (0x2),

+    // Additional Sense Code is ASC_NO_MEDIA (0x3A)

+    //

+    if ((SensePtr->Sense_Key == EFI_SCSI_SK_NOT_READY) &&

+        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_NO_MEDIA)) {

+      IsNoMedia = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return IsNoMedia;

+}

+

+BOOLEAN

+ScsiDiskIsMediaError (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsError;

+

+  IsError   = FALSE;

+  SensePtr  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    switch (SensePtr->Sense_Key) {

+

+    case EFI_SCSI_SK_MEDIUM_ERROR:

+      //

+      // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)

+      //

+      switch (SensePtr->Addnl_Sense_Code) {

+

+      //

+      // fall through

+      //

+      case EFI_SCSI_ASC_MEDIA_ERR1:

+

+      //

+      // fall through

+      //

+      case EFI_SCSI_ASC_MEDIA_ERR2:

+

+      //

+      // fall through

+      //

+      case EFI_SCSI_ASC_MEDIA_ERR3:

+      case EFI_SCSI_ASC_MEDIA_ERR4:

+        IsError = TRUE;

+        break;

+

+      default:

+        break;

+      }

+

+      break;

+

+    case EFI_SCSI_SK_NOT_READY:

+      //

+      // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)

+      //

+      switch (SensePtr->Addnl_Sense_Code) {

+      //

+      // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)

+      //

+      case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN:

+        IsError = TRUE;

+        break;

+

+      default:

+        break;

+      }

+      break;

+

+    default:

+      break;

+    }

+

+    SensePtr++;

+  }

+

+  return IsError;

+}

+

+BOOLEAN

+ScsiDiskIsHardwareError (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsError;

+

+  IsError   = FALSE;

+  SensePtr  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    

+    //

+    // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)

+    //

+    if (SensePtr->Sense_Key == EFI_SCSI_SK_HARDWARE_ERROR) {

+      IsError = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return IsError;

+}

+

+BOOLEAN

+ScsiDiskIsMediaChange (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsMediaChanged;

+

+  IsMediaChanged  = FALSE;

+  SensePtr        = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    //

+    // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6),

+    // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)

+    //

+    if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&

+        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_MEDIA_CHANGE)) {

+      IsMediaChanged = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return IsMediaChanged;

+}

+

+BOOLEAN

+ScsiDiskIsResetBefore (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsResetBefore;

+

+  IsResetBefore = FALSE;

+  SensePtr      = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    

+    //

+    // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)

+    // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)

+    //

+    if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&

+        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_RESET)) {

+      IsResetBefore = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return IsResetBefore;

+}

+

+BOOLEAN

+ScsiDiskIsDriveReady (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts,

+  OUT BOOLEAN               *RetryLater

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+  RetryLater  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsReady;

+

+  IsReady     = TRUE;

+  *RetryLater = FALSE;

+  SensePtr    = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    switch (SensePtr->Sense_Key) {

+

+    case EFI_SCSI_SK_NOT_READY:

+      //

+      // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)

+      //

+      switch (SensePtr->Addnl_Sense_Code) {

+      case EFI_SCSI_ASC_NOT_READY:

+        //

+        // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)

+        //

+        switch (SensePtr->Addnl_Sense_Code_Qualifier) {

+        case EFI_SCSI_ASCQ_IN_PROGRESS:

+          //

+          // Additional Sense Code Qualifier is

+          // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)

+          //

+          IsReady     = FALSE;

+          *RetryLater = TRUE;

+          break;

+

+        default:

+          IsReady     = FALSE;

+          *RetryLater = FALSE;

+          break;

+        }

+        break;

+

+      default:

+        break;

+      }

+      break;

+

+    default:

+      break;

+    }

+

+    SensePtr++;

+  }

+

+  return IsReady;

+}

+

+BOOLEAN

+ScsiDiskHaveSenseKey (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SCSI_SENSE_DATA *SensePtr;

+  UINTN               Index;

+  BOOLEAN             HaveSenseKey;

+

+  if (SenseCounts == 0) {

+    HaveSenseKey = FALSE;

+  } else {

+    HaveSenseKey = TRUE;

+  }

+

+  SensePtr = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    

+    //

+    // Sense Key is SK_NO_SENSE (0x0)

+    //

+    if ((SensePtr->Sense_Key == EFI_SCSI_SK_NO_SENSE) &&

+        (Index == 0)) {

+      HaveSenseKey = FALSE;

+    }

+

+    SensePtr++;

+  }

+

+  return HaveSenseKey;

+}

+

+VOID

+ReleaseScsiDiskDeviceResources (

+  IN  SCSI_DISK_DEV   *ScsiDiskDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  if (ScsiDiskDevice == NULL) {

+    return ;

+  }

+

+  if (ScsiDiskDevice->SenseData != NULL) {

+    gBS->FreePool (ScsiDiskDevice->SenseData);

+    ScsiDiskDevice->SenseData = NULL;

+  }

+

+  if (ScsiDiskDevice->ControllerNameTable != NULL) {

+    FreeUnicodeStringTable (ScsiDiskDevice->ControllerNameTable);

+    ScsiDiskDevice->ControllerNameTable = NULL;

+  }

+

+  gBS->FreePool (ScsiDiskDevice);

+

+  ScsiDiskDevice = NULL;

+}

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h
new file mode 100644
index 0000000..96d1da4
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h
@@ -0,0 +1,728 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ScsiDisk.h

+

+Abstract:

+  

+  Header file for SCSI Disk Driver.

+

+--*/

+

+#ifndef _SCSI_DISK_H

+#define _SCSI_DISK_H

+

+

+#include <IndustryStandard/scsi.h>

+

+#define IsDeviceFixed(a)        (a)->FixedDevice ? 1 : 0

+

+#define SCSI_DISK_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'c', 'd', 'k')

+

+typedef struct {

+  UINT32                    Signature;

+

+  EFI_HANDLE                Handle;

+

+  EFI_BLOCK_IO_PROTOCOL     BlkIo;

+  EFI_BLOCK_IO_MEDIA        BlkIoMedia;

+  EFI_SCSI_IO_PROTOCOL      *ScsiIo;

+  UINT8                     DeviceType;

+  BOOLEAN                   FixedDevice;

+  UINT16                    Reserved;

+

+  EFI_SCSI_SENSE_DATA       *SenseData;

+  UINTN                     SenseDataNumber;

+  EFI_SCSI_INQUIRY_DATA     InquiryData;

+

+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;

+

+} SCSI_DISK_DEV;

+

+#define SCSI_DISK_DEV_FROM_THIS(a)  CR (a, SCSI_DISK_DEV, BlkIo, SCSI_DISK_DEV_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gScsiDiskDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gScsiDiskComponentName;

+//

+// action code used in detect media process

+//

+#define ACTION_NO_ACTION            0x00

+#define ACTION_READ_CAPACITY        0x01

+#define ACTION_RETRY_COMMAND_LATER  0x02

+

+EFI_STATUS

+EFIAPI

+ScsiDiskReset (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  BOOLEAN                 ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+ScsiDiskReadBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  LBA         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+ScsiDiskWriteBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  IN  VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  LBA         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+ScsiDiskFlushBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskDetectMedia (

+  SCSI_DISK_DEV   *ScsiDiskDevice,

+  BOOLEAN         MustReadCap,

+  BOOLEAN         *MediaChange

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  MustReadCap     - TODO: add argument description

+  MediaChange     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+  

+EFI_STATUS

+ScsiDiskTestUnitReady (

+  SCSI_DISK_DEV        *ScsiDiskDevice,

+  BOOLEAN              *NeedRetry,

+  EFI_SCSI_SENSE_DATA  **SenseDataArray,

+  UINTN                *NumberOfSenseKeys

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+DetectMediaParsingSenseKeys (

+  SCSI_DISK_DEV           *ScsiDiskDevice,

+  EFI_SCSI_SENSE_DATA     *SenseData,

+  UINTN                   NumberOfSenseKeys,

+  UINTN                   *Action

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  SenseData         - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  Action            - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskReadCapacity (

+  SCSI_DISK_DEV           *ScsiDiskDevice,

+  BOOLEAN                 *NeedRetry,

+  EFI_SCSI_SENSE_DATA     **SenseDataArray,

+  UINTN                   *NumberOfSenseKeys

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CheckHostAdapterStatus (

+  UINT8   HostAdapterStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  HostAdapterStatus - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+CheckTargetStatus (

+  UINT8   TargetStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  TargetStatus  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskRequestSenseKeys (

+  SCSI_DISK_DEV           *ScsiDiskDevice,

+  BOOLEAN                 *NeedRetry,

+  EFI_SCSI_SENSE_DATA     **SenseDataArray,

+  UINTN                   *NumberOfSenseKeys,

+  BOOLEAN                 AskResetIfError

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  AskResetIfError   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskInquiryDevice (

+  SCSI_DISK_DEV   *ScsiDiskDevice,

+  BOOLEAN         *NeedRetry

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  NeedRetry       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+ParseInquiryData (

+  SCSI_DISK_DEV   *ScsiDiskDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskReadSectors (

+  SCSI_DISK_DEV     *ScsiDiskDevice,

+  VOID              *Buffer,

+  EFI_LBA           Lba,

+  UINTN             NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  Buffer          - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskWriteSectors (

+  SCSI_DISK_DEV     *ScsiDiskDevice,

+  VOID              *Buffer,

+  EFI_LBA           Lba,

+  UINTN             NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  Buffer          - TODO: add argument description

+  Lba             - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskRead10 (

+  SCSI_DISK_DEV         *ScsiDiskDevice,

+  BOOLEAN               *NeedRetry,

+  EFI_SCSI_SENSE_DATA   **SenseDataArray,

+  UINTN                 *NumberOfSenseKeys,

+  UINT64                Timeout,

+  UINT8                 *DataBuffer,

+  UINT32                *DataLength,

+  UINT32                StartLba,

+  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  Timeout           - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  StartLba          - TODO: add argument description

+  SectorSize        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+ScsiDiskWrite10 (

+  SCSI_DISK_DEV         *ScsiDiskDevice,

+  BOOLEAN               *NeedRetry,

+  EFI_SCSI_SENSE_DATA   **SenseDataArray,

+  UINTN                 *NumberOfSenseKeys,

+  UINT64                Timeout,

+  UINT8                 *DataBuffer,

+  UINT32                *DataLength,

+  UINT32                StartLba,

+  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice    - TODO: add argument description

+  NeedRetry         - TODO: add argument description

+  SenseDataArray    - TODO: add argument description

+  NumberOfSenseKeys - TODO: add argument description

+  Timeout           - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  StartLba          - TODO: add argument description

+  SectorSize        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+GetMediaInfo (

+  SCSI_DISK_DEV                 *ScsiDiskDevice,

+  EFI_SCSI_DISK_CAPACITY_DATA   *Capacity

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+  Capacity        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskIsNoMedia (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskIsMediaError (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskIsHardwareError (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskIsMediaChange (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskIsResetBefore (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskIsDriveReady (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts,

+  OUT BOOLEAN               *NeedRetry

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+  NeedRetry   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+ScsiDiskHaveSenseKey (

+  IN  EFI_SCSI_SENSE_DATA   *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SenseData   - TODO: add argument description

+  SenseCounts - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+ReleaseScsiDiskDeviceResources (

+  IN  SCSI_DISK_DEV   *ScsiDiskDevice

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiDiskDevice  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd
new file mode 100644
index 0000000..ec19f96
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>ScsiDisk</BaseName>

+    <Guid>0A66E322-3740-4cce-AD62-BD172CECCA35</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkScsiLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa
new file mode 100644
index 0000000..5248576
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>ScsiDisk</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>0A66E322-3740-4cce-AD62-BD172CECCA35</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Scsi Disk module.Revision History</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkScsiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ScsiDisk.h</Filename>

+    <Filename>ScsiDisk.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">ScsiIo</Protocol>

+    <Protocol Usage="BY_START">BlockIo</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gScsiDiskDriverBinding</DriverBinding>

+      <ComponentName>gScsiDiskComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml
new file mode 100644
index 0000000..4117857
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="ScsiDisk"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Scsi/ScsiDisk/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="ScsiDisk">

+      <GenBuild baseName="ScsiDisk" mbdFilename="${MODULE_DIR}/ScsiDisk.mbd" msaFilename="${MODULE_DIR}/ScsiDisk.msa"/>

+   </target>

+   <target depends="ScsiDisk_clean" name="clean"/>

+   <target depends="ScsiDisk_cleanall" name="cleanall"/>

+   <target name="ScsiDisk_clean">

+      <OutputDirSetup baseName="ScsiDisk" mbdFilename="${MODULE_DIR}/ScsiDisk.mbd" msaFilename="${MODULE_DIR}/ScsiDisk.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ScsiDisk_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ScsiDisk_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="ScsiDisk_cleanall">

+      <OutputDirSetup baseName="ScsiDisk" mbdFilename="${MODULE_DIR}/ScsiDisk.mbd" msaFilename="${MODULE_DIR}/ScsiDisk.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ScsiDisk_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ScsiDisk_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**ScsiDisk*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/ComponentName.c
new file mode 100644
index 0000000..6a9cf13
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/ComponentName.c
@@ -0,0 +1,190 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "bot.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UsbBotComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UsbBotComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gUsbBotComponentName = {

+  UsbBotComponentNameGetDriverName,

+  UsbBotComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mUsbBotDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Usb Bot Mass Storage Driver" },

+  { NULL , NULL }

+};

+

+

+EFI_STATUS

+EFIAPI

+UsbBotComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUsbBotComponentName.SupportedLanguages,

+          mUsbBotDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UsbBotComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS              Status;

+  USB_BOT_DEVICE          *UsbBotDev;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapi;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the device context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  (VOID **) &UsbAtapi,

+                  gUsbBotDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UsbBotDev = USB_BOT_DEVICE_FROM_THIS (UsbAtapi);

+

+  return LookupUnicodeString (

+          Language,

+          gUsbBotComponentName.SupportedLanguages,

+          UsbBotDev->ControllerNameTable,

+          ControllerName

+          );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/UsbBot.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/UsbBot.mbd
new file mode 100644
index 0000000..1d18c75
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/UsbBot.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbBot</BaseName>

+    <Guid>B40612B9-A063-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/UsbBot.msa b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/UsbBot.msa
new file mode 100644
index 0000000..a0f85b9
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/UsbBot.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbBot</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>B40612B9-A063-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbBot module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>bot.h</Filename>

+    <Filename>bot.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">UsbIo</Protocol>

+    <Protocol Usage="BY_START">UsbAtapi</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUsbBotDriverBinding</DriverBinding>

+      <ComponentName>gUsbBotComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
new file mode 100644
index 0000000..0aa0507
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
@@ -0,0 +1,1088 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BOT.c

+

+Abstract:

+

+--*/

+

+#include "bot.h"

+

+//

+// Function prototypes

+//

+EFI_STATUS

+EFIAPI

+UsbBotDriverEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+//

+// Bot Driver Binding Protocol

+//

+EFI_STATUS

+EFIAPI

+BotDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+BotDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+BotDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+

+EFI_DRIVER_BINDING_PROTOCOL   gUsbBotDriverBinding = {

+  BotDriverBindingSupported,

+  BotDriverBindingStart,

+  BotDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+//

+// Bot Protocol

+//

+STATIC

+EFI_STATUS

+BotCommandPhase (

+  IN  USB_BOT_DEVICE            *UsbBotDev,

+  IN  VOID                      *Command,

+  IN  UINT8                     CommandSize,

+  IN  UINT32                    DataTransferLength,

+  IN  EFI_USB_DATA_DIRECTION    Direction,

+  IN  UINT16                    Timeout

+  );

+

+STATIC

+EFI_STATUS

+BotDataPhase (

+  IN     USB_BOT_DEVICE            *UsbBotDev,

+  IN     UINT32                    *DataSize,

+  IN OUT VOID                      *DataBuffer,

+  IN     EFI_USB_DATA_DIRECTION    Direction,

+  IN     UINT16                    Timeout

+  );

+

+STATIC

+EFI_STATUS

+BotStatusPhase (

+  IN  USB_BOT_DEVICE      *UsbBotDev,

+  OUT UINT8               *TransferStatus,

+  IN  UINT16              Timeout

+  );

+

+//

+// USB Atapi protocol prototype

+//

+STATIC

+EFI_STATUS

+EFIAPI

+BotAtapiCommand (

+  IN  EFI_USB_ATAPI_PROTOCOL    *This,

+  IN  VOID                      *Command,

+  IN  UINT8                     CommandSize,

+  IN  VOID                      *DataBuffer,

+  IN  UINT32                    BufferLength,

+  IN  EFI_USB_DATA_DIRECTION    Direction,

+  IN  UINT16                    TimeOutInMilliSeconds

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+BotMassStorageReset (

+  IN  EFI_USB_ATAPI_PROTOCOL    *This,

+  IN  BOOLEAN                   ExtendedVerification

+  );

+

+VOID

+BotReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  );

+

+STATIC EFI_USB_ATAPI_PROTOCOL BotAtapiProtocol = {

+  BotAtapiCommand,

+  BotMassStorageReset,

+  0

+};

+

+EFI_STATUS

+EFIAPI

+BotDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    than contains a BlockIo and DiskIo protocol can be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device

+    EFI_ALREADY_STARTED - This driver is already running on this device

+    other               - This driver does not support this device

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+

+  //

+  // Check if the Controller supports USB IO protocol

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the Default interface descriptor, now we only

+  // suppose interface 1

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Status)) {

+    goto Exit;

+  }

+  //

+  // Check if it is a BOT type Mass Storage Device

+  //

+  if ((InterfaceDescriptor.InterfaceClass    != 0x08) ||

+      (InterfaceDescriptor.InterfaceProtocol != BOT)) {

+    Status = EFI_UNSUPPORTED;

+    goto Exit;

+  }

+

+Exit:

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+BotDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Start this driver on ControllerHandle by opening a Block IO and Disk IO

+    protocol, reading Device Path, and creating a child handle with a

+    Disk IO and device path protocol.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to bind driver to

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver is added to DeviceHandle

+    EFI_ALREADY_STARTED - This driver is already running on DeviceHandle

+    EFI_OUT_OF_RESOURCES- Can't allocate the memory resource

+    other               - This driver does not support this device

+

+--*/

+{

+  USB_BOT_DEVICE                *UsbBotDev;

+  UINT8                         Index;

+  EFI_USB_ENDPOINT_DESCRIPTOR   *EndpointDescriptor;

+  EFI_USB_INTERFACE_DESCRIPTOR  *InterfaceDescriptor;

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+

+  //

+  // Check if the Controller supports USB IO protocol

+  //

+  UsbBotDev = NULL;

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  InterfaceDescriptor = AllocateZeroPool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR));

+  if (InterfaceDescriptor == NULL) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Get the controller interface descriptor,

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (InterfaceDescriptor);

+    goto ErrorExit;

+  }

+

+  BotAtapiProtocol.CommandProtocol  = InterfaceDescriptor->InterfaceSubClass;

+

+  UsbBotDev                         = AllocateZeroPool (sizeof (USB_BOT_DEVICE));

+  if (UsbBotDev == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    gBS->FreePool (InterfaceDescriptor);

+    goto ErrorExit;

+  }

+

+  UsbBotDev->Signature            = USB_BOT_DEVICE_SIGNATURE;

+  UsbBotDev->UsbIo                = UsbIo;

+  UsbBotDev->InterfaceDescriptor  = InterfaceDescriptor;

+  CopyMem (&UsbBotDev->UsbAtapiProtocol, &BotAtapiProtocol, sizeof (BotAtapiProtocol));

+

+  //

+  // Get the Device Path Protocol on Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &UsbBotDev->DevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  for (Index = 0; Index < InterfaceDescriptor->NumEndpoints; Index++) {

+    EndpointDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR));

+    if (EndpointDescriptor == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto ErrorExit;

+    }

+

+    UsbIo->UsbGetEndpointDescriptor (

+            UsbIo,

+            Index,

+            EndpointDescriptor

+            );

+

+    //

+    // We parse bulk endpoint

+    //

+    if ((EndpointDescriptor->Attributes & 0x03) == 0x02) {

+      if ((EndpointDescriptor->EndpointAddress & 0x80) != 0) {

+        UsbBotDev->BulkInEndpointDescriptor = EndpointDescriptor;

+      } else {

+        UsbBotDev->BulkOutEndpointDescriptor = EndpointDescriptor;

+      }

+

+      continue;

+    }

+

+    gBS->FreePool (EndpointDescriptor);

+  }

+  //

+  // Double check we have these endpoint descriptors

+  //

+  if (!(UsbBotDev->BulkInEndpointDescriptor &&

+        UsbBotDev->BulkOutEndpointDescriptor)) {

+    Status = EFI_DEVICE_ERROR;

+    goto ErrorExit;

+  }

+  //

+  // After installing Usb-Atapi protocol onto this handle

+  // it will be called by upper layer drivers such as Fat

+  //

+  BotReportStatusCode (

+    UsbBotDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)

+    );

+

+  //

+  // Install Usb-Atapi Protocol onto the handle

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &UsbBotDev->UsbAtapiProtocol

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  UsbBotDev->ControllerNameTable = NULL;

+  AddUnicodeString (

+    "eng",

+    gUsbBotComponentName.SupportedLanguages,

+    &UsbBotDev->ControllerNameTable,

+    (CHAR16 *) L"Usb Bot Mass Storage"

+    );

+

+  return EFI_SUCCESS;

+

+ErrorExit:

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  if (UsbBotDev != NULL) {

+    if (UsbBotDev->InterfaceDescriptor != NULL) {

+      gBS->FreePool (UsbBotDev->InterfaceDescriptor);

+    }

+

+    if (UsbBotDev->BulkInEndpointDescriptor != NULL) {

+      gBS->FreePool (UsbBotDev->BulkInEndpointDescriptor);

+    }

+

+    if (UsbBotDev->BulkOutEndpointDescriptor != NULL) {

+      gBS->FreePool (UsbBotDev->BulkOutEndpointDescriptor);

+    }

+

+    gBS->FreePool (UsbBotDev);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+BotDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    ControllerHandle  - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS       - This driver is removed DeviceHandle

+    EFI_UNSUPPORTED   - Can't open the gEfiUsbAtapiProtocolGuid protocl  

+    other             - This driver was not removed from this device

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_USB_ATAPI_PROTOCOL  *BotAtapiProtocol;

+  USB_BOT_DEVICE          *UsbBotDev;

+

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  (VOID **) &BotAtapiProtocol,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  UsbBotDev = USB_BOT_DEVICE_FROM_THIS (BotAtapiProtocol);

+

+  //

+  // After installing Usb-Atapi protocol onto this handle

+  // it will be called by upper layer drivers such as Fat

+  //

+  UsbIo = UsbBotDev->UsbIo;

+

+  BotReportStatusCode (

+    UsbBotDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)

+    );

+

+  //

+  // Uninstall protocol

+  //

+  Status = gBS->UninstallProtocolInterface (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  &UsbBotDev->UsbAtapiProtocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->CloseProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  This->DriverBindingHandle,

+                  ControllerHandle

+                  );

+  //

+  // Free all allocated resources

+  //

+  if (UsbBotDev->InterfaceDescriptor != NULL) {

+    gBS->FreePool (UsbBotDev->InterfaceDescriptor);

+  }

+

+  if (UsbBotDev->BulkInEndpointDescriptor != NULL) {

+    gBS->FreePool (UsbBotDev->BulkInEndpointDescriptor);

+  }

+

+  if (UsbBotDev->BulkOutEndpointDescriptor != NULL) {

+    gBS->FreePool (UsbBotDev->BulkOutEndpointDescriptor);

+  }

+

+  if (UsbBotDev->ControllerNameTable) {

+    FreeUnicodeStringTable (UsbBotDev->ControllerNameTable);

+  }

+

+  gBS->FreePool (UsbBotDev);

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+BotRecoveryReset (

+  IN  USB_BOT_DEVICE          *UsbBotDev

+  )

+/*++

+

+Routine Description:

+

+  Bot reset routine

+

+Arguments:

+

+  UsbBotDev - USB_BOT_DEVICE pointer

+

+Returns:

+  EFI_SUCCESS - Success the operation

+  

+--*/

+{

+  EFI_STATUS              Status;

+  UINT32                  Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+  UINT8                   EndpointAddr;

+

+  UsbIo = UsbBotDev->UsbIo;

+

+  BotReportStatusCode (

+    UsbBotDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)

+    );

+

+  ZeroMem (&Request, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // See BOT specification

+  //

+  Request.RequestType = 0x21;

+  Request.Request     = 0xFF;

+

+  Status = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbNoData,

+                    TIMEOUT_VALUE,

+                    NULL,

+                    0,

+                    &Result

+                    );

+

+  gBS->Stall (100 * 1000);

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // clear bulk in endpoint stall feature

+    //

+    EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;

+

+    Status = UsbClearEndpointHalt (

+               UsbIo,

+               EndpointAddr,

+               &Result

+               );

+

+    //

+    // clear bulk out endpoint stall feature

+    //

+    EndpointAddr = UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress;

+    Status = UsbClearEndpointHalt (

+               UsbIo,

+               EndpointAddr,

+               &Result

+               );

+  }

+

+  return Status;

+}

+//

+// Bot Protocol Implementation

+//

+STATIC

+EFI_STATUS

+BotCommandPhase (

+  IN  USB_BOT_DEVICE          *UsbBotDev,

+  IN  VOID                    *Command,

+  IN  UINT8                   CommandSize,

+  IN  UINT32                  DataTransferLength,

+  IN  EFI_USB_DATA_DIRECTION  Direction,

+  IN  UINT16                  Timeout

+  )

+/*++

+

+  Routine Description:

+    Send ATAPI command through BOT interface.

+

+  Parameters:

+    UsbBotDev           -   USB_BOT_DEVICE

+    Command             -   command packet

+    CommandSize         -   Command size

+    DataTransferLength  -   Data Transfer Length

+    Direction           -   Data IN/OUT/NODATA

+    Timeout             -   Time out value in milliseconds

+  Return Values:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  CBW                 cbw;

+  EFI_STATUS          Status;

+  UINT32              Result;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINTN               DataSize;

+

+  UsbIo = UsbBotDev->UsbIo;

+

+  ZeroMem (&cbw, sizeof (CBW));

+

+  //

+  // Fill the command block, detailed see BOT spec

+  //

+  cbw.dCBWSignature           = CBWSIG;

+  cbw.dCBWTag                 = 0x01;

+  cbw.dCBWDataTransferLength  = DataTransferLength;

+  cbw.bmCBWFlags              = (UINT8) (Direction << 7);

+  cbw.bCBWCBLength            = CommandSize;

+

+  CopyMem (cbw.CBWCB, Command, CommandSize);

+

+  DataSize = sizeof (CBW);

+

+  Status = UsbIo->UsbBulkTransfer (

+                    UsbIo,

+                    (UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress,

+                    &cbw,

+                    &DataSize,

+                    Timeout,

+                    &Result

+                    );

+  if (EFI_ERROR (Status)) {

+    //

+    // Command phase fail, we need to recovery reset this device

+    //

+    BotRecoveryReset (UsbBotDev);

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+BotDataPhase (

+  IN      USB_BOT_DEVICE            *UsbBotDev,

+  IN      UINT32                    *DataSize,

+  IN  OUT VOID                      *DataBuffer,

+  IN      EFI_USB_DATA_DIRECTION    Direction,

+  IN      UINT16                    Timeout

+  )

+/*++

+

+  Routine Description:

+    Get/Send Data through BOT interface

+

+  Parameters:

+    UsbBotDev    -  USB_BOT_DEVICE pointer

+    DataSize     -  Data size

+    DataBuffer   -  Data buffer pointer

+    Direction    -  IN/OUT/NODATA

+    Timeout      -  Time out value in milliseconds

+  Return Value:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  EFI_STATUS          Status;

+  UINT32              Result;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               EndpointAddr;

+  UINTN               Remain;

+  UINTN               Increment;

+  UINT32              MaxPacketLen;

+  UINT8               *BufferPtr;

+  UINTN               TransferredSize;

+  UINTN               RetryTimes;

+  UINTN               MaxRetry;

+  UINTN               BlockSize;

+  UINTN               PackageNum;

+

+  UsbIo           = UsbBotDev->UsbIo;

+  Remain          = *DataSize;

+  BufferPtr       = (UINT8 *) DataBuffer;

+  TransferredSize = 0;

+  MaxRetry        = 10;

+  PackageNum      = 15;

+

+  //

+  // retrieve the the max packet length of the given endpoint

+  //

+  if (Direction == EfiUsbDataIn) {

+    MaxPacketLen  = (UsbBotDev->BulkInEndpointDescriptor)->MaxPacketSize;

+    EndpointAddr  = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;

+  } else {

+    MaxPacketLen  = (UsbBotDev->BulkOutEndpointDescriptor)->MaxPacketSize;

+    EndpointAddr  = (UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress;

+  }

+

+  RetryTimes  = MaxRetry;

+  BlockSize   = PackageNum * MaxPacketLen;

+  while (Remain > 0) {

+    //

+    // Using 15 packets to aVOID Bitstuff error

+    //

+    if (Remain > PackageNum * MaxPacketLen) {

+      Increment = BlockSize;

+    } else {

+      Increment = Remain;

+    }

+

+    Status = UsbIo->UsbBulkTransfer (

+                      UsbIo,

+                      EndpointAddr,

+                      BufferPtr,

+                      &Increment,

+                      Timeout,

+                      &Result

+                      );

+

+    TransferredSize += Increment;

+

+    if (EFI_ERROR (Status)) {

+      RetryTimes--;

+      if ((RetryTimes == 0) || ((Result & EFI_USB_ERR_TIMEOUT) == 0)) {

+        goto ErrorExit;

+      }

+

+      TransferredSize -= Increment;

+      continue;

+    } else {

+      //

+      // we try MaxTetry times for every bulk transfer

+      //

+      RetryTimes = MaxRetry;

+    }

+

+    BufferPtr += Increment;

+    Remain -= Increment;

+    if (Increment < BlockSize && TransferredSize <= *DataSize) {

+      //

+      // we get to the end of transter and transter size is

+      // less than requriedsize

+      //

+      break;

+    }

+  }

+

+  *DataSize = (UINT32) TransferredSize;

+

+  return EFI_SUCCESS;

+

+ErrorExit:

+  if (Direction == EfiUsbDataIn) {

+    BotReportStatusCode (

+      UsbBotDev->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)

+      );

+  } else {

+    BotReportStatusCode (

+      UsbBotDev->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)

+      );

+  }

+

+  if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+    //

+    // just endpoint stall happens

+    //

+    UsbClearEndpointHalt (

+      UsbIo,

+      EndpointAddr,

+      &Result

+      );

+  }

+

+  *DataSize = (UINT32) TransferredSize;

+

+  return Status;

+

+}

+

+STATIC

+EFI_STATUS

+BotStatusPhase (

+  IN  USB_BOT_DEVICE        *UsbBotDev,

+  OUT UINT8                 *TransferStatus,

+  IN  UINT16                Timeout

+  )

+/*++

+

+  Routine Description:

+    Get transfer status through BOT interface

+

+  Parameters:

+    UsbBotDev       -  USB_BOT_DEVICE pointer

+    TransferStatus  -  TransferStatus

+    Timeout         -  Time out value in milliseconds

+  Return Value:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  CSW                 csw;

+  EFI_STATUS          Status;

+  UINT32              Result;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               EndpointAddr;

+  UINTN               DataSize;

+

+  UsbIo = UsbBotDev->UsbIo;

+

+  ZeroMem (&csw, sizeof (CSW));

+

+  EndpointAddr  = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;

+

+  DataSize      = sizeof (CSW);

+

+  //

+  // Get the status field from bulk transfer

+  //

+  Status = UsbIo->UsbBulkTransfer (

+                    UsbIo,

+                    EndpointAddr,

+                    &csw,

+                    &DataSize,

+                    Timeout,

+                    &Result

+                    );

+  if (EFI_ERROR (Status)) {

+    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+      //

+      // just endpoint stall happens

+      //

+      UsbClearEndpointHalt (

+        UsbIo,

+        EndpointAddr,

+        &Result

+        );

+    }

+

+    ZeroMem (&csw, sizeof (CSW));

+

+    EndpointAddr  = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;

+

+    DataSize      = sizeof (CSW);

+    Status = UsbIo->UsbBulkTransfer (

+                      UsbIo,

+                      EndpointAddr,

+                      &csw,

+                      &DataSize,

+                      Timeout,

+                      &Result

+                      );

+    if (EFI_ERROR (Status)) {

+      if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+        UsbClearEndpointHalt (

+          UsbIo,

+          EndpointAddr,

+          &Result

+          );

+      }

+

+      return Status;

+    }

+  }

+

+  if (csw.dCSWSignature == CSWSIG) {

+    *TransferStatus = csw.bCSWStatus;

+  } else {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// Usb Atapi Protocol implementation

+//

+EFI_STATUS

+EFIAPI

+BotAtapiCommand (

+  IN  EFI_USB_ATAPI_PROTOCOL      *This,

+  IN  VOID                        *Command,

+  IN  UINT8                       CommandSize,

+  IN  VOID                        *DataBuffer,

+  IN  UINT32                      BufferLength,

+  IN  EFI_USB_DATA_DIRECTION      Direction,

+  IN  UINT16                      TimeOutInMilliSeconds

+  )

+/*++

+

+  Routine Description:

+    Send ATAPI command using BOT protocol.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    Command               - Command buffer

+    CommandSize           - Size of Command Buffer

+    DataBuffer            - Data buffer

+    BufferLength          - Length of Data buffer

+    Direction             - Data direction of this command

+    TimeoutInMilliSeconds - Timeout value in ms

+

+  Returns:

+    EFI_SUCCESS         - Command succeeded.

+    EFI_DEVICE_ERROR    - Command failed.

+

+--*/

+{

+  EFI_STATUS      Status;

+  EFI_STATUS      BotDataStatus;

+  UINT8           TransferStatus;

+  USB_BOT_DEVICE  *UsbBotDev;

+  UINT32          BufferSize;

+

+  BotDataStatus = EFI_SUCCESS;

+  TransferStatus = 0;

+

+  //

+  // Get the context

+  //

+  UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);

+

+  //

+  // First send ATAPI command through Bot

+  //

+  Status = BotCommandPhase (

+            UsbBotDev,

+            Command,

+            CommandSize,

+            BufferLength,

+            Direction,

+            TimeOutInMilliSeconds

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Send/Get Data if there is a Data Stage

+  //

+  switch (Direction) {

+

+  case EfiUsbDataIn:

+  case EfiUsbDataOut:

+    BufferSize = BufferLength;

+

+    BotDataStatus = BotDataPhase (

+                      UsbBotDev,

+                      &BufferSize,

+                      DataBuffer,

+                      Direction,

+                      (UINT16) (TimeOutInMilliSeconds)

+                      );

+

+    break;

+

+  case EfiUsbNoData:

+    break;

+  }

+  

+  //

+  // Status Phase

+  //

+  Status = BotStatusPhase (

+            UsbBotDev,

+            &TransferStatus,

+            TimeOutInMilliSeconds

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (TransferStatus == 0x02) {

+    //

+    // Phase error

+    //

+    BotRecoveryReset (UsbBotDev);

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (TransferStatus == 0x01) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return BotDataStatus;

+}

+

+EFI_STATUS

+EFIAPI

+BotMassStorageReset (

+  IN  EFI_USB_ATAPI_PROTOCOL      *This,

+  IN  BOOLEAN                     ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset Bot Devices

+

+  Arguments:

+    This                    - Protocol instance pointer.

+    ExtendedVerification    - TRUE if we need to do strictly reset.

+

+  Returns:

+    EFI_SUCCESS         - Command succeeded.

+    EFI_DEVICE_ERROR    - Command failed.

+

+--*/

+{

+  EFI_STATUS          Status;

+  USB_BOT_DEVICE      *UsbBotDev;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+

+  UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);

+  UsbIo     = UsbBotDev->UsbIo;

+

+  if (ExtendedVerification) {

+    //

+    // If we need to do strictly reset, reset its parent hub port

+    //

+    Status = UsbIo->UsbPortReset (UsbIo);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  Status = BotRecoveryReset (UsbBotDev);

+

+  return Status;

+}

+

+VOID

+BotReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  )

+/*++

+

+  Routine Description:

+    Report Status Code in Usb Bot Driver

+

+  Arguments:

+    DevicePath - Use this to get Device Path

+    CodeType   - Status Code Type

+    CodeValue  - Status Code Value

+

+  Returns:

+    None

+

+--*/

+{

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    CodeType,

+    Value,

+    DevicePath

+    );

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.h b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.h
new file mode 100644
index 0000000..5f9006b
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.h
@@ -0,0 +1,78 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BOT.h

+

+Abstract:

+

+--*/

+

+#ifndef _BOT_H

+#define _BOT_H

+

+

+#include <IndustryStandard/Usb.h>

+

+#pragma pack(1)

+//

+// Bulk Only device protocol

+//

+typedef struct {

+  UINT32  dCBWSignature;

+  UINT32  dCBWTag;

+  UINT32  dCBWDataTransferLength;

+  UINT8   bmCBWFlags;

+  UINT8   bCBWLUN;

+  UINT8   bCBWCBLength;

+  UINT8   CBWCB[16];

+} CBW;

+

+typedef struct {

+  UINT32  dCSWSignature;

+  UINT32  dCSWTag;

+  UINT32  dCSWDataResidue;

+  UINT8   bCSWStatus;

+} CSW;

+

+#pragma pack()

+

+#define USB_BOT_DEVICE_SIGNATURE  EFI_SIGNATURE_32 ('u', 'b', 'o', 't')

+

+typedef struct {

+  UINTN                         Signature;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  EFI_USB_ATAPI_PROTOCOL        UsbAtapiProtocol;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_INTERFACE_DESCRIPTOR  *InterfaceDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   *BulkInEndpointDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   *BulkOutEndpointDescriptor;

+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;

+} USB_BOT_DEVICE;

+

+#define USB_BOT_DEVICE_FROM_THIS(a) \

+    CR(a, USB_BOT_DEVICE, UsbAtapiProtocol, USB_BOT_DEVICE_SIGNATURE)

+

+//

+// Status code, see Usb Bot device spec

+//

+#define CSWSIG  0x53425355

+#define CBWSIG  0x43425355

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gUsbBotDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gUsbBotComponentName;

+extern EFI_GUID                     gUsbBotDriverGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/build.xml
new file mode 100644
index 0000000..905ca30
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBot/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbBot"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbBot/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbBot">

+      <GenBuild baseName="UsbBot" mbdFilename="${MODULE_DIR}/UsbBot.mbd" msaFilename="${MODULE_DIR}/UsbBot.msa"/>

+   </target>

+   <target depends="UsbBot_clean" name="clean"/>

+   <target depends="UsbBot_cleanall" name="cleanall"/>

+   <target name="UsbBot_clean">

+      <OutputDirSetup baseName="UsbBot" mbdFilename="${MODULE_DIR}/UsbBot.mbd" msaFilename="${MODULE_DIR}/UsbBot.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbBot_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbBot_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbBot_cleanall">

+      <OutputDirSetup baseName="UsbBot" mbdFilename="${MODULE_DIR}/UsbBot.mbd" msaFilename="${MODULE_DIR}/UsbBot.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbBot_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbBot_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbBot*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/ComponentName.c
new file mode 100644
index 0000000..8ecbbb0
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/ComponentName.c
@@ -0,0 +1,154 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "usbbus.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UsbBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UsbBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_HANDLE                      ChildHandle, OPTIONAL

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gUsbBusComponentName = {

+  UsbBusComponentNameGetDriverName,

+  UsbBusComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mUsbBusDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"USB Bus Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+UsbBusComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUsbBusComponentName.SupportedLanguages,

+          mUsbBusDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UsbBusComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_HANDLE                      ChildHandle, OPTIONAL

+  IN  CHAR8                           *Language,

+  OUT CHAR16                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.mbd
new file mode 100644
index 0000000..4e46c13
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbBus</BaseName>

+    <Guid>240612B7-A063-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa
new file mode 100644
index 0000000..f841f11
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbBus</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>240612B7-A063-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbBus module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>usbbus.h</Filename>

+    <Filename>usbutil.h</Filename>

+    <Filename>hub.h</Filename>

+    <Filename>usbbus.c</Filename>

+    <Filename>usbio.c</Filename>

+    <Filename>usb.c</Filename>

+    <Filename>usbutil.c</Filename>

+    <Filename>hub.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="BY_START">UsbIo</Protocol>

+    <Protocol Usage="TO_START">UsbHc</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUsbBusDriverBinding</DriverBinding>

+      <ComponentName>gUsbBusComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/build.xml
new file mode 100644
index 0000000..e979dab
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbBus"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbBus/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbBus">

+      <GenBuild baseName="UsbBus" mbdFilename="${MODULE_DIR}/UsbBus.mbd" msaFilename="${MODULE_DIR}/UsbBus.msa"/>

+   </target>

+   <target depends="UsbBus_clean" name="clean"/>

+   <target depends="UsbBus_cleanall" name="cleanall"/>

+   <target name="UsbBus_clean">

+      <OutputDirSetup baseName="UsbBus" mbdFilename="${MODULE_DIR}/UsbBus.mbd" msaFilename="${MODULE_DIR}/UsbBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbBus_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbBus_cleanall">

+      <OutputDirSetup baseName="UsbBus" mbdFilename="${MODULE_DIR}/UsbBus.mbd" msaFilename="${MODULE_DIR}/UsbBus.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbBus_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbBus_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbBus*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.c b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.c
new file mode 100644
index 0000000..fd9e673
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.c
@@ -0,0 +1,507 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    Hub.c

+    

+  Abstract:

+

+    Usb Hub Request

+

+  Revision History

+

+--*/

+

+#include "usbbus.h"

+

+EFI_STATUS

+HubGetPortStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Port,

+  OUT UINT32                  *PortStatus

+  )

+/*++

+  

+  Routine Description:

+    Get a given hub port status

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    Port            -   Usb hub port number (starting from 1).

+    PortStatus      -   Current Hub port status and change status.

+    

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+    EFI_INVALID_PARAMETER

+    

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = HUB_GET_PORT_STATUS_REQ_TYPE;

+  DevReq.Request      = HUB_GET_PORT_STATUS;

+  DevReq.Value        = 0;

+  DevReq.Index        = Port;

+  DevReq.Length       = sizeof (UINT32);

+

+  Timeout             = 3000;

+

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbDataIn,

+                      Timeout,

+                      PortStatus,

+                      sizeof (UINT32),

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+}

+

+EFI_STATUS

+HubSetPortFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Port,

+  IN UINT8                   Value

+  )

+/*++

+  

+  Routine Description:

+    Set specified feature to a give hub port

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    Port            -   Usb hub port number (starting from 1).

+    Value           -   New feature value.

+  

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+    EFI_INVALID_PARAMETER

+  

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = HUB_SET_PORT_FEATURE_REQ_TYPE;

+  DevReq.Request      = HUB_SET_PORT_FEATURE;

+  DevReq.Value        = Value;

+  DevReq.Index        = Port;

+  DevReq.Length       = 0;

+

+  Timeout             = 3000;

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbNoData,

+                      Timeout,

+                      NULL,

+                      0,

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+}

+

+EFI_STATUS

+HubClearPortFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Port,

+  IN UINT8                   Value

+  )

+/*++

+  

+  Routine Description:

+    Clear a specified feature of a given hub port

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    Port            -   Usb hub port number (starting from 1).

+    Value           -   Feature value that will be cleared from

+                        that hub port.

+  

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+    EFI_INVALID_PARAMETER

+  

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = HUB_CLEAR_FEATURE_PORT_REQ_TYPE;

+  DevReq.Request      = HUB_CLEAR_FEATURE_PORT;

+  DevReq.Value        = Value;

+  DevReq.Index        = Port;

+  DevReq.Length       = 0;

+

+  Timeout             = 3000;

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbNoData,

+                      Timeout,

+                      NULL,

+                      0,

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+}

+

+EFI_STATUS

+HubGetHubStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  OUT UINT32                  *HubStatus

+  )

+/*++

+  

+  Routine Description:

+    Get Hub Status

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    HubStatus       -   Current Hub status and change status.

+  

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+  

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = HUB_GET_HUB_STATUS_REQ_TYPE;

+  DevReq.Request      = HUB_GET_HUB_STATUS;

+  DevReq.Value        = 0;

+  DevReq.Index        = 0;

+  DevReq.Length       = sizeof (UINT32);

+

+  Timeout             = 3000;

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbDataIn,

+                      Timeout,

+                      HubStatus,

+                      sizeof (UINT32),

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+}

+

+EFI_STATUS

+HubSetHubFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Value

+  )

+/*++

+  

+  Routine Description:

+    Set a specified feature to the hub

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    Value           -   Feature value that will be set to the hub.

+  

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+  

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = HUB_SET_HUB_FEATURE_REQ_TYPE;

+  DevReq.Request      = HUB_SET_HUB_FEATURE;

+  DevReq.Value        = Value;

+  DevReq.Index        = 0;

+  DevReq.Length       = 0;

+

+  Timeout             = 3000;

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbNoData,

+                      Timeout,

+                      NULL,

+                      0,

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+}

+

+EFI_STATUS

+HubClearHubFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Value

+  )

+/*++

+  

+  Routine Description:

+    Set a specified feature to the hub

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    Value           -   Feature value that will be cleared from the hub.

+  

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+  

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = HUB_CLEAR_FEATURE_REQ_TYPE;

+  DevReq.Request      = HUB_CLEAR_FEATURE;

+  DevReq.Value        = Value;

+  DevReq.Index        = 0;

+  DevReq.Length       = 0;

+

+  Timeout             = 3000;

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbNoData,

+                      Timeout,

+                      NULL,

+                      0,

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+

+}

+

+EFI_STATUS

+GetHubDescriptor (

+  IN  EFI_USB_IO_PROTOCOL        *UsbIo,

+  IN  UINTN                      DescriptorSize,

+  OUT EFI_USB_HUB_DESCRIPTOR     *HubDescriptor

+  )

+/*++

+  

+  Routine Description:

+    Get the hub descriptor

+  

+  Arguments:

+    UsbIo           -   EFI_USB_IO_PROTOCOL instance

+    DescriptorSize  -   The length of Hub Descriptor buffer.

+    HubDescriptor   -   Caller allocated buffer to store the hub descriptor

+                        if successfully returned.

+                              

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE

+    EFI_TIME_OUT

+  

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+  EFI_STATUS              EfiStatus;

+  UINT32                  UsbStatus;

+  UINT32                  Timeout;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Fill Device request packet

+  //

+  DevReq.RequestType  = USB_RT_HUB | 0x80;

+  DevReq.Request      = HUB_GET_DESCRIPTOR;

+  DevReq.Value        = USB_DT_HUB << 8;

+  DevReq.Index        = 0;

+  DevReq.Length       = (UINT16) DescriptorSize;

+

+  Timeout             = 3000;

+  EfiStatus = UsbIo->UsbControlTransfer (

+                      UsbIo,

+                      &DevReq,

+                      EfiUsbDataIn,

+                      Timeout,

+                      HubDescriptor,

+                      (UINT16) DescriptorSize,

+                      &UsbStatus

+                      );

+

+  return EfiStatus;

+

+}

+

+EFI_STATUS

+DoHubConfig (

+  IN USB_IO_CONTROLLER_DEVICE     *HubController

+  )

+/*++

+  

+  Routine Description:

+    Configure the hub

+  

+  Arguments:

+    HubController         -   Indicating the hub controller device that

+                              will be configured

+                                

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    

+--*/

+{

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+  EFI_USB_HUB_DESCRIPTOR  HubDescriptor;

+  EFI_STATUS              Status;

+  EFI_USB_HUB_STATUS      HubStatus;

+  UINTN                   Index;

+  UINT32                  PortStatus;

+

+  UsbIo = &HubController->UsbIo;

+

+  ZeroMem (&HubDescriptor, sizeof (HubDescriptor));

+

+  //

+  // First get the hub descriptor length

+  //

+  Status = GetHubDescriptor (UsbIo, 2, &HubDescriptor);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+    

+  //

+  // First get the whole descriptor, then

+  // get the number of hub ports

+  //

+  Status = GetHubDescriptor (

+            UsbIo,

+            HubDescriptor.Length,

+            &HubDescriptor

+            );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((gUSBErrorLevel, "Get hub descriptor fail\n"));

+    return EFI_DEVICE_ERROR;

+  }

+

+  HubController->DownstreamPorts  = HubDescriptor.NbrPorts;

+

+  Status                          = HubGetHubStatus (UsbIo, (UINT32 *) &HubStatus);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((gUSBErrorLevel, "Get hub status fail when configure\n"));

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  //  Get all hub ports status

+  //

+  for (Index = 0; Index < HubController->DownstreamPorts; Index++) {

+

+    Status = HubGetPortStatus (UsbIo, (UINT8) (Index + 1), &PortStatus);

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+  }

+  //

+  //  Power all the hub ports

+  //

+  for (Index = 0; Index < HubController->DownstreamPorts; Index++) {

+    Status = HubSetPortFeature (

+              UsbIo,

+              (UINT8) (Index + 1),

+              EfiUsbPortPower

+              );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+  }

+  

+  //

+  // Clear Hub Status Change

+  //

+  Status = HubGetHubStatus (UsbIo, (UINT32 *) &HubStatus);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((gUSBErrorLevel, "Get hub status fail\n"));

+    return EFI_DEVICE_ERROR;

+  } else {

+    //

+    // Hub power supply change happens

+    //

+    if (HubStatus.HubChange & HUB_CHANGE_LOCAL_POWER) {

+      HubClearHubFeature (UsbIo, C_HUB_LOCAL_POWER);

+    }

+    //

+    // Hub change overcurrent happens

+    //

+    if (HubStatus.HubChange & HUB_CHANGE_OVERCURRENT) {

+      HubClearHubFeature (UsbIo, C_HUB_OVER_CURRENT);

+    }

+  }

+

+  return EFI_SUCCESS;

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.h b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.h
new file mode 100644
index 0000000..4545d71
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/hub.h
@@ -0,0 +1,138 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    Hub.h

+    

+  Abstract:

+

+    Constants definitions for Usb Hub

+

+  Revision History

+

+--*/

+

+#ifndef _HUB_H

+#define _HUB_H

+

+//

+// Hub feature numbers

+//

+#define C_HUB_LOCAL_POWER   0

+#define C_HUB_OVER_CURRENT  1

+

+//

+// Hub class code & sub class code

+//

+#define CLASS_CODE_HUB      0x09

+#define SUB_CLASS_CODE_HUB  0

+

+//

+// Hub Status & Hub Change bit masks

+//

+#define HUB_STATUS_LOCAL_POWER  0x0001

+#define HUB_STATUS_OVERCURRENT  0x0002

+

+#define HUB_CHANGE_LOCAL_POWER  0x0001

+#define HUB_CHANGE_OVERCURRENT  0x0002

+

+//

+// Hub Characteristics

+//

+#define HUB_CHAR_LPSM     0x0003

+#define HUB_CHAR_COMPOUND 0x0004

+#define HUB_CHAR_OCPM     0x0018

+

+//

+// Hub specific request

+//

+#define HUB_CLEAR_FEATURE               0x01

+#define HUB_CLEAR_FEATURE_REQ_TYPE      0x20

+

+#define HUB_CLEAR_FEATURE_PORT          0x01

+#define HUB_CLEAR_FEATURE_PORT_REQ_TYPE 0x23

+

+#define HUB_GET_BUS_STATE               0x02

+#define HUB_GET_BUS_STATE_REQ_TYPE      0xA3

+

+#define HUB_GET_DESCRIPTOR              0x06

+#define HUB_GET_DESCRIPTOR_REQ_TYPE     0xA0

+

+#define HUB_GET_HUB_STATUS              0x00

+#define HUB_GET_HUB_STATUS_REQ_TYPE     0xA0

+

+#define HUB_GET_PORT_STATUS             0x00

+#define HUB_GET_PORT_STATUS_REQ_TYPE    0xA3

+

+#define HUB_SET_DESCRIPTOR              0x07

+#define HUB_SET_DESCRIPTOR_REQ_TYPE     0x20

+

+#define HUB_SET_HUB_FEATURE             0x03

+#define HUB_SET_HUB_FEATURE_REQ_TYPE    0x20

+

+#define HUB_SET_PORT_FEATURE            0x03

+#define HUB_SET_PORT_FEATURE_REQ_TYPE   0x23

+

+#pragma pack(1)

+typedef struct usb_hub_status {

+  UINT16  HubStatus;

+  UINT16  HubChange;

+} EFI_USB_HUB_STATUS;

+#pragma pack()

+

+EFI_STATUS

+HubGetPortStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Port,

+  OUT UINT32                  *PortStatus

+  );

+

+EFI_STATUS

+HubSetPortFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Port,

+  IN UINT8                   Value

+  );

+

+EFI_STATUS

+HubSetHubFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Value

+  );

+

+EFI_STATUS

+HubGetHubStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  OUT UINT32                  *HubStatus

+  );

+

+EFI_STATUS

+HubClearPortFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Port,

+  IN UINT8                   Value

+  );

+

+EFI_STATUS

+HubClearHubFeature (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Value

+  );

+

+EFI_STATUS

+GetHubDescriptor (

+  IN  EFI_USB_IO_PROTOCOL        *UsbIo,

+  IN  UINTN                      DescriptorSize,

+  OUT EFI_USB_HUB_DESCRIPTOR     *HubDescriptor

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usb.c b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usb.c
new file mode 100644
index 0000000..474e388
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usb.c
@@ -0,0 +1,825 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    Usb.c

+

+  Abstract:

+

+    Parse usb device configurations.

+

+  Revision History

+

+--*/

+

+#include "usbbus.h"

+

+//

+// Here are some internal helper functions

+//

+STATIC

+EFI_STATUS

+GetExpectedDescriptor (

+  IN  UINT8     *Buffer,

+  IN  UINTN     Length,

+  IN  UINT8     DescType,

+  IN  UINT8     DescLength,

+  OUT UINTN     *ParsedBytes

+  );

+

+STATIC

+EFI_STATUS

+ParseThisEndpoint (

+  IN  ENDPOINT_DESC_LIST_ENTRY     *EndpointEntry,

+  IN  UINT8                        *Buffer,

+  IN  UINTN                        BufferLength,

+  OUT UINTN                        *ParsedBytes

+  );

+

+STATIC

+EFI_STATUS

+ParseThisInterface (

+  IN  INTERFACE_DESC_LIST_ENTRY      *InterfaceEntry,

+  IN  UINT8                          *Buffer,

+  IN  UINTN                          *BufferLen,

+  OUT UINTN                          *ParsedBytes

+  );

+

+STATIC

+EFI_STATUS

+ParseThisConfig (

+  IN CONFIG_DESC_LIST_ENTRY     *ConfigDescEntry,

+  IN UINT8                      *Buffer,

+  IN UINTN                      Length

+  );

+

+//

+// Implementations

+//

+BOOLEAN

+IsHub (

+  IN USB_IO_CONTROLLER_DEVICE     *Dev

+  )

+/*++

+  

+  Routine Description:

+    Tell if a usb controller is a hub controller.

+    

+  Arguments:

+    Dev - UsbIoController device structure.

+    

+  Returns:

+    TRUE/FALSE

+--*/

+{

+  EFI_USB_INTERFACE_DESCRIPTOR  Interface;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;

+  UINT8                         Index;

+

+  if (Dev == NULL) {

+    return FALSE;

+  }

+

+  UsbIo = &Dev->UsbIo;

+

+  UsbIo->UsbGetInterfaceDescriptor (

+          UsbIo,

+          &Interface

+          );

+

+  //

+  // Check classcode

+  //

+  if (Interface.InterfaceClass != 0x09) {

+    return FALSE;

+  }

+  

+  //

+  // Check protocol

+  //

+  if (Interface.InterfaceProtocol != 0x0) {

+    return FALSE;

+  }

+

+  for (Index = 0; Index < Interface.NumEndpoints; Index++) {

+    UsbIo->UsbGetEndpointDescriptor (

+            UsbIo,

+            Index,

+            &EndpointDescriptor

+            );

+

+    if ((EndpointDescriptor.EndpointAddress & 0x80) == 0) {

+      continue;

+    }

+

+    if (EndpointDescriptor.Attributes != 0x03) {

+      continue;

+    }

+

+    Dev->HubEndpointAddress = EndpointDescriptor.EndpointAddress;

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+UsbGetStringtable (

+  IN USB_IO_DEVICE     *Dev

+  )

+/*++

+  

+  Routine Description:

+    Get the string table stored in a usb device.

+    

+  Arguments:

+    Dev     -     UsbIoController device structure.

+    

+  Returns:

+    EFI_SUCCESS

+    EFI_UNSUPPORTED

+    EFI_OUT_OF_RESOURCES

+    

+--*/

+{

+  EFI_STATUS                  Result;

+  UINT32                      Status;

+  EFI_USB_SUPPORTED_LANGUAGES *LanguageTable;

+  UINT8                       *Buffer;

+  UINT8                       *ptr;

+  UINTN                       Index;

+  UINTN                       LangTableSize;

+  EFI_USB_IO_PROTOCOL         *UsbIo;

+  UINT16                      TempBuffer;

+

+  UsbIo = &(Dev->UsbController[0]->UsbIo);

+

+  //

+  // We get first 2 byte of langID table,

+  // so we can have the whole table length

+  //

+  Result = UsbGetString (

+            UsbIo,

+            0,

+            0,

+            &TempBuffer,

+            2,

+            &Status

+            );

+  if (EFI_ERROR (Result)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  LanguageTable = (EFI_USB_SUPPORTED_LANGUAGES *) &TempBuffer;

+

+  if (LanguageTable->Length == 0) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // If length is 2, then there is no string table

+  //

+  if (LanguageTable->Length == 2) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Buffer = AllocateZeroPool (LanguageTable->Length);

+  if (Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Now we get the whole LangID table

+  //

+  Result = UsbGetString (

+            UsbIo,

+            0,

+            0,

+            Buffer,

+            LanguageTable->Length,

+            &Status

+            );

+  if (EFI_ERROR (Result)) {

+    gBS->FreePool (Buffer);

+    return EFI_UNSUPPORTED;

+  }

+

+  LanguageTable = (EFI_USB_SUPPORTED_LANGUAGES *) Buffer;

+

+  //

+  // ptr point to the LangID table

+  //

+  ptr           = Buffer + 2;

+  LangTableSize = (LanguageTable->Length - 2) / 2;

+

+  for (Index = 0; Index < LangTableSize && Index < USB_MAXLANID; Index++) {

+    Dev->LangID[Index] = *((UINT16 *) ptr);

+    ptr += 2;

+  }

+

+  gBS->FreePool (Buffer);

+  LanguageTable = NULL;

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+UsbGetAllConfigurations (

+  IN USB_IO_DEVICE     *UsbIoDevice

+  )

+/*++

+

+  Routine Description:

+    This function is to parse all the configuration descriptor.

+    

+  Arguments:

+    UsbIoDevice  -  USB_IO_DEVICE device structure.

+    

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_OUT_OF_RESOURCES  

+

+--*/

+{

+  EFI_STATUS              Result;

+  UINT32                  Status;

+  UINTN                   Index;

+  UINTN                   TotalLength;

+  UINT8                   *Buffer;

+  CONFIG_DESC_LIST_ENTRY  *ConfigDescEntry;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+

+  InitializeListHead (&UsbIoDevice->ConfigDescListHead);

+  UsbIo = &(UsbIoDevice->UsbController[0]->UsbIo);

+

+  for (Index = 0; Index < UsbIoDevice->DeviceDescriptor.NumConfigurations; Index++) {

+    ConfigDescEntry = NULL;

+

+    ConfigDescEntry = AllocateZeroPool (sizeof (CONFIG_DESC_LIST_ENTRY));

+    if (ConfigDescEntry == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+    //

+    // 1st only get 1st 4 bytes config descriptor,

+    // so we can know the whole length

+    //

+    Result = UsbGetDescriptor (

+              UsbIo,

+              (UINT16) ((USB_DT_CONFIG << 8) | Index),

+              0,

+              4,

+              &ConfigDescEntry->CongfigDescriptor,

+              &Status

+              );

+    if (EFI_ERROR (Result)) {

+      DEBUG ((gUSBErrorLevel, "First get config descriptor error\n"));

+      gBS->FreePool (ConfigDescEntry);

+      return EFI_DEVICE_ERROR;

+    }

+

+    TotalLength = ConfigDescEntry->CongfigDescriptor.TotalLength;

+

+    Buffer      = AllocateZeroPool (TotalLength);

+    if (Buffer == NULL) {

+      gBS->FreePool (ConfigDescEntry);

+      return EFI_OUT_OF_RESOURCES;

+    }

+    //

+    // Then we get the total descriptors for this configuration

+    //

+    Result = UsbGetDescriptor (

+              UsbIo,

+              (UINT16) ((USB_DT_CONFIG << 8) | Index),

+              0,

+              (UINT16) TotalLength,

+              Buffer,

+              &Status

+              );

+    if (EFI_ERROR (Result)) {

+      DEBUG ((gUSBErrorLevel, "Get whole config descriptor error\n"));

+      gBS->FreePool (ConfigDescEntry);

+      gBS->FreePool (Buffer);

+      return EFI_DEVICE_ERROR;

+    }

+

+    InitializeListHead (&ConfigDescEntry->InterfaceDescListHead);

+

+    //

+    // Parse this whole configuration

+    //

+    Result = ParseThisConfig (ConfigDescEntry, Buffer, TotalLength);

+

+    if (EFI_ERROR (Result)) {

+      //

+      // Ignore this configuration, parse next one

+      //

+      gBS->FreePool (ConfigDescEntry);

+      gBS->FreePool (Buffer);

+      continue;

+    }

+

+    InsertTailList (&UsbIoDevice->ConfigDescListHead, &ConfigDescEntry->Link);

+

+    gBS->FreePool (Buffer);

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+GetExpectedDescriptor (

+  IN  UINT8     *Buffer,

+  IN  UINTN     Length,

+  IN  UINT8     DescType,

+  IN  UINT8     DescLength,

+  OUT UINTN     *ParsedBytes

+  )

+/*++

+  

+  Routine Description:

+    Get the start position of next wanted descriptor.

+    

+  Arguments:

+    Buffer      - Buffer to parse

+    Length      - Buffer length 

+    DescType    - Descriptor type 

+    DescLength  - Descriptor length

+    ParsedBytes - Parsed Bytes to return

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  UINT16  DescriptorHeader;

+  UINT8   Len;

+  UINT8   *ptr;

+  UINTN   Parsed;

+

+  Parsed  = 0;

+  ptr     = Buffer;

+

+  while (TRUE) {

+    //

+    // Buffer length should not less than Desc length

+    //

+    if (Length < DescLength) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // DescriptorHeader = *((UINT16 *)ptr), compatible with IPF

+    //

+    DescriptorHeader  = (UINT16) ((*(ptr + 1) << 8) | *ptr);

+

+    Len               = ptr[0];

+

+    //

+    // Check to see if it is a start of expected descriptor

+    //

+    if (DescriptorHeader == ((DescType << 8) | DescLength)) {

+      break;

+    }

+

+    if ((UINT8) (DescriptorHeader >> 8) == DescType) {

+      if (Len > DescLength) {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+    //

+    // Descriptor length should be at least 2

+    // and should not exceed the buffer length

+    //

+    if (Len < 2) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (Len > Length) {

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // Skip this mismatch descriptor

+    //

+    Length -= Len;

+    ptr += Len;

+    Parsed += Len;

+  }

+

+  *ParsedBytes = Parsed;

+

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+EFI_STATUS

+ParseThisEndpoint (

+  IN  ENDPOINT_DESC_LIST_ENTRY     *EndpointEntry,

+  IN  UINT8                        *Buffer,

+  IN  UINTN                        BufferLength,

+  OUT UINTN                        *ParsedBytes

+  )

+/*++

+

+  Routine Description:

+    Get the start position of next wanted endpoint descriptor.

+

+  Arguments:

+    EndpointEntry - ENDPOINT_DESC_LIST_ENTRY

+    Buffer        - Buffer to parse 

+    BufferLength  - Buffer Length

+    ParsedBytes   - Parsed Bytes to return

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  UINT8       *ptr;

+  EFI_STATUS  Status;

+  UINTN       SkipBytes;

+

+  //

+  // Skip some data for this interface

+  //

+  Status = GetExpectedDescriptor (

+            Buffer,

+            BufferLength,

+            USB_DT_ENDPOINT,

+            sizeof (EFI_USB_ENDPOINT_DESCRIPTOR),

+            &SkipBytes

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ptr           = Buffer + SkipBytes;

+  *ParsedBytes  = SkipBytes;

+

+  CopyMem (

+    &EndpointEntry->EndpointDescriptor,

+    ptr,

+    sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)

+    );

+

+  *ParsedBytes += sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ParseThisInterface (

+  IN  INTERFACE_DESC_LIST_ENTRY     *InterfaceEntry,

+  IN  UINT8                         *Buffer,

+  IN  UINTN                         *BufferLen,

+  OUT UINTN                         *ParsedBytes

+  )

+/*++

+

+  Routine Description:

+    Get the start position of next wanted interface descriptor.

+

+  Arguments:

+    InterfaceEntry - INTERFACE_DESC_LIST_ENTRY

+    Buffer         - Buffer to parse 

+    BufferLength   - Buffer Length

+    ParsedBytes    - Parsed Bytes to return

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  UINT8                     *ptr;

+  UINTN                     SkipBytes;

+  UINTN                     Index;

+  UINTN                     Length;

+  UINTN                     Parsed;

+  ENDPOINT_DESC_LIST_ENTRY  *EndpointEntry;

+  EFI_STATUS                Status;

+

+  Parsed = 0;

+

+  //

+  // Skip some data for this interface

+  //

+  Status = GetExpectedDescriptor (

+            Buffer,

+            *BufferLen,

+            USB_DT_INTERFACE,

+            sizeof (EFI_USB_INTERFACE_DESCRIPTOR),

+            &SkipBytes

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ptr           = Buffer + SkipBytes;

+  *ParsedBytes  = SkipBytes;

+

+  //

+  // Copy the interface descriptor

+  //

+  CopyMem (

+    &InterfaceEntry->InterfaceDescriptor,

+    ptr,

+    sizeof (EFI_USB_INTERFACE_DESCRIPTOR)

+    );

+

+  ptr = Buffer + sizeof (EFI_USB_INTERFACE_DESCRIPTOR);

+  *ParsedBytes += sizeof (EFI_USB_INTERFACE_DESCRIPTOR);

+

+  InitializeListHead (&InterfaceEntry->EndpointDescListHead);

+

+  Length = *BufferLen - SkipBytes - sizeof (EFI_USB_INTERFACE_DESCRIPTOR);

+

+  for (Index = 0; Index < InterfaceEntry->InterfaceDescriptor.NumEndpoints; Index++) {

+    EndpointEntry = AllocateZeroPool (sizeof (ENDPOINT_DESC_LIST_ENTRY));

+    if (EndpointEntry == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+    

+    //

+    // Parses all the endpoint descriptors within this interface.

+    //

+    Status = ParseThisEndpoint (EndpointEntry, ptr, Length, &Parsed);

+

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (EndpointEntry);

+      return Status;

+    }

+

+    InsertTailList (

+      &InterfaceEntry->EndpointDescListHead,

+      &EndpointEntry->Link

+      );

+

+    Length -= Parsed;

+    ptr += Parsed;

+    *ParsedBytes += Parsed;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ParseThisConfig (

+  IN CONFIG_DESC_LIST_ENTRY     *ConfigDescEntry,

+  IN UINT8                      *Buffer,

+  IN UINTN                      Length

+  )

+/*++

+

+  Routine Description:

+    Parse the current configuration descriptior.

+

+  Arguments:

+    ConfigDescEntry - CONFIG_DESC_LIST_ENTRY

+    Buffer          - Buffer to parse 

+    Length          - Buffer Length

+

+  Returns

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  UINT8                     *ptr;

+  UINT8                     NumInterface;

+  UINTN                     Index;

+  INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;

+  UINTN                     SkipBytes;

+  UINTN                     Parsed;

+  EFI_STATUS                Status;

+  UINTN                     LengthLeft;

+

+  Parsed = 0;

+

+  //

+  //  First skip the current config descriptor;

+  //

+  Status = GetExpectedDescriptor (

+            Buffer,

+            Length,

+            USB_DT_CONFIG,

+            sizeof (EFI_USB_CONFIG_DESCRIPTOR),

+            &SkipBytes

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ptr = Buffer + SkipBytes;

+

+  CopyMem (

+    &ConfigDescEntry->CongfigDescriptor,

+    ptr,

+    sizeof (EFI_USB_CONFIG_DESCRIPTOR)

+    );

+

+  NumInterface = ConfigDescEntry->CongfigDescriptor.NumInterfaces;

+

+  //

+  // Skip size of Configuration Descriptor

+  //

+  ptr += sizeof (EFI_USB_CONFIG_DESCRIPTOR);

+

+  LengthLeft = Length - SkipBytes - sizeof (EFI_USB_CONFIG_DESCRIPTOR);

+

+  for (Index = 0; Index < NumInterface; Index++) {

+    //

+    // Parse all Interface

+    //

+    InterfaceEntry = AllocateZeroPool (sizeof (INTERFACE_DESC_LIST_ENTRY));

+    if (InterfaceEntry == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Status = ParseThisInterface (InterfaceEntry, ptr, &LengthLeft, &Parsed);

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (InterfaceEntry);

+      return Status;

+    }

+

+    InsertTailList (

+      &ConfigDescEntry->InterfaceDescListHead,

+      &InterfaceEntry->Link

+      );

+

+    //

+    // Parsed for next interface

+    //

+    LengthLeft -= Parsed;

+    ptr += Parsed;

+  }

+  //

+  // Parse for additional alt setting;

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UsbSetConfiguration (

+  IN USB_IO_DEVICE     *UsbIoDev,

+  IN UINTN             ConfigurationValue

+  )

+/*++

+

+  Routine Description:

+    Set the device to a configuration value.

+    

+  Arguments:

+    UsbIoDev            -   USB_IO_DEVICE to be set configuration

+    ConfigrationValue   -   The configuration value to be set to that device

+    

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    

+--*/

+{

+  LIST_ENTRY          *NextEntry;

+  CONFIG_DESC_LIST_ENTRY  *ConfigEntry;

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+

+  UsbIo     = &(UsbIoDev->UsbController[0]->UsbIo);

+  NextEntry = UsbIoDev->ConfigDescListHead.ForwardLink;

+

+  while (NextEntry != &UsbIoDev->ConfigDescListHead) {

+    //

+    // Get one entry

+    //

+    ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;

+    if (ConfigEntry->CongfigDescriptor.ConfigurationValue == ConfigurationValue) {

+      //

+      // Find one, set to the active configuration

+      //

+      UsbIoDev->ActiveConfig = ConfigEntry;

+      break;

+    }

+

+    NextEntry = NextEntry->ForwardLink;

+  }

+  //

+  // Next Entry should not be null

+  //

+  Result = UsbSetDeviceConfiguration (

+            UsbIo,

+            (UINT16) ConfigurationValue,

+            &Status

+            );

+

+  return Result;

+}

+

+EFI_STATUS

+UsbSetDefaultConfiguration (

+  IN  USB_IO_DEVICE      *UsbIoDev

+  )

+/*++

+

+  Routine Description:

+    Set the device to a default configuration value.

+    

+  Arguments:

+    UsbIoDev       -    USB_IO_DEVICE to be set configuration

+    

+  Returns

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    

+--*/

+{

+  CONFIG_DESC_LIST_ENTRY  *ConfigEntry;

+  UINT16                  ConfigValue;

+  LIST_ENTRY          *NextEntry;

+

+  if (IsListEmpty (&UsbIoDev->ConfigDescListHead)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  NextEntry   = UsbIoDev->ConfigDescListHead.ForwardLink;

+

+  ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;

+  ConfigValue = ConfigEntry->CongfigDescriptor.ConfigurationValue;

+

+  return UsbSetConfiguration (UsbIoDev, ConfigValue);

+}

+

+VOID

+UsbDestroyAllConfiguration (

+  IN  USB_IO_DEVICE      *UsbIoDevice

+  )

+/*++

+

+  Routine Description:

+    Delete all configuration data when device is not used.

+    

+  Arguments:

+    UsbIoDevice  - USB_IO_DEVICE to be set configuration

+  

+  Returns:

+    N/A

+    

+--*/

+{

+  CONFIG_DESC_LIST_ENTRY    *ConfigEntry;

+  INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;

+  ENDPOINT_DESC_LIST_ENTRY  *EndpointEntry;

+  LIST_ENTRY                *NextEntry;

+

+  //

+  // Delete all configuration descriptor data

+  //

+  ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) UsbIoDevice->ConfigDescListHead.ForwardLink;

+

+  while (ConfigEntry != (CONFIG_DESC_LIST_ENTRY *) &UsbIoDevice->ConfigDescListHead) {

+    //

+    // Delete all its interface descriptors

+    //

+    InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *) ConfigEntry->InterfaceDescListHead.ForwardLink;

+

+    while (InterfaceEntry != (INTERFACE_DESC_LIST_ENTRY *) &ConfigEntry->InterfaceDescListHead) {

+      //

+      // Delete all its endpoint descriptors

+      //

+      EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *) InterfaceEntry->EndpointDescListHead.ForwardLink;

+      while (EndpointEntry != (ENDPOINT_DESC_LIST_ENTRY *) &InterfaceEntry->EndpointDescListHead) {

+        NextEntry = ((LIST_ENTRY *) EndpointEntry)->ForwardLink;

+        RemoveEntryList ((LIST_ENTRY *) EndpointEntry);

+        gBS->FreePool (EndpointEntry);

+        EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *) NextEntry;

+      }

+

+      NextEntry = ((LIST_ENTRY *) InterfaceEntry)->ForwardLink;

+      RemoveEntryList ((LIST_ENTRY *) InterfaceEntry);

+      gBS->FreePool (InterfaceEntry);

+      InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *) NextEntry;

+    }

+

+    NextEntry = ((LIST_ENTRY *) ConfigEntry)->ForwardLink;

+    RemoveEntryList ((LIST_ENTRY *) ConfigEntry);

+    gBS->FreePool (ConfigEntry);

+    ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;

+  }

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
new file mode 100644
index 0000000..f4ac69e
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
@@ -0,0 +1,2305 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    UsbBus.c

+

+  Abstract:

+

+    USB Bus Driver

+

+  Revision History

+

+--*/

+

+#include "usbbus.h"

+

+//#ifdef EFI_DEBUG

+UINTN                       gUSBDebugLevel  = EFI_D_ERROR;

+UINTN                       gUSBErrorLevel  = EFI_D_ERROR;

+//#endif

+//

+// The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER

+// structure in the UsbBusDriverControllerDriverStop(). Then we can

+// Close all opened protocols and release this structure.

+//

+STATIC EFI_GUID             mUsbBusProtocolGuid = EFI_USB_BUS_PROTOCOL_GUID;

+

+

+

+//

+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface

+//

+EFI_STATUS

+EFIAPI

+UsbBusControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+UsbBusControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+UsbBusControllerDriverStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN UINTN                           NumberOfChildren,

+  IN EFI_HANDLE                      *ChildHandleBuffer

+  );

+

+EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding = {

+  UsbBusControllerDriverSupported,

+  UsbBusControllerDriverStart,

+  UsbBusControllerDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+//

+// Internal use only

+//

+STATIC

+EFI_STATUS

+ReportUsbStatusCode (

+  IN USB_BUS_CONTROLLER_DEVICE     *UsbBusController,

+  IN EFI_STATUS_CODE_TYPE          Type,

+  IN EFI_STATUS_CODE_VALUE         Code

+  );

+

+//

+// Supported function

+//

+VOID

+InitializeUsbIoInstance (

+  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController

+  );

+

+STATIC

+USB_IO_CONTROLLER_DEVICE    *

+CreateUsbIoControllerDevice (

+  VOID

+  );

+

+STATIC

+EFI_STATUS

+InitUsbIoController (

+  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController

+  );

+

+//

+// USB Device Configuration / Deconfiguration

+//

+STATIC

+EFI_STATUS

+UsbDeviceConfiguration (

+  IN USB_IO_CONTROLLER_DEVICE     *ParentHubController,

+  IN EFI_HANDLE                   HostController,

+  IN UINT8                        ParentPort,

+  IN USB_IO_DEVICE                *UsbIoDevice

+  );

+

+//

+// Usb Bus enumeration function

+//

+STATIC

+VOID

+EFIAPI

+UsbEnumeration (

+  IN EFI_EVENT     Event,

+  IN VOID          *Context

+  );

+

+EFI_STATUS

+ResetRootPort (

+  IN EFI_USB_HC_PROTOCOL     *UsbHCInterface,

+  IN UINT8                   PortNum,

+  IN UINT8                   RetryTimes

+  );

+

+EFI_STATUS

+ResetHubPort (

+  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,

+  IN UINT8                       PortIndex

+  );

+

+EFI_STATUS

+ClearRootPortConnectionChangeStatus (

+  IN UINT8                   PortNum,

+  IN EFI_USB_HC_PROTOCOL     *UsbHCInterface

+  );

+

+STATIC

+EFI_STATUS

+ParentPortReset (

+  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,

+  IN BOOLEAN                     ReConfigure,

+  IN UINT8                       RetryTimes

+  );

+

+//

+// Following are address allocate and free functions

+//

+STATIC

+UINT8

+UsbAllocateAddress (

+  IN UINT8    *AddressPool

+  )

+{

+  UINT8 ByteIndex;

+  UINT8 BitIndex;

+

+  for (ByteIndex = 0; ByteIndex < 16; ByteIndex++) {

+    for (BitIndex = 0; BitIndex < 8; BitIndex++) {

+      if ((AddressPool[ByteIndex] & (1 << BitIndex)) == 0) {

+        //

+        // Found one, covert to address, and mark it use

+        //

+        AddressPool[ByteIndex] |= (1 << BitIndex);

+        return (UINT8) (ByteIndex * 8 + BitIndex);

+      }

+    }

+  }

+

+  return 0;

+

+}

+

+STATIC

+VOID

+UsbFreeAddress (

+  IN UINT8     DevAddress,

+  IN UINT8     *AddressPool

+  )

+{

+  UINT8 WhichByte;

+  UINT8 WhichBit;

+  //

+  // Locate the position

+  //

+  WhichByte = (UINT8) (DevAddress / 8);

+  WhichBit  = (UINT8) (DevAddress & 0x7);

+

+  AddressPool[WhichByte] &= (~(1 << WhichBit));

+}

+

+EFI_STATUS

+EFIAPI

+UsbBusControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    that has UsbHcProtocol installed will be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller         - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS  OpenStatus;

+

+  //

+  // Check whether USB Host Controller Protocol is already

+  // installed on this handle. If it is installed, we can start

+  // USB Bus Driver now.

+  //

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiUsbHcProtocolGuid,

+                      NULL,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                      );

+

+  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return OpenStatus;

+}

+

+

+EFI_STATUS

+EFIAPI

+UsbBusControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+

+    Starting the Usb Bus Driver

+

+  Arguments:

+

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+    EFI_DEVICE_ERROR    - This driver cannot be started due to device

+                          Error

+    EFI_OUT_OF_RESOURCES- Can't allocate memory resources

+    EFI_ALREADY_STARTED - This driver has been started

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_STATUS                OpenStatus;

+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev;

+  USB_IO_DEVICE             *RootHub;

+  USB_IO_CONTROLLER_DEVICE  *RootHubController;

+  EFI_USB_HC_PROTOCOL       *UsbHCInterface;

+

+  //

+  // Allocate USB_BUS_CONTROLLER_DEVICE structure

+  //

+  UsbBusDev = NULL;

+  UsbBusDev = AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE));

+  if (UsbBusDev == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  UsbBusDev->Signature      = USB_BUS_DEVICE_SIGNATURE;

+  UsbBusDev->AddressPool[0] = 1;

+

+  //

+  // Get the Device Path Protocol on Controller's handle

+  //

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiDevicePathProtocolGuid,

+                      (VOID **) &UsbBusDev->DevicePath,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+

+  if (EFI_ERROR (OpenStatus)) {

+    gBS->FreePool (UsbBusDev);

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Locate the Host Controller Interface

+  //

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiUsbHcProtocolGuid,

+                      (VOID **) &UsbHCInterface,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+

+  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {

+    

+    //

+    // Report Status Code here since we will reset the host controller

+    //

+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,

+      UsbBusDev->DevicePath

+      );

+

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->FreePool (UsbBusDev);

+    return EFI_UNSUPPORTED;

+  }

+

+  if (OpenStatus == EFI_ALREADY_STARTED) {

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->FreePool (UsbBusDev);

+    return EFI_ALREADY_STARTED;

+  }

+

+  UsbBusDev->UsbHCInterface = UsbHCInterface;

+

+  //

+  // Attach EFI_USB_BUS_PROTOCOL to controller handle,

+  // for locate UsbBusDev later

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &Controller,

+                  &mUsbBusProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &UsbBusDev->BusIdentify

+                  );

+

+  if (EFI_ERROR (Status)) {

+

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiUsbHcProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->FreePool (UsbBusDev);

+    return Status;

+  }

+  //

+  // Add root hub to the tree

+  //

+  RootHub = NULL;

+  RootHub = AllocateZeroPool (sizeof (USB_IO_DEVICE));

+  if (RootHub == NULL) {

+    gBS->UninstallProtocolInterface (

+           Controller,

+           &mUsbBusProtocolGuid,

+           &UsbBusDev->BusIdentify

+           );

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiUsbHcProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->FreePool (UsbBusDev);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  RootHub->BusController  = UsbBusDev;

+  RootHub->DeviceAddress  = UsbAllocateAddress (UsbBusDev->AddressPool);

+

+  UsbBusDev->Root         = RootHub;

+

+  //

+  // Allocate Root Hub Controller

+  //

+  RootHubController = CreateUsbIoControllerDevice ();

+  if (RootHubController == NULL) {

+    gBS->UninstallProtocolInterface (

+           Controller,

+           &mUsbBusProtocolGuid,

+           &UsbBusDev->BusIdentify

+           );

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiUsbHcProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+    gBS->FreePool (UsbBusDev);

+    gBS->FreePool (RootHub);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  UsbHCInterface->GetRootHubPortNumber (

+                    UsbHCInterface,

+                    &RootHubController->DownstreamPorts

+                    );

+  RootHubController->UsbDevice      = RootHub;

+  RootHubController->IsUsbHub       = TRUE;

+  RootHubController->DevicePath     = UsbBusDev->DevicePath;

+  RootHubController->HostController = Controller;

+

+  RootHub->NumOfControllers         = 1;

+  RootHub->UsbController[0]         = RootHubController;

+

+  //

+  // Report Status Code here since we will reset the host controller

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    EFI_IO_BUS_USB | EFI_IOB_PC_RESET,

+    UsbBusDev->DevicePath

+    );

+

+  //

+  // Reset USB Host Controller

+  //

+  UsbHCInterface->Reset (

+                    UsbHCInterface,

+                    EFI_USB_HC_RESET_GLOBAL

+                    );

+

+  //

+  // Report Status Code while we are going to bring up the Host Controller

+  // and start bus enumeration

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE,

+    UsbBusDev->DevicePath

+    );

+

+  //

+  // Start USB Host Controller

+  //

+  UsbHCInterface->SetState (

+                    UsbHCInterface,

+                    EfiUsbHcStateOperational

+                    );

+

+  //

+  // Create a timer to query root ports periodically

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  UsbEnumeration,

+                  RootHubController,

+                  &RootHubController->HubNotify

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->UninstallProtocolInterface (

+           Controller,

+           &mUsbBusProtocolGuid,

+           &UsbBusDev->BusIdentify

+           );

+

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiUsbHcProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+

+    gBS->FreePool (RootHubController);

+    gBS->FreePool (RootHub);

+    gBS->FreePool (UsbBusDev);

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Before depending on the timer to check root ports periodically,

+  // here we should check them immediately for the first time, or

+  // there will be an interval between bus start and devices start.

+  //

+  gBS->SignalEvent (RootHubController->HubNotify);

+  

+  Status = gBS->SetTimer (

+                  RootHubController->HubNotify,

+                  TimerPeriodic,

+                  BUSPOLLING_PERIOD

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->UninstallProtocolInterface (

+           Controller,

+           &mUsbBusProtocolGuid,

+           &UsbBusDev->BusIdentify

+           );

+

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiDevicePathProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+

+    gBS->CloseProtocol (

+           Controller,

+           &gEfiUsbHcProtocolGuid,

+           This->DriverBindingHandle,

+           Controller

+           );

+

+    gBS->CloseEvent (RootHubController->HubNotify);

+    gBS->FreePool (RootHubController);

+    gBS->FreePool (RootHub);

+    gBS->FreePool (UsbBusDev);

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// Stop the bus controller

+//

+EFI_STATUS

+EFIAPI

+UsbBusControllerDriverStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN EFI_HANDLE                      Controller,

+  IN UINTN                           NumberOfChildren,

+  IN EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    Controller        - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    others

+

+--*/

+{

+  EFI_STATUS                Status;

+  USB_IO_DEVICE             *Root;

+  USB_IO_CONTROLLER_DEVICE  *RootHubController;

+  USB_BUS_CONTROLLER_DEVICE *UsbBusController;

+  EFI_USB_BUS_PROTOCOL      *UsbIdentifier;

+  UINT8                     Index2;

+  EFI_USB_HC_PROTOCOL       *UsbHCInterface;

+  USB_IO_CONTROLLER_DEVICE  *UsbController;

+  USB_IO_DEVICE             *UsbIoDevice;

+  USB_IO_CONTROLLER_DEVICE  *HubController;

+  UINTN                     Index;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+

+  if (NumberOfChildren > 0) {

+

+    for (Index = 0; Index < NumberOfChildren; Index++) {

+      Status = gBS->OpenProtocol (

+                      ChildHandleBuffer[Index],

+                      &gEfiUsbIoProtocolGuid,

+                      (VOID **) &UsbIo,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                      );

+      if (EFI_ERROR (Status)) {

+        //

+        // We are here since the handle passed in does not support

+        // UsbIo protocol. There are several reasons that will cause

+        // this.

+        // For combo device such as keyboard, it may have 2 devices

+        // in one, namely, keyboard and mouse. If we deconfigure one

+        // of them, the other will be freed at the same time. This will

+        // cause the status error. But this is the correct behavior.

+        // For hub device, if we deconfigure hub first, the other chile

+        // device will be disconnected also, this will also provide us

+        // a status error. Now we will only report EFI_SUCCESS since Uhc

+        // driver will be disconnected at the second time.(pls see

+        // CoreDisconnectController for details)

+        //

+        continue;

+      }

+

+      UsbController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo);

+      UsbIoDevice   = UsbController->UsbDevice;

+      HubController = UsbController->Parent;

+      UsbDeviceDeConfiguration (UsbIoDevice);

+      for (Index2 = 0; Index2 < HubController->DownstreamPorts; Index2++) {

+        if (HubController->Children[Index2] == UsbIoDevice) {

+          HubController->Children[Index2] = NULL;

+        }

+      }

+    }

+

+    return EFI_SUCCESS;

+  }

+  //

+  // Get the USB_BUS_CONTROLLER_DEVICE

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &mUsbBusProtocolGuid,

+                  (VOID **) &UsbIdentifier,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbBusController = USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier);

+

+  //

+  // Stop USB Host Controller

+  //

+  UsbHCInterface = UsbBusController->UsbHCInterface;

+

+  //

+  // Report Status Code here since we will reset the host controller

+  //

+  ReportUsbStatusCode (

+    UsbBusController,

+    EFI_PROGRESS_CODE,

+    EFI_IO_BUS_USB | EFI_IOB_PC_RESET

+    );

+

+  UsbHCInterface->SetState (

+                    UsbHCInterface,

+                    EfiUsbHcStateHalt

+                    );

+

+  //

+  // Deconfiguration all its devices

+  //

+  Root              = UsbBusController->Root;

+  RootHubController = Root->UsbController[0];

+

+  gBS->CloseEvent (RootHubController->HubNotify);

+

+  for (Index2 = 0; Index2 < RootHubController->DownstreamPorts; Index2++) {

+    if (RootHubController->Children[Index2]) {

+      UsbDeviceDeConfiguration (RootHubController->Children[Index2]);

+      RootHubController->Children[Index2] = NULL;

+    }

+  }

+

+  gBS->FreePool (RootHubController);

+  gBS->FreePool (Root);

+

+  //

+  // Uninstall USB Bus Protocol

+  //

+  gBS->UninstallProtocolInterface (

+        Controller,

+        &mUsbBusProtocolGuid,

+        &UsbBusController->BusIdentify

+        );

+

+  //

+  // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL

+  // Opened by this Controller

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbHcProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->FreePool (UsbBusController);

+

+  return EFI_SUCCESS;

+}

+//

+// USB Device Configuration

+//

+STATIC

+EFI_STATUS

+UsbDeviceConfiguration (

+  IN USB_IO_CONTROLLER_DEVICE     *ParentHubController,

+  IN EFI_HANDLE                   HostController,

+  IN UINT8                        ParentPort,

+  IN USB_IO_DEVICE                *UsbIoDevice

+  )

+/*++

+

+  Routine Description:

+    Configurate a new device attached to the usb bus

+

+  Arguments:

+    ParentHubController   -   Parent Hub which this device is connected.

+    HostController        -   Host Controller handle

+    ParentPort            -   Parent Hub port which this device is connected.

+    UsbIoDevice           -   The device to be configured.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_OUT_OF_RESOURCES

+

+--*/

+{

+  UINT8                     DevAddress;

+  UINT8                     Index;

+  EFI_STATUS                Result;

+  UINT32                    Status;

+  CHAR16                    *StrManufacturer;

+  CHAR16                    *StrProduct;

+  CHAR16                    *StrSerialNumber;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+  UINT8                     NumOfInterface;

+  USB_IO_CONTROLLER_DEVICE  *FirstController;

+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev;

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+

+  UsbBusDev = UsbIoDevice->BusController;

+  //

+  // Since a USB device must have at least on interface,

+  // so create this instance first

+  //

+  FirstController                   = CreateUsbIoControllerDevice ();

+  FirstController->UsbDevice        = UsbIoDevice;

+  UsbIoDevice->UsbController[0]     = FirstController;

+  FirstController->InterfaceNumber  = 0;

+  FirstController->ParentPort       = ParentPort;

+  FirstController->Parent           = ParentHubController;

+  FirstController->HostController   = HostController;

+

+  InitializeUsbIoInstance (FirstController);

+

+  DEBUG ((gUSBDebugLevel, "Configuration Usb Device at 0x%x...\n", ParentPort));

+

+  //

+  // Ensure we used the correctly USB I/O instance

+  //

+  UsbIo = &FirstController->UsbIo;

+

+  //

+  // First retrieve the 1st 8 bytes of

+  // in order to get the MaxPacketSize for Endpoint 0

+  //

+  for (Index = 0; Index < 3; Index++) {

+

+    UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;

+

+    ParentPortReset (FirstController, FALSE, Index);

+

+    Result = UsbGetDescriptor (

+              UsbIo,

+              (USB_DT_DEVICE << 8),

+              0,

+              8,

+              &UsbIoDevice->DeviceDescriptor,

+              &Status

+              );

+    if (!EFI_ERROR (Result)) {

+      DEBUG ((gUSBDebugLevel,

+        "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",

+        UsbIoDevice->DeviceDescriptor.MaxPacketSize0)

+        );

+      break;

+    }

+

+  }

+

+  if (Index == 3) {

+    ReportUsbStatusCode (

+      UsbBusDev,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR

+      );

+    DEBUG ((gUSBErrorLevel, "Get Device Descriptor Fail when configing\n"));

+    gBS->FreePool (FirstController);

+    return EFI_DEVICE_ERROR;

+  }

+

+  DevAddress = UsbAllocateAddress (UsbIoDevice->BusController->AddressPool);

+  if (DevAddress == 0) {

+    DEBUG ((gUSBErrorLevel, "Cannot allocate address\n"));

+    gBS->FreePool (FirstController);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Result = UsbSetDeviceAddress (UsbIo, DevAddress, &Status);

+

+  if (EFI_ERROR (Result)) {

+    DEBUG ((gUSBErrorLevel, "Set address error\n"));

+    ReportUsbStatusCode (

+      UsbBusDev,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR

+      );

+

+    UsbFreeAddress (

+      DevAddress,

+      UsbIoDevice->BusController->AddressPool

+      );

+

+    gBS->FreePool (FirstController);

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbIoDevice->DeviceAddress = DevAddress;

+

+  //

+  // Get the whole device descriptor

+  //

+  Result = UsbGetDescriptor (

+            UsbIo,

+            (USB_DT_DEVICE << 8),

+            0,

+            sizeof (EFI_USB_DEVICE_DESCRIPTOR),

+            &UsbIoDevice->DeviceDescriptor,

+            &Status

+            );

+

+  if (EFI_ERROR (Result)) {

+    DEBUG ((gUSBErrorLevel, "Get whole Device Descriptor error\n"));

+    ReportUsbStatusCode (

+      UsbBusDev,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR

+      );

+    UsbFreeAddress (

+      DevAddress,

+      UsbIoDevice->BusController->AddressPool

+      );

+

+    gBS->FreePool (FirstController);

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Get & parse all configurations for this device, including

+  // all configuration descriptors, all interface descriptors, all

+  // endpoint descriptors

+  //

+  Result = UsbGetAllConfigurations (UsbIoDevice);

+

+  if (EFI_ERROR (Result)) {

+    DEBUG ((gUSBErrorLevel, "Failed to get device configuration\n"));

+    ReportUsbStatusCode (

+      UsbBusDev,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR

+      );

+    UsbFreeAddress (

+      DevAddress,

+      UsbIoDevice->BusController->AddressPool

+      );

+

+    gBS->FreePool (FirstController);

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set the 1st configuration value

+  //

+  Result = UsbSetDefaultConfiguration (UsbIoDevice);

+  if (EFI_ERROR (Result)) {

+    DEBUG ((gUSBErrorLevel, "Failed to set device configuration\n"));

+    ReportUsbStatusCode (

+      UsbBusDev,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR

+      );

+    UsbFreeAddress (

+      DevAddress,

+      UsbIoDevice->BusController->AddressPool

+      );

+

+    gBS->FreePool (FirstController);

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbIoDevice->IsConfigured = TRUE;

+

+  //

+  // Get all string table if applicable

+  //

+  Result = UsbGetStringtable (UsbIoDevice);

+  if (EFI_ERROR (Result)) {

+    DEBUG ((gUSBDebugLevel, "Device doesn't support string table\n"));

+  } else {

+

+    StrManufacturer = NULL;

+    UsbIo->UsbGetStringDescriptor (

+            UsbIo,

+            UsbIoDevice->LangID[0],

+            (UsbIoDevice->DeviceDescriptor).StrManufacturer,

+            &StrManufacturer

+            );

+

+    StrProduct = NULL;

+    UsbIo->UsbGetStringDescriptor (

+            UsbIo,

+            UsbIoDevice->LangID[0],

+            (UsbIoDevice->DeviceDescriptor).StrProduct,

+            &StrProduct

+            );

+

+    StrSerialNumber = NULL;

+    UsbIo->UsbGetStringDescriptor (

+            UsbIo,

+            UsbIoDevice->LangID[0],

+            (UsbIoDevice->DeviceDescriptor).StrSerialNumber,

+            &StrSerialNumber

+            );

+

+    if (StrManufacturer) {

+      gBS->FreePool (StrManufacturer);

+    }

+

+    if (StrProduct) {

+      gBS->FreePool (StrProduct);

+    }

+

+    if (StrSerialNumber) {

+      gBS->FreePool (StrSerialNumber);

+    }

+  }

+  //

+  // Create USB_IO_CONTROLLER_DEVICE for

+  // each detected interface

+  //

+  FirstController->CurrentConfigValue =

+  UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;

+

+  NumOfInterface                      =

+  UsbIoDevice->ActiveConfig->CongfigDescriptor.NumInterfaces;

+  UsbIoDevice->NumOfControllers       = NumOfInterface;

+

+  Result = InitUsbIoController (FirstController);

+  if (EFI_ERROR (Result)) {

+    ReportUsbStatusCode (

+      UsbBusDev,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR

+      );

+    gBS->FreePool (FirstController);

+    UsbIoDevice->UsbController[0] = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+

+  for (Index = 1; Index < NumOfInterface; Index++) {

+    UsbIoController                     = CreateUsbIoControllerDevice ();

+    UsbIoController->UsbDevice          = UsbIoDevice;

+    UsbIoController->CurrentConfigValue =

+    UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;

+    UsbIoController->InterfaceNumber    = Index;

+    UsbIoDevice->UsbController[Index]   = UsbIoController;

+    UsbIoController->ParentPort         = ParentPort;

+    UsbIoController->Parent             = ParentHubController;

+    UsbIoController->HostController     = HostController;

+

+    //

+    // First copy the USB_IO Protocol instance

+    //

+    CopyMem (

+      &UsbIoController->UsbIo,

+      UsbIo,

+      sizeof (EFI_USB_IO_PROTOCOL)

+      );

+

+    Result = InitUsbIoController (UsbIoController);

+    if (EFI_ERROR (Result)) {

+      ReportUsbStatusCode (

+        UsbBusDev,

+        EFI_ERROR_CODE | EFI_ERROR_MINOR,

+        EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR

+        );

+      gBS->FreePool (UsbIoController);

+      UsbIoDevice->UsbController[Index] = NULL;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// USB Device DeConfiguration

+//

+

+EFI_STATUS

+UsbDeviceDeConfiguration (

+  IN USB_IO_DEVICE     *UsbIoDevice

+  )

+/*++

+

+  Routine Description:

+    Remove Device, Device Handles, Uninstall Protocols.

+

+  Arguments:

+    UsbIoDevice     -   The device to be deconfigured.

+

+  Returns: 

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *UsbController;

+  UINT8                     index;

+  USB_IO_DEVICE             *ChildDevice;

+  UINT8                     Index;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+

+  DEBUG ((gUSBDebugLevel, "Enter Usb Device Deconfiguration\n"));

+

+  //

+  // Double check UsbIoDevice exists

+  //

+  if (UsbIoDevice == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {

+    //

+    // Check if it is a hub, if so, de configuration all its

+    // downstream ports

+    //

+    UsbController = UsbIoDevice->UsbController[index];

+

+    //

+    // Check the controller pointer

+    //

+    if (UsbController == NULL) {

+      continue;

+    }

+

+    if (UsbController->IsUsbHub) {

+

+      DEBUG ((gUSBDebugLevel, "Hub Deconfig, First Deconfig its downstream ports\n"));

+

+      //

+      // First Remove interrupt transfer request for the status

+      // change port

+      //

+      UsbIo = &UsbController->UsbIo;

+      UsbIo->UsbAsyncInterruptTransfer (

+              UsbIo,

+              UsbController->HubEndpointAddress,

+              FALSE,

+              0,

+              0,

+              NULL,

+              NULL

+              );

+

+      if (NULL != UsbController->HubNotify) {

+        gBS->CloseEvent (UsbController->HubNotify);

+      }

+

+      for (Index = 0; Index < UsbController->DownstreamPorts; Index++) {

+        if (UsbController->Children[Index]) {

+          ChildDevice = UsbController->Children[Index];

+          UsbDeviceDeConfiguration (ChildDevice);

+          UsbController->Children[Index] = NULL;

+        }

+      }

+    }

+    //

+    // If the controller is managed by a device driver, we need to

+    // disconnect them

+    //

+    if (UsbController->IsManagedByDriver) {

+      gBS->DisconnectController (

+            UsbController->Handle,

+            NULL,

+            NULL

+            );

+    }

+    

+    //

+    // remove child handle reference to the USB_HC_PROTOCOL

+    //

+    gBS->CloseProtocol (

+          UsbController->HostController,

+          &gEfiUsbHcProtocolGuid,

+          gUsbBusDriverBinding.DriverBindingHandle,

+          UsbController->Handle

+          );

+

+    //

+    // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL

+    // installed on this handle

+    //

+    gBS->UninstallMultipleProtocolInterfaces (

+          UsbController->Handle,

+          &gEfiDevicePathProtocolGuid,

+          UsbController->DevicePath,

+          &gEfiUsbIoProtocolGuid,

+          &UsbController->UsbIo,

+          NULL

+          );

+

+    if (UsbController->DevicePath != NULL) {

+      gBS->FreePool (UsbController->DevicePath);

+    }

+

+    gBS->FreePool (UsbController);

+    UsbIoDevice->UsbController[index] = NULL;

+  }

+  //

+  // Free address for later use

+  //

+  UsbFreeAddress (

+    UsbIoDevice->DeviceAddress,

+    UsbIoDevice->BusController->AddressPool

+    );

+

+  //

+  // Free all resouces allocated for all its configurations

+  //

+  UsbDestroyAllConfiguration (UsbIoDevice);

+

+  if (UsbIoDevice) {

+    gBS->FreePool (UsbIoDevice);

+    UsbIoDevice = NULL;

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// After interrupt complete, this function will be called,

+// This function need to be well-defined later

+//

+STATIC

+EFI_STATUS

+EFIAPI

+OnHubInterruptComplete (

+  IN  VOID          *Data,

+  IN  UINTN         DataLength,

+  IN  VOID          *Context,

+  IN  UINT32        Result

+  )

+/*++

+

+  Routine Description:

+    Whenever hub interrupt occurs, this routine will be called to check

+    which event happens.

+

+  Arguments:

+    Data          -   Hub interrupt transfer data.

+    DataLength    -   The length of the Data.

+    Context       -   Hub Controller Device.

+    Result        -   Hub interrupt transfer status.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *HubController;

+  UINT8                     Index;

+  UINT8                     *ptr;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+  UINT32                    UsbResult;

+  BOOLEAN                   Disconnected;

+  EFI_STATUS                Status;

+

+  HubController = (USB_IO_CONTROLLER_DEVICE *) Context;

+  UsbIo         = &HubController->UsbIo;

+

+  //

+  // If something error in this interrupt transfer,

+  //

+  if (Result != EFI_USB_NOERROR) {

+    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+      UsbClearEndpointHalt (

+        UsbIo,

+        HubController->HubEndpointAddress,

+        &UsbResult

+        );

+    }

+    

+    //

+    // Delete & Submit this interrupt again

+    //

+    UsbIo->UsbAsyncInterruptTransfer (

+            UsbIo,

+            HubController->HubEndpointAddress,

+            FALSE,

+            0,

+            0,

+            NULL,

+            NULL

+            );

+

+    //

+    // try to detect if the hub itself was disconnected or not

+    //

+    Status = IsDeviceDisconnected (

+              HubController,

+              &Disconnected

+              );

+

+    if (!EFI_ERROR (Status) && Disconnected == TRUE) {

+      DEBUG ((gUSBErrorLevel, "Hub is disconnected\n"));

+      return EFI_DEVICE_ERROR;

+    }

+    //

+    // Hub ports < 7

+    //

+    UsbIo->UsbAsyncInterruptTransfer (

+            UsbIo,

+            HubController->HubEndpointAddress,

+            TRUE,

+            100,

+            1,

+            OnHubInterruptComplete,

+            HubController

+            );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (DataLength == 0 || Data == NULL) {

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // Scan which port has status change

+  // Bit 0 stands for hub itself, other bit stands for

+  // the corresponding port

+  //

+  for (Index = 0; Index < DataLength * 8; Index++) {

+    ptr = (UINT8 *) Data + Index / 8;

+    if ((*ptr) & (1 << (Index & 0x7))) {

+      HubController->StatusChangePort = Index;

+      break;

+    }

+  }

+  //

+  // Signal hub notify event

+  //

+  gBS->SignalEvent (HubController->HubNotify);

+

+  return EFI_SUCCESS;

+}

+//

+// USB Root Hub Enumerator

+//

+STATIC

+VOID

+EFIAPI

+UsbEnumeration (

+  IN EFI_EVENT     Event,

+  IN VOID          *Context

+  )

+/*++

+

+  Routine Description:

+    This is USB enumerator

+

+  Arguments:

+    Event   -   Indicating which event is signaled

+    Context -  actually it is a USB_IO_DEVICE

+

+  Returns:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *HubController;

+  EFI_USB_PORT_STATUS       HubPortStatus;

+  EFI_STATUS                Status;

+  UINT8                     Index;

+  EFI_USB_HC_PROTOCOL       *UsbHCInterface;

+  USB_IO_DEVICE             *UsbIoDev;

+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev;

+  EFI_HANDLE                HostController;

+  USB_IO_DEVICE             *OldUsbIoDevice;

+  USB_IO_DEVICE             *NewDevice;

+  USB_IO_CONTROLLER_DEVICE  *NewController;

+  UINT8                     Index2;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+  UINT8                     StatusChangePort;

+

+  HubController   = (USB_IO_CONTROLLER_DEVICE *) Context;

+  HostController  = HubController->HostController;

+  UsbBusDev       = HubController->UsbDevice->BusController;

+

+  if (HubController->UsbDevice->DeviceAddress == 1) {

+    //

+    // Root hub has the address 1

+    //

+    UsbIoDev        = HubController->UsbDevice;

+    UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;

+

+    for (Index = 0; Index < HubController->DownstreamPorts; Index++) {

+      UsbHCInterface->GetRootHubPortStatus (

+                        UsbHCInterface,

+                        Index,

+                        (EFI_USB_PORT_STATUS *) &HubPortStatus

+                        );

+

+      if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {

+        continue;

+      }

+      //

+      // Clear root hub status change status

+      //

+      ClearRootPortConnectionChangeStatus (

+        Index,

+        UsbHCInterface

+        );

+

+      gBS->Stall (100 * 1000);

+

+      UsbHCInterface->GetRootHubPortStatus (

+                        UsbHCInterface,

+                        Index,

+                        (EFI_USB_PORT_STATUS *) &HubPortStatus

+                        );

+

+      if (IsPortConnect (HubPortStatus.PortStatus)) {

+        

+        //

+        // There is something connected to this port

+        //

+        DEBUG ((gUSBDebugLevel, "Something attached from Root Hub in 0x%x\n", Index));

+

+        ReportUsbStatusCode (

+          UsbBusDev,

+          EFI_PROGRESS_CODE,

+          EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG

+          );

+        //

+        // if there is something physically detached, but still logically

+        // attached...

+        //

+        OldUsbIoDevice = HubController->Children[Index];

+

+        if (NULL != OldUsbIoDevice) {

+          UsbDeviceDeConfiguration (OldUsbIoDevice);

+          HubController->Children[Index] = NULL;

+        }

+

+        NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));

+        if (NewDevice == NULL) {

+          return ;

+        }

+        //

+        // Initialize some fields by copying data from

+        // its parents

+        //

+        NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);

+

+        DEBUG ((gUSBDebugLevel, "DeviceSpeed 0x%x\n", NewDevice->IsSlowDevice));

+

+        NewDevice->BusController = UsbIoDev->BusController;

+

+        //

+        // Configure that device

+        //

+        Status = UsbDeviceConfiguration (

+                  HubController,

+                  HostController,

+                  Index,

+                  NewDevice

+                  );

+        if (EFI_ERROR (Status)) {

+          gBS->FreePool (NewDevice);

+          return ;

+        }

+        //

+        // Add this device to the usb bus tree

+        //

+        HubController->Children[Index] = NewDevice;

+

+        for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {

+          //

+          // If this device is hub, add to the hub index

+          //

+          NewController = NewDevice->UsbController[Index2];

+

+          Status = gBS->ConnectController (

+                          NewController->Handle,

+                          NULL,

+                          NULL,

+                          TRUE

+                          );

+          //

+          // If connect success, we need to disconnect when

+          // stop the controller, otherwise we need not call

+          // gBS->DisconnectController ()

+          // This is used by those usb devices we don't plan

+          // to support. We can allocate

+          // controller handles for them, but we don't have

+          // device drivers to manage them.

+          //

+          NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));

+

+          if (IsHub (NewController)) {

+

+            NewController->IsUsbHub = TRUE;

+

+            //

+            // Configure Hub Controller

+            //

+            Status = DoHubConfig (NewController);

+            if (EFI_ERROR (Status)) {

+              continue;

+            }

+            //

+            // Create an event to do hub enumeration

+            //

+            gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  UsbEnumeration,

+                  NewController,

+                  &NewController->HubNotify

+                  );

+

+            //

+            // Add request to do query hub status

+            // change endpoint

+            // Hub ports < 7

+            //

+            UsbIo = &NewController->UsbIo;

+            UsbIo->UsbAsyncInterruptTransfer (

+                    UsbIo,

+                    NewController->HubEndpointAddress,

+                    TRUE,

+                    100,

+                    1,

+                    OnHubInterruptComplete,

+                    NewController

+                    );

+

+          }

+        }

+      } else {

+        //

+        // Something disconnected from USB root hub

+        //

+        DEBUG ((gUSBDebugLevel, "Something deteached from Root Hub\n"));

+

+        OldUsbIoDevice = HubController->Children[Index];

+

+        UsbDeviceDeConfiguration (OldUsbIoDevice);

+

+        HubController->Children[Index] = NULL;

+

+        UsbHCInterface->ClearRootHubPortFeature (

+                          UsbHCInterface,

+                          Index,

+                          EfiUsbPortEnableChange

+                          );

+

+        UsbHCInterface->GetRootHubPortStatus (

+                          UsbHCInterface,

+                          Index,

+                          (EFI_USB_PORT_STATUS *) &HubPortStatus

+                          );

+

+      }

+    }

+

+    return ;

+  } else {

+    //

+    // Event from Hub, Get the hub controller handle

+    //

+    //

+    // Get the status change endpoint

+    //

+    StatusChangePort = HubController->StatusChangePort;

+

+    //

+    // Clear HubController Status Change Bit

+    //

+    HubController->StatusChangePort = 0;

+

+    if (StatusChangePort == 0) {

+      //

+      // Hub changes, we don't handle here

+      //

+      return ;

+    }

+    //

+    // Check which event took place at that port

+    //

+    UsbIo = &HubController->UsbIo;

+    Status = HubGetPortStatus (

+              UsbIo,

+              StatusChangePort,

+              (UINT32 *) &HubPortStatus

+              );

+

+    if (EFI_ERROR (Status)) {

+      return ;

+    }

+    //

+    // Clear some change status

+    //

+    if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {

+      //

+      // Clear Hub port enable change

+      //

+      DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));

+      HubClearPortFeature (

+        UsbIo,

+        StatusChangePort,

+        EfiUsbPortEnableChange

+        );

+

+      HubGetPortStatus (

+        UsbIo,

+        StatusChangePort,

+        (UINT32 *) &HubPortStatus

+        );

+    }

+

+    if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {

+      //

+      // Clear Hub reset change

+      //

+      DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));

+      HubClearPortFeature (

+        UsbIo,

+        StatusChangePort,

+        EfiUsbPortResetChange

+        );

+

+      HubGetPortStatus (

+        UsbIo,

+        StatusChangePort,

+        (UINT32 *) &HubPortStatus

+        );

+    }

+

+    if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {

+      //

+      // Clear Hub overcurrent change

+      //

+      DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));

+      HubClearPortFeature (

+        UsbIo,

+        StatusChangePort,

+        EfiUsbPortOverCurrentChange

+        );

+

+      HubGetPortStatus (

+        UsbIo,

+        StatusChangePort,

+        (UINT32 *) &HubPortStatus

+        );

+    }

+

+    if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {

+      //

+      // First clear port connection change

+      //

+      DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));

+      HubClearPortFeature (

+        UsbIo,

+        StatusChangePort,

+        EfiUsbPortConnectChange

+        );

+

+      HubGetPortStatus (

+        UsbIo,

+        StatusChangePort,

+        (UINT32 *) &HubPortStatus

+        );

+

+      if (IsPortConnect (HubPortStatus.PortStatus)) {

+

+        DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));

+

+        ReportUsbStatusCode (

+          UsbBusDev,

+          EFI_PROGRESS_CODE,

+          EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG

+          );

+

+        //

+        // if there is something physically detached, but still logically

+        // attached...

+        //

+        OldUsbIoDevice = HubController->Children[StatusChangePort - 1];

+

+        if (NULL != OldUsbIoDevice) {

+          UsbDeviceDeConfiguration (OldUsbIoDevice);

+          HubController->Children[StatusChangePort - 1] = NULL;

+        }

+

+        NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));

+        if (NewDevice == NULL) {

+          return ;

+        }

+

+        ResetHubPort (HubController, StatusChangePort);

+

+        HubGetPortStatus (

+          UsbIo,

+          StatusChangePort,

+          (UINT32 *) &HubPortStatus

+          );

+

+        //

+        // Initialize some fields

+        //

+        NewDevice->IsSlowDevice   = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);

+

+        NewDevice->BusController  = HubController->UsbDevice->BusController;

+

+        //

+        // Configure that device

+        //

+        Status = UsbDeviceConfiguration (

+                  HubController,

+                  HostController,

+                  (UINT8) (StatusChangePort - 1),

+                  NewDevice

+                  );

+

+        if (EFI_ERROR (Status)) {

+          gBS->FreePool (NewDevice);

+          return ;

+        }

+        //

+        // Add this device to the usb bus tree

+        // StatusChangePort is begin from 1,

+        //

+        HubController->Children[StatusChangePort - 1] = NewDevice;

+

+        for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {

+          //

+          // If this device is hub, add to the hub index

+          //

+          NewController = NewDevice->UsbController[Index2];

+

+          //

+          // Connect the controller to the driver image

+          //

+          Status = gBS->ConnectController (

+                          NewController->Handle,

+                          NULL,

+                          NULL,

+                          TRUE

+                          );

+          //

+          // If connect success, we need to disconnect when

+          // stop the controller, otherwise we need not call

+          // gBS->DisconnectController ()

+          // This is used by those usb devices we don't plan

+          // to support. We can allocate

+          // controller handles for them, but we don't have

+          // device drivers to manage them.

+          //

+          NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));

+

+          //

+          // If this device is hub, add to the hub index

+          //

+          if (IsHub (NewController)) {

+

+            NewController->IsUsbHub = TRUE;

+

+            //

+            // Configure Hub

+            //

+            Status = DoHubConfig (NewController);

+

+            if (EFI_ERROR (Status)) {

+              continue;

+            }

+            //

+            // Create an event to do hub enumeration

+            //

+            gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  UsbEnumeration,

+                  NewController,

+                  &NewController->HubNotify

+                  );

+

+            //

+            // Add request to do query hub status

+            // change endpoint

+            //

+            UsbIo = &NewController->UsbIo;

+            UsbIo->UsbAsyncInterruptTransfer (

+                    UsbIo,

+                    NewController->HubEndpointAddress,  // Hub endpoint address

+                    TRUE,

+                    100,

+                    1,                                  // Hub ports < 7

+                    OnHubInterruptComplete,

+                    NewController

+                    );

+          }

+        }

+      } else {

+        //

+        // Something disconnected from USB hub

+        //

+        DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));

+

+        OldUsbIoDevice = HubController->Children[StatusChangePort - 1];

+

+        UsbDeviceDeConfiguration (OldUsbIoDevice);

+

+        HubController->Children[StatusChangePort - 1] = NULL;

+

+      }

+

+      return ;

+    }

+

+    return ;

+  }

+}

+//

+// Clear port connection change status over a given root hub port

+//

+EFI_STATUS

+ClearRootPortConnectionChangeStatus (

+  UINT8                   PortNum,

+  EFI_USB_HC_PROTOCOL     *UsbHCInterface

+  )

+/*++

+

+  Routine Description:

+    Clear port connection change status over a given root hub port

+

+  Arguments:

+    PortNum         -   The given port.

+    UsbHCInterface  -   The EFI_USB_HC_PROTOCOL instance.

+

+  Returns:

+     EFI_SUCCESS

+

+--*/

+{

+  EFI_STATUS  Status;

+  Status = UsbHCInterface->ClearRootHubPortFeature (

+                            UsbHCInterface,

+                            PortNum,

+                            EfiUsbPortConnectChange

+                            );

+  return Status;

+}

+

+STATIC

+USB_IO_CONTROLLER_DEVICE *

+CreateUsbIoControllerDevice (

+  VOID

+  )

+/*++

+

+  Routine Description:

+    Allocate a structure for USB_IO_CONTROLLER_DEVICE

+

+  Arguments:

+    N/A

+

+  Returns:

+    A pointer to a USB_IO_CONTROLLER_DEVICE structure,

+    Or NULL.

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *UsbIoControllerDev;

+

+  //

+  // Allocate USB_IO_CONTROLLER_DEVICE structure

+  //

+  UsbIoControllerDev  = NULL;

+  UsbIoControllerDev  = AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE));

+

+  if (UsbIoControllerDev == NULL) {

+    return NULL;

+  }

+

+  UsbIoControllerDev->Signature = USB_IO_CONTROLLER_SIGNATURE;

+

+  return UsbIoControllerDev;

+}

+

+STATIC

+EFI_STATUS

+InitUsbIoController (

+  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController

+  )

+/*++

+

+  Routine Description:

+    Init and install EFI_USB_IO_PROTOCOL onto that controller.

+

+  Arguments:

+    UsbIoController   -   The Controller to be operated.

+

+  Returns:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  USB_DEVICE_PATH           UsbNode;

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+  EFI_USB_HC_PROTOCOL       *UsbHcProtocol;

+

+  //

+  // Build the child device path for each new USB_IO device

+  //

+  ZeroMem (&UsbNode, sizeof (UsbNode));

+  UsbNode.Header.Type     = MESSAGING_DEVICE_PATH;

+  UsbNode.Header.SubType  = MSG_USB_DP;

+  SetDevicePathNodeLength (&UsbNode.Header, sizeof (UsbNode));

+  UsbNode.InterfaceNumber     = UsbIoController->InterfaceNumber;

+  UsbNode.ParentPortNumber    = UsbIoController->ParentPort;

+  ParentDevicePath            = UsbIoController->Parent->DevicePath;

+

+  UsbIoController->DevicePath =

+  AppendDevicePathNode (ParentDevicePath, &UsbNode.Header);

+  if (UsbIoController->DevicePath == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &UsbIoController->Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  UsbIoController->DevicePath,

+                  &gEfiUsbIoProtocolGuid,

+                  &UsbIoController->UsbIo,

+                  NULL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  UsbIoController->HostController,

+                  &gEfiUsbHcProtocolGuid,

+                  (VOID **) &UsbHcProtocol,

+                  gUsbBusDriverBinding.DriverBindingHandle,

+                  UsbIoController->Handle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+ParentPortReset (

+  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,

+  IN BOOLEAN                     ReConfigure,

+  IN UINT8                       RetryTimes

+  )

+/*++

+

+  Routine Description:

+    Reset parent hub port to which this device is connected.

+

+  Arguments:

+    UsbIoController   - Indicating the Usb Controller Device.

+    Reconfigure       - Do we need to reconfigure it.

+    RetryTimes        - Retry Times when failed

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_DEVICE             *ParentIoDev;

+  USB_IO_DEVICE             *UsbIoDev;

+  USB_IO_CONTROLLER_DEVICE  *ParentController;

+  UINT8                     HubPort;

+  UINT32                    Status;

+  EFI_STATUS                Result;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+  UINT8                     Address;

+

+  ParentController  = UsbIoController->Parent;

+  ParentIoDev       = ParentController->UsbDevice;

+  UsbIoDev          = UsbIoController->UsbDevice;

+  HubPort           = UsbIoController->ParentPort;

+

+  gBS->Stall (100 * 1000);

+

+  if (ParentIoDev->DeviceAddress == 1) {

+    DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));

+    ResetRootPort (ParentIoDev->BusController->UsbHCInterface, HubPort, RetryTimes);

+  } else {

+    DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));

+    ResetHubPort (ParentController, HubPort + 1);

+  }

+  //

+  // If we only need port reset, just return

+  //

+  if (!ReConfigure) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Re-config that USB device

+  //

+  UsbIo = &UsbIoController->UsbIo;

+

+  //

+  // Assign a unique address to this device

+  //

+  Address                 = UsbIoDev->DeviceAddress;

+  UsbIoDev->DeviceAddress = 0;

+

+  Result                  = UsbSetDeviceAddress (UsbIo, Address, &Status);

+  UsbIoDev->DeviceAddress = Address;

+

+  if (EFI_ERROR (Result)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set the device to the default configuration

+  //

+  Result = UsbSetDefaultConfiguration (UsbIoDev);

+  if (EFI_ERROR (Result)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+UsbPortReset (

+  IN EFI_USB_IO_PROTOCOL      *This

+  )

+/*++

+

+  Routine Description:

+    Resets and reconfigures the USB controller.  This function will

+    work for all USB devices except USB Hub Controllers.

+

+  Arguments:

+    This          -   Indicates the calling context.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+  EFI_STATUS                Status;

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+

+  //

+  // Since at this time, this device has already been configured,

+  // it needs to be re-configured.

+  //

+  Status = ParentPortReset (UsbIoController, TRUE, 0);

+

+  return Status;

+}

+

+EFI_STATUS

+ResetRootPort (

+  IN EFI_USB_HC_PROTOCOL     *UsbHCInterface,

+  IN UINT8                   PortNum,

+  IN UINT8                   RetryTimes

+  )

+/*++

+

+  Routine Description:

+    Reset Root Hub port.

+

+  Arguments:

+    UsbHCInterface  -   The EFI_USB_HC_PROTOCOL instance.

+    PortNum         -   The given port to be reset.

+    RetryTimes      -   RetryTimes when failed

+  Returns:

+    N/A

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // reset root port

+  //

+  Status = UsbHCInterface->SetRootHubPortFeature (

+                            UsbHCInterface,

+                            PortNum,

+                            EfiUsbPortReset

+                            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  gBS->Stall (50 * 1000);

+

+  //

+  // clear reset root port

+  //

+  Status = UsbHCInterface->ClearRootHubPortFeature (

+                            UsbHCInterface,

+                            PortNum,

+                            EfiUsbPortReset

+                            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  gBS->Stall (1000);

+

+  Status = ClearRootPortConnectionChangeStatus (PortNum, UsbHCInterface);

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set port enable

+  //

+  Status = UsbHCInterface->SetRootHubPortFeature (

+                            UsbHCInterface,

+                            PortNum,

+                            EfiUsbPortEnable

+                            );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = UsbHCInterface->ClearRootHubPortFeature (

+                            UsbHCInterface,

+                            PortNum,

+                            EfiUsbPortEnableChange

+                            );

+  gBS->Stall ((1 + RetryTimes) * 50 * 1000);

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+ResetHubPort (

+  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,

+  IN UINT8                       PortIndex

+  )

+/*++

+

+  Routine Description:

+    Reset Hub port.

+

+  Arguments:

+    UsbIoController  -   The USB_IO_CONTROLLER_DEVICE instance.

+    PortIndex        -   The given port to be reset.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  EFI_USB_PORT_STATUS HubPortStatus;

+  UINT8               Number;

+

+  ASSERT (UsbIoController->IsUsbHub == TRUE);

+

+  UsbIo = &UsbIoController->UsbIo;

+

+  HubSetPortFeature (

+    UsbIo,

+    PortIndex,

+    EfiUsbPortReset

+    );

+

+  gBS->Stall (10 * 1000);

+

+  //

+  // Wait for port reset complete

+  //

+  Number = 10;

+  do {

+    HubGetPortStatus (

+      UsbIo,

+      PortIndex,

+      (UINT32 *) &HubPortStatus

+      );

+    gBS->Stall (10 * 100);

+    Number -= 1;

+  } while ((HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0 && Number > 0);

+

+  if (Number == 0) {

+    //

+    // Cannot reset port, return error

+    //

+    return EFI_DEVICE_ERROR;

+  }

+

+  gBS->Stall (1000);

+

+  HubGetPortStatus (

+    UsbIo,

+    PortIndex,

+    (UINT32 *) &HubPortStatus

+    );

+  //

+  // reset port will cause some bits change, clear them

+  //

+  if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {

+    DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));

+    HubClearPortFeature (

+      UsbIo,

+      PortIndex,

+      EfiUsbPortEnableChange

+      );

+  }

+

+  if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {

+    DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));

+    HubClearPortFeature (

+      UsbIo,

+      PortIndex,

+      EfiUsbPortResetChange

+      );

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+

+

+

+STATIC

+EFI_STATUS

+ReportUsbStatusCode (

+  IN USB_BUS_CONTROLLER_DEVICE     *UsbBusController,

+  IN EFI_STATUS_CODE_TYPE          Type,

+  IN EFI_STATUS_CODE_VALUE         Code

+  )

+/*++

+

+Routine Description:

+

+  report a error Status code of USB bus driver controller

+

+ Arguments:

+   UsbBusController - USB_BUS_CONTROLLER_DEVICE

+   Type             - EFI_STATUS_CODE_TYPE

+   Code             - EFI_STATUS_CODE_VALUE

+ Returns:

+

+  None

+

+--*/

+{

+  return REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+          Type,

+          Code,

+          UsbBusController->DevicePath

+          );

+}

+

+

+EFI_STATUS

+IsDeviceDisconnected (

+  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,

+  IN OUT BOOLEAN                 *Disconnected

+  )

+/*++

+

+  Routine Description:

+    Reset if the device is disconencted or not

+

+  Arguments:

+    UsbIoController   -   Indicating the Usb Controller Device.

+    Disconnected      -   Indicate whether the device is disconencted or not

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_DEVICE             *ParentIoDev;

+  USB_IO_DEVICE             *UsbIoDev;

+  USB_IO_CONTROLLER_DEVICE  *ParentController;

+  UINT8                     HubPort;

+  EFI_STATUS                Status;

+  EFI_USB_IO_PROTOCOL       *UsbIo;

+  EFI_USB_PORT_STATUS       PortStatus;

+  EFI_USB_HC_PROTOCOL       *UsbHCInterface;

+

+  ParentController  = UsbIoController->Parent;

+  ParentIoDev       = ParentController->UsbDevice;

+  UsbIoDev          = UsbIoController->UsbDevice;

+  HubPort           = UsbIoController->ParentPort;

+

+  if (ParentIoDev->DeviceAddress == 1) {

+    //

+    // Connected to the root hub

+    //

+    UsbHCInterface = ParentIoDev->BusController->UsbHCInterface;

+    Status = UsbHCInterface->GetRootHubPortStatus (

+                              UsbHCInterface,

+                              HubPort,

+                              &PortStatus

+                              );

+

+  } else {

+    UsbIo = &UsbIoController->UsbIo;

+    Status = HubGetPortStatus (

+              &ParentController->UsbIo,

+              HubPort + 1,

+              (UINT32 *) &PortStatus

+              );

+

+    if (EFI_ERROR (Status)) {

+      return IsDeviceDisconnected (ParentController, Disconnected);

+    }

+  }

+

+  *Disconnected = FALSE;

+

+  if (!IsPortConnect (PortStatus.PortStatus)) {

+    *Disconnected = TRUE;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h
new file mode 100644
index 0000000..036f4df
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h
@@ -0,0 +1,261 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    usbbus.h

+

+  Abstract:

+

+    Header file for USB bus driver Interface

+

+  Revision History

+

+

+

+--*/

+

+#ifndef _EFI_USB_BUS_H

+#define _EFI_USB_BUS_H

+

+

+#include <IndustryStandard/Usb.h>

+#include "hub.h"

+#include "usbutil.h"

+

+//#ifdef EFI_DEBUG

+extern UINTN  gUSBDebugLevel;

+extern UINTN  gUSBErrorLevel;

+//#endif

+

+#define MICROSECOND 10000

+#define ONESECOND   (1000 * MICROSECOND)

+#define BUSPOLLING_PERIOD ONESECOND

+//

+// We define some maximun value here

+//

+#define USB_MAXCONFIG               8

+#define USB_MAXALTSETTING           4

+#define USB_MAXINTERFACES           32

+#define USB_MAXENDPOINTS            16

+#define USB_MAXSTRINGS              16

+#define USB_MAXLANID                16

+#define USB_MAXCHILDREN             8

+#define USB_MAXCONTROLLERS          4

+

+#define USB_IO_CONTROLLER_SIGNATURE EFI_SIGNATURE_32 ('u', 's', 'b', 'd')

+

+typedef struct {

+  LIST_ENTRY      Link;

+  UINT16          StringIndex;

+  CHAR16          *String;

+} STR_LIST_ENTRY;

+

+typedef struct {

+  LIST_ENTRY                  Link;

+  UINT16                      Toggle;

+  EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;

+} ENDPOINT_DESC_LIST_ENTRY;

+

+typedef struct {

+  LIST_ENTRY                    Link;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  LIST_ENTRY                    EndpointDescListHead;

+} INTERFACE_DESC_LIST_ENTRY;

+

+typedef struct {

+  LIST_ENTRY                Link;

+  EFI_USB_CONFIG_DESCRIPTOR CongfigDescriptor;

+  LIST_ENTRY                InterfaceDescListHead;

+  UINTN                     ActiveInterface;

+} CONFIG_DESC_LIST_ENTRY;

+

+//

+// Forward declaring

+//

+struct usb_io_device;

+

+//

+// This is used to form the USB Controller Handle

+//

+typedef struct usb_io_controller_device {

+  UINTN                           Signature;

+  EFI_HANDLE                      Handle;

+  EFI_USB_IO_PROTOCOL             UsbIo;

+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;

+  EFI_HANDLE                      HostController;

+  UINT8                           CurrentConfigValue;

+  UINT8                           InterfaceNumber;

+  struct usb_io_device            *UsbDevice;

+

+  BOOLEAN                         IsUsbHub;

+  BOOLEAN                         IsManagedByDriver;

+

+  //

+  // Fields specified for USB Hub

+  //

+  EFI_EVENT                       HubNotify;

+  UINT8                           HubEndpointAddress;

+  UINT8                           StatusChangePort;

+  UINT8                           DownstreamPorts;

+

+  UINT8                           ParentPort;

+  struct usb_io_controller_device *Parent;

+  struct usb_io_device            *Children[USB_MAXCHILDREN];

+} USB_IO_CONTROLLER_DEVICE;

+

+#define USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS(a) \

+    CR(a, USB_IO_CONTROLLER_DEVICE, UsbIo, USB_IO_CONTROLLER_SIGNATURE)

+

+//

+// This is used to keep the topology of USB bus

+//

+struct _usb_bus_controller_device;

+

+typedef struct usb_io_device {

+  UINT8                             DeviceAddress;

+  BOOLEAN                           IsConfigured;

+  BOOLEAN                           IsSlowDevice;

+  EFI_USB_DEVICE_DESCRIPTOR         DeviceDescriptor;

+  LIST_ENTRY                        ConfigDescListHead;

+  CONFIG_DESC_LIST_ENTRY            *ActiveConfig;

+  UINT16                            LangID[USB_MAXLANID];

+

+  struct _usb_bus_controller_device *BusController;

+

+  //

+  // Track the controller handle

+  //

+  UINT8                             NumOfControllers;

+  USB_IO_CONTROLLER_DEVICE          *UsbController[USB_MAXCONTROLLERS];

+

+} USB_IO_DEVICE;

+

+//

+// Usb Bus Controller device strcuture

+//

+#define EFI_USB_BUS_PROTOCOL_GUID \

+ { 0x2B2F68CC, 0x0CD2, 0x44cf, { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75  } }

+

+typedef struct _EFI_USB_BUS_PROTOCOL {

+  UINT64  Reserved;

+} EFI_USB_BUS_PROTOCOL;

+

+#define USB_BUS_DEVICE_SIGNATURE  EFI_SIGNATURE_32 ('u', 'b', 'u', 's')

+

+typedef struct _usb_bus_controller_device {

+  UINTN                     Signature;

+

+  EFI_USB_BUS_PROTOCOL      BusIdentify;

+  EFI_USB_HC_PROTOCOL       *UsbHCInterface;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  UINT8                     AddressPool[16];

+  USB_IO_DEVICE             *Root;

+} USB_BUS_CONTROLLER_DEVICE;

+

+#define USB_BUS_CONTROLLER_DEVICE_FROM_THIS(a) \

+    CR(a, USB_BUS_CONTROLLER_DEVICE, BusIdentify, USB_BUS_DEVICE_SIGNATURE)

+

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gUsbBusDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gUsbBusComponentName;

+extern EFI_GUID                     gUSBBusDriverGuid;

+

+//

+// Usb Device Configuration functions

+//

+BOOLEAN

+IsHub (

+  IN USB_IO_CONTROLLER_DEVICE     *Dev

+  );

+

+EFI_STATUS

+UsbGetStringtable (

+  IN  USB_IO_DEVICE     *UsbIoDevice

+  );

+

+EFI_STATUS

+UsbGetAllConfigurations (

+  IN  USB_IO_DEVICE     *UsbIoDevice

+  );

+

+EFI_STATUS

+UsbSetConfiguration (

+  IN  USB_IO_DEVICE     *Dev,

+  IN  UINTN             ConfigurationValue

+  );

+

+EFI_STATUS

+UsbSetDefaultConfiguration (

+  IN  USB_IO_DEVICE     *Dev

+  );

+

+//

+// Device Deconfiguration functions

+//

+VOID

+UsbDestroyAllConfiguration (

+  IN USB_IO_DEVICE     *UsbIoDevice

+  );

+

+EFI_STATUS

+DoHubConfig (

+  IN USB_IO_CONTROLLER_DEVICE     *HubIoDevice

+  );

+

+VOID

+GetDeviceEndPointMaxPacketLength (

+  IN EFI_USB_IO_PROTOCOL    *UsbIo,

+  IN  UINT8                 EndpointAddr,

+  OUT UINT8                 *MaxPacketLength

+  );

+

+VOID

+GetDataToggleBit (

+  IN EFI_USB_IO_PROTOCOL    *UsbIo,

+  IN  UINT8                 EndpointAddr,

+  OUT UINT8                 *DataToggle

+  );

+

+VOID

+SetDataToggleBit (

+  IN EFI_USB_IO_PROTOCOL    *UsbIo,

+  IN UINT8                  EndpointAddr,

+  IN UINT8                  DataToggle

+  );

+

+INTERFACE_DESC_LIST_ENTRY *

+FindInterfaceListEntry (

+  IN EFI_USB_IO_PROTOCOL    *This

+  );

+

+ENDPOINT_DESC_LIST_ENTRY *

+FindEndPointListEntry (

+  IN EFI_USB_IO_PROTOCOL    *This,

+  IN UINT8                  EndPointAddress

+  );

+

+

+EFI_STATUS

+IsDeviceDisconnected (

+  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,

+  IN OUT BOOLEAN                 *Disconnected

+  );

+

+EFI_STATUS

+UsbDeviceDeConfiguration (

+  IN USB_IO_DEVICE     *UsbIoDevice

+  );

+

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
new file mode 100644
index 0000000..bd87c5c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
@@ -0,0 +1,1176 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    UsbIo.c

+

+  Abstract:

+

+    USB I/O Abstraction Driver

+

+  Revision History

+

+--*/

+

+#include "usbbus.h"

+

+//

+// USB I/O Support Function Prototypes

+//

+STATIC

+EFI_STATUS

+EFIAPI

+UsbControlTransfer (

+  IN       EFI_USB_IO_PROTOCOL        *This,

+  IN       EFI_USB_DEVICE_REQUEST     *Request,

+  IN       EFI_USB_DATA_DIRECTION     Direction,

+  IN       UINT32                     Timeout,

+  IN OUT   VOID                       *Data, OPTIONAL

+  IN       UINTN                      DataLength, OPTIONAL

+  OUT      UINT32                     *Status

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbBulkTransfer (

+  IN       EFI_USB_IO_PROTOCOL     *This,

+  IN       UINT8                   DeviceEndpoint,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN       UINTN                   Timeout,

+  OUT      UINT32                  *Status

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbAsyncInterruptTransfer (

+  IN EFI_USB_IO_PROTOCOL                 * This,

+  IN UINT8                               DeviceEndpoint,

+  IN BOOLEAN                             IsNewTransfer,

+  IN UINTN                               PollingInterval, OPTIONAL

+  IN UINTN                               DataLength, OPTIONAL

+  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     InterruptCallBack, OPTIONAL

+  IN VOID                                *Context OPTIONAL

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbSyncInterruptTransfer (

+  IN       EFI_USB_IO_PROTOCOL     *This,

+  IN       UINT8                   DeviceEndpoint,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN       UINTN                   Timeout,

+  OUT      UINT32                  *Status

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbIsochronousTransfer (

+  IN       EFI_USB_IO_PROTOCOL     *This,

+  IN       UINT8                   DeviceEndpoint,

+  IN OUT   VOID                    *Data,

+  IN       UINTN                   DataLength,

+  OUT      UINT32                  *Status

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbAsyncIsochronousTransfer (

+  IN        EFI_USB_IO_PROTOCOL                 * This,

+  IN        UINT8                               DeviceEndpoint,

+  IN OUT    VOID                                *Data,

+  IN        UINTN                               DataLength,

+  IN        EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,

+  IN        VOID                                *Context OPTIONAL

+  );

+

+extern

+EFI_STATUS

+EFIAPI

+UsbPortReset (

+  IN EFI_USB_IO_PROTOCOL     *This

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetDeviceDescriptor (

+  IN  EFI_USB_IO_PROTOCOL           *This,

+  OUT EFI_USB_DEVICE_DESCRIPTOR     *DeviceDescriptor

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetActiveConfigDescriptor (

+  IN  EFI_USB_IO_PROTOCOL           *This,

+  OUT EFI_USB_CONFIG_DESCRIPTOR     *ConfigurationDescriptor

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetInterfaceDescriptor (

+  IN  EFI_USB_IO_PROTOCOL              *This,

+  OUT EFI_USB_INTERFACE_DESCRIPTOR     *InterfaceDescriptor

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetEndpointDescriptor (

+  IN  EFI_USB_IO_PROTOCOL             *This,

+  IN  UINT8                           EndpointIndex,

+  OUT EFI_USB_ENDPOINT_DESCRIPTOR     *EndpointDescriptor

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetStringDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *This,

+  IN  UINT16                  LangID,

+  IN  UINT8                   StringIndex,

+  OUT CHAR16                  **String

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetSupportedLanguages (

+  IN  EFI_USB_IO_PROTOCOL      *This,

+  OUT UINT16                   **LangIDTable,

+  OUT UINT16                   *TableSize

+  );

+

+//

+// USB I/O Interface structure

+//

+STATIC EFI_USB_IO_PROTOCOL  UsbIoInterface = {

+  UsbControlTransfer,

+  UsbBulkTransfer,

+  UsbAsyncInterruptTransfer,

+  UsbSyncInterruptTransfer,

+  UsbIsochronousTransfer,

+  UsbAsyncIsochronousTransfer,

+  UsbGetDeviceDescriptor,

+  UsbGetActiveConfigDescriptor,

+  UsbGetInterfaceDescriptor,

+  UsbGetEndpointDescriptor,

+  UsbGetStringDescriptor,

+  UsbGetSupportedLanguages,

+  UsbPortReset

+};

+

+VOID

+InitializeUsbIoInstance (

+  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController

+  )

+{

+  //

+  // Copy EFI_USB_IO protocol instance

+  //

+  CopyMem (

+    &UsbIoController->UsbIo,

+    &UsbIoInterface,

+    sizeof (EFI_USB_IO_PROTOCOL)

+    );

+}

+//

+// Implementation

+//

+STATIC

+EFI_STATUS

+EFIAPI

+UsbControlTransfer (

+  IN       EFI_USB_IO_PROTOCOL        *This,

+  IN       EFI_USB_DEVICE_REQUEST     *Request,

+  IN       EFI_USB_DATA_DIRECTION     Direction,

+  IN       UINT32                     Timeout,

+  IN OUT   VOID                       *Data, OPTIONAL

+  IN       UINTN                      DataLength, OPTIONAL

+  OUT      UINT32                     *Status

+  )

+/*++

+

+  Routine Description:

+    This function is used to manage a USB device with a control transfer pipe.

+

+  Arguments:

+    This        -   Indicates calling context.

+    Request     -   A pointer to the USB device request that will be sent to

+                    the USB device.

+    Direction   -   Indicates the data direction.

+    Data        -   A pointer to the buffer of data that will be transmitted

+                    to USB device or received from USB device.

+    Timeout     -   Indicates the transfer should be completed within this time

+                    frame.

+    DataLength  -   The size, in bytes, of the data buffer specified by Data.

+    Status      -   A pointer to the result of the USB transfer.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_OUT_OF_RESOURCES

+    EFI_TIMEOUT

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+  EFI_USB_HC_PROTOCOL       *UsbHCInterface;

+  EFI_STATUS                RetStatus;

+  USB_IO_DEVICE             *UsbIoDevice;

+  UINT8                     MaxPacketLength;

+  UINT32                    TransferResult;

+  BOOLEAN                   Disconnected;

+  //

+  // Parameters Checking

+  //

+  if (Status == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // leave the HostController's ControlTransfer

+  // to perform other parameters checking

+  //

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDevice     = UsbIoController->UsbDevice;

+  UsbHCInterface  = UsbIoDevice->BusController->UsbHCInterface;

+  MaxPacketLength = UsbIoDevice->DeviceDescriptor.MaxPacketSize0;

+

+ 

+  if (Request->Request     == USB_DEV_CLEAR_FEATURE && 

+      Request->RequestType == 0x02                  && 

+      Request->Value       == EfiUsbEndpointHalt) {

+     //

+     //Reduce the remove delay time for system response

+     //

+     IsDeviceDisconnected (UsbIoController, &Disconnected);

+     if (!EFI_ERROR (Status) && Disconnected == TRUE) {

+      DEBUG ((gUSBErrorLevel, "Device is disconnected when trying reset\n"));

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+

+

+  //

+  // using HostController's ControlTransfer to complete the request

+  //

+  RetStatus = UsbHCInterface->ControlTransfer (

+                                UsbHCInterface,

+                                UsbIoDevice->DeviceAddress,

+                                UsbIoDevice->IsSlowDevice,

+                                MaxPacketLength,

+                                Request,

+                                Direction,

+                                Data,

+                                &DataLength,

+                                (UINTN) Timeout,

+                                &TransferResult

+                                );

+  *Status = TransferResult;

+

+  if (Request->Request     == USB_DEV_CLEAR_FEATURE && 

+      Request->RequestType == 0x02                  && 

+      Request->Value       == EfiUsbEndpointHalt) {

+    //

+    // This is a UsbClearEndpointHalt request

+    // Need to clear data toggle

+    // Request.Index == EndpointAddress

+    //

+    if (!EFI_ERROR (RetStatus) && TransferResult == EFI_USB_NOERROR) {

+      SetDataToggleBit (

+        This,

+        (UINT8) Request->Index,

+        0

+        );

+    }

+  }

+  return RetStatus;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbBulkTransfer (

+  IN       EFI_USB_IO_PROTOCOL     *This,

+  IN       UINT8                   DeviceEndpoint,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN       UINTN                   Timeout,

+  OUT      UINT32                  *Status

+  )

+/*++

+

+  Routine Description:

+    This function is used to manage a USB device with the bulk transfer pipe.

+

+  Arguments:

+    This            - Indicates calling context.

+    DeviceEndpoint  - The destination USB device endpoint to which the device

+                      request is being sent.

+    Data            - A pointer to the buffer of data that will be transmitted

+                      to USB device or received from USB device.

+    DataLength      - On input, the size, in bytes, of the data buffer

+                      specified by Data.  On output, the number of bytes that

+                      were actually transferred.

+    Timeout         - Indicates the transfer should be completed within this

+                      time frame.

+    Status          - This parameter indicates the USB transfer status.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_OUT_OF_RESOURCES

+    EFI_TIMEOUT

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_DEVICE               *UsbIoDev;

+  UINT8                       MaxPacketLength;

+  UINT8                       DataToggle;

+  UINT8                       OldToggle;

+  EFI_STATUS                  RetStatus;

+  EFI_USB_HC_PROTOCOL         *UsbHCInterface;

+  USB_IO_CONTROLLER_DEVICE    *UsbIoController;

+  ENDPOINT_DESC_LIST_ENTRY    *EndPointListEntry;

+  UINT32                      TransferResult;

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+  UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;

+

+  //

+  // Parameters Checking

+  //

+  if ((DeviceEndpoint & 0x7F) == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((DeviceEndpoint & 0x7F) > 15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Status == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EndPointListEntry = FindEndPointListEntry (

+                        This,

+                        DeviceEndpoint

+                        );

+

+  if (EndPointListEntry == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x02) {

+    return EFI_INVALID_PARAMETER;

+  }

+                        

+  //

+  // leave the HostController's BulkTransfer

+  // to perform other parameters checking

+  //

+  GetDeviceEndPointMaxPacketLength (

+    This,

+    DeviceEndpoint,

+    &MaxPacketLength

+    );

+

+  GetDataToggleBit (

+    This,

+    DeviceEndpoint,

+    &DataToggle

+    );

+

+  OldToggle = DataToggle;

+

+  //

+  // using HostController's BulkTransfer to complete the request

+  //

+  RetStatus = UsbHCInterface->BulkTransfer (

+                                UsbHCInterface,

+                                UsbIoDev->DeviceAddress,

+                                DeviceEndpoint,

+                                MaxPacketLength,

+                                Data,

+                                DataLength,

+                                &DataToggle,

+                                Timeout,

+                                &TransferResult

+                                );

+

+  if (OldToggle != DataToggle) {

+    //

+    // Write the toggle back

+    //

+    SetDataToggleBit (

+      This,

+      DeviceEndpoint,

+      DataToggle

+      );

+  }

+

+  *Status = TransferResult;

+

+  return RetStatus;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbSyncInterruptTransfer (

+  IN       EFI_USB_IO_PROTOCOL     *This,

+  IN       UINT8                   DeviceEndpoint,

+  IN OUT   VOID                    *Data,

+  IN OUT   UINTN                   *DataLength,

+  IN       UINTN                   Timeout,

+  OUT      UINT32                  *Status

+  )

+/*++

+

+  Routine Description:

+    Usb Sync Interrupt Transfer

+

+  Arguments:

+    This            - Indicates calling context.

+    DeviceEndpoint  - The destination USB device endpoint to which the device

+                      request is being sent.

+    Data            - A pointer to the buffer of data that will be transmitted

+                      to USB device or received from USB device.

+    DataLength      - On input, the size, in bytes, of the data buffer

+                      specified by Data.  On output, the number of bytes that

+                      were actually transferred.

+    Timeout         - Indicates the transfer should be completed within this

+                      time frame.

+    Status          - This parameter indicates the USB transfer status.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_OUT_OF_RESOURCES

+    EFI_TIMEOUT

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_IO_DEVICE               *UsbIoDev;

+  UINT8                       MaxPacketLength;

+  UINT8                       DataToggle;

+  UINT8                       OldToggle;

+  EFI_STATUS                  RetStatus;

+  EFI_USB_HC_PROTOCOL         *UsbHCInterface;

+  USB_IO_CONTROLLER_DEVICE    *UsbIoController;

+  ENDPOINT_DESC_LIST_ENTRY    *EndPointListEntry;

+

+  //

+  // Parameters Checking

+  //

+  if ((DeviceEndpoint & 0x7F) == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((DeviceEndpoint & 0x7F) > 15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Status == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EndPointListEntry = FindEndPointListEntry (

+                        This,

+                        DeviceEndpoint

+                        );

+

+  if (EndPointListEntry == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x03) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // leave the HostController's SyncInterruptTransfer

+  // to perform other parameters checking

+  //

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+  UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;

+

+  GetDeviceEndPointMaxPacketLength (

+    This,

+    DeviceEndpoint,

+    &MaxPacketLength

+    );

+

+  GetDataToggleBit (

+    This,

+    DeviceEndpoint,

+    &DataToggle

+    );

+

+  OldToggle = DataToggle;

+  //

+  // using HostController's SyncInterruptTransfer to complete the request

+  //

+  RetStatus = UsbHCInterface->SyncInterruptTransfer (

+                                UsbHCInterface,

+                                UsbIoDev->DeviceAddress,

+                                DeviceEndpoint,

+                                UsbIoDev->IsSlowDevice,

+                                MaxPacketLength,

+                                Data,

+                                DataLength,

+                                &DataToggle,

+                                Timeout,

+                                Status

+                                );

+

+  if (OldToggle != DataToggle) {

+    //

+    // Write the toggle back

+    //

+    SetDataToggleBit (

+      This,

+      DeviceEndpoint,

+      DataToggle

+      );

+  }

+

+  return RetStatus;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbAsyncInterruptTransfer (

+  IN EFI_USB_IO_PROTOCOL                 *This,

+  IN UINT8                               DeviceEndpoint,

+  IN BOOLEAN                             IsNewTransfer,

+  IN UINTN                               PollingInterval, OPTIONAL

+  IN UINTN                               DataLength, OPTIONAL

+  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     InterruptCallBack, OPTIONAL

+  IN VOID                                *Context OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Usb Async Interrput Transfer

+

+  Arguments:

+    This              -   Indicates calling context.

+    DeviceEndpoint    -   The destination USB device endpoint to which the

+                          device request is being sent.

+    IsNewTransfer     -   If TRUE, a new transfer will be submitted to USB

+                          controller.  If FALSE,  the interrupt transfer is

+                          deleted from the device's interrupt transfer queue.

+    PollingInterval   -   Indicates the periodic rate, in milliseconds, that

+                          the transfer is to be executed.

+    DataLength        -   Specifies the length, in bytes, of the data to be

+                          received from the USB device.

+    InterruptCallback -   The Callback function.  This function is called if

+                          the asynchronous interrupt transfer is completed.

+    Context           -   Passed to InterruptCallback 

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_OUT_OF_RESOURCES

+

+--*/

+{

+  USB_IO_DEVICE               *UsbIoDev;

+  UINT8                       MaxPacketLength;

+  UINT8                       DataToggle;

+  EFI_USB_HC_PROTOCOL         *UsbHCInterface;

+  EFI_STATUS                  RetStatus;

+  USB_IO_CONTROLLER_DEVICE    *UsbIoController;

+  ENDPOINT_DESC_LIST_ENTRY    *EndpointListEntry;

+

+  //

+  // Check endpoint

+  //

+  if ((DeviceEndpoint & 0x7F) == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((DeviceEndpoint & 0x7F) > 15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EndpointListEntry = FindEndPointListEntry (

+                        This,

+                        DeviceEndpoint

+                        );

+

+  if (EndpointListEntry == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((EndpointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x03) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+  UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;

+

+  if (!IsNewTransfer) {

+    //

+    // Delete this transfer

+    //

+    UsbHCInterface->AsyncInterruptTransfer (

+                      UsbHCInterface,

+                      UsbIoDev->DeviceAddress,

+                      DeviceEndpoint,

+                      UsbIoDev->IsSlowDevice,

+                      0,

+                      FALSE,

+                      &DataToggle,

+                      PollingInterval,

+                      DataLength,

+                      NULL,

+                      NULL

+                      );

+

+    //

+    // We need to store the toggle value

+    //

+    SetDataToggleBit (

+      This,

+      DeviceEndpoint,

+      DataToggle

+      );

+

+    return EFI_SUCCESS;

+  }

+

+  GetDeviceEndPointMaxPacketLength (

+    This,

+    DeviceEndpoint,

+    &MaxPacketLength

+    );

+

+  GetDataToggleBit (

+    This,

+    DeviceEndpoint,

+    &DataToggle

+    );

+

+  RetStatus = UsbHCInterface->AsyncInterruptTransfer (

+                                UsbHCInterface,

+                                UsbIoDev->DeviceAddress,

+                                DeviceEndpoint,

+                                UsbIoDev->IsSlowDevice,

+                                MaxPacketLength,

+                                TRUE,

+                                &DataToggle,

+                                PollingInterval,

+                                DataLength,

+                                InterruptCallBack,

+                                Context

+                                );

+

+  return RetStatus;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbIsochronousTransfer (

+  IN       EFI_USB_IO_PROTOCOL     *This,

+  IN       UINT8                   DeviceEndpoint,

+  IN OUT   VOID                    *Data,

+  IN       UINTN                   DataLength,

+  OUT      UINT32                  *Status

+  )

+/*++

+

+  Routine Description:

+    Usb Isochronous Transfer

+

+  Arguments:

+    This              -   Indicates calling context.

+    DeviceEndpoint    -   The destination USB device endpoint to which the

+                          device request is being sent.

+    Data              -   A pointer to the buffer of data that will be

+                          transmitted to USB device or received from USB device.

+    DataLength        -   The size, in bytes, of the data buffer specified by

+                          Data.

+    Status            -   This parameter indicates the USB transfer status.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_OUT_OF_RESOURCES

+    EFI_TIMEOUT

+    EFI_DEVICE_ERROR

+    EFI_UNSUPPORTED

+--*/

+{

+  //

+  // Currently we don't support this transfer

+  //

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbAsyncIsochronousTransfer (

+  IN        EFI_USB_IO_PROTOCOL                 *This,

+  IN        UINT8                               DeviceEndpoint,

+  IN OUT    VOID                                *Data,

+  IN        UINTN                               DataLength,

+  IN        EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,

+  IN        VOID                                *Context OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Usb Async Isochronous Transfer

+

+Arguments:

+

+  This                - EFI_USB_IO_PROTOCOL

+  DeviceEndpoint      - DeviceEndpoint number

+  Data                - Data to transfer

+  DataLength          - DataLength

+  IsochronousCallBack - Isochronous CallBack function

+  Context             - Passed to IsochronousCallBack function

+Returns:

+

+  EFI_UNSUPPORTED     - Unsupported now

+

+--*/

+{

+  //

+  // Currently we don't support this transfer

+  //

+  return EFI_UNSUPPORTED;

+}

+//

+// Here is new definitions

+//

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetDeviceDescriptor (

+  IN  EFI_USB_IO_PROTOCOL           *This,

+  OUT EFI_USB_DEVICE_DESCRIPTOR     *DeviceDescriptor

+  )

+/*++

+

+  Routine Description:

+    Retrieves the USB Device Descriptor.

+

+  Arguments:

+    This              -   Indicates the calling context.

+    DeviceDescriptor  -   A pointer to the caller allocated USB Device

+                          Descriptor.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_NOT_FOUND

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+  USB_IO_DEVICE             *UsbIoDev;

+

+  //

+  // This function just wrapps UsbGetDeviceDescriptor.

+  //

+  

+  if (DeviceDescriptor == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+

+  if (!UsbIoDev->IsConfigured) {

+    return EFI_NOT_FOUND;

+  }

+

+  CopyMem (

+    DeviceDescriptor,

+    &UsbIoDev->DeviceDescriptor,

+    sizeof (EFI_USB_DEVICE_DESCRIPTOR)

+    );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetActiveConfigDescriptor (

+  IN  EFI_USB_IO_PROTOCOL           *This,

+  OUT EFI_USB_CONFIG_DESCRIPTOR     *ConfigurationDescriptor

+  )

+/*++

+

+  Routine Description:

+    Retrieves the current USB configuration Descriptor.

+

+  Arguments:

+    This                     -   Indicates the calling context.

+    ConfigurationDescriptor  -   A pointer to the caller allocated USB active

+                                 Configuration Descriptor.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_NOT_FOUND

+

+--*/

+{

+  USB_IO_DEVICE             *UsbIoDev;

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+

+  //

+  // This function just wrapps UsbGetActiveConfigDescriptor.

+  //

+  if (ConfigurationDescriptor == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+

+  if (!UsbIoDev->IsConfigured) {

+    return EFI_NOT_FOUND;

+  }

+

+  CopyMem (

+    ConfigurationDescriptor,

+    &(UsbIoDev->ActiveConfig->CongfigDescriptor),

+    sizeof (EFI_USB_CONFIG_DESCRIPTOR)

+    );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetInterfaceDescriptor (

+  IN  EFI_USB_IO_PROTOCOL              *This,

+  OUT EFI_USB_INTERFACE_DESCRIPTOR     *InterfaceDescriptor

+  )

+/*++

+

+  Routine Description:

+    Retrieves the interface Descriptor for that controller.

+

+  Arguments:

+    This                  -   Indicates the calling context.

+    InterfaceDescriptor   -   A pointer to the caller allocated USB interface

+                              Descriptor.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_NOT_FOUND

+

+--*/

+{

+  INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;

+

+  if (InterfaceDescriptor == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  InterfaceListEntry = FindInterfaceListEntry (This);

+

+  if (InterfaceListEntry == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  CopyMem (

+    InterfaceDescriptor,

+    &(InterfaceListEntry->InterfaceDescriptor),

+    sizeof (EFI_USB_INTERFACE_DESCRIPTOR)

+    );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetEndpointDescriptor (

+  IN  EFI_USB_IO_PROTOCOL             *This,

+  IN  UINT8                           EndpointIndex,

+  OUT EFI_USB_ENDPOINT_DESCRIPTOR     *EndpointDescriptor

+  )

+/*++

+

+  Routine Description:

+    Retrieves the endpoint Descriptor for a given endpoint.

+

+  Arguments:

+    This                  -   Indicates the calling context.

+    EndpointIndex         -   Indicates which endpoint descriptor to retrieve.

+                              The valid range is 0..15.

+    EndpointDescriptor    -   A pointer to the caller allocated USB Endpoint

+                              Descriptor of a USB controller.

+

+  Returns:

+    EFI_SUCCESS           -   The endpoint descriptor was retrieved successfully.

+    EFI_INVALID_PARAMETER -   EndpointIndex is not valid.

+                          -   EndpointDescriptor is NULL.

+    EFI_NOT_FOUND         -   The endpoint descriptor cannot be found.

+                              The device may not be correctly configured.

+

+--*/

+{

+  INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;

+  LIST_ENTRY            *EndpointListHead;

+  ENDPOINT_DESC_LIST_ENTRY  *EndpointListEntry;

+

+  if (EndpointDescriptor == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (EndpointIndex > 15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  InterfaceListEntry = FindInterfaceListEntry (This);

+

+  if (InterfaceListEntry == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  EndpointListHead  = (LIST_ENTRY *) (&InterfaceListEntry->EndpointDescListHead);

+  EndpointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointListHead->ForwardLink);

+

+  if (EndpointIndex >= InterfaceListEntry->InterfaceDescriptor.NumEndpoints) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Loop all endpoint descriptor to get match one.

+  //

+  while (EndpointIndex != 0) {

+    EndpointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointListEntry->Link.ForwardLink);

+    EndpointIndex--;

+  }

+

+  CopyMem (

+    EndpointDescriptor,

+    &EndpointListEntry->EndpointDescriptor,

+    sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)

+    );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetSupportedLanguages (

+  IN  EFI_USB_IO_PROTOCOL     *This,

+  OUT UINT16                  **LangIDTable,

+  OUT UINT16                  *TableSize

+  )

+/*++

+

+  Routine Description:

+    Get all the languages that the USB device supports

+

+  Arguments:

+    This        -   Indicates the calling context.

+    LangIDTable -   Language ID for the string the caller wants to get.

+    TableSize   -   The size, in bytes, of the table LangIDTable.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_NOT_FOUND

+

+--*/

+{

+  USB_IO_DEVICE             *UsbIoDev;

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+  UINTN                     Index;

+  BOOLEAN                   Found;

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+

+  Found           = FALSE;

+  Index           = 0;

+  //

+  // Loop language table

+  //

+  while (UsbIoDev->LangID[Index]) {

+    Found = TRUE;

+    Index++;

+  }

+

+  if (!Found) {

+    return EFI_NOT_FOUND;

+  }

+

+  *LangIDTable  = UsbIoDev->LangID;

+  *TableSize    = (UINT16) Index;

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbGetStringDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *This,

+  IN  UINT16                  LangID,

+  IN  UINT8                   StringIndex,

+  OUT CHAR16                  **String

+  )

+/*++

+

+  Routine Description:

+    Get a given string descriptor

+

+  Arguments:

+    This          -   Indicates the calling context.

+    LangID        -   The Language ID for the string being retrieved.

+    StringIndex  -   The ID of the string being retrieved.

+    String        -   A pointer to a buffer allocated by this function

+                      with AllocatePool() to store the string.  If this

+                      function returns EFI_SUCCESS, it stores the string

+                      the caller wants to get.  The caller should release

+                      the string buffer with FreePool() after the string

+                      is not used any more.

+  Returns:

+    EFI_SUCCESS

+    EFI_NOT_FOUND

+    EFI_OUT_OF_RESOURCES

+

+--*/

+{

+  UINT32                    Status;

+  EFI_STATUS                Result;

+  EFI_USB_STRING_DESCRIPTOR *StrDescriptor;

+  UINT8                     *Buffer;

+  CHAR16                    *UsbString;

+  UINT16                    TempBuffer;

+  USB_IO_DEVICE             *UsbIoDev;

+  UINT8                     Index;

+  BOOLEAN                   Found;

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+

+  if (StringIndex == 0) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Search LanguageID, check if it is supported by this device

+  //

+  if (LangID == 0) {

+    return EFI_NOT_FOUND;

+  }

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+

+  Found           = FALSE;

+  Index           = 0;

+  while (UsbIoDev->LangID[Index]) {

+    if (UsbIoDev->LangID[Index] == LangID) {

+      Found = TRUE;

+      break;

+    }

+

+    Index++;

+  }

+

+  if (!Found) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Get String Length

+  //

+  Result = UsbGetString (

+            This,

+            LangID,

+            StringIndex,

+            &TempBuffer,

+            2,

+            &Status

+            );

+  if (EFI_ERROR (Result)) {

+    return EFI_NOT_FOUND;

+  }

+

+  StrDescriptor = (EFI_USB_STRING_DESCRIPTOR *) &TempBuffer;

+

+  if (StrDescriptor->Length == 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Buffer = AllocateZeroPool (StrDescriptor->Length);

+  if (Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Result = UsbGetString (

+            This,

+            LangID,

+            StringIndex,

+            Buffer,

+            StrDescriptor->Length,

+            &Status

+            );

+

+  if (EFI_ERROR (Result)) {

+    gBS->FreePool (Buffer);

+    return EFI_NOT_FOUND;

+  }

+

+  StrDescriptor = (EFI_USB_STRING_DESCRIPTOR *) Buffer;

+

+  //

+  // UsbString is a UNICODE string

+  //

+  UsbString = AllocateZeroPool (StrDescriptor->Length);

+  if (UsbString == NULL) {

+    gBS->FreePool (Buffer);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  CopyMem (

+    (VOID *) UsbString,

+    Buffer + 2,

+    StrDescriptor->Length - 2

+    );

+

+  *String = UsbString;

+

+  gBS->FreePool (Buffer);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c
new file mode 100644
index 0000000..07eb580
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c
@@ -0,0 +1,556 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+    usbutil.c

+

+  Abstract:

+

+    Helper functions for USB

+

+  Revision History

+

+--*/

+

+#include "usbbus.h"

+

+//

+// Following APIs are used to query Port Status

+//

+BOOLEAN

+IsPortConnect (

+  IN UINT16  PortStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if there is a device connected to that port according to

+    the Port Status.

+

+  Parameters:

+    PortStatus  -   The status value of that port.

+

+  Return Value:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 0 value of PortStatus

+  //

+  if ((PortStatus & USB_PORT_STAT_CONNECTION) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortEnable (

+  IN UINT16  PortStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if Port is enabled.

+

+  Arguments:

+    PortStatus  -   The status value of that port.

+

+  Returns:

+    TRUE  - Port is enable

+    FALSE - Port is disable

+

+--*/

+{

+  //

+  // return the bit 1 value of PortStatus

+  //

+  if ((PortStatus & USB_PORT_STAT_ENABLE) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortInReset (

+  IN UINT16  PortStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if the port is being reset.

+

+  Arguments:

+    PortStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 4 value of PortStatus

+  //

+  if ((PortStatus & USB_PORT_STAT_RESET) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortPowerApplied (

+  IN UINT16  PortStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if there is power applied to that port.

+

+  Arguments:

+    PortStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 8 value of PortStatus

+  //

+  if ((PortStatus & USB_PORT_STAT_POWER) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortLowSpeedDeviceAttached (

+  IN UINT16  PortStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if the connected device is a low device.

+

+  Arguments:

+    PortStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 9 value of PortStatus

+  //

+  if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortSuspend (

+  IN UINT16  PortStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if the port is suspend.

+

+  Arguments:

+    PortStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 2 value of PortStatus

+  //

+  if ((PortStatus & USB_PORT_STAT_SUSPEND) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+//

+// Following APIs are used to query Port Change Status

+//

+BOOLEAN

+IsPortConnectChange (

+  IN UINT16  PortChangeStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if there is a Connect Change status in that port.

+

+  Arguments:

+    PortChangeStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 0 value of PortChangeStatus

+  //

+  if ((PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortEnableDisableChange (

+  IN UINT16  PortChangeStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if there is a Enable/Disable change in that port.

+

+  Arguments:

+    PortChangeStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 1 value of PortChangeStatus

+  //

+  if ((PortChangeStatus & USB_PORT_STAT_C_ENABLE) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsPortResetChange (

+  IN UINT16  PortChangeStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if there is a Port Reset Change status in that port.

+

+  Arguments:

+    PortChangeStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 4 value of PortChangeStatus

+  //

+  if ((PortChangeStatus & USB_PORT_STAT_C_RESET) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+

+BOOLEAN

+IsPortSuspendChange (

+  IN UINT16  PortChangeStatus

+  )

+/*++

+

+  Routine Description:

+    Tell if there is a Suspend Change Status in that port.

+

+  Arguments:

+    PortChangeStatus  -   The status value of that port.

+

+  Returns:

+    TRUE

+    FALSE

+

+--*/

+{

+  //

+  // return the bit 2 value of PortChangeStatus

+  //

+  if ((PortChangeStatus & USB_PORT_STAT_C_SUSPEND) != 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+

+INTERFACE_DESC_LIST_ENTRY* 

+FindInterfaceListEntry (

+  IN EFI_USB_IO_PROTOCOL    *This

+  )

+/*++

+

+  Routine Description:

+    Find Interface ListEntry.

+

+  Arguments:

+    This         -  EFI_USB_IO_PROTOCOL   

+  

+  Returns:

+    INTERFACE_DESC_LIST_ENTRY pointer

+

+--*/

+{

+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;

+  USB_IO_DEVICE             *UsbIoDev;

+  LIST_ENTRY            *InterfaceListHead;

+  INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;

+

+  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);

+  UsbIoDev        = UsbIoController->UsbDevice;

+

+  if (!UsbIoDev->IsConfigured) {

+    return NULL;

+  }

+

+  InterfaceListHead   = &UsbIoDev->ActiveConfig->InterfaceDescListHead;

+  InterfaceListEntry  = (INTERFACE_DESC_LIST_ENTRY *) (InterfaceListHead->ForwardLink);

+

+  //

+  // Loop all interface descriptor to get match one.

+  //

+  while (InterfaceListEntry != (INTERFACE_DESC_LIST_ENTRY *) InterfaceListHead) {

+    if (InterfaceListEntry->InterfaceDescriptor.InterfaceNumber == UsbIoController->InterfaceNumber) {

+      return InterfaceListEntry;

+    }

+

+    InterfaceListEntry = (INTERFACE_DESC_LIST_ENTRY *) InterfaceListEntry->Link.ForwardLink;

+  }

+

+  return NULL;

+}

+

+ENDPOINT_DESC_LIST_ENTRY* 

+FindEndPointListEntry (

+  IN EFI_USB_IO_PROTOCOL    *This,

+  IN UINT8                  EndPointAddress

+  )

+/*++

+

+  Routine Description:

+    Find EndPoint ListEntry.

+

+  Arguments:

+    This         -  EFI_USB_IO_PROTOCOL   

+    EndpointAddr -  Endpoint address.

+ 

+  Returns:

+    ENDPOINT_DESC_LIST_ENTRY pointer

+

+--*/

+{

+  INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;

+  LIST_ENTRY                *EndpointDescListHead;

+  ENDPOINT_DESC_LIST_ENTRY  *EndPointListEntry;

+

+  InterfaceListEntry = FindInterfaceListEntry (This);

+  if (InterfaceListEntry != NULL) {

+    EndpointDescListHead  = &InterfaceListEntry->EndpointDescListHead;

+    EndPointListEntry     = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointDescListHead->ForwardLink);

+

+    //

+    // Loop all interface descriptor to get match one.

+    //

+    while (EndPointListEntry != (ENDPOINT_DESC_LIST_ENTRY *) EndpointDescListHead) {

+      if (EndPointListEntry->EndpointDescriptor.EndpointAddress == EndPointAddress) {

+        return EndPointListEntry;

+      }

+

+      EndPointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) EndPointListEntry->Link.ForwardLink;

+    }

+  }

+

+  return NULL;

+}

+

+VOID

+GetDataToggleBit (

+  IN EFI_USB_IO_PROTOCOL    *UsbIo,

+  IN  UINT8                 EndpointAddr,

+  OUT UINT8                 *DataToggle

+  )

+/*++

+

+  Routine Description:

+    Get the datatoggle of a specified endpoint.

+

+  Arguments:

+    UsbIo         -     Given Usb Controller device.

+    EndpointAddr  -     Given Endpoint address.

+    DataToggle    -     The current data toggle of that endpoint

+

+  Returns:

+    N/A

+

+--*/

+{

+

+  ENDPOINT_DESC_LIST_ENTRY  *EndpointListEntry;

+

+  *DataToggle       = 0;

+

+  EndpointListEntry = FindEndPointListEntry (UsbIo, EndpointAddr);

+  if (EndpointListEntry == NULL) {

+    return ;

+  }

+

+  *DataToggle = (UINT8) (EndpointListEntry->Toggle);

+  return ;

+}

+

+VOID

+SetDataToggleBit (

+  IN EFI_USB_IO_PROTOCOL    *UsbIo,

+  IN UINT8                  EndpointAddr,

+  IN UINT8                  DataToggle

+  )

+/*++

+

+  Routine Description:

+    Set the datatoggle of a specified endpoint

+

+  Arguments:

+    UsbIo         -     Given Usb Controller device.

+    EndpointAddr  -     Given Endpoint address.

+    DataToggle    -     The current data toggle of that endpoint to be set

+

+  Returns:

+    N/A

+

+--*/

+{

+

+  ENDPOINT_DESC_LIST_ENTRY  *EndpointListEntry;

+

+  EndpointListEntry = FindEndPointListEntry (UsbIo, EndpointAddr);

+  if (EndpointListEntry == NULL) {

+    return ;

+  }

+

+  EndpointListEntry->Toggle = DataToggle;

+  return ;

+}

+

+VOID

+GetDeviceEndPointMaxPacketLength (

+  IN  EFI_USB_IO_PROTOCOL    *UsbIo,

+  IN  UINT8                  EndpointAddr,

+  OUT UINT8                  *MaxPacketLength

+  )

+/*++

+

+  Routine Description:

+    Get the Max Packet Length of the speified Endpoint.

+

+  Arguments:

+    UsbIo           -     Given Usb Controller device.

+    EndpointAddr    -     Given Endpoint address.

+    MaxPacketLength -     The max packet length of that endpoint

+

+  Returns:

+    N/A

+

+--*/

+{

+

+  ENDPOINT_DESC_LIST_ENTRY  *EndpointListEntry;

+

+  *MaxPacketLength  = 0;

+

+  EndpointListEntry = FindEndPointListEntry (UsbIo, EndpointAddr);

+  if (EndpointListEntry == NULL) {

+    return ;

+  }

+

+  *MaxPacketLength = (UINT8) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);

+

+  return ;

+}

+

+

+EFI_STATUS

+UsbSetDeviceAddress (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  AddressValue,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Set Device Address

+

+Arguments:

+

+  UsbIo         - EFI_USB_IO_PROTOCOL

+  AddressValue  - Device address 

+  Status        - Transfer status

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_ADDRESS_REQ_TYPE;

+  DevReq.Request      = USB_DEV_SET_ADDRESS;

+  DevReq.Value        = AddressValue;

+ 

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  TIMEOUT_VALUE,

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.h b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.h
new file mode 100644
index 0000000..259276c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.h
@@ -0,0 +1,94 @@
+/*++

+ 

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+    usbutil.h

+  

+  Abstract:

+ 

+    Helper functions for USB

+ 

+  Revision History

+ 

+  

+--*/

+

+#ifndef _USB_UTIL_H

+#define _USB_UTIL_H

+

+//

+// Following APIs are used to query Port Status

+//

+BOOLEAN

+IsPortConnect (

+  IN UINT16  PortStatus

+  );

+

+BOOLEAN

+IsPortEnable (

+  IN UINT16  PortStatus

+  );

+

+BOOLEAN

+IsPortInReset (

+  IN UINT16  PortStatus

+  );

+

+BOOLEAN

+IsPortPowerApplied (

+  IN UINT16  PortStatus

+  );

+

+BOOLEAN

+IsPortLowSpeedDeviceAttached (

+  IN UINT16  PortStatus

+  );

+

+BOOLEAN

+IsPortSuspend (

+  IN UINT16  PortStatus

+  );

+

+//

+// Following APIs are used to query Port Change Status

+//

+BOOLEAN

+IsPortConnectChange (

+  IN UINT16  PortChangeStatus

+  );

+

+BOOLEAN

+IsPortEnableDisableChange (

+  IN UINT16  PortChangeStatus

+  );

+

+BOOLEAN

+IsPortResetChange (

+  IN UINT16  PortChangeStatus

+  );

+

+BOOLEAN

+IsPortSuspendChange (

+  IN UINT16  PortChangeStatus

+  );

+

+//

+// Set device address;

+//

+EFI_STATUS

+UsbSetDeviceAddress (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  AddressValue,

+  OUT UINT32                  *Status

+  );

+

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/Cbi0.c b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/Cbi0.c
new file mode 100644
index 0000000..5bd8728
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/Cbi0.c
@@ -0,0 +1,1042 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Cbi0.c

+

+Abstract:

+

+--*/

+

+#include "../cbi.h"

+

+extern EFI_COMPONENT_NAME_PROTOCOL  gUsbCbi0ComponentName;

+//

+// Function prototypes

+//

+EFI_STATUS

+EFIAPI

+UsbCbi0DriverEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+//

+// Bot Driver Binding Protocol

+//

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0DriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0DriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0DriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+VOID

+Cbi0ReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  );

+

+

+EFI_DRIVER_BINDING_PROTOCOL         gUsbCbi0DriverBinding = {

+  Cbi0DriverBindingSupported,

+  Cbi0DriverBindingStart,

+  Cbi0DriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+STATIC

+EFI_STATUS

+Cbi0RecoveryReset (

+  IN  USB_CBI_DEVICE   *UsbCbiDev

+  );

+

+STATIC

+EFI_STATUS

+Cbi0CommandPhase (

+  IN  USB_CBI_DEVICE            *UsbCbiDev,

+  IN  VOID                      *Command,

+  IN  UINT8                     CommandSize,

+  IN  UINT16                    Timeout

+  );

+

+STATIC

+EFI_STATUS

+Cbi0DataPhase (

+  IN     USB_CBI_DEVICE            *UsbCbiDev,

+  IN     UINT32                    *DataSize,

+  IN OUT VOID                      *DataBuffer,

+  IN     EFI_USB_DATA_DIRECTION    Direction,

+  IN     UINT16                    Timeout

+  );

+

+STATIC

+EFI_STATUS

+Cbi0StatusPhase (

+  IN  USB_CBI_DEVICE        *UsbCbiDev,

+  OUT INTERRUPT_DATA_BLOCK  *InterruptDataBlock,

+  IN  UINT16                Timeout

+  );

+

+//

+// USB Atapi protocol prototype

+//

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0AtapiCommand (

+  IN  EFI_USB_ATAPI_PROTOCOL    *This,

+  IN  VOID                      *Command,

+  IN  UINT8                     CommandSize,

+  IN  VOID                      *DataBuffer,

+  IN  UINT32                    BufferLength,

+  IN  EFI_USB_DATA_DIRECTION    Direction,

+  IN  UINT16                    TimeOutInMilliSeconds

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0MassStorageReset (

+  IN  EFI_USB_ATAPI_PROTOCOL    *This,

+  IN  BOOLEAN                   ExtendedVerification

+  );

+

+STATIC EFI_USB_ATAPI_PROTOCOL       Cbi0AtapiProtocol = {

+  Cbi0AtapiCommand,

+  Cbi0MassStorageReset,

+  0

+};

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0DriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    than contains a BlockIo and DiskIo protocol can be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device

+    EFI_ALREADY_STARTED - This driver is already running on this device

+    other               - This driver does not support this device

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+

+  //

+  // Check if the Controller supports USB IO protocol

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the Default interface descriptor, now we only

+  // suppose interface 1

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return Status;

+  }

+  //

+  // Check if it is a Cbi0 Type Mass Storage Device

+  //

+  if((InterfaceDescriptor.InterfaceClass != MASS_STORAGE_CLASS) ||

+     (InterfaceDescriptor.InterfaceProtocol != CBI0_INTERFACE_PROTOCOL)) {

+    Status = EFI_UNSUPPORTED;

+  } else {

+    Status = EFI_SUCCESS;

+  }

+

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0DriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Start this driver on ControllerHandle by opening a Block IO and Disk IO

+    protocol, reading Device Path, and creating a child handle with a

+    Disk IO and device path protocol.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to bind driver to

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver is added to DeviceHandle

+    EFI_ALREADY_STARTED - This driver is already running on DeviceHandle

+    other               - This driver does not support this device

+    EFI_OUT_OF_RESOURCES- Can't allocate memory 

+    EFI_UNSUPPORTED     - Endpoint is not as expected

+--*/

+{

+  USB_CBI_DEVICE                *UsbCbiDev;

+  UINT8                         Index;

+  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  UINT8                         EndpointExistMask;

+

+  //

+  // Check if the Controller supports USB IO protocol

+  //

+  UsbCbiDev = NULL;

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the controller interface descriptor

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return Status;

+  }

+

+  Cbi0AtapiProtocol.CommandProtocol = InterfaceDescriptor.InterfaceSubClass;

+

+  UsbCbiDev                         = AllocateZeroPool (sizeof (USB_CBI_DEVICE));

+  if (UsbCbiDev == NULL) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  UsbCbiDev->Signature            = USB_CBI_DEVICE_SIGNATURE;

+  UsbCbiDev->UsbIo                = UsbIo;

+  CopyMem (&UsbCbiDev->InterfaceDescriptor, &InterfaceDescriptor, sizeof (InterfaceDescriptor));

+  CopyMem (&UsbCbiDev->UsbAtapiProtocol, &Cbi0AtapiProtocol, sizeof (Cbi0AtapiProtocol));

+

+  //

+  // Get the Device Path Protocol on Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &UsbCbiDev->DevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    if (UsbCbiDev != NULL) {

+      gBS->FreePool (UsbCbiDev);

+    }

+

+    return Status;

+  }

+  //

+  // Mask used to see whether all three kinds of endpoints exist,

+  // Mask value:

+  //  bit0: bulk in endpoint;

+  //  bit1: bulk out endpoint;

+  //  bit2: interrupt in endpoint;

+  //

+  EndpointExistMask = 0;

+  for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {

+    UsbIo->UsbGetEndpointDescriptor (

+            UsbIo,

+            Index,

+            &EndpointDescriptor

+            );

+

+    //

+    // We parse bulk endpoint

+    //

+    if (EndpointDescriptor.Attributes == 0x02) {

+      if (EndpointDescriptor.EndpointAddress & 0x80) {

+        CopyMem (&UsbCbiDev->BulkInEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));

+	 // UsbCbiDev->BulkInEndpointDescriptor = EndpointDescriptor;

+        EndpointExistMask |= bit (0);

+      } else {

+        CopyMem (&UsbCbiDev->BulkOutEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));

+	 // UsbCbiDev->BulkOutEndpointDescriptor = EndpointDescriptor;

+        EndpointExistMask |= bit (1);

+      }

+    }

+    //

+    // We parse interrupt endpoint

+    //

+    if (EndpointDescriptor.Attributes == 0x03) {

+      CopyMem (&UsbCbiDev->InterruptEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));

+      // UsbCbiDev->InterruptEndpointDescriptor = EndpointDescriptor;

+      EndpointExistMask |= bit (2);

+    }

+

+  }

+  //

+  // Double check we have all endpoints needed

+  //

+  if (EndpointExistMask != (bit (0) | bit (1) | bit (2))) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    if (UsbCbiDev != NULL) {

+      gBS->FreePool (UsbCbiDev);

+    }

+

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // After installing Usb-Atapi protocol onto this handle

+  // it will be called by upper layer drivers such as Fat

+  //

+  Cbi0ReportStatusCode (

+    UsbCbiDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)

+    );

+

+  Status = gBS->InstallProtocolInterface (

+                  &ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &UsbCbiDev->UsbAtapiProtocol

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    if (UsbCbiDev != NULL) {

+      gBS->FreePool (UsbCbiDev);

+    }

+

+    return Status;

+  }

+

+  UsbCbiDev->ControllerNameTable = NULL;

+  AddUnicodeString (

+    "eng",

+    gUsbCbi0ComponentName.SupportedLanguages,

+    &UsbCbiDev->ControllerNameTable,

+    (CHAR16 *) L"Usb Cbi0 Mass Storage"

+    );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0DriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    ControllerHandle - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS         - This driver is removed DeviceHandle

+    EFI_UNSUPPORTED     - This driver was not removed from this device

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_USB_ATAPI_PROTOCOL  *Cbi0AtapiProtocol;

+  USB_CBI_DEVICE          *UsbCbiDev;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  (VOID **) &Cbi0AtapiProtocol,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (Cbi0AtapiProtocol);

+

+  UsbIo     = UsbCbiDev->UsbIo;

+

+  Cbi0ReportStatusCode (

+    UsbCbiDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)

+    );

+

+  //

+  // Uninstall protocol

+  //

+  Status = gBS->UninstallProtocolInterface (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  &UsbCbiDev->UsbAtapiProtocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->CloseProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  This->DriverBindingHandle,

+                  ControllerHandle

+                  );

+  //

+  // Free all allocated resources

+  //

+  if (UsbCbiDev->ControllerNameTable) {

+    FreeUnicodeStringTable (UsbCbiDev->ControllerNameTable);

+  }

+

+  gBS->FreePool (UsbCbiDev);

+

+  return Status;

+}

+

+

+STATIC

+EFI_STATUS

+Cbi0RecoveryReset (

+  IN  USB_CBI_DEVICE   *UsbCbiDev

+  )

+/*++

+

+Routine Description:

+

+  Cbi0 Recovery Reset routine

+

+Arguments:

+

+  UsbCbiDev - Cbi0RecoveryReset

+

+Returns:

+

+  EFI_SUCCESS - Success

+

+--*/

+{

+  UINT8               ResetCommand[12];

+  EFI_STATUS          Status;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               EndpointAddress;

+  UINT32              Result;

+  UINT16              Timeout;

+

+  UsbIo = UsbCbiDev->UsbIo;

+

+  Cbi0ReportStatusCode (

+    UsbCbiDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)

+    );

+  //

+  // CBI reset command protocol

+  //

+  SetMem (ResetCommand, sizeof (ResetCommand), 0xff);

+  ResetCommand[0] = 0x1d;

+  ResetCommand[1] = 0x04;

+

+  //

+  // (in millisecond unit)

+  //

+  Timeout = STALL_1_SECOND;

+

+  Status = Cbi0AtapiCommand (

+            &UsbCbiDev->UsbAtapiProtocol,

+            ResetCommand,

+            12,

+            NULL,

+            0,

+            EfiUsbNoData,

+            Timeout

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->Stall (100 * 1000);

+  //

+  // clear bulk in endpoint stall feature

+  //

+  EndpointAddress = UsbCbiDev->BulkInEndpointDescriptor.EndpointAddress;

+  Status = UsbClearEndpointHalt (

+            UsbIo,

+            EndpointAddress,

+            &Result

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // clear bulk out endpoint stall feature

+  //

+  EndpointAddress = UsbCbiDev->BulkOutEndpointDescriptor.EndpointAddress;

+  Status = UsbClearEndpointHalt (

+            UsbIo,

+            EndpointAddress,

+            &Result

+            );

+  //

+  // according to CBI spec, no need to clear interrupt endpoint feature.

+  //

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+Cbi0CommandPhase (

+  IN  USB_CBI_DEVICE          *UsbCbiDev,

+  IN  VOID                    *Command,

+  IN  UINT8                   CommandSize,

+  IN  UINT16                  Timeout

+  )

+/*++

+

+  Routine Description:

+    Send ATAPI command through CBI0 interface.

+

+  Arguments:

+    UsbCbiDev   - USB_CBI_DEVICE

+    Command     - Command to send

+    CommandSize - Command size

+    Timeout     - Time out value in milliseconds

+  Returns:

+    EFI_SUCCESS      - Success

+    EFI_DEVICE_ERROR - Fail

+    Others

+

+--*/

+{

+  EFI_STATUS              Status;

+  UINT32                  Result;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  UsbIo = UsbCbiDev->UsbIo;

+

+  ZeroMem (&Request, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Device request see CBI specification

+  //

+  Request.RequestType = 0x21;

+  Request.Request     = 0x00;

+  Request.Value       = 0;

+  Request.Index       = 0;

+  Request.Length      = CommandSize;

+

+  Status = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataOut,

+                    Timeout,

+                    Command,

+                    CommandSize,

+                    &Result

+                    );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+Cbi0DataPhase (

+  IN      USB_CBI_DEVICE             *UsbCbiDev,

+  IN      UINT32                     *DataSize,

+  IN  OUT VOID                       *DataBuffer,

+  IN      EFI_USB_DATA_DIRECTION     Direction,

+  IN      UINT16                     Timeout

+  )

+/*++

+

+  Routine Description:

+    Get/Send Data through CBI0 interface

+

+  Arguments:

+    UsbCbiDev   - USB_CBI_DEVICE

+    DataSize    - Data size

+    DataBuffer  - Data buffer

+    Direction   - IN/OUT/NODATA

+    Timeout     - Time out value in milliseconds

+  Returns:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               EndpointAddress;

+  UINTN               Remain;

+  UINTN               Increment;

+  UINT32              MaxPacketLength;

+  UINT8               *BufferPtr;

+  UINT32              Result;

+  UINTN               TransferredSize;

+

+  UsbIo           = UsbCbiDev->UsbIo;

+

+  Remain          = *DataSize;

+  BufferPtr       = (UINT8 *) DataBuffer;

+  TransferredSize = 0;

+  //

+  // retrieve the the max packet length of the given endpoint

+  //

+  if (Direction == EfiUsbDataIn) {

+    MaxPacketLength = UsbCbiDev->BulkInEndpointDescriptor.MaxPacketSize;

+    EndpointAddress = UsbCbiDev->BulkInEndpointDescriptor.EndpointAddress;

+  } else {

+    MaxPacketLength = UsbCbiDev->BulkOutEndpointDescriptor.MaxPacketSize;

+    EndpointAddress = UsbCbiDev->BulkOutEndpointDescriptor.EndpointAddress;

+  }

+

+  while (Remain > 0) {

+

+    if (Remain > 16 * MaxPacketLength) {

+      Increment = 16 * MaxPacketLength;

+    } else {

+      Increment = Remain;

+    }

+

+    Status = UsbIo->UsbBulkTransfer (

+                      UsbIo,

+                      EndpointAddress,

+                      BufferPtr,

+                      &Increment,

+                      Timeout,

+                      &Result

+                      );

+    TransferredSize += Increment;

+

+    if (EFI_ERROR (Status)) {

+      goto ErrorExit;

+    }

+

+    BufferPtr += Increment;

+    Remain -= Increment;

+  }

+

+  return EFI_SUCCESS;

+

+ErrorExit:

+

+  if (Direction == EfiUsbDataIn) {

+    Cbi0ReportStatusCode (

+      UsbCbiDev->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)

+      );

+  } else {

+    Cbi0ReportStatusCode (

+      UsbCbiDev->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)

+      );

+  }

+

+  if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+    Status = Cbi0RecoveryReset (UsbCbiDev);

+  }

+

+  *DataSize = (UINT32) TransferredSize;

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+Cbi0StatusPhase (

+  IN  USB_CBI_DEVICE        *UsbCbiDev,

+  OUT INTERRUPT_DATA_BLOCK  *InterruptDataBlock,

+  IN  UINT16                Timeout

+  )

+/*++

+

+  Routine Description:

+    Get transfer status through BOT interface

+

+  Arguments:

+    UsbCbiDev           -  USB_CBI_DEVICE

+    InterruptDataBlock  -  Interrupt Data Block for interrupt transfer

+    Timeout             -  Time out value in milliseconds  

+  Returns:

+    EFI_SUCCESS

+    Others

+

+--*/

+{

+  UINT8       EndpointAddress;

+  UINTN       InterruptDataBlockLength;

+  UINT32      Result;

+  EFI_STATUS  Status;

+

+  ZeroMem (InterruptDataBlock, sizeof (INTERRUPT_DATA_BLOCK));

+

+  EndpointAddress           = UsbCbiDev->InterruptEndpointDescriptor.EndpointAddress;

+  InterruptDataBlockLength  = sizeof (INTERRUPT_DATA_BLOCK);

+

+  Status = UsbCbiDev->UsbIo->UsbSyncInterruptTransfer (

+                              UsbCbiDev->UsbIo,

+                              EndpointAddress,

+                              InterruptDataBlock,

+                              &InterruptDataBlockLength,

+                              Timeout,

+                              &Result

+                              );

+  if (EFI_ERROR (Status)) {

+    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+      //

+      // just endpoint stall happens

+      //

+      UsbClearEndpointHalt (

+        UsbCbiDev->UsbIo,

+        EndpointAddress,

+        &Result

+        );

+      gBS->Stall (100 * 1000);

+    }

+

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// Cbi0 Atapi Protocol Implementation

+//

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0MassStorageReset (

+  IN  EFI_USB_ATAPI_PROTOCOL      *This,

+  IN  BOOLEAN                     ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset CBI Devices

+    

+  Arguments:

+    This                    - Protocol instance pointer.

+    ExtendedVerification    - TRUE if we need to do strictly reset.

+

+  Returns:

+    EFI_SUCCESS         - Command succeeded.

+    EFI_DEVICE_ERROR    - Command failed.

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  USB_CBI_DEVICE      *UsbCbiDev;

+

+  UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);

+  UsbIo     = UsbCbiDev->UsbIo;

+

+  if (ExtendedVerification) {

+    //

+    //    UsbIo->UsbPortReset (UsbIo);

+    //

+  }

+

+  Status = Cbi0RecoveryReset (UsbCbiDev);

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+Cbi0AtapiCommand (

+  IN  EFI_USB_ATAPI_PROTOCOL      *This,

+  IN  VOID                        *Command,

+  IN  UINT8                       CommandSize,

+  IN  VOID                        *DataBuffer,

+  IN  UINT32                      BufferLength,

+  IN  EFI_USB_DATA_DIRECTION      Direction,

+  IN  UINT16                      TimeOutInMilliSeconds

+  )

+/*++

+

+  Routine Description:

+    Send ATAPI command using BOT protocol.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    Command               - Command buffer

+    CommandSize           - Size of Command Buffer

+    DataBuffer            - Data buffer

+    BufferLength          - Length of Data buffer

+    Direction             - Data direction of this command

+    TimeOutInMilliSeconds - Timeout value in ms

+

+  Returns:

+    EFI_SUCCESS           - Command succeeded.

+    EFI_DEVICE_ERROR      - Command failed.

+    EFI_INVALID_PARAMETER - Invalidate parameter 

+--*/

+{

+  EFI_STATUS            Status;

+  USB_CBI_DEVICE        *UsbCbiDev;

+  UINT32                BufferSize;

+  INTERRUPT_DATA_BLOCK  InterruptDataBlock;

+  EFI_STATUS            DataPhaseStatus;

+

+  if (Direction != EfiUsbNoData) {

+    if (DataBuffer == NULL || BufferLength == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  DataPhaseStatus = EFI_SUCCESS;

+  //

+  // Get the context

+  //

+  UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);

+

+  //

+  // First send ATAPI command through Cbi

+  //

+  Status = Cbi0CommandPhase (

+            UsbCbiDev,

+            Command,

+            CommandSize,

+            TimeOutInMilliSeconds

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Send/Get Data if there is a Data Stage

+  //

+  switch (Direction) {

+

+  case EfiUsbDataIn:

+  case EfiUsbDataOut:

+    BufferSize = BufferLength;

+

+    DataPhaseStatus = Cbi0DataPhase (

+                        UsbCbiDev,

+                        &BufferSize,

+                        DataBuffer,

+                        Direction,

+                        TimeOutInMilliSeconds

+                        );

+    break;

+

+  case EfiUsbNoData:

+    break;

+  }

+

+  if (EFI_ERROR (DataPhaseStatus)) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // Status Phase

+  //

+  Status = Cbi0StatusPhase (

+            UsbCbiDev,

+            &InterruptDataBlock,

+            TimeOutInMilliSeconds

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (This->CommandProtocol != EFI_USB_SUBCLASS_UFI) {

+

+    if (InterruptDataBlock.bType == 0) {

+      //

+      // indicates command completion

+      //

+      switch (InterruptDataBlock.bValue & 0x03) {

+

+      case 0:

+        Status = EFI_SUCCESS;

+        break;

+

+      case 1:

+        Status = EFI_DEVICE_ERROR;

+        break;

+

+      case 2:

+        Status = Cbi0RecoveryReset (UsbCbiDev);

+        if (EFI_ERROR (Status)) {

+          UsbCbiDev->UsbIo->UsbPortReset (UsbCbiDev->UsbIo);

+        }

+

+        Status = EFI_DEVICE_ERROR;

+        break;

+

+      case 3:

+        Status = EFI_DEVICE_ERROR;

+      }

+    } else {

+      Status = DataPhaseStatus;

+    }

+

+  } else {

+    //

+    // UFI device, InterruptDataBlock.bType: ASC (Additional Sense Code)

+    //             InterruptDataBlock.bValue: ASCQ (Additional Snese Code Qualifier)

+    //

+    Status = DataPhaseStatus;

+  }

+

+  return Status;

+}

+

+VOID

+Cbi0ReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  )

+/*++

+

+  Routine Description:

+    Report Status Code in Usb Cbi0 Driver

+

+  Arguments:

+    DevicePath   - Use this to get Device Path

+    CodeType     - Status Code Type

+    CodeValue    - Status Code Value

+

+  Returns:

+    None

+

+--*/

+{

+

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    CodeType,

+    Value,

+    DevicePath

+    );

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/ComponentName.c b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/ComponentName.c
new file mode 100644
index 0000000..0692c7f
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/ComponentName.c
@@ -0,0 +1,192 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "../cbi.h"

+

+extern EFI_DRIVER_BINDING_PROTOCOL  gUsbCbi0DriverBinding;

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UsbCbi0ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UsbCbi0ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL         gUsbCbi0ComponentName = {

+  UsbCbi0ComponentNameGetDriverName,

+  UsbCbi0ComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE     mUsbCbi0DriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Usb Cbi0 Mass Storage Driver" },

+  { NULL , NULL }

+};

+

+

+EFI_STATUS

+EFIAPI

+UsbCbi0ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUsbCbi0ComponentName.SupportedLanguages,

+          mUsbCbi0DriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UsbCbi0ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS              Status;

+  USB_CBI_DEVICE          *UsbCbiDev;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapi;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the device context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  (VOID **) &UsbAtapi,

+                  gUsbCbi0DriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (UsbAtapi);

+

+  return LookupUnicodeString (

+          Language,

+          gUsbCbi0ComponentName.SupportedLanguages,

+          UsbCbiDev->ControllerNameTable,

+          ControllerName

+          );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.mbd
new file mode 100644
index 0000000..17a63f9
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbCbi0</BaseName>

+    <Guid>A3527D16-E6CC-42f5-BADB-BF3DE177742B</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.msa b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.msa
new file mode 100644
index 0000000..0abe2e2
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbCbi0</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>A3527D16-E6CC-42f5-BADB-BF3DE177742B</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbCbi1 module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Cbi0.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">UsbIo</Protocol>

+    <Protocol Usage="BY_START">UsbAtapi</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUsbCbi0DriverBinding</DriverBinding>

+      <ComponentName>gUsbCbi0ComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/build.xml
new file mode 100644
index 0000000..7ffd6f1
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi0/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbCbi0"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbCbi/Dxe/Cbi0"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbCbi0">

+      <GenBuild baseName="UsbCbi0" mbdFilename="${MODULE_DIR}/UsbCbi0.mbd" msaFilename="${MODULE_DIR}/UsbCbi0.msa"/>

+   </target>

+   <target depends="UsbCbi0_clean" name="clean"/>

+   <target depends="UsbCbi0_cleanall" name="cleanall"/>

+   <target name="UsbCbi0_clean">

+      <OutputDirSetup baseName="UsbCbi0" mbdFilename="${MODULE_DIR}/UsbCbi0.mbd" msaFilename="${MODULE_DIR}/UsbCbi0.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbCbi0_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbCbi0_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbCbi0_cleanall">

+      <OutputDirSetup baseName="UsbCbi0" mbdFilename="${MODULE_DIR}/UsbCbi0.mbd" msaFilename="${MODULE_DIR}/UsbCbi0.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbCbi0_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbCbi0_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbCbi0*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.mbd
new file mode 100644
index 0000000..e48251e
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbCbi1</BaseName>

+    <Guid>B40612B2-A063-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.msa b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.msa
new file mode 100644
index 0000000..05e8c00
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.msa
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbCbi1</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>B40612B2-A063-11d4-9A3A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbCbi1 module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>cbi1.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">UsbIo</Protocol>

+    <Protocol Usage="BY_START">UsbAtapi</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gCBI1DriverBinding</DriverBinding>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/build.xml
new file mode 100644
index 0000000..129dab1
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbCbi1"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbCbi/Dxe/Cbi1"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbCbi1">

+      <GenBuild baseName="UsbCbi1" mbdFilename="${MODULE_DIR}/UsbCbi1.mbd" msaFilename="${MODULE_DIR}/UsbCbi1.msa"/>

+   </target>

+   <target depends="UsbCbi1_clean" name="clean"/>

+   <target depends="UsbCbi1_cleanall" name="cleanall"/>

+   <target name="UsbCbi1_clean">

+      <OutputDirSetup baseName="UsbCbi1" mbdFilename="${MODULE_DIR}/UsbCbi1.mbd" msaFilename="${MODULE_DIR}/UsbCbi1.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbCbi1_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbCbi1_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbCbi1_cleanall">

+      <OutputDirSetup baseName="UsbCbi1" mbdFilename="${MODULE_DIR}/UsbCbi1.mbd" msaFilename="${MODULE_DIR}/UsbCbi1.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbCbi1_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbCbi1_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbCbi1*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/cbi1.c b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/cbi1.c
new file mode 100644
index 0000000..71644ac
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/cbi1.c
@@ -0,0 +1,854 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  cbi1.c

+

+Abstract:

+    cbi1 transportation protocol implementation files

+

+--*/

+

+#include "../cbi.h"

+

+EFI_STATUS

+EFIAPI

+UsbCBI1DriverEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+//

+// CBI Function prototypes

+//

+STATIC

+EFI_STATUS

+CBI1CommandPhase (

+  IN  USB_CBI_DEVICE          *UsbCbiDev,

+  IN  VOID                    *Command,

+  IN  UINT8                   CommandSize,

+  OUT UINT32                  *Result

+  );

+

+STATIC

+EFI_STATUS

+CBI1DataPhase (

+  IN  USB_CBI_DEVICE          *UsbCbiDev,

+  IN  UINT32                  DataSize,

+  IN  OUT VOID                *DataBuffer,

+  IN  EFI_USB_DATA_DIRECTION  Direction,

+  IN  UINT16                  Timeout,

+  OUT UINT32                  *Result

+  );

+

+//

+// USB Atapi implementation

+//

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1AtapiCommand (

+  IN  EFI_USB_ATAPI_PROTOCOL    *This,

+  IN  VOID                      *Command,

+  IN  UINT8                     CommandSize,

+  IN  VOID                      *DataBuffer,

+  IN  UINT32                    BufferLength,

+  IN  EFI_USB_DATA_DIRECTION    Direction,

+  IN  UINT16                    TimeOutInMilliSeconds

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1MassStorageReset (

+  IN  EFI_USB_ATAPI_PROTOCOL      *This,

+  IN  BOOLEAN                     ExtendedVerification

+  );

+

+//

+// CBI1 Driver Binding Protocol

+//

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1DriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1DriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1DriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+VOID

+Cbi1ReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  );

+

+

+EFI_DRIVER_BINDING_PROTOCOL   gCBI1DriverBinding = {

+  CBI1DriverBindingSupported,

+  CBI1DriverBindingStart,

+  CBI1DriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+STATIC EFI_USB_ATAPI_PROTOCOL CBI1AtapiProtocol = {

+  CBI1AtapiCommand,

+  CBI1MassStorageReset,

+  0

+};

+

+//

+// CBI1 Driver Binding implementation

+//

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1DriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle 

+    than contains a BlockIo and DiskIo protocol can be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device

+    EFI_ALREADY_STARTED - This driver is already running on this device

+    other               - This driver does not support this device

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+

+  //

+  // Check if the Controller supports USB IO protocol

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the Controller interface descriptor

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Status)) {

+    goto Exit;

+  }

+  //

+  // Bug here: just let Vendor specific CBI protocol get supported

+  //

+  if (!((InterfaceDescriptor.InterfaceClass == 0xFF) &&

+        (InterfaceDescriptor.InterfaceProtocol == 0))) {

+    Status = EFI_UNSUPPORTED;

+    goto Exit;

+  }

+

+Exit:

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+  return Status;

+

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1DriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Start this driver on ControllerHandle by opening a Block IO and Disk IO 

+    protocol, reading Device Path, and creating a child handle with a 

+    Disk IO and device path protocol.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to bind driver to

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver is added to DeviceHandle

+    EFI_ALREADY_STARTED - This driver is already running on DeviceHandle

+    other               - This driver does not support this device

+

+--*/

+{

+  USB_CBI_DEVICE                *UsbCbiDev;

+  UINT8                         Index;

+  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  BOOLEAN                       Found;

+

+  Found = FALSE;

+  //

+  // Check if the Controller supports USB IO protocol

+  //

+  UsbCbiDev = NULL;

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the controller interface descriptor

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  CBI1AtapiProtocol.CommandProtocol = InterfaceDescriptor.InterfaceSubClass;

+

+  UsbCbiDev                         = AllocateZeroPool (sizeof (USB_CBI_DEVICE));

+  if (UsbCbiDev == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto ErrorExit;

+  }

+

+  UsbCbiDev->Signature            = USB_CBI_DEVICE_SIGNATURE;

+  UsbCbiDev->UsbIo                = UsbIo;

+  CopyMem (&UsbCbiDev->InterfaceDescriptor, &InterfaceDescriptor, sizeof (InterfaceDescriptor));

+  CopyMem (&UsbCbiDev->UsbAtapiProtocol   , &CBI1AtapiProtocol,   sizeof (CBI1AtapiProtocol));

+

+  //

+  // Get the Device Path Protocol on Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &UsbCbiDev->DevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {

+    UsbIo->UsbGetEndpointDescriptor (

+            UsbIo,

+            Index,

+            &EndpointDescriptor

+            );

+

+    //

+    // We parse bulk endpoint

+    //

+    if (EndpointDescriptor.Attributes == 0x02) {

+      if (EndpointDescriptor.EndpointAddress & 0x80) {

+        CopyMem (&UsbCbiDev->BulkInEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));

+	 //UsbCbiDev->BulkInEndpointDescriptor = EndpointDescriptor;

+      } else {

+        CopyMem (&UsbCbiDev->BulkOutEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));

+	  //UsbCbiDev->BulkOutEndpointDescriptor = EndpointDescriptor;

+      }

+

+      Found = TRUE;

+    }

+    //

+    // We parse interrupt endpoint

+    //

+    if (EndpointDescriptor.Attributes == 0x03) {

+      CopyMem (&UsbCbiDev->InterruptEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));

+      //UsbCbiDev->InterruptEndpointDescriptor  = EndpointDescriptor;

+      Found = TRUE;

+    }

+

+  }

+  //

+  // Double check we have these

+  //

+  if (!Found) {

+    goto ErrorExit;

+  }

+  //

+  // After installing Usb-Atapi protocol onto this handle

+  // it will be called by upper layer drivers such as Fat

+  //

+  Cbi1ReportStatusCode (

+    UsbCbiDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)

+    );

+

+  Status = gBS->InstallProtocolInterface (

+                  &ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &UsbCbiDev->UsbAtapiProtocol

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  return EFI_SUCCESS;

+

+ErrorExit:

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+  if (UsbCbiDev != NULL) {

+    gBS->FreePool (UsbCbiDev);

+  }

+

+  return Status;

+

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1DriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles 

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    ControllerHandle  - Handle of device to stop driver on 

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS         - This driver is removed DeviceHandle

+    EFI_UNSUPPORTED     - Can't open the gEfiUsbAtapiProtocolGuid protocol 

+    other               - This driver was not removed from this device

+   

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_USB_ATAPI_PROTOCOL  *CBI1AtapiProtocol;

+  USB_CBI_DEVICE          *UsbCbiDev;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  (VOID **) &CBI1AtapiProtocol,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol);

+

+  UsbIo     = UsbCbiDev->UsbIo;

+

+  Cbi1ReportStatusCode (

+    UsbCbiDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)

+    );

+

+  Status = gBS->UninstallProtocolInterface (

+                  ControllerHandle,

+                  &gEfiUsbAtapiProtocolGuid,

+                  &UsbCbiDev->UsbAtapiProtocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->CloseProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  This->DriverBindingHandle,

+                  ControllerHandle

+                  );

+  gBS->FreePool (UsbCbiDev);

+

+  return Status;

+

+}

+//

+// CBI1 command

+//

+STATIC

+EFI_STATUS

+CBI1CommandPhase (

+  IN  USB_CBI_DEVICE          *UsbCbiDev,

+  IN  VOID                    *Command,

+  IN  UINT8                   CommandSize,

+  OUT UINT32                  *Result

+  )

+/*++

+

+  Routine Description:

+    In order to make consistence, CBI transportation protocol does only use

+     the first 3 parameters. Other parameters are not used here.

+

+  Arguments:

+    UsbCbiDev    - USB_CBI_DEVICE

+    Command      - Command to send 

+    CommandSize  - Command Size

+    Result       - Result to return

+

+  Returns:

+    EFI_SUCCESS         - This driver is removed DeviceHandle

+    other               - This driver was not removed from this device 

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+  EFI_USB_DEVICE_REQUEST  Request;

+  UINT32                  TimeOutInMilliSeconds;

+

+  UsbIo = UsbCbiDev->UsbIo;

+

+  ZeroMem (&Request, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  //

+  // Device request see CBI specification

+  //

+  Request.RequestType   = 0x21;

+  Request.Length        = CommandSize;

+

+  TimeOutInMilliSeconds = 1000;

+

+  Status = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataOut,

+                    TimeOutInMilliSeconds,

+                    Command,

+                    CommandSize,

+                    Result

+                    );

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+CBI1DataPhase (

+  IN  USB_CBI_DEVICE              *UsbCbiDev,

+  IN  UINT32                      DataSize,

+  IN  OUT VOID                    *DataBuffer,

+  IN  EFI_USB_DATA_DIRECTION      Direction,

+  IN  UINT16                      Timeout,

+  OUT UINT32                      *Result

+  )

+/*++

+

+Routine Description:

+

+  CBI1 Data Phase

+

+Arguments:

+

+  UsbCbiDev   - USB_CBI_DEVICE

+  DataSize    - Data Size

+  DataBuffer  - Data Buffer

+  Direction   - IN/OUT/NODATA

+  Timeout     - Time out value in milliseconds

+  Result      - Transfer result

+

+Returns:

+

+  EFI_SUCCESS - Success

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               EndpointAddr;

+  UINTN               Remain;

+  UINTN               Increment;

+  UINT32              MaxPacketLen;

+  UINT8               *BufferPtr;

+

+  UsbIo     = UsbCbiDev->UsbIo;

+

+  Remain    = DataSize;

+  BufferPtr = (UINT8 *) DataBuffer;

+

+  //

+  // retrieve the the max packet length of the given endpoint

+  //

+  if (Direction == EfiUsbDataIn) {

+    MaxPacketLen  = (UsbCbiDev->BulkInEndpointDescriptor).MaxPacketSize;

+    EndpointAddr  = (UsbCbiDev->BulkInEndpointDescriptor).EndpointAddress;

+  } else {

+    MaxPacketLen  = (UsbCbiDev->BulkOutEndpointDescriptor).MaxPacketSize;

+    EndpointAddr  = (UsbCbiDev->BulkOutEndpointDescriptor).EndpointAddress;

+  }

+

+  while (Remain > 0) {

+    //

+    // Using 15 packets to aVOID Bitstuff error

+    //

+    if (Remain > 15 * MaxPacketLen) {

+      Increment = 15 * MaxPacketLen;

+    } else {

+      Increment = Remain;

+    }

+

+    Status = UsbIo->UsbBulkTransfer (

+                      UsbIo,

+                      EndpointAddr,

+                      BufferPtr,

+                      &Increment,

+                      Timeout,

+                      Result

+                      );

+

+    if (EFI_ERROR (Status)) {

+      goto ErrorExit;

+    }

+

+    BufferPtr += Increment;

+    Remain -= Increment;

+  }

+

+  return EFI_SUCCESS;

+

+ErrorExit:

+

+  if (Direction == EfiUsbDataIn) {

+    Cbi1ReportStatusCode (

+      UsbCbiDev->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)

+      );

+  } else {

+    Cbi1ReportStatusCode (

+      UsbCbiDev->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)

+      );

+  }

+

+  if (((*Result) & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+    //

+    // just endpoint stall happens

+    //

+    UsbClearEndpointHalt (

+      UsbIo,

+      EndpointAddr,

+      Result

+      );

+  }

+

+  return Status;

+}

+//

+// CBI1 USB ATAPI Protocol

+//

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1MassStorageReset (

+  IN  EFI_USB_ATAPI_PROTOCOL      *This,

+  IN  BOOLEAN                     ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset CBI Devices

+    

+  Arguments:

+    This                    - Protocol instance pointer.

+    ExtendedVerification    - TRUE if we need to do strictly reset.

+

+  Returns:

+    EFI_SUCCESS         - Command succeeded.

+    EFI_DEVICE_ERROR    - Command failed.

+

+--*/

+{

+  UINT8               ResetCommand[12];

+  EFI_STATUS          Status;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  USB_CBI_DEVICE      *UsbCbiDev;

+  UINT8               EndpointAddr;

+  UINT32              Result;

+

+  UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);

+  UsbIo     = UsbCbiDev->UsbIo;

+

+  Cbi1ReportStatusCode (

+    UsbCbiDev->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)

+    );

+

+  if (ExtendedVerification) {

+    UsbIo->UsbPortReset (UsbIo);

+  }

+  //

+  // CBI reset command protocol

+  //

+  SetMem (ResetCommand, sizeof (ResetCommand), 0xff);

+  ResetCommand[0] = 0x1d;

+  ResetCommand[1] = 0x04;

+

+  Status = CBI1CommandPhase (

+            UsbCbiDev,

+            ResetCommand,

+            12,

+            &Result

+            );

+

+  //

+  // clear bulk in endpoint stall feature

+  //

+  EndpointAddr = UsbCbiDev->BulkInEndpointDescriptor.EndpointAddress;

+  UsbClearEndpointHalt (

+    UsbIo,

+    EndpointAddr,

+    &Result

+    );

+

+  //

+  // clear bulk out endpoint stall feature

+  //

+  EndpointAddr = UsbCbiDev->BulkOutEndpointDescriptor.EndpointAddress;

+  UsbClearEndpointHalt (

+    UsbIo,

+    EndpointAddr,

+    &Result

+    );

+

+  return EFI_SUCCESS;

+

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+CBI1AtapiCommand (

+  IN  EFI_USB_ATAPI_PROTOCOL  *This,

+  IN  VOID                    *Command,

+  IN  UINT8                   CommandSize,

+  IN  VOID                    *DataBuffer,

+  IN  UINT32                  BufferLength,

+  IN  EFI_USB_DATA_DIRECTION  Direction,

+  IN  UINT16                  TimeOutInMilliSeconds

+  )

+/*++

+

+  Routine Description:

+    Send ATAPI command using CBI1 protocol.

+    

+  Arguments:

+    This              - Protocol instance pointer.

+    Command           - Command buffer 

+    CommandSize       - Size of Command Buffer

+    DataBuffer        - Data buffer

+    BufferLength      - Length of Data buffer

+    Direction         - Data direction of this command

+    TimeOutInMilliSeconds - Timeout value in ms

+

+  Returns:

+    EFI_SUCCESS         - Command succeeded.

+    EFI_DEVICE_ERROR    - Command failed.

+

+--*/

+{

+  EFI_STATUS      Status;

+  USB_CBI_DEVICE  *UsbCbiDev;

+  UINT32          Result;

+  UINT8           Index;

+  UINT8           MaxRetryNum;

+

+  UsbCbiDev   = USB_CBI_DEVICE_FROM_THIS (This);

+

+  MaxRetryNum = 3;

+

+  for (Index = 0; Index < MaxRetryNum; Index++) {

+  

+    //

+    // First send ATAPI command through CBI1

+    //

+    Status = CBI1CommandPhase (

+              UsbCbiDev,

+              Command,

+              CommandSize,

+              &Result

+              );

+    if (EFI_ERROR (Status)) {

+

+      switch (Result) {

+

+      case EFI_USB_NOERROR:

+      case EFI_USB_ERR_STALL:

+      case EFI_USB_ERR_SYSTEM:

+        return EFI_DEVICE_ERROR;

+

+      default:

+        continue;

+        break;

+      }

+    } else {

+      break;

+    }

+  }

+

+  if (Index == MaxRetryNum) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  for (Index = 0; Index < MaxRetryNum; Index++) {

+    //

+    // Send/Get Data if there is a Data Stage

+    //

+    switch (Direction) {

+

+    case EfiUsbDataIn:

+    case EfiUsbDataOut:

+      Status = CBI1DataPhase (

+                UsbCbiDev,

+                BufferLength,

+                DataBuffer,

+                Direction,

+                TimeOutInMilliSeconds,

+                &Result

+                );

+

+      if (EFI_ERROR (Status)) {

+        switch (Result) {

+

+        case EFI_USB_NOERROR:

+        case EFI_USB_ERR_STALL:

+        case EFI_USB_ERR_SYSTEM:

+          return EFI_DEVICE_ERROR;

+

+        default:

+          continue;

+          break;

+        }

+

+      } else {

+

+        return EFI_SUCCESS;

+      }

+      break;

+

+    case EfiUsbNoData:

+      return EFI_SUCCESS;

+    }

+  }

+  //

+  // If goes here, means met error.

+  //

+  return EFI_DEVICE_ERROR;

+}

+

+VOID

+Cbi1ReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  )

+/*++

+

+  Routine Description:

+    Report Status Code in Usb Cbi1 Driver

+

+  Arguments:

+    DevicePath  - Use this to get Device Path

+    CodeType    - Status Code Type

+    CodeValue   - Status Code Value

+

+  Returns:

+    None

+

+--*/

+{

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    CodeType,

+    Value,

+    DevicePath

+    );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/cbi.h b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/cbi.h
new file mode 100644
index 0000000..e2a7c9d
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbCbi/Dxe/cbi.h
@@ -0,0 +1,70 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    cbi.h

+

+Abstract:

+

+    USB CBI transportation protocol definitions.

+--*/

+

+#ifndef _CBI_H

+#define _CBI_H

+

+

+#include <IndustryStandard/Usb.h>

+

+#define bit(a)                  (1 << (a))

+

+#define MASS_STORAGE_CLASS      0x08

+#define CBI0_INTERFACE_PROTOCOL 0x00

+#define CBI1_INTERFACE_PROTOCOL 0x01

+

+//

+// in millisecond unit

+//

+#define STALL_1_SECOND          1000  

+

+#pragma pack(1)

+//

+// Data block definition for transportation through interrupt endpoint

+//

+typedef struct {

+  UINT8 bType;

+  UINT8 bValue;

+} INTERRUPT_DATA_BLOCK;

+

+#pragma pack()

+

+#define USB_CBI_DEVICE_SIGNATURE  EFI_SIGNATURE_32 ('u', 'c', 'b', 'i')

+

+//

+// Device structure for CBI, interrupt endpoint may be not used in

+// CBI1 Protocol

+//

+typedef struct {

+  UINT32                        Signature;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  EFI_USB_ATAPI_PROTOCOL        UsbAtapiProtocol;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   BulkInEndpointDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   BulkOutEndpointDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   InterruptEndpointDescriptor;

+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;

+} USB_CBI_DEVICE;

+

+#define USB_CBI_DEVICE_FROM_THIS(a) \

+    CR(a, USB_CBI_DEVICE, UsbAtapiProtocol, USB_CBI_DEVICE_SIGNATURE)

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/ComponentName.c
new file mode 100644
index 0000000..3e139f9
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/ComponentName.c
@@ -0,0 +1,215 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "keyboard.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UsbKeyboardComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UsbKeyboardComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gUsbKeyboardComponentName = {

+  UsbKeyboardComponentNameGetDriverName,

+  UsbKeyboardComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mUsbKeyboardDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Usb Keyboard Driver" },

+  { NULL , NULL }

+};

+

+

+EFI_STATUS

+EFIAPI

+UsbKeyboardComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUsbKeyboardComponentName.SupportedLanguages,

+          mUsbKeyboardDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UsbKeyboardComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  USB_KB_DEV                  *UsbKbDev;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL *SimpleTxtIn;

+  EFI_USB_IO_PROTOCOL         *UsbIoProtocol;

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Check Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIoProtocol,

+                  gUsbKeyboardDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          gUsbKeyboardDriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get the device context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextInProtocolGuid,

+                  (VOID **) &SimpleTxtIn,

+                  gUsbKeyboardDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UsbKbDev = USB_KB_DEV_FROM_THIS (SimpleTxtIn);

+

+  return LookupUnicodeString (

+          Language,

+          gUsbKeyboardComponentName.SupportedLanguages,

+          UsbKbDev->ControllerNameTable,

+          ControllerName

+          );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/UsbKb.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/UsbKb.mbd
new file mode 100644
index 0000000..ecb6af6
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/UsbKb.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbKb</BaseName>

+    <Guid>2D2E62CF-9ECF-43b7-8219-94E7FC713DFE</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/UsbKb.msa b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/UsbKb.msa
new file mode 100644
index 0000000..6dff14b
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/UsbKb.msa
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbKb</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>2D2E62CF-9ECF-43b7-8219-94E7FC713DFE</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbKb module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>efikey.h</Filename>

+    <Filename>keyboard.h</Filename>

+    <Filename>efikey.c</Filename>

+    <Filename>keyboard.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">UsbIo</Protocol>

+    <Protocol Usage="BY_START">SimpleTextIn</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>HotPlugDevice</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUsbKeyboardDriverBinding</DriverBinding>

+      <ComponentName>gUsbKeyboardComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/build.xml
new file mode 100644
index 0000000..fda7667
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbKb"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbKb/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbKb">

+      <GenBuild baseName="UsbKb" mbdFilename="${MODULE_DIR}/UsbKb.mbd" msaFilename="${MODULE_DIR}/UsbKb.msa"/>

+   </target>

+   <target depends="UsbKb_clean" name="clean"/>

+   <target depends="UsbKb_cleanall" name="cleanall"/>

+   <target name="UsbKb_clean">

+      <OutputDirSetup baseName="UsbKb" mbdFilename="${MODULE_DIR}/UsbKb.mbd" msaFilename="${MODULE_DIR}/UsbKb.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbKb_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbKb_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbKb_cleanall">

+      <OutputDirSetup baseName="UsbKb" mbdFilename="${MODULE_DIR}/UsbKb.mbd" msaFilename="${MODULE_DIR}/UsbKb.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbKb_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbKb_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbKb*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.c b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.c
new file mode 100644
index 0000000..a9cdbc8
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.c
@@ -0,0 +1,772 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiKey.c

+    

+Abstract:

+

+  USB Keyboard Driver

+

+Revision History

+

+--*/

+

+#include "efikey.h"

+#include "keyboard.h"

+

+//

+// Prototypes

+// Driver model protocol interface

+//

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+//

+// Simple Text In Protocol Interface

+//

+STATIC

+EFI_STATUS

+EFIAPI

+USBKeyboardReset (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL  *This,

+  IN  BOOLEAN                      ExtendedVerification

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBKeyboardReadKeyStroke (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL   *This,

+  OUT EFI_INPUT_KEY                 *Key

+  );

+

+STATIC

+VOID

+EFIAPI

+USBKeyboardWaitForKey (

+  IN  EFI_EVENT               Event,

+  IN  VOID                    *Context

+  );

+

+//

+//  Helper functions

+//

+STATIC

+EFI_STATUS

+USBKeyboardCheckForKey (

+  IN  USB_KB_DEV      *UsbKeyboardDevice

+  );

+

+//

+// USB Keyboard Driver Global Variables

+//

+EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding = {

+  USBKeyboardDriverBindingSupported,

+  USBKeyboardDriverBindingStart,

+  USBKeyboardDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+    Supported.

+    

+  Arguments:

+    This          - EFI_DRIVER_BINDING_PROTOCOL

+    Controller    - Controller handle

+    RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL 

+  Returns:

+    EFI_STATUS

+  

+--*/ 

+{

+  EFI_STATUS          OpenStatus;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  EFI_STATUS          Status;

+

+  //

+  // Check if USB_IO protocol is attached on the controller handle.

+  //

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiUsbIoProtocolGuid,

+                      (VOID **) &UsbIo,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+  if (EFI_ERROR (OpenStatus)) {

+    return OpenStatus;

+  }

+   

+  //

+  // Use the USB I/O protocol interface to check whether the Controller is

+  // the Keyboard controller that can be managed by this driver.

+  //

+  Status = EFI_SUCCESS;

+

+  if (!IsUSBKeyboard (UsbIo)) {

+    Status = EFI_UNSUPPORTED;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+  

+  Routine Description:

+    Start.

+  

+  Arguments:

+    This       - EFI_DRIVER_BINDING_PROTOCOL

+    Controller - Controller handle

+    RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL

+  Returns:

+    EFI_SUCCESS          - Success

+    EFI_OUT_OF_RESOURCES - Can't allocate memory

+    EFI_UNSUPPORTED      - The Start routine fail

+--*/       

+{ 

+  EFI_STATUS                    Status;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  USB_KB_DEV                    *UsbKeyboardDevice;

+  UINT8                         EndpointNumber;

+  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;

+  UINT8                         Index;

+  UINT8                         EndpointAddr;

+  UINT8                         PollingInterval;

+  UINT8                         PacketSize;

+  BOOLEAN                       Found;

+  

+  UsbKeyboardDevice = NULL;

+  Found             = FALSE;

+

+  //

+  // Open USB_IO Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV));

+  if (UsbKeyboardDevice == NULL) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Get the Device Path Protocol on Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &UsbKeyboardDevice->DevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (UsbKeyboardDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+  //

+  // Report that the usb keyboard is being enabled

+  //

+  KbdReportStatusCode (

+    UsbKeyboardDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE)

+    );

+

+  //

+  // This is pretty close to keyboard detection, so log progress

+  //

+  KbdReportStatusCode (

+    UsbKeyboardDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT)

+    );

+

+  //

+  // Initialize UsbKeyboardDevice

+  //

+  UsbKeyboardDevice->UsbIo = UsbIo;

+

+  //

+  // Get interface & endpoint descriptor

+  //

+  UsbIo->UsbGetInterfaceDescriptor (

+          UsbIo,

+          &UsbKeyboardDevice->InterfaceDescriptor

+          );

+

+  EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;

+

+  for (Index = 0; Index < EndpointNumber; Index++) {

+

+    UsbIo->UsbGetEndpointDescriptor (

+            UsbIo,

+            Index,

+            &EndpointDescriptor

+            );

+

+    if ((EndpointDescriptor.Attributes & 0x03) == 0x03) {

+      //

+      // We only care interrupt endpoint here

+      //

+      CopyMem (&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));

+      //UsbKeyboardDevice->IntEndpointDescriptor  = EndpointDescriptor;

+      Found = TRUE;

+    }

+  }

+

+  if (!Found) {

+    //

+    // No interrupt endpoint found, then return unsupported.

+    //

+    gBS->FreePool (UsbKeyboardDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return EFI_UNSUPPORTED;

+  }

+

+  UsbKeyboardDevice->Signature                  = USB_KB_DEV_SIGNATURE;

+  UsbKeyboardDevice->SimpleInput.Reset          = USBKeyboardReset;

+  UsbKeyboardDevice->SimpleInput.ReadKeyStroke  = USBKeyboardReadKeyStroke;

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  USBKeyboardWaitForKey,

+                  UsbKeyboardDevice,

+                  &(UsbKeyboardDevice->SimpleInput.WaitForKey)

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (UsbKeyboardDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+       

+  //

+  // Install simple txt in protocol interface

+  // for the usb keyboard device.

+  // Usb keyboard is a hot plug device, and expected to work immediately

+  // when plugging into system, so a HotPlugDeviceGuid is installed onto

+  // the usb keyboard device handle, to distinguish it from other conventional

+  // console devices.

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Controller,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &UsbKeyboardDevice->SimpleInput,

+                  &gEfiHotPlugDeviceGuid,

+                  NULL,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);

+    gBS->FreePool (UsbKeyboardDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+    

+  //

+  // Reset USB Keyboard Device

+  //

+  Status = UsbKeyboardDevice->SimpleInput.Reset (

+                                            &UsbKeyboardDevice->SimpleInput,

+                                            TRUE

+                                            );

+  if (EFI_ERROR (Status)) {

+    gBS->UninstallMultipleProtocolInterfaces (

+          Controller,

+          &gEfiSimpleTextInProtocolGuid,

+          &UsbKeyboardDevice->SimpleInput,

+          &gEfiHotPlugDeviceGuid,

+          NULL,

+          NULL

+          );

+    gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);

+    gBS->FreePool (UsbKeyboardDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+  //

+  // submit async interrupt transfer

+  //

+  EndpointAddr    = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;

+  PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;

+  PacketSize      = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);

+

+  Status = UsbIo->UsbAsyncInterruptTransfer (

+                    UsbIo,

+                    EndpointAddr,

+                    TRUE,

+                    PollingInterval,

+                    PacketSize,

+                    KeyboardHandler,

+                    UsbKeyboardDevice

+                    );

+

+  if (EFI_ERROR (Status)) {

+

+    gBS->UninstallMultipleProtocolInterfaces (

+          Controller,

+          &gEfiSimpleTextInProtocolGuid,

+          &UsbKeyboardDevice->SimpleInput,

+          &gEfiHotPlugDeviceGuid,

+          NULL,

+          NULL

+          );

+    gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);

+    gBS->FreePool (UsbKeyboardDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+

+  UsbKeyboardDevice->ControllerNameTable = NULL;

+  AddUnicodeString (

+    "eng",

+    gUsbKeyboardComponentName.SupportedLanguages,

+    &UsbKeyboardDevice->ControllerNameTable,

+    (CHAR16 *) L"Generic Usb Keyboard"

+    );

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+USBKeyboardDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+  

+  Routine Description:

+    Stop.

+  

+  Arguments:

+    This              - EFI_DRIVER_BINDING_PROTOCOL

+    Controller        - Controller handle

+    NumberOfChildren  - Child handle number

+    ChildHandleBuffer - Child handle buffer 

+  Returns:

+    EFI_SUCCESS       - Success

+    EFI_UNSUPPORTED   - Can't support 

+--*/       

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL *SimpleInput;

+  USB_KB_DEV                  *UsbKeyboardDevice;

+  EFI_USB_IO_PROTOCOL         *UsbIo;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSimpleTextInProtocolGuid,

+                  (VOID **) &SimpleInput,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get USB_KB_DEV instance.

+  //

+  UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiSimpleTextInProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  UsbIo = UsbKeyboardDevice->UsbIo;

+  //

+  // Uninstall the Asyn Interrupt Transfer from this device

+  // will disable the key data input from this device

+  //

+  KbdReportStatusCode (

+    UsbKeyboardDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE)

+    );

+

+  //

+  // Destroy asynchronous interrupt transfer

+  //

+  UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (

+                              UsbKeyboardDevice->UsbIo,

+                              UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,

+                              FALSE,

+                              UsbKeyboardDevice->IntEndpointDescriptor.Interval,

+                              0,

+                              NULL,

+                              NULL

+                              );

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Controller,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &UsbKeyboardDevice->SimpleInput,

+                  &gEfiHotPlugDeviceGuid,

+                  NULL,

+                  NULL

+                  );

+  //

+  // free all the resources.

+  //

+  gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);

+  gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);

+  gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);

+

+  if (UsbKeyboardDevice->ControllerNameTable != NULL) {

+    FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);

+  }

+

+  gBS->FreePool (UsbKeyboardDevice);

+

+  return Status;

+

+}

+

+

+EFI_STATUS

+EFIAPI

+USBKeyboardReset (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL   *This,

+  IN  BOOLEAN                       ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.

+  

+  Arguments:

+    This      The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.

+    ExtendedVerification

+              Indicates that the driver may perform a more exhaustive

+              verification operation of the device during reset.              

+    

+  Returns:  

+    EFI_SUCCESS      - Success

+    EFI_DEVICE_ERROR - Hardware Error

+--*/      

+{

+  EFI_STATUS          Status;

+  USB_KB_DEV          *UsbKeyboardDevice;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+

+  UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);

+

+  UsbIo             = UsbKeyboardDevice->UsbIo;

+

+  KbdReportStatusCode (

+    UsbKeyboardDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET)

+    );

+

+  //

+  // Non Exhaustive reset:

+  // only reset private data structures.

+  //

+  if (!ExtendedVerification) {

+    //

+    // Clear the key buffer of this Usb keyboard

+    //

+    KbdReportStatusCode (

+      UsbKeyboardDevice->DevicePath,

+      EFI_PROGRESS_CODE,

+      (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER)

+      );

+

+    InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));

+    UsbKeyboardDevice->CurKeyChar = 0;

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // Exhaustive reset

+  //

+  Status                        = InitUSBKeyboard (UsbKeyboardDevice);

+  UsbKeyboardDevice->CurKeyChar = 0;

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBKeyboardReadKeyStroke (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL   *This,

+  OUT EFI_INPUT_KEY                 *Key

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.

+  

+  Arguments:

+    This     The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.

+    Key      A pointer to a buffer that is filled in with the keystroke

+             information for the key that was pressed.

+    

+  Returns:  

+    EFI_SUCCESS - Success

+--*/       

+{

+  USB_KB_DEV  *UsbKeyboardDevice;

+  EFI_STATUS  Status;

+  UINT8       KeyChar;

+

+  UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);

+

+  //

+  // if there is no saved ASCII byte, fetch it

+  // by calling USBKeyboardCheckForKey().

+  //

+  if (UsbKeyboardDevice->CurKeyChar == 0) {

+    Status = USBKeyboardCheckForKey (UsbKeyboardDevice);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  Key->UnicodeChar              = 0;

+  Key->ScanCode                 = SCAN_NULL;

+

+  KeyChar                       = UsbKeyboardDevice->CurKeyChar;

+

+  UsbKeyboardDevice->CurKeyChar = 0;

+

+  //

+  // Translate saved ASCII byte into EFI_INPUT_KEY

+  //

+  Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key);

+

+  return Status;

+

+}

+

+STATIC

+VOID

+EFIAPI

+USBKeyboardWaitForKey (

+  IN  EFI_EVENT               Event,

+  IN  VOID                    *Context

+  )

+/*++

+

+  Routine Description:

+    Handler function for WaitForKey event.    

+  

+  Arguments:

+    Event        Event to be signaled when a key is pressed.

+    Context      Points to USB_KB_DEV instance.

+    

+  Returns:  

+    VOID

+--*/       

+{

+  USB_KB_DEV  *UsbKeyboardDevice;

+

+  UsbKeyboardDevice = (USB_KB_DEV *) Context;

+

+  if (UsbKeyboardDevice->CurKeyChar == 0) {

+

+    if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) {

+      return ;

+    }

+  }

+  //

+  // If has key pending, signal the event.

+  //

+  gBS->SignalEvent (Event);

+}

+

+

+STATIC

+EFI_STATUS

+USBKeyboardCheckForKey (

+  IN  USB_KB_DEV    *UsbKeyboardDevice

+  )

+/*++

+

+  Routine Description:

+    Check whether there is key pending.

+  

+  Arguments:

+    UsbKeyboardDevice    The USB_KB_DEV instance.

+    

+  Returns:  

+    EFI_SUCCESS  - Success

+--*/       

+{

+  EFI_STATUS  Status;

+  UINT8       KeyChar;

+

+  //

+  // Fetch raw data from the USB keyboard input,

+  // and translate it into ASCII data.

+  //

+  Status = USBParseKey (UsbKeyboardDevice, &KeyChar);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UsbKeyboardDevice->CurKeyChar = KeyChar;

+  return EFI_SUCCESS;

+}

+

+VOID

+KbdReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  )

+/*++

+

+  Routine Description:

+    Report Status Code in Usb Bot Driver

+

+  Arguments:

+    DevicePath  - Use this to get Device Path

+    CodeType    - Status Code Type

+    CodeValue   - Status Code Value

+

+  Returns:

+    None

+

+--*/

+{

+

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    CodeType,

+    Value,

+    DevicePath

+    );

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.h b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.h
new file mode 100644
index 0000000..091dd69
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.h
@@ -0,0 +1,118 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    EfiKey.h

+

+Abstract:

+

+    Header file for USB Keyboard Driver's Data Structures

+

+Revision History

+--*/

+#ifndef _USB_KB_H

+#define _USB_KB_H

+

+

+#include <IndustryStandard/Usb.h>

+

+#define MAX_KEY_ALLOWED     32

+

+#define HZ                  1000 * 1000 * 10

+#define USBKBD_REPEAT_DELAY ((HZ) / 2)

+#define USBKBD_REPEAT_RATE  ((HZ) / 50)

+

+#define CLASS_HID           3

+#define SUBCLASS_BOOT       1

+#define PROTOCOL_KEYBOARD   1

+

+#define BOOT_PROTOCOL       0

+#define REPORT_PROTOCOL     1

+

+typedef struct {

+  UINT8 Down;

+  UINT8 KeyCode;

+} USB_KEY;

+

+typedef struct {

+  USB_KEY buffer[MAX_KEY_ALLOWED + 1];

+  UINT8   bHead;

+  UINT8   bTail;

+} USB_KB_BUFFER;

+

+#define USB_KB_DEV_SIGNATURE  EFI_SIGNATURE_32 ('u', 'k', 'b', 'd')

+typedef struct {

+  UINTN                         Signature;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  EFI_EVENT                     DelayedRecoveryEvent;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL   SimpleInput;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   IntEndpointDescriptor;

+

+  USB_KB_BUFFER                 KeyboardBuffer;

+  UINT8                         CtrlOn;

+  UINT8                         AltOn;

+  UINT8                         ShiftOn;

+  UINT8                         NumLockOn;

+  UINT8                         CapsOn;

+  UINT8                         LastKeyCodeArray[8];

+  UINT8                         CurKeyChar;

+

+  UINT8                         RepeatKey;

+  EFI_EVENT                     RepeatTimer;

+

+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;

+

+} USB_KB_DEV;

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gUsbKeyboardDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gUsbKeyboardComponentName;

+extern EFI_GUID                     gEfiUsbKeyboardDriverGuid;

+

+VOID

+KbdReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  );

+

+#define USB_KB_DEV_FROM_THIS(a) \

+    CR(a, USB_KB_DEV, SimpleInput, USB_KB_DEV_SIGNATURE)

+

+#define MOD_CONTROL_L           0x01

+#define MOD_CONTROL_R           0x10

+#define MOD_SHIFT_L             0x02

+#define MOD_SHIFT_R             0x20

+#define MOD_ALT_L               0x04

+#define MOD_ALT_R               0x40

+#define MOD_WIN_L               0x08

+#define MOD_WIN_R               0x80

+

+typedef struct {

+  UINT8 Mask;

+  UINT8 Key;

+} KB_MODIFIER;

+

+#define USB_KEYCODE_MAX_MAKE      0x64

+

+#define USBKBD_VALID_KEYCODE(key) ((UINT8) (key) > 3)

+

+typedef struct {

+  UINT8 NumLock : 1;

+  UINT8 CapsLock : 1;

+  UINT8 Resrvd : 6;

+} LED_MAP;

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/keyboard.c b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/keyboard.c
new file mode 100644
index 0000000..1328e6a
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/keyboard.c
@@ -0,0 +1,1150 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Keyboard.c

+    

+Abstract:

+

+  Helper functions for USB Keyboard Driver

+

+Revision History

+

+--*/

+

+#include "keyboard.h"

+

+//

+// USB Key Code to Efi key mapping table

+// Format:<efi scan code>, <unicode without shift>, <unicode with shift>

+//

+STATIC

+UINT8 KeyConvertionTable[USB_KEYCODE_MAX_MAKE][3] = {

+  { SCAN_NULL,      'a',      'A' },      // 0x04

+  { SCAN_NULL,      'b',      'B' },      // 0x05

+  { SCAN_NULL,      'c',      'C' },      // 0x06

+  { SCAN_NULL,      'd',      'D' },      // 0x07

+  { SCAN_NULL,      'e',      'E' },      // 0x08

+  { SCAN_NULL,      'f',      'F' },      // 0x09

+  { SCAN_NULL,      'g',      'G' },      // 0x0A

+  { SCAN_NULL,      'h',      'H' },      // 0x0B

+  { SCAN_NULL,      'i',      'I' },      // 0x0C

+  { SCAN_NULL,      'j',      'J' },      // 0x0D

+  { SCAN_NULL,      'k',      'K' },      // 0x0E

+  { SCAN_NULL,      'l',      'L' },      // 0x0F

+  { SCAN_NULL,      'm',      'M' },      // 0x10

+  { SCAN_NULL,      'n',      'N' },      // 0x11

+  { SCAN_NULL,      'o',      'O' },      // 0x12

+  { SCAN_NULL,      'p',      'P' },      // 0x13

+  { SCAN_NULL,      'q',      'Q' },      // 0x14

+  { SCAN_NULL,      'r',      'R' },      // 0x15

+  { SCAN_NULL,      's',      'S' },      // 0x16

+  { SCAN_NULL,      't',      'T' },      // 0x17

+  { SCAN_NULL,      'u',      'U' },      // 0x18

+  { SCAN_NULL,      'v',      'V' },      // 0x19

+  { SCAN_NULL,      'w',      'W' },      // 0x1A

+  { SCAN_NULL,      'x',      'X' },      // 0x1B

+  { SCAN_NULL,      'y',      'Y' },      // 0x1C

+  { SCAN_NULL,      'z',      'Z' },      // 0x1D

+  { SCAN_NULL,      '1',      '!' },      // 0x1E

+  { SCAN_NULL,      '2',      '@' },      // 0x1F

+  { SCAN_NULL,      '3',      '#' },      // 0x20

+  { SCAN_NULL,      '4',      '$' },      // 0x21

+  { SCAN_NULL,      '5',      '%' },      // 0x22

+  { SCAN_NULL,      '6',      '^' },      // 0x23

+  { SCAN_NULL,      '7',      '&' },      // 0x24

+  { SCAN_NULL,      '8',      '*' },      // 0x25

+  { SCAN_NULL,      '9',      '(' },      // 0x26

+  { SCAN_NULL,      '0',      ')' },      // 0x27

+  { SCAN_NULL,      0x0d,     0x0d },     // 0x28   Enter

+  { SCAN_ESC,       0x00,     0x00 },     // 0x29   Esc

+  { SCAN_NULL,      0x08,     0x08 },     // 0x2A   Backspace

+  { SCAN_NULL,      0x09,     0x09 },     // 0x2B   Tab

+  { SCAN_NULL,      ' ',      ' ' },      // 0x2C   Spacebar

+  { SCAN_NULL,      '-',      '_' },      // 0x2D

+  { SCAN_NULL,      '=',      '+' },      // 0x2E

+  { SCAN_NULL,      '[',      '{' },      // 0x2F

+  { SCAN_NULL,      ']',      '}' },      // 0x30

+  { SCAN_NULL,      '\\',     '|' },      // 0x31

+  { SCAN_NULL,      '\\',     '|' },      // 0x32  Keyboard US \ and |

+  { SCAN_NULL,      ';',      ':' },      // 0x33

+  { SCAN_NULL,      '\'',     '"' },      // 0x34

+  { SCAN_NULL,      '`',      '~' },      // 0x35  Keyboard Grave Accent and Tlide

+  { SCAN_NULL,      ',',      '<' },      // 0x36

+  { SCAN_NULL,      '.',      '>' },      // 0x37

+  { SCAN_NULL,      '/',      '?' },      // 0x38

+  { SCAN_NULL,      0x00,     0x00 },     // 0x39   CapsLock

+  { SCAN_F1,        0x00,     0x00 },     // 0x3A

+  { SCAN_F2,        0x00,     0x00 },     // 0x3B

+  { SCAN_F3,        0x00,     0x00 },     // 0x3C  

+  { SCAN_F4,        0x00,     0x00 },     // 0x3D  

+  { SCAN_F5,        0x00,     0x00 },     // 0x3E

+  { SCAN_F6,        0x00,     0x00 },     // 0x3F

+  { SCAN_F7,        0x00,     0x00 },     // 0x40

+  { SCAN_F8,        0x00,     0x00 },     // 0x41

+  { SCAN_F9,        0x00,     0x00 },     // 0x42

+  { SCAN_F10,       0x00,     0x00 },     // 0x43

+  { SCAN_NULL,      0x00,     0x00 },     // 0x44   F11

+  { SCAN_NULL,      0x00,     0x00 },     // 0x45   F12

+  { SCAN_NULL,      0x00,     0x00 },     // 0x46   PrintScreen

+  { SCAN_NULL,      0x00,     0x00 },     // 0x47   Scroll Lock

+  { SCAN_NULL,      0x00,     0x00 },     // 0x48   Pause

+  { SCAN_INSERT,    0x00,     0x00 },     // 0x49

+  { SCAN_HOME,      0x00,     0x00 },     // 0x4A

+  { SCAN_PAGE_UP,   0x00,     0x00 },     // 0x4B

+  { SCAN_DELETE,    0x00,     0x00 },     // 0x4C

+  { SCAN_END,       0x00,     0x00 },     // 0x4D

+  { SCAN_PAGE_DOWN, 0x00,     0x00 },     // 0x4E

+  { SCAN_RIGHT,     0x00,     0x00 },     // 0x4F

+  { SCAN_LEFT,      0x00,     0x00 },     // 0x50

+  { SCAN_DOWN,      0x00,     0x00 },     // 0x51

+  { SCAN_UP,        0x00,     0x00 },     // 0x52

+  { SCAN_NULL,      0x00,     0x00 },     // 0x53   NumLock

+  { SCAN_NULL,      '/',      '/' },      // 0x54

+  { SCAN_NULL,      '*',      '*' },      // 0x55

+  { SCAN_NULL,      '-',      '-' },      // 0x56

+  { SCAN_NULL,      '+',      '+' },      // 0x57

+  { SCAN_NULL,      0x0d,     0x0d },     // 0x58

+  { SCAN_END,       '1',      '1' },      // 0x59

+  { SCAN_DOWN,      '2',      '2' },      // 0x5A

+  { SCAN_PAGE_DOWN, '3',      '3' },      // 0x5B

+  { SCAN_LEFT,      '4',      '4' },      // 0x5C

+  { SCAN_NULL,      '5',      '5' },      // 0x5D

+  { SCAN_RIGHT,     '6',      '6' },      // 0x5E

+  { SCAN_HOME,      '7',      '7' },      // 0x5F

+  { SCAN_UP,        '8',      '8' },      // 0x60

+  { SCAN_PAGE_UP,   '9',      '9' },      // 0x61

+  { SCAN_INSERT,    '0',      '0' },      // 0x62

+  { SCAN_DELETE,    '.',      '.' },      // 0x63

+  { SCAN_NULL,      '\\',     '|' },      // 0x64 Keyboard Non-US \ and |

+  { SCAN_NULL,      0x00,     0x00 },     // 0x65 Keyboard Application

+  { SCAN_NULL,      0x00,     0x00 },     // 0x66 Keyboard Power

+  { SCAN_NULL,      '=' ,     '='  }      // 0x67 Keypad =

+};

+

+STATIC KB_MODIFIER  KB_Mod[8] = {

+  { MOD_CONTROL_L,  0xe0 }, // 11100000 

+  { MOD_CONTROL_R,  0xe4 }, // 11100100 

+  { MOD_SHIFT_L,    0xe1 }, // 11100001 

+  { MOD_SHIFT_R,    0xe5 }, // 11100101 

+  { MOD_ALT_L,      0xe2 }, // 11100010 

+  { MOD_ALT_R,      0xe6 }, // 11100110 

+  { MOD_WIN_L,      0xe3 }, // 11100011 

+  { MOD_WIN_R,      0xe7 }  // 11100111 

+};

+

+

+BOOLEAN

+IsUSBKeyboard (

+  IN  EFI_USB_IO_PROTOCOL       *UsbIo

+  )

+/*++

+  

+  Routine Description:

+    Uses USB I/O to check whether the device is a USB Keyboard device.

+  

+  Arguments:

+    UsbIo:    Points to a USB I/O protocol instance.

+    

+  Returns:

+  

+--*/  

+{

+  EFI_STATUS                    Status;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+

+  //

+  // Get the Default interface descriptor, currently we

+  // assume it is interface 1

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  if (InterfaceDescriptor.InterfaceClass == CLASS_HID &&

+      InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&

+      InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD

+      ) {

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+

+EFI_STATUS

+InitUSBKeyboard (

+  IN USB_KB_DEV   *UsbKeyboardDevice

+  )

+/*++

+  

+  Routine Description:

+    Initialize USB Keyboard device and all private data structures.

+    

+  Arguments:

+    UsbKeyboardDevice    The USB_KB_DEV instance.

+    

+  Returns:

+    EFI_SUCCESS      - Success

+    EFI_DEVICE_ERROR - Hardware Error

+--*/

+{

+  UINT8               ConfigValue;

+  UINT8               Protocol;

+  UINT8               ReportId;

+  UINT8               Duration;

+  EFI_STATUS          Status;

+  UINT32              TransferResult;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+

+  UsbIo = UsbKeyboardDevice->UsbIo;

+

+  KbdReportStatusCode (

+    UsbKeyboardDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST)

+    );

+

+  InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));

+

+  //

+  // default configurations

+  //

+  ConfigValue = 0x01;

+

+  //

+  // Uses default configuration to configure the USB Keyboard device.

+  //

+  Status = UsbSetDeviceConfiguration (

+            UsbKeyboardDevice->UsbIo,

+            (UINT16) ConfigValue,

+            &TransferResult

+            );

+  if (EFI_ERROR (Status)) {

+    //

+    // If configuration could not be set here, it means

+    // the keyboard interface has some errors and could

+    // not be initialized

+    //

+    KbdReportStatusCode (

+      UsbKeyboardDevice->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbGetProtocolRequest (

+    UsbKeyboardDevice->UsbIo,

+    UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,

+    &Protocol

+    );

+  //

+  // Sets boot protocol for the USB Keyboard.

+  // This driver only supports boot protocol.

+  // !!BugBug: How about the device that does not support boot protocol?

+  //

+  if (Protocol != BOOT_PROTOCOL) {

+    UsbSetProtocolRequest (

+      UsbKeyboardDevice->UsbIo,

+      UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,

+      BOOT_PROTOCOL

+      );

+  }

+  //

+  // the duration is indefinite, so the endpoint will inhibit reporting forever,

+  // and only reporting when a change is detected in the report data.

+  //

+

+  //

+  // idle value for all report ID

+  //

+  ReportId = 0;

+  //

+  // idle forever until there is a key pressed and released.

+  //

+  Duration = 0;

+  UsbSetIdleRequest (

+    UsbKeyboardDevice->UsbIo,

+    UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,

+    ReportId,

+    Duration

+    );

+

+  UsbKeyboardDevice->CtrlOn     = 0;

+  UsbKeyboardDevice->AltOn      = 0;

+  UsbKeyboardDevice->ShiftOn    = 0;

+  UsbKeyboardDevice->NumLockOn  = 0;

+  UsbKeyboardDevice->CapsOn     = 0;

+  ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);

+

+  //

+  // Set a timer for repeat keys' generation.

+  //

+  if (UsbKeyboardDevice->RepeatTimer) {

+    gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);

+    UsbKeyboardDevice->RepeatTimer = 0;

+  }

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_NOTIFY,

+                  USBKeyboardRepeatHandler,

+                  UsbKeyboardDevice,

+                  &UsbKeyboardDevice->RepeatTimer

+                  );

+

+  if (UsbKeyboardDevice->DelayedRecoveryEvent) {

+    gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);

+    UsbKeyboardDevice->DelayedRecoveryEvent = 0;

+  }

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_NOTIFY,

+                  USBKeyboardRecoveryHandler,

+                  UsbKeyboardDevice,

+                  &UsbKeyboardDevice->DelayedRecoveryEvent

+                  );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+KeyboardHandler (

+  IN  VOID          *Data,

+  IN  UINTN         DataLength,

+  IN  VOID          *Context,

+  IN  UINT32        Result

+  )

+/*++

+  

+  Routine Description:

+    Handler function for USB Keyboard's asynchronous interrupt transfer.

+    

+  Arguments:

+    Data       A pointer to a buffer that is filled with key data which is

+               retrieved via asynchronous interrupt transfer.

+    DataLength Indicates the size of the data buffer.

+    Context    Pointing to USB_KB_DEV instance.

+    Result     Indicates the result of the asynchronous interrupt transfer.

+    

+  Returns:

+    EFI_SUCCESS      - Success

+    EFI_DEVICE_ERROR - Hardware Error

+--*/  

+{

+  USB_KB_DEV          *UsbKeyboardDevice;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               *CurKeyCodeBuffer;

+  UINT8               *OldKeyCodeBuffer;

+  UINT8               CurModifierMap;

+  UINT8               OldModifierMap;

+  UINT8               Index;

+  UINT8               Index2;

+  BOOLEAN             Down;

+  EFI_STATUS          Status;

+  BOOLEAN             KeyRelease;

+  BOOLEAN             KeyPress;

+  UINT8               SavedTail;

+  USB_KEY             UsbKey;

+  UINT8               NewRepeatKey;

+  UINT32              UsbStatus;

+  UINT8               *DataPtr;

+

+  ASSERT (Context);

+

+  NewRepeatKey      = 0;

+  DataPtr           = (UINT8 *) Data;

+  UsbKeyboardDevice = (USB_KB_DEV *) Context;

+  UsbIo             = UsbKeyboardDevice->UsbIo;

+

+  //

+  // Analyzes the Result and performs corresponding action.

+  //

+  if (Result != EFI_USB_NOERROR) {

+    //

+    // Some errors happen during the process

+    //

+    KbdReportStatusCode (

+      UsbKeyboardDevice->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR)

+      );

+

+    //

+    // stop the repeat key generation if any

+    //

+    UsbKeyboardDevice->RepeatKey = 0;

+

+    gBS->SetTimer (

+          UsbKeyboardDevice->RepeatTimer,

+          TimerCancel,

+          USBKBD_REPEAT_RATE

+          );

+

+    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+      UsbClearEndpointHalt (

+        UsbIo,

+        UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,

+        &UsbStatus

+        );

+    }

+    

+    //

+    // Delete & Submit this interrupt again

+    //

+    

+    Status = UsbIo->UsbAsyncInterruptTransfer (

+                      UsbIo,

+                      UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,

+                      FALSE,

+                      0,

+                      0,

+                      NULL,

+                      NULL

+                      );

+

+    gBS->SetTimer (

+          UsbKeyboardDevice->DelayedRecoveryEvent,

+          TimerRelative,

+          EFI_USB_INTERRUPT_DELAY

+          );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (DataLength == 0 || Data == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  CurKeyCodeBuffer  = (UINT8 *) Data;

+  OldKeyCodeBuffer  = UsbKeyboardDevice->LastKeyCodeArray;

+

+  //

+  // checks for new key stroke.

+  // if no new key got, return immediately.

+  //

+  for (Index = 0; Index < 8; Index++) {

+    if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {

+      break;

+    }

+  }

+

+  if (Index == 8) {

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // Parse the modifier key

+  //

+  CurModifierMap  = CurKeyCodeBuffer[0];

+  OldModifierMap  = OldKeyCodeBuffer[0];

+

+  //

+  // handle modifier key's pressing or releasing situation.

+  //

+  for (Index = 0; Index < 8; Index++) {

+

+    if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) {

+      //

+      // if current modifier key is up, then

+      // CurModifierMap & KB_Mod[Index].Mask = 0;

+      // otherwize it is a non-zero value.

+      // Inserts the pressed modifier key into key buffer.

+      //

+      Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask);

+      InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), KB_Mod[Index].Key, Down);

+    }

+  }

+  

+  //

+  // handle normal key's releasing situation

+  //

+  KeyRelease = FALSE;

+  for (Index = 2; Index < 8; Index++) {

+

+    if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {

+      continue;

+    }

+

+    KeyRelease = TRUE;

+    for (Index2 = 2; Index2 < 8; Index2++) {

+

+      if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) {

+        continue;

+      }

+

+      if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) {

+        KeyRelease = FALSE;

+        break;

+      }

+    }

+

+    if (KeyRelease) {

+      InsertKeyCode (

+        &(UsbKeyboardDevice->KeyboardBuffer),

+        OldKeyCodeBuffer[Index],

+        0

+        );

+      //

+      // the original reapeat key is released.

+      //

+      if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {

+        UsbKeyboardDevice->RepeatKey = 0;

+      }

+    }

+  }

+    

+  //

+  // original repeat key is released, cancel the repeat timer

+  //

+  if (UsbKeyboardDevice->RepeatKey == 0) {

+    gBS->SetTimer (

+          UsbKeyboardDevice->RepeatTimer,

+          TimerCancel,

+          USBKBD_REPEAT_RATE

+          );

+  }

+  

+  //

+  // handle normal key's pressing situation

+  //

+  KeyPress = FALSE;

+  for (Index = 2; Index < 8; Index++) {

+

+    if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {

+      continue;

+    }

+

+    KeyPress = TRUE;

+    for (Index2 = 2; Index2 < 8; Index2++) {

+

+      if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) {

+        continue;

+      }

+

+      if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) {

+        KeyPress = FALSE;

+        break;

+      }

+    }

+

+    if (KeyPress) {

+      InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1);

+      //

+      // NumLock pressed or CapsLock pressed

+      //

+      if (CurKeyCodeBuffer[Index] == 0x53 || CurKeyCodeBuffer[Index] == 0x39) {

+        UsbKeyboardDevice->RepeatKey = 0;

+      } else {

+        NewRepeatKey = CurKeyCodeBuffer[Index];

+        //

+        // do not repeat the original repeated key

+        //

+        UsbKeyboardDevice->RepeatKey = 0;

+      }

+    }

+  }

+  

+  //

+  // Update LastKeycodeArray[] buffer in the

+  // Usb Keyboard Device data structure.

+  //

+  for (Index = 0; Index < 8; Index++) {

+    UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];

+  }

+  

+  //

+  // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence

+  // and judge whether it will invoke reset event.

+  //

+  SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;

+  Index     = UsbKeyboardDevice->KeyboardBuffer.bHead;

+  while (Index != SavedTail) {

+    RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);

+

+    switch (UsbKey.KeyCode) {

+

+    case 0xe0:

+    case 0xe4:

+      if (UsbKey.Down) {

+        UsbKeyboardDevice->CtrlOn = 1;

+      } else {

+        UsbKeyboardDevice->CtrlOn = 0;

+      }

+      break;

+

+    case 0xe2:

+    case 0xe6:

+      if (UsbKey.Down) {

+        UsbKeyboardDevice->AltOn = 1;

+      } else {

+        UsbKeyboardDevice->AltOn = 0;

+      }

+      break;

+

+    //

+    // Del Key Code

+    //

+    case 0x4c:

+    case 0x63:

+      if (UsbKey.Down) {

+        if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {

+          gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);

+        }

+      }

+      break;

+

+    default:

+      break;

+    }

+    

+    //

+    // insert the key back to the buffer.

+    // so the key sequence will not be destroyed.

+    //

+    InsertKeyCode (

+      &(UsbKeyboardDevice->KeyboardBuffer),

+      UsbKey.KeyCode,

+      UsbKey.Down

+      );

+    Index = UsbKeyboardDevice->KeyboardBuffer.bHead;

+

+  }

+  //

+  // If have new key pressed, update the RepeatKey value, and set the

+  // timer to repeate delay timer

+  //

+  if (NewRepeatKey != 0) {

+    //

+    // sets trigger time to "Repeat Delay Time",

+    // to trigger the repeat timer when the key is hold long

+    // enough time.

+    //

+    gBS->SetTimer (

+          UsbKeyboardDevice->RepeatTimer,

+          TimerRelative,

+          USBKBD_REPEAT_DELAY

+          );

+    UsbKeyboardDevice->RepeatKey = NewRepeatKey;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+USBParseKey (

+  IN OUT  USB_KB_DEV  *UsbKeyboardDevice,

+  OUT     UINT8       *KeyChar

+  )

+/*++

+  

+  Routine Description:

+    Retrieves a key character after parsing the raw data in keyboard buffer.

+    

+  Arguments:

+    UsbKeyboardDevice    The USB_KB_DEV instance.

+    KeyChar              Points to the Key character after key parsing.

+    

+  Returns:

+    EFI_SUCCESS   - Success

+    EFI_NOT_READY - Device is not ready 

+--*/  

+{

+  USB_KEY UsbKey;

+

+  *KeyChar = 0;

+

+  while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {

+    //

+    // pops one raw data off.

+    //

+    RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);

+

+    if (!UsbKey.Down) {

+      switch (UsbKey.KeyCode) {

+

+      case 0xe0:

+      case 0xe4:

+        UsbKeyboardDevice->CtrlOn = 0;

+        break;

+

+      case 0xe1:

+      case 0xe5:

+        UsbKeyboardDevice->ShiftOn = 0;

+        break;

+

+      case 0xe2:

+      case 0xe6:

+        UsbKeyboardDevice->AltOn = 0;

+        break;

+

+      default:

+        break;

+      }

+

+      continue;

+    }

+    

+    //

+    // Analyzes key pressing situation

+    //

+    switch (UsbKey.KeyCode) {

+

+    case 0xe0:

+    case 0xe4:

+      UsbKeyboardDevice->CtrlOn = 1;

+      continue;

+      break;

+

+    case 0xe1:

+    case 0xe5:

+      UsbKeyboardDevice->ShiftOn = 1;

+      continue;

+      break;

+

+    case 0xe2:

+    case 0xe6:

+      UsbKeyboardDevice->AltOn = 1;

+      continue;

+      break;

+

+    case 0xe3:

+    case 0xe7:

+      continue;

+      break;

+

+    case 0x53:

+      UsbKeyboardDevice->NumLockOn ^= 1;

+      SetKeyLED (UsbKeyboardDevice);

+      continue;

+      break;

+

+    case 0x39:

+      UsbKeyboardDevice->CapsOn ^= 1;

+      SetKeyLED (UsbKeyboardDevice);

+      continue;

+      break;

+

+    //

+    // F11,F12,PrintScreen,ScrollLock,Pause,Application,Power

+    // keys are not valid EFI key

+    //

+    case 0x44:

+    //

+    // fall through

+    //

+    case 0x45:

+    //

+    // fall through

+    //

+    case 0x46:

+    //

+    // fall through

+    //

+    case 0x47:

+    //

+    // fall through

+    //

+    case 0x48:

+    //

+    // fall through

+    //

+    case 0x65:

+    case 0x66:

+      continue;

+      break;

+

+    default:

+      break;

+    }

+    

+    //

+    // When encountered Del Key...

+    //

+    if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) {

+      if (UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {

+        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);

+      }

+    }

+

+    *KeyChar = UsbKey.KeyCode;

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_READY;

+

+}

+

+

+EFI_STATUS

+USBKeyCodeToEFIScanCode (

+  IN  USB_KB_DEV      *UsbKeyboardDevice,

+  IN  UINT8           KeyChar,

+  OUT EFI_INPUT_KEY   *Key

+  )

+/*++

+  

+  Routine Description:

+    Converts USB Keyboard code to EFI Scan Code.

+    

+  Arguments:  

+    UsbKeyboardDevice    The USB_KB_DEV instance.

+    KeyChar              Indicates the key code that will be interpreted.    

+    Key                  A pointer to a buffer that is filled in with 

+                         the keystroke information for the key that 

+                         was pressed.

+  Returns:

+    EFI_NOT_READY - Device is not ready

+    EFI_SUCCESS   - Success

+--*/

+{

+  UINT8 Index;

+

+  if (!USBKBD_VALID_KEYCODE (KeyChar)) {

+    return EFI_NOT_READY;

+  }

+  

+  //

+  // valid USB Key Code starts from 4

+  //

+  Index = (UINT8) (KeyChar - 4);

+

+  if (Index >= USB_KEYCODE_MAX_MAKE) {

+    return EFI_NOT_READY;

+  }

+

+  Key->ScanCode = KeyConvertionTable[Index][0];

+

+  if (UsbKeyboardDevice->ShiftOn) {

+

+    Key->UnicodeChar = KeyConvertionTable[Index][2];

+

+  } else {

+

+    Key->UnicodeChar = KeyConvertionTable[Index][1];

+  }

+

+  if (UsbKeyboardDevice->CapsOn) {

+

+    if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {

+

+      Key->UnicodeChar = KeyConvertionTable[Index][2];

+

+    } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {

+

+      Key->UnicodeChar = KeyConvertionTable[Index][1];

+

+    }

+  }

+

+  if (KeyChar >= 0x59 && KeyChar <= 0x63) {

+

+    if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) {

+

+      Key->ScanCode = SCAN_NULL;

+

+    } else {

+

+      Key->UnicodeChar = 0x00;

+    }

+  }

+

+  if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {

+    return EFI_NOT_READY;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+

+EFI_STATUS

+InitUSBKeyBuffer (

+  IN OUT  USB_KB_BUFFER   *KeyboardBuffer

+  )

+/*++

+  

+  Routine Description:

+    Resets USB Keyboard Buffer.

+    

+  Arguments:

+    KeyboardBuffer - Points to the USB Keyboard Buffer.

+    

+  Returns:

+    EFI_SUCCESS - Success

+--*/  

+{

+  ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));

+

+  KeyboardBuffer->bHead = KeyboardBuffer->bTail;

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsUSBKeyboardBufferEmpty (

+  IN  USB_KB_BUFFER   *KeyboardBuffer

+  )

+/*++

+  

+  Routine Description:

+    Check whether USB Keyboard buffer is empty.

+    

+  Arguments:

+    KeyboardBuffer - USB Keyboard Buffer.

+    

+  Returns:

+  

+--*/

+{

+  //

+  // meet FIFO empty condition

+  //

+  return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail);

+}

+

+

+BOOLEAN

+IsUSBKeyboardBufferFull (

+  IN  USB_KB_BUFFER   *KeyboardBuffer

+  )

+/*++

+  

+  Routine Description:

+    Check whether USB Keyboard buffer is full.

+    

+  Arguments:

+    KeyboardBuffer - USB Keyboard Buffer.

+    

+  Returns:

+  

+--*/

+{

+  return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) == 

+                                                        KeyboardBuffer->bHead);

+}

+

+

+EFI_STATUS

+InsertKeyCode (

+  IN OUT  USB_KB_BUFFER *KeyboardBuffer,

+  IN      UINT8         Key,

+  IN      UINT8         Down

+  )

+/*++

+  

+  Routine Description:

+    Inserts a key code into keyboard buffer.

+    

+  Arguments:

+    KeyboardBuffer - Points to the USB Keyboard Buffer.

+    Key            - Key code

+    Down           - Special key

+  Returns:

+    EFI_SUCCESS - Success

+--*/

+{

+  USB_KEY UsbKey;

+

+  //

+  // if keyboard buffer is full, throw the

+  // first key out of the keyboard buffer.

+  //

+  if (IsUSBKeyboardBufferFull (KeyboardBuffer)) {

+    RemoveKeyCode (KeyboardBuffer, &UsbKey);

+  }

+

+  KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;

+  KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down    = Down;

+

+  //

+  // adjust the tail pointer of the FIFO keyboard buffer.

+  //

+  KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RemoveKeyCode (

+  IN OUT  USB_KB_BUFFER *KeyboardBuffer,

+  OUT     USB_KEY       *UsbKey

+  )

+/*++

+  

+  Routine Description:

+    Pops a key code off from keyboard buffer.

+    

+  Arguments:

+    KeyboardBuffer -  Points to the USB Keyboard Buffer.

+    UsbKey         -  Points to the buffer that contains a usb key code.

+  

+  Returns:

+    EFI_SUCCESS      - Success

+    EFI_DEVICE_ERROR - Hardware Error

+--*/  

+{

+  if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;

+  UsbKey->Down    = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;

+

+  //

+  // adjust the head pointer of the FIFO keyboard buffer.

+  //

+  KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+SetKeyLED (

+  IN  USB_KB_DEV    *UsbKeyboardDevice

+  )

+/*++

+  

+  Routine Description:

+    Sets USB Keyboard LED state.

+    

+  Arguments:

+    UsbKeyboardDevice - The USB_KB_DEV instance.

+  

+  Returns:

+    EFI_SUCCESS - Success

+--*/  

+{

+  LED_MAP Led;

+  UINT8   ReportId;

+

+  //

+  // Set each field in Led map.

+  //

+  Led.NumLock   = (UINT8) UsbKeyboardDevice->NumLockOn;

+  Led.CapsLock  = (UINT8) UsbKeyboardDevice->CapsOn;

+  Led.Resrvd    = 0;

+

+  ReportId      = 0;

+  //

+  // call Set Report Request to lighten the LED.

+  //

+  UsbSetReportRequest (

+    UsbKeyboardDevice->UsbIo,

+    UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,

+    ReportId,

+    HID_OUTPUT_REPORT,

+    1,

+    (UINT8 *) &Led

+    );

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+USBKeyboardRepeatHandler (

+  IN    EFI_EVENT    Event,

+  IN    VOID         *Context

+  )

+/*++

+  

+  Routine Description:

+    Timer handler for Repeat Key timer.

+    

+  Arguments:

+    Event   - The Repeat Key event.

+    Context - Points to the USB_KB_DEV instance.

+    

+  Returns:

+  

+--*/    

+{

+  USB_KB_DEV  *UsbKeyboardDevice;

+

+  UsbKeyboardDevice = (USB_KB_DEV *) Context;

+

+  //

+  // Do nothing when there is no repeat key.

+  //

+  if (UsbKeyboardDevice->RepeatKey != 0) {

+    //

+    // Inserts one Repeat key into keyboard buffer,

+    //

+    InsertKeyCode (

+      &(UsbKeyboardDevice->KeyboardBuffer),

+      UsbKeyboardDevice->RepeatKey,

+      1

+      );

+

+    //

+    // set repeate rate for repeat key generation.

+    //

+    gBS->SetTimer (

+          UsbKeyboardDevice->RepeatTimer,

+          TimerRelative,

+          USBKBD_REPEAT_RATE

+          );

+

+  }

+}

+

+VOID

+EFIAPI

+USBKeyboardRecoveryHandler (

+  IN    EFI_EVENT    Event,

+  IN    VOID         *Context

+  )

+/*++

+  

+  Routine Description:

+    Timer handler for Delayed Recovery timer.

+    

+  Arguments:

+    Event   -  The Delayed Recovery event.

+    Context -  Points to the USB_KB_DEV instance.

+    

+  Returns:

+  

+--*/    

+{

+

+  USB_KB_DEV          *UsbKeyboardDevice;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               PacketSize;

+

+  UsbKeyboardDevice = (USB_KB_DEV *) Context;

+

+  UsbIo             = UsbKeyboardDevice->UsbIo;

+

+  PacketSize        = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);

+

+  UsbIo->UsbAsyncInterruptTransfer (

+          UsbIo,

+          UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,

+          TRUE,

+          UsbKeyboardDevice->IntEndpointDescriptor.Interval,

+          PacketSize,

+          KeyboardHandler,

+          UsbKeyboardDevice

+          );

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/keyboard.h b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/keyboard.h
new file mode 100644
index 0000000..a01fda3
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbKb/Dxe/keyboard.h
@@ -0,0 +1,106 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    Keyboard.h

+

+Abstract:

+

+    Function prototype for USB Keyboard Driver

+

+Revision History

+--*/

+

+#ifndef _KEYBOARD_H

+#define _KEYBOARD_H

+

+#include "efikey.h"

+

+BOOLEAN

+IsUSBKeyboard (

+  IN  EFI_USB_IO_PROTOCOL       *UsbIo

+  );

+

+EFI_STATUS

+InitUSBKeyboard (

+  IN USB_KB_DEV   *UsbKeyboardDevice

+  );

+

+EFI_STATUS

+EFIAPI

+KeyboardHandler (

+  IN  VOID          *Data,

+  IN  UINTN         DataLength,

+  IN  VOID          *Context,

+  IN  UINT32        Result

+  );

+

+VOID

+EFIAPI

+USBKeyboardRecoveryHandler (

+  IN    EFI_EVENT    Event,

+  IN    VOID         *Context

+  );

+

+EFI_STATUS

+USBParseKey (

+  IN OUT  USB_KB_DEV  *UsbKeyboardDevice,

+  OUT     UINT8       *KeyChar

+  );

+

+EFI_STATUS

+USBKeyCodeToEFIScanCode (

+  IN  USB_KB_DEV      *UsbKeyboardDevice,

+  IN  UINT8           KeyChar,

+  OUT EFI_INPUT_KEY   *Key

+  );

+

+EFI_STATUS

+InitUSBKeyBuffer (

+  IN OUT  USB_KB_BUFFER   *KeyboardBuffer

+  );

+

+BOOLEAN

+IsUSBKeyboardBufferEmpty (

+  IN  USB_KB_BUFFER   *KeyboardBuffer

+  );

+

+BOOLEAN

+IsUSBKeyboardBufferFull (

+  IN  USB_KB_BUFFER   *KeyboardBuffer

+  );

+

+EFI_STATUS

+InsertKeyCode (

+  IN OUT  USB_KB_BUFFER *KeyboardBuffer,

+  IN      UINT8         Key,

+  IN      UINT8         Down

+  );

+

+EFI_STATUS

+RemoveKeyCode (

+  IN OUT  USB_KB_BUFFER *KeyboardBuffer,

+  OUT     USB_KEY       *UsbKey

+  );

+

+VOID

+EFIAPI

+USBKeyboardRepeatHandler (

+  IN    EFI_EVENT    Event,

+  IN    VOID         *Context

+  );

+

+EFI_STATUS

+SetKeyLED (

+  IN  USB_KB_DEV    *UsbKeyboardDevice

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/ComponentName.c
new file mode 100644
index 0000000..a021d95
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/ComponentName.c
@@ -0,0 +1,154 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "UsbMassStorage.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UsbMassStorageComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UsbMassStorageComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gUsbMassStorageComponentName = {

+  UsbMassStorageComponentNameGetDriverName,

+  UsbMassStorageComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mUsbMassStorageDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Generic USB Mass Storage Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+UsbMassStorageComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUsbMassStorageComponentName.SupportedLanguages,

+          mUsbMassStorageDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UsbMassStorageComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.c b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.c
new file mode 100644
index 0000000..932b8c5
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.c
@@ -0,0 +1,727 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  UsbMassStorage.c

+    

+Abstract:

+

+  USB Mass Storage Driver

+

+Revision History

+

+--*/

+

+#include "UsbMassStorage.h"

+#include "UsbMassStorageHelper.h"

+

+extern EFI_COMPONENT_NAME_PROTOCOL  gUsbMassStorageComponentName;

+

+//

+// Prototypes

+// Driver model protocol interface

+//

+EFI_STATUS

+EFIAPI

+USBMassStorageDriverBindingEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+USBFloppyDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+USBFloppyDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+USBFloppyDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+//

+// Block I/O Protocol Interface

+//

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyReset (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  BOOLEAN                 ExtendedVerification

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyReadBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  OUT VOID                    *Buffer

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyWriteBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  IN  VOID                    *Buffer

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyFlushBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This

+  );

+

+//

+// USB Floppy Driver Global Variables

+//

+EFI_DRIVER_BINDING_PROTOCOL         gUSBFloppyDriverBinding = {

+  USBFloppyDriverBindingSupported,

+  USBFloppyDriverBindingStart,

+  USBFloppyDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+USBFloppyDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    that has UsbHcProtocol installed will be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller         - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS              OpenStatus;

+  EFI_USB_ATAPI_PROTOCOL  *AtapiProtocol;

+

+  //

+  // check whether EFI_USB_ATAPI_PROTOCOL exists, if it does,

+  // then the controller must be a USB Mass Storage Controller

+  //

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiUsbAtapiProtocolGuid,

+                      (VOID **) &AtapiProtocol,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+  if (EFI_ERROR (OpenStatus)) {

+    return OpenStatus;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbAtapiProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+USBFloppyDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Starting the Usb Bus Driver

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+    EFI_DEVICE_ERROR    - This driver cannot be started due to device

+                          Error

+    EFI_OUT_OF_RESOURCES- Can't allocate memory resources

+    EFI_ALREADY_STARTED - Thios driver has been started

+--*/

+{ 

+  EFI_STATUS                Status; 

+  EFI_USB_ATAPI_PROTOCOL    *AtapiProtocol;

+  USB_FLOPPY_DEV            *UsbFloppyDevice;

+  

+  UsbFloppyDevice = NULL;

+  //

+  // Check whether Usb Atapi Protocol attached on the controller handle.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiUsbAtapiProtocolGuid,

+                  (VOID **) &AtapiProtocol,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (USB_FLOPPY_DEV),

+                  (VOID **) &UsbFloppyDevice

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbAtapiProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+

+  ZeroMem (UsbFloppyDevice, sizeof (USB_FLOPPY_DEV));

+

+  UsbFloppyDevice->Handle             = Controller;

+  UsbFloppyDevice->BlkIo.Media        = &UsbFloppyDevice->BlkMedia;

+  UsbFloppyDevice->Signature          = USB_FLOPPY_DEV_SIGNATURE;

+  UsbFloppyDevice->BlkIo.Reset        = USBFloppyReset;

+  UsbFloppyDevice->BlkIo.ReadBlocks   = USBFloppyReadBlocks;

+  UsbFloppyDevice->BlkIo.WriteBlocks  = USBFloppyWriteBlocks;

+  UsbFloppyDevice->BlkIo.FlushBlocks  = USBFloppyFlushBlocks;

+  UsbFloppyDevice->AtapiProtocol      = AtapiProtocol;

+

+  //

+  // Identify drive type and retrieve media information.

+  //

+  Status = USBFloppyIdentify (UsbFloppyDevice);

+  if (EFI_ERROR (Status)) {

+    if (UsbFloppyDevice->SenseData != NULL) {

+      gBS->FreePool (UsbFloppyDevice->SenseData);

+    }

+

+    gBS->FreePool (UsbFloppyDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbAtapiProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+  //

+  // Install Block I/O protocol for the usb floppy device.

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &Controller,

+                  &gEfiBlockIoProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &UsbFloppyDevice->BlkIo

+                  );

+  if (EFI_ERROR (Status)) {

+    if (UsbFloppyDevice->SenseData != NULL) {

+      gBS->FreePool (UsbFloppyDevice->SenseData);

+    }

+

+    gBS->FreePool (UsbFloppyDevice);

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbAtapiProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+

+EFI_STATUS

+EFIAPI

+USBFloppyDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    Controller        - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    others

+

+--*/  

+{

+  EFI_STATUS            Status;

+  USB_FLOPPY_DEV        *UsbFloppyDevice;

+  EFI_BLOCK_IO_PROTOCOL *BlkIo;

+

+  //

+  // First find USB_FLOPPY_DEV

+  //

+  gBS->OpenProtocol (

+        Controller,

+        &gEfiBlockIoProtocolGuid,

+        (VOID **) &BlkIo,

+        This->DriverBindingHandle,

+        Controller,

+        EFI_OPEN_PROTOCOL_GET_PROTOCOL

+        );

+

+  UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (BlkIo);

+

+  //

+  // Uninstall Block I/O protocol from the device handle

+  //

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiBlockIoProtocolGuid,

+                  &UsbFloppyDevice->BlkIo

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Stop using EFI_USB_ATAPI_PROTOCOL

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbAtapiProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  if (UsbFloppyDevice->SenseData != NULL) {

+    gBS->FreePool (UsbFloppyDevice->SenseData);

+  }

+

+  gBS->FreePool (UsbFloppyDevice);

+

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyReset (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  BOOLEAN                 ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.

+  

+  Arguments:

+    This     The EFI_BLOCK_IO_PROTOCOL instance.

+    ExtendedVerification

+              Indicates that the driver may perform a more exhaustive

+              verification operation of the device during reset.

+              (This parameter is ingored in this driver.)

+    

+  Returns:  

+    EFI_SUCCESS - Success

+--*/      

+{

+  USB_FLOPPY_DEV          *UsbFloppyDevice;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+  EFI_STATUS              Status;

+

+  UsbFloppyDevice   = USB_FLOPPY_DEV_FROM_THIS (This);

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  //

+  // directly calling EFI_USB_ATAPI_PROTOCOL.Reset() to implement reset.

+  //

+  Status = UsbAtapiInterface->UsbAtapiReset (UsbAtapiInterface, TRUE);

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyReadBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.

+  

+  Arguments:

+    This     The EFI_BLOCK_IO_PROTOCOL instance.

+    MediaId  The media id that the read request is for.

+    LBA      The starting logical block address to read from on the device.

+    BufferSize

+              The size of the Buffer in bytes. This must be a multiple of 

+              the intrinsic block size of the device.

+    Buffer    A pointer to the destination buffer for the data. The caller 

+              is responsible for either having implicit or explicit ownership

+              of the buffer.                               

+  

+  Returns:  

+    EFI_INVALID_PARAMETER - Parameter is error

+    EFI_SUCCESS           - Success  

+    EFI_DEVICE_ERROR      - Hardware Error

+    EFI_NO_MEDIA          - No media

+    EFI_MEDIA_CHANGED     - Media Change

+    EFI_BAD_BUFFER_SIZE   - Buffer size is bad

+ --*/      

+{

+  USB_FLOPPY_DEV      *UsbFloppyDevice;

+  EFI_STATUS          Status;

+  EFI_BLOCK_IO_MEDIA  *Media;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  BOOLEAN             MediaChange;

+  EFI_TPL             OldTpl;

+  UINT32              Retry;

+

+  OldTpl          = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+  Status          = EFI_SUCCESS;

+  MediaChange     = FALSE;

+  Retry           = 0;

+

+  UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);

+

+  //

+  // Check parameters

+  //

+  if (!Buffer) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if (BufferSize == 0) {

+    Status = EFI_SUCCESS;

+    goto Done;

+  }

+

+  UsbFloppyTestUnitReady (UsbFloppyDevice);

+

+  Status = UsbFloppyDetectMedia (UsbFloppyDevice, &MediaChange);

+  if (EFI_ERROR (Status)) {

+

+    Status = EFI_DEVICE_ERROR;

+    goto Done;

+  }

+

+  if (MediaChange) {

+    gBS->RestoreTPL (OldTpl);

+    gBS->ReinstallProtocolInterface (

+          UsbFloppyDevice->Handle,

+          &gEfiBlockIoProtocolGuid,

+          &UsbFloppyDevice->BlkIo,

+          &UsbFloppyDevice->BlkIo

+          );

+    gBS->RaiseTPL (EFI_TPL_NOTIFY);

+  }

+

+  Media           = UsbFloppyDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (!(Media->MediaPresent)) {

+    Status = EFI_NO_MEDIA;

+    goto Done;

+  }

+

+  if (MediaId != Media->MediaId) {

+    Status = EFI_MEDIA_CHANGED;

+    goto Done;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    Status = EFI_BAD_BUFFER_SIZE;

+    goto Done;

+  }

+

+  if (LBA > Media->LastBlock) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if (!EFI_ERROR (Status)) {

+

+    Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, 1);

+    if (EFI_ERROR (Status)) {

+      This->Reset (This, TRUE);

+      Status = EFI_DEVICE_ERROR;

+      goto Done;

+    }

+

+    LBA += 1;

+    NumberOfBlocks -= 1;

+    Buffer = (UINT8 *) Buffer + This->Media->BlockSize;

+

+    if (NumberOfBlocks == 0) {

+      Status = EFI_SUCCESS;

+      goto Done;

+    }

+

+    Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);

+    if (EFI_ERROR (Status)) {

+      This->Reset (This, TRUE);

+      Status = EFI_DEVICE_ERROR;

+    }

+  }

+

+Done:

+  gBS->RestoreTPL (OldTpl);

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyWriteBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This,

+  IN  UINT32                  MediaId,

+  IN  EFI_LBA                 LBA,

+  IN  UINTN                   BufferSize,

+  IN  VOID                    *Buffer

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.

+  

+  Arguments:

+    This     The EFI_BLOCK_IO_PROTOCOL instance.

+    MediaId  The media id that the write request is for.

+    LBA      The starting logical block address to be written.

+             The caller is responsible for writing to only 

+             legitimate locations.

+    BufferSize

+              The size of the Buffer in bytes. This must be a multiple of 

+              the intrinsic block size of the device.

+    Buffer    A pointer to the source buffer for the data. The caller 

+              is responsible for either having implicit or explicit ownership

+              of the buffer.                               

+  

+  Returns:  

+    EFI_INVALID_PARAMETER - Parameter is error

+    EFI_SUCCESS           - Success  

+    EFI_DEVICE_ERROR      - Hardware Error

+    EFI_NO_MEDIA          - No media

+    EFI_MEDIA_CHANGED     - Media Change

+    EFI_BAD_BUFFER_SIZE   - Buffer size is bad

+

+--*/        

+{

+  USB_FLOPPY_DEV      *UsbFloppyDevice;

+  EFI_STATUS          Status;

+  EFI_BLOCK_IO_MEDIA  *Media;

+  UINTN               BlockSize;

+  UINTN               NumberOfBlocks;

+  BOOLEAN             MediaChange;

+  EFI_TPL             OldTpl;

+  UINT32              Retry;

+

+  OldTpl          = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+  Status          = EFI_SUCCESS;

+  MediaChange     = FALSE;

+  Retry           = 0;

+

+  UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);

+

+  //

+  // Check parameters

+  //

+  if (!Buffer) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if (BufferSize == 0) {

+    Status = EFI_SUCCESS;

+    goto Done;

+  }

+

+  UsbFloppyTestUnitReady (UsbFloppyDevice);

+

+  Status = UsbFloppyDetectMedia (UsbFloppyDevice, &MediaChange);

+  if (EFI_ERROR (Status)) {

+

+    Status = EFI_DEVICE_ERROR;

+    goto Done;

+  }

+

+  if (MediaChange) {

+    gBS->RestoreTPL (OldTpl);

+    gBS->ReinstallProtocolInterface (

+          UsbFloppyDevice->Handle,

+          &gEfiBlockIoProtocolGuid,

+          &UsbFloppyDevice->BlkIo,

+          &UsbFloppyDevice->BlkIo

+          );

+    gBS->RaiseTPL (EFI_TPL_NOTIFY);

+  }

+

+  Media           = UsbFloppyDevice->BlkIo.Media;

+  BlockSize       = Media->BlockSize;

+  NumberOfBlocks  = BufferSize / BlockSize;

+

+  if (!(Media->MediaPresent)) {

+    Status = EFI_NO_MEDIA;

+    goto Done;

+  }

+

+  if (MediaId != Media->MediaId) {

+    Status = EFI_MEDIA_CHANGED;

+    goto Done;

+  }

+

+  if (BufferSize % BlockSize != 0) {

+    Status = EFI_BAD_BUFFER_SIZE;

+    goto Done;

+  }

+

+  if (LBA > Media->LastBlock) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  if (UsbFloppyDevice->BlkMedia.ReadOnly) {

+    Status = EFI_WRITE_PROTECTED;

+    goto Done;

+  }

+

+  if (!EFI_ERROR (Status)) {

+    Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, 1);

+    if (EFI_ERROR (Status)) {

+      This->Reset (This, TRUE);

+      Status = EFI_DEVICE_ERROR;

+      goto Done;

+    }

+

+    LBA += 1;

+    NumberOfBlocks -= 1;

+    Buffer = (UINT8 *) Buffer + This->Media->BlockSize;

+

+    if (NumberOfBlocks == 0) {

+      Status = EFI_SUCCESS;

+      goto Done;

+    }

+

+    Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);

+    if (EFI_ERROR (Status)) {

+      This->Reset (This, TRUE);

+      Status = EFI_DEVICE_ERROR;

+    }

+  }

+

+Done:

+  gBS->RestoreTPL (OldTpl);

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+USBFloppyFlushBlocks (

+  IN  EFI_BLOCK_IO_PROTOCOL   *This

+  )

+/*++

+

+  Routine Description:

+    Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.

+    (In this driver, this function just returns EFI_SUCCESS.)

+  

+  Arguments:

+    This     The EFI_BLOCK_IO_PROTOCOL instance.

+  

+  Returns:  

+    EFI_SUCCESS - Success

+--*/    

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.h b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.h
new file mode 100644
index 0000000..387c53a
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.h
@@ -0,0 +1,59 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    UsbMassStorage.h

+

+Abstract:

+

+    Header file for USB Mass Storage Driver's Data Structures

+

+Revision History

+--*/

+

+#ifndef _USB_FLP_H

+#define _USB_FLP_H

+

+

+#include <IndustryStandard/Usb.h>

+#include "UsbMassStorageData.h"

+

+#define CLASS_MASSTORAGE          8

+#define SUBCLASS_UFI              4

+#define SUBCLASS_8070             5

+#define PROTOCOL_BOT              0x50

+#define PROTOCOL_CBI0             0

+#define PROTOCOL_CBI1             1

+

+#define USBFLOPPY                 1

+#define USBFLOPPY2                2 // for those that use ReadCapacity(0x25) command to retrieve media capacity

+#define USBCDROM                  3

+

+#define USB_FLOPPY_DEV_SIGNATURE  EFI_SIGNATURE_32 ('u', 'f', 'l', 'p')

+

+typedef struct {

+  UINTN                   Signature;

+

+  EFI_HANDLE              Handle;

+  EFI_BLOCK_IO_PROTOCOL   BlkIo;

+  EFI_BLOCK_IO_MEDIA      BlkMedia;

+  EFI_USB_ATAPI_PROTOCOL  *AtapiProtocol;

+

+  REQUEST_SENSE_DATA      *SenseData;

+  UINT8                   SenseDataNumber;

+  UINT8                   DeviceType;

+

+} USB_FLOPPY_DEV;

+

+#define USB_FLOPPY_DEV_FROM_THIS(a) \

+    CR(a, USB_FLOPPY_DEV, BlkIo, USB_FLOPPY_DEV_SIGNATURE)

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.mbd
new file mode 100644
index 0000000..c9c9b5c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbMassStorage</BaseName>

+    <Guid>A5C6D68B-E78A-4426-9278-A8F0D9EB4D8F</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.msa b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.msa
new file mode 100644
index 0000000..a739aeb
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.msa
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbMassStorage</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>A5C6D68B-E78A-4426-9278-A8F0D9EB4D8F</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbMassStorage module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UsbMassStorage.h</Filename>

+    <Filename>UsbMassStorageData.h</Filename>

+    <Filename>UsbMassStorageHelper.h</Filename>

+    <Filename>UsbMassStorage.c</Filename>

+    <Filename>UsbMassStorageHelper.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">UsbAtapi</Protocol>

+    <Protocol Usage="BY_START">BlockIo</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUSBFloppyDriverBinding</DriverBinding>

+      <ComponentName>gUsbMassStorageComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageData.h b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageData.h
new file mode 100644
index 0000000..598c82e
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageData.h
@@ -0,0 +1,394 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    UsbMassStorageData.h

+

+Abstract:

+

+    Header file for USB Mass Storage Device related Data Structures

+

+Revision History

+--*/

+

+#ifndef _USB_FLP_DATA_H

+#define _USB_FLP_DATA_H

+

+//

+// bit definition

+//

+#define bit(a)  1 << (a)

+

+//

+// timeout unit is in millisecond.

+//

+#define USBFLPTIMEOUT         2000

+#define STALL_1_MILLI_SECOND  1000

+

+//

+// ATAPI Packet Command

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1;

+  UINT8 reserved_2;

+  UINT8 reserved_3;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 reserved_8;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} TEST_UNIT_READY_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 4;

+  UINT8 lun : 4;

+  UINT8 page_code;

+  UINT8 reserved_3;

+  UINT8 allocation_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 reserved_8;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} INQUIRY_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 4;

+  UINT8 lun : 4;

+  UINT8 reserved_2;

+  UINT8 reserved_3;

+  UINT8 allocation_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 reserved_8;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} REQUEST_SENSE_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 4;

+  UINT8 lun : 4;

+  UINT8 page_code : 6;

+  UINT8 page_control : 2;

+  UINT8 reserved_3;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 parameter_list_length_hi;

+  UINT8 parameter_list_length_lo;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} MODE_SENSE_CMD_UFI;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 3;

+  UINT8 dbd : 1;

+  UINT8 reserved_2 : 1;

+  UINT8 lun : 3;

+  UINT8 page_code : 6;

+  UINT8 page_control : 2;

+  UINT8 reserved_3;

+  UINT8 allocation_length;

+  UINT8 control;

+} MODE_SENSE_CMD_SCSI;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1 : 5;

+  UINT8 lun : 3;

+  UINT8 Lba0;

+  UINT8 Lba1;

+  UINT8 Lba2;

+  UINT8 Lba3;

+  UINT8 reserved_6;

+  UINT8 TranLen0;

+  UINT8 TranLen1;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} READ10_CMD;

+

+typedef struct {

+  UINT8 opcode;

+  UINT8 reserved_1;

+  UINT8 reserved_2;

+  UINT8 reserved_3;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 allocation_length_hi;

+  UINT8 allocation_length_lo;

+  UINT8 reserved_9;

+  UINT8 reserved_10;

+  UINT8 reserved_11;

+} READ_FORMAT_CAP_CMD;

+

+typedef union {

+  UINT16              Data16[6];

+  TEST_UNIT_READY_CMD TestUnitReady;

+  READ10_CMD          Read10;

+  REQUEST_SENSE_CMD   RequestSense;

+  INQUIRY_CMD         Inquiry;

+  MODE_SENSE_CMD_UFI  ModeSenseUFI;

+  READ_FORMAT_CAP_CMD ReadFormatCapacity;

+  MODE_SENSE_CMD_SCSI ModeSenseSCSI;

+} ATAPI_PACKET_COMMAND;

+

+#pragma pack()

+//

+// Packet Command Code

+//

+#define TEST_UNIT_READY             0x00

+#define REZERO                      0x01

+#define REQUEST_SENSE               0x03

+#define FORMAT_UNIT                 0x04

+#define REASSIGN_BLOCKS             0x07

+#define INQUIRY                     0x12

+#define START_STOP_UNIT             0x1B

+#define PREVENT_ALLOW_MEDIA_REMOVAL 0x1E

+#define READ_FORMAT_CAPACITY        0x23

+#define OLD_FORMAT_UNIT             0x24

+#define READ_CAPACITY               0x25

+#define READ_10                     0x28

+#define WRITE_10                    0x2A

+#define SEEK                        0x2B

+#define SEND_DIAGNOSTICS            0x3D

+#define WRITE_VERIFY                0x2E

+#define VERIFY                      0x2F

+#define READ_DEFECT_DATA            0x37

+#define WRITE_BUFFER                0x38

+#define READ_BUFFER                 0x3C

+#define READ_LONG                   0x3E

+#define WRITE_LONG                  0x3F

+#define MODE_SELECT                 0x55

+#define UFI_MODE_SENSE5A            0x5A

+#define SCSI_MODE_SENSE1A           0x1A

+#define READ_12                     0xA8

+#define WRITE_12                    0xAA

+#define MAX_ATAPI_BYTE_COUNT        (0xfffe)

+

+//

+// Sense Key

+//

+#define REQUEST_SENSE_ERROR (0x70)

+#define SK_NO_SENSE         (0x0)

+#define SK_RECOVERY_ERROR   (0x1)

+#define SK_NOT_READY        (0x2)

+#define SK_MEDIUM_ERROR     (0x3)

+#define SK_HARDWARE_ERROR   (0x4)

+#define SK_ILLEGAL_REQUEST  (0x5)

+#define SK_UNIT_ATTENTION   (0x6)

+#define SK_DATA_PROTECT     (0x7)

+#define SK_BLANK_CHECK      (0x8)

+#define SK_VENDOR_SPECIFIC  (0x9)

+#define SK_RESERVED_A       (0xA)

+#define SK_ABORT            (0xB)

+#define SK_RESERVED_C       (0xC)

+#define SK_OVERFLOW         (0xD)

+#define SK_MISCOMPARE       (0xE)

+#define SK_RESERVED_F       (0xF)

+

+//

+// Additional Sense Codes

+//

+#define ASC_NOT_READY                   (0x04)

+#define ASC_MEDIA_ERR1                  (0x10)

+#define ASC_MEDIA_ERR2                  (0x11)

+#define ASC_MEDIA_ERR3                  (0x14)

+#define ASC_MEDIA_ERR4                  (0x30)

+#define ASC_MEDIA_UPSIDE_DOWN           (0x06)

+#define ASC_INVALID_CMD                 (0x20)

+#define ASC_LBA_OUT_OF_RANGE            (0x21)

+#define ASC_INVALID_FIELD               (0x24)

+#define ASC_WRITE_PROTECTED             (0x27)

+#define ASC_MEDIA_CHANGE                (0x28)

+#define ASC_RESET                       (0x29)  /* Power On Reset or Bus Reset occurred */

+#define ASC_ILLEGAL_FIELD               (0x26)

+#define ASC_NO_MEDIA                    (0x3A)

+#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK (0x64)

+#define ASC_LOGICAL_UNIT_STATUS         (0x08)

+

+//

+// Additional Sense Code Qualifier

+//

+#define ASCQ_IN_PROGRESS          (0x01)

+#define ASCQ_DEVICE_BUSY          (0xff)

+#define ASCQ_LOGICAL_UNIT_FAILURE (0x00)

+#define ASCQ_LOGICAL_UNIT_TIMEOUT (0x01)

+#define ASCQ_LOGICAL_UNIT_OVERRUN (0x80)

+

+#define SETFEATURE                TRUE

+#define CLEARFEATURE              FALSE

+

+//

+//  ATAPI Data structure

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8 peripheral_type;

+  UINT8 RMB;

+  UINT8 version;

+  UINT8 response_data_format;

+  UINT8 addnl_length;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+  UINT8 vendor_info[8];

+  UINT8 product_id[12];

+  UINT8 eeprom_product_code[4];

+  UINT8 firmware_rev_level[4];

+} USB_INQUIRY_DATA;

+

+typedef struct {

+  UINT8 error_code : 7;

+  UINT8 valid : 1;

+  UINT8 reserved_1;

+  UINT8 sense_key : 4;

+  UINT8 reserved_21 : 1;

+  UINT8 ILI : 1;

+  UINT8 reserved_22 : 2;

+  UINT8 vendor_specific_3;

+  UINT8 vendor_specific_4;

+  UINT8 vendor_specific_5;

+  UINT8 vendor_specific_6;

+  UINT8 addnl_sense_length;           // n - 7

+  UINT8 vendor_specific_8;

+  UINT8 vendor_specific_9;

+  UINT8 vendor_specific_10;

+  UINT8 vendor_specific_11;

+  UINT8 addnl_sense_code;             // mandatory

+  UINT8 addnl_sense_code_qualifier;   // mandatory

+  UINT8 field_replaceable_unit_code;  // optional

+  UINT8 reserved_15;

+  UINT8 reserved_16;

+  UINT8 reserved_17;

+  //

+  // Followed by additional sense bytes     : FIXME

+  //

+} REQUEST_SENSE_DATA;

+

+typedef struct {

+  UINT8 LastLba3;

+  UINT8 LastLba2;

+  UINT8 LastLba1;

+  UINT8 LastLba0;

+  UINT8 BlockSize3;

+  UINT8 BlockSize2;

+  UINT8 BlockSize1;

+  UINT8 BlockSize0;

+} READ_CAPACITY_DATA;

+

+typedef struct {

+  UINT8 reserved_0;

+  UINT8 reserved_1;

+  UINT8 reserved_2;

+  UINT8 Capacity_Length;

+  UINT8 LastLba3;

+  UINT8 LastLba2;

+  UINT8 LastLba1;

+  UINT8 LastLba0;

+  UINT8 DesCode : 2;

+  UINT8 reserved_9 : 6;

+  UINT8 BlockSize2;

+  UINT8 BlockSize1;

+  UINT8 BlockSize0;

+} READ_FORMAT_CAPACITY_DATA;

+

+typedef struct {

+  UINT8 mode_data_len_hi;

+  UINT8 mode_data_len_lo;

+  UINT8 media_type_code;

+  UINT8 reserved_3_0 : 4;

+  UINT8 dpofua : 1;

+  UINT8 reserved_3_1 : 2;

+  UINT8 write_protected : 1;

+  UINT8 reserved_4;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+} UFI_MODE_PARAMETER_HEADER;

+

+typedef struct {

+  UINT8 mode_data_len;

+  UINT8 media_type_code;

+  UINT8 speed : 4;

+  UINT8 buffered_mode : 3;

+  UINT8 write_protected : 1;

+  UINT8 block_descritptor_length;

+} SCSI_MODE_PARAMETER_HEADER6;

+

+typedef struct {

+  UINT8 page_code : 6;

+  UINT8 reserved_0 : 1;

+  UINT8 parameter_savable : 1;

+  UINT8 page_length;

+  UINT8 transfer_rate_msb;

+  UINT8 transfer_rate_lsb;

+  UINT8 number_of_heads;

+  UINT8 sectors_per_track;

+  UINT8 databytes_per_sector_msb;

+  UINT8 databytes_per_sector_lsb;

+  UINT8 number_of_cylinders_msb;

+  UINT8 number_of_cylinders_lsb;

+  UINT8 reserved_10_18[9];

+  UINT8 motor_on_delay;

+  UINT8 motor_off_delay;

+  UINT8 reserved_21_27[7];

+  UINT8 medium_rotation_rate_msb;

+  UINT8 medium_rotation_rate_lsb;

+  UINT8 reserved_30_31[2];

+} FLEXIBLE_DISK_PAGE;

+

+typedef struct {

+  UFI_MODE_PARAMETER_HEADER mode_param_header;

+  FLEXIBLE_DISK_PAGE        flex_disk_page;

+} UFI_MODE_PARAMETER_PAGE_5;

+

+typedef struct {

+  UINT8 page_code : 6;

+  UINT8 reserved_0 : 1;

+  UINT8 parameter_savable : 1;

+  UINT8 page_length;

+  UINT8 reserved_2;

+  UINT8 inactive_time_multplier : 4;

+  UINT8 reserved_3 : 4;

+  UINT8 software_write_protect : 1;

+  UINT8 disable_media_access : 1;

+  UINT8 reserved_4 : 6;

+  UINT8 reserved_5;

+  UINT8 reserved_6;

+  UINT8 reserved_7;

+} TIMER_AND_PROTECT_PAGE;

+

+typedef struct {

+  UFI_MODE_PARAMETER_HEADER mode_param_header;

+  TIMER_AND_PROTECT_PAGE    time_and_protect_page;

+} UFI_MODE_PARAMETER_PAGE_1C;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageHelper.c b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageHelper.c
new file mode 100644
index 0000000..b8ed813
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageHelper.c
@@ -0,0 +1,1653 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  UsbMassStorageHelper.c

+    

+Abstract:

+

+  Helper functions for USB Mass Storage Driver

+

+Revision History

+

+--*/

+

+#include "UsbMassStorageHelper.h"

+

+STATIC

+BOOLEAN

+IsNoMedia (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  );

+

+STATIC

+BOOLEAN

+IsMediaError (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  );

+

+STATIC

+BOOLEAN

+IsMediaChange (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  );

+

+STATIC

+BOOLEAN

+IsDriveReady (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts,

+  OUT BOOLEAN               *NeedRetry

+  );

+

+STATIC

+BOOLEAN

+IsMediaWriteProtected (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  );

+

+STATIC

+BOOLEAN

+IsLogicalUnitCommunicationOverRun (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  );

+

+EFI_STATUS

+USBFloppyPacketCommand (

+  USB_FLOPPY_DEV            *UsbFloppyDevice,

+  VOID                      *Command,

+  UINT8                     CommandSize,

+  VOID                      *DataBuffer,

+  UINT32                    BufferLength,

+  EFI_USB_DATA_DIRECTION    Direction,

+  UINT16                    TimeOutInMilliSeconds

+  )

+/*++

+

+  Routine Description:

+    Sends Packet Command to USB Floppy Drive.

+  

+  Arguments:

+    UsbFloppyDevice  -  The USB_FLOPPY_DEV instance.

+    Command          -  A pointer to the command packet.

+    CommandSize      -  Indicates the size of the command packet.

+    DataBuffer       -  A pointer to the buffer for the data transfer

+                        after the command packet.              

+    BufferLength     -  Indicates the size of the Data Buffer.

+    Direction        -  Transfer Direction

+    TimeOutInMilliSeconds - Timeout Value

+  Returns:  

+    EFI_SUCCESS  - Success

+--*/    

+{

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+  EFI_STATUS              Status;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+  //

+  // Directly calling EFI_USB_ATAPI_PROTOCOL.UsbAtapiPacketCmd()

+  // to perform the command request.

+  //

+  Status = UsbAtapiInterface->UsbAtapiPacketCmd (

+                                UsbAtapiInterface,

+                                Command,

+                                CommandSize,

+                                DataBuffer,

+                                BufferLength,

+                                Direction,

+                                TimeOutInMilliSeconds

+                                );

+

+  return Status;

+}

+

+EFI_STATUS

+USBFloppyIdentify (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves device information to tell the device type.

+  

+  Arguments:

+    UsbFloppyDevice    The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/    

+{

+

+  EFI_STATUS        Status;

+  USB_INQUIRY_DATA  *Idata;

+  BOOLEAN           MediaChange;

+

+  //

+  // Send Inquiry Packet Command to get INQUIRY data.

+  //

+  Status = USBFloppyInquiry (UsbFloppyDevice, &Idata);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+   

+  //

+  // Get media removable info from INQUIRY data.

+  //

+  UsbFloppyDevice->BlkIo.Media->RemovableMedia = (UINT8) ((Idata->RMB & 0x80) == 0x80);

+

+  //

+  // Identify device type via INQUIRY data.

+  //

+  switch ((Idata->peripheral_type) & 0x1f) {

+  //

+  // Floppy

+  //

+  case 0x00:

+    UsbFloppyDevice->DeviceType                 = USBFLOPPY;

+    UsbFloppyDevice->BlkIo.Media->MediaId       = 0;

+    UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;

+    UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;

+    UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x200;

+    break;

+

+  //

+  // CD-ROM

+  //

+  case 0x05:

+    UsbFloppyDevice->DeviceType                 = USBCDROM;

+    UsbFloppyDevice->BlkIo.Media->MediaId       = 0;

+    UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;

+    UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;

+    UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x800;

+    UsbFloppyDevice->BlkIo.Media->ReadOnly      = TRUE;

+    break;

+

+  default:

+    gBS->FreePool (Idata);

+    return EFI_DEVICE_ERROR;

+  };

+

+  //

+  // Initialize some device specific data.

+  //

+  //

+  // original sense data numbers

+  //

+  UsbFloppyDevice->SenseDataNumber = 6;

+

+  if (UsbFloppyDevice->SenseData != NULL) {

+    gBS->FreePool (UsbFloppyDevice->SenseData);

+    UsbFloppyDevice->SenseData = NULL;

+  }

+

+  UsbFloppyDevice->SenseData = AllocatePool (UsbFloppyDevice->SenseDataNumber * sizeof (REQUEST_SENSE_DATA));

+

+  if (UsbFloppyDevice->SenseData == NULL) {

+    gBS->FreePool (Idata);

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // Get media information.

+  //

+  UsbFloppyDetectMedia (UsbFloppyDevice, &MediaChange);

+

+  gBS->FreePool (Idata);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+USBFloppyInquiry (

+  IN    USB_FLOPPY_DEV        *UsbFloppyDevice,

+  OUT   USB_INQUIRY_DATA      **Idata

+  )

+/*++

+

+  Routine Description:

+    Send Inquiry Packet Command to device and retrieve Inquiry Data.

+  

+  Arguments:

+    UsbFloppyDevice    The USB_FLOPPY_DEV instance.

+    Idata              A pointer pointing to the address of 

+                       Inquiry Data.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/      

+{

+  ATAPI_PACKET_COMMAND    Packet;

+  EFI_STATUS              Status;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  //

+  // prepare command packet for the Inquiry Packet Command.

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.Inquiry.opcode             = INQUIRY;

+  Packet.Inquiry.page_code          = 0;

+  Packet.Inquiry.allocation_length  = sizeof (USB_INQUIRY_DATA);

+

+  *Idata = AllocateZeroPool (sizeof (USB_INQUIRY_DATA));

+  if (*Idata == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Send command packet and retrieve requested Inquiry Data.

+  //

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (ATAPI_PACKET_COMMAND),

+            (VOID *) (*Idata),

+            sizeof (USB_INQUIRY_DATA),

+            EfiUsbDataIn,

+            USBFLPTIMEOUT * 3

+            );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (*Idata);

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+USBFloppyRead10 (

+  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,

+  IN    VOID              *Buffer,

+  IN    EFI_LBA           Lba,

+  IN    UINTN             NumberOfBlocks

+  )

+/*++

+

+  Routine Description:

+    Sends Read10 Packet Command to device to perform data transfer

+    from device to host.

+  

+  Arguments:

+    UsbFloppyDevice -   The USB_FLOPPY_DEV instance.

+    Buffer          -   A pointer to the destination buffer for the data. 

+                        The caller is responsible for either having implicit

+                        or explicit ownership of the buffer.

+    Lba             -   The starting logical block address to read from 

+                        on the device.

+    NumberOfBlocks  -   Indicates the number of blocks that the read 

+                        operation requests.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/      

+{

+  ATAPI_PACKET_COMMAND    Packet;

+  READ10_CMD              *Read10Packet;

+  UINT16                  MaxBlock;

+  UINT16                  BlocksRemaining;

+  UINT16                  SectorCount;

+  UINT32                  Lba32;

+  UINT32                  BlockSize;

+  UINT32                  ByteCount;

+  VOID                    *ptrBuffer;

+  EFI_STATUS              Status;

+  UINT16                  TimeOut;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+  UINTN                   SenseCounts;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  //

+  // prepare command packet for the Inquiry Packet Command.

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Read10Packet    = &Packet.Read10;

+  Lba32           = (UINT32) Lba;

+  ptrBuffer       = Buffer;

+  BlockSize       = UsbFloppyDevice->BlkIo.Media->BlockSize;

+

+  MaxBlock        = (UINT16) (65536 / BlockSize);

+  BlocksRemaining = (UINT16) NumberOfBlocks;

+

+  Status          = EFI_SUCCESS;

+  while (BlocksRemaining > 0) {

+    if (BlocksRemaining <= MaxBlock) {

+      SectorCount = BlocksRemaining;

+    } else {

+      SectorCount = MaxBlock;

+    }

+    //

+    // fill the Packet data structure

+    //

+    Read10Packet->opcode = READ_10;

+

+    //

+    // Lba0 ~ Lba3 specify the start logical block address of the data transfer.

+    // Lba0 is MSB, Lba3 is LSB

+    //

+    Read10Packet->Lba3  = (UINT8) (Lba32 & 0xff);

+    Read10Packet->Lba2  = (UINT8) (Lba32 >> 8);

+    Read10Packet->Lba1  = (UINT8) (Lba32 >> 16);

+    Read10Packet->Lba0  = (UINT8) (Lba32 >> 24);

+

+    //

+    // TranLen0 ~ TranLen1 specify the transfer length in block unit.

+    // TranLen0 is MSB, TranLen is LSB

+    //

+    Read10Packet->TranLen1  = (UINT8) (SectorCount & 0xff);

+    Read10Packet->TranLen0  = (UINT8) (SectorCount >> 8);

+

+    ByteCount               = SectorCount * BlockSize;

+

+    TimeOut                 = (UINT16) (SectorCount * USBFLPTIMEOUT);

+

+    Status = USBFloppyPacketCommand (

+              UsbFloppyDevice,

+              &Packet,

+              sizeof (ATAPI_PACKET_COMMAND),

+              (VOID *) ptrBuffer,

+              ByteCount,

+              EfiUsbDataIn,

+              TimeOut

+              );

+    if (EFI_ERROR (Status)) {

+

+      Status = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);

+      if (!EFI_ERROR (Status)) {

+        if (IsLogicalUnitCommunicationOverRun (

+              UsbFloppyDevice->SenseData,

+              SenseCounts

+              )) {

+          Lba32           = (UINT32) Lba;

+          ptrBuffer       = Buffer;

+          BlocksRemaining = (UINT16) NumberOfBlocks;

+          MaxBlock        = (UINT16) (MaxBlock / 4);

+          if (MaxBlock < 1) {

+            MaxBlock = 1;

+          }

+

+          continue;

+        }

+      } else {

+        return EFI_DEVICE_ERROR;

+      }

+      //

+      // retry read10 command

+      //

+      Status = USBFloppyPacketCommand (

+                UsbFloppyDevice,

+                &Packet,

+                sizeof (ATAPI_PACKET_COMMAND),

+                (VOID *) ptrBuffer,

+                ByteCount,

+                EfiUsbDataIn,

+                TimeOut

+                );

+      if (EFI_ERROR (Status)) {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+

+    Lba32 += SectorCount;

+    ptrBuffer       = (UINT8 *) ptrBuffer + SectorCount * BlockSize;

+    BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+USBFloppyReadCapacity (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves media capacity information via 

+    sending Read Capacity Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice -   The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/        

+{ 

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS              Status;

+  ATAPI_PACKET_COMMAND    Packet;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+

+  //

+  // used for capacity data returned from Usb Floppy

+  //

+  READ_CAPACITY_DATA      Data;

+

+  ZeroMem (&Data, sizeof (Data));

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.Inquiry.opcode = READ_CAPACITY;

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (ATAPI_PACKET_COMMAND),

+            (VOID *) &Data,

+            sizeof (READ_CAPACITY_DATA),

+            EfiUsbDataIn,

+            USBFLPTIMEOUT

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbFloppyDevice->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |

+    (Data.LastLba2 << 16) |

+    (Data.LastLba1 << 8) |

+    Data.LastLba0;

+

+  UsbFloppyDevice->BlkIo.Media->MediaPresent  = TRUE;

+

+  UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x800;

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+USBFloppyReadFormatCapacity (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves media capacity information via sending Read Format 

+    Capacity Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/         

+{ 

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS                Status;

+  ATAPI_PACKET_COMMAND      Packet;

+  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;

+

+  //

+  // used for capacity data returned from Usb Floppy

+  //

+  READ_FORMAT_CAPACITY_DATA FormatData;

+

+  ZeroMem (&FormatData, sizeof (FormatData));

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.ReadFormatCapacity.opcode                = READ_FORMAT_CAPACITY;

+  Packet.ReadFormatCapacity.allocation_length_lo  = 12;

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (ATAPI_PACKET_COMMAND),

+            (VOID *) &FormatData,

+            sizeof (READ_FORMAT_CAPACITY_DATA),

+            EfiUsbDataIn,

+            USBFLPTIMEOUT

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (FormatData.DesCode == 3) {

+    //

+    // Media is not present

+    //

+    UsbFloppyDevice->BlkIo.Media->MediaId       = 0;

+    UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;

+    UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;

+  } else {

+

+    UsbFloppyDevice->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) |

+                                              (FormatData.LastLba2 << 16) | 

+                                              (FormatData.LastLba1 << 8)  |

+                                               FormatData.LastLba0;

+

+    UsbFloppyDevice->BlkIo.Media->LastBlock--;

+

+    UsbFloppyDevice->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |

+      (FormatData.BlockSize1 << 8) |

+      FormatData.BlockSize0;

+

+    UsbFloppyDevice->BlkIo.Media->MediaPresent  = TRUE;

+

+    UsbFloppyDevice->BlkIo.Media->BlockSize     = 0x200;

+

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+UsbFloppyRequestSense (

+  IN  USB_FLOPPY_DEV  *UsbFloppyDevice,

+  OUT UINTN           *SenseCounts

+  )

+/*++

+

+  Routine Description:

+    Retrieves Sense Data from device via 

+    sending Request Sense Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice - The USB_FLOPPY_DEV instance.

+    SenseCounts     - A pointer to the number of Sense Data returned.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/         

+{

+  EFI_STATUS              Status;

+  REQUEST_SENSE_DATA      *Sense;

+  UINT8                   *Ptr;

+  BOOLEAN                 SenseReq;

+  ATAPI_PACKET_COMMAND    Packet;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  *SenseCounts      = 0;

+

+  ZeroMem (

+    UsbFloppyDevice->SenseData,

+    sizeof (REQUEST_SENSE_DATA) * (UsbFloppyDevice->SenseDataNumber)

+    );

+  //

+  // fill command packet for Request Sense Packet Command

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.RequestSense.opcode            = REQUEST_SENSE;

+  Packet.RequestSense.allocation_length = sizeof (REQUEST_SENSE_DATA);

+  

+  //

+  // initialize pointer

+  //

+  Ptr = (UINT8 *) (UsbFloppyDevice->SenseData);

+

+  //

+  //  request sense data from device continuously

+  //  until no sense data exists in the device.

+  //

+  for (SenseReq = TRUE; SenseReq;) {

+

+    Sense = (REQUEST_SENSE_DATA *) Ptr;

+

+    //

+    // send out Request Sense Packet Command and get one Sense

+    // data from device.

+    //

+    Status = USBFloppyPacketCommand (

+              UsbFloppyDevice,

+              &Packet,

+              sizeof (ATAPI_PACKET_COMMAND),

+              (VOID *) Ptr,

+              sizeof (REQUEST_SENSE_DATA),

+              EfiUsbDataIn,

+              USBFLPTIMEOUT

+              );

+    //

+    // failed to get Sense data

+    //

+    if (EFI_ERROR (Status)) {

+      //

+      // Recovery the device back to normal state.

+      //

+      UsbFloppyDevice->AtapiProtocol->UsbAtapiReset (

+                                        UsbFloppyDevice->AtapiProtocol,

+                                        TRUE

+                                        );

+

+      if (*SenseCounts == 0) {

+        //

+        // never retrieved any sense data from device,

+        // just return error.

+        //

+        return EFI_DEVICE_ERROR;

+      } else {

+        //

+        // has retrieved some sense data from device,

+        // so return success.

+        //

+        return EFI_SUCCESS;

+      }

+    }

+

+    if (Sense->sense_key != SK_NO_SENSE) {

+      //

+      // Ptr is byte based pointer

+      //

+      Ptr += sizeof (REQUEST_SENSE_DATA);

+

+      (*SenseCounts)++;

+

+    } else {

+      //

+      // when no sense key, skip out the loop

+      //

+      SenseReq = FALSE;

+    }

+  

+    //

+    // If the sense key numbers exceed Sense Data Buffer size,

+    // just skip the loop and do not fetch the sense key in this function.

+    //

+    if (*SenseCounts == UsbFloppyDevice->SenseDataNumber) {

+      SenseReq = FALSE;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UsbFloppyTestUnitReady (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Sends Test Unit ReadyPacket Command to the device.

+  

+  Arguments:

+    UsbFloppyDevice -  The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/  

+{ 

+  ATAPI_PACKET_COMMAND      Packet; 

+  EFI_STATUS                Status;

+  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;

+  UINT32                    RetryIndex;

+  UINT32                    MaximumRetryTimes;

+  

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+  MaximumRetryTimes = 2;

+  //

+  // fill command packet  

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.TestUnitReady.opcode = TEST_UNIT_READY;

+

+  //

+  // send command packet

+  //

+  Status = EFI_DEVICE_ERROR;

+

+  for (RetryIndex = 0; RetryIndex < MaximumRetryTimes && EFI_ERROR (Status); RetryIndex++) {

+

+    Status = USBFloppyPacketCommand (

+              UsbFloppyDevice,

+              &Packet,

+              sizeof (ATAPI_PACKET_COMMAND),

+              NULL,

+              0,

+              EfiUsbNoData,

+              USBFLPTIMEOUT

+              );

+

+    if (EFI_ERROR (Status)) {

+      gBS->Stall (100 * STALL_1_MILLI_SECOND);

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+USBFloppyWrite10 (

+  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,

+  IN    VOID              *Buffer,

+  IN    EFI_LBA           Lba,

+  IN    UINTN             NumberOfBlocks

+  )

+/*++

+

+  Routine Description:

+    Sends Write10 Packet Command to device to perform data transfer

+    from host to device.

+  

+  Arguments:

+    UsbFloppyDevice -   The USB_FLOPPY_DEV instance.

+    Buffer          -   A pointer to the source buffer for the data. 

+                        The caller is responsible for either having implicit

+                        or explicit ownership of the buffer.

+    Lba             -   The starting logical block address to written to 

+                        the device.

+    NumberOfBlocks  -   Indicates the number of blocks that the write 

+                        operation requests.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+--*/      

+{

+  ATAPI_PACKET_COMMAND    Packet;

+  READ10_CMD              *Write10Packet;

+  UINT16                  MaxBlock;

+  UINT16                  BlocksRemaining;

+  UINT16                  SectorCount;

+  UINT32                  Lba32;

+  UINT32                  BlockSize;

+  UINT32                  ByteCount;

+  VOID                    *ptrBuffer;

+  EFI_STATUS              Status;

+  UINT16                  TimeOut;

+  EFI_USB_ATAPI_PROTOCOL  *UsbAtapiInterface;

+  UINTN                   SenseCounts;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  //

+  // prepare command packet for the Write10 Packet Command.

+  //

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Write10Packet   = &Packet.Read10;

+  Lba32           = (UINT32) Lba;

+  ptrBuffer       = Buffer;

+  BlockSize       = UsbFloppyDevice->BlkIo.Media->BlockSize;

+

+  MaxBlock        = (UINT16) (65536 / BlockSize);

+  BlocksRemaining = (UINT16) NumberOfBlocks;

+

+  Status          = EFI_SUCCESS;

+  while (BlocksRemaining > 0) {

+

+    if (BlocksRemaining <= MaxBlock) {

+

+      SectorCount = BlocksRemaining;

+    } else {

+

+      SectorCount = MaxBlock;

+    }

+    //

+    // fill the Packet data structure

+    //

+    Write10Packet->opcode = WRITE_10;

+

+    //

+    // Lba0 ~ Lba3 specify the start logical block address

+    // of the data transfer.

+    // Lba0 is MSB, Lba3 is LSB

+    //

+    Write10Packet->Lba3 = (UINT8) (Lba32 & 0xff);

+    Write10Packet->Lba2 = (UINT8) (Lba32 >> 8);

+    Write10Packet->Lba1 = (UINT8) (Lba32 >> 16);

+    Write10Packet->Lba0 = (UINT8) (Lba32 >> 24);

+

+    //

+    // TranLen0 ~ TranLen1 specify the transfer length in block unit.

+    // TranLen0 is MSB, TranLen is LSB

+    //

+    Write10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);

+    Write10Packet->TranLen0 = (UINT8) (SectorCount >> 8);

+

+    ByteCount               = SectorCount * BlockSize;

+

+    TimeOut                 = (UINT16) (SectorCount * USBFLPTIMEOUT);

+

+    Status = USBFloppyPacketCommand (

+              UsbFloppyDevice,

+              &Packet,

+              sizeof (ATAPI_PACKET_COMMAND),

+              (VOID *) ptrBuffer,

+              ByteCount,

+              EfiUsbDataOut,

+              TimeOut

+              );

+    if (EFI_ERROR (Status)) {

+      Status = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);

+      if (!EFI_ERROR (Status)) {

+        if (IsLogicalUnitCommunicationOverRun (

+              UsbFloppyDevice->SenseData,

+              SenseCounts

+              )) {

+          Lba32           = (UINT32) Lba;

+          ptrBuffer       = Buffer;

+          BlocksRemaining = (UINT16) NumberOfBlocks;

+          MaxBlock        = (UINT16) (MaxBlock / 4);

+          if (MaxBlock < 1) {

+            MaxBlock = 1;

+          }

+

+          continue;

+        }

+      }

+      //

+      // retry write10 command

+      //

+      Status = USBFloppyPacketCommand (

+                UsbFloppyDevice,

+                &Packet,

+                sizeof (ATAPI_PACKET_COMMAND),

+                (VOID *) ptrBuffer,

+                ByteCount,

+                EfiUsbDataOut,

+                TimeOut

+                );

+      if (EFI_ERROR (Status)) {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+

+    Lba32 += SectorCount;

+    ptrBuffer       = (UINT8 *) ptrBuffer + SectorCount * BlockSize;

+    BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+UsbFloppyDetectMedia (

+  IN  USB_FLOPPY_DEV  *UsbFloppyDevice,

+  OUT BOOLEAN         *MediaChange

+  )

+/*++

+

+  Routine Description:

+    Retrieves media information.

+  

+  Arguments:

+    UsbFloppyDevice  -  The USB_FLOPPY_DEV instance.

+    MediaChange      -  Indicates whether media was changed.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+    EFI_INVALID_PARAMETER - Parameter is error

+--*/        

+{

+  EFI_STATUS          Status;

+  EFI_STATUS          FloppyStatus;

+  //

+  // the following variables are used to record previous media information

+  //

+  EFI_BLOCK_IO_MEDIA  OldMediaInfo;

+  UINTN               SenseCounts;

+  UINTN               RetryIndex;

+  UINTN               RetryTimes;

+  UINTN               MaximumRetryTimes;

+  BOOLEAN             NeedRetry;

+

+  //

+  // a flag used to determine whether need to perform Read Capacity command.

+  //

+  BOOLEAN             NeedReadCapacity;

+

+  REQUEST_SENSE_DATA  *SensePtr;

+

+  //

+  // init

+  //

+  Status            = EFI_SUCCESS;

+  FloppyStatus      = EFI_SUCCESS;

+  CopyMem (&OldMediaInfo, UsbFloppyDevice->BlkIo.Media, sizeof (OldMediaInfo));

+  //OldMediaInfo      = *UsbFloppyDevice->BlkIo.Media;

+  *MediaChange      = FALSE;

+  NeedReadCapacity  = TRUE;

+

+  //

+  // if there is no media present,or media not changed,

+  // the request sense command will detect faster than read capacity command.

+  // read capacity command can be bypassed, thus improve performance.

+  //

+  SenseCounts = 0;

+  Status      = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);

+

+  if (!EFI_ERROR (Status)) {

+

+    SensePtr = UsbFloppyDevice->SenseData;

+

+    //

+    // No Media

+    //

+    if (IsNoMedia (UsbFloppyDevice->SenseData, SenseCounts)) {

+

+      NeedReadCapacity = FALSE;

+      UsbFloppyDevice->BlkIo.Media->MediaId = 0;

+      UsbFloppyDevice->BlkIo.Media->MediaPresent = FALSE;

+      UsbFloppyDevice->BlkIo.Media->LastBlock = 0;

+    } else {

+      //

+      // Media Changed

+      //

+      if (IsMediaChange (UsbFloppyDevice->SenseData, SenseCounts)) {

+        UsbFloppyDevice->BlkIo.Media->MediaId++;

+      }

+        

+      //

+      // Media Write-protected

+      //

+      if (IsMediaWriteProtected (UsbFloppyDevice->SenseData, SenseCounts)) {

+        UsbFloppyDevice->BlkIo.Media->ReadOnly = TRUE;

+      }

+        

+      //

+      // Media Error

+      //

+      if (IsMediaError (UsbFloppyDevice->SenseData, SenseCounts)) {

+        //

+        // if media error encountered, make it look like no media present.

+        //

+        UsbFloppyDevice->BlkIo.Media->MediaId       = 0;

+        UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;

+        UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;

+      }

+

+    }

+

+  }

+

+  if (NeedReadCapacity) {

+    //

+    // at most retry 5 times

+    //

+    MaximumRetryTimes = 5;

+    //

+    // initial retry twice

+    //

+    RetryTimes        = 2;

+

+    for (RetryIndex = 0; (RetryIndex < RetryTimes) && (RetryIndex < MaximumRetryTimes); RetryIndex++) {

+      //

+      // Using different command to retrieve media capacity.

+      //

+      switch (UsbFloppyDevice->DeviceType) {

+

+      case USBCDROM:

+        Status = USBFloppyReadCapacity (UsbFloppyDevice);

+        break;

+

+      case USBFLOPPY:

+        UsbMassStorageModeSense (UsbFloppyDevice);

+        Status = USBFloppyReadFormatCapacity (UsbFloppyDevice);

+        if (EFI_ERROR (Status) || !UsbFloppyDevice->BlkMedia.MediaPresent) {

+          //

+          // retry the ReadCapacity command

+          //

+          UsbFloppyDevice->DeviceType = USBFLOPPY2;

+          Status                      = EFI_DEVICE_ERROR;

+        }

+        break;

+

+      case USBFLOPPY2:

+        UsbMassStorageModeSense (UsbFloppyDevice);

+        Status = USBFloppyReadCapacity (UsbFloppyDevice);

+        if (EFI_ERROR (Status)) {

+          //

+          // retry the ReadFormatCapacity command

+          //

+          UsbFloppyDevice->DeviceType = USBFLOPPY;

+        }

+        //

+        // force the BlockSize to be 0x200.

+        //

+        UsbFloppyDevice->BlkIo.Media->BlockSize = 0x200;

+        break;

+

+      default:

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if (!EFI_ERROR (Status)) {

+        //

+        // skip the loop when read capacity succeeds.

+        //

+        break;

+      }

+

+      SenseCounts   = 0;

+

+      FloppyStatus  = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);

+

+      //

+      // If Request Sense data failed,retry.

+      //

+      if (EFI_ERROR (FloppyStatus)) {

+        //

+        // retry once more

+        //

+        RetryTimes++;

+        continue;

+      }

+      //

+      // No Media

+      //

+      if (IsNoMedia (UsbFloppyDevice->SenseData, SenseCounts)) {

+

+        UsbFloppyDevice->BlkIo.Media->MediaId       = 0;

+        UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;

+        UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;

+        break;

+      }

+

+      if (IsMediaError (UsbFloppyDevice->SenseData, SenseCounts)) {

+        //

+        // if media error encountered, make it look like no media present.

+        //

+        UsbFloppyDevice->BlkIo.Media->MediaId       = 0;

+        UsbFloppyDevice->BlkIo.Media->MediaPresent  = FALSE;

+        UsbFloppyDevice->BlkIo.Media->LastBlock     = 0;

+        break;

+      }

+

+      if (IsMediaWriteProtected (UsbFloppyDevice->SenseData, SenseCounts)) {

+        UsbFloppyDevice->BlkIo.Media->ReadOnly = TRUE;

+        continue;

+      }

+

+      if (!IsDriveReady (UsbFloppyDevice->SenseData, SenseCounts, &NeedRetry)) {

+          

+        //

+        // Drive not ready: if NeedRetry, then retry once more;

+        // else return error

+        //

+        if (NeedRetry) {

+          //

+          // Stall 0.1 second to wait for drive becoming ready

+          //

+          gBS->Stall (100 * STALL_1_MILLI_SECOND);

+          //

+          // reset retry variable to zero,

+          // to make it retry for "drive in progress of becoming ready".

+          //

+          RetryIndex = 0;

+          continue;

+        } else {

+          return EFI_DEVICE_ERROR;

+        }

+      }

+      //

+      // if read capacity fail not for above reasons, retry once more

+      //

+      RetryTimes++;

+

+    }

+    //

+    // ENDFOR

+    //

+

+    //

+    // tell whether the readcapacity process is successful or not

+    // ("Status" variable record the latest status returned

+    // by ReadCapacity AND "FloppyStatus" record the latest status

+    // returned by RequestSense)

+    //

+    if (EFI_ERROR (Status) && EFI_ERROR (FloppyStatus)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+  }

+

+  if (UsbFloppyDevice->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {

+

+    if (UsbFloppyDevice->BlkIo.Media->MediaPresent) {

+      UsbFloppyDevice->BlkIo.Media->MediaId = 1;

+    }

+

+    *MediaChange = TRUE;

+  }

+

+  if (UsbFloppyDevice->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {

+    *MediaChange = TRUE;

+    UsbFloppyDevice->BlkIo.Media->MediaId += 1;

+  }

+

+  if (UsbFloppyDevice->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {

+    *MediaChange = TRUE;

+    UsbFloppyDevice->BlkIo.Media->MediaId += 1;

+  }

+

+  if (UsbFloppyDevice->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {

+    *MediaChange = TRUE;

+    UsbFloppyDevice->BlkIo.Media->MediaId += 1;

+  }

+

+  if (UsbFloppyDevice->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {

+    *MediaChange = TRUE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+UsbFloppyModeSense5APage5 (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves media capacity information via sending Read Format 

+    Capacity Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+    

+--*/         

+{ 

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS                Status;

+  ATAPI_PACKET_COMMAND      Packet;

+  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;

+  UFI_MODE_PARAMETER_PAGE_5 ModePage5;

+  EFI_LBA                   LastBlock;

+  UINT32                    SectorsPerTrack;

+  UINT32                    NumberOfCylinders;

+  UINT32                    NumberOfHeads;

+  UINT32                    DataBytesPerSector;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  ZeroMem (&ModePage5, sizeof (UFI_MODE_PARAMETER_PAGE_5));

+

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.ModeSenseUFI.opcode    = UFI_MODE_SENSE5A;

+  //

+  // Flexible Disk Page

+  //

+  Packet.ModeSenseUFI.page_code = 5;

+  //

+  // current values

+  //

+  Packet.ModeSenseUFI.page_control = 0;

+  Packet.ModeSenseUFI.parameter_list_length_hi  = 0;

+  Packet.ModeSenseUFI.parameter_list_length_lo  = sizeof (UFI_MODE_PARAMETER_PAGE_5);

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (ATAPI_PACKET_COMMAND),

+            (VOID *) &ModePage5,

+            sizeof (UFI_MODE_PARAMETER_PAGE_5),

+            EfiUsbDataIn,

+            USBFLPTIMEOUT

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  NumberOfHeads   = ModePage5.flex_disk_page.number_of_heads;

+  SectorsPerTrack = ModePage5.flex_disk_page.sectors_per_track;

+  NumberOfCylinders = ModePage5.flex_disk_page.number_of_cylinders_msb << 8 |

+                      ModePage5.flex_disk_page.number_of_cylinders_lsb;

+

+  LastBlock = SectorsPerTrack * NumberOfHeads * NumberOfCylinders;

+  DataBytesPerSector = ModePage5.flex_disk_page.databytes_per_sector_msb << 8 |

+                       ModePage5.flex_disk_page.databytes_per_sector_lsb;

+

+  UsbFloppyDevice->BlkIo.Media->LastBlock = LastBlock;

+

+  UsbFloppyDevice->BlkIo.Media->LastBlock--;

+

+  UsbFloppyDevice->BlkIo.Media->BlockSize     = DataBytesPerSector;

+

+  UsbFloppyDevice->BlkIo.Media->MediaPresent  = TRUE;

+

+  UsbFloppyDevice->BlkIo.Media->ReadOnly      =

+  ModePage5.mode_param_header.write_protected;

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+UsbFloppyModeSense5APage1C (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves media capacity information via sending Read Format 

+    Capacity Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+    

+--*/         

+{ 

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS                  Status;

+  ATAPI_PACKET_COMMAND        Packet;

+  EFI_USB_ATAPI_PROTOCOL      *UsbAtapiInterface;

+  UFI_MODE_PARAMETER_PAGE_1C  ModePage1C;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  ZeroMem (&ModePage1C, sizeof (UFI_MODE_PARAMETER_PAGE_1C));

+

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.ModeSenseUFI.opcode    = UFI_MODE_SENSE5A;

+  //

+  // Flexible Disk Page

+  //

+  Packet.ModeSenseUFI.page_code = 0x1C;

+  //

+  // current values

+  //

+  Packet.ModeSenseUFI.page_control = 0;

+  Packet.ModeSenseUFI.parameter_list_length_hi  = 0;

+  Packet.ModeSenseUFI.parameter_list_length_lo  = sizeof (UFI_MODE_PARAMETER_PAGE_1C);

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (ATAPI_PACKET_COMMAND),

+            (VOID *) &ModePage1C,

+            sizeof (UFI_MODE_PARAMETER_PAGE_1C),

+            EfiUsbDataIn,

+            USBFLPTIMEOUT

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbFloppyDevice->BlkIo.Media->ReadOnly = ModePage1C.mode_param_header.write_protected;

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+UsbMassStorageModeSense (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+{

+  if (UsbFloppyDevice->AtapiProtocol->CommandProtocol == EFI_USB_SUBCLASS_SCSI) {

+    return UsbSCSIModeSense1APage3F (UsbFloppyDevice);

+  } else {

+    return UsbFloppyModeSense5APage3F (UsbFloppyDevice);

+  }

+}

+

+EFI_STATUS

+UsbFloppyModeSense5APage3F (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves mode sense information via sending Mode Sense

+    Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+

+--*/         

+{ 

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS                Status;

+  ATAPI_PACKET_COMMAND      Packet;

+  EFI_USB_ATAPI_PROTOCOL    *UsbAtapiInterface;

+  UFI_MODE_PARAMETER_HEADER Header;

+  UINT32                    Size;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  Size              = sizeof (UFI_MODE_PARAMETER_HEADER);

+

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.ModeSenseUFI.opcode                    = UFI_MODE_SENSE5A;

+  Packet.ModeSenseUFI.page_code                 = 0x3F;

+  Packet.ModeSenseUFI.page_control              = 0;

+  Packet.ModeSenseUFI.parameter_list_length_hi  = 0;

+  Packet.ModeSenseUFI.parameter_list_length_lo  = (UINT8) Size;

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (ATAPI_PACKET_COMMAND),

+            &Header,

+            Size,

+            EfiUsbDataIn,

+            USBFLPTIMEOUT

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbFloppyDevice->BlkIo.Media->ReadOnly = Header.write_protected;

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+UsbSCSIModeSense1APage3F (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  )

+/*++

+

+  Routine Description:

+    Retrieves mode sense information via sending Mode Sense

+    Packet Command.

+  

+  Arguments:

+    UsbFloppyDevice  - The USB_FLOPPY_DEV instance.

+      

+  Returns:  

+    EFI_DEVICE_ERROR - Hardware error

+    EFI_SUCCESS      - Success

+    

+--*/  

+{ 

+  //

+  // status returned by Read Capacity Packet Command

+  //

+  EFI_STATUS                  Status;

+  ATAPI_PACKET_COMMAND        Packet;

+  EFI_USB_ATAPI_PROTOCOL      *UsbAtapiInterface;

+  SCSI_MODE_PARAMETER_HEADER6 Header;

+  UINT32                      Size;

+

+  UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;

+

+  Size              = sizeof (SCSI_MODE_PARAMETER_HEADER6);

+

+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));

+  Packet.ModeSenseSCSI.opcode             = SCSI_MODE_SENSE1A;

+  Packet.ModeSenseSCSI.page_code          = 0x3F;

+  Packet.ModeSenseSCSI.page_control       = 0;

+  Packet.ModeSenseSCSI.allocation_length  = (UINT8) Size;

+  Status = USBFloppyPacketCommand (

+            UsbFloppyDevice,

+            &Packet,

+            sizeof (MODE_SENSE_CMD_SCSI),

+            &Header,

+            Size,

+            EfiUsbDataIn,

+            USBFLPTIMEOUT

+            );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  UsbFloppyDevice->BlkIo.Media->ReadOnly = Header.write_protected;

+  return EFI_SUCCESS;

+

+}

+

+/*++

+

+  The following functions are a set of helper functions,

+  which are used to parse sense key returned by the device.

+

+--*/

+BOOLEAN

+IsNoMedia (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+{

+  REQUEST_SENSE_DATA  *SensePtr;

+  UINTN               Index;

+  BOOLEAN             NoMedia;

+

+  NoMedia   = FALSE;

+

+  SensePtr  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    if ((SensePtr->sense_key == SK_NOT_READY) && 

+        (SensePtr->addnl_sense_code == ASC_NO_MEDIA)) {

+

+      NoMedia = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return NoMedia;

+}

+

+

+BOOLEAN

+IsMediaError (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+{

+  REQUEST_SENSE_DATA  *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsError;

+

+  IsError   = FALSE;

+  SensePtr  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    switch (SensePtr->sense_key) {

+      

+    //

+    // Medium error case

+    //

+    case SK_MEDIUM_ERROR:

+      switch (SensePtr->addnl_sense_code) {

+

+      case ASC_MEDIA_ERR1:

+      case ASC_MEDIA_ERR2:

+      case ASC_MEDIA_ERR3:

+      case ASC_MEDIA_ERR4:

+        IsError = TRUE;

+        break;

+

+      default:

+        break;

+      }

+

+      break;

+

+    //

+    // Medium upside-down case

+    //

+    case SK_NOT_READY:

+      switch (SensePtr->addnl_sense_code) {

+      case ASC_MEDIA_UPSIDE_DOWN:

+        IsError = TRUE;

+        break;

+

+      default:

+        break;

+      }

+      break;

+

+    default:

+      break;

+    }

+

+    SensePtr++;

+  }

+

+  return IsError;

+}

+

+BOOLEAN

+IsMediaChange (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+{

+  REQUEST_SENSE_DATA  *SensePtr;

+  UINTN               Index;

+  BOOLEAN             MediaChanged;

+

+  MediaChanged  = FALSE;

+  SensePtr      = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    if ((SensePtr->sense_key == SK_UNIT_ATTENTION) &&

+        (SensePtr->addnl_sense_code == ASC_MEDIA_CHANGE)) {

+

+      MediaChanged = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return MediaChanged;

+}

+

+BOOLEAN

+IsDriveReady (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts,

+  OUT BOOLEAN               *NeedRetry

+  )

+{

+  REQUEST_SENSE_DATA  *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsReady;

+

+  IsReady     = TRUE;

+  *NeedRetry  = FALSE;

+  SensePtr    = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    if ((SensePtr->sense_key == SK_NOT_READY) &&

+        (SensePtr->addnl_sense_code == ASC_NOT_READY)) {

+

+      switch (SensePtr->addnl_sense_code_qualifier) {

+

+      case ASCQ_IN_PROGRESS:

+      case ASCQ_DEVICE_BUSY:

+        IsReady     = FALSE;

+        *NeedRetry  = TRUE;

+        break;

+

+      default:

+        //

+        // Drive is in error condition,

+        // no need to retry.

+        //

+        IsReady     = FALSE;

+        *NeedRetry  = FALSE;

+        break;

+      }

+    }

+

+    SensePtr++;

+  }

+

+  return IsReady;

+}

+

+BOOLEAN

+IsMediaWriteProtected (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+{

+  REQUEST_SENSE_DATA  *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsWriteProtected;

+

+  IsWriteProtected  = FALSE;

+  SensePtr          = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+    //

+    // catch media write-protected condition.

+    //

+    if ((SensePtr->sense_key == SK_DATA_PROTECT) &&

+        (SensePtr->addnl_sense_code == ASC_WRITE_PROTECTED)) {

+

+      IsWriteProtected = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return IsWriteProtected;

+}

+

+BOOLEAN

+IsLogicalUnitCommunicationOverRun (

+  IN  REQUEST_SENSE_DATA    *SenseData,

+  IN  UINTN                 SenseCounts

+  )

+{

+  REQUEST_SENSE_DATA  *SensePtr;

+  UINTN               Index;

+  BOOLEAN             IsOverRun;

+

+  IsOverRun = FALSE;

+  SensePtr  = SenseData;

+

+  for (Index = 0; Index < SenseCounts; Index++) {

+

+    if ((SensePtr->sense_key == SK_NOT_READY) &&

+        (SensePtr->addnl_sense_code == ASC_LOGICAL_UNIT_STATUS) &&

+        (SensePtr->addnl_sense_code_qualifier == ASCQ_LOGICAL_UNIT_OVERRUN)) {

+      IsOverRun = TRUE;

+    }

+

+    SensePtr++;

+  }

+

+  return IsOverRun;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageHelper.h b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageHelper.h
new file mode 100644
index 0000000..f41241a
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/UsbMassStorageHelper.h
@@ -0,0 +1,111 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    UsbMassStorageHelper.h

+

+Abstract:

+

+    Function prototype for USB Mass Storage Driver

+

+Revision History

+--*/

+#ifndef _USB_FLPHLP_H

+#define _USB_FLPHLP_H

+

+#include "UsbMassStorage.h"

+

+EFI_STATUS

+USBFloppyIdentify (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+USBFloppyPacketCommand (

+  USB_FLOPPY_DEV            *UsbFloppyDevice,

+  VOID                      *Command,

+  UINT8                     CommandSize,

+  VOID                      *DataBuffer,

+  UINT32                    BufferLength,

+  EFI_USB_DATA_DIRECTION    Direction,

+  UINT16                    TimeOutInMilliSeconds

+  );

+

+EFI_STATUS

+USBFloppyInquiry (

+  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,

+  OUT   USB_INQUIRY_DATA  **Idata

+  );

+

+EFI_STATUS

+USBFloppyRead10 (

+  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,

+  IN    VOID              *Buffer,

+  IN    EFI_LBA           Lba,

+  IN    UINTN             NumberOfBlocks

+  );

+

+EFI_STATUS

+USBFloppyReadFormatCapacity (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+UsbFloppyRequestSense (

+  IN  USB_FLOPPY_DEV  *UsbFloppyDevice,

+  OUT UINTN           *SenseCounts

+  );

+

+EFI_STATUS

+UsbFloppyTestUnitReady (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+USBFloppyWrite10 (

+  IN    USB_FLOPPY_DEV    *UsbFloppyDevice,

+  IN    VOID              *Buffer,

+  IN    EFI_LBA           Lba,

+  IN    UINTN             NumberOfBlocks

+  );

+

+EFI_STATUS

+UsbFloppyDetectMedia (

+  IN  USB_FLOPPY_DEV  *UsbFloppyDevice,

+  OUT BOOLEAN         *MediaChange

+  );

+

+EFI_STATUS

+UsbFloppyModeSense5APage5 (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+UsbFloppyModeSense5APage1C (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+UsbFloppyModeSense5APage3F (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+UsbSCSIModeSense1APage3F (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+EFI_STATUS

+UsbMassStorageModeSense (

+  IN  USB_FLOPPY_DEV    *UsbFloppyDevice

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/build.xml
new file mode 100644
index 0000000..3d98316
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMassStorage/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbMassStorage"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbMassStorage/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbMassStorage">

+      <GenBuild baseName="UsbMassStorage" mbdFilename="${MODULE_DIR}/UsbMassStorage.mbd" msaFilename="${MODULE_DIR}/UsbMassStorage.msa"/>

+   </target>

+   <target depends="UsbMassStorage_clean" name="clean"/>

+   <target depends="UsbMassStorage_cleanall" name="cleanall"/>

+   <target name="UsbMassStorage_clean">

+      <OutputDirSetup baseName="UsbMassStorage" mbdFilename="${MODULE_DIR}/UsbMassStorage.mbd" msaFilename="${MODULE_DIR}/UsbMassStorage.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbMassStorage_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbMassStorage_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbMassStorage_cleanall">

+      <OutputDirSetup baseName="UsbMassStorage" mbdFilename="${MODULE_DIR}/UsbMassStorage.mbd" msaFilename="${MODULE_DIR}/UsbMassStorage.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbMassStorage_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbMassStorage_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbMassStorage*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/ComponentName.c b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/ComponentName.c
new file mode 100644
index 0000000..5b01cea
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/ComponentName.c
@@ -0,0 +1,216 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "usbmouse.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+UsbMouseComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+UsbMouseComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gUsbMouseComponentName = {

+  UsbMouseComponentNameGetDriverName,

+  UsbMouseComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mUsbMouseDriverNameTable[] = {

+  { "eng", (CHAR16 *) L"Usb Mouse Driver" },

+  { NULL , NULL }

+};

+

+

+EFI_STATUS

+EFIAPI

+UsbMouseComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gUsbMouseComponentName.SupportedLanguages,

+          mUsbMouseDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+UsbMouseComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  USB_MOUSE_DEV               *UsbMouseDev;

+  EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;

+  EFI_USB_IO_PROTOCOL         *UsbIoProtocol;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Check Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIoProtocol,

+                  gUsbMouseDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiUsbIoProtocolGuid,

+          gUsbMouseDriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get the device context

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimplePointerProtocolGuid,

+                  (VOID **) &SimplePointerProtocol,

+                  gUsbMouseDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  UsbMouseDev = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol);

+

+  return LookupUnicodeString (

+          Language,

+          gUsbMouseComponentName.SupportedLanguages,

+          UsbMouseDev->ControllerNameTable,

+          ControllerName

+          );

+

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/UsbMouse.mbd b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/UsbMouse.mbd
new file mode 100644
index 0000000..88b3e47
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/UsbMouse.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>UsbMouse</BaseName>

+    <Guid>2D2E62AA-9ECF-43b7-8219-94E7FC713DFE</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>EdkUsbLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/UsbMouse.msa b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/UsbMouse.msa
new file mode 100644
index 0000000..526c21c
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/UsbMouse.msa
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>UsbMouse</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>2D2E62AA-9ECF-43b7-8219-94E7FC713DFE</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbMouse module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>usbmouse.h</Filename>

+    <Filename>usbmouse.c</Filename>

+    <Filename>mousehid.h</Filename>

+    <Filename>mousehid.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">UsbIo</Protocol>

+    <Protocol Usage="BY_START">SimplePointer</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gUsbMouseDriverBinding</DriverBinding>

+      <ComponentName>gUsbMouseComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/build.xml b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/build.xml
new file mode 100644
index 0000000..3ce60ca
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UsbMouse"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Bus/Usb/UsbMouse/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UsbMouse">

+      <GenBuild baseName="UsbMouse" mbdFilename="${MODULE_DIR}/UsbMouse.mbd" msaFilename="${MODULE_DIR}/UsbMouse.msa"/>

+   </target>

+   <target depends="UsbMouse_clean" name="clean"/>

+   <target depends="UsbMouse_cleanall" name="cleanall"/>

+   <target name="UsbMouse_clean">

+      <OutputDirSetup baseName="UsbMouse" mbdFilename="${MODULE_DIR}/UsbMouse.mbd" msaFilename="${MODULE_DIR}/UsbMouse.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbMouse_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbMouse_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UsbMouse_cleanall">

+      <OutputDirSetup baseName="UsbMouse" mbdFilename="${MODULE_DIR}/UsbMouse.mbd" msaFilename="${MODULE_DIR}/UsbMouse.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UsbMouse_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UsbMouse_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UsbMouse*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/mousehid.c b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/mousehid.c
new file mode 100644
index 0000000..cbe0970
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/mousehid.c
@@ -0,0 +1,395 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Mousehid.c

+

+Abstract:

+  Parse mouse hid descriptor

+

+--*/

+

+#include "usbmouse.h"

+#include "mousehid.h"

+

+//

+// Get an item from report descriptor

+//

+STATIC

+UINT8 *

+GetNextItem (

+  IN  UINT8    *StartPos,

+  IN  UINT8    *EndPos,

+  OUT HID_ITEM *HidItem

+  )

+/*++

+

+Routine Description:

+

+  Get Next Item

+

+Arguments:

+

+  StartPos  - Start Position

+  EndPos    - End Position

+  HidItem   - HidItem to return

+

+Returns:

+  Position

+

+--*/

+{

+  UINT8 Temp;

+

+  if ((EndPos - StartPos) <= 0) {

+    return NULL;

+  }

+

+  Temp = *StartPos;

+  StartPos++;

+  //

+  // bit 2,3

+  //

+  HidItem->Type = (UINT8) ((Temp >> 2) & 0x03);

+  //

+  // bit 4-7

+  //

+  HidItem->Tag = (UINT8) ((Temp >> 4) & 0x0F);

+

+  if (HidItem->Tag == HID_ITEM_TAG_LONG) {

+    //

+    // Long Items are not supported by HID rev1.0,

+    // although we try to parse it.

+    //

+    HidItem->Format = HID_ITEM_FORMAT_LONG;

+

+    if ((EndPos - StartPos) >= 2) {

+      HidItem->Size = *StartPos++;

+      HidItem->Tag  = *StartPos++;

+

+      if ((EndPos - StartPos) >= HidItem->Size) {

+        HidItem->Data.LongData = StartPos;

+        StartPos += HidItem->Size;

+        return StartPos;

+      }

+    }

+  } else {

+    HidItem->Format = HID_ITEM_FORMAT_SHORT;

+    //

+    // bit 0, 1

+    //

+    HidItem->Size   = (UINT8) (Temp & 0x03);

+    switch (HidItem->Size) {

+

+    case 0:

+      //

+      // No data

+      //

+      return StartPos;

+

+    case 1:

+      //

+      // One byte data

+      //

+      if ((EndPos - StartPos) >= 1) {

+        HidItem->Data.U8 = *StartPos++;

+        return StartPos;

+      }

+

+    case 2:

+      //

+      // Two byte data

+      //

+      if ((EndPos - StartPos) >= 2) {

+        CopyMem (&HidItem->Data.U16, StartPos, sizeof (UINT16));

+        StartPos += 2;

+        return StartPos;

+      }

+

+    case 3:

+      //

+      // 4 byte data, adjust size

+      //

+      HidItem->Size++;

+      if ((EndPos - StartPos) >= 4) {

+        CopyMem (&HidItem->Data.U32, StartPos, sizeof (UINT32));

+        StartPos += 4;

+        return StartPos;

+      }

+    }

+  }

+

+  return NULL;

+}

+

+STATIC

+UINT32

+GetItemData (

+  IN  HID_ITEM *HidItem

+  )

+/*++

+

+Routine Description:

+

+  Get Item Data

+

+Arguments:

+

+  HidItem - HID_ITEM

+

+Returns:

+  HidItem Data

+  

+

+--*/

+{

+  //

+  // Get Data from HID_ITEM structure

+  //

+  switch (HidItem->Size) {

+

+  case 1:

+    return HidItem->Data.U8;

+

+  case 2:

+    return HidItem->Data.U16;

+

+  case 4:

+    return HidItem->Data.U32;

+  }

+

+  return 0;

+}

+

+STATIC

+VOID

+ParseLocalItem (

+  IN  USB_MOUSE_DEV   *UsbMouse,

+  IN  HID_ITEM        *LocalItem

+  )

+/*++

+

+Routine Description:

+

+  Parse Local Item

+

+Arguments:

+

+  UsbMouse  - USB_MOUSE_DEV

+  LocalItem - Local Item

+

+Returns:

+

+--*/

+{

+  UINT32  Data;

+

+  if (LocalItem->Size == 0) {

+    //

+    // No expected data for local item

+    //

+    return ;

+  }

+

+  Data = GetItemData (LocalItem);

+

+  switch (LocalItem->Tag) {

+

+  case HID_LOCAL_ITEM_TAG_DELIMITER:

+    //

+    // we don't support delimiter here

+    //

+    return ;

+

+  case HID_LOCAL_ITEM_TAG_USAGE:

+    return ;

+

+  case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:

+    if (UsbMouse->PrivateData.ButtonDetected) {

+      UsbMouse->PrivateData.ButtonMinIndex = (UINT8) Data;

+    }

+

+    return ;

+

+  case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:

+    {

+      if (UsbMouse->PrivateData.ButtonDetected) {

+        UsbMouse->PrivateData.ButtonMaxIndex = (UINT8) Data;

+      }

+

+      return ;

+    }

+  }

+}

+

+STATIC

+VOID

+ParseGlobalItem (

+  IN  USB_MOUSE_DEV   *UsbMouse,

+  IN  HID_ITEM        *GlobalItem

+  )

+{

+  UINT8 UsagePage;

+

+  switch (GlobalItem->Tag) {

+  case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:

+    {

+      UsagePage = (UINT8) GetItemData (GlobalItem);

+

+      //

+      // We only care Button Page here

+      //

+      if (UsagePage == 0x09) {

+        //

+        // Button Page

+        //

+        UsbMouse->PrivateData.ButtonDetected = TRUE;

+        return ;

+      }

+      break;

+    }

+

+  }

+}

+

+

+STATIC

+VOID

+ParseMainItem (

+  IN  USB_MOUSE_DEV   *UsbMouse,

+  IN  HID_ITEM        *MainItem

+  )

+/*++

+

+Routine Description:

+

+  Parse Main Item

+

+Arguments:

+

+  UsbMouse  - TODO: add argument description

+  MainItem  - HID_ITEM to parse

+

+Returns:

+

+  VOID

+

+--*/

+{

+  //

+  // we don't care any main items, just skip

+  //

+  return ;

+}

+

+STATIC

+VOID

+ParseHidItem (

+  IN  USB_MOUSE_DEV   *UsbMouse,

+  IN  HID_ITEM        *HidItem

+  )

+/*++

+

+Routine Description:

+

+  Parse Hid Item

+

+Arguments:

+

+  UsbMouse  - USB_MOUSE_DEV

+  HidItem   - HidItem to parse

+

+Returns:

+

+  VOID

+

+--*/

+{

+  switch (HidItem->Type) {

+

+  case HID_ITEM_TYPE_MAIN:

+    //

+    // For Main Item, parse main item

+    //

+    ParseMainItem (UsbMouse, HidItem);

+    break;

+

+  case HID_ITEM_TYPE_GLOBAL:

+    //

+    // For global Item, parse global item

+    //

+    ParseGlobalItem (UsbMouse, HidItem);

+    break;

+

+  case HID_ITEM_TYPE_LOCAL:

+    //

+    // For Local Item, parse local item

+    //

+    ParseLocalItem (UsbMouse, HidItem);

+    break;

+  }

+}

+//

+// A simple parse just read some field we are interested in

+//

+EFI_STATUS

+ParseMouseReportDescriptor (

+  IN  USB_MOUSE_DEV   *UsbMouse,

+  IN  UINT8           *ReportDescriptor,

+  IN  UINTN           ReportSize

+  )

+/*++

+

+Routine Description:

+

+  Parse Mouse Report Descriptor

+

+Arguments:

+

+  UsbMouse          - USB_MOUSE_DEV

+  ReportDescriptor  - Report descriptor to parse

+  ReportSize        - Report descriptor size

+

+Returns:

+

+  EFI_DEVICE_ERROR - Report descriptor error

+  EFI_SUCCESS      - Success

+

+--*/

+{

+  UINT8     *DescriptorEnd;

+  UINT8     *ptr;

+  HID_ITEM  HidItem;

+

+  DescriptorEnd = ReportDescriptor + ReportSize;

+

+  ptr           = GetNextItem (ReportDescriptor, DescriptorEnd, &HidItem);

+

+  while (ptr != NULL) {

+    if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {

+      //

+      // Long Format Item is not supported at current HID revision

+      //

+      return EFI_DEVICE_ERROR;

+    }

+

+    ParseHidItem (UsbMouse, &HidItem);

+

+    ptr = GetNextItem (ptr, DescriptorEnd, &HidItem);

+  }

+

+  UsbMouse->NumberOfButtons                 = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);

+  UsbMouse->XLogicMax                       = UsbMouse->YLogicMax = 127;

+  UsbMouse->XLogicMin                       = UsbMouse->YLogicMin = -127;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/mousehid.h b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/mousehid.h
new file mode 100644
index 0000000..ccce835
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/mousehid.h
@@ -0,0 +1,84 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MouseHid.h

+

+Abstract:

+

+--*/

+

+#ifndef __MOUSE_HID_H

+#define __MOUSE_HID_H

+

+#include "usbmouse.h"

+

+//

+// HID Item general structure

+//

+typedef struct _hid_item {

+  UINT16  Format;

+  UINT8   Size;

+  UINT8   Type;

+  UINT8   Tag;

+  union {

+    UINT8   U8;

+    UINT16  U16;

+    UINT32  U32;

+    INT8    I8;

+    INT16   I16;

+    INT32   I32;

+    UINT8   *LongData;

+  } Data;

+} HID_ITEM;

+

+typedef struct {

+  UINT16  UsagePage;

+  INT32   LogicMin;

+  INT32   LogicMax;

+  INT32   PhysicalMin;

+  INT32   PhysicalMax;

+  UINT16  UnitExp;

+  UINT16 UINT;

+  UINT16 ReportId;

+  UINT16 ReportSize;

+  UINT16 ReportCount;

+} HID_GLOBAL;

+

+typedef struct {

+  UINT16  Usage[16];  /* usage array */

+  UINT16  UsageIndex;

+  UINT16  UsageMin;

+} HID_LOCAL;

+

+typedef struct {

+  UINT16  Type;

+  UINT16  Usage;

+} HID_COLLECTION;

+

+typedef struct {

+  HID_GLOBAL      Global;

+  HID_GLOBAL      GlobalStack[8];

+  UINT32          GlobalStackPtr;

+  HID_LOCAL       Local;

+  HID_COLLECTION  CollectionStack[8];

+  UINT32          CollectionStackPtr;

+} HID_PARSER;

+

+EFI_STATUS

+ParseMouseReportDescriptor (

+  IN  USB_MOUSE_DEV   *UsbMouse,

+  IN  UINT8           *ReportDescriptor,

+  IN  UINTN           ReportSize

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/usbmouse.c b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/usbmouse.c
new file mode 100644
index 0000000..81da020
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/usbmouse.c
@@ -0,0 +1,1028 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    UsbMouse.c

+

+  Abstract:

+

+--*/

+

+#include "usbmouse.h"

+#include "mousehid.h"

+

+//

+// Prototypes

+// Driver model protocol interface

+//

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  );

+

+

+EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding = {

+  USBMouseDriverBindingSupported,

+  USBMouseDriverBindingStart,

+  USBMouseDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+//

+// helper functions

+//

+STATIC

+BOOLEAN

+IsUsbMouse (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo

+  );

+

+STATIC

+EFI_STATUS

+InitializeUsbMouseDevice (

+  IN  USB_MOUSE_DEV           *UsbMouseDev

+  );

+

+STATIC

+VOID

+EFIAPI

+UsbMouseWaitForInput (

+  IN  EFI_EVENT               Event,

+  IN  VOID                    *Context

+  );

+

+//

+// Mouse interrupt handler

+//

+STATIC

+EFI_STATUS

+EFIAPI

+OnMouseInterruptComplete (

+  IN  VOID        *Data,

+  IN  UINTN       DataLength,

+  IN  VOID        *Context,

+  IN  UINT32      Result

+  );

+

+//

+// Mouse Protocol

+//

+STATIC

+EFI_STATUS

+EFIAPI

+GetMouseState (

+  IN   EFI_SIMPLE_POINTER_PROTOCOL  *This,

+  OUT  EFI_SIMPLE_POINTER_STATE     *MouseState

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbMouseReset (

+  IN EFI_SIMPLE_POINTER_PROTOCOL    *This,

+  IN BOOLEAN                        ExtendedVerification

+  );

+

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    that has UsbHcProtocol installed will be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller         - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS          OpenStatus;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  EFI_STATUS          Status;

+

+  OpenStatus = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiUsbIoProtocolGuid,

+                      (VOID **) &UsbIo,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (OpenStatus == EFI_ALREADY_STARTED) {

+    return EFI_ALREADY_STARTED;

+  }

+  

+  //

+  // Use the USB I/O protocol interface to see the Controller is

+  // the Mouse controller that can be managed by this driver.

+  //

+  Status = EFI_SUCCESS;

+  if (!IsUsbMouse (UsbIo)) {

+    Status = EFI_UNSUPPORTED;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Starting the Usb Bus Driver

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_UNSUPPORTED     - This driver does not support this device.

+    EFI_DEVICE_ERROR    - This driver cannot be started due to device

+                          Error

+    EFI_OUT_OF_RESOURCES- Can't allocate memory resources

+    EFI_ALREADY_STARTED - Thios driver has been started

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_USB_IO_PROTOCOL         *UsbIo;

+  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc;

+  USB_MOUSE_DEV               *UsbMouseDevice;

+  UINT8                       EndpointNumber;

+  UINT8                       Index;

+  UINT8                       EndpointAddr;

+  UINT8                       PollingInterval;

+  UINT8                       PacketSize;

+

+  UsbMouseDevice  = NULL;

+  Status          = EFI_SUCCESS;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiUsbIoProtocolGuid,

+                  (VOID **) &UsbIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  UsbMouseDevice = AllocateZeroPool (sizeof (USB_MOUSE_DEV));

+  if (UsbMouseDevice == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto ErrorExit;

+  }

+

+  UsbMouseDevice->UsbIo               = UsbIo;

+

+  UsbMouseDevice->Signature           = USB_MOUSE_DEV_SIGNATURE;

+

+  UsbMouseDevice->InterfaceDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR));

+  if (UsbMouseDevice->InterfaceDescriptor == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto ErrorExit;

+  }

+

+  EndpointDesc = AllocatePool (sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));

+  if (EndpointDesc == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto ErrorExit;

+  }

+  //

+  // Get the Device Path Protocol on Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &UsbMouseDevice->DevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+  //

+  // Get interface & endpoint descriptor

+  //

+  UsbIo->UsbGetInterfaceDescriptor (

+          UsbIo,

+          UsbMouseDevice->InterfaceDescriptor

+          );

+

+  EndpointNumber = UsbMouseDevice->InterfaceDescriptor->NumEndpoints;

+

+  for (Index = 0; Index < EndpointNumber; Index++) {

+    UsbIo->UsbGetEndpointDescriptor (

+            UsbIo,

+            Index,

+            EndpointDesc

+            );

+

+    if ((EndpointDesc->Attributes & 0x03) == 0x03) {

+

+      //

+      // We only care interrupt endpoint here

+      //

+      UsbMouseDevice->IntEndpointDescriptor = EndpointDesc;

+    }

+  }

+

+  if (UsbMouseDevice->IntEndpointDescriptor == NULL) {

+    //

+    // No interrupt endpoint, then error

+    //

+    Status = EFI_UNSUPPORTED;

+    goto ErrorExit;

+  }

+

+  Status = InitializeUsbMouseDevice (UsbMouseDevice);

+  if (EFI_ERROR (Status)) {

+    MouseReportStatusCode (

+      UsbMouseDevice->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR)

+      );

+

+    goto ErrorExit;

+  }

+

+  UsbMouseDevice->SimplePointerProtocol.GetState  = GetMouseState;

+  UsbMouseDevice->SimplePointerProtocol.Reset     = UsbMouseReset;

+  UsbMouseDevice->SimplePointerProtocol.Mode      = &UsbMouseDevice->Mode;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  UsbMouseWaitForInput,

+                  UsbMouseDevice,

+                  &((UsbMouseDevice->SimplePointerProtocol).WaitForInput)

+                  );

+  if (EFI_ERROR (Status)) {

+    goto ErrorExit;

+  }

+

+  Status = gBS->InstallProtocolInterface (

+                  &Controller,

+                  &gEfiSimplePointerProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &UsbMouseDevice->SimplePointerProtocol

+                  );

+

+  if (EFI_ERROR (Status)) {

+    Status = EFI_DEVICE_ERROR;

+    goto ErrorExit;

+  }

+  

+  //

+  // After Enabling Async Interrupt Transfer on this mouse Device

+  // we will be able to get key data from it. Thus this is deemed as

+  // the enable action of the mouse

+  //

+  

+  MouseReportStatusCode (

+    UsbMouseDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE)

+    );

+

+  //

+  // submit async interrupt transfer

+  //

+  EndpointAddr    = UsbMouseDevice->IntEndpointDescriptor->EndpointAddress;

+  PollingInterval = UsbMouseDevice->IntEndpointDescriptor->Interval;

+  PacketSize      = (UINT8) (UsbMouseDevice->IntEndpointDescriptor->MaxPacketSize);

+

+  Status = UsbIo->UsbAsyncInterruptTransfer (

+                    UsbIo,

+                    EndpointAddr,

+                    TRUE,

+                    PollingInterval,

+                    PacketSize,

+                    OnMouseInterruptComplete,

+                    UsbMouseDevice

+                    );

+

+  if (!EFI_ERROR (Status)) {

+

+    UsbMouseDevice->ControllerNameTable = NULL;

+    AddUnicodeString (

+      "eng",

+      gUsbMouseComponentName.SupportedLanguages,

+      &UsbMouseDevice->ControllerNameTable,

+      (CHAR16 *) L"Generic Usb Mouse"

+      );

+

+    return EFI_SUCCESS;

+  }

+

+  //

+  // If submit error, uninstall that interface

+  //

+  Status = EFI_DEVICE_ERROR;

+  gBS->UninstallProtocolInterface (

+        Controller,

+        &gEfiSimplePointerProtocolGuid,

+        &UsbMouseDevice->SimplePointerProtocol

+        );

+

+ErrorExit:

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUsbIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    if (UsbMouseDevice != NULL) {

+      if (UsbMouseDevice->InterfaceDescriptor != NULL) {

+        gBS->FreePool (UsbMouseDevice->InterfaceDescriptor);

+      }

+

+      if (UsbMouseDevice->IntEndpointDescriptor != NULL) {

+        gBS->FreePool (UsbMouseDevice->IntEndpointDescriptor);

+      }

+

+      if ((UsbMouseDevice->SimplePointerProtocol).WaitForInput != NULL) {

+        gBS->CloseEvent ((UsbMouseDevice->SimplePointerProtocol).WaitForInput);

+      }

+

+      gBS->FreePool (UsbMouseDevice);

+      UsbMouseDevice = NULL;

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+USBMouseDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    Controller        - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    others

+

+--*/

+{

+  EFI_STATUS                  Status;

+  USB_MOUSE_DEV               *UsbMouseDevice;

+  EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;

+  EFI_USB_IO_PROTOCOL         *UsbIo;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSimplePointerProtocolGuid,

+                  (VOID **) &SimplePointerProtocol,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  UsbMouseDevice = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol);

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiSimplePointerProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  UsbIo = UsbMouseDevice->UsbIo;

+

+  //

+  // Uninstall the Asyn Interrupt Transfer from this device

+  // will disable the mouse data input from this device

+  //

+  MouseReportStatusCode (

+    UsbMouseDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE)

+    );

+

+  //

+  // Delete Mouse Async Interrupt Transfer

+  //

+  UsbIo->UsbAsyncInterruptTransfer (

+          UsbIo,

+          UsbMouseDevice->IntEndpointDescriptor->EndpointAddress,

+          FALSE,

+          UsbMouseDevice->IntEndpointDescriptor->Interval,

+          0,

+          NULL,

+          NULL

+          );

+

+  gBS->CloseEvent (UsbMouseDevice->SimplePointerProtocol.WaitForInput);

+

+  if (UsbMouseDevice->DelayedRecoveryEvent) {

+    gBS->CloseEvent (UsbMouseDevice->DelayedRecoveryEvent);

+    UsbMouseDevice->DelayedRecoveryEvent = 0;

+  }

+

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiSimplePointerProtocolGuid,

+                  &UsbMouseDevice->SimplePointerProtocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUsbIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  gBS->FreePool (UsbMouseDevice->InterfaceDescriptor);

+  gBS->FreePool (UsbMouseDevice->IntEndpointDescriptor);

+

+  if (UsbMouseDevice->ControllerNameTable) {

+    FreeUnicodeStringTable (UsbMouseDevice->ControllerNameTable);

+  }

+

+  gBS->FreePool (UsbMouseDevice);

+

+  return EFI_SUCCESS;

+

+}

+

+BOOLEAN

+IsUsbMouse (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo

+  )

+/*++

+

+  Routine Description:

+    Tell if a Usb Controller is a mouse

+

+  Arguments:

+    UsbIo              - Protocol instance pointer.

+

+  Returns:

+    TRUE              - It is a mouse

+    FALSE             - It is not a mouse

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+

+  //

+  // Get the Default interface descriptor, now we only

+  // suppose it is interface 1

+  //

+  Status = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  if ((InterfaceDescriptor.InterfaceClass == CLASS_HID) &&

+      (InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT) &&

+      (InterfaceDescriptor.InterfaceProtocol == PROTOCOL_MOUSE)

+      ) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+STATIC

+EFI_STATUS

+InitializeUsbMouseDevice (

+  IN  USB_MOUSE_DEV           *UsbMouseDev

+  )

+/*++

+

+  Routine Description:

+    Initialize the Usb Mouse Device.

+

+  Arguments:

+    UsbMouseDev         - Device instance to be initialized

+

+  Returns:

+    EFI_SUCCESS         - Success

+    EFI_DEVICE_ERROR    - Init error.

+    EFI_OUT_OF_RESOURCES- Can't allocate memory

+--*/

+{

+  EFI_USB_IO_PROTOCOL     *UsbIo;

+  UINT8                   Protocol;

+  EFI_STATUS              Status;

+  EFI_USB_HID_DESCRIPTOR  MouseHidDesc;

+  UINT8                   *ReportDesc;

+

+  UsbIo = UsbMouseDev->UsbIo;

+

+  //

+  // Get HID descriptor

+  //

+  Status = UsbGetHidDescriptor (

+            UsbIo,

+            UsbMouseDev->InterfaceDescriptor->InterfaceNumber,

+            &MouseHidDesc

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get Report descriptor

+  //

+  if (MouseHidDesc.HidClassDesc[0].DescriptorType != 0x22) {

+    return EFI_UNSUPPORTED;

+  }

+

+  ReportDesc = AllocateZeroPool (MouseHidDesc.HidClassDesc[0].DescriptorLength);

+  if (ReportDesc == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = UsbGetReportDescriptor (

+            UsbIo,

+            UsbMouseDev->InterfaceDescriptor->InterfaceNumber,

+            MouseHidDesc.HidClassDesc[0].DescriptorLength,

+            ReportDesc

+            );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (ReportDesc);

+    return Status;

+  }

+

+  //

+  // Parse report descriptor

+  //

+  Status = ParseMouseReportDescriptor (

+            UsbMouseDev,

+            ReportDesc,

+            MouseHidDesc.HidClassDesc[0].DescriptorLength

+            );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (ReportDesc);

+    return Status;

+  }

+

+  if (UsbMouseDev->NumberOfButtons >= 1) {

+    UsbMouseDev->Mode.LeftButton = TRUE;

+  }

+

+  if (UsbMouseDev->NumberOfButtons > 1) {

+    UsbMouseDev->Mode.RightButton = TRUE;

+  }

+

+  UsbMouseDev->Mode.ResolutionX = 8;

+  UsbMouseDev->Mode.ResolutionY = 8;

+  UsbMouseDev->Mode.ResolutionZ = 0;

+  //

+  // Here we just assume interface 0 is the mouse interface

+  //

+  UsbGetProtocolRequest (

+    UsbIo,

+    0,

+    &Protocol

+    );

+

+  if (Protocol != BOOT_PROTOCOL) {

+    Status = UsbSetProtocolRequest (

+              UsbIo,

+              0,

+              BOOT_PROTOCOL

+              );

+

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (ReportDesc);

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  //

+  // Set indefinite Idle rate for USB Mouse

+  //

+  UsbSetIdleRequest (

+    UsbIo,

+    0,

+    0,

+    0

+    );

+

+  gBS->FreePool (ReportDesc);

+

+  if (UsbMouseDev->DelayedRecoveryEvent) {

+    gBS->CloseEvent (UsbMouseDev->DelayedRecoveryEvent);

+    UsbMouseDev->DelayedRecoveryEvent = 0;

+  }

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_NOTIFY,

+                  USBMouseRecoveryHandler,

+                  UsbMouseDev,

+                  &UsbMouseDev->DelayedRecoveryEvent

+                  );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+OnMouseInterruptComplete (

+  IN  VOID        *Data,

+  IN  UINTN       DataLength,

+  IN  VOID        *Context,

+  IN  UINT32      Result

+  )

+/*++

+

+  Routine Description:

+    It is called whenever there is data received from async interrupt

+    transfer.

+

+  Arguments:

+    Data            - Data received.

+    DataLength      - Length of Data

+    Context         - Passed in context

+    Result          - Async Interrupt Transfer result

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+

+--*/

+{

+  USB_MOUSE_DEV       *UsbMouseDevice;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+  UINT8               EndpointAddr;

+  UINT32              UsbResult;

+

+  UsbMouseDevice  = (USB_MOUSE_DEV *) Context;

+  UsbIo           = UsbMouseDevice->UsbIo;

+

+  if (Result != EFI_USB_NOERROR) {

+    //

+    // Some errors happen during the process

+    //

+    MouseReportStatusCode (

+      UsbMouseDevice->DevicePath,

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR)

+      );

+

+    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {

+      EndpointAddr = UsbMouseDevice->IntEndpointDescriptor->EndpointAddress;

+

+      UsbClearEndpointHalt (

+        UsbIo,

+        EndpointAddr,

+        &UsbResult

+        );

+    }

+

+    UsbIo->UsbAsyncInterruptTransfer (

+            UsbIo,

+            UsbMouseDevice->IntEndpointDescriptor->EndpointAddress,

+            FALSE,

+            0,

+            0,

+            NULL,

+            NULL

+            );

+

+    gBS->SetTimer (

+          UsbMouseDevice->DelayedRecoveryEvent,

+          TimerRelative,

+          EFI_USB_INTERRUPT_DELAY

+          );

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (DataLength == 0 || Data == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  UsbMouseDevice->StateChanged = TRUE;

+

+  //

+  // Check mouse Data

+  //

+  UsbMouseDevice->State.LeftButton  = (BOOLEAN) (*(UINT8 *) Data & 0x01);

+  UsbMouseDevice->State.RightButton = (BOOLEAN) (*(UINT8 *) Data & 0x02);

+  UsbMouseDevice->State.RelativeMovementX += *((INT8 *) Data + 1);

+  UsbMouseDevice->State.RelativeMovementY += *((INT8 *) Data + 2);

+

+  if (DataLength > 3) {

+    UsbMouseDevice->State.RelativeMovementZ += *((INT8 *) Data + 3);

+  }

+

+  return EFI_SUCCESS;

+}

+

+/*

+STATIC VOID

+PrintMouseState(

+    IN  EFI_MOUSE_STATE *MouseState

+    )

+{

+    Aprint("(%x: %x, %x)\n",

+        MouseState->ButtonStates,

+        MouseState->dx,

+        MouseState->dy

+        );

+}

+*/

+STATIC

+EFI_STATUS

+EFIAPI

+GetMouseState (

+  IN   EFI_SIMPLE_POINTER_PROTOCOL  *This,

+  OUT  EFI_SIMPLE_POINTER_STATE     *MouseState

+  )

+/*++

+

+  Routine Description:

+    Get the mouse state, see SIMPLE POINTER PROTOCOL.

+    

+  Arguments:

+    This              - Protocol instance pointer.

+    MouseState        - Current mouse state

+    

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_NOT_READY

+

+--*/

+{

+  USB_MOUSE_DEV *MouseDev;

+

+  if (MouseState == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  MouseDev = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This);

+

+  if (!MouseDev->StateChanged) {

+    return EFI_NOT_READY;

+  }

+

+  CopyMem (

+    MouseState,

+    &MouseDev->State,

+    sizeof (EFI_SIMPLE_POINTER_STATE)

+    );

+

+  //

+  // Clear previous move state

+  //

+  MouseDev->State.RelativeMovementX = 0;

+  MouseDev->State.RelativeMovementY = 0;

+  MouseDev->State.RelativeMovementZ = 0;

+

+  MouseDev->StateChanged            = FALSE;

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+UsbMouseReset (

+  IN EFI_SIMPLE_POINTER_PROTOCOL    *This,

+  IN BOOLEAN                        ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset the mouse device, see SIMPLE POINTER PROTOCOL.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    ExtendedVerification  - Ignored here/

+    

+  Returns:

+    EFI_SUCCESS

+

+--*/

+{

+  USB_MOUSE_DEV       *UsbMouseDevice;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+

+  UsbMouseDevice  = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This);

+

+  UsbIo           = UsbMouseDevice->UsbIo;

+

+  MouseReportStatusCode (

+    UsbMouseDevice->DevicePath,

+    EFI_PROGRESS_CODE,

+    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET)

+    );

+

+  ZeroMem (

+    &UsbMouseDevice->State,

+    sizeof (EFI_SIMPLE_POINTER_STATE)

+    );

+  UsbMouseDevice->StateChanged = FALSE;

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+VOID

+EFIAPI

+UsbMouseWaitForInput (

+  IN  EFI_EVENT               Event,

+  IN  VOID                    *Context

+  )

+/*++

+

+Routine Description:

+

+  Event notification function for SIMPLE_POINTER.WaitForInput event

+  Signal the event if there is input from mouse

+

+Arguments:

+  Event    - Wait Event

+  Context  - Passed parameter to event handler

+Returns:

+  VOID

+--*/

+{

+  USB_MOUSE_DEV *UsbMouseDev;

+

+  UsbMouseDev = (USB_MOUSE_DEV *) Context;

+

+  //

+  // Someone is waiting on the mouse event, if there's

+  // input from mouse, signal the event

+  //

+  if (UsbMouseDev->StateChanged) {

+    gBS->SignalEvent (Event);

+  }

+}

+

+VOID

+EFIAPI

+USBMouseRecoveryHandler (

+  IN    EFI_EVENT    Event,

+  IN    VOID         *Context

+  )

+/*++

+  

+  Routine Description:

+    Timer handler for Delayed Recovery timer.

+    

+  Arguments:

+    Event   -  The Delayed Recovery event.

+    Context -  Points to the USB_KB_DEV instance.

+    

+  Returns:

+  

+--*/    

+{

+  USB_MOUSE_DEV       *UsbMouseDev;

+  EFI_USB_IO_PROTOCOL *UsbIo;

+

+  UsbMouseDev = (USB_MOUSE_DEV *) Context;

+

+  UsbIo       = UsbMouseDev->UsbIo;

+

+  UsbIo->UsbAsyncInterruptTransfer (

+          UsbIo,

+          UsbMouseDev->IntEndpointDescriptor->EndpointAddress,

+          TRUE,

+          UsbMouseDev->IntEndpointDescriptor->Interval,

+          UsbMouseDev->IntEndpointDescriptor->MaxPacketSize,

+          OnMouseInterruptComplete,

+          UsbMouseDev

+          );

+}

+

+VOID

+MouseReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  )

+/*++

+

+  Routine Description:

+    Report Status Code in Usb Bot Driver

+

+  Arguments:

+    DevicePath  - Use this to get Device Path

+    CodeType    - Status Code Type

+    CodeValue   - Status Code Value

+

+  Returns:

+    None

+

+--*/

+{

+

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    CodeType,

+    Value,

+    DevicePath

+    );

+}

diff --git a/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/usbmouse.h b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/usbmouse.h
new file mode 100644
index 0000000..47485bf
--- /dev/null
+++ b/edk2/EdkModulePkg/Bus/Usb/UsbMouse/Dxe/usbmouse.h
@@ -0,0 +1,85 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    UsbMouse.h

+

+  Abstract:

+

+--*/

+

+#ifndef _USB_MOUSE_H

+#define _USB_MOUSE_H

+

+#include <IndustryStandard/Usb.h>

+

+#define CLASS_HID               3

+#define SUBCLASS_BOOT           1

+#define PROTOCOL_MOUSE          2

+

+#define BOOT_PROTOCOL           0

+#define REPORT_PROTOCOL         1

+

+#define USB_MOUSE_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'm', 'o', 'u')

+

+typedef struct {

+  BOOLEAN ButtonDetected;

+  UINT8   ButtonMinIndex;

+  UINT8   ButtonMaxIndex;

+  UINT8   Reserved;

+} PRIVATE_DATA;

+

+typedef struct {

+  UINTN                         Signature;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  EFI_EVENT                     DelayedRecoveryEvent;

+  EFI_USB_IO_PROTOCOL           *UsbIo;

+  EFI_USB_INTERFACE_DESCRIPTOR  *InterfaceDescriptor;

+  EFI_USB_ENDPOINT_DESCRIPTOR   *IntEndpointDescriptor;

+  UINT8                         NumberOfButtons;

+  INT32                         XLogicMax;

+  INT32                         XLogicMin;

+  INT32                         YLogicMax;

+  INT32                         YLogicMin;

+  EFI_SIMPLE_POINTER_PROTOCOL   SimplePointerProtocol;

+  EFI_SIMPLE_POINTER_STATE      State;

+  EFI_SIMPLE_POINTER_MODE       Mode;

+  BOOLEAN                       StateChanged;

+  PRIVATE_DATA                  PrivateData;

+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;

+} USB_MOUSE_DEV;

+

+#define USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL(a) \

+    CR(a, USB_MOUSE_DEV, SimplePointerProtocol, USB_MOUSE_DEV_SIGNATURE)

+

+VOID

+EFIAPI

+USBMouseRecoveryHandler (

+  IN    EFI_EVENT    Event,

+  IN    VOID         *Context

+  );

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gUsbMouseDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gUsbMouseComponentName;

+extern EFI_GUID                     gEfiUsbMouseDriverGuid;

+

+VOID

+MouseReportStatusCode (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN EFI_STATUS_CODE_TYPE      CodeType,

+  IN EFI_STATUS_CODE_VALUE     Value

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/DebugImageInfo.h b/edk2/EdkModulePkg/Core/Dxe/DebugImageInfo.h
new file mode 100644
index 0000000..be1d1f1
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/DebugImageInfo.h
@@ -0,0 +1,126 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugImageInfo.h

+    

+Abstract:

+

+  Support functions for managing debug image info table when loading and unloading

+  images.

+

+--*/

+

+#ifndef __DEBUG_IMAGE_INFO_H__

+#define __DEBUG_IMAGE_INFO_H__

+

+#define FOUR_MEG_PAGES  0x400  

+#define FOUR_MEG_MASK   ((FOUR_MEG_PAGES * EFI_PAGE_SIZE) - 1)

+

+#define EFI_DEBUG_TABLE_ENTRY_SIZE       (sizeof (VOID *))

+

+VOID

+CoreInitializeDebugImageInfoTable (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Creates and initializes the DebugImageInfo Table.  Also creates the configuration

+  table and registers it into the system table.

+

+Arguments:

+  None

+

+Returns:

+  NA

+

+Notes:

+  This function allocates memory, frees it, and then allocates memory at an

+  address within the initial allocation. Since this function is called early

+  in DXE core initialization (before drivers are dispatched), this should not

+  be a problem.

+

+--*/

+;

+

+VOID

+CoreUpdateDebugTableCrc32 (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Update the CRC32 in the Debug Table.

+  Since the CRC32 service is made available by the Runtime driver, we have to

+  wait for the Runtime Driver to be installed before the CRC32 can be computed.

+  This function is called elsewhere by the core when the runtime architectural

+  protocol is produced.

+

+Arguments:

+  None

+

+Returns:

+  NA

+

+--*/

+;

+

+VOID

+CoreNewDebugImageInfoEntry (

+  UINTN                    ImageInfoType,

+  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,

+  EFI_HANDLE                ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Adds a new DebugImageInfo structure to the DebugImageInfo Table.  Re-Allocates

+  the table if it's not large enough to accomidate another entry.

+

+Arguments:

+

+  ImageInfoType     - type of debug image information

+  LoadedImage       - pointer to the loaded image protocol for the image being loaded

+  ImageHandle       - image handle for the image being loaded

+

+Returns:

+  NA

+

+--*/

+;

+

+VOID

+CoreRemoveDebugImageInfoEntry (

+  EFI_HANDLE ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Removes and frees an entry from the DebugImageInfo Table.

+

+Arguments:

+

+  ImageHandle       - image handle for the image being unloaded

+

+Returns:

+

+  NA

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/edk2/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
new file mode 100644
index 0000000..fec7948
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
@@ -0,0 +1,1164 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Dispatcher.c

+

+Abstract:

+

+  Tiano DXE Dispatcher.

+

+  Step #1 - When a FV protocol is added to the system every driver in the FV

+            is added to the mDiscoveredList. The SOR, Before, and After Depex are 

+            pre-processed as drivers are added to the mDiscoveredList. If an Apriori 

+            file exists in the FV those drivers are addeded to the 

+            mScheduledQueue. The mFvHandleList is used to make sure a 

+            FV is only processed once.

+

+  Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and

+            start it. After mScheduledQueue is drained check the 

+            mDiscoveredList to see if any item has a Depex that is ready to 

+            be placed on the mScheduledQueue.

+

+  Step #3 - Adding to the mScheduledQueue requires that you process Before 

+            and After dependencies. This is done recursively as the call to add

+            to the mScheduledQueue checks for Before and recursively adds 

+            all Befores. It then addes the item that was passed in and then 

+            processess the After dependecies by recursively calling the routine.

+

+  Dispatcher Rules:

+  The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3 

+  is the state diagram for the DXE dispatcher

+

+  Depex - Dependency Expresion.

+  SOR   - Schedule On Request - Don't schedule if this bit is set.

+

+--*/

+

+#include <DxeMain.h>

+

+//

+// The Driver List contains one copy of every driver that has been discovered.

+// Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY

+//

+LIST_ENTRY  mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);  

+

+//

+// Queue of drivers that are ready to dispatch. This queue is a subset of the

+// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY.

+//

+LIST_ENTRY  mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);

+

+//

+// List of handles who's Fv's have been parsed and added to the mFwDriverList.

+//

+LIST_ENTRY  mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);           // list of KNOWN_HANDLE

+

+//

+// Lock for mDiscoveredList, mScheduledQueue, gDispatcherRunning.

+//

+EFI_LOCK  mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);

+

+

+//

+// Flag for the DXE Dispacher.  TRUE if dispatcher is execuing.

+//

+BOOLEAN  gDispatcherRunning = FALSE;

+

+//

+// Module globals to manage the FwVol registration notification event

+//

+EFI_EVENT       mFwVolEvent;

+VOID            *mFwVolEventRegistration;

+

+//

+// List of file types supported by dispatcher

+//

+static EFI_FV_FILETYPE mDxeFileTypes[] = { 

+  EFI_FV_FILETYPE_DRIVER, 

+  EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER, 

+  EFI_FV_FILETYPE_DXE_CORE,

+  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE

+};

+

+typedef struct {

+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   File;

+  EFI_DEVICE_PATH_PROTOCOL            End;

+} FV_FILEPATH_DEVICE_PATH;

+

+FV_FILEPATH_DEVICE_PATH mFvDevicePath;

+

+

+//

+// Function Prototypes

+//

+VOID

+CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (

+  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry

+  );

+ 

+VOID

+EFIAPI

+CoreFwVolEventProtocolNotify (

+  IN  EFI_EVENT       Event,

+  IN  VOID            *Context

+  );

+

+EFI_DEVICE_PATH_PROTOCOL *

+CoreFvToDevicePath (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,

+  IN  EFI_HANDLE                      FvHandle,

+  IN  EFI_GUID                        *DriverName

+  );

+

+STATIC 

+EFI_STATUS

+CoreAddToDriverList (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv,

+  IN  EFI_HANDLE                    FvHandle,

+  IN  EFI_GUID                      *DriverName

+  );

+

+STATIC

+EFI_STATUS 

+CoreProcessFvImageFile (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,

+  IN  EFI_HANDLE                      FvHandle,

+  IN  EFI_GUID                        *DriverName

+  );

+

+

+VOID

+CoreAcquireDispatcherLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Enter critical section by gaining lock on mDispatcherLock

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+

+{

+  CoreAcquireLock (&mDispatcherLock);

+}

+

+VOID

+CoreReleaseDispatcherLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Exit critical section by releasing lock on mDispatcherLock

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  CoreReleaseLock (&mDispatcherLock);

+}

+

+

+EFI_STATUS

+CoreGetDepexSectionAndPreProccess (

+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry

+  )

+/*++

+

+Routine Description:

+

+  Read Depex and pre-process the Depex for Before and After. If Section Extraction

+  protocol returns an error via ReadSection defer the reading of the Depex.

+

+Arguments:

+

+  DriverEntry - Driver to work on.

+  

+Returns:

+

+  EFI_SUCCESS - Depex read and preprossesed 

+

+  EFI_PROTOCOL_ERROR - The section extraction protocol returned an error and 

+                        Depex reading needs to be retried.

+

+  Other Error - DEPEX not found.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SECTION_TYPE              SectionType;

+  UINT32                        AuthenticationStatus;

+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;

+

+  

+  Fv = DriverEntry->Fv;

+

+  //

+  // Grab Depex info, it will never be free'ed.

+  //

+  SectionType         = EFI_SECTION_DXE_DEPEX;

+  Status = Fv->ReadSection (

+                DriverEntry->Fv, 

+                &DriverEntry->FileName,

+                SectionType, 

+                0, 

+                &DriverEntry->Depex, 

+                (UINTN *)&DriverEntry->DepexSize,

+                &AuthenticationStatus

+                );

+  if (EFI_ERROR (Status)) {

+    if (Status == EFI_PROTOCOL_ERROR) {

+      //

+      // The section extraction protocol failed so set protocol error flag

+      //

+      DriverEntry->DepexProtocolError = TRUE;

+    } else {

+      //

+      // If no Depex assume EFI 1.1 driver model

+      //

+      DriverEntry->Depex = NULL;

+      DriverEntry->Dependent = TRUE;

+      DriverEntry->DepexProtocolError = FALSE;

+    }

+  } else {

+    //

+    // Set Before, After, and Unrequested state information based on Depex

+    // Driver will be put in Dependent or Unrequested state

+    //

+    CorePreProcessDepex (DriverEntry);

+    DriverEntry->DepexProtocolError = FALSE;

+  }  

+

+  return Status;

+}

+

+EFI_DXESERVICE

+EFI_STATUS

+EFIAPI

+CoreSchedule (

+  IN  EFI_HANDLE  FirmwareVolumeHandle,

+  IN  EFI_GUID    *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Check every driver and locate a matching one. If the driver is found, the Unrequested

+  state flag is cleared.

+

+Arguments:

+

+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware 

+                         file specified by DriverName.

+

+  DriverName           - The Driver name to put in the Dependent state.

+

+Returns:

+

+  EFI_SUCCESS   - The DriverName was found and it's SOR bit was cleared

+

+  EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.

+

+--*/

+{

+  LIST_ENTRY            *Link;

+  EFI_CORE_DRIVER_ENTRY *DriverEntry;

+

+  //

+  // Check every driver

+  //

+  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {

+    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&

+        DriverEntry->Unrequested && 

+        CompareGuid (DriverName, &DriverEntry->FileName)) {

+      //

+      // Move the driver from the Unrequested to the Dependent state

+      //

+      CoreAcquireDispatcherLock ();

+      DriverEntry->Unrequested  = FALSE;

+      DriverEntry->Dependent    = TRUE;

+      CoreReleaseDispatcherLock ();

+    

+      return EFI_SUCCESS;

+    }

+  }

+  return EFI_NOT_FOUND;  

+}

+

+

+EFI_DXESERVICE

+EFI_STATUS

+EFIAPI

+CoreTrust (

+  IN  EFI_HANDLE  FirmwareVolumeHandle,

+  IN  EFI_GUID    *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Convert a driver from the Untrused back to the Scheduled state

+

+Arguments:

+

+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware 

+                         file specified by DriverName.

+

+  DriverName           - The Driver name to put in the Scheduled state

+

+Returns:

+

+  EFI_SUCCESS   - The file was found in the untrusted state, and it was promoted 

+                  to the trusted state.

+

+  EFI_NOT_FOUND - The file was not found in the untrusted state.

+

+--*/

+{

+  LIST_ENTRY            *Link;

+  EFI_CORE_DRIVER_ENTRY *DriverEntry;

+

+  //

+  // Check every driver

+  //

+  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {

+    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&

+        DriverEntry->Untrusted && 

+        CompareGuid (DriverName, &DriverEntry->FileName)) {

+      //

+      // Transition driver from Untrusted to Scheduled state.

+      //

+      CoreAcquireDispatcherLock ();

+      DriverEntry->Untrusted = FALSE;

+      DriverEntry->Scheduled = TRUE;

+      InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);

+      CoreReleaseDispatcherLock ();

+    

+      return EFI_SUCCESS;

+    }

+  }

+  return EFI_NOT_FOUND;  

+}

+

+

+EFI_DXESERVICE

+EFI_STATUS

+EFIAPI

+CoreDispatcher (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This is the main Dispatcher for DXE and it exits when there are no more 

+  drivers to run. Drain the mScheduledQueue and load and start a PE

+  image for each driver. Search the mDiscoveredList to see if any driver can 

+  be placed on the mScheduledQueue. If no drivers are placed on the

+  mScheduledQueue exit the function. On exit it is assumed the Bds()

+  will be called, and when the Bds() exits the Dispatcher will be called 

+  again.

+

+Arguments:

+

+  NONE

+

+Returns:

+

+  EFI_ALREADY_STARTED - The DXE Dispatcher is already running

+

+  EFI_NOT_FOUND       - No DXE Drivers were dispatched

+

+  EFI_SUCCESS         - One or more DXE Drivers were dispatched

+

+--*/

+{

+  EFI_STATUS                      Status;

+  EFI_STATUS                      ReturnStatus;

+  LIST_ENTRY                      *Link;

+  EFI_CORE_DRIVER_ENTRY           *DriverEntry;

+  BOOLEAN                         ReadyToRun;

+

+  if (gDispatcherRunning) {

+    //

+    // If the dispatcher is running don't let it be restarted.

+    //

+    return EFI_ALREADY_STARTED;

+  }

+

+  gDispatcherRunning = TRUE;

+

+

+  ReturnStatus = EFI_NOT_FOUND;

+  do {

+    //

+    // Drain the Scheduled Queue

+    //

+    while (!IsListEmpty (&mScheduledQueue)) {

+      DriverEntry = CR (

+                      mScheduledQueue.ForwardLink,

+                      EFI_CORE_DRIVER_ENTRY,

+                      ScheduledLink,

+                      EFI_CORE_DRIVER_ENTRY_SIGNATURE

+                      );

+

+      //

+      // Load the DXE Driver image into memory. If the Driver was transitioned from

+      // Untrused to Scheduled it would have already been loaded so we may need to

+      // skip the LoadImage

+      //

+      if (DriverEntry->ImageHandle == NULL) {

+        Status = CoreLoadImage (

+                        TRUE, 

+                        gDxeCoreImageHandle, 

+                        DriverEntry->FvFileDevicePath,

+                        NULL, 

+                        0, 

+                        &DriverEntry->ImageHandle

+                        );

+

+        //

+        // Update the driver state to reflect that it's been loaded

+        //

+        if (EFI_ERROR (Status)) {

+          CoreAcquireDispatcherLock ();

+

+          if (Status == EFI_SECURITY_VIOLATION) {

+            //

+            // Take driver from Scheduled to Untrused state

+            //

+            DriverEntry->Untrusted = TRUE;

+          } else {

+            //

+            // The DXE Driver could not be loaded, and do not attempt to load or start it again.

+            // Take driver from Scheduled to Initialized. 

+            //

+            // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned

+            //

+            DriverEntry->Initialized  = TRUE;

+          }

+

+          DriverEntry->Scheduled = FALSE;

+          RemoveEntryList (&DriverEntry->ScheduledLink);

+          

+          CoreReleaseDispatcherLock ();

+        

+          //

+          // If it's an error don't try the StartImage

+          //

+          continue;

+        }

+      }

+

+      CoreAcquireDispatcherLock ();

+

+      DriverEntry->Scheduled    = FALSE;

+      DriverEntry->Initialized  = TRUE;

+      RemoveEntryList (&DriverEntry->ScheduledLink);

+      

+      CoreReleaseDispatcherLock ();

+

+

+      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);

+      Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);

+      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);

+

+      ReturnStatus = EFI_SUCCESS;

+    }

+

+    //

+    // Search DriverList for items to place on Scheduled Queue

+    //

+    ReadyToRun = FALSE;

+    for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {

+      DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+

+      if (DriverEntry->DepexProtocolError){

+        //

+        // If Section Extraction Protocol did not let the Depex be read before retry the read

+        //

+        Status = CoreGetDepexSectionAndPreProccess (DriverEntry);

+      } 

+

+      if (DriverEntry->Dependent) {

+        if (CoreIsSchedulable (DriverEntry)) {

+          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); 

+          ReadyToRun = TRUE;

+        } 

+      }

+    }

+  } while (ReadyToRun);

+

+  gDispatcherRunning = FALSE;

+

+  return ReturnStatus;

+}

+

+

+VOID

+CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (

+  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry

+  )

+/*++

+

+Routine Description:

+

+  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you 

+  must add any driver with a before dependency on InsertedDriverEntry first.

+  You do this by recursively calling this routine. After all the Befores are

+  processed you can add InsertedDriverEntry to the mScheduledQueue. 

+  Then you can add any driver with an After dependency on InsertedDriverEntry 

+  by recursively calling this routine.

+

+Arguments:

+

+  InsertedDriverEntry - The driver to insert on the ScheduledLink Queue

+

+Returns:

+

+  NONE 

+

+--*/

+{

+  LIST_ENTRY            *Link;

+  EFI_CORE_DRIVER_ENTRY *DriverEntry;

+

+  //

+  // Process Before Dependency

+  //

+  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {

+    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+    if (DriverEntry->Before && DriverEntry->Dependent) {

+      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {

+        //

+        // Recursively process BEFORE

+        //

+        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);

+      }

+    }

+  }

+

+  //

+  // Convert driver from Dependent to Scheduled state

+  //

+  CoreAcquireDispatcherLock ();

+

+  InsertedDriverEntry->Dependent = FALSE;

+  InsertedDriverEntry->Scheduled = TRUE;

+  InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);

+  

+  CoreReleaseDispatcherLock ();

+

+  //

+  // Process After Dependency

+  //

+  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {

+    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+    if (DriverEntry->After && DriverEntry->Dependent) {

+      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {

+        //

+        // Recursively process AFTER

+        //

+        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);

+      }

+    }

+  }

+}

+

+

+BOOLEAN

+FvHasBeenProcessed (

+  IN  EFI_HANDLE      FvHandle

+  )

+/*++

+

+Routine Description:

+

+  Return TRUE if the Fv has been processed, FALSE if not.

+

+Arguments:

+

+  FvHandle - The handle of a FV that's being tested

+

+Returns:

+

+  TRUE  - Fv protocol on FvHandle has been processed

+

+  FALSE - Fv protocol on FvHandle has not yet been processed

+

+--*/

+{

+  LIST_ENTRY      *Link;

+  KNOWN_HANDLE    *KnownHandle;

+

+  for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {

+    KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);

+    if (KnownHandle->Handle == FvHandle) {

+      return TRUE;

+    }

+  }

+  return FALSE;

+}

+

+

+VOID

+FvIsBeingProcesssed (

+  IN  EFI_HANDLE    FvHandle

+  )

+/*++

+

+Routine Description:

+

+  Remember that Fv protocol on FvHandle has had it's drivers placed on the

+  mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are

+  never removed/freed from the mFvHandleList.

+

+Arguments:

+

+  FvHandle - The handle of a FV that has been processed

+

+Returns:

+

+  None

+

+--*/

+{

+  KNOWN_HANDLE  *KnownHandle;

+

+  KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));

+  ASSERT (KnownHandle != NULL);

+

+  KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;

+  KnownHandle->Handle = FvHandle;

+  InsertTailList (&mFvHandleList, &KnownHandle->Link);

+}

+

+

+

+

+EFI_DEVICE_PATH_PROTOCOL *

+CoreFvToDevicePath (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,

+  IN  EFI_HANDLE                      FvHandle,

+  IN  EFI_GUID                        *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Convert FvHandle and DriverName into an EFI device path

+

+Arguments:

+

+  Fv         - Fv protocol, needed to read Depex info out of FLASH.

+  

+  FvHandle   - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the

+               PE image can be read out of the FV at a later time.

+

+  DriverName - Name of driver to add to mDiscoveredList.

+

+Returns:

+

+  Pointer to device path constructed from FvHandle and DriverName

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_DEVICE_PATH_PROTOCOL            *FvDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL            *FileNameDevicePath;

+

+  //

+  // Remember the device path of the FV

+  //

+  Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);

+  if (EFI_ERROR (Status)) {

+    FileNameDevicePath = NULL;

+  } else {

+    //

+    // Build a device path to the file in the FV to pass into gBS->LoadImage

+    //

+    EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);

+    mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;

+    mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;

+    SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));

+

+    FileNameDevicePath = CoreAppendDevicePath (

+                            FvDevicePath, 

+                            (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath

+                            );

+  }

+

+  return FileNameDevicePath;

+}

+

+

+

+EFI_STATUS

+CoreAddToDriverList (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,

+  IN  EFI_HANDLE                      FvHandle,

+  IN  EFI_GUID                        *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry, 

+  and initilize any state variables. Read the Depex from the FV and store it

+  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.

+  The Discovered list is never free'ed and contains booleans that represent the

+  other possible DXE driver states.

+

+Arguments:

+

+  Fv         - Fv protocol, needed to read Depex info out of FLASH.

+  

+  FvHandle   - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the

+               PE image can be read out of the FV at a later time.

+

+  DriverName - Name of driver to add to mDiscoveredList.

+

+Returns:

+

+  EFI_SUCCESS - If driver was added to the mDiscoveredList.

+

+  EFI_ALREADY_STARTED - The driver has already been started. Only one DriverName

+                        may be active in the system at any one time.

+

+--*/

+{

+  EFI_CORE_DRIVER_ENTRY               *DriverEntry;

+

+ 

+  //

+  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to 

+  // NULL or FALSE.

+  //

+  DriverEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_CORE_DRIVER_ENTRY));

+  ASSERT (DriverEntry != NULL);

+

+  DriverEntry->Signature        = EFI_CORE_DRIVER_ENTRY_SIGNATURE;

+  CopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));

+  DriverEntry->FvHandle         = FvHandle;

+  DriverEntry->Fv               = Fv;

+  DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);

+

+  CoreGetDepexSectionAndPreProccess (DriverEntry);

+  

+  CoreAcquireDispatcherLock ();

+  

+  InsertTailList (&mDiscoveredList, &DriverEntry->Link);

+

+  CoreReleaseDispatcherLock ();

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS 

+CoreProcessFvImageFile (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,

+  IN  EFI_HANDLE                      FvHandle,

+  IN  EFI_GUID                        *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.

+

+Arguments:

+

+  Fv          - The FIRMWARE_VOLUME protocol installed on the FV.

+  FvHandle    - The handle which FVB protocol installed on.

+  DriverName  - The driver guid specified.

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES    - No enough memory or other resource.

+  

+  EFI_VOLUME_CORRUPTED    - Corrupted volume.

+  

+  EFI_SUCCESS             - Function successfully returned.

+  

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_SECTION_TYPE                    SectionType;

+  UINT32                              AuthenticationStatus;

+  VOID                                *Buffer;

+  UINTN                               BufferSize;

+

+  //

+  // Read the first (and only the first) firmware volume section

+  //

+  SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;

+  Buffer      = NULL;

+  BufferSize  = 0;

+  Status = Fv->ReadSection (

+                Fv, 

+                DriverName, 

+                SectionType, 

+                0, 

+                &Buffer, 

+                &BufferSize,

+                &AuthenticationStatus

+                );

+  if (!EFI_ERROR (Status)) {

+    //

+    // Produce a FVB protocol for the file

+    //

+    Status = ProduceFVBProtocolOnBuffer (

+              (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,

+              (UINT64)BufferSize,

+              FvHandle,

+              NULL

+              );

+  }

+

+  if (EFI_ERROR (Status) && (Buffer != NULL)) {    

+  //

+  // ReadSection or Produce FVB failed, Free data buffer

+  //

+  CoreFreePool (Buffer); 

+

+  }

+

+  return Status;

+}

+

+

+VOID

+EFIAPI

+CoreFwVolEventProtocolNotify (

+  IN  EFI_EVENT       Event,

+  IN  VOID            *Context

+  )

+/*++

+

+Routine Description:

+

+  Event notification that is fired every time a FV dispatch protocol is added. 

+  More than one protocol may have been added when this event is fired, so you

+  must loop on CoreLocateHandle () to see how many protocols were added and

+  do the following to each FV:

+

+  If the Fv has already been processed, skip it. If the Fv has not been 

+  processed then mark it as being processed, as we are about to process it.

+

+  Read the Fv and add any driver in the Fv to the mDiscoveredList.The 

+  mDiscoveredList is never free'ed and contains variables that define

+  the other states the DXE driver transitions to.. 

+  

+  While you are at it read the A Priori file into memory.

+  Place drivers in the A Priori list onto the mScheduledQueue.

+

+Arguments:

+

+  Event   - The Event that is being processed, not used.

+  

+  Context - Event Context, not used.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_STATUS                    GetNextFileStatus;

+  EFI_STATUS                    SecurityStatus;

+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;

+  EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;

+  EFI_HANDLE                    FvHandle;

+  UINTN                         BufferSize;

+  EFI_GUID                      NameGuid;

+  UINTN                         Key;

+  EFI_FV_FILETYPE               Type;

+  EFI_FV_FILE_ATTRIBUTES        Attributes;

+  UINTN                         Size;

+  EFI_CORE_DRIVER_ENTRY         *DriverEntry;

+  EFI_GUID                      *AprioriFile;

+  UINTN                         AprioriEntryCount;

+  UINTN                         Index;

+  LIST_ENTRY                    *Link;

+  UINT32                        AuthenticationStatus;

+  UINTN                         SizeOfBuffer;

+

+

+  while (TRUE) {

+    BufferSize = sizeof (EFI_HANDLE);

+    Status = CoreLocateHandle (

+                    ByRegisterNotify,

+                    NULL,

+                    mFwVolEventRegistration,

+                    &BufferSize,

+                    &FvHandle

+                    );

+    if (EFI_ERROR (Status)) {

+      //

+      // If no more notification events exit

+      //

+      return;

+    }

+

+    if (FvHasBeenProcessed (FvHandle)) {

+      //

+      // This Fv has already been processed so lets skip it!

+      //

+      continue;

+    }

+

+    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, (VOID **)&Fv);

+    if (EFI_ERROR (Status)) {

+      //

+      // If no dispatch protocol then skip, but do not marked as being processed as it

+      // may show up later.

+      //

+      continue;

+    }

+

+    //

+    // Since we are about to process this Fv mark it as processed.

+    //

+    FvIsBeingProcesssed (FvHandle);

+

+

+    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);

+    if (EFI_ERROR (Status)) {

+      //

+      // The Handle has a FirmwareVolumeDispatch protocol and should also contiain

+      // a FirmwareVolume protocol thus we should never get here.

+      //

+      ASSERT (FALSE);

+      continue;

+    }

+    

+    Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);

+    if (EFI_ERROR (Status)) {

+      //

+      // The Firmware volume doesn't have device path, can't be dispatched.

+      //

+      continue;

+    }

+    

+    //

+    // Evaluate the authentication status of the Firmware Volume through 

+    // Security Architectural Protocol

+    //

+    if (gSecurity != NULL) {

+      SecurityStatus = gSecurity->FileAuthenticationState (

+                                    gSecurity, 

+                                    0, 

+                                    FvDevicePath

+                                    );

+      if (SecurityStatus != EFI_SUCCESS) {

+        //

+        // Security check failed. The firmware volume should not be used for any purpose.

+        //

+        continue;

+      }

+    }   

+    

+    //

+    // Discover Drivers in FV and add them to the Discovered Driver List. 

+    // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 

+    //  EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core

+    //  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb

+    //

+    for (Index = 0; Index < sizeof (mDxeFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {

+      //

+      // Initialize the search key

+      //

+      Key = 0;

+      do {

+        Type = mDxeFileTypes[Index];

+        GetNextFileStatus = Fv->GetNextFile (

+                                  Fv, 

+                                  &Key,

+                                  &Type,  

+                                  &NameGuid, 

+                                  &Attributes, 

+                                  &Size

+                                  );

+        if (!EFI_ERROR (GetNextFileStatus)) {

+          if (Type == EFI_FV_FILETYPE_DXE_CORE) {

+            //

+            // If this is the DXE core fill in it's DevicePath & DeviceHandle

+            //

+            if (gDxeCoreLoadedImage->FilePath == NULL) {

+              if (CompareGuid (&NameGuid, gDxeCoreFileName)) {

+                //

+                // Because mFvDevicePath has been initialized when discoveried 

+                // EFI_FV_FILETYPE_DRIVER file. So only need to update the name 

+                // guid of device path.

+                //

+                CopyGuid (&mFvDevicePath.File.NameGuid, &NameGuid);

+

+                gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (

+                                                  (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath

+                                                  );

+                gDxeCoreLoadedImage->DeviceHandle = FvHandle;

+              }

+            }

+          } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {

+            //

+            // Found a firmware volume image. Produce a firmware volume block

+            // protocol for it so it gets dispatched from. This is usually a 

+            // capsule.

+            //

+            CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);

+          } else {

+            //

+            // Transition driver from Undiscovered to Discovered state

+            //

+            CoreAddToDriverList (Fv, FvHandle, &NameGuid);

+          }

+        }

+      } while (!EFI_ERROR (GetNextFileStatus));

+    }

+    

+    //

+    // Read the array of GUIDs from the Apriori file if it is present in the firmware volume

+    //

+    AprioriFile = NULL;

+    Status = Fv->ReadSection (

+                  Fv,

+                  &gAprioriGuid,

+                  EFI_SECTION_RAW,

+                  0,

+                  (VOID **)&AprioriFile,

+                  &SizeOfBuffer,

+                  &AuthenticationStatus

+                  );

+    if (!EFI_ERROR (Status)) {

+      AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);

+    } else {

+      AprioriEntryCount = 0;

+    }

+

+    //

+    // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes

+    // drivers not in the current FV and these must be skipped since the a priori list

+    // is only valid for the FV that it resided in.

+    //

+    CoreAcquireDispatcherLock ();

+    

+    for (Index = 0; Index < AprioriEntryCount; Index++) {

+      for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {

+        DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+        if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&

+            (FvHandle == DriverEntry->FvHandle)) {

+          DriverEntry->Dependent = FALSE;

+          DriverEntry->Scheduled = TRUE;

+          InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);

+          break;

+        }

+      }

+    }

+

+    CoreReleaseDispatcherLock ();

+

+    //

+    // Free data allocated by Fv->ReadSection () 

+    //

+    CoreFreePool (AprioriFile);  

+  }

+}

+

+

+VOID

+CoreInitializeDispatcher (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialize the dispatcher. Initialize the notification function that runs when

+  a FV protocol is added to the system.

+

+Arguments:

+

+  NONE

+

+Returns:

+

+  NONE 

+

+--*/

+{

+  mFwVolEvent = CoreCreateProtocolNotifyEvent (

+                  &gEfiFirmwareVolumeProtocolGuid, 

+                  EFI_TPL_CALLBACK,

+                  CoreFwVolEventProtocolNotify,

+                  NULL,

+                  &mFwVolEventRegistration,

+                  TRUE

+                  );

+}

+

+//

+// Function only used in debug buils

+//

+VOID

+CoreDisplayDiscoveredNotDispatched (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Traverse the discovered list for any drivers that were discovered but not loaded 

+  because the dependency experessions evaluated to false

+

+Arguments:

+

+  NONE

+

+Returns:

+

+  NONE 

+

+--*/

+{

+  LIST_ENTRY                    *Link;

+  EFI_CORE_DRIVER_ENTRY         *DriverEntry;

+

+  for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {

+    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);

+    if (DriverEntry->Dependent) {

+      DEBUG ((EFI_D_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));

+    }

+  }

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Dispatcher/dependency.c b/edk2/EdkModulePkg/Core/Dxe/Dispatcher/dependency.c
new file mode 100644
index 0000000..e6dc328
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Dispatcher/dependency.c
@@ -0,0 +1,450 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  dependency.c

+

+Abstract:

+

+  DXE Dispatcher Dependency Evaluator

+

+  This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine

+  if a driver can be scheduled for execution.  The criteria for

+  schedulability is that the dependency expression is satisfied.

+

+--*/

+

+#include <DxeMain.h>

+

+//

+// Global stack used to evaluate dependency expressions

+//

+BOOLEAN *mDepexEvaluationStack        = NULL;

+BOOLEAN *mDepexEvaluationStackEnd     = NULL;

+BOOLEAN *mDepexEvaluationStackPointer = NULL;

+

+//

+// Worker functions

+//

+

+STATIC

+EFI_STATUS

+GrowDepexStack (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Grow size of the Depex stack

+

+Arguments:

+

+  Stack     - Old stack on the way in and new stack on the way out

+

+  StackSize - New size of the stack

+

+Returns:

+

+  EFI_SUCCESS          - Stack successfully growed.

+  

+  EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.

+  

+  

+

+--*/

+{

+  BOOLEAN     *NewStack;

+  UINTN       Size;

+

+  Size = DEPEX_STACK_SIZE_INCREMENT;

+  if (mDepexEvaluationStack != NULL) {

+    Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);

+  }

+

+  NewStack = CoreAllocateBootServicesPool (Size * sizeof (BOOLEAN));

+  if (NewStack == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  if (mDepexEvaluationStack != NULL) {

+    //

+    // Copy to Old Stack to the New Stack

+    //

+    CopyMem (

+      NewStack, 

+      mDepexEvaluationStack, 

+      (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN)

+      );

+

+    //

+    // Free The Old Stack

+    //

+    CoreFreePool (mDepexEvaluationStack);

+  }

+

+  //

+  // Make the Stack pointer point to the old data in the new stack

+  //

+  mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack);

+  mDepexEvaluationStack        = NewStack;

+  mDepexEvaluationStackEnd     = NewStack + Size;

+

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+EFI_STATUS

+PushBool (

+  IN BOOLEAN  Value

+  )

+/*++

+

+Routine Description:

+

+  Push an element onto the Boolean Stack

+

+Arguments:

+

+  Value - BOOLEAN to push.

+

+Returns:

+

+  EFI_SUCCESS          - The value was pushed onto the stack.

+

+  EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Check for a stack overflow condition

+  //

+  if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) {

+    //

+    // Grow the stack

+    //

+    Status = GrowDepexStack ();

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  //

+  // Push the item onto the stack

+  //

+  *mDepexEvaluationStackPointer = Value;

+  mDepexEvaluationStackPointer++;

+

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+EFI_STATUS 

+PopBool (

+  OUT BOOLEAN  *Value

+  )

+/*++

+

+Routine Description:

+

+  Pop an element from the Boolean stack.

+

+Arguments:

+

+  Value - BOOLEAN to pop.

+

+Returns:

+

+  EFI_SUCCESS       - The value was popped onto the stack.

+

+  EFI_ACCESS_DENIED - The pop operation underflowed the stack

+

+--*/

+{

+  //

+  // Check for a stack underflow condition

+  //

+  if (mDepexEvaluationStackPointer == mDepexEvaluationStack) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  //

+  // Pop the item off the stack

+  //

+  mDepexEvaluationStackPointer--;

+  *Value = *mDepexEvaluationStackPointer;

+  return EFI_SUCCESS;  

+}

+

+

+EFI_STATUS

+CorePreProcessDepex (

+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  

+  )

+/*++

+

+Routine Description:

+

+  Preprocess dependency expression and update DriverEntry to reflect the

+  state of  Before, After, and SOR dependencies. If DriverEntry->Before

+  or DriverEntry->After is set it will never be cleared. If SOR is set

+  it will be cleared by CoreSchedule(), and then the driver can be 

+  dispatched.

+

+Arguments:

+

+  DriverEntry - DriverEntry element to update

+

+Returns:

+

+  EFI_SUCCESS - It always works.

+

+--*/

+{

+  UINT8  *Iterator;

+    

+  Iterator = DriverEntry->Depex;

+  if (*Iterator == EFI_DEP_SOR) {

+    DriverEntry->Unrequested = TRUE;

+  } else {

+    DriverEntry->Dependent = TRUE;

+  }

+    

+  if (*Iterator == EFI_DEP_BEFORE) {

+    DriverEntry->Before = TRUE;

+  } else if (*Iterator == EFI_DEP_AFTER) {

+    DriverEntry->After = TRUE;

+  } 

+

+  if (DriverEntry->Before || DriverEntry->After) {

+    CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+BOOLEAN

+CoreIsSchedulable (

+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  

+  )

+/*++

+

+Routine Description:

+

+  This is the POSTFIX version of the dependency evaluator.  This code does 

+  not need to handle Before or After, as it is not valid to call this 

+  routine in this case. The SOR is just ignored and is a nop in the grammer.

+

+  POSTFIX means all the math is done on top of the stack.

+

+Arguments:

+

+  DriverEntry - DriverEntry element to update

+  

+Returns:

+

+  TRUE - If driver is ready to run.

+

+  FALSE - If driver is not ready to run or some fatal error was found.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       *Iterator;

+  BOOLEAN     Operator;

+  BOOLEAN     Operator2;

+  EFI_GUID    DriverGuid;

+  VOID        *Interface;

+

+  if (DriverEntry->After || DriverEntry->Before) {

+    //

+    // If Before or After Depex skip as CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ()

+    // processes them.

+    //

+    return FALSE;

+  }

+

+  if (DriverEntry->Depex == NULL) {

+    //

+    // A NULL Depex means treat the driver like an EFI 1.0 thing.

+    //

+    Status = CoreAllEfiServicesAvailable ();

+    if (EFI_ERROR (Status)) {

+      return FALSE;

+    }

+    return TRUE;

+  }

+

+  //

+  // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by

+  //  incorrectly formed DEPEX expressions

+  //

+  mDepexEvaluationStackPointer = mDepexEvaluationStack;

+

+

+  Iterator = DriverEntry->Depex;

+  

+  while (TRUE) {

+    //

+    // Check to see if we are attempting to fetch dependency expression instructions

+    // past the end of the dependency expression.

+    //

+    if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) > DriverEntry->DepexSize) {

+      return FALSE;

+    }

+

+    //

+    // Look at the opcode of the dependency expression instruction.

+    //

+    switch (*Iterator) {

+    case EFI_DEP_BEFORE:

+    case EFI_DEP_AFTER:

+      //

+      // For a well-formed Dependency Expression, the code should never get here.

+      // The BEFORE and AFTER are processed prior to this routine's invocation.

+      // If the code flow arrives at this point, there was a BEFORE or AFTER

+      // that were not the first opcodes.

+      //

+      ASSERT (FALSE);

+    case EFI_DEP_SOR:

+      //

+      // These opcodes can only appear once as the first opcode.  If it is found 

+      // at any other location, then the dependency expression evaluates to FALSE

+      //

+      if (Iterator != DriverEntry->Depex) {

+        return FALSE;

+      }

+      //

+      // Otherwise, it is the first opcode and should be treated as a NOP.

+      //

+      break;

+

+    case EFI_DEP_PUSH:  

+      //

+      // Push operator is followed by a GUID. Test to see if the GUID protocol

+      // is installed and push the boolean result on the stack.

+      //

+      CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));

+

+      Status = CoreLocateProtocol (&DriverGuid, NULL, &Interface);

+

+      if (EFI_ERROR (Status)) {

+        Status = PushBool (FALSE);

+      } else {

+        *Iterator = EFI_DEP_REPLACE_TRUE;

+        Status = PushBool (TRUE);

+      }

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Iterator += sizeof (EFI_GUID);

+      break;

+

+    case EFI_DEP_AND:    

+      Status = PopBool (&Operator);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Status = PopBool (&Operator2);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Status = PushBool ((BOOLEAN)(Operator && Operator2));

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+      break;

+

+    case EFI_DEP_OR:     

+      Status = PopBool (&Operator);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Status = PopBool (&Operator2);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Status = PushBool ((BOOLEAN)(Operator || Operator2));

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+      break;

+

+    case EFI_DEP_NOT:    

+      Status = PopBool (&Operator);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Status = PushBool ((BOOLEAN)(!Operator));

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+      break;

+

+    case EFI_DEP_TRUE:   

+      Status = PushBool (TRUE);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+      break;

+

+    case EFI_DEP_FALSE: 

+      Status = PushBool (FALSE);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+      break;

+

+    case EFI_DEP_END:    

+      Status = PopBool (&Operator);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+      return Operator;

+

+    case EFI_DEP_REPLACE_TRUE:

+      Status = PushBool (TRUE);

+      if (EFI_ERROR (Status)) {

+        return FALSE;

+      }

+

+      Iterator += sizeof (EFI_GUID);

+      break;

+

+    default:      

+      return FALSE;

+    }

+    

+    //

+    // Skip over the Dependency Op Code we just processed in the switch.

+    // The math is done out of order, but it should not matter. That is

+    // we may add in the sizeof (EFI_GUID) before we account for the OP Code.

+    // This is not an issue, since we just need the correct end result. You

+    // need to be careful using Iterator in the loop as it's intermediate value

+    // may be strange.

+    //

+    Iterator++;

+  }

+  return FALSE;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/DxeMain.h b/edk2/EdkModulePkg/Core/Dxe/DxeMain.h
new file mode 100644
index 0000000..9a9ba68
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/DxeMain.h
@@ -0,0 +1,2539 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeMain.h

+

+Abstract:

+

+Revision History

+

+--*/

+

+#ifndef _DXE_MAIN_H_

+#define _DXE_MAIN_H_

+

+

+#include "DebugImageInfo.h"

+#include "Library.h"

+#include "FwVolBlock.h"

+#include "FwVolDriver.h"

+#include "gcd.h"

+#include "imem.h"

+#include "Image.h"

+#include "Exec.h"

+#include "hand.h"

+

+typedef struct {

+  EFI_GUID                    *ProtocolGuid;

+  VOID                        **Protocol;

+  EFI_EVENT                   Event;

+  VOID                        *Registration;

+  BOOLEAN                     Present;

+} ARCHITECTURAL_PROTOCOL_ENTRY;

+

+

+//

+// DXE Dispatcher Data structures

+//

+

+#define KNOWN_HANDLE_SIGNATURE  EFI_SIGNATURE_32('k','n','o','w')

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      Link;         // mFvHandleList           

+  EFI_HANDLE      Handle;

+} KNOWN_HANDLE;

+

+

+#define EFI_CORE_DRIVER_ENTRY_SIGNATURE EFI_SIGNATURE_32('d','r','v','r')

+typedef struct {

+  UINTN                           Signature;

+  LIST_ENTRY                      Link;             // mDriverList

+

+  LIST_ENTRY                      ScheduledLink;    // mScheduledQueue

+

+  EFI_HANDLE                      FvHandle;

+  EFI_GUID                        FileName;

+  EFI_DEVICE_PATH_PROTOCOL        *FvFileDevicePath;

+  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv;

+

+  VOID                            *Depex;

+  UINTN                           DepexSize;

+

+  BOOLEAN                         Before;

+  BOOLEAN                         After;

+  EFI_GUID                        BeforeAfterGuid;

+

+  BOOLEAN                         Dependent;

+  BOOLEAN                         Unrequested;

+  BOOLEAN                         Scheduled;

+  BOOLEAN                         Untrusted;

+  BOOLEAN                         Initialized;

+  BOOLEAN                         DepexProtocolError;

+

+  EFI_HANDLE                      ImageHandle;

+

+} EFI_CORE_DRIVER_ENTRY;

+

+//

+//The data structure of GCD memory map entry

+//

+#define EFI_GCD_MAP_SIGNATURE  EFI_SIGNATURE_32('g','c','d','m')

+typedef struct {

+  UINTN                 Signature;

+  LIST_ENTRY            Link;

+  EFI_PHYSICAL_ADDRESS  BaseAddress;

+  UINT64                EndAddress;

+  UINT64                Capabilities;

+  UINT64                Attributes;

+  EFI_GCD_MEMORY_TYPE   GcdMemoryType;

+  EFI_GCD_IO_TYPE       GcdIoType;

+  EFI_HANDLE            ImageHandle;

+  EFI_HANDLE            DeviceHandle;

+} EFI_GCD_MAP_ENTRY;

+

+//

+// DXE Core Global Variables

+//

+extern EFI_SYSTEM_TABLE                         *gST;

+extern EFI_BOOT_SERVICES                        *gBS;

+extern EFI_RUNTIME_SERVICES                     *gRT;

+extern EFI_DXE_SERVICES                         *gDS;

+extern EFI_HANDLE                               gDxeCoreImageHandle;

+

+extern EFI_DECOMPRESS_PROTOCOL                  gEfiDecompress;

+extern EFI_PEI_PE_COFF_LOADER_PROTOCOL          *gEfiPeiPeCoffLoader;

+

+extern EFI_RUNTIME_ARCH_PROTOCOL                *gRuntime;

+extern EFI_CPU_ARCH_PROTOCOL                    *gCpu;

+extern EFI_WATCHDOG_TIMER_ARCH_PROTOCOL         *gWatchdogTimer;

+extern EFI_METRONOME_ARCH_PROTOCOL              *gMetronome;

+extern EFI_TIMER_ARCH_PROTOCOL                  *gTimer;

+extern EFI_SECURITY_ARCH_PROTOCOL               *gSecurity;

+extern EFI_BDS_ARCH_PROTOCOL                    *gBds;

+extern EFI_STATUS_CODE_PROTOCOL                 *gStatusCode;

+

+extern EFI_TPL                                  gEfiCurrentTpl;

+

+extern EFI_GUID                                 *gDxeCoreFileName;

+extern EFI_LOADED_IMAGE_PROTOCOL                *gDxeCoreLoadedImage;

+

+extern EFI_MEMORY_TYPE_INFORMATION              gMemoryTypeInformation[EfiMaxMemoryType + 1];

+

+extern BOOLEAN                                  gDispatcherRunning;

+

+//

+// Service Initialization Functions

+//

+

+

+VOID

+CoreInitializePool (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Called to initialize the pool.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+CoreAddMemoryDescriptor (

+  IN EFI_MEMORY_TYPE       Type,

+  IN EFI_PHYSICAL_ADDRESS  Start,

+  IN UINT64                NumberOfPages,

+  IN UINT64                Attribute

+  )

+/*++

+

+Routine Description:

+

+  Called to initialize the memory map and add descriptors to

+  the current descriptor list.

+

+       The first descriptor that is added must be general usable

+  memory as the addition allocates heap.

+

+Arguments:

+

+  Type          - The type of memory to add

+

+  Start         - The starting address in the memory range

+                  Must be page aligned

+

+  NumberOfPages - The number of pages in the range

+

+  Attribute     - Attributes of the memory to add

+

+Returns:

+

+  None.  The range is added to the memory map

+

+--*/

+;

+

+VOID

+CoreReleaseGcdMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+    Release memory lock on mGcdMemorySpaceLock

+

+Arguments:

+    None

+

+Returns:

+    None

+

+--*/

+;

+

+VOID

+CoreAcquireGcdMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+    Acquire memory lock on mGcdMemorySpaceLock

+

+Arguments:

+    None

+

+Returns:

+    None

+

+--*/

+;

+

+EFI_STATUS

+CoreInitializeMemoryServices (

+  IN VOID                  **HobStart,

+  IN EFI_PHYSICAL_ADDRESS  *MemoryBaseAddress,

+  IN UINT64                *MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  External function. Initializes the GCD and memory services based on the memory 

+  descriptor HOBs.  This function is responsible for priming the GCD map and the

+  memory map, so memory allocations and resource allocations can be made.  The first

+  part of this function can not depend on any memory services until at least one

+  memory descriptor is provided to the memory services.  Then the memory services

+  can be used to intialize the GCD map.

+

+Arguments:

+

+  HobStart - The start address of the HOB.

+  

+  MemoryBaseAddress   - Start address of memory region found to init DXE core.

+  

+  MemoryLength        - Length of memory region found to init DXE core.

+

+Returns:

+

+  EFI_SUCCESS         - Memory services successfully initialized.

+

+--*/

+;

+

+

+EFI_STATUS

+CoreInitializeGcdServices (

+  IN VOID                  **HobStart,

+  IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,

+  IN UINT64                MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  External function. Initializes the GCD and memory services based on the memory 

+  descriptor HOBs.  This function is responsible for priming the GCD map and the

+  memory map, so memory allocations and resource allocations can be made.  The first

+  part of this function can not depend on any memory services until at least one

+  memory descriptor is provided to the memory services.  Then the memory services

+  can be used to intialize the GCD map.

+

+Arguments:

+

+  HobStart - The start address of the HOB

+  

+  MemoryBaseAddress   - Start address of memory region found to init DXE core.

+  

+  MemoryLength        - Length of memory region found to init DXE core.

+

+

+Returns:

+

+  EFI_SUCCESS         - GCD services successfully initialized.

+

+--*/

+;

+

+EFI_STATUS

+CoreInitializeEventServices (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initializes "event" support and populates parts of the System and Runtime Table.

+

+Arguments:

+

+  None

+    

+Returns:

+

+  EFI_SUCCESS - Always return success

+

+--*/

+;

+

+EFI_STATUS

+CoreShutdownEventServices (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Register all runtime events to make sure they are still available after ExitBootService.

+

+Arguments:

+

+  None

+    

+Returns:

+

+  EFI_SUCCESS - Always return success

+

+--*/

+;

+

+EFI_STATUS

+CoreInitializeImageServices (

+  IN  VOID *HobStart

+  )

+/*++

+

+Routine Description:

+

+  Add the Image Services to EFI Boot Services Table and install the protocol

+  interfaces for this image.

+

+Arguments:

+

+  HobStart        - The HOB to initialize

+

+Returns:

+

+  Status code.

+

+--*/

+;

+

+EFI_STATUS

+CoreShutdownImageServices (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Transfer control of runtime images to runtime service

+

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_SUCCESS       - Function successfully returned

+

+--*/

+;

+

+VOID

+CoreNotifyOnArchProtocolInstallation (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Creates an event that is fired everytime a Protocol of a specific type is installed

+

+Arguments:

+  NONE

+

+Returns:

+  NONE

+

+--*/

+;

+

+EFI_STATUS

+CoreAllEfiServicesAvailable (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if all AP services are availible.

+

+Arguments:

+  NONE

+

+Returns:

+  EFI_SUCCESS   - All AP services are available

+  EFI_NOT_FOUND - At least one AP service is not available 

+

+--*/

+;

+

+VOID

+CalculateEfiHdrCrc (

+  IN  OUT EFI_TABLE_HEADER    *Hdr

+  )

+/*++

+

+Routine Description:

+

+  Calcualte the 32-bit CRC in a EFI table using the service provided by the

+  gRuntime service.

+

+Arguments:

+

+  Hdr  - Pointer to an EFI standard header

+

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+EFIAPI

+CoreTimerTick (

+  IN UINT64     Duration

+  )

+/*++

+

+Routine Description:

+

+  Called by the platform code to process a tick.

+

+Arguments:

+

+  Duration    - The number of 100ns elasped since the last call to TimerTick

+    

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+CoreInitializeDispatcher (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialize the dispatcher. Initialize the notification function that runs when

+  a FV protocol is added to the system.

+

+Arguments:

+

+  NONE

+

+Returns:

+

+  NONE 

+

+--*/

+;

+

+BOOLEAN

+CoreIsSchedulable (

+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  

+  )

+/*++

+

+Routine Description:

+

+  This is the POSTFIX version of the dependency evaluator.  This code does 

+  not need to handle Before or After, as it is not valid to call this 

+  routine in this case. The SOR is just ignored and is a nop in the grammer.

+

+  POSTFIX means all the math is done on top of the stack.

+

+Arguments:

+

+  DriverEntry - DriverEntry element to update

+  

+Returns:

+

+  TRUE - If driver is ready to run.

+

+  FALSE - If driver is not ready to run or some fatal error was found.

+

+--*/

+;

+

+EFI_STATUS

+CorePreProcessDepex (

+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  

+  )

+/*++

+

+Routine Description:

+

+  Preprocess dependency expression and update DriverEntry to reflect the

+  state of  Before, After, and SOR dependencies. If DriverEntry->Before

+  or DriverEntry->After is set it will never be cleared. If SOR is set

+  it will be cleared by CoreSchedule(), and then the driver can be 

+  dispatched.

+

+Arguments:

+

+  DriverEntry - DriverEntry element to update

+

+Returns:

+

+  EFI_SUCCESS - It always works.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreExitBootServices (

+  IN EFI_HANDLE   ImageHandle,

+  IN UINTN        MapKey

+  )

+/*++

+

+Routine Description:

+

+  EFI 1.0 API to terminate Boot Services

+

+Arguments:

+

+  ImageHandle - Handle that represents the identity of the calling image

+

+  MapKey      -Key to the latest memory map.

+

+Returns:

+

+  EFI_SUCCESS - Boot Services terminated

+  EFI_INVALID_PARAMETER - MapKey is incorrect.

+

+--*/

+;

+

+EFI_STATUS

+CoreTerminateMemoryMap (

+  IN UINTN        MapKey

+  )

+/*++

+

+Routine Description:

+

+  Make sure the memory map is following all the construction rules, 

+  it is the last time to check memory map error before exit boot services.

+

+Arguments:

+

+  MapKey        - Memory map key

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Memory map not consistent with construction rules.

+  

+  EFI_SUCCESS                 - Valid memory map.

+

+--*/

+;

+

+VOID

+CoreNotifySignalList (

+  IN EFI_GUID     *EventGroup

+  )

+/*++

+

+Routine Description:

+

+  Signals all events on the requested list

+

+Arguments:

+

+  SignalType      - The list to signal

+    

+Returns:

+

+  None

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreInstallConfigurationTable (

+  IN EFI_GUID         *Guid,

+  IN VOID             *Table

+  )

+/*++

+

+Routine Description:

+

+  Boot Service called to add, modify, or remove a system configuration table from 

+  the EFI System Table.

+

+Arguments:

+

+  Guid:   Pointer to the GUID for the entry to add, update, or remove

+  Table:  Pointer to the configuration table for the entry to add, update, or

+          remove, may be NULL.

+

+Returns:

+  

+  EFI_SUCCESS               Guid, Table pair added, updated, or removed.

+  EFI_INVALID_PARAMETER     Input GUID not valid.

+  EFI_NOT_FOUND             Attempted to delete non-existant entry

+  EFI_OUT_OF_RESOURCES      Not enough memory available

+

+--*/

+;

+

+

+EFI_TPL

+EFIAPI

+CoreRaiseTpl (

+  IN EFI_TPL  NewTpl

+  )

+/*++

+

+Routine Description:

+

+  Raise the task priority level to the new level.

+  High level is implemented by disabling processor interrupts.

+

+Arguments:

+

+  NewTpl  - New task priority level

+    

+Returns:

+

+  The previous task priority level

+

+--*/

+;

+

+

+VOID

+EFIAPI

+CoreRestoreTpl (

+  IN EFI_TPL  NewTpl

+  )

+/*++

+

+Routine Description:

+

+  Lowers the task priority to the previous value.   If the new 

+  priority unmasks events at a higher priority, they are dispatched.

+

+Arguments:

+

+  NewTpl  - New, lower, task priority

+    

+Returns:

+

+  None

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreStall (

+  IN UINTN            Microseconds

+  )

+/*++

+

+Routine Description:

+

+  Introduces a fine-grained stall.

+

+Arguments:

+

+  Microseconds      The number of microseconds to stall execution

+

+Returns:

+

+  EFI_SUCCESS            - Execution was stalled for at least the requested amount

+                           of microseconds.

+

+  EFI_NOT_AVAILABLE_YET  - gMetronome is not available yet

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreSetWatchdogTimer (

+  IN UINTN            Timeout,

+  IN UINT64           WatchdogCode,

+  IN UINTN            DataSize,

+  IN CHAR16           *WatchdogData   OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Sets the system's watchdog timer.

+

+Arguments:

+

+  Timeout         The number of seconds.  Zero disables the timer.

+

+  ///////following  three parameters are left for platform specific using  

+  

+  WatchdogCode    The numberic code to log.  0x0 to 0xffff are firmware

+  DataSize        Size of the optional data

+  WatchdogData    Optional Null terminated unicode string followed by binary 

+                  data.

+

+Returns:

+

+  EFI_SUCCESS               Timeout has been set

+  EFI_NOT_AVAILABLE_YET     WatchdogTimer is not available yet 

+  EFI_UNSUPPORTED           System does not have a timer (currently not used)

+  EFI_DEVICE_ERROR          Could not complete due to hardware error

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreInstallProtocolInterface (

+  IN OUT EFI_HANDLE     *UserHandle,

+  IN EFI_GUID           *Protocol,

+  IN EFI_INTERFACE_TYPE InterfaceType,

+  IN VOID               *Interface

+  )

+/*++

+

+Routine Description:

+

+  Wrapper function to CoreInstallProtocolInterfaceNotify.  This is the public API which

+  Calls the private one which contains a BOOLEAN parameter for notifications

+

+Arguments:

+

+  UserHandle     - The handle to install the protocol handler on,

+                    or NULL if a new handle is to be allocated

+

+  Protocol       - The protocol to add to the handle

+

+  InterfaceType  - Indicates whether Interface is supplied in native form.

+

+  Interface      - The interface for the protocol being added

+

+Returns:

+

+  Status code    

+

+--*/

+;

+

+EFI_STATUS

+CoreInstallProtocolInterfaceNotify (

+  IN OUT EFI_HANDLE     *UserHandle,

+  IN EFI_GUID           *Protocol,

+  IN EFI_INTERFACE_TYPE InterfaceType,

+  IN VOID               *Interface,

+  IN BOOLEAN            Notify

+  )

+/*++

+

+Routine Description:

+

+  Installs a protocol interface into the boot services environment.

+

+Arguments:

+

+  UserHandle     - The handle to install the protocol handler on,

+                   or NULL if a new handle is to be allocated

+

+  Protocol       - The protocol to add to the handle

+

+  InterfaceType  - Indicates whether Interface is supplied in native form.

+

+  Interface      - The interface for the protocol being added

+  

+  Notify         - Whether to notify the notification list for this protocol 

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES       - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Protocol interface successfully installed

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreInstallMultipleProtocolInterfaces (

+  IN OUT EFI_HANDLE           *Handle,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Installs a list of protocol interface into the boot services environment.

+  This function calls InstallProtocolInterface() in a loop. If any error

+  occures all the protocols added by this function are removed. This is 

+  basically a lib function to save space.

+

+Arguments:

+

+  Handle      - The handle to install the protocol handlers on,

+                or NULL if a new handle is to be allocated

+  ...         - EFI_GUID followed by protocol instance. A NULL terminates the 

+                list. The pairs are the arguments to InstallProtocolInterface().

+                All the protocols are added to Handle.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Handle is NULL.

+  

+  EFI_SUCCESS                 - Protocol interfaces successfully installed.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreUninstallMultipleProtocolInterfaces (

+  IN EFI_HANDLE           Handle,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Uninstalls a list of protocol interface in the boot services environment. 

+  This function calls UnisatllProtocolInterface() in a loop. This is 

+  basically a lib function to save space.

+

+Arguments:

+

+  Handle      - The handle to uninstall the protocol

+

+  ...         - EFI_GUID followed by protocol instance. A NULL terminates the 

+                list. The pairs are the arguments to UninstallProtocolInterface().

+                All the protocols are added to Handle.

+

+Returns:

+

+  Status code    

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreReinstallProtocolInterface (

+  IN EFI_HANDLE     UserHandle,

+  IN EFI_GUID       *Protocol,

+  IN VOID           *OldInterface,

+  IN VOID           *NewInterface

+  )

+/*++

+

+Routine Description:

+

+  Reinstall a protocol interface on a device handle.  The OldInterface for Protocol is replaced by the NewInterface.

+

+Arguments:

+

+  UserHandle    - Handle on which the interface is to be reinstalled

+  Protocol      - The numeric ID of the interface

+  OldInterface  - A pointer to the old interface

+  NewInterface  - A pointer to the new interface 

+

+

+Returns:

+

+  Status code.

+

+  On EFI_SUCCESS            The protocol interface was installed

+  On EFI_NOT_FOUND          The OldInterface on the handle was not found

+  On EFI_INVALID_PARAMETER  One of the parameters has an invalid value

+  

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreUninstallProtocolInterface (

+  IN EFI_HANDLE       UserHandle,

+  IN EFI_GUID         *Protocol,

+  IN VOID             *Interface

+  )

+/*++

+

+Routine Description:

+

+  Uninstalls all instances of a protocol:interfacer from a handle. 

+  If the last protocol interface is remove from the handle, the 

+  handle is freed.

+

+Arguments:

+

+  UserHandle      - The handle to remove the protocol handler from

+

+  Protocol        - The protocol, of protocol:interface, to remove

+

+  Interface       - The interface, of protocol:interface, to remove

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Protocol is NULL.

+  

+  EFI_SUCCESS                 - Protocol interface successfully uninstalled.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreHandleProtocol (

+  IN  EFI_HANDLE       UserHandle,

+  IN  EFI_GUID         *Protocol,

+  OUT VOID             **Interface

+  )

+/*++

+

+Routine Description:

+

+  Queries a handle to determine if it supports a specified protocol.

+

+Arguments:

+

+  UserHandle  - The handle being queried.

+

+  Protocol    - The published unique identifier of the protocol.

+

+  Interface   - Supplies the address where a pointer to the corresponding Protocol

+               Interface is returned.

+

+Returns:

+

+  The requested protocol interface for the handle

+  

+--*/  

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreOpenProtocol (

+  IN  EFI_HANDLE                UserHandle,

+  IN  EFI_GUID                  *Protocol,

+  OUT VOID                      **Interface OPTIONAL,

+  IN  EFI_HANDLE                ImageHandle,

+  IN  EFI_HANDLE                ControllerHandle,

+  IN  UINT32                    Attributes

+  )

+/*++

+

+Routine Description:

+

+  Locates the installed protocol handler for the handle, and

+  invokes it to obtain the protocol interface. Usage information

+  is registered in the protocol data base.

+

+Arguments:

+

+  UserHandle        - The handle to obtain the protocol interface on

+

+  Protocol          - The ID of the protocol 

+

+  Interface         - The location to return the protocol interface

+

+  ImageHandle       - The handle of the Image that is opening the protocol interface

+                    specified by Protocol and Interface.

+  

+  ControllerHandle  - The controller handle that is requiring this interface.

+

+  Attributes     - The open mode of the protocol interface specified by Handle

+                    and Protocol.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Protocol is NULL.

+  

+  EFI_SUCCESS                 - Get the protocol interface.

+  

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreOpenProtocolInformation (

+  IN  EFI_HANDLE                          UserHandle,

+  IN  EFI_GUID                            *Protocol,

+  OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,

+  OUT UINTN                               *EntryCount

+  )

+/*++

+

+Routine Description:

+

+  Return information about Opened protocols in the system

+

+Arguments:

+

+  UserHandle  - The handle to close the protocol interface on

+

+  Protocol    - The ID of the protocol 

+

+  EntryBuffer - A pointer to a buffer of open protocol information in the form of

+                EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.

+

+  EntryCount  - Number of EntryBuffer entries

+

+Returns:

+

+  

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreCloseProtocol (

+  IN  EFI_HANDLE                UserHandle,

+  IN  EFI_GUID                  *Protocol,

+  IN  EFI_HANDLE                ImageHandle,

+  IN  EFI_HANDLE                ControllerHandle

+  )

+/*++

+

+Routine Description:

+

+  Close Protocol

+

+Arguments:

+

+  UserHandle       - The handle to close the protocol interface on

+

+  Protocol         - The ID of the protocol 

+

+  ImageHandle      - The user of the protocol to close

+

+  ControllerHandle - The user of the protocol to close

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Protocol is NULL.

+    

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreProtocolsPerHandle (

+  IN  EFI_HANDLE       UserHandle,

+  OUT EFI_GUID         ***ProtocolBuffer,

+  OUT UINTN            *ProtocolBufferCount

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated

+ from pool.

+

+Arguments:

+

+  UserHandle           - The handle from which to retrieve the list of protocol interface

+                          GUIDs.

+

+  ProtocolBuffer       - A pointer to the list of protocol interface GUID pointers that are

+                          installed on Handle.

+

+  ProtocolBufferCount  - A pointer to the number of GUID pointers present in

+                          ProtocolBuffer.

+

+Returns:

+  EFI_SUCCESS   -  The list of protocol interface GUIDs installed on Handle was returned in

+                   ProtocolBuffer. The number of protocol interface GUIDs was

+                   returned in ProtocolBufferCount.

+  EFI_INVALID_PARAMETER   -  Handle is NULL.

+  EFI_INVALID_PARAMETER   -  Handle is not a valid EFI_HANDLE.

+  EFI_INVALID_PARAMETER   -  ProtocolBuffer is NULL.

+  EFI_INVALID_PARAMETER   -  ProtocolBufferCount is NULL.

+  EFI_OUT_OF_RESOURCES    -  There is not enough pool memory to store the results.

+  

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreRegisterProtocolNotify (

+  IN  EFI_GUID       *Protocol,

+  IN  EFI_EVENT      Event,

+  OUT VOID           **Registration

+  )

+/*++

+

+Routine Description:

+

+  Add a new protocol notification record for the request protocol.

+

+Arguments:

+

+  Protocol      - The requested protocol to add the notify registration

+

+  Event         - The event to signal 

+

+  Registration  - Returns the registration record

+

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter

+

+  EFI_SUCCESS                 - Successfully returned the registration record that has been added

+  

+--*/

+;

+  

+

+EFI_STATUS

+EFIAPI

+CoreLocateHandle (

+  IN     EFI_LOCATE_SEARCH_TYPE         SearchType,

+  IN     EFI_GUID                       *Protocol OPTIONAL,

+  IN     VOID                           *SearchKey OPTIONAL,

+  IN OUT UINTN                          *BufferSize,

+  OUT    EFI_HANDLE                     *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Locates the requested handle(s) and returns them in Buffer.

+

+Arguments:

+

+  SearchType  - The type of search to perform to locate the handles

+

+  Protocol    - The protocol to search for

+  

+  SearchKey   - Dependant on SearchType

+

+  BufferSize  - On input the size of Buffer.  On output the 

+                size of data returned.  

+

+  Buffer      - The buffer to return the results in

+

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL      - Buffer too small, required buffer size is returned in BufferSize.

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_SUCCESS               - Successfully found the requested handle(s) and returns them in Buffer.

+  

+--*/

+;

+  

+

+EFI_STATUS

+EFIAPI

+CoreLocateDevicePath (

+  IN     EFI_GUID                       *Protocol,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **FilePath,

+  OUT    EFI_HANDLE                     *Device

+  )

+/*++

+

+Routine Description:

+

+  Locates the handle to a device on the device path that supports the specified protocol.

+

+Arguments:

+

+  Protocol    - The protocol to search for.

+  FilePath    - On input, a pointer to a pointer to the device path. On output, the device

+                  path pointer is modified to point to the remaining part of the devicepath.

+  Device      - A pointer to the returned device handle.              

+

+Returns:

+

+  EFI_SUCCESS           - The resulting handle was returned.

+  EFI_NOT_FOUND         - No handles matched the search.

+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value.

+

+--*/

+;

+

+ 

+EFI_STATUS

+EFIAPI

+CoreLocateHandleBuffer (

+  IN     EFI_LOCATE_SEARCH_TYPE         SearchType,

+  IN     EFI_GUID                       *Protocol OPTIONAL,

+  IN     VOID                           *SearchKey OPTIONAL,

+  IN OUT UINTN                          *NumberHandles,

+  OUT    EFI_HANDLE                     **Buffer

+  )

+/*++

+

+Routine Description:

+

+  Function returns an array of handles that support the requested protocol 

+  in a buffer allocated from pool. This is a version of CoreLocateHandle()

+  that allocates a buffer for the caller.

+

+Arguments:

+

+  SearchType           - Specifies which handle(s) are to be returned.

+  Protocol             - Provides the protocol to search by.   

+                         This parameter is only valid for SearchType ByProtocol.

+  SearchKey            - Supplies the search key depending on the SearchType.

+  NumberHandles      - The number of handles returned in Buffer.

+  Buffer               - A pointer to the buffer to return the requested array of 

+                         handles that support Protocol.

+

+Returns:

+  

+  EFI_SUCCESS             - The result array of handles was returned.

+  EFI_NOT_FOUND           - No handles match the search. 

+  EFI_OUT_OF_RESOURCES    - There is not enough pool memory to store the matching results.

+  EFI_INVALID_PARAMETER   - Invalid parameter

+

+--*/

+;

+

+ 

+EFI_STATUS

+EFIAPI

+CoreLocateProtocol (

+  IN    EFI_GUID  *Protocol,

+  IN    VOID      *Registration OPTIONAL,

+  OUT   VOID      **Interface

+  )

+/*++

+

+Routine Description:

+

+  Return the first Protocol Interface that matches the Protocol GUID. If

+  Registration is pasased in return a Protocol Instance that was just add

+  to the system. If Retistration is NULL return the first Protocol Interface

+  you find.

+

+Arguments:

+

+  Protocol     - The protocol to search for

+  

+  Registration - Optional Registration Key returned from RegisterProtocolNotify() 

+

+  Interface    - Return the Protocol interface (instance).

+

+Returns:

+

+  EFI_SUCCESS                 - If a valid Interface is returned

+  

+  EFI_INVALID_PARAMETER       - Invalid parameter

+  

+  EFI_NOT_FOUND               - Protocol interface not found

+

+--*/

+;

+

+UINT64

+CoreGetHandleDatabaseKey (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  return handle database key.

+

+Arguments:

+

+  None

+  

+Returns:

+  

+  Handle database key.

+  

+--*/

+;

+

+VOID

+CoreConnectHandlesByKey (

+  UINT64  Key

+  )

+/*++

+

+Routine Description:

+

+  Go connect any handles that were created or modified while a image executed.

+

+Arguments:

+

+  Key  -  The Key to show that the handle has been created/modified

+

+Returns:

+  

+  None

+--*/

+;

+

+

+EFI_STATUS 

+EFIAPI

+CoreConnectController (

+  IN  EFI_HANDLE                ControllerHandle,

+  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL,

+  IN  BOOLEAN                   Recursive

+  )

+/*++

+

+Routine Description:

+

+  Connects one or more drivers to a controller.

+

+Arguments:

+

+  ControllerHandle            - Handle of the controller to be connected.

+

+  DriverImageHandle           - DriverImageHandle A pointer to an ordered list of driver image handles.

+

+  RemainingDevicePath         - RemainingDevicePath A pointer to the device path that specifies a child of the

+                                controller specified by ControllerHandle.

+    

+  Recursive -                 - Whether the function would be called recursively or not.

+

+Returns:

+

+  Status code.

+

+--*/

+;

+

+

+EFI_STATUS 

+EFIAPI

+CoreDisconnectController (

+  IN EFI_HANDLE  ControllerHandle,

+  IN EFI_HANDLE  DriverImageHandle  OPTIONAL,

+  IN EFI_HANDLE  ChildHandle        OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Disonnects a controller from a driver

+

+Arguments:

+

+  ControllerHandle  - ControllerHandle The handle of the controller from which driver(s) 

+                        are to be disconnected.

+  DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.

+  ChildHandle       - ChildHandle The handle of the child to destroy.

+

+Returns:

+

+  EFI_SUCCESS           -  One or more drivers were disconnected from the controller.

+  EFI_SUCCESS           -  On entry, no drivers are managing ControllerHandle.

+  EFI_SUCCESS           -  DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.

+  EFI_INVALID_PARAMETER -  ControllerHandle is not a valid EFI_HANDLE.

+  EFI_INVALID_PARAMETER -  DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.

+  EFI_INVALID_PARAMETER -  ChildHandle is not NULL, and it is not a valid EFI_HANDLE.

+  EFI_OUT_OF_RESOURCES  -  There are not enough resources available to disconnect any drivers from ControllerHandle.

+  EFI_DEVICE_ERROR      -  The controller could not be disconnected because of a device error.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreAllocatePages (

+  IN      EFI_ALLOCATE_TYPE       Type,

+  IN      EFI_MEMORY_TYPE         MemoryType,

+  IN      UINTN                   NumberOfPages,

+  IN OUT  EFI_PHYSICAL_ADDRESS    *Memory

+  )

+/*++

+

+Routine Description:

+

+  Allocates pages from the memory map.

+

+Arguments:

+

+  Type          - The type of allocation to perform

+

+  MemoryType    - The type of memory to turn the allocated pages into

+

+  NumberOfPages - The number of pages to allocate

+

+  Memory        - A pointer to receive the base allocated memory address

+

+Returns:

+

+  Status. On success, Memory is filled in with the base address allocated

+  

+  EFI_INVALID_PARAMETER     - Parameters violate checking rules defined in spec.

+  

+  EFI_NOT_FOUND             - Could not allocate pages match the requirement.

+  

+  EFI_OUT_OF_RESOURCES      - No enough pages to allocate.

+  

+  EFI_SUCCESS               - Pages successfully allocated.

+

+--*/

+;

+

+

+EFI_STATUS 

+EFIAPI

+CoreFreePages (

+  IN EFI_PHYSICAL_ADDRESS   Memory,

+  IN UINTN                  NumberOfPages

+  )

+/*++

+

+Routine Description:

+

+  Frees previous allocated pages.

+

+Arguments:

+

+  Memory        - Base address of memory being freed

+

+  NumberOfPages - The number of pages to free

+

+Returns:

+

+  EFI_NOT_FOUND       - Could not find the entry that covers the range

+  

+  EFI_INVALID_PARAMETER   - Address not aligned

+  

+  EFI_SUCCESS         -Pages successfully freed.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreGetMemoryMap (

+  IN OUT UINTN                       *MemoryMapSize,

+  IN OUT EFI_MEMORY_DESCRIPTOR       *Desc,

+  OUT    UINTN                       *MapKey,

+  OUT    UINTN                       *DescriptorSize,

+  OUT    UINT32                      *DescriptorVersion

+  )

+/*++

+

+Routine Description:

+

+  Returns the current memory map.

+

+Arguments:

+

+  MemoryMapSize     - On input the buffer size of MemoryMap allocated by caller

+                      On output the required buffer size to contain the memory map 

+                      

+  Desc              - The buffer to return the current memory map

+

+  MapKey            - The address to return the current map key

+

+  DescriptorSize    - The size in bytes for an individual EFI_MEMORY_DESCRIPTOR

+

+  DescriptorVersion - The version number associated with the EFI_MEMORY_DESCRIPTOR

+

+Returns:

+

+  EFI_SUCCESS           The current memory map was returned successfully

+

+  EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small

+

+  EFI_INVALID_PARAMETER One of the parameters has an invalid value

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreAllocatePool (

+  IN   EFI_MEMORY_TYPE  PoolType,

+  IN   UINTN            Size,

+  OUT  VOID             **Buffer

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of a particular type.

+

+Arguments:

+

+  PoolType    - Type of pool to allocate

+

+  Size        - The amount of pool to allocate

+

+  Buffer      - The address to return a pointer to the allocated pool

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - PoolType not valid

+  

+  EFI_OUT_OF_RESOURCES      - Size exceeds max pool size or allocation failed.  

+  

+  EFI_SUCCESS               - Pool successfully allocated.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreFreePool (

+  IN VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Frees pool.

+

+Arguments:

+

+  Buffer      - The allocated pool entry to free

+

+Returns:

+

+  EFI_INVALID_PARAMETER   - Buffer is not a valid value.

+  

+  EFI_SUCCESS             - Pool successfully freed.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreLoadImage (

+  IN  BOOLEAN                    BootPolicy,

+  IN  EFI_HANDLE                 ParentImageHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL   *FilePath,

+  IN  VOID                       *SourceBuffer   OPTIONAL,

+  IN  UINTN                      SourceSize,

+  OUT EFI_HANDLE                 *ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Loads an EFI image into memory and returns a handle to the image.

+

+Arguments:

+

+  BootPolicy          - If TRUE, indicates that the request originates from the boot manager,

+                        and that the boot manager is attempting to load FilePath as a boot selection.

+  ParentImageHandle   - The caller's image handle.

+  FilePath            - The specific file path from which the image is loaded.

+  SourceBuffer        - If not NULL, a pointer to the memory location containing a copy of 

+                        the image to be loaded.

+  SourceSize          - The size in bytes of SourceBuffer.

+  ImageHandle         - Pointer to the returned image handle that is created when the image 

+                        is successfully loaded.

+

+Returns:

+

+  EFI_SUCCESS            - The image was loaded into memory.

+  EFI_NOT_FOUND          - The FilePath was not found.

+  EFI_INVALID_PARAMETER  - One of the parameters has an invalid value.

+  EFI_UNSUPPORTED        - The image type is not supported, or the device path cannot be 

+                           parsed to locate the proper protocol for loading the file.

+  EFI_OUT_OF_RESOURCES   - Image was not loaded due to insufficient resources.

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreUnloadImage (

+  IN EFI_HANDLE  ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Unload the specified image.

+

+Arguments:

+

+  ImageHandle       - The specified image handle.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Image handle is NULL.

+  

+  EFI_UNSUPPORTED             - Attempt to unload an unsupported image.

+  

+  EFI_SUCCESS                 - Image successfully unloaded.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreStartImage (

+  IN  EFI_HANDLE  ImageHandle,

+  OUT UINTN       *ExitDataSize,

+  OUT CHAR16      **ExitData  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Transfer control to a loaded image's entry point.

+

+Arguments:

+

+  ImageHandle     - Handle of image to be started.

+  

+  ExitDataSize    - Pointer of the size to ExitData

+  

+  ExitData        - Pointer to a pointer to a data buffer that includes a Null-terminated

+                    Unicode string, optionally followed by additional binary data. The string

+                    is a description that the caller may use to further indicate the reason for

+                    the image¡¯s exit.

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES       - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Successfully transfer control to the image's entry point.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreExit (

+  IN EFI_HANDLE  ImageHandle,

+  IN EFI_STATUS  Status,

+  IN UINTN       ExitDataSize,

+  IN CHAR16      *ExitData  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Terminates the currently loaded EFI image and returns control to boot services.

+

+Arguments:

+

+  ImageHandle       - Handle that identifies the image. This parameter is passed to the image 

+                      on entry.

+  Status            - The image¡¯s exit code.

+  ExitDataSize      - The size, in bytes, of ExitData. Ignored if ExitStatus is

+                      EFI_SUCCESS.

+  ExitData          - Pointer to a data buffer that includes a Null-terminated Unicode string,

+                      optionally followed by additional binary data. The string is a 

+                      description that the caller may use to further indicate the reason for

+                      the image¡¯s exit.

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Image handle is NULL or it is not current image.

+  

+  EFI_SUCCESS               - Successfully terminates the currently loaded EFI image.

+  

+  EFI_ACCESS_DENIED         - Should never reach there.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreCreateEvent (

+  IN  UINT32               Type,

+  IN  EFI_TPL              NotifyTpl,

+  IN  EFI_EVENT_NOTIFY     NotifyFunction,

+  IN  VOID                 *NotifyContext,

+  OUT EFI_EVENT            *pEvent

+  )

+/*++

+

+Routine Description:

+

+  Creates a general-purpose event structure

+

+Arguments:

+

+  Type                - The type of event to create and its mode and attributes

+  NotifyTpl           - The task priority level of event notifications

+  NotifyFunction      - Pointer to the eventÂ’s notification function

+  NotifyContext       - Pointer to the notification functionÂ’s context; corresponds to

+                        parameter "Context" in the notification function

+  pEvent              - Pointer to the newly created event if the call succeeds; undefined otherwise

+

+Returns:

+

+  EFI_SUCCESS           - The event structure was created

+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value

+  EFI_OUT_OF_RESOURCES  - The event could not be allocated

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreCreateEventEx (

+  IN UINT32                   Type,

+  IN EFI_TPL                  NotifyTpl,

+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL

+  IN CONST VOID               *NotifyContext, OPTIONAL

+  IN CONST EFI_GUID           *EventGroup,    OPTIONAL

+  OUT EFI_EVENT               *Event

+  )

+/*++

+

+Routine Description:

+  Creates a general-purpose event structure

+

+Arguments:

+  Type                - The type of event to create and its mode and attributes

+  NotifyTpl           - The task priority level of event notifications

+  NotifyFunction      - Pointer to the events notification function

+  NotifyContext       - Pointer to the notification functions context; corresponds to

+                        parameter "Context" in the notification function

+  EventGrout          - GUID for EventGroup if NULL act the same as gBS->CreateEvent().

+  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise

+

+Returns:

+  EFI_SUCCESS           - The event structure was created

+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value

+  EFI_OUT_OF_RESOURCES  - The event could not be allocated

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreSetTimer (

+  IN EFI_EVENT            Event,

+  IN EFI_TIMER_DELAY      Type,

+  IN UINT64               TriggerTime

+  )

+/*++

+

+Routine Description:

+

+  Sets the type of timer and the trigger time for a timer event.

+

+Arguments:

+

+  UserEvent   - The timer event that is to be signaled at the specified time

+  Type        - The type of time that is specified in TriggerTime

+  TriggerTime - The number of 100ns units until the timer expires

+  

+Returns:

+

+  EFI_SUCCESS           - The event has been set to be signaled at the requested time

+  EFI_INVALID_PARAMETER - Event or Type is not valid

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreSignalEvent (

+  IN EFI_EVENT            Event

+  )

+/*++

+

+Routine Description:

+

+  Signals the event.  Queues the event to be notified if needed

+    

+Arguments:

+

+  Event - The event to signal

+    

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameters are not valid.

+  

+  EFI_SUCCESS - The event was signaled.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreWaitForEvent (

+  IN  UINTN        NumberOfEvents,

+  IN  EFI_EVENT    *UserEvents,

+  OUT UINTN        *UserIndex

+  )

+/*++

+

+Routine Description:

+

+  Stops execution until an event is signaled.

+    

+Arguments:

+

+  NumberOfEvents  - The number of events in the UserEvents array

+  UserEvents      - An array of EFI_EVENT

+  UserIndex       - Pointer to the index of the event which satisfied the wait condition

+    

+Returns:

+

+  EFI_SUCCESS           - The event indicated by Index was signaled.

+  EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or 

+                          Event was not a valid type

+  EFI_UNSUPPORTED       - The current TPL is not TPL_APPLICATION

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreCloseEvent (

+  IN EFI_EVENT            Event

+  )

+/*++

+

+Routine Description:

+

+  Closes an event and frees the event structure.

+    

+Arguments:

+

+  UserEvent - Event to close

+    

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameters are not valid.

+  

+  EFI_SUCCESS - The event has been closed

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreCheckEvent (

+  IN EFI_EVENT            Event

+  )

+/*++

+

+Routine Description:

+

+  Check the status of an event

+    

+Arguments:

+

+  UserEvent - The event to check

+    

+Returns:

+

+  EFI_SUCCESS           - The event is in the signaled state

+  EFI_NOT_READY         - The event is not in the signaled state

+  EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL

+

+--*/

+;

+

+EFI_STATUS

+CoreAddMemorySpace (

+  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Capabilities

+  )

+/*++

+

+Routine Description:

+

+  Add a segment of memory space to GCD map and add all available pages in this segment 

+  as memory descriptors.

+

+Arguments:

+    

+  GcdMemoryType     - Memory type of the segment.

+  

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+  Capabilities      - alterable attributes of the segment.

+

+Returns:

+

+  EFI_SUCCESS       - Merged this segment into GCD map.

+

+--*/

+;

+

+EFI_STATUS

+CoreAllocateMemorySpace (

+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,

+  IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,

+  IN     UINTN                  Alignment,

+  IN     UINT64                 Length,

+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,

+  IN     EFI_HANDLE             ImageHandle,

+  IN     EFI_HANDLE             DeviceHandle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Allocate memory space on GCD map.

+

+Arguments:

+  

+  GcdAllocateType   - The type of allocate operation

+  

+  GcdMemoryType     - The desired memory type

+  

+  Alignment         - Align with 2^Alignment

+  

+  Length            - Length to allocate

+  

+  BaseAddress       - Base address to allocate

+  

+  ImageHandle       - The image handle consume the allocated space.

+  

+  DeviceHandle      - The device handle consume the allocated space.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter.

+  

+  EFI_NOT_FOUND               - No descriptor contains the desired space.

+  

+  EFI_SUCCESS                 - Memory space successfully allocated.

+

+--*/

+;

+

+EFI_STATUS

+CoreFreeMemorySpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:Routine Description:

+

+  Free a segment of memory space in GCD map.

+

+Arguments:

+    

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+Returns:

+

+  EFI_SUCCESS       - Space successfully freed.

+

+--*/

+;

+

+EFI_STATUS

+CoreRemoveMemorySpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:Routine Description:

+

+  Remove a segment of memory space in GCD map.

+

+Arguments:

+    

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+Returns:

+

+  EFI_SUCCESS       - Successfully a segment of memory space.

+

+--*/

+;

+

+EFI_STATUS

+CoreGetMemorySpaceDescriptor (

+  IN  EFI_PHYSICAL_ADDRESS             BaseAddress,

+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor

+  )

+/*++

+

+Routine Description:

+

+  Search all entries in GCD map which contains specified segment and build it to a descriptor.

+

+Arguments:

+

+  BaseAddress       - Specified start address

+  

+  Descriptor        - Specified length

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter

+  

+  EFI_SUCCESS                 - Successfully get memory space descriptor.

+

+--*/

+;

+

+EFI_STATUS

+CoreSetMemorySpaceAttributes (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Attributes

+  )

+/*++

+

+Routine Description:

+

+  Set memory space with specified attributes.

+

+Arguments:

+

+  BaseAddress       - Specified start address

+  

+  Length            - Specified length

+  

+  Attributes        - Specified attributes

+

+Returns:

+

+  EFI_SUCCESS       - Successfully set attribute of a segment of memory space.

+

+--*/

+;

+

+EFI_STATUS

+CoreGetMemorySpaceMap (

+  OUT UINTN                            *NumberOfDescriptors,

+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  **MemorySpaceMap

+  )

+/*++

+

+Routine Description:

+

+  Transer all entries of GCD memory map into memory descriptors and pass to caller.

+

+Arguments:

+

+  NumberOfDescriptors       - Number of descriptors.

+  

+  MemorySpaceMap            - Descriptor array

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Successfully get memory space map.

+

+--*/

+;

+

+EFI_STATUS

+CoreAddIoSpace (

+  IN EFI_GCD_IO_TYPE       GcdIoType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:

+

+  Add a segment of IO space to GCD map.

+

+Arguments:

+    

+  GcdIoType         - IO type of the segment.

+  

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+

+Returns:

+

+  EFI_SUCCESS       - Merged this segment into GCD map.

+

+--*/

+;

+

+EFI_STATUS

+CoreAllocateIoSpace (

+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,

+  IN     EFI_GCD_IO_TYPE        GcdIoType,

+  IN     UINTN                  Alignment,

+  IN     UINT64                 Length,

+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,

+  IN     EFI_HANDLE             ImageHandle,

+  IN     EFI_HANDLE             DeviceHandle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Allocate IO space on GCD map.

+

+Arguments:

+  

+  GcdAllocateType   - The type of allocate operation

+  

+  GcdIoType         - The desired IO type

+  

+  Alignment         - Align with 2^Alignment

+  

+  Length            - Length to allocate

+  

+  BaseAddress       - Base address to allocate

+  

+  ImageHandle       - The image handle consume the allocated space.

+  

+  DeviceHandle      - The device handle consume the allocated space.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter.

+  

+  EFI_NOT_FOUND               - No descriptor contains the desired space.

+  

+  EFI_SUCCESS                 - IO space successfully allocated.

+

+--*/

+;

+

+EFI_STATUS

+CoreFreeIoSpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:Routine Description:

+

+  Free a segment of IO space in GCD map.

+

+Arguments:

+    

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+Returns:

+

+  EFI_SUCCESS       - Space successfully freed.

+

+--*/

+;

+

+EFI_STATUS

+CoreRemoveIoSpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:Routine Description:

+

+  Remove a segment of IO space in GCD map.

+

+Arguments:

+    

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+Returns:

+

+  EFI_SUCCESS       - Successfully removed a segment of IO space.

+

+--*/

+;

+

+EFI_STATUS

+CoreGetIoSpaceDescriptor (

+  IN  EFI_PHYSICAL_ADDRESS         BaseAddress,

+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor

+  )

+/*++

+

+Routine Description:

+

+  Search all entries in GCD map which contains specified segment and build it to a descriptor.

+

+Arguments:

+

+  BaseAddress       - Specified start address

+  

+  Descriptor        - Specified length

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Descriptor is NULL.

+  

+  EFI_SUCCESS                 - Successfully get the IO space descriptor.

+

+--*/

+;

+

+EFI_STATUS

+CoreGetIoSpaceMap (

+  OUT UINTN                        *NumberOfDescriptors,

+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  **IoSpaceMap

+  )

+/*++

+

+Routine Description:

+

+  Transer all entries of GCD IO map into IO descriptors and pass to caller.

+

+Arguments:

+

+  NumberOfDescriptors       - Number of descriptors.

+  

+  IoSpaceMap                - Descriptor array

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Successfully get IO space map.

+

+--*/

+;

+

+EFI_DXESERVICE

+EFI_STATUS

+EFIAPI

+CoreDispatcher (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This is the main Dispatcher for DXE and it exits when there are no more 

+  drivers to run. Drain the mScheduledQueue and load and start a PE

+  image for each driver. Search the mDiscoveredList to see if any driver can 

+  be placed on the mScheduledQueue. If no drivers are placed on the

+  mScheduledQueue exit the function. On exit it is assumed the Bds()

+  will be called, and when the Bds() exits the Dispatcher will be called 

+  again.

+

+Arguments:

+

+  NONE

+

+Returns:

+

+  EFI_ALREADY_STARTED - The DXE Dispatcher is already running

+

+  EFI_NOT_FOUND       - No DXE Drivers were dispatched

+

+  EFI_SUCCESS         - One or more DXE Drivers were dispatched

+

+--*/

+;

+EFI_DXESERVICE

+EFI_STATUS

+EFIAPI

+CoreSchedule (

+  IN  EFI_HANDLE  FirmwareVolumeHandle,

+  IN  EFI_GUID    *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Check every driver and locate a matching one. If the driver is found, the Unrequested

+  state flag is cleared.

+

+Arguments:

+

+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware 

+                         file specified by DriverName.

+

+  DriverName           - The Driver name to put in the Dependent state.

+

+Returns:

+

+  EFI_SUCCESS   - The DriverName was found and it's SOR bit was cleared

+

+  EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.

+

+--*/

+;

+

+EFI_DXESERVICE

+EFI_STATUS

+EFIAPI

+CoreTrust (

+  IN  EFI_HANDLE  FirmwareVolumeHandle,

+  IN  EFI_GUID    *DriverName

+  )

+/*++

+

+Routine Description:

+

+  Convert a driver from the Untrused back to the Scheduled state

+

+Arguments:

+

+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware 

+                         file specified by DriverName.

+

+  DriverName           - The Driver name to put in the Scheduled state

+

+Returns:

+

+  EFI_SUCCESS   - The file was found in the untrusted state, and it was promoted 

+                  to the trusted state.

+

+  EFI_NOT_FOUND - The file was not found in the untrusted state.

+

+--*/

+;

+

+BOOLEAN

+CoreGrowBuffer (

+  IN OUT EFI_STATUS       *Status,

+  IN OUT VOID             **Buffer,

+  IN     UINTN            BufferSize

+  )

+/*++

+

+Routine Description:

+

+    Helper function called as part of the code needed

+    to allocate the proper sized buffer for various 

+    EFI interfaces.

+

+Arguments:

+

+    Status      - Current status

+

+    Buffer      - Current allocated buffer, or NULL

+

+    BufferSize  - Current buffer size needed

+    

+Returns:

+    

+    TRUE - if the buffer was reallocated and the caller 

+    should try the API again.

+

+    FALSE - buffer could not be allocated and the caller

+    should not try the API again.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+FwVolDriverInit (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+/*++

+

+Routine Description:

+    This routine is the driver initialization entry point.  It initializes the

+    libraries, and registers two notification functions.  These notification

+    functions are responsible for building the FV stack dynamically.

+    

+Arguments:

+    ImageHandle   - The image handle.

+    SystemTable   - The system table.

+    

+Returns:

+    EFI_SUCCESS   - Function successfully returned.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+InitializeSectionExtraction (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+/*++

+

+Routine Description: 

+  Entry point of the section extraction code. Initializes an instance of the 

+  section extraction interface and installs it on a new handle.

+

+Arguments:  

+  ImageHandle   EFI_HANDLE: A handle for the image that is initializing this driver

+  SystemTable   EFI_SYSTEM_TABLE: A pointer to the EFI system table        

+

+Returns:  

+  EFI_SUCCESS:  Driver initialized successfully

+  EFI_OUT_OF_RESOURCES:   Could not allocate needed resources

+

+--*/

+;

+

+EFI_STATUS

+CoreProcessFirmwareVolume (

+  IN  VOID                         *FvHeader,

+  IN  UINTN                        Size, 

+  OUT EFI_HANDLE                   *FVProtocolHandle

+  )

+/*++

+

+Routine Description:

+    This DXE service routine is used to process a firmware volume. In

+    particular, it can be called by BDS to process a single firmware

+    volume found in a capsule. 

+

+Arguments:

+    FvHeader              - pointer to a firmware volume header

+    Size                  - the size of the buffer pointed to by FvHeader

+    FVProtocolHandle      - the handle on which a firmware volume protocol

+                            was produced for the firmware volume passed in.

+

+Returns:

+    EFI_OUT_OF_RESOURCES  - if an FVB could not be produced due to lack of 

+                            system resources

+    EFI_VOLUME_CORRUPTED  - if the volume was corrupted

+    EFI_SUCCESS           - a firmware volume protocol was produced for the

+                            firmware volume

+

+--*/

+;

+

+//

+//Functions used during debug buils

+//

+VOID

+CoreDisplayMissingArchProtocols (

+  VOID

+  )

+/*++

+

+  Routine Description:

+  Displays Architectural protocols that were not loaded and are required for DXE core to function

+  Only used in Debug Builds

+

+  Arguments:

+    NONE

+

+  Returns:

+    NONE

+

+--*/;

+  

+VOID

+CoreDisplayDiscoveredNotDispatched (

+  VOID

+  )

+/*++

+

+  Routine Description:

+

+    Traverse the discovered list for any drivers that were discovered but not loaded 

+    because the dependency experessions evaluated to false

+

+  Arguments:

+

+    NONE

+

+  Returns:

+

+    NONE 

+

+--*/;

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/DxeMain.mbd b/edk2/EdkModulePkg/Core/Dxe/DxeMain.mbd
new file mode 100644
index 0000000..55967ca
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/DxeMain.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+    <MbdHeader>
+        <BaseName>DxeMain</BaseName>
+        <Guid>D6A2CB7F-6A18-4e2f-B43B-9920A733700A</Guid>
+        <Version>0</Version>
+        <Description>FIX ME!</Description>
+        <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+        <License> All rights reserved. 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. </License>
+        <Created>2006-03-12 17:09</Created>
+        <Modified>2006-03-19 15:18</Modified>
+    </MbdHeader>
+    <Libraries>
+        <Library>BaseLib</Library>
+        <Library>BaseCacheMaintenanceLib</Library>
+        <Library>DxeReportStatusCodeLib</Library>
+        <Library>BaseDebugLibReportStatusCode</Library>
+        <Library OverrideID="1111">DxeCoreUefiDecompressLibFromHob</Library>
+        <Library OverrideID="1111">DxeCoreTianoDecompressLibFromHob</Library>
+        <Library OverrideID="3333">DxeCoreCustomDecompressLibFromHob</Library>
+        <Library OverrideID="4444">EdkDxePeCoffLoaderFromHobLib</Library>
+        <Library>DxeCoreHobLib</Library>
+        <Library>DxeCoreEntryPoint</Library>
+        <Library>BaseMemoryLib</Library>
+        <Library>UefiLib</Library>
+        <Library>BasePerformanceLibNull</Library>
+    </Libraries>
+    <BuildOptions ToolChain="MSFT">
+        <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+        <Option>C_PROJ_FLAGS = ${C_PROJ_FLAGS} /Ob0</Option>
+    </BuildOptions>
+</ModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Core/Dxe/DxeMain.msa b/edk2/EdkModulePkg/Core/Dxe/DxeMain.msa
new file mode 100644
index 0000000..5204e54
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/DxeMain.msa
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+    <MsaHeader>
+        <BaseName>DxeMain</BaseName>
+        <ModuleType>DXE_CORE</ModuleType>
+        <ComponentType>BS_DRIVER</ComponentType>
+        <Guid>D6A2CB7F-6A18-4e2f-B43B-9920A733700A</Guid>
+        <Version>0</Version>
+        <Abstract>Component description file for DxeMain.</Abstract>
+        <Description>FIX ME!</Description>
+        <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+        <License> All rights reserved. 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. </License>
+        <Created>2006-03-12 17:09</Created>
+        <Updated>2006-03-19 15:18</Updated>
+        <Specification>0</Specification>
+    </MsaHeader>
+    <LibraryClassDefinitions>
+        <LibraryClass Usage="ALWAYS_CONSUMED">DxeCoreEntryPoint</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">UefiDecompressLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">TianoDecompressLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">CustomDecompressLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">EdkPeCoffLoaderLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">CacheMaintenanceLib</LibraryClass>
+        <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+    </LibraryClassDefinitions>
+    <SourceFiles>
+        <Filename>DxeMain/DxeMain.c</Filename>
+        <Filename>DxeMain/DxeProtocolNotify.c</Filename>
+        <Filename>Dispatcher/Dispatcher.c</Filename>
+        <Filename>Dispatcher/dependency.c</Filename>
+        <Filename>Event/execdata.c</Filename>
+        <Filename>Event/event.c</Filename>
+        <Filename>Event/timer.c</Filename>
+        <Filename>Event/tpl.c</Filename>
+        <Filename>FwVol/FwVol.c</Filename>
+        <Filename>FwVol/Ffs.c</Filename>
+        <Filename>FwVol/FwVolAttrib.c</Filename>
+        <Filename>FwVol/FwVolRead.c</Filename>
+        <Filename>FwVol/FwVolWrite.c</Filename>
+        <Filename>FwVolBlock/FwVolBlock.c</Filename>
+        <Filename>Mem/memdata.c</Filename>
+        <Filename>Mem/Page.c</Filename>
+        <Filename>Mem/pool.c</Filename>
+        <Filename>Gcd/gcd.c</Filename>
+        <Filename>Hand/handle.c</Filename>
+        <Filename>Hand/locate.c</Filename>
+        <Filename>Hand/Notify.c</Filename>
+        <Filename>Hand/DriverSupport.c</Filename>
+        <Filename>Library/Library.c</Filename>
+        <Filename>Misc/InstallConfigurationTable.c</Filename>
+        <Filename>Misc/SetWatchdogTimer.c</Filename>
+        <Filename>Misc/Stall.c</Filename>
+        <Filename>Misc/DebugImageInfo.c</Filename>
+        <Filename>Image/Image.c</Filename>
+        <Filename>Image/ImageFile.c</Filename>
+        <Filename>SectionExtraction/CoreSectionExtraction.c</Filename>
+        <Filename>DebugImageInfo.h</Filename>
+        <Filename>DebugMask.h</Filename>
+        <Filename>DxeMain.h</Filename>
+        <Filename>Exec.h</Filename>
+        <Filename>FwVolBlock.h</Filename>
+        <Filename>FwVolDriver.h</Filename>
+        <Filename>Gcd.h</Filename>
+        <Filename>Hand.h</Filename>
+        <Filename>Image.h</Filename>
+        <Filename>Imem.h</Filename>
+        <Filename>Library.h</Filename>
+    </SourceFiles>
+    <Includes>
+        <PackageName>MdePkg</PackageName>
+        <PackageName>EdkModulePkg</PackageName>
+    </Includes>
+    <Protocols>
+        <Protocol Usage="SOMETIMES_CONSUMED">Ebc</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Cpu</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolume</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeDispatch</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">SectionExtraction</Protocol>
+        <Protocol Usage="SOMETIMES_CONSUMED">DriverBinding</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">PlatformDriverOverride</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">BusSpecificDriverOverride</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Timer</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Metronome</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">MonotonicCounter</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Bds</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Security</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">WatchdogTimer</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Runtime</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">RealTimeClock</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Reset</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">LoadFile</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">SimpleFileSystem</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">LoadPeImage</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">CustomizedDecompress</Protocol>
+        <Protocol Usage="ALWAYS_CONSUMED">TianoDecompress</Protocol>
+    </Protocols>
+    <Guids>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>MemoryTypeInformation</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>DxeServicesTable</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>HobList</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>DebugImageInfoTable</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>Apriori</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>FirmwareFileSystem</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>FileInfo</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>HobMemoryAllocModule</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>PeiPeCoffLoader</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>LoadPeImage</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>EventExitBootServices</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>EventVirtualAddressChange</C_Name>
+        </GuidEntry>
+        <GuidEntry Usage="ALWAYS_CONSUMED">
+            <C_Name>EventMemoryMapChange</C_Name>
+        </GuidEntry>
+    </Guids>
+    <Externs>
+        <Extern>
+            <ModuleEntryPoint>DxeMain</ModuleEntryPoint>
+        </Extern>
+    </Externs>
+    <BuildOptions>
+        <Option>BUILD_TYPE=DXE_CORE</Option>
+    </BuildOptions>
+</ModuleSurfaceArea>
diff --git a/edk2/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c b/edk2/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c
new file mode 100644
index 0000000..67a26fe
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -0,0 +1,1083 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. 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.             
+
+Module Name:
+
+  DxeMain.c
+
+Abstract:
+
+  DXE Core Main Entry Point
+
+--*/
+
+#include <DxeMain.h>
+
+VOID
+EFIAPI
+DxeMain (
+  IN  VOID *HobStart
+  );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg0 (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg1 (
+  UINTN Arg1
+  );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg2 (
+  UINTN Arg1,
+  UINTN Arg2
+  );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg3 (
+  UINTN Arg1,
+  UINTN Arg2,
+  UINTN Arg3
+  );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg4 (
+  UINTN Arg1,
+  UINTN Arg2,
+  UINTN Arg3,
+  UINTN Arg4
+  );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg5 (
+  UINTN Arg1,
+  UINTN Arg2,
+  UINTN Arg3,
+  UINTN Arg4,
+  UINTN Arg5
+  );
+
+EFI_STATUS
+CoreGetPeiProtocol (
+  IN EFI_GUID  *ProtocolGuid,
+  IN VOID      **Interface
+  );
+  
+EFI_STATUS
+DxeMainUefiDecompressGetInfo (
+  IN EFI_DECOMPRESS_PROTOCOL            *This,
+  IN   VOID                             *Source,
+  IN   UINT32                           SourceSize,
+  OUT  UINT32                           *DestinationSize,
+  OUT  UINT32                           *ScratchSize
+  );
+
+EFI_STATUS
+EFIAPI
+DxeMainUefiDecompress (
+  IN EFI_DECOMPRESS_PROTOCOL              *This,
+  IN     VOID                             *Source,
+  IN     UINT32                           SourceSize,
+  IN OUT VOID                             *Destination,
+  IN     UINT32                           DestinationSize,
+  IN OUT VOID                             *Scratch,
+  IN     UINT32                           ScratchSize
+  );
+
+EFI_STATUS
+DxeMainTianoDecompressGetInfo (
+  IN EFI_TIANO_DECOMPRESS_PROTOCOL      *This,
+  IN   VOID                             *Source,
+  IN   UINT32                           SourceSize,
+  OUT  UINT32                           *DestinationSize,
+  OUT  UINT32                           *ScratchSize
+  );
+
+EFI_STATUS
+EFIAPI
+DxeMainTianoDecompress (
+  IN EFI_TIANO_DECOMPRESS_PROTOCOL        *This,
+  IN     VOID                             *Source,
+  IN     UINT32                           SourceSize,
+  IN OUT VOID                             *Destination,
+  IN     UINT32                           DestinationSize,
+  IN OUT VOID                             *Scratch,
+  IN     UINT32                           ScratchSize
+  );
+
+EFI_STATUS
+DxeMainCustomDecompressGetInfo (
+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  *This,
+  IN   VOID                              *Source,
+  IN   UINT32                            SourceSize,
+  OUT  UINT32                            *DestinationSize,
+  OUT  UINT32                            *ScratchSize
+  );
+
+EFI_STATUS
+EFIAPI
+DxeMainCustomDecompress (
+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  *This,
+  IN     VOID                            *Source,
+  IN     UINT32                          SourceSize,
+  IN OUT VOID                            *Destination,
+  IN     UINT32                          DestinationSize,
+  IN OUT VOID                            *Scratch,
+  IN     UINT32                          ScratchSize
+  );
+
+//
+// DXE Core Global Variables for Protocols from PEI
+//
+EFI_HANDLE                                mDecompressHandle = NULL;
+EFI_PEI_PE_COFF_LOADER_PROTOCOL           *gEfiPeiPeCoffLoader          = NULL;
+
+//
+// DXE Core globals for Architecture Protocols
+//
+EFI_SECURITY_ARCH_PROTOCOL        *gSecurity      = NULL;
+EFI_CPU_ARCH_PROTOCOL             *gCpu           = NULL;
+EFI_METRONOME_ARCH_PROTOCOL       *gMetronome     = NULL;
+EFI_TIMER_ARCH_PROTOCOL           *gTimer         = NULL;
+EFI_BDS_ARCH_PROTOCOL             *gBds           = NULL;
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *gWatchdogTimer = NULL;
+EFI_RUNTIME_ARCH_PROTOCOL         *gRuntime       = NULL;
+
+//
+// BugBug: I'n not runtime, but is the PPI?
+//
+EFI_STATUS_CODE_PROTOCOL     gStatusCodeInstance = {
+  NULL
+};
+
+EFI_STATUS_CODE_PROTOCOL     *gStatusCode    = &gStatusCodeInstance;
+
+
+//
+// DXE Core Global used to update core loaded image protocol handle
+//
+EFI_GUID                           *gDxeCoreFileName;
+EFI_LOADED_IMAGE_PROTOCOL          *gDxeCoreLoadedImage;
+
+
+
+//
+// DXE Core Module Variables
+//
+
+EFI_BOOT_SERVICES mBootServices = {
+  {
+    EFI_BOOT_SERVICES_SIGNATURE,                                                          // Signature
+    EFI_BOOT_SERVICES_REVISION,                                                           // Revision
+    sizeof (EFI_BOOT_SERVICES),                                                           // HeaderSize
+    0,                                                                                    // CRC32
+    0                                                                                     // Reserved
+  },                                                                                      
+  (EFI_RAISE_TPL)                               CoreRaiseTpl,                             // RaiseTPL
+  (EFI_RESTORE_TPL)                             CoreRestoreTpl,                           // RestoreTPL
+  (EFI_ALLOCATE_PAGES)                          CoreAllocatePages,                        // AllocatePages
+  (EFI_FREE_PAGES)                              CoreFreePages,                            // FreePages
+  (EFI_GET_MEMORY_MAP)                          CoreGetMemoryMap,                         // GetMemoryMap
+  (EFI_ALLOCATE_POOL)                           CoreAllocatePool,                         // AllocatePool
+  (EFI_FREE_POOL)                               CoreFreePool,                             // FreePool
+  (EFI_CREATE_EVENT)                            CoreCreateEvent,                          // CreateEvent
+  (EFI_SET_TIMER)                               CoreSetTimer,                             // SetTimer
+  (EFI_WAIT_FOR_EVENT)                          CoreWaitForEvent,                         // WaitForEvent
+  (EFI_SIGNAL_EVENT)                            CoreSignalEvent,                          // SignalEvent
+  (EFI_CLOSE_EVENT)                             CoreCloseEvent,                           // CloseEvent
+  (EFI_CHECK_EVENT)                             CoreCheckEvent,                           // CheckEvent
+  (EFI_INSTALL_PROTOCOL_INTERFACE)              CoreInstallProtocolInterface,             // InstallProtocolInterface
+  (EFI_REINSTALL_PROTOCOL_INTERFACE)            CoreReinstallProtocolInterface,           // ReinstallProtocolInterface
+  (EFI_UNINSTALL_PROTOCOL_INTERFACE)            CoreUninstallProtocolInterface,           // UninstallProtocolInterface
+  (EFI_HANDLE_PROTOCOL)                         CoreHandleProtocol,                       // HandleProtocol
+  (VOID *)                                      NULL,                                     // Reserved
+  (EFI_REGISTER_PROTOCOL_NOTIFY)                CoreRegisterProtocolNotify,               // RegisterProtocolNotify
+  (EFI_LOCATE_HANDLE)                           CoreLocateHandle,                         // LocateHandle
+  (EFI_LOCATE_DEVICE_PATH)                      CoreLocateDevicePath,                     // LocateDevicePath
+  (EFI_INSTALL_CONFIGURATION_TABLE)             CoreInstallConfigurationTable,            // InstallConfigurationTable
+  (EFI_IMAGE_LOAD)                              CoreLoadImage,                            // LoadImage
+  (EFI_IMAGE_START)                             CoreStartImage,                           // StartImage
+  (EFI_EXIT)                                    CoreExit,                                 // Exit
+  (EFI_IMAGE_UNLOAD)                            CoreUnloadImage,                          // UnloadImage
+  (EFI_EXIT_BOOT_SERVICES)                      CoreExitBootServices,                     // ExitBootServices
+  (EFI_GET_NEXT_MONOTONIC_COUNT)                CoreEfiNotAvailableYetArg1,               // GetNextMonotonicCount
+  (EFI_STALL)                                   CoreStall,                                // Stall
+  (EFI_SET_WATCHDOG_TIMER)                      CoreSetWatchdogTimer,                     // SetWatchdogTimer
+  (EFI_CONNECT_CONTROLLER)                      CoreConnectController,                    // ConnectController
+  (EFI_DISCONNECT_CONTROLLER)                   CoreDisconnectController,                 // DisconnectController
+  (EFI_OPEN_PROTOCOL)                           CoreOpenProtocol,                         // OpenProtocol
+  (EFI_CLOSE_PROTOCOL)                          CoreCloseProtocol,                        // CloseProtocol
+  (EFI_OPEN_PROTOCOL_INFORMATION)               CoreOpenProtocolInformation,              // OpenProtocolInformation
+  (EFI_PROTOCOLS_PER_HANDLE)                    CoreProtocolsPerHandle,                   // ProtocolsPerHandle
+  (EFI_LOCATE_HANDLE_BUFFER)                    CoreLocateHandleBuffer,                   // LocateHandleBuffer
+  (EFI_LOCATE_PROTOCOL)                         CoreLocateProtocol,                       // LocateProtocol
+  (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)    CoreInstallMultipleProtocolInterfaces,    // InstallMultipleProtocolInterfaces
+  (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)  CoreUninstallMultipleProtocolInterfaces,  // UninstallMultipleProtocolInterfaces
+  (EFI_CALCULATE_CRC32)                         CoreEfiNotAvailableYetArg3,               // CalculateCrc32
+  (EFI_COPY_MEM)                                CopyMem,                                  // CopyMem
+  (EFI_SET_MEM)                                 SetMem                                    // SetMem
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+  ,                                   
+  (EFI_CREATE_EVENT_EX)                          CoreCreateEventEx                         // CreateEventEx
+#endif
+};
+
+EFI_DXE_SERVICES mDxeServices = {
+  {
+    EFI_DXE_SERVICES_SIGNATURE,                                           // Signature
+    EFI_DXE_SERVICES_REVISION,                                            // Revision
+    sizeof (EFI_DXE_SERVICES),                                            // HeaderSize
+    0,                                                                    // CRC32
+    0                                                                     // Reserved
+  },
+  (EFI_ADD_MEMORY_SPACE)             CoreAddMemorySpace,                  // AddMemorySpace
+  (EFI_ALLOCATE_MEMORY_SPACE)        CoreAllocateMemorySpace,             // AllocateMemorySpace
+  (EFI_FREE_MEMORY_SPACE)            CoreFreeMemorySpace,                 // FreeMemorySpace
+  (EFI_REMOVE_MEMORY_SPACE)          CoreRemoveMemorySpace,               // RemoveMemorySpace
+  (EFI_GET_MEMORY_SPACE_DESCRIPTOR)  CoreGetMemorySpaceDescriptor,        // GetMemorySpaceDescriptor
+  (EFI_SET_MEMORY_SPACE_ATTRIBUTES)  CoreSetMemorySpaceAttributes,        // SetMemorySpaceAttributes
+  (EFI_GET_MEMORY_SPACE_MAP)         CoreGetMemorySpaceMap,               // GetMemorySpaceMap
+  (EFI_ADD_IO_SPACE)                 CoreAddIoSpace,                      // AddIoSpace
+  (EFI_ALLOCATE_IO_SPACE)            CoreAllocateIoSpace,                 // AllocateIoSpace
+  (EFI_FREE_IO_SPACE)                CoreFreeIoSpace,                     // FreeIoSpace
+  (EFI_REMOVE_IO_SPACE)              CoreRemoveIoSpace,                   // RemoveIoSpace
+  (EFI_GET_IO_SPACE_DESCRIPTOR)      CoreGetIoSpaceDescriptor,            // GetIoSpaceDescriptor
+  (EFI_GET_IO_SPACE_MAP)             CoreGetIoSpaceMap,                   // GetIoSpaceMap
+  (EFI_DISPATCH)                     CoreDispatcher,                      // Dispatch
+  (EFI_SCHEDULE)                     CoreSchedule,                        // Schedule
+  (EFI_TRUST)                        CoreTrust,                           // Trust
+  (EFI_PROCESS_FIRMWARE_VOLUME)      CoreProcessFirmwareVolume,           // ProcessFirmwareVolume
+};
+
+EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
+  {
+    EFI_SYSTEM_TABLE_SIGNATURE,                                           // Signature
+    EFI_SYSTEM_TABLE_REVISION,                                            // Revision
+    sizeof (EFI_SYSTEM_TABLE),                                            // HeaderSize
+    0,                                                                    // CRC32
+    0                                                                     // Reserved
+  },
+  NULL,                                                                   // FirmwareVendor
+  0,                                                                      // FirmwareRevision
+  NULL,                                                                   // ConsoleInHandle
+  NULL,                                                                   // ConIn
+  NULL,                                                                   // ConsoleOutHandle
+  NULL,                                                                   // ConOut
+  NULL,                                                                   // StandardErrorHandle
+  NULL,                                                                   // StdErr
+  NULL,                                                                   // RuntimeServices
+  &mBootServices,                                                         // BootServices
+  0,                                                                      // NumberOfConfigurationTableEntries
+  NULL                                                                    // ConfigurationTable
+};
+
+EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
+  {
+    EFI_RUNTIME_SERVICES_SIGNATURE,                               // Signature
+    EFI_RUNTIME_SERVICES_REVISION,                                // Revision
+    sizeof (EFI_RUNTIME_SERVICES),                                // HeaderSize
+    0,                                                            // CRC32
+    0                                                             // Reserved
+  },
+  (EFI_GET_TIME)                 CoreEfiNotAvailableYetArg2,      // GetTime
+  (EFI_SET_TIME)                 CoreEfiNotAvailableYetArg1,      // SetTime
+  (EFI_GET_WAKEUP_TIME)          CoreEfiNotAvailableYetArg3,      // GetWakeupTime
+  (EFI_SET_WAKEUP_TIME)          CoreEfiNotAvailableYetArg2,      // SetWakeupTime
+  (EFI_SET_VIRTUAL_ADDRESS_MAP)  CoreEfiNotAvailableYetArg4,      // SetVirtualAddressMap
+  (EFI_CONVERT_POINTER)          CoreEfiNotAvailableYetArg2,      // ConvertPointer
+  (EFI_GET_VARIABLE)             CoreEfiNotAvailableYetArg5,      // GetVariable
+  (EFI_GET_NEXT_VARIABLE_NAME)   CoreEfiNotAvailableYetArg3,      // GetNextVariableName
+  (EFI_SET_VARIABLE)             CoreEfiNotAvailableYetArg5,      // SetVariable
+  (EFI_GET_NEXT_HIGH_MONO_COUNT) CoreEfiNotAvailableYetArg1,      // GetNextHighMonotonicCount
+  (EFI_RESET_SYSTEM)             CoreEfiNotAvailableYetArg4       // ResetSystem 
+#if ((EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION <  0x00020000))
+  ,
+  (TIANO_REPORT_STATUS_CODE)       CoreEfiNotAvailableYetArg5     // ReportStatusCode
+#elif (EFI_SPECIFICATION_VERSION >= 0x00020000)
+  ,
+  (EFI_UPDATE_CAPSULE)              CoreEfiNotAvailableYetArg3,   // UpdateCapsule
+  (EFI_QUERY_CAPSULE_CAPABILITIES)  CoreEfiNotAvailableYetArg4,   // QueryCapsuleCapabilities
+  (EFI_QUERY_VARIABLE_INFO)         CoreEfiNotAvailableYetArg4    // QueryVariableInfo
+#endif
+};
+
+//
+// DXE Core Global Variables for the EFI System Table, Boot Services Table, 
+// DXE Services Table, and Runtime Services Table
+//
+EFI_BOOT_SERVICES     *gBS = &mBootServices;
+EFI_DXE_SERVICES      *gDS = &mDxeServices;
+EFI_SYSTEM_TABLE      *gST = NULL;
+
+//
+// For debug initialize gRT to template. gRT must be allocated from RT memory
+//  but gRT is used for ASSERT () and DEBUG () type macros so lets give it
+//  a value that will not cause debug infrastructure to crash early on.
+//
+EFI_RUNTIME_SERVICES  *gRT = &mEfiRuntimeServicesTableTemplate;
+EFI_HANDLE            gDxeCoreImageHandle = NULL;
+
+VOID  *mHobStart;
+
+//
+// EFI Decompress Protocol
+//
+EFI_DECOMPRESS_PROTOCOL  gEfiDecompress = {
+  DxeMainUefiDecompressGetInfo,
+  DxeMainUefiDecompress
+};
+
+//
+// Tiano Decompress Protocol
+//
+EFI_TIANO_DECOMPRESS_PROTOCOL  gEfiTianoDecompress = {
+  DxeMainTianoDecompressGetInfo,
+  DxeMainTianoDecompress
+};
+
+//
+// Customized Decompress Protocol
+//
+EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  gEfiCustomizedDecompress = {
+  DxeMainCustomDecompressGetInfo,
+  DxeMainCustomDecompress
+};
+
+//
+// Main entry point to the DXE Core
+//
+VOID
+EFIAPI
+DxeMain (
+  IN  VOID *HobStart
+  )
+/*++
+
+Routine Description:
+
+  Main entry point to DXE Core.
+
+Arguments:
+
+  HobStart - Pointer to the beginning of the HOB List from PEI
+
+Returns:
+
+  This function should never return
+
+--*/
+{
+  EFI_STATUS                         Status;
+  EFI_PHYSICAL_ADDRESS               MemoryBaseAddress;
+  UINT64                             MemoryLength;
+
+#ifdef EFI_DXE_PERFORMANCE
+  UINT64                             Tick;
+
+  GetTimerValue (&Tick);
+#endif
+
+  mHobStart = HobStart;
+
+  //
+  // Initialize Memory Services
+  //
+  CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
+
+  //
+  // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
+  // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
+  //
+  gST = CoreAllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
+  ASSERT (gST != NULL);
+
+  gRT = CoreAllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
+  ASSERT (gRT != NULL);
+
+  gST->RuntimeServices = gRT;
+  
+  //
+  // Start the Image Services.
+  //
+  Status = CoreInitializeImageServices (HobStart);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Call constructor for all libraries
+  //
+  ProcessLibraryConstructorList (gDxeCoreImageHandle, gST);
+
+  //
+  // Initialize the Global Coherency Domain Services
+  //
+  Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install the DXE Services Table into the EFI System Tables's Configuration Table
+  //
+  Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDS);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install the HOB List into the EFI System Tables's Configuration Table
+  //
+  Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install Memory Type Information Table into the EFI System Tables's Configuration Table
+  //
+  Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize the ReportStatusCode with PEI version, if availible
+  //
+  CoreGetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **)&gStatusCode->ReportStatusCode);
+#if ((EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000))
+  gRT->ReportStatusCode = gStatusCode->ReportStatusCode;
+#endif
+
+  //
+  // Report Status Code here for DXE_ENTRY_POINT once it is available
+  //
+  CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT));
+
+  //
+  // Create the aligned system table pointer structure that is used by external
+  // debuggers to locate the system table...  Also, install debug image info
+  // configuration table.
+  //
+  CoreInitializeDebugImageInfoTable ();
+  CoreNewDebugImageInfoEntry (
+    EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
+    gDxeCoreLoadedImage,
+    gDxeCoreImageHandle
+    );
+
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "HOBLIST address in DXE = 0x%08x\n", HobStart));
+
+  //
+  // Initialize the Event Services
+  //
+  Status = CoreInitializeEventServices ();
+  ASSERT_EFI_ERROR (Status);
+
+   
+  //
+  // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
+  //
+  // These Protocols are not architectural. This implementation is sharing code between 
+  // PEI and DXE in order to save FLASH space. These Protocols could also be implemented 
+  // as part of the DXE Core. However, that would also require the DXE Core to be ported 
+  // each time a different CPU is used, a different Decompression algorithm is used, or a 
+  // different Image type is used. By placing these Protocols in PEI, the DXE Core remains 
+  // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform, 
+  // and from CPU to CPU.
+  //
+
+  //
+  // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components
+  //   
+  Status = CoreInstallMultipleProtocolInterfaces (
+              &mDecompressHandle,
+              &gEfiDecompressProtocolGuid,           &gEfiDecompress,
+              &gEfiTianoDecompressProtocolGuid,      &gEfiTianoDecompress,
+              &gEfiCustomizedDecompressProtocolGuid, &gEfiCustomizedDecompress,
+              NULL
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  gEfiPeiPeCoffLoader = GetPeCoffLoaderProtocol ();
+  ASSERT (gEfiPeiPeCoffLoader != NULL);
+
+  //
+  // Register for the GUIDs of the Architectural Protocols, so the rest of the
+  // EFI Boot Services and EFI Runtime Services tables can be filled in.
+  //
+  CoreNotifyOnArchProtocolInstallation ();
+
+  //
+  // Produce Firmware Volume Protocols, one for each FV in the HOB list.
+  //
+  Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gST);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = FwVolDriverInit (gDxeCoreImageHandle, gST);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Produce the Section Extraction Protocol 
+  //
+  Status = InitializeSectionExtraction (gDxeCoreImageHandle, gST);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize the DXE Dispatcher
+  //
+  PERF_START (0,"CoreInitializeDispatcher", "DxeMain", 0) ;
+  CoreInitializeDispatcher ();
+  PERF_END (0,"CoreInitializeDispatcher", "DxeMain", 0) ;
+
+  //
+  // Invoke the DXE Dispatcher
+  //
+  PERF_START (0, "CoreDispatcher", "DxeMain", 0);
+  CoreDispatcher ();
+  PERF_END (0, "CoreDispatcher", "DxeMain", 0);
+
+  //
+  // Display Architectural protocols that were not loaded if this is DEBUG build
+  //
+  DEBUG_CODE (
+    CoreDisplayMissingArchProtocols ();
+  );
+  
+  //
+  // Assert if the Architectural Protocols are not present.
+  //
+  ASSERT_EFI_ERROR (CoreAllEfiServicesAvailable ());
+
+  //
+  // Report Status code before transfer control to BDS
+  //
+  CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT));
+  //
+  // Display any drivers that were not dispatched because dependency expression
+  // evaluated to false if this is a debug build
+  //
+  DEBUG_CODE (
+    CoreDisplayDiscoveredNotDispatched ();
+  );
+
+  //
+  // Transfer control to the BDS Architectural Protocol
+  //
+  gBds->Entry (gBds);
+  
+  //
+  // BDS should never return
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg0 (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+  None
+
+Returns:
+
+  EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+  //
+  // This function should never be executed.  If it does, then the architectural protocols
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
+  // DXE Core and all the Architectural Protocols are complete.
+  //
+
+  return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg1 (
+  UINTN Arg1
+  )
+/*++
+
+Routine Description:
+
+  Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+  Arg1        - Undefined
+
+Returns:
+
+  EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+  //
+  // This function should never be executed.  If it does, then the architectural protocols
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
+  // DXE Core and all the Architectural Protocols are complete.
+  //
+
+  return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg2 (
+  UINTN Arg1,
+  UINTN Arg2
+  )
+/*++
+
+Routine Description:
+
+  Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+  Arg1        - Undefined
+  
+  Arg2        - Undefined
+
+Returns:
+
+  EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+  //
+  // This function should never be executed.  If it does, then the architectural protocols
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
+  // DXE Core and all the Architectural Protocols are complete.
+  //
+
+  return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg3 (
+  UINTN Arg1,
+  UINTN Arg2,
+  UINTN Arg3
+  )
+/*++
+
+Routine Description:
+
+  Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+  Arg1        - Undefined
+  
+  Arg2        - Undefined
+  
+  Arg3        - Undefined
+
+Returns:
+
+  EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+  //
+  // This function should never be executed.  If it does, then the architectural protocols
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
+  // DXE Core and all the Architectural Protocols are complete.
+  //
+
+  return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg4 (
+  UINTN Arg1,
+  UINTN Arg2,
+  UINTN Arg3,
+  UINTN Arg4
+  )
+/*++
+
+Routine Description:
+
+  Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+  Arg1        - Undefined
+  
+  Arg2        - Undefined
+  
+  Arg3        - Undefined
+  
+  Arg4        - Undefined
+
+Returns:
+
+  EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+  //
+  // This function should never be executed.  If it does, then the architectural protocols
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
+  // DXE Core and all the Architectural Protocols are complete.
+  //
+
+  return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg5 (
+  UINTN Arg1,
+  UINTN Arg2,
+  UINTN Arg3,
+  UINTN Arg4,
+  UINTN Arg5
+  )
+/*++
+
+Routine Description:
+
+  Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+  Arg1        - Undefined
+  
+  Arg2        - Undefined
+  
+  Arg3        - Undefined
+  
+  Arg4        - Undefined
+  
+  Arg5        - Undefined
+
+Returns:
+
+  EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+  //
+  // This function should never be executed.  If it does, then the architectural protocols
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
+  // DXE Core and all the Architectural Protocols are complete.
+  //
+
+  return EFI_NOT_AVAILABLE_YET;
+}
+
+
+EFI_STATUS
+CoreGetPeiProtocol (
+  IN EFI_GUID  *ProtocolGuid,
+  IN VOID      **Interface
+  )
+/*++
+
+Routine Description:
+
+  Searches for a Protocol Interface passed from PEI through a HOB
+
+Arguments:
+
+  ProtocolGuid - The Protocol GUID to search for in the HOB List
+
+  Interface    - A pointer to the interface for the Protocol GUID
+
+Returns:
+
+  EFI_SUCCESS   - The Protocol GUID was found and its interface is returned in Interface
+
+  EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
+
+--*/
+{
+  EFI_HOB_GUID_TYPE   *GuidHob;
+  VOID                *Buffer;
+
+  GuidHob = GetNextGuidHob (ProtocolGuid, mHobStart);
+  if (GuidHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  
+  Buffer = GET_GUID_HOB_DATA (GuidHob);
+  ASSERT (Buffer != NULL);
+
+  *Interface = (VOID *)(*(UINTN *)(Buffer));
+
+  return EFI_SUCCESS;
+}
+
+
+VOID
+CalculateEfiHdrCrc (
+  IN  OUT EFI_TABLE_HEADER    *Hdr
+  )
+/*++
+
+Routine Description:
+
+  Calcualte the 32-bit CRC in a EFI table using the service provided by the
+  gRuntime service.
+
+Arguments:
+
+  Hdr  - Pointer to an EFI standard header
+
+Returns:
+
+  None
+
+--*/
+{
+  UINT32 Crc;
+
+  Hdr->CRC32 = 0;
+  
+  //
+  // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
+  //  Crc will come back as zero if we set it to zero here
+  //
+  Crc = 0;
+  gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
+  Hdr->CRC32 = Crc; 
+}
+
+
+
+EFI_STATUS
+EFIAPI
+CoreExitBootServices (
+  IN EFI_HANDLE   ImageHandle,
+  IN UINTN        MapKey
+  )
+/*++
+
+Routine Description:
+
+  EFI 1.0 API to terminate Boot Services
+
+Arguments:
+
+  ImageHandle  - Handle that represents the identity of the calling image
+
+  MapKey -Key to the latest memory map.
+
+Returns:
+
+  EFI_SUCCESS - Boot Services terminated
+  EFI_INVALID_PARAMETER - MapKey is incorrect.
+
+--*/
+{
+  EFI_STATUS    Status;
+
+  //
+  // Terminate memory services if the MapKey matches
+  //
+  Status = CoreTerminateMemoryMap (MapKey);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Notify other drivers that we are exiting boot services.
+  //
+  CoreNotifySignalList (&gEfiEventExitBootServicesGuid);
+
+  //
+  // Disable Timer
+  //
+  gTimer->SetTimerPeriod (gTimer, 0);
+
+  //
+  // Disable CPU Interrupts
+  //
+  gCpu->DisableInterrupt (gCpu);
+
+  //
+  // Register Runtime events with the Runtime Architectural Protocol
+  //
+  CoreShutdownEventServices ();
+
+  //
+  // Register Runtime images with the Runtime Architectural Protocol
+  //
+  CoreShutdownImageServices ();
+
+  //
+  // Report that ExitBootServices() has been called
+  //
+  // We are using gEfiDxeServicesTableGuid as the caller ID for Dxe Core
+  //
+  CoreReportProgressCode ((EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES));
+
+  //
+  // Clear the non-runtime values of the EFI System Table
+  //
+  gST->BootServices        = NULL;
+  gST->ConIn               = NULL;
+  gST->ConsoleInHandle     = NULL;
+  gST->ConOut              = NULL;
+  gST->ConsoleOutHandle    = NULL;
+  gST->StdErr              = NULL;
+  gST->StandardErrorHandle = NULL;
+
+  //
+  // Recompute the 32-bit CRC of the EFI System Table
+  //
+  CalculateEfiHdrCrc (&gST->Hdr);
+
+  //
+  // Zero out the Boot Service Table
+  //
+  SetMem (gBS, sizeof (EFI_BOOT_SERVICES), 0);
+  gBS = NULL;
+
+  return Status;
+}
+
+EFI_STATUS
+DxeMainUefiDecompressGetInfo (
+  IN EFI_DECOMPRESS_PROTOCOL            *This,
+  IN   VOID                             *Source,
+  IN   UINT32                           SourceSize,
+  OUT  UINT32                           *DestinationSize,
+  OUT  UINT32                           *ScratchSize
+  )
+{
+  return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
+}
+
+EFI_STATUS
+EFIAPI
+DxeMainUefiDecompress (
+  IN EFI_DECOMPRESS_PROTOCOL              *This,
+  IN     VOID                             *Source,
+  IN     UINT32                           SourceSize,
+  IN OUT VOID                             *Destination,
+  IN     UINT32                           DestinationSize,
+  IN OUT VOID                             *Scratch,
+  IN     UINT32                           ScratchSize
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TestDestinationSize;
+  UINT32      TestScratchSize;
+
+  Status = UefiDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  return UefiDecompress (Source, Destination, Scratch);
+}
+
+EFI_STATUS
+DxeMainTianoDecompressGetInfo (
+  IN EFI_TIANO_DECOMPRESS_PROTOCOL      *This,
+  IN   VOID                             *Source,
+  IN   UINT32                           SourceSize,
+  OUT  UINT32                           *DestinationSize,
+  OUT  UINT32                           *ScratchSize
+  )
+{
+  return TianoDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
+}
+
+EFI_STATUS
+EFIAPI
+DxeMainTianoDecompress (
+  IN EFI_TIANO_DECOMPRESS_PROTOCOL        *This,
+  IN     VOID                             *Source,
+  IN     UINT32                           SourceSize,
+  IN OUT VOID                             *Destination,
+  IN     UINT32                           DestinationSize,
+  IN OUT VOID                             *Scratch,
+  IN     UINT32                           ScratchSize
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TestDestinationSize;
+  UINT32      TestScratchSize;
+
+  Status = TianoDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  return TianoDecompress (Source, Destination, Scratch);
+}
+
+EFI_STATUS
+DxeMainCustomDecompressGetInfo (
+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  *This,
+  IN   VOID                              *Source,
+  IN   UINT32                            SourceSize,
+  OUT  UINT32                            *DestinationSize,
+  OUT  UINT32                            *ScratchSize
+  )
+{
+  return CustomDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
+}
+
+EFI_STATUS
+EFIAPI
+DxeMainCustomDecompress (
+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  *This,
+  IN     VOID                            *Source,
+  IN     UINT32                          SourceSize,
+  IN OUT VOID                            *Destination,
+  IN     UINT32                          DestinationSize,
+  IN OUT VOID                            *Scratch,
+  IN     UINT32                          ScratchSize
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TestDestinationSize;
+  UINT32      TestScratchSize;
+
+  Status = CustomDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  return CustomDecompress (Source, Destination, Scratch);
+}
+
diff --git a/edk2/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c b/edk2/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
new file mode 100644
index 0000000..7e49423
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
@@ -0,0 +1,266 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeProtocolNotify.c

+

+Abstract:

+

+  This file deals with Architecture Protocol (AP) registration in 

+  the Dxe Core. The mArchProtocols[] array represents a list of 

+  events that represent the Architectural Protocols.

+

+--*/

+

+#include <DxeMain.h>

+

+

+//

+// DXE Core Global Variables for all of the Architectural Protocols.

+// If a protocol is installed mArchProtocols[].Present will be TRUE.

+//

+// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event

+// and mArchProtocols[].Registration as it creates events for every array

+// entry.

+//

+

+ARCHITECTURAL_PROTOCOL_ENTRY  mArchProtocols[] = {

+  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE },

+  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE },

+  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE },

+  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE },

+  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE },

+  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },

+  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE },

+  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE },

+  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },

+  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE },

+  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE },

+//  { &gEfiStatusCodeRuntimeProtocolGuid,    (VOID **)&gStatusCode,    NULL, NULL, FALSE },

+  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },

+  { NULL,                                  (VOID **)NULL,            NULL, NULL, FALSE }

+};

+

+

+EFI_STATUS

+CoreAllEfiServicesAvailable (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if all AP services are availible.

+

+Arguments:

+  NONE

+

+Returns:

+  EFI_SUCCESS   - All AP services are available

+  EFI_NOT_FOUND - At least one AP service is not available 

+

+--*/

+{

+  ARCHITECTURAL_PROTOCOL_ENTRY  *Entry;

+

+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {

+    if (!Entry->Present) {

+      return EFI_NOT_FOUND;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+VOID

+EFIAPI

+GenericArchProtocolNotify (

+  IN	EFI_EVENT       Event,

+  IN	VOID            *Context

+  )

+/*++

+

+Routine Description:

+  Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().

+  This notify function is registered for every architectural protocol. This handler

+  updates mArchProtocol[] array entry with protocol instance data and sets it's 

+  present flag to TRUE. If any constructor is required it is executed. The EFI 

+  System Table headers are updated.

+

+Arguments:

+

+  Event   - The Event that is being processed, not used.

+  

+  Context - Event Context, not used.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                      Status;

+  ARCHITECTURAL_PROTOCOL_ENTRY    *Entry;

+  VOID                            *Protocol;

+  BOOLEAN                         Found;

+  

+  Found = FALSE;

+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {

+ 

+    Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);

+    if (EFI_ERROR (Status)) {

+      continue;

+    } 

+    

+    Found = TRUE;

+    Entry->Present = TRUE;

+    

+    //

+    // Update protocol global variable if one exists. Entry->Protocol points to a global variable

+    // if one exists in the DXE core for this Architectural Protocol 

+    //

+    if (Entry->Protocol != NULL) {

+      *(Entry->Protocol) = Protocol;

+    }

+

+    if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {

+      //

+      // Register the Core timer tick handler with the Timer AP

+      //

+      gTimer->RegisterHandler (gTimer, CoreTimerTick);

+    }

+

+    if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {

+      //

+      // When runtime architectural protocol is available, updates CRC32 in the Debug Table

+      //

+      CoreUpdateDebugTableCrc32 ();

+    }

+  }

+

+  //

+  // It's over kill to do them all every time, but it saves a lot of code.

+  //

+  if (Found) {

+    CalculateEfiHdrCrc (&gRT->Hdr);

+    CalculateEfiHdrCrc (&gBS->Hdr);

+    CalculateEfiHdrCrc (&gST->Hdr);

+    CalculateEfiHdrCrc (&gDS->Hdr);

+  }

+}

+

+

+

+VOID

+CoreNotifyOnArchProtocolInstallation (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Creates an event that is fired everytime a Protocol of a specific type is installed

+

+Arguments:

+  NONE

+

+Returns:

+  NONE

+

+--*/

+{

+  EFI_STATUS                      Status;

+  ARCHITECTURAL_PROTOCOL_ENTRY    *Entry;

+

+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {

+    

+    //

+    // Create the event

+    //

+    Status = CoreCreateEvent (

+              EFI_EVENT_NOTIFY_SIGNAL,

+              EFI_TPL_CALLBACK,

+              GenericArchProtocolNotify,

+              NULL,

+              &Entry->Event

+              );

+    ASSERT_EFI_ERROR(Status);

+

+    //

+    // Register for protocol notifactions on this event

+    //

+    Status = CoreRegisterProtocolNotify (

+              Entry->ProtocolGuid, 

+              Entry->Event, 

+              &Entry->Registration

+              );

+    ASSERT_EFI_ERROR(Status);

+

+  }

+}

+

+//

+// Following is needed to display missing architectural protocols in debug builds

+//

+typedef struct {

+  EFI_GUID                    *ProtocolGuid;

+  CHAR16                       *GuidString;

+} GUID_TO_STRING_PROTOCOL_ENTRY;

+

+static const GUID_TO_STRING_PROTOCOL_ENTRY MissingProtocols[] = {

+  { &gEfiSecurityArchProtocolGuid,         (CHAR16 *)L"Security"           },

+  { &gEfiCpuArchProtocolGuid,              (CHAR16 *)L"CPU"                },

+  { &gEfiMetronomeArchProtocolGuid,        (CHAR16 *)L"Metronome"          },

+  { &gEfiTimerArchProtocolGuid,            (CHAR16 *)L"Timer"              },

+  { &gEfiBdsArchProtocolGuid,              (CHAR16 *)L"Bds"                },

+  { &gEfiWatchdogTimerArchProtocolGuid,    (CHAR16 *)L"Watchdog Timer"     },

+  { &gEfiRuntimeArchProtocolGuid,          (CHAR16 *)L"Runtime"            },

+  { &gEfiVariableArchProtocolGuid,         (CHAR16 *)L"Variable"           },

+  { &gEfiVariableWriteArchProtocolGuid,    (CHAR16 *)L"Variable Write"     },

+  { &gEfiMonotonicCounterArchProtocolGuid, (CHAR16 *)L"Monotonic Counter"  },

+  { &gEfiResetArchProtocolGuid,            (CHAR16 *)L"Reset"              },

+//  { &gEfiStatusCodeRuntimeProtocolGuid,       (CHAR16 *)L"Status Code"        },

+  { &gEfiRealTimeClockArchProtocolGuid,    (CHAR16 *)L"Real Time Clock"    }

+};

+

+VOID

+CoreDisplayMissingArchProtocols (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Displays Architectural protocols that were not loaded and are required for DXE core to function

+  Only used in Debug Builds

+

+Arguments:

+  NONE

+

+Returns:

+  NONE

+

+--*/

+{

+  const GUID_TO_STRING_PROTOCOL_ENTRY  *MissingEntry;

+  ARCHITECTURAL_PROTOCOL_ENTRY         *Entry;

+

+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {

+    if (!Entry->Present) {

+      MissingEntry = MissingProtocols;

+      for (MissingEntry = MissingProtocols; TRUE ; MissingEntry++) {

+        if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {

+          DEBUG ((EFI_D_ERROR, "\n%s Arch Protocol not present!!\n", MissingEntry->GuidString));

+          break;

+        }

+      }

+    }

+  } 

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Event/event.c b/edk2/EdkModulePkg/Core/Dxe/Event/event.c
new file mode 100644
index 0000000..6751b18
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Event/event.c
@@ -0,0 +1,862 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. 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.             
+
+Module Name:
+
+    event.c
+
+Abstract:
+
+    EFI Event support
+ 
+--*/
+
+
+#include <DxeMain.h>
+
+//
+// Enumerate the valid types
+//
+UINT32 mEventTable[] = {
+  //
+  // 0x80000200       Timer event with a notification function that is
+  // queue when the event is signaled with SignalEvent()
+  //
+  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+  //
+  // 0x80000000       Timer event without a notification function. It can be
+  // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().
+  //
+  EFI_EVENT_TIMER,
+  //
+  // 0x00000100       Generic event with a notification function that 
+  // can be waited on with CheckEvent() or WaitForEvent()
+  //
+  EFI_EVENT_NOTIFY_WAIT,
+  //
+  // 0x00000200       Generic event with a notification function that 
+  // is queue when the event is signaled with SignalEvent()
+  //
+  EFI_EVENT_NOTIFY_SIGNAL,
+  //
+  // 0x00000201       ExitBootServicesEvent.  
+  //
+  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+  //
+  // 0x60000202       SetVirtualAddressMapEvent.
+  //
+  EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+  //
+  // 0x00000203       ReadyToBootEvent.
+  //
+  EFI_EVENT_SIGNAL_READY_TO_BOOT,
+  //
+  // 0x00000204       LegacyBootEvent.
+  //
+  EFI_EVENT_SIGNAL_LEGACY_BOOT,
+  //
+  // 0x00000603       Signal all ReadyToBootEvents.
+  //
+  EFI_EVENT_NOTIFY_SIGNAL_ALL | EFI_EVENT_SIGNAL_READY_TO_BOOT,
+  //
+  // 0x00000604       Signal all LegacyBootEvents.
+  //
+  EFI_EVENT_NOTIFY_SIGNAL_ALL | EFI_EVENT_SIGNAL_LEGACY_BOOT,
+#endif
+
+  //
+  // 0x00000000       Generic event without a notification function. 
+  // It can be signaled with SignalEvent() and checked with CheckEvent() 
+  // or WaitForEvent().
+  //
+  0x00000000,
+  //
+  // 0x80000100       Timer event with a notification function that can be 
+  // waited on with CheckEvent() or WaitForEvent()
+  //
+  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_WAIT,
+};
+
+
+VOID
+CoreAcquireEventLock (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Enter critical section by acquiring the lock on gEventQueueLock.
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+{
+  CoreAcquireLock (&gEventQueueLock);
+}
+
+
+VOID
+CoreReleaseEventLock (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Exit critical section by releasing the lock on gEventQueueLock.
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+{
+  CoreReleaseLock (&gEventQueueLock);
+}
+
+
+EFI_STATUS
+CoreInitializeEventServices (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Initializes "event" support and populates parts of the System and Runtime Table.
+
+Arguments:
+
+  None
+    
+Returns:
+
+  EFI_SUCCESS - Always return success
+
+--*/
+{
+  UINTN        Index;
+
+  for (Index=0; Index <= EFI_TPL_HIGH_LEVEL; Index++) {
+    InitializeListHead (&gEventQueue[Index]);
+  }
+
+  CoreInitializeTimer ();
+  
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+CoreShutdownEventServices (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Register all runtime events to make sure they are still available after ExitBootService.
+
+Arguments:
+
+  None
+    
+Returns:
+
+  EFI_SUCCESS - Always return success.
+
+--*/
+{
+  LIST_ENTRY        *Link;
+  IEVENT            *Event;
+
+  //
+  // The Runtime AP is required for the core to function!
+  //
+  ASSERT (gRuntime != NULL);
+
+  for (Link = mRuntimeEventList.ForwardLink; Link != &mRuntimeEventList; Link = Link->ForwardLink) {
+    Event = CR (Link, IEVENT, RuntimeLink, EVENT_SIGNATURE);
+    gRuntime->RegisterEvent (
+                gRuntime, 
+                Event->Type, 
+                Event->NotifyTpl, 
+                Event->NotifyFunction, 
+                Event->NotifyContext, 
+                (VOID **)Event
+                );
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+VOID
+CoreDispatchEventNotifies (
+  IN EFI_TPL      Priority
+  )
+/*++
+
+Routine Description:
+
+  Dispatches all pending events. 
+
+Arguments:
+
+  Priority - The task priority level of event notifications to dispatch
+    
+Returns:
+
+  None
+
+--*/
+{
+  IEVENT          *Event;
+  LIST_ENTRY      *Head;
+  
+  CoreAcquireEventLock ();
+  ASSERT (gEventQueueLock.OwnerTpl == Priority);
+  Head = &gEventQueue[Priority];
+
+  //
+  // Dispatch all the pending notifications
+  //
+  while (!IsListEmpty (Head)) {
+      
+    Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
+    RemoveEntryList (&Event->NotifyLink);
+
+    Event->NotifyLink.ForwardLink = NULL;
+
+    //
+    // Only clear the SIGNAL status if it is a SIGNAL type event.
+    // WAIT type events are only cleared in CheckEvent()
+    //
+    if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
+      Event->SignalCount = 0;
+    }
+
+    CoreReleaseEventLock ();
+      
+    //
+    // Notify this event
+    //
+    ASSERT (Event->NotifyFunction != NULL);
+    Event->NotifyFunction (Event, Event->NotifyContext);
+
+    //
+    // Check for next pending event
+    //
+    CoreAcquireEventLock ();
+  }
+
+  gEventPending &= ~(1 << Priority);
+  CoreReleaseEventLock ();
+}
+
+
+VOID
+STATIC
+CoreNotifyEvent (
+  IN  IEVENT      *Event
+  )
+/*++
+
+Routine Description:
+
+  Queues the event's notification function to fire
+
+Arguments:
+
+  Event       - The Event to notify
+    
+Returns:
+
+  None
+
+--*/
+{
+
+  //
+  // Event database must be locked
+  //
+  ASSERT_LOCKED (&gEventQueueLock);
+
+  //
+  // If the event is queued somewhere, remove it
+  //
+
+  if (Event->NotifyLink.ForwardLink != NULL) {
+    RemoveEntryList (&Event->NotifyLink);
+    Event->NotifyLink.ForwardLink = NULL;
+  }
+
+  // 
+  // Queue the event to the pending notification list
+  //
+
+  InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
+  gEventPending |= (UINTN)(1 << Event->NotifyTpl);
+}
+
+
+
+VOID
+CoreNotifySignalList (
+  IN EFI_GUID     *EventGroup
+  )
+/*++
+
+Routine Description:
+  Signals all events in the EventGroup
+
+Arguments:
+  EventGroup - The list to signal
+    
+Returns:
+
+  None
+
+--*/
+{
+  LIST_ENTRY              *Link;
+  LIST_ENTRY              *Head;
+  IEVENT                  *Event;
+
+  CoreAcquireEventLock ();
+
+  Head = &gEventSignalQueue;
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
+    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
+    if (CompareGuid (&Event->EventGroup, EventGroup)) {
+      CoreNotifyEvent (Event);
+    }
+  }
+
+  CoreReleaseEventLock ();
+}
+
+
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+
+static
+VOID
+EFIAPI
+EventNofitySignalAllNullEvent (
+  IN EFI_EVENT                Event,
+  IN VOID                     *Context
+  )
+{
+  //
+  // This null event is a size efficent way to enusre that 
+  // EFI_EVENT_NOTIFY_SIGNAL_ALL is error checked correctly.
+  // EFI_EVENT_NOTIFY_SIGNAL_ALL is now mapped into 
+  // CreateEventEx() and this function is used to make the
+  // old error checking in CreateEvent() for Tiano extensions
+  // function.
+  //
+  return;
+}
+
+#endif
+
+
+
+
+EFI_STATUS
+EFIAPI
+CoreCreateEvent (
+  IN UINT32                   Type,
+  IN EFI_TPL                  NotifyTpl,
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL
+  IN VOID                     *NotifyContext, OPTIONAL
+  OUT EFI_EVENT               *Event
+  )
+/*++
+
+Routine Description:
+  Creates a general-purpose event structure
+
+Arguments:
+  Type                - The type of event to create and its mode and attributes
+  NotifyTpl           - The task priority level of event notifications
+  NotifyFunction      - Pointer to the events notification function
+  NotifyContext       - Pointer to the notification functions context; corresponds to
+                        parameter "Context" in the notification function
+  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise
+
+Returns:
+  EFI_SUCCESS           - The event structure was created
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value
+  EFI_OUT_OF_RESOURCES  - The event could not be allocated
+
+--*/
+{ 
+  EFI_GUID            *GuidPtr;
+  EFI_EVENT_NOTIFY    Function;
+  
+  GuidPtr = NULL;
+  Function = NotifyFunction;
+
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+  //
+  // Clear EFI_EVENT_NOFITY_SIGNAL_ALL (Tiano extension) as all events in the 
+  //  EventGroup now have this property. So we need to filter it out.
+  //
+  if (Type & EFI_EVENT_NOTIFY_SIGNAL_ALL) {
+    Type &= ~EFI_EVENT_NOTIFY_SIGNAL_ALL;
+    Function = EventNofitySignalAllNullEvent;
+  }
+
+  //
+  // Map the Tiano extensions Events to CreateEventEx form
+  //
+  if (Type == EFI_EVENT_SIGNAL_READY_TO_BOOT) {
+    GuidPtr = &gEfiEventReadyToBootGuid;
+  } else if (Type == EFI_EVENT_SIGNAL_LEGACY_BOOT) {
+    GuidPtr = &gEfiEventLegacyBootGuid
+  }
+#endif
+
+  //
+  // Convert EFI 1.10 Events to thier UEFI 2.0 CreateEventEx mapping
+  // 
+  if (Type == EVENT_SIGNAL_EXIT_BOOT_SERVICES) {
+    GuidPtr = &gEfiEventExitBootServicesGuid;
+  } else if (Type == EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
+    GuidPtr = &gEfiEventVirtualAddressChangeGuid;
+  }
+  
+  return CoreCreateEventEx (Type, NotifyTpl, Function, NotifyContext, GuidPtr, Event);
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreCreateEventEx (
+  IN UINT32                   Type,
+  IN EFI_TPL                  NotifyTpl,
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL
+  IN CONST VOID               *NotifyContext, OPTIONAL
+  IN CONST EFI_GUID           *EventGroup,    OPTIONAL
+  OUT EFI_EVENT               *Event
+  )
+/*++
+
+Routine Description:
+  Creates a general-purpose event structure
+
+Arguments:
+  Type                - The type of event to create and its mode and attributes
+  NotifyTpl           - The task priority level of event notifications
+  NotifyFunction      - Pointer to the events notification function
+  NotifyContext       - Pointer to the notification functions context; corresponds to
+                        parameter "Context" in the notification function
+  EventGrout          - GUID for EventGroup if NULL act the same as gBS->CreateEvent().
+  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise
+
+Returns:
+  EFI_SUCCESS           - The event structure was created
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value
+  EFI_OUT_OF_RESOURCES  - The event could not be allocated
+
+--*/
+{
+  EFI_STATUS      Status;
+  IEVENT          *IEvent;
+  INTN            Index;
+
+
+  if ((Event == NULL) || (NotifyTpl == EFI_TPL_APPLICATION)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to make sure no reserved flags are set
+  //
+  Status = EFI_INVALID_PARAMETER;
+  for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {
+     if (Type == mEventTable[Index]) {
+       Status = EFI_SUCCESS;
+       break;
+     }
+  }
+  if(EFI_ERROR (Status)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If it's a notify type of event, check its parameters
+  //
+  if ((Type & (EFI_EVENT_NOTIFY_WAIT | EFI_EVENT_NOTIFY_SIGNAL))) {
+    //
+    // Check for an invalid NotifyFunction or NotifyTpl
+    //
+    if ((NotifyFunction == NULL) || 
+        (NotifyTpl < EFI_TPL_APPLICATION) || 
+       (NotifyTpl >= EFI_TPL_HIGH_LEVEL)) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+  } else {
+    //
+    // No notification needed, zero ignored values
+    //
+    NotifyTpl = 0;
+    NotifyFunction = NULL;
+    NotifyContext = NULL;
+  }
+
+  //
+  // Allcoate and initialize a new event structure.
+  //
+  Status = CoreAllocatePool (
+             (Type & EFI_EVENT_RUNTIME) ? EfiRuntimeServicesData: EfiBootServicesData, 
+             sizeof (IEVENT),
+             (VOID **)&IEvent
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SetMem (IEvent, sizeof (IEVENT), 0);
+
+  IEvent->Signature = EVENT_SIGNATURE;
+  IEvent->Type = Type;
+  
+  IEvent->NotifyTpl      = NotifyTpl;
+  IEvent->NotifyFunction = NotifyFunction;
+  IEvent->NotifyContext  = (VOID *)NotifyContext;
+  if (EventGroup != NULL) {
+    CopyGuid (&IEvent->EventGroup, EventGroup);
+    IEvent->ExFlag = TRUE;
+  }
+
+  *Event = IEvent;
+
+  if (Type & EFI_EVENT_RUNTIME) {
+    //
+    // Keep a list of all RT events so we can tell the RT AP.
+    //
+    InsertTailList (&mRuntimeEventList, &IEvent->RuntimeLink);
+  }
+
+  CoreAcquireEventLock ();
+  
+  if ((Type & EFI_EVENT_NOTIFY_SIGNAL) != 0x00000000) {
+    //
+    // The Event's NotifyFunction must be queued whenever the event is signaled
+    //
+    InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);
+  }
+  
+  CoreReleaseEventLock ();
+  
+  //
+  // Done
+  //
+  return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+CoreSignalEvent (
+  IN EFI_EVENT    UserEvent
+  )
+/*++
+
+Routine Description:
+
+  Signals the event.  Queues the event to be notified if needed
+    
+Arguments:
+
+  UserEvent - The event to signal
+    
+Returns:
+
+  EFI_INVALID_PARAMETER - Parameters are not valid.
+  
+  EFI_SUCCESS - The event was signaled.
+
+--*/
+{
+  IEVENT          *Event;
+
+  Event = UserEvent;
+
+  if (Event == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Event->Signature != EVENT_SIGNATURE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CoreAcquireEventLock ();
+
+  //
+  // If the event is not already signalled, do so
+  //
+
+  if (Event->SignalCount == 0x00000000) {
+    Event->SignalCount++;
+
+    //
+    // If signalling type is a notify function, queue it
+    //
+    if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
+      if (Event->ExFlag) {
+        //
+        // The CreateEventEx() style requires all members of the Event Group 
+        //  to be signaled. 
+        //
+        CoreReleaseEventLock ();
+        CoreNotifySignalList (&Event->EventGroup);
+        CoreAcquireEventLock ();
+       } else {
+        CoreNotifyEvent (Event);
+      }
+    }
+  }
+
+  CoreReleaseEventLock ();
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreCheckEvent (
+  IN EFI_EVENT        UserEvent
+  )
+/*++
+
+Routine Description:
+
+  Check the status of an event
+    
+Arguments:
+
+  UserEvent - The event to check
+    
+Returns:
+
+  EFI_SUCCESS           - The event is in the signaled state
+  EFI_NOT_READY         - The event is not in the signaled state
+  EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL
+
+--*/
+
+{
+  IEVENT      *Event;
+  EFI_STATUS  Status;
+
+  Event = UserEvent;
+
+  if (Event == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Event->Signature != EVENT_SIGNATURE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = EFI_NOT_READY;
+
+  if (!Event->SignalCount && (Event->Type & EFI_EVENT_NOTIFY_WAIT)) {
+
+    //
+    // Queue the wait notify function
+    //
+
+    CoreAcquireEventLock ();
+    if (!Event->SignalCount) {
+      CoreNotifyEvent (Event);
+    }
+    CoreReleaseEventLock ();
+  }
+
+  //
+  // If the even looks signalled, get the lock and clear it
+  //
+
+  if (Event->SignalCount) {
+    CoreAcquireEventLock ();
+
+    if (Event->SignalCount) {
+      Event->SignalCount = 0;
+      Status = EFI_SUCCESS;
+    }
+
+    CoreReleaseEventLock ();
+  }
+
+  return Status;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+CoreWaitForEvent (
+  IN UINTN        NumberOfEvents,
+  IN EFI_EVENT    *UserEvents,
+  OUT UINTN       *UserIndex
+  )
+/*++
+
+Routine Description:
+
+  Stops execution until an event is signaled.
+    
+Arguments:
+
+  NumberOfEvents  - The number of events in the UserEvents array
+  UserEvents      - An array of EFI_EVENT
+  UserIndex       - Pointer to the index of the event which satisfied the wait condition
+    
+Returns:
+
+  EFI_SUCCESS           - The event indicated by Index was signaled.
+  EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or 
+                          Event was not a valid type
+  EFI_UNSUPPORTED       - The current TPL is not TPL_APPLICATION
+
+--*/
+
+{
+  EFI_STATUS      Status;
+  UINTN           Index;
+
+  //
+  // Can only WaitForEvent at TPL_APPLICATION
+  //
+  if (gEfiCurrentTpl != EFI_TPL_APPLICATION) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for(;;) {
+      
+    for(Index = 0; Index < NumberOfEvents; Index++) {
+
+      Status = CoreCheckEvent (UserEvents[Index]);
+
+      //
+      // provide index of event that caused problem
+      //
+      if (Status != EFI_NOT_READY) {
+        *UserIndex = Index;
+        return Status;
+      }
+    }
+
+    //
+    // This was the location of the Idle loop callback in EFI 1.x reference
+    // code. We don't have that concept in this base at this point.
+    // 
+  }
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreCloseEvent (
+  IN EFI_EVENT    UserEvent
+  )
+/*++
+
+Routine Description:
+
+  Closes an event and frees the event structure.
+    
+Arguments:
+
+  UserEvent - Event to close
+    
+Returns:
+
+  EFI_INVALID_PARAMETER - Parameters are not valid.
+  
+  EFI_SUCCESS - The event has been closed
+
+--*/
+
+{
+  EFI_STATUS  Status;
+  IEVENT      *Event;
+
+  Event = UserEvent;
+
+  if (Event == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Event->Signature != EVENT_SIGNATURE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If it's a timer event, make sure it's not pending
+  //
+  if (Event->Type & EFI_EVENT_TIMER) {
+    CoreSetTimer (Event, TimerCancel, 0);
+  }
+
+  CoreAcquireEventLock ();
+
+  //
+  // If the event is queued somewhere, remove it
+  //
+
+  if (Event->RuntimeLink.ForwardLink != NULL) {
+    RemoveEntryList (&Event->RuntimeLink);
+  }
+
+  if (Event->NotifyLink.ForwardLink != NULL) {
+    RemoveEntryList (&Event->NotifyLink);
+  }
+
+  if (Event->SignalLink.ForwardLink != NULL) {
+    RemoveEntryList (&Event->SignalLink);
+  }
+
+  CoreReleaseEventLock ();
+
+  //
+  // If the event is registered on a protocol notify, then remove it from the protocol database
+  //
+  CoreUnregisterProtocolNotify (Event);
+
+  Status = CoreFreePool (Event);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/edk2/EdkModulePkg/Core/Dxe/Event/execdata.c b/edk2/EdkModulePkg/Core/Dxe/Event/execdata.c
new file mode 100644
index 0000000..e7a11c2
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Event/execdata.c
@@ -0,0 +1,55 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  execdata.c

+

+Abstract:

+

+

+

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+

+//

+// gTpl - Task priority level

+//

+EFI_TPL  gEfiCurrentTpl = EFI_TPL_APPLICATION;

+

+

+//

+// gEventQueueLock - Protects the event queus

+//

+EFI_LOCK gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);

+

+//

+// gEventQueue - A list of event's to notify for each priority level

+// gEventPending - A bitmask of the EventQueues that are pending

+//

+LIST_ENTRY      gEventQueue[EFI_TPL_HIGH_LEVEL + 1];

+UINTN           gEventPending = 0;

+

+

+//

+// gEventSignalQueue - A list of events to signal based on EventGroup type

+//

+LIST_ENTRY      gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue);

+

+//

+// LIST of runtime events that need to be fired by RT AP.

+//

+LIST_ENTRY      mRuntimeEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRuntimeEventList);

diff --git a/edk2/EdkModulePkg/Core/Dxe/Event/timer.c b/edk2/EdkModulePkg/Core/Dxe/Event/timer.c
new file mode 100644
index 0000000..8d7932f
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Event/timer.c
@@ -0,0 +1,386 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  timer.c

+

+Abstract:

+

+  EFI Event support

+

+Revision History

+

+--*/

+

+

+#include <DxeMain.h>

+

+//

+// Internal prototypes

+//

+STATIC

+UINT64

+CoreCurrentSystemTime (

+  VOID

+  );

+

+VOID

+EFIAPI

+CoreCheckTimers (

+  IN EFI_EVENT    Event,

+  IN VOID         *Context

+  );

+

+STATIC

+VOID

+CoreInsertEventTimer (

+  IN IEVENT       *Event

+  );

+

+//

+// Internal data

+//

+

+static LIST_ENTRY       mEfiTimerList = INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList);

+static EFI_LOCK         mEfiTimerLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL - 1);

+static EFI_EVENT        mEfiCheckTimerEvent;

+

+static EFI_LOCK         mEfiSystemTimeLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);

+static UINT64           mEfiSystemTime = 0;

+

+//

+// Timer functions

+//

+

+VOID

+CoreInitializeTimer (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initializes timer support

+

+Arguments:

+

+  None

+    

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = CoreCreateEvent (

+              EFI_EVENT_NOTIFY_SIGNAL,

+              EFI_TPL_HIGH_LEVEL - 1,

+              CoreCheckTimers,

+              NULL,

+              &mEfiCheckTimerEvent

+              );

+  ASSERT_EFI_ERROR (Status);

+}

+

+STATIC

+UINT64

+CoreCurrentSystemTime (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Returns the current system time

+

+Arguments:

+

+  None

+    

+Returns:

+

+  Returns the current system time

+

+--*/

+{

+  UINT64          SystemTime;

+

+  CoreAcquireLock (&mEfiSystemTimeLock);

+  SystemTime = mEfiSystemTime;

+  CoreReleaseLock (&mEfiSystemTimeLock);

+  return SystemTime;

+}

+

+VOID

+EFIAPI

+CoreTimerTick (

+  IN UINT64   Duration

+  )

+/*++

+

+Routine Description:

+

+  Called by the platform code to process a tick.

+

+Arguments:

+

+  Duration    - The number of 100ns elasped since the last call to TimerTick

+    

+Returns:

+

+  None

+

+--*/

+{

+  IEVENT          *Event;

+

+  //

+  // Check runtiem flag in case there are ticks while exiting boot services

+  //

+

+  CoreAcquireLock (&mEfiSystemTimeLock);

+

+  //

+  // Update the system time

+  //

+

+  mEfiSystemTime += Duration;

+

+  //

+  // If the head of the list is expired, fire the timer event

+  // to process it

+  //

+

+  if (!IsListEmpty (&mEfiTimerList)) {

+    Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);

+

+    if (Event->u.Timer.TriggerTime <= mEfiSystemTime) {

+      CoreSignalEvent (mEfiCheckTimerEvent);

+    }

+  }

+

+  CoreReleaseLock (&mEfiSystemTimeLock);

+}

+

+VOID

+EFIAPI

+CoreCheckTimers (

+  IN EFI_EVENT            CheckEvent,

+  IN VOID                 *Context

+  )

+/*++

+

+Routine Description:

+

+  Checks the sorted timer list against the current system time.

+  Signals any expired event timer.

+

+Arguments:

+

+  CheckEvent  - Not used

+

+  Context     - Not used

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT64                  SystemTime;

+  IEVENT                  *Event;

+

+  //

+  // Check the timer database for expired timers

+  //

+

+  CoreAcquireLock (&mEfiTimerLock);

+  SystemTime = CoreCurrentSystemTime ();

+

+  while (!IsListEmpty (&mEfiTimerList)) {

+    Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);

+

+    //

+    // If this timer is not expired, then we're done

+    //

+

+    if (Event->u.Timer.TriggerTime > SystemTime) {

+      break;

+    }

+

+    //

+    // Remove this timer from the timer queue

+    //

+

+    RemoveEntryList (&Event->u.Timer.Link);

+    Event->u.Timer.Link.ForwardLink = NULL;

+

+    //

+    // Signal it

+    //

+    CoreSignalEvent (Event);

+

+    //

+    // If this is a periodic timer, set it

+    //

+    if (Event->u.Timer.Period) {

+

+      //

+      // Compute the timers new trigger time

+      //

+

+      Event->u.Timer.TriggerTime = Event->u.Timer.TriggerTime + Event->u.Timer.Period;

+

+      //

+      // If that's before now, then reset the timer to start from now

+      //

+      if (Event->u.Timer.TriggerTime <= SystemTime) {

+        Event->u.Timer.TriggerTime = SystemTime;

+        CoreSignalEvent (mEfiCheckTimerEvent);

+      }

+

+      //

+      // Add the timer

+      //

+

+      CoreInsertEventTimer (Event);

+    }

+  }

+

+  CoreReleaseLock (&mEfiTimerLock);

+}

+

+STATIC

+VOID

+CoreInsertEventTimer (

+  IN IEVENT   *Event

+  )

+/*++

+

+Routine Description:

+

+  Inserts the timer event

+

+Arguments:

+

+  Event - Points to the internal structure of timer event to be installed

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT64          TriggerTime;

+  LIST_ENTRY      *Link;

+  IEVENT          *Event2;

+

+  ASSERT_LOCKED (&mEfiTimerLock);

+

+  //

+  // Get the timer's trigger time

+  //

+

+  TriggerTime = Event->u.Timer.TriggerTime;

+

+  //

+  // Insert the timer into the timer database in assending sorted order

+  //

+

+  for (Link = mEfiTimerList.ForwardLink; Link  != &mEfiTimerList; Link = Link->ForwardLink) {

+    Event2 = CR (Link, IEVENT, u.Timer.Link, EVENT_SIGNATURE);

+

+    if (Event2->u.Timer.TriggerTime > TriggerTime) {

+      break;

+    }

+  }

+

+  InsertTailList (Link, &Event->u.Timer.Link);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreSetTimer (

+  IN EFI_EVENT            UserEvent,

+  IN EFI_TIMER_DELAY      Type,

+  IN UINT64               TriggerTime

+  )

+/*++

+

+Routine Description:

+

+  Sets the type of timer and the trigger time for a timer event.

+

+Arguments:

+

+  UserEvent   - The timer event that is to be signaled at the specified time

+  Type        - The type of time that is specified in TriggerTime

+  TriggerTime - The number of 100ns units until the timer expires

+  

+Returns:

+

+  EFI_SUCCESS           - The event has been set to be signaled at the requested time

+  EFI_INVALID_PARAMETER - Event or Type is not valid

+

+--*/  

+{

+  IEVENT      *Event;

+  

+  Event = UserEvent;

+

+  if (Event == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Event->Signature != EVENT_SIGNATURE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Type < 0 || Type > TimerRelative  || !(Event->Type & EFI_EVENT_TIMER)) {

+    return EFI_INVALID_PARAMETER;

+  }

+ 

+  CoreAcquireLock (&mEfiTimerLock);

+

+  //

+  // If the timer is queued to the timer database, remove it

+  //

+

+  if (Event->u.Timer.Link.ForwardLink != NULL) {

+    RemoveEntryList (&Event->u.Timer.Link);

+    Event->u.Timer.Link.ForwardLink = NULL;

+  }

+

+  Event->u.Timer.TriggerTime = 0;

+  Event->u.Timer.Period = 0;

+

+  if (Type != TimerCancel) {

+

+    if (Type == TimerPeriodic) {

+      Event->u.Timer.Period = TriggerTime;

+    }

+

+    Event->u.Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;

+    CoreInsertEventTimer (Event);

+

+    if (TriggerTime == 0) {

+      CoreSignalEvent (mEfiCheckTimerEvent);

+    }

+  }

+

+  CoreReleaseLock (&mEfiTimerLock);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Event/tpl.c b/edk2/EdkModulePkg/Core/Dxe/Event/tpl.c
new file mode 100644
index 0000000..ae85163
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Event/tpl.c
@@ -0,0 +1,198 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    tpl.c

+

+Abstract:

+

+    Task priority function    

+

+--*/

+

+#include <DxeMain.h>

+

+STATIC

+VOID

+CoreSetInterruptState (

+  IN BOOLEAN      Enable

+  )

+/*++

+

+Routine Description:

+  

+  Set Interrupt State

+  

+Arguments:

+  

+  Enable - The state of enable or disable interrupt

+  

+Returns:

+  

+  None

+

+--*/

+

+{

+  if (gCpu != NULL) {

+    if (Enable) {

+      gCpu->EnableInterrupt(gCpu);

+    } else {

+      gCpu->DisableInterrupt(gCpu);

+    }

+  }

+}

+

+//

+// Return the highest set bit

+//

+UINTN

+CoreHighestSetBit (

+  IN UINTN     Number

+  )

+/*++

+

+Routine Description:

+  

+  Return the highest set bit

+  

+Arguments:

+  

+  Number - The value to check

+  

+Returns:

+  

+  Bit position of the highest set bit

+

+--*/

+{

+  UINTN   msb;

+  

+  msb = 31;

+  while ((msb > 0) && ((Number & (UINTN)(1 << msb)) == 0)) {

+    msb--;

+  }

+

+  return msb;

+}

+

+

+

+EFI_TPL

+EFIAPI

+CoreRaiseTpl (

+  IN EFI_TPL      NewTpl

+  )

+/*++

+

+Routine Description:

+

+  Raise the task priority level to the new level.

+  High level is implemented by disabling processor interrupts.

+

+Arguments:

+

+  NewTpl  - New task priority level

+    

+Returns:

+

+  The previous task priority level

+

+--*/

+{

+  EFI_TPL     OldTpl;

+

+  OldTpl = gEfiCurrentTpl;

+  ASSERT (OldTpl <= NewTpl);

+  ASSERT (VALID_TPL (NewTpl));

+

+  //

+  // If raising to high level, disable interrupts

+  //

+  if (NewTpl >= EFI_TPL_HIGH_LEVEL  &&  OldTpl < EFI_TPL_HIGH_LEVEL) {

+    CoreSetInterruptState (FALSE);

+  }

+

+  //

+  // Set the new value

+  //

+  gEfiCurrentTpl = NewTpl;

+

+  return OldTpl;

+}

+

+

+

+VOID

+EFIAPI

+CoreRestoreTpl (

+  IN EFI_TPL NewTpl

+  )

+/*++

+

+Routine Description:

+

+  Lowers the task priority to the previous value.   If the new 

+  priority unmasks events at a higher priority, they are dispatched.

+

+Arguments:

+

+  NewTpl  - New, lower, task priority

+    

+Returns:

+

+  None

+

+--*/

+{

+  EFI_TPL     OldTpl;

+

+  OldTpl = gEfiCurrentTpl;

+  ASSERT (NewTpl <= OldTpl);

+  ASSERT (VALID_TPL (NewTpl));

+

+  //

+  // If lowering below HIGH_LEVEL, make sure

+  // interrupts are enabled

+  //

+

+  if (OldTpl >= EFI_TPL_HIGH_LEVEL  &&  NewTpl < EFI_TPL_HIGH_LEVEL) {

+    gEfiCurrentTpl = EFI_TPL_HIGH_LEVEL;  

+  }

+

+  //

+  // Dispatch any pending events

+  //

+

+  while ((-2 << NewTpl) & gEventPending) {

+    gEfiCurrentTpl = CoreHighestSetBit (gEventPending);

+    if (gEfiCurrentTpl < EFI_TPL_HIGH_LEVEL) {

+      CoreSetInterruptState (TRUE);

+    }

+    CoreDispatchEventNotifies (gEfiCurrentTpl);

+  }

+

+  //

+  // Set the new value

+  //

+

+  gEfiCurrentTpl = NewTpl;

+

+  //

+  // If lowering below HIGH_LEVEL, make sure

+  // interrupts are enabled

+  //

+  if (gEfiCurrentTpl < EFI_TPL_HIGH_LEVEL) {

+    CoreSetInterruptState (TRUE);

+  }

+

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Exec.h b/edk2/EdkModulePkg/Core/Dxe/Exec.h
new file mode 100644
index 0000000..e7b0f7b
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Exec.h
@@ -0,0 +1,209 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  exec.h

+

+Abstract:

+    

+  EFI Event support

+

+--*/

+

+#ifndef _EXEC_H_

+#define _EXEC_H_

+

+#define VALID_TPL(a)            ((a) <= EFI_TPL_HIGH_LEVEL)

+

+//

+// EFI_EVENT

+//

+

+

+

+#define EVENT_SIGNATURE         EFI_SIGNATURE_32('e','v','n','t')

+typedef struct {

+  UINTN                   Signature;

+  UINT32                  Type;

+  UINT32                  SignalCount;

+

+  //

+  // Entry if the event is registered to be signalled

+  //

+

+  LIST_ENTRY              SignalLink;

+

+  //

+  // Notification information for this event

+  //

+

+  EFI_TPL                 NotifyTpl;

+  EFI_EVENT_NOTIFY        NotifyFunction;

+  VOID                    *NotifyContext;

+  EFI_GUID                EventGroup;

+  LIST_ENTRY              NotifyLink; 

+  BOOLEAN                 ExFlag;

+  

+  //

+  // A list of all runtime events

+  //

+  LIST_ENTRY              RuntimeLink;

+

+  //

+  // Information by event type

+  //

+

+  union {

+    //

+    // For timer events

+    //

+    struct {

+      LIST_ENTRY      Link;

+      UINT64          TriggerTime;

+      UINT64          Period;

+    } Timer;

+  } u;

+

+} IEVENT;    

+

+//

+// Internal prototypes

+//

+

+VOID

+CoreDispatchEventNotifies (

+  IN EFI_TPL      Priority

+  )

+/*++

+

+Routine Description:

+

+  Dispatches all pending events. 

+

+Arguments:

+

+  Priority - The task priority level of event notifications to dispatch

+    

+Returns:

+

+  None

+

+--*/

+;

+

+

+UINTN

+CoreHighestSetBit (

+  IN UINTN         Number

+  )

+/*++

+

+Routine Description:

+  

+  Return the highest set bit

+  

+Arguments:

+  

+  Number - The value to check

+  

+Returns:

+  

+  Bit position of the highest set bit

+

+--*/

+;

+

+

+BOOLEAN

+GetInterruptState (

+  VOID               

+  )

+/*++

+

+Routine Description:

+

+  Disables CPU interrupts.

+

+Arguments:

+

+  This                - Protocol instance structure

+

+  State               - Pointer to the CPU's current interrupt state

+

+Returns: 

+

+  EFI_SUCCESS           - If interrupts were disabled in the CPU.

+

+  EFI_INVALID_PARAMETER - State is NULL.

+  

+--*/

+;

+

+//

+// Exported functions

+//

+

+VOID

+CoreEventVirtualAddressFixup (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  A function out of date, should be removed.

+

+Arguments:

+

+  None

+    

+Returns:

+

+  None

+

+--*/

+;

+

+

+VOID

+CoreInitializeTimer (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initializes timer support

+

+Arguments:

+

+  None

+    

+Returns:

+

+  None

+

+--*/

+;

+

+//

+// extern data declarations

+//

+

+extern EFI_LOCK       gEventQueueLock;

+extern UINTN          gEventPending;

+extern LIST_ENTRY     gEventQueue[];

+extern LIST_ENTRY     gEventSignalQueue;

+extern UINT8          gHSB[];

+extern LIST_ENTRY     mRuntimeEventList;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVol/Ffs.c b/edk2/EdkModulePkg/Core/Dxe/FwVol/Ffs.c
new file mode 100644
index 0000000..6f7d353
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVol/Ffs.c
@@ -0,0 +1,266 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ffs.c

+

+Abstract:

+

+  FFS file access utilities.

+

+--*/

+

+

+#include <DxeMain.h>

+

+#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *)((UINTN)(Address)))

+

+

+EFI_FFS_FILE_STATE

+GetFileState (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Get the FFS file state by checking the highest bit set in the header's state field

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  FfsHeader     -  Points to the FFS file header

+    

+Returns:

+  FFS File state 

+    

+--*/

+{

+  EFI_FFS_FILE_STATE      FileState;

+  UINT8                   HighestBit;

+

+  FileState = FfsHeader->State;

+

+  if (ErasePolarity != 0) {

+    FileState = (EFI_FFS_FILE_STATE)~FileState;

+  }

+

+  HighestBit = 0x80;

+  while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {

+    HighestBit >>= 1;

+  }

+

+  return (EFI_FFS_FILE_STATE)HighestBit;

+}

+

+

+BOOLEAN

+IsBufferErased (

+  IN UINT8    ErasePolarity,

+  IN VOID     *InBuffer,

+  IN UINTN    BufferSize

+  )

+/*++

+

+Routine Description:

+  Check if a block of buffer is erased

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  InBuffer      -  The buffer to be checked

+  BufferSize    -  Size of the buffer in bytes

+    

+Returns:

+  TRUE  -  The block of buffer is erased

+  FALSE -  The block of buffer is not erased

+    

+--*/

+{

+  UINTN   Count;

+  UINT8   EraseByte;

+  UINT8   *Buffer;

+

+  if(ErasePolarity == 1) {

+    EraseByte = 0xFF;

+  } else {

+    EraseByte = 0;

+  }

+

+  Buffer = InBuffer;

+  for (Count = 0; Count < BufferSize; Count++) {

+    if (Buffer[Count] != EraseByte) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+

+BOOLEAN

+VerifyFvHeaderChecksum (

+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader

+  )

+/*++

+

+Routine Description:

+  Verify checksum of the firmware volume header 

+

+Arguments:

+  FvHeader  -  Points to the firmware volume header to be checked

+    

+Returns:

+  TRUE  -  Checksum verification passed

+  FALSE -  Checksum verification failed

+    

+--*/

+{

+  UINT32  Index;

+  UINT32  HeaderLength;

+  UINT16  Checksum;

+  UINT16  *ptr;

+

+  HeaderLength = FvHeader->HeaderLength;

+  ptr = (UINT16 *)FvHeader;

+  Checksum = 0;

+

+  for (Index = 0; Index < HeaderLength / sizeof (UINT16); Index++) {

+    Checksum = (UINT16)(Checksum + ptr[Index]);

+  }

+

+  if (Checksum == 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+

+BOOLEAN

+VerifyHeaderChecksum (

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Verify checksum of the FFS file header 

+

+Arguments:

+  FfsHeader  -  Points to the FFS file header to be checked

+    

+Returns:

+  TRUE  -  Checksum verification passed

+  FALSE -  Checksum verification failed

+    

+--*/

+{

+  UINT32            Index;

+  UINT8             *ptr;

+  UINT8             HeaderChecksum;

+

+  ptr = (UINT8 *)FfsHeader;

+  HeaderChecksum = 0;

+  for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {

+    HeaderChecksum = (UINT8)(HeaderChecksum + ptr[Index]);

+  }

+

+  HeaderChecksum = HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File;

+

+  if (HeaderChecksum == 0) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+

+BOOLEAN

+IsValidFfsHeader (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader,

+  OUT EFI_FFS_FILE_STATE  *FileState

+  )

+/*++

+

+Routine Description:

+  Check if it's a valid FFS file header

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  FfsHeader     -  Points to the FFS file header to be checked

+  FileState     -  FFS file state to be returned

+    

+Returns:

+  TRUE  -  Valid FFS file header

+  FALSE -  Invalid FFS file header

+    

+--*/

+{

+  *FileState = GetFileState (ErasePolarity, FfsHeader);

+

+  switch (*FileState) {

+    case EFI_FILE_HEADER_VALID:

+    case EFI_FILE_DATA_VALID:

+    case EFI_FILE_MARKED_FOR_UPDATE:

+    case EFI_FILE_DELETED:

+      //

+      // Here we need to verify header checksum

+      //

+      return VerifyHeaderChecksum (FfsHeader);

+    

+    case EFI_FILE_HEADER_CONSTRUCTION:

+    case EFI_FILE_HEADER_INVALID:

+    default:

+      return FALSE;

+  }

+}

+

+

+BOOLEAN

+IsValidFfsFile (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Check if it's a valid FFS file. 

+  Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  FfsHeader     -  Points to the FFS file to be checked

+    

+Returns:

+  TRUE  -  Valid FFS file

+  FALSE -  Invalid FFS file

+    

+--*/

+{

+  EFI_FFS_FILE_STATE  FileState;

+

+  FileState = GetFileState (ErasePolarity, FfsHeader);

+  switch (FileState) {

+

+    case EFI_FILE_DELETED:

+    case EFI_FILE_DATA_VALID:

+    case EFI_FILE_MARKED_FOR_UPDATE:

+      //

+      // Some other vliadation like file content checksum might be done here.

+      // For performance issue, Tiano only do FileState check.

+      //

+      return TRUE;

+

+    default:

+      return FALSE;

+  }

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVol.c b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVol.c
new file mode 100644
index 0000000..d8137d7
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVol.c
@@ -0,0 +1,553 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVol.c

+

+Abstract:

+

+  Firmware File System driver that produce Firmware Volume protocol.

+  Layers on top of Firmware Block protocol to produce a file abstraction 

+  of FV based files.

+

+--*/

+

+#include <DxeMain.h>

+

+#define KEYSIZE       sizeof (UINTN)

+

+//

+// Protocol notify related globals

+//

+VOID          *gEfiFwVolBlockNotifyReg;

+EFI_EVENT     gEfiFwVolBlockEvent;

+

+FV_DEVICE mFvDevice = {

+  FV_DEVICE_SIGNATURE,

+  NULL,

+  NULL,

+  {

+    FvGetVolumeAttributes,

+    FvSetVolumeAttributes,

+    FvReadFile,

+    FvReadFileSection,

+    FvWriteFile,

+    FvGetNextFile,

+    KEYSIZE

+  },

+  NULL,

+  NULL,

+  NULL,

+  NULL,

+  { NULL, NULL },

+  0

+};

+

+

+//

+// FFS helper functions

+//

+

+EFI_STATUS

+GetFwVolHeader (

+  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *Fvb,

+  OUT    EFI_FIRMWARE_VOLUME_HEADER             **FwVolHeader

+  )

+/*++

+

+Routine Description:

+  given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and

+  copy the volume header into it.

+

+Arguments:

+  Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume

+          header

+  FwVolHeader - Pointer to pointer to allocated buffer in which the volume

+                  header is returned.

+

+Returns:

+  EFI_OUT_OF_RESOURCES    - No enough buffer could be allocated.

+  EFI_SUCCESS             - Successfully read volume header to the allocated buffer.

+

+--*/

+

+{

+  EFI_STATUS                  Status;

+  EFI_FIRMWARE_VOLUME_HEADER  TempFvh;

+  UINTN                       FvhLength;

+  UINT8                       *Buffer;

+

+

+  //

+  //Determine the real length of FV header

+  //

+  FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER);

+  Status = Fvb->Read (Fvb, 0, 0, &FvhLength, (UINT8 *)&TempFvh);

+

+  //

+  // Allocate a buffer for the caller

+  //

+  *FwVolHeader = CoreAllocateBootServicesPool (TempFvh.HeaderLength);

+  if (*FwVolHeader == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Copy the standard header into the buffer

+  //

+  CopyMem (*FwVolHeader, &TempFvh, sizeof (EFI_FIRMWARE_VOLUME_HEADER));

+

+  //

+  // Read the rest of the header

+  //

+  FvhLength = TempFvh.HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER);

+  Buffer = (UINT8 *)*FwVolHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER);

+  Status = Fvb->Read (Fvb, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER), &FvhLength, Buffer);

+  if (EFI_ERROR (Status)) {

+    //

+    // Read failed so free buffer

+    //

+    CoreFreePool (*FwVolHeader);

+  }

+ 

+  return Status;

+}

+

+

+STATIC

+VOID

+FreeFvDeviceResource (

+  IN FV_DEVICE  *FvDevice

+  )

+/*++

+

+Routine Description:

+  Free FvDevice resource when error happens

+

+Arguments:

+  FvDevice - pointer to the FvDevice to be freed.

+

+Returns:

+  None.

+

+--*/

+{

+  FFS_FILE_LIST_ENTRY         *FfsFileEntry;

+  LIST_ENTRY                  *NextEntry;

+

+  //

+  // Free File List Entry

+  //

+  FfsFileEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->FfsFileListHeader.ForwardLink;

+  while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) {

+    NextEntry = (&FfsFileEntry->Link)->ForwardLink;

+    

+    if (FfsFileEntry->StreamHandle != 0) {

+      //

+      // Close stream and free resources from SEP

+      //

+      FfsFileEntry->Sep->CloseSectionStream (FfsFileEntry->Sep, FfsFileEntry->StreamHandle);

+    }

+

+    CoreFreePool (FfsFileEntry);

+

+    FfsFileEntry = (FFS_FILE_LIST_ENTRY *)NextEntry;

+  }

+

+

+  //

+  // Free the cache

+  //

+  CoreFreePool (FvDevice->CachedFv);

+

+  //

+  // Free Volume Header

+  //

+  CoreFreePool (FvDevice->FwVolHeader);

+

+  return;

+}

+

+

+EFI_STATUS

+FvCheck (

+  IN OUT FV_DEVICE  *FvDevice

+  )

+/*++

+

+Routine Description:

+  Check if a FV is consistent and allocate cache

+

+Arguments:

+  FvDevice - pointer to the FvDevice to be checked.

+

+Returns:

+  EFI_OUT_OF_RESOURCES    - No enough buffer could be allocated.

+  EFI_SUCCESS             - FV is consistent and cache is allocated.

+  EFI_VOLUME_CORRUPTED    - File system is corrupted.

+

+--*/

+{

+  EFI_STATUS                            Status;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;

+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;

+  EFI_FVB_ATTRIBUTES                    FvbAttributes;

+  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;

+  FFS_FILE_LIST_ENTRY                   *FfsFileEntry;

+  EFI_FFS_FILE_HEADER                   *FfsHeader;

+  UINT8                                 *CacheLocation;

+  UINTN                                 LbaOffset;

+  UINTN                                 Index;

+  EFI_LBA                               LbaIndex;

+  UINTN                                 Size;

+  UINTN                                 FileLength;

+  EFI_FFS_FILE_STATE                    FileState;

+  UINT8                                 *TopFvAddress;

+  UINTN                                 TestLength;

+

+

+  Fvb = FvDevice->Fvb;

+  FwVolHeader = FvDevice->FwVolHeader;

+ 

+  Status = Fvb->GetVolumeAttributes (Fvb, &FvbAttributes);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Size is the size of the FV minus the head. We have already allocated

+  // the header to check to make sure the volume is valid

+  //

+  Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);

+  FvDevice->CachedFv = CoreAllocateZeroBootServicesPool (Size);

+  if (FvDevice->CachedFv == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Remember a pointer to the end fo the CachedFv

+  //

+  FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;

+

+  //

+  // Copy FV minus header into memory using the block map we have all ready

+  // read into memory.

+  //

+  BlockMap = FwVolHeader->FvBlockMap;

+  CacheLocation = FvDevice->CachedFv;

+  LbaIndex = 0;

+  LbaOffset = FwVolHeader->HeaderLength;

+  while ((BlockMap->NumBlocks != 0) || (BlockMap->BlockLength != 0)) {

+    

+    for (Index = 0; Index < BlockMap->NumBlocks; Index ++) {

+

+      Size = BlockMap->BlockLength;

+      if (Index == 0) {

+        //

+        // Cache does not include FV Header

+        //

+        Size -= LbaOffset;

+      }

+      Status = Fvb->Read (Fvb,

+                          LbaIndex,

+                          LbaOffset,

+                          &Size,

+                          CacheLocation

+                          );

+      //

+      // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->BlockLength

+      //

+      if (EFI_ERROR (Status)) {

+        goto Done;

+      }

+      

+      //

+      // After we skip Fv Header always read from start of block

+      //

+      LbaOffset = 0;

+

+      LbaIndex++;

+      CacheLocation += Size;

+    }

+    BlockMap++;

+  }

+

+  //

+  // Scan to check the free space & File list

+  //

+  if (FvbAttributes & EFI_FVB_ERASE_POLARITY) {

+    FvDevice->ErasePolarity = 1;

+  } else {

+    FvDevice->ErasePolarity = 0;

+  } 

+

+

+  //

+  // go through the whole FV cache, check the consistence of the FV.

+  // Make a linked list off all the Ffs file headers

+  //

+  Status = EFI_SUCCESS;

+  InitializeListHead (&FvDevice->FfsFileListHeader);

+

+  //

+  // Build FFS list

+  //

+  FfsHeader = (EFI_FFS_FILE_HEADER *)FvDevice->CachedFv;

+  TopFvAddress = FvDevice->EndOfCachedFv;

+  while ((UINT8 *)FfsHeader < TopFvAddress) {

+

+    TestLength = TopFvAddress - ((UINT8 *)FfsHeader);

+    if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {

+      TestLength = sizeof (EFI_FFS_FILE_HEADER);

+    }

+

+    if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) {

+      //

+      // We have found the free space so we are done!

+      //

+      goto Done;

+    }

+

+    if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) {

+      if ((FileState == EFI_FILE_HEADER_INVALID) || 

+          (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {

+        FfsHeader++;

+      

+        continue;

+      

+      } else {

+        //

+        // File system is corrputed

+        //

+        Status = EFI_VOLUME_CORRUPTED;

+        goto Done;

+      }

+    }

+

+    if (!IsValidFfsFile (FvDevice->ErasePolarity, FfsHeader)) {

+      //

+      // File system is corrupted

+      //

+      Status = EFI_VOLUME_CORRUPTED;

+      goto Done;

+    }

+

+    //

+    // Size[3] is a three byte array, read 4 bytes and throw one away

+    //

+    FileLength = *(UINT32 *)&FfsHeader->Size[0] & 0x00FFFFFF;

+

+    FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);

+    

+    //

+    // check for non-deleted file

+    //

+    if (FileState != EFI_FILE_DELETED) {

+      //

+      // Create a FFS list entry for each non-deleted file

+      //

+      FfsFileEntry = CoreAllocateZeroBootServicesPool (sizeof (FFS_FILE_LIST_ENTRY));

+      if (FfsFileEntry == NULL) {

+        Status = EFI_OUT_OF_RESOURCES;

+        goto Done;

+      }

+    

+      FfsFileEntry->FfsHeader = FfsHeader;

+      InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);

+    }

+

+    FfsHeader =  (EFI_FFS_FILE_HEADER *)(((UINT8 *)FfsHeader) + FileLength);

+    

+    //

+    // Adjust pointer to the next 8-byte aligned boundry.

+    //

+    FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07);

+    

+  }

+

+Done:

+  if (EFI_ERROR (Status)) {

+    FreeFvDeviceResource (FvDevice);

+  }

+

+  return Status;

+}

+

+

+STATIC

+VOID

+EFIAPI

+NotifyFwVolBlock (

+  IN  EFI_EVENT Event,

+  IN  VOID      *Context

+  )

+/*++

+

+Routine Description:

+    This notification function is invoked when an instance of the

+    EFI_FW_VOLUME_BLOCK_PROTOCOL is produced.  It layers an instance of the

+    EFI_FIRMWARE_VOLUME_PROTOCOL on the same handle.  This is the function where

+    the actual initialization of the EFI_FIRMWARE_VOLUME_PROTOCOL is done.

+

+Arguments:

+    Event - The event that occured

+    Context - For EFI compatiblity.  Not used.

+

+Returns:

+

+    None.

+

+--*/

+{

+  EFI_HANDLE                            Handle;

+  EFI_STATUS                            Status;

+  UINTN                                 BufferSize;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;

+  EFI_FIRMWARE_VOLUME_PROTOCOL          *Fv;

+  FV_DEVICE                             *FvDevice;

+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;

+  //

+  // Examine all new handles

+  //

+  for (;;) {

+    //

+    // Get the next handle

+    //

+    BufferSize = sizeof (Handle);

+    Status = CoreLocateHandle (

+              ByRegisterNotify,

+              NULL,

+              gEfiFwVolBlockNotifyReg,

+              &BufferSize,

+              &Handle

+              );

+

+    //

+    // If not found, we're done

+    //

+    if (EFI_NOT_FOUND == Status) {

+      break;

+    }

+

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+    

+    //

+    // Get the FirmwareVolumeBlock protocol on that handle

+    //

+    Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb); 

+    ASSERT_EFI_ERROR (Status);

+    

+

+    //

+    // Make sure the Fv Header is O.K.

+    //

+    Status = GetFwVolHeader (Fvb, &FwVolHeader);

+    if (EFI_ERROR (Status)) {

+      return;

+    }

+

+    if (!VerifyFvHeaderChecksum (FwVolHeader)) {

+      CoreFreePool (FwVolHeader);

+      continue;

+    }

+

+

+    //

+    // Check to see that the file system is indeed formatted in a way we can

+    // understand it...

+    //

+    if (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystemGuid)) {

+      continue;

+    }

+

+    //

+    // Check if there is an FV protocol already installed in that handle

+    //

+    Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);

+    if (!EFI_ERROR (Status)) {

+      //

+      // Update Fv to use a new Fvb

+      //

+      FvDevice = _CR (Fv, FV_DEVICE, Fv);

+      if (FvDevice->Signature == FV_DEVICE_SIGNATURE) {

+        //

+        // Only write into our device structure if it's our device structure

+        //

+        FvDevice->Fvb = Fvb;

+      }

+

+    } else {

+      //

+      // No FwVol protocol on the handle so create a new one

+      //

+      FvDevice = CoreAllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice);

+      if (FvDevice == NULL) {

+        return;

+      }

+      

+      FvDevice->Fvb         = Fvb;

+      FvDevice->Handle      = Handle;

+      FvDevice->FwVolHeader = FwVolHeader;

+      FvDevice->Fv.ParentHandle = Fvb->ParentHandle;

+      

+      //

+      // Install an New FV protocol on the existing handle

+      //

+      Status = CoreInstallProtocolInterface (

+                  &Handle,

+                  &gEfiFirmwareVolumeProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &FvDevice->Fv

+                  );

+      ASSERT_EFI_ERROR (Status);

+    }

+  }

+  

+  return;

+}

+

+

+EFI_STATUS

+EFIAPI

+FwVolDriverInit (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+/*++

+

+Routine Description:

+    This routine is the driver initialization entry point.  It initializes the

+    libraries, and registers two notification functions.  These notification

+    functions are responsible for building the FV stack dynamically.

+    

+Arguments:

+    ImageHandle   - The image handle.

+    SystemTable   - The system table.

+    

+Returns:

+    EFI_SUCCESS   - Function successfully returned.

+

+--*/

+{

+  gEfiFwVolBlockEvent = CoreCreateProtocolNotifyEvent (

+                          &gEfiFirmwareVolumeBlockProtocolGuid,

+                          EFI_TPL_CALLBACK,

+                          NotifyFwVolBlock,

+                          NULL,

+                          &gEfiFwVolBlockNotifyReg,

+                          TRUE

+                          );

+  return EFI_SUCCESS;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolAttrib.c b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
new file mode 100644
index 0000000..8a44653
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
@@ -0,0 +1,99 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVolAttrib.c

+

+Abstract:

+

+  Implements get/set firmware volume attributes

+

+--*/

+

+#include <DxeMain.h>

+

+EFI_STATUS

+EFIAPI

+FvGetVolumeAttributes (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL  *This,

+  OUT EFI_FV_ATTRIBUTES             *Attributes

+  )

+/*++

+

+Routine Description:

+    Retrieves attributes, insures positive polarity of attribute bits, returns

+    resulting attributes in output parameter

+

+Arguments:

+    This        - Calling context

+    Attributes  - output buffer which contains attributes

+

+Returns:

+    EFI_SUCCESS         - Successfully got volume attributes

+

+--*/

+{

+  EFI_STATUS                                Status;

+  FV_DEVICE                                 *FvDevice;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *Fvb;

+  EFI_FVB_ATTRIBUTES                        FvbAttributes;

+

+  FvDevice = FV_DEVICE_FROM_THIS (This);

+  Fvb = FvDevice->Fvb;

+

+  if (FvDevice->CachedFv == NULL) {

+    Status = FvCheck (FvDevice);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  //

+  // First get the Firmware Volume Block Attributes

+  //

+  Status = Fvb->GetVolumeAttributes (Fvb, &FvbAttributes);

+

+  //

+  // Mask out Fvb bits that are not defined in FV 

+  //

+  FvbAttributes &= 0xfffff0ff;

+  

+  *Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes; 

+  

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+FvSetVolumeAttributes (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN OUT EFI_FV_ATTRIBUTES          *Attributes

+  )

+/*++

+

+Routine Description:

+    Sets current attributes for volume

+

+Arguments:

+    This       - Calling context

+    Attributes - At input, contains attributes to be set.  At output contains

+      new value of FV

+

+Returns:

+    EFI_UNSUPPORTED   - Could not be set.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolRead.c b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolRead.c
new file mode 100644
index 0000000..ff2fcb8
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolRead.c
@@ -0,0 +1,516 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVolRead.c

+

+Abstract:

+

+  Implements read firmware file

+

+--*/

+

+#include <DxeMain.h>

+

+/*++

+

+Required Alignment    Alignment Value in FFS       Alignment Value in

+(bytes)                        Attributes Field               Firmware Volume Interfaces

+1                                    0                                     0

+2                                    0                                     1

+4                                    0                                     2

+8                                    0                                     3

+16                                   1                                     4

+128                                  2                                     7

+512                                  3                                     9

+1 KB                                 4                                     10

+4 KB                                 5                                     12

+32 KB                                6                                     15

+64 KB                                7                                     16

+

+--*/

+

+UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16}; 

+

+

+STATIC

+EFI_FV_FILE_ATTRIBUTES

+FfsAttributes2FvFileAttributes (

+  IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes

+  )

+/*++

+

+  Routine Description:

+    Convert the FFS File Attributes to FV File Attributes

+    

+  Arguments:

+    FfsAttributes   -   The attributes of UINT8 type.

+    

+  Returns:

+    The attributes of EFI_FV_FILE_ATTRIBUTES

+    

+--*/

+{

+  FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);

+  ASSERT (FfsAttributes < 8);

+

+  return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];

+}

+

+

+EFI_STATUS

+EFIAPI

+FvGetNextFile (

+  IN         EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN OUT     VOID                            *Key,

+  IN OUT     EFI_FV_FILETYPE                *FileType,

+  OUT        EFI_GUID                      *NameGuid,

+  OUT        EFI_FV_FILE_ATTRIBUTES        *Attributes,

+  OUT        UINTN                           *Size

+  )

+/*++

+

+Routine Description:

+    Given the input key, search for the next matching file in the volume.

+

+Arguments:

+    This          -   Indicates the calling context.

+    FileType      -   FileType is a pointer to a caller allocated

+                      EFI_FV_FILETYPE. The GetNextFile() API can filter it's

+                      search for files based on the value of *FileType input.

+                      A *FileType input of 0 causes GetNextFile() to search for

+                      files of all types.  If a file is found, the file's type

+                      is returned in *FileType.  *FileType is not modified if

+                      no file is found.

+    Key           -   Key is a pointer to a caller allocated buffer that

+                      contains implementation specific data that is used to

+                      track where to begin the search for the next file.

+                      The size of the buffer must be at least This->KeySize

+                      bytes long. To reinitialize the search and begin from

+                      the beginning of the firmware volume, the entire buffer

+                      must be cleared to zero. Other than clearing the buffer

+                      to initiate a new search, the caller must not modify the

+                      data in the buffer between calls to GetNextFile().

+    NameGuid      -   NameGuid is a pointer to a caller allocated EFI_GUID.

+                      If a file is found, the file's name is returned in

+                      *NameGuid.  *NameGuid is not modified if no file is

+                      found.

+    Attributes    -   Attributes is a pointer to a caller allocated

+                      EFI_FV_FILE_ATTRIBUTES.  If a file is found, the file's

+                      attributes are returned in *Attributes. *Attributes is

+                      not modified if no file is found.

+    Size          -   Size is a pointer to a caller allocated UINTN.

+                      If a file is found, the file's size is returned in *Size.

+                      *Size is not modified if no file is found.

+

+Returns:

+    EFI_SUCCESS                 - Successfully find the file.

+    EFI_DEVICE_ERROR            - Device error.

+    EFI_ACCESS_DENIED           - Fv could not read.

+    EFI_NOT_FOUND               - No matching file found.

+    EFI_INVALID_PARAMETER       - Invalid parameter

+

+--*/

+{

+  EFI_STATUS                                  Status;

+  FV_DEVICE                                   *FvDevice;

+  EFI_FV_ATTRIBUTES                           FvAttributes;

+  EFI_FFS_FILE_HEADER                         *FfsFileHeader;

+  UINTN                                       *KeyValue;

+  LIST_ENTRY                                  *Link;

+  FFS_FILE_LIST_ENTRY                         *FfsFileEntry;

+  UINTN                                       FileLength;

+

+  FvDevice = FV_DEVICE_FROM_THIS (This);

+

+  Status = FvGetVolumeAttributes (This, &FvAttributes);

+  if (EFI_ERROR (Status)){

+    return Status;

+  }

+

+  //

+  // Check if read operation is enabled

+  //

+  if ((FvAttributes & EFI_FV_READ_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  if (*FileType > EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {

+    //

+    // File type needs to be in 0 - 0x0B

+    //

+    return EFI_INVALID_PARAMETER;

+  }

+

+  KeyValue = (UINTN *)Key;

+  for (;;) {

+    if (*KeyValue == 0) {

+      //

+      // Search for 1st matching file

+      //

+      Link = &FvDevice->FfsFileListHeader;

+    } else {

+      //

+      // Key is pointer to FFsFileEntry, so get next one

+      //

+      Link = (LIST_ENTRY *)(*KeyValue);

+    }

+

+    if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {

+      //

+      // Next is end of list so we did not find data

+      //

+      return EFI_NOT_FOUND;

+    }

+

+    FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;

+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;

+

+    //

+    // remember the key

+    //

+    *KeyValue = (UINTN)FfsFileEntry;

+

+    if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {

+      //

+      // we ignore pad files

+      //

+      continue;

+    }

+

+    if (*FileType == 0) {

+      //

+      // Process all file types so we have a match

+      //

+      break;

+    }

+

+    if (*FileType == FfsFileHeader->Type) {

+      //

+      // Found a matching file type

+      //

+      break;

+    }

+

+  } 

+

+  //

+  // Return FileType, NameGuid, and Attributes

+  //

+  *FileType = FfsFileHeader->Type;

+  CopyMem (NameGuid, &FfsFileHeader->Name, sizeof (EFI_GUID));

+  *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);

+

+  //

+  // Read four bytes out of the 3 byte array and throw out extra data

+  //

+  FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;

+

+  //

+  // we need to substract the header size

+  //

+  *Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);

+

+  if (FfsFileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+    //

+    // If tail is present substract it's size;

+    //

+    *Size -= sizeof(EFI_FFS_FILE_TAIL);

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+FvReadFile (

+  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN     EFI_GUID                       *NameGuid,

+  IN OUT VOID                           **Buffer,

+  IN OUT UINTN                          *BufferSize,

+  OUT    EFI_FV_FILETYPE               *FoundType,

+  OUT    EFI_FV_FILE_ATTRIBUTES        *FileAttributes,

+  OUT    UINT32                        *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+    Locates a file in the firmware volume and

+    copies it to the supplied buffer.

+

+Arguments:

+    This              -   Indicates the calling context.

+    NameGuid          -   Pointer to an EFI_GUID, which is the filename.

+    Buffer            -   Buffer is a pointer to pointer to a buffer in

+                          which the file or section contents or are returned.

+    BufferSize        -   BufferSize is a pointer to caller allocated

+                          UINTN. On input *BufferSize indicates the size

+                          in bytes of the memory region pointed to by

+                          Buffer. On output, *BufferSize contains the number

+                          of bytes required to read the file.

+    FoundType         -   FoundType is a pointer to a caller allocated

+                          EFI_FV_FILETYPE that on successful return from Read()

+                          contains the type of file read.  This output reflects

+                          the file type irrespective of the value of the

+                          SectionType input.

+    FileAttributes    -   FileAttributes is a pointer to a caller allocated

+                          EFI_FV_FILE_ATTRIBUTES.  On successful return from

+                          Read(), *FileAttributes contains the attributes of

+                          the file read.

+    AuthenticationStatus -  AuthenticationStatus is a pointer to a caller

+                          allocated UINTN in which the authentication status

+                          is returned.

+Returns:

+    EFI_SUCCESS                   - Successfully read to memory buffer.

+    EFI_WARN_BUFFER_TOO_SMALL     - Buffer too small.

+    EFI_NOT_FOUND                 - Not found.

+    EFI_DEVICE_ERROR              - Device error.

+    EFI_ACCESS_DENIED             - Could not read.

+    EFI_INVALID_PARAMETER         - Invalid parameter.

+    EFI_OUT_OF_RESOURCES          - Not enough buffer to be allocated.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  FV_DEVICE                         *FvDevice;

+  EFI_GUID                          SearchNameGuid;

+  EFI_FV_FILETYPE                   LocalFoundType;

+  EFI_FV_FILE_ATTRIBUTES            LocalAttributes;

+  UINTN                             FileSize;

+  UINT8                             *SrcPtr;

+  EFI_FFS_FILE_HEADER               *FfsHeader;

+  UINTN                             InputBufferSize;

+  

+  if (NULL == NameGuid) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  FvDevice = FV_DEVICE_FROM_THIS (This);

+  

+

+  //

+  // Keep looking until we find the matching NameGuid.

+  // The Key is really an FfsFileEntry

+  //

+  FvDevice->LastKey = 0;

+  do {

+    LocalFoundType = 0;

+    Status = FvGetNextFile (

+              This,

+              &FvDevice->LastKey,

+              &LocalFoundType,

+              &SearchNameGuid,

+              &LocalAttributes,

+              &FileSize

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_NOT_FOUND;

+    }

+  } while (!CompareGuid (&SearchNameGuid, NameGuid));

+

+  //

+  // Get a pointer to the header

+  //

+  FfsHeader = FvDevice->LastKey->FfsHeader;

+

+  //

+  // Remember callers buffer size

+  //

+  InputBufferSize = *BufferSize;

+

+  //

+  // Calculate return values

+  //

+  *FoundType = FfsHeader->Type;

+  *FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);

+  *AuthenticationStatus = 0;

+  *BufferSize = FileSize;

+

+  if (Buffer == NULL) {

+    //

+    // If Buffer is NULL, we only want to get the information colected so far

+    //

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Skip over file header

+  //

+  SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);

+

+  Status = EFI_SUCCESS;

+  if (*Buffer == NULL) {

+    //

+    // Caller passed in a pointer so allocate buffer for them

+    //

+    *Buffer = CoreAllocateBootServicesPool (FileSize);

+    if (*Buffer == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  } else if (FileSize > InputBufferSize) {

+    //

+    // Callers buffer was not big enough

+    // 

+    Status = EFI_WARN_BUFFER_TOO_SMALL;

+    FileSize = InputBufferSize;

+  }

+  

+  //

+  // Copy data into callers buffer 

+  //

+  CopyMem (*Buffer, SrcPtr, FileSize);

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+FvReadFileSection (

+  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN     EFI_GUID                       *NameGuid,

+  IN     EFI_SECTION_TYPE               SectionType,

+  IN     UINTN                          SectionInstance,

+  IN OUT VOID                           **Buffer,

+  IN OUT UINTN                          *BufferSize,

+  OUT    UINT32                         *AuthenticationStatus

+  )

+/*++

+

+  Routine Description:

+    Locates a section in a given FFS File and

+    copies it to the supplied buffer (not including section header).

+

+  Arguments:

+    This              -   Indicates the calling context.

+    NameGuid          -   Pointer to an EFI_GUID, which is the filename.

+    SectionType       -   Indicates the section type to return.

+    SectionInstance   -   Indicates which instance of sections with a type of

+                          SectionType to return.

+    Buffer            -   Buffer is a pointer to pointer to a buffer in which

+                          the file or section contents or are returned.

+    BufferSize        -   BufferSize is a pointer to caller allocated UINTN.

+    AuthenticationStatus -AuthenticationStatus is a pointer to a caller

+                          allocated UINT32 in which the authentication status

+                          is returned.

+

+  Returns:

+    EFI_SUCCESS                     - Successfully read the file section into buffer.

+    EFI_WARN_BUFFER_TOO_SMALL       - Buffer too small.

+    EFI_NOT_FOUND                   - Section not found.

+    EFI_DEVICE_ERROR                - Device error.

+    EFI_ACCESS_DENIED               - Could not read.

+    EFI_INVALID_PARAMETER           - Invalid parameter.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  FV_DEVICE                         *FvDevice;

+  EFI_FV_FILETYPE                   FileType;

+  EFI_FV_FILE_ATTRIBUTES            FileAttributes;

+  UINTN                             FileSize;

+  UINT8                             *FileBuffer;

+  EFI_SECTION_EXTRACTION_PROTOCOL   *Sep;

+  FFS_FILE_LIST_ENTRY               *FfsEntry;

+ 

+  if (NULL == NameGuid || Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  FvDevice = FV_DEVICE_FROM_THIS (This);

+

+  //

+  // Read the whole file into buffer

+  //

+  FileBuffer = NULL;

+  Status = FvReadFile (

+            This,

+            NameGuid,

+            (VOID **)&FileBuffer,

+            &FileSize,

+            &FileType,

+            &FileAttributes,

+            AuthenticationStatus

+            );             

+  //

+  // Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.

+  //  

+  FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  

+  //

+  // Check to see that the file actually HAS sections before we go any further.

+  //

+  if (FileType == EFI_FV_FILETYPE_RAW) {

+    Status = EFI_NOT_FOUND;

+    goto Done;

+  }

+

+  //

+  // Use FfsEntry to cache Section Extraction Protocol Inforomation

+  //

+  if (FfsEntry->StreamHandle == 0) {

+    //

+    // Located the protocol

+    //

+    Status = CoreLocateProtocol (&gEfiSectionExtractionProtocolGuid, NULL, (VOID **)&Sep);

+    //

+    // Section Extraction Protocol is part of Dxe Core so this should never fail

+    //

+    ASSERT_EFI_ERROR (Status);

+

+    Status = Sep->OpenSectionStream (

+                    Sep,

+                    FileSize,

+                    FileBuffer,

+                    &FfsEntry->StreamHandle

+                    );

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    FfsEntry->Sep = Sep;

+  } else {

+    //

+    // Get cached copy of Sep

+    //

+    Sep = FfsEntry->Sep;

+  }

+

+  //

+  // If SectionType == 0 We need the whole section stream

+  //

+  Status = Sep->GetSection (

+                  Sep,

+                            FfsEntry->StreamHandle,

+                            (SectionType == 0) ? NULL : &SectionType,

+                            NULL,

+                            (SectionType == 0) ? 0 : SectionInstance,

+                            Buffer,

+                            BufferSize,

+                            AuthenticationStatus

+                            );

+

+  //

+  // Close of stream defered to close of FfsHeader list to allow SEP to cache data

+  //

+

+Done:

+  CoreFreePool (FileBuffer);

+

+  return Status;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolWrite.c b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolWrite.c
new file mode 100644
index 0000000..4368fe5
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVol/FwVolWrite.c
@@ -0,0 +1,60 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVolWrite.c

+

+Abstract:

+

+  Implements write firmware file

+

+--*/

+

+#include <DxeMain.h>

+

+

+EFI_STATUS

+EFIAPI

+FvWriteFile (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN UINT32                         NumberOfFiles,

+  IN EFI_FV_WRITE_POLICY            WritePolicy,

+  IN EFI_FV_WRITE_FILE_DATA         *FileData

+  )

+/*++

+

+    Routine Description:

+      Writes one or more files to the firmware volume.

+

+    Arguments:

+    This            - Indicates the calling context.

+    NumberOfFiles   - Number of files.

+    WritePolicy     - WritePolicy indicates the level of reliability for

+                      the write in the event of a power failure or other

+                      system failure during the write operation.

+    FileData        - FileData is an pointer to an array of EFI_FV_WRITE_DATA.

+                      Each element of FileData[] represents a file to be written.

+

+    Returns:

+      EFI_SUCCESS                   - Files successfully written to firmware volume

+      EFI_OUT_OF_RESOURCES          - Not enough buffer to be allocated.

+      EFI_DEVICE_ERROR              - Device error.

+      EFI_WRITE_PROTECTED           - Write protected.

+      EFI_NOT_FOUND                 - Not found.

+      EFI_INVALID_PARAMETER         - Invalid parameter.

+      EFI_UNSUPPORTED               - This function not supported.

+

+--*/

+{ 

+  return EFI_UNSUPPORTED;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVolBlock.h b/edk2/EdkModulePkg/Core/Dxe/FwVolBlock.h
new file mode 100644
index 0000000..2e76242
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVolBlock.h
@@ -0,0 +1,324 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVolBlock.h

+

+Abstract:

+

+  Firmware Volume Block protocol..  Consumes FV hobs and creates

+  appropriate block protocols.

+

+  Also consumes NT_NON_MM_FV envinronment variable and produces appropriate

+  block protocols fro them also... (this is TBD)

+

+--*/

+

+#ifndef _FWVOL_BLOCK_H_

+#define _FWVOL_BLOCK_H_

+

+

+#define FVB_DEVICE_SIGNATURE       EFI_SIGNATURE_32('_','F','V','B')

+

+typedef struct {

+  UINTN                       Base;

+  UINTN                       Length;

+} LBA_CACHE;

+

+typedef struct {

+  MEMMAP_DEVICE_PATH          MemMapDevPath;

+  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;

+} FV_DEVICE_PATH;

+

+

+typedef struct {

+  UINTN                                 Signature;

+  EFI_HANDLE                            Handle;

+  FV_DEVICE_PATH                        DevicePath;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    FwVolBlockInstance;

+  UINTN                                 NumBlocks;

+  LBA_CACHE                             *LbaCache;

+  UINT32                                FvbAttributes;

+  EFI_PHYSICAL_ADDRESS                  BaseAddress;

+} EFI_FW_VOL_BLOCK_DEVICE;

+

+#define FVB_DEVICE_FROM_THIS(a) \

+  CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)

+

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockDriverInit (

+  IN EFI_HANDLE               ImageHandle,

+  IN EFI_SYSTEM_TABLE         *SystemTable

+  )

+/*++

+

+Routine Description:

+    This routine is the driver initialization entry point.  It initializes the

+    libraries, consumes FV hobs and NT_NON_MM_FV environment variable and

+    produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.

+Arguments:

+    ImageHandle   - The image handle.

+    SystemTable   - The system table.

+Returns:

+    EFI_SUCCESS   - Successfully initialized firmware volume block driver.

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockGetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+/*++

+

+Routine Description:

+    Retrieves Volume attributes.  No polarity translations are done.

+

+Arguments:

+    This - Calling context

+    Attributes - output buffer which contains attributes

+

+Returns:

+    EFI_SUCCESS - The firmware volume attributes were returned.

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockSetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the input parameter.

+

+Arguments:

+  This - Calling context

+  Attributes - input buffer which contains attributes

+

+Returns:

+  EFI_SUCCESS -  The firmware volume attributes were returned.

+  EFI_INVALID_PARAMETER  -  The attributes requested are in conflict with the capabilities as

+                             declared in the firmware volume header.

+  EFI_UNSUPPORTED        -  Not supported.

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockEraseBlock (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  ...

+  )

+/*++

+

+Routine Description:

+  The EraseBlock() function erases one or more blocks as denoted by the 

+variable argument list. The entire parameter list of blocks must be verified

+prior to erasing any blocks.  If a block is requested that does not exist 

+within the associated firmware volume (it has a larger index than the last 

+block of the firmware volume), the EraseBlock() function must return

+EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

+

+Arguments:

+  This - Calling context

+  ...  - Starting LBA followed by Number of Lba to erase. a -1 to terminate

+           the list.

+    

+Returns:

+  EFI_SUCCESS   -  The erase request was successfully completed.

+  EFI_ACCESS_DENIED   -  The firmware volume is in the WriteDisabled state.

+  EFI_DEVICE_ERROR    -  The block device is not functioning correctly and could not be

+                         written. The firmware device may have been partially erased.

+  EFI_INVALID_PARAMETER  -  One or more of the LBAs listed in the variable argument list do

+  EFI_UNSUPPORTED        -  Not supported.

+    

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockReadBlock (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Read the specified number of bytes from the block to the input buffer.

+

+Arguments:

+  This          -  Indicates the calling context.

+  Lba           -  The starting logical block index to read.

+  Offset        -  Offset into the block at which to begin reading.

+  NumBytes      -  Pointer to a UINT32. At entry, *NumBytes contains the

+                   total size of the buffer. At exit, *NumBytes contains the

+                   total number of bytes actually read.

+  Buffer        -  Pinter to a caller-allocated buffer that contains the destine

+                   for the read.    

+

+Returns:      

+  EFI_SUCCESS  -  The firmware volume was read successfully.

+  EFI_BAD_BUFFER_SIZE -  The read was attempted across an LBA boundary.

+  EFI_ACCESS_DENIED  -  Access denied.

+  EFI_DEVICE_ERROR   -  The block device is malfunctioning and could not be read.

+--*/

+;

+

+  

+EFI_STATUS

+EFIAPI

+FwVolBlockWriteBlock (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                Offset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer

+  )

+/*++

+

+Routine Description:

+  Writes the specified number of bytes from the input buffer to the block.

+

+Arguments:

+  This          -  Indicates the calling context.

+  Lba           -  The starting logical block index to write to.

+  Offset        -  Offset into the block at which to begin writing.

+  NumBytes      -  Pointer to a UINT32. At entry, *NumBytes contains the

+                   total size of the buffer. At exit, *NumBytes contains the

+                   total number of bytes actually written.

+  Buffer        -  Pinter to a caller-allocated buffer that contains the source

+                   for the write.    

+

+Returns:     

+  EFI_SUCCESS  -  The firmware volume was written successfully.

+  EFI_BAD_BUFFER_SIZE -  The write was attempted across an LBA boundary. On output,

+                         NumBytes contains the total number of bytes actually written.

+  EFI_ACCESS_DENIED  -  The firmware volume is in the WriteDisabled state.

+  EFI_DEVICE_ERROR   -  The block device is malfunctioning and could not be written.

+  EFI_UNSUPPORTED    -  Not supported.

+--*/

+;

+

+    

+EFI_STATUS

+EFIAPI

+FwVolBlockGetPhysicalAddress (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+/*++

+

+Routine Description:

+  Get Fvb's base address.

+

+Arguments:

+  This          -  Indicates the calling context.

+  Address       -  Fvb device base address.

+

+Returns:     

+  EFI_SUCCESS  -  Successfully got Fvb's base address.

+  EFI_UNSUPPORTED -  Not supported.

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockGetBlockSize (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  IN EFI_LBA                             Lba,

+  OUT UINTN                              *BlockSize,

+  OUT UINTN                              *NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieves the size in bytes of a specific block within a firmware volume.

+

+Arguments:

+  This            -  Indicates the calling context.

+  Lba             -  Indicates the block for which to return the size.

+  BlockSize       -  Pointer to a caller-allocated UINTN in which the size of the

+                     block is returned.

+  NumberOfBlocks  -  Pointer to a caller-allocated UINTN in which the number of

+                     consecutive blocks starting with Lba is returned. All blocks

+                     in this range have a size of BlockSize.   

+Returns:

+  EFI_SUCCESS  -  The firmware volume base address is returned.

+  EFI_INVALID_PARAMETER  -  The requested LBA is out of range.

+--*/

+;

+EFI_STATUS

+FwVolBlockDriverInit (

+  IN EFI_HANDLE               ImageHandle,

+  IN EFI_SYSTEM_TABLE         *SystemTable

+  )

+/*++

+

+Routine Description:

+    This routine is the driver initialization entry point.  It initializes the

+    libraries, consumes FV hobs and NT_NON_MM_FV environment variable and

+    produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.

+Arguments:

+    ImageHandle   - The image handle.

+    SystemTable   - The system table.

+Returns:

+    Status code

+

+--*/

+;

+

+EFI_STATUS

+ProduceFVBProtocolOnBuffer (

+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,

+  IN UINT64                 Length,

+  IN EFI_HANDLE             ParentHandle,

+  OUT EFI_HANDLE            *FvProtocolHandle  OPTIONAL

+  )

+/*++

+

+Routine Description:

+    This routine produces a firmware volume block protocol on a given

+    buffer. 

+

+Arguments:

+    BaseAddress     - base address of the firmware volume image

+    Length          - length of the firmware volume image

+    ParentHandle    - handle of parent firmware volume, if this

+                      image came from an FV image file in another

+                      firmware volume (ala capsules)

+    FvProtocolHandle  - Firmware volume block protocol produced.

+    

+Returns:

+    EFI_VOLUME_CORRUPTED    - Volume corrupted.

+    EFI_OUT_OF_RESOURCES    - No enough buffer to be allocated.

+    EFI_SUCCESS             - Successfully produced a FVB protocol on given buffer.

+                     

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c b/edk2/EdkModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
new file mode 100644
index 0000000..49f197f
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
@@ -0,0 +1,598 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVolBlock.c

+

+Abstract:

+

+  Firmware Volume Block protocol..  Consumes FV hobs and creates

+  appropriate block protocols.

+

+  Also consumes NT_NON_MM_FV envinronment variable and produces appropriate

+  block protocols fro them also... (this is TBD)

+

+--*/

+

+#include <DxeMain.h>

+

+

+EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {

+  FVB_DEVICE_SIGNATURE,

+  NULL,

+  {

+    {

+      {

+        HARDWARE_DEVICE_PATH,

+        HW_MEMMAP_DP,

+        { (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) }

+      },

+      EfiMemoryMappedIO,

+      (EFI_PHYSICAL_ADDRESS)0,

+      (EFI_PHYSICAL_ADDRESS)0,

+    },

+    {

+      END_DEVICE_PATH_TYPE,

+      END_ENTIRE_DEVICE_PATH_SUBTYPE,

+      { END_DEVICE_PATH_LENGTH, 0 }      

+    },

+  },

+  {

+    FwVolBlockGetAttributes,

+    (EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes,

+    FwVolBlockGetPhysicalAddress,

+    FwVolBlockGetBlockSize,

+    FwVolBlockReadBlock,

+    (EFI_FVB_WRITE)FwVolBlockWriteBlock,

+    (EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock,

+    NULL      

+  },

+  0,

+  NULL,

+  0,

+  0

+};

+

+

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockGetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+/*++

+

+Routine Description:

+    Retrieves Volume attributes.  No polarity translations are done.

+

+Arguments:

+    This - Calling context

+    Attributes - output buffer which contains attributes

+

+Returns:

+    EFI_SUCCESS - The firmware volume attributes were returned.

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;

+  

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  //

+  // Since we are read only, it's safe to get attributes data from our in-memory copy.

+  //

+  *Attributes = FvbDevice->FvbAttributes;

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockSetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  IN EFI_FVB_ATTRIBUTES                   *Attributes

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the input parameter.

+

+Arguments:

+  This - Calling context

+  Attributes - input buffer which contains attributes

+

+Returns:

+  EFI_SUCCESS -  The firmware volume attributes were returned.

+  EFI_INVALID_PARAMETER  -  The attributes requested are in conflict with the capabilities as

+                             declared in the firmware volume header.

+  EFI_UNSUPPORTED        -  Not supported.

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockEraseBlock (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  ...

+  )

+/*++

+

+Routine Description:

+  The EraseBlock() function erases one or more blocks as denoted by the 

+variable argument list. The entire parameter list of blocks must be verified

+prior to erasing any blocks.  If a block is requested that does not exist 

+within the associated firmware volume (it has a larger index than the last 

+block of the firmware volume), the EraseBlock() function must return

+EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

+

+Arguments:

+  This - Calling context

+  ...  - Starting LBA followed by Number of Lba to erase. a -1 to terminate

+           the list.

+    

+Returns:

+  EFI_SUCCESS   -  The erase request was successfully completed.

+  EFI_ACCESS_DENIED   -  The firmware volume is in the WriteDisabled state.

+  EFI_DEVICE_ERROR    -  The block device is not functioning correctly and could not be

+                         written. The firmware device may have been partially erased.

+  EFI_INVALID_PARAMETER  -  One or more of the LBAs listed in the variable argument list do

+  EFI_UNSUPPORTED        -  Not supported.

+    

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockReadBlock (

+  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *This,

+  IN     EFI_LBA                                Lba,

+  IN     UINTN                                  Offset,

+  IN OUT UINTN                                  *NumBytes,

+  IN     UINT8                                  *Buffer

+  )

+/*++

+

+Routine Description:

+  Read the specified number of bytes from the block to the input buffer.

+

+Arguments:

+  This          -  Indicates the calling context.

+  Lba           -  The starting logical block index to read.

+  Offset        -  Offset into the block at which to begin reading.

+  NumBytes      -  Pointer to a UINT32. At entry, *NumBytes contains the

+                   total size of the buffer. At exit, *NumBytes contains the

+                   total number of bytes actually read.

+  Buffer        -  Pinter to a caller-allocated buffer that contains the destine

+                   for the read.    

+

+Returns:      

+  EFI_SUCCESS  -  The firmware volume was read successfully.

+  EFI_BAD_BUFFER_SIZE -  The read was attempted across an LBA boundary.

+  EFI_ACCESS_DENIED  -  Access denied.

+  EFI_DEVICE_ERROR   -  The block device is malfunctioning and could not be read.

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;

+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;

+  UINT8                                 *LbaOffset;

+  UINTN                                 LbaStart;

+  UINTN                                 NumOfBytesRead;

+  UINTN                                 LbaIndex;

+  

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  //

+  // Check if This FW can be read

+  //

+  if ((FvbDevice->FvbAttributes & EFI_FVB_READ_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  

+  LbaIndex = (UINTN)Lba;

+  if (LbaIndex >= FvbDevice->NumBlocks) {

+    //

+    // Invalid Lba, read nothing.

+    //

+    *NumBytes = 0;

+    return EFI_BAD_BUFFER_SIZE;

+  }

+  

+  if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {

+    //

+    // all exceed boundry, read nothing.

+    //

+    *NumBytes = 0;

+    return EFI_BAD_BUFFER_SIZE;

+  }

+  

+  NumOfBytesRead = *NumBytes;

+  if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {

+    //

+    // partial exceed boundry, read data from current postion to end.

+    //

+    NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;

+  }

+  

+  LbaStart = FvbDevice->LbaCache[LbaIndex].Base;

+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);

+  LbaOffset = (UINT8 *)FwVolHeader + LbaStart + Offset;

+

+  //

+  // Perform read operation

+  //

+  CopyMem (Buffer, LbaOffset, NumOfBytesRead);

+  

+  if (NumOfBytesRead == *NumBytes) {

+    return EFI_SUCCESS;

+  }

+    

+  *NumBytes = NumOfBytesRead;

+  return EFI_BAD_BUFFER_SIZE;

+}

+  

+

+EFI_STATUS

+EFIAPI

+FwVolBlockWriteBlock (

+  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  IN     EFI_LBA                              Lba,

+  IN     UINTN                                Offset,

+  IN OUT UINTN                                *NumBytes,

+  IN     UINT8                                *Buffer

+  )

+/*++

+

+Routine Description:

+  Writes the specified number of bytes from the input buffer to the block.

+

+Arguments:

+  This          -  Indicates the calling context.

+  Lba           -  The starting logical block index to write to.

+  Offset        -  Offset into the block at which to begin writing.

+  NumBytes      -  Pointer to a UINT32. At entry, *NumBytes contains the

+                   total size of the buffer. At exit, *NumBytes contains the

+                   total number of bytes actually written.

+  Buffer        -  Pinter to a caller-allocated buffer that contains the source

+                   for the write.    

+

+Returns:     

+  EFI_SUCCESS  -  The firmware volume was written successfully.

+  EFI_BAD_BUFFER_SIZE -  The write was attempted across an LBA boundary. On output,

+                         NumBytes contains the total number of bytes actually written.

+  EFI_ACCESS_DENIED  -  The firmware volume is in the WriteDisabled state.

+  EFI_DEVICE_ERROR   -  The block device is malfunctioning and could not be written.

+  EFI_UNSUPPORTED    -  Not supported.

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+ 

+

+EFI_STATUS

+EFIAPI

+FwVolBlockGetPhysicalAddress (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+/*++

+

+Routine Description:

+  Get Fvb's base address.

+

+Arguments:

+  This          -  Indicates the calling context.

+  Address       -  Fvb device base address.

+

+Returns:     

+  EFI_SUCCESS  -  Successfully got Fvb's base address.

+  EFI_UNSUPPORTED -  Not supported.

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;

+  

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+  

+  if (FvbDevice->FvbAttributes & EFI_FVB_MEMORY_MAPPED) {

+    *Address = FvbDevice->BaseAddress;

+    return EFI_SUCCESS;

+  }

+  

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockGetBlockSize (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,

+  IN EFI_LBA                              Lba,

+  OUT UINTN                               *BlockSize,

+  OUT UINTN                               *NumberOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieves the size in bytes of a specific block within a firmware volume.

+

+Arguments:

+  This            -  Indicates the calling context.

+  Lba             -  Indicates the block for which to return the size.

+  BlockSize       -  Pointer to a caller-allocated UINTN in which the size of the

+                     block is returned.

+  NumberOfBlocks  -  Pointer to a caller-allocated UINTN in which the number of

+                     consecutive blocks starting with Lba is returned. All blocks

+                     in this range have a size of BlockSize.   

+Returns:

+  EFI_SUCCESS  -  The firmware volume base address is returned.

+  EFI_INVALID_PARAMETER  -  The requested LBA is out of range.

+--*/

+{

+  UINTN                                 TotalBlocks;

+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;

+  EFI_FV_BLOCK_MAP_ENTRY                *PtrBlockMapEntry;

+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;

+  

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+  

+  //

+  // Do parameter checking

+  //

+  if (Lba >= FvbDevice->NumBlocks) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);

+  

+  PtrBlockMapEntry = FwVolHeader->FvBlockMap;

+  

+  //

+  // Search the block map for the given block

+  //

+  TotalBlocks = 0;

+  while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->BlockLength !=0 )) {

+    TotalBlocks += PtrBlockMapEntry->NumBlocks;

+    if (Lba < TotalBlocks) {

+      //

+      // We find the range

+      //

+      break;

+    }

+    

+    PtrBlockMapEntry++;

+  }

+  

+  *BlockSize = PtrBlockMapEntry->BlockLength;

+  *NumberOfBlocks = TotalBlocks - (UINTN)Lba;

+  

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+ProduceFVBProtocolOnBuffer (

+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,

+  IN UINT64                 Length,

+  IN EFI_HANDLE             ParentHandle,

+  OUT EFI_HANDLE            *FvProtocol  OPTIONAL

+  )

+/*++

+

+Routine Description:

+    This routine produces a firmware volume block protocol on a given

+    buffer. 

+

+Arguments:

+    BaseAddress     - base address of the firmware volume image

+    Length          - length of the firmware volume image

+    ParentHandle    - handle of parent firmware volume, if this

+                      image came from an FV image file in another

+                      firmware volume (ala capsules)

+    FvProtocol      - Firmware volume block protocol produced.

+    

+Returns:

+    EFI_VOLUME_CORRUPTED    - Volume corrupted.

+    EFI_OUT_OF_RESOURCES    - No enough buffer to be allocated.

+    EFI_SUCCESS             - Successfully produced a FVB protocol on given buffer.

+                     

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_FW_VOL_BLOCK_DEVICE       *FvbDev;

+  EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader;

+  UINTN                         BlockIndex;

+  UINTN                         BlockIndex2;

+  UINTN                         LinearOffset;

+  EFI_FV_BLOCK_MAP_ENTRY        *PtrBlockMapEntry;

+

+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;

+  //

+  // Validate FV Header, if not as expected, return

+  //

+  if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) {

+    return EFI_VOLUME_CORRUPTED;

+  }

+  //

+  // Allocate EFI_FW_VOL_BLOCK_DEVICE 

+  //

+  FvbDev = CoreAllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);

+  if (FvbDev == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  FvbDev->BaseAddress   = BaseAddress;

+  FvbDev->FvbAttributes = FwVolHeader->Attributes;

+  FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle;

+

+  //

+  // Init the block caching fields of the device

+  // First, count the number of blocks

+  //

+  FvbDev->NumBlocks = 0;

+  for (PtrBlockMapEntry = FwVolHeader->FvBlockMap;

+        PtrBlockMapEntry->NumBlocks != 0;

+        PtrBlockMapEntry++) {

+    FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks;

+  }

+  //

+  // Second, allocate the cache

+  //

+  FvbDev->LbaCache = CoreAllocateBootServicesPool (FvbDev->NumBlocks * sizeof (LBA_CACHE));

+  if (FvbDev->LbaCache == NULL) {

+    CoreFreePool (FvbDev);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Last, fill in the cache with the linear address of the blocks

+  //

+  BlockIndex = 0;

+  LinearOffset = 0;

+  for (PtrBlockMapEntry = FwVolHeader->FvBlockMap;

+        PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {

+    for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {

+      FvbDev->LbaCache[BlockIndex].Base = LinearOffset;

+      FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->BlockLength;

+      LinearOffset += PtrBlockMapEntry->BlockLength;

+      BlockIndex++;

+    }

+  }

+

+  //

+  // Set up the devicepath

+  //

+  FvbDev->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;

+  FvbDev->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1;

+

+  //

+  //

+  // Attach FvVolBlock Protocol to new handle

+  //

+  Status = CoreInstallMultipleProtocolInterfaces (

+            &FvbDev->Handle,

+            &gEfiFirmwareVolumeBlockProtocolGuid,     &FvbDev->FwVolBlockInstance,

+            &gEfiDevicePathProtocolGuid,              &FvbDev->DevicePath,

+            &gEfiFirmwareVolumeDispatchProtocolGuid,  NULL,

+            NULL

+            );

+

+  //

+  // If they want the handle back, set it.

+  //

+  if (FvProtocol != NULL) {

+    *FvProtocol = FvbDev->Handle;

+  }

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+FwVolBlockDriverInit (

+  IN EFI_HANDLE                 ImageHandle,

+  IN EFI_SYSTEM_TABLE           *SystemTable

+  )

+/*++

+

+Routine Description:

+    This routine is the driver initialization entry point.  It initializes the

+    libraries, consumes FV hobs and NT_NON_MM_FV environment variable and

+    produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.

+Arguments:

+    ImageHandle   - The image handle.

+    SystemTable   - The system table.

+Returns:

+    EFI_SUCCESS   - Successfully initialized firmware volume block driver.

+--*/

+{

+  EFI_PEI_HOB_POINTERS          FvHob;

+  //

+  // Core Needs Firmware Volumes to function

+  //

+  FvHob.Raw = GetHobList ();

+  while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {

+    //

+    // Produce an FVB protocol for it

+    //

+    ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, NULL);    

+    FvHob.Raw = GET_NEXT_HOB (FvHob);

+  }

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CoreProcessFirmwareVolume (

+  IN VOID                             *FvHeader,

+  IN UINTN                            Size, 

+  OUT EFI_HANDLE                      *FVProtocolHandle

+  )

+/*++

+

+Routine Description:

+    This DXE service routine is used to process a firmware volume. In

+    particular, it can be called by BDS to process a single firmware

+    volume found in a capsule. 

+

+Arguments:

+    FvHeader              - pointer to a firmware volume header

+    Size                  - the size of the buffer pointed to by FvHeader

+    FVProtocolHandle      - the handle on which a firmware volume protocol

+                            was produced for the firmware volume passed in.

+

+Returns:

+    EFI_OUT_OF_RESOURCES  - if an FVB could not be produced due to lack of 

+                            system resources

+    EFI_VOLUME_CORRUPTED  - if the volume was corrupted

+    EFI_SUCCESS           - a firmware volume protocol was produced for the

+                            firmware volume

+

+--*/

+{

+  VOID        *Ptr;

+  EFI_STATUS  Status;

+

+  *FVProtocolHandle = NULL;

+  Status = ProduceFVBProtocolOnBuffer ( 

+            (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, 

+            (UINT64)Size, 

+            NULL, 

+            FVProtocolHandle

+            );

+  //

+  // Since in our implementation we use register-protocol-notify to put a

+  // FV protocol on the FVB protocol handle, we can't directly verify that

+  // the FV protocol was produced. Therefore here we will check the handle

+  // and make sure an FV protocol is on it. This indicates that all went 

+  // well. Otherwise we have to assume that the volume was corrupted 

+  // somehow.

+  //

+  if (!EFI_ERROR(Status)) {

+    Ptr = NULL;

+    Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Ptr);

+    if (EFI_ERROR(Status) || (Ptr == NULL)) {

+      return EFI_VOLUME_CORRUPTED;

+    }

+    return EFI_SUCCESS;

+  }

+  return Status;

+}

+

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/FwVolDriver.h b/edk2/EdkModulePkg/Core/Dxe/FwVolDriver.h
new file mode 100644
index 0000000..fb4e0d5
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/FwVolDriver.h
@@ -0,0 +1,466 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVolDriver.h

+

+Abstract:

+

+  Firmware File System protocol. Layers on top of Firmware

+  Block protocol to produce a file abstraction of FV based files.

+

+--*/

+

+#ifndef __FWVOL_H

+#define __FWVOL_H

+

+

+//

+// Used to track all non-deleted files

+//

+typedef struct {

+  LIST_ENTRY                      Link;

+  EFI_FFS_FILE_HEADER             *FfsHeader;

+  UINTN                           StreamHandle;

+  EFI_SECTION_EXTRACTION_PROTOCOL *Sep;

+} FFS_FILE_LIST_ENTRY;

+

+typedef struct {

+  UINTN                                   Signature;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL      *Fvb;

+  EFI_HANDLE                              Handle;

+  EFI_FIRMWARE_VOLUME_PROTOCOL            Fv;

+

+  EFI_FIRMWARE_VOLUME_HEADER              *FwVolHeader;

+  UINT8                                   *CachedFv;

+  UINT8                                   *EndOfCachedFv;

+

+  FFS_FILE_LIST_ENTRY                     *LastKey;

+

+  LIST_ENTRY                              FfsFileListHeader;

+

+  UINT8                                   ErasePolarity;

+} FV_DEVICE;

+

+#define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV_DEVICE_SIGNATURE)

+

+

+EFI_STATUS

+EFIAPI

+FvGetVolumeAttributes (

+  IN    EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  OUT   EFI_FV_ATTRIBUTES              *Attributes

+  )

+/*++

+

+Routine Description:

+    Retrieves attributes, insures positive polarity of attribute bits, returns

+    resulting attributes in output parameter

+

+Arguments:

+    This        - Calling context

+    Attributes  - output buffer which contains attributes

+

+Returns:

+    EFI_SUCCESS         - Successfully got volume attributes

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+FvSetVolumeAttributes (

+  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN OUT EFI_FV_ATTRIBUTES              *Attributes

+  )

+/*++

+

+Routine Description:

+    Sets current attributes for volume

+

+Arguments:

+    This       - Calling context

+    Attributes - At input, contains attributes to be set.  At output contains

+      new value of FV

+

+Returns:

+    EFI_UNSUPPORTED   - Could not be set.

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+FvGetNextFile (

+  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN OUT VOID                           *Key,

+  IN OUT EFI_FV_FILETYPE                *FileType,

+  OUT    EFI_GUID                       *NameGuid,

+  OUT    EFI_FV_FILE_ATTRIBUTES         *Attributes,

+  OUT    UINTN                          *Size

+  )

+/*++

+

+Routine Description:

+    Given the input key, search for the next matching file in the volume.

+

+Arguments:

+    This          -   Indicates the calling context.

+    FileType      -   FileType is a pointer to a caller allocated

+                      EFI_FV_FILETYPE. The GetNextFile() API can filter it's

+                      search for files based on the value of *FileType input.

+                      A *FileType input of 0 causes GetNextFile() to search for

+                      files of all types.  If a file is found, the file's type

+                      is returned in *FileType.  *FileType is not modified if

+                      no file is found.

+    Key           -   Key is a pointer to a caller allocated buffer that

+                      contains implementation specific data that is used to

+                      track where to begin the search for the next file.

+                      The size of the buffer must be at least This->KeySize

+                      bytes long. To reinitialize the search and begin from

+                      the beginning of the firmware volume, the entire buffer

+                      must be cleared to zero. Other than clearing the buffer

+                      to initiate a new search, the caller must not modify the

+                      data in the buffer between calls to GetNextFile().

+    NameGuid      -   NameGuid is a pointer to a caller allocated EFI_GUID.

+                      If a file is found, the file's name is returned in

+                      *NameGuid.  *NameGuid is not modified if no file is

+                      found.

+    Attributes    -   Attributes is a pointer to a caller allocated

+                      EFI_FV_FILE_ATTRIBUTES.  If a file is found, the file's

+                      attributes are returned in *Attributes. *Attributes is

+                      not modified if no file is found.

+    Size          -   Size is a pointer to a caller allocated UINTN.

+                      If a file is found, the file's size is returned in *Size.

+                      *Size is not modified if no file is found.

+

+Returns:    

+    EFI_SUCCESS                 - Successfully find the file.

+    EFI_DEVICE_ERROR            - Device error.

+    EFI_ACCESS_DENIED           - Fv could not read.

+    EFI_NOT_FOUND               - No matching file found.

+    EFI_INVALID_PARAMETER       - Invalid parameter

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+FvReadFile (

+  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN     EFI_GUID                       *NameGuid,

+  IN OUT VOID                           **Buffer,

+  IN OUT UINTN                          *BufferSize,

+  OUT    EFI_FV_FILETYPE                *FoundType,

+  OUT    EFI_FV_FILE_ATTRIBUTES         *FileAttributes,

+  OUT    UINT32                         *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+    Locates a file in the firmware volume and

+    copies it to the supplied buffer.

+

+Arguments:

+    This              -   Indicates the calling context.

+    NameGuid          -   Pointer to an EFI_GUID, which is the filename.

+    Buffer            -   Buffer is a pointer to pointer to a buffer in

+                          which the file or section contents or are returned.

+    BufferSize        -   BufferSize is a pointer to caller allocated

+                          UINTN. On input *BufferSize indicates the size

+                          in bytes of the memory region pointed to by

+                          Buffer. On output, *BufferSize contains the number

+                          of bytes required to read the file.

+    FoundType         -   FoundType is a pointer to a caller allocated

+                          EFI_FV_FILETYPE that on successful return from Read()

+                          contains the type of file read.  This output reflects

+                          the file type irrespective of the value of the

+                          SectionType input.

+    FileAttributes    -   FileAttributes is a pointer to a caller allocated

+                          EFI_FV_FILE_ATTRIBUTES.  On successful return from

+                          Read(), *FileAttributes contains the attributes of

+                          the file read.

+    AuthenticationStatus -  AuthenticationStatus is a pointer to a caller

+                          allocated UINTN in which the authentication status

+                          is returned.

+Returns:

+    EFI_SUCCESS                   - Successfully read to memory buffer.

+    EFI_WARN_BUFFER_TOO_SMALL     - Buffer too small.

+    EFI_NOT_FOUND                 - Not found.

+    EFI_DEVICE_ERROR              - Device error.

+    EFI_ACCESS_DENIED             - Could not read.

+    EFI_INVALID_PARAMETER         - Invalid parameter.

+    EFI_OUT_OF_RESOURCES          - Not enough buffer to be allocated.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+FvReadFileSection (

+  IN     EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN     EFI_GUID                       *NameGuid,

+  IN     EFI_SECTION_TYPE               SectionType,

+  IN     UINTN                          SectionInstance,

+  IN OUT VOID                           **Buffer,

+  IN OUT UINTN                          *BufferSize,

+  OUT    UINT32                         *AuthenticationStatus

+  )

+/*++

+

+  Routine Description:

+    Locates a section in a given FFS File and

+    copies it to the supplied buffer (not including section header).

+

+  Arguments:

+    This              -   Indicates the calling context.

+    NameGuid          -   Pointer to an EFI_GUID, which is the filename.

+    SectionType       -   Indicates the section type to return.

+    SectionInstance   -   Indicates which instance of sections with a type of

+                          SectionType to return.

+    Buffer            -   Buffer is a pointer to pointer to a buffer in which

+                          the file or section contents or are returned.

+    BufferSize        -   BufferSize is a pointer to caller allocated UINTN.

+    AuthenticationStatus -AuthenticationStatus is a pointer to a caller

+                          allocated UINT32 in which the authentication status

+                          is returned.

+

+  Returns:

+    EFI_SUCCESS                     - Successfully read the file section into buffer.

+    EFI_WARN_BUFFER_TOO_SMALL       - Buffer too small.

+    EFI_NOT_FOUND                   - Section not found.

+    EFI_DEVICE_ERROR                - Device error.

+    EFI_ACCESS_DENIED               - Could not read.

+    EFI_INVALID_PARAMETER           - Invalid parameter.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+FvWriteFile (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL       *This,

+  IN UINT32                             NumberOfFiles,

+  IN EFI_FV_WRITE_POLICY                WritePolicy,

+  IN EFI_FV_WRITE_FILE_DATA             *FileData

+  )

+/*++

+

+    Routine Description:

+      Writes one or more files to the firmware volume.

+

+    Arguments:

+    This        - Indicates the calling context.

+    WritePolicy - WritePolicy indicates the level of reliability for

+                  the write in the event of a power failure or other

+                  system failure during the write operation.

+    FileData    - FileData is an pointer to an array of EFI_FV_WRITE_DATA.

+                  Each element of FileData[] represents a file to be written.

+

+    Returns:

+      EFI_SUCCESS                   - Files successfully written to firmware volume

+      EFI_OUT_OF_RESOURCES          - Not enough buffer to be allocated.

+      EFI_DEVICE_ERROR              - Device error.

+      EFI_WRITE_PROTECTED           - Write protected.

+      EFI_NOT_FOUND                 - Not found.

+      EFI_INVALID_PARAMETER         - Invalid parameter.

+      EFI_UNSUPPORTED               - This function not supported.

+

+--*/

+;

+

+

+  

+//

+//Internal functions

+//

+typedef enum {

+  EfiCheckSumUint8    = 0,

+  EfiCheckSumUint16   = 1,

+  EfiCheckSumUint32   = 2,

+  EfiCheckSumUint64   = 3,

+  EfiCheckSumMaximum  = 4

+} EFI_CHECKSUM_TYPE;

+

+

+BOOLEAN

+IsBufferErased (

+  IN UINT8    ErasePolarity,

+  IN VOID     *Buffer,

+  IN UINTN    BufferSize

+  )

+/*++

+

+Routine Description:

+  Check if a block of buffer is erased

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  Buffer        -  The buffer to be checked

+  BufferSize    -  Size of the buffer in bytes

+    

+Returns:

+  TRUE  -  The block of buffer is erased

+  FALSE -  The block of buffer is not erased

+    

+--*/

+;

+

+EFI_FFS_FILE_STATE 

+GetFileState (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Get the FFS file state by checking the highest bit set in the header's state field

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  FfsHeader     -  Points to the FFS file header

+    

+Returns:

+  FFS File state 

+    

+--*/

+;

+

+VOID

+SetFileState (

+  IN UINT8                State,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Set the FFS file state.

+

+Arguments:

+  State         -  The state to be set.

+  FfsHeader     -  Points to the FFS file header

+    

+Returns:

+  None.

+    

+--*/

+;

+

+BOOLEAN

+VerifyFvHeaderChecksum (

+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader

+  )

+/*++

+

+Routine Description:

+  Verify checksum of the firmware volume header 

+

+Arguments:

+  FvHeader  -  Points to the firmware volume header to be checked

+    

+Returns:

+  TRUE  -  Checksum verification passed

+  FALSE -  Checksum verification failed

+    

+--*/

+;

+    

+BOOLEAN

+IsValidFfsHeader (

+  IN  UINT8                ErasePolarity,

+  IN  EFI_FFS_FILE_HEADER  *FfsHeader,

+  OUT EFI_FFS_FILE_STATE   *FileState

+  )

+/*++

+

+Routine Description:

+  Check if it's a valid FFS file header

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  FfsHeader     -  Points to the FFS file header to be checked

+  FileState     -  FFS file state to be returned

+    

+Returns:

+  TRUE  -  Valid FFS file header

+  FALSE -  Invalid FFS file header

+    

+--*/

+;

+

+BOOLEAN

+IsValidFfsFile (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Check if it's a valid FFS file. 

+  Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.

+

+Arguments:

+  ErasePolarity -  Erase polarity attribute of the firmware volume

+  FfsHeader     -  Points to the FFS file to be checked

+    

+Returns:

+  TRUE  -  Valid FFS file

+  FALSE -  Invalid FFS file

+    

+--*/

+;

+

+EFI_STATUS

+GetFwVolHeader (

+  IN  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL      *Fvb,

+  OUT EFI_FIRMWARE_VOLUME_HEADER              **FwVolHeader

+  )

+/*++

+

+Routine Description:

+  given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and

+  copy the volume header into it.

+

+Arguments:

+  Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume

+          header

+  FwVolHeader - Pointer to pointer to allocated buffer in which the volume

+                  header is returned.

+

+Returns:

+  Status code.

+

+--*/

+;

+

+

+EFI_STATUS

+FvCheck (

+  IN OUT FV_DEVICE  *FvDevice

+  )

+/*++

+

+Routine Description:

+  Check if a FV is consistent and allocate cache

+

+Arguments:

+  FvDevice - pointer to the FvDevice to be checked.

+

+Returns:

+  EFI_OUT_OF_RESOURCES    - Not enough buffer to be allocated.

+  EFI_SUCCESS             - FV is consistent and cache is allocated.

+  EFI_VOLUME_CORRUPTED    - File system is corrupted.

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/Gcd/gcd.c b/edk2/EdkModulePkg/Core/Dxe/Gcd/gcd.c
new file mode 100644
index 0000000..73037ed
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Gcd/gcd.c
@@ -0,0 +1,2481 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    gcd.c

+

+Abstract:

+    The file contains the GCD related services in the EFI Boot Services Table.

+    The GCD services are used to manage the memory and I/O regions that 

+    are accessible to the CPU that is executing the DXE core.

+

+--*/

+

+#include <DxeMain.h>

+

+#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000

+

+#define MEMORY_ATTRIBUTE_MASK         (EFI_RESOURCE_ATTRIBUTE_PRESENT             | \

+                                       EFI_RESOURCE_ATTRIBUTE_INITIALIZED         | \

+                                       EFI_RESOURCE_ATTRIBUTE_TESTED              | \

+                                       EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED      | \

+                                       EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED     | \

+                                       EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \

+                                       EFI_RESOURCE_ATTRIBUTE_16_BIT_IO           | \

+                                       EFI_RESOURCE_ATTRIBUTE_32_BIT_IO           | \

+                                       EFI_RESOURCE_ATTRIBUTE_64_BIT_IO           ) 

+

+#define TESTED_MEMORY_ATTRIBUTES      (EFI_RESOURCE_ATTRIBUTE_PRESENT     | \

+                                       EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \

+                                       EFI_RESOURCE_ATTRIBUTE_TESTED      )

+

+#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT     | \

+                                       EFI_RESOURCE_ATTRIBUTE_INITIALIZED )

+

+#define PRESENT_MEMORY_ATTRIBUTES     (EFI_RESOURCE_ATTRIBUTE_PRESENT)

+

+#define INVALID_CPU_ARCH_ATTRIBUTES   0xffffffff

+

+//

+// Module Variables

+//

+EFI_LOCK           mGcdMemorySpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);

+EFI_LOCK           mGcdIoSpaceLock     = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);

+LIST_ENTRY         mGcdMemorySpaceMap  = INITIALIZE_LIST_HEAD_VARIABLE (mGcdMemorySpaceMap);

+LIST_ENTRY         mGcdIoSpaceMap      = INITIALIZE_LIST_HEAD_VARIABLE (mGcdIoSpaceMap);

+

+EFI_GCD_MAP_ENTRY mGcdMemorySpaceMapEntryTemplate = {

+  EFI_GCD_MAP_SIGNATURE,

+  { NULL, NULL },

+  0,

+  0,

+  0,

+  0,

+  EfiGcdMemoryTypeNonExistent,

+  0,

+  NULL,

+  NULL

+};

+

+EFI_GCD_MAP_ENTRY mGcdIoSpaceMapEntryTemplate = {

+  EFI_GCD_MAP_SIGNATURE,

+  { NULL, NULL },

+  0,

+  0,

+  0,

+  0,

+  0,

+  EfiGcdIoTypeNonExistent,

+  NULL,

+  NULL

+};

+

+GCD_ATTRIBUTE_CONVERSION_ENTRY mAttributeConversionTable[] = {

+  { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE,             EFI_MEMORY_UC,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED,       EFI_MEMORY_UCE,         TRUE  },   

+  { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE,       EFI_MEMORY_WC,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,    EFI_MEMORY_WB,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED,          EFI_MEMORY_RP,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED,         EFI_MEMORY_WP,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED,     EFI_MEMORY_XP,          TRUE  },

+  { EFI_RESOURCE_ATTRIBUTE_PRESENT,                 EFI_MEMORY_PRESENT,     FALSE },

+  { EFI_RESOURCE_ATTRIBUTE_INITIALIZED,             EFI_MEMORY_INITIALIZED, FALSE },

+  { EFI_RESOURCE_ATTRIBUTE_TESTED,                  EFI_MEMORY_TESTED,      FALSE },

+  { 0, 0, FALSE }

+};

+

+VOID

+CoreAcquireGcdMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+    Acquire memory lock on mGcdMemorySpaceLock

+

+Arguments:

+    None

+

+Returns:

+    None

+

+--*/

+{

+  CoreAcquireLock (&mGcdMemorySpaceLock);

+}

+

+

+VOID

+CoreReleaseGcdMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+    Release memory lock on mGcdMemorySpaceLock

+

+Arguments:

+    None

+

+Returns:

+    None

+

+--*/

+{

+  CoreReleaseLock (&mGcdMemorySpaceLock);

+}

+

+

+

+VOID

+CoreAcquireGcdIoLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+    Acquire memory lock on mGcdIoSpaceLock

+

+Arguments:

+    None

+

+Returns:

+    None

+

+--*/

+{

+  CoreAcquireLock (&mGcdIoSpaceLock);

+}

+

+

+VOID

+CoreReleaseGcdIoLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+    Release memory lock on mGcdIoSpaceLock

+

+Arguments:

+    None

+

+Returns:

+    None

+

+--*/

+{

+  CoreReleaseLock (&mGcdIoSpaceLock);

+}

+

+

+

+//

+// GCD Initialization Worker Functions

+//

+UINT64

+AlignValue (

+  IN UINT64   Value,

+  IN UINTN    Alignment,

+  IN BOOLEAN  RoundUp

+  )

+/*++

+

+Routine Description:

+

+  Aligns a value to the specified boundary.

+

+Arguments:

+

+  Value     - 64 bit value to align

+  Alignment - Log base 2 of the boundary to align Value to

+  RoundUp   - TRUE if Value is to be rounded up to the nearest aligned boundary. 

+              FALSE is Value is to be rounded down to the nearest aligned boundary.

+

+Returns:

+

+  A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.

+

+--*/

+{

+  UINT64  AlignmentMask;

+

+  AlignmentMask = LShiftU64 (1, Alignment) - 1;

+  if (RoundUp) {

+    Value += AlignmentMask;

+  }

+  return Value & (~AlignmentMask);

+}

+

+UINT64

+PageAlignAddress (

+  IN UINT64 Value

+  )

+/*++

+

+Routine Description:

+

+  Aligns address to the page boundary.

+

+Arguments:

+

+  Value     - 64 bit address to align

+

+Returns:

+

+  A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.

+

+--*/

+{

+  return AlignValue (Value, EFI_PAGE_SHIFT, TRUE);

+}

+

+UINT64

+PageAlignLength (

+  IN UINT64 Value

+  )

+/*++

+

+Routine Description:

+

+  Aligns length to the page boundary.

+

+Arguments:

+

+  Value     - 64 bit length to align

+

+Returns:

+

+  A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.

+

+--*/

+{

+  return AlignValue (Value, EFI_PAGE_SHIFT, FALSE);

+}

+

+//

+// GCD Memory Space Worker Functions

+//

+EFI_STATUS

+CoreAllocateGcdMapEntry (

+  IN OUT EFI_GCD_MAP_ENTRY  **TopEntry,

+  IN OUT EFI_GCD_MAP_ENTRY  **BottomEntry

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool for two entries.

+

+Arguments:

+

+  TopEntry      - An entry of GCD map

+  BottomEntry   - An entry of GCD map

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to be allocated.

+  EFI_SUCCESS             - Both entries successfully allocated.

+

+--*/

+{

+  *TopEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_GCD_MAP_ENTRY));

+  if (*TopEntry == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  *BottomEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_GCD_MAP_ENTRY));

+  if (*BottomEntry == NULL) {

+    CoreFreePool (*TopEntry);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreInsertGcdMapEntry (

+  IN LIST_ENTRY           *Link,

+  IN EFI_GCD_MAP_ENTRY     *Entry,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN EFI_GCD_MAP_ENTRY     *TopEntry,

+  IN EFI_GCD_MAP_ENTRY     *BottomEntry

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Inserts a new descriptor into a sorted list

+

+Arguments:

+

+  Link        - The linked list to insert the range BaseAddress and Length into

+

+  Entry     -   A pointer to the entry that is inserted

+

+  BaseAddress - The base address of the new range

+  

+  Length      - The length of the new range in bytes

+  

+  TopEntry    - Top pad entry to insert if needed.

+

+  BottomEntry - Bottom pad entry to insert if needed.

+

+Returns:

+

+  EFI_SUCCESS - The new range was inserted into the linked list

+  

+--*/

+{

+  ASSERT (Length != 0);

+  ASSERT (TopEntry->Signature == 0);

+  ASSERT (BottomEntry->Signature == 0);

+

+  if (BaseAddress > Entry->BaseAddress) {

+    CopyMem (BottomEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));

+    Entry->BaseAddress      = BaseAddress;

+    BottomEntry->EndAddress = BaseAddress - 1;

+    InsertTailList (Link, &BottomEntry->Link);

+  } 

+

+  if ((BaseAddress + Length - 1) < Entry->EndAddress) {

+    CopyMem (TopEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));

+    TopEntry->BaseAddress = BaseAddress + Length;

+    Entry->EndAddress     = BaseAddress + Length - 1;

+    InsertHeadList (Link, &TopEntry->Link);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreMergeGcdMapEntry (

+  IN LIST_ENTRY      *Link,

+  IN BOOLEAN         Forward,

+  IN LIST_ENTRY      *Map

+  )

+/*++

+

+Routine Description:

+

+  Merge the Gcd region specified by Link and its adjacent entry

+

+Arguments:

+

+  Link      - Specify the entry to be merged (with its adjacent entry).

+  

+  Forward   - Direction (forward or backward).

+  

+  Map       - Boundary.

+

+Returns:

+

+  EFI_SUCCESS     - Successfully returned.

+  

+  EFI_UNSUPPORTED - These adjacent regions could not merge.

+

+--*/

+{

+  LIST_ENTRY         *AdjacentLink;

+  EFI_GCD_MAP_ENTRY  *Entry;

+  EFI_GCD_MAP_ENTRY  *AdjacentEntry;

+

+  //

+  // Get adjacent entry

+  //

+  if (Forward) {

+    AdjacentLink = Link->ForwardLink;

+  } else {

+    AdjacentLink = Link->BackLink;

+  }

+

+  //

+  // If AdjacentLink is the head of the list, then no merge can be performed

+  //

+  if (AdjacentLink == Map) {

+    return EFI_SUCCESS;

+  }

+

+  Entry         = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+  AdjacentEntry = CR (AdjacentLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+

+  if (Entry->Capabilities != AdjacentEntry->Capabilities) {

+    return EFI_UNSUPPORTED;

+  }

+  if (Entry->Attributes != AdjacentEntry->Attributes) {

+    return EFI_UNSUPPORTED;

+  }

+  if (Entry->GcdMemoryType != AdjacentEntry->GcdMemoryType) {

+    return EFI_UNSUPPORTED;

+  }

+  if (Entry->GcdIoType != AdjacentEntry->GcdIoType) {

+    return EFI_UNSUPPORTED;

+  }

+  if (Entry->ImageHandle != AdjacentEntry->ImageHandle) {

+    return EFI_UNSUPPORTED;

+  }

+  if (Entry->DeviceHandle != AdjacentEntry->DeviceHandle) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Forward) {

+    Entry->EndAddress  = AdjacentEntry->EndAddress;

+  } else {

+    Entry->BaseAddress = AdjacentEntry->BaseAddress;

+  }

+  RemoveEntryList (AdjacentLink);

+  CoreFreePool (AdjacentEntry);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreCleanupGcdMapEntry (

+  IN EFI_GCD_MAP_ENTRY  *TopEntry,

+  IN EFI_GCD_MAP_ENTRY  *BottomEntry,

+  IN LIST_ENTRY         *StartLink,

+  IN LIST_ENTRY         *EndLink,

+  IN LIST_ENTRY         *Map

+  )

+/*++

+

+Routine Description:

+

+  Merge adjacent entries on total chain.

+

+Arguments:

+

+  TopEntry      - Top entry of GCD map.

+  

+  BottomEntry   - Bottom entry of GCD map.

+  

+  StartLink     - Start link of the list for this loop.

+  

+  EndLink       - End link of the list for this loop.

+  

+  Map           - Boundary.

+

+Returns:

+

+  EFI_SUCCESS   - GCD map successfully cleaned up.

+

+--*/

+{

+  LIST_ENTRY  *Link;

+

+  if (TopEntry->Signature == 0) {

+    CoreFreePool (TopEntry);

+  }

+  if (BottomEntry->Signature == 0) {

+    CoreFreePool (BottomEntry);

+  }

+

+  Link = StartLink;

+  while (Link != EndLink->ForwardLink) {

+    CoreMergeGcdMapEntry (Link, FALSE, Map);

+    Link = Link->ForwardLink;

+  }

+  CoreMergeGcdMapEntry (EndLink, TRUE, Map);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreSearchGcdMapEntry (

+  IN  EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN  UINT64                Length,

+  OUT LIST_ENTRY            **StartLink,

+  OUT LIST_ENTRY            **EndLink,

+  IN  LIST_ENTRY            *Map

+  )

+/*++

+

+Routine Description:

+

+  Search a segment of memory space in GCD map. The result is a range of GCD entry list.

+

+Arguments:

+

+  BaseAddress       - The start address of the segment.

+  

+  Length            - The length of the segment.

+  

+  StartLink         - The first GCD entry involves this segment of memory space.

+  

+  EndLink           - The first GCD entry involves this segment of memory space.

+  

+  Map               - Points to the start entry to search.

+

+Returns:

+

+  EFI_SUCCESS       - Successfully found the entry.

+  

+  EFI_NOT_FOUND     - Not found.

+

+--*/

+{

+  LIST_ENTRY         *Link;

+  EFI_GCD_MAP_ENTRY  *Entry;

+

+  ASSERT (Length != 0);

+

+  *StartLink = NULL;

+  *EndLink   = NULL;

+

+  Link = Map->ForwardLink;

+  while (Link != Map) {

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    if (BaseAddress >= Entry->BaseAddress && BaseAddress <= Entry->EndAddress) {

+      *StartLink = Link;

+    }

+    if (*StartLink != NULL) {

+      if ((BaseAddress + Length - 1) >= Entry->BaseAddress && 

+          (BaseAddress + Length - 1) <= Entry->EndAddress     ) {

+        *EndLink = Link;

+        return EFI_SUCCESS;

+      }

+    }

+    Link = Link->ForwardLink;

+  }

+  return EFI_NOT_FOUND;

+}

+

+UINTN

+CoreCountGcdMapEntry (

+  IN LIST_ENTRY  *Map

+  )

+/*++

+

+Routine Description:

+

+  Count the amount of GCD map entries.

+

+Arguments:

+

+  Map       - Points to the start entry to do the count loop.

+

+Returns:

+

+  The count.

+

+--*/

+{

+  UINTN           Count;

+  LIST_ENTRY      *Link;

+

+  Count = 0;

+  Link = Map->ForwardLink;

+  while (Link != Map) {

+    Count++;

+    Link = Link->ForwardLink;

+  }

+  return Count;

+}

+

+

+

+UINT64

+ConverToCpuArchAttributes (

+  UINT64 Attributes

+  ) 

+/*++

+

+Routine Description:

+

+  Return the memory attribute specified by Attributes

+

+Arguments:

+

+  Attributes        - A num with some attribute bits on.

+

+Returns:

+

+  The enum value of memory attribute.

+

+--*/

+{

+  if ( (Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) {

+    return EFI_MEMORY_UC;

+  }

+

+  if ( (Attributes & EFI_MEMORY_WC ) == EFI_MEMORY_WC) {

+    return EFI_MEMORY_WC;

+  }

+

+  if ( (Attributes & EFI_MEMORY_WT ) == EFI_MEMORY_WT) {

+    return EFI_MEMORY_WT;

+  }

+

+  if ( (Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) {

+    return EFI_MEMORY_WB;

+  }

+

+  if ( (Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) {

+    return EFI_MEMORY_WP;

+  }

+

+  return INVALID_CPU_ARCH_ATTRIBUTES;

+

+}

+

+

+EFI_STATUS

+CoreConvertSpace (

+  IN UINTN                 Operation,

+  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,

+  IN EFI_GCD_IO_TYPE       GcdIoType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Capabilities,

+  IN UINT64                Attributes

+  )

+/*++

+

+Routine Description:

+

+  Do operation on a segment of memory space specified (add, free, remove, change attribute ...).

+

+Arguments:

+

+  Operation       - The type of the operation

+  

+  GcdMemoryType   - Additional information for the operation

+  

+  GcdIoType       - Additional information for the operation

+  

+  BaseAddress     - Start address of the segment

+  

+  Length          - length of the segment

+  

+  Capabilities    - The alterable attributes of a newly added entry

+  

+  Attributes      - The attributes needs to be set

+  

+Returns:

+

+  EFI_INVALID_PARAMETER       - Length is 0 or address (length) not aligned when setting attribute.

+  

+  EFI_SUCCESS                 - Action successfully done.

+  

+  EFI_UNSUPPORTED             - Could not find the proper descriptor on this segment or 

+                                set an upsupported attribute.

+  

+  EFI_ACCESS_DENIED           - Operate on an space non-exist or is used for an image.

+  

+  EFI_NOT_FOUND               - Free a non-using space or remove a non-exist space, and so on.

+  

+  EFI_OUT_OF_RESOURCES        - No buffer could be allocated.

+

+Returns:

+

+--*/

+{

+  EFI_STATUS         Status;

+  LIST_ENTRY         *Map;

+  LIST_ENTRY         *Link;

+  EFI_GCD_MAP_ENTRY  *Entry;

+  EFI_GCD_MAP_ENTRY  *TopEntry;

+  EFI_GCD_MAP_ENTRY  *BottomEntry;

+  LIST_ENTRY         *StartLink;

+  LIST_ENTRY         *EndLink;

+  

+  EFI_CPU_ARCH_PROTOCOL           *CpuArch;

+  UINT64                          CpuArchAttributes;

+

+  if (Length == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Map = NULL;

+  if (Operation & GCD_MEMORY_SPACE_OPERATION) {

+    CoreAcquireGcdMemoryLock ();

+    Map = &mGcdMemorySpaceMap;

+  }

+  if (Operation & GCD_IO_SPACE_OPERATION) {

+    CoreAcquireGcdIoLock ();

+    Map = &mGcdIoSpaceMap;

+  }

+

+  //

+  // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length

+  //

+  Status = CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, &EndLink, Map);

+  if (EFI_ERROR (Status)) {

+    Status = EFI_UNSUPPORTED;

+

+    goto Done;

+  }

+

+  //

+  // Verify that the list of descriptors are unallocated non-existent memory.

+  //

+  Link = StartLink;

+  while (Link != EndLink->ForwardLink) {

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    switch (Operation) {

+    //

+    // Add operations

+    //

+    case GCD_ADD_MEMORY_OPERATION:

+      if (Entry->GcdMemoryType != EfiGcdMemoryTypeNonExistent ||

+          Entry->ImageHandle   != NULL                           ) {

+        Status = EFI_ACCESS_DENIED;

+        goto Done;

+      }

+      break;

+    case GCD_ADD_IO_OPERATION:

+      if (Entry->GcdIoType   != EfiGcdIoTypeNonExistent ||

+          Entry->ImageHandle != NULL                       ) {

+        Status = EFI_ACCESS_DENIED;

+        goto Done;

+      }

+      break;

+    //

+    // Free operations

+    //

+    case GCD_FREE_MEMORY_OPERATION:

+    case GCD_FREE_IO_OPERATION:

+      if (Entry->ImageHandle == NULL) {

+        Status = EFI_NOT_FOUND;

+        goto Done;

+      }

+      break;

+    //

+    // Remove operations

+    //

+    case GCD_REMOVE_MEMORY_OPERATION:

+      if (Entry->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {

+        Status = EFI_NOT_FOUND;

+        goto Done;

+      }

+      if (Entry->ImageHandle != NULL) {

+        Status = EFI_ACCESS_DENIED;

+        goto Done;

+      }

+      break;

+    case GCD_REMOVE_IO_OPERATION:

+      if (Entry->GcdIoType == EfiGcdIoTypeNonExistent) {

+        Status = EFI_NOT_FOUND;

+        goto Done;

+      }

+      if (Entry->ImageHandle != NULL) {

+        Status = EFI_ACCESS_DENIED;

+        goto Done;

+      }

+      break;

+    //

+    // Set attribute operations

+    //

+    case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:

+      if (Attributes & EFI_MEMORY_RUNTIME) {

+        if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) {

+          Status = EFI_INVALID_PARAMETER;

+

+          goto Done;

+        }

+      }

+      if ((Entry->Capabilities & Attributes) != Attributes) {

+        Status = EFI_UNSUPPORTED;

+        goto Done;

+      }

+      break;

+    }

+    Link = Link->ForwardLink;

+  }

+

+  //

+  // Allocate work space to perform this operation

+  //

+  Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);

+  if (EFI_ERROR (Status)) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  //

+  //

+  //

+  if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) {

+    //

+    // Call CPU Arch Protocol to attempt to set attributes on the range

+    //

+    CpuArchAttributes = ConverToCpuArchAttributes (Attributes);

+    if ( CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES ) {

+      Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&CpuArch);

+      if (EFI_ERROR (Status)) {

+        Status = EFI_ACCESS_DENIED;

+        goto Done;

+      }

+

+      Status = CpuArch->SetMemoryAttributes (

+                          CpuArch,

+                          BaseAddress,

+                          Length,

+                          CpuArchAttributes

+                          );

+      if (EFI_ERROR (Status)) {

+        goto Done;

+      }

+    }

+

+  }

+

+  //

+  // Convert/Insert the list of descriptors from StartLink to EndLink

+  //

+  Link = StartLink;

+  while (Link != EndLink->ForwardLink) {

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    CoreInsertGcdMapEntry (Link, Entry, BaseAddress, Length, TopEntry, BottomEntry);

+    switch (Operation) {

+    //

+    // Add operations

+    //

+    case GCD_ADD_MEMORY_OPERATION:

+      Entry->GcdMemoryType = GcdMemoryType;

+      if (GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {

+        Entry->Capabilities  = Capabilities | EFI_MEMORY_RUNTIME | EFI_MEMORY_PORT_IO;

+      } else {

+        Entry->Capabilities  = Capabilities | EFI_MEMORY_RUNTIME;

+      }

+      break;

+    case GCD_ADD_IO_OPERATION:

+      Entry->GcdIoType = GcdIoType;

+      break;

+    //

+    // Free operations

+    //

+    case GCD_FREE_MEMORY_OPERATION:

+    case GCD_FREE_IO_OPERATION:

+      Entry->ImageHandle  = NULL;

+      Entry->DeviceHandle = NULL;

+      break;

+    //

+    // Remove operations

+    //

+    case GCD_REMOVE_MEMORY_OPERATION:

+      Entry->GcdMemoryType = EfiGcdMemoryTypeNonExistent;

+      Entry->Capabilities  = 0;

+      break;

+    case GCD_REMOVE_IO_OPERATION:

+      Entry->GcdIoType = EfiGcdIoTypeNonExistent;

+      break;

+    //

+    // Set attribute operations

+    //

+    case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:

+      Entry->Attributes = Attributes;

+      break;

+    }

+    Link = Link->ForwardLink;

+  }

+

+  //

+  // Cleanup

+  //

+  Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);

+

+Done:

+  if (Operation & GCD_MEMORY_SPACE_OPERATION) {

+    CoreReleaseGcdMemoryLock ();

+  }

+  if (Operation & GCD_IO_SPACE_OPERATION) {

+    CoreReleaseGcdIoLock ();

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+CoreAllocateSpaceCheckEntry (

+  IN UINTN                Operation,

+  IN EFI_GCD_MAP_ENTRY    *Entry,

+  IN EFI_GCD_MEMORY_TYPE  GcdMemoryType,

+  IN EFI_GCD_IO_TYPE      GcdIoType

+  )

+/*++

+

+Routine Description:

+

+  Check whether an entry could be used to allocate space.

+

+Arguments:

+

+  Operation       - Allocate memory or IO

+  

+  Entry           - The entry to be tested

+  

+  GcdMemoryType   - The desired memory type

+  

+  GcdIoType       - The desired IO type

+  

+Returns:

+

+  EFI_NOT_FOUND   - The memory type does not match or there's an image handle on the entry.

+  

+  EFI_UNSUPPORTED - The operation unsupported.

+  

+  EFI_SUCCESS     - It's ok for this entry to be used to allocate space.

+

+--*/

+{

+  if (Entry->ImageHandle != NULL) {

+    return EFI_NOT_FOUND;

+  }

+  switch (Operation) {

+  case GCD_ALLOCATE_MEMORY_OPERATION:

+    if (Entry->GcdMemoryType != GcdMemoryType) {

+      return EFI_NOT_FOUND;

+    }

+    break;

+  case GCD_ALLOCATE_IO_OPERATION:

+    if (Entry->GcdIoType != GcdIoType) {

+      return EFI_NOT_FOUND;

+    }

+    break;

+  default:

+    return EFI_UNSUPPORTED;

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreAllocateSpace (

+  IN     UINTN                  Operation,

+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,

+  IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,

+  IN     EFI_GCD_IO_TYPE        GcdIoType,

+  IN     UINTN                  Alignment,

+  IN     UINT64                 Length,

+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,

+  IN     EFI_HANDLE             ImageHandle,

+  IN     EFI_HANDLE             DeviceHandle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Allocate space on specified address and length.

+

+Arguments:

+

+  Operation         - The type of operation (memory or IO)

+  

+  GcdAllocateType   - The type of allocate operation

+  

+  GcdMemoryType     - The desired memory type

+  

+  GcdIoType         - The desired IO type

+  

+  Alignment         - Align with 2^Alignment

+  

+  Length            - Length to allocate

+  

+  BaseAddress       - Base address to allocate

+  

+  ImageHandle       - The image handle consume the allocated space.

+  

+  DeviceHandle      - The device handle consume the allocated space.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter.

+  

+  EFI_NOT_FOUND               - No descriptor for the desired space exists.

+  

+  EFI_SUCCESS                 - Space successfully allocated.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  AlignmentMask;

+  EFI_PHYSICAL_ADDRESS  MaxAddress;

+  LIST_ENTRY            *Map;

+  LIST_ENTRY            *Link;

+  LIST_ENTRY            *SubLink;

+  EFI_GCD_MAP_ENTRY     *Entry;

+  EFI_GCD_MAP_ENTRY     *TopEntry;

+  EFI_GCD_MAP_ENTRY     *BottomEntry;

+  LIST_ENTRY            *StartLink;

+  LIST_ENTRY            *EndLink;

+  BOOLEAN               Found;

+

+  //

+  // Make sure parameters are valid

+  //

+  if (GcdAllocateType < 0 || GcdAllocateType >= EfiGcdMaxAllocateType) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (GcdMemoryType < 0 || GcdMemoryType >= EfiGcdMemoryTypeMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (GcdIoType < 0 || GcdIoType >= EfiGcdIoTypeMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (BaseAddress == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (ImageHandle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (Alignment >= 64) {

+    return EFI_NOT_FOUND;

+  }

+  if (Length == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Map = NULL;

+  if (Operation & GCD_MEMORY_SPACE_OPERATION) {

+    CoreAcquireGcdMemoryLock ();

+    Map = &mGcdMemorySpaceMap;

+  }

+  if (Operation & GCD_IO_SPACE_OPERATION) {

+    CoreAcquireGcdIoLock ();

+    Map = &mGcdIoSpaceMap;

+  }

+

+  Found     = FALSE;

+  StartLink = NULL;

+  EndLink   = NULL;

+  //

+  // Compute alignment bit mask

+  //

+  AlignmentMask = LShiftU64 (1, Alignment) - 1;

+

+  if (GcdAllocateType == EfiGcdAllocateAddress) {

+    //

+    // Verify that the BaseAddress passed in is aligned correctly

+    //

+    if ((*BaseAddress & AlignmentMask) != 0) {

+      Status = EFI_NOT_FOUND;

+      goto Done;

+    }

+

+    //

+    // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length

+    //

+    Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);

+    if (EFI_ERROR (Status)) {

+      Status = EFI_NOT_FOUND;

+      goto Done;

+    }

+

+    //

+    // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.

+    //

+    Link = StartLink;

+    while (Link != EndLink->ForwardLink) {

+      Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+      Link = Link->ForwardLink;

+      Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);

+      if (EFI_ERROR (Status)) {

+        goto Done;

+      }

+    }

+    Found = TRUE;

+  } else {

+

+    Entry = CR (Map->BackLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+

+    //

+    // Compute the maximum address to use in the search algorithm

+    //

+    if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchBottomUp ||

+        GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown     ) {

+      MaxAddress = *BaseAddress - 1;

+    } else {

+      MaxAddress = Entry->EndAddress;

+    }

+

+    //

+    // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.

+    //

+    if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||

+        GcdAllocateType == EfiGcdAllocateAnySearchTopDown           ) {

+      Link = Map->BackLink;

+    } else {

+      Link = Map->ForwardLink;

+    }

+    while (Link != Map) {

+      Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+

+      if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||

+          GcdAllocateType == EfiGcdAllocateAnySearchTopDown           ) {

+        Link = Link->BackLink;

+      } else {

+        Link = Link->ForwardLink;

+      }

+

+      Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);

+      if (EFI_ERROR (Status)) {

+        continue;

+      }

+

+      if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||

+          GcdAllocateType == EfiGcdAllocateAnySearchTopDown           ) {

+        if ((Entry->BaseAddress + Length) > MaxAddress) {

+          continue;

+        }

+        if (Length > (Entry->EndAddress + 1)) {

+          Status = EFI_NOT_FOUND;

+          goto Done;

+        }

+        if (Entry->EndAddress > MaxAddress) {

+          *BaseAddress = MaxAddress;

+        } else {

+          *BaseAddress = Entry->EndAddress;

+        }

+        *BaseAddress = (*BaseAddress + 1 - Length) & (~AlignmentMask);

+      } else {

+        *BaseAddress = (Entry->BaseAddress + AlignmentMask) & (~AlignmentMask);

+        if ((*BaseAddress + Length - 1) > MaxAddress) {

+          Status = EFI_NOT_FOUND;

+          goto Done;

+        }

+      }

+

+      //

+      // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length

+      //

+      Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);

+      if (EFI_ERROR (Status)) {

+        Status = EFI_NOT_FOUND;

+        goto Done;

+      }

+

+      Link = StartLink;

+      //

+      // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.

+      //

+      Found = TRUE;

+      SubLink = StartLink;

+      while (SubLink != EndLink->ForwardLink) {

+        Entry = CR (SubLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+        Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);

+        if (EFI_ERROR (Status)) {

+          Link = SubLink;

+          Found = FALSE;

+          break;

+        }

+        SubLink = SubLink->ForwardLink;

+      }

+      if (Found) {

+        break;

+      }

+    }

+  }

+  if (!Found) {

+    Status = EFI_NOT_FOUND;

+    goto Done;

+  }

+

+  //

+  // Allocate work space to perform this operation

+  //

+  Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);

+  if (EFI_ERROR (Status)) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  //

+  // Convert/Insert the list of descriptors from StartLink to EndLink

+  //

+  Link = StartLink;

+  while (Link != EndLink->ForwardLink) {

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    CoreInsertGcdMapEntry (Link, Entry, *BaseAddress, Length, TopEntry, BottomEntry);

+    Entry->ImageHandle  = ImageHandle;

+    Entry->DeviceHandle = DeviceHandle;

+    Link = Link->ForwardLink;

+  }

+

+  //

+  // Cleanup

+  //

+  Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);

+

+Done:

+  if (Operation & GCD_MEMORY_SPACE_OPERATION) {

+    CoreReleaseGcdMemoryLock ();

+  }

+  if (Operation & GCD_IO_SPACE_OPERATION) {

+    CoreReleaseGcdIoLock ();

+  }

+

+  return Status;

+}

+

+

+EFI_STATUS

+CoreInternalAddMemorySpace (

+  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Capabilities

+  )

+/*++

+

+Routine Description:

+

+  Add a segment of memory to GCD map.

+

+Arguments:

+

+  GcdMemoryType     - Memory type of the segment.

+  

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+  Capabilities      - alterable attributes of the segment.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameters.

+  

+  EFI_SUCCESS                 - Successfully add a segment of memory space.

+

+--*/

+{

+  //

+  // Make sure parameters are valid

+  //

+  if (GcdMemoryType <= EfiGcdMemoryTypeNonExistent || GcdMemoryType >= EfiGcdMemoryTypeMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return CoreConvertSpace (GCD_ADD_MEMORY_OPERATION, GcdMemoryType, 0, BaseAddress, Length, Capabilities, 0);

+}

+

+//

+// GCD Core Services

+//

+EFI_STATUS

+CoreAllocateMemorySpace (

+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,

+  IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,

+  IN     UINTN                  Alignment,

+  IN     UINT64                 Length,

+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,

+  IN     EFI_HANDLE             ImageHandle,

+  IN     EFI_HANDLE             DeviceHandle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Allocates nonexistent memory, reserved memory, system memory, or memorymapped

+I/O resources from the global coherency domain of the processor.

+

+Arguments:

+

+  GcdAllocateType   - The type of allocate operation

+  

+  GcdMemoryType     - The desired memory type

+  

+  Alignment         - Align with 2^Alignment

+  

+  Length            - Length to allocate

+  

+  BaseAddress       - Base address to allocate

+  

+  ImageHandle       - The image handle consume the allocated space.

+  

+  DeviceHandle      - The device handle consume the allocated space.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter.

+  

+  EFI_NOT_FOUND               - No descriptor contains the desired space.

+  

+  EFI_SUCCESS                 - Memory space successfully allocated.

+

+--*/

+{

+  return CoreAllocateSpace (

+           GCD_ALLOCATE_MEMORY_OPERATION, 

+           GcdAllocateType, 

+           GcdMemoryType, 

+           0, 

+           Alignment, 

+           Length, 

+           BaseAddress, 

+           ImageHandle, 

+           DeviceHandle

+           );

+}

+

+EFI_STATUS

+CoreAddMemorySpace (

+  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Capabilities

+  )

+/*++

+

+Routine Description:

+

+  Adds reserved memory, system memory, or memory-mapped I/O resources to the

+global coherency domain of the processor.

+

+Arguments:

+

+  GcdMemoryType     - Memory type of the memory space.

+  

+  BaseAddress       - Base address of the memory space.

+  

+  Length            - Length of the memory space.

+  

+  Capabilities      - alterable attributes of the memory space.

+

+Returns:

+

+  EFI_SUCCESS       - Merged this memory space into GCD map.  

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  PageBaseAddress;

+  UINT64                PageLength;

+

+  Status = CoreInternalAddMemorySpace (GcdMemoryType, BaseAddress, Length, Capabilities);

+

+  if (!EFI_ERROR (Status) && GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {

+

+    PageBaseAddress = PageAlignLength (BaseAddress);

+    PageLength      = PageAlignLength (BaseAddress + Length - PageBaseAddress);

+

+    Status = CoreAllocateMemorySpace (

+               EfiGcdAllocateAddress,

+               GcdMemoryType,

+               EFI_PAGE_SHIFT,         

+               PageLength,

+               &PageBaseAddress,

+               gDxeCoreImageHandle,

+               NULL

+               );

+

+    if (!EFI_ERROR (Status)) {

+      CoreAddMemoryDescriptor (

+        EfiConventionalMemory,

+        PageBaseAddress,

+        RShiftU64 (PageLength, EFI_PAGE_SHIFT),

+        Capabilities

+        );

+    } else {

+      for (; PageLength != 0; PageLength -= EFI_PAGE_SIZE, PageBaseAddress += EFI_PAGE_SIZE) {

+        Status = CoreAllocateMemorySpace (

+                   EfiGcdAllocateAddress,

+                   GcdMemoryType,

+                   EFI_PAGE_SHIFT,         

+                   EFI_PAGE_SIZE,

+                   &PageBaseAddress,

+                   gDxeCoreImageHandle,

+                   NULL

+                   );

+

+        if (!EFI_ERROR (Status)) {

+          CoreAddMemoryDescriptor (

+            EfiConventionalMemory,

+            PageBaseAddress,

+            1,

+            Capabilities

+            );

+        }

+      }

+    }

+  }

+  return Status;

+}

+

+EFI_STATUS

+CoreFreeMemorySpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:

+

+  Frees nonexistent memory, reserved memory, system memory, or memory-mapped

+I/O resources from the global coherency domain of the processor.

+

+Arguments:

+

+  BaseAddress       - Base address of the memory space.

+  

+  Length            - Length of the memory space.

+  

+Returns:

+

+  EFI_SUCCESS       - Space successfully freed.

+

+--*/

+{

+  return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, 0);

+}

+

+EFI_STATUS

+CoreRemoveMemorySpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:

+

+  Removes reserved memory, system memory, or memory-mapped I/O resources from

+the global coherency domain of the processor.

+

+Arguments:

+

+  BaseAddress       - Base address of the memory space.

+  

+  Length            - Length of the memory space.

+  

+Returns:

+

+  EFI_SUCCESS       - Successfully remove a segment of memory space.

+

+--*/

+{

+  return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, 0);

+}

+

+VOID

+BuildMemoryDescriptor (

+  IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor,

+  IN EFI_GCD_MAP_ENTRY                *Entry

+  )

+/*++

+

+Routine Description:

+

+  Build a memory descriptor according to an entry.

+

+Arguments:

+

+  Descriptor          - The descriptor to be built

+  

+  Entry               - According to this entry

+

+Returns:

+

+  None

+

+--*/

+{

+  Descriptor->BaseAddress   = Entry->BaseAddress;

+  Descriptor->Length        = Entry->EndAddress - Entry->BaseAddress + 1;

+  Descriptor->Capabilities  = Entry->Capabilities;

+  Descriptor->Attributes    = Entry->Attributes;

+  Descriptor->GcdMemoryType = Entry->GcdMemoryType;

+  Descriptor->ImageHandle   = Entry->ImageHandle;

+  Descriptor->DeviceHandle  = Entry->DeviceHandle;

+}

+

+EFI_STATUS

+CoreGetMemorySpaceDescriptor (

+  IN  EFI_PHYSICAL_ADDRESS             BaseAddress,

+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the descriptor for a memory region containing a specified address.

+

+Arguments:

+

+  BaseAddress       - Specified start address

+  

+  Descriptor        - Specified length

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter

+  

+  EFI_SUCCESS                 - Successfully get memory space descriptor.

+

+--*/

+{

+  EFI_STATUS         Status;

+  LIST_ENTRY         *StartLink;

+  LIST_ENTRY         *EndLink;

+  EFI_GCD_MAP_ENTRY  *Entry;

+

+  //

+  // Make sure parameters are valid

+  //

+  if (Descriptor == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CoreAcquireGcdMemoryLock ();

+

+  //

+  // Search for the list of descriptors that contain BaseAddress 

+  //

+  Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap);

+  if (EFI_ERROR (Status)) {

+    Status = EFI_NOT_FOUND;

+  } else {

+    //

+    // Copy the contents of the found descriptor into Descriptor

+    //

+    Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    BuildMemoryDescriptor (Descriptor, Entry);

+  }

+

+  CoreReleaseGcdMemoryLock ();

+

+  return Status;

+}

+

+EFI_STATUS

+CoreSetMemorySpaceAttributes (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Attributes

+  )

+/*++

+

+Routine Description:

+

+  Modifies the attributes for a memory region in the global coherency domain of the

+processor.

+

+Arguments:

+

+  BaseAddress       - Specified start address

+  

+  Length            - Specified length

+  

+  Attributes        - Specified attributes

+

+Returns:

+

+  EFI_SUCCESS       - Successfully set attribute of a segment of memory space.

+

+--*/

+{

+  return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, Attributes);

+}

+

+EFI_STATUS

+CoreGetMemorySpaceMap (

+  OUT UINTN                            *NumberOfDescriptors,

+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  **MemorySpaceMap

+  )

+/*++

+

+Routine Description:

+

+  Returns a map of the memory resources in the global coherency domain of the

+processor.

+

+Arguments:

+

+  NumberOfDescriptors       - Number of descriptors.

+  

+  MemorySpaceMap            - Descriptor array

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Successfully get memory space map.

+

+--*/

+{

+  EFI_STATUS                       Status;

+  LIST_ENTRY                       *Link;

+  EFI_GCD_MAP_ENTRY                *Entry;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor;

+

+  //

+  // Make sure parameters are valid

+  //

+  if (NumberOfDescriptors == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (MemorySpaceMap == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CoreAcquireGcdMemoryLock ();

+

+  //

+  // Count the number of descriptors

+  //

+  *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdMemorySpaceMap);

+

+  //

+  // Allocate the MemorySpaceMap

+  //

+  *MemorySpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));

+  if (*MemorySpaceMap == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  //

+  // Fill in the MemorySpaceMap

+  //

+  Descriptor = *MemorySpaceMap;

+  Link = mGcdMemorySpaceMap.ForwardLink;

+  while (Link != &mGcdMemorySpaceMap) {

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    BuildMemoryDescriptor (Descriptor, Entry);

+    Descriptor++;

+    Link = Link->ForwardLink;

+  }

+  Status = EFI_SUCCESS;

+

+Done:

+  CoreReleaseGcdMemoryLock ();

+  return Status;

+}

+

+EFI_STATUS

+CoreAddIoSpace (

+  IN EFI_GCD_IO_TYPE       GcdIoType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:

+

+  Adds reserved I/O or I/O resources to the global coherency domain of the processor.

+

+Arguments:

+

+  GcdIoType         - IO type of the segment.

+  

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+

+Returns:

+

+  EFI_SUCCESS       - Merged this segment into GCD map.

+  EFI_INVALID_PARAMETER    - Parameter not valid

+

+--*/

+{

+  //

+  // Make sure parameters are valid

+  //

+  if (GcdIoType <= EfiGcdIoTypeNonExistent || GcdIoType >= EfiGcdIoTypeMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+  return CoreConvertSpace (GCD_ADD_IO_OPERATION, 0, GcdIoType, BaseAddress, Length, 0, 0);

+}

+

+EFI_STATUS

+CoreAllocateIoSpace (

+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,

+  IN     EFI_GCD_IO_TYPE        GcdIoType,

+  IN     UINTN                  Alignment,

+  IN     UINT64                 Length,

+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,

+  IN     EFI_HANDLE             ImageHandle,

+  IN     EFI_HANDLE             DeviceHandle OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency

+domain of the processor.

+

+Arguments:

+

+  GcdAllocateType   - The type of allocate operation

+  

+  GcdIoType         - The desired IO type

+  

+  Alignment         - Align with 2^Alignment

+  

+  Length            - Length to allocate

+  

+  BaseAddress       - Base address to allocate

+  

+  ImageHandle       - The image handle consume the allocated space.

+  

+  DeviceHandle      - The device handle consume the allocated space.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter.

+  

+  EFI_NOT_FOUND               - No descriptor contains the desired space.

+  

+  EFI_SUCCESS                 - IO space successfully allocated.

+

+--*/

+{

+  return CoreAllocateSpace (

+           GCD_ALLOCATE_IO_OPERATION, 

+           GcdAllocateType, 

+           0, 

+           GcdIoType, 

+           Alignment, 

+           Length, 

+           BaseAddress, 

+           ImageHandle, 

+           DeviceHandle

+           );

+}

+

+EFI_STATUS

+CoreFreeIoSpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:

+

+  Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency

+domain of the processor.

+

+Arguments:

+

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+Returns:

+

+  EFI_SUCCESS       - Space successfully freed.

+

+--*/

+{

+  return CoreConvertSpace (GCD_FREE_IO_OPERATION, 0, 0, BaseAddress, Length, 0, 0);

+}

+

+EFI_STATUS

+CoreRemoveIoSpace (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+/*++

+

+Routine Description:

+

+  Removes reserved I/O or I/O resources from the global coherency domain of the

+processor.

+

+Arguments:

+

+  BaseAddress       - Base address of the segment.

+  

+  Length            - Length of the segment.

+  

+Returns:

+

+  EFI_SUCCESS       - Successfully removed a segment of IO space.

+

+--*/

+{

+  return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, 0, 0, BaseAddress, Length, 0, 0);

+}

+

+VOID

+BuildIoDescriptor (

+  IN EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor,

+  IN EFI_GCD_MAP_ENTRY            *Entry

+  )

+/*++

+

+Routine Description:

+

+  Build a IO descriptor according to an entry.

+

+Arguments:

+

+  Descriptor          - The descriptor to be built

+  

+  Entry               - According to this entry

+

+Returns:

+

+  None

+

+--*/

+{

+  Descriptor->BaseAddress  = Entry->BaseAddress;

+  Descriptor->Length       = Entry->EndAddress - Entry->BaseAddress + 1;

+  Descriptor->GcdIoType    = Entry->GcdIoType;

+  Descriptor->ImageHandle  = Entry->ImageHandle;

+  Descriptor->DeviceHandle = Entry->DeviceHandle;

+}

+

+EFI_STATUS

+CoreGetIoSpaceDescriptor (

+  IN  EFI_PHYSICAL_ADDRESS         BaseAddress,

+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the descriptor for an I/O region containing a specified address.

+

+Arguments:

+

+  BaseAddress       - Specified start address

+  

+  Descriptor        - Specified length

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Descriptor is NULL.

+  

+  EFI_SUCCESS                 - Successfully get the IO space descriptor.

+

+--*/

+{

+  EFI_STATUS         Status;

+  LIST_ENTRY         *StartLink;

+  LIST_ENTRY         *EndLink;

+  EFI_GCD_MAP_ENTRY  *Entry;

+

+  //

+  // Make sure parameters are valid

+  //

+  if (Descriptor == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CoreAcquireGcdIoLock ();

+

+  //

+  // Search for the list of descriptors that contain BaseAddress 

+  //

+  Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap);

+  if (EFI_ERROR (Status)) {

+    Status = EFI_NOT_FOUND;

+  } else {

+    //

+    // Copy the contents of the found descriptor into Descriptor

+    //

+    Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    BuildIoDescriptor (Descriptor, Entry);

+  }

+

+  CoreReleaseGcdIoLock ();

+

+  return Status;

+}

+

+EFI_STATUS

+CoreGetIoSpaceMap (

+  OUT UINTN                        *NumberOfDescriptors,

+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  **IoSpaceMap

+  )

+/*++

+

+Routine Description:

+

+  Returns a map of the I/O resources in the global coherency domain of the processor.

+

+Arguments:

+

+  NumberOfDescriptors       - Number of descriptors.

+  

+  IoSpaceMap                - Descriptor array

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Successfully get IO space map.

+

+--*/

+{

+  EFI_STATUS                   Status;

+  LIST_ENTRY                   *Link;

+  EFI_GCD_MAP_ENTRY            *Entry;

+  EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor;

+

+  //

+  // Make sure parameters are valid

+  //

+  if (NumberOfDescriptors == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (IoSpaceMap == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CoreAcquireGcdIoLock ();

+

+  //

+  // Count the number of descriptors

+  //

+  *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdIoSpaceMap);

+

+  //

+  // Allocate the IoSpaceMap

+  //

+  *IoSpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));

+  if (*IoSpaceMap == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  //

+  // Fill in the IoSpaceMap

+  //

+  Descriptor = *IoSpaceMap;

+  Link = mGcdIoSpaceMap.ForwardLink;

+  while (Link != &mGcdIoSpaceMap) {

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    BuildIoDescriptor (Descriptor, Entry);

+    Descriptor++;

+    Link = Link->ForwardLink;

+  }

+  Status = EFI_SUCCESS;

+

+Done:

+  CoreReleaseGcdIoLock ();

+  return Status;

+}  

+

+UINT64

+CoreConvertResourceDescriptorHobAttributesToCapabilities (

+  EFI_GCD_MEMORY_TYPE  GcdMemoryType,

+  UINT64               Attributes

+  )

+/*++

+

+Routine Description:

+

+  Converts a Resource Descriptor HOB attributes mask to an EFI Memory Descriptor 

+  capabilities mask

+

+Arguments:

+

+  GcdMemoryType   - Type of resource in the GCD memory map.

+  Attributes      - The attribute mask in the Resource Descriptor HOB.

+

+Returns:

+

+  The capabilities mask for an EFI Memory Descriptor.

+

+--*/

+{

+  UINT64                          Capabilities;

+  GCD_ATTRIBUTE_CONVERSION_ENTRY  *Conversion;

+  

+  //

+  // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask

+  //

+  for (Capabilities = 0, Conversion = mAttributeConversionTable; Conversion->Attribute != 0; Conversion++) {

+    if (Conversion->Memory || (GcdMemoryType != EfiGcdMemoryTypeSystemMemory)) {

+      if (Attributes & Conversion->Attribute) {

+        Capabilities |= Conversion->Capability;

+      }

+    }

+  }

+  

+  return Capabilities;

+}

+

+EFI_STATUS

+CoreInitializeMemoryServices (

+  IN  VOID                  **HobStart,

+  OUT EFI_PHYSICAL_ADDRESS  *MemoryBaseAddress,

+  OUT UINT64                *MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  External function. Initializes the GCD and memory services based on the memory 

+  descriptor HOBs.  This function is responsible for priming the GCD map and the

+  memory map, so memory allocations and resource allocations can be made.  The first

+  part of this function can not depend on any memory services until at least one

+  memory descriptor is provided to the memory services.  Then the memory services

+  can be used to intialize the GCD map.

+

+Arguments:

+

+  HobStart            - The start address of the HOB.

+  MemoryBaseAddress   - Start address of memory region found to init DXE core.

+  MemoryLength        - Length of memory region found to init DXE core.

+

+Returns:

+

+  EFI_SUCCESS   - Memory services successfully initialized.

+

+--*/

+{

+  EFI_PEI_HOB_POINTERS               Hob;

+  EFI_MEMORY_TYPE_INFORMATION        *EfiMemoryTypeInformation;

+  UINTN                              DataSize;

+  BOOLEAN                            Found;

+  EFI_HOB_HANDOFF_INFO_TABLE         *PhitHob;

+  EFI_HOB_RESOURCE_DESCRIPTOR        *ResourceHob;

+  EFI_HOB_RESOURCE_DESCRIPTOR        *PhitResourceHob;

+  EFI_PHYSICAL_ADDRESS               BaseAddress;

+  UINT64                             Length;

+  UINT64                             Attributes;

+  UINT64                             Capabilities;

+  EFI_PHYSICAL_ADDRESS               MaxMemoryBaseAddress;

+  UINT64                             MaxMemoryLength;

+  UINT64                             MaxMemoryAttributes;

+  EFI_PHYSICAL_ADDRESS               MaxAddress;

+  EFI_PHYSICAL_ADDRESS               HighAddress;

+  EFI_HOB_RESOURCE_DESCRIPTOR        *MaxResourceHob;

+  EFI_HOB_GUID_TYPE                  *GuidHob;

+

+  //

+  // Point at the first HOB.  This must be the PHIT HOB.

+  //

+  Hob.Raw = *HobStart;

+  ASSERT (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_HANDOFF);

+

+  //

+  // Initialize the spin locks and maps in the memory services.

+  // Also fill in the memory services into the EFI Boot Services Table

+  //

+  CoreInitializePool ();

+

+  //

+  // Initialize Local Variables

+  //

+  PhitResourceHob       = NULL;

+  MaxResourceHob        = NULL;

+  ResourceHob           = NULL;

+  BaseAddress           = 0;

+  Length                = 0;

+  Attributes            = 0;

+  MaxMemoryBaseAddress  = 0;

+  MaxMemoryLength       = 0;

+  MaxMemoryAttributes   = 0;

+

+  //

+  // Cache the PHIT HOB for later use

+  //

+  PhitHob = Hob.HandoffInformationTable;

+

+  //

+  // See if a Memory Type Information HOB is available

+  //

+  GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);

+  if (GuidHob != NULL) {

+    EfiMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);

+    DataSize                 = GET_GUID_HOB_DATA_SIZE (GuidHob);

+    if (EfiMemoryTypeInformation != NULL && DataSize > 0 && DataSize < EfiMaxMemoryType * sizeof (EFI_MEMORY_TYPE_INFORMATION)) {

+      CopyMem (&gMemoryTypeInformation, EfiMemoryTypeInformation, DataSize);

+    }

+  }

+

+  //

+  // Find the Resource Descriptor HOB that contains range FreeMemoryBaseAddress..FreeMemoryLength

+  //

+  Length = 0;

+  Found  = FALSE;

+  for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {

+

+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

+

+      ResourceHob = Hob.ResourceDescriptor;

+

+      if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY                                       &&

+          (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES    ) {

+

+        if (PhitHob->EfiFreeMemoryBottom >= ResourceHob->PhysicalStart                         && 

+            PhitHob->EfiFreeMemoryTop    <= (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)    ) {

+

+          //

+          // Cache the resource descriptor HOB for the memory region described by the PHIT HOB

+          //

+          PhitResourceHob = ResourceHob;

+          Found = TRUE;

+

+          Attributes  = PhitResourceHob->ResourceAttribute;

+          BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);

+          Length      = PageAlignLength  (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);

+          if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {

+            BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);

+            Length      = PageAlignLength  (PhitHob->EfiFreeMemoryTop - BaseAddress);

+            if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {

+              BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);

+              Length      = PageAlignLength  ((UINT64)((UINTN)*HobStart - BaseAddress));

+            }

+          }

+          break;

+        }

+      }

+    }

+  }

+

+  //

+  // Assert if a resource descriptor HOB for the memory region described by the PHIT was not found

+  //

+  ASSERT (Found);

+

+  //

+  // Search all the resource descriptor HOBs from the highest possible addresses down for a memory

+  // region that is big enough to initialize the DXE core.  Always skip the PHIT Resource HOB.

+  // The max address must be within the physically addressible range for the processor.

+  //

+  MaxMemoryLength = 0;

+  MaxAddress      = EFI_MAX_ADDRESS;

+  do {

+    HighAddress = 0;

+    Found       = FALSE;

+    //

+    // Search for a tested memory region that is below MaxAddress

+    //

+    for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {

+

+      //

+      // See if this is a resource descriptor HOB that does not contain the PHIT.

+      //

+      if (Hob.ResourceDescriptor != PhitResourceHob && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

+

+        ResourceHob = Hob.ResourceDescriptor;

+        //

+        // See if this resource descrior HOB describes tested system memory below MaxAddress

+        //

+        if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY                                       &&

+            (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES &&

+            ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MaxAddress                            ) {

+

+          //

+          // See if this is the highest tested system memory region below MaxAddress

+          //

+          if (ResourceHob->PhysicalStart > HighAddress) {

+

+            MaxResourceHob = ResourceHob;

+            HighAddress = MaxResourceHob->PhysicalStart;

+            Found = TRUE;

+          }

+        }

+      }

+    }

+    if (Found) {

+      //

+      // Compute the size of the tested memory region below MaxAddrees

+      //

+      MaxMemoryBaseAddress = PageAlignAddress (MaxResourceHob->PhysicalStart);

+      MaxMemoryLength      = PageAlignLength  (MaxResourceHob->PhysicalStart + MaxResourceHob->ResourceLength - MaxMemoryBaseAddress);

+      MaxMemoryAttributes  = MaxResourceHob->ResourceAttribute;

+    }

+    MaxAddress = ResourceHob->PhysicalStart;

+  } while (Found && MaxMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE);

+

+  //

+  //

+  //

+  if ((Length < MINIMUM_INITIAL_MEMORY_SIZE)                                                 ||

+      (MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE)    ) {

+    BaseAddress = MaxMemoryBaseAddress;

+    Length      = MaxMemoryLength;

+    Attributes  = MaxMemoryAttributes;

+  }

+

+  //

+  // If no memory regions are found that are big enough to initialize the DXE core, then ASSERT().

+  //

+  ASSERT (Length >= MINIMUM_INITIAL_MEMORY_SIZE);

+

+  //

+  // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask

+  //

+  Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeSystemMemory, Attributes);

+

+  //

+  // Declare the very first memory region, so the EFI Memory Services are available.

+  //

+  CoreAddMemoryDescriptor (

+    EfiConventionalMemory,

+    BaseAddress,

+    RShiftU64 (Length, EFI_PAGE_SHIFT),

+    Capabilities

+    );

+

+  *MemoryBaseAddress = BaseAddress;

+  *MemoryLength      = Length;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreInitializeGcdServices (

+  IN VOID                  **HobStart,

+  IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,

+  IN UINT64                MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  External function. Initializes the GCD and memory services based on the memory 

+  descriptor HOBs.  This function is responsible for priming the GCD map and the

+  memory map, so memory allocations and resource allocations can be made.  The first

+  part of this function can not depend on any memory services until at least one

+  memory descriptor is provided to the memory services.  Then the memory services

+  can be used to intialize the GCD map.

+

+Arguments:

+

+  HobStart - The start address of the HOB

+

+  MemoryBaseAddress   - Start address of memory region found to init DXE core.

+  

+  MemoryLength        - Length of memory region found to init DXE core.

+

+

+Returns:

+

+  EFI_SUCCESS         - GCD services successfully initialized.

+

+--*/

+{

+  EFI_PEI_HOB_POINTERS                   Hob;

+  VOID                               *NewHobList;

+  EFI_HOB_HANDOFF_INFO_TABLE  *PhitHob;

+  UINT8                              SizeOfMemorySpace;

+  UINT8                              SizeOfIoSpace;

+  EFI_HOB_RESOURCE_DESCRIPTOR        *ResourceHob;

+  EFI_PHYSICAL_ADDRESS               BaseAddress;

+  UINT64                             Length;

+  EFI_STATUS                         Status;

+  EFI_GCD_MAP_ENTRY                  *Entry;

+  EFI_GCD_MEMORY_TYPE                GcdMemoryType;

+  EFI_GCD_IO_TYPE                    GcdIoType;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR    Descriptor;

+  EFI_HOB_MEMORY_ALLOCATION          *MemoryHob;

+  EFI_HOB_FIRMWARE_VOLUME            *FirmwareVolumeHob;

+  UINTN                              NumberOfDescriptors;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap;

+  UINTN                              Index;

+  UINT64                             Capabilities;

+  EFI_HOB_CPU *                      CpuHob;

+  //

+  // Cache the PHIT HOB for later use

+  //

+  PhitHob = (EFI_HOB_HANDOFF_INFO_TABLE *)(*HobStart);

+

+  //

+  // Get the number of address lines in the I/O and Memory space for the CPU

+  //

+  CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU);

+  ASSERT (CpuHob != NULL);

+  SizeOfMemorySpace = CpuHob->SizeOfMemorySpace;

+  SizeOfIoSpace     = CpuHob->SizeOfIoSpace;

+ 

+  //

+  // Initialize the GCD Memory Space Map

+  //

+  Entry = CoreAllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate);

+  ASSERT (Entry != NULL);

+

+  Entry->EndAddress = LShiftU64 (1, SizeOfMemorySpace) - 1;

+

+  InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link);

+

+  //

+  // Initialize the GCD I/O Space Map

+  //

+  Entry = CoreAllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate);

+  ASSERT (Entry != NULL);

+

+  Entry->EndAddress = LShiftU64 (1, SizeOfIoSpace) - 1;

+

+  InsertHeadList (&mGcdIoSpaceMap, &Entry->Link);

+

+  //

+  // Walk the HOB list and add all resource descriptors to the GCD 

+  //

+  for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {

+

+    GcdMemoryType = EfiGcdMemoryTypeNonExistent;

+    GcdIoType     = EfiGcdIoTypeNonExistent;

+

+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

+

+      ResourceHob = Hob.ResourceDescriptor;

+

+      switch (ResourceHob->ResourceType) {

+      case EFI_RESOURCE_SYSTEM_MEMORY:

+        if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {

+          GcdMemoryType = EfiGcdMemoryTypeSystemMemory;

+        }

+        if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {

+          GcdMemoryType = EfiGcdMemoryTypeReserved;

+        }

+        if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {

+          GcdMemoryType = EfiGcdMemoryTypeReserved;

+        }

+        break;

+      case EFI_RESOURCE_MEMORY_MAPPED_IO:

+      case EFI_RESOURCE_FIRMWARE_DEVICE:

+        GcdMemoryType = EfiGcdMemoryTypeMemoryMappedIo;

+        break;

+      case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:

+      case EFI_RESOURCE_MEMORY_RESERVED:

+        GcdMemoryType = EfiGcdMemoryTypeReserved;

+        break;

+      case EFI_RESOURCE_IO:

+        GcdIoType = EfiGcdIoTypeIo;

+        break;

+      case EFI_RESOURCE_IO_RESERVED:

+        GcdIoType = EfiGcdIoTypeReserved;

+        break;

+      }

+

+      if (GcdMemoryType != EfiGcdMemoryTypeNonExistent) {

+

+        //

+        // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask

+        //

+        Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (

+                         GcdMemoryType,

+                         ResourceHob->ResourceAttribute

+                         );

+

+        Status = CoreInternalAddMemorySpace (

+                   GcdMemoryType,

+                   ResourceHob->PhysicalStart,

+                   ResourceHob->ResourceLength,

+                   Capabilities

+                   );

+      }

+

+      if (GcdIoType != EfiGcdIoTypeNonExistent) {

+        Status = CoreAddIoSpace (

+                   GcdIoType,

+                   ResourceHob->PhysicalStart,

+                   ResourceHob->ResourceLength

+                   );

+      }

+    }

+  }

+

+  //

+  // Allocate first memory region from the GCD by the DXE core

+  //

+  Status = CoreAllocateMemorySpace (

+             EfiGcdAllocateAddress,

+             EfiGcdMemoryTypeSystemMemory,

+             0,

+             MemoryLength,

+             &MemoryBaseAddress,

+             gDxeCoreImageHandle,

+             NULL

+             );

+

+  //

+  // Walk the HOB list and allocate all memory space that is consumed by memory allocation HOBs,

+  // and Firmware Volume HOBs.  Also update the EFI Memory Map with the memory allocation HOBs.

+  //

+  for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {

+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {

+      MemoryHob = Hob.MemoryAllocation;

+      BaseAddress = MemoryHob->AllocDescriptor.MemoryBaseAddress;

+      Status = CoreAllocateMemorySpace (

+                 EfiGcdAllocateAddress,

+                 EfiGcdMemoryTypeSystemMemory, 

+                 0,

+                 MemoryHob->AllocDescriptor.MemoryLength,

+                 &BaseAddress,

+                 gDxeCoreImageHandle,

+                 NULL

+                 );

+      if (!EFI_ERROR (Status)) {

+        Status = CoreGetMemorySpaceDescriptor (MemoryHob->AllocDescriptor.MemoryBaseAddress, &Descriptor);

+        if (!EFI_ERROR (Status)) {

+          CoreAddMemoryDescriptor (

+            MemoryHob->AllocDescriptor.MemoryType,

+            MemoryHob->AllocDescriptor.MemoryBaseAddress,

+            RShiftU64 (MemoryHob->AllocDescriptor.MemoryLength, EFI_PAGE_SHIFT),

+            Descriptor.Capabilities & (~EFI_MEMORY_RUNTIME)

+            );

+        }

+      }

+    }

+

+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {

+      FirmwareVolumeHob = Hob.FirmwareVolume;

+      BaseAddress = FirmwareVolumeHob->BaseAddress;

+      Status = CoreAllocateMemorySpace (

+                 EfiGcdAllocateAddress,

+                 EfiGcdMemoryTypeMemoryMappedIo, 

+                 0,

+                 FirmwareVolumeHob->Length,

+                 &BaseAddress,

+                 gDxeCoreImageHandle,

+                 NULL

+                 );

+    }

+  }

+

+  //

+  // Relocate HOB List to an allocated pool buffer.

+  //

+  NewHobList = CoreAllocateCopyPool (

+                 (UINTN)PhitHob->EfiFreeMemoryBottom - (UINTN)(*HobStart), 

+                 *HobStart

+                 );

+  ASSERT (NewHobList != NULL);

+

+  *HobStart = NewHobList;

+

+  //

+  // Add and allocate the remaining unallocated system memory to the memory services.

+  //

+  Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);

+  for (Index = 0; Index < NumberOfDescriptors; Index++) {

+    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {

+      if (MemorySpaceMap[Index].ImageHandle == NULL) {

+        BaseAddress  = PageAlignAddress (MemorySpaceMap[Index].BaseAddress);

+        Length       = PageAlignLength  (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - BaseAddress);

+        CoreAddMemoryDescriptor (

+          EfiConventionalMemory,

+          BaseAddress,

+          RShiftU64 (Length, EFI_PAGE_SHIFT),

+          MemorySpaceMap[Index].Capabilities & (~EFI_MEMORY_RUNTIME)

+          );

+        Status = CoreAllocateMemorySpace (

+                   EfiGcdAllocateAddress,

+                   EfiGcdMemoryTypeSystemMemory,

+                   0,

+                   Length,

+                   &BaseAddress,

+                   gDxeCoreImageHandle,

+                   NULL

+                   );

+      }

+    }

+  }

+  CoreFreePool (MemorySpaceMap);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Hand/DriverSupport.c b/edk2/EdkModulePkg/Core/Dxe/Hand/DriverSupport.c
new file mode 100644
index 0000000..aa601fba
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Hand/DriverSupport.c
@@ -0,0 +1,848 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    DriverSupport.c

+    

+Abstract:

+

+    EFI Driver Support Protocol

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+

+

+STATIC

+EFI_STATUS

+GetHandleFromDriverBinding (

+  IN EFI_DRIVER_BINDING_PROTOCOL           *DriverBindingNeed,

+  OUT  EFI_HANDLE                          *Handle 

+  );

+

+

+//

+// Driver Support Function Prototypes

+//

+STATIC

+EFI_STATUS 

+CoreConnectSingleController (

+  IN  EFI_HANDLE                ControllerHandle,

+  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL

+  );

+

+//

+// Driver Support Functions

+//

+

+

+EFI_STATUS 

+EFIAPI

+CoreConnectController (

+  IN  EFI_HANDLE                ControllerHandle,

+  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL,

+  IN  BOOLEAN                   Recursive

+  )

+/*++

+

+Routine Description:

+

+  Connects one or more drivers to a controller.

+

+Arguments:

+

+  ControllerHandle            - Handle of the controller to be connected.

+

+  DriverImageHandle           - DriverImageHandle A pointer to an ordered list of driver image handles.

+

+  RemainingDevicePath         - RemainingDevicePath A pointer to the device path that specifies a child of the

+                                controller specified by ControllerHandle.

+    

+  Recursive                   - Whether the function would be called recursively or not.

+

+Returns:

+

+  Status code.

+

+--*/

+{

+  EFI_STATUS                           Status;

+  EFI_STATUS                           ReturnStatus;

+  IHANDLE                              *Handle;

+  PROTOCOL_INTERFACE                   *Prot;

+  LIST_ENTRY                           *Link;

+  LIST_ENTRY                           *ProtLink;

+  OPEN_PROTOCOL_DATA                   *OpenData;

+  EFI_DEVICE_PATH_PROTOCOL             *AlignedRemainingDevicePath;

+  

+  //

+  // Make sure ControllerHandle is valid

+  //

+  Status = CoreValidateHandle (ControllerHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Handle = ControllerHandle;

+

+  //

+  // Connect all drivers to ControllerHandle 

+  //

+  AlignedRemainingDevicePath = NULL;

+  if (RemainingDevicePath != NULL) {

+    AlignedRemainingDevicePath = CoreDuplicateDevicePath (RemainingDevicePath);

+  }

+  ReturnStatus = CoreConnectSingleController (

+                   ControllerHandle,

+                   DriverImageHandle,

+                   AlignedRemainingDevicePath

+                   );

+  if (AlignedRemainingDevicePath != NULL) {

+    CoreFreePool (AlignedRemainingDevicePath);

+  }

+

+  //

+  // If not recursive, then just return after connecting drivers to ControllerHandle

+  //

+  if (!Recursive) {

+    return ReturnStatus;

+  }

+

+  //

+  // If recursive, then connect all drivers to all of ControllerHandle's children

+  //

+  CoreAcquireProtocolLock ();

+  for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+    Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+    for (ProtLink = Prot->OpenList.ForwardLink; 

+           ProtLink != &Prot->OpenList; 

+           ProtLink = ProtLink->ForwardLink) {

+        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {

+          CoreReleaseProtocolLock ();

+          Status = CoreConnectController (

+                          OpenData->ControllerHandle,

+                          NULL,

+                          NULL,

+                          TRUE

+                          ); 

+          CoreAcquireProtocolLock ();

+        }

+    }

+  }

+  CoreReleaseProtocolLock ();

+  

+  return ReturnStatus;

+}

+

+VOID

+AddSortedDriverBindingProtocol (

+  IN      EFI_HANDLE                   DriverBindingHandle,

+  IN OUT  UINTN                        *NumberOfSortedDriverBindingProtocols, 

+  IN OUT  EFI_DRIVER_BINDING_PROTOCOL  **SortedDriverBindingProtocols,

+  IN      UINTN                        DriverBindingHandleCount,

+  IN OUT  EFI_HANDLE                   *DriverBindingHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  Add Driver Binding Protocols from Context Driver Image Handles to sorted 

+   Driver Binding Protocol list.

+

+Arguments:

+

+  DriverBindingHandle - Handle of the driver binding protocol.

+

+  NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols

+

+  SortedDriverBindingProtocols - The sorted protocol list.                        

+    

+  DriverBindingHandleCount - Driver Binding Handle Count.

+

+  DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.

+

+Returns:

+

+  None.

+

+--*/

+{

+  EFI_STATUS                   Status;

+  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;

+  UINTN                        Index;

+

+  //

+  // Make sure the DriverBindingHandle is valid

+  //

+  Status = CoreValidateHandle (DriverBindingHandle);

+  if (EFI_ERROR (Status)) {

+    return;

+  }

+

+  //

+  // Retrieve the Driver Binding Protocol from DriverBindingHandle

+  //

+  Status = CoreHandleProtocol(

+             DriverBindingHandle,

+             &gEfiDriverBindingProtocolGuid,

+             (VOID **)&DriverBinding

+             );

+  //

+  // If DriverBindingHandle does not support the Driver Binding Protocol then return

+  //

+  if (EFI_ERROR (Status) || DriverBinding == NULL) {

+    return;

+  }

+

+  //

+  // See if DriverBinding is already in the sorted list

+  //

+  for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols; Index++) {

+    if (DriverBinding == SortedDriverBindingProtocols[Index]) {

+      return;

+    }

+  }

+

+  //

+  // Add DriverBinding to the end of the list

+  //

+  SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;

+  *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;

+

+  //

+  // Mark the cooresponding handle in DriverBindingHandleBuffer as used

+  //

+  for (Index = 0; Index < DriverBindingHandleCount; Index++) {

+    if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {

+      DriverBindingHandleBuffer[Index] = NULL;

+    }

+  }

+}

+ 

+STATIC

+EFI_STATUS 

+CoreConnectSingleController (

+  IN  EFI_HANDLE                ControllerHandle,

+  IN  EFI_HANDLE                *ContextDriverImageHandles OPTIONAL,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath       OPTIONAL     

+  )

+/*++

+

+Routine Description:

+

+  Connects a controller to a driver.

+

+Arguments:

+

+  ControllerHandle            - Handle of the controller to be connected.

+  ContextDriverImageHandles   - DriverImageHandle A pointer to an ordered list of driver image handles.

+  RemainingDevicePath         - RemainingDevicePath A pointer to the device path that specifies a child 

+                                of the controller specified by ControllerHandle.

+    

+Returns:

+

+  EFI_SUCCESS           - One or more drivers were connected to ControllerHandle.

+  EFI_OUT_OF_RESOURCES  - No enough system resources to complete the request.

+  EFI_NOT_FOUND         - No drivers were connected to ControllerHandle.

+

+--*/

+{

+  EFI_STATUS                                 Status;

+  UINTN                                      Index;

+  EFI_HANDLE                                 DriverImageHandle;

+  UINTN                                      PlatformDriverOverrideHandleCount;

+  EFI_HANDLE                                 *PlatformDriverOverrideHandleBuffer;

+  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL      *PlatformDriverOverride;

+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  *BusSpecificDriverOverride;

+  UINTN                                      DriverBindingHandleCount;

+  EFI_HANDLE                                 *DriverBindingHandleBuffer;

+  EFI_DRIVER_BINDING_PROTOCOL                *DriverBinding;

+  UINTN                                      NumberOfSortedDriverBindingProtocols;

+  EFI_DRIVER_BINDING_PROTOCOL                **SortedDriverBindingProtocols;

+  UINT32                                     HighestVersion;

+  UINTN                                      HighestIndex;

+  UINTN                                      SortIndex;

+  BOOLEAN                                    OneStarted;

+  BOOLEAN                                    DriverFound;

+  EFI_HANDLE                                 DriverBindingHandle;

+

+  //

+  // DriverBindingHandle is used for performance measurement, initialize it here just in case.

+  //

+  DriverBindingHandle                   = NULL;

+  //

+  // Initialize local variables

+  //

+  DriverBindingHandleCount              = 0;

+  DriverBindingHandleBuffer             = NULL;

+  PlatformDriverOverrideHandleCount     = 0;

+  PlatformDriverOverrideHandleBuffer    = NULL;

+  NumberOfSortedDriverBindingProtocols  = 0;

+  SortedDriverBindingProtocols          = NULL;

+

+  //

+  // Get list of all Driver Binding Protocol Instances

+  //

+  Status = CoreLocateHandleBuffer (

+             ByProtocol,   

+             &gEfiDriverBindingProtocolGuid,  

+             NULL,

+             &DriverBindingHandleCount, 

+             &DriverBindingHandleBuffer

+             );

+  if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Allocate a duplicate array for the sorted Driver Binding Protocol Instances

+  //

+  SortedDriverBindingProtocols = CoreAllocateBootServicesPool (sizeof (VOID *) * DriverBindingHandleCount);

+  if (SortedDriverBindingProtocols == NULL) {

+    CoreFreePool (DriverBindingHandleBuffer);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Add Driver Binding Protocols from Context Driver Image Handles first

+  //

+  if (ContextDriverImageHandles != NULL) {

+    for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {

+      AddSortedDriverBindingProtocol (

+        ContextDriverImageHandles[Index],

+        &NumberOfSortedDriverBindingProtocols, 

+        SortedDriverBindingProtocols,

+        DriverBindingHandleCount,

+        DriverBindingHandleBuffer

+        );

+    }

+  }

+

+  //

+  // Add the Platform Driver Override Protocol drivers for ControllerHandle next

+  //

+  Status = CoreLocateProtocol (

+             &gEfiPlatformDriverOverrideProtocolGuid, 

+             NULL, 

+             (VOID **)&PlatformDriverOverride

+             );

+  if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {

+    DriverImageHandle = NULL;

+    do {

+      Status = PlatformDriverOverride->GetDriver (

+                                         PlatformDriverOverride,

+                                         ControllerHandle,

+                                         &DriverImageHandle

+                                         );

+      if (!EFI_ERROR (Status)) {

+        AddSortedDriverBindingProtocol (

+          DriverImageHandle,

+          &NumberOfSortedDriverBindingProtocols, 

+          SortedDriverBindingProtocols,

+          DriverBindingHandleCount,

+          DriverBindingHandleBuffer

+          );

+      }

+    } while (!EFI_ERROR (Status));

+  }

+

+  //

+  // Get the Bus Specific Driver Override Protocol instance on the Controller Handle

+  //

+  Status = CoreHandleProtocol(

+             ControllerHandle,  

+             &gEfiBusSpecificDriverOverrideProtocolGuid, 

+             (VOID **)&BusSpecificDriverOverride

+             );

+  if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {

+    DriverImageHandle = NULL;

+    do {

+      Status = BusSpecificDriverOverride->GetDriver (

+                                            BusSpecificDriverOverride,

+                                            &DriverImageHandle

+                                            );

+      if (!EFI_ERROR (Status)) {

+        AddSortedDriverBindingProtocol (

+          DriverImageHandle,

+          &NumberOfSortedDriverBindingProtocols, 

+          SortedDriverBindingProtocols,

+          DriverBindingHandleCount,

+          DriverBindingHandleBuffer

+          );

+      }

+    } while (!EFI_ERROR (Status));

+  }

+

+  //

+  // Then add all the remaining Driver Binding Protocols

+  //

+  SortIndex = NumberOfSortedDriverBindingProtocols;

+  for (Index = 0; Index < DriverBindingHandleCount; Index++) {

+    AddSortedDriverBindingProtocol (

+      DriverBindingHandleBuffer[Index],

+      &NumberOfSortedDriverBindingProtocols, 

+      SortedDriverBindingProtocols,

+      DriverBindingHandleCount,

+      DriverBindingHandleBuffer

+      );

+  }

+

+  //

+  // Free the Driver Binding Handle Buffer

+  //

+  CoreFreePool (DriverBindingHandleBuffer);

+

+  //

+  // Sort the remaining DriverBinding Protocol based on their Version field from

+  // highest to lowest.

+  //

+  for ( ; SortIndex < DriverBindingHandleCount; SortIndex++) {

+    HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;

+    HighestIndex   = SortIndex;

+    for (Index = SortIndex + 1; Index < DriverBindingHandleCount; Index++) {

+      if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {

+        HighestVersion = SortedDriverBindingProtocols[Index]->Version;

+        HighestIndex   = Index;

+      }

+    }

+    if (SortIndex != HighestIndex) {

+      DriverBinding = SortedDriverBindingProtocols[SortIndex];

+      SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];

+      SortedDriverBindingProtocols[HighestIndex] = DriverBinding;

+    }

+  }

+

+  //

+  // Loop until no more drivers can be started on ControllerHandle

+  //

+  OneStarted = FALSE;

+  do {

+

+    //

+    // Loop through the sorted Driver Binding Protocol Instances in order, and see if

+    // any of the Driver Binding Protocols support the controller specified by 

+    // ControllerHandle.

+    //

+    DriverBinding = NULL;

+    DriverFound = FALSE;

+    for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {

+      if (SortedDriverBindingProtocols[Index] != NULL) {

+        DriverBinding = SortedDriverBindingProtocols[Index];

+        Status = DriverBinding->Supported(

+                                  DriverBinding, 

+                                  ControllerHandle,

+                                  RemainingDevicePath

+                                  );

+        if (!EFI_ERROR (Status)) {

+          SortedDriverBindingProtocols[Index] = NULL;

+          DriverFound = TRUE;

+

+          //

+          // A driver was found that supports ControllerHandle, so attempt to start the driver

+          // on ControllerHandle.

+          //

+          PERF_CODE_BEGIN ();

+          GetHandleFromDriverBinding (DriverBinding, &DriverBindingHandle);

+          PERF_CODE_END ();

+

+          PERF_START (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);

+          Status = DriverBinding->Start (

+                                    DriverBinding, 

+                                    ControllerHandle,

+                                    RemainingDevicePath

+                                    );

+          PERF_END (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);

+

+          if (!EFI_ERROR (Status)) {

+            //

+            // The driver was successfully started on ControllerHandle, so set a flag

+            //

+            OneStarted = TRUE;

+          }

+        }

+      }

+    }

+  } while (DriverFound);

+

+  //

+  // Free any buffers that were allocated with AllocatePool()

+  //

+  CoreFreePool (SortedDriverBindingProtocols);

+

+  //

+  // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.

+  //

+  if (OneStarted) {

+    return EFI_SUCCESS;

+  } 

+

+  //

+  // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS

+  //

+  if (RemainingDevicePath != NULL) {

+    if (IsDevicePathEnd (RemainingDevicePath)) {

+      return EFI_SUCCESS;

+    }

+  } 

+

+  //

+  // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND

+  //

+  return EFI_NOT_FOUND;

+}

+

+

+EFI_STATUS 

+EFIAPI

+CoreDisconnectController (

+  IN  EFI_HANDLE  ControllerHandle,

+  IN  EFI_HANDLE  DriverImageHandle  OPTIONAL,

+  IN  EFI_HANDLE  ChildHandle        OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Disonnects a controller from a driver

+

+Arguments:

+

+  ControllerHandle  - ControllerHandle The handle of the controller from which driver(s) 

+                        are to be disconnected.

+  DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.

+  ChildHandle       - ChildHandle The handle of the child to destroy.

+

+Returns:

+

+  EFI_SUCCESS           -  One or more drivers were disconnected from the controller.

+  EFI_SUCCESS           -  On entry, no drivers are managing ControllerHandle.

+  EFI_SUCCESS           -  DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.

+  EFI_INVALID_PARAMETER -  ControllerHandle is not a valid EFI_HANDLE.

+  EFI_INVALID_PARAMETER -  DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.

+  EFI_INVALID_PARAMETER -  ChildHandle is not NULL, and it is not a valid EFI_HANDLE.

+  EFI_OUT_OF_RESOURCES  -  There are not enough resources available to disconnect any drivers from ControllerHandle.

+  EFI_DEVICE_ERROR      -  The controller could not be disconnected because of a device error.

+

+--*/

+{

+  EFI_STATUS                          Status;

+  IHANDLE                             *Handle;

+  EFI_HANDLE                          *DriverImageHandleBuffer;

+  EFI_HANDLE                          *ChildBuffer;

+  UINTN                               Index;

+  UINTN                               HandleIndex;

+  UINTN                               DriverImageHandleCount;

+  UINTN                               ChildrenToStop;

+  UINTN                               ChildBufferCount;

+  UINTN                               StopCount;

+  BOOLEAN                             Duplicate;

+  BOOLEAN                             ChildHandleValid;

+  BOOLEAN                             DriverImageHandleValid;

+  LIST_ENTRY                          *Link;

+  LIST_ENTRY                          *ProtLink;

+  OPEN_PROTOCOL_DATA                  *OpenData;

+  PROTOCOL_INTERFACE                  *Prot;

+  EFI_DRIVER_BINDING_PROTOCOL         *DriverBinding;

+

+  //

+  // Make sure ControllerHandle is valid

+  //

+  Status = CoreValidateHandle (ControllerHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure ChildHandle is valid if it is not NULL

+  //

+  if (ChildHandle != NULL) {

+    Status = CoreValidateHandle (ChildHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  Handle = ControllerHandle;

+

+  //

+  // Get list of drivers that are currently managing ControllerHandle

+  //

+  DriverImageHandleBuffer = NULL;

+  DriverImageHandleCount  = 1;  

+  

+  if (DriverImageHandle == NULL) {

+    //

+    // Look at each protocol interface for a match

+    //

+    DriverImageHandleCount = 0;

+

+    CoreAcquireProtocolLock ();

+    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+      for (ProtLink = Prot->OpenList.ForwardLink; 

+           ProtLink != &Prot->OpenList; 

+           ProtLink = ProtLink->ForwardLink) {

+        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {

+          DriverImageHandleCount++;

+        }

+      }

+    }

+    CoreReleaseProtocolLock ();

+    

+    //

+    // If there are no drivers managing this controller, then return EFI_SUCCESS

+    //

+    if (DriverImageHandleCount == 0) {

+      Status = EFI_SUCCESS;

+      goto Done;

+    }

+

+    DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount);

+    if (DriverImageHandleBuffer == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto Done;

+    }

+

+    DriverImageHandleCount = 0;

+

+    CoreAcquireProtocolLock ();

+    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+      for (ProtLink = Prot->OpenList.ForwardLink; 

+           ProtLink != &Prot->OpenList; 

+           ProtLink = ProtLink->ForwardLink) {

+        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {

+          Duplicate = FALSE;

+          for (Index = 0; Index< DriverImageHandleCount; Index++) {

+            if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {

+              Duplicate = TRUE;

+              break;

+            }

+          }

+          if (!Duplicate) {

+            DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;

+            DriverImageHandleCount++;

+          }

+        }

+      }

+    }

+    CoreReleaseProtocolLock ();

+  }

+

+  StopCount = 0;

+  for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {

+

+    if (DriverImageHandleBuffer != NULL) {

+      DriverImageHandle = DriverImageHandleBuffer[HandleIndex];

+    }

+

+    //

+    // Get the Driver Binding Protocol of the driver that is managing this controller

+    //

+    Status = CoreHandleProtocol (

+               DriverImageHandle,  

+               &gEfiDriverBindingProtocolGuid,   

+               (VOID **)&DriverBinding

+               );

+    if (EFI_ERROR (Status)) {

+      Status = EFI_INVALID_PARAMETER;

+      goto Done;

+    }

+

+    //

+    // Look at each protocol interface for a match

+    //

+    DriverImageHandleValid = FALSE;

+    ChildBufferCount = 0;

+

+    CoreAcquireProtocolLock ();

+    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+      for (ProtLink = Prot->OpenList.ForwardLink; 

+           ProtLink != &Prot->OpenList; 

+           ProtLink = ProtLink->ForwardLink) {

+        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+        if (OpenData->AgentHandle == DriverImageHandle) {

+          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {

+            ChildBufferCount++;

+          } 

+          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {

+            DriverImageHandleValid = TRUE;

+          }

+        }

+      }

+    }

+    CoreReleaseProtocolLock ();

+

+    if (DriverImageHandleValid) {

+      ChildHandleValid = FALSE;

+      ChildBuffer = NULL;

+      if (ChildBufferCount != 0) {

+        ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount);

+        if (ChildBuffer == NULL) {

+          Status = EFI_OUT_OF_RESOURCES;

+          goto Done;

+        }

+

+        ChildBufferCount = 0;

+

+        CoreAcquireProtocolLock ();

+        for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+          Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+          for (ProtLink = Prot->OpenList.ForwardLink; 

+               ProtLink != &Prot->OpenList; 

+               ProtLink = ProtLink->ForwardLink) {

+            OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+            if ((OpenData->AgentHandle == DriverImageHandle) &&

+                ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {

+              Duplicate = FALSE;

+              for (Index = 0; Index < ChildBufferCount; Index++) {

+                if (ChildBuffer[Index] == OpenData->ControllerHandle) {

+                  Duplicate = TRUE;

+                  break;

+                }

+              }

+              if (!Duplicate) {

+                ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;

+                if (ChildHandle == ChildBuffer[ChildBufferCount]) {

+                  ChildHandleValid = TRUE;

+                }

+                ChildBufferCount++;

+              }

+            }

+          }

+        }

+        CoreReleaseProtocolLock ();

+      }

+

+      if (ChildHandle == NULL || ChildHandleValid) {

+        ChildrenToStop = 0;

+        Status = EFI_SUCCESS;

+        if (ChildBufferCount > 0) {

+          if (ChildHandle != NULL) {

+            ChildrenToStop = 1;

+            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);

+          } else {

+            ChildrenToStop = ChildBufferCount;

+            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);

+          }

+        }

+        if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {

+          Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);

+        }

+        if (!EFI_ERROR (Status)) {

+          StopCount++;

+        }

+      }

+

+      if (ChildBuffer != NULL) {

+        CoreFreePool (ChildBuffer);

+      }

+    }

+  }

+

+  if (StopCount > 0) {

+    Status = EFI_SUCCESS;

+  } else {

+    Status = EFI_NOT_FOUND;

+  }

+  

+Done:  

+

+  if (DriverImageHandleBuffer != NULL) {

+    CoreFreePool (DriverImageHandleBuffer);

+  }

+

+  return Status;

+}

+

+

+

+STATIC

+EFI_STATUS

+GetHandleFromDriverBinding (

+  IN   EFI_DRIVER_BINDING_PROTOCOL           *DriverBindingNeed,

+  OUT  EFI_HANDLE                            *Handle 

+ )

+/*++

+

+Routine Description:

+

+  Locate the driver binding handle which a specified driver binding protocol installed on.

+

+Arguments:

+

+  DriverBindingNeed  - The specified driver binding protocol.

+  

+  Handle             - The driver binding handle which the protocol installed on.

+  

+

+Returns:

+

+  EFI_NOT_FOUND         - Could not find the handle.

+  

+  EFI_SUCCESS           - Successfully find the associated driver binding handle.

+  

+--*/ 

+ {

+  EFI_STATUS                          Status ;

+  EFI_DRIVER_BINDING_PROTOCOL         *DriverBinding;

+  UINTN                               DriverBindingHandleCount;

+  EFI_HANDLE                          *DriverBindingHandleBuffer;

+  UINTN                               Index;

+  

+  DriverBindingHandleCount = 0;

+  DriverBindingHandleBuffer = NULL;

+  *Handle = NULL_HANDLE;

+  Status = CoreLocateHandleBuffer (

+              ByProtocol,   

+              &gEfiDriverBindingProtocolGuid,  

+              NULL,

+              &DriverBindingHandleCount, 

+              &DriverBindingHandleBuffer

+              );

+  if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {

+    return EFI_NOT_FOUND;

+  }

+  

+  for (Index = 0 ; Index < DriverBindingHandleCount; Index++ ) {

+    Status = CoreOpenProtocol(

+                      DriverBindingHandleBuffer[Index],

+                      &gEfiDriverBindingProtocolGuid,

+                      (VOID **)&DriverBinding,

+                      gDxeCoreImageHandle,

+                      NULL,

+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                      );

+                      

+   if (!EFI_ERROR (Status) && DriverBinding != NULL) {

+    

+    if ( DriverBinding == DriverBindingNeed ) {

+      *Handle = DriverBindingHandleBuffer[Index];

+      CoreFreePool (DriverBindingHandleBuffer);         

+      return EFI_SUCCESS ;

+    }

+   }

+ }

+ 

+ CoreFreePool (DriverBindingHandleBuffer);

+ return EFI_NOT_FOUND ;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/Hand/Notify.c b/edk2/EdkModulePkg/Core/Dxe/Hand/Notify.c
new file mode 100644
index 0000000..f48fee7
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Hand/Notify.c
@@ -0,0 +1,333 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  notify.c

+

+Abstract:

+

+  EFI notify infrastructure

+

+

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+VOID

+CoreNotifyProtocolEntry (

+  IN PROTOCOL_ENTRY   *ProtEntry

+  )

+/*++

+

+Routine Description:

+

+  Signal event for every protocol in protocol entry.

+

+Arguments:

+

+  ProtEntry     - Protocol entry

+

+Returns:

+

+--*/

+{

+  PROTOCOL_NOTIFY     *ProtNotify;

+  LIST_ENTRY          *Link;

+

+  ASSERT_LOCKED (&gProtocolDatabaseLock);

+

+  for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {

+    ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);

+    CoreSignalEvent (ProtNotify->Event);

+  }

+}

+

+

+PROTOCOL_INTERFACE *

+CoreRemoveInterfaceFromProtocol (

+  IN IHANDLE        *Handle,

+  IN EFI_GUID       *Protocol,

+  IN VOID           *Interface

+  )

+/*++

+

+Routine Description:

+

+  Removes Protocol from the protocol list (but not the handle list).

+

+Arguments:

+

+  Handle -  The handle to remove protocol on.

+

+  Protocol  -  GUID of the protocol to be moved

+

+  Interface - The interface of the protocol

+

+Returns:

+

+  Protocol Entry

+

+--*/

+{

+  PROTOCOL_INTERFACE  *Prot;

+  PROTOCOL_NOTIFY     *ProtNotify;

+  PROTOCOL_ENTRY      *ProtEntry;

+  LIST_ENTRY          *Link;

+

+  ASSERT_LOCKED (&gProtocolDatabaseLock);

+

+  Prot = CoreFindProtocolInterface (Handle, Protocol, Interface);

+  if (Prot != NULL) {

+

+    ProtEntry = Prot->Protocol;

+

+    //

+    // If there's a protocol notify location pointing to this entry, back it up one

+    //

+

+    for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {

+      ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);

+

+      if (ProtNotify->Position == &Prot->ByProtocol) {

+        ProtNotify->Position = Prot->ByProtocol.BackLink;

+      }

+    }

+

+    //

+    // Remove the protocol interface entry

+    //

+

+    RemoveEntryList (&Prot->ByProtocol);

+  }

+

+  return Prot;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreRegisterProtocolNotify (

+  IN EFI_GUID       *Protocol,

+  IN EFI_EVENT      Event,

+  OUT  VOID           **Registration

+  )

+/*++

+

+Routine Description:

+

+  Add a new protocol notification record for the request protocol.

+

+Arguments:

+

+  Protocol      - The requested protocol to add the notify registration

+

+  Event         - The event to signal 

+

+  Registration  - Returns the registration record

+

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Invalid parameter

+

+  EFI_SUCCESS                 - Successfully returned the registration record that has been added

+  

+--*/

+{

+  PROTOCOL_ENTRY      *ProtEntry;

+  PROTOCOL_NOTIFY     *ProtNotify;

+  EFI_STATUS        Status;

+  

+  if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL))  {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CoreAcquireProtocolLock ();

+

+  ProtNotify = NULL;

+  

+  //

+  // Get the protocol entry to add the notification too

+  //

+

+  ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);

+  if (ProtEntry != NULL) {

+

+    //

+    // Allocate a new notification record

+    //

+

+    ProtNotify = CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY));

+

+    if (ProtNotify != NULL) {

+      

+      ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;

+      ProtNotify->Protocol = ProtEntry;

+      ProtNotify->Event = Event;

+      //

+      // start at the begining

+      //

+      ProtNotify->Position = &ProtEntry->Protocols; 

+

+      InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);

+    }

+  }

+

+  CoreReleaseProtocolLock ();

+

+  //

+  // Done.  If we have a protocol notify entry, then return it.

+  // Otherwise, we must have run out of resources trying to add one

+  //

+

+  Status = EFI_OUT_OF_RESOURCES;

+  if (ProtNotify != NULL) {

+    *Registration = ProtNotify;

+    Status = EFI_SUCCESS;

+  }

+

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreReinstallProtocolInterface (

+  IN EFI_HANDLE     UserHandle,

+  IN EFI_GUID       *Protocol,

+  IN VOID           *OldInterface,

+  IN VOID           *NewInterface

+  )

+/*++

+

+Routine Description:

+

+  Reinstall a protocol interface on a device handle.  The OldInterface for Protocol is replaced by the NewInterface.

+

+Arguments:

+

+  UserHandle    - Handle on which the interface is to be reinstalled

+  Protocol      - The numeric ID of the interface

+  OldInterface  - A pointer to the old interface

+  NewInterface  - A pointer to the new interface 

+

+

+Returns:

+

+  Status code.

+

+  On EFI_SUCCESS            The protocol interface was installed

+  On EFI_NOT_FOUND          The OldInterface on the handle was not found

+  On EFI_INVALID_PARAMETER  One of the parameters has an invalid value

+  

+--*/

+{

+  EFI_STATUS                Status;

+  IHANDLE                   *Handle;

+  PROTOCOL_INTERFACE        *Prot;

+  PROTOCOL_ENTRY            *ProtEntry;

+

+  Status = CoreValidateHandle (UserHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (Protocol == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Handle = (IHANDLE *) UserHandle;

+

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  //

+  // Check that Protocol exists on UserHandle, and Interface matches the interface in the database

+  //

+  Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);

+  if (Prot == NULL) {

+    CoreReleaseProtocolLock ();

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled

+  //

+  Status = CoreDisconnectControllersUsingProtocolInterface (

+             UserHandle,

+             Prot

+             );

+  if (EFI_ERROR (Status)) {

+    //

+    // One or more drivers refused to release, so return the error

+    //

+    CoreReleaseProtocolLock ();

+    return Status;

+  }

+

+  //

+  // Remove the protocol interface from the protocol

+  //

+  Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface);

+

+  if (Prot == NULL) {

+    CoreReleaseProtocolLock ();

+    return EFI_NOT_FOUND;

+  }

+

+  ProtEntry = Prot->Protocol;

+

+  //

+  // Update the interface on the protocol

+  //

+  Prot->Interface = NewInterface;

+

+  //

+  // Add this protocol interface to the tail of the

+  // protocol entry

+  //

+  InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);

+

+  //

+  // Update the Key to show that the handle has been created/modified

+  //

+  gHandleDatabaseKey++;

+  Handle->Key = gHandleDatabaseKey;

+

+  //

+  // Release the lock and connect all drivers to UserHandle

+  //

+  CoreReleaseProtocolLock ();

+  Status = CoreConnectController (

+                  UserHandle, 

+                  NULL, 

+                  NULL, 

+                  TRUE

+                  );

+  CoreAcquireProtocolLock ();

+  

+  //

+  // Notify the notification list for this protocol

+  //

+  CoreNotifyProtocolEntry (ProtEntry);

+

+  CoreReleaseProtocolLock ();

+  

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Hand/handle.c b/edk2/EdkModulePkg/Core/Dxe/Hand/handle.c
new file mode 100644
index 0000000..2edfdeb
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Hand/handle.c
@@ -0,0 +1,1699 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  handle.c

+

+Abstract:

+

+  EFI handle & protocol handling

+

+

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+

+//

+// mProtocolDatabase     - A list of all protocols in the system.  (simple list for now)

+// gHandleList           - A list of all the handles in the system

+// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase

+// gHandleDatabaseKey    -  The Key to show that the handle has been created/modified

+//

+static LIST_ENTRY      mProtocolDatabase     = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);

+LIST_ENTRY             gHandleList           = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);

+EFI_LOCK               gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);

+UINT64                 gHandleDatabaseKey    = 0;

+

+

+VOID

+CoreAcquireProtocolLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Acquire lock on gProtocolDatabaseLock.

+  

+Arguments:

+

+  None

+  

+Returns:

+

+  None

+

+--*/

+{

+  CoreAcquireLock (&gProtocolDatabaseLock);

+}

+

+

+VOID

+CoreReleaseProtocolLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Release lock on gProtocolDatabaseLock.

+  

+Arguments:

+

+  None

+  

+Returns:

+

+  None

+

+--*/

+{

+  CoreReleaseLock (&gProtocolDatabaseLock);

+}

+

+

+EFI_STATUS

+CoreValidateHandle (

+  IN  EFI_HANDLE                UserHandle

+  )

+/*++

+

+Routine Description:

+

+  Check whether a handle is a valid EFI_HANDLE

+  

+Arguments:

+

+  UserHandle    - The handle to check

+  

+Returns:

+

+  EFI_INVALID_PARAMETER   - The handle is NULL or not a valid EFI_HANDLE.

+

+  EFI_SUCCESS             - The handle is valid EFI_HANDLE.

+

+--*/

+{

+  IHANDLE             *Handle;

+

+  Handle = (IHANDLE *)UserHandle;

+  if (Handle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (Handle->Signature != EFI_HANDLE_SIGNATURE) {

+    return EFI_INVALID_PARAMETER;

+  }

+  return EFI_SUCCESS;

+}

+

+

+PROTOCOL_ENTRY  *

+CoreFindProtocolEntry (

+  IN EFI_GUID   *Protocol,

+  IN BOOLEAN    Create

+  )

+/*++

+

+Routine Description:

+

+  Finds the protocol entry for the requested protocol.

+  

+  The gProtocolDatabaseLock must be owned

+

+Arguments:

+  

+  Protocol  - The ID of the protocol 

+

+  Create    - Create a new entry if not found

+

+Returns:

+

+  Protocol entry

+

+--*/

+{

+  LIST_ENTRY          *Link;

+  PROTOCOL_ENTRY      *Item;

+  PROTOCOL_ENTRY      *ProtEntry;

+

+  ASSERT_LOCKED(&gProtocolDatabaseLock);

+

+  //

+  // Search the database for the matching GUID

+  //

+

+  ProtEntry = NULL;

+  for (Link = mProtocolDatabase.ForwardLink; 

+       Link != &mProtocolDatabase; 

+       Link = Link->ForwardLink) {

+

+    Item = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);

+    if (CompareGuid (&Item->ProtocolID, Protocol)) {

+

+      //

+      // This is the protocol entry

+      //

+

+      ProtEntry = Item;

+      break;

+    }

+  }

+

+  //

+  // If the protocol entry was not found and Create is TRUE, then 

+  // allocate a new entry

+  //     

+  if ((ProtEntry == NULL) && Create) {

+    ProtEntry = CoreAllocateBootServicesPool (sizeof(PROTOCOL_ENTRY));

+    

+    if (ProtEntry != NULL) {

+      //

+      // Initialize new protocol entry structure

+      //

+      ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;

+      CopyMem ((VOID *)&ProtEntry->ProtocolID, Protocol, sizeof (EFI_GUID));

+      InitializeListHead (&ProtEntry->Protocols);

+      InitializeListHead (&ProtEntry->Notify);

+

+      //

+      // Add it to protocol database

+      //

+      InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);

+    }

+  }

+

+  return ProtEntry;

+}

+

+

+PROTOCOL_INTERFACE *

+CoreFindProtocolInterface (

+  IN IHANDLE        *Handle,

+  IN EFI_GUID       *Protocol,

+  IN VOID           *Interface

+  )

+/*++

+

+Routine Description:

+

+  Finds the protocol instance for the requested handle and protocol.

+  

+  Note: This function doesn't do parameters checking, it's caller's responsibility 

+        to pass in valid parameters.

+  

+Arguments:

+  

+  Handle    - The handle to search the protocol on

+  

+  Protocol  - GUID of the protocol

+

+  Interface - The interface for the protocol being searched

+

+Returns:

+

+  Protocol instance (NULL: Not found)

+

+--*/  

+{

+  PROTOCOL_INTERFACE  *Prot;

+  PROTOCOL_ENTRY      *ProtEntry;

+  LIST_ENTRY          *Link;

+

+  ASSERT_LOCKED(&gProtocolDatabaseLock);

+  Prot = NULL;

+

+  //

+  // Lookup the protocol entry for this protocol ID

+  //

+

+  ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);

+  if (ProtEntry != NULL) {

+

+    //

+    // Look at each protocol interface for any matches

+    //

+    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) {

+

+      //

+      // If this protocol interface matches, remove it

+      //

+      Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+      if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) {

+        break;

+      }

+

+      Prot = NULL;

+    }

+  }

+

+  return Prot;

+}

+

+STATIC

+EFI_STATUS

+CoreUnregisterProtocolNotifyEvent (

+  IN EFI_EVENT      Event

+  )

+/*++

+

+Routine Description:

+

+  Removes an event from a register protocol notify list on a protocol.

+

+Arguments:

+  

+  Event   - The event to search for in the protocol database.

+

+Returns:

+

+  EFI_SUCCESS   if the event was found and removed.

+  EFI_NOT_FOUND if the event was not found in the protocl database.

+

+--*/

+{

+  LIST_ENTRY         *Link;

+  PROTOCOL_ENTRY     *ProtEntry;

+  LIST_ENTRY         *NotifyLink;

+  PROTOCOL_NOTIFY    *ProtNotify;

+

+  CoreAcquireProtocolLock ();

+

+  for ( Link =  mProtocolDatabase.ForwardLink; 

+        Link != &mProtocolDatabase; 

+        Link =  Link->ForwardLink) {

+

+    ProtEntry = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);

+

+    for ( NotifyLink =  ProtEntry->Notify.ForwardLink; 

+          NotifyLink != &ProtEntry->Notify; 

+          NotifyLink =  NotifyLink->ForwardLink) {

+

+      ProtNotify = CR(NotifyLink, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);

+

+      if (ProtNotify->Event == Event) {

+        RemoveEntryList(&ProtNotify->Link);

+        CoreFreePool(ProtNotify);

+        CoreReleaseProtocolLock ();

+        return EFI_SUCCESS;

+      }

+    }

+  }

+

+  CoreReleaseProtocolLock ();

+  return EFI_NOT_FOUND;

+}

+

+

+EFI_STATUS

+CoreUnregisterProtocolNotify (

+  IN EFI_EVENT      Event

+  )

+/*++

+

+Routine Description:

+

+  Removes all the events in the protocol database that match Event.

+

+Arguments:

+  

+  Event   - The event to search for in the protocol database.

+

+Returns:

+

+  EFI_SUCCESS when done searching the entire database.

+

+--*/

+{

+  EFI_STATUS       Status;

+

+  do {

+    Status = CoreUnregisterProtocolNotifyEvent (Event);

+  } while (!EFI_ERROR (Status));

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreInstallProtocolInterface (

+  IN OUT EFI_HANDLE     *UserHandle,

+  IN EFI_GUID           *Protocol,

+  IN EFI_INTERFACE_TYPE InterfaceType,

+  IN VOID               *Interface

+  )

+/*++

+

+Routine Description:

+

+  Wrapper function to CoreInstallProtocolInterfaceNotify.  This is the public API which

+  Calls the private one which contains a BOOLEAN parameter for notifications

+

+Arguments:

+

+  UserHandle     - The handle to install the protocol handler on,

+                    or NULL if a new handle is to be allocated

+

+  Protocol       - The protocol to add to the handle

+

+  InterfaceType  - Indicates whether Interface is supplied in native form.

+

+  Interface      - The interface for the protocol being added

+

+Returns:

+

+  Status code    

+

+--*/

+{

+  return CoreInstallProtocolInterfaceNotify (

+            UserHandle, 

+            Protocol, 

+            InterfaceType, 

+            Interface, 

+            TRUE

+            );

+}

+

+EFI_STATUS

+CoreInstallProtocolInterfaceNotify (

+  IN OUT EFI_HANDLE     *UserHandle,

+  IN EFI_GUID           *Protocol,

+  IN EFI_INTERFACE_TYPE InterfaceType,

+  IN VOID               *Interface,

+  IN BOOLEAN            Notify

+  )

+/*++

+

+Routine Description:

+

+  Installs a protocol interface into the boot services environment.

+

+Arguments:

+

+  UserHandle     - The handle to install the protocol handler on,

+                   or NULL if a new handle is to be allocated

+

+  Protocol       - The protocol to add to the handle

+

+  InterfaceType  - Indicates whether Interface is supplied in native form.

+

+  Interface      - The interface for the protocol being added

+

+  Notify         - indicates whether notify the notification list 

+                   for this protocol

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_OUT_OF_RESOURCES       - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Protocol interface successfully installed

+

+--*/

+{

+  PROTOCOL_INTERFACE  *Prot;

+  PROTOCOL_ENTRY      *ProtEntry;

+  IHANDLE             *Handle;

+  EFI_STATUS          Status;

+  VOID                *ExistingInterface;

+

+  //

+  // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.

+  // Also added check for invalid UserHandle and Protocol pointers.

+  //

+  if (UserHandle == NULL || Protocol == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (InterfaceType != EFI_NATIVE_INTERFACE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Print debug message

+  //

+  DEBUG((EFI_D_ERROR | EFI_D_INFO, "InstallProtocolInterface: %g %x\n", Protocol, Interface));

+

+  Status = EFI_OUT_OF_RESOURCES;

+  Prot = NULL;

+  Handle = NULL;

+

+  ASSERT (NULL != gBS);

+

+  if (*UserHandle != NULL_HANDLE) {

+    Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);

+    if (!EFI_ERROR (Status)) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  //

+  // Lock the protocol database 

+  //

+  CoreAcquireProtocolLock ();

+

+  //

+  // Lookup the Protocol Entry for the requested protocol

+  //

+  ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);

+  if (ProtEntry == NULL) {

+    goto Done;

+  }

+

+  //

+  // Allocate a new protocol interface structure

+  //

+  Prot = CoreAllocateZeroBootServicesPool (sizeof(PROTOCOL_INTERFACE));

+  if (Prot == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  //

+  // If caller didn't supply a handle, allocate a new one

+  //

+  Handle = (IHANDLE *)*UserHandle;

+  if (Handle == NULL) {

+    Handle = CoreAllocateZeroBootServicesPool (sizeof(IHANDLE));

+    if (Handle == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto Done;

+    }

+

+    //

+    // Initialize new handler structure

+    //

+    Handle->Signature = EFI_HANDLE_SIGNATURE;

+    InitializeListHead (&Handle->Protocols);

+

+    //

+    // Initialize the Key to show that the handle has been created/modified

+    //

+    gHandleDatabaseKey++;

+    Handle->Key = gHandleDatabaseKey;

+

+    //

+    // Add this handle to the list global list of all handles

+    // in the system

+    //

+    InsertTailList (&gHandleList, &Handle->AllHandles);

+  } 

+

+  Status = CoreValidateHandle (Handle);

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  //

+  // Each interface that is added must be unique

+  //

+  ASSERT (CoreFindProtocolInterface (Handle, Protocol, Interface) == NULL);

+

+  //

+  // Initialize the protocol interface structure

+  //

+  Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;

+  Prot->Handle = Handle;

+  Prot->Protocol = ProtEntry;

+  Prot->Interface = Interface;

+

+  //

+  // Initalize OpenProtocol Data base

+  //

+  InitializeListHead (&Prot->OpenList);

+  Prot->OpenListCount = 0;

+

+  //

+  // Add this protocol interface to the head of the supported 

+  // protocol list for this handle

+  //

+  InsertHeadList (&Handle->Protocols, &Prot->Link);

+

+  //

+  // Add this protocol interface to the tail of the 

+  // protocol entry

+  // 

+  InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);

+

+  //

+  // Notify the notification list for this protocol 

+  //

+  if (Notify) {

+    CoreNotifyProtocolEntry (ProtEntry);

+  }

+  Status = EFI_SUCCESS;

+

+Done:

+  //

+  // Done, unlock the database and return

+  //

+  CoreReleaseProtocolLock ();

+  if (!EFI_ERROR (Status)) {

+    //

+    // Return the new handle back to the caller

+    //

+    *UserHandle = Handle;

+  } else {

+    //

+    // There was an error, clean up

+    //

+    if (Prot != NULL) {

+      CoreFreePool (Prot);

+    }

+  }

+

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreInstallMultipleProtocolInterfaces (

+  IN OUT EFI_HANDLE           *Handle,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Installs a list of protocol interface into the boot services environment.

+  This function calls InstallProtocolInterface() in a loop. If any error

+  occures all the protocols added by this function are removed. This is 

+  basically a lib function to save space.

+

+Arguments:

+

+  Handle      - The handle to install the protocol handlers on,

+                or NULL if a new handle is to be allocated

+  ...         - EFI_GUID followed by protocol instance. A NULL terminates the 

+                list. The pairs are the arguments to InstallProtocolInterface().

+                All the protocols are added to Handle.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Handle is NULL.

+  

+  EFI_SUCCESS                 - Protocol interfaces successfully installed.

+

+--*/

+{

+  VA_LIST                   args;

+  EFI_STATUS                Status;

+  EFI_GUID                  *Protocol;

+  VOID                      *Interface;

+  EFI_TPL                   OldTpl;

+  UINTN                     Index;

+  EFI_HANDLE                OldHandle;

+  EFI_HANDLE                DeviceHandle;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  

+  if (Handle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // Syncronize with notifcations. 

+  // 

+  OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);

+  OldHandle = *Handle;

+

+  //

+  // Check for duplicate device path and install the protocol interfaces

+  //

+  VA_START (args, Handle);

+  for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {

+    //

+    // If protocol is NULL, then it's the end of the list

+    //

+    Protocol = VA_ARG (args, EFI_GUID *);

+    if (Protocol == NULL) {

+      break;

+    }

+

+    Interface = VA_ARG (args, VOID *);

+

+    //

+    // Make sure you are installing on top a device path that has already been added.

+    //

+    if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) {

+      DeviceHandle = NULL;

+      DevicePath   = Interface;

+      Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);

+      if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) {

+        Status = EFI_ALREADY_STARTED;

+        continue;

+      }

+    }

+  

+    //

+    // Install it

+    //

+    Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);

+  }

+  

+  //

+  // If there was an error, remove all the interfaces that were installed without any errors

+  //

+  if (EFI_ERROR (Status)) {

+    //

+    // Reset the va_arg back to the first argument.

+    //

+    VA_START (args, Handle);

+    for (; Index > 1; Index--) {

+      Protocol = VA_ARG (args, EFI_GUID *);

+      Interface = VA_ARG (args, VOID *);

+      CoreUninstallProtocolInterface (*Handle, Protocol, Interface);

+    }        

+    *Handle = OldHandle;

+  }

+

+  //

+  // Done

+  //

+  CoreRestoreTpl (OldTpl);

+  return Status;

+}

+

+EFI_STATUS

+CoreDisconnectControllersUsingProtocolInterface (

+  IN EFI_HANDLE           UserHandle,

+  IN PROTOCOL_INTERFACE   *Prot

+  )

+/*++

+

+Routine Description:

+

+  Attempts to disconnect all drivers that are using the protocol interface being queried.

+  If failed, reconnect all drivers disconnected.

+  

+  Note: This function doesn't do parameters checking, it's caller's responsibility 

+        to pass in valid parameters.

+

+Arguments:

+

+  UserHandle  - The handle on which the protocol is installed 

+  Prot        - The protocol to disconnect drivers from

+

+Returns:

+

+  EFI_SUCCESS       - Drivers using the protocol interface are all disconnected

+  EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers

+

+--*/

+{

+  EFI_STATUS            Status;

+  BOOLEAN               ItemFound;

+  LIST_ENTRY            *Link;

+  OPEN_PROTOCOL_DATA    *OpenData;

+

+  Status = EFI_SUCCESS;

+  

+  //

+  // Attempt to disconnect all drivers from this protocol interface

+  //

+  do {

+    ItemFound = FALSE;

+    for ( Link = Prot->OpenList.ForwardLink;

+          (Link != &Prot->OpenList) && !ItemFound;

+          Link = Link->ForwardLink ) {

+      OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+      if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {

+        ItemFound = TRUE;

+        CoreReleaseProtocolLock ();

+        Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);

+        CoreAcquireProtocolLock ();

+        if (EFI_ERROR (Status)) {

+           ItemFound = FALSE;

+           break;

+        }

+      }

+    }

+  } while (ItemFound);

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items

+    //

+    do {

+      ItemFound = FALSE;

+      for ( Link = Prot->OpenList.ForwardLink;

+            (Link != &Prot->OpenList) && !ItemFound;

+            Link = Link->ForwardLink ) {

+        OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+        if (OpenData->Attributes & 

+            (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {

+          ItemFound = TRUE;

+          RemoveEntryList (&OpenData->Link);  

+          Prot->OpenListCount--;

+          CoreFreePool (OpenData);

+        }

+      }

+    } while (ItemFound);

+  }

+

+  //

+  // If there are errors or still has open items in the list, then reconnect all the drivers and return an error

+  //

+  if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {

+    CoreReleaseProtocolLock ();

+    CoreConnectController (UserHandle, NULL, NULL, TRUE);

+    CoreAcquireProtocolLock ();

+    Status = EFI_ACCESS_DENIED;

+  }

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreUninstallProtocolInterface (

+  IN EFI_HANDLE       UserHandle,

+  IN EFI_GUID         *Protocol,

+  IN VOID             *Interface

+  )

+/*++

+

+Routine Description:

+

+  Uninstalls all instances of a protocol:interfacer from a handle. 

+  If the last protocol interface is remove from the handle, the 

+  handle is freed.

+

+Arguments:

+

+  UserHandle      - The handle to remove the protocol handler from

+

+  Protocol        - The protocol, of protocol:interface, to remove

+

+  Interface       - The interface, of protocol:interface, to remove

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Protocol is NULL.

+  

+  EFI_SUCCESS                 - Protocol interface successfully uninstalled.

+

+--*/

+{

+  EFI_STATUS            Status;

+  IHANDLE               *Handle;

+  PROTOCOL_INTERFACE    *Prot;

+

+  //

+  // Check that Protocol is valid

+  //

+  if (Protocol == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check that UserHandle is a valid handle

+  //

+  Status = CoreValidateHandle (UserHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  //

+  // Check that Protocol exists on UserHandle, and Interface matches the interface in the database

+  //

+  Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface);

+  if (Prot == NULL) {

+    Status = EFI_NOT_FOUND;

+    goto Done;

+  }

+

+  //

+  // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed

+  //

+  Status = CoreDisconnectControllersUsingProtocolInterface (

+             UserHandle,

+             Prot

+             );

+  if (EFI_ERROR (Status)) {

+    //

+    // One or more drivers refused to release, so return the error

+    //

+    goto Done;

+  }

+

+  //

+  // Remove the protocol interface from the protocol

+  //

+  Status = EFI_NOT_FOUND;

+  Handle = (IHANDLE *)UserHandle;

+  Prot   = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface);

+

+  if (Prot != NULL) {

+    //

+    // Update the Key to show that the handle has been created/modified

+    //

+    gHandleDatabaseKey++;

+    Handle->Key = gHandleDatabaseKey;

+    

+    //

+    // Remove the protocol interface from the handle

+    //

+    RemoveEntryList (&Prot->Link);

+

+    //

+    // Free the memory

+    //

+    Prot->Signature = 0;

+    CoreFreePool (Prot);

+    Status = EFI_SUCCESS;

+  }

+

+  //

+  // If there are no more handlers for the handle, free the handle

+  //

+  if (IsListEmpty (&Handle->Protocols)) {

+    Handle->Signature = 0;

+    RemoveEntryList (&Handle->AllHandles);

+    CoreFreePool (Handle);

+  }

+

+Done:  

+  //

+  // Done, unlock the database and return

+  //

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreUninstallMultipleProtocolInterfaces (

+  IN EFI_HANDLE           Handle,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Uninstalls a list of protocol interface in the boot services environment. 

+  This function calls UnisatllProtocolInterface() in a loop. This is 

+  basically a lib function to save space.

+

+Arguments:

+

+  Handle      - The handle to uninstall the protocol

+

+  ...         - EFI_GUID followed by protocol instance. A NULL terminates the 

+                list. The pairs are the arguments to UninstallProtocolInterface().

+                All the protocols are added to Handle.

+

+Returns:

+

+  Status code    

+

+--*/

+{

+  EFI_STATUS      Status;

+  VA_LIST         args;

+  EFI_GUID        *Protocol;

+  VOID            *Interface;

+  UINTN           Index;

+

+  VA_START (args, Handle);

+  for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {

+    //

+    // If protocol is NULL, then it's the end of the list

+    //

+    Protocol = VA_ARG (args, EFI_GUID *);

+    if (Protocol == NULL) {

+      break;

+    }

+

+    Interface = VA_ARG (args, VOID *);

+

+    //

+    // Uninstall it

+    //

+    Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface);

+  }

+

+  //

+  // If there was an error, add all the interfaces that were

+  // uninstalled without any errors

+  //

+  if (EFI_ERROR (Status)) {

+    //

+    // Reset the va_arg back to the first argument.

+    //

+    VA_START (args, Handle);

+    for (; Index > 1; Index--) {

+      Protocol = VA_ARG(args, EFI_GUID *);

+      Interface = VA_ARG(args, VOID *);

+      CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);

+    }        

+  }

+

+  return Status;

+}    

+

+PROTOCOL_INTERFACE  *

+CoreGetProtocolInterface (

+  IN  EFI_HANDLE                UserHandle,

+  IN  EFI_GUID                  *Protocol

+  )

+/*++

+

+Routine Description:

+

+  Locate a certain GUID protocol interface in a Handle's protocols.

+

+Arguments:

+

+  UserHandle  - The handle to obtain the protocol interface on

+

+  Protocol    - The GUID of the protocol 

+

+Returns:

+

+  The requested protocol interface for the handle

+  

+--*/  

+{

+  EFI_STATUS          Status;

+  PROTOCOL_ENTRY      *ProtEntry;

+  PROTOCOL_INTERFACE  *Prot;

+  IHANDLE             *Handle;

+  LIST_ENTRY          *Link;

+

+  Status = CoreValidateHandle (UserHandle);

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+  

+  Handle = (IHANDLE *)UserHandle;

+

+  //

+  // Look at each protocol interface for a match

+  //

+  for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+    Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+    ProtEntry = Prot->Protocol;

+    if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {

+      return Prot;

+    }

+  }

+  return NULL;

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreHandleProtocol (

+  IN EFI_HANDLE       UserHandle,

+  IN EFI_GUID         *Protocol,

+  OUT VOID            **Interface

+  )

+/*++

+

+Routine Description:

+

+  Queries a handle to determine if it supports a specified protocol.

+

+Arguments:

+

+  UserHandle  - The handle being queried.

+

+  Protocol    - The published unique identifier of the protocol.

+

+  Interface   - Supplies the address where a pointer to the corresponding Protocol

+               Interface is returned.

+

+Returns:

+

+  The requested protocol interface for the handle

+  

+--*/  

+{

+  return CoreOpenProtocol (

+          UserHandle,     

+          Protocol, 

+          Interface, 

+          gDxeCoreImageHandle, 

+          NULL,     

+          EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL

+          );

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreOpenProtocol (

+  IN  EFI_HANDLE                UserHandle,

+  IN  EFI_GUID                  *Protocol,

+  OUT VOID                      **Interface OPTIONAL,

+  IN  EFI_HANDLE                ImageHandle,

+  IN  EFI_HANDLE                ControllerHandle,

+  IN  UINT32                    Attributes

+  )

+/*++

+

+Routine Description:

+

+  Locates the installed protocol handler for the handle, and

+  invokes it to obtain the protocol interface. Usage information

+  is registered in the protocol data base.

+

+Arguments:

+

+  UserHandle     - The handle to obtain the protocol interface on

+

+  Protocol       - The ID of the protocol 

+

+  Interface      - The location to return the protocol interface

+

+  ImageHandle       - The handle of the Image that is opening the protocol interface

+                    specified by Protocol and Interface.

+  

+  ControllerHandle  - The controller handle that is requiring this interface.

+

+  Attributes     - The open mode of the protocol interface specified by Handle

+                    and Protocol.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Protocol is NULL.

+  

+  EFI_SUCCESS                 - Get the protocol interface.

+  

+--*/

+{

+  EFI_STATUS          Status;

+  PROTOCOL_INTERFACE  *Prot;

+  LIST_ENTRY          *Link;

+  OPEN_PROTOCOL_DATA  *OpenData;

+  BOOLEAN             ByDriver;

+  BOOLEAN             Exclusive;

+  BOOLEAN             Disconnect;

+  BOOLEAN             ExactMatch;

+

+  //

+  // Check for invalid Protocol

+  //

+  if (Protocol == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check for invalid Interface

+  //

+  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {

+    if (Interface == NULL) {

+      return EFI_INVALID_PARAMETER;

+    } else {

+      *Interface = NULL;

+    }

+  }

+  

+  //

+  // Check for invalid UserHandle

+  //

+  Status = CoreValidateHandle (UserHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Check for invalid Attributes

+  //

+  switch (Attributes) {

+  case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :

+    Status = CoreValidateHandle (ImageHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    Status = CoreValidateHandle (ControllerHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    if (UserHandle == ControllerHandle) {

+      return EFI_INVALID_PARAMETER;

+    }

+    break;

+  case EFI_OPEN_PROTOCOL_BY_DRIVER :

+  case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :

+    Status = CoreValidateHandle (ImageHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    Status = CoreValidateHandle (ControllerHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    break;

+  case EFI_OPEN_PROTOCOL_EXCLUSIVE :

+    Status = CoreValidateHandle (ImageHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    break;

+  case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :

+  case EFI_OPEN_PROTOCOL_GET_PROTOCOL :

+  case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :

+    break;

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  //

+  // Look at each protocol interface for a match

+  //

+  Prot = CoreGetProtocolInterface (UserHandle, Protocol);

+  if (Prot == NULL) {

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+

+  //

+  // This is the protocol interface entry for this protocol

+  //    

+  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {

+    *Interface = Prot->Interface;

+  }

+  Status = EFI_SUCCESS;

+

+  ByDriver        = FALSE;

+  Exclusive       = FALSE;

+  for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {

+    OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+    ExactMatch =  (BOOLEAN)((OpenData->AgentHandle == ImageHandle) && 

+                            (OpenData->Attributes == Attributes)  &&

+                            (OpenData->ControllerHandle == ControllerHandle));

+    if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {

+      ByDriver = TRUE;

+      if (ExactMatch) {

+        Status = EFI_ALREADY_STARTED;

+        goto Done;

+      }

+    }

+    if (OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {

+      Exclusive = TRUE;

+    } else if (ExactMatch) {

+      OpenData->OpenCount++;

+      Status = EFI_SUCCESS;

+      goto Done;

+    }

+  }

+

+  //

+  // ByDriver  TRUE  -> A driver is managing (UserHandle, Protocol)

+  // ByDriver  FALSE -> There are no drivers managing (UserHandle, Protocol)

+  // Exclusive TRUE  -> Something has exclusive access to (UserHandle, Protocol)

+  // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)

+  //

+

+  switch (Attributes) {

+  case EFI_OPEN_PROTOCOL_BY_DRIVER :

+    if (Exclusive || ByDriver) {

+      Status = EFI_ACCESS_DENIED;

+      goto Done;

+    }

+    break;

+  case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :

+  case EFI_OPEN_PROTOCOL_EXCLUSIVE :

+    if (Exclusive) {

+      Status = EFI_ACCESS_DENIED;

+      goto Done;

+    }

+    if (ByDriver) {

+      do {

+        Disconnect = FALSE;

+        for ( Link = Prot->OpenList.ForwardLink; (Link != &Prot->OpenList) && (!Disconnect); Link = Link->ForwardLink) {

+          OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+          if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {

+            Disconnect = TRUE;

+            CoreReleaseProtocolLock ();

+            Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);

+            CoreAcquireProtocolLock ();

+            if (EFI_ERROR (Status)) {

+              Status = EFI_ACCESS_DENIED;

+              goto Done;

+            }

+          }

+        }

+      } while (Disconnect);

+    } 

+    break;

+  case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :

+  case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :

+  case EFI_OPEN_PROTOCOL_GET_PROTOCOL :

+  case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :

+    break;

+  }

+

+  if (ImageHandle == NULL) {

+    Status = EFI_SUCCESS;

+    goto Done;

+  }

+  //

+  // Create new entry

+  //

+  OpenData = CoreAllocateBootServicesPool (sizeof(OPEN_PROTOCOL_DATA));

+  if (OpenData == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+  } else {

+    OpenData->Signature         = OPEN_PROTOCOL_DATA_SIGNATURE;

+    OpenData->AgentHandle       = ImageHandle;

+    OpenData->ControllerHandle  = ControllerHandle;

+    OpenData->Attributes        = Attributes;

+    OpenData->OpenCount         = 1;

+    InsertTailList (&Prot->OpenList, &OpenData->Link);

+    Prot->OpenListCount++;

+    Status = EFI_SUCCESS;

+  }

+

+Done:

+  //

+  // Done. Release the database lock are return

+  //

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreCloseProtocol (

+  IN  EFI_HANDLE                UserHandle,

+  IN  EFI_GUID                  *Protocol,

+  IN  EFI_HANDLE                AgentHandle,

+  IN  EFI_HANDLE                ControllerHandle  

+  )

+/*++

+

+Routine Description:

+

+  Closes a protocol on a handle that was opened using OpenProtocol().

+

+Arguments:

+

+  UserHandle       -  The handle for the protocol interface that was previously opened

+                      with OpenProtocol(), and is now being closed.

+  Protocol         -  The published unique identifier of the protocol. It is the caller¡¯s

+                      responsibility to pass in a valid GUID.

+  AgentHandle      -  The handle of the agent that is closing the protocol interface.

+  ControllerHandle -  If the agent that opened a protocol is a driver that follows the

+                      EFI Driver Model, then this parameter is the controller handle

+                      that required the protocol interface. If the agent does not follow

+                      the EFI Driver Model, then this parameter is optional and may be NULL.

+

+Returns:

+

+  EFI_SUCCESS             - The protocol instance was closed.

+  EFI_INVALID_PARAMETER   - Handle, AgentHandle or ControllerHandle is not a valid EFI_HANDLE. 

+  EFI_NOT_FOUND           - Can not find the specified protocol or AgentHandle.

+  

+--*/

+{

+  EFI_STATUS          Status;

+  PROTOCOL_INTERFACE  *ProtocolInterface;

+  LIST_ENTRY          *Link;

+  OPEN_PROTOCOL_DATA  *OpenData;

+

+  //

+  // Check for invalid parameters

+  //

+  Status = CoreValidateHandle (UserHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  Status = CoreValidateHandle (AgentHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  if (ControllerHandle != NULL_HANDLE) {

+    Status = CoreValidateHandle (ControllerHandle);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  if (Protocol == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  //

+  // Look at each protocol interface for a match

+  //

+  Status = EFI_NOT_FOUND;

+  ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol);

+  if (ProtocolInterface == NULL) {

+    goto Done;

+  }

+

+  //

+  // Walk the Open data base looking for AgentHandle

+  //

+  Link = ProtocolInterface->OpenList.ForwardLink;

+  while (Link != &ProtocolInterface->OpenList) {

+    OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+    Link = Link->ForwardLink;

+    if ((OpenData->AgentHandle == AgentHandle) && (OpenData->ControllerHandle == ControllerHandle)) {

+        RemoveEntryList (&OpenData->Link);  

+        ProtocolInterface->OpenListCount--;

+        CoreFreePool (OpenData);

+        Status = EFI_SUCCESS;

+    }

+  }

+

+Done:

+  //

+  // Done. Release the database lock and return.

+  //

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreOpenProtocolInformation (

+  IN  EFI_HANDLE                          UserHandle,

+  IN  EFI_GUID                            *Protocol,

+  OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,

+  OUT UINTN                               *EntryCount

+  )

+/*++

+

+Routine Description:

+

+  Return information about Opened protocols in the system

+

+Arguments:

+

+  UserHandle  - The handle to close the protocol interface on

+

+  Protocol    - The ID of the protocol 

+

+  EntryBuffer - A pointer to a buffer of open protocol information in the form of

+                EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.

+

+  EntryCount  - Number of EntryBuffer entries

+

+Returns:

+

+  

+--*/

+{

+  EFI_STATUS                          Status;

+  PROTOCOL_INTERFACE                  *ProtocolInterface;

+  LIST_ENTRY                          *Link;

+  OPEN_PROTOCOL_DATA                  *OpenData;

+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Buffer;

+  UINTN                               Count;

+  UINTN                               Size;

+

+  *EntryBuffer = NULL;

+  *EntryCount = 0;

+

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  //

+  // Look at each protocol interface for a match

+  //

+  Status = EFI_NOT_FOUND;

+  ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol);

+  if (ProtocolInterface == NULL) {

+    goto Done;

+  }

+

+  //

+  // Count the number of Open Entries

+  //

+  for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0; 

+        (Link != &ProtocolInterface->OpenList) ;

+        Link = Link->ForwardLink  ) {

+    Count++;

+  } 

+

+  ASSERT (Count == ProtocolInterface->OpenListCount);

+

+  if (Count == 0) {

+    Size = sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);

+  } else {

+    Size = Count * sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);

+  }

+

+  Buffer = CoreAllocateBootServicesPool (Size);

+  if (Buffer == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  Status = EFI_SUCCESS;

+  for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0; 

+        (Link != &ProtocolInterface->OpenList);

+        Link = Link->ForwardLink, Count++  ) {

+    OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);

+

+    Buffer[Count].AgentHandle      = OpenData->AgentHandle;

+    Buffer[Count].ControllerHandle = OpenData->ControllerHandle;

+    Buffer[Count].Attributes       = OpenData->Attributes;

+    Buffer[Count].OpenCount        = OpenData->OpenCount;

+  } 

+

+  *EntryBuffer = Buffer;

+  *EntryCount = Count;

+        

+Done:

+  //

+  // Done. Release the database lock are return

+  //

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreProtocolsPerHandle (

+  IN EFI_HANDLE       UserHandle,

+  OUT EFI_GUID        ***ProtocolBuffer,

+  OUT UINTN           *ProtocolBufferCount

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated

+ from pool.

+

+Arguments:

+

+  UserHandle           - The handle from which to retrieve the list of protocol interface

+                          GUIDs.

+

+  ProtocolBuffer       - A pointer to the list of protocol interface GUID pointers that are

+                          installed on Handle.

+

+  ProtocolBufferCount  - A pointer to the number of GUID pointers present in

+                          ProtocolBuffer.

+

+Returns:

+  EFI_SUCCESS   -  The list of protocol interface GUIDs installed on Handle was returned in

+                   ProtocolBuffer. The number of protocol interface GUIDs was

+                   returned in ProtocolBufferCount.

+  EFI_INVALID_PARAMETER   -  Handle is NULL.

+  EFI_INVALID_PARAMETER   -  Handle is not a valid EFI_HANDLE.

+  EFI_INVALID_PARAMETER   -  ProtocolBuffer is NULL.

+  EFI_INVALID_PARAMETER   -  ProtocolBufferCount is NULL.

+  EFI_OUT_OF_RESOURCES    -  There is not enough pool memory to store the results.

+  

+--*/

+{

+  EFI_STATUS                          Status;

+  IHANDLE                             *Handle;

+  PROTOCOL_INTERFACE                  *Prot;

+  LIST_ENTRY                          *Link;

+  UINTN                               ProtocolCount;

+  EFI_GUID                            **Buffer;

+

+  Status = CoreValidateHandle (UserHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Handle = (IHANDLE *)UserHandle;

+

+  if (ProtocolBuffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (ProtocolBufferCount == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *ProtocolBufferCount = 0;

+

+  ProtocolCount = 0;

+

+  CoreAcquireProtocolLock ();

+  

+  for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {

+    ProtocolCount++;

+  }

+

+  //

+  // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE

+  //

+  if (ProtocolCount == 0) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  Buffer = CoreAllocateBootServicesPool (sizeof (EFI_GUID *) * ProtocolCount);

+  if (Buffer == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  *ProtocolBuffer = Buffer;

+  *ProtocolBufferCount = ProtocolCount;

+

+  for ( Link = Handle->Protocols.ForwardLink, ProtocolCount = 0;

+        Link != &Handle->Protocols; 

+        Link = Link->ForwardLink, ProtocolCount++) {

+    Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);

+    Buffer[ProtocolCount] = &(Prot->Protocol->ProtocolID);

+  }

+  Status = EFI_SUCCESS;

+

+Done:

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+UINT64

+CoreGetHandleDatabaseKey (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  return handle database key.

+

+Arguments:

+

+  None

+  

+Returns:

+  

+  Handle database key.

+  

+--*/

+{

+  return gHandleDatabaseKey;

+}

+

+

+VOID

+CoreConnectHandlesByKey (

+  UINT64  Key

+  )

+/*++

+

+Routine Description:

+

+  Go connect any handles that were created or modified while a image executed.

+

+Arguments:

+

+  Key  -  The Key to show that the handle has been created/modified

+

+Returns:

+  

+  None

+--*/

+{

+  UINTN           Count;

+  LIST_ENTRY      *Link;

+  EFI_HANDLE      *HandleBuffer;

+  IHANDLE         *Handle;

+  UINTN           Index;

+

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) {

+    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);

+    if (Handle->Key > Key) {

+      Count++;

+    }

+  }

+

+  HandleBuffer = CoreAllocateBootServicesPool (Count * sizeof (EFI_HANDLE));

+  if (HandleBuffer == NULL) {

+    CoreReleaseProtocolLock ();

+    return;

+  }

+  

+  for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) {

+    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);

+    if (Handle->Key > Key) {

+      HandleBuffer[Count++] = Handle;

+    }

+  }

+

+  //

+  // Unlock the protocol database

+  //

+  CoreReleaseProtocolLock ();

+

+  //

+  // Connect all handles whose Key value is greater than Key

+  //

+  for (Index = 0; Index < Count; Index++) {

+    CoreConnectController (HandleBuffer[Index], NULL, NULL, TRUE);

+  }

+  

+  CoreFreePool(HandleBuffer);

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Hand/locate.c b/edk2/EdkModulePkg/Core/Dxe/Hand/locate.c
new file mode 100644
index 0000000..faa4255
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Hand/locate.c
@@ -0,0 +1,737 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  locate.c

+

+Abstract:

+

+  Locate handle functions    

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+//

+// ProtocolRequest - Last LocateHandle request ID

+//

+UINTN mEfiLocateHandleRequest = 0;

+

+//

+// Internal prototypes

+//

+

+typedef struct {

+  EFI_GUID        *Protocol;

+  VOID            *SearchKey;

+  LIST_ENTRY      *Position;

+  PROTOCOL_ENTRY  *ProtEntry;

+} LOCATE_POSITION;

+

+typedef 

+IHANDLE *

+(* CORE_GET_NEXT) (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  );

+

+STATIC

+IHANDLE *

+CoreGetNextLocateAllHandles (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  );

+

+STATIC

+IHANDLE *

+CoreGetNextLocateByRegisterNotify (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  );

+

+STATIC

+IHANDLE *

+CoreGetNextLocateByProtocol (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  );

+

+//

+//

+//

+

+

+

+ 

+EFI_STATUS

+EFIAPI

+CoreLocateHandle (

+  IN EFI_LOCATE_SEARCH_TYPE   SearchType,

+  IN EFI_GUID                 *Protocol   OPTIONAL,

+  IN VOID                     *SearchKey  OPTIONAL,

+  IN OUT UINTN                *BufferSize,

+  OUT EFI_HANDLE              *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Locates the requested handle(s) and returns them in Buffer.

+

+Arguments:

+

+  SearchType  - The type of search to perform to locate the handles

+

+  Protocol    - The protocol to search for

+  

+  SearchKey   - Dependant on SearchType

+

+  BufferSize  - On input the size of Buffer.  On output the 

+                size of data returned.  

+

+  Buffer      - The buffer to return the results in

+

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL      - Buffer too small, required buffer size is returned in BufferSize.

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+  

+  EFI_SUCCESS               - Successfully found the requested handle(s) and returns them in Buffer.

+  

+--*/

+{

+  EFI_STATUS          Status;

+  LOCATE_POSITION     Position;

+  PROTOCOL_NOTIFY     *ProtNotify;

+  CORE_GET_NEXT       GetNext;

+  UINTN               ResultSize;

+  IHANDLE             *Handle;

+  IHANDLE             **ResultBuffer;

+  VOID                *Interface;

+ 

+  if (BufferSize == NULL) {

+    Status = EFI_INVALID_PARAMETER;

+  }

+  

+  if ((*BufferSize > 0) && (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  GetNext = NULL;

+  //

+  // Set initial position

+  //

+

+  Position.Protocol  = Protocol;

+  Position.SearchKey = SearchKey;

+  Position.Position  = &gHandleList;

+

+  ResultSize = 0;

+  ResultBuffer = (IHANDLE **) Buffer;

+  Status = EFI_SUCCESS;

+

+  //

+  // Lock the protocol database

+  //

+  

+  CoreAcquireProtocolLock ();

+

+  //

+  // Get the search function based on type

+  //

+  switch (SearchType) {

+  case AllHandles:      

+    GetNext = CoreGetNextLocateAllHandles;       

+    break;

+

+  case ByRegisterNotify:    

+    //

+    // Must have SearchKey for locate ByRegisterNotify

+    //

+    if (SearchKey == NULL) {

+      Status = EFI_INVALID_PARAMETER;

+      break;

+    }

+    GetNext = CoreGetNextLocateByRegisterNotify;   

+    break;

+

+  case ByProtocol:      

+    GetNext = CoreGetNextLocateByProtocol;

+    if (Protocol == NULL) {

+      Status = EFI_INVALID_PARAMETER;

+      break;

+    }

+    //

+    // Look up the protocol entry and set the head pointer

+    //

+    Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);

+    if (Position.ProtEntry == NULL) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+    Position.Position = &Position.ProtEntry->Protocols;

+    break;

+

+  default:

+    Status = EFI_INVALID_PARAMETER;

+    break;

+  }

+

+  if (EFI_ERROR(Status)) {

+    CoreReleaseProtocolLock ();

+    return Status;

+  }

+

+  //

+  // Enumerate out the matching handles

+  //

+  mEfiLocateHandleRequest += 1;

+  for (; ;) {

+    //

+    // Get the next handle.  If no more handles, stop

+    //

+    Handle = GetNext (&Position, &Interface);

+    if (NULL == Handle) {

+      break;

+    }

+

+    //

+    // Increase the resulting buffer size, and if this handle

+    // fits return it

+    //

+    ResultSize += sizeof(Handle);

+    if (ResultSize <= *BufferSize) {

+        *ResultBuffer = Handle;

+        ResultBuffer += 1;

+    }

+  }

+

+  //

+  // If the result is a zero length buffer, then there were no

+  // matching handles

+  //

+  if (ResultSize == 0) {

+    Status = EFI_NOT_FOUND;

+  } else {

+    //

+    // Return the resulting buffer size.  If it's larger than what

+    // was passed, then set the error code

+    //

+    if (ResultSize > *BufferSize) {

+      Status = EFI_BUFFER_TOO_SMALL;

+    } 

+    

+    *BufferSize = ResultSize;

+

+    if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {

+      //

+      // If this is a search by register notify and a handle was

+      // returned, update the register notification position

+      // 

+      ProtNotify = SearchKey;

+      ProtNotify->Position = ProtNotify->Position->ForwardLink;

+    }

+  }

+

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+STATIC

+IHANDLE *

+CoreGetNextLocateAllHandles (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  )

+/*++

+

+Routine Description:

+

+  Routine to get the next Handle, when you are searching for all handles.

+

+Arguments:

+

+  Position  - Information about which Handle to seach for.

+

+  Interface - Return the interface structure for the matching protocol.

+  

+Returns:

+  IHANDLE - An IHANDLE is returned if the next Position is not the end of the

+            list. A NULL_HANDLE is returned if it's the end of the list.

+  

+--*/

+{

+  IHANDLE     *Handle;

+

+  //

+  // Next handle

+  //

+  Position->Position = Position->Position->ForwardLink;

+

+  //

+  // If not at the end of the list, get the handle

+  //

+  Handle      = NULL_HANDLE;

+  *Interface  = NULL;

+  if (Position->Position != &gHandleList) {

+    Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);

+  }

+

+  return Handle;

+}

+

+

+STATIC

+IHANDLE *

+CoreGetNextLocateByRegisterNotify (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  )

+/*++

+

+Routine Description:

+

+  Routine to get the next Handle, when you are searching for register protocol 

+  notifies.

+

+Arguments:

+

+  Position  - Information about which Handle to seach for.

+

+  Interface - Return the interface structure for the matching protocol.

+  

+Returns:

+  IHANDLE - An IHANDLE is returned if the next Position is not the end of the

+            list. A NULL_HANDLE is returned if it's the end of the list.

+  

+--*/

+{

+  IHANDLE             *Handle;

+  PROTOCOL_NOTIFY     *ProtNotify;

+  PROTOCOL_INTERFACE  *Prot;

+  LIST_ENTRY          *Link;    

+

+  Handle      = NULL_HANDLE;

+  *Interface  = NULL;

+  ProtNotify = Position->SearchKey;

+

+  //

+  // If this is the first request, get the next handle

+  //

+  if (ProtNotify != NULL) {

+    ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);

+    Position->SearchKey = NULL;

+

+    //

+    // If not at the end of the list, get the next handle

+    //

+    Link = ProtNotify->Position->ForwardLink;

+    if (Link != &ProtNotify->Protocol->Protocols) {

+      Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);

+      Handle = (IHANDLE *) Prot->Handle;

+      *Interface = Prot->Interface;

+    }  

+  }

+

+  return Handle;

+}

+

+

+STATIC

+IHANDLE *

+CoreGetNextLocateByProtocol (

+  IN OUT LOCATE_POSITION    *Position,

+  OUT VOID                  **Interface

+  )

+/*++

+

+Routine Description:

+

+  Routine to get the next Handle, when you are searching for a given protocol.

+

+Arguments:

+

+  Position  - Information about which Handle to seach for.

+

+  Interface - Return the interface structure for the matching protocol.

+  

+Returns:

+  IHANDLE - An IHANDLE is returned if the next Position is not the end of the

+            list. A NULL_HANDLE is returned if it's the end of the list.

+  

+--*/

+{

+  IHANDLE             *Handle;

+  LIST_ENTRY          *Link;

+  PROTOCOL_INTERFACE  *Prot;

+ 

+  Handle      = NULL_HANDLE;

+  *Interface  = NULL;

+  for (; ;) {

+    //

+    // Next entry

+    //

+    Link = Position->Position->ForwardLink;

+    Position->Position = Link;

+

+    //

+    // If not at the end, return the handle

+    //

+    if (Link == &Position->ProtEntry->Protocols) {

+      Handle = NULL_HANDLE;

+      break;

+    }

+

+    //

+    // Get the handle

+    //

+    Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);

+    Handle = (IHANDLE *) Prot->Handle;

+    *Interface = Prot->Interface;

+

+    //

+    // If this handle has not been returned this request, then 

+    // return it now

+    //

+    if (Handle->LocateRequest != mEfiLocateHandleRequest) {

+      Handle->LocateRequest = mEfiLocateHandleRequest;

+      break;

+    }

+  }

+

+  return Handle;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreLocateDevicePath (

+  IN EFI_GUID                       *Protocol,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL   **DevicePath,

+  OUT EFI_HANDLE                    *Device

+  )

+/*++

+

+Routine Description:

+

+  Locates the handle to a device on the device path that best matches the specified protocol.

+

+Arguments:

+

+  Protocol    - The protocol to search for.

+  DevicePath  - On input, a pointer to a pointer to the device path. On output, the device

+                  path pointer is modified to point to the remaining part of the devicepath.

+  Device      - A pointer to the returned device handle.              

+

+Returns:

+

+  EFI_SUCCESS           - The resulting handle was returned.

+  EFI_NOT_FOUND         - No handles matched the search.

+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value.

+

+--*/

+{

+  INTN                        SourceSize;

+  INTN                        Size;

+  INTN                        BestMatch;

+  UINTN                       HandleCount;

+  UINTN                       Index;

+  EFI_STATUS                  Status;

+  EFI_HANDLE                  *Handles;

+  EFI_HANDLE                  Handle;

+  EFI_DEVICE_PATH_PROTOCOL    *SourcePath;

+  EFI_DEVICE_PATH_PROTOCOL    *TmpDevicePath;

+  

+  if (Protocol == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  if ((DevicePath == NULL) || (*DevicePath == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  if (Device == NULL) {

+    return  EFI_INVALID_PARAMETER;

+  }

+  

+  *Device = NULL_HANDLE;

+  SourcePath = *DevicePath;

+  SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);

+  

+  //

+  // The source path can only have 1 instance

+  //

+  if (CoreIsDevicePathMultiInstance (SourcePath)) {

+    DEBUG((EFI_D_ERROR, "LocateDevicePath: Device path has too many instances\n"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Get a list of all handles that support the requested protocol

+  //

+  Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);

+  if (EFI_ERROR (Status) || HandleCount == 0) {

+    return EFI_NOT_FOUND;

+  }

+

+  BestMatch = -1;

+  for(Index = 0; Index < HandleCount; Index += 1) {

+    Handle = Handles[Index];

+    Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath);

+    if (EFI_ERROR (Status)) {

+      //

+      // If this handle doesn't support device path, then skip it

+      //

+      continue;

+    }

+

+    //

+    // Check if DevicePath is first part of SourcePath

+    //

+    Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);

+    if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) {

+      //

+      // If the size is equal to the best match, then we

+      // have a duplice device path for 2 different device

+      // handles

+      //

+      ASSERT (Size != BestMatch);

+      

+      //

+      // We've got a match, see if it's the best match so far

+      //

+      if (Size > BestMatch) {

+        BestMatch = Size;

+        *Device = Handle;

+      }

+    }

+  }

+

+  CoreFreePool (Handles);

+   

+  //

+  // If there wasn't any match, then no parts of the device path was found.  

+  // Which is strange since there is likely a "root level" device path in the system.

+  //

+  if (BestMatch == -1) {

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Return the remaining part of the device path

+  //

+  *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch);

+  return EFI_SUCCESS;

+}

+

+

+ 

+EFI_STATUS

+EFIAPI

+CoreLocateProtocol (

+  IN  EFI_GUID  *Protocol,

+  IN  VOID      *Registration OPTIONAL,

+  OUT VOID      **Interface

+  )

+/*++

+

+Routine Description:

+

+  Return the first Protocol Interface that matches the Protocol GUID. If

+  Registration is pasased in return a Protocol Instance that was just add

+  to the system. If Retistration is NULL return the first Protocol Interface

+  you find.

+

+Arguments:

+

+  Protocol     - The protocol to search for

+  

+  Registration - Optional Registration Key returned from RegisterProtocolNotify() 

+

+  Interface    - Return the Protocol interface (instance).

+

+Returns:

+

+  EFI_SUCCESS - If a valid Interface is returned

+  

+  EFI_INVALID_PARAMETER       - Invalid parameter

+  

+  EFI_NOT_FOUND               - Protocol interface not found

+

+--*/

+{

+  EFI_STATUS              Status;

+  LOCATE_POSITION         Position;

+  PROTOCOL_NOTIFY         *ProtNotify;

+  IHANDLE                 *Handle;

+

+  if (Interface == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  if (Protocol == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  

+  *Interface = NULL;

+  Status = EFI_SUCCESS;

+

+  //

+  // Set initial position

+  //

+  Position.Protocol  = Protocol;

+  Position.SearchKey = Registration;

+  Position.Position  = &gHandleList;

+  

+  //

+  // Lock the protocol database

+  //

+  CoreAcquireProtocolLock ();

+

+  mEfiLocateHandleRequest += 1;

+

+  if (NULL == Registration) {

+    //

+    // Look up the protocol entry and set the head pointer

+    //

+    Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);

+    if (Position.ProtEntry == NULL) {

+      Status = EFI_NOT_FOUND;

+      goto Done;

+    }

+    Position.Position = &Position.ProtEntry->Protocols;

+

+    Handle = CoreGetNextLocateByProtocol (&Position, Interface);

+  } else {

+    Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface);   

+  }

+

+  if (NULL == Handle) {

+    Status = EFI_NOT_FOUND;

+  } else if (NULL != Registration) {

+    //

+    // If this is a search by register notify and a handle was

+    // returned, update the register notification position

+    // 

+    ProtNotify = Registration;

+    ProtNotify->Position = ProtNotify->Position->ForwardLink;

+  }

+

+Done:

+  CoreReleaseProtocolLock ();

+  return Status;

+}

+

+

+ 

+EFI_STATUS

+EFIAPI

+CoreLocateHandleBuffer (

+  IN EFI_LOCATE_SEARCH_TYPE       SearchType,

+  IN EFI_GUID                     *Protocol OPTIONAL,

+  IN VOID                         *SearchKey OPTIONAL,

+  IN OUT UINTN                    *NumberHandles,

+  OUT EFI_HANDLE                  **Buffer

+  )

+/*++

+

+Routine Description:

+

+  Function returns an array of handles that support the requested protocol 

+  in a buffer allocated from pool. This is a version of CoreLocateHandle()

+  that allocates a buffer for the caller.

+

+Arguments:

+

+  SearchType           - Specifies which handle(s) are to be returned.

+  Protocol             - Provides the protocol to search by.   

+                         This parameter is only valid for SearchType ByProtocol.

+  SearchKey            - Supplies the search key depending on the SearchType.

+  NumberHandles      - The number of handles returned in Buffer.

+  Buffer               - A pointer to the buffer to return the requested array of 

+                         handles that support Protocol.

+

+Returns:

+  

+  EFI_SUCCESS          - The result array of handles was returned.

+  EFI_NOT_FOUND        - No handles match the search. 

+  EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the matching results.

+  EFI_INVALID_PARAMETER   - Invalid parameter

+

+--*/

+{

+  EFI_STATUS          Status;

+  UINTN               BufferSize;

+

+  if (NumberHandles == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  BufferSize = 0;

+  *NumberHandles = 0;

+  *Buffer = NULL;

+  Status = CoreLocateHandle (

+             SearchType,

+             Protocol,

+             SearchKey,

+             &BufferSize,

+             *Buffer

+             );

+  //

+  // LocateHandleBuffer() returns incorrect status code if SearchType is

+  // invalid.

+  //

+  // Add code to correctly handle expected errors from CoreLocateHandle().

+  //

+  if (EFI_ERROR(Status)) {

+    switch (Status) {

+    case EFI_BUFFER_TOO_SMALL:

+      break;

+    case EFI_INVALID_PARAMETER:

+      return Status;

+    default:

+      return EFI_NOT_FOUND;

+    }

+  }

+

+  *Buffer = CoreAllocateBootServicesPool (BufferSize);

+  if (*Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = CoreLocateHandle (

+             SearchType,

+             Protocol,

+             SearchKey,

+             &BufferSize,

+             *Buffer

+             );

+

+  *NumberHandles = BufferSize/sizeof(EFI_HANDLE);

+  if (EFI_ERROR(Status)) {

+    *NumberHandles = 0;

+  }

+

+  return Status;

+}

+

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/Image.h b/edk2/EdkModulePkg/Core/Dxe/Image.h
new file mode 100644
index 0000000..067d42d
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Image.h
@@ -0,0 +1,380 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  Image.h

+

+Abstract:

+

+Revision History

+

+--*/

+

+

+#ifndef _IMAGE_H_

+#define _IMAGE_H_

+

+

+

+#define LOADED_IMAGE_PRIVATE_DATA_SIGNATURE   EFI_SIGNATURE_32('l','d','r','i')

+

+typedef struct {

+    UINTN                       Signature;

+    EFI_HANDLE                  Handle;         // Image handle

+    UINTN                       Type;           // Image type

+

+    BOOLEAN                     Started;        // If entrypoint has been called

+

+    EFI_IMAGE_ENTRY_POINT       EntryPoint;     // The image's entry point

+    EFI_LOADED_IMAGE_PROTOCOL   Info;           // loaded image protocol

+

+    EFI_PHYSICAL_ADDRESS        ImageBasePage;  // Location in memory

+    UINTN                       NumberOfPages;  // Number of pages

+

+    CHAR8                       *FixupData;     // Original fixup data

+

+    EFI_TPL                     Tpl;            // Tpl of started image

+    EFI_STATUS                  Status;         // Status returned by started image

+

+    UINTN                       ExitDataSize;   // Size of ExitData from started image

+    VOID                        *ExitData;      // Pointer to exit data from started image

+    BASE_LIBRARY_JUMP_BUFFER    *JumpContext;   // Pointer to buffer for context save/retore

+    UINT16                      Machine;        // Machine type from PE image

+

+    EFI_EBC_PROTOCOL            *Ebc;           // EBC Protocol pointer

+

+    BOOLEAN                     RuntimeFixupValid; // True if RT image needs fixup

+    VOID                        *RuntimeFixup;     // Copy of fixup data;

+    LIST_ENTRY                  Link;              // List of RT LOADED_IMAGE_PRIVATE_DATA

+

+    PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;     // PeCoffLoader ImageContext

+

+} LOADED_IMAGE_PRIVATE_DATA;

+

+#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \

+          CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)

+

+

+

+#define LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32('l','p','e','i')

+

+typedef struct {

+    UINTN                       Signature;

+    EFI_HANDLE                  Handle;         // Image handle

+    EFI_PE32_IMAGE_PROTOCOL     Pe32Image;

+} LOAD_PE32_IMAGE_PRIVATE_DATA;

+

+#define LOAD_PE32_IMAGE_PRIVATE_DATA_FROM_THIS(a) \

+          CR(a, LOAD_PE32_IMAGE_PRIVATE_DATA, Pe32Image, LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE)

+

+

+

+//

+// Private Data Types

+//

+#define IMAGE_FILE_HANDLE_SIGNATURE       EFI_SIGNATURE_32('i','m','g','f')

+typedef struct {

+  UINTN               Signature;

+  BOOLEAN             FreeBuffer;

+  VOID                *Source;

+  UINTN               SourceSize;

+} IMAGE_FILE_HANDLE;

+

+

+//

+// Abstractions for reading image contents

+//

+

+EFI_STATUS

+CoreOpenImageFile (

+  IN BOOLEAN                        BootPolicy,

+  IN VOID                           *SourceBuffer   OPTIONAL,

+  IN UINTN                          SourceSize,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL   *FilePath,

+  OUT EFI_HANDLE                    *DeviceHandle,

+  IN IMAGE_FILE_HANDLE              *ImageFileHandle,

+  OUT UINT32                        *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+

+    Opens a file for (simple) reading.  The simple read abstraction

+    will access the file either from a memory copy, from a file

+    system interface, or from the load file interface.

+

+Arguments:

+

+  BootPolicy    - Policy for Open Image File.

+  SourceBuffer  - Pointer to the memory location containing copy

+                  of the image to be loaded.

+  SourceSize    - The size in bytes of SourceBuffer.

+  FilePath      - The specific file path from which the image is loaded

+  DeviceHandle  - Pointer to the return device handle.

+  ImageFileHandle      - Pointer to the image file handle.

+  AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned.

+

+Returns:

+

+    A handle to access the file

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+CoreReadImageFile (

+  IN     VOID     *UserHandle,

+  IN     UINTN    Offset,

+  IN OUT UINTN    *ReadSize,

+  OUT     VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Read image file (specified by UserHandle) into user specified buffer with specified offset

+  and length.

+

+Arguments:

+

+  UserHandle      - Image file handle

+

+  Offset          - Offset to the source file

+

+  ReadSize        - For input, pointer of size to read;

+                    For output, pointer of size actually read.

+

+  Buffer          - Buffer to write into

+

+Returns:

+

+  EFI_SUCCESS     - Successfully read the specified part of file into buffer.

+

+--*/

+;

+

+VOID

+EFIAPI

+CoreCloseImageFile (

+  IN IMAGE_FILE_HANDLE *ImageFileHandle

+  )

+/*++

+

+Routine Description:

+

+  A function out of date, should be removed.

+

+Arguments:

+

+  ImageFileHandle    - Handle of the file to close

+

+Returns:

+

+  None

+

+--*/

+;

+

+//

+// Image processing worker functions

+//

+EFI_STATUS

+CoreDevicePathToInterface (

+  IN EFI_GUID                     *Protocol,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,

+  OUT VOID                        **Interface,

+  OUT EFI_HANDLE                  *Handle

+  )

+/*++

+

+Routine Description:

+

+  Search a handle to a device on a specified device path that supports a specified protocol,

+  interface of that protocol on that handle is another output.

+

+Arguments:

+

+  Protocol      - The protocol to search for

+

+  FilePath      - The specified device path

+

+  Interface     - Interface of the protocol on the handle

+

+  Handle        - The handle to the device on the specified device path that supports the protocol.

+

+Returns:

+

+  Status code.

+

+--*/

+;

+

+EFI_STATUS

+CoreLoadPeImage (

+  IN  VOID                       *Pe32Handle,

+  IN  LOADED_IMAGE_PRIVATE_DATA  *Image,

+  IN  EFI_PHYSICAL_ADDRESS       DstBuffer   OPTIONAL,

+  OUT EFI_PHYSICAL_ADDRESS       *EntryPoint  OPTIONAL,

+  IN  UINT32                     Attribute

+  )

+/*++

+

+Routine Description:

+

+  Loads, relocates, and invokes a PE/COFF image

+

+Arguments:

+

+  Pe32Handle       - The handle of PE32 image

+  Image            - PE image to be loaded

+  DstBuffer        - The buffer to store the image

+  EntryPoint       - A pointer to the entry point

+  Attribute        - The bit mask of attributes to set for the load PE image

+

+Returns:

+

+  EFI_SUCCESS           - The file was loaded, relocated, and invoked

+

+  EFI_OUT_OF_RESOURCES  - There was not enough memory to load and relocate the PE/COFF file

+

+  EFI_INVALID_PARAMETER - Invalid parameter

+

+  EFI_BUFFER_TOO_SMALL  - Buffer for image is too small

+

+--*/

+;

+

+LOADED_IMAGE_PRIVATE_DATA *

+CoreLoadedImageInfo (

+  IN EFI_HANDLE  ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+CoreUnloadAndCloseImage (

+  IN LOADED_IMAGE_PRIVATE_DATA  *Image,

+  IN BOOLEAN                    FreePage

+  )

+/*++

+

+Routine Description:

+

+  Unloads EFI image from memory.

+

+Arguments:

+

+  Image      - EFI image

+  FreePage   - Free allocated pages

+

+Returns:

+

+  None

+

+--*/

+;

+

+

+//

+// Exported Image functions

+//

+

+EFI_STATUS

+EFIAPI

+CoreLoadImageEx (

+  IN EFI_PE32_IMAGE_PROTOCOL           *This,

+  IN  EFI_HANDLE                       ParentImageHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN  VOID                             *SourceBuffer       OPTIONAL,

+  IN  UINTN                            SourceSize,

+  IN  EFI_PHYSICAL_ADDRESS             DstBuffer           OPTIONAL,

+  OUT UINTN                            *NumberOfPages      OPTIONAL,

+  OUT EFI_HANDLE                       *ImageHandle,

+  OUT EFI_PHYSICAL_ADDRESS             *EntryPoint         OPTIONAL,

+  IN  UINT32                           Attribute

+  )

+/*++

+

+Routine Description:

+

+  Loads an EFI image into memory and returns a handle to the image with extended parameters.

+

+Arguments:

+

+  ParentImageHandle   - The caller's image handle.

+  FilePath            - The specific file path from which the image is loaded.

+  SourceBuffer        - If not NULL, a pointer to the memory location containing a copy of

+                        the image to be loaded.

+  SourceSize          - The size in bytes of SourceBuffer.

+  DstBuffer           - The buffer to store the image.

+  NumberOfPages       - For input, specifies the space size of the image by caller if not NULL.

+                        For output, specifies the actual space size needed.

+  ImageHandle         - Image handle for output.

+  EntryPoint          - Image entry point for output.

+  Attribute           - The bit mask of attributes to set for the load PE image.

+

+Returns:

+

+  EFI_SUCCESS            - The image was loaded into memory.

+  EFI_NOT_FOUND          - The FilePath was not found.

+  EFI_INVALID_PARAMETER  - One of the parameters has an invalid value.

+  EFI_UNSUPPORTED        - The image type is not supported, or the device path cannot be

+                           parsed to locate the proper protocol for loading the file.

+  EFI_OUT_OF_RESOURCES   - Image was not loaded due to insufficient resources.

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+CoreUnloadImageEx (

+  IN EFI_PE32_IMAGE_PROTOCOL            *This,

+  IN EFI_HANDLE                         ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Unload the specified image.

+

+Arguments:

+

+  This              - Indicates the calling context.

+

+  ImageHandle       - The specified image handle.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Image handle is NULL.

+

+  EFI_UNSUPPORTED             - Attempt to unload an unsupported image.

+

+  EFI_SUCCESS                 - Image successfully unloaded.

+

+--*/

+;

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/Image/Image.c b/edk2/EdkModulePkg/Core/Dxe/Image/Image.c
new file mode 100644
index 0000000..c818cc2
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Image/Image.c
@@ -0,0 +1,1377 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  Image.c

+

+Abstract:

+

+  Core image handling services

+

+--*/

+

+#include <DxeMain.h>

+//

+// Module Globals

+//

+

+//

+// LIST of runtime images that need to be relocated.

+//

+LIST_ENTRY                 mRuntimeImageList = INITIALIZE_LIST_HEAD_VARIABLE (mRuntimeImageList);

+

+LOADED_IMAGE_PRIVATE_DATA  *mCurrentImage = NULL;

+

+LOAD_PE32_IMAGE_PRIVATE_DATA  mLoadPe32PrivateData = {

+  LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE,

+  NULL,

+  {

+    CoreLoadImageEx,

+    CoreUnloadImageEx

+  }

+};

+

+

+//

+// This code is needed to build the Image handle for the DXE Core

+//

+LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage  = {

+  LOADED_IMAGE_PRIVATE_DATA_SIGNATURE,            // Signature

+  NULL,                                           // Image handle

+  EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,    // Image type

+  TRUE,                                           // If entrypoint has been called

+  NULL, // EntryPoint

+  {

+    EFI_LOADED_IMAGE_INFORMATION_REVISION,        // Revision

+    NULL,                                         // Parent handle

+    NULL,                                         // System handle

+

+    NULL,                                         // Device handle

+    NULL,                                         // File path

+    NULL,                                         // Reserved

+

+    0,                                            // LoadOptionsSize

+    NULL,                                         // LoadOptions

+

+    NULL,                                         // ImageBase

+    0,                                            // ImageSize

+    EfiBootServicesCode,                          // ImageCodeType

+    EfiBootServicesData                           // ImageDataType

+  },

+  (EFI_PHYSICAL_ADDRESS)0,    // ImageBasePage

+  0,                          // NumberOfPages

+  NULL,                       // FixupData

+  0,                          // Tpl

+  EFI_SUCCESS,                // Status

+  0,                          // ExitDataSize

+  NULL,                       // ExitData

+  NULL,                       // JumpContext

+  0,                          // Machine

+  NULL,                       // Ebc

+  FALSE,                      // RuntimeFixupValid

+  NULL,                       // RuntimeFixup

+  { NULL, NULL },             // Link

+};

+

+

+EFI_STATUS

+CoreInitializeImageServices (

+  IN  VOID *HobStart

+  )

+/*++

+

+Routine Description:

+

+  Add the Image Services to EFI Boot Services Table and install the protocol

+  interfaces for this image.

+

+Arguments:

+

+  HobStart        - The HOB to initialize

+

+Returns:

+

+  Status code.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  LOADED_IMAGE_PRIVATE_DATA         *Image;

+  EFI_PHYSICAL_ADDRESS              DxeCoreImageBaseAddress;

+  UINT64                            DxeCoreImageLength;

+  VOID                              *DxeCoreEntryPoint;

+  EFI_PEI_HOB_POINTERS              DxeCoreHob;

+  //

+  // Searching for image hob

+  //

+  DxeCoreHob.Raw          = HobStart;

+  while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) {

+    if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {

+      //

+      // Find Dxe Core HOB

+      //

+      break;

+    }

+    DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob);

+  }

+  ASSERT (DxeCoreHob.Raw != NULL);

+

+  DxeCoreImageBaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;

+  DxeCoreImageLength      = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength;

+  DxeCoreEntryPoint       = (VOID *) (UINTN) DxeCoreHob.MemoryAllocationModule->EntryPoint;

+  gDxeCoreFileName        = &DxeCoreHob.MemoryAllocationModule->ModuleName;

+  //

+  // Initialize the fields for an internal driver

+  //

+  Image = &mCorePrivateImage;

+

+  Image->EntryPoint         = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint;

+  Image->ImageBasePage      = DxeCoreImageBaseAddress;

+  Image->NumberOfPages      = (UINTN)(EFI_SIZE_TO_PAGES((UINTN)(DxeCoreImageLength)));

+  Image->Tpl                = gEfiCurrentTpl;

+  Image->Info.SystemTable   = gST;

+  Image->Info.ImageBase     = (VOID *)(UINTN)DxeCoreImageBaseAddress;

+  Image->Info.ImageSize     = DxeCoreImageLength;

+

+  //

+  // Install the protocol interfaces for this image

+  //

+  Status = CoreInstallProtocolInterface (

+             &Image->Handle,

+             &gEfiLoadedImageProtocolGuid,

+             EFI_NATIVE_INTERFACE,

+             &Image->Info

+             );

+  ASSERT_EFI_ERROR (Status);

+

+  mCurrentImage = Image;

+

+  //

+  // Fill in DXE globals

+  //

+  gDxeCoreImageHandle = Image->Handle;

+  gDxeCoreLoadedImage = &Image->Info;

+

+  //

+  // Export DXE Core PE Loader functionality

+  //

+  return CoreInstallProtocolInterface (

+           &mLoadPe32PrivateData.Handle,

+           &gEfiLoadPeImageProtocolGuid,

+           EFI_NATIVE_INTERFACE,

+           &mLoadPe32PrivateData.Pe32Image

+           );

+}

+

+

+EFI_STATUS

+CoreShutdownImageServices (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Transfer control of runtime images to runtime service

+

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_SUCCESS       - Function successfully returned

+

+--*/

+{

+  LIST_ENTRY                  *Link;

+  LOADED_IMAGE_PRIVATE_DATA   *Image;

+

+  //

+  // The Runtime AP is required for the core to function!

+  //

+  ASSERT (gRuntime != NULL);

+

+  for (Link = mRuntimeImageList.ForwardLink; Link != &mRuntimeImageList; Link = Link->ForwardLink) {

+    Image = CR (Link, LOADED_IMAGE_PRIVATE_DATA, Link, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE);

+    if (Image->RuntimeFixupValid) {

+      gRuntime->RegisterImage (

+                  gRuntime,

+                  (UINT64)(UINTN)(Image->Info.ImageBase),

+                  (EFI_SIZE_TO_PAGES ((UINTN)Image->Info.ImageSize)),

+                  Image->RuntimeFixup

+                  );

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+CoreLoadPeImage (

+  IN VOID                        *Pe32Handle,

+  IN LOADED_IMAGE_PRIVATE_DATA   *Image,

+  IN EFI_PHYSICAL_ADDRESS        DstBuffer    OPTIONAL,

+  OUT EFI_PHYSICAL_ADDRESS       *EntryPoint  OPTIONAL,

+  IN  UINT32                     Attribute

+  )

+/*++

+

+Routine Description:

+

+  Loads, relocates, and invokes a PE/COFF image

+

+Arguments:

+

+  Pe32Handle       - The handle of PE32 image

+  Image            - PE image to be loaded

+  DstBuffer        - The buffer to store the image

+  EntryPoint       - A pointer to the entry point

+  Attribute        - The bit mask of attributes to set for the load PE image

+

+Returns:

+

+  EFI_SUCCESS          - The file was loaded, relocated, and invoked

+

+  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file

+

+  EFI_INVALID_PARAMETER - Invalid parameter

+

+  EFI_BUFFER_TOO_SMALL  - Buffer for image is too small

+

+--*/

+{

+  EFI_STATUS                            Status;

+  UINTN                                 Size;

+

+  ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext));

+

+  Image->ImageContext.Handle    = Pe32Handle;

+  Image->ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)CoreReadImageFile;

+

+  //

+  // Get information about the image being loaded

+  //

+  Status = gEfiPeiPeCoffLoader->GetImageInfo (gEfiPeiPeCoffLoader, &Image->ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Allocate memory of the correct memory type aligned on the required image boundry

+  //

+

+  if (DstBuffer == 0) {

+    //

+    // Allocate Destination Buffer as caller did not pass it in

+    //

+

+    if (Image->ImageContext.SectionAlignment > EFI_PAGE_SIZE) {

+      Size = (UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment;

+    } else {

+      Size = (UINTN)Image->ImageContext.ImageSize;

+    }

+

+    Image->NumberOfPages = EFI_SIZE_TO_PAGES (Size);

+

+    //

+    // If the image relocations have not been stripped, then load at any address.

+    // Otherwise load at the address at which it was linked.

+    //

+    Status = CoreAllocatePages (

+               (Image->ImageContext.RelocationsStripped) ? AllocateAddress : AllocateAnyPages,

+               Image->ImageContext.ImageCodeMemoryType,

+               Image->NumberOfPages,

+               &Image->ImageContext.ImageAddress

+               );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Image->ImageBasePage = Image->ImageContext.ImageAddress;

+

+  } else {

+    //

+    // Caller provided the destination buffer

+    //

+

+    if (Image->ImageContext.RelocationsStripped && (Image->ImageContext.ImageAddress != DstBuffer)) {

+      //

+      // If the image relocations were stripped, and the caller provided a

+      // destination buffer address that does not match the address that the

+      // image is linked at, then the image cannot be loaded.

+      //

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (Image->NumberOfPages != 0 &&

+        Image->NumberOfPages <

+        (EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment))) {

+      Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);

+    Image->ImageContext.ImageAddress = DstBuffer;

+    Image->ImageBasePage = Image->ImageContext.ImageAddress;

+  }

+

+  Image->ImageContext.ImageAddress =

+      (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &

+      ~((UINTN)Image->ImageContext.SectionAlignment - 1);

+

+  //

+  // Load the image from the file into the allocated memory

+  //

+  Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &Image->ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // If this is a Runtime Driver, then allocate memory for the FixupData that

+  // is used to relocate the image when SetVirtualAddressMap() is called. The

+  // relocation is done by the Runtime AP.

+  //

+  if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) {

+    if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {

+      Image->ImageContext.FixupData = CoreAllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize));

+      if (Image->ImageContext.FixupData == NULL) {

+        Status = EFI_OUT_OF_RESOURCES;

+        goto Done;

+      }

+

+      //

+      // Make a list off all the RT images so we can let the RT AP know about them

+      //

+      Image->RuntimeFixupValid = TRUE;

+      Image->RuntimeFixup = Image->ImageContext.FixupData;

+      InsertTailList (&mRuntimeImageList, &Image->Link);

+    }

+  }

+

+  //

+  // Relocate the image in memory

+  //

+  Status = gEfiPeiPeCoffLoader->RelocateImage (gEfiPeiPeCoffLoader, &Image->ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Flush the Instruction Cache

+  //

+  InvalidateInstructionCacheRange ((VOID *)(UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.ImageSize);

+

+  //

+  // Copy the machine type from the context to the image private data. This

+  // is needed during image unload to know if we should call an EBC protocol

+  // to unload the image.

+  //

+  Image->Machine = Image->ImageContext.Machine;

+

+  //

+  // Get the image entry point. If it's an EBC image, then call into the

+  // interpreter to create a thunk for the entry point and use the returned

+  // value for the entry point.

+  //

+  Image->EntryPoint   = (EFI_IMAGE_ENTRY_POINT)(UINTN)Image->ImageContext.EntryPoint;

+  if (Image->ImageContext.Machine == EFI_IMAGE_MACHINE_EBC) {

+    //

+    // Locate the EBC interpreter protocol

+    //

+    Status = CoreLocateProtocol (&gEfiEbcProtocolGuid, NULL, (VOID **)&Image->Ebc);

+    if (EFI_ERROR(Status)) {

+      goto Done;

+    }

+

+    //

+    // Register a callback for flushing the instruction cache so that created

+    // thunks can be flushed.

+    //

+    Status = Image->Ebc->RegisterICacheFlush (Image->Ebc, (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange);

+    if (EFI_ERROR(Status)) {

+      goto Done;

+    }

+

+    //

+    // Create a thunk for the image's entry point. This will be the new

+    // entry point for the image.

+    //

+    Status = Image->Ebc->CreateThunk (

+                           Image->Ebc,

+                           Image->Handle,

+                           (VOID *)(UINTN)Image->ImageContext.EntryPoint,

+                           (VOID **)&Image->EntryPoint

+                           );

+    if (EFI_ERROR(Status)) {

+      goto Done;

+    }

+  }

+

+  //

+  // Fill in the image information for the Loaded Image Protocol

+  //

+  Image->Type               = Image->ImageContext.ImageType;

+  Image->Info.ImageBase     = (VOID *)(UINTN)Image->ImageContext.ImageAddress;

+  Image->Info.ImageSize     = Image->ImageContext.ImageSize;

+  Image->Info.ImageCodeType = Image->ImageContext.ImageCodeMemoryType;

+  Image->Info.ImageDataType = Image->ImageContext.ImageDataMemoryType;

+

+  //

+  // Fill in the entry point of the image if it is available

+  //

+  if (EntryPoint != NULL) {

+    *EntryPoint = Image->ImageContext.EntryPoint;

+  }

+

+  //

+  // Print the load address and the PDB file name if it is available

+  //

+

+  DEBUG_CODE (

+  {

+    UINTN Index;

+    UINTN StartIndex;

+    CHAR8 EfiFileName[256];

+

+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading driver at 0x%08x EntryPoint=0x%08x ", (UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.EntryPoint));

+    if (Image->ImageContext.PdbPointer != NULL) {

+      StartIndex = 0;

+      for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {

+        if (Image->ImageContext.PdbPointer[Index] == '\\') {

+          StartIndex = Index + 1;

+        }

+      }

+      //

+      // Copy the PDB file name to our temporary string, and replace .pdb with .efi

+      //

+      for (Index = 0; Index < sizeof (EfiFileName); Index++) {

+        EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];

+        if (EfiFileName[Index] == 0) {

+          EfiFileName[Index] = '.';

+        }

+        if (EfiFileName[Index] == '.') {

+          EfiFileName[Index + 1] = 'e';

+          EfiFileName[Index + 2] = 'f';

+          EfiFileName[Index + 3] = 'i';

+          EfiFileName[Index + 4] = 0;

+          break;

+        }

+      }

+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));

+    }

+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));

+  }

+  );

+

+  return EFI_SUCCESS;

+

+Done:

+  //

+  // Free memory

+  //

+  CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages);

+  return Status;

+}

+

+

+LOADED_IMAGE_PRIVATE_DATA *

+CoreLoadedImageInfo (

+  IN EFI_HANDLE  ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Get the image's private data from its handle.

+

+Arguments:

+

+  ImageHandle     - The image handle

+

+Returns:

+

+  Return the image private data associated with ImageHandle.

+

+--*/

+{

+  EFI_STATUS                 Status;

+  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;

+  LOADED_IMAGE_PRIVATE_DATA  *Image;

+

+  Status = CoreHandleProtocol (

+             ImageHandle,

+             &gEfiLoadedImageProtocolGuid,

+             (VOID **)&LoadedImage

+             );

+  if (!EFI_ERROR (Status)) {

+    Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage);

+  } else {

+    DEBUG ((EFI_D_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %x\n", ImageHandle));

+    Image = NULL;

+  }

+

+  return Image;

+}

+

+

+EFI_STATUS

+CoreLoadImageCommon (

+  IN  BOOLEAN                          BootPolicy,

+  IN  EFI_HANDLE                       ParentImageHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN  VOID                             *SourceBuffer       OPTIONAL,

+  IN  UINTN                            SourceSize,

+  IN  EFI_PHYSICAL_ADDRESS             DstBuffer           OPTIONAL,

+  IN OUT UINTN                         *NumberOfPages      OPTIONAL,

+  OUT EFI_HANDLE                       *ImageHandle,

+  OUT EFI_PHYSICAL_ADDRESS             *EntryPoint         OPTIONAL,

+  IN  UINT32                           Attribute

+  )

+/*++

+

+Routine Description:

+

+  Loads an EFI image into memory and returns a handle to the image.

+

+Arguments:

+

+  BootPolicy          - If TRUE, indicates that the request originates from the boot manager,

+                        and that the boot manager is attempting to load FilePath as a boot selection.

+  ParentImageHandle   - The caller's image handle.

+  FilePath            - The specific file path from which the image is loaded.

+  SourceBuffer        - If not NULL, a pointer to the memory location containing a copy of

+                        the image to be loaded.

+  SourceSize          - The size in bytes of SourceBuffer.

+  DstBuffer           - The buffer to store the image

+  NumberOfPages       - If not NULL, a pointer to the image's page number, if this number

+                        is not enough, return EFI_BUFFER_TOO_SMALL and this parameter contain

+                        the required number.

+  ImageHandle         - Pointer to the returned image handle that is created when the image

+                        is successfully loaded.

+  EntryPoint          - A pointer to the entry point

+  Attribute           - The bit mask of attributes to set for the load PE image

+

+Returns:

+

+  EFI_SUCCESS            - The image was loaded into memory.

+  EFI_NOT_FOUND          - The FilePath was not found.

+  EFI_INVALID_PARAMETER  - One of the parameters has an invalid value.

+  EFI_BUFFER_TOO_SMALL   - The buffer is too small

+  EFI_UNSUPPORTED        - The image type is not supported, or the device path cannot be

+                           parsed to locate the proper protocol for loading the file.

+  EFI_OUT_OF_RESOURCES   - Image was not loaded due to insufficient resources.

+--*/

+{

+  LOADED_IMAGE_PRIVATE_DATA  *Image;

+  LOADED_IMAGE_PRIVATE_DATA  *ParentImage;

+  IMAGE_FILE_HANDLE          FHand;

+  EFI_STATUS                 Status;

+  EFI_STATUS                 SecurityStatus;

+  EFI_HANDLE                 DeviceHandle;

+  UINT32                     AuthenticationStatus;

+  EFI_DEVICE_PATH_PROTOCOL   *OriginalFilePath;

+  EFI_DEVICE_PATH_PROTOCOL   *HandleFilePath;

+  UINTN                      FilePathSize;

+

+

+  ASSERT (gEfiCurrentTpl < EFI_TPL_NOTIFY);

+  ParentImage = NULL;

+

+  //

+  // The caller must pass in a valid ParentImageHandle

+  //

+  if (ImageHandle == NULL || ParentImageHandle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ParentImage = CoreLoadedImageInfo (ParentImageHandle);

+  if (ParentImage == NULL) {

+    DEBUG((EFI_D_LOAD|EFI_D_ERROR, "LoadImageEx: Parent handle not an image handle\n"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Get simple read access to the source file

+  //

+  OriginalFilePath = FilePath;

+  Status = CoreOpenImageFile (

+             BootPolicy,

+             SourceBuffer,

+             SourceSize,

+             FilePath,

+             &DeviceHandle,

+             &FHand,

+             &AuthenticationStatus

+             );

+  if (Status == EFI_ALREADY_STARTED) {

+    Image = NULL;

+    goto Done;

+  } else if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Verify the Authentication Status through the Security Architectural Protocol

+  //

+  if ((gSecurity != NULL) && (OriginalFilePath != NULL)) {

+    SecurityStatus = gSecurity->FileAuthenticationState (

+                                  gSecurity,

+                                  AuthenticationStatus,

+                                  OriginalFilePath

+                                  );

+    if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {

+      Status = SecurityStatus;

+      Image = NULL;

+      goto Done;

+    }

+  }

+

+

+  //

+  // Allocate a new image structure

+  //

+  Image = CoreAllocateZeroBootServicesPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));

+  if (Image == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Pull out just the file portion of the DevicePath for the LoadedImage FilePath

+  //

+  Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);

+  if (!EFI_ERROR (Status)) {

+    FilePathSize = CoreDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);

+    FilePath = (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *)FilePath) + FilePathSize );

+  }

+

+  //

+  // Initialize the fields for an internal driver

+  //

+  Image->Signature         = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE;

+  Image->Info.SystemTable  = gST;

+  Image->Info.DeviceHandle = DeviceHandle;

+  Image->Info.Revision     = EFI_LOADED_IMAGE_INFORMATION_REVISION;

+  Image->Info.FilePath     = CoreDuplicateDevicePath (FilePath);

+  Image->Info.ParentHandle = ParentImageHandle;

+

+  if (NumberOfPages != NULL) {

+    Image->NumberOfPages = *NumberOfPages ;

+  } else {

+    Image->NumberOfPages = 0 ;

+  }

+

+  //

+  // Install the protocol interfaces for this image

+  // don't fire notifications yet

+  //

+  Status = CoreInstallProtocolInterfaceNotify (

+             &Image->Handle,

+             &gEfiLoadedImageProtocolGuid,

+             EFI_NATIVE_INTERFACE,

+             &Image->Info,

+             FALSE

+             );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  //

+  // Load the image.  If EntryPoint is Null, it will not be set.

+  //

+  Status = CoreLoadPeImage (&FHand, Image, DstBuffer, EntryPoint, Attribute);

+  if (EFI_ERROR (Status)) {

+    if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) {

+      if (NumberOfPages != NULL) {

+        *NumberOfPages = Image->NumberOfPages;

+      }

+    }

+    goto Done;

+  }

+

+  //

+  // Register the image in the Debug Image Info Table if the attribute is set

+  //

+  if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) {

+    CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle);

+  }

+

+  //

+  //Reinstall loaded image protocol to fire any notifications

+  //

+  Status = CoreReinstallProtocolInterface (

+             Image->Handle,

+             &gEfiLoadedImageProtocolGuid,

+             &Image->Info,

+             &Image->Info

+             );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+

+  //

+  // Success.  Return the image handle

+  //

+  *ImageHandle = Image->Handle;

+

+Done:

+  //

+  // All done accessing the source file

+  // If we allocated the Source buffer, free it

+  //

+  if (FHand.FreeBuffer) {

+    CoreFreePool (FHand.Source);

+  }

+

+  //

+  // There was an error.  If there's an Image structure, free it

+  //

+  if (EFI_ERROR (Status)) {

+    if (Image != NULL) {

+      CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0));

+      *ImageHandle = NULL;

+    }

+  }

+

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreLoadImage (

+  IN BOOLEAN                    BootPolicy,

+  IN EFI_HANDLE                 ParentImageHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,

+  IN VOID                       *SourceBuffer   OPTIONAL,

+  IN UINTN                      SourceSize,

+  OUT EFI_HANDLE                *ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Loads an EFI image into memory and returns a handle to the image.

+

+Arguments:

+

+  BootPolicy          - If TRUE, indicates that the request originates from the boot manager,

+                        and that the boot manager is attempting to load FilePath as a boot selection.

+  ParentImageHandle   - The caller's image handle.

+  FilePath            - The specific file path from which the image is loaded.

+  SourceBuffer        - If not NULL, a pointer to the memory location containing a copy of

+                        the image to be loaded.

+  SourceSize          - The size in bytes of SourceBuffer.

+  ImageHandle         - Pointer to the returned image handle that is created when the image

+                        is successfully loaded.

+

+Returns:

+

+  EFI_SUCCESS            - The image was loaded into memory.

+  EFI_NOT_FOUND          - The FilePath was not found.

+  EFI_INVALID_PARAMETER  - One of the parameters has an invalid value.

+  EFI_UNSUPPORTED        - The image type is not supported, or the device path cannot be

+                           parsed to locate the proper protocol for loading the file.

+  EFI_OUT_OF_RESOURCES   - Image was not loaded due to insufficient resources.

+--*/

+{

+  EFI_STATUS    Status;

+

+  PERF_START (NULL, "LoadImage", NULL, 0);

+

+  Status = CoreLoadImageCommon (

+             BootPolicy,

+             ParentImageHandle,

+             FilePath,

+             SourceBuffer,

+             SourceSize,

+             (EFI_PHYSICAL_ADDRESS)NULL,

+             NULL,

+             ImageHandle,

+             NULL,

+             EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION

+             );

+

+  PERF_END (NULL, "LoadImage", NULL, 0);

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreLoadImageEx (

+  IN  EFI_PE32_IMAGE_PROTOCOL          *This,

+  IN  EFI_HANDLE                       ParentImageHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN  VOID                             *SourceBuffer       OPTIONAL,

+  IN  UINTN                            SourceSize,

+  IN  EFI_PHYSICAL_ADDRESS             DstBuffer           OPTIONAL,

+  OUT UINTN                            *NumberOfPages      OPTIONAL,

+  OUT EFI_HANDLE                       *ImageHandle,

+  OUT EFI_PHYSICAL_ADDRESS             *EntryPoint         OPTIONAL,

+  IN  UINT32                           Attribute

+  )

+/*++

+

+Routine Description:

+

+  Loads an EFI image into memory and returns a handle to the image with extended parameters.

+

+Arguments:

+

+  This                - Calling context

+  ParentImageHandle   - The caller's image handle.

+  FilePath            - The specific file path from which the image is loaded.

+  SourceBuffer        - If not NULL, a pointer to the memory location containing a copy of

+                        the image to be loaded.

+  SourceSize          - The size in bytes of SourceBuffer.

+  DstBuffer           - The buffer to store the image.

+  NumberOfPages       - For input, specifies the space size of the image by caller if not NULL.

+                        For output, specifies the actual space size needed.

+  ImageHandle         - Image handle for output.

+  EntryPoint          - Image entry point for output.

+  Attribute           - The bit mask of attributes to set for the load PE image.

+

+Returns:

+

+  EFI_SUCCESS            - The image was loaded into memory.

+  EFI_NOT_FOUND          - The FilePath was not found.

+  EFI_INVALID_PARAMETER  - One of the parameters has an invalid value.

+  EFI_UNSUPPORTED        - The image type is not supported, or the device path cannot be

+                           parsed to locate the proper protocol for loading the file.

+  EFI_OUT_OF_RESOURCES   - Image was not loaded due to insufficient resources.

+--*/

+{

+  return CoreLoadImageCommon (

+           TRUE,

+           ParentImageHandle,

+           FilePath,

+           SourceBuffer,

+           SourceSize,

+           DstBuffer,

+           NumberOfPages,

+           ImageHandle,

+           EntryPoint,

+           Attribute

+           );

+}

+

+

+

+

+EFI_STATUS

+EFIAPI

+CoreStartImage (

+  IN EFI_HANDLE  ImageHandle,

+  OUT UINTN      *ExitDataSize,

+  OUT CHAR16     **ExitData  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Transfer control to a loaded image's entry point.

+

+Arguments:

+

+  ImageHandle     - Handle of image to be started.

+

+  ExitDataSize    - Pointer of the size to ExitData

+

+  ExitData        - Pointer to a pointer to a data buffer that includes a Null-terminated

+                    Unicode string, optionally followed by additional binary data. The string

+                    is a description that the caller may use to further indicate the reason for

+                    the image¡¯s exit.

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Invalid parameter

+

+  EFI_OUT_OF_RESOURCES       - No enough buffer to allocate

+

+  EFI_SUCCESS               - Successfully transfer control to the image's entry point.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  LOADED_IMAGE_PRIVATE_DATA     *Image;

+  LOADED_IMAGE_PRIVATE_DATA     *LastImage;

+  UINT64                        HandleDatabaseKey;

+  UINTN                         SetJumpFlag;

+

+  Image = CoreLoadedImageInfo (ImageHandle);

+  if (Image == NULL_HANDLE  ||  Image->Started) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Don't profile Objects or invalid start requests

+  //

+  PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);

+

+  if (sizeof (UINTN) == 4 && Image->Machine == EFI_IMAGE_MACHINE_X64) {

+    return EFI_UNSUPPORTED;

+  } else if (sizeof (UINTN) == 8 && Image->Machine == EFI_IMAGE_MACHINE_IA32) {

+    return EFI_UNSUPPORTED;

+  } else {

+    //

+    // For orther possible cases

+    //

+  }

+

+  //

+  // Push the current start image context, and

+  // link the current image to the head.   This is the

+  // only image that can call Exit()

+  //

+  HandleDatabaseKey = CoreGetHandleDatabaseKey();

+  LastImage         = mCurrentImage;

+  mCurrentImage     = Image;

+  Image->Tpl        = gEfiCurrentTpl;

+

+  //

+  // Set long jump for Exit() support

+  //

+  Image->JumpContext = CoreAllocateBootServicesPool (sizeof (*Image->JumpContext));

+  if (Image->JumpContext == NULL) {

+    PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetJumpFlag = SetJump (Image->JumpContext);

+  //

+  // The initial call to SetJump() must always return 0.  

+  // Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump(). 

+  //

+  if (!SetJumpFlag) {

+    //

+    // Call the image's entry point

+    //

+    Image->Started = TRUE;

+    Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);

+

+    //

+    // Add some debug information if the image returned with error.

+    // This make the user aware and check if the driver image have already released

+    // all the resource in this situation.

+    //

+    DEBUG_CODE (

+      if (EFI_ERROR (Image->Status)) {

+        DEBUG ((EFI_D_ERROR, "Error: Image at %08X start failed: %x\n", Image->Info.ImageBase, Image->Status));

+      }

+    );

+

+    //

+    // If the image returns, exit it through Exit()

+    //

+    CoreExit (ImageHandle, Image->Status, 0, NULL);

+  }

+

+  //

+  // Image has completed.  Verify the tpl is the same

+  //

+  ASSERT (Image->Tpl == gEfiCurrentTpl);

+  CoreRestoreTpl (Image->Tpl);

+

+  CoreFreePool (Image->JumpContext);

+

+  //

+  // Pop the current start image context

+  //

+  mCurrentImage = LastImage;

+

+  //

+  // Go connect any handles that were created or modified while the image executed.

+  //

+  CoreConnectHandlesByKey (HandleDatabaseKey);

+

+  //

+  // Handle the image's returned ExitData

+  //

+  DEBUG_CODE (

+    if (Image->ExitDataSize != 0 || Image->ExitData != NULL) {

+

+      DEBUG (

+        (EFI_D_LOAD,

+        "StartImage: ExitDataSize %d, ExitData %x",

+                            Image->ExitDataSize,

+        Image->ExitData)

+        );

+      if (Image->ExitData != NULL) {

+        DEBUG ((EFI_D_LOAD, " (%hs)", Image->ExitData));

+      }

+      DEBUG ((EFI_D_LOAD, "\n"));

+    }

+  );

+

+  //

+  //  Return the exit data to the caller

+  //

+  if (ExitData != NULL && ExitDataSize != NULL) {

+    *ExitDataSize = Image->ExitDataSize;

+    *ExitData     = Image->ExitData;

+  } else {

+    //

+    // Caller doesn't want the exit data, free it

+    //

+    CoreFreePool (Image->ExitData);

+    Image->ExitData = NULL;

+  }

+

+  //

+  // Save the Status because Image will get destroyed if it is unloaded.

+  //

+  Status = Image->Status;

+

+  //

+  // If the image returned an error, or if the image is an application

+  // unload it

+  //

+  if (EFI_ERROR (Image->Status) || Image->Type == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {

+    CoreUnloadAndCloseImage (Image, TRUE);

+  }

+

+  //

+  // Done

+  //

+  PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);

+  return Status;

+}

+

+

+VOID

+CoreUnloadAndCloseImage (

+  IN LOADED_IMAGE_PRIVATE_DATA  *Image,

+  IN BOOLEAN                    FreePage

+  )

+/*++

+

+Routine Description:

+

+  Unloads EFI image from memory.

+

+Arguments:

+

+  Image      - EFI image

+  FreePage   - Free allocated pages

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                          Status;

+  UINTN                               HandleCount;

+  EFI_HANDLE                          *HandleBuffer;

+  UINTN                               HandleIndex;

+  EFI_GUID                            **ProtocolGuidArray;

+  UINTN                               ArrayCount;

+  UINTN                               ProtocolIndex;

+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;

+  UINTN                               OpenInfoCount;

+  UINTN                               OpenInfoIndex;

+

+  if (Image->Ebc != NULL) {

+    //

+    // If EBC protocol exists we must perform cleanups for this image.

+    //

+    Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);

+  }

+

+  //

+  // Unload image, free Image->ImageContext->ModHandle

+  //

+  gEfiPeiPeCoffLoader->UnloadImage (gEfiPeiPeCoffLoader, &Image->ImageContext);

+

+  //

+  // Free our references to the image handle

+  //

+  if (Image->Handle != NULL_HANDLE) {

+

+    Status = CoreLocateHandleBuffer (

+               AllHandles,

+               NULL,

+               NULL,

+               &HandleCount,

+               &HandleBuffer

+               );

+    if (!EFI_ERROR (Status)) {

+      for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {

+        Status = CoreProtocolsPerHandle (

+                   HandleBuffer[HandleIndex],

+                   &ProtocolGuidArray,

+                   &ArrayCount

+                   );

+        if (!EFI_ERROR (Status)) {

+          for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {

+            Status = CoreOpenProtocolInformation (

+                       HandleBuffer[HandleIndex],

+                       ProtocolGuidArray[ProtocolIndex],

+                       &OpenInfo,

+                       &OpenInfoCount

+                       );

+            if (!EFI_ERROR (Status)) {

+              for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {

+                if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {

+                  Status = CoreCloseProtocol (

+                             HandleBuffer[HandleIndex],

+                             ProtocolGuidArray[ProtocolIndex],

+                             Image->Handle,

+                             OpenInfo[OpenInfoIndex].ControllerHandle

+                             );

+                }

+              }

+              if (OpenInfo != NULL) {

+                CoreFreePool(OpenInfo);

+              }

+            }

+          }

+          if (ProtocolGuidArray != NULL) {

+            CoreFreePool(ProtocolGuidArray);

+          }

+        }

+      }

+      if (HandleBuffer != NULL) {

+        CoreFreePool (HandleBuffer);

+      }

+    }

+

+    CoreRemoveDebugImageInfoEntry (Image->Handle);

+

+    Status = CoreUninstallProtocolInterface (

+               Image->Handle,

+               &gEfiLoadedImageProtocolGuid,

+               &Image->Info

+               );

+  }

+

+  if (Image->RuntimeFixupValid) {

+    //

+    // Remove the Image from the Runtime Image list as we are about to Free it!

+    //

+    RemoveEntryList (&Image->Link);

+  }

+

+  //

+  // Free the Image from memory

+  //

+  if ((Image->ImageBasePage != 0) && FreePage) {

+    CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);

+  }

+

+  //

+  // Done with the Image structure

+  //

+  if (Image->Info.FilePath != NULL) {

+    CoreFreePool (Image->Info.FilePath);

+  }

+

+  if (Image->FixupData != NULL) {

+    CoreFreePool (Image->FixupData);

+  }

+

+  CoreFreePool (Image);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreExit (

+  IN EFI_HANDLE  ImageHandle,

+  IN EFI_STATUS  Status,

+  IN UINTN       ExitDataSize,

+  IN CHAR16      *ExitData  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Terminates the currently loaded EFI image and returns control to boot services.

+

+Arguments:

+

+  ImageHandle       - Handle that identifies the image. This parameter is passed to the image

+                      on entry.

+  Status            - The image¡¯s exit code.

+  ExitDataSize      - The size, in bytes, of ExitData. Ignored if ExitStatus is

+                      EFI_SUCCESS.

+  ExitData          - Pointer to a data buffer that includes a Null-terminated Unicode string,

+                      optionally followed by additional binary data. The string is a

+                      description that the caller may use to further indicate the reason for

+                      the image¡¯s exit.

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Image handle is NULL or it is not current image.

+

+  EFI_SUCCESS               - Successfully terminates the currently loaded EFI image.

+

+  EFI_ACCESS_DENIED         - Should never reach there.

+

+  EFI_OUT_OF_RESOURCES      - Could not allocate pool

+

+--*/

+{

+  LOADED_IMAGE_PRIVATE_DATA  *Image;

+

+  Image = CoreLoadedImageInfo (ImageHandle);

+  if (Image == NULL_HANDLE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!Image->Started) {

+    //

+    // The image has not been started so just free its resources

+    //

+    CoreUnloadAndCloseImage (Image, TRUE);

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Image has been started, verify this image can exit

+  //

+  if (Image != mCurrentImage) {

+    DEBUG ((EFI_D_LOAD|EFI_D_ERROR, "Exit: Image is not exitable image\n"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Set status

+  //

+  Image->Status = Status;

+

+  //

+  // If there's ExitData info, move it

+  //

+  if (ExitData != NULL) {

+    Image->ExitDataSize = ExitDataSize;

+    Image->ExitData = CoreAllocateBootServicesPool (Image->ExitDataSize);

+    if (Image->ExitData == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+    CopyMem (Image->ExitData, ExitData, Image->ExitDataSize);

+  }

+

+  //

+  // return to StartImage

+  //

+  LongJump (Image->JumpContext, (UINTN)-1);

+

+  //

+  // If we return from LongJump, then it is an error

+  //

+  ASSERT (FALSE);

+  return EFI_ACCESS_DENIED;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreUnloadImage (

+  IN EFI_HANDLE  ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Unloads an image.

+

+Arguments:

+

+  ImageHandle           - Handle that identifies the image to be unloaded.

+

+Returns:

+

+ EFI_SUCCESS            - The image has been unloaded.

+ EFI_UNSUPPORTED        - The image has been sarted, and does not support unload.

+ EFI_INVALID_PARAMPETER - ImageHandle is not a valid image handle.

+

+--*/

+{

+  EFI_STATUS                 Status;

+  LOADED_IMAGE_PRIVATE_DATA  *Image;

+

+  Image = CoreLoadedImageInfo (ImageHandle);

+  if (Image == NULL ) {

+    //

+    // The image handle is not valid

+    //

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Image->Started) {

+    //

+    // The image has been started, request it to unload.

+    //

+    Status = EFI_UNSUPPORTED;

+    if (Image->Info.Unload != NULL) {

+      Status = Image->Info.Unload (ImageHandle);

+    }

+

+  } else {

+    //

+    // This Image hasn't been started, thus it can be unloaded

+    //

+    Status = EFI_SUCCESS;

+  }

+

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // if the Image was not started or Unloaded O.K. then clean up

+    //

+    CoreUnloadAndCloseImage (Image, TRUE);

+  }

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreUnloadImageEx (

+  IN EFI_PE32_IMAGE_PROTOCOL  *This,

+  IN EFI_HANDLE                         ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Unload the specified image.

+

+Arguments:

+

+  This              - Indicates the calling context.

+

+  ImageHandle       - The specified image handle.

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Image handle is NULL.

+

+  EFI_UNSUPPORTED             - Attempt to unload an unsupported image.

+

+  EFI_SUCCESS                 - Image successfully unloaded.

+

+--*/

+{

+  return CoreUnloadImage (ImageHandle);

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Image/ImageFile.c b/edk2/EdkModulePkg/Core/Dxe/Image/ImageFile.c
new file mode 100644
index 0000000..999cd69
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Image/ImageFile.c
@@ -0,0 +1,569 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  ImageFile.c

+

+

+Abstract:

+

+  

+

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+

+VOID

+CoreDevicePathToFileName (

+  IN  FILEPATH_DEVICE_PATH      *FilePath,

+  OUT CHAR16                    **String

+  );

+

+

+

+EFI_STATUS

+CoreOpenImageFile (

+  IN BOOLEAN                        BootPolicy,

+  IN VOID                           *SourceBuffer   OPTIONAL,

+  IN UINTN                          SourceSize,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL   *FilePath,

+  OUT EFI_HANDLE                    *DeviceHandle,

+  IN IMAGE_FILE_HANDLE              *ImageFileHandle,

+  OUT UINT32                        *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+

+    Opens a file for (simple) reading.  The simple read abstraction

+    will access the file either from a memory copy, from a file

+    system interface, or from the load file interface.

+

+Arguments:

+

+  BootPolicy    - Policy for Open Image File.

+  SourceBuffer  - Pointer to the memory location containing copy

+                  of the image to be loaded.

+  SourceSize    - The size in bytes of SourceBuffer.

+  FilePath      - The specific file path from which the image is loaded

+  DeviceHandle  - Pointer to the return device handle.

+  ImageFileHandle      - Pointer to the image file handle.

+  AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned. 

+    

+Returns:

+

+    EFI_SUCCESS     - Image file successfully opened.

+    

+    EFI_LOAD_ERROR  - If the caller passed a copy of the file, and SourceSize is 0.

+    

+    EFI_INVALID_PARAMETER   - File path is not valid.

+    

+    EFI_NOT_FOUND   - File not found.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_DEVICE_PATH_PROTOCOL          *TempFilePath;

+  FILEPATH_DEVICE_PATH              *FilePathNode;

+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FwVolFilePathNode;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;

+  EFI_FILE_HANDLE                   FileHandle;

+  EFI_FILE_HANDLE                   LastHandle;

+  EFI_LOAD_FILE_PROTOCOL            *LoadFile;

+  EFI_FIRMWARE_VOLUME_PROTOCOL      *FwVol;

+  EFI_SECTION_TYPE                  SectionType;

+  UINT8                             *Pe32Buffer;

+  UINTN                             Pe32BufferSize;

+  EFI_FV_FILETYPE                   Type;

+  EFI_FV_FILE_ATTRIBUTES            Attrib;

+  EFI_FILE_INFO                     *FileInfo;

+  UINTN                             FileInfoSize;

+  EFI_GUID                          *NameGuid;

+

+  *AuthenticationStatus = 0;

+  ZeroMem (ImageFileHandle, sizeof (IMAGE_FILE_HANDLE));

+  ImageFileHandle->Signature = IMAGE_FILE_HANDLE_SIGNATURE;

+

+  //

+  // If the caller passed a copy of the file, then just use it

+  //

+  if (SourceBuffer != NULL) {

+    ImageFileHandle->Source     = SourceBuffer;

+    ImageFileHandle->SourceSize = SourceSize;

+    *DeviceHandle     = NULL;

+    if (SourceSize > 0) {

+      Status = EFI_SUCCESS;

+    } else {

+      Status = EFI_LOAD_ERROR;

+    }

+    goto Done;

+  }

+

+  //

+  // Make sure FilePath is valid

+  //

+  if (FilePath == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check to see if it's in a Firmware Volume

+  //

+  FwVolFilePathNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)FilePath;

+  Status = CoreDevicePathToInterface (

+            &gEfiFirmwareVolumeProtocolGuid, 

+            (EFI_DEVICE_PATH_PROTOCOL **)&FwVolFilePathNode, 

+            (VOID*)&FwVol, 

+            DeviceHandle

+            );

+  if (!EFI_ERROR (Status)) {

+    //

+    // For FwVol File system there is only a single file name that is a GUID.

+    //

+    NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (FwVolFilePathNode);

+    if (NameGuid != NULL) {

+

+      SectionType = EFI_SECTION_PE32;

+      Pe32Buffer  = NULL;

+      Status = FwVol->ReadSection (

+                        FwVol, 

+                        NameGuid,  

+                        SectionType,   

+                        0,

+                        (VOID **)&Pe32Buffer,

+                        &Pe32BufferSize,

+                        AuthenticationStatus

+                        );

+      if (EFI_ERROR (Status)) {

+        //

+        // Try a raw file, since a PE32 SECTION does not exist

+        //

+        if (Pe32Buffer != NULL) {

+          CoreFreePool (Pe32Buffer);

+          *AuthenticationStatus = 0;

+        }

+        Pe32Buffer = NULL;

+        Status = FwVol->ReadFile (

+                          FwVol, 

+                          NameGuid, 

+                          (VOID **)&Pe32Buffer,

+                          &Pe32BufferSize,

+                          &Type,

+                          &Attrib,

+                          AuthenticationStatus

+                          );

+      }

+            

+      if (!EFI_ERROR (Status)) {

+        //

+        // One of the reads passed so we are done

+        //

+        ImageFileHandle->Source = Pe32Buffer;

+        ImageFileHandle->SourceSize = Pe32BufferSize;

+        ImageFileHandle->FreeBuffer = TRUE;

+        goto Done;

+      }

+    }

+  }

+

+  //

+  // Attempt to access the file via a file system interface

+  //

+  FilePathNode = (FILEPATH_DEVICE_PATH *) FilePath;

+  Status = CoreDevicePathToInterface (

+            &gEfiSimpleFileSystemProtocolGuid, 

+            (EFI_DEVICE_PATH_PROTOCOL **)&FilePathNode, 

+            (VOID*)&Volume, 

+            DeviceHandle

+            );

+  if (!EFI_ERROR (Status)) {

+    //

+    // Open the Volume to get the File System handle

+    //

+    Status = Volume->OpenVolume (Volume, &FileHandle);

+    if (!EFI_ERROR (Status)) {

+     

+      //

+      // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the

+      //  directory information and filename can be seperate. The goal is to inch

+      //  our way down each device path node and close the previous node

+      //

+      while (!IsDevicePathEnd (&FilePathNode->Header)) {

+        if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||

+            DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {

+          Status = EFI_UNSUPPORTED;

+        }

+

+        if (EFI_ERROR (Status)) {

+          //

+          // Exit loop on Error

+          //

+          break;

+        }

+

+        LastHandle = FileHandle;

+        FileHandle = NULL;

+        Status = LastHandle->Open (

+                              LastHandle,

+                              &FileHandle,

+                              FilePathNode->PathName,

+                              EFI_FILE_MODE_READ,

+                              0

+                              );

+

+        //

+        // Close the previous node

+        //

+        LastHandle->Close (LastHandle);

+

+        FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);

+      }

+

+      if (!EFI_ERROR (Status)) {

+        //

+        // We have found the file. Now we need to read it. Before we can read the file we need to

+        // figure out how big the file is.

+        //

+        FileInfo = NULL;

+        FileInfoSize = sizeof (EFI_FILE_INFO);

+        while (CoreGrowBuffer (&Status, (VOID **)&FileInfo, FileInfoSize)) {

+          //

+          // Automatically allocate buffer of the correct size and make the call

+          //

+          Status = FileHandle->GetInfo (

+                                FileHandle,

+                                &gEfiFileInfoGuid,

+                                &FileInfoSize,

+                                FileInfo                               

+                                );

+        }

+        if (!EFI_ERROR (Status)) {

+          //

+          // Allocate space for the file

+          //

+          ImageFileHandle->Source = CoreAllocateBootServicesPool ((UINTN)FileInfo->FileSize);

+          if (ImageFileHandle->Source != NULL) {

+            //

+            // Read the file into the buffer we allocated

+            //

+            ImageFileHandle->SourceSize = (UINTN)FileInfo->FileSize;

+            ImageFileHandle->FreeBuffer = TRUE;

+            Status = FileHandle->Read (FileHandle, &ImageFileHandle->SourceSize, ImageFileHandle->Source);

+

+            //

+            // Close the file since we are done

+            //

+            FileHandle->Close (FileHandle);

+          } else {

+            Status = EFI_OUT_OF_RESOURCES;

+          }

+

+          goto Done;

+        }

+      }

+    }

+  } 

+

+

+  //

+  // Try LoadFile style

+  //

+

+  TempFilePath = FilePath;

+  Status = CoreDevicePathToInterface (

+              &gEfiLoadFileProtocolGuid,

+              &TempFilePath,

+              (VOID*)&LoadFile,

+              DeviceHandle

+              );

+  if (!EFI_ERROR (Status)) {

+    //

+    // Call LoadFile with the correct buffer size

+    //

+    while (CoreGrowBuffer (&Status, (VOID **)&ImageFileHandle->Source, ImageFileHandle->SourceSize)) {

+      Status = LoadFile->LoadFile (

+                           LoadFile,

+                           TempFilePath,

+                           BootPolicy,

+                           &ImageFileHandle->SourceSize,

+                           ImageFileHandle->Source

+                           );

+      //

+      // If success or other error happens, stop loop

+      //

+      if (Status != EFI_BUFFER_TOO_SMALL) {

+        break;

+      }

+    }

+

+    if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {

+      ImageFileHandle->FreeBuffer = TRUE;

+      goto Done;

+    }

+  }

+

+  //

+  // Nothing else to try

+  //

+  DEBUG ((EFI_D_LOAD|EFI_D_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));

+  Status = EFI_NOT_FOUND;

+

+Done:

+

+  //

+  // If the file was not accessed, clean up

+  //

+  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {

+    if (ImageFileHandle->FreeBuffer) {

+      //

+      // Free the source buffer if we allocated it

+      //

+      CoreFreePool (ImageFileHandle->Source);

+    }

+  }

+

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreReadImageFile (

+  IN     VOID    *UserHandle,

+  IN     UINTN   Offset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Read image file (specified by UserHandle) into user specified buffer with specified offset

+  and length.

+

+Arguments:

+

+  UserHandle      - Image file handle

+  

+  Offset          - Offset to the source file

+  

+  ReadSize        - For input, pointer of size to read;

+                    For output, pointer of size actually read.

+  

+  Buffer          - Buffer to write into

+

+Returns:

+

+  EFI_SUCCESS     - Successfully read the specified part of file into buffer.

+

+--*/

+{

+  UINTN               EndPosition;

+  IMAGE_FILE_HANDLE  *FHand;

+

+  FHand = (IMAGE_FILE_HANDLE  *)UserHandle;

+  ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);

+

+  //

+  // Move data from our local copy of the file

+  //

+  EndPosition = Offset + *ReadSize;

+  if (EndPosition > FHand->SourceSize) {

+    *ReadSize = (UINT32)(FHand->SourceSize - Offset);

+  }  

+  if (Offset >= FHand->SourceSize) {

+      *ReadSize = 0;

+  }

+

+  CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CoreDevicePathToInterface (

+  IN EFI_GUID                     *Protocol,

+  IN EFI_DEVICE_PATH_PROTOCOL     **FilePath,

+  OUT VOID                        **Interface,

+  OUT EFI_HANDLE                  *Handle

+  )

+/*++

+

+Routine Description:

+

+  Search a handle to a device on a specified device path that supports a specified protocol,

+  interface of that protocol on that handle is another output.

+

+Arguments:

+

+  Protocol      - The protocol to search for

+  

+  FilePath      - The specified device path

+  

+  Interface     - Interface of the protocol on the handle

+  

+  Handle        - The handle to the device on the specified device path that supports the protocol.

+  

+Returns:

+

+  Status code.

+

+--*/

+{

+  EFI_STATUS                      Status;

+

+  Status = CoreLocateDevicePath (Protocol, FilePath, Handle);

+  if (!EFI_ERROR (Status)) {

+    Status = CoreHandleProtocol (*Handle, Protocol, Interface);

+  }

+  return Status;

+}

+

+

+VOID

+CoreDevicePathToFileName (

+  IN  FILEPATH_DEVICE_PATH      *FilePath,

+  OUT CHAR16                    **String

+  )

+/*++

+

+Routine Description:

+

+  Transfer a device's full path a string.

+

+Arguments:

+

+  FilePath      - Device path

+  

+  String        - The string represent the device's full path

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN                     StringSize;

+  FILEPATH_DEVICE_PATH      *FilePathNode;

+  CHAR16                    *Str;

+

+  *String = NULL;

+  StringSize = 0;

+  FilePathNode = FilePath;

+  while (!IsDevicePathEnd (&FilePathNode->Header)) {

+

+    //

+    // For filesystem access each node should be a filepath component

+    //

+    if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||

+        DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {

+

+      return;

+    }

+

+    StringSize += StrLen (FilePathNode->PathName);

+

+    FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);

+  }

+

+  *String = CoreAllocateBootServicesPool (StringSize);

+  if (*String == NULL) {

+    return;

+  }

+

+  FilePathNode = FilePath;

+  Str = *String;

+  while (!IsDevicePathEnd (&FilePathNode->Header)) {

+    StrCat (Str, FilePathNode->PathName);

+    FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);

+  }

+}

+

+

+BOOLEAN

+CoreGrowBuffer (

+  IN OUT EFI_STATUS   *Status,

+  IN OUT VOID         **Buffer,

+  IN UINTN            BufferSize

+  )

+/*++

+

+Routine Description:

+

+    Helper function called as part of the code needed

+    to allocate the proper sized buffer for various 

+    EFI interfaces.

+

+Arguments:

+

+    Status      - Current status

+

+    Buffer      - Current allocated buffer, or NULL

+

+    BufferSize  - Current buffer size needed

+    

+Returns:

+    

+    TRUE - if the buffer was reallocated and the caller 

+    should try the API again.

+

+    FALSE - buffer could not be allocated and the caller

+    should not try the API again.

+

+--*/

+{

+  BOOLEAN         TryAgain;

+

+  TryAgain = FALSE;

+  //

+  // If this is an initial request, buffer will be null with a new buffer size

+  //

+  if (*Buffer == NULL) {

+    *Status = EFI_BUFFER_TOO_SMALL;

+  }

+

+  if (BufferSize == 0) {

+    return TRUE;

+  }

+

+  //

+  // If the status code is "buffer too small", resize the buffer

+  //

+      

+  if (*Status == EFI_BUFFER_TOO_SMALL) {

+    if (*Buffer != NULL) {

+      CoreFreePool (*Buffer);

+    }

+

+    *Buffer = CoreAllocateBootServicesPool (BufferSize);

+    if (*Buffer != NULL) {

+      TryAgain = TRUE;

+    } else {    

+      *Status = EFI_OUT_OF_RESOURCES;

+    } 

+  }

+

+  //

+  // If there's an error, free the buffer

+  //

+  if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer)) {

+    CoreFreePool (*Buffer);

+    *Buffer = NULL;

+  }

+

+  return TryAgain;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/Library.h b/edk2/EdkModulePkg/Core/Dxe/Library.h
new file mode 100644
index 0000000..5e33da5
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Library.h
@@ -0,0 +1,407 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Library.h

+

+Abstract:

+

+Revision History

+

+--*/

+

+#ifndef _DXE_LIBRARY_H_

+#define _DXE_LIBRARY_H_

+

+

+VOID

+CoreReportProgressCode (

+  IN  EFI_STATUS_CODE_VALUE   Value

+  )

+/*++

+

+Routine Description:

+

+  Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid.

+    

+Arguments:

+

+  Value    - Describes the class/subclass/operation of the hardware or software entity 

+             that the Status Code relates to. 

+   

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+CoreReportProgressCodeSpecific (

+  IN  EFI_STATUS_CODE_VALUE   Value,

+  IN  EFI_HANDLE              Handle

+  )

+/*++

+

+Routine Description:

+

+  Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid, 

+  with a handle as additional information.

+    

+Arguments:

+

+  Value    - Describes the class/subclass/operation of the hardware or software entity 

+             that the Status Code relates to. 

+             

+  Handle   - Additional information.

+   

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+CoreAcquireLock (

+  IN EFI_LOCK *Lock

+  )

+/*++

+

+Routine Description:

+

+  Raising to the task priority level of the mutual exclusion

+  lock, and then acquires ownership of the lock.

+    

+Arguments:

+

+  Lock - The lock to acquire

+    

+Returns:

+

+  Lock owned

+

+--*/

+;

+

+EFI_STATUS

+CoreAcquireLockOrFail (

+  IN EFI_LOCK  *Lock

+  )

+/*++

+

+Routine Description:

+

+  Initialize a basic mutual exclusion lock.   Each lock

+  provides mutual exclusion access at it's task priority

+  level.  Since there is no-premption (at any TPL) or

+  multiprocessor support, acquiring the lock only consists

+  of raising to the locks TPL.

+    

+Arguments:

+

+  Lock        - The EFI_LOCK structure to initialize

+   

+Returns:

+

+  EFI_SUCCESS       - Lock Owned.

+  EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned.

+

+--*/

+;

+

+VOID

+CoreReleaseLock (

+  IN EFI_LOCK *Lock

+  )

+/*++

+

+Routine Description:

+

+    Releases ownership of the mutual exclusion lock, and

+    restores the previous task priority level.

+    

+Arguments:

+

+    Lock - The lock to release

+    

+Returns:

+

+    Lock unowned

+

+--*/

+;

+

+//

+// Device Path functions

+//

+

+UINTN

+CoreDevicePathSize (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+/*++

+

+Routine Description:

+

+  Calculate the size of a whole device path.    

+    

+Arguments:

+

+  DevicePath - The pointer to the device path data.

+    

+Returns:

+

+  Size of device path data structure..

+

+--*/

+;

+

+BOOLEAN

+CoreIsDevicePathMultiInstance (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+/*++

+

+Routine Description:

+  Return TRUE is this is a multi instance device path.

+

+Arguments:

+  DevicePath  - A pointer to a device path data structure.

+

+

+Returns:

+  TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi

+  instance.

+

+--*/

+;

+

+

+EFI_DEVICE_PATH_PROTOCOL *

+CoreDuplicateDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath

+  )

+/*++

+

+Routine Description:

+  Duplicate a new device path data structure from the old one.

+

+Arguments:

+  DevicePath  - A pointer to a device path data structure.

+

+Returns:

+  A pointer to the new allocated device path data.

+  Caller must free the memory used by DevicePath if it is no longer needed.

+

+--*/

+;

+

+EFI_DEVICE_PATH_PROTOCOL *

+CoreAppendDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL  *Src1,

+  IN EFI_DEVICE_PATH_PROTOCOL  *Node

+  )

+/*++

+

+Routine Description:

+  Function is used to append a Src1 and Src2 together.

+

+Arguments:

+  Src1  - A pointer to a device path data structure.

+

+  Node  - A pointer to a device path data structure.

+

+Returns:

+

+  A pointer to the new device path is returned.

+  NULL is returned if space for the new device path could not be allocated from pool.

+  It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.

+

+--*/

+;

+

+VOID *

+CoreAllocateBootServicesPool (

+  IN  UINTN   AllocationSize

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+;

+

+VOID *

+CoreAllocateZeroBootServicesPool (

+  IN  UINTN   AllocationSize

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+;

+

+EFI_STATUS

+CoreGetConfigTable (

+  IN EFI_GUID *Guid,

+  IN OUT VOID **Table

+  )

+/*++

+

+Routine Description:

+

+  Find a config table by name in system table's ConfigurationTable.

+

+Arguments:

+

+  Guid        - The table name to look for

+  

+  Table       - Pointer of the config table

+

+Returns: 

+

+  EFI_NOT_FOUND       - Could not find the table in system table's ConfigurationTable.

+  

+  EFI_SUCCESS         - Table successfully found.

+

+--*/

+;

+

+VOID *

+CoreAllocateRuntimeCopyPool (

+  IN  UINTN   AllocationSize,

+  IN  VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+  

+  Buffer            - Specified buffer that will be copy to the allocated pool

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+;

+

+VOID *

+CoreAllocateRuntimePool (

+  IN  UINTN   AllocationSize

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+;

+

+VOID *

+CoreAllocateCopyPool (

+  IN  UINTN   AllocationSize,

+  IN  VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+  

+  Buffer            - Specified buffer that will be copy to the allocated pool

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+;

+

+EFI_EVENT

+CoreCreateProtocolNotifyEvent (

+  IN EFI_GUID             *ProtocolGuid,

+  IN EFI_TPL              NotifyTpl,

+  IN EFI_EVENT_NOTIFY     NotifyFunction,

+  IN VOID                 *NotifyContext,

+  OUT VOID                **Registration,

+  IN  BOOLEAN             SignalFlag

+  )

+/*++

+

+Routine Description:

+

+  Create a protocol notification event and return it.

+

+Arguments:

+

+  ProtocolGuid    - Protocol to register notification event on.

+

+  NotifyTpl       - Maximum TPL to signal the NotifyFunction.

+

+  NotifyFuncition - EFI notification routine.

+

+  NotifyContext   - Context passed into Event when it is created.

+

+  Registration    - Registration key returned from RegisterProtocolNotify().

+

+  SignalFlag      -  Boolean value to decide whether kick the event after register or not. 

+

+Returns:

+

+  The EFI_EVENT that has been registered to be signaled when a ProtocolGuid

+  is added to the system.

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/Library/Library.c b/edk2/EdkModulePkg/Core/Dxe/Library/Library.c
new file mode 100644
index 0000000..74d873e
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Library/Library.c
@@ -0,0 +1,613 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Library.c

+

+Abstract:

+

+  DXE Core library services.

+

+--*/

+

+#include <DxeMain.h>

+

+UINTN mErrorLevel = EFI_D_ERROR | EFI_D_LOAD;

+

+EFI_DEVICE_HANDLE_EXTENDED_DATA mStatusCodeData = {

+  {

+    sizeof (EFI_STATUS_CODE_DATA),

+    0,

+    EFI_STATUS_CODE_SPECIFIC_DATA_GUID

+  },

+  NULL

+};

+

+VOID

+CoreReportProgressCodeSpecific (

+  IN  EFI_STATUS_CODE_VALUE   Value,

+  IN  EFI_HANDLE              Handle

+  )

+/*++

+

+Routine Description:

+

+  Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid, 

+  with a handle as additional information.

+    

+Arguments:

+

+  Value    - Describes the class/subclass/operation of the hardware or software entity 

+             that the Status Code relates to. 

+             

+  Handle   - Additional information.

+   

+Returns:

+

+  None

+

+--*/

+{

+  mStatusCodeData.DataHeader.Size = sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - sizeof (EFI_STATUS_CODE_DATA);

+  mStatusCodeData.Handle          = Handle;

+

+  if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {

+    gStatusCode->ReportStatusCode (

+      EFI_PROGRESS_CODE,

+      Value,

+      0,

+      &gEfiDxeServicesTableGuid,

+      (EFI_STATUS_CODE_DATA *) &mStatusCodeData

+      );

+  }

+}

+

+VOID

+CoreReportProgressCode (

+  IN  EFI_STATUS_CODE_VALUE   Value

+  )

+/*++

+

+Routine Description:

+

+  Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid.

+    

+Arguments:

+

+  Value    - Describes the class/subclass/operation of the hardware or software entity 

+             that the Status Code relates to. 

+   

+Returns:

+

+  None

+

+--*/

+{

+  if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {

+    gStatusCode->ReportStatusCode (

+      EFI_PROGRESS_CODE,

+      Value,

+      0,

+      &gEfiDxeServicesTableGuid,

+      NULL

+      );

+  }

+}

+

+

+VOID *

+CoreAllocateBootServicesPool (

+  IN  UINTN   AllocationSize

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+{

+  VOID  *Memory;

+

+  CoreAllocatePool (EfiBootServicesData, AllocationSize, &Memory);

+  return Memory;

+}

+

+

+VOID *

+CoreAllocateZeroBootServicesPool (

+  IN  UINTN   AllocationSize

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+{

+  VOID  *Memory;

+

+  Memory = CoreAllocateBootServicesPool (AllocationSize);

+  SetMem (Memory, (Memory == NULL) ? 0 : AllocationSize, 0);

+  return Memory;

+}

+

+

+VOID *

+CoreAllocateCopyPool (

+  IN  UINTN   AllocationSize,

+  IN  VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+  

+  Buffer            - Specified buffer that will be copy to the allocated pool

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+{

+  VOID  *Memory;

+

+  Memory = CoreAllocateBootServicesPool (AllocationSize);

+  CopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);

+  

+  return Memory;

+}

+

+ 

+

+VOID *

+CoreAllocateRuntimePool (

+  IN  UINTN   AllocationSize

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+{

+  VOID  *Memory;

+

+  CoreAllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory);

+  return Memory;

+}

+

+VOID *

+CoreAllocateRuntimeCopyPool (

+  IN  UINTN   AllocationSize,

+  IN  VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.

+    

+Arguments:

+

+  AllocationSize    - Size to allocate.

+  

+  Buffer            - Specified buffer that will be copy to the allocated pool

+   

+Returns:

+

+  Pointer of the allocated pool.

+

+--*/

+

+{

+  VOID  *Memory;

+

+  Memory = CoreAllocateRuntimePool (AllocationSize);

+  CopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);

+  

+  return Memory;

+}

+

+

+

+//

+// Lock Stuff

+//

+

+

+

+EFI_STATUS

+CoreAcquireLockOrFail (

+  IN EFI_LOCK  *Lock

+  )

+/*++

+

+Routine Description:

+

+  Initialize a basic mutual exclusion lock.   Each lock

+  provides mutual exclusion access at it's task priority

+  level.  Since there is no-premption (at any TPL) or

+  multiprocessor support, acquiring the lock only consists

+  of raising to the locks TPL.

+    

+Arguments:

+

+  Lock        - The EFI_LOCK structure to initialize

+   

+Returns:

+

+  EFI_SUCCESS       - Lock Owned.

+  EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned.

+

+--*/

+{

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock != EfiLockUninitialized);

+

+  if (Lock->Lock == EfiLockAcquired) {

+    //

+    // Lock is already owned, so bail out

+    //

+    return EFI_ACCESS_DENIED;

+  }

+

+  Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);

+

+  Lock->Lock = EfiLockAcquired;

+  return EFI_SUCCESS;

+}

+

+

+VOID

+CoreAcquireLock (

+  IN EFI_LOCK  *Lock

+  )

+/*++

+

+Routine Description:

+

+  Raising to the task priority level of the mutual exclusion

+  lock, and then acquires ownership of the lock.

+    

+Arguments:

+

+  Lock - The lock to acquire

+    

+Returns:

+

+  Lock owned

+

+--*/

+{

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock == EfiLockReleased);

+

+  Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);

+  Lock->Lock     = EfiLockAcquired;

+}

+

+

+VOID

+CoreReleaseLock (

+  IN EFI_LOCK  *Lock

+  )

+/*++

+

+Routine Description:

+

+    Releases ownership of the mutual exclusion lock, and

+    restores the previous task priority level.

+    

+Arguments:

+

+    Lock - The lock to release

+    

+Returns:

+

+    Lock unowned

+

+--*/

+{

+  EFI_TPL Tpl;

+

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock == EfiLockAcquired);

+

+  Tpl = Lock->OwnerTpl;

+  

+  Lock->Lock = EfiLockReleased;

+

+  CoreRestoreTpl (Tpl);

+}

+

+

+UINTN

+CoreDevicePathSize (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+/*++

+

+Routine Description:

+

+  Calculate the size of a whole device path.    

+    

+Arguments:

+

+  DevicePath - The pointer to the device path data.

+    

+Returns:

+

+  Size of device path data structure..

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL     *Start;

+

+  if (DevicePath == NULL) {

+    return 0;

+  }

+

+  //

+  // Search for the end of the device path structure

+  //

+  Start = DevicePath;

+  while (!EfiIsDevicePathEnd (DevicePath)) {

+    DevicePath = EfiNextDevicePathNode (DevicePath);

+  }

+

+  //

+  // Compute the size and add back in the size of the end device path structure

+  //

+  return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);

+}

+

+

+BOOLEAN

+CoreIsDevicePathMultiInstance (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+/*++

+

+Routine Description:

+  Return TRUE is this is a multi instance device path.

+

+Arguments:

+  DevicePath  - A pointer to a device path data structure.

+

+

+Returns:

+  TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi

+  instance.

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL *Node;

+

+  if (DevicePath == NULL) {

+    return FALSE;

+  }

+

+  Node = DevicePath;

+  while (!EfiIsDevicePathEnd (Node)) {

+    if (EfiIsDevicePathEndInstance (Node)) {

+      return TRUE;

+    }

+    Node = EfiNextDevicePathNode (Node);

+  }

+  return FALSE;

+}

+

+

+

+EFI_DEVICE_PATH_PROTOCOL *

+CoreDuplicateDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath

+  )

+/*++

+

+Routine Description:

+  Duplicate a new device path data structure from the old one.

+

+Arguments:

+  DevicePath  - A pointer to a device path data structure.

+

+Returns:

+  A pointer to the new allocated device path data.

+  Caller must free the memory used by DevicePath if it is no longer needed.

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  UINTN                     Size;

+

+  if (DevicePath == NULL) {

+    return NULL;

+  }

+

+  //

+  // Compute the size

+  //

+  Size = CoreDevicePathSize (DevicePath);

+

+  //

+  // Allocate space for duplicate device path

+  //

+  NewDevicePath = CoreAllocateCopyPool (Size, DevicePath);

+

+  return NewDevicePath;

+}

+

+

+

+EFI_DEVICE_PATH_PROTOCOL *

+CoreAppendDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL  *Src1,

+  IN EFI_DEVICE_PATH_PROTOCOL  *Src2

+  )

+/*++

+

+Routine Description:

+  Function is used to append a Src1 and Src2 together.

+

+Arguments:

+  Src1  - A pointer to a device path data structure.

+

+  Src2  - A pointer to a device path data structure.

+

+Returns:

+

+  A pointer to the new device path is returned.

+  NULL is returned if space for the new device path could not be allocated from pool.

+  It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.

+

+--*/

+{

+  UINTN                       Size;

+  UINTN                       Size1;

+  UINTN                       Size2;

+  EFI_DEVICE_PATH_PROTOCOL    *NewDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL    *SecondDevicePath;

+

+  if (Src1 == NULL && Src2 == NULL) {

+    return NULL;

+  }

+  

+  //

+  // Allocate space for the combined device path. It only has one end node of

+  // length EFI_DEVICE_PATH_PROTOCOL

+  //

+  Size1 = CoreDevicePathSize (Src1);

+  Size2 = CoreDevicePathSize (Src2);

+  Size = Size1 + Size2 - sizeof(EFI_DEVICE_PATH_PROTOCOL);

+

+  NewDevicePath = CoreAllocateCopyPool (Size, Src1);

+  if (NewDevicePath != NULL) {

+

+     //

+     // Over write Src1 EndNode and do the copy

+     //

+     SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((CHAR8 *)NewDevicePath + (Size1 - sizeof(EFI_DEVICE_PATH_PROTOCOL)));

+     CopyMem (SecondDevicePath, Src2, Size2);

+  }

+

+  return NewDevicePath;

+}

+

+

+

+EFI_EVENT

+CoreCreateProtocolNotifyEvent (

+  IN EFI_GUID             *ProtocolGuid,

+  IN EFI_TPL              NotifyTpl,

+  IN EFI_EVENT_NOTIFY     NotifyFunction,

+  IN VOID                 *NotifyContext,

+  OUT VOID                **Registration,

+  IN  BOOLEAN             SignalFlag

+  )

+/*++

+

+Routine Description:

+

+  Create a protocol notification event and return it.

+

+Arguments:

+

+  ProtocolGuid    - Protocol to register notification event on.

+

+  NotifyTpl        - Maximum TPL to signal the NotifyFunction.

+

+  NotifyFuncition  - EFI notification routine.

+

+  NotifyContext   - Context passed into Event when it is created.

+

+  Registration    - Registration key returned from RegisterProtocolNotify().

+

+  SignalFlag      -  Boolean value to decide whether kick the event after register or not. 

+

+Returns:

+

+  The EFI_EVENT that has been registered to be signaled when a ProtocolGuid

+  is added to the system.

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_EVENT               Event;

+

+  //

+  // Create the event

+  //

+

+  Status = CoreCreateEvent (

+            EFI_EVENT_NOTIFY_SIGNAL,

+            NotifyTpl,

+            NotifyFunction,

+            NotifyContext,

+            &Event

+            );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Register for protocol notifactions on this event

+  //

+

+  Status = CoreRegisterProtocolNotify (

+            ProtocolGuid,

+            Event,

+            Registration

+            );

+  ASSERT_EFI_ERROR (Status);

+

+  if (SignalFlag) {

+    //

+    // Kick the event so we will perform an initial pass of

+    // current installed drivers

+    //

+    CoreSignalEvent (Event);

+  }

+

+  return Event;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/Mem/Page.c b/edk2/EdkModulePkg/Core/Dxe/Mem/Page.c
new file mode 100644
index 0000000..e65b028
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Mem/Page.c
@@ -0,0 +1,1589 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  page.c

+

+Abstract:

+

+  EFI Memory page management

+

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+#define EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT  (EFI_PAGE_SIZE)

+

+//

+// Entry for tracking the memory regions for each memory type to help cooalese like memory types

+//

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  BaseAddress;

+  EFI_PHYSICAL_ADDRESS  MaximumAddress;

+  UINT64                CurrentNumberOfPages;

+  UINTN                 InformationIndex;

+} EFI_MEMORY_TYPE_STAISTICS;

+

+//

+// MemoryMap - The current memory map

+//

+UINTN     mMemoryMapKey = 0;

+

+//

+// mMapStack - space to use as temp storage to build new map descriptors

+// mMapDepth - depth of new descriptor stack

+//

+

+#define MAX_MAP_DEPTH 6

+UINTN         mMapDepth = 0;

+MEMORY_MAP    mMapStack[MAX_MAP_DEPTH];

+UINTN         mFreeMapStack = 0;

+

+BOOLEAN mMemoryTypeInformationInitialized = FALSE;

+

+EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiReservedMemoryType

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiLoaderCode

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiLoaderData

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiBootServicesCode

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiBootServicesData

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiRuntimeServicesCode

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiRuntimeServicesData

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiConventionalMemory

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiUnusableMemory

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiACPIReclaimMemory

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiACPIMemoryNVS

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiMemoryMappedIO

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiMemoryMappedIOPortSpace

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiPalCode

+  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }   // EfiMaxMemoryType

+};

+

+EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS;

+

+EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {

+  { EfiReservedMemoryType,      0 },

+  { EfiLoaderCode,              0 },

+  { EfiLoaderData,              0 },

+  { EfiBootServicesCode,        0 },

+  { EfiBootServicesData,        0 },

+  { EfiRuntimeServicesCode,     0 },

+  { EfiRuntimeServicesData,     0 },

+  { EfiConventionalMemory,      0 },

+  { EfiUnusableMemory,          0 },

+  { EfiACPIReclaimMemory,       0 },

+  { EfiACPIMemoryNVS,           0 },

+  { EfiMemoryMappedIO,          0 },

+  { EfiMemoryMappedIOPortSpace, 0 },

+  { EfiPalCode,                 0 },

+  { EfiMaxMemoryType,           0 }

+};

+

+//

+// Internal prototypes

+//

+VOID 

+PromoteMemoryResource (

+  VOID

+);

+

+STATIC

+VOID

+CoreAddRange (

+  IN EFI_MEMORY_TYPE          Type,

+  IN EFI_PHYSICAL_ADDRESS     Start,

+  IN EFI_PHYSICAL_ADDRESS     End,

+  IN UINT64                   Attribute

+  );

+

+STATIC

+VOID

+CoreFreeMemoryMapStack (

+  VOID

+  );

+

+STATIC

+EFI_STATUS

+CoreConvertPages (

+  IN UINT64           Start,

+  IN UINT64           NumberOfPages,

+  IN EFI_MEMORY_TYPE  NewType

+  );

+

+STATIC

+VOID

+RemoveMemoryMapEntry (

+  MEMORY_MAP      *Entry

+  );

+

+VOID

+CoreAcquireMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Enter critical section by gaining lock on gMemoryLock

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  CoreAcquireLock (&gMemoryLock);

+}

+

+

+VOID

+CoreReleaseMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Exit critical section by releasing lock on gMemoryLock

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  CoreReleaseLock (&gMemoryLock);

+}

+

+VOID

+PromoteMemoryResource (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Find untested but initialized memory regions in GCD map and convert them to be DXE allocatable.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  LIST_ENTRY                       *Link;

+  EFI_GCD_MAP_ENTRY                *Entry;

+

+  DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "Promote the memory resource\n"));

+  

+  CoreAcquireGcdMemoryLock ();

+  

+  Link = mGcdMemorySpaceMap.ForwardLink;

+  while (Link != &mGcdMemorySpaceMap) {

+

+    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+

+    if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved &&

+        Entry->EndAddress < EFI_MAX_ADDRESS &&

+        (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==

+          (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) {

+      //

+      // Update the GCD map

+      //

+      Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory;

+      Entry->Capabilities |= EFI_MEMORY_TESTED;

+      Entry->ImageHandle  = gDxeCoreImageHandle;

+      Entry->DeviceHandle = NULL;

+

+      //

+      // Add to allocable system memory resource

+      //      

+

+      CoreAddRange (

+        EfiConventionalMemory, 

+        Entry->BaseAddress, 

+        Entry->EndAddress, 

+        Entry->Capabilities & ~(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)

+        );

+      CoreFreeMemoryMapStack ();

+      

+    }

+

+    Link = Link->ForwardLink;

+  }

+  

+  CoreReleaseGcdMemoryLock ();

+  

+  return;

+}

+

+VOID

+CoreAddMemoryDescriptor (

+  IN EFI_MEMORY_TYPE       Type,

+  IN EFI_PHYSICAL_ADDRESS  Start,

+  IN UINT64                NumberOfPages,

+  IN UINT64                Attribute

+  )

+/*++

+

+Routine Description:

+

+  Called to initialize the memory map and add descriptors to

+  the current descriptor list.

+

+  The first descriptor that is added must be general usable

+  memory as the addition allocates heap.

+

+Arguments:

+

+  Type          - The type of memory to add

+

+  Start         - The starting address in the memory range

+                  Must be page aligned

+

+  NumberOfPages - The number of pages in the range

+

+  Attribute     - Attributes of the memory to add

+

+Returns:

+

+  None.  The range is added to the memory map

+

+--*/

+{

+  EFI_PHYSICAL_ADDRESS        End;

+  EFI_STATUS                  Status;

+  UINTN                       Index;

+  UINTN                       FreeIndex;

+

+  if ((Start & EFI_PAGE_MASK) != 0) {

+    return;

+  }

+

+  if (Type >= EfiMaxMemoryType && Type <= 0x7fffffff) {

+    return;

+  }

+  

+  CoreAcquireMemoryLock ();

+  End = Start + LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT) - 1;

+  CoreAddRange (Type, Start, End, Attribute);

+  CoreFreeMemoryMapStack ();

+  CoreReleaseMemoryLock ();

+

+  //

+  // Check to see if the statistics for the different memory types have already been established

+  //

+  if (mMemoryTypeInformationInitialized) {

+    return;

+  }

+

+  //

+  // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array

+  //

+  for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {

+    //

+    // Make sure the memory type in the gMemoryTypeInformation[] array is valid

+    //

+    Type = gMemoryTypeInformation[Index].Type;

+    if (Type < 0 || Type > EfiMaxMemoryType) {

+      continue;

+    }

+

+    if (gMemoryTypeInformation[Index].NumberOfPages != 0) {

+      //

+      // Allocate pages for the current memory type from the top of available memory

+      //

+      Status = CoreAllocatePages (

+                 AllocateAnyPages,

+                 Type,

+                 gMemoryTypeInformation[Index].NumberOfPages,

+                 &mMemoryTypeStatistics[Type].BaseAddress

+                 );

+      if (EFI_ERROR (Status)) {

+        //

+        // If an error occurs allocating the pages for the current memory type, then 

+        // free all the pages allocates for the previous memory types and return.  This

+        // operation with be retied when/if more memory is added to the system

+        //

+        for (FreeIndex = 0; FreeIndex < Index; FreeIndex++) {

+          //

+          // Make sure the memory type in the gMemoryTypeInformation[] array is valid

+          //

+          Type = gMemoryTypeInformation[FreeIndex].Type;

+          if (Type < 0 || Type > EfiMaxMemoryType) {

+            continue;

+          }

+

+          if (gMemoryTypeInformation[FreeIndex].NumberOfPages != 0) {

+            CoreFreePages (

+              mMemoryTypeStatistics[Type].BaseAddress, 

+              gMemoryTypeInformation[FreeIndex].NumberOfPages

+              );

+            mMemoryTypeStatistics[Type].BaseAddress    = 0;

+            mMemoryTypeStatistics[Type].MaximumAddress = EFI_MAX_ADDRESS;

+          }

+        }

+        return;

+      }

+

+      //

+      // Compute the address at the top of the current statistics

+      //

+      mMemoryTypeStatistics[Type].MaximumAddress = 

+        mMemoryTypeStatistics[Type].BaseAddress + 

+        LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT) - 1;

+

+      //

+      // If the current base address is the lowest address so far, then update the default 

+      // maximum address

+      //

+      if (mMemoryTypeStatistics[Type].BaseAddress < mDefaultMaximumAddress) {

+        mDefaultMaximumAddress = mMemoryTypeStatistics[Type].BaseAddress - 1;

+      }

+    }

+  }

+

+  //

+  // There was enough system memory for all the the memory types were allocated.  So,

+  // those memory areas can be freed for future allocations, and all future memory

+  // allocations can occur within their respective bins

+  //

+  for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {

+    //

+    // Make sure the memory type in the gMemoryTypeInformation[] array is valid

+    //

+    Type = gMemoryTypeInformation[Index].Type;

+    if (Type < 0 || Type > EfiMaxMemoryType) {

+      continue;

+    }

+

+    if (gMemoryTypeInformation[Index].NumberOfPages != 0) {

+      CoreFreePages (

+        mMemoryTypeStatistics[Type].BaseAddress, 

+        gMemoryTypeInformation[Index].NumberOfPages

+        );

+      gMemoryTypeInformation[Index].NumberOfPages = 0;

+    }

+  }

+

+  //

+  // If the number of pages reserved for a memory type is 0, then all allocations for that type

+  // should be in the default range.

+  //

+  for (Type = 0; Type < EfiMaxMemoryType; Type++) {

+    for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {

+      if (Type == (EFI_MEMORY_TYPE)gMemoryTypeInformation[Index].Type) {

+        mMemoryTypeStatistics[Type].InformationIndex = Index;

+      }

+    }

+    mMemoryTypeStatistics[Type].CurrentNumberOfPages = 0;

+    if (mMemoryTypeStatistics[Type].MaximumAddress == EFI_MAX_ADDRESS) {

+      mMemoryTypeStatistics[Type].MaximumAddress = mDefaultMaximumAddress;

+    }

+  }

+

+  mMemoryTypeInformationInitialized = TRUE;

+}

+

+

+STATIC

+VOID

+CoreAddRange (

+  IN EFI_MEMORY_TYPE          Type,

+  IN EFI_PHYSICAL_ADDRESS     Start,

+  IN EFI_PHYSICAL_ADDRESS     End,

+  IN UINT64                   Attribute

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Adds a ranges to the memory map.

+  The range must not already exist in the map.

+

+Arguments:

+

+  Type    - The type of memory range to add

+

+  Start   - The starting address in the memory range

+            Must be paged aligned

+

+  End     - The last address in the range

+          Must be the last byte of a page

+

+  Attribute - The attributes of the memory range to add

+

+Returns:

+

+  None.  The range is added to the memory map

+

+--*/

+{

+  LIST_ENTRY        *Link;

+  MEMORY_MAP        *Entry;

+

+  ASSERT ((Start & EFI_PAGE_MASK) == 0);

+  ASSERT (End > Start) ;

+

+  ASSERT_LOCKED (&gMemoryLock);

+  

+  DEBUG ((EFI_D_PAGE, "AddRange: %lx-%lx to %d\n", Start, End, Type));

+

+  //

+  // Memory map being altered so updated key

+  //

+  mMemoryMapKey += 1;

+

+  //

+  // UEFI 2.0 added an event group for notificaiton on memory map changes.

+  // So we need to signal this Event Group every time the memory map changes.

+  // If we are in EFI 1.10 compatability mode no event groups will be 

+  // found and nothing will happen we we call this function. These events

+  // will get signaled but since a lock is held around the call to this 

+  // function the notificaiton events will only be called after this funciton

+  // returns and the lock is released.

+  //

+  CoreNotifySignalList (&gEfiEventMemoryMapChangeGuid);

+

+  //

+  // Look for adjoining memory descriptor

+  //

+  

+  // Two memory descriptors can only be merged if they have the same Type

+  // and the same Attribute

+  //

+

+  Link = gMemoryMap.ForwardLink;

+  while (Link != &gMemoryMap) {

+    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+    Link  = Link->ForwardLink;

+

+    if (Entry->Type != Type) {

+      continue;

+    }

+

+    if (Entry->Attribute != Attribute) {

+      continue;

+    }

+

+    if (Entry->End + 1 == Start) {

+      

+      Start = Entry->Start;

+      RemoveMemoryMapEntry (Entry);

+

+    } else if (Entry->Start == End + 1) {

+      

+      End = Entry->End;

+      RemoveMemoryMapEntry (Entry);

+    }

+  }

+

+  //

+  // Add descriptor 

+  //

+

+  mMapStack[mMapDepth].Signature     = MEMORY_MAP_SIGNATURE;

+  mMapStack[mMapDepth].FromPool      = FALSE;

+  mMapStack[mMapDepth].Type          = Type;

+  mMapStack[mMapDepth].Start         = Start;

+  mMapStack[mMapDepth].End           = End;

+  mMapStack[mMapDepth].VirtualStart  = 0;

+  mMapStack[mMapDepth].Attribute     = Attribute;

+  InsertTailList (&gMemoryMap, &mMapStack[mMapDepth].Link);

+

+  mMapDepth += 1;

+  ASSERT (mMapDepth < MAX_MAP_DEPTH);

+

+  return ;

+}

+

+STATIC

+VOID

+CoreFreeMemoryMapStack (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Moves any memory descriptors that are on the

+  temporary descriptor stack to heap.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  MEMORY_MAP      *Entry;

+  MEMORY_MAP      *Entry2;

+  LIST_ENTRY      *Link2;

+

+  ASSERT_LOCKED (&gMemoryLock);

+

+  //

+  // If already freeing the map stack, then return

+  //

+  if (mFreeMapStack) {

+    return ;

+  }

+

+  //

+  // Move the temporary memory descriptor stack into pool

+  //

+  mFreeMapStack += 1;

+

+  while (mMapDepth) {

+

+    //

+    // Allocate memory for a entry

+    //

+    Entry = CoreAllocatePoolI (EfiRuntimeServicesData, sizeof(MEMORY_MAP));

+    

+    ASSERT (Entry);

+

+    //

+    // Update to proper entry

+    //

+    mMapDepth -= 1;

+

+    if (mMapStack[mMapDepth].Link.ForwardLink != NULL) {

+

+      //

+      // Move this entry to general pool

+      //

+      RemoveEntryList (&mMapStack[mMapDepth].Link);

+      mMapStack[mMapDepth].Link.ForwardLink = NULL;

+

+      CopyMem (Entry , &mMapStack[mMapDepth], sizeof (MEMORY_MAP));

+      Entry->FromPool = TRUE;

+

+      //

+      // Find insertion location

+      //

+      for (Link2 = gMemoryMap.ForwardLink; Link2 != &gMemoryMap; Link2 = Link2->ForwardLink) {

+        Entry2 = CR (Link2, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+        if (Entry2->FromPool && Entry2->Start > Entry->Start) {

+          break;

+        }

+      }

+

+      InsertTailList (Link2, &Entry->Link);

+

+    } else {

+

+      //

+      // It was removed, don't move it

+      //

+      CoreFreePoolI (Entry);

+

+    }

+  }

+

+  mFreeMapStack -= 1;

+}

+

+STATIC

+VOID

+RemoveMemoryMapEntry (

+  MEMORY_MAP      *Entry

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Removes a descriptor entry.

+

+Arguments:

+

+  Entry   - The entry to remove

+

+Returns:

+

+  None

+

+--*/

+{

+  RemoveEntryList (&Entry->Link);

+  Entry->Link.ForwardLink = NULL;

+

+  if (Entry->FromPool) {

+    CoreFreePoolI (Entry);

+  }

+}

+

+

+STATIC

+EFI_STATUS

+CoreConvertPages (

+  IN UINT64           Start,

+  IN UINT64           NumberOfPages,

+  IN EFI_MEMORY_TYPE  NewType

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Converts a memory range to the specified type.

+  The range must exist in the memory map.

+

+Arguments:

+

+  Start         - The first address of the range

+                  Must be page aligned

+

+  NumberOfPages - The number of pages to convert

+

+  NewType       - The new type for the memory range

+

+Returns:

+

+  EFI_INVALID_PARAMETER   - Invalid parameter

+  

+  EFI_NOT_FOUND           - Could not find a descriptor cover the specified range 

+                            or convertion not allowed.

+  

+  EFI_SUCCESS             - Successfully converts the memory range to the specified type.

+

+--*/

+{

+

+  UINT64          NumberOfBytes;

+  UINT64          End;

+  UINT64          RangeEnd;

+  UINT64          Attribute;

+  LIST_ENTRY      *Link;

+  MEMORY_MAP      *Entry;

+

+  Entry = NULL;

+  NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);

+  End = Start + NumberOfBytes - 1;

+

+  ASSERT (NumberOfPages);

+  ASSERT ((Start & EFI_PAGE_MASK) == 0);

+  ASSERT (End > Start) ;

+  ASSERT_LOCKED (&gMemoryLock);

+

+  if (NumberOfPages == 0 || (Start & EFI_PAGE_MASK ) || (Start > (Start + NumberOfBytes))) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Convert the entire range

+  //

+

+  while (Start < End) {

+

+    //

+    // Find the entry that the covers the range

+    //

+    for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {

+      Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+

+      if (Entry->Start <= Start && Entry->End > Start) {

+        break;

+      }

+    }

+

+    if (Link == &gMemoryMap) {

+      DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "ConvertPages: failed to find range %lx - %lx\n", Start, End));

+      return EFI_NOT_FOUND;

+    }

+

+    //

+    // Convert range to the end, or to the end of the descriptor

+    // if that's all we've got

+    //

+    RangeEnd = End;

+    if (Entry->End < End) {

+      RangeEnd = Entry->End;

+    }

+

+    DEBUG ((EFI_D_PAGE, "ConvertRange: %lx-%lx to %d\n", Start, RangeEnd, NewType));

+

+    //

+    // Debug code - verify conversion is allowed

+    //

+    if (!(NewType == EfiConventionalMemory ? 1 : 0) ^ (Entry->Type == EfiConventionalMemory ? 1 : 0)) {

+      DEBUG ((EFI_D_ERROR , "ConvertPages: Incompatible memory types\n"));

+      return EFI_NOT_FOUND;

+    }  

+

+    //

+    // Update counters for the number of pages allocated to each memory type

+    //

+    if (Entry->Type >= 0 && Entry->Type < EfiMaxMemoryType) {

+      if (Start >= mMemoryTypeStatistics[Entry->Type].BaseAddress && 

+          Start <= mMemoryTypeStatistics[Entry->Type].MaximumAddress) {

+        if (NumberOfPages > mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages) {

+          mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages = 0;

+        } else {

+          mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages -= NumberOfPages;

+        }

+      }

+    }

+

+    if (NewType >= 0 && NewType < EfiMaxMemoryType) {

+      if (Start >= mMemoryTypeStatistics[NewType].BaseAddress && Start <= mMemoryTypeStatistics[NewType].MaximumAddress) {

+        mMemoryTypeStatistics[NewType].CurrentNumberOfPages += NumberOfPages;

+        if (mMemoryTypeStatistics[NewType].CurrentNumberOfPages > 

+            gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages) {

+          gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages = (UINT32)mMemoryTypeStatistics[NewType].CurrentNumberOfPages;

+        }

+      }

+    }

+

+    //

+    // Pull range out of descriptor

+    //

+    if (Entry->Start == Start) {

+      

+      //

+      // Clip start

+      //

+      Entry->Start = RangeEnd + 1;

+

+    } else if (Entry->End == RangeEnd) {

+      

+      //

+      // Clip end

+      //

+      Entry->End = Start - 1;

+

+    } else {

+

+      //

+      // Pull it out of the center, clip current

+      //

+      

+      //

+      // Add a new one

+      //

+      mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;

+      mMapStack[mMapDepth].FromPool  = FALSE;

+      mMapStack[mMapDepth].Type      = Entry->Type;

+      mMapStack[mMapDepth].Start     = RangeEnd+1;

+      mMapStack[mMapDepth].End       = Entry->End;

+

+      //

+      // Inherit Attribute from the Memory Descriptor that is being clipped

+      //

+      mMapStack[mMapDepth].Attribute = Entry->Attribute;

+

+      Entry->End = Start - 1;

+      ASSERT (Entry->Start < Entry->End);

+

+      Entry = &mMapStack[mMapDepth];

+      InsertTailList (&gMemoryMap, &Entry->Link);

+

+      mMapDepth += 1;

+      ASSERT (mMapDepth < MAX_MAP_DEPTH);

+    }

+

+    //

+    // The new range inherits the same Attribute as the Entry 

+    //it is being cut out of

+    //

+    Attribute = Entry->Attribute;

+

+    //

+    // If the descriptor is empty, then remove it from the map

+    //

+    if (Entry->Start == Entry->End + 1) {

+      RemoveMemoryMapEntry (Entry);

+      Entry = NULL;

+    }

+    

+    //

+    // Add our new range in

+    //

+    CoreAddRange (NewType, Start, RangeEnd, Attribute);

+

+    //

+    // Move any map descriptor stack to general pool

+    //

+    CoreFreeMemoryMapStack ();

+

+    //

+    // Bump the starting address, and convert the next range

+    //

+    Start = RangeEnd + 1;

+  }

+

+  //

+  // Converted the whole range, done

+  //

+

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+UINT64

+CoreFindFreePagesI (

+  IN UINT64           MaxAddress,

+  IN UINT64           NumberOfPages,

+  IN EFI_MEMORY_TYPE  NewType,

+  IN UINTN            Alignment

+  )

+/*++

+

+Routine Description:

+

+  Internal function. Finds a consecutive free page range below

+  the requested address.

+

+Arguments:

+

+  MaxAddress    - The address that the range must be below

+

+  NumberOfPages - Number of pages needed

+

+  NewType       - The type of memory the range is going to be turned into

+

+  Alignment     - Bits to align with

+

+Returns:

+

+  The base address of the range, or 0 if the range was not found

+

+--*/

+{

+  UINT64          NumberOfBytes;

+  UINT64          Target;

+  UINT64          DescStart;

+  UINT64          DescEnd;

+  UINT64          DescNumberOfBytes;

+  LIST_ENTRY      *Link;

+  MEMORY_MAP      *Entry;

+

+  if ((MaxAddress < EFI_PAGE_MASK) ||(NumberOfPages == 0)) {

+    return 0;

+  }

+

+  if ((MaxAddress & EFI_PAGE_MASK) != EFI_PAGE_MASK) {

+    

+    //

+    // If MaxAddress is not aligned to the end of a page

+    //

+    

+    //

+    // Change MaxAddress to be 1 page lower

+    //

+    MaxAddress -= (EFI_PAGE_MASK + 1);

+    

+    //

+    // Set MaxAddress to a page boundary

+    //

+    MaxAddress &= ~EFI_PAGE_MASK;

+    

+    //

+    // Set MaxAddress to end of the page

+    //

+    MaxAddress |= EFI_PAGE_MASK;

+  }

+

+  NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);

+  Target = 0;

+

+  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {

+    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+  

+    //

+    // If it's not a free entry, don't bother with it

+    //

+    if (Entry->Type != EfiConventionalMemory) {

+      continue;

+    }

+

+    DescStart = Entry->Start;

+    DescEnd = Entry->End;

+

+    //

+    // If desc is past max allowed address, skip it

+    //

+    if (DescStart >= MaxAddress) {

+      continue;

+    }

+

+    //

+    // If desc ends past max allowed address, clip the end

+    //

+    if (DescEnd >= MaxAddress) {

+      DescEnd = MaxAddress;

+    }

+

+    DescEnd = ((DescEnd + 1) & (~(Alignment - 1))) - 1;

+

+    //

+    // Compute the number of bytes we can used from this 

+    // descriptor, and see it's enough to satisfy the request

+    //

+    DescNumberOfBytes = DescEnd - DescStart + 1;

+

+    if (DescNumberOfBytes >= NumberOfBytes) {

+

+      //

+      // If this is the best match so far remember it

+      //

+      if (DescEnd > Target) {

+        Target = DescEnd;

+      }

+    }

+  }          

+

+  //

+  // If this is a grow down, adjust target to be the allocation base

+  //

+  Target -= NumberOfBytes - 1;

+

+  //

+  // If we didn't find a match, return 0

+  //

+  if ((Target & EFI_PAGE_MASK) != 0) {

+    return 0;

+  }

+

+  return Target;

+}

+

+STATIC

+UINT64

+FindFreePages (

+    IN UINT64           MaxAddress,

+    IN UINT64           NoPages,

+    IN EFI_MEMORY_TYPE  NewType,

+    IN UINTN            Alignment

+    )

+/*++

+

+Routine Description:

+

+    Internal function.  Finds a consecutive free page range below

+    the requested address

+

+Arguments:

+

+    MaxAddress          - The address that the range must be below

+

+    NoPages             - Number of pages needed

+

+    NewType             - The type of memory the range is going to be turned into

+

+    Alignment           - Bits to align with

+

+Returns:

+

+    The base address of the range, or 0 if the range was not found.

+

+--*/

+{

+  UINT64  NewMaxAddress;

+  UINT64  Start;

+

+  NewMaxAddress = MaxAddress;

+

+  if (NewType >= 0 && NewType < EfiMaxMemoryType && NewMaxAddress >= mMemoryTypeStatistics[NewType].MaximumAddress) {

+    NewMaxAddress  = mMemoryTypeStatistics[NewType].MaximumAddress;

+  } else {

+    if (NewMaxAddress > mDefaultMaximumAddress) {

+      NewMaxAddress  = mDefaultMaximumAddress;

+    }

+  }

+

+  Start = CoreFindFreePagesI (NewMaxAddress, NoPages, NewType, Alignment);

+  if (!Start) {

+    Start = CoreFindFreePagesI (MaxAddress, NoPages, NewType, Alignment);

+    if (!Start) {

+      //

+      // Here means there may be no enough memory to use, so try to go through

+      // all the memory descript to promote the untested memory directly

+      //

+      PromoteMemoryResource ();

+

+      //

+      // Allocate memory again after the memory resource re-arranged

+      //

+      Start = CoreFindFreePagesI (MaxAddress, NoPages, NewType, Alignment);

+    }

+  }

+

+  return Start;

+}

+

+

+EFI_STATUS

+EFIAPI

+CoreAllocatePages (

+  IN EFI_ALLOCATE_TYPE      Type,

+  IN EFI_MEMORY_TYPE        MemoryType,

+  IN UINTN                  NumberOfPages,

+  IN OUT EFI_PHYSICAL_ADDRESS  *Memory

+  )

+/*++

+

+Routine Description:

+

+  Allocates pages from the memory map.

+

+Arguments:

+

+  Type          - The type of allocation to perform

+

+  MemoryType    - The type of memory to turn the allocated pages into

+

+  NumberOfPages - The number of pages to allocate

+

+  Memory        - A pointer to receive the base allocated memory address

+

+Returns:

+

+  Status. On success, Memory is filled in with the base address allocated

+

+  EFI_INVALID_PARAMETER     - Parameters violate checking rules defined in spec.

+  

+  EFI_NOT_FOUND             - Could not allocate pages match the requirement.

+  

+  EFI_OUT_OF_RESOURCES      - No enough pages to allocate.

+  

+  EFI_SUCCESS               - Pages successfully allocated.

+

+--*/

+{

+  EFI_STATUS      Status;

+  UINT64          Start;

+  UINT64          MaxAddress;

+  UINTN           Alignment;

+

+  if (Type < AllocateAnyPages || Type >= (UINTN) MaxAllocateType) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((MemoryType >= EfiMaxMemoryType && MemoryType <= 0x7fffffff) ||

+       MemoryType == EfiConventionalMemory) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;

+

+  if  (MemoryType == EfiACPIReclaimMemory   ||

+       MemoryType == EfiACPIMemoryNVS       ||

+       MemoryType == EfiRuntimeServicesCode ||

+       MemoryType == EfiRuntimeServicesData) {

+

+    Alignment = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;

+  }

+

+  if (Type == AllocateAddress) {

+    if ((*Memory & (Alignment - 1)) != 0) {

+      return EFI_NOT_FOUND;

+    }

+  }

+

+  NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1;

+  NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1);

+

+  //

+  // If this is for below a particular address, then 

+  //

+  Start = *Memory;

+  

+  //

+  // The max address is the max natively addressable address for the processor

+  //

+  MaxAddress = EFI_MAX_ADDRESS;

+  

+  if (Type == AllocateMaxAddress) {

+    MaxAddress = Start;

+  }

+

+  CoreAcquireMemoryLock ();

+  

+  //

+  // If not a specific address, then find an address to allocate

+  //

+  if (Type != AllocateAddress) {

+    Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment);

+    if (Start == 0) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto Done;

+    }

+  }

+

+  //

+  // Convert pages from FreeMemory to the requested type

+  //

+  Status = CoreConvertPages (Start, NumberOfPages, MemoryType);

+

+Done:

+  CoreReleaseMemoryLock ();

+

+  if (!EFI_ERROR (Status)) {

+    *Memory = Start;

+  }

+

+  return Status;

+}

+

+

+

+

+EFI_STATUS 

+EFIAPI

+CoreFreePages (

+  IN EFI_PHYSICAL_ADDRESS   Memory,

+  IN UINTN                  NumberOfPages

+  )

+/*++

+

+Routine Description:

+

+  Frees previous allocated pages.

+

+Arguments:

+

+  Memory        - Base address of memory being freed

+

+  NumberOfPages - The number of pages to free

+

+Returns:

+

+  EFI_NOT_FOUND       - Could not find the entry that covers the range

+  

+  EFI_INVALID_PARAMETER   - Address not aligned

+  

+  EFI_SUCCESS         -Pages successfully freed.

+

+--*/

+{

+  EFI_STATUS      Status;

+  LIST_ENTRY      *Link;

+  MEMORY_MAP      *Entry;

+  UINTN           Alignment;

+

+  //

+  // Free the range

+  //

+  CoreAcquireMemoryLock ();

+

+  //

+  // Find the entry that the covers the range

+  //

+  Entry = NULL;

+  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {

+    Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+    if (Entry->Start <= Memory && Entry->End > Memory) {

+        break;

+    }

+  }

+  if (Link == &gMemoryMap) {

+    CoreReleaseMemoryLock ();

+    return EFI_NOT_FOUND;

+  }

+

+  Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;

+

+  if  (Entry->Type == EfiACPIReclaimMemory   ||

+       Entry->Type == EfiACPIMemoryNVS       ||

+       Entry->Type == EfiRuntimeServicesCode ||

+       Entry->Type == EfiRuntimeServicesData) {

+

+    Alignment = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;

+

+  }

+

+  if ((Memory & (Alignment - 1)) != 0) {

+    CoreReleaseMemoryLock ();

+    return EFI_INVALID_PARAMETER;

+  }

+

+  NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1;

+  NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1);

+

+  Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);

+

+  CoreReleaseMemoryLock ();

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Destroy the contents

+  //

+  if (Memory < EFI_MAX_ADDRESS) {

+    DEBUG_CLEAR_MEMORY ((VOID *)(UINTN)Memory, NumberOfPages << EFI_PAGE_SHIFT);

+  }

+  

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreGetMemoryMap (

+  IN OUT UINTN                  *MemoryMapSize,

+  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,

+  OUT UINTN                     *MapKey,

+  OUT UINTN                     *DescriptorSize,

+  OUT UINT32                    *DescriptorVersion

+  )

+/*++

+

+Routine Description:

+

+  This function returns a copy of the current memory map. The map is an array of 

+  memory descriptors, each of which describes a contiguous block of memory.

+

+Arguments:

+

+  MemoryMapSize     - A pointer to the size, in bytes, of the MemoryMap buffer. On

+                      input, this is the size of the buffer allocated by the caller. 

+                      On output, it is the size of the buffer returned by the firmware 

+                      if the buffer was large enough, or the size of the buffer needed 

+                      to contain the map if the buffer was too small.

+  MemoryMap         - A pointer to the buffer in which firmware places the current memory map.

+  MapKey            - A pointer to the location in which firmware returns the key for the

+                      current memory map.

+  DescriptorSize    - A pointer to the location in which firmware returns the size, in

+                      bytes, of an individual EFI_MEMORY_DESCRIPTOR.

+  DescriptorVersion - A pointer to the location in which firmware returns the version

+                      number associated with the EFI_MEMORY_DESCRIPTOR.

+

+Returns:

+

+  EFI_SUCCESS           - The memory map was returned in the MemoryMap buffer.       

+  EFI_BUFFER_TOO_SMALL  - The MemoryMap buffer was too small. The current buffer size

+                          needed to hold the memory map is returned in MemoryMapSize.

+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value.                

+

+--*/

+{

+  EFI_STATUS                        Status;

+  UINTN                             Size;  

+  UINTN                             BufferSize;  

+  UINTN                             NumberOfRuntimeEntries;

+  LIST_ENTRY                        *Link;

+  MEMORY_MAP                        *Entry;  

+  EFI_GCD_MAP_ENTRY                 *GcdMapEntry;  

+

+  //

+  // Make sure the parameters are valid

+  //

+  if (MemoryMapSize == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  CoreAcquireGcdMemoryLock ();

+  

+  //

+  // Count the number of Reserved and MMIO entries that are marked for runtime use

+  //

+  NumberOfRuntimeEntries = 0;

+  for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {

+    GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||

+        (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {

+      if ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {

+        NumberOfRuntimeEntries++;

+      }

+    }

+  }

+

+  Size = sizeof (EFI_MEMORY_DESCRIPTOR);

+

+  //

+  // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will

+  // prevent people from having pointer math bugs in their code.

+  // now you have to use *DescriptorSize to make things work.

+  //

+  Size += sizeof(UINT64) - (Size % sizeof (UINT64));

+

+  if (DescriptorSize != NULL) {

+    *DescriptorSize = Size;

+  }

+  

+  if (DescriptorVersion != NULL) {

+    *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION;

+  }

+

+  CoreAcquireMemoryLock ();

+

+  //

+  // Compute the buffer size needed to fit the entire map

+  //

+  BufferSize = Size * NumberOfRuntimeEntries;

+  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {

+    BufferSize += Size;

+  }

+

+  if (*MemoryMapSize < BufferSize) {

+    Status = EFI_BUFFER_TOO_SMALL;

+    goto Done;

+  }

+

+  if (MemoryMap == NULL) {

+    Status = EFI_INVALID_PARAMETER;

+    goto Done;

+  }

+

+  //

+  // Build the map

+  //

+  ZeroMem (MemoryMap, Size);

+  for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {

+    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+    ASSERT (Entry->VirtualStart == 0);

+

+    MemoryMap->Type           = Entry->Type;

+    MemoryMap->PhysicalStart  = Entry->Start;

+    MemoryMap->VirtualStart   = Entry->VirtualStart;

+    MemoryMap->NumberOfPages  = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT);

+  

+    switch (Entry->Type) {

+    case EfiRuntimeServicesCode:

+    case EfiRuntimeServicesData:

+    case EfiPalCode:

+      MemoryMap->Attribute = Entry->Attribute | EFI_MEMORY_RUNTIME;

+      break;

+

+    default:

+      MemoryMap->Attribute = Entry->Attribute;

+      break;

+    }

+    

+    MemoryMap = NextMemoryDescriptor (MemoryMap, Size);

+  }

+

+  for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {

+    GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

+    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||

+        (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {

+      if ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {

+        

+        MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;

+        MemoryMap->VirtualStart  = 0;

+        MemoryMap->NumberOfPages = MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);

+        MemoryMap->Attribute     = GcdMapEntry->Attributes & ~EFI_MEMORY_PORT_IO;

+

+        if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {

+          MemoryMap->Type = EfiReservedMemoryType;

+        } else if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {

+          if ((GcdMapEntry->Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {

+            MemoryMap->Type = EfiMemoryMappedIOPortSpace;

+          } else {

+            MemoryMap->Type = EfiMemoryMappedIO;

+          }

+        }

+

+        MemoryMap = NextMemoryDescriptor (MemoryMap, Size);

+      }

+    }

+  }

+  

+  Status = EFI_SUCCESS;

+

+Done:

+

+  CoreReleaseMemoryLock ();

+  

+  CoreReleaseGcdMemoryLock ();

+  

+  // 

+  // Update the map key finally 

+  // 

+  if (MapKey != NULL) {

+    *MapKey = mMemoryMapKey;

+  }

+  

+  *MemoryMapSize = BufferSize;

+  

+  return Status;

+}

+

+VOID *

+CoreAllocatePoolPages (

+  IN EFI_MEMORY_TYPE    PoolType,

+  IN UINTN              NumberOfPages,

+  IN UINTN              Alignment

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Used by the pool functions to allocate pages

+  to back pool allocation requests.

+

+Arguments:

+

+  PoolType      - The type of memory for the new pool pages

+

+  NumberOfPages - No of pages to allocate

+

+  Alignment     - Bits to align.

+

+Returns:

+

+  The allocated memory, or NULL

+

+--*/

+{

+  EFI_STATUS        Status;

+  UINT64            Start;

+

+  //

+  // Find the pages to convert

+  //

+  Start = FindFreePages (EFI_MAX_ADDRESS, NumberOfPages, PoolType, Alignment);

+

+  //

+  // Convert it to boot services data

+  //

+  if (Start == 0) {

+    DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", NumberOfPages));

+  } else {

+    Status = CoreConvertPages (Start, NumberOfPages, PoolType);

+  }

+

+  return (VOID *)(UINTN)Start;

+}

+

+VOID

+CoreFreePoolPages (

+  IN EFI_PHYSICAL_ADDRESS   Memory,

+  IN UINTN                  NumberOfPages

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Frees pool pages allocated via AllocatePoolPages ()

+

+Arguments:

+

+  Memory        - The base address to free

+

+  NumberOfPages - The number of pages to free

+

+Returns:

+

+  None

+

+--*/

+{

+  CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);

+}

+

+

+EFI_STATUS

+CoreTerminateMemoryMap (

+  IN UINTN          MapKey

+  )

+/*++

+

+Routine Description:

+

+  Make sure the memory map is following all the construction rules, 

+  it is the last time to check memory map error before exit boot services.

+

+Arguments:

+

+  MapKey        - Memory map key

+

+Returns:

+

+  EFI_INVALID_PARAMETER       - Memory map not consistent with construction rules.

+  

+  EFI_SUCCESS                 - Valid memory map.

+

+--*/

+{

+  EFI_STATUS        Status;

+  LIST_ENTRY        *Link;

+  MEMORY_MAP        *Entry;

+

+  Status = EFI_SUCCESS;

+

+  CoreAcquireMemoryLock ();

+

+  if (MapKey == mMemoryMapKey) {

+

+    //

+    // Make sure the memory map is following all the construction rules

+    // This is the last chance we will be able to display any messages on

+    // the  console devices.

+    //

+

+    for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {

+      Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);

+      if (Entry->Attribute & EFI_MEMORY_RUNTIME) { 

+        if (Entry->Type == EfiACPIReclaimMemory || Entry->Type == EfiACPIMemoryNVS) {

+          DEBUG((EFI_D_ERROR, "ExitBootServices: ACPI memory entry has RUNTIME attribute set.\n"));

+          CoreReleaseMemoryLock ();

+          return EFI_INVALID_PARAMETER;

+        }

+        if (Entry->Start & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) {

+          DEBUG((EFI_D_ERROR, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));

+          CoreReleaseMemoryLock ();

+          return EFI_INVALID_PARAMETER;

+        }

+        if ((Entry->End + 1) & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) {

+          DEBUG((EFI_D_ERROR, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));

+          CoreReleaseMemoryLock ();

+          return EFI_INVALID_PARAMETER;

+        }

+      }

+    }

+

+    //

+    // The map key they gave us matches what we expect. Fall through and

+    // return success. In an ideal world we would clear out all of

+    // EfiBootServicesCode and EfiBootServicesData. However this function

+    // is not the last one called by ExitBootServices(), so we have to

+    // preserve the memory contents.

+    //

+  } else {

+    Status = EFI_INVALID_PARAMETER;

+  }

+

+  CoreReleaseMemoryLock ();

+

+  return Status;

+}

+

+

+

+

+

+

+

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/Mem/memdata.c b/edk2/EdkModulePkg/Core/Dxe/Mem/memdata.c
new file mode 100644
index 0000000..2fa4843
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Mem/memdata.c
@@ -0,0 +1,41 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  memdata.c

+

+Abstract:

+

+  Global data used in memory service

+

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+

+//

+// MemoryLock - synchronizes access to the memory map and pool lists

+//

+EFI_LOCK          gMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);

+

+//

+// MemoryMap - the current memory map

+//

+LIST_ENTRY        gMemoryMap  = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap);

+

+//

+// MemoryLastConvert - the last memory descriptor used for a conversion request

+//

+MEMORY_MAP        *gMemoryLastConvert;

diff --git a/edk2/EdkModulePkg/Core/Dxe/Mem/pool.c b/edk2/EdkModulePkg/Core/Dxe/Mem/pool.c
new file mode 100644
index 0000000..2f4669e
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Mem/pool.c
@@ -0,0 +1,613 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  pool.c

+

+Abstract:

+

+  EFI Memory pool management

+

+Revision History

+

+--*/

+

+#include <DxeMain.h>

+

+#define POOL_FREE_SIGNATURE   EFI_SIGNATURE_32('p','f','r','0')

+typedef struct {

+  UINT32          Signature;

+  UINT32          Index;

+  LIST_ENTRY      Link;

+} POOL_FREE;

+

+

+#define POOL_HEAD_SIGNATURE   EFI_SIGNATURE_32('p','h','d','0')

+typedef struct {

+  UINT32          Signature;

+  UINT32          Size;

+  EFI_MEMORY_TYPE Type;

+  UINTN           Reserved;

+  CHAR8           Data[1];

+} POOL_HEAD;

+

+#define SIZE_OF_POOL_HEAD EFI_FIELD_OFFSET(POOL_HEAD,Data)

+

+#define POOL_TAIL_SIGNATURE   EFI_SIGNATURE_32('p','t','a','l')

+typedef struct {

+  UINT32      Signature;

+  UINT32      Size;

+} POOL_TAIL;

+

+

+#define POOL_SHIFT  7

+

+#define POOL_OVERHEAD (SIZE_OF_POOL_HEAD + sizeof(POOL_TAIL))

+

+#define HEAD_TO_TAIL(a)   \

+  ((POOL_TAIL *) (((CHAR8 *) (a)) + (a)->Size - sizeof(POOL_TAIL)));

+

+

+#define SIZE_TO_LIST(a)   ((a) >> POOL_SHIFT)

+#define LIST_TO_SIZE(a)   ((a+1) << POOL_SHIFT)

+

+#define MAX_POOL_LIST       SIZE_TO_LIST(DEFAULT_PAGE_ALLOCATION)

+

+#define MAX_POOL_SIZE      0xffffff00

+

+//

+// Globals

+//

+

+#define POOL_SIGNATURE  EFI_SIGNATURE_32('p','l','s','t')

+typedef struct {

+    INTN             Signature;

+    UINTN            Used;

+    EFI_MEMORY_TYPE  MemoryType;

+    LIST_ENTRY       FreeList[MAX_POOL_LIST];

+    LIST_ENTRY       Link;

+} POOL; 

+

+

+POOL            PoolHead[EfiMaxMemoryType];

+LIST_ENTRY      PoolHeadList;

+

+//

+//

+//

+

+VOID

+CoreInitializePool (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Called to initialize the pool.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN  Type;

+  UINTN  Index;

+

+  for (Type=0; Type < EfiMaxMemoryType; Type++) {

+    PoolHead[Type].Signature  = 0;

+    PoolHead[Type].Used       = 0;

+    PoolHead[Type].MemoryType = Type;

+    for (Index=0; Index < MAX_POOL_LIST; Index++) {

+        InitializeListHead (&PoolHead[Type].FreeList[Index]);

+    }

+  }

+  InitializeListHead (&PoolHeadList);

+}

+

+

+POOL *

+LookupPoolHead (

+  IN EFI_MEMORY_TYPE  MemoryType

+  )

+/*++

+

+Routine Description:

+

+  Look up pool head for specified memory type.

+

+Arguments:

+

+  MemoryType      - Memory type of which pool head is looked for

+

+Returns:

+

+  Pointer of Corresponding pool head.

+

+--*/

+{

+  LIST_ENTRY      *Link;

+  POOL            *Pool;

+  UINTN           Index;

+

+  if (MemoryType >= 0 && MemoryType < EfiMaxMemoryType) {

+    return &PoolHead[MemoryType];

+  }

+

+  if (MemoryType < 0) {

+

+    for (Link = PoolHeadList.ForwardLink; Link != &PoolHeadList; Link = Link->ForwardLink) {

+      Pool = CR(Link, POOL, Link, POOL_SIGNATURE);

+      if (Pool->MemoryType == MemoryType) {

+        return Pool;

+      }

+    }

+

+    Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL));

+    if (Pool == NULL) {

+      return NULL;

+    }

+

+    Pool->Signature = POOL_SIGNATURE;

+    Pool->Used      = 0;

+    Pool->MemoryType = MemoryType;

+    for (Index=0; Index < MAX_POOL_LIST; Index++) {

+      InitializeListHead (&Pool->FreeList[Index]);

+    }

+

+    InsertHeadList (&PoolHeadList, &Pool->Link);

+

+    return Pool;

+  }

+

+  return NULL;

+}

+

+ 

+

+EFI_STATUS

+EFIAPI

+CoreAllocatePool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            Size,

+  OUT VOID            **Buffer

+  )

+/*++

+

+Routine Description:

+

+  Allocate pool of a particular type.

+

+Arguments:

+

+  PoolType    - Type of pool to allocate

+

+  Size        - The amount of pool to allocate

+

+  Buffer      - The address to return a pointer to the allocated pool

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - PoolType not valid

+  

+  EFI_OUT_OF_RESOURCES      - Size exceeds max pool size or allocation failed.  

+  

+  EFI_SUCCESS               - Pool successfully allocated.

+

+--*/

+{

+  EFI_STATUS    Status;

+

+  //

+  // If it's not a valid type, fail it

+  //

+  if ((PoolType >= EfiMaxMemoryType && PoolType <= 0x7fffffff) ||

+       PoolType == EfiConventionalMemory) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  *Buffer = NULL;

+  

+  //

+  // If size is too large, fail it

+  // Base on the EFI spec, return status of EFI_OUT_OF_RESOURCES

+  //

+  if (Size > MAX_POOL_SIZE) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Acquire the memory lock and make the allocation

+  //

+  Status = CoreAcquireLockOrFail (&gMemoryLock);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  *Buffer = CoreAllocatePoolI (PoolType, Size);

+  CoreReleaseMemoryLock ();

+  return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;

+}

+

+

+VOID *

+CoreAllocatePoolI (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            Size

+  )

+/*++

+

+Routine Description:

+

+  Internal function to allocate pool of a particular type.

+

+  Caller must have the memory lock held

+

+

+Arguments:

+

+  PoolType    - Type of pool to allocate

+

+  Size        - The amount of pool to allocate

+

+Returns:

+

+  The allocate pool, or NULL

+

+--*/

+{

+  POOL        *Pool;

+  POOL_FREE   *Free;

+  POOL_HEAD   *Head;

+  POOL_TAIL   *Tail;

+  CHAR8       *NewPage;

+  VOID        *Buffer;

+  UINTN       Index;

+  UINTN       FSize;

+  UINTN       offset;

+  UINTN       Adjustment;

+  UINTN       NoPages;

+

+  ASSERT_LOCKED (&gMemoryLock);

+

+  //

+  // Adjust the size by the pool header & tail overhead

+  //

+  

+  //

+  // Adjusting the Size to be of proper alignment so that

+  // we don't get an unaligned access fault later when

+  // pool_Tail is being initialized

+  //

+  ALIGN_VARIABLE (Size, Adjustment);

+

+  Size += POOL_OVERHEAD;

+  Index = SIZE_TO_LIST(Size);

+  Pool = LookupPoolHead (PoolType);

+  if (Pool== NULL) {

+    return NULL;

+  }

+  Head = NULL;

+

+  //

+  // If allocation is over max size, just allocate pages for the request

+  // (slow)

+  //

+  if (Index >= MAX_POOL_LIST) {

+    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;

+    NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);

+    Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);

+    goto Done;

+  }

+

+  //

+  // If there's no free pool in the proper list size, go get some more pages

+  //

+  if (IsListEmpty (&Pool->FreeList[Index])) {

+

+    //

+    // Get another page

+    //

+    NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);

+    if (NewPage == NULL) {

+      goto Done;

+    }

+

+    //

+    // Carve up new page into free pool blocks

+    //

+    offset = 0;

+    while (offset < DEFAULT_PAGE_ALLOCATION) {

+      ASSERT (Index < MAX_POOL_LIST);

+      FSize = LIST_TO_SIZE(Index);

+

+      while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {

+        Free = (POOL_FREE *) &NewPage[offset];          

+        Free->Signature = POOL_FREE_SIGNATURE;

+        Free->Index     = (UINT32)Index;

+        InsertHeadList (&Pool->FreeList[Index], &Free->Link);

+        offset += FSize;

+      }

+

+      Index -= 1;

+    }

+

+    ASSERT (offset == DEFAULT_PAGE_ALLOCATION);

+    Index = SIZE_TO_LIST(Size);

+  }

+

+  //

+  // Remove entry from free pool list

+  //

+  Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);

+  RemoveEntryList (&Free->Link);

+

+  Head = (POOL_HEAD *) Free;

+

+Done:

+  Buffer = NULL;

+

+  if (Head != NULL) {

+    

+    //

+    // If we have a pool buffer, fill in the header & tail info

+    //

+    Head->Signature = POOL_HEAD_SIGNATURE;

+    Head->Size      = (UINT32) Size;

+    Head->Type      = (EFI_MEMORY_TYPE) PoolType;

+    Tail            = HEAD_TO_TAIL (Head);

+    Tail->Signature = POOL_TAIL_SIGNATURE;

+    Tail->Size      = (UINT32) Size;

+    Buffer          = Head->Data;

+    DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);

+

+    DEBUG (

+      (EFI_D_POOL,

+      "AllcocatePoolI: Type %x, Addr %x (len %x) %,d\n",

+       PoolType, 

+       Buffer, 

+       Size - POOL_OVERHEAD, 

+      Pool->Used)

+      );

+

+    //

+    // Account the allocation

+    //

+    Pool->Used += Size;

+

+  } else {

+    DEBUG ((EFI_D_ERROR | EFI_D_POOL, "AllocatePool: failed to allocate %d bytes\n", Size));

+  }

+

+  return Buffer;

+}

+  

+

+

+EFI_STATUS

+EFIAPI

+CoreFreePool (

+  IN VOID        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Frees pool.

+

+Arguments:

+

+  Buffer      - The allocated pool entry to free

+

+Returns:

+

+  EFI_INVALID_PARAMETER   - Buffer is not a valid value.

+  

+  EFI_SUCCESS             - Pool successfully freed.

+

+--*/

+{

+  EFI_STATUS Status;

+

+  if (NULL == Buffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CoreAcquireMemoryLock ();

+  Status = CoreFreePoolI (Buffer);

+  CoreReleaseMemoryLock ();

+  return Status;

+}

+

+

+EFI_STATUS

+CoreFreePoolI (

+  IN VOID       *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Internal function to free a pool entry.

+

+  Caller must have the memory lock held

+

+

+Arguments:

+

+  Buffer      - The allocated pool entry to free

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Buffer not valid

+  

+  EFI_SUCCESS               - Buffer successfully freed.

+

+--*/

+{

+  POOL        *Pool;

+  POOL_HEAD   *Head;

+  POOL_TAIL   *Tail;

+  POOL_FREE   *Free;

+  UINTN       Index;

+  UINTN       NoPages;

+  UINTN       Size;

+  CHAR8       *NewPage;

+  UINTN       FSize;

+  UINTN       offset;

+  BOOLEAN     AllFree;

+

+  ASSERT(NULL != Buffer);

+  //

+  // Get the head & tail of the pool entry

+  //

+  Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);

+  ASSERT(NULL != Head);

+

+  if (Head->Signature != POOL_HEAD_SIGNATURE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Tail = HEAD_TO_TAIL (Head);

+  ASSERT(NULL != Tail);

+

+  //

+  // Debug

+  //

+  ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);

+  ASSERT (Head->Size == Tail->Size);

+  ASSERT_LOCKED (&gMemoryLock);

+

+  if (Tail->Signature != POOL_TAIL_SIGNATURE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Head->Size != Tail->Size) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Determine the pool type and account for it

+  //

+  Size = Head->Size;

+  Pool = LookupPoolHead (Head->Type);

+  if (Pool == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  Pool->Used -= Size;

+  DEBUG ((EFI_D_POOL, "FreePool: %x (len %x) %,d\n", Head->Data, Head->Size - POOL_OVERHEAD, Pool->Used));

+

+  //

+  // Determine the pool list 

+  //

+  Index = SIZE_TO_LIST(Size);

+  DEBUG_CLEAR_MEMORY (Head, Size);

+

+  //

+  // If it's not on the list, it must be pool pages

+  //

+  if (Index >= MAX_POOL_LIST) {

+

+    //

+    // Return the memory pages back to free memory

+    //

+    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;

+    NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);

+    CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);

+

+  } else {

+

+    //

+    // Put the pool entry onto the free pool list

+    //

+    Free = (POOL_FREE *) Head;

+    ASSERT(NULL != Free);

+    Free->Signature = POOL_FREE_SIGNATURE;

+    Free->Index     = (UINT32)Index;

+    InsertHeadList (&Pool->FreeList[Index], &Free->Link);

+

+    //

+    // See if all the pool entries in the same page as Free are freed pool 

+    // entries

+    //

+    NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));

+    Free = (POOL_FREE *) &NewPage[0];

+    ASSERT(NULL != Free);

+

+    if (Free->Signature == POOL_FREE_SIGNATURE) {

+

+      Index = Free->Index;

+

+      AllFree = TRUE;

+      offset = 0;

+      

+      while ((offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {

+        FSize = LIST_TO_SIZE(Index);

+        while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {

+          Free = (POOL_FREE *) &NewPage[offset];

+          ASSERT(NULL != Free);

+          if (Free->Signature != POOL_FREE_SIGNATURE) {

+            AllFree = FALSE;

+          }

+          offset += FSize;

+        }

+        Index -= 1;

+      }

+

+      if (AllFree) {

+

+        //

+        // All of the pool entries in the same page as Free are free pool 

+        // entries

+        // Remove all of these pool entries from the free loop lists.

+        //

+        Free = (POOL_FREE *) &NewPage[0];

+        ASSERT(NULL != Free);

+        Index = Free->Index;

+        offset = 0;

+        

+        while (offset < DEFAULT_PAGE_ALLOCATION) {

+          FSize = LIST_TO_SIZE(Index);

+          while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {

+            Free = (POOL_FREE *) &NewPage[offset];

+            ASSERT(NULL != Free);

+            RemoveEntryList (&Free->Link);

+            offset += FSize;

+          }

+          Index -= 1;

+        }

+

+        //

+        // Free the page

+        //

+        CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));

+      }

+    }

+  }

+

+  //

+  // If this is an OS specific memory type, then check to see if the last 

+  // portion of that memory type has been freed.  If it has, then free the

+  // list entry for that memory type

+  //

+  if (Pool->MemoryType < 0 && Pool->Used == 0) {

+    RemoveEntryList (&Pool->Link);

+    CoreFreePoolI (Pool);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/edk2/EdkModulePkg/Core/Dxe/Misc/DebugImageInfo.c
new file mode 100644
index 0000000..e7f90de
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Misc/DebugImageInfo.c
@@ -0,0 +1,260 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugImageInfo.c

+    

+Abstract:

+

+  Support functions for managing debug image info table when loading and unloading

+  images.

+

+--*/

+

+#include <DxeMain.h>

+

+

+static EFI_DEBUG_IMAGE_INFO_TABLE_HEADER  mDebugInfoTableHeader = {

+  0,          // volatile UINT32                 UpdateStatus;

+  0,          // UINT32                          TableSize;

+  NULL        // EFI_DEBUG_IMAGE_INFO            *EfiDebugImageInfoTable;

+};

+

+static EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;

+

+    

+VOID

+CoreInitializeDebugImageInfoTable (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Creates and initializes the DebugImageInfo Table.  Also creates the configuration

+  table and registers it into the system table.

+

+Arguments:

+  None

+

+Returns:

+  NA

+

+Notes:

+  This function allocates memory, frees it, and then allocates memory at an

+  address within the initial allocation. Since this function is called early

+  in DXE core initialization (before drivers are dispatched), this should not

+  be a problem.

+

+--*/

+{ 

+  EFI_STATUS                          Status;

+  EFI_PHYSICAL_ADDRESS                Mem;

+  UINTN                               NumberOfPages; 

+

+  //

+  // Allocate boot services memory for the structure. It's required to be aligned on

+  // a 4M boundary, so allocate a 4M block (plus what we require), free it up, calculate

+  // a 4M aligned address within the memory we just freed, and then allocate memory at that

+  // address for our initial structure.

+  //

+  NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER));  

+

+  Status = CoreAllocatePages (AllocateAnyPages, EfiBootServicesData, NumberOfPages , &Mem); 

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR(Status)) {

+    return;

+  }

+  Status = CoreFreePages (Mem, NumberOfPages); 

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR(Status)) {

+    return;

+  }

+  //

+  // Now get a 4M aligned address within the memory range we were given.

+  // Then allocate memory at that address

+  //

+  Mem = (Mem + FOUR_MEG_MASK) & (~FOUR_MEG_MASK);

+  

+  Status = CoreAllocatePages (AllocateAddress, EfiBootServicesData, NumberOfPages - FOUR_MEG_PAGES, &Mem); 

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR(Status)) {

+    return;

+  }

+  //

+  // We now have a 4M aligned page allocated, so fill in the data structure.

+  // Ideally we would update the CRC now as well, but the service may not yet be available.

+  // See comments in the CoreUpdateDebugTableCrc32() function below for details.

+  //

+  mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem;

+  mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;

+  mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gST;

+  mDebugTable->Crc32 = 0;

+  Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);

+  ASSERT_EFI_ERROR (Status);

+}

+

+VOID

+CoreUpdateDebugTableCrc32 (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Update the CRC32 in the Debug Table.

+  Since the CRC32 service is made available by the Runtime driver, we have to

+  wait for the Runtime Driver to be installed before the CRC32 can be computed.

+  This function is called elsewhere by the core when the runtime architectural

+  protocol is produced.

+

+Arguments:

+  None

+

+Returns:

+  NA

+

+--*/

+{

+  ASSERT(mDebugTable != NULL);

+  mDebugTable->Crc32 = 0;

+  gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);

+}

+

+VOID

+CoreNewDebugImageInfoEntry (

+  IN  UINTN                       ImageInfoType,

+  IN  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage,

+  IN  EFI_HANDLE                  ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Adds a new DebugImageInfo structure to the DebugImageInfo Table.  Re-Allocates

+  the table if it's not large enough to accomidate another entry.

+

+Arguments:

+

+  ImageInfoType     - type of debug image information

+  LoadedImage       - pointer to the loaded image protocol for the image being loaded

+  ImageHandle       - image handle for the image being loaded

+

+Returns:

+  NA

+

+--*/

+{    

+  EFI_DEBUG_IMAGE_INFO      *Table;

+  EFI_DEBUG_IMAGE_INFO      *NewTable;

+  UINTN                     Index;

+  UINTN                     MaxTableIndex;

+  UINTN                     TableSize;

+

+  //

+  // Set the flag indicating that we're in the process of updating the table.

+  //

+  mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

+

+  Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;

+  MaxTableIndex = mDebugInfoTableHeader.TableSize;

+

+  for (Index = 0; Index < MaxTableIndex; Index++) {

+    if (Table[Index].NormalImage == NULL) {

+      //

+      // We have found a free entry so exit the loop

+      //

+      break;

+    }

+  }

+  if (Index == MaxTableIndex) {

+    //

+    //  Table is full, so re-allocate another page for a larger table...

+    //

+    TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;

+    NewTable = CoreAllocateZeroBootServicesPool (TableSize + EFI_PAGE_SIZE);

+    if (NewTable == NULL) {

+      mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

+      return;

+    }

+    //

+    // Copy the old table into the new one

+    //

+    CopyMem (NewTable, Table, TableSize);

+    //

+    // Free the old table

+    //

+    CoreFreePool (Table);

+    //

+    // Update the table header

+    //

+    Table = NewTable;

+    mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;

+    mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;

+  }

+  //

+  // Allocate data for new entry

+  //

+  Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));

+  if (Table[Index].NormalImage != NULL) {

+    //

+    // Update the entry

+    //

+    Table[Index].NormalImage->ImageInfoType               = (UINT32) ImageInfoType;

+    Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;

+    Table[Index].NormalImage->ImageHandle                 = ImageHandle;

+  }

+  mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

+}

+

+

+VOID

+CoreRemoveDebugImageInfoEntry (

+  EFI_HANDLE ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  Removes and frees an entry from the DebugImageInfo Table.

+

+Arguments:

+

+  ImageHandle       - image handle for the image being unloaded

+

+Returns:

+

+  NA

+

+--*/

+{    

+  EFI_DEBUG_IMAGE_INFO  *Table;

+  UINTN                 Index;

+

+  mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

+

+  Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;

+

+  for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {

+    if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {

+      //

+      // Found a match. Free up the record, then NULL the pointer to indicate the slot

+      // is free.

+      //

+      CoreFreePool (Table[Index].NormalImage);

+      Table[Index].NormalImage = NULL;

+      break;

+    }

+  }

+  mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c b/edk2/EdkModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
new file mode 100644
index 0000000..e81fcad
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
@@ -0,0 +1,214 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  InstallConfigurationTable.c

+

+

+Abstract:

+

+  Tiano Miscellaneous Services InstallConfigurationTable service

+

+--*/

+

+#include <DxeMain.h>

+

+#define CONFIG_TABLE_SIZE_INCREASED 0x10

+

+UINTN mSystemTableAllocateSize = 0;

+

+

+EFI_STATUS

+CoreGetConfigTable (

+  IN EFI_GUID *Guid,

+  OUT VOID    **Table

+  )

+/*++

+

+Routine Description:

+

+  Find a config table by name in system table's ConfigurationTable.

+

+Arguments:

+

+  Guid        - The table name to look for

+  

+  Table       - Pointer of the config table

+

+Returns: 

+

+  EFI_NOT_FOUND       - Could not find the table in system table's ConfigurationTable.

+  

+  EFI_SUCCESS         - Table successfully found.

+

+--*/

+{

+  UINTN Index;

+

+  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {

+    if (CompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) {

+      *Table = gST->ConfigurationTable[Index].VendorTable;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CoreInstallConfigurationTable (

+  IN EFI_GUID *Guid,

+  IN VOID     *Table

+  )

+/*++

+

+Routine Description:

+

+  Boot Service called to add, modify, or remove a system configuration table from 

+  the EFI System Table.

+

+Arguments:

+

+  Guid     -  Pointer to the GUID for the entry to add, update, or remove

+  Table    -  Pointer to the configuration table for the entry to add, update, or

+              remove, may be NULL.

+

+Returns:

+  

+  EFI_SUCCESS               Guid, Table pair added, updated, or removed.

+  EFI_INVALID_PARAMETER     Input GUID not valid.

+  EFI_NOT_FOUND             Attempted to delete non-existant entry

+  EFI_OUT_OF_RESOURCES      Not enough memory available

+

+--*/

+{

+  UINTN                   Index;

+  EFI_CONFIGURATION_TABLE *EfiConfigurationTable;

+

+  //

+  // If Guid is NULL, then this operation cannot be performed

+  //

+  if (Guid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiConfigurationTable = gST->ConfigurationTable;

+

+  //

+  // Search all the table for an entry that matches Guid

+  //

+  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {

+    if (CompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) {

+      break;

+    }

+  }

+

+  if (Index < gST->NumberOfTableEntries) {

+    //

+    // A match was found, so this is either a modify or a delete operation

+    //

+    if (Table != NULL) {

+      //

+      // If Table is not NULL, then this is a modify operation.

+      // Modify the table enty and return.

+      //

+      gST->ConfigurationTable[Index].VendorTable = Table;

+      return EFI_SUCCESS;

+    }

+

+    //

+    // A match was found and Table is NULL, so this is a delete operation.

+    //

+    gST->NumberOfTableEntries--;

+

+    //

+    // Copy over deleted entry

+    //

+    CopyMem (

+      &(EfiConfigurationTable[Index]),

+      &(gST->ConfigurationTable[Index + 1]),

+      (gST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)

+      );

+

+  } else {

+

+    //

+    // No matching GUIDs were found, so this is an add operation.

+    //

+

+    if (Table == NULL) {

+      //

+      // If Table is NULL on an add operation, then return an error.

+      //

+      return EFI_NOT_FOUND;

+    }

+

+    //

+    // Assume that Index == gST->NumberOfTableEntries

+    //

+    if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {

+      //

+      // Allocate a table with one additional entry.

+      //

+      mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));

+      EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize);

+      if (EfiConfigurationTable == NULL) {

+        //

+        // If a new table could not be allocated, then return an error.

+        //

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      if (gST->ConfigurationTable != NULL) {

+        //

+        // Copy the old table to the new table.

+        //

+        CopyMem (

+          EfiConfigurationTable,

+          gST->ConfigurationTable,

+          Index * sizeof (EFI_CONFIGURATION_TABLE)

+          );

+

+        //

+        // Free Old Table

+        //

+        CoreFreePool (gST->ConfigurationTable);

+      }

+

+      //

+      // Update System Table

+      //

+      gST->ConfigurationTable = EfiConfigurationTable;

+    }

+

+    //

+    // Fill in the new entry

+    //

+    CopyMem ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid, sizeof (EFI_GUID));

+    EfiConfigurationTable[Index].VendorTable  = Table;

+

+    //

+    // This is an add operation, so increment the number of table entries

+    //

+    gST->NumberOfTableEntries++;

+  }

+

+  //

+  // Fix up the CRC-32 in the EFI System Table

+  //

+  CalculateEfiHdrCrc (&gST->Hdr);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c b/edk2/EdkModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c
new file mode 100644
index 0000000..c11c926
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c
@@ -0,0 +1,83 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    SetWatchdogTimer.c

+

+Abstract:

+

+    Tiano Miscellaneous Services SetWatchdogTimer service implementation

+

+--*/

+

+#include <DxeMain.h>

+

+#define WATCHDOG_TIMER_CALIBRATE_PER_SECOND 10000000

+

+

+EFI_STATUS

+EFIAPI

+CoreSetWatchdogTimer (

+  IN UINTN    Timeout,

+  IN UINT64   WatchdogCode,

+  IN UINTN    DataSize,

+  IN CHAR16   *WatchdogData OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Sets the system's watchdog timer.

+

+Arguments:

+

+  Timeout         The number of seconds.  Zero disables the timer.

+

+  ///////following  three parameters are left for platform specific using  

+  

+  WatchdogCode    The numberic code to log.  0x0 to 0xffff are firmware

+  DataSize        Size of the optional data

+  WatchdogData    Optional Null terminated unicode string followed by binary 

+                  data.

+

+Returns:

+

+  EFI_SUCCESS               Timeout has been set

+  EFI_NOT_AVAILABLE_YET     WatchdogTimer is not available yet 

+  EFI_UNSUPPORTED           System does not have a timer (currently not used)

+  EFI_DEVICE_ERROR          Could not complete due to hardware error

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Check our architectural protocol

+  //

+  if (gWatchdogTimer == NULL) {

+    return EFI_NOT_AVAILABLE_YET;

+  }

+

+  //

+  // Attempt to set the timeout

+  //

+  Status = gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, MultU64x32 (Timeout, WATCHDOG_TIMER_CALIBRATE_PER_SECOND));

+

+  //

+  // Check for errors

+  //

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/Misc/Stall.c b/edk2/EdkModulePkg/Core/Dxe/Misc/Stall.c
new file mode 100644
index 0000000..c251f31
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/Misc/Stall.c
@@ -0,0 +1,82 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+    Stall.c

+

+Abstract:

+

+    Tiano Miscellaneous Services Stall service implementation

+

+--*/

+

+//

+// Include statements

+//

+

+#include <DxeMain.h>

+

+

+EFI_STATUS

+EFIAPI

+CoreStall (

+  IN UINTN            Microseconds

+  )

+/*++

+

+Routine Description:

+

+  Introduces a fine-grained stall.

+

+Arguments:

+

+  Microseconds      The number of microseconds to stall execution

+

+Returns:

+

+  EFI_SUCCESS            - Execution was stalled for at least the requested amount

+                           of microseconds.

+

+  EFI_NOT_AVAILABLE_YET  - gMetronome is not available yet

+

+--*/

+{

+  UINT32  Counter;

+  UINT32  Remainder;

+

+  if (gMetronome == NULL) {

+    return EFI_NOT_AVAILABLE_YET;

+  }

+

+  //

+  // Calculate the number of ticks by dividing the number of microseconds by

+  // the TickPeriod.

+  // Calcullation is based on 100ns unit.

+  //

+  Counter = (UINT32) DivU64x32Remainder (

+                       Microseconds * 10,

+                       gMetronome->TickPeriod,

+                       &Remainder

+                       );

+

+  //

+  // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick

+  // periods, thus attempting to ensure Microseconds of stall time.

+  //

+  if (Remainder != 0) {

+    Counter++;

+  }

+

+  gMetronome->WaitForTick (gMetronome, Counter);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/edk2/EdkModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
new file mode 100644
index 0000000..e98b80c
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
@@ -0,0 +1,1339 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CoreSectionExtraction.c

+  

+Abstract:

+

+  Section Extraction Protocol implementation.

+  

+  Stream database is implemented as a linked list of section streams,

+  where each stream contains a linked list of children, which may be leaves or

+  encapsulations.  

+  

+  Children that are encapsulations generate new stream entries

+  when they are created.  Streams can also be created by calls to 

+  SEP->OpenSectionStream().

+  

+  The database is only created far enough to return the requested data from

+  any given stream, or to determine that the requested data is not found.

+  

+  If a GUIDed encapsulation is encountered, there are three possiblilites.

+  

+  1) A support protocol is found, in which the stream is simply processed with

+     the support protocol.

+     

+  2) A support protocol is not found, but the data is available to be read

+     without processing.  In this case, the database is built up through the

+     recursions to return the data, and a RPN event is set that will enable

+     the stream in question to be refreshed if and when the required section

+     extraction protocol is published.This insures the AuthenticationStatus 

+     does not become stale in the cache.

+     

+  3) A support protocol is not found, and the data is not available to be read

+     without it.  This results in EFI_PROTOCOL_ERROR.

+  

+--*/

+

+#include <DxeMain.h>

+

+//

+// Local defines and typedefs

+//

+#define CORE_SECTION_CHILD_SIGNATURE  EFI_SIGNATURE_32('S','X','C','S')

+#define CHILD_SECTION_NODE_FROM_LINK(Node) \

+  CR (Node, CORE_SECTION_CHILD_NODE, Link, CORE_SECTION_CHILD_SIGNATURE)

+

+typedef struct {

+  UINT32                      Signature;

+  LIST_ENTRY                  Link;

+  UINT32                      Type;

+  UINT32                      Size;

+  //

+  // StreamBase + OffsetInStream == pointer to section header in stream.  The

+  // stream base is always known when walking the sections within.

+  //

+  UINT32                      OffsetInStream;

+  //

+  // Then EncapsulatedStreamHandle below is always 0 if the section is NOT an

+  // encapsulating section.  Otherwise, it contains the stream handle

+  // of the encapsulated stream.  This handle is ALWAYS produced any time an

+  // encapsulating child is encountered, irrespective of whether the

+  // encapsulated stream is processed further.

+  //

+  UINTN                       EncapsulatedStreamHandle;

+  EFI_GUID                    *EncapsulationGuid;

+} CORE_SECTION_CHILD_NODE;

+

+#define CORE_SECTION_STREAM_SIGNATURE EFI_SIGNATURE_32('S','X','S','S')

+#define STREAM_NODE_FROM_LINK(Node) \

+  CR (Node, CORE_SECTION_STREAM_NODE, Link, CORE_SECTION_STREAM_SIGNATURE)

+

+typedef struct {

+  UINT32                      Signature;

+  LIST_ENTRY                  Link;

+  UINTN                       StreamHandle;

+  UINT8                       *StreamBuffer;

+  UINTN                       StreamLength;

+  LIST_ENTRY                  Children;

+  //

+  // Authentication status is from GUIDed encapsulations.

+  //

+  UINT32                      AuthenticationStatus;

+} CORE_SECTION_STREAM_NODE;

+

+#define NULL_STREAM_HANDLE    0

+

+typedef struct {

+  CORE_SECTION_CHILD_NODE     *ChildNode;

+  CORE_SECTION_STREAM_NODE    *ParentStream;

+  VOID                        *Registration;

+  EFI_EVENT                   Event;

+} RPN_EVENT_CONTEXT;

+  

+  

+

+//

+// Local prototypes

+//

+

+STATIC

+BOOLEAN

+ChildIsType (

+  IN CORE_SECTION_STREAM_NODE                 *Stream,

+  IN CORE_SECTION_CHILD_NODE                  *Child,

+  IN EFI_SECTION_TYPE                         SearchType,

+  IN EFI_GUID                                 *SectionDefinitionGuid

+  );

+

+STATIC

+VOID

+EFIAPI

+NotifyGuidedExtraction (

+  IN  EFI_EVENT                             Event,

+  IN  VOID                                  *RpnContext

+  );

+

+STATIC

+VOID

+CreateGuidedExtractionRpnEvent (

+  IN CORE_SECTION_STREAM_NODE                 *ParentStream,

+  IN CORE_SECTION_CHILD_NODE                  *ChildNode

+  );

+

+EFI_STATUS

+EFIAPI

+OpenSectionStream (

+  IN     EFI_SECTION_EXTRACTION_PROTOCOL      *This,

+  IN     UINTN                                SectionStreamLength,

+  IN     VOID                                 *SectionStream,

+     OUT UINTN                                *SectionStreamHandle

+  );

+  

+EFI_STATUS

+EFIAPI

+GetSection (

+  IN EFI_SECTION_EXTRACTION_PROTOCOL          *This,

+  IN UINTN                                    SectionStreamHandle,

+  IN EFI_SECTION_TYPE                         *SectionType,

+  IN EFI_GUID                                 *SectionDefinitionGuid,

+  IN UINTN                                    SectionInstance,

+  IN VOID                                     **Buffer,

+  IN OUT UINTN                                *BufferSize,

+  OUT UINT32                                  *AuthenticationStatus

+  );

+  

+EFI_STATUS

+EFIAPI

+CloseSectionStream (

+  IN  EFI_SECTION_EXTRACTION_PROTOCOL         *This,

+  IN  UINTN                                   StreamHandleToClose

+  );

+  

+STATIC

+EFI_STATUS

+FindStreamNode (

+  IN  UINTN                                   SearchHandle,

+  OUT CORE_SECTION_STREAM_NODE                **FoundStream

+  );

+  

+STATIC

+EFI_STATUS

+FindChildNode (

+  IN     CORE_SECTION_STREAM_NODE             *SourceStream,

+  IN     EFI_SECTION_TYPE                     SearchType,

+  IN     UINTN                                *SectionInstance,

+  IN     EFI_GUID                             *SectionDefinitionGuid,

+  OUT    CORE_SECTION_CHILD_NODE              **FoundChild,

+  OUT    CORE_SECTION_STREAM_NODE             **FoundStream,

+  OUT    UINT32                               *AuthenticationStatus

+  );

+  

+STATIC

+EFI_STATUS

+CreateChildNode (

+  IN     CORE_SECTION_STREAM_NODE             *Stream,

+  IN     UINT32                               ChildOffset,

+  OUT    CORE_SECTION_CHILD_NODE              **ChildNode

+  );

+  

+STATIC

+VOID

+FreeChildNode (

+  IN  CORE_SECTION_CHILD_NODE                 *ChildNode

+  );

+  

+STATIC

+EFI_STATUS

+OpenSectionStreamEx (

+  IN     UINTN                                SectionStreamLength,

+  IN     VOID                                 *SectionStream,

+  IN     BOOLEAN                              AllocateBuffer,

+  IN     UINT32                               AuthenticationStatus,   

+     OUT UINTN                                *SectionStreamHandle

+  );

+  

+STATIC

+BOOLEAN

+IsValidSectionStream (

+  IN  VOID                                    *SectionStream,

+  IN  UINTN                                   SectionStreamLength

+  );

+  

+//

+// Module globals

+//

+LIST_ENTRY mStreamRoot = INITIALIZE_LIST_HEAD_VARIABLE (mStreamRoot);

+

+EFI_HANDLE mSectionExtractionHandle = NULL;

+

+EFI_SECTION_EXTRACTION_PROTOCOL mSectionExtraction = { 

+  OpenSectionStream, 

+  GetSection, 

+  CloseSectionStream

+};

+

+                                             

+EFI_STATUS

+EFIAPI

+InitializeSectionExtraction (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+/*++

+

+Routine Description: 

+  Entry point of the section extraction code. Initializes an instance of the 

+  section extraction interface and installs it on a new handle.

+

+Arguments:  

+  ImageHandle   EFI_HANDLE: A handle for the image that is initializing this driver

+  SystemTable   EFI_SYSTEM_TABLE: A pointer to the EFI system table        

+

+Returns:  

+  EFI_SUCCESS:  Driver initialized successfully

+  EFI_OUT_OF_RESOURCES:   Could not allocate needed resources

+

+--*/

+{

+  EFI_STATUS                         Status;

+

+  //

+  // Install SEP to a new handle

+  //

+  Status = CoreInstallProtocolInterface (

+            &mSectionExtractionHandle,

+            &gEfiSectionExtractionProtocolGuid,

+            EFI_NATIVE_INTERFACE,

+            &mSectionExtraction

+            );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+OpenSectionStream (

+  IN     EFI_SECTION_EXTRACTION_PROTOCOL           *This,

+  IN     UINTN                                     SectionStreamLength,

+  IN     VOID                                      *SectionStream,

+     OUT UINTN                                     *SectionStreamHandle

+  )

+/*++

+

+Routine Description:

+  SEP member function.  This function creates and returns a new section stream

+  handle to represent the new section stream.

+

+Arguments:

+  This                - Indicates the calling context.

+  SectionStreamLength - Size in bytes of the section stream.

+  SectionStream       - Buffer containing the new section stream.

+  SectionStreamHandle - A pointer to a caller allocated UINTN that on output

+                        contains the new section stream handle.

+

+Returns:

+  EFI_SUCCESS

+  EFI_OUT_OF_RESOURCES - memory allocation failed.

+  EFI_INVALID_PARAMETER - section stream does not end concident with end of

+                          last section.

+

+--*/

+{

+  //

+  // Check to see section stream looks good...

+  //

+  if (!IsValidSectionStream (SectionStream, SectionStreamLength)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  return OpenSectionStreamEx ( 

+          SectionStreamLength, 

+          SectionStream,

+          TRUE,

+          0,

+          SectionStreamHandle

+          );

+}

+  

+

+EFI_STATUS

+EFIAPI

+GetSection (

+  IN EFI_SECTION_EXTRACTION_PROTOCOL                    *This,

+  IN UINTN                                              SectionStreamHandle,

+  IN EFI_SECTION_TYPE                                   *SectionType,

+  IN EFI_GUID                                           *SectionDefinitionGuid,

+  IN UINTN                                              SectionInstance,

+  IN VOID                                               **Buffer,

+  IN OUT UINTN                                          *BufferSize,

+  OUT UINT32                                            *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+  SEP member function.  Retrieves requested section from section stream.

+

+Arguments:  

+  This:                 Pointer to SEP instance.

+  SectionStreamHandle:  The section stream from which to extract the requested

+                          section.

+  SectionType:         A pointer to the type of section to search for.

+  SectionDefinitionGuid: If the section type is EFI_SECTION_GUID_DEFINED, then

+                        SectionDefinitionGuid indicates which of these types

+                          of sections to search for.

+  SectionInstance:      Indicates which instance of the requested section to

+                          return.

+  Buffer:               Double indirection to buffer.  If *Buffer is non-null on

+                          input, then the buffer is caller allocated.  If

+                          *Buffer is NULL, then the buffer is callee allocated.

+                          In either case, the requried buffer size is returned

+                          in *BufferSize.

+  BufferSize:           On input, indicates the size of *Buffer if *Buffer is

+                          non-null on input.  On output, indicates the required

+                          size (allocated size if callee allocated) of *Buffer.

+  AuthenticationStatus: Indicates the authentication status of the retrieved

+                          section.

+

+Returns:  

+  EFI_SUCCESS:        Section was retrieved successfully

+  EFI_PROTOCOL_ERROR: A GUID defined section was encountered in the section 

+                        stream with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED

+                        bit set, but there was no corresponding GUIDed Section 

+                        Extraction Protocol in the handle database.  *Buffer is 

+                        unmodified.

+  EFI_NOT_FOUND:      An error was encountered when parsing the SectionStream.

+                        This indicates the SectionStream  is not correctly 

+                        formatted.

+  EFI_NOT_FOUND:      The requested section does not exist.

+  EFI_OUT_OF_RESOURCES: The system has insufficient resources to process the 

+                        request.

+  EFI_INVALID_PARAMETER: The SectionStreamHandle does not exist.

+  EFI_WARN_TOO_SMALL: The size of the caller allocated input buffer is 

+                        insufficient to contain the requested section.  The 

+                        input buffer is filled and contents are section contents

+                        are truncated.

+

+--*/

+{

+  CORE_SECTION_STREAM_NODE                              *StreamNode;

+  EFI_TPL                                               OldTpl;

+  EFI_STATUS                                            Status;

+  CORE_SECTION_CHILD_NODE                               *ChildNode;

+  CORE_SECTION_STREAM_NODE                              *ChildStreamNode;

+  UINTN                                                 CopySize;

+  UINT32                                                ExtractedAuthenticationStatus;

+  UINTN                                                 Instance;

+  UINT8                                                 *CopyBuffer;

+  UINTN                                                 SectionSize;

+  

+

+  OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);

+  Instance = SectionInstance + 1;

+  

+  //

+  // Locate target stream

+  //

+  Status = FindStreamNode (SectionStreamHandle, &StreamNode);

+  if (EFI_ERROR (Status)) {

+    Status = EFI_INVALID_PARAMETER;

+    goto GetSection_Done;

+  }

+  

+  //

+  // Found the stream, now locate and return the appropriate section

+  //

+  if (SectionType == NULL) {

+    //

+    // SectionType == NULL means return the WHOLE section stream...

+    //

+    CopySize = StreamNode->StreamLength;

+    CopyBuffer = StreamNode->StreamBuffer;

+    *AuthenticationStatus = StreamNode->AuthenticationStatus;

+  } else {

+    //

+    // There's a requested section type, so go find it and return it...

+    //

+    Status = FindChildNode (

+                      StreamNode, 

+                      *SectionType, 

+                      &Instance, 

+                      SectionDefinitionGuid,

+                      &ChildNode,

+                      &ChildStreamNode, 

+                      &ExtractedAuthenticationStatus

+                      );

+    if (EFI_ERROR (Status)) {

+      goto GetSection_Done;

+    }

+    CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER);

+    CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER);

+    *AuthenticationStatus = ExtractedAuthenticationStatus;

+  }   

+    

+  SectionSize = CopySize;  

+  if (*Buffer != NULL) {

+    //

+    // Caller allocated buffer.  Fill to size and return required size...

+    //

+    if (*BufferSize < CopySize) {

+      Status = EFI_WARN_BUFFER_TOO_SMALL;

+      CopySize = *BufferSize;

+    }

+  } else {

+    //

+    // Callee allocated buffer.  Allocate buffer and return size.

+    //

+    *Buffer = CoreAllocateBootServicesPool (CopySize);

+    if (*Buffer == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto GetSection_Done;

+    }

+  }

+  CopyMem (*Buffer, CopyBuffer, CopySize);

+  *BufferSize = SectionSize;

+  

+GetSection_Done:

+  CoreRestoreTpl (OldTpl);

+  return Status;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CloseSectionStream (

+  IN  EFI_SECTION_EXTRACTION_PROTOCOL           *This,

+  IN  UINTN                                     StreamHandleToClose

+  )

+/*++

+

+Routine Description:

+  SEP member function.  Deletes an existing section stream

+

+Arguments:

+  This                - Indicates the calling context.

+  StreamHandleToClose - Indicates the stream to close

+

+Returns:

+  EFI_SUCCESS

+  EFI_OUT_OF_RESOURCES - memory allocation failed.

+  EFI_INVALID_PARAMETER - section stream does not end concident with end of

+                          last section.

+

+--*/

+{

+  CORE_SECTION_STREAM_NODE                      *StreamNode;

+  EFI_TPL                                       OldTpl;

+  EFI_STATUS                                    Status;

+  LIST_ENTRY                                    *Link;

+  CORE_SECTION_CHILD_NODE                       *ChildNode;

+  

+  OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);

+  

+  //

+  // Locate target stream

+  //

+  Status = FindStreamNode (StreamHandleToClose, &StreamNode);

+  if (!EFI_ERROR (Status)) {

+    //

+    // Found the stream, so close it

+    //

+    RemoveEntryList (&StreamNode->Link);

+    while (!IsListEmpty (&StreamNode->Children)) {

+      Link = GetFirstNode (&StreamNode->Children);

+      ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);

+      FreeChildNode (ChildNode);

+    }

+    CoreFreePool (StreamNode->StreamBuffer);

+    CoreFreePool (StreamNode);

+    Status = EFI_SUCCESS;

+  } else {

+    Status = EFI_INVALID_PARAMETER;

+  }

+  

+  CoreRestoreTpl (OldTpl);

+  return Status;

+}

+

+

+STATIC

+BOOLEAN

+ChildIsType (

+  IN CORE_SECTION_STREAM_NODE *Stream,

+  IN CORE_SECTION_CHILD_NODE  *Child,

+  IN EFI_SECTION_TYPE         SearchType,

+  IN EFI_GUID                 *SectionDefinitionGuid

+  )

+/*++

+

+Routine Description:

+  Worker function.  Determine if the input stream:child matches the input type.

+

+Arguments:

+  Stream              - Indicates the section stream associated with the child

+  Child               - Indicates the child to check

+  SearchType          - Indicates the type of section to check against for

+  SectionDefinitionGuid - Indicates the GUID to check against if the type is

+                        EFI_SECTION_GUID_DEFINED

+Returns:

+  TRUE                - The child matches

+  FALSE               - The child doesn't match

+

+--*/

+{

+  EFI_GUID_DEFINED_SECTION    *GuidedSection;

+  

+  if (SearchType == EFI_SECTION_ALL) {

+    return TRUE;

+  }

+  if (Child->Type != SearchType) {

+    return FALSE;

+  }

+  if (SearchType != EFI_SECTION_GUID_DEFINED) {

+    return TRUE;

+  }

+  GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream);

+  return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);

+}

+

+

+STATIC

+EFI_STATUS

+FindChildNode (

+  IN     CORE_SECTION_STREAM_NODE                   *SourceStream,

+  IN     EFI_SECTION_TYPE                           SearchType,

+  IN OUT UINTN                                      *SectionInstance,

+  IN     EFI_GUID                                   *SectionDefinitionGuid,

+  OUT    CORE_SECTION_CHILD_NODE                    **FoundChild,

+  OUT    CORE_SECTION_STREAM_NODE                   **FoundStream,

+  OUT    UINT32                                     *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+  Worker function  Recursively searches / builds section stream database

+  looking for requested section.

+

+Arguments:

+  SourceStream        - Indicates the section stream in which to do the search.

+  SearchType          - Indicates the type of section to search for.

+  SectionInstance     - Indicates which instance of section to find.  This is

+                        an in/out parameter to deal with recursions.

+  SectionDefinitionGuid  - Guid of section definition

+  FoundChild          - Output indicating the child node that is found.

+  FoundStream         - Output indicating which section stream the child was

+                        found in.  If this stream was generated as a result of

+                        an encapsulation section, the streamhandle is visible

+                        within the SEP driver only.

+  AuthenticationStatus- Indicates the authentication status of the found section.

+

+Returns:

+  EFI_SUCCESS         - Child node was found and returned.

+  EFI_OUT_OF_RESOURCES- Memory allocation failed.

+  EFI_NOT_FOUND       - Requested child node does not exist.

+  EFI_PROTOCOL_ERROR  - a required GUIDED section extraction protocol does not

+                        exist

+

+--*/

+{

+  CORE_SECTION_CHILD_NODE                       *CurrentChildNode;

+  CORE_SECTION_CHILD_NODE                       *RecursedChildNode;

+  CORE_SECTION_STREAM_NODE                      *RecursedFoundStream;

+  UINT32                                        NextChildOffset;

+  EFI_STATUS                                    ErrorStatus;

+  EFI_STATUS                                    Status;

+  

+  CurrentChildNode = NULL;

+  ErrorStatus = EFI_NOT_FOUND;

+  

+  if (SourceStream->StreamLength == 0) {

+    return EFI_NOT_FOUND;

+  }

+  

+  if (IsListEmpty (&SourceStream->Children) && 

+                   SourceStream->StreamLength > sizeof (EFI_COMMON_SECTION_HEADER)) {

+    //

+    // This occurs when a section stream exists, but no child sections

+    // have been parsed out yet.  Therefore, extract the first child and add it

+    // to the list of children so we can get started.

+    //

+    Status = CreateChildNode (SourceStream, 0, &CurrentChildNode);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  

+  //

+  // At least one child has been parsed out of the section stream.  So, walk

+  // through the sections that have already been parsed out looking for the

+  // requested section, if necessary, continue parsing section stream and

+  // adding children until either the requested section is found, or we run

+  // out of data

+  //

+  CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetFirstNode(&SourceStream->Children));

+

+  for (;;) {

+    if (ChildIsType (SourceStream, CurrentChildNode, SearchType, SectionDefinitionGuid)) {

+      //

+      // The type matches, so check the instance count to see if it's the one we want

+      //

+      (*SectionInstance)--;

+      if (*SectionInstance == 0) {

+        //

+        // Got it!

+        //

+        *FoundChild = CurrentChildNode;

+        *FoundStream = SourceStream;

+        *AuthenticationStatus = SourceStream->AuthenticationStatus;

+        return EFI_SUCCESS;

+      }

+    }

+    

+    if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {

+      //

+      // If the current node is an encapsulating node, recurse into it...

+      //

+      Status = FindChildNode (

+                (CORE_SECTION_STREAM_NODE *)CurrentChildNode->EncapsulatedStreamHandle,

+                SearchType,

+                SectionInstance,

+                SectionDefinitionGuid,

+                &RecursedChildNode,

+                &RecursedFoundStream,

+                AuthenticationStatus

+                );

+      //

+      // If the status is not EFI_SUCCESS, just save the error code and continue

+      // to find the request child node in the rest stream.

+      //

+      if (*SectionInstance == 0) {

+        ASSERT_EFI_ERROR (Status);

+        *FoundChild = RecursedChildNode;

+        *FoundStream = RecursedFoundStream;

+        return EFI_SUCCESS;

+      } else {

+        ErrorStatus = Status;

+      }

+    }

+    

+    if (!IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) {

+      //

+      // We haven't found the child node we're interested in yet, but there's

+      // still more nodes that have already been parsed so get the next one

+      // and continue searching..

+      //

+      CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetNextNode (&SourceStream->Children, &CurrentChildNode->Link));

+    } else {

+      //

+      // We've exhausted children that have already been parsed, so see if

+      // there's any more data and continue parsing out more children if there

+      // is.

+      //

+      NextChildOffset = CurrentChildNode->OffsetInStream + CurrentChildNode->Size;

+      //

+      // Round up to 4 byte boundary

+      //

+      NextChildOffset += 3;

+      NextChildOffset &= ~(UINTN)3;

+      if (NextChildOffset <= SourceStream->StreamLength - sizeof (EFI_COMMON_SECTION_HEADER)) {

+        //

+        // There's an unparsed child remaining in the stream, so create a new child node

+        //

+        Status = CreateChildNode (SourceStream, NextChildOffset, &CurrentChildNode);

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+      } else {

+        ASSERT (EFI_ERROR (ErrorStatus));

+        return ErrorStatus;

+      }

+    }

+  }

+}

+

+

+STATIC

+EFI_STATUS

+CreateChildNode (

+  IN     CORE_SECTION_STREAM_NODE              *Stream,

+  IN     UINT32                                ChildOffset,

+     OUT CORE_SECTION_CHILD_NODE               **ChildNode

+  )

+/*++

+

+Routine Description:

+  Worker function.  Constructor for new child nodes.

+

+Arguments:

+  Stream              - Indicates the section stream in which to add the child.

+  ChildOffset         - Indicates the offset in Stream that is the beginning

+                        of the child section.

+  ChildNode           - Indicates the Callee allocated and initialized child.

+

+Returns:

+  EFI_SUCCESS         - Child node was found and returned.

+  EFI_OUT_OF_RESOURCES- Memory allocation failed.

+  EFI_PROTOCOL_ERROR  - Encapsulation sections produce new stream handles when

+                        the child node is created.  If the section type is GUID

+                        defined, and the extraction GUID does not exist, and

+                        producing the stream requires the GUID, then a protocol

+                        error is generated and no child is produced.

+  Values returned by OpenSectionStreamEx.

+

+--*/

+{

+  EFI_STATUS                                   Status;

+  EFI_COMMON_SECTION_HEADER                    *SectionHeader;

+  EFI_COMPRESSION_SECTION                      *CompressionHeader;

+  EFI_GUID_DEFINED_SECTION                     *GuidedHeader;

+  EFI_TIANO_DECOMPRESS_PROTOCOL                *Decompress;

+  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL       *GuidedExtraction;

+  VOID                                         *NewStreamBuffer;

+  VOID                                         *ScratchBuffer;

+  UINT32                                       ScratchSize;

+  UINTN                                        NewStreamBufferSize;

+  UINT32                                       AuthenticationStatus;

+  UINT32                                       SectionLength;

+    

+  CORE_SECTION_CHILD_NODE                      *Node;

+

+  SectionHeader = (EFI_COMMON_SECTION_HEADER *) (Stream->StreamBuffer + ChildOffset);

+

+  //

+  // Allocate a new node

+  //

+  *ChildNode = CoreAllocateBootServicesPool (sizeof (CORE_SECTION_CHILD_NODE));

+  Node = *ChildNode;

+  if (Node == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Now initialize it

+  //

+  Node->Signature = CORE_SECTION_CHILD_SIGNATURE;

+  Node->Type = SectionHeader->Type;

+  Node->Size = SECTION_SIZE (SectionHeader);

+  Node->OffsetInStream = ChildOffset;

+  Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE;

+  Node->EncapsulationGuid = NULL;

+  

+  //

+  // If it's an encapsulating section, then create the new section stream also

+  //

+  switch (Node->Type) {

+    case EFI_SECTION_COMPRESSION:

+      //

+      // Get the CompressionSectionHeader

+      //

+      ASSERT (Node->Size >= sizeof (EFI_COMPRESSION_SECTION));

+      

+      CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader;

+      

+      //

+      // Allocate space for the new stream

+      //

+      if (CompressionHeader->UncompressedLength > 0) {

+        NewStreamBufferSize = CompressionHeader->UncompressedLength;

+        NewStreamBuffer = CoreAllocateBootServicesPool (NewStreamBufferSize);

+        if (NewStreamBuffer == NULL) {

+          CoreFreePool (Node);

+          return EFI_OUT_OF_RESOURCES;

+        }

+        

+        if (CompressionHeader->CompressionType == EFI_NOT_COMPRESSED) {

+          //

+          // stream is not actually compressed, just encapsulated.  So just copy it.

+          //

+          CopyMem (NewStreamBuffer, CompressionHeader + 1, NewStreamBufferSize);

+        } else if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION ||

+                   CompressionHeader->CompressionType == EFI_CUSTOMIZED_COMPRESSION) {

+          //

+          // Decompress the stream

+          //

+          if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION) {

+          Status = CoreLocateProtocol (&gEfiTianoDecompressProtocolGuid, NULL, (VOID **)&Decompress);

+          } else {

+            Status = CoreLocateProtocol (&gEfiCustomizedDecompressProtocolGuid, NULL, (VOID **)&Decompress);

+          }

+          

+          ASSERT_EFI_ERROR (Status);

+          

+          Status = Decompress->GetInfo (

+                                 Decompress,

+                                 CompressionHeader + 1,

+                                 Node->Size - sizeof (EFI_COMPRESSION_SECTION),

+                                 (UINT32 *)&NewStreamBufferSize,

+                                 &ScratchSize

+                                 );

+          ASSERT_EFI_ERROR (Status);

+          ASSERT (NewStreamBufferSize == CompressionHeader->UncompressedLength);

+

+          ScratchBuffer = CoreAllocateBootServicesPool (ScratchSize);

+          if (ScratchBuffer == NULL) {

+            CoreFreePool (Node);

+            CoreFreePool (NewStreamBuffer);

+            return EFI_OUT_OF_RESOURCES;

+          }

+

+          Status = Decompress->Decompress (

+                                 Decompress,

+                                 CompressionHeader + 1,

+                                 Node->Size - sizeof (EFI_COMPRESSION_SECTION),

+                                 NewStreamBuffer,

+                                 (UINT32)NewStreamBufferSize,

+                                 ScratchBuffer,

+                                 ScratchSize

+                                 );

+          ASSERT_EFI_ERROR (Status);

+          CoreFreePool (ScratchBuffer);                                           

+        }

+      } else {

+        NewStreamBuffer = NULL;

+        NewStreamBufferSize = 0;

+      }

+      

+      Status = OpenSectionStreamEx (

+                 NewStreamBufferSize,

+                 NewStreamBuffer,

+                 FALSE,

+                 Stream->AuthenticationStatus,

+                 &Node->EncapsulatedStreamHandle

+                 );

+      if (EFI_ERROR (Status)) {

+        CoreFreePool (Node);

+        CoreFreePool (NewStreamBuffer);

+        return Status;

+      }

+      break;

+

+    case EFI_SECTION_GUID_DEFINED:

+      GuidedHeader = (EFI_GUID_DEFINED_SECTION *) SectionHeader;

+      Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;

+      Status = CoreLocateProtocol (Node->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);

+      if (!EFI_ERROR (Status)) {

+        //

+        // NewStreamBuffer is always allocated by ExtractSection... No caller

+        // allocation here.

+        //

+        Status = GuidedExtraction->ExtractSection (

+                                     GuidedExtraction,

+                                     GuidedHeader,

+                                     &NewStreamBuffer,

+                                     &NewStreamBufferSize,

+                                     &AuthenticationStatus

+                                     );

+        if (EFI_ERROR (Status)) {

+          CoreFreePool (*ChildNode);

+          return EFI_PROTOCOL_ERROR;

+        }

+        

+        //

+        // Make sure we initialize the new stream with the correct 

+        // authentication status for both aggregate and local status fields.

+        //

+        if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {

+          //

+          // OR in the parent stream's aggregate status.

+          //

+          AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;

+        } else {

+          //

+          // since there's no authentication data contributed by the section,

+          // just inherit the full value from our immediate parent.

+          //

+          AuthenticationStatus = Stream->AuthenticationStatus;

+        }

+        

+        Status = OpenSectionStreamEx (

+                   NewStreamBufferSize,

+                   NewStreamBuffer,

+                   FALSE,

+                   AuthenticationStatus,

+                   &Node->EncapsulatedStreamHandle

+                   );

+        if (EFI_ERROR (Status)) {

+          CoreFreePool (*ChildNode);

+          CoreFreePool (NewStreamBuffer);

+          return Status;

+        }

+      } else {

+        //

+        // There's no GUIDed section extraction protocol available.

+        //

+        if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) {

+          //

+          // If the section REQUIRES an extraction protocol, then we're toast

+          //

+          CoreFreePool (*ChildNode);

+          return EFI_PROTOCOL_ERROR;

+        }

+        

+        //

+        // Figure out the proper authentication status

+        //

+        AuthenticationStatus = Stream->AuthenticationStatus;

+        if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {

+          //

+          //  The local status of the new stream is contained in 

+          //  AuthenticaionStatus.  This value needs to be ORed into the

+          //  Aggregate bits also...

+          //

+          

+          //

+          // Clear out and initialize the local status

+          //

+          AuthenticationStatus &= ~EFI_LOCAL_AUTH_STATUS_ALL;

+          AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED;

+          //

+          // OR local status into aggregate status

+          //

+          AuthenticationStatus |= AuthenticationStatus >> 16;

+        }

+        

+        SectionLength = SECTION_SIZE (GuidedHeader);

+        Status = OpenSectionStreamEx (

+                   SectionLength - GuidedHeader->DataOffset,

+                   (UINT8 *) GuidedHeader + GuidedHeader->DataOffset,

+                   TRUE,

+                   AuthenticationStatus,

+                   &Node->EncapsulatedStreamHandle

+                   );

+        if (EFI_ERROR (Status)) {

+          CoreFreePool (Node);

+          return Status;

+        }

+      }

+      

+      if ((AuthenticationStatus & EFI_LOCAL_AUTH_STATUS_ALL) == 

+            (EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED)) {

+        //

+        // Need to register for RPN for when the required GUIDed extraction

+        // protocol becomes available.  This will enable us to refresh the

+        // AuthenticationStatus cached in the Stream if it's ever requested

+        // again.

+        //

+        CreateGuidedExtractionRpnEvent (Stream, Node);

+      }

+      

+      break;

+

+    default:

+      

+      //

+      // Nothing to do if it's a leaf

+      //

+      break;

+  }

+  

+  //

+  // Last, add the new child node to the stream

+  //

+  InsertTailList (&Stream->Children, &Node->Link);

+

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+VOID

+CreateGuidedExtractionRpnEvent (

+  IN CORE_SECTION_STREAM_NODE       *ParentStream,

+  IN CORE_SECTION_CHILD_NODE        *ChildNode

+  )

+/*++

+

+Routine Description:

+  Worker function.  Constructor for RPN event if needed to keep AuthenticationStatus

+  cache correct when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears...

+

+Arguments:

+  ParentStream        - Indicates the parent of the ecnapsulation section (child)

+  ChildNode           - Indicates the child node that is the encapsulation section.

+

+Returns:

+  None

+

+--*/

+{

+  RPN_EVENT_CONTEXT *Context;

+  

+  //

+  // Allocate new event structure and context

+  //

+  Context = CoreAllocateBootServicesPool (sizeof (RPN_EVENT_CONTEXT));

+  ASSERT (Context != NULL);

+  

+  Context->ChildNode = ChildNode;

+  Context->ParentStream = ParentStream;

+ 

+  Context->Event = CoreCreateProtocolNotifyEvent (

+                    Context->ChildNode->EncapsulationGuid,

+                    EFI_TPL_NOTIFY,

+                    NotifyGuidedExtraction,

+                    Context,

+                    &Context->Registration,

+                    FALSE

+                    );

+}

+  

+  

+STATIC

+VOID

+EFIAPI

+NotifyGuidedExtraction (

+  IN   EFI_EVENT   Event,

+  IN   VOID        *RpnContext

+  )

+/*++

+

+Routine Description:

+  RPN callback function.  Removes a stale section stream and re-initializes it

+  with an updated AuthenticationStatus.

+

+Arguments:

+  Event               - The event that fired

+  RpnContext          - A pointer to the context that allows us to identify

+                        the relevent encapsulation...

+

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS                              Status;

+  EFI_GUID_DEFINED_SECTION                *GuidedHeader;

+  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL  *GuidedExtraction;

+  VOID                                    *NewStreamBuffer;

+  UINTN                                   NewStreamBufferSize;

+  UINT32                                  AuthenticationStatus;

+  RPN_EVENT_CONTEXT                       *Context;

+  

+  Context = RpnContext;

+  

+  Status = CloseSectionStream (&mSectionExtraction, Context->ChildNode->EncapsulatedStreamHandle);

+  if (!EFI_ERROR (Status)) {

+    //

+    // The stream closed successfully, so re-open the stream with correct AuthenticationStatus

+    //

+  

+    GuidedHeader = (EFI_GUID_DEFINED_SECTION *) 

+      (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream);

+    ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED);

+    

+    Status = CoreLocateProtocol (Context->ChildNode->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);

+    ASSERT_EFI_ERROR (Status);

+

+    

+    Status = GuidedExtraction->ExtractSection (

+                                 GuidedExtraction,

+                                 GuidedHeader,

+                                 &NewStreamBuffer,

+                                 &NewStreamBufferSize,

+                                 &AuthenticationStatus

+                                 );

+    ASSERT_EFI_ERROR (Status);

+    //

+    // OR in the parent stream's aggregagate status.

+    //

+    AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;

+    Status = OpenSectionStreamEx (

+               NewStreamBufferSize,

+               NewStreamBuffer,

+               FALSE,

+               AuthenticationStatus,

+               &Context->ChildNode->EncapsulatedStreamHandle

+               );

+    ASSERT_EFI_ERROR (Status);

+  }

+

+  //

+  //  If above, the stream  did not close successfully, it indicates it's

+  //  alread been closed by someone, so just destroy the event and be done with

+  //  it.

+  //

+  

+  CoreCloseEvent (Event);

+  CoreFreePool (Context);

+}  

+  

+

+STATIC

+VOID

+FreeChildNode (

+  IN  CORE_SECTION_CHILD_NODE                   *ChildNode

+  )

+/*++

+

+Routine Description:

+  Worker function.  Destructor for child nodes.

+

+Arguments:

+  ChildNode           - Indicates the node to destroy

+

+Returns:

+  none

+

+--*/

+{

+  ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);

+  //

+  // Remove the child from it's list

+  //

+  RemoveEntryList (&ChildNode->Link);

+  

+  if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {

+    //

+    // If it's an encapsulating section, we close the resulting section stream.

+    // CloseSectionStream will free all memory associated with the stream.

+    //

+    CloseSectionStream (&mSectionExtraction, ChildNode->EncapsulatedStreamHandle);

+  }

+  //

+  // Last, free the child node itself

+  //

+  CoreFreePool (ChildNode);

+}  

+

+

+STATIC

+EFI_STATUS

+OpenSectionStreamEx (

+  IN     UINTN                                     SectionStreamLength,

+  IN     VOID                                      *SectionStream,

+  IN     BOOLEAN                                   AllocateBuffer,

+  IN     UINT32                                    AuthenticationStatus,   

+     OUT UINTN                                     *SectionStreamHandle

+  )

+/*++

+

+  Routine Description:

+    Worker function.  Constructor for section streams.

+

+  Arguments:

+    SectionStreamLength - Size in bytes of the section stream.

+    SectionStream       - Buffer containing the new section stream.

+    AllocateBuffer      - Indicates whether the stream buffer is to be copied

+                          or the input buffer is to be used in place.

+    AuthenticationStatus- Indicates the default authentication status for the

+                          new stream.

+    SectionStreamHandle - A pointer to a caller allocated section stream handle.

+

+  Returns:

+    EFI_SUCCESS         - Stream was added to stream database.

+    EFI_OUT_OF_RESOURCES - memory allocation failed.

+

+--*/

+{

+  CORE_SECTION_STREAM_NODE    *NewStream;

+  EFI_TPL                     OldTpl;

+  

+  //

+  // Allocate a new stream

+  //

+  NewStream = CoreAllocateBootServicesPool (sizeof (CORE_SECTION_STREAM_NODE));

+  if (NewStream == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  if (AllocateBuffer) { 

+    //

+    // if we're here, we're double buffering, allocate the buffer and copy the

+    // data in

+    //

+    if (SectionStreamLength > 0) {

+      NewStream->StreamBuffer = CoreAllocateBootServicesPool (SectionStreamLength); 

+      if (NewStream->StreamBuffer == NULL) {

+        CoreFreePool (NewStream);

+        return EFI_OUT_OF_RESOURCES;

+      }

+      //

+      // Copy in stream data

+      //

+      CopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);

+    } else {

+      //

+      // It's possible to have a zero length section stream.

+      //

+      NewStream->StreamBuffer = NULL;

+    }

+  } else {

+    //

+    // If were here, the caller has supplied the buffer (it's an internal call)

+    // so just assign the buffer.  This happens when we open section streams

+    // as a result of expanding an encapsulating section.

+    //

+    NewStream->StreamBuffer = SectionStream;

+  }

+  

+  //

+  // Initialize the rest of the section stream

+  //

+  NewStream->Signature = CORE_SECTION_STREAM_SIGNATURE;

+  NewStream->StreamHandle = (UINTN) NewStream;

+  NewStream->StreamLength = SectionStreamLength;

+  InitializeListHead (&NewStream->Children);

+  NewStream->AuthenticationStatus = AuthenticationStatus;

+  

+  //

+  // Add new stream to stream list

+  //

+  OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);

+  InsertTailList (&mStreamRoot, &NewStream->Link);

+  CoreRestoreTpl (OldTpl);

+

+  *SectionStreamHandle = NewStream->StreamHandle;

+  

+  return EFI_SUCCESS;

+}

+

+

+STATIC

+EFI_STATUS

+FindStreamNode (

+  IN  UINTN                                     SearchHandle,

+  OUT CORE_SECTION_STREAM_NODE                  **FoundStream

+  )

+/*++

+

+  Routine Description:

+    Worker function.  Search stream database for requested stream handle.

+

+  Arguments:

+    SearchHandle        - Indicates which stream to look for.

+    FoundStream         - Output pointer to the found stream.

+

+  Returns:

+    EFI_SUCCESS         - StreamHandle was found and *FoundStream contains

+                          the stream node.

+    EFI_NOT_FOUND       - SearchHandle was not found in the stream database.

+

+--*/

+{  

+  CORE_SECTION_STREAM_NODE                      *StreamNode;

+  

+  if (!IsListEmpty (&mStreamRoot)) {

+    StreamNode = STREAM_NODE_FROM_LINK (GetFirstNode (&mStreamRoot));

+    for (;;) {

+      if (StreamNode->StreamHandle == SearchHandle) {

+        *FoundStream = StreamNode;

+        return EFI_SUCCESS;

+      } else if (IsNodeAtEnd (&mStreamRoot, &StreamNode->Link)) {

+        break;

+      } else {

+        StreamNode = STREAM_NODE_FROM_LINK (GetNextNode (&mStreamRoot, &StreamNode->Link));

+      }

+    }

+  }

+  

+  return EFI_NOT_FOUND;

+}

+

+

+STATIC

+BOOLEAN

+IsValidSectionStream (

+  IN  VOID              *SectionStream,

+  IN  UINTN             SectionStreamLength

+  )

+/*++

+

+Routine Description:

+  Check if a stream is valid.

+

+Arguments:

+  SectionStream         - The section stream to be checked

+  SectionStreamLength   - The length of section stream

+

+Returns:

+  TRUE

+  FALSE

+

+--*/

+{

+  UINTN                       TotalLength;

+  UINTN                       SectionLength;

+  EFI_COMMON_SECTION_HEADER   *SectionHeader;

+  EFI_COMMON_SECTION_HEADER   *NextSectionHeader;

+

+  TotalLength = 0;

+  SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream;

+  

+  while (TotalLength < SectionStreamLength) {

+    SectionLength = SECTION_SIZE (SectionHeader);

+    TotalLength += SectionLength;

+

+    if (TotalLength == SectionStreamLength) {

+      return TRUE;    

+    }

+

+    //

+    // Move to the next byte following the section...

+    //

+    SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength);

+    

+    //

+    // Figure out where the next section begins

+    //

+    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) SectionHeader + 3);

+    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader & ~(UINTN)3);

+    TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;

+    SectionHeader = NextSectionHeader;

+  }

+

+  ASSERT (FALSE);

+  return FALSE;

+}

diff --git a/edk2/EdkModulePkg/Core/Dxe/build.xml b/edk2/EdkModulePkg/Core/Dxe/build.xml
new file mode 100644
index 0000000..f153562
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeMain"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Core/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeMain">

+      <GenBuild baseName="DxeMain" mbdFilename="${MODULE_DIR}/DxeMain.mbd" msaFilename="${MODULE_DIR}/DxeMain.msa"/>

+   </target>

+   <target depends="DxeMain_clean" name="clean"/>

+   <target depends="DxeMain_cleanall" name="cleanall"/>

+   <target name="DxeMain_clean">

+      <OutputDirSetup baseName="DxeMain" mbdFilename="${MODULE_DIR}/DxeMain.mbd" msaFilename="${MODULE_DIR}/DxeMain.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeMain_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeMain_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeMain_cleanall">

+      <OutputDirSetup baseName="DxeMain" mbdFilename="${MODULE_DIR}/DxeMain.mbd" msaFilename="${MODULE_DIR}/DxeMain.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeMain_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeMain_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeMain*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Core/Dxe/gcd.h b/edk2/EdkModulePkg/Core/Dxe/gcd.h
new file mode 100644
index 0000000..445821e
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/gcd.h
@@ -0,0 +1,51 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    gcd.h

+

+Abstract:

+

+Revision History

+

+--*/

+

+#ifndef _GCD_H

+#define _GCD_H

+

+//

+// GCD Operations

+//

+#define GCD_MEMORY_SPACE_OPERATION 0x20

+#define GCD_IO_SPACE_OPERATION     0x40

+

+#define GCD_ADD_MEMORY_OPERATION             (GCD_MEMORY_SPACE_OPERATION | 0)

+#define GCD_ALLOCATE_MEMORY_OPERATION        (GCD_MEMORY_SPACE_OPERATION | 1)

+#define GCD_FREE_MEMORY_OPERATION            (GCD_MEMORY_SPACE_OPERATION | 2)

+#define GCD_REMOVE_MEMORY_OPERATION          (GCD_MEMORY_SPACE_OPERATION | 3)

+#define GCD_SET_ATTRIBUTES_MEMORY_OPERATION  (GCD_MEMORY_SPACE_OPERATION | 4)

+

+#define GCD_ADD_IO_OPERATION                 (GCD_IO_SPACE_OPERATION | 0)

+#define GCD_ALLOCATE_IO_OPERATION            (GCD_IO_SPACE_OPERATION | 1)

+#define GCD_FREE_IO_OPERATION                (GCD_IO_SPACE_OPERATION | 2)

+#define GCD_REMOVE_IO_OPERATION              (GCD_IO_SPACE_OPERATION | 3)

+

+//

+// The data structure used to convert from GCD attributes to EFI Memory Map attributes

+//

+typedef struct {

+  UINT64   Attribute;

+  UINT64   Capability;

+  BOOLEAN  Memory;

+} GCD_ATTRIBUTE_CONVERSION_ENTRY;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/hand.h b/edk2/EdkModulePkg/Core/Dxe/hand.h
new file mode 100644
index 0000000..c61af16
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/hand.h
@@ -0,0 +1,337 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  hand.h

+

+Abstract:

+

+  EFI internal protocol definitions

+

+

+

+Revision History

+

+--*/

+

+#ifndef  _HAND_H_

+#define  _HAND_H_

+

+

+//

+// IHANDLE - contains a list of protocol handles

+//

+

+#define EFI_HANDLE_SIGNATURE            EFI_SIGNATURE_32('h','n','d','l')

+typedef struct {

+  UINTN               Signature;

+  LIST_ENTRY          AllHandles;     // All handles list of IHANDLE

+  LIST_ENTRY          Protocols;      // List of PROTOCOL_INTERFACE's for this handle

+  UINTN               LocateRequest;  // 

+  UINT64              Key;            // The Handle Database Key value when this handle was last created or modified

+} IHANDLE;

+

+#define ASSERT_IS_HANDLE(a)  ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)

+

+

+//

+// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol 

+// database.  Each handler that supports this protocol is listed, along

+// with a list of registered notifies.

+//

+

+#define PROTOCOL_ENTRY_SIGNATURE        EFI_SIGNATURE_32('p','r','t','e')

+typedef struct {

+  UINTN               Signature;

+  LIST_ENTRY          AllEntries;             // All entries

+  EFI_GUID            ProtocolID;             // ID of the protocol

+  LIST_ENTRY          Protocols;              // All protocol interfaces

+  LIST_ENTRY          Notify;                 // Registerd notification handlers

+} PROTOCOL_ENTRY;

+

+//

+// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked

+// with a protocol interface structure

+//

+

+#define PROTOCOL_INTERFACE_SIGNATURE  EFI_SIGNATURE_32('p','i','f','c')

+typedef struct {

+  UINTN                       Signature;

+  EFI_HANDLE                  Handle;     // Back pointer

+  LIST_ENTRY                  Link;       // Link on IHANDLE.Protocols

+  LIST_ENTRY                  ByProtocol; // Link on PROTOCOL_ENTRY.Protocols

+  PROTOCOL_ENTRY              *Protocol;  // The protocol ID

+  VOID                        *Interface; // The interface value

+                                          

+  LIST_ENTRY                  OpenList;       // OPEN_PROTOCOL_DATA list.

+  UINTN                       OpenListCount;  

+  

+  EFI_HANDLE                  ControllerHandle;

+

+} PROTOCOL_INTERFACE;

+

+#define OPEN_PROTOCOL_DATA_SIGNATURE  EFI_SIGNATURE_32('p','o','d','l')

+

+typedef struct {

+  UINTN                       Signature;

+  LIST_ENTRY                  Link;

+

+  EFI_HANDLE                  AgentHandle;

+  EFI_HANDLE                  ControllerHandle;

+  UINT32                      Attributes;

+  UINT32                      OpenCount;

+} OPEN_PROTOCOL_DATA;

+

+

+//

+// PROTOCOL_NOTIFY - used for each register notification for a protocol

+//

+

+#define PROTOCOL_NOTIFY_SIGNATURE       EFI_SIGNATURE_32('p','r','t','n')

+typedef struct {

+  UINTN               Signature;

+  PROTOCOL_ENTRY      *Protocol;

+  LIST_ENTRY          Link;                   // All notifications for this protocol

+  EFI_EVENT           Event;                  // Event to notify

+  LIST_ENTRY          *Position;              // Last position notified

+} PROTOCOL_NOTIFY;

+

+//

+// Internal prototypes

+//

+

+

+PROTOCOL_ENTRY  *

+CoreFindProtocolEntry (

+  IN EFI_GUID     *Protocol,

+  IN BOOLEAN      Create

+  )

+/*++

+

+Routine Description:

+

+  Finds the protocol entry for the requested protocol.

+  

+  The gProtocolDatabaseLock must be owned

+

+Arguments:

+  

+  Protocol  - The ID of the protocol 

+

+  Create    - Create a new entry if not found

+

+Returns:

+

+  Protocol entry

+

+--*/

+;

+

+VOID

+CoreNotifyProtocolEntry (

+  IN PROTOCOL_ENTRY       *ProtEntry

+  )

+/*++

+

+Routine Description:

+

+  Signal event for every protocol in protocol entry.

+

+Arguments:

+

+  ProtEntry     - Protocol entry

+

+Returns:

+

+--*/

+;

+

+PROTOCOL_INTERFACE *

+CoreFindProtocolInterface (

+  IN IHANDLE              *Handle,

+  IN EFI_GUID             *Protocol,

+  IN VOID                 *Interface

+  )

+/*++

+

+Routine Description:

+

+  Finds the protocol instance for the requested handle and protocol.

+  

+  Note: This function doesn't do parameters checking, it's caller's responsibility 

+        to pass in valid parameters.

+  

+Arguments:

+  

+  Handle    - The handle to search the protocol on

+  

+  Protocol  - GUID of the protocol

+

+  Interface - The interface for the protocol being searched

+

+Returns:

+

+  Protocol instance (NULL: Not found)

+

+--*/

+;

+

+PROTOCOL_INTERFACE *

+CoreRemoveInterfaceFromProtocol (

+  IN IHANDLE              *Handle,

+  IN EFI_GUID             *Protocol,

+  IN VOID                 *Interface

+  )

+/*++

+

+Routine Description:

+

+  Removes Protocol from the protocol list (but not the handle list).

+

+Arguments:

+

+  Handle -  The handle to remove protocol on.

+

+  Protocol  -  GUID of the protocol to be moved

+

+  Interface - The interface of the protocol

+

+Returns:

+

+  Protocol Entry

+

+--*/

+;

+

+EFI_STATUS

+CoreUnregisterProtocolNotify (

+  IN EFI_EVENT            Event

+  )

+/*++

+

+Routine Description:

+

+  Removes all the events in the protocol database that match Event.

+

+Arguments:

+  

+  Event   - The event to search for in the protocol database.

+

+Returns:

+

+  EFI_SUCCESS when done searching the entire database.

+

+--*/

+;

+

+EFI_STATUS

+CoreDisconnectControllersUsingProtocolInterface (

+  IN EFI_HANDLE           UserHandle,

+  IN PROTOCOL_INTERFACE   *Prot

+  )

+/*++

+

+Routine Description:

+

+  Attempts to disconnect all drivers that are using the protocol interface being queried.

+  If failed, reconnect all drivers disconnected.

+  

+  Note: This function doesn't do parameters checking, it's caller's responsibility 

+        to pass in valid parameters.

+

+Arguments:

+

+  UserHandle  - The handle on which the protocol is installed 

+  Prot        - The protocol to disconnect drivers from

+

+Returns:

+

+  EFI_SUCCESS       - Drivers using the protocol interface are all disconnected

+  EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers

+

+--*/

+;

+

+VOID

+CoreAcquireProtocolLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Acquire lock on gProtocolDatabaseLock.

+  

+Arguments:

+

+  None

+  

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+CoreReleaseProtocolLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Release lock on gProtocolDatabaseLock.

+  

+Arguments:

+

+  None

+  

+Returns:

+

+  None

+

+--*/

+;

+

+EFI_STATUS

+CoreValidateHandle (

+  IN  EFI_HANDLE                UserHandle

+  )

+/*++

+

+Routine Description:

+

+  Check whether a handle is a valid EFI_HANDLE

+  

+Arguments:

+

+  UserHandle		-	The handle to check

+  

+Returns:

+

+  EFI_INVALID_PARAMETER		-	The handle is NULL or not a valid EFI_HANDLE.

+  

+  EFI_SUCCESS							-	The handle is valid EFI_HANDLE.

+

+--*/

+;

+

+//

+// Externs

+//

+

+extern EFI_LOCK         gProtocolDatabaseLock;

+extern LIST_ENTRY       gHandleList;

+extern UINT64           gHandleDatabaseKey;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Dxe/imem.h b/edk2/EdkModulePkg/Core/Dxe/imem.h
new file mode 100644
index 0000000..e1f8215
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Dxe/imem.h
@@ -0,0 +1,227 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  imem.h

+

+Abstract:

+

+  Head file to imem.h

+

+

+Revision History

+

+--*/

+

+#ifndef _IMEM_H_

+#define _IMEM_H_

+

+#if defined (MDE_CPU_IPF)

+//

+// For Itanium machines make the default allocations 8K aligned

+//

+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT  (EFI_PAGE_SIZE * 2)

+#define DEFAULT_PAGE_ALLOCATION                     (EFI_PAGE_SIZE * 2)

+

+#else

+//

+// For genric EFI machines make the default allocations 4K aligned

+//

+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT  (EFI_PAGE_SIZE)

+#define DEFAULT_PAGE_ALLOCATION                     (EFI_PAGE_SIZE)

+

+#endif

+

+

+//

+// MEMORY_MAP_ENTRY

+//

+

+#define MEMORY_MAP_SIGNATURE   EFI_SIGNATURE_32('m','m','a','p')

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      Link;

+  BOOLEAN         FromPool;

+

+  EFI_MEMORY_TYPE Type;

+  UINT64          Start;

+  UINT64          End;

+

+  UINT64          VirtualStart;

+  UINT64          Attribute;

+} MEMORY_MAP;

+

+//

+// Internal prototypes

+//

+

+VOID *

+CoreAllocatePoolPages (

+  IN EFI_MEMORY_TYPE   PoolType,

+  IN UINTN             NumberOfPages,

+  IN UINTN             Alignment

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Used by the pool functions to allocate pages

+  to back pool allocation requests.

+

+Arguments:

+

+  PoolType      - The type of memory for the new pool pages

+

+  NumberOfPages - No of pages to allocate

+  

+  Alignment     - Bits to align.

+

+Returns:

+

+  The allocated memory, or NULL

+

+--*/

+;

+

+

+VOID

+CoreFreePoolPages (

+  IN EFI_PHYSICAL_ADDRESS   Memory,

+  IN UINTN                  NumberOfPages

+  )

+/*++

+

+Routine Description:

+

+  Internal function.  Frees pool pages allocated via AllocatePoolPages ()

+

+Arguments:

+

+  Memory        - The base address to free

+

+  NumberOfPages - The number of pages to free

+

+Returns:

+

+  None

+

+--*/

+;

+

+

+VOID *

+CoreAllocatePoolI (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            Size

+  )

+/*++

+

+Routine Description:

+

+  Internal function to allocate pool of a particular type.

+

+  Caller must have the memory lock held

+

+

+Arguments:

+

+  PoolType    - Type of pool to allocate

+

+  Size        - The amount of pool to allocate

+

+Returns:

+

+  The allocate pool, or NULL

+

+--*/

+;

+

+

+EFI_STATUS

+CoreFreePoolI (

+  IN VOID           *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Internal function to free a pool entry.

+

+  Caller must have the memory lock held

+

+

+Arguments:

+

+  Buffer      - The allocated pool entry to free

+

+Returns:

+

+  EFI_INVALID_PARAMETER     - Buffer not valid

+  

+  EFI_SUCCESS               - Buffer successfully freed.

+

+--*/

+;

+

+

+VOID

+CoreAcquireMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Enter critical section by gaining lock on gMemoryLock

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+CoreReleaseMemoryLock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Exit critical section by releasing lock on gMemoryLock

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+;

+

+

+//

+// Internal Global data

+//

+

+extern EFI_LOCK           gMemoryLock; 

+extern LIST_ENTRY         gMemoryMap;

+extern MEMORY_MAP         *gMemoryLastConvert;

+extern LIST_ENTRY         mGcdMemorySpaceMap;

+#endif

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.dxs b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.dxs
new file mode 100644
index 0000000..6370d86
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.dxs
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeIpl.dxs

+

+Abstract:

+

+  Dependency expression file for DXE Initial Program Loader PEIM.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+   EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.h b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.h
new file mode 100644
index 0000000..bc50666
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.h
@@ -0,0 +1,146 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeIpl.h

+

+Abstract:

+

+--*/

+

+#ifndef __PEI_DXEIPL_H__

+#define __PEI_DXEIPL_H__

+

+#define STACK_SIZE      0x20000

+#define BSP_STORE_SIZE  0x4000

+

+extern BOOLEAN gInMemory;

+

+VOID

+SwitchIplStacks (

+  VOID  *EntryPoint,

+  UINTN Parameter1,

+  UINTN Parameter2,

+  VOID  *NewStack,

+  VOID  *NewBsp

+  )

+;

+

+EFI_STATUS

+PeiFindFile (

+  IN  UINT8                  Type,

+  IN  UINT16                 SectionType,

+  OUT EFI_GUID               *FileName,

+  OUT VOID                   **Pe32Data

+  )

+;

+

+EFI_STATUS

+PeiLoadFile (

+  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,

+  IN  VOID                                      *Pe32Data,

+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,

+  OUT UINT64                                    *ImageSize,

+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint

+  )

+;

+

+

+EFI_STATUS

+CreateArchSpecificHobs (

+  OUT EFI_PHYSICAL_ADDRESS                      *BspStore

+  )

+;

+

+EFI_STATUS

+GetImageReadFunction (

+  IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+;

+

+EFI_STATUS

+PeiImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DxeIplLoadFile (

+  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,

+  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,

+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,

+  OUT UINT64                                    *ImageSize,

+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint

+  );

+

+EFI_STATUS

+ShadowDxeIpl (

+  IN EFI_FFS_FILE_HEADER                       *DxeIpl,

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader

+  );

+

+EFI_STATUS

+EFIAPI

+DxeLoadCore (

+  IN EFI_DXE_IPL_PPI       *This,

+  IN EFI_PEI_SERVICES      **PeiServices,

+  IN EFI_PEI_HOB_POINTERS  HobList

+  );

+

+EFI_STATUS

+PeiProcessFile (

+  IN  UINT16                 SectionType,

+  IN  EFI_FFS_FILE_HEADER    *FfsFileHeader,

+  OUT VOID                   **Pe32Data

+  );

+

+EFI_STATUS

+EFIAPI

+PeimInitializeDxeIpl (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  );

+

+EFI_STATUS

+PeiLoadx64File (

+  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,

+  IN  VOID                                      *Pe32Data,

+  IN  EFI_MEMORY_TYPE                           MemoryType,

+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,

+  OUT UINT64                                    *ImageSize,

+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint

+  )

+;

+

+EFI_PHYSICAL_ADDRESS

+CreateIdentityMappingPageTables (

+  IN UINT32                NumberOfProcessorPhysicalAddressBits

+  )

+;

+

+VOID

+ActivateLongMode (

+  IN  EFI_PHYSICAL_ADDRESS  PageTables,  

+  IN  EFI_PHYSICAL_ADDRESS  HobStart,

+  IN  EFI_PHYSICAL_ADDRESS  Stack,

+  IN  EFI_PHYSICAL_ADDRESS  CodeEntryPoint1,

+  IN  EFI_PHYSICAL_ADDRESS  CodeEntryPoint2

+  );

+

+VOID

+LoadGo64Gdt();

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.mbd b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.mbd
new file mode 100644
index 0000000..3b5ae36
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.mbd
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MbdHeader>
+    <BaseName>DxeIpl</BaseName>
+    <Guid>86D70125-BAA3-4296-A62F-602BEBBB9081</Guid>
+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-03-12 17:09</Created>
+    <Modified>2006-03-22 18:54</Modified>
+  </MbdHeader>
+  <Libraries>
+    <Library>PeimEntryPoint</Library>
+    <Library>PeiMemoryLib</Library>
+    <Library>PeiCoreLib</Library>
+    <Library OverrideID="4444">PeiServicesTablePointerLib</Library>
+    <Library>PeiHobLib</Library>
+    <Library>BaseCacheMaintenanceLib</Library>
+    <Library>BaseUefiTianoDecompressLib</Library>
+    <Library>BaseCustomDecompressLibNull</Library>
+    <Library>PeiReportStatusCodeLib</Library>
+    <Library>BaseDebugLibReportStatusCode</Library>
+    <Library>BaseLib</Library>
+    <Library>PeiMemoryAllocationLib</Library>
+    <Arch ArchType="IA32">
+      <Library OverrideID="8888">EdkPeCoffLoaderLib</Library>
+      <Library OverrideID="8888">BasePeCoffLib</Library>
+    </Arch>
+    <Arch ArchType="X64">
+      <Library>EdkPeCoffLoaderLib</Library>
+      <Library>BasePeCoffLib</Library>
+    </Arch>
+    <Arch ArchType="IPF">
+      <Library>EdkPeCoffLoaderLib</Library>
+      <Library>BasePeCoffLib</Library>
+    </Arch>
+    <Arch ArchType="EBC">
+      <Library>EdkPeCoffLoaderLib</Library>
+      <Library>BasePeCoffLib</Library>
+    </Arch>
+  </Libraries>
+  <BuildOptions ToolChain="MSFT">
+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+  </BuildOptions>
+</ModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.msa b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.msa
new file mode 100644
index 0000000..318df35
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIpl.msa
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DxeIpl</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>86D70125-BAA3-4296-A62F-602BEBBB9081</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for DxeIpl module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-22 18:54</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">CacheMaintenanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkPeCoffLoaderLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TianoDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">CustomDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeLoad.c</Filename>

+    <Filename>DxeIpl.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/ImageRead.c</Filename>

+      <Filename>Ia32/DxeLoadFunc.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>Ia32/ImageRead.c</Filename>

+      <Filename>Ia32/DxeLoadFunc.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>ipf/ImageRead.c</Filename>

+      <Filename>ipf/DxeLoadFunc.c</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>Ia32/ImageRead.c</Filename>

+      <Filename>Ia32/DxeLoadFunc.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="SOMETIMES_PRODUCED">Decompress</Protocol>

+    <Protocol Usage="SOMETIMES_PRODUCED">TianoDecompress</Protocol>

+    <Protocol Usage="SOMETIMES_PRODUCED">CustomizedDecompress</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="MEMORY_ALLOCATION">

+      <C_Name>gEfiHobMemoryAllocBspStoreGuid</C_Name>

+      <Guid>0x564b33cd, 0xc92a, 0x4593, 0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <C_Name>gEfiDecompressProtocolGuid</C_Name>

+      <Guid>0xd8117cfe, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <C_Name>gEfiTianoDecompressProtocolGuid</C_Name>

+      <Guid>0xe84cf29c, 0x191f, 0x4eae, 0x96, 0xe1, 0xf4, 0x6a, 0xec, 0xea, 0xea, 0x0b</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <C_Name>gEfiCustomizedDecompressProtocolGuid</C_Name>

+      <Guid>0x9a44198e, 0xa4a2, 0x44e6, 0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <C_Name>gEfiPeiPeCoffLoaderGuid</C_Name>

+      <Guid>0xd8117cff, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="MEMORY_ALLOCATION">

+      <C_Name>gEfiHobMemoryAllocModuleGuid</C_Name>

+      <Guid>0xf8e21975, 0x0899, 0x4f58, 0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="FIRMWARE_VOLUME">

+      <Name>DecompressedFvmain.fv</Name>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="SOMETIMES_PRODUCED">DxeIpl</Ppi>

+    <Ppi Usage="SOMETIMES_PRODUCED">FvFileLoader</Ppi>

+    <Ppi Usage="SOMETIMES_PRODUCED">EndOfPeiSignal</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">RecoveryModule</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">S3Resume</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">SectionExtraction</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">Security</Ppi>

+    <Ppi Usage="PRIVATE">PeiInMemory</Ppi>

+  </PPIs>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>PeiPeCoffLoader</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimInitializeDxeIpl</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIplX64.mbd b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIplX64.mbd
new file mode 100644
index 0000000..ef039fc
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIplX64.mbd
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MbdHeader>
+    <BaseName>DxeIplX64</BaseName>
+    <Guid>86D70125-BAA3-4296-A62F-602BEBBB9081</Guid>
+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright 2004-2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-04-03 23:58</Created>
+  </MbdHeader>
+  <Libraries>
+    <Library>PeimEntryPoint</Library>
+    <Library>PeiMemoryLib</Library>
+    <Library>PeiCoreLib</Library>
+    <Library OverrideID="4444">PeiServicesTablePointerLib</Library>
+    <Library>PeiHobLib</Library>
+    <Library>BaseCacheMaintenanceLib</Library>
+    <Library>BaseUefiTianoDecompressLib</Library>
+    <Library>BaseCustomDecompressLibNull</Library>
+    <Library>BaseDebugLibReportStatusCode</Library>
+    <Library>BaseLib</Library>
+    <Library>PeiMemoryAllocationLib</Library>
+    <Library>PeiReportStatusCodeLib</Library>
+    <Library>EdkPeCoffLoaderX64Lib</Library>
+    <Library>EdkPeCoffLoaderLib</Library>
+    <Library>BasePeCoffLib</Library>
+  </Libraries>
+  <BuildOptions ToolChain="MSFT">
+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+  </BuildOptions>
+</ModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIplX64.msa b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIplX64.msa
new file mode 100644
index 0000000..68a2a98
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeIplX64.msa
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MsaHeader>
+    <BaseName>DxeIplX64</BaseName>
+    <ModuleType>PEIM</ModuleType>
+    <ComponentType>PE32_PEIM</ComponentType>
+    <Guid>86D70125-BAA3-4296-A62F-602BEBBB9081</Guid>
+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>
+    <Abstract>Component description file for DxeIpl module</Abstract>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright 2004-2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-04-03 23:58</Created>
+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>
+  </MsaHeader>
+  <LibraryClassDefinitions>
+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">CacheMaintenanceLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkPeCoffLoaderLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDecompressLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">TianoDecompressLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">CustomDecompressLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkPeCoffLoaderX64Lib</LibraryClass>
+  </LibraryClassDefinitions>
+  <SourceFiles>
+    <Filename>DxeIpl.dxs</Filename>
+    <Filename>DxeLoadX64.c</Filename>
+    <Arch ArchType="IA32">
+      <Filename>x64/ImageRead.c</Filename>
+      <Filename>x64/LongMode.asm</Filename>
+      <Filename>x64/DxeLoadFunc.c</Filename>
+      <Filename>x64/VirtualMemory.c</Filename>
+    </Arch>
+  </SourceFiles>
+  <Includes>
+    <PackageName>MdePkg</PackageName>
+    <PackageName>EdkModulePkg</PackageName>
+  </Includes>
+  <Protocols>
+    <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>
+    <Protocol Usage="ALWAYS_CONSUMED">TianoDecompress</Protocol>
+    <Protocol Usage="ALWAYS_CONSUMED">CustomizedDecompress</Protocol>
+  </Protocols>
+  <Hobs>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="MEMORY_ALLOCATION">
+      <C_Name>gEfiHobMemoryAllocBspStoreGuid</C_Name>
+      <Guid>0x564b33cd, 0xc92a, 0x4593, 0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22</Guid>
+    </Hob>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">
+      <C_Name>gEfiDecompressProtocolGuid</C_Name>
+      <Guid>0xd8117cfe, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Hob>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">
+      <C_Name>gEfiTianoDecompressProtocolGuid</C_Name>
+      <Guid>0xe84cf29c, 0x191f, 0x4eae, 0x96, 0xe1, 0xf4, 0x6a, 0xec, 0xea, 0xea, 0x0b</Guid>
+    </Hob>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">
+      <C_Name>gEfiCustomizedDecompressProtocolGuid</C_Name>
+      <Guid>0x9a44198e, 0xa4a2, 0x44e6, 0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f</Guid>
+    </Hob>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">
+      <C_Name>gEfiPeiPeCoffLoaderGuid</C_Name>
+      <Guid>0xd8117cff, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Hob>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="MEMORY_ALLOCATION">
+      <C_Name>gEfiHobMemoryAllocModuleGuid</C_Name>
+      <Guid>0xf8e21975, 0x0899, 0x4f58, 0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a</Guid>
+    </Hob>
+    <Hob Usage="SOMETIMES_PRODUCED" HobType="FIRMWARE_VOLUME">
+      <Name>DecompressedFvmain.fv</Name>
+    </Hob>
+  </Hobs>
+  <PPIs>
+    <Ppi Usage="SOMETIMES_PRODUCED">DxeIpl</Ppi>
+    <Ppi Usage="SOMETIMES_PRODUCED">FvFileLoader</Ppi>
+    <Ppi Usage="SOMETIMES_PRODUCED">EndOfPeiSignal</Ppi>
+    <Ppi Usage="SOMETIMES_CONSUMED">RecoveryModule</Ppi>
+    <Ppi Usage="SOMETIMES_CONSUMED">S3Resume</Ppi>
+    <Ppi Usage="SOMETIMES_CONSUMED">SectionExtraction</Ppi>
+    <Ppi Usage="SOMETIMES_CONSUMED">Security</Ppi>
+    <Ppi Usage="PRIVATE">PeiInMemory</Ppi>
+  </PPIs>
+  <Guids>
+    <GuidEntry Usage="ALWAYS_CONSUMED">
+      <C_Name>PeiPeCoffLoader</C_Name>
+    </GuidEntry>
+  </Guids>
+  <Externs>
+    <Extern>
+      <ModuleEntryPoint>PeimInitializeDxeIpl</ModuleEntryPoint>
+    </Extern>
+  </Externs>
+  <BuildOptions ToolChain="MSFT">
+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+  </BuildOptions>
+</ModuleSurfaceArea>
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c
new file mode 100644
index 0000000..a181095
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -0,0 +1,1010 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  DxeLoad.c

+

+Abstract:

+

+  Last PEIM.

+  Responsibility of this module is to load the DXE Core from a Firmware Volume.

+

+--*/

+

+#include <DxeIpl.h>

+

+BOOLEAN gInMemory = FALSE;

+

+//

+// Module Globals used in the DXE to PEI handoff

+// These must be module globals, so the stack can be switched

+//

+static EFI_DXE_IPL_PPI mDxeIplPpi = {

+  DxeLoadCore

+};

+

+static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {

+  DxeIplLoadFile

+};

+

+static EFI_PEI_PPI_DESCRIPTOR     mPpiLoadFile = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiPeiFvFileLoaderPpiGuid,

+  &mLoadFilePpi

+};

+

+static EFI_PEI_PPI_DESCRIPTOR     mPpiList = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiDxeIplPpiGuid,

+  &mDxeIplPpi

+};

+

+static EFI_PEI_PPI_DESCRIPTOR     mPpiPeiInMemory = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gPeiInMemoryGuid,

+  NULL

+};

+

+static EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiEndOfPeiSignalPpiGuid,

+  NULL

+};

+

+DECOMPRESS_LIBRARY  gEfiDecompress = {

+  UefiDecompressGetInfo,

+  UefiDecompress

+};

+

+DECOMPRESS_LIBRARY  gTianoDecompress = {

+  TianoDecompressGetInfo,

+  TianoDecompress

+};

+

+DECOMPRESS_LIBRARY  gCustomDecompress = {

+  CustomDecompressGetInfo,

+  CustomDecompress

+};

+

+STATIC

+UINTN

+GetOccupiedSize (

+  IN UINTN   ActualSize,

+  IN UINTN   Alignment

+  )

+{

+  UINTN OccupiedSize;

+

+  OccupiedSize = ActualSize;

+  while ((OccupiedSize & (Alignment - 1)) != 0) {

+    OccupiedSize++;

+  }

+

+  return OccupiedSize;

+}

+

+EFI_STATUS

+EFIAPI

+PeimInitializeDxeIpl (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Initializes the Dxe Ipl PPI

+

+Arguments:

+

+  FfsHeader   - Pointer to FFS file header

+  PeiServices - General purpose services available to every PEIM.

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  EFI_STATUS                                Status;

+  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;

+  EFI_BOOT_MODE                             BootMode;

+

+  Status = PeiCoreGetBootMode (&BootMode);

+

+  ASSERT_EFI_ERROR (Status);

+

+  Status = PeiCoreLocatePpi (

+             &gPeiInMemoryGuid,

+             0,

+             NULL,

+             NULL

+             );

+

+  if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {   

+    //

+    // The DxeIpl has not yet been shadowed

+    //

+    PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();

+

+    //

+    // Shadow DxeIpl and then re-run its entry point

+    //

+    Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+  } else {

+    if (BootMode != BOOT_ON_S3_RESUME) {

+    //

+    // The DxeIpl has been shadowed

+    //

+    gInMemory = TRUE;

+

+    //

+    // Install LoadFile PPI

+    //

+    Status = PeiCoreInstallPpi (&mPpiLoadFile);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+      }

+    }

+    //

+    // Install DxeIpl PPI

+    //

+    PeiCoreInstallPpi (&mPpiList);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DxeLoadCore (

+  IN EFI_DXE_IPL_PPI       *This,

+  IN EFI_PEI_SERVICES      **PeiServices,

+  IN EFI_PEI_HOB_POINTERS  HobList

+  )

+/*++

+

+Routine Description:

+

+  Main entry point to last PEIM

+

+Arguments:

+  This         - Entry point for DXE IPL PPI

+  PeiServices  - General purpose services available to every PEIM.

+  HobList      - Address to the Pei HOB list

+

+Returns:

+

+  EFI_SUCCESS          - DEX core was successfully loaded.

+  EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.

+

+--*/

+{

+  EFI_STATUS                                Status;

+  VOID                                      *TopOfStack;

+  VOID                                      *BaseOfStack;

+  EFI_PHYSICAL_ADDRESS                      BspStore;

+  EFI_GUID                                  DxeCoreFileName;

+  EFI_GUID                                  FirmwareFileName;

+  VOID                                      *Pe32Data;

+  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;

+  UINT64                                    DxeCoreSize;

+  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;

+  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;

+  EFI_BOOT_MODE                             BootMode;

+  EFI_PEI_RECOVERY_MODULE_PPI               *PeiRecovery;

+  EFI_PEI_S3_RESUME_PPI                     *S3Resume;

+

+//  PERF_START (PeiServices, L"DxeIpl", NULL, 0);

+  TopOfStack  = NULL;

+  BaseOfStack = NULL;

+  BspStore    = 0;

+  Status      = EFI_SUCCESS;

+

+  //

+  // if in S3 Resume, restore configure

+  //

+  Status = PeiCoreGetBootMode (&BootMode);

+

+  if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {

+    Status = PeiCoreLocatePpi (

+               &gEfiPeiS3ResumePpiGuid,

+               0,

+               NULL,

+               (VOID **)&S3Resume

+               );

+

+    ASSERT_EFI_ERROR (Status);

+

+    Status = S3Resume->S3RestoreConfig (PeiServices);

+

+    ASSERT_EFI_ERROR (Status);

+  }

+

+  Status = EFI_SUCCESS;

+

+  //

+  // Install the PEI Protocols that are shared between PEI and DXE

+  //

+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();

+  ASSERT (PeiEfiPeiPeCoffLoader != NULL);

+

+

+  //

+  // Allocate 128KB for the Stack

+  //

+  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));

+  ASSERT (BaseOfStack != NULL);

+

+  //

+  // Compute the top of the stack we were allocated. Pre-allocate a UINTN

+  // for safety.

+  //

+  TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - sizeof (UINTN));

+

+  //

+  // Add architecture-specifc HOBs (including the BspStore HOB)

+  //

+  Status = CreateArchSpecificHobs (&BspStore);

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Add HOB for the EFI Decompress Protocol

+  //

+  BuildGuidDataHob (

+    &gEfiDecompressProtocolGuid,

+    (VOID *)&gEfiDecompress,

+    sizeof (gEfiDecompress)

+    );

+

+  //

+  // Add HOB for the Tiano Decompress Protocol

+  //

+  BuildGuidDataHob (

+    &gEfiTianoDecompressProtocolGuid,

+    (VOID *)&gTianoDecompress,

+    sizeof (gTianoDecompress)

+    );

+

+  //

+  // Add HOB for the user customized Decompress Protocol

+  //

+  BuildGuidDataHob (

+    &gEfiCustomizedDecompressProtocolGuid,

+    (VOID *)&gCustomDecompress,

+    sizeof (gCustomDecompress)

+    );

+

+  //

+  // Add HOB for the PE/COFF Loader Protocol

+  //

+  BuildGuidDataHob (

+    &gEfiPeiPeCoffLoaderGuid,

+    (VOID *)&PeiEfiPeiPeCoffLoader,

+    sizeof (VOID *)

+    );

+

+  //

+  // See if we are in crisis recovery

+  //

+  Status = PeiCoreGetBootMode (&BootMode);

+

+  if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {

+

+    Status = PeiCoreLocatePpi (

+               &gEfiPeiRecoveryModulePpiGuid,

+               0,

+               NULL,

+               (VOID **)&PeiRecovery

+               );

+

+    ASSERT_EFI_ERROR (Status);

+    Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);

+    ASSERT_EFI_ERROR (Status);

+

+    //

+    // Now should have a HOB with the DXE core w/ the old HOB destroyed

+    //

+  }

+

+  //

+  // Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block

+  // The file found will be processed by PeiProcessFile: It will first be decompressed to

+  // a normal FV, then a corresponding FV type hob will be built which is provided for DXE

+  // core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks

+  // for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned

+  // status

+  //

+  Status = PeiFindFile (

+            EFI_FV_FILETYPE_RAW,

+            EFI_SECTION_PE32,

+            &FirmwareFileName,

+            &Pe32Data

+            );

+

+  //

+  // Find the DXE Core in a Firmware Volume

+  //

+  Status = PeiFindFile (

+            EFI_FV_FILETYPE_DXE_CORE,

+            EFI_SECTION_PE32,

+            &DxeCoreFileName,

+            &Pe32Data

+            );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Load the DXE Core from a Firmware Volume

+  //

+  Status = PeiLoadFile (

+            PeiEfiPeiPeCoffLoader,

+            Pe32Data,

+            &DxeCoreAddress,

+            &DxeCoreSize,

+            &DxeCoreEntryPoint

+            );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Transfer control to the DXE Core

+  // The handoff state is simply a pointer to the HOB list

+  //

+//  PERF_END (PeiServices, L"DxeIpl", NULL, 0);

+

+  Status = PeiCoreInstallPpi (&mPpiSignal);

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Add HOB for the DXE Core

+  //

+  BuildModuleHob (

+    &DxeCoreFileName,

+    DxeCoreAddress,

+    DxeCoreSize,

+    DxeCoreEntryPoint

+    );

+

+  //

+  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT

+  //

+  REPORT_STATUS_CODE (

+    EFI_PROGRESS_CODE,

+    EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT

+    );

+

+  DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));

+  SwitchStack (

+    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,

+    HobList.Raw,

+    (VOID *) (UINTN) BspStore,

+    TopOfStack

+    );

+

+  //

+  // If we get here, then the DXE Core returned.  This is an error

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_OUT_OF_RESOURCES;

+}

+

+EFI_STATUS

+PeiFindFile (

+  IN  UINT8                  Type,

+  IN  UINT16                 SectionType,

+  OUT EFI_GUID               *FileName,

+  OUT VOID                   **Pe32Data

+  )

+/*++

+

+Routine Description:

+

+  Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes

+  described in the HOB list. Able to search in a compression set in a FFS file.

+  But only one level of compression is supported, that is, not able to search

+  in a compression set that is within another compression set.

+

+Arguments:

+

+  Type        - The Type of file to retrieve

+

+  SectionType - The type of section to retrieve from a file

+

+  FileName    - The name of the file found in the Firmware Volume

+

+  Pe32Data    - Pointer to the beginning of the PE/COFF file found in the Firmware Volume

+

+Returns:

+

+  EFI_SUCCESS   - The file was found, and the name is returned in FileName, and a pointer to

+                  the PE/COFF image is returned in Pe32Data

+

+  EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List

+

+--*/

+{

+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;

+  EFI_FFS_FILE_HEADER         *FfsFileHeader;

+  VOID                        *SectionData;

+  EFI_STATUS                  Status;

+  EFI_PEI_HOB_POINTERS        Hob;

+

+

+  FwVolHeader   = NULL;

+  FfsFileHeader = NULL;

+  SectionData   = NULL;

+

+  //

+  // Foreach Firmware Volume, look for a specified type

+  // of file and break out when one is found

+  //

+  Hob.Raw = GetHobList ();

+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress);

+    Status = PeiCoreFfsFindNextFile (

+               Type,

+               FwVolHeader,

+               &FfsFileHeader

+               );

+    if (!EFI_ERROR (Status)) {

+      CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));

+      Status = PeiProcessFile (

+                 SectionType,

+                 FfsFileHeader,

+                 Pe32Data

+                 );

+      return Status;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+PeiLoadFile (

+  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,

+  IN  VOID                                      *Pe32Data,

+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,

+  OUT UINT64                                    *ImageSize,

+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  Loads and relocates a PE/COFF image into memory.

+

+Arguments:

+

+  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol

+

+  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated

+

+  ImageAddress     - The base address of the relocated PE/COFF image

+

+  ImageSize        - The size of the relocated PE/COFF image

+

+  EntryPoint       - The entry point of the relocated PE/COFF image

+

+Returns:

+

+  EFI_SUCCESS   - The file was loaded and relocated

+

+  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file

+

+--*/

+{

+  EFI_STATUS                            Status;

+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;

+

+  ZeroMem (&ImageContext, sizeof (ImageContext));

+  ImageContext.Handle = Pe32Data;

+  Status              = GetImageReadFunction (&ImageContext);

+

+  ASSERT_EFI_ERROR (Status);

+

+  Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Allocate Memory for the image

+  //

+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));

+  ASSERT (ImageContext.ImageAddress != 0);

+

+  //

+  // Load the image to our new buffer

+  //

+  Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Relocate the image in our new buffer

+  //

+  Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Flush the instruction cache so the image data is written before we execute it

+  //

+  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);

+

+  *ImageAddress = ImageContext.ImageAddress;

+  *ImageSize    = ImageContext.ImageSize;

+  *EntryPoint   = ImageContext.EntryPoint;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ShadowDxeIpl (

+  IN EFI_FFS_FILE_HEADER                       *DxeIplFileHeader,

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader

+  )

+/*++

+

+Routine Description:

+

+  Shadow the DXE IPL to a different memory location. This occurs after permanent

+  memory has been discovered.

+

+Arguments:

+

+  DxeIplFileHeader      - Pointer to the FFS file header of the DXE IPL driver

+

+  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol

+

+Returns:

+

+  EFI_SUCCESS   - DXE IPL was successfully shadowed to a different memory location.

+

+  EFI_ ERROR    - The shadow was unsuccessful.

+

+

+--*/

+{

+  UINTN                     SectionLength;

+  UINTN                     OccupiedSectionLength;

+  EFI_PHYSICAL_ADDRESS      DxeIplAddress;

+  UINT64                    DxeIplSize;

+  EFI_PHYSICAL_ADDRESS      DxeIplEntryPoint;

+  EFI_STATUS                Status;

+  EFI_COMMON_SECTION_HEADER *Section;

+

+  Section = (EFI_COMMON_SECTION_HEADER *) (DxeIplFileHeader + 1);

+

+  while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {

+    SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;

+    OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);

+    Section               = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);

+  }

+  //

+  // Relocate DxeIpl into memory by using loadfile service

+  //

+  Status = PeiLoadFile (

+            PeiEfiPeiPeCoffLoader,

+            (VOID *) (Section + 1),

+            &DxeIplAddress,

+            &DxeIplSize,

+            &DxeIplEntryPoint

+            );

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Install PeiInMemory to indicate the Dxeipl is shadowed

+    //

+    Status = PeiCoreInstallPpi (&mPpiPeiInMemory);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+DxeIplLoadFile (

+  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,

+  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,

+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,

+  OUT UINT64                                    *ImageSize,

+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  Given a pointer to an FFS file containing a PE32 image, get the

+  information on the PE32 image, and then "load" it so that it

+  can be executed.

+

+Arguments:

+

+  This  - pointer to our file loader protocol

+

+  FfsHeader - pointer to the FFS file header of the FFS file that

+              contains the PE32 image we want to load

+

+  ImageAddress  - returned address where the PE32 image is loaded

+

+  ImageSize     - returned size of the loaded PE32 image

+

+  EntryPoint    - entry point to the loaded PE32 image

+

+Returns:

+

+  EFI_SUCCESS  - The FFS file was successfully loaded.

+

+  EFI_ERROR    - Unable to load the FFS file.

+

+--*/

+{

+  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;

+  EFI_STATUS                                Status;

+  VOID                                      *Pe32Data;

+

+  Pe32Data = NULL;

+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();

+

+  //

+  // Preprocess the FFS file to get a pointer to the PE32 information

+  // in the enclosed PE32 image.

+  //

+  Status = PeiProcessFile (

+            EFI_SECTION_PE32,

+            FfsHeader,

+            &Pe32Data

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Load the PE image from the FFS file

+  //

+  Status = PeiLoadFile (

+            PeiEfiPeiPeCoffLoader,

+            Pe32Data,

+            ImageAddress,

+            ImageSize,

+            EntryPoint

+            );

+

+  return Status;

+}

+

+EFI_STATUS

+PeiProcessFile (

+  IN  UINT16                 SectionType,

+  IN  EFI_FFS_FILE_HEADER    *FfsFileHeader,

+  OUT VOID                   **Pe32Data

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+  SectionType       - The type of section in the FFS file to process.

+

+  FfsFileHeader     - Pointer to the FFS file to process, looking for the

+                      specified SectionType

+

+  Pe32Data          - returned pointer to the start of the PE32 image found

+                      in the FFS file.

+

+Returns:

+

+  EFI_SUCCESS       - found the PE32 section in the FFS file

+

+--*/

+{

+  EFI_STATUS                      Status;

+  VOID                            *SectionData;

+  DECOMPRESS_LIBRARY              *DecompressLibrary;

+  UINT8                           *DstBuffer;

+  UINT8                           *ScratchBuffer;

+  UINT32                          DstBufferSize;

+  UINT32                          ScratchBufferSize;

+  EFI_COMMON_SECTION_HEADER       *CmpSection;

+  UINTN                           CmpSectionLength;

+  UINTN                           OccupiedCmpSectionLength;

+  VOID                            *CmpFileData;

+  UINTN                           CmpFileSize;

+  EFI_COMMON_SECTION_HEADER       *Section;

+  UINTN                           SectionLength;

+  UINTN                           OccupiedSectionLength;

+  UINT64                          FileSize;

+  EFI_GUID_DEFINED_SECTION        *GuidedSectionHeader;

+  UINT32                          AuthenticationStatus;

+  EFI_PEI_SECTION_EXTRACTION_PPI  *SectionExtract;

+  UINT32                          BufferSize;

+  UINT8                           *Buffer;

+  EFI_PEI_SECURITY_PPI            *Security;

+  BOOLEAN                         StartCrisisRecovery;

+  EFI_GUID                        TempGuid;

+  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;

+  EFI_COMPRESSION_SECTION         *CompressionSection;

+

+  Status = PeiCoreFfsFindSectionData (

+             EFI_SECTION_COMPRESSION,

+             FfsFileHeader,

+             &SectionData

+             );

+

+  //

+  // Upon finding a DXE Core file, see if there is first a compression section

+  //

+  if (!EFI_ERROR (Status)) {

+    //

+    // Yes, there is a compression section, so extract the contents

+    // Decompress the image here

+    //

+    Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));

+

+    do {

+      SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;

+      OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);

+

+      //

+      // Was the DXE Core file encapsulated in a GUID'd section?

+      //

+      if (Section->Type == EFI_SECTION_GUID_DEFINED) {

+        //

+        // Locate the GUID'd Section Extractor

+        //

+        GuidedSectionHeader = (VOID *) (Section + 1);

+

+        //

+        // This following code constitutes the addition of the security model

+        // to the DXE IPL.

+        //

+        //

+        // Set a default authenticatino state

+        //

+        AuthenticationStatus = 0;

+

+        Status = PeiCoreLocatePpi (

+                   &gEfiPeiSectionExtractionPpiGuid,

+                   0,

+                   NULL,

+                   (VOID **)&SectionExtract

+                   );

+

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+        //

+        // Verify Authentication State

+        //

+        CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));

+

+        Status = SectionExtract->PeiGetSection (

+                                  GetPeiServicesTablePointer(),

+                                  SectionExtract,

+                                  (EFI_SECTION_TYPE *) &SectionType,

+                                  &TempGuid,

+                                  0,

+                                  (VOID **) &Buffer,

+                                  &BufferSize,

+                                  &AuthenticationStatus

+                                  );

+

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+        //

+        // If not ask the Security PPI, if exists, for disposition

+        //

+        //

+        Status = PeiCoreLocatePpi (

+                   &gEfiPeiSecurityPpiGuid,

+                   0,

+                   NULL,

+                   (VOID **)&Security

+                   );

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+

+        Status = Security->AuthenticationState (

+                            GetPeiServicesTablePointer(),

+                            (struct _EFI_PEI_SECURITY_PPI *) Security,

+                            AuthenticationStatus,

+                            FfsFileHeader,

+                            &StartCrisisRecovery

+                            );

+

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+        //

+        // If there is a security violation, report to caller and have

+        // the upper-level logic possible engender a crisis recovery

+        //

+        if (StartCrisisRecovery) {

+          return EFI_SECURITY_VIOLATION;

+        }

+      }

+

+      if (Section->Type == EFI_SECTION_PE32) {

+        //

+        // This is what we want

+        //

+        *Pe32Data = (VOID *) (Section + 1);

+        return EFI_SUCCESS;

+      } else if (Section->Type == EFI_SECTION_COMPRESSION) {

+        //

+        // This is a compression set, expand it

+        //

+        CompressionSection  = (EFI_COMPRESSION_SECTION *) Section;

+

+        switch (CompressionSection->CompressionType) {

+        case EFI_STANDARD_COMPRESSION:

+          DecompressLibrary = &gTianoDecompress;

+          break;

+

+        case EFI_CUSTOMIZED_COMPRESSION:

+          //

+          // Load user customized compression protocol.

+          //

+          DecompressLibrary = &gCustomDecompress;

+          break;

+

+        case EFI_NOT_COMPRESSED:

+        default:

+          //

+          // Need to support not compressed file

+          //

+          ASSERT_EFI_ERROR (Status);

+          return EFI_NOT_FOUND;

+        }

+

+        Status = DecompressLibrary->GetInfo (

+                   (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),

+                   (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),

+                   &DstBufferSize,

+                   &ScratchBufferSize

+                   );

+        if (EFI_ERROR (Status)) {

+          //

+          // GetInfo failed

+          //

+          return EFI_NOT_FOUND;

+        }

+

+        //

+        // Allocate scratch buffer

+        //

+        ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));

+        if (ScratchBuffer == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+

+        //

+        // Allocate destination buffer

+        //

+        DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));

+        if (DstBuffer == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+

+        //

+        // Call decompress function

+        //

+        Status = DecompressLibrary->Decompress (

+                    (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),

+                    DstBuffer,

+                    ScratchBuffer

+                    );

+

+        CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;

+        if (CmpSection->Type == EFI_SECTION_RAW) {

+          //

+          // Skip the section header and

+          // adjust the pointer alignment to 16

+          //

+          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);

+

+          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {

+            FfsFileHeader = NULL;

+            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);

+            Status = PeiCoreFfsFindNextFile (

+                       EFI_FV_FILETYPE_DXE_CORE,

+                       FvHeader,

+                       &FfsFileHeader

+                       );

+

+            if (EFI_ERROR (Status)) {

+              return EFI_NOT_FOUND;

+            }

+

+            return PeiProcessFile (SectionType, FfsFileHeader, Pe32Data);

+          }

+        }

+        //

+        // Decompress successfully.

+        // Loop the decompressed data searching for expected section.

+        //

+        CmpFileData = (VOID *) DstBuffer;

+        CmpFileSize = DstBufferSize;

+        do {

+          CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;

+          if (CmpSection->Type == EFI_SECTION_PE32) {

+            //

+            // This is what we want

+            //

+            *Pe32Data = (VOID *) (CmpSection + 1);

+            return EFI_SUCCESS;

+          }

+

+          OccupiedCmpSectionLength  = GetOccupiedSize (CmpSectionLength, 4);

+          CmpSection                = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);

+        } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);

+      }

+

+      Section   = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);

+      FileSize  = FfsFileHeader->Size[0] & 0xFF;

+      FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;

+      FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;

+      FileSize &= 0x00FFFFFF;

+    } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);

+

+    //

+    // End of the decompression activity

+    //

+  } else {

+

+    Status = PeiCoreFfsFindSectionData (

+               EFI_SECTION_PE32,

+               FfsFileHeader,

+               &SectionData

+               );

+

+    if (EFI_ERROR (Status)) {

+      Status = PeiCoreFfsFindSectionData (

+                 EFI_SECTION_TE,

+                 FfsFileHeader,

+                 &SectionData

+                 );

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    }

+  }

+

+  *Pe32Data = SectionData;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/DxeLoadX64.c b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeLoadX64.c
new file mode 100644
index 0000000..e0dbe84
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/DxeLoadX64.c
@@ -0,0 +1,990 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. 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.             
+
+Module Name:
+
+  DxeLoad.c
+
+Abstract:
+
+  Last PEIM.
+  Responsibility of this module is to load the DXE Core from a Firmware Volume.
+
+--*/
+
+#include <DxeIpl.h>
+
+#pragma warning( disable : 4305 )
+
+BOOLEAN gInMemory = FALSE;
+
+//
+// GUID for EM64T
+//
+#define EFI_PPI_NEEDED_BY_DXE \
+  { \
+    0x4d37da42, 0x3a0c, 0x4eda, 0xb9, 0xeb, 0xbc, 0x0e, 0x1d, 0xb4, 0x71, 0x3b \
+  }
+EFI_GUID mPpiNeededByDxeGuid = EFI_PPI_NEEDED_BY_DXE;
+
+//
+// Module Globals used in the DXE to PEI handoff
+// These must be module globals, so the stack can be switched
+//
+static EFI_DXE_IPL_PPI mDxeIplPpi = {
+  DxeLoadCore
+};
+
+static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {
+  DxeIplLoadFile
+};
+
+static EFI_PEI_PPI_DESCRIPTOR     mPpiLoadFile = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiFvFileLoaderPpiGuid,
+  &mLoadFilePpi
+};
+
+static EFI_PEI_PPI_DESCRIPTOR     mPpiList = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiDxeIplPpiGuid,
+  &mDxeIplPpi
+};
+
+static EFI_PEI_PPI_DESCRIPTOR     mPpiPeiInMemory = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gPeiInMemoryGuid,
+  NULL
+};
+
+static EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiEndOfPeiSignalPpiGuid,
+  NULL
+};
+
+DECOMPRESS_LIBRARY  gEfiDecompress = {
+  UefiDecompressGetInfo,
+  UefiDecompress
+};
+
+DECOMPRESS_LIBRARY  gTianoDecompress = {
+  TianoDecompressGetInfo,
+  TianoDecompress
+};
+
+DECOMPRESS_LIBRARY  gCustomDecompress = {
+  CustomDecompressGetInfo,
+  CustomDecompress
+};
+
+STATIC
+UINTN
+GetOccupiedSize (
+  IN UINTN   ActualSize,
+  IN UINTN   Alignment
+  )
+{
+  UINTN OccupiedSize;
+
+  OccupiedSize = ActualSize;
+  while ((OccupiedSize & (Alignment - 1)) != 0) {
+    OccupiedSize++;
+  }
+
+  return OccupiedSize;
+}
+
+EFI_STATUS
+EFIAPI
+PeimInitializeDxeIpl (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN EFI_PEI_SERVICES          **PeiServices
+  )
+/*++
+
+Routine Description:
+
+  Initializes the Dxe Ipl PPI
+
+Arguments:
+
+  FfsHeader   - Pointer to FFS file header
+  PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+  EFI_SUCCESS
+
+--*/
+{
+  EFI_STATUS                                Status;
+  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;
+  EFI_BOOT_MODE                             BootMode;
+
+  Status = PeiCoreGetBootMode (&BootMode);
+
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiCoreLocatePpi (
+             &gPeiInMemoryGuid,
+             0,
+             NULL,
+             NULL
+             );
+
+  if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {   
+    //
+    // The DxeIpl has not yet been shadowed
+    //
+    PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
+
+    //
+    // Shadow DxeIpl and then re-run its entry point
+    //
+    Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+  } else {
+    if (BootMode != BOOT_ON_S3_RESUME) {
+    //
+    // The DxeIpl has been shadowed
+    //
+    gInMemory = TRUE;
+
+    //
+    // Install LoadFile PPI
+    //
+    Status = PeiCoreInstallPpi (&mPpiLoadFile);
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+      }
+    }
+    //
+    // Install DxeIpl PPI
+    //
+    PeiCoreInstallPpi (&mPpiList);
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DxeLoadCore (
+  IN EFI_DXE_IPL_PPI       *This,
+  IN EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_HOB_POINTERS  HobList
+  )
+/*++
+
+Routine Description:
+
+  Main entry point to last PEIM
+
+Arguments:
+
+  This         - Entry point for DXE IPL PPI
+  PeiServices  - General purpose services available to every PEIM.
+  HobList      - Address to the Pei HOB list
+
+Returns:
+
+  EFI_SUCCESS          - DEX core was successfully loaded.
+  EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.
+
+--*/
+{
+  EFI_STATUS                                                Status;
+  EFI_PHYSICAL_ADDRESS                                      TopOfStack;
+  EFI_PHYSICAL_ADDRESS                                      BaseOfStack;
+  EFI_PHYSICAL_ADDRESS                                      BspStore;
+  EFI_GUID                                                  DxeCoreFileName;
+  VOID                                                      *DxeCorePe32Data;
+  EFI_PHYSICAL_ADDRESS                                      DxeCoreAddress;
+  UINT64                                                    DxeCoreSize;
+  EFI_PHYSICAL_ADDRESS                                      DxeCoreEntryPoint;
+  EFI_PEI_PE_COFF_LOADER_PROTOCOL                           *PeiEfiPeiPeCoffLoader;
+  EFI_BOOT_MODE                                             BootMode;
+  EFI_PEI_RECOVERY_MODULE_PPI                               *PeiRecovery;
+  EFI_PEI_S3_RESUME_PPI                                     *S3Resume;
+  EFI_PHYSICAL_ADDRESS                                      PageTables;
+  
+  TopOfStack  = 0;
+  BaseOfStack = 0;
+  BspStore    = 0;
+  Status      = EFI_SUCCESS;
+
+  //
+  // if in S3 Resume, restore configure
+  //
+  Status = PeiCoreGetBootMode (&BootMode);
+
+  if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {
+    Status = PeiCoreLocatePpi (
+               &gEfiPeiS3ResumePpiGuid,
+               0,
+               NULL,
+               (VOID **)&S3Resume
+               );
+
+    ASSERT_EFI_ERROR (Status);
+
+    Status = S3Resume->S3RestoreConfig (PeiServices);
+
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Install the PEI Protocols that are shared between PEI and DXE
+  //
+#ifdef EFI_NT_EMULATOR
+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
+  ASSERT (PeiEfiPeiPeCoffLoader != NULL);
+#else
+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderX64Protocol ();
+#endif 
+
+#if 0
+  Status = InstallEfiPeiPeCoffLoader64 (PeiServices, &PeiEfiPeiPeCoffLoader, NULL);
+  ASSERT_EFI_ERROR (Status);
+#endif
+  //
+  // Allocate 128KB for the Stack
+  //
+  PeiCoreAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
+  ASSERT (BaseOfStack != 0);
+
+  //
+  // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes
+  // for safety (PpisNeededByDxe and DxeCore).
+  //
+  TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;
+
+  //
+  // Add architecture-specifc HOBs (including the BspStore HOB)
+  //
+  Status = CreateArchSpecificHobs (&BspStore);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // See if we are in crisis recovery
+  //
+  Status = PeiCoreGetBootMode (&BootMode);
+  if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {
+    Status = PeiCoreLocatePpi (
+               &gEfiPeiRecoveryModulePpiGuid,
+               0,
+               NULL,
+               (VOID **)&PeiRecovery
+               );
+
+    ASSERT_EFI_ERROR (Status);
+    Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Find the DXE Core in a Firmware Volume
+  //
+  Status = PeiFindFile (
+             EFI_FV_FILETYPE_DXE_CORE,
+             EFI_SECTION_PE32,
+             &DxeCoreFileName,
+             &DxeCorePe32Data
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Transfer control to the DXE Core
+  // The handoff state is simply a pointer to the HOB list
+  //
+  // PEI_PERF_END (PeiServices, L"DxeIpl", NULL, 0);
+
+  Status = PeiCoreInstallPpi (&mPpiSignal);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \
+  // memory, it may be corrupted when copying FV to high-end memory 
+  LoadGo64Gdt();
+
+  //
+  // Limit to 36 bits of addressing for debug. Should get it from CPU
+  //
+  PageTables = CreateIdentityMappingPageTables (36);
+
+
+  //
+  // Load the DXE Core from a Firmware Volume
+  //
+  Status = PeiLoadx64File (
+             PeiEfiPeiPeCoffLoader,
+             DxeCorePe32Data,
+             EfiBootServicesData,
+             &DxeCoreAddress,
+             &DxeCoreSize,
+             &DxeCoreEntryPoint
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  //
+  // Add HOB for the DXE Core
+  //
+  BuildModuleHob (
+    &DxeCoreFileName,
+    DxeCoreAddress,
+    DxeCoreSize,
+    DxeCoreEntryPoint
+    );
+
+  //
+  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
+  //
+  REPORT_STATUS_CODE (
+    EFI_PROGRESS_CODE,
+    EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
+    );
+
+  DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));
+  //
+  // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
+  // Call x64 drivers passing in single argument, a pointer to the HOBs.
+  //
+  ActivateLongMode (
+    PageTables, 
+    (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw), 
+    TopOfStack,
+    0x00000000,
+    DxeCoreEntryPoint
+    );
+
+  //
+  // If we get here, then the DXE Core returned.  This is an error
+  //
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_OUT_OF_RESOURCES;
+}
+
+EFI_STATUS
+PeiFindFile (
+  IN  UINT8                  Type,
+  IN  UINT16                 SectionType,
+  OUT EFI_GUID               *FileName,
+  OUT VOID                   **Pe32Data
+  )
+/*++
+
+Routine Description:
+
+  Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
+  described in the HOB list. Able to search in a compression set in a FFS file.
+  But only one level of compression is supported, that is, not able to search
+  in a compression set that is within another compression set.
+
+Arguments:
+
+  Type        - The Type of file to retrieve
+
+  SectionType - The type of section to retrieve from a file
+
+  FileName    - The name of the file found in the Firmware Volume
+
+  Pe32Data    - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
+
+Returns:
+
+  EFI_SUCCESS   - The file was found, and the name is returned in FileName, and a pointer to
+                  the PE/COFF image is returned in Pe32Data
+
+  EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
+
+--*/
+{
+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
+  EFI_FFS_FILE_HEADER         *FfsFileHeader;
+  VOID                        *SectionData;
+  EFI_STATUS                  Status;
+  EFI_PEI_HOB_POINTERS        Hob;
+
+
+  FwVolHeader   = NULL;
+  FfsFileHeader = NULL;
+  SectionData   = NULL;
+
+  //
+  // Foreach Firmware Volume, look for a specified type
+  // of file and break out when one is found
+  //
+  Hob.Raw = GetHobList ();
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {
+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress);
+    Status = PeiCoreFfsFindNextFile (
+               Type,
+               FwVolHeader,
+               &FfsFileHeader
+               );
+    if (!EFI_ERROR (Status)) {
+      CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));
+      Status = PeiProcessFile (
+                 SectionType,
+                 FfsFileHeader,
+                 Pe32Data
+                 );
+      return Status;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+PeiLoadx64File (
+  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,
+  IN  VOID                                      *Pe32Data,
+  IN  EFI_MEMORY_TYPE                           MemoryType,
+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
+  OUT UINT64                                    *ImageSize,
+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
+  )
+/*++
+
+Routine Description:
+
+  Loads and relocates a PE/COFF image into memory.
+
+Arguments:
+
+  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
+
+  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated
+
+  ImageAddress     - The base address of the relocated PE/COFF image
+
+  ImageSize        - The size of the relocated PE/COFF image
+
+  EntryPoint       - The entry point of the relocated PE/COFF image
+
+Returns:
+
+  EFI_SUCCESS                     - The file was loaded and relocated
+  EFI_OUT_OF_RESOURCES            - There was not enough memory to load and relocate the PE/COFF file
+
+--*/
+{
+  EFI_STATUS                            Status;
+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
+  EFI_PHYSICAL_ADDRESS                  MemoryBuffer;
+
+  ZeroMem (&ImageContext, sizeof (ImageContext));
+  ImageContext.Handle = Pe32Data;
+  Status              = GetImageReadFunction (&ImageContext);
+
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Allocate Memory for the image
+  //
+  //
+  // Allocate Memory for the image
+  //
+  PeiCoreAllocatePages (MemoryType, EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize), &MemoryBuffer);
+  ImageContext.ImageAddress = MemoryBuffer;
+  ASSERT (ImageContext.ImageAddress != 0);
+
+  //
+  // Load the image to our new buffer
+  //
+
+  Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  //
+  // Relocate the image in our new buffer
+  //
+  Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Flush the instruction cache so the image data is written before we execute it
+  //
+  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+
+  *ImageAddress = ImageContext.ImageAddress;
+  *ImageSize    = ImageContext.ImageSize;
+  *EntryPoint   = ImageContext.EntryPoint;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ShadowDxeIpl (
+  IN EFI_FFS_FILE_HEADER                       *DxeIplFileHeader,
+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader
+  )
+/*++
+
+Routine Description:
+
+  Shadow the DXE IPL to a different memory location. This occurs after permanent
+  memory has been discovered.
+
+Arguments:
+
+  DxeIplFileHeader      - Pointer to the FFS file header of the DXE IPL driver
+
+  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
+
+Returns:
+
+  EFI_SUCCESS   - DXE IPL was successfully shadowed to a different memory location.
+
+  EFI_ ERROR    - The shadow was unsuccessful.
+
+
+--*/
+{
+  UINTN                     SectionLength;
+  UINTN                     OccupiedSectionLength;
+  EFI_PHYSICAL_ADDRESS      DxeIplAddress;
+  UINT64                    DxeIplSize;
+  EFI_PHYSICAL_ADDRESS      DxeIplEntryPoint;
+  EFI_STATUS                Status;
+  EFI_COMMON_SECTION_HEADER *Section;
+
+  Section = (EFI_COMMON_SECTION_HEADER *) (DxeIplFileHeader + 1);
+
+  while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {
+    SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;
+    OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
+    Section               = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
+  }
+  
+  //
+  // Relocate DxeIpl into memory by using loadfile service
+  //
+  Status = PeiLoadx64File (
+            PeiEfiPeiPeCoffLoader,
+            (VOID *) (Section + 1),
+            EfiBootServicesData,
+            &DxeIplAddress,
+            &DxeIplSize,
+            &DxeIplEntryPoint
+            );
+ 
+  if (Status == EFI_SUCCESS) {
+    //
+    // Install PeiInMemory to indicate the Dxeipl is shadowed
+    //
+    Status = PeiCoreInstallPpi (&mPpiPeiInMemory);
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DxeIplLoadFile (
+  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,
+  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,
+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
+  OUT UINT64                                    *ImageSize,
+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
+  )
+/*++
+
+Routine Description:
+
+  Given a pointer to an FFS file containing a PE32 image, get the
+  information on the PE32 image, and then "load" it so that it
+  can be executed.
+
+Arguments:
+
+  This  - pointer to our file loader protocol
+  FfsHeader - pointer to the FFS file header of the FFS file that
+              contains the PE32 image we want to load
+  ImageAddress  - returned address where the PE32 image is loaded
+  ImageSize     - returned size of the loaded PE32 image
+  EntryPoint    - entry point to the loaded PE32 image
+
+Returns:
+ 
+  EFI_SUCCESS  - The FFS file was successfully loaded.
+  EFI_ERROR    - Unable to load the FFS file.
+
+--*/
+{
+  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;
+  EFI_STATUS                                Status;
+  VOID                                      *Pe32Data;
+
+  Pe32Data = NULL;
+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
+
+  //
+  // Preprocess the FFS file to get a pointer to the PE32 information
+  // in the enclosed PE32 image.
+  //
+  Status = PeiProcessFile (
+            EFI_SECTION_PE32,
+            FfsHeader,
+            &Pe32Data
+            );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Load the PE image from the FFS file
+  //
+  Status = PeiLoadx64File (
+            PeiEfiPeiPeCoffLoader,
+            Pe32Data,
+            EfiBootServicesData,
+            ImageAddress,
+            ImageSize,
+            EntryPoint
+            );
+
+  return Status;
+}
+
+EFI_STATUS
+PeiProcessFile (
+  IN  UINT16                 SectionType,
+  IN  EFI_FFS_FILE_HEADER    *FfsFileHeader,
+  OUT VOID                   **Pe32Data
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+  SectionType       - The type of section in the FFS file to process.
+
+  FfsFileHeader     - Pointer to the FFS file to process, looking for the
+                      specified SectionType
+
+  Pe32Data          - returned pointer to the start of the PE32 image found
+                      in the FFS file.
+
+Returns:
+
+  EFI_SUCCESS       - found the PE32 section in the FFS file
+
+--*/
+{
+  EFI_STATUS                      Status;
+  VOID                            *SectionData;
+  DECOMPRESS_LIBRARY              *DecompressLibrary;
+  UINT8                           *DstBuffer;
+  UINT8                           *ScratchBuffer;
+  UINT32                          DstBufferSize;
+  UINT32                          ScratchBufferSize;
+  EFI_COMMON_SECTION_HEADER       *CmpSection;
+  UINTN                           CmpSectionLength;
+  UINTN                           OccupiedCmpSectionLength;
+  VOID                            *CmpFileData;
+  UINTN                           CmpFileSize;
+  EFI_COMMON_SECTION_HEADER       *Section;
+  UINTN                           SectionLength;
+  UINTN                           OccupiedSectionLength;
+  UINT64                          FileSize;
+  EFI_GUID_DEFINED_SECTION        *GuidedSectionHeader;
+  UINT32                          AuthenticationStatus;
+  EFI_PEI_SECTION_EXTRACTION_PPI  *SectionExtract;
+  UINT32                          BufferSize;
+  UINT8                           *Buffer;
+  EFI_PEI_SECURITY_PPI            *Security;
+  BOOLEAN                         StartCrisisRecovery;
+  EFI_GUID                        TempGuid;
+  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;
+  EFI_COMPRESSION_SECTION         *CompressionSection;
+
+  Status = PeiCoreFfsFindSectionData (
+             EFI_SECTION_COMPRESSION,
+             FfsFileHeader,
+             &SectionData
+             );
+
+  //
+  // Upon finding a DXE Core file, see if there is first a compression section
+  //
+  if (!EFI_ERROR (Status)) {
+    //
+    // Yes, there is a compression section, so extract the contents
+    // Decompress the image here
+    //
+    Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));
+
+    do {
+      SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;
+      OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
+
+      //
+      // Was the DXE Core file encapsulated in a GUID'd section?
+      //
+      if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+        //
+        // Locate the GUID'd Section Extractor
+        //
+        GuidedSectionHeader = (VOID *) (Section + 1);
+
+        //
+        // This following code constitutes the addition of the security model
+        // to the DXE IPL.
+        //
+        //
+        // Set a default authenticatino state
+        //
+        AuthenticationStatus = 0;
+
+        Status = PeiCoreLocatePpi (
+                   &gEfiPeiSectionExtractionPpiGuid,
+                   0,
+                   NULL,
+                   (VOID **)&SectionExtract
+                   );
+
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        //
+        // Verify Authentication State
+        //
+        CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));
+
+        Status = SectionExtract->PeiGetSection (
+                                  GetPeiServicesTablePointer(),
+                                  SectionExtract,
+                                  (EFI_SECTION_TYPE *) &SectionType,
+                                  &TempGuid,
+                                  0,
+                                  (VOID **) &Buffer,
+                                  &BufferSize,
+                                  &AuthenticationStatus
+                                  );
+
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        //
+        // If not ask the Security PPI, if exists, for disposition
+        //
+        //
+        Status = PeiCoreLocatePpi (
+                   &gEfiPeiSecurityPpiGuid,
+                   0,
+                   NULL,
+                   (VOID **)&Security
+                   );
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+
+        Status = Security->AuthenticationState (
+                            GetPeiServicesTablePointer(),
+                            (struct _EFI_PEI_SECURITY_PPI *) Security,
+                            AuthenticationStatus,
+                            FfsFileHeader,
+                            &StartCrisisRecovery
+                            );
+
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        //
+        // If there is a security violation, report to caller and have
+        // the upper-level logic possible engender a crisis recovery
+        //
+        if (StartCrisisRecovery) {
+          return EFI_SECURITY_VIOLATION;
+        }
+      }
+
+      if (Section->Type == EFI_SECTION_PE32) {
+        //
+        // This is what we want
+        //
+        *Pe32Data = (VOID *) (Section + 1);
+        return EFI_SUCCESS;
+      } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+        //
+        // This is a compression set, expand it
+        //
+        CompressionSection  = (EFI_COMPRESSION_SECTION *) Section;
+
+        switch (CompressionSection->CompressionType) {
+        case EFI_STANDARD_COMPRESSION:
+          DecompressLibrary = &gTianoDecompress;
+          break;
+
+        case EFI_CUSTOMIZED_COMPRESSION:
+          //
+          // Load user customized compression protocol.
+          //
+          DecompressLibrary = &gCustomDecompress;
+          break;
+
+        case EFI_NOT_COMPRESSED:
+        default:
+          //
+          // Need to support not compressed file
+          //
+          ASSERT_EFI_ERROR (Status);
+          return EFI_NOT_FOUND;
+        }
+
+        Status = DecompressLibrary->GetInfo (
+                   (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+                   (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
+                   &DstBufferSize,
+                   &ScratchBufferSize
+                   );
+        if (EFI_ERROR (Status)) {
+          //
+          // GetInfo failed
+          //
+          return EFI_NOT_FOUND;
+        }
+
+        //
+        // Allocate scratch buffer
+        //
+        ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
+        if (ScratchBuffer == NULL) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+
+        //
+        // Allocate destination buffer
+        //
+        DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+        if (DstBuffer == NULL) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+
+        //
+        // Call decompress function
+        //
+        Status = DecompressLibrary->Decompress (
+                    (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+                    DstBuffer,
+                    ScratchBuffer
+                    );
+
+        CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
+        if (CmpSection->Type == EFI_SECTION_RAW) {
+          //
+          // Skip the section header and
+          // adjust the pointer alignment to 16
+          //
+          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);
+
+          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
+            FfsFileHeader = NULL;
+            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
+            Status = PeiCoreFfsFindNextFile (
+                       EFI_FV_FILETYPE_DXE_CORE,
+                       FvHeader,
+                       &FfsFileHeader
+                       );
+
+            if (EFI_ERROR (Status)) {
+              return EFI_NOT_FOUND;
+            }
+
+            return PeiProcessFile (SectionType, FfsFileHeader, Pe32Data);
+          }
+        }
+        //
+        // Decompress successfully.
+        // Loop the decompressed data searching for expected section.
+        //
+        CmpFileData = (VOID *) DstBuffer;
+        CmpFileSize = DstBufferSize;
+        do {
+          CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
+          if (CmpSection->Type == EFI_SECTION_PE32) {
+            //
+            // This is what we want
+            //
+            *Pe32Data = (VOID *) (CmpSection + 1);
+            return EFI_SUCCESS;
+          }
+
+          OccupiedCmpSectionLength  = GetOccupiedSize (CmpSectionLength, 4);
+          CmpSection                = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
+        } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
+      }
+
+      Section   = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
+      FileSize  = FfsFileHeader->Size[0] & 0xFF;
+      FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
+      FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
+      FileSize &= 0x00FFFFFF;
+    } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);
+
+    //
+    // End of the decompression activity
+    //
+  } else {
+
+    Status = PeiCoreFfsFindSectionData (
+               EFI_SECTION_PE32,
+               FfsFileHeader,
+               &SectionData
+               );
+
+    if (EFI_ERROR (Status)) {
+      Status = PeiCoreFfsFindSectionData (
+                 EFI_SECTION_TE,
+                 FfsFileHeader,
+                 &SectionData
+                 );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+    }
+  }
+
+  *Pe32Data = SectionData;
+
+  return EFI_SUCCESS;
+}
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/edk2/EdkModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
new file mode 100644
index 0000000..4d1015b
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -0,0 +1,51 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeLoadFunc.c

+

+Abstract:

+

+  Ia32-specifc functionality for DxeLoad.

+

+--*/

+

+#include <DxeIpl.h>

+

+EFI_STATUS

+CreateArchSpecificHobs (

+  OUT EFI_PHYSICAL_ADDRESS      *BspStore

+  )

+/*++

+

+Routine Description:

+

+  Creates architecture-specific HOBs.

+

+  Note: New parameters should NOT be added for any HOBs that are added to this

+        function.  BspStore is a special case because it is required for the

+        call to SwitchStacks() in DxeLoad().

+

+Arguments:

+

+  BspStore    - The address of the BSP Store for those architectures that need

+                it.  Otherwise 0.

+

+Returns:

+

+  EFI_SUCCESS   - The HOBs were created successfully.

+

+--*/

+{

+  *BspStore = 0;

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/Ia32/ImageRead.c b/edk2/EdkModulePkg/Core/DxeIplPeim/Ia32/ImageRead.c
new file mode 100644
index 0000000..fe07608
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/Ia32/ImageRead.c
@@ -0,0 +1,112 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ImageRead.c

+

+Abstract:

+

+--*/

+

+#include <DxeIpl.h>

+

+EFI_STATUS

+EFIAPI

+PeiImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

+

+Arguments:

+

+  FileHandle - The handle to the PE/COFF file

+

+  FileOffset - The offset, in bytes, into the file to read

+

+  ReadSize   - The number of bytes to read from the file starting at FileOffset

+

+  Buffer     - A pointer to the buffer to read the data into.

+

+Returns:

+

+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

+

+--*/

+{

+  UINT8 *Destination32;

+  UINT8 *Source32;

+  UINTN  Length;

+

+ 

+  Destination32 = Buffer;

+  Source32      = (UINT8 *) ((UINTN) FileHandle + FileOffset);

+

+  //

+  // This function assumes 32-bit alignment to increase performance

+  //

+//  ASSERT (ALIGN_POINTER (Destination32, sizeof (UINT32)) == Destination32);

+//  ASSERT (ALIGN_POINTER (Source32, sizeof (UINT32)) == Source32);

+

+  Length = *ReadSize;

+  while (Length--) {

+    *(Destination32++) = *(Source32++);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetImageReadFunction (

+  IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+/*++

+

+Routine Description:

+  Support routine to return the PE32 Image Reader.

+  If the PeiImageRead() function is less than a page

+  in legnth. If the function is more than a page the DXE IPL will crash!!!!

+

+Arguments:

+  ImageContext  - The context of the image being loaded

+

+Returns:

+  EFI_SUCCESS - If Image function location is found

+

+--*/

+{

+  VOID        *MemoryBuffer;

+

+  if (gInMemory) {

+    ImageContext->ImageRead = PeiImageRead;

+    return EFI_SUCCESS;

+  }

+

+  //

+  // BugBug; This code assumes PeiImageRead() is less than a page in size!

+  //  Allocate a page so we can shaddow the read function from FLASH into 

+  //  memory to increase performance. 

+  //

+  

+  MemoryBuffer = AllocateCopyPool (0x400, (VOID *)(UINTN) PeiImageRead);

+  ASSERT (MemoryBuffer != NULL);

+

+  ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c b/edk2/EdkModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c
new file mode 100644
index 0000000..95fb093
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c
@@ -0,0 +1,70 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  IpfDxeLoad.c

+

+Abstract:

+

+  Ipf-specifc functionality for DxeLoad.

+

+--*/

+

+#include <DxeIpl.h>

+

+EFI_STATUS

+CreateArchSpecificHobs (

+  OUT EFI_PHYSICAL_ADDRESS      *BspStore

+  )

+/*++

+

+Routine Description:

+

+  Creates architecture-specific HOBs.

+

+  Note: New parameters should NOT be added for any HOBs that are added to this

+        function.  BspStore is a special case because it is required for the

+        call to SwitchStacks() in DxeLoad().

+

+Arguments:

+

+  BspStore    - The address of the BSP Store for those architectures that need

+                it.  Otherwise 0.

+

+Returns:

+

+  EFI_SUCCESS   - The HOBs were created successfully.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = EFI_SUCCESS; 

+ 

+  ASSERT (NULL != BspStore);

+

+  //

+  // Allocate 16KB for the BspStore

+  //

+  Status = PeiCoreAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (BSP_STORE_SIZE), BspStore);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  BuildBspStoreHob (

+    *BspStore,

+    BSP_STORE_SIZE,

+    EfiBootServicesData

+    );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/Ipf/ImageRead.c b/edk2/EdkModulePkg/Core/DxeIplPeim/Ipf/ImageRead.c
new file mode 100644
index 0000000..16b44b2
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/Ipf/ImageRead.c
@@ -0,0 +1,72 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ImageRead.c

+

+Abstract:

+

+--*/

+

+#include <DxeIpl.h>

+

+EFI_STATUS

+PeiImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

+

+Arguments:

+

+  FileHandle - The handle to the PE/COFF file

+

+  FileOffset - The offset, in bytes, into the file to read

+

+  ReadSize   - The number of bytes to read from the file starting at FileOffset

+

+  Buffer     - A pointer to the buffer to read the data into.

+

+Returns:

+

+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

+

+--*/

+{

+  CHAR8 *Destination8;

+  CHAR8 *Source8;

+  UINTN Length;

+

+  Destination8  = Buffer;

+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);

+  Length        = *ReadSize;

+  while (Length--) {

+    *(Destination8++) = *(Source8++);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetImageReadFunction (

+  IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  ImageContext->ImageRead = PeiImageRead;

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/build.xml b/edk2/EdkModulePkg/Core/DxeIplPeim/build.xml
new file mode 100644
index 0000000..158d088
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 
+All rights reserved. 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.-->
+<project basedir="." default="DxeIpl"><!--Apply external ANT tasks-->
+   <taskdef resource="GenBuild.tasks"/>
+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+   <property environment="env"/>
+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+   <property name="MODULE_RELATIVE_PATH" value="Core/DxeIplPeim"/>
+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>
+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>
+   <target name="DxeIplX64">
+      <GenBuild baseName="DxeIplX64" mbdFilename="${MODULE_DIR}/DxeIplX64.mbd" msaFilename="${MODULE_DIR}/DxeIplX64.msa"/>
+   </target>
+   <target name="DxeIpl">
+      <GenBuild baseName="DxeIpl" mbdFilename="${MODULE_DIR}/DxeIpl.mbd" msaFilename="${MODULE_DIR}/DxeIpl.msa"/>
+   </target>
+   <target depends="DxeIpl_clean" name="clean"/>
+   <target depends="DxeIpl_cleanall" name="cleanall"/>
+   <target name="DxeIplX64_clean">
+      <OutputDirSetup baseName="DxeIplX64" mbdFilename="${MODULE_DIR}/DxeIplX64.mbd" msaFilename="${MODULE_DIR}/DxeIplX64.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/DxeIplX64_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/DxeIplX64_build.xml" target="clean"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+   </target>
+   <target name="DxeIpl_clean">
+      <OutputDirSetup baseName="DxeIpl" mbdFilename="${MODULE_DIR}/DxeIpl.mbd" msaFilename="${MODULE_DIR}/DxeIpl.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/DxeIpl_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/DxeIpl_build.xml" target="clean"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+   </target>
+   <target name="DxeIplX64_cleanall">
+      <OutputDirSetup baseName="DxeIplX64" mbdFilename="${MODULE_DIR}/DxeIplX64.mbd" msaFilename="${MODULE_DIR}/DxeIplX64.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/DxeIplX64_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/DxeIplX64_build.xml" target="cleanall"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}"/>
+      <delete dir="${DEST_DIR_DEBUG}"/>
+      <delete>
+         <fileset dir="${BIN_DIR}" includes="**DxeIplX64*"/>
+      </delete>
+   </target>
+   <target name="DxeIpl_cleanall">
+      <OutputDirSetup baseName="DxeIpl" mbdFilename="${MODULE_DIR}/DxeIpl.mbd" msaFilename="${MODULE_DIR}/DxeIpl.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/DxeIpl_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/DxeIpl_build.xml" target="cleanall"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}"/>
+      <delete dir="${DEST_DIR_DEBUG}"/>
+      <delete>
+         <fileset dir="${BIN_DIR}" includes="**DxeIpl*"/>
+      </delete>
+   </target>
+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/build_X64.xml b/edk2/EdkModulePkg/Core/DxeIplPeim/build_X64.xml
new file mode 100644
index 0000000..aef68ec
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/build_X64.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeIpl"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Core\DxeIplPeim"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="DxeIpl">

+      <GenBuild baseName="DxeIpl" mbdFilename="${MODULE_DIR}\DxeIplX64.mbd" msaFilename="${MODULE_DIR}\DxeIplX64.msa"/>

+   </target>

+   <target depends="DxeIpl_clean" name="clean"/>

+   <target depends="DxeIpl_cleanAll" name="cleanAll"/>

+   <target name="DxeIpl_clean">

+      <OutputDirSetup baseName="DxeIpl" mbdFilename="${MODULE_DIR}\DxeIplX64.mbd" msaFilename="${MODULE_DIR}\DxeIplX64.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\DxeIpl_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\DxeIpl_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeIpl_cleanAll">

+      <OutputDirSetup baseName="DxeIpl" mbdFilename="${MODULE_DIR}\DxeIplX64.mbd" msaFilename="${MODULE_DIR}\DxeIplX64.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\DxeIpl_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\DxeIpl_build.xml" target="cleanAll"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeIpl*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/x64/DxeLoadFunc.c b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/DxeLoadFunc.c
new file mode 100644
index 0000000..c93c7e1
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/DxeLoadFunc.c
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeLoadFunc.c

+

+Abstract:

+

+  Ia32-specifc functionality for DxeLoad X64 Lakeport.

+

+--*/

+

+#include <DxeIpl.h>

+

+EFI_STATUS

+CreateArchSpecificHobs (

+  OUT EFI_PHYSICAL_ADDRESS      *BspStore

+  )

+/*++

+

+Routine Description:

+

+  Creates architecture-specific HOBs.

+

+  Note: New parameters should NOT be added for any HOBs that are added to this

+        function.  BspStore is a special case because it is required for the

+        call to SwitchStacks() in DxeLoad().

+

+Arguments:

+

+  PeiServices - General purpose services available to every PEIM.

+  BspStore    - The address of the BSP Store for those architectures that need

+                it.  Otherwise 0.

+

+Returns:

+

+  EFI_SUCCESS   - The HOBs were created successfully.

+

+--*/

+{

+  *BspStore = 0;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/x64/ImageRead.c b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/ImageRead.c
new file mode 100644
index 0000000..dd977f2
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/ImageRead.c
@@ -0,0 +1,106 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ImageRead.c

+

+Abstract:

+

+--*/

+

+#include <DxeIpl.h>

+

+EFI_STATUS

+EFIAPI

+PeiImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

+

+Arguments:

+

+  FileHandle - The handle to the PE/COFF file

+

+  FileOffset - The offset, in bytes, into the file to read

+

+  ReadSize   - The number of bytes to read from the file starting at FileOffset

+

+  Buffer     - A pointer to the buffer to read the data into.

+

+Returns:

+

+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

+

+--*/

+{

+  CHAR8 *Destination8;

+  CHAR8 *Source8;

+  UINTN Length;

+

+  Destination8  = Buffer;

+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);

+  Length        = *ReadSize;

+  while (Length--) {

+    *(Destination8++) = *(Source8++);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetImageReadFunction (

+  IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+/*++

+

+Routine Description:

+

+  Support routine to return the PE32 Image Reader.

+  If the PeiImageRead() function is less than a page

+  in legnth. If the function is more than a page the DXE IPL will crash!!!!

+

+Arguments:

+  ImageContext  - The context of the image being loaded

+

+Returns:

+

+  EFI_SUCCESS - If Image function location is found

+

+--*/

+{

+  VOID        *MemoryBuffer;

+

+  if (gInMemory) {

+    ImageContext->ImageRead = PeiImageRead;

+    return EFI_SUCCESS;

+  }

+

+  //

+  // BugBug; This code assumes PeiImageRead() is less than a page in size!

+  //  Allocate a page so we can shaddow the read function from FLASH into 

+  //  memory to increase performance. 

+  //

+  

+  MemoryBuffer = AllocateCopyPool (0x400, (VOID *)(UINTN) PeiImageRead);

+  ASSERT (MemoryBuffer != NULL);

+

+  ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/x64/LongMode.asm b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/LongMode.asm
new file mode 100644
index 0000000..ae87bd8
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/LongMode.asm
@@ -0,0 +1,1350 @@
+      TITLE   LongMode.asm: Assembly code for the entering long mode
+
+;------------------------------------------------------------------------------
+;*
+;*   Copyright (c) 2006, Intel Corporation                                                         
+;*   All rights reserved. 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.             
+;*   
+;*    LongMode.asm
+;*  
+;*   Abstract:
+;*
+;*    Transition from 32-bit protected mode EFI environment into x64 
+;*    64-bit bit long mode.
+;*  
+;------------------------------------------------------------------------------
+
+.686p
+.model  flat        
+
+;
+; Create the exception handler code in IA32 C code
+;
+
+.code
+.stack
+.MMX
+.XMM
+
+_LoadGo64Gdt	PROC Near Public
+    push    ebp               ; C prolog
+    push    edi
+    mov     ebp, esp
+    ;
+    ; Disable interrupts
+    ;
+    cli
+    ;
+    ; Reload the selectors
+    ; Note:
+    ;      Make the Selectors 64-bit ready
+    ;
+    mov     edi, OFFSET gdtr    ; Load GDT register
+    mov     ax,cs               ; Get the selector data from our code image          
+    mov     es,ax
+    lgdt    FWORD PTR es:[edi]  ; and update the GDTR   
+
+    db      067h
+    db      0eah              ; Far Jump Offset:Selector to reload CS
+    dd      OFFSET DataSelectorRld;   Offset is ensuing instruction boundary
+    dw      LINEAR_CODE_SEL   ;   Selector is our code selector, 10h
+DataSelectorRld::
+    mov     ax, SYS_DATA_SEL ; Update the Base for the new selectors, too
+    mov     ds, ax
+    mov     es, ax
+    mov     fs, ax
+    mov     gs, ax
+    mov     ss, ax  
+    
+    pop     edi
+    pop     ebp
+    ret
+_LoadGo64Gdt endp   
+    
+
+; VOID
+; ActivateLongMode (
+;   IN  EFI_PHYSICAL_ADDRESS  PageTables,  
+;   IN  EFI_PHYSICAL_ADDRESS  HobStart,
+;   IN  EFI_PHYSICAL_ADDRESS  Stack,
+;   IN  EFI_PHYSICAL_ADDRESS  PpisNeededByDxeIplEntryPoint,
+;   IN  EFI_PHYSICAL_ADDRESS  DxeCoreEntryPoint
+;   )
+;
+; Input:  [ebp][0h]  = Original ebp
+;         [ebp][4h]  = Return address
+;         [ebp][8h]  = PageTables
+;         [ebp][10h] = HobStart
+;         [ebp][18h] = Stack
+;         [ebp][20h] = CodeEntryPoint1 <--- Call this first (for each call, pass HOB pointer)
+;         [ebp][28h] = CodeEntryPoint2 <--- Call this second
+;
+;
+_ActivateLongMode  PROC Near Public
+    push    ebp               ; C prolog
+    mov     ebp, esp
+
+    ;
+    ; Use CPUID to determine if the processor supports long mode.
+    ;
+    mov     eax, 80000000h  ; Extended-function code 8000000h.
+    cpuid                   ; Is largest extended function
+    cmp     eax, 80000000h  ; any function > 80000000h?
+    jbe     no_long_mode    ; If not, no long mode.
+    mov     eax, 80000001h  ; Extended-function code 8000001h.
+    cpuid                   ; Now EDX = extended-features flags.
+    bt      edx, 29         ; Test if long mode is supported.
+    jnc     no_long_mode    ; Exit if not supported.
+
+    ;
+    ; Enable the 64-bit page-translation-table entries by
+    ; setting CR4.PAE=1 (this is _required_ before activating
+    ; long mode). Paging is not enabled until after long mode
+    ; is enabled.
+    ;
+    mov eax, cr4
+    bts eax, 5
+    mov cr4, eax
+
+    ;
+    ; Get the long-mode page tables, and initialize the
+    ; 64-bit CR3 (page-table base address) to point to the base
+    ; of the PML4 page table. The PML4 page table must be located
+    ; below 4 Gbytes because only 32 bits of CR3 are loaded when
+    ; the processor is not in 64-bit mode.
+    ;
+    mov eax, [ebp+8h]       ; Get Page Tables
+    mov cr3, eax            ; Initialize CR3 with PML4 base.
+
+    ;
+    ; Enable long mode (set EFER.LME=1).
+    ;
+    mov ecx, 0c0000080h ; EFER MSR number.
+    rdmsr               ; Read EFER.
+    bts eax, 8          ; Set LME=1.
+    wrmsr               ; Write EFER.
+
+    ;
+    ; Enable paging to activate long mode (set CR0.PG=1)
+    ;
+   
+   
+    mov eax, cr0 ; Read CR0.
+    bts eax, 31  ; Set PG=1.
+    mov cr0, eax ; Write CR0.
+    jmp   go_to_long_mode
+go_to_long_mode:
+
+    ;
+    ; This is the next instruction after enabling paging.  Jump to long mode
+    ;
+    db      067h
+    db      0eah              ; Far Jump Offset:Selector to reload CS
+    dd      OFFSET in_long_mode;   Offset is ensuing instruction boundary
+    dw      SYS_CODE64_SEL    ;   Selector is our code selector, 10h
+in_long_mode::
+    mov     ax, SYS_DATA64_SEL
+    mov     es, ax
+    mov     ss, ax
+    mov     ds, ax
+;;    jmp     $
+    
+           
+    ;
+    ; We're in long mode, so marshall the arguments to call the
+    ; passed in function pointers
+    ; Recall
+    ;         [ebp][10h] = HobStart
+    ;         [ebp][18h] = Stack
+    ;         [ebp][20h] = PpisNeededByDxeIplEntryPoint <--- Call this first (for each call, pass HOB pointer)
+    ;         [ebp][28h] = DxeCoreEntryPoint            <--- Call this second
+    ;
+    db  48h
+    mov ebx, [ebp+18h]        ; Setup the stack
+    db  48h
+    mov esp, ebx              ; On a new stack now
+
+
+;; 00000905  FF D0		    call rax
+
+    db  48h
+    mov ecx, [ebp+10h]        ; Pass Hob Start in RCX
+    db  48h
+    mov eax, [ebp+28h]        ; Get the function pointer for 
+                              ; DxeCoreEntryPoint into EAX
+
+;; 00000905  FF D0		    call rax
+    db 0ffh
+    db 0d0h
+
+    ;
+    ; WE SHOULD NEVER GET HERE!!!!!!!!!!!!!
+    ;
+no_long_mode:
+    jmp   no_long_mode
+_ActivateLongMode endp
+
+        align 16
+
+gdtr    dw GDT_END - GDT_BASE - 1   ; GDT limit
+        dd OFFSET GDT_BASE          ; (GDT base gets set above)
+
+;-----------------------------------------------------------------------------;
+;   global descriptor table (GDT)
+;-----------------------------------------------------------------------------;
+
+        align 16
+
+public GDT_BASE
+GDT_BASE:
+; null descriptor
+NULL_SEL            equ $-GDT_BASE    ; Selector [0]
+        dw 0            ; limit 15:0
+        dw 0            ; base 15:0
+        db 0            ; base 23:16
+        db 0            ; type
+        db 0            ; limit 19:16, flags
+        db 0            ; base 31:24
+
+; linear data segment descriptor
+LINEAR_SEL      equ $-GDT_BASE        ; Selector [0x8]
+        dw 0FFFFh       ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 092h         ; present, ring 0, data, expand-up, writable
+        db 0CFh                 ; page-granular, 32-bit
+        db 0
+
+; linear code segment descriptor
+LINEAR_CODE_SEL equ $-GDT_BASE        ; Selector [0x10]
+        dw 0FFFFh       ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 09Fh         ; present, ring 0, data, expand-up, writable
+        db 0CFh                 ; page-granular, 32-bit
+        db 0
+
+; system data segment descriptor
+SYS_DATA_SEL    equ $-GDT_BASE        ; Selector [0x18]
+        dw 0FFFFh       ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 093h         ; present, ring 0, data, expand-up, writable
+        db 0CFh                 ; page-granular, 32-bit
+        db 0
+
+; system code segment descriptor
+SYS_CODE_SEL    equ $-GDT_BASE        ; Selector [0x20]
+        dw 0FFFFh       ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 09Ah         ; present, ring 0, data, expand-up, writable
+        db 0CFh                 ; page-granular, 32-bit
+        db 0
+
+; spare segment descriptor
+SPARE3_SEL  equ $-GDT_BASE            ; Selector [0x28]
+        dw 0            ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 0            ; present, ring 0, data, expand-up, writable
+        db 0            ; page-granular, 32-bit
+        db 0
+
+;
+; system data segment descriptor
+;
+SYS_DATA64_SEL    equ $-GDT_BASE          ; Selector [0x30]
+        dw 0FFFFh       ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 092h         ; P | DPL [1..2] | 1   | 1   | C | R | A
+        db 0CFh         ; G | D   | L    | AVL | Segment [19..16]
+        db 0
+
+;
+; system code segment descriptor
+;
+SYS_CODE64_SEL    equ $-GDT_BASE          ; Selector [0x38]
+        dw 0FFFFh       ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 09Ah         ; P | DPL [1..2] | 1   | 1   | C | R | A
+        db 0AFh         ; G | D   | L    | AVL | Segment [19..16]
+        db 0
+
+; spare segment descriptor
+SPARE4_SEL  equ $-GDT_BASE            ; Selector [0x40]
+        dw 0            ; limit 0xFFFFF
+        dw 0            ; base 0
+        db 0
+        db 0            ; present, ring 0, data, expand-up, writable
+        db 0            ; page-granular, 32-bit
+        db 0
+
+GDT_END:
+
+;
+;
+;------------------------------------------------------------------------------
+;  Generic IDT Vector Handlers for the Host. They are all the same so they
+;  will compress really well.
+;
+;  By knowing the return address for Vector 00 you can can calculate the
+;  vector number by looking at the call CommonInterruptEntry return address.
+;  (return address - AsmIdtVector00Base)/8 == IDT index
+;
+;------------------------------------------------------------------------------
+
+_AsmIdtVector00 PROC NEAR PUBLIC
+    call  CommonInterruptEntry
+_AsmIdtVector00 ENDP
+AsmIdtVector00Base PROC NEAR PUBLIC
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+    call  CommonInterruptEntry
+	nop
+	nop
+	nop
+AsmIdtVector00Base ENDP
+
+
+;---------------------------------------;
+; CommonInterruptEntry                  ;
+;---------------------------------------;
+; The follow algorithm is used for the common interrupt routine.
+; TBD: Save EFI_SYSTEM_CONTEXT_x64 on the stack per AP definition
+;
+;
+CommonInterruptEntry PROC NEAR PUBLIC
+  cli
+  jmp   $  
+  iret
+
+CommonInterruptEntry ENDP
+
+END
+
diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/x64/VirtualMemory.c b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/VirtualMemory.c
new file mode 100644
index 0000000..40eaed2
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/VirtualMemory.c
@@ -0,0 +1,434 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  VirtualMemory.c

+  

+Abstract:

+

+  x64 Virtual Memory Management Services in the form of an IA-32 driver.  

+  Used to establish a 1:1 Virtual to Physical Mapping that is required to

+  enter Long Mode (x64 64-bit mode).

+

+  While we make a 1:1 mapping (identity mapping) for all physical pages 

+  we still need to use the MTRR's to ensure that the cachability attirbutes

+  for all memory regions is correct.

+

+  The basic idea is to use 2MB page table entries where ever possible. If

+  more granularity of cachability is required then 4K page tables are used.

+

+  References:

+    1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel

+    2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel

+    3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel

+  

+--*/  

+

+#include "VirtualMemory.h"

+

+x64_MTRR_VARIABLE_RANGE     *mMTRRVariableRange;

+x64_MTRR_FIXED_RANGE        mMTRRFixedRange;

+

+

+//

+// Physial memory limit values for each of the 11 fixed MTRRs

+//

+UINTN mFixedRangeLimit[] = {

+  0x7FFFF,  // Fixed MTRR  #0 describes 0x00000..0x7FFFF

+  0x9FFFF,  // Fixed MTRR  #1 describes 0x80000..0x9FFFF

+  0xBFFFF,  // Fixed MTRR  #2 describes 0xA0000..0xBFFFF

+  0xC7FFF,  // Fixed MTRR  #3 describes 0xC0000..0xC7FFF

+  0xCFFFF,  // Fixed MTRR  #4 describes 0xC8000..0xCFFFF

+  0xD7FFF,  // Fixed MTRR  #5 describes 0xD0000..0xD7FFF

+  0xDFFFF,  // Fixed MTRR  #6 describes 0xD8000..0xDFFFF

+  0xE7FFF,  // Fixed MTRR  #7 describes 0xE0000..0xE7FFF

+  0xEFFFF,  // Fixed MTRR  #8 describes 0xE8000..0xEFFFF

+  0xF7FFF,  // Fixed MTRR  #9 describes 0xF0000..0xF7FFF

+  0xFFFFF   // Fixed MTRR #10 describes 0xF8000..0xFFFFF

+};

+

+//

+// The size, in bits, of each of the 11 fixed MTRR.

+//

+UINTN mFixedRangeShift[] = {

+  16,   // Fixed MTRR  #0 describes 8, 64 KB ranges

+  14,   // Fixed MTRR  #1 describes 8, 16 KB ranges

+  14,   // Fixed MTRR  #2 describes 8, 16 KB ranges

+  12,   // Fixed MTRR  #3 describes 8, 4 KB ranges

+  12,   // Fixed MTRR  #4 describes 8, 4 KB ranges

+  12,   // Fixed MTRR  #5 describes 8, 4 KB ranges

+  12,   // Fixed MTRR  #6 describes 8, 4 KB ranges

+  12,   // Fixed MTRR  #7 describes 8, 4 KB ranges

+  12,   // Fixed MTRR  #8 describes 8, 4 KB ranges

+  12,   // Fixed MTRR  #9 describes 8, 4 KB ranges

+  12    // Fixed MTRR #10 describes 8, 4 KB ranges

+};

+

+

+UINTN mPowerOf2[] = {

+  1,

+  2,

+  4,

+  8,

+  16,

+  32,

+  64,

+  128,

+  256,

+  512

+};

+

+x64_MTRR_MEMORY_TYPE

+EfiGetMTRRMemoryType (

+  IN  EFI_PHYSICAL_ADDRESS      Address

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the memory type from the MTRR that describes a physical address.

+

+Arguments:

+

+  VariableRange - Set of Variable MTRRs

+

+  FixedRange    - Set of Fixed MTRRs

+

+  Address       - The physical address for which the MTRR memory type is being retrieved

+

+Returns:

+

+  The MTRR Memory Type for the physical memory specified by Address.

+

+--*/

+{

+  UINTN                   Index;

+  UINTN                   TypeIndex;

+  BOOLEAN                 Found;

+  x64_MTRR_MEMORY_TYPE  VariableType;

+  EFI_PHYSICAL_ADDRESS    MaskBase;

+  EFI_PHYSICAL_ADDRESS    PhysMask;

+

+  //

+  // If the MTRRs are disabled, then return the Uncached Memory Type

+  //

+  if (mMTRRFixedRange.DefaultType.Bits.E == 0) {

+    return Uncached;

+  }

+

+  //

+  // If the CPU supports Fixed MTRRs and the Fixed MTRRs are enabled, then 

+  // see if Address falls into one of the Fixed MTRRs

+  //

+  if (mMTRRFixedRange.Capabilities.Bits.FIX && mMTRRFixedRange.DefaultType.Bits.FE) {

+    //

+    // Loop though 11 fixed MTRRs

+    //

+    for (Index = 0; Index < 11; Index++) {

+      //

+      // Check for a matching range

+      //

+      if (Address <= mFixedRangeLimit[Index]) {

+        //

+        // Compute the offset address into the MTRR bu subtrating the base address of the MTRR

+        //

+        if (Index > 0) {

+          Address = Address - (mFixedRangeLimit[Index-1] + 1);

+        }

+        //

+        // Retrieve the index into the MTRR to extract the memory type.  The range is 0..7

+        //

+        TypeIndex = (UINTN)RShiftU64 (Address, mFixedRangeShift[Index]);

+        

+        //

+        // Retrieve and return the memory type for the matching range

+        //

+        return mMTRRFixedRange.Fixed[Index].Type[TypeIndex];

+      }

+    }

+  }

+

+  //

+  // If Address was not found in a Fixed MTRR, then search the Variable MTRRs

+  //

+  for (Index = 0, Found = FALSE, VariableType = WriteBack; Index < mMTRRFixedRange.Capabilities.Bits.VCNT; Index++) {

+    //

+    // BugBug: __aullshr complier error

+    //

+    if ((mMTRRVariableRange[Index].PhysMask.Uint64 & 0x800) == 0x800) {    

+    //if (mMTRRVariableRange[Index].PhysMask.Bits.Valid == 1) {

+      PhysMask = mMTRRVariableRange[Index].PhysMask.Uint64 & ~0xfff;

+      MaskBase = PhysMask & (mMTRRVariableRange[Index].PhysBase.Uint64 & ~0xfff);

+      if (MaskBase == (PhysMask & Address)) {

+        //

+        // Check to see how many matches we find

+        //

+        Found = TRUE;

+        if ((mMTRRVariableRange[Index].PhysBase.Bits.Type == Uncached) || (VariableType == Uncached)) {

+          //

+          // If any matching region uses UC, the memory region is UC

+          //

+          VariableType = Uncached;

+        } else if ((mMTRRVariableRange[Index].PhysBase.Bits.Type == WriteThrough) || (VariableType == WriteThrough)){

+          //

+          // If it's WT and WB then set it to WT. If it's WT and other type it's undefined

+          //

+          VariableType = WriteThrough;

+        } else {

+          VariableType = mMTRRVariableRange[Index].PhysBase.Bits.Type;

+        }

+      }

+    }

+  }

+  

+  if (Found) {

+    return VariableType;

+  }

+

+  //

+  // Address was not found in the Fixed or Variable MTRRs, so return the default memory type

+  //

+  return mMTRRFixedRange.DefaultType.Bits.Type;

+}

+

+

+BOOLEAN

+CanNotUse2MBPage (

+  IN  EFI_PHYSICAL_ADDRESS  BaseAddress

+  )

+/*++

+

+Routine Description:

+  Test to see if a 2MB aligned page has all the same attributes. If a 2MB page

+  has more than one attibute type it needs to be split into multiple 4K pages.

+

+Arguments:

+  BaseAddress - 2MB aligned address to check out

+

+Returns:

+  TRUE  - This 2MB address range (BaseAddress) can NOT be mapped by a 2MB page

+  FALSE - This 2MB address range can be mapped by a 2MB page

+

+--*/

+{

+  UINTN                   Index;

+  x64_MTRR_MEMORY_TYPE  MemoryType;

+  x64_MTRR_MEMORY_TYPE  PreviousMemoryType;

+  

+  //

+  // Address needs to be 2MB aligned

+  //

+  ASSERT ((BaseAddress & 0x1fffff) == 0);

+

+  PreviousMemoryType = -1;

+  for (Index = 0; Index < 512; Index++, BaseAddress += 0x1000) {

+    MemoryType = EfiGetMTRRMemoryType (BaseAddress);

+    if ((Index != 0) && (MemoryType != PreviousMemoryType)) {

+      return TRUE;

+    }

+

+    PreviousMemoryType = MemoryType;

+  }

+

+  //

+  // All the pages had the same type

+  //

+  return FALSE;

+}

+

+

+

+

+VOID

+Convert2MBPageTo4KPages (  

+  IN  x64_PAGE_TABLE_ENTRY_2M   *PageDirectoryEntry2MB, 

+  IN  EFI_PHYSICAL_ADDRESS        PageAddress

+  )

+/*++

+

+Routine Description:

+ Convert a single 2MB page entry to 512 4K page entries. The attributes for 

+ the 4K pages are read from the MTRR registers.

+

+Arguments:

+  PageDirectoryEntry2MB - Page directory entry for PageAddress

+  PageAddress           - 2MB algined address of region to convert

+

+Returns:

+  None

+

+--*/

+{

+  EFI_PHYSICAL_ADDRESS                          Address;

+  x64_PAGE_DIRECTORY_ENTRY_4K                   *PageDirectoryEntry4k;

+  x64_PAGE_TABLE_ENTRY_4K                       *PageTableEntry;

+  UINTN                                         Index1;

+

+  //

+  // Allocate the page table entry for the 4K pages

+  //

+  PageTableEntry = (x64_PAGE_TABLE_ENTRY_4K *) AllocatePages (1);

+

+  ASSERT (PageTableEntry != NULL);

+

+  //

+  // Convert PageDirectoryEntry2MB into a 4K Page Directory

+  //

+  PageDirectoryEntry4k = (x64_PAGE_DIRECTORY_ENTRY_4K *)PageDirectoryEntry2MB;

+  PageDirectoryEntry2MB->Uint64 = (UINT64)PageTableEntry;

+  PageDirectoryEntry2MB->Bits.ReadWrite = 1;

+  PageDirectoryEntry2MB->Bits.Present = 1;

+  

+  //

+  // Fill in the 4K page entries with the attributes from the MTRRs

+  //

+  for (Index1 = 0, Address = PageAddress; Index1 < 512; Index1++, PageTableEntry++, Address += 0x1000) {

+    PageTableEntry->Uint64 = (UINT64)Address;

+    PageTableEntry->Bits.ReadWrite = 1;

+    PageTableEntry->Bits.Present = 1;

+  }

+}

+

+

+EFI_PHYSICAL_ADDRESS

+CreateIdentityMappingPageTables (

+  IN UINT32                NumberOfProcessorPhysicalAddressBits

+  )

+/*++

+

+Routine Description:

+

+  Allocates and fills in the Page Directory and Page Table Entries to

+  establish a 1:1 Virtual to Physical mapping for physical memory from

+  0 to 4GB.  Memory above 4GB is not mapped.  The MTRRs are used to 

+  determine the cachability of the physical memory regions

+

+Arguments:

+

+  NumberOfProcessorPhysicalAddressBits - Number of processor address bits to use.

+                                         Limits the number of page table entries 

+                                         to the physical address space.

+

+Returns:

+  EFI_OUT_OF_RESOURCES  There are not enough resources to allocate the Page Tables

+

+  EFI_SUCCESS           The 1:1 Virtual to Physical identity mapping was created

+

+--*/

+{  

+  EFI_PHYSICAL_ADDRESS                          PageAddress;

+  UINTN                                         Index;

+  UINTN                                         MaxBitsSupported;

+  UINTN                                         Index1;

+  UINTN                                         Index2;

+  x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageMapLevel4Entry;

+  x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageMap;

+  x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K     *PageDirectoryPointerEntry;

+  x64_PAGE_TABLE_ENTRY_2M                       *PageDirectoryEntry2MB;

+

+

+  //

+  //  Page Table structure 4 level 4K, 3 level 2MB.

+  //

+  //                   PageMapLevel4Entry        : bits 47-39

+  //                   PageDirectoryPointerEntry : bits 38-30

+  //  Page Table 2MB : PageDirectoryEntry2M      : bits 29-21

+  //  Page Table 4K  : PageDirectoryEntry4K      : bits 29 - 21

+  //                   PageTableEntry            : bits 20 - 12

+  //

+  // Strategy is to map every thing in the processor address space using 

+  //  2MB pages. If more  granularity is required the 2MB page will get 

+  //  converted to set of 4K pages. 

+  //

+

+  //

+  // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.

+  //

+  PageMap = PageMapLevel4Entry = (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *) AllocatePages (1);

+  ASSERT (PageMap != NULL);

+  PageAddress = 0;

+

+  //

+  // The number of page-map Level-4 Offset entries is based on the number of 

+  // physical address bits. Less than equal to 38 bits only takes one entry.

+  // 512 entries represents 48 address bits. 

+  //

+  if (NumberOfProcessorPhysicalAddressBits <= 38) {

+    MaxBitsSupported = 1;

+  } else {

+    MaxBitsSupported = mPowerOf2[NumberOfProcessorPhysicalAddressBits - 39];

+  }

+

+  for (Index = 0; Index < MaxBitsSupported; Index++, PageMapLevel4Entry++) {

+    //

+    // Each PML4 entry points to a page of Page Directory Pointer entires.

+    //  So lets allocate space for them and fill them in in the Index1 loop.

+    //  

+    PageDirectoryPointerEntry = (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *) AllocatePages (1);

+    ASSERT (PageDirectoryPointerEntry != NULL);

+

+    //

+    // Make a PML4 Entry

+    //

+    PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;

+    PageMapLevel4Entry->Bits.ReadWrite = 1;

+    PageMapLevel4Entry->Bits.Present = 1;

+

+    for (Index1 = 0; Index1 < 512; Index1++, PageDirectoryPointerEntry++) {

+      //

+      // Each Directory Pointer entries points to a page of Page Directory entires.

+      //  So lets allocate space for them and fill them in in the Index2 loop.

+      //       

+      PageDirectoryEntry2MB = (x64_PAGE_TABLE_ENTRY_2M *) AllocatePages (1);

+      ASSERT (PageDirectoryEntry2MB != NULL);

+

+      //

+      // Fill in a Page Directory Pointer Entries

+      //

+      PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry2MB;

+      PageDirectoryPointerEntry->Bits.ReadWrite = 1;

+      PageDirectoryPointerEntry->Bits.Present = 1;

+

+      for (Index2 = 0; Index2 < 512; Index2++, PageDirectoryEntry2MB++, PageAddress += 0x200000) {

+        //

+        // Fill in the Page Directory entries

+        //

+        PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress;

+        PageDirectoryEntry2MB->Bits.ReadWrite = 1;

+        PageDirectoryEntry2MB->Bits.Present = 1;

+        PageDirectoryEntry2MB->Bits.MustBe1 = 1;

+

+        if (CanNotUse2MBPage (PageAddress)) {

+          //

+          // Check to see if all 2MB has the same mapping. If not convert

+          //  to 4K pages by adding the 4th level of page table entries

+          //

+          Convert2MBPageTo4KPages (PageDirectoryEntry2MB, PageAddress);

+        }

+      }

+    }

+  }

+

+  //

+  // For the PML4 entries we are not using fill in a null entry.

+  //  for now we just copy the first entry.

+  //

+  for (; Index < 512; Index++, PageMapLevel4Entry++) {

+  //    EfiCopyMem (PageMapLevel4Entry, PageMap, sizeof (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K));

+     CopyMem (PageMapLevel4Entry,

+              PageMap,

+              sizeof (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K)

+              );

+  }

+

+  return (EFI_PHYSICAL_ADDRESS)PageMap;

+}

+

diff --git a/edk2/EdkModulePkg/Core/DxeIplPeim/x64/VirtualMemory.h b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/VirtualMemory.h
new file mode 100644
index 0000000..8133ad4
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/DxeIplPeim/x64/VirtualMemory.h
@@ -0,0 +1,239 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  VirtualMemory.h

+  

+Abstract:

+

+  x64 Long Mode Virtual Memory Management Definitions  

+

+  References:

+    1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel

+    2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel

+    3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel

+    4) AMD64 Architecture Programmer's Manual Volume 2: System Programming

+--*/  

+#ifndef _VIRTUAL_MEMORY_H_

+#define _VIRTUAL_MEMORY_H_

+

+

+#pragma pack(1)

+

+//

+// Page-Map Level-4 Offset (PML4) and

+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB

+//

+

+typedef union {

+  struct {

+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory

+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write

+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User

+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching

+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached

+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)

+    UINT64  Reserved:1;               // Reserved

+    UINT64  MustBeZero:2;             // Must Be Zero

+    UINT64  Available:3;              // Available for use by system software

+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address

+    UINT64  AvabilableHigh:11;        // Available for use by system software

+    UINT64  Nx:1;                     // No Execute bit

+  } Bits;

+  UINT64    Uint64;

+} x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K;

+

+//

+// Page-Directory Offset 4K

+//

+typedef union {

+  struct {

+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory

+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write

+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User

+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching

+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached

+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)

+    UINT64  Reserved:1;               // Reserved

+    UINT64  MustBeZero:1;             // Must Be Zero

+    UINT64  Reserved2:1;              // Reserved

+    UINT64  Available:3;              // Available for use by system software

+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address

+    UINT64  AvabilableHigh:11;        // Available for use by system software

+    UINT64  Nx:1;                     // No Execute bit

+  } Bits;

+  UINT64    Uint64;

+} x64_PAGE_DIRECTORY_ENTRY_4K;

+

+//

+// Page Table Entry 4K

+//

+typedef union {

+  struct {

+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory

+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write

+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User

+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching

+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached

+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)

+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page

+    UINT64  PAT:1;                    // 0 = Ignore Page Attribute Table 

+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write

+    UINT64  Available:3;              // Available for use by system software

+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address

+    UINT64  AvabilableHigh:11;        // Available for use by system software

+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution

+  } Bits;

+  UINT64    Uint64;

+} x64_PAGE_TABLE_ENTRY_4K;

+

+

+//

+// Page Table Entry 2MB

+//

+typedef union {

+  struct {

+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory

+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write

+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User

+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching

+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached

+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)

+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page

+    UINT64  MustBe1:1;                // Must be 1 

+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write

+    UINT64  Available:3;              // Available for use by system software

+    UINT64  PAT:1;                    //

+    UINT64  MustBeZero:8;             // Must be zero;

+    UINT64  PageTableBaseAddress:31;  // Page Table Base Address

+    UINT64  AvabilableHigh:11;        // Available for use by system software

+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution

+  } Bits;

+  UINT64    Uint64;

+} x64_PAGE_TABLE_ENTRY_2M;

+

+typedef union {

+  UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory

+  UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write

+  UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User

+  UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching

+  UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached

+  UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)

+  UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page

+  UINT64  Reserved:57;

+} x64_PAGE_TABLE_ENTRY_COMMON;

+

+typedef union {

+  x64_PAGE_TABLE_ENTRY_4K     Page4k;

+  x64_PAGE_TABLE_ENTRY_2M     Page2Mb;

+  x64_PAGE_TABLE_ENTRY_COMMON Common;

+} x64_PAGE_TABLE_ENTRY;

+

+//

+// MTRR Definitions

+//

+typedef enum {

+  Uncached       = 0,

+  WriteCombining = 1,

+  WriteThrough   = 4,

+  WriteProtected = 5,

+  WriteBack      = 6

+} x64_MTRR_MEMORY_TYPE;

+

+typedef union {

+  struct {

+    UINT32  VCNT:8;         // The number of Variable Range MTRRs

+    UINT32  FIX:1;          // 1=Fixed Range MTRRs supported.  0=Fixed Range MTRRs not supported

+    UINT32  Reserved_0;     // Reserved

+    UINT32  WC:1;           // Write combining memory type supported

+    UINT32  Reserved_1:21;  // Reserved

+    UINT32  Reserved_2:32;  // Reserved

+  } Bits;

+  UINT64  Uint64;

+} x64_MTRRCAP_MSR;

+

+typedef union {

+  struct {

+    UINT32  Type:8;         // Default Memory Type

+    UINT32  Reserved_0:2;   // Reserved

+    UINT32  FE:1;           // 1=Fixed Range MTRRs enabled.  0=Fixed Range MTRRs disabled

+    UINT32  E:1;            // 1=MTRRs enabled, 0=MTRRs disabled

+    UINT32  Reserved_1:20;  // Reserved

+    UINT32  Reserved_2:32;  // Reserved

+  } Bits;

+  UINT64  Uint64;

+} x64_MTRR_DEF_TYPE_MSR;

+

+typedef union {

+  UINT8   Type[8];          // The 8 Memory Type values in the 64-bit MTRR

+  UINT64  Uint64;           // The full 64-bit MSR

+} x64_MTRR_FIXED_RANGE_MSR;

+

+typedef struct {

+  x64_MTRRCAP_MSR           Capabilities;   // MTRR Capabilities MSR value

+  x64_MTRR_DEF_TYPE_MSR     DefaultType;    // Default Memory Type MSR Value

+  x64_MTRR_FIXED_RANGE_MSR  Fixed[11];      // The 11 Fixed MTRR MSR Values

+} x64_MTRR_FIXED_RANGE;

+

+

+typedef union {

+  struct {

+    UINT64  Type:8;         // Memory Type

+    UINT64  Reserved0:4;    // Reserved

+    UINT64  PhysBase:40;    // The physical base address(bits 35..12) of the MTRR

+    UINT64  Reserved1:12 ;  // Reserved

+  } Bits;

+  UINT64  Uint64;

+} x64_MTRR_PHYSBASE_MSR;

+

+typedef union {

+  struct {

+    UINT64  Reserved0:11;  // Reserved

+    UINT64  Valid:1;        // 1=MTRR is valid, 0=MTRR is not valid

+    UINT64  PhysMask:40;    // The physical address mask (bits 35..12) of the MTRR

+    UINT64  Reserved1:12;  // Reserved

+  } Bits;

+  UINT64  Uint64;

+} x64_MTRR_PHYSMASK_MSR;

+

+typedef struct {

+  x64_MTRR_PHYSBASE_MSR  PhysBase;  // Variable MTRR Physical Base MSR

+  x64_MTRR_PHYSMASK_MSR  PhysMask;  // Variable MTRR Physical Mask MSR

+} x64_MTRR_VARIABLE_RANGE;

+

+#pragma pack()

+

+x64_MTRR_MEMORY_TYPE

+EfiGetMTRRMemoryType (

+  IN  EFI_PHYSICAL_ADDRESS      Address

+  )

+;

+

+BOOLEAN

+CanNotUse2MBPage (

+  IN  EFI_PHYSICAL_ADDRESS  BaseAddress

+  )

+;

+

+VOID

+Convert2MBPageTo4KPages (  

+  IN  x64_PAGE_TABLE_ENTRY_2M   *PageDirectoryEntry2MB, 

+  IN  EFI_PHYSICAL_ADDRESS        PageAddress

+  )

+;

+

+EFI_PHYSICAL_ADDRESS

+CreateIdentityMappingPageTables (

+  IN UINT32                NumberOfProcessorPhysicalAddressBits

+  )

+;

+

+#endif 

diff --git a/edk2/EdkModulePkg/Core/Pei/BootMode/BootMode.c b/edk2/EdkModulePkg/Core/Pei/BootMode/BootMode.c
new file mode 100644
index 0000000..049cfd1
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/BootMode/BootMode.c
@@ -0,0 +1,106 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BootMode.c

+

+Abstract:

+

+  EFI PEI Core Boot Mode services

+

+

+

+Revision History

+

+--*/

+

+#include <PeiMain.h>

+

+EFI_STATUS

+EFIAPI

+PeiGetBootMode (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  OUT EFI_BOOT_MODE *BootMode

+  )

+/*++

+

+Routine Description:

+

+  This service enables PEIMs to ascertain the present value of the boot mode.  

+

+Arguments:

+

+  PeiServices    - The PEI core services table.

+  BootMode       - A pointer to contain the value of the boot mode. 

+

+Returns:

+

+  EFI_SUCCESS           - The boot mode was returned successfully.

+  EFI_INVALID_PARAMETER - BootMode is NULL.

+

+--*/

+{

+  PEI_CORE_INSTANCE                    *PrivateData;    

+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;

+

+

+  if (BootMode == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+  

+  HandOffHob  = (PrivateData->HobList.HandoffInformationTable);

+  

+  *BootMode   = HandOffHob->BootMode;

+  

+

+  return EFI_SUCCESS;   

+};

+

+

+EFI_STATUS

+EFIAPI

+PeiSetBootMode (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN EFI_BOOT_MODE     BootMode

+  )

+/*++

+

+Routine Description:

+

+  This service enables PEIMs to update the boot mode variable.    

+

+Arguments:

+

+  PeiServices    - The PEI core services table.

+  BootMode       - The value of the boot mode to set.

+

+Returns:

+

+  EFI_SUCCESS    - The value was successfully updated

+

+--*/

+{

+  PEI_CORE_INSTANCE                    *PrivateData;    

+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;

+

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+  

+  HandOffHob  = (PrivateData->HobList.HandoffInformationTable);

+  

+  HandOffHob->BootMode = BootMode;

+

+

+  return EFI_SUCCESS;   

+};

diff --git a/edk2/EdkModulePkg/Core/Pei/Dependency/dependency.c b/edk2/EdkModulePkg/Core/Pei/Dependency/dependency.c
new file mode 100644
index 0000000..b893cbe
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Dependency/dependency.c
@@ -0,0 +1,264 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  dependency.c

+

+Abstract:

+

+  PEI Dispatcher Dependency Evaluator

+

+  This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine

+  if a driver can be scheduled for execution.  The criteria for

+  schedulability is that the dependency expression is satisfied.

+  

+--*/

+

+#include <PeiMain.h>

+#include "dependency.h"

+

+STATIC

+BOOLEAN

+IsPpiInstalled (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN EVAL_STACK_ENTRY  *Stack

+  )

+/*++

+

+Routine Description:

+

+  This routine determines if a PPI has been installed.

+  The truth value of a GUID is determined by if the PPI has

+  been published and can be queried from the PPI database.

+

+Arguments:

+  PeiServices - The PEI core services table.

+  Stack       - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check

+

+Returns:

+

+  True if the PPI is already installed.

+  False if the PPI has yet to be installed.

+

+--*/

+{

+  VOID        *PeiInstance;

+  EFI_STATUS  Status;

+  EFI_GUID    PpiGuid;

+  

+  //

+  // If there is no GUID to evaluate, just return current result on stack.

+  //

+  if (Stack->Operator == NULL) {

+    return Stack->Result;

+  }

+  

+  //

+  // Copy the Guid into a locale variable so that there are no

+  // possibilities of alignment faults for cross-compilation 

+  // environments such as Intel?Itanium(TM).

+  //

+  CopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));

+

+  //

+  // Check if the PPI is installed.

+  //

+  Status = PeiCoreLocatePpi(

+             &PpiGuid,        // GUID

+             0,               // INSTANCE

+             NULL,            // EFI_PEI_PPI_DESCRIPTOR

+             &PeiInstance     // PPI

+             );

+

+  if (EFI_ERROR(Status)) {

+    return FALSE;

+  }

+   

+  return TRUE;

+}

+

+

+EFI_STATUS

+PeimDispatchReadiness (

+  IN EFI_PEI_SERVICES   **PeiServices,

+  IN VOID               *DependencyExpression,

+  OUT BOOLEAN           *Runnable

+  )

+/*++

+

+Routine Description:

+

+  This is the POSTFIX version of the dependency evaluator.  When a

+  PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on

+  the evaluation stack.  When that entry is poped from the evaluation

+  stack, the PPI is checked if it is installed.  This method allows

+  some time savings as not all PPIs must be checked for certain

+  operation types (AND, OR).

+

+Arguments:

+

+  PeiServices               - Calling context.

+

+  DependencyExpression      - Pointer to a dependency expression.  The Grammar adheres to 

+                              the BNF described above and is stored in postfix notation.

+  Runnable                  - is True if the driver can be scheduled and False if the driver 

+                              cannot be scheduled.  This is the value that the schedulers 

+                              should use for deciding the state of the driver.

+

+Returns:

+

+  Status = EFI_SUCCESS            if it is a well-formed Grammar

+           EFI_INVALID_PARAMETER  if the dependency expression overflows

+                                  the evaluation stack

+           EFI_INVALID_PARAMETER  if the dependency expression underflows

+                                  the evaluation stack

+           EFI_INVALID_PARAMETER  if the dependency expression is not a

+                                  well-formed Grammar.

+--*/

+{

+  EFI_STATUS                     Status;

+  DEPENDENCY_EXPRESSION_OPERAND  *Iterator;

+  EVAL_STACK_ENTRY               *StackPtr;

+  EVAL_STACK_ENTRY               EvalStack[MAX_GRAMMAR_SIZE];

+

+  Status    = EFI_SUCCESS;

+  Iterator  = DependencyExpression;

+  *Runnable = FALSE;

+

+  StackPtr = &EvalStack[0];

+

+  while (TRUE) {

+

+    switch (*(Iterator++)) {

+      

+      //

+      // For performance reason we put the frequently used items in front of 

+      // the rarely used  items

+      //

+      

+      case (EFI_DEP_PUSH):

+        //

+        // Check to make sure the dependency grammar doesn't overflow the

+        // EvalStack on the push

+        //

+        if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        //

+        // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)

+        // We will evaluate if the PPI is insalled on the POP operation.

+        //

+        StackPtr->Operator = (VOID *) Iterator;

+        Iterator = Iterator + sizeof (EFI_GUID);

+        StackPtr++;

+        break;

+

+      case (EFI_DEP_AND):    

+      case (EFI_DEP_OR):     

+        //

+        // Check to make sure the dependency grammar doesn't underflow the

+        // EvalStack on the two POPs for the AND operation.  Don't need to

+        // check for the overflow on PUSHing the result since we already

+        // did two POPs.

+        //

+        if (StackPtr < &EvalStack[2]) {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        //

+        // Evaluate the first POPed operator only. If the operand is

+        // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the

+        // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,

+        // we don't need to check the second operator, and the result will be

+        // evaluation of the POPed operator. Otherwise, don't POP the second

+        // operator since it will now evaluate to the final result on the

+        // next operand that causes a POP.

+        // 

+        StackPtr--;

+        //

+        // Iterator has increased by 1 after we retrieve the operand, so here we 

+        // should get the value pointed by (Iterator - 1), in order to obtain the 

+        // same operand.

+        //

+        if (*(Iterator - 1) == EFI_DEP_AND) {

+          if (!(IsPpiInstalled (PeiServices, StackPtr))) {

+            (StackPtr-1)->Result = FALSE;

+            (StackPtr-1)->Operator = NULL;

+          }

+        } else {

+          if (IsPpiInstalled (PeiServices, StackPtr)) {

+            (StackPtr-1)->Result = TRUE;

+            (StackPtr-1)->Operator = NULL;

+          }

+        }

+        break;

+        

+      case (EFI_DEP_END):

+        StackPtr--;

+        //

+        // Check to make sure EvalStack is balanced.  If not, then there is

+        // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.

+        //

+        if (StackPtr != &EvalStack[0]) {

+          return EFI_INVALID_PARAMETER;

+        }

+        *Runnable = IsPpiInstalled (PeiServices, StackPtr);

+        return EFI_SUCCESS;

+        break;

+

+      case (EFI_DEP_NOT):    

+        //

+        // Check to make sure the dependency grammar doesn't underflow the

+        // EvalStack on the POP for the NOT operation.  Don't need to

+        // check for the overflow on PUSHing the result since we already

+        // did a POP.

+        //

+        if (StackPtr < &EvalStack[1]) {

+          return EFI_INVALID_PARAMETER;

+        }

+        (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));

+        (StackPtr-1)->Operator = NULL;

+        break;

+

+      case (EFI_DEP_TRUE):

+      case (EFI_DEP_FALSE):

+        //

+        // Check to make sure the dependency grammar doesn't overflow the

+        // EvalStack on the push

+        //

+        if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {

+          return EFI_INVALID_PARAMETER;

+        }

+        //

+        // Iterator has increased by 1 after we retrieve the operand, so here we 

+        // should get the value pointed by (Iterator - 1), in order to obtain the 

+        // same operand.

+        //

+        if (*(Iterator - 1) == EFI_DEP_TRUE) {

+          StackPtr->Result = TRUE;

+        } else {

+          StackPtr->Result = FALSE;

+        }

+        StackPtr->Operator = NULL;

+        StackPtr++;

+        break;

+

+      default:

+        //

+        // The grammar should never arrive here

+        //

+        return EFI_INVALID_PARAMETER;

+        break;

+    }

+  }

+}

diff --git a/edk2/EdkModulePkg/Core/Pei/Dependency/dependency.h b/edk2/EdkModulePkg/Core/Pei/Dependency/dependency.h
new file mode 100644
index 0000000..a1a54ed
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Dependency/dependency.h
@@ -0,0 +1,38 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  dependency.h

+

+Abstract:

+   

+  This module contains data specific to dependency expressions

+  and local function prototypes.

+        

+--*/

+

+#ifndef _PEI_DEPENDENCY_H_

+#define _PEI_DEPENDENCY_H_

+

+#define MAX_GRAMMAR_SIZE  256

+

+//

+// type definitions

+//

+typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;

+

+typedef struct {

+  BOOLEAN                 Result;

+  VOID                    *Operator;

+} EVAL_STACK_ENTRY;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/edk2/EdkModulePkg/Core/Pei/Dispatcher/Dispatcher.c
new file mode 100644
index 0000000..b4e09e3
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -0,0 +1,535 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  Dispatcher.c

+

+Abstract:

+

+  EFI PEI Core dispatch services

+

+Revision History

+

+--*/

+

+#include <PeiMain.h>

+

+VOID *

+TransferOldDataToNewDataRange (

+  IN PEI_CORE_INSTANCE        *PrivateData

+  );

+

+EFI_GUID gEfiPeiCorePrivateGuid = EFI_PEI_CORE_PRIVATE_GUID;

+

+

+EFI_STATUS

+PeiDispatcher (

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN PEI_CORE_INSTANCE           *PrivateData,

+  IN PEI_CORE_DISPATCH_DATA      *DispatchData

+  )

+

+/*++

+

+Routine Description:

+

+  Conduct PEIM dispatch.

+

+Arguments:

+

+  PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR

+  PrivateData          - Pointer to the private data passed in from caller

+  DispatchData         - Pointer to PEI_CORE_DISPATCH_DATA data.

+

+Returns:

+

+  EFI_SUCCESS   - Successfully dispatched PEIM.

+  EFI_NOT_FOUND - The dispatch failed.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  PEI_CORE_TEMP_POINTERS            TempPtr;

+  UINTN                             PrivateDataInMem;

+  BOOLEAN                           NextFvFound;

+  EFI_FIRMWARE_VOLUME_HEADER        *NextFvAddress;

+  EFI_FIRMWARE_VOLUME_HEADER        *DefaultFvAddress;

+  //

+  // Debug data for uninstalled Peim list

+  //

+  EFI_GUID                          DebugFoundPeimList[32];

+  REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA   ExtendedData;

+

+  //

+  // save the Current FV Address so that we will not process it again if FindFv returns it later

+  //

+  DefaultFvAddress = DispatchData->BootFvAddress;

+

+  //

+  // This is the main dispatch loop.  It will search known FVs for PEIMs and

+  // attempt to dispatch them.  If any PEIM gets dispatched through a single

+  // pass of the dispatcher, it will start over from the Bfv again to see

+  // if any new PEIMs dependencies got satisfied.  With a well ordered

+  // FV where PEIMs are found in the order their dependencies are also

+  // satisfied, this dipatcher should run only once.

+  //

+  for (;;) {

+    //

+    // This is the PEIM search loop. It will scan through all PEIMs it can find

+    // looking for PEIMs to dispatch, and will dipatch them if they have not

+    // already been dispatched and all of their dependencies are met.

+    // If no more PEIMs can be found in this pass through all known FVs,

+    // then it will break out of this loop.

+    //

+    for (;;) {

+

+      Status = FindNextPeim (

+                 &PrivateData->PS,

+                 DispatchData->CurrentFvAddress,

+                 &DispatchData->CurrentPeimAddress

+                 );

+

+      //

+      // If we found a PEIM, check if it is dispatched.  If so, go to the

+      // next PEIM.  If not, dispatch it if its dependencies are satisfied.

+      // If its dependencies are not satisfied, go to the next PEIM.

+      //

+      if (Status == EFI_SUCCESS) {

+

+        DEBUG_CODE (

+

+          //

+          // Fill list of found Peims for later list of those not installed

+          //

+          CopyMem (

+            &DebugFoundPeimList[DispatchData->CurrentPeim],

+            &DispatchData->CurrentPeimAddress->Name,

+            sizeof (EFI_GUID)

+            );

+

+        );

+

+        if (!Dispatched (

+               DispatchData->CurrentPeim,

+               DispatchData->DispatchedPeimBitMap

+               )) {

+          if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {

+            Status = PeiLoadImage (

+                       &PrivateData->PS,

+                       DispatchData->CurrentPeimAddress,

+                       &TempPtr.Raw

+                       );

+            if (Status == EFI_SUCCESS) {

+

+              //

+              // The PEIM has its dependencies satisfied, and its entry point

+              // has been found, so invoke it.

+              //

+              PERF_START (

+                (VOID *) (UINTN) (DispatchData->CurrentPeimAddress),

+                "PEIM",

+                NULL,

+                0

+                );

+

+              //

+              // BUGBUG: Used to be EFI_PEI_REPORT_STATUS_CODE_CODE

+              //

+              ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;

+

+              REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+                EFI_PROGRESS_CODE,

+                EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,

+                (VOID *)(&ExtendedData),

+                sizeof (ExtendedData)

+                );

+

+              //

+              // Is this a authentic image

+              //

+              Status = VerifyPeim (

+                        &PrivateData->PS,

+                        DispatchData->CurrentPeimAddress

+                        );

+

+              if (Status != EFI_SECURITY_VIOLATION) {

+

+                Status =  TempPtr.PeimEntry (

+                                    DispatchData->CurrentPeimAddress,

+                                    &PrivateData->PS

+                                    );

+              }

+

+              REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+                EFI_PROGRESS_CODE,

+                EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,

+                (VOID *)(&ExtendedData),

+                sizeof (ExtendedData)

+                );

+

+              PERF_END ((VOID *) (UINTN) (DispatchData->CurrentPeimAddress), "PEIM", NULL, 0);

+

+              //

+              // Mark the PEIM as dispatched so we don't attempt to run it again

+              //

+              SetDispatched (

+                &PrivateData->PS,

+                DispatchData->CurrentPeim,

+                &DispatchData->DispatchedPeimBitMap

+                );

+

+              //

+              // Process the Notify list and dispatch any notifies for

+              // newly installed PPIs.

+              //

+              ProcessNotifyList (&PrivateData->PS);

+

+              //

+              // If real system memory was discovered and installed by this

+              // PEIM, switch the stacks to the new memory.  Since we are

+              // at dispatch level, only the Core's private data is preserved,

+              // nobody else should have any data on the stack.

+              //

+              if (PrivateData->SwitchStackSignal) {

+                TempPtr.PeiCore = (PEI_CORE_ENTRY_POINT)PeiCore;

+                PrivateDataInMem = (UINTN) TransferOldDataToNewDataRange (PrivateData);

+                ASSERT (PrivateDataInMem != 0);

+                //

+                //Subtract 0x10 from the 4th parameter indicating the new stack base,

+                //in order to provide buffer protection against possible illegal stack

+                //access that might corrupt the stack.

+                //

+                SwitchStack (

+                  (SWITCH_STACK_ENTRY_POINT)(UINTN)TempPtr.Raw,

+                  PeiStartupDescriptor,

+                  (VOID*)PrivateDataInMem,

+                  (VOID*)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize)

+                );

+              }

+            }

+          }

+        }

+        DispatchData->CurrentPeim++;

+        continue;

+

+      } else {

+

+        //

+        // If we could not find another PEIM in the current FV, go try

+        // the FindFv PPI to look in other FVs for more PEIMs.  If we can

+        // not locate the FindFv PPI, or if the FindFv PPI can not find

+        // anymore FVs, then exit the PEIM search loop.

+        //

+        if (DispatchData->FindFv == NULL) {

+          Status = PeiCoreLocatePpi (

+                     &gEfiFindFvPpiGuid,

+                     0,

+                     NULL,

+                     (VOID **)&DispatchData->FindFv

+                     );

+          if (Status != EFI_SUCCESS) {

+            break;

+          }

+        }

+        NextFvFound = FALSE;

+        while (!NextFvFound) {

+          Status = DispatchData->FindFv->FindFv (

+                                           DispatchData->FindFv,

+                                           &PrivateData->PS,

+                                           &DispatchData->CurrentFv,

+                                           &NextFvAddress

+                                           );

+          //

+          // if there is no next fv, get out of this loop of finding FVs

+          //

+          if (Status != EFI_SUCCESS) {

+            break;

+          }

+          //

+          // don't process the default Fv again. (we don't know the order in which the hobs were created)

+          //

+          if ((NextFvAddress != DefaultFvAddress) &&

+              (NextFvAddress != DispatchData->CurrentFvAddress)) {

+

+            //

+            // VerifyFv() is currently returns SUCCESS all the time, add code to it to

+            // actually verify the given FV

+            //

+            Status = VerifyFv (NextFvAddress);

+            if (Status == EFI_SUCCESS) {

+              NextFvFound = TRUE;

+              DispatchData->CurrentFvAddress = NextFvAddress;

+              DispatchData->CurrentPeimAddress = NULL;

+              //

+              // current PRIM number (CurrentPeim) must continue as is, don't reset it here

+              //

+            }

+          }

+        }

+        //

+        // if there is no next fv, get out of this loop of dispatching PEIMs

+        //

+        if (!NextFvFound) {

+          break;

+        }

+        //

+        // continue in the inner for(;;) loop with a new FV;

+        //

+      }

+    }

+

+    //

+    // If all the PEIMs that we have found have been dispatched, then

+    // there is nothing left to dispatch and we don't need to go search

+    // through all PEIMs again.

+    //

+    if ((~(DispatchData->DispatchedPeimBitMap) &

+         ((1 << DispatchData->CurrentPeim)-1)) == 0) {

+      break;

+    }

+

+    //

+    // Check if no more PEIMs that depex was satisfied

+    //

+    if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {

+      break;

+    }

+

+    //

+    // Case when Depex is not satisfied and has to traverse the list again

+    //

+    DispatchData->CurrentPeim = 0;

+    DispatchData->CurrentPeimAddress = 0;

+    DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;

+

+    //

+    // don't go back to the loop without making sure that the CurrentFvAddress is the

+    // same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and

+    // mess it up, always start processing the PEIMs from the default FV just like in the first time around.

+    //

+    DispatchData->CurrentFv = 0;

+    DispatchData->CurrentFvAddress = DefaultFvAddress;

+  }

+

+  DEBUG_CODE (

+    //

+    // Debug data for uninstalled Peim list

+    //

+    UINT32        DebugNotDispatchedBitmap;

+    UINT8         DebugFoundPeimPoint;

+

+    DebugFoundPeimPoint = 0;

+    //

+    // Get bitmap of Peims that were not dispatched,

+    //

+

+    DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ ((1 << DispatchData->CurrentPeim)-1));

+    //

+    // Scan bitmap of Peims not installed and print GUIDS

+    //

+    while (DebugNotDispatchedBitmap != 0) {

+      if ((DebugNotDispatchedBitmap & 1) != 0) {

+        DEBUG ((EFI_D_INFO, "WARNING -> InstallPpi: Not Installed: %g\n",

+           &DebugFoundPeimList[DebugFoundPeimPoint]

+           ));

+      }

+      DebugFoundPeimPoint++;

+      DebugNotDispatchedBitmap >>= 1;

+    }

+

+  );

+

+   return EFI_NOT_FOUND;

+}

+

+VOID

+InitializeDispatcherData (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN PEI_CORE_INSTANCE            *OldCoreData,

+  IN EFI_PEI_STARTUP_DESCRIPTOR   *PeiStartupDescriptor

+  )

+/*++

+

+Routine Description:

+

+  Initialize the Dispatcher's data members

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  OldCoreData          - Pointer to old core data (before switching stack).

+                         NULL if being run in non-permament memory mode.

+  PeiStartupDescriptor - Information and services provided by SEC phase.

+

+Returns:

+

+  None.

+

+--*/

+{

+  PEI_CORE_INSTANCE *PrivateData;

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);

+

+  if (OldCoreData == NULL) {

+    PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;

+    PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;

+  } else {

+

+    //

+    // Current peim has been dispatched, but not count

+    //

+    PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);

+  }

+

+  return;

+}

+

+

+BOOLEAN

+Dispatched (

+  IN UINT8  CurrentPeim,

+  IN UINT32 DispatchedPeimBitMap

+  )

+/*++

+

+Routine Description:

+

+  This routine checks to see if a particular PEIM has been dispatched during

+  the PEI core dispatch.

+

+Arguments:

+  CurrentPeim          - The PEIM/FV in the bit array to check.

+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.

+

+Returns:

+  TRUE  - PEIM already dispatched

+  FALSE - Otherwise

+

+--*/

+{

+  return (BOOLEAN)((DispatchedPeimBitMap & (1 << CurrentPeim)) != 0);

+}

+

+VOID

+SetDispatched (

+  IN EFI_PEI_SERVICES   **PeiServices,

+  IN UINT8              CurrentPeim,

+  OUT UINT32            *DispatchedPeimBitMap

+  )

+/*++

+

+Routine Description:

+

+  This routine sets a PEIM as having been dispatched once its entry

+  point has been invoked.

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  CurrentPeim          - The PEIM/FV in the bit array to check.

+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.

+

+Returns:

+  None

+

+--*/

+{

+  //

+  // Check if the total number of PEIMs exceed the bitmap.

+  // CurrentPeim is 0-based

+  //

+  DEBUG_CODE (

+    if (CurrentPeim > (sizeof (*DispatchedPeimBitMap) * 8 - 1)) {

+      ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);

+    }

+  );

+

+  *DispatchedPeimBitMap |= (1 << CurrentPeim);

+  return;

+}

+

+BOOLEAN

+DepexSatisfied (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN VOID              *CurrentPeimAddress

+  )

+/*++

+

+Routine Description:

+

+  This routine parses the Dependency Expression, if available, and

+  decides if the module can be executed.

+

+Arguments:

+  PeiServices - The PEI Service Table

+  CurrentPeimAddress - Address of the PEIM Firmware File under investigation

+

+Returns:

+  TRUE  - Can be dispatched

+  FALSE - Cannot be dispatched

+

+--*/

+{

+  EFI_STATUS  Status;

+  INT8        *DepexData;

+  BOOLEAN     Runnable;

+

+  Status = PeiCoreFfsFindSectionData (

+             EFI_SECTION_PEI_DEPEX,

+             CurrentPeimAddress,

+             (VOID **)&DepexData

+             );

+  //

+  // If there is no DEPEX, assume the module can be executed

+  //

+  if (EFI_ERROR (Status)) {

+    return TRUE;

+  }

+

+  //

+  // Evaluate a given DEPEX

+  //

+  Status = PeimDispatchReadiness (

+            PeiServices,

+            DepexData,

+            &Runnable

+            );

+

+  return Runnable;

+}

+

+

+VOID *

+TransferOldDataToNewDataRange (

+  IN PEI_CORE_INSTANCE        *PrivateData

+  )

+/*++

+

+Routine Description:

+

+  This routine transfers the contents of the pre-permanent memory

+  PEI Core private data to a post-permanent memory data location.

+

+Arguments:

+

+  PrivateData       - Pointer to the current PEI Core private data pre-permanent memory

+

+Returns:

+

+  Pointer to the PrivateData once the private data has been transferred to permanent memory

+

+--*/

+{

+  return BuildGuidDataHob (&gEfiPeiCorePrivateGuid, PrivateData, sizeof (PEI_CORE_INSTANCE));

+}

+

diff --git a/edk2/EdkModulePkg/Core/Pei/FwVol/FwVol.c b/edk2/EdkModulePkg/Core/Pei/FwVol/FwVol.c
new file mode 100644
index 0000000..d034513
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/FwVol/FwVol.c
@@ -0,0 +1,474 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwVol.c

+

+Abstract:

+

+  Pei Core Firmware File System service routines.

+

+--*/

+

+#include <PeiMain.h>

+

+#define GETOCCUPIEDSIZE(ActualSize, Alignment) \

+  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))

+

+STATIC

+EFI_FFS_FILE_STATE

+GetFileState(

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+

+  Returns the highest bit set of the State field

+

+Arguments:

+

+  ErasePolarity   - Erase Polarity  as defined by EFI_FVB_ERASE_POLARITY

+                    in the Attributes field.

+  FfsHeader       - Pointer to FFS File Header.

+

+Returns:

+  Returns the highest bit in the State field

+

+--*/

+{

+  EFI_FFS_FILE_STATE  FileState;

+  EFI_FFS_FILE_STATE  HighestBit;

+

+  FileState = FfsHeader->State;

+

+  if (ErasePolarity != 0) {

+    FileState = (EFI_FFS_FILE_STATE)~FileState;

+  }

+

+  HighestBit = 0x80;

+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {

+    HighestBit >>= 1;

+  }

+

+  return HighestBit;

+} 

+

+STATIC

+UINT8

+CalculateHeaderChecksum (

+  IN EFI_FFS_FILE_HEADER  *FileHeader

+  )

+/*++

+

+Routine Description:

+

+  Calculates the checksum of the header of a file.

+

+Arguments:

+

+  FileHeader       - Pointer to FFS File Header.

+

+Returns:

+  Checksum of the header.

+  

+  The header is zero byte checksum.

+    - Zero means the header is good.

+    - Non-zero means the header is bad.

+    

+  

+Bugbug: For PEI performance reason, we comments this code at this time.

+--*/

+{

+  UINT8   *ptr;

+  UINTN   Index;

+  UINT8   Sum;

+  

+  Sum = 0;

+  ptr = (UINT8 *)FileHeader;

+

+  for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {

+    Sum = (UINT8)(Sum + ptr[Index]);

+    Sum = (UINT8)(Sum + ptr[Index+1]);

+    Sum = (UINT8)(Sum + ptr[Index+2]);

+    Sum = (UINT8)(Sum + ptr[Index+3]);

+  }

+

+  for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {

+    Sum = (UINT8)(Sum + ptr[Index]);

+  }

+  

+  //

+  // State field (since this indicates the different state of file). 

+  //

+  Sum = (UINT8)(Sum - FileHeader->State);

+  //

+  // Checksum field of the file is not part of the header checksum.

+  //

+  Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);

+

+  return Sum;

+}

+

+STATIC

+EFI_STATUS

+PeiFfsFindNextFileEx (

+  IN     EFI_FV_FILETYPE             SearchType,

+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER         **FileHeader,

+  IN     BOOLEAN                     Flag

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching file in the

+    FFS volume as defined by SearchType. The search starts from FileHeader inside

+    the Firmware Volume defined by FwVolHeader.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+    SearchType - Filter to find only files of this type.

+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.

+    FwVolHeader - Pointer to the FV header of the volume to search.

+      This parameter must point to a valid FFS volume.

+    FileHeader  - Pointer to the current file from which to begin searching.

+      This pointer will be updated upon return to reflect the file found.

+    Flag        - Indicator for if this is for PEI Dispath search 

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+{

+  EFI_FFS_FILE_HEADER  *FfsFileHeader;

+  UINT32               FileLength;

+  UINT32               FileOccupiedSize;

+  UINT32               FileOffset;

+  UINT64               FvLength;

+  UINT8                ErasePolarity;

+  UINT8                FileState;

+  

+

+  FvLength = FwVolHeader->FvLength;

+  if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {

+    ErasePolarity = 1;

+  } else {

+    ErasePolarity = 0;

+  }

+  

+  //

+  // If FileHeader is not specified (NULL) start with the first file in the

+  // firmware volume.  Otherwise, start from the FileHeader.

+  //

+  if (*FileHeader == NULL)  {

+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);

+  } else {

+    //

+    // Length is 24 bits wide so mask upper 8 bits

+    // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.

+    //

+    FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;

+    FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);

+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);

+  }

+

+  FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);

+  ASSERT (FileOffset <= 0xFFFFFFFF);

+  

+  while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {

+    //

+    // Get FileState which is the highest bit of the State 

+    //

+    FileState = GetFileState (ErasePolarity, FfsFileHeader);

+

+    switch (FileState) {

+

+    case EFI_FILE_HEADER_INVALID:

+      FileOffset += sizeof(EFI_FFS_FILE_HEADER);

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));

+      break;

+        

+    case EFI_FILE_DATA_VALID:

+    case EFI_FILE_MARKED_FOR_UPDATE:

+       if (CalculateHeaderChecksum (FfsFileHeader) == 0) {

+        FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;

+        FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);

+        if (Flag) {

+          if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || 

+              (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { 

+            

+            *FileHeader = FfsFileHeader;

+        

+        

+            return EFI_SUCCESS;

+          }

+        } else {        

+          if ((SearchType == FfsFileHeader->Type) || 

+              (SearchType == EFI_FV_FILETYPE_ALL)) { 

+          

+            *FileHeader = FfsFileHeader;

+        

+        

+            return EFI_SUCCESS;

+          }

+        }

+

+        FileOffset += FileOccupiedSize; 

+        FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);

+      } else {

+        ASSERT (FALSE);

+        return EFI_NOT_FOUND;

+      }

+      break;

+    

+    case EFI_FILE_DELETED:

+      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;

+      FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);

+      FileOffset += FileOccupiedSize;

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);

+      break;

+

+    default:

+      return EFI_NOT_FOUND;

+

+    } 

+  }

+

+  return EFI_NOT_FOUND;  

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiFfsFindSectionData (

+  IN     EFI_PEI_SERVICES      **PeiServices,

+  IN     EFI_SECTION_TYPE      SectionType,

+  IN     EFI_FFS_FILE_HEADER   *FfsFileHeader,

+  IN OUT VOID                  **SectionData

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching section in the

+    FFS volume.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+    SearchType - Filter to find only sections of this type.

+    FfsFileHeader  - Pointer to the current file to search.

+    SectionData - Pointer to the Section matching SectionType in FfsFileHeader.

+                - NULL if section not found

+

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+{

+  UINT32                        FileSize;

+  EFI_COMMON_SECTION_HEADER     *Section;

+  UINT32                        SectionLength;

+  UINT32                        ParsedLength;

+  

+

+  //

+  // Size is 24 bits wide so mask upper 8 bits. 

+  //    Does not include FfsFileHeader header size

+  // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.

+  //

+  Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);

+  FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;

+  FileSize -= sizeof(EFI_FFS_FILE_HEADER);

+  

+  *SectionData = NULL;

+  ParsedLength = 0;

+  while (ParsedLength < FileSize) {

+    if (Section->Type == SectionType) {

+      *SectionData = (VOID *)(Section + 1);

+

+

+      return EFI_SUCCESS;

+    }

+    //

+    // Size is 24 bits wide so mask upper 8 bits. 

+    // SectionLength is adjusted it is 4 byte aligned.

+    // Go to the next section

+    //

+    SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;

+    SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);

+    ASSERT (SectionLength != 0);

+    ParsedLength += SectionLength;

+    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);

+  }

+  

+  return EFI_NOT_FOUND;

+  

+}

+

+

+EFI_STATUS

+FindNextPeim (

+  IN     EFI_PEI_SERVICES            **PeiServices,

+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER         **PeimFileHeader

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching file in the

+    FFS volume. The search starts from FileHeader inside

+    the Firmware Volume defined by FwVolHeader.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+

+    FwVolHeader - Pointer to the FV header of the volume to search.

+                     This parameter must point to a valid FFS volume.

+                     

+    PeimFileHeader  - Pointer to the current file from which to begin searching.

+                  This pointer will be updated upon return to reflect the file found.

+

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+{

+  return PeiFfsFindNextFileEx ( 

+           0,

+           FwVolHeader,

+           PeimFileHeader,

+           TRUE

+           );

+}

+

+EFI_STATUS

+EFIAPI

+PeiFfsFindNextFile (

+  IN     EFI_PEI_SERVICES            **PeiServices,

+  IN     EFI_FV_FILETYPE             SearchType,

+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER         **FileHeader

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching file in the

+    FFS volume as defined by SearchType. The search starts from FileHeader inside

+    the Firmware Volume defined by FwVolHeader.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+    

+    SearchType - Filter to find only files of this type.

+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.

+      

+    FwVolHeader - Pointer to the FV header of the volume to search.

+      This parameter must point to a valid FFS volume.

+      

+    FileHeader  - Pointer to the current file from which to begin searching.

+      This pointer will be updated upon return to reflect the file found.

+  

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+{

+  return PeiFfsFindNextFileEx ( 

+           SearchType,

+           FwVolHeader,

+           FileHeader,

+           FALSE

+           );

+}

+

+EFI_STATUS 

+EFIAPI

+PeiFvFindNextVolume (

+  IN     EFI_PEI_SERVICES           **PeiServices,

+  IN     UINTN                      Instance,

+  IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader

+  )

+/*++

+

+Routine Description:

+

+  Return the BFV location

+

+  BugBug -- Move this to the location of this code to where the

+  other FV and FFS support code lives.

+  Also, update to use FindFV for instances #'s >= 1.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  Instance    - Instance of FV to find

+  FwVolHeader - Pointer to contain the data to return

+

+Returns:

+  Pointer to the Firmware Volume instance requested

+

+  EFI_INVALID_PARAMETER     - FwVolHeader is NULL

+  

+  EFI_SUCCESS               - Firmware volume instance successfully found.

+

+--*/

+{

+  PEI_CORE_INSTANCE       *PrivateData;

+  EFI_STATUS              Status;

+  EFI_PEI_FIND_FV_PPI     *FindFvPpi;

+  UINT8                   LocalInstance;

+

+

+  LocalInstance = (UINT8) Instance;

+

+  Status = EFI_SUCCESS;

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  if (FwVolHeader == NULL) {

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Instance == 0) {

+    *FwVolHeader = PrivateData->DispatchData.BootFvAddress;

+

+

+    return Status;

+  } else {

+    //

+    // Locate all instances of FindFV

+    // Alternately, could use FV HOBs, but the PPI is cleaner

+    //

+    Status = PeiCoreLocatePpi (

+               &gEfiFindFvPpiGuid,

+               0,

+               NULL,

+               (VOID **)&FindFvPpi

+               );

+

+    if (Status != EFI_SUCCESS) {

+      Status = EFI_NOT_FOUND;

+    } else {

+      Status = FindFvPpi->FindFv (

+                            FindFvPpi,

+                            PeiServices,

+                            &LocalInstance,

+                            FwVolHeader

+                            );  

+

+    }

+  }

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Core/Pei/Hob/Hob.c b/edk2/EdkModulePkg/Core/Pei/Hob/Hob.c
new file mode 100644
index 0000000..6117827
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Hob/Hob.c
@@ -0,0 +1,189 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Hob.c

+

+Abstract:

+

+  EFI PEI Core HOB services

+

+--*/

+

+#include <PeiMain.h>

+

+EFI_STATUS

+EFIAPI

+PeiGetHobList (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN OUT VOID          **HobList

+  )

+/*++

+

+Routine Description:

+

+  Gets the pointer to the HOB List.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  HobList     - Pointer to the HOB List.

+

+Returns:

+

+  EFI_SUCCESS                 - Get the pointer of HOB List

+  EFI_NOT_AVAILABLE_YET       - the HOB List is not yet published

+  EFI_INVALID_PARAMETER       - HobList is NULL (in debug mode)

+            

+--*/

+{

+  PEI_CORE_INSTANCE *PrivateData;

+

+  

+  //

+  // Only check this parameter in debug mode

+  //

+  

+  DEBUG_CODE (  

+    if (HobList == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+  );

+  

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  *HobList = PrivateData->HobList.Raw;

+

+

+  return EFI_SUCCESS;   

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiCreateHob (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN UINT16            Type,

+  IN UINT16            Length,

+  IN OUT VOID          **Hob

+  )

+/*++

+

+Routine Description:

+

+  Add a new HOB to the HOB List.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  Type        - Type of the new HOB.

+  Length      - Length of the new HOB to allocate.

+  Hob         - Pointer to the new HOB.

+

+Returns:

+

+  Status  - EFI_SUCCESS

+          - EFI_INVALID_PARAMETER if Hob is NULL

+          - EFI_NOT_AVAILABLE_YET if HobList is still not available.

+          - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.

+            

+--*/

+{

+  EFI_STATUS                           Status;

+  EFI_HOB_HANDOFF_INFO_TABLE           *HandOffHob;

+  EFI_HOB_GENERIC_HEADER               *HobEnd;

+  EFI_PHYSICAL_ADDRESS                 FreeMemory;

+

+

+  Status = PeiGetHobList (PeiServices, Hob);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  HandOffHob = *Hob;

+

+  Length = (UINT16)((Length + 0x7) & (~0x7));

+

+  FreeMemory = HandOffHob->EfiFreeMemoryTop -

+               HandOffHob->EfiFreeMemoryBottom;

+

+  if (FreeMemory < Length) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;

+  ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;

+  ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;

+  ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;

+

+  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);

+  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;

+ 

+  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;

+  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);

+  HobEnd->Reserved  = 0;

+  HobEnd++;

+  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;

+

+

+  return EFI_SUCCESS;   

+}

+

+

+EFI_STATUS

+PeiCoreBuildHobHandoffInfoTable (

+  IN EFI_BOOT_MODE         BootMode,

+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,

+  IN UINT64                MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  Builds a Handoff Information Table HOB

+

+Arguments:

+

+  BootMode      - Current Bootmode

+  MemoryBegin   - Start Memory Address.

+  MemoryLength  - Length of Memory.

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  EFI_HOB_HANDOFF_INFO_TABLE   *Hob;

+  EFI_HOB_GENERIC_HEADER              *HobEnd;

+

+  Hob = (VOID *)(UINTN)MemoryBegin;

+  HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);

+  Hob->Header.HobType  = EFI_HOB_TYPE_HANDOFF;

+  Hob->Header.HobLength   = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);

+  Hob->Header.Reserved = 0;

+  

+  HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;

+  HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);

+  HobEnd->Reserved    = 0;

+

+  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;

+  Hob->BootMode            = BootMode;

+  

+  Hob->EfiMemoryTop        = MemoryBegin + MemoryLength;

+  Hob->EfiMemoryBottom     = MemoryBegin;

+  Hob->EfiFreeMemoryTop    = MemoryBegin + MemoryLength;

+  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);

+  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Pei/Image/Image.c b/edk2/EdkModulePkg/Core/Pei/Image/Image.c
new file mode 100644
index 0000000..1580750
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Image/Image.c
@@ -0,0 +1,239 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. 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.             
+
+Module Name:
+
+  Image.c
+
+Abstract:
+
+  Pei Core Load Image Support
+
+--*/
+
+#include <PeiMain.h>
+
+EFI_STATUS
+PeiLoadImage (
+  IN EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_FFS_FILE_HEADER      *PeimFileHeader,
+  OUT VOID                    **EntryPoint
+  )
+/*++
+
+Routine Description:
+
+  Routine for loading file image.
+
+Arguments:
+
+  PeiServices     - The PEI core services table.
+  PeimFileHeader  - Pointer to the FFS file header of the image.
+  EntryPoint      - Pointer to entry point of specified image file for output.
+
+Returns:
+
+  Status - EFI_SUCCESS    - Image is successfully loaded.
+           EFI_NOT_FOUND  - Fail to locate necessary PPI
+           Others         - Fail to load file.
+
+--*/
+{
+  EFI_STATUS                  Status;
+  VOID                        *Pe32Data;
+  EFI_PEI_FV_FILE_LOADER_PPI  *FvLoadFilePpi;
+  EFI_PHYSICAL_ADDRESS        ImageAddress;
+  UINT64                      ImageSize;
+  EFI_PHYSICAL_ADDRESS        ImageEntryPoint;
+  EFI_TE_IMAGE_HEADER         *TEImageHeader;
+
+  *EntryPoint   = NULL;
+  TEImageHeader = NULL;
+
+  //
+  // Try to find a PE32 section.
+  //
+  Status = PeiCoreFfsFindSectionData (
+             EFI_SECTION_PE32,
+             PeimFileHeader,
+             &Pe32Data
+             );
+  //
+  // If we didn't find a PE32 section, try to find a TE section.
+  //
+  if (EFI_ERROR (Status)) {
+    Status = PeiCoreFfsFindSectionData (
+               EFI_SECTION_TE,
+               PeimFileHeader,
+               (VOID **) &TEImageHeader
+               );
+    if (EFI_ERROR (Status) || TEImageHeader == NULL) {
+      //
+      // There was not a PE32 or a TE section, so assume that it's a Compressed section
+      // and use the LoadFile
+      //
+      Status = PeiCoreLocatePpi (
+                &gEfiPeiFvFileLoaderPpiGuid,
+                0,
+                NULL,
+                (VOID **)&FvLoadFilePpi
+                );
+      if (EFI_ERROR (Status)) {
+        return EFI_NOT_FOUND;
+      }
+
+      Status = FvLoadFilePpi->FvLoadFile (
+                                FvLoadFilePpi,
+                                PeimFileHeader,
+                                &ImageAddress,
+                                &ImageSize,
+                                &ImageEntryPoint
+                                );
+
+      if (EFI_ERROR (Status)) {
+        return EFI_NOT_FOUND;
+      }
+
+      //
+      // Retrieve the entry point from the PE/COFF image header
+      //
+      Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)ImageAddress, EntryPoint);
+      if (EFI_ERROR (Status)) {
+        return EFI_NOT_FOUND;
+      }
+    } else {
+      //
+      // Retrieve the entry point from the TE image header
+      //
+      ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;
+      *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+                    TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+    }
+  } else {
+    //
+    // Retrieve the entry point from the PE/COFF image header
+    //
+    ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;
+    Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
+    if (EFI_ERROR (Status)) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  //
+  // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
+  //
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", Pe32Data, *EntryPoint));
+  DEBUG_CODE (
+    EFI_IMAGE_DATA_DIRECTORY * DirectoryEntry;
+    EFI_IMAGE_DEBUG_DIRECTORY_ENTRY * DebugEntry;
+    UINTN DirCount;
+    UINTN Index;
+    UINTN Index1;
+    BOOLEAN FileNameFound;
+    CHAR8 *AsciiString;
+    CHAR8 AsciiBuffer[512];
+    VOID *CodeViewEntryPointer;
+    INTN TEImageAdjust;
+    EFI_IMAGE_DOS_HEADER  *DosHeader;
+    EFI_IMAGE_NT_HEADERS  *PeHeader;
+
+    //
+    // Pe32Data is NULL when load TE image 
+    //    
+    PeHeader = NULL;
+    if (TEImageHeader == NULL) {
+      DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+      if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+        //
+        // DOS image header is present, so read the PE header after the DOS image header
+        //
+        PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));
+      } else {
+        //
+        // DOS image header is not present, so PE header is at the image base
+        //
+        PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+      }
+    }
+
+    //
+    // Find the codeview info in the image and display the file name
+    // being loaded.
+    //
+    // Per the PE/COFF spec, you can't assume that a given data directory
+    // is present in the image. You have to check the NumberOfRvaAndSizes in
+    // the optional header to verify a desired directory entry is there.
+    //
+    DebugEntry      = NULL;
+    DirectoryEntry  = NULL;
+    TEImageAdjust   = 0;
+    if (TEImageHeader == NULL) {
+      if (PeHeader->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHeader->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+        DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);
+      }
+    } else {
+      if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+        DirectoryEntry  = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+        TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;
+        DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +
+                      TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
+                      TEImageAdjust);
+      }
+    }
+
+    if (DebugEntry != NULL && DirectoryEntry != NULL) {
+      for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {
+        if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+          if (DebugEntry->SizeOfData > 0) {
+            CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
+            switch (* (UINT32 *) CodeViewEntryPointer) {
+              case CODEVIEW_SIGNATURE_NB10:
+                AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+                break;
+
+              case CODEVIEW_SIGNATURE_RSDS:
+                AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+                break;
+
+              default:
+                AsciiString = NULL;
+                break;
+            }
+            if (AsciiString != NULL) {
+              FileNameFound = FALSE;
+              for (Index = 0, Index1 = 0; AsciiString[Index] != 0; Index++) {
+                if (AsciiString[Index] == '\\') {
+                  Index1 = Index;
+                  FileNameFound = TRUE;
+                }
+              }
+
+              if (FileNameFound) {
+                for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {
+                  AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];
+                }
+                AsciiBuffer[Index - (Index1 + 1)] = 0;
+                DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  );
+
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/edk2/EdkModulePkg/Core/Pei/Ipf/IpfCpuCore.i b/edk2/EdkModulePkg/Core/Pei/Ipf/IpfCpuCore.i
new file mode 100644
index 0000000..c8a209d
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Ipf/IpfCpuCore.i
@@ -0,0 +1,93 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//  

+//   IpfCpuCore.i

+//

+// Abstract:

+//   IPF CPU definitions

+//

+//--

+

+#ifndef _IPF_CPU_CORE_

+#define _IPF_CPU_CORE_

+

+#define  PEI_BSP_STORE_SIZE                     0x4000

+#define  ResetFn                                0x00

+#define  MachineCheckFn                         0x01

+#define  InitFn                                 0x02

+#define  RecoveryFn                             0x03

+#define  GuardBand                              0x10 

+

+//

+// Define hardware RSE Configuration Register

+//

+

+//

+// RS Configuration (RSC) bit field positions

+//

+#define RSC_MODE       0

+#define RSC_PL         2

+#define RSC_BE         4

+//

+// RSC bits 5-15 reserved

+//

+#define RSC_MBZ0       5

+#define RSC_MBZ0_V     0x3ff

+#define RSC_LOADRS     16

+#define RSC_LOADRS_LEN 14

+//

+// RSC bits 30-63 reserved

+//

+#define RSC_MBZ1       30

+#define RSC_MBZ1_V     0x3ffffffffULL

+

+//

+// RSC modes

+//

+

+//

+// Lazy

+//

+#define RSC_MODE_LY (0x0)

+//

+// Store intensive

+//

+#define RSC_MODE_SI (0x1)

+//

+// Load intensive

+//

+#define RSC_MODE_LI (0x2)

+//

+// Eager

+//

+#define RSC_MODE_EA (0x3)

+

+//

+// RSC Endian bit values

+//

+#define RSC_BE_LITTLE 0

+#define RSC_BE_BIG    1

+

+//

+// RSC while in kernel: enabled, little endian, pl = 0, eager mode

+//

+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))

+//

+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode

+//

+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))

+//

+// RSE disabled: disabled, pl = 0, little endian, eager mode

+//

+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Pei/Ipf/IpfCpuCore.s b/edk2/EdkModulePkg/Core/Pei/Ipf/IpfCpuCore.s
new file mode 100644
index 0000000..d8744b5
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Ipf/IpfCpuCore.s
@@ -0,0 +1,192 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+//  Module Name:

+//

+//    IpfCpuCore.s

+//

+//  Abstract:

+//    IPF Specific assembly routines

+//

+//-- 

+

+.file  "IpfCpuCore.s"

+

+#include  "IpfMacro.i"

+#include  "IpfCpuCore.i"

+

+//----------------------------------------------------------------------------------

+// This module supports terminating CAR (Cache As RAM) stage. It copies all the

+// CAR data into real RAM and then makes a stack switch.

+

+// EFI_STATUS

+// SwitchCoreStacks (

+//   IN VOID  *EntryPoint,

+//   IN UINTN CopySize,

+//   IN VOID  *OldBase,

+//   IN VOID  *NewBase

+//   IN UINTN NewSP, OPTIONAL

+//   IN UINTN NewBSP OPTIONAL

+//   )

+// EFI_STATUS

+// SwitchCoreStacks (

+//   IN VOID  *EntryPointForContinuationFunction,

+//   IN UINTN StartupDescriptor,

+//   IN VOID  PEICorePointer,

+//   IN UINTN NewSP

+//   )

+//----------------------------------------------------------------------------------

+PROCEDURE_ENTRY (SwitchCoreStacks)

+

+        NESTED_SETUP (4,2,0,0)

+

+        // first save all stack registers in GPRs.

+        mov     r13 = in0;;             // this is a pointer to the PLABEL of the continuation function.  

+        ld8     r16 = [r13],8;;         // r16 = address of continuation function from the PLABEL

+        ld8     gp = [r13];;            // gp  = gp of continuation function from the PLABEL

+        mov     b1 = r16;;

+

+        // save the parameters in r5, r6. these 2 seemed to be preserved across PAL calls

+        mov     r5 = in1;;              // this is the parameter1 to pass to the continuation function

+        mov     r6 = in2;;              // this is the parameter2 to pass to the continuation function

+        dep     r6=0,r6,63,1;;          // zero the bit 63.

+

+        mov     r8 = in3;;              // new stack pointer.

+

+        // r8 has the sp, this is 128K stack size, from this we will reserve 16K for the bspstore 

+        movl    r15 = PEI_BSP_STORE_SIZE;;

+        sub     r8 = r8, r15;;

+        add     r15 = (GuardBand),r8;;  // some little buffer, now r15 will be our bspstore

+

+        // save the bspstore value to r4, save sp value to r7

+        mov     r4  = r15

+        mov     r7  = r8

+        mov     r16 = r8;;              // will be the new sp in uncache mode

+      

+

+        alloc   r11=0,0,0,0;;           // Set 0-size frame

+        flushrs;;

+

+        mov     r21 = RSC_KERNEL_DISABLED;; // for rse disable             

+        mov     ar.rsc = r21;;          // turn off RSE                

+

+        add     sp = r0, r16            // transfer to the EFI stack

+        mov     ar.bspstore = r15       // switch to EFI BSP        

+        invala                          // change of ar.bspstore needs invala.     

+      

+        mov     r19 = RSC_KERNEL_LAZ;;  // RSC enabled, Lazy mode

+        mov     ar.rsc = r19;;          // turn rse on, in kernel mode 

+                

+//-----------------------------------------------------------------------------------

+// Save here the meaningful stuff for next few lines and then make the PAL call.

+// Make PAL call to terminate the CAR status.

+        // AVL: do this only for recovery check call...

+

+        mov     r28=ar.k3;;

+        dep     r2 = r28,r0,0,8;;       // Extract Function bits from GR20.

+        cmp.eq  p6,p7 = RecoveryFn,r2;; // Is it Recovery check  

+        (p7)  br.sptk.few DoneCARTermination; // if not, don't terminate car..

+

+TerminateCAR::

+

+        mov     r28 = ip;;

+        add     r28 = (DoneCARTerminationPALCall - TerminateCAR),r28;;

+        mov     b0 = r28

+

+        mov     r8 = ar.k5;;

+        mov     b6 = r8

+        mov     r28 = 0x208

+

+        mov     r29 = r0

+        mov     r30 = r0

+        mov     r31 = r0

+        mov     r8 = r0;;

+        br.sptk.few b6;;                // Call PAL-A call.

+

+DoneCARTerminationPALCall::

+

+// don't check error in soft sdv, it is always returning -1 for this call for some reason

+#if SOFT_SDV

+#else

+ReturnToPEIMain::

+        cmp.eq  p6,p7 = r8,r0;;

+        //

+        // dead loop if the PAL call failed, we have the CAR on but the stack is now pointing to memory

+        //

+        (p7) br.sptk.few ReturnToPEIMain;; 

+        //

+        // PAL call successed,now the stack are in memory so come into cache mode 

+        // instead of uncache mode

+        //

+

+        alloc   r11=0,0,0,0;;           // Set 0-size frame

+        flushrs;;

+     

+        mov     r21 = RSC_KERNEL_DISABLED;; // for rse disable             

+        mov     ar.rsc = r21;;          // turn off RSE                

+    

+        dep     r6 = 0,r6,63,1          // zero the bit 63                               

+        dep     r7 = 0,r7,63,1          // zero the bit 63    

+        dep     r4 = 0,r4,63,1;;        // zero the bit 63   

+        add     sp = r0, r7             // transfer to the EFI stack in cache mode    

+        mov     ar.bspstore = r4        // switch to EFI BSP        

+        invala                          // change of ar.bspstore needs invala.     

+    

+        mov     r19 = RSC_KERNEL_LAZ;;  // RSC enabled, Lazy mode

+        mov     ar.rsc = r19;;          // turn rse on, in kernel mode

+

+#endif

+

+DoneCARTermination::                                                                    

+

+        // allocate a stack frame:                  

+        alloc   r11=0,2,2,0 ;;          // alloc  outs going to ensuing DXE IPL service

+                                                                                                // on the new stack

+        mov     out0 = r5;;

+        mov     out1 = r6;;        

+

+        mov     r16 = b1;;

+        mov     b6 = r16;;

+        br.call.sptk.few b0=b6;;        // Call the continuation function

+

+        NESTED_RETURN

+

+PROCEDURE_EXIT(SwitchCoreStacks)

+//-----------------------------------------------------------------------------------

+

+//---------------------------------------------------------------------------------

+//++

+// GetHandOffStatus

+//

+// This routine is called by all processors simultaneously, to get some hand-off

+// status that has been captured by IPF dispatcher and recorded in kernel registers.

+//

+// Arguments : 

+//

+// On Entry :  None.

+//

+// Return Value: Lid, R20Status.

+// 

+//--

+//----------------------------------------------------------------------------------

+PROCEDURE_ENTRY (GetHandOffStatus)

+        

+        NESTED_SETUP (0,2+0,0,0)

+

+        mov     r8 = ar.k6              // Health Status (Self test params)

+        mov     r9 = ar.k4              // LID bits

+        mov     r10 = ar.k3;;           // SAL_E entry state

+        mov     r11 = ar.k7             // Return address to PAL

+        

+        NESTED_RETURN

+PROCEDURE_EXIT (GetHandOffStatus)

+//----------------------------------------------------------------------------------

+

+

diff --git a/edk2/EdkModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c b/edk2/EdkModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c
new file mode 100644
index 0000000..34018d3
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c
@@ -0,0 +1,76 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SwitchToCacheMode.c

+

+Abstract:

+

+  Ipf CAR specific function used to switch to cache mode for the later memory access

+

+Revision History

+

+--*/

+#include <PeiMain.h>

+#include "IpfCpuCore.i"

+

+extern 

+SAL_RETURN_REGS

+GetHandOffStatus (

+  VOID

+  );

+

+VOID

+SwitchToCacheMode (

+  IN PEI_CORE_INSTANCE           *CoreData

+  )

+/*++

+

+Routine Description:

+

+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.

+

+Arguments:

+

+  CoreData   - The PEI core Private Data

+

+Returns:

+

+--*/

+{

+  EFI_HOB_HANDOFF_INFO_TABLE    *Phit;

+

+  if (CoreData == NULL) {

+    //

+    // the first call with CoreData as NULL.

+    //

+    return;

+  }

+  

+  if ((GetHandOffStatus().r10 & 0xFF) == RecoveryFn) {

+    CoreData->StackBase = CoreData->StackBase &  CACHE_MODE_ADDRESS_MASK;

+    CoreData->HobList.Raw = (UINT8 *)((UINTN)CoreData->HobList.Raw & CACHE_MODE_ADDRESS_MASK);

+

+    //

+    // Change the PHIT pointer value to cache mode

+    //

+    Phit = CoreData->HobList.HandoffInformationTable;

+

+    Phit->EfiMemoryTop        = Phit->EfiMemoryTop & CACHE_MODE_ADDRESS_MASK;

+    Phit->EfiFreeMemoryTop    = Phit->EfiFreeMemoryTop & CACHE_MODE_ADDRESS_MASK;

+    Phit->EfiMemoryBottom     = Phit->EfiMemoryBottom  & CACHE_MODE_ADDRESS_MASK;

+    Phit->EfiFreeMemoryBottom = Phit->EfiFreeMemoryBottom & CACHE_MODE_ADDRESS_MASK;

+    Phit->EfiEndOfHobList     = Phit->EfiEndOfHobList & CACHE_MODE_ADDRESS_MASK;

+  }

+

+  return;

+}
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Core/Pei/Memory/MemoryServices.c b/edk2/EdkModulePkg/Core/Pei/Memory/MemoryServices.c
new file mode 100644
index 0000000..eb99a80
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Memory/MemoryServices.c
@@ -0,0 +1,318 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MemoryServices.c

+

+Abstract:

+

+  EFI PEI Core memory services

+

+--*/

+

+#include <PeiMain.h>

+

+VOID

+InitializeMemoryServices (

+  IN EFI_PEI_SERVICES            **PeiServices,

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN PEI_CORE_INSTANCE           *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Initialize the memory services.

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  PeiStartupDescriptor - Information and services provided by SEC phase.

+  OldCoreData          - Pointer to the PEI Core data.

+                         NULL if being run in non-permament memory mode.

+

+Returns:

+

+  None

+

+--*/

+{

+  PEI_CORE_INSTANCE                    *PrivateData;

+  UINT64                               SizeOfCarHeap;

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);

+  PrivateData->SwitchStackSignal = FALSE;

+

+  if (OldCoreData == NULL) {

+

+    PrivateData->PeiMemoryInstalled = FALSE;

+

+    PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))

+                                   & (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1))); 

+    PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);

+    //

+    // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.

+    //

+    SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;

+    SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);

+ 

+    DEBUG_CODE (

+        PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;

+        PrivateData->MaxTopOfCarHeap  = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);

+    );

+

+    PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;

+    

+    PeiCoreBuildHobHandoffInfoTable (

+      BOOT_WITH_FULL_CONFIGURATION,

+      (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,

+      (UINTN) SizeOfCarHeap

+      );

+    //

+    // Copy PeiServices from ROM to Cache in PrivateData

+    //

+    CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));

+

+    //

+    // Set PS to point to ServiceTableShadow in Cache

+    //

+    PrivateData->PS = &(PrivateData->ServiceTableShadow);

+  } else {

+  //                                                                    

+  // Set PS to point to ServiceTableShadow in Cache one time after the  

+  // stack switched to main memory                                      

+  //                                                                    

+  PrivateData->PS = &(PrivateData->ServiceTableShadow);                 

+}                                                                       

+

+  return;

+}

+

+EFI_STATUS

+EFIAPI

+PeiInstallPeiMemory (

+  IN EFI_PEI_SERVICES      **PeiServices,

+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,

+  IN UINT64                MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  Install the permanent memory is now available.

+  Creates HOB (PHIT and Stack).

+

+Arguments:

+

+  PeiServices   - The PEI core services table.

+  MemoryBegin   - Start of memory address.

+  MemoryLength  - Length of memory.

+

+Returns:

+

+  Status  - EFI_SUCCESS

+            

+--*/

+{

+  PEI_CORE_INSTANCE                     *PrivateData;

+  EFI_HOB_HANDOFF_INFO_TABLE            *OldHandOffHob;

+  EFI_HOB_HANDOFF_INFO_TABLE            *NewHandOffHob;

+  UINT64                                PeiStackSize;

+  UINT64                                EfiFreeMemorySize;

+  EFI_PHYSICAL_ADDRESS                  PhysicalAddressOfOldHob;

+  

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);

+

+  PrivateData->SwitchStackSignal = TRUE;

+  PrivateData->PeiMemoryInstalled = TRUE;

+

+  PrivateData->StackBase = MemoryBegin;

+  

+  PeiStackSize = RShiftU64 (MemoryLength, 1);

+  if (PEI_STACK_SIZE > PeiStackSize) {

+    PrivateData->StackSize = PeiStackSize;

+  } else {

+    PrivateData->StackSize = PEI_STACK_SIZE;

+  }

+

+  OldHandOffHob = PrivateData->HobList.HandoffInformationTable;

+

+  PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));

+  NewHandOffHob = PrivateData->HobList.HandoffInformationTable;

+  PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;

+

+  EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;

+  

+  DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));

+  DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));

+

+  CopyMem (

+    NewHandOffHob,

+    OldHandOffHob,

+    (UINTN)EfiFreeMemorySize

+    );

+

+  NewHandOffHob->EfiMemoryTop     = MemoryBegin + MemoryLength;

+  NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;

+  NewHandOffHob->EfiMemoryBottom  = MemoryBegin;

+  

+  NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;                                     

+                                       

+  NewHandOffHob->EfiEndOfHobList     = (UINTN)NewHandOffHob +

+                                       (OldHandOffHob->EfiEndOfHobList -

+                                        PhysicalAddressOfOldHob);

+

+  ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);

+

+  BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);

+  

+

+  return EFI_SUCCESS;   

+}

+

+EFI_STATUS

+EFIAPI

+PeiAllocatePages (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_MEMORY_TYPE            MemoryType,

+  IN UINTN                      Pages,

+  OUT EFI_PHYSICAL_ADDRESS      *Memory

+  )

+/*++

+

+Routine Description:

+

+  Memory allocation service on permanent memory, 

+  not usable prior to the memory installation.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  MemoryType  - Type of memory to allocate.

+  Pages       - Number of pages to allocate.

+  Memory      - Pointer of memory allocated.

+

+Returns:

+

+  Status - EFI_SUCCESS              The allocation was successful

+           EFI_INVALID_PARAMETER    Only AllocateAnyAddress is supported.

+           EFI_NOT_AVAILABLE_YET    Called with permanent memory not available

+           EFI_OUT_OF_RESOURCES     There is not enough HOB heap to satisfy the requirement

+                                    to allocate the number of pages.

+

+--*/

+{

+  PEI_CORE_INSTANCE                       *PrivateData;

+  EFI_PEI_HOB_POINTERS                    Hob;

+  EFI_PHYSICAL_ADDRESS                    Offset;

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);

+

+  //

+  // Check if Hob already available

+  //

+  if (!PrivateData->PeiMemoryInstalled) {

+    return EFI_NOT_AVAILABLE_YET;

+  }

+

+  Hob.Raw = PrivateData->HobList.Raw;

+

+  //

+  // Check to see if on 4k boundary

+  //

+  Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;

+

+  //

+  // If not aligned, make the allocation aligned.

+  //

+  if (Offset != 0) {

+    Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;

+  }

+

+  //

+  // Verify that there is sufficient memory to satisfy the allocation

+  //

+  if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < 

+      Hob.HandoffInformationTable->EfiFreeMemoryBottom) {

+    return  EFI_OUT_OF_RESOURCES;

+  } else {

+    //

+    // Update the PHIT to reflect the memory usage

+    //

+    Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;

+

+    //

+    // Update the value for the caller

+    //

+    *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;

+

+    //

+    // Create a memory allocation HOB.

+    //

+    BuildMemoryAllocationHob (

+      Hob.HandoffInformationTable->EfiFreeMemoryTop,

+      Pages * EFI_PAGE_SIZE + Offset,

+      MemoryType

+      );

+

+    return EFI_SUCCESS;

+  }

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiAllocatePool (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN UINTN                      Size,

+  OUT VOID                      **Buffer

+  )

+/*++

+

+Routine Description:

+

+  Memory allocation service on the CAR.  

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+

+  Size        - Amount of memory required

+

+  Buffer      - Address of pointer to the buffer

+

+Returns:

+

+  Status - EFI_SUCCESS              The allocation was successful

+           EFI_OUT_OF_RESOURCES     There is not enough heap to satisfy the requirement

+                                    to allocate the requested size.

+                                    

+--*/

+{

+  EFI_STATUS               Status;

+  EFI_HOB_MEMORY_POOL      *Hob;

+

+ //

+ // If some ¡°post-memory¡± PEIM wishes to allocate larger pool,

+ // it should use AllocatePages service instead.

+ //

+ ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));

+ Status = PeiCoreCreateHob (

+             EFI_HOB_TYPE_PEI_MEMORY_POOL,

+             (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),

+             (VOID **)&Hob

+             );

+  *Buffer = Hob+1;  

+

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Core/Pei/PeiMain.h b/edk2/EdkModulePkg/Core/Pei/PeiMain.h
new file mode 100644
index 0000000..9555513
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/PeiMain.h
@@ -0,0 +1,1118 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PeiMain.h

+

+Abstract:

+

+  Definition of Pei Core Structures and Services

+

+Revision History

+

+--*/

+

+#ifndef _PEI_MAIN_H_

+#define _PEI_MAIN_H_

+

+#ifdef EFI64

+#include "SalApi.h"

+#endif

+

+//

+//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range

+//

+#define EFI_PEI_CORE_PRIVATE_GUID  \

+  {0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 } }

+

+//

+// Pei Core private data structures

+//

+typedef union {

+  EFI_PEI_PPI_DESCRIPTOR      *Ppi;

+  EFI_PEI_NOTIFY_DESCRIPTOR   *Notify;

+  VOID                        *Raw;

+} PEI_PPI_LIST_POINTERS;

+

+#define PEI_STACK_SIZE 0x20000

+

+#define MAX_PPI_DESCRIPTORS 64

+

+typedef struct {

+  INTN                    PpiListEnd;

+  INTN                    NotifyListEnd;

+  INTN                    DispatchListEnd;

+  INTN                    LastDispatchedInstall;

+  INTN                    LastDispatchedNotify;

+  PEI_PPI_LIST_POINTERS   PpiListPtrs[MAX_PPI_DESCRIPTORS];

+} PEI_PPI_DATABASE;

+

+typedef struct {

+  UINT8                       CurrentPeim;

+  UINT8                       CurrentFv;

+  UINT32                      DispatchedPeimBitMap;

+  UINT32                      PreviousPeimBitMap;

+  EFI_FFS_FILE_HEADER         *CurrentPeimAddress;

+  EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress;

+  EFI_FIRMWARE_VOLUME_HEADER  *BootFvAddress;

+  EFI_PEI_FIND_FV_PPI         *FindFv;

+} PEI_CORE_DISPATCH_DATA;

+

+

+//

+// Pei Core private data structure instance

+//

+

+#define PEI_CORE_HANDLE_SIGNATURE  EFI_SIGNATURE_32('P','e','i','C')

+

+typedef struct{

+  UINTN                              Signature;

+  EFI_PEI_SERVICES                   *PS;     // Point to ServiceTableShadow

+  PEI_PPI_DATABASE                   PpiData;

+  PEI_CORE_DISPATCH_DATA             DispatchData;

+  EFI_PEI_HOB_POINTERS               HobList;

+  BOOLEAN                            SwitchStackSignal;

+  BOOLEAN                            PeiMemoryInstalled;

+  EFI_PHYSICAL_ADDRESS               StackBase;

+  UINT64                             StackSize;

+  VOID                               *BottomOfCarHeap;

+  VOID                               *TopOfCarHeap;

+  VOID                               *CpuIo;

+  EFI_PEI_SECURITY_PPI               *PrivateSecurityPpi;

+  EFI_PEI_SERVICES                   ServiceTableShadow;

+  UINTN                              SizeOfCacheAsRam;

+  VOID                               *MaxTopOfCarHeap;

+} PEI_CORE_INSTANCE;

+

+//

+// Pei Core Instance Data Macros

+//

+

+#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \

+  CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE)

+

+//

+// BUGBUG: Where does this go really?

+//

+typedef

+EFI_STATUS

+(EFIAPI *PEI_CORE_ENTRY_POINT)(

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN PEI_CORE_INSTANCE           *OldCoreData

+  );

+

+//

+// Union of temporarily used function pointers (to save stack space)

+//

+typedef union {

+  PEI_CORE_ENTRY_POINT         PeiCore;

+  EFI_PEIM_ENTRY_POINT         PeimEntry;

+  EFI_PEIM_NOTIFY_ENTRY_POINT  PeimNotifyEntry;

+  EFI_DXE_IPL_PPI              *DxeIpl;

+  EFI_PEI_PPI_DESCRIPTOR       *PpiDescriptor;

+  EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor;

+  VOID                         *Raw;

+} PEI_CORE_TEMP_POINTERS;

+

+

+//

+// Main PEI entry

+//

+

+EFI_STATUS

+EFIAPI

+PeiCore (

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN PEI_CORE_INSTANCE           *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Main entry point to Pei Core. After switching stack in the PEI core, 

+  it will restart with the old core data.

+

+Arguments:

+

+  PeiStartupDescriptor - Information and services provided by SEC phase.

+  OldCoreData          - Pointer to old core data that is used to initialize the

+                         core's data areas.

+

+Returns:

+

+  This function never returns

+

+--*/

+;

+

+

+//

+// Dispatcher support functions

+//

+

+EFI_STATUS

+PeimDispatchReadiness (

+  IN EFI_PEI_SERVICES   **PeiServices,

+  IN VOID               *DependencyExpression,

+  IN OUT BOOLEAN        *Runnable

+  )

+/*++

+

+Routine Description:

+

+  This is the POSTFIX version of the dependency evaluator.  When a

+  PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on

+  the evaluation stack.  When that entry is poped from the evaluation

+  stack, the PPI is checked if it is installed.  This method allows

+  some time savings as not all PPIs must be checked for certain

+  operation types (AND, OR).

+

+Arguments:

+

+  PeiServices               - Calling context.

+

+  DependencyExpression      - Pointer to a dependency expression.  The Grammar adheres to 

+                              the BNF described above and is stored in postfix notation.

+  Runnable                  - is True if the driver can be scheduled and False if the driver 

+                              cannot be scheduled.  This is the value that the schedulers 

+                              should use for deciding the state of the driver.

+

+Returns:

+

+  Status = EFI_SUCCESS            if it is a well-formed Grammar

+           EFI_INVALID_PARAMETER  if the dependency expression overflows

+                                  the evaluation stack

+           EFI_INVALID_PARAMETER  if the dependency expression underflows

+                                  the evaluation stack

+           EFI_INVALID_PARAMETER  if the dependency expression is not a

+                                  well-formed Grammar.

+--*/

+;

+

+

+EFI_STATUS

+PeiDispatcher (

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN PEI_CORE_INSTANCE           *PrivateData,

+  IN PEI_CORE_DISPATCH_DATA      *DispatchData

+  )

+

+/*++

+

+Routine Description:

+

+  Conduct PEIM dispatch.

+

+Arguments:

+

+  PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR

+  PrivateData          - Pointer to the private data passed in from caller

+  DispatchData         - Pointer to PEI_CORE_DISPATCH_DATA data.

+

+Returns:

+

+  EFI_SUCCESS   - Successfully dispatched PEIM.

+  EFI_NOT_FOUND - The dispatch failed.

+            

+--*/

+;

+

+

+VOID

+InitializeDispatcherData (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN PEI_CORE_INSTANCE            *OldCoreData,

+  IN EFI_PEI_STARTUP_DESCRIPTOR   *PeiStartupDescriptor

+  )

+/*++

+

+Routine Description:

+

+  Initialize the Dispatcher's data members

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  OldCoreData          - Pointer to old core data (before switching stack).

+                         NULL if being run in non-permament memory mode.

+  PeiStartupDescriptor - Information and services provided by SEC phase.

+

+

+Returns:

+

+  None

+

+--*/

+;

+

+

+EFI_STATUS

+FindNextPeim (

+  IN EFI_PEI_SERVICES            **PeiServices,

+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER     **PeimFileHeader

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching file in the

+    FFS volume. The search starts from FileHeader inside

+    the Firmware Volume defined by FwVolHeader.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+

+    FwVolHeader - Pointer to the FV header of the volume to search.

+                     This parameter must point to a valid FFS volume.

+                     

+    PeimFileHeader  - Pointer to the current file from which to begin searching.

+                  This pointer will be updated upon return to reflect the file found.

+

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+;

+

+BOOLEAN

+Dispatched (

+  IN UINT8  CurrentPeim,

+  IN UINT32 DispatchedPeimBitMap

+  )

+/*++

+

+Routine Description:

+

+  This routine checks to see if a particular PEIM has been dispatched during

+  the PEI core dispatch.

+

+Arguments:

+  CurrentPeim - The PEIM/FV in the bit array to check.

+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.

+

+Returns:

+  TRUE if PEIM already dispatched

+  FALSE if not

+

+--*/

+;

+

+VOID

+SetDispatched (

+  IN EFI_PEI_SERVICES   **PeiServices,

+  IN UINT8              CurrentPeim,

+  OUT UINT32            *DispatchedPeimBitMap

+  )

+/*++

+

+Routine Description:

+

+  This routine sets a PEIM as having been dispatched once its entry

+  point has been invoked.

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  CurrentPeim          - The PEIM/FV in the bit array to check.

+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.

+

+Returns:

+  None

+

+--*/

+;

+

+BOOLEAN

+DepexSatisfied (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN  VOID             *CurrentPeimAddress

+  )

+/*++

+

+Routine Description:

+

+  This routine parses the Dependency Expression, if available, and

+  decides if the module can be executed.

+

+Arguments:

+  PeiServices - The PEI Service Table

+  CurrentPeimAddress - Address of the PEIM Firmware File under investigation

+

+Returns:

+  TRUE  - Can be dispatched

+  FALSE - Cannot be dispatched

+

+--*/

+;

+

+#ifdef EFI64

+  //

+  // In Ipf we should make special changes for the PHIT pointers to support

+  // recovery boot in cache mode.

+  //

+#define  SWITCH_TO_CACHE_MODE(CoreData)  SwitchToCacheMode(CoreData)

+#define  CACHE_MODE_ADDRESS_MASK         0x7FFFFFFFFFFFFFFFULL

+VOID

+SwitchToCacheMode (

+  IN PEI_CORE_INSTANCE           *CoreData

+)

+/*++

+

+Routine Description:

+

+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.

+

+Arguments:

+

+  CoreData   - The PEI core Private Data

+  

+Returns:

+        

+--*/

+;

+

+#else

+

+#define  SWITCH_TO_CACHE_MODE(CoreData)

+

+#endif

+

+//

+// PPI support functions

+//

+VOID

+InitializePpiServices (

+  IN EFI_PEI_SERVICES    **PeiServices,

+  IN PEI_CORE_INSTANCE   *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Initialize PPI services.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  OldCoreData - Pointer to the PEI Core data.

+                NULL if being run in non-permament memory mode.

+

+Returns:

+  Nothing

+

+--*/

+;

+

+VOID

+ConvertPpiPointers (

+  IN EFI_PEI_SERVICES              **PeiServices,

+  IN EFI_HOB_HANDOFF_INFO_TABLE    *OldHandOffHob,

+  IN EFI_HOB_HANDOFF_INFO_TABLE    *NewHandOffHob

+  )

+/*++

+

+Routine Description:

+

+  Migrate the Hob list from the CAR stack to PEI installed memory.

+

+Arguments:

+

+  PeiServices   - The PEI core services table.

+  OldHandOffHob - The old handoff HOB list.

+  NewHandOffHob - The new handoff HOB list.

+

+Returns:

+            

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiInstallPpi (

+  IN EFI_PEI_SERVICES        **PeiServices,

+  IN EFI_PEI_PPI_DESCRIPTOR  *PpiList

+  )

+/*++

+

+Routine Description:

+

+  Install PPI services.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+  PpiList     - Pointer to a list of PEI PPI Descriptors.

+

+Returns:

+

+    EFI_SUCCESS             - if all PPIs in PpiList are successfully installed.

+    EFI_INVALID_PARAMETER   - if PpiList is NULL pointer

+    EFI_INVALID_PARAMETER   - if any PPI in PpiList is not valid

+    EFI_OUT_OF_RESOURCES    - if there is no more memory resource to install PPI

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiReInstallPpi (

+  IN EFI_PEI_SERVICES        **PeiServices,

+  IN EFI_PEI_PPI_DESCRIPTOR  *OldPpi,

+  IN EFI_PEI_PPI_DESCRIPTOR  *NewPpi

+  )

+/*++

+

+Routine Description:

+

+  Re-Install PPI services.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+  OldPpi      - Pointer to the old PEI PPI Descriptors.

+  NewPpi      - Pointer to the new PEI PPI Descriptors.

+

+Returns:

+

+  EFI_SUCCESS           - if the operation was successful

+  EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL

+  EFI_INVALID_PARAMETER - if NewPpi is not valid

+  EFI_NOT_FOUND         - if the PPI was not in the database

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiLocatePpi (

+  IN EFI_PEI_SERVICES            **PeiServices,

+  IN EFI_GUID                    *Guid,

+  IN UINTN                       Instance,

+  IN OUT EFI_PEI_PPI_DESCRIPTOR  **PpiDescriptor,

+  IN OUT VOID                    **Ppi

+  )

+/*++

+

+Routine Description:

+

+  Locate a given named PPI.

+

+Arguments:

+

+  PeiServices   - Pointer to the PEI Service Table

+  Guid          - Pointer to GUID of the PPI.

+  Instance      - Instance Number to discover.

+  PpiDescriptor - Pointer to reference the found descriptor. If not NULL,

+                returns a pointer to the descriptor (includes flags, etc)

+  Ppi           - Pointer to reference the found PPI

+

+Returns:

+

+  Status -  EFI_SUCCESS   if the PPI is in the database           

+            EFI_NOT_FOUND if the PPI is not in the database

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiNotifyPpi (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList

+  )

+/*++

+

+Routine Description:

+

+  Install a notification for a given PPI.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+  NotifyList  - Pointer to list of Descriptors to notify upon.

+

+Returns:

+

+  Status - EFI_SUCCESS          if successful

+           EFI_OUT_OF_RESOURCES if no space in the database

+           EFI_INVALID_PARAMETER if not a good decriptor

+

+--*/

+;

+

+VOID

+ProcessNotifyList (

+  IN EFI_PEI_SERVICES    **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Process the Notify List at dispatch level.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+

+Returns:

+

+--*/

+;

+

+VOID

+DispatchNotify (

+  IN EFI_PEI_SERVICES    **PeiServices,

+  IN UINTN               NotifyType,

+  IN INTN                InstallStartIndex,

+  IN INTN                InstallStopIndex,

+  IN INTN                NotifyStartIndex,

+  IN INTN                NotifyStopIndex

+  )

+/*++

+

+Routine Description:

+

+  Dispatch notifications.

+

+Arguments:

+

+  PeiServices         - Pointer to the PEI Service Table

+  NotifyType          - Type of notify to fire.

+  InstallStartIndex   - Install Beginning index.

+  InstallStopIndex    - Install Ending index.

+  NotifyStartIndex    - Notify Beginning index.

+  NotifyStopIndex    - Notify Ending index.

+

+Returns:  None

+

+--*/

+;

+

+//

+// Boot mode support functions

+//

+EFI_STATUS

+EFIAPI

+PeiGetBootMode (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN OUT EFI_BOOT_MODE *BootMode

+  )

+/*++

+

+Routine Description:

+

+  This service enables PEIMs to ascertain the present value of the boot mode.  

+

+Arguments:

+

+  PeiServices    - The PEI core services table.

+  BootMode       - A pointer to contain the value of the boot mode. 

+

+Returns:

+

+  EFI_SUCCESS           - The boot mode was returned successfully.

+  EFI_INVALID_PARAMETER - BootMode is NULL.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiSetBootMode (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN EFI_BOOT_MODE     BootMode

+  )

+/*++

+

+Routine Description:

+

+  This service enables PEIMs to update the boot mode variable.    

+

+Arguments:

+

+  PeiServices    - The PEI core services table.

+  BootMode       - The value of the boot mode to set.

+

+Returns:

+

+  EFI_SUCCESS    - The value was successfully updated

+

+--*/

+;

+

+//

+// Security support functions

+//

+VOID

+InitializeSecurityServices (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN PEI_CORE_INSTANCE *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Initialize the security services.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  OldCoreData - Pointer to the old core data.

+                NULL if being run in non-permament memory mode.

+Returns:

+

+  None

+

+--*/

+;

+

+EFI_STATUS

+VerifyFv (

+  IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress

+  )

+/*++

+

+Routine Description:

+

+  Provide a callout to the OEM FV verification service.

+

+Arguments:

+

+  CurrentFvAddress       - Pointer to the FV under investigation.

+

+Returns:

+

+  Status - EFI_SUCCESS

+

+--*/

+;

+

+

+EFI_STATUS

+VerifyPeim (

+  IN EFI_PEI_SERVICES     **PeiServices,

+  IN EFI_FFS_FILE_HEADER  *CurrentPeimAddress

+  )

+/*++

+

+Routine Description:

+

+  Provide a callout to the security verification service.

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  CurrentPeimAddress   - Pointer to the Firmware File under investigation.

+

+Returns:

+

+  EFI_SUCCESS             - Image is OK

+  EFI_SECURITY_VIOLATION  - Image is illegal

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiGetHobList (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN OUT VOID          **HobList

+  )

+/*++

+

+Routine Description:

+

+  Gets the pointer to the HOB List.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  HobList     - Pointer to the HOB List.

+

+Returns:

+

+  EFI_SUCCESS                 - Get the pointer of HOB List

+  EFI_NOT_AVAILABLE_YET       - the HOB List is not yet published

+  EFI_INVALID_PARAMETER       - HobList is NULL (in debug mode)

+            

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiCreateHob (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN UINT16            Type,

+  IN UINT16            Length,

+  IN OUT VOID          **Hob

+  )

+/*++

+

+Routine Description:

+

+  Add a new HOB to the HOB List.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  Type        - Type of the new HOB.

+  Length      - Length of the new HOB to allocate.

+  Hob         - Pointer to the new HOB.

+

+Returns:

+

+  Status  - EFI_SUCCESS

+          - EFI_INVALID_PARAMETER if Hob is NULL

+          - EFI_NOT_AVAILABLE_YET if HobList is still not available.

+          - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.

+            

+--*/

+;

+

+EFI_STATUS

+PeiCoreBuildHobHandoffInfoTable (

+  IN EFI_BOOT_MODE         BootMode,

+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,

+  IN UINT64                MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  Builds a Handoff Information Table HOB

+

+Arguments:

+

+  BootMode      - Current Bootmode

+  MemoryBegin   - Start Memory Address.

+  MemoryLength  - Length of Memory.

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+;

+

+

+//

+// FFS Fw Volume support functions

+//

+EFI_STATUS

+EFIAPI

+PeiFfsFindNextFile (

+  IN EFI_PEI_SERVICES            **PeiServices,

+  IN UINT8                       SearchType,

+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching file in the

+    FFS volume as defined by SearchType. The search starts from FileHeader inside

+    the Firmware Volume defined by FwVolHeader.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+    

+    SearchType - Filter to find only files of this type.

+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.

+      

+    FwVolHeader - Pointer to the FV header of the volume to search.

+      This parameter must point to a valid FFS volume.

+      

+    FileHeader  - Pointer to the current file from which to begin searching.

+      This pointer will be updated upon return to reflect the file found.

+  

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiFfsFindSectionData (

+  IN EFI_PEI_SERVICES            **PeiServices,

+  IN EFI_SECTION_TYPE            SectionType,

+  IN EFI_FFS_FILE_HEADER         *FfsFileHeader,

+  IN OUT VOID                    **SectionData

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching section in the

+    FFS volume.

+

+Arguments:

+    PeiServices - Pointer to the PEI Core Services Table.

+    SearchType - Filter to find only sections of this type.

+    FfsFileHeader  - Pointer to the current file to search.

+    SectionData - Pointer to the Section matching SectionType in FfsFileHeader.

+                - NULL if section not found

+

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiFvFindNextVolume (

+  IN EFI_PEI_SERVICES                **PeiServices,

+  IN UINTN                           Instance,

+  IN OUT EFI_FIRMWARE_VOLUME_HEADER  **FwVolHeader

+  )

+/*++

+

+Routine Description:

+

+  Return the BFV location

+

+  BugBug -- Move this to the location of this code to where the

+  other FV and FFS support code lives.

+  Also, update to use FindFV for instances #'s >= 1.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  Instance    - Instance of FV to find

+  FwVolHeader - Pointer to contain the data to return

+

+Returns:

+  Pointer to the Firmware Volume instance requested

+  

+  EFI_INVALID_PARAMETER     - FwVolHeader is NULL

+  

+  EFI_SUCCESS               - Firmware volume instance successfully found.

+

+--*/

+;

+

+//

+// Memory support functions

+//

+VOID

+InitializeMemoryServices (

+  IN EFI_PEI_SERVICES            **PeiServices,

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN PEI_CORE_INSTANCE           *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Initialize the memory services.

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  PeiStartupDescriptor - Information and services provided by SEC phase.

+  OldCoreData          - Pointer to the PEI Core data.

+                         NULL if being run in non-permament memory mode.

+

+Returns:

+

+  None

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiInstallPeiMemory (

+  IN EFI_PEI_SERVICES      **PeiServices,

+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,

+  IN UINT64                MemoryLength

+  )

+/*++

+

+Routine Description:

+

+  Install the permanent memory is now available.

+  Creates HOB (PHIT and Stack).

+

+Arguments:

+

+  PeiServices   - The PEI core services table.

+  MemoryBegin   - Start of memory address.

+  MemoryLength  - Length of memory.

+

+Returns:

+

+  Status  - EFI_SUCCESS

+            

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiAllocatePages (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_MEMORY_TYPE            MemoryType,

+  IN UINTN                      Pages,

+  OUT EFI_PHYSICAL_ADDRESS      *Memory

+  )

+/*++

+

+Routine Description:

+

+  Memory allocation service on permanent memory, 

+  not usable prior to the memory installation.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  Type        - Type of allocation.

+  MemoryType  - Type of memory to allocate.

+  Pages       - Number of pages to allocate.

+  Memory      - Pointer of memory allocated.

+

+Returns:

+

+  Status - EFI_SUCCESS              The allocation was successful

+           EFI_INVALID_PARAMETER    Only AllocateAnyAddress is supported.

+           EFI_NOT_AVAILABLE_YET    Called with permanent memory not available

+           EFI_OUT_OF_RESOURCES     There is not enough HOB heap to satisfy the requirement

+                                    to allocate the number of pages.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiAllocatePool (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN UINTN                      Size,

+  OUT VOID                      **Buffer

+  )

+/*++

+

+Routine Description:

+

+  Memory allocation service on the CAR.  

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+

+  Size        - Amount of memory required

+

+  Buffer      - Address of pointer to the buffer

+

+Returns:

+

+  Status - EFI_SUCCESS              The allocation was successful

+           EFI_OUT_OF_RESOURCES     There is not enough heap to satisfy the requirement

+                                    to allocate the requested size.

+                                    

+--*/

+;

+

+EFI_STATUS

+PeiLoadImage (

+  IN  EFI_PEI_SERVICES            **PeiServices,

+  IN  EFI_FFS_FILE_HEADER         *PeimFileHeader,

+  OUT VOID                        **EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  Get entry point of a Peim file.

+

+Arguments:

+

+  PeiServices                 - Calling context.

+  

+  PeimFileHeader              - Peim file's header.

+  

+  EntryPoint                  - Entry point of that Peim file.

+

+Returns:

+

+  Status code.

+            

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiReportStatusCode (

+  IN EFI_PEI_SERVICES         **PeiServices,

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId,

+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Core version of the Status Code reporter

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  

+  CodeType    - Type of Status Code.

+  

+  Value       - Value to output for Status Code.

+  

+  Instance    - Instance Number of this status code.

+  

+  CallerId    - ID of the caller of this status code.

+  

+  Data        - Optional data associated with this status code.

+

+Returns:

+

+  Status  - EFI_SUCCESS             if status code is successfully reported

+          - EFI_NOT_AVAILABLE_YET   if StatusCodePpi has not been installed

+

+--*/

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiResetSystem (

+  IN EFI_PEI_SERVICES   **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Core version of the Reset System

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+

+Returns:

+

+  Status  - EFI_NOT_AVAILABLE_YET. PPI not available yet.

+          - EFI_DEVICE_ERROR.   Did not reset system.

+          

+  Otherwise, resets the system. 

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Core/Pei/PeiMain.mbd b/edk2/EdkModulePkg/Core/Pei/PeiMain.mbd
new file mode 100644
index 0000000..145a544
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/PeiMain.mbd
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MbdHeader>
+    <BaseName>PeiMain</BaseName>
+    <Guid>52C05B14-0B98-496c-BC3B-04B50211D680</Guid>
+    <Version>0</Version>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-03-12 17:09</Created>
+    <Modified>2006-03-19 15:18</Modified>
+  </MbdHeader>
+  <Libraries>
+    <Library>PeiCoreEntryPoint</Library>
+    <Library>BaseLib</Library>
+    <Library>BaseMemoryLib</Library>
+    <Library OverrideID="4444">PeiServicesTablePointerLib</Library>
+    <Library>PeiCoreLib</Library>
+    <Library>PeiHobLib</Library>
+    <Library>PeiReportStatusCodeLib</Library>
+    <Library>BaseDebugLibReportStatusCode</Library>
+    <Library>BasePerformanceLibNull</Library>
+    <Arch ArchType="IA32">
+      <Library OverrideID="6666">BasePeCoffGetEntryPointLib</Library>
+    </Arch>
+    <Arch ArchType="X64">
+      <Library>BasePeCoffGetEntryPointLib</Library>
+    </Arch>
+    <Arch ArchType="IPF">
+      <Library>BasePeCoffGetEntryPointLib</Library>
+    </Arch>
+    <Arch ArchType="EBC">
+      <Library>BasePeCoffGetEntryPointLib</Library>
+    </Arch>
+  </Libraries>
+</ModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Core/Pei/PeiMain.msa b/edk2/EdkModulePkg/Core/Pei/PeiMain.msa
new file mode 100644
index 0000000..1f5342e
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/PeiMain.msa
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PeiMain</BaseName>

+    <ModuleType>PEI_CORE</ModuleType>

+    <ComponentType>PEI_CORE</ComponentType>

+    <Guid>52C05B14-0B98-496c-BC3B-04B50211D680</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for PeiMain module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeCoffGetEntryPointLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TimerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiMain.h</Filename>

+    <Filename>BootMode/BootMode.c</Filename>

+    <Filename>Dependency/dependency.c</Filename>

+    <Filename>Dispatcher/Dispatcher.c</Filename>

+    <Filename>FwVol/FwVol.c</Filename>

+    <Filename>Hob/Hob.c</Filename>

+    <Filename>Image/Image.c</Filename>

+    <Filename>Memory/MemoryServices.c</Filename>

+    <Filename>PeiMain/PeiMain.c</Filename>

+    <Filename>Ppi/Ppi.c</Filename>

+    <Filename>Reset/Reset.c</Filename>

+    <Filename>Security/Security.c</Filename>

+    <Filename>StatusCode/StatusCode.c</Filename>

+    <Arch ArchType="IPF">

+      <Filename>ipf/SwitchToCacheMode.c</Filename>

+      <Filename>ipf/IpfCpuCore.i</Filename>

+      <Filename>ipf/IpfCpuCore.s</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="PHIT"></Hob>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <C_Name>gPeiPerformanceHobGuid</C_Name>

+      <Guid>0xec4df5af, 0x4395, 0x4cc9, 0x94, 0xde, 0x77, 0x50, 0x6d, 0x12, 0xc7, 0xb8</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">MemoryDiscovered</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">FindFv</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">FvFileLoader</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">DxeIpl</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">Reset</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">StatusCode</Ppi>

+    <PpiNotify Usage="SOMETIMES_CONSUMED">Security</PpiNotify>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeiCore</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Core/Pei/PeiMain/PeiMain.c b/edk2/EdkModulePkg/Core/Pei/PeiMain/PeiMain.c
new file mode 100644
index 0000000..7b4c2f9
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -0,0 +1,241 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  PeiMain.c
+
+Abstract:
+
+  Pei Core Main Entry Point
+
+Revision History
+
+--*/
+
+#include <PeiMain.h>
+
+//
+//CAR is filled with this initial value during SEC phase
+//
+#define INIT_CAR_VALUE 0x5AA55AA5
+
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiMemoryDiscoveredPpiGuid,
+  NULL
+};
+
+//
+// Pei Core Module Variables
+//
+//
+static EFI_PEI_SERVICES  mPS = {
+  {
+    PEI_SERVICES_SIGNATURE,
+    PEI_SERVICES_REVISION,
+    sizeof (EFI_PEI_SERVICES),
+    0,
+    0
+  },
+  PeiInstallPpi,
+  PeiReInstallPpi,
+  PeiLocatePpi,
+  PeiNotifyPpi,
+
+  PeiGetBootMode,
+  PeiSetBootMode,
+
+  PeiGetHobList,
+  PeiCreateHob,
+
+  PeiFvFindNextVolume,
+  PeiFfsFindNextFile,
+  PeiFfsFindSectionData,
+
+  PeiInstallPeiMemory,
+  PeiAllocatePages,
+  PeiAllocatePool,
+  (EFI_PEI_COPY_MEM)CopyMem,
+  (EFI_PEI_SET_MEM)SetMem,
+
+  PeiReportStatusCode,
+
+  PeiResetSystem
+};
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,
+  IN PEI_CORE_INSTANCE           *OldCoreData
+  )
+/*++
+
+Routine Description:
+
+  Main entry point to Pei Core. After switching stack in the PEI core, 
+  it will restart with the old core data.
+
+Arguments:
+
+  PeiStartupDescriptor - Information and services provided by SEC phase.
+  OldCoreData          - Pointer to old core data that is used to initialize the
+                         core's data areas.
+
+Returns:
+
+  This function never returns
+  EFI_NOT_FOUND        - Never reach
+
+--*/
+{
+  PEI_CORE_INSTANCE                                     PrivateData;
+  EFI_STATUS                                            Status;
+  PEI_CORE_TEMP_POINTERS                                TempPtr;
+  PEI_CORE_DISPATCH_DATA                                *DispatchData;
+  UINT64                                                mTick;
+
+  mTick = 0;
+
+#ifdef EFI_PEI_PERFORMANCE
+  if (OldCoreData == NULL) {
+    mTick = GetPerformanceCounter ();
+  }
+#endif
+
+  //
+  // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
+  //  the 63-bit of address is set to 1.
+  //
+  SWITCH_TO_CACHE_MODE (OldCoreData);
+
+  if (OldCoreData != NULL) {
+    CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
+  } else {
+    ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));
+  }
+
+  PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
+  PrivateData.PS = &mPS;
+
+  //
+  // Initialize libraries that the PeiCore is linked against
+  // BUGBUG: The FfsHeader is passed in as NULL.  Do we look it up or remove it from the lib init?
+  //
+  ProcessLibraryConstructorList (NULL, &PrivateData.PS);
+
+  InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);
+
+  InitializePpiServices (&PrivateData.PS, OldCoreData);
+
+  InitializeSecurityServices (&PrivateData.PS, OldCoreData);
+
+  InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor);
+
+  if (OldCoreData != NULL) {
+
+    PERF_END (NULL,"PreMem", NULL, 0);
+    PERF_START (NULL,"PostMem", NULL, 0);
+
+    //
+    // The following code dumps out interesting cache as RAM usage information
+    // so we can keep tabs on how the cache as RAM is being utilized.  The
+    // DEBUG_CODE macro is used to prevent this code from being compiled
+    // on a debug build.
+    //
+    DEBUG_CODE (
+      UINTN  *StackPointer;
+      UINTN  StackValue;
+
+      StackValue = INIT_CAR_VALUE;
+      for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;
+           ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
+           && StackValue == INIT_CAR_VALUE;
+           StackPointer++) {
+        StackValue = *StackPointer;
+      }
+
+      DEBUG ((EFI_D_INFO, "Total Cache as RAM:    %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
+      DEBUG ((EFI_D_INFO, "  CAR stack ever used: %d bytes.\n",
+        ((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)
+        ));
+      DEBUG ((EFI_D_INFO, "  CAR heap used:       %d bytes.\n",
+        ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
+        (UINTN) OldCoreData->HobList.Raw)
+        ));
+    );
+
+    //
+    // Alert any listeners that there is permanent memory available
+    //
+    PERF_START (NULL,"DisMem", NULL, 0);
+    Status = PeiCoreInstallPpi (&mMemoryDiscoveredPpi);
+    PERF_END (NULL,"DisMem", NULL, 0);
+
+  } else {
+
+    //
+    // Report Status Code EFI_SW_PC_INIT
+    //
+    REPORT_STATUS_CODE (
+      EFI_PROGRESS_CODE,
+      EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT
+      );
+
+    //
+    // If first pass, start performance measurement.
+    //
+    PERF_START (NULL,"PreMem", NULL, mTick);
+
+    //
+    // If SEC provided any PPI services to PEI, install them.
+    //
+    if (PeiStartupDescriptor->DispatchTable != NULL) {
+      Status = PeiCoreInstallPpi (PeiStartupDescriptor->DispatchTable);
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  DispatchData = &PrivateData.DispatchData;
+
+  //
+  // Call PEIM dispatcher
+  //
+  PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
+
+  //
+  // Check if InstallPeiMemory service was called.
+  //
+  ASSERT(PrivateData.PeiMemoryInstalled == TRUE);
+
+  PERF_END (NULL, "PostMem", NULL, 0);
+
+  Status = PeiCoreLocatePpi (
+             &gEfiDxeIplPpiGuid,
+             0,
+             NULL,
+             (VOID **)&TempPtr.DxeIpl
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_INFO, "DXE IPL Entry\n"));
+  Status = TempPtr.DxeIpl->Entry (
+                             TempPtr.DxeIpl,
+                             &PrivateData.PS,
+                             PrivateData.HobList
+                             );
+
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_NOT_FOUND;
+}
+
diff --git a/edk2/EdkModulePkg/Core/Pei/Ppi/Ppi.c b/edk2/EdkModulePkg/Core/Pei/Ppi/Ppi.c
new file mode 100644
index 0000000..7fdb08c
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Ppi/Ppi.c
@@ -0,0 +1,658 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ppi.c

+

+Abstract:

+

+  EFI PEI Core PPI services

+

+Revision History

+

+--*/

+

+#include <PeiMain.h>

+

+VOID

+InitializePpiServices (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN PEI_CORE_INSTANCE *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Initialize PPI services.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  OldCoreData - Pointer to the PEI Core data.

+                NULL if being run in non-permament memory mode.

+

+Returns:

+  Nothing

+

+--*/

+{

+  PEI_CORE_INSTANCE                    *PrivateData;

+  

+  if (OldCoreData == NULL) {

+    PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+    PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;

+    PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;

+    PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;

+  }

+ 

+  return;   

+}

+

+VOID

+ConvertPpiPointers (

+  IN EFI_PEI_SERVICES                     **PeiServices,

+  IN EFI_HOB_HANDOFF_INFO_TABLE    *OldHandOffHob,

+  IN EFI_HOB_HANDOFF_INFO_TABLE    *NewHandOffHob

+  )

+/*++

+

+Routine Description:

+

+  Migrate the Hob list from the CAR stack to PEI installed memory.

+

+Arguments:

+

+  PeiServices   - The PEI core services table.

+  OldHandOffHob - The old handoff HOB list.

+  NewHandOffHob - The new handoff HOB list.

+

+Returns:

+            

+--*/

+{

+  PEI_CORE_INSTANCE     *PrivateData;

+  UINT8                 Index;

+  PEI_PPI_LIST_POINTERS *PpiPointer;

+  UINTN                 Fixup;

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;

+  

+  for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {

+    if (Index < PrivateData->PpiData.PpiListEnd ||

+        Index > PrivateData->PpiData.NotifyListEnd) {

+      PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];

+      

+      if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) && 

+          ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {

+        //

+        // Convert the pointer to the PEIM descriptor from the old HOB heap

+        // to the relocated HOB heap.

+        //

+        PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);

+

+        //

+        // Only when the PEIM descriptor is in the old HOB should it be necessary

+        // to try to convert the pointers in the PEIM descriptor

+        //

+        

+        if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) && 

+            ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {

+          //

+          // Convert the pointer to the GUID in the PPI or NOTIFY descriptor

+          // from the old HOB heap to the relocated HOB heap.

+          //

+          PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);

+        }

+

+        //

+        // Assume that no code is located in the temporary memory, so the pointer to

+        // the notification function in the NOTIFY descriptor needs not be converted.

+        //

+        if (Index < PrivateData->PpiData.PpiListEnd &&

+            (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&

+            (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {

+            //

+            // Convert the pointer to the PPI interface structure in the PPI descriptor

+            // from the old HOB heap to the relocated HOB heap.

+            //

+            PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);   

+        }

+      }

+    }

+  }

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiInstallPpi (

+  IN EFI_PEI_SERVICES        **PeiServices,

+  IN EFI_PEI_PPI_DESCRIPTOR  *PpiList

+  )

+/*++

+

+Routine Description:

+

+  Install PPI services.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+  PpiList     - Pointer to a list of PEI PPI Descriptors.

+

+Returns:

+

+    EFI_SUCCESS             - if all PPIs in PpiList are successfully installed.

+    EFI_INVALID_PARAMETER   - if PpiList is NULL pointer

+    EFI_INVALID_PARAMETER   - if any PPI in PpiList is not valid

+    EFI_OUT_OF_RESOURCES    - if there is no more memory resource to install PPI

+

+--*/

+{

+  PEI_CORE_INSTANCE *PrivateData;

+  INTN              Index;

+  INTN              LastCallbackInstall;

+

+

+  if (PpiList == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  Index = PrivateData->PpiData.PpiListEnd;

+  LastCallbackInstall = Index;

+

+  //

+  // This is loop installs all PPI descriptors in the PpiList.  It is terminated

+  // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last

+  // EFI_PEI_PPI_DESCRIPTOR in the list.

+  //

+    

+  for (;;) {

+    //

+    // Since PpiData is used for NotifyList and InstallList, max resource

+    // is reached if the Install reaches the NotifyList

+    //

+    if (Index == PrivateData->PpiData.NotifyListEnd + 1) {

+      return  EFI_OUT_OF_RESOURCES;

+    }

+    //

+    // Check if it is a valid PPI. 

+    // If not, rollback list to exclude all in this list.

+    // Try to indicate which item failed.

+    //

+    if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {

+      PrivateData->PpiData.PpiListEnd = LastCallbackInstall;

+      DEBUG((EFI_D_INFO, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));

+      return  EFI_INVALID_PARAMETER;

+    } 

+

+    DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid)); 

+    PrivateData->PpiData.PpiListPtrs[Index].Ppi = PpiList;    

+    PrivateData->PpiData.PpiListEnd++;

+    

+    //

+    // Continue until the end of the PPI List.

+    //

+    if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==  

+        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {

+      break;

+    }

+    PpiList++;

+    Index++;

+  }

+

+  //

+  // Dispatch any callback level notifies for newly installed PPIs.

+  //

+  DispatchNotify (

+    PeiServices,

+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,

+    LastCallbackInstall,

+    PrivateData->PpiData.PpiListEnd,

+    PrivateData->PpiData.DispatchListEnd,                 

+    PrivateData->PpiData.NotifyListEnd

+    );

+

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiReInstallPpi (

+  IN EFI_PEI_SERVICES        **PeiServices,

+  IN EFI_PEI_PPI_DESCRIPTOR  *OldPpi,

+  IN EFI_PEI_PPI_DESCRIPTOR  *NewPpi

+  )

+/*++

+

+Routine Description:

+

+  Re-Install PPI services.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+  OldPpi      - Pointer to the old PEI PPI Descriptors.

+  NewPpi      - Pointer to the new PEI PPI Descriptors.

+

+Returns:

+

+  EFI_SUCCESS           - if the operation was successful

+  EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL

+  EFI_INVALID_PARAMETER - if NewPpi is not valid

+  EFI_NOT_FOUND         - if the PPI was not in the database

+

+--*/

+{

+  PEI_CORE_INSTANCE   *PrivateData;

+  INTN                Index;

+

+

+  if ((OldPpi == NULL) || (NewPpi == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {

+    return  EFI_INVALID_PARAMETER;

+  }

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  //

+  // Find the old PPI instance in the database.  If we can not find it,

+  // return the EFI_NOT_FOUND error.

+  //

+  for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {

+    if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {

+      break;

+    }

+  }

+  if (Index == PrivateData->PpiData.PpiListEnd) {

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Remove the old PPI from the database, add the new one.

+  // 

+  DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));

+  PrivateData->PpiData.PpiListPtrs[Index].Ppi = NewPpi;

+

+  //

+  // Dispatch any callback level notifies for the newly installed PPI.

+  //

+  DispatchNotify (

+    PeiServices,

+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,

+    Index,

+    Index+1,

+    PrivateData->PpiData.DispatchListEnd,                 

+    PrivateData->PpiData.NotifyListEnd

+    );

+

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiLocatePpi (

+  IN EFI_PEI_SERVICES        **PeiServices,

+  IN EFI_GUID                *Guid,

+  IN UINTN                   Instance,

+  IN OUT EFI_PEI_PPI_DESCRIPTOR  **PpiDescriptor,

+  IN OUT VOID                **Ppi

+  )

+/*++

+

+Routine Description:

+

+  Locate a given named PPI.

+

+Arguments:

+

+  PeiServices   - Pointer to the PEI Service Table

+  Guid          - Pointer to GUID of the PPI.

+  Instance      - Instance Number to discover.

+  PpiDescriptor - Pointer to reference the found descriptor. If not NULL,

+                returns a pointer to the descriptor (includes flags, etc)

+  Ppi           - Pointer to reference the found PPI

+

+Returns:

+

+  Status -  EFI_SUCCESS   if the PPI is in the database           

+            EFI_NOT_FOUND if the PPI is not in the database

+--*/

+{

+  PEI_CORE_INSTANCE   *PrivateData;

+  INTN                Index;

+  EFI_GUID            *CheckGuid;

+  EFI_PEI_PPI_DESCRIPTOR  *TempPtr;

+

+  

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  //

+  // Search the data base for the matching instance of the GUIDed PPI.

+  //

+  for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {

+    TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;

+    CheckGuid = TempPtr->Guid;

+

+    //

+    // Don't use CompareGuid function here for performance reasons.

+    // Instead we compare the GUID as INT32 at a time and branch

+    // on the first failed comparison.

+    //

+    if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&

+        (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&

+        (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&

+        (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {

+      if (Instance == 0) {

+

+        if (PpiDescriptor != NULL) {

+          *PpiDescriptor = TempPtr;

+        }

+

+        if (Ppi != NULL) {

+          *Ppi = TempPtr->Ppi;

+        }

+

+

+        return EFI_SUCCESS;

+      }

+      Instance--;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiNotifyPpi (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList

+  )

+/*++

+

+Routine Description:

+

+  Install a notification for a given PPI.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+  NotifyList  - Pointer to list of Descriptors to notify upon.

+

+Returns:

+

+  Status - EFI_SUCCESS           if successful

+           EFI_OUT_OF_RESOURCES  if no space in the database

+           EFI_INVALID_PARAMETER if not a good decriptor

+

+--*/

+{

+  PEI_CORE_INSTANCE                *PrivateData;

+  INTN                             Index;

+  INTN                             NotifyIndex;

+  INTN                             LastCallbackNotify;

+  EFI_PEI_NOTIFY_DESCRIPTOR        *NotifyPtr;

+  UINTN                            NotifyDispatchCount;

+

+

+  NotifyDispatchCount = 0;

+

+  if (NotifyList == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  Index = PrivateData->PpiData.NotifyListEnd;

+  LastCallbackNotify = Index;

+

+  //

+  // This is loop installs all Notify descriptors in the NotifyList.  It is

+  // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last

+  // EFI_PEI_NOTIFY_DESCRIPTOR in the list.

+  //

+

+  for (;;) {

+    //

+    // Since PpiData is used for NotifyList and InstallList, max resource

+    // is reached if the Install reaches the PpiList

+    //

+    if (Index == PrivateData->PpiData.PpiListEnd - 1) {

+      return  EFI_OUT_OF_RESOURCES;

+    }

+    

+    //

+    // If some of the PPI data is invalid restore original Notify PPI database value

+    //

+    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {

+        PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;

+        DEBUG((EFI_D_INFO, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));

+      return  EFI_INVALID_PARAMETER;

+    }

+     

+    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {

+      NotifyDispatchCount ++; 

+    }        

+    

+    PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyList;      

+   

+    PrivateData->PpiData.NotifyListEnd--;

+    DEBUG((EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));

+    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==

+        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {

+      break;

+    }

+    //

+    // Go the next descriptor. Remember the NotifyList moves down.

+    //

+    NotifyList++;

+    Index--;

+  }

+ 

+  //

+  // If there is Dispatch Notify PPI installed put them on the bottom 

+  //

+  if (NotifyDispatchCount > 0) {

+    for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {             

+      if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {

+        NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;

+        

+        for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){

+          PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;

+        }

+        PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;

+        PrivateData->PpiData.DispatchListEnd--;                

+      }

+    }

+    

+    LastCallbackNotify -= NotifyDispatchCount;        

+  }

+  

+  //

+  // Dispatch any callback level notifies for all previously installed PPIs.

+  //

+  DispatchNotify (

+    PeiServices,

+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,

+    0,

+    PrivateData->PpiData.PpiListEnd,

+    LastCallbackNotify,

+    PrivateData->PpiData.NotifyListEnd

+    );

+  

+  

+  return  EFI_SUCCESS;

+}

+

+

+VOID

+ProcessNotifyList (

+  IN EFI_PEI_SERVICES    **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Process the Notify List at dispatch level.

+

+Arguments:

+

+  PeiServices - Pointer to the PEI Service Table

+

+Returns:

+

+--*/

+

+{

+  PEI_CORE_INSTANCE       *PrivateData;

+  INTN                    TempValue;

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+ 

+  while (TRUE) {

+    //

+    // Check if the PEIM that was just dispatched resulted in any

+    // Notifies getting installed.  If so, go process any dispatch

+    // level Notifies that match the previouly installed PPIs.

+    // Use "while" instead of "if" since DispatchNotify can modify 

+    // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.

+    //

+    while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {

+      TempValue = PrivateData->PpiData.DispatchListEnd;

+      DispatchNotify (

+        PeiServices,

+        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,

+        0,

+        PrivateData->PpiData.LastDispatchedInstall,

+        PrivateData->PpiData.LastDispatchedNotify,

+        PrivateData->PpiData.DispatchListEnd

+        );

+      PrivateData->PpiData.LastDispatchedNotify = TempValue;

+    }

+    

+    

+    //

+    // Check if the PEIM that was just dispatched resulted in any

+    // PPIs getting installed.  If so, go process any dispatch

+    // level Notifies that match the installed PPIs.

+    // Use "while" instead of "if" since DispatchNotify can modify 

+    // PpiListEnd (with InstallPpi) so we have to iterate until the same.

+    //

+    while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {

+      TempValue = PrivateData->PpiData.PpiListEnd;

+      DispatchNotify (

+        PeiServices,

+        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,

+        PrivateData->PpiData.LastDispatchedInstall,

+        PrivateData->PpiData.PpiListEnd,

+        MAX_PPI_DESCRIPTORS-1,

+        PrivateData->PpiData.DispatchListEnd

+        );

+      PrivateData->PpiData.LastDispatchedInstall = TempValue;

+    }

+    

+    if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {

+      break;

+    }

+  } 

+  return;

+}

+

+VOID

+DispatchNotify (

+  IN EFI_PEI_SERVICES    **PeiServices,

+  IN UINTN               NotifyType,

+  IN INTN                InstallStartIndex,

+  IN INTN                InstallStopIndex,

+  IN INTN                NotifyStartIndex,

+  IN INTN                NotifyStopIndex

+  )

+/*++

+

+Routine Description:

+

+  Dispatch notifications.

+

+Arguments:

+

+  PeiServices         - Pointer to the PEI Service Table

+  NotifyType          - Type of notify to fire.

+  InstallStartIndex   - Install Beginning index.

+  InstallStopIndex    - Install Ending index.

+  NotifyStartIndex    - Notify Beginning index.

+  NotifyStopIndex    - Notify Ending index.

+

+Returns:  None

+

+--*/

+

+{

+  PEI_CORE_INSTANCE       *PrivateData;

+  INTN                   Index1;

+  INTN                   Index2;

+  EFI_GUID                *SearchGuid;

+  EFI_GUID                *CheckGuid;

+  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor;

+

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

+

+  //

+  // Remember that Installs moves up and Notifies moves down.

+  //

+  for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {

+    NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;

+

+    CheckGuid = NotifyDescriptor->Guid;

+

+    for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {

+      SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;

+      //

+      // Don't use CompareGuid function here for performance reasons.

+      // Instead we compare the GUID as INT32 at a time and branch

+      // on the first failed comparison.

+      //

+      if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&

+          (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&

+          (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&

+          (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {

+        DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %x\n", 

+          SearchGuid, 

+          NotifyDescriptor->Notify

+          ));

+        NotifyDescriptor->Notify (

+                            PeiServices,

+                            NotifyDescriptor,

+                            (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi

+                            );

+      }

+    }

+  }

+

+  return;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Pei/Reset/Reset.c b/edk2/EdkModulePkg/Core/Pei/Reset/Reset.c
new file mode 100644
index 0000000..6bcb4ce
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Reset/Reset.c
@@ -0,0 +1,68 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Reset.c

+

+Abstract:

+

+  Pei Core Reset System Support

+

+Revision History

+

+--*/

+

+#include <PeiMain.h>

+

+EFI_STATUS

+EFIAPI

+PeiResetSystem (

+  IN EFI_PEI_SERVICES         **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Core version of the Reset System

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+

+Returns:

+

+  Status  - EFI_NOT_AVAILABLE_YET. PPI not available yet.

+          - EFI_DEVICE_ERROR.   Did not reset system.

+          

+  Otherwise, resets the system. 

+

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_PEI_RESET_PPI *ResetPpi;

+

+  Status = PeiCoreLocatePpi (

+             &gEfiPeiResetPpiGuid,         

+             0,                         

+             NULL,                      

+             (VOID **)&ResetPpi                  

+             );

+

+  //

+  // LocatePpi returns EFI_NOT_FOUND on error

+  //

+  if (!EFI_ERROR (Status)) {

+    return ResetPpi->ResetSystem (PeiServices);

+  } 

+  return  EFI_NOT_AVAILABLE_YET;

+}

+

diff --git a/edk2/EdkModulePkg/Core/Pei/Security/Security.c b/edk2/EdkModulePkg/Core/Pei/Security/Security.c
new file mode 100644
index 0000000..5908928
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/Security/Security.c
@@ -0,0 +1,192 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Security.c

+

+Abstract:

+

+  EFI PEI Core Security services

+

+--*/

+

+#include <PeiMain.h>

+

+EFI_STATUS

+EFIAPI

+SecurityPpiNotifyCallback (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,

+  IN VOID                       *Ppi

+  );

+

+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {

+   EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,

+   &gEfiPeiSecurityPpiGuid,

+   SecurityPpiNotifyCallback

+};

+

+VOID

+InitializeSecurityServices (

+  IN EFI_PEI_SERVICES  **PeiServices,

+  IN PEI_CORE_INSTANCE *OldCoreData

+  )

+/*++

+

+Routine Description:

+

+  Initialize the security services.

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  OldCoreData - Pointer to the old core data.

+                NULL if being run in non-permament memory mode.

+Returns:

+

+  None

+

+--*/

+{

+  if (OldCoreData == NULL) {

+    PeiCoreNotifyPpi (&mNotifyList);

+  }

+  return;

+}

+

+EFI_STATUS

+EFIAPI

+SecurityPpiNotifyCallback (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,

+  IN VOID                       *Ppi

+  )

+/*++

+

+Routine Description:

+

+  Provide a callback for when the security PPI is installed.

+

+Arguments:

+

+  PeiServices       - The PEI core services table.

+  NotifyDescriptor  - The descriptor for the notification event.

+  Ppi               - Pointer to the PPI in question.

+

+Returns:

+

+  EFI_SUCCESS - The function is successfully processed.

+

+--*/

+{

+  PEI_CORE_INSTANCE                       *PrivateData;

+

+  //

+  // Get PEI Core private data

+  //

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);

+  

+  //

+  // If there isn't a security PPI installed, use the one from notification

+  //

+  if (PrivateData->PrivateSecurityPpi == NULL) {

+    PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY_PPI *)Ppi;

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+VerifyPeim (

+  IN EFI_PEI_SERVICES     **PeiServices,

+  IN EFI_FFS_FILE_HEADER  *CurrentPeimAddress

+  )

+/*++

+

+Routine Description:

+

+  Provide a callout to the security verification service.

+

+Arguments:

+

+  PeiServices          - The PEI core services table.

+  CurrentPeimAddress   - Pointer to the Firmware File under investigation.

+

+Returns:

+

+  EFI_SUCCESS             - Image is OK

+  EFI_SECURITY_VIOLATION  - Image is illegal

+

+--*/

+{

+  PEI_CORE_INSTANCE               *PrivateData;

+  EFI_STATUS                      Status;

+  UINT32                          AuthenticationStatus;

+  BOOLEAN                         StartCrisisRecovery;

+

+  //

+  // Set a default authentication state

+  //

+  AuthenticationStatus = 0;

+

+  //

+  // get security PPI instance from PEI private data

+  //

+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);

+

+  if (PrivateData->PrivateSecurityPpi == NULL) {

+    Status = EFI_NOT_FOUND;

+  } else {

+    //

+    // Check to see if the image is OK

+    //

+    Status = PrivateData->PrivateSecurityPpi->AuthenticationState (

+                                                PeiServices,

+                                                PrivateData->PrivateSecurityPpi,

+                                                AuthenticationStatus,

+                                                CurrentPeimAddress,

+                                                &StartCrisisRecovery

+                                                );

+    if (StartCrisisRecovery) {

+      Status = EFI_SECURITY_VIOLATION;

+    }

+  }

+  return Status;

+}

+

+

+EFI_STATUS

+VerifyFv (

+  IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress

+  )

+/*++

+

+Routine Description:

+

+  Verify a Firmware volume

+

+Arguments:

+

+  CurrentFvAddress - Pointer to the current Firmware Volume under consideration

+

+Returns:

+

+  EFI_SUCCESS             - Firmware Volume is legal

+  EFI_SECURITY_VIOLATION  - Firmware Volume fails integrity test

+

+--*/

+{

+  //

+  // Right now just pass the test.  Future can authenticate and/or check the

+  // FV-header or other metric for goodness of binary.

+  //

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Core/Pei/StatusCode/StatusCode.c b/edk2/EdkModulePkg/Core/Pei/StatusCode/StatusCode.c
new file mode 100644
index 0000000..496effa
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/StatusCode/StatusCode.c
@@ -0,0 +1,95 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StatusCode.c

+

+Abstract:

+

+  Pei Core Status Code Support

+

+Revision History

+

+--*/

+

+#include <PeiMain.h>

+

+EFI_STATUS

+EFIAPI

+PeiReportStatusCode (

+  IN EFI_PEI_SERVICES         **PeiServices,

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value, 

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId,

+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Core version of the Status Code reporter

+

+Arguments:

+

+  PeiServices - The PEI core services table.

+  

+  CodeType    - Type of Status Code.

+  

+  Value       - Value to output for Status Code.

+  

+  Instance    - Instance Number of this status code.

+  

+  CallerId    - ID of the caller of this status code.

+  

+  Data        - Optional data associated with this status code.

+

+Returns:

+

+  Status  - EFI_SUCCESS             if status code is successfully reported

+          - EFI_NOT_AVAILABLE_YET   if StatusCodePpi has not been installed

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_PEI_PROGRESS_CODE_PPI *StatusCodePpi;

+  

+

+  //

+  //Locate StatusCode Ppi.

+  //

+  Status = PeiCoreLocatePpi (

+             &gEfiPeiStatusCodePpiGuid,         

+             0,                         

+             NULL,                      

+             (VOID **)&StatusCodePpi                  

+             );

+

+  if (!EFI_ERROR (Status)) {

+    Status = StatusCodePpi->ReportStatusCode (

+                            PeiServices,

+                            CodeType,

+                            Value,

+                            Instance,

+                            CallerId,

+                            Data

+                            );

+ 

+   return Status;   

+  } 

+  

+  

+  return  EFI_NOT_AVAILABLE_YET; 

+}

+

+

+

diff --git a/edk2/EdkModulePkg/Core/Pei/build.xml b/edk2/EdkModulePkg/Core/Pei/build.xml
new file mode 100644
index 0000000..8ffb689
--- /dev/null
+++ b/edk2/EdkModulePkg/Core/Pei/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiMain"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Core/Pei"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiMain">

+      <GenBuild baseName="PeiMain" mbdFilename="${MODULE_DIR}/PeiMain.mbd" msaFilename="${MODULE_DIR}/PeiMain.msa"/>

+   </target>

+   <target depends="PeiMain_clean" name="clean"/>

+   <target depends="PeiMain_cleanall" name="cleanall"/>

+   <target name="PeiMain_clean">

+      <OutputDirSetup baseName="PeiMain" mbdFilename="${MODULE_DIR}/PeiMain.mbd" msaFilename="${MODULE_DIR}/PeiMain.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiMain_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiMain_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiMain_cleanall">

+      <OutputDirSetup baseName="PeiMain" mbdFilename="${MODULE_DIR}/PeiMain.mbd" msaFilename="${MODULE_DIR}/PeiMain.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiMain_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiMain_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiMain*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/EdkModulePkg-All-Archs.fpd b/edk2/EdkModulePkg/EdkModulePkg-All-Archs.fpd
new file mode 100644
index 0000000..dd4b712
--- /dev/null
+++ b/edk2/EdkModulePkg/EdkModulePkg-All-Archs.fpd
@@ -0,0 +1,28265 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<FrameworkPlatformDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <PlatformHeader>

+    <PlatformName>EdkModuleAll</PlatformName>

+    <GuidValue>dc967761-e6e9-4d1a-b02c-818102db4cc6</GuidValue>

+    <Version>0.3</Version>

+    <Abstract>EFI/Framework Reference Module Package for All Architectures</Abstract>

+    <Description>This FPD file is used for Package Level build.</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-02-24 14:49</CreatedDate>

+    <ModifiedDate>2006-06-03 22:14</ModifiedDate>

+    <BuildTarget>BOTH</BuildTarget>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </PlatformHeader>

+  <Flash>

+    <FlashDefinitionFile>dummy.fdf</FlashDefinitionFile>

+  </Flash>

+  <TianoImage>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+    </DXE_DRIVERS>

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Partition" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="English" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIo" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIoPartition" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SecurityStub" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMain" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMain" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIpl" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="GraphicsConsole" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Runtime" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="MonotonicCounter" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Variable" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="EmuVariable" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="StatusCode" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiVariable" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="WatchDogTimer" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="FtwLite" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugPort" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugSupport" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Terminal" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHub" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHubStdErr" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="NullMemoryTest" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiDatabase" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ConSplitter" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BC" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Dhcp4" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SNP" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Ebc" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SetupBrowser" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DriverSample" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PciBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="AtapiPassThru" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="IdeBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Uhci" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiDisk" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBot" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi0" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi1" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbKb" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMassStorage" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMouse" />

+      <!-- X64 -->

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="HelloWorld" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Partition" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="English" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DiskIo" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DiskIoPartition" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="SecurityStub" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeMain" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiMain" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeIpl" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="GraphicsConsole" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Runtime" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="MonotonicCounter" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Variable" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="EmuVariable" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="StatusCode" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiVariable" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="WatchDogTimer" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="FtwLite" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DebugPort" />

+      <!--

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DebugSupport" />

+      -->

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Terminal" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DataHub" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DataHubStdErr" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="NullMemoryTest" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="HiiDatabase" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="ConSplitter" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BC" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Dhcp4" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="SNP" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Ebc" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="SetupBrowser" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DriverSample" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PciBus" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="AtapiPassThru" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="IdeBus" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Uhci" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="ScsiBus" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="ScsiDisk" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbBot" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbBus" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbCbi0" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbCbi1" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbKb" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbMassStorage" />

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbMouse" />

+      <!-- IFP -->

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="HelloWorld" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Partition" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="English" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DiskIo" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DiskIoPartition" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="SecurityStub" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeMain" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiMain" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeIpl" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="GraphicsConsole" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Runtime" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="MonotonicCounter" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Variable" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="EmuVariable" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="StatusCode" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiVariable" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="WatchDogTimer" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="FtwLite" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DebugPort" />

+

+      <!--

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DebugSupport" />

+      -->

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Terminal" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DataHub" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DataHubStdErr" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="NullMemoryTest" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="HiiDatabase" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="ConSplitter" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BC" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Dhcp4" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="SNP" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Ebc" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="SetupBrowser" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DriverSample" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PciBus" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="AtapiPassThru" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="IdeBus" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Uhci" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="ScsiBus" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="ScsiDisk" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbBot" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbBus" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbCbi0" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbCbi1" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbKb" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbMassStorage" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbMouse" />

+

+      <!-- EBC -->

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="HelloWorld" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Partition" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="English" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DiskIo" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DiskIoPartition" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="SecurityStub" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeMain" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiMain" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeIpl" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="GraphicsConsole" />

+

+      <!-- Not Support 

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Runtime" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="MonotonicCounter" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Variable" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="EmuVariable" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="StatusCode" />

+      -->

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiVariable" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="WatchDogTimer" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="FtwLite" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DebugPort" />

+

+      <!--

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DebugSupport" />

+      -->

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Terminal" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DataHub" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DataHubStdErr" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="NullMemoryTest" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="HiiDatabase" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="ConSplitter" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BC" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Dhcp4" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="SNP" />

+

+      <!--

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Ebc" />

+      -->

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="SetupBrowser" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DriverSample" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PciBus" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="AtapiPassThru" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" />

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="IdeBus" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Uhci" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="ScsiBus" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="ScsiDisk" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbBot" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbBus" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbCbi0" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbCbi1" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbKb" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbMassStorage" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbMouse" />

+    </OTHER_COMPONENTS>

+  </TianoImage>

+  <FrameworkModules>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdDxe">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdVpdBaseAddress</C_Name>

+            <Token>0x00010010</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </DXE_DRIVERS>

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Partition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="English" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIo" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIoPartition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SecurityStub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIpl" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="GraphicsConsole" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Runtime" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="MonotonicCounter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Variable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="EmuVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="StatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PcdPeim" >

+        <PcdBuildDeclarations>

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+              <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+              <Token>0x0001000f</Token>

+              <DatumType>UINT32</DatumType>

+              <HiiEnable>false</HiiEnable>

+              <VpdEnable>false</VpdEnable>

+              <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+              <SkuEnable>false</SkuEnable>

+              <SkuDataArrayEnable>false</SkuDataArrayEnable>

+              <MaxSku>0</MaxSku>

+              <SkuId>0</SkuId>

+              <DatumSize>4</DatumSize>

+              <VariableGuid>0</VariableGuid>

+              <VariableName>L""</VariableName>

+              <DataOffset>0</DataOffset>

+              <DefaultValue>0x08</DefaultValue>

+            </PcdBuildData>           

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+             <C_Name>PcdVpdBaseAddress</C_Name>

+                <Token>0x00010010</Token>

+                <DatumType>UINT32</DatumType>

+                <HiiEnable>false</HiiEnable>

+                <VpdEnable>false</VpdEnable>

+                <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+                <SkuEnable>false</SkuEnable>

+                <SkuDataArrayEnable>false</SkuDataArrayEnable>

+                <MaxSku>0</MaxSku>

+                <SkuId>0</SkuId>

+                <DatumSize>4</DatumSize>

+                <VariableGuid>0</VariableGuid>

+                <VariableName>L""</VariableName>

+                <DataOffset>0</DataOffset>

+                <DefaultValue>0x10000000</DefaultValue>

+            </PcdBuildData>           

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="WatchDogTimer" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="FtwLite" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugPort" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugSupport" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Terminal" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHubStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="NullMemoryTest" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiDatabase" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ConSplitter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BC" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Dhcp4" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SNP" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Ebc" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SetupBrowser" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DriverSample" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PciBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="AtapiPassThru" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="IdeBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Uhci" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiDisk" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBot" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi0" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi1" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbKb" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMassStorage" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMouse" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      

+      <!-- X64 -->

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Partition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="English" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DiskIo" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DiskIoPartition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="SecurityStub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeIpl" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="GraphicsConsole" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Runtime" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="MonotonicCounter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Variable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="EmuVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="StatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PcdPeim" >

+        <PcdBuildDeclarations>

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+              <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+              <Token>0x0001000f</Token>

+              <DatumType>UINT32</DatumType>

+              <HiiEnable>false</HiiEnable>

+              <VpdEnable>false</VpdEnable>

+              <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+              <SkuEnable>false</SkuEnable>

+              <SkuDataArrayEnable>false</SkuDataArrayEnable>

+              <MaxSku>0</MaxSku>

+              <SkuId>0</SkuId>

+              <DatumSize>4</DatumSize>

+              <VariableGuid>0</VariableGuid>

+              <VariableName>L""</VariableName>

+              <DataOffset>0</DataOffset>

+              <DefaultValue>0x08</DefaultValue>

+            </PcdBuildData>           

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+             <C_Name>PcdVpdBaseAddress</C_Name>

+                <Token>0x00010010</Token>

+                <DatumType>UINT32</DatumType>

+                <HiiEnable>false</HiiEnable>

+                <VpdEnable>false</VpdEnable>

+                <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+                <SkuEnable>false</SkuEnable>

+                <SkuDataArrayEnable>false</SkuDataArrayEnable>

+                <MaxSku>0</MaxSku>

+                <SkuId>0</SkuId>

+                <DatumSize>4</DatumSize>

+                <VariableGuid>0</VariableGuid>

+                <VariableName>L""</VariableName>

+                <DataOffset>0</DataOffset>

+                <DefaultValue>0x10000000</DefaultValue>

+            </PcdBuildData>           

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="WatchDogTimer" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="FtwLite" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DebugPort" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <!--

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DebugSupport" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      -->

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Terminal" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DataHub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DataHubStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="NullMemoryTest" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="HiiDatabase" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="ConSplitter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BC" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Dhcp4" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="SNP" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Ebc" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="SetupBrowser" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DriverSample" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PciBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="AtapiPassThru" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="IdeBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="Uhci" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="ScsiBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="ScsiDisk" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbBot" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbCbi0" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbCbi1" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbKb" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbMassStorage" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UsbMouse" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+

+      <!-- IPF -->

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Partition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="English" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DiskIo" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DiskIoPartition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="SecurityStub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeIpl" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="GraphicsConsole" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Runtime" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="MonotonicCounter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Variable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="EmuVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="StatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PcdPeim" >

+        <PcdBuildDeclarations>

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+              <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+              <Token>0x0001000f</Token>

+              <DatumType>UINT32</DatumType>

+              <HiiEnable>false</HiiEnable>

+              <VpdEnable>false</VpdEnable>

+              <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+              <SkuEnable>false</SkuEnable>

+              <SkuDataArrayEnable>false</SkuDataArrayEnable>

+              <MaxSku>0</MaxSku>

+              <SkuId>0</SkuId>

+              <DatumSize>4</DatumSize>

+              <VariableGuid>0</VariableGuid>

+              <VariableName>L""</VariableName>

+              <DataOffset>0</DataOffset>

+              <DefaultValue>0x08</DefaultValue>

+            </PcdBuildData>           

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+             <C_Name>PcdVpdBaseAddress</C_Name>

+                <Token>0x00010010</Token>

+                <DatumType>UINT32</DatumType>

+                <HiiEnable>false</HiiEnable>

+                <VpdEnable>false</VpdEnable>

+                <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+                <SkuEnable>false</SkuEnable>

+                <SkuDataArrayEnable>false</SkuDataArrayEnable>

+                <MaxSku>0</MaxSku>

+                <SkuId>0</SkuId>

+                <DatumSize>4</DatumSize>

+                <VariableGuid>0</VariableGuid>

+                <VariableName>L""</VariableName>

+                <DataOffset>0</DataOffset>

+                <DefaultValue>0x10000000</DefaultValue>

+            </PcdBuildData>           

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="WatchDogTimer" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="FtwLite" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DebugPort" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <!--

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DebugSupport" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>   

+      -->   

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Terminal" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DataHub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DataHubStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="NullMemoryTest" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="HiiDatabase" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="ConSplitter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BC" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Dhcp4" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="SNP" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Ebc" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="SetupBrowser" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DriverSample" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PciBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="AtapiPassThru" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="IdeBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="Uhci" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="ScsiBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="ScsiDisk" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbBot" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbCbi0" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbCbi1" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbKb" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbMassStorage" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UsbMouse" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+

+      <!-- EBC -->

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Partition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="English" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DiskIo" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DiskIoPartition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="SecurityStub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeIpl" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="GraphicsConsole" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <!-- Not Support

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Runtime" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="MonotonicCounter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Variable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="EmuVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="StatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>     

+      --> 

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PcdPeim" >

+        <PcdBuildDeclarations>

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+              <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+              <Token>0x0001000f</Token>

+              <DatumType>UINT32</DatumType>

+              <HiiEnable>false</HiiEnable>

+              <VpdEnable>false</VpdEnable>

+              <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+              <SkuEnable>false</SkuEnable>

+              <SkuDataArrayEnable>false</SkuDataArrayEnable>

+              <MaxSku>0</MaxSku>

+              <SkuId>0</SkuId>

+              <DatumSize>4</DatumSize>

+              <VariableGuid>0</VariableGuid>

+              <VariableName>L""</VariableName>

+              <DataOffset>0</DataOffset>

+              <DefaultValue>0x08</DefaultValue>

+            </PcdBuildData>           

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+             <C_Name>PcdVpdBaseAddress</C_Name>

+                <Token>0x00010010</Token>

+                <DatumType>UINT32</DatumType>

+                <HiiEnable>false</HiiEnable>

+                <VpdEnable>false</VpdEnable>

+                <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+                <SkuEnable>false</SkuEnable>

+                <SkuDataArrayEnable>false</SkuDataArrayEnable>

+                <MaxSku>0</MaxSku>

+                <SkuId>0</SkuId>

+                <DatumSize>4</DatumSize>

+                <VariableGuid>0</VariableGuid>

+                <VariableName>L""</VariableName>

+                <DataOffset>0</DataOffset>

+                <DefaultValue>0x10000000</DefaultValue>

+            </PcdBuildData>           

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="WatchDogTimer" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="FtwLite" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DebugPort" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <!-- 

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DebugSupport" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>  

+      -->    

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Terminal" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DataHub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DataHubStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="NullMemoryTest" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="HiiDatabase" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="ConSplitter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BC" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Dhcp4" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="SNP" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <!--

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Ebc" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA> 

+      -->     

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="SetupBrowser" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DriverSample" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PciBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="AtapiPassThru" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="IdeBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="Uhci" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="ScsiBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="ScsiDisk" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbBot" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbCbi0" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbCbi1" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbKb" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbMassStorage" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UsbMouse" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </OTHER_COMPONENTS>

+  </FrameworkModules>

+  <BuildOptions>

+    <OutputDirectory IntermediateDirectories="UNIFIED"/>

+  </BuildOptions>

+</FrameworkPlatformDescription>

diff --git a/edk2/EdkModulePkg/EdkModulePkg.fpd b/edk2/EdkModulePkg/EdkModulePkg.fpd
new file mode 100644
index 0000000..02f7e35
--- /dev/null
+++ b/edk2/EdkModulePkg/EdkModulePkg.fpd
@@ -0,0 +1,7960 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<FrameworkPlatformDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <PlatformHeader>

+    <PlatformName>EdkModule</PlatformName>

+    <GuidValue>dbb0551f-a04b-4038-9303-e60998023c8d</GuidValue>

+    <Version>0.3</Version>

+    <Abstract>EFI/Tiano Edk Module Reference Designs Package</Abstract>

+    <Description>This FPD file is used for Package Level build.</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-02-24 14:49</CreatedDate>

+    <ModifiedDate>2006-06-01 17:59</ModifiedDate>

+    <BuildTarget>DEBUG</BuildTarget>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>

+  </PlatformHeader>

+  <Flash>

+    <FlashDefinitionFile>dummy.fdf</FlashDefinitionFile>

+  </Flash>

+  <TianoImage>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld"/>

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld"/>

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld"/>

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld"/>

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdDxe"/>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld"/>

+    </DXE_DRIVERS>

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Partition" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="English" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIo" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIoPartition" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SecurityStub" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMain" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMain" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIpl" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="GraphicsConsole" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Runtime" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="MonotonicCounter" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Variable" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="EmuVariable" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="StatusCode" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PcdPeim" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiVariable" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="WatchDogTimer" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="FtwLite" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugPort" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugSupport" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Terminal" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHub" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHubStdErr" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="NullMemoryTest" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiDatabase" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ConSplitter" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BC" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Dhcp4" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SNP" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Ebc" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SetupBrowser" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DriverSample" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PciBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="AtapiPassThru" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="IdeBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Uhci" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiDisk" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBot" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBus" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi0" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi1" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbKb" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMassStorage" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMouse" />

+    </OTHER_COMPONENTS>

+  </TianoImage>

+  <FrameworkModules>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdDxe">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdVpdBaseAddress</C_Name>

+            <Token>0x00010010</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </DXE_DRIVERS>

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HelloWorld" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Partition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="English" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIo" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DiskIoPartition" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SecurityStub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMain" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIpl" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="GraphicsConsole" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Runtime" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="MonotonicCounter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Variable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="EmuVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="StatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiBaseMemoryTestInit" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PcdPeim" >

+        <PcdBuildDeclarations>

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+              <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+              <Token>0x0001000f</Token>

+              <DatumType>UINT32</DatumType>

+              <HiiEnable>false</HiiEnable>

+              <VpdEnable>false</VpdEnable>

+              <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+              <SkuEnable>false</SkuEnable>

+              <SkuDataArrayEnable>false</SkuDataArrayEnable>

+              <MaxSku>0</MaxSku>

+              <SkuId>0</SkuId>

+              <DatumSize>4</DatumSize>

+              <VariableGuid>0</VariableGuid>

+              <VariableName>L""</VariableName>

+              <DataOffset>0</DataOffset>

+              <DefaultValue>0x08</DefaultValue>

+            </PcdBuildData>           

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+             <C_Name>PcdVpdBaseAddress</C_Name>

+                <Token>0x00010010</Token>

+                <DatumType>UINT32</DatumType>

+                <HiiEnable>false</HiiEnable>

+                <VpdEnable>false</VpdEnable>

+                <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+                <SkuEnable>false</SkuEnable>

+                <SkuDataArrayEnable>false</SkuDataArrayEnable>

+                <MaxSku>0</MaxSku>

+                <SkuId>0</SkuId>

+                <DatumSize>4</DatumSize>

+                <VariableGuid>0</VariableGuid>

+                <VariableName>L""</VariableName>

+                <DataOffset>0</DataOffset>

+                <DefaultValue>0x10000000</DefaultValue>

+            </PcdBuildData>           

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiVariable" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="WatchDogTimer" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="FtwLite" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugPort" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugSupport" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Terminal" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHub" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DataHubStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="NullMemoryTest" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiDatabase" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ConSplitter" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BC" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Dhcp4" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SNP" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Ebc" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SetupBrowser" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DriverSample" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PciBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="AtapiPassThru" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="CirrusLogic5430UgaDraw" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="IdeBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="Uhci" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="ScsiDisk" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBot" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbBus" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi0" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbCbi1" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbKb" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMassStorage" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UsbMouse" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <TokenSpaceGuid>866baf87-e00c-4dc6-9733-1e23af2115ee</TokenSpaceGuid>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <TokenSpaceGuid>f1a9de0d-f005-45c4-bdb5-5ec0fb468316</TokenSpaceGuid>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>      

+    </OTHER_COMPONENTS>

+  </FrameworkModules>

+  <BuildOptions>

+    <OutputDirectory IntermediateDirectories="UNIFIED"/>

+  </BuildOptions>

+</FrameworkPlatformDescription>

diff --git a/edk2/EdkModulePkg/EdkModulePkg.spd b/edk2/EdkModulePkg/EdkModulePkg.spd
new file mode 100644
index 0000000..1409f10
--- /dev/null
+++ b/edk2/EdkModulePkg/EdkModulePkg.spd
@@ -0,0 +1,720 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <SpdHeader>
+    <PackageName>EdkModulePkg</PackageName>
+    <Guid>0xb6ec423c, 0x21d2, 0x490d, 0x85, 0xc6, 0xdd, 0x58, 0x64, 0xea, 0xa6, 0x74</Guid>
+    <Version>0.3</Version>
+    <Abstract>Edk Module Package Reference Implementations</Abstract>
+    <Description>This Module provides standard reference information for EFI/Tiano implementations.</Description>
+    <Copyright>Copyright (c) 2006,  Intel Corporation.</Copyright>
+    <License>
+      All rights reserved.
+      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.
+    </License>
+    <Created>2006-02-21 17:43</Created>
+    <Updated>2006-03-19 16:26</Updated>
+    <URL>http://www.TianoCore.org</URL>
+    <PackageType>SOURCE</PackageType>
+    <ReadOnly>true</ReadOnly>
+    <RePackage>false</RePackage>
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>
+  </SpdHeader>
+  <LibraryClassDeclarations>
+    <LibraryClassDeclaration>
+      <LibraryClass>CustomDecompressLib</LibraryClass>
+      <IncludeHeader>Include/Library/CustomDecompressLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkBsDataHubStatusCodeLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkBsDataHubStatusCodeLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkDxeSalLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkDxeSalLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkFvbServiceLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkFvbServiceLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkGraphicsLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkGraphicsLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkIfrSupportLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkIfrSupportLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkMemoryStatusCodeLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkMemoryStatusCodeLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkPeCoffLoaderLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkPeCoffLoaderLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkPeCoffLoaderX64Lib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkPeCoffLoaderX64Lib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkRtMemoryStatusCodeLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkRtMemoryStatusCodeLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkRtPlatformStatusCodeLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkRtPlatformStatusCodeLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkScsiLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkScsiLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>EdkUsbLib</LibraryClass>
+      <IncludeHeader>Include/Library/EdkUsbLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+    <LibraryClassDeclaration>
+      <LibraryClass>TianoDecompressLib</LibraryClass>
+      <IncludeHeader>Include/Library/TianoDecompressLib.h</IncludeHeader>
+    </LibraryClassDeclaration>
+  </LibraryClassDeclarations>
+  <MsaFiles>
+    <MsaFile>
+      <Filename>Application/HelloWorld/HelloWorld.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/IdeBus/Dxe/idebus.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/IdeBus/Dxe/idebusLite.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/PciBus/Dxe/LightPciBus.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/PciBus/Dxe/PciBus.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/PciBus/Dxe/PciBusLite.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/Uhci/Dxe/Uhci.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Pci/Undi/RuntimeDxe/Undi.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbBot/Dxe/UsbBot.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbBus/Dxe/UsbBus.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbCbi/Dxe/Cbi0/UsbCbi0.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbCbi/Dxe/Cbi1/UsbCbi1.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbKb/Dxe/UsbKb.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbMassStorage/Dxe/UsbMassStorage.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Bus/Usb/UsbMouse/Dxe/UsbMouse.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Core/Dxe/DxeMain.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Core/DxeIplPeim/DxeIpl.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Core/DxeIplPeim/DxeIplX64.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Core/Pei/PeiMain.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkDxePerformanceLib/EdkDxePerformanceLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkDxePrintLib/EdkDxePrintLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkDxeSalLib/EdkDxeSalLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkFvbServiceLib/EdkFvbServiceLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkGraphicsLib/EdkGraphicsLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkIfrSupportLib/EdkIfrSupportLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkScsiLib/EdkScsiLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Library/EdkUsbLib/EdkUsbLib.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Console/ConSplitter/Dxe/ConSplitter.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Console/Terminal/Dxe/Terminal.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/DataHub/DataHub/Dxe/DataHub.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Debugger/Debugport/Dxe/DebugPort.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/DebugSupport/Dxe/DebugSupport.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Disk/DiskIo/Dxe/DiskIo.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Disk/Partition/Dxe/Partition.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Disk/UnicodeCollation/English/Dxe/English.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Ebc/Dxe/Ebc.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/GenericMemoryTest/Dxe/NullMemoryTest.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/GenericMemoryTest/Pei/BaseMemoryTest.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Network/PxeBc/Dxe/BC.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Network/PxeDhcp4/Dxe/Dhcp4.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Network/Snp32_64/Dxe/SNP.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/PCD/Pei/Pcd.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/PCD/Test/PeiPcdTest.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/PCD/Dxe/Pcd.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Runtime/RuntimeDxe/Runtime.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Security/SecurityStub/Dxe/SecurityStub.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/StatusCode/RuntimeDxe/StatusCode.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Variable/Pei/Variable.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/EmuVariable/RuntimeDxe/EmuVariable.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/Variable/RuntimeDxe/Variable.msa</Filename>
+    </MsaFile>
+    <MsaFile>
+      <Filename>Universal/WatchdogTimer/Dxe/WatchDogTimer.msa</Filename>
+    </MsaFile>
+  </MsaFiles>
+  <PackageHeaders>
+    <IncludeHeader ModuleType="SEC">Include/EdkPeim.h</IncludeHeader>
+    <IncludeHeader ModuleType="PEI_CORE">Include/EdkPeiCore.h</IncludeHeader>
+    <IncludeHeader ModuleType="PEIM">Include/EdkPeim.h</IncludeHeader>
+    <IncludeHeader ModuleType="DXE_CORE">Include/EdkDxeCore.h</IncludeHeader>
+    <IncludeHeader ModuleType="DXE_DRIVER">Include/EdkDxe.h</IncludeHeader>
+    <IncludeHeader ModuleType="DXE_RUNTIME_DRIVER">Include/EdkDxe.h</IncludeHeader>
+    <IncludeHeader ModuleType="DXE_SMM_DRIVER">Include/EdkDxe.h</IncludeHeader>
+    <IncludeHeader ModuleType="DXE_SAL_DRIVER">Include/EdkDxe.h</IncludeHeader>
+    <IncludeHeader ModuleType="UEFI_DRIVER">Include/EdkDxe.h</IncludeHeader>
+  </PackageHeaders>
+  <GuidDeclarations>
+    <Entry Name="PcdDataBaseHob">
+      <C_Name>gPcdDataBaseHobGuid</C_Name>
+      <Guid>0xea296d92, 0xb69,  0x423c, 0x8c, 0x28, 0x33, 0xb4, 0xe0, 0xa9, 0x12, 0x68</Guid>
+    </Entry>
+    <Entry Name="PcdPeiCallbackFnTable">
+      <C_Name>gPcdPeiCallbackFnTableHobGuid</C_Name>
+      <Guid>0xc625f4b2, 0xea09, 0x4675, 0x82, 0xd7, 0xba, 0x36, 0x82, 0x15, 0x7a, 0x14</Guid>
+    </Entry>
+    <Entry Name="PeiPeCoffLoader">
+      <C_Name>gEfiPeiPeCoffLoaderGuid</C_Name>
+      <Guid>0xd8117cff, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Entry>
+    <Entry Name="FlashMapHob">
+      <C_Name>gEfiFlashMapHobGuid</C_Name>
+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>
+    </Entry>
+    <Entry Name="StatusCodeDataTypeString">
+      <C_Name>gEfiStatusCodeDataTypeStringGuid</C_Name>
+      <Guid>0x92D11080, 0x496F, 0x4D95, 0xBE, 0x7E, 0x03, 0x74, 0x88, 0x38, 0x2B, 0x0A</Guid>
+    </Entry>
+    <Entry Name="StatusCodeDataTypeDebug">
+      <C_Name>gEfiStatusCodeDataTypeDebugGuid</C_Name>
+      <Guid>0x9A4E9246, 0xD553, 0x11D5, 0x87, 0xE2, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xb9</Guid>
+    </Entry>
+    <Entry Name="StatusCodeDataTypeAssert">
+      <C_Name>gEfiStatusCodeDataTypeAssertGuid</C_Name>
+      <Guid>0xDA571595, 0x4D99, 0x487C, 0x82, 0x7C, 0x26, 0x22, 0x67, 0x7D, 0x33, 0x07</Guid>
+    </Entry>
+    <Entry Name="StatusCodeDataTypeExceptionHandler">
+      <C_Name>gEfiStatusCodeDataTypeExceptionHandlerGuid</C_Name>
+      <Guid>0x3BC2BD12, 0xAD2E, 0x11D5, 0x87, 0xDD, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9</Guid>
+    </Entry>
+    <Entry Name="StatusCodeDataTypeError">
+      <C_Name>gEfiStatusCodeDataTypeErrorGuid</C_Name>
+      <Guid>0xAB359CE3, 0x99B3, 0xAE18, 0xC8, 0x9D, 0x95, 0xD3, 0xB0, 0x72, 0xE1, 0x9B</Guid>
+    </Entry>
+    <Entry Name="StatusCodeDataTypeProgressCode">
+      <C_Name>gEfiStatusCodeDataTypeProgressCodeGuid</C_Name>
+      <Guid>0xA356AB39, 0x35C4, 0x35DA, 0xB3, 0x7A, 0xF8, 0xEA, 0x9E, 0x8B, 0x36, 0xA3</Guid>
+    </Entry>
+    <Entry Name="StatusCodeSpecificData">
+      <C_Name>gEfiStatusCodeSpecificDataGuid</C_Name>
+      <Guid>0x335984bd, 0xe805, 0x409a, 0xb8, 0xf8, 0xd2, 0x7e, 0xce, 0x5f, 0xf7, 0xa6</Guid>
+    </Entry>
+    <Entry Name="SystemNvDataHob">
+      <C_Name>gEfiSystemNvDataHobGuid</C_Name>
+      <Guid>0xd6e5092d, 0xc7b2, 0x4872, 0xaf, 0x66, 0xfd, 0xc0, 0xe6, 0xf9, 0x5e, 0x78</Guid>
+    </Entry>
+    <Entry Name="SystemNvDataFv">
+      <C_Name>gEfiSystemNvDataFvGuid</C_Name>
+      <Guid>0xfff12b8d, 0x7696, 0x4c8b, 0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50</Guid>
+    </Entry>
+    <Entry Name="DiskInfoIde">
+      <C_Name>gEfiDiskInfoIdeInterfaceGuid</C_Name>
+      <Guid>0x5e948fe3, 0x26d3, 0x42b5, 0xaf, 0x17, 0x61, 0x02, 0x87, 0x18, 0x8d, 0xec</Guid>
+    </Entry>
+    <Entry Name="DiskInfoScsi">
+      <C_Name>gEfiDiskInfoScsiInterfaceGuid</C_Name>
+      <Guid>0x8f74baa, 0xea36, 0x41d9, 0x95, 0x21, 0x21, 0xa7, 0x0f, 0x87, 0x80, 0xbc</Guid>
+    </Entry>
+    <Entry Name="DiskInfoUsb">
+      <C_Name>gEfiDiskInfoUsbInterfaceGuid</C_Name>
+      <Guid>0xcb871572, 0xc11a, 0x47b5, 0xb4, 0x92, 0x67, 0x5e, 0xaf, 0xa7, 0x77, 0x27</Guid>
+    </Entry>
+    <Entry Name="AlternateFvBlock">
+      <C_Name>gEfiAlternateFvBlockGuid</C_Name>
+      <Guid>0xf496922d, 0x172f, 0x4bbc, 0xa1, 0xeb, 0x0e, 0xeb, 0x94, 0x9c, 0x34, 0x86</Guid>
+    </Entry>
+    <Entry Name="ConsoleInDevice">
+      <C_Name>gEfiConsoleInDeviceGuid</C_Name>
+      <Guid>0xd3b36f2b, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Entry>
+    <Entry Name="ConsoleOutDevice">
+      <C_Name>gEfiConsoleOutDeviceGuid</C_Name>
+      <Guid>0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Entry>
+    <Entry Name="StandardErrorDevice">
+      <C_Name>gEfiStandardErrorDeviceGuid</C_Name>
+      <Guid>0xd3b36f2d, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Entry>
+    <Entry Name="HotPlugDevice">
+      <C_Name>gEfiHotPlugDeviceGuid</C_Name>
+      <Guid>0x220ac432, 0x1d43, 0x49e5, 0xa7, 0x4f, 0x4c, 0x9d, 0xa6, 0x7a, 0xd2, 0x3b</Guid>
+    </Entry>
+    <Entry Name="PrimaryStandardErrorDevice">
+      <C_Name>gEfiPrimaryStandardErrorDeviceGuid</C_Name>
+      <Guid>0x5a68191b, 0x9b97, 0x4752, 0x99, 0x46, 0xe3, 0x6a, 0x5d, 0xa9, 0x42, 0xb1</Guid>
+    </Entry>
+    <Entry Name="PrimaryConsoleInDevice">
+      <C_Name>gEfiPrimaryConsoleInDeviceGuid</C_Name>
+      <Guid>0xe451dcbe, 0x96a1, 0x4729, 0xa5, 0xcf, 0x6b, 0x9c, 0x2c, 0xff, 0x47, 0xfd</Guid>
+    </Entry>
+    <Entry Name="PrimaryConsoleOutDevice">
+      <C_Name>gEfiPrimaryConsoleOutDeviceGuid</C_Name>
+      <Guid>0x62bdf38a, 0xe3d5, 0x492c, 0x95, 0x0c, 0x23, 0xa7, 0xf6, 0x6e, 0x67, 0x2e</Guid>
+    </Entry>
+    <Entry Name="Bmp">
+      <C_Name>gEfiDefaultBmpLogoGuid</C_Name>
+      <Guid>0x7BB28B99, 0x61BB, 0x11d5, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>
+    </Entry>
+    <Entry Name="BootState">
+      <C_Name>gEfiBootStateGuid</C_Name>
+      <Guid>0x60b5e939, 0xfcf, 0x4227, 0xba, 0x83, 0x6b, 0xbe, 0xd4, 0x5b, 0xc0, 0xe3</Guid>
+    </Entry>
+    <Entry Name="ShellFile">
+      <C_Name>gEfiShellFileGuid</C_Name>
+      <Guid>0xc57ad6b7, 0x0515, 0x40a8, 0x9d, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4e, 0x37</Guid>
+    </Entry>
+    <Entry Name="MiniShellFile">
+      <C_Name>gEfiMiniShellFileGuid</C_Name>
+      <Guid>0x86ad232b, 0xd33a, 0x465c, 0xbf, 0x5f, 0x41, 0x37, 0x0b, 0xa9, 0x2f, 0xe2</Guid>
+    </Entry>
+    <Entry Name="StatusCode">
+      <C_Name>gEfiStatusCodeGuid</C_Name>
+      <Guid>0xd083e94c, 0x6560, 0x42e4, 0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a</Guid>
+    </Entry>
+    <Entry Name="PciOptionRomTable">
+      <C_Name>gEfiPciOptionRomTableGuid</C_Name>
+      <Guid>0x7462660f, 0x1cbd, 0x48da, 0xad, 0x11, 0x91, 0x71, 0x79, 0x13, 0x83, 0x1c</Guid>
+    </Entry>
+    <Entry Name="PciHotplugDevice">
+      <C_Name>gEfiPciHotplugDeviceGuid</C_Name>
+      <Guid>0x0b280816, 0x52e7, 0x4e51, 0xaa, 0x57, 0x11, 0xbd, 0x41, 0xcb, 0xef, 0xc3</Guid>
+    </Entry>
+    <Entry Name="MemoryTypeInformation">
+      <C_Name>gEfiMemoryTypeInformationGuid</C_Name>
+      <Guid>0x4c19049f, 0x4137, 0x4dd3, 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa</Guid>
+    </Entry>
+    <Entry Name="CapsuleVendor">
+      <C_Name>gEfiCapsuleVendorGuid</C_Name>
+      <Guid>0x711C703F, 0xC285, 0x4B10, 0xA3, 0xB0, 0x36, 0xEC, 0xBD, 0x3C, 0x8B, 0xE2</Guid>
+    </Entry>
+    <Entry Name="CompatibleMemoryTested">
+      <C_Name>gEfiCompatibleMemoryTestedGuid</C_Name>
+      <Guid>0x64c475ef, 0x344b, 0x492c, 0x93, 0xad, 0xab, 0x9e, 0xb4, 0x39, 0x50, 0x4</Guid>
+    </Entry>
+    <Entry Name="PeiPerformanceHob">
+      <C_Name>gPeiPerformanceHobGuid</C_Name>
+      <Guid>0xec4df5af, 0x4395, 0x4cc9, 0x94, 0xde, 0x77, 0x50, 0x6d, 0x12, 0xc7, 0xb8</Guid>
+    </Entry>
+  </GuidDeclarations>
+  <ProtocolDeclarations>
+    <Entry Name="CustomizedDecompress">
+      <C_Name>gEfiCustomizedDecompressProtocolGuid</C_Name>
+      <Guid>0x9a44198e, 0xa4a2, 0x44e6, 0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f</Guid>
+    </Entry>
+    <Entry Name="DebugLevel">
+      <C_Name>gEfiDebugLevelProtocolGuid</C_Name>
+      <Guid>0x8d4c62e6, 0xcd98, 0x4e1d, 0xad, 0x6e, 0x48, 0xbb, 0x50, 0xd2, 0x9f, 0xf7</Guid>
+    </Entry>
+    <Entry Name="TianoDecompress">
+      <C_Name>gEfiTianoDecompressProtocolGuid</C_Name>
+      <Guid>0xe84cf29c, 0x191f, 0x4eae, 0x96, 0xe1, 0xf4, 0x6a, 0xec, 0xea, 0xea, 0x0b</Guid>
+    </Entry>
+    <Entry Name="LoadPeImage">
+      <C_Name>gEfiLoadPeImageProtocolGuid</C_Name>
+      <Guid>0x5cb5c776, 0x60d5, 0x45ee, 0x88, 0x3c, 0x45, 0x27, 0x08, 0xcd, 0x74, 0x3f</Guid>
+    </Entry>
+    <Entry Name="Print">
+      <C_Name>gEfiPrintProtocolGuid</C_Name>
+      <Guid>0xdf2d868e, 0x32fc, 0x4cf0, 0x8e, 0x6b, 0xff, 0xd9, 0x5d, 0x13, 0x43, 0xd0</Guid>
+    </Entry>
+    <Entry Name="GenericMemTest">
+      <C_Name>gEfiGenericMemTestProtocolGuid</C_Name>
+      <Guid>0x309de7f1, 0x7f5e, 0x4ace, 0xb4, 0x9c, 0x53, 0x1b, 0xe5, 0xaa, 0x95, 0xef</Guid>
+    </Entry>
+    <Entry Name="DiskInfo">
+      <C_Name>gEfiDiskInfoProtocolGuid</C_Name>
+      <Guid>0xd432a67f, 0x14dc, 0x484b, 0xb3, 0xbb, 0x3f, 0x02, 0x91, 0x84, 0x93, 0x27</Guid>
+    </Entry>
+    <Entry Name="FvbExtension">
+      <C_Name>gEfiFvbExtensionProtocolGuid</C_Name>
+      <Guid>0x53a4c71b, 0xb581, 0x4170, 0x91, 0xb3, 0x8d, 0xb8, 0x7a, 0x4b, 0x5c, 0x46</Guid>
+    </Entry>
+    <Entry Name="FaultTolerantWriteLite">
+      <C_Name>gEfiFaultTolerantWriteLiteProtocolGuid</C_Name>
+      <Guid>0x3f557189, 0x8dae, 0x45ae, 0xa0, 0xb3, 0x2b, 0x99, 0xca, 0x7a, 0xa7, 0xa0</Guid>
+    </Entry>
+    <Entry Name="ConsoleControl">
+      <C_Name>gEfiConsoleControlProtocolGuid</C_Name>
+      <Guid>0xf42f7782, 0x12e, 0x4c12, 0x99, 0x56, 0x49, 0xf9, 0x43, 0x04, 0xf7, 0x21</Guid>
+    </Entry>
+    <Entry Name="OEMBadging">
+      <C_Name>gEfiOEMBadgingProtocolGuid</C_Name>
+      <Guid>0x170e13c0, 0xbf1b, 0x4218, 0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87, 0xbc</Guid>
+    </Entry>
+    <Entry Name="UgaSplash">
+      <C_Name>gEfiUgaSplashProtocolGuid</C_Name>
+      <Guid>0xa45b3a0d, 0x2e55, 0x4c03, 0xad, 0x9c, 0x27, 0xd4, 0x82, 0x0b, 0x50, 0x7e</Guid>
+    </Entry>
+    <Entry Name="AcpiS3Save">
+      <C_Name>gEfiAcpiS3SaveProtocolGuid</C_Name>
+      <Guid>0x125f2de1, 0xfb85, 0x440c, 0xa5, 0x4c, 0x4d, 0x99, 0x35, 0x8a, 0x8d, 0x38</Guid>
+    </Entry>
+    <Entry Name="Performance">
+      <C_Name>gEfiPerformanceProtocolGuid</C_Name>
+      <Guid>0xFFECFFFF, 0x923C, 0x14d2, 0x9E, 0x3F, 0x22, 0xA0, 0xC9, 0x69, 0x56, 0x3B</Guid>
+    </Entry>
+    <Entry Name="PxeDhcp4">
+      <C_Name>gEfiPxeDhcp4ProtocolGuid</C_Name>
+      <Guid>0x03c4e624, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x29, 0x3f, 0xc1, 0x4d</Guid>
+    </Entry>
+    <Entry Name="PxeDhcp4Callback">
+      <C_Name>gEfiPxeDhcp4CallbackProtocolGuid</C_Name>
+      <Guid>0xc1544c01, 0x92a4, 0x4198, 0x8a, 0x84, 0x77, 0x85, 0x83, 0xc2, 0x36, 0x21</Guid>
+    </Entry>
+    <Entry Name="UgaIo">
+      <C_Name>gEfiUgaIoProtocolGuid</C_Name>
+      <Guid>0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2</Guid>
+    </Entry>
+    <Entry Name="DebugAssert">
+      <C_Name>gEfiDebugAssertProtocolGuid</C_Name>
+      <Guid>0xbe499c92, 0x7d4b, 0x11d4, 0xbc, 0xee, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>
+    </Entry>
+    <Entry Name="UsbAtapi">
+      <C_Name>gEfiUsbAtapiProtocolGuid</C_Name>
+      <Guid>0x2B2F68DA, 0x0CD2, 0x44cf, 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75</Guid>
+    </Entry>
+    <Entry Name="PciHotPlugRequest">
+      <C_Name>gEfiPciHotPlugRequestProtocolGuid</C_Name>
+      <Guid>0x19cb87ab, 0x2cb9, 0x4665, 0x83, 0x60, 0xdd, 0xcf, 0x60, 0x54, 0xf7, 0x9d</Guid>
+    </Entry>
+    <Entry Name="ExtendedSalBootService">
+      <C_Name>gEfiExtendedSalBootServiceProtocolGuid</C_Name>
+      <Guid>0xde0ee9a4, 0x3c7a, 0x44f2, 0xb7, 0x8b, 0xe3, 0xcc, 0xd6, 0x9c, 0x3a, 0xf7</Guid>
+    </Entry>
+    <Entry Name="ExtendedSalVariableServices">
+      <C_Name>gEfiExtendedSalVariableServicesProtocolGuid</C_Name>
+      <Guid>0x4ecb6c53, 0xc641, 0x4370, 0x8c, 0xb2, 0x3b, 0x0e, 0x49, 0x6e, 0x83, 0x78</Guid>
+    </Entry>
+    <Entry Name="ExtendedSalStatusCodeServices">
+      <C_Name>gEfiExtendedSalStatusCodeServicesProtocolGuid</C_Name>
+      <Guid>0x00dbd91d, 0x55e9, 0x420f, 0x96, 0x39, 0x5e, 0x9f, 0x84, 0x37, 0xb4, 0x4f</Guid>
+    </Entry>
+    <Entry Name="IsaIo">
+      <C_Name>gEfiIsaIoProtocolGuid</C_Name>
+      <Guid>0x7ee2bd44, 0x3da0, 0x11d4, 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>
+    </Entry>
+    <Entry Name="IsaAcpi">
+      <C_Name>gEfiIsaAcpiProtocolGuid</C_Name>
+      <Guid>0x64a892dc, 0x5561, 0x4536, 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55</Guid>
+    </Entry>
+    <Entry Name="Performance">
+      <C_Name>gPerformanceProtocolGuid</C_Name>
+      <Guid>0x76b6bdfa, 0x2acd, 0x4462, 0x9E, 0x3F, 0xcb, 0x58, 0xC9, 0x69, 0xd9, 0x37</Guid>
+    </Entry>
+  </ProtocolDeclarations>
+  <PpiDeclarations>
+    <Entry Name="PeiInMemory">
+      <C_Name>gPeiInMemoryGuid</C_Name>
+      <Guid>0x643b8786, 0xb417, 0x48d2, 0x8f, 0x5e, 0x78, 0x19, 0x93, 0x1c, 0xae, 0xd8</Guid>
+    </Entry>
+    <Entry Name="FlashMap">
+      <C_Name>gPeiFlashMapPpiGuid</C_Name>
+      <Guid>0xf34c2fa0, 0xde88, 0x4270, 0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c</Guid>
+    </Entry>
+    <Entry Name="BaseMemoryTest">
+      <C_Name>gPeiBaseMemoryTestPpiGuid</C_Name>
+      <Guid>0xb6ec423c, 0x21d2, 0x490d, 0x85, 0xc6, 0xdd, 0x58, 0x64, 0xea, 0xa6, 0x74</Guid>
+    </Entry>
+    <Entry Name="StatusCodeMemory">
+      <C_Name>gPeiStatusCodeMemoryPpiGuid</C_Name>
+      <Guid>0x26f8ab01, 0xd3cd, 0x489c, 0x98, 0x4f, 0xdf, 0xde, 0xf7, 0x68, 0x39, 0x5b</Guid>
+    </Entry>
+  </PpiDeclarations>
+  <PcdDefinitions>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdMaximumUnicodeStringLength</C_Name>
+      <Token>0x00000001</Token>
+      <DatumType>UINT32</DatumType>
+      <DefaultValue>1000000</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdMaximumAsciiStringLength</C_Name>
+      <Token>0x00000002</Token>
+      <DatumType>UINT32</DatumType>
+      <DefaultValue>1000000</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdMaximumLinkedListLength</C_Name>
+      <Token>0x00000003</Token>
+      <DatumType>UINT32</DatumType>
+      <DefaultValue>1000000</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdSpinLockTimeout</C_Name>
+      <Token>0x00000004</Token>
+      <DatumType>UINT32</DatumType>
+      <DefaultValue>10000000</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdDebugPropertyMask</C_Name>
+      <Token>0x00000005</Token>
+      <DatumType>UINT8</DatumType>
+      <DefaultValue>0x0f</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="PATCHABLE_IN_MODULE">
+      <C_Name>PcdDebugPrintErrorLevel</C_Name>
+      <Token>0x00000006</Token>
+      <DatumType>UINT32</DatumType>
+      <DefaultValue>0x80000000</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdReportStatusCodePropertyMask</C_Name>
+      <Token>0x00000007</Token>
+      <DatumType>UINT8</DatumType>
+      <DefaultValue>0x07</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdDebugClearMemoryValue</C_Name>
+      <Token>0x00000008</Token>
+      <DatumType>UINT8</DatumType>
+      <DefaultValue>0xAF</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdDebugClearMemoryValue</C_Name>
+      <Token>0x00000008</Token>
+      <DatumType>UINT8</DatumType>
+      <DefaultValue>0xAF</DefaultValue>
+    </PcdEntry>    
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>
+      <Token>0x00000009</Token>
+      <DatumType>UINT8</DatumType>
+      <DefaultValue>0</DefaultValue>
+    </PcdEntry>
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdMaxPcdCallBackNumber</C_Name>
+      <Token>0x0001000f</Token>
+      <DatumType>UINT32</DatumType>
+      <DefaultValue>0</DefaultValue>
+    </PcdEntry>    
+    <PcdEntry ItemType="DYNAMIC">
+      <C_Name>PcdTestDynamicUint8</C_Name>
+      <Token>0x00011000</Token>
+      <DatumType>UINT8</DatumType>
+      <DefaultValue>0x01</DefaultValue>
+    </PcdEntry>    
+    <PcdEntry ItemType="DYNAMIC">
+      <C_Name>PcdTestDynamicUint16</C_Name>
+      <Token>0x00011001</Token>
+      <DatumType>UINT16</DatumType>
+      <DefaultValue>0x1234</DefaultValue>
+    </PcdEntry>    
+    <PcdEntry ItemType="DYNAMIC">
+      <C_Name>PcdTestDynamicUint32</C_Name>
+      <Token>0x00011002</Token>
+      <DatumType>UINT32</DatumType>
+    </PcdEntry>    
+    <PcdEntry ItemType="DYNAMIC">
+      <C_Name>PcdTestDynamicUint64</C_Name>
+      <Token>0x00011003</Token>
+      <DatumType>UINT64</DatumType>
+    </PcdEntry>    
+    <PcdEntry ItemType="DYNAMIC">
+      <C_Name>PcdTestDynamicBoolean</C_Name>
+      <Token>0x00011004</Token>
+      <DatumType>BOOLEAN</DatumType>
+    </PcdEntry>    
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>
+      <Token>0x0001000f</Token>
+      <DatumType>UINT32</DatumType>
+    </PcdEntry>    
+    <PcdEntry ItemType="FIXED_AT_BUILD">
+      <C_Name>PcdVpdBaseAddress</C_Name>
+      <Token>0x00010010</Token>
+      <DatumType>UINT32</DatumType>
+    </PcdEntry>    
+  </PcdDefinitions>
+</PackageSurfaceArea>
diff --git a/edk2/EdkModulePkg/Include/Common/CapsuleName.h b/edk2/EdkModulePkg/Include/Common/CapsuleName.h
new file mode 100644
index 0000000..651fbe3
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Common/CapsuleName.h
@@ -0,0 +1,28 @@
+/*++        

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CapsuleName.h

+

+Abstract:

+  

+--*/

+

+#ifndef _CAPSULE_NAME_H

+#define _CAPSULE_NAME_H

+

+//

+// If capsule data is passed via a variable, then this name should be used.

+//

+#define EFI_CAPSULE_VARIABLE_NAME L"CapsuleUpdateData"

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Common/DecompressLibraryHob.h b/edk2/EdkModulePkg/Include/Common/DecompressLibraryHob.h
new file mode 100644
index 0000000..ee7b8a2
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Common/DecompressLibraryHob.h
@@ -0,0 +1,47 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DecompressLibraryHob.h

+

+Abstract:

+

+  Declaration of HOB that is used to pass decompressor library functions from PEI to DXE

+

+--*/

+

+#ifndef __DECOMPRESS_LIBRARY_HOB_H__

+#define __DECOMPRESS_LIBRARY_HOB_H__

+

+typedef

+RETURN_STATUS

+(EFIAPI *DECOMPRESS_LIBRARY_GET_INFO) (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  );

+

+typedef

+RETURN_STATUS

+(EFIAPI *DECOMPRESS_LIBRARY_DECOMPRESS) (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  );

+

+typedef struct {

+  DECOMPRESS_LIBRARY_GET_INFO    GetInfo;

+  DECOMPRESS_LIBRARY_DECOMPRESS  Decompress;

+} DECOMPRESS_LIBRARY;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Common/FlashMap.h b/edk2/EdkModulePkg/Include/Common/FlashMap.h
new file mode 100644
index 0000000..829fa2d
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Common/FlashMap.h
@@ -0,0 +1,110 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FlashMap.h

+

+Abstract:

+

+  FlashMap PPI defined in Tiano

+

+  This code abstracts FlashMap access

+

+--*/

+

+#ifndef __COMMON_FLASHMAP_H__

+#define __COMMON_FLASHMAP_H__

+

+#include <Common/Hob.h>

+//

+// Definition for flash map GUIDed HOBs

+//

+typedef UINT32  EFI_FLASH_AREA_ATTRIBUTES;

+

+#define EFI_FLASH_AREA_FV           0x0001

+#define EFI_FLASH_AREA_SUBFV        0x0002

+#define EFI_FLASH_AREA_MEMMAPPED_FV 0x0004

+#define EFI_FLASH_AREA_REQUIRED     0x0008

+#define EFI_FLASH_AREA_CORRUPT      0x0010

+

+typedef UINT8   EFI_FLASH_AREA_TYPE;

+

+#define EFI_FLASH_AREA_RECOVERY_BIOS  0x0   // Recovery code

+#define EFI_FLASH_AREA_MAIN_BIOS      0x1   // Regular BIOS code

+#define EFI_FLASH_AREA_PAL_B          0x2   // PAL-B

+#define EFI_FLASH_AREA_RESERVED_03    0x3   // Reserved for backwards compatibility

+#define EFI_FLASH_AREA_RESERVED_04    0x4   // Reserved for backwards compatibility

+#define EFI_FLASH_AREA_DMI_FRU        0x5   // DMI FRU information

+#define EFI_FLASH_AREA_OEM_BINARY     0x6   // OEM Binary Code/data

+#define EFI_FLASH_AREA_RESERVED_07    0x7   // Reserved for backwards compatibility

+#define EFI_FLASH_AREA_RESERVED_08    0x8   // Reserved for backwards compatibility

+#define EFI_FLASH_AREA_RESERVED_09    0x9   // Reserved for backwards compatibility

+#define EFI_FLASH_AREA_RESERVED_0A    0x0a  // Reserved for backwards compatibility

+#define EFI_FLASH_AREA_EFI_VARIABLES  0x0b  // EFI variables

+#define EFI_FLASH_AREA_MCA_LOG        0x0c  // MCA error log

+#define EFI_FLASH_AREA_SMBIOS_LOG     0x0d  // SMBIOS error log

+#define EFI_FLASH_AREA_FTW_BACKUP     0x0e  // A backup block during FTW operations

+#define EFI_FLASH_AREA_FTW_STATE      0x0f  // State information during FTW operations

+#define EFI_FLASH_AREA_UNUSED         0x0fd // Not used

+#define EFI_FLASH_AREA_GUID_DEFINED   0x0fe // Usage defined by a GUID

+#pragma pack(1)

+//

+// An individual sub-area Entry.

+// A single flash area may consist of  more than one sub-area.

+//

+typedef struct {

+  EFI_FLASH_AREA_ATTRIBUTES Attributes;

+  UINT32                    Reserved;

+  EFI_PHYSICAL_ADDRESS      Base;

+  EFI_PHYSICAL_ADDRESS      Length;

+  EFI_GUID                  FileSystem;

+} EFI_FLASH_SUBAREA_ENTRY;

+

+typedef struct {

+  UINT8                   Reserved[3];

+  EFI_FLASH_AREA_TYPE     AreaType;

+  EFI_GUID                AreaTypeGuid;

+  UINT32                  NumEntries;

+  EFI_FLASH_SUBAREA_ENTRY Entries[1];

+} EFI_FLASH_MAP_ENTRY_DATA;

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+  EFI_GUID                Name;

+  UINT8                   Reserved[3];

+  EFI_FLASH_AREA_TYPE     AreaType;

+  EFI_GUID                AreaTypeGuid;

+  UINT32                  NumEntries;

+  EFI_FLASH_SUBAREA_ENTRY Entries[1];

+} EFI_HOB_FLASH_MAP_ENTRY_TYPE;

+

+//

+// Internal definitions

+//

+typedef struct {

+  UINT8                   Reserved[3];

+  EFI_FLASH_AREA_TYPE     AreaType;

+  EFI_GUID                AreaTypeGuid;

+  UINT32                  NumberOfEntries;

+  EFI_FLASH_SUBAREA_ENTRY SubAreaData;

+} EFI_FLASH_AREA_HOB_DATA;

+

+typedef struct {

+  UINTN                     Base;

+  UINTN                     Length;

+  EFI_FLASH_AREA_ATTRIBUTES Attributes;

+  EFI_FLASH_AREA_TYPE       AreaType;

+} EFI_FLASH_AREA_DATA;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Common/Variable.h b/edk2/EdkModulePkg/Include/Common/Variable.h
new file mode 100644
index 0000000..e75adaf
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Common/Variable.h
@@ -0,0 +1,78 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiVariable.h

+  

+Abstract:

+  

+  Header file for EFI Variable Services

+

+--*/

+

+#ifndef _EFI_VARIABLE_H_

+#define _EFI_VARIABLE_H_

+

+#define VARIABLE_STORE_SIGNATURE  EFI_SIGNATURE_32 ('$', 'V', 'S', 'S')

+

+#define MAX_VARIABLE_SIZE         1024

+

+#define VARIABLE_DATA             0x55AA

+

+//

+// Variable Store Header flags

+//

+#define VARIABLE_STORE_FORMATTED  0x5a

+#define VARIABLE_STORE_HEALTHY    0xfe

+

+//

+// Variable Store Status

+//

+typedef enum {

+  EfiRaw,

+  EfiValid,

+  EfiInvalid,

+  EfiUnknown

+} VARIABLE_STORE_STATUS;

+

+//

+// Variable State flags

+//

+#define VAR_IN_DELETED_TRANSITION     0xfe  // Variable is in obsolete transistion

+#define VAR_DELETED                   0xfd  // Variable is obsolete

+#define VAR_ADDED                     0x7f  // Variable has been completely added

+#define IS_VARIABLE_STATE(_c, _Mask)  (BOOLEAN) (((~_c) & (~_Mask)) != 0)

+

+#pragma pack(1)

+

+typedef struct {

+  UINT32  Signature;

+  UINT32  Size;

+  UINT8   Format;

+  UINT8   State;

+  UINT16  Reserved;

+  UINT32  Reserved1;

+} VARIABLE_STORE_HEADER;

+

+typedef struct {

+  UINT16    StartId;

+  UINT8     State;

+  UINT8     Reserved;

+  UINT32    Attributes;

+  UINT32     NameSize;

+  UINT32     DataSize;

+  EFI_GUID  VendorGuid;

+} VARIABLE_HEADER;

+

+#pragma pack()

+

+#endif // _EFI_VARIABLE_H_

diff --git a/edk2/EdkModulePkg/Include/Common/WorkingBlockHeader.h b/edk2/EdkModulePkg/Include/Common/WorkingBlockHeader.h
new file mode 100644
index 0000000..235b740
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Common/WorkingBlockHeader.h
@@ -0,0 +1,47 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiWorkingBlockHeader.h

+

+Abstract:

+

+  Defines data structure that is the headers found at the runtime 

+  updatable firmware volumes, such as the FileSystemGuid of the 

+  working block, the header structure of the variable block, FTW

+  working block, or event log block.

+

+--*/

+

+#ifndef _EFI_WORKING_BLOCK_HEADER_H_

+#define _EFI_WORKING_BLOCK_HEADER_H_

+

+//

+// EFI Fault tolerant working block header

+// The header is immediately followed by the write queue.

+//

+typedef struct {

+  EFI_GUID  Signature;

+  UINT32    Crc;

+  UINT32    WorkingBlockValid : 1;

+  UINT32    WorkingBlockInvalid : 1;

+#define WORKING_BLOCK_VALID   0x1

+#define WORKING_BLOCK_INVALID 0x2

+  UINT32    Reserved : 6;

+  UINT8     Reserved3[3];

+  UINTN     WriteQueueSize;

+  //

+  // UINT8                WriteQueue[WriteQueueSize];

+  //

+} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/EdkDxe.h b/edk2/EdkModulePkg/Include/EdkDxe.h
new file mode 100644
index 0000000..7d05ffd
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/EdkDxe.h
@@ -0,0 +1,95 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  EdkDxe.h

+

+Abstract:

+  This file defines the base package surface area for writting a PEIM

+  

+  Things defined in the Tiano specification go in DxeCis.h. 

+

+  Dxe.h contains build environment and library information needed to build

+  a basic Dxe driver. This file must match the "base package" definition of

+  how to write a Dxe driver.

+

+--*/

+

+#ifndef __EDK_DXE_H__

+#define __EDK_DXE_H__

+

+//

+#include <Common/FlashMap.h>

+// BUGBUG: We must include this lib here due to ordering issues

+//

+#include <Ipf/SalApi.h>

+#include <Library/PeCoffLib.h>

+

+

+#include <Guid/MemoryTypeInformation.h>

+#include <Guid/FlashMapHob.h>

+#include <Guid/SystemNvDataGuid.h>

+#include <Guid/AlternateFvBlock.h>

+#include <Guid/ConsoleInDevice.h>

+#include <Guid/ConsoleOutDevice.h>

+#include <Guid/StandardErrorDevice.h>

+#include <Guid/HotPlugDevice.h>

+#include <Guid/PrimaryStandardErrorDevice.h>

+#include <Guid/PrimaryConsoleInDevice.h>

+#include <Guid/PrimaryConsoleOutDevice.h>

+#include <Guid/Bmp.h>

+#include <Guid/BootState.h>

+#include <Guid/ShellFile.h>

+#include <Guid/MiniShellFile.h>

+#include <Guid/StatusCode.h>

+#include <Guid/PciOptionRomTable.h>

+#include <Guid/PciHotplugDevice.h>

+#include <Guid/ExtendedSalGuid.h>

+#include <Guid/PeiPeCoffLoader.h>

+#include <Guid/CapsuleVendor.h>

+#include <Guid/CompatibleMemoryTested.h>

+

+#include <Ppi/StatusCodeMemory.h>

+

+#include <Protocol/CustomizedDecompress.h>

+#include <Protocol/DebugLevel.h>

+#include <Protocol/LoadPe32Image.h>

+#include <Protocol/EdkDecompress.h>

+#include <Protocol/Print.h>

+#include <Protocol/GenericMemoryTest.h>

+#include <Protocol/DiskInfo.h>

+#include <Protocol/FvbExtension.h>

+#include <Protocol/SecurityPolicy.h>

+#include <Protocol/FaultTolerantWriteLite.h>

+#include <Protocol/ConsoleControl.h>

+#include <Protocol/OEMBadging.h>

+#include <Protocol/LegacyBios.h>

+#include <Protocol/UgaSplash.h>

+#include <Protocol/AcpiS3Save.h>

+#include <Protocol/Performance.h>

+#include <Protocol/PxeDhcp4.h>

+#include <Protocol/PxeDhcp4CallBack.h>

+#include <Protocol/UgaIo.h>

+#include <Protocol/DebugAssert.h>

+#include <Protocol/usbatapi.h>

+#include <Protocol/PciHotPlugRequest.h>

+#include <Protocol/ExtendedSalBootService.h>

+#include <Protocol/IsaAcpi.h>

+

+#if ((EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000))

+//

+// Tiano8.5 Module use ScsiPassThru protocol together with the original ScsiIo protocol 

+// In UEFI2.0, Module use ScsiPassThruExt Protocol with new UEFI2.0 ScsiIo protocol

+//

+#include <Protocol/ScsiIo.h>

+#endif

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/EdkDxeCore.h b/edk2/EdkModulePkg/Include/EdkDxeCore.h
new file mode 100644
index 0000000..d1b4ca7
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/EdkDxeCore.h
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  EdkDxe.h

+

+Abstract:

+  This file defines the base package surface area for writting a PEIM

+  

+  Things defined in the Tiano specification go in DxeCis.h. 

+

+  Dxe.h contains build environment and library information needed to build

+  a basic Dxe driver. This file must match the "base package" definition of

+  how to write a Dxe driver.

+

+--*/

+

+#ifndef __EDK_DXE_CORE_H__

+#define __EDK_DXE_CORE_H__

+

+//

+// BUGBUG: We must include this lib here due to ordering issues

+//

+#include <Common/DecompressLibraryHob.h>

+#include <Library/PeCoffLib.h>

+

+//

+// BUGBUG: Performance related protocol and Guid.

+// They are Tiano-private, but are required for DxeCore

+//

+#include <Protocol/Performance.h>

+#include <Guid/PeiPerformanceHob.h>

+//

+// BUGBUG: Do these really belomg here?

+//

+#include <Guid/PeiPeCoffLoader.h>

+#include <Guid/MemoryTypeInformation.h>

+

+#include <Protocol/CustomizedDecompress.h>

+#include <Protocol/DebugLevel.h>

+#include <Protocol/LoadPe32Image.h>

+#include <Protocol/EdkDecompress.h>

+#include <Protocol/Print.h>

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/EdkDxeDepex.h b/edk2/EdkModulePkg/Include/EdkDxeDepex.h
new file mode 100644
index 0000000..1ce8be1
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/EdkDxeDepex.h
@@ -0,0 +1,62 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  EdkDxeDepex.h

+

+Abstract:

+  This include file is only used in *.DXS files. Do not use this 

+  include file in normal DXE code.

+

+  Depex - Dependency Expresion

+

+  The BNF grammar is thus:

+     <depex>   ::= before GUID       

+                 | after GUID

+                 | SOR <bool>

+                 | <bool>            

+     <bool>    ::= <bool> and <term> 

+                 | <bool> or <term>  

+                 | <term>            

+     <term>    ::= not <factor>      

+                 | <factor>          

+     <factor>  ::= <bool>            

+                 | <boolval>         

+                 | <depinst>         

+                 | <termval>         

+     <boolval> ::= true              

+                 | false             

+     <depinst> ::= push GUID         

+     <termval> ::= end               

+

+--*/

+

+#ifndef __EDK_DXE_DEPEX_H__

+#define __EDK_DXE_DEPEX_H__

+

+#include <EdkDxe.h>

+

+//

+// The Depex grammer needs the following strings so we must undo

+// any pre-processor redefinitions

+//

+#undef DEPENDENCY_START   

+#undef BEFORE             

+#undef AFTER              

+#undef SOR                               

+#undef AND                

+#undef OR                 

+#undef NOT                

+#undef TRUE               

+#undef FALSE              

+#undef DEPENDENCY_END     

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/EdkPeiCore.h b/edk2/EdkModulePkg/Include/EdkPeiCore.h
new file mode 100644
index 0000000..4e07efb
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/EdkPeiCore.h
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  EdkDxe.h

+

+Abstract:

+  This file defines the base package surface area for writting a PEIM

+  

+  Things defined in the Tiano specification go in DxeCis.h. 

+

+  Dxe.h contains build environment and library information needed to build

+  a basic Dxe driver. This file must match the "base package" definition of

+  how to write a Dxe driver.

+

+--*/

+

+#ifndef __EDK_PEI_CORE_H__

+#define __EDK_PEI_CORE_H__

+

+//

+// BUGBUG: We must include this lib here due to ordering issues

+//

+#include <Library/PeCoffLib.h>

+

+#include <Guid/PeiPeCoffLoader.h>

+

+//

+// BUGBUG: Performance related Guid.

+// It is Tiano-private, but is required for PeiCore

+//

+#include <Guid/PeiPerformanceHob.h>

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/EdkPeim.h b/edk2/EdkModulePkg/Include/EdkPeim.h
new file mode 100644
index 0000000..3c17999
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/EdkPeim.h
@@ -0,0 +1,60 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EdkPeim.h

+

+Abstract:

+  This file defines the base package surface area for writting a PEIM

+

+  Things defined in the PEI CIS specification go in PeiCis.h. 

+

+  EdkPeim.h contains build environment and library information needed to build

+  a basic PEIM that needs Tiano specific definitiosn. T

+  

+  Currently we just add in some extra PPI and GUID definitions

+

+--*/

+

+#ifndef __EDK_PEIM_H__

+#define __EDK_PEIM_H__

+

+//

+#include <Common/FlashMap.h>

+#include <Common/DecompressLibraryHob.h>

+// BUGBUG: We must include this lib here due to ordering issues

+//

+#include <Library/PeCoffLib.h>

+

+//

+// BUGBUG: Performance related Guid.

+// It is Tiano-private, but is required for PeiCore

+//

+#include <Guid/PeiPerformanceHob.h>

+#include <Guid/PeiPeCoffLoader.h>

+#include <Guid/SystemNvDataGuid.h>

+#include <Guid/FlashMapHob.h>

+#include <Guid/MemoryTypeInformation.h>

+#include <Guid/CapsuleVendor.h>

+#include <Guid/BootState.h>

+

+#include <Ppi/PeiInMemory.h>

+#include <Ppi/FlashMap.h>

+#include <Ppi/BaseMemoryTest.h>

+#include <Ppi/StatusCodeMemory.h>

+

+#include <Protocol/CustomizedDecompress.h>

+#include <Protocol/EdkDecompress.h>

+

+#include <Dxe/ArchProtocol/StatusCode.h>

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/EdkPeimDepex.h b/edk2/EdkModulePkg/Include/EdkPeimDepex.h
new file mode 100644
index 0000000..0b50599
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/EdkPeimDepex.h
@@ -0,0 +1,56 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  EdkPeimDepex.h

+

+Abstract:

+  This include file is only used in *.DXS files. Do not use this 

+  include file in normal Peim code.

+

+  Depex - Dependency Expresion

+

+  The BNF grammar is thus:

+     <depex>   ::= <bool>            

+     <bool>    ::= <bool> and <term> 

+                 | <bool> or <term>  

+                 | <term>            

+     <term>    ::= not <factor>      

+                 | <factor>          

+     <factor>  ::= <bool>            

+                 | <boolval>         

+                 | <depinst>         

+                 | <termval>         

+     <boolval> ::= true              

+                 | false             

+     <depinst> ::= push GUID         

+     <termval> ::= end               

+

+--*/

+

+#ifndef __EDK_PEIM_DEPEX_H__

+#define __EDK_PEIM_DEPEX_H__

+

+#include <EdkPeim.h>

+

+//

+// The Depex grammer needs the following strings so we must undo

+// any pre-processor redefinitions

+//

+#undef DEPENDENCY_START                          

+#undef AND                

+#undef OR                 

+#undef NOT                

+#undef TRUE               

+#undef FALSE                                        

+#undef DEPENDENCY_END     

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/AlternateFvBlock.h b/edk2/EdkModulePkg/Include/Guid/AlternateFvBlock.h
new file mode 100644
index 0000000..e3a789a
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/AlternateFvBlock.h
@@ -0,0 +1,32 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  AlternateFvBlock.h

+    

+Abstract:

+

+  Tiano Guid used to define the Alternate Firmware Volume Block Guid.  

+

+--*/

+

+#ifndef _ALT_FVB_GUID_H

+#define _ALT_FVB_GUID_H

+

+#define EFI_ALTERNATE_FV_BLOCK_GUID \

+  { \

+    0xf496922d, 0x172f, 0x4bbc, {0xa1, 0xeb, 0xe, 0xeb, 0x94, 0x9c, 0x34, 0x86 } \

+  }

+

+extern EFI_GUID gEfiAlternateFvBlockGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/Bmp.h b/edk2/EdkModulePkg/Include/Guid/Bmp.h
new file mode 100644
index 0000000..7a5f5a8
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/Bmp.h
@@ -0,0 +1,62 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Bmp.h

+    

+Abstract:

+

+--*/

+

+#ifndef _BMP_GUID_H_

+#define _BMP_GUID_H_

+

+

+//

+// Definitions for BMP files

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8   Blue;

+  UINT8   Green;

+  UINT8   Red;

+  UINT8   Reserved;

+} BMP_COLOR_MAP;

+

+typedef struct {

+  CHAR8         CharB;

+  CHAR8         CharM;

+  UINT32        Size;

+  UINT16        Reserved[2];

+  UINT32        ImageOffset;

+  UINT32        HeaderSize;

+  UINT32        PixelWidth;

+  UINT32        PixelHeight;

+  UINT16        Planes;       // Must be 1

+  UINT16        BitPerPixel;  // 1, 4, 8, or 24

+  UINT32        CompressionType;

+  UINT32        ImageSize;    // Compressed image size in bytes

+  UINT32        XPixelsPerMeter;

+  UINT32        YPixelsPerMeter;

+  UINT32        NumberOfColors;

+  UINT32        ImportantColors;

+} BMP_IMAGE_HEADER;

+

+#pragma pack()

+

+#define EFI_DEFAULT_BMP_LOGO_GUID \

+  {0x7BB28B99,0x61BB,0x11d5,{0x9A,0x5D,0x00,0x90,0x27,0x3F,0xC1,0x4D}}

+

+extern EFI_GUID gEfiDefaultBmpLogoGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/BootState.h b/edk2/EdkModulePkg/Include/Guid/BootState.h
new file mode 100644
index 0000000..2d9a0d1
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/BootState.h
@@ -0,0 +1,36 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BootState.h

+

+Abstract:

+

+  Constants and declarations that are common accross PEI and DXE.

+--*/

+

+#ifndef _BOOT_STATE_H_

+#define _BOOT_STATE_H_

+

+//

+// BOOT STATE

+//

+

+typedef UINT32 EFI_BOOT_STATE;

+

+#define BOOT_STATE_VARIABLE_NAME  L"BootState"

+

+#define  EFI_BOOT_STATE_VARIABLE_GUID  \

+  {0x60b5e939, 0xfcf, 0x4227, {0xba, 0x83, 0x6b, 0xbe, 0xd4, 0x5b, 0xc0, 0xe3} }

+

+extern EFI_GUID gEfiBootStateGuid;

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/CapsuleVendor.h b/edk2/EdkModulePkg/Include/Guid/CapsuleVendor.h
new file mode 100644
index 0000000..4f57628
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/CapsuleVendor.h
@@ -0,0 +1,35 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CapsuleVendor.h

+    

+Abstract:

+

+  Capsule update Guid definitions

+

+--*/

+

+#ifndef _EFI_CAPSULE_VENDOR_GUID_H_

+#define _EFI_CAPSULE_VENDOR_GUID_H_

+

+//

+// Note -- This guid is used as a vendor GUID (depending on implementation)

+// for the capsule variable if the capsule pointer is passes through reset

+// via a variable.

+//

+#define EFI_CAPSULE_VENDOR_GUID  \

+  { 0x711C703F, 0xC285, 0x4B10, { 0xA3, 0xB0, 0x36, 0xEC, 0xBD, 0x3C, 0x8B, 0xE2 } }

+  

+extern EFI_GUID gEfiCapsuleVendorGuid;

+

+#endif // #ifndef _EFI_CAPSULE_VENDOR_GUID_H_

diff --git a/edk2/EdkModulePkg/Include/Guid/CompatibleMemoryTested.h b/edk2/EdkModulePkg/Include/Guid/CompatibleMemoryTested.h
new file mode 100644
index 0000000..645cacf
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/CompatibleMemoryTested.h
@@ -0,0 +1,32 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CompatibleMemoryTested.h

+    

+Abstract:

+

+  Tiano Guid used for all Compatible Memory Range Tested GUID.  

+

+--*/

+

+#ifndef _COMPATIBLE_MEMORY_TESTED_GUID_H_

+#define _COMPATIBLE_MEMORY_TESTED_GUID_H_

+

+#define EFI_COMPATIBLE_MEMORY_TESTED_PROTOCOL_GUID \

+  { \

+    0x64c475ef, 0x344b, 0x492c, 0x93, 0xad, 0xab, 0x9e, 0xb4, 0x39, 0x50, 0x4 \

+  }

+

+extern EFI_GUID gEfiCompatibleMemoryTestedGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/ConsoleInDevice.h b/edk2/EdkModulePkg/Include/Guid/ConsoleInDevice.h
new file mode 100644
index 0000000..6e53028
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/ConsoleInDevice.h
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConsoleInDevice.h

+    

+Abstract:

+

+

+--*/

+

+#ifndef _CONSOLE_IN_DEVICE_H_

+#define _CONSOLE_IN_DEVICE_H_

+

+#define EFI_CONSOLE_IN_DEVICE_GUID    \

+    { 0xd3b36f2b, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }

+

+extern EFI_GUID gEfiConsoleInDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/ConsoleOutDevice.h b/edk2/EdkModulePkg/Include/Guid/ConsoleOutDevice.h
new file mode 100644
index 0000000..691aa41
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/ConsoleOutDevice.h
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConsoleOutDevice.h

+    

+Abstract:

+

+

+--*/

+

+#ifndef _CONSOLE_OUT_DEVICE_H_

+#define _CONSOLE_OUT_DEVICE_H_

+

+#define EFI_CONSOLE_OUT_DEVICE_GUID    \

+    { 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }

+

+extern EFI_GUID gEfiConsoleOutDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/ExtendedSalGuid.h b/edk2/EdkModulePkg/Include/Guid/ExtendedSalGuid.h
new file mode 100644
index 0000000..4a4dbee
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/ExtendedSalGuid.h
@@ -0,0 +1,279 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ExtendedSalGuid.h

+

+Abstract:

+

+                  

+--*/

+

+#ifndef _EXTENDED_SAL_GUID_H_

+#define _EXTENDED_SAL_GUID_H_

+

+//

+// Extended SAL Services protocol GUIDs

+//

+

+#define EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID \

+  { 0x5aea42b5, 0x31e1, 0x4515, {0xbc, 0x31, 0xb8, 0xd5, 0x25, 0x75, 0x65, 0xa6 } }

+

+#define EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID \

+  { 0x53a58d06, 0xac27, 0x4d8c, {0xb5, 0xe9, 0xf0, 0x8a, 0x80, 0x65, 0x41, 0x70 } }

+

+#define EFI_EXTENDED_SAL_LOCK_SERVICES_PROTOCOL_GUID  \

+  { 0x76b75c23, 0xfe4f, 0x4e17, {0xa2, 0xad, 0x1a, 0x65, 0x3d, 0xbb, 0x49, 0x4a } }

+

+#define EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID  \

+  { 0xc1a74056, 0x260e, 0x4871, {0xa0, 0x31, 0xe6, 0x45, 0xa6, 0x5b, 0x6e, 0x11 } }

+

+#define EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID  \

+  { 0x7e97a470, 0xefdb, 0x4d02, {0x8f, 0xce, 0x61, 0x90, 0xd2, 0x7b, 0xa2, 0x96 } }

+

+#define EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID  \

+  { 0x4ecb6c53, 0xc641, 0x4370, {0x8c, 0xb2, 0x3b, 0x0e, 0x49, 0x6e, 0x83, 0x78 } }

+

+#define EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID  \

+  { 0x899afd18, 0x75e8, 0x408b, {0xa4, 0x1a, 0x6e, 0x2e, 0x7e, 0xcd, 0xf4, 0x54 } }

+

+#define EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID  \

+  { 0x7d019990, 0x8ce1, 0x46f5, {0xa7, 0x76, 0x3c, 0x51, 0x98, 0x67, 0x6a, 0xa0 } }

+

+#define EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID  \

+  { 0xdbd91d, 0x55e9, 0x420f, {0x96, 0x39, 0x5e, 0x9f, 0x84, 0x37, 0xb4, 0x4f } }

+

+#define EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID \

+  { 0xa2271df1, 0xbcbb, 0x4f1d, {0x98, 0xa9, 0x06, 0xbc, 0x17, 0x2f, 0x07, 0x1a } }

+

+#define EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID \

+  { 0x697d81a2, 0xcf18, 0x4dc0, {0x9e, 0x0d, 0x06, 0x11, 0x3b, 0x61, 0x8a, 0x3f } }

+

+#define EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID \

+  { 0xe1cd9d21, 0x0fc2, 0x438d, {0x97, 0x03, 0x04, 0xe6, 0x6d, 0x96, 0x1e, 0x57 } }

+

+#define EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID \

+  { 0xd9e9fa06, 0x0fe0, 0x41c3, {0x96, 0xfb, 0x83, 0x42, 0x5a, 0x33, 0x94, 0xf8 } }

+

+#define EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID \

+  { 0x2a591128, 0x6cc7, 0x42b1, {0x8a, 0xf0, 0x58, 0x93, 0x3b, 0x68, 0x2d, 0xbb } }

+

+#define EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID \

+  { 0xa46b1a31, 0xad66, 0x4905, {0x92, 0xf6, 0x2b, 0x46, 0x59, 0xdc, 0x30, 0x63 } }

+

+#define EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID \

+  { 0xedc9494, 0x2743, 0x4ba5, { 0x88, 0x18, 0x0a, 0xef, 0x52, 0x13, 0xf1, 0x88 } }

+

+#define EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID \

+  { 0xcb3fd86e, 0x38a3, 0x4c03, {0x9a, 0x5c, 0x90, 0xcf, 0xa3, 0xa2, 0xab, 0x7a } }

+

+#define EFI_EXTENDED_SAL_ELOG_SERVICES_PROTOCOL_GUID \

+  { 0xd5e4ee5f, 0x3e0a, 0x453c, {0xa7, 0x25, 0xb6, 0x92, 0xbb, 0x6, 0x36, 0x5a } }

+

+#define EFI_EXTENDED_SAL_SENSOR_SERVICES_PROTOCOL_GUID \

+  { 0x4a153b6e, 0x85a1, 0x4982, {0x98, 0xf4, 0x6a, 0x8c, 0xfc, 0xa4, 0xab, 0xa1 } }

+

+#define EFI_EXTENDED_SAL_SM_COM_LAYER_SERVICES_PROTOCOL_GUID \

+  { 0x4356799, 0x81b7, 0x4e08, { 0xa3, 0x8d, 0xd9, 0x78, 0xfa, 0x47, 0xba, 0x42 } }

+

+#define EFI_EXTENDED_SAL_SST_GUID \

+  { 0x38802700, 0x868a, 0x4b4e, {0x81, 0xd4, 0x4f, 0x1b, 0xdc, 0xcf, 0xb4, 0x6f } }

+

+//

+// Extended Sal Proc Function IDs.

+//

+

+//

+// BugBug: These enums are name colisions waiting to happen. They should all be

+//         prefixed with Esal! It might be better to just make them #define, so

+//         they would be all caps.

+//

+

+typedef enum {

+  IoRead,

+  IoWrite,

+  MemRead,

+  MemWrite

+} EFI_EXTENDED_SAL_BASE_IO_SERVICES_FUNC_ID;

+

+typedef enum {

+  Stall

+} EFI_EXTENDED_SAL_STALL_FUNC_ID;

+

+

+typedef enum {

+  InitializeLockService,

+  AcquireLockService,

+  ReleaseLockService,

+  MaxLockServiceFunctionId

+} EFI_EXTENDED_SAL_LOCK_SERVICES_FUNC_ID;

+

+//

+// BugBug : Covert the first 3 functions into a lib functions

+// and move SalRegisterPhysicalAddress to SAL BASE Class

+//

+typedef enum {

+  SetVirtualAddress,

+  IsVirtual,

+  IsEfiRuntime,

+  SalRegisterPhysicalAddress

+} EFI_EXTENDED_SAL_VIRTUAL_SERVICES_FUNC_ID;

+

+typedef enum {

+  GetTime,

+  SetTime,

+  GetWakeupTime,

+  SetWakeupTime,

+  GetRtcFreq,

+  InitializeThreshold,

+  BumpThresholdCount,

+  GetThresholdCount

+} EFI_EXTENDED_SAL_RTC_SERVICES_FUNC_ID;

+

+typedef enum {

+  EsalGetVariable,

+  EsalGetNextVariableName,

+  EsalSetVariable

+} EFI_EXTENDED_SAL_VARIABLE_SERVICES_FUNC_ID;

+

+typedef enum {

+  GetNextHighMonotonicCount

+} EFI_EXTENDED_SAL_MTC_SERVICES_FUNC_ID;

+

+typedef enum {

+  ResetSystem

+} EFI_EXTENDED_SAL_RESET_SERVICES_FUNC_ID;

+

+typedef enum {

+  StatusCode

+} EFI_EXTENDED_SAL_STATUS_CODE_FUNC_ID;

+

+typedef enum {

+  ReportStatusCodeService

+} EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_FUNC_ID;

+

+typedef enum {

+  Read,

+  Write,

+  EraseBlock,

+  GetVolumeAttributes,

+  SetVolumeAttributes,

+  GetPhysicalAddress,

+  GetBlockSize,

+  EraseCustomBlockRange,

+} EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_FUNC_ID;

+

+typedef enum {

+  AddCpuData,

+  RemoveCpuData,

+  ModifyCpuData,

+  GetCpuDataByID,

+  GetCpuDataByIndex,

+  SendIpi,

+  CurrentProcInfo,

+  NumProcessors,

+  SetMinState,

+  GetMinState

+} EFI_EXTENDED_SAL_MP_SERVICES_FUNC_ID;

+

+typedef enum {

+  PalProc,

+  SetNewPalEntry,

+  GetNewPalEntry

+} EFI_EXTENDED_SAL_PAL_SERVICES_FUNC_ID;

+

+typedef enum {

+  SalSetVectors,

+  SalMcRendez,

+  SalMcSetParams,

+  EsalGetVectors,

+  EsalMcGetParams,

+  EsalMcGetMcParams,

+  EsalGetMcCheckinFlags,

+  EsalGetPlatformBaseFreq

+} EFI_EXTENDED_SAL_BASE_SERVICES_FUNC_ID;

+

+typedef enum {

+  McaGetStateInfo,

+  McaRegisterCpu

+} EFI_EXTENDED_SAL_MCA_SERVICES_FUNC_ID;

+

+typedef enum {

+  SalPciConfigRead,

+  SalPciConfigWrite

+} EFI_EXTENDED_SAL_PCI_SERVICES_FUNC_ID;

+

+typedef enum {

+  SalCacheInit,

+  SalCacheFlush

+} EFI_EXTENDED_SAL_CACHE_SERVICES_FUNC_ID;

+

+typedef enum {

+  SalGetStateInfo,

+  SalGetStateInfoSize,

+  SalClearStateInfo,

+  EsalGetStateBuffer,

+  EsalSaveStateBuffer

+} EFI_EXTENDED_SAL_MCA_LOG_SERVICES_FUNC_ID;

+

+typedef enum {

+  SalSetEventLogData,

+  SalGetEventLogData,

+  SalEraseEventLogData,

+  SalActivateEventLogData

+} EFI_EXTENDED_SAL_ELOG_SERVICES_FUNC_ID;

+

+typedef enum {

+  EsalGetComControllerInfo,

+  EsalSendComData,

+  EsalReceiveComData 

+} EFI_EXTENDED_SAL_SM_COM_LAYER_SERVICES_FUNC_ID;

+

+typedef enum {

+  SalUpdatePal

+} EFI_EXTENDED_SAL_UPDATE_PAL_SERVICES_FUNC_ID;

+

+typedef enum {

+  EsalReadSensorInfo,   

+  EsalReadSensorStatus,

+  EsalRearmSensor,

+  EsalReadSensorData  

+} EFI_EXTENDED_SAL_SENSOR_SERVICES_FUNC_ID;

+

+typedef struct {

+  UINT64      ProtoData;       

+} ESAL_GUID_DUMMY_PROTOCOL;

+

+extern EFI_GUID gEfiExtendedSalBaseIoServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalStallServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalLockServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalVirtualServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalRtcServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalVariableServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalMtcServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalResetServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalStatusCodeServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalFvBlockServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalMpServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalPalServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalBaseServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalMcaServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalPciServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalCacheServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalMcaLogServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalElogServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalSensorServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalSmComLayerServicesProtocolGuid;

+extern EFI_GUID gEfiExtendedSalSstGuid;

+

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/FlashMapHob.h b/edk2/EdkModulePkg/Include/Guid/FlashMapHob.h
new file mode 100644
index 0000000..a9e9b67
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/FlashMapHob.h
@@ -0,0 +1,33 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FlashMapHob.h

+    

+Abstract:

+

+  GUID used for Flash Map HOB entries in the HOB list.

+

+--*/

+

+#ifndef _FLASH_MAP_HOB_GUID_H_

+#define _FLASH_MAP_HOB_GUID_H_

+

+//

+// Definitions for Flash Map

+//

+#define EFI_FLASH_MAP_HOB_GUID \

+  { 0xb091e7d2, 0x5a0, 0x4198, {0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59 } }

+

+extern EFI_GUID gEfiFlashMapHobGuid;

+

+#endif // _FLASH_MAP_HOB_GUID_H_

diff --git a/edk2/EdkModulePkg/Include/Guid/HotPlugDevice.h b/edk2/EdkModulePkg/Include/Guid/HotPlugDevice.h
new file mode 100644
index 0000000..42fb6da
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/HotPlugDevice.h
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  HotPlugDevice.h

+    

+Abstract:

+

+

+--*/

+

+#ifndef _HOT_PLUG_DEVICE_H_

+#define _HOT_PLUG_DEVICE_H_

+

+#define HOT_PLUG_DEVICE_GUID    \

+    { 0x220ac432, 0x1d43, 0x49e5, {0xa7, 0x4f, 0x4c, 0x9d, 0xa6, 0x7a, 0xd2, 0x3b } }

+

+extern EFI_GUID gEfiHotPlugDeviceGuid;

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/MemoryTypeInformation.h b/edk2/EdkModulePkg/Include/Guid/MemoryTypeInformation.h
new file mode 100644
index 0000000..ed9270b
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/MemoryTypeInformation.h
@@ -0,0 +1,35 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  MemoryTypeInformation.h

+    

+Abstract:

+  GUID used for Memory Type Information entries in the HOB list.

+

+--*/

+

+#ifndef __MEMORY_TYPE_INFORMATION_GUID_H__

+#define __MEMORY_TYPE_INFORMATION_GUID_H__

+

+#define EFI_MEMORY_TYPE_INFORMATION_GUID \

+  { 0x4c19049f,0x4137,0x4dd3, { 0x9c,0x10,0x8b,0x97,0xa8,0x3f,0xfd,0xfa } }

+

+#define EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME L"MemoryTypeInformation"

+

+extern EFI_GUID gEfiMemoryTypeInformationGuid;

+

+typedef struct {

+  UINT32  Type;

+  UINT32  NumberOfPages;

+} EFI_MEMORY_TYPE_INFORMATION;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/MiniShellFile.h b/edk2/EdkModulePkg/Include/Guid/MiniShellFile.h
new file mode 100644
index 0000000..fa42d4d
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/MiniShellFile.h
@@ -0,0 +1,30 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  EfiShell.h

+    

+Abstract:

+

+  FFS Filename for EFI Shell

+

+--*/

+

+#ifndef _MINISHELLFILE_H_

+#define _MINISHELLFILE_H_

+

+#define EFI_MINI_SHELL_FILE_GUID  \

+  { 0x86ad232b, 0xd33a, 0x465c, {0xbf, 0x5f, 0x41, 0x37, 0xb, 0xa9, 0x2f, 0xe2 } }

+  

+extern EFI_GUID gEfiMiniShellFileGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PciHotplugDevice.h b/edk2/EdkModulePkg/Include/Guid/PciHotplugDevice.h
new file mode 100644
index 0000000..3b488ce
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PciHotplugDevice.h
@@ -0,0 +1,30 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    PciHotplugDevice.h

+    

+Abstract:

+

+  GUIDs used to indicate the device is Pccard hotplug device

+  

+--*/

+

+#ifndef _PCI_HOTPLUG_DEVICE_GUID_H_

+#define _PCI_HOTPLUG_DEVICE_GUID_H_

+

+#define EFI_PCI_HOTPLUG_DEVICE_GUID \

+  { 0x0b280816, 0x52e7, 0x4e51, {0xaa, 0x57, 0x11, 0xbd, 0x41, 0xcb, 0xef, 0xc3 } }

+

+extern EFI_GUID gEfiPciHotplugDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PciOptionRomTable.h b/edk2/EdkModulePkg/Include/Guid/PciOptionRomTable.h
new file mode 100644
index 0000000..5ad956e
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PciOptionRomTable.h
@@ -0,0 +1,46 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciOptionRomTable.h

+    

+Abstract:

+

+  GUID and data structure used to describe the list of PCI Option ROMs present in a system.

+

+--*/

+

+#ifndef _PCI_OPTION_ROM_TABLE_GUID_H_

+

+#define EFI_PCI_OPTION_ROM_TABLE_GUID \

+  { 0x7462660f, 0x1cbd, 0x48da, {0xad, 0x11, 0x91, 0x71, 0x79, 0x13, 0x83, 0x1c } }

+

+extern EFI_GUID gEfiPciOptionRomTableGuid;

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS   RomAddress; 

+  EFI_MEMORY_TYPE        MemoryType;

+  UINT32                 RomLength; 

+  UINT32                 Seg; 

+  UINT8                  Bus; 

+  UINT8                  Dev; 

+  UINT8                  Func; 

+  BOOLEAN                ExecutedLegacyBiosImage; 

+  BOOLEAN                DontLoadEfiRom;

+} EFI_PCI_OPTION_ROM_DESCRIPTOR;

+

+typedef struct {

+  UINT64                         PciOptionRomCount;

+  EFI_PCI_OPTION_ROM_DESCRIPTOR   *PciOptionRomDescriptors;

+} EFI_PCI_OPTION_ROM_TABLE;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PeiPeCoffLoader.h b/edk2/EdkModulePkg/Include/Guid/PeiPeCoffLoader.h
new file mode 100644
index 0000000..abafb71
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PeiPeCoffLoader.h
@@ -0,0 +1,67 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+    PeiPeCoffLoader.h

+    

+Abstract:

+  GUID for the PE/COFF Loader APIs shared between PEI and DXE

+

+--*/

+

+#ifndef __PEI_PE_COFF_LOADER_H__

+#define __PEI_PE_COFF_LOADER_H__

+

+

+#define EFI_PEI_PE_COFF_LOADER_GUID  \

+  { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }

+

+typedef struct _EFI_PEI_PE_COFF_LOADER_PROTOCOL   EFI_PEI_PE_COFF_LOADER_PROTOCOL;

+

+

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_PEI_PE_COFF_LOADER_GET_IMAGE_INFO) (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_PEI_PE_COFF_LOADER_LOAD_IMAGE) (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_PEI_PE_COFF_LOADER_RELOCATE_IMAGE) (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_PEI_PE_COFF_LOADER_UNLOAD_IMAGE) (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+struct _EFI_PEI_PE_COFF_LOADER_PROTOCOL {

+  EFI_PEI_PE_COFF_LOADER_GET_IMAGE_INFO  GetImageInfo;

+  EFI_PEI_PE_COFF_LOADER_LOAD_IMAGE      LoadImage;

+  EFI_PEI_PE_COFF_LOADER_RELOCATE_IMAGE  RelocateImage;

+  EFI_PEI_PE_COFF_LOADER_UNLOAD_IMAGE    UnloadImage;

+};

+

+extern EFI_GUID gEfiPeiPeCoffLoaderGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PeiPerformanceHob.h b/edk2/EdkModulePkg/Include/Guid/PeiPerformanceHob.h
new file mode 100644
index 0000000..33a2dc9
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PeiPerformanceHob.h
@@ -0,0 +1,60 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PeiPerformanceHob.h

+    

+Abstract:

+

+  GUIDs used for PEI Performance HOB data structures

+

+--*/

+

+#ifndef __PEI_PERFORMANCE_HOB_H__

+#define __PEI_PERFORMANCE_HOB_H__

+

+//

+// This is the GUID of PEI performance HOB

+//

+#define PEI_PERFORMANCE_HOB_GUID \

+  { 0xec4df5af, 0x4395, 0x4cc9, { 0x94, 0xde, 0x77, 0x50, 0x6d, 0x12, 0xc7, 0xb8 } }

+

+//

+// PEI_PERFORMANCE_STRING_SIZE must be a multiple of 8.

+//

+#define PEI_PERFORMANCE_STRING_SIZE     8

+#define PEI_PERFORMANCE_STRING_LENGTH   (PEI_PERFORMANCE_STRING_SIZE - 1)

+//

+// Bugbug: This macro will be replaced by a binary patchable PCD entry in EdkModulePkg

+//

+#define MAX_PEI_PERFORMANCE_LOG_ENTRIES 28

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  Handle;

+  CHAR8                 Token[PEI_PERFORMANCE_STRING_SIZE];

+  CHAR8                 Module[PEI_PERFORMANCE_STRING_SIZE];

+  UINT64                StartTimeStamp;

+  UINT64                EndTimeStamp;

+} PEI_PERFORMANCE_LOG_ENTRY;

+

+//

+// The header must be aligned at 8 bytes.

+// 

+typedef struct {

+  UINT32                             NumberOfEntries;

+  UINT32                             Reserved;

+} PEI_PERFORMANCE_LOG_HEADER;

+

+

+extern EFI_GUID gPeiPerformanceHobGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PrimaryConsoleInDevice.h b/edk2/EdkModulePkg/Include/Guid/PrimaryConsoleInDevice.h
new file mode 100644
index 0000000..e5aa49c
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PrimaryConsoleInDevice.h
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PrimaryConsoleInDevice.h

+    

+Abstract:

+

+

+--*/

+

+#ifndef _PRIMARY_CONSOLE_IN_DEVICE_H_

+#define _PRIMARY_CONSOLE_IN_DEVICE_H_

+

+#define EFI_PRIMARY_CONSOLE_IN_DEVICE_GUID    \

+  { 0xe451dcbe, 0x96a1, 0x4729, {0xa5, 0xcf, 0x6b, 0x9c, 0x2c, 0xff, 0x47, 0xfd } }

+

+extern EFI_GUID gEfiPrimaryConsoleInDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PrimaryConsoleOutDevice.h b/edk2/EdkModulePkg/Include/Guid/PrimaryConsoleOutDevice.h
new file mode 100644
index 0000000..f73d727
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PrimaryConsoleOutDevice.h
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PrimaryConsoleOutDevice.h

+    

+Abstract:

+

+--*/

+

+#ifndef _PRIMARY_CONSOLE_OUT_DEVICE_H_

+#define _PRIMARY_CONSOLE_OUT_DEVICE_H_

+

+#define EFI_PRIMARY_CONSOLE_OUT_DEVICE_GUID    \

+  { 0x62bdf38a, 0xe3d5, 0x492c, {0x95, 0xc, 0x23, 0xa7, 0xf6, 0x6e, 0x67, 0x2e } }

+

+extern EFI_GUID gEfiPrimaryConsoleOutDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/PrimaryStandardErrorDevice.h b/edk2/EdkModulePkg/Include/Guid/PrimaryStandardErrorDevice.h
new file mode 100644
index 0000000..97905ea
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/PrimaryStandardErrorDevice.h
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PrimaryStandardErrorDevice.h

+    

+Abstract:

+

+--*/

+

+#ifndef _PRIMARY_STANDARD_ERROR_DEVICE_H_

+#define _PRIMARY_STANDARD_ERROR_DEVICE_H_

+

+#define EFI_PRIMARY_STANDARD_ERROR_DEVICE_GUID    \

+  { 0x5a68191b, 0x9b97, 0x4752, {0x99, 0x46, 0xe3, 0x6a, 0x5d, 0xa9, 0x42, 0xb1 } }

+

+extern EFI_GUID gEfiPrimaryStandardErrorDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/ShellFile.h b/edk2/EdkModulePkg/Include/Guid/ShellFile.h
new file mode 100644
index 0000000..1f3d3b3
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/ShellFile.h
@@ -0,0 +1,31 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  EfiShell.h

+    

+Abstract:

+

+  FFS Filename for EFI Shell

+

+--*/

+

+#ifndef _SHELLFILE_H_

+#define _SHELLFILE_H_

+

+#define EFI_SHELL_FILE_GUID  \

+  { 0xc57ad6b7, 0x0515, 0x40a8, {0x9d, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4e, 0x37 } }

+

+

+extern EFI_GUID gEfiShellFileGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/StandardErrorDevice.h b/edk2/EdkModulePkg/Include/Guid/StandardErrorDevice.h
new file mode 100644
index 0000000..32b5af4
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/StandardErrorDevice.h
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StandardErrorDevice.h

+    

+Abstract:

+

+

+--*/

+

+#ifndef _STANDARD_ERROR_DEVICE_H_

+#define _STANDARD_ERROR_DEVICE_H_

+

+#define EFI_STANDARD_ERROR_DEVICE_GUID    \

+    { 0xd3b36f2d, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }

+

+extern EFI_GUID gEfiStandardErrorDeviceGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/StatusCode.h b/edk2/EdkModulePkg/Include/Guid/StatusCode.h
new file mode 100644
index 0000000..8242290
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/StatusCode.h
@@ -0,0 +1,33 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StatusCode.h

+    

+Abstract:

+

+  GUID used to identify Data Hub records that originate from the Tiano 

+  ReportStatusCode API.

+

+--*/

+

+#ifndef _STATUS_CODE_H__

+#define _STATUS_CODE_H__

+

+#define EFI_STATUS_CODE_GUID \

+  { \

+    0xd083e94c, 0x6560, 0x42e4, {0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a } \

+  }

+

+extern EFI_GUID gEfiStatusCodeGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/StatusCodeCallerId.h b/edk2/EdkModulePkg/Include/Guid/StatusCodeCallerId.h
new file mode 100644
index 0000000..8cf9d16
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/StatusCodeCallerId.h
@@ -0,0 +1,30 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  StatusCodeCallerId.h

+    

+Abstract:

+  GUID used to identify id for the caller who is initiating the Status Code.

+

+--*/

+

+#ifndef __STATUS_CODE_CALLER_ID_H__

+#define __STATUS_CODE_CALLER_ID_H__

+

+

+#define EFI_STANDARD_CALLER_ID_GUID \

+  {0xC9DCF469, 0xA7C4, 0x11D5, {0x87, 0xDA, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9} }

+

+extern EFI_GUID gEfiCallerIdGuid;

+

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Guid/SystemNvDataGuid.h b/edk2/EdkModulePkg/Include/Guid/SystemNvDataGuid.h
new file mode 100644
index 0000000..946d4d8
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Guid/SystemNvDataGuid.h
@@ -0,0 +1,45 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    SystemNvDataGuid.h

+    

+Abstract:

+

+  GUIDs used for System Non Volatile HOB entries in the in the HOB list and FV Guids carrying

+  the System specific information.

+

+--*/

+

+#ifndef __SYSTEM_NV_DATA_GUID_H__

+#define __SYSTEM_NV_DATA_GUID_H__

+

+#define EFI_SYSTEM_NV_DATA_FV_GUID \

+  {0xfff12b8d, 0x7696, 0x4c8b, {0xa9, 0x85, 0x27, 0x47, 0x7, 0x5b, 0x4f, 0x50} }

+

+#define EFI_SYSTEM_NV_DATA_HOB_GUID \

+  {0xd6e5092d, 0xc7b2, 0x4872, {0xaf, 0x66, 0xfd, 0xc0, 0xe6, 0xf9, 0x5e, 0x78} }

+

+typedef struct {

+  EFI_GUID                  SystemNvDataHobGuid;

+  EFI_GUID                  SystemNvDataFvGuid;

+  EFI_LBA                   StartLba;    

+  UINTN                     StartLbaOffset;

+  EFI_LBA                   EndLba;    

+  UINTN                     EndLbaOffset;

+  UINT32                    DataTypeSignature;

+} NV_SYSTEM_DATA_GUID_TYPE;

+

+extern EFI_GUID gEfiSystemNvDataHobGuid;

+extern EFI_GUID gEfiSystemNvDataFvGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/CustomDecompressLib.h b/edk2/EdkModulePkg/Include/Library/CustomDecompressLib.h
new file mode 100644
index 0000000..6edd3ba
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/CustomDecompressLib.h
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CustomDecompressLib.h

+

+Abstract:

+

+  Custom Decompress Functions

+

+--*/

+

+#ifndef __CUSTOM_DECPOMPRESS_LIB_H__

+#define __CUSTOM_DECPOMPRESS_LIB_H__

+

+RETURN_STATUS

+EFIAPI

+CustomDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  );

+

+RETURN_STATUS

+EFIAPI

+CustomDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkBsDataHubStatusCodeLib.h b/edk2/EdkModulePkg/Include/Library/EdkBsDataHubStatusCodeLib.h
new file mode 100644
index 0000000..a334c92
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkBsDataHubStatusCodeLib.h
@@ -0,0 +1,47 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  BsDataHubStatusCodeLib.h

+   

+Abstract:

+

+  Lib to provide data hub status code reporting.

+

+--*/

+

+#ifndef _EFI_BS_DATA_HUB_STATUS_CODE_LIB_H_

+#define _EFI_BS_DATA_HUB_STATUS_CODE_LIB_H_

+

+//

+// Initialization function

+//

+VOID

+BsDataHubStatusCodeInitialize (

+  VOID

+  )

+;

+

+//

+// Status code reporting function

+//

+EFI_STATUS

+BsDataHubReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkDxeSalLib.h b/edk2/EdkModulePkg/Include/Library/EdkDxeSalLib.h
new file mode 100644
index 0000000..9d21846
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkDxeSalLib.h
@@ -0,0 +1,141 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EdkDxeSalLib.h

+

+Abstract:

+

+--*/

+

+#ifndef _ESAL_SERVICE_LIB_H__

+#define _ESAL_SERVICE_LIB_H__

+

+//#include <Ipf/SalApi.h>

+

+EFI_STATUS

+RegisterEsalFunction (

+  IN  UINT64                                    FunctionId,

+  IN  EFI_GUID                                  *ClassGuid,

+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,

+  IN  VOID                                      *ModuleGlobal

+  )

+/*++

+

+Routine Description:

+

+  Register ESAL Class Function and it's asociated global.

+  This function is boot service only!

+

+Arguments:

+  FunctionId    - ID of function to register

+  ClassGuid     - GUID of function class 

+  Function      - Function to register under ClassGuid/FunctionId pair

+  ModuleGlobal  - Module global for Function.

+

+Returns: 

+  EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.

+

+--*/

+;

+

+EFI_STATUS

+RegisterEsalClass (

+  IN  EFI_GUID                                  *ClassGuid,

+  IN  VOID                                      *ModuleGlobal,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Register ESAL Class and it's asociated global.

+  This function is boot service only!

+

+Arguments:

+  ClassGuid     - GUID of function class 

+  ModuleGlobal  - Module global for Function.

+  ..            - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL 

+                  indicates the end of the list.

+

+Returns: 

+  EFI_SUCCESS - All members of ClassGuid registered

+

+--*/

+;

+

+SAL_RETURN_REGS

+EfiCallEsalService (

+  IN  EFI_GUID                                      *ClassGuid,

+  IN  UINT64                                        FunctionId,

+  IN  UINT64                                        Arg2,

+  IN  UINT64                                        Arg3,

+  IN  UINT64                                        Arg4,

+  IN  UINT64                                        Arg5,

+  IN  UINT64                                        Arg6,

+  IN  UINT64                                        Arg7,

+  IN  UINT64                                        Arg8

+  )

+/*++

+

+Routine Description:

+

+  Call module that is not linked direclty to this module. This code is IP 

+  relative and hides the binding issues of virtual or physical calling. The

+  function that gets dispatched has extra arguments that include the registered

+  module global and a boolean flag to indicate if the system is in virutal mode.

+

+Arguments:

+  ClassGuid   - GUID of function

+  FunctionId  - Function in ClassGuid to call

+  Arg2        - Argument 2 ClassGuid/FunctionId defined

+  Arg3        - Argument 3 ClassGuid/FunctionId defined

+  Arg4        - Argument 4 ClassGuid/FunctionId defined

+  Arg5        - Argument 5 ClassGuid/FunctionId defined

+  Arg6        - Argument 6 ClassGuid/FunctionId defined

+  Arg7        - Argument 7 ClassGuid/FunctionId defined

+  Arg8        - Argument 8 ClassGuid/FunctionId defined

+

+Returns: 

+  Status of ClassGuid/FuncitonId

+

+--*/

+;

+

+SAL_RETURN_REGS

+SetEsalVirtualEntryPoint (

+  IN  UINT64  EntryPoint,

+  IN  UINT64  Gp

+  )

+;

+

+SAL_RETURN_REGS

+SetEsalPhysicalEntryPoint (

+  IN  UINT64  EntryPoint,

+  IN  UINT64  Gp

+  )

+;

+

+SAL_RETURN_REGS

+GetEsalEntryPoint (

+  VOID

+  )

+;

+

+VOID

+SalFlushCache (

+  IN EFI_PHYSICAL_ADDRESS  Start,

+  IN UINT64                Length

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkFvbServiceLib.h b/edk2/EdkModulePkg/Include/Library/EdkFvbServiceLib.h
new file mode 100644
index 0000000..16e00d3
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkFvbServiceLib.h
@@ -0,0 +1,250 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EdkFvbServiceLib.h

+

+Abstract:

+

+--*/

+#ifndef __EDK_FVB_SERVICE_LIB_H__

+#define __EDK_FVB_SERVICE_LIB_H__

+

+EFI_STATUS

+EfiFvbReadBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Reads specified number of bytes into a buffer from the specified block

+

+Arguments:

+  Instance              - The FV instance to be read from

+  Lba                   - The logical block address to be read from

+  Offset                - Offset into the block at which to begin reading

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes read

+  Buffer                - Pointer to a caller allocated buffer that will be

+                          used to hold the data read

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbWriteBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the block

+

+Arguments:

+  Instance              - The FV instance to be written to

+  Lba                   - The starting logical block index to write to

+  Offset                - Offset into the block at which to begin writing

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes actually written

+  Buffer                - Pointer to a caller allocated buffer that contains

+                          the source for the write

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a firmware volume block

+

+Arguments:

+  Instance              - The FV instance to be erased

+  Lba                   - The logical block index to be erased

+  

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes

+  )

+/*++

+

+Routine Description:

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          returned

+  Attributes            - Output buffer which contains attributes

+

+Returns: 

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN EFI_FVB_ATTRIBUTES                   Attributes

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the 

+  input parameter, and returns the new setting of the volume

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          modified

+  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 

+                          containing the desired firmware volume settings.

+                          On successful return, it contains the new settings

+                          of the firmware volume

+

+Returns: 

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *BaseAddress

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  BaseAddress           - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 

+                          that on successful return, contains the base address

+                          of the firmware volume. 

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbGetBlockSize (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieve the size of a logical block

+

+Arguments:

+  Instance              - The FV instance whose block size is going to be

+                          returned

+  Lba                   - Indicates which block to return the size for.

+  BlockSize             - A pointer to a caller allocated UINTN in which

+                          the size of the block is returned

+  NumOfBlocks           - a pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+                          

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+;

+

+EFI_STATUS

+EfiFvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  Instance              - The FV instance to be erased

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetLastLba         - Offset into the last block at which to end erasing

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+  

+  EFI_UNSUPPORTED       - not support

+  

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkGraphicsLib.h b/edk2/EdkModulePkg/Include/Library/EdkGraphicsLib.h
new file mode 100644
index 0000000..52bedd8
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkGraphicsLib.h
@@ -0,0 +1,185 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GraphicsLib.h

+

+Abstract:

+

+ 

+--*/

+

+#ifndef _EFI_GRAPHICS_LIB_H_

+#define _EFI_GRAPHICS_LIB_H_

+

+EFI_STATUS

+GetGraphicsBitMapFromFV (

+  IN  EFI_GUID      *FileNameGuid,

+  OUT VOID          **Image,

+  OUT UINTN         *ImageSize

+  )

+/*++

+

+Routine Description:

+

+  Return the graphics image file named FileNameGuid into Image and return it's

+  size in ImageSize. All Firmware Volumes (FV) in the system are searched for the

+  file name.

+

+Arguments:

+

+  FileNameGuid  - File Name of graphics file in the FV(s).

+

+  Image         - Pointer to pointer to return graphics image.  If NULL, a 

+                  buffer will be allocated.

+

+  ImageSize     - Size of the graphics Image in bytes. Zero if no image found.

+

+

+Returns: 

+

+  EFI_SUCCESS          - Image and ImageSize are valid. 

+  EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size

+  EFI_NOT_FOUND        - FileNameGuid not found

+

+--*/

+;

+

+EFI_STATUS

+ConvertBmpToUgaBlt (

+  IN  VOID      *BmpImage,

+  IN  UINTN     BmpImageSize,

+  IN OUT VOID   **UgaBlt,

+  IN OUT UINTN  *UgaBltSize,

+  OUT UINTN     *PixelHeight,

+  OUT UINTN     *PixelWidth

+  )

+/*++

+

+Routine Description:

+

+  Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer

+  is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt

+  buffer is passed in it will be used if it is big enough.

+

+Arguments:

+

+  BmpImage      - Pointer to BMP file

+

+  BmpImageSize  - Number of bytes in BmpImage

+

+  UgaBlt        - Buffer containing UGA version of BmpImage.

+

+  UgaBltSize    - Size of UgaBlt in bytes.

+

+  PixelHeight   - Height of UgaBlt/BmpImage in pixels

+

+  PixelWidth    - Width of UgaBlt/BmpImage in pixels

+

+

+Returns: 

+

+  EFI_SUCCESS           - UgaBlt and UgaBltSize are returned. 

+  EFI_UNSUPPORTED       - BmpImage is not a valid *.BMP image

+  EFI_BUFFER_TOO_SMALL  - The passed in UgaBlt buffer is not big enough.

+                          UgaBltSize will contain the required size.

+

+--*/

+;

+

+EFI_STATUS

+EnableQuietBoot (

+  IN  EFI_GUID  *LogoFile

+  )

+/*++

+

+Routine Description:

+

+  Use Console Control to turn off UGA based Simple Text Out consoles from going

+  to the UGA device. Put up LogoFile on every UGA device that is a console

+

+Arguments:

+

+  LogoFile - File name of logo to display on the center of the screen.

+

+

+Returns: 

+

+  EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo

+                          displayed.

+  EFI_UNSUPPORTED       - Logo not found

+

+--*/

+;

+

+EFI_STATUS

+DisableQuietBoot (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Use Console Control to turn on UGA based Simple Text Out consoles. The UGA 

+  Simple Text Out screens will now be synced up with all non UGA output devices

+

+Arguments:

+

+  NONE

+

+Returns: 

+

+  EFI_SUCCESS           - UGA devices are back in text mode and synced up.

+  EFI_UNSUPPORTED       - Logo not found

+

+--*/

+;

+

+EFI_STATUS

+LockKeyboards (

+  IN  CHAR16    *Password

+  )

+/*++

+

+Routine Description:

+  Use Console Control Protocol to lock the Console In Spliter virtual handle. 

+  This is the ConInHandle and ConIn handle in the EFI system table. All key

+  presses will be ignored until the Password is typed in. The only way to

+  disable the password is to type it in to a ConIn device.

+

+Arguments:

+  Password - Password used to lock ConIn device

+

+

+Returns: 

+

+  EFI_SUCCESS     - ConsoleControl has been flipped to graphics and logo

+                    displayed.

+  EFI_UNSUPPORTED - Logo not found

+

+--*/

+;

+

+UINTN

+EFIAPI

+PrintXY (

+  IN UINTN                            X,

+  IN UINTN                            Y,

+  IN EFI_UGA_PIXEL                    *Foreground, OPTIONAL

+  IN EFI_UGA_PIXEL                    *Background, OPTIONAL

+  IN CHAR16                           *Fmt,

+  ...

+  )

+;

+

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkIfrSupportLib.h b/edk2/EdkModulePkg/Include/Library/EdkIfrSupportLib.h
new file mode 100644
index 0000000..d2a1ff5
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkIfrSupportLib.h
@@ -0,0 +1,1270 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  IfrSupportLib.h

+

+Abstract:

+

+  The file contain all library function for Ifr Operations.

+

+--*/

+

+#ifndef _IFRSUPPORTLIBRARY_H

+#define _IFRSUPPORTLIBRARY_H

+

+#define DEFAULT_FORM_BUFFER_SIZE    0xFFFF

+#define DEFAULT_STRING_BUFFER_SIZE  0xFFFF

+

+#pragma pack(1)

+typedef struct {

+  CHAR16      *OptionString;  // Passed in string to generate a token for in a truly dynamic form creation

+  STRING_REF  StringToken;    // This is used when creating a single op-code without generating a StringToken (have one already)

+  UINT16      Value;

+  UINT8       Flags;

+  UINT16      Key;

+} IFR_OPTION;

+#pragma pack()

+

+EFI_STATUS

+GetCurrentLanguage (

+  OUT     CHAR16              *Lang

+  )

+/*++

+

+Routine Description:

+

+  Determine what is the current language setting

+  

+Arguments:

+

+  Lang      - Pointer of system language

+  

+Returns: 

+  

+  Status code

+

+--*/

+;

+

+EFI_STATUS

+AddString (

+  IN      VOID                *StringBuffer,

+  IN      CHAR16              *Language,

+  IN      CHAR16              *String,

+  IN OUT  STRING_REF          *StringToken

+  )

+/*++

+

+Routine Description:

+

+  Add a string to the incoming buffer and return the token and offset data

+  

+Arguments:

+

+  StringBuffer      - The incoming buffer

+  

+  Language          - Currrent language

+  

+  String            - The string to be added

+  

+  StringToken       - The index where the string placed

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_SUCCESS             - String successfully added to the incoming buffer

+

+--*/

+;

+

+EFI_STATUS

+AddOpCode (

+  IN      VOID                *FormBuffer,

+  IN OUT  VOID                *OpCodeData

+  )

+/*++

+

+Routine Description:

+

+  Add op-code data to the FormBuffer

+  

+Arguments:

+

+  FormBuffer      - Form buffer to be inserted to

+  

+  OpCodeData      - Op-code data to be inserted

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_SUCCESS             - Op-code data successfully inserted

+

+--*/

+;

+

+EFI_STATUS

+CreateFormSet (

+  IN      CHAR16              *FormSetTitle,

+  IN      EFI_GUID            *Guid,

+  IN      UINT8               Class,

+  IN      UINT8               SubClass,

+  IN OUT  VOID                **FormBuffer,

+  IN OUT  VOID                **StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a formset

+  

+Arguments:

+

+  FormSetTitle        - Title of formset

+  

+  Guid                - Guid of formset

+  

+  Class               - Class of formset

+  

+  SubClass            - Sub class of formset

+  

+  FormBuffer          - Pointer of the formset created

+  

+  StringBuffer        - Pointer of FormSetTitile string created

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_SUCCESS             - Formset successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateForm (

+  IN      CHAR16              *FormTitle,

+  IN      UINT16              FormId,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a form

+  

+Arguments:

+

+  FormTitle       - Title of the form

+  

+  FormId          - Id of the form

+  

+  FormBuffer          - Pointer of the form created

+  

+  StringBuffer        - Pointer of FormTitil string created

+  

+Returns: 

+

+  EFI_SUCCESS     - Form successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateSubTitle (

+  IN      CHAR16              *SubTitle,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a SubTitle

+  

+Arguments:

+

+  SubTitle        - Sub title to be created

+  

+  FormBuffer      - Where this subtitle to add to

+  

+  StringBuffer    - String buffer created for subtitle

+  

+Returns: 

+

+  EFI_SUCCESS     - Subtitle successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateText (

+  IN      CHAR16              *String,

+  IN      CHAR16              *String2,

+  IN      CHAR16              *String3,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a line of text

+  

+Arguments:

+

+  String          - First string of the text

+  

+  String2         - Second string of the text

+  

+  String3         - Help string of the text

+  

+  Flags           - Flag of the text

+  

+  Key             - Key of the text

+  

+  FormBuffer      - The form where this text adds to

+  

+  StringBuffer    - String buffer created for String, String2 and String3

+  

+Returns: 

+

+  EFI_SUCCESS     - Text successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateGoto (

+  IN      UINT16              FormId,

+  IN      CHAR16              *Prompt,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a hyperlink

+  

+Arguments:

+

+  FormId        - Form ID of the hyperlink

+  

+  Prompt        - Prompt of the hyperlink

+  

+  FormBuffer    - The form where this hyperlink adds to

+  

+  StringBuffer  - String buffer created for Prompt

+  

+Returns: 

+

+  EFI_SUCCESS     - Hyperlink successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateOneOf (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a one-of question with a set of options to choose from.  The

+  OptionsList is a pointer to a null-terminated list of option descriptions.

+  

+Arguments:

+

+  QuestionId      - Question ID of the one-of box

+  

+  DataWidth       - DataWidth of the one-of box

+  

+  Prompt          - Prompt of the one-of box

+  

+  Help            - Help of the one-of box

+  

+  OptionsList     - Each string in it is an option of the one-of box

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - The form where this one-of box adds to

+  

+  StringBuffer    - String buffer created for Prompt, Help and Option strings

+  

+Returns: 

+

+  EFI_DEVICE_ERROR    - DataWidth > 2

+

+  EFI_SUCCESS         - One-Of box successfully created.

+

+--*/

+;

+

+EFI_STATUS

+CreateOrderedList (

+  IN      UINT16              QuestionId,

+  IN      UINT8               MaxEntries,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a one-of question with a set of options to choose from.  The

+  OptionsList is a pointer to a null-terminated list of option descriptions.

+  

+Arguments:

+

+  QuestionId      - Question ID of the ordered list

+  

+  MaxEntries      - MaxEntries of the ordered list

+  

+  Prompt          - Prompt of the ordered list

+  

+  Help            - Help of the ordered list

+  

+  OptionsList     - Each string in it is an option of the ordered list

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - The form where this ordered list adds to

+  

+  StringBuffer    - String buffer created for Prompt, Help and Option strings

+  

+Returns: 

+

+  EFI_SUCCESS     - Ordered list successfully created.

+

+--*/

+;

+

+EFI_STATUS

+CreateCheckBox (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      UINT8               Flags,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a checkbox

+  

+Arguments:

+

+  QuestionId      - Question ID of the check box

+  

+  DataWidth       - DataWidth of the check box

+  

+  Prompt          - Prompt of the check box

+  

+  Help            - Help of the check box

+  

+  Flags           - Flags of the check box

+  

+  FormBuffer      - The form where this check box adds to

+  

+  StringBuffer    - String buffer created for Prompt and Help.

+  

+Returns: 

+

+  EFI_DEVICE_ERROR    - DataWidth > 1

+

+  EFI_SUCCESS         - Check box successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateNumeric (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      UINT16              Minimum,

+  IN      UINT16              Maximum,

+  IN      UINT16              Step,

+  IN      UINT16              Default,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a numeric

+  

+Arguments:

+

+  QuestionId      - Question ID of the numeric

+  

+  DataWidth       - DataWidth of the numeric

+  

+  Prompt          - Prompt of the numeric

+  

+  Help            - Help of the numeric

+  

+  Minimum         - Minumun boundary of the numeric

+  

+  Maximum         - Maximum boundary of the numeric

+  

+  Step            - Step of the numeric

+   

+  Default         - Default value

+  

+  Flags           - Flags of the numeric

+  

+  Key             - Key of the numeric

+  

+  FormBuffer      - The form where this numeric adds to

+  

+  StringBuffer    - String buffer created for Prompt and Help.

+  

+Returns: 

+

+  EFI_DEVICE_ERROR      - DataWidth > 2

+  

+  EFI_SUCCESS           - Numeric is successfully created

+

+--*/

+;

+

+EFI_STATUS

+CreateString (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      UINT8               MinSize,

+  IN      UINT8               MaxSize,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a string

+  

+Arguments:

+

+  QuestionId      - Question ID of the string

+  

+  DataWidth       - DataWidth of the string

+  

+  Prompt          - Prompt of the string

+  

+  Help            - Help of the string

+  

+  MinSize         - Min size boundary of the string

+  

+  MaxSize         - Max size boundary of the string

+    

+  Flags           - Flags of the string

+  

+  Key             - Key of the string

+  

+  FormBuffer      - The form where this string adds to

+  

+  StringBuffer    - String buffer created for Prompt and Help.

+  

+Returns: 

+

+  EFI_SUCCESS     - String successfully created.

+

+--*/

+;

+

+EFI_STATUS

+ExtractDataFromHiiHandle (

+  IN      EFI_HII_HANDLE      HiiHandle,

+  IN OUT  UINT16              *ImageLength,

+  OUT     UINT8               *DefaultImage,

+  OUT     EFI_GUID            *Guid

+  )

+/*++

+

+Routine Description:

+

+  Extract information pertaining to the HiiHandle

+  

+Arguments:

+

+  HiiHandle       - Hii handle

+  

+  ImageLength     - For input, length of DefaultImage;

+                    For output, length of actually required

+                    

+  DefaultImage    - Image buffer prepared by caller

+  

+  Guid            - Guid information about the form

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_BUFFER_TOO_SMALL    - DefualtImage has no enough ImageLength

+  

+  EFI_SUCCESS             - Successfully extract data from Hii database.

+  

+  

+--*/

+;

+

+EFI_HII_HANDLE

+FindHiiHandle (

+  IN OUT EFI_HII_PROTOCOL    **HiiProtocol, OPTIONAL

+  IN     EFI_GUID            *Guid

+  )

+/*++

+

+Routine Description:

+  Finds HII handle for given pack GUID previously registered with the HII.

+

+Arguments:

+  HiiProtocol - pointer to pointer to HII protocol interface. 

+                If NULL, the interface will be found but not returned.

+                If it points to NULL, the interface will be found and 

+                written back to the pointer that is pointed to.

+  Guid        - The GUID of the pack that registered with the HII.

+

+Returns:

+  Handle to the HII pack previously registered by the memory driver.

+

+--*/

+;

+

+EFI_STATUS

+CreateSubTitleOpCode (

+  IN      STRING_REF          StringToken,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a SubTitle opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+

+  StringToken     - StringToken of the subtitle

+  

+  FormBuffer      - Output of subtitle as a form

+  

+Returns: 

+

+  EFI_SUCCESS     - Subtitle created to be a form

+

+--*/

+;

+

+EFI_STATUS

+CreateTextOpCode (

+  IN      STRING_REF          StringToken,

+  IN      STRING_REF          StringTokenTwo,

+  IN      STRING_REF          StringTokenThree,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a Text opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+

+  StringToken               - First string token of the text

+  

+  StringTokenTwo            - Second string token of the text

+  

+  StringTokenThree          - Help string token of the text

+  

+  Flags                     - Flag of the text

+  

+  Key                       - Key of the text

+  

+  FormBuffer                - Output of text as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - Text created to be a form

+

+--*/

+;

+

+EFI_STATUS

+CreateGotoOpCode (

+  IN      UINT16              FormId,

+  IN      STRING_REF          StringToken,

+  IN      STRING_REF          StringTokenTwo,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a hyperlink opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+

+  FormId          - Form ID of the hyperlink

+  

+  StringToken     - Prompt string token of the hyperlink

+  

+  StringTokenTwo  - Help string token of the hyperlink

+  

+  Flags           - Flags of the hyperlink

+  

+  Key             - Key of the hyperlink

+  

+  FormBuffer      - Output of hyperlink as a form

+  

+Returns: 

+

+  EFI_SUCCESS   - Hyperlink created to be a form

+

+--*/

+;

+

+EFI_STATUS

+CreateOneOfOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a one-of opcode with a set of option op-codes to choose from independent of string creation.

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+

+  OptionsList is a pointer to a null-terminated list of option descriptions.  Ensure that OptionsList[x].StringToken

+  has been filled in since this routine will not generate StringToken values.

+  

+Arguments:

+

+  QuestionId      - Question ID of the one-of box

+  

+  DataWidth       - DataWidth of the one-of box

+  

+  PromptToken     - Prompt string token of the one-of box

+  

+  HelpToken       - Help string token of the one-of box

+  

+  OptionsList     - Each string in it is an option of the one-of box

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - Output of One-Of box as a form

+  

+Returns: 

+

+  EFI_SUCCESS         - One-Of box created to be a form

+  

+  EFI_DEVICE_ERROR    - DataWidth > 2

+

+--*/

+;

+

+EFI_STATUS

+CreateOrderedListOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               MaxEntries,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a ordered list opcode with a set of option op-codes to choose from independent of string creation.

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+

+  OptionsList is a pointer to a null-terminated list of option descriptions.  Ensure that OptionsList[x].StringToken

+  has been filled in since this routine will not generate StringToken values.

+  

+Arguments:

+

+  QuestionId      - Question ID of the ordered list

+  

+  MaxEntries      - MaxEntries of the ordered list

+  

+  PromptToken     - Prompt string token of the ordered list

+  

+  HelpToken       - Help string token of the ordered list

+  

+  OptionsList     - Each string in it is an option of the ordered list

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - Output of ordered list as a form

+  

+Returns: 

+

+  EFI_SUCCESS     - Ordered list created to be a form

+

+--*/

+;

+

+EFI_STATUS

+CreateCheckBoxOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a checkbox opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+

+  QuestionId      - Question ID of the check box

+  

+  DataWidth       - DataWidth of the check box

+  

+  PromptToken     - Prompt string token of the check box

+  

+  HelpToken       - Help string token of the check box

+  

+  Flags           - Flags of the check box

+  

+  Key             - Key of the check box

+  

+  FormBuffer      - Output of the check box as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - Checkbox created to be a form

+  

+  EFI_DEVICE_ERROR  - DataWidth > 1

+

+--*/

+;

+

+EFI_STATUS

+CreateNumericOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      UINT16              Minimum,

+  IN      UINT16              Maximum,

+  IN      UINT16              Step,

+  IN      UINT16              Default,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a numeric opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+

+  QuestionId      - Question ID of the numeric

+  

+  DataWidth       - DataWidth of the numeric

+  

+  PromptToken     - Prompt string token of the numeric

+  

+  HelpToken       - Help string token of the numeric

+  

+  Minimum         - Minumun boundary of the numeric

+  

+  Maximum         - Maximum boundary of the numeric

+  

+  Step            - Step of the numeric

+  

+  Default         - Default value of the numeric

+  

+  Flags           - Flags of the numeric

+  

+  Key             - Key of the numeric

+  

+  FormBuffer      - Output of the numeric as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - The numeric created to be a form.

+  

+  EFI_DEVICE_ERROR  - DataWidth > 2

+

+--*/

+;

+

+EFI_STATUS

+CreateStringOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      UINT8               MinSize,

+  IN      UINT8               MaxSize,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a numeric opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+

+  QuestionId      - Question ID of the string

+  

+  DataWidth       - DataWidth of the string

+  

+  PromptToken     - Prompt token of the string

+  

+  HelpToken       - Help token of the string

+  

+  MinSize         - Min size boundary of the string

+  

+  MaxSize         - Max size boundary of the string

+    

+  Flags           - Flags of the string

+  

+  Key             - Key of the string

+  

+  FormBuffer      - Output of the string as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - String created to be a form.

+

+--*/

+;

+

+EFI_STATUS

+ValidateDataFromHiiHandle (

+  IN      EFI_HII_HANDLE      HiiHandle,

+  OUT     BOOLEAN             *Results

+  )

+/*++

+

+Routine Description:

+

+  Validate that the data associated with the HiiHandle in NVRAM is within

+  the reasonable parameters for that FormSet.  Values for strings and passwords

+  are not verified due to their not having the equivalent of valid range settings.

+  

+Arguments:

+

+  HiiHandle -   Handle of the HII database entry to query

+

+  Results -     If return Status is EFI_SUCCESS, Results provides valid data

+                TRUE  = NVRAM Data is within parameters

+                FALSE = NVRAM Data is NOT within parameters

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Data successfully validated

+--*/

+;

+

+EFI_STATUS

+CreateBannerOpCode (

+  IN      UINT16              Title,

+  IN      UINT16              LineNumber,

+  IN      UINT8               Alignment,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a banner opcode.  This is primarily used by the FrontPage implementation from BDS.

+  

+Arguments:

+

+  Title       - Title of the banner

+  

+  LineNumber  - LineNumber of the banner

+  

+  Alignment   - Alignment of the banner

+  

+  FormBuffer  - Output of banner as a form

+  

+Returns: 

+

+  EFI_SUCCESS     - Banner created to be a form.

+

+--*/

+;

+

+VOID

+EfiLibHiiVariablePackGetMap (

+  IN    EFI_HII_VARIABLE_PACK        *Pack,  

+  OUT   CHAR16                       **Name,  OPTIONAL

+  OUT   EFI_GUID                     **Guid,  OPTIONAL

+  OUT   UINT16                       *Id,     OPTIONAL

+  OUT   VOID                         **Var,   OPTIONAL

+  OUT   UINTN                        *Size    OPTIONAL

+  ) 

+/*++

+

+Routine Description:

+

+  Extracts a variable form a Pack.

+

+Arguments:

+

+  Pack - List of variables

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns: 

+

+  VOID.

+

+--*/

+;

+

+UINTN

+EfiLibHiiVariablePackListGetMapCnt (

+  IN    EFI_HII_VARIABLE_PACK_LIST   *List

+  )

+/*++

+

+Routine Description:

+

+  Finds a count of the variables/maps in the List.

+

+Arguments:

+

+  List - List of variables

+

+Returns: 

+

+  Number of Map in the variable pack list.

+

+--*/

+;

+

+typedef VOID (EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK) (

+  IN CHAR16                      *Name,

+  IN EFI_GUID                    *Guid,

+  IN UINT16                      Id,

+  IN VOID                        *Var,

+  IN UINTN                       Size

+  )  

+/*++

+

+Routine Description:

+

+  type definition for the callback to be 

+  used with EfiLibHiiVariablePackListForEachVar().

+

+Arguments:

+

+  Id   - Variable/Map ID

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns: 

+

+  VOID

+

+--*/

+;

+

+VOID

+EfiLibHiiVariablePackListForEachVar (

+  IN    EFI_HII_VARIABLE_PACK_LIST               *List,

+  IN    EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK  *Callback

+  )

+/*++

+

+Routine Description:

+

+  Will iterate all variable/maps as appearing 

+  in List and for each, it will call the Callback.

+

+Arguments:

+

+  List     - List of variables

+  Callback - Routine to be called for each iterated variable.

+

+Returns: 

+

+  VOID

+

+--*/

+;

+

+EFI_STATUS

+EfiLibHiiVariablePackListGetMapByIdx (

+  IN    UINTN                         Idx,  

+  IN    EFI_HII_VARIABLE_PACK_LIST    *List,  

+  OUT   CHAR16                        **Name,  OPTIONAL

+  OUT   EFI_GUID                      **Guid,  OPTIONAL

+  OUT   UINT16                        *Id,    OPTIONAL

+  OUT   VOID                          **Var,

+  OUT   UINTN                         *Size

+  ) 

+/*++

+

+Routine Description:

+

+  Finds a variable form List given 

+  the order number as appears in the List.

+

+Arguments:

+

+  Idx  - The index of the variable/map to retrieve

+  List - List of variables

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns:

+

+  EFI_SUCCESS   - Variable is found, OUT parameters are valid

+  EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid

+

+--*/

+;

+

+EFI_STATUS

+EfiLibHiiVariablePackListGetMapById (

+  IN    UINT16                        Id,  

+  IN    EFI_HII_VARIABLE_PACK_LIST    *List,

+  OUT   CHAR16                        **Name,  OPTIONAL

+  OUT   EFI_GUID                      **Guid,  OPTIONAL

+  OUT   VOID                          **Var,

+  OUT   UINTN                         *Size

+  ) 

+/*++

+

+Routine Description:

+

+  Finds a variable form List given the 

+  order number as appears in the List.

+

+Arguments:

+

+  Id   - The ID of the variable/map to retrieve

+  List - List of variables

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns:

+

+  EFI_SUCCESS   - Variable is found, OUT parameters are valid

+  EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid

+

+--*/

+;

+

+EFI_STATUS

+EfiLibHiiVariablePackListGetMap (

+  IN    EFI_HII_VARIABLE_PACK_LIST   *List,

+  IN    CHAR16                       *Name,

+  IN    EFI_GUID                     *Guid,

+  OUT   UINT16                       *Id,

+  OUT   VOID                         **Var, 

+  OUT   UINTN                        *Size

+  ) 

+/*++

+

+Routine Description:

+

+  Finds a variable form EFI_HII_VARIABLE_PACK_LIST given name and GUID.

+

+Arguments:

+

+  List - List of variables

+  Name - Name of the variable/map to be found

+  Guid - GUID of the variable/map to be found

+  Var  - Pointer to the variable/map found

+  Size - Size of the variable/map in bytes found

+

+Returns:

+

+  EFI_SUCCESS   - variable is found, OUT parameters are valid

+  EFI_NOT_FOUND - variable is not found, OUT parameters are not valid

+

+--*/

+;

+

+EFI_STATUS

+EfiLibHiiVariableRetrieveFromNv (

+  IN  CHAR16                     *Name,

+  IN  EFI_GUID                   *Guid,

+  IN  UINTN                      Size,

+  OUT VOID                       **Var

+  )

+/*++

+

+Routine Description:

+  Finds out if a variable of specific Name/Guid/Size exists in NV. 

+  If it does, it will retrieve it into the Var. 

+

+Arguments:

+  Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.

+  Var              - Variable will be retrieved into buffer pointed by this pointer.

+                     If pointing to NULL, the buffer will be allocated. Caller is responsible for releasing the buffer.

+Returns:

+  EFI_SUCCESS    - The variable of exact Name/Guid/Size parameters was retrieved and written to Var.

+  EFI_NOT_FOUND  - The variable of this Name/Guid was not found in the NV.

+  EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.

+

+--*/

+;

+

+////

+//// Variable override support.

+////

+

+EFI_STATUS

+EfiLibHiiVariableOverrideIfSuffix (

+  IN  CHAR16                 *Suffix,

+  IN  CHAR16                 *Name,

+  IN  EFI_GUID               *Guid,

+  IN  UINTN                   Size,

+  OUT VOID                   *Var

+  )  

+/*++

+

+Routine Description:

+  Overrrides the variable with NV data if found.

+  But it only does it if the Name ends with specified Suffix.

+  For example, if Suffix="MyOverride" and the Name="XyzSetupMyOverride",

+  the Suffix matches the end of Name, so the variable will be loaded from NV

+  provided the variable exists and the GUID and Size matches.

+

+Arguments:

+  Suffix           - Suffix the Name should end with.

+  Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.

+  Var              - Variable will be retrieved into this buffer.

+                     Caller is responsible for providing storage of exactly Size size in bytes.

+Returns:

+  EFI_SUCCESS           - The variable was overriden with NV variable of same Name/Guid/Size.

+  EFI_INVALID_PARAMETER - The name of the variable does not end with <Suffix>.

+  EFI_NOT_FOUND         - The variable of this Name/Guid was not found in the NV.

+  EFI_LOAD_ERROR        - The variable in the NV was of different size, or NV API returned error.

+

+--*/

+;

+

+EFI_STATUS

+EfiLibHiiVariableOverrideBySuffix (

+  IN  CHAR16                 *Suffix,

+  IN  CHAR16                 *Name,

+  IN  EFI_GUID               *Guid,

+  IN  UINTN                   Size,

+  OUT VOID                   *Var

+  ) 

+/*++

+

+Routine Description:

+  Overrrides the variable with NV data if found.

+  But it only does it if the NV contains the same variable with Name is appended with Suffix.  

+  For example, if Suffix="MyOverride" and the Name="XyzSetup",

+  the Suffix will be appended to the end of Name, and the variable with Name="XyzSetupMyOverride"

+  will be loaded from NV provided the variable exists and the GUID and Size matches.

+

+Arguments:

+  Suffix           - Suffix the variable will be appended with.

+  Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.

+  Var              - Variable will be retrieved into this buffer.

+                     Caller is responsible for providing storage of exactly Size size in bytes.

+

+Returns:

+  EFI_SUCCESS    - The variable was overriden with NV variable of same Name/Guid/Size.

+  EFI_NOT_FOUND  - The variable of this Name/Guid was not found in the NV.

+  EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkMemoryStatusCodeLib.h b/edk2/EdkModulePkg/Include/Library/EdkMemoryStatusCodeLib.h
new file mode 100644
index 0000000..08aaf69
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkMemoryStatusCodeLib.h
@@ -0,0 +1,48 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MemoryStatusCodeLib.h

+

+Abstract:

+

+  Lib to provide memory status code reporting.

+

+--*/

+

+#ifndef _PEI_MEMORY_STATUS_CODE_LIB_H_

+#define _PEI_MEMORY_STATUS_CODE_LIB_H_

+

+//

+// Initialization function

+//

+EFI_STATUS

+MemoryStatusCodeInitialize (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+;

+

+//

+// Status code reporting function

+//

+EFI_STATUS

+MemoryReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkPeCoffLoaderLib.h b/edk2/EdkModulePkg/Include/Library/EdkPeCoffLoaderLib.h
new file mode 100644
index 0000000..ccacf7e
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkPeCoffLoaderLib.h
@@ -0,0 +1,32 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EdkPeCoffLoaderLib.h

+

+Abstract:

+  Wrap the Base PE/COFF loader with the PE COFF Protocol

+

+  

+

+--*/

+

+#ifndef __EDK_PE_COFF_LOADER_LIB__

+#define __EDK_PE_COFF_LOADER_LIB__

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL *

+EFIAPI

+GetPeCoffLoaderProtocol (

+  VOID

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkPeCoffLoaderX64Lib.h b/edk2/EdkModulePkg/Include/Library/EdkPeCoffLoaderX64Lib.h
new file mode 100644
index 0000000..47756d3
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkPeCoffLoaderX64Lib.h
@@ -0,0 +1,33 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EdkPeCoffLoaderX64Lib.h

+

+Abstract:

+  Wrap the Base PE/COFF loader with the PE COFF Protocol

+

+  

+

+--*/

+

+#ifndef __EDK_PE_COFF_LOADER_X64_LIB__

+#define __EDK_PE_COFF_LOADER_X64_LIB__

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL *

+EFIAPI

+GetPeCoffLoaderX64Protocol (

+  VOID

+  );

+

+#endif

+

diff --git a/edk2/EdkModulePkg/Include/Library/EdkRtMemoryStatusCodeLib.h b/edk2/EdkModulePkg/Include/Library/EdkRtMemoryStatusCodeLib.h
new file mode 100644
index 0000000..02ae5a8
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkRtMemoryStatusCodeLib.h
@@ -0,0 +1,66 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  RtMemoryStatusCodeLib.h

+   

+Abstract:

+

+  Lib to provide memory status code reporting.

+

+--*/

+

+#ifndef _EFI_RT_MEMORY_STATUS_CODE_LIB_H_

+#define _EFI_RT_MEMORY_STATUS_CODE_LIB_H_

+

+//

+// Initialization function

+//

+VOID

+RtMemoryStatusCodeInitialize (

+  VOID

+  )

+;

+

+//

+// Status code reporting function

+//

+EFI_STATUS

+RtMemoryReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+//

+// Playback all prior status codes to a listener

+//

+typedef

+EFI_STATUS

+(*PLATFORM_REPORT_STATUS_CODE) (

+  IN EFI_STATUS_CODE_TYPE     Type,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId OPTIONAL,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  );

+

+VOID

+PlaybackStatusCodes (

+  IN PLATFORM_REPORT_STATUS_CODE  ReportStatusCode

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkRtPlatformStatusCodeLib.h b/edk2/EdkModulePkg/Include/Library/EdkRtPlatformStatusCodeLib.h
new file mode 100644
index 0000000..c0a6907
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkRtPlatformStatusCodeLib.h
@@ -0,0 +1,49 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  RtPlatformStatusCodeLib.h

+   

+Abstract:

+

+  Lib to provide platform implementations necessary for the Monolithic status

+  code to work.

+

+--*/

+

+#ifndef _EFI_PLATFORM_STATUS_CODE_LIB_H_

+#define _EFI_PLATFORM_STATUS_CODE_LIB_H_

+

+

+//

+// Initialization function

+//

+VOID

+RtPlatformStatusCodeInitialize (

+  VOID

+  )

+;

+

+//

+// Status code reporting function

+//

+EFI_STATUS

+RtPlatformReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkScsiLib.h b/edk2/EdkModulePkg/Include/Library/EdkScsiLib.h
new file mode 100644
index 0000000..bb1a1ad
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkScsiLib.h
@@ -0,0 +1,299 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ScsiLib.h

+

+ Abstract:

+

+   Common Libarary for SCSI

+

+ Revision History

+

+--*/

+

+#ifndef _SCSI_LIB_H

+#define _SCSI_LIB_H

+

+//

+// the time unit is 100ns, since the SCSI I/O defines timeout in 100ns unit.

+//

+#define EFI_SCSI_STALL_1_MICROSECOND  10

+#define EFI_SCSI_STALL_1_MILLISECOND  10000

+#define EFI_SCSI_STALL_1_SECOND       10000000

+

+//

+// this macro cannot be directly used by the gBS->Stall(),

+// since the value output by this macro is in 100ns unit,

+// not 1us unit (1us = 1000ns)

+//

+#define EfiScsiStallSeconds(a)  (a) * EFI_SCSI_STALL_1_SECOND

+

+EFI_STATUS

+SubmitTestUnitReadyCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  OUT VOID                  *SenseData,

+  OUT UINT8                 *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SubmitInquiryCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  IN OUT VOID               *InquiryDataBuffer,

+  IN OUT UINT32             *InquiryDataLength,

+  IN  BOOLEAN               EnableVitalProductData

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo                  - TODO: add argument description

+  Timeout                 - TODO: add argument description

+  SenseData               - TODO: add argument description

+  SenseDataLength         - TODO: add argument description

+  HostAdapterStatus       - TODO: add argument description

+  TargetStatus            - TODO: add argument description

+  InquiryDataBuffer       - TODO: add argument description

+  InquiryDataLength       - TODO: add argument description

+  EnableVitalProductData  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SubmitModeSense10Command (

+  IN  EFI_SCSI_IO_PROTOCOL    *ScsiIo,

+  IN  UINT64                  Timeout,

+  IN  VOID                    *SenseData,

+  IN OUT UINT8                *SenseDataLength,

+  OUT UINT8                   *HostAdapterStatus,

+  OUT UINT8                   *TargetStatus,

+  IN  VOID                    *DataBuffer,

+  IN OUT UINT32               *DataLength,

+  IN  UINT8                   DBDField, OPTIONAL

+  IN  UINT8                   PageControl,

+  IN  UINT8                   PageCode

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  DBDField          - TODO: add argument description

+  PageControl       - TODO: add argument description

+  PageCode          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SubmitRequestSenseCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Commands for direct access command

+//

+EFI_STATUS

+SubmitReadCapacityCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  OUT VOID                  *DataBuffer,

+  IN OUT UINT32             *DataLength,

+  IN  BOOLEAN               PMI

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  PMI               - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SubmitRead10Command (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  OUT VOID                  *DataBuffer,

+  IN OUT UINT32             *DataLength,

+  IN  UINT32                StartLba,

+  IN  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  StartLba          - TODO: add argument description

+  SectorSize        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SubmitWrite10Command (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  OUT VOID                  *DataBuffer,

+  IN OUT UINT32             *DataLength,

+  IN  UINT32                StartLba,

+  IN  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ScsiIo            - TODO: add argument description

+  Timeout           - TODO: add argument description

+  SenseData         - TODO: add argument description

+  SenseDataLength   - TODO: add argument description

+  HostAdapterStatus - TODO: add argument description

+  TargetStatus      - TODO: add argument description

+  DataBuffer        - TODO: add argument description

+  DataLength        - TODO: add argument description

+  StartLba          - TODO: add argument description

+  SectorSize        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/EdkUsbLib.h b/edk2/EdkModulePkg/Include/Library/EdkUsbLib.h
new file mode 100644
index 0000000..005e045
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/EdkUsbLib.h
@@ -0,0 +1,373 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+ Module Name:

+

+    UsbDxeLib.h

+

+ Abstract:

+

+   Common Dxe Libarary  for USB

+   Add Constants & structure definitions for Usb HID

+

+ Revision History

+

+--*/

+

+#ifndef _USB_DXE_LIB_H

+#define _USB_DXE_LIB_H

+

+//

+// define the timeout time as 3ms

+//

+#define TIMEOUT_VALUE 3 * 1000

+

+//

+// HID constants definition, see HID rev1.0

+//

+//

+// HID report item format

+//

+#define HID_ITEM_FORMAT_SHORT 0

+#define HID_ITEM_FORMAT_LONG  1

+

+//

+// Special tag indicating long items

+//

+#define HID_ITEM_TAG_LONG 15

+

+//

+// HID report descriptor item type (prefix bit 2,3)

+//

+#define HID_ITEM_TYPE_MAIN      0

+#define HID_ITEM_TYPE_GLOBAL    1

+#define HID_ITEM_TYPE_LOCAL     2

+#define HID_ITEM_TYPE_RESERVED  3

+

+//

+// HID report descriptor main item tags

+//

+#define HID_MAIN_ITEM_TAG_INPUT             8

+#define HID_MAIN_ITEM_TAG_OUTPUT            9

+#define HID_MAIN_ITEM_TAG_FEATURE           11

+#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION  10

+#define HID_MAIN_ITEM_TAG_END_COLLECTION    12

+

+//

+// HID report descriptor main item contents

+//

+#define HID_MAIN_ITEM_CONSTANT      0x001

+#define HID_MAIN_ITEM_VARIABLE      0x002

+#define HID_MAIN_ITEM_RELATIVE      0x004

+#define HID_MAIN_ITEM_WRAP          0x008

+#define HID_MAIN_ITEM_NONLINEAR     0x010

+#define HID_MAIN_ITEM_NO_PREFERRED  0x020

+#define HID_MAIN_ITEM_NULL_STATE    0x040

+#define HID_MAIN_ITEM_VOLATILE      0x080

+#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100

+

+//

+// HID report descriptor collection item types

+//

+#define HID_COLLECTION_PHYSICAL     0

+#define HID_COLLECTION_APPLICATION  1

+#define HID_COLLECTION_LOGICAL      2

+

+//

+// HID report descriptor global item tags

+//

+#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE        0

+#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM   1

+#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM   2

+#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM  3

+#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM  4

+#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT     5

+#define HID_GLOBAL_ITEM_TAG_UNIT              6

+#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE       7

+#define HID_GLOBAL_ITEM_TAG_REPORT_ID         8

+#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT      9

+#define HID_GLOBAL_ITEM_TAG_PUSH              10

+#define HID_GLOBAL_ITEM_TAG_POP               11

+

+//

+// HID report descriptor local item tags

+//

+#define HID_LOCAL_ITEM_TAG_USAGE              0

+#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM      1

+#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM      2

+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX   3

+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4

+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5

+#define HID_LOCAL_ITEM_TAG_STRING_INDEX       7

+#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM     8

+#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM     9

+#define HID_LOCAL_ITEM_TAG_DELIMITER          10

+

+//

+// HID usage tables

+//

+#define HID_USAGE_PAGE    0xffff0000

+

+#define HID_UP_GENDESK    0x00010000

+#define HID_UP_KEYBOARD   0x00070000

+#define HID_UP_LED        0x00080000

+#define HID_UP_BUTTON     0x00090000

+#define HID_UP_CONSUMER   0x000c0000

+#define HID_UP_DIGITIZER  0x000d0000

+#define HID_UP_PID        0x000f0000

+

+#define HID_USAGE         0x0000ffff

+

+#define HID_GD_POINTER    0x00010001

+#define HID_GD_MOUSE      0x00010002

+#define HID_GD_JOYSTICK   0x00010004

+#define HID_GD_GAMEPAD    0x00010005

+#define HID_GD_HATSWITCH  0x00010039

+

+//

+// HID report types

+//

+#define HID_INPUT_REPORT    1

+#define HID_OUTPUT_REPORT   2

+#define HID_FEATURE_REPORT  3

+

+//

+// HID device quirks.

+//

+#define HID_QUIRK_INVERT  0x01

+#define HID_QUIRK_NOTOUCH 0x02

+

+//

+// HID class protocol request

+//

+#define EFI_USB_GET_REPORT_REQUEST    0x01

+#define EFI_USB_GET_IDLE_REQUEST      0x02

+#define EFI_USB_GET_PROTOCOL_REQUEST  0x03

+#define EFI_USB_SET_REPORT_REQUEST    0x09

+#define EFI_USB_SET_IDLE_REQUEST      0x0a

+#define EFI_USB_SET_PROTOCOL_REQUEST  0x0b

+

+#pragma pack(1)

+//

+// Descriptor header for Report/Physical Descriptors

+//

+typedef struct hid_class_descriptor {

+  UINT8   DescriptorType;

+  UINT16  DescriptorLength;

+} EFI_USB_HID_CLASS_DESCRIPTOR;

+

+typedef struct hid_descriptor {

+  UINT8                         Length;

+  UINT8                         DescriptorType;

+  UINT16                        BcdHID;

+  UINT8                         CountryCode;

+  UINT8                         NumDescriptors;

+  EFI_USB_HID_CLASS_DESCRIPTOR  HidClassDesc[1];

+} EFI_USB_HID_DESCRIPTOR;

+

+#pragma pack()

+

+EFI_STATUS

+UsbGetHidDescriptor (

+  IN  EFI_USB_IO_PROTOCOL        *UsbIo,

+  IN  UINT8                      InterfaceNum,

+  OUT EFI_USB_HID_DESCRIPTOR     *HidDescriptor

+  );

+

+EFI_STATUS

+UsbGetReportDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   InterfaceNum,

+  IN  UINT16                  DescriptorSize,

+  OUT UINT8                   *DescriptorBuffer

+  );

+

+EFI_STATUS

+UsbGetProtocolRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   *Protocol

+  );

+

+EFI_STATUS

+UsbSetProtocolRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   Protocol

+  );

+

+EFI_STATUS

+UsbSetIdleRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   Duration

+  );

+

+EFI_STATUS

+UsbGetIdleRequest (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Interface,

+  IN  UINT8                   ReportId,

+  OUT UINT8                   *Duration

+  );

+

+EFI_STATUS

+UsbSetReportRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   ReportType,

+  IN UINT16                  ReportLen,

+  IN UINT8                   *Report

+  );

+

+EFI_STATUS

+UsbGetReportRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   ReportType,

+  IN UINT16                  ReportLen,

+  IN UINT8                   *Report

+  );

+

+//

+// Get Device Descriptor

+//

+EFI_STATUS

+UsbGetDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  IN  UINT16                  Index,

+  IN  UINT16                  DescriptorLength,

+  OUT VOID                    *Descriptor,

+  OUT UINT32                  *Status

+  );

+

+//

+// Set Device Descriptor

+//

+EFI_STATUS

+UsbSetDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  IN  UINT16                  Index,

+  IN  UINT16                  DescriptorLength,

+  IN  VOID                    *Descriptor,

+  OUT UINT32                  *Status

+  );

+

+//

+// Get device Interface

+//

+EFI_STATUS

+UsbGetDeviceInterface (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Index,

+  OUT UINT8                   *AltSetting,

+  OUT UINT32                  *Status

+  );

+

+//

+// Set device interface

+//

+EFI_STATUS

+UsbSetDeviceInterface (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  InterfaceNo,

+  IN  UINT16                  AltSetting,

+  OUT UINT32                  *Status

+  );

+

+//

+// Get device configuration

+//

+EFI_STATUS

+UsbGetDeviceConfiguration (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  OUT UINT8                   *ConfigValue,

+  OUT UINT32                  *Status

+  );

+

+//

+// Set device configuration

+//

+EFI_STATUS

+UsbSetDeviceConfiguration (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  OUT UINT32                  *Status

+  );

+

+//

+//  Set Device Feature

+//

+EFI_STATUS

+UsbSetDeviceFeature (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  EFI_USB_RECIPIENT       Recipient,

+  IN  UINT16                  Value,

+  IN  UINT16                  Target,

+  OUT UINT32                  *Status

+  );

+

+//

+// Clear Device Feature

+//

+EFI_STATUS

+UsbClearDeviceFeature (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  EFI_USB_RECIPIENT       Recipient,

+  IN  UINT16                  Value,

+  IN  UINT16                  Target,

+  OUT UINT32                  *Status

+  );

+

+//

+//  Get Device Status

+//

+EFI_STATUS

+UsbGetDeviceStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  EFI_USB_RECIPIENT       Recipient,

+  IN  UINT16                  Target,

+  OUT UINT16                  *DevStatus,

+  OUT UINT32                  *Status

+  );

+

+//

+// The following APIs are not basic library, but they are common used.

+//

+//

+// Usb Get String

+//

+EFI_STATUS

+UsbGetString (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  LangID,

+  IN  UINT8                   Index,

+  IN  VOID                    *Buf,

+  IN  UINTN                   BufSize,

+  OUT UINT32                  *Status

+  );

+

+//

+// Clear endpoint stall

+//

+EFI_STATUS

+UsbClearEndpointHalt (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   EndpointNo,

+  OUT UINT32                  *Status

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Library/TianoDecompressLib.h b/edk2/EdkModulePkg/Include/Library/TianoDecompressLib.h
new file mode 100644
index 0000000..58e9426
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Library/TianoDecompressLib.h
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  TianoDecompressLib.h

+

+Abstract:

+

+  Tiano Decompress functions

+

+--*/

+

+#ifndef __TIANO_DECPOMPRESS_LIB_H__

+#define __TIANO_DECPOMPRESS_LIB_H__

+

+RETURN_STATUS

+EFIAPI

+TianoDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  );

+

+RETURN_STATUS

+EFIAPI

+TianoDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Ppi/BaseMemoryTest.h b/edk2/EdkModulePkg/Include/Ppi/BaseMemoryTest.h
new file mode 100644
index 0000000..8b0be6e
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Ppi/BaseMemoryTest.h
@@ -0,0 +1,56 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BaseMemoryTest.h

+

+Abstract:

+

+  Pei memory test PPI as defined in Tiano

+

+  Used to Pei memory test in PEI

+

+--*/

+

+#ifndef _BASE_MEMORY_TEST_H_

+#define _BASE_MEMORY_TEST_H_

+

+#define PEI_BASE_MEMORY_TEST_GUID \

+  { 0xb6ec423c, 0x21d2, 0x490d, {0x85, 0xc6, 0xdd, 0x58, 0x64, 0xea, 0xa6, 0x74 } }

+

+typedef struct _PEI_BASE_MEMORY_TEST_PPI  PEI_BASE_MEMORY_TEST_PPI;

+

+typedef enum {

+  Ignore,

+  Quick,

+  Sparse,

+  Extensive

+} PEI_MEMORY_TEST_OP;

+

+typedef

+EFI_STATUS

+(EFIAPI *PEI_BASE_MEMORY_TEST) (

+  IN  EFI_PEI_SERVICES                   **PeiServices,

+  IN PEI_BASE_MEMORY_TEST_PPI            * This,

+  IN  EFI_PHYSICAL_ADDRESS               BeginAddress,

+  IN  UINT64                             MemoryLength,

+  IN  PEI_MEMORY_TEST_OP                 Operation,

+  OUT EFI_PHYSICAL_ADDRESS               * ErrorAddress

+  );

+

+struct _PEI_BASE_MEMORY_TEST_PPI {

+  PEI_BASE_MEMORY_TEST  BaseMemoryTest;

+};

+

+extern EFI_GUID gPeiBaseMemoryTestPpiGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Ppi/FlashMap.h b/edk2/EdkModulePkg/Include/Ppi/FlashMap.h
new file mode 100644
index 0000000..312f38b
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Ppi/FlashMap.h
@@ -0,0 +1,52 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FlashMap.h

+

+Abstract:

+

+  FlashMap PPI defined in Tiano

+

+  This code abstracts FlashMap access

+

+--*/

+

+#ifndef _PEI_FLASH_MAP_PPI_H_

+#define _PEI_FLASH_MAP_PPI_H_

+

+#define PEI_FLASH_MAP_PPI_GUID \

+  { 0xf34c2fa0, 0xde88, 0x4270, {0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c } }

+

+typedef struct _PEI_FLASH_MAP_PPI PEI_FLASH_MAP_PPI;

+//

+// Functions

+//

+typedef

+EFI_STATUS

+(EFIAPI *PEI_GET_FLASH_AREA_INFO) (

+  IN  EFI_PEI_SERVICES            **PeiServices,

+  IN  PEI_FLASH_MAP_PPI            *This,

+  IN  EFI_FLASH_AREA_TYPE         AreaType,

+  IN  EFI_GUID                    *AreaTypeGuid,

+  OUT UINT32                      *NumEntries,

+  OUT EFI_FLASH_SUBAREA_ENTRY     **Entries

+  );

+

+

+struct _PEI_FLASH_MAP_PPI {

+  PEI_GET_FLASH_AREA_INFO GetAreaInfo;

+};

+

+extern EFI_GUID gPeiFlashMapPpiGuid;

+

+#endif 

diff --git a/edk2/EdkModulePkg/Include/Ppi/PeiInMemory.h b/edk2/EdkModulePkg/Include/Ppi/PeiInMemory.h
new file mode 100644
index 0000000..74d0905
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Ppi/PeiInMemory.h
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PeiInMemory.h

+    

+Abstract:

+

+  

+--*/

+

+#ifndef __PEI_IN_MEMORY_H__

+#define __PEI_IN_MEMORY_H__

+        

+#define PEI_IN_MEMORY_GUID \

+  {0x643b8786, 0xb417, 0x48d2, {0x8f, 0x5e, 0x78, 0x19, 0x93, 0x1c, 0xae, 0xd8} }

+  

+extern EFI_GUID gPeiInMemoryGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Ppi/StatusCodeMemory.h b/edk2/EdkModulePkg/Include/Ppi/StatusCodeMemory.h
new file mode 100644
index 0000000..85b2b6d
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Ppi/StatusCodeMemory.h
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StatusCodeMemory.h

+    

+Abstract:

+

+  Status Code memory descriptor PPI.  Contains information about memory that 

+  the Status Code PEIM may use to journal Status Codes.

+

+--*/

+

+#ifndef _PEI_STATUS_CODE_MEMORY_PPI_H_

+#define _PEI_STATUS_CODE_MEMORY_PPI_H_

+

+//

+// GUID definition

+//

+#define PEI_STATUS_CODE_MEMORY_PPI_GUID \

+  { 0x26f8ab01, 0xd3cd, 0x489c, {0x98, 0x4f, 0xdf, 0xde, 0xf7, 0x68, 0x39, 0x5b } }

+

+//

+// Data types

+//

+typedef struct {

+  EFI_STATUS_CODE_TYPE    Type;

+  EFI_STATUS_CODE_VALUE   Value;

+  UINT32                  Instance;

+} EFI_STATUS_CODE_ENTRY;

+

+//

+// PPI definition

+//

+typedef struct {

+  UINTN                   FirstEntry;

+  UINTN                   LastEntry;

+  EFI_PHYSICAL_ADDRESS    Address;

+  UINTN                   Length;

+} PEI_STATUS_CODE_MEMORY_PPI;

+

+extern EFI_GUID gPeiStatusCodeMemoryPpiGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/AcpiS3Save.h b/edk2/EdkModulePkg/Include/Protocol/AcpiS3Save.h
new file mode 100644
index 0000000..1571e3d
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/AcpiS3Save.h
@@ -0,0 +1,61 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  AcpiS3Save.h

+

+Abstract:

+

+  

+--*/

+

+#ifndef _ACPI_S3_SAVE_PROTOCOL_H

+#define _ACPI_S3_SAVE_PROTOCOL_H

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_ACPI_S3_SAVE_PROTOCOL EFI_ACPI_S3_SAVE_PROTOCOL;

+

+//

+// S3 Save Protocol GUID

+//

+#define EFI_ACPI_S3_SAVE_GUID \

+  { \

+    0x125f2de1, 0xfb85, 0x440c, {0xa5, 0x4c, 0x4d, 0x99, 0x35, 0x8a, 0x8d, 0x38 } \

+  }

+

+//

+// Protocol Data Structures

+//

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ACPI_S3_SAVE) (

+  IN EFI_ACPI_S3_SAVE_PROTOCOL      * This,

+  IN VOID                           * LegacyMemoryAddress 

+  );

+

+typedef 

+EFI_STATUS  

+(EFIAPI *EFI_ACPI_GET_LEGACY_MEMORY_SIZE) (

+  IN  EFI_ACPI_S3_SAVE_PROTOCOL     * This,

+  OUT UINTN                         * Size

+);

+

+struct _EFI_ACPI_S3_SAVE_PROTOCOL {

+  EFI_ACPI_GET_LEGACY_MEMORY_SIZE   GetLegacyMemorySize;

+  EFI_ACPI_S3_SAVE                  S3Save;

+};

+

+extern EFI_GUID gEfiAcpiS3SaveProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/ConsoleControl.h b/edk2/EdkModulePkg/Include/Protocol/ConsoleControl.h
new file mode 100644
index 0000000..c894302
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/ConsoleControl.h
@@ -0,0 +1,121 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConsoleControl.h

+

+Abstract:

+

+  Abstraction of a Text mode or UGA screen

+

+--*/

+

+#ifndef __CONSOLE_CONTROL_H__

+#define __CONSOLE_CONTROL_H__

+

+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \

+  { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }

+

+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL   EFI_CONSOLE_CONTROL_PROTOCOL;

+

+

+typedef enum {

+  EfiConsoleControlScreenText,

+  EfiConsoleControlScreenGraphics,

+  EfiConsoleControlScreenMaxValue

+} EFI_CONSOLE_CONTROL_SCREEN_MODE;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,

+  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE   *Mode,

+  OUT BOOLEAN                           *UgaExists,   OPTIONAL  

+  OUT BOOLEAN                           *StdInLocked  OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Return the current video mode information. Also returns info about existence

+    of UGA Draw devices in system, and if the Std In device is locked. All the

+    arguments are optional and only returned if a non NULL pointer is passed in.

+

+  Arguments:

+    This - Protocol instance pointer.

+    Mode        - Are we in text of grahics mode.

+    UgaExists   - TRUE if UGA Spliter has found a UGA device

+    StdInLocked - TRUE if StdIn device is keyboard locked

+

+  Returns:

+    EFI_SUCCESS     - Mode information returned.

+

+--*/

+;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,

+  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE   Mode

+  )

+/*++

+

+  Routine Description:

+    Set the current mode to either text or graphics. Graphics is

+    for Quiet Boot.

+

+  Arguments:

+    This  - Protocol instance pointer.

+    Mode  - Mode to set the 

+

+  Returns:

+    EFI_SUCCESS     - Mode information returned.

+

+--*/

+;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,

+  IN CHAR16                             *Password

+  )

+/*++

+

+  Routine Description:

+    Lock Std In devices until Password is typed.

+

+  Arguments:

+    This     - Protocol instance pointer.

+    Password - Password needed to unlock screen. NULL means unlock keyboard

+

+  Returns:

+    EFI_SUCCESS      - Mode information returned.

+    EFI_DEVICE_ERROR - Std In not locked

+

+--*/

+;

+

+

+

+struct _EFI_CONSOLE_CONTROL_PROTOCOL {

+  EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE           GetMode;

+  EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE           SetMode;

+  EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN        LockStdIn;

+};

+

+extern EFI_GUID gEfiConsoleControlProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/CustomizedDecompress.h b/edk2/EdkModulePkg/Include/Protocol/CustomizedDecompress.h
new file mode 100644
index 0000000..bff8d46
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/CustomizedDecompress.h
@@ -0,0 +1,137 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  CustomizedDecompress.h

+    

+Abstract:

+  The user Customized Decompress Protocol Interface

+

+--*/

+

+#ifndef __CUSTOMIZED_DECOMPRESS_H__

+#define __CUSTOMIZED_DECOMPRESS_H__

+

+#define EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID \

+  { 0x9a44198e, 0xa4a2, 0x44e6, {0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f } }

+

+typedef struct _EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL    EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CUSTOMIZED_DECOMPRESS_GET_INFO) (

+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL       *This,

+  IN   VOID                                   *Source,

+  IN   UINT32                                 SourceSize,

+  OUT  UINT32                                 *DestinationSize,

+  OUT  UINT32                                 *ScratchSize

+  );

+/*++

+

+Routine Description:

+

+  The GetInfo() function retrieves the size of the uncompressed buffer 

+  and the temporary scratch buffer required to decompress the buffer 

+  specified by Source and SourceSize.  If the size of the uncompressed

+  buffer or the size of the scratch buffer cannot be determined from 

+  the compressed data specified by Source and SourceData, then 

+  EFI_INVALID_PARAMETER is returned.  Otherwise, the size of the uncompressed

+  buffer is returned in DestinationSize, the size of the scratch buffer is 

+  returned in ScratchSize, and EFI_SUCCESS is returned.

+  

+  The GetInfo() function does not have scratch buffer available to perform 

+  a thorough checking of the validity of the source data. It just retrieves

+  the 'Original Size' field from the beginning bytes of the source data and

+  output it as DestinationSize.  And ScratchSize is specific to the decompression

+  implementation.

+

+Arguments:

+

+  This            - The protocol instance pointer

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size, in bytes, of source buffer.

+  DestinationSize - A pointer to the size, in bytes, of the uncompressed buffer

+                    that will be generated when the compressed buffer specified 

+                    by Source and SourceSize is decompressed.

+  ScratchSize     - A pointer to the size, in bytes, of the scratch buffer that 

+                    is required to decompress the compressed buffer specified by

+                    Source and SourceSize.

+

+Returns:

+  EFI_SUCCESS     - The size of the uncompressed data was returned in DestinationSize

+                    and the size of the scratch buffer was returned in ScratchSize.

+  EFI_INVALID_PARAMETER - The size of the uncompressed data or the size of the scratch

+                  buffer cannot be determined from the compressed data specified by 

+                  Source and SourceData.

+

+--*/

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CUSTOMIZED_DECOMPRESS_DECOMPRESS) (

+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL         *This,

+  IN     VOID*                                  Source,

+  IN     UINT32                                 SourceSize,

+  IN OUT VOID*                                  Destination,

+  IN     UINT32                                 DestinationSize,

+  IN OUT VOID*                                  Scratch,

+  IN     UINT32                                 ScratchSize

+  );

+/*++

+

+Routine Description:

+

+  The Decompress() function extracts decompressed data to its original form.

+  

+  This protocol is designed so that the decompression algorithm can be 

+  implemented without using any memory services.  As a result, the 

+  Decompress() function is not allowed to call AllocatePool() or 

+  AllocatePages() in its implementation.  It is the caller's responsibility 

+  to allocate and free the Destination and Scratch buffers.

+  

+  If the compressed source data specified by Source and SourceSize is 

+  sucessfully decompressed into Destination, then EFI_SUCCESS is returned.  

+  If the compressed source data specified by Source and SourceSize is not in 

+  a valid compressed data format, then EFI_INVALID_PARAMETER is returned.

+

+Arguments:

+

+  This            - The protocol instance pointer

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source data.

+  Destination     - On output, the destination buffer that contains 

+                    the uncompressed data.

+  DestinationSize - The size of destination buffer. The size of destination

+                    buffer needed is obtained from GetInfo().

+  Scratch         - A temporary scratch buffer that is used to perform the 

+                    decompression.

+  ScratchSize     - The size of scratch buffer. The size of scratch buffer needed

+                    is obtained from GetInfo().

+

+Returns:

+

+  EFI_SUCCESS     - Decompression completed successfully, and the uncompressed 

+                    buffer is returned in Destination.

+  EFI_INVALID_PARAMETER 

+                  - The source buffer specified by Source and SourceSize is 

+                    corrupted (not in a valid compressed format).

+

+--*/

+

+struct _EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL {

+  EFI_CUSTOMIZED_DECOMPRESS_GET_INFO    GetInfo;

+  EFI_CUSTOMIZED_DECOMPRESS_DECOMPRESS  Decompress;

+};

+

+extern EFI_GUID gEfiCustomizedDecompressProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/DebugAssert.h b/edk2/EdkModulePkg/Include/Protocol/DebugAssert.h
new file mode 100644
index 0000000..9d26d83
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/DebugAssert.h
@@ -0,0 +1,89 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugAssert.h

+

+Abstract:

+

+  This protocol allows provides debug services to a driver. This is not 

+  debugger support, but things like ASSERT() and DEBUG() macros

+

+--*/

+

+#ifndef _DEBUG_ASSERT_H_

+#define _DEBUG_ASSERT_H_

+

+

+#define EFI_DEBUG_ASSERT_PROTOCOL_GUID \

+  { 0xbe499c92, 0x7d4b, 0x11d4, {0xbc, 0xee, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_DEBUG_ASSERT_PROTOCOL EFI_DEBUG_ASSERT_PROTOCOL;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEBUG_ASSERT) (

+  IN EFI_DEBUG_ASSERT_PROTOCOL  *This,

+  IN CHAR8                              *FileName,

+  IN INTN                               LineNumber,

+  IN CHAR8                              *Description

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEBUG_PRINT) (

+  IN EFI_DEBUG_ASSERT_PROTOCOL  *This,

+  IN  UINTN                             ErrorLevel,

+  IN  CHAR8                             *Format,

+  IN  VA_LIST                           Marker

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_POST_CODE) (

+  IN EFI_DEBUG_ASSERT_PROTOCOL  *This,

+  IN  UINT16                            PostCode,

+  IN  CHAR8                             *PostCodeString  OPTIONAL

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_ERROR_LEVEL) (

+  IN EFI_DEBUG_ASSERT_PROTOCOL  *This,

+  IN  UINTN                             *ErrorLevel

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_ERROR_LEVEL) (

+  IN EFI_DEBUG_ASSERT_PROTOCOL  *This,

+  IN  UINTN                             ErrorLevel

+  );

+

+struct _EFI_DEBUG_ASSERT_PROTOCOL {

+  

+  EFI_DEBUG_ASSERT    Assert;

+  EFI_DEBUG_PRINT     Print;

+  EFI_POST_CODE       PostCode;

+

+  EFI_GET_ERROR_LEVEL GetErrorLevel;

+  EFI_SET_ERROR_LEVEL SetErrorLevel;

+

+};

+

+extern EFI_GUID gEfiDebugAssertProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/DebugLevel.h b/edk2/EdkModulePkg/Include/Protocol/DebugLevel.h
new file mode 100644
index 0000000..9c5f06a
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/DebugLevel.h
@@ -0,0 +1,40 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugLevel.h

+

+Abstract:

+  This protocol is used to abstract the Debug Mask serivces for 

+  the specific driver or application image.

+

+--*/

+

+#ifndef __DEBUG_LEVEL_H__

+#define __DEBUG_LEVEL_H__

+

+//

+// 8D4C62E6-CD98-4e1d-AD6E-48BB50D29FF7

+//

+#define EFI_DEBUG_LEVEL_PROTOCOL_GUID \

+  { 0x8d4c62e6, 0xcd98, 0x4e1d, {0xad, 0x6e, 0x48, 0xbb, 0x50, 0xd2, 0x9f, 0xf7 } }

+

+//

+// DebugLevel protocol definition

+//

+typedef struct _EFI_DEBUG_LEVEL_PROTOCOL {

+  UINTN  DebugLevel;

+} EFI_DEBUG_LEVEL_PROTOCOL;

+

+extern EFI_GUID gEfiDebugLevelProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/DiskInfo.h b/edk2/EdkModulePkg/Include/Protocol/DiskInfo.h
new file mode 100644
index 0000000..6952163
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/DiskInfo.h
@@ -0,0 +1,179 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    DiskInfo.h

+

+Abstract:

+

+  Disk Info protocol is used to export Inquiry Data for a drive.

+  Its needed to support low level formating of drives in a mannor

+  thats DOS compatible.

+

+--*/

+

+#ifndef __DISK_INFO_H__

+#define __DISK_INFO_H__

+

+#define EFI_DISK_INFO_PROTOCOL_GUID \

+  { \

+    0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27 } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_DISK_INFO_PROTOCOL  EFI_DISK_INFO_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISK_INFO_INQUIRY) (

+  IN EFI_DISK_INFO_PROTOCOL           * This,

+  IN OUT VOID                         *InquiryData,

+  IN OUT UINT32                       *IntquiryDataSize

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Inquiry command to a drive in InquiryData.

+    Data format of Inquiry data is defined by the Interface GUID.

+

+  Arguments:

+    This        - Protocol instance pointer.

+    InquiryData - Results of Inquiry command to device

+    InquiryDataSize - Size of InquiryData in bytes.

+

+  Returns:

+    EFI_SUCCESS       - InquiryData valid

+    EFI_NOT_FOUND     - Device does not support this data class

+    EFI_DEVICE_ERROR  - Error reading InquiryData from device 

+    EFI_BUFFER_TOO_SMALL - IntquiryDataSize not big enough

+

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISK_INFO_IDENTIFY) (

+  IN EFI_DISK_INFO_PROTOCOL           * This,

+  IN OUT VOID                         *IdentifyData,

+  IN OUT UINT32                       *IdentifyDataSize

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Identify command to a drive in IdentifyData.

+    Data format of Identify data is defined by the Interface GUID.

+

+  Arguments:

+    This        - Protocol instance pointer.

+    IdentifyData - Results of Identify command to device

+    IdentifyDataSize - Size of IdentifyData in bytes.

+

+  Returns:

+    EFI_SUCCESS       - IdentifyData valid

+    EFI_NOT_FOUND     - Device does not support this data class

+    EFI_DEVICE_ERROR  - Error reading IdentifyData from device 

+    EFI_BUFFER_TOO_SMALL - IdentifyDataSize not big enough

+

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISK_INFO_SENSE_DATA) (

+  IN EFI_DISK_INFO_PROTOCOL           * This,

+  IN OUT VOID                         *SenseData,

+  IN OUT UINT32                       *SenseDataSize,

+  OUT UINT8                           *SenseDataNumber

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Request Sense command to a drive in SenseData.

+    Data format of Sense data is defined by the Interface GUID.

+

+  Arguments:

+    This            - Protocol instance pointer.

+    SenseData       - Results of Request Sense command to device

+    SenseDataSize   - Size of SenseData in bytes.

+    SenseDataNumber - Type of SenseData

+

+  Returns:

+    EFI_SUCCESS       - InquiryData valid

+    EFI_NOT_FOUND     - Device does not support this data class

+    EFI_DEVICE_ERROR  - Error reading InquiryData from device 

+    EFI_BUFFER_TOO_SMALL - SenseDataSize not big enough

+

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISK_INFO_WHICH_IDE) (

+  IN EFI_DISK_INFO_PROTOCOL           * This,

+  OUT UINT32                          *IdeChannel,

+  OUT UINT32                          *IdeDevice

+  )

+/*++

+

+  Routine Description:

+    Return the results of the Request Sense command to a drive in SenseData.

+    Data format of Sense data is defined by the Interface GUID.

+

+  Arguments:

+    This        - Protocol instance pointer.

+    IdeChannel  - Primary or Secondary

+    IdeDevice   - Master or Slave

+

+  Returns:

+    EFI_SUCCESS       - IdeChannel and IdeDevice are valid

+    EFI_UNSUPPORTED   - This is not an IDE device

+

+--*/

+;

+

+//

+// GUIDs for EFI_DISK_INFO_PROTOCOL.Interface. Defines the format of the

+// buffers returned by member functions

+//

+#define EFI_DISK_INFO_IDE_INTERFACE_GUID \

+  { \

+    0x5e948fe3, 0x26d3, 0x42b5, {0xaf, 0x17, 0x61, 0x2, 0x87, 0x18, 0x8d, 0xec } \

+  }

+extern EFI_GUID gEfiDiskInfoIdeInterfaceGuid;

+

+#define EFI_DISK_INFO_SCSI_INTERFACE_GUID \

+  { \

+    0x8f74baa, 0xea36, 0x41d9, {0x95, 0x21, 0x21, 0xa7, 0xf, 0x87, 0x80, 0xbc } \

+  }

+extern EFI_GUID gEfiDiskInfoScsiInterfaceGuid;

+

+#define EFI_DISK_INFO_USB_INTERFACE_GUID \

+  { \

+    0xcb871572, 0xc11a, 0x47b5, {0xb4, 0x92, 0x67, 0x5e, 0xaf, 0xa7, 0x77, 0x27 } \

+  }

+extern EFI_GUID gEfiDiskInfoUsbInterfaceGuid;

+

+struct _EFI_DISK_INFO_PROTOCOL {

+  EFI_GUID                  Interface;

+  EFI_DISK_INFO_INQUIRY     Inquiry;

+  EFI_DISK_INFO_IDENTIFY    Identify;

+  EFI_DISK_INFO_SENSE_DATA  SenseData;

+  EFI_DISK_INFO_WHICH_IDE   WhichIde;

+};

+

+extern EFI_GUID gEfiDiskInfoProtocolGuid;

+

+#endif

+

+

diff --git a/edk2/EdkModulePkg/Include/Protocol/EdkDecompress.h b/edk2/EdkModulePkg/Include/Protocol/EdkDecompress.h
new file mode 100644
index 0000000..ab9b840
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/EdkDecompress.h
@@ -0,0 +1,137 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  EdkDecompress.h

+    

+Abstract:

+  The Tiano Decompress Protocol Interface

+

+--*/

+

+#ifndef __EDK_DECOMPRESS_H__

+#define __EDK_DECOMPRESS_H__

+

+#define EFI_TIANO_DECOMPRESS_PROTOCOL_GUID  \

+  { 0xe84cf29c, 0x191f, 0x4eae, {0x96, 0xe1, 0xf4, 0x6a, 0xec, 0xea, 0xea, 0x0b } }

+

+typedef struct _EFI_TIANO_DECOMPRESS_PROTOCOL   EFI_TIANO_DECOMPRESS_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TIANO_DECOMPRESS_GET_INFO) (

+  IN EFI_TIANO_DECOMPRESS_PROTOCOL            *This,

+  IN   VOID                                   *Source,

+  IN   UINT32                                 SourceSize,

+  OUT  UINT32                                 *DestinationSize,

+  OUT  UINT32                                 *ScratchSize

+  );

+/*++

+

+Routine Description:

+

+  The GetInfo() function retrieves the size of the uncompressed buffer 

+  and the temporary scratch buffer required to decompress the buffer 

+  specified by Source and SourceSize.  If the size of the uncompressed

+  buffer or the size of the scratch buffer cannot be determined from 

+  the compressed data specified by Source and SourceData, then 

+  EFI_INVALID_PARAMETER is returned.  Otherwise, the size of the uncompressed

+  buffer is returned in DestinationSize, the size of the scratch buffer is 

+  returned in ScratchSize, and EFI_SUCCESS is returned.

+  

+  The GetInfo() function does not have scratch buffer available to perform 

+  a thorough checking of the validity of the source data. It just retrieves

+  the 'Original Size' field from the beginning bytes of the source data and

+  output it as DestinationSize.  And ScratchSize is specific to the decompression

+  implementation.

+

+Arguments:

+

+  This            - The protocol instance pointer

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size, in bytes, of source buffer.

+  DestinationSize - A pointer to the size, in bytes, of the uncompressed buffer

+                    that will be generated when the compressed buffer specified 

+                    by Source and SourceSize is decompressed.

+  ScratchSize     - A pointer to the size, in bytes, of the scratch buffer that 

+                    is required to decompress the compressed buffer specified by

+                    Source and SourceSize.

+

+Returns:

+  EFI_SUCCESS     - The size of the uncompressed data was returned in DestinationSize

+                    and the size of the scratch buffer was returned in ScratchSize.

+  EFI_INVALID_PARAMETER - The size of the uncompressed data or the size of the scratch

+                  buffer cannot be determined from the compressed data specified by 

+                  Source and SourceData.

+

+--*/

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TIANO_DECOMPRESS_DECOMPRESS) (

+  IN EFI_TIANO_DECOMPRESS_PROTOCOL              *This,

+  IN     VOID*                                  Source,

+  IN     UINT32                                 SourceSize,

+  IN OUT VOID*                                  Destination,

+  IN     UINT32                                 DestinationSize,

+  IN OUT VOID*                                  Scratch,

+  IN     UINT32                                 ScratchSize

+  );

+/*++

+

+Routine Description:

+

+  The Decompress() function extracts decompressed data to its original form.

+  

+  This protocol is designed so that the decompression algorithm can be 

+  implemented without using any memory services.  As a result, the 

+  Decompress() function is not allowed to call AllocatePool() or 

+  AllocatePages() in its implementation.  It is the caller's responsibility 

+  to allocate and free the Destination and Scratch buffers.

+  

+  If the compressed source data specified by Source and SourceSize is 

+  sucessfully decompressed into Destination, then EFI_SUCCESS is returned.  

+  If the compressed source data specified by Source and SourceSize is not in 

+  a valid compressed data format, then EFI_INVALID_PARAMETER is returned.

+

+Arguments:

+

+  This            - The protocol instance pointer

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source data.

+  Destination     - On output, the destination buffer that contains 

+                    the uncompressed data.

+  DestinationSize - The size of destination buffer. The size of destination

+                    buffer needed is obtained from GetInfo().

+  Scratch         - A temporary scratch buffer that is used to perform the 

+                    decompression.

+  ScratchSize     - The size of scratch buffer. The size of scratch buffer needed

+                    is obtained from GetInfo().

+

+Returns:

+

+  EFI_SUCCESS     - Decompression completed successfully, and the uncompressed 

+                    buffer is returned in Destination.

+  EFI_INVALID_PARAMETER 

+                  - The source buffer specified by Source and SourceSize is 

+                    corrupted (not in a valid compressed format).

+

+--*/

+

+struct _EFI_TIANO_DECOMPRESS_PROTOCOL {

+  EFI_TIANO_DECOMPRESS_GET_INFO    GetInfo;

+  EFI_TIANO_DECOMPRESS_DECOMPRESS  Decompress;

+};

+

+extern EFI_GUID gEfiTianoDecompressProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/ExtendedSalBootService.h b/edk2/EdkModulePkg/Include/Protocol/ExtendedSalBootService.h
new file mode 100644
index 0000000..28aceb3
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/ExtendedSalBootService.h
@@ -0,0 +1,113 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ExtendedSalBootService.h

+

+Abstract:

+

+--*/

+

+#ifndef _EXTENDED_SAL_PROTOCOL_H_

+#define _EXTENDED_SAL_PROTOCOL_H_

+

+#define EXTENDED_SAL_BOOT_SERVICE_PROTOCOL_GUID   \

+  {0xde0ee9a4,0x3c7a,0x44f2, {0xb7,0x8b,0xe3,0xcc,0xd6,0x9c,0x3a,0xf7}}

+

+#define EXTENDED_SAL_SIGNATURE  EFI_SIGNATURE_32('e', 's', 'a', 'l')

+

+#define SAL_MIN_STATE_SIZE    0x400 * 1

+#define PAL_SCARTCH_SIZE      0x400 * 3

+#define ALIGN_MINSTATE_SIZE   512

+#define MAX_SAL_RECORD_SIZE   8*1024

+

+#define SAL_RUNTIMESERVICE

+

+typedef UINT16    EFI_SAL_PROCESSOR_ID;

+

+typedef struct _EXTENDED_SAL_BOOT_SERVICE_PROTOCOL EXTENDED_SAL_BOOT_SERVICE_PROTOCOL;

+

+typedef

+SAL_RUNTIMESERVICE

+SAL_RETURN_REGS

+(EFIAPI *SAL_EXTENDED_SAL_PROC) (

+  IN  EFI_GUID                                    *ClassGuid,

+  IN   UINT64                                      FunctionId,

+  IN  UINT64                                      Arg2,

+  IN  UINT64                                      Arg3,

+  IN  UINT64                                      Arg4,

+  IN  UINT64                                      Arg5,

+  IN  UINT64                                      Arg6,

+  IN  UINT64                                      Arg7,

+  IN  UINT64                                      Arg8

+  );

+

+typedef

+SAL_RUNTIMESERVICE

+SAL_RETURN_REGS

+(EFIAPI *SAL_INTERNAL_EXTENDED_SAL_PROC) (

+  IN  UINT64                                      FunctionId,

+  IN  UINT64                                      Arg2,

+  IN  UINT64                                      Arg3,

+  IN  UINT64                                      Arg4,

+  IN  UINT64                                      Arg5,

+  IN  UINT64                                      Arg6,

+  IN  UINT64                                      Arg7,

+  IN  UINT64                                      Arg8,

+  IN  SAL_EXTENDED_SAL_PROC                       ExtendedSalProc,

+  IN   BOOLEAN                                     VirtualMode,

+  IN  VOID                                        *ModuleGlobal

+  ); 

+

+typedef

+EFI_STATUS

+(EFIAPI *EXTENDED_SAL_ADD_SST_INFO) (

+  IN EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *This,

+  IN  UINT16                                      SalAVersion,

+  IN   UINT16                                      SalBVersion,

+  IN  CHAR8                                        *OemId,

+  IN  CHAR8                                        *ProductId

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EXTENDED_SAL_ADD_SST_ENTRY) (

+  IN EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *This,

+  IN  UINT8                                        EntryType,

+  IN   UINT8                                        *TableEntry,

+  IN  UINTN                                        EntrySize

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EXTENDED_SAL_REGISTER_INTERNAL_PROC) (

+  IN EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *This,

+  IN  EFI_GUID                                    *ClassGuid,

+  IN   UINT64                                      FunctionId,

+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC              InternalSalProc,

+  IN  VOID                                        *PhysicalModuleGlobal

+  );

+

+//

+// Extended Sal Boot Service Protocol Interface

+//

+struct _EXTENDED_SAL_BOOT_SERVICE_PROTOCOL{

+  EXTENDED_SAL_ADD_SST_INFO                       AddSalSystemTableInfo;

+  EXTENDED_SAL_ADD_SST_ENTRY                      AddSalSystemTableEntry;

+  EXTENDED_SAL_REGISTER_INTERNAL_PROC             AddExtendedSalProc;   

+  SAL_EXTENDED_SAL_PROC                           ExtendedSalProc;

+  SAL_PROC                                        SalProc;

+};

+

+extern EFI_GUID   gEfiExtendedSalBootServiceProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/FaultTolerantWriteLite.h b/edk2/EdkModulePkg/Include/Protocol/FaultTolerantWriteLite.h
new file mode 100644
index 0000000..c3ec825
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/FaultTolerantWriteLite.h
@@ -0,0 +1,88 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FaultTolerantWriteLite.h

+

+Abstract:

+

+  This is a simple fault tolerant write driver, based on PlatformFd library.

+  And it only supports write BufferSize <= SpareAreaLength.

+

+--*/

+

+#ifndef _FW_FAULT_TOLERANT_WRITE_LITE_PROTOCOL_H_

+#define _FW_FAULT_TOLERANT_WRITE_LITE_PROTOCOL_H_

+

+#define EFI_FTW_LITE_PROTOCOL_GUID \

+{ 0x3f557189, 0x8dae, 0x45ae, {0xa0, 0xb3, 0x2b, 0x99, 0xca, 0x7a, 0xa7, 0xa0 } }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_FTW_LITE_PROTOCOL EFI_FTW_LITE_PROTOCOL;

+

+//

+// Protocol API definitions

+//

+

+typedef

+EFI_STATUS

+(EFIAPI * EFI_FTW_LITE_WRITE) (

+  IN EFI_FTW_LITE_PROTOCOL             *This,

+  IN EFI_HANDLE                        FvbHandle,

+  IN EFI_LBA                           Lba,

+  IN UINTN                             Offset,

+  IN UINTN                             *NumBytes,

+  IN VOID                              *Buffer

+  );

+/*++

+

+Routine Description:

+

+  Starts a target block update. This records information about the write 

+  in fault tolerant storage and will complete the write in a recoverable 

+  manner, ensuring at all times that either the original contents or 

+  the modified contents are available.

+

+Arguments:

+

+  This             - Calling context

+  FvBlockHandle    - The handle of FVB protocol that provides services for 

+                     reading, writing, and erasing the target block.

+  Lba              - The logical block address of the target block.  

+  Offset           - The offset within the target block to place the data.

+  Length           - The number of bytes to write to the target block.

+  Buffer           - The data to write.

+

+Returns:

+

+  EFI_SUCCESS          - The function completed successfully

+  EFI_ABORTED          - The function could not complete successfully.

+  EFI_BAD_BUFFER_SIZE  - The write would span a block boundary, 

+                         which is not a valid action.

+  EFI_ACCESS_DENIED    - No writes have been allocated.

+  EFI_NOT_READY        - The last write has not been completed.  

+                         Restart () must be called to complete it.

+

+--*/

+

+//

+// Protocol declaration

+//

+struct _EFI_FTW_LITE_PROTOCOL {

+  EFI_FTW_LITE_WRITE               Write;

+};

+

+extern EFI_GUID gEfiFaultTolerantWriteLiteProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/FvbExtension.h b/edk2/EdkModulePkg/Include/Protocol/FvbExtension.h
new file mode 100644
index 0000000..c2be78b
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/FvbExtension.h
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    FvbExtension.h

+

+Abstract:

+

+  FVB Extension protocol that extends the FVB Class in a component fashion.

+

+--*/

+

+#ifndef _FVB_EXTENSION_H_

+#define _FVB_EXTENSION_H_

+

+#define EFI_FVB_EXTENSION_PROTOCOL_GUID  \

+  {0x53a4c71b, 0xb581, 0x4170, {0x91, 0xb3, 0x8d, 0xb8, 0x7a, 0x4b, 0x5c, 0x46 } }

+

+typedef struct _EFI_FVB_EXTENSION_PROTOCOL EFI_FVB_EXTENSION_PROTOCOL;

+

+//

+//  FVB Extension Function Prototypes

+//

+typedef

+EFI_STATUS

+(EFIAPI * EFI_FV_ERASE_CUSTOM_BLOCK) (

+  IN EFI_FVB_EXTENSION_PROTOCOL   *This,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+);

+

+//

+// IPMI TRANSPORT PROTOCOL

+//

+struct _EFI_FVB_EXTENSION_PROTOCOL {

+  EFI_FV_ERASE_CUSTOM_BLOCK               EraseFvbCustomBlock;

+};

+

+extern EFI_GUID                           gEfiFvbExtensionProtocolGuid;

+

+#endif

+

diff --git a/edk2/EdkModulePkg/Include/Protocol/GenericMemoryTest.h b/edk2/EdkModulePkg/Include/Protocol/GenericMemoryTest.h
new file mode 100644
index 0000000..8f566d3
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/GenericMemoryTest.h
@@ -0,0 +1,156 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    GenericMemoryTest.h

+

+Abstract:

+

+    The EFI generic memory test protocol

+    For more information please look at EfiMemoryTest.doc

+

+--*/

+

+#ifndef __GENERIC_MEMORY_TEST_H__

+#define __GENERIC_MEMORY_TEST_H__

+

+#define EFI_GENERIC_MEMORY_TEST_PROTOCOL_GUID  \

+  { 0x309de7f1, 0x7f5e, 0x4ace, {0xb4, 0x9c, 0x53, 0x1b, 0xe5, 0xaa, 0x95, 0xef} }

+

+typedef struct _EFI_GENERIC_MEMORY_TEST_PROTOCOL  EFI_GENERIC_MEMORY_TEST_PROTOCOL;

+

+typedef enum {

+  IGNORE,

+  QUICK,

+  SPARSE,

+  EXTENSIVE,

+  MAXLEVEL

+} EXTENDMEM_COVERAGE_LEVEL;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MEMORY_TEST_INIT) (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This,

+  IN  EXTENDMEM_COVERAGE_LEVEL                 Level,

+  OUT BOOLEAN                                  *RequireSoftECCInit

+  )

+/*++

+

+  Routine Description:

+    Initialize the generic memory test.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    Level                 - The coverage level of the memory test.

+    RequireSoftECCInit    - Indicate if the memory need software ECC init.

+

+  Returns:

+    EFI_SUCCESS           - The generic memory test initialized correctly.

+    EFI_NO_MEDIA          - There is not any non-tested memory found, in this

+                            function if not any non-tesed memory found means 

+                            that the memory test driver have not detect any

+                            non-tested extended memory of current system.

+

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PERFORM_MEMORY_TEST) (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This,

+  OUT UINT64                                   *TestedMemorySize,

+  OUT UINT64                                   *TotalMemorySize,

+  OUT BOOLEAN                                  *ErrorOut,

+  IN BOOLEAN                                   IfTestAbort

+  )

+/*++

+

+  Routine Description:

+    Perform the memory test.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    TestedMemorySize      - Return the tested extended memory size.

+    TotalMemorySize       - Return the whole system physical memory size, this 

+                            value may be changed if in some case some error 

+                            DIMMs be disabled.

+    ErrorOut              - Any time the memory error occurs, this will be TRUE.

+    IfTestAbort           - Indicate if the user press "ESC" to skip the memory

+                            test.

+

+  Returns:

+    EFI_SUCCESS           - One block of memory test ok, the block size is hide

+                            internally.

+    EFI_NOT_FOUND         - Indicate all the non-tested memory blocks have 

+                            already go through.

+

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MEMORY_TEST_FINISHED) (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This

+  )

+/*++

+

+  Routine Description:

+    The memory test finished.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS           - Successful free all the generic memory test driver

+                            allocated resource and notify to platform memory

+                            test driver that memory test finished.

+

+--*/

+;

+  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MEMORY_TEST_COMPATIBLE_RANGE) (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This,

+  IN  EFI_PHYSICAL_ADDRESS                     StartAddress,

+  IN  UINT64                                   Length

+  )

+/*++

+  

+  Routine Description:

+    Provide capability to test compatible range which used by some sepcial

+    driver required using memory range before BDS perform memory test.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    StartAddress          - The start address of the memory range.

+    Length                - The memory range's length.

+    

+  Return:

+    EFI_SUCCESS           - The compatible memory range pass the memory test.

+    EFI_DEVICE_ERROR      - The compatible memory range test find memory error

+                            and also return return the error address.

+    

+--*/

+;

+

+struct _EFI_GENERIC_MEMORY_TEST_PROTOCOL {

+  EFI_MEMORY_TEST_INIT              MemoryTestInit;

+  EFI_PERFORM_MEMORY_TEST           PerformMemoryTest;

+  EFI_MEMORY_TEST_FINISHED          Finished;

+  EFI_MEMORY_TEST_COMPATIBLE_RANGE  CompatibleRangeTest;

+};

+

+extern EFI_GUID gEfiGenericMemTestProtocolGuid;

+

+#endif

+

diff --git a/edk2/EdkModulePkg/Include/Protocol/IsaAcpi.h b/edk2/EdkModulePkg/Include/Protocol/IsaAcpi.h
new file mode 100644
index 0000000..c3d92f6
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/IsaAcpi.h
@@ -0,0 +1,177 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    IsaAcpi.h

+    

+Abstract:

+

+    EFI ISA Acpi Protocol

+

+Revision History

+

+--*/

+

+#ifndef _ISA_ACPI_H_

+#define _ISA_ACPI_H_

+

+#define EFI_ISA_ACPI_PROTOCOL_GUID \

+		{ 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } }

+

+typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;

+

+//

+// Resource Attribute definition

+//

+#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE   0x01

+#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE    0x02

+#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE  0x04

+#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE   0x08

+

+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK                 0x03

+

+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY        0x00

+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A                    0x01

+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B                    0x02

+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F                    0x03

+#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE                   0x04

+#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD                   0x08

+#define EFI_ISA_ACPI_DMA_BUS_MASTER                      0x10

+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT             0x20

+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT  0x40

+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT            0x80

+

+#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK                   0x03

+

+#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT                  0x00

+#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT                 0x01

+#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT       0x02

+#define EFI_ISA_ACPI_MEMORY_WRITEABLE                    0x04

+#define EFI_ISA_ACPI_MEMORY_CACHEABLE                    0x08

+#define EFI_ISA_ACPI_MEMORY_SHADOWABLE                   0x10

+#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM                0x20

+

+#define EFI_ISA_ACPI_IO_DECODE_10_BITS                   0x01

+#define EFI_ISA_ACPI_IO_DECODE_16_BITS                   0x02

+

+//

+// Resource List definition: 

+// at first, the resource was defined as below

+// but in the future, it will be defined again that follow ACPI spec: ACPI resource type

+// so that, in this driver, we can interpret the ACPI table and get the ISA device information. 

+//

+ 

+typedef enum {

+  EfiIsaAcpiResourceEndOfList,

+  EfiIsaAcpiResourceIo,

+  EfiIsaAcpiResourceMemory,

+  EfiIsaAcpiResourceDma,

+  EfiIsaAcpiResourceInterrupt

+} EFI_ISA_ACPI_RESOURCE_TYPE;

+

+typedef struct {

+  EFI_ISA_ACPI_RESOURCE_TYPE  Type;

+  UINT32                      Attribute;

+  UINT32                      StartRange;

+  UINT32                      EndRange;

+} EFI_ISA_ACPI_RESOURCE;

+

+typedef struct {

+  UINT32                      HID;

+  UINT32                      UID;

+} EFI_ISA_ACPI_DEVICE_ID;

+

+typedef struct {

+  EFI_ISA_ACPI_DEVICE_ID      Device;

+  EFI_ISA_ACPI_RESOURCE       *ResourceItem;

+} EFI_ISA_ACPI_RESOURCE_LIST;

+

+//

+// Prototypes for the ISA ACPI Protocol

+//

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  OUT EFI_ISA_ACPI_DEVICE_ID         **Device

+  );

+  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  IN EFI_ISA_ACPI_DEVICE_ID          *Device,

+  IN BOOLEAN                         OnOff

+  );

+  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  IN EFI_ISA_ACPI_DEVICE_ID          *Device,

+  OUT EFI_ISA_ACPI_RESOURCE_LIST     **ResourceList

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  IN EFI_ISA_ACPI_DEVICE_ID          *Device,

+  OUT EFI_ISA_ACPI_RESOURCE_LIST     **ResourceList

+  );

+  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  IN EFI_ISA_ACPI_DEVICE_ID          *Device,

+  IN EFI_ISA_ACPI_RESOURCE_LIST      *ResourceList

+  );    

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  IN EFI_ISA_ACPI_DEVICE_ID          *Device,

+  IN BOOLEAN                         Enable

+  );    

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This,

+  IN EFI_ISA_ACPI_DEVICE_ID          *Device

+  );  

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT) (

+  IN EFI_ISA_ACPI_PROTOCOL           *This

+  );

+

+//

+// Interface structure for the ISA ACPI Protocol

+//

+struct _EFI_ISA_ACPI_PROTOCOL {

+  EFI_ISA_ACPI_DEVICE_ENUMERATE     DeviceEnumerate;

+  EFI_ISA_ACPI_SET_DEVICE_POWER     SetPower;

+  EFI_ISA_ACPI_GET_CUR_RESOURCE     GetCurResource;

+  EFI_ISA_ACPI_GET_POS_RESOURCE     GetPosResource;

+  EFI_ISA_ACPI_SET_RESOURCE         SetResource;

+  EFI_ISA_ACPI_ENABLE_DEVICE        EnableDevice;

+  EFI_ISA_ACPI_INIT_DEVICE          InitDevice;

+  EFI_ISA_ACPI_INTERFACE_INIT       InterfaceInit;

+};

+

+extern EFI_GUID gEfiIsaAcpiProtocolGuid;

+  

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/IsaIo.h b/edk2/EdkModulePkg/Include/Protocol/IsaIo.h
new file mode 100644
index 0000000..8419dd4
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/IsaIo.h
@@ -0,0 +1,174 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    IsaIo.h

+    

+Abstract:

+

+    EFI ISA I/O Protocol

+

+Revision History

+

+--*/

+

+#ifndef _EFI_ISA_IO_H

+#define _EFI_ISA_IO_H

+

+//

+// Global ID for the ISA I/O Protocol

+//

+

+#define EFI_ISA_IO_PROTOCOL_GUID \

+  { 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }

+

+typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;

+

+//

+// Prototypes for the ISA I/O Protocol

+//

+

+typedef enum {

+  EfiIsaIoWidthUint8,

+  EfiIsaIoWidthUint16,

+  EfiIsaIoWidthUint32,

+  EfiIsaIoWidthReserved,

+  EfiIsaIoWidthFifoUint8,

+  EfiIsaIoWidthFifoUint16,

+  EfiIsaIoWidthFifoUint32,

+  EfiIsaIoWidthFifoReserved,

+  EfiIsaIoWidthFillUint8,

+  EfiIsaIoWidthFillUint16,

+  EfiIsaIoWidthFillUint32,

+  EfiIsaIoWidthFillReserved,

+  EfiIsaIoWidthMaximum

+} EFI_ISA_IO_PROTOCOL_WIDTH;

+

+//

+// Attributes for common buffer allocations

+//

+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE  0x080    // Map a memory range so write are combined

+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED         0x800    // Map a memory range so all r/w accesses are cached

+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE        0x1000   // Disable a memory range 

+

+//

+// Channel attribute for DMA operations

+//

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE  0x001

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A           0x002

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B           0x004

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C           0x008

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8           0x010

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16          0x020

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE       0x040

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE       0x080

+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE   0x100

+

+typedef enum {

+  EfiIsaIoOperationBusMasterRead,

+  EfiIsaIoOperationBusMasterWrite,

+  EfiIsaIoOperationBusMasterCommonBuffer,

+  EfiIsaIoOperationSlaveRead,

+  EfiIsaIoOperationSlaveWrite,

+  EfiIsaIoOperationMaximum

+} EFI_ISA_IO_PROTOCOL_OPERATION;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM) (

+  IN EFI_ISA_IO_PROTOCOL  *This,

+  IN     EFI_ISA_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT32                       Offset,

+  IN     UINTN                        Count,

+  IN OUT VOID                         *Buffer

+  );

+

+typedef struct {

+  EFI_ISA_IO_PROTOCOL_IO_MEM  Read;

+  EFI_ISA_IO_PROTOCOL_IO_MEM  Write;

+} EFI_ISA_IO_PROTOCOL_ACCESS;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM) (

+  IN EFI_ISA_IO_PROTOCOL  *This,

+  IN     EFI_ISA_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT32                       DestOffset,

+  IN     UINT32                       SrcOffset,

+  IN     UINTN                        Count

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP) (

+  IN EFI_ISA_IO_PROTOCOL    *This,

+  IN     EFI_ISA_IO_PROTOCOL_OPERATION  Operation,

+  IN     UINT8                          ChannelNumber      OPTIONAL,

+  IN     UINT32                         ChannelAttributes,

+  IN     VOID                           *HostAddress,

+  IN OUT UINTN                          *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,

+  OUT    VOID                           **Mapping

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP) (

+  IN EFI_ISA_IO_PROTOCOL  *This,

+  IN  VOID                         *Mapping

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER) (

+  IN EFI_ISA_IO_PROTOCOL  *This,

+  IN  EFI_ALLOCATE_TYPE            Type,

+  IN  EFI_MEMORY_TYPE              MemoryType,

+  IN  UINTN                        Pages,

+  OUT VOID                         **HostAddress,

+  IN  UINT64                       Attributes

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER) (

+  IN EFI_ISA_IO_PROTOCOL  *This,

+  IN  UINTN                        Pages,

+  IN  VOID                         *HostAddress

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH) (

+  IN EFI_ISA_IO_PROTOCOL  *This

+  );

+

+//

+// Interface structure for the ISA I/O Protocol

+//

+struct _EFI_ISA_IO_PROTOCOL {

+  EFI_ISA_IO_PROTOCOL_ACCESS           Mem;

+  EFI_ISA_IO_PROTOCOL_ACCESS           Io;

+  EFI_ISA_IO_PROTOCOL_COPY_MEM         CopyMem;

+  EFI_ISA_IO_PROTOCOL_MAP              Map;

+  EFI_ISA_IO_PROTOCOL_UNMAP            Unmap;

+  EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER  AllocateBuffer;

+  EFI_ISA_IO_PROTOCOL_FREE_BUFFER      FreeBuffer;

+  EFI_ISA_IO_PROTOCOL_FLUSH            Flush;

+  EFI_ISA_ACPI_RESOURCE_LIST           *ResourceList;

+  UINT32                               RomSize;

+  VOID                                 *RomImage;

+};

+

+extern EFI_GUID gEfiIsaIoProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/LoadPe32Image.h b/edk2/EdkModulePkg/Include/Protocol/LoadPe32Image.h
new file mode 100644
index 0000000..d6f54aa
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/LoadPe32Image.h
@@ -0,0 +1,68 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  LoadPe32Image.h

+

+Abstract:

+  Load File protocol as defined in the EFI 1.0 specification.

+

+  Load file protocol exists to supports the addition of new boot devices, 

+  and to support booting from devices that do not map well to file system. 

+  Network boot is done via a LoadFile protocol.

+

+  EFI 1.0 can boot from any device that produces a LoadFile protocol.

+

+--*/

+

+#ifndef __LOAD_PE32_IMAGE_H__

+#define __LOAD_PE32_IMAGE_H__

+

+#define PE32_IMAGE_PROTOCOL_GUID  \

+  {0x5cb5c776,0x60d5,0x45ee,{0x88,0x3c,0x45,0x27,0x8,0xcd,0x74,0x3f }}

+

+#define EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE                                 0x00

+#define EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION                 0x01

+#define EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION  0x02

+

+typedef struct _EFI_PE32_IMAGE_PROTOCOL   EFI_PE32_IMAGE_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI *LOAD_PE_IMAGE) (

+  IN EFI_PE32_IMAGE_PROTOCOL           *This,

+  IN  EFI_HANDLE                       ParentImageHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN  VOID                             *SourceBuffer       OPTIONAL,

+  IN  UINTN                            SourceSize,

+  IN  EFI_PHYSICAL_ADDRESS             DstBuffer           OPTIONAL,

+  OUT UINTN                            *NumberOfPages      OPTIONAL,

+  OUT EFI_HANDLE                       *ImageHandle,

+  OUT EFI_PHYSICAL_ADDRESS             *EntryPoint         OPTIONAL,

+  IN  UINT32                           Attribute

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *UNLOAD_PE_IMAGE) (

+  IN EFI_PE32_IMAGE_PROTOCOL          *This,

+  IN EFI_HANDLE                       ImageHandle

+  );

+

+struct _EFI_PE32_IMAGE_PROTOCOL {

+  LOAD_PE_IMAGE     LoadPeImage;

+  UNLOAD_PE_IMAGE  UnLoadPeImage;

+};

+

+extern EFI_GUID gEfiLoadPeImageProtocolGuid;

+

+#endif

+

diff --git a/edk2/EdkModulePkg/Include/Protocol/OEMBadging.h b/edk2/EdkModulePkg/Include/Protocol/OEMBadging.h
new file mode 100644
index 0000000..6b4602e
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/OEMBadging.h
@@ -0,0 +1,79 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    EfiOEMBadging.h

+    

+Abstract:

+

+    EFI OEM Badging Protocol definition header file

+

+Revision History

+

+--*/

+

+#ifndef _EFI_OEM_BADGING_H_

+#define _EFI_OEM_BADGING_H_

+

+//

+// GUID for EFI OEM Badging Protocol

+//

+#define EFI_OEM_BADGING_PROTOCOL_GUID \

+  { 0x170e13c0, 0xbf1b, 0x4218, {0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87, 0xbc } }

+  

+

+typedef struct _EFI_OEM_BADGING_PROTOCOL EFI_OEM_BADGING_PROTOCOL;

+

+typedef enum {

+  EfiBadgingFormatBMP,

+  EfiBadgingFormatJPEG,

+  EfiBadgingFormatTIFF,

+  EfiBadgingFormatGIF,

+  EfiBadgingFormatUnknown

+} EFI_BADGING_FORMAT;

+

+typedef enum {

+  EfiBadgingDisplayAttributeLeftTop,

+  EfiBadgingDisplayAttributeCenterTop,

+  EfiBadgingDisplayAttributeRightTop,

+  EfiBadgingDisplayAttributeCenterRight,

+  EfiBadgingDisplayAttributeRightBottom,

+  EfiBadgingDisplayAttributeCenterBottom,

+  EfiBadgingDisplayAttributeLeftBottom,

+  EfiBadgingDisplayAttributeCenterLeft,

+  EfiBadgingDisplayAttributeCenter,

+  EfiBadgingDisplayAttributeCustomized

+} EFI_BADGING_DISPLAY_ATTRIBUTE;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BADGING_GET_IMAGE) (

+  IN     EFI_OEM_BADGING_PROTOCOL          *This,

+  IN OUT UINT32                            *Instance,

+     OUT EFI_BADGING_FORMAT                *Format,

+     OUT UINT8                             **ImageData,

+     OUT UINTN                             *ImageSize,

+     OUT EFI_BADGING_DISPLAY_ATTRIBUTE     *Attribute,

+     OUT UINTN                             *CoordinateX,   

+     OUT UINTN                             *CoordinateY   

+);

+

+

+struct _EFI_OEM_BADGING_PROTOCOL {

+  EFI_BADGING_GET_IMAGE       GetImage;

+};

+

+

+extern EFI_GUID gEfiOEMBadgingProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/PciHotPlugRequest.h b/edk2/EdkModulePkg/Include/Protocol/PciHotPlugRequest.h
new file mode 100644
index 0000000..6d194ae
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/PciHotPlugRequest.h
@@ -0,0 +1,54 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PciHotPlugRequest.h

+

+Abstract:

+

+  

+ 

+--*/

+

+#ifndef _PCI_HOTPLUG_REQUEST_H_

+#define _PCI_HOTPLUG_REQUEST_H_

+

+#define EFI_PCI_HOTPLUG_REQUEST_PROTOCOL_GUID \

+{0x19cb87ab,0x2cb9,{0x4665,0x83,0x60,0xdd,0xcf,0x60,0x54,0xf7,0x9d}}

+

+typedef enum {

+  EfiPciHotPlugRequestAdd,

+  EfiPciHotplugRequestRemove

+} EFI_PCI_HOTPLUG_OPERATION;

+

+typedef struct _EFI_PCI_HOTPLUG_REQUEST_PROTOCOL  EFI_PCI_HOTPLUG_REQUEST_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOTPLUG_REQUEST_NOTIFY) (

+ IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL *This,

+ IN EFI_PCI_HOTPLUG_OPERATION        Operation,

+ IN EFI_HANDLE                       Controller,

+ IN EFI_DEVICE_PATH_PROTOCOL         *RemainingDevicePath OPTIONAL,

+ IN OUT UINT8                        *NumberOfChildren,

+ IN OUT EFI_HANDLE                   *ChildHandleBuffer

+);

+

+

+

+struct _EFI_PCI_HOTPLUG_REQUEST_PROTOCOL {

+  EFI_PCI_HOTPLUG_REQUEST_NOTIFY     Notify;

+};

+

+extern EFI_GUID gEfiPciHotPlugRequestProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/Performance.h b/edk2/EdkModulePkg/Include/Protocol/Performance.h
new file mode 100644
index 0000000..c16ed8c
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/Performance.h
@@ -0,0 +1,166 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Performance.h

+

+Abstract:

+

+  

+--*/

+

+#ifndef __PERFORMANCE_H_

+#define __PERFORMANCE_H_

+

+#define PERFORMANCE_PROTOCOL_GUID \

+  { 0x76b6bdfa, 0x2acd, 0x4462, {0x9E, 0x3F, 0xcb, 0x58, 0xC9, 0x69, 0xd9, 0x37 } }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _PERFORMANCE_PROTOCOL PERFORMANCE_PROTOCOL;

+

+#define DXE_TOK                         "DXE"

+#define SHELL_TOK                       "SHELL"

+#define PEI_TOK                         "PEI"

+#define BDS_TOK                         "BDS"

+#define DRIVERBINDING_START_TOK         "DriverBinding:Start"

+#define DRIVERBINDING_SUPPORT_TOK       "DriverBinding:Support"

+#define START_IMAGE_TOK                 "StartImage"

+#define LOAD_IMAGE_TOK                  "LoadImage"

+

+//

+// DXE_PERFORMANCE_STRING_SIZE must be a multiple of 8.

+//

+#define DXE_PERFORMANCE_STRING_SIZE     32

+#define DXE_PERFORMANCE_STRING_LENGTH   (DXE_PERFORMANCE_STRING_SIZE - 1)

+

+//

+// The default guage entries number for DXE phase.

+//

+#define INIT_DXE_GAUGE_DATA_ENTRIES     800

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  Handle; 

+  CHAR8                 Token[DXE_PERFORMANCE_STRING_SIZE];

+  CHAR8                 Module[DXE_PERFORMANCE_STRING_SIZE];

+  UINT64                StartTimeStamp;

+  UINT64                EndTimeStamp;

+} GAUGE_DATA_ENTRY;

+

+//

+// The header must be aligned at 8 bytes

+// 

+typedef struct {

+  UINT32                NumberOfEntries;

+  UINT32                Reserved;

+} GAUGE_DATA_HEADER;

+

+/**

+  Adds a record at the end of the performance measurement log

+  that records the start time of a performance measurement.

+

+  Adds a record to the end of the performance measurement log

+  that contains the Handle, Token, and Module.

+  The end time of the new record must be set to zero.

+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.

+  If TimeStamp is zero, the start time in the record is filled in with the value

+  read from the current time stamp. 

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval EFI_SUCCESS             The data was read correctly from the device.

+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI * PERFORMANCE_START_GAUGE) (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  );

+

+/**

+  Searches the performance measurement log from the beginning of the log

+  for the first matching record that contains a zero end time and fills in a valid end time. 

+  

+  Searches the performance measurement log from the beginning of the log

+  for the first record that matches Handle, Token, and Module and has an end time value of zero.

+  If the record can not be found then return EFI_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then the end time in the record is filled in with the value specified by TimeStamp.

+  If the record is found and TimeStamp is zero, then the end time in the matching record

+  is filled in with the current time stamp value.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval EFI_SUCCESS             The end of  the measurement was recorded.

+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI * PERFORMANCE_END_GAUGE) (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  );

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Retrieves the performance log entry from the performance log specified by LogEntryKey.

+  If it stands for a valid entry, then EFI_SUCCESS is returned and

+  GaugeDataEntry stores the pointer to that entry.

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey

+                                  if the retrieval is successful.

+

+  @retval EFI_SUCCESS             The GuageDataEntry is successfuly found based on LogEntryKey.

+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).

+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).

+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL. 

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI * PERFORMANCE_GET_GAUGE) (

+  IN  UINTN               LogEntryKey,

+  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry

+  );

+

+struct _PERFORMANCE_PROTOCOL {

+  PERFORMANCE_START_GAUGE             StartGauge;

+  PERFORMANCE_END_GAUGE               EndGauge;

+  PERFORMANCE_GET_GAUGE               GetGauge;

+};

+

+extern EFI_GUID gPerformanceProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/Print.h b/edk2/EdkModulePkg/Include/Protocol/Print.h
new file mode 100644
index 0000000..eee7a0d
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/Print.h
@@ -0,0 +1,50 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Print.h

+

+Abstract:

+

+  This file defines the Print protocol

+

+--*/

+

+#ifndef _PPRINT_H_

+#define _PPRINT_H_

+

+#define EFI_PRINT_PROTOCOL_GUID  \

+   { 0xdf2d868e, 0x32fc, 0x4cf0, {0x8e, 0x6b, 0xff, 0xd9, 0x5d, 0x13, 0x43, 0xd0 } }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_PRINT_PROTOCOL  EFI_PRINT_PROTOCOL;

+

+

+typedef

+UINTN

+(EFIAPI *EFI_VSPRINT) (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  );

+

+struct _EFI_PRINT_PROTOCOL {

+  EFI_VSPRINT                                   VSPrint;

+};

+

+

+extern EFI_GUID gEfiPrintProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/PxeDhcp4.h b/edk2/EdkModulePkg/Include/Protocol/PxeDhcp4.h
new file mode 100644
index 0000000..cd4602c
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/PxeDhcp4.h
@@ -0,0 +1,350 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4.h

+

+Abstract:

+  EFI PXE DHCPv4 protocol definition

+

+--*/

+

+#ifndef _PXEDHCP4_H_

+#define _PXEDHCP4_H_

+

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+//

+// PXE DHCPv4 GUID definition

+//

+

+#define EFI_PXE_DHCP4_PROTOCOL_GUID \

+  { 0x03c4e624, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x29, 0x3f, 0xc1, 0x4d } }

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+//

+// Interface definition

+//

+

+typedef struct _EFI_PXE_DHCP4_PROTOCOL EFI_PXE_DHCP4_PROTOCOL;

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+//

+// Descriptions of the DHCP version 4 header and options can be found

+// in RFC-2131 and RFC-2132 at www.ietf.org

+//

+

+#pragma pack(1)

+typedef struct {

+

+  UINT8 op;

+#define BOOTP_REQUEST   1

+#define BOOTP_REPLY   2

+

+  UINT8 htype;

+

+  UINT8 hlen;

+

+  UINT8 hops;

+

+  UINT32 xid;

+

+  UINT16 secs;

+#define DHCP4_INITIAL_SECONDS 4

+

+  UINT16 flags;

+#define DHCP4_BROADCAST_FLAG  0x8000

+

+  UINT32 ciaddr;

+

+  UINT32 yiaddr;

+

+  UINT32 siaddr;

+

+  UINT32 giaddr;

+

+  UINT8 chaddr[16];

+

+  UINT8 sname[64];

+

+  UINT8 fname[128];

+

+//

+// This is the minimum option length as specified in RFC-2131.

+// The packet must be padded out this far with DHCP4_PAD.

+// DHCPv4 packets are usually 576 bytes in length.  This length

+// includes the IPv4 and UDPv4 headers but not the media header.

+// Note: Not all DHCP relay agents will forward DHCPv4 packets

+// if they are less than 384 bytes or exceed 576 bytes.  Even if

+// the underlying hardware can handle smaller and larger packets,

+// many older relay agents will not accept them.

+//

+  UINT32 magik;

+#define DHCP4_MAGIK_NUMBER  0x63825363

+

+  UINT8 options[308];

+

+} DHCP4_HEADER;

+#pragma pack()

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+//

+// DHCPv4 packet definition.  Room for 576 bytes including IP and

+// UDP header.

+//

+

+#define DHCP4_MAX_PACKET_SIZE     576

+#define DHCP4_UDP_HEADER_SIZE     8

+#define DHCP4_IP_HEADER_SIZE      20

+

+#pragma pack(1)

+typedef union _DHCP4_PACKET {

+  UINT32 _force_data_alignment;

+

+  UINT8 raw[1500];

+

+  DHCP4_HEADER dhcp4;

+} DHCP4_PACKET;

+#pragma pack()

+

+#define DHCP4_SERVER_PORT 67

+#define DHCP4_CLIENT_PORT 68

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+//

+// DHCPv4 and PXE option numbers.

+//

+

+#define DHCP4_PAD                             0

+#define DHCP4_END                             255

+#define DHCP4_SUBNET_MASK                     1

+#define DHCP4_TIME_OFFSET                     2

+#define DHCP4_ROUTER_LIST                     3

+#define DHCP4_TIME_SERVERS                    4

+#define DHCP4_NAME_SERVERS                    5

+#define DHCP4_DNS_SERVERS                     6

+#define DHCP4_LOG_SERVERS                     7

+#define DHCP4_COOKIE_SERVERS                  8

+#define DHCP4_LPR_SREVERS                     9

+#define DHCP4_IMPRESS_SERVERS                 10

+#define DHCP4_RESOURCE_LOCATION_SERVERS       11

+#define DHCP4_HOST_NAME                       12

+#define DHCP4_BOOT_FILE_SIZE                  13

+#define DHCP4_DUMP_FILE                       14

+#define DHCP4_DOMAIN_NAME                     15

+#define DHCP4_SWAP_SERVER                     16

+#define DHCP4_ROOT_PATH                       17

+#define DHCP4_EXTENSION_PATH                  18

+#define DHCP4_IP_FORWARDING                   19

+#define DHCP4_NON_LOCAL_SOURCE_ROUTE          20

+#define DHCP4_POLICY_FILTER                   21

+#define DHCP4_MAX_DATAGRAM_SIZE               22

+#define DHCP4_DEFAULT_TTL                     23

+#define DHCP4_MTU_AGING_TIMEOUT               24

+#define DHCP4_MTU_SIZES                       25

+#define DHCP4_MTU_TO_USE                      26

+#define DHCP4_ALL_SUBNETS_LOCAL               27

+#define DHCP4_BROADCAST_ADDRESS               28

+#define DHCP4_PERFORM_MASK_DISCOVERY          29

+#define DHCP4_RESPOND_TO_MASK_REQ             30

+#define DHCP4_PERFORM_ROUTER_DISCOVERY        31

+#define DHCP4_ROUTER_SOLICIT_ADDRESS          32

+#define DHCP4_STATIC_ROUTER_LIST              33

+#define DHCP4_USE_ARP_TRAILERS                34

+#define DHCP4_ARP_CACHE_TIMEOUT               35

+#define DHCP4_ETHERNET_ENCAPSULATION          36

+#define DHCP4_TCP_DEFAULT_TTL                 37

+#define DHCP4_TCP_KEEP_ALIVE_INT              38

+#define DHCP4_KEEP_ALIVE_GARBAGE              39

+#define DHCP4_NIS_DOMAIN_NAME                 40

+#define DHCP4_NIS_SERVERS                     41

+#define DHCP4_NTP_SERVERS                     42

+#define DHCP4_VENDOR_SPECIFIC                 43

+# define PXE_MTFTP_IP                         1

+# define PXE_MTFTP_CPORT                      2

+# define PXE_MTFTP_SPORT                      3

+# define PXE_MTFTP_TMOUT                      4

+# define PXE_MTFTP_DELAY                      5

+# define PXE_DISCOVERY_CONTROL                6

+#  define PXE_DISABLE_BROADCAST_DISCOVERY     0x01

+#  define PXE_DISABLE_MULTICAST_DISCOVERY     0x02

+#  define PXE_ACCEPT_ONLY_PXE_BOOT_SERVERS    0x04

+#  define PXE_DO_NOT_PROMPT                   0x08

+# define PXE_DISCOVERY_MCAST_ADDR             7

+# define PXE_BOOT_SERVERS                     8

+# define PXE_BOOT_MENU                        9

+# define PXE_BOOT_PROMPT                      10

+# define PXE_MCAST_ADDRS_ALLOC                11

+# define PXE_CREDENTIAL_TYPES                 12

+# define PXE_BOOT_ITEM                        71

+#define DHCP4_NBNS_SERVERS                    44

+#define DHCP4_NBDD_SERVERS                    45

+#define DHCP4_NETBIOS_NODE_TYPE               46

+#define DHCP4_NETBIOS_SCOPE                   47

+#define DHCP4_XWINDOW_SYSTEM_FONT_SERVERS     48

+#define DHCP4_XWINDOW_SYSTEM_DISPLAY_MANAGERS 49

+#define DHCP4_REQUESTED_IP_ADDRESS            50

+#define DHCP4_LEASE_TIME                      51

+#define DHCP4_OPTION_OVERLOAD                 52

+# define DHCP4_OVERLOAD_FNAME                 1

+# define DHCP4_OVERLOAD_SNAME                 2

+# define DHCP4_OVERLOAD_FNAME_AND_SNAME       3

+#define DHCP4_MESSAGE_TYPE                    53

+# define DHCP4_MESSAGE_TYPE_DISCOVER          1

+# define DHCP4_MESSAGE_TYPE_OFFER             2

+# define DHCP4_MESSAGE_TYPE_REQUEST           3

+# define DHCP4_MESSAGE_TYPE_DECLINE           4

+# define DHCP4_MESSAGE_TYPE_ACK               5

+# define DHCP4_MESSAGE_TYPE_NAK               6

+# define DHCP4_MESSAGE_TYPE_RELEASE           7

+# define DHCP4_MESSAGE_TYPE_INFORM            8

+#define DHCP4_SERVER_IDENTIFIER               54

+#define DHCP4_PARAMETER_REQUEST_LIST          55

+#define DHCP4_ERROR_MESSAGE                   56

+#define DHCP4_MAX_MESSAGE_SIZE                57

+# define DHCP4_DEFAULT_MAX_MESSAGE_SIZE       576

+#define DHCP4_RENEWAL_TIME                    58

+#define DHCP4_REBINDING_TIME                  59

+#define DHCP4_CLASS_IDENTIFIER                60

+#define DHCP4_CLIENT_IDENTIFIER               61

+#define DHCP4_NISPLUS_DOMAIN_NAME             64

+#define DHCP4_NISPLUS_SERVERS                 65

+#define DHCP4_TFTP_SERVER_NAME                66

+#define DHCP4_BOOTFILE                        67

+#define DHCP4_MOBILE_IP_HOME_AGENTS           68

+#define DHCP4_SMPT_SERVERS                    69

+#define DHCP4_POP3_SERVERS                    70

+#define DHCP4_NNTP_SERVERS                    71

+#define DHCP4_WWW_SERVERS                     72

+#define DHCP4_FINGER_SERVERS                  73

+#define DHCP4_IRC_SERVERS                     74

+#define DHCP4_STREET_TALK_SERVERS             75

+#define DHCP4_STREET_TALK_DIR_ASSIST_SERVERS  76

+#define DHCP4_NDS_SERVERS                     85

+#define DHCP4_NDS_TREE_NAME                   86

+#define DHCP4_NDS_CONTEXT                     87

+#define DHCP4_SYSTEM_ARCHITECTURE             93

+#define DHCP4_NETWORK_ARCHITECTURE            94

+#define DHCP4_PLATFORM_ID                     97

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+//

+// DHCP4 option format.

+//

+

+#pragma pack(1)

+typedef struct {

+  UINT8 op;

+  UINT8 len;

+  UINT8 data[1];

+} DHCP4_OP;

+#pragma pack()

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+typedef struct {

+  DHCP4_PACKET Discover;

+  DHCP4_PACKET Offer;

+  DHCP4_PACKET Request;

+  DHCP4_PACKET AckNak;

+  BOOLEAN SetupCompleted;

+  BOOLEAN InitCompleted;

+  BOOLEAN SelectCompleted;

+  BOOLEAN IsBootp;

+  BOOLEAN IsAck;

+} EFI_PXE_DHCP4_DATA;

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_RUN) (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN OPTIONAL UINTN         OpLen,

+  IN OPTIONAL VOID          *OpList

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_SETUP) (

+  IN EFI_PXE_DHCP4_PROTOCOL          *This,

+  IN OPTIONAL EFI_PXE_DHCP4_DATA     * NewData

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_INIT) (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  SecondsTimeout,

+  OUT UINTN                 *Offers,

+  OUT DHCP4_PACKET          **OfferList

+  );

+

+#define DHCP4_MIN_SECONDS   1

+#define DHCP4_MAX_SECONDS   60

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_SELECT) (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  SecondsTimeout,

+  IN DHCP4_PACKET           * offer

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_RENEW) (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  UINTN                     seconds_timeout

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_REBIND) (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  UINTN                     seconds_timeout

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_DHCP4_RELEASE) (

+  IN EFI_PXE_DHCP4_PROTOCOL * This

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+#define EFI_PXE_DHCP4_PROTOCOL_REVISION    0x00010000

+

+struct _EFI_PXE_DHCP4_PROTOCOL {

+  UINT64 Revision;

+  EFI_PXE_DHCP4_RUN Run;

+  EFI_PXE_DHCP4_SETUP Setup;

+  EFI_PXE_DHCP4_INIT Init;

+  EFI_PXE_DHCP4_SELECT Select;

+  EFI_PXE_DHCP4_RENEW Renew;

+  EFI_PXE_DHCP4_REBIND Rebind;

+  EFI_PXE_DHCP4_RELEASE Release;

+  EFI_PXE_DHCP4_DATA *Data;

+};

+

+//

+//

+//

+

+extern EFI_GUID gEfiPxeDhcp4ProtocolGuid;

+

+#endif /* _PXEDHCP4_H_ */

+/* EOF - PxeDhcp4.h */

diff --git a/edk2/EdkModulePkg/Include/Protocol/PxeDhcp4CallBack.h b/edk2/EdkModulePkg/Include/Protocol/PxeDhcp4CallBack.h
new file mode 100644
index 0000000..aa2b89a
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/PxeDhcp4CallBack.h
@@ -0,0 +1,85 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4Callback.h

+

+Abstract:

+  EFI PXE DHCP4 Callback protocol definition.

+

+--*/

+

+#ifndef _PXE_DHCP4CALLBACK_H

+#define _PXE_DHCP4CALLBACK_H

+

+#include <Protocol/PxeDhcp4.h>

+//

+// GUID definition

+//

+

+#define EFI_PXE_DHCP4_CALLBACK_PROTOCOL_GUID \

+{ 0xc1544c01, 0x92a4, 0x4198, {0x8a, 0x84, 0x77, 0x85, 0x83, 0xc2, 0x36, 0x21 } }

+

+

+//

+// Revision number

+//

+

+#define EFI_PXE_DHCP4_CALLBACK_INTERFACE_REVISION   0x00010000

+

+//

+// Interface definition

+//

+

+typedef struct _EFI_PXE_DHCP4_CALLBACK_PROTOCOL EFI_PXE_DHCP4_CALLBACK_PROTOCOL;

+

+typedef enum {

+  EFI_PXE_DHCP4_FUNCTION_FIRST,

+  EFI_PXE_DHCP4_FUNCTION_INIT,

+  EFI_PXE_DHCP4_FUNCTION_SELECT,

+  EFI_PXE_DHCP4_FUNCTION_RENEW,

+  EFI_PXE_DHCP4_FUNCTION_REBIND,

+  EFI_PXE_DHCP4_FUNCTION_LAST

+} EFI_PXE_DHCP4_FUNCTION;

+

+typedef enum {

+  EFI_PXE_DHCP4_CALLBACK_STATUS_FIRST,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_ABORT,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_ABORT,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_ABORT,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_CONTINUE,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE,

+  EFI_PXE_DHCP4_CALLBACK_STATUS_LAST

+} EFI_PXE_DHCP4_CALLBACK_STATUS;

+

+typedef

+EFI_PXE_DHCP4_CALLBACK_STATUS

+(EFIAPI *EFI_PXE_DHCP4_CALLBACK) (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN EFI_PXE_DHCP4_FUNCTION Function,

+  IN UINT32                 PacketLen,

+  IN DHCP4_PACKET           *Packet OPTIONAL

+  );

+

+struct _EFI_PXE_DHCP4_CALLBACK_PROTOCOL {

+  UINT64                      Revision;

+  EFI_PXE_DHCP4_CALLBACK      Callback;

+};

+

+//

+// GUID declaration

+//

+

+extern EFI_GUID gEfiPxeDhcp4CallbackProtocolGuid;

+

+#endif /* _PXE_DHCP4CALLBACK_H */

+/* EOF - PxeDhcp4Callback.h */

diff --git a/edk2/EdkModulePkg/Include/Protocol/ScsiIo.h b/edk2/EdkModulePkg/Include/Protocol/ScsiIo.h
new file mode 100644
index 0000000..1b0bbbf
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/ScsiIo.h
@@ -0,0 +1,241 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ScsiIo.h

+

+Abstract:

+

+  SCSI I/O protocol.

+

+--*/

+

+#ifndef __SCSI_IO_H__

+#define __SCSI_IO_H__

+

+#define EFI_SCSI_IO_PROTOCOL_GUID \

+  { 0x403cd195, 0xf233, 0x48ec, {0x84, 0x55, 0xb2, 0xe5, 0x2f, 0x1d, 0x9e, 0x2  } }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_SCSI_IO_PROTOCOL  EFI_SCSI_IO_PROTOCOL;

+

+//

+// SCSI Host Adapter Status definition

+//

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK                     0x00

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND        0x09    // timeout when processing the command

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT                0x0b    // timeout when waiting for the command processing

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT         0x0d    // a message reject was received when processing command

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET              0x0e    // a bus reset was detected

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR           0x0f

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED   0x10    // the adapter failed in issuing request sense command

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT      0x11    // selection timeout

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN  0x12    // data overrun or data underrun

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE               0x13    // Unexepected bus free

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR            0x14    // Target bus phase sequence failure

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OTHER                  0x7f

+

+

+//

+// SCSI Target Status definition

+//

+#define EFI_SCSI_IO_STATUS_TARGET_GOOD                         0x00

+#define EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION              0x02    // check condition

+#define EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET                0x04    // condition met

+#define EFI_SCSI_IO_STATUS_TARGET_BUSY                         0x08    // busy

+#define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE                 0x10    // intermediate

+#define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET   0x14    // intermediate-condition met

+#define EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT         0x18    // reservation conflict

+#define EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED           0x22    // command terminated

+#define EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL                   0x28    // queue full

+

+typedef struct {

+  UINT64      Timeout;

+  VOID        *DataBuffer;

+  VOID        *SenseData;

+  VOID        *Cdb;

+  UINT32      TransferLength;

+  UINT8       CdbLength;

+  UINT8       DataDirection;

+  UINT8       HostAdapterStatus;

+  UINT8       TargetStatus;

+  UINT8       SenseDataLength;

+}EFI_SCSI_IO_SCSI_REQUEST_PACKET;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE) (

+  IN EFI_SCSI_IO_PROTOCOL     *This,

+  OUT UINT8                           *DeviceType

+  )

+/*++

+

+  Routine Description:

+    Retrieves the device type information of the SCSI Controller.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    DeviceType            - A pointer to the device type information

+                            retrieved from the SCSI Controller. 

+

+  Returns:

+    EFI_SUCCESS            - Retrieves the device type information successfully.

+    EFI_INVALID_PARAMETER  - The DeviceType is NULL.

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION) (

+  IN EFI_SCSI_IO_PROTOCOL   *This,

+  OUT UINT32                        *Target,

+  OUT UINT64                        *Lun

+  )

+/*++

+  Routine Description:

+    Retrieves the device location in the SCSI channel.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    Target                - A pointer to the Target ID of a SCSI device 

+                            on the SCSI channel. 

+    Lun                    - A pointer to the LUN of the SCSI device on 

+                            the SCSI channel.

+

+  Returns:

+    EFI_SUCCESS            - Retrieves the device location successfully.

+    EFI_INVALID_PARAMETER  - The Target or Lun is NULL.

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_BUS) (

+  IN EFI_SCSI_IO_PROTOCOL     *This

+  )

+/*++

+

+  Routine Description:

+    Resets the SCSI Bus that the SCSI Controller is attached to.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS            - The SCSI bus is reset successfully.

+    EFI_DEVICE_ERROR      - Errors encountered when resetting the SCSI bus.

+    EFI_UNSUPPORTED        - The bus reset operation is not supported by the

+                            SCSI Host Controller.

+    EFI_TIMEOUT            - A timeout occurred while attempting to reset 

+                            the SCSI bus.

+--*/

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_DEVICE) (

+  IN EFI_SCSI_IO_PROTOCOL     *This

+  )

+/*++

+

+  Routine Description:

+    Resets the SCSI Controller that the device handle specifies.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    

+

+  Returns:

+    EFI_SUCCESS            - Reset the SCSI controller successfully.

+    EFI_DEVICE_ERROR      - Errors are encountered when resetting the

+                            SCSI Controller.

+    EFI_UNSUPPORTED        - The SCSI bus does not support a device 

+                            reset operation.

+    EFI_TIMEOUT            - A timeout occurred while attempting to 

+                            reset the SCSI Controller.

+--*/

+;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_CMD) (

+  IN EFI_SCSI_IO_PROTOCOL           *This,

+  IN OUT  EFI_SCSI_IO_SCSI_REQUEST_PACKET   *Packet,

+  IN EFI_EVENT                              Event  OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Sends a SCSI Request Packet to the SCSI Controller for execution.

+    

+  Arguments:

+    This                  - Protocol instance pointer.

+    Packet                - The SCSI request packet to send to the SCSI 

+                            Controller specified by the device handle.

+    Event                  - If the SCSI bus where the SCSI device is attached

+                            does not support non-blocking I/O, then Event is 

+                            ignored, and blocking I/O is performed.  

+                            If Event is NULL, then blocking I/O is performed.

+                            If Event is not NULL and non-blocking I/O is 

+                            supported, then non-blocking I/O is performed,

+                            and Event will be signaled when the SCSI Request

+                            Packet completes.

+  Returns:

+    EFI_SUCCESS            - The SCSI Request Packet was sent by the host 

+                            successfully, and TransferLength bytes were 

+                            transferred to/from DataBuffer.See 

+                            HostAdapterStatus, TargetStatus, 

+                            SenseDataLength, and SenseData in that order

+                            for additional status information.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength. See HostAdapterStatus, 

+                            TargetStatus, SenseDataLength, and SenseData in 

+                            that order for additional status information.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.The caller may retry again later.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet. See HostAdapterStatus, 

+                            TargetStatus, SenseDataLength, and SenseData in 

+                            that order for additional status information.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+                            The SCSI Request Packet was not sent, so no 

+                            additional status information is available.

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller). The SCSI Request Packet was not

+                            sent, so no additional status information is 

+                            available.

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute. See HostAdapterStatus,

+                            TargetStatus, SenseDataLength, and SenseData in 

+                            that order for additional status information.

+--*/

+;

+

+struct _EFI_SCSI_IO_PROTOCOL {

+    EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE      GetDeviceType;

+    EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION  GetDeviceLocation;

+    EFI_SCSI_IO_PROTOCOL_RESET_BUS            ResetBus;

+    EFI_SCSI_IO_PROTOCOL_RESET_DEVICE         ResetDevice;

+    EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_CMD        ExecuteSCSICommand;    

+};

+

+extern EFI_GUID gEfiScsiIoProtocolGuid;

+

+#endif

+

diff --git a/edk2/EdkModulePkg/Include/Protocol/SecurityPolicy.h b/edk2/EdkModulePkg/Include/Protocol/SecurityPolicy.h
new file mode 100644
index 0000000..f587b44
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/SecurityPolicy.h
@@ -0,0 +1,33 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SecurityPolicy.h

+

+Abstract:

+

+  Security Policy protocol as defined in the DXE CIS

+

+--*/

+

+#ifndef _SECURITY_POLICY_H_

+#define _SECURITY_POLICY_H_

+

+//

+// Security policy protocol GUID definition

+//

+#define EFI_SECURITY_POLICY_PROTOCOL_GUID  \

+  {0x78E4D245, 0xCD4D, 0x4a05, {0xA2, 0xBA, 0x47, 0x43, 0xE8, 0x6C, 0xFC, 0xAB} }

+

+extern EFI_GUID gEfiSecurityPolicyProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/UgaIo.h b/edk2/EdkModulePkg/Include/Protocol/UgaIo.h
new file mode 100644
index 0000000..91ff8df
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/UgaIo.h
@@ -0,0 +1,236 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  UgaIo.h

+

+Abstract:

+

+  UGA IO protocol from the EFI 1.1 specification.

+

+  Abstraction of a very simple graphics device.

+

+--*/

+

+#ifndef __UGA_IO_H__

+#define __UGA_IO_H__

+

+#define EFI_UGA_IO_PROTOCOL_GUID \

+  { \

+    0x61a4d49e, 0x6f68, 0x4f1b, { 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 } \

+  }

+

+typedef struct _EFI_UGA_IO_PROTOCOL EFI_UGA_IO_PROTOCOL;

+

+typedef UINT32                      UGA_STATUS;

+

+typedef enum {

+  UgaDtParentBus          = 1,

+  UgaDtGraphicsController,

+  UgaDtOutputController,

+  UgaDtOutputPort,

+  UgaDtOther

+}

+UGA_DEVICE_TYPE, *PUGA_DEVICE_TYPE;

+

+typedef UINT32 UGA_DEVICE_ID, *PUGA_DEVICE_ID;

+

+typedef struct {

+  UGA_DEVICE_TYPE deviceType;

+  UGA_DEVICE_ID   deviceId;

+  UINT32          ui32DeviceContextSize;

+  UINT32          ui32SharedContextSize;

+}

+UGA_DEVICE_DATA, *PUGA_DEVICE_DATA;

+

+typedef struct _UGA_DEVICE {

+  VOID                *pvDeviceContext;

+  VOID                *pvSharedContext;

+  VOID                *pvRunTimeContext;

+  struct _UGA_DEVICE  *pParentDevice;

+  VOID                *pvBusIoServices;

+  VOID                *pvStdIoServices;

+  UGA_DEVICE_DATA     deviceData;

+}

+UGA_DEVICE, *PUGA_DEVICE;

+

+#ifndef UGA_IO_REQUEST_CODE

+//

+// Prevent conflicts with UGA typedefs.

+//

+typedef enum {

+  UgaIoGetVersion             = 1,

+  UgaIoGetChildDevice,

+  UgaIoStartDevice,

+  UgaIoStopDevice,

+  UgaIoFlushDevice,

+  UgaIoResetDevice,

+  UgaIoGetDeviceState,

+  UgaIoSetDeviceState,

+  UgaIoSetPowerState,

+  UgaIoGetMemoryConfiguration,

+  UgaIoSetVideoMode,

+  UgaIoCopyRectangle,

+  UgaIoGetEdidSegment,

+  UgaIoDeviceChannelOpen,

+  UgaIoDeviceChannelClose,

+  UgaIoDeviceChannelRead,

+  UgaIoDeviceChannelWrite,

+  UgaIoGetPersistentDataSize,

+  UgaIoGetPersistentData,

+  UgaIoSetPersistentData,

+  UgaIoGetDevicePropertySize,

+  UgaIoGetDeviceProperty,

+  UgaIoBtPrivateInterface

+}

+UGA_IO_REQUEST_CODE, *PUGA_IO_REQUEST_CODE;

+

+#endif

+

+typedef struct {

+  IN UGA_IO_REQUEST_CODE  ioRequestCode;

+  IN VOID                 *pvInBuffer;

+  IN UINT64               ui64InBufferSize;

+  OUT VOID                *pvOutBuffer;

+  IN UINT64               ui64OutBufferSize;

+  OUT UINT64              ui64BytesReturned;

+}

+UGA_IO_REQUEST, *PUGA_IO_REQUEST;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UGA_IO_PROTOCOL_CREATE_DEVICE) (

+  IN  EFI_UGA_IO_PROTOCOL  * This,

+  IN  UGA_DEVICE           * ParentDevice,

+  IN  UGA_DEVICE_DATA      * DeviceData,

+  IN  VOID                 *RunTimeContext,

+  OUT UGA_DEVICE           **Device

+  );

+

+/*++

+

+  Routine Description:

+

+    Dynamically allocate storage for a child UGA_DEVICE .

+

+  Arguments:

+

+    This           - The EFI_UGA_IO_PROTOCOL instance. Type EFI_UGA_IO_PROTOCOL is 

+                     defined in Section 10.7.

+

+    ParentDevice   - ParentDevice specifies a pointer to the parent device of Device.

+

+    DeviceData     - A pointer to UGA_DEVICE_DATA returned from a call to DispatchService()

+                     with a UGA_DEVICE of Parent and an IoRequest of type UgaIoGetChildDevice.

+

+    RuntimeContext - Context to associate with Device.

+

+    Device         - The Device returns a dynamically allocated child UGA_DEVICE object

+                     for ParentDevice. The caller is responsible for deleting Device.

+      

+  Returns:

+

+    EFI_SUCCESS           - Device was returned.

+

+    EFI_INVALID_PARAMETER - One of the arguments was not valid.

+

+    EFI_DEVICE_ERROR      - The device had an error and could not complete the request.

+

+--*/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UGA_IO_PROTOCOL_DELETE_DEVICE) (

+  IN EFI_UGA_IO_PROTOCOL  * This,

+  IN UGA_DEVICE           * Device

+  );

+

+/*++

+

+  Routine Description:

+

+    Delete a dynamically allocated child UGA_DEVICE object that was allocated via

+    CreateDevice() .

+

+  Arguments:

+

+    This   - The EFI_UGA_IO_PROTOCOL instance. Type EFI_UGA_IO_PROTOCOL is defined 

+             in Section 10.7.

+

+    Device - The Device points to a UGA_DEVICE object that was dynamically

+             allocated via a CreateDevice() call.

+

+  Returns:

+

+    EFI_SUCCESS           - Device was deleted.

+

+    EFI_INVALID_PARAMETER - The Device was not allocated via CreateDevice()

+

+--*/

+typedef UGA_STATUS (EFIAPI *PUGA_FW_SERVICE_DISPATCH) (IN PUGA_DEVICE pDevice, IN OUT PUGA_IO_REQUEST pIoRequest);

+

+/*++

+

+  Routine Description:

+

+    This is the main UGA service dispatch routine for all UGA_IO_REQUEST s.

+

+  Arguments:

+

+    pDevice    - pDevice specifies a pointer to a device object associated with a 

+                 device enumerated by a pIoRequest->ioRequestCode of type 

+                 UgaIoGetChildDevice. The root device for the EFI_UGA_IO_PROTOCOL 

+                 is represented by pDevice being set to NULL.

+

+    pIoRequest - pIoRequest points to a caller allocated buffer that contains data

+                 defined by pIoRequest->ioRequestCode. See Related Definitions for

+                 a definition of UGA_IO_REQUEST_CODE s and their associated data 

+                 structures.

+

+  Returns:

+

+  Varies depending on pIoRequest.

+

+--*/

+struct _EFI_UGA_IO_PROTOCOL {

+  EFI_UGA_IO_PROTOCOL_CREATE_DEVICE CreateDevice;

+  EFI_UGA_IO_PROTOCOL_DELETE_DEVICE DeleteDevice;

+  PUGA_FW_SERVICE_DISPATCH          DispatchService;

+};

+

+extern EFI_GUID gEfiUgaIoProtocolGuid;

+

+//

+// Data structure that is stored in the EFI Configuration Table with the

+// EFI_UGA_IO_PROTOCOL_GUID.  The option ROMs listed in this table may have

+// EBC UGA drivers.

+//

+typedef struct {

+  UINT32  Version;

+  UINT32  HeaderSize;

+  UINT32  SizeOfEntries;

+  UINT32  NumberOfEntries;

+} EFI_DRIVER_OS_HANDOFF_HEADER;

+

+typedef enum {

+  EfiUgaDriverFromPciRom,

+  EfiUgaDriverFromSystem,

+  EfiDriverHandoffMax

+} EFI_DRIVER_HANOFF_ENUM;

+

+typedef struct {

+  EFI_DRIVER_HANOFF_ENUM    Type;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  VOID                      *PciRomImage;

+  UINT64                    PciRomSize;

+} EFI_DRIVER_OS_HANDOFF;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/UgaSplash.h b/edk2/EdkModulePkg/Include/Protocol/UgaSplash.h
new file mode 100644
index 0000000..51dcf52
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/UgaSplash.h
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    UgaSplash.h

+

+Abstract:

+

+  UGA Splash screen protocol.

+

+  Abstraction of a very simple graphics device.

+

+--*/

+

+#ifndef __UGA_SPLASH_H__

+#define __UGA_SPLASH_H__

+

+

+#define EFI_UGA_SPLASH_PROTOCOL_GUID \

+  { 0xa45b3a0d, 0x2e55, 0x4c03, {0xad, 0x9c, 0x27, 0xd4, 0x82, 0xb, 0x50, 0x7e } }

+

+typedef struct _EFI_UGA_SPLASH_PROTOCOL   EFI_UGA_SPLASH_PROTOCOL;

+

+

+struct _EFI_UGA_SPLASH_PROTOCOL {

+  UINT32          PixelWidth;

+  UINT32          PixelHeight;

+  EFI_UGA_PIXEL   *Image;

+};

+

+extern EFI_GUID gEfiUgaSplashProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Include/Protocol/usbatapi.h b/edk2/EdkModulePkg/Include/Protocol/usbatapi.h
new file mode 100644
index 0000000..8801a7a
--- /dev/null
+++ b/edk2/EdkModulePkg/Include/Protocol/usbatapi.h
@@ -0,0 +1,83 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    UsbAtapi.h

+    

+Abstract:

+

+    EFI Atapi Protocol definition.

+

+Revision History

+

+--*/

+

+#ifndef _EFI_USB_ATAPI_H

+#define _EFI_USB_ATAPI_H

+

+//

+// Transfer protocol types

+//

+#define BOT    0x50

+#define CBI0  0x00

+#define CBI1  0x01

+

+//

+// SubClass Code (defines command set)

+//

+#define EFI_USB_SUBCLASS_RBC            0x01

+#define EFI_USB_SUBCLASS_ATAPI          0x02

+#define EFI_USB_SUBCLASS_QIC_157        0x03

+#define EFI_USB_SUBCLASS_UFI            0x04

+#define EFI_USB_SUBCLASS_SFF_8070i      0x05

+#define EFI_USB_SUBCLASS_SCSI           0x06

+#define EFI_USB_SUBCLASS_RESERVED_LOW   0x07

+#define EFI_USB_SUBCLASS_RESERVED_HIGH  0xff

+//

+// Global GUID for transfer protocol interface

+//

+#define EFI_USB_ATAPI_PROTOCOL_GUID \

+    { 0x2B2F68DA, 0x0CD2, 0x44cf, {0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } }

+

+typedef struct _EFI_USB_ATAPI_PROTOCOL EFI_USB_ATAPI_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_ATAPI_PACKET_CMD) (

+  IN EFI_USB_ATAPI_PROTOCOL  *This,

+  IN  VOID                            *Command,

+  IN  UINT8                            CommandSize,

+  IN  VOID                            *DataBuffer,

+  IN  UINT32                          BufferLength,

+  IN  EFI_USB_DATA_DIRECTION          Direction,

+  IN  UINT16                          TimeOutInMilliSeconds

+);    

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_MASS_STORAGE_RESET) (

+  IN EFI_USB_ATAPI_PROTOCOL  *This,

+  IN  BOOLEAN                         ExtendedVerification

+);

+

+//

+//  Protocol Interface Structure

+//

+struct _EFI_USB_ATAPI_PROTOCOL {

+  EFI_USB_ATAPI_PACKET_CMD        UsbAtapiPacketCmd;

+  EFI_USB_MASS_STORAGE_RESET      UsbAtapiReset;

+  UINT32                          CommandProtocol;

+};

+

+extern EFI_GUID gEfiUsbAtapiProtocolGuid;

+

+#endif

diff --git a/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c
new file mode 100644
index 0000000..b165f47
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c
@@ -0,0 +1,80 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BaseCustomDecompressLibNull.c

+

+Abstract:

+

+  NULL Custom Decompress Library 

+

+--*/

+

+RETURN_STATUS

+EFIAPI

+CustomDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source buffer

+  DestinationSize - The size of destination buffer.

+  ScratchSize     - The size of scratch buffer.

+

+Returns:

+

+  RETURN_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return RETURN_UNSUPPORTED;

+}

+

+RETURN_STATUS

+EFIAPI

+CustomDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return RETURN_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.mbd b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.mbd
new file mode 100644
index 0000000..0cbb341
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseCustomDecompressLibNull</BaseName>

+    <Guid>e5566134-c75e-4ace-bad1-e23a3b335e30</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.msa b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.msa
new file mode 100644
index 0000000..b644ff0
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseCustomDecompressLibNull</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e5566134-c75e-4ace-bad1-e23a3b335e30</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">CustomDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BaseCustomDecompressLibNull.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/build.xml b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/build.xml
new file mode 100644
index 0000000..30ee33c
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseCustomDecompressLibNull/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseCustomDecompressLibNull"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseCustomDecompressLibNull"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseCustomDecompressLibNull">

+      <GenBuild baseName="BaseCustomDecompressLibNull" mbdFilename="${MODULE_DIR}/BaseCustomDecompressLibNull.mbd" msaFilename="${MODULE_DIR}/BaseCustomDecompressLibNull.msa"/>

+   </target>

+   <target depends="BaseCustomDecompressLibNull_clean" name="clean"/>

+   <target depends="BaseCustomDecompressLibNull_cleanall" name="cleanall"/>

+   <target name="BaseCustomDecompressLibNull_clean">

+      <OutputDirSetup baseName="BaseCustomDecompressLibNull" mbdFilename="${MODULE_DIR}/BaseCustomDecompressLibNull.mbd" msaFilename="${MODULE_DIR}/BaseCustomDecompressLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseCustomDecompressLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseCustomDecompressLibNull_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseCustomDecompressLibNull_cleanall">

+      <OutputDirSetup baseName="BaseCustomDecompressLibNull" mbdFilename="${MODULE_DIR}/BaseCustomDecompressLibNull.mbd" msaFilename="${MODULE_DIR}/BaseCustomDecompressLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseCustomDecompressLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseCustomDecompressLibNull_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseCustomDecompressLibNull*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.c b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.c
new file mode 100644
index 0000000..bbf88f9
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.c
@@ -0,0 +1,887 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BaseUefiTianoDecompressLib.c

+

+Abstract:

+

+  UEFI and Tiano Decompress Library 

+

+--*/

+

+//

+// Decompression algorithm begins here

+//

+#define BITBUFSIZ 32

+#define MAXMATCH  256

+#define THRESHOLD 3

+#define CODE_BIT  16

+#define BAD_TABLE - 1

+

+//

+// C: Char&Len Set; P: Position Set; T: exTra Set

+//

+#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)

+#define CBIT    9

+#define MAXPBIT 5

+#define TBIT    5

+#define MAXNP   ((1U << MAXPBIT) - 1)

+#define NT      (CODE_BIT + 3)

+#if NT > MAXNP

+#define NPT NT

+#else

+#define NPT MAXNP

+#endif

+

+typedef struct {

+  UINT8   *mSrcBase;  // Starting address of compressed data

+  UINT8   *mDstBase;  // Starting address of decompressed data

+  UINT32  mOutBuf;

+  UINT32  mInBuf;

+

+  UINT16  mBitCount;

+  UINT32  mBitBuf;

+  UINT32  mSubBitBuf;

+  UINT16  mBlockSize;

+  UINT32  mCompSize;

+  UINT32  mOrigSize;

+

+  UINT16  mBadTableFlag;

+

+  UINT16  mLeft[2 * NC - 1];

+  UINT16  mRight[2 * NC - 1];

+  UINT8   mCLen[NC];

+  UINT8   mPTLen[NPT];

+  UINT16  mCTable[4096];

+  UINT16  mPTTable[256];

+

+  //

+  // The length of the field 'Position Set Code Length Array Size' in Block Header.

+  // For EFI 1.1 de/compression algorithm, mPBit = 4

+  // For Tiano de/compression algorithm, mPBit = 5

+  //

+  UINT8   mPBit;

+} SCRATCH_DATA;

+

+VOID

+FillBuf (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+/*++

+

+Routine Description:

+

+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.

+

+Arguments:

+

+  Sd        - The global scratch data

+  NumOfBits  - The number of bits to shift and read.

+

+Returns: (VOID)

+

+--*/

+{

+  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);

+

+  while (NumOfBits > Sd->mBitCount) {

+

+    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));

+

+    if (Sd->mCompSize > 0) {

+      //

+      // Get 1 byte into SubBitBuf

+      //

+      Sd->mCompSize--;

+      Sd->mSubBitBuf  = 0;

+      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];

+      Sd->mBitCount   = 8;

+

+    } else {

+      //

+      // No more bits from the source, just pad zero bit.

+      //

+      Sd->mSubBitBuf  = 0;

+      Sd->mBitCount   = 8;

+

+    }

+  }

+

+  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);

+  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;

+}

+

+UINT32

+GetBits (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+/*++

+

+Routine Description:

+

+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent 

+  NumOfBits of bits from source. Returns NumOfBits of bits that are 

+  popped out.

+

+Arguments:

+

+  Sd            - The global scratch data.

+  NumOfBits     - The number of bits to pop and read.

+

+Returns:

+

+  The bits that are popped out.

+

+--*/

+{

+  UINT32  OutBits;

+

+  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));

+

+  FillBuf (Sd, NumOfBits);

+

+  return OutBits;

+}

+

+UINT16

+MakeTable (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfChar,

+  IN  UINT8         *BitLen,

+  IN  UINT16        TableBits,

+  OUT UINT16        *Table

+  )

+/*++

+

+Routine Description:

+

+  Creates Huffman Code mapping table according to code length array.

+

+Arguments:

+

+  Sd        - The global scratch data

+  NumOfChar - Number of symbols in the symbol set

+  BitLen    - Code length array

+  TableBits - The width of the mapping table

+  Table     - The table

+  

+Returns:

+  

+  0         - OK.

+  BAD_TABLE - The table is corrupted.

+

+--*/

+{

+  UINT16  Count[17];

+  UINT16  Weight[17];

+  UINT16  Start[18];

+  UINT16  *Pointer;

+  UINT16  Index3;

+  volatile UINT16  Index;

+  UINT16  Len;

+  UINT16  Char;

+  UINT16  JuBits;

+  UINT16  Avail;

+  UINT16  NextCode;

+  UINT16  Mask;

+

+  for (Index = 1; Index <= 16; Index++) {

+    Count[Index] = 0;

+  }

+

+  for (Index = 0; Index < NumOfChar; Index++) {

+    Count[BitLen[Index]]++;

+  }

+

+  Start[1] = 0;

+

+  for (Index = 1; Index <= 16; Index++) {

+    Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));

+  }

+

+  if (Start[17] != 0) {

+    /*(1U << 16)*/

+    return (UINT16) BAD_TABLE;

+  }

+

+  JuBits = (UINT16) (16 - TableBits);

+

+  for (Index = 1; Index <= TableBits; Index++) {

+    Start[Index] >>= JuBits;

+    Weight[Index] = (UINT16) (1U << (TableBits - Index));

+  }

+

+  while (Index <= 16) {

+    Weight[Index] = (UINT16) (1U << (16 - Index));

+    Index++;

+  }

+

+  Index = (UINT16) (Start[TableBits + 1] >> JuBits);

+

+  if (Index != 0) {

+    Index3 = (UINT16) (1U << TableBits);

+    while (Index != Index3) {

+      Table[Index++] = 0;

+    }

+  }

+

+  Avail = NumOfChar;

+  Mask  = (UINT16) (1U << (15 - TableBits));

+

+  for (Char = 0; Char < NumOfChar; Char++) {

+

+    Len = BitLen[Char];

+    if (Len == 0) {

+      continue;

+    }

+

+    NextCode = (UINT16) (Start[Len] + Weight[Len]);

+

+    if (Len <= TableBits) {

+

+      for (Index = Start[Len]; Index < NextCode; Index++) {

+        Table[Index] = Char;

+      }

+

+    } else {

+

+      Index3  = Start[Len];

+      Pointer = &Table[Index3 >> JuBits];

+      Index   = (UINT16) (Len - TableBits);

+

+      while (Index != 0) {

+        if (*Pointer == 0) {

+          Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;

+          *Pointer = Avail++;

+        }

+

+        if (Index3 & Mask) {

+          Pointer = &Sd->mRight[*Pointer];

+        } else {

+          Pointer = &Sd->mLeft[*Pointer];

+        }

+

+        Index3 <<= 1;

+        Index--;

+      }

+

+      *Pointer = Char;

+

+    }

+

+    Start[Len] = NextCode;

+  }

+  //

+  // Succeeds

+  //

+  return 0;

+}

+

+UINT32

+DecodeP (

+  IN  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Decodes a position value.

+

+Arguments:

+

+  Sd      - the global scratch data

+

+Returns:

+

+  The position value decoded.

+

+--*/

+{

+  UINT16  Val;

+  UINT32  Mask;

+  UINT32  Pos;

+

+  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+

+  if (Val >= MAXNP) {

+    Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+    do {

+

+      if (Sd->mBitBuf & Mask) {

+        Val = Sd->mRight[Val];

+      } else {

+        Val = Sd->mLeft[Val];

+      }

+

+      Mask >>= 1;

+    } while (Val >= MAXNP);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mPTLen[Val]);

+

+  Pos = Val;

+  if (Val > 1) {

+    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));

+  }

+

+  return Pos;

+}

+

+UINT16

+ReadPTLen (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        nn,

+  IN  UINT16        nbit,

+  IN  UINT16        Special

+  )

+/*++

+

+Routine Description:

+

+  Reads code lengths for the Extra Set or the Position Set

+

+Arguments:

+

+  Sd        - The global scratch data

+  nn        - Number of symbols

+  nbit      - Number of bits needed to represent nn

+  Special   - The special symbol that needs to be taken care of 

+

+Returns:

+

+  0         - OK.

+  BAD_TABLE - Table is corrupted.

+

+--*/

+{

+  UINT16  Number;

+  UINT16  CharC;

+  volatile UINT16  Index;

+  UINT32  Mask;

+

+  Number = (UINT16) GetBits (Sd, nbit);

+

+  if (Number == 0) {

+    CharC = (UINT16) GetBits (Sd, nbit);

+

+    for (Index = 0; Index < 256; Index++) {

+      Sd->mPTTable[Index] = CharC;

+    }

+

+    for (Index = 0; Index < nn; Index++) {

+      Sd->mPTLen[Index] = 0;

+    }

+

+    return 0;

+  }

+

+  Index = 0;

+

+  while (Index < Number) {

+

+    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));

+

+    if (CharC == 7) {

+      Mask = 1U << (BITBUFSIZ - 1 - 3);

+      while (Mask & Sd->mBitBuf) {

+        Mask >>= 1;

+        CharC += 1;

+      }

+    }

+

+    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));

+

+    Sd->mPTLen[Index++] = (UINT8) CharC;

+

+    if (Index == Special) {

+      CharC = (UINT16) GetBits (Sd, 2);

+      while ((INT16) (--CharC) >= 0) {

+        Sd->mPTLen[Index++] = 0;

+      }

+    }

+  }

+

+  while (Index < nn) {

+    Sd->mPTLen[Index++] = 0;

+  }

+

+  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);

+}

+

+VOID

+ReadCLen (

+  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Reads code lengths for Char&Len Set.

+

+Arguments:

+

+  Sd    - the global scratch data

+

+Returns: (VOID)

+

+--*/

+{

+  UINT16  Number;

+  UINT16  CharC;

+  volatile UINT16  Index;

+  UINT32  Mask;

+

+  Number = (UINT16) GetBits (Sd, CBIT);

+

+  if (Number == 0) {

+    CharC = (UINT16) GetBits (Sd, CBIT);

+

+    for (Index = 0; Index < NC; Index++) {

+      Sd->mCLen[Index] = 0;

+    }

+

+    for (Index = 0; Index < 4096; Index++) {

+      Sd->mCTable[Index] = CharC;

+    }

+

+    return ;

+  }

+

+  Index = 0;

+  while (Index < Number) {

+

+    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+    if (CharC >= NT) {

+      Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+      do {

+

+        if (Mask & Sd->mBitBuf) {

+          CharC = Sd->mRight[CharC];

+        } else {

+          CharC = Sd->mLeft[CharC];

+        }

+

+        Mask >>= 1;

+

+      } while (CharC >= NT);

+    }

+    //

+    // Advance what we have read

+    //

+    FillBuf (Sd, Sd->mPTLen[CharC]);

+

+    if (CharC <= 2) {

+

+      if (CharC == 0) {

+        CharC = 1;

+      } else if (CharC == 1) {

+        CharC = (UINT16) (GetBits (Sd, 4) + 3);

+      } else if (CharC == 2) {

+        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);

+      }

+

+      while ((INT16) (--CharC) >= 0) {

+        Sd->mCLen[Index++] = 0;

+      }

+

+    } else {

+

+      Sd->mCLen[Index++] = (UINT8) (CharC - 2);

+

+    }

+  }

+

+  while (Index < NC) {

+    Sd->mCLen[Index++] = 0;

+  }

+

+  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);

+

+  return ;

+}

+

+UINT16

+DecodeC (

+  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Decode a character/length value.

+

+Arguments:

+

+  Sd    - The global scratch data.

+

+Returns:

+

+  The value decoded.

+

+--*/

+{

+  UINT16  Index2;

+  UINT32  Mask;

+

+  if (Sd->mBlockSize == 0) {

+    //

+    // Starting a new block

+    //

+    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);

+    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+

+    ReadCLen (Sd);

+

+    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+  }

+

+  Sd->mBlockSize--;

+  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];

+

+  if (Index2 >= NC) {

+    Mask = 1U << (BITBUFSIZ - 1 - 12);

+

+    do {

+      if (Sd->mBitBuf & Mask) {

+        Index2 = Sd->mRight[Index2];

+      } else {

+        Index2 = Sd->mLeft[Index2];

+      }

+

+      Mask >>= 1;

+    } while (Index2 >= NC);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mCLen[Index2]);

+

+  return Index2;

+}

+

+VOID

+Decode (

+  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Decode the source data and put the resulting data into the destination buffer.

+

+Arguments:

+

+  Sd            - The global scratch data

+

+Returns: (VOID)

+

+ --*/

+{

+  UINT16  BytesRemain;

+  UINT32  DataIdx;

+  UINT16  CharC;

+

+  BytesRemain = (UINT16) (-1);

+

+  DataIdx     = 0;

+

+  for (;;) {

+    CharC = DecodeC (Sd);

+    if (Sd->mBadTableFlag != 0) {

+      return ;

+    }

+

+    if (CharC < 256) {

+      //

+      // Process an Original character

+      //

+      if (Sd->mOutBuf >= Sd->mOrigSize) {

+        return ;

+      } else {

+        Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;

+      }

+

+    } else {

+      //

+      // Process a Pointer

+      //

+      CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));

+

+      BytesRemain = CharC;

+

+      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;

+

+      BytesRemain--;

+      while ((INT16) (BytesRemain) >= 0) {

+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];

+        if (Sd->mOutBuf >= Sd->mOrigSize) {

+          return ;

+        }

+

+        BytesRemain--;

+      }

+    }

+  }

+

+  return ;

+}

+

+RETURN_STATUS

+EFIAPI

+UefiDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source buffer

+  DestinationSize - The size of destination buffer.

+  ScratchSize     - The size of scratch buffer.

+

+Returns:

+

+  RETURN_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  UINT32  CompressedSize;

+

+  ASSERT (Source != NULL);

+  ASSERT (DestinationSize != NULL);

+  ASSERT (ScratchSize != NULL);

+

+  *ScratchSize  = sizeof (SCRATCH_DATA);

+

+  if (SourceSize < 8) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  CopyMem (&CompressedSize, Source, sizeof (UINT32));

+  CopyMem (DestinationSize, (VOID *)((UINT8 *)Source + 4), sizeof (UINT32));

+

+  if (SourceSize < (CompressedSize + 8)) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+UefiTianoDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch,

+  IN UINT32      Version

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  Version         - 1 for UEFI Decompress algoruthm, 2 for Tiano Decompess algorithm

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  volatile UINT32  Index;

+  UINT32           CompSize;

+  UINT32           OrigSize;

+  SCRATCH_DATA     *Sd;

+  CONST UINT8      *Src;

+  UINT8            *Dst;

+

+  ASSERT (Source != NULL);

+  ASSERT (Destination != NULL);

+  ASSERT (Scratch != NULL);

+

+  Src     = Source;

+  Dst     = Destination;

+

+  Sd = (SCRATCH_DATA *) Scratch;

+

+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);

+  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);

+

+  //

+  // If compressed file size is 0, return

+  //

+  if (OrigSize == 0) {

+    return RETURN_SUCCESS;

+  }

+

+  Src = Src + 8;

+

+  for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {

+    ((UINT8 *) Sd)[Index] = 0;

+  }

+  //

+  // The length of the field 'Position Set Code Length Array Size' in Block Header.

+  // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4

+  // For Tiano de/compression algorithm(Version 2), mPBit = 5

+  //

+  switch (Version) {

+    case 1 :

+      Sd->mPBit = 4;

+      break;

+    case 2 :

+      Sd->mPBit = 5;

+      break;

+    default:

+      ASSERT (FALSE);

+  }

+  Sd->mSrcBase  = (UINT8 *)Src;

+  Sd->mDstBase  = Dst;

+  Sd->mCompSize = CompSize;

+  Sd->mOrigSize = OrigSize;

+

+  //

+  // Fill the first BITBUFSIZ bits

+  //

+  FillBuf (Sd, BITBUFSIZ);

+

+  //

+  // Decompress it

+  //

+  Decode (Sd);

+

+  if (Sd->mBadTableFlag != 0) {

+    //

+    // Something wrong with the source

+    //

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+UefiDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return UefiTianoDecompress (Source, Destination, Scratch, 1);

+}

+

+RETURN_STATUS

+EFIAPI

+TianoDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source buffer

+  DestinationSize - The size of destination buffer.

+  ScratchSize     - The size of scratch buffer.

+

+Returns:

+

+  RETURN_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);

+}

+

+RETURN_STATUS

+EFIAPI

+TianoDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return UefiTianoDecompress (Source, Destination, Scratch, 2);

+}

diff --git a/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.mbd b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.mbd
new file mode 100644
index 0000000..684d8e6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseUefiTianoDecompressLib</BaseName>

+    <Guid>d774c4d9-c121-4da3-a5e2-0f317e3c630c</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:18</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.msa b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.msa
new file mode 100644
index 0000000..b36e85a
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/BaseUefiTianoDecompressLib.msa
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseUefiTianoDecompressLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>d774c4d9-c121-4da3-a5e2-0f317e3c630c</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_PRODUCED">TianoDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BaseUefiTianoDecompressLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/build.xml b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/build.xml
new file mode 100644
index 0000000..42b0263
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/BaseUefiTianoDecompressLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseUefiTianoDecompressLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseUefiTianoDecompressLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseUefiTianoDecompressLib">

+      <GenBuild baseName="BaseUefiTianoDecompressLib" mbdFilename="${MODULE_DIR}/BaseUefiTianoDecompressLib.mbd" msaFilename="${MODULE_DIR}/BaseUefiTianoDecompressLib.msa"/>

+   </target>

+   <target depends="BaseUefiTianoDecompressLib_clean" name="clean"/>

+   <target depends="BaseUefiTianoDecompressLib_cleanall" name="cleanall"/>

+   <target name="BaseUefiTianoDecompressLib_clean">

+      <OutputDirSetup baseName="BaseUefiTianoDecompressLib" mbdFilename="${MODULE_DIR}/BaseUefiTianoDecompressLib.mbd" msaFilename="${MODULE_DIR}/BaseUefiTianoDecompressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseUefiTianoDecompressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseUefiTianoDecompressLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseUefiTianoDecompressLib_cleanall">

+      <OutputDirSetup baseName="BaseUefiTianoDecompressLib" mbdFilename="${MODULE_DIR}/BaseUefiTianoDecompressLib.mbd" msaFilename="${MODULE_DIR}/BaseUefiTianoDecompressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseUefiTianoDecompressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseUefiTianoDecompressLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseUefiTianoDecompressLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.c b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.c
new file mode 100644
index 0000000..300cc91
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.c
@@ -0,0 +1,105 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeCoreCustomDecompressLibFromHob.c

+

+Abstract:

+

+  Custom Decompress Library from HOBs 

+

+--*/

+

+static DECOMPRESS_LIBRARY  mCustomDecompress;

+

+EFI_STATUS

+DxeCoreCustomDecompressLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_HOB_GUID_TYPE  *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gEfiCustomizedDecompressProtocolGuid);

+  ASSERT (GuidHob != NULL);

+  CopyMem (&mCustomDecompress, GET_GUID_HOB_DATA (GuidHob), sizeof (mCustomDecompress));  

+  return EFI_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+CustomDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source buffer

+  DestinationSize - The size of destination buffer.

+  ScratchSize     - The size of scratch buffer.

+

+Returns:

+

+  RETURN_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return mCustomDecompress.GetInfo (Source, SourceSize, DestinationSize, ScratchSize);

+}

+

+RETURN_STATUS

+EFIAPI

+CustomDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return mCustomDecompress.Decompress (Source, Destination, Scratch);

+}

diff --git a/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.mbd b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.mbd
new file mode 100644
index 0000000..f183e5a
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeCoreCustomDecompressLibFromHob</BaseName>

+    <Guid>942e0182-3e1d-47f9-92dc-4939d1a0ba00</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:07</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.msa b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.msa
new file mode 100644
index 0000000..e708963
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/DxeCoreCustomDecompressLibFromHob.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeCoreCustomDecompressLibFromHob</BaseName>

+    <ModuleType>DXE_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>942e0182-3e1d-47f9-92dc-4939d1a0ba00</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:07</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">CustomDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeCoreCustomDecompressLibFromHob.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">CustomizedDecompress</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DxeCoreCustomDecompressLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/build.xml b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/build.xml
new file mode 100644
index 0000000..c18b27f
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreCustomDecompressLibFromHob/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeCoreCustomDecompressLibFromHob"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeCoreCustomDecompressLibFromHob"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeCoreCustomDecompressLibFromHob">

+      <GenBuild baseName="DxeCoreCustomDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreCustomDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreCustomDecompressLibFromHob.msa"/>

+   </target>

+   <target depends="DxeCoreCustomDecompressLibFromHob_clean" name="clean"/>

+   <target depends="DxeCoreCustomDecompressLibFromHob_cleanall" name="cleanall"/>

+   <target name="DxeCoreCustomDecompressLibFromHob_clean">

+      <OutputDirSetup baseName="DxeCoreCustomDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreCustomDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreCustomDecompressLibFromHob.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreCustomDecompressLibFromHob_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreCustomDecompressLibFromHob_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeCoreCustomDecompressLibFromHob_cleanall">

+      <OutputDirSetup baseName="DxeCoreCustomDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreCustomDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreCustomDecompressLibFromHob.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreCustomDecompressLibFromHob_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreCustomDecompressLibFromHob_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeCoreCustomDecompressLibFromHob*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
new file mode 100644
index 0000000..c75ab85
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
@@ -0,0 +1,623 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeCorePerformance.c

+

+Abstract:

+

+  Support for measurement of DXE performance 

+

+--*/

+

+//

+// Interface declarations for Performance Protocol.

+//

+/**

+  Adds a record at the end of the performance measurement log

+  that records the start time of a performance measurement.

+

+  Adds a record to the end of the performance measurement log

+  that contains the Handle, Token, and Module.

+  The end time of the new record must be set to zero.

+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.

+  If TimeStamp is zero, the start time in the record is filled in with the value

+  read from the current time stamp. 

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval EFI_SUCCESS             The data was read correctly from the device.

+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.

+

+**/

+EFI_STATUS

+EFIAPI

+StartGauge (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  );

+

+/**

+  Searches the performance measurement log from the beginning of the log

+  for the first matching record that contains a zero end time and fills in a valid end time. 

+  

+  Searches the performance measurement log from the beginning of the log

+  for the first record that matches Handle, Token, and Module and has an end time value of zero.

+  If the record can not be found then return EFI_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then the end time in the record is filled in with the value specified by TimeStamp.

+  If the record is found and TimeStamp is zero, then the end time in the matching record

+  is filled in with the current time stamp value.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval EFI_SUCCESS             The end of  the measurement was recorded.

+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.

+

+**/

+EFI_STATUS

+EFIAPI

+EndGauge (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  );

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Retrieves the performance log entry from the performance log specified by LogEntryKey.

+  If it stands for a valid entry, then EFI_SUCCESS is returned and

+  GaugeDataEntry stores the pointer to that entry.

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey

+                                  if the retrieval is successful.

+

+  @retval EFI_SUCCESS             The GuageDataEntry is successfuly found based on LogEntryKey.

+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).

+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).

+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL. 

+

+**/

+EFI_STATUS

+EFIAPI

+GetGauge (

+  IN  UINTN               LogEntryKey,

+  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry

+  );

+

+//

+// Definition for global variables.

+//

+STATIC GAUGE_DATA_HEADER    *mGaugeData;

+STATIC UINT32               mMaxGaugeRecords;

+

+PERFORMANCE_PROTOCOL PerformanceInterface = {

+  StartGauge,

+  EndGauge,

+  GetGauge

+  };

+

+

+/**

+  Searches in the gauge array with keyword Handle, Token and Module.

+

+  This internal function searches for the gauge entry in the gauge array.

+  If there is an entry that exactly matches the given key word triple

+  and its end time stamp is zero, then the index of that gauge entry is returned;

+  otherwise, the the number of gauge entries in the array is returned.  

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+

+  @retval The index of gauge entry in the array.

+

+**/

+UINT32

+InternalSearchForGaugeEntry (

+  IN CONST VOID                 *Handle,  OPTIONAL

+  IN CONST CHAR8                *Token,   OPTIONAL

+  IN CONST CHAR8                *Module   OPTIONAL

+  )

+{

+  UINT32                    Index;

+  UINT32                    NumberOfEntries;

+  GAUGE_DATA_ENTRY          *GaugeEntryArray;

+

+  if (Token == NULL) {

+    Token = "";

+  }

+  if (Module == NULL) {

+    Module = "";

+  }

+

+  NumberOfEntries = mGaugeData->NumberOfEntries;

+  GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);

+

+  for (Index = 0; Index < NumberOfEntries; Index++) {

+    if ((GaugeEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&

+         AsciiStrnCmp (GaugeEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH) == 0 &&

+         AsciiStrnCmp (GaugeEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH) == 0 &&

+         GaugeEntryArray[Index].EndTimeStamp == 0

+       ) {

+      break;

+    }

+  }

+ 

+  return Index;

+}

+

+/**

+  Adds a record at the end of the performance measurement log

+  that records the start time of a performance measurement.

+

+  Adds a record to the end of the performance measurement log

+  that contains the Handle, Token, and Module.

+  The end time of the new record must be set to zero.

+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.

+  If TimeStamp is zero, the start time in the record is filled in with the value

+  read from the current time stamp. 

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval EFI_SUCCESS             The data was read correctly from the device.

+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.

+

+**/

+EFI_STATUS

+EFIAPI

+StartGauge (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  GAUGE_DATA_ENTRY          *GaugeEntryArray;

+  UINTN                     GaugeDataSize;

+  UINTN                     OldGaugeDataSize;

+  GAUGE_DATA_HEADER         *OldGaugeData;

+  EFI_STATUS                Status;

+  UINT32                    Index;

+

+  Index = mGaugeData->NumberOfEntries;

+  if (Index >= mMaxGaugeRecords) {

+    //

+    // Try to enlarge the scale of gauge arrary.

+    //

+    OldGaugeData      = mGaugeData;

+    OldGaugeDataSize  = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;

+    mMaxGaugeRecords *= 2;

+    GaugeDataSize     = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;

+    Status            = gBS->AllocatePool (

+                               EfiBootServicesData,

+                               GaugeDataSize,

+                               (VOID **) &mGaugeData

+                               );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Initialize new data arry and migrate old data one. 

+    //

+    mGaugeData        = ZeroMem (mGaugeData, GaugeDataSize);

+    mGaugeData        = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize);

+    

+    gBS->FreePool (OldGaugeData); 

+  }

+  

+  GaugeEntryArray               = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);

+  GaugeEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;

+

+  if (Token != NULL) {

+    AsciiStrnCpy (GaugeEntryArray[Index].Token, Token, DXE_PERFORMANCE_STRING_LENGTH);

+  }

+  if (Module != NULL) {

+    AsciiStrnCpy (GaugeEntryArray[Index].Module, Module, DXE_PERFORMANCE_STRING_LENGTH);

+  }

+

+  if (TimeStamp == 0) {

+    TimeStamp = GetPerformanceCounter ();

+  }

+  GaugeEntryArray[Index].StartTimeStamp = TimeStamp;

+

+  mGaugeData->NumberOfEntries++;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Searches the performance measurement log from the beginning of the log

+  for the first matching record that contains a zero end time and fills in a valid end time. 

+  

+  Searches the performance measurement log from the beginning of the log

+  for the first record that matches Handle, Token, and Module and has an end time value of zero.

+  If the record can not be found then return EFI_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then the end time in the record is filled in with the value specified by TimeStamp.

+  If the record is found and TimeStamp is zero, then the end time in the matching record

+  is filled in with the current time stamp value.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval EFI_SUCCESS             The end of  the measurement was recorded.

+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.

+

+**/

+EFI_STATUS

+EFIAPI

+EndGauge (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  GAUGE_DATA_ENTRY  *GaugeEntryArray;

+  UINT32            Index;

+

+  if (TimeStamp == 0) {

+    TimeStamp = GetPerformanceCounter ();

+  }

+

+  Index = InternalSearchForGaugeEntry (Handle, Token, Module);

+  if (Index >= mGaugeData->NumberOfEntries) {

+    return EFI_NOT_FOUND;

+  }

+  GaugeEntryArray = (GAUGE_DATA_ENTRY  *) (mGaugeData + 1);

+  GaugeEntryArray[Index].EndTimeStamp = TimeStamp;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Retrieves the performance log entry from the performance log specified by LogEntryKey.

+  If it stands for a valid entry, then EFI_SUCCESS is returned and

+  GaugeDataEntry stores the pointer to that entry.

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey

+                                  if the retrieval is successful.

+

+  @retval EFI_SUCCESS             The GuageDataEntry is successfuly found based on LogEntryKey.

+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).

+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).

+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL. 

+

+**/

+EFI_STATUS

+EFIAPI

+GetGauge (

+  IN  UINTN               LogEntryKey,

+  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry

+  )

+{

+  UINTN               NumberOfEntries;

+  GAUGE_DATA_ENTRY    *LogEntryArray;

+

+  NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);

+  if (LogEntryKey > NumberOfEntries) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (LogEntryKey == NumberOfEntries) {

+    return EFI_NOT_FOUND;

+  }

+  

+  LogEntryArray   = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);

+  

+  if (GaugeDataEntry == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  *GaugeDataEntry = &LogEntryArray[LogEntryKey];

+  

+  return EFI_SUCCESS;

+}

+

+/**

+  Dumps all the PEI performance log to DXE performance gauge array.

+  

+  This internal function dumps all the PEI performance log to the DXE performance gauge array.

+  It retrieves the optional GUID HOB for PEI performance and then saves the performance data

+  to DXE performance data structures.

+

+**/

+VOID

+InternalGetPeiPerformance (

+  VOID

+  )

+{

+  EFI_HOB_GUID_TYPE                 *GuidHob;

+  PEI_PERFORMANCE_LOG_HEADER        *LogHob;

+  PEI_PERFORMANCE_LOG_ENTRY         *LogEntryArray;

+  GAUGE_DATA_ENTRY                  *GaugeEntryArray;

+  UINT32                            Index;

+  UINT32                            NumberOfEntries;

+

+  NumberOfEntries = 0;

+  GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);

+

+  //

+  // Dump PEI Log Entries to DXE Guage Data structure. 

+  //

+  GuidHob = GetFirstGuidHob (&gPeiPerformanceHobGuid);

+  if (GuidHob != NULL) {

+    LogHob          = GET_GUID_HOB_DATA (GuidHob);

+    LogEntryArray   = (PEI_PERFORMANCE_LOG_ENTRY *) (LogHob + 1);

+    GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);

+

+    NumberOfEntries = LogHob->NumberOfEntries;

+    for (Index = 0; Index < NumberOfEntries; Index++) {

+      GaugeEntryArray[Index].Handle         = LogEntryArray[Index].Handle;

+      AsciiStrnCpy (GaugeEntryArray[Index].Token,  LogEntryArray[Index].Token,  DXE_PERFORMANCE_STRING_LENGTH);

+      AsciiStrnCpy (GaugeEntryArray[Index].Module, LogEntryArray[Index].Module, DXE_PERFORMANCE_STRING_LENGTH);

+      GaugeEntryArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp;

+      GaugeEntryArray[Index].EndTimeStamp   = LogEntryArray[Index].EndTimeStamp;

+    }

+  }

+  mGaugeData->NumberOfEntries = NumberOfEntries;

+}

+

+/**

+  The constructor function initializes Performance infrastructure for DXE phase.

+  

+  The constructor function publishes Performance protocol, allocates memory to log DXE performance

+  and merges PEI performance data to DXE performance log.

+  It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeCorePerformanceLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                Status;

+  EFI_HANDLE                Handle;

+  UINTN                     GaugeDataSize;

+

+  //

+  // Install the protocol interfaces.

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gPerformanceProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &PerformanceInterface

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  mMaxGaugeRecords = INIT_DXE_GAUGE_DATA_ENTRIES + MAX_PEI_PERFORMANCE_LOG_ENTRIES;

+  GaugeDataSize   = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  GaugeDataSize,

+                  (VOID **) &mGaugeData

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  ZeroMem (mGaugeData, GaugeDataSize);

+

+  InternalGetPeiPerformance ();

+

+  return Status;

+}

+

+/**

+  Adds a record at the end of the performance measurement log

+  that records the start time of a performance measurement.

+

+  Adds a record to the end of the performance measurement log

+  that contains the Handle, Token, and Module.

+  The end time of the new record must be set to zero.

+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.

+  If TimeStamp is zero, the start time in the record is filled in with the value

+  read from the current time stamp. 

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = StartGauge (Handle, Token, Module, TimeStamp);

+  return (RETURN_STATUS) Status;

+}

+

+/**

+  Searches the performance measurement log from the beginning of the log

+  for the first matching record that contains a zero end time and fills in a valid end time. 

+  

+  Searches the performance measurement log from the beginning of the log

+  for the first record that matches Handle, Token, and Module and has an end time value of zero.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then the end time in the record is filled in with the value specified by TimeStamp.

+  If the record is found and TimeStamp is zero, then the end time in the matching record

+  is filled in with the current time stamp value.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.

+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = EndGauge (Handle, Token, Module, TimeStamp);

+  return (RETURN_STATUS) Status;

+}

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Retrieves the performance log entry from the performance log

+  that immediately follows the log entry specified by LogEntryKey.

+  If LogEntryKey is zero, then the first entry from the performance log is returned.

+  If the log entry specified by LogEntryKey is the last entry in the performance log,

+  then 0 is returned.  Otherwise, the performance log entry is returned in Handle,

+  Token, Module, StartTimeStamp, and EndTimeStamp.

+  The key for the current performance log entry is returned. 

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  StartTimeStamp          The 64-bit time stamp that was recorded when the measurement was started.

+  @param  EndTimeStamp            The 64-bit time stamp that was recorded when the measurement was ended.

+

+  @return The key for the current performance log entry.

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurement (

+  UINTN           LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp

+  )

+{

+  EFI_STATUS        Status;

+  GAUGE_DATA_ENTRY  *GaugeData;

+

+  ASSERT (Handle != NULL);

+  ASSERT (Token != NULL);

+  ASSERT (Module != NULL);

+  ASSERT (StartTimeStamp != NULL);

+  ASSERT (EndTimeStamp != NULL);

+

+  Status = GetGauge (LogEntryKey++, &GaugeData);

+  

+  //

+  // Make sure that LogEntryKey is a valid log entry key,

+  //

+  ASSERT (Status != EFI_INVALID_PARAMETER);

+

+  if (EFI_ERROR (Status)) {

+    //

+    // The LogEntryKey is the last entry (equals to the total entry number).

+    //

+    return 0;

+  }

+

+  ASSERT (GaugeData != NULL);

+

+  *Handle         = (VOID *) (UINTN) GaugeData->Handle;

+  *Token          = GaugeData->Token;

+  *Module         = GaugeData->Module;

+  *StartTimeStamp = GaugeData->StartTimeStamp;

+  *EndTimeStamp   = GaugeData->EndTimeStamp;

+

+  return LogEntryKey;  

+}

+

+/**

+  Returns TRUE if the performance measurement macros are enabled. 

+  

+  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is set.

+  @retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PerformanceMeasurementEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);

+}

diff --git a/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.mbd b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.mbd
new file mode 100644
index 0000000..a8f235f
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeCorePerformanceLib</BaseName>

+    <Guid>D0F78BBF-0A30-4c63-8A48-0F618A4AFACD</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:10</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa
new file mode 100644
index 0000000..3c086d2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeCorePerformanceLib</BaseName>

+    <ModuleType>DXE_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>D0F78BBF-0A30-4c63-8A48-0F618A4AFACD</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the Tiano Decompress Library</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:10</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TimerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeCorePerformanceLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Performance</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PeiPerformanceHob</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <Constructor>DxeCorePerformanceLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/build.xml b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/build.xml
new file mode 100644
index 0000000..c711b30
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCorePerformanceLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeCorePerformanceLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeCorePerformanceLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeCorePerformanceLib">

+      <GenBuild baseName="DxeCorePerformanceLib" mbdFilename="${MODULE_DIR}/DxeCorePerformanceLib.mbd" msaFilename="${MODULE_DIR}/DxeCorePerformanceLib.msa"/>

+   </target>

+   <target depends="DxeCorePerformanceLib_clean" name="clean"/>

+   <target depends="DxeCorePerformanceLib_cleanall" name="cleanall"/>

+   <target name="DxeCorePerformanceLib_clean">

+      <OutputDirSetup baseName="DxeCorePerformanceLib" mbdFilename="${MODULE_DIR}/DxeCorePerformanceLib.mbd" msaFilename="${MODULE_DIR}/DxeCorePerformanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCorePerformanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCorePerformanceLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeCorePerformanceLib_cleanall">

+      <OutputDirSetup baseName="DxeCorePerformanceLib" mbdFilename="${MODULE_DIR}/DxeCorePerformanceLib.mbd" msaFilename="${MODULE_DIR}/DxeCorePerformanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCorePerformanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCorePerformanceLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeCorePerformanceLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.c b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.c
new file mode 100644
index 0000000..1bb832b
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.c
@@ -0,0 +1,106 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeCoreTianoDecompressLibFromHob.c

+

+Abstract:

+

+  Tiano Decompress Library from HOBs 

+

+--*/

+

+static DECOMPRESS_LIBRARY  mTianoDecompress;

+

+EFI_STATUS

+DxeCoreTianoDecompressLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_HOB_GUID_TYPE  *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gEfiTianoDecompressProtocolGuid);

+  ASSERT (GuidHob != NULL);   

+  CopyMem (&mTianoDecompress, GET_GUID_HOB_DATA (GuidHob), sizeof (mTianoDecompress));  

+  return EFI_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+TianoDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source buffer

+  DestinationSize - The size of destination buffer.

+  ScratchSize     - The size of scratch buffer.

+

+Returns:

+

+  RETURN_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return mTianoDecompress.GetInfo (Source, SourceSize, DestinationSize, ScratchSize);

+}

+

+RETURN_STATUS

+EFIAPI

+TianoDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return mTianoDecompress.Decompress (Source, Destination, Scratch);

+}

+

diff --git a/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.mbd b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.mbd
new file mode 100644
index 0000000..f3ca9a4
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeCoreTianoDecompressLibFromHob</BaseName>

+    <Guid>cef487a1-751d-4fe0-a39b-e6892b4610c8</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:10</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.msa b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.msa
new file mode 100644
index 0000000..c711c2d
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeCoreTianoDecompressLibFromHob</BaseName>

+    <ModuleType>DXE_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>cef487a1-751d-4fe0-a39b-e6892b4610c8</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:10</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">TianoDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeCoreTianoDecompressLibFromHob.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">TianoDecompress</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DxeCoreTianoDecompressLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/build.xml b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/build.xml
new file mode 100644
index 0000000..c59b44c
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreTianoDecompressLibFromHob/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeCoreTianoDecompressLibFromHob"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeCoreTianoDecompressLibFromHob"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeCoreTianoDecompressLibFromHob">

+      <GenBuild baseName="DxeCoreTianoDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreTianoDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreTianoDecompressLibFromHob.msa"/>

+   </target>

+   <target depends="DxeCoreTianoDecompressLibFromHob_clean" name="clean"/>

+   <target depends="DxeCoreTianoDecompressLibFromHob_cleanall" name="cleanall"/>

+   <target name="DxeCoreTianoDecompressLibFromHob_clean">

+      <OutputDirSetup baseName="DxeCoreTianoDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreTianoDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreTianoDecompressLibFromHob.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreTianoDecompressLibFromHob_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreTianoDecompressLibFromHob_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeCoreTianoDecompressLibFromHob_cleanall">

+      <OutputDirSetup baseName="DxeCoreTianoDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreTianoDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreTianoDecompressLibFromHob.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreTianoDecompressLibFromHob_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreTianoDecompressLibFromHob_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeCoreTianoDecompressLibFromHob*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.c b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.c
new file mode 100644
index 0000000..b4bd539
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.c
@@ -0,0 +1,105 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxeCoreUefiDecompressLibFromHob.c

+

+Abstract:

+

+  UEFI Decompress Library from HOBs 

+

+--*/

+

+static DECOMPRESS_LIBRARY  mEfiDecompress;

+

+EFI_STATUS

+DxeCoreUefiDecompressLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_HOB_GUID_TYPE  *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gEfiDecompressProtocolGuid);

+  ASSERT (GuidHob != NULL);

+  CopyMem (&mEfiDecompress, GET_GUID_HOB_DATA (GuidHob), sizeof (mEfiDecompress));  

+  return EFI_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+UefiDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  SourceSize      - The size of source buffer

+  DestinationSize - The size of destination buffer.

+  ScratchSize     - The size of scratch buffer.

+

+Returns:

+

+  RETURN_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return mEfiDecompress.GetInfo (Source, SourceSize, DestinationSize, ScratchSize);

+}

+

+RETURN_STATUS

+EFIAPI

+UefiDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+/*++

+

+Routine Description:

+

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  Source          - The source buffer containing the compressed data.

+  Destination     - The destination buffer to store the decompressed data

+  Scratch         - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+Returns:

+

+  RETURN_SUCCESS           - Decompression is successfull

+  RETURN_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  return mEfiDecompress.Decompress (Source, Destination, Scratch);

+}

diff --git a/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.mbd b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.mbd
new file mode 100644
index 0000000..5bb0b93
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeCoreUefiDecompressLibFromHob</BaseName>

+    <Guid>5c12c06f-5cf8-48a6-9860-6c5b2c036bbf</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:10</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.msa b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.msa
new file mode 100644
index 0000000..7e0c233
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeCoreUefiDecompressLibFromHob</BaseName>

+    <ModuleType>DXE_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>5c12c06f-5cf8-48a6-9860-6c5b2c036bbf</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:10</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeCoreUefiDecompressLibFromHob.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Decompress</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DxeCoreUefiDecompressLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/build.xml b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/build.xml
new file mode 100644
index 0000000..92fedaf
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/DxeCoreUefiDecompressLibFromHob/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeCoreUefiDecompressLibFromHob"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeCoreUefiDecompressLibFromHob"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeCoreUefiDecompressLibFromHob">

+      <GenBuild baseName="DxeCoreUefiDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreUefiDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreUefiDecompressLibFromHob.msa"/>

+   </target>

+   <target depends="DxeCoreUefiDecompressLibFromHob_clean" name="clean"/>

+   <target depends="DxeCoreUefiDecompressLibFromHob_cleanall" name="cleanall"/>

+   <target name="DxeCoreUefiDecompressLibFromHob_clean">

+      <OutputDirSetup baseName="DxeCoreUefiDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreUefiDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreUefiDecompressLibFromHob.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreUefiDecompressLibFromHob_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreUefiDecompressLibFromHob_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeCoreUefiDecompressLibFromHob_cleanall">

+      <OutputDirSetup baseName="DxeCoreUefiDecompressLibFromHob" mbdFilename="${MODULE_DIR}/DxeCoreUefiDecompressLibFromHob.mbd" msaFilename="${MODULE_DIR}/DxeCoreUefiDecompressLibFromHob.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreUefiDecompressLibFromHob_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreUefiDecompressLibFromHob_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeCoreUefiDecompressLibFromHob*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/DebugLib.c b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/DebugLib.c
new file mode 100644
index 0000000..5a7300f
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/DebugLib.c
@@ -0,0 +1,314 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugLib.c

+

+Abstract:

+

+  EFI Debug Library 

+

+--*/

+

+static BOOLEAN                   mDebugLevelInstalled = FALSE;

+static EFI_DEBUG_LEVEL_PROTOCOL  mDebugLevel = { 0 };

+

+EFI_STATUS

+DebugLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS               Status;

+

+  //

+  // Initialize Debug Level Protocol

+  //

+  mDebugLevel.DebugLevel = PcdGet32(PcdDebugPrintErrorLevel);

+

+  //

+  // Install Debug Level Protocol 

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ImageHandle,

+                  &gEfiDebugLevelProtocolGuid, &mDebugLevel,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Set flag to show that the Debug Level Protocol has been installed

+  //

+  mDebugLevelInstalled = TRUE;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+DebugAssert (

+  IN CHAR8  *FileName,

+  IN INTN   LineNumber,

+  IN CHAR8  *Description

+  )

+/*++

+

+Routine Description:

+

+  Worker function for ASSERT(). If Error Logging hub is loaded log ASSERT

+  information. If Error Logging hub is not loaded CpuBreakpoint ().

+

+  We use UINT64 buffers due to IPF alignment concerns.

+

+Arguments:

+

+  FileName    - File name of failing routine.

+

+  LineNumber  - Line number of failing ASSERT().

+

+  Description - Descritption, usally the assertion,

+  

+Returns:

+  

+  None

+

+--*/

+{

+  UINT64                 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof(UINT64)];

+  EFI_DEBUG_ASSERT_DATA  *AssertData;

+  UINTN                  TotalSize;

+  CHAR8                  *Temp;

+

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) == 0) {

+    return;

+  }

+

+  //

+  // Make sure it will all fit in the passed in buffer

+  //

+  TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA) + AsciiStrLen (FileName) + 1 + AsciiStrLen (Description) + 1;

+  if (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE) {

+    //

+    // Fill in EFI_DEBUG_ASSERT_DATA

+    //

+    AssertData = (EFI_DEBUG_ASSERT_DATA *)Buffer;

+    AssertData->LineNumber = (UINT32)LineNumber;

+

+    //

+    // Copy Ascii FileName including NULL.

+    //

+    Temp = AsciiStrCpy ((CHAR8 *)(AssertData + 1), FileName);

+

+    //

+    // Copy Ascii Description 

+    //

+    AsciiStrCpy (Temp + AsciiStrLen(FileName) + 1, Description);

+

+    REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+      (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),

+      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),

+      AssertData,

+      TotalSize

+      );

+  }

+

+  //

+  // Put break point in module that contained the error.

+  //

+  CpuBreakpoint ();

+}

+

+VOID

+DebugVPrint (

+  IN  UINTN    ErrorLevel,

+  IN  CHAR8    *Format,

+  IN  VA_LIST  Marker

+  )

+/*++

+

+Routine Description:

+

+  Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT

+  information. If Error Logging hub is not loaded do nothing.

+

+  We use UINT64 buffers due to IPF alignment concerns.

+

+Arguments:

+

+  ErrorLevel - If error level is set do the debug print.

+

+  Format     - String to use for the print, followed by Print arguments.

+

+  Marker     - VarArgs

+  

+Returns:

+  

+  None

+

+--*/

+{

+  UINT64          Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)];

+  EFI_DEBUG_INFO  *DebugInfo;

+  UINTN           TotalSize;

+  UINTN           Index;

+  UINT64          *ArgumentPointer;

+

+  //

+  // Check driver Debug Level value and global debug level

+  //

+  if (mDebugLevelInstalled) {

+    if ((ErrorLevel & mDebugLevel.DebugLevel) == 0) {

+      return;

+    }

+  } else {

+    if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+      return;

+    }

+  }

+

+  TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64 *) + AsciiStrLen (Format) + 1;

+  if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {

+    return;

+  }

+

+  //

+  // Then EFI_DEBUG_INFO

+  //

+  DebugInfo = (EFI_DEBUG_INFO *)Buffer;

+  DebugInfo->ErrorLevel = (UINT32)ErrorLevel;

+

+  //

+  // 256 byte mini Var Arg stack. That is followed by the format string.

+  //

+  for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) {

+    *ArgumentPointer = VA_ARG (Marker, UINT64);

+  }

+  AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format);

+

+  //

+  //

+  //

+  REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+    EFI_DEBUG_CODE,

+    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),

+    DebugInfo,

+    TotalSize

+    );

+}

+

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN  ErrorLevel,

+  IN  CHAR8  *Format,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Wrapper for DebugVPrint ()

+  

+Arguments:

+

+  ErrorLevel - If error level is set do the debug print.

+

+  Format     - String to use for the print, followed by Print arguments.

+

+  ...        - Print arguments.

+

+Returns:

+  

+  None

+

+--*/

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, Format);

+  DebugVPrint (ErrorLevel, Format, Marker);

+  VA_END (Marker);

+}

+

+/**

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param  Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param  Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+//  SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+  SetMem (Buffer, Length, 0xAF);

+  return Buffer;

+}

+

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

+

diff --git a/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.mbd b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.mbd
new file mode 100644
index 0000000..9825a20
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkDxeDebugLibReportStatusCode</BaseName>

+    <Guid>76a2a4d8-f605-407a-8057-4a17dcdc4c6d</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:12</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.msa b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.msa
new file mode 100644
index 0000000..d7dbda6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkDxeDebugLibReportStatusCode</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>76a2a4d8-f605-407a-8057-4a17dcdc4c6d</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Debug Library for DXE drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:12</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DebugLevel</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DebugLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/build.xml b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/build.xml
new file mode 100644
index 0000000..6cedc55
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkDxeDebugLibReportStatusCode"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkDxeDebugLibReportStatusCode"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkDxeDebugLibReportStatusCode">

+      <GenBuild baseName="EdkDxeDebugLibReportStatusCode" mbdFilename="${MODULE_DIR}/EdkDxeDebugLibReportStatusCode.mbd" msaFilename="${MODULE_DIR}/EdkDxeDebugLibReportStatusCode.msa"/>

+   </target>

+   <target depends="EdkDxeDebugLibReportStatusCode_clean" name="clean"/>

+   <target depends="EdkDxeDebugLibReportStatusCode_cleanall" name="cleanall"/>

+   <target name="EdkDxeDebugLibReportStatusCode_clean">

+      <OutputDirSetup baseName="EdkDxeDebugLibReportStatusCode" mbdFilename="${MODULE_DIR}/EdkDxeDebugLibReportStatusCode.mbd" msaFilename="${MODULE_DIR}/EdkDxeDebugLibReportStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxeDebugLibReportStatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxeDebugLibReportStatusCode_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkDxeDebugLibReportStatusCode_cleanall">

+      <OutputDirSetup baseName="EdkDxeDebugLibReportStatusCode" mbdFilename="${MODULE_DIR}/EdkDxeDebugLibReportStatusCode.mbd" msaFilename="${MODULE_DIR}/EdkDxeDebugLibReportStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxeDebugLibReportStatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxeDebugLibReportStatusCode_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkDxeDebugLibReportStatusCode*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.mbd b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.mbd
new file mode 100644
index 0000000..bc500a0
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkDxePeCoffLoaderFromHobLib</BaseName>

+    <Guid>ed3de5c8-c389-44f2-a35e-2ebdc9802a49</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-22 15:50</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.msa b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.msa
new file mode 100644
index 0000000..aa996f8
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.msa
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkDxePeCoffLoaderFromHobLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>ed3de5c8-c389-44f2-a35e-2ebdc9802a49</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-22 15:50</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkPeCoffLoaderLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeCoff.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PeiPeCoffLoader</C_Name>

+    </GuidEntry>

+  </Guids>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/PeCoff.c b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/PeCoff.c
new file mode 100644
index 0000000..7afe9c2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/PeCoff.c
@@ -0,0 +1,38 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Decompress.c

+

+Abstract:

+  

+--*/

+

+

+

+

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL *

+EFIAPI

+GetPeCoffLoaderProtocol (

+  )

+{

+  EFI_HOB_GUID_TYPE        *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gEfiPeiPeCoffLoaderGuid);

+  if (GuidHob == NULL) {

+    return NULL;

+  } else {

+    return (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));

+  }

+}

+

diff --git a/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/build.xml b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/build.xml
new file mode 100644
index 0000000..ad5f9c9
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePeCoffLoaderFromHobLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkDxePeCoffLoaderFromHobLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkDxePeCoffLoaderFromHobLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkDxePeCoffLoaderFromHobLib">

+      <GenBuild baseName="EdkDxePeCoffLoaderFromHobLib" mbdFilename="${MODULE_DIR}/EdkDxePeCoffLoaderFromHobLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePeCoffLoaderFromHobLib.msa"/>

+   </target>

+   <target depends="EdkDxePeCoffLoaderFromHobLib_clean" name="clean"/>

+   <target depends="EdkDxePeCoffLoaderFromHobLib_cleanall" name="cleanall"/>

+   <target name="EdkDxePeCoffLoaderFromHobLib_clean">

+      <OutputDirSetup baseName="EdkDxePeCoffLoaderFromHobLib" mbdFilename="${MODULE_DIR}/EdkDxePeCoffLoaderFromHobLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePeCoffLoaderFromHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxePeCoffLoaderFromHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxePeCoffLoaderFromHobLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkDxePeCoffLoaderFromHobLib_cleanall">

+      <OutputDirSetup baseName="EdkDxePeCoffLoaderFromHobLib" mbdFilename="${MODULE_DIR}/EdkDxePeCoffLoaderFromHobLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePeCoffLoaderFromHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxePeCoffLoaderFromHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxePeCoffLoaderFromHobLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkDxePeCoffLoaderFromHobLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/DxePerformanceLib.c b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/DxePerformanceLib.c
new file mode 100644
index 0000000..5e448c6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/DxePerformanceLib.c
@@ -0,0 +1,213 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DxePerformanceLib.c

+

+Abstract:

+

+  Performance Library

+

+--*/

+

+STATIC PERFORMANCE_PROTOCOL    *mPerformance = NULL;

+

+/**

+  The constructor function caches the pointer to Performance protocol.

+  

+  The constructor function locates Performance protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PerformanceLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS            Status;

+

+  Status = gBS->LocateProtocol (&gPerformanceProtocolGuid, NULL, (VOID **) &mPerformance);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mPerformance != NULL);

+

+  return Status;

+}

+

+/**

+  Creates a record for the beginning of a performance measurement. 

+  

+  Creates a record that contains the Handle, Token, and Module.

+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.

+  If TimeStamp is zero, then this function reads the current time stamp

+  and adds that time stamp value to the record as the start time.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  EFI_STATUS  Status;

+  

+  Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);

+

+  return (RETURN_STATUS) Status;

+}

+

+/**

+  Fills in the end time of a performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then TimeStamp is added to the record as the end time.

+  If the record is found and TimeStamp is zero, then this function reads

+  the current time stamp and adds that time stamp value to the record as the end time.

+  If this function is called multiple times for the same record, then the end time is overwritten.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.

+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);

+

+  return (RETURN_STATUS) Status;

+}

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found then the start of the measurement is returned in StartTimeStamp,

+  and the end of the measurement is returned in EndTimeStamp.

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  StartTimeStamp          The 64-bit time stamp that was recorded when the measurement was started.

+  @param  EndTimeStamp            The 64-bit time stamp that was recorded when the measurement was ended.

+

+  @return The key for the current performance log entry.

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurement (

+  UINTN           LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp

+  )

+{

+  EFI_STATUS        Status;

+  GAUGE_DATA_ENTRY  *GaugeData;

+

+  ASSERT (Handle != NULL);

+  ASSERT (Token != NULL);

+  ASSERT (Module != NULL);

+  ASSERT (StartTimeStamp != NULL);

+  ASSERT (EndTimeStamp != NULL);

+

+  Status = mPerformance->GetGauge (LogEntryKey++, &GaugeData);

+  

+  //

+  // Make sure that LogEntryKey is a valid log entry key,

+  //

+  ASSERT (Status != EFI_INVALID_PARAMETER);

+

+  if (EFI_ERROR (Status)) {

+    //

+    // The LogEntryKey is the last entry (equals to the total entry number).

+    //

+    return 0;

+  }

+

+  ASSERT (GaugeData != NULL);

+

+  *Handle         = (VOID *) (UINTN) GaugeData->Handle;

+  *Token          = GaugeData->Token;

+  *Module         = GaugeData->Module;

+  *StartTimeStamp = GaugeData->StartTimeStamp;

+  *EndTimeStamp   = GaugeData->EndTimeStamp;

+

+  return LogEntryKey;  

+}

+

+/**

+  Returns TRUE if the performance measurement macros are enabled. 

+  

+  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is set.

+  @retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PerformanceMeasurementEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/EdkDxePerformanceLib.mbd b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/EdkDxePerformanceLib.mbd
new file mode 100644
index 0000000..7bd0e10
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/EdkDxePerformanceLib.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkDxePerformanceLib</BaseName>

+    <Guid>8B8B4CCC-65FC-41a5-8067-308B8E42CCF2</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:11</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/EdkDxePerformanceLib.msa b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/EdkDxePerformanceLib.msa
new file mode 100644
index 0000000..5fe5bd6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/EdkDxePerformanceLib.msa
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkDxePerformanceLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>8B8B4CCC-65FC-41a5-8067-308B8E42CCF2</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:11</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TimerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxePerformanceLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Performance</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>PerformanceLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/build.xml b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/build.xml
new file mode 100644
index 0000000..3165132
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePerformanceLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkDxePerformanceLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkDxePerformanceLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkDxePerformanceLib">

+      <GenBuild baseName="EdkDxePerformanceLib" mbdFilename="${MODULE_DIR}/EdkDxePerformanceLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePerformanceLib.msa"/>

+   </target>

+   <target depends="EdkDxePerformanceLib_clean" name="clean"/>

+   <target depends="EdkDxePerformanceLib_cleanall" name="cleanall"/>

+   <target name="EdkDxePerformanceLib_clean">

+      <OutputDirSetup baseName="EdkDxePerformanceLib" mbdFilename="${MODULE_DIR}/EdkDxePerformanceLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePerformanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxePerformanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxePerformanceLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkDxePerformanceLib_cleanall">

+      <OutputDirSetup baseName="EdkDxePerformanceLib" mbdFilename="${MODULE_DIR}/EdkDxePerformanceLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePerformanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxePerformanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxePerformanceLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkDxePerformanceLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.mbd b/edk2/EdkModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.mbd
new file mode 100644
index 0000000..ca9912b
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkDxePrintLib</BaseName>

+    <Guid>50bcb105-6634-441d-b403-659110a03ad2</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.msa b/edk2/EdkModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.msa
new file mode 100644
index 0000000..f91a6c4
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.msa
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkDxePrintLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>50bcb105-6634-441d-b403-659110a03ad2</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PrintLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Print</Protocol>

+  </Protocols>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkDxePrintLib/PrintLib.c b/edk2/EdkModulePkg/Library/EdkDxePrintLib/PrintLib.c
new file mode 100644
index 0000000..30c0354
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePrintLib/PrintLib.c
@@ -0,0 +1,145 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PrintLib.c

+

+Abstract:

+

+  Print Library

+

+--*/

+

+

+

+static EFI_PRINT_PROTOCOL  *gPrintProtocol = NULL;

+

+UINTN

+UnicodeVSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  const CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  )

+/*++

+

+Routine Description:

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+Arguments:

+

+  StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.

+

+  BufferSize    - Maximum number of characters to put into buffer. Zero means 

+                  no limit.

+

+  FormatString  - Unicode format string see file header for more details.

+

+  Marker        - Vararg list consumed by processing Format.

+

+Returns: 

+

+  Number of characters printed.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  if (gPrintProtocol == NULL) {

+    Status = gBS->LocateProtocol (

+                    &gEfiPrintProtocolGuid,

+                    NULL,

+                    (VOID **)&gPrintProtocol

+                    );

+    if (EFI_ERROR (Status)) {

+      gPrintProtocol = NULL;

+    } 

+    if (gPrintProtocol == NULL) {

+      return 0;

+    }

+  }

+  return gPrintProtocol->VSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+UINTN

+UnicodeSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  const CHAR16  *FormatString,

+  ...

+  )

+

+{

+  UINTN    Return;

+  VA_LIST  Marker;

+

+  VA_START (Marker, FormatString);

+  Return = UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+  VA_END (Marker);

+  return Return;

+}

+

+UINTN

+AsciiVSPrint (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  const CHAR8   *FormatString,

+  IN  VA_LIST       Marker

+  )

+/*++

+

+Routine Description:

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+Arguments:

+

+  StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.

+

+  BufferSize    - Maximum number of characters to put into buffer. Zero means 

+                  no limit.

+

+  FormatString  - Unicode format string see file header for more details.

+

+  Marker        - Vararg list consumed by processing Format.

+

+Returns: 

+

+  Number of characters printed.

+

+--*/

+{

+  return 0;

+}

+

+UINTN

+AsciiSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  const CHAR8  *FormatString,

+  ...

+  )

+

+{

+  UINTN    Return;

+  VA_LIST  Marker;

+

+  VA_START (Marker, FormatString);

+  Return = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+  VA_END (Marker);

+  return Return;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkDxePrintLib/build.xml b/edk2/EdkModulePkg/Library/EdkDxePrintLib/build.xml
new file mode 100644
index 0000000..e9ae5b6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxePrintLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkDxePrintLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkDxePrintLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkDxePrintLib">

+      <GenBuild baseName="EdkDxePrintLib" mbdFilename="${MODULE_DIR}/EdkDxePrintLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePrintLib.msa"/>

+   </target>

+   <target depends="EdkDxePrintLib_clean" name="clean"/>

+   <target depends="EdkDxePrintLib_cleanall" name="cleanall"/>

+   <target name="EdkDxePrintLib_clean">

+      <OutputDirSetup baseName="EdkDxePrintLib" mbdFilename="${MODULE_DIR}/EdkDxePrintLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePrintLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxePrintLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxePrintLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkDxePrintLib_cleanall">

+      <OutputDirSetup baseName="EdkDxePrintLib" mbdFilename="${MODULE_DIR}/EdkDxePrintLib.mbd" msaFilename="${MODULE_DIR}/EdkDxePrintLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxePrintLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxePrintLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkDxePrintLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Common/RuntimeLib.c b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Common/RuntimeLib.c
new file mode 100644
index 0000000..adddf93
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Common/RuntimeLib.c
@@ -0,0 +1,258 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    RuntimeLib.c

+

+Abstract:

+

+  Light weight lib to support Tiano drivers.

+

+--*/

+

+#include <RuntimeLibInternal.h>

+

+//

+// Driver Lib Module Globals

+//

+STATIC EFI_EVENT            mRuntimeNotifyEvent;

+STATIC EFI_EVENT            mEfiVirtualNotifyEvent;

+STATIC BOOLEAN              mEfiGoneVirtual         = FALSE;

+STATIC BOOLEAN              mEfiAtRuntime           = FALSE;

+

+EFI_RUNTIME_SERVICES        *mRT                    = NULL;

+

+VOID

+EFIAPI

+RuntimeDriverExitBootServices (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Set AtRuntime flag as TRUE after ExitBootServices

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns: 

+

+  None

+

+--*/

+{

+  EFI_EVENT_NOTIFY  ChildNotifyEventHandler;

+  UINTN             Index;

+

+  for (Index = 0; 

+       _gDriverExitBootServicesEvent[Index] != NULL;

+       Index++) {

+    ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index];

+    ChildNotifyEventHandler (Event, NULL);

+  }

+

+  mEfiAtRuntime = TRUE;

+}

+

+STATIC

+VOID

+EFIAPI

+RuntimeLibVirtualNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Fixup internal data so that EFI can be call in virtual mode.

+  Call the passed in Child Notify event and convert any pointers in 

+  lib to virtual mode.

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns: 

+

+  None

+

+--*/

+{

+  UINTN Index;

+  EFI_EVENT_NOTIFY  ChildNotifyEventHandler;

+

+  for (Index = 0; 

+       _gDriverSetVirtualAddressMapEvent[Index] != NULL;

+       Index++) {

+    ChildNotifyEventHandler = _gDriverSetVirtualAddressMapEvent[Index];

+    ChildNotifyEventHandler (Event, NULL);

+  }

+

+  //

+  // Update global for Runtime Services Table and IO

+  //

+  EfiConvertInternalPointer ((VOID **) &mRT);

+

+  //

+  // Clear out BootService globals

+  //

+  gBS             = NULL;

+  gST             = NULL;

+  mEfiGoneVirtual = TRUE;

+}

+

+EFI_STATUS

+RuntimeDriverLibConstruct (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Intialize runtime Driver Lib if it has not yet been initialized. 

+

+Arguments:

+

+  ImageHandle     - The firmware allocated handle for the EFI image.

+  

+  SystemTable     - A pointer to the EFI System Table.

+

+  GoVirtualChildEvent - Caller can register a virtual notification event.

+

+Returns: 

+

+  EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  mRT = SystemTable->RuntimeServices;

+

+  //

+  // Register our ExitBootServices () notify function

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,

+                  EFI_TPL_NOTIFY,

+                  RuntimeDriverExitBootServices,

+                  NULL,

+                  &mRuntimeNotifyEvent

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  // 

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,

+                  EFI_TPL_NOTIFY,

+                  RuntimeLibVirtualNotifyEvent,

+                  NULL,

+                  &mEfiVirtualNotifyEvent

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RuntimeDriverLibDeconstruct (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This routine will free some resources which have been allocated in

+  EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error, 

+  it must call this routine to free the allocated resource before the exiting.

+

+Arguments:

+

+  None

+

+Returns: 

+

+  EFI_SUCCESS     - Shotdown the Runtime Driver Lib successfully

+  EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Close our ExitBootServices () notify function

+  //

+  Status = gBS->CloseEvent (mRuntimeNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Close SetVirtualAddressMap () notify function

+  //

+  Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+EfiAtRuntime (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if ExitBootServices () has been called

+

+Arguments:

+  NONE

+

+Returns: 

+  TRUE - If ExitBootServices () has been called

+

+--*/

+{

+  return mEfiAtRuntime;

+}

+

+BOOLEAN

+EfiGoneVirtual (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if SetVirtualAddressMap () has been called

+

+Arguments:

+  NONE

+

+Returns: 

+  TRUE - If SetVirtualAddressMap () has been called

+

+--*/

+{

+  return mEfiGoneVirtual;

+}

+

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Common/RuntimeService.c b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Common/RuntimeService.c
new file mode 100644
index 0000000..971dcdb
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Common/RuntimeService.c
@@ -0,0 +1,480 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    RuntimeService.c

+

+Abstract:

+

+  Light weight lib to support Tiano drivers.

+

+--*/

+

+#include <RuntimeLibInternal.h>

+

+VOID

+EfiResetSystem (

+  IN EFI_RESET_TYPE               ResetType,

+  IN EFI_STATUS                   ResetStatus,

+  IN UINTN                        DataSize,

+  IN CHAR16                       *ResetData

+  )

+/*++

+

+Routine Description:

+

+  Resets the entire platform.

+

+Arguments:

+

+  ResetType   - The type of reset to perform.

+  ResetStatus - The status code for the reset.

+  DataSize    - The size, in bytes, of ResetData.

+  ResetData   - A data buffer that includes a Null-terminated Unicode string, optionally

+                followed by additional binary data.

+

+Returns:

+

+  None

+

+--*/

+{

+  mRT->ResetSystem (ResetType, ResetStatus, DataSize, ResetData);

+}

+

+//

+// The following functions hide the mRT local global from the call to

+// runtime service in the EFI system table.

+//

+EFI_STATUS

+EfiGetTime (

+  OUT EFI_TIME                    *Time,

+  OUT EFI_TIME_CAPABILITIES       *Capabilities

+  )

+/*++

+

+Routine Description:

+

+  Returns the current time and date information, and the time-keeping 

+  capabilities of the hardware platform.

+

+Arguments:

+

+  Time          - A pointer to storage to receive a snapshot of the current time.

+  Capabilities  - An optional pointer to a buffer to receive the real time clock device¡¯s

+                  capabilities.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->GetTime (Time, Capabilities);

+}

+

+EFI_STATUS

+EfiSetTime (

+  IN EFI_TIME                   *Time

+  )

+/*++

+

+Routine Description:

+

+  Sets the current local time and date information.

+

+Arguments:

+

+  Time  - A pointer to the current time.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->SetTime (Time);

+}

+

+EFI_STATUS

+EfiGetWakeupTime (

+  OUT BOOLEAN                     *Enabled,

+  OUT BOOLEAN                     *Pending,

+  OUT EFI_TIME                    *Time

+  )

+/*++

+

+Routine Description:

+

+  Returns the current wakeup alarm clock setting.

+

+Arguments:

+

+  Enabled - Indicates if the alarm is currently enabled or disabled.

+  Pending - Indicates if the alarm signal is pending and requires acknowledgement.

+  Time    - The current alarm setting.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->GetWakeupTime (Enabled, Pending, Time);

+}

+

+EFI_STATUS

+EfiSetWakeupTime (

+  IN BOOLEAN                      Enable,

+  IN EFI_TIME                     *Time

+  )

+/*++

+

+Routine Description:

+

+  Sets the system wakeup alarm clock time.

+

+Arguments:

+

+  Enable  - Enable or disable the wakeup alarm.

+  Time    - If Enable is TRUE, the time to set the wakeup alarm for.

+            If Enable is FALSE, then this parameter is optional, and may be NULL.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->SetWakeupTime (Enable, Time);

+}

+

+

+

+

+EFI_STATUS

+EfiGetVariable (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     * VendorGuid,

+  OUT UINT32                      *Attributes OPTIONAL,

+  IN OUT UINTN                    *DataSize,

+  OUT VOID                        *Data

+  )

+/*++

+

+Routine Description:

+

+  Returns the value of a variable.

+

+Arguments:

+

+  VariableName  - A Null-terminated Unicode string that is the name of the

+                  vendor¡¯s variable.

+  VendorGuid    - A unique identifier for the vendor.

+  Attributes    - If not NULL, a pointer to the memory location to return the

+                  attributes bitmask for the variable.

+  DataSize      - On input, the size in bytes of the return Data buffer.

+                  On output the size of data returned in Data.

+  Data          - The buffer to return the contents of the variable.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);

+}

+

+EFI_STATUS

+EfiGetNextVariableName (

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  )

+/*++

+

+Routine Description:

+

+  Enumerates the current variable names.

+

+Arguments:

+

+  VariableNameSize  - The size of the VariableName buffer.

+  VariableName      - On input, supplies the last VariableName that was returned

+                      by GetNextVariableName(). 

+                      On output, returns the Nullterminated Unicode string of the

+                      current variable.

+  VendorGuid        - On input, supplies the last VendorGuid that was returned by

+                      GetNextVariableName(). 

+                      On output, returns the VendorGuid of the current variable.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->GetNextVariableName (VariableNameSize, VariableName, VendorGuid);

+}

+

+EFI_STATUS

+EfiSetVariable (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  IN UINT32                       Attributes,

+  IN UINTN                        DataSize,

+  IN VOID                         *Data

+  )

+/*++

+

+Routine Description:

+

+  Sets the value of a variable.

+

+Arguments:

+

+  VariableName  - A Null-terminated Unicode string that is the name of the

+                  vendor¡¯s variable.

+  VendorGuid    - A unique identifier for the vendor.

+  Attributes    - Attributes bitmask to set for the variable.

+  DataSize      - The size in bytes of the Data buffer.

+  Data          - The contents for the variable.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->SetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);

+}

+

+EFI_STATUS

+EfiGetNextHighMonotonicCount (

+  OUT UINT32                      *HighCount

+  )

+/*++

+

+Routine Description:

+

+  Returns the next high 32 bits of the platform¡¯s monotonic counter.

+

+Arguments:

+

+  HighCount - Pointer to returned value.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->GetNextHighMonotonicCount (HighCount);

+}

+

+EFI_STATUS

+EfiConvertPointer (

+  IN UINTN                  DebugDisposition,

+  IN OUT VOID               *Address

+  )

+/*++

+

+Routine Description:

+

+  Determines the new virtual address that is to be used on subsequent memory accesses.

+

+Arguments:

+

+  DebugDisposition  - Supplies type information for the pointer being converted.

+  Address           - A pointer to a pointer that is to be fixed to be the value needed

+                      for the new virtual address mappings being applied.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->ConvertPointer (DebugDisposition, Address);

+}

+

+EFI_STATUS

+EfiConvertInternalPointer (

+  IN OUT VOID                  *Address

+  )

+/*++

+

+Routine Description:

+

+  Call EfiConvertPointer() to convert internal pointer.

+

+Arguments:

+

+  Address - A pointer to a pointer that is to be fixed to be the value needed

+            for the new virtual address mappings being applied.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return EfiConvertPointer (0x0, Address);

+}

+

+EFI_STATUS

+EfiConvertList (

+  IN UINTN                DebugDisposition,

+  IN OUT LIST_ENTRY       *ListHead

+  )

+/*++

+

+Routine Description:

+

+  Conver the standard Lib double linked list to a virtual mapping.

+

+Arguments:

+

+  DebugDisposition - Argument to EfiConvertPointer (EFI 1.0 API)

+

+  ListHead         - Head of linked list to convert

+

+Returns: 

+

+  EFI_SUCCESS

+

+--*/

+{

+  LIST_ENTRY  *Link;

+  LIST_ENTRY  *NextLink;

+

+  //

+  // Convert all the ForwardLink & BackLink pointers in the list

+  //

+  Link = ListHead;

+  do {

+    NextLink = Link->ForwardLink;

+

+    EfiConvertPointer (

+      Link->ForwardLink == ListHead ? DebugDisposition : 0,

+      (VOID **) &Link->ForwardLink

+      );

+

+    EfiConvertPointer (

+      Link->BackLink == ListHead ? DebugDisposition : 0,

+      (VOID **) &Link->BackLink

+      );

+

+    Link = NextLink;

+  } while (Link != ListHead);

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Change the runtime addressing mode of EFI firmware from physical to virtual.

+

+  @param  MemoryMapSize         The size in bytes of VirtualMap.

+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.

+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.

+  @param  VirtualMap            An array of memory descriptors which contain new virtual

+                                address mapping information for all runtime ranges. Type

+                                EFI_MEMORY_DESCRIPTOR is defined in the

+                                GetMemoryMap() function description.

+

+  @retval EFI_SUCCESS           The virtual address map has been applied.

+  @retval EFI_UNSUPPORTED       EFI firmware is not at runtime, or the EFI firmware is already in

+                                virtual address mapped mode.

+  @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is

+                                invalid.

+  @retval EFI_NO_MAPPING        A virtual address was not supplied for a range in the memory

+                                map that requires a mapping.

+  @retval EFI_NOT_FOUND         A virtual address was supplied for an address that is not found

+                                in the memory map.

+**/

+EFI_STATUS

+EFIAPI

+EfiSetVirtualAddressMap (

+  IN UINTN                          MemoryMapSize,

+  IN UINTN                          DescriptorSize,

+  IN UINT32                         DescriptorVersion,

+  IN CONST EFI_MEMORY_DESCRIPTOR    *VirtualMap

+  )

+{

+  return mRT->SetVirtualAddressMap (

+                MemoryMapSize,

+                DescriptorSize,

+                DescriptorVersion,

+                (EFI_MEMORY_DESCRIPTOR *) VirtualMap

+                );

+}

+

+

+EFI_STATUS

+EfiUpdateCapsule (

+  IN UEFI_CAPSULE_HEADER	**CapsuleHeaderArray,

+  IN UINTN				    CapsuleCount,

+  IN EFI_PHYSICAL_ADDRESS	ScatterGatherList	OPTIONAL

+  )

+{

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+  return mRT->UpdateCapsule (

+                CapsuleHeaderArray,

+                CapsuleCount,

+                ScatterGatherList

+                );

+#else

+  return EFI_UNSUPPORTED;

+#endif

+}

+

+EFI_STATUS

+EfiQueryCapsuleCapabilities (

+  IN UEFI_CAPSULE_HEADER	**CapsuleHeaderArray,

+  IN UINTN				    CapsuleCount,

+  OUT	UINT64			    *MaximumCapsuleSize,

+  OUT EFI_RESET_TYPE		*ResetType

+  )

+{

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+  return mRT->QueryCapsuleCapabilities (

+          CapsuleHeaderArray,

+          CapsuleCount,

+          MaximumCapsuleSize,

+          ResetType

+          );

+#else

+  return EFI_UNSUPPORTED;

+#endif

+}

+

+

+EFI_STATUS

+EfiQueryVariableInfo (

+  IN UINT32			  Attributes,

+  OUT UINT64			*MaximumVariableStorageSize,

+  OUT	 UINT64			*RemainingVariableStorageSize,

+  OUT UINT64			*MaximumVariableSize

+  )

+{

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+  return mRT->QueryVariableInfo (

+          Attributes,

+          MaximumVariableStorageSize,

+          RemainingVariableStorageSize,

+          MaximumVariableSize

+          );

+#else 

+  return EFI_UNSUPPORTED;

+#endif

+}

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.mbd b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.mbd
new file mode 100644
index 0000000..72edffb
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkDxeRuntimeDriverLib</BaseName>

+    <Guid>b1ee6c28-54aa-4d17-b705-3e28ccb27b2e</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:13</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.msa b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.msa
new file mode 100644
index 0000000..2c60697
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/EdkDxeRuntimeDriverLib.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkDxeRuntimeDriverLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>b1ee6c28-54aa-4d17-b705-3e28ccb27b2e</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:13</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>Common/RuntimeLib.c</Filename>

+      <Filename>Common/RuntimeService.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>Common/RuntimeLib.c</Filename>

+      <Filename>Common/RuntimeService.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/RuntimeLib.c</Filename>

+      <Filename>Ipf/RuntimeService.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>RuntimeDriverLibConstruct</Constructor>

+      <Destructor>RuntimeDriverLibDeconstruct</Destructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Ipf/RuntimeLib.c b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Ipf/RuntimeLib.c
new file mode 100644
index 0000000..a4eeb33
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Ipf/RuntimeLib.c
@@ -0,0 +1,284 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    RuntimeLib.c

+

+Abstract:

+

+  Light weight lib to support Tiano drivers.

+

+--*/

+

+#include <SalApi.h>

+#include <RuntimeLibInternal.h>

+

+//

+// Driver Lib Module Globals

+//

+

+STATIC EFI_EVENT            mRuntimeNotifyEvent;

+STATIC EFI_EVENT            mEfiVirtualNotifyEvent;

+

+STATIC EFI_PLABEL           mPlabel;

+STATIC EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;

+

+EFI_RUNTIME_SERVICES        *mRT                    = NULL;

+

+STATIC

+VOID

+EFIAPI

+RuntimeDriverExitBootServices (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Set AtRuntime flag as TRUE after ExitBootServices

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns: 

+

+  None

+

+--*/

+{

+  EFI_EVENT_NOTIFY  ChildNotifyEventHandler;

+  UINTN             Index;

+

+  for (Index = 0; _gDriverExitBootServicesEvent[Index] != NULL; Index++) {

+    ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index];

+    ChildNotifyEventHandler (Event, NULL);

+  }

+}

+

+STATIC

+VOID

+EFIAPI

+RuntimeLibVirtualNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Fixup internal data so that EFI can be call in virtual mode.

+  Call the passed in Child Notify event and convert any pointers in 

+  lib to virtual mode.

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns: 

+

+  None

+

+--*/

+{

+  UINTN Index;

+  EFI_EVENT_NOTIFY  ChildNotifyEventHandler;

+

+  for (Index = 0; _gDriverSetVirtualAddressMapEvent[Index] != NULL; Index++) {

+    ChildNotifyEventHandler = _gDriverSetVirtualAddressMapEvent[Index];

+    ChildNotifyEventHandler (Event, NULL);

+  }

+

+  mRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);

+  mRT->ConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);

+

+  SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);

+

+  //

+  // Clear out BootService globals

+  //

+  gBS             = NULL;

+  gST             = NULL;

+  mRT             = NULL;

+}

+

+EFI_STATUS

+RuntimeDriverLibConstruct (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Intialize runtime Driver Lib if it has not yet been initialized. 

+

+Arguments:

+

+  ImageHandle     - The firmware allocated handle for the EFI image.

+  

+  SystemTable     - A pointer to the EFI System Table.

+

+  GoVirtualChildEvent - Caller can register a virtual notification event.

+

+Returns: 

+

+  EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.

+

+--*/

+{

+  EFI_PLABEL  *Plabel;

+  EFI_STATUS  Status;

+

+  mRT = SystemTable->RuntimeServices;

+

+  //

+  // The protocol contains a function pointer, which is an indirect procedure call.

+  // An indirect procedure call goes through a plabel, and pointer to a function is

+  // a pointer to a plabel. To implement indirect procedure calls that can work in

+  // both physical and virtual mode, two plabels are required (one physical and one

+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it

+  // away. We cache it in a module global, so we can register the vitrual version.

+  //

+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);

+  ASSERT_EFI_ERROR (Status);

+

+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;

+

+  mPlabel.EntryPoint  = Plabel->EntryPoint;

+  mPlabel.GP          = Plabel->GP;

+

+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);

+

+  //

+  // Register our ExitBootServices () notify function

+  //

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,

+                  EFI_TPL_NOTIFY,

+                  RuntimeDriverExitBootServices,

+                  NULL,

+                  &mRuntimeNotifyEvent

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+  

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,

+                  EFI_TPL_NOTIFY,

+                  RuntimeLibVirtualNotifyEvent,

+                  NULL,

+                  mEfiVirtualNotifyEvent

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RuntimeDriverLibDeconstruct (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This routine will free some resources which have been allocated in

+  EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error, 

+  it must call this routine to free the allocated resource before the exiting.

+

+Arguments:

+

+  None

+

+Returns: 

+

+  EFI_SUCCESS     - Shotdown the Runtime Driver Lib successfully

+  EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Close our ExitBootServices () notify function

+  //

+  Status = gBS->CloseEvent (mRuntimeNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Close SetVirtualAddressMap () notify function

+  //

+  Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+EfiAtRuntime (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if ExitBootService () has been called

+

+Arguments:

+  NONE

+

+Returns: 

+  TRUE - If ExitBootService () has been called

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;

+  SAL_RETURN_REGS ReturnReg;

+

+  ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);

+

+  return (BOOLEAN) (ReturnReg.r9 == 1);

+}

+

+BOOLEAN

+EfiGoneVirtual (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if SetVirtualAddressMap () has been called

+

+Arguments:

+  NONE

+

+Returns: 

+  TRUE - If SetVirtualAddressMap () has been called

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;

+  SAL_RETURN_REGS ReturnReg;

+

+  ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);

+

+  return (BOOLEAN) (ReturnReg.r9 == 1);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Ipf/RuntimeService.c b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Ipf/RuntimeService.c
new file mode 100644
index 0000000..bc7a318
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/Ipf/RuntimeService.c
@@ -0,0 +1,516 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    RuntimeService.c

+

+Abstract:

+

+  Light weight lib to support Tiano drivers.

+

+--*/

+

+#include <RuntimeLibInternal.h>

+

+VOID

+EfiResetSystem (

+  IN EFI_RESET_TYPE               ResetType,

+  IN EFI_STATUS                   ResetStatus,

+  IN UINTN                        DataSize,

+  IN CHAR16                       *ResetData

+  )

+/*++

+

+Routine Description:

+

+  Resets the entire platform.

+

+Arguments:

+

+  ResetType   - The type of reset to perform.

+  ResetStatus - The status code for the reset.

+  DataSize    - The size, in bytes, of ResetData.

+  ResetData   - A data buffer that includes a Null-terminated Unicode string, optionally

+                followed by additional binary data.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID;

+

+  EfiCallEsalService (

+    &Guid,

+    ResetSystem,

+    (UINT64) ResetType,

+    (UINT64) ResetStatus,

+    (UINT64) DataSize,

+    (UINT64) ResetData,

+    0,

+    0,

+    0

+    );

+}

+

+

+//

+// The following functions hide the mRT local global from the call to

+// runtime service in the EFI system table.

+//

+EFI_STATUS

+EfiGetTime (

+  OUT EFI_TIME                    *Time,

+  OUT EFI_TIME_CAPABILITIES       *Capabilities

+  )

+/*++

+

+Routine Description:

+

+  Returns the current time and date information, and the time-keeping 

+  capabilities of the hardware platform.

+

+Arguments:

+

+  Time          - A pointer to storage to receive a snapshot of the current time.

+  Capabilities  - An optional pointer to a buffer to receive the real time clock device¡¯s

+                  capabilities.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+  EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (&Guid, GetTime, (UINT64) Time, (UINT64) Capabilities, 0, 0, 0, 0, 0);

+  return ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiSetTime (

+  IN EFI_TIME                   *Time

+  )

+/*++

+

+Routine Description:

+

+  Sets the current local time and date information.

+

+Arguments:

+

+  Time  - A pointer to the current time.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+

+  EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (&Guid, SetTime, (UINT64) Time, 0, 0, 0, 0, 0, 0);

+  return ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiGetWakeupTime (

+  OUT BOOLEAN                     *Enabled,

+  OUT BOOLEAN                     *Pending,

+  OUT EFI_TIME                    *Time

+  )

+/*++

+

+Routine Description:

+

+  Returns the current wakeup alarm clock setting.

+

+Arguments:

+

+  Enabled - Indicates if the alarm is currently enabled or disabled.

+  Pending - Indicates if the alarm signal is pending and requires acknowledgement.

+  Time    - The current alarm setting.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+

+  EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (&Guid, GetWakeupTime, (UINT64) Enabled, (UINT64) Pending, (UINT64) Time, 0, 0, 0, 0);

+  return ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiSetWakeupTime (

+  IN BOOLEAN                      Enable,

+  IN EFI_TIME                     *Time

+  )

+/*++

+

+Routine Description:

+

+  Sets the system wakeup alarm clock time.

+

+Arguments:

+

+  Enable  - Enable or disable the wakeup alarm.

+  Time    - If Enable is TRUE, the time to set the wakeup alarm for.

+            If Enable is FALSE, then this parameter is optional, and may be NULL.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+

+  EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (&Guid, SetWakeupTime, (UINT64) Enable, (UINT64) Time, 0, 0, 0, 0, 0);

+  return ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiGetVariable (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     * VendorGuid,

+  OUT UINT32                      *Attributes OPTIONAL,

+  IN OUT UINTN                    *DataSize,

+  OUT VOID                        *Data

+  )

+/*++

+

+Routine Description:

+

+  Returns the value of a variable.

+

+Arguments:

+

+  VariableName  - A Null-terminated Unicode string that is the name of the

+                  vendor¡¯s variable.

+  VendorGuid    - A unique identifier for the vendor.

+  Attributes    - If not NULL, a pointer to the memory location to return the

+                  attributes bitmask for the variable.

+  DataSize      - On input, the size in bytes of the return Data buffer.

+                  On output the size of data returned in Data.

+  Data          - The buffer to return the contents of the variable.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+  EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (

+                &Guid,

+                EsalGetVariable,

+                (UINT64) VariableName,

+                (UINT64) VendorGuid,

+                (UINT64) Attributes,

+                (UINT64) DataSize,

+                (UINT64) Data,

+                0,

+                0

+                );

+  return (EFI_STATUS) ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiGetNextVariableName (

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  )

+/*++

+

+Routine Description:

+

+  Enumerates the current variable names.

+

+Arguments:

+

+  VariableNameSize  - The size of the VariableName buffer.

+  VariableName      - On input, supplies the last VariableName that was returned

+                      by GetNextVariableName(). 

+                      On output, returns the Nullterminated Unicode string of the

+                      current variable.

+  VendorGuid        - On input, supplies the last VendorGuid that was returned by

+                      GetNextVariableName(). 

+                      On output, returns the VendorGuid of the current variable.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+  EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (

+                &Guid,

+                EsalGetNextVariableName,

+                (UINT64) VariableNameSize,

+                (UINT64) VariableName,

+                (UINT64) VendorGuid,

+                0,

+                0,

+                0,

+                0

+                );

+  return (EFI_STATUS) ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiSetVariable (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  IN UINT32                       Attributes,

+  IN UINTN                        DataSize,

+  IN VOID                         *Data

+  )

+/*++

+

+Routine Description:

+

+  Sets the value of a variable.

+

+Arguments:

+

+  VariableName  - A Null-terminated Unicode string that is the name of the

+                  vendor¡¯s variable.

+  VendorGuid    - A unique identifier for the vendor.

+  Attributes    - Attributes bitmask to set for the variable.

+  DataSize      - The size in bytes of the Data buffer.

+  Data          - The contents for the variable.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+  EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (

+                &Guid,

+                EsalSetVariable,

+                (UINT64) VariableName,

+                (UINT64) VendorGuid,

+                (UINT64) Attributes,

+                (UINT64) DataSize,

+                (UINT64) Data,

+                0,

+                0

+                );

+  return (EFI_STATUS) ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiGetNextHighMonotonicCount (

+  OUT UINT32                      *HighCount

+  )

+/*++

+

+Routine Description:

+

+  Returns the next high 32 bits of the platform¡¯s monotonic counter.

+

+Arguments:

+

+  HighCount - Pointer to returned value.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  SAL_RETURN_REGS ReturnReg;

+

+  EFI_GUID Guid = EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (&Guid, GetNextHighMonotonicCount, (UINT64) HighCount, 0, 0, 0, 0, 0, 0);

+  return (EFI_STATUS) ReturnReg.Status;

+}

+

+EFI_STATUS

+EfiConvertPointer (

+  IN UINTN                  DebugDisposition,

+  IN OUT VOID               *Address

+  )

+/*++

+

+Routine Description:

+

+  Determines the new virtual address that is to be used on subsequent memory accesses.

+

+Arguments:

+

+  DebugDisposition  - Supplies type information for the pointer being converted.

+  Address           - A pointer to a pointer that is to be fixed to be the value needed

+                      for the new virtual address mappings being applied.

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return mRT->ConvertPointer (DebugDisposition, Address);

+}

+

+EFI_STATUS

+EfiConvertList (

+  IN UINTN                DebugDisposition,

+  IN OUT LIST_ENTRY       *ListHead

+  )

+/*++

+

+Routine Description:

+

+  Conver the standard Lib double linked list to a virtual mapping.

+

+Arguments:

+

+  DebugDisposition - Argument to EfiConvertPointer (EFI 1.0 API)

+

+  ListHead         - Head of linked list to convert

+

+Returns: 

+

+  EFI_SUCCESS

+

+--*/

+{

+  LIST_ENTRY  *Link;

+  LIST_ENTRY  *NextLink;

+

+  //

+  // Convert all the ForwardLink & BackLink pointers in the list

+  //

+  Link = ListHead;

+  do {

+    NextLink = Link->ForwardLink;

+

+    EfiConvertPointer (

+      Link->ForwardLink == ListHead ? DebugDisposition : 0,

+      (VOID **) &Link->ForwardLink

+      );

+

+    EfiConvertPointer (

+      Link->BackLink == ListHead ? DebugDisposition : 0,

+      (VOID **) &Link->BackLink

+      );

+

+    Link = NextLink;

+  } while (Link != ListHead);

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Change the runtime addressing mode of EFI firmware from physical to virtual.

+

+  @param  MemoryMapSize         The size in bytes of VirtualMap.

+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.

+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.

+  @param  VirtualMap            An array of memory descriptors which contain new virtual

+                                address mapping information for all runtime ranges. Type

+                                EFI_MEMORY_DESCRIPTOR is defined in the

+                                GetMemoryMap() function description.

+

+  @retval EFI_SUCCESS           The virtual address map has been applied.

+  @retval EFI_UNSUPPORTED       EFI firmware is not at runtime, or the EFI firmware is already in

+                                virtual address mapped mode.

+  @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is

+                                invalid.

+  @retval EFI_NO_MAPPING        A virtual address was not supplied for a range in the memory

+                                map that requires a mapping.

+  @retval EFI_NOT_FOUND         A virtual address was supplied for an address that is not found

+                                in the memory map.

+**/

+EFI_STATUS

+EFIAPI

+EfiSetVirtualAddressMap (

+  IN UINTN                          MemoryMapSize,

+  IN UINTN                          DescriptorSize,

+  IN UINT32                         DescriptorVersion,

+  IN CONST EFI_MEMORY_DESCRIPTOR    *VirtualMap

+  )

+{

+  SAL_RETURN_REGS ReturnReg;

+  EFI_GUID        Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;

+

+  ReturnReg = EfiCallEsalService (

+                &Guid,

+                SetVirtualAddress,

+                (UINT64) MemoryMapSize,

+                (UINT64) DescriptorSize,

+                (UINT64) DescriptorVersion,

+                (UINT64) VirtualMap,

+                0,

+                0,

+                0

+                );

+

+  return ReturnReg.Status;

+}

+

+

+EFI_STATUS

+EfiUpdateCapsule (

+  IN UEFI_CAPSULE_HEADER	**CapsuleHeaderArray,

+  IN UINTN				    CapsuleCount,

+  IN EFI_PHYSICAL_ADDRESS	ScatterGatherList	OPTIONAL

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+EfiQueryCapsuleCapabilities (

+  IN UEFI_CAPSULE_HEADER	**CapsuleHeaderArray,

+  IN UINTN				    CapsuleCount,

+  OUT	UINT64			    *MaximumCapsuleSize,

+  OUT EFI_RESET_TYPE		*ResetType

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EfiQueryVariableInfo (

+  IN UINT32			  Attributes,

+  OUT UINT64			*MaximumVariableStorageSize,

+  OUT	 UINT64			*RemainingVariableStorageSize,

+  OUT UINT64			*MaximumVariableSize

+  )

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/RuntimeLibInternal.h b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/RuntimeLibInternal.h
new file mode 100644
index 0000000..82494fd
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/RuntimeLibInternal.h
@@ -0,0 +1,30 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  RuntimeLibInternal.h

+

+Abstract:

+

+--*/

+

+#ifndef __RUNTIMELIBINTERNAL_H__

+#define __RUNTIMELIBINTERNAL_H__

+

+EFI_STATUS

+EfiConvertInternalPointer (

+  IN OUT VOID                  *Address

+  );

+

+extern EFI_RUNTIME_SERVICES   *mRT;

+

+#endif //__RUNTIMELIBINTERNAL_H__

diff --git a/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/build.xml b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/build.xml
new file mode 100644
index 0000000..1442612
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeRuntimeDriverLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkDxeRuntimeDriverLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkDxeRuntimeDriverLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkDxeRuntimeDriverLib">

+      <GenBuild baseName="EdkDxeRuntimeDriverLib" mbdFilename="${MODULE_DIR}/EdkDxeRuntimeDriverLib.mbd" msaFilename="${MODULE_DIR}/EdkDxeRuntimeDriverLib.msa"/>

+   </target>

+   <target depends="EdkDxeRuntimeDriverLib_clean" name="clean"/>

+   <target depends="EdkDxeRuntimeDriverLib_cleanall" name="cleanall"/>

+   <target name="EdkDxeRuntimeDriverLib_clean">

+      <OutputDirSetup baseName="EdkDxeRuntimeDriverLib" mbdFilename="${MODULE_DIR}/EdkDxeRuntimeDriverLib.mbd" msaFilename="${MODULE_DIR}/EdkDxeRuntimeDriverLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxeRuntimeDriverLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxeRuntimeDriverLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkDxeRuntimeDriverLib_cleanall">

+      <OutputDirSetup baseName="EdkDxeRuntimeDriverLib" mbdFilename="${MODULE_DIR}/EdkDxeRuntimeDriverLib.mbd" msaFilename="${MODULE_DIR}/EdkDxeRuntimeDriverLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxeRuntimeDriverLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxeRuntimeDriverLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkDxeRuntimeDriverLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.mbd b/edk2/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.mbd
new file mode 100644
index 0000000..dababd2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkDxeSalLib</BaseName>

+    <Guid>61999c3c-72a5-4506-a4ff-4271d18a1d14</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:13</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa b/edk2/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa
new file mode 100644
index 0000000..de00042
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkDxeSalLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>61999c3c-72a5-4506-a4ff-4271d18a1d14</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:13</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkDxeSalLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/EsalServiceLib.c</Filename>

+      <Filename>Ipf/AsmEsalServiceLib.s</Filename>

+      <Filename>Ipf/AsmIpfCpuCache.s</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DxeSalLibConstruct</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/AsmEsalServiceLib.s b/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/AsmEsalServiceLib.s
new file mode 100644
index 0000000..2b040b7
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/AsmEsalServiceLib.s
@@ -0,0 +1,149 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+//  Module Name:

+//

+//    EsalLib.s

+//

+//  Abstract:

+//

+//

+// Revision History:

+//

+//--

+

+.file  "EsalLib.s"

+

+#include  "IpfMacro.i"

+

+//

+// Exports

+//

+.global GetEsalEntryPoint

+

+

+//-----------------------------------------------------------------------------

+//++

+// GetEsalEntryPoint

+//

+// Return Esal global and PSR register.

+//

+// On Entry :

+//

+//

+// Return Value:

+//        r8  = EFI_SAL_SUCCESS

+//        r9  = Physical Plabel

+//        r10 = Virtual Plabel

+//        r11 = psr

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (GetEsalEntryPoint)

+

+      NESTED_SETUP (0,8,0,0)

+

+EsalCalcStart:

+      mov   r8  = ip;;

+      add   r8  = (EsalEntryPoint - EsalCalcStart), r8;;

+      mov   r9  = r8;;

+      add   r10 = 0x10, r8;;

+      mov   r11 = psr;;

+      mov   r8  = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (GetEsalEntryPoint)

+

+

+

+

+

+//-----------------------------------------------------------------------------

+//++

+// SetEsalPhysicalEntryPoint

+//

+// Set the dispatcher entry point

+//

+// On Entry:

+//  in0 = Physical address of Esal Dispatcher

+//  in1 = Physical GP

+//

+// Return Value: 

+//   r8 = EFI_SAL_SUCCESS

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (SetEsalPhysicalEntryPoint)

+

+      NESTED_SETUP (2,8,0,0)

+

+EsalCalcStart1:

+      mov   r8   = ip;;

+      add   r8   = (EsalEntryPoint - EsalCalcStart1), r8;;

+      st8   [r8] = in0;;

+      add   r8   = 0x08, r8;;

+      st8   [r8] = in1;;

+      mov   r8   = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (SetEsalPhysicalEntryPoint)

+

+

+//-----------------------------------------------------------------------------

+//++

+// SetEsalVirtualEntryPoint

+//

+// Register physical address of Esal globals.

+//

+// On Entry :

+//  in0 = Virtual address of Esal Dispatcher

+//  in1 = Virtual GP

+//

+// Return Value: 

+//  r8 = EFI_SAL_ERROR

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (SetEsalVirtualEntryPoint)

+

+      NESTED_SETUP (2,8,0,0)

+

+EsalCalcStart2:

+      mov   r8   = ip;;

+      add   r8   = (EsalEntryPoint - EsalCalcStart2), r8;;

+      add   r8   = 0x10, r8;;

+      st8   [r8] = in0;;

+      add   r8   = 0x08, r8;;

+      st8   [r8] = in1;;

+      mov   r8   = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (SetEsalVirtualEntryPoint)

+

+

+

+

+.align 32

+EsalEntryPoint: 

+    data8 0   // Physical Entry

+    data8 0   //         GP

+    data8 0   // Virtual Entry

+    data8 0   //         GP

+

+

diff --git a/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/AsmIpfCpuCache.s b/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/AsmIpfCpuCache.s
new file mode 100644
index 0000000..c450505
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/AsmIpfCpuCache.s
@@ -0,0 +1,88 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+//  Module Name:

+//

+//    IpfCpuCache.s

+//

+//  Abstract:

+//

+//    Contains Misc assembly procedures to support IPF CPU AP.

+//

+// Revision History:

+//

+//--

+

+.file  "IpfCpuCache.s"

+

+#include  "IpfMacro.i"

+#include  "IpfDefines.h"

+

+//-----------------------------------------------------------------------------

+//++

+// Flush Cache

+//

+// Arguments : 

+

+// Input = in0 = Starting Address to Flush.

+// Input = in1 = Length in bytes.

+// Input = b0 = return branch register.

+// On Entry :

+//

+// Return Value: 

+//

+//  VOID

+//  SalFlushCache (

+//    IN UINT64   BaseToFlush,

+//    IN UINT64   LengthToFlush

+//    );

+//

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (SalFlushCache)

+

+      NESTED_SETUP (5,8,0,0)

+            

+      mov         loc2 = ar.lc

+      

+      mov         loc3 = in0                  // Start address.

+      mov         loc4 = in1;;                // Length in bytes.

+      

+      cmp.eq  p6,p7 = loc4, r0;;               // If Length is zero then don't flush any cache

+      (p6)  br.spnt.many DoneFlushingC;;         

+      

+      add         loc4 = loc4,loc3 

+      mov         loc5 = 1;;

+      sub         loc4 = loc4, loc5 ;; // the End address to flush

+                                         

+      dep         loc3 = r0,loc3,0,5          

+      dep         loc4 = r0,loc4,0,5;;         

+      shr         loc3 = loc3,5             

+      shr         loc4 = loc4,5;;    // 32 byte cache line

+      

+      sub         loc4 = loc4,loc3;; // total flush count, It should be add 1 but 

+                                     // the br.cloop will first execute one time 

+      mov         loc3 = in0                  

+      mov         loc5 = 32      

+      mov         ar.lc = loc4;;

+

+StillFlushingC:

+      fc          loc3;; 

+      sync.i;;

+      srlz.i;;

+      add         loc3 = loc5,loc3;;

+      br.cloop.sptk.few StillFlushingC;;

+

+DoneFlushingC:      

+      mov         ar.lc = loc2     

+      NESTED_RETURN

+

+PROCEDURE_EXIT (SalFlushCache)

+

diff --git a/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/EsalServiceLib.c b/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/EsalServiceLib.c
new file mode 100644
index 0000000..d258b98
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeSalLib/Ipf/EsalServiceLib.c
@@ -0,0 +1,199 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EsalServiceLib.c

+

+Abstract:

+

+--*/

+

+#include <Ipf/IpfDefines.h>

+

+

+STATIC EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;

+

+EFI_STATUS

+EFIAPI

+DxeSalLibConstruct (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS Status;

+

+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+EFI_STATUS

+RegisterEsalFunction (

+  IN  UINT64                                    FunctionId,

+  IN  EFI_GUID                                  *ClassGuid,

+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,

+  IN  VOID                                      *ModuleGlobal

+  )

+/*++

+

+Routine Description:

+

+  Register ESAL Class Function and it's asociated global.

+  This function is boot service only!

+

+Arguments:

+  FunctionId    - ID of function to register

+  ClassGuid     - GUID of function class 

+  Function      - Function to register under ClassGuid/FunctionId pair

+  ModuleGlobal  - Module global for Function.

+

+Returns: 

+  EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.

+

+--*/

+{

+  return mEsalBootService->AddExtendedSalProc (

+                            mEsalBootService,

+                            ClassGuid,

+                            FunctionId,

+                            Function,

+                            ModuleGlobal

+                            );

+}

+

+EFI_STATUS

+RegisterEsalClass (

+  IN  EFI_GUID                                  *ClassGuid,

+  IN  VOID                                      *ModuleGlobal,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Register ESAL Class and it's asociated global.

+  This function is boot service only!

+

+Arguments:

+  ClassGuid     - GUID of function class 

+  ModuleGlobal  - Module global for Function.

+  ...           - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL 

+                  indicates the end of the list.

+

+Returns: 

+  EFI_SUCCESS - All members of ClassGuid registered

+

+--*/

+{

+  VA_LIST                         Args;

+  EFI_STATUS                      Status;

+  SAL_INTERNAL_EXTENDED_SAL_PROC  Function;

+  UINT64                          FunctionId;

+  EFI_HANDLE                      NewHandle;

+

+  VA_START (Args, ModuleGlobal);

+

+  Status = EFI_SUCCESS;

+  while (!EFI_ERROR (Status)) {

+    Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);

+    if (Function == NULL) {

+      break;

+    }

+

+    FunctionId  = VA_ARG (Args, UINT64);

+

+    Status      = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  NewHandle = NULL;

+  return gBS->InstallProtocolInterface (

+                &NewHandle,

+                ClassGuid,

+                EFI_NATIVE_INTERFACE,

+                NULL

+                );

+}

+

+SAL_RETURN_REGS

+EfiCallEsalService (

+  IN  EFI_GUID                                      *ClassGuid,

+  IN  UINT64                                        FunctionId,

+  IN  UINT64                                        Arg2,

+  IN  UINT64                                        Arg3,

+  IN  UINT64                                        Arg4,

+  IN  UINT64                                        Arg5,

+  IN  UINT64                                        Arg6,

+  IN  UINT64                                        Arg7,

+  IN  UINT64                                        Arg8

+  )

+/*++

+

+Routine Description:

+

+  Call module that is not linked direclty to this module. This code is IP 

+  relative and hides the binding issues of virtual or physical calling. The

+  function that gets dispatched has extra arguments that include the registered

+  module global and a boolean flag to indicate if the system is in virutal mode.

+

+Arguments:

+  ClassGuid   - GUID of function

+  FunctionId  - Function in ClassGuid to call

+  Arg2        - Argument 2 ClassGuid/FunctionId defined

+  Arg3        - Argument 3 ClassGuid/FunctionId defined

+  Arg4        - Argument 4 ClassGuid/FunctionId defined

+  Arg5        - Argument 5 ClassGuid/FunctionId defined

+  Arg6        - Argument 6 ClassGuid/FunctionId defined

+  Arg7        - Argument 7 ClassGuid/FunctionId defined

+  Arg8        - Argument 8 ClassGuid/FunctionId defined

+

+Returns: 

+  Status of ClassGuid/FuncitonId

+

+--*/

+{

+  SAL_RETURN_REGS       ReturnReg;

+  SAL_EXTENDED_SAL_PROC EsalProc;

+

+  ReturnReg = GetEsalEntryPoint ();

+  if (ReturnReg.Status != EFI_SAL_SUCCESS) {

+    return ReturnReg;

+  }

+

+  if (ReturnReg.r11 & PSR_IT_MASK) {

+    //

+    // Virtual mode plabel to entry point

+    //

+    EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;

+  } else {

+    //

+    // Physical mode plabel to entry point

+    //

+    EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;

+  }

+

+  return EsalProc (

+          ClassGuid,

+          FunctionId,

+          Arg2,

+          Arg3,

+          Arg4,

+          Arg5,

+          Arg6,

+          Arg7,

+          Arg8

+          );

+}

diff --git a/edk2/EdkModulePkg/Library/EdkDxeSalLib/build.xml b/edk2/EdkModulePkg/Library/EdkDxeSalLib/build.xml
new file mode 100644
index 0000000..580d1a6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkDxeSalLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkDxeSalLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkDxeSalLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkDxeSalLib">

+      <GenBuild baseName="EdkDxeSalLib" mbdFilename="${MODULE_DIR}/EdkDxeSalLib.mbd" msaFilename="${MODULE_DIR}/EdkDxeSalLib.msa"/>

+   </target>

+   <target depends="EdkDxeSalLib_clean" name="clean"/>

+   <target depends="EdkDxeSalLib_cleanall" name="cleanall"/>

+   <target name="EdkDxeSalLib_clean">

+      <OutputDirSetup baseName="EdkDxeSalLib" mbdFilename="${MODULE_DIR}/EdkDxeSalLib.mbd" msaFilename="${MODULE_DIR}/EdkDxeSalLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxeSalLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxeSalLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkDxeSalLib_cleanall">

+      <OutputDirSetup baseName="EdkDxeSalLib" mbdFilename="${MODULE_DIR}/EdkDxeSalLib.mbd" msaFilename="${MODULE_DIR}/EdkDxeSalLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkDxeSalLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkDxeSalLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkDxeSalLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.mbd b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.mbd
new file mode 100644
index 0000000..a5ee7cb
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkFvbServiceLib</BaseName>

+    <Guid>bd4d540e-04b0-4b10-8fd5-4a7bb533cf67</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:13</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa
new file mode 100644
index 0000000..eb1844d
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkFvbServiceLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>bd4d540e-04b0-4b10-8fd5-4a7bb533cf67</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>FvbService Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:13</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkFvbServiceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/Fvb.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x64/Fvb.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/Fvb.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FvbExtension</Protocol>

+    <ProtocolNotify Usage="SOMETIMES_CONSUMED">FirmwareVolumeBlock</ProtocolNotify>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>FvbLibInitialize</Constructor>

+    </Extern>

+    <Extern>

+      <SetVirtualAddressMapCallBack>FvbVirtualAddressChangeNotifyEvent</SetVirtualAddressMapCallBack>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Fvb.h b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Fvb.h
new file mode 100644
index 0000000..c6d1eb7
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Fvb.h
@@ -0,0 +1,31 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Fvb.h

+

+Abstract:

+

+--*/

+

+#ifndef __FVB_H__

+#define __FVB_H__

+

+#define MAX_FVB_COUNT 16

+

+typedef struct {

+  EFI_HANDLE                          Handle;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  EFI_FVB_EXTENSION_PROTOCOL          *FvbExtension;

+} FVB_ENTRY;

+

+#endif

diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c
new file mode 100644
index 0000000..222fb9b
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c
@@ -0,0 +1,534 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    Fvb.c 

+

+Abstract:

+

+  Firmware Volume Block Protocol Runtime Abstraction

+

+  mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the 

+  index in the mFvbEntry array. This should be the same sequence as the FVB's

+  were described in the HOB. We have to remember the handle so we can tell if 

+  the protocol has been reinstalled and it needs updateing.

+

+  If you are using any of these lib functions.you must first call FvbInitialize ().

+

+Key:

+  FVB - Firmware Volume Block

+

+--*/

+

+#include "Fvb.h"

+

+//

+// Lib will ASSERT if more FVB devices than this are added to the system.

+//

+STATIC FVB_ENTRY          *mFvbEntry;

+STATIC EFI_EVENT          mFvbRegistration;

+STATIC BOOLEAN            mEfiFvbInitialized        = FALSE;

+STATIC UINTN              mFvbCount;

+

+STATIC

+VOID

+EFIAPI

+FvbNotificationEvent (

+  IN  EFI_EVENT       Event,

+  IN  VOID            *Context

+  )

+/*++

+

+Routine Description:

+  Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is

+  reinstalled.

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns: 

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       BufferSize;

+  EFI_HANDLE  Handle;

+  UINTN       Index;

+  UINTN       UpdateIndex;

+

+  while (TRUE) {

+    BufferSize = sizeof (Handle);

+    Status = gBS->LocateHandle (

+                    ByRegisterNotify,

+                    &gEfiFirmwareVolumeBlockProtocolGuid,

+                    mFvbRegistration,

+                    &BufferSize,

+                    &Handle

+                    );

+    if (EFI_ERROR (Status)) {

+      //

+      // Exit Path of While Loop....

+      //

+      break;

+    }

+

+    UpdateIndex = MAX_FVB_COUNT;

+    for (Index = 0; Index < mFvbCount; Index++) {

+      if (mFvbEntry[Index].Handle == Handle) {

+        //

+        //  If the handle is already in the table just update the protocol

+        //

+        UpdateIndex = Index;

+        break;

+      }

+    }

+

+    if (UpdateIndex == MAX_FVB_COUNT) {

+      //

+      // Use the next free slot for a new entry

+      //

+      UpdateIndex                   = mFvbCount++;;

+      mFvbEntry[UpdateIndex].Handle = Handle;

+    }

+    //

+    // The array does not have enough entries

+    //

+    ASSERT (UpdateIndex < MAX_FVB_COUNT);

+

+    //

+    //  Get the interface pointer and if it's ours, skip it

+    //

+    Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **) &mFvbEntry[UpdateIndex].Fvb);

+    ASSERT_EFI_ERROR (Status);

+

+    Status = gBS->HandleProtocol (Handle, &gEfiFvbExtensionProtocolGuid, (VOID **) &mFvbEntry[UpdateIndex].FvbExtension);

+    if (Status != EFI_SUCCESS) {

+      mFvbEntry[UpdateIndex].FvbExtension = NULL;

+    }

+  }

+}

+

+VOID

+EFIAPI

+FvbVirtualAddressChangeNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Convert all pointers in mFvbEntry after ExitBootServices.

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Index;

+  if (mFvbEntry != NULL) {

+    for (Index = 0; Index < MAX_FVB_COUNT; Index++) {

+      if (NULL != mFvbEntry[Index].Fvb) {

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetVolumeAttributes);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetVolumeAttributes);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);

+      }

+

+      if (NULL != mFvbEntry[Index].FvbExtension) {

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension);

+      }

+    }

+

+    EfiConvertPointer (0x0, (VOID **) &mFvbEntry);

+  }

+}

+

+EFI_STATUS

+EFIAPI

+FvbLibInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  Initialize globals and register Fvb Protocol notification function.

+

+Arguments:

+  None 

+

+Returns: 

+  EFI_SUCCESS

+

+--*/

+{

+  UINTN Status;

+  mFvbCount = 0;

+

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,

+                  (VOID *) &mFvbEntry

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);

+

+  EfiCreateProtocolNotifyEvent (

+    &gEfiFirmwareVolumeBlockProtocolGuid,

+    EFI_TPL_CALLBACK,

+    FvbNotificationEvent,

+    NULL,

+    &mFvbRegistration

+    );

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+  //  Status = gBS->CreateEvent (

+  //                EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,

+  //                EFI_TPL_NOTIFY,

+  //                EfiRuntimeLibFvbVirtualNotifyEvent,

+  //                NULL,

+  //                &mEfiFvbVirtualNotifyEvent

+  //                );

+  //  ASSERT_EFI_ERROR (Status);

+  //

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+

+  ASSERT_EFI_ERROR (Status);

+

+  mEfiFvbInitialized = TRUE;

+

+  return EFI_SUCCESS;

+}

+//

+// The following functions wrap Fvb protocol in the Runtime Lib functions.

+// The Instance translates into Fvb instance. The Fvb order defined by HOBs and

+// thus the sequence of FVB protocol addition define Instance.

+//

+// EfiFvbInitialize () must be called before any of the following functions

+// must be called.

+//

+

+EFI_STATUS

+EfiFvbReadBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Reads specified number of bytes into a buffer from the specified block

+

+Arguments:

+  Instance              - The FV instance to be read from

+  Lba                   - The logical block address to be read from

+  Offset                - Offset into the block at which to begin reading

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes read

+  Buffer                - Pointer to a caller allocated buffer that will be

+                          used to hold the data read

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);

+}

+

+EFI_STATUS

+EfiFvbWriteBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the block

+

+Arguments:

+  Instance              - The FV instance to be written to

+  Lba                   - The starting logical block index to write to

+  Offset                - Offset into the block at which to begin writing

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes actually written

+  Buffer                - Pointer to a caller allocated buffer that contains

+                          the source for the write

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);

+}

+

+EFI_STATUS

+EfiFvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a firmware volume block

+

+Arguments:

+  Instance              - The FV instance to be erased

+  Lba                   - The logical block index to be erased

+  

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, -1);

+}

+

+EFI_STATUS

+EfiFvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes

+  )

+/*++

+

+Routine Description:

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          returned

+  Attributes            - Output buffer which contains attributes

+

+Returns: 

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->GetVolumeAttributes (mFvbEntry[Instance].Fvb, Attributes);

+}

+

+EFI_STATUS

+EfiFvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN EFI_FVB_ATTRIBUTES                   Attributes

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the 

+  input parameter, and returns the new setting of the volume

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          modified

+  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 

+                          containing the desired firmware volume settings.

+                          On successful return, it contains the new settings

+                          of the firmware volume

+

+Returns: 

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->SetVolumeAttributes (mFvbEntry[Instance].Fvb, &Attributes);

+}

+

+EFI_STATUS

+EfiFvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *BaseAddress

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  BaseAddress           - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 

+                          that on successful return, contains the base address

+                          of the firmware volume. 

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);

+}

+

+EFI_STATUS

+EfiFvbGetBlockSize (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieve the size of a logical block

+

+Arguments:

+  Instance              - The FV instance whose block size is going to be

+                          returned

+  Lba                   - Indicates which block to return the size for.

+  BlockSize             - A pointer to a caller allocated UINTN in which

+                          the size of the block is returned

+  NumOfBlocks           - a pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+                          

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);

+}

+

+EFI_STATUS

+EfiFvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  Instance              - The FV instance to be erased

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetLastLba         - Offset into the last block at which to end erasing

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+  

+  EFI_UNSUPPORTED       - not support

+  

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!(mFvbEntry[Instance].FvbExtension)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (

+                                            mFvbEntry[Instance].FvbExtension,

+                                            StartLba,

+                                            OffsetStartLba,

+                                            LastLba,

+                                            OffsetLastLba

+                                            );

+}

diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Ipf/Fvb.c b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Ipf/Fvb.c
new file mode 100644
index 0000000..58ad6f5
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/Ipf/Fvb.c
@@ -0,0 +1,324 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    Fvb.c

+

+Abstract:

+

+  Light weight lib to support Tiano Firmware Volume Block 

+  protocol abstraction at runtime.

+

+  All these functions convert EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID

+  class function to the Runtime Lib function. There is a 1 to 1 mapping.

+

+  If you are using any of these lib functions.you must first call FvbInitialize ().

+

+--*/

+

+EFI_STATUS

+FvbLibInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  Initialize globals and register Fvb Protocol notification function.

+

+Arguments:

+  None

+

+Returns: 

+  EFI_SUCCESS

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+//

+// The following functions wrap Fvb protocol in the Runtime Lib functions.

+// The Instance translates into Fvb instance. The Fvb order defined by HOBs and

+// thus the sequence of FVB protocol addition define Instance.

+//

+// EfiFvbInitialize () must be called before any of the following functions

+// must be called.

+//

+EFI_STATUS

+EfiFvbReadBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Reads specified number of bytes into a buffer from the specified block

+

+Arguments:

+  Instance              - The FV instance to be read from

+  Lba                   - The logical block address to be read from

+  Offset                - Offset into the block at which to begin reading

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes read

+  Buffer                - Pointer to a caller allocated buffer that will be

+                          used to hold the data read

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (&Guid, Read, Instance, Lba, Offset, (UINT64) NumBytes, (UINT64) Buffer, 0, 0).Status;

+}

+

+EFI_STATUS

+EfiFvbWriteBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the block

+

+Arguments:

+  Instance              - The FV instance to be written to

+  Lba                   - The starting logical block index to write to

+  Offset                - Offset into the block at which to begin writing

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes actually written

+  Buffer                - Pointer to a caller allocated buffer that contains

+                          the source for the write

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (&Guid, Write, Instance, Lba, Offset, (UINT64) NumBytes, (UINT64) Buffer, 0, 0).Status;

+}

+

+EFI_STATUS

+EfiFvbEraseBlock (

+  IN UINTN                                Instance,

+  IN UINTN                                Lba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a firmware volume block

+

+Arguments:

+  Instance              - The FV instance to be erased

+  Lba                   - The logical block index to be erased

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (&Guid, EraseBlock, Instance, Lba, 0, 0, 0, 0, 0).Status;

+}

+

+EFI_STATUS

+EfiFvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes

+  )

+/*++

+

+Routine Description:

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          returned

+  Attributes            - Output buffer which contains attributes

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (&Guid, SetVolumeAttributes, Instance, (UINT64) Attributes, 0, 0, 0, 0, 0).Status;

+}

+

+EFI_STATUS

+EfiFvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN EFI_FVB_ATTRIBUTES                   Attributes

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the 

+  input parameter, and returns the new setting of the volume

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          modified

+  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 

+                          containing the desired firmware volume settings.

+                          On successful return, it contains the new settings

+                          of the firmware volume

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (&Guid, SetVolumeAttributes, Instance, (UINT64) Attributes, 0, 0, 0, 0, 0).Status;

+}

+

+EFI_STATUS

+EfiFvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *BaseAddress

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  BaseAddress           - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 

+                          that on successful return, contains the base address

+                          of the firmware volume. 

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (&Guid, GetPhysicalAddress, Instance, (UINT64) BaseAddress, 0, 0, 0, 0, 0).Status;

+}

+

+EFI_STATUS

+EfiFvbGetBlockSize (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  OUT UINTN                               *BlockSize,

+  OUT UINTN                               *NumOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieve the size of a logical block

+

+Arguments:

+  Instance              - The FV instance whose block size is going to be

+                          returned

+  Lba                   - Indicates which block to return the size for.

+  BlockSize             - A pointer to a caller allocated UINTN in which

+                          the size of the block is returned

+  NumOfBlocks           - a pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+

+Returns:

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (

+          &Guid,

+          GetBlockSize,

+          Instance,

+          Lba,

+          (UINT64) BlockSize,

+          (UINT64) NumOfBlocks,

+          0,

+          0,

+          0

+          ).Status;

+}

+

+EFI_STATUS

+EfiFvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  Instance              - The FV instance to be erased

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetLastLba         - Offset into the last block at which to end erasing

+

+Returns:

+  Status code

+

+--*/

+{

+  EFI_GUID Guid = EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID;

+

+  return EfiCallEsalService (

+          &Guid,

+          EraseCustomBlockRange,

+          Instance,

+          StartLba,

+          OffsetStartLba,

+          LastLba,

+          OffsetLastLba,

+          0,

+          0

+          ).Status;

+}

+

+

+/**

+  BugBug: Can't turn this off in the current MSA so we need a stub

+**/

+VOID

+EFIAPI

+FvbVirtualAddressChangeNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+{

+}

diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/build.xml b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/build.xml
new file mode 100644
index 0000000..a111fb2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkFvbServiceLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkFvbServiceLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkFvbServiceLib">

+      <GenBuild baseName="EdkFvbServiceLib" mbdFilename="${MODULE_DIR}/EdkFvbServiceLib.mbd" msaFilename="${MODULE_DIR}/EdkFvbServiceLib.msa"/>

+   </target>

+   <target depends="EdkFvbServiceLib_clean" name="clean"/>

+   <target depends="EdkFvbServiceLib_cleanall" name="cleanall"/>

+   <target name="EdkFvbServiceLib_clean">

+      <OutputDirSetup baseName="EdkFvbServiceLib" mbdFilename="${MODULE_DIR}/EdkFvbServiceLib.mbd" msaFilename="${MODULE_DIR}/EdkFvbServiceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkFvbServiceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkFvbServiceLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkFvbServiceLib_cleanall">

+      <OutputDirSetup baseName="EdkFvbServiceLib" mbdFilename="${MODULE_DIR}/EdkFvbServiceLib.mbd" msaFilename="${MODULE_DIR}/EdkFvbServiceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkFvbServiceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkFvbServiceLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkFvbServiceLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkFvbServiceLib/x64/Fvb.c b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/x64/Fvb.c
new file mode 100644
index 0000000..76ddfa8
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkFvbServiceLib/x64/Fvb.c
@@ -0,0 +1,536 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    Fvb.c 

+

+Abstract:

+

+  Firmware Volume Block Protocol Runtime Abstraction

+

+  mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the 

+  index in the mFvbEntry array. This should be the same sequence as the FVB's

+  were described in the HOB. We have to remember the handle so we can tell if 

+  the protocol has been reinstalled and it needs updateing.

+

+  If you are using any of these lib functions.you must first call FvbInitialize ().

+

+Key:

+  FVB - Firmware Volume Block

+

+--*/

+

+#include "Fvb.h"

+

+//

+// Lib will ASSERT if more FVB devices than this are added to the system.

+//

+STATIC FVB_ENTRY          *mFvbEntry;

+STATIC EFI_EVENT          mFvbVirtualNotifyEvent;

+STATIC EFI_EVENT          mFvbRegistration;

+STATIC EFI_EVENT          mEfiFvbVirtualNotifyEvent;

+STATIC BOOLEAN            mEfiFvbInitialized        = FALSE;

+STATIC UINTN              mFvbCount;

+

+STATIC

+VOID

+EFIAPI

+FvbNotificationEvent (

+  IN  EFI_EVENT       Event,

+  IN  VOID            *Context

+  )

+/*++

+

+Routine Description:

+  Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is

+  reinstalled.

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns: 

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       BufferSize;

+  EFI_HANDLE  Handle;

+  UINTN       Index;

+  UINTN       UpdateIndex;

+

+  while (TRUE) {

+    BufferSize = sizeof (Handle);

+    Status = gBS->LocateHandle (

+                    ByRegisterNotify,

+                    &gEfiFirmwareVolumeBlockProtocolGuid,

+                    mFvbRegistration,

+                    &BufferSize,

+                    &Handle

+                    );

+    if (EFI_ERROR (Status)) {

+      //

+      // Exit Path of While Loop....

+      //

+      break;

+    }

+

+    UpdateIndex = MAX_FVB_COUNT;

+    for (Index = 0; Index < mFvbCount; Index++) {

+      if (mFvbEntry[Index].Handle == Handle) {

+        //

+        //  If the handle is already in the table just update the protocol

+        //

+        UpdateIndex = Index;

+        break;

+      }

+    }

+

+    if (UpdateIndex == MAX_FVB_COUNT) {

+      //

+      // Use the next free slot for a new entry

+      //

+      UpdateIndex                   = mFvbCount++;;

+      mFvbEntry[UpdateIndex].Handle = Handle;

+    }

+    //

+    // The array does not have enough entries

+    //

+    ASSERT (UpdateIndex < MAX_FVB_COUNT);

+

+    //

+    //  Get the interface pointer and if it's ours, skip it

+    //

+    Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &mFvbEntry[UpdateIndex].Fvb);

+    ASSERT_EFI_ERROR (Status);

+

+    Status = gBS->HandleProtocol (Handle, &gEfiFvbExtensionProtocolGuid, &mFvbEntry[UpdateIndex].FvbExtension);

+    if (Status != EFI_SUCCESS) {

+      mFvbEntry[UpdateIndex].FvbExtension = NULL;

+    }

+  }

+}

+

+VOID

+EFIAPI

+FvbVirtualAddressChangeNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Convert all pointers in mFvbEntry after ExitBootServices.

+

+Arguments:

+

+  Event   - The Event that is being processed

+  

+  Context - Event Context

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Index;

+  if (mFvbEntry != NULL) {

+    for (Index = 0; Index < MAX_FVB_COUNT; Index++) {

+      if (NULL != mFvbEntry[Index].Fvb) {

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetVolumeAttributes);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetVolumeAttributes);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);

+      }

+

+      if (NULL != mFvbEntry[Index].FvbExtension) {

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);

+        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension);

+      }

+    }

+

+    EfiConvertPointer (0x0, (VOID **) &mFvbEntry);

+  }

+}

+

+EFI_STATUS

+EFIAPI

+FvbLibInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  Initialize globals and register Fvb Protocol notification function.

+

+Arguments:

+  None 

+

+Returns: 

+  EFI_SUCCESS

+

+--*/

+{

+  UINTN Status;

+  mFvbCount = 0;

+

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,

+                  (VOID *) &mFvbEntry

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  ZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);

+

+  EfiCreateProtocolNotifyEvent (

+    &gEfiFirmwareVolumeBlockProtocolGuid,

+    EFI_TPL_CALLBACK,

+    FvbNotificationEvent,

+    NULL,

+    &mFvbRegistration

+    );

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+  //  Status = gBS->CreateEvent (

+  //                EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,

+  //                EFI_TPL_NOTIFY,

+  //                EfiRuntimeLibFvbVirtualNotifyEvent,

+  //                NULL,

+  //                &mEfiFvbVirtualNotifyEvent

+  //                );

+  //  ASSERT_EFI_ERROR (Status);

+  //

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+

+  ASSERT_EFI_ERROR (Status);

+

+  mEfiFvbInitialized = TRUE;

+

+  return EFI_SUCCESS;

+}

+//

+// The following functions wrap Fvb protocol in the Runtime Lib functions.

+// The Instance translates into Fvb instance. The Fvb order defined by HOBs and

+// thus the sequence of FVB protocol addition define Instance.

+//

+// EfiFvbInitialize () must be called before any of the following functions

+// must be called.

+//

+

+EFI_STATUS

+EfiFvbReadBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Reads specified number of bytes into a buffer from the specified block

+

+Arguments:

+  Instance              - The FV instance to be read from

+  Lba                   - The logical block address to be read from

+  Offset                - Offset into the block at which to begin reading

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes read

+  Buffer                - Pointer to a caller allocated buffer that will be

+                          used to hold the data read

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);

+}

+

+EFI_STATUS

+EfiFvbWriteBlock (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the block

+

+Arguments:

+  Instance              - The FV instance to be written to

+  Lba                   - The starting logical block index to write to

+  Offset                - Offset into the block at which to begin writing

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes actually written

+  Buffer                - Pointer to a caller allocated buffer that contains

+                          the source for the write

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);

+}

+

+EFI_STATUS

+EfiFvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a firmware volume block

+

+Arguments:

+  Instance              - The FV instance to be erased

+  Lba                   - The logical block index to be erased

+  

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, -1);

+}

+

+EFI_STATUS

+EfiFvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes

+  )

+/*++

+

+Routine Description:

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          returned

+  Attributes            - Output buffer which contains attributes

+

+Returns: 

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->GetVolumeAttributes (mFvbEntry[Instance].Fvb, Attributes);

+}

+

+EFI_STATUS

+EfiFvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN EFI_FVB_ATTRIBUTES                   Attributes

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the 

+  input parameter, and returns the new setting of the volume

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          modified

+  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 

+                          containing the desired firmware volume settings.

+                          On successful return, it contains the new settings

+                          of the firmware volume

+

+Returns: 

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->SetVolumeAttributes (mFvbEntry[Instance].Fvb, &Attributes);

+}

+

+EFI_STATUS

+EfiFvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *BaseAddress

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  BaseAddress           - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 

+                          that on successful return, contains the base address

+                          of the firmware volume. 

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);

+}

+

+EFI_STATUS

+EfiFvbGetBlockSize (

+  IN UINTN                                        Instance,

+  IN EFI_LBA                                      Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieve the size of a logical block

+

+Arguments:

+  Instance              - The FV instance whose block size is going to be

+                          returned

+  Lba                   - Indicates which block to return the size for.

+  BlockSize             - A pointer to a caller allocated UINTN in which

+                          the size of the block is returned

+  NumOfBlocks           - a pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+                          

+  EFI_INVALID_PARAMETER - invalid parameter

+

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);

+}

+

+EFI_STATUS

+EfiFvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  Instance              - The FV instance to be erased

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetLastLba         - Offset into the last block at which to end erasing

+

+Returns: 

+

+  Status code

+  

+  EFI_INVALID_PARAMETER - invalid parameter

+  

+  EFI_UNSUPPORTED       - not support

+  

+--*/

+{

+  if (Instance >= mFvbCount) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!(mFvbEntry[Instance].FvbExtension)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (

+                                            mFvbEntry[Instance].FvbExtension,

+                                            StartLba,

+                                            OffsetStartLba,

+                                            LastLba,

+                                            OffsetLastLba

+                                            );

+}

diff --git a/edk2/EdkModulePkg/Library/EdkGraphicsLib/EdkGraphicsLib.mbd b/edk2/EdkModulePkg/Library/EdkGraphicsLib/EdkGraphicsLib.mbd
new file mode 100644
index 0000000..4758d6b
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkGraphicsLib/EdkGraphicsLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkGraphicsLib</BaseName>

+    <Guid>08c1a0e4-1208-47f8-a2c5-f42eabee653a</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkGraphicsLib/EdkGraphicsLib.msa b/edk2/EdkModulePkg/Library/EdkGraphicsLib/EdkGraphicsLib.msa
new file mode 100644
index 0000000..ac1ae6c
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkGraphicsLib/EdkGraphicsLib.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkGraphicsLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>08c1a0e4-1208-47f8-a2c5-f42eabee653a</Guid>

+    <Version>0</Version>

+    <Abstract>Graphics Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkGraphicsLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Graphics.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">OEMBadging</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolume</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ConsoleControl</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">UgaDraw</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleTextOut</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>Bmp</C_Name>

+    </GuidEntry>

+  </Guids>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkGraphicsLib/Graphics.c b/edk2/EdkModulePkg/Library/EdkGraphicsLib/Graphics.c
new file mode 100644
index 0000000..01c612a
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkGraphicsLib/Graphics.c
@@ -0,0 +1,780 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Graphics.c

+

+Abstract:

+

+  Support for Basic Graphics operations.

+

+  BugBug: Currently *.BMP files are supported. This will be replaced

+          when Tiano graphics format is supported.

+

+--*/

+

+EFI_STATUS

+GetGraphicsBitMapFromFV (

+  IN  EFI_GUID      *FileNameGuid,

+  OUT VOID          **Image,

+  OUT UINTN         *ImageSize

+  )

+/*++

+

+Routine Description:

+

+  Return the graphics image file named FileNameGuid into Image and return it's

+  size in ImageSize. All Firmware Volumes (FV) in the system are searched for the

+  file name.

+

+Arguments:

+

+  FileNameGuid  - File Name of graphics file in the FV(s).

+

+  Image         - Pointer to pointer to return graphics image.  If NULL, a 

+                  buffer will be allocated.

+

+  ImageSize     - Size of the graphics Image in bytes. Zero if no image found.

+

+

+Returns: 

+

+  EFI_SUCCESS          - Image and ImageSize are valid. 

+  EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size

+  EFI_NOT_FOUND        - FileNameGuid not found

+

+--*/

+{

+  EFI_STATUS                    Status;

+  UINTN                         FvProtocolCount;

+  EFI_HANDLE                    *FvHandles;

+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;

+  UINTN                         Index;

+  UINT32                        AuthenticationStatus;

+

+

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiFirmwareVolumeProtocolGuid,

+                  NULL,

+                  &FvProtocolCount,

+                  &FvHandles

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  for (Index = 0; Index < FvProtocolCount; Index++) {

+    Status = gBS->HandleProtocol (

+                    FvHandles[Index],

+                    &gEfiFirmwareVolumeProtocolGuid,

+                    (VOID **) &Fv

+                    );

+

+    //

+    // Assuming Image and ImageSize are correct on input.

+    //

+    Status = Fv->ReadSection (

+                  Fv,

+                  &gEfiDefaultBmpLogoGuid,

+                  EFI_SECTION_RAW,

+                  0,

+                  Image,

+                  ImageSize,

+                  &AuthenticationStatus

+                  );

+    if (!EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    } else if (Status == EFI_BUFFER_TOO_SMALL) {

+      //

+      // ImageSize updated to needed size so return

+      //

+      return EFI_BUFFER_TOO_SMALL;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+

+EFI_STATUS

+ConvertBmpToUgaBlt (

+  IN  VOID      *BmpImage,

+  IN  UINTN     BmpImageSize,

+  IN OUT VOID   **UgaBlt,

+  IN OUT UINTN  *UgaBltSize,

+  OUT UINTN     *PixelHeight,

+  OUT UINTN     *PixelWidth

+  )

+/*++

+

+Routine Description:

+

+  Convert a *.BMP graphics image to a UGA blt buffer. If a NULL UgaBlt buffer

+  is passed in a UgaBlt buffer will be allocated by this routine. If a UgaBlt

+  buffer is passed in it will be used if it is big enough.

+

+Arguments:

+

+  BmpImage      - Pointer to BMP file

+

+  BmpImageSize  - Number of bytes in BmpImage

+

+  UgaBlt        - Buffer containing UGA version of BmpImage.

+

+  UgaBltSize    - Size of UgaBlt in bytes.

+

+  PixelHeight   - Height of UgaBlt/BmpImage in pixels

+

+  PixelWidth    - Width of UgaBlt/BmpImage in pixels

+

+

+Returns: 

+

+  EFI_SUCCESS           - UgaBlt and UgaBltSize are returned. 

+  EFI_UNSUPPORTED       - BmpImage is not a valid *.BMP image

+  EFI_BUFFER_TOO_SMALL  - The passed in UgaBlt buffer is not big enough.

+                          UgaBltSize will contain the required size.

+  EFI_OUT_OF_RESOURCES  - No enough buffer to allocate

+

+--*/

+{

+  UINT8             *Image;

+  UINT8             *ImageHeader;

+  BMP_IMAGE_HEADER  *BmpHeader;

+  BMP_COLOR_MAP     *BmpColorMap;

+  EFI_UGA_PIXEL     *BltBuffer;

+  EFI_UGA_PIXEL     *Blt;

+  UINTN             BltBufferSize;

+  UINTN             Index;

+  UINTN             Height;

+  UINTN             Width;

+  UINTN             ImageIndex;

+

+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;

+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (BmpHeader->CompressionType != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Calculate Color Map offset in the image.

+  //

+  Image       = BmpImage;

+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));

+

+  //

+  // Calculate graphics image data address in the image

+  //

+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;

+  ImageHeader   = Image;

+

+  BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_UGA_PIXEL);

+  if (*UgaBlt == NULL) {

+    *UgaBltSize = BltBufferSize;

+    *UgaBlt     = AllocatePool (*UgaBltSize);

+    if (*UgaBlt == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  } else {

+    if (*UgaBltSize < BltBufferSize) {

+      *UgaBltSize = BltBufferSize;

+      return EFI_BUFFER_TOO_SMALL;

+    }

+  }

+

+  *PixelWidth   = BmpHeader->PixelWidth;

+  *PixelHeight  = BmpHeader->PixelHeight;

+

+  //

+  // Convert image from BMP to Blt buffer format

+  //

+  BltBuffer = *UgaBlt;

+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {

+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];

+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {

+      switch (BmpHeader->BitPerPixel) {

+      case 1:

+        //

+        // Convert 1bit BMP to 24-bit color

+        //

+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {

+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;

+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;

+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;

+          Blt++;

+          Width++;

+        }

+

+        Blt --;

+        Width --;

+        break;

+      

+      case 4:

+        //

+        // Convert BMP Palette to 24-bit color

+        //

+        Index       = (*Image) >> 4;

+        Blt->Red    = BmpColorMap[Index].Red;

+        Blt->Green  = BmpColorMap[Index].Green;

+        Blt->Blue   = BmpColorMap[Index].Blue;

+        if (Width < (BmpHeader->PixelWidth - 1)) {

+          Blt++;

+          Width++;

+          Index       = (*Image) & 0x0f;

+          Blt->Red    = BmpColorMap[Index].Red;

+          Blt->Green  = BmpColorMap[Index].Green;

+          Blt->Blue   = BmpColorMap[Index].Blue;

+        }

+        break;

+

+      case 8:

+        //

+        // Convert BMP Palette to 24-bit color

+        //

+        Blt->Red    = BmpColorMap[*Image].Red;

+        Blt->Green  = BmpColorMap[*Image].Green;

+        Blt->Blue   = BmpColorMap[*Image].Blue;

+        break;

+

+      case 24:

+        Blt->Blue   = *Image++;

+        Blt->Green  = *Image++;

+        Blt->Red    = *Image;

+        break;

+

+      default:

+        return EFI_UNSUPPORTED;

+        break;

+      };

+

+    }

+

+    ImageIndex = (UINTN) (Image - ImageHeader);

+    if ((ImageIndex % 4) != 0) {

+      //

+      // Bmp Image starts each row on a 32-bit boundary!

+      //

+      Image = Image + (4 - (ImageIndex % 4));

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+LockKeyboards (

+  IN  CHAR16    *Password

+  )

+/*++

+

+Routine Description:

+  Use Console Control Protocol to lock the Console In Spliter virtual handle. 

+  This is the ConInHandle and ConIn handle in the EFI system table. All key

+  presses will be ignored until the Password is typed in. The only way to

+  disable the password is to type it in to a ConIn device.

+

+Arguments:

+  Password - Password used to lock ConIn device

+

+

+Returns: 

+

+  EFI_SUCCESS     - ConsoleControl has been flipped to graphics and logo

+                          displayed.

+  EFI_UNSUPPORTED - Logo not found

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;

+

+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = ConsoleControl->LockStdIn (ConsoleControl, Password);

+  return Status;

+}

+

+

+EFI_STATUS

+EnableQuietBoot (

+  IN  EFI_GUID  *LogoFile

+  )

+/*++

+

+Routine Description:

+

+  Use Console Control to turn off UGA based Simple Text Out consoles from going

+  to the UGA device. Put up LogoFile on every UGA device that is a console

+

+Arguments:

+

+  LogoFile - File name of logo to display on the center of the screen.

+

+

+Returns: 

+

+  EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo

+                          displayed.

+  EFI_UNSUPPORTED       - Logo not found

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;

+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

+  EFI_OEM_BADGING_PROTOCOL      *Badging;

+  UINT32                        SizeOfX;

+  UINT32                        SizeOfY;

+  UINT32                        ColorDepth;

+  UINT32                        RefreshRate;

+  INTN                          DestX;

+  INTN                          DestY;

+

+  UINT8                         *ImageData;

+  UINTN                         ImageSize;

+  EFI_UGA_PIXEL                 *UgaBlt;

+  UINTN                         UgaBltSize;

+

+  UINT32                        Instance;

+  EFI_BADGING_FORMAT            Format;

+  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;

+  UINTN                         CoordinateX;

+  UINTN                         CoordinateY;

+  UINTN                         Height;

+  UINTN                         Width;

+

+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Badging = NULL;

+  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);

+

+  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);

+

+  Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Instance = 0;

+  while (1) {

+    ImageData = NULL;

+    ImageSize = 0;

+

+    if (Badging != NULL) {

+      Status = Badging->GetImage (

+                          Badging,

+                          &Instance,

+                          &Format,

+                          &ImageData,

+                          &ImageSize,

+                          &Attribute,

+                          &CoordinateX,

+                          &CoordinateY

+                          );

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      //

+      // Currently only support BMP format

+      //

+      if (Format != EfiBadgingFormatBMP) {

+        gBS->FreePool (ImageData);

+        continue;

+      }

+    } else {

+      Status = GetGraphicsBitMapFromFV (LogoFile, (VOID **) &ImageData, &ImageSize);

+      if (EFI_ERROR (Status)) {

+        return EFI_UNSUPPORTED;

+      }

+

+      CoordinateX = 0;

+      CoordinateY = 0;

+      Attribute   = EfiBadgingDisplayAttributeCenter;

+    }

+

+    UgaBlt = NULL;

+    Status = ConvertBmpToUgaBlt (

+              ImageData,

+              ImageSize,

+              (VOID **) &UgaBlt,

+              &UgaBltSize,

+              &Height,

+              &Width

+              );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (ImageData);

+      continue;

+    }

+

+    switch (Attribute) {

+    case EfiBadgingDisplayAttributeLeftTop:

+      DestX = CoordinateX;

+      DestY = CoordinateY;

+      break;

+

+    case EfiBadgingDisplayAttributeCenterTop:

+      DestX = (SizeOfX - Width) / 2;

+      DestY = CoordinateY;

+      break;

+

+    case EfiBadgingDisplayAttributeRightTop:

+      DestX = (SizeOfX - Width - CoordinateX);

+      DestY = CoordinateY;;

+      break;

+

+    case EfiBadgingDisplayAttributeCenterRight:

+      DestX = (SizeOfX - Width - CoordinateX);

+      DestY = (SizeOfY - Height) / 2;

+      break;

+

+    case EfiBadgingDisplayAttributeRightBottom:

+      DestX = (SizeOfX - Width - CoordinateX);

+      DestY = (SizeOfY - Height - CoordinateY);

+      break;

+

+    case EfiBadgingDisplayAttributeCenterBottom:

+      DestX = (SizeOfX - Width) / 2;

+      DestY = (SizeOfY - Height - CoordinateY);

+      break;

+

+    case EfiBadgingDisplayAttributeLeftBottom:

+      DestX = CoordinateX;

+      DestY = (SizeOfY - Height - CoordinateY);

+      break;

+

+    case EfiBadgingDisplayAttributeCenterLeft:

+      DestX = CoordinateX;

+      DestY = (SizeOfY - Height) / 2;

+      break;

+

+    case EfiBadgingDisplayAttributeCenter:

+      DestX = (SizeOfX - Width) / 2;

+      DestY = (SizeOfY - Height) / 2;

+      break;

+

+    default:

+      DestX = CoordinateX;

+      DestY = CoordinateY;

+      break;

+    }

+

+    if ((DestX >= 0) && (DestY >= 0)) {

+      Status = UgaDraw->Blt (

+                          UgaDraw,

+                          UgaBlt,

+                          EfiUgaBltBufferToVideo,

+                          0,

+                          0,

+                          (UINTN) DestX,

+                          (UINTN) DestY,

+                          Width,

+                          Height,

+                          Width * sizeof (EFI_UGA_PIXEL)

+                          );

+    }

+

+    gBS->FreePool (ImageData);

+    gBS->FreePool (UgaBlt);

+

+    if (Badging == NULL) {

+      break;

+    }

+  }

+

+  return Status;

+}

+

+

+EFI_STATUS

+DisableQuietBoot (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Use Console Control to turn on UGA based Simple Text Out consoles. The UGA 

+  Simple Text Out screens will now be synced up with all non UGA output devices

+

+Arguments:

+

+  NONE

+

+Returns: 

+

+  EFI_SUCCESS           - UGA devices are back in text mode and synced up.

+  EFI_UNSUPPORTED       - Logo not found

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;

+

+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);

+}

+

+static EFI_UGA_PIXEL  mEfiColors[16] = {

+  { 0x00, 0x00, 0x00, 0x00 },

+  { 0x98, 0x00, 0x00, 0x00 },

+  { 0x00, 0x98, 0x00, 0x00 },

+  { 0x98, 0x98, 0x00, 0x00 },

+  { 0x00, 0x00, 0x98, 0x00 },

+  { 0x98, 0x00, 0x98, 0x00 },

+  { 0x00, 0x98, 0x98, 0x00 },

+  { 0x98, 0x98, 0x98, 0x00 },

+  { 0x10, 0x10, 0x10, 0x00 },

+  { 0xff, 0x10, 0x10, 0x00 },

+  { 0x10, 0xff, 0x10, 0x00 },

+  { 0xff, 0xff, 0x10, 0x00 },

+  { 0x10, 0x10, 0xff, 0x00 },

+  { 0xf0, 0x10, 0xff, 0x00 },

+  { 0x10, 0xff, 0xff, 0x00 },

+  { 0xff, 0xff, 0xff, 0x00 }

+};

+

+STATIC

+UINTN

+_IPrint (

+  IN EFI_UGA_DRAW_PROTOCOL            *UgaDraw,

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL     *Sto,

+  IN UINTN                            X,

+  IN UINTN                            Y,

+  IN EFI_UGA_PIXEL                    *Foreground,

+  IN EFI_UGA_PIXEL                    *Background,

+  IN CHAR16                           *fmt,

+  IN VA_LIST                          args

+  )

+/*++

+

+Routine Description:

+

+  Display string worker for: Print, PrintAt, IPrint, IPrintAt

+

+Arguments:

+

+  UgaDraw         - UGA draw protocol interface

+  

+  Sto             - Simple text out protocol interface

+  

+  X               - X coordinate to start printing

+  

+  Y               - Y coordinate to start printing

+  

+  Foreground      - Foreground color

+  

+  Background      - Background color

+  

+  fmt             - Format string

+  

+  args            - Print arguments

+

+Returns: 

+

+  EFI_SUCCESS             -  success

+  EFI_OUT_OF_RESOURCES    -  out of resources

+

+--*/

+{

+  VOID              *Buffer;

+  EFI_STATUS        Status;

+  UINT16            GlyphWidth;

+  UINT32            GlyphStatus;

+  UINT16            StringIndex;

+  UINTN             Index;

+  CHAR16            *UnicodeWeight;

+  EFI_NARROW_GLYPH  *Glyph;

+  EFI_HII_PROTOCOL  *Hii;

+  EFI_UGA_PIXEL     *LineBuffer;

+  UINT32            HorizontalResolution;

+  UINT32            VerticalResolution;

+  UINT32            ColorDepth;

+  UINT32            RefreshRate;

+

+  GlyphStatus = 0;

+

+  //

+  // For now, allocate an arbitrarily long buffer

+  //

+  Buffer = AllocateZeroPool (0x10000);

+  if (Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);

+

+  LineBuffer = AllocatePool (sizeof (EFI_UGA_PIXEL) * HorizontalResolution * GLYPH_WIDTH * GLYPH_HEIGHT);

+  if (LineBuffer == NULL) {

+    gBS->FreePool (Buffer);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID **) &Hii);

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  UnicodeVSPrint (Buffer, 0x10000, fmt, args);

+

+  UnicodeWeight = (CHAR16 *) Buffer;

+

+  for (Index = 0; UnicodeWeight[Index] != 0; Index++) {

+    if (UnicodeWeight[Index] == CHAR_BACKSPACE ||

+        UnicodeWeight[Index] == CHAR_LINEFEED  ||

+        UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {

+      UnicodeWeight[Index] = 0;

+    }

+  }

+

+  for (Index = 0; Index < StrLen (Buffer); Index++) {

+    StringIndex = (UINT16) Index;

+    Status      = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);

+    if (EFI_ERROR (Status)) {

+      goto Error;

+    }

+

+    if (Foreground == NULL || Background == NULL) {

+      Status = Hii->GlyphToBlt (

+                      Hii,

+                      (UINT8 *) Glyph,

+                      mEfiColors[Sto->Mode->Attribute & 0x0f],

+                      mEfiColors[Sto->Mode->Attribute >> 4],

+                      StrLen (Buffer),

+                      GlyphWidth,

+                      GLYPH_HEIGHT,

+                      &LineBuffer[Index * GLYPH_WIDTH]

+                      );

+    } else {

+      Status = Hii->GlyphToBlt (

+                      Hii,

+                      (UINT8 *) Glyph,

+                      *Foreground,

+                      *Background,

+                      StrLen (Buffer),

+                      GlyphWidth,

+                      GLYPH_HEIGHT,

+                      &LineBuffer[Index * GLYPH_WIDTH]

+                      );

+    }

+  }

+

+  //

+  // Blt a character to the screen

+  //

+  Status = UgaDraw->Blt (

+                      UgaDraw,

+                      LineBuffer,

+                      EfiUgaBltBufferToVideo,

+                      0,

+                      0,

+                      X,

+                      Y,

+                      GLYPH_WIDTH * StrLen (Buffer),

+                      GLYPH_HEIGHT,

+                      GLYPH_WIDTH * StrLen (Buffer) * sizeof (EFI_UGA_PIXEL)

+                      );

+

+Error:

+  gBS->FreePool (LineBuffer);

+  gBS->FreePool (Buffer);

+  return Status;

+}

+

+

+UINTN

+PrintXY (

+  IN UINTN                            X,

+  IN UINTN                            Y,

+  IN EFI_UGA_PIXEL                    *ForeGround, OPTIONAL

+  IN EFI_UGA_PIXEL                    *BackGround, OPTIONAL

+  IN CHAR16                           *Fmt,

+  ...

+  )

+/*++

+

+Routine Description:

+

+    Prints a formatted unicode string to the default console

+

+Arguments:

+

+    X           - X coordinate to start printing

+    

+    Y           - Y coordinate to start printing

+    

+    ForeGround  - Foreground color

+    

+    BackGround  - Background color

+

+    Fmt         - Format string

+

+    ...         - Print arguments

+

+Returns:

+

+    Length of string printed to the console

+

+--*/

+{

+  EFI_HANDLE                    Handle;

+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *Sto;

+  EFI_STATUS                    Status;

+  VA_LIST                       Args;

+

+  VA_START (Args, Fmt);

+

+  Handle = gST->ConsoleOutHandle;

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &Sto

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return _IPrint (UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkGraphicsLib/build.xml b/edk2/EdkModulePkg/Library/EdkGraphicsLib/build.xml
new file mode 100644
index 0000000..1bb2458
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkGraphicsLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkGraphicsLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkGraphicsLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkGraphicsLib">

+      <GenBuild baseName="EdkGraphicsLib" mbdFilename="${MODULE_DIR}/EdkGraphicsLib.mbd" msaFilename="${MODULE_DIR}/EdkGraphicsLib.msa"/>

+   </target>

+   <target depends="EdkGraphicsLib_clean" name="clean"/>

+   <target depends="EdkGraphicsLib_cleanall" name="cleanall"/>

+   <target name="EdkGraphicsLib_clean">

+      <OutputDirSetup baseName="EdkGraphicsLib" mbdFilename="${MODULE_DIR}/EdkGraphicsLib.mbd" msaFilename="${MODULE_DIR}/EdkGraphicsLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkGraphicsLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkGraphicsLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkGraphicsLib_cleanall">

+      <OutputDirSetup baseName="EdkGraphicsLib" mbdFilename="${MODULE_DIR}/EdkGraphicsLib.mbd" msaFilename="${MODULE_DIR}/EdkGraphicsLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkGraphicsLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkGraphicsLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkGraphicsLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/EdkIfrSupportLib.mbd b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/EdkIfrSupportLib.mbd
new file mode 100644
index 0000000..3864ea2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/EdkIfrSupportLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkIfrSupportLib</BaseName>

+    <Guid>ea55bada-d488-427b-9d2d-227e0aaa3707</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:14</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/EdkIfrSupportLib.msa b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/EdkIfrSupportLib.msa
new file mode 100644
index 0000000..7973024
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/EdkIfrSupportLib.msa
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkIfrSupportLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>ea55bada-d488-427b-9d2d-227e0aaa3707</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Graphics Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:14</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkIfrSupportLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>IfrCommon.c</Filename>

+    <Filename>IfrOnTheFly.c</Filename>

+    <Filename>IfrOpCodeCreation.c</Filename>

+    <Filename>IfrLibrary.h</Filename>

+    <Filename>IfrVariable.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable>

+      <String>L"Lang"</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}</Guid>

+    </Variable>

+  </Variables>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>GlobalVariable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <Constructor>IfrLibConstruct</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrCommon.c b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrCommon.c
new file mode 100644
index 0000000..6d0a84d
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrCommon.c
@@ -0,0 +1,995 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  IfrCommon.c

+

+Abstract:

+

+  Common Library Routines to assist in IFR creation on-the-fly

+

+Revision History:

+

+--*/

+

+EFI_STATUS

+IfrLibConstruct (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetCurrentLanguage (

+  OUT     CHAR16              *Lang

+  )

+/*++

+

+Routine Description:

+

+  Determine what is the current language setting

+  

+Arguments:

+  

+  Lang      - Pointer of system language

+  

+Returns: 

+

+  Status code

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Size;

+  UINTN       Index;

+  CHAR8       Language[4];

+

+  //

+  // Getting the system language and placing it into our Global Data

+  //

+  Size = sizeof (Language);

+

+  Status = gRT->GetVariable (

+                  (CHAR16 *) L"Lang",

+                  &gEfiGlobalVariableGuid,

+                  NULL,

+                  &Size,

+                  Language

+                  );

+

+  if (EFI_ERROR (Status)) {

+    AsciiStrCpy (Language, "eng");

+  }

+

+  for (Index = 0; Language[Index] != 0; Index++) {

+    //

+    // Bitwise AND ascii value with 0xDF yields an uppercase value.

+    // Sign extend into a unicode value

+    //

+    Lang[Index] = (CHAR16) (Language[Index] & 0xDF);

+  }

+

+  //

+  // Null-terminate the value

+  //

+  Lang[3] = (CHAR16) 0;

+

+  return Status;

+}

+

+

+EFI_STATUS

+AddString (

+  IN      VOID                *StringBuffer,

+  IN      CHAR16              *Language,

+  IN      CHAR16              *String,

+  IN OUT  STRING_REF          *StringToken

+  )

+/*++

+

+Routine Description:

+

+  Add a string to the incoming buffer and return the token and offset data

+  

+Arguments:

+  

+  StringBuffer      - The incoming buffer

+  

+  Language          - Currrent language

+  

+  String            - The string to be added

+  

+  StringToken       - The index where the string placed

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_SUCCESS             - String successfully added to the incoming buffer

+

+--*/

+{

+  EFI_HII_STRING_PACK *StringPack;

+  EFI_HII_STRING_PACK *StringPackBuffer;

+  VOID                *NewBuffer;

+  RELOFST             *PackSource;

+  RELOFST             *PackDestination;

+  UINT8               *Source;

+  UINT8               *Destination;

+  UINTN               Index;

+  BOOLEAN             Finished;

+

+  StringPack  = (EFI_HII_STRING_PACK *) StringBuffer;

+  Finished    = FALSE;

+

+  //

+  // Pre-allocate a buffer sufficient for us to work on.

+  // We will use it as a destination scratch pad to build data on

+  // and when complete shift the data back to the original buffer

+  //

+  NewBuffer = AllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE);

+  if (NewBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  StringPackBuffer = (EFI_HII_STRING_PACK *) NewBuffer;

+

+  //

+  // StringPack is terminated with a length 0 entry

+  //

+  for (; StringPack->Header.Length != 0;) {

+    //

+    // If this stringpack's language is same as CurrentLanguage, use it

+    //

+    if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language, 3) == 0) {

+      //

+      // We have some data in this string pack, copy the string package up to the string data

+      //

+      CopyMem (&StringPackBuffer->Header, &StringPack->Header, sizeof (StringPack));

+

+      //

+      // These are references in the structure to tokens, need to increase them by the space occupied by an additional StringPointer

+      //

+      StringPackBuffer->LanguageNameString = (UINT16) (StringPackBuffer->LanguageNameString + (UINT16) sizeof (RELOFST));

+      StringPackBuffer->PrintableLanguageName = (UINT16) (StringPackBuffer->PrintableLanguageName + (UINT16) sizeof (RELOFST));

+

+      PackSource      = (RELOFST *) (StringPack + 1);

+      PackDestination = (RELOFST *) (StringPackBuffer + 1);

+      for (Index = 0; PackSource[Index] != 0x0000; Index++) {

+        //

+        // Copy the stringpointers from old to new buffer

+        // remember that we are adding a string, so the string offsets will all go up by sizeof (RELOFST)

+        //

+        PackDestination[Index] = (UINT16) (PackDestination[Index] + sizeof (RELOFST));

+      }

+      

+      //

+      // Add a new stringpointer in the new buffer since we are adding a string.  Null terminate it

+      //

+      PackDestination[Index] = (UINT16)(PackDestination[Index-1] + 

+                                        StrSize((CHAR16 *)((CHAR8 *)(StringPack) + PackSource[Index-1])));

+      PackDestination[Index + 1] = (UINT16) 0;

+

+      //

+      // Index is the token value for the new string

+      //

+      *StringToken = (UINT16) Index;

+

+      //

+      // Source now points to the beginning of the old buffer strings

+      // Destination now points to the beginning of the new buffer strings

+      //

+      Source      = (UINT8 *) &PackSource[Index + 1];

+      Destination = (UINT8 *) &PackDestination[Index + 2];

+

+      //

+      // This should copy all the strings from the old buffer to the new buffer

+      //

+      for (; Index != 0; Index--) {

+        //

+        // Copy Source string to destination buffer

+        //

+        StrCpy ((CHAR16 *) Destination, (CHAR16 *) Source);

+

+        //

+        // Adjust the source/destination to the next string location

+        //

+        Destination = Destination + StrSize ((CHAR16 *) Source);

+        Source      = Source + StrSize ((CHAR16 *) Source);

+      }

+      

+      //

+      // This copies the new string to the destination buffer

+      //

+      StrCpy ((CHAR16 *) Destination, (CHAR16 *) String);

+

+      //

+      // Adjust the size of the changed string pack by adding the size of the new string

+      // along with the size of the additional offset entry for the new string

+      //

+      StringPackBuffer->Header.Length = (UINT32) ((UINTN) StringPackBuffer->Header.Length + StrSize (String) + sizeof (RELOFST));

+

+      //

+      // Advance the buffers to point to the next spots.

+      //

+      StringPackBuffer  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPackBuffer->Header.Length);

+      StringPack        = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);

+      Finished          = TRUE;

+      continue;

+    }

+    //

+    // This isn't the language of the stringpack we were asked to add a string to

+    // so we need to copy it to the new buffer.

+    //

+    CopyMem (&StringPackBuffer->Header, &StringPack->Header, StringPack->Header.Length);

+

+    //

+    // Advance the buffers to point to the next spots.

+    //

+    StringPackBuffer  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPack->Header.Length);

+    StringPack        = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);

+  }

+  

+  //

+  // If we didn't copy the new data to a stringpack yet

+  //

+  if (!Finished) {

+    PackDestination = (RELOFST *) (StringPackBuffer + 1);

+    //

+    // Pointing to a new string pack location

+    //

+    StringPackBuffer->Header.Length = (UINT32)

+      (

+        sizeof (EFI_HII_STRING_PACK) -

+        sizeof (EFI_STRING) +

+        sizeof (RELOFST) +

+        sizeof (RELOFST) +

+        StrSize (Language) +

+        StrSize (String)

+      );

+    StringPackBuffer->Header.Type           = EFI_HII_STRING;

+    StringPackBuffer->LanguageNameString    = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);

+    StringPackBuffer->PrintableLanguageName = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);

+    StringPackBuffer->Attributes            = 0;

+    PackDestination[0]                      = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);

+    PackDestination[1]                      = (UINT16) (PackDestination[0] + StrSize (Language));

+    PackDestination[2]                      = (UINT16) 0;

+

+    //

+    // The first string location will be set to destination.  The minimum number of strings

+    // associated with a stringpack will always be token 0 stored as the languagename (e.g. ENG, SPA, etc)

+    // and token 1 as the new string being added and and null entry for the stringpointers

+    //

+    Destination = (UINT8 *) &PackDestination[3];

+

+    //

+    // Copy the language name string to the new buffer

+    //

+    StrCpy ((CHAR16 *) Destination, Language);

+

+    //

+    // Advance the destination to the new empty spot

+    //

+    Destination = Destination + StrSize (Language);

+

+    //

+    // Copy the string to the new buffer

+    //

+    StrCpy ((CHAR16 *) Destination, String);

+

+    //

+    // Since we are starting with a new string pack - we know the new string is token 1

+    //

+    *StringToken = (UINT16) 1;

+  }

+

+  //

+  // Zero out the original buffer and copy the updated data in the new buffer to the old buffer

+  //

+  ZeroMem (StringBuffer, DEFAULT_STRING_BUFFER_SIZE);

+  CopyMem (StringBuffer, NewBuffer, DEFAULT_STRING_BUFFER_SIZE);

+

+  //

+  // Free the newly created buffer since we don't need it anymore

+  //

+  gBS->FreePool (NewBuffer);

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+AddOpCode (

+  IN      VOID                *FormBuffer,

+  IN OUT  VOID                *OpCodeData

+  )

+/*++

+

+Routine Description:

+

+  Add op-code data to the FormBuffer

+  

+Arguments:

+  

+  FormBuffer      - Form buffer to be inserted to

+  

+  OpCodeData      - Op-code data to be inserted

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_SUCCESS             - Op-code data successfully inserted

+

+--*/

+{

+  EFI_HII_PACK_HEADER *NewBuffer;

+  UINT8               *Source;

+  UINT8               *Destination;

+

+  //

+  // Pre-allocate a buffer sufficient for us to work on.

+  // We will use it as a destination scratch pad to build data on

+  // and when complete shift the data back to the original buffer

+  //

+  NewBuffer = AllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE);

+  if (NewBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Source      = (UINT8 *) FormBuffer;

+  Destination = (UINT8 *) NewBuffer;

+

+  //

+  // Copy the IFR Package header to the new buffer

+  //

+  CopyMem (Destination, Source, sizeof (EFI_HII_PACK_HEADER));

+

+  //

+  // Advance Source and Destination to next op-code

+  //

+  Source      = Source + sizeof (EFI_HII_PACK_HEADER);

+  Destination = Destination + sizeof (EFI_HII_PACK_HEADER);

+

+  //

+  // Copy data to the new buffer until we run into the end_form

+  //

+  for (; ((EFI_IFR_OP_HEADER *) Source)->OpCode != EFI_IFR_END_FORM_OP;) {

+    //

+    // If the this opcode is an end_form_set we better be creating and endform

+    // Nonetheless, we will add data before the end_form_set.  This also provides

+    // for interesting behavior in the code we will run, but has no bad side-effects

+    // since we will possibly do a 0 byte copy in this particular end-case.

+    //

+    if (((EFI_IFR_OP_HEADER *) Source)->OpCode == EFI_IFR_END_FORM_SET_OP) {

+      break;

+    }

+

+    //

+    // Copy data to new buffer

+    //

+    CopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);

+

+    //

+    // Adjust Source/Destination to next op-code location

+    //

+    Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;

+    Source      = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;

+  }

+

+  //

+  // Prior to the end_form is where we insert the new op-code data

+  //

+  CopyMem (Destination, OpCodeData, ((EFI_IFR_OP_HEADER *) OpCodeData)->Length);

+  Destination       = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;

+

+  NewBuffer->Length = (UINT32) (NewBuffer->Length + (UINT32) (((EFI_IFR_OP_HEADER *) OpCodeData)->Length));

+

+  //

+  // Copy end-form data to new buffer

+  //

+  CopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);

+

+  //

+  // Adjust Source/Destination to next op-code location

+  //

+  Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;

+  Source      = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;

+

+  //

+  // Copy end-formset data to new buffer

+  //

+  CopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);

+

+  //

+  // Zero out the original buffer and copy the updated data in the new buffer to the old buffer

+  //

+  ZeroMem (FormBuffer, DEFAULT_FORM_BUFFER_SIZE);

+  CopyMem (FormBuffer, NewBuffer, DEFAULT_FORM_BUFFER_SIZE);

+

+  //

+  // Free the newly created buffer since we don't need it anymore

+  //

+  gBS->FreePool (NewBuffer);

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+GetHiiInterface (

+  OUT     EFI_HII_PROTOCOL    **Hii

+  )

+/*++

+

+Routine Description:

+

+  Get the HII protocol interface

+  

+Arguments:

+  

+  Hii     - HII protocol interface

+  

+Returns: 

+

+  Status code

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // There should only be one HII protocol

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  (VOID **) Hii

+                  );

+

+  return Status;;

+}

+

+

+EFI_STATUS

+ExtractDataFromHiiHandle (

+  IN      EFI_HII_HANDLE      HiiHandle,

+  IN OUT  UINT16              *ImageLength,

+  OUT     UINT8               *DefaultImage,

+  OUT     EFI_GUID            *Guid

+  )

+/*++

+

+Routine Description:

+

+  Extract information pertaining to the HiiHandle

+  

+Arguments:

+  

+  HiiHandle       - Hii handle

+  

+  ImageLength     - For input, length of DefaultImage;

+                    For output, length of actually required

+                    

+  DefaultImage    - Image buffer prepared by caller

+  

+  Guid            - Guid information about the form

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_BUFFER_TOO_SMALL    - DefualtImage has no enough ImageLength

+  

+  EFI_SUCCESS             - Successfully extract data from Hii database.

+  

+  

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_HII_PROTOCOL  *Hii;

+  UINTN             DataLength;

+  UINT8             *RawData;

+  UINT8             *OldData;

+  UINTN             Index;

+  UINTN             Temp;

+  UINTN             SizeOfNvStore;

+  UINTN             CachedStart;

+

+  DataLength    = DEFAULT_FORM_BUFFER_SIZE;

+  SizeOfNvStore = 0;

+  CachedStart   = 0;

+

+  Status        = GetHiiInterface (&Hii);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Allocate space for retrieval of IFR data

+  //

+  RawData = AllocateZeroPool (DataLength);

+  if (RawData == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Get all the forms associated with this HiiHandle

+  //

+  Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData);

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (RawData);

+

+    //

+    // Allocate space for retrieval of IFR data

+    //

+    RawData = AllocateZeroPool (DataLength);

+    if (RawData == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    //

+    // Get all the forms associated with this HiiHandle

+    //

+    Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData);

+  }

+

+  OldData = RawData;

+

+  //

+  // Point RawData to the beginning of the form data

+  //

+  RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER));

+

+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    switch (RawData[Index]) {

+    case EFI_IFR_FORM_SET_OP:

+      //

+      // Copy the GUID information from this handle

+      //

+      CopyMem (Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));

+      break;

+

+    case EFI_IFR_ONE_OF_OP:

+    case EFI_IFR_CHECKBOX_OP:

+    case EFI_IFR_NUMERIC_OP:

+    case EFI_IFR_DATE_OP:

+    case EFI_IFR_TIME_OP:

+    case EFI_IFR_PASSWORD_OP:

+    case EFI_IFR_STRING_OP:

+      //

+      // Remember, multiple op-codes may reference the same item, so let's keep a running

+      // marker of what the highest QuestionId that wasn't zero length.  This will accurately

+      // maintain the Size of the NvStore

+      //

+      if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) {

+        Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;

+        if (SizeOfNvStore < Temp) {

+          SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;

+        }

+      }

+    }

+

+    Index = RawData[Index + 1] + Index;

+  }

+    

+  //

+  // Return an error if buffer is too small

+  //

+  if (SizeOfNvStore > *ImageLength) {

+    gBS->FreePool (OldData);

+    *ImageLength = (UINT16) SizeOfNvStore;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  if (DefaultImage != NULL) {

+    ZeroMem (DefaultImage, SizeOfNvStore);

+  }

+

+  //

+  // Copy the default image information to the user's buffer

+  //

+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    switch (RawData[Index]) {

+    case EFI_IFR_ONE_OF_OP:

+      CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId;

+      break;

+

+    case EFI_IFR_ONE_OF_OPTION_OP:

+      if (((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Flags & EFI_IFR_FLAG_DEFAULT) {

+        CopyMem (&DefaultImage[CachedStart], &((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value, 2);

+      }

+      break;

+

+    case EFI_IFR_CHECKBOX_OP:

+      DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId] = ((EFI_IFR_CHECKBOX *) &RawData[Index])->Flags;

+      break;

+

+    case EFI_IFR_NUMERIC_OP:

+      CopyMem (

+        &DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId],

+        &((EFI_IFR_NUMERIC *) &RawData[Index])->Default,

+        2

+        );

+      break;

+

+    }

+

+    Index = RawData[Index + 1] + Index;

+  }

+

+  *ImageLength = (UINT16) SizeOfNvStore;

+

+  //

+  // Free our temporary repository of form data

+  //

+  gBS->FreePool (OldData);

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_HII_HANDLE

+FindHiiHandle (

+  IN OUT EFI_HII_PROTOCOL    **HiiProtocol, OPTIONAL

+  IN     EFI_GUID            *Guid

+  )

+/*++

+

+Routine Description:

+  Finds HII handle for given pack GUID previously registered with the HII.

+

+Arguments:

+  HiiProtocol - pointer to pointer to HII protocol interface. 

+                If NULL, the interface will be found but not returned.

+                If it points to NULL, the interface will be found and 

+                written back to the pointer that is pointed to.

+  Guid        - The GUID of the pack that registered with the HII.

+

+Returns:

+  Handle to the HII pack previously registered by the memory driver.

+

+--*/

+{

+  EFI_STATUS        Status;

+

+  EFI_HII_HANDLE    *HiiHandleBuffer;

+  EFI_HII_HANDLE    HiiHandle;

+  UINT16            HiiHandleBufferLength;

+  UINT32            NumberOfHiiHandles;

+  EFI_GUID          HiiGuid;

+  EFI_HII_PROTOCOL  *HiiProt;

+  UINT32            Index;

+  UINT16            Length;

+

+  HiiHandle = 0;

+  if ((HiiProtocol != NULL) && (*HiiProtocol != NULL)) {

+    //

+    // The protocol has been passed in

+    //

+    HiiProt = *HiiProtocol;

+  } else {

+    gBS->LocateProtocol (

+          &gEfiHiiProtocolGuid,

+          NULL,

+          (VOID **) &HiiProt

+          );

+    if (HiiProt == NULL) {

+      return HiiHandle;

+    }

+

+    if (HiiProtocol != NULL) {

+      //

+      // Return back the HII protocol for the caller as promissed

+      //

+      *HiiProtocol = HiiProt;

+    }

+  }

+  //

+  // Allocate buffer

+  //

+  HiiHandleBufferLength = 10;

+  HiiHandleBuffer       = AllocatePool (HiiHandleBufferLength);

+  ASSERT (HiiHandleBuffer != NULL);

+

+  //

+  // Get the Handles of the packages that were registered with Hii

+  //

+  Status = HiiProt->FindHandles (

+                      HiiProt,

+                      &HiiHandleBufferLength,

+                      HiiHandleBuffer

+                      );

+

+  //

+  // Get a bigger bugffer if this one is to small, and try again

+  //

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+

+    gBS->FreePool (HiiHandleBuffer);

+

+    HiiHandleBuffer = AllocatePool (HiiHandleBufferLength);

+    ASSERT (HiiHandleBuffer != NULL);

+

+    Status = HiiProt->FindHandles (

+                        HiiProt,

+                        &HiiHandleBufferLength,

+                        HiiHandleBuffer

+                        );

+  }

+

+  if (EFI_ERROR (Status)) {

+    goto lbl_exit;

+  }

+

+  NumberOfHiiHandles = HiiHandleBufferLength / sizeof (EFI_HII_HANDLE);

+

+  //

+  // Iterate Hii handles and look for the one that matches our Guid

+  //

+  for (Index = 0; Index < NumberOfHiiHandles; Index++) {

+

+    Length = 0;

+    ExtractDataFromHiiHandle (HiiHandleBuffer[Index], &Length, NULL, &HiiGuid);

+

+    if (CompareGuid (&HiiGuid, Guid)) {

+

+      HiiHandle = HiiHandleBuffer[Index];

+      break;

+    }

+  }

+

+lbl_exit:

+  gBS->FreePool (HiiHandleBuffer);

+  return HiiHandle;

+}

+

+

+EFI_STATUS

+ValidateDataFromHiiHandle (

+  IN      EFI_HII_HANDLE      HiiHandle,

+  OUT     BOOLEAN             *Results

+  )

+/*++

+

+Routine Description:

+

+  Validate that the data associated with the HiiHandle in NVRAM is within

+  the reasonable parameters for that FormSet.  Values for strings and passwords

+  are not verified due to their not having the equivalent of valid range settings.

+  

+Arguments:

+

+  HiiHandle -   Handle of the HII database entry to query

+

+  Results -     If return Status is EFI_SUCCESS, Results provides valid data

+                TRUE  = NVRAM Data is within parameters

+                FALSE = NVRAM Data is NOT within parameters

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate

+  

+  EFI_SUCCESS               - Data successfully validated

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_HII_PROTOCOL  *Hii;

+  EFI_GUID          Guid;

+  UINT8             *RawData;

+  UINT8             *OldData;

+  UINTN             RawDataLength;

+  UINT8             *VariableData;

+  UINTN             Index;

+  UINTN             Temp;

+  UINTN             SizeOfNvStore;

+  UINTN             CachedStart;

+  BOOLEAN           GotMatch;

+

+  RawDataLength = DEFAULT_FORM_BUFFER_SIZE;

+  SizeOfNvStore = 0;

+  CachedStart   = 0;

+  GotMatch      = FALSE;

+  *Results      = TRUE;

+

+  Status        = GetHiiInterface (&Hii);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Allocate space for retrieval of IFR data

+  //

+  RawData = AllocateZeroPool (RawDataLength);

+  if (RawData == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Get all the forms associated with this HiiHandle

+  //

+  Status = Hii->GetForms (Hii, HiiHandle, 0, &RawDataLength, RawData);

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (RawData);

+

+    //

+    // Allocate space for retrieval of IFR data

+    //

+    RawData = AllocateZeroPool (RawDataLength);

+    if (RawData == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    //

+    // Get all the forms associated with this HiiHandle

+    //

+    Status = Hii->GetForms (Hii, HiiHandle, 0, &RawDataLength, RawData);

+  }

+

+  OldData = RawData;

+

+  //

+  // Point RawData to the beginning of the form data

+  //

+  RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER));

+

+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    if (RawData[Index] == EFI_IFR_FORM_SET_OP) {

+      CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));

+      break;

+    }

+

+    Index = RawData[Index + 1] + Index;

+  }

+

+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    switch (RawData[Index]) {

+    case EFI_IFR_FORM_SET_OP:

+      break;

+

+    case EFI_IFR_ONE_OF_OP:

+    case EFI_IFR_CHECKBOX_OP:

+    case EFI_IFR_NUMERIC_OP:

+    case EFI_IFR_DATE_OP:

+    case EFI_IFR_TIME_OP:

+    case EFI_IFR_PASSWORD_OP:

+    case EFI_IFR_STRING_OP:

+      //

+      // Remember, multiple op-codes may reference the same item, so let's keep a running

+      // marker of what the highest QuestionId that wasn't zero length.  This will accurately

+      // maintain the Size of the NvStore

+      //

+      if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) {

+        Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;

+        if (SizeOfNvStore < Temp) {

+          SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;

+        }

+      }

+    }

+

+    Index = RawData[Index + 1] + Index;

+  }

+    

+  //

+  // Allocate memory for our File Form Tags

+  //

+  VariableData = AllocateZeroPool (SizeOfNvStore);

+  if (VariableData == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gRT->GetVariable (

+                  (CHAR16 *) L"Setup",

+                  &Guid,

+                  NULL,

+                  &SizeOfNvStore,

+                  (VOID *) VariableData

+                  );

+

+  if (EFI_ERROR (Status)) {

+

+    //

+    // If there is a variable that exists already and it is larger than what we calculated the

+    // storage needs to be, we must assume the variable size from GetVariable is correct and not

+    // allow the truncation of the variable.  It is very possible that the user who created the IFR

+    // we are cracking is not referring to a variable that was in a previous map, however we cannot

+    // allow it's truncation.

+    //

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      //

+      // Free the buffer that was allocated that was too small

+      //

+      gBS->FreePool (VariableData);

+

+      VariableData = AllocatePool (SizeOfNvStore);

+      if (VariableData == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      Status = gRT->GetVariable (

+                      (CHAR16 *) L"Setup",

+                      &Guid,

+                      NULL,

+                      &SizeOfNvStore,

+                      (VOID *) VariableData

+                      );

+    }

+  }

+

+  //

+  // Walk through the form and see that the variable data it refers to is ok.

+  // This allows for the possibility of stale (obsoleted) data in the variable

+  // can be overlooked without causing an error

+  //

+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    switch (RawData[Index]) {

+    case EFI_IFR_ONE_OF_OP:

+      //

+      // A one_of has no data, its the option that does - cache the storage Id

+      //

+      CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId;

+      break;

+

+    case EFI_IFR_ONE_OF_OPTION_OP:

+      //

+      // A one_of_option can be any value

+      //

+      if (VariableData[CachedStart] == ((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value) {

+        GotMatch = TRUE;

+      }

+      break;

+

+    case EFI_IFR_END_ONE_OF_OP:

+      //

+      // At this point lets make sure that the data value in the NVRAM matches one of the options

+      //

+      if (!GotMatch) {

+        *Results = FALSE;

+        return EFI_SUCCESS;

+      }

+      break;

+

+    case EFI_IFR_CHECKBOX_OP:

+      //

+      // A checkbox is a boolean, so 0 and 1 are valid

+      // Remember, QuestionId corresponds to the offset location of the data in the variable

+      //

+      if (VariableData[((EFI_IFR_CHECKBOX *) &RawData[Index])->QuestionId] > 1) {

+        *Results = FALSE;

+        return EFI_SUCCESS;

+      }

+      break;

+

+    case EFI_IFR_NUMERIC_OP:

+        if ((VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] < ((EFI_IFR_NUMERIC *)&RawData[Index])->Minimum) ||

+            (VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] > ((EFI_IFR_NUMERIC *)&RawData[Index])->Maximum)) {

+        *Results = FALSE;

+        return EFI_SUCCESS;

+      }

+      break;

+

+    }

+

+    Index = RawData[Index + 1] + Index;

+  }

+

+  //

+  // Free our temporary repository of form data

+  //

+  gBS->FreePool (OldData);

+  gBS->FreePool (VariableData);

+

+  return EFI_SUCCESS;

+}

+

diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrOnTheFly.c b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrOnTheFly.c
new file mode 100644
index 0000000..e3d1040
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrOnTheFly.c
@@ -0,0 +1,972 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  IfrOnTheFly.c

+

+Abstract:

+

+  Library Routines to create IFR on-the-fly

+

+Revision History:

+

+--*/

+

+EFI_STATUS

+CreateFormSet (

+  IN      CHAR16              *FormSetTitle,

+  IN      EFI_GUID            *Guid,

+  IN      UINT8               Class,

+  IN      UINT8               SubClass,

+  IN OUT  VOID                **FormBuffer,

+  IN OUT  VOID                **StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a formset

+  

+Arguments:

+  

+  FormSetTitle        - Title of formset

+  

+  Guid                - Guid of formset

+  

+  Class               - Class of formset

+  

+  SubClass            - Sub class of formset

+  

+  FormBuffer          - Pointer of the formset created

+  

+  StringBuffer        - Pointer of FormSetTitile string created

+  

+Returns: 

+

+  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate

+  

+  EFI_SUCCESS             - Formset successfully created

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_HII_IFR_PACK      IfrPack;

+  EFI_IFR_FORM_SET      FormSet;

+  EFI_IFR_END_FORM_SET  EndFormSet;

+  UINT8                 *Destination;

+  CHAR16                CurrentLanguage[4];

+  STRING_REF            StringToken;

+

+  //

+  // Pre-allocate a buffer sufficient for us to work from.

+  //

+  FormBuffer = AllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE);

+  if (FormBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Pre-allocate a buffer sufficient for us to work from.

+  //

+  StringBuffer = AllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE);

+  if (StringBuffer == NULL) {

+    gBS->FreePool (FormBuffer);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add the FormSetTitle to the string buffer and get the StringToken

+  //

+  Status = AddString (*StringBuffer, CurrentLanguage, FormSetTitle, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Initialize the Ifr Package header data

+  //

+  IfrPack.Header.Length = sizeof (EFI_HII_PACK_HEADER) + sizeof (EFI_IFR_FORM_SET) + sizeof (EFI_IFR_END_FORM_SET);

+  IfrPack.Header.Type   = EFI_HII_IFR;

+

+  //

+  // Initialize FormSet with the appropriate information

+  //

+  FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;

+  FormSet.Header.Length = sizeof (EFI_IFR_FORM_SET);

+  FormSet.FormSetTitle  = StringToken;

+  FormSet.Class         = Class;

+  FormSet.SubClass      = SubClass;

+  CopyMem (&FormSet.Guid, Guid, sizeof (EFI_GUID));

+

+  //

+  // Initialize the end formset data

+  //

+  EndFormSet.Header.Length  = sizeof (EFI_IFR_END_FORM_SET);

+  EndFormSet.Header.OpCode  = EFI_IFR_END_FORM_SET_OP;

+

+  Destination               = (UINT8 *) *FormBuffer;

+

+  //

+  // Copy the formset/endformset data to the form buffer

+  //

+  CopyMem (Destination, &IfrPack, sizeof (EFI_HII_PACK_HEADER));

+

+  Destination = Destination + sizeof (EFI_HII_PACK_HEADER);

+

+  CopyMem (Destination, &FormSet, sizeof (EFI_IFR_FORM_SET));

+

+  Destination = Destination + sizeof (EFI_IFR_FORM_SET);

+

+  CopyMem (Destination, &EndFormSet, sizeof (EFI_IFR_END_FORM_SET));

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateForm (

+  IN      CHAR16              *FormTitle,

+  IN      UINT16              FormId,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a form

+  

+Arguments:

+  

+  FormTitle       - Title of the form

+  

+  FormId          - Id of the form

+  

+  FormBuffer          - Pointer of the form created

+  

+  StringBuffer        - Pointer of FormTitil string created

+  

+Returns: 

+

+  EFI_SUCCESS     - Form successfully created

+

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_IFR_FORM      Form;

+  EFI_IFR_END_FORM  EndForm;

+  CHAR16            CurrentLanguage[4];

+  STRING_REF        StringToken;

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  Status = AddString (StringBuffer, CurrentLanguage, FormTitle, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Form.Header.OpCode  = EFI_IFR_FORM_OP;

+  Form.Header.Length  = sizeof (EFI_IFR_FORM);

+  Form.FormId         = FormId;

+  Form.FormTitle      = StringToken;

+

+  Status              = AddOpCode (FormBuffer, &Form);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  EndForm.Header.OpCode = EFI_IFR_END_FORM_OP;

+  EndForm.Header.Length = sizeof (EFI_IFR_END_FORM);

+

+  Status                = AddOpCode (FormBuffer, &EndForm);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateSubTitle (

+  IN      CHAR16              *SubTitle,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a SubTitle

+  

+Arguments:

+  

+  SubTitle        - Sub title to be created

+  

+  FormBuffer      - Where this subtitle to add to

+  

+  StringBuffer    - String buffer created for subtitle

+  

+Returns: 

+

+  EFI_SUCCESS     - Subtitle successfully created

+

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_IFR_SUBTITLE  Subtitle;

+  CHAR16            CurrentLanguage[4];

+  STRING_REF        StringToken;

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  Status = AddString (StringBuffer, CurrentLanguage, SubTitle, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Subtitle.Header.OpCode  = EFI_IFR_SUBTITLE_OP;

+  Subtitle.Header.Length  = sizeof (EFI_IFR_SUBTITLE);

+  Subtitle.SubTitle       = StringToken;

+

+  Status                  = AddOpCode (FormBuffer, &Subtitle);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateText (

+  IN      CHAR16              *String,

+  IN      CHAR16              *String2,

+  IN      CHAR16              *String3,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a line of text

+  

+Arguments:

+  

+  String          - First string of the text

+  

+  String2         - Second string of the text

+  

+  String3         - Help string of the text

+  

+  Flags           - Flag of the text

+  

+  Key             - Key of the text

+  

+  FormBuffer      - The form where this text adds to

+  

+  StringBuffer    - String buffer created for String, String2 and String3

+  

+Returns: 

+

+  EFI_SUCCESS     - Text successfully created

+

+--*/

+{

+  EFI_STATUS    Status;

+  EFI_IFR_TEXT  Text;

+  CHAR16        CurrentLanguage[4];

+  STRING_REF    StringToken;

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add first string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, String, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Text.Header.OpCode  = EFI_IFR_TEXT_OP;

+  Text.Header.Length  = sizeof (EFI_IFR_TEXT);

+  Text.Text           = StringToken;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, String2, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Text.TextTwo  = StringToken;

+

+  Text.Flags    = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);

+  Text.Key      = Key;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, String3, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Text.Help = StringToken;

+

+  Status    = AddOpCode (FormBuffer, &Text);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateGoto (

+  IN      UINT16              FormId,

+  IN      CHAR16              *Prompt,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a hyperlink

+  

+Arguments:

+  

+  FormId        - Form ID of the hyperlink

+  

+  Prompt        - Prompt of the hyperlink

+  

+  FormBuffer    - The form where this hyperlink adds to

+  

+  StringBuffer  - String buffer created for Prompt

+  

+Returns: 

+

+  EFI_SUCCESS     - Hyperlink successfully created

+

+--*/

+{

+  EFI_STATUS  Status;

+  EFI_IFR_REF Hyperlink;

+  CHAR16      CurrentLanguage[4];

+  STRING_REF  StringToken;

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Hyperlink.Header.OpCode = EFI_IFR_REF_OP;

+  Hyperlink.Header.Length = sizeof (EFI_IFR_REF);

+  Hyperlink.FormId        = FormId;

+  Hyperlink.Prompt        = StringToken;

+

+  Status                  = AddOpCode (FormBuffer, &Hyperlink);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateOneOf (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a one-of question with a set of options to choose from.  The

+  OptionsList is a pointer to a null-terminated list of option descriptions.

+  

+Arguments:

+  

+  QuestionId      - Question ID of the one-of box

+  

+  DataWidth       - DataWidth of the one-of box

+  

+  Prompt          - Prompt of the one-of box

+  

+  Help            - Help of the one-of box

+  

+  OptionsList     - Each string in it is an option of the one-of box

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - The form where this one-of box adds to

+  

+  StringBuffer    - String buffer created for Prompt, Help and Option strings

+  

+Returns: 

+

+  EFI_DEVICE_ERROR    - DataWidth > 2

+

+  EFI_SUCCESS         - One-Of box successfully created.

+

+--*/

+{

+  EFI_STATUS            Status;

+  UINTN                 Index;

+  EFI_IFR_ONE_OF        OneOf;

+  EFI_IFR_ONE_OF_OPTION OneOfOption;

+  EFI_IFR_END_ONE_OF    EndOneOf;

+  CHAR16                CurrentLanguage[4];

+  STRING_REF            StringToken;

+

+  //

+  // We do not create op-code storage widths for one-of in excess of 16 bits for now

+  //

+  if (DataWidth > 2) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add first string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;

+  OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);

+  OneOf.QuestionId    = QuestionId;

+  OneOf.Width         = DataWidth;

+  OneOf.Prompt        = StringToken;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  OneOf.Help  = StringToken;

+

+  Status      = AddOpCode (FormBuffer, &OneOf);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < OptionCount; Index++) {

+    OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;

+    OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);

+

+    //

+    // Add string and get token back

+    //

+    Status              = AddString (StringBuffer, CurrentLanguage, OptionsList[Index].OptionString, &StringToken);

+

+    OneOfOption.Option  = StringToken;

+    OneOfOption.Value   = OptionsList[Index].Value;

+    OneOfOption.Flags   = (UINT8) (OptionsList[Index].Flags | EFI_IFR_FLAG_CREATED);

+    OneOfOption.Key     = OptionsList[Index].Key;

+

+    Status              = AddOpCode (FormBuffer, &OneOfOption);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  EndOneOf.Header.Length  = sizeof (EFI_IFR_END_ONE_OF);

+  EndOneOf.Header.OpCode  = EFI_IFR_END_ONE_OF_OP;

+

+  Status                  = AddOpCode (FormBuffer, &EndOneOf);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CreateOrderedList (

+  IN      UINT16              QuestionId,

+  IN      UINT8               MaxEntries,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a one-of question with a set of options to choose from.  The

+  OptionsList is a pointer to a null-terminated list of option descriptions.

+  

+Arguments:

+  

+  QuestionId      - Question ID of the ordered list

+  

+  MaxEntries      - MaxEntries of the ordered list

+  

+  Prompt          - Prompt of the ordered list

+  

+  Help            - Help of the ordered list

+  

+  OptionsList     - Each string in it is an option of the ordered list

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - The form where this ordered list adds to

+  

+  StringBuffer    - String buffer created for Prompt, Help and Option strings

+  

+Returns: 

+

+  EFI_SUCCESS     - Ordered list successfully created.

+

+--*/

+{

+  EFI_STATUS            Status;

+  UINTN                 Index;

+  EFI_IFR_ORDERED_LIST  OrderedList;

+  EFI_IFR_ONE_OF_OPTION OrderedListOption;

+  EFI_IFR_END_ONE_OF    EndOrderedList;

+  CHAR16                CurrentLanguage[4];

+  STRING_REF            StringToken;

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add first string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;

+  OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);

+  OrderedList.QuestionId    = QuestionId;

+  OrderedList.MaxEntries    = MaxEntries;

+  OrderedList.Prompt        = StringToken;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  OrderedList.Help  = StringToken;

+

+  Status            = AddOpCode (FormBuffer, &OrderedList);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < OptionCount; Index++) {

+    OrderedListOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;

+    OrderedListOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);

+

+    //

+    // Add string and get token back

+    //

+    Status                    = AddString (StringBuffer, CurrentLanguage, OptionsList[Index].OptionString, &StringToken);

+

+    OrderedListOption.Option  = StringToken;

+    OrderedListOption.Value   = OptionsList[Index].Value;

+    OrderedListOption.Flags   = (UINT8) (OptionsList[Index].Flags | EFI_IFR_FLAG_CREATED);

+    OrderedListOption.Key     = OptionsList[Index].Key;

+

+    Status                    = AddOpCode (FormBuffer, &OrderedListOption);

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  EndOrderedList.Header.Length  = sizeof (EFI_IFR_END_ONE_OF);

+  EndOrderedList.Header.OpCode  = EFI_IFR_END_ONE_OF_OP;

+

+  Status                        = AddOpCode (FormBuffer, &EndOrderedList);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateCheckBox (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      UINT8               Flags,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a checkbox

+  

+Arguments:

+  

+  QuestionId      - Question ID of the check box

+  

+  DataWidth       - DataWidth of the check box

+  

+  Prompt          - Prompt of the check box

+  

+  Help            - Help of the check box

+  

+  Flags           - Flags of the check box

+  

+  FormBuffer      - The form where this check box adds to

+  

+  StringBuffer    - String buffer created for Prompt and Help.

+  

+Returns: 

+

+  EFI_DEVICE_ERROR    - DataWidth > 1

+

+  EFI_SUCCESS         - Check box successfully created

+

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_IFR_CHECKBOX  CheckBox;

+  CHAR16            CurrentLanguage[4];

+  STRING_REF        StringToken;

+

+  //

+  // We do not create op-code storage widths for checkbox in excess of 8 bits for now

+  //

+  if (DataWidth > 1) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add first string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  CheckBox.Header.OpCode  = EFI_IFR_CHECKBOX_OP;

+  CheckBox.Header.Length  = sizeof (EFI_IFR_CHECKBOX);

+  CheckBox.QuestionId     = QuestionId;

+  CheckBox.Width          = DataWidth;

+  CheckBox.Prompt         = StringToken;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  CheckBox.Help   = StringToken;

+  CheckBox.Flags  = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);

+

+  Status          = AddOpCode (FormBuffer, &CheckBox);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateNumeric (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      UINT16              Minimum,

+  IN      UINT16              Maximum,

+  IN      UINT16              Step,

+  IN      UINT16              Default,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a numeric

+  

+Arguments:

+  

+  QuestionId      - Question ID of the numeric

+  

+  DataWidth       - DataWidth of the numeric

+  

+  Prompt          - Prompt of the numeric

+  

+  Help            - Help of the numeric

+  

+  Minimum         - Minumun boundary of the numeric

+  

+  Maximum         - Maximum boundary of the numeric

+  

+  Step            - Step of the numeric

+  

+  Default         - Default value

+  

+  Flags           - Flags of the numeric

+  

+  Key             - Key of the numeric

+  

+  FormBuffer      - The form where this numeric adds to

+  

+  StringBuffer    - String buffer created for Prompt and Help.

+  

+Returns: 

+

+  EFI_DEVICE_ERROR      - DataWidth > 2

+  

+  EFI_SUCCESS           - Numeric is successfully created

+

+--*/

+{

+  EFI_STATUS      Status;

+  EFI_IFR_NUMERIC Numeric;

+  CHAR16          CurrentLanguage[4];

+  STRING_REF      StringToken;

+

+  //

+  // We do not create op-code storage widths for numerics in excess of 16 bits for now

+  //

+  if (DataWidth > 2) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add first string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;

+  Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);

+  Numeric.QuestionId    = QuestionId;

+  Numeric.Width         = DataWidth;

+  Numeric.Prompt        = StringToken;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Numeric.Help    = StringToken;

+  Numeric.Minimum = Minimum;

+  Numeric.Maximum = Maximum;

+  Numeric.Step    = Step;

+  Numeric.Default = Default;

+  Numeric.Flags   = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);

+  Numeric.Key     = Key;

+

+  Status          = AddOpCode (FormBuffer, &Numeric);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateString (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      CHAR16              *Prompt,

+  IN      CHAR16              *Help,

+  IN      UINT8               MinSize,

+  IN      UINT8               MaxSize,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer,

+  IN OUT  VOID                *StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a string

+  

+Arguments:

+  

+  QuestionId      - Question ID of the string

+  

+  DataWidth       - DataWidth of the string

+  

+  Prompt          - Prompt of the string

+  

+  Help            - Help of the string

+  

+  MinSize         - Min size boundary of the string

+  

+  MaxSize         - Max size boundary of the string

+    

+  Flags           - Flags of the string

+  

+  Key             - Key of the string

+  

+  FormBuffer      - The form where this string adds to

+  

+  StringBuffer    - String buffer created for Prompt and Help.

+  

+Returns: 

+

+  EFI_SUCCESS     - String successfully created.

+

+--*/

+{

+  EFI_STATUS      Status;

+  EFI_IFR_STRING  String;

+  CHAR16          CurrentLanguage[4];

+  STRING_REF      StringToken;

+

+  //

+  // Obtain current language value

+  //

+  GetCurrentLanguage (CurrentLanguage);

+

+  //

+  // Add first string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  String.Header.OpCode  = EFI_IFR_STRING_OP;

+  String.Header.Length  = sizeof (EFI_IFR_STRING);

+  String.QuestionId     = QuestionId;

+  String.Width          = DataWidth;

+  String.Prompt         = StringToken;

+

+  //

+  // Add second string, get first string's token

+  //

+  Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  String.Help     = StringToken;

+  String.MinSize  = MinSize;

+  String.MaxSize  = MaxSize;

+  String.Flags    = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);

+  String.Key      = Key;

+

+  Status          = AddOpCode (FormBuffer, &String);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrOpCodeCreation.c b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrOpCodeCreation.c
new file mode 100644
index 0000000..6fb2be7
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrOpCodeCreation.c
@@ -0,0 +1,613 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  IfrOpCodeCreation.c

+

+Abstract:

+

+  Library Routines to create IFR independent of string data - assume tokens already exist

+  Primarily to be used for exporting op-codes at a label in pre-defined forms.

+

+Revision History:

+

+--*/

+

+EFI_STATUS

+CreateSubTitleOpCode (

+  IN      STRING_REF          StringToken,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a SubTitle opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+  

+  StringToken     - StringToken of the subtitle

+  

+  FormBuffer      - Output of subtitle as a form

+  

+Returns: 

+

+  EFI_SUCCESS     - Subtitle created to be a form

+

+--*/

+{

+  EFI_IFR_SUBTITLE  Subtitle;

+

+  Subtitle.Header.OpCode  = EFI_IFR_SUBTITLE_OP;

+  Subtitle.Header.Length  = sizeof (EFI_IFR_SUBTITLE);

+  Subtitle.SubTitle       = StringToken;

+

+  CopyMem (FormBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateTextOpCode (

+  IN      STRING_REF          StringToken,

+  IN      STRING_REF          StringTokenTwo,

+  IN      STRING_REF          StringTokenThree,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a Text opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+  

+  StringToken               - First string token of the text

+  

+  StringTokenTwo            - Second string token of the text

+  

+  StringTokenThree          - Help string token of the text

+  

+  Flags                     - Flag of the text

+  

+  Key                       - Key of the text

+  

+  FormBuffer                - Output of text as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - Text created to be a form

+

+--*/

+{

+  EFI_IFR_TEXT  Text;

+

+  Text.Header.OpCode  = EFI_IFR_TEXT_OP;

+  Text.Header.Length  = sizeof (EFI_IFR_TEXT);

+  Text.Text           = StringToken;

+

+  Text.TextTwo        = StringTokenTwo;

+  Text.Help           = StringTokenThree;

+  Text.Flags          = Flags;

+  Text.Key            = Key;

+

+  CopyMem (FormBuffer, &Text, sizeof (EFI_IFR_TEXT));

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateGotoOpCode (

+  IN      UINT16              FormId,

+  IN      STRING_REF          StringToken,

+  IN      STRING_REF          StringTokenTwo,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a hyperlink opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+  

+  FormId          - Form ID of the hyperlink

+  

+  StringToken     - Prompt string token of the hyperlink

+  

+  StringTokenTwo  - Help string token of the hyperlink

+  

+  Flags           - Flags of the hyperlink

+  

+  Key             - Key of the hyperlink

+  

+  FormBuffer      - Output of hyperlink as a form

+  

+Returns: 

+

+  EFI_SUCCESS   - Hyperlink created to be a form

+

+--*/

+{

+  EFI_IFR_REF Hyperlink;

+

+  Hyperlink.Header.OpCode = EFI_IFR_REF_OP;

+  Hyperlink.Header.Length = sizeof (EFI_IFR_REF);

+  Hyperlink.FormId        = FormId;

+  Hyperlink.Prompt        = StringToken;

+  Hyperlink.Help          = StringTokenTwo;

+  Hyperlink.Key           = Key;

+  Hyperlink.Flags         = Flags;

+

+  CopyMem (FormBuffer, &Hyperlink, sizeof (EFI_IFR_REF));

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateOneOfOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a one-of opcode with a set of option op-codes to choose from independent of string creation.

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+

+  OptionsList is a pointer to a null-terminated list of option descriptions.  Ensure that OptionsList[x].StringToken

+  has been filled in since this routine will not generate StringToken values.

+  

+Arguments:

+  

+  QuestionId      - Question ID of the one-of box

+  

+  DataWidth       - DataWidth of the one-of box

+  

+  PromptToken     - Prompt string token of the one-of box

+  

+  HelpToken       - Help string token of the one-of box

+  

+  OptionsList     - Each string in it is an option of the one-of box

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - Output of One-Of box as a form

+  

+Returns: 

+

+  EFI_SUCCESS         - One-Of box created to be a form

+  

+  EFI_DEVICE_ERROR    - DataWidth > 2

+

+--*/

+{

+  UINTN                 Index;

+  EFI_IFR_ONE_OF        OneOf;

+  EFI_IFR_ONE_OF_OPTION OneOfOption;

+  EFI_IFR_END_ONE_OF    EndOneOf;

+  UINT8                 *LocalBuffer;

+

+  //

+  // We do not create op-code storage widths for one-of in excess of 16 bits for now

+  //

+  if (DataWidth > 2) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;

+  OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);

+  OneOf.QuestionId    = QuestionId;

+  OneOf.Width         = DataWidth;

+  OneOf.Prompt        = PromptToken;

+

+  OneOf.Help          = HelpToken;

+

+  LocalBuffer         = (UINT8 *) FormBuffer;

+

+  CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));

+

+  LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ONE_OF));

+

+  for (Index = 0; Index < OptionCount; Index++) {

+    OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;

+    OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);

+

+    OneOfOption.Option        = OptionsList[Index].StringToken;

+    OneOfOption.Value         = OptionsList[Index].Value;

+    OneOfOption.Flags         = OptionsList[Index].Flags;

+    OneOfOption.Key           = OptionsList[Index].Key;

+

+    CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));

+

+    LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ONE_OF_OPTION));

+  }

+

+  EndOneOf.Header.Length  = sizeof (EFI_IFR_END_ONE_OF);

+  EndOneOf.Header.OpCode  = EFI_IFR_END_ONE_OF_OP;

+

+  CopyMem (LocalBuffer, &EndOneOf, sizeof (EFI_IFR_END_ONE_OF));

+

+  LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_END_ONE_OF));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CreateOrderedListOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               MaxEntries,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      IFR_OPTION          *OptionsList,

+  IN      UINTN               OptionCount,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a ordered list opcode with a set of option op-codes to choose from independent of string creation.

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+

+  OptionsList is a pointer to a null-terminated list of option descriptions.  Ensure that OptionsList[x].StringToken

+  has been filled in since this routine will not generate StringToken values.

+  

+Arguments:

+  

+  QuestionId      - Question ID of the ordered list

+  

+  MaxEntries      - MaxEntries of the ordered list

+  

+  PromptToken     - Prompt string token of the ordered list

+  

+  HelpToken       - Help string token of the ordered list

+  

+  OptionsList     - Each string in it is an option of the ordered list

+  

+  OptionCount     - Option string count

+  

+  FormBuffer      - Output of ordered list as a form

+  

+Returns: 

+

+  EFI_SUCCESS     - Ordered list created to be a form

+

+--*/

+{

+  UINTN                 Index;

+  EFI_IFR_ORDERED_LIST  OrderedList;

+  EFI_IFR_ONE_OF_OPTION OrderedListOption;

+  EFI_IFR_END_ONE_OF    EndOrderedList;

+  UINT8                 *LocalBuffer;

+

+  OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;

+  OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);

+  OrderedList.QuestionId    = QuestionId;

+  OrderedList.MaxEntries    = MaxEntries;

+  OrderedList.Prompt        = PromptToken;

+

+  OrderedList.Help          = HelpToken;

+

+  LocalBuffer               = (UINT8 *) FormBuffer;

+

+  CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));

+

+  LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ORDERED_LIST));

+

+  for (Index = 0; Index < OptionCount; Index++) {

+    OrderedListOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;

+    OrderedListOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);

+

+    OrderedListOption.Option        = OptionsList[Index].StringToken;

+    OrderedListOption.Value         = OptionsList[Index].Value;

+    OrderedListOption.Flags         = OptionsList[Index].Flags;

+    OrderedListOption.Key           = OptionsList[Index].Key;

+

+    CopyMem (LocalBuffer, &OrderedListOption, sizeof (EFI_IFR_ONE_OF_OPTION));

+

+    LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ONE_OF_OPTION));

+  }

+

+  EndOrderedList.Header.Length  = sizeof (EFI_IFR_END_ONE_OF);

+  EndOrderedList.Header.OpCode  = EFI_IFR_END_ONE_OF_OP;

+

+  CopyMem (LocalBuffer, &EndOrderedList, sizeof (EFI_IFR_END_ONE_OF));

+

+  LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_END_ONE_OF));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CreateCheckBoxOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a checkbox opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+  

+  QuestionId      - Question ID of the check box

+  

+  DataWidth       - DataWidth of the check box

+  

+  PromptToken     - Prompt string token of the check box

+  

+  HelpToken       - Help string token of the check box

+  

+  Flags           - Flags of the check box

+  

+  Key             - Key of the check box

+  

+  FormBuffer      - Output of the check box as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - Checkbox created to be a form

+  

+  EFI_DEVICE_ERROR  - DataWidth > 1

+

+--*/

+{

+  EFI_IFR_CHECKBOX  CheckBox;

+

+  //

+  // We do not create op-code storage widths for checkbox in excess of 8 bits for now

+  //

+  if (DataWidth > 1) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  CheckBox.Header.OpCode  = EFI_IFR_CHECKBOX_OP;

+  CheckBox.Header.Length  = sizeof (EFI_IFR_CHECKBOX);

+  CheckBox.QuestionId     = QuestionId;

+  CheckBox.Width          = DataWidth;

+  CheckBox.Prompt         = PromptToken;

+

+  CheckBox.Help           = HelpToken;

+  CheckBox.Flags          = Flags;

+  CheckBox.Key            = Key;

+

+  CopyMem (FormBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateNumericOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      UINT16              Minimum,

+  IN      UINT16              Maximum,

+  IN      UINT16              Step,

+  IN      UINT16              Default,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a numeric opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+  

+  QuestionId      - Question ID of the numeric

+  

+  DataWidth       - DataWidth of the numeric

+  

+  PromptToken     - Prompt string token of the numeric

+  

+  HelpToken       - Help string token of the numeric

+  

+  Minimum         - Minumun boundary of the numeric

+  

+  Maximum         - Maximum boundary of the numeric

+  

+  Step            - Step of the numeric

+  

+  Default         - Default value of the numeric

+  

+  Flags           - Flags of the numeric

+  

+  Key             - Key of the numeric

+  

+  FormBuffer      - Output of the numeric as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - The numeric created to be a form.

+  

+  EFI_DEVICE_ERROR  - DataWidth > 2

+

+--*/

+{

+  EFI_IFR_NUMERIC Numeric;

+

+  //

+  // We do not create op-code storage widths for numerics in excess of 16 bits for now

+  //

+  if (DataWidth > 2) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;

+  Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);

+  Numeric.QuestionId    = QuestionId;

+  Numeric.Width         = DataWidth;

+  Numeric.Prompt        = PromptToken;

+

+  Numeric.Help          = HelpToken;

+  Numeric.Minimum       = Minimum;

+  Numeric.Maximum       = Maximum;

+  Numeric.Step          = Step;

+  Numeric.Default       = Default;

+  Numeric.Flags         = Flags;

+  Numeric.Key           = Key;

+

+  CopyMem (FormBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateStringOpCode (

+  IN      UINT16              QuestionId,

+  IN      UINT8               DataWidth,

+  IN      STRING_REF          PromptToken,

+  IN      STRING_REF          HelpToken,

+  IN      UINT8               MinSize,

+  IN      UINT8               MaxSize,

+  IN      UINT8               Flags,

+  IN      UINT16              Key,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a numeric opcode independent of string creation

+  This is used primarily by users who need to create just one particular valid op-code and the string

+  data will be assumed to exist in the HiiDatabase already.  (Useful when exporting op-codes at a label

+  location to pre-defined forms in HII)

+  

+Arguments:

+  

+  QuestionId      - Question ID of the string

+  

+  DataWidth       - DataWidth of the string

+  

+  PromptToken     - Prompt token of the string

+  

+  HelpToken       - Help token of the string

+  

+  MinSize         - Min size boundary of the string

+  

+  MaxSize         - Max size boundary of the string

+    

+  Flags           - Flags of the string

+  

+  Key             - Key of the string

+  

+  FormBuffer      - Output of the string as a form

+  

+Returns: 

+

+  EFI_SUCCESS       - String created to be a form.

+

+--*/

+{

+  EFI_IFR_STRING  String;

+

+  String.Header.OpCode  = EFI_IFR_STRING_OP;

+  String.Header.Length  = sizeof (EFI_IFR_STRING);

+  String.QuestionId     = QuestionId;

+  String.Width          = DataWidth;

+  String.Prompt         = PromptToken;

+

+  String.Help           = HelpToken;

+  String.MinSize        = MinSize;

+  String.MaxSize        = MaxSize;

+  String.Flags          = Flags;

+  String.Key            = Key;

+

+  CopyMem (FormBuffer, &String, sizeof (EFI_IFR_STRING));

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CreateBannerOpCode (

+  IN      UINT16              Title,

+  IN      UINT16              LineNumber,

+  IN      UINT8               Alignment,

+  IN OUT  VOID                *FormBuffer

+  )

+/*++

+

+Routine Description:

+

+  Create a banner opcode.  This is primarily used by the FrontPage implementation from BDS.

+  

+Arguments:

+  

+  Title       - Title of the banner

+  

+  LineNumber  - LineNumber of the banner

+  

+  Alignment   - Alignment of the banner

+  

+  FormBuffer  - Output of banner as a form

+  

+Returns: 

+

+  EFI_SUCCESS     - Banner created to be a form.

+

+--*/

+{

+  EFI_IFR_BANNER  Banner;

+

+  Banner.Header.OpCode  = EFI_IFR_BANNER_OP;

+  Banner.Header.Length  = sizeof (EFI_IFR_BANNER);

+  CopyMem (&Banner.Title, &Title, sizeof (UINT16));

+  CopyMem (&Banner.LineNumber, &LineNumber, sizeof (UINT16));

+  Banner.Alignment = Alignment;

+

+  CopyMem (FormBuffer, &Banner, sizeof (EFI_IFR_BANNER));

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrVariable.c b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrVariable.c
new file mode 100644
index 0000000..3e37553
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/IfrVariable.c
@@ -0,0 +1,484 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  IfrVariable.c

+

+Abstract:

+  Variable/Map manipulations routines

+

+--*/

+

+VOID

+EfiLibHiiVariablePackGetMap (

+  IN    EFI_HII_VARIABLE_PACK       *Pack,  

+  OUT   CHAR16                      **Name,  OPTIONAL

+  OUT   EFI_GUID                    **Guid,  OPTIONAL

+  OUT   UINT16                      *Id,     OPTIONAL

+  OUT   VOID                        **Var,   OPTIONAL

+  OUT   UINTN                       *Size    OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Extracts a variable form a Pack.

+

+Arguments:

+

+  Pack - List of variables

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns: 

+

+  VOID

+  

+--*/

+{

+  if (NULL != Name) {

+    *Name = (VOID *) (Pack + 1);

+  }

+    

+  if (NULL != Guid) { 

+    *Guid = (EFI_GUID *)(UINTN)&Pack->VariableGuid;

+  }

+    

+    

+  if (NULL != Id) {

+    *Id   = Pack->VariableId;

+  }

+    

+  if (NULL != Var) {

+    *Var  = (VOID *) ((CHAR8 *) (Pack + 1) + Pack->VariableNameLength);

+  }

+    

+  if (NULL != Size) {

+    *Size = Pack->Header.Length - sizeof (*Pack) - Pack->VariableNameLength;

+  }

+}

+

+

+UINTN

+EfiLibHiiVariablePackListGetMapCnt (

+  IN    EFI_HII_VARIABLE_PACK_LIST   *List

+  )

+  

+/*++

+

+Routine Description:

+

+  Finds a count of the variables/maps in the List.

+

+Arguments:

+

+  List - List of variables

+

+Returns: 

+

+  UINTN - The number of map count.

+

+--*/

+

+{

+  UINTN   Cnt = 0;

+  while (NULL != List) {

+    Cnt++;

+    List = List->NextVariablePack;

+  }

+  return Cnt;

+}

+

+

+VOID

+EfiLibHiiVariablePackListForEachVar (

+  IN    EFI_HII_VARIABLE_PACK_LIST               *List,

+  IN    EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK  *Callback

+  )

+/*++

+

+Routine Description:

+

+  Will iterate all variable/maps as appearing 

+  in List and for each, it will call the Callback.

+

+Arguments:

+

+  List     - List of variables

+  Callback - Routine to be called for each iterated variable.

+

+Returns: 

+

+  VOID

+  

+--*/

+

+{

+  CHAR16    *MapName;

+  EFI_GUID  *MapGuid;

+  UINT16    MapId;

+  VOID      *Map;

+  UINTN     MapSize;

+

+  while (NULL != List) {

+    EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);

+    //

+    // call the callback

+    //

+    Callback (MapName, MapGuid, MapId, Map, MapSize); 

+    List = List->NextVariablePack;

+  }

+}

+

+

+EFI_STATUS

+EfiLibHiiVariablePackListGetMapByIdx (

+  IN    UINTN                       Idx,  

+  IN    EFI_HII_VARIABLE_PACK_LIST  *List,  

+  OUT   CHAR16                      **Name,  OPTIONAL

+  OUT   EFI_GUID                    **Guid,  OPTIONAL

+  OUT   UINT16                      *Id,     OPTIONAL

+  OUT   VOID                        **Var,

+  OUT   UINTN                       *Size

+  )

+

+/*++

+

+Routine Description:

+

+  Finds a variable form List given 

+  the order number as appears in the List.

+

+Arguments:

+

+  Idx  - The index of the variable/map to retrieve

+  List - List of variables

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns:

+

+  EFI_SUCCESS   - Variable is found, OUT parameters are valid

+  EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid

+

+--*/

+{

+  CHAR16     *MapName;

+  EFI_GUID   *MapGuid;

+  UINT16     MapId;

+  VOID       *Map;

+  UINTN      MapSize;

+

+  while (NULL != List) {

+    EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);

+    if (0 == Idx--) {

+      *Var  = Map;

+      *Size = MapSize;

+

+      if (NULL != Name) {

+        *Name = MapName;

+      }

+

+      if (NULL != Guid) {

+        *Guid = MapGuid;

+      }

+        

+      if (NULL != Id) {

+        *Id   = MapId;

+      }

+        

+      return EFI_SUCCESS; // Map found

+    }

+    List = List->NextVariablePack;

+  }

+  //

+  // If here, the map is not found

+  //

+  return EFI_NOT_FOUND; 

+}

+

+

+EFI_STATUS

+EfiLibHiiVariablePackListGetMapById (

+  IN    UINT16                        Id,  

+  IN    EFI_HII_VARIABLE_PACK_LIST    *List,

+  OUT   CHAR16                        **Name,  OPTIONAL

+  OUT   EFI_GUID                      **Guid,  OPTIONAL

+  OUT   VOID                          **Var,

+  OUT   UINTN                         *Size

+  )

+  

+/*++

+

+Routine Description:

+

+  Finds a variable form List given the 

+  order number as appears in the List.

+

+Arguments:

+

+  Id   - The ID of the variable/map to retrieve

+  List - List of variables

+  Name - Name of the variable/map

+  Guid - GUID of the variable/map

+  Var  - Pointer to the variable/map

+  Size - Size of the variable/map in bytes

+

+Returns:

+

+  EFI_SUCCESS   - Variable is found, OUT parameters are valid

+  EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid

+

+--*/

+

+{ 

+  CHAR16    *MapName;

+  EFI_GUID  *MapGuid;

+  UINT16    MapId;

+  VOID      *Map;

+  UINTN     MapSize;

+

+  while (NULL != List) {

+    EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);

+    if (MapId == Id) {

+      *Var  = Map;

+      *Size = MapSize;

+      if (NULL != Name) {

+         *Name = MapName;

+      }

+      if (NULL != Guid) {

+        *Guid = MapGuid;

+      }

+      //

+      // Map found

+      //

+      return EFI_SUCCESS; 

+    }

+    List = List->NextVariablePack;

+  }

+  //

+  // If here, the map is not found

+  //

+  return EFI_NOT_FOUND; 

+}

+

+

+EFI_STATUS

+EfiLibHiiVariablePackListGetMap (

+  IN    EFI_HII_VARIABLE_PACK_LIST   *List,

+  IN    CHAR16                       *Name,

+  IN    EFI_GUID                     *Guid,

+  OUT   UINT16                       *Id,

+  OUT   VOID                         **Var, 

+  OUT   UINTN                        *Size

+  )

+

+/*++

+

+Routine Description:

+

+  Finds a variable form EFI_HII_VARIABLE_PACK_LIST given name and GUID.

+

+Arguments:

+

+  List - List of variables

+  Name - Name of the variable/map to be found

+  Guid - GUID of the variable/map to be found

+  Var  - Pointer to the variable/map found

+  Size - Size of the variable/map in bytes found

+

+Returns:

+

+  EFI_SUCCESS   - variable is found, OUT parameters are valid

+  EFI_NOT_FOUND - variable is not found, OUT parameters are not valid

+

+--*/

+

+{ 

+  VOID      *Map;

+  UINTN     MapSize;

+  UINT16    MapId;

+  CHAR16    *MapName;

+  EFI_GUID  *MapGuid;

+

+  while (NULL != List) {

+    EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);

+    if ((0 == StrCmp (Name, MapName)) && CompareGuid (Guid, MapGuid)) {

+      *Id   = MapId;

+      *Var  = Map;

+      *Size = MapSize;

+      return EFI_SUCCESS;

+    }

+    List = List->NextVariablePack;

+  }

+  //

+  // If here, the map is not found

+  //

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EfiLibHiiVariableRetrieveFromNv (

+  IN  CHAR16                 *Name,

+  IN  EFI_GUID               *Guid,

+  IN  UINTN                   Size,

+  OUT VOID                  **Var

+  )

+/*++

+

+Routine Description:

+  Finds out if a variable of specific Name/Guid/Size exists in NV. 

+  If it does, it will retrieve it into the Var. 

+

+Arguments:

+  Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.

+  Var              - Variable will be retrieved into buffer pointed by this pointer.

+                     If pointing to NULL, the buffer will be allocated. Caller is responsible for releasing the buffer.

+Returns:

+  EFI_SUCCESS    - The variable of exact Name/Guid/Size parameters was retrieved and written to Var.

+  EFI_NOT_FOUND  - The variable of this Name/Guid was not found in the NV.

+  EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  UINTN                       SizeNv;

+

+  //

+  // Test for existence of the variable.

+  //

+  SizeNv = 0;

+  Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, NULL);

+  if (EFI_BUFFER_TOO_SMALL != Status) {

+    ASSERT (EFI_SUCCESS != Status);

+    return EFI_NOT_FOUND;

+  }

+  if (SizeNv != Size) {

+    //

+    // The variable is considered corrupt, as it has different size from expected.

+    //

+    return EFI_LOAD_ERROR; 

+  }

+

+  if (NULL == *Var) {

+    *Var = AllocatePool (Size);

+    ASSERT (NULL != *Var);

+  }

+  SizeNv = Size;

+  //

+  // Final read into the Var

+  //

+  Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, *Var); 

+  //

+  // No tolerance for random failures. Such behavior is undetermined and not validated.

+  //

+  ASSERT_EFI_ERROR (Status); 

+  ASSERT (SizeNv == Size);

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+EfiLibHiiVariableOverrideIfSuffix (

+  IN  CHAR16                 *Suffix,

+  IN  CHAR16                 *Name,

+  IN  EFI_GUID               *Guid,

+  IN  UINTN                   Size,

+  OUT VOID                   *Var

+  )  

+/*++

+

+Routine Description:

+  Overrrides the variable with NV data if found.

+  But it only does it if the Name ends with specified Suffix.

+  For example, if Suffix="MyOverride" and the Name="XyzSetupMyOverride",

+  the Suffix matches the end of Name, so the variable will be loaded from NV

+  provided the variable exists and the GUID and Size matches.

+

+Arguments:

+  Suffix           - Suffix the Name should end with.

+  Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.

+  Var              - Variable will be retrieved into this buffer.

+                     Caller is responsible for providing storage of exactly Size size in bytes.

+Returns:

+  EFI_SUCCESS           - The variable was overriden with NV variable of same Name/Guid/Size.

+  EFI_INVALID_PARAMETER - The name of the variable does not end with <Suffix>.

+  EFI_NOT_FOUND         - The variable of this Name/Guid was not found in the NV.

+  EFI_LOAD_ERROR        - The variable in the NV was of different size, or NV API returned error.

+

+--*/

+{

+  UINTN         StrLength;

+  UINTN         StrLenSuffix;

+

+  StrLength       = StrLen (Name);

+  StrLenSuffix    = StrLen (Suffix);

+  if ((StrLength <= StrLenSuffix) || (0 != StrCmp (Suffix, &Name[StrLength - StrLenSuffix]))) {

+    //

+    // Not ending with <Suffix>.

+    //

+    return EFI_INVALID_PARAMETER; 

+  }

+  return EfiLibHiiVariableRetrieveFromNv (Name, Guid, Size, &Var);

+}

+

+EFI_STATUS

+EfiLibHiiVariableOverrideBySuffix (

+  IN  CHAR16                 *Suffix,

+  IN  CHAR16                 *Name,

+  IN  EFI_GUID               *Guid,

+  IN  UINTN                   Size,

+  OUT VOID                   *Var

+  ) 

+/*++

+

+Routine Description:

+  Overrrides the variable with NV data if found.

+  But it only does it if the NV contains the same variable with Name is appended with Suffix.  

+  For example, if Suffix="MyOverride" and the Name="XyzSetup",

+  the Suffix will be appended to the end of Name, and the variable with Name="XyzSetupMyOverride"

+  will be loaded from NV provided the variable exists and the GUID and Size matches.

+

+Arguments:

+  Suffix           - Suffix the variable will be appended with.

+  Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.

+  Var              - Variable will be retrieved into this buffer.

+                     Caller is responsible for providing storage of exactly Size size in bytes.

+

+Returns:

+  EFI_SUCCESS    - The variable was overriden with NV variable of same Name/Guid/Size.

+  EFI_NOT_FOUND  - The variable of this Name/Guid was not found in the NV.

+  EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.

+

+--*/

+{

+  EFI_STATUS    Status;

+  CHAR16       *NameSuffixed;

+

+  //

+  // enough to concatenate both strings.

+  //

+  NameSuffixed = AllocateZeroPool ((StrLen (Name) + StrLen (Suffix) + 1) * sizeof (CHAR16)); 

+  

+  StrCpy (NameSuffixed, Name);

+  StrCat (NameSuffixed, Suffix);

+  

+  Status = EfiLibHiiVariableRetrieveFromNv (NameSuffixed, Guid, Size, &Var);

+  gBS->FreePool (NameSuffixed);

+  

+  return Status;

+}

+

diff --git a/edk2/EdkModulePkg/Library/EdkIfrSupportLib/build.xml b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/build.xml
new file mode 100644
index 0000000..50edb6a
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkIfrSupportLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkIfrSupportLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkIfrSupportLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkIfrSupportLib">

+      <GenBuild baseName="EdkIfrSupportLib" mbdFilename="${MODULE_DIR}/EdkIfrSupportLib.mbd" msaFilename="${MODULE_DIR}/EdkIfrSupportLib.msa"/>

+   </target>

+   <target depends="EdkIfrSupportLib_clean" name="clean"/>

+   <target depends="EdkIfrSupportLib_cleanall" name="cleanall"/>

+   <target name="EdkIfrSupportLib_clean">

+      <OutputDirSetup baseName="EdkIfrSupportLib" mbdFilename="${MODULE_DIR}/EdkIfrSupportLib.mbd" msaFilename="${MODULE_DIR}/EdkIfrSupportLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkIfrSupportLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkIfrSupportLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkIfrSupportLib_cleanall">

+      <OutputDirSetup baseName="EdkIfrSupportLib" mbdFilename="${MODULE_DIR}/EdkIfrSupportLib.mbd" msaFilename="${MODULE_DIR}/EdkIfrSupportLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkIfrSupportLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkIfrSupportLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkIfrSupportLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.mbd b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.mbd
new file mode 100644
index 0000000..01e0cb2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkMemoryStatusCodeLib</BaseName>

+    <Guid>e2368d1d-4c94-4e62-be2f-7817bbd78293</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.msa b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.msa
new file mode 100644
index 0000000..d402cba
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/EdkMemoryStatusCodeLib.msa
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkMemoryStatusCodeLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e2368d1d-4c94-4e62-be2f-7817bbd78293</Guid>

+    <Version>0</Version>

+    <Abstract>Memory Status Code Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkMemoryStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MemoryStatusCode.c</Filename>

+    <Filename>MemoryStatusCode.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>StatusCodeMemoryPpi</Name>

+      <C_Name>gPeiStatusCodeMemoryPpiGuid</C_Name>

+      <Guid>0x26f8ab01, 0xd3cd, 0x489c, 0x98, 0x4f, 0xdf, 0xde, 0xf7, 0x68, 0x39, 0x5b</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="SOMETIMES_PRODUCED">StatusCodeMemory</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">StatusCode</Ppi>

+    <PpiNotify Usage="SOMETIMES_CONSUMED">FvFileLoader</PpiNotify>

+  </PPIs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/MemoryStatusCode.c b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/MemoryStatusCode.c
new file mode 100644
index 0000000..1661d77
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/MemoryStatusCode.c
@@ -0,0 +1,498 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  MemoryStatusCode.c

+   

+Abstract:

+

+  Lib to provide memory journal status code reporting Routines.

+

+--*/

+#include "MemoryStatusCode.h"

+

+//

+// Global variable.  Not accessible while running from flash.

+// After we relocate ourselves into memory, we update this

+// and use it to determine if we are running from flash or memory.

+//

+

+//

+// Global variable used to replace the PPI once we start running from memory.

+//

+PEI_STATUS_CODE_MEMORY_PPI    mStatusCodeMemoryPpi = { 0, 0, 0, 0 };

+

+//

+// PPI descriptor for the MonoStatusCode PEIM, see MonoStatusCode.c

+//

+extern EFI_PEI_PPI_DESCRIPTOR mPpiListStatusCode;

+

+EFI_STATUS

+EFIAPI

+MemoryStatusCodeInitialize (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Initialization routine.

+  Allocates heap space for storing Status Codes.

+  Installs a PPI to point to that heap space.

+  Installs a callback to switch to memory.

+  Installs a callback to 

+

+Arguments: 

+

+  FfsHeader   - FV this PEIM was loaded from.

+  PeiServices - General purpose services available to every PEIM.

+

+Returns: 

+

+  None

+

+--*/

+{

+  EFI_STATUS                  Status;

+  MEMORY_STATUS_CODE_INSTANCE *PrivateData;

+  PEI_STATUS_CODE_MEMORY_PPI  *StatusCodeMemoryPpi;

+  EFI_PEI_PROGRESS_CODE_PPI   *ReportStatusCodePpi;

+  EFI_PHYSICAL_ADDRESS        Buffer;

+  VOID                        *StartPointer;

+  UINTN                       Length;

+  UINTN                       LastEntry;

+  EFI_PEI_PPI_DESCRIPTOR      *ReportStatusCodeDescriptor;

+  EFI_PEI_PPI_DESCRIPTOR      *StatusCodeMemoryDescriptor;

+

+  //

+  // Determine if we are being called after relocation into memory.

+  //

+  if (!gRunningFromMemory) {

+    //

+    // If we are not running from memory, we need to allocate some heap and

+    // install the PPI

+    //

+    //

+    // Allocate heap storage for the journal

+    //

+    Status = (*PeiServices)->AllocatePool (

+                              PeiServices,

+                              PEI_STATUS_CODE_HEAP_LENGTH,

+                              &StartPointer

+                              );

+

+    //

+    // This is not a required feature to boot.

+    //

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Allocate heap storage for private data

+    // The private data contains the FFS header for this PEIM,

+    // a PPI containing information about the status code journal, and

+    // a notification for the LoadFile service, to relocate the PEIM into

+    // memory.

+    //

+    Status = (*PeiServices)->AllocatePool (

+                              PeiServices,

+                              sizeof (MEMORY_STATUS_CODE_INSTANCE),

+                              (VOID **) &PrivateData

+                              );

+

+    //

+    // This is not a required feature to boot.

+    //

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Update the contents of the private data.

+    //

+    PrivateData->Signature                      = MEMORY_STATUS_CODE_SIGNATURE;

+    PrivateData->This = PrivateData;

+    PrivateData->FfsHeader = FfsHeader;

+    PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);

+    PrivateData->PpiDescriptor.Guid = &gPeiStatusCodeMemoryPpiGuid;

+    PrivateData->PpiDescriptor.Ppi = &PrivateData->StatusCodeMemoryPpi;

+    PrivateData->StatusCodeMemoryPpi.FirstEntry = 0;

+    PrivateData->StatusCodeMemoryPpi.LastEntry = 0;

+    PrivateData->StatusCodeMemoryPpi.Address = (EFI_PHYSICAL_ADDRESS) (UINTN) StartPointer;

+    PrivateData->StatusCodeMemoryPpi.Length = PEI_STATUS_CODE_HEAP_LENGTH;

+    PrivateData->NotifyDescriptor.Flags =

+      (

+        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |

+        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST

+      );

+    PrivateData->NotifyDescriptor.Guid    = &gEfiPeiFvFileLoaderPpiGuid;

+    PrivateData->NotifyDescriptor.Notify  = LoadImageCallback;

+

+    //

+    // Publish the PPI

+    //

+    Status = (*PeiServices)->InstallPpi (PeiServices, &PrivateData->PpiDescriptor);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Post a callback to relocate to memory

+    //

+    Status = (**PeiServices).NotifyPpi (PeiServices, &PrivateData->NotifyDescriptor);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  } else {

+    //

+    // If we are running from memory, we need to copy from the heap to a RT

+    // memory buffer.

+    //

+    //

+    // Locate Journal

+    //

+    Status = (*PeiServices)->LocatePpi (

+                              PeiServices,

+                              &gPeiStatusCodeMemoryPpiGuid,

+                              0,

+                              &StatusCodeMemoryDescriptor,

+                              (VOID **) &StatusCodeMemoryPpi

+                              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Get private data

+    //

+    PrivateData = _CR (StatusCodeMemoryDescriptor, MEMORY_STATUS_CODE_INSTANCE, PpiDescriptor);

+    //

+    // At this point, we need to fix up any addresses that we have as the heap

+    // has moved.

+    //

+    PrivateData->PpiDescriptor.Ppi  = &PrivateData->StatusCodeMemoryPpi;

+    PrivateData->PpiDescriptor.Guid = &gPeiStatusCodeMemoryPpiGuid;

+    PrivateData->StatusCodeMemoryPpi.Address = PrivateData->StatusCodeMemoryPpi.Address +

+      (UINTN) PrivateData - (UINTN) PrivateData->This;

+    PrivateData->NotifyDescriptor.Guid    = &gEfiPeiFvFileLoaderPpiGuid;

+    PrivateData->NotifyDescriptor.Notify  = LoadImageCallback;

+    PrivateData->This                     = PrivateData;

+

+    //

+    // Allocate RT memory.

+    //

+    Status = (*PeiServices)->AllocatePages (

+                              PeiServices,

+                              EfiRuntimeServicesData,

+                              PEI_STATUS_CODE_RT_PAGES,

+                              &Buffer

+                              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    DEBUG_CODE (

+      ZeroMem ((VOID *) (UINTN) Buffer, PEI_STATUS_CODE_RT_LENGTH);

+    );

+

+    //

+    // Copy the heap to the allocated memory.

+    // Unwind the rolling queue to start at 0 in the new space.  We need to do

+    // this because the new queue is much bigger than the heap allocation.

+    //

+    if (PEI_STATUS_CODE_RT_LENGTH <= PEI_STATUS_CODE_HEAP_LENGTH) {

+      return Status;

+    }

+

+    if (StatusCodeMemoryPpi->LastEntry >= StatusCodeMemoryPpi->FirstEntry) {

+      LastEntry = StatusCodeMemoryPpi->LastEntry - StatusCodeMemoryPpi->FirstEntry;

+      StartPointer = (VOID *) ((UINTN) StatusCodeMemoryPpi->Address + (StatusCodeMemoryPpi->FirstEntry * sizeof (EFI_STATUS_CODE_ENTRY)));

+      Length = (StatusCodeMemoryPpi->LastEntry - StatusCodeMemoryPpi->FirstEntry) * sizeof (EFI_STATUS_CODE_ENTRY);

+      (*PeiServices)->CopyMem ((VOID *) (UINTN) Buffer, StartPointer, Length);

+    } else {

+      //

+      // The last entry will be the new last entry after moving heap to buffer

+      //

+      LastEntry = (PEI_STATUS_CODE_MAX_HEAP_ENTRY - StatusCodeMemoryPpi->FirstEntry) + StatusCodeMemoryPpi->LastEntry;

+      //

+      // Copy from the first entry to the end of the heap

+      //

+      StartPointer = (VOID *) ((UINTN) StatusCodeMemoryPpi->Address + (StatusCodeMemoryPpi->FirstEntry * sizeof (EFI_STATUS_CODE_ENTRY)));

+      Length = PEI_STATUS_CODE_HEAP_LENGTH - (StatusCodeMemoryPpi->FirstEntry * sizeof (EFI_STATUS_CODE_ENTRY));

+      (*PeiServices)->CopyMem ((VOID *) (UINTN) Buffer, StartPointer, Length);

+      //

+      // Copy from the start to the heap to the last entry

+      //

+      StartPointer = (VOID *) (UINTN) StatusCodeMemoryPpi->Address;

+      (*PeiServices)->CopyMem (

+                        (VOID *) (UINTN) (Buffer + Length),

+                        StartPointer,

+                        (StatusCodeMemoryPpi->LastEntry * sizeof (EFI_STATUS_CODE_ENTRY))

+                        );

+    };

+

+    //

+    // Update the PPI to NULL, so it will not be used.

+    //

+    StatusCodeMemoryPpi->FirstEntry = 0;

+    StatusCodeMemoryPpi->LastEntry  = 0;

+    StatusCodeMemoryPpi->Address    = 0;

+    StatusCodeMemoryPpi->Length     = 0;

+

+    //

+    // Update in memory version of PPI that will be used.

+    //

+    mStatusCodeMemoryPpi.FirstEntry = 0;

+    mStatusCodeMemoryPpi.LastEntry  = LastEntry;

+    mStatusCodeMemoryPpi.Address    = (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer;

+    mStatusCodeMemoryPpi.Length     = PEI_STATUS_CODE_RT_LENGTH;

+

+    //

+    // Reinstall the report status code function

+    //

+    //

+    // Locate status code PPI

+    //

+    Status = (*PeiServices)->LocatePpi (

+                              PeiServices,

+                              &gEfiPeiStatusCodePpiGuid,

+                              0,

+                              &ReportStatusCodeDescriptor,

+                              (VOID **) &ReportStatusCodePpi

+                              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Reinstall the ReportStatusCode interface using the memory-based

+    // descriptor

+    //

+    Status = (*PeiServices)->ReInstallPpi (

+                              PeiServices,

+                              ReportStatusCodeDescriptor,

+                              &mPpiListStatusCode

+                              );

+    if (EFI_ERROR (Status)) {

+      CpuBreakpoint ();

+      return Status;

+    }

+    //

+    // Publish a GUIDed HOB that contains a pointer to the status code PPI

+    // structure.  This is a bit of a short cut as I just used the PPI GUID to

+    // identify the HOB.  This HOB is caught by the DXE status code memory

+    // listener and used to find the journal.

+    //

+    StatusCodeMemoryPpi = &mStatusCodeMemoryPpi;

+

+    BuildGuidDataHob (

+      &gPeiStatusCodeMemoryPpiGuid,

+      &StatusCodeMemoryPpi,

+      sizeof (VOID *)

+      );

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+MemoryReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Provide a memory status code

+

+Arguments:

+

+  Same as ReportStatusCode PPI

+    

+Returns:

+

+  EFI_SUCCESS   This function always returns success

+

+--*/

+{

+  EFI_STATUS                  Status;

+  PEI_STATUS_CODE_MEMORY_PPI  *StatusCodeMemoryPpi;

+  EFI_STATUS_CODE_ENTRY       *CurrentEntry;

+  UINTN                       LastEntry;

+  MEMORY_STATUS_CODE_INSTANCE *PrivateData;

+  EFI_PEI_PPI_DESCRIPTOR      *StatusCodeMemoryDescriptor;

+  EFI_PEI_SERVICES            **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  //

+  // We don't care to log debug codes.

+  //

+  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {

+    return EFI_SUCCESS;

+  }

+

+  if (!gRunningFromMemory) {

+    //

+    // If we are called from DXE and have not been reinstalled into memory, we

+    // can no longer locate the journal, so we can no longer log status codes.

+    //

+    if (!PeiServices) {

+      return EFI_SUCCESS;

+    }

+    //

+    // Locate Journal

+    //

+    Status = (*PeiServices)->LocatePpi (

+                              PeiServices,

+                              &gPeiStatusCodeMemoryPpiGuid,

+                              0,

+                              &StatusCodeMemoryDescriptor,

+                              (VOID **) &StatusCodeMemoryPpi

+                              );

+    if (EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    }

+    //

+    // Determine the last entry in the journal.

+    // This is needed to properly implement the rolling queue.

+    //

+    LastEntry = PEI_STATUS_CODE_MAX_HEAP_ENTRY;

+

+    //

+    // Get private data

+    //

+    PrivateData = _CR (StatusCodeMemoryDescriptor, MEMORY_STATUS_CODE_INSTANCE, PpiDescriptor);

+

+    //

+    // Once memory gets installed, heap gets moved to real memory.

+    // We need to fix up the pointers to match the move.

+    //

+    PrivateData->PpiDescriptor.Ppi  = &PrivateData->StatusCodeMemoryPpi;

+    PrivateData->PpiDescriptor.Guid = &gPeiStatusCodeMemoryPpiGuid;

+    PrivateData->StatusCodeMemoryPpi.Address = PrivateData->StatusCodeMemoryPpi.Address +

+      (UINTN) PrivateData - (UINTN) PrivateData->This;

+    PrivateData->NotifyDescriptor.Guid    = &gEfiPeiFvFileLoaderPpiGuid;

+    PrivateData->NotifyDescriptor.Notify  = LoadImageCallback;

+    PrivateData->This                     = PrivateData;

+

+    StatusCodeMemoryPpi                   = PrivateData->PpiDescriptor.Ppi;

+  } else {

+    //

+    // Use global/memory copy of the PPI

+    //

+    StatusCodeMemoryPpi = &mStatusCodeMemoryPpi;

+

+    //

+    // Determine the last entry in the journal.

+    // This is needed to properly implement the rolling queue.

+    //

+    LastEntry = PEI_STATUS_CODE_MAX_RT_ENTRY;

+  }

+  //

+  // Return if we are using a cleared PPI somehow

+  //

+  if (!StatusCodeMemoryPpi->Address || !StatusCodeMemoryPpi->Length) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Update the latest entry in the journal (may actually be first due to rolling

+  // queue).

+  //

+  CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (StatusCodeMemoryPpi->Address + (StatusCodeMemoryPpi->LastEntry * sizeof (EFI_STATUS_CODE_ENTRY)));

+

+  StatusCodeMemoryPpi->LastEntry = (StatusCodeMemoryPpi->LastEntry + 1) % LastEntry;

+  if (StatusCodeMemoryPpi->LastEntry == StatusCodeMemoryPpi->FirstEntry) {

+    StatusCodeMemoryPpi->FirstEntry = (StatusCodeMemoryPpi->FirstEntry + 1) % LastEntry;

+  }

+

+  CurrentEntry->Type      = CodeType;

+  CurrentEntry->Value     = Value;

+  CurrentEntry->Instance  = Instance;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+LoadImageCallback (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,

+  IN VOID                       *Ppi

+  )

+/*++

+

+Routine Description:

+

+  Relocate the PEIM into memory.

+

+  Once load protocol becomes available, relocate our PEIM into memory.

+  The primary benefit is to eliminate the blackout window that we would have in

+  the memory log between the end of PEI and the status code DXE driver taking

+  control.  If we don't do this, we cannot determine where our memory journal

+  is located and cannot function.

+

+  A second benefit is speed optimization throughout DXE.

+

+Arguments:

+

+  PeiServices      - General purpose services available to every PEIM.

+  NotifyDescriptor - Information about the notify event.

+  Ppi              - Context

+    

+Returns:

+

+  EFI_SUCCESS   This function always returns success.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PHYSICAL_ADDRESS        ImageAddress;

+  EFI_PHYSICAL_ADDRESS        EntryPoint;

+  UINT64                      ImageSize;

+  MEMORY_STATUS_CODE_INSTANCE *PrivateData;

+

+  //

+  // Relocate to memory

+  //

+  if (!gRunningFromMemory) {

+    //

+    // Use the callback descriptor to get the FfsHeader

+    //

+    PrivateData = _CR (NotifyDescriptor, MEMORY_STATUS_CODE_INSTANCE, NotifyDescriptor);

+

+    Status = ((EFI_PEI_FV_FILE_LOADER_PPI *) Ppi)->FvLoadFile (

+                                                    Ppi,

+                                                    PrivateData->FfsHeader,

+                                                    &ImageAddress,

+                                                    &ImageSize,

+                                                    &EntryPoint

+                                                    );

+    if (EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    }

+    //

+    // Set the flag in the loaded image that indicates the PEIM is executing

+    // from memory.

+    //

+#ifdef EFI_NT_EMULATOR

+    gRunningFromMemory = TRUE;

+#else

+    * (BOOLEAN *) ((UINTN) &gRunningFromMemory + (UINTN) EntryPoint - (UINTN) InstallMonoStatusCode) = TRUE;

+#endif

+    Status = ((EFI_PEIM_ENTRY_POINT )(UINTN) EntryPoint) (PrivateData->FfsHeader, PeiServices);

+    if (EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/MemoryStatusCode.h b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/MemoryStatusCode.h
new file mode 100644
index 0000000..3580083
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/MemoryStatusCode.h
@@ -0,0 +1,94 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  MemoryStatusCode.h

+   

+Abstract:

+

+  Lib to provide status code reporting via memory.

+

+--*/

+

+#ifndef _PEI_MEMORY_STATUS_CODE_H_

+#define _PEI_MEMORY_STATUS_CODE_H_

+

+//

+// Publicly exported function

+//

+EFI_STATUS

+EFIAPI

+InstallMonoStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+;

+//

+// Publicly exported data

+//

+extern BOOLEAN  gRunningFromMemory;

+//

+// Private data

+//

+//

+// Define the amount of heap to use before memory is allocated

+//

+#define PEI_STATUS_CODE_HEAP_LENGTH     512

+#define PEI_STATUS_CODE_MAX_HEAP_ENTRY  (PEI_STATUS_CODE_HEAP_LENGTH / sizeof (EFI_STATUS_CODE_ENTRY))

+

+//

+// Define the number of 4K pages of BS memory to allocate (1MB)

+//

+#define PEI_STATUS_CODE_RT_PAGES      (128)

+#define PEI_STATUS_CODE_RT_LENGTH     (PEI_STATUS_CODE_RT_PAGES * 1024 * 4)

+#define PEI_STATUS_CODE_MAX_RT_ENTRY  (PEI_STATUS_CODE_RT_LENGTH / sizeof (EFI_STATUS_CODE_ENTRY))

+

+//

+// Define a private data structure

+//

+#define MEMORY_STATUS_CODE_SIGNATURE  EFI_SIGNATURE_32 ('M', 'S', 'C', 'S')

+

+typedef struct _MEMORY_STATUS_CODE_INSTANCE {

+  UINT32                              Signature;

+  struct _MEMORY_STATUS_CODE_INSTANCE *This;

+  EFI_FFS_FILE_HEADER                 *FfsHeader;

+  EFI_PEI_PPI_DESCRIPTOR              PpiDescriptor;

+  PEI_STATUS_CODE_MEMORY_PPI          StatusCodeMemoryPpi;

+  EFI_PEI_NOTIFY_DESCRIPTOR           NotifyDescriptor;

+} MEMORY_STATUS_CODE_INSTANCE;

+

+#define MEMORY_STATUS_CODE_FROM_DESCRIPTOR_THIS(a) \

+  PEI_CR (a, \

+          MEMORY_STATUS_CODE_INSTANCE, \

+          PpiDescriptor, \

+          MEMORY_STATUS_CODE_SIGNATURE \

+      )

+#define MEMORY_STATUS_CODE_FROM_NOTIFY_THIS(a) \

+  PEI_CR (a, \

+          MEMORY_STATUS_CODE_INSTANCE, \

+          NotifyDescriptor, \

+          MEMORY_STATUS_CODE_SIGNATURE \

+      )

+

+//

+// Private function declarations

+//

+EFI_STATUS

+EFIAPI

+LoadImageCallback (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,

+  IN VOID                       *Ppi

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/build.xml b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/build.xml
new file mode 100644
index 0000000..1efd304
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkMemoryStatusCodeLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkMemoryStatusCodeLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkMemoryStatusCodeLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkMemoryStatusCodeLib">

+      <GenBuild baseName="EdkMemoryStatusCodeLib" mbdFilename="${MODULE_DIR}/EdkMemoryStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/EdkMemoryStatusCodeLib.msa"/>

+   </target>

+   <target depends="EdkMemoryStatusCodeLib_clean" name="clean"/>

+   <target depends="EdkMemoryStatusCodeLib_cleanall" name="cleanall"/>

+   <target name="EdkMemoryStatusCodeLib_clean">

+      <OutputDirSetup baseName="EdkMemoryStatusCodeLib" mbdFilename="${MODULE_DIR}/EdkMemoryStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/EdkMemoryStatusCodeLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkMemoryStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkMemoryStatusCodeLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkMemoryStatusCodeLib_cleanall">

+      <OutputDirSetup baseName="EdkMemoryStatusCodeLib" mbdFilename="${MODULE_DIR}/EdkMemoryStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/EdkMemoryStatusCodeLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkMemoryStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkMemoryStatusCodeLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkMemoryStatusCodeLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/CustomizedDecompress.c b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/CustomizedDecompress.c
new file mode 100644
index 0000000..55d9bbe
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/CustomizedDecompress.c
@@ -0,0 +1,109 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  CustomizedDecompress.c

+

+Abstract:

+

+  Implementation file for Customized decompression routine

+  

+--*/

+

+#include <CustomizedDecompress.h>

+

+EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  mCustomizedDecompress = {

+  CustomizedGetInfo,

+  CustomizedDecompress

+};

+

+EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL *

+EFIAPI

+GetCustomizedDecompressProtocol (

+  VOID

+  )

+{

+  return &mCustomizedDecompress;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+CustomizedGetInfo (

+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL     *This,

+  IN      VOID                              *Source,

+  IN      UINT32                            SrcSize,

+  OUT     UINT32                            *DstSize,

+  OUT     UINT32                            *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of Customized GetInfo().

+

+Arguments:

+  This        - The EFI customized decompress protocol

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  DstSize     - The size of destination buffer.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  EFI_INVALID_PARAMETER - The source data is corrupted

+  EFI_UNSUPPORTED       - Not supported

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+EFIAPI

+CustomizedDecompress (

+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL     *This,

+  IN      VOID                              *Source,

+  IN      UINT32                            SrcSize,

+  IN OUT  VOID                              *Destination,

+  IN      UINT32                            DstSize,

+  IN OUT  VOID                              *Scratch,

+  IN      UINT32                            ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of Customized Decompress().

+

+Arguments:

+

+  This        - The protocol instance pointer

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  Destination - The destination buffer to store the decompressed data

+  DstSize     - The size of destination buffer.

+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - Decompression is successfull

+  EFI_INVALID_PARAMETER - The source data is corrupted

+  EFI_UNSUPPORTED       - Not supported

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/CustomizedDecompress.h b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/CustomizedDecompress.h
new file mode 100644
index 0000000..e94be43
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/CustomizedDecompress.h
@@ -0,0 +1,95 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  CustomizedDecompress.h

+

+Abstract:

+

+  Header file for Customized decompression routine

+  

+--*/

+#ifndef _CUSTOMIZED_DECOMPRESS_LIB_H_

+#define _CUSTOMIZED_DECOMPRESS_LIB_H_

+

+

+

+

+EFI_STATUS

+EFIAPI

+CustomizedGetInfo (

+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL     *This,

+  IN      VOID                              *Source,

+  IN      UINT32                            SrcSize,

+  OUT     UINT32                            *DstSize,

+  OUT     UINT32                            *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of Customized GetInfo().

+

+Arguments:

+  This        - The EFI customized decompress protocol

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  DstSize     - The size of destination buffer.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  EFI_INVALID_PARAMETER - The source data is corrupted

+  EFI_UNSUPPORTED       - Not supported

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+CustomizedDecompress (

+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL     *This,

+  IN      VOID                              *Source,

+  IN      UINT32                            SrcSize,

+  IN OUT  VOID                              *Destination,

+  IN      UINT32                            DstSize,

+  IN OUT  VOID                              *Scratch,

+  IN      UINT32                            ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of Customized Decompress().

+

+Arguments:

+

+  This        - The protocol instance pointer

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  Destination - The destination buffer to store the decompressed data

+  DstSize     - The size of destination buffer.

+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - Decompression is successfull

+  EFI_INVALID_PARAMETER - The source data is corrupted

+  EFI_UNSUPPORTED       - Not supported

+

+--*/

+;

+

+

+#endif

diff --git a/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.mbd b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.mbd
new file mode 100644
index 0000000..a6a6d56
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkNullCustomizedDecompressLib</BaseName>

+    <Guid>4a024320-0648-49c3-84d4-3d04670a1c77</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.msa b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.msa
new file mode 100644
index 0000000..774c8d6
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/EdkNullCustomizedDecompressLib.msa
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkNullCustomizedDecompressLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>4a024320-0648-49c3-84d4-3d04670a1c77</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">CustomDecompressLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>CustomizedDecompress.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/build.xml b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/build.xml
new file mode 100644
index 0000000..815ab35
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkNullCustomizedDecompressLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkNullCustomizedDecompressLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkNullCustomizedDecompressLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkNullCustomizedDecompressLib">

+      <GenBuild baseName="EdkNullCustomizedDecompressLib" mbdFilename="${MODULE_DIR}/EdkNullCustomizedDecompressLib.mbd" msaFilename="${MODULE_DIR}/EdkNullCustomizedDecompressLib.msa"/>

+   </target>

+   <target depends="EdkNullCustomizedDecompressLib_clean" name="clean"/>

+   <target depends="EdkNullCustomizedDecompressLib_cleanall" name="cleanall"/>

+   <target name="EdkNullCustomizedDecompressLib_clean">

+      <OutputDirSetup baseName="EdkNullCustomizedDecompressLib" mbdFilename="${MODULE_DIR}/EdkNullCustomizedDecompressLib.mbd" msaFilename="${MODULE_DIR}/EdkNullCustomizedDecompressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkNullCustomizedDecompressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkNullCustomizedDecompressLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkNullCustomizedDecompressLib_cleanall">

+      <OutputDirSetup baseName="EdkNullCustomizedDecompressLib" mbdFilename="${MODULE_DIR}/EdkNullCustomizedDecompressLib.mbd" msaFilename="${MODULE_DIR}/EdkNullCustomizedDecompressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkNullCustomizedDecompressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkNullCustomizedDecompressLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkNullCustomizedDecompressLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoader.c b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoader.c
new file mode 100644
index 0000000..86421db
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoader.c
@@ -0,0 +1,112 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  TianoPeCoffLoader.c

+

+Abstract:

+

+  Wrap the Base PE/COFF loader with the PE COFF Protocol

+

+

+--*/

+

+

+

+EFI_STATUS

+EFIAPI

+TianoPeCoffLoaderLibGetImageInfo (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = PeCoffLoaderGetImageInfo (ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  switch (ImageContext->ImageType) {

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:

+    ImageContext->ImageCodeMemoryType = EfiLoaderCode;

+    ImageContext->ImageDataMemoryType = EfiLoaderData;

+    break;

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:

+    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;

+    ImageContext->ImageDataMemoryType = EfiBootServicesData;

+    break;

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:

+  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:

+    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;

+    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;

+    break;

+

+  default:

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+    return RETURN_UNSUPPORTED;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TianoPeCoffLoaderLibLoadImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  return PeCoffLoaderLoadImage (ImageContext);

+}

+

+EFI_STATUS

+EFIAPI

+TianoPeCoffLoaderLibRelocateImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  return PeCoffLoaderRelocateImage (ImageContext);

+}

+

+

+EFI_STATUS

+EFIAPI

+TianoPeCoffLoaderLibUnloadimage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,

+  IN PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  return EFI_SUCCESS;

+}

+

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL  mPeiEfiPeiPeCoffLoader = {

+  TianoPeCoffLoaderLibGetImageInfo,

+  TianoPeCoffLoaderLibLoadImage,

+  TianoPeCoffLoaderLibRelocateImage,

+  TianoPeCoffLoaderLibUnloadimage

+};

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL *

+EFIAPI

+GetPeCoffLoaderProtocol (

+  )

+{

+  return &mPeiEfiPeiPeCoffLoader;

+}

+

+

diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.mbd b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.mbd
new file mode 100644
index 0000000..4ffdf99
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkPeCoffLoaderLib</BaseName>

+    <Guid>858bbbc9-474f-4556-a361-0ae52a44ffa5</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.msa b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.msa
new file mode 100644
index 0000000..835d0ba
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/EdkPeCoffLoaderLib.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkPeCoffLoaderLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>858bbbc9-474f-4556-a361-0ae52a44ffa5</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkPeCoffLoaderLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeCoffLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>EdkPeCoffLoader.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/build.xml b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/build.xml
new file mode 100644
index 0000000..f3339fe
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkPeCoffLoaderLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkPeCoffLoaderLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkPeCoffLoaderLib">

+      <GenBuild baseName="EdkPeCoffLoaderLib" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderLib.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderLib.msa"/>

+   </target>

+   <target depends="EdkPeCoffLoaderLib_clean" name="clean"/>

+   <target depends="EdkPeCoffLoaderLib_cleanall" name="cleanall"/>

+   <target name="EdkPeCoffLoaderLib_clean">

+      <OutputDirSetup baseName="EdkPeCoffLoaderLib" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderLib.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkPeCoffLoaderLib_cleanall">

+      <OutputDirSetup baseName="EdkPeCoffLoaderLib" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderLib.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkPeCoffLoaderLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.c b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.c
new file mode 100644
index 0000000..5ed74f5
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.c
@@ -0,0 +1,940 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. 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.             
+
+Module Name:
+
+  EdkPeCoffLoaderX64.c
+
+Abstract:
+
+  Wrap the Base PE/COFF loader with the PE COFF Protocol
+
+
+--*/
+
+#define IMAGE_64_MACHINE_TYPE_SUPPORTED(Machine) \
+  ((Machine) == EFI_IMAGE_MACHINE_IA32 || \
+   (Machine) == EFI_IMAGE_MACHINE_X64 || \
+   (Machine) == EFI_IMAGE_MACHINE_EBC)
+
+STATIC
+EFI_STATUS
+PeCoffLoader64GetPeHeader (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
+  OUT    EFI_IMAGE_NT_HEADERS64                  *PeHdr
+  );
+
+STATIC
+EFI_STATUS
+PeCoffLoader64CheckImageType (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
+  IN     EFI_IMAGE_NT_HEADERS64                  *PeHdr
+  );
+
+STATIC
+VOID *
+PeCoffLoader64ImageAddress (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
+  IN     UINTN                                 Address
+  );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64GetImageInfo (
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64RelocateImage (
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64LoadImage (
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64UnloadImage (
+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,
+  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext
+  );
+
+EFI_STATUS
+PeCoffLoader64RelocateImageEx (
+  IN UINT16      *Reloc,
+  IN OUT CHAR8   *Fixup, 
+  IN OUT CHAR8   **FixupData,
+  IN UINT64      Adjust
+  );
+
+EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoaderX64 = {
+  PeCoffLoader64GetImageInfo,
+  PeCoffLoader64LoadImage,
+  PeCoffLoader64RelocateImage,
+  PeCoffLoader64UnloadImage
+};
+
+STATIC
+EFI_STATUS
+PeCoffLoader64GetPeHeader (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
+  OUT    EFI_IMAGE_NT_HEADERS64                *PeHdr
+  )
+/*++
+
+Routine Description:
+  Retrieves the PE Header from a PE/COFF image
+
+Arguments:
+  ImageContext  - The context of the image being loaded
+  PeHdr         - The buffer in which to return the PE header
+
+Returns:
+  EFI_SUCCESS if the PE Header is read, 
+  Otherwise, the error status from reading the PE/COFF image using the ImageRead function.
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_IMAGE_DOS_HEADER  DosHdr;
+  UINTN                 Size;
+  
+  //
+  // Read the DOS image headers
+  //
+  Size = sizeof (EFI_IMAGE_DOS_HEADER);
+  Status = ImageContext->ImageRead (
+                           ImageContext->Handle, 
+                           0,
+                           &Size, 
+                           &DosHdr
+                           );
+  if (EFI_ERROR (Status)) {
+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+    return Status;
+  }
+
+  ImageContext->PeCoffHeaderOffset = 0;
+  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+    //
+    // DOS image header is present, so read the PE header after the DOS image header
+    //
+    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;
+  } 
+
+  //
+  // Read the PE/COFF Header
+  //
+  Size = sizeof (EFI_IMAGE_NT_HEADERS64);
+  Status = ImageContext->ImageRead (
+                           ImageContext->Handle, 
+                           ImageContext->PeCoffHeaderOffset, 
+                           &Size, 
+                           PeHdr
+                           );
+  if (EFI_ERROR (Status)) {
+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+      return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+static
+EFI_STATUS
+PeCoffLoader64CheckImageType (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,
+  IN     EFI_IMAGE_NT_HEADERS64                    *PeHdr
+  )
+/*++
+
+Routine Description:
+  Checks the PE header of a PE/COFF image to determine if it supported
+
+Arguments:
+  ImageContext  - The context of the image being loaded
+  PeHdr         - The buffer in which to return the PE header
+
+Returns:
+  EFI_SUCCESS if the PE/COFF image is supported
+  EFI_UNSUPPORTED of the PE/COFF image is not supported.
+
+--*/
+{
+  //
+  // Check the PE/COFF Header SIgnature
+  //
+  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE;
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)
+  // and the machine type for the Virtual Machine.
+  //
+  ImageContext->Machine = PeHdr->FileHeader.Machine;
+  if (!(IMAGE_64_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // See if the image type is supported.  We support EFI Applications, 
+  // EFI Boot Service Drivers, and EFI Runtime Drivers.
+  //
+  ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;
+  switch (ImageContext->ImageType) {
+
+  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
+    ImageContext->ImageCodeMemoryType = EfiLoaderCode;
+    ImageContext->ImageDataMemoryType = EfiLoaderData;
+    break;
+  
+  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;
+    ImageContext->ImageDataMemoryType = EfiBootServicesData;
+    break;
+  
+  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;
+    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;
+    break;
+  
+  default:
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64GetImageInfo (
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext
+  )
+/*++
+
+Routine Description:
+  Retrieves information on a PE/COFF image
+
+Arguments:
+  ImageContext  - The context of the image being loaded
+  PeHdr         - The buffer in which to return the PE header
+
+Returns:
+  EFI_SUCCESS if the information on the PE/COFF image was collected.
+  EFI_UNSUPPORTED of the PE/COFF image is not supported.
+  Otherwise, the error status from reading the PE/COFF image using the 
+    ImageContext->ImageRead() function
+
+--*/
+{
+  EFI_STATUS                      Status;
+  EFI_IMAGE_NT_HEADERS64          PeHdr;
+  EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;
+  UINTN                           Size;
+  UINTN                           Index;
+  UINTN                           DebugDirectoryEntryRva;
+  UINTN                           DebugDirectoryEntryFileOffset;
+  UINTN                           SectionHeaderOffset;
+  EFI_IMAGE_SECTION_HEADER        SectionHeader;
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;
+
+  if (NULL == ImageContext) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Assume success
+  //
+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
+  
+  Status = PeCoffLoader64GetPeHeader (ImageContext, &PeHdr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Verify machine type
+  //
+  Status = PeCoffLoader64CheckImageType (ImageContext, &PeHdr);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Retrieve the base address of the image
+  //
+  ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;
+  
+  //
+  // Initialize the alternate destination address to 0 indicating that it 
+  // should not be used.
+  //
+  ImageContext->DestinationAddress = 0;
+
+  //
+  // Initialize the codeview pointer.
+  //
+  ImageContext->CodeView   = NULL;
+  ImageContext->PdbPointer = NULL;
+  
+  //
+  // Three cases with regards to relocations:
+  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable
+  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable
+  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but
+  //   has no base relocs to apply
+  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.
+  //
+  // Look at the file header to determine if relocations have been stripped, and
+  // save this info in the image context for later use.
+  //
+  if (PeHdr.FileHeader.Characteristics &  EFI_IMAGE_FILE_RELOCS_STRIPPED) {
+    ImageContext->RelocationsStripped = TRUE;
+  } else {
+    ImageContext->RelocationsStripped = FALSE;
+  }
+
+  ImageContext->ImageSize        = (UINT64)PeHdr.OptionalHeader.SizeOfImage;
+  ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment;
+  ImageContext->SizeOfHeaders    = PeHdr.OptionalHeader.SizeOfHeaders; 
+
+  //
+  // Modify ImageSize to contain .PDB file name if required and initialize
+  // PdbRVA field...
+  //
+
+  if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+    DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
+      &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+
+    DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
+
+    //
+    // Determine the file offset of the debug directory...  This means we walk
+    // the sections to find which section contains the RVA of the debug
+    // directory
+    //
+    
+    DebugDirectoryEntryFileOffset = 0;
+    
+    SectionHeaderOffset = (UINTN) (
+                      ImageContext->PeCoffHeaderOffset +
+                      sizeof (UINT32) + 
+                      sizeof (EFI_IMAGE_FILE_HEADER) + 
+                      PeHdr.FileHeader.SizeOfOptionalHeader
+                      );
+    
+    for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index += 1) {
+      //
+      // Read section header from file
+      //
+      Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+      Status = ImageContext->ImageRead (
+                               ImageContext->Handle, 
+                               SectionHeaderOffset, 
+                               &Size, 
+                               &SectionHeader
+                               );
+      if (EFI_ERROR (Status)) {
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+        return Status;
+      }
+      
+      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
+          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
+        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;
+        break;
+      }
+      
+      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+    }
+    
+    if (DebugDirectoryEntryFileOffset != 0) {
+      for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
+        //
+        // Read next debug directory entry
+        //
+        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+        Status = ImageContext->ImageRead (
+                                 ImageContext->Handle, 
+                                 DebugDirectoryEntryFileOffset, 
+                                 &Size, 
+                                 &DebugEntry
+                                 );
+        if (EFI_ERROR (Status)) {
+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+          return Status;
+        }
+        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
+          if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
+            ImageContext->ImageSize += DebugEntry.SizeOfData;
+          }
+          return EFI_SUCCESS;
+        }
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+static
+VOID *
+PeCoffLoader64ImageAddress (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,
+  IN     UINTN                                     Address
+  )
+/*++
+
+Routine Description:
+  Converts an image address to the loaded address
+
+Arguments:
+  ImageContext  - The context of the image being loaded
+  Address       - The address to be converted to the loaded address
+
+Returns:
+  NULL if the address can not be converted, otherwise, the converted address
+
+--*/
+{
+  if (Address >= ImageContext->ImageSize) {
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+    return NULL;
+  }
+  return (CHAR8 *)((UINTN)ImageContext->ImageAddress + Address);
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64RelocateImage (
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext
+  )
+/*++
+
+Routine Description:
+  Relocates a PE/COFF image in memory
+
+Arguments:
+  ImageContext - Contains information on the loaded image to relocate
+
+Returns:
+  EFI_SUCCESS    if the PE/COFF image was relocated
+  EFI_LOAD_ERROR if the image is not a valid PE/COFF image
+
+--*/
+{
+  EFI_STATUS                 Status;
+  EFI_IMAGE_NT_HEADERS64     *PeHdr;
+  EFI_IMAGE_DATA_DIRECTORY   *RelocDir;
+  IN UINT64                  Adjust;
+  EFI_IMAGE_BASE_RELOCATION  *RelocBase;
+  EFI_IMAGE_BASE_RELOCATION  *RelocBaseEnd;
+  UINT16                     *Reloc;
+  UINT16                     *RelocEnd;
+  CHAR8                      *Fixup;
+  CHAR8                      *FixupBase;
+  UINT16                     *F16;
+  UINT32                     *F32;
+  CHAR8                      *FixupData;
+  EFI_PHYSICAL_ADDRESS       BaseAddress;
+
+
+  //
+  // Assume success
+  //
+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
+
+  //
+  // If there are no relocation entries, then we are done
+  //
+  if (ImageContext->RelocationsStripped) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // If the destination address is not 0, use that rather than the
+  // image address as the relocation target.
+  //
+  if (ImageContext->DestinationAddress) {
+    BaseAddress = ImageContext->DestinationAddress;
+  } else {
+    BaseAddress = ImageContext->ImageAddress;
+  }
+  PeHdr    = (EFI_IMAGE_NT_HEADERS64 *)((UINTN)ImageContext->ImageAddress + 
+                                            ImageContext->PeCoffHeaderOffset);
+  Adjust   = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;
+
+  PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;
+
+  //
+  // Find the relocation block
+  //
+  // Per the PE/COFF spec, you can't assume that a given data directory 
+  // is present in the image. You have to check the NumberOfRvaAndSizes in 
+  // the optional header to verify a desired directory entry is there.
+  //
+  if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+    RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+    RelocBase = PeCoffLoader64ImageAddress (ImageContext, RelocDir->VirtualAddress);
+    RelocBaseEnd = PeCoffLoader64ImageAddress ( 
+                    ImageContext, 
+                    RelocDir->VirtualAddress + RelocDir->Size - 1
+                    );
+} else {
+    //
+    // Set base and end to bypass processing below.
+    //
+    RelocBase = RelocBaseEnd = 0;
+  }
+  //
+  // Run the relocation information and apply the fixups
+  //
+  FixupData = ImageContext->FixupData;
+  while (RelocBase < RelocBaseEnd) {
+           
+    Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));
+    RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
+    FixupBase = PeCoffLoader64ImageAddress (ImageContext, RelocBase->VirtualAddress);
+    if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN)ImageContext->ImageAddress) || 
+        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + 
+          (UINTN)ImageContext->ImageSize)) {
+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+      return EFI_LOAD_ERROR;
+    }
+
+    //
+    // Run this relocation record
+    //
+    while (Reloc < RelocEnd) {
+
+      Fixup = FixupBase + (*Reloc & 0xFFF);
+      switch ((*Reloc) >> 12) {
+      case EFI_IMAGE_REL_BASED_ABSOLUTE:
+        break;
+      case EFI_IMAGE_REL_BASED_HIGH:
+        F16 = (UINT16 *) Fixup;
+        *F16 = (UINT16)((*F16 << 16) + (UINT16) Adjust);
+        if (FixupData != NULL) {
+          *(UINT16 *) FixupData = *F16;
+          FixupData = FixupData + sizeof(UINT16);
+        }
+        break;
+      case EFI_IMAGE_REL_BASED_LOW:
+        F16 = (UINT16 *) Fixup;
+        *F16 = (UINT16)(*F16 + (UINT16) Adjust);
+        if (FixupData != NULL) {
+          *(UINT16 *) FixupData = *F16;
+          FixupData = FixupData + sizeof(UINT16);
+        }
+        break;
+      case EFI_IMAGE_REL_BASED_HIGHLOW:
+        F32 = (UINT32 *) Fixup;
+        *F32 = *F32 + (UINT32) Adjust;
+        if (FixupData != NULL) {
+          FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));
+          *(UINT32 *) FixupData = *F32;
+          FixupData = FixupData + sizeof(UINT32);
+        }
+        break;
+      case EFI_IMAGE_REL_BASED_HIGHADJ:
+        // Return the same EFI_UNSUPPORTED return code as 
+        // PeCoffLoader64RelocateImageEx() returns if it does not recognize
+        // the relocation type.
+        //
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+        return EFI_UNSUPPORTED;
+      default:
+        Status = PeCoffLoader64RelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
+        if (EFI_ERROR (Status)) {
+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+          return Status;
+        }
+      }
+
+      //
+      // Next relocation record
+      //
+      Reloc += 1;
+    }
+
+    //
+    // Next reloc block
+    //
+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PeCoffLoader64RelocateImageEx (
+  IN UINT16      *Reloc,
+  IN OUT CHAR8   *Fixup, 
+  IN OUT CHAR8   **FixupData,
+  IN UINT64      Adjust
+  )
+/*++
+
+Routine Description:
+  Performs an IA-32 specific relocation fixup
+
+Arguments:
+  Reloc      - Pointer to the relocation record
+  Fixup      - Pointer to the address to fix up
+  FixupData  - Pointer to a buffer to log the fixups
+  Adjust     - The offset to adjust the fixup
+
+Returns:
+  None
+
+--*/
+{
+  UINT64      *F64;
+
+  switch ((*Reloc) >> 12) {
+
+    case EFI_IMAGE_REL_BASED_DIR64:
+      F64 = (UINT64 *) Fixup;
+      *F64 = *F64 + (UINT64) Adjust;
+      if (*FixupData != NULL) {
+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
+        *(UINT64 *)(*FixupData) = *F64;
+        *FixupData = *FixupData + sizeof(UINT64);
+      }
+      break;
+
+    default:
+      return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64LoadImage (
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext
+  )
+/*++
+
+Routine Description:
+  Loads a PE/COFF image into memory
+
+Arguments:
+  ImageContext - Contains information on image to load into memory
+
+Returns:
+  EFI_SUCCESS            if the PE/COFF image was loaded
+  EFI_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer
+  EFI_LOAD_ERROR         if the image is a runtime driver with no relocations
+  EFI_INVALID_PARAMETER  if the image address is invalid
+
+--*/
+{
+  EFI_STATUS                            Status;
+  EFI_IMAGE_NT_HEADERS64                *PeHdr;
+  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;
+  EFI_IMAGE_SECTION_HEADER              *FirstSection;
+  EFI_IMAGE_SECTION_HEADER              *Section;
+  UINTN                                 Index;
+  CHAR8                                 *Base;
+  CHAR8                                 *End;
+  CHAR8                                 *MaxEnd;
+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
+  UINTN                                 Size;
+  UINT32                                TempDebugEntryRva;
+
+  //
+  // Assume success
+  //
+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
+
+  //
+  // Copy the provided context info into our local version, get what we
+  // can from the original image, and then use that to make sure everything
+  // is legit.
+  //
+  CopyMem (
+    &CheckContext, 
+    ImageContext, 
+    sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)
+    );
+            
+  Status = PeCoffLoader64GetImageInfo (
+             This,
+             &CheckContext 
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Make sure there is enough allocated space for the image being loaded
+  //
+  if (ImageContext->ImageSize < CheckContext.ImageSize) {
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  //
+  // If there's no relocations, then make sure it's not a runtime driver,
+  // and that it's being loaded at the linked address.
+  //
+  if (CheckContext.RelocationsStripped == TRUE) {
+    //
+    // If the image does not contain relocations and it is a runtime driver 
+    // then return an error.
+    //
+    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
+      return EFI_LOAD_ERROR;
+    }
+    //
+    // If the image does not contain relocations, and the requested load address 
+    // is not the linked address, then return an error.
+    //
+    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {
+      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Make sure the allocated space has the proper section alignment
+  //
+  if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Read the entire PE/COFF header into memory
+  //
+  Status = ImageContext->ImageRead (
+                ImageContext->Handle, 
+                0, 
+                &ImageContext->SizeOfHeaders, 
+                (VOID *)(UINTN)ImageContext->ImageAddress
+                );
+  if (EFI_ERROR(Status)) {
+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+    return EFI_LOAD_ERROR;
+  }
+
+  PeHdr = (EFI_IMAGE_NT_HEADERS64 *)
+      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
+
+  //
+  // Load each section of the image
+  //
+  FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
+                      (UINTN)ImageContext->ImageAddress +
+                      ImageContext->PeCoffHeaderOffset +
+                      sizeof(UINT32) + 
+                      sizeof(EFI_IMAGE_FILE_HEADER) + 
+                      PeHdr->FileHeader.SizeOfOptionalHeader
+                      );
+
+  Section = FirstSection;
+  for ( Index=0, MaxEnd = NULL; 
+        Index < PeHdr->FileHeader.NumberOfSections; 
+        Index += 1) {
+
+    //
+    // Compute sections address
+    //
+    Base = PeCoffLoader64ImageAddress (ImageContext, Section->VirtualAddress);
+    End  = PeCoffLoader64ImageAddress (
+                  ImageContext, 
+                  Section->VirtualAddress + Section->Misc.VirtualSize - 1);
+    if (End > MaxEnd) {
+      MaxEnd = End;
+    }
+    //
+    // If the base start or end address resolved to 0, then fail.
+    //
+    if (!Base  ||  !End) {
+      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;
+      return EFI_LOAD_ERROR;
+    }
+
+    //
+    // Read the section, we can resume the length of PE image can't 
+    // exceed the max 32bit integer
+    //
+    Size = (UINTN) Section->Misc.VirtualSize;
+    if ((Size == 0) || (Size > Section->SizeOfRawData)) {
+      Size = (UINTN) Section->SizeOfRawData;
+    }
+    if (Section->SizeOfRawData) {
+      Status = ImageContext->ImageRead (
+                               ImageContext->Handle, 
+                               Section->PointerToRawData, 
+                               &Size, 
+                               Base);
+      if (EFI_ERROR(Status)) {
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+        return Status;
+      }
+    }
+
+    //
+    // If raw size is less then virt size, zero fill the remaining
+    //
+
+    if (Size < Section->Misc.VirtualSize) {
+      ZeroMem (Base + Size, Section->Misc.VirtualSize - (UINTN)Size);
+    }
+
+    //
+    // Next Section
+    //
+    Section += 1;
+  }
+
+  //
+  // Get image's entry point
+  //
+  ImageContext->EntryPoint = 
+      (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoader64ImageAddress (
+                                      ImageContext, 
+                                      PeHdr->OptionalHeader.AddressOfEntryPoint
+                                      );
+
+  //
+  // Determine the size of the fixup data
+  //
+  // Per the PE/COFF spec, you can't assume that a given data directory 
+  // is present in the image. You have to check the NumberOfRvaAndSizes in 
+  // the optional header to verify a desired directory entry is there.
+  //
+  if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+    DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
+      &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+    ImageContext->FixupDataSize = 
+      DirectoryEntry->Size / sizeof(UINT16) * sizeof(UINTN);
+  } else {
+    ImageContext->FixupDataSize = 0;
+  }
+  //
+  // Consumer must allocate a buffer for the relocation fixup log.
+  // Only used for runtime drivers.
+  //
+  ImageContext->FixupData     = NULL;
+
+  //
+  // Load the Codeview info if present
+  //
+  if (ImageContext->DebugDirectoryEntryRva != 0) {
+    DebugEntry = PeCoffLoader64ImageAddress (
+                  ImageContext, 
+                  ImageContext->DebugDirectoryEntryRva
+                  );
+    if (DebugEntry != NULL) {
+      TempDebugEntryRva = DebugEntry->RVA;
+      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
+        Section--;
+        if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {
+          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
+        } else {
+          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
+        }
+      }
+      if (TempDebugEntryRva != 0) {
+        ImageContext->CodeView = PeCoffLoader64ImageAddress (ImageContext, TempDebugEntryRva);
+        if (ImageContext->CodeView == NULL) {
+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+          return EFI_LOAD_ERROR;
+        }
+
+        if (DebugEntry->RVA == 0) {
+          Size = (UINTN) DebugEntry->SizeOfData;
+          Status = ImageContext->ImageRead (
+                        ImageContext->Handle, 
+                        DebugEntry->FileOffset,
+                        &Size, 
+                        ImageContext->CodeView
+                        );
+          if (EFI_ERROR(Status)) {
+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+            return EFI_LOAD_ERROR;
+          }
+          DebugEntry->RVA = TempDebugEntryRva;
+        }
+
+        switch (* (UINT32 *) ImageContext->CodeView) {
+          case CODEVIEW_SIGNATURE_NB10:
+            ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+            break;
+          case CODEVIEW_SIGNATURE_RSDS:
+            ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+            break;
+          default:
+            break;
+        }
+      }
+    }
+  }
+  
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoader64UnloadImage (
+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,
+  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext
+  )
+/*++
+
+Routine Description:
+  Unload of images is not supported
+
+Arguments:
+  ImageContext - The image to unload
+
+Returns:
+  EFI_SUCCESS
+
+--*/
+{
+  return EFI_SUCCESS;
+}
+
+EFI_PEI_PE_COFF_LOADER_PROTOCOL *
+EFIAPI
+GetPeCoffLoaderProtocol (
+  )
+{
+  return &mPeCoffLoaderX64;
+}
+
+
diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.mbd b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.mbd
new file mode 100644
index 0000000..fd0b050
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.mbd
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MbdLibHeader>
+    <BaseName>EdkPeCoffLoaderLibX64</BaseName>
+    <Guid>742597d6-2b50-4120-bfba-2400549a792f</Guid>
+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-04-26 13:50</Created>
+  </MbdLibHeader>
+</LibraryModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.msa b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.msa
new file mode 100644
index 0000000..097cb71
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.msa
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MsaLibHeader>
+    <BaseName>EdkPeCoffLoaderLibX64</BaseName>
+    <ModuleType>DXE_CORE</ModuleType>
+    <ComponentType>LIBRARY</ComponentType>
+    <Guid>742597d6-2b50-4120-bfba-2400549a792f</Guid>
+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>
+    <Abstract>Component description file for the PEI library.</Abstract>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-04-26 13:50</Created>
+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>
+  </MsaLibHeader>
+  <LibraryClassDefinitions>
+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkPeCoffLoaderLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+    <LibraryClass Usage="ALWAYS_CONSUMED">PeCoffLib</LibraryClass>
+  </LibraryClassDefinitions>
+  <SourceFiles>
+    <Filename>EdkPeCoffLoaderLibX64.c</Filename>
+  </SourceFiles>
+  <Includes>
+    <PackageName>MdePkg</PackageName>
+    <PackageName>EdkModulePkg</PackageName>
+  </Includes>
+</LibraryModuleSurfaceArea>
diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/build.xml b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/build.xml
new file mode 100644
index 0000000..6a41900
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderLibX64/build.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 
+All rights reserved. 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.-->
+<project basedir="." default="EdkPeCoffLoaderLibX64"><!--Apply external ANT tasks-->
+   <taskdef resource="GenBuild.tasks"/>
+   <property environment="env"/>
+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkPeCoffLoaderLibX64"/>
+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>
+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>
+   <target name="EdkPeCoffLoaderLibX64">
+      <GenBuild baseName="EdkPeCoffLoaderLibX64" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderLibX64.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderLibX64.msa"/>
+   </target>
+   <target depends="EdkPeCoffLoaderLibX64_clean" name="clean"/>
+   <target depends="EdkPeCoffLoaderLibX64_cleanAll" name="cleanAll"/>
+   <target name="EdkPeCoffLoaderLibX64_clean">
+      <OutputDirSetup baseName="EdkPeCoffLoaderLibX64" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderLibX64.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderLibX64.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLibX64_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLibX64_build.xml" target="clean"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+   </target>
+   <target name="EdkPeCoffLoaderLibX64_cleanAll">
+      <OutputDirSetup baseName="EdkPeCoffLoaderLibX64" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderLibX64.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderLibX64.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLibX64_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderLibX64_build.xml" target="cleanAll"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}"/>
+      <delete dir="${DEST_DIR_DEBUG}"/>
+      <delete>
+         <fileset dir="${BIN_DIR}" includes="**EdkPeCoffLoaderLibX64*"/>
+      </delete>
+   </target>
+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64.c b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64.c
new file mode 100644
index 0000000..a286257
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64.c
@@ -0,0 +1,940 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EdkPeCoffLoaderX64.c

+

+Abstract:

+

+  Wrap the Base PE/COFF loader with the PE COFF Protocol

+

+

+--*/

+

+#define IMAGE_64_MACHINE_TYPE_SUPPORTED(Machine) \

+  ((Machine) == EFI_IMAGE_MACHINE_IA32 || \

+   (Machine) == EFI_IMAGE_MACHINE_X64 || \

+   (Machine) == EFI_IMAGE_MACHINE_EBC)

+

+STATIC

+EFI_STATUS

+PeCoffLoader64GetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  OUT    EFI_IMAGE_NT_HEADERS64                  *PeHdr

+  );

+

+STATIC

+EFI_STATUS

+PeCoffLoader64CheckImageType (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  IN     EFI_IMAGE_NT_HEADERS64                  *PeHdr

+  );

+

+STATIC

+VOID *

+PeCoffLoader64ImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  IN     UINTN                                 Address

+  );

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64GetImageInfo (

+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  );

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64RelocateImage (

+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  );

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64LoadImage (

+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  );

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64UnloadImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,

+  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext

+  );

+

+EFI_STATUS

+PeCoffLoader64RelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup, 

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  );

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoaderX64 = {

+  PeCoffLoader64GetImageInfo,

+  PeCoffLoader64LoadImage,

+  PeCoffLoader64RelocateImage,

+  PeCoffLoader64UnloadImage

+};

+

+STATIC

+EFI_STATUS

+PeCoffLoader64GetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  OUT    EFI_IMAGE_NT_HEADERS64                *PeHdr

+  )

+/*++

+

+Routine Description:

+  Retrieves the PE Header from a PE/COFF image

+

+Arguments:

+  ImageContext  - The context of the image being loaded

+  PeHdr         - The buffer in which to return the PE header

+

+Returns:

+  EFI_SUCCESS if the PE Header is read, 

+  Otherwise, the error status from reading the PE/COFF image using the ImageRead function.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_IMAGE_DOS_HEADER  DosHdr;

+  UINTN                 Size;

+  

+  //

+  // Read the DOS image headers

+  //

+  Size = sizeof (EFI_IMAGE_DOS_HEADER);

+  Status = ImageContext->ImageRead (

+                           ImageContext->Handle, 

+                           0,

+                           &Size, 

+                           &DosHdr

+                           );

+  if (EFI_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return Status;

+  }

+

+  ImageContext->PeCoffHeaderOffset = 0;

+  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header

+    //

+    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;

+  } 

+

+  //

+  // Read the PE/COFF Header

+  //

+  Size = sizeof (EFI_IMAGE_NT_HEADERS64);

+  Status = ImageContext->ImageRead (

+                           ImageContext->Handle, 

+                           ImageContext->PeCoffHeaderOffset, 

+                           &Size, 

+                           PeHdr

+                           );

+  if (EFI_ERROR (Status)) {

+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+      return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+static

+EFI_STATUS

+PeCoffLoader64CheckImageType (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,

+  IN     EFI_IMAGE_NT_HEADERS64                    *PeHdr

+  )

+/*++

+

+Routine Description:

+  Checks the PE header of a PE/COFF image to determine if it supported

+

+Arguments:

+  ImageContext  - The context of the image being loaded

+  PeHdr         - The buffer in which to return the PE header

+

+Returns:

+  EFI_SUCCESS if the PE/COFF image is supported

+  EFI_UNSUPPORTED of the PE/COFF image is not supported.

+

+--*/

+{

+  //

+  // Check the PE/COFF Header SIgnature

+  //

+  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE;

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)

+  // and the machine type for the Virtual Machine.

+  //

+  ImageContext->Machine = PeHdr->FileHeader.Machine;

+  if (!(IMAGE_64_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // See if the image type is supported.  We support EFI Applications, 

+  // EFI Boot Service Drivers, and EFI Runtime Drivers.

+  //

+  ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;

+  switch (ImageContext->ImageType) {

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:

+    ImageContext->ImageCodeMemoryType = EfiLoaderCode;

+    ImageContext->ImageDataMemoryType = EfiLoaderData;

+    break;

+  

+  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:

+    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;

+    ImageContext->ImageDataMemoryType = EfiBootServicesData;

+    break;

+  

+  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:

+  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:

+    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;

+    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;

+    break;

+  

+  default:

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64GetImageInfo (

+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext

+  )

+/*++

+

+Routine Description:

+  Retrieves information on a PE/COFF image

+

+Arguments:

+  ImageContext  - The context of the image being loaded

+  PeHdr         - The buffer in which to return the PE header

+

+Returns:

+  EFI_SUCCESS if the information on the PE/COFF image was collected.

+  EFI_UNSUPPORTED of the PE/COFF image is not supported.

+  Otherwise, the error status from reading the PE/COFF image using the 

+    ImageContext->ImageRead() function

+

+--*/

+{

+  EFI_STATUS                      Status;

+  EFI_IMAGE_NT_HEADERS64          PeHdr;

+  EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;

+  UINTN                           Size;

+  UINTN                           Index;

+  UINTN                           DebugDirectoryEntryRva;

+  UINTN                           DebugDirectoryEntryFileOffset;

+  UINTN                           SectionHeaderOffset;

+  EFI_IMAGE_SECTION_HEADER        SectionHeader;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;

+

+  if (NULL == ImageContext) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+  

+  Status = PeCoffLoader64GetPeHeader (ImageContext, &PeHdr);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Verify machine type

+  //

+  Status = PeCoffLoader64CheckImageType (ImageContext, &PeHdr);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  //

+  // Retrieve the base address of the image

+  //

+  ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;

+  

+  //

+  // Initialize the alternate destination address to 0 indicating that it 

+  // should not be used.

+  //

+  ImageContext->DestinationAddress = 0;

+

+  //

+  // Initialize the codeview pointer.

+  //

+  ImageContext->CodeView   = NULL;

+  ImageContext->PdbPointer = NULL;

+  

+  //

+  // Three cases with regards to relocations:

+  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but

+  //   has no base relocs to apply

+  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.

+  //

+  // Look at the file header to determine if relocations have been stripped, and

+  // save this info in the image context for later use.

+  //

+  if (PeHdr.FileHeader.Characteristics &  EFI_IMAGE_FILE_RELOCS_STRIPPED) {

+    ImageContext->RelocationsStripped = TRUE;

+  } else {

+    ImageContext->RelocationsStripped = FALSE;

+  }

+

+  ImageContext->ImageSize        = (UINT64)PeHdr.OptionalHeader.SizeOfImage;

+  ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment;

+  ImageContext->SizeOfHeaders    = PeHdr.OptionalHeader.SizeOfHeaders; 

+

+  //

+  // Modify ImageSize to contain .PDB file name if required and initialize

+  // PdbRVA field...

+  //

+

+  if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+    DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)

+      &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+

+    DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;

+

+    //

+    // Determine the file offset of the debug directory...  This means we walk

+    // the sections to find which section contains the RVA of the debug

+    // directory

+    //

+    

+    DebugDirectoryEntryFileOffset = 0;

+    

+    SectionHeaderOffset = (UINTN) (

+                      ImageContext->PeCoffHeaderOffset +

+                      sizeof (UINT32) + 

+                      sizeof (EFI_IMAGE_FILE_HEADER) + 

+                      PeHdr.FileHeader.SizeOfOptionalHeader

+                      );

+    

+    for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index += 1) {

+      //

+      // Read section header from file

+      //

+      Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle, 

+                               SectionHeaderOffset, 

+                               &Size, 

+                               &SectionHeader

+                               );

+      if (EFI_ERROR (Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+      

+      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;

+        break;

+      }

+      

+      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+    }

+    

+    if (DebugDirectoryEntryFileOffset != 0) {

+      for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {

+        //

+        // Read next debug directory entry

+        //

+        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle, 

+                                 DebugDirectoryEntryFileOffset, 

+                                 &Size, 

+                                 &DebugEntry

+                                 );

+        if (EFI_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return Status;

+        }

+        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));

+          if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {

+            ImageContext->ImageSize += DebugEntry.SizeOfData;

+          }

+          return EFI_SUCCESS;

+        }

+      }

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+static

+VOID *

+PeCoffLoader64ImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,

+  IN     UINTN                                     Address

+  )

+/*++

+

+Routine Description:

+  Converts an image address to the loaded address

+

+Arguments:

+  ImageContext  - The context of the image being loaded

+  Address       - The address to be converted to the loaded address

+

+Returns:

+  NULL if the address can not be converted, otherwise, the converted address

+

+--*/

+{

+  if (Address >= ImageContext->ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+    return NULL;

+  }

+  return (CHAR8 *)((UINTN)ImageContext->ImageAddress + Address);

+}

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64RelocateImage (

+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext

+  )

+/*++

+

+Routine Description:

+  Relocates a PE/COFF image in memory

+

+Arguments:

+  ImageContext - Contains information on the loaded image to relocate

+

+Returns:

+  EFI_SUCCESS    if the PE/COFF image was relocated

+  EFI_LOAD_ERROR if the image is not a valid PE/COFF image

+

+--*/

+{

+  EFI_STATUS                 Status;

+  EFI_IMAGE_NT_HEADERS64     *PeHdr;

+  EFI_IMAGE_DATA_DIRECTORY   *RelocDir;

+  IN UINT64                  Adjust;

+  EFI_IMAGE_BASE_RELOCATION  *RelocBase;

+  EFI_IMAGE_BASE_RELOCATION  *RelocBaseEnd;

+  UINT16                     *Reloc;

+  UINT16                     *RelocEnd;

+  CHAR8                      *Fixup;

+  CHAR8                      *FixupBase;

+  UINT16                     *F16;

+  UINT32                     *F32;

+  CHAR8                      *FixupData;

+  EFI_PHYSICAL_ADDRESS       BaseAddress;

+

+

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // If there are no relocation entries, then we are done

+  //

+  if (ImageContext->RelocationsStripped) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // If the destination address is not 0, use that rather than the

+  // image address as the relocation target.

+  //

+  if (ImageContext->DestinationAddress) {

+    BaseAddress = ImageContext->DestinationAddress;

+  } else {

+    BaseAddress = ImageContext->ImageAddress;

+  }

+  PeHdr    = (EFI_IMAGE_NT_HEADERS64 *)((UINTN)ImageContext->ImageAddress + 

+                                            ImageContext->PeCoffHeaderOffset);

+  Adjust   = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;

+

+  PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;

+

+  //

+  // Find the relocation block

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory 

+  // is present in the image. You have to check the NumberOfRvaAndSizes in 

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+    RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+    RelocBase = PeCoffLoader64ImageAddress (ImageContext, RelocDir->VirtualAddress);

+    RelocBaseEnd = PeCoffLoader64ImageAddress ( 

+                    ImageContext, 

+                    RelocDir->VirtualAddress + RelocDir->Size - 1

+                    );

+} else {

+    //

+    // Set base and end to bypass processing below.

+    //

+    RelocBase = RelocBaseEnd = 0;

+  }

+  //

+  // Run the relocation information and apply the fixups

+  //

+  FixupData = ImageContext->FixupData;

+  while (RelocBase < RelocBaseEnd) {

+           

+    Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));

+    RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);

+    FixupBase = PeCoffLoader64ImageAddress (ImageContext, RelocBase->VirtualAddress);

+    if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN)ImageContext->ImageAddress) || 

+        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + 

+          (UINTN)ImageContext->ImageSize)) {

+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+      return EFI_LOAD_ERROR;

+    }

+

+    //

+    // Run this relocation record

+    //

+    while (Reloc < RelocEnd) {

+

+      Fixup = FixupBase + (*Reloc & 0xFFF);

+      switch ((*Reloc) >> 12) {

+      case EFI_IMAGE_REL_BASED_ABSOLUTE:

+        break;

+      case EFI_IMAGE_REL_BASED_HIGH:

+        F16 = (UINT16 *) Fixup;

+        *F16 = (UINT16)((*F16 << 16) + (UINT16) Adjust);

+        if (FixupData != NULL) {

+          *(UINT16 *) FixupData = *F16;

+          FixupData = FixupData + sizeof(UINT16);

+        }

+        break;

+      case EFI_IMAGE_REL_BASED_LOW:

+        F16 = (UINT16 *) Fixup;

+        *F16 = (UINT16)(*F16 + (UINT16) Adjust);

+        if (FixupData != NULL) {

+          *(UINT16 *) FixupData = *F16;

+          FixupData = FixupData + sizeof(UINT16);

+        }

+        break;

+      case EFI_IMAGE_REL_BASED_HIGHLOW:

+        F32 = (UINT32 *) Fixup;

+        *F32 = *F32 + (UINT32) Adjust;

+        if (FixupData != NULL) {

+          FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));

+          *(UINT32 *) FixupData = *F32;

+          FixupData = FixupData + sizeof(UINT32);

+        }

+        break;

+      case EFI_IMAGE_REL_BASED_HIGHADJ:

+        // Return the same EFI_UNSUPPORTED return code as 

+        // PeCoffLoader64RelocateImageEx() returns if it does not recognize

+        // the relocation type.

+        //

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return EFI_UNSUPPORTED;

+      default:

+        Status = PeCoffLoader64RelocateImageEx (Reloc, Fixup, &FixupData, Adjust);

+        if (EFI_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+          return Status;

+        }

+      }

+

+      //

+      // Next relocation record

+      //

+      Reloc += 1;

+    }

+

+    //

+    // Next reloc block

+    //

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+PeCoffLoader64RelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup, 

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+  Performs an IA-32 specific relocation fixup

+

+Arguments:

+  Reloc      - Pointer to the relocation record

+  Fixup      - Pointer to the address to fix up

+  FixupData  - Pointer to a buffer to log the fixups

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+  None

+

+--*/

+{

+  UINT64      *F64;

+

+  switch ((*Reloc) >> 12) {

+

+    case EFI_IMAGE_REL_BASED_DIR64:

+      F64 = (UINT64 *) Fixup;

+      *F64 = *F64 + (UINT64) Adjust;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64LoadImage (

+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext

+  )

+/*++

+

+Routine Description:

+  Loads a PE/COFF image into memory

+

+Arguments:

+  ImageContext - Contains information on image to load into memory

+

+Returns:

+  EFI_SUCCESS            if the PE/COFF image was loaded

+  EFI_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer

+  EFI_LOAD_ERROR         if the image is a runtime driver with no relocations

+  EFI_INVALID_PARAMETER  if the image address is invalid

+

+--*/

+{

+  EFI_STATUS                            Status;

+  EFI_IMAGE_NT_HEADERS64                *PeHdr;

+  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;

+  EFI_IMAGE_SECTION_HEADER              *FirstSection;

+  EFI_IMAGE_SECTION_HEADER              *Section;

+  UINTN                                 Index;

+  CHAR8                                 *Base;

+  CHAR8                                 *End;

+  CHAR8                                 *MaxEnd;

+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;

+  UINTN                                 Size;

+  UINT32                                TempDebugEntryRva;

+

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // Copy the provided context info into our local version, get what we

+  // can from the original image, and then use that to make sure everything

+  // is legit.

+  //

+  CopyMem (

+    &CheckContext, 

+    ImageContext, 

+    sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)

+    );

+            

+  Status = PeCoffLoader64GetImageInfo (

+             This,

+             &CheckContext 

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure there is enough allocated space for the image being loaded

+  //

+  if (ImageContext->ImageSize < CheckContext.ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  //

+  // If there's no relocations, then make sure it's not a runtime driver,

+  // and that it's being loaded at the linked address.

+  //

+  if (CheckContext.RelocationsStripped == TRUE) {

+    //

+    // If the image does not contain relocations and it is a runtime driver 

+    // then return an error.

+    //

+    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+      return EFI_LOAD_ERROR;

+    }

+    //

+    // If the image does not contain relocations, and the requested load address 

+    // is not the linked address, then return an error.

+    //

+    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  //

+  // Make sure the allocated space has the proper section alignment

+  //

+  if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Read the entire PE/COFF header into memory

+  //

+  Status = ImageContext->ImageRead (

+                ImageContext->Handle, 

+                0, 

+                &ImageContext->SizeOfHeaders, 

+                (VOID *)(UINTN)ImageContext->ImageAddress

+                );

+  if (EFI_ERROR(Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return EFI_LOAD_ERROR;

+  }

+

+  PeHdr = (EFI_IMAGE_NT_HEADERS64 *)

+      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);

+

+  //

+  // Load each section of the image

+  //

+  FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+                      (UINTN)ImageContext->ImageAddress +

+                      ImageContext->PeCoffHeaderOffset +

+                      sizeof(UINT32) + 

+                      sizeof(EFI_IMAGE_FILE_HEADER) + 

+                      PeHdr->FileHeader.SizeOfOptionalHeader

+                      );

+

+  Section = FirstSection;

+  for ( Index=0, MaxEnd = NULL; 

+        Index < PeHdr->FileHeader.NumberOfSections; 

+        Index += 1) {

+

+    //

+    // Compute sections address

+    //

+    Base = PeCoffLoader64ImageAddress (ImageContext, Section->VirtualAddress);

+    End  = PeCoffLoader64ImageAddress (

+                  ImageContext, 

+                  Section->VirtualAddress + Section->Misc.VirtualSize - 1);

+    if (End > MaxEnd) {

+      MaxEnd = End;

+    }

+    //

+    // If the base start or end address resolved to 0, then fail.

+    //

+    if (!Base  ||  !End) {

+      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;

+      return EFI_LOAD_ERROR;

+    }

+

+    //

+    // Read the section, we can resume the length of PE image can't 

+    // exceed the max 32bit integer

+    //

+    Size = (UINTN) Section->Misc.VirtualSize;

+    if ((Size == 0) || (Size > Section->SizeOfRawData)) {

+      Size = (UINTN) Section->SizeOfRawData;

+    }

+    if (Section->SizeOfRawData) {

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle, 

+                               Section->PointerToRawData, 

+                               &Size, 

+                               Base);

+      if (EFI_ERROR(Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+    }

+

+    //

+    // If raw size is less then virt size, zero fill the remaining

+    //

+

+    if (Size < Section->Misc.VirtualSize) {

+      ZeroMem (Base + Size, Section->Misc.VirtualSize - (UINTN)Size);

+    }

+

+    //

+    // Next Section

+    //

+    Section += 1;

+  }

+

+  //

+  // Get image's entry point

+  //

+  ImageContext->EntryPoint = 

+      (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoader64ImageAddress (

+                                      ImageContext, 

+                                      PeHdr->OptionalHeader.AddressOfEntryPoint

+                                      );

+

+  //

+  // Determine the size of the fixup data

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory 

+  // is present in the image. You have to check the NumberOfRvaAndSizes in 

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+    DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)

+      &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+    ImageContext->FixupDataSize = 

+      DirectoryEntry->Size / sizeof(UINT16) * sizeof(UINTN);

+  } else {

+    ImageContext->FixupDataSize = 0;

+  }

+  //

+  // Consumer must allocate a buffer for the relocation fixup log.

+  // Only used for runtime drivers.

+  //

+  ImageContext->FixupData     = NULL;

+

+  //

+  // Load the Codeview info if present

+  //

+  if (ImageContext->DebugDirectoryEntryRva != 0) {

+    DebugEntry = PeCoffLoader64ImageAddress (

+                  ImageContext, 

+                  ImageContext->DebugDirectoryEntryRva

+                  );

+    if (DebugEntry != NULL) {

+      TempDebugEntryRva = DebugEntry->RVA;

+      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {

+        Section--;

+        if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {

+          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;

+        } else {

+          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;

+        }

+      }

+      if (TempDebugEntryRva != 0) {

+        ImageContext->CodeView = PeCoffLoader64ImageAddress (ImageContext, TempDebugEntryRva);

+        if (ImageContext->CodeView == NULL) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return EFI_LOAD_ERROR;

+        }

+

+        if (DebugEntry->RVA == 0) {

+          Size = (UINTN) DebugEntry->SizeOfData;

+          Status = ImageContext->ImageRead (

+                        ImageContext->Handle, 

+                        DebugEntry->FileOffset,

+                        &Size, 

+                        ImageContext->CodeView

+                        );

+          if (EFI_ERROR(Status)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            return EFI_LOAD_ERROR;

+          }

+          DebugEntry->RVA = TempDebugEntryRva;

+        }

+

+        switch (* (UINT32 *) ImageContext->CodeView) {

+          case CODEVIEW_SIGNATURE_NB10:

+            ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);

+            break;

+          case CODEVIEW_SIGNATURE_RSDS:

+            ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);

+            break;

+          default:

+            break;

+        }

+      }

+    }

+  }

+  

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PeCoffLoader64UnloadImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,

+  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext

+  )

+/*++

+

+Routine Description:

+  Unload of images is not supported

+

+Arguments:

+  ImageContext - The image to unload

+

+Returns:

+  EFI_SUCCESS

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL *

+EFIAPI

+GetPeCoffLoaderX64Protocol (

+  )

+{

+  return &mPeCoffLoaderX64;

+}

+

+

diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.mbd b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.mbd
new file mode 100644
index 0000000..8b6f365
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkPeCoffLoaderX64Lib</BaseName>

+    <Guid>6aac37f2-7b46-4ef3-8645-c24800a3d410</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-03 23:59</Created>

+    <Modified>2006-04-05 21:30</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.msa b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.msa
new file mode 100644
index 0000000..c29c01e
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/EdkPeCoffLoaderX64Lib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkPeCoffLoaderX64Lib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>6aac37f2-7b46-4ef3-8645-c24800a3d410</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-03 23:59</Created>

+    <Updated>2006-04-05 21:30</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkPeCoffLoaderX64Lib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeCoffLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>EdkPeCoffLoaderX64.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/build.xml b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/build.xml
new file mode 100644
index 0000000..7114597
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeCoffLoaderX64Lib/build.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkPeCoffLoaderX64Lib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkPeCoffLoaderX64Lib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkPeCoffLoaderX64Lib">

+      <GenBuild baseName="EdkPeCoffLoaderX64Lib" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderX64Lib.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderX64Lib.msa"/>

+   </target>

+   <target depends="EdkPeCoffLoaderX64Lib_clean" name="clean"/>

+   <target depends="EdkPeCoffLoaderX64Lib_cleanAll" name="cleanAll"/>

+   <target name="EdkPeCoffLoaderX64Lib_clean">

+      <OutputDirSetup baseName="EdkPeCoffLoaderX64Lib" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderX64Lib.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderX64Lib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderX64Lib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderX64Lib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkPeCoffLoaderX64Lib_cleanAll">

+      <OutputDirSetup baseName="EdkPeCoffLoaderX64Lib" mbdFilename="${MODULE_DIR}/EdkPeCoffLoaderX64Lib.mbd" msaFilename="${MODULE_DIR}/EdkPeCoffLoaderX64Lib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderX64Lib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeCoffLoaderX64Lib_build.xml" target="cleanAll"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkPeCoffLoaderX64Lib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.mbd b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.mbd
new file mode 100644
index 0000000..103f7c4
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkPeiPerformanceLib</BaseName>

+    <Guid>F72DE735-B24F-4ef6-897F-70A85D01A047</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:12</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.msa b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.msa
new file mode 100644
index 0000000..e3d21cf
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/EdkPeiPerformanceLib.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkPeiPerformanceLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>F72DE735-B24F-4ef6-897F-70A85D01A047</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:12</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TimerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiPerformanceLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>PeiPerformanceHob</C_Name>

+    </GuidEntry>

+  </Guids>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/PeiPerformanceLib.c b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/PeiPerformanceLib.c
new file mode 100644
index 0000000..89e2dd3
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/PeiPerformanceLib.c
@@ -0,0 +1,315 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PeiPerformanceLib.c

+

+Abstract:

+

+  Performance Library

+

+--*/

+

+/**

+  Gets PEI the GUID HOB for PEI performance.

+

+  This internal function searches for the GUID HOB for PEI performance.

+  If that GUID HOB is not found, it will build a new one.

+  It returns the data area of that GUID HOB to record performance log.    

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+

+  @retval The index of log entry in the array.

+

+**/

+PEI_PERFORMANCE_LOG_HEADER *

+InternalGetPerformanceHobLog (

+  VOID

+  )

+{

+  EFI_HOB_GUID_TYPE           *GuidHob;

+  PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;

+  UINTN                       PeiPerformanceLogSize;

+

+  GuidHob = GetFirstGuidHob (&gPeiPerformanceHobGuid);

+  

+  if (GuidHob != NULL) {

+    //

+    // PEI Performance HOB was found, then return the existing one.

+    //

+    PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob);

+  } else {

+    //

+    // PEI Performance HOB was not found, then build one.

+    //

+    PeiPerformanceLogSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) + 

+                            sizeof (PEI_PERFORMANCE_LOG_ENTRY) * MAX_PEI_PERFORMANCE_LOG_ENTRIES;

+    PeiPerformanceLog     = BuildGuidHob (&gPeiPerformanceHobGuid, PeiPerformanceLogSize);

+    PeiPerformanceLog     = ZeroMem (PeiPerformanceLog, PeiPerformanceLogSize);

+  }

+

+  return PeiPerformanceLog;

+}

+

+/**

+  Searches in the log array with keyword Handle, Token and Module.

+

+  This internal function searches for the log entry in the log array.

+  If there is an entry that exactly matches the given key word triple

+  and its end time stamp is zero, then the index of that log entry is returned;

+  otherwise, the the number of log entries in the array is returned.  

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+

+  @retval The index of log entry in the array.

+

+**/

+UINT32

+InternalSearchForLogEntry (

+  IN PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog,

+  IN CONST VOID                 *Handle,  OPTIONAL

+  IN CONST CHAR8                *Token,   OPTIONAL

+  IN CONST CHAR8                *Module   OPTIONAL

+  )

+{

+  UINT32                    Index;

+  UINT32                    NumberOfEntries;

+  PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray;

+  

+

+  if (Token == NULL) {

+    Token = "";

+  }

+  if (Module == NULL) {

+    Module = "";

+  }

+  NumberOfEntries = PeiPerformanceLog->NumberOfEntries;

+  LogEntryArray   = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1);

+  

+  for (Index = 0; Index < NumberOfEntries; Index++) {

+    if ((LogEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&

+         AsciiStrnCmp (LogEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH) == 0 &&

+         AsciiStrnCmp (LogEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH) == 0 &&

+         LogEntryArray[Index].EndTimeStamp == 0

+       ) {

+      break;

+    }

+  }

+  return Index;

+} 

+

+/**

+  Creates a record for the beginning of a performance measurement. 

+  

+  Creates a record that contains the Handle, Token, and Module.

+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.

+  If TimeStamp is zero, then this function reads the current time stamp

+  and adds that time stamp value to the record as the start time.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;

+  PEI_PERFORMANCE_LOG_ENTRY   *LogEntryArray;

+  UINT32                      Index;

+

+  PeiPerformanceLog = InternalGetPerformanceHobLog ();

+  

+  if (PeiPerformanceLog->NumberOfEntries >= MAX_PEI_PERFORMANCE_LOG_ENTRIES) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  Index                       = PeiPerformanceLog->NumberOfEntries++;

+  LogEntryArray               = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1);        

+  LogEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;

+

+  if (Token != NULL) {

+    AsciiStrnCpy (LogEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH);

+  }

+  if (Module != NULL) {

+    AsciiStrnCpy (LogEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH);

+  }

+

+  if (TimeStamp == 0) {

+    TimeStamp = GetPerformanceCounter ();

+  }

+  LogEntryArray[Index].StartTimeStamp = TimeStamp;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Fills in the end time of a performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then TimeStamp is added to the record as the end time.

+  If the record is found and TimeStamp is zero, then this function reads

+  the current time stamp and adds that time stamp value to the record as the end time.

+  If this function is called multiple times for the same record, then the end time is overwritten.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.

+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;

+  PEI_PERFORMANCE_LOG_ENTRY   *LogEntryArray;

+  UINT32                      Index;

+

+  if (TimeStamp == 0) {

+    TimeStamp = GetPerformanceCounter ();

+  }

+  

+  PeiPerformanceLog = InternalGetPerformanceHobLog ();

+  Index             = InternalSearchForLogEntry (PeiPerformanceLog, Handle, Token, Module);

+  if (Index >= PeiPerformanceLog->NumberOfEntries) {

+    return RETURN_NOT_FOUND;

+  }

+  LogEntryArray     = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1);

+  LogEntryArray[Index].EndTimeStamp = TimeStamp;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found then the start of the measurement is returned in StartTimeStamp,

+  and the end of the measurement is returned in EndTimeStamp.

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  StartTimeStamp          The 64-bit time stamp that was recorded when the measurement was started.

+  @param  EndTimeStamp            The 64-bit time stamp that was recorded when the measurement was ended.

+

+  @return The key for the current performance log entry.

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurement (

+  UINTN           LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp

+  )

+{

+  PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;

+  PEI_PERFORMANCE_LOG_ENTRY   *CurrentLogEntry;

+  PEI_PERFORMANCE_LOG_ENTRY   *LogEntryArray;

+  UINTN                       NumberOfEntries;

+

+  ASSERT (Handle != NULL);

+  ASSERT (Token != NULL);

+  ASSERT (Module != NULL);

+  ASSERT (StartTimeStamp != NULL);

+  ASSERT (EndTimeStamp != NULL);

+  

+  PeiPerformanceLog = InternalGetPerformanceHobLog ();

+ 

+  NumberOfEntries   = (UINTN) (PeiPerformanceLog->NumberOfEntries);

+  LogEntryArray     = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1);

+  //

+  // Make sure that LogEntryKey is a valid log entry key.

+  //

+  ASSERT (LogEntryKey <= NumberOfEntries);

+  

+  if (LogEntryKey == NumberOfEntries) {

+    return 0;

+  }

+

+  CurrentLogEntry = &(LogEntryArray[LogEntryKey++]);

+

+  *Handle         = (VOID *) (UINTN) (CurrentLogEntry->Handle);

+  *Token          = CurrentLogEntry->Token;

+  *Module         = CurrentLogEntry->Module;

+  *StartTimeStamp = CurrentLogEntry->StartTimeStamp;

+  *EndTimeStamp   = CurrentLogEntry->EndTimeStamp;

+

+  return LogEntryKey;  

+}

+

+/**

+  Returns TRUE if the performance measurement macros are enabled. 

+  

+  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is set.

+  @retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PerformanceMeasurementEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/build.xml b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/build.xml
new file mode 100644
index 0000000..e269b31
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkPeiPerformanceLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkPeiPerformanceLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkPeiPerformanceLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkPeiPerformanceLib">

+      <GenBuild baseName="EdkPeiPerformanceLib" mbdFilename="${MODULE_DIR}/EdkPeiPerformanceLib.mbd" msaFilename="${MODULE_DIR}/EdkPeiPerformanceLib.msa"/>

+   </target>

+   <target depends="EdkPeiPerformanceLib_clean" name="clean"/>

+   <target depends="EdkPeiPerformanceLib_cleanall" name="cleanall"/>

+   <target name="EdkPeiPerformanceLib_clean">

+      <OutputDirSetup baseName="EdkPeiPerformanceLib" mbdFilename="${MODULE_DIR}/EdkPeiPerformanceLib.mbd" msaFilename="${MODULE_DIR}/EdkPeiPerformanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkPeiPerformanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeiPerformanceLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkPeiPerformanceLib_cleanall">

+      <OutputDirSetup baseName="EdkPeiPerformanceLib" mbdFilename="${MODULE_DIR}/EdkPeiPerformanceLib.mbd" msaFilename="${MODULE_DIR}/EdkPeiPerformanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkPeiPerformanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkPeiPerformanceLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkPeiPerformanceLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.c b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.c
new file mode 100644
index 0000000..d72aae1
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.c
@@ -0,0 +1,397 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BsDataHubStatusCode.c

+

+Abstract:

+

+  This implements a status code listener that logs status codes into the data

+  hub.  This is only active during non-runtime DXE.

+

+--*/

+#include "BsDataHubStatusCode.h"

+

+//

+// Globals only work at BootService Time. NOT at Runtime!

+//

+static EFI_DATA_HUB_PROTOCOL  *mDataHub;

+static LIST_ENTRY             mRecordBuffer;

+static INTN                   mRecordNum;

+static EFI_EVENT              mLogDataHubEvent;

+static EFI_LOCK               mStatusCodeReportLock;

+static BOOLEAN                mEventHandlerActive   = FALSE;

+

+STATUS_CODE_RECORD_LIST *

+GetRecordBuffer (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Returned buffer of length BYTES_PER_RECORD

+

+Arguments:

+

+  None

+

+Returns:

+

+  Entry in mRecordBuffer or NULL if non available

+

+--*/

+{

+  STATUS_CODE_RECORD_LIST *Buffer;

+

+  gBS->AllocatePool (EfiBootServicesData, sizeof (STATUS_CODE_RECORD_LIST), (VOID **) &Buffer);

+  if (Buffer == NULL) {

+    return NULL;

+  }

+

+  ZeroMem (Buffer, sizeof (STATUS_CODE_RECORD_LIST));

+  Buffer->Signature = BS_DATA_HUB_STATUS_CODE_SIGNATURE;

+

+  return Buffer;

+}

+

+DATA_HUB_STATUS_CODE_DATA_RECORD *

+AquireEmptyRecordBuffer (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Allocate a mRecordBuffer entry in the form of a pointer.

+

+Arguments:

+

+  None

+

+Returns:

+

+  Pointer to new buffer. NULL if none exist.

+

+--*/

+{

+  STATUS_CODE_RECORD_LIST *DataBuffer;

+

+  if (mRecordNum < MAX_RECORD_NUM) {

+    DataBuffer = GetRecordBuffer ();

+    if (DataBuffer != NULL) {

+      EfiAcquireLock (&mStatusCodeReportLock);

+      InsertTailList (&mRecordBuffer, &DataBuffer->Link);

+      mRecordNum++;

+      EfiReleaseLock (&mStatusCodeReportLock);

+      return (DATA_HUB_STATUS_CODE_DATA_RECORD *) DataBuffer->RecordBuffer;

+    }

+  }

+

+  return NULL;

+}

+

+EFI_STATUS

+ReleaseRecordBuffer (

+  IN  STATUS_CODE_RECORD_LIST  *RecordBuffer

+  )

+/*++

+

+Routine Description:

+

+  Release a mRecordBuffer entry allocated by AquireEmptyRecordBuffer ().

+

+Arguments:

+

+  RecordBuffer          - Data to free

+

+Returns:

+

+  EFI_SUCCESS           - If DataRecord is valid

+  EFI_UNSUPPORTED       - The record list has empty

+

+--*/

+{

+  ASSERT (RecordBuffer != NULL);

+  if (mRecordNum <= 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  EfiAcquireLock (&mStatusCodeReportLock);

+  RemoveEntryList (&RecordBuffer->Link);

+  mRecordNum--;

+  EfiReleaseLock (&mStatusCodeReportLock);

+  gBS->FreePool (RecordBuffer);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BsDataHubReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Boot service report status code listener.  This function logs the status code

+  into the data hub.

+

+Arguments:

+

+  Same as ReportStatusCode (See Tiano Runtime Specification)

+

+Returns:

+

+  None

+

+--*/

+{

+  DATA_HUB_STATUS_CODE_DATA_RECORD  *DataHub;

+  UINT32                            ErrorLevel;

+  VA_LIST                           Marker;

+  CHAR8                             *Format;

+  UINTN                             Index;

+  CHAR16                            FormatBuffer[BYTES_PER_RECORD];

+

+  if (EfiAtRuntime ()) {

+    //

+    // For now all we do is post code at runtime

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // If we had an error while in our event handler, then do nothing so

+  // that we don't get in an endless loop.

+  //

+  if (mEventHandlerActive) {

+    return EFI_SUCCESS;

+  }

+

+  DataHub = (DATA_HUB_STATUS_CODE_DATA_RECORD *) AquireEmptyRecordBuffer ();

+  if (DataHub == NULL) {

+    //

+    // There are no empty record buffer in private buffers

+    //

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Construct Data Hub Extended Data

+  //

+  DataHub->CodeType = CodeType;

+  DataHub->Value    = Value;

+  DataHub->Instance = Instance;

+

+  if (CallerId != NULL) {

+    CopyMem (&DataHub->CallerId, CallerId, sizeof (EFI_GUID));

+  } else {

+    ZeroMem (&DataHub->CallerId, sizeof (EFI_GUID));

+  }

+

+  if (Data == NULL) {

+    ZeroMem (&DataHub->Data, sizeof (EFI_STATUS_CODE_DATA));

+  } else {

+    //

+    // Copy generic Header

+    //

+    CopyMem (&DataHub->Data, Data, sizeof (EFI_STATUS_CODE_DATA));

+

+    if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {

+      //

+      // Convert Ascii Format string to Unicode.

+      //

+      for (Index = 0; Format[Index] != '\0' && Index < (BYTES_PER_RECORD - 1); Index += 1) {

+        FormatBuffer[Index] = (CHAR16) Format[Index];

+      }

+

+      FormatBuffer[Index] = L'\0';

+

+      //

+      // Put processed string into the buffer

+      //

+      Index = UnicodeVSPrint (

+                (CHAR16 *) (DataHub + 1),

+                BYTES_PER_RECORD - (sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD)),

+                FormatBuffer,

+                Marker

+                );

+

+      //

+      // DATA_HUB_STATUS_CODE_DATA_RECORD followed by VSPrint String Buffer

+      //

+      DataHub->Data.Size = (UINT16) (Index * sizeof (CHAR16));

+

+    } else {

+      //

+      // Default behavior is to copy optional data

+      //

+      if (Data->Size > (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD))) {

+        DataHub->Data.Size = (UINT16) (BYTES_PER_RECORD - sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD));

+      }

+

+      CopyMem (DataHub + 1, Data + 1, DataHub->Data.Size);

+    }

+  }

+

+  gBS->SignalEvent (mLogDataHubEvent);

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+LogDataHubEventHandler (

+  IN  EFI_EVENT     Event,

+  IN  VOID          *Context

+  )

+/*++

+

+Routine Description:

+

+  The Event handler which will be notified to log data in Data Hub.

+

+Arguments:

+

+  Event     -   Instance of the EFI_EVENT to signal whenever data is

+                available to be logged in the system.

+  Context   -   Context of the event.

+

+Returns:

+

+  None.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  DATA_HUB_STATUS_CODE_DATA_RECORD  *DataRecord;

+  UINTN                             Size;

+  UINT64                            DataRecordClass;

+  LIST_ENTRY                        *Link;

+  STATUS_CODE_RECORD_LIST           *BufferEntry;

+

+  //

+  // Set our global flag so we don't recurse if we get an error here.

+  //

+  mEventHandlerActive = TRUE;

+

+  //

+  // Log DataRecord in Data Hub.

+  // If there are multiple DataRecords, Log all of them.

+  //

+  for (Link = mRecordBuffer.ForwardLink; Link != &mRecordBuffer;) {

+    BufferEntry = CR (Link, STATUS_CODE_RECORD_LIST, Link, BS_DATA_HUB_STATUS_CODE_SIGNATURE);

+    DataRecord  = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (BufferEntry->RecordBuffer);

+    Link        = Link->ForwardLink;

+

+    //

+    // Add in the size of the header we added.

+    //

+    Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + DataRecord->Data.Size;

+

+    if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {

+      DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE;

+    } else if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {

+      DataRecordClass = EFI_DATA_RECORD_CLASS_ERROR;

+    } else if ((DataRecord->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {

+      DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG;

+    } else {

+      //

+      // Should never get here.

+      //

+      DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG |

+        EFI_DATA_RECORD_CLASS_ERROR |

+        EFI_DATA_RECORD_CLASS_DATA |

+        EFI_DATA_RECORD_CLASS_PROGRESS_CODE;

+    }

+

+    if (((DataRecord->Instance & EFI_D_ERROR) != 0) &&

+        (((DataRecord->Instance & EFI_D_POOL) != 0) || ((DataRecord->Instance & EFI_D_PAGE) != 0))

+        ) {

+      //

+      // If memory error, do not call LogData ().

+      //

+      DebugPrint ((UINTN)-1, "Memory Error\n");

+      Status = EFI_OUT_OF_RESOURCES;

+    } else {

+      //

+      // Log DataRecord in Data Hub

+      //

+      Status = mDataHub->LogData (

+                          mDataHub,

+                          &gEfiStatusCodeGuid,

+                          &gEfiStatusCodeRuntimeProtocolGuid,

+                          DataRecordClass,

+                          DataRecord,

+                          (UINT32) Size

+                          );

+    }

+

+    ReleaseRecordBuffer (BufferEntry);

+  }

+

+  mEventHandlerActive = FALSE;

+

+  return ;

+}

+

+VOID

+BsDataHubStatusCodeInitialize (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Install a data hub listener.

+

+Arguments:

+

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+  EFI_SUCCESS - Logging Hub protocol installed

+  Other       - No protocol installed, unload driver.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub);

+  //

+  // Should never fail due to dependency grammer

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Initialize FIFO

+  //

+  InitializeListHead (&mRecordBuffer);

+  mRecordNum = 0;

+

+  EfiInitializeLock (&mStatusCodeReportLock, EFI_TPL_HIGH_LEVEL);

+

+  //

+  // Create a Notify Event to log data in Data Hub

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  LogDataHubEventHandler,

+                  NULL,

+                  &mLogDataHubEvent

+                  );

+

+}

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.h b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.h
new file mode 100644
index 0000000..f15a90e
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.h
@@ -0,0 +1,130 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BsDataHubStatusCode.h

+

+Abstract:

+

+  Header for the status code data hub logging component

+

+--*/

+

+#ifndef _EFI_BS_DATA_HUB_STATUS_CODE_H_

+#define _EFI_BS_DATA_HUB_STATUS_CODE_H_

+

+//

+// Private data declarations

+//

+#define MAX_RECORD_NUM                    1000

+#define BYTES_PER_RECORD                  EFI_STATUS_CODE_DATA_MAX_SIZE

+#define EMPTY_RECORD_TAG                  0xFF

+

+#define BS_DATA_HUB_STATUS_CODE_SIGNATURE EFI_SIGNATURE_32 ('B', 'D', 'H', 'S')

+

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      Link;

+  UINT8           RecordBuffer[BYTES_PER_RECORD];

+} STATUS_CODE_RECORD_LIST;

+

+//

+// Function prototypes

+//

+STATUS_CODE_RECORD_LIST           *

+GetRecordBuffer (

+  VOID

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Returned buffer of length BYTES_PER_RECORD

+

+Arguments:

+

+  None

+

+Returns:

+

+  Entry in mRecordBuffer or NULL if non available

+

+--*/

+DATA_HUB_STATUS_CODE_DATA_RECORD  *

+AquireEmptyRecordBuffer (

+  VOID

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Allocate a mRecordBuffer entry in the form of a pointer.

+

+Arguments:

+

+  None

+

+Returns:

+

+  Pointer to new buffer. NULL if none exist.

+

+--*/

+EFI_STATUS

+ReleaseRecordBuffer (

+  IN  STATUS_CODE_RECORD_LIST  *RecordBuffer

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Release a mRecordBuffer entry allocated by AquireEmptyRecordBuffer ().

+

+Arguments:

+

+  RecordBuffer          - Data to free

+

+Returns:

+

+  EFI_SUCCESS           - If RecordBuffer is valid

+  EFI_UNSUPPORTED       - The record list has empty

+

+--*/

+VOID

+EFIAPI

+LogDataHubEventHandler (

+  IN  EFI_EVENT   Event,

+  IN  VOID        *Context

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Event Handler that log in Status code in Data Hub.

+

+Arguments:

+

+  (Standard EFI Event Handler - EFI_EVENT_NOTIFY)

+

+Returns:

+

+  NONE

+

+--*/

+#endif

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.mbd b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.mbd
new file mode 100644
index 0000000..ce1bd63
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkBsDataHubStatusCodeLib</BaseName>

+    <Guid>041bf780-dc3e-49ab-8d67-4b86075440ea</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.msa b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.msa
new file mode 100644
index 0000000..ea369fb
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/BsDataHubStatusCode.msa
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkBsDataHubStatusCodeLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>041bf780-dc3e-49ab-8d67-4b86075440ea</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkBsDataHubStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BsDataHubStatusCode.c</Filename>

+    <Filename>BsDataHubStatusCode.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">StatusCode</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">DataHub</Protocol>

+  </Protocols>

+  <Events>

+    <CreateEvents>

+      <Event>

+        <C_Name>EFI_EVENT_NOTIFY_SIGNAL</C_Name>

+      </Event>

+    </CreateEvents>

+  </Events>

+  <DataHubs>

+    <DataHubRecord>gEfiStatusCodeGuid</DataHubRecord>

+  </DataHubs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCode</C_Name>

+    </GuidEntry>

+  </Guids>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/build.xml b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/build.xml
new file mode 100644
index 0000000..4c7f99b
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkBsDataHubStatusCodeLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkRuntimeStatusCodeLib/BsDataHubStatusCode"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkBsDataHubStatusCodeLib">

+      <GenBuild baseName="EdkBsDataHubStatusCodeLib" mbdFilename="${MODULE_DIR}/BsDataHubStatusCode.mbd" msaFilename="${MODULE_DIR}/BsDataHubStatusCode.msa"/>

+   </target>

+   <target depends="EdkBsDataHubStatusCodeLib_clean" name="clean"/>

+   <target depends="EdkBsDataHubStatusCodeLib_cleanall" name="cleanall"/>

+   <target name="EdkBsDataHubStatusCodeLib_clean">

+      <OutputDirSetup baseName="EdkBsDataHubStatusCodeLib" mbdFilename="${MODULE_DIR}/BsDataHubStatusCode.mbd" msaFilename="${MODULE_DIR}/BsDataHubStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkBsDataHubStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkBsDataHubStatusCodeLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkBsDataHubStatusCodeLib_cleanall">

+      <OutputDirSetup baseName="EdkBsDataHubStatusCodeLib" mbdFilename="${MODULE_DIR}/BsDataHubStatusCode.mbd" msaFilename="${MODULE_DIR}/BsDataHubStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkBsDataHubStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkBsDataHubStatusCodeLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkBsDataHubStatusCodeLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.c b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.c
new file mode 100644
index 0000000..375a338
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.c
@@ -0,0 +1,188 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  RtMemoryStatusCode.c

+   

+Abstract:

+

+  EFI lib to provide memory journal status code reporting routines.

+

+--*/

+

+#include <Ppi/StatusCodeMemory.h>

+

+//

+// Global variables

+//

+PEI_STATUS_CODE_MEMORY_PPI  mStatusCodeMemoryPpi = { 0, 0, 0, 0 };

+

+//

+// Function implementations

+//

+EFI_STATUS

+RtMemoryReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Log a status code to a memory journal.  If no memory journal exists, 

+  we will just return.

+

+Arguments:

+

+  Same as ReportStatusCode AP

+    

+Returns:

+

+  EFI_SUCCESS   This function always returns success

+

+--*/

+{

+  EFI_STATUS_CODE_ENTRY *CurrentEntry;

+  UINTN                 MaxEntry;

+

+  //

+  // We don't care to log debug codes.

+  //

+  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Update the latest entry in the journal.

+  //

+  MaxEntry = mStatusCodeMemoryPpi.Length / sizeof (EFI_STATUS_CODE_ENTRY);

+  if (!MaxEntry) {

+    //

+    // If we don't have any entries, then we can return.

+    // This effectively means that no memory buffer was passed forward from PEI.

+    //

+    return EFI_SUCCESS;

+  }

+

+  CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (mStatusCodeMemoryPpi.Address + (mStatusCodeMemoryPpi.LastEntry * sizeof (EFI_STATUS_CODE_ENTRY)));

+

+  mStatusCodeMemoryPpi.LastEntry = (mStatusCodeMemoryPpi.LastEntry + 1) % MaxEntry;

+  if (mStatusCodeMemoryPpi.LastEntry == mStatusCodeMemoryPpi.FirstEntry) {

+    mStatusCodeMemoryPpi.FirstEntry = (mStatusCodeMemoryPpi.FirstEntry + 1) % MaxEntry;

+  }

+

+  CurrentEntry->Type      = CodeType;

+  CurrentEntry->Value     = Value;

+  CurrentEntry->Instance  = Instance;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+RtMemoryStatusCodeInitialize (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialization routine.

+  Allocates heap space for storing Status Codes.

+  Installs a PPI to point to that heap space.

+  Installs a callback to switch to memory.

+  Installs a callback to 

+

+Arguments: 

+

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns: 

+

+  None

+

+--*/

+{

+  EFI_HOB_GUID_TYPE           *GuidHob;

+  PEI_STATUS_CODE_MEMORY_PPI  **StatusCodeMemoryPpi;

+

+  GuidHob = GetFirstGuidHob (&gPeiStatusCodeMemoryPpiGuid);

+  if (GuidHob == NULL) {

+    return;

+  }

+

+  StatusCodeMemoryPpi = GET_GUID_HOB_DATA (GuidHob);

+

+  //

+  // Copy data to our structure since the HOB will go away at runtime

+  //

+  // BUGBUG: Virtualize for RT

+  //

+  mStatusCodeMemoryPpi.FirstEntry = (*StatusCodeMemoryPpi)->FirstEntry;

+  mStatusCodeMemoryPpi.LastEntry  = (*StatusCodeMemoryPpi)->LastEntry;

+  mStatusCodeMemoryPpi.Address    = (*StatusCodeMemoryPpi)->Address;

+  mStatusCodeMemoryPpi.Length     = (*StatusCodeMemoryPpi)->Length;

+}

+

+VOID

+PlaybackStatusCodes (

+  IN EFI_REPORT_STATUS_CODE   ReportStatusCodeFunc

+  )

+/*++

+

+Routine Description:

+

+  Call the input ReportStatusCode function with every status code recorded in

+  the journal.

+

+Arguments: 

+

+  ReportStatusCode    ReportStatusCode function to call.

+

+Returns: 

+

+  None

+

+--*/

+{

+  UINTN                 MaxEntry;

+  EFI_STATUS_CODE_ENTRY *CurrentEntry;

+  UINTN                 Counter;

+

+  if (ReportStatusCodeFunc == RtMemoryReportStatusCode) {

+    return ;

+  }

+  //

+  // Playback prior status codes to current listeners

+  //

+  MaxEntry = mStatusCodeMemoryPpi.Length / sizeof (EFI_STATUS_CODE_ENTRY);

+  for (Counter = mStatusCodeMemoryPpi.FirstEntry; Counter != mStatusCodeMemoryPpi.LastEntry; Counter++) {

+    //

+    // Check if we have to roll back to beginning of queue buffer

+    //

+    if (Counter == MaxEntry) {

+      Counter = 0;

+    }

+    //

+    // Play current entry

+    //

+    CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (mStatusCodeMemoryPpi.Address + (Counter * sizeof (EFI_STATUS_CODE_ENTRY)));

+    ReportStatusCodeFunc (

+      CurrentEntry->Type,

+      CurrentEntry->Value,

+      CurrentEntry->Instance,

+      NULL,

+      NULL

+      );

+  }

+}

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.mbd b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.mbd
new file mode 100644
index 0000000..1795204
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkRtMemoryStatusCodeLib</BaseName>

+    <Guid>1517564b-ab66-42b7-8903-731a95f314f9</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.msa b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.msa
new file mode 100644
index 0000000..8f68fcf
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.msa
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkRtMemoryStatusCodeLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>1517564b-ab66-42b7-8903-731a95f314f9</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkRtMemoryStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>RtMemoryStatusCode.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/build.xml b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/build.xml
new file mode 100644
index 0000000..5152c14
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkRtMemoryStatusCodeLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkRtMemoryStatusCodeLib">

+      <GenBuild baseName="EdkRtMemoryStatusCodeLib" mbdFilename="${MODULE_DIR}/RtMemoryStatusCode.mbd" msaFilename="${MODULE_DIR}/RtMemoryStatusCode.msa"/>

+   </target>

+   <target depends="EdkRtMemoryStatusCodeLib_clean" name="clean"/>

+   <target depends="EdkRtMemoryStatusCodeLib_cleanall" name="cleanall"/>

+   <target name="EdkRtMemoryStatusCodeLib_clean">

+      <OutputDirSetup baseName="EdkRtMemoryStatusCodeLib" mbdFilename="${MODULE_DIR}/RtMemoryStatusCode.mbd" msaFilename="${MODULE_DIR}/RtMemoryStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkRtMemoryStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkRtMemoryStatusCodeLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkRtMemoryStatusCodeLib_cleanall">

+      <OutputDirSetup baseName="EdkRtMemoryStatusCodeLib" mbdFilename="${MODULE_DIR}/RtMemoryStatusCode.mbd" msaFilename="${MODULE_DIR}/RtMemoryStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkRtMemoryStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkRtMemoryStatusCodeLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkRtMemoryStatusCodeLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.c b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.c
new file mode 100644
index 0000000..47f7f96
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.c
@@ -0,0 +1,130 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  RtPlatformStatusCode.c 

+   

+Abstract:

+

+  Contains NT32 specific implementations required to use status codes.

+

+--*/

+

+//

+// Globals only work at BootService Time. NOT at Runtime!

+//

+// 

+

+typedef

+EFI_STATUS

+(EFIAPI *REPORT_STATUS_CODE_FUNCTION) (

+  IN EFI_STATUS_CODE_TYPE     Type,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId OPTIONAL,

+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL

+  );

+

+REPORT_STATUS_CODE_FUNCTION  mPeiReportStatusCode;

+

+//

+// Function implementations

+//

+EFI_STATUS

+RtPlatformReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Call all status code listeners in the MonoStatusCode.

+

+Arguments:

+

+  Same as ReportStatusCode service

+  

+Returns:

+

+  EFI_SUCCESS     Always returns success.

+

+--*/

+{

+  RtMemoryReportStatusCode (CodeType, Value, Instance, CallerId, Data);

+  if (EfiAtRuntime ()) {

+    //

+    // For now all we do is post code at runtime

+    //

+    return EFI_SUCCESS;

+  }

+

+  BsDataHubReportStatusCode (CodeType, Value, Instance, CallerId, Data);

+

+  //

+  // Call back into PEI to get status codes.  This is because SecMain contains

+  // status code that reports to Win32.

+  //

+  if (mPeiReportStatusCode != NULL) {

+    return mPeiReportStatusCode (CodeType, Value, Instance, CallerId, Data);

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+RtPlatformStatusCodeInitialize (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialize the status code listeners.

+

+Arguments:

+

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_HOB_GUID_TYPE   *GuidHob;

+  void                *Pointer;

+

+  RtMemoryStatusCodeInitialize ();

+  BsDataHubStatusCodeInitialize ();

+

+  //

+  // Play any prior status codes to the data hub.

+  //

+  PlaybackStatusCodes (BsDataHubReportStatusCode);

+

+  //

+  // If PEI has a ReportStatusCode callback find it and use it before StdErr

+  // is connected.

+  //

+  mPeiReportStatusCode  = NULL;

+

+  GuidHob = GetFirstGuidHob (&gEfiStatusCodeRuntimeProtocolGuid);

+  if (NULL == GuidHob) {

+    return;

+  }

+  Pointer = GET_GUID_HOB_DATA (GuidHob);

+  mPeiReportStatusCode = (REPORT_STATUS_CODE_FUNCTION) (*(UINTN *) Pointer);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.mbd b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.mbd
new file mode 100644
index 0000000..6459131
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkRtPlatformStatusCodeLib</BaseName>

+    <Guid>68b157b5-9534-43ff-9cd3-6705e4e1d56c</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.msa b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.msa
new file mode 100644
index 0000000..df04b83
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/RtPlatformStatusCode.msa
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkRtPlatformStatusCodeLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>68b157b5-9534-43ff-9cd3-6705e4e1d56c</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkRtPlatformStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkBsDataHubStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkRtMemoryStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>RtPlatformStatusCode.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/build.xml b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/build.xml
new file mode 100644
index 0000000..2cffff0
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkRtPlatformStatusCodeLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkRuntimeStatusCodeLib/RtPlatformStatusCode"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkRtPlatformStatusCodeLib">

+      <GenBuild baseName="EdkRtPlatformStatusCodeLib" mbdFilename="${MODULE_DIR}/RtPlatformStatusCode.mbd" msaFilename="${MODULE_DIR}/RtPlatformStatusCode.msa"/>

+   </target>

+   <target depends="EdkRtPlatformStatusCodeLib_clean" name="clean"/>

+   <target depends="EdkRtPlatformStatusCodeLib_cleanall" name="cleanall"/>

+   <target name="EdkRtPlatformStatusCodeLib_clean">

+      <OutputDirSetup baseName="EdkRtPlatformStatusCodeLib" mbdFilename="${MODULE_DIR}/RtPlatformStatusCode.mbd" msaFilename="${MODULE_DIR}/RtPlatformStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkRtPlatformStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkRtPlatformStatusCodeLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkRtPlatformStatusCodeLib_cleanall">

+      <OutputDirSetup baseName="EdkRtPlatformStatusCodeLib" mbdFilename="${MODULE_DIR}/RtPlatformStatusCode.mbd" msaFilename="${MODULE_DIR}/RtPlatformStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkRtPlatformStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkRtPlatformStatusCodeLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkRtPlatformStatusCodeLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkScsiLib/EdkScsiLib.mbd b/edk2/EdkModulePkg/Library/EdkScsiLib/EdkScsiLib.mbd
new file mode 100644
index 0000000..18d03c2
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkScsiLib/EdkScsiLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkScsiLib</BaseName>

+    <Guid>46c9adef-aee6-410c-99e4-240e3af18d8b</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkScsiLib/EdkScsiLib.msa b/edk2/EdkModulePkg/Library/EdkScsiLib/EdkScsiLib.msa
new file mode 100644
index 0000000..5109895
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkScsiLib/EdkScsiLib.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkScsiLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>46c9adef-aee6-410c-99e4-240e3af18d8b</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Scsi Dxe Library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkScsiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ScsiLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkScsiLib/ScsiLib.c b/edk2/EdkModulePkg/Library/EdkScsiLib/ScsiLib.c
new file mode 100644
index 0000000..9a6eb67
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkScsiLib/ScsiLib.c
@@ -0,0 +1,651 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ScsiLib.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+

+#include <IndustryStandard/scsi.h>

+

+EFI_STATUS

+SubmitTestUnitReadyCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  OUT VOID                  *SenseData,

+  OUT UINT8                 *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus

+  )

+/*++

+

+Routine Description:

+  Function tests the ready status of SCSI unit.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in InTransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[6];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 6);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = NULL;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= 0;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Test Unit Ready Command

+  //

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]                        = EFI_SCSI_OP_TEST_UNIT_READY;

+  Cdb[1]                        = (UINT8) (Lun & 0xe0);

+  CommandPacket.CdbLength       = (UINT8) 6;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+

+  return Status;

+}

+

+EFI_STATUS

+SubmitInquiryCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  IN OUT VOID               *InquiryDataBuffer,

+  IN OUT UINT32             *InquiryDataLength,

+  IN  BOOLEAN               EnableVitalProductData

+  )

+/*++

+

+Routine Description:

+  Function to submit SCSI inquiry command.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+  InquiryDataBuffer    - A pointer to inquiry data buffer.

+  InquiryDataLength    - The length of inquiry data buffer.

+  EnableVitalProductData - Boolean to enable Vital Product Data.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[6];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 6);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = InquiryDataBuffer;

+  CommandPacket.InTransferLength= *InquiryDataLength;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+  CommandPacket.Cdb             = Cdb;

+

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]  = EFI_SCSI_OP_INQUIRY;

+  Cdb[1]  = (UINT8) (Lun & 0xe0);

+  if (EnableVitalProductData) {

+    Cdb[1] |= 0x01;

+  }

+

+  if (*InquiryDataLength > 0xff) {

+    *InquiryDataLength = 0xff;

+  }

+

+  Cdb[4]                      = (UINT8) (*InquiryDataLength);

+  CommandPacket.CdbLength     = (UINT8) 6;

+  CommandPacket.DataDirection = EFI_SCSI_DATA_IN;

+

+  Status                      = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus          = CommandPacket.HostAdapterStatus;

+  *TargetStatus               = CommandPacket.TargetStatus;

+  *SenseDataLength            = CommandPacket.SenseDataLength;

+  *InquiryDataLength          = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+EFI_STATUS

+SubmitModeSense10Command (

+  IN  EFI_SCSI_IO_PROTOCOL    *ScsiIo,

+  IN  UINT64                  Timeout,

+  IN  VOID                    *SenseData,

+  IN OUT UINT8                *SenseDataLength,

+  OUT UINT8                   *HostAdapterStatus,

+  OUT UINT8                   *TargetStatus,

+  IN  VOID                    *DataBuffer,

+  IN OUT UINT32               *DataLength,

+  IN  UINT8                   DBDField, OPTIONAL

+  IN  UINT8                   PageControl,

+  IN  UINT8                   PageCode

+  )

+/*++

+

+Routine Description:

+  Function to submit SCSI mode sense 10 command.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+  DataBuffer           - A pointer to input data buffer.

+  DataLength           - The length of input data buffer.

+  DBDField             - The DBD Field (Optional).

+  PageControl          - Page Control.

+  PageCode             - Page code.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[10];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 10);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Mode Sense (10) Command

+  //

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]                        = EFI_SCSI_OP_MODE_SEN10;

+  Cdb[1]                        = (UINT8) ((Lun & 0xe0) + ((DBDField << 3) & 0x08));

+  Cdb[2]                        = (UINT8) ((PageControl & 0xc0) | (PageCode & 0x3f));

+  Cdb[7]                        = (UINT8) (*DataLength >> 8);

+  Cdb[8]                        = (UINT8) (*DataLength);

+

+  CommandPacket.CdbLength       = 10;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+EFI_STATUS

+SubmitRequestSenseCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus

+  )

+/*++

+

+Routine Description:

+  Function to submit SCSI request sense command.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[6];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 6);

+/*

+  if (*SenseDataLength > 0xff) {

+    *SenseDataLength = 0xff;

+  }

+*/

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = SenseData;

+  CommandPacket.SenseData       = NULL;

+  CommandPacket.InTransferLength= *SenseDataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Request Sense Command

+  //

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]                        = EFI_SCSI_OP_REQUEST_SENSE;

+  Cdb[1]                        = (UINT8) (Lun & 0xe0);

+  Cdb[4]                        = (UINT8) (*SenseDataLength);

+

+  CommandPacket.CdbLength       = (UINT8) 6;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = 0;

+

+  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = (UINT8) CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+EFI_STATUS

+SubmitReadCapacityCommand (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  OUT VOID                  *DataBuffer,

+  IN OUT UINT32             *DataLength,

+  IN  BOOLEAN               PMI

+  )

+/*++

+

+Routine Description:

+  Function to submit read capacity command.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+  DataBuffer           - A pointer to a data buffer.

+  DataLength           - The length of data buffer.

+  PMI                  - Partial medium indicator.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[10];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 10);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Read Capacity Command

+  //

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]  = EFI_SCSI_OP_READ_CAPACITY;

+  Cdb[1]  = (UINT8) (Lun & 0xe0);

+  if (!PMI) {

+    //

+    // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.

+    //

+    ZeroMem ((Cdb + 2), 4);

+  } else {

+    Cdb[8] |= 0x01;

+  }

+

+  CommandPacket.CdbLength       = 10;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+EFI_STATUS

+SubmitRead10Command (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  OUT VOID                  *DataBuffer,

+  IN OUT UINT32             *DataLength,

+  IN  UINT32                StartLba,

+  IN  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+  Function to submit read 10 command.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+  DataBuffer           - A pointer to a data buffer.

+  DataLength           - The length of data buffer.

+  StartLba             - The start address of LBA.

+  SectorSize           - The sector size.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in TransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[10];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 10);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Read (10) Command

+  //

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]                        = EFI_SCSI_OP_READ10;

+  Cdb[1]                        = (UINT8) (Lun & 0xe0);

+  Cdb[2]                        = (UINT8) (StartLba >> 24);

+  Cdb[3]                        = (UINT8) (StartLba >> 16);

+  Cdb[4]                        = (UINT8) (StartLba >> 8);

+  Cdb[5]                        = (UINT8) StartLba;

+  Cdb[7]                        = (UINT8) (SectorSize >> 8);

+  Cdb[8]                        = (UINT8) SectorSize;

+

+  CommandPacket.CdbLength       = 10;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+EFI_STATUS

+SubmitWrite10Command (

+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN  UINT64                Timeout,

+  IN  VOID                  *SenseData,

+  IN OUT UINT8              *SenseDataLength,

+  OUT UINT8                 *HostAdapterStatus,

+  OUT UINT8                 *TargetStatus,

+  OUT VOID                  *DataBuffer,

+  IN OUT UINT32             *DataLength,

+  IN  UINT32                StartLba,

+  IN  UINT32                SectorSize

+  )

+/*++

+

+Routine Description:

+  Function to submit SCSI write 10 command.

+

+Arguments:

+  ScsiIo               - A pointer to SCSI IO protocol.

+  Timeout              - The length of timeout period.

+  SenseData            - A pointer to output sense data.

+  SenseDataLength      - The length of output sense data.

+  HostAdapterStatus    - The status of Host Adapter.

+  TargetStatus         - The status of the target.

+  DataBuffer           - A pointer to a data buffer.

+  DataLength           - The length of data buffer.

+  StartLba             - The start address of LBA.

+  SectorSize           - The sector size.

+

+Returns:

+

+  Returns:

+    EFI_SUCCESS            - The status of the unit is tested successfully.

+    EFI_WARN_BUFFER_TOO_SMALL  - The SCSI Request Packet was executed, 

+                            but the entire DataBuffer could not be transferred.

+                            The actual number of bytes transferred is returned

+                            in InTransferLength.

+    EFI_NOT_READY          - The SCSI Request Packet could not be sent because 

+                            there are too many SCSI Command Packets already 

+                            queued.

+    EFI_DEVICE_ERROR      - A device error occurred while attempting to send 

+                            the SCSI Request Packet.

+    EFI_INVALID_PARAMETER  - The contents of CommandPacket are invalid.  

+    EFI_UNSUPPORTED        - The command described by the SCSI Request Packet

+                            is not supported by the SCSI initiator(i.e., SCSI 

+                            Host Controller).

+    EFI_TIMEOUT            - A timeout occurred while waiting for the SCSI 

+                            Request Packet to execute.

+

+--*/

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  UINT64                          Lun;

+  UINT8                           *Target;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[10];

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 10);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Write (10) Command

+  //

+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);

+

+  Cdb[0]                        = EFI_SCSI_OP_WRITE10;

+  Cdb[1]                        = (UINT8) (Lun & 0xe0);

+  Cdb[2]                        = (UINT8) (StartLba >> 24);

+  Cdb[3]                        = (UINT8) (StartLba >> 16);

+  Cdb[4]                        = (UINT8) (StartLba >> 8);

+  Cdb[5]                        = (UINT8) StartLba;

+  Cdb[7]                        = (UINT8) (SectorSize >> 8);

+  Cdb[8]                        = (UINT8) SectorSize;

+

+  CommandPacket.CdbLength       = 10;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_OUT;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkScsiLib/build.xml b/edk2/EdkModulePkg/Library/EdkScsiLib/build.xml
new file mode 100644
index 0000000..56e9701
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkScsiLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkScsiLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkScsiLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkScsiLib">

+      <GenBuild baseName="EdkScsiLib" mbdFilename="${MODULE_DIR}/EdkScsiLib.mbd" msaFilename="${MODULE_DIR}/EdkScsiLib.msa"/>

+   </target>

+   <target depends="EdkScsiLib_clean" name="clean"/>

+   <target depends="EdkScsiLib_cleanall" name="cleanall"/>

+   <target name="EdkScsiLib_clean">

+      <OutputDirSetup baseName="EdkScsiLib" mbdFilename="${MODULE_DIR}/EdkScsiLib.mbd" msaFilename="${MODULE_DIR}/EdkScsiLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkScsiLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkScsiLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkScsiLib_cleanall">

+      <OutputDirSetup baseName="EdkScsiLib" mbdFilename="${MODULE_DIR}/EdkScsiLib.mbd" msaFilename="${MODULE_DIR}/EdkScsiLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkScsiLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkScsiLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkScsiLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/DebugLib.c b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/DebugLib.c
new file mode 100644
index 0000000..911002e
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/DebugLib.c
@@ -0,0 +1,255 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugLib.c

+

+Abstract:

+

+  UEFI Debug Library that uses PrintLib to send messages to CONOUT

+

+--*/

+

+static BOOLEAN                   mDebugLevelInstalled = FALSE;

+static EFI_DEBUG_LEVEL_PROTOCOL  mDebugLevel = { 0 };

+

+EFI_STATUS

+DebugLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS               Status;

+

+  //

+  // Initialize Debug Level Protocol

+  //

+  mDebugLevel.DebugLevel = PcdGet32(PcdDebugPrintErrorLevel);

+

+  //

+  // Install Debug Level Protocol 

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ImageHandle,

+                  &gEfiDebugLevelProtocolGuid, &mDebugLevel,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Set flag to show that the Debug Level Protocol has been installed

+  //

+  mDebugLevelInstalled = TRUE;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN  ErrorLevel,

+  IN  CHAR8  *Format,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Wrapper for DebugVPrint ()

+  

+Arguments:

+

+  ErrorLevel - If error level is set do the debug print.

+

+  Format     - String to use for the print, followed by Print arguments.

+

+  ...        - Print arguments.

+

+Returns:

+  

+  None

+

+--*/

+{

+  CHAR16   Buffer[0x100];

+  CHAR16   UnicodeBuffer[0x100];

+  UINT32   Index;

+  VA_LIST  Marker;

+

+  //

+  // Check to see if CONOUT is avilable

+  //

+  if (gST->ConOut == NULL) {

+    return;

+  }

+

+  //

+  // Check driver Debug Level value and global debug level

+  //

+  if (mDebugLevelInstalled) {

+    if ((ErrorLevel & mDebugLevel.DebugLevel) == 0) {

+      return;

+    }

+  } else {

+    if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+      return;

+    }

+  }

+

+  //

+  // BUGBUG: Need print that take CHAR8 Format and returns CHAR16 Buffer

+  //

+  for (Index = 0; Format[Index] != 0; Index++) {

+    UnicodeBuffer[Index] = Format[Index];

+  }

+  UnicodeBuffer[Index] = Format[Index];

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrint (Buffer, sizeof (Buffer), UnicodeBuffer, Marker);

+  VA_END (Marker);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  gST->ConOut->OutputString (gST->ConOut, Buffer);

+}

+

+VOID

+EFIAPI

+DebugAssert (

+  IN CHAR8  *FileName,

+  IN INTN   LineNumber,

+  IN CHAR8  *Description

+  )

+/*++

+

+Routine Description:

+

+  Worker function for ASSERT(). If Error Logging hub is loaded log ASSERT

+  information. If Error Logging hub is not loaded CpuBreakpoint ().

+

+  We use UINT64 buffers due to IPF alignment concerns.

+

+Arguments:

+

+  FileName    - File name of failing routine.

+

+  LineNumber  - Line number of failing ASSERT().

+

+  Description - Descritption, usally the assertion,

+  

+Returns:

+  

+  None

+

+--*/

+{

+  CHAR16  Buffer[0x100];

+

+  //

+  // Check to see if CONOUT is avilable

+  //

+  if (gST->ConOut == NULL) {

+    return;

+  }

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  UnicodeSPrint (Buffer, sizeof (Buffer), (CHAR16 *)L"ASSERT %s(%d): %s\n", FileName, LineNumber, Description);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  gST->ConOut->OutputString (gST->ConOut, Buffer);

+

+  //

+  // Put break point in module that contained the error.

+  //

+  CpuBreakpoint ();

+}

+

+/**

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param  Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param  Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+//  SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+  SetMem (Buffer, Length, 0xAF);

+  return Buffer;

+}

+

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.mbd b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.mbd
new file mode 100644
index 0000000..08bc04d
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkUefiDebugLibConOut</BaseName>

+    <Guid>7293fe0b-1fff-4f8f-b808-10cb55f6a174</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:14</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.msa b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.msa
new file mode 100644
index 0000000..dd724d0
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/EdkUefiDebugLibConOut.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkUefiDebugLibConOut</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>7293fe0b-1fff-4f8f-b808-10cb55f6a174</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Debug Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:14</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">DebugLevel</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DebugLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/build.xml b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/build.xml
new file mode 100644
index 0000000..864a64f
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibConOut/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkUefiDebugLibConOut"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkUefiDebugLibConOut"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkUefiDebugLibConOut">

+      <GenBuild baseName="EdkUefiDebugLibConOut" mbdFilename="${MODULE_DIR}/EdkUefiDebugLibConOut.mbd" msaFilename="${MODULE_DIR}/EdkUefiDebugLibConOut.msa"/>

+   </target>

+   <target depends="EdkUefiDebugLibConOut_clean" name="clean"/>

+   <target depends="EdkUefiDebugLibConOut_cleanall" name="cleanall"/>

+   <target name="EdkUefiDebugLibConOut_clean">

+      <OutputDirSetup baseName="EdkUefiDebugLibConOut" mbdFilename="${MODULE_DIR}/EdkUefiDebugLibConOut.mbd" msaFilename="${MODULE_DIR}/EdkUefiDebugLibConOut.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkUefiDebugLibConOut_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkUefiDebugLibConOut_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkUefiDebugLibConOut_cleanall">

+      <OutputDirSetup baseName="EdkUefiDebugLibConOut" mbdFilename="${MODULE_DIR}/EdkUefiDebugLibConOut.mbd" msaFilename="${MODULE_DIR}/EdkUefiDebugLibConOut.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkUefiDebugLibConOut_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkUefiDebugLibConOut_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkUefiDebugLibConOut*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/DebugLib.c b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/DebugLib.c
new file mode 100644
index 0000000..1074d6a
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/DebugLib.c
@@ -0,0 +1,255 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugLib.c

+

+Abstract:

+

+  UEFI Debug Library that uses PrintLib to send messages to STDERR

+

+--*/

+

+static BOOLEAN                   mDebugLevelInstalled = FALSE;

+static EFI_DEBUG_LEVEL_PROTOCOL  mDebugLevel = { 0 };

+

+EFI_STATUS

+DebugLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS               Status;

+

+  //

+  // Initialize Debug Level Protocol

+  //

+  mDebugLevel.DebugLevel = PcdGet32(PcdDebugPrintErrorLevel);

+

+  //

+  // Install Debug Level Protocol 

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ImageHandle,

+                  &gEfiDebugLevelProtocolGuid, &mDebugLevel,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Set flag to show that the Debug Level Protocol has been installed

+  //

+  mDebugLevelInstalled = TRUE;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN  ErrorLevel,

+  IN  CHAR8  *Format,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Wrapper for DebugVPrint ()

+  

+Arguments:

+

+  ErrorLevel - If error level is set do the debug print.

+

+  Format     - String to use for the print, followed by Print arguments.

+

+  ...        - Print arguments.

+

+Returns:

+  

+  None

+

+--*/

+{

+  CHAR16   Buffer[0x100];

+  CHAR16   UnicodeBuffer[0x100];

+  UINT32   Index;

+  VA_LIST  Marker;

+

+  //

+  // Check to see if STDERR is avilable

+  //

+  if (gST->StdErr == NULL) {

+    return;

+  }

+

+  //

+  // Check driver Debug Level value and global debug level

+  //

+  if (mDebugLevelInstalled) {

+    if ((ErrorLevel & mDebugLevel.DebugLevel) == 0) {

+      return;

+    }

+  } else {

+    if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+      return;

+    }

+  }

+

+  //

+  // BUGBUG: Need print that take CHAR8 Format and returns CHAR16 Buffer

+  //

+  for (Index = 0; Format[Index] != 0; Index++) {

+    UnicodeBuffer[Index] = Format[Index];

+  }

+  UnicodeBuffer[Index] = Format[Index];

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrint (Buffer, sizeof (Buffer), UnicodeBuffer, Marker);

+  VA_END (Marker);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  gST->StdErr->OutputString (gST->StdErr, Buffer);

+}

+

+VOID

+EFIAPI

+DebugAssert (

+  IN CHAR8  *FileName,

+  IN INTN   LineNumber,

+  IN CHAR8  *Description

+  )

+/*++

+

+Routine Description:

+

+  Worker function for ASSERT(). If Error Logging hub is loaded log ASSERT

+  information. If Error Logging hub is not loaded CpuBreakpoint ().

+

+  We use UINT64 buffers due to IPF alignment concerns.

+

+Arguments:

+

+  FileName    - File name of failing routine.

+

+  LineNumber  - Line number of failing ASSERT().

+

+  Description - Descritption, usally the assertion,

+  

+Returns:

+  

+  None

+

+--*/

+{

+  CHAR16  Buffer[0x100];

+

+  //

+  // Check to see if STDERR is avilable

+  //

+  if (gST->StdErr == NULL) {

+    return;

+  }

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  UnicodeSPrint (Buffer, sizeof (Buffer), (CHAR16 *)L"ASSERT %s(%d): %s\n", FileName, LineNumber, Description);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  gST->StdErr->OutputString (gST->StdErr, Buffer);

+

+  //

+  // Put break point in module that contained the error.

+  //

+  CpuBreakpoint ();

+}

+

+/**

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param  Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param  Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+//  SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+  SetMem (Buffer, Length, 0xAF);

+  return Buffer;

+}

+

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.mbd b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.mbd
new file mode 100644
index 0000000..833b2ee
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkUefiDebugLibStdErr</BaseName>

+    <Guid>8b9968e0-c76b-4b57-aec4-24e17fe602c0</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-31 13:14</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.msa b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.msa
new file mode 100644
index 0000000..fcfa3fb
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/EdkUefiDebugLibStdErr.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkUefiDebugLibStdErr</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>8b9968e0-c76b-4b57-aec4-24e17fe602c0</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Debug Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-31 13:14</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">DebugLevel</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DebugLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/build.xml b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/build.xml
new file mode 100644
index 0000000..20eb351
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUefiDebugLibStdErr/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkUefiDebugLibStdErr"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkUefiDebugLibStdErr"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkUefiDebugLibStdErr">

+      <GenBuild baseName="EdkUefiDebugLibStdErr" mbdFilename="${MODULE_DIR}/EdkUefiDebugLibStdErr.mbd" msaFilename="${MODULE_DIR}/EdkUefiDebugLibStdErr.msa"/>

+   </target>

+   <target depends="EdkUefiDebugLibStdErr_clean" name="clean"/>

+   <target depends="EdkUefiDebugLibStdErr_cleanall" name="cleanall"/>

+   <target name="EdkUefiDebugLibStdErr_clean">

+      <OutputDirSetup baseName="EdkUefiDebugLibStdErr" mbdFilename="${MODULE_DIR}/EdkUefiDebugLibStdErr.mbd" msaFilename="${MODULE_DIR}/EdkUefiDebugLibStdErr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkUefiDebugLibStdErr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkUefiDebugLibStdErr_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkUefiDebugLibStdErr_cleanall">

+      <OutputDirSetup baseName="EdkUefiDebugLibStdErr" mbdFilename="${MODULE_DIR}/EdkUefiDebugLibStdErr.mbd" msaFilename="${MODULE_DIR}/EdkUefiDebugLibStdErr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkUefiDebugLibStdErr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkUefiDebugLibStdErr_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkUefiDebugLibStdErr*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkUsbLib/EdkUsbLib.mbd b/edk2/EdkModulePkg/Library/EdkUsbLib/EdkUsbLib.mbd
new file mode 100644
index 0000000..79fa4b1
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUsbLib/EdkUsbLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkUsbLib</BaseName>

+    <Guid>87eb5df9-722a-4241-ad7f-370d0b3a56d7</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Library/EdkUsbLib/EdkUsbLib.msa b/edk2/EdkModulePkg/Library/EdkUsbLib/EdkUsbLib.msa
new file mode 100644
index 0000000..d58942c
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUsbLib/EdkUsbLib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkUsbLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>87eb5df9-722a-4241-ad7f-370d0b3a56d7</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UsbDxeLib module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkUsbLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UsbDxeLib.c</Filename>

+    <Filename>hid.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Library/EdkUsbLib/UsbDxeLib.c b/edk2/EdkModulePkg/Library/EdkUsbLib/UsbDxeLib.c
new file mode 100644
index 0000000..8bbd089
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUsbLib/UsbDxeLib.c
@@ -0,0 +1,699 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+ Module Name:

+

+    UsbDxeLib.c

+

+ Abstract:

+

+   Common Dxe Libarary  for USB

+

+ Revision History

+

+--*/

+

+//

+// Get Device Descriptor

+//

+EFI_STATUS

+UsbGetDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  IN  UINT16                  Index,

+  IN  UINT16                  DescriptorLength,

+  OUT VOID                    *Descriptor,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Get Descriptor

+

+Arguments:

+

+  UsbIo             - EFI_USB_IO_PROTOCOL

+  Value             - Device Request Value

+  Index             - Device Request Index 

+  DescriptorLength  - Descriptor Length

+  Descriptor        - Descriptor buffer to contain result

+  Status            - Transfer Status

+Returns:

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;

+  DevReq.Request      = USB_DEV_GET_DESCRIPTOR;

+  DevReq.Value        = Value;

+  DevReq.Index        = Index;

+  DevReq.Length       = DescriptorLength;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  TIMEOUT_VALUE,

+                  Descriptor,

+                  DescriptorLength,

+                  Status

+                  );

+}

+//

+// Set Device Descriptor

+//

+EFI_STATUS

+UsbSetDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  IN  UINT16                  Index,

+  IN  UINT16                  DescriptorLength,

+  IN  VOID                    *Descriptor,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Set Descriptor

+

+Arguments:

+

+  UsbIo             - EFI_USB_IO_PROTOCOL

+  Value             - Device Request Value

+  Index             - Device Request Index 

+  DescriptorLength  - Descriptor Length

+  Descriptor        - Descriptor buffer to set

+  Status            - Transfer Status

+Returns:

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;

+  DevReq.Request      = USB_DEV_SET_DESCRIPTOR;

+  DevReq.Value        = Value;

+  DevReq.Index        = Index;

+  DevReq.Length       = DescriptorLength;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataOut,

+                  TIMEOUT_VALUE,

+                  Descriptor,

+                  DescriptorLength,

+                  Status

+                  );

+}

+

+//

+// Get device Interface

+//

+EFI_STATUS

+UsbGetDeviceInterface (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Index,

+  OUT UINT8                   *AltSetting,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Get Device Interface

+

+Arguments:

+

+  UsbIo       - EFI_USB_IO_PROTOCOL

+  Index       - Interface index value

+  AltSetting  - Alternate setting

+  Status      - Trasnsfer status

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_GET_INTERFACE_REQ_TYPE;

+  DevReq.Request      = USB_DEV_GET_INTERFACE;

+  DevReq.Index        = Index;

+  DevReq.Length       = 1;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  TIMEOUT_VALUE,

+                  AltSetting,

+                  1,

+                  Status

+                  );

+}

+//

+// Set device interface

+//

+EFI_STATUS

+UsbSetDeviceInterface (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  InterfaceNo,

+  IN  UINT16                  AltSetting,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Set Device Interface

+

+Arguments:

+

+  UsbIo       - EFI_USB_IO_PROTOCOL

+  InterfaceNo - Interface Number

+  AltSetting  - Alternate setting

+  Status      - Trasnsfer status

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_INTERFACE_REQ_TYPE;

+  DevReq.Request      = USB_DEV_SET_INTERFACE;

+  DevReq.Value        = AltSetting;

+  DevReq.Index        = InterfaceNo;

+ 

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  TIMEOUT_VALUE,

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+//

+// Get device configuration

+//

+EFI_STATUS

+UsbGetDeviceConfiguration (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  OUT UINT8                   *ConfigValue,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Get Device Configuration

+

+Arguments:

+

+  UsbIo       - EFI_USB_IO_PROTOCOL

+  ConfigValue - Config Value

+  Status      - Transfer Status

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_GET_CONFIGURATION_REQ_TYPE;

+  DevReq.Request      = USB_DEV_GET_CONFIGURATION;

+  DevReq.Length       = 1;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  TIMEOUT_VALUE,

+                  ConfigValue,

+                  1,

+                  Status

+                  );

+}

+//

+// Set device configuration

+//

+EFI_STATUS

+UsbSetDeviceConfiguration (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Set Device Configuration

+

+Arguments:

+

+  UsbIo   - EFI_USB_IO_PROTOCOL

+  Value   - Configuration Value to set

+  Status  - Transfer status

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_CONFIGURATION_REQ_TYPE;

+  DevReq.Request      = USB_DEV_SET_CONFIGURATION;

+  DevReq.Value        = Value;

+ 

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  TIMEOUT_VALUE,

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+//

+//  Set Device Feature

+//

+EFI_STATUS

+UsbSetDeviceFeature (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  EFI_USB_RECIPIENT       Recipient,

+  IN  UINT16                  Value,

+  IN  UINT16                  Target,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Set Device Feature

+

+Arguments:

+

+  UsbIo     - EFI_USB_IO_PROTOCOL

+  Recipient - Interface/Device/Endpoint

+  Value     - Request value

+  Target    - Request Index

+  Status    - Transfer status

+

+Returns:

+  

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  switch (Recipient) {

+

+  case EfiUsbDevice:

+    DevReq.RequestType = 0x00;

+    break;

+

+  case EfiUsbInterface:

+    DevReq.RequestType = 0x01;

+    break;

+

+  case EfiUsbEndpoint:

+    DevReq.RequestType = 0x02;

+    break;

+  }

+  //

+  // Fill device request, see USB1.1 spec

+  //

+  DevReq.Request  = USB_DEV_SET_FEATURE;

+  DevReq.Value    = Value;

+  DevReq.Index    = Target;

+

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  TIMEOUT_VALUE,

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+//

+// Clear Device Feature

+//

+EFI_STATUS

+UsbClearDeviceFeature (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  EFI_USB_RECIPIENT       Recipient,

+  IN  UINT16                  Value,

+  IN  UINT16                  Target,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Clear Device Feature

+

+Arguments:

+

+  UsbIo     - EFI_USB_IO_PROTOCOL

+  Recipient - Interface/Device/Endpoint

+  Value     - Request value

+  Target    - Request Index

+  Status    - Transfer status

+

+Returns:

+  

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  switch (Recipient) {

+

+  case EfiUsbDevice:

+    DevReq.RequestType = 0x00;

+    break;

+

+  case EfiUsbInterface:

+    DevReq.RequestType = 0x01;

+    break;

+

+  case EfiUsbEndpoint:

+    DevReq.RequestType = 0x02;

+    break;

+  }

+  //

+  // Fill device request, see USB1.1 spec

+  //

+  DevReq.Request  = USB_DEV_CLEAR_FEATURE;

+  DevReq.Value    = Value;

+  DevReq.Index    = Target;

+

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  TIMEOUT_VALUE,

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+//

+//  Get Device Status

+//

+EFI_STATUS

+UsbGetDeviceStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  EFI_USB_RECIPIENT       Recipient,

+  IN  UINT16                  Target,

+  OUT UINT16                  *DevStatus,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Get Device Status

+

+Arguments:

+

+  UsbIo     - EFI_USB_IO_PROTOCOL

+  Recipient - Interface/Device/Endpoint

+  Target    - Request index

+  DevStatus - Device status

+  Status    - Transfer status

+

+Returns:

+  

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  switch (Recipient) {

+

+  case EfiUsbDevice:

+    DevReq.RequestType = 0x80;

+    break;

+

+  case EfiUsbInterface:

+    DevReq.RequestType = 0x81;

+    break;

+

+  case EfiUsbEndpoint:

+    DevReq.RequestType = 0x82;

+    break;

+  }

+  //

+  // Fill device request, see USB1.1 spec

+  //

+  DevReq.Request  = USB_DEV_GET_STATUS;

+  DevReq.Value    = 0;

+  DevReq.Index    = Target;

+  DevReq.Length   = 2;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  TIMEOUT_VALUE,

+                  DevStatus,

+                  2,

+                  Status

+                  );

+}

+//

+// Usb Get String

+//

+EFI_STATUS

+UsbGetString (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  LangID,

+  IN  UINT8                   Index,

+  IN  VOID                    *Buf,

+  IN  UINTN                   BufSize,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Usb Get String

+

+Arguments:

+

+  UsbIo     - EFI_USB_IO_PROTOCOL

+  LangID    - Language ID

+  Index     - Request index

+  Buf       - Buffer to store string

+  BufSize   - Buffer size

+  Status    - Transfer status

+

+Returns:

+  

+  EFI_INVALID_PARAMETER - Parameter is error

+  EFI_SUCCESS           - Success

+  EFI_TIMEOUT           - Device has no response 

+

+--*/

+{

+  UINT16  Value;

+

+  if (UsbIo == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Fill value, see USB1.1 spec

+  //

+  Value = (UINT16) ((USB_DT_STRING << 8) | Index);

+

+  return UsbGetDescriptor (

+          UsbIo,

+          Value,

+          LangID,

+          (UINT16) BufSize,

+          Buf,

+          Status

+          );

+}

+

+EFI_STATUS

+UsbClearEndpointHalt (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   EndpointNo,

+  OUT UINT32                  *Status

+  )

+/*++

+

+Routine Description:

+

+  Clear endpoint stall

+

+Arguments:

+

+  UsbIo       - EFI_USB_IO_PROTOCOL

+  EndpointNo  - Endpoint Number

+  Status      - Transfer Status

+

+Returns:

+

+  EFI_NOT_FOUND    - Can't find the Endpoint

+  EFI_DEVICE_ERROR - Hardware error

+  EFI_SUCCESS      - Success

+

+--*/

+{

+  EFI_STATUS                    Result;

+  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  UINT8                         Index;

+

+  ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));

+  //

+  // First seach the endpoint descriptor for that endpoint addr

+  //

+  Result = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Result)) {

+    return Result;

+  }

+

+  for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {

+    Result = UsbIo->UsbGetEndpointDescriptor (

+                      UsbIo,

+                      Index,

+                      &EndpointDescriptor

+                      );

+    if (EFI_ERROR (Result)) {

+      continue;

+    }

+

+    if (EndpointDescriptor.EndpointAddress == EndpointNo) {

+      break;

+    }

+  }

+

+  if (Index == InterfaceDescriptor.NumEndpoints) {

+    //

+    // No such endpoint

+    //

+    return EFI_NOT_FOUND;

+  }

+

+  Result = UsbClearDeviceFeature (

+            UsbIo,

+            EfiUsbEndpoint,

+            EfiUsbEndpointHalt,

+            EndpointDescriptor.EndpointAddress,

+            Status

+            );

+

+  return Result;

+}

diff --git a/edk2/EdkModulePkg/Library/EdkUsbLib/build.xml b/edk2/EdkModulePkg/Library/EdkUsbLib/build.xml
new file mode 100644
index 0000000..501838a
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUsbLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkUsbLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/EdkUsbLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EdkUsbLib">

+      <GenBuild baseName="EdkUsbLib" mbdFilename="${MODULE_DIR}/EdkUsbLib.mbd" msaFilename="${MODULE_DIR}/EdkUsbLib.msa"/>

+   </target>

+   <target depends="EdkUsbLib_clean" name="clean"/>

+   <target depends="EdkUsbLib_cleanall" name="cleanall"/>

+   <target name="EdkUsbLib_clean">

+      <OutputDirSetup baseName="EdkUsbLib" mbdFilename="${MODULE_DIR}/EdkUsbLib.mbd" msaFilename="${MODULE_DIR}/EdkUsbLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkUsbLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkUsbLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkUsbLib_cleanall">

+      <OutputDirSetup baseName="EdkUsbLib" mbdFilename="${MODULE_DIR}/EdkUsbLib.mbd" msaFilename="${MODULE_DIR}/EdkUsbLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EdkUsbLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EdkUsbLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkUsbLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Library/EdkUsbLib/hid.c b/edk2/EdkModulePkg/Library/EdkUsbLib/hid.c
new file mode 100644
index 0000000..edf9a94
--- /dev/null
+++ b/edk2/EdkModulePkg/Library/EdkUsbLib/hid.c
@@ -0,0 +1,459 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:

+

+    hid.c

+

+  Abstract:

+

+    HID class request

+

+  Revision History

+

+--*/

+

+//

+// Function to get HID descriptor

+//

+EFI_STATUS

+UsbGetHidDescriptor (

+  IN  EFI_USB_IO_PROTOCOL        *UsbIo,

+  IN  UINT8                      InterfaceNum,

+  OUT EFI_USB_HID_DESCRIPTOR     *HidDescriptor

+  )

+/*++

+

+  Routine Description:

+    Get Hid Descriptor

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    InterfaceNum      -   Hid interface number

+    HidDescriptor     -   Caller allocated buffer to store Usb hid descriptor

+                          if successfully returned.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  Request.RequestType = 0x81;

+  Request.Request     = 0x06;

+  Request.Value       = (UINT16) (0x21 << 8);

+  Request.Index       = InterfaceNum;

+  Request.Length      = sizeof (EFI_USB_HID_DESCRIPTOR);

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    TIMEOUT_VALUE,

+                    HidDescriptor,

+                    sizeof (EFI_USB_HID_DESCRIPTOR),

+                    &Status

+                    );

+

+  return Result;

+

+}

+//

+// Function to get Report Class descriptor

+//

+EFI_STATUS

+UsbGetReportDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   InterfaceNum,

+  IN  UINT16                  DescriptorSize,

+  OUT UINT8                   *DescriptorBuffer

+  )

+/*++

+

+  Routine Description:

+    get Report Class descriptor

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL.

+    InterfaceNum      -   Report interface number.

+    DescriptorSize    -   Length of DescriptorBuffer.

+    DescriptorBuffer  -   Caller allocated buffer to store Usb report descriptor

+                          if successfully returned.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0x81;

+  Request.Request     = 0x06;

+  Request.Value       = (UINT16) (0x22 << 8);

+  Request.Index       = InterfaceNum;

+  Request.Length      = DescriptorSize;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    TIMEOUT_VALUE,

+                    DescriptorBuffer,

+                    DescriptorSize,

+                    &Status

+                    );

+

+  return Result;

+

+}

+//

+// Following are HID class request

+//

+EFI_STATUS

+UsbGetProtocolRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   *Protocol

+  )

+/*++

+

+  Routine Description:

+    Get Hid Protocol Request

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    Interface         -   Which interface the caller wants to get protocol

+    Protocol          -   Protocol value returned.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0xa1;

+  //

+  // 10100001b;

+  //

+  Request.Request = EFI_USB_GET_PROTOCOL_REQUEST;

+  Request.Value   = 0;

+  Request.Index   = Interface;

+  Request.Length  = 1;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    TIMEOUT_VALUE,

+                    Protocol,

+                    sizeof (UINT8),

+                    &Status

+                    );

+

+  return Result;

+}

+

+

+EFI_STATUS

+UsbSetProtocolRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   Protocol

+  )

+/*++

+

+  Routine Description:

+    Set Hid Protocol Request

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    Interface         -   Which interface the caller wants to set protocol

+    Protocol          -   Protocol value the caller wants to set.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0x21;

+  //

+  // 00100001b;

+  //

+  Request.Request = EFI_USB_SET_PROTOCOL_REQUEST;

+  Request.Value   = Protocol;

+  Request.Index   = Interface;

+  Request.Length  = 0;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbNoData,

+                    TIMEOUT_VALUE,

+                    NULL,

+                    0,

+                    &Status

+                    );

+  return Result;

+}

+

+

+EFI_STATUS

+UsbSetIdleRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   Duration

+  )

+/*++

+

+  Routine Description:

+    Set Idel request.

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    Interface         -   Which interface the caller wants to set.

+    ReportId          -   Which report the caller wants to set.

+    Duration          -   Idle rate the caller wants to set.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0x21;

+  //

+  // 00100001b;

+  //

+  Request.Request = EFI_USB_SET_IDLE_REQUEST;

+  Request.Value   = (UINT16) ((Duration << 8) | ReportId);

+  Request.Index   = Interface;

+  Request.Length  = 0;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbNoData,

+                    TIMEOUT_VALUE,

+                    NULL,

+                    0,

+                    &Status

+                    );

+  return Result;

+}

+

+EFI_STATUS

+UsbGetIdleRequest (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Interface,

+  IN  UINT8                   ReportId,

+  OUT UINT8                   *Duration

+  )

+/*++

+

+  Routine Description:

+    Get Idel request.

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    Interface         -   Which interface the caller wants to get.

+    ReportId          -   Which report the caller wants to get.

+    Duration          -   Idle rate the caller wants to get.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0xa1;

+  //

+  // 10100001b;

+  //

+  Request.Request = EFI_USB_GET_IDLE_REQUEST;

+  Request.Value   = ReportId;

+  Request.Index   = Interface;

+  Request.Length  = 1;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    TIMEOUT_VALUE,

+                    Duration,

+                    1,

+                    &Status

+                    );

+

+  return Result;

+}

+

+

+EFI_STATUS

+UsbSetReportRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   ReportType,

+  IN UINT16                  ReportLen,

+  IN UINT8                   *Report

+  )

+/*++

+

+  Routine Description:

+    Hid Set Report request.

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    Interface         -   Which interface the caller wants to set.

+    ReportId          -   Which report the caller wants to set.

+    ReportType        -   Type of report.

+    ReportLen         -   Length of report descriptor.

+    Report            -   Report Descriptor buffer.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0x21;

+  //

+  // 00100001b;

+  //

+  Request.Request = EFI_USB_SET_REPORT_REQUEST;

+  Request.Value   = (UINT16) ((ReportType << 8) | ReportId);

+  Request.Index   = Interface;

+  Request.Length  = ReportLen;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataOut,

+                    TIMEOUT_VALUE,

+                    Report,

+                    ReportLen,

+                    &Status

+                    );

+

+  return Result;

+}

+

+EFI_STATUS

+UsbGetReportRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   ReportType,

+  IN UINT16                  ReportLen,

+  IN UINT8                   *Report

+  )

+/*++

+

+  Routine Description:

+    Hid Set Report request.

+

+  Arguments:

+    UsbIo             -   EFI_USB_IO_PROTOCOL

+    Interface         -   Which interface the caller wants to set.

+    ReportId          -   Which report the caller wants to set.

+    ReportType        -   Type of report.

+    ReportLen         -   Length of report descriptor.

+    Report            -   Caller allocated buffer to store Report Descriptor.

+

+  Returns:

+    EFI_SUCCESS

+    EFI_DEVICE_ERROR

+    EFI_TIMEOUT

+

+--*/

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = 0xa1;

+  //

+  // 10100001b;

+  //

+  Request.Request = EFI_USB_GET_REPORT_REQUEST;

+  Request.Value   = (UINT16) ((ReportType << 8) | ReportId);

+  Request.Index   = Interface;

+  Request.Length  = ReportLen;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    TIMEOUT_VALUE,

+                    Report,

+                    ReportLen,

+                    &Status

+                    );

+

+  return Result;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ComponentName.c
new file mode 100644
index 0000000..dc2a22f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ComponentName.c
@@ -0,0 +1,531 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "ConSplitter.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+ConSplitterComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gConSplitterConInComponentName = {

+  ConSplitterComponentNameGetDriverName,

+  ConSplitterConInComponentNameGetControllerName,

+  "eng"

+};

+

+EFI_COMPONENT_NAME_PROTOCOL     gConSplitterSimplePointerComponentName = {

+  ConSplitterComponentNameGetDriverName,

+  ConSplitterSimplePointerComponentNameGetControllerName,

+  "eng"

+};

+

+EFI_COMPONENT_NAME_PROTOCOL     gConSplitterConOutComponentName = {

+  ConSplitterComponentNameGetDriverName,

+  ConSplitterConOutComponentNameGetControllerName,

+  "eng"

+};

+

+EFI_COMPONENT_NAME_PROTOCOL     gConSplitterStdErrComponentName = {

+  ConSplitterComponentNameGetDriverName,

+  ConSplitterStdErrComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mConSplitterDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"Console Splitter Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+static EFI_UNICODE_STRING_TABLE mConSplitterConInControllerNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"Primary Console Input Device"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+static EFI_UNICODE_STRING_TABLE mConSplitterSimplePointerControllerNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"Primary Simple Pointer Device"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+static EFI_UNICODE_STRING_TABLE mConSplitterConOutControllerNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"Primary Console Output Device"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+static EFI_UNICODE_STRING_TABLE mConSplitterStdErrControllerNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"Primary Standard Error Device"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+ConSplitterComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+           Language,

+           gConSplitterConInComponentName.SupportedLanguages,

+           mConSplitterDriverNameTable,

+           DriverName

+           );

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;

+  //

+  // here ChildHandle is not an Optional parameter.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextInProtocolGuid,

+                  (VOID **) &TextIn,

+                  NULL,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return LookupUnicodeString (

+           Language,

+           gConSplitterConInComponentName.SupportedLanguages,

+           mConSplitterConInControllerNameTable,

+           ControllerName

+           );

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;

+  //

+  // here ChildHandle is not an Optional parameter.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimplePointerProtocolGuid,

+                  (VOID **) &SimplePointer,

+                  NULL,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return LookupUnicodeString (

+          Language,

+          gConSplitterSimplePointerComponentName.SupportedLanguages,

+          mConSplitterSimplePointerControllerNameTable,

+          ControllerName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+  //

+  // here ChildHandle is not an Optional parameter.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &TextOut,

+                  NULL,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return LookupUnicodeString (

+          Language,

+          gConSplitterConOutComponentName.SupportedLanguages,

+          mConSplitterConOutControllerNameTable,

+          ControllerName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *ErrOut;

+  //

+  // here ChildHandle is not an Optional parameter.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &ErrOut,

+                  NULL,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return LookupUnicodeString (

+          Language,

+          gConSplitterStdErrComponentName.SupportedLanguages,

+          mConSplitterStdErrControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.c b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.c
new file mode 100644
index 0000000..a9d39e9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.c
@@ -0,0 +1,3193 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConSplitter.c

+

+Abstract:

+

+  Console Splitter Driver. Any Handle that attatched 

+  EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.

+  

+  So far it works like any other driver by opening a SimpleTextIn and/or 

+  SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big 

+  difference is this driver does not layer a protocol on the passed in

+  handle, or construct a child handle like a standard device or bus driver. 

+  This driver produces three virtual handles as children, one for console input 

+  splitter, one for console output splitter and one for error output splitter.

+  EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to 

+  identify the splitter type.

+  

+  Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL

+  and Console I/O protocol, will be produced in the driver entry point. 

+  The virtual handle are added on driver entry and never removed.

+  Such design ensures sytem function well during none console device situation.

+  

+--*/

+

+#include "ConSplitter.h"

+

+//

+// Global Variables

+//

+static TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {

+  TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,

+  (EFI_HANDLE) NULL,

+  {

+    ConSplitterTextInReset,

+    ConSplitterTextInReadKeyStroke,

+    (EFI_EVENT) NULL

+  },

+  0,

+  (EFI_SIMPLE_TEXT_IN_PROTOCOL **) NULL,

+  0,

+

+  {

+    ConSplitterSimplePointerReset,

+    ConSplitterSimplePointerGetState,

+    (EFI_EVENT) NULL,

+    (EFI_SIMPLE_POINTER_MODE *) NULL

+  },

+  {

+    0x10000,

+    0x10000,

+    0x10000,

+    TRUE,

+    TRUE

+  },

+  0,

+  (EFI_SIMPLE_POINTER_PROTOCOL **) NULL,

+  0,

+

+  FALSE,

+  {

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

+  },

+  0,

+  {

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

+  },

+  (EFI_EVENT) NULL,

+

+  FALSE,

+  FALSE

+};

+

+static TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {

+  TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,

+  (EFI_HANDLE) NULL,

+  {

+    ConSplitterTextOutReset,

+    ConSplitterTextOutOutputString,

+    ConSplitterTextOutTestString,

+    ConSplitterTextOutQueryMode,

+    ConSplitterTextOutSetMode,

+    ConSplitterTextOutSetAttribute,

+    ConSplitterTextOutClearScreen,

+    ConSplitterTextOutSetCursorPosition,

+    ConSplitterTextOutEnableCursor,

+    (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL

+  },

+  {

+    1,

+    0,

+    0,

+    0,

+    0,

+    FALSE,

+  },

+  {

+    ConSpliterUgaDrawGetMode,

+    ConSpliterUgaDrawSetMode,

+    ConSpliterUgaDrawBlt

+  },

+  0,

+  0,

+  0,

+  0,

+  (EFI_UGA_PIXEL *) NULL,

+

+  {

+    ConSpliterConsoleControlGetMode,

+    ConSpliterConsoleControlSetMode,

+    ConSpliterConsoleControlLockStdIn

+  },

+

+  0,

+  (TEXT_OUT_AND_UGA_DATA *) NULL,

+  0,

+  (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,

+  0,

+  (INT32 *) NULL,

+

+  EfiConsoleControlScreenText,

+  0,

+  0,

+  (CHAR16 *) NULL,

+  (INT32 *) NULL

+};

+

+static TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {

+  TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,

+  (EFI_HANDLE) NULL,

+  {

+    ConSplitterTextOutReset,

+    ConSplitterTextOutOutputString,

+    ConSplitterTextOutTestString,

+    ConSplitterTextOutQueryMode,

+    ConSplitterTextOutSetMode,

+    ConSplitterTextOutSetAttribute,

+    ConSplitterTextOutClearScreen,

+    ConSplitterTextOutSetCursorPosition,

+    ConSplitterTextOutEnableCursor,

+    (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL

+  },

+  {

+    1,

+    0,

+    0,

+    0,

+    0,

+    FALSE,

+  },

+  {

+    ConSpliterUgaDrawGetMode,

+    ConSpliterUgaDrawSetMode,

+    ConSpliterUgaDrawBlt

+  },

+  0,

+  0,

+  0,

+  0,

+  (EFI_UGA_PIXEL *) NULL,

+

+  {

+    ConSpliterConsoleControlGetMode,

+    ConSpliterConsoleControlSetMode,

+    ConSpliterConsoleControlLockStdIn

+  },

+

+  0,

+  (TEXT_OUT_AND_UGA_DATA *) NULL,

+  0,

+  (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,

+  0,

+  (INT32 *) NULL,

+

+  EfiConsoleControlScreenText,

+  0,

+  0,

+  (CHAR16 *) NULL,

+  (INT32 *) NULL

+};

+

+EFI_DRIVER_BINDING_PROTOCOL           gConSplitterConInDriverBinding = {

+  ConSplitterConInDriverBindingSupported,

+  ConSplitterConInDriverBindingStart,

+  ConSplitterConInDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_DRIVER_BINDING_PROTOCOL           gConSplitterSimplePointerDriverBinding = {

+  ConSplitterSimplePointerDriverBindingSupported,

+  ConSplitterSimplePointerDriverBindingStart,

+  ConSplitterSimplePointerDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_DRIVER_BINDING_PROTOCOL           gConSplitterConOutDriverBinding = {

+  ConSplitterConOutDriverBindingSupported,

+  ConSplitterConOutDriverBindingStart,

+  ConSplitterConOutDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_DRIVER_BINDING_PROTOCOL           gConSplitterStdErrDriverBinding = {

+  ConSplitterStdErrDriverBindingSupported,

+  ConSplitterStdErrDriverBindingStart,

+  ConSplitterStdErrDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+ConSplitterDriverEntry (

+  IN EFI_HANDLE                       ImageHandle,

+  IN EFI_SYSTEM_TABLE                 *SystemTable

+  )

+/*++

+

+Routine Description:

+  Intialize a virtual console device to act as an agrigator of physical console

+  devices. 

+

+Arguments:

+  ImageHandle - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+  SystemTable - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+Returns: 

+  EFI_SUCCESS

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // The driver creates virtual handles for ConIn, ConOut, and StdErr.

+  // The virtual handles will always exist even if no console exist in the

+  // system. This is need to support hotplug devices like USB.

+  //

+  //

+  // Create virtual device handle for StdErr Splitter

+  //

+  Status = ConSplitterTextOutConstructor (&mStdErr);

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &mStdErr.VirtualHandle,

+                    &gEfiSimpleTextOutProtocolGuid,

+                    &mStdErr.TextOut,

+                    &gEfiPrimaryStandardErrorDeviceGuid,

+                    NULL,

+                    NULL

+                    );

+  }

+  //

+  // Create virtual device handle for ConIn Splitter

+  //

+  Status = ConSplitterTextInConstructor (&mConIn);

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &mConIn.VirtualHandle,

+                    &gEfiSimpleTextInProtocolGuid,

+                    &mConIn.TextIn,

+                    &gEfiSimplePointerProtocolGuid,

+                    &mConIn.SimplePointer,

+                    &gEfiPrimaryConsoleInDeviceGuid,

+                    NULL,

+                    NULL

+                    );

+    if (!EFI_ERROR (Status)) {

+      //

+      // Update the EFI System Table with new virtual console

+      //

+      gST->ConsoleInHandle  = mConIn.VirtualHandle;

+      gST->ConIn            = &mConIn.TextIn;

+    }

+  }

+  //

+  // Create virtual device handle for ConOut Splitter

+  //

+  Status = ConSplitterTextOutConstructor (&mConOut);

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &mConOut.VirtualHandle,

+                    &gEfiSimpleTextOutProtocolGuid,

+                    &mConOut.TextOut,

+                    &gEfiUgaDrawProtocolGuid,

+                    &mConOut.UgaDraw,

+                    &gEfiConsoleControlProtocolGuid,

+                    &mConOut.ConsoleControl,

+                    &gEfiPrimaryConsoleOutDeviceGuid,

+                    NULL,

+                    NULL

+                    );

+    if (!EFI_ERROR (Status)) {

+      //

+      // Update the EFI System Table with new virtual console

+      //

+      gST->ConsoleOutHandle = mConOut.VirtualHandle;

+      gST->ConOut           = &mConOut.TextOut;

+    }

+

+  }

+  //

+  // Update the CRC32 in the EFI System Table header

+  //

+  gST->Hdr.CRC32 = 0;

+  gBS->CalculateCrc32 (

+        (UINT8 *) &gST->Hdr,

+        gST->Hdr.HeaderSize,

+        &gST->Hdr.CRC32

+        );

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+ConSplitterTextInConstructor (

+  TEXT_IN_SPLITTER_PRIVATE_DATA       *ConInPrivate

+  )

+/*++

+

+Routine Description:

+

+  Construct the ConSplitter.

+

+Arguments:

+

+  ConInPrivate    - A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA structure.

+

+Returns: 

+  EFI_OUT_OF_RESOURCES - Out of resources.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Initilize console input splitter's private data.

+  //

+  Status = ConSplitterGrowBuffer (

+            sizeof (EFI_SIMPLE_TEXT_IN_PROTOCOL *),

+            &ConInPrivate->TextInListCount,

+            (VOID **) &ConInPrivate->TextInList

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Create Event to support locking StdIn Device

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  ConSpliterConsoleControlLockStdInEvent,

+                  NULL,

+                  &ConInPrivate->LockEvent

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  ConSplitterTextInWaitForKey,

+                  ConInPrivate,

+                  &ConInPrivate->TextIn.WaitForKey

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;

+

+  Status = ConSplitterGrowBuffer (

+            sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),

+            &ConInPrivate->PointerListCount,

+            (VOID **) &ConInPrivate->PointerList

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  ConSplitterSimplePointerWaitForInput,

+                  ConInPrivate,

+                  &ConInPrivate->SimplePointer.WaitForInput

+                  );

+

+  return Status;

+}

+

+

+EFI_STATUS

+ConSplitterTextOutConstructor (

+  TEXT_OUT_SPLITTER_PRIVATE_DATA      *ConOutPrivate

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Initilize console output splitter's private data.

+  //

+  ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;

+

+  Status = ConSplitterGrowBuffer (

+            sizeof (TEXT_OUT_AND_UGA_DATA),

+            &ConOutPrivate->TextOutListCount,

+            (VOID **) &ConOutPrivate->TextOutList

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = ConSplitterGrowBuffer (

+            sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),

+            &ConOutPrivate->TextOutQueryDataCount,

+            (VOID **) &ConOutPrivate->TextOutQueryData

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Setup the DevNullTextOut console to 80 x 25

+  //

+  ConOutPrivate->TextOutQueryData[0].Columns  = 80;

+  ConOutPrivate->TextOutQueryData[0].Rows     = 25;

+  DevNullTextOutSetMode (ConOutPrivate, 0);

+

+  //

+  // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel

+  //

+  ConSpliterUgaDrawSetMode (&ConOutPrivate->UgaDraw, 800, 600, 32, 60);

+

+  return Status;

+}

+

+

+EFI_STATUS

+ConSplitterSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_GUID                        *Guid

+  )

+/*++

+

+Routine Description:

+  Generic Supported Check

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller Handle.

+  Guid              - Guid.

+

+Returns:

+

+  EFI_UNSUPPORTED - unsupported.

+  EFI_SUCCESS     - operation is OK.

+

+--*/

+{

+  EFI_STATUS  Status;

+  VOID        *Instance;

+

+  //

+  // Make sure the Console Splitter does not attempt to attach to itself

+  //

+  if (ControllerHandle == mConIn.VirtualHandle) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (ControllerHandle == mConOut.VirtualHandle) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (ControllerHandle == mStdErr.VirtualHandle) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Check to see whether the handle has the ConsoleInDevice GUID on it

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  Guid,

+                  &Instance,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        ControllerHandle,

+        Guid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Console In Supported Check

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+{

+  return ConSplitterSupported (

+          This,

+          ControllerHandle,

+          &gEfiConsoleInDeviceGuid

+          );

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Standard Error Supported Check

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+{

+  return ConSplitterSupported (

+          This,

+          ControllerHandle,

+          &gEfiSimplePointerProtocolGuid

+          );

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Console Out Supported Check

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+{

+  return ConSplitterSupported (

+          This,

+          ControllerHandle,

+          &gEfiConsoleOutDeviceGuid

+          );

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Standard Error Supported Check

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+{

+  return ConSplitterSupported (

+          This,

+          ControllerHandle,

+          &gEfiStandardErrorDeviceGuid

+          );

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_HANDLE                      ConSplitterVirtualHandle,

+  IN  EFI_GUID                        *DeviceGuid,

+  IN  EFI_GUID                        *InterfaceGuid,

+  IN  VOID                            **Interface

+  )

+/*++

+

+Routine Description:

+  Start ConSplitter on ControllerHandle, and create the virtual 

+  agrogated console device on first call Start for a SimpleTextIn handle.

+

+Arguments:

+  (Standard DriverBinding Protocol Start() function)

+

+Returns:

+  EFI_ERROR if a SimpleTextIn protocol is not started.

+

+--*/

+{

+  EFI_STATUS  Status;

+  VOID        *Instance;

+

+  //

+  // Check to see whether the handle has the ConsoleInDevice GUID on it

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  DeviceGuid,

+                  &Instance,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  DeviceGuid,

+                  &Instance,

+                  This->DriverBindingHandle,

+                  ConSplitterVirtualHandle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return gBS->OpenProtocol (

+                ControllerHandle,

+                InterfaceGuid,

+                Interface,

+                This->DriverBindingHandle,

+                ConSplitterVirtualHandle,

+                EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                );

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Start ConSplitter on ControllerHandle, and create the virtual 

+  agrogated console device on first call Start for a SimpleTextIn handle.

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+

+  EFI_STATUS

+  EFI_ERROR if a SimpleTextIn protocol is not started.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;

+

+  //

+  // Start ConSplitter on ControllerHandle, and create the virtual

+  // agrogated console device on first call Start for a SimpleTextIn handle.

+  //

+  Status = ConSplitterStart (

+            This,

+            ControllerHandle,

+            mConIn.VirtualHandle,

+            &gEfiConsoleInDeviceGuid,

+            &gEfiSimpleTextInProtocolGuid,

+            (VOID **) &TextIn

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return ConSplitterTextInAddDevice (&mConIn, TextIn);

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Start ConSplitter on ControllerHandle, and create the virtual 

+  agrogated console device on first call Start for a SimpleTextIn handle.

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+

+  EFI_ERROR if a SimpleTextIn protocol is not started.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;

+

+  Status = ConSplitterStart (

+            This,

+            ControllerHandle,

+            mConIn.VirtualHandle,

+            &gEfiSimplePointerProtocolGuid,

+            &gEfiSimplePointerProtocolGuid,

+            (VOID **) &SimplePointer

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer);

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Start ConSplitter on ControllerHandle, and create the virtual 

+  agrogated console device on first call Start for a SimpleTextIn handle.

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+  EFI_ERROR if a SimpleTextIn protocol is not started.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

+

+  Status = ConSplitterStart (

+            This,

+            ControllerHandle,

+            mConOut.VirtualHandle,

+            &gEfiConsoleOutDeviceGuid,

+            &gEfiSimpleTextOutProtocolGuid,

+            (VOID **) &TextOut

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Open UGA_DRAW protocol

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw,

+                  This->DriverBindingHandle,

+                  mConOut.VirtualHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    UgaDraw = NULL;

+  }

+  //

+  // If both ConOut and StdErr incorporate the same Text Out device,

+  // their MaxMode and QueryData should be the intersection of both.

+  //

+  Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, UgaDraw);

+  ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+  //

+  // Match the UGA mode data of ConOut with the current mode

+  //

+  if (UgaDraw) {

+    UgaDraw->GetMode (

+               UgaDraw,

+               &mConOut.UgaHorizontalResolution,

+               &mConOut.UgaVerticalResolution,

+               &mConOut.UgaColorDepth,

+               &mConOut.UgaRefreshRate

+               );

+  }  

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Start ConSplitter on ControllerHandle, and create the virtual 

+  agrogated console device on first call Start for a SimpleTextIn handle.

+

+Arguments:

+  This              - Pointer to protocol.

+  ControllerHandle  - Controller handle.

+  RemainingDevicePath  - Remaining device path.

+

+Returns:

+  EFI_ERROR if a SimpleTextIn protocol is not started.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+

+  Status = ConSplitterStart (

+            This,

+            ControllerHandle,

+            mStdErr.VirtualHandle,

+            &gEfiStandardErrorDeviceGuid,

+            &gEfiSimpleTextOutProtocolGuid,

+            (VOID **) &TextOut

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // If both ConOut and StdErr incorporate the same Text Out device,

+  // their MaxMode and QueryData should be the intersection of both.

+  //

+  Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL);

+  ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (mStdErr.CurrentNumberOfConsoles == 1) {

+    gST->StandardErrorHandle  = mStdErr.VirtualHandle;

+    gST->StdErr               = &mStdErr.TextOut;

+    //

+    // Update the CRC32 in the EFI System Table header

+    //

+    gST->Hdr.CRC32 = 0;

+    gBS->CalculateCrc32 (

+          (UINT8 *) &gST->Hdr,

+          gST->Hdr.HeaderSize,

+          &gST->Hdr.CRC32

+          );

+  }

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_HANDLE                      ConSplitterVirtualHandle,

+  IN  EFI_GUID                        *DeviceGuid,

+  IN  EFI_GUID                        *InterfaceGuid,

+  IN  VOID                            **Interface

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard DriverBinding Protocol Stop() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  InterfaceGuid,

+                  Interface,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // close the protocol refered.

+  //

+  gBS->CloseProtocol (

+        ControllerHandle,

+        DeviceGuid,

+        This->DriverBindingHandle,

+        ConSplitterVirtualHandle

+        );

+  gBS->CloseProtocol (

+        ControllerHandle,

+        DeviceGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard DriverBinding Protocol Stop() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;

+

+  if (NumberOfChildren == 0) {

+    return EFI_SUCCESS;

+  }

+

+  Status = ConSplitterStop (

+            This,

+            ControllerHandle,

+            mConIn.VirtualHandle,

+            &gEfiConsoleInDeviceGuid,

+            &gEfiSimpleTextInProtocolGuid,

+            (VOID **) &TextIn

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Delete this console input device's data structures.

+  //

+  return ConSplitterTextInDeleteDevice (&mConIn, TextIn);

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard DriverBinding Protocol Stop() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;

+

+  if (NumberOfChildren == 0) {

+    return EFI_SUCCESS;

+  }

+

+  Status = ConSplitterStop (

+            This,

+            ControllerHandle,

+            mConIn.VirtualHandle,

+            &gEfiSimplePointerProtocolGuid,

+            &gEfiSimplePointerProtocolGuid,

+            (VOID **) &SimplePointer

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Delete this console input device's data structures.

+  //

+  return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard DriverBinding Protocol Stop() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

+

+  if (NumberOfChildren == 0) {

+    return EFI_SUCCESS;

+  }

+

+  Status = ConSplitterStop (

+            This,

+            ControllerHandle,

+            mConOut.VirtualHandle,

+            &gEfiConsoleOutDeviceGuid,

+            &gEfiSimpleTextOutProtocolGuid,

+            (VOID **) &TextOut

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Remove any UGA devices

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw,

+                  This->DriverBindingHandle,

+                  mConOut.VirtualHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  //

+  // Delete this console output device's data structures.

+  //

+  return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);

+}

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard DriverBinding Protocol Stop() function)

+

+Returns:

+

+  EFI_SUCCESS - Complete successfully.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+

+  if (NumberOfChildren == 0) {

+    return EFI_SUCCESS;

+  }

+

+  Status = ConSplitterStop (

+            This,

+            ControllerHandle,

+            mStdErr.VirtualHandle,

+            &gEfiStandardErrorDeviceGuid,

+            &gEfiSimpleTextOutProtocolGuid,

+            (VOID **) &TextOut

+            );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Delete this console error out device's data structures.

+  //

+  Status = ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (mStdErr.CurrentNumberOfConsoles == 0) {

+    gST->StandardErrorHandle  = NULL;

+    gST->StdErr               = NULL;

+    //

+    // Update the CRC32 in the EFI System Table header

+    //

+    gST->Hdr.CRC32 = 0;

+    gBS->CalculateCrc32 (

+          (UINT8 *) &gST->Hdr,

+          gST->Hdr.HeaderSize,

+          &gST->Hdr.CRC32

+          );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+ConSplitterGrowBuffer (

+  IN  UINTN                           SizeOfCount,

+  IN  UINTN                           *Count,

+  IN OUT  VOID                        **Buffer

+  )

+/*++

+

+Routine Description:

+  Take the passed in Buffer of size SizeOfCount and grow the buffer

+  by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount

+  bytes. Copy the current data in Buffer to the new version of Buffer

+  and free the old version of buffer.

+

+

+Arguments:

+  SizeOfCount - Size of element in array

+  Count       - Current number of elements in array

+  Buffer      - Bigger version of passed in Buffer with all the data

+

+Returns:

+  EFI_SUCCESS - Buffer size has grown

+  EFI_OUT_OF_RESOURCES - Could not grow the buffer size

+

+  None

+

+--*/

+{

+  UINTN NewSize;

+  UINTN OldSize;

+  VOID  *Ptr;

+

+  //

+  // grow the buffer to new buffer size,

+  // copy the old buffer's content to the new-size buffer,

+  // then free the old buffer.

+  //

+  OldSize = *Count * SizeOfCount;

+  *Count += CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT;

+  NewSize = *Count * SizeOfCount;

+

+  Ptr     = AllocateZeroPool (NewSize);

+  if (Ptr == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  CopyMem (Ptr, *Buffer, OldSize);

+

+  if (*Buffer != NULL) {

+    gBS->FreePool (*Buffer);

+  }

+

+  *Buffer = Ptr;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ConSplitterTextInAddDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *TextIn

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  EFI_SUCCESS

+  EFI_OUT_OF_RESOURCES

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // If the Text In List is full, enlarge it by calling growbuffer().

+  //

+  if (Private->CurrentNumberOfConsoles >= Private->TextInListCount) {

+    Status = ConSplitterGrowBuffer (

+              sizeof (EFI_SIMPLE_TEXT_IN_PROTOCOL *),

+              &Private->TextInListCount,

+              (VOID **) &Private->TextInList

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+  //

+  // Add the new text-in device data structure into the Text In List.

+  //

+  Private->TextInList[Private->CurrentNumberOfConsoles] = TextIn;

+  Private->CurrentNumberOfConsoles++;

+

+  //

+  // Extra CheckEvent added to reduce the double CheckEvent() in UI.c

+  //

+  gBS->CheckEvent (TextIn->WaitForKey);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ConSplitterTextInDeleteDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *TextIn

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  EFI_SUCCESS

+  EFI_NOT_FOUND

+

+--*/

+{

+  UINTN Index;

+  //

+  // Remove the specified text-in device data structure from the Text In List,

+  // and rearrange the remaining data structures in the Text In List.

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

+    if (Private->TextInList[Index] == TextIn) {

+      for (Index = Index; Index < Private->CurrentNumberOfConsoles - 1; Index++) {

+        Private->TextInList[Index] = Private->TextInList[Index + 1];

+      }

+

+      Private->CurrentNumberOfConsoles--;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+ConSplitterSimplePointerAddDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *SimplePointer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES

+  EFI_SUCCESS

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // If the Text In List is full, enlarge it by calling growbuffer().

+  //

+  if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {

+    Status = ConSplitterGrowBuffer (

+              sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),

+              &Private->PointerListCount,

+              (VOID **) &Private->PointerList

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+  //

+  // Add the new text-in device data structure into the Text In List.

+  //

+  Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;

+  Private->CurrentNumberOfPointers++;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ConSplitterSimplePointerDeleteDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *SimplePointer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Index;

+  //

+  // Remove the specified text-in device data structure from the Text In List,

+  // and rearrange the remaining data structures in the Text In List.

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {

+    if (Private->PointerList[Index] == SimplePointer) {

+      for (Index = Index; Index < Private->CurrentNumberOfPointers - 1; Index++) {

+        Private->PointerList[Index] = Private->PointerList[Index + 1];

+      }

+

+      Private->CurrentNumberOfPointers--;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+ConSplitterGrowMapTable (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Size;

+  UINTN NewSize;

+  UINTN TotalSize;

+  INT32 *TextOutModeMap;

+  INT32 *OldTextOutModeMap;

+  INT32 *SrcAddress;

+  INT32 Index;

+

+  NewSize           = Private->TextOutListCount * sizeof (INT32);

+  OldTextOutModeMap = Private->TextOutModeMap;

+  TotalSize         = NewSize * Private->TextOutQueryDataCount;

+

+  TextOutModeMap    = AllocateZeroPool (TotalSize);

+  if (TextOutModeMap == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetMem (TextOutModeMap, TotalSize, 0xFF);

+  Private->TextOutModeMap = TextOutModeMap;

+

+  //

+  // If TextOutList has been enlarged, need to realloc the mode map table

+  // The mode map table is regarded as a two dimension array.

+  //

+  //                         Old                    New

+  //  0   ---------> TextOutListCount ----> TextOutListCount

+  //  |   -------------------------------------------

+  //  |  |                    |                      |

+  //  |  |                    |                      |

+  //  |  |                    |                      |

+  //  |  |                    |                      |

+  //  |  |                    |                      |

+  // \/  |                    |                      |

+  //      -------------------------------------------

+  // QueryDataCount

+  //

+  if (OldTextOutModeMap != NULL) {

+

+    Size        = Private->CurrentNumberOfConsoles * sizeof (INT32);

+    Index       = 0;

+    SrcAddress  = OldTextOutModeMap;

+

+    //

+    // Copy the old data to the new one

+    //

+    while (Index < Private->TextOutMode.MaxMode) {

+      CopyMem (TextOutModeMap, SrcAddress, Size);

+      TextOutModeMap += NewSize;

+      SrcAddress += Size;

+      Index++;

+    }

+    //

+    // Free the old buffer

+    //

+    gBS->FreePool (OldTextOutModeMap);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ConSplitterAddOutputMode (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+  INT32       MaxMode;

+  INT32       Mode;

+  UINTN       Index;

+

+  MaxMode                       = TextOut->Mode->MaxMode;

+  Private->TextOutMode.MaxMode  = MaxMode;

+

+  //

+  // Grow the buffer if query data buffer is not large enough to

+  // hold all the mode supported by the first console.

+  //

+  while (MaxMode > (INT32) Private->TextOutQueryDataCount) {

+    Status = ConSplitterGrowBuffer (

+              sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),

+              &Private->TextOutQueryDataCount,

+              (VOID **) &Private->TextOutQueryData

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+  //

+  // Allocate buffer for the output mode map

+  //

+  Status = ConSplitterGrowMapTable (Private);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // As the first textout device, directly add the mode in to QueryData

+  // and at the same time record the mapping between QueryData and TextOut.

+  //

+  Mode  = 0;

+  Index = 0;

+  while (Mode < MaxMode) {

+    TextOut->QueryMode (

+              TextOut,

+              Mode,

+              &Private->TextOutQueryData[Mode].Columns,

+              &Private->TextOutQueryData[Mode].Rows

+              );

+    Private->TextOutModeMap[Index] = Mode;

+    Mode++;

+    Index += Private->TextOutListCount;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+ConSplitterGetIntersection (

+  IN  INT32                           *TextOutModeMap,

+  IN  INT32                           *NewlyAddedMap,

+  IN  UINTN                           MapStepSize,

+  IN  UINTN                           NewMapStepSize,

+  OUT INT32                           *MaxMode,

+  OUT INT32                           *CurrentMode

+  )

+{

+  INT32 Index;

+  INT32 *CurrentMapEntry;

+  INT32 *NextMapEntry;

+  INT32 CurrentMaxMode;

+  INT32 Mode;

+

+  Index           = 0;

+  CurrentMapEntry = TextOutModeMap;

+  NextMapEntry    = TextOutModeMap;

+  CurrentMaxMode  = *MaxMode;

+  Mode            = *CurrentMode;

+

+  while (Index < CurrentMaxMode) {

+    if (*NewlyAddedMap == -1) {

+      //

+      // This mode is not supported any more. Remove it. Special care

+      // must be taken as this remove will also affect current mode;

+      //

+      if (Index == *CurrentMode) {

+        Mode = -1;

+      } else if (Index < *CurrentMode) {

+        Mode--;

+      }

+      (*MaxMode)--;

+    } else {

+      if (CurrentMapEntry != NextMapEntry) {

+        CopyMem (NextMapEntry, CurrentMapEntry, MapStepSize * sizeof (INT32));

+      }

+

+      NextMapEntry += MapStepSize;

+    }

+

+    CurrentMapEntry += MapStepSize;

+    NewlyAddedMap += NewMapStepSize;

+    Index++;

+  }

+

+  *CurrentMode = Mode;

+

+  return ;

+}

+

+VOID

+ConSplitterSyncOutputMode (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  Private - Private data structure.

+  TextOut - Text Out Protocol.

+Returns:

+

+  None

+

+--*/

+{

+  INT32                         CurrentMode;

+  INT32                         CurrentMaxMode;

+  INT32                         Mode;

+  INT32                         Index;

+  INT32                         *TextOutModeMap;

+  INT32                         *MapTable;

+  TEXT_OUT_SPLITTER_QUERY_DATA  *TextOutQueryData;

+  UINTN                         Rows;

+  UINTN                         Columns;

+  UINTN                         StepSize;

+

+  //

+  // Must make sure that current mode won't change even if mode number changes

+  //

+  CurrentMode       = Private->TextOutMode.Mode;

+  CurrentMaxMode    = Private->TextOutMode.MaxMode;

+  TextOutModeMap    = Private->TextOutModeMap;

+  StepSize          = Private->TextOutListCount;

+  TextOutQueryData  = Private->TextOutQueryData;

+

+  //

+  // Query all the mode that the newly added TextOut supports

+  //

+  Mode      = 0;

+  MapTable  = TextOutModeMap + Private->CurrentNumberOfConsoles;

+  while (Mode < TextOut->Mode->MaxMode) {

+    TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);

+

+    //

+    // Search the QueryData database to see if they intersects

+    //

+    Index = 0;

+    while (Index < CurrentMaxMode) {

+      if ((TextOutQueryData[Index].Rows == Rows) && (TextOutQueryData[Index].Columns == Columns)) {

+        MapTable[Index * StepSize] = Mode;

+        break;

+      }

+

+      Index++;

+    }

+

+    Mode++;

+  }

+  //

+  // Now search the TextOutModeMap table to find the intersection of supported

+  // mode between ConSplitter and the newly added device.

+  //

+  ConSplitterGetIntersection (

+    TextOutModeMap,

+    MapTable,

+    StepSize,

+    StepSize,

+    &Private->TextOutMode.MaxMode,

+    &Private->TextOutMode.Mode

+    );

+

+  return ;

+}

+

+EFI_STATUS

+ConSplitterGetIntersectionBetweenConOutAndStrErr (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN                         ConOutNumOfConsoles;

+  UINTN                         StdErrNumOfConsoles;

+  TEXT_OUT_AND_UGA_DATA         *ConOutTextOutList;

+  TEXT_OUT_AND_UGA_DATA         *StdErrTextOutList;

+  UINTN                         Indexi;

+  UINTN                         Indexj;

+  UINTN                         Rows;

+  UINTN                         Columns;

+  INT32                         ConOutCurrentMode;

+  INT32                         StdErrCurrentMode;

+  INT32                         ConOutMaxMode;

+  INT32                         StdErrMaxMode;

+  INT32                         Mode;

+  INT32                         Index;

+  INT32                         *ConOutModeMap;

+  INT32                         *StdErrModeMap;

+  INT32                         *ConOutMapTable;

+  INT32                         *StdErrMapTable;

+  TEXT_OUT_SPLITTER_QUERY_DATA  *ConOutQueryData;

+  TEXT_OUT_SPLITTER_QUERY_DATA  *StdErrQueryData;

+  UINTN                         ConOutStepSize;

+  UINTN                         StdErrStepSize;

+  BOOLEAN                       FoundTheSameTextOut;

+  UINTN                         ConOutMapTableSize;

+  UINTN                         StdErrMapTableSize;

+

+  ConOutNumOfConsoles = mConOut.CurrentNumberOfConsoles;

+  StdErrNumOfConsoles = mStdErr.CurrentNumberOfConsoles;

+  ConOutTextOutList   = mConOut.TextOutList;

+  StdErrTextOutList   = mStdErr.TextOutList;

+

+  Indexi              = 0;

+  FoundTheSameTextOut = FALSE;

+  while ((Indexi < ConOutNumOfConsoles) && (!FoundTheSameTextOut)) {

+    Indexj = 0;

+    while (Indexj < StdErrNumOfConsoles) {

+      if (ConOutTextOutList->TextOut == StdErrTextOutList->TextOut) {

+        FoundTheSameTextOut = TRUE;

+        break;

+      }

+

+      Indexj++;

+      StdErrTextOutList++;

+    }

+

+    Indexi++;

+    ConOutTextOutList++;

+  }

+

+  if (!FoundTheSameTextOut) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Must make sure that current mode won't change even if mode number changes

+  //

+  ConOutCurrentMode = mConOut.TextOutMode.Mode;

+  ConOutMaxMode     = mConOut.TextOutMode.MaxMode;

+  ConOutModeMap     = mConOut.TextOutModeMap;

+  ConOutStepSize    = mConOut.TextOutListCount;

+  ConOutQueryData   = mConOut.TextOutQueryData;

+

+  StdErrCurrentMode = mStdErr.TextOutMode.Mode;

+  StdErrMaxMode     = mStdErr.TextOutMode.MaxMode;

+  StdErrModeMap     = mStdErr.TextOutModeMap;

+  StdErrStepSize    = mStdErr.TextOutListCount;

+  StdErrQueryData   = mStdErr.TextOutQueryData;

+

+  //

+  // Allocate the map table and set the map table's index to -1.

+  //

+  ConOutMapTableSize  = ConOutMaxMode * sizeof (INT32);

+  ConOutMapTable      = AllocateZeroPool (ConOutMapTableSize);

+  if (ConOutMapTable == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetMem (ConOutMapTable, ConOutMapTableSize, 0xFF);

+

+  StdErrMapTableSize  = StdErrMaxMode * sizeof (INT32);

+  StdErrMapTable      = AllocateZeroPool (StdErrMapTableSize);

+  if (StdErrMapTable == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetMem (StdErrMapTable, StdErrMapTableSize, 0xFF);

+

+  //

+  // Find the intersection of the two set of modes. If they actually intersect, the

+  // correponding entry in the map table is set to 1.

+  //

+  Mode = 0;

+  while (Mode < ConOutMaxMode) {

+    //

+    // Search the other's QueryData database to see if they intersect

+    //

+    Index   = 0;

+    Rows    = ConOutQueryData[Mode].Rows;

+    Columns = ConOutQueryData[Mode].Columns;

+    while (Index < StdErrMaxMode) {

+      if ((StdErrQueryData[Index].Rows == Rows) && (StdErrQueryData[Index].Columns == Columns)) {

+        ConOutMapTable[Mode]  = 1;

+        StdErrMapTable[Index] = 1;

+        break;

+      }

+

+      Index++;

+    }

+

+    Mode++;

+  }

+  //

+  // Now search the TextOutModeMap table to find the intersection of supported

+  // mode between ConSplitter and the newly added device.

+  //

+  ConSplitterGetIntersection (

+    ConOutModeMap,

+    ConOutMapTable,

+    mConOut.TextOutListCount,

+    1,

+    &(mConOut.TextOutMode.MaxMode),

+    &(mConOut.TextOutMode.Mode)

+    );

+  if (mConOut.TextOutMode.Mode < 0) {

+    mConOut.TextOut.SetMode (&(mConOut.TextOut), 0);

+  }

+

+  ConSplitterGetIntersection (

+    StdErrModeMap,

+    StdErrMapTable,

+    mStdErr.TextOutListCount,

+    1,

+    &(mStdErr.TextOutMode.MaxMode),

+    &(mStdErr.TextOutMode.Mode)

+    );

+  if (mStdErr.TextOutMode.Mode < 0) {

+    mStdErr.TextOut.SetMode (&(mStdErr.TextOut), 0);

+  }

+

+  gBS->FreePool (ConOutMapTable);

+  gBS->FreePool (StdErrMapTable);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ConSplitterTextOutAddDevice (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut,

+  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS            Status;

+  UINTN                 CurrentNumOfConsoles;

+  INT32                 CurrentMode;

+  INT32                 MaxMode;

+  TEXT_OUT_AND_UGA_DATA *TextAndUga;

+

+  Status                = EFI_SUCCESS;

+  CurrentNumOfConsoles  = Private->CurrentNumberOfConsoles;

+

+  //

+  // If the Text Out List is full, enlarge it by calling growbuffer().

+  //

+  while (CurrentNumOfConsoles >= Private->TextOutListCount) {

+    Status = ConSplitterGrowBuffer (

+              sizeof (TEXT_OUT_AND_UGA_DATA),

+              &Private->TextOutListCount,

+              (VOID **) &Private->TextOutList

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+    //

+    // Also need to reallocate the TextOutModeMap table

+    //

+    Status = ConSplitterGrowMapTable (Private);

+    if (EFI_ERROR (Status)) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+

+  TextAndUga          = &Private->TextOutList[CurrentNumOfConsoles];

+

+  TextAndUga->TextOut = TextOut;

+  TextAndUga->UgaDraw = UgaDraw;

+  if (UgaDraw == NULL) {

+    //

+    // If No UGA device then use the ConOut device

+    //

+    TextAndUga->TextOutEnabled = TRUE;

+  } else {

+    //

+    // If UGA device use ConOut device only used if UGA screen is in Text mode

+    //

+    TextAndUga->TextOutEnabled = (BOOLEAN) (Private->UgaMode == EfiConsoleControlScreenText);

+  }

+

+  if (CurrentNumOfConsoles == 0) {

+    //

+    // Add the first device's output mode to console splitter's mode list

+    //

+    Status = ConSplitterAddOutputMode (Private, TextOut);

+  } else {

+    ConSplitterSyncOutputMode (Private, TextOut);

+  }

+

+  Private->CurrentNumberOfConsoles++;

+

+  //

+  // Scan both TextOutList, for the intersection TextOut device

+  // maybe both ConOut and StdErr incorporate the same Text Out

+  // device in them, thus the output of both should be synced.

+  //

+  ConSplitterGetIntersectionBetweenConOutAndStrErr ();

+

+  CurrentMode = Private->TextOutMode.Mode;

+  MaxMode     = Private->TextOutMode.MaxMode;

+  ASSERT (MaxMode >= 1);

+

+  if (Private->UgaMode == EfiConsoleControlScreenGraphics && UgaDraw != NULL) {

+    //

+    // We just added a new UGA device in graphics mode

+    //

+    DevNullUgaSync (Private, UgaDraw);

+

+  } else if ((CurrentMode >= 0) && (UgaDraw != NULL) && (CurrentMode < Private->TextOutMode.MaxMode)) {

+    //

+    // The new console supports the same mode of the current console so sync up

+    //

+    DevNullSyncUgaStdOut (Private);

+  } else {

+    //

+    // If ConOut, then set the mode to Mode #0 which us 80 x 25

+    //

+    Private->TextOut.SetMode (&Private->TextOut, 0);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+ConSplitterTextOutDeleteDevice (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  INT32                 Index;

+  UINTN                 CurrentNumOfConsoles;

+  TEXT_OUT_AND_UGA_DATA *TextOutList;

+  EFI_STATUS            Status;

+

+  //

+  // Remove the specified text-out device data structure from the Text out List,

+  // and rearrange the remaining data structures in the Text out List.

+  //

+  CurrentNumOfConsoles  = Private->CurrentNumberOfConsoles;

+  Index                 = (INT32) CurrentNumOfConsoles - 1;

+  TextOutList           = Private->TextOutList;

+  while (Index >= 0) {

+    if (TextOutList->TextOut == TextOut) {

+      CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_UGA_DATA) * Index);

+      CurrentNumOfConsoles--;

+      break;

+    }

+

+    Index--;

+    TextOutList++;

+  }

+  //

+  // The specified TextOut is not managed by the ConSplitter driver

+  //

+  if (Index < 0) {

+    return EFI_NOT_FOUND;

+  }

+

+  if (CurrentNumOfConsoles == 0) {

+    //

+    // If the number of consoles is zero clear the Dev NULL device

+    //

+    Private->CurrentNumberOfConsoles      = 0;

+    Private->TextOutMode.MaxMode          = 1;

+    Private->TextOutQueryData[0].Columns  = 80;

+    Private->TextOutQueryData[0].Rows     = 25;

+    DevNullTextOutSetMode (Private, 0);

+

+    return EFI_SUCCESS;

+  }

+  //

+  // Max Mode is realy an intersection of the QueryMode command to all

+  // devices. So we must copy the QueryMode of the first device to

+  // QueryData.

+  //

+  ZeroMem (

+    Private->TextOutQueryData,

+    Private->TextOutQueryDataCount * sizeof (TEXT_OUT_SPLITTER_QUERY_DATA)

+    );

+

+  gBS->FreePool (Private->TextOutModeMap);

+  Private->TextOutModeMap = NULL;

+  TextOutList             = Private->TextOutList;

+

+  //

+  // Add the first TextOut to the QueryData array and ModeMap table

+  //

+  Status = ConSplitterAddOutputMode (Private, TextOutList->TextOut);

+

+  //

+  // Now add one by one

+  //

+  Index = 1;

+  Private->CurrentNumberOfConsoles = 1;

+  TextOutList++;

+  while ((UINTN) Index < CurrentNumOfConsoles) {

+    ConSplitterSyncOutputMode (Private, TextOutList->TextOut);

+    Index++;

+    Private->CurrentNumberOfConsoles++;

+    TextOutList++;

+  }

+

+  ConSplitterGetIntersectionBetweenConOutAndStrErr ();

+

+  return Status;

+}

+//

+// ConSplitter TextIn member functions

+//

+EFI_STATUS

+EFIAPI

+ConSplitterTextInReset (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset the input device and optionaly run diagnostics

+

+  Arguments:

+    This                 - Protocol instance pointer.

+    ExtendedVerification - Driver may perform diagnostics on reset.

+

+  Returns:

+    EFI_SUCCESS           - The device was reset.

+    EFI_DEVICE_ERROR      - The device is not functioning properly and could 

+                            not be reset.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_STATUS                    ReturnStatus;

+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;

+  UINTN                         Index;

+

+  Private                       = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  Private->KeyEventSignalState  = FALSE;

+

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+    Status = Private->TextInList[Index]->Reset (

+                                          Private->TextInList[Index],

+                                          ExtendedVerification

+                                          );

+    if (EFI_ERROR (Status)) {

+      ReturnStatus = Status;

+    }

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextInPrivateReadKeyStroke (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  OUT EFI_INPUT_KEY                   *Key

+  )

+/*++

+

+  Routine Description:

+    Reads the next keystroke from the input device. The WaitForKey Event can 

+    be used to test for existance of a keystroke via WaitForEvent () call.

+

+  Arguments:

+    This   - Protocol instance pointer.

+    Key    - Driver may perform diagnostics on reset.

+

+  Returns:

+    EFI_SUCCESS       - The keystroke information was returned.

+    EFI_NOT_READY     - There was no keystroke data availiable.

+    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 

+                        hardware errors.

+

+--*/

+{

+  EFI_STATUS    Status;

+  UINTN         Index;

+  EFI_INPUT_KEY CurrentKey;

+

+  Key->UnicodeChar  = 0;

+  Key->ScanCode     = SCAN_NULL;

+

+  //

+  // if no physical console input device exists, return EFI_NOT_READY;

+  // if any physical console input device has key input,

+  // return the key and EFI_SUCCESS.

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

+    Status = Private->TextInList[Index]->ReadKeyStroke (

+                                          Private->TextInList[Index],

+                                          &CurrentKey

+                                          );

+    if (!EFI_ERROR (Status)) {

+      *Key = CurrentKey;

+      return Status;

+    }

+  }

+

+  return EFI_NOT_READY;

+}

+

+BOOLEAN

+ConSpliterConssoleControlStdInLocked (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE if StdIn is locked. The ConIn device on the virtual handle is

+  the only device locked.

+

+Arguments:

+  NONE

+

+Returns:

+  TRUE  - StdIn locked

+  FALSE - StdIn working normally

+

+--*/

+{

+  return mConIn.PasswordEnabled;

+}

+

+VOID

+EFIAPI

+ConSpliterConsoleControlLockStdInEvent (

+  IN  EFI_EVENT                       Event,

+  IN  VOID                            *Context

+  )

+/*++

+

+Routine Description:

+  This timer event will fire when StdIn is locked. It will check the key 

+  sequence on StdIn to see if it matches the password. Any error in the

+  password will cause the check to reset. As long a mConIn.PasswordEnabled is

+  TRUE the StdIn splitter will not report any input.

+

+Arguments:

+  (Standard EFI_EVENT_NOTIFY)

+  

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS    Status;

+  EFI_INPUT_KEY Key;

+  CHAR16        BackSpaceString[2];

+  CHAR16        SpaceString[2];

+

+  do {

+    Status = ConSplitterTextInPrivateReadKeyStroke (&mConIn, &Key);

+    if (!EFI_ERROR (Status)) {

+      //

+      // if it's an ENTER, match password

+      //

+      if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN) && (Key.ScanCode == SCAN_NULL)) {

+        mConIn.PwdAttempt[mConIn.PwdIndex] = CHAR_NULL;

+        if (StrCmp (mConIn.Password, mConIn.PwdAttempt)) {

+          //

+          // Password not match

+          //

+          ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\rPassword not correct\n\r");

+          mConIn.PwdIndex = 0;

+        } else {

+          //

+          // Key matches password sequence

+          //

+          gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, 0);

+          mConIn.PasswordEnabled  = FALSE;

+          Status                  = EFI_NOT_READY;

+        }

+      } else if ((Key.UnicodeChar == CHAR_BACKSPACE) && (Key.ScanCode == SCAN_NULL)) {

+        //

+        // BackSpace met

+        //

+        if (mConIn.PwdIndex > 0) {

+          BackSpaceString[0]  = CHAR_BACKSPACE;

+          BackSpaceString[1]  = 0;

+

+          SpaceString[0]      = ' ';

+          SpaceString[1]      = 0;

+

+          ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);

+          ConSplitterTextOutOutputString (&mConOut.TextOut, SpaceString);

+          ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);

+

+          mConIn.PwdIndex--;

+        }

+      } else if ((Key.ScanCode == SCAN_NULL) && (Key.UnicodeChar >= 32)) {

+        //

+        // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input

+        //

+        if (mConIn.PwdIndex < (MAX_STD_IN_PASSWORD - 1)) {

+          if (mConIn.PwdIndex == 0) {

+            ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\r");

+          }

+

+          ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"*");

+          mConIn.PwdAttempt[mConIn.PwdIndex] = Key.UnicodeChar;

+          mConIn.PwdIndex++;

+        }

+      }

+    }

+  } while (!EFI_ERROR (Status));

+}

+

+EFI_STATUS

+EFIAPI

+ConSpliterConsoleControlLockStdIn (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,

+  IN  CHAR16                          *Password

+  )

+/*++

+

+Routine Description:

+  If Password is NULL unlock the password state variable and set the event 

+  timer. If the Password is too big return an error. If the Password is valid

+  Copy the Password and enable state variable and then arm the periodic timer

+

+Arguments:

+

+Returns:

+  EFI_SUCCESS           - Lock the StdIn device

+  EFI_INVALID_PARAMETER - Password is NULL

+  EFI_OUT_OF_RESOURCES  - Buffer allocation to store the password fails

+

+--*/

+{

+  if (Password == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (StrLen (Password) >= MAX_STD_IN_PASSWORD) {

+    //

+    // Currently have a max password size

+    //

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Save the password, initialize state variables and arm event timer

+  //

+  StrCpy (mConIn.Password, Password);

+  mConIn.PasswordEnabled  = TRUE;

+  mConIn.PwdIndex         = 0;

+  gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, (10000 * 25));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextInReadKeyStroke (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *This,

+  OUT EFI_INPUT_KEY                   *Key

+  )

+/*++

+

+  Routine Description:

+    Reads the next keystroke from the input device. The WaitForKey Event can 

+    be used to test for existance of a keystroke via WaitForEvent () call.

+    If the ConIn is password locked make it look like no keystroke is availible

+

+  Arguments:

+    This   - Protocol instance pointer.

+    Key    - Driver may perform diagnostics on reset.

+

+  Returns:

+    EFI_SUCCESS       - The keystroke information was returned.

+    EFI_NOT_READY     - There was no keystroke data availiable.

+    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 

+                        hardware errors.

+

+--*/

+{

+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;

+

+  Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+  if (Private->PasswordEnabled) {

+    //

+    // If StdIn Locked return not ready

+    //

+    return EFI_NOT_READY;

+  }

+

+  Private->KeyEventSignalState = FALSE;

+

+  return ConSplitterTextInPrivateReadKeyStroke (Private, Key);

+}

+

+VOID

+EFIAPI

+ConSplitterTextInWaitForKey (

+  IN  EFI_EVENT                       Event,

+  IN  VOID                            *Context

+  )

+/*++

+

+Routine Description:

+  This event agregates all the events of the ConIn devices in the spliter.

+  If the ConIn is password locked then return.

+  If any events of physical ConIn devices are signaled, signal the ConIn

+  spliter event. This will cause the calling code to call 

+  ConSplitterTextInReadKeyStroke ().

+

+Arguments:

+  Event   - The Event assoicated with callback.

+  Context - Context registered when Event was created.

+

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS                    Status;

+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;

+  UINTN                         Index;

+

+  Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;

+  if (Private->PasswordEnabled) {

+    //

+    // If StdIn Locked return not ready

+    //

+    return ;

+  }

+

+  //

+  // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()

+  //

+  if (Private->KeyEventSignalState) {

+    gBS->SignalEvent (Event);

+    return ;

+  }

+  //

+  // if any physical console input device has key input, signal the event.

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

+    Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);

+    if (!EFI_ERROR (Status)) {

+      gBS->SignalEvent (Event);

+      Private->KeyEventSignalState = TRUE;

+    }

+  }

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerReset (

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset the input device and optionaly run diagnostics

+

+  Arguments:

+    This                 - Protocol instance pointer.

+    ExtendedVerification - Driver may perform diagnostics on reset.

+

+  Returns:

+    EFI_SUCCESS           - The device was reset.

+    EFI_DEVICE_ERROR      - The device is not functioning properly and could 

+                            not be reset.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_STATUS                    ReturnStatus;

+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;

+  UINTN                         Index;

+

+  Private                         = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);

+

+  Private->InputEventSignalState  = FALSE;

+

+  if (Private->CurrentNumberOfPointers == 0) {

+    return EFI_SUCCESS;

+  }

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfPointers; Index++) {

+    Status = Private->PointerList[Index]->Reset (

+                                            Private->PointerList[Index],

+                                            ExtendedVerification

+                                            );

+    if (EFI_ERROR (Status)) {

+      ReturnStatus = Status;

+    }

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerPrivateGetState (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN OUT EFI_SIMPLE_POINTER_STATE     *State

+  )

+/*++

+

+  Routine Description:

+    Reads the next keystroke from the input device. The WaitForKey Event can 

+    be used to test for existance of a keystroke via WaitForEvent () call.

+

+  Arguments:

+    This   - Protocol instance pointer.

+    State  - 

+

+  Returns:

+    EFI_SUCCESS       - The keystroke information was returned.

+    EFI_NOT_READY     - There was no keystroke data availiable.

+    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 

+                        hardware errors.

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_STATUS                ReturnStatus;

+  UINTN                     Index;

+  EFI_SIMPLE_POINTER_STATE  CurrentState;

+

+  State->RelativeMovementX  = 0;

+  State->RelativeMovementY  = 0;

+  State->RelativeMovementZ  = 0;

+  State->LeftButton         = FALSE;

+  State->RightButton        = FALSE;

+

+  //

+  // if no physical console input device exists, return EFI_NOT_READY;

+  // if any physical console input device has key input,

+  // return the key and EFI_SUCCESS.

+  //

+  ReturnStatus = EFI_NOT_READY;

+  for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {

+

+    Status = Private->PointerList[Index]->GetState (

+                                            Private->PointerList[Index],

+                                            &CurrentState

+                                            );

+    if (!EFI_ERROR (Status)) {

+      if (ReturnStatus == EFI_NOT_READY) {

+        ReturnStatus = EFI_SUCCESS;

+      }

+

+      if (CurrentState.LeftButton) {

+        State->LeftButton = TRUE;

+      }

+

+      if (CurrentState.RightButton) {

+        State->RightButton = TRUE;

+      }

+

+      if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {

+        State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32) Private->SimplePointerMode.ResolutionX) / (INT32) Private->PointerList[Index]->Mode->ResolutionX;

+      }

+

+      if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {

+        State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32) Private->SimplePointerMode.ResolutionY) / (INT32) Private->PointerList[Index]->Mode->ResolutionY;

+      }

+

+      if (CurrentState.RelativeMovementZ != 0 && Private->PointerList[Index]->Mode->ResolutionZ != 0) {

+        State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32) Private->SimplePointerMode.ResolutionZ) / (INT32) Private->PointerList[Index]->Mode->ResolutionZ;

+      }

+    } else if (Status == EFI_DEVICE_ERROR) {

+      ReturnStatus = EFI_DEVICE_ERROR;

+    }

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerGetState (

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *This,

+  IN OUT EFI_SIMPLE_POINTER_STATE     *State

+  )

+/*++

+

+  Routine Description:

+    Reads the next keystroke from the input device. The WaitForKey Event can 

+    be used to test for existance of a keystroke via WaitForEvent () call.

+    If the ConIn is password locked make it look like no keystroke is availible

+

+  Arguments:

+    This   - Protocol instance pointer.

+    State  - 

+

+  Returns:

+    EFI_SUCCESS       - The keystroke information was returned.

+    EFI_NOT_READY     - There was no keystroke data availiable.

+    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 

+                        hardware errors.

+

+--*/

+{

+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;

+

+  Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);

+  if (Private->PasswordEnabled) {

+    //

+    // If StdIn Locked return not ready

+    //

+    return EFI_NOT_READY;

+  }

+

+  Private->InputEventSignalState = FALSE;

+

+  return ConSplitterSimplePointerPrivateGetState (Private, State);

+}

+

+VOID

+EFIAPI

+ConSplitterSimplePointerWaitForInput (

+  IN  EFI_EVENT                       Event,

+  IN  VOID                            *Context

+  )

+/*++

+

+Routine Description:

+  This event agregates all the events of the ConIn devices in the spliter.

+  If the ConIn is password locked then return.

+  If any events of physical ConIn devices are signaled, signal the ConIn

+  spliter event. This will cause the calling code to call 

+  ConSplitterTextInReadKeyStroke ().

+

+Arguments:

+  Event   - The Event assoicated with callback.

+  Context - Context registered when Event was created.

+

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS                    Status;

+  TEXT_IN_SPLITTER_PRIVATE_DATA *Private;

+  UINTN                         Index;

+

+  Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;

+  if (Private->PasswordEnabled) {

+    //

+    // If StdIn Locked return not ready

+    //

+    return ;

+  }

+

+  //

+  // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()

+  //

+  if (Private->InputEventSignalState) {

+    gBS->SignalEvent (Event);

+    return ;

+  }

+  //

+  // if any physical console input device has key input, signal the event.

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {

+    Status = gBS->CheckEvent (Private->PointerList[Index]->WaitForInput);

+    if (!EFI_ERROR (Status)) {

+      gBS->SignalEvent (Event);

+      Private->InputEventSignalState = TRUE;

+    }

+  }

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutReset (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset the text output device hardware and optionaly run diagnostics

+

+  Arguments:

+    This                 - Protocol instance pointer.

+    ExtendedVerification - Driver may perform more exhaustive verfication 

+                           operation of the device during reset.

+

+  Returns:

+    EFI_SUCCESS       - The text output device was reset.

+    EFI_DEVICE_ERROR  - The text output device is not functioning correctly and

+                        could not be reset.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+

+      Status = Private->TextOutList[Index].TextOut->Reset (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      ExtendedVerification

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));

+

+  Status = DevNullTextOutSetMode (Private, 0);

+  if (EFI_ERROR (Status)) {

+    ReturnStatus = Status;

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutOutputString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  CHAR16                          *WString

+  )

+/*++

+

+  Routine Description:

+    Write a Unicode string to the output device.

+

+  Arguments:

+    This    - Protocol instance pointer.

+    String  - The NULL-terminated Unicode string to be displayed on the output

+              device(s). All output devices must also support the Unicode 

+              drawing defined in this file.

+

+  Returns:

+    EFI_SUCCESS       - The string was output to the device.

+    EFI_DEVICE_ERROR  - The device reported an error while attempting to output

+                         the text.

+    EFI_UNSUPPORTED        - The output device's mode is not currently in a 

+                              defined text mode.

+    EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the 

+                              characters in the Unicode string could not be 

+                              rendered and were skipped.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  UINTN                           BackSpaceCount;

+  EFI_STATUS                      ReturnStatus;

+  CHAR16                          *TargetString;

+

+  This->SetAttribute (This, This->Mode->Attribute);

+

+  Private         = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  BackSpaceCount  = 0;

+  for (TargetString = WString; *TargetString; TargetString++) {

+    if (*TargetString == CHAR_BACKSPACE) {

+      BackSpaceCount++;

+    }

+

+  }

+

+  if (BackSpaceCount == 0) {

+    TargetString = WString;

+  } else {

+    TargetString = AllocatePool (sizeof (CHAR16) * (StrLen (WString) + BackSpaceCount + 1));

+    StrCpy (TargetString, WString);

+  }

+  //

+  // return the worst status met

+  //

+  Status = DevNullTextOutOutputString (Private, TargetString);

+  if (EFI_ERROR (Status)) {

+    ReturnStatus = Status;

+  }

+

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->OutputString (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      TargetString

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  if (BackSpaceCount) {

+    gBS->FreePool (TargetString);

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutTestString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  CHAR16                          *WString

+  )

+/*++

+

+  Routine Description:

+    Verifies that all characters in a Unicode string can be output to the 

+    target device.

+

+  Arguments:

+    This    - Protocol instance pointer.

+    String  - The NULL-terminated Unicode string to be examined for the output

+               device(s).

+

+  Returns:

+    EFI_SUCCESS     - The device(s) are capable of rendering the output string.

+    EFI_UNSUPPORTED - Some of the characters in the Unicode string cannot be 

+                       rendered by one or more of the output devices mapped 

+                       by the EFI handle.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->TestString (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      WString

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+  //

+  // There is no DevNullTextOutTestString () since a Unicode buffer would

+  // always return EFI_SUCCESS.

+  // ReturnStatus will be EFI_SUCCESS if no consoles are present

+  //

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutQueryMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           ModeNumber,

+  OUT UINTN                           *Columns,

+  OUT UINTN                           *Rows

+  )

+/*++

+

+  Routine Description:

+    Returns information for an available text mode that the output device(s)

+    supports.

+

+  Arguments:

+    This       - Protocol instance pointer.

+    ModeNumber - The mode number to return information on.

+    Columns, Rows - Returns the geometry of the text output device for the

+                    requested ModeNumber.

+

+  Returns:

+    EFI_SUCCESS      - The requested mode information was returned.

+    EFI_DEVICE_ERROR - The device had an error and could not 

+                       complete the request.

+    EFI_UNSUPPORTED - The mode number was not valid.

+

+--*/

+{

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // Check whether param ModeNumber is valid.

+  // ModeNumber should be within range 0 ~ MaxMode - 1.

+  //

+  if (ModeNumber > (UINTN)(((UINT32)-1)>>1)) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  if ((INT32) ModeNumber >= This->Mode->MaxMode) {

+    return EFI_UNSUPPORTED;

+  }

+

+  *Columns  = Private->TextOutQueryData[ModeNumber].Columns;

+  *Rows     = Private->TextOutQueryData[ModeNumber].Rows;

+

+  if (*Columns <= 0 && *Rows <= 0) {

+    return EFI_UNSUPPORTED;

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutSetMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           ModeNumber

+  )

+/*++

+

+  Routine Description:

+    Sets the output device(s) to a specified mode.

+

+  Arguments:

+    This       - Protocol instance pointer.

+    ModeNumber - The mode number to set.

+

+  Returns:

+    EFI_SUCCESS      - The requested text mode was set.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The mode number was not valid.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  INT32                           *TextOutModeMap;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // Check whether param ModeNumber is valid.

+  // ModeNumber should be within range 0 ~ MaxMode - 1.

+  //

+  if (ModeNumber > (UINTN)(((UINT32)-1)>>1)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if ((INT32) ModeNumber >= This->Mode->MaxMode) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // If the mode is being set to the curent mode, then just clear the screen and return.

+  //

+  if (Private->TextOutMode.Mode == (INT32) ModeNumber) {

+    return ConSplitterTextOutClearScreen (This);

+  }

+  //

+  // return the worst status met

+  //

+  TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->SetMode (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      TextOutModeMap[Index]

+                                                      );

+      //

+      // If this console device is based on a UGA device, then sync up the bitmap from

+      // the UGA splitter and reclear the text portion of the display in the new mode.

+      //

+      if (Private->TextOutList[Index].UgaDraw != NULL) {

+        Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);

+      }

+

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+  //

+  // The DevNull Console will support any possible mode as it allocates memory

+  //

+  Status = DevNullTextOutSetMode (Private, ModeNumber);

+  if (EFI_ERROR (Status)) {

+    ReturnStatus = Status;

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutSetAttribute (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           Attribute

+  )

+/*++

+

+  Routine Description:

+    Sets the background and foreground colors for the OutputString () and

+    ClearScreen () functions.

+

+  Arguments:

+    This      - Protocol instance pointer.

+    Attribute - The attribute to set. Bits 0..3 are the foreground color, and

+                bits 4..6 are the background color. All other bits are undefined

+                and must be zero. The valid Attributes are defined in this file.

+

+  Returns:

+    EFI_SUCCESS      - The attribute was set.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The attribute requested is not defined.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // Check whether param Attribute is valid.

+  //

+  if ( (Attribute > (UINTN)(((UINT32)-1)>>1)) ) {

+    return EFI_UNSUPPORTED;

+  }  

+

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->SetAttribute (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      Attribute

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  Private->TextOutMode.Attribute = (INT32) Attribute;

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutClearScreen (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This

+  )

+/*++

+

+  Routine Description:

+    Clears the output device(s) display to the currently selected background 

+    color.

+

+  Arguments:

+    This      - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS      - The operation completed successfully.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The output device is not in a valid text mode.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  Status = DevNullTextOutClearScreen (Private);

+  if (EFI_ERROR (Status)) {

+    ReturnStatus = Status;

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutSetCursorPosition (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           Column,

+  IN  UINTN                           Row

+  )

+/*++

+

+  Routine Description:

+    Sets the current coordinates of the cursor position

+

+  Arguments:

+    This        - Protocol instance pointer.

+    Column, Row - the position to set the cursor to. Must be greater than or

+                  equal to zero and less than the number of columns and rows

+                  by QueryMode ().

+

+  Returns:

+    EFI_SUCCESS      - The operation completed successfully.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The output device is not in a valid text mode, or the 

+                       cursor position is invalid for the current mode.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+  UINTN                           MaxColumn;

+  UINTN                           MaxRow;

+

+  Private   = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  MaxColumn = Private->TextOutQueryData[Private->TextOutMode.Mode].Columns;

+  MaxRow    = Private->TextOutQueryData[Private->TextOutMode.Mode].Rows;

+

+  if (Column >= MaxColumn || Row >= MaxRow) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->SetCursorPosition (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      Column,

+                                                      Row

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  DevNullTextOutSetCursorPosition (Private, Column, Row);

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutEnableCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  BOOLEAN                         Visible

+  )

+/*++

+

+  Routine Description:

+    Makes the cursor visible or invisible

+

+  Arguments:

+    This    - Protocol instance pointer.

+    Visible - If TRUE, the cursor is set to be visible. If FALSE, the cursor is

+              set to be invisible.

+

+  Returns:

+    EFI_SUCCESS      - The operation completed successfully.

+    EFI_DEVICE_ERROR - The device had an error and could not complete the 

+                        request, or the device does not support changing

+                        the cursor mode.

+    EFI_UNSUPPORTED - The output device is not in a valid text mode.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // return the worst status met

+  //

+  for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {

+

+    if (Private->TextOutList[Index].TextOutEnabled) {

+      Status = Private->TextOutList[Index].TextOut->EnableCursor (

+                                                      Private->TextOutList[Index].TextOut,

+                                                      Visible

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  DevNullTextOutEnableCursor (Private, Visible);

+

+  return ReturnStatus;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.h b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.h
new file mode 100644
index 0000000..fc68f04
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.h
@@ -0,0 +1,623 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConSplitter.h

+

+Abstract:

+

+  Private data structures for the Console Splitter driver

+

+--*/

+

+#ifndef SPLITER_H_

+#define SPLITER_H_

+

+//

+// Private Data Structures

+//

+#define CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT  32

+#define CONSOLE_SPLITTER_MODES_ALLOC_UNIT     32

+#define MAX_STD_IN_PASSWORD                   80

+

+typedef struct {

+  UINTN Columns;

+  UINTN Rows;

+} TEXT_OUT_SPLITTER_QUERY_DATA;

+

+//

+// Private data for the EFI_SIMPLE_INPUT_PROTOCOL splitter

+//

+#define TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('T', 'i', 'S', 'p')

+

+typedef struct {

+  UINT64                      Signature;

+  EFI_HANDLE                  VirtualHandle;

+

+  EFI_SIMPLE_TEXT_IN_PROTOCOL TextIn;

+  UINTN                       CurrentNumberOfConsoles;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL **TextInList;

+  UINTN                       TextInListCount;

+

+  EFI_SIMPLE_POINTER_PROTOCOL SimplePointer;

+  EFI_SIMPLE_POINTER_MODE     SimplePointerMode;

+  UINTN                       CurrentNumberOfPointers;

+  EFI_SIMPLE_POINTER_PROTOCOL **PointerList;

+  UINTN                       PointerListCount;

+

+  BOOLEAN                     PasswordEnabled;

+  CHAR16                      Password[MAX_STD_IN_PASSWORD];

+  UINTN                       PwdIndex;

+  CHAR16                      PwdAttempt[MAX_STD_IN_PASSWORD];

+  EFI_EVENT                   LockEvent;

+

+  BOOLEAN                     KeyEventSignalState;

+  BOOLEAN                     InputEventSignalState;

+} TEXT_IN_SPLITTER_PRIVATE_DATA;

+

+#define TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      TEXT_IN_SPLITTER_PRIVATE_DATA, \

+      TextIn, \

+      TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \

+      )

+

+#define TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS(a) \

+  CR (a, \

+      TEXT_IN_SPLITTER_PRIVATE_DATA, \

+      SimplePointer, \

+      TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \

+      )

+

+//

+// Private data for the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL splitter

+//

+#define TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('T', 'o', 'S', 'p')

+

+typedef struct {

+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+  BOOLEAN                       TextOutEnabled;

+} TEXT_OUT_AND_UGA_DATA;

+

+typedef struct {

+  UINT64                          Signature;

+  EFI_HANDLE                      VirtualHandle;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL    TextOut;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE     TextOutMode;

+  EFI_UGA_DRAW_PROTOCOL           UgaDraw;

+  UINT32                          UgaHorizontalResolution;

+  UINT32                          UgaVerticalResolution;

+  UINT32                          UgaColorDepth;

+  UINT32                          UgaRefreshRate;

+  EFI_UGA_PIXEL                   *UgaBlt;

+

+  EFI_CONSOLE_CONTROL_PROTOCOL    ConsoleControl;

+

+  UINTN                           CurrentNumberOfConsoles;

+  TEXT_OUT_AND_UGA_DATA           *TextOutList;

+  UINTN                           TextOutListCount;

+  TEXT_OUT_SPLITTER_QUERY_DATA    *TextOutQueryData;

+  UINTN                           TextOutQueryDataCount;

+  INT32                           *TextOutModeMap;

+

+  EFI_CONSOLE_CONTROL_SCREEN_MODE UgaMode;

+

+  UINTN                           DevNullColumns;

+  UINTN                           DevNullRows;

+  CHAR16                          *DevNullScreen;

+  INT32                           *DevNullAttributes;

+

+} TEXT_OUT_SPLITTER_PRIVATE_DATA;

+

+#define TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      TEXT_OUT_SPLITTER_PRIVATE_DATA, \

+      TextOut, \

+      TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE \

+      )

+

+#define UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      TEXT_OUT_SPLITTER_PRIVATE_DATA, \

+      UgaDraw, \

+      TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE \

+      )

+

+#define CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      TEXT_OUT_SPLITTER_PRIVATE_DATA, \

+      ConsoleControl, \

+      TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE \

+      )

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+ConSplitterDriverEntry (

+  IN EFI_HANDLE                       ImageHandle,

+  IN EFI_SYSTEM_TABLE                 *SystemTable

+  )

+;

+

+

+EFI_STATUS

+ConSplitterTextInConstructor (

+  TEXT_IN_SPLITTER_PRIVATE_DATA       *Private

+  )

+;

+

+

+EFI_STATUS

+ConSplitterTextOutConstructor (

+  TEXT_OUT_SPLITTER_PRIVATE_DATA      *Private

+  )

+;

+

+//

+// Driver Binding Functions

+//

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConInDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterConOutDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+ConSplitterStdErrDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      ControllerHandle,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+;

+

+//

+// TextIn Constructor/Destructor functions

+//

+EFI_STATUS

+ConSplitterTextInAddDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *TextIn

+  )

+;

+

+EFI_STATUS

+ConSplitterTextInDeleteDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *TextIn

+  )

+;

+

+//

+// SimplePointer Constuctor/Destructor functions

+//

+EFI_STATUS

+ConSplitterSimplePointerAddDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *SimplePointer

+  )

+;

+

+EFI_STATUS

+ConSplitterSimplePointerDeleteDevice (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *SimplePointer

+  )

+;

+

+//

+// TextOut Constuctor/Destructor functions

+//

+EFI_STATUS

+ConSplitterTextOutAddDevice (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut,

+  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw

+  )

+;

+

+EFI_STATUS

+ConSplitterTextOutDeleteDevice (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *TextOut

+  )

+;

+

+//

+// TextIn I/O Functions

+//

+EFI_STATUS

+EFIAPI

+ConSplitterTextInReset (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextInReadKeyStroke (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *This,

+  OUT EFI_INPUT_KEY                   *Key

+  )

+;

+

+VOID

+EFIAPI

+ConSplitterTextInWaitForKey (

+  IN  EFI_EVENT                       Event,

+  IN  VOID                            *Context

+  )

+;

+

+BOOLEAN

+ConSpliterConssoleControlStdInLocked (

+  VOID

+  )

+;

+

+VOID

+EFIAPI

+ConSpliterConsoleControlLockStdInEvent (

+  IN  EFI_EVENT                       Event,

+  IN  VOID                            *Context

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSpliterConsoleControlLockStdIn (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,

+  IN  CHAR16                          *Password

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextInPrivateReadKeyStroke (

+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,

+  OUT EFI_INPUT_KEY                   *Key

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerReset (

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterSimplePointerGetState (

+  IN  EFI_SIMPLE_POINTER_PROTOCOL     *This,

+  IN OUT EFI_SIMPLE_POINTER_STATE     *State

+  )

+;

+

+VOID

+EFIAPI

+ConSplitterSimplePointerWaitForInput (

+  IN  EFI_EVENT                       Event,

+  IN  VOID                            *Context

+  )

+;

+

+//

+// TextOut I/O Functions

+//

+VOID

+ConSplitterSynchronizeModeData (

+  TEXT_OUT_SPLITTER_PRIVATE_DATA      *Private

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutReset (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutOutputString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  CHAR16                          *WString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutTestString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  CHAR16                          *WString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutQueryMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           ModeNumber,

+  OUT UINTN                           *Columns,

+  OUT UINTN                           *Rows

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutSetMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           ModeNumber

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutSetAttribute (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           Attribute

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutClearScreen (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutSetCursorPosition (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  UINTN                           Column,

+  IN  UINTN                           Row

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSplitterTextOutEnableCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  BOOLEAN                         Visible

+  )

+;

+

+EFI_STATUS

+ConSplitterGrowBuffer (

+  IN  UINTN                           SizeOfCount,

+  IN  UINTN                           *Count,

+  IN OUT  VOID                        **Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSpliterConsoleControlGetMode (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,

+  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,

+  OUT BOOLEAN                         *UgaExists,

+  OUT BOOLEAN                         *StdInLocked

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSpliterConsoleControlSetMode (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,

+  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE Mode

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSpliterUgaDrawGetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL           *This,

+  OUT UINT32                          *HorizontalResolution,

+  OUT UINT32                          *VerticalResolution,

+  OUT UINT32                          *ColorDepth,

+  OUT UINT32                          *RefreshRate

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSpliterUgaDrawSetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL           *This,

+  IN UINT32                           HorizontalResolution,

+  IN UINT32                           VerticalResolution,

+  IN UINT32                           ColorDepth,

+  IN UINT32                           RefreshRate

+  )

+;

+

+EFI_STATUS

+EFIAPI

+ConSpliterUgaDrawBlt (

+  IN  EFI_UGA_DRAW_PROTOCOL                         *This,

+  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION                         BltOperation,

+  IN  UINTN                                         SourceX,

+  IN  UINTN                                         SourceY,

+  IN  UINTN                                         DestinationX,

+  IN  UINTN                                         DestinationY,

+  IN  UINTN                                         Width,

+  IN  UINTN                                         Height,

+  IN  UINTN                                         Delta         OPTIONAL

+  )

+;

+

+EFI_STATUS

+DevNullUgaSync (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw

+  )

+;

+

+EFI_STATUS

+DevNullTextOutOutputString (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  CHAR16                          *WString

+  )

+;

+

+EFI_STATUS

+DevNullTextOutSetMode (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  UINTN                           ModeNumber

+  )

+;

+

+EFI_STATUS

+DevNullTextOutClearScreen (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private

+  )

+;

+

+EFI_STATUS

+DevNullTextOutSetCursorPosition (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  UINTN                           Column,

+  IN  UINTN                           Row

+  )

+;

+

+EFI_STATUS

+DevNullTextOutEnableCursor (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  BOOLEAN                         Visible

+  )

+;

+

+EFI_STATUS

+DevNullSyncUgaStdOut (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.mbd b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.mbd
new file mode 100644
index 0000000..d4b36b6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>ConSplitter</BaseName>

+    <Guid>408edcec-cf6d-477c-a5a8-b4844e3de281</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.msa b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.msa
new file mode 100644
index 0000000..027c6b9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitter.msa
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>ConSplitter</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>408edcec-cf6d-477c-a5a8-b4844e3de281</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ConSplitter.c</Filename>

+    <Filename>ConSplitter.h</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>ConSplitterGraphics.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>    

+    <Protocol Usage="ALWAYS_CONSUMED">UgaDraw</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleTextOut</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleTextIn</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimplePointer</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">ConsoleControl</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_PRODUCED">

+      <C_Name>PrimaryStandardErrorDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_PRODUCED">

+      <C_Name>PrimaryConsoleInDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_PRODUCED">

+      <C_Name>PrimaryConsoleOutDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>ConsoleOutDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StandardErrorDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>ConsoleInDevice</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>ConSplitterDriverEntry</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gConSplitterConInDriverBinding</DriverBinding>

+      <ComponentName>gConSplitterConInComponentName</ComponentName>

+    </Extern>

+    <Extern>

+      <DriverBinding>gConSplitterSimplePointerDriverBinding</DriverBinding>

+      <ComponentName>gConSplitterSimplePointerComponentName</ComponentName>

+    </Extern>

+    <Extern>

+      <DriverBinding>gConSplitterConOutDriverBinding</DriverBinding>

+      <ComponentName>gConSplitterConOutComponentName</ComponentName>

+    </Extern>

+    <Extern>

+      <DriverBinding>gConSplitterStdErrDriverBinding</DriverBinding>

+      <ComponentName>gConSplitterStdErrComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitterGraphics.c b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitterGraphics.c
new file mode 100644
index 0000000..412d695
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitterGraphics.c
@@ -0,0 +1,1076 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  ConSplitterGraphics.c

+

+Abstract:

+

+  Support for ConsoleControl protocol. Support for UGA Draw spliter.

+  Support for DevNull Console Out. This console uses memory buffers

+  to represnt the console. It allows a console to start very early and

+  when a new console is added it is synced up with the current console

+

+--*/

+

+

+#include "ConSplitter.h"

+

+static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };

+

+EFI_STATUS

+EFIAPI

+ConSpliterConsoleControlGetMode (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,

+  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,

+  OUT BOOLEAN                         *UgaExists,

+  OUT BOOLEAN                         *StdInLocked

+  )

+/*++

+

+  Routine Description:

+    Return the current video mode information. Also returns info about existence

+    of UGA Draw devices in system, and if the Std In device is locked. All the

+    arguments are optional and only returned if a non NULL pointer is passed in.

+

+  Arguments:

+    This - Protocol instance pointer.

+    Mode        - Are we in text of grahics mode.

+    UgaExists   - TRUE if UGA Spliter has found a UGA device

+    StdInLocked - TRUE if StdIn device is keyboard locked

+

+  Returns:

+    EFI_SUCCESS - Mode information returned.

+    EFI_INVALID_PARAMETER - Invalid parameters.

+

+--*/

+{

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+

+  Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Mode == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Mode = Private->UgaMode;

+

+  if (UgaExists != NULL) {

+    *UgaExists = FALSE;

+    for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

+      if (Private->TextOutList[Index].UgaDraw != NULL) {

+        *UgaExists = TRUE;

+        break;

+      }

+    }

+  }

+

+  if (StdInLocked != NULL) {

+    *StdInLocked = ConSpliterConssoleControlStdInLocked ();

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ConSpliterConsoleControlSetMode (

+  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,

+  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE Mode

+  )

+/*++

+

+  Routine Description:

+    Set the current mode to either text or graphics. Graphics is

+    for Quiet Boot.

+

+  Arguments:

+    This  - Protocol instance pointer.

+    Mode  - Mode to set the 

+

+  Returns:

+    EFI_SUCCESS     - Mode information returned.

+    EFI_INVALID_PARAMETER - Invalid parameter.

+    EFI_UNSUPPORTED - Operation unsupported.

+

+--*/

+{

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  TEXT_OUT_AND_UGA_DATA           *TextAndUga;

+  BOOLEAN                         Supported;

+

+  Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Mode >= EfiConsoleControlScreenMaxValue) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Supported   = FALSE;

+  TextAndUga  = &Private->TextOutList[0];

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndUga++) {

+    if (TextAndUga->UgaDraw != NULL) {

+      Supported = TRUE;

+      break;

+    }

+  }

+

+  if ((!Supported) && (Mode == EfiConsoleControlScreenGraphics)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private->UgaMode  = Mode;

+

+  TextAndUga        = &Private->TextOutList[0];

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndUga++) {

+

+    TextAndUga->TextOutEnabled = TRUE;

+    //

+    // If we are going into Graphics mode disable ConOut to any UGA device

+    //

+    if ((Mode == EfiConsoleControlScreenGraphics) && (TextAndUga->UgaDraw != NULL)) {

+      TextAndUga->TextOutEnabled = FALSE;

+      DevNullUgaSync (Private, TextAndUga->UgaDraw);

+    }

+  }

+

+  if (Mode == EfiConsoleControlScreenText) {

+    DevNullSyncUgaStdOut (Private);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ConSpliterUgaDrawGetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL           *This,

+  OUT UINT32                          *HorizontalResolution,

+  OUT UINT32                          *VerticalResolution,

+  OUT UINT32                          *ColorDepth,

+  OUT UINT32                          *RefreshRate

+  )

+/*++

+

+  Routine Description:

+    Return the current video mode information.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    HorizontalResolution  - Current video horizontal resolution in pixels

+    VerticalResolution    - Current video vertical resolution in pixels

+    ColorDepth            - Current video color depth in bits per pixel

+    RefreshRate           - Current video refresh rate in Hz.

+

+  Returns:

+    EFI_SUCCESS           - Mode information returned.

+    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode () 

+    EFI_INVALID_PARAMETER - One of the input args was NULL.

+

+--*/

+{

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+

+  if (!(HorizontalResolution && VerticalResolution && RefreshRate && ColorDepth)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // retrieve private data

+  //

+  Private               = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  *HorizontalResolution = Private->UgaHorizontalResolution;

+  *VerticalResolution   = Private->UgaVerticalResolution;

+  *ColorDepth           = Private->UgaColorDepth;

+  *RefreshRate          = Private->UgaRefreshRate;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ConSpliterUgaDrawSetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL           *This,

+  IN UINT32                           HorizontalResolution,

+  IN UINT32                           VerticalResolution,

+  IN UINT32                           ColorDepth,

+  IN UINT32                           RefreshRate

+  )

+/*++

+

+  Routine Description:

+    Return the current video mode information.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    HorizontalResolution  - Current video horizontal resolution in pixels

+    VerticalResolution    - Current video vertical resolution in pixels

+    ColorDepth            - Current video color depth in bits per pixel

+    RefreshRate           - Current video refresh rate in Hz.

+

+  Returns:

+    EFI_SUCCESS     - Mode information returned.

+    EFI_NOT_STARTED - Video display is not initialized. Call SetMode () 

+    EFI_OUT_OF_RESOURCES - Out of resources.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+  UINTN                           Size;

+

+  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // UgaDevNullSetMode ()

+  //

+  ReturnStatus = EFI_SUCCESS;

+

+  //

+  // Free the old version

+  //

+  gBS->FreePool (Private->UgaBlt);

+

+  //

+  // Allocate the virtual Blt buffer

+  //

+  Size            = HorizontalResolution * VerticalResolution * sizeof (EFI_UGA_PIXEL);

+  Private->UgaBlt = AllocateZeroPool (Size);

+  if (Private->UgaBlt == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Update the Mode data

+  //

+  Private->UgaHorizontalResolution  = HorizontalResolution;

+  Private->UgaVerticalResolution    = VerticalResolution;

+  Private->UgaColorDepth            = ColorDepth;

+  Private->UgaRefreshRate           = RefreshRate;

+

+  if (Private->UgaMode != EfiConsoleControlScreenGraphics) {

+    return ReturnStatus;

+  }

+  //

+  // return the worst status met

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

+    if (Private->TextOutList[Index].UgaDraw != NULL) {

+      Status = Private->TextOutList[Index].UgaDraw->SetMode (

+                                                      Private->TextOutList[Index].UgaDraw,

+                                                      HorizontalResolution,

+                                                      VerticalResolution,

+                                                      ColorDepth,

+                                                      RefreshRate

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+DevNullUgaBlt (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA                *Private,

+  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION                         BltOperation,

+  IN  UINTN                                         SourceX,

+  IN  UINTN                                         SourceY,

+  IN  UINTN                                         DestinationX,

+  IN  UINTN                                         DestinationY,

+  IN  UINTN                                         Width,

+  IN  UINTN                                         Height,

+  IN  UINTN                                         Delta         OPTIONAL

+  )

+{

+  UINTN         SrcY;

+  UINTN         Index;

+  EFI_UGA_PIXEL *BltPtr;

+  EFI_UGA_PIXEL *ScreenPtr;

+  UINT32        HorizontalResolution;

+  UINT32        VerticalResolution;

+

+  if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Width == 0 || Height == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Delta == 0) {

+    Delta = Width * sizeof (EFI_UGA_PIXEL);

+  }

+

+  HorizontalResolution  = Private->UgaHorizontalResolution;

+  VerticalResolution    = Private->UgaVerticalResolution;

+

+  //

+  // We need to fill the Virtual Screen buffer with the blt data.

+  //

+  if (BltOperation == EfiUgaVideoToBltBuffer) {

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    if ((SourceY + Height) > VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if ((SourceX + Width) > HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    BltPtr    = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));

+    ScreenPtr = &Private->UgaBlt[SourceY * HorizontalResolution + SourceX];

+    while (Height) {

+      CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_UGA_PIXEL));

+      BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltPtr + Delta);

+      ScreenPtr += HorizontalResolution;

+      Height--;

+    }

+  } else {

+    //

+    // BltBuffer to Video: Source is BltBuffer, destination is Video

+    //

+    if (DestinationY + Height > VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (DestinationX + Width > HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    ScreenPtr = &Private->UgaBlt[DestinationY * HorizontalResolution + DestinationX];

+    SrcY      = SourceY;

+    while (Height) {

+      if (BltOperation == EfiUgaVideoFill) {

+        for (Index = 0; Index < Width; Index++) {

+          ScreenPtr[Index] = *BltBuffer;

+        }

+      } else {

+        if (BltOperation == EfiUgaBltBufferToVideo) {

+          BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_UGA_PIXEL));

+        } else {

+          BltPtr = &Private->UgaBlt[SrcY * HorizontalResolution + SourceX];

+        }

+

+        CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_UGA_PIXEL));

+      }

+

+      ScreenPtr += HorizontalResolution;

+      SrcY++;

+      Height--;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+ConSpliterUgaDrawBlt (

+  IN  EFI_UGA_DRAW_PROTOCOL                         *This,

+  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION                         BltOperation,

+  IN  UINTN                                         SourceX,

+  IN  UINTN                                         SourceY,

+  IN  UINTN                                         DestinationX,

+  IN  UINTN                                         DestinationY,

+  IN  UINTN                                         Width,

+  IN  UINTN                                         Height,

+  IN  UINTN                                         Delta         OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    The following table defines actions for BltOperations:

+    EfiUgaVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY) 

+      directly to every pixel of the video display rectangle 

+      (DestinationX, DestinationY) 

+      (DestinationX + Width, DestinationY + Height).

+      Only one pixel will be used from the BltBuffer. Delta is NOT used.

+    EfiUgaVideoToBltBuffer - Read data from the video display rectangle 

+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in 

+      the BltBuffer rectangle (DestinationX, DestinationY ) 

+      (DestinationX + Width, DestinationY + Height). If DestinationX or 

+      DestinationY is not zero then Delta must be set to the length in bytes 

+      of a row in the BltBuffer.

+    EfiUgaBltBufferToVideo - Write data from the  BltBuffer rectangle 

+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the 

+      video display rectangle (DestinationX, DestinationY) 

+      (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is 

+      not zero then Delta must be set to the length in bytes of a row in the 

+      BltBuffer.

+    EfiUgaVideoToVideo - Copy from the video display rectangle 

+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) .

+      to the video display rectangle (DestinationX, DestinationY) 

+      (DestinationX + Width, DestinationY + Height). 

+     The BltBuffer and Delta  are not used in this mode.

+

+  Arguments:

+    This          - Protocol instance pointer.

+    BltBuffer     - Buffer containing data to blit into video buffer. This 

+                    buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)

+    BltOperation  - Operation to perform on BlitBuffer and video memory

+    SourceX       - X coordinate of source for the BltBuffer.

+    SourceY       - Y coordinate of source for the BltBuffer.

+    DestinationX  - X coordinate of destination for the BltBuffer.

+    DestinationY  - Y coordinate of destination for the BltBuffer.

+    Width         - Width of rectangle in BltBuffer in pixels.

+    Height        - Hight of rectangle in BltBuffer in pixels.

+    Delta         -

+  

+  Returns:

+    EFI_SUCCESS           - The Blt operation completed.

+    EFI_INVALID_PARAMETER - BltOperation is not valid.

+    EFI_DEVICE_ERROR      - A hardware error occured writting to the video 

+                             buffer.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+  EFI_STATUS                      ReturnStatus;

+

+  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // Sync up DevNull UGA device

+  //

+  ReturnStatus = DevNullUgaBlt (

+                  Private,

+                  BltBuffer,

+                  BltOperation,

+                  SourceX,

+                  SourceY,

+                  DestinationX,

+                  DestinationY,

+                  Width,

+                  Height,

+                  Delta

+                  );

+  if (Private->UgaMode != EfiConsoleControlScreenGraphics) {

+    return ReturnStatus;

+  }

+  //

+  // return the worst status met

+  //

+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {

+    if (Private->TextOutList[Index].UgaDraw != NULL) {

+      Status = Private->TextOutList[Index].UgaDraw->Blt (

+                                                      Private->TextOutList[Index].UgaDraw,

+                                                      BltBuffer,

+                                                      BltOperation,

+                                                      SourceX,

+                                                      SourceY,

+                                                      DestinationX,

+                                                      DestinationY,

+                                                      Width,

+                                                      Height,

+                                                      Delta

+                                                      );

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      } else if (BltOperation == EfiUgaVideoToBltBuffer) {

+        //

+        // Only need to read the data into buffer one time

+        //

+        return EFI_SUCCESS;

+      }

+    }

+  }

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+DevNullUgaSync (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw

+  )

+{

+  return UgaDraw->Blt (

+                    UgaDraw,

+                    Private->UgaBlt,

+                    EfiUgaBltBufferToVideo,

+                    0,

+                    0,

+                    0,

+                    0,

+                    Private->UgaHorizontalResolution,

+                    Private->UgaVerticalResolution,

+                    Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL)

+                    );

+}

+

+EFI_STATUS

+DevNullTextOutOutputString (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  CHAR16                          *WString

+  )

+/*++

+

+  Routine Description:

+    Write a Unicode string to the output device.

+

+  Arguments:

+    Private - Pointer to the console output splitter's private data. It

+              indicates the calling context.

+    WString - The NULL-terminated Unicode string to be displayed on the output

+              device(s). All output devices must also support the Unicode 

+              drawing defined in this file.

+

+  Returns:

+    EFI_SUCCESS            - The string was output to the device.

+    EFI_DEVICE_ERROR       - The device reported an error while attempting to 

+                              output the text.

+    EFI_UNSUPPORTED        - The output device's mode is not currently in a 

+                              defined text mode.

+    EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the 

+                              characters in the Unicode string could not be 

+                              rendered and were skipped.

+

+--*/

+{

+  UINTN                       SizeScreen;

+  UINTN                       SizeAttribute;

+  UINTN                       Index;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;

+  CHAR16                      *Screen;

+  CHAR16                      *NullScreen;

+  CHAR16                      InsertChar;

+  CHAR16                      TempChar;

+  CHAR16                      *PStr;

+  INT32                       *Attribute;

+  INT32                       *NullAttributes;

+  INT32                       CurrentWidth;

+  UINTN                       LastRow;

+  UINTN                       MaxColumn;

+

+  Mode            = &Private->TextOutMode;

+  NullScreen      = Private->DevNullScreen;

+  NullAttributes  = Private->DevNullAttributes;

+  LastRow         = Private->DevNullRows - 1;

+  MaxColumn       = Private->DevNullColumns;

+

+  if (Mode->Attribute & EFI_WIDE_ATTRIBUTE) {

+    CurrentWidth = 2;

+  } else {

+    CurrentWidth = 1;

+  }

+

+  while (*WString) {

+

+    if (*WString == CHAR_BACKSPACE) {

+      //

+      // If the cursor is at the left edge of the display, then move the cursor

+      // one row up.

+      //

+      if (Mode->CursorColumn == 0 && Mode->CursorRow > 0) {

+        Mode->CursorRow--;

+        Mode->CursorColumn = (INT32) MaxColumn;

+      }

+

+      //

+      // If the cursor is not at the left edge of the display,

+      // then move the cursor left one column.

+      //

+      if (Mode->CursorColumn > 0) {

+        Mode->CursorColumn--;

+        if (Mode->CursorColumn > 0 &&

+            NullAttributes[Mode->CursorRow * MaxColumn + Mode->CursorColumn - 1] & EFI_WIDE_ATTRIBUTE

+            ) {

+          Mode->CursorColumn--;

+

+          //

+          // Insert an extra backspace

+          //

+          InsertChar  = CHAR_BACKSPACE;

+          PStr        = WString + 1;

+          while (*PStr) {

+            TempChar    = *PStr;

+            *PStr       = InsertChar;

+            InsertChar  = TempChar;

+            PStr++;

+          }

+

+          *PStr     = InsertChar;

+          *(++PStr) = 0;

+

+          WString++;

+        }

+      }

+

+      WString++;

+

+    } else if (*WString == CHAR_LINEFEED) {

+      //

+      // If the cursor is at the bottom of the display,

+      // then scroll the display one row, and do not update

+      // the cursor position. Otherwise, move the cursor down one row.

+      //

+      if (Mode->CursorRow == (INT32) (LastRow)) {

+        //

+        // Scroll Screen Up One Row

+        //

+        SizeAttribute = LastRow * MaxColumn;

+        CopyMem (

+          NullAttributes,

+          NullAttributes + MaxColumn,

+          SizeAttribute * sizeof (INT32)

+          );

+

+        //

+        // Each row has an ending CHAR_NULL. So one more character each line

+        // for DevNullScreen than DevNullAttributes

+        //

+        SizeScreen = SizeAttribute + LastRow;

+        CopyMem (

+          NullScreen,

+          NullScreen + (MaxColumn + 1),

+          SizeScreen * sizeof (CHAR16)

+          );

+

+        //

+        // Print Blank Line at last line

+        //

+        Screen    = NullScreen + SizeScreen;

+        Attribute = NullAttributes + SizeAttribute;

+

+        for (Index = 0; Index < MaxColumn; Index++, Screen++, Attribute++) {

+          *Screen     = ' ';

+          *Attribute  = Mode->Attribute;

+        }

+      } else {

+        Mode->CursorRow++;

+      }

+

+      WString++;

+    } else if (*WString == CHAR_CARRIAGE_RETURN) {

+      //

+      // Move the cursor to the beginning of the current row.

+      //

+      Mode->CursorColumn = 0;

+      WString++;

+    } else {

+      //

+      // Print the character at the current cursor position and

+      // move the cursor right one column. If this moves the cursor

+      // past the right edge of the display, then the line should wrap to

+      // the beginning of the next line. This is equivalent to inserting

+      // a CR and an LF. Note that if the cursor is at the bottom of the

+      // display, and the line wraps, then the display will be scrolled

+      // one line.

+      //

+      Index = Mode->CursorRow * MaxColumn + Mode->CursorColumn;

+

+      while (Mode->CursorColumn < (INT32) MaxColumn) {

+        if (*WString == CHAR_NULL) {

+          break;

+        }

+

+        if (*WString == CHAR_BACKSPACE) {

+          break;

+        }

+

+        if (*WString == CHAR_LINEFEED) {

+          break;

+        }

+

+        if (*WString == CHAR_CARRIAGE_RETURN) {

+          break;

+        }

+

+        if (*WString == WIDE_CHAR || *WString == NARROW_CHAR) {

+          CurrentWidth = (*WString == WIDE_CHAR) ? 2 : 1;

+          WString++;

+          continue;

+        }

+

+        if (Mode->CursorColumn + CurrentWidth > (INT32) MaxColumn) {

+          //

+          // If a wide char is at the rightmost column, then move the char

+          // to the beginning of the next row

+          //

+          NullScreen[Index + Mode->CursorRow] = L' ';

+          NullAttributes[Index]               = Mode->Attribute | (UINT32) EFI_WIDE_ATTRIBUTE;

+          Index++;

+          Mode->CursorColumn++;

+        } else {

+          NullScreen[Index + Mode->CursorRow] = *WString;

+          NullAttributes[Index]               = Mode->Attribute;

+          if (CurrentWidth == 1) {

+            NullAttributes[Index] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);

+          } else {

+            NullAttributes[Index] |= (UINT32) EFI_WIDE_ATTRIBUTE;

+            NullAttributes[Index + 1] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);

+          }

+

+          Index += CurrentWidth;

+          WString++;

+          Mode->CursorColumn += CurrentWidth;

+        }

+      }

+      //

+      // At the end of line, output carriage return and line feed

+      //

+      if (Mode->CursorColumn >= (INT32) MaxColumn) {

+        DevNullTextOutOutputString (Private, mCrLfString);

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DevNullTextOutSetMode (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  UINTN                           ModeNumber

+  )

+/*++

+

+  Routine Description:

+    Sets the output device(s) to a specified mode.

+

+  Arguments:

+    Private    - Private data structure pointer.

+    ModeNumber - The mode number to set.

+

+  Returns:

+    EFI_SUCCESS      - The requested text mode was set.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The mode number was not valid.

+    EFI_OUT_OF_RESOURCES - Out of resources.

+

+--*/

+{

+  UINTN                         Size;

+  UINTN                         Row;

+  UINTN                         Column;

+  TEXT_OUT_SPLITTER_QUERY_DATA  *Mode;

+

+  //

+  // No extra check for ModeNumber here, as it has been checked in

+  // ConSplitterTextOutSetMode. And mode 0 should always be supported.

+  //

+  Mode    = &(Private->TextOutQueryData[ModeNumber]);

+  Row     = Mode->Rows;

+  Column  = Mode->Columns;

+

+  if (Row <= 0 && Column <= 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Private->DevNullColumns != Column || Private->DevNullRows != Row) {

+

+    Private->TextOutMode.Mode = (INT32) ModeNumber;

+    Private->DevNullColumns   = Column;

+    Private->DevNullRows      = Row;

+

+    gBS->FreePool (Private->DevNullScreen);

+

+    Size                    = (Row * (Column + 1)) * sizeof (CHAR16);

+    Private->DevNullScreen  = AllocateZeroPool (Size);

+    if (Private->DevNullScreen == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    gBS->FreePool (Private->DevNullAttributes);

+

+    Size                        = Row * Column * sizeof (INT32);

+    Private->DevNullAttributes  = AllocateZeroPool (Size);

+    if (Private->DevNullAttributes == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+

+  DevNullTextOutClearScreen (Private);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DevNullTextOutClearScreen (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private

+  )

+/*++

+

+  Routine Description:

+    Clears the output device(s) display to the currently selected background 

+    color.

+

+  Arguments:

+    Private     - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS      - The operation completed successfully.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The output device is not in a valid text mode.

+

+--*/

+{

+  UINTN   Row;

+  UINTN   Column;

+  CHAR16  *Screen;

+  INT32   *Attributes;

+  INT32   CurrentAttribute;

+

+  //

+  // Clear the DevNull Text Out Buffers.

+  // The screen is filled with spaces.

+  // The attributes are all synced with the current Simple Text Out Attribute

+  //

+  Screen            = Private->DevNullScreen;

+  Attributes        = Private->DevNullAttributes;

+  CurrentAttribute  = Private->TextOutMode.Attribute;

+

+  for (Row = 0; Row < Private->DevNullRows; Row++) {

+    for (Column = 0; Column < Private->DevNullColumns; Column++, Screen++, Attributes++) {

+      *Screen     = ' ';

+      *Attributes = CurrentAttribute;

+    }

+    //

+    // Each line of the screen has a NULL on the end so we must skip over it

+    //

+    Screen++;

+  }

+

+  DevNullTextOutSetCursorPosition (Private, 0, 0);

+

+  return DevNullTextOutEnableCursor (Private, TRUE);

+}

+

+EFI_STATUS

+DevNullTextOutSetCursorPosition (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  UINTN                           Column,

+  IN  UINTN                           Row

+  )

+/*++

+

+  Routine Description:

+    Sets the current coordinates of the cursor position

+

+  Arguments:

+    Private       - Protocol instance pointer.

+    Column, Row - the position to set the cursor to. Must be greater than or

+                  equal to zero and less than the number of columns and rows

+                  by QueryMode ().

+

+  Returns:

+    EFI_SUCCESS      - The operation completed successfully.

+    EFI_DEVICE_ERROR - The device had an error and 

+                       could not complete the request.

+    EFI_UNSUPPORTED - The output device is not in a valid text mode, or the 

+                       cursor position is invalid for the current mode.

+

+--*/

+{

+  //

+  // No need to do extra check here as whether (Column, Row) is valid has

+  // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should

+  // always be supported.

+  //

+  Private->TextOutMode.CursorColumn = (INT32) Column;

+  Private->TextOutMode.CursorRow    = (INT32) Row;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DevNullTextOutEnableCursor (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,

+  IN  BOOLEAN                         Visible

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.EnableCursor().

+    In this driver, the cursor cannot be hidden.        

+  

+  Arguments:

+  

+    Private - Indicates the calling context.

+        

+    Visible - If TRUE, the cursor is set to be visible, If FALSE, the cursor 

+              is set to be invisible.        

+

+  Returns:

+  

+    EFI_SUCCESS - The request is valid.

+       

+               

+--*/

+{

+  Private->TextOutMode.CursorVisible = Visible;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DevNullSyncUgaStdOut (

+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private

+  )

+/*++

+  Routine Description:

+    Take the DevNull TextOut device and update the Simple Text Out on every

+    UGA device. 

+ 

+  Arguments:

+    Private - Indicates the calling context.

+

+  Returns:

+    EFI_SUCCESS - The request is valid.

+    other       - Return status of TextOut->OutputString ()

+               

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_STATUS                    ReturnStatus;

+  UINTN                         Row;

+  UINTN                         Column;

+  UINTN                         List;

+  UINTN                         MaxColumn;

+  UINTN                         CurrentColumn;

+  UINTN                         StartRow;

+  UINTN                         StartColumn;

+  INT32                         StartAttribute;

+  BOOLEAN                       StartCursorState;

+  CHAR16                        *Screen;

+  CHAR16                        *Str;

+  CHAR16                        *Buffer;

+  CHAR16                        *BufferTail;

+  CHAR16                        *ScreenStart;

+  INT32                         CurrentAttribute;

+  INT32                         *Attributes;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *Sto;

+

+  //

+  // Save the devices Attributes, Cursor enable state and location

+  //

+  StartColumn       = Private->TextOutMode.CursorColumn;

+  StartRow          = Private->TextOutMode.CursorRow;

+  StartAttribute    = Private->TextOutMode.Attribute;

+  StartCursorState  = Private->TextOutMode.CursorVisible;

+

+  for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {

+

+    Sto = Private->TextOutList[List].TextOut;

+

+    //

+    // Skip non UGA devices

+    //

+    if (Private->TextOutList[List].UgaDraw != NULL) {

+      Sto->EnableCursor (Sto, FALSE);

+      Sto->ClearScreen (Sto);

+    }

+  }

+

+  ReturnStatus  = EFI_SUCCESS;

+  Screen        = Private->DevNullScreen;

+  Attributes    = Private->DevNullAttributes;

+  MaxColumn     = Private->DevNullColumns;

+

+  Buffer        = AllocateZeroPool ((MaxColumn + 1) * sizeof (CHAR16));

+

+  for (Row = 0; Row < Private->DevNullRows; Row++, Screen += (MaxColumn + 1), Attributes += MaxColumn) {

+

+    if (Row == (Private->DevNullRows - 1)) {

+      //

+      // Don't ever sync the last character as it will scroll the screen

+      //

+      Screen[MaxColumn - 1] = 0x00;

+    }

+

+    Column = 0;

+    while (Column < MaxColumn) {

+      if (Screen[Column]) {

+        CurrentAttribute  = Attributes[Column];

+        CurrentColumn     = Column;

+        ScreenStart       = &Screen[Column];

+

+        //

+        // the line end is alway 0x0. So Column should be less than MaxColumn

+        // It should be still in the same row

+        //

+        for (Str = ScreenStart, BufferTail = Buffer; *Str != 0; Str++, Column++) {

+

+          if (Attributes[Column] != CurrentAttribute) {

+            Column--;

+            break;

+          }

+

+          *BufferTail = *Str;

+          BufferTail++;

+          if (Attributes[Column] & EFI_WIDE_ATTRIBUTE) {

+            Str++;

+            Column++;

+          }

+        }

+

+        *BufferTail = 0;

+

+        for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {

+

+          Sto = Private->TextOutList[List].TextOut;

+

+          //

+          // Skip non UGA devices

+          //

+          if (Private->TextOutList[List].UgaDraw != NULL) {

+            Sto->SetAttribute (Sto, CurrentAttribute);

+            Sto->SetCursorPosition (Sto, CurrentColumn, Row);

+            Status = Sto->OutputString (Sto, Buffer);

+            if (EFI_ERROR (Status)) {

+              ReturnStatus = Status;

+            }

+          }

+        }

+

+      }

+

+      Column++;

+    }

+  }

+  //

+  // Restore the devices Attributes, Cursor enable state and location

+  //

+  for (List = 0; List < Private->CurrentNumberOfConsoles; List++) {

+    Sto = Private->TextOutList[List].TextOut;

+

+    //

+    // Skip non UGA devices

+    //

+    if (Private->TextOutList[List].UgaDraw != NULL) {

+      Sto->SetAttribute (Sto, StartAttribute);

+      Sto->SetCursorPosition (Sto, StartColumn, StartRow);

+      Status = Sto->EnableCursor (Sto, StartCursorState);

+      if (EFI_ERROR (Status)) {

+        ReturnStatus = Status;

+      }

+    }

+  }

+

+  gBS->FreePool (Buffer);

+

+  return ReturnStatus;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/build.xml
new file mode 100644
index 0000000..dc1058a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/ConSplitter/Dxe/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="ConSplitter"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Console/ConSplitter/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="ConSplitter">

+      <GenBuild baseName="ConSplitter" mbdFilename="${MODULE_DIR}/ConSplitter.mbd" msaFilename="${MODULE_DIR}/ConSplitter.msa"/>

+   </target>

+   <target name="ConSplitterLite">

+      <GenBuild baseName="ConSplitterLite" mbdFilename="${MODULE_DIR}/ConSplitterLite.mbd" msaFilename="${MODULE_DIR}/ConSplitterLite.msa"/>

+   </target>

+   <target depends="ConSplitter_clean" name="clean"/>

+   <target depends="ConSplitter_cleanall" name="cleanall"/>

+   <target name="ConSplitter_clean">

+      <OutputDirSetup baseName="ConSplitter" mbdFilename="${MODULE_DIR}/ConSplitter.mbd" msaFilename="${MODULE_DIR}/ConSplitter.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ConSplitter_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ConSplitter_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="ConSplitterLite_clean">

+      <OutputDirSetup baseName="ConSplitterLite" mbdFilename="${MODULE_DIR}/ConSplitterLite.mbd" msaFilename="${MODULE_DIR}/ConSplitterLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ConSplitterLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ConSplitterLite_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="ConSplitter_cleanall">

+      <OutputDirSetup baseName="ConSplitter" mbdFilename="${MODULE_DIR}/ConSplitter.mbd" msaFilename="${MODULE_DIR}/ConSplitter.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ConSplitter_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ConSplitter_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**ConSplitter*"/>

+      </delete>

+   </target>

+   <target name="ConSplitterLite_cleanall">

+      <OutputDirSetup baseName="ConSplitterLite" mbdFilename="${MODULE_DIR}/ConSplitterLite.mbd" msaFilename="${MODULE_DIR}/ConSplitterLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/ConSplitterLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/ConSplitterLite_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**ConSplitterLite*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/ComponentName.c
new file mode 100644
index 0000000..5c615ba
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/ComponentName.c
@@ -0,0 +1,139 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "GraphicsConsole.h"

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gGraphicsConsoleComponentName = {

+  GraphicsConsoleComponentNameGetDriverName,

+  GraphicsConsoleComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mGraphicsConsoleDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *)L"UGA Console Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gGraphicsConsoleComponentName.SupportedLanguages,

+          mGraphicsConsoleDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/ComponentName.h b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/ComponentName.h
new file mode 100644
index 0000000..c5999b6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/ComponentName.h
@@ -0,0 +1,51 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.h

+

+Abstract:

+

+  

+Revision History

+

+--*/

+

+#ifndef _GRAPHICS_CONSOLE_COMPONENT_NAME_H

+#define _GRAPHICS_CONSOLE_COMPONENT_NAME_H

+

+extern EFI_COMPONENT_NAME_PROTOCOL  gGraphicsConsoleComponentName;

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+GraphicsConsoleComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.c b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.c
new file mode 100644
index 0000000..a475723
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.c
@@ -0,0 +1,1566 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GraphicsConsole.c

+  

+Abstract:

+

+  This is the main routine for initializing the Graphics Console support routines.

+

+Revision History

+

+Remaining Tasks

+  Add all standard Glyphs from EFI 1.02 Specification

+  Implement optimal automatic Mode creation algorithm

+  Solve palette issues for mixed graphics and text

+  When does this protocol reset the palette?

+

+--*/

+

+#include "GraphicsConsole.h"

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+GraphicsConsoleControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleControllerDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+EFI_STATUS

+GetTextColors (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  OUT EFI_UGA_PIXEL                 *Foreground,

+  OUT EFI_UGA_PIXEL                 *Background

+  );

+

+EFI_STATUS

+DrawUnicodeWeightAtCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        UnicodeWeight

+  );

+

+EFI_STATUS

+DrawUnicodeWeightAtCursorN (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *UnicodeWeight,

+  IN  UINTN                         Count

+  );

+

+EFI_STATUS

+EraseCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This

+  );

+

+//

+// Globals

+//

+GRAPHICS_CONSOLE_DEV        mGraphicsConsoleDevTemplate = {

+  GRAPHICS_CONSOLE_DEV_SIGNATURE,

+  (EFI_UGA_DRAW_PROTOCOL *) NULL,

+  {

+    GraphicsConsoleConOutReset,

+    GraphicsConsoleConOutOutputString,

+    GraphicsConsoleConOutTestString,

+    GraphicsConsoleConOutQueryMode,

+    GraphicsConsoleConOutSetMode,

+    GraphicsConsoleConOutSetAttribute,

+    GraphicsConsoleConOutClearScreen,

+    GraphicsConsoleConOutSetCursorPosition,

+    GraphicsConsoleConOutEnableCursor,

+    (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL

+  },

+  {

+    0,

+    0,

+    EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),

+    0,

+    0,

+    TRUE

+  },

+  {

+    { 80, 25, 0, 0, 0, 0 },  // Mode 0

+    {  0,  0, 0, 0, 0, 0 },  // Mode 1

+    {  0,  0, 0, 0, 0, 0 }   // Mode 2

+  },

+  (EFI_UGA_PIXEL *) NULL,

+  (EFI_HII_HANDLE) 0

+};

+

+EFI_HII_PROTOCOL            *mHii;

+

+static CHAR16               mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };

+

+static EFI_UGA_PIXEL        mEfiColors[16] = {

+  //

+  // B     G     R

+  //

+  { 0x00, 0x00, 0x00, 0x00 },  // BLACK

+  { 0x98, 0x00, 0x00, 0x00 },  // BLUE

+  { 0x00, 0x98, 0x00, 0x00 },  // GREEN

+  { 0x98, 0x98, 0x00, 0x00 },  // CYAN

+  { 0x00, 0x00, 0x98, 0x00 },  // RED

+  { 0x98, 0x00, 0x98, 0x00 },  // MAGENTA

+  { 0x00, 0x98, 0x98, 0x00 },  // BROWN

+  { 0x98, 0x98, 0x98, 0x00 },  // LIGHTGRAY

+  { 0x30, 0x30, 0x30, 0x00 },  // DARKGRAY - BRIGHT BLACK

+  { 0xff, 0x00, 0x00, 0x00 },  // LIGHTBLUE - ?

+  { 0x00, 0xff, 0x00, 0x00 },  // LIGHTGREEN - ?

+  { 0xff, 0xff, 0x00, 0x00 },  // LIGHTCYAN

+  { 0x00, 0x00, 0xff, 0x00 },  // LIGHTRED

+  { 0xff, 0x00, 0xff, 0x00 },  // LIGHTMAGENTA

+  { 0x00, 0xff, 0xff, 0x00 },  // LIGHTBROWN

+  { 0xff, 0xff, 0xff, 0x00 }   // WHITE

+};

+

+static EFI_NARROW_GLYPH     mCursorGlyph = {

+  0x0000,

+  0x00,

+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }

+};

+

+static CHAR16  SpaceStr[] = { (CHAR16)NARROW_CHAR, ' ', 0 };

+

+

+EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {

+  GraphicsConsoleControllerDriverSupported,

+  GraphicsConsoleControllerDriverStart,

+  GraphicsConsoleControllerDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+{

+  EFI_STATUS                Status;

+  EFI_UGA_DRAW_PROTOCOL     *UgaDraw;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // We need to ensure that we do not layer on top of a virtual handle.

+  // We need to ensure that the handles produced by the conspliter do not

+  // get used.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &DevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+  } else {

+    goto Error;

+  }

+  //

+  // Does Hii Exist?  If not, we aren't ready to run

+  //

+  Status = EfiLocateHiiProtocol ();

+

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+Error:

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiUgaDrawProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+

+    Start the controller.

+

+  Arguments:

+

+    This                - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.

+    Controller          - The handle of the controller to start.

+    RemainingDevicePath - A pointer to the remaining portion of a devcie path.

+

+  Returns:

+

+    EFI_SUCCESS          - Return successfully.

+    EFI_OUT_OF_RESOURCES - Out of resources.

+

+--*/

+{

+  EFI_STATUS            Status;

+  GRAPHICS_CONSOLE_DEV  *Private;

+  EFI_HII_PACKAGES      *Package;

+  EFI_HII_FONT_PACK     *FontPack;

+  UINTN                 NarrowFontSize;

+  UINT32                HorizontalResolution;

+  UINT32                VerticalResolution;

+  UINT32                ColorDepth;

+  UINT32                RefreshRate;

+  UINTN                 MaxMode;

+  UINTN                 Columns;

+  UINTN                 Rows;

+  UINT8                 *Location;

+  //

+  // Initialize the Graphics Console device instance

+  //

+  Private = AllocateCopyPool (

+              sizeof (GRAPHICS_CONSOLE_DEV),

+              &mGraphicsConsoleDevTemplate

+              );

+  if (Private == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &Private->UgaDraw,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+  //

+  // Get the HII protocol. If Supported() succeeds, do we really

+  // need to get HII protocol again?

+  //

+  Status = EfiLocateHiiProtocol ();

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  NarrowFontSize  = ReturnNarrowFontSize ();

+

+  FontPack        = AllocateZeroPool (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);

+  ASSERT (FontPack);

+

+  FontPack->Header.Length         = (UINT32) (sizeof (EFI_HII_FONT_PACK) + NarrowFontSize);

+  FontPack->Header.Type           = EFI_HII_FONT;

+  FontPack->NumberOfNarrowGlyphs  = (UINT16) (NarrowFontSize / sizeof (EFI_NARROW_GLYPH));

+

+  Location                        = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8));

+  CopyMem (Location, UsStdNarrowGlyphData, NarrowFontSize);

+

+  //

+  // Register our Fonts into the global database

+  //

+  Package = PreparePackages (1, NULL, FontPack);

+  mHii->NewPack (mHii, Package, &(Private->HiiHandle));

+  gBS->FreePool (Package);

+

+  //

+  // Free the font database

+  //

+  gBS->FreePool (FontPack);

+

+  //

+  // If the current mode information can not be retrieved, then attemp to set the default mode

+  // of 800x600, 32 bit colot, 60 Hz refresh.

+  //

+  HorizontalResolution  = 800;

+  VerticalResolution    = 600;

+  ColorDepth            = 32;

+  RefreshRate           = 60;

+  Status = Private->UgaDraw->SetMode (

+                              Private->UgaDraw,

+                              HorizontalResolution,

+                              VerticalResolution,

+                              ColorDepth,

+                              RefreshRate

+                              );

+  if (EFI_ERROR (Status)) {

+    //

+    // Get the current mode information from the UGA Draw Protocol

+    //

+    Status = Private->UgaDraw->GetMode (

+                                Private->UgaDraw,

+                                &HorizontalResolution,

+                                &VerticalResolution,

+                                &ColorDepth,

+                                &RefreshRate

+                                );

+    if (EFI_ERROR (Status)) {

+      goto Error;

+    }

+  }

+  //

+  // Compute the maximum number of text Rows and Columns that this current graphics mode can support

+  //

+  Columns = HorizontalResolution / GLYPH_WIDTH;

+  Rows    = VerticalResolution / GLYPH_HEIGHT;

+

+  //

+  // See if the mode is too small to support the required 80x25 text mode

+  //

+  if (Columns < 80 || Rows < 25) {

+    goto Error;

+  }

+  //

+  // Add Mode #0 that must be 80x25

+  //

+  MaxMode = 0;

+  Private->ModeData[MaxMode].UgaWidth   = HorizontalResolution;

+  Private->ModeData[MaxMode].UgaHeight  = VerticalResolution;

+  Private->ModeData[MaxMode].DeltaX     = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;

+  Private->ModeData[MaxMode].DeltaY     = (VerticalResolution - (25 * GLYPH_HEIGHT)) >> 1;

+  MaxMode++;

+

+  //

+  // If it is possible to support Mode #1 - 80x50, than add it as an active mode

+  //

+  if (Rows >= 50) {

+    Private->ModeData[MaxMode].UgaWidth   = HorizontalResolution;

+    Private->ModeData[MaxMode].UgaHeight  = VerticalResolution;

+    Private->ModeData[MaxMode].DeltaX     = (HorizontalResolution - (80 * GLYPH_WIDTH)) >> 1;

+    Private->ModeData[MaxMode].DeltaY     = (VerticalResolution - (50 * GLYPH_HEIGHT)) >> 1;

+    MaxMode++;

+  }

+  //

+  // If the graphics mode is 800x600, than add a text mode that uses the entire display

+  //

+  if (HorizontalResolution == 800 && VerticalResolution == 600) {

+

+    if (MaxMode < 2) {

+      Private->ModeData[MaxMode].Columns    = 0;

+      Private->ModeData[MaxMode].Rows       = 0;

+      Private->ModeData[MaxMode].UgaWidth   = 800;

+      Private->ModeData[MaxMode].UgaHeight  = 600;

+      Private->ModeData[MaxMode].DeltaX     = 0;

+      Private->ModeData[MaxMode].DeltaY     = 0;

+      MaxMode++;

+    }

+

+    Private->ModeData[MaxMode].Columns    = 800 / GLYPH_WIDTH;

+    Private->ModeData[MaxMode].Rows       = 600 / GLYPH_HEIGHT;

+    Private->ModeData[MaxMode].UgaWidth   = 800;

+    Private->ModeData[MaxMode].UgaHeight  = 600;

+    Private->ModeData[MaxMode].DeltaX     = (800 % GLYPH_WIDTH) >> 1;

+    Private->ModeData[MaxMode].DeltaY     = (600 % GLYPH_HEIGHT) >> 1;

+    MaxMode++;

+  }

+  //

+  // Update the maximum number of modes

+  //

+  Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;

+

+  //

+  // Determine the number of text modes that this protocol can support

+  //

+  Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  DEBUG_CODE (

+    GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");

+  );

+

+  //

+  // Install protocol interfaces for the Graphics Console device.

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Controller,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &Private->SimpleTextOutput,

+                  NULL

+                  );

+

+Error:

+  if (EFI_ERROR (Status)) {

+    //

+    // Close the UGA IO Protocol

+    //

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUgaDrawProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    //

+    // Free private data

+    //

+    if (Private != NULL) {

+      gBS->FreePool (Private->LineBuffer);

+      gBS->FreePool (Private);

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleControllerDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *SimpleTextOutput;

+  GRAPHICS_CONSOLE_DEV          *Private;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &SimpleTextOutput,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_STARTED;

+  }

+

+  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);

+

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &Private->SimpleTextOutput

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // Close the UGA IO Protocol

+    //

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiUgaDrawProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    //

+    // Remove the font pack

+    //

+    mHii->RemovePack (mHii, Private->HiiHandle);

+

+    //

+    // Free our instance data

+    //

+    if (Private != NULL) {

+      gBS->FreePool (Private->LineBuffer);

+      gBS->FreePool (Private);

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EfiLocateHiiProtocol (

+  VOID

+  )

+/*++

+

+  Routine Description:

+    Find if the HII protocol is available. If yes, locate the HII protocol

+

+  Arguments:

+

+  Returns:

+

+--*/

+{

+  EFI_HANDLE  Handle;

+  UINTN       Size;

+  EFI_STATUS  Status;

+

+  //

+  // There should only be one - so buffer size is this

+  //

+  Size = sizeof (EFI_HANDLE);

+

+  Status = gBS->LocateHandle (

+                  ByProtocol,

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  &Size,

+                  &Handle

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiHiiProtocolGuid,

+                  (VOID **)&mHii

+                  );

+

+  return Status;

+}

+//

+// Body of the STO functions

+//

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutReset (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  BOOLEAN                       ExtendedVerification

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.Reset().

+    If ExtendeVerification is TRUE, then perform dependent Graphics Console 

+    device reset, and set display mode to mode 0.

+    If ExtendedVerification is FALSE, only set display mode to mode 0.

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    ExtendedVerification - Indicates that the driver may perform a more exhaustive

+                           verification operation of the device during reset.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The reset operation succeeds.   

+    

+    EFI_DEVICE_ERROR

+      The Graphics Console is not functioning correctly 

+                

+--*/

+{

+  This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));

+  return This->SetMode (This, 0);

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutOutputString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.OutputString().

+    The Unicode string will be converted to Glyphs and will be 

+    sent to the Graphics Console.

+    

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    WString - The Null-terminated Unicode string to be displayed on 

+              the Graphics Console.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The string is output successfully.   

+    

+    EFI_DEVICE_ERROR

+      The Graphics Console failed to send the string out.

+      

+    EFI_WARN_UNKNOWN_GLYPH

+      Indicates that some of the characters in the Unicode string could not 

+      be rendered and are skipped.          

+                

+--*/

+{

+  GRAPHICS_CONSOLE_DEV  *Private;

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  INTN                  Mode;

+  UINTN                 MaxColumn;

+  UINTN                 MaxRow;

+  UINTN                 Width;

+  UINTN                 Height;

+  UINTN                 Delta;

+  EFI_STATUS            Status;

+  BOOLEAN               Warning;

+  EFI_UGA_PIXEL         Foreground;

+  EFI_UGA_PIXEL         Background;

+  UINTN                 DeltaX;

+  UINTN                 DeltaY;

+  UINTN                 Count;

+  UINTN                 Index;

+  INT32                 OriginAttribute;

+

+  //

+  // Current mode

+  //

+  Mode      = This->Mode->Mode;

+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+  UgaDraw   = Private->UgaDraw;

+

+  MaxColumn = Private->ModeData[Mode].Columns;

+  MaxRow    = Private->ModeData[Mode].Rows;

+  DeltaX    = Private->ModeData[Mode].DeltaX;

+  DeltaY    = Private->ModeData[Mode].DeltaY;

+  Width     = MaxColumn * GLYPH_WIDTH;

+  Height    = (MaxRow - 1) * GLYPH_HEIGHT;

+  Delta     = Width * sizeof (EFI_UGA_PIXEL);

+

+  //

+  // The Attributes won't change when during the time OutputString is called

+  //

+  GetTextColors (This, &Foreground, &Background);

+

+  EraseCursor (This);

+

+  Warning = FALSE;

+

+  //

+  // Backup attribute

+  //

+  OriginAttribute = This->Mode->Attribute;

+

+  while (*WString) {

+

+    if (*WString == CHAR_BACKSPACE) {

+      //

+      // If the cursor is at the left edge of the display, then move the cursor

+      // one row up.

+      //

+      if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {

+        This->Mode->CursorRow--;

+        This->Mode->CursorColumn = (INT32) (MaxColumn - 1);

+        This->OutputString (This, SpaceStr);

+        EraseCursor (This);

+        This->Mode->CursorRow--;

+        This->Mode->CursorColumn = (INT32) (MaxColumn - 1);

+      } else if (This->Mode->CursorColumn > 0) {

+        //

+        // If the cursor is not at the left edge of the display, then move the cursor

+        // left one column.

+        //

+        This->Mode->CursorColumn--;

+        This->OutputString (This, SpaceStr);

+        EraseCursor (This);

+        This->Mode->CursorColumn--;

+      }

+

+      WString++;

+

+    } else if (*WString == CHAR_LINEFEED) {

+      //

+      // If the cursor is at the bottom of the display, then scroll the display one

+      // row, and do not update the cursor position. Otherwise, move the cursor

+      // down one row.

+      //

+      if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {

+        //

+        // Scroll Screen Up One Row

+        //

+        UgaDraw->Blt (

+                  UgaDraw,

+                  NULL,

+                  EfiUgaVideoToVideo,

+                  DeltaX,

+                  DeltaY + GLYPH_HEIGHT,

+                  DeltaX,

+                  DeltaY,

+                  Width,

+                  Height,

+                  Delta

+                  );

+

+        //

+        // Print Blank Line at last line

+        //

+        UgaDraw->Blt (

+                  UgaDraw,

+                  &Background,

+                  EfiUgaVideoFill,

+                  0,

+                  0,

+                  DeltaX,

+                  DeltaY + Height,

+                  Width,

+                  GLYPH_HEIGHT,

+                  Delta

+                  );

+

+      } else {

+        This->Mode->CursorRow++;

+      }

+

+      WString++;

+

+    } else if (*WString == CHAR_CARRIAGE_RETURN) {

+      //

+      // Move the cursor to the beginning of the current row.

+      //

+      This->Mode->CursorColumn = 0;

+      WString++;

+

+    } else if (*WString == WIDE_CHAR) {

+

+      This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;

+      WString++;

+

+    } else if (*WString == NARROW_CHAR) {

+

+      This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);

+      WString++;

+

+    } else {

+      //

+      // Print the character at the current cursor position and move the cursor

+      // right one column. If this moves the cursor past the right edge of the

+      // display, then the line should wrap to the beginning of the next line. This

+      // is equivalent to inserting a CR and an LF. Note that if the cursor is at the

+      // bottom of the display, and the line wraps, then the display will be scrolled

+      // one line.

+      // If wide char is going to be displayed, need to display one character at a time

+      // Or, need to know the display length of a certain string.

+      //

+      // Index is used to determine how many character width units (wide = 2, narrow = 1)

+      // Count is used to determine how many characters are used regardless of their attributes

+      //

+      for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {

+        if (WString[Count] == CHAR_NULL) {

+          break;

+        }

+

+        if (WString[Count] == CHAR_BACKSPACE) {

+          break;

+        }

+

+        if (WString[Count] == CHAR_LINEFEED) {

+          break;

+        }

+

+        if (WString[Count] == CHAR_CARRIAGE_RETURN) {

+          break;

+        }

+

+        if (WString[Count] == WIDE_CHAR) {

+          break;

+        }

+

+        if (WString[Count] == NARROW_CHAR) {

+          break;

+        }

+        //

+        // Is the wide attribute on?

+        //

+        if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {

+          //

+          // If wide, add one more width unit than normal since we are going to increment at the end of the for loop

+          //

+          Index++;

+          //

+          // This is the end-case where if we are at column 79 and about to print a wide character

+          // We should prevent this from happening because we will wrap inappropriately.  We should

+          // not print this character until the next line.

+          //

+          if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {

+            Index++;

+            break;

+          }

+        }

+      }

+

+      Status = DrawUnicodeWeightAtCursorN (This, WString, Count);

+      if (EFI_ERROR (Status)) {

+        Warning = TRUE;

+      }

+      //

+      // At the end of line, output carriage return and line feed

+      //

+      WString += Count;

+      This->Mode->CursorColumn += (INT32) Index;

+      if (This->Mode->CursorColumn > (INT32) MaxColumn) {

+        This->Mode->CursorColumn -= 2;

+        This->OutputString (This, SpaceStr);

+      }

+

+      if (This->Mode->CursorColumn >= (INT32) MaxColumn) {

+        EraseCursor (This);

+        This->OutputString (This, mCrLfString);

+        EraseCursor (This);

+      }

+    }

+  }

+

+  This->Mode->Attribute = OriginAttribute;

+

+  EraseCursor (This);

+

+  if (Warning) {

+    return EFI_WARN_UNKNOWN_GLYPH;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutTestString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.TestString().

+    If one of the characters in the *Wstring is

+    neither valid valid Unicode drawing characters,

+    not ASCII code, then this function will return

+    EFI_UNSUPPORTED.

+        

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    WString - The Null-terminated Unicode string to be tested.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The Graphics Console is capable of rendering the output string. 

+    

+    EFI_UNSUPPORTED

+      Some of the characters in the Unicode string cannot be rendered.      

+                

+--*/

+{

+  EFI_STATUS            Status;

+  UINT16                GlyphWidth;

+  UINT32                GlyphStatus;

+  UINT16                Count;

+  GRAPHICS_CONSOLE_DEV  *Private;

+  GLYPH_UNION           *Glyph;

+

+  Private     = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+  GlyphStatus = 0;

+  Count       = 0;

+

+  while (WString[Count]) {

+    Status = mHii->GetGlyph (

+                    mHii,

+                    WString,

+                    &Count,

+                    (UINT8 **) &Glyph,

+                    &GlyphWidth,

+                    &GlyphStatus

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutQueryMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber,

+  OUT UINTN                         *Columns,

+  OUT UINTN                         *Rows

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.QueryMode().

+    It returnes information for an available text mode

+    that the Graphics Console supports.

+    In this driver,we only support text mode 80x25, which is

+    defined as mode 0.

+        

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    ModeNumber - The mode number to return information on.

+        

+    Columns - The returned columns of the requested mode.

+        

+    Rows - The returned rows of the requested mode.                

+        

+  Returns:

+  

+    EFI_SUCCESS

+      The requested mode information is returned. 

+    

+    EFI_UNSUPPORTED

+      The mode number is not valid.   

+                

+--*/

+{

+  GRAPHICS_CONSOLE_DEV  *Private;

+

+  if (ModeNumber >= (UINTN) This->Mode->MaxMode) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+

+  *Columns  = Private->ModeData[ModeNumber].Columns;

+  *Rows     = Private->ModeData[ModeNumber].Rows;

+

+  if (*Columns <= 0 && *Rows <= 0) {

+    return EFI_UNSUPPORTED;

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutSetMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.SetMode().

+    Set the Graphics Console to a specified mode.

+    In this driver, we only support mode 0.        

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    ModeNumber - The text mode to set.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The requested text mode is set.

+       

+    EFI_DEVICE_ERROR

+      The requested text mode cannot be set because of Graphics Console device error.

+    

+    EFI_UNSUPPORTED

+      The text mode number is not valid.       

+                

+--*/

+{

+  EFI_STATUS                  Status;

+  GRAPHICS_CONSOLE_DEV        *Private;

+  EFI_UGA_DRAW_PROTOCOL       *UgaDraw;

+  GRAPHICS_CONSOLE_MODE_DATA  *ModeData;

+  EFI_UGA_PIXEL               *NewLineBuffer;

+  UINT32                      HorizontalResolution;

+  UINT32                      VerticalResolution;

+  UINT32                      ColorDepth;

+  UINT32                      RefreshRate;

+

+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+  UgaDraw   = Private->UgaDraw;

+  ModeData  = &(Private->ModeData[ModeNumber]);

+

+  //

+  // Make sure the requested mode number is supported

+  //

+  if (ModeNumber >= (UINTN) This->Mode->MaxMode) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Attempt to allocate a line buffer for the requested mode number

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_UGA_PIXEL) * ModeData->Columns * GLYPH_WIDTH * GLYPH_HEIGHT,

+                  (VOID **) &NewLineBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    //

+    // The new line buffer could not be allocated, so return an error.

+    // No changes to the state of the current console have been made, so the current console is still valid

+    //

+    return Status;

+  }

+  //

+  // If the mode has been set at least one other time, then LineBuffer will not be NULL

+  //

+  if (Private->LineBuffer != NULL) {

+    //

+    // Clear the current text window on the current graphics console

+    //

+    This->ClearScreen (This);

+

+    //

+    // If the new mode is the same as the old mode, then just return EFI_SUCCESS

+    //

+    if ((INT32) ModeNumber == This->Mode->Mode) {

+      gBS->FreePool (NewLineBuffer);

+      return EFI_SUCCESS;

+    }

+    //

+    // Otherwise, the size of the text console and/or the UGA mode will be changed,

+    // so turn off the cursor, and free the LineBuffer for the current mode

+    //

+    This->EnableCursor (This, FALSE);

+

+    gBS->FreePool (Private->LineBuffer);

+  }

+  //

+  // Assign the current line buffer to the newly allocated line buffer

+  //

+  Private->LineBuffer = NewLineBuffer;

+

+  //

+  // Get the current UGA Draw mode information

+  //

+  Status = UgaDraw->GetMode (

+                      UgaDraw,

+                      &HorizontalResolution,

+                      &VerticalResolution,

+                      &ColorDepth,

+                      &RefreshRate

+                      );

+  if (EFI_ERROR (Status) || HorizontalResolution != ModeData->UgaWidth || VerticalResolution != ModeData->UgaHeight) {

+    //

+    // Either no graphics mode is currently set, or it is set to the wrong resolution, so set the new grapghics mode

+    //

+    Status = UgaDraw->SetMode (

+                        UgaDraw,

+                        ModeData->UgaWidth,

+                        ModeData->UgaHeight,

+                        32,

+                        60

+                        );

+    if (EFI_ERROR (Status)) {

+      //

+      // The mode set operation failed

+      //

+      return Status;

+    }

+  } else {

+    //

+    // The current graphics mode is correct, so simply clear the entire display

+    //

+    Status = UgaDraw->Blt (

+                        UgaDraw,

+                        &mEfiColors[0],

+                        EfiUgaVideoFill,

+                        0,

+                        0,

+                        0,

+                        0,

+                        ModeData->UgaWidth,

+                        ModeData->UgaHeight,

+                        0

+                        );

+  }

+  //

+  // The new mode is valid, so commit the mode change

+  //

+  This->Mode->Mode = (INT32) ModeNumber;

+

+  //

+  // Move the text cursor to the upper left hand corner of the displat and enable it

+  //

+  This->SetCursorPosition (This, 0, 0);

+  This->EnableCursor (This, TRUE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutSetAttribute (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Attribute

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.SetAttribute().       

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    Attrubute - The attribute to set. Only bit0..6 are valid, all other bits

+                are undefined and must be zero.

+        

+  Returns:

+  

+    EFI_SUCCESS

+      The requested attribute is set. 

+       

+    EFI_DEVICE_ERROR

+      The requested attribute cannot be set due to Graphics Console port error.

+          

+    EFI_UNSUPPORTED

+      The attribute requested is not defined by EFI spec.   

+                

+--*/

+{

+  if ((Attribute | 0xFF) != 0xFF) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if ((INT32) Attribute == This->Mode->Attribute) {

+    return EFI_SUCCESS;

+  }

+

+  EraseCursor (This);

+

+  This->Mode->Attribute = (INT32) Attribute;

+

+  EraseCursor (This);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutClearScreen (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.ClearScreen().

+    It clears the Graphics Console's display to the 

+    currently selected background color.

+        

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+

+  Returns:

+  

+    EFI_SUCCESS

+      The operation completed successfully.

+       

+    EFI_DEVICE_ERROR

+      The Graphics Console cannot be cleared due to Graphics Console device error.        

+    

+    EFI_UNSUPPORTED

+      The Graphics Console is not in a valid text mode.       

+                

+--*/

+{

+  EFI_STATUS                  Status;

+  GRAPHICS_CONSOLE_DEV        *Private;

+  GRAPHICS_CONSOLE_MODE_DATA  *ModeData;

+  EFI_UGA_DRAW_PROTOCOL       *UgaDraw;

+  EFI_UGA_PIXEL               Foreground;

+  EFI_UGA_PIXEL               Background;

+

+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+  UgaDraw   = Private->UgaDraw;

+  ModeData  = &(Private->ModeData[This->Mode->Mode]);

+

+  GetTextColors (This, &Foreground, &Background);

+

+  Status = UgaDraw->Blt (

+                      UgaDraw,

+                      &Background,

+                      EfiUgaVideoFill,

+                      0,

+                      0,

+                      0,

+                      0,

+                      ModeData->UgaWidth,

+                      ModeData->UgaHeight,

+                      0

+                      );

+

+  This->Mode->CursorColumn  = 0;

+  This->Mode->CursorRow     = 0;

+

+  EraseCursor (This);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutSetCursorPosition (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Column,

+  IN  UINTN                         Row

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().          

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+        

+    Column - The row to set cursor to.

+        

+    Row - The column to set cursor to.                

+

+  Returns:

+  

+    EFI_SUCCESS

+      The operation completed successfully.

+       

+    EFI_DEVICE_ERROR

+      The request fails due to Graphics Console device error.        

+    

+    EFI_UNSUPPORTED

+      The Graphics Console is not in a valid text mode, or the cursor position

+      is invalid for current mode.     

+                

+--*/

+{

+  GRAPHICS_CONSOLE_DEV        *Private;

+  GRAPHICS_CONSOLE_MODE_DATA  *ModeData;

+

+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+  ModeData  = &(Private->ModeData[This->Mode->Mode]);

+

+  if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (((INT32) Column == This->Mode->CursorColumn) && ((INT32) Row == This->Mode->CursorRow)) {

+    return EFI_SUCCESS;

+  }

+

+  EraseCursor (This);

+

+  This->Mode->CursorColumn  = (INT32) Column;

+  This->Mode->CursorRow     = (INT32) Row;

+

+  EraseCursor (This);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutEnableCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  BOOLEAN                       Visible

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.EnableCursor().

+    In this driver, the cursor cannot be hidden.        

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+        

+    Visible - If TRUE, the cursor is set to be visible,

+              If FALSE, the cursor is set to be invisible.        

+

+  Returns:

+  

+    EFI_SUCCESS

+      The request is valid.

+       

+    EFI_UNSUPPORTED

+      The Graphics Console does not support a hidden cursor.   

+                

+--*/

+{

+  EraseCursor (This);

+

+  This->Mode->CursorVisible = Visible;

+

+  EraseCursor (This);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetTextColors (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  OUT EFI_UGA_PIXEL                 *Foreground,

+  OUT EFI_UGA_PIXEL                 *Background

+  )

+{

+  INTN  Attribute;

+

+  Attribute   = This->Mode->Attribute & 0x7F;

+

+  *Foreground = mEfiColors[Attribute & 0x0f];

+  *Background = mEfiColors[Attribute >> 4];

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DrawUnicodeWeightAtCursorN (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *UnicodeWeight,

+  IN  UINTN                         Count

+  )

+{

+  GRAPHICS_CONSOLE_DEV  *Private;

+  EFI_STATUS            Status;

+  EFI_STATUS            ReturnStatus;

+  GLYPH_UNION           *Glyph;

+  GLYPH_UNION           GlyphData;

+  INTN                  GlyphX;

+  INTN                  GlyphY;

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  EFI_UGA_PIXEL         Foreground;

+  EFI_UGA_PIXEL         Background;

+  UINTN                 Index;

+  UINTN                 ArrayIndex;

+  UINTN                 Counts;

+  UINT16                GlyphWidth;

+  UINT32                GlyphStatus;

+

+  Private       = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+

+  ReturnStatus  = EFI_SUCCESS;

+  GlyphStatus   = 0;

+  GlyphWidth    = 0x08;

+

+  GetTextColors (This, &Foreground, &Background);

+

+  Index       = 0;

+  ArrayIndex  = 0;

+  while (Index < Count) {

+    if (This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) {

+      GlyphStatus = WIDE_CHAR;

+    } else {

+      GlyphStatus = NARROW_CHAR;

+    }

+

+    Status = mHii->GetGlyph (

+                    mHii,

+                    UnicodeWeight,

+                    (UINT16 *) &Index,

+                    (UINT8 **) &Glyph,

+                    &GlyphWidth,

+                    &GlyphStatus

+                    );

+    if (EFI_ERROR (Status)) {

+      ReturnStatus = Status;

+    }

+

+    Counts = 0;

+

+    CopyMem (&GlyphData, Glyph, sizeof (GLYPH_UNION));

+

+    do {

+      //

+      // We are creating the second half of the wide character's BLT buffer

+      //

+      if (GlyphWidth == 0x10 && Counts == 1) {

+        CopyMem (&GlyphData.NarrowGlyph.GlyphCol1, &Glyph->WideGlyph.GlyphCol2, sizeof (Glyph->WideGlyph.GlyphCol2));

+      }

+

+      Counts++;

+

+      if (GlyphWidth == 0x10) {

+        mHii->GlyphToBlt (

+                mHii,

+                (UINT8 *) &GlyphData,

+                Foreground,

+                Background,

+                Count * 2,

+                GLYPH_WIDTH,

+                GLYPH_HEIGHT,

+                &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]

+                );

+      } else {

+        mHii->GlyphToBlt (

+                mHii,

+                (UINT8 *) &GlyphData,

+                Foreground,

+                Background,

+                Count,

+                GLYPH_WIDTH,

+                GLYPH_HEIGHT,

+                &Private->LineBuffer[ArrayIndex * GLYPH_WIDTH]

+                );

+      }

+

+      ArrayIndex++;

+

+    } while (Counts < 2 && GlyphWidth == 0x10);

+

+  }

+  //

+  // If we are printing Wide characters, treat the BLT as if it is twice as many characters

+  //

+  if (GlyphWidth == 0x10) {

+    Count = Count * 2;

+  }

+  //

+  // Blt a character to the screen

+  //

+  GlyphX  = This->Mode->CursorColumn * GLYPH_WIDTH;

+  GlyphY  = This->Mode->CursorRow * GLYPH_HEIGHT;

+  UgaDraw = Private->UgaDraw;

+  UgaDraw->Blt (

+            UgaDraw,

+            Private->LineBuffer,

+            EfiUgaBltBufferToVideo,

+            0,

+            0,

+            GlyphX + Private->ModeData[This->Mode->Mode].DeltaX,

+            GlyphY + Private->ModeData[This->Mode->Mode].DeltaY,

+            GLYPH_WIDTH * Count,

+            GLYPH_HEIGHT,

+            GLYPH_WIDTH * Count * sizeof (EFI_UGA_PIXEL)

+            );

+

+  return ReturnStatus;

+}

+

+EFI_STATUS

+EraseCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This

+  )

+{

+  GRAPHICS_CONSOLE_DEV        *Private;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE *CurrentMode;

+  INTN                        GlyphX;

+  INTN                        GlyphY;

+  EFI_UGA_DRAW_PROTOCOL       *UgaDraw;

+  EFI_UGA_PIXEL_UNION         Foreground;

+  EFI_UGA_PIXEL_UNION         Background;

+  EFI_UGA_PIXEL_UNION         BltChar[GLYPH_HEIGHT][GLYPH_WIDTH];

+  UINTN                       X;

+  UINTN                       Y;

+

+  CurrentMode = This->Mode;

+

+  if (!CurrentMode->CursorVisible) {

+    return EFI_SUCCESS;

+  }

+

+  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);

+  UgaDraw = Private->UgaDraw;

+

+  //

+  // BUGBUG - we need to think about what to do with wide and narrow character deletions.

+  //

+  //

+  // Blt a character to the screen

+  //

+  GlyphX  = (CurrentMode->CursorColumn * GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;

+  GlyphY  = (CurrentMode->CursorRow * GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;

+  UgaDraw->Blt (

+            UgaDraw,

+            (EFI_UGA_PIXEL *) BltChar,

+            EfiUgaVideoToBltBuffer,

+            GlyphX,

+            GlyphY,

+            0,

+            0,

+            GLYPH_WIDTH,

+            GLYPH_HEIGHT,

+            GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)

+            );

+

+  GetTextColors (This, &Foreground.Pixel, &Background.Pixel);

+

+  //

+  // Convert Monochrome bitmap of the Glyph to BltBuffer structure

+  //

+  for (Y = 0; Y < GLYPH_HEIGHT; Y++) {

+    for (X = 0; X < GLYPH_WIDTH; X++) {

+      if ((mCursorGlyph.GlyphCol1[Y] & (1 << X)) != 0) {

+        BltChar[Y][GLYPH_WIDTH - X - 1].Raw ^= Foreground.Raw;

+      }

+    }

+  }

+

+  UgaDraw->Blt (

+            UgaDraw,

+            (EFI_UGA_PIXEL *) BltChar,

+            EfiUgaBltBufferToVideo,

+            0,

+            0,

+            GlyphX,

+            GlyphY,

+            GLYPH_WIDTH,

+            GLYPH_HEIGHT,

+            GLYPH_WIDTH * sizeof (EFI_UGA_PIXEL)

+            );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.h b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.h
new file mode 100644
index 0000000..cfbbbb2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.h
@@ -0,0 +1,160 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GraphicsConsole.h

+

+Abstract:

+

+  

+Revision History

+

+--*/

+

+#ifndef _GRAPHICS_CONSOLE_H

+#define _GRAPHICS_CONSOLE_H

+

+

+#include "ComponentName.h"

+

+//

+// Glyph database

+//

+#define GLYPH_WIDTH   8

+#define GLYPH_HEIGHT  19

+

+typedef union {

+  EFI_NARROW_GLYPH  NarrowGlyph;

+  EFI_WIDE_GLYPH    WideGlyph;

+} GLYPH_UNION;

+

+extern EFI_NARROW_GLYPH UsStdNarrowGlyphData[];

+extern EFI_WIDE_GLYPH   UsStdWideGlyphData[];

+

+//

+// Device Structure

+//

+#define GRAPHICS_CONSOLE_DEV_SIGNATURE  EFI_SIGNATURE_32 ('g', 's', 't', 'o')

+

+typedef struct {

+  UINTN   Columns;

+  UINTN   Rows;

+  INTN    DeltaX;

+  INTN    DeltaY;

+  UINT32  UgaWidth;

+  UINT32  UgaHeight;

+} GRAPHICS_CONSOLE_MODE_DATA;

+

+#define GRAPHICS_MAX_MODE 3

+

+typedef struct {

+  UINTN                         Signature;

+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  SimpleTextOutput;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE   SimpleTextOutputMode;

+  GRAPHICS_CONSOLE_MODE_DATA    ModeData[GRAPHICS_MAX_MODE];

+  EFI_UGA_PIXEL                 *LineBuffer;

+  EFI_HII_HANDLE                HiiHandle;

+} GRAPHICS_CONSOLE_DEV;

+

+#define GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS(a) \

+  CR (a, GRAPHICS_CONSOLE_DEV, SimpleTextOutput, GRAPHICS_CONSOLE_DEV_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gGraphicsConsoleDriverBinding;

+

+//

+// Prototypes

+//

+UINTN

+ReturnNarrowFontSize (

+  VOID

+  );

+

+UINTN

+ReturnWideFontSize (

+  VOID

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutReset (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  BOOLEAN                         ExtendedVerification

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutOutputString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutTestString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutQueryMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber,

+  OUT UINTN                         *Columns,

+  OUT UINTN                         *Rows

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutSetMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutSetAttribute (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Attribute

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutClearScreen (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutSetCursorPosition (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Column,

+  IN  UINTN                         Row

+  );

+

+EFI_STATUS

+EFIAPI

+GraphicsConsoleConOutEnableCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  BOOLEAN                       Visible

+  );

+

+EFI_STATUS

+EfiLocateHiiProtocol (

+  VOID

+  );

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.mbd b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.mbd
new file mode 100644
index 0000000..4b240ac
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>GraphicsConsole</BaseName>

+    <Guid>CCCB0C28-4B24-11d5-9A5A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>HiiLib</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.msa b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.msa
new file mode 100644
index 0000000..ce61cd6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/GraphicsConsole.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>GraphicsConsole</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>CCCB0C28-4B24-11d5-9A5A-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for GraphicsConsole module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>GraphicsConsole.h</Filename>

+    <Filename>GraphicsConsole.c</Filename>

+    <Filename>LaffStd.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">UgaDraw</Protocol>

+    <Protocol Usage="TO_START">Hii</Protocol>

+    <Protocol Usage="BY_START">SimpleTextOut</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gGraphicsConsoleDriverBinding</DriverBinding>

+      <ComponentName>gGraphicsConsoleComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/LaffStd.c b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/LaffStd.c
new file mode 100644
index 0000000..ac8dd16
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/LaffStd.c
@@ -0,0 +1,290 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  LaffStd.c

+

+Abstract:

+

+  

+Revision History

+

+--*/

+

+#include "GraphicsConsole.h"

+

+EFI_NARROW_GLYPH  UsStdNarrowGlyphData[] = {

+  //

+  // Unicode glyphs from 0x20 to 0x7e are the same as ASCII characters 0x20 to 0x7e

+  //

+  { 0x0020, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x0021, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x0022, 0x00, {0x00,0x00,0x00,0x6C,0x6C,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x0023, 0x00, {0x00,0x00,0x00,0x00,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00}},

+  { 0x0024, 0x00, {0x00,0x00,0x18,0x18,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00}},

+  { 0x0025, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x60,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x0026, 0x00, {0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x76,0xDC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x0027, 0x00, {0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x0028, 0x00, {0x00,0x00,0x00,0x06,0x0C,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00}},

+  { 0x0029, 0x00, {0x00,0x00,0x00,0xC0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0x60,0xC0,0x00,0x00,0x00,0x00}},

+  { 0x002a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x38,0xFE,0x38,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x002b, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x002c, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00}},

+  { 0x002d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x002e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},

+  { 0x002f, 0x00, {0x00,0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x60,0xC0,0xC0,0x00,0x00,0x00,0x00}},

+  { 0x0030, 0x00, {0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00}},

+  { 0x0031, 0x00, {0x00,0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}},

+  { 0x0032, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC2,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x0033, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x3C,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0034, 0x00, {0x00,0x00,0x00,0x1C,0x1C,0x3C,0x3C,0x6C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}},

+  { 0x0035, 0x00, {0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0036, 0x00, {0x00,0x00,0x00,0x3C,0x60,0xC0,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0037, 0x00, {0x00,0x00,0x00,0xFE,0xC6,0x06,0x06,0x06,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x0038, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0039, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00}},

+  { 0x003a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},

+  { 0x003b, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00}},

+  { 0x003c, 0x00, {0x00,0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}},

+  { 0x003d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x003e, 0x00, {0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,0x00,0x00,0x00}},

+  { 0x003f, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x0040, 0x00, {0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0xC0,0x7E,0x00,0x00,0x00,0x00}},

+

+  { 0x0041, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+

+  { 0x0042, 0x00, {0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00}},

+  { 0x0043, 0x00, {0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x0044, 0x00, {0x00,0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00}},

+  { 0x0045, 0x00, {0x00,0x00,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x0046, 0x00, {0x00,0x00,0x00,0xFE,0x66,0x62,0x60,0x64,0x7C,0x64,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}},

+  { 0x0047, 0x00, {0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xDE,0xC6,0xC6,0xC6,0x66,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x0048, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x0049, 0x00, {0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xFC,0x00,0x00,0x00,0x00}},

+  { 0x004a, 0x00, {0x00,0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00}},

+  { 0x004b, 0x00, {0x00,0x00,0x00,0xE6,0x66,0x6C,0x6C,0x78,0x70,0x78,0x6C,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}},

+  { 0x004c, 0x00, {0x00,0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x004d, 0x00, {0x00,0x00,0x00,0xC6,0xEE,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x004e, 0x00, {0x00,0x00,0x00,0xC6,0xE6,0xF6,0xF6,0xF6,0xDE,0xCE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x004f, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0050, 0x00, {0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}},

+  { 0x0051, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0x7C,0x1C,0x0E,0x00,0x00}},

+  { 0x0052, 0x00, {0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x78,0x6C,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}},

+  { 0x0053, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x60,0x38,0x0C,0x06,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0054, 0x00, {0x00,0x00,0x00,0xFC,0xFC,0xB4,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}},

+  { 0x0055, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0056, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00}},

+  { 0x0057, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00}},

+  { 0x0058, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0xC6,0x6C,0x6C,0x38,0x6C,0x6C,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x0059, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}},

+  { 0x005a, 0x00, {0x00,0x00,0x00,0xFE,0xC6,0x86,0x0C,0x0C,0x18,0x30,0x60,0xC0,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x005b, 0x00, {0x00,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1E,0x00,0x00,0x00,0x00}},

+  { 0x005c, 0x00, {0x00,0x00,0x00,0xC0,0xC0,0x60,0x60,0x30,0x30,0x18,0x18,0x0C,0x0C,0x06,0x06,0x00,0x00,0x00,0x00}},

+  { 0x005d, 0x00, {0x00,0x00,0x00,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0x00,0x00,0x00,0x00}},

+  { 0x005e, 0x00, {0x00,0x00,0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x005f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x0060, 0x00, {0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x0061, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x0062, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0063, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0064, 0x00, {0x00,0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0xCC,0x7E,0x00,0x00,0x00,0x00}},

+  { 0x0065, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0066, 0x00, {0x00,0x00,0x00,0x1E,0x33,0x30,0x30,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}},

+  { 0x0067, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00}},

+  { 0x0068, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}},

+  { 0x0069, 0x00, {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x006a, 0x00, {0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x6C,0x38,0x00}},

+  { 0x006b, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x70,0x78,0x6C,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00}},

+  { 0x006c, 0x00, {0x00,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x006d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0xEE,0xFE,0xD6,0xD6,0xD6,0xD6,0xD6,0x00,0x00,0x00,0x00}},

+  { 0x006e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00}},

+  { 0x006f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0070, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00}},

+  { 0x0071, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00}},

+  { 0x0072, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}},

+  { 0x0073, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0x7C,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x0074, 0x00, {0x00,0x00,0x00,0x10,0x30,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00}},

+  { 0x0075, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x0076, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00,0x00}},

+  { 0x0077, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00}},

+  { 0x0078, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x0079, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00}},

+  { 0x007a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x86,0x0C,0x18,0x30,0x60,0xC0,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x007b, 0x00, {0x00,0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x30,0x18,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}},

+  { 0x007c, 0x00, {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x007d, 0x00, {0x00,0x00,0x00,0xE0,0x30,0x30,0x30,0x30,0x18,0x30,0x30,0x30,0x30,0x30,0xE0,0x00,0x00,0x00,0x00}},

+  { 0x007e, 0x00, {0x00,0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+

+  { 0x00a0, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00a1, 0x00, {0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00}},

+  { 0x00a2, 0x00, {0x00,0x00,0x00,0x00,0x18,0x18,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x00a3, 0x00, {0x00,0x00,0x00,0x38,0x6C,0x64,0x60,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00}},

+  { 0x00a4, 0x00, {0x00,0x00,0x18,0x00,0x00,0x00,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00a5, 0x00, {0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x00a6, 0x00, {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00}},

+  { 0x00a7, 0x00, {0x00,0x00,0x18,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00a8, 0x00, {0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00a9, 0x00, {0x00,0x00,0x00,0x00,0x7C,0x82,0x9A,0xA2,0xA2,0xA2,0x9A,0x82,0x7C,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00aa, 0x00, {0x00,0x00,0x00,0x00,0x3C,0x6C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00ab, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00ac, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00ad, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00ae, 0x00, {0x00,0x00,0x00,0x00,0x7C,0x82,0xB2,0xAA,0xAA,0xB2,0xAA,0xAA,0x82,0x7C,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00af, 0x00, {0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b0, 0x00, {0x00,0x00,0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b1, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b2, 0x00, {0x00,0x00,0x00,0x3C,0x66,0x0C,0x18,0x32,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b3, 0x00, {0x00,0x00,0x00,0x7C,0x06,0x3C,0x06,0x06,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b4, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b5, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00}},

+  { 0x00b6, 0x00, {0x00,0x00,0x00,0x7F,0xDB,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00}},

+  { 0x00b7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00b8, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0x78,0x00,0x00,0x00}},

+  { 0x00b9, 0x00, {0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00ba, 0x00, {0x00,0x00,0x00,0x00,0x38,0x6C,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00bb, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00bc, 0x00, {0x00,0x00,0x00,0x60,0xE0,0x62,0x66,0x6C,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x06,0x00,0x00,0x00}},

+  { 0x00bd, 0x00, {0x00,0x00,0x00,0x60,0xE0,0x62,0x66,0x6C,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00,0x00}},

+  { 0x00be, 0x00, {0x00,0x00,0x00,0xE0,0x30,0x62,0x36,0xEC,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x06,0x00,0x00,0x00}},

+  { 0x00bf, 0x00, {0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00c0, 0x00, {0x60,0x30,0x18,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00c1, 0x00, {0x18,0x30,0x60,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00c2, 0x00, {0x10,0x38,0x6C,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00c3, 0x00, {0x76,0xDC,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00c4, 0x00, {0xCC,0xCC,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00c5, 0x00, {0x38,0x6C,0x38,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00c6, 0x00, {0x00,0x00,0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00}},

+  { 0x00c7, 0x00, {0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x18,0x70,0x00,0x00}},

+  { 0x00c8, 0x00, {0x60,0x30,0x18,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x00c9, 0x00, {0x18,0x30,0x60,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x00ca, 0x00, {0x10,0x38,0x6C,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x00cb, 0x00, {0xCC,0xCC,0x00,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}},

+  { 0x00cc, 0x00, {0x60,0x30,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00cd, 0x00, {0x18,0x30,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00ce, 0x00, {0x10,0x38,0x6C,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00cf, 0x00, {0xCC,0xCC,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00d0, 0x00, {0x00,0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0xF6,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00}},

+  { 0x00d1, 0x00, {0x76,0xDC,0x00,0x00,0xC6,0xE6,0xE6,0xF6,0xF6,0xDE,0xDE,0xCE,0xCE,0xC6,0xC6,0x00,0x00,0x00,0x00}},

+  { 0x00d2, 0x00, {0x60,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00d3, 0x00, {0x18,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00d4, 0x00, {0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00d5, 0x00, {0x76,0xDC,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00d6, 0x00, {0xCC,0xCC,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00d7, 0x00, {0x10,0x28,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00d8, 0x00, {0x00,0x00,0x00,0x7C,0xCE,0xCE,0xDE,0xD6,0xD6,0xD6,0xD6,0xF6,0xE6,0xE6,0x7C,0x40,0x00,0x00,0x00}},

+  { 0x00d9, 0x00, {0x60,0x30,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00da, 0x00, {0x18,0x30,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00db, 0x00, {0x10,0x38,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00dc, 0x00, {0xCC,0xCC,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00dd, 0x00, {0x18,0x30,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00de, 0x00, {0x00,0x00,0x10,0x00,0xF0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x00,0x00}},

+  { 0x00df, 0x00, {0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0xCC,0xD8,0xCC,0xC6,0xC6,0xC6,0xC6,0xCC,0x00,0x00,0x00,0x00}},

+  { 0x00e0, 0x00, {0x00,0x30,0x30,0x60,0x30,0x18,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00e1, 0x00, {0x00,0x00,0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00e2, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00e3, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00e4, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00e5, 0x00, {0x00,0x00,0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00e6, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0x36,0x36,0x7E,0xD8,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00}},

+  { 0x00e7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x70,0x00,0x00}},

+  { 0x00e8, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00e9, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00ea, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00eb, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00ec, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00ed, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00ee, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00ef, 0x00, {0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00f0, 0x00, {0x00,0x00,0x00,0x34,0x18,0x2C,0x0C,0x06,0x3E,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}},

+  { 0x00f1, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00}},

+  { 0x00f2, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00f3, 0x00, {0x00,0x00,0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00f4, 0x00, {0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00f5, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00f6, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00f7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { 0x00f8, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xCE,0xDE,0xD6,0xF6,0xE6,0xC6,0x7C,0x00,0x00,0x00,0x00}},

+  { 0x00f9, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00fa, 0x00, {0x00,0x00,0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00fb, 0x00, {0x00,0x00,0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00fc, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}},

+  { 0x00fd, 0x00, {0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00}},

+  { 0x00fe, 0x00, {0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00}},

+  { 0x00ff, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00}},

+

+  { (CHAR16)BOXDRAW_HORIZONTAL,                 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_VERTICAL,                   0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOWN_RIGHT,                 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOWN_LEFT,                  0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_UP_RIGHT,                   0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_UP_LEFT,                    0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_VERTICAL_RIGHT,             0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_VERTICAL_LEFT,              0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOWN_HORIZONTAL,            0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_UP_HORIZONTAL,              0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_VERTICAL_HORIZONTAL,        0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOUBLE_HORIZONTAL,          0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_DOUBLE_VERTICAL,            0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOWN_RIGHT_DOUBLE,          0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOWN_DOUBLE_RIGHT,          0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOUBLE_DOWN_RIGHT,          0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOWN_LEFT_DOUBLE,           0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOWN_DOUBLE_LEFT,           0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOUBLE_DOWN_LEFT,           0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_UP_RIGHT_DOUBLE,            0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_UP_DOUBLE_RIGHT,            0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_DOUBLE_UP_RIGHT,            0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_UP_LEFT_DOUBLE,             0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_UP_DOUBLE_LEFT,             0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_DOUBLE_UP_LEFT,             0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_VERTICAL_RIGHT_DOUBLE,      0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_VERTICAL_DOUBLE_RIGHT,      0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOUBLE_VERTICAL_RIGHT,      0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_VERTICAL_LEFT_DOUBLE,       0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_VERTICAL_DOUBLE_LEFT,       0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOUBLE_VERTICAL_LEFT,       0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOWN_HORIZONTAL_DOUBLE,     0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_DOWN_DOUBLE_HORIZONTAL,     0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOUBLE_DOWN_HORIZONTAL,     0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_UP_HORIZONTAL_DOUBLE,       0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_UP_DOUBLE_HORIZONTAL,       0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_DOUBLE_UP_HORIZONTAL,       0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},

+  { (CHAR16)BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+  { (CHAR16)BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},

+

+  { (CHAR16)BLOCKELEMENT_FULL_BLOCK,            0x00, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},

+  { (CHAR16)BLOCKELEMENT_LIGHT_SHADE,           0x00, {0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22}},

+

+  { (CHAR16)GEOMETRICSHAPE_RIGHT_TRIANGLE,      0x00, {0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)GEOMETRICSHAPE_LEFT_TRIANGLE,       0x00, {0x00,0x00,0x00,0x00,0x00,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)GEOMETRICSHAPE_UP_TRIANGLE,         0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)GEOMETRICSHAPE_DOWN_TRIANGLE,       0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00}},

+

+  { (CHAR16)ARROW_UP,                           0x00, {0x00,0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)ARROW_DOWN,                         0x00, {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)ARROW_LEFT,                         0x00, {0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x60,0xFE,0xFE,0x60,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00}},

+  { (CHAR16)ARROW_RIGHT,                        0x00, {0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0C,0xFE,0xFE,0x0C,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00}},

+

+  { 0x0000, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} //EOL

+};

+

+UINTN

+ReturnNarrowFontSize (

+  VOID

+  )

+{

+  //

+  // I need the size of this outside of this file, so here is a stub function to do that for me

+  //

+  return sizeof (UsStdNarrowGlyphData);

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/build.xml
new file mode 100644
index 0000000..852b17b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/GraphicsConsole/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="GraphicsConsole"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Console/GraphicsConsole/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="GraphicsConsole">

+      <GenBuild baseName="GraphicsConsole" mbdFilename="${MODULE_DIR}/GraphicsConsole.mbd" msaFilename="${MODULE_DIR}/GraphicsConsole.msa"/>

+   </target>

+   <target depends="GraphicsConsole_clean" name="clean"/>

+   <target depends="GraphicsConsole_cleanall" name="cleanall"/>

+   <target name="GraphicsConsole_clean">

+      <OutputDirSetup baseName="GraphicsConsole" mbdFilename="${MODULE_DIR}/GraphicsConsole.mbd" msaFilename="${MODULE_DIR}/GraphicsConsole.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/GraphicsConsole_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/GraphicsConsole_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="GraphicsConsole_cleanall">

+      <OutputDirSetup baseName="GraphicsConsole" mbdFilename="${MODULE_DIR}/GraphicsConsole.mbd" msaFilename="${MODULE_DIR}/GraphicsConsole.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/GraphicsConsole_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/GraphicsConsole_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**GraphicsConsole*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/ComponentName.c
new file mode 100644
index 0000000..cc925b1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/ComponentName.c
@@ -0,0 +1,194 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+

+#include "Terminal.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+TerminalComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+TerminalComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gTerminalComponentName = {

+  TerminalComponentNameGetDriverName,

+  TerminalComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mTerminalDriverNameTable[] = {

+  {

+    "eng",

+   (CHAR16 *) L"Serial Terminal Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+TerminalComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gTerminalComponentName.SupportedLanguages,

+          mTerminalDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+TerminalComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *SimpleTextOutput;

+  TERMINAL_DEV                  *TerminalDevice;

+

+  //

+  // This is a bus driver, so ChildHandle can not be NULL.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ChildHandle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &SimpleTextOutput,

+                  gTerminalDriverBinding.DriverBindingHandle,

+                  ChildHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);

+

+  return LookupUnicodeString (

+          Language,

+          gTerminalComponentName.SupportedLanguages,

+          TerminalDevice->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.c b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.c
new file mode 100644
index 0000000..d462e05
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.c
@@ -0,0 +1,1214 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    Terminal.c

+    

+Abstract: 

+

+Revision History:

+

+--*/

+

+

+#include "Terminal.h"

+#include <Common/StatusCode.h>

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+TerminalDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+TerminalDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+TerminalDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+//

+// Globals

+//

+EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding = {

+  TerminalDriverBindingSupported,

+  TerminalDriverBindingStart,

+  TerminalDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+

+EFI_STATUS

+EFIAPI

+TerminalDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+  EFI_SERIAL_IO_PROTOCOL    *SerialIo;

+  VENDOR_DEVICE_PATH        *Node;

+

+  //

+  // If remaining device path is not NULL, then make sure it is a

+  // device path that describes a terminal communications protocol.

+  //

+  if (RemainingDevicePath != NULL) {

+

+    Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;

+

+    if (Node->Header.Type != MESSAGING_DEVICE_PATH ||

+        Node->Header.SubType != MSG_VENDOR_DP ||

+        DevicePathNodeLength(&Node->Header) != sizeof(VENDOR_DEVICE_PATH)) {

+

+      return EFI_UNSUPPORTED;

+

+    }

+    //

+    // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types

+    //

+    if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&

+        !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&

+        !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&

+        !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {

+

+      return EFI_UNSUPPORTED;

+    }

+  }

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  //

+  // The Controller must support the Serial I/O Protocol.

+  // This driver is a bus driver with at most 1 child device, so it is

+  // ok for it to be already started.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSerialIoProtocolGuid,

+                  (VOID **) &SerialIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiSerialIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+

+    Start the controller.

+

+  Arguments:

+

+    This                - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.

+    Controller          - The handle of the controller to start.

+    RemainingDevicePath - A pointer to the remaining portion of a devcie path.

+

+  Returns:

+

+    EFI_SUCCESS.

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_SERIAL_IO_PROTOCOL              *SerialIo;

+  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;

+  VENDOR_DEVICE_PATH                  *Node;

+  VENDOR_DEVICE_PATH                  *DefaultNode;

+  EFI_SERIAL_IO_MODE                  *Mode;

+  UINTN                               SerialInTimeOut;

+  TERMINAL_DEV                        *TerminalDevice;

+  UINT8                               TerminalType;

+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;

+  UINTN                               EntryCount;

+  UINTN                               Index;

+  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;

+

+  TerminalDevice = NULL;

+  DefaultNode    = NULL;

+  //

+  // Get the Device Path Protocol to build the device path of the child device

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+  //

+  // Report that the remote terminal is being enabled

+  //

+  DevicePath = ParentDevicePath;

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_ENABLE,

+    DevicePath

+    );

+

+  //

+  // Open the Serial I/O Protocol BY_DRIVER.  It might already be started.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSerialIoProtocolGuid,

+                  (VOID **) &SerialIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    //

+    // If Serial I/O is not already open by this driver, then tag the handle

+    // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and

+    // StdErrDev variables with the list of possible terminal types on this

+    // serial port.

+    //

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiCallerIdGuid,

+                    NULL,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &Controller,

+                      &gEfiCallerIdGuid,

+                      DuplicateDevicePath (ParentDevicePath),

+                      NULL

+                      );

+      if (EFI_ERROR (Status)) {

+        goto Error;

+      }

+      //

+      // if the serial device is a hot plug device, do not update the

+      // ConInDev, ConOutDev, and StdErrDev variables.

+      //

+      Status = gBS->OpenProtocol (

+                      Controller,

+                      &gEfiHotPlugDeviceGuid,

+                      NULL,

+                      This->DriverBindingHandle,

+                      Controller,

+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                      );

+      if (EFI_ERROR (Status)) {

+        TerminalUpdateConsoleDevVariable ((CHAR16 *)VarConsoleInpDev, ParentDevicePath);

+        TerminalUpdateConsoleDevVariable ((CHAR16 *)VarConsoleOutDev, ParentDevicePath);

+        TerminalUpdateConsoleDevVariable ((CHAR16 *)VarErrorOutDev, ParentDevicePath);

+      }

+    }

+  }

+  //

+  // Make sure a child handle does not already exist.  This driver can only

+  // produce one child per serial port.

+  //

+  Status = gBS->OpenProtocolInformation (

+                  Controller,

+                  &gEfiSerialIoProtocolGuid,

+                  &OpenInfoBuffer,

+                  &EntryCount

+                  );

+  if (!EFI_ERROR (Status)) {

+    Status = EFI_SUCCESS;

+    for (Index = 0; Index < EntryCount; Index++) {

+      if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {

+        Status = EFI_ALREADY_STARTED;

+      }

+    }

+

+    gBS->FreePool (OpenInfoBuffer);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  //

+  // If RemainingDevicePath is NULL, then create default device path node

+  //

+  if (RemainingDevicePath == NULL) {

+    DefaultNode = AllocatePool (sizeof (VENDOR_DEVICE_PATH));

+    if (DefaultNode == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto Error;

+    }

+    

+    CopyMem (&DefaultNode->Guid, &gEfiPcAnsiGuid, sizeof (EFI_GUID));

+    RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL*) DefaultNode;

+  }  

+  //

+  // Use the RemainingDevicePath to determine the terminal type

+  //

+  Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;

+

+  if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {

+

+    TerminalType = PcAnsiType;

+

+  } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {

+

+    TerminalType = VT100Type;

+

+  } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {

+

+    TerminalType = VT100PlusType;

+

+  } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {

+

+    TerminalType = VTUTF8Type;

+

+  } else {

+    goto Error;

+  }

+  //

+  // Initialize the Terminal Dev

+  //

+  TerminalDevice = AllocatePool (sizeof (TERMINAL_DEV));

+  if (TerminalDevice == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+

+  ZeroMem (TerminalDevice, sizeof (TERMINAL_DEV));

+

+  TerminalDevice->Signature     = TERMINAL_DEV_SIGNATURE;

+

+  TerminalDevice->TerminalType  = TerminalType;

+

+  TerminalDevice->SerialIo      = SerialIo;

+

+  //

+  // Simple Input Protocol

+  //

+  TerminalDevice->SimpleInput.Reset         = TerminalConInReset;

+  TerminalDevice->SimpleInput.ReadKeyStroke = TerminalConInReadKeyStroke;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  TerminalConInWaitForKey,

+                  &TerminalDevice->SimpleInput,

+                  &TerminalDevice->SimpleInput.WaitForKey

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+  //

+  // initialize the FIFO buffer used for accommodating

+  // the pre-read pending characters

+  //

+  InitializeRawFiFo (TerminalDevice);

+  InitializeUnicodeFiFo (TerminalDevice);

+  InitializeEfiKeyFiFo (TerminalDevice);

+

+  //

+  // Set the timeout value of serial buffer for

+  // keystroke response performance issue

+  //

+  Mode            = TerminalDevice->SerialIo->Mode;

+

+  SerialInTimeOut = 0;

+  if (Mode->BaudRate != 0) {

+    SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;

+  }

+

+  Status = TerminalDevice->SerialIo->SetAttributes (

+                                      TerminalDevice->SerialIo,

+                                      Mode->BaudRate,

+                                      Mode->ReceiveFifoDepth,

+                                      (UINT32) SerialInTimeOut,

+                                      Mode->Parity,

+                                      (UINT8) Mode->DataBits,

+                                      Mode->StopBits

+                                      );

+  if (EFI_ERROR (Status)) {

+    //

+    // if set attributes operation fails, invalidate

+    // the value of SerialInTimeOut,thus make it

+    // inconsistent with the default timeout value

+    // of serial buffer. This will invoke the recalculation

+    // in the readkeystroke routine.

+    //

+    TerminalDevice->SerialInTimeOut = 0;

+  } else {

+    TerminalDevice->SerialInTimeOut = SerialInTimeOut;

+  }

+  //

+  // Build the device path for the child device

+  //

+  Status = SetTerminalDevicePath (

+            TerminalDevice->TerminalType,

+            ParentDevicePath,

+            &TerminalDevice->DevicePath

+            );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  DevicePath = TerminalDevice->DevicePath;

+

+  Status = TerminalDevice->SimpleInput.Reset (

+                                        &TerminalDevice->SimpleInput,

+                                        FALSE

+                                        );

+  if (EFI_ERROR (Status)) {

+    //

+    // Need to report Error Code first

+    //

+    goto ReportError;

+  }

+  //

+  // Simple Text Output Protocol

+  //

+  TerminalDevice->SimpleTextOutput.Reset              = TerminalConOutReset;

+  TerminalDevice->SimpleTextOutput.OutputString       = TerminalConOutOutputString;

+  TerminalDevice->SimpleTextOutput.TestString         = TerminalConOutTestString;

+  TerminalDevice->SimpleTextOutput.QueryMode          = TerminalConOutQueryMode;

+  TerminalDevice->SimpleTextOutput.SetMode            = TerminalConOutSetMode;

+  TerminalDevice->SimpleTextOutput.SetAttribute       = TerminalConOutSetAttribute;

+  TerminalDevice->SimpleTextOutput.ClearScreen        = TerminalConOutClearScreen;

+  TerminalDevice->SimpleTextOutput.SetCursorPosition  = TerminalConOutSetCursorPosition;

+  TerminalDevice->SimpleTextOutput.EnableCursor       = TerminalConOutEnableCursor;

+  TerminalDevice->SimpleTextOutput.Mode               = &TerminalDevice->SimpleTextOutputMode;

+

+  TerminalDevice->SimpleTextOutputMode.MaxMode        = 1;

+  //

+  // For terminal devices, cursor is always visible

+  //

+  TerminalDevice->SimpleTextOutputMode.CursorVisible  = TRUE;

+  TerminalDevice->SimpleTextOutputMode.Attribute      = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK);

+

+  Status = TerminalDevice->SimpleTextOutput.Reset (

+                                              &TerminalDevice->SimpleTextOutput,

+                                              FALSE

+                                              );

+  if (EFI_ERROR (Status)) {

+    goto ReportError;

+  }

+

+  Status = TerminalDevice->SimpleTextOutput.SetMode (

+                                              &TerminalDevice->SimpleTextOutput,

+                                              0

+                                              );

+  if (EFI_ERROR (Status)) {

+    goto ReportError;

+  }

+

+  Status = TerminalDevice->SimpleTextOutput.EnableCursor (

+                                              &TerminalDevice->SimpleTextOutput,

+                                              TRUE

+                                              );

+  if (EFI_ERROR (Status)) {

+    goto ReportError;

+  }

+  //

+  //

+  //

+  TerminalDevice->InputState  = INPUT_STATE_DEFAULT;

+  TerminalDevice->ResetState  = RESET_STATE_DEFAULT;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER,

+                  EFI_TPL_CALLBACK,

+                  NULL,

+                  NULL,

+                  &TerminalDevice->TwoSecondTimeOut

+                  );

+

+  //

+  // Build the component name for the child device

+  //

+  TerminalDevice->ControllerNameTable = NULL;

+  switch (TerminalDevice->TerminalType) {

+  case PcAnsiType:

+    AddUnicodeString (

+      "eng",

+      gTerminalComponentName.SupportedLanguages,

+      &TerminalDevice->ControllerNameTable,

+      (CHAR16 *)L"PC-ANSI Serial Console"

+      );

+    break;

+

+  case VT100Type:

+    AddUnicodeString (

+      "eng",

+      gTerminalComponentName.SupportedLanguages,

+      &TerminalDevice->ControllerNameTable,

+      (CHAR16 *)L"VT-100 Serial Console"

+      );

+    break;

+

+  case VT100PlusType:

+    AddUnicodeString (

+      "eng",

+      gTerminalComponentName.SupportedLanguages,

+      &TerminalDevice->ControllerNameTable,

+      (CHAR16 *)L"VT-100+ Serial Console"

+      );

+    break;

+

+  case VTUTF8Type:

+    AddUnicodeString (

+      "eng",

+      gTerminalComponentName.SupportedLanguages,

+      &TerminalDevice->ControllerNameTable,

+      (CHAR16 *)L"VT-UTF8 Serial Console"

+      );

+    break;

+  }

+  //

+  // Install protocol interfaces for the serial device.

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &TerminalDevice->Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  TerminalDevice->DevicePath,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &TerminalDevice->SimpleInput,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &TerminalDevice->SimpleTextOutput,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+  //

+  // if the serial device is a hot plug device, attaches the HotPlugGuid

+  // onto the terminal device handle.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiHotPlugDeviceGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &TerminalDevice->Handle,

+                    &gEfiHotPlugDeviceGuid,

+                    NULL,

+                    NULL

+                    );

+  }

+  //

+  // Register the Parent-Child relationship via

+  // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSerialIoProtocolGuid,

+                  (VOID **) &TerminalDevice->SerialIo,

+                  This->DriverBindingHandle,

+                  TerminalDevice->Handle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  if (DefaultNode != NULL) {

+    gBS->FreePool (DefaultNode);

+  }

+  

+  return EFI_SUCCESS;

+

+ReportError:

+  //

+  // Report error code before exiting

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_ERROR_CODE | EFI_ERROR_MINOR,

+    EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,

+    DevicePath

+    );

+

+Error:

+  //

+  // Use the Stop() function to free all resources allocated in Start()

+  //

+  if (TerminalDevice != NULL) {

+

+    if (TerminalDevice->Handle != NULL) {

+      This->Stop (This, Controller, 1, &TerminalDevice->Handle);

+    } else {

+

+      if (TerminalDevice->TwoSecondTimeOut != NULL) {

+        gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);

+      }

+

+      if (TerminalDevice->SimpleInput.WaitForKey != NULL) {

+        gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);

+      }

+

+      if (TerminalDevice->ControllerNameTable != NULL) {

+        FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);

+      }

+

+      if (TerminalDevice->DevicePath != NULL) {

+        gBS->FreePool (TerminalDevice->DevicePath);

+      }

+

+      gBS->FreePool (TerminalDevice);

+    }

+  }

+

+  if (DefaultNode != NULL) {

+    gBS->FreePool (DefaultNode);

+  }

+  

+  This->Stop (This, Controller, 0, NULL);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Controller,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+

+    Stop a device controller.

+

+  Arguments:

+

+    This              - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.

+    Controller        - A handle to the device being stopped.

+    NumberOfChildren  - The number of child device handles in ChildHandleBuffer.

+    ChildHandleBuffer - An array of child handles to be freed.

+

+  Returns:

+

+    EFI_SUCCESS      - Operation successful.

+    EFI_DEVICE_ERROR - Devices error.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  UINTN                         Index;

+  BOOLEAN                       AllChildrenStopped;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *SimpleTextOutput;

+  TERMINAL_DEV                  *TerminalDevice;

+  EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath;

+  EFI_SERIAL_IO_PROTOCOL        *SerialIo;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+

+  Status = gBS->HandleProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &DevicePath

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Report that the remote terminal is being disabled

+  //

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_PROGRESS_CODE,

+    EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_DISABLE,

+    DevicePath

+    );

+

+  //

+  // Complete all outstanding transactions to Controller.

+  // Don't allow any new transaction to Controller to be started.

+  //

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiCallerIdGuid,

+                    (VOID **) &ParentDevicePath,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+      //

+      // Remove Parent Device Path from

+      // the Console Device Environment Variables

+      //

+      TerminalRemoveConsoleDevVariable ((CHAR16 *)VarConsoleInpDev, ParentDevicePath);

+      TerminalRemoveConsoleDevVariable ((CHAR16 *)VarConsoleOutDev, ParentDevicePath);

+      TerminalRemoveConsoleDevVariable ((CHAR16 *)VarErrorOutDev, ParentDevicePath);

+

+      //

+      // Uninstall the Terminal Driver's GUID Tag from the Serial controller

+      //

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      Controller,

+                      &gEfiCallerIdGuid,

+                      ParentDevicePath,

+                      NULL

+                      );

+

+      //

+      // Free the ParentDevicePath that was duplicated in Start()

+      //

+      if (!EFI_ERROR (Status)) {

+        gBS->FreePool (ParentDevicePath);

+      }

+    }

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiSerialIoProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    return EFI_SUCCESS;

+  }

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+

+    Status = gBS->OpenProtocol (

+                    ChildHandleBuffer[Index],

+                    &gEfiSimpleTextOutProtocolGuid,

+                    (VOID **) &SimpleTextOutput,

+                    This->DriverBindingHandle,

+                    ChildHandleBuffer[Index],

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+

+      TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);

+

+      gBS->CloseProtocol (

+            Controller,

+            &gEfiSerialIoProtocolGuid,

+            This->DriverBindingHandle,

+            ChildHandleBuffer[Index]

+            );

+

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      ChildHandleBuffer[Index],

+                      &gEfiSimpleTextInProtocolGuid,

+                      &TerminalDevice->SimpleInput,

+                      &gEfiSimpleTextOutProtocolGuid,

+                      &TerminalDevice->SimpleTextOutput,

+                      &gEfiDevicePathProtocolGuid,

+                      TerminalDevice->DevicePath,

+                      NULL

+                      );

+      if (EFI_ERROR (Status)) {

+        gBS->OpenProtocol (

+              Controller,

+              &gEfiSerialIoProtocolGuid,

+              (VOID **) &SerialIo,

+              This->DriverBindingHandle,

+              ChildHandleBuffer[Index],

+              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+              );

+      } else {

+

+        if (TerminalDevice->ControllerNameTable != NULL) {

+          FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);

+        }

+

+        Status = gBS->OpenProtocol (

+                        ChildHandleBuffer[Index],

+                        &gEfiHotPlugDeviceGuid,

+                        NULL,

+                        This->DriverBindingHandle,

+                        Controller,

+                        EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                        );

+        if (!EFI_ERROR (Status)) {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          ChildHandleBuffer[Index],

+                          &gEfiHotPlugDeviceGuid,

+                          NULL,

+                          NULL

+                          );

+        } else {

+          Status = EFI_SUCCESS;

+        }

+

+        gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);

+        gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);

+        gBS->FreePool (TerminalDevice->DevicePath);

+        gBS->FreePool (TerminalDevice);

+      }

+    }

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+TerminalUpdateConsoleDevVariable (

+  IN CHAR16                    *VariableName,

+  IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath

+  )

+{

+  EFI_STATUS                Status;

+  UINTN                     VariableSize;

+  UINT8                     TerminalType;

+  EFI_DEVICE_PATH_PROTOCOL  *Variable;

+  EFI_DEVICE_PATH_PROTOCOL  *NewVariable;

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

+

+  Variable = NULL;

+

+  //

+  // Get global variable and its size according to the name given.

+  //

+  Variable = TerminalGetVariableAndSize (

+              VariableName,

+              &gEfiGlobalVariableGuid,

+              &VariableSize

+              );

+  //

+  // Append terminal device path onto the variable.

+  //

+  for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {

+    SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);

+    NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);

+    if (Variable != NULL) {

+      gBS->FreePool (Variable);

+    }

+

+    if (TempDevicePath != NULL) {

+      gBS->FreePool (TempDevicePath);

+    }

+

+    Variable = NewVariable;

+  }

+

+  VariableSize = GetDevicePathSize (Variable);

+

+  Status = gRT->SetVariable (

+                  VariableName,

+                  &gEfiGlobalVariableGuid,

+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                  VariableSize,

+                  Variable

+                  );

+  gBS->FreePool (Variable);

+

+  return ;

+}

+

+VOID

+TerminalRemoveConsoleDevVariable (

+  IN CHAR16                    *VariableName,

+  IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath

+  )

+/*++

+

+  Routine Description:

+  

+    Remove console device variable.

+    

+  Arguments:

+

+    VariableName     - A pointer to the variable name.

+    ParentDevicePath - A pointer to the parent device path.

+

+  Returns:

+

+--*/

+{

+  EFI_STATUS                Status;

+  BOOLEAN                   FoundOne;

+  BOOLEAN                   Match;

+  UINTN                     VariableSize;

+  UINTN                     InstanceSize;

+  UINT8                     TerminalType;

+  EFI_DEVICE_PATH_PROTOCOL  *Instance;

+  EFI_DEVICE_PATH_PROTOCOL  *Variable;

+  EFI_DEVICE_PATH_PROTOCOL  *OriginalVariable;

+  EFI_DEVICE_PATH_PROTOCOL  *NewVariable;

+  EFI_DEVICE_PATH_PROTOCOL  *SavedNewVariable;

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

+

+  Variable  = NULL;

+  Instance  = NULL;

+

+  //

+  // Get global variable and its size according to the name given.

+  //

+  Variable = TerminalGetVariableAndSize (

+              VariableName,

+              &gEfiGlobalVariableGuid,

+              &VariableSize

+              );

+  if (Variable == NULL) {

+    return ;

+  }

+

+  FoundOne          = FALSE;

+  OriginalVariable  = Variable;

+  NewVariable       = NULL;

+

+  //

+  // Get first device path instance from Variable

+  //

+  Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);

+  if (Instance == NULL) {

+    gBS->FreePool (OriginalVariable);

+    return ;

+  }

+  //

+  // Loop through all the device path instances of Variable

+  //

+  do {

+    //

+    // Loop through all the terminal types that this driver supports

+    //

+    Match = FALSE;

+    for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {

+

+      SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);

+

+      //

+      // Compare the genterated device path to the current device path instance

+      //

+      if (TempDevicePath != NULL) {

+        if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {

+          Match     = TRUE;

+          FoundOne  = TRUE;

+        }

+

+        gBS->FreePool (TempDevicePath);

+      }

+    }

+    //

+    // If a match was not found, then keep the current device path instance

+    //

+    if (!Match) {

+      SavedNewVariable  = NewVariable;

+      NewVariable       = AppendDevicePathInstance (NewVariable, Instance);

+      if (SavedNewVariable != NULL) {

+        gBS->FreePool (SavedNewVariable);

+      }

+    }

+    //

+    // Get next device path instance from Variable

+    //

+    gBS->FreePool (Instance);

+    Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);

+  } while (Instance != NULL);

+

+  gBS->FreePool (OriginalVariable);

+

+  if (FoundOne) {

+    VariableSize = GetDevicePathSize (NewVariable);

+

+    Status = gRT->SetVariable (

+                    VariableName,

+                    &gEfiGlobalVariableGuid,

+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    VariableSize,

+                    NewVariable

+                    );

+  }

+

+  if (NewVariable != NULL) {

+    gBS->FreePool (NewVariable);

+  }

+

+  return ;

+}

+

+VOID *

+TerminalGetVariableAndSize (

+  IN  CHAR16              *Name,

+  IN  EFI_GUID            *VendorGuid,

+  OUT UINTN               *VariableSize

+  )

+/*++

+

+Routine Description:

+  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated

+  buffer, and the size of the buffer. On failure return NULL.

+

+Arguments:

+  Name       - String part of EFI variable name

+

+  VendorGuid - GUID part of EFI variable name

+

+  VariableSize - Returns the size of the EFI variable that was read

+

+Returns:

+  Dynamically allocated memory that contains a copy of the EFI variable.

+  Caller is repsoncible freeing the buffer.

+

+  NULL - Variable was not read

+  

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       BufferSize;

+  VOID        *Buffer;

+

+  Buffer = NULL;

+

+  //

+  // Pass in a small size buffer to find the actual variable size.

+  //

+  BufferSize  = 1;

+  Buffer      = AllocatePool (BufferSize);

+  if (Buffer == NULL) {

+    *VariableSize = 0;

+    return NULL;

+  }

+

+  Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);

+

+  if (Status == EFI_SUCCESS) {

+    *VariableSize = BufferSize;

+    return Buffer;

+

+  } else if (Status == EFI_BUFFER_TOO_SMALL) {

+    //

+    // Allocate the buffer to return

+    //

+    gBS->FreePool (Buffer);

+    Buffer = AllocatePool (BufferSize);

+    if (Buffer == NULL) {

+      *VariableSize = 0;

+      return NULL;

+    }

+    //

+    // Read variable into the allocated buffer.

+    //

+    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);

+    if (EFI_ERROR (Status)) {

+      BufferSize = 0;

+      gBS->FreePool (Buffer);

+      Buffer = NULL;

+    }

+  } else {

+    //

+    // Variable not found or other errors met.

+    //

+    BufferSize = 0;

+    gBS->FreePool (Buffer);

+    Buffer = NULL;

+  }

+

+  *VariableSize = BufferSize;

+  return Buffer;

+}

+

+EFI_STATUS

+SetTerminalDevicePath (

+  IN  UINT8                       TerminalType,

+  IN  EFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath,

+  OUT EFI_DEVICE_PATH_PROTOCOL    **TerminalDevicePath

+  )

+{

+  VENDOR_DEVICE_PATH  Node;

+

+  *TerminalDevicePath = NULL;

+  Node.Header.Type    = MESSAGING_DEVICE_PATH;

+  Node.Header.SubType = MSG_VENDOR_DP;

+

+  //

+  // generate terminal device path node according to terminal type.

+  //

+  switch (TerminalType) {

+

+  case PcAnsiType:

+    CopyMem (

+      &Node.Guid,

+      &gEfiPcAnsiGuid,

+      sizeof (EFI_GUID)

+      );

+    break;

+

+  case VT100Type:

+    CopyMem (

+      &Node.Guid,

+      &gEfiVT100Guid,

+      sizeof (EFI_GUID)

+      );

+    break;

+

+  case VT100PlusType:

+    CopyMem (

+      &Node.Guid,

+      &gEfiVT100PlusGuid,

+      sizeof (EFI_GUID)

+      );

+    break;

+

+  case VTUTF8Type:

+    CopyMem (

+      &Node.Guid,

+      &gEfiVTUTF8Guid,

+      sizeof (EFI_GUID)

+      );

+    break;

+

+  default:

+    return EFI_UNSUPPORTED;

+    break;

+  }

+

+  SetDevicePathNodeLength (

+    &Node.Header,

+    sizeof (VENDOR_DEVICE_PATH)

+    );

+  //

+  // append the terminal node onto parent device path

+  // to generate a complete terminal device path.

+  //

+  *TerminalDevicePath = AppendDevicePathNode (

+                          ParentDevicePath,

+                          (EFI_DEVICE_PATH_PROTOCOL *) &Node

+                          );

+  if (*TerminalDevicePath == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+InitializeRawFiFo (

+  IN  TERMINAL_DEV  *TerminalDevice

+  )

+{

+  //

+  // Make the raw fifo empty.

+  //

+  TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;

+}

+

+VOID

+InitializeUnicodeFiFo (

+  IN  TERMINAL_DEV  *TerminalDevice

+  )

+{

+  //

+  // Make the unicode fifo empty

+  //

+  TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;

+}

+

+VOID

+InitializeEfiKeyFiFo (

+  IN  TERMINAL_DEV  *TerminalDevice

+  )

+{

+  //

+  // Make the efi key fifo empty

+  //

+  TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.h b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.h
new file mode 100644
index 0000000..2382d86
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.h
@@ -0,0 +1,506 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  terminal.h

+

+Abstract:

+

+  

+Revision History

+

+--*/

+

+#ifndef _TERMINAL_H

+#define _TERMINAL_H

+

+#define RAW_FIFO_MAX_NUMBER 256

+#define FIFO_MAX_NUMBER     128

+

+typedef struct {

+  UINT8 Head;

+  UINT8 Tail;

+  UINT8 Data[RAW_FIFO_MAX_NUMBER + 1];

+} RAW_DATA_FIFO;

+

+typedef struct {

+  UINT8   Head;

+  UINT8   Tail;

+  UINT16  Data[FIFO_MAX_NUMBER + 1];

+} UNICODE_FIFO;

+

+typedef struct {

+  UINT8         Head;

+  UINT8         Tail;

+  EFI_INPUT_KEY Data[FIFO_MAX_NUMBER + 1];

+} EFI_KEY_FIFO;

+

+#define TERMINAL_DEV_SIGNATURE  EFI_SIGNATURE_32 ('t', 'm', 'n', 'l')

+

+typedef struct {

+  UINTN                         Signature;

+  EFI_HANDLE                    Handle;

+  UINT8                         TerminalType;

+  EFI_SERIAL_IO_PROTOCOL        *SerialIo;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  VENDOR_DEVICE_PATH            Node;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL   SimpleInput;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  SimpleTextOutput;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE   SimpleTextOutputMode;

+  UINTN                         SerialInTimeOut;

+  RAW_DATA_FIFO                 RawFiFo;

+  UNICODE_FIFO                  UnicodeFiFo;

+  EFI_KEY_FIFO                  EfiKeyFiFo;

+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;

+  EFI_EVENT                     TwoSecondTimeOut;

+  UINT32                        InputState;

+  UINT32                        ResetState;

+

+  //

+  // Esc could not be output to the screen by user,

+  // but the terminal driver need to output it to

+  // the terminal emulation software to send control sequence.

+  // This boolean is used by the terminal driver only

+  // to indicate whether the Esc could be sent or not.

+  //

+  BOOLEAN                       OutputEscChar;

+} TERMINAL_DEV;

+

+#define INPUT_STATE_DEFAULT               0x00

+#define INPUT_STATE_ESC                   0x01

+#define INPUT_STATE_CSI                   0x02

+#define INPUT_STATE_LEFTOPENBRACKET       0x04

+#define INPUT_STATE_O                     0x08

+#define INPUT_STATE_2                     0x10

+

+#define RESET_STATE_DEFAULT               0x00

+#define RESET_STATE_ESC_R                 0x01

+#define RESET_STATE_ESC_R_ESC_r           0x02

+

+#define TERMINAL_CON_IN_DEV_FROM_THIS(a)  CR (a, TERMINAL_DEV, SimpleInput, TERMINAL_DEV_SIGNATURE)

+#define TERMINAL_CON_OUT_DEV_FROM_THIS(a) CR (a, TERMINAL_DEV, SimpleTextOutput, TERMINAL_DEV_SIGNATURE)

+

+typedef union {

+  UINT8 Utf8_1;

+  UINT8 Utf8_2[2];

+  UINT8 Utf8_3[3];

+} UTF8_CHAR;

+

+#define PcAnsiType                0

+#define VT100Type                 1

+#define VT100PlusType             2

+#define VTUTF8Type                3

+

+#define LEFTOPENBRACKET           0x5b  // '['

+#define ACAP                      0x41

+#define BCAP                      0x42

+#define CCAP                      0x43

+#define DCAP                      0x44

+

+#define MODE0_COLUMN_COUNT        80

+#define MODE0_ROW_COUNT           25

+

+#define BACKSPACE                 8

+#define ESC                       27

+#define CSI                       0x9B

+#define DEL                       127

+#define BRIGHT_CONTROL_OFFSET     2

+#define FOREGROUND_CONTROL_OFFSET 6

+#define BACKGROUND_CONTROL_OFFSET 11

+#define ROW_OFFSET                2

+#define COLUMN_OFFSET             5

+

+typedef struct {

+  UINT16  Unicode;

+  CHAR8   PcAnsi;

+  CHAR8   Ascii;

+} UNICODE_TO_CHAR;

+

+#define VarConsoleInpDev  L"ConInDev"

+#define VarConsoleOutDev  L"ConOutDev"

+#define VarErrorOutDev    L"ErrOutDev"

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gTerminalDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gTerminalComponentName;

+

+//

+// Prototypes

+//

+EFI_STATUS

+EFIAPI

+InitializeTerminal (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConInReset (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL    *This,

+  IN  BOOLEAN                        ExtendedVerification

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConInReadKeyStroke (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL  *This,

+  OUT EFI_INPUT_KEY                *Key

+  )

+;

+

+VOID

+EFIAPI

+TerminalConInWaitForKey (

+  IN  EFI_EVENT     Event,

+  IN  VOID          *Context

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutReset (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *This,

+  IN  BOOLEAN                         ExtendedVerification

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutOutputString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutTestString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutQueryMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber,

+  OUT UINTN                         *Columns,

+  OUT UINTN                         *Rows

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutSetMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutSetAttribute (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Attribute

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutClearScreen (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutSetCursorPosition (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Column,

+  IN  UINTN                         Row

+  )

+;

+

+EFI_STATUS

+EFIAPI

+TerminalConOutEnableCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  BOOLEAN                       Visible

+  )

+;

+

+//

+// internal functions

+//

+EFI_STATUS

+TerminalConInCheckForKey (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL  *This

+  )

+;

+

+VOID

+TerminalUpdateConsoleDevVariable (

+  IN CHAR16                    *VariableName,

+  IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath

+  )

+;

+

+VOID

+TerminalRemoveConsoleDevVariable (

+  IN CHAR16                    *VariableName,

+  IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath

+  )

+;

+

+VOID                                *

+TerminalGetVariableAndSize (

+  IN  CHAR16              *Name,

+  IN  EFI_GUID            *VendorGuid,

+  OUT UINTN               *VariableSize

+  )

+;

+

+EFI_STATUS

+SetTerminalDevicePath (

+  IN  UINT8                       TerminalType,

+  IN  EFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath,

+  OUT EFI_DEVICE_PATH_PROTOCOL    **TerminalDevicePath

+  )

+;

+

+VOID

+InitializeRawFiFo (

+  IN  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+VOID

+InitializeUnicodeFiFo (

+  IN  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+VOID

+InitializeEfiKeyFiFo (

+  IN  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+EFI_STATUS

+GetOneKeyFromSerial (

+  EFI_SERIAL_IO_PROTOCOL  *SerialIo,

+  UINT8                   *Input

+  )

+;

+

+BOOLEAN

+RawFiFoInsertOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  UINT8         Input

+  )

+;

+

+BOOLEAN

+RawFiFoRemoveOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  UINT8         *Output

+  )

+;

+

+BOOLEAN

+IsRawFiFoEmpty (

+  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+BOOLEAN

+IsRawFiFoFull (

+  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+BOOLEAN

+EfiKeyFiFoInsertOneKey (

+  TERMINAL_DEV      *TerminalDevice,

+  EFI_INPUT_KEY     Key

+  )

+;

+

+BOOLEAN

+EfiKeyFiFoRemoveOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  EFI_INPUT_KEY *Output

+  )

+;

+

+BOOLEAN

+IsEfiKeyFiFoEmpty (

+  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+BOOLEAN

+IsEfiKeyFiFoFull (

+  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+BOOLEAN

+UnicodeFiFoInsertOneKey (

+  TERMINAL_DEV      *TerminalDevice,

+  UINT16            Input

+  )

+;

+

+BOOLEAN

+UnicodeFiFoRemoveOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  UINT16        *Output

+  )

+;

+

+BOOLEAN

+IsUnicodeFiFoEmpty (

+  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+BOOLEAN

+IsUnicodeFiFoFull (

+  TERMINAL_DEV  *TerminalDevice

+  )

+;

+

+UINT8

+UnicodeFiFoGetKeyCount (

+  TERMINAL_DEV    *TerminalDevice

+  )

+;

+

+VOID

+TranslateRawDataToEfiKey (

+  IN  TERMINAL_DEV      *TerminalDevice

+  )

+;

+

+//

+// internal functions for PC ANSI

+//

+VOID

+AnsiRawDataToUnicode (

+  IN  TERMINAL_DEV    *PcAnsiDevice

+  )

+;

+

+VOID

+UnicodeToEfiKey (

+  IN  TERMINAL_DEV    *PcAnsiDevice

+  )

+;

+

+EFI_STATUS

+AnsiTestString (

+  IN  TERMINAL_DEV    *TerminalDevice,

+  IN  CHAR16          *WString

+  )

+;

+

+//

+// internal functions for VT100

+//

+EFI_STATUS

+VT100TestString (

+  IN  TERMINAL_DEV    *VT100Device,

+  IN  CHAR16          *WString

+  )

+;

+

+//

+// internal functions for VT100Plus

+//

+EFI_STATUS

+VT100PlusTestString (

+  IN  TERMINAL_DEV    *TerminalDevice,

+  IN  CHAR16          *WString

+  )

+;

+

+//

+// internal functions for VTUTF8

+//

+VOID

+VTUTF8RawDataToUnicode (

+  IN  TERMINAL_DEV    *VtUtf8Device

+  )

+;

+

+EFI_STATUS

+VTUTF8TestString (

+  IN  TERMINAL_DEV    *TerminalDevice,

+  IN  CHAR16          *WString

+  )

+;

+

+VOID

+UnicodeToUtf8 (

+  IN  CHAR16      Unicode,

+  OUT UTF8_CHAR   *Utf8Char,

+  OUT UINT8       *ValidBytes

+  )

+;

+

+VOID

+GetOneValidUtf8Char (

+  IN  TERMINAL_DEV      *Utf8Device,

+  OUT UTF8_CHAR         *Utf8Char,

+  OUT UINT8             *ValidBytes

+  )

+;

+

+VOID

+Utf8ToUnicode (

+  IN  UTF8_CHAR       Utf8Char,

+  IN  UINT8           ValidBytes,

+  OUT CHAR16          *UnicodeChar

+  )

+;

+

+//

+// functions for boxdraw unicode

+//

+BOOLEAN

+TerminalIsValidTextGraphics (

+  IN  CHAR16  Graphic,

+  OUT CHAR8   *PcAnsi, OPTIONAL

+  OUT CHAR8   *Ascii OPTIONAL

+  )

+;

+

+BOOLEAN

+TerminalIsValidAscii (

+  IN  CHAR16  Ascii

+  )

+;

+

+BOOLEAN

+TerminalIsValidEfiCntlChar (

+  IN  CHAR16  CharC

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.mbd b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.mbd
new file mode 100644
index 0000000..7ec90ab
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Terminal</BaseName>

+    <Guid>9E863906-A40F-4875-977F-5B93FF237FC6</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-22 19:05</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.msa b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.msa
new file mode 100644
index 0000000..92458b8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/Terminal.msa
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Terminal</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>9E863906-A40F-4875-977F-5B93FF237FC6</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-22 19:05</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>    

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Terminal.h</Filename>

+    <Filename>Terminal.c</Filename>

+    <Filename>TerminalConIn.c</Filename>

+    <Filename>TerminalConOut.c</Filename>

+    <Filename>ansi.c</Filename>

+    <Filename>vtutf8.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="BY_START">SimpleTextOut</Protocol>

+    <Protocol Usage="BY_START">SimpleTextIn</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">SerialIo</Protocol>    

+  </Protocols>

+  <Variables>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ConInDev</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ConOutDev</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ErrOutDev</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+  </Variables>    

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>HotPlugDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>GlobalVariable</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>PcAnsi</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>VT100Plus</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>VT100</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>VTUTF8</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gTerminalDriverBinding</DriverBinding>

+      <ComponentName>gTerminalComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/TerminalConIn.c b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/TerminalConIn.c
new file mode 100644
index 0000000..feaef5f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/TerminalConIn.c
@@ -0,0 +1,1185 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    TerminalConIn.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+

+#include <Common/StatusCode.h>

+#include "Terminal.h"

+

+

+EFI_STATUS

+EFIAPI

+TerminalConInReset (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL  *This,

+  IN  BOOLEAN                      ExtendedVerification

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset().

+    This driver only perform dependent serial device reset regardless of 

+    the value of ExtendeVerification

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    ExtendedVerification - Skip by this driver.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The reset operation succeeds.   

+    

+    EFI_DEVICE_ERROR

+      The dependent serial port reset fails.

+                

+--*/

+{

+  EFI_STATUS    Status;

+  TERMINAL_DEV  *TerminalDevice;

+

+  TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);

+

+  //

+  // Report progress code here

+  //

+  Status = REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+            EFI_PROGRESS_CODE,

+            EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET,

+            TerminalDevice->DevicePath

+            );

+

+  Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);

+

+  //

+  // clear all the internal buffer for keys

+  //

+  InitializeRawFiFo (TerminalDevice);

+  InitializeUnicodeFiFo (TerminalDevice);

+  InitializeEfiKeyFiFo (TerminalDevice);

+

+  if (EFI_ERROR (Status)) {

+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,

+      TerminalDevice->DevicePath

+      );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConInReadKeyStroke (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL  *This,

+  OUT EFI_INPUT_KEY                *Key

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke().

+      

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    Key  - A pointer to a buffer that is filled in with the keystroke

+        information for the key that was sent from terminal.        

+        

+  Returns:

+  

+    EFI_SUCCESS

+      The keystroke information is returned successfully.

+       

+    EFI_NOT_READY

+      There is no keystroke data available.

+ 

+    EFI_DEVICE_ERROR

+      The dependent serial device encounters error.

+                

+--*/

+{

+  TERMINAL_DEV  *TerminalDevice;

+  EFI_STATUS    Status;

+

+  //

+  // Initialize *Key to nonsense value.

+  //

+  Key->ScanCode     = SCAN_NULL;

+  Key->UnicodeChar  = 0;

+  //

+  //  get TERMINAL_DEV from "This" parameter.

+  //

+  TerminalDevice  = TERMINAL_CON_IN_DEV_FROM_THIS (This);

+

+  Status          = TerminalConInCheckForKey (This);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_READY;

+  }

+

+  EfiKeyFiFoRemoveOneKey (TerminalDevice, Key);

+

+  return EFI_SUCCESS;

+

+}

+

+VOID

+TranslateRawDataToEfiKey (

+  IN  TERMINAL_DEV      *TerminalDevice

+  )

+/*++

+    Step1: Turn raw data into Unicode (according to different encode).

+    Step2: Translate Unicode into key information. 

+    (according to different terminal standard).

+--*/

+{

+  switch (TerminalDevice->TerminalType) {

+

+  case PcAnsiType:

+  case VT100Type:

+  case VT100PlusType:

+    AnsiRawDataToUnicode (TerminalDevice);

+    UnicodeToEfiKey (TerminalDevice);

+    break;

+

+  case VTUTF8Type:

+    //

+    // Process all the raw data in the RawFIFO,

+    // put the processed key into UnicodeFIFO.

+    //

+    VTUTF8RawDataToUnicode (TerminalDevice);

+

+    //

+    // Translate all the Unicode data in the UnicodeFIFO to Efi key,

+    // then put into EfiKeyFIFO.

+    //

+    UnicodeToEfiKey (TerminalDevice);

+

+    break;

+  }

+}

+

+VOID

+EFIAPI

+TerminalConInWaitForKey (

+  IN  EFI_EVENT       Event,

+  IN  VOID            *Context

+  )

+/*++

+  Routine Description:

+  

+    Event notification function for EFI_SIMPLE_TEXT_IN_PROTOCOL.WaitForKey event

+    Signal the event if there is key available     

+  

+  Arguments:

+  

+    Event - Indicates the event that invoke this function.

+    

+    Context - Indicates the calling context.

+        

+  Returns:

+  

+    N/A

+                

+--*/

+{

+  //

+  // Someone is waiting on the keystroke event, if there's

+  // a key pending, signal the event

+  //

+  // Context is the pointer to EFI_SIMPLE_TEXT_IN_PROTOCOL

+  //

+  if (!EFI_ERROR (TerminalConInCheckForKey (Context))) {

+

+    gBS->SignalEvent (Event);

+  }

+}

+

+EFI_STATUS

+TerminalConInCheckForKey (

+  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL  *This

+  )

+/*++

+  Routine Description:

+  

+    Check for a pending key in the Efi Key FIFO or Serial device buffer.

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       There is key pending.   

+    

+    EFI_NOT_READY

+      There is no key pending.

+      

+    EFI_DEVICE_ERROR

+                

+--*/

+{

+  EFI_STATUS              Status;

+  TERMINAL_DEV            *TerminalDevice;

+  UINT32                  Control;

+  UINT8                   Input;

+  EFI_SERIAL_IO_MODE      *Mode;

+  EFI_SERIAL_IO_PROTOCOL  *SerialIo;

+  UINTN                   SerialInTimeOut;

+

+  TerminalDevice  = TERMINAL_CON_IN_DEV_FROM_THIS (This);

+

+  SerialIo        = TerminalDevice->SerialIo;

+  if (SerialIo == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //  if current timeout value for serial device is not identical with

+  //  the value saved in TERMINAL_DEV structure, then recalculate the

+  //  timeout value again and set serial attribute according to this value.

+  //

+  Mode = SerialIo->Mode;

+  if (Mode->Timeout != TerminalDevice->SerialInTimeOut) {

+

+    SerialInTimeOut = 0;

+    if (Mode->BaudRate != 0) {

+      SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;

+    }

+

+    Status = SerialIo->SetAttributes (

+                        SerialIo,

+                        Mode->BaudRate,

+                        Mode->ReceiveFifoDepth,

+                        (UINT32) SerialInTimeOut,

+                        Mode->Parity,

+                        (UINT8) Mode->DataBits,

+                        Mode->StopBits

+                        );

+

+    if (EFI_ERROR (Status)) {

+      TerminalDevice->SerialInTimeOut = 0;

+    } else {

+      TerminalDevice->SerialInTimeOut = SerialInTimeOut;

+    }

+  }

+  //

+  //  check whether serial buffer is empty

+  //

+  Status = SerialIo->GetControl (SerialIo, &Control);

+

+  if (Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) {

+    //

+    // Translate all the raw data in RawFIFO into EFI Key,

+    // according to different terminal type supported.

+    //

+    TranslateRawDataToEfiKey (TerminalDevice);

+

+    //

+    //  if there is pre-fetched Efi Key in EfiKeyFIFO buffer,

+    //  return directly.

+    //

+    if (!IsEfiKeyFiFoEmpty (TerminalDevice)) {

+      return EFI_SUCCESS;

+    } else {

+      return EFI_NOT_READY;

+    }

+  }

+  //

+  // Fetch all the keys in the serial buffer,

+  // and insert the byte stream into RawFIFO.

+  //

+  do {

+

+    Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);

+

+    if (EFI_ERROR (Status)) {

+      if (Status == EFI_DEVICE_ERROR) {

+        REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+          EFI_ERROR_CODE | EFI_ERROR_MINOR,

+          EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR,

+          TerminalDevice->DevicePath

+          );

+      }

+      break;

+    }

+

+    RawFiFoInsertOneKey (TerminalDevice, Input);

+  } while (TRUE);

+

+  //

+  // Translate all the raw data in RawFIFO into EFI Key,

+  // according to different terminal type supported.

+  //

+  TranslateRawDataToEfiKey (TerminalDevice);

+

+  if (IsEfiKeyFiFoEmpty (TerminalDevice)) {

+    return EFI_NOT_READY;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetOneKeyFromSerial (

+  EFI_SERIAL_IO_PROTOCOL  *SerialIo,

+  UINT8                   *Input

+  )

+/*++

+    Get one key out of serial buffer.

+    If serial buffer is empty, return EFI_NOT_READY;

+    if reading serial buffer encounter error, returns EFI_DEVICE_ERROR;

+    if reading serial buffer successfully, put the fetched key to 

+    the parameter "Input", and return EFI_SUCCESS.

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Size;

+

+  Size    = 1;

+  *Input  = 0;

+

+  Status  = SerialIo->Read (SerialIo, &Size, Input);

+

+  if (EFI_ERROR (Status)) {

+

+    if (Status == EFI_TIMEOUT) {

+      return EFI_NOT_READY;

+    }

+

+    return EFI_DEVICE_ERROR;

+

+  }

+

+  if (*Input == 0) {

+    return EFI_NOT_READY;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+RawFiFoInsertOneKey (

+  TERMINAL_DEV      *TerminalDevice,

+  UINT8             Input

+  )

+/*++

+    Insert one byte raw data into the Raw Data FIFO.

+    If FIFO is FULL before data insertion,

+    return FALSE, and the key is lost.

+--*/

+{

+  UINT8 Tail;

+

+  Tail = TerminalDevice->RawFiFo.Tail;

+

+  if (IsRawFiFoFull (TerminalDevice)) {

+    //

+    // Raw FIFO is full

+    //

+    return FALSE;

+  }

+

+  TerminalDevice->RawFiFo.Data[Tail]  = Input;

+

+  TerminalDevice->RawFiFo.Tail        = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1));

+

+  return TRUE;

+}

+

+BOOLEAN

+RawFiFoRemoveOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  UINT8         *Output

+  )

+/*++

+    Remove one byte raw data out of the Raw Data FIFO.

+    If FIFO buffer is empty before remove operation,

+    return FALSE.

+--*/

+{

+  UINT8 Head;

+

+  Head = TerminalDevice->RawFiFo.Head;

+

+  if (IsRawFiFoEmpty (TerminalDevice)) {

+    //

+    //  FIFO is empty

+    //

+    *Output = 0;

+    return FALSE;

+  }

+

+  *Output                       = TerminalDevice->RawFiFo.Data[Head];

+

+  TerminalDevice->RawFiFo.Head  = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1));

+

+  return TRUE;

+}

+

+BOOLEAN

+IsRawFiFoEmpty (

+  TERMINAL_DEV  *TerminalDevice

+  )

+/*++

+    Clarify whether FIFO buffer is empty.

+--*/

+{

+  if (TerminalDevice->RawFiFo.Head == TerminalDevice->RawFiFo.Tail) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsRawFiFoFull (

+  TERMINAL_DEV  *TerminalDevice

+  )

+/*++

+    Clarify whether FIFO buffer is full.

+--*/

+{

+  UINT8 Tail;

+  UINT8 Head;

+

+  Tail  = TerminalDevice->RawFiFo.Tail;

+  Head  = TerminalDevice->RawFiFo.Head;

+

+  if (((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1)) == Head) {

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+EfiKeyFiFoInsertOneKey (

+  TERMINAL_DEV      *TerminalDevice,

+  EFI_INPUT_KEY     Key

+  )

+/*++

+    Insert one pre-fetched key into the FIFO buffer.

+    If FIFO buffer is FULL before key insertion,

+    return FALSE, and the key is lost.

+--*/

+{

+  UINT8 Tail;

+

+  Tail = TerminalDevice->EfiKeyFiFo.Tail;

+

+  if (IsEfiKeyFiFoFull (TerminalDevice)) {

+    //

+    // Efi Key FIFO is full

+    //

+    return FALSE;

+  }

+

+  TerminalDevice->EfiKeyFiFo.Data[Tail] = Key;

+

+  TerminalDevice->EfiKeyFiFo.Tail       = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));

+

+  return TRUE;

+}

+

+BOOLEAN

+EfiKeyFiFoRemoveOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  EFI_INPUT_KEY *Output

+  )

+/*++

+    Remove one pre-fetched key out of the FIFO buffer.

+    If FIFO buffer is empty before remove operation,

+    return FALSE.

+--*/

+{

+  UINT8 Head;

+

+  Head = TerminalDevice->EfiKeyFiFo.Head;

+

+  if (IsEfiKeyFiFoEmpty (TerminalDevice)) {

+    //

+    //  FIFO is empty

+    //

+    Output->ScanCode    = SCAN_NULL;

+    Output->UnicodeChar = 0;

+    return FALSE;

+  }

+

+  *Output                         = TerminalDevice->EfiKeyFiFo.Data[Head];

+

+  TerminalDevice->EfiKeyFiFo.Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));

+

+  return TRUE;

+}

+

+BOOLEAN

+IsEfiKeyFiFoEmpty (

+  TERMINAL_DEV  *TerminalDevice

+  )

+/*++

+    Clarify whether FIFO buffer is empty.

+--*/

+{

+  if (TerminalDevice->EfiKeyFiFo.Head == TerminalDevice->EfiKeyFiFo.Tail) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsEfiKeyFiFoFull (

+  TERMINAL_DEV  *TerminalDevice

+  )

+/*++

+    Clarify whether FIFO buffer is full.

+--*/

+{

+  UINT8 Tail;

+  UINT8 Head;

+

+  Tail  = TerminalDevice->EfiKeyFiFo.Tail;

+  Head  = TerminalDevice->EfiKeyFiFo.Head;

+

+  if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+UnicodeFiFoInsertOneKey (

+  TERMINAL_DEV      *TerminalDevice,

+  UINT16            Input

+  )

+/*++

+    Insert one pre-fetched key into the FIFO buffer.

+    If FIFO buffer is FULL before key insertion,

+    return FALSE, and the key is lost.

+--*/

+{

+  UINT8 Tail;

+

+  Tail = TerminalDevice->UnicodeFiFo.Tail;

+

+  if (IsUnicodeFiFoFull (TerminalDevice)) {

+    //

+    // Unicode FIFO is full

+    //

+    return FALSE;

+  }

+

+  TerminalDevice->UnicodeFiFo.Data[Tail]  = Input;

+

+  TerminalDevice->UnicodeFiFo.Tail        = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));

+

+  return TRUE;

+}

+

+BOOLEAN

+UnicodeFiFoRemoveOneKey (

+  TERMINAL_DEV  *TerminalDevice,

+  UINT16        *Output

+  )

+/*++

+    Remove one pre-fetched key out of the FIFO buffer.

+    If FIFO buffer is empty before remove operation,

+    return FALSE.

+--*/

+{

+  UINT8 Head;

+

+  Head = TerminalDevice->UnicodeFiFo.Head;

+

+  if (IsUnicodeFiFoEmpty (TerminalDevice)) {

+    //

+    //  FIFO is empty

+    //

+    Output = NULL;

+    return FALSE;

+  }

+

+  *Output = TerminalDevice->UnicodeFiFo.Data[Head];

+

+  TerminalDevice->UnicodeFiFo.Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));

+

+  return TRUE;

+}

+

+BOOLEAN

+IsUnicodeFiFoEmpty (

+  TERMINAL_DEV  *TerminalDevice

+  )

+/*++

+    Clarify whether FIFO buffer is empty.

+--*/

+{

+  if (TerminalDevice->UnicodeFiFo.Head == TerminalDevice->UnicodeFiFo.Tail) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+IsUnicodeFiFoFull (

+  TERMINAL_DEV  *TerminalDevice

+  )

+/*++

+    Clarify whether FIFO buffer is full.

+--*/

+{

+  UINT8 Tail;

+  UINT8 Head;

+

+  Tail  = TerminalDevice->UnicodeFiFo.Tail;

+  Head  = TerminalDevice->UnicodeFiFo.Head;

+

+  if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+UINT8

+UnicodeFiFoGetKeyCount (

+  TERMINAL_DEV    *TerminalDevice

+  )

+{

+  UINT8 Tail;

+  UINT8 Head;

+

+  Tail  = TerminalDevice->UnicodeFiFo.Tail;

+  Head  = TerminalDevice->UnicodeFiFo.Head;

+

+  if (Tail >= Head) {

+    return (UINT8) (Tail - Head);

+  } else {

+    return (UINT8) (Tail + FIFO_MAX_NUMBER + 1 - Head);

+  }

+}

+

+VOID

+UnicodeToEfiKeyFlushState (

+  IN  TERMINAL_DEV    *TerminalDevice

+  )

+{

+  EFI_INPUT_KEY Key;

+

+  if (TerminalDevice->InputState & INPUT_STATE_ESC) {

+    Key.ScanCode    = SCAN_ESC;

+    Key.UnicodeChar = 0;

+    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);

+  }

+

+  if (TerminalDevice->InputState & INPUT_STATE_CSI) {

+    Key.ScanCode    = SCAN_NULL;

+    Key.UnicodeChar = CSI;

+    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);

+  }

+

+  if (TerminalDevice->InputState & INPUT_STATE_LEFTOPENBRACKET) {

+    Key.ScanCode    = SCAN_NULL;

+    Key.UnicodeChar = LEFTOPENBRACKET;

+    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);

+  }

+

+  if (TerminalDevice->InputState & INPUT_STATE_O) {

+    Key.ScanCode    = SCAN_NULL;

+    Key.UnicodeChar = 'O';

+    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);

+  }

+

+  if (TerminalDevice->InputState & INPUT_STATE_2) {

+    Key.ScanCode    = SCAN_NULL;

+    Key.UnicodeChar = '2';

+    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);

+  }

+

+  gBS->SetTimer (

+        TerminalDevice->TwoSecondTimeOut,

+        TimerCancel,

+        0

+        );

+

+  TerminalDevice->InputState = INPUT_STATE_DEFAULT;

+}

+

+VOID

+UnicodeToEfiKey (

+  IN  TERMINAL_DEV    *TerminalDevice

+  )

+/*++

+  Routine Description:

+  

+    Converts a stream of Unicode characters from a terminal input device into EFI Keys that

+    can be read through the Simple Input Protocol.  The table below shows the keyboard

+    input mappings that this function supports.  If the ESC sequence listed in one of the 

+    columns is presented, then it is translated into the coorespoding EFI Scan Code.  If a

+    matching sequence is not found, then the raw key strokes are converted into EFI Keys.

+    

+    2 seconds are allowed for an ESC sequence to be completed.  If the ESC sequence is not 

+    completed in 2 seconds, then the raw key strokes of the partial ESC sequence are 

+    converted into EFI Keys.

+    

+    There is one special input sequence that will force the system to reset.  

+    This is ESC R ESC r ESC R.

+  

+  Arguments:

+

+    TerminaDevice : The terminal device to use to translate raw input into EFI Keys

+        

+  Returns:

+

+    None

+

+Symbols used in table below

+===========================

+  ESC = 0x1B  

+  CSI = 0x9B  

+  DEL = 0x7f  

+  ^   = CTRL

+

++=========+======+===========+==========+==========+

+|         | EFI  | EFI 1.10  |          |          |

+|         | Scan |           |  VT100+  |          |

+|   KEY   | Code |  PC ANSI  |  VTUTF8  |   VT100  |

++=========+======+===========+==========+==========+

+| NULL    | 0x00 |           |          |          |

+| UP      | 0x01 | ESC [ A   | ESC [ A  | ESC [ A  |

+| DOWN    | 0x02 | ESC [ B   | ESC [ B  | ESC [ B  |

+| RIGHT   | 0x03 | ESC [ C   | ESC [ C  | ESC [ C  | 

+| LEFT    | 0x04 | ESC [ D   | ESC [ D  | ESC [ D  |

+| HOME    | 0x05 | ESC [ H   | ESC h    | ESC [ H  |

+| END     | 0x06 | ESC [ F   | ESC k    | ESC [ K  |

+| INSERT  | 0x07 | ESC [ @   | ESC +    | ESC [ @  |

+|         |      | ESC [ L   |          | ESC [ L  |

+| DELETE  | 0x08 | ESC [ X   | ESC -    | ESC [ P  |

+| PG UP   | 0x09 | ESC [ I   | ESC ?    | ESC [ V  |

+|         |      |           |          | ESC [ ?  |

+| PG DOWN | 0x0A | ESC [ G   | ESC /    | ESC [ U  |

+|         |      |           |          | ESC [ /  |

+| F1      | 0x0B | ESC [ M   | ESC 1    | ESC O P  |

+| F2      | 0x0C | ESC [ N   | ESC 2    | ESC O Q  |

+| F3      | 0x0D | ESC [ O   | ESC 3    | ESC O w  |

+| F4      | 0x0E | ESC [ P   | ESC 4    | ESC O x  |

+| F5      | 0x0F | ESC [ Q   | ESC 5    | ESC O t  |

+| F6      | 0x10 | ESC [ R   | ESC 6    | ESC O u  |

+| F7      | 0x11 | ESC [ S   | ESC 7    | ESC O q  |

+| F8      | 0x12 | ESC [ T   | ESC 8    | ESC O r  |

+| F9      | 0x13 | ESC [ U   | ESC 9    | ESC O p  |

+| F10     | 0x14 | ESC [ V   | ESC 0    | ESC O M  |

+| Escape  | 0x17 | ESC       | ESC      | ESC      |

++=========+======+===========+==========+=========+

+

+Special Mappings

+================

+ESC R ESC r ESC R = Reset System

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_STATUS          TimerStatus;

+  UINT16              UnicodeChar;

+  EFI_INPUT_KEY       Key;

+  BOOLEAN             SetDefaultResetState;

+  

+  TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);

+

+  if (!EFI_ERROR (TimerStatus)) {

+    UnicodeToEfiKeyFlushState (TerminalDevice);

+    TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+  }

+

+  while (!IsUnicodeFiFoEmpty(TerminalDevice)) {

+    

+    if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {

+      //

+      // Check to see if the 2 second timer has expired

+      //

+      TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);

+      if (!EFI_ERROR (TimerStatus)) {

+        UnicodeToEfiKeyFlushState (TerminalDevice);

+        TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+      }

+    }

+

+    //

+    // Fetch one Unicode character from the Unicode FIFO

+    //

+    UnicodeFiFoRemoveOneKey (TerminalDevice,&UnicodeChar);

+

+    SetDefaultResetState = TRUE;

+

+    switch (TerminalDevice->InputState) {

+    case INPUT_STATE_DEFAULT:

+

+      break;

+

+    case INPUT_STATE_ESC:

+

+      if (UnicodeChar == LEFTOPENBRACKET) {

+        TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET;

+        TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+        continue;

+      }

+

+      if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100Type) {

+        TerminalDevice->InputState |= INPUT_STATE_O;

+        TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+        continue;

+      }

+

+      Key.ScanCode = SCAN_NULL;

+      

+      if (TerminalDevice->TerminalType == VT100PlusType || 

+          TerminalDevice->TerminalType == VTUTF8Type) {

+        switch (UnicodeChar) {

+        case '1': 

+          Key.ScanCode = SCAN_F1;         

+          break;

+        case '2': 

+          Key.ScanCode = SCAN_F2;         

+          break;

+        case '3': 

+          Key.ScanCode = SCAN_F3;         

+          break;

+        case '4': 

+          Key.ScanCode = SCAN_F4;         

+          break;

+        case '5': 

+          Key.ScanCode = SCAN_F5;         

+          break;

+        case '6': 

+          Key.ScanCode = SCAN_F6;         

+          break;

+        case '7': 

+          Key.ScanCode = SCAN_F7;         

+          break;

+        case '8': 

+          Key.ScanCode = SCAN_F8;         

+          break;

+        case '9': 

+          Key.ScanCode = SCAN_F9;         

+          break;

+        case '0': 

+          Key.ScanCode = SCAN_F10;        

+          break;

+        case 'h': 

+          Key.ScanCode = SCAN_HOME;       

+          break;

+        case 'k': 

+          Key.ScanCode = SCAN_END;        

+          break;

+        case '+': 

+          Key.ScanCode = SCAN_INSERT;     

+          break;

+        case '-': 

+          Key.ScanCode = SCAN_DELETE;     

+          break;

+        case '/': 

+          Key.ScanCode = SCAN_PAGE_DOWN;  

+          break;

+        case '?': 

+          Key.ScanCode = SCAN_PAGE_UP;    

+          break;        

+        default :                                 

+          break;

+        }

+      }

+      

+      switch (UnicodeChar) {

+      case 'R': 

+        if (TerminalDevice->ResetState == RESET_STATE_DEFAULT) {

+          TerminalDevice->ResetState = RESET_STATE_ESC_R;

+          SetDefaultResetState = FALSE;

+        } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_r) {

+          gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);

+        }

+        Key.ScanCode = SCAN_NULL;

+        break;

+      case 'r': 

+        if (TerminalDevice->ResetState == RESET_STATE_ESC_R) {

+          TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_r;

+          SetDefaultResetState = FALSE;

+        }

+        Key.ScanCode = SCAN_NULL;

+        break;

+      default : 

+        break;

+      }

+

+      if (SetDefaultResetState) {

+        TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+      }

+

+      if (Key.ScanCode != SCAN_NULL) {

+        Key.UnicodeChar = 0;

+        EfiKeyFiFoInsertOneKey (TerminalDevice,Key);

+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;

+        UnicodeToEfiKeyFlushState (TerminalDevice);

+        continue;

+      }

+

+      UnicodeToEfiKeyFlushState (TerminalDevice);

+

+      break;

+

+    case INPUT_STATE_ESC | INPUT_STATE_O:

+

+      TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+

+      Key.ScanCode = SCAN_NULL;

+      

+      if (TerminalDevice->TerminalType == VT100Type) {

+        switch (UnicodeChar) {

+        case 'P': 

+          Key.ScanCode = SCAN_F1;         

+          break;

+        case 'Q': 

+          Key.ScanCode = SCAN_F2;         

+          break;

+        case 'w': 

+          Key.ScanCode = SCAN_F3;         

+          break;

+        case 'x': 

+          Key.ScanCode = SCAN_F4;         

+          break;

+        case 't': 

+          Key.ScanCode = SCAN_F5;         

+          break;

+        case 'u': 

+          Key.ScanCode = SCAN_F6;         

+          break;

+        case 'q': 

+          Key.ScanCode = SCAN_F7;         

+          break;

+        case 'r': 

+          Key.ScanCode = SCAN_F8;         

+          break;

+        case 'p': 

+          Key.ScanCode = SCAN_F9;         

+          break;

+        case 'M': 

+          Key.ScanCode = SCAN_F10;        

+          break;

+        default :                                 

+          break;

+        }

+      }

+

+      if (Key.ScanCode != SCAN_NULL) {

+        Key.UnicodeChar = 0;

+        EfiKeyFiFoInsertOneKey (TerminalDevice,Key);

+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;

+        UnicodeToEfiKeyFlushState (TerminalDevice);

+        continue;

+      }

+

+      UnicodeToEfiKeyFlushState (TerminalDevice);

+

+      break;

+

+    case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET:

+    

+      TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+      

+      Key.ScanCode = SCAN_NULL;

+      

+      if (TerminalDevice->TerminalType == PcAnsiType    ||

+          TerminalDevice->TerminalType == VT100Type     ||

+          TerminalDevice->TerminalType == VT100PlusType || 

+          TerminalDevice->TerminalType == VTUTF8Type) {

+        switch (UnicodeChar) {

+        case 'A': 

+          Key.ScanCode = SCAN_UP;         

+          break;

+        case 'B': 

+          Key.ScanCode = SCAN_DOWN;       

+          break;

+        case 'C': 

+          Key.ScanCode = SCAN_RIGHT;      

+          break;

+        case 'D': 

+          Key.ScanCode = SCAN_LEFT;       

+          break;

+        case 'H': 

+          if (TerminalDevice->TerminalType == PcAnsiType ||

+              TerminalDevice->TerminalType == VT100Type) {

+            Key.ScanCode = SCAN_HOME;       

+          }

+          break;

+        case 'F': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_END;

+          }

+          break;

+        case 'K': 

+          if (TerminalDevice->TerminalType == VT100Type) {

+            Key.ScanCode = SCAN_END;        

+          }

+          break;

+        case 'L':   

+        case '@': 

+          if (TerminalDevice->TerminalType == PcAnsiType ||

+              TerminalDevice->TerminalType == VT100Type) {

+            Key.ScanCode = SCAN_INSERT;     

+          }

+          break;

+        case 'X': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_DELETE;

+          }

+          break;

+        case 'P': 

+          if (TerminalDevice->TerminalType == VT100Type) {

+            Key.ScanCode = SCAN_DELETE;        

+          } else if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F4;

+          }

+          break;

+        case 'I': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_PAGE_UP;

+          }

+          break;        

+        case 'V': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F10;

+          }  

+        case '?': 

+          if (TerminalDevice->TerminalType == VT100Type) {

+            Key.ScanCode = SCAN_PAGE_UP;        

+          }

+          break;

+        case 'G': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_PAGE_DOWN;

+          }

+          break;        

+        case 'U': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F9;

+          }

+        case '/': 

+          if (TerminalDevice->TerminalType == VT100Type) {

+            Key.ScanCode = SCAN_PAGE_DOWN;        

+          }

+          break;

+        case 'M': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F1;

+          }

+          break;        

+        case 'N': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F2;

+          }

+          break;        

+        case 'O': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F3;

+          }

+          break;        

+        case 'Q': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F5;

+          }

+          break;        

+        case 'R': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F6;

+          }

+          break;        

+        case 'S': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F7;

+          }

+          break;        

+        case 'T': 

+          if (TerminalDevice->TerminalType == PcAnsiType) {

+            Key.ScanCode = SCAN_F8;

+          }

+          break;        

+        default : 

+          break;

+        }

+      }

+

+      if (Key.ScanCode != SCAN_NULL) {

+        Key.UnicodeChar = 0;

+        EfiKeyFiFoInsertOneKey (TerminalDevice,Key);

+        TerminalDevice->InputState = INPUT_STATE_DEFAULT;

+        UnicodeToEfiKeyFlushState (TerminalDevice);

+        continue;

+      }

+

+      UnicodeToEfiKeyFlushState (TerminalDevice);

+

+      break;

+

+    

+    default:

+      //

+      // Invalid state. This should never happen.

+      //

+      ASSERT (FALSE);

+

+      UnicodeToEfiKeyFlushState (TerminalDevice);

+

+      break;

+    }

+

+    if (UnicodeChar == ESC) {

+      TerminalDevice->InputState = INPUT_STATE_ESC;

+    }

+    

+    if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {

+      Status = gBS->SetTimer(

+                      TerminalDevice->TwoSecondTimeOut,

+                      TimerRelative,

+                      (UINT64)20000000

+                      );

+      continue;

+    }

+

+    if (SetDefaultResetState) {

+      TerminalDevice->ResetState = RESET_STATE_DEFAULT;

+    }

+

+    if (UnicodeChar == DEL) {

+      Key.ScanCode    = SCAN_DELETE;

+      Key.UnicodeChar = 0;

+    } else {

+      Key.ScanCode    = SCAN_NULL;

+      Key.UnicodeChar = UnicodeChar;

+    }

+

+    EfiKeyFiFoInsertOneKey (TerminalDevice,Key);

+  }

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/TerminalConOut.c b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/TerminalConOut.c
new file mode 100644
index 0000000..4d98e59
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/TerminalConOut.c
@@ -0,0 +1,997 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    TerminalConOut.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+

+#include "Terminal.h"

+#include <Common/StatusCode.h>

+

+//

+// This list is used to define the valid extend chars.

+// It also provides a mapping from Unicode to PCANSI or

+// ASCII. The ASCII mapping we just made up.

+//

+//

+STATIC UNICODE_TO_CHAR  UnicodeToPcAnsiOrAscii[] = {

+  { BOXDRAW_HORIZONTAL,                 0xc4, L'-' }, 

+  { BOXDRAW_VERTICAL,                   0xb3, L'|' },

+  { BOXDRAW_DOWN_RIGHT,                 0xda, L'/' },

+  { BOXDRAW_DOWN_LEFT,                  0xbf, L'\\' },

+  { BOXDRAW_UP_RIGHT,                   0xc0, L'\\' },

+  { BOXDRAW_UP_LEFT,                    0xd9, L'/' },

+  { BOXDRAW_VERTICAL_RIGHT,             0xc3, L'|' },

+  { BOXDRAW_VERTICAL_LEFT,              0xb4, L'|' },

+  { BOXDRAW_DOWN_HORIZONTAL,            0xc2, L'+' },

+  { BOXDRAW_UP_HORIZONTAL,              0xc1, L'+' },

+  { BOXDRAW_VERTICAL_HORIZONTAL,        0xc5, L'+' },

+  { BOXDRAW_DOUBLE_HORIZONTAL,          0xcd, L'-' },

+  { BOXDRAW_DOUBLE_VERTICAL,            0xba, L'|' },

+  { BOXDRAW_DOWN_RIGHT_DOUBLE,          0xd5, L'/' },

+  { BOXDRAW_DOWN_DOUBLE_RIGHT,          0xd6, L'/' },

+  { BOXDRAW_DOUBLE_DOWN_RIGHT,          0xc9, L'/' },

+  { BOXDRAW_DOWN_LEFT_DOUBLE,           0xb8, L'\\' },

+  { BOXDRAW_DOWN_DOUBLE_LEFT,           0xb7, L'\\' },

+  { BOXDRAW_DOUBLE_DOWN_LEFT,           0xbb, L'\\' },

+  { BOXDRAW_UP_RIGHT_DOUBLE,            0xd4, L'\\' },

+  { BOXDRAW_UP_DOUBLE_RIGHT,            0xd3, L'\\' },

+  { BOXDRAW_DOUBLE_UP_RIGHT,            0xc8, L'\\' },

+  { BOXDRAW_UP_LEFT_DOUBLE,             0xbe, L'/' },

+  { BOXDRAW_UP_DOUBLE_LEFT,             0xbd, L'/' },

+  { BOXDRAW_DOUBLE_UP_LEFT,             0xbc, L'/' },

+  { BOXDRAW_VERTICAL_RIGHT_DOUBLE,      0xc6, L'|' },

+  { BOXDRAW_VERTICAL_DOUBLE_RIGHT,      0xc7, L'|' },

+  { BOXDRAW_DOUBLE_VERTICAL_RIGHT,      0xcc, L'|' },

+  { BOXDRAW_VERTICAL_LEFT_DOUBLE,       0xb5, L'|' },

+  { BOXDRAW_VERTICAL_DOUBLE_LEFT,       0xb6, L'|' },

+  { BOXDRAW_DOUBLE_VERTICAL_LEFT,       0xb9, L'|' },

+  { BOXDRAW_DOWN_HORIZONTAL_DOUBLE,     0xd1, L'+' },

+  { BOXDRAW_DOWN_DOUBLE_HORIZONTAL,     0xd2, L'+' },

+  { BOXDRAW_DOUBLE_DOWN_HORIZONTAL,     0xcb, L'+' },

+  { BOXDRAW_UP_HORIZONTAL_DOUBLE,       0xcf, L'+' },

+  { BOXDRAW_UP_DOUBLE_HORIZONTAL,       0xd0, L'+' },

+  { BOXDRAW_DOUBLE_UP_HORIZONTAL,       0xca, L'+' },

+  { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+' },

+  { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+' },

+  { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+' },

+

+  { BLOCKELEMENT_FULL_BLOCK,            0xdb, L'*' },

+  { BLOCKELEMENT_LIGHT_SHADE,           0xb0, L'+' },

+

+  { GEOMETRICSHAPE_UP_TRIANGLE,         0x1e, L'^' },

+  { GEOMETRICSHAPE_RIGHT_TRIANGLE,      0x10, L'>' },

+  { GEOMETRICSHAPE_DOWN_TRIANGLE,       0x1f, L'v' },

+  { GEOMETRICSHAPE_LEFT_TRIANGLE,       0x11, L'<' },

+

+  {  ARROW_LEFT,                         0x3c, L'<' },

+  {  ARROW_UP,                           0x18, L'^' },

+  {  ARROW_RIGHT,                        0x3e, L'>' },

+  {  ARROW_DOWN,                         0x19, L'v' },

+

+  { 0x0000,                             0x00, L'\0' }

+};

+

+CHAR16 mSetModeString[]            = { ESC, '[', '=', '3', 'h', 0 };

+CHAR16 mSetAttributeString[]       = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };

+CHAR16 mClearScreenString[]        = { ESC, '[', '2', 'J', 0 };

+CHAR16 mSetCursorPositionString[]  = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 };

+

+//

+// Body of the ConOut functions

+//

+EFI_STATUS

+EFIAPI

+TerminalConOutReset (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  BOOLEAN                       ExtendedVerification

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.Reset().

+    If ExtendeVerification is TRUE, then perform dependent serial device reset,

+    and set display mode to mode 0.

+    If ExtendedVerification is FALSE, only set display mode to mode 0.

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    ExtendedVerification - Indicates that the driver may perform a more exhaustive

+                           verification operation of the device during reset.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The reset operation succeeds.   

+    

+    EFI_DEVICE_ERROR

+      The terminal is not functioning correctly or the serial port reset fails.

+                

+--*/

+{

+  EFI_STATUS    Status;

+  TERMINAL_DEV  *TerminalDevice;

+

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  //

+  // Perform a more exhaustive reset by resetting the serial port.

+  //

+  if (ExtendedVerification) {

+    //

+    // Report progress code here

+    //

+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+      EFI_PROGRESS_CODE,

+      EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET,

+      TerminalDevice->DevicePath

+      );

+

+    Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);

+    if (EFI_ERROR (Status)) {

+      //

+      // Report error code here

+      //

+      REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+        EFI_ERROR_CODE | EFI_ERROR_MINOR,

+        EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,

+        TerminalDevice->DevicePath

+        );

+

+      return Status;

+    }

+  }

+

+  This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));

+

+  Status = This->SetMode (This, 0);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutOutputString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.OutputString().

+    The Unicode string will be converted to terminal expressible data stream

+    and send to terminal via serial port.

+    

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    WString - The Null-terminated Unicode string to be displayed on 

+              the terminal screen.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The string is output successfully.   

+    

+    EFI_DEVICE_ERROR

+      The serial port fails to send the string out.

+      

+    EFI_WARN_UNKNOWN_GLYPH

+      Indicates that some of the characters in the Unicode string could not 

+      be rendered and are skipped.          

+      

+    EFI_UNSUPPORTED

+                

+--*/

+{

+  TERMINAL_DEV                *TerminalDevice;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;

+  UINTN                       MaxColumn;

+  UINTN                       MaxRow;

+  UINTN                       Length;

+  UTF8_CHAR                   Utf8Char;

+  CHAR8                       GraphicChar;

+  CHAR8                       AsciiChar;

+  EFI_STATUS                  Status;

+  UINT8                       ValidBytes;

+  //

+  //  flag used to indicate whether condition happens which will cause

+  //  return EFI_WARN_UNKNOWN_GLYPH

+  //

+  BOOLEAN                     Warning;

+

+  ValidBytes  = 0;

+  Warning     = FALSE;

+

+  //

+  //  get Terminal device data structure pointer.

+  //

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  //

+  //  get current display mode

+  //  Terminal driver only support mode 0

+  //

+  Mode = This->Mode;

+  if (Mode->Mode != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  This->QueryMode (

+          This,

+          Mode->Mode,

+          &MaxColumn,

+          &MaxRow

+          );

+

+  for (; *WString != CHAR_NULL; WString++) {

+

+    switch (TerminalDevice->TerminalType) {

+

+    case PcAnsiType:

+    case VT100Type:

+    case VT100PlusType:

+

+      if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {

+        //

+        // If it's not a graphic character convert Unicode to ASCII.

+        //

+        GraphicChar = (CHAR8) *WString;

+

+        if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {

+          //

+          // when this driver use the OutputString to output control string,

+          // TerminalDevice->OutputEscChar is set to let the Esc char

+          // to be output to the terminal emulation software.

+          //

+          if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {

+            GraphicChar = 27;

+          } else {

+            GraphicChar = '?';

+            Warning     = TRUE;

+          }

+        }

+

+        AsciiChar = GraphicChar;

+

+      }

+

+      if (TerminalDevice->TerminalType != PcAnsiType) {

+        GraphicChar = AsciiChar;

+      }

+

+      Length = 1;

+

+      Status = TerminalDevice->SerialIo->Write (

+                                          TerminalDevice->SerialIo,

+                                          &Length,

+                                          &GraphicChar

+                                          );

+

+      if (EFI_ERROR (Status)) {

+        goto OutputError;

+      }

+

+      break;

+

+    case VTUTF8Type:

+      UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);

+      Length = ValidBytes;

+      Status = TerminalDevice->SerialIo->Write (

+                                          TerminalDevice->SerialIo,

+                                          &Length,

+                                          (UINT8 *) &Utf8Char

+                                          );

+      if (EFI_ERROR (Status)) {

+        goto OutputError;

+      }

+      break;

+    }

+    //

+    //  Update cursor position.

+    //

+    switch (*WString) {

+

+    case CHAR_BACKSPACE:

+      if (Mode->CursorColumn > 0) {

+        Mode->CursorColumn--;

+      }

+      break;

+

+    case CHAR_LINEFEED:

+      if (Mode->CursorRow < (INT32) (MaxRow - 1)) {

+        Mode->CursorRow++;

+      }

+      break;

+

+    case CHAR_CARRIAGE_RETURN:

+      Mode->CursorColumn = 0;

+      break;

+

+    default:

+      if (Mode->CursorColumn < (INT32) (MaxColumn - 1)) {

+

+        Mode->CursorColumn++;

+

+      } else {

+

+        Mode->CursorColumn = 0;

+        if (Mode->CursorRow < (INT32) (MaxRow - 1)) {

+          Mode->CursorRow++;

+        }

+

+      }

+      break;

+

+    };

+

+  }

+

+  if (Warning) {

+    return EFI_WARN_UNKNOWN_GLYPH;

+  }

+

+  return EFI_SUCCESS;

+

+OutputError:

+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (

+    EFI_ERROR_CODE | EFI_ERROR_MINOR,

+    EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_OUTPUT_ERROR,

+    TerminalDevice->DevicePath

+    );

+

+  return EFI_DEVICE_ERROR;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutTestString (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  CHAR16                        *WString

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.TestString().

+    If one of the characters in the *Wstring is

+    neither valid Unicode drawing characters,

+    not ASCII code, then this function will return

+    EFI_UNSUPPORTED.

+        

+  

+  Arguments:

+  

+    This - Indicates the calling context.

+    

+    WString - The Null-terminated Unicode string to be tested.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The terminal is capable of rendering the output string. 

+    

+    EFI_UNSUPPORTED

+      Some of the characters in the Unicode string cannot be rendered.      

+                

+--*/

+{

+  TERMINAL_DEV  *TerminalDevice;

+  EFI_STATUS    Status;

+

+  //

+  //  get Terminal device data structure pointer.

+  //

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  switch (TerminalDevice->TerminalType) {

+

+  case PcAnsiType:

+  case VT100Type:

+  case VT100PlusType:

+    Status = AnsiTestString (TerminalDevice, WString);

+    break;

+

+  case VTUTF8Type:

+    Status = VTUTF8TestString (TerminalDevice, WString);

+    break;

+

+  default:

+    Status = EFI_UNSUPPORTED;

+    break;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutQueryMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber,

+  OUT UINTN                         *Columns,

+  OUT UINTN                         *Rows

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.QueryMode().

+    It returns information for an available text mode

+    that the terminal supports.

+    In this driver, we only support text mode 80x25, which is

+    defined as mode 0.

+        

+  

+  Arguments:

+  

+    *This

+        Indicates the calling context.

+    

+    ModeNumber

+        The mode number to return information on.

+        

+    Columns

+        The returned columns of the requested mode.

+        

+    Rows

+        The returned rows of the requested mode.                

+        

+  Returns:

+  

+    EFI_SUCCESS

+      The requested mode information is returned. 

+    

+    EFI_UNSUPPORTED

+      The mode number is not valid.   

+      

+    EFI_DEVICE_ERROR

+                

+--*/

+{

+  if (This->Mode->MaxMode > 1) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (ModeNumber == 0) {

+

+    *Columns  = MODE0_COLUMN_COUNT;

+    *Rows     = MODE0_ROW_COUNT;

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutSetMode (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         ModeNumber

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT.SetMode().

+    Set the terminal to a specified display mode.

+    In this driver, we only support mode 0.        

+  

+  Arguments:

+  

+    This

+        Indicates the calling context.

+    

+    ModeNumber

+        The text mode to set.

+        

+  Returns:

+  

+    EFI_SUCCESS

+       The requested text mode is set.

+       

+    EFI_DEVICE_ERROR

+      The requested text mode cannot be set because of serial device error.

+    

+    EFI_UNSUPPORTED

+      The text mode number is not valid.       

+                

+--*/

+{

+  EFI_STATUS    Status;

+  TERMINAL_DEV  *TerminalDevice;

+

+  //

+  //  get Terminal device data structure pointer.

+  //

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  if (ModeNumber != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  This->Mode->Mode = 0;

+

+  This->ClearScreen (This);

+

+  TerminalDevice->OutputEscChar = TRUE;

+  Status                        = This->OutputString (This, mSetModeString);

+  TerminalDevice->OutputEscChar = FALSE;

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  This->Mode->Mode  = 0;

+

+  Status            = This->ClearScreen (This);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutSetAttribute (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Attribute

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.SetAttribute().       

+  

+  Arguments:

+  

+    This

+        Indicates the calling context.

+    

+    Attribute

+        The attribute to set. Only bit0..6 are valid, all other bits

+        are undefined and must be zero.

+        

+  Returns:

+  

+    EFI_SUCCESS

+      The requested attribute is set. 

+       

+    EFI_DEVICE_ERROR

+      The requested attribute cannot be set due to serial port error.

+          

+    EFI_UNSUPPORTED

+      The attribute requested is not defined by EFI spec.   

+                

+--*/

+{

+  UINT8         ForegroundControl;

+  UINT8         BackgroundControl;

+  UINT8         BrightControl;

+  INT32         SavedColumn;

+  INT32         SavedRow;

+  EFI_STATUS    Status;

+  TERMINAL_DEV  *TerminalDevice;

+

+  SavedColumn = 0;

+  SavedRow    = 0;

+

+  //

+  //  get Terminal device data structure pointer.

+  //

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  //

+  //  only the bit0..6 of the Attribute is valid

+  //

+  if ((Attribute | 0x7f) != 0x7f) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  //  convert Attribute value to terminal emulator

+  //  understandable foreground color

+  //

+  switch (Attribute & 0x07) {

+

+  case EFI_BLACK:

+    ForegroundControl = 30;

+    break;

+

+  case EFI_BLUE:

+    ForegroundControl = 34;

+    break;

+

+  case EFI_GREEN:

+    ForegroundControl = 32;

+    break;

+

+  case EFI_CYAN:

+    ForegroundControl = 36;

+    break;

+

+  case EFI_RED:

+    ForegroundControl = 31;

+    break;

+

+  case EFI_MAGENTA:

+    ForegroundControl = 35;

+    break;

+

+  case EFI_BROWN:

+    ForegroundControl = 33;

+    break;

+

+  default:

+

+  case EFI_LIGHTGRAY:

+    ForegroundControl = 37;

+    break;

+

+  }

+  //

+  //  bit4 of the Attribute indicates bright control

+  //  of terminal emulator.

+  //

+  BrightControl = (UINT8) ((Attribute >> 3) & 1);

+

+  //

+  //  convert Attribute value to terminal emulator

+  //  understandable background color.

+  //

+  switch ((Attribute >> 4) & 0x07) {

+

+  case EFI_BLACK:

+    BackgroundControl = 40;

+    break;

+

+  case EFI_BLUE:

+    BackgroundControl = 44;

+    break;

+

+  case EFI_GREEN:

+    BackgroundControl = 42;

+    break;

+

+  case EFI_CYAN:

+    BackgroundControl = 46;

+    break;

+

+  case EFI_RED:

+    BackgroundControl = 41;

+    break;

+

+  case EFI_MAGENTA:

+    BackgroundControl = 45;

+    break;

+

+  case EFI_BROWN:

+    BackgroundControl = 43;

+    break;

+

+  default:

+

+  case EFI_LIGHTGRAY:

+    BackgroundControl = 47;

+    break;

+  }

+  //

+  // terminal emulator's control sequence to set attributes

+  //

+  mSetAttributeString[BRIGHT_CONTROL_OFFSET]          = (CHAR16) ('0' + BrightControl);

+  mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0]  = (CHAR16) ('0' + (ForegroundControl / 10));

+  mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1]  = (CHAR16) ('0' + (ForegroundControl % 10));

+  mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0]  = (CHAR16) ('0' + (BackgroundControl / 10));

+  mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1]  = (CHAR16) ('0' + (BackgroundControl % 10));

+

+  //

+  // save current column and row

+  // for future scrolling back use.

+  //

+  SavedColumn                   = This->Mode->CursorColumn;

+  SavedRow                      = This->Mode->CursorRow;

+

+  TerminalDevice->OutputEscChar = TRUE;

+  Status                        = This->OutputString (This, mSetAttributeString);

+  TerminalDevice->OutputEscChar = FALSE;

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //  scroll back to saved cursor position.

+  //

+  This->Mode->CursorColumn  = SavedColumn;

+  This->Mode->CursorRow     = SavedRow;

+

+  This->Mode->Attribute     = (INT32) Attribute;

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutClearScreen (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.ClearScreen().

+    It clears the ANSI terminal's display to the 

+    currently selected background color.

+        

+  

+  Arguments:

+  

+    This

+        Indicates the calling context.

+

+  Returns:

+  

+    EFI_SUCCESS

+      The operation completed successfully.

+       

+    EFI_DEVICE_ERROR

+      The terminal screen cannot be cleared due to serial port error.        

+    

+    EFI_UNSUPPORTED

+      The terminal is not in a valid display mode.       

+                

+--*/

+{

+  EFI_STATUS    Status;

+  TERMINAL_DEV  *TerminalDevice;

+

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  //

+  //  control sequence for clear screen request

+  //

+  TerminalDevice->OutputEscChar = TRUE;

+  Status                        = This->OutputString (This, mClearScreenString);

+  TerminalDevice->OutputEscChar = FALSE;

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = This->SetCursorPosition (This, 0, 0);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutSetCursorPosition (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  UINTN                         Column,

+  IN  UINTN                         Row

+  )

+/*++

+  Routine Description:

+  

+    Implements EFI_SIMPLE_TEXT_OUT_PROTOCOL.SetCursorPosition().          

+  

+  Arguments:

+  

+    This

+        Indicates the calling context.

+        

+    Column

+        The row to set cursor to.

+        

+    Row

+        The column to set cursor to.                

+

+  Returns:

+  

+    EFI_SUCCESS

+      The operation completed successfully.

+       

+    EFI_DEVICE_ERROR

+      The request fails due to serial port error.        

+    

+    EFI_UNSUPPORTED

+      The terminal is not in a valid text mode, or the cursor position

+      is invalid for current mode.     

+                

+--*/

+{

+  EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;

+  UINTN                       MaxColumn;

+  UINTN                       MaxRow;

+  EFI_STATUS                  Status;

+  TERMINAL_DEV                *TerminalDevice;

+

+  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

+

+  //

+  //  get current mode

+  //

+  Mode = This->Mode;

+

+  //

+  //  get geometry of current mode

+  //

+  Status = This->QueryMode (

+                  This,

+                  Mode->Mode,

+                  &MaxColumn,

+                  &MaxRow

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Column >= MaxColumn || Row >= MaxRow) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // control sequence to move the cursor

+  //

+  mSetCursorPositionString[ROW_OFFSET + 0]    = (CHAR16) ('0' + ((Row + 1) / 10));

+  mSetCursorPositionString[ROW_OFFSET + 1]    = (CHAR16) ('0' + ((Row + 1) % 10));

+  mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16) ('0' + ((Column + 1) / 10));

+  mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16) ('0' + ((Column + 1) % 10));

+

+  TerminalDevice->OutputEscChar               = TRUE;

+  Status = This->OutputString (This, mSetCursorPositionString);

+  TerminalDevice->OutputEscChar = FALSE;

+

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //  update current cursor position

+  //  in the Mode data structure.

+  //

+  Mode->CursorColumn  = (INT32) Column;

+  Mode->CursorRow     = (INT32) Row;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+TerminalConOutEnableCursor (

+  IN  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,

+  IN  BOOLEAN                       Visible

+  )

+/*++

+  Routine Description:

+  

+    Implements SIMPLE_TEXT_OUTPUT.EnableCursor().

+    In this driver, the cursor cannot be hidden.        

+  

+  Arguments:

+  

+    This

+        Indicates the calling context.

+        

+    Visible

+        If TRUE, the cursor is set to be visible,

+        If FALSE, the cursor is set to be invisible.        

+

+  Returns:

+  

+    EFI_SUCCESS

+      The request is valid.

+       

+    EFI_UNSUPPORTED

+      The terminal does not support cursor hidden.   

+                

+--*/

+{

+  if (!Visible) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+TerminalIsValidTextGraphics (

+  IN  CHAR16  Graphic,

+  OUT CHAR8   *PcAnsi, OPTIONAL

+  OUT CHAR8   *Ascii OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+    Detects if a Unicode char is for Box Drawing text graphics.

+

+Arguments:

+

+    Graphic  - Unicode char to test.

+

+    PcAnsi  - Optional pointer to return PCANSI equivalent of Graphic.

+

+    Ascii   - Optional pointer to return ASCII equivalent of Graphic.

+

+Returns:

+

+    TRUE if Graphic is a supported Unicode Box Drawing character.

+

+--*/

+{

+  UNICODE_TO_CHAR *Table;

+

+  if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {

+    //

+    // Unicode drawing code charts are all in the 0x25xx range,

+    //  arrows are 0x21xx

+    //

+    return FALSE;

+  }

+

+  for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {

+    if (Graphic == Table->Unicode) {

+      if (PcAnsi != NULL) {

+        *PcAnsi = Table->PcAnsi;

+      }

+

+      if (Ascii != NULL) {

+        *Ascii = Table->Ascii;

+      }

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+TerminalIsValidAscii (

+  IN  CHAR16  Ascii

+  )

+{

+  //

+  // valid ascii code lies in the extent of 0x20 ~ 0x7f

+  //

+  if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+TerminalIsValidEfiCntlChar (

+  IN  CHAR16  CharC

+  )

+{

+  //

+  // only support four control characters.

+  //

+  if (CharC == CHAR_NULL ||

+      CharC == CHAR_BACKSPACE ||

+      CharC == CHAR_LINEFEED ||

+      CharC == CHAR_CARRIAGE_RETURN ||

+      CharC == CHAR_TAB

+      ) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/ansi.c b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/ansi.c
new file mode 100644
index 0000000..babc4bb
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/ansi.c
@@ -0,0 +1,68 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ansi.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+

+#include "Terminal.h"

+

+VOID

+AnsiRawDataToUnicode (

+  IN  TERMINAL_DEV    *TerminalDevice

+  )

+{

+  UINT8 RawData;

+

+  //

+  // pop the raw data out from the raw fifo,

+  // and translate it into unicode, then push

+  // the unicode into unicode fifo, until the raw fifo is empty.

+  //

+  while (!IsRawFiFoEmpty (TerminalDevice)) {

+

+    RawFiFoRemoveOneKey (TerminalDevice, &RawData);

+

+    UnicodeFiFoInsertOneKey (TerminalDevice, (UINT16) RawData);

+  }

+}

+

+EFI_STATUS

+AnsiTestString (

+  IN  TERMINAL_DEV    *TerminalDevice,

+  IN  CHAR16          *WString

+  )

+{

+  CHAR8 GraphicChar;

+

+  //

+  // support three kind of character:

+  // valid ascii, valid efi control char, valid text graphics.

+  //

+  for (; *WString != CHAR_NULL; WString++) {

+

+    if ( !(TerminalIsValidAscii (*WString) || 

+        TerminalIsValidEfiCntlChar (*WString) ||

+        TerminalIsValidTextGraphics (*WString, &GraphicChar, NULL) )) {

+

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/build.xml
new file mode 100644
index 0000000..e9d06dd
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Terminal"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Console/Terminal/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Terminal">

+      <GenBuild baseName="Terminal" mbdFilename="${MODULE_DIR}/Terminal.mbd" msaFilename="${MODULE_DIR}/Terminal.msa"/>

+   </target>

+   <target depends="Terminal_clean" name="clean"/>

+   <target depends="Terminal_cleanall" name="cleanall"/>

+   <target name="Terminal_clean">

+      <OutputDirSetup baseName="Terminal" mbdFilename="${MODULE_DIR}/Terminal.mbd" msaFilename="${MODULE_DIR}/Terminal.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Terminal_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Terminal_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Terminal_cleanall">

+      <OutputDirSetup baseName="Terminal" mbdFilename="${MODULE_DIR}/Terminal.mbd" msaFilename="${MODULE_DIR}/Terminal.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Terminal_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Terminal_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Terminal*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/vtutf8.c b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/vtutf8.c
new file mode 100644
index 0000000..062d0d4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Console/Terminal/Dxe/vtutf8.c
@@ -0,0 +1,270 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    vtutf8.c

+    

+Abstract: 

+    

+

+Revision History

+--*/

+

+

+#include "Terminal.h"

+

+VOID

+VTUTF8RawDataToUnicode (

+  IN  TERMINAL_DEV    *TerminalDevice

+  )

+{

+  UTF8_CHAR Utf8Char;

+  UINT8     ValidBytes;

+  UINT16    UnicodeChar;

+

+  ValidBytes = 0;

+  //

+  // pop the raw data out from the raw fifo,

+  // and translate it into unicode, then push

+  // the unicode into unicode fifo, until the raw fifo is empty.

+  //

+  while (!IsRawFiFoEmpty (TerminalDevice)) {

+

+    GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes);

+

+    if (ValidBytes < 1 || ValidBytes > 3) {

+      continue;

+    }

+

+    Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar);

+

+    UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar);

+  }

+}

+

+VOID

+GetOneValidUtf8Char (

+  IN  TERMINAL_DEV      *Utf8Device,

+  OUT UTF8_CHAR         *Utf8Char,

+  OUT UINT8             *ValidBytes

+  )

+{

+  UINT8   Temp;

+  UINT8   Index;

+  BOOLEAN FetchFlag;

+

+  Temp      = 0;

+  Index     = 0;

+  FetchFlag = TRUE;

+

+  //

+  // if no valid Utf8 char is found in the RawFiFo,

+  // then *ValidBytes will be zero.

+  //

+  *ValidBytes = 0;

+

+  while (!IsRawFiFoEmpty (Utf8Device)) {

+

+    RawFiFoRemoveOneKey (Utf8Device, &Temp);

+

+    switch (*ValidBytes) {

+

+    case 0:

+      if ((Temp & 0x80) == 0) {

+        //

+        // one-byte utf8 char

+        //

+        *ValidBytes       = 1;

+

+        Utf8Char->Utf8_1  = Temp;

+

+        FetchFlag         = FALSE;

+

+      } else if ((Temp & 0xe0) == 0xc0) {

+        //

+        // two-byte utf8 char

+        //

+        *ValidBytes         = 2;

+

+        Utf8Char->Utf8_2[1] = Temp;

+

+      } else if ((Temp & 0xf0) == 0xe0) {

+        //

+        // three-byte utf8 char

+        //

+        *ValidBytes         = 3;

+

+        Utf8Char->Utf8_3[2] = Temp;

+

+        Index++;

+

+      } else {

+        //

+        // reset *ValidBytes to zero, let valid utf8 char search restart

+        //

+        *ValidBytes = 0;

+      }

+

+      break;

+

+    case 2:

+      if ((Temp & 0xc0) == 0x80) {

+

+        Utf8Char->Utf8_2[0] = Temp;

+

+        FetchFlag           = FALSE;

+

+      } else {

+

+        *ValidBytes = 0;

+      }

+      break;

+

+    case 3:

+      if ((Temp & 0xc0) == 0x80) {

+

+        Utf8Char->Utf8_3[2 - Index] = Temp;

+        Index++;

+        if (Index == 3) {

+          FetchFlag = FALSE;

+        }

+      } else {

+

+        *ValidBytes = 0;

+        Index       = 0;

+      }

+      break;

+

+    default:

+      break;

+    }

+

+    if (!FetchFlag) {

+      break;

+    }

+  }

+

+  return ;

+}

+

+VOID

+Utf8ToUnicode (

+  IN  UTF8_CHAR       Utf8Char,

+  IN  UINT8           ValidBytes,

+  OUT CHAR16          *UnicodeChar

+  )

+{

+  UINT8 UnicodeByte0;

+  UINT8 UnicodeByte1;

+  UINT8 Byte0;

+  UINT8 Byte1;

+  UINT8 Byte2;

+

+  *UnicodeChar = 0;

+

+  //

+  // translate utf8 code to unicode, in terminal standard,

+  // up to 3 bytes utf8 code is supported.

+  //

+  switch (ValidBytes) {

+  case 1:

+    //

+    // one-byte utf8 code

+    //

+    *UnicodeChar = (UINT16) Utf8Char.Utf8_1;

+    break;

+

+  case 2:

+    //

+    // two-byte utf8 code

+    //

+    Byte0         = Utf8Char.Utf8_2[0];

+    Byte1         = Utf8Char.Utf8_2[1];

+

+    UnicodeByte0  = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));

+    UnicodeByte1  = (UINT8) ((Byte1 >> 2) & 0x07);

+    *UnicodeChar  = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));

+    break;

+

+  case 3:

+    //

+    // three-byte utf8 code

+    //

+    Byte0         = Utf8Char.Utf8_3[0];

+    Byte1         = Utf8Char.Utf8_3[1];

+    Byte2         = Utf8Char.Utf8_3[2];

+

+    UnicodeByte0  = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));

+    UnicodeByte1  = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f));

+    *UnicodeChar  = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));

+

+  default:

+    break;

+  }

+

+  return ;

+}

+

+VOID

+UnicodeToUtf8 (

+  IN  CHAR16      Unicode,

+  OUT UTF8_CHAR   *Utf8Char,

+  OUT UINT8       *ValidBytes

+  )

+{

+  UINT8 UnicodeByte0;

+  UINT8 UnicodeByte1;

+  //

+  // translate unicode to utf8 code

+  //

+  UnicodeByte0  = (UINT8) Unicode;

+  UnicodeByte1  = (UINT8) (Unicode >> 8);

+

+  if (Unicode < 0x0080) {

+

+    Utf8Char->Utf8_1  = (UINT8) (UnicodeByte0 & 0x7f);

+    *ValidBytes       = 1;

+

+  } else if (Unicode < 0x0800) {

+    //

+    // byte sequence: high -> low

+    //                Utf8_2[0], Utf8_2[1]

+    //

+    Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);

+    Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0);

+

+    *ValidBytes         = 2;

+

+  } else {

+    //

+    // byte sequence: high -> low

+    //                Utf8_3[0], Utf8_3[1], Utf8_3[2]

+    //

+    Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);

+    Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);

+    Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0);

+

+    *ValidBytes         = 3;

+  }

+}

+

+EFI_STATUS

+VTUTF8TestString (

+  IN  TERMINAL_DEV    *TerminalDevice,

+  IN  CHAR16          *WString

+  )

+{

+  //

+  // to utf8, all kind of characters are supported.

+  //

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c
new file mode 100644
index 0000000..01e7a6e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c
@@ -0,0 +1,655 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DataHub.c

+

+Abstract:

+

+  This code produces the Data Hub protocol. It preloads the data hub

+  with status information copied in from PEI HOBs.

+  

+  Only code that implements the Data Hub protocol should go in this file!

+

+  The Term MTC stands for MonoTonicCounter. 

+

+  For more information please look at DataHub.doc

+

+  NOTE: For extra security of the log GetNextDataRecord () could return a copy

+        of the data record.

+--*/

+

+#include "DataHub.h"

+

+CONST EFI_GUID gZeroGuid  = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };

+

+//

+// Worker functions private to this file

+//

+STATIC

+DATA_HUB_FILTER_DRIVER  *

+FindFilterDriverByEvent (

+  IN  LIST_ENTRY      *Head,

+  IN  EFI_EVENT       Event

+  );

+

+STATIC

+EFI_DATA_RECORD_HEADER  *

+GetNextDataRecord (

+  IN  LIST_ENTRY          *Head,

+  IN  UINT64              ClassFilter,

+  IN OUT  UINT64          *PtrCurrentMTC

+  );

+

+EFI_STATUS

+EFIAPI

+DataHubLogData (

+  IN  EFI_DATA_HUB_PROTOCOL   *This,

+  IN  EFI_GUID                *DataRecordGuid,

+  IN  EFI_GUID                *ProducerName,

+  IN  UINT64                  DataRecordClass,

+  IN  VOID                    *RawData,

+  IN  UINT32                  RawDataSize

+  )

+/*++

+

+Routine Description:

+

+  Log data record into the data logging hub

+

+Arguments:

+

+  This                - Protocol instance structure

+

+  DataRecordGuid      - GUID that defines record contents

+

+  ProducerName        - GUID that defines the name of the producer of the data

+

+  DataRecordClass     - Class that defines generic record type

+

+  RawData             - Data Log record as defined by DataRecordGuid

+  

+  RawDataSize         - Size of Data Log data in bytes

+

+Returns: 

+

+  EFI_SUCCESS           - If data was logged

+

+  EFI_OUT_OF_RESOURCES  - If data was not logged due to lack of system 

+                           resources.

+--*/

+{

+  EFI_STATUS              Status;

+  DATA_HUB_INSTANCE       *Private;

+  EFI_DATA_ENTRY          *LogEntry;

+  UINT32                  TotalSize;

+  UINT32                  RecordSize;

+  EFI_DATA_RECORD_HEADER  *Record;

+  VOID                    *Raw;

+  DATA_HUB_FILTER_DRIVER  *FilterEntry;

+  LIST_ENTRY              *Link;

+  LIST_ENTRY              *Head;

+

+  Private = DATA_HUB_INSTANCE_FROM_THIS (This);

+

+  //

+  // Combine the storage for the internal structs and a copy of the log record.

+  //  Record follows PrivateLogEntry. The consumer will be returned a pointer

+  //  to Record so we don't what it to be the thing that was allocated from

+  //  pool, so the consumer can't free an data record by mistake.

+  //

+  RecordSize  = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize;

+  TotalSize   = sizeof (EFI_DATA_ENTRY) + RecordSize;

+

+  //

+  // The Logging action is the critical section, so it is locked.

+  //  The MTC asignment & update, time, and logging must be an

+  //  atomic operation, so use the lock.

+  //

+  Status = EfiAcquireLockOrFail (&Private->DataLock);

+  if (EFI_ERROR (Status)) {

+    //

+    // Reentrancy detected so exit!

+    //

+    return Status;

+  }

+

+  Status = gBS->AllocatePool (EfiBootServicesData, TotalSize, (VOID **) &LogEntry);

+  if (EFI_ERROR (Status)) {

+    EfiReleaseLock (&Private->DataLock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  ZeroMem (LogEntry, TotalSize);

+

+  Record  = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1);

+  Raw     = (VOID *) (Record + 1);

+

+  //

+  // Build Standard Log Header

+  //

+  Record->Version     = EFI_DATA_RECORD_HEADER_VERSION;

+  Record->HeaderSize  = sizeof (EFI_DATA_RECORD_HEADER);

+  Record->RecordSize  = RecordSize;

+  CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID));

+  CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID));

+  Record->DataRecordClass   = DataRecordClass;

+

+  Record->LogMonotonicCount = Private->GlobalMonotonicCount++;

+

+  gRT->GetTime (&Record->LogTime, NULL);

+

+  //

+  // Insert log into the internal linked list.

+  //

+  LogEntry->Signature   = EFI_DATA_ENTRY_SIGNATURE;

+  LogEntry->Record      = Record;

+  LogEntry->RecordSize  = sizeof (EFI_DATA_ENTRY) + RawDataSize;

+  InsertTailList (&Private->DataListHead, &LogEntry->Link);

+

+  CopyMem (Raw, RawData, RawDataSize);

+

+  EfiReleaseLock (&Private->DataLock);

+

+  //

+  // Send Signal to all the filter drivers which are interested

+  //  in the record's class and guid.

+  //

+  Head = &Private->FilterDriverListHead;

+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {

+    FilterEntry = FILTER_ENTRY_FROM_LINK (Link);

+    if (((FilterEntry->ClassFilter & DataRecordClass) != 0) &&

+        (CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) || 

+         CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) {

+      gBS->SignalEvent (FilterEntry->Event);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DataHubGetNextRecord (

+  IN EFI_DATA_HUB_PROTOCOL            *This,

+  IN OUT UINT64                       *MonotonicCount,

+  IN EFI_EVENT                        *FilterDriverEvent, OPTIONAL

+  OUT EFI_DATA_RECORD_HEADER          **Record

+  )

+/*++

+

+Routine Description:

+

+  Get a previously logged data record and the MonotonicCount for the next

+  availible Record. This allows all records or all records later 

+  than a give MonotonicCount to be returned. If an optional FilterDriverEvent

+  is passed in with a MonotonicCout of zero return the first record 

+  not yet read by the filter driver. If FilterDriverEvent is NULL and 

+  MonotonicCount is zero return the first data record.

+

+Arguments:

+

+  This              - The EFI_DATA_HUB_PROTOCOL instance.

+  MonotonicCount    - Specifies the Record to return. On input, zero means

+                      return the first record. On output, contains the next

+                      record to availible. Zero indicates no more records.

+  FilterDriverEvent - If FilterDriverEvent is not passed in a MonotonicCount 

+                      of zero, it means to return the first data record. 

+                      If FilterDriverEvent is passed in, then a MonotonicCount 

+                      of zero means to return the first data not yet read by 

+                      FilterDriverEvent.

+  Record            - Returns a dynamically allocated memory buffer with a data 

+                      record that matches MonotonicCount.

+

+Returns: 

+

+  EFI_SUCCESS             - Data was returned in Record.

+  EFI_INVALID_PARAMETER   - FilterDriverEvent was passed in but does not exist.

+  EFI_NOT_FOUND           - MonotonicCount does not match any data record in the

+                            system. If a MonotonicCount of zero was passed in, then

+                            no data records exist in the system.

+  EFI_OUT_OF_RESOURCES    - Record was not returned due to lack of system resources.

+

+--*/

+{

+  DATA_HUB_INSTANCE       *Private;

+  DATA_HUB_FILTER_DRIVER  *FilterDriver;

+  UINT64                  ClassFilter;

+  UINT64                  FilterMonotonicCount;

+

+  Private               = DATA_HUB_INSTANCE_FROM_THIS (This);

+

+  FilterDriver          = NULL;

+  FilterMonotonicCount  = 0;

+  ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |

+    EFI_DATA_RECORD_CLASS_ERROR |

+    EFI_DATA_RECORD_CLASS_DATA |

+    EFI_DATA_RECORD_CLASS_PROGRESS_CODE;

+

+  if (FilterDriverEvent != NULL) {

+    //

+    // For events the beginning is the last unread record. This info is

+    // stored in the instance structure, so we must look up the event

+    // to get the data.

+    //

+    FilterDriver = FindFilterDriverByEvent (

+                    &Private->FilterDriverListHead,

+                    *FilterDriverEvent

+                    );

+    if (FilterDriver == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // Use the Class filter the event was created with.

+    //

+    ClassFilter = FilterDriver->ClassFilter;

+

+    if (*MonotonicCount == 0) {

+      //

+      // Use the MTC from the Filter Driver.

+      //

+      FilterMonotonicCount = FilterDriver->GetNextMonotonicCount;

+      if (FilterMonotonicCount != 0) {

+        //

+        // The GetNextMonotonicCount field remembers the last value from the previous time.

+        // But we already processed this vaule, so we need to find the next one. So if

+        // It is not the first time get the new record entry.

+        //

+        *Record         = GetNextDataRecord (&Private->DataListHead, ClassFilter, &FilterMonotonicCount);

+        *MonotonicCount = FilterMonotonicCount;

+        if (FilterMonotonicCount == 0) {

+          //

+          // If there is no new record to get exit now.

+          //

+          return EFI_NOT_FOUND;

+        }

+      }

+    }

+  }

+  //

+  // Return the record

+  //

+  *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);

+  if (*Record == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  if (FilterDriver != NULL) {

+    //

+    // If we have a filter driver update the records that have been read.

+    // If MonotonicCount is zero No more reacords left.

+    //

+    if (*MonotonicCount == 0) {

+      if (FilterMonotonicCount != 0) {

+        //

+        // Return the result of our extra GetNextDataRecord.

+        //

+        FilterDriver->GetNextMonotonicCount = FilterMonotonicCount;

+      }

+    } else {

+      //

+      // Point to next undread record

+      //

+      FilterDriver->GetNextMonotonicCount = *MonotonicCount;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DataHubRegisterFilterDriver (

+  IN EFI_DATA_HUB_PROTOCOL    * This,

+  IN EFI_EVENT                FilterEvent,

+  IN EFI_TPL                  FilterTpl,

+  IN UINT64                   FilterClass,

+  IN EFI_GUID                 * FilterDataRecordGuid OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  This function registers the data hub filter driver that is represented 

+  by FilterEvent. Only one instance of each FilterEvent can be registered.

+  After the FilterEvent is registered, it will be signaled so it can sync 

+  with data records that have been recorded prior to the FilterEvent being 

+  registered.

+    

+Arguments:

+

+  This                  - The EFI_DATA_HUB_PROTOCOL instance.

+  FilterEvent           - The EFI_EVENT to signal whenever data that matches 

+                          FilterClass is logged in the system.

+  FilterTpl             - The maximum EFI_TPL at which FilterEvent can be 

+                          signaled. It is strongly recommended that you use the 

+                          lowest EFI_TPL possible.

+  FilterClass           - FilterEvent will be signaled whenever a bit in 

+                          EFI_DATA_RECORD_HEADER.DataRecordClass is also set in 

+                          FilterClass. If FilterClass is zero, no class-based 

+                          filtering will be performed.

+  FilterDataRecordGuid  - FilterEvent will be signaled whenever FilterDataRecordGuid 

+                          matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If 

+                          FilterDataRecordGuid is NULL, then no GUID-based filtering 

+                          will be performed.              

+Returns: 

+

+  EFI_SUCCESS             - The filter driver event was registered.

+  EFI_ALREADY_STARTED     - FilterEvent was previously registered and cannot be 

+                            registered again.

+  EFI_OUT_OF_RESOURCES    - The filter driver event was not registered due to lack of 

+                            system resources.

+

+--*/

+{

+  DATA_HUB_INSTANCE       *Private;

+  DATA_HUB_FILTER_DRIVER  *FilterDriver;

+

+  Private       = DATA_HUB_INSTANCE_FROM_THIS (This);

+

+  FilterDriver  = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER));

+  if (FilterDriver == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Initialize filter driver info

+  //

+  FilterDriver->Signature             = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE;

+  FilterDriver->Event                 = FilterEvent;

+  FilterDriver->Tpl                   = FilterTpl;

+  FilterDriver->GetNextMonotonicCount = 0;

+  if (FilterClass == 0) {

+    FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |

+      EFI_DATA_RECORD_CLASS_ERROR |

+      EFI_DATA_RECORD_CLASS_DATA |

+      EFI_DATA_RECORD_CLASS_PROGRESS_CODE;

+  } else {

+    FilterDriver->ClassFilter = FilterClass;

+  }

+

+  if (FilterDataRecordGuid != NULL) {

+    CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));

+  }

+  //

+  // Search for duplicate entries

+  //

+  if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {

+    gBS->FreePool (FilterDriver);

+    return EFI_ALREADY_STARTED;

+  }

+  //

+  // Make insertion an atomic operation with the lock.

+  //

+  EfiAcquireLock (&Private->DataLock);

+  InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link);

+  EfiReleaseLock (&Private->DataLock);

+

+  //

+  // Signal the Filter driver we just loaded so they will recieve all the

+  // previous history. If we did not signal here we would have to wait until

+  // the next data was logged to get the history. In a case where no next

+  // data was logged we would never get synced up.

+  //

+  gBS->SignalEvent (FilterEvent);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DataHubUnregisterFilterDriver (

+  IN EFI_DATA_HUB_PROTOCOL    *This,

+  IN EFI_EVENT                FilterEvent

+  )

+/*++

+

+Routine Description:

+

+  Remove a Filter Driver, so it no longer gets called when data 

+   information is logged.

+

+Arguments:

+

+  This        - Protocol instance structure

+

+  FilterEvent - Event that represents a filter driver that is to be 

+                 Unregistered.

+

+Returns: 

+

+  EFI_SUCCESS   - If FilterEvent was unregistered

+

+  EFI_NOT_FOUND - If FilterEvent does not exist

+

+--*/

+{

+  DATA_HUB_INSTANCE       *Private;

+  DATA_HUB_FILTER_DRIVER  *FilterDriver;

+

+  Private = DATA_HUB_INSTANCE_FROM_THIS (This);

+

+  //

+  // Search for duplicate entries

+  //

+  FilterDriver = FindFilterDriverByEvent (

+                  &Private->FilterDriverListHead,

+                  FilterEvent

+                  );

+  if (FilterDriver == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Make removal an atomic operation with the lock

+  //

+  EfiAcquireLock (&Private->DataLock);

+  RemoveEntryList (&FilterDriver->Link);

+  EfiReleaseLock (&Private->DataLock);

+

+  return EFI_SUCCESS;

+}

+//

+// STATIC Worker fucntions follow

+//

+STATIC

+DATA_HUB_FILTER_DRIVER *

+FindFilterDriverByEvent (

+  IN  LIST_ENTRY      *Head,

+  IN  EFI_EVENT       Event

+  )

+/*++

+

+Routine Description:

+  Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that

+   represents Event and return it.

+

+Arguments:

+

+  Head  - Head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER

+           structures.

+

+  Event - Event to be search for in the Head list.

+

+Returns: 

+

+  EFI_DATA_HUB_FILTER_DRIVER - Returned if Event stored in the

+                               Head doubly linked list.

+

+  NULL - If Event is not in the list

+

+--*/

+{

+  DATA_HUB_FILTER_DRIVER  *FilterEntry;

+  LIST_ENTRY              *Link;

+

+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {

+    FilterEntry = FILTER_ENTRY_FROM_LINK (Link);

+    if (FilterEntry->Event == Event) {

+      return FilterEntry;

+    }

+  }

+

+  return NULL;

+}

+

+STATIC

+EFI_DATA_RECORD_HEADER *

+GetNextDataRecord (

+  IN  LIST_ENTRY          *Head,

+  IN  UINT64              ClassFilter,

+  IN OUT  UINT64          *PtrCurrentMTC

+  )

+/*++

+

+Routine Description:

+  Search the Head doubly linked list for the passed in MTC. Return the 

+   matching element in Head and the MTC on the next entry.

+

+Arguments:

+

+  Head          - Head of Data Log linked list.

+

+  ClassFilter   - Only match the MTC if it is in the same Class as the

+                  ClassFilter.

+

+  PtrCurrentMTC - On IN contians MTC to search for. On OUT contians next

+                   MTC in the data log list or zero if at end of the list.

+  

+Returns:

+

+  EFI_DATA_LOG_ENTRY - Return pointer to data log data from Head list.

+

+  NULL - If no data record exists.

+

+--*/

+{

+  EFI_DATA_ENTRY          *LogEntry;

+  LIST_ENTRY              *Link;

+  BOOLEAN                 ReturnFirstEntry;

+  EFI_DATA_RECORD_HEADER  *Record;

+  EFI_DATA_ENTRY          *NextLogEntry;

+

+  //

+  // If MonotonicCount == 0 just return the first one

+  //

+  ReturnFirstEntry  = (BOOLEAN) (*PtrCurrentMTC == 0);

+

+  Record            = NULL;

+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {

+    LogEntry = DATA_ENTRY_FROM_LINK (Link);

+    if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) {

+      //

+      // Skip any entry that does not have the correct ClassFilter

+      //

+      continue;

+    }

+

+    if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) {

+      //

+      // Return record to the user

+      //

+      Record = LogEntry->Record;

+

+      //

+      // Calculate the next MTC value. If there is no next entry set

+      // MTC to zero.

+      //

+      *PtrCurrentMTC = 0;

+      for (Link = Link->ForwardLink; Link != Head; Link = Link->ForwardLink) {

+        NextLogEntry = DATA_ENTRY_FROM_LINK (Link);

+        if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) {

+          //

+          // Return the MTC of the next thing to search for if found

+          //

+          *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount;

+          break;

+        }

+      }

+      //

+      // Record found exit loop and return

+      //

+      break;

+    }

+  }

+

+  return Record;

+}

+//

+// Module Global:

+//  Since this driver will only ever produce one instance of the Logging Hub

+//  protocol you are not required to dynamically allocate the PrivateData.

+//

+DATA_HUB_INSTANCE mPrivateData;

+

+EFI_STATUS

+EFIAPI

+DataHubInstall (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+  Install Driver to produce Data Hub protocol. 

+

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns: 

+

+  EFI_SUCCESS - Logging Hub protocol installed

+

+  Other       - No protocol installed, unload driver.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT32      HighMontonicCount;

+

+  mPrivateData.Signature                      = DATA_HUB_INSTANCE_SIGNATURE;

+  mPrivateData.DataHub.LogData                = DataHubLogData;

+  mPrivateData.DataHub.GetNextRecord          = DataHubGetNextRecord;

+  mPrivateData.DataHub.RegisterFilterDriver   = DataHubRegisterFilterDriver;

+  mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver;

+

+  //

+  // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is

+  //  required by this protocol

+  //

+  InitializeListHead (&mPrivateData.DataListHead);

+  InitializeListHead (&mPrivateData.FilterDriverListHead);

+

+  EfiInitializeLock (&mPrivateData.DataLock, EFI_TPL_NOTIFY);

+

+  //

+  // Make sure we get a bigger MTC number on every boot!

+  //

+  Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount);

+  if (EFI_ERROR (Status)) {

+    //

+    // if system service fails pick a sane value.

+    //

+    mPrivateData.GlobalMonotonicCount = 0;

+  } else {

+    mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32);

+  }

+  //

+  // Make a new handle and install the protocol

+  //

+  mPrivateData.Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &mPrivateData.Handle,

+                  &gEfiDataHubProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &mPrivateData.DataHub

+                  );

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.dxs b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.dxs
new file mode 100644
index 0000000..3483185
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DataHub.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.h b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.h
new file mode 100644
index 0000000..fb364a3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.h
@@ -0,0 +1,122 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DataHub.h

+

+Abstract:

+  This code supports a the private implementation 

+  of the Data Hub protocol

+

+--*/

+

+#ifndef _DATA_HUB_H_

+#define _DATA_HUB_H_

+

+

+#define DATA_HUB_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('D', 'H', 'u', 'b')

+typedef struct {

+  UINT32                Signature;

+

+  EFI_HANDLE            Handle;

+

+  //

+  // Produced protocol(s)

+  //

+  EFI_DATA_HUB_PROTOCOL DataHub;

+

+  //

+  // Private Data

+  //

+  //

+  // Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead

+  //  must be locked.

+  //

+  EFI_LOCK              DataLock;

+

+  //

+  // Runing Monotonic Count to use for each error record.

+  //  Increment AFTER use in an error record.

+  //

+  UINT64                GlobalMonotonicCount;

+

+  //

+  // List of EFI_DATA_ENTRY structures. This is the data log! The list

+  //  must be in assending order of LogMonotonicCount.

+  //

+  LIST_ENTRY            DataListHead;

+

+  //

+  // List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all

+  //  the registered filter drivers.

+  //

+  LIST_ENTRY            FilterDriverListHead;

+

+} DATA_HUB_INSTANCE;

+

+#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE)

+

+//

+// Private data structure to contain the data log. One record per

+//  structure. Head pointer to the list is the Log member of

+//  EFI_DATA_ENTRY. Record is a copy of the data passed in.

+//

+#define EFI_DATA_ENTRY_SIGNATURE  EFI_SIGNATURE_32 ('D', 'r', 'e', 'c')

+typedef struct {

+  UINT32                  Signature;

+  LIST_ENTRY              Link;

+

+  EFI_DATA_RECORD_HEADER  *Record;

+

+  UINTN                   RecordSize;

+

+} EFI_DATA_ENTRY;

+

+#define DATA_ENTRY_FROM_LINK(link)  CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE)

+

+//

+// Private data to contain the filter driver Event and it's

+//  associated EFI_TPL.

+//

+#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE  EFI_SIGNATURE_32 ('D', 'h', 'F', 'd')

+

+typedef struct {

+  UINT32          Signature;

+  LIST_ENTRY      Link;

+

+  //

+  // Store Filter Driver Event and Tpl level it can be Signaled at.

+  //

+  EFI_EVENT       Event;

+  EFI_TPL         Tpl;

+

+  //

+  // Monotonic count on the get next operation for Event.

+  //  Zero indicates get next has not been called for this event yet.

+  //

+  UINT64          GetNextMonotonicCount;

+

+  //

+  // Filter driver will register what class filter should be used.

+  //

+  UINT64          ClassFilter;

+

+  //

+  // Filter driver will register what record guid filter should be used.

+  //

+  EFI_GUID        FilterDataRecordGuid;

+

+} DATA_HUB_FILTER_DRIVER;

+

+#define FILTER_ENTRY_FROM_LINK(link)  CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE)

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.mbd b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.mbd
new file mode 100644
index 0000000..39b2c93
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>DataHub</BaseName>

+    <Guid>53BCC14F-C24F-434C-B294-8ED2D4CC1860</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.msa b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.msa
new file mode 100644
index 0000000..a337b81
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DataHub</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>53BCC14F-C24F-434C-B294-8ED2D4CC1860</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DataHub.c</Filename>

+    <Filename>DataHub.h</Filename>

+    <Filename>DataHub.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">DataHub</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>DataHubInstall</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/build.xml b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/build.xml
new file mode 100644
index 0000000..fcf00f8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHub/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DataHub"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/DataHub/DataHub/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DataHub">

+      <GenBuild baseName="DataHub" mbdFilename="${MODULE_DIR}/DataHub.mbd" msaFilename="${MODULE_DIR}/DataHub.msa"/>

+   </target>

+   <target depends="DataHub_clean" name="clean"/>

+   <target depends="DataHub_cleanall" name="cleanall"/>

+   <target name="DataHub_clean">

+      <OutputDirSetup baseName="DataHub" mbdFilename="${MODULE_DIR}/DataHub.mbd" msaFilename="${MODULE_DIR}/DataHub.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DataHub_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DataHub_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DataHub_cleanall">

+      <OutputDirSetup baseName="DataHub" mbdFilename="${MODULE_DIR}/DataHub.mbd" msaFilename="${MODULE_DIR}/DataHub.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DataHub_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DataHub_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DataHub*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c
new file mode 100644
index 0000000..1a392ab
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c
@@ -0,0 +1,163 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DataHubStdErr.c

+

+Abstract:

+

+  Data Hub filter driver that takes DEBUG () info from Data Hub and writes it 

+  to StdErr if it exists.

+

+--*/

+

+

+

+EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;

+

+EFI_EVENT             mDataHubStdErrEvent;

+

+STATIC

+VOID

+EFIAPI

+DataHubStdErrEventHandler (

+  IN EFI_EVENT Event,

+  IN VOID      *Context

+  )

+/*++

+

+Routine Description:

+  Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This

+  handler reads the Data Hub and sends any DEBUG info to StdErr.

+

+Arguments:

+  Event    - The event that occured, not used

+  Context  - DataHub Protocol Pointer

+  

+Returns:

+  None.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_DATA_HUB_PROTOCOL             *DataHub;

+  EFI_DATA_RECORD_HEADER            *Record;

+  DATA_HUB_STATUS_CODE_DATA_RECORD  *DataRecord;

+  UINT64                            Mtc;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL      *Sto;

+  INT32                             OldAttribute;

+

+  DataHub = (EFI_DATA_HUB_PROTOCOL *) Context;

+

+  //

+  // If StdErr is not yet initialized just return a DEBUG print in the BDS

+  // after consoles are connect will make sure data gets flushed properly

+  // when StdErr is availible.

+  //

+  if (gST == NULL) {

+    return ;

+  }

+

+  if (gST->StdErr == NULL) {

+    return ;

+  }

+  //

+  // Mtc of zero means return the next record that has not been read by the

+  // event handler.

+  //

+  Mtc = 0;

+  do {

+    Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record);

+    if (!EFI_ERROR (Status)) {

+      if (CompareGuid (&Record->DataRecordGuid, &gEfiStatusCodeGuid)) {

+        DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize);

+

+        if (DataRecord->Data.HeaderSize > 0) {

+          if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) {

+            //

+            // If the Data record is from a DEBUG () then send it to Standard Error

+            //

+            Sto           = gST->StdErr;

+            OldAttribute  = Sto->Mode->Attribute;

+            Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));

+            Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1));

+            Sto->SetAttribute (Sto, OldAttribute);

+          }

+        }

+      }

+    }

+  } while ((Mtc != 0) && !EFI_ERROR (Status));

+}

+

+EFI_STATUS

+EFIAPI

+DataHubStdErrInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This

+  handler reads the Data Hub and sends any DEBUG info to StdErr.

+

+Arguments:

+

+  ImageHandle - Image handle of this driver.

+  SystemTable - Pointer to EFI system table.

+

+Returns:

+

+  EFI_SUCCESS             - The event handler was registered.

+  EFI_OUT_OF_RESOURCES    - The event hadler was not registered due to lack of 

+                            system resources.

+  

+--*/

+{

+  EFI_STATUS  Status;

+  UINT64      DataClass;

+

+  gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub);

+  //

+  // Should never fail due to Depex grammer.

+  //

+  ASSERT (mDataHub != NULL);

+

+  //

+  // Create an event and register it with the filter driver

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  DataHubStdErrEventHandler,

+                  mDataHub,

+                  &mDataHubStdErrEvent

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR;

+  Status = mDataHub->RegisterFilterDriver (

+                      mDataHub,

+                      mDataHubStdErrEvent,

+                      EFI_TPL_CALLBACK,

+                      DataClass,

+                      NULL

+                      );

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (mDataHubStdErrEvent);

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.dxs b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.dxs
new file mode 100644
index 0000000..ac6fb1d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    DataHubStdErr.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+

+DEPENDENCY_START

+  EFI_DATA_HUB_PROTOCOL_GUID 

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.mbd b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.mbd
new file mode 100644
index 0000000..8d03e0c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+   <MbdHeader>

+    <BaseName>DataHubStdErr</BaseName>

+    <Guid>CA515306-00CE-4032-874E-11B755FF6866</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>    

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>BaseLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa
new file mode 100644
index 0000000..ac9417d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DataHubStdErr</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>CA515306-00CE-4032-874E-11B755FF6866</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>  

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DataHubStdErr.c</Filename>

+    <Filename>DataHubStdErr.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DataHub</Protocol>

+  </Protocols>  

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>StatusCode</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>StatusCodeDataTypeDebug</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>DataHubStdErrInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/build.xml b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/build.xml
new file mode 100644
index 0000000..e712520
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DataHubStdErr"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/DataHub/DataHubStdErr/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DataHubStdErr">

+      <GenBuild baseName="DataHubStdErr" mbdFilename="${MODULE_DIR}/DataHubStdErr.mbd" msaFilename="${MODULE_DIR}/DataHubStdErr.msa"/>

+   </target>

+   <target depends="DataHubStdErr_clean" name="clean"/>

+   <target depends="DataHubStdErr_cleanall" name="cleanall"/>

+   <target name="DataHubStdErr_clean">

+      <OutputDirSetup baseName="DataHubStdErr" mbdFilename="${MODULE_DIR}/DataHubStdErr.mbd" msaFilename="${MODULE_DIR}/DataHubStdErr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DataHubStdErr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DataHubStdErr_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DataHubStdErr_cleanall">

+      <OutputDirSetup baseName="DataHubStdErr" mbdFilename="${MODULE_DIR}/DataHubStdErr.mbd" msaFilename="${MODULE_DIR}/DataHubStdErr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DataHubStdErr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DataHubStdErr_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DataHubStdErr*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.c b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.c
new file mode 100644
index 0000000..118e9b7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.c
@@ -0,0 +1,151 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    DebugSupport.c

+

+Abstract:

+

+    Top level C file for debug support driver.  Contains initialization function.

+

+Revision History

+

+--*/

+

+//

+// private header files

+//

+#include "plDebugSupport.h"

+

+//

+// This is a global that is the actual interface

+//

+EFI_DEBUG_SUPPORT_PROTOCOL  gDebugSupportProtocolInterface = {

+  EFI_ISA,

+  GetMaximumProcessorIndex,

+  RegisterPeriodicCallback,

+  RegisterExceptionCallback,

+  InvalidateInstructionCache

+};

+

+//

+// Driver Entry Point

+//

+EFI_STATUS

+InitializeDebugSupportDriver (

+  IN EFI_HANDLE               ImageHandle,

+  IN EFI_SYSTEM_TABLE         *SystemTable

+  )

+/*++

+

+Routine Description:

+  Driver entry point.  Checks to see there's not already a DebugSupport protocol

+  installed for the selected processor before installing protocol.

+

+Arguments:

+  IN EFI_HANDLE               ImageHandle,

+  IN EFI_SYSTEM_TABLE         *SystemTable

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+// TODO:    ImageHandle - add argument and description to function comment

+// TODO:    SystemTable - add argument and description to function comment

+{

+  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImageProtocolPtr;

+  EFI_STATUS                  Status;

+  EFI_HANDLE                  Handle;

+  EFI_HANDLE                  *HandlePtr;

+  UINTN                       NumHandles;

+  EFI_DEBUG_SUPPORT_PROTOCOL  *DebugSupportProtocolPtr;

+

+  //

+  //  Install Protocol Interface...

+  //

+  // First check to see that the debug support protocol for this processor

+  // type is not already installed

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiDebugSupportProtocolGuid,

+                  NULL,

+                  &NumHandles,

+                  &HandlePtr

+                  );

+

+  if (Status != EFI_NOT_FOUND) {

+    do {

+      NumHandles--;

+      Status = gBS->OpenProtocol (

+                      HandlePtr[NumHandles],

+                      &gEfiDebugSupportProtocolGuid,

+                      (VOID **) &DebugSupportProtocolPtr,

+                      ImageHandle,

+                      NULL,

+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                      );

+      if (Status == EFI_SUCCESS && DebugSupportProtocolPtr->Isa == EFI_ISA) {

+        gBS->FreePool (HandlePtr);

+        Status = EFI_ALREADY_STARTED;

+        goto ErrExit;

+      }

+    } while (NumHandles > 0);

+    gBS->FreePool (HandlePtr);

+  }

+

+  //

+  // Get our image information and install platform specific unload handler

+  //

+  Status = gBS->OpenProtocol (

+                  ImageHandle,

+                  &gEfiLoadedImageProtocolGuid,

+                  (VOID **) &LoadedImageProtocolPtr,

+                  ImageHandle,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  ASSERT (!EFI_ERROR (Status));

+  if (Status != EFI_SUCCESS) {

+    goto ErrExit;

+  }

+

+  LoadedImageProtocolPtr->Unload = plUnloadDebugSupportDriver;

+

+  //

+  // Call hook for platform specific initialization

+  //

+  Status = plInitializeDebugSupportDriver ();

+  ASSERT (!EFI_ERROR (Status));

+  if (Status != EFI_SUCCESS) {

+    goto ErrExit;

+  }

+

+  //

+  // Install DebugSupport protocol to new handle

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiDebugSupportProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &gDebugSupportProtocolInterface

+                  );

+  ASSERT (!EFI_ERROR (Status));

+  if (Status != EFI_SUCCESS) {

+    goto ErrExit;

+  }

+

+ErrExit:

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.dxs b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.dxs
new file mode 100644
index 0000000..34f680a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugSupport.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.mbd b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.mbd
new file mode 100644
index 0000000..a38bf30
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>DebugSupport</BaseName>

+    <Guid>911D584C-35F7-4955-BEF9-B452769DDC3A</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>    

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.msa b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.msa
new file mode 100644
index 0000000..aaa1b9d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/DebugSupport.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DebugSupport</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>911D584C-35F7-4955-BEF9-B452769DDC3A</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>            

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugSupport.c</Filename>

+    <Filename>DebugSupport.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/AsmFuncs.asm</Filename>

+      <Filename>Ia32/plDebugSupport.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>ipf/AsmFuncs.s</Filename>

+      <Filename>ipf/common.i</Filename>

+      <Filename>ipf/ds64macros.i</Filename>

+      <Filename>ipf/plDebugSupport.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="SOMETIMES_PRODUCED">DebugSupport</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeDebugSupportDriver</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/build.xml b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/build.xml
new file mode 100644
index 0000000..06a7f1d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DebugSupport"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/DebugSupport/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DebugSupport">

+      <GenBuild baseName="DebugSupport" mbdFilename="${MODULE_DIR}/DebugSupport.mbd" msaFilename="${MODULE_DIR}/DebugSupport.msa"/>

+   </target>

+   <target depends="DebugSupport_clean" name="clean"/>

+   <target depends="DebugSupport_cleanall" name="cleanall"/>

+   <target name="DebugSupport_clean">

+      <OutputDirSetup baseName="DebugSupport" mbdFilename="${MODULE_DIR}/DebugSupport.mbd" msaFilename="${MODULE_DIR}/DebugSupport.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DebugSupport_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DebugSupport_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DebugSupport_cleanall">

+      <OutputDirSetup baseName="DebugSupport" mbdFilename="${MODULE_DIR}/DebugSupport.mbd" msaFilename="${MODULE_DIR}/DebugSupport.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DebugSupport_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DebugSupport_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DebugSupport*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm
new file mode 100644
index 0000000..89c9f83
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm
@@ -0,0 +1,547 @@
+;******************************************************************************

+;*

+;* Copyright (c) 2006, Intel Corporation                                                         

+;* All rights reserved. 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.             

+;*

+;******************************************************************************

+

+.586p

+.MODEL          FLAT, C

+

+EXCPT32_DIVIDE_ERROR     EQU    0

+EXCPT32_DEBUG            EQU    1

+EXCPT32_NMI              EQU    2

+EXCPT32_BREAKPOINT       EQU    3

+EXCPT32_OVERFLOW         EQU    4

+EXCPT32_BOUND            EQU    5

+EXCPT32_INVALID_OPCODE   EQU    6

+EXCPT32_DOUBLE_FAULT     EQU    8

+EXCPT32_INVALID_TSS      EQU   10

+EXCPT32_SEG_NOT_PRESENT  EQU   11

+EXCPT32_STACK_FAULT      EQU   12

+EXCPT32_GP_FAULT         EQU   13

+EXCPT32_PAGE_FAULT       EQU   14

+EXCPT32_FP_ERROR         EQU   16

+EXCPT32_ALIGNMENT_CHECK  EQU   17

+EXCPT32_MACHINE_CHECK    EQU   18

+EXCPT32_SIMD             EQU   19

+

+FXSTOR_FLAG              EQU   01000000h         ; bit cpuid 24 of feature flags

+

+;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87,

+;; MMX, SSE, SSE2, etc registers.  The initialization of the debugsupport driver

+;; MUST check the CPUID feature flags to see that these instructions are available

+;; and fail to init if they are not.

+

+;; fxstor [edi]

+FXSTOR_EDI               MACRO

+                         db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi]

+ENDM

+

+;; fxrstor [esi]

+FXRSTOR_ESI              MACRO

+                         db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi]

+ENDM

+.DATA

+

+public          OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport

+

+StubSize        dd      InterruptEntryStubEnd - InterruptEntryStub

+AppEsp          dd      11111111h ; ?

+DebugEsp        dd      22222222h ; ?

+ExtraPush       dd      33333333h ; ?

+ExceptData      dd      44444444h ; ?

+Eflags          dd      55555555h ; ?

+OrigVector      dd      66666666h ; ?

+

+;; The declarations below define the memory region that will be used for the debug stack.

+;; The context record will be built by pushing register values onto this stack.

+;; It is imparitive that alignment be carefully managed, since the FXSTOR and

+;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.

+;;

+;; The stub will switch stacks from the application stack to the debuger stack

+;; and pushes the exception number.

+;;

+;; Then we building the context record on the stack. Since the stack grows down,

+;; we push the fields of the context record from the back to the front.  There

+;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be

+;; used as the memory buffer for the fxstor instruction. Therefore address of

+;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which

+;; must be 16 byte aligned.

+;;

+;; We carefully locate the stack to make this happen.

+;;

+;; For reference, the context structure looks like this:

+;;      struct {

+;;        UINT32        ExceptionData;

+;;        FX_SAVE_STATE FxSaveState;    // 512 bytes, must be 16 byte aligned

+;;        UINT32        Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;

+;;        UINT32        Cr0, Cr1, Cr2, Cr3, Cr4;

+;;        UINT32        Ldtr, Tr;

+;;        UINT64        Gdtr, Idtr;

+;;        UINT32        EFlags;

+;;        UINT32        Eip;

+;;        UINT32        SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;

+;;        UINT32        Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;

+;;      } SYSTEM_CONTEXT_IA32;  // 32 bit system context record

+

+

+align           16

+DebugStackEnd   db      "DbgStkEnd >>>>>>"      ;; 16 byte long string - must be 16 bytes to preserve alignment

+                dd      1ffdh dup (000000000h)  ;; 32K should be enough stack

+                                                ;;   This allocation is coocked to insure 

+                                                ;;   that the the buffer for the FXSTORE instruction

+                                                ;;   will be 16 byte aligned also.

+                                                ;;

+ExceptionNumber dd      ?                       ;; first entry will be the vector number pushed by the stub

+

+DebugStackBegin db      "<<<< DbgStkBegin"      ;; initial debug ESP == DebugStackBegin, set in stub

+

+.CODE

+

+externdef InterruptDistrubutionHub:near

+

+;------------------------------------------------------------------------------

+; BOOLEAN

+; FxStorSupport (

+;   void

+;   )

+;

+; Abstract: Returns TRUE if FxStor instructions are supported

+;

+FxStorSupport   PROC    C PUBLIC

+

+;

+; cpuid corrupts ebx which must be preserved per the C calling convention

+;

+                push    ebx

+                mov     eax, 1

+                cpuid

+                mov     eax, edx

+                and     eax, FXSTOR_FLAG

+                shr     eax, 24

+                pop     ebx

+                ret

+FxStorSupport   ENDP

+

+

+;------------------------------------------------------------------------------

+; DESCRIPTOR *

+; GetIdtr (

+;   void

+;   )

+;

+; Abstract: Returns physical address of IDTR

+;

+GetIdtr         PROC    C PUBLIC

+                LOCAL   IdtrBuf:FWORD

+

+                sidt    IdtrBuf

+                mov     eax, DWORD PTR IdtrBuf + 2

+                ret

+GetIdtr         ENDP

+

+

+;------------------------------------------------------------------------------

+; BOOLEAN

+; WriteInterruptFlag (

+;   BOOLEAN NewState

+;   )

+;

+; Abstract: Programs interrupt flag to the requested state and returns previous

+;           state.

+;

+WriteInterruptFlag  PROC C PUBLIC State:DWORD

+

+                pushfd

+                pop     eax

+                and     eax, 200h

+                shr     eax, 9

+                mov     ecx, State

+                .IF     ecx == 0

+                        cli

+                .ELSE

+                        sti

+                .ENDIF

+                ret

+

+WriteInterruptFlag  ENDP

+

+

+

+;------------------------------------------------------------------------------

+; void

+; Vect2Desc (

+;   DESCRIPTOR * DestDesc,

+;   void (*Vector) (void)

+;   )

+;

+; Abstract: Encodes an IDT descriptor with the given physical address

+;

+Vect2Desc       PROC    C PUBLIC DestPtr:DWORD, Vector:DWORD

+

+                mov     eax, Vector

+                mov     ecx, DestPtr

+                mov     word ptr [ecx], ax                  ; write bits 15..0 of offset

+                mov     word ptr [ecx+2], 20h               ; SYS_CODE_SEL from GDT

+                mov     word ptr [ecx+4], 0e00h OR 8000h    ; type = 386 interrupt gate, present

+                shr     eax, 16

+                mov     word ptr [ecx+6], ax                ; write bits 31..16 of offset

+

+                ret

+

+Vect2Desc       ENDP

+

+

+

+;------------------------------------------------------------------------------

+; InterruptEntryStub

+;

+; Abstract: This code is not a function, but is a small piece of code that is

+;               copied and fixed up once for each IDT entry that is hooked.

+;

+InterruptEntryStub::

+                mov     AppEsp, esp             ; save stack top

+                mov     esp, offset DebugStackBegin  ; switch to debugger stack

+                push    0                       ; push vector number - will be modified before installed

+                db      0e9h                    ; jump rel32

+                dd      0                       ; fixed up to relative address of CommonIdtEntry

+InterruptEntryStubEnd:

+

+

+

+;------------------------------------------------------------------------------

+; CommonIdtEntry

+;

+; Abstract: This code is not a function, but is the common part for all IDT

+;               vectors.

+;

+CommonIdtEntry::

+;;

+;; At this point, the stub has saved the current application stack esp into AppEsp

+;; and switched stacks to the debug stack, where it pushed the vector number

+;;

+;; The application stack looks like this:

+;;

+;;              ...

+;;              (last application stack entry)

+;;              eflags from interrupted task

+;;              CS from interrupted task

+;;              EIP from interrupted task

+;;              Error code <-------------------- Only present for some exeption types

+;;

+;;

+

+

+;; The stub switched us to the debug stack and pushed the interrupt number.

+;;

+;; Next, construct the context record.  It will be build on the debug stack by

+;; pushing the registers in the correct order so as to create the context structure

+;; on the debug stack.  The context record must be built from the end back to the

+;; beginning because the stack grows down...

+;

+;; For reference, the context record looks like this:

+;;

+;; typedef

+;; struct {

+;;   UINT32        ExceptionData;

+;;   FX_SAVE_STATE FxSaveState;

+;;   UINT32        Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;

+;;   UINT32        Cr0, Cr2, Cr3, Cr4;

+;;   UINT32        Ldtr, Tr;

+;;   UINT64        Gdtr, Idtr;

+;;   UINT32        EFlags;

+;;   UINT32        Eip;

+;;   UINT32        SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;

+;;   UINT32        Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;

+;; } SYSTEM_CONTEXT_IA32;  // 32 bit system context record

+

+;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;

+                pushad

+

+;; Save interrupt state eflags register...

+                pushfd

+                pop     eax

+                mov     dword ptr Eflags, eax

+

+;; We need to determine if any extra data was pushed by the exception, and if so, save it

+;; To do this, we check the exception number pushed by the stub, and cache the

+;; result in a variable since we'll need this again.

+                .IF     ExceptionNumber == EXCPT32_DOUBLE_FAULT

+                mov     ExtraPush, 1

+                .ELSEIF ExceptionNumber == EXCPT32_INVALID_TSS

+                mov     ExtraPush, 1

+                .ELSEIF ExceptionNumber == EXCPT32_SEG_NOT_PRESENT

+                mov     ExtraPush, 1

+                .ELSEIF ExceptionNumber == EXCPT32_STACK_FAULT

+                mov     ExtraPush, 1

+                .ELSEIF ExceptionNumber == EXCPT32_GP_FAULT

+                mov     ExtraPush, 1

+                .ELSEIF ExceptionNumber == EXCPT32_PAGE_FAULT

+                mov     ExtraPush, 1

+                .ELSEIF ExceptionNumber == EXCPT32_ALIGNMENT_CHECK

+                mov     ExtraPush, 1

+                .ELSE

+                mov     ExtraPush, 0

+                .ENDIF

+

+;; If there's some extra data, save it also, and modify the saved AppEsp to effectively

+;; pop this value off the application's stack.

+                .IF     ExtraPush == 1

+                mov     eax, AppEsp

+                mov     ebx, [eax]

+                mov     ExceptData, ebx

+                add     eax, 4

+                mov     AppEsp, eax

+                .ELSE

+                mov     ExceptData, 0

+                .ENDIF

+

+;; The "pushad" above pushed the debug stack esp.  Since what we're actually doing

+;; is building the context record on the debug stack, we need to save the pushed

+;; debug ESP, and replace it with the application's last stack entry...

+                mov     eax, [esp + 12]

+                mov     DebugEsp, eax

+                mov     eax, AppEsp

+                add     eax, 12

+                ; application stack has eflags, cs, & eip, so

+                ; last actual application stack entry is

+                ; 12 bytes into the application stack.

+                mov     [esp + 12], eax

+

+;; continue building context record

+;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero

+                mov     eax, ss

+                push    eax

+

+                ; CS from application is one entry back in application stack

+                mov     eax, AppEsp

+                movzx   eax, word ptr [eax + 4]

+                push    eax

+

+                mov     eax, ds

+                push    eax

+                mov     eax, es

+                push    eax

+                mov     eax, fs

+                push    eax

+                mov     eax, gs

+                push    eax

+

+;; UINT32  Eip;

+                ; Eip from application is on top of application stack

+                mov     eax, AppEsp

+                push    dword ptr [eax]

+

+;; UINT64  Gdtr, Idtr;

+                push    0

+                push    0

+                sidt    fword ptr [esp]

+                push    0

+                push    0

+                sgdt    fword ptr [esp]

+

+;; UINT32  Ldtr, Tr;

+                xor     eax, eax

+                str     ax

+                push    eax

+                sldt    ax

+                push    eax

+

+;; UINT32  EFlags;

+;; Eflags from application is two entries back in application stack

+                mov     eax, AppEsp

+                push    dword ptr [eax + 8]

+

+;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;

+;; insure FXSAVE/FXRSTOR is enabled in CR4...

+;; ... while we're at it, make sure DE is also enabled...

+                mov     eax, cr4

+                or      eax, 208h

+                mov     cr4, eax

+                push    eax

+                mov     eax, cr3

+                push    eax

+                mov     eax, cr2

+                push    eax

+                push    0

+                mov     eax, cr0

+                push    eax

+

+;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;

+                mov     eax, dr7

+                push    eax

+;; clear Dr7 while executing debugger itself

+                xor     eax, eax

+                mov     dr7, eax

+

+                mov     eax, dr6

+                push    eax

+;; insure all status bits in dr6 are clear...

+                xor     eax, eax

+                mov     dr6, eax

+

+                mov     eax, dr3

+                push    eax

+                mov     eax, dr2

+                push    eax

+                mov     eax, dr1

+                push    eax

+                mov     eax, dr0

+                push    eax

+

+;; FX_SAVE_STATE FxSaveState;

+                sub     esp, 512

+                mov     edi, esp

+                ; IMPORTANT!! The debug stack has been carefully constructed to

+                ; insure that esp and edi are 16 byte aligned when we get here.

+                ; They MUST be.  If they are not, a GP fault will occur.

+                FXSTOR_EDI

+

+;; UINT32  ExceptionData;

+                mov     eax, ExceptData

+                push    eax

+

+; call to C code which will in turn call registered handler

+; pass in the vector number

+                mov     eax, esp

+                push    eax

+                mov     eax, ExceptionNumber

+                push    eax

+                call    InterruptDistrubutionHub

+                add     esp, 8

+

+; restore context...

+;; UINT32  ExceptionData;

+                add     esp, 4

+

+;; FX_SAVE_STATE FxSaveState;

+                mov     esi, esp

+                FXRSTOR_ESI

+                add     esp, 512

+

+;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;

+                pop     eax

+                mov     dr0, eax

+                pop     eax

+                mov     dr1, eax

+                pop     eax

+                mov     dr2, eax

+                pop     eax

+                mov     dr3, eax

+;; skip restore of dr6.  We cleared dr6 during the context save.

+                add     esp, 4

+                pop     eax

+                mov     dr7, eax

+

+;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;

+                pop     eax

+                mov     cr0, eax

+                add     esp, 4

+                pop     eax

+                mov     cr2, eax

+                pop     eax

+                mov     cr3, eax

+                pop     eax

+                mov     cr4, eax

+

+;; UINT32  EFlags;

+                mov     eax, AppEsp

+                pop     dword ptr [eax + 8]

+

+;; UINT16  Ldtr, Tr;

+;; UINT64  Gdtr, Idtr;

+;; Best not let anyone mess with these particular registers...

+                add     esp, 24

+

+;; UINT32  Eip;

+                pop     dword ptr [eax]

+

+;; UINT32  SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;

+;; NOTE - modified segment registers could hang the debugger...  We

+;;        could attempt to insulate ourselves against this possibility,

+;;        but that poses risks as well.

+;;

+

+                pop     gs

+                pop     fs

+                pop     es

+                pop     ds

+                pop     [eax + 4]

+                pop     ss

+

+;; The next stuff to restore is the general purpose registers that were pushed

+;; using the pushad instruction.

+;;

+;; The value of ESP as stored in the context record is the application ESP

+;; including the 3 entries on the application stack caused by the exception

+;; itself. It may have been modified by the debug agent, so we need to

+;; determine if we need to relocate the application stack.

+

+                mov     ebx, [esp + 12]  ; move the potentially modified AppEsp into ebx

+                mov     eax, AppEsp

+                add     eax, 12

+                cmp     ebx, eax

+                je      NoAppStackMove

+

+                mov     eax, AppEsp

+                mov     ecx, [eax]       ; EIP

+                mov     [ebx], ecx

+

+                mov     ecx, [eax + 4]   ; CS

+                mov     [ebx + 4], ecx

+

+                mov     ecx, [eax + 8]   ; EFLAGS

+                mov     [ebx + 8], ecx

+

+                mov     eax, ebx         ; modify the saved AppEsp to the new AppEsp

+                mov     AppEsp, eax

+NoAppStackMove:

+                mov     eax, DebugEsp    ; restore the DebugEsp on the debug stack

+                                         ; so our popad will not cause a stack switch

+                mov     [esp + 12], eax

+

+                cmp     ExceptionNumber, 068h

+                jne     NoChain

+

+Chain:

+

+;; Restore eflags so when we chain, the flags will be exactly as if we were never here.

+;; We gin up the stack to do an iretd so we can get ALL the flags.

+                mov     eax, AppEsp

+                mov     ebx, [eax + 8]

+                and     ebx, NOT 300h ; special handling for IF and TF

+                push    ebx

+                push    cs

+                push    PhonyIretd

+                iretd

+PhonyIretd:

+

+;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;

+                popad

+

+;; Switch back to application stack

+                mov     esp, AppEsp

+

+;; Jump to original handler

+                jmp     OrigVector

+

+NoChain:

+;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;

+                popad

+

+;; Switch back to application stack

+                mov     esp, AppEsp

+

+;; We're outa here...

+                iretd

+END

+

+

+

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c
new file mode 100644
index 0000000..2198192
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c
@@ -0,0 +1,440 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    plDebugSupport.c

+

+Abstract:

+

+    IA32 specific debug support functions

+

+Revision History

+

+--*/

+

+//

+// private header files

+//

+#include "plDebugSupport.h"

+

+//

+// This the global main table to keep track of the interrupts

+//

+IDT_ENTRY   *IdtEntryTable  = NULL;

+DESCRIPTOR  NullDesc        = 0;

+

+#ifndef EFI_NT_EMULATOR

+STATIC

+EFI_STATUS

+CreateEntryStub (

+  IN EFI_EXCEPTION_TYPE     ExceptionType,

+  OUT VOID                  **Stub

+  )

+/*++

+

+Routine Description: Allocate pool for a new IDT entry stub.  Copy the generic

+    stub into the new buffer and fixup the vector number and jump target address.

+

+Arguments:

+    ExceptionType - This is the exception type that the new stub will be created

+                    for.

+    Stub - On successful exit, *Stub contains the newly allocated entry stub.

+Returns:

+  Typically EFI_SUCCESS

+  other possibilities are passed through from AllocatePool

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       *StubCopy;

+

+  //

+  // First, allocate a new buffer and copy the stub code into it

+  //

+  Status = gBS->AllocatePool (EfiBootServicesData, StubSize, Stub);

+  if (Status == EFI_SUCCESS) {

+    StubCopy = *Stub;

+    gBS->CopyMem (StubCopy, InterruptEntryStub, StubSize);

+

+    //

+    // Next fixup the stub code for this vector

+    //

+

+    // The stub code looks like this:

+    //

+    //    00000000  89 25 00000004 R  mov     AppEsp, esp             ; save stack top

+    //    00000006  BC 00008014 R     mov     esp, offset DbgStkBot   ; switch to debugger stack

+    //    0000000B  6A 00             push    0                       ; push vector number - will be modified before installed

+    //    0000000D  E9                db      0e9h                    ; jump rel32

+    //    0000000E  00000000          dd      0                       ; fixed up to relative address of CommonIdtEntry

+    //

+

+    //

+    // poke in the exception type so the second push pushes the exception type

+    //

+    StubCopy[0x0c] = (UINT8) ExceptionType;

+

+    //

+    // fixup the jump target to point to the common entry

+    //

+    *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize];

+  }

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+HookEntry (

+  IN EFI_EXCEPTION_TYPE            ExceptionType,

+  IN VOID                         (*NewCallback) ()

+  )

+/*++

+

+Routine Description:

+  Creates a nes entry stub.  Then saves the current IDT entry and replaces it

+  with an interrupt gate for the new entry point.  The IdtEntryTable is updated

+  with the new registered function.

+

+  This code executes in boot services context.  The stub entry executes in interrupt

+  context.

+

+Arguments:

+  ExceptionType - specifies which vector to hook.

+  NewCallback - a pointer to the new function to be registered.

+

+Returns:

+  EFI_SUCCESS

+  Other possibilities are passed through by CreateEntryStub

+

+--*/

+// TODO:    ) - add argument and description to function comment

+{

+  BOOLEAN     OldIntFlagState;

+  EFI_STATUS  Status;

+

+  Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry);

+  if (Status == EFI_SUCCESS) {

+    OldIntFlagState = WriteInterruptFlag (0);

+    ReadIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));

+

+    ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0]  = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[0];

+    ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1]  = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[3];

+

+    Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry);

+    IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback;

+    WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc));

+    WriteInterruptFlag (OldIntFlagState);

+  }

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+UnhookEntry (

+  IN EFI_EXCEPTION_TYPE           ExceptionType

+  )

+/*++

+

+Routine Description:

+  Undoes HookEntry. This code executes in boot services context.

+

+Arguments:

+  ExceptionType - specifies which entry to unhook

+

+Returns:

+  EFI_SUCCESS

+  Other values are passed through from FreePool

+

+--*/

+{

+  BOOLEAN     OldIntFlagState;

+  EFI_STATUS  Status;

+

+  OldIntFlagState = WriteInterruptFlag (0);

+  WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));

+  Status = gBS->FreePool ((VOID *) (UINTN) IdtEntryTable[ExceptionType].StubEntry);

+  ZeroMem (&IdtEntryTable[ExceptionType], sizeof (IDT_ENTRY));

+  WriteInterruptFlag (OldIntFlagState);

+

+  return (Status);

+}

+#endif

+

+EFI_STATUS

+ManageIdtEntryTable (

+  VOID (*NewCallback)(),

+  EFI_EXCEPTION_TYPE ExceptionType

+  )

+/*++

+

+Routine Description:

+  This is the main worker function that manages the state of the interrupt

+  handlers.  It both installs and uninstalls interrupt handlers based on the

+  value of NewCallback.  If NewCallback is NULL, then uninstall is indicated.

+  If NewCallback is non-NULL, then install is indicated.

+

+Arguments:

+  NewCallback - If non-NULL, NewCallback specifies the new handler to register.

+                If NULL, specifies that the previously registered handler should

+                    be uninstalled.

+  ExceptionType - Indicates which entry to manage

+

+Returns:

+  EFI_SUCCESS

+  EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has

+                          no handler registered for it

+  EFI_ALREADY_STARTED   - requested install to a vector that already has a handler registered.

+

+  Other possible return values are passed through from UnHookEntry and HookEntry.

+

+--*/

+// TODO:    ) - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+

+  Status = EFI_SUCCESS;

+

+#ifndef EFI_NT_EMULATOR

+  if (CompareDescriptor (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) {

+    //

+    // we've already installed to this vector

+    //

+    if (NewCallback != NULL) {

+      //

+      // if the input handler is non-null, error

+      //

+      Status = EFI_ALREADY_STARTED;

+    } else {

+      Status = UnhookEntry (ExceptionType);

+    }

+  } else {

+    //

+    // no user handler installed on this vector

+    //

+    if (NewCallback == NULL) {

+      //

+      // if the input handler is null, error

+      //

+      Status = EFI_INVALID_PARAMETER;

+    } else {

+      Status = HookEntry (ExceptionType, NewCallback);

+    }

+  }

+#endif

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+GetMaximumProcessorIndex (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,

+  OUT UINTN                           *MaxProcessorIndex

+  )

+/*++

+

+Routine Description: This is a DebugSupport protocol member function.

+

+Arguments:

+

+Returns: Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    MaxProcessorIndex - add argument and description to function comment

+{

+  *MaxProcessorIndex = 0;

+  return (EFI_SUCCESS);

+}

+

+EFI_STATUS

+EFIAPI

+RegisterPeriodicCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL *This,

+  IN UINTN                      ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK      PeriodicCallback

+  )

+/*++

+

+Routine Description: This is a DebugSupport protocol member function.

+

+Arguments:

+

+Returns:

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ProcessorIndex - add argument and description to function comment

+// TODO:    PeriodicCallback - add argument and description to function comment

+{

+  return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR);

+}

+

+EFI_STATUS

+EFIAPI

+RegisterExceptionCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL *This,

+  IN UINTN                      ProcessorIndex,

+  IN EFI_EXCEPTION_CALLBACK     NewCallback,

+  IN EFI_EXCEPTION_TYPE         ExceptionType

+  )

+/*++

+

+Routine Description:

+  This is a DebugSupport protocol member function.

+

+  This code executes in boot services context.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ProcessorIndex - add argument and description to function comment

+// TODO:    NewCallback - add argument and description to function comment

+// TODO:    ExceptionType - add argument and description to function comment

+{

+  return ManageIdtEntryTable (NewCallback, ExceptionType);

+}

+

+EFI_STATUS

+EFIAPI

+InvalidateInstructionCache (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,

+  IN UINTN                            ProcessorIndex,

+  IN VOID                             *Start,

+  IN UINT64                           Length

+  )

+/*++

+

+Routine Description:

+  This is a DebugSupport protocol member function.

+  For IA32, this is a no-op since the instruction and data caches are coherent.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ProcessorIndex - add argument and description to function comment

+// TODO:    Start - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+plInitializeDebugSupportDriver (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Initializes driver's handler registration database.

+

+  This code executes in boot services context.

+

+Arguments:

+  None

+

+Returns:

+  EFI_SUCCESS

+  EFI_UNSUPPORTED - if IA32 processor does not support FXSTOR/FXRSTOR instructions,

+                    the context save will fail, so these processor's are not supported.

+

+--*/

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  if (!FxStorSupport ()) {

+    return EFI_UNSUPPORTED;

+  } else {

+    IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES);

+    if (IdtEntryTable != NULL) {

+      return EFI_SUCCESS;

+    } else {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+}

+

+EFI_STATUS

+EFIAPI

+plUnloadDebugSupportDriver (

+  IN EFI_HANDLE ImageHandle

+  )

+/*++

+

+Routine Description:

+  This is the callback that is written to the LoadedImage protocol instance

+  on the image handle. It uninstalls all registered handlers and frees all entry

+  stub memory.

+

+  This code executes in boot services context.

+

+Arguments:

+  ImageHandle - The image handle of the unload handler

+

+Returns:

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_EXCEPTION_TYPE  ExceptionType;

+

+  for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {

+    ManageIdtEntryTable (NULL, ExceptionType);

+  }

+

+  gBS->FreePool (IdtEntryTable);

+  return EFI_SUCCESS;

+}

+

+VOID

+InterruptDistrubutionHub (

+  EFI_EXCEPTION_TYPE      ExceptionType,

+  EFI_SYSTEM_CONTEXT_IA32 *ContextRecord

+  )

+/*++

+

+Routine Description: Common piece of code that invokes the registered handlers.

+

+  This code executes in exception context so no efi calls are allowed.

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    ExceptionType - add argument and description to function comment

+// TODO:    ContextRecord - add argument and description to function comment

+{

+  if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) {

+    if (ExceptionType != SYSTEM_TIMER_VECTOR) {

+      IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord);

+    } else {

+      OrigVector = IdtEntryTable[ExceptionType].OrigVector;

+      IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord);

+    }

+  }

+}

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h
new file mode 100644
index 0000000..abb6967
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h
@@ -0,0 +1,312 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    plDebugSupport.h

+

+Abstract:

+

+    IA32 specific debug support macros, typedefs and prototypes.

+

+Revision History

+

+--*/

+

+#ifndef _PLDEBUG_SUPPORT_H

+#define _PLDEBUG_SUPPORT_H

+

+#define NUM_IDT_ENTRIES                 0x78

+#define SYSTEM_TIMER_VECTOR             0x68

+#define VECTOR_ENTRY_PAGES              1

+#define CopyDescriptor(Dest, Src)       CopyMem ((Dest), (Src), sizeof (DESCRIPTOR))

+#define ZeroDescriptor(Dest)            CopyDescriptor ((Dest), &NullDesc)

+#define ReadIdt(Vector, Dest)           CopyDescriptor ((Dest), &((GetIdtr ())[(Vector)]))

+#define WriteIdt(Vector, Src)           CopyDescriptor (&((GetIdtr ())[(Vector)]), (Src))

+#define CompareDescriptor(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR))

+#define EFI_ISA                         IsaIa32

+#define FF_FXSR                         (1 << 24)

+

+typedef UINT64  DESCRIPTOR;

+

+typedef struct {

+  DESCRIPTOR  OrigDesc;

+  VOID (*OrigVector) (VOID);

+  DESCRIPTOR  NewDesc;

+  VOID (*StubEntry) (VOID);

+  VOID (*RegisteredCallback) ();

+} IDT_ENTRY;

+

+extern EFI_SYSTEM_CONTEXT SystemContext;

+extern UINT8              InterruptEntryStub[];

+extern UINT32             StubSize;

+extern VOID (*OrigVector) (VOID);

+

+VOID

+CommonIdtEntry (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+FxStorSupport (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+DESCRIPTOR  *

+GetIdtr (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+Vect2Desc (

+  DESCRIPTOR * DestDesc,

+  VOID (*Vector) (VOID)

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  DestDesc  - TODO: add argument description

+  )         - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+WriteInterruptFlag (

+  BOOLEAN NewState

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  NewState  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+plInitializeDebugSupportDriver (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+plUnloadDebugSupportDriver (

+  IN EFI_HANDLE                       ImageHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// DebugSupport protocol member functions

+//

+EFI_STATUS

+EFIAPI

+GetMaximumProcessorIndex (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,

+  OUT UINTN                           *MaxProcessorIndex

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  MaxProcessorIndex - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+RegisterPeriodicCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,

+  IN UINTN                            ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK            PeriodicCallback

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  ProcessorIndex    - TODO: add argument description

+  PeriodicCallback  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+RegisterExceptionCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,

+  IN UINTN                            ProcessorIndex,

+  IN EFI_EXCEPTION_CALLBACK           NewCallback,

+  IN EFI_EXCEPTION_TYPE               ExceptionType

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This            - TODO: add argument description

+  ProcessorIndex  - TODO: add argument description

+  NewCallback     - TODO: add argument description

+  ExceptionType   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+InvalidateInstructionCache (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,

+  IN UINTN                            ProcessorIndex,

+  IN VOID                             *Start,

+  IN UINT64                           Length

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This            - TODO: add argument description

+  ProcessorIndex  - TODO: add argument description

+  Start           - TODO: add argument description

+  Length          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/AsmFuncs.s b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/AsmFuncs.s
new file mode 100644
index 0000000..1ac4a7e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/AsmFuncs.s
@@ -0,0 +1,1389 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//  AsmFuncs.s

+//

+// Abstract:

+//

+//  Low level IPF routines used by the debug support driver

+//

+// Revision History:

+//

+//--

+

+

+#include "common.i"

+#include "Ds64Macros.i"

+

+.global PatchSaveBuffer

+.global IpfContextBuf

+.global CommonHandler

+.global ExternalInterruptCount

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      InstructionCacheFlush

+//

+//  Description:

+//      Flushes instruction cache for specified number of bytes

+//

+        .global InstructionCacheFlush

+        .proc   InstructionCacheFlush

+        .align 32

+InstructionCacheFlush::

+ {      .mii

+        alloc   r3=2, 0, 0, 0

+        cmp4.leu p0,p6=32, r33;;

+        (p6)    mov r33=32;;

+ }

+ {      .mii

+        nop.m    0

+        zxt4    r29=r33;;

+        dep.z   r30=r29, 0, 5;;

+ }

+ {      .mii

+        cmp4.eq p0,p7=r0, r30

+        shr.u   r28=r29, 5;;

+        (p7)    adds    r28=1, r28;;

+ }

+ {      .mii

+        nop.m    0

+        shl r27=r28, 5;;

+        zxt4    r26=r27;;

+ }

+ {      .mfb

+        add r31=r26, r32

+        nop.f    0

+        nop.b    0

+ }

+LoopBack:   // $L143:

+ {      .mii

+        fc   r32

+        adds    r32=32, r32;;

+        cmp.ltu p14,p15=r32, r31

+ }

+ {      .mfb

+        nop.m    0

+        nop.f    0

+        //(p14) br.cond.dptk.few $L143#;;

+        (p14)   br.cond.dptk.few LoopBack;;

+ }

+ {      .mmi

+        sync.i;;

+        srlz.i

+        nop.i   0;;

+ }

+ {      .mfb

+        nop.m    0

+        nop.f    0

+        br.ret.sptk.few b0;;

+ }

+        .endp   InstructionCacheFlush

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      ChainHandler

+//

+//  Description:

+//      Chains an interrupt handler

+//

+//      The purpose of this function is to enable chaining of the external interrupt.

+//      Since there's no clean SAL abstraction for doing this, we must do it

+//      surreptitiously.

+//

+//      The reserved IVT entry at offset 0x3400 is coopted for use by this handler.

+//      According to Itanium architecture, it is reserved.  Strictly speaking, this is

+//      not safe, as we're cheating and violating the Itanium architecture.  However,

+//      as long as we're the only ones cheating, we should be OK.  Without hooks in

+//      the SAL to enable IVT management, there aren't many good options.

+//

+//      The strategy is to replace the first bundle of the external interrupt handler

+//      with our own that will branch into a piece of code we've supplied and located

+//      in the reserved IVT entry.  Only the first bundle of the external interrupt

+//      IVT entry is modified.

+//

+//      The original bundle is moved and relocated to space

+//      allocated within the reserved IVT entry.  The next bundle following is

+//      is generated to go a hard coded branch back to the second bundle of the

+//      external interrupt IVT entry just in case the first bundle had no branch.

+//

+//      Our new code will execute our handler, and then fall through to the

+//      original bundle after restoring all context appropriately.

+//

+//      The following is a representation of what the IVT memory map looks like with

+//      our chained handler installed:

+//

+//

+//                                                 

+//                                                 

+//                           

+//      This IVT entry is      Failsafe bundle     

+//      reserved by the         

+//      Itanium architecture   Original bundle 0   

+//      and is used for         

+//      for locating our                           

+//      handler and the                            

+//      original bundle        Patch code...       

+//      zero of the ext                            

+//      interrupt handler                          

+//                              

+//      RSVD    (3400)         Unused              

+//                           

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                                                 

+//                              

+//      EXT_INT (3000)         Bundle 0               Bundle zero - This one is

+//                                modified, all other bundles

+//                                                       in the EXT_INT entry are

+//                                                       untouched.

+//

+//

+//       Arguments:

+//

+//       Returns:

+//

+//       Notes:

+//

+//

+        .global ChainHandler

+        .proc ChainHandler

+ChainHandler:

+

+        NESTED_SETUP( 0,2+3,3,0 )

+

+        mov         r8=1                           // r8 = success

+        mov         r2=cr.iva;;

+//

+// NOTE: There's a potential hazard here in that we're simply stealing a bunch of

+// bundles (memory) from the IVT and assuming there's no catastrophic side effect.

+//

+// First, save IVT area we're taking over with the patch so we can restore it later

+//

+        addl        out0=PATCH_ENTRY_OFFSET, r2    // out0 = source buffer

+        movl        out1=PatchSaveBuffer           // out1 = destination buffer

+        mov         out2=0x40;;                    // out2 = number of bundles to copy... save entire IDT entry

+        br.call.sptk.few    b0 = CopyBundles

+

+// Next, copy the patch code into the IVT

+        movl        out0=PatchCode                 // out0 = source buffer of patch code

+        addl        out1=PATCH_OFFSET, r2          // out1 = destination buffer - in IVT

+        mov         out2=NUM_PATCH_BUNDLES;;       // out2 = number of bundles to copy

+        br.call.sptk.few    b0 = CopyBundles

+

+

+// copy original bundle 0 from the external interrupt handler to the

+// appropriate place in the reserved IVT interrupt slot

+        addl        out0=EXT_INT_ENTRY_OFFSET, r2  // out0 = source buffer

+        addl        out1=RELOCATED_EXT_INT, r2     // out1 = destination buffer - in reserved IVT

+        mov         out2=1;;                       // out2 = copy 1 bundle

+        br.call.sptk.few    b0 = CopyBundles

+

+// Now relocate it there because it very likely had a branch instruction that

+// that must now be fixed up.

+        addl        out0=RELOCATED_EXT_INT, r2     // out0 = new runtime address of bundle - in reserved IVT

+        addl        out1=EXT_INT_ENTRY_OFFSET, r2;;// out1 = IP address of previous location

+        mov         out2=out0;;                    // out2 = IP address of new location

+        br.call.sptk.few    b0 = RelocateBundle

+

+// Now copy into the failsafe branch into the next bundle just in case

+// the original ext int bundle 0 bundle did not contain a branch instruction

+        movl        out0=FailsafeBranch            // out0 = source buffer

+        addl        out1=FAILSAFE_BRANCH_OFFSET, r2  // out1 = destination buffer - in reserved IVT

+        mov         out2=1;;                       // out2 = copy 1 bundle

+        br.call.sptk.few    b0 = CopyBundles

+

+// Last, copy in our replacement for the external interrupt IVT entry bundle 0

+        movl        out0=PatchCodeNewBun0          // out0 = source buffer - our replacement bundle 0

+        addl        out1=EXT_INT_ENTRY_OFFSET, r2  // out1 = destination buffer - bundle 0 of External interrupt entry

+        mov         out2=1;;                       // out2 = copy 1 bundle

+        br.call.sptk.few    b0 = CopyBundles

+

+ChainHandlerDone:

+        NESTED_RETURN

+

+        .endp ChainHandler

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      UnchainHandler

+//

+//  Description:

+//      Unchains an interrupt handler

+//

+//  Arguments:

+//

+//  Returns:

+//

+//  Notes:

+//

+//

+        .global UnchainHandler

+        .proc UnchainHandler

+

+UnchainHandler:

+

+        NESTED_SETUP( 0,2+3,3,0 )

+

+        mov         r8=1                        // r8 = success

+        mov         r2=cr.iva;;                 // r2 = interrupt vector address

+

+// First copy original Ext Int bundle 0 back to it's proper home...

+        addl        out0=RELOCATED_EXT_INT, r2     // out0 = source - in reserved IVT

+        addl        out1=EXT_INT_ENTRY_OFFSET, r2  // out1 = destination buffer - first bundle of Ext Int entry

+        mov         out2=1;;                       // out2 = copy 1 bundle

+        br.call.sptk.few    b0 = CopyBundles

+

+// Now, relocate it again...

+        addl        out0=EXT_INT_ENTRY_OFFSET, r2  // out1 = New runtime address

+        addl        out1=RELOCATED_EXT_INT, r2;;   // out0 = IP address of previous location

+        mov         out2=out0;;                    // out2 = IP address of new location

+        br.call.sptk.few    b0 = RelocateBundle

+

+// Last, restore the patch area

+        movl        out0=PatchSaveBuffer           // out0 = source buffer

+        addl        out1=PATCH_ENTRY_OFFSET, r2    // out1 = destination buffer

+        mov         out2=0x40;;                    // out2 = number of bundles to copy... save entire IDT entry

+        br.call.sptk.few    b0 = CopyBundles

+

+UnchainHandlerDone:

+        NESTED_RETURN

+

+        .endp UnchainHandler

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      CopyBundles

+//

+//  Description:

+//      Copies instruction bundles - flushes icache as necessary

+//

+//  Arguments:

+//      in0 - Bundle source

+//      in1 - Bundle destination

+//      in2 - Bundle count

+//

+//  Returns:

+//

+//  Notes:

+//      This procedure is a leaf routine

+//

+        .proc   CopyBundles

+

+CopyBundles:

+

+        NESTED_SETUP(3,2+1,0,0)

+

+        shl         in2=in2, 1;;                // in2 = count of 8 byte blocks to copy

+

+CopyBundlesLoop:

+

+        cmp.eq      p14, p15 = 0, in2;;         // Check if done

+(p14)   br.sptk.few CopyBundlesDone;;

+

+        ld8         loc2=[in0], 0x8;;           // loc2 = source bytes

+        st8         [in1]=loc2;;                // [in1] = destination bytes

+        fc          in1;;                       // Flush instruction cache

+        sync.i;;                                // Ensure local and remote data/inst caches in sync

+        srlz.i;;                                // Ensure sync has been observed

+        add         in1=0x8, in1;;              // in1 = next destination

+        add         in2=-1, in2;;               // in2 = decrement 8 bytes blocks to copy

+        br.sptk.few CopyBundlesLoop;;

+

+CopyBundlesDone:

+        NESTED_RETURN

+

+        .endp   CopyBundles

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      RelocateBundle

+//

+//  Description:

+//      Relocates an instruction bundle by updating any ip-relative branch instructions.

+//

+//  Arguments:

+//      in0 - Runtime address of bundle

+//      in1 - IP address of previous location of bundle

+//      in2 - IP address of new location of bundle

+//

+//  Returns:

+//      in0 - 1 if successful or 0 if unsuccessful

+//

+//  Notes:

+//      This routine examines all slots in the given bundle that are destined for the

+//      branch execution unit.  If any of these slots contain an IP-relative branch

+//      namely instructions B1, B2, B3, or B6, the slot is fixed-up with a new relative

+//      address.  Errors can occur if a branch cannot be reached.

+//

+        .proc   RelocateBundle

+

+RelocateBundle:

+

+        NESTED_SETUP(3,2+4,3,0)

+

+        mov         loc2=SLOT0                  // loc2 = slot index

+        mov         loc5=in0;;                  // loc5 = runtime address of bundle

+        mov         in0=1;;                     // in0 = success

+

+RelocateBundleNextSlot:

+

+        cmp.ge      p14, p15 = SLOT2, loc2;;    // Check if maximum slot

+(p15)   br.sptk.few RelocateBundleDone

+

+        mov         out0=loc5;;                 // out0 = runtime address of bundle

+        br.call.sptk.few    b0 = GetTemplate

+        mov         loc3=out0;;                 // loc3 = instruction template

+        mov         out0=loc5                   // out0 = runtime address of bundle

+        mov         out1=loc2;;                 // out1 = instruction slot number

+        br.call.sptk.few    b0 = GetSlot

+        mov         loc4=out0;;                 // loc4 = instruction encoding

+        mov         out0=loc4                   // out0 = instuction encoding

+        mov         out1=loc2                   // out1 = instruction slot number

+        mov         out2=loc3;;                 // out2 = instruction template

+        br.call.sptk.few    b0 = IsSlotBranch

+        cmp.eq      p14, p15 = 1, out0;;        // Check if branch slot

+(p15)   add         loc2=1,loc2                 // Increment slot

+(p15)   br.sptk.few RelocateBundleNextSlot

+        mov         out0=loc4                   // out0 = instuction encoding

+        mov         out1=in1                    // out1 = IP address of previous location

+        mov         out2=in2;;                  // out2 = IP address of new location

+        br.call.sptk.few    b0 = RelocateSlot

+        cmp.eq      p14, p15 = 1, out1;;        // Check if relocated slot

+(p15)   mov         in0=0                       // in0 = failure

+(p15)   br.sptk.few RelocateBundleDone

+        mov         out2=out0;;                 // out2 = instruction encoding

+        mov         out0=loc5                   // out0 = runtime address of bundle

+        mov         out1=loc2;;                 // out1 = instruction slot number

+        br.call.sptk.few    b0 = SetSlot

+        add         loc2=1,loc2;;               // Increment slot

+        br.sptk.few RelocateBundleNextSlot

+

+RelocateBundleDone:

+        NESTED_RETURN

+

+        .endp   RelocateBundle

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      RelocateSlot

+//

+//  Description:

+//      Relocates an instruction bundle by updating any ip-relative branch instructions.

+//

+//  Arguments:

+//      in0 - Instruction encoding (41-bits, right justified)

+//      in1 - IP address of previous location of bundle

+//      in2 - IP address of new location of bundle

+//

+//  Returns:

+//      in0 - Instruction encoding (41-bits, right justified)

+//      in1 - 1 if successful otherwise 0

+//

+//  Notes:

+//      This procedure is a leaf routine

+//

+        .proc   RelocateSlot

+

+RelocateSlot:

+        NESTED_SETUP(3,2+5,0,0)

+        extr.u      loc2=in0, 37, 4;;           // loc2 = instruction opcode

+        cmp.eq      p14, p15 = 4, loc2;;        // IP-relative branch (B1) or

+                                                // IP-relative counted branch (B2)

+(p15)   cmp.eq      p14, p15 = 5, loc2;;        // IP-relative call (B3)

+(p15)   cmp.eq      p14, p15 = 7, loc2;;        // IP-relative predict (B6)

+(p15)   mov         in1=1                       // Instruction did not need to be reencoded

+(p15)   br.sptk.few RelocateSlotDone

+        tbit.nz     p14, p15 = in0, 36;;        // put relative offset sign bit in p14

+        extr.u      loc2=in0, 13, 20;;          // loc2 = relative offset in instruction

+(p14)   movl        loc3=0xfffffffffff00000;;   // extend sign

+(p14)   or          loc2=loc2, loc3;;

+        shl         loc2=loc2,4;;               // convert to byte offset instead of bundle offset

+        add         loc3=loc2, in1;;            // loc3 = physical address of branch target

+(p14)   sub         loc2=r0,loc2;;              // flip sign in loc2 if offset is negative

+        sub         loc4=loc3,in2;;             // loc4 = relative offset from new ip to branch target

+        cmp.lt      p15, p14 = 0, loc4;;        // get new sign bit 

+(p14)   sub         loc5=r0,loc4                // get absolute value of offset

+(p15)   mov         loc5=loc4;;

+        movl        loc6=0x0FFFFFF;;            // maximum offset in bytes for ip-rel branch

+        cmp.gt      p14, p15 = loc5, loc6;;     // check to see we're not out of range for an ip-relative branch

+(p14)   br.sptk.few RelocateSlotError

+        cmp.lt      p15, p14 = 0, loc4;;        // store sign in p14 again

+(p14)   dep         in0=1,in0,36,1              // store sign bit in instruction

+(p15)   dep         in0=0,in0,36,1

+        shr         loc4=loc4, 4;;              // convert back to bundle offset

+        dep         in0=loc4,in0,13,16;;        // put first 16 bits of new offset into instruction

+        shr         loc4=loc4,16;;

+        dep         in0=loc4,in0,13+16,4        // put last 4 bits of new offset into instruction

+        mov         in1=1;;                     // in1 = success

+        br.sptk.few RelocateSlotDone;;

+

+RelocateSlotError:

+        mov         in1=0;;                     // in1 = failure

+

+RelocateSlotDone:

+        NESTED_RETURN

+

+        .endp   RelocateSlot

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      IsSlotBranch

+//

+//  Description:

+//      Determines if the given instruction is a branch instruction.

+//

+//  Arguments:

+//      in0 - Instruction encoding (41-bits, right justified)

+//      in1 - Instruction slot number

+//      in2 - Bundle template

+//

+//  Returns:

+//      in0 - 1 if branch or 0 if not branch

+//

+//  Notes:

+//      This procedure is a leaf routine

+//

+//      IsSlotBranch recognizes all branch instructions by looking at the provided template.

+//      The instruction encoding is only passed to this routine for future expansion.

+//

+        .proc   IsSlotBranch

+

+IsSlotBranch:

+

+        NESTED_SETUP (3,2+0,0,0)

+

+        mov         in0=1;;                     // in0 = 1 which destroys the instruction

+        andcm       in2=in2,in0;;               // in2 = even template to reduce compares

+        mov         in0=0;;                     // in0 = not a branch

+        cmp.eq      p14, p15 = 0x16, in2;;      // Template 0x16 is BBB

+(p14)   br.sptk.few IsSlotBranchTrue

+        cmp.eq      p14, p15 = SLOT0, in1;;     // Slot 0 has no other possiblities

+(p14)   br.sptk.few IsSlotBranchDone

+        cmp.eq      p14, p15 = 0x12, in2;;      // Template 0x12 is MBB

+(p14)   br.sptk.few IsSlotBranchTrue

+        cmp.eq      p14, p15 = SLOT1, in1;;     // Slot 1 has no other possiblities

+(p14)   br.sptk.few IsSlotBranchDone

+        cmp.eq      p14, p15 = 0x10, in2;;      // Template 0x10 is MIB

+(p14)   br.sptk.few IsSlotBranchTrue

+        cmp.eq      p14, p15 = 0x18, in2;;      // Template 0x18 is MMB

+(p14)   br.sptk.few IsSlotBranchTrue

+        cmp.eq      p14, p15 = 0x1C, in2;;      // Template 0x1C is MFB

+(p14)   br.sptk.few IsSlotBranchTrue

+        br.sptk.few IsSlotBranchDone

+

+IsSlotBranchTrue:

+        mov         in0=1;;                     // in0 = branch

+

+IsSlotBranchDone:

+        NESTED_RETURN

+

+        .endp   IsSlotBranch

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      GetTemplate

+//

+//  Description:

+//      Retrieves the instruction template for an instruction bundle

+//

+//  Arguments:

+//      in0 - Runtime address of bundle

+//

+//  Returns:

+//      in0 - Instruction template (5-bits, right-justified)

+//

+//  Notes:

+//      This procedure is a leaf routine

+//

+        .proc   GetTemplate

+

+GetTemplate:

+

+        NESTED_SETUP (1,2+2,0,0)

+

+        ld8     loc2=[in0], 0x8             // loc2 = first 8 bytes of branch bundle

+        movl    loc3=MASK_0_4;;             // loc3 = template mask

+        and     loc2=loc2,loc3;;            // loc2 = template, right justified

+        mov     in0=loc2;;                  // in0 = template, right justified

+

+        NESTED_RETURN

+

+        .endp   GetTemplate

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      GetSlot

+//

+//  Description:

+//      Gets the instruction encoding for an instruction slot and bundle

+//

+//  Arguments:

+//      in0 - Runtime address of bundle

+//      in1 - Instruction slot (either 0, 1, or 2)

+//

+//  Returns:

+//      in0 - Instruction encoding (41-bits, right justified)

+//

+//  Notes:

+//      This procedure is a leaf routine

+//

+//      Slot0 - [in0 + 0x8] Bits 45-5

+//      Slot1 - [in0 + 0x8] Bits 63-46 and [in0] Bits 22-0

+//      Slot2 - [in0] Bits 63-23

+//

+        .proc   GetSlot

+

+GetSlot:

+        NESTED_SETUP (2,2+3,0,0)

+

+        ld8     loc2=[in0], 0x8;;           // loc2 = first 8 bytes of branch bundle

+        ld8     loc3=[in0];;                // loc3 = second 8 bytes of branch bundle

+        cmp.eq  p14, p15 = 2, in1;;         // check if slot 2 specified

+ (p14)  br.cond.sptk.few    GetSlot2;;      // get slot 2

+        cmp.eq  p14, p15 = 1, in1;;         // check if slot 1 specified

+ (p14)  br.cond.sptk.few    GetSlot1;;      // get slot 1

+

+GetSlot0:

+        extr.u  in0=loc2, 5, 45             // in0 = extracted slot 0

+        br.sptk.few GetSlotDone;;

+

+GetSlot1:

+        extr.u  in0=loc2, 46, 18            // in0 = bits 63-46 of loc2 right-justified

+        extr.u  loc4=loc3, 0, 23;;          // loc4 = bits 22-0 of loc3 right-justified

+        dep     in0=loc4, in0, 18, 15;;

+        shr.u   loc4=loc4,15;;

+        dep     in0=loc4, in0, 33, 8;;      // in0 = extracted slot 1

+        br.sptk.few GetSlotDone;;

+

+GetSlot2:

+        extr.u  in0=loc3, 23, 41;;          // in0 = extracted slot 2

+

+GetSlotDone:

+        NESTED_RETURN

+

+        .endp   GetSlot

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      SetSlot

+//

+//  Description:

+//      Sets the instruction encoding for an instruction slot and bundle

+//

+//  Arguments:

+//      in0 - Runtime address of bundle

+//      in1 - Instruction slot (either 0, 1, or 2)

+//      in2 - Instruction encoding (41-bits, right justified)

+//

+//  Returns:

+//

+//  Notes:

+//      This procedure is a leaf routine

+//

+        .proc       SetSlot

+

+SetSlot:

+        NESTED_SETUP (3,2+3,0,0)

+

+        ld8     loc2=[in0], 0x8;;           // loc2 = first 8 bytes of bundle

+        ld8     loc3=[in0];;                // loc3 = second 8 bytes of bundle

+        cmp.eq  p14, p15 = 2, in1;;         // check if slot 2 specified

+ (p14)  br.cond.sptk.few    SetSlot2;;      // set slot 2

+        cmp.eq  p14, p15 = 1, in1;;         // check if slot 1 specified

+ (p14)  br.cond.sptk.few    SetSlot1;;      // set slot 1

+

+SetSlot0:

+        dep     loc2=0, loc2, 5, 41;;       // remove old instruction from slot 0

+        shl     loc4=in2, 5;;               // loc4 = new instruction ready to be inserted

+        or      loc2=loc2, loc4;;           // loc2 = updated first 8 bytes of bundle

+        add     loc4=0x8,in0;;              // loc4 = address to store first 8 bytes of bundle

+        st8     [loc4]=loc2                 // [loc4] = updated bundle

+        br.sptk.few SetSlotDone;;

+        ;;

+

+SetSlot1:

+        dep     loc2=0, loc2, 46, 18        // remove old instruction from slot 1

+        dep     loc3=0, loc3, 0, 23;;

+        shl     loc4=in2, 46;;              // loc4 = partial instruction ready to be inserted

+        or      loc2=loc2, loc4;;           // loc2 = updated first 8 bytes of bundle

+        add     loc4=0x8,in0;;              // loc4 = address to store first 8 bytes of bundle

+        st8     [loc4]=loc2;;               // [loc4] = updated bundle

+        shr.u   loc4=in2, 18;;              // loc4 = partial instruction ready to be inserted

+        or      loc3=loc3, loc4;;           // loc3 = updated second 8 bytes of bundle

+        st8     [in0]=loc3;;                // [in0] = updated bundle

+        br.sptk.few SetSlotDone;;

+

+SetSlot2:

+        dep     loc3=0, loc3, 23, 41;;      // remove old instruction from slot 2

+        shl     loc4=in2, 23;;              // loc4 = instruction ready to be inserted

+        or      loc3=loc3, loc4;;           // loc3 = updated second 8 bytes of bundle

+        st8     [in0]=loc3;;                // [in0] = updated bundle

+

+SetSlotDone:

+

+        NESTED_RETURN

+        .endp       SetSlot

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      GetIva

+//

+//  Description:

+//      C callable function to obtain the current value of IVA

+//

+//  Returns:

+//      Current value if IVA

+

+        .global     GetIva

+        .proc       GetIva

+GetIva:

+        mov         r8=cr2;;

+        br.ret.sptk.many    b0

+

+        .endp       GetIva

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      ProgramInterruptFlags

+//

+//  Description:

+//      C callable function to enable/disable interrupts

+//

+//  Returns:

+//      Previous state of psr.ic

+//

+        .global     ProgramInterruptFlags

+        .proc       ProgramInterruptFlags

+ProgramInterruptFlags:

+        alloc       loc0=1,2,0,0;;

+        mov         loc0=psr

+        mov         loc1=0x6000;;

+        and         r8=loc0, loc1           // obtain current psr.ic and psr.i state

+        and         in0=in0, loc1           // insure no extra bits set in input

+        andcm       loc0=loc0,loc1;;        // clear original psr.i and psr.ic

+        or          loc0=loc0,in0;;         // OR in new psr.ic value

+        mov         psr.l=loc0;;            // write new psr

+        srlz.d

+        br.ret.sptk.many    b0              // return

+

+        .endp       ProgramInterruptFlags

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      SpillContext

+//

+//  Description:

+//      Saves system context to context record.

+//

+//  Arguments:

+//          in0 = 512 byte aligned context record address

+//          in1 = original B0

+//          in2 = original ar.bsp

+//          in3 = original ar.bspstore

+//          in4 = original ar.rnat

+//          in5 = original ar.pfs

+//

+//  Notes:

+//      loc0 - scratch

+//      loc1 - scratch

+//      loc2 - temporary application unat storage

+//      loc3 - temporary exception handler unat storage

+

+        .proc       SpillContext

+

+SpillContext:

+        alloc       loc0=6,4,0,0;;          // alloc 6 input, 4 locals, 0 outs

+        mov         loc2=ar.unat;;          // save application context unat (spilled later)

+        mov         ar.unat=r0;;            // set UNAT=0

+        st8.spill   [in0]=r0,8;;

+        st8.spill   [in0]=r1,8;;            // save R1 - R31

+        st8.spill   [in0]=r2,8;;

+        st8.spill   [in0]=r3,8;;

+        st8.spill   [in0]=r4,8;;

+        st8.spill   [in0]=r5,8;;

+        st8.spill   [in0]=r6,8;;

+        st8.spill   [in0]=r7,8;;

+        st8.spill   [in0]=r8,8;;

+        st8.spill   [in0]=r9,8;;

+        st8.spill   [in0]=r10,8;;

+        st8.spill   [in0]=r11,8;;

+        st8.spill   [in0]=r12,8;;

+        st8.spill   [in0]=r13,8;;

+        st8.spill   [in0]=r14,8;;

+        st8.spill   [in0]=r15,8;;

+        st8.spill   [in0]=r16,8;;

+        st8.spill   [in0]=r17,8;;

+        st8.spill   [in0]=r18,8;;

+        st8.spill   [in0]=r19,8;;

+        st8.spill   [in0]=r20,8;;

+        st8.spill   [in0]=r21,8;;

+        st8.spill   [in0]=r22,8;;

+        st8.spill   [in0]=r23,8;;

+        st8.spill   [in0]=r24,8;;

+        st8.spill   [in0]=r25,8;;

+        st8.spill   [in0]=r26,8;;

+        st8.spill   [in0]=r27,8;;

+        st8.spill   [in0]=r28,8;;

+        st8.spill   [in0]=r29,8;;

+        st8.spill   [in0]=r30,8;;

+        st8.spill   [in0]=r31,8;;

+        mov         loc3=ar.unat;;          // save debugger context unat (spilled later)

+        stf.spill   [in0]=f2,16;;           // save f2 - f31

+        stf.spill   [in0]=f3,16;;

+        stf.spill   [in0]=f4,16;;

+        stf.spill   [in0]=f5,16;;

+        stf.spill   [in0]=f6,16;;

+        stf.spill   [in0]=f7,16;;

+        stf.spill   [in0]=f8,16;;

+        stf.spill   [in0]=f9,16;;

+        stf.spill   [in0]=f10,16;;

+        stf.spill   [in0]=f11,16;;

+        stf.spill   [in0]=f12,16;;

+        stf.spill   [in0]=f13,16;;

+        stf.spill   [in0]=f14,16;;

+        stf.spill   [in0]=f15,16;;

+        stf.spill   [in0]=f16,16;;

+        stf.spill   [in0]=f17,16;;

+        stf.spill   [in0]=f18,16;;

+        stf.spill   [in0]=f19,16;;

+        stf.spill   [in0]=f20,16;;

+        stf.spill   [in0]=f21,16;;

+        stf.spill   [in0]=f22,16;;

+        stf.spill   [in0]=f23,16;;

+        stf.spill   [in0]=f24,16;;

+        stf.spill   [in0]=f25,16;;

+        stf.spill   [in0]=f26,16;;

+        stf.spill   [in0]=f27,16;;

+        stf.spill   [in0]=f28,16;;

+        stf.spill   [in0]=f29,16;;

+        stf.spill   [in0]=f30,16;;

+        stf.spill   [in0]=f31,16;;

+        mov         loc0=pr;;               // save predicates

+        st8.spill   [in0]=loc0,8;;

+        st8.spill   [in0]=in1,8;;           // save b0 - b7... in1 already equals saved b0

+        mov         loc0=b1;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=b2;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=b3;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=b4;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=b5;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=b6;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=b7;;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.rsc;;           // save ar.rsc

+        st8.spill   [in0]=loc0,8;;

+        st8.spill   [in0]=in2,8;;           // save ar.bsp (in2)

+        st8.spill   [in0]=in3,8;;           // save ar.bspstore (in3)

+        st8.spill   [in0]=in4,8;;           // save ar.rnat (in4)

+        mov         loc0=ar.fcr;;           // save ar.fcr (ar21 - IA32 floating-point control register)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.eflag;;         // save ar.eflag (ar24)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.csd;;           // save ar.csd (ar25 - ia32 CS descriptor)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.ssd;;           // save ar.ssd (ar26 - ia32 ss descriptor)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.cflg;;          // save ar.cflg (ar27 - ia32 cr0 and cr4)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.fsr;;           // save ar.fsr (ar28 - ia32 floating-point status register)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.fir;;           // save ar.fir (ar29 - ia32 floating-point instruction register)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.fdr;;           // save ar.fdr (ar30 - ia32 floating-point data register)

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.ccv;;           // save ar.ccv

+        st8.spill   [in0]=loc0,8;;

+        st8.spill   [in0]=loc2,8;;          // save ar.unat (saved to loc2 earlier)

+        mov         loc0=ar.fpsr;;          // save floating point status register

+        st8.spill   [in0]=loc0,8;;

+        st8.spill   [in0]=in5,8;;           // save ar.pfs

+        mov         loc0=ar.lc;;            // save ar.lc

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ar.ec;;            // save ar.ec

+        st8.spill   [in0]=loc0,8;;

+

+        // save control registers

+        mov         loc0=cr.dcr;;           // save dcr

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.itm;;           // save itm

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.iva;;           // save iva

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.pta;;           // save pta

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.ipsr;;          // save ipsr

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.isr;;           // save isr

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.iip;;           // save iip

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.ifa;;           // save ifa

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.itir;;          // save itir

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.iipa;;          // save iipa

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.ifs;;           // save ifs

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.iim;;           // save iim

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=cr.iha;;           // save iha

+        st8.spill   [in0]=loc0,8;;

+

+        // save debug registers

+        mov         loc0=dbr[r0];;          // save dbr0 - dbr7

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=1;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=2;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=3;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=4;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=5;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=6;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=7;;

+        mov         loc0=dbr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        mov         loc0=ibr[r0];;          // save ibr0 - ibr7

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=1;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=2;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=3;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=4;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=5;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=6;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        movl        loc1=7;;

+        mov         loc0=ibr[loc1];;

+        st8.spill   [in0]=loc0,8;;

+        st8.spill   [in0]=loc3;;

+

+        br.ret.sptk.few     b0

+

+        .endp       SpillContext

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      FillContext

+//

+//  Description:

+//      Restores register context from context record.

+//

+//  Arguments:

+//          in0 = address of last element 512 byte aligned context record address

+//          in1 = modified B0

+//          in2 = modified ar.bsp

+//          in3 = modified ar.bspstore

+//          in4 = modified ar.rnat

+//          in5 = modified ar.pfs

+//

+//  Notes:

+//      loc0 - scratch

+//      loc1 - scratch

+//      loc2 - temporary application unat storage

+//      loc3 - temporary exception handler unat storage

+

+        .proc       FillContext

+FillContext:

+        alloc       loc0=6,4,0,0;;          // alloc 6 inputs, 4 locals, 0 outs

+        ld8.fill    loc3=[in0],-8;;         // int_nat (nat bits for R1-31)

+        movl        loc1=7;;                // ibr7

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        movl        loc1=6;;                // ibr6

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        movl        loc1=5;;                // ibr5

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        movl        loc1=4;;                // ibr4

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        movl        loc1=3;;                // ibr3

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        movl        loc1=2;;                // ibr2

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        movl        loc1=1;;                // ibr1

+        ld8.fill    loc0=[in0],-8;;

+        mov         ibr[loc1]=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ibr0

+        mov         ibr[r0]=loc0;;

+        movl        loc1=7;;                // dbr7

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        movl        loc1=6;;                // dbr6

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        movl        loc1=5;;                // dbr5

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        movl        loc1=4;;                // dbr4

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        movl        loc1=3;;                // dbr3

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        movl        loc1=2;;                // dbr2

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        movl        loc1=1;;                // dbr1

+        ld8.fill    loc0=[in0],-8;;

+        mov         dbr[loc1]=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // dbr0

+        mov         dbr[r0]=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // iha

+        mov         cr.iha=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // iim

+        mov         cr.iim=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ifs

+        mov         cr.ifs=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // iipa

+        mov         cr.iipa=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // itir

+        mov         cr.itir=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ifa

+        mov         cr.ifa=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // iip

+        mov         cr.iip=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // isr

+        mov         cr.isr=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ipsr

+        mov         cr.ipsr=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // pta

+        mov         cr.pta=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // iva

+        mov         cr.iva=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // itm

+        mov         cr.itm=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // dcr

+        mov         cr.dcr=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ec

+        mov         ar.ec=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // lc

+        mov         ar.lc=loc0;;

+        ld8.fill    in5=[in0],-8;;          // ar.pfs

+        ld8.fill    loc0=[in0],-8;;         // ar.fpsr

+        mov         ar.fpsr=loc0;;

+        ld8.fill    loc2=[in0],-8;;         // ar.unat - restored later...

+        ld8.fill    loc0=[in0],-8;;         // ar.ccv

+        mov         ar.ccv=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.fdr

+        mov         ar.fdr=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.fir

+        mov         ar.fir=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.fsr

+        mov         ar.fsr=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.cflg

+        mov         ar.cflg=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.ssd

+        mov         ar.ssd=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.csd

+        mov         ar.csd=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.eflag

+        mov         ar.eflag=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // ar.fcr

+        mov         ar.fcr=loc0;;

+        ld8.fill    in4=[in0],-8;;          // ar.rnat

+        ld8.fill    in3=[in0],-8;;          // bspstore

+        ld8.fill    in2=[in0],-8;;          // bsp

+        ld8.fill    loc0=[in0],-8;;         // ar.rsc

+        mov         ar.rsc=loc0;;

+        ld8.fill    loc0=[in0],-8;;         // B7 - B0

+        mov         b7=loc0;;

+        ld8.fill    loc0=[in0],-8;;

+        mov         b6=loc0;;

+        ld8.fill    loc0=[in0],-8;;

+        mov         b5=loc0;;

+        ld8.fill    loc0=[in0],-8;;

+        mov         b4=loc0;;

+        ld8.fill    loc0=[in0],-8;;

+        mov         b3=loc0;;

+        ld8.fill    loc0=[in0],-8;;

+        mov         b2=loc0;;

+        ld8.fill    loc0=[in0],-8;;

+        mov         b1=loc0;;

+        ld8.fill    in1=[in0],-8;;          // b0 is temporarily stored in in1

+        ld8.fill    loc0=[in0],-16;;        // predicates

+        mov         pr=loc0;;

+        ldf.fill    f31=[in0],-16;;

+        ldf.fill    f30=[in0],-16;;

+        ldf.fill    f29=[in0],-16;;

+        ldf.fill    f28=[in0],-16;;

+        ldf.fill    f27=[in0],-16;;

+        ldf.fill    f26=[in0],-16;;

+        ldf.fill    f25=[in0],-16;;

+        ldf.fill    f24=[in0],-16;;

+        ldf.fill    f23=[in0],-16;;

+        ldf.fill    f22=[in0],-16;;

+        ldf.fill    f21=[in0],-16;;

+        ldf.fill    f20=[in0],-16;;

+        ldf.fill    f19=[in0],-16;;

+        ldf.fill    f18=[in0],-16;;

+        ldf.fill    f17=[in0],-16;;

+        ldf.fill    f16=[in0],-16;;

+        ldf.fill    f15=[in0],-16;;

+        ldf.fill    f14=[in0],-16;;

+        ldf.fill    f13=[in0],-16;;

+        ldf.fill    f12=[in0],-16;;

+        ldf.fill    f11=[in0],-16;;

+        ldf.fill    f10=[in0],-16;;

+        ldf.fill    f9=[in0],-16;;

+        ldf.fill    f8=[in0],-16;;

+        ldf.fill    f7=[in0],-16;;

+        ldf.fill    f6=[in0],-16;;

+        ldf.fill    f5=[in0],-16;;

+        ldf.fill    f4=[in0],-16;;

+        ldf.fill    f3=[in0],-16;;

+        ldf.fill    f2=[in0],-8;;

+        mov         ar.unat=loc3;;          // restore unat (int_nat) before fill of general registers

+        ld8.fill    r31=[in0],-8;;

+        ld8.fill    r30=[in0],-8;;

+        ld8.fill    r29=[in0],-8;;

+        ld8.fill    r28=[in0],-8;;

+        ld8.fill    r27=[in0],-8;;

+        ld8.fill    r26=[in0],-8;;

+        ld8.fill    r25=[in0],-8;;

+        ld8.fill    r24=[in0],-8;;

+        ld8.fill    r23=[in0],-8;;

+        ld8.fill    r22=[in0],-8;;

+        ld8.fill    r21=[in0],-8;;

+        ld8.fill    r20=[in0],-8;;

+        ld8.fill    r19=[in0],-8;;

+        ld8.fill    r18=[in0],-8;;

+        ld8.fill    r17=[in0],-8;;

+        ld8.fill    r16=[in0],-8;;

+        ld8.fill    r15=[in0],-8;;

+        ld8.fill    r14=[in0],-8;;

+        ld8.fill    r13=[in0],-8;;

+        ld8.fill    r12=[in0],-8;;

+        ld8.fill    r11=[in0],-8;;

+        ld8.fill    r10=[in0],-8;;

+        ld8.fill    r9=[in0],-8;;

+        ld8.fill    r8=[in0],-8;;

+        ld8.fill    r7=[in0],-8;;

+        ld8.fill    r6=[in0],-8;;

+        ld8.fill    r5=[in0],-8;;

+        ld8.fill    r4=[in0],-8;;

+        ld8.fill    r3=[in0],-8;;

+        ld8.fill    r2=[in0],-8;;

+        ld8.fill    r1=[in0],-8;;

+        mov         ar.unat=loc2;;          // restore application context unat

+

+        br.ret.sptk.many    b0

+

+        .endp       FillContext

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      HookHandler

+//

+//  Description:

+//      Common branch target from hooked IVT entries.  Runs in interrupt context.

+//      Responsible for saving and restoring context and calling common C

+//      handler.  Banked registers running on bank 0 at entry.

+//

+//  Arguments:

+//      All arguments are passed in banked registers:

+//          B0_REG = Original B0

+//          SCRATCH_REG1 = IVT entry index

+//

+//  Returns:

+//      Returns via rfi

+//

+//  Notes:

+//      loc0 - scratch

+//      loc1 - scratch

+//      loc2 - vector number / mask

+//      loc3 - 16 byte aligned context record address

+//      loc4 - temporary storage of last address in context record

+

+HookHandler:

+        flushrs;;                               // Synch RSE with backing store

+        mov         SCRATCH_REG2=ar.bsp         // save interrupted context bsp

+        mov         SCRATCH_REG3=ar.bspstore    // save interrupted context bspstore

+        mov         SCRATCH_REG4=ar.rnat        // save interrupted context rnat

+        mov         SCRATCH_REG6=cr.ifs;;       // save IFS in case we need to chain...

+        cover;;                                 // creates new frame, moves old

+                                                //   CFM to IFS.

+        alloc       SCRATCH_REG5=0,5,6,0        // alloc 5 locals, 6 outs

+        ;;

+        // save banked registers to locals

+        mov         out1=B0_REG                 // out1 = Original B0

+        mov         out2=SCRATCH_REG2           // out2 = original ar.bsp

+        mov         out3=SCRATCH_REG3           // out3 = original ar.bspstore

+        mov         out4=SCRATCH_REG4           // out4 = original ar.rnat

+        mov         out5=SCRATCH_REG5           // out5 = original ar.pfs

+        mov         loc2=SCRATCH_REG1;;         // loc2 = vector number + chain flag

+        bsw.1;;                                 // switch banked registers to bank 1

+        srlz.d                                  // explicit serialize required

+                                                // now fill in context record structure

+        movl        loc3=IpfContextBuf          // Insure context record is aligned

+        add         loc0=-0x200,r0;;            // mask the lower 9 bits (align on 512 byte boundary)

+        and         loc3=loc3,loc0;;

+        add         loc3=0x200,loc3;;           // move to next 512 byte boundary

+                                                // loc3 now contains the 512 byte aligned context record

+                                                // spill register context into context record

+        mov         out0=loc3;;                 // Context record base in out0

+                                                // original B0 in out1 already

+                                                // original ar.bsp in out2 already

+                                                // original ar.bspstore in out3 already

+        br.call.sptk.few b0=SpillContext;;      // spill context

+        mov         loc4=out0                   // save modified address

+

+    // At this point, the context has been saved to the context record and we're

+    // ready to call the C part of the handler...

+

+        movl        loc0=CommonHandler;;        // obtain address of plabel

+        ld8         loc1=[loc0];;               // get entry point of CommonHandler

+        mov         b6=loc1;;                   // put it in a branch register

+        adds        loc1= 8, loc0;;             // index to GP in plabel

+        ld8         r1=[loc1];;                 // set up gp for C call

+        mov         loc1=0xfffff;;              // mask off so only vector bits are present

+        and         out0=loc2,loc1;;            // pass vector number (exception type)

+        mov         out1=loc3;;                 // pass context record address

+        br.call.sptk.few b0=b6;;                // call C handler

+

+    // We've returned from the C call, so restore the context and either rfi

+    // back to interrupted thread, or chain into the SAL if this was an external interrupt

+        mov         out0=loc4;;                 // pass address of last element in context record

+        br.call.sptk.few b0=FillContext;;       // Fill context

+        mov         b0=out1                     // fill in b0

+        mov         ar.rnat=out4

+        mov         ar.pfs=out5

+

+  // Loadrs is necessary because the debugger may have changed some values in

+  // the backing store.  The processor, however may not be aware that the

+  // stacked registers need to be reloaded from the backing store.  Therefore,

+  // we explicitly cause the RSE to refresh the stacked register's contents

+  // from the backing store.  

+        mov         loc0=ar.rsc                 // get RSC value

+        mov         loc1=ar.rsc                 // save it so we can restore it

+        movl        loc3=0xffffffffc000ffff;;   // create mask for clearing RSC.loadrs

+        and         loc0=loc0,loc3;;            // create value for RSC with RSC.loadrs==0

+        mov         ar.rsc=loc0;;               // modify RSC

+        loadrs;;                                // invalidate register stack

+        mov         ar.rsc=loc1;;               // restore original RSC

+

+        bsw.0;;                                 // switch banked registers back to bank 0

+        srlz.d;;                                // explicit serialize required

+        mov         PR_REG=pr                   // save predicates - to be restored after chaining decision

+        mov         B0_REG=b0                   // save b0 - required by chain code

+        mov         loc2=EXCPT_EXTERNAL_INTERRUPT;;

+        cmp.eq      p7,p0=SCRATCH_REG1,loc2;;   // check to see if this is the timer tick

+  (p7)  br.cond.dpnt.few    DO_CHAIN;;

+

+NO_CHAIN:

+        mov         pr=PR_REG;;

+        rfi;;                                   // we're outa here.

+

+DO_CHAIN:

+        mov         pr=PR_REG

+        mov         SCRATCH_REG1=cr.iva

+        mov         SCRATCH_REG2=PATCH_RETURN_OFFSET;;

+        add         SCRATCH_REG1=SCRATCH_REG1, SCRATCH_REG2;;

+        mov         b0=SCRATCH_REG1;;

+        br.cond.sptk.few  b0;;

+

+EndHookHandler:

+

+

+/////////////////////////////////////////////

+//

+//  Name:

+//      HookStub

+//

+//  Description:

+//      HookStub will be copied from it's loaded location into the IVT when

+//      an IVT entry is hooked.  The IVT entry does an indirect jump via B0 to

+//      HookHandler, which in turn calls into the default C handler, which calls

+//      the user-installed C handler.  The calls return and HookHandler executes

+//      an rfi.

+//

+//  Notes:

+//      Saves B0 to B0_REG

+//      Saves IVT index to SCRATCH_REG1 (immediate value is fixed up when code is copied

+//          to the IVT entry.

+

+        .global HookStub

+        .proc   HookStub

+HookStub:

+

+        mov         B0_REG=b0

+        movl        SCRATCH_REG1=HookHandler;;

+        mov         b0=SCRATCH_REG1;;

+        mov         SCRATCH_REG1=0;;// immediate value is fixed up during install of handler to be the vector number

+        br.cond.sptk.few b0

+

+        .endp       HookStub

+

+

+/////////////////////////////////////////////

+// The following code is moved into IVT entry 14 (offset 3400) which is reserved

+// in the Itanium architecture.  The patch code is located at the end of the

+// IVT entry.

+

+PatchCode:

+        mov       SCRATCH_REG0=psr

+        mov       SCRATCH_REG6=cr.ipsr

+        mov       PR_REG=pr

+        mov       B0_REG=b0;;

+

+        // turn off any virtual translations

+        movl      SCRATCH_REG1 = ~( MASK(PSR_DT,1) | MASK(PSR_RT,1));;

+        and       SCRATCH_REG1 = SCRATCH_REG0, SCRATCH_REG1;;

+        mov       psr.l = SCRATCH_REG1;;

+        srlz.d  

+        tbit.z    p14, p15 = SCRATCH_REG6, PSR_IS;;   // Check to see if we were

+                                                      // interrupted from IA32

+                                                      // context.  If so, bail out

+                                                      // and chain to SAL immediately

+ (p15)  br.cond.sptk.few Stub_IVT_Passthru;;

+        // we only want to take 1 out of 32 external interrupts to minimize the

+        // impact to system performance.  Check our interrupt count and bail

+        // out if we're not up to 32

+        movl      SCRATCH_REG1=ExternalInterruptCount;;

+        ld8       SCRATCH_REG2=[SCRATCH_REG1];;       // ExternalInterruptCount

+        tbit.z    p14, p15 = SCRATCH_REG2, 5;;        // bit 5 set?

+ (p14)  add       SCRATCH_REG2=1, SCRATCH_REG2;;      // No?  Then increment

+                                                      // ExternalInterruptCount

+                                                      // and Chain to SAL

+                                                      // immediately

+ (p14)  st8       [SCRATCH_REG1]=SCRATCH_REG2;;

+ (p14)  br.cond.sptk.few Stub_IVT_Passthru;;

+ (p15)  mov       SCRATCH_REG2=0;;                    // Yes?  Then reset

+                                                        // ExternalInterruptCount

+                                                        // and branch to

+                                                        // HookHandler

+ (p15)  st8       [SCRATCH_REG1]=SCRATCH_REG2;;

+        mov       pr=PR_REG

+        movl      SCRATCH_REG1=HookHandler;;          // SCRATCH_REG1 = entrypoint of HookHandler

+        mov       b0=SCRATCH_REG1;;                   // b0 = entrypoint of HookHandler

+        mov       SCRATCH_REG1=EXCPT_EXTERNAL_INTERRUPT;;

+        br.sptk.few b0;;                                // branch to HookHandler

+

+PatchCodeRet:

+        // fake-up an rfi to get RSE back to being coherent and insure psr has

+        // original contents when interrupt occured, then exit to SAL

+        // at this point:

+        //      cr.ifs has been modified by previous "cover"

+        //      SCRATCH_REG6 has original cr.ifs

+

+        mov       SCRATCH_REG5=cr.ipsr

+        mov       SCRATCH_REG4=cr.iip;;

+        mov       cr.ipsr=SCRATCH_REG0

+        mov       SCRATCH_REG1=ip;;

+        add       SCRATCH_REG1=0x30, SCRATCH_REG1;;

+        mov       cr.iip=SCRATCH_REG1;;

+        rfi;;                       // rfi to next instruction

+

+Stub_RfiTarget:

+        mov       cr.ifs=SCRATCH_REG6

+        mov       cr.ipsr=SCRATCH_REG5

+        mov       cr.iip=SCRATCH_REG4;;

+

+Stub_IVT_Passthru:

+        mov       pr=PR_REG                         // pr = saved predicate registers

+        mov       b0=B0_REG;;                       // b0 = saved b0

+EndPatchCode:

+

+

+/////////////////////////////////////////////

+// The following bundle is moved into IVT entry 14 (offset 0x3400) which is reserved

+// in the Itanium architecture.  This bundle will be the last bundle and will

+// be located at offset 0x37F0 in the IVT.

+

+FailsafeBranch:

+{

+        .mib

+        nop.m     0

+        nop.i     0

+        br.sptk.few -(FAILSAFE_BRANCH_OFFSET - EXT_INT_ENTRY_OFFSET - 0x10)

+}

+

+

+/////////////////////////////////////////////

+// The following bundle is moved into IVT entry 13 (offset 0x3000) which is the

+// external interrupt.  It branches to the patch code.

+

+PatchCodeNewBun0:

+{

+        .mib

+        nop.m     0

+        nop.i     0

+        br.cond.sptk.few PATCH_BRANCH

+}

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/Ds64Macros.i b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/Ds64Macros.i
new file mode 100644
index 0000000..6088ce7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/Ds64Macros.i
@@ -0,0 +1,85 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//  Ds64Macros.i

+//

+// Abstract:

+//

+//  This is set of macros used in calculating offsets in the IVT

+//

+// Revision History:

+//

+//--

+

+#define EXCPT_EXTERNAL_INTERRUPT 12

+#define MASK_0_4        0x000000000000001F  // mask bits 0 through 4

+#define SLOT0           0

+#define SLOT1           1

+#define SLOT2           2

+

+#define PSR_DT          17

+#define PSR_TB          26

+#define PSR_RT          27

+#define PSR_IS          34

+#define PSR_IT          36

+#define PSR_IC          13

+#define PSR_I           14

+#define PSR_SS          40

+#define PSR_BN          44

+#define PSR_RI_MASK     0x60000000000

+

+#define EXCPT_EXTERNAL_INTERRUPT 12

+

+#define SCRATCH_REG0    r23

+#define SCRATCH_REG1    r24

+#define SCRATCH_REG2    r25

+#define SCRATCH_REG3    r26

+#define SCRATCH_REG4    r27

+#define SCRATCH_REG5    r28

+#define SCRATCH_REG6    r29

+#define PR_REG          r30

+#define B0_REG          r31

+

+

+// EXT_INT_OFFSET is the offset of the external interrupt entry in the IVT

+#define EXT_INT_ENTRY_OFFSET    0x03000

+

+// PATCH_ENTRY_OFFSET is the offset into the IVT of the entry that is coopted (stolen)

+// for use by the handler.  The entire entry is restored when the handler is

+// unloaded.

+#define PATCH_ENTRY_OFFSET      0x03400

+

+// PATCH_BUNDLES is the number of bundles actually in the patch

+#define NUM_PATCH_BUNDLES       ((EndPatchCode - PatchCode) / 0x10)

+

+// A hard coded branch back into the external interrupt IVT entry's second bundle

+// is put here, just in case the original bundle zero did not have a branch

+// This is the last bundle in the reserved IVT entry

+#define FAILSAFE_BRANCH_OFFSET  (PATCH_ENTRY_OFFSET + 0x400 - 0x10)

+

+// the original external interrupt IVT entry bundle zero is copied and relocated

+// here... also in the reserved IVT entry

+// This is the second-to-last bundle in the reserved IVT entry

+#define RELOCATED_EXT_INT       (PATCH_ENTRY_OFFSET + 0x400 - 0x20)

+

+// The patch is actually stored at the end of IVT:PATCH_ENTRY.  The PATCH_OFFSET

+// is the offset into IVT where the patch is actually stored.  It is carefully

+// located so that when we run out of patch code, the next bundle is the

+// relocated bundle 0 from the original external interrupt handler

+#define PATCH_OFFSET            (PATCH_ENTRY_OFFSET + 0x400 - ( EndPatchCode - PatchCode ) - 0x20)

+

+#define PATCH_RETURN_OFFSET     (PATCH_ENTRY_OFFSET + 0x400 - ( EndPatchCode - PatchCodeRet ) - 0x20)

+

+// PATCH_BRANCH is used only in the new bundle that is placed at the beginning

+// of the external interrupt IVT entry.

+#define PATCH_BRANCH            (PATCH_OFFSET - EXT_INT_ENTRY_OFFSET)

+

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/common.i b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/common.i
new file mode 100644
index 0000000..a7b571b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/common.i
@@ -0,0 +1,34 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//  Common.i

+//

+// Abstract:

+//

+//  This is set of useful macros

+//

+// Revision History:

+//

+//--

+

+#define NESTED_SETUP(i,l,o,r)               \

+         alloc loc1=ar##.##pfs,i,l,o,r ;    \

+         mov loc0=b0 ;;

+

+

+#define NESTED_RETURN                       \

+         mov b0=loc0 ;                      \

+         mov ar##.##pfs=loc1 ;;             \

+         br##.##ret##.##dpnt  b0 ;;

+

+#define MASK(bp,value)  (value << bp)

+

diff --git a/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/plDebugSupport.c b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/plDebugSupport.c
new file mode 100644
index 0000000..6f2ded2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/DebugSupport/Dxe/ipf/plDebugSupport.c
@@ -0,0 +1,625 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PlDebugSupport.c

+

+Abstract:

+

+    IPF specific debug support functions

+

+Revision History

+

+--*/

+

+//

+// Master EFI header file

+//

+#include "Tiano.h"

+

+//

+// Common library header files

+//

+#include "EfiDriverLib.h"

+

+//

+// Produced protocols

+//

+#include EFI_PROTOCOL_DEFINITION (DebugSupport)

+

+//

+// private header files

+//

+#include "plDebugSupport.h"

+

+typedef struct {

+  UINT64  low;

+  UINT64  high;

+} BUNDLE;

+

+//

+// number of bundles to swap in ivt

+//

+#define NUM_BUNDLES_IN_STUB 5

+#define NUM_IVT_ENTRIES     64

+

+typedef struct {

+  BUNDLE  OrigBundles[NUM_BUNDLES_IN_STUB];

+  VOID (*RegisteredCallback) ();

+} IVT_ENTRY;

+

+STATIC

+EFI_STATUS

+ManageIvtEntryTable (

+  IN  EFI_EXCEPTION_TYPE                ExceptionType,

+  IN  BUNDLE                NewBundles[4],

+  IN  VOID                  (*NewCallback) ()

+  );

+

+STATIC

+VOID

+HookEntry (

+  IN  EFI_EXCEPTION_TYPE                ExceptionType,

+  IN  BUNDLE                NewBundles[4],

+  IN  VOID                  (*NewCallback) ()

+  );

+

+STATIC

+VOID

+UnhookEntry (

+  IN  EFI_EXCEPTION_TYPE    ExceptionType

+  );

+

+STATIC

+VOID

+ChainExternalInterrupt (

+  IN  VOID                  (*NewCallback) ()

+  );

+

+STATIC

+VOID

+UnchainExternalInterrupt (

+  VOID

+  );

+

+STATIC

+VOID

+GetHandlerEntryPoint (

+  UINTN                     HandlerIndex,

+  VOID                      **EntryPoint

+  );

+

+IVT_ENTRY IvtEntryTable[NUM_IVT_ENTRIES];

+

+//

+// IPF context record is overallocated by 512 bytes to guarantee a 512 byte alignment exists

+// within the buffer and still have a large enough buffer to hold a whole IPF context record.

+//

+UINT8     IpfContextBuf[sizeof (EFI_SYSTEM_CONTEXT_IPF) + 512];

+

+//

+// The PatchSaveBuffer is used to store the original bundles from the IVT where it is patched

+// with the common handler.

+//

+UINT8     PatchSaveBuffer[0x400];

+UINTN     ExternalInterruptCount;

+

+EFI_STATUS

+plInitializeDebugSupportDriver (

+  VOID

+  )

+/*++

+

+Routine Description:

+  IPF specific DebugSupport driver initialization.  Must be public because it's

+  referenced from DebugSupport.c

+

+Arguments:

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  gBS->SetMem (IvtEntryTable, sizeof (IvtEntryTable), 0);

+  ExternalInterruptCount = 0;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+plUnloadDebugSupportDriver (

+  IN EFI_HANDLE       ImageHandle

+  )

+/*++

+

+Routine Description:

+  Unload handler that is called during UnloadImage() - deallocates pool memory

+  used by the driver.  Must be public because it's referenced from DebugSuport.c

+

+Arguments:

+  IN EFI_HANDLE       ImageHandle

+

+Returns:

+

+  EFI_STATUS - anything other than EFI_SUCCESS indicates the callback was not registered.

+

+--*/

+// TODO:    ImageHandle - add argument and description to function comment

+{

+  EFI_EXCEPTION_TYPE  ExceptionType;

+

+  for (ExceptionType = 0; ExceptionType < NUM_IVT_ENTRIES; ExceptionType++) {

+    ManageIvtEntryTable (ExceptionType, NULL, NULL);

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+CommonHandler (

+  IN EFI_EXCEPTION_TYPE ExceptionType,

+  IN EFI_SYSTEM_CONTEXT Context

+  )

+/*++

+

+Routine Description:

+  C routine that is called for all registered exceptions.  This is the main

+  exception dispatcher.  Must be public because it's referenced from AsmFuncs.s.

+

+Arguments:

+  IN EFI_EXCEPTION_TYPE ExceptionType,

+  IN EFI_SYSTEM_CONTEXT Context

+

+Returns:

+

+  Nothing

+  

+--*/

+// TODO:    ExceptionType - add argument and description to function comment

+// TODO:    Context - add argument and description to function comment

+{

+  static BOOLEAN  InHandler = FALSE;

+

+  DEBUG_CODE (

+    if (InHandler) {

+      EfiDebugPrint (EFI_D_GENERIC, "ERROR: Re-entered debugger!\n"

+                                    "       ExceptionType == %X\n"

+                                    "       Context       == %X\n"

+                                    "       Context.SystemContextIpf->CrIip  == %X\n"

+                                    "       Context.SystemContextIpf->CrIpsr == %X\n"

+                                    "       InHandler     == %X\n",

+                                    ExceptionType, 

+                                    Context, 

+                                    Context.SystemContextIpf->CrIip,

+                                    Context.SystemContextIpf->CrIpsr,

+                                    InHandler);

+    }

+  )

+  ASSERT (!InHandler);

+  InHandler = TRUE;

+  if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) {

+    if (ExceptionType != EXCEPT_IPF_EXTERNAL_INTERRUPT) {

+      IvtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, Context.SystemContextIpf);

+    } else {

+      IvtEntryTable[ExceptionType].RegisteredCallback (Context.SystemContextIpf);

+    }

+  } else {

+    ASSERT (0);

+  }

+

+  InHandler = FALSE;

+}

+

+STATIC

+VOID

+GetHandlerEntryPoint (

+  UINTN   HandlerIndex,

+  VOID    **EntryPoint

+  )

+/*++

+

+Routine Description:

+  Given an integer number, return the physical address of the entry point in the IFT

+  

+Arguments:

+  UINTN   HandlerIndex, 

+  VOID    ** EntryPoint

+

+Returns:

+

+  Nothing

+  

+--*/

+// TODO:    HandlerIndex - add argument and description to function comment

+// TODO:    EntryPoint - add argument and description to function comment

+{

+  UINT8 *TempPtr;

+

+  //

+  // get base address of IVT

+  //

+  TempPtr = GetIva ();

+

+  if (HandlerIndex < 20) {

+    //

+    // first 20 provide 64 bundles per vector

+    //

+    TempPtr += 0x400 * HandlerIndex;

+  } else {

+    //

+    // the rest provide 16 bundles per vector

+    //

+    TempPtr += 0x5000 + 0x100 * (HandlerIndex - 20);

+  }

+

+  *EntryPoint = (VOID *) TempPtr;

+}

+

+STATIC

+EFI_STATUS

+ManageIvtEntryTable (

+  IN  EFI_EXCEPTION_TYPE                                         ExceptionType,

+  IN  BUNDLE                       NewBundles[NUM_BUNDLES_IN_STUB],

+  IN  VOID                         (*NewCallback) ()

+  )

+/*++

+

+Routine Description:

+  This is the worker function that installs and removes all handlers

+  

+Arguments:

+  IN  EFI_EXCEPTION_TYPE           ExceptionType,

+  IN  BUNDLE                       NewBundles[NUM_BUNDLES_IN_STUB],

+  IN  VOID                         (*NewCallback) ()

+

+Returns:

+

+  EFI_STATUS - any return other than EFI_SUCCESS indicates the request was not

+  satisfied.

+  

+--*/

+// TODO:    ExceptionType - add argument and description to function comment

+// TODO:    ] - add argument and description to function comment

+// TODO:    ) - add argument and description to function comment

+// TODO:    EFI_ALREADY_STARTED - add return value to function comment

+{

+  BUNDLE  *B0Ptr;

+  UINT64  InterruptFlags;

+  EFI_TPL OldTpl;

+

+  //

+  // Get address of bundle 0

+  //

+  GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);

+

+  if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) {

+    //

+    // we've already installed to this vector

+    //

+    if (NewCallback != NULL) {

+      //

+      // if the input handler is non-null, error

+      //

+      return EFI_ALREADY_STARTED;

+    } else {

+      //

+      // else remove the previously installed handler

+      //

+      OldTpl          = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+      InterruptFlags  = ProgramInterruptFlags (DISABLE_INTERRUPTS);

+      if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) {

+        UnchainExternalInterrupt ();

+      } else {

+        UnhookEntry (ExceptionType);

+      }

+

+      ProgramInterruptFlags (InterruptFlags);

+      gBS->RestoreTPL (OldTpl);

+      //

+      // re-init IvtEntryTable

+      //

+      gBS->SetMem (&IvtEntryTable[ExceptionType], sizeof (IVT_ENTRY), 0);

+    }

+  } else {

+    //

+    // no user handler installed on this vector

+    //

+    if (NewCallback != NULL) {

+      OldTpl          = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+      InterruptFlags  = ProgramInterruptFlags (DISABLE_INTERRUPTS);

+      if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) {

+        ChainExternalInterrupt (NewCallback);

+      } else {

+        HookEntry (ExceptionType, NewBundles, NewCallback);

+      }

+

+      ProgramInterruptFlags (InterruptFlags);

+      gBS->RestoreTPL (OldTpl);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+VOID

+HookEntry (

+  IN  EFI_EXCEPTION_TYPE  ExceptionType,

+  IN  BUNDLE              NewBundles[4],

+  IN  VOID                (*NewCallback) ()

+  )

+/*++

+

+Routine Description:

+  Saves original IVT contents and inserts a few new bundles which are fixed up

+  to store the ExceptionType and then call the common handler.

+  

+Arguments:

+  IN  EFI_EXCEPTION_TYPE  ExceptionType,

+  IN  BUNDLE              NewBundles[4],

+  IN  VOID                (*NewCallback) ()

+

+Returns:

+

+  Nothing

+    

+--*/

+// TODO:    ExceptionType - add argument and description to function comment

+// TODO:    ] - add argument and description to function comment

+// TODO:    ) - add argument and description to function comment

+{

+  BUNDLE  *FixupBundle;

+  BUNDLE  *B0Ptr;

+

+  //

+  // Get address of bundle 0

+  //

+  GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);

+

+  //

+  // copy original bundles from IVT to IvtEntryTable so we can restore them later

+  //

+  gBS->CopyMem (

+        IvtEntryTable[ExceptionType].OrigBundles,

+        B0Ptr,

+        sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB

+        );

+  //

+  // insert new B0

+  //

+  gBS->CopyMem (B0Ptr, NewBundles, sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB);

+

+  //

+  // fixup IVT entry so it stores its index and whether or not to chain...

+  //

+  FixupBundle = B0Ptr + 2;

+  FixupBundle->high |= ExceptionType << 36;

+

+  InstructionCacheFlush (B0Ptr, 5);

+  IvtEntryTable[ExceptionType].RegisteredCallback = NewCallback;

+}

+

+STATIC

+VOID

+UnhookEntry (

+  IN  EFI_EXCEPTION_TYPE  ExceptionType

+  )

+/*++

+

+Routine Description:

+  Restores original IVT contents when unregistering a callback function

+  

+Arguments:

+  IN  EFI_EXCEPTION_TYPE  ExceptionType,

+

+Returns:

+

+  Nothing

+    

+--*/

+// TODO:    ExceptionType - add argument and description to function comment

+{

+  BUNDLE  *B0Ptr;

+

+  //

+  // Get address of bundle 0

+  //

+  GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);

+  //

+  // restore original bundles in IVT

+  //

+  gBS->CopyMem (

+        B0Ptr,

+        IvtEntryTable[ExceptionType].OrigBundles,

+        sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB

+        );

+  InstructionCacheFlush (B0Ptr, 5);

+}

+

+STATIC

+VOID

+ChainExternalInterrupt (

+  IN  VOID  (*NewCallback) ()

+  )

+/*++

+

+Routine Description:

+  Sets up cache flush and calls assembly function to chain external interrupt.

+  Records new callback in IvtEntryTable.

+  

+Arguments:

+  IN  VOID  (*NewCallback) ()

+

+Returns:

+

+  Nothing

+    

+--*/

+// TODO:    ) - add argument and description to function comment

+{

+  VOID  *Start;

+

+  Start = (VOID *) ((UINT8 *) GetIva () + 0x400 * EXCEPT_IPF_EXTERNAL_INTERRUPT + 0x400);

+  IvtEntryTable[EXCEPT_IPF_EXTERNAL_INTERRUPT].RegisteredCallback = NewCallback;

+  ChainHandler ();

+  InstructionCacheFlush (Start, 0x400);

+}

+

+STATIC

+VOID

+UnchainExternalInterrupt (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Sets up cache flush and calls assembly function to restore external interrupt.

+  Removes registered callback from IvtEntryTable.

+  

+Arguments:

+  Nothing

+  

+Returns:

+

+  Nothing

+    

+--*/

+{

+  VOID  *Start;

+

+  Start = (VOID *) ((UINT8 *) GetIva () + 0x400 * EXCEPT_IPF_EXTERNAL_INTERRUPT + 0x400);

+  UnchainHandler ();

+  InstructionCacheFlush (Start, 0x400);

+  IvtEntryTable[EXCEPT_IPF_EXTERNAL_INTERRUPT].RegisteredCallback = NULL;

+}

+

+//

+// The rest of the functions in this file are all member functions for the

+// DebugSupport protocol

+//

+

+EFI_STATUS

+EFIAPI

+GetMaximumProcessorIndex (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL    *This,

+  OUT UINTN                        *MaxProcessorIndex

+  )

+/*++

+

+Routine Description: This is a DebugSupport protocol member function.  Hard

+  coded to support only 1 processor for now.

+

+Arguments:

+

+Returns: Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    MaxProcessorIndex - add argument and description to function comment

+{

+  *MaxProcessorIndex = 0;

+  return (EFI_SUCCESS);

+}

+

+EFI_STATUS

+EFIAPI

+RegisterPeriodicCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,

+  IN UINTN                          ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK          NewPeriodicCallback

+  )

+/*++

+

+Routine Description:

+  DebugSupport protocol member function

+

+Arguments:

+  IN EFI_DEBUG_SUPPORT_PROTOCOL   *This,

+  IN UINTN                        ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK        NewPeriodicCallback

+

+Returns:

+

+  EFI_STATUS - anything other than EFI_SUCCESS indicates the callback was not registered.

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ProcessorIndex - add argument and description to function comment

+// TODO:    NewPeriodicCallback - add argument and description to function comment

+{

+  return ManageIvtEntryTable (EXCEPT_IPF_EXTERNAL_INTERRUPT, NULL, NewPeriodicCallback);

+}

+

+EFI_STATUS

+EFIAPI

+RegisterExceptionCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL    *This,

+  IN UINTN                         ProcessorIndex,

+  IN EFI_EXCEPTION_CALLBACK        NewCallback,

+  IN EFI_EXCEPTION_TYPE            ExceptionType

+  )

+/*++

+

+Routine Description:

+  DebugSupport protocol member function

+

+Arguments:

+  IN EFI_DEBUG_SUPPORT_PROTOCOL   *This,

+  IN EFI_EXCEPTION_CALLBACK       NewCallback,

+  IN EFI_EXCEPTION_TYPE           ExceptionType

+

+Returns:

+

+  EFI_STATUS - anything other than EFI_SUCCESS indicates the callback was not registered.

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ProcessorIndex - add argument and description to function comment

+// TODO:    NewCallback - add argument and description to function comment

+// TODO:    ExceptionType - add argument and description to function comment

+{

+  return ManageIvtEntryTable (

+          ExceptionType,

+          (BUNDLE *) ((EFI_PLABEL *) HookStub)->EntryPoint,

+          NewCallback

+          );

+}

+

+EFI_STATUS

+EFIAPI

+InvalidateInstructionCache (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL    *This,

+  IN UINTN                         ProcessorIndex,

+  IN VOID                          *Start,

+  IN UINTN                         Length

+  )

+/*++

+

+Routine Description:

+  DebugSupport protocol member function.  Calls assembly routine to flush cache.

+

+Arguments:

+

+Returns:

+  EFI_SUCCESS

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ProcessorIndex - add argument and description to function comment

+// TODO:    Start - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+{

+  InstructionCacheFlush (Start, Length);

+  return (EFI_SUCCESS);

+}

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/ComponentName.c
new file mode 100644
index 0000000..078bdab
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/ComponentName.c
@@ -0,0 +1,108 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  ComponentName.c

+

+Abstract:

+  Component name protocol member functions for DebugPort...

+  

+--*/

+

+#include "DebugPort.h"

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gDebugPortComponentName = {

+  DebugPortComponentNameGetDriverName,

+  DebugPortComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mDebugPortDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"DebugPort Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+DebugPortComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+           Language,

+           gDebugPortComponentName.SupportedLanguages,

+           mDebugPortDriverNameTable,

+           DriverName

+           );

+}

+

+EFI_STATUS

+EFIAPI

+DebugPortComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    The debug port driver does not support GetControllerName, so this function

+    is just stubbed and returns EFI_UNSUPPORTED.

+

+  Arguments:

+    Per EFI 1.10 driver model

+

+  Returns:

+    EFI_UNSUPPORTED

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.c b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.c
new file mode 100644
index 0000000..a24bfd0
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.c
@@ -0,0 +1,833 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    DebugPort.c

+

+Abstract:

+

+    Top level C file for debugport driver.  Contains initialization function.

+    This driver layers on top of SerialIo.

+    

+    ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM

+    INTERRUPT CONTEXT.

+

+Revision History

+

+--*/

+

+

+#include "DebugPort.h"

+

+//

+// Misc. functions local to this module

+//

+STATIC

+VOID

+GetDebugPortVariable (

+  DEBUGPORT_DEVICE  *DebugPortDevice

+  );

+

+EFI_STATUS

+EFIAPI

+ImageUnloadHandler (

+  EFI_HANDLE ImageHandle

+  );

+

+//

+// Globals

+//

+

+EFI_DRIVER_BINDING_PROTOCOL gDebugPortDriverBinding = {

+  DebugPortSupported,

+  DebugPortStart,

+  DebugPortStop,

+  DEBUGPORT_DRIVER_VERSION,

+  NULL,

+  NULL

+};

+

+DEBUGPORT_DEVICE  *gDebugPortDevice;

+static UINT32     mHid16550;

+static UINT32     mHidStdPcComPort;

+

+//

+// implementation code

+//

+

+EFI_STATUS

+EFIAPI

+InitializeDebugPortDriver (

+  IN EFI_HANDLE             ImageHandle,

+  IN EFI_SYSTEM_TABLE       *SystemTable

+  )

+/*++

+

+Routine Description:

+  Driver entry point.  Reads DebugPort variable to determine what device and settings

+  to use as the debug port.  Binds exclusively to SerialIo. Reverts to defaults \

+  if no variable is found.  

+  

+  Creates debugport and devicepath protocols on new handle.

+

+Arguments:

+  ImageHandle,

+  SystemTable

+

+Returns:

+

+  EFI_UNSUPPORTED

+  EFI_OUT_OF_RESOURCES

+

+--*/

+{

+  mHid16550         = EFI_ACPI_16550UART_HID;

+  mHidStdPcComPort  = EFI_ACPI_PC_COMPORT_HID;

+

+  //

+  // Allocate and Initialize dev structure

+  //

+  gDebugPortDevice = AllocateZeroPool (sizeof (DEBUGPORT_DEVICE));

+  if (gDebugPortDevice == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Fill in static and default pieces of device structure first.

+  //

+  gDebugPortDevice->Signature = DEBUGPORT_DEVICE_SIGNATURE;

+

+  gDebugPortDevice->DebugPortInterface.Reset = DebugPortReset;

+  gDebugPortDevice->DebugPortInterface.Read = DebugPortRead;

+  gDebugPortDevice->DebugPortInterface.Write = DebugPortWrite;

+  gDebugPortDevice->DebugPortInterface.Poll = DebugPortPoll;

+

+  gDebugPortDevice->BaudRate = DEBUGPORT_UART_DEFAULT_BAUDRATE;

+  gDebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;

+  gDebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;

+  gDebugPortDevice->Parity = DEBUGPORT_UART_DEFAULT_PARITY;

+  gDebugPortDevice->DataBits = DEBUGPORT_UART_DEFAULT_DATA_BITS;

+  gDebugPortDevice->StopBits = DEBUGPORT_UART_DEFAULT_STOP_BITS;

+

+  return EFI_SUCCESS;

+}

+//

+// DebugPort driver binding member functions...

+//

+EFI_STATUS

+EFIAPI

+DebugPortSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Checks to see that there's not already a DebugPort interface somewhere.  If so,

+  fail.

+  

+  If there's a DEBUGPORT variable, the device path must match exactly.  If there's

+  no DEBUGPORT variable, then device path is not checked and does not matter.

+  

+  Checks to see that there's a serial io interface on the controller handle

+  that can be bound BY_DRIVER | EXCLUSIVE.

+  

+  If all these tests succeed, then we return EFI_SUCCESS, else, EFI_UNSUPPORTED

+  or other error returned by OpenProtocol.

+

+Arguments:

+  This

+  ControllerHandle

+  RemainingDevicePath

+  

+Returns:

+  EFI_UNSUPPORTED

+  EFI_OUT_OF_RESOURCES

+  EFI_SUCCESS

+  

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *Dp1;

+  EFI_DEVICE_PATH_PROTOCOL  *Dp2;

+  EFI_SERIAL_IO_PROTOCOL    *SerialIo;

+  EFI_DEBUGPORT_PROTOCOL    *DebugPortInterface;

+  EFI_HANDLE                TempHandle;

+

+  //

+  // Check to see that there's not a debugport protocol already published

+  //

+  if (gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **) &DebugPortInterface) != EFI_NOT_FOUND) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Read DebugPort variable to determine debug port selection and parameters

+  //

+  GetDebugPortVariable (gDebugPortDevice);

+

+  if (gDebugPortDevice->DebugPortVariable != NULL) {

+    //

+    // There's a DEBUGPORT variable, so do LocateDevicePath and check to see if

+    // the closest matching handle matches the controller handle, and if it does,

+    // check to see that the remaining device path has the DebugPort GUIDed messaging

+    // device path only.  Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.

+    //

+    Dp1 = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) gDebugPortDevice->DebugPortVariable);

+    if (Dp1 == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Dp2 = Dp1;

+

+    Status = gBS->LocateDevicePath (

+                    &gEfiSerialIoProtocolGuid,

+                    &Dp2,

+                    &TempHandle

+                    );

+

+    if (Status == EFI_SUCCESS && TempHandle != ControllerHandle) {

+      Status = EFI_UNSUPPORTED;

+    }

+

+    if (Status == EFI_SUCCESS && (Dp2->Type != 3 || Dp2->SubType != 10 || *((UINT16 *) Dp2->Length) != 20)) {

+      Status = EFI_UNSUPPORTED;

+    }

+

+    if (Status == EFI_SUCCESS && CompareMem (&gEfiDebugPortDevicePathGuid, Dp2 + 1, sizeof (EFI_GUID))) {

+      Status = EFI_UNSUPPORTED;

+    }

+

+    gBS->FreePool (Dp1);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSerialIoProtocolGuid,

+                  (VOID **) &SerialIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiSerialIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DebugPortStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Binds exclusively to serial io on the controller handle.  Produces DebugPort

+  protocol and DevicePath on new handle.

+

+Arguments:

+  This

+  ControllerHandle

+  RemainingDevicePath

+  

+Returns:

+  EFI_OUT_OF_RESOURCES

+  EFI_SUCCESS

+--*/

+{

+  EFI_STATUS                Status;

+  DEBUGPORT_DEVICE_PATH     DebugPortDP;

+  EFI_DEVICE_PATH_PROTOCOL  EndDP;

+  EFI_DEVICE_PATH_PROTOCOL  *Dp1;

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSerialIoProtocolGuid,

+                  (VOID **) &gDebugPortDevice->SerialIoBinding,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gDebugPortDevice->SerialIoDeviceHandle = ControllerHandle;

+

+  //

+  // Initialize the Serial Io interface...

+  //

+  Status = gDebugPortDevice->SerialIoBinding->SetAttributes (

+                                                gDebugPortDevice->SerialIoBinding,

+                                                gDebugPortDevice->BaudRate,

+                                                gDebugPortDevice->ReceiveFifoDepth,

+                                                gDebugPortDevice->Timeout,

+                                                gDebugPortDevice->Parity,

+                                                gDebugPortDevice->DataBits,

+                                                gDebugPortDevice->StopBits

+                                                );

+  if (EFI_ERROR (Status)) {

+    gDebugPortDevice->BaudRate          = 0;

+    gDebugPortDevice->Parity            = DefaultParity;

+    gDebugPortDevice->DataBits          = 0;

+    gDebugPortDevice->StopBits          = DefaultStopBits;

+    gDebugPortDevice->ReceiveFifoDepth  = 0;

+    Status = gDebugPortDevice->SerialIoBinding->SetAttributes (

+                                                  gDebugPortDevice->SerialIoBinding,

+                                                  gDebugPortDevice->BaudRate,

+                                                  gDebugPortDevice->ReceiveFifoDepth,

+                                                  gDebugPortDevice->Timeout,

+                                                  gDebugPortDevice->Parity,

+                                                  gDebugPortDevice->DataBits,

+                                                  gDebugPortDevice->StopBits

+                                                  );

+    if (EFI_ERROR (Status)) {

+      gBS->CloseProtocol (

+            ControllerHandle,

+            &gEfiSerialIoProtocolGuid,

+            This->DriverBindingHandle,

+            ControllerHandle

+            );

+      return Status;

+    }

+  }

+

+  gDebugPortDevice->SerialIoBinding->Reset (gDebugPortDevice->SerialIoBinding);

+

+  //

+  // Create device path instance for DebugPort

+  //

+  DebugPortDP.Header.Type     = MESSAGING_DEVICE_PATH;

+  DebugPortDP.Header.SubType  = MSG_VENDOR_DP;

+  SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP));

+  gBS->CopyMem (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid, sizeof (EFI_GUID));

+

+  Dp1 = DevicePathFromHandle (ControllerHandle);

+  if (Dp1 == NULL) {

+    Dp1 = &EndDP;

+    SetDevicePathEndNode (Dp1);

+  }

+

+  gDebugPortDevice->DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *) &DebugPortDP);

+  if (gDebugPortDevice->DebugPortDevicePath == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Publish DebugPort and Device Path protocols

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &gDebugPortDevice->DebugPortDeviceHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  gDebugPortDevice->DebugPortDevicePath,

+                  &gEfiDebugPortProtocolGuid,

+                  &gDebugPortDevice->DebugPortInterface,

+                  NULL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiSerialIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return Status;

+  }

+  //

+  // Connect debugport child to serial io

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSerialIoProtocolGuid,

+                  (VOID **) &gDebugPortDevice->SerialIoBinding,

+                  This->DriverBindingHandle,

+                  gDebugPortDevice->DebugPortDeviceHandle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    DEBUG_CODE (

+      UINTN  BufferSize;

+

+      BufferSize = 48;

+      DebugPortWrite (

+        &gDebugPortDevice->DebugPortInterface,

+        0,

+        &BufferSize,

+        "DebugPort driver failed to open child controller\n\n"

+        );

+    );

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiSerialIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return Status;

+  }

+

+  DEBUG_CODE (

+    UINTN  BufferSize;

+

+    BufferSize = 38;

+    DebugPortWrite (

+      &gDebugPortDevice->DebugPortInterface,

+      0,

+      &BufferSize,

+      "Hello World from the DebugPort driver\n\n"

+      );

+  );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DebugPortStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+  We're never intending to be stopped via the driver model so this just returns

+  EFI_UNSUPPORTED

+

+Arguments:

+  Per EFI 1.10 driver model

+  

+Returns:

+  EFI_UNSUPPORTED

+  EFI_SUCCESS

+  

+--*/

+{

+  EFI_STATUS  Status;

+

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiSerialIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+

+    gDebugPortDevice->SerialIoBinding = NULL;

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+

+    gBS->FreePool (gDebugPortDevice->DebugPortDevicePath);

+

+    return EFI_SUCCESS;

+  } else {

+    //

+    // Disconnect SerialIo child handle

+    //

+    Status = gBS->CloseProtocol (

+                    gDebugPortDevice->SerialIoDeviceHandle,

+                    &gEfiSerialIoProtocolGuid,

+                    This->DriverBindingHandle,

+                    gDebugPortDevice->DebugPortDeviceHandle

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Unpublish our protocols (DevicePath, DebugPort)

+    //

+    Status = gBS->UninstallMultipleProtocolInterfaces (

+                    gDebugPortDevice->DebugPortDeviceHandle,

+                    &gEfiDevicePathProtocolGuid,

+                    gDebugPortDevice->DebugPortDevicePath,

+                    &gEfiDebugPortProtocolGuid,

+                    &gDebugPortDevice->DebugPortInterface,

+                    NULL

+                    );

+

+    if (EFI_ERROR (Status)) {

+      gBS->OpenProtocol (

+            ControllerHandle,

+            &gEfiSerialIoProtocolGuid,

+            (VOID **) &gDebugPortDevice->SerialIoBinding,

+            This->DriverBindingHandle,

+            gDebugPortDevice->DebugPortDeviceHandle,

+            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+            );

+    } else {

+      gDebugPortDevice->DebugPortDeviceHandle = NULL;

+    }

+  }

+

+  return Status;

+}

+//

+// Debugport protocol member functions

+//

+EFI_STATUS

+EFIAPI

+DebugPortReset (

+  IN EFI_DEBUGPORT_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+  DebugPort protocol member function.  Calls SerialIo:GetControl to flush buffer.

+  We cannot call SerialIo:SetAttributes because it uses pool services, which use

+  locks, which affect TPL, so it's not interrupt context safe or re-entrant.

+  SerialIo:Reset() calls SetAttributes, so it can't be used either.

+  

+  The port itself should be fine since it was set up during initialization.  

+  

+Arguments:

+  This

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  DEBUGPORT_DEVICE  *DebugPortDevice;

+  UINTN             BufferSize;

+  UINTN             BitBucket;

+

+  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);

+  while (This->Poll (This) == EFI_SUCCESS) {

+    BufferSize = 1;

+    This->Read (This, 0, &BufferSize, &BitBucket);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DebugPortRead (

+  IN EFI_DEBUGPORT_PROTOCOL   *This,

+  IN UINT32                   Timeout,

+  IN OUT UINTN                *BufferSize,

+  IN VOID                     *Buffer

+  )

+/*++

+

+Routine Description:

+  DebugPort protocol member function.  Calls SerialIo:Read() after setting

+  if it's different than the last SerialIo access.

+  

+Arguments:

+  IN EFI_DEBUGPORT_PROTOCOL   *This

+  IN UINT32                   Timeout,

+  IN OUT UINTN                *BufferSize,

+  IN VOID                     *Buffer

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+{

+  DEBUGPORT_DEVICE  *DebugPortDevice;

+  UINTN             LocalBufferSize;

+  EFI_STATUS        Status;

+  UINT8             *BufferPtr;

+

+  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);

+  BufferPtr       = Buffer;

+  LocalBufferSize = *BufferSize;

+  do {

+    Status = DebugPortDevice->SerialIoBinding->Read (

+                                                DebugPortDevice->SerialIoBinding,

+                                                &LocalBufferSize,

+                                                BufferPtr

+                                                );

+    if (Status == EFI_TIMEOUT) {

+      if (Timeout > DEBUGPORT_UART_DEFAULT_TIMEOUT) {

+        Timeout -= DEBUGPORT_UART_DEFAULT_TIMEOUT;

+      } else {

+        Timeout = 0;

+      }

+    } else if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    BufferPtr += LocalBufferSize;

+    LocalBufferSize = *BufferSize - (BufferPtr - (UINT8 *) Buffer);

+  } while (LocalBufferSize != 0 && Timeout > 0);

+

+  *BufferSize = (UINTN) (BufferPtr - (UINT8 *) Buffer);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+DebugPortWrite (

+  IN EFI_DEBUGPORT_PROTOCOL   *This,

+  IN UINT32                   Timeout,

+  IN OUT UINTN                *BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+  DebugPort protocol member function.  Calls SerialIo:Write() Writes 8 bytes at

+  a time and does a GetControl between 8 byte writes to help insure reads are

+  interspersed This is poor-man's flow control..

+  

+Arguments:

+  This               - Pointer to DebugPort protocol

+  Timeout            - Timeout value

+  BufferSize         - On input, the size of Buffer. 

+                       On output, the amount of data actually written.

+  Buffer             - Pointer to buffer to write

+

+Returns:

+  EFI_SUCCESS        - The data was written.

+  EFI_DEVICE_ERROR   - The device reported an error.

+  EFI_TIMEOUT        - The data write was stopped due to a timeout.

+

+--*/

+{

+  DEBUGPORT_DEVICE  *DebugPortDevice;

+  UINTN             Position;

+  UINTN             WriteSize;

+  EFI_STATUS        Status;

+  UINT32            SerialControl;

+

+  Status          = EFI_SUCCESS;

+  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);

+

+  WriteSize       = 8;

+  for (Position = 0; Position < *BufferSize && !EFI_ERROR (Status); Position += WriteSize) {

+    DebugPortDevice->SerialIoBinding->GetControl (

+                                        DebugPortDevice->SerialIoBinding,

+                                        &SerialControl

+                                        );

+    if (*BufferSize - Position < 8) {

+      WriteSize = *BufferSize - Position;

+    }

+

+    Status = DebugPortDevice->SerialIoBinding->Write (

+                                                DebugPortDevice->SerialIoBinding,

+                                                &WriteSize,

+                                                &((UINT8 *) Buffer)[Position]

+                                                );

+  }

+

+  *BufferSize = Position;

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+DebugPortPoll (

+  IN EFI_DEBUGPORT_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+  DebugPort protocol member function.  Calls SerialIo:Write() after setting

+  if it's different than the last SerialIo access.

+  

+Arguments:

+  IN EFI_DEBUGPORT_PROTOCOL   *This

+

+Returns:

+  EFI_SUCCESS - At least 1 character is ready to be read from the DebugPort interface

+  EFI_NOT_READY - There are no characters ready to read from the DebugPort interface

+  EFI_DEVICE_ERROR - A hardware failure occured... (from SerialIo)

+

+--*/

+{

+  EFI_STATUS        Status;

+  UINT32            SerialControl;

+  DEBUGPORT_DEVICE  *DebugPortDevice;

+

+  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);

+

+  Status = DebugPortDevice->SerialIoBinding->GetControl (

+                                              DebugPortDevice->SerialIoBinding,

+                                              &SerialControl

+                                              );

+

+  if (!EFI_ERROR (Status)) {

+    if (SerialControl & EFI_SERIAL_INPUT_BUFFER_EMPTY) {

+      Status = EFI_NOT_READY;

+    } else {

+      Status = EFI_SUCCESS;

+    }

+  }

+

+  return Status;

+}

+//

+// Misc. functions local to this module..

+//

+STATIC

+VOID

+GetDebugPortVariable (

+  DEBUGPORT_DEVICE            *DebugPortDevice

+  )

+/*++

+

+Routine Description:

+  Local worker function to obtain device path information from DebugPort variable.

+  Records requested settings in DebugPort device structure.

+  

+Arguments:

+  DEBUGPORT_DEVICE  *DebugPortDevice,

+

+Returns:

+

+  Nothing

+

+--*/

+{

+  UINTN                     DataSize;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_STATUS                Status;

+

+  DataSize = 0;

+

+  Status = gRT->GetVariable (

+                  (CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,

+                  &gEfiDebugPortVariableGuid,

+                  NULL,

+                  &DataSize,

+                  DebugPortDevice->DebugPortVariable

+                  );

+

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    if (gDebugPortDevice->DebugPortVariable != NULL) {

+      gBS->FreePool (gDebugPortDevice->DebugPortVariable);

+    }

+

+    DebugPortDevice->DebugPortVariable = AllocatePool (DataSize);

+    if (DebugPortDevice->DebugPortVariable != NULL) {

+      gRT->GetVariable (

+            (CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,

+            &gEfiDebugPortVariableGuid,

+            NULL,

+            &DataSize,

+            DebugPortDevice->DebugPortVariable

+            );

+      DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DebugPortDevice->DebugPortVariable;

+      while (!EfiIsDevicePathEnd (DevicePath) && !EfiIsUartDevicePath (DevicePath)) {

+        DevicePath = EfiNextDevicePathNode (DevicePath);

+      }

+

+      if (EfiIsDevicePathEnd (DevicePath)) {

+        gBS->FreePool (gDebugPortDevice->DebugPortVariable);

+        DebugPortDevice->DebugPortVariable = NULL;

+      } else {

+        gBS->CopyMem (

+              &DebugPortDevice->BaudRate,

+              &((UART_DEVICE_PATH *) DevicePath)->BaudRate,

+              sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)

+              );

+        DebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;

+        DebugPortDevice->Timeout          = DEBUGPORT_UART_DEFAULT_TIMEOUT;

+        gBS->CopyMem (

+              &DebugPortDevice->Parity,

+              &((UART_DEVICE_PATH *) DevicePath)->Parity,

+              sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)

+              );

+        gBS->CopyMem (

+              &DebugPortDevice->DataBits,

+              &((UART_DEVICE_PATH *) DevicePath)->DataBits,

+              sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)

+              );

+        gBS->CopyMem (

+              &DebugPortDevice->StopBits,

+              &((UART_DEVICE_PATH *) DevicePath)->StopBits,

+              sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)

+              );

+      }

+    }

+  }

+}

+

+EFI_STATUS

+EFIAPI

+ImageUnloadHandler (

+  EFI_HANDLE ImageHandle

+  )

+/*++

+

+Routine Description:

+  Unload function that is registered in the LoadImage protocol.  It un-installs

+  protocols produced and deallocates pool used by the driver.  Called by the core

+  when unloading the driver.

+  

+Arguments:

+  EFI_HANDLE ImageHandle

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  if (gDebugPortDevice->SerialIoBinding != NULL) {

+    return EFI_ABORTED;

+  }

+

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  ImageHandle,

+                  &gEfiDriverBindingProtocolGuid,

+                  &gDebugPortDevice->DriverBindingInterface,

+                  &gEfiComponentNameProtocolGuid,

+                  &gDebugPortDevice->ComponentNameInterface,

+                  NULL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Clean up allocations

+  //

+  if (gDebugPortDevice->DebugPortVariable != NULL) {

+    gBS->FreePool (gDebugPortDevice->DebugPortVariable);

+  }

+

+  gBS->FreePool (gDebugPortDevice);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.dxs b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.dxs
new file mode 100644
index 0000000..280931b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugPort.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.h b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.h
new file mode 100644
index 0000000..bb486c3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.h
@@ -0,0 +1,172 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  DebugPort.h

+

+Abstract:

+  Definitions and prototypes for DebugPort driver

+

+--*/

+

+#ifndef __DEBUGPORT_H__

+#define __DEBUGPORT_H__

+

+

+//

+// local type definitions

+//

+#define DEBUGPORT_DEVICE_SIGNATURE  EFI_SIGNATURE_32 ('D', 'B', 'G', 'P')

+

+//

+// Device structure used by driver

+//

+typedef struct {

+  UINT32                      Signature;

+  EFI_HANDLE                  DriverBindingHandle;

+  EFI_HANDLE                  DebugPortDeviceHandle;

+  VOID                        *DebugPortVariable;

+

+  EFI_DRIVER_BINDING_PROTOCOL DriverBindingInterface;

+  EFI_COMPONENT_NAME_PROTOCOL ComponentNameInterface;

+  EFI_DEVICE_PATH_PROTOCOL    *DebugPortDevicePath;

+  EFI_DEBUGPORT_PROTOCOL      DebugPortInterface;

+

+  EFI_HANDLE                  SerialIoDeviceHandle;

+  EFI_SERIAL_IO_PROTOCOL      *SerialIoBinding;

+  UINT64                      BaudRate;

+  UINT32                      ReceiveFifoDepth;

+  UINT32                      Timeout;

+  EFI_PARITY_TYPE             Parity;

+  UINT8                       DataBits;

+  EFI_STOP_BITS_TYPE          StopBits;

+} DEBUGPORT_DEVICE;

+

+#define DEBUGPORT_DEVICE_FROM_THIS(a)     CR (a, DEBUGPORT_DEVICE, DebugPortInterface, DEBUGPORT_DEVICE_SIGNATURE)

+

+#define EFI_ACPI_PC_COMPORT_HID           EISA_PNP_ID (0x0500)

+#define EFI_ACPI_16550UART_HID            EISA_PNP_ID (0x0501)

+

+#define DEBUGPORT_UART_DEFAULT_BAUDRATE   115200

+#define DEBUGPORT_UART_DEFAULT_PARITY     0

+#define DEBUGPORT_UART_DEFAULT_FIFO_DEPTH 16

+#define DEBUGPORT_UART_DEFAULT_TIMEOUT    50000 // 5 ms

+#define DEBUGPORT_UART_DEFAULT_DATA_BITS  8

+#define DEBUGPORT_UART_DEFAULT_STOP_BITS  1

+

+#define DEBUGPORT_DRIVER_VERSION          1

+

+#define EfiIsUartDevicePath(dp)           (DevicePathType (dp) == MESSAGING_DEVICE_PATH && DevicePathSubType (dp) == MSG_UART_DP)

+

+//

+// globals

+//

+extern DEBUGPORT_DEVICE *gDebugPortDevice;

+

+//

+// Driver binding interface functions...

+//

+EFI_STATUS

+DebugPortEntryPoint (

+  IN EFI_HANDLE                     ImageHandle,

+  IN EFI_SYSTEM_TABLE               *SystemTable

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+;

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+DebugPortComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL   *This,

+  IN  CHAR8                         *Language,

+  OUT CHAR16                        **DriverName

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                       ControllerHandle,

+  IN  EFI_HANDLE                                       ChildHandle        OPTIONAL,

+  IN  CHAR8                                            *Language,

+  OUT CHAR16                                           **ControllerName

+  )

+;

+

+//

+// DebugPort member functions

+//

+EFI_STATUS

+EFIAPI

+DebugPortReset (

+  IN EFI_DEBUGPORT_PROTOCOL         *This

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortRead (

+  IN EFI_DEBUGPORT_PROTOCOL         *This,

+  IN UINT32                         Timeout,

+  IN OUT UINTN                      *BufferSize,

+  IN VOID                           *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortWrite (

+  IN EFI_DEBUGPORT_PROTOCOL         *This,

+  IN UINT32                         Timeout,

+  IN OUT UINTN                      *BufferSize,

+  OUT VOID                          *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+DebugPortPoll (

+  IN EFI_DEBUGPORT_PROTOCOL         *This

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.mbd b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.mbd
new file mode 100644
index 0000000..62abeee
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>DebugPort</BaseName>

+    <Guid>73E9457A-CEA1-4917-9A9C-9F1F0F0FD322</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.msa b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.msa
new file mode 100644
index 0000000..4e80897
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.msa
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DebugPort</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>73E9457A-CEA1-4917-9A9C-9F1F0F0FD322</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugPort.h</Filename>

+    <Filename>DebugPort.c</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>DebugPort.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="BY_START">DebugPort</Protocol>

+    <Protocol Usage="BY_START">DevicePath</Protocol>

+    <Protocol Usage="TO_START">SerialIo</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>DEBUGPORT</String>

+      <Guid>0xEBA4E8D2, 0x3858, 0x41EC, 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0</Guid>     

+    </Variable>

+  </Variables>    

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeDebugPortDriver</ModuleEntryPoint>

+      <ModuleUnloadImage>ImageUnloadHandler</ModuleUnloadImage>

+    </Extern>

+    <Extern>

+      <DriverBinding>gDebugPortDriverBinding</DriverBinding>

+      <ComponentName>gDebugPortComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/build.xml
new file mode 100644
index 0000000..4b9c2e4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Debugger/Debugport/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DebugPort"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Debugger/Debugport/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DebugPort">

+      <GenBuild baseName="DebugPort" mbdFilename="${MODULE_DIR}/DebugPort.mbd" msaFilename="${MODULE_DIR}/DebugPort.msa"/>

+   </target>

+   <target depends="DebugPort_clean" name="clean"/>

+   <target depends="DebugPort_cleanall" name="cleanall"/>

+   <target name="DebugPort_clean">

+      <OutputDirSetup baseName="DebugPort" mbdFilename="${MODULE_DIR}/DebugPort.mbd" msaFilename="${MODULE_DIR}/DebugPort.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DebugPort_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DebugPort_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DebugPort_cleanall">

+      <OutputDirSetup baseName="DebugPort" mbdFilename="${MODULE_DIR}/DebugPort.mbd" msaFilename="${MODULE_DIR}/DebugPort.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DebugPort_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DebugPort_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DebugPort*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c
new file mode 100644
index 0000000..35ca70d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c
@@ -0,0 +1,160 @@
+ /*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "DiskIo.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+DiskIoComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+DiskIoComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gDiskIoComponentName = {

+  DiskIoComponentNameGetDriverName,

+  DiskIoComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mDiskIoDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *)L"Generic Disk I/O Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+DiskIoComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+           Language,

+           gDiskIoComponentName.SupportedLanguages,

+           mDiskIoDriverNameTable,

+           DriverName

+           );

+}

+

+EFI_STATUS

+EFIAPI

+DiskIoComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h
new file mode 100644
index 0000000..39d8766
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h
@@ -0,0 +1,44 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DiskIo.h

+  

+Abstract:

+  Private Data definition for Disk IO driver

+

+--*/

+

+#ifndef _DISK_IO_H

+#define _DISK_IO_H

+

+

+

+#define DISK_IO_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('d', 's', 'k', 'I')

+

+#define DATA_BUFFER_BLOCK_NUM           (64)

+

+typedef struct {

+  UINTN                 Signature;

+  EFI_DISK_IO_PROTOCOL  DiskIo;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+} DISK_IO_PRIVATE_DATA;

+

+#define DISK_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gDiskIoDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gDiskIoComponentName;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.mbd b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.mbd
new file mode 100644
index 0000000..087bedf
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>DiskIo</BaseName>

+    <Guid>6B38F7B4-AD98-40e9-9093-ACA2B5A253C4</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa
new file mode 100644
index 0000000..f1dd132
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DiskIo</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>6B38F7B4-AD98-40e9-9093-ACA2B5A253C4</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>diskio.c</Filename>

+    <Filename>diskio.h</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">BlockIo</Protocol>

+    <Protocol Usage="BY_START">DiskIo</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gDiskIoDriverBinding</DriverBinding>

+      <ComponentName>gDiskIoComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/build.xml
new file mode 100644
index 0000000..6c19fe4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DiskIo"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Disk/DiskIo/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DiskIo">

+      <GenBuild baseName="DiskIo" mbdFilename="${MODULE_DIR}/DiskIo.mbd" msaFilename="${MODULE_DIR}/DiskIo.msa"/>

+   </target>

+   <target depends="DiskIo_clean" name="clean"/>

+   <target depends="DiskIo_cleanall" name="cleanall"/>

+   <target name="DiskIo_clean">

+      <OutputDirSetup baseName="DiskIo" mbdFilename="${MODULE_DIR}/DiskIo.mbd" msaFilename="${MODULE_DIR}/DiskIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DiskIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DiskIo_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DiskIo_cleanall">

+      <OutputDirSetup baseName="DiskIo" mbdFilename="${MODULE_DIR}/DiskIo.mbd" msaFilename="${MODULE_DIR}/DiskIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DiskIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DiskIo_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DiskIo*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c
new file mode 100644
index 0000000..35d2a19
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c
@@ -0,0 +1,781 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  DiskIo.c
+
+Abstract:
+
+  DiskIo driver that layers it's self on every Block IO protocol in the system.
+  DiskIo converts a block oriented device to a byte oriented device.
+
+  ReadDisk may have to do reads that are not aligned on sector boundaries.
+  There are three cases:
+
+    UnderRun - The first byte is not on a sector boundary or the read request is
+               less than a sector in length.
+
+    Aligned  - A read of N contiguous sectors.
+
+    OverRun  - The last byte is not on a sector boundary.
+
+--*/
+
+#include "DiskIo.h"
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+EFI_STATUS
+EFIAPI
+DiskIoDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+DiskIoDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+DiskIoDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     ControllerHandle,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  );
+
+//
+// Disk I/O Protocol Interface
+//
+EFI_STATUS
+EFIAPI
+DiskIoReadDisk (
+  IN EFI_DISK_IO_PROTOCOL  *This,
+  IN UINT32                MediaId,
+  IN UINT64                Offset,
+  IN UINTN                 BufferSize,
+  OUT VOID                 *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+DiskIoWriteDisk (
+  IN EFI_DISK_IO_PROTOCOL  *This,
+  IN UINT32                MediaId,
+  IN UINT64                Offset,
+  IN UINTN                 BufferSize,
+  IN VOID                  *Buffer
+  );
+
+EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {
+  DiskIoDriverBindingSupported,
+  DiskIoDriverBindingStart,
+  DiskIoDriverBindingStop,
+  0x10,
+  NULL,
+  NULL
+};
+
+DISK_IO_PRIVATE_DATA        gDiskIoPrivateDataTemplate = {
+  DISK_IO_PRIVATE_DATA_SIGNATURE,
+  {
+    EFI_DISK_IO_PROTOCOL_REVISION,
+    DiskIoReadDisk,
+    DiskIoWriteDisk
+  },
+  NULL
+};
+
+EFI_STATUS
+EFIAPI
+DiskIoDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
+  )
+/*++
+
+  Routine Description:
+    Test to see if this driver supports ControllerHandle. Any ControllerHandle
+    than contains a BlockIo protocol can be supported.
+
+  Arguments:
+    This                - Protocol instance pointer.
+    ControllerHandle    - Handle of device to test.
+    RemainingDevicePath - Not used.
+
+  Returns:
+    EFI_SUCCESS         - This driver supports this device.
+    EFI_ALREADY_STARTED - This driver is already running on this device.
+    other               - This driver does not support this device.
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+  //
+  // Open the IO Abstraction(s) needed to perform the supported test.
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &BlockIo,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Close the I/O Abstraction(s) used to perform the supported test.
+  //
+  gBS->CloseProtocol (
+        ControllerHandle,
+        &gEfiBlockIoProtocolGuid,
+        This->DriverBindingHandle,
+        ControllerHandle
+        );
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DiskIoDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
+  )
+/*++
+
+  Routine Description:
+    Start this driver on ControllerHandle by opening a Block IO protocol and
+    installing a Disk IO protocol on ControllerHandle.
+
+  Arguments:
+    This                - Protocol instance pointer.
+    ControllerHandle    - Handle of device to bind driver to.
+    RemainingDevicePath - Not used, always produce all possible children.
+
+  Returns:
+    EFI_SUCCESS         - This driver is added to ControllerHandle.
+    EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
+    other               - This driver does not support this device.
+
+--*/
+{
+  EFI_STATUS            Status;
+  DISK_IO_PRIVATE_DATA  *Private;
+
+  Private = NULL;
+
+  //
+  // Connect to the Block IO interface on ControllerHandle.
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &gDiskIoPrivateDataTemplate.BlockIo,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Initialize the Disk IO device instance.
+  //
+  Private = AllocateCopyPool (sizeof (DISK_IO_PRIVATE_DATA), &gDiskIoPrivateDataTemplate);
+  if (Private == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+  //
+  // Install protocol interfaces for the Disk IO device.
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &Private->DiskIo
+                  );
+
+ErrorExit:
+  if (EFI_ERROR (Status)) {
+
+    if (Private != NULL) {
+      gBS->FreePool (Private);
+    }
+
+    gBS->CloseProtocol (
+          ControllerHandle,
+          &gEfiBlockIoProtocolGuid,
+          This->DriverBindingHandle,
+          ControllerHandle
+          );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DiskIoDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     ControllerHandle,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  )
+/*++
+
+  Routine Description:
+    Stop this driver on ControllerHandle by removing Disk IO protocol and closing
+    the Block IO protocol on ControllerHandle.
+
+  Arguments:
+    This              - Protocol instance pointer.
+    ControllerHandle  - Handle of device to stop driver on.
+    NumberOfChildren  - Not used.
+    ChildHandleBuffer - Not used.
+
+  Returns:
+    EFI_SUCCESS         - This driver is removed ControllerHandle.
+    other               - This driver was not removed from this device.
+    EFI_UNSUPPORTED
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_DISK_IO_PROTOCOL  *DiskIo;
+  DISK_IO_PRIVATE_DATA  *Private;
+
+  //
+  // Get our context back.
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);
+
+  Status = gBS->UninstallProtocolInterface (
+                  ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  &Private->DiskIo
+                  );
+  if (!EFI_ERROR (Status)) {
+
+    Status = gBS->CloseProtocol (
+                    ControllerHandle,
+                    &gEfiBlockIoProtocolGuid,
+                    This->DriverBindingHandle,
+                    ControllerHandle
+                    );
+  }
+
+  if (!EFI_ERROR (Status)) {
+    gBS->FreePool (Private);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DiskIoReadDisk (
+  IN EFI_DISK_IO_PROTOCOL  *This,
+  IN UINT32                MediaId,
+  IN UINT64                Offset,
+  IN UINTN                 BufferSize,
+  OUT VOID                 *Buffer
+  )
+/*++
+
+  Routine Description:
+    Read BufferSize bytes from Offset into Buffer.
+
+    Reads may support reads that are not aligned on
+    sector boundaries. There are three cases:
+
+      UnderRun - The first byte is not on a sector boundary or the read request is
+                 less than a sector in length.
+
+      Aligned  - A read of N contiguous sectors.
+
+      OverRun  - The last byte is not on a sector boundary.
+
+
+  Arguments:
+    This       - Protocol instance pointer.
+    MediaId    - Id of the media, changes every time the media is replaced.
+    Offset     - The starting byte offset to read from.
+    BufferSize - Size of Buffer.
+    Buffer     - Buffer containing read data.
+
+  Returns:
+    EFI_SUCCESS           - The data was read correctly from the device.
+    EFI_DEVICE_ERROR      - The device reported an error while performing the read.
+    EFI_NO_MEDIA          - There is no media in the device.
+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.
+    EFI_INVALID_PARAMETER - The read request contains device addresses that are not
+                            valid for the device.
+    EFI_OUT_OF_RESOURCES
+
+--*/
+{
+  EFI_STATUS            Status;
+  DISK_IO_PRIVATE_DATA  *Private;
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;
+  EFI_BLOCK_IO_MEDIA    *Media;
+  UINT32                BlockSize;
+  UINT64                Lba;
+  UINT64                OverRunLba;
+  UINT32                UnderRun;
+  UINT32                OverRun;
+  BOOLEAN               TransactionComplete;
+  UINTN                 WorkingBufferSize;
+  UINT8                 *WorkingBuffer;
+  UINTN                 Length;
+  UINT8                 *Data;
+  UINT8                 *PreData;
+  UINTN                 IsBufferAligned;
+  UINTN                 DataBufferSize;
+  BOOLEAN               LastRead;
+
+  Private   = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  BlockIo   = Private->BlockIo;
+  Media     = BlockIo->Media;
+  BlockSize = Media->BlockSize;
+
+  if (Media->MediaId != MediaId) {
+    return EFI_MEDIA_CHANGED;
+  }
+
+  WorkingBuffer     = Buffer;
+  WorkingBufferSize = BufferSize;
+
+  //
+  // Allocate a temporary buffer for operation
+  //
+  DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
+
+  if (Media->IoAlign > 1) {
+    PreData = AllocatePool (DataBufferSize + Media->IoAlign);
+    Data    = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
+  } else {
+    PreData = AllocatePool (DataBufferSize);
+    Data    = PreData;
+  }
+
+  if (PreData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Lba                 = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
+
+  Length              = BlockSize - UnderRun;
+  TransactionComplete = FALSE;
+
+  Status              = EFI_SUCCESS;
+  if (UnderRun != 0) {
+    //
+    // Offset starts in the middle of an Lba, so read the entire block.
+    //
+    Status = BlockIo->ReadBlocks (
+                        BlockIo,
+                        MediaId,
+                        Lba,
+                        BlockSize,
+                        Data
+                        );
+
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+
+    if (Length > BufferSize) {
+      Length              = BufferSize;
+      TransactionComplete = TRUE;
+    }
+
+    CopyMem (WorkingBuffer, Data + UnderRun, Length);
+
+    WorkingBuffer += Length;
+
+    WorkingBufferSize -= Length;
+    if (WorkingBufferSize == 0) {
+      goto Done;
+    }
+
+    Lba += 1;
+  }
+
+  OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
+
+  if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
+    //
+    // If the DiskIo maps directly to a BlockIo device do the read.
+    //
+    if (OverRun != 0) {
+      WorkingBufferSize -= OverRun;
+    }
+    //
+    // Check buffer alignment
+    //
+    IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
+
+    if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
+      //
+      // Alignment is satisfied, so read them together
+      //
+      Status = BlockIo->ReadBlocks (
+                          BlockIo,
+                          MediaId,
+                          Lba,
+                          WorkingBufferSize,
+                          WorkingBuffer
+                          );
+
+      if (EFI_ERROR (Status)) {
+        goto Done;
+      }
+
+      WorkingBuffer += WorkingBufferSize;
+
+    } else {
+      //
+      // Use the allocated buffer instead of the original buffer
+      // to avoid alignment issue.
+      // Here, the allocated buffer (8-byte align) can satisfy the alignment
+      //
+      LastRead = FALSE;
+      do {
+        if (WorkingBufferSize <= DataBufferSize) {
+          //
+          // It is the last calling to readblocks in this loop
+          //
+          DataBufferSize  = WorkingBufferSize;
+          LastRead        = TRUE;
+        }
+
+        Status = BlockIo->ReadBlocks (
+                            BlockIo,
+                            MediaId,
+                            Lba,
+                            DataBufferSize,
+                            Data
+                            );
+        if (EFI_ERROR (Status)) {
+          goto Done;
+        }
+
+        CopyMem (WorkingBuffer, Data, DataBufferSize);
+        WorkingBufferSize -= DataBufferSize;
+        WorkingBuffer += DataBufferSize;
+        Lba += DATA_BUFFER_BLOCK_NUM;
+      } while (!LastRead);
+    }
+  }
+
+  if (!TransactionComplete && OverRun != 0) {
+    //
+    // Last read is not a complete block.
+    //
+    Status = BlockIo->ReadBlocks (
+                        BlockIo,
+                        MediaId,
+                        OverRunLba,
+                        BlockSize,
+                        Data
+                        );
+
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+
+    CopyMem (WorkingBuffer, Data, OverRun);
+  }
+
+Done:
+  if (PreData != NULL) {
+    gBS->FreePool (PreData);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DiskIoWriteDisk (
+  IN EFI_DISK_IO_PROTOCOL  *This,
+  IN UINT32                MediaId,
+  IN UINT64                Offset,
+  IN UINTN                 BufferSize,
+  IN VOID                  *Buffer
+  )
+/*++
+
+  Routine Description:
+    Read BufferSize bytes from Offset into Buffer.
+
+    Writes may require a read modify write to support writes that are not
+    aligned on sector boundaries. There are three cases:
+
+      UnderRun - The first byte is not on a sector boundary or the write request
+                 is less than a sector in length. Read modify write is required.
+
+      Aligned  - A write of N contiguous sectors.
+
+      OverRun  - The last byte is not on a sector boundary. Read modified write
+                 required.
+
+  Arguments:
+    This       - Protocol instance pointer.
+    MediaId    - Id of the media, changes every time the media is replaced.
+    Offset     - The starting byte offset to read from.
+    BufferSize - Size of Buffer.
+    Buffer     - Buffer containing read data.
+
+  Returns:
+    EFI_SUCCESS           - The data was written correctly to the device.
+    EFI_WRITE_PROTECTED   - The device can not be written to.
+    EFI_DEVICE_ERROR      - The device reported an error while performing the write.
+    EFI_NO_MEDIA          - There is no media in the device.
+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.
+    EFI_INVALID_PARAMETER - The write request contains device addresses that are not
+                            valid for the device.
+    EFI_OUT_OF_RESOURCES
+
+--*/
+{
+  EFI_STATUS            Status;
+  DISK_IO_PRIVATE_DATA  *Private;
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;
+  EFI_BLOCK_IO_MEDIA    *Media;
+  UINT32                BlockSize;
+  UINT64                Lba;
+  UINT64                OverRunLba;
+  UINT32                UnderRun;
+  UINT32                OverRun;
+  BOOLEAN               TransactionComplete;
+  UINTN                 WorkingBufferSize;
+  UINT8                 *WorkingBuffer;
+  UINTN                 Length;
+  UINT8                 *Data;
+  UINT8                 *PreData;
+  UINTN                 IsBufferAligned;
+  UINTN                 DataBufferSize;
+  BOOLEAN               LastWrite;
+
+  Private   = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+  BlockIo   = Private->BlockIo;
+  Media     = BlockIo->Media;
+  BlockSize = Media->BlockSize;
+
+  if (Media->ReadOnly) {
+    return EFI_WRITE_PROTECTED;
+  }
+
+  if (Media->MediaId != MediaId) {
+    return EFI_MEDIA_CHANGED;
+  }
+
+  DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
+
+  if (Media->IoAlign > 1) {
+    PreData = AllocatePool (DataBufferSize + Media->IoAlign);
+    Data    = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
+  } else {
+    PreData = AllocatePool (DataBufferSize);
+    Data    = PreData;
+  }
+
+  if (PreData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  WorkingBuffer       = Buffer;
+  WorkingBufferSize   = BufferSize;
+
+  Lba                 = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
+
+  Length              = BlockSize - UnderRun;
+  TransactionComplete = FALSE;
+
+  Status              = EFI_SUCCESS;
+  if (UnderRun != 0) {
+    //
+    // Offset starts in the middle of an Lba, so do read modify write.
+    //
+    Status = BlockIo->ReadBlocks (
+                        BlockIo,
+                        MediaId,
+                        Lba,
+                        BlockSize,
+                        Data
+                        );
+
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+
+    if (Length > BufferSize) {
+      Length              = BufferSize;
+      TransactionComplete = TRUE;
+    }
+
+    CopyMem (Data + UnderRun, WorkingBuffer, Length);
+
+    Status = BlockIo->WriteBlocks (
+                        BlockIo,
+                        MediaId,
+                        Lba,
+                        BlockSize,
+                        Data
+                        );
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+
+    WorkingBuffer += Length;
+    WorkingBufferSize -= Length;
+    if (WorkingBufferSize == 0) {
+      goto Done;
+    }
+
+    Lba += 1;
+  }
+
+  OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
+
+  if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
+    //
+    // If the DiskIo maps directly to a BlockIo device do the write.
+    //
+    if (OverRun != 0) {
+      WorkingBufferSize -= OverRun;
+    }
+    //
+    // Check buffer alignment
+    //
+    IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
+
+    if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
+      //
+      // Alignment is satisfied, so write them together
+      //
+      Status = BlockIo->WriteBlocks (
+                          BlockIo,
+                          MediaId,
+                          Lba,
+                          WorkingBufferSize,
+                          WorkingBuffer
+                          );
+
+      if (EFI_ERROR (Status)) {
+        goto Done;
+      }
+
+      WorkingBuffer += WorkingBufferSize;
+
+    } else {
+      //
+      // The buffer parameter is not aligned with the request
+      // So use the allocated instead.
+      // It can fit almost all the cases.
+      //
+      LastWrite = FALSE;
+      do {
+        if (WorkingBufferSize <= DataBufferSize) {
+          //
+          // It is the last calling to writeblocks in this loop
+          //
+          DataBufferSize  = WorkingBufferSize;
+          LastWrite       = TRUE;
+        }
+
+        CopyMem (Data, WorkingBuffer, DataBufferSize);
+        Status = BlockIo->WriteBlocks (
+                            BlockIo,
+                            MediaId,
+                            Lba,
+                            DataBufferSize,
+                            Data
+                            );
+        if (EFI_ERROR (Status)) {
+          goto Done;
+        }
+
+        WorkingBufferSize -= DataBufferSize;
+        WorkingBuffer += DataBufferSize;
+        Lba += DATA_BUFFER_BLOCK_NUM;
+      } while (!LastWrite);
+    }
+  }
+
+  if (!TransactionComplete && OverRun != 0) {
+    //
+    // Last bit is not a complete block, so do a read modify write.
+    //
+    Status = BlockIo->ReadBlocks (
+                        BlockIo,
+                        MediaId,
+                        OverRunLba,
+                        BlockSize,
+                        Data
+                        );
+
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+
+    CopyMem (Data, WorkingBuffer, OverRun);
+
+    Status = BlockIo->WriteBlocks (
+                        BlockIo,
+                        MediaId,
+                        OverRunLba,
+                        BlockSize,
+                        Data
+                        );
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+  }
+
+Done:
+  if (PreData != NULL) {
+    gBS->FreePool (PreData);
+  }
+
+  return Status;
+}
diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.mbd b/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.mbd
new file mode 100644
index 0000000..ed89f07
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>DiskIoPartition</BaseName>

+    <Guid>854E153A-8AC8-40f4-A5A9-4C51F18CFB1B</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.msa b/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.msa
new file mode 100644
index 0000000..62e8022
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/DiskIoPartition.msa
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DiskIoPartition</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>854E153A-8AC8-40f4-A5A9-4C51F18CFB1B</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>../../DiskIo/Dxe/diskio.c</Filename>

+    <Filename>../../DiskIo/Dxe/diskio.h</Filename>

+    <Filename>../../DiskIo/Dxe/ComponentName.c</Filename>

+    <Filename>../../Partition/Dxe/Partition.h</Filename>

+    <Filename>../../Partition/Dxe/ElTorito.h</Filename>

+    <Filename>../../Partition/Dxe/Gpt.h</Filename>

+    <Filename>../../Partition/Dxe/Mbr.h</Filename>

+    <Filename>../../Partition/Dxe/Partition.c</Filename>

+    <Filename>../../Partition/Dxe/ElTorito.c</Filename>

+    <Filename>../../Partition/Dxe/Gpt.c</Filename>

+    <Filename>../../Partition/Dxe/Mbr.c</Filename>

+    <Filename>../../Partition/Dxe/ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">BlockIo</Protocol>

+    <Protocol Usage="TO_START">DiskIo</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>PartTypeSystemPart</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PartTypeUnused</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPartitionDriverBinding</DriverBinding>

+      <ComponentName>gPartitionComponentName</ComponentName>

+    </Extern>

+    <Extern>

+      <DriverBinding>gDiskIoDriverBinding</DriverBinding>

+      <ComponentName>gDiskIoComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/build.xml
new file mode 100644
index 0000000..5148719
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/DiskIoPartition/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DiskIoPartition"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Disk/DiskIoPartition/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DiskIoPartition">

+      <GenBuild baseName="DiskIoPartition" mbdFilename="${MODULE_DIR}/DiskIoPartition.mbd" msaFilename="${MODULE_DIR}/DiskIoPartition.msa"/>

+   </target>

+   <target depends="DiskIoPartition_clean" name="clean"/>

+   <target depends="DiskIoPartition_cleanall" name="cleanall"/>

+   <target name="DiskIoPartition_clean">

+      <OutputDirSetup baseName="DiskIoPartition" mbdFilename="${MODULE_DIR}/DiskIoPartition.mbd" msaFilename="${MODULE_DIR}/DiskIoPartition.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DiskIoPartition_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DiskIoPartition_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DiskIoPartition_cleanall">

+      <OutputDirSetup baseName="DiskIoPartition" mbdFilename="${MODULE_DIR}/DiskIoPartition.mbd" msaFilename="${MODULE_DIR}/DiskIoPartition.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DiskIoPartition_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DiskIoPartition_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DiskIoPartition*"/>

+      </delete>

+   </target>

+</project>

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c
new file mode 100644
index 0000000..3821690
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c
@@ -0,0 +1,160 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "Partition.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+PartitionComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+PartitionComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gPartitionComponentName = {

+  PartitionComponentNameGetDriverName,

+  PartitionComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mPartitionDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *)L"Partition Driver(MBR/GPT/El Torito)"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+PartitionComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gPartitionComponentName.SupportedLanguages,

+          mPartitionDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+PartitionComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c
new file mode 100644
index 0000000..27beba1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c
@@ -0,0 +1,277 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  ElTorito.c

+

+Abstract:

+

+  Decode an El Torito formatted CD-ROM

+

+Revision History

+

+--*/

+

+#include "Partition.h"

+#include "ElTorito.h"

+

+BOOLEAN

+PartitionInstallElToritoChildHandles (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath

+  )

+/*++

+

+Routine Description:

+  Install child handles if the Handle supports El Torito format.

+

+Arguments:

+  This       - Calling context.

+  Handle     - Parent Handle

+  DiskIo     - Parent DiskIo interface

+  BlockIo    - Parent BlockIo interface

+  DevicePath - Parent Device Path

+

+Returns:

+  TRUE       - some child handle(s) was added

+  FALSE      - no child handle was added

+

+--*/

+{

+  EFI_STATUS              Status;

+  UINT32                  VolDescriptorLba;

+  UINT32                  Lba;

+  EFI_BLOCK_IO_MEDIA      *Media;

+  CDROM_VOLUME_DESCRIPTOR *VolDescriptor;

+  ELTORITO_CATALOG        *Catalog;

+  UINTN                   Check;

+  UINTN                   Index;

+  UINTN                   BootEntry;

+  UINTN                   MaxIndex;

+  UINT16                  *CheckBuffer;

+  CDROM_DEVICE_PATH       CdDev;

+  UINT32                  SubBlockSize;

+  UINT32                  SectorCount;

+  BOOLEAN                 Found;

+  UINT32                  VolSpaceSize;

+

+  Found         = FALSE;

+  Media         = BlockIo->Media;

+  VolSpaceSize  = 0;

+

+  //

+  // CD_ROM has the fixed block size as 2048 bytes

+  //

+  if (Media->BlockSize != 2048) {

+    return FALSE;

+  }

+

+  VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);

+

+  if (VolDescriptor == NULL) {

+    return FALSE;

+  }

+

+  Catalog = (ELTORITO_CATALOG *) VolDescriptor;

+

+  //

+  // the ISO-9660 volume descriptor starts at 32k on the media

+  // and CD_ROM has the fixed block size as 2048 bytes, so...

+  //

+  //

+  // ((16*2048) / Media->BlockSize) - 1;

+  //

+  VolDescriptorLba = 15;

+  //

+  // Loop: handle one volume descriptor per time

+  //

+  while (TRUE) {

+

+    VolDescriptorLba += 1;

+    if (VolDescriptorLba > Media->LastBlock) {

+      //

+      // We are pointing past the end of the device so exit

+      //

+      break;

+    }

+

+    Status = BlockIo->ReadBlocks (

+                        BlockIo,

+                        Media->MediaId,

+                        VolDescriptorLba,

+                        Media->BlockSize,

+                        VolDescriptor

+                        );

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+    //

+    // Check for valid volume descriptor signature

+    //

+    if (VolDescriptor->Type == CDVOL_TYPE_END ||

+        CompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0

+        ) {

+      //

+      // end of Volume descriptor list

+      //

+      break;

+    }

+    //

+    // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,

+    // the 32-bit numerical values is stored in Both-byte orders

+    //

+    if (VolDescriptor->Type == CDVOL_TYPE_CODED) {

+      VolSpaceSize = VolDescriptor->VolSpaceSize[1];

+    }

+    //

+    // Is it an El Torito volume descriptor?

+    //

+    if (CompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {

+      continue;

+    }

+    //

+    // Read in the boot El Torito boot catalog

+    //

+    Lba = UNPACK_INT32 (VolDescriptor->EltCatalog);

+    if (Lba > Media->LastBlock) {

+      continue;

+    }

+

+    Status = BlockIo->ReadBlocks (

+                        BlockIo,

+                        Media->MediaId,

+                        Lba,

+                        Media->BlockSize,

+                        Catalog

+                        );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));

+      continue;

+    }

+    //

+    // We don't care too much about the Catalog header's contents, but we do want

+    // to make sure it looks like a Catalog header

+    //

+    if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {

+      DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n"));

+      continue;

+    }

+

+    Check       = 0;

+    CheckBuffer = (UINT16 *) Catalog;

+    for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {

+      Check += CheckBuffer[Index];

+    }

+

+    if (Check & 0xFFFF) {

+      DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));

+      continue;

+    }

+

+    MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG);

+    for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) {

+      //

+      // Next entry

+      //

+      Catalog += 1;

+

+      //

+      // Check this entry

+      //

+      if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {

+        continue;

+      }

+

+      SubBlockSize  = 512;

+      SectorCount   = Catalog->Boot.SectorCount;

+

+      switch (Catalog->Boot.MediaType) {

+

+      case ELTORITO_NO_EMULATION:

+        SubBlockSize = Media->BlockSize;

+        break;

+

+      case ELTORITO_HARD_DISK:

+        break;

+

+      case ELTORITO_12_DISKETTE:

+        SectorCount = 0x50 * 0x02 * 0x0F;

+        break;

+

+      case ELTORITO_14_DISKETTE:

+        SectorCount = 0x50 * 0x02 * 0x12;

+        break;

+

+      case ELTORITO_28_DISKETTE:

+        SectorCount = 0x50 * 0x02 * 0x24;

+        break;

+

+      default:

+        DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType));

+        SectorCount   = 0;

+        SubBlockSize  = Media->BlockSize;

+        break;

+      }

+      //

+      // Create child device handle

+      //

+      CdDev.Header.Type     = MEDIA_DEVICE_PATH;

+      CdDev.Header.SubType  = MEDIA_CDROM_DP;

+      SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev));

+

+      if (Index == 1) {

+        //

+        // This is the initial/default entry

+        //

+        BootEntry = 0;

+      }

+

+      CdDev.BootEntry = (UINT32) BootEntry;

+      BootEntry++;

+      CdDev.PartitionStart = Catalog->Boot.Lba;

+      if (SectorCount < 2) {

+        CdDev.PartitionSize = VolSpaceSize;

+      } else {

+        CdDev.PartitionSize = DivU64x32 (

+                                MultU64x32 (

+                                  SectorCount,

+                                  SubBlockSize

+                                  ) + Media->BlockSize - 1,

+                                Media->BlockSize

+                                );

+      }

+

+      Status = PartitionInstallChildHandle (

+                This,

+                Handle,

+                DiskIo,

+                BlockIo,

+                DevicePath,

+                (EFI_DEVICE_PATH_PROTOCOL *) &CdDev,

+                Catalog->Boot.Lba,

+                Catalog->Boot.Lba + CdDev.PartitionSize - 1,

+                SubBlockSize,

+                FALSE

+                );

+      if (!EFI_ERROR (Status)) {

+        Found = TRUE;

+      }

+    }

+  }

+

+  gBS->FreePool (VolDescriptor);

+

+  return Found;

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.h b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.h
new file mode 100644
index 0000000..f085315
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.h
@@ -0,0 +1,130 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ElTorito.h

+  

+Abstract:

+

+  Data Structures required for detecting ElTorito Partitions

+  

+Revision History

+

+--*/

+

+#ifndef _ELTORITO_H_

+#define _ELTORITO_H_

+

+#pragma pack(1)

+//

+// CDROM_VOLUME_DESCRIPTOR.Types

+//

+#define CDVOL_TYPE_STANDARD 0x0

+#define CDVOL_TYPE_CODED    0x1

+#define CDVOL_TYPE_END      0xFF

+

+//

+// CDROM_VOLUME_DESCRIPTOR.Id

+//

+#define CDVOL_ID  "CD001"

+

+//

+// CDROM_VOLUME_DESCRIPTOR.SystemId

+//

+#define CDVOL_ELTORITO_ID "EL TORITO SPECIFICATION"

+

+//

+// Indicator types

+//

+#define ELTORITO_ID_CATALOG               0x01

+#define ELTORITO_ID_SECTION_BOOTABLE      0x88

+#define ELTORITO_ID_SECTION_NOT_BOOTABLE  0x00

+#define ELTORITO_ID_SECTION_HEADER        0x90

+#define ELTORITO_ID_SECTION_HEADER_FINAL  0x91

+

+//

+// ELTORITO_CATALOG.Boot.MediaTypes

+//

+#define ELTORITO_NO_EMULATION 0x00

+#define ELTORITO_12_DISKETTE  0x01

+#define ELTORITO_14_DISKETTE  0x02

+#define ELTORITO_28_DISKETTE  0x03

+#define ELTORITO_HARD_DISK    0x04

+

+//

+// El Torito Volume Descriptor

+// Note that the CDROM_VOLUME_DESCRIPTOR does not match the ISO-9660

+// descriptor.  For some reason descriptor used by El Torito is

+// different, but they start the same.   The El Torito descriptor

+// is left shifted 1 byte starting with the SystemId.  (Note this

+// causes the field to get unaligned)

+//

+typedef struct {

+  UINT8   Type;

+  CHAR8   Id[5];  // CD001

+  UINT8   Version;

+  CHAR8   SystemId[26];

+  CHAR8   Unused[38];

+  UINT8   EltCatalog[4];

+  CHAR8   Unused2[5];

+  UINT32  VolSpaceSize[2];

+} CDROM_VOLUME_DESCRIPTOR;

+

+//

+// Catalog Entry

+//

+typedef union {

+  struct {

+    CHAR8       Reserved[0x20];

+  } Unknown;

+

+  //

+  // Catalog validation entry (Catalog header)

+  //

+  struct {

+    UINT8   Indicator;

+    UINT8   PlatformId;

+    UINT16  Reserved;

+    CHAR8   ManufacId[24];

+    UINT16  Checksum;

+    UINT16  Id55AA;

+  } Catalog;

+

+  //

+  // Initial/Default Entry or Section Entry

+  //

+  struct {

+    UINT8   Indicator;

+    UINT8   MediaType : 4;

+    UINT8   Reserved1 : 4;

+    UINT16  LoadSegment;

+    UINT8   SystemType;

+    UINT8   Reserved2;

+    UINT16  SectorCount;

+    UINT32  Lba;

+  } Boot;

+

+  //

+  // Section Header Entry

+  //

+  struct {

+    UINT8   Indicator;

+    UINT8   PlatformId;

+    UINT16  SectionEntries;

+    CHAR8   Id[28];

+  } Section;

+

+} ELTORITO_CATALOG;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c
new file mode 100644
index 0000000..35ff1a8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c
@@ -0,0 +1,768 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Gpt.c

+  

+Abstract:

+

+  Decode a hard disk partitioned with the GPT scheme in the EFI 1.0 

+  specification.

+

+--*/

+

+#include "Partition.h"

+#include "Gpt.h"

+#include "Mbr.h"

+

+BOOLEAN

+PartitionValidGptTable (

+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,

+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,

+  IN  EFI_LBA                     Lba,

+  OUT EFI_PARTITION_TABLE_HEADER  *PartHeader

+  );

+

+BOOLEAN

+PartitionCheckGptEntryArrayCRC (

+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,

+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,

+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader

+  );

+

+BOOLEAN

+PartitionRestoreGptTable (

+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,

+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,

+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader

+  );

+

+VOID

+PartitionCheckGptEntry (

+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader,

+  IN  EFI_PARTITION_ENTRY         *PartEntry,

+  OUT EFI_PARTITION_ENTRY_STATUS  *PEntryStatus

+  );

+

+BOOLEAN

+PartitionCheckCrcAltSize (

+  IN UINTN                 MaxSize,

+  IN UINTN                 Size,

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  );

+

+BOOLEAN

+PartitionCheckCrc (

+  IN UINTN                 MaxSize,

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  );

+

+VOID

+PartitionSetCrcAltSize (

+  IN UINTN                 Size,

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  );

+

+VOID

+PartitionSetCrc (

+  IN OUT EFI_TABLE_HEADER *Hdr

+  );

+

+BOOLEAN

+PartitionInstallGptChildHandles (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath

+  )

+/*++

+

+Routine Description:

+  Install child handles if the Handle supports GPT partition structure.

+

+Arguments:       

+  This       - Calling context.

+  Handle     - Parent Handle 

+  DiskIo     - Parent DiskIo interface

+  BlockIo    - Parent BlockIo interface

+  DevicePath - Parent Device Path

+

+Returns:

+  TRUE       - Valid GPT disk

+  FALSE      - Not a valid GPT disk

+

+--*/

+{

+  EFI_STATUS                  Status;

+  UINT32                      BlockSize;

+  EFI_LBA                     LastBlock;

+  MASTER_BOOT_RECORD          *ProtectiveMbr;

+  EFI_PARTITION_TABLE_HEADER  *PrimaryHeader;

+  EFI_PARTITION_TABLE_HEADER  *BackupHeader;

+  EFI_PARTITION_ENTRY         *PartEntry;

+  EFI_PARTITION_ENTRY_STATUS  *PEntryStatus;

+  UINTN                       Index;

+  BOOLEAN                     GptValid;

+  HARDDRIVE_DEVICE_PATH       HdDev;

+

+  ProtectiveMbr = NULL;

+  PrimaryHeader = NULL;

+  BackupHeader  = NULL;

+  PartEntry     = NULL;

+  PEntryStatus  = NULL;

+

+  BlockSize     = BlockIo->Media->BlockSize;

+  LastBlock     = BlockIo->Media->LastBlock;

+

+  DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));

+  DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock));

+

+  GptValid = FALSE;

+

+  //

+  // Allocate a buffer for the Protective MBR

+  //

+  ProtectiveMbr = AllocatePool (BlockSize);

+  if (ProtectiveMbr == NULL) {

+    return FALSE;

+  }

+

+  //

+  // Read the Protective MBR from LBA #0

+  //

+  Status = BlockIo->ReadBlocks (

+                      BlockIo,

+                      BlockIo->Media->MediaId,

+                      0,

+                      BlockIo->Media->BlockSize,

+                      ProtectiveMbr

+                      );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+  //

+  // Verify that the Protective MBR is valid

+  //

+  if (ProtectiveMbr->Partition[0].BootIndicator != 0x00 ||

+      ProtectiveMbr->Partition[0].OSIndicator != 0xEE ||

+      UNPACK_UINT32 (ProtectiveMbr->Partition[0].StartingLBA) != 1

+      ) {

+    goto Done;

+  }

+

+  //

+  // Allocate the GPT structures

+  //

+  PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));

+  if (PrimaryHeader == NULL) {

+    goto Done;

+  }

+

+  BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));

+

+  if (BackupHeader == NULL) {

+    goto Done;

+  }

+

+  //

+  // Check primary and backup partition tables

+  //

+  if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {

+    DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));

+

+    if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {

+      DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));

+      goto Done;

+    } else {

+      DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));

+      DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));

+      if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {

+        DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));

+      }

+

+      if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {

+        DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));

+      }

+    }

+  } else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {

+    DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));

+    DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));

+    if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {

+      DEBUG ((EFI_D_INFO, " Restore  backup partition table error\n"));

+    }

+

+    if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {

+      DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));

+    }

+

+  }

+

+  DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));

+

+  //

+  // Read the EFI Partition Entries

+  //

+  PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY));

+  if (PartEntry == NULL) {

+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));

+    goto Done;

+  }

+

+  Status = DiskIo->ReadDisk (

+                    DiskIo,

+                    BlockIo->Media->MediaId,

+                    MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),

+                    PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),

+                    PartEntry

+                    );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));

+    goto Done;

+  }

+

+  DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));

+

+  DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));

+

+  PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));

+  if (PEntryStatus == NULL) {

+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));

+    goto Done;

+  }

+

+  //

+  // Check the integrity of partition entries

+  //

+  PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);

+

+  //

+  // If we got this far the GPT layout of the disk is valid and we should return true

+  //

+  GptValid = TRUE;

+

+  //

+  // Create child device handles

+  //

+  for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {

+    if (CompareGuid (&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||

+        PEntryStatus[Index].OutOfRange ||

+        PEntryStatus[Index].Overlap

+        ) {

+      //

+      // Don't use null EFI Partition Entries or Invalid Partition Entries

+      //

+      continue;

+    }

+

+    ZeroMem (&HdDev, sizeof (HdDev));

+    HdDev.Header.Type     = MEDIA_DEVICE_PATH;

+    HdDev.Header.SubType  = MEDIA_HARDDRIVE_DP;

+    SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));

+

+    HdDev.PartitionNumber = (UINT32) Index + 1;

+    HdDev.MBRType         = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;

+    HdDev.SignatureType   = SIGNATURE_TYPE_GUID;

+    HdDev.PartitionStart  = PartEntry[Index].StartingLBA;

+    HdDev.PartitionSize   = PartEntry[Index].EndingLBA - PartEntry[Index].StartingLBA + 1;

+    CopyMem (HdDev.Signature, &PartEntry[Index].UniquePartitionGUID, sizeof (EFI_GUID));

+

+    DEBUG ((EFI_D_INFO, " Index : %d\n", Index));

+    DEBUG ((EFI_D_INFO, " Start LBA : %x\n", HdDev.PartitionStart));

+    DEBUG ((EFI_D_INFO, " End LBA : %x\n", PartEntry[Index].EndingLBA));

+    DEBUG ((EFI_D_INFO, " Partition size: %x\n", HdDev.PartitionSize));

+    DEBUG ((EFI_D_INFO, " Start : %x", MultU64x32 (PartEntry[Index].StartingLBA, BlockSize)));

+    DEBUG ((EFI_D_INFO, " End : %x\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));

+

+    Status = PartitionInstallChildHandle (

+              This,

+              Handle,

+              DiskIo,

+              BlockIo,

+              DevicePath,

+              (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,

+              PartEntry[Index].StartingLBA,

+              PartEntry[Index].EndingLBA,

+              BlockSize,

+              CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)

+              );

+  }

+

+  DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));

+

+Done:

+  if (ProtectiveMbr != NULL) {

+    gBS->FreePool (ProtectiveMbr);

+  }

+  if (PrimaryHeader != NULL) {

+    gBS->FreePool (PrimaryHeader);

+  }

+  if (BackupHeader != NULL) {

+    gBS->FreePool (BackupHeader);

+  }

+  if (PartEntry != NULL) {

+    gBS->FreePool (PartEntry);

+  }

+  if (PEntryStatus != NULL) {

+    gBS->FreePool (PEntryStatus);

+  }

+

+  return GptValid;

+}

+

+BOOLEAN

+PartitionValidGptTable (

+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,

+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,

+  IN  EFI_LBA                     Lba,

+  OUT EFI_PARTITION_TABLE_HEADER  *PartHeader

+  )

+/*++

+

+Routine Description:

+  Check if the GPT partition table is valid

+

+Arguments:       

+  BlockIo   - Parent BlockIo interface

+  DiskIo    - Disk Io protocol.

+  Lba       - The starting Lba of the Partition Table

+  PartHeader   - Stores the partition table that is read

+

+Returns:

+  TRUE       - The partition table is valid

+  FALSE      - The partition table is not valid

+

+--*/

+{

+  EFI_STATUS                  Status;

+  UINT32                      BlockSize;

+  EFI_PARTITION_TABLE_HEADER  *PartHdr;

+

+  BlockSize = BlockIo->Media->BlockSize;

+

+  PartHdr   = AllocateZeroPool (BlockSize);

+

+  if (PartHdr == NULL) {

+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));

+    return FALSE;

+  }

+  //

+  // Read the EFI Partition Table Header

+  //

+  Status = BlockIo->ReadBlocks (

+                      BlockIo,

+                      BlockIo->Media->MediaId,

+                      Lba,

+                      BlockSize,

+                      PartHdr

+                      );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (PartHdr);

+    return FALSE;

+  }

+

+  if (CompareMem (&PartHdr->Header.Signature, EFI_PTAB_HEADER_ID, sizeof (UINT64)) != 0 ||

+      !PartitionCheckCrc (BlockSize, &PartHdr->Header) ||

+      PartHdr->MyLBA != Lba

+      ) {

+    DEBUG ((EFI_D_INFO, " !Valid efi partition table header\n"));

+    gBS->FreePool (PartHdr);

+    return FALSE;

+  }

+

+  CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));

+  if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {

+    gBS->FreePool (PartHdr);

+    return FALSE;

+  }

+

+  DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));

+  gBS->FreePool (PartHdr);

+  return TRUE;

+}

+

+BOOLEAN

+PartitionCheckGptEntryArrayCRC (

+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,

+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,

+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader

+  )

+/*++

+

+Routine Description:

+

+  Check if the CRC field in the Partition table header is valid 

+  for Partition entry array

+

+Arguments:

+

+  BlockIo   - parent BlockIo interface 

+  DiskIo    - Disk Io Protocol.

+  PartHeader   - Partition table header structure

+

+Returns:

+  

+  TRUE      - the CRC is valid

+  FALSE     - the CRC is invalid

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       *Ptr;

+  UINT32      Crc;

+  UINTN       Size;

+

+  //

+  // Read the EFI Partition Entries

+  //

+  Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);

+  if (Ptr == NULL) {

+    DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));

+    return FALSE;

+  }

+

+  Status = DiskIo->ReadDisk (

+                    DiskIo,

+                    BlockIo->Media->MediaId,

+                    MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),

+                    PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,

+                    Ptr

+                    );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Ptr);

+    return FALSE;

+  }

+

+  Size    = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;

+

+  Status  = gBS->CalculateCrc32 (Ptr, Size, &Crc);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));

+    gBS->FreePool (Ptr);

+    return FALSE;

+  }

+

+  gBS->FreePool (Ptr);

+

+  return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);

+}

+

+BOOLEAN

+PartitionRestoreGptTable (

+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,

+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,

+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader

+  )

+/*++

+

+Routine Description:

+

+  Restore Partition Table to its alternate place

+  (Primary -> Backup or Backup -> Primary)

+

+Arguments:

+

+  BlockIo   - parent BlockIo interface 

+  DiskIo    - Disk Io Protocol.

+  PartHeader   - the source Partition table header structure

+

+Returns:

+  

+  TRUE      - Restoring succeeds

+  FALSE     - Restoring failed

+

+--*/

+{

+  EFI_STATUS                  Status;

+  UINTN                       BlockSize;

+  EFI_PARTITION_TABLE_HEADER  *PartHdr;

+  EFI_LBA                     PEntryLBA;

+  UINT8                       *Ptr;

+

+  PartHdr   = NULL;

+  Ptr       = NULL;

+

+  BlockSize = BlockIo->Media->BlockSize;

+

+  PartHdr   = AllocateZeroPool (BlockSize);

+

+  if (PartHdr == NULL) {

+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));

+    return FALSE;

+  }

+

+  PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \

+                             (PartHeader->LastUsableLBA + 1) : \

+                             (PRIMARY_PART_HEADER_LBA + 1);

+

+  CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));

+

+  PartHdr->MyLBA              = PartHeader->AlternateLBA;

+  PartHdr->AlternateLBA       = PartHeader->MyLBA;

+  PartHdr->PartitionEntryLBA  = PEntryLBA;

+  PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);

+

+  Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, PartHdr->MyLBA, BlockSize, PartHdr);

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);

+  if (Ptr == NULL) {

+    DEBUG ((EFI_D_ERROR, " Allocate pool effor\n"));

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Done;

+  }

+

+  Status = DiskIo->ReadDisk (

+                    DiskIo,

+                    BlockIo->Media->MediaId,

+                    MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),

+                    PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,

+                    Ptr

+                    );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Status = DiskIo->WriteDisk (

+                    DiskIo,

+                    BlockIo->Media->MediaId,

+                    MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),

+                    PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,

+                    Ptr

+                    );

+

+Done:

+  gBS->FreePool (PartHdr);

+  gBS->FreePool (Ptr);

+

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+VOID

+PartitionCheckGptEntry (

+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader,

+  IN  EFI_PARTITION_ENTRY         *PartEntry,

+  OUT EFI_PARTITION_ENTRY_STATUS  *PEntryStatus

+  )

+/*++

+

+Routine Description:

+

+  Check each partition entry for its range

+

+Arguments:

+

+  PartHeader       - the partition table header

+  PartEntry        - the partition entry array

+  PEntryStatus  - the partition entry status array recording the status of

+                  each partition

+

+Returns:

+  VOID

+

+--*/

+{

+  EFI_LBA StartingLBA;

+  EFI_LBA EndingLBA;

+  UINTN   Index1;

+  UINTN   Index2;

+

+  DEBUG ((EFI_D_INFO, " start check partition entries\n"));

+  for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {

+    if (CompareGuid (&PartEntry[Index1].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {

+      continue;

+    }

+

+    StartingLBA = PartEntry[Index1].StartingLBA;

+    EndingLBA   = PartEntry[Index1].EndingLBA;

+    if (StartingLBA > EndingLBA ||

+        StartingLBA < PartHeader->FirstUsableLBA ||

+        StartingLBA > PartHeader->LastUsableLBA ||

+        EndingLBA < PartHeader->FirstUsableLBA ||

+        EndingLBA > PartHeader->LastUsableLBA

+        ) {

+      PEntryStatus[Index1].OutOfRange = TRUE;

+      continue;

+    }

+

+    for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {

+

+      if (CompareGuid (&PartEntry[Index2].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {

+        continue;

+      }

+

+      if (PartEntry[Index2].EndingLBA >= StartingLBA && PartEntry[Index2].StartingLBA <= EndingLBA) {

+        //

+        // This region overlaps with the Index1'th region

+        //

+        PEntryStatus[Index1].Overlap  = TRUE;

+        PEntryStatus[Index2].Overlap  = TRUE;

+        continue;

+

+      }

+    }

+  }

+

+  DEBUG ((EFI_D_INFO, " End check partition entries\n"));

+}

+

+VOID

+PartitionSetCrc (

+  IN OUT EFI_TABLE_HEADER *Hdr

+  )

+/*++

+

+Routine Description:

+

+  Updates the CRC32 value in the table header

+

+Arguments:

+

+  Hdr     - The table to update

+

+Returns:

+

+  None

+

+--*/

+{

+  PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);

+}

+

+VOID

+PartitionSetCrcAltSize (

+  IN UINTN                 Size,

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  )

+/*++

+

+Routine Description:

+

+  Updates the CRC32 value in the table header

+

+Arguments:

+

+  Size    - The size of the table

+  Hdr     - The table to update

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT32  Crc;

+

+  Hdr->CRC32 = 0;

+  gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);

+  Hdr->CRC32 = Crc;

+}

+

+BOOLEAN

+PartitionCheckCrc (

+  IN UINTN                 MaxSize,

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  )

+/*++

+

+Routine Description:

+

+  Checks the CRC32 value in the table header

+

+Arguments:

+  

+  MaxSize - Max Size limit

+  Hdr     - The table to check

+

+Returns:

+

+  TRUE if the CRC is OK in the table

+

+--*/

+{

+  return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);

+}

+

+BOOLEAN

+PartitionCheckCrcAltSize (

+  IN UINTN                 MaxSize,

+  IN UINTN                 Size,

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  )

+/*++

+

+Routine Description:

+

+  Checks the CRC32 value in the table header

+

+Arguments:

+  

+  MaxSize - Max Size Limit

+  Size    - The size of the table

+  Hdr     - The table to check

+

+Returns:

+

+  TRUE if the CRC is OK in the table

+

+--*/

+{

+  UINT32      Crc;

+  UINT32      OrgCrc;

+  EFI_STATUS  Status;

+

+  Crc = 0;

+

+  if (Size == 0) {

+    //

+    // If header size is 0 CRC will pass so return FALSE here

+    //

+    return FALSE;

+  }

+

+  if (MaxSize && Size > MaxSize) {

+    DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));

+    return FALSE;

+  }

+  //

+  // clear old crc from header

+  //

+  OrgCrc      = Hdr->CRC32;

+  Hdr->CRC32  = 0;

+

+  Status      = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));

+    return FALSE;

+  }

+  //

+  // set results

+  //

+  Hdr->CRC32 = Crc;

+

+  //

+  // return status

+  //

+  DEBUG_CODE (

+    if (OrgCrc != Crc) {

+      DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));

+    }

+  );

+

+  return (BOOLEAN) (OrgCrc == Crc);

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.h b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.h
new file mode 100644
index 0000000..fbcd93d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.h
@@ -0,0 +1,76 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Gpt.h

+  

+Abstract:

+

+  Data Structures required for detecting GPT Partitions

+  

+Revision History

+

+--*/

+

+#ifndef _GPT_H_

+#define _GPT_H_

+

+#pragma pack(1)

+

+#define PRIMARY_PART_HEADER_LBA 1

+

+#define EFI_PTAB_HEADER_ID      "EFI PART"

+

+//

+// EFI Partition Attributes

+//

+#define EFI_PART_REQUIRED_TO_FUNCTION 0x0000000000000001

+

+//

+// GPT Partition Table Header

+//

+typedef struct {

+  EFI_TABLE_HEADER  Header;

+  EFI_LBA           MyLBA;

+  EFI_LBA           AlternateLBA;

+  EFI_LBA           FirstUsableLBA;

+  EFI_LBA           LastUsableLBA;

+  EFI_GUID          DiskGUID;

+  EFI_LBA           PartitionEntryLBA;

+  UINT32            NumberOfPartitionEntries;

+  UINT32            SizeOfPartitionEntry;

+  UINT32            PartitionEntryArrayCRC32;

+} EFI_PARTITION_TABLE_HEADER;

+

+//

+// GPT Partition Entry

+//

+typedef struct {

+  EFI_GUID  PartitionTypeGUID;

+  EFI_GUID  UniquePartitionGUID;

+  EFI_LBA   StartingLBA;

+  EFI_LBA   EndingLBA;

+  UINT64    Attributes;

+  CHAR16    PartitionName[36];

+} EFI_PARTITION_ENTRY;

+

+//

+// GPT Partition Entry Status

+//

+typedef struct {

+  BOOLEAN OutOfRange;

+  BOOLEAN Overlap;

+} EFI_PARTITION_ENTRY_STATUS;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c
new file mode 100644
index 0000000..07e3cbe
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c
@@ -0,0 +1,317 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Mbr.c

+  

+Abstract:

+

+  Decode a hard disk partitioned with the legacy MBR found on most PC's

+

+  MBR - Master Boot Record is in the first sector of a partitioned hard disk.

+        The MBR supports four partitions per disk. The MBR also contains legacy

+        code that is not run on an EFI system. The legacy code reads the 

+        first sector of the active partition into memory and 

+

+  BPB - Boot(?) Parameter Block is in the first sector of a FAT file system. 

+        The BPB contains information about the FAT file system. The BPB is 

+        always on the first sector of a media. The first sector also contains

+        the legacy boot strap code.

+

+--*/

+

+#include "Partition.h"

+#include "Mbr.h"

+

+BOOLEAN

+PartitionValidMbr (

+  IN  MASTER_BOOT_RECORD      *Mbr,

+  IN  EFI_LBA                 LastLba

+  )

+/*++

+

+Routine Description:

+  Test to see if the Mbr buffer is a valid MBR

+

+Arguments:       

+  Mbr     - Parent Handle 

+  LastLba - Last Lba address on the device.

+

+Returns:

+  TRUE  - Mbr is a Valid MBR

+  FALSE - Mbr is not a Valid MBR

+

+--*/

+{

+  UINT32  StartingLBA;

+  UINT32  EndingLBA;

+  UINT32  NewEndingLBA;

+  INTN    Index1;

+  INTN    Index2;

+  BOOLEAN MbrValid;

+

+  if (Mbr->Signature != MBR_SIGNATURE) {

+    return FALSE;

+  }

+  //

+  // The BPB also has this signature, so it can not be used alone.

+  //

+  MbrValid = FALSE;

+  for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {

+    if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {

+      continue;

+    }

+

+    MbrValid    = TRUE;

+    StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);

+    EndingLBA   = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;

+    if (EndingLBA > LastLba) {

+      //

+      // Compatibility Errata:

+      //  Some systems try to hide drive space with their INT 13h driver

+      //  This does not hide space from the OS driver. This means the MBR

+      //  that gets created from DOS is smaller than the MBR created from

+      //  a real OS (NT & Win98). This leads to BlockIo->LastBlock being

+      //  wrong on some systems FDISKed by the OS.

+      //

+      // return FALSE since no block devices on a system are implemented

+      // with INT 13h

+      //

+      return FALSE;

+    }

+

+    for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {

+      if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {

+        continue;

+      }

+

+      NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;

+      if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {

+        //

+        // This region overlaps with the Index1'th region

+        //

+        return FALSE;

+      }

+    }

+  }

+  //

+  // Non of the regions overlapped so MBR is O.K.

+  //

+  return MbrValid;

+}

+

+BOOLEAN

+PartitionInstallMbrChildHandles (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath

+  )

+/*++

+

+Routine Description:

+  Install child handles if the Handle supports MBR format.

+

+Arguments:       

+  This       - Calling context.

+  Handle     - Parent Handle 

+  DiskIo     - Parent DiskIo interface

+  BlockIo    - Parent BlockIo interface

+  DevicePath - Parent Device Path

+

+Returns:

+  EFI_SUCCESS - If a child handle was added

+  other       - A child handle was not added

+

+--*/

+{

+  EFI_STATUS                Status;

+  MASTER_BOOT_RECORD        *Mbr;

+  UINT32                    ExtMbrStartingLba;

+  UINTN                     Index;

+  HARDDRIVE_DEVICE_PATH     HdDev;

+  HARDDRIVE_DEVICE_PATH     ParentHdDev;

+  BOOLEAN                   Found;

+  UINT32                    PartitionNumber;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;

+  EFI_DEVICE_PATH_PROTOCOL  *LastDevicePathNode;

+

+  Mbr             = NULL;

+  Found           = FALSE;

+

+  Mbr             = AllocatePool (BlockIo->Media->BlockSize);

+  if (Mbr == NULL) {

+    goto Done;

+  }

+

+  Status = BlockIo->ReadBlocks (

+                      BlockIo,

+                      BlockIo->Media->MediaId,

+                      0,

+                      BlockIo->Media->BlockSize,

+                      Mbr

+                      );

+  if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {

+    goto Done;

+  }

+  //

+  // We have a valid mbr - add each partition

+  //

+  //

+  // Get starting and ending LBA of the parent block device.

+  //

+  LastDevicePathNode = NULL;

+  ZeroMem (&ParentHdDev, sizeof (ParentHdDev));

+  DevicePathNode = DevicePath;

+  while (!EfiIsDevicePathEnd (DevicePathNode)) {

+    LastDevicePathNode  = DevicePathNode;

+    DevicePathNode      = EfiNextDevicePathNode (DevicePathNode);

+  }

+

+  if (LastDevicePathNode != NULL) {

+    if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH &&

+        DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP

+        ) {

+      gBS->CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev));

+    } else {

+      LastDevicePathNode = NULL;

+    }

+  }

+

+  PartitionNumber = 1;

+

+  ZeroMem (&HdDev, sizeof (HdDev));

+  HdDev.Header.Type     = MEDIA_DEVICE_PATH;

+  HdDev.Header.SubType  = MEDIA_HARDDRIVE_DP;

+  SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));

+  HdDev.MBRType         = MBR_TYPE_PCAT;

+  HdDev.SignatureType   = SIGNATURE_TYPE_MBR;

+

+  if (LastDevicePathNode == NULL) {

+    //

+    // This is a MBR, add each partition

+    //

+    for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {

+      if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA) == 0) {

+        //

+        // Don't use null MBR entries

+        //

+        continue;

+      }

+

+      if (Mbr->Partition[Index].OSIndicator == 0xEE) {

+        //

+        // This is the guard MBR for the GPT. If you ever see a GPT disk with zero partitions you can get here.

+        //  We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating 

+        //  this BlockIo would corrupt the GPT structures and require a recovery that would corrupt the format

+        //  that corrupted the GPT partition. 

+        //

+        continue;

+      }

+

+      HdDev.PartitionNumber = PartitionNumber ++;

+      HdDev.PartitionStart  = UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA);

+      HdDev.PartitionSize   = UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA);

+      CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (UINT32));

+

+      Status = PartitionInstallChildHandle (

+                This,

+                Handle,

+                DiskIo,

+                BlockIo,

+                DevicePath,

+                (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,

+                HdDev.PartitionStart,

+                HdDev.PartitionStart + HdDev.PartitionSize - 1,

+                MBR_SIZE,

+                (BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION)

+                );

+

+      if (!EFI_ERROR (Status)) {

+        Found = TRUE;

+      }

+    }

+  } else {

+    //

+    // It's an extended partition. Follow the extended partition

+    // chain to get all the logical drives

+    //

+    ExtMbrStartingLba = 0;

+

+    do {

+

+      Status = BlockIo->ReadBlocks (

+                          BlockIo,

+                          BlockIo->Media->MediaId,

+                          ExtMbrStartingLba,

+                          BlockIo->Media->BlockSize,

+                          Mbr

+                          );

+      if (EFI_ERROR (Status)) {

+        goto Done;

+      }

+

+      if (Mbr->Partition[0].OSIndicator == 0) {

+        break;

+      }

+

+      HdDev.PartitionNumber = PartitionNumber ++;

+      HdDev.PartitionStart  = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart;

+      HdDev.PartitionSize   = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA);

+      if (HdDev.PartitionStart + HdDev.PartitionSize - 1 >=

+            ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) {

+        break;

+      }

+

+      //

+      // The signature in EBR(Extended Boot Record) should always be 0.

+      //

+      *((UINT32 *) &HdDev.Signature[0]) = 0;

+

+      Status = PartitionInstallChildHandle (

+                This,

+                Handle,

+                DiskIo,

+                BlockIo,

+                DevicePath,

+                (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,

+                HdDev.PartitionStart - ParentHdDev.PartitionStart,

+                HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,

+                MBR_SIZE,

+                (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)

+                );

+      if (!EFI_ERROR (Status)) {

+        Found = TRUE;

+      }

+

+      if (Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION &&

+          Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION

+          ) {

+        break;

+      }

+

+      ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA);

+      //

+      // Don't allow partition to be self referencing

+      //

+      if (ExtMbrStartingLba == 0) {

+        break;

+      }

+    } while (ExtMbrStartingLba  < ParentHdDev.PartitionSize);

+  }

+

+Done:

+  gBS->FreePool (Mbr);

+

+  return Found;

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.h b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.h
new file mode 100644
index 0000000..c0022c8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.h
@@ -0,0 +1,68 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Mbr.h

+  

+Abstract:

+

+  Data Structures required for detecting MBR Partitions

+  

+Revision History

+

+--*/

+

+#ifndef _MBR_H_

+#define _MBR_H_

+

+#pragma pack(1)

+

+#define MBR_SIGNATURE               0xaa55

+#define MIN_MBR_DEVICE_SIZE         0x80000

+#define MBR_ERRATA_PAD              0x40000 // 128 MB

+#define EXTENDED_DOS_PARTITION      0x05

+#define EXTENDED_WINDOWS_PARTITION  0x0F

+#define MAX_MBR_PARTITIONS          4

+

+#define EFI_PARTITION               0xef

+#define MBR_SIZE                    512

+

+//

+// MBR Partition Entry

+//

+typedef struct {

+  UINT8 BootIndicator;

+  UINT8 StartHead;

+  UINT8 StartSector;

+  UINT8 StartTrack;

+  UINT8 OSIndicator;

+  UINT8 EndHead;

+  UINT8 EndSector;

+  UINT8 EndTrack;

+  UINT8 StartingLBA[4];

+  UINT8 SizeInLBA[4];

+} MBR_PARTITION_RECORD;

+

+//

+// MBR Partition table

+//

+typedef struct {

+  UINT8                 BootStrapCode[440];

+  UINT8                 UniqueMbrSignature[4];

+  UINT8                 Unknown[2];

+  MBR_PARTITION_RECORD  Partition[MAX_MBR_PARTITIONS];

+  UINT16                Signature;

+} MASTER_BOOT_RECORD;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c
new file mode 100644
index 0000000..59e33b2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c
@@ -0,0 +1,735 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  Partition.c

+

+Abstract:

+

+  Partition driver that produces logical BlockIo devices from a physical

+  BlockIo device. The logical BlockIo devices are based on the format

+  of the raw block devices media. Currently "El Torito CD-ROM", Legacy

+  MBR, and GPT partition schemes are supported.

+

+--*/

+

+#include "Partition.h"

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+PartitionEntryPoint (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+PartitionDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PartitionDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PartitionDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  );

+

+//

+// Partition Driver Global Variables

+//

+EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {

+  PartitionDriverBindingSupported,

+  PartitionDriverBindingStart,

+  PartitionDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+PartitionDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle. Any ControllerHandle

+    than contains a BlockIo and DiskIo protocol can be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to test

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device

+    EFI_ALREADY_STARTED - This driver is already running on this device

+    EFI_UNSUPPORTED     - This driver does not support this device

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+  EFI_DISK_IO_PROTOCOL      *DiskIo;

+  EFI_DEV_PATH              *Node;

+

+  if (RemainingDevicePath != NULL) {

+    Node = (EFI_DEV_PATH *) RemainingDevicePath;

+    if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||

+        Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||

+        DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)

+        ) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDiskIoProtocolGuid,

+                  (VOID **) &DiskIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiDiskIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PartitionDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Start this driver on ControllerHandle by opening a Block IO and Disk IO

+    protocol, reading Device Path, and creating a child handle with a

+    Disk IO and device path protocol.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to bind driver to

+    RemainingDevicePath - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver is added to DeviceHandle

+    EFI_ALREADY_STARTED - This driver is already running on DeviceHandle

+    other               - This driver does not support this device

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_STATUS                OpenStatus;

+  EFI_BLOCK_IO_PROTOCOL     *BlockIo;

+  EFI_DISK_IO_PROTOCOL      *DiskIo;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlockIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the Device Path Protocol on ControllerHandle's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDiskIoProtocolGuid,

+                  (VOID **) &DiskIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return Status;

+  }

+

+  OpenStatus = Status;

+

+  //

+  // If no media is present, do nothing here.

+  //

+  Status = EFI_UNSUPPORTED;

+  if (BlockIo->Media->MediaPresent) {

+    //

+    // Try for GPT, then El Torito, and then legacy MBR partition types. If the

+    // media supports a given partition type install child handles to represent

+    // the partitions described by the media.

+    //

+    if (PartitionInstallGptChildHandles (

+          This,

+          ControllerHandle,

+          DiskIo,

+          BlockIo,

+          ParentDevicePath

+          ) ||

+

+    PartitionInstallElToritoChildHandles (

+          This,

+          ControllerHandle,

+          DiskIo,

+          BlockIo,

+          ParentDevicePath

+          ) ||

+

+    PartitionInstallMbrChildHandles (

+          This,

+          ControllerHandle,

+          DiskIo,

+          BlockIo,

+          ParentDevicePath

+          )) {

+      Status = EFI_SUCCESS;

+    } else {

+      Status = EFI_NOT_FOUND;

+    }

+  }

+  //

+  // In the case that the driver is already started (OpenStatus == EFI_ALREADY_STARTED),

+  // the DevicePathProtocol and the DiskIoProtocol are not actually opened by the

+  // driver. So don't try to close them. Otherwise, we will break the dependency

+  // between the controller and the driver set up before.

+  //

+  if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDiskIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PartitionDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    ControllerHandle,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle. Support stoping any child handles

+    created by this driver.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    ControllerHandle  - Handle of device to stop driver on

+    NumberOfChildren  - Number of Children in the ChildHandleBuffer

+    ChildHandleBuffer - List of handles for the children we need to stop.

+

+  Returns:

+    EFI_SUCCESS         - This driver is removed DeviceHandle

+    EFI_DEVICE_ERROR    - This driver was not removed from this device

+

+--*/

+{

+  EFI_STATUS              Status;

+  UINTN                   Index;

+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;

+  BOOLEAN                 AllChildrenStopped;

+  PARTITION_PRIVATE_DATA  *Private;

+  EFI_DISK_IO_PROTOCOL    *DiskIo;

+

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDiskIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_SUCCESS;

+  }

+

+  AllChildrenStopped = TRUE;

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+    Status = gBS->OpenProtocol (

+                    ChildHandleBuffer[Index],

+                    &gEfiBlockIoProtocolGuid,

+                    (VOID **) &BlockIo,

+                    This->DriverBindingHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+

+      Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);

+

+      //

+      // All Software protocols have be freed from the handle so remove it.

+      //

+      BlockIo->FlushBlocks (BlockIo);

+

+      Status = gBS->CloseProtocol (

+                      ControllerHandle,

+                      &gEfiDiskIoProtocolGuid,

+                      This->DriverBindingHandle,

+                      ChildHandleBuffer[Index]

+                      );

+

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      ChildHandleBuffer[Index],

+                      &gEfiDevicePathProtocolGuid,

+                      Private->DevicePath,

+                      &gEfiBlockIoProtocolGuid,

+                      &Private->BlockIo,

+                      Private->EspGuid,

+                      NULL,

+                      NULL

+                      );

+      if (EFI_ERROR (Status)) {

+        gBS->OpenProtocol (

+              ControllerHandle,

+              &gEfiDiskIoProtocolGuid,

+              (VOID **) &DiskIo,

+              This->DriverBindingHandle,

+              ChildHandleBuffer[Index],

+              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+              );

+      } else {

+        gBS->FreePool (Private->DevicePath);

+        gBS->FreePool (Private);

+      }

+

+    }

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PartitionReset (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN BOOLEAN                ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset the parent Block Device.

+

+  Arguments:

+    This                 - Protocol instance pointer.

+    ExtendedVerification - Driver may perform diagnostics on reset.

+

+  Returns:

+    EFI_SUCCESS           - The device was reset.

+    EFI_DEVICE_ERROR      - The device is not functioning properly and could

+                            not be reset.

+

+--*/

+{

+  PARTITION_PRIVATE_DATA  *Private;

+

+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);

+

+  return Private->ParentBlockIo->Reset (

+                                  Private->ParentBlockIo,

+                                  ExtendedVerification

+                                  );

+}

+

+EFI_STATUS

+EFIAPI

+PartitionReadBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN UINT32                 MediaId,

+  IN EFI_LBA                Lba,

+  IN UINTN                  BufferSize,

+  OUT VOID                  *Buffer

+  )

+/*++

+

+  Routine Description:

+    Read by using the Disk IO protocol on the parent device. Lba addresses

+    must be converted to byte offsets.

+

+  Arguments:

+    This       - Protocol instance pointer.

+    MediaId    - Id of the media, changes every time the media is replaced.

+    Lba        - The starting Logical Block Address to read from

+    BufferSize - Size of Buffer, must be a multiple of device block size.

+    Buffer     - Buffer containing read data

+

+  Returns:

+    EFI_SUCCESS           - The data was read correctly from the device.

+    EFI_DEVICE_ERROR      - The device reported an error while performing the read.

+    EFI_NO_MEDIA          - There is no media in the device.

+    EFI_MEDIA_CHANGED     - The MediaId does not matched the current device.

+    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the

+                            device.

+    EFI_INVALID_PARAMETER - The read request contains device addresses that are not

+                            valid for the device.

+

+--*/

+{

+  PARTITION_PRIVATE_DATA  *Private;

+  UINT64                  Offset;

+

+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);

+

+  if (BufferSize % Private->BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;

+  if (Offset + BufferSize > Private->End) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Because some kinds of partition have different block size from their parent

+  // device, we call the Disk IO protocol on the parent device, not the Block IO

+  // protocol

+  //

+  return Private->DiskIo->ReadDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);

+}

+

+EFI_STATUS

+EFIAPI

+PartitionWriteBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN UINT32                 MediaId,

+  IN EFI_LBA                Lba,

+  IN UINTN                  BufferSize,

+  OUT VOID                  *Buffer

+  )

+/*++

+

+  Routine Description:

+    Write by using the Disk IO protocol on the parent device. Lba addresses

+    must be converted to byte offsets.

+

+  Arguments:

+    This       - Protocol instance pointer.

+    MediaId    - Id of the media, changes every time the media is replaced.

+    Lba        - The starting Logical Block Address to read from

+    BufferSize - Size of Buffer, must be a multiple of device block size.

+    Buffer     - Buffer containing read data

+

+  Returns:

+    EFI_SUCCESS           - The data was written correctly to the device.

+    EFI_WRITE_PROTECTED   - The device can not be written to.

+    EFI_DEVICE_ERROR      - The device reported an error while performing the write.

+    EFI_NO_MEDIA          - There is no media in the device.

+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.

+    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the

+                            device.

+    EFI_INVALID_PARAMETER - The write request contains a LBA that is not

+                            valid for the device.

+

+--*/

+{

+  PARTITION_PRIVATE_DATA  *Private;

+  UINT64                  Offset;

+

+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);

+

+  if (BufferSize % Private->BlockSize != 0) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;

+  if (Offset + BufferSize > Private->End) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Because some kinds of partition have different block size from their parent

+  // device, we call the Disk IO protocol on the parent device, not the Block IO

+  // protocol

+  //

+  return Private->DiskIo->WriteDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);

+}

+

+EFI_STATUS

+EFIAPI

+PartitionFlushBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This

+  )

+/*++

+

+  Routine Description:

+    Flush the parent Block Device.

+

+  Arguments:

+    This             - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS      - All outstanding data was written to the device

+    EFI_DEVICE_ERROR - The device reported an error while writing back the data

+    EFI_NO_MEDIA     - There is no media in the device.

+

+--*/

+{

+  PARTITION_PRIVATE_DATA  *Private;

+

+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);

+

+  return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);

+}

+

+EFI_STATUS

+PartitionInstallChildHandle (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ParentHandle,

+  IN  EFI_DISK_IO_PROTOCOL         *ParentDiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *ParentBlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *ParentDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,

+  IN  EFI_LBA                      Start,

+  IN  EFI_LBA                      End,

+  IN  UINT32                       BlockSize,

+  IN  BOOLEAN                      InstallEspGuid

+  )

+/*++

+

+Routine Description:

+  Create a child handle for a logical block device that represents the

+  bytes Start to End of the Parent Block IO device.

+

+Arguments:

+  This             - Calling context.

+  ParentHandle     - Parent Handle for new child

+  ParentDiskIo     - Parent DiskIo interface

+  ParentBlockIo    - Parent BlockIo interface

+  ParentDevicePath - Parent Device Path

+  DevicePathNode   - Child Device Path node

+  Start            - Start Block

+  End              - End Block

+  BlockSize        - Child block size

+  InstallEspGuid   - Flag to install EFI System Partition GUID on handle

+

+Returns:

+  EFI_SUCCESS - If a child handle was added

+  EFI_OUT_OF_RESOURCES  - A child handle was not added

+

+--*/

+{

+  EFI_STATUS              Status;

+  PARTITION_PRIVATE_DATA  *Private;

+

+  Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));

+  if (Private == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Private->Signature        = PARTITION_PRIVATE_DATA_SIGNATURE;

+

+  Private->Start            = MultU64x32 (Start, ParentBlockIo->Media->BlockSize);

+  Private->End              = MultU64x32 (End + 1, ParentBlockIo->Media->BlockSize);

+

+  Private->BlockSize        = BlockSize;

+  Private->ParentBlockIo    = ParentBlockIo;

+  Private->DiskIo           = ParentDiskIo;

+

+  Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;

+

+  Private->BlockIo.Media    = &Private->Media;

+  CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));

+  Private->Media.LogicalPartition = TRUE;

+  Private->Media.LastBlock = DivU64x32 (

+                               MultU64x32 (

+                                 End - Start + 1,

+                                 ParentBlockIo->Media->BlockSize

+                                 ),

+                               BlockSize

+                               ) - 1;

+

+  Private->Media.BlockSize      = (UINT32) BlockSize;

+

+  Private->BlockIo.Reset        = PartitionReset;

+  Private->BlockIo.ReadBlocks   = PartitionReadBlocks;

+  Private->BlockIo.WriteBlocks  = PartitionWriteBlocks;

+  Private->BlockIo.FlushBlocks  = PartitionFlushBlocks;

+

+  Private->DevicePath           = AppendDevicePathNode (ParentDevicePath, DevicePathNode);

+

+  if (Private->DevicePath == NULL) {

+    gBS->FreePool (Private);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  if (InstallEspGuid) {

+    Private->EspGuid = &gEfiPartTypeSystemPartGuid;

+  } else {

+    //

+    // If NULL InstallMultipleProtocolInterfaces will ignore it.

+    //

+    Private->EspGuid = NULL;

+  }

+  //

+  // Create the new handle

+  //

+  Private->Handle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Private->Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  Private->DevicePath,

+                  &gEfiBlockIoProtocolGuid,

+                  &Private->BlockIo,

+                  Private->EspGuid,

+                  NULL,

+                  NULL

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // Open the Parent Handle for the child

+    //

+    Status = gBS->OpenProtocol (

+                    ParentHandle,

+                    &gEfiDiskIoProtocolGuid,

+                    (VOID **) &ParentDiskIo,

+                    This->DriverBindingHandle,

+                    Private->Handle,

+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                    );

+  } else {

+    gBS->FreePool (Private->DevicePath);

+    gBS->FreePool (Private);

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h
new file mode 100644
index 0000000..de6fbf1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h
@@ -0,0 +1,123 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Partition.h

+  

+Abstract:

+

+  Partition driver that produces logical BlockIo devices from a physical 

+  BlockIo device. The logical BlockIo devices are based on the format

+  of the raw block devices media. Currently "El Torito CD-ROM", Legacy 

+  MBR, and GPT partition schemes are supported.

+

+Revision History

+

+--*/

+

+#ifndef __PARTITION_H__

+#define __PARTITION_H__

+

+

+

+//

+// Partition private data

+//

+#define PARTITION_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('P', 'a', 'r', 't')

+typedef struct {

+  UINT64                    Signature;

+

+  EFI_HANDLE                Handle;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_BLOCK_IO_PROTOCOL     BlockIo;

+  EFI_BLOCK_IO_MEDIA        Media;

+

+  EFI_DISK_IO_PROTOCOL      *DiskIo;

+  EFI_BLOCK_IO_PROTOCOL     *ParentBlockIo;

+  UINT64                    Start;

+  UINT64                    End;

+  UINT32                    BlockSize;

+

+  EFI_GUID                  *EspGuid;

+

+} PARTITION_PRIVATE_DATA;

+

+#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a)  CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gPartitionDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gPartitionComponentName;

+

+//

+// Extract INT32 from char array

+//

+#define UNPACK_INT32(a) (INT32)( (((UINT8 *) a)[0] <<  0) |    \

+                                 (((UINT8 *) a)[1] <<  8) |    \

+                                 (((UINT8 *) a)[2] << 16) |    \

+                                 (((UINT8 *) a)[3] << 24) )

+

+//

+// Extract UINT32 from char array

+//

+#define UNPACK_UINT32(a) (UINT32)( (((UINT8 *) a)[0] <<  0) |    \

+                                   (((UINT8 *) a)[1] <<  8) |    \

+                                   (((UINT8 *) a)[2] << 16) |    \

+                                   (((UINT8 *) a)[3] << 24) )

+

+EFI_STATUS

+PartitionInstallChildHandle (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ParentHandle,

+  IN  EFI_DISK_IO_PROTOCOL         *ParentDiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *ParentBlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *ParentDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,

+  IN  UINT64                       Start,

+  IN  UINT64                       End,

+  IN  UINT32                       BlockSize,

+  IN  BOOLEAN                      InstallEspGuid

+  )

+;

+

+BOOLEAN

+PartitionInstallGptChildHandles (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath

+  )

+;

+

+BOOLEAN

+PartitionInstallElToritoChildHandles (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath

+  )

+;

+

+BOOLEAN

+PartitionInstallMbrChildHandles (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,

+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.mbd b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.mbd
new file mode 100644
index 0000000..7be0d52
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Partition</BaseName>

+    <Guid>1FA1F39E-FEFF-4aae-BD7B-38A070A3B609</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.msa b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.msa
new file mode 100644
index 0000000..3604555
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.msa
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Partition</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>1FA1F39E-FEFF-4aae-BD7B-38A070A3B609</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Partition module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Partition.h</Filename>

+    <Filename>ElTorito.h</Filename>

+    <Filename>Gpt.h</Filename>

+    <Filename>Mbr.h</Filename>

+    <Filename>Partition.c</Filename>

+    <Filename>ElTorito.c</Filename>

+    <Filename>Gpt.c</Filename>

+    <Filename>Mbr.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">BlockIo</Protocol>

+    <Protocol Usage="TO_START">DiskIo</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>PartTypeSystemPart</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PartTypeUnused</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPartitionDriverBinding</DriverBinding>

+      <ComponentName>gPartitionComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/build.xml
new file mode 100644
index 0000000..42d5194
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/Partition/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Partition"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Disk/Partition/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Partition">

+      <GenBuild baseName="Partition" mbdFilename="${MODULE_DIR}/Partition.mbd" msaFilename="${MODULE_DIR}/Partition.msa"/>

+   </target>

+   <target depends="Partition_clean" name="clean"/>

+   <target depends="Partition_cleanall" name="cleanall"/>

+   <target name="Partition_clean">

+      <OutputDirSetup baseName="Partition" mbdFilename="${MODULE_DIR}/Partition.mbd" msaFilename="${MODULE_DIR}/Partition.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Partition_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Partition_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Partition_cleanall">

+      <OutputDirSetup baseName="Partition" mbdFilename="${MODULE_DIR}/Partition.mbd" msaFilename="${MODULE_DIR}/Partition.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Partition_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Partition_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Partition*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.mbd b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.mbd
new file mode 100644
index 0000000..46b51cf
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.mbd
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>English</BaseName>

+    <Guid>CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>    

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa
new file mode 100644
index 0000000..0a01547
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>English</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for English module for unicode collation.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UnicodeCollationEng.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">UnicodeCollation</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeUnicodeCollationEng</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c
new file mode 100644
index 0000000..f043f37
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c
@@ -0,0 +1,478 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  UnicodeCollationEng.c

+

+Abstract:

+  

+  Unicode Collation Protocol (English)

+

+Revision History

+

+--*/

+

+#include "UnicodeCollationEng.h"

+

+CHAR8 mEngUpperMap[0x100];

+CHAR8 mEngLowerMap[0x100];

+CHAR8 mEngInfoMap[0x100];

+

+CHAR8 mOtherChars[] = {

+  '0',

+  '1',

+  '2',

+  '3',

+  '4',

+  '5',

+  '6',

+  '7',

+  '8',

+  '9',

+  '\\',

+  '.',

+  '_',

+  '^',

+  '$',

+  '~',

+  '!',

+  '#',

+  '%',

+  '&',

+  '-',

+  '{',

+  '}',

+  '(',

+  ')',

+  '@',

+  '`',

+  '\'',

+  '\0'

+};

+

+EFI_HANDLE  mHandle = NULL;

+

+EFI_UNICODE_COLLATION_PROTOCOL  UnicodeEng = {

+  EngStriColl,

+  EngMetaiMatch,

+  EngStrLwr,

+  EngStrUpr,

+  EngFatToStr,

+  EngStrToFat,

+  "eng"

+};

+

+//

+//

+//

+EFI_STATUS

+InitializeUnicodeCollationEng (

+  IN EFI_HANDLE       ImageHandle,

+  IN EFI_SYSTEM_TABLE *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initializes the Unicode Collation Driver

+

+Arguments:

+

+  ImageHandle -

+

+  SystemTable -

+  

+Returns:

+

+  EFI_SUCCESS

+  EFI_OUT_OF_RESOURCES

+

+--*/

+{

+  UINTN       Index;

+  UINTN       Index2;

+

+  //

+  // Initialize mapping tables for the supported languages

+  //

+  for (Index = 0; Index < 0x100; Index++) {

+    mEngUpperMap[Index] = (CHAR8) Index;

+    mEngLowerMap[Index] = (CHAR8) Index;

+    mEngInfoMap[Index]  = 0;

+

+    if ((Index >= 'a' && Index <= 'z') || (Index >= 0xe0 && Index <= 0xf6) || (Index >= 0xf8 && Index <= 0xfe)) {

+

+      Index2                = Index - 0x20;

+      mEngUpperMap[Index]   = (CHAR8) Index2;

+      mEngLowerMap[Index2]  = (CHAR8) Index;

+

+      mEngInfoMap[Index] |= CHAR_FAT_VALID;

+      mEngInfoMap[Index2] |= CHAR_FAT_VALID;

+    }

+  }

+

+  for (Index = 0; mOtherChars[Index]; Index++) {

+    Index2 = mOtherChars[Index];

+    mEngInfoMap[Index2] |= CHAR_FAT_VALID;

+  }

+  //

+  // Create a handle for the device

+  //

+  return gBS->InstallProtocolInterface (

+                &mHandle,

+                &gEfiUnicodeCollationProtocolGuid,

+                EFI_NATIVE_INTERFACE,

+                &UnicodeEng

+                );

+}

+

+INTN

+EFIAPI

+EngStriColl (

+  IN EFI_UNICODE_COLLATION_PROTOCOL   *This,

+  IN CHAR16                           *s1,

+  IN CHAR16                           *s2

+  )

+/*++

+

+Routine Description:

+

+  Performs a case-insensitive comparison of two Null-terminated Unicode strings.

+  

+Arguments:

+

+  This

+  s1

+  s2

+  

+Returns:

+

+--*/

+{

+  while (*s1) {

+    if (ToUpper (*s1) != ToUpper (*s2)) {

+      break;

+    }

+

+    s1 += 1;

+    s2 += 1;

+  }

+

+  return ToUpper (*s1) - ToUpper (*s2);

+}

+

+VOID

+EFIAPI

+EngStrLwr (

+  IN EFI_UNICODE_COLLATION_PROTOCOL   *This,

+  IN OUT CHAR16                       *Str

+  )

+/*++

+

+Routine Description:

+

+  Converts all the Unicode characters in a Null-terminated Unicode string

+  to lower case Unicode characters.

+

+Arguments:

+

+  This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.

+  Str1  - A pointer to a Null-terminated Unicode string.

+  Str2  - A pointer to a Null-terminated Unicode string.

+

+Returns:

+

+  0   - s1 is equivalent to s2.

+  > 0 - s1 is lexically greater than s2.

+  < 0 - s1 is lexically less than s2.

+

+--*/

+{

+  while (*Str) {

+    *Str = ToLower (*Str);

+    Str += 1;

+  }

+}

+

+VOID

+EFIAPI

+EngStrUpr (

+  IN EFI_UNICODE_COLLATION_PROTOCOL   *This,

+  IN OUT CHAR16                       *Str

+  )

+/*++

+

+Routine Description:

+

+  Converts all the Unicode characters in a Null-terminated 

+  Unicode string to upper case Unicode characters.

+

+Arguments:

+  This

+  Str

+

+Returns:

+  None

+  

+--*/

+{

+  while (*Str) {

+    *Str = ToUpper (*Str);

+    Str += 1;

+  }

+}

+

+BOOLEAN

+EFIAPI

+EngMetaiMatch (

+  IN EFI_UNICODE_COLLATION_PROTOCOL   *This,

+  IN CHAR16                           *String,

+  IN CHAR16                           *Pattern

+  )

+/*++

+

+Routine Description:

+

+  Performs a case-insensitive comparison between a Null-terminated

+  Unicode pattern string and a Null-terminated Unicode string. 

+

+  The pattern string can use the '?' wildcard to match any character, 

+  and the '*' wildcard to match any sub-string.

+

+Arguments:

+

+  This     - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.

+  String   - A pointer to a Null-terminated Unicode string.

+  Pattern  - A pointer to a Null-terminated Unicode pattern string.

+

+Returns:

+

+  TRUE  - Pattern was found in String.

+  FALSE - Pattern was not found in String.

+

+--*/

+{

+  CHAR16  CharC;

+  CHAR16  CharP;

+  CHAR16  Index3;

+

+  for (;;) {

+    CharP = *Pattern;

+    Pattern += 1;

+

+    switch (CharP) {

+    case 0:

+      //

+      // End of pattern.  If end of string, TRUE match

+      //

+      if (*String) {

+        return FALSE;

+      } else {

+        return TRUE;

+      }

+

+    case '*':

+      //

+      // Match zero or more chars

+      //

+      while (*String) {

+        if (EngMetaiMatch (This, String, Pattern)) {

+          return TRUE;

+        }

+

+        String += 1;

+      }

+

+      return EngMetaiMatch (This, String, Pattern);

+

+    case '?':

+      //

+      // Match any one char

+      //

+      if (!*String) {

+        return FALSE;

+      }

+

+      String += 1;

+      break;

+

+    case '[':

+      //

+      // Match char set

+      //

+      CharC = *String;

+      if (!CharC) {

+        //

+        // syntax problem

+        //

+        return FALSE;

+      }

+

+      Index3  = 0;

+      CharP   = *Pattern++;

+      while (CharP) {

+        if (CharP == ']') {

+          return FALSE;

+        }

+

+        if (CharP == '-') {

+          //

+          // if range of chars, get high range

+          //

+          CharP = *Pattern;

+          if (CharP == 0 || CharP == ']') {

+            //

+            // syntax problem

+            //

+            return FALSE;

+          }

+

+          if (ToUpper (CharC) >= ToUpper (Index3) && ToUpper (CharC) <= ToUpper (CharP)) {

+            //

+            // if in range, it's a match

+            //

+            break;

+          }

+        }

+

+        Index3 = CharP;

+        if (ToUpper (CharC) == ToUpper (CharP)) {

+          //

+          // if char matches

+          //

+          break;

+        }

+

+        CharP = *Pattern++;

+      }

+      //

+      // skip to end of match char set

+      //

+      while (CharP && CharP != ']') {

+        CharP = *Pattern;

+        Pattern += 1;

+      }

+

+      String += 1;

+      break;

+

+    default:

+      CharC = *String;

+      if (ToUpper (CharC) != ToUpper (CharP)) {

+        return FALSE;

+      }

+

+      String += 1;

+      break;

+    }

+  }

+}

+

+VOID

+EFIAPI

+EngFatToStr (

+  IN EFI_UNICODE_COLLATION_PROTOCOL   *This,

+  IN UINTN                            FatSize,

+  IN CHAR8                            *Fat,

+  OUT CHAR16                          *String

+  )

+/*++

+

+Routine Description:

+

+  Converts an 8.3 FAT file name using an OEM character set 

+  to a Null-terminated Unicode string.

+

+  BUGBUG: Function has to expand DBCS FAT chars, currently not.

+

+Arguments:

+  This

+  FatSize

+  Fat

+  String

+  

+Returns:

+

+--*/

+{

+  //

+  // No DBCS issues, just expand and add null terminate to end of string

+  //

+  while (*Fat && FatSize) {

+    *String = *Fat;

+    String += 1;

+    Fat += 1;

+    FatSize -= 1;

+  }

+

+  *String = 0;

+}

+

+BOOLEAN

+EFIAPI

+EngStrToFat (

+  IN EFI_UNICODE_COLLATION_PROTOCOL   *This,

+  IN CHAR16                           *String,

+  IN UINTN                            FatSize,

+  OUT CHAR8                           *Fat

+  )

+/*++

+

+Routine Description:

+

+  Converts a Null-terminated Unicode string to legal characters 

+  in a FAT filename using an OEM character set.

+

+  Functions has to crunch string to a fat string. Replacing

+  any chars that can't be represented in the fat name.

+

+Arguments:

+  This

+  String

+  FatSize

+  Fat

+

+Returns:

+  TRUE

+  FALSE

+--*/

+{

+  BOOLEAN SpecialCharExist;

+

+  SpecialCharExist = FALSE;

+  while (*String && FatSize) {

+    //

+    // Skip '.' or ' ' when making a fat name

+    //

+    if (*String != '.' && *String != ' ') {

+      //

+      // If this is a valid fat char, move it.

+      // Otherwise, move a '_' and flag the fact that the name needs an Lfn

+      //

+      if (*String < 0x100 && (mEngInfoMap[*String] & CHAR_FAT_VALID)) {

+        *Fat = mEngUpperMap[*String];

+      } else {

+        *Fat              = '_';

+        SpecialCharExist  = TRUE;

+      }

+

+      Fat += 1;

+      FatSize -= 1;

+    }

+

+    String += 1;

+  }

+  //

+  // Do not terminate that fat string

+  //

+  return SpecialCharExist;

+}

diff --git a/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h
new file mode 100644
index 0000000..6bd5479
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h
@@ -0,0 +1,102 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  UnicodeCollationEng.h

+

+Abstract:

+

+  Head file for Unicode Collation Protocol (English)

+

+Revision History

+

+--*/

+

+#ifndef _UNICODE_COLLATION_ENG_H

+#define _UNICODE_COLLATION_ENG_H

+

+

+

+//

+// Defines

+//

+#define CHAR_FAT_VALID  0x01

+

+#define ToUpper(a)      (CHAR16) (a <= 0xFF ? mEngUpperMap[a] : a)

+#define ToLower(a)      (CHAR16) (a <= 0xFF ? mEngLowerMap[a] : a)

+

+//

+// Prototypes

+//

+INTN

+EFIAPI

+EngStriColl (

+  IN EFI_UNICODE_COLLATION_PROTOCOL           *This,

+  IN CHAR16                                   *s1,

+  IN CHAR16                                   *s2

+  )

+;

+

+BOOLEAN

+EFIAPI

+EngMetaiMatch (

+  IN EFI_UNICODE_COLLATION_PROTOCOL          *This,

+  IN CHAR16                                  *String,

+  IN CHAR16                                  *Pattern

+  )

+;

+

+VOID

+EFIAPI

+EngStrLwr (

+  IN EFI_UNICODE_COLLATION_PROTOCOL          *This,

+  IN OUT CHAR16                              *Str

+  )

+;

+

+VOID

+EFIAPI

+EngStrUpr (

+  IN EFI_UNICODE_COLLATION_PROTOCOL          *This,

+  IN OUT CHAR16                              *Str

+  )

+;

+

+VOID

+EFIAPI

+EngFatToStr (

+  IN EFI_UNICODE_COLLATION_PROTOCOL          *This,

+  IN UINTN                                   FatSize,

+  IN CHAR8                                   *Fat,

+  OUT CHAR16                                 *String

+  )

+;

+

+BOOLEAN

+EFIAPI

+EngStrToFat (

+  IN EFI_UNICODE_COLLATION_PROTOCOL          *This,

+  IN CHAR16                                  *String,

+  IN UINTN                                   FatSize,

+  OUT CHAR8                                  *Fat

+  )

+;

+

+EFI_STATUS

+EFIAPI

+InitializeUnicodeCollationEng (

+  IN EFI_HANDLE       ImageHandle,

+  IN EFI_SYSTEM_TABLE *SystemTable

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/build.xml
new file mode 100644
index 0000000..ab86d5a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="English"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Disk/UnicodeCollation/English/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="English">

+      <GenBuild baseName="English" mbdFilename="${MODULE_DIR}/English.mbd" msaFilename="${MODULE_DIR}/English.msa"/>

+   </target>

+   <target depends="English_clean" name="clean"/>

+   <target depends="English_cleanall" name="cleanall"/>

+   <target name="English_clean">

+      <OutputDirSetup baseName="English" mbdFilename="${MODULE_DIR}/English.mbd" msaFilename="${MODULE_DIR}/English.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/English_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/English_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="English_cleanall">

+      <OutputDirSetup baseName="English" mbdFilename="${MODULE_DIR}/English.mbd" msaFilename="${MODULE_DIR}/English.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/English_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/English_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**English*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.dxs b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.dxs
new file mode 100644
index 0000000..662aa1c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ebc.dxs

+

+Abstract:

+

+  Dependency expression file for EBC VM.

+  

+--*/

+#include <AutoGen.h>

+#include <DxeDepex.h>  

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.mbd b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.mbd
new file mode 100644
index 0000000..6107359
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Ebc</BaseName>

+    <Guid>13AC6DD0-73D0-11D4-B06B-00AA00BD6DE7</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-22 14:03</Created>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.msa b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.msa
new file mode 100644
index 0000000..8f027fa
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ebc.msa
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Ebc</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>13AC6DD0-73D0-11D4-B06B-00AA00BD6DE7</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-22 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>EbcInt.c</Filename>

+    <Filename>EbcInt.h</Filename>

+    <Filename>EbcExecute.c</Filename>

+    <Filename>EbcExecute.h</Filename>

+    <Filename>Ebc.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/EbcLowLevel.asm</Filename>

+      <Filename>Ia32/Ia32Math.asm</Filename>

+      <Filename>Ia32/EbcSupport.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x64/EbcLowLevel.asm</Filename>

+      <Filename>x64/x64Math.c</Filename>

+      <Filename>x64/EbcSupport.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/EbcLowLevel.s</Filename>

+      <Filename>Ipf/IpfMath.c</Filename>

+      <Filename>Ipf/IpfMul.s</Filename>

+      <Filename>Ipf/EbcSupport.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Ebc</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">DebugSupport</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeEbcDriver</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c
new file mode 100644
index 0000000..9d375a5
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c
@@ -0,0 +1,4603 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EbcExecute.c

+

+Abstract:

+

+  Contains code that implements the virtual machine.

+

+--*/

+

+#include "EbcInt.h"

+#include "EbcExecute.h"

+

+//

+// VM major/minor version

+//

+#define VM_MAJOR_VERSION  1

+#define VM_MINOR_VERSION  0

+

+//

+// Define some useful data size constants to allow switch statements based on

+// size of operands or data.

+//

+#define DATA_SIZE_INVALID 0

+#define DATA_SIZE_8       1

+#define DATA_SIZE_16      2

+#define DATA_SIZE_32      4

+#define DATA_SIZE_64      8

+#define DATA_SIZE_N       48  // 4 or 8

+//

+// Structure we'll use to dispatch opcodes to execute functions.

+//

+typedef struct {

+  EFI_STATUS (*ExecuteFunction) (IN VM_CONTEXT * VmPtr);

+}

+VM_TABLE_ENTRY;

+

+typedef

+UINT64

+(*DATA_MANIP_EXEC_FUNCTION) (

+  IN VM_CONTEXT * VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+INT16

+VmReadIndex16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     CodeOffset

+  );

+

+STATIC

+INT32

+VmReadIndex32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     CodeOffset

+  );

+

+STATIC

+INT64

+VmReadIndex64 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     CodeOffset

+  );

+

+STATIC

+UINT8

+VmReadMem8 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  );

+

+STATIC

+UINT16

+VmReadMem16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  );

+

+STATIC

+UINT32

+VmReadMem32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  );

+

+STATIC

+UINT64

+VmReadMem64 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  );

+

+STATIC

+UINTN

+VmReadMemN (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  );

+

+STATIC

+EFI_STATUS

+VmWriteMem8 (

+  IN VM_CONTEXT *VmPtr,

+  UINTN         Addr,

+  IN UINT8      Data

+  );

+

+STATIC

+EFI_STATUS

+VmWriteMem16 (

+  IN VM_CONTEXT *VmPtr,

+  UINTN         Addr,

+  IN UINT16     Data

+  );

+

+STATIC

+EFI_STATUS

+VmWriteMem32 (

+  IN VM_CONTEXT *VmPtr,

+  UINTN         Addr,

+  IN UINT32     Data

+  );

+

+EFI_STATUS

+VmWriteMemN (

+  IN VM_CONTEXT *VmPtr,

+  UINTN         Addr,

+  IN UINTN      Data

+  );

+

+EFI_STATUS

+VmWriteMem64 (

+  IN VM_CONTEXT *VmPtr,

+  UINTN         Addr,

+  IN UINT64     Data

+  );

+

+STATIC

+UINT16

+VmReadCode16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+UINT32

+VmReadCode32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+UINT64

+VmReadCode64 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+INT8

+VmReadImmed8 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+INT16

+VmReadImmed16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+INT32

+VmReadImmed32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+INT64

+VmReadImmed64 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  );

+

+STATIC

+UINTN

+ConvertStackAddr (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteDataManip (

+  IN VM_CONTEXT   *VmPtr,

+  IN BOOLEAN      IsSignedOperation

+  );

+

+//

+// Functions that execute VM opcodes

+//

+STATIC

+EFI_STATUS

+ExecuteBREAK (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteJMP (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteJMP8 (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteCALL (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteRET (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteCMP (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteCMPI (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteMOVxx (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteMOVI (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteMOVIn (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteMOVREL (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecutePUSHn (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecutePUSH (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecutePOPn (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecutePOP (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteSignedDataManip (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteUnsignedDataManip (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteLOADSP (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteSTORESP (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteMOVsnd (

+  IN VM_CONTEXT *VmPtr

+  );

+

+STATIC

+EFI_STATUS

+ExecuteMOVsnw (

+  IN VM_CONTEXT *VmPtr

+  );

+

+//

+// Data manipulation subfunctions

+//

+STATIC

+UINT64

+ExecuteNOT (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteNEG (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteADD (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteSUB (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteMUL (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteMULU (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteDIV (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteDIVU (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteMOD (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteMODU (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteAND (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteOR (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteXOR (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteSHL (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteSHR (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteASHR (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteEXTNDB (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteEXTNDW (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+STATIC

+UINT64

+ExecuteEXTNDD (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT64     Op1,

+  IN UINT64     Op2

+  );

+

+//

+// Once we retrieve the operands for the data manipulation instructions,

+// call these functions to perform the operation.

+//

+static CONST DATA_MANIP_EXEC_FUNCTION mDataManipDispatchTable[] = {

+  ExecuteNOT,

+  ExecuteNEG,

+  ExecuteADD,

+  ExecuteSUB,

+  ExecuteMUL,

+  ExecuteMULU,

+  ExecuteDIV,

+  ExecuteDIVU,

+  ExecuteMOD,

+  ExecuteMODU,

+  ExecuteAND,

+  ExecuteOR,

+  ExecuteXOR,

+  ExecuteSHL,

+  ExecuteSHR,

+  ExecuteASHR,

+  ExecuteEXTNDB,

+  ExecuteEXTNDW,

+  ExecuteEXTNDD,

+};

+

+static CONST VM_TABLE_ENTRY           mVmOpcodeTable[] = {

+  { ExecuteBREAK },             // opcode 0x00

+  { ExecuteJMP },               // opcode 0x01

+  { ExecuteJMP8 },              // opcode 0x02

+  { ExecuteCALL },              // opcode 0x03

+  { ExecuteRET },               // opcode 0x04

+  { ExecuteCMP },               // opcode 0x05 CMPeq

+  { ExecuteCMP },               // opcode 0x06 CMPlte

+  { ExecuteCMP },               // opcode 0x07 CMPgte

+  { ExecuteCMP },               // opcode 0x08 CMPulte

+  { ExecuteCMP },               // opcode 0x09 CMPugte

+  { ExecuteUnsignedDataManip }, // opcode 0x0A NOT

+  { ExecuteSignedDataManip },   // opcode 0x0B NEG

+  { ExecuteSignedDataManip },   // opcode 0x0C ADD

+  { ExecuteSignedDataManip },   // opcode 0x0D SUB

+  { ExecuteSignedDataManip },   // opcode 0x0E MUL

+  { ExecuteUnsignedDataManip }, // opcode 0x0F MULU

+  { ExecuteSignedDataManip },   // opcode 0x10 DIV

+  { ExecuteUnsignedDataManip }, // opcode 0x11 DIVU

+  { ExecuteSignedDataManip },   // opcode 0x12 MOD

+  { ExecuteUnsignedDataManip }, // opcode 0x13 MODU

+  { ExecuteUnsignedDataManip }, // opcode 0x14 AND

+  { ExecuteUnsignedDataManip }, // opcode 0x15 OR

+  { ExecuteUnsignedDataManip }, // opcode 0x16 XOR

+  { ExecuteUnsignedDataManip }, // opcode 0x17 SHL

+  { ExecuteUnsignedDataManip }, // opcode 0x18 SHR

+  { ExecuteSignedDataManip },   // opcode 0x19 ASHR

+  { ExecuteUnsignedDataManip }, // opcode 0x1A EXTNDB

+  { ExecuteUnsignedDataManip }, // opcode 0x1B EXTNDW

+  { ExecuteUnsignedDataManip }, // opcode 0x1C EXTNDD

+  { ExecuteMOVxx },             // opcode 0x1D MOVBW

+  { ExecuteMOVxx },             // opcode 0x1E MOVWW

+  { ExecuteMOVxx },             // opcode 0x1F MOVDW

+  { ExecuteMOVxx },             // opcode 0x20 MOVQW

+  { ExecuteMOVxx },             // opcode 0x21 MOVBD

+  { ExecuteMOVxx },             // opcode 0x22 MOVWD

+  { ExecuteMOVxx },             // opcode 0x23 MOVDD

+  { ExecuteMOVxx },             // opcode 0x24 MOVQD

+  { ExecuteMOVsnw },            // opcode 0x25 MOVsnw

+  { ExecuteMOVsnd },            // opcode 0x26 MOVsnd

+  { NULL },                     // opcode 0x27

+  { ExecuteMOVxx },             // opcode 0x28 MOVqq

+  { ExecuteLOADSP },            // opcode 0x29 LOADSP SP1, R2

+  { ExecuteSTORESP },           // opcode 0x2A STORESP R1, SP2

+  { ExecutePUSH },              // opcode 0x2B PUSH {@}R1 [imm16]

+  { ExecutePOP },               // opcode 0x2C POP {@}R1 [imm16]

+  { ExecuteCMPI },              // opcode 0x2D CMPIEQ

+  { ExecuteCMPI },              // opcode 0x2E CMPILTE

+  { ExecuteCMPI },              // opcode 0x2F CMPIGTE

+  { ExecuteCMPI },              // opcode 0x30 CMPIULTE

+  { ExecuteCMPI },              // opcode 0x31 CMPIUGTE

+  { ExecuteMOVxx },             // opcode 0x32 MOVN

+  { ExecuteMOVxx },             // opcode 0x33 MOVND

+  { NULL },                     // opcode 0x34

+  { ExecutePUSHn },             // opcode 0x35

+  { ExecutePOPn },              // opcode 0x36

+  { ExecuteMOVI },              // opcode 0x37 - mov immediate data

+  { ExecuteMOVIn },             // opcode 0x38 - mov immediate natural

+  { ExecuteMOVREL }             // opcode 0x39 - move data relative to PC

+};

+

+//

+// Length of JMP instructions, depending on upper two bits of opcode.

+//

+static CONST UINT8                    mJMPLen[] = { 2, 2, 6, 10 };

+

+//

+// Simple Debugger Protocol GUID

+//

+EFI_GUID mEbcSimpleDebuggerProtocolGuid = EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL_GUID;

+

+EFI_STATUS

+EbcExecuteInstructions (

+  IN EFI_EBC_VM_TEST_PROTOCOL *This,

+  IN VM_CONTEXT               *VmPtr,

+  IN OUT UINTN                *InstructionCount

+  )

+/*++

+

+Routine Description:

+  

+  Given a pointer to a new VM context, execute one or more instructions. This

+  function is only used for test purposes via the EBC VM test protocol.

+

+Arguments:

+

+  This              - pointer to protocol interface

+  VmPtr             - pointer to a VM context

+  InstructionCount  - how many instructions to execute. 0 if don't count.

+

+Returns:

+

+  EFI_UNSUPPORTED

+  EFI_SUCCESS

+

+--*/

+{

+  UINTN       ExecFunc;

+  EFI_STATUS  Status;

+  UINTN       InstructionsLeft;

+  UINTN       SavedInstructionCount;

+

+  Status = EFI_SUCCESS;

+

+  if (*InstructionCount == 0) {

+    InstructionsLeft = 1;

+  } else {

+    InstructionsLeft = *InstructionCount;

+  }

+

+  SavedInstructionCount = *InstructionCount;

+  *InstructionCount     = 0;

+

+  //

+  // Index into the opcode table using the opcode byte for this instruction.

+  // This gives you the execute function, which we first test for null, then

+  // call it if it's not null.

+  //

+  while (InstructionsLeft != 0) {

+    ExecFunc = (UINTN) mVmOpcodeTable[(*VmPtr->Ip & 0x3F)].ExecuteFunction;

+    if (ExecFunc == (UINTN) NULL) {

+      EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr);

+      return EFI_UNSUPPORTED;

+    } else {

+      mVmOpcodeTable[(*VmPtr->Ip & 0x3F)].ExecuteFunction (VmPtr);

+      *InstructionCount = *InstructionCount + 1;

+    }

+

+    //

+    // Decrement counter if applicable

+    //

+    if (SavedInstructionCount != 0) {

+      InstructionsLeft--;

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EbcExecute (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute an EBC image from an entry point or from a published protocol.

+

+Arguments:

+

+  VmPtr - pointer to prepared VM context.

+

+Returns:

+

+  Standard EBC status.

+

+--*/

+{

+  UINTN                             ExecFunc;

+  UINT8                             StackCorrupted;

+  EFI_STATUS                        Status;

+  EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL  *EbcSimpleDebugger;

+

+  //

+  // end DEBUG_CODE

+  //

+  EbcSimpleDebugger = NULL;

+  Status            = EFI_SUCCESS;

+  StackCorrupted    = 0;

+

+  //

+  // Make sure the magic value has been put on the stack before we got here.

+  //

+  if (*VmPtr->StackMagicPtr != (UINTN) VM_STACK_KEY_VALUE) {

+    StackCorrupted = 1;

+  }

+

+  VmPtr->FramePtr = (VOID *) ((UINT8 *) (UINTN) VmPtr->R[0] + 8);

+

+  //

+  // Try to get the debug support for EBC

+  //

+  DEBUG_CODE (

+    Status = gBS->LocateProtocol (

+                    &mEbcSimpleDebuggerProtocolGuid,

+                    NULL,

+                    (VOID **) &EbcSimpleDebugger

+                    );

+    if (EFI_ERROR (Status)) {

+      EbcSimpleDebugger = NULL;

+    }

+  );

+

+  //

+  // Save the start IP for debug. For example, if we take an exception we

+  // can print out the location of the exception relative to the entry point,

+  // which could then be used in a disassembly listing to find the problem.

+  //

+  VmPtr->EntryPoint = (VOID *) VmPtr->Ip;

+

+  //

+  // We'll wait for this flag to know when we're done. The RET

+  // instruction sets it if it runs out of stack.

+  //

+  VmPtr->StopFlags = 0;

+  while (!(VmPtr->StopFlags & STOPFLAG_APP_DONE)) {

+    //

+    // If we've found a simple debugger protocol, call it

+    //

+    DEBUG_CODE (

+      if (EbcSimpleDebugger != NULL) {

+        EbcSimpleDebugger->Debugger (EbcSimpleDebugger, VmPtr);

+      }

+    );

+

+    //

+    // Verify the opcode is in range. Otherwise generate an exception.

+    //

+    if ((*VmPtr->Ip & OPCODE_M_OPCODE) >= (sizeof (mVmOpcodeTable) / sizeof (mVmOpcodeTable[0]))) {

+      EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr);

+      Status = EFI_UNSUPPORTED;

+      goto Done;

+    }

+    //

+    // Use the opcode bits to index into the opcode dispatch table. If the

+    // function pointer is null then generate an exception.

+    //

+    ExecFunc = (UINTN) mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction;

+    if (ExecFunc == (UINTN) NULL) {

+      EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr);

+      Status = EFI_UNSUPPORTED;

+      goto Done;

+    }

+    //

+    // The EBC VM is a strongly ordered processor, so perform a fence operation before

+    // and after each instruction is executed.

+    //

+    MemoryFence ();

+

+    mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction (VmPtr);

+

+    MemoryFence ();

+

+    //

+    // If the step flag is set, signal an exception and continue. We don't

+    // clear it here. Assuming the debugger is responsible for clearing it.

+    //

+    if (VMFLAG_ISSET (VmPtr, VMFLAGS_STEP)) {

+      EbcDebugSignalException (EXCEPT_EBC_STEP, EXCEPTION_FLAG_NONE, VmPtr);

+    }

+    //

+    // Make sure stack has not been corrupted. Only report it once though.

+    //

+    if (!StackCorrupted && (*VmPtr->StackMagicPtr != (UINTN) VM_STACK_KEY_VALUE)) {

+      EbcDebugSignalException (EXCEPT_EBC_STACK_FAULT, EXCEPTION_FLAG_FATAL, VmPtr);

+      StackCorrupted = 1;

+    }

+  }

+

+Done:

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+ExecuteMOVxx (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the MOVxx instructions.

+

+Arguments:

+

+  VmPtr - pointer to a VM context.

+

+Returns:

+

+  EFI_UNSUPPORTED

+  EFI_SUCCESS

+

+Instruction format:

+  

+  MOV[b|w|d|q|n]{w|d} {@}R1 {Index16|32}, {@}R2 {Index16|32}

+  MOVqq {@}R1 {Index64}, {@}R2 {Index64}

+

+  Copies contents of [R2] -> [R1], zero extending where required.

+

+  First character indicates the size of the move.

+  Second character indicates the size of the index(s).

+

+  Invalid to have R1 direct with index.

+  

+--*/

+{

+  UINT8   Opcode;

+  UINT8   OpcMasked;

+  UINT8   Operands;

+  UINT8   Size;

+  UINT8   MoveSize;

+  INT16   Index16;

+  INT32   Index32;

+  INT64   Index64Op1;

+  INT64   Index64Op2;

+  UINT64  Data64;

+  UINT64  DataMask;

+  UINTN   Source;

+

+  Opcode    = GETOPCODE (VmPtr);

+  OpcMasked = (UINT8) (Opcode & OPCODE_M_OPCODE);

+

+  //

+  // Get the operands byte so we can get R1 and R2

+  //

+  Operands = GETOPERANDS (VmPtr);

+

+  //

+  // Assume no indexes

+  //

+  Index64Op1  = 0;

+  Index64Op2  = 0;

+  Data64      = 0;

+

+  //

+  // Determine if we have an index/immediate data. Base instruction size

+  // is 2 (opcode + operands). Add to this size each index specified.

+  //

+  Size = 2;

+  if (Opcode & (OPCODE_M_IMMED_OP1 | OPCODE_M_IMMED_OP2)) {

+    //

+    // Determine size of the index from the opcode. Then get it.

+    //

+    if ((OpcMasked <= OPCODE_MOVQW) || (OpcMasked == OPCODE_MOVNW)) {

+      //

+      // MOVBW, MOVWW, MOVDW, MOVQW, and MOVNW have 16-bit immediate index.

+      // Get one or both index values.

+      //

+      if (Opcode & OPCODE_M_IMMED_OP1) {

+        Index16     = VmReadIndex16 (VmPtr, 2);

+        Index64Op1  = (INT64) Index16;

+        Size += sizeof (UINT16);

+      }

+

+      if (Opcode & OPCODE_M_IMMED_OP2) {

+        Index16     = VmReadIndex16 (VmPtr, Size);

+        Index64Op2  = (INT64) Index16;

+        Size += sizeof (UINT16);

+      }

+    } else if ((OpcMasked <= OPCODE_MOVQD) || (OpcMasked == OPCODE_MOVND)) {

+      //

+      // MOVBD, MOVWD, MOVDD, MOVQD, and MOVND have 32-bit immediate index

+      //

+      if (Opcode & OPCODE_M_IMMED_OP1) {

+        Index32     = VmReadIndex32 (VmPtr, 2);

+        Index64Op1  = (INT64) Index32;

+        Size += sizeof (UINT32);

+      }

+

+      if (Opcode & OPCODE_M_IMMED_OP2) {

+        Index32     = VmReadIndex32 (VmPtr, Size);

+        Index64Op2  = (INT64) Index32;

+        Size += sizeof (UINT32);

+      }

+    } else if (OpcMasked == OPCODE_MOVQQ) {

+      //

+      // MOVqq -- only form with a 64-bit index

+      //

+      if (Opcode & OPCODE_M_IMMED_OP1) {

+        Index64Op1 = VmReadIndex64 (VmPtr, 2);

+        Size += sizeof (UINT64);

+      }

+

+      if (Opcode & OPCODE_M_IMMED_OP2) {

+        Index64Op2 = VmReadIndex64 (VmPtr, Size);

+        Size += sizeof (UINT64);

+      }

+    } else {

+      //

+      // Obsolete MOVBQ, MOVWQ, MOVDQ, and MOVNQ have 64-bit immediate index

+      //

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+  }

+  //

+  // Determine the size of the move, and create a mask for it so we can

+  // clear unused bits.

+  //

+  if ((OpcMasked == OPCODE_MOVBW) || (OpcMasked == OPCODE_MOVBD)) {

+    MoveSize  = DATA_SIZE_8;

+    DataMask  = 0xFF;

+  } else if ((OpcMasked == OPCODE_MOVWW) || (OpcMasked == OPCODE_MOVWD)) {

+    MoveSize  = DATA_SIZE_16;

+    DataMask  = 0xFFFF;

+  } else if ((OpcMasked == OPCODE_MOVDW) || (OpcMasked == OPCODE_MOVDD)) {

+    MoveSize  = DATA_SIZE_32;

+    DataMask  = 0xFFFFFFFF;

+  } else if ((OpcMasked == OPCODE_MOVQW) || (OpcMasked == OPCODE_MOVQD) || (OpcMasked == OPCODE_MOVQQ)) {

+    MoveSize  = DATA_SIZE_64;

+    DataMask  = (UINT64)~0;

+  } else if ((OpcMasked == OPCODE_MOVNW) || (OpcMasked == OPCODE_MOVND)) {

+    MoveSize  = DATA_SIZE_N;

+    DataMask  = (UINT64)~0 >> (64 - 8 * sizeof (UINTN));

+  } else {

+    //

+    // We were dispatched to this function and we don't recognize the opcode

+    //

+    EbcDebugSignalException (EXCEPT_EBC_UNDEFINED, EXCEPTION_FLAG_FATAL, VmPtr);

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Now get the source address

+  //

+  if (OPERAND2_INDIRECT (Operands)) {

+    //

+    // Indirect form @R2. Compute address of operand2

+    //

+    Source = (UINTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Index64Op2);

+    //

+    // Now get the data from the source. Always 0-extend and let the compiler

+    // sign-extend where required.

+    //

+    switch (MoveSize) {

+    case DATA_SIZE_8:

+      Data64 = (UINT64) (UINT8) VmReadMem8 (VmPtr, Source);

+      break;

+

+    case DATA_SIZE_16:

+      Data64 = (UINT64) (UINT16) VmReadMem16 (VmPtr, Source);

+      break;

+

+    case DATA_SIZE_32:

+      Data64 = (UINT64) (UINT32) VmReadMem32 (VmPtr, Source);

+      break;

+

+    case DATA_SIZE_64:

+      Data64 = (UINT64) VmReadMem64 (VmPtr, Source);

+      break;

+

+    case DATA_SIZE_N:

+      Data64 = (UINT64) (UINTN) VmReadMemN (VmPtr, Source);

+      break;

+

+    default:

+      //

+      // not reached

+      //

+      break;

+    }

+  } else {

+    //

+    // Not indirect source: MOVxx {@}Rx, Ry [Index]

+    //

+    Data64 = VmPtr->R[OPERAND2_REGNUM (Operands)] + Index64Op2;

+    //

+    // Did Operand2 have an index? If so, treat as two signed values since

+    // indexes are signed values.

+    //

+    if (Opcode & OPCODE_M_IMMED_OP2) {

+      //

+      // NOTE: need to find a way to fix this, most likely by changing the VM

+      // implementation to remove the stack gap. To do that, we'd need to

+      // allocate stack space for the VM and actually set the system

+      // stack pointer to the allocated buffer when the VM starts.

+      //

+      // Special case -- if someone took the address of a function parameter

+      // then we need to make sure it's not in the stack gap. We can identify

+      // this situation if (Operand2 register == 0) && (Operand2 is direct)

+      // && (Index applies to Operand2) && (Index > 0) && (Operand1 register != 0)

+      // Situations that to be aware of:

+      //   * stack adjustments at beginning and end of functions R0 = R0 += stacksize

+      //

+      if ((OPERAND2_REGNUM (Operands) == 0) &&

+          (!OPERAND2_INDIRECT (Operands)) &&

+          (Index64Op2 > 0) &&

+          (OPERAND1_REGNUM (Operands) == 0) &&

+          (OPERAND1_INDIRECT (Operands))

+          ) {

+        Data64 = (UINT64) ConvertStackAddr (VmPtr, (UINTN) (INT64) Data64);

+      }

+    }

+  }

+  //

+  // Now write it back

+  //

+  if (OPERAND1_INDIRECT (Operands)) {

+    //

+    // Reuse the Source variable to now be dest.

+    //

+    Source = (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index64Op1);

+    //

+    // Do the write based on the size

+    //

+    switch (MoveSize) {

+    case DATA_SIZE_8:

+      VmWriteMem8 (VmPtr, Source, (UINT8) Data64);

+      break;

+

+    case DATA_SIZE_16:

+      VmWriteMem16 (VmPtr, Source, (UINT16) Data64);

+      break;

+

+    case DATA_SIZE_32:

+      VmWriteMem32 (VmPtr, Source, (UINT32) Data64);

+      break;

+

+    case DATA_SIZE_64:

+      VmWriteMem64 (VmPtr, Source, Data64);

+      break;

+

+    case DATA_SIZE_N:

+      VmWriteMemN (VmPtr, Source, (UINTN) Data64);

+      break;

+

+    default:

+      //

+      // not reached

+      //

+      break;

+    }

+  } else {

+    //

+    // Operand1 direct.

+    // Make sure we didn't have an index on operand1.

+    //

+    if (Opcode & OPCODE_M_IMMED_OP1) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+    //

+    // Direct storage in register. Clear unused bits and store back to

+    // register.

+    //

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = Data64 & DataMask;

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteBREAK (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC BREAK instruction

+

+Arguments:

+

+  VmPtr - pointer to current VM context

+

+Returns:

+

+  EFI_UNSUPPORTED

+  EFI_SUCCESS

+

+--*/

+{

+  UINT8       Operands;

+  VOID        *EbcEntryPoint;

+  VOID        *Thunk;

+  EFI_STATUS  Status;

+  UINT64      U64EbcEntryPoint;

+  INT32       Offset;

+

+  Operands = GETOPERANDS (VmPtr);

+  switch (Operands) {

+  //

+  // Runaway program break. Generate an exception and terminate

+  //

+  case 0:

+    EbcDebugSignalException (EXCEPT_EBC_BAD_BREAK, EXCEPTION_FLAG_FATAL, VmPtr);

+    break;

+

+  //

+  // Get VM version -- return VM revision number in R7

+  //

+  case 1:

+    //

+    // Bits:

+    //  63-17 = 0

+    //  16-8  = Major version

+    //  7-0   = Minor version

+    //

+    VmPtr->R[7] = GetVmVersion ();

+    break;

+

+  //

+  // Debugger breakpoint

+  //

+  case 3:

+    VmPtr->StopFlags |= STOPFLAG_BREAKPOINT;

+    //

+    // See if someone has registered a handler

+    //

+    EbcDebugSignalException (

+      EXCEPT_EBC_BREAKPOINT,

+      EXCEPTION_FLAG_NONE,

+      VmPtr

+      );

+    //

+    // Don't advance the IP

+    //

+    return EFI_UNSUPPORTED;

+    break;

+

+  //

+  // System call, which there are none, so NOP it.

+  //

+  case 4:

+    break;

+

+  //

+  // Create a thunk for EBC code. R7 points to a 32-bit (in a 64-bit slot)

+  // "offset from self" pointer to the EBC entry point.

+  // After we're done, *(UINT64 *)R7 will be the address of the new thunk.

+  //

+  case 5:

+    Offset            = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->R[7]);

+    U64EbcEntryPoint  = (UINT64) (VmPtr->R[7] + Offset + 4);

+    EbcEntryPoint     = (VOID *) (UINTN) U64EbcEntryPoint;

+

+    //

+    // Now create a new thunk

+    //

+    Status = EbcCreateThunks (VmPtr->ImageHandle, EbcEntryPoint, &Thunk, 0);

+

+    //

+    // Finally replace the EBC entry point memory with the thunk address

+    //

+    VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[7], (UINT64) (UINTN) Thunk);

+    break;

+

+  //

+  // Compiler setting version per value in R7

+  //

+  case 6:

+    VmPtr->CompilerVersion = (UINT32) VmPtr->R[7];

+    //

+    // Check compiler version against VM version?

+    //

+    break;

+

+  //

+  // Unhandled break code. Signal exception.

+  //

+  default:

+    EbcDebugSignalException (EXCEPT_EBC_BAD_BREAK, EXCEPTION_FLAG_FATAL, VmPtr);

+    break;

+  }

+  //

+  // Advance IP

+  //

+  VmPtr->Ip += 2;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteJMP (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the JMP instruction

+

+Arguments:

+  VmPtr      - pointer to VM context

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+  JMP64{cs|cc} Immed64

+  JMP32{cs|cc} {@}R1 {Immed32|Index32}

+

+Encoding:

+  b0.7 -  immediate data present

+  b0.6 -  1 = 64 bit immediate data

+          0 = 32 bit immediate data

+  b1.7 -  1 = conditional

+  b1.6    1 = CS (condition set)

+          0 = CC (condition clear)

+  b1.4    1 = relative address

+          0 = absolute address

+  b1.3    1 = operand1 indirect

+  b1.2-0  operand 1

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   CompareSet;

+  UINT8   ConditionFlag;

+  UINT8   Size;

+  UINT8   Operand;

+  UINT64  Data64;

+  INT32   Index32;

+  UINTN   Addr;

+

+  Operand = GETOPERANDS (VmPtr);

+  Opcode  = GETOPCODE (VmPtr);

+

+  //

+  // Get instruction length from the opcode. The upper two bits are used here

+  // to index into the length array.

+  //

+  Size = mJMPLen[(Opcode >> 6) & 0x03];

+

+  //

+  // Decode instruction conditions

+  // If we haven't met the condition, then simply advance the IP and return.

+  //

+  CompareSet    = (UINT8) ((Operand & JMP_M_CS) ? 1 : 0);

+  ConditionFlag = (UINT8) VMFLAG_ISSET (VmPtr, VMFLAGS_CC);

+  if (Operand & CONDITION_M_CONDITIONAL) {

+    if (CompareSet != ConditionFlag) {

+      VmPtr->Ip += Size;

+      return EFI_SUCCESS;

+    }

+  }

+  //

+  // Check for 64-bit form and do it right away since it's the most

+  // straight-forward form.

+  //

+  if (Opcode & OPCODE_M_IMMDATA64) {

+    //

+    // Double check for immediate-data, which is required. If not there,

+    // then signal an exception

+    //

+    if (!(Opcode & OPCODE_M_IMMDATA)) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_ERROR,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+    //

+    // 64-bit immediate data is full address. Read the immediate data,

+    // check for alignment, and jump absolute.

+    //

+    Data64 = VmReadImmed64 (VmPtr, 2);

+    if (!IS_ALIGNED ((UINTN) Data64, sizeof (UINT16))) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_ALIGNMENT_CHECK,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+

+      return EFI_UNSUPPORTED;

+    }

+

+    //

+    // Take jump -- relative or absolute

+    //

+    if (Operand & JMP_M_RELATIVE) {

+      VmPtr->Ip += (UINTN) Data64 + Size;

+    } else {

+      VmPtr->Ip = (VMIP) (UINTN) Data64;

+    }

+

+    return EFI_SUCCESS;

+  }

+  //

+  // 32-bit forms:

+  // Get the index if there is one. May be either an index, or an immediate

+  // offset depending on indirect operand.

+  //   JMP32 @R1 Index32 -- immediate data is an index

+  //   JMP32 R1 Immed32  -- immedate data is an offset

+  //

+  if (Opcode & OPCODE_M_IMMDATA) {

+    if (OPERAND1_INDIRECT (Operand)) {

+      Index32 = VmReadIndex32 (VmPtr, 2);

+    } else {

+      Index32 = VmReadImmed32 (VmPtr, 2);

+    }

+  } else {

+    Index32 = 0;

+  }

+  //

+  // Get the register data. If R == 0, then special case where it's ignored.

+  //

+  if (OPERAND1_REGNUM (Operand) == 0) {

+    Data64 = 0;

+  } else {

+    Data64 = OPERAND1_REGDATA (VmPtr, Operand);

+  }

+  //

+  // Decode the forms

+  //

+  if (OPERAND1_INDIRECT (Operand)) {

+    //

+    // Form: JMP32 @Rx {Index32}

+    //

+    Addr = VmReadMemN (VmPtr, (UINTN) Data64 + Index32);

+    if (!IS_ALIGNED ((UINTN) Addr, sizeof (UINT16))) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_ALIGNMENT_CHECK,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+

+      return EFI_UNSUPPORTED;

+    }

+

+    if (Operand & JMP_M_RELATIVE) {

+      VmPtr->Ip += (UINTN) Addr + Size;

+    } else {

+      VmPtr->Ip = (VMIP) Addr;

+    }

+  } else {

+    //

+    // Form: JMP32 Rx {Immed32}

+    //

+    Addr = (UINTN) (Data64 + Index32);

+    if (!IS_ALIGNED ((UINTN) Addr, sizeof (UINT16))) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_ALIGNMENT_CHECK,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+

+      return EFI_UNSUPPORTED;

+    }

+

+    if (Operand & JMP_M_RELATIVE) {

+      VmPtr->Ip += (UINTN) Addr + Size;

+    } else {

+      VmPtr->Ip = (VMIP) Addr;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteJMP8 (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC JMP8 instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+  JMP8{cs|cc}  Offset/2

+

+--*/

+{

+  UINT8 Opcode;

+  UINT8 ConditionFlag;

+  UINT8 CompareSet;

+  INT8  Offset;

+

+  //

+  // Decode instruction.

+  //

+  Opcode        = GETOPCODE (VmPtr);

+  CompareSet    = (UINT8) ((Opcode & JMP_M_CS) ? 1 : 0);

+  ConditionFlag = (UINT8) VMFLAG_ISSET (VmPtr, VMFLAGS_CC);

+

+  //

+  // If we haven't met the condition, then simply advance the IP and return

+  //

+  if (Opcode & CONDITION_M_CONDITIONAL) {

+    if (CompareSet != ConditionFlag) {

+      VmPtr->Ip += 2;

+      return EFI_SUCCESS;

+    }

+  }

+  //

+  // Get the offset from the instruction stream. It's relative to the

+  // following instruction, and divided by 2.

+  //

+  Offset = VmReadImmed8 (VmPtr, 1);

+  //

+  // Want to check for offset == -2 and then raise an exception?

+  //

+  VmPtr->Ip += (Offset * 2) + 2;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteMOVI (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC MOVI 

+

+Arguments:

+

+  VmPtr   - pointer to a VM context  

+

+Returns:

+

+  Standard EFI_STATUS

+

+Instruction syntax:

+

+  MOVI[b|w|d|q][w|d|q] {@}R1 {Index16}, ImmData16|32|64

+

+  First variable character specifies the move size

+  Second variable character specifies size of the immediate data

+

+  Sign-extend the immediate data to the size of the operation, and zero-extend

+  if storing to a register.

+

+  Operand1 direct with index/immed is invalid.

+    

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT16   Index16;

+  INT64   ImmData64;

+  UINT64  Op1;

+  UINT64  Mask64;

+

+  //

+  // Get the opcode and operands byte so we can get R1 and R2

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+

+  //

+  // Get the index (16-bit) if present

+  //

+  if (Operands & MOVI_M_IMMDATA) {

+    Index16 = VmReadIndex16 (VmPtr, 2);

+    Size    = 4;

+  } else {

+    Index16 = 0;

+    Size    = 2;

+  }

+  //

+  // Extract the immediate data. Sign-extend always.

+  //

+  if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {

+    ImmData64 = (INT64) (INT16) VmReadImmed16 (VmPtr, Size);

+    Size += 2;

+  } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {

+    ImmData64 = (INT64) (INT32) VmReadImmed32 (VmPtr, Size);

+    Size += 4;

+  } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {

+    ImmData64 = (INT64) VmReadImmed64 (VmPtr, Size);

+    Size += 8;

+  } else {

+    //

+    // Invalid encoding

+    //

+    EbcDebugSignalException (

+      EXCEPT_EBC_INSTRUCTION_ENCODING,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Now write back the result

+  //

+  if (!OPERAND1_INDIRECT (Operands)) {

+    //

+    // Operand1 direct. Make sure it didn't have an index.

+    //

+    if (Operands & MOVI_M_IMMDATA) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+    //

+    // Writing directly to a register. Clear unused bits.

+    //

+    if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH8) {

+      Mask64 = 0x000000FF;

+    } else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH16) {

+      Mask64 = 0x0000FFFF;

+    } else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH32) {

+      Mask64 = 0x00000000FFFFFFFF;

+    } else {

+      Mask64 = (UINT64)~0;

+    }

+

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = ImmData64 & Mask64;

+  } else {

+    //

+    // Get the address then write back based on size of the move

+    //

+    Op1 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;

+    if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH8) {

+      VmWriteMem8 (VmPtr, (UINTN) Op1, (UINT8) ImmData64);

+    } else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH16) {

+      VmWriteMem16 (VmPtr, (UINTN) Op1, (UINT16) ImmData64);

+    } else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH32) {

+      VmWriteMem32 (VmPtr, (UINTN) Op1, (UINT32) ImmData64);

+    } else {

+      VmWriteMem64 (VmPtr, (UINTN) Op1, ImmData64);

+    }

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteMOVIn (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC MOV immediate natural. This instruction moves an immediate

+  index value into a register or memory location.

+

+Arguments:

+

+  VmPtr   - pointer to a VM context  

+

+Returns:

+

+  Standard EFI_STATUS

+

+Instruction syntax:

+

+  MOVIn[w|d|q] {@}R1 {Index16}, Index16|32|64

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT16   Index16;

+  INT16   ImmedIndex16;

+  INT32   ImmedIndex32;

+  INT64   ImmedIndex64;

+  UINT64  Op1;

+

+  //

+  // Get the opcode and operands byte so we can get R1 and R2

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+

+  //

+  // Get the operand1 index (16-bit) if present

+  //

+  if (Operands & MOVI_M_IMMDATA) {

+    Index16 = VmReadIndex16 (VmPtr, 2);

+    Size    = 4;

+  } else {

+    Index16 = 0;

+    Size    = 2;

+  }

+  //

+  // Extract the immediate data and convert to a 64-bit index.

+  //

+  if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {

+    ImmedIndex16  = VmReadIndex16 (VmPtr, Size);

+    ImmedIndex64  = (INT64) ImmedIndex16;

+    Size += 2;

+  } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {

+    ImmedIndex32  = VmReadIndex32 (VmPtr, Size);

+    ImmedIndex64  = (INT64) ImmedIndex32;

+    Size += 4;

+  } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {

+    ImmedIndex64 = VmReadIndex64 (VmPtr, Size);

+    Size += 8;

+  } else {

+    //

+    // Invalid encoding

+    //

+    EbcDebugSignalException (

+      EXCEPT_EBC_INSTRUCTION_ENCODING,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Now write back the result

+  //

+  if (!OPERAND1_INDIRECT (Operands)) {

+    //

+    // Check for MOVIn R1 Index16, Immed (not indirect, with index), which

+    // is illegal

+    //

+    if (Operands & MOVI_M_IMMDATA) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = ImmedIndex64;

+  } else {

+    //

+    // Get the address

+    //

+    Op1 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;

+    VmWriteMemN (VmPtr, (UINTN) Op1, (INTN) ImmedIndex64);

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteMOVREL (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC MOVREL instruction.

+  Dest <- Ip + ImmData

+

+Arguments:

+

+  VmPtr   - pointer to a VM context  

+

+Returns:

+

+  Standard EFI_STATUS

+

+Instruction syntax:

+

+  MOVREL[w|d|q] {@}R1 {Index16}, ImmData16|32|64

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT16   Index16;

+  INT64   ImmData64;

+  UINT64  Op1;

+  UINT64  Op2;

+

+  //

+  // Get the opcode and operands byte so we can get R1 and R2

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+

+  //

+  // Get the Operand 1 index (16-bit) if present

+  //

+  if (Operands & MOVI_M_IMMDATA) {

+    Index16 = VmReadIndex16 (VmPtr, 2);

+    Size    = 4;

+  } else {

+    Index16 = 0;

+    Size    = 2;

+  }

+  //

+  // Get the immediate data.

+  //

+  if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {

+    ImmData64 = (INT64) VmReadImmed16 (VmPtr, Size);

+    Size += 2;

+  } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {

+    ImmData64 = (INT64) VmReadImmed32 (VmPtr, Size);

+    Size += 4;

+  } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {

+    ImmData64 = VmReadImmed64 (VmPtr, Size);

+    Size += 8;

+  } else {

+    //

+    // Invalid encoding

+    //

+    EbcDebugSignalException (

+      EXCEPT_EBC_INSTRUCTION_ENCODING,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Compute the value and write back the result

+  //

+  Op2 = (UINT64) ((INT64) ((UINT64) (UINTN) VmPtr->Ip) + (INT64) ImmData64 + Size);

+  if (!OPERAND1_INDIRECT (Operands)) {

+    //

+    // Check for illegal combination of operand1 direct with immediate data

+    //

+    if (Operands & MOVI_M_IMMDATA) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = (VM_REGISTER) Op2;

+  } else {

+    //

+    // Get the address = [Rx] + Index16

+    // Write back the result. Always a natural size write, since

+    // we're talking addresses here.

+    //

+    Op1 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;

+    VmWriteMemN (VmPtr, (UINTN) Op1, (UINTN) Op2);

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteMOVsnw (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC MOVsnw instruction. This instruction loads a signed 

+  natural value from memory or register to another memory or register. On

+  32-bit machines, the value gets sign-extended to 64 bits if the destination

+  is a register.

+

+Arguments:

+

+  VmPtr   - pointer to a VM context  

+

+Returns:

+

+  Standard EFI_STATUS

+

+Instruction syntax:

+

+  MOVsnw {@}R1 {Index16}, {@}R2 {Index16|Immed16}

+

+  0:7 1=>operand1 index present

+  0:6 1=>operand2 index present

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT16   Op1Index;

+  INT16   Op2Index;

+  UINT64  Op2;

+

+  //

+  // Get the opcode and operand bytes

+  //

+  Opcode              = GETOPCODE (VmPtr);

+  Operands            = GETOPERANDS (VmPtr);

+

+  Op1Index            = Op2Index = 0;

+

+  //

+  // Get the indexes if present.

+  //

+  Size = 2;

+  if (Opcode & OPCODE_M_IMMED_OP1) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Op1Index = VmReadIndex16 (VmPtr, 2);

+    } else {

+      //

+      // Illegal form operand1 direct with index:  MOVsnw R1 Index16, {@}R2

+      //

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+

+    Size += sizeof (UINT16);

+  }

+

+  if (Opcode & OPCODE_M_IMMED_OP2) {

+    if (OPERAND2_INDIRECT (Operands)) {

+      Op2Index = VmReadIndex16 (VmPtr, Size);

+    } else {

+      Op2Index = VmReadImmed16 (VmPtr, Size);

+    }

+

+    Size += sizeof (UINT16);

+  }

+  //

+  // Get the data from the source.

+  //

+  Op2 = (INT64) ((INTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Op2Index));

+  if (OPERAND2_INDIRECT (Operands)) {

+    Op2 = (INT64) (INTN) VmReadMemN (VmPtr, (UINTN) Op2);

+  }

+  //

+  // Now write back the result.

+  //

+  if (!OPERAND1_INDIRECT (Operands)) {

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = Op2;

+  } else {

+    VmWriteMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2);

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteMOVsnd (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC MOVsnw instruction. This instruction loads a signed 

+  natural value from memory or register to another memory or register. On

+  32-bit machines, the value gets sign-extended to 64 bits if the destination

+  is a register.

+

+Arguments:

+

+  VmPtr   - pointer to a VM context  

+

+Returns:

+

+  Standard EFI_STATUS

+

+Instruction syntax:

+

+  MOVsnd {@}R1 {Indx32}, {@}R2 {Index32|Immed32}

+

+  0:7 1=>operand1 index present

+  0:6 1=>operand2 index present

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT32   Op1Index;

+  INT32   Op2Index;

+  UINT64  Op2;

+

+  //

+  // Get the opcode and operand bytes

+  //

+  Opcode              = GETOPCODE (VmPtr);

+  Operands            = GETOPERANDS (VmPtr);

+

+  Op1Index            = Op2Index = 0;

+

+  //

+  // Get the indexes if present.

+  //

+  Size = 2;

+  if (Opcode & OPCODE_M_IMMED_OP1) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Op1Index = VmReadIndex32 (VmPtr, 2);

+    } else {

+      //

+      // Illegal form operand1 direct with index:  MOVsnd R1 Index16,..

+      //

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+      return EFI_UNSUPPORTED;

+    }

+

+    Size += sizeof (UINT32);

+  }

+

+  if (Opcode & OPCODE_M_IMMED_OP2) {

+    if (OPERAND2_INDIRECT (Operands)) {

+      Op2Index = VmReadIndex32 (VmPtr, Size);

+    } else {

+      Op2Index = VmReadImmed32 (VmPtr, Size);

+    }

+

+    Size += sizeof (UINT32);

+  }

+  //

+  // Get the data from the source.

+  //

+  Op2 = (INT64) ((INTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Op2Index));

+  if (OPERAND2_INDIRECT (Operands)) {

+    Op2 = (INT64) (INTN) VmReadMemN (VmPtr, (UINTN) Op2);

+  }

+  //

+  // Now write back the result.

+  //

+  if (!OPERAND1_INDIRECT (Operands)) {

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = Op2;

+  } else {

+    VmWriteMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2);

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecutePUSHn (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC PUSHn instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   PUSHn {@}R1 {Index16|Immed16}

+

+--*/

+{

+  UINT8 Opcode;

+  UINT8 Operands;

+  INT16 Index16;

+  UINTN DataN;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+

+  //

+  // Get index if present

+  //

+  if (Opcode & PUSHPOP_M_IMMDATA) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Index16 = VmReadIndex16 (VmPtr, 2);

+    } else {

+      Index16 = VmReadImmed16 (VmPtr, 2);

+    }

+

+    VmPtr->Ip += 4;

+  } else {

+    Index16 = 0;

+    VmPtr->Ip += 2;

+  }

+  //

+  // Get the data to push

+  //

+  if (OPERAND1_INDIRECT (Operands)) {

+    DataN = VmReadMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16));

+  } else {

+    DataN = (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16);

+  }

+  //

+  // Adjust the stack down.

+  //

+  VmPtr->R[0] -= sizeof (UINTN);

+  VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], DataN);

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecutePUSH (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC PUSH instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   PUSH[32|64] {@}R1 {Index16|Immed16}

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT32  Data32;

+  UINT64  Data64;

+  INT16   Index16;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+  //

+  // Get immediate index if present, then advance the IP.

+  //

+  if (Opcode & PUSHPOP_M_IMMDATA) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Index16 = VmReadIndex16 (VmPtr, 2);

+    } else {

+      Index16 = VmReadImmed16 (VmPtr, 2);

+    }

+

+    VmPtr->Ip += 4;

+  } else {

+    Index16 = 0;

+    VmPtr->Ip += 2;

+  }

+  //

+  // Get the data to push

+  //

+  if (Opcode & PUSHPOP_M_64) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Data64 = VmReadMem64 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16));

+    } else {

+      Data64 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;

+    }

+    //

+    // Adjust the stack down, then write back the data

+    //

+    VmPtr->R[0] -= sizeof (UINT64);

+    VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], Data64);

+  } else {

+    //

+    // 32-bit data

+    //

+    if (OPERAND1_INDIRECT (Operands)) {

+      Data32 = VmReadMem32 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16));

+    } else {

+      Data32 = (UINT32) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;

+    }

+    //

+    // Adjust the stack down and write the data

+    //

+    VmPtr->R[0] -= sizeof (UINT32);

+    VmWriteMem32 (VmPtr, (UINTN) VmPtr->R[0], Data32);

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecutePOPn (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC POPn instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   POPn {@}R1 {Index16|Immed16}

+

+--*/

+{

+  UINT8 Opcode;

+  UINT8 Operands;

+  INT16 Index16;

+  UINTN DataN;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+  //

+  // Get immediate data if present, and advance the IP

+  //

+  if (Opcode & PUSHPOP_M_IMMDATA) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Index16 = VmReadIndex16 (VmPtr, 2);

+    } else {

+      Index16 = VmReadImmed16 (VmPtr, 2);

+    }

+

+    VmPtr->Ip += 4;

+  } else {

+    Index16 = 0;

+    VmPtr->Ip += 2;

+  }

+  //

+  // Read the data off the stack, then adjust the stack pointer

+  //

+  DataN = VmReadMemN (VmPtr, (UINTN) VmPtr->R[0]);

+  VmPtr->R[0] += sizeof (UINTN);

+  //

+  // Do the write-back

+  //

+  if (OPERAND1_INDIRECT (Operands)) {

+    VmWriteMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16), DataN);

+  } else {

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = (INT64) (UINT64) ((UINTN) DataN + Index16);

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecutePOP (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC POP instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+  POP {@}R1 {Index16|Immed16}

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  INT16   Index16;

+  INT32   Data32;

+  UINT64  Data64;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+  //

+  // Get immediate data if present, and advance the IP.

+  //

+  if (Opcode & PUSHPOP_M_IMMDATA) {

+    if (OPERAND1_INDIRECT (Operands)) {

+      Index16 = VmReadIndex16 (VmPtr, 2);

+    } else {

+      Index16 = VmReadImmed16 (VmPtr, 2);

+    }

+

+    VmPtr->Ip += 4;

+  } else {

+    Index16 = 0;

+    VmPtr->Ip += 2;

+  }

+  //

+  // Get the data off the stack, then write it to the appropriate location

+  //

+  if (Opcode & PUSHPOP_M_64) {

+    //

+    // Read the data off the stack, then adjust the stack pointer

+    //

+    Data64 = VmReadMem64 (VmPtr, (UINTN) VmPtr->R[0]);

+    VmPtr->R[0] += sizeof (UINT64);

+    //

+    // Do the write-back

+    //

+    if (OPERAND1_INDIRECT (Operands)) {

+      VmWriteMem64 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16), Data64);

+    } else {

+      VmPtr->R[OPERAND1_REGNUM (Operands)] = Data64 + Index16;

+    }

+  } else {

+    //

+    // 32-bit pop. Read it off the stack and adjust the stack pointer

+    //

+    Data32 = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->R[0]);

+    VmPtr->R[0] += sizeof (UINT32);

+    //

+    // Do the write-back

+    //

+    if (OPERAND1_INDIRECT (Operands)) {

+      VmWriteMem32 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16), Data32);

+    } else {

+      VmPtr->R[OPERAND1_REGNUM (Operands)] = (INT64) Data32 + Index16;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteCALL (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Implements the EBC CALL instruction.

+

+  Instruction format:  

+

+    CALL64 Immed64

+    CALL32 {@}R1 {Immed32|Index32}

+    CALLEX64 Immed64

+    CALLEX16 {@}R1 {Immed32}

+

+  If Rx == R0, then it's a PC relative call to PC = PC + imm32.

+  

+Arguments:

+  VmPtr - pointer to a VM context.

+

+Returns:

+  Standard EFI_STATUS

+

+--*/

+{

+  UINT8 Opcode;

+  UINT8 Operands;

+  INT32 Immed32;

+  UINT8 Size;

+  INT64 Immed64;

+  VOID  *FramePtr;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+  //

+  // Assign these as well to avoid compiler warnings

+  //

+  Immed64   = 0;

+  Immed32   = 0;

+

+  FramePtr  = VmPtr->FramePtr;

+  //

+  // Determine the instruction size, and get immediate data if present

+  //

+  if (Opcode & OPCODE_M_IMMDATA) {

+    if (Opcode & OPCODE_M_IMMDATA64) {

+      Immed64 = VmReadImmed64 (VmPtr, 2);

+      Size    = 10;

+    } else {

+      //

+      // If register operand is indirect, then the immediate data is an index

+      //

+      if (OPERAND1_INDIRECT (Operands)) {

+        Immed32 = VmReadIndex32 (VmPtr, 2);

+      } else {

+        Immed32 = VmReadImmed32 (VmPtr, 2);

+      }

+

+      Size = 6;

+    }

+  } else {

+    Size = 2;

+  }

+  //

+  // If it's a call to EBC, adjust the stack pointer down 16 bytes and

+  // put our return address and frame pointer on the VM stack.

+  //

+  if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {

+    VmPtr->R[0] -= 8;

+    VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);

+    VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];

+    VmPtr->R[0] -= 8;

+    VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (UINTN) (VmPtr->Ip + Size));

+  }

+  //

+  // If 64-bit data, then absolute jump only

+  //

+  if (Opcode & OPCODE_M_IMMDATA64) {

+    //

+    // Native or EBC call?

+    //

+    if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {

+      VmPtr->Ip = (VMIP) (UINTN) Immed64;

+    } else {

+      //

+      // Call external function, get the return value, and advance the IP

+      //

+      EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN) VmPtr->R[0], FramePtr, Size);

+    }

+  } else {

+    //

+    // Get the register data. If operand1 == 0, then ignore register and

+    // take immediate data as relative or absolute address.

+    // Compiler should take care of upper bits if 32-bit machine.

+    //

+    if (OPERAND1_REGNUM (Operands) != 0) {

+      Immed64 = (UINT64) (UINTN) VmPtr->R[OPERAND1_REGNUM (Operands)];

+    }

+    //

+    // Get final address

+    //

+    if (OPERAND1_INDIRECT (Operands)) {

+      Immed64 = (INT64) (UINT64) (UINTN) VmReadMemN (VmPtr, (UINTN) (Immed64 + Immed32));

+    } else {

+      Immed64 += Immed32;

+    }

+    //

+    // Now determine if external call, and then if relative or absolute

+    //

+    if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {

+      //

+      // EBC call. Relative or absolute? If relative, then it's relative to the

+      // start of the next instruction.

+      //

+      if (Operands & OPERAND_M_RELATIVE_ADDR) {

+        VmPtr->Ip += Immed64 + Size;

+      } else {

+        VmPtr->Ip = (VMIP) (UINTN) Immed64;

+      }

+    } else {

+      //

+      // Native call. Relative or absolute?

+      //

+      if (Operands & OPERAND_M_RELATIVE_ADDR) {

+        EbcLLCALLEX (VmPtr, (UINTN) (Immed64 + VmPtr->Ip + Size), (UINTN) VmPtr->R[0], FramePtr, Size);

+      } else {

+        if (VmPtr->StopFlags & STOPFLAG_BREAK_ON_CALLEX) {

+          CpuBreakpoint ();

+        }

+

+        EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN) VmPtr->R[0], FramePtr, Size);

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteRET (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC RET instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   RET

+

+--*/

+{

+  //

+  // If we're at the top of the stack, then simply set the done

+  // flag and return

+  //

+  if (VmPtr->StackRetAddr == (UINT64) VmPtr->R[0]) {

+    VmPtr->StopFlags |= STOPFLAG_APP_DONE;

+  } else {

+    //

+    // Pull the return address off the VM app's stack and set the IP

+    // to it

+    //

+    if (!IS_ALIGNED ((UINTN) VmPtr->R[0], sizeof (UINT16))) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_ALIGNMENT_CHECK,

+        EXCEPTION_FLAG_FATAL,

+        VmPtr

+        );

+    }

+    //

+    // Restore the IP and frame pointer from the stack

+    //

+    VmPtr->Ip = (VMIP) (UINTN) VmReadMem64 (VmPtr, (UINTN) VmPtr->R[0]);

+    VmPtr->R[0] += 8;

+    VmPtr->FramePtr = (VOID *) VmReadMemN (VmPtr, (UINTN) VmPtr->R[0]);

+    VmPtr->R[0] += 8;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteCMP (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC CMP instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   CMP[32|64][eq|lte|gte|ulte|ugte] R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT16   Index16;

+  UINT32  Flag;

+  INT64   Op2;

+  INT64   Op1;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+  //

+  // Get the register data we're going to compare to

+  //

+  Op1 = VmPtr->R[OPERAND1_REGNUM (Operands)];

+  //

+  // Get immediate data

+  //

+  if (Opcode & OPCODE_M_IMMDATA) {

+    if (OPERAND2_INDIRECT (Operands)) {

+      Index16 = VmReadIndex16 (VmPtr, 2);

+    } else {

+      Index16 = VmReadImmed16 (VmPtr, 2);

+    }

+

+    Size = 4;

+  } else {

+    Index16 = 0;

+    Size    = 2;

+  }

+  //

+  // Now get Op2

+  //

+  if (OPERAND2_INDIRECT (Operands)) {

+    if (Opcode & OPCODE_M_64BIT) {

+      Op2 = (INT64) VmReadMem64 (VmPtr, (UINTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16));

+    } else {

+      //

+      // 32-bit operations. 0-extend the values for all cases.

+      //

+      Op2 = (INT64) (UINT64) ((UINT32) VmReadMem32 (VmPtr, (UINTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16)));

+    }

+  } else {

+    Op2 = VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16;

+  }

+  //

+  // Now do the compare

+  //

+  Flag = 0;

+  if (Opcode & OPCODE_M_64BIT) {

+    //

+    // 64-bit compares

+    //

+    switch (Opcode & OPCODE_M_OPCODE) {

+    case OPCODE_CMPEQ:

+      if (Op1 == Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPLTE:

+      if (Op1 <= Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPGTE:

+      if (Op1 >= Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPULTE:

+      if ((UINT64) Op1 <= (UINT64) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPUGTE:

+      if ((UINT64) Op1 >= (UINT64) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    default:

+      ASSERT (0);

+    }

+  } else {

+    //

+    // 32-bit compares

+    //

+    switch (Opcode & OPCODE_M_OPCODE) {

+    case OPCODE_CMPEQ:

+      if ((INT32) Op1 == (INT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPLTE:

+      if ((INT32) Op1 <= (INT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPGTE:

+      if ((INT32) Op1 >= (INT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPULTE:

+      if ((UINT32) Op1 <= (UINT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPUGTE:

+      if ((UINT32) Op1 >= (UINT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    default:

+      ASSERT (0);

+    }

+  }

+  //

+  // Now set the flag accordingly for the comparison

+  //

+  if (Flag) {

+    VMFLAG_SET (VmPtr, VMFLAGS_CC);

+  } else {

+    VMFLAG_CLEAR (VmPtr, VMFLAGS_CC);

+  }

+  //

+  // Advance the IP

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteCMPI (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC CMPI instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   CMPI[32|64]{w|d}[eq|lte|gte|ulte|ugte] {@}Rx {Index16}, Immed16|Immed32

+

+--*/

+{

+  UINT8   Opcode;

+  UINT8   Operands;

+  UINT8   Size;

+  INT64   Op1;

+  INT64   Op2;

+  INT16   Index16;

+  UINT32  Flag;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+

+  //

+  // Get operand1 index if present

+  //

+  Size = 2;

+  if (Operands & OPERAND_M_CMPI_INDEX) {

+    Index16 = VmReadIndex16 (VmPtr, 2);

+    Size += 2;

+  } else {

+    Index16 = 0;

+  }

+  //

+  // Get operand1 data we're going to compare to

+  //

+  Op1 = (INT64) VmPtr->R[OPERAND1_REGNUM (Operands)];

+  if (OPERAND1_INDIRECT (Operands)) {

+    //

+    // Indirect operand1. Fetch 32 or 64-bit value based on compare size.

+    //

+    if (Opcode & OPCODE_M_CMPI64) {

+      Op1 = (INT64) VmReadMem64 (VmPtr, (UINTN) Op1 + Index16);

+    } else {

+      Op1 = (INT64) VmReadMem32 (VmPtr, (UINTN) Op1 + Index16);

+    }

+  } else {

+    //

+    // Better not have been an index with direct. That is, CMPI R1 Index,...

+    // is illegal.

+    //

+    if (Operands & OPERAND_M_CMPI_INDEX) {

+      EbcDebugSignalException (

+        EXCEPT_EBC_INSTRUCTION_ENCODING,

+        EXCEPTION_FLAG_ERROR,

+        VmPtr

+        );

+      VmPtr->Ip += Size;

+      return EFI_UNSUPPORTED;

+    }

+  }

+  //

+  // Get immediate data -- 16- or 32-bit sign extended

+  //

+  if (Opcode & OPCODE_M_CMPI32_DATA) {

+    Op2 = (INT64) VmReadImmed32 (VmPtr, Size);

+    Size += 4;

+  } else {

+    //

+    // 16-bit immediate data. Sign extend always.

+    //

+    Op2 = (INT64) ((INT16) VmReadImmed16 (VmPtr, Size));

+    Size += 2;

+  }

+  //

+  // Now do the compare

+  //

+  Flag = 0;

+  if (Opcode & OPCODE_M_CMPI64) {

+    //

+    // 64 bit comparison

+    //

+    switch (Opcode & OPCODE_M_OPCODE) {

+    case OPCODE_CMPIEQ:

+      if (Op1 == (INT64) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPILTE:

+      if (Op1 <= (INT64) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPIGTE:

+      if (Op1 >= (INT64) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPIULTE:

+      if ((UINT64) Op1 <= (UINT64) ((UINT32) Op2)) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPIUGTE:

+      if ((UINT64) Op1 >= (UINT64) ((UINT32) Op2)) {

+        Flag = 1;

+      }

+      break;

+

+    default:

+      ASSERT (0);

+    }

+  } else {

+    //

+    // 32-bit comparisons

+    //

+    switch (Opcode & OPCODE_M_OPCODE) {

+    case OPCODE_CMPIEQ:

+      if ((INT32) Op1 == Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPILTE:

+      if ((INT32) Op1 <= Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPIGTE:

+      if ((INT32) Op1 >= Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPIULTE:

+      if ((UINT32) Op1 <= (UINT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    case OPCODE_CMPIUGTE:

+      if ((UINT32) Op1 >= (UINT32) Op2) {

+        Flag = 1;

+      }

+      break;

+

+    default:

+      ASSERT (0);

+    }

+  }

+  //

+  // Now set the flag accordingly for the comparison

+  //

+  if (Flag) {

+    VMFLAG_SET (VmPtr, VMFLAGS_CC);

+  } else {

+    VMFLAG_CLEAR (VmPtr, VMFLAGS_CC);

+  }

+  //

+  // Advance the IP

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+UINT64

+ExecuteNOT (

+  IN VM_CONTEXT     *VmPtr,

+  IN UINT64         Op1,

+  IN UINT64         Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC NOT instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  ~Op2

+

+Instruction syntax:

+  NOT[32|64] {@}R1, {@}R2 {Index16|Immed16}

+  

+--*/

+{

+  return ~Op2;

+}

+

+STATIC

+UINT64

+ExecuteNEG (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC NEG instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op2 * -1

+

+Instruction syntax:

+  NEG[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  return ~Op2 + 1;

+}

+

+STATIC

+UINT64

+ExecuteADD (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC ADD instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 + Op2

+

+Instruction syntax:

+   ADD[32|64] {@}R1, {@}R2 {Index16}

+

+--*/

+{

+  return Op1 + Op2;

+}

+

+STATIC

+UINT64

+ExecuteSUB (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC SUB instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 - Op2

+  Standard EFI_STATUS

+

+Instruction syntax:

+  SUB[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  if (*VmPtr->Ip & DATAMANIP_M_64) {

+    return (UINT64) ((INT64) ((INT64) Op1 - (INT64) Op2));

+  } else {

+    return (UINT64) ((INT64) ((INT32) Op1 - (INT32) Op2));

+  }

+}

+

+STATIC

+UINT64

+ExecuteMUL (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC MUL instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 * Op2

+

+Instruction syntax:

+  MUL[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  INT64 ResultHigh;

+

+  if (*VmPtr->Ip & DATAMANIP_M_64) {

+    return MulS64x64 (Op1, Op2, &ResultHigh);

+  } else {

+    return (UINT64) ((INT64) ((INT32) Op1 * (INT32) Op2));

+  }

+}

+

+STATIC

+UINT64

+ExecuteMULU (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC MULU instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  (unsigned)Op1 * (unsigned)Op2 

+

+Instruction syntax:

+  MULU[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  INT64 ResultHigh;

+  if (*VmPtr->Ip & DATAMANIP_M_64) {

+    return MulU64x64 (Op1, Op2, (UINT64 *)&ResultHigh);

+  } else {

+    return (UINT64) ((UINT32) Op1 * (UINT32) Op2);

+  }

+}

+

+STATIC

+UINT64

+ExecuteDIV (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC DIV instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1/Op2

+

+Instruction syntax:

+  DIV[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  INT64   Remainder;

+  UINT32  Error;

+

+  //

+  // Check for divide-by-0

+  //

+  if (Op2 == 0) {

+    EbcDebugSignalException (

+      EXCEPT_EBC_DIVIDE_ERROR,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+

+    return 0;

+  } else {

+    if (*VmPtr->Ip & DATAMANIP_M_64) {

+      return (UINT64) (DivS64x64 (Op1, Op2, &Remainder, &Error));

+    } else {

+      return (UINT64) ((INT64) ((INT32) Op1 / (INT32) Op2));

+    }

+  }

+}

+

+STATIC

+UINT64

+ExecuteDIVU (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC DIVU instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  (unsigned)Op1 / (unsigned)Op2

+

+Instruction syntax:

+  DIVU[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  UINT64  Remainder;

+  UINT32  Error;

+

+  //

+  // Check for divide-by-0

+  //

+  if (Op2 == 0) {

+    EbcDebugSignalException (

+      EXCEPT_EBC_DIVIDE_ERROR,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+    return 0;

+  } else {

+    //

+    // Get the destination register

+    //

+    if (*VmPtr->Ip & DATAMANIP_M_64) {

+      return (UINT64) (DivU64x64 (Op1, Op2, &Remainder, &Error));

+    } else {

+      return (UINT64) ((UINT32) Op1 / (UINT32) Op2);

+    }

+  }

+}

+

+STATIC

+UINT64

+ExecuteMOD (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC MOD instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 MODULUS Op2

+

+Instruction syntax:

+  MOD[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  INT64   Remainder;

+  UINT32  Error;

+

+  //

+  // Check for divide-by-0

+  //

+  if (Op2 == 0) {

+    EbcDebugSignalException (

+      EXCEPT_EBC_DIVIDE_ERROR,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+    return 0;

+  } else {

+    DivS64x64 ((INT64) Op1, (INT64) Op2, &Remainder, &Error);

+    return Remainder;

+  }

+}

+

+STATIC

+UINT64

+ExecuteMODU (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC MODU instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 UNSIGNED_MODULUS Op2

+

+Instruction syntax:

+  MODU[32|64] {@}R1, {@}R2 {Index16|Immed16}

+  

+--*/

+{

+  UINT64  Remainder;

+  UINT32  Error;

+

+  //

+  // Check for divide-by-0

+  //

+  if (Op2 == 0) {

+    EbcDebugSignalException (

+      EXCEPT_EBC_DIVIDE_ERROR,

+      EXCEPTION_FLAG_FATAL,

+      VmPtr

+      );

+    return 0;

+  } else {

+    DivU64x64 (Op1, Op2, &Remainder, &Error);

+    return Remainder;

+  }

+}

+

+STATIC

+UINT64

+ExecuteAND (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC AND instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 AND Op2

+

+Instruction syntax:

+  AND[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  return Op1 & Op2;

+}

+

+STATIC

+UINT64

+ExecuteOR (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC OR instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 OR Op2

+

+Instruction syntax:

+  OR[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  return Op1 | Op2;

+}

+

+STATIC

+UINT64

+ExecuteXOR (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC XOR instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 XOR Op2

+

+Instruction syntax:

+  XOR[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  return Op1 ^ Op2;

+}

+

+STATIC

+UINT64

+ExecuteSHL (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  

+  Execute the EBC SHL shift left instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 << Op2

+

+Instruction syntax:

+  SHL[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  if (*VmPtr->Ip & DATAMANIP_M_64) {

+    return LeftShiftU64 (Op1, Op2);

+  } else {

+    return (UINT64) ((UINT32) ((UINT32) Op1 << (UINT32) Op2));

+  }

+}

+

+STATIC

+UINT64

+ExecuteSHR (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC SHR instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 >> Op2  (unsigned operands)

+

+Instruction syntax:

+  SHR[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  if (*VmPtr->Ip & DATAMANIP_M_64) {

+    return RightShiftU64 (Op1, Op2);

+  } else {

+    return (UINT64) ((UINT32) Op1 >> (UINT32) Op2);

+  }

+}

+

+STATIC

+UINT64

+ExecuteASHR (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC ASHR instruction

+

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  Op1 >> Op2 (signed)

+

+Instruction syntax:

+  ASHR[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+--*/

+{

+  if (*VmPtr->Ip & DATAMANIP_M_64) {

+    return ARightShift64 (Op1, Op2);

+  } else {

+    return (UINT64) ((INT64) ((INT32) Op1 >> (UINT32) Op2));

+  }

+}

+

+STATIC

+UINT64

+ExecuteEXTNDB (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC EXTNDB instruction to sign-extend a byte value.

+  

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  (INT64)(INT8)Op2

+

+Instruction syntax:

+  EXTNDB[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+  

+--*/

+{

+  INT8  Data8;

+  INT64 Data64;

+  //

+  // Convert to byte, then return as 64-bit signed value to let compiler

+  // sign-extend the value

+  //

+  Data8   = (INT8) Op2;

+  Data64  = (INT64) Data8;

+

+  return (UINT64) Data64;

+}

+

+STATIC

+UINT64

+ExecuteEXTNDW (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC EXTNDW instruction to sign-extend a 16-bit value.

+  

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  (INT64)(INT16)Op2

+

+Instruction syntax:

+  EXTNDW[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+  

+--*/

+{

+  INT16 Data16;

+  INT64 Data64;

+  //

+  // Convert to word, then return as 64-bit signed value to let compiler

+  // sign-extend the value

+  //

+  Data16  = (INT16) Op2;

+  Data64  = (INT64) Data16;

+

+  return (UINT64) Data64;

+}

+//

+// Execute the EBC EXTNDD instruction.

+//

+// Format: EXTNDD {@}Rx, {@}Ry [Index16|Immed16]

+//         EXTNDD Dest, Source

+//

+// Operation:  Dest <- SignExtended((DWORD)Source))

+//

+STATIC

+UINT64

+ExecuteEXTNDD (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINT64       Op1,

+  IN UINT64       Op2

+  )

+/*++

+

+Routine Description:

+  Execute the EBC EXTNDD instruction to sign-extend a 32-bit value.

+  

+Arguments:

+  VmPtr     - pointer to a VM context  

+  Op1       - Operand 1 from the instruction 

+  Op2       - Operand 2 from the instruction

+

+Returns:

+  (INT64)(INT32)Op2

+

+Instruction syntax:

+  EXTNDD[32|64] {@}R1, {@}R2 {Index16|Immed16}

+

+  

+--*/

+{

+  INT32 Data32;

+  INT64 Data64;

+  //

+  // Convert to 32-bit value, then return as 64-bit signed value to let compiler

+  // sign-extend the value

+  //

+  Data32  = (INT32) Op2;

+  Data64  = (INT64) Data32;

+

+  return (UINT64) Data64;

+}

+

+STATIC

+EFI_STATUS

+ExecuteSignedDataManip (

+  IN VM_CONTEXT   *VmPtr

+  )

+{

+  //

+  // Just call the data manipulation function with a flag indicating this

+  // is a signed operation.

+  //

+  return ExecuteDataManip (VmPtr, TRUE);

+}

+

+STATIC

+EFI_STATUS

+ExecuteUnsignedDataManip (

+  IN VM_CONTEXT   *VmPtr

+  )

+{

+  //

+  // Just call the data manipulation function with a flag indicating this

+  // is not a signed operation.

+  //

+  return ExecuteDataManip (VmPtr, FALSE);

+}

+

+STATIC

+EFI_STATUS

+ExecuteDataManip (

+  IN VM_CONTEXT   *VmPtr,

+  IN BOOLEAN      IsSignedOp

+  )

+/*++

+

+Routine Description:

+  Execute all the EBC data manipulation instructions. 

+  Since the EBC data manipulation instructions all have the same basic form, 

+  they can share the code that does the fetch of operands and the write-back

+  of the result. This function performs the fetch of the operands (even if

+  both are not needed to be fetched, like NOT instruction), dispatches to the

+  appropriate subfunction, then writes back the returned result.

+

+Arguments:

+  VmPtr - pointer to VM context

+

+Returns:

+  Standard EBC status

+

+Format:  

+  INSTRUCITON[32|64] {@}R1, {@}R2 {Immed16|Index16}

+

+--*/

+{

+  UINT8   Opcode;

+  INT16   Index16;

+  UINT8   Operands;

+  UINT8   Size;

+  UINT64  Op1;

+  UINT64  Op2;

+

+  //

+  // Get opcode and operands

+  //

+  Opcode    = GETOPCODE (VmPtr);

+  Operands  = GETOPERANDS (VmPtr);

+

+  //

+  // Determine if we have immediate data by the opcode

+  //

+  if (Opcode & DATAMANIP_M_IMMDATA) {

+    //

+    // Index16 if Ry is indirect, or Immed16 if Ry direct.

+    //

+    if (OPERAND2_INDIRECT (Operands)) {

+      Index16 = VmReadIndex16 (VmPtr, 2);

+    } else {

+      Index16 = VmReadImmed16 (VmPtr, 2);

+    }

+

+    Size = 4;

+  } else {

+    Index16 = 0;

+    Size    = 2;

+  }

+  //

+  // Now get operand2 (source). It's of format {@}R2 {Index16|Immed16}

+  //

+  Op2 = (UINT64) VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16;

+  if (OPERAND2_INDIRECT (Operands)) {

+    //

+    // Indirect form: @R2 Index16. Fetch as 32- or 64-bit data

+    //

+    if (Opcode & DATAMANIP_M_64) {

+      Op2 = VmReadMem64 (VmPtr, (UINTN) Op2);

+    } else {

+      //

+      // Read as signed value where appropriate.

+      //

+      if (IsSignedOp) {

+        Op2 = (UINT64) (INT64) ((INT32) VmReadMem32 (VmPtr, (UINTN) Op2));

+      } else {

+        Op2 = (UINT64) VmReadMem32 (VmPtr, (UINTN) Op2);

+      }

+    }

+  } else {

+    if ((Opcode & DATAMANIP_M_64) == 0) {

+      if (IsSignedOp) {

+        Op2 = (UINT64) (INT64) ((INT32) Op2);

+      } else {

+        Op2 = (UINT64) ((UINT32) Op2);

+      }

+    }

+  }

+  //

+  // Get operand1 (destination and sometimes also an actual operand)

+  // of form {@}R1

+  //

+  Op1 = VmPtr->R[OPERAND1_REGNUM (Operands)];

+  if (OPERAND1_INDIRECT (Operands)) {

+    if (Opcode & DATAMANIP_M_64) {

+      Op1 = VmReadMem64 (VmPtr, (UINTN) Op1);

+    } else {

+      if (IsSignedOp) {

+        Op1 = (UINT64) (INT64) ((INT32) VmReadMem32 (VmPtr, (UINTN) Op1));

+      } else {

+        Op1 = (UINT64) VmReadMem32 (VmPtr, (UINTN) Op1);

+      }

+    }

+  } else {

+    if ((Opcode & DATAMANIP_M_64) == 0) {

+      if (IsSignedOp) {

+        Op1 = (UINT64) (INT64) ((INT32) Op1);

+      } else {

+        Op1 = (UINT64) ((UINT32) Op1);

+      }

+    }

+  }

+  //

+  // Dispatch to the computation function

+  //

+  if (((Opcode & OPCODE_M_OPCODE) - OPCODE_NOT) >=

+        (sizeof (mDataManipDispatchTable) / sizeof (mDataManipDispatchTable[0]))

+        ) {

+    EbcDebugSignalException (

+      EXCEPT_EBC_INVALID_OPCODE,

+      EXCEPTION_FLAG_ERROR,

+      VmPtr

+      );

+    //

+    // Advance and return

+    //

+    VmPtr->Ip += Size;

+    return EFI_UNSUPPORTED;

+  } else {

+    Op2 = mDataManipDispatchTable[(Opcode & OPCODE_M_OPCODE) - OPCODE_NOT](VmPtr, Op1, Op2);

+  }

+  //

+  // Write back the result.

+  //

+  if (OPERAND1_INDIRECT (Operands)) {

+    Op1 = VmPtr->R[OPERAND1_REGNUM (Operands)];

+    if (Opcode & DATAMANIP_M_64) {

+      VmWriteMem64 (VmPtr, (UINTN) Op1, Op2);

+    } else {

+      VmWriteMem32 (VmPtr, (UINTN) Op1, (UINT32) Op2);

+    }

+  } else {

+    //

+    // Storage back to a register. Write back, clearing upper bits (as per

+    // the specification) if 32-bit operation.

+    //

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = Op2;

+    if ((Opcode & DATAMANIP_M_64) == 0) {

+      VmPtr->R[OPERAND1_REGNUM (Operands)] &= 0xFFFFFFFF;

+    }

+  }

+  //

+  // Advance the instruction pointer

+  //

+  VmPtr->Ip += Size;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteLOADSP (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC LOADSP instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+  LOADSP  SP1, R2

+

+--*/

+{

+  UINT8 Operands;

+

+  //

+  // Get the operands

+  //

+  Operands = GETOPERANDS (VmPtr);

+

+  //

+  // Do the operation

+  //

+  switch (OPERAND1_REGNUM (Operands)) {

+  //

+  // Set flags

+  //

+  case 0:

+    //

+    // Spec states that this instruction will not modify reserved bits in

+    // the flags register.

+    //

+    VmPtr->Flags = (VmPtr->Flags &~VMFLAGS_ALL_VALID) | (VmPtr->R[OPERAND2_REGNUM (Operands)] & VMFLAGS_ALL_VALID);

+    break;

+

+  default:

+    EbcDebugSignalException (

+      EXCEPT_EBC_INSTRUCTION_ENCODING,

+      EXCEPTION_FLAG_WARNING,

+      VmPtr

+      );

+    VmPtr->Ip += 2;

+    return EFI_UNSUPPORTED;

+  }

+

+  VmPtr->Ip += 2;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+ExecuteSTORESP (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+  Execute the EBC STORESP instruction

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+

+Returns:

+  Standard EFI_STATUS

+

+Instruction syntax:

+   STORESP  Rx, FLAGS|IP

+

+--*/

+{

+  UINT8 Operands;

+

+  //

+  // Get the operands

+  //

+  Operands = GETOPERANDS (VmPtr);

+

+  //

+  // Do the operation

+  //

+  switch (OPERAND2_REGNUM (Operands)) {

+  //

+  // Get flags

+  //

+  case 0:

+    //

+    // Retrieve the value in the flags register, then clear reserved bits

+    //

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = (UINT64) (VmPtr->Flags & VMFLAGS_ALL_VALID);

+    break;

+

+  //

+  // Get IP -- address of following instruction

+  //

+  case 1:

+    VmPtr->R[OPERAND1_REGNUM (Operands)] = (UINT64) (UINTN) VmPtr->Ip + 2;

+    break;

+

+  default:

+    EbcDebugSignalException (

+      EXCEPT_EBC_INSTRUCTION_ENCODING,

+      EXCEPTION_FLAG_WARNING,

+      VmPtr

+      );

+    VmPtr->Ip += 2;

+    return EFI_UNSUPPORTED;

+    break;

+  }

+

+  VmPtr->Ip += 2;

+  return EFI_SUCCESS;

+}

+

+STATIC

+INT16

+VmReadIndex16 (

+  IN VM_CONTEXT     *VmPtr,

+  IN UINT32         CodeOffset

+  )

+/*++

+

+Routine Description:

+  Decode a 16-bit index to determine the offset. Given an index value:

+

+    b15     - sign bit

+    b14:12  - number of bits in this index assigned to natural units (=a)

+    ba:11   - constant units = C

+    b0:a    - natural units = N

+  

+  Given this info, the offset can be computed by:

+    offset = sign_bit * (C + N * sizeof(UINTN))

+

+  Max offset is achieved with index = 0x7FFF giving an offset of

+  0x27B (32-bit machine) or 0x477 (64-bit machine).

+  Min offset is achieved with index = 

+  

+Arguments:

+  VmPtr       - pointer to VM context

+  CodeOffset  - offset from IP of the location of the 16-bit index to decode

+

+Returns:

+  The decoded offset.

+  

+--*/

+{

+  UINT16  Index;

+  INT16   Offset;

+  INT16   C;

+  INT16   N;

+  INT16   NBits;

+  INT16   Mask;

+

+  //

+  // First read the index from the code stream

+  //

+  Index = VmReadCode16 (VmPtr, CodeOffset);

+

+  //

+  // Get the mask for N. First get the number of bits from the index.

+  //

+  NBits = (INT16) ((Index & 0x7000) >> 12);

+

+  //

+  // Scale it for 16-bit indexes

+  //

+  NBits *= 2;

+

+  //

+  // Now using the number of bits, create a mask.

+  //

+  Mask = (INT16) ((INT16)~0 << NBits);

+

+  //

+  // Now using the mask, extract N from the lower bits of the index.

+  //

+  N = (INT16) (Index &~Mask);

+

+  //

+  // Now compute C

+  //

+  C       = (INT16) (((Index &~0xF000) & Mask) >> NBits);

+

+  Offset  = (INT16) (N * sizeof (UINTN) + C);

+

+  //

+  // Now set the sign

+  //

+  if (Index & 0x8000) {

+    //

+    // Do it the hard way to work around a bogus compiler warning

+    //

+    // Offset = -1 * Offset;

+    //

+    Offset = (INT16) ((INT32) Offset * -1);

+  }

+

+  return Offset;

+}

+

+STATIC

+INT32

+VmReadIndex32 (

+  IN VM_CONTEXT     *VmPtr,

+  IN UINT32         CodeOffset

+  )

+/*++

+

+Routine Description:

+  Decode a 32-bit index to determine the offset.

+

+Arguments:

+  VmPtr       - pointer to VM context

+  CodeOffset  - offset from IP of the location of the 32-bit index to decode

+

+Returns:

+  Converted index per EBC VM specification

+

+--*/

+{

+  UINT32  Index;

+  INT32   Offset;

+  INT32   C;

+  INT32   N;

+  INT32   NBits;

+  INT32   Mask;

+

+  Index = VmReadImmed32 (VmPtr, CodeOffset);

+

+  //

+  // Get the mask for N. First get the number of bits from the index.

+  //

+  NBits = (Index & 0x70000000) >> 28;

+

+  //

+  // Scale it for 32-bit indexes

+  //

+  NBits *= 4;

+

+  //

+  // Now using the number of bits, create a mask.

+  //

+  Mask = (INT32)~0 << NBits;

+

+  //

+  // Now using the mask, extract N from the lower bits of the index.

+  //

+  N = Index &~Mask;

+

+  //

+  // Now compute C

+  //

+  C       = ((Index &~0xF0000000) & Mask) >> NBits;

+

+  Offset  = N * sizeof (UINTN) + C;

+

+  //

+  // Now set the sign

+  //

+  if (Index & 0x80000000) {

+    Offset = Offset * -1;

+  }

+

+  return Offset;

+}

+

+STATIC

+INT64

+VmReadIndex64 (

+  IN VM_CONTEXT     *VmPtr,

+  IN UINT32         CodeOffset

+  )

+/*++

+

+Routine Description:

+  Decode a 64-bit index to determine the offset.

+

+Arguments:

+  VmPtr       - pointer to VM context

+  CodeOffset  - offset from IP of the location of the 64-bit index to decode

+

+Returns:

+  Converted index per EBC VM specification

+

+--*/

+{

+  UINT64  Index;

+  UINT64  Remainder;

+  INT64   Offset;

+  INT64   C;

+  INT64   N;

+  INT64   NBits;

+  INT64   Mask;

+

+  Index = VmReadCode64 (VmPtr, CodeOffset);

+

+  //

+  // Get the mask for N. First get the number of bits from the index.

+  //

+  NBits = RightShiftU64 ((Index & 0x7000000000000000ULL), 60);

+

+  //

+  // Scale it for 64-bit indexes (multiply by 8 by shifting left 3)

+  //

+  NBits = LeftShiftU64 (NBits, 3);

+

+  //

+  // Now using the number of bits, create a mask.

+  //

+  Mask = (LeftShiftU64 ((UINT64)~0, (UINT64) NBits));

+

+  //

+  // Now using the mask, extract N from the lower bits of the index.

+  //

+  N = Index &~Mask;

+

+  //

+  // Now compute C

+  //

+  C       = ARightShift64 (((Index &~0xF000000000000000ULL) & Mask), (UINTN) NBits);

+

+  Offset  = MulU64x64 (N, sizeof (UINTN), &Remainder) + C;

+

+  //

+  // Now set the sign

+  //

+  if (Index & 0x8000000000000000ULL) {

+    Offset = MulS64x64 (Offset, -1, (INT64 *)&Index);

+  }

+

+  return Offset;

+}

+

+STATIC

+EFI_STATUS

+VmWriteMem8 (

+  IN VM_CONTEXT    *VmPtr,

+  IN UINTN         Addr,

+  IN UINT8         Data

+  )

+/*++

+

+Routine Description:

+  The following VmWriteMem? routines are called by the EBC data

+  movement instructions that write to memory. Since these writes

+  may be to the stack, which looks like (high address on top) this,

+

+  [EBC entry point arguments]

+  [VM stack]

+  [EBC stack]

+

+  we need to detect all attempts to write to the EBC entry point argument

+  stack area and adjust the address (which will initially point into the 

+  VM stack) to point into the EBC entry point arguments.

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+  Addr    - adddress to write to

+  Data    - value to write to Addr

+  

+Returns:

+  Standard EFI_STATUS

+

+--*/

+{

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr            = ConvertStackAddr (VmPtr, Addr);

+  *(UINT8 *) Addr = Data;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+VmWriteMem16 (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr,

+  IN UINT16       Data

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+

+  //

+  // Do a simple write if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINT16))) {

+    *(UINT16 *) Addr = Data;

+  } else {

+    //

+    // Write as two bytes

+    //

+    MemoryFence ();

+    if ((Status = VmWriteMem8 (VmPtr, Addr, (UINT8) Data)) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    MemoryFence ();

+    if ((Status = VmWriteMem8 (VmPtr, Addr + 1, (UINT8) (Data >> 8))) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    MemoryFence ();

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+VmWriteMem32 (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr,

+  IN UINT32       Data

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+

+  //

+  // Do a simple write if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINT32))) {

+    *(UINT32 *) Addr = Data;

+  } else {

+    //

+    // Write as two words

+    //

+    MemoryFence ();

+    if ((Status = VmWriteMem16 (VmPtr, Addr, (UINT16) Data)) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    MemoryFence ();

+    if ((Status = VmWriteMem16 (VmPtr, Addr + sizeof (UINT16), (UINT16) (Data >> 16))) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    MemoryFence ();

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+VmWriteMem64 (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr,

+  IN UINT64       Data

+  )

+{

+  EFI_STATUS  Status;

+  UINT32      Data32;

+

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+

+  //

+  // Do a simple write if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINT64))) {

+    *(UINT64 *) Addr = Data;

+  } else {

+    //

+    // Write as two 32-bit words

+    //

+    MemoryFence ();

+    if ((Status = VmWriteMem32 (VmPtr, Addr, (UINT32) Data)) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    MemoryFence ();

+    Data32 = (UINT32) (((UINT32 *) &Data)[1]);

+    if ((Status = VmWriteMem32 (VmPtr, Addr + sizeof (UINT32), Data32)) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    MemoryFence ();

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+VmWriteMemN (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr,

+  IN UINTN        Data

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+

+  Status = EFI_SUCCESS;

+

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+

+  //

+  // Do a simple write if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINTN))) {

+    *(UINTN *) Addr = Data;

+  } else {

+    for (Index = 0; Index < sizeof (UINTN) / sizeof (UINT32); Index++) {

+      MemoryFence ();

+      Status = VmWriteMem32 (VmPtr, Addr + Index * sizeof (UINT32), (UINT32) Data);

+      MemoryFence ();

+      Data = (UINTN)RShiftU64 ((UINT64)Data, 32);

+    }

+  }

+

+  return Status;

+}

+

+STATIC

+INT8

+VmReadImmed8 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+/*++

+

+Routine Description:

+  

+  The following VmReadImmed routines are called by the EBC execute

+  functions to read EBC immediate values from the code stream.

+  Since we can't assume alignment, each tries to read in the biggest 

+  chunks size available, but will revert to smaller reads if necessary.

+

+Arguments:

+  VmPtr   - pointer to a VM context  

+  Offset  - offset from IP of the code bytes to read.

+

+Returns:

+  Signed data of the requested size from the specified address.

+

+--*/

+{

+  //

+  // Simply return the data in flat memory space

+  //

+  return * (INT8 *) (VmPtr->Ip + Offset);

+}

+

+STATIC

+INT16

+VmReadImmed16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+{

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (INT16))) {

+    return * (INT16 *) (VmPtr->Ip + Offset);

+  } else {

+    //

+    // All code word reads should be aligned

+    //

+    EbcDebugSignalException (

+      EXCEPT_EBC_ALIGNMENT_CHECK,

+      EXCEPTION_FLAG_WARNING,

+      VmPtr

+      );

+  }

+  //

+  // Return unaligned data

+  //

+  return (INT16) (*(UINT8 *) (VmPtr->Ip + Offset) + (*(UINT8 *) (VmPtr->Ip + Offset + 1) << 8));

+}

+

+STATIC

+INT32

+VmReadImmed32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+{

+  UINT32  Data;

+

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT32))) {

+    return * (INT32 *) (VmPtr->Ip + Offset);

+  }

+  //

+  // Return unaligned data

+  //

+  Data = (UINT32) VmReadCode16 (VmPtr, Offset);

+  Data |= (UINT32) (VmReadCode16 (VmPtr, Offset + 2) << 16);

+  return Data;

+}

+

+STATIC

+INT64

+VmReadImmed64 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+{

+  UINT64  Data64;

+  UINT32  Data32;

+  UINT8   *Ptr;

+

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT64))) {

+    return * (UINT64 *) (VmPtr->Ip + Offset);

+  }

+  //

+  // Return unaligned data.

+  //

+  Ptr             = (UINT8 *) &Data64;

+  Data32          = VmReadCode32 (VmPtr, Offset);

+  *(UINT32 *) Ptr = Data32;

+  Ptr += sizeof (Data32);

+  Data32          = VmReadCode32 (VmPtr, Offset + sizeof (UINT32));

+  *(UINT32 *) Ptr = Data32;

+  return Data64;

+}

+

+STATIC

+UINT16

+VmReadCode16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+/*++

+

+Routine Description:

+  The following VmReadCode() routines provide the ability to read raw 

+  unsigned data from the code stream. 

+  

+Arguments:

+  VmPtr   - pointer to VM context

+  Offset  - offset from current IP to the raw data to read.

+

+Returns:

+  The raw unsigned 16-bit value from the code stream.

+  

+--*/

+{

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT16))) {

+    return * (UINT16 *) (VmPtr->Ip + Offset);

+  } else {

+    //

+    // All code word reads should be aligned

+    //

+    EbcDebugSignalException (

+      EXCEPT_EBC_ALIGNMENT_CHECK,

+      EXCEPTION_FLAG_WARNING,

+      VmPtr

+      );

+  }

+  //

+  // Return unaligned data

+  //

+  return (UINT16) (*(UINT8 *) (VmPtr->Ip + Offset) + (*(UINT8 *) (VmPtr->Ip + Offset + 1) << 8));

+}

+

+STATIC

+UINT32

+VmReadCode32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+{

+  UINT32  Data;

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT32))) {

+    return * (UINT32 *) (VmPtr->Ip + Offset);

+  }

+  //

+  // Return unaligned data

+  //

+  Data = (UINT32) VmReadCode16 (VmPtr, Offset);

+  Data |= (VmReadCode16 (VmPtr, Offset + 2) << 16);

+  return Data;

+}

+

+STATIC

+UINT64

+VmReadCode64 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINT32     Offset

+  )

+{

+  UINT64  Data64;

+  UINT32  Data32;

+  UINT8   *Ptr;

+

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT64))) {

+    return * (UINT64 *) (VmPtr->Ip + Offset);

+  }

+  //

+  // Return unaligned data.

+  //

+  Ptr             = (UINT8 *) &Data64;

+  Data32          = VmReadCode32 (VmPtr, Offset);

+  *(UINT32 *) Ptr = Data32;

+  Ptr += sizeof (Data32);

+  Data32          = VmReadCode32 (VmPtr, Offset + sizeof (UINT32));

+  *(UINT32 *) Ptr = Data32;

+  return Data64;

+}

+

+STATIC

+UINT8

+VmReadMem8 (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr

+  )

+{

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+  //

+  // Simply return the data in flat memory space

+  //

+  return * (UINT8 *) Addr;

+}

+

+STATIC

+UINT16

+VmReadMem16 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  )

+{

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINT16))) {

+    return * (UINT16 *) Addr;

+  }

+  //

+  // Return unaligned data

+  //

+  return (UINT16) (*(UINT8 *) Addr + (*(UINT8 *) (Addr + 1) << 8));

+}

+

+STATIC

+UINT32

+VmReadMem32 (

+  IN VM_CONTEXT *VmPtr,

+  IN UINTN      Addr

+  )

+{

+  UINT32  Data;

+

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINT32))) {

+    return * (UINT32 *) Addr;

+  }

+  //

+  // Return unaligned data

+  //

+  Data = (UINT32) VmReadMem16 (VmPtr, Addr);

+  Data |= (VmReadMem16 (VmPtr, Addr + 2) << 16);

+  return Data;

+}

+

+STATIC

+UINT64

+VmReadMem64 (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr

+  )

+{

+  UINT64  Data;

+  UINT32  Data32;

+

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINT64))) {

+    return * (UINT64 *) Addr;

+  }

+  //

+  // Return unaligned data. Assume little endian.

+  //

+  Data    = (UINT64) VmReadMem32 (VmPtr, Addr);

+  Data32  = VmReadMem32 (VmPtr, Addr + sizeof (UINT32));

+  *(UINT32 *) ((UINT32 *) &Data + 1) = Data32;

+  return Data;

+}

+

+STATIC

+UINTN

+ConvertStackAddr (

+  IN VM_CONTEXT    *VmPtr,

+  IN UINTN         Addr

+  )

+/*++

+

+Routine Description:

+

+  Given an address that EBC is going to read from or write to, return

+  an appropriate address that accounts for a gap in the stack.

+  

+  The stack for this application looks like this (high addr on top)

+  [EBC entry point arguments]

+  [VM stack]

+  [EBC stack]

+

+  The EBC assumes that its arguments are at the top of its stack, which

+  is where the VM stack is really. Therefore if the EBC does memory

+  accesses into the VM stack area, then we need to convert the address

+  to point to the EBC entry point arguments area. Do this here.

+

+Arguments:

+

+  VmPtr    - pointer to VM context

+  Addr  - address of interest

+

+Returns:

+

+  The unchanged address if it's not in the VM stack region. Otherwise, 

+  adjust for the stack gap and return the modified address.

+  

+--*/

+{

+  if ((Addr >= VmPtr->LowStackTop) && (Addr < VmPtr->HighStackBottom)) {

+    //

+    // In the stack gap -- now make sure it's not in the VM itself, which

+    // would be the case if it's accessing VM register contents.

+    //

+    if ((Addr < (UINTN) VmPtr) || (Addr > (UINTN) VmPtr + sizeof (VM_CONTEXT))) {

+      VmPtr->LastAddrConverted      = Addr;

+      VmPtr->LastAddrConvertedValue = Addr - VmPtr->LowStackTop + VmPtr->HighStackBottom;

+      return Addr - VmPtr->LowStackTop + VmPtr->HighStackBottom;

+    }

+  }

+

+  return Addr;

+}

+

+STATIC

+UINTN

+VmReadMemN (

+  IN VM_CONTEXT    *VmPtr,

+  IN UINTN         Addr

+  )

+/*++

+

+Routine Description:

+  Read a natural value from memory. May or may not be aligned.

+  

+Arguments:

+  VmPtr   - current VM context

+  Addr    - the address to read from

+

+Returns:

+  The natural value at address Addr.

+  

+--*/

+{

+  UINTN   Data;

+  UINT32  Size;

+  UINT8   *FromPtr;

+  UINT8   *ToPtr;

+  //

+  // Convert the address if it's in the stack gap

+  //

+  Addr = ConvertStackAddr (VmPtr, Addr);

+  //

+  // Read direct if aligned

+  //

+  if (IS_ALIGNED (Addr, sizeof (UINTN))) {

+    return * (UINTN *) Addr;

+  }

+  //

+  // Return unaligned data

+  //

+  Data    = 0;

+  FromPtr = (UINT8 *) Addr;

+  ToPtr   = (UINT8 *) &Data;

+

+  for (Size = 0; Size < sizeof (Data); Size++) {

+    *ToPtr = *FromPtr;

+    ToPtr++;

+    FromPtr++;

+  }

+

+  return Data;

+}

+

+UINT64

+GetVmVersion (

+  VOID

+  )

+{

+  return (UINT64) (((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF)));

+}

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.h b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.h
new file mode 100644
index 0000000..62b530b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.h
@@ -0,0 +1,383 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EbcExecute.h

+

+Abstract:

+

+  Header file for Virtual Machine support. Contains EBC defines that can

+  be of use to a disassembler for the most part. Also provides function 

+  prototypes for VM functions.

+

+--*/

+

+#ifndef _EBC_EXECUTE_H_

+#define _EBC_EXECUTE_H_

+

+//

+// Macros to check and set alignment

+//

+#define ASSERT_ALIGNED(addr, size)  ASSERT (!((UINT32) (addr) & (size - 1)))

+#define IS_ALIGNED(addr, size)      !((UINT32) (addr) & (size - 1))

+

+//

+// Define a macro to get the operand. Then we can change it to be either a

+// direct read or have it call a function to read memory.

+//

+#define GETOPERANDS(pVM)  (UINT8) (*(UINT8 *) (pVM->Ip + 1))

+#define GETOPCODE(pVM)    (UINT8) (*(UINT8 *) pVM->Ip)

+

+//

+// Bit masks for opcode encodings

+//

+#define OPCODE_M_OPCODE       0x3F  // bits of interest for first level decode

+#define OPCODE_M_IMMDATA      0x80

+#define OPCODE_M_IMMDATA64    0x40

+#define OPCODE_M_64BIT        0x40  // for CMP

+#define OPCODE_M_RELADDR      0x10  // for CALL instruction

+#define OPCODE_M_CMPI32_DATA  0x80  // for CMPI

+#define OPCODE_M_CMPI64       0x40  // for CMPI 32 or 64 bit comparison

+#define OPERAND_M_MOVIN_N     0x80

+#define OPERAND_M_CMPI_INDEX  0x10

+

+//

+// Masks for instructions that encode presence of indexes for operand1 and/or

+// operand2.

+//

+#define OPCODE_M_IMMED_OP1  0x80

+#define OPCODE_M_IMMED_OP2  0x40

+

+//

+// Bit masks for operand encodings

+//

+#define OPERAND_M_INDIRECT1 0x08

+#define OPERAND_M_INDIRECT2 0x80

+#define OPERAND_M_OP1       0x07

+#define OPERAND_M_OP2       0x70

+

+//

+// Masks for data manipulation instructions

+//

+#define DATAMANIP_M_64      0x40  // 64-bit width operation

+#define DATAMANIP_M_IMMDATA 0x80

+

+//

+// For MOV instructions, need a mask for the opcode when immediate

+// data applies to R2.

+//

+#define OPCODE_M_IMMED_OP2  0x40

+

+//

+// The MOVI/MOVIn instructions use bit 6 of operands byte to indicate

+// if an index is present. Then bits 4 and 5 are used to indicate the width

+// of the move.

+//

+#define MOVI_M_IMMDATA    0x40

+#define MOVI_M_DATAWIDTH  0xC0

+#define MOVI_DATAWIDTH16  0x40

+#define MOVI_DATAWIDTH32  0x80

+#define MOVI_DATAWIDTH64  0xC0

+#define MOVI_M_MOVEWIDTH  0x30

+#define MOVI_MOVEWIDTH8   0x00

+#define MOVI_MOVEWIDTH16  0x10

+#define MOVI_MOVEWIDTH32  0x20

+#define MOVI_MOVEWIDTH64  0x30

+

+//

+// Masks for CALL instruction encodings

+//

+#define OPERAND_M_RELATIVE_ADDR 0x10

+#define OPERAND_M_NATIVE_CALL   0x20

+

+//

+// Masks for decoding push/pop instructions

+//

+#define PUSHPOP_M_IMMDATA 0x80  // opcode bit indicating immediate data

+#define PUSHPOP_M_64      0x40  // opcode bit indicating 64-bit operation

+//

+// Mask for operand of JMP instruction

+//

+#define JMP_M_RELATIVE    0x10

+#define JMP_M_CONDITIONAL 0x80

+#define JMP_M_CS          0x40

+

+//

+// Macros to determine if a given operand is indirect

+//

+#define OPERAND1_INDIRECT(op) ((op) & OPERAND_M_INDIRECT1)

+#define OPERAND2_INDIRECT(op) ((op) & OPERAND_M_INDIRECT2)

+

+//

+// Macros to extract the operands from second byte of instructions

+//

+#define OPERAND1_REGNUM(op)       ((op) & OPERAND_M_OP1)

+#define OPERAND2_REGNUM(op)       (((op) & OPERAND_M_OP2) >> 4)

+

+#define OPERAND1_CHAR(op)         ('0' + OPERAND1_REGNUM (op))

+#define OPERAND2_CHAR(op)         ('0' + OPERAND2_REGNUM (op))

+

+#define OPERAND1_REGDATA(pvm, op) pvm->R[OPERAND1_REGNUM (op)]

+#define OPERAND2_REGDATA(pvm, op) pvm->R[OPERAND2_REGNUM (op)]

+

+//

+// Condition masks usually for byte 1 encodings of code

+//

+#define CONDITION_M_CONDITIONAL 0x80

+#define CONDITION_M_CS          0x40

+

+//

+// Bits in the VM->StopFlags field

+//

+#define STOPFLAG_APP_DONE         0x0001

+#define STOPFLAG_BREAKPOINT       0x0002

+#define STOPFLAG_INVALID_BREAK    0x0004

+#define STOPFLAG_BREAK_ON_CALLEX  0x0008

+

+//

+// Masks for working with the VM flags register

+//

+#define VMFLAGS_CC        0x0001  // condition flag

+#define VMFLAGS_STEP      0x0002  // step instruction mode

+#define VMFLAGS_ALL_VALID (VMFLAGS_CC | VMFLAGS_STEP)

+

+//

+// Macros for operating on the VM flags register

+//

+#define VMFLAG_SET(pVM, Flag)   (pVM->Flags |= (Flag))

+#define VMFLAG_ISSET(pVM, Flag) ((pVM->Flags & (Flag)) ? 1 : 0)

+#define VMFLAG_CLEAR(pVM, Flag) (pVM->Flags &= ~(Flag))

+

+//

+// Debug macro

+//

+#define EBCMSG(s) gST->ConOut->OutputString (gST->ConOut, s)

+

+//

+// Define OPCODES

+//

+#define OPCODE_BREAK    0x00

+#define OPCODE_JMP      0x01

+#define OPCODE_JMP8     0x02

+#define OPCODE_CALL     0x03

+#define OPCODE_RET      0x04

+#define OPCODE_CMPEQ    0x05

+#define OPCODE_CMPLTE   0x06

+#define OPCODE_CMPGTE   0x07

+#define OPCODE_CMPULTE  0x08

+#define OPCODE_CMPUGTE  0x09

+#define OPCODE_NOT      0x0A

+#define OPCODE_NEG      0x0B

+#define OPCODE_ADD      0x0C

+#define OPCODE_SUB      0x0D

+#define OPCODE_MUL      0x0E

+#define OPCODE_MULU     0x0F

+#define OPCODE_DIV      0x10

+#define OPCODE_DIVU     0x11

+#define OPCODE_MOD      0x12

+#define OPCODE_MODU     0x13

+#define OPCODE_AND      0x14

+#define OPCODE_OR       0x15

+#define OPCODE_XOR      0x16

+#define OPCODE_SHL      0x17

+#define OPCODE_SHR      0x18

+#define OPCODE_ASHR     0x19

+#define OPCODE_EXTNDB   0x1A

+#define OPCODE_EXTNDW   0x1B

+#define OPCODE_EXTNDD   0x1C

+#define OPCODE_MOVBW    0x1D

+#define OPCODE_MOVWW    0x1E

+#define OPCODE_MOVDW    0x1F

+#define OPCODE_MOVQW    0x20

+#define OPCODE_MOVBD    0x21

+#define OPCODE_MOVWD    0x22

+#define OPCODE_MOVDD    0x23

+#define OPCODE_MOVQD    0x24

+#define OPCODE_MOVSNW   0x25  // Move signed natural with word index

+#define OPCODE_MOVSND   0x26  // Move signed natural with dword index

+//

+// #define OPCODE_27         0x27

+//

+#define OPCODE_MOVQQ    0x28  // Does this go away?

+#define OPCODE_LOADSP   0x29

+#define OPCODE_STORESP  0x2A

+#define OPCODE_PUSH     0x2B

+#define OPCODE_POP      0x2C

+#define OPCODE_CMPIEQ   0x2D

+#define OPCODE_CMPILTE  0x2E

+#define OPCODE_CMPIGTE  0x2F

+#define OPCODE_CMPIULTE 0x30

+#define OPCODE_CMPIUGTE 0x31

+#define OPCODE_MOVNW    0x32

+#define OPCODE_MOVND    0x33

+//

+// #define OPCODE_34         0x34

+//

+#define OPCODE_PUSHN  0x35

+#define OPCODE_POPN   0x36

+#define OPCODE_MOVI   0x37

+#define OPCODE_MOVIN  0x38

+#define OPCODE_MOVREL 0x39

+

+EFI_STATUS

+EbcExecute (

+  IN VM_CONTEXT *VmPtr

+  )

+;

+

+//

+// Math library routines

+//

+INT64

+DivS64x64 (

+  IN INT64      Value1,

+  IN INT64      Value2,

+  OUT INT64     *Remainder,

+  OUT UINT32    *Error

+  )

+;

+#if 0

+UINT64

+DivU64x64 (

+  IN UINT64   Value1,

+  IN UINT64   Value2,

+  OUT UINT64  *Remainder,

+  OUT UINT32  *Error

+  )

+;

+#endif

+

+INT64

+MulS64x64 (

+  IN INT64  Value1,

+  IN INT64  Value2,

+  OUT INT64 *ResultHigh

+  )

+;

+

+UINT64

+MulU64x64 (

+  IN UINT64   Value1,

+  IN UINT64   Value2,

+  OUT UINT64  *ResultHigh

+  )

+;

+

+UINT64

+DivU64x64 (

+  IN UINT64   Value1,

+  IN UINT64   Value2,

+  OUT UINT64  *Remainder,

+  OUT UINT32  *Error

+  )

+;

+

+INT64

+ARightShift64 (

+  IN INT64  Operand,

+  IN INT64  Count

+  )

+;

+

+UINT64

+LeftShiftU64 (

+  IN UINT64   Operand,

+  IN UINT64   Count

+  )

+;

+

+UINT64

+RightShiftU64 (

+  IN UINT64   Operand,

+  IN UINT64   Count

+  )

+;

+

+UINT64

+GetVmVersion (

+  VOID

+  )

+;

+

+EFI_STATUS

+VmWriteMemN (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        Addr,

+  IN UINTN        Data

+  )

+;

+

+EFI_STATUS

+VmWriteMem64 (

+  IN VM_CONTEXT *VmPtr,

+  UINTN         Addr,

+  IN UINT64     Data

+  )

+;

+

+//

+// Define a protocol for an EBC VM test interface.

+//

+#define EFI_EBC_VM_TEST_PROTOCOL_GUID \

+  { \

+    0xAAEACCFDL, 0xF27B, 0x4C17, { 0xB6, 0x10, 0x75, 0xCA, 0x1F, 0x2D, 0xFB, 0x52 } \

+  }

+

+//

+// Define for forward reference.

+//

+typedef struct _EFI_EBC_VM_TEST_PROTOCOL EFI_EBC_VM_TEST_PROTOCOL;

+

+typedef

+EFI_STATUS

+(*EBC_VM_TEST_EXECUTE) (

+  IN EFI_EBC_VM_TEST_PROTOCOL         * This,

+  IN VM_CONTEXT                       * VmPtr,

+  IN OUT UINTN                        *InstructionCount

+  );

+

+typedef

+EFI_STATUS

+(*EBC_VM_TEST_ASM) (

+  IN EFI_EBC_VM_TEST_PROTOCOL         * This,

+  IN CHAR16                           *AsmText,

+  IN OUT INT8                         *Buffer,

+  IN OUT UINTN                        *BufferLen

+  );

+

+typedef

+EFI_STATUS

+(*EBC_VM_TEST_DASM) (

+  IN EFI_EBC_VM_TEST_PROTOCOL         * This,

+  IN OUT CHAR16                       *AsmText,

+  IN OUT INT8                         *Buffer,

+  IN OUT UINTN                        *Len

+  );

+

+//

+// Prototype for the actual EBC test protocol interface

+//

+struct _EFI_EBC_VM_TEST_PROTOCOL {

+  EBC_VM_TEST_EXECUTE Execute;

+  EBC_VM_TEST_ASM     Assemble;

+  EBC_VM_TEST_DASM    Disassemble;

+};

+

+EFI_STATUS

+EbcExecuteInstructions (

+  IN EFI_EBC_VM_TEST_PROTOCOL *This,

+  IN VM_CONTEXT               *VmPtr,

+  IN OUT UINTN                *InstructionCount

+  )

+;

+

+#endif // ifndef _EBC_EXECUTE_H_

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c
new file mode 100644
index 0000000..220c8fe
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c
@@ -0,0 +1,932 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  EbcInt.c

+  

+Abstract:

+

+  Top level module for the EBC virtual machine implementation.

+  Provides auxilliary support routines for the VM. That is, routines

+  that are not particularly related to VM execution of EBC instructions.

+  

+--*/

+

+#include "EbcInt.h"

+#include "EbcExecute.h"

+

+//

+// We'll keep track of all thunks we create in a linked list. Each

+// thunk is tied to an image handle, so we have a linked list of

+// image handles, with each having a linked list of thunks allocated

+// to that image handle.

+//

+typedef struct _EBC_THUNK_LIST {

+  VOID                    *ThunkBuffer;

+  struct _EBC_THUNK_LIST  *Next;

+} EBC_THUNK_LIST;

+

+typedef struct _EBC_IMAGE_LIST {

+  struct _EBC_IMAGE_LIST  *Next;

+  EFI_HANDLE              ImageHandle;

+  EBC_THUNK_LIST          *ThunkList;

+} EBC_IMAGE_LIST;

+

+//

+// Function prototypes

+//

+EFI_STATUS

+EFIAPI

+InitializeEbcDriver (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcUnloadImage (

+  IN EFI_EBC_PROTOCOL     *This,

+  IN EFI_HANDLE           ImageHandle

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcCreateThunk (

+  IN EFI_EBC_PROTOCOL     *This,

+  IN EFI_HANDLE           ImageHandle,

+  IN VOID                 *EbcEntryPoint,

+  OUT VOID                **Thunk

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcGetVersion (

+  IN EFI_EBC_PROTOCOL     *This,

+  IN OUT UINT64           *Version

+  );

+

+//

+// These two functions and the  GUID are used to produce an EBC test protocol.

+// This functionality is definitely not required for execution.

+//

+STATIC

+EFI_STATUS

+InitEbcVmTestProtocol (

+  IN EFI_HANDLE     *Handle

+  );

+

+STATIC

+EFI_STATUS

+EbcVmTestUnsupported (

+  VOID

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcRegisterICacheFlush (

+  IN EFI_EBC_PROTOCOL               *This,

+  IN EBC_ICACHE_FLUSH               Flush

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugGetMaximumProcessorIndex (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,

+  OUT UINTN                         *MaxProcessorIndex

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugRegisterPeriodicCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,

+  IN UINTN                          ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK          PeriodicCallback

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugRegisterExceptionCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,

+  IN UINTN                          ProcessorIndex,

+  IN EFI_EXCEPTION_CALLBACK         ExceptionCallback,

+  IN EFI_EXCEPTION_TYPE             ExceptionType

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugInvalidateInstructionCache (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,

+  IN UINTN                          ProcessorIndex,

+  IN VOID                           *Start,

+  IN UINT64                         Length

+  );

+

+//

+// We have one linked list of image handles for the whole world. Since

+// there should only be one interpreter, make them global. They must

+// also be global since the execution of an EBC image does not provide

+// a This pointer.

+//

+static EBC_IMAGE_LIST         *mEbcImageList = NULL;

+

+//

+// Callback function to flush the icache after thunk creation

+//

+static EBC_ICACHE_FLUSH       mEbcICacheFlush;

+

+//

+// These get set via calls by the debug agent

+//

+static EFI_PERIODIC_CALLBACK  mDebugPeriodicCallback    = NULL;

+static EFI_EXCEPTION_CALLBACK mDebugExceptionCallback   = NULL;

+static EFI_GUID               mEfiEbcVmTestProtocolGuid = EFI_EBC_VM_TEST_PROTOCOL_GUID;

+

+EFI_STATUS

+EFIAPI

+InitializeEbcDriver (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description: 

+

+  Initializes the VM EFI interface.  Allocates memory for the VM interface 

+  and registers the VM protocol.

+

+Arguments:  

+

+  ImageHandle - EFI image handle.

+  SystemTable - Pointer to the EFI system table.

+

+Returns:  

+  Standard EFI status code.

+

+--*/

+{

+  EFI_EBC_PROTOCOL            *EbcProtocol;

+  EFI_EBC_PROTOCOL            *OldEbcProtocol;

+  EFI_STATUS                  Status;

+  EFI_DEBUG_SUPPORT_PROTOCOL  *EbcDebugProtocol;

+  EFI_HANDLE                  *HandleBuffer;

+  UINTN                       NumHandles;

+  UINTN                       Index;

+  BOOLEAN                     Installed;

+

+  //

+  // Allocate memory for our protocol. Then fill in the blanks.

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_EBC_PROTOCOL),

+                  (VOID **) &EbcProtocol

+                  );

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  EbcProtocol->CreateThunk          = EbcCreateThunk;

+  EbcProtocol->UnloadImage          = EbcUnloadImage;

+  EbcProtocol->RegisterICacheFlush  = EbcRegisterICacheFlush;

+  EbcProtocol->GetVersion           = EbcGetVersion;

+  mEbcICacheFlush                   = NULL;

+

+  //

+  // Find any already-installed EBC protocols and uninstall them

+  //

+  Installed     = FALSE;

+  HandleBuffer  = NULL;

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiEbcProtocolGuid,

+                  NULL,

+                  &NumHandles,

+                  &HandleBuffer

+                  );

+  if (Status == EFI_SUCCESS) {

+    //

+    // Loop through the handles

+    //

+    for (Index = 0; Index < NumHandles; Index++) {

+      Status = gBS->HandleProtocol (

+                      HandleBuffer[Index],

+                      &gEfiEbcProtocolGuid,

+                      (VOID **) &OldEbcProtocol

+                      );

+      if (Status == EFI_SUCCESS) {

+        if (gBS->ReinstallProtocolInterface (

+                  HandleBuffer[Index],

+                  &gEfiEbcProtocolGuid,

+                  OldEbcProtocol,

+                  EbcProtocol

+                  ) == EFI_SUCCESS) {

+          Installed = TRUE;

+        }

+      }

+    }

+  }

+

+  if (HandleBuffer != NULL) {

+    gBS->FreePool (HandleBuffer);

+    HandleBuffer = NULL;

+  }

+  //

+  // Add the protocol so someone can locate us if we haven't already.

+  //

+  if (!Installed) {

+    Status = gBS->InstallProtocolInterface (

+                    &ImageHandle,

+                    &gEfiEbcProtocolGuid,

+                    EFI_NATIVE_INTERFACE,

+                    EbcProtocol

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (EbcProtocol);

+      return Status;

+    }

+  }

+  //

+  // Allocate memory for our debug protocol. Then fill in the blanks.

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_DEBUG_SUPPORT_PROTOCOL),

+                  (VOID **) &EbcDebugProtocol

+                  );

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  EbcDebugProtocol->Isa                         = IsaEbc;

+  EbcDebugProtocol->GetMaximumProcessorIndex    = EbcDebugGetMaximumProcessorIndex;

+  EbcDebugProtocol->RegisterPeriodicCallback    = EbcDebugRegisterPeriodicCallback;

+  EbcDebugProtocol->RegisterExceptionCallback   = EbcDebugRegisterExceptionCallback;

+  EbcDebugProtocol->InvalidateInstructionCache  = EbcDebugInvalidateInstructionCache;

+

+  //

+  // Add the protocol so the debug agent can find us

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &ImageHandle,

+                  &gEfiDebugSupportProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  EbcDebugProtocol

+                  );

+  //

+  // This is recoverable, so free the memory and continue.

+  //

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (EbcDebugProtocol);

+  }

+  //

+  // Produce a VM test interface protocol. Not required for execution.

+  //

+  DEBUG_CODE (

+    InitEbcVmTestProtocol (&ImageHandle);

+  );

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcCreateThunk (

+  IN EFI_EBC_PROTOCOL   *This,

+  IN EFI_HANDLE         ImageHandle,

+  IN VOID               *EbcEntryPoint,

+  OUT VOID              **Thunk

+  )

+/*++

+

+Routine Description:

+  

+  This is the top-level routine plugged into the EBC protocol. Since thunks

+  are very processor-specific, from here we dispatch directly to the very 

+  processor-specific routine EbcCreateThunks().

+

+Arguments:

+

+  This          - protocol instance pointer

+  ImageHandle   - handle to the image. The EBC interpreter may use this to keep

+                  track of any resource allocations performed in loading and

+                  executing the image.

+  EbcEntryPoint - the entry point for the image (as defined in the file header)

+  Thunk         - pointer to thunk pointer where the address of the created

+                  thunk is returned.

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = EbcCreateThunks (

+            ImageHandle,

+            EbcEntryPoint,

+            Thunk,

+            FLAG_THUNK_ENTRY_POINT

+            );

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugGetMaximumProcessorIndex (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,

+  OUT UINTN                              *MaxProcessorIndex

+  )

+/*++

+

+Routine Description:

+  

+  This EBC debugger protocol service is called by the debug agent

+

+Arguments:

+

+  This              - pointer to the caller's debug support protocol interface

+  MaxProcessorIndex - pointer to a caller allocated UINTN in which the maximum

+                      processor index is returned.

+                                               

+Returns:

+

+  Standard EFI_STATUS

+

+--*/

+{

+  *MaxProcessorIndex = 0;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugRegisterPeriodicCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,

+  IN UINTN                       ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK       PeriodicCallback

+  )

+/*++

+

+Routine Description:

+  

+  This protocol service is called by the debug agent to register a function

+  for us to call on a periodic basis.

+  

+

+Arguments:

+

+  This              - pointer to the caller's debug support protocol interface

+  PeriodicCallback  - pointer to the function to call periodically

+

+Returns:

+

+  Always EFI_SUCCESS

+

+--*/

+{

+  mDebugPeriodicCallback = PeriodicCallback;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugRegisterExceptionCallback (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,

+  IN UINTN                       ProcessorIndex,

+  IN EFI_EXCEPTION_CALLBACK      ExceptionCallback,

+  IN EFI_EXCEPTION_TYPE          ExceptionType

+  )

+/*++

+

+Routine Description:

+  

+  This protocol service is called by the debug agent to register a function

+  for us to call when we detect an exception.

+  

+

+Arguments:

+

+  This              - pointer to the caller's debug support protocol interface

+  PeriodicCallback  - pointer to the function to call periodically

+

+Returns:

+

+  Always EFI_SUCCESS

+

+--*/

+{

+  mDebugExceptionCallback = ExceptionCallback;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcDebugInvalidateInstructionCache (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,

+  IN UINTN                               ProcessorIndex,

+  IN VOID                                *Start,

+  IN UINT64                              Length

+  )

+/*++

+

+Routine Description:

+  

+  This EBC debugger protocol service is called by the debug agent.  Required

+  for DebugSupport compliance but is only stubbed out for EBC.

+

+Arguments:

+                                               

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EbcDebugSignalException (

+  IN EFI_EXCEPTION_TYPE                   ExceptionType,

+  IN EXCEPTION_FLAGS                      ExceptionFlags,

+  IN VM_CONTEXT                           *VmPtr

+  )

+/*++

+

+Routine Description:

+

+  The VM interpreter calls this function when an exception is detected.

+  

+Arguments:

+

+  VmPtr - pointer to a VM context for passing info to the EFI debugger.

+

+Returns:

+

+  EFI_SUCCESS if it returns at all

+  

+--*/

+{

+  EFI_SYSTEM_CONTEXT_EBC  EbcContext;

+  EFI_SYSTEM_CONTEXT      SystemContext;

+  EFI_STATUS_CODE_VALUE   StatusCodeValue;

+  BOOLEAN                 Report;

+  //

+  // Save the exception in the context passed in

+  //

+  VmPtr->ExceptionFlags |= ExceptionFlags;

+  VmPtr->LastException = ExceptionType;

+  //

+  // If it's a fatal exception, then flag it in the VM context in case an

+  // attached debugger tries to return from it.

+  //

+  if (ExceptionFlags & EXCEPTION_FLAG_FATAL) {

+    VmPtr->StopFlags |= STOPFLAG_APP_DONE;

+  }

+  //

+  // Initialize the context structure

+  //

+  EbcContext.R0                   = VmPtr->R[0];

+  EbcContext.R1                   = VmPtr->R[1];

+  EbcContext.R2                   = VmPtr->R[2];

+  EbcContext.R3                   = VmPtr->R[3];

+  EbcContext.R4                   = VmPtr->R[4];

+  EbcContext.R5                   = VmPtr->R[5];

+  EbcContext.R6                   = VmPtr->R[6];

+  EbcContext.R7                   = VmPtr->R[7];

+  EbcContext.Ip                   = (UINT64) (UINTN) VmPtr->Ip;

+  EbcContext.Flags                = VmPtr->Flags;

+  SystemContext.SystemContextEbc  = &EbcContext;

+  //

+  // If someone's registered for exception callbacks, then call them.

+  // Otherwise report the status code via the status code API

+  //

+  if (mDebugExceptionCallback != NULL) {

+    mDebugExceptionCallback (ExceptionType, SystemContext);

+  }

+  //

+  // Determine if we should report the exception. We report all of them by default,

+  // but if a debugger is attached don't report the breakpoint, debug, and step exceptions.

+  // Note that EXCEPT_EBC_OVERFLOW is never reported by this VM implementation, so is

+  // not included in the switch statement.

+  //

+  Report = TRUE;

+  switch (ExceptionType) {

+  case EXCEPT_EBC_UNDEFINED:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_UNDEFINED;

+    break;

+

+  case EXCEPT_EBC_DIVIDE_ERROR:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_DIVIDE_ERROR;

+    break;

+

+  case EXCEPT_EBC_DEBUG:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_DEBUG;

+    Report          = (BOOLEAN) ((mDebugExceptionCallback == NULL) ? TRUE : FALSE);

+    break;

+

+  case EXCEPT_EBC_BREAKPOINT:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_BREAKPOINT;

+    Report          = (BOOLEAN) ((mDebugExceptionCallback == NULL) ? TRUE : FALSE);

+    break;

+

+  case EXCEPT_EBC_INVALID_OPCODE:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_INVALID_OPCODE;

+    break;

+

+  case EXCEPT_EBC_STACK_FAULT:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_STACK_FAULT;

+    break;

+

+  case EXCEPT_EBC_ALIGNMENT_CHECK:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_ALIGNMENT_CHECK;

+    break;

+

+  case EXCEPT_EBC_INSTRUCTION_ENCODING:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_INSTRUCTION_ENCODING;

+    break;

+

+  case EXCEPT_EBC_BAD_BREAK:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_BAD_BREAK;

+    break;

+

+  case EXCEPT_EBC_STEP:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_EBC_STEP;

+    Report          = (BOOLEAN) ((mDebugExceptionCallback == NULL) ? TRUE : FALSE);

+    break;

+

+  default:

+    StatusCodeValue = EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_NON_SPECIFIC;

+    break;

+  }

+  //

+  // If we determined that we should report the condition, then do so now.

+  //

+  if (Report) {

+    REPORT_STATUS_CODE (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, StatusCodeValue);

+  }

+

+  switch (ExceptionType) {

+  //

+  // If ReportStatusCode returned, then for most exceptions we do an assert. The

+  // ExceptionType++ is done simply to force the ASSERT() condition to be met.

+  // For breakpoints, assume a debugger did not insert a software breakpoint

+  // and skip the instruction.

+  //

+  case EXCEPT_EBC_BREAKPOINT:

+    VmPtr->Ip += 2;

+    break;

+

+  case EXCEPT_EBC_STEP:

+    break;

+

+  case EXCEPT_EBC_UNDEFINED:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_UNDEFINED);

+    break;

+

+  case EXCEPT_EBC_DIVIDE_ERROR:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_DIVIDE_ERROR);

+    break;

+

+  case EXCEPT_EBC_DEBUG:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_DEBUG);

+    break;

+

+  case EXCEPT_EBC_INVALID_OPCODE:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_INVALID_OPCODE);

+    break;

+

+  case EXCEPT_EBC_STACK_FAULT:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_STACK_FAULT);

+    break;

+

+  case EXCEPT_EBC_ALIGNMENT_CHECK:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_ALIGNMENT_CHECK);

+    break;

+

+  case EXCEPT_EBC_INSTRUCTION_ENCODING:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_INSTRUCTION_ENCODING);

+    break;

+

+  case EXCEPT_EBC_BAD_BREAK:

+    ExceptionType++;

+    ASSERT (ExceptionType == EXCEPT_EBC_BAD_BREAK);

+    break;

+

+  default:

+    //

+    // Unknown

+    //

+    ASSERT (0);

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EbcDebugPeriodic (

+  IN VM_CONTEXT *VmPtr

+  )

+/*++

+

+Routine Description:

+

+  The VM interpreter calls this function on a periodic basis to support

+  the EFI debug support protocol.

+  

+Arguments:

+

+  VmPtr - pointer to a VM context for passing info to the debugger.

+

+Returns:

+

+  Standard EFI status.

+  

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcUnloadImage (

+  IN EFI_EBC_PROTOCOL   *This,

+  IN EFI_HANDLE         ImageHandle

+  )

+/*++

+

+Routine Description:

+  

+  This routine is called by the core when an image is being unloaded from 

+  memory. Basically we now have the opportunity to do any necessary cleanup.

+  Typically this will include freeing any memory allocated for thunk-creation.

+

+Arguments:

+

+  This          - protocol instance pointer

+  ImageHandle   - handle to the image being unloaded.

+

+Returns:

+

+  EFI_INVALID_PARAMETER  - the ImageHandle passed in was not found in

+                           the internal list of EBC image handles.

+  EFI_STATUS             - completed successfully

+

+--*/

+{

+  EBC_THUNK_LIST  *ThunkList;

+  EBC_THUNK_LIST  *NextThunkList;

+  EBC_IMAGE_LIST  *ImageList;

+  EBC_IMAGE_LIST  *PrevImageList;

+  //

+  // First go through our list of known image handles and see if we've already

+  // created an image list element for this image handle.

+  //

+  PrevImageList = NULL;

+  for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {

+    if (ImageList->ImageHandle == ImageHandle) {

+      break;

+    }

+    //

+    // Save the previous so we can connect the lists when we remove this one

+    //

+    PrevImageList = ImageList;

+  }

+

+  if (ImageList == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Free up all the thunk buffers and thunks list elements for this image

+  // handle.

+  //

+  ThunkList = ImageList->ThunkList;

+  while (ThunkList != NULL) {

+    NextThunkList = ThunkList->Next;

+    gBS->FreePool (ThunkList->ThunkBuffer);

+    gBS->FreePool (ThunkList);

+    ThunkList = NextThunkList;

+  }

+  //

+  // Now remove this image list element from the chain

+  //

+  if (PrevImageList == NULL) {

+    //

+    // Remove from head

+    //

+    mEbcImageList = ImageList->Next;

+  } else {

+    PrevImageList->Next = ImageList->Next;

+  }

+  //

+  // Now free up the image list element

+  //

+  gBS->FreePool (ImageList);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EbcAddImageThunk (

+  IN EFI_HANDLE      ImageHandle,

+  IN VOID            *ThunkBuffer,

+  IN UINT32          ThunkSize

+  )

+/*++

+

+Routine Description:

+  

+  Add a thunk to our list of thunks for a given image handle. 

+  Also flush the instruction cache since we've written thunk code

+  to memory that will be executed eventually.

+

+Arguments:

+

+  ImageHandle - the image handle to which the thunk is tied

+  ThunkBuffer - the buffer we've created/allocated

+  ThunkSize    - the size of the thunk memory allocated

+

+Returns:

+ 

+  EFI_OUT_OF_RESOURCES    - memory allocation failed

+  EFI_SUCCESS             - successful completion

+

+--*/

+{

+  EBC_THUNK_LIST  *ThunkList;

+  EBC_IMAGE_LIST  *ImageList;

+  EFI_STATUS      Status;

+

+  //

+  // It so far so good, then flush the instruction cache

+  //

+  if (mEbcICacheFlush != NULL) {

+    Status = mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS) (UINTN) ThunkBuffer, ThunkSize);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  //

+  // Go through our list of known image handles and see if we've already

+  // created a image list element for this image handle.

+  //

+  for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {

+    if (ImageList->ImageHandle == ImageHandle) {

+      break;

+    }

+  }

+

+  if (ImageList == NULL) {

+    //

+    // Allocate a new one

+    //

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (EBC_IMAGE_LIST),

+                    (VOID **) &ImageList

+                    );

+    if (Status != EFI_SUCCESS) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    ImageList->ThunkList    = NULL;

+    ImageList->ImageHandle  = ImageHandle;

+    ImageList->Next         = mEbcImageList;

+    mEbcImageList           = ImageList;

+  }

+  //

+  // Ok, now create a new thunk element to add to the list

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EBC_THUNK_LIST),

+                  (VOID **) &ThunkList

+                  );

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Add it to the head of the list

+  //

+  ThunkList->Next         = ImageList->ThunkList;

+  ThunkList->ThunkBuffer  = ThunkBuffer;

+  ImageList->ThunkList    = ThunkList;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcRegisterICacheFlush (

+  IN EFI_EBC_PROTOCOL   *This,

+  IN EBC_ICACHE_FLUSH   Flush

+  )

+{

+  mEbcICacheFlush = Flush;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+EbcGetVersion (

+  IN EFI_EBC_PROTOCOL   *This,

+  IN OUT UINT64         *Version

+  )

+{

+  if (Version == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Version = GetVmVersion ();

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+InitEbcVmTestProtocol (

+  IN EFI_HANDLE     *IHandle

+  )

+/*++

+

+Routine Description:

+  

+  Produce an EBC VM test protocol that can be used for regression tests.

+

+Arguments:

+

+  IHandle - handle on which to install the protocol.

+

+Returns:

+

+  EFI_OUT_OF_RESOURCES  - memory allocation failed

+  EFI_SUCCESS           - successful completion

+

+--*/

+{

+  EFI_HANDLE Handle;

+  EFI_STATUS Status;

+  EFI_EBC_VM_TEST_PROTOCOL *EbcVmTestProtocol;

+

+  //

+  // Allocate memory for the protocol, then fill in the fields

+  //

+  Status = gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_EBC_VM_TEST_PROTOCOL), (VOID **) &EbcVmTestProtocol);

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  EbcVmTestProtocol->Execute      = (EBC_VM_TEST_EXECUTE) EbcExecuteInstructions;

+

+  DEBUG_CODE(

+    EbcVmTestProtocol->Assemble     = (EBC_VM_TEST_ASM) EbcVmTestUnsupported;

+    EbcVmTestProtocol->Disassemble  = (EBC_VM_TEST_DASM) EbcVmTestUnsupported;

+  );

+

+  //

+  // Publish the protocol

+  //

+  Handle  = NULL;

+  Status  = gBS->InstallProtocolInterface (&Handle, &mEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (EbcVmTestProtocol);

+  }

+  return Status;

+}

+STATIC

+EFI_STATUS

+EbcVmTestUnsupported ()

+{

+  return EFI_UNSUPPORTED;

+}

+

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h
new file mode 100644
index 0000000..51bd785
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h
@@ -0,0 +1,231 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  EbcInt.h

+  

+Abstract:

+

+  Main routines for the EBC interpreter.  Includes the initialization and

+  main interpreter routines. 

+  

+--*/

+

+#ifndef _EBC_INT_H_

+#define _EBC_INT_H_

+

+typedef INT64   VM_REGISTER;

+typedef UINT8   *VMIP;      // instruction pointer for the VM

+typedef UINT32  EXCEPTION_FLAGS;

+

+typedef struct {

+  VM_REGISTER       R[8];   // General purpose registers.

+  UINT64            Flags;  // Flags register:

+                            //   0   Set to 1 if the result of the last compare was true

+                            //   1  Set to 1 if stepping

+                            //   2..63 Reserved.

+  VMIP              Ip;                     // Instruction pointer.

+  UINTN             LastException;          //

+  EXCEPTION_FLAGS   ExceptionFlags;         // to keep track of exceptions

+  UINT32            StopFlags;

+  UINT32            CompilerVersion;        // via break(6)

+  UINTN             HighStackBottom;        // bottom of the upper stack

+  UINTN             LowStackTop;            // top of the lower stack

+  UINT64            StackRetAddr;           // location of final return address on stack

+  UINTN             *StackMagicPtr;         // pointer to magic value on stack to detect corruption

+  EFI_HANDLE        ImageHandle;            // for this EBC driver

+  EFI_SYSTEM_TABLE  *SystemTable;           // for debugging only

+  UINTN             LastAddrConverted;      // for debug

+  UINTN             LastAddrConvertedValue; // for debug

+  VOID              *FramePtr;

+  VOID              *EntryPoint;            // entry point of EBC image

+  UINTN             ImageBase;

+} VM_CONTEXT;

+

+//

+// Bits of exception flags field of VM context

+//

+#define EXCEPTION_FLAG_FATAL    0x80000000  // can't continue

+#define EXCEPTION_FLAG_ERROR    0x40000000  // bad, but try to continue

+#define EXCEPTION_FLAG_WARNING  0x20000000  // harmless problem

+#define EXCEPTION_FLAG_NONE     0x00000000  // for normal return

+//

+// Flags passed to the internal create-thunks function.

+//

+#define FLAG_THUNK_ENTRY_POINT  0x01  // thunk for an image entry point

+#define FLAG_THUNK_PROTOCOL     0x00  // thunk for an EBC protocol service

+//

+// Put this value at the bottom of the VM's stack gap so we can check it on

+// occasion to make sure the stack has not been corrupted.

+//

+#define VM_STACK_KEY_VALUE  0xDEADBEEF

+

+EFI_STATUS

+EbcCreateThunks (

+  IN EFI_HANDLE           ImageHandle,

+  IN VOID                 *EbcEntryPoint,

+  OUT VOID                **Thunk,

+  IN UINT32               Flags

+  )

+;

+

+EFI_STATUS

+EbcAddImageThunk (

+  IN EFI_HANDLE     ImageHandle,

+  IN VOID           *ThunkBuffer,

+  IN UINT32         ThunkSize

+  )

+;

+

+//

+// The interpreter calls these when an exception is detected,

+// or as a periodic callback.

+//

+EFI_STATUS

+EbcDebugSignalException (

+  IN EFI_EXCEPTION_TYPE ExceptionType,

+  IN EXCEPTION_FLAGS    ExceptionFlags,

+  IN VM_CONTEXT         *VmPtr

+  )

+;

+

+//

+// Define a constant of how often to call the debugger periodic callback

+// function.

+//

+#define EBC_VM_PERIODIC_CALLBACK_RATE 1000

+

+EFI_STATUS

+EbcDebugSignalPeriodic (

+  IN VM_CONTEXT   *VmPtr

+  )

+;

+

+//

+// External low level functions that are native-processor dependent

+//

+UINTN

+EbcLLGetEbcEntryPoint (

+  VOID

+  )

+;

+

+UINTN

+EbcLLGetStackPointer (

+  VOID

+  )

+;

+

+VOID

+EbcLLCALLEXNative (

+  IN UINTN        CallAddr,

+  IN UINTN        EbcSp,

+  IN VOID         *FramePtr

+  )

+;

+

+VOID

+EbcLLCALLEX (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        CallAddr,

+  IN UINTN        EbcSp,

+  IN VOID         *FramePtr,

+  IN UINT8        Size

+  )

+;

+

+INT64

+EbcLLGetReturnValue (

+  VOID

+  )

+;

+

+//

+// Defines for a simple EBC debugger interface

+//

+typedef struct _EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL;

+

+#define EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL_GUID \

+  { \

+    0x2a72d11e, 0x7376, 0x40f6, { 0x9c, 0x68, 0x23, 0xfa, 0x2f, 0xe3, 0x63, 0xf1 } \

+  }

+

+typedef

+EFI_STATUS

+(*EBC_DEBUGGER_SIGNAL_EXCEPTION) (

+  IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL           * This,

+  IN VM_CONTEXT                                 * VmPtr,

+  IN EFI_EXCEPTION_TYPE                         ExceptionType

+  );

+

+typedef

+VOID

+(*EBC_DEBUGGER_DEBUG) (

+  IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL           * This,

+  IN VM_CONTEXT                                 * VmPtr

+  );

+

+typedef

+UINT32

+(*EBC_DEBUGGER_DASM) (

+  IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL           * This,

+  IN VM_CONTEXT                                 * VmPtr,

+  IN UINT16                                     *DasmString OPTIONAL,

+  IN UINT32                                     DasmStringSize

+  );

+

+//

+// This interface allows you to configure the EBC debug support

+// driver. For example, turn on or off saving and printing of

+// delta VM even if called. Or to even disable the entire interface,

+// in which case all functions become no-ops.

+//

+typedef

+EFI_STATUS

+(*EBC_DEBUGGER_CONFIGURE) (

+  IN EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL           * This,

+  IN UINT32                                     ConfigId,

+  IN UINTN                                      ConfigValue

+  );

+

+//

+// Prototype for the actual EBC debug support protocol interface

+//

+struct _EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL {

+  EBC_DEBUGGER_DEBUG            Debugger;

+  EBC_DEBUGGER_SIGNAL_EXCEPTION SignalException;

+  EBC_DEBUGGER_DASM             Dasm;

+  EBC_DEBUGGER_CONFIGURE        Configure;

+};

+

+typedef struct {

+  EFI_EBC_PROTOCOL  *This;

+  VOID              *EntryPoint;

+  EFI_HANDLE        ImageHandle;

+  VM_CONTEXT        VmContext;

+} EFI_EBC_THUNK_DATA;

+

+#define EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('e', 'b', 'c', 'p')

+

+struct _EBC_PROTOCOL_PRIVATE_DATA {

+  UINT32            Signature;

+  EFI_EBC_PROTOCOL  EbcProtocol;

+  UINTN             StackBase;

+  UINTN             StackTop;

+  UINTN             StackSize;

+} ;

+

+#define EBC_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \

+      CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE)

+

+

+#endif // #ifndef _EBC_INT_H_

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/EbcLowLevel.asm b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/EbcLowLevel.asm
new file mode 100644
index 0000000..b485bc9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/EbcLowLevel.asm
@@ -0,0 +1,148 @@
+  page    ,132

+  title   VM ASSEMBLY LANGUAGE ROUTINES

+;****************************************************************************

+;*                                                                         

+;*  Copyright (c) 2006, Intel Corporation                                                         

+;*  All rights reserved. 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.             

+;*                                                                          

+;****************************************************************************

+;****************************************************************************

+;                                   REV 1.0

+;****************************************************************************

+;

+; Rev  Date      Description

+; ---  --------  ------------------------------------------------------------

+; 1.0  03/14/01  Initial creation of file.

+;

+;****************************************************************************

+                             

+;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

+; This code provides low level routines that support the Virtual Machine

+; for option ROMs. 

+;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

+

+;---------------------------------------------------------------------------

+; Equate files needed.

+;---------------------------------------------------------------------------

+

+.XLIST

+

+.LIST

+

+;---------------------------------------------------------------------------

+; Assembler options

+;---------------------------------------------------------------------------

+

+.686p

+.model  flat        

+.code        

+;---------------------------------------------------------------------------

+;;GenericPostSegment      SEGMENT USE16

+;---------------------------------------------------------------------------

+

+;****************************************************************************

+; EbcLLCALLEXNative

+;

+; This function is called to execute an EBC CALLEX instruction

+; to native code. 

+; This instruction requires that we thunk out to external native

+; code. For IA32, we simply switch stacks and jump to the 

+; specified function. On return, we restore the stack pointer

+; to its original location.

+;

+; Destroys no working registers.

+;****************************************************************************

+; VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)

+_EbcLLCALLEXNative        PROC    NEAR    PUBLIC

+      push   ebp

+      mov    ebp, esp              ; standard function prolog

+      

+      ; Get function address in a register

+      ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]

+      mov    ecx, dword ptr [esp]+8

+

+      ; Set stack pointer to new value

+      ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]

+      mov    eax, dword ptr [esp] + 0Ch

+      mov    esp, eax      

+

+      ; Now call the external routine

+      call  ecx

+      

+      ; ebp is preserved by the callee. In this function it

+      ; equals the original esp, so set them equal

+      mov    esp, ebp

+

+      ; Standard function epilog

+      mov      esp, ebp

+      pop      ebp

+      ret

+_EbcLLCALLEXNative    ENDP

+

+

+; UINTN EbcLLGetEbcEntryPoint(VOID);

+; Routine Description:

+;   The VM thunk code stuffs an EBC entry point into a processor

+;   register. Since we can't use inline assembly to get it from

+;   the interpreter C code, stuff it into the return value 

+;   register and return.

+;

+; Arguments:

+;     None.

+;

+; Returns:

+;     The contents of the register in which the entry point is passed.

+;

+_EbcLLGetEbcEntryPoint        PROC    NEAR    PUBLIC

+    ret

+_EbcLLGetEbcEntryPoint    ENDP

+

+;/*++

+;

+;Routine Description:

+;  

+;  Return the caller's value of the stack pointer.

+;

+;Arguments:

+;

+;  None.

+;

+;Returns:

+;

+;  The current value of the stack pointer for the caller. We

+;  adjust it by 4 here because when they called us, the return address

+;  is put on the stack, thereby lowering it by 4 bytes.

+;

+;--*/

+

+; UINTN EbcLLGetStackPointer()            

+_EbcLLGetStackPointer        PROC    NEAR    PUBLIC

+    mov    eax, esp      ; get current stack pointer

+    add   eax, 4        ; stack adjusted by this much when we were called

+    ret

+_EbcLLGetStackPointer    ENDP

+

+; UINT64 EbcLLGetReturnValue(VOID);

+; Routine Description:

+;   When EBC calls native, on return the VM has to stuff the return

+;   value into a VM register. It's assumed here that the value is still

+;    in the register, so simply return and the caller should get the

+;   return result properly.

+;

+; Arguments:

+;     None.

+;

+; Returns:

+;     The unmodified value returned by the native code.

+;

+_EbcLLGetReturnValue   PROC    NEAR    PUBLIC

+    ret

+_EbcLLGetReturnValue    ENDP

+

+END

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/EbcSupport.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/EbcSupport.c
new file mode 100644
index 0000000..14059d7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/EbcSupport.c
@@ -0,0 +1,482 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EbcSupport.c

+

+Abstract:

+

+  This module contains EBC support routines that are customized based on

+  the target processor.

+

+--*/

+

+#include "EbcInt.h"

+#include "EbcExecute.h"

+

+//

+// NOTE: This is the stack size allocated for the interpreter

+//       when it executes an EBC image. The requirements can change

+//       based on whether or not a debugger is present, and other

+//       platform-specific configurations.

+//

+#define VM_STACK_SIZE   (1024 * 4)

+#define EBC_THUNK_SIZE  32

+

+VOID

+EbcLLCALLEX (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        FuncAddr,

+  IN UINTN        NewStackPointer,

+  IN VOID         *FramePtr,

+  IN UINT8        Size

+  )

+/*++

+

+Routine Description:

+

+  This function is called to execute an EBC CALLEX instruction. 

+  The function check the callee's content to see whether it is common native

+  code or a thunk to another piece of EBC code.

+  If the callee is common native code, use EbcLLCAllEXASM to manipulate,

+  otherwise, set the VM->IP to target EBC code directly to avoid another VM

+  be startup which cost time and stack space.

+  

+Arguments:

+

+  VmPtr             - Pointer to a VM context.

+  FuncAddr          - Callee's address

+  NewStackPointer   - New stack pointer after the call

+  FramePtr          - New frame pointer after the call

+  Size              - The size of call instruction

+

+Returns:

+

+  None.

+  

+--*/

+{

+  UINTN    IsThunk;

+  UINTN    TargetEbcAddr;

+

+  IsThunk       = 1;

+  TargetEbcAddr = 0;

+

+  //

+  // Processor specific code to check whether the callee is a thunk to EBC.

+  //

+  if (*((UINT8 *)FuncAddr) != 0xB8) {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 1) != 0xBC)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 2) != 0x2E)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 3) != 0x11)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 4) != 0xCA)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 5) != 0xB8)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 10) != 0xB9)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 15) != 0xFF)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 16) != 0xE1)  {

+    IsThunk = 0;

+    goto Action;

+  }

+

+  TargetEbcAddr = ((UINTN)(*((UINT8 *)FuncAddr + 9)) << 24) + ((UINTN)(*((UINT8 *)FuncAddr + 8)) << 16) +

+                    ((UINTN)(*((UINT8 *)FuncAddr + 7)) << 8) + ((UINTN)(*((UINT8 *)FuncAddr + 6)));

+

+Action:

+  if (IsThunk == 1){

+    //

+    // The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and

+    // put our return address and frame pointer on the VM stack.

+    // Then set the VM's IP to new EBC code.

+    //

+    VmPtr->R[0] -= 8;

+    VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);

+    VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];

+    VmPtr->R[0] -= 8;

+    VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (UINTN) (VmPtr->Ip + Size));

+

+    VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;

+  } else {

+    //

+    // The callee is not a thunk to EBC, call native code.

+    //

+    EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);

+    

+    //

+    // Get return value and advance the IP.

+    //

+    VmPtr->R[7] = EbcLLGetReturnValue ();

+    VmPtr->Ip += Size;

+  }

+}

+

+STATIC

+UINT64

+EbcInterpret (

+  IN OUT UINTN      Arg1,

+  IN OUT UINTN      Arg2,

+  IN OUT UINTN      Arg3,

+  IN OUT UINTN      Arg4,

+  IN OUT UINTN      Arg5,

+  IN OUT UINTN      Arg6,

+  IN OUT UINTN      Arg7,

+  IN OUT UINTN      Arg8

+  )

+/*++

+

+Routine Description:

+

+  Begin executing an EBC image. The address of the entry point is passed

+  in via a processor register, so we'll need to make a call to get the

+  value.

+  

+Arguments:

+

+  None. Since we're called from a fixed up thunk (which we want to keep

+  small), our only so-called argument is the EBC entry point passed in

+  to us in a processor register.

+

+Returns:

+

+  The value returned by the EBC application we're going to run.

+  

+--*/

+{

+  //

+  // Create a new VM context on the stack

+  //

+  VM_CONTEXT  VmContext;

+  UINTN       Addr;

+

+  //

+  // Get the EBC entry point from the processor register.

+  //

+  Addr = EbcLLGetEbcEntryPoint ();

+

+  //

+  // Now clear out our context

+  //

+  ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));

+

+  //

+  // Set the VM instruction pointer to the correct location in memory.

+  //

+  VmContext.Ip = (VMIP) Addr;

+

+  //

+  // Initialize the stack pointer for the EBC. Get the current system stack

+  // pointer and adjust it down by the max needed for the interpreter.

+  //

+  Addr            = EbcLLGetStackPointer ();

+

+  VmContext.R[0]  = (UINT64) Addr;

+  VmContext.R[0] -= VM_STACK_SIZE;

+

+  //

+  // Align the stack on a natural boundary

+  //

+  VmContext.R[0] &= ~(sizeof (UINTN) - 1);

+

+  //

+  // Put a magic value in the stack gap, then adjust down again

+  //

+  *(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;

+  VmContext.StackMagicPtr             = (UINTN *) (UINTN) VmContext.R[0];

+  VmContext.R[0] -= sizeof (UINTN);

+

+  //

+  // For IA32, this is where we say our return address is

+  //

+  VmContext.StackRetAddr  = (UINT64) VmContext.R[0];

+  VmContext.LowStackTop   = (UINTN) VmContext.R[0];

+

+  //

+  // We need to keep track of where the EBC stack starts. This way, if the EBC

+  // accesses any stack variables above its initial stack setting, then we know

+  // it's accessing variables passed into it, which means the data is on the

+  // VM's stack.

+  // When we're called, on the stack (high to low) we have the parameters, the

+  // return address, then the saved ebp. Save the pointer to the return address.

+  // EBC code knows that's there, so should look above it for function parameters.

+  // The offset is the size of locals (VMContext + Addr + saved ebp).

+  // Note that the interpreter assumes there is a 16 bytes of return address on

+  // the stack too, so adjust accordingly.

+  //  VmContext.HighStackBottom = (UINTN)(Addr + sizeof (VmContext) + sizeof (Addr));

+  //

+  VmContext.HighStackBottom = (UINTN) &Arg1 - 16;

+  //

+  // Begin executing the EBC code

+  //

+  EbcExecute (&VmContext);

+

+  //

+  // Return the value in R[7] unless there was an error

+  //

+  return (UINT64) VmContext.R[7];

+}

+

+STATIC

+UINT64

+ExecuteEbcImageEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Begin executing an EBC image. The address of the entry point is passed

+  in via a processor register, so we'll need to make a call to get the

+  value.

+  

+Arguments:

+

+  ImageHandle   - image handle for the EBC application we're executing

+  SystemTable   - standard system table passed into an driver's entry point

+

+Returns:

+

+  The value returned by the EBC application we're going to run.

+

+--*/

+{

+  //

+  // Create a new VM context on the stack

+  //

+  VM_CONTEXT  VmContext;

+  UINTN       Addr;

+

+  //

+  // Get the EBC entry point from the processor register. Make sure you don't

+  // call any functions before this or you could mess up the register the

+  // entry point is passed in.

+  //

+  Addr = EbcLLGetEbcEntryPoint ();

+

+  //

+  //  Print(L"*** Thunked into EBC entry point - ImageHandle = 0x%X\n", (UINTN)ImageHandle);

+  //  Print(L"EBC entry point is 0x%X\n", (UINT32)(UINTN)Addr);

+  //

+  // Now clear out our context

+  //

+  ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));

+

+  //

+  // Save the image handle so we can track the thunks created for this image

+  //

+  VmContext.ImageHandle = ImageHandle;

+  VmContext.SystemTable = SystemTable;

+

+  //

+  // Set the VM instruction pointer to the correct location in memory.

+  //

+  VmContext.Ip = (VMIP) Addr;

+

+  //

+  // Initialize the stack pointer for the EBC. Get the current system stack

+  // pointer and adjust it down by the max needed for the interpreter.

+  //

+  Addr            = EbcLLGetStackPointer ();

+  VmContext.R[0]  = (UINT64) Addr;

+  VmContext.R[0] -= VM_STACK_SIZE;

+  //

+  // Put a magic value in the stack gap, then adjust down again

+  //

+  *(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;

+  VmContext.StackMagicPtr             = (UINTN *) (UINTN) VmContext.R[0];

+  VmContext.R[0] -= sizeof (UINTN);

+

+  //

+  // Align the stack on a natural boundary

+  //  VmContext.R[0] &= ~(sizeof(UINTN) - 1);

+  //

+  VmContext.StackRetAddr  = (UINT64) VmContext.R[0];

+  VmContext.LowStackTop   = (UINTN) VmContext.R[0];

+  //

+  // VM pushes 16-bytes for return address. Simulate that here.

+  //

+  VmContext.HighStackBottom = (UINTN) &ImageHandle - 16;

+

+  //

+  // Begin executing the EBC code

+  //

+  EbcExecute (&VmContext);

+

+  //

+  // Return the value in R[7] unless there was an error

+  //

+  return (UINT64) VmContext.R[7];

+}

+

+EFI_STATUS

+EbcCreateThunks (

+  IN EFI_HANDLE           ImageHandle,

+  IN VOID                 *EbcEntryPoint,

+  OUT VOID                **Thunk,

+  IN  UINT32              Flags

+  )

+/*++

+

+Routine Description:

+

+  Create an IA32 thunk for the given EBC entry point.

+  

+Arguments:

+

+  ImageHandle     - Handle of image for which this thunk is being created

+  EbcEntryPoint   - Address of the EBC code that the thunk is to call

+  Thunk           - Returned thunk we create here

+

+Returns:

+

+  Standard EFI status.

+  

+--*/

+{

+  UINT8       *Ptr;

+  UINT8       *ThunkBase;

+  UINT32      I;

+  UINT32      Addr;

+  INT32       Size;

+  INT32       ThunkSize;

+  EFI_STATUS  Status;

+

+  //

+  // Check alignment of pointer to EBC code

+  //

+  if ((UINT32) (UINTN) EbcEntryPoint & 0x01) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Size      = EBC_THUNK_SIZE;

+  ThunkSize = Size;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  Size,

+                  (VOID *) &Ptr

+                  );

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  //  Print(L"Allocate TH: 0x%X\n", (UINT32)Ptr);

+  //

+  // Save the start address so we can add a pointer to it to a list later.

+  //

+  ThunkBase = Ptr;

+

+  //

+  // Give them the address of our buffer we're going to fix up

+  //

+  *Thunk = (VOID *) Ptr;

+

+  //

+  // Add a magic code here to help the VM recognize the thunk..

+  // mov eax, 0xca112ebc  => B8 BC 2E 11 CA

+  //

+  *Ptr = 0xB8;

+  Ptr++;

+  Size--;

+  Addr = (UINT32) 0xCA112EBC;

+  for (I = 0; I < sizeof (Addr); I++) {

+    *Ptr = (UINT8) (UINTN) Addr;

+    Addr >>= 8;

+    Ptr++;

+    Size--;

+  }

+

+  //

+  // Add code bytes to load up a processor register with the EBC entry point.

+  // mov eax, 0xaa55aa55  => B8 55 AA 55 AA

+  // The first 8 bytes of the thunk entry is the address of the EBC

+  // entry point.

+  //

+  *Ptr = 0xB8;

+  Ptr++;

+  Size--;

+  Addr = (UINT32) EbcEntryPoint;

+  for (I = 0; I < sizeof (Addr); I++) {

+    *Ptr = (UINT8) (UINTN) Addr;

+    Addr >>= 8;

+    Ptr++;

+    Size--;

+  }

+  //

+  // Stick in a load of ecx with the address of appropriate VM function.

+  //  mov ecx 12345678h  => 0xB9 0x78 0x56 0x34 0x12

+  //

+  if (Flags & FLAG_THUNK_ENTRY_POINT) {

+    Addr = (UINT32) (UINTN) ExecuteEbcImageEntryPoint;

+  } else {

+    Addr = (UINT32) (UINTN) EbcInterpret;

+  }

+

+  //

+  // MOV ecx

+  //

+  *Ptr = 0xB9;

+  Ptr++;

+  Size--;

+  for (I = 0; I < sizeof (Addr); I++) {

+    *Ptr = (UINT8) Addr;

+    Addr >>= 8;

+    Ptr++;

+    Size--;

+  }

+  //

+  // Stick in jump opcode bytes for jmp ecx => 0xFF 0xE1

+  //

+  *Ptr = 0xFF;

+  Ptr++;

+  Size--;

+  *Ptr = 0xE1;

+  Size--;

+

+  //

+  // Double check that our defined size is ok (application error)

+  //

+  if (Size < 0) {

+    ASSERT (FALSE);

+    return EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // Add the thunk to the list for this image. Do this last since the add

+  // function flushes the cache for us.

+  //

+  EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/Ia32Math.asm b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/Ia32Math.asm
new file mode 100644
index 0000000..4c91a27
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ia32/Ia32Math.asm
@@ -0,0 +1,622 @@
+  TITLE   Ia32math.asm: Generic math routines for EBC interpreter running on IA32 processor

+

+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation                                                         

+; All rights reserved. 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.             

+; 

+; Module Name:

+;

+;   Ia32math.asm

+; 

+; Abstract:

+; 

+;   Generic math routines for EBC interpreter running on IA32 processor

+;

+;------------------------------------------------------------------------------

+

+  .686P

+  .XMM

+  .MODEL SMALL

+  .CODE

+

+LeftShiftU64  PROTO C  Operand:  QWORD, CountIn: QWORD

+RightShiftU64 PROTO C  Operand:  QWORD, CountIn: QWORD

+ARightShift64 PROTO C  Operand:  QWORD, CountIn: QWORD

+MulU64x64     PROTO C  Value1:   QWORD, Value2:  QWORD, ResultHigh: DWORD

+MulS64x64     PROTO C  Value1:   QWORD, Value2:  QWORD, ResultHigh: DWORD

+DivU64x64     PROTO C  Dividend: QWORD, Divisor: QWORD, Remainder:  DWORD, Error: DWORD

+DivS64x64     PROTO C  Dividend: QWORD, Divisor: QWORD, Remainder:  DWORD, Error: DWORD

+

+  

+LeftShiftU64 PROC C Operand: QWORD, CountIn: QWORD

+

+;------------------------------------------------------------------------------

+; UINT64

+; LeftShiftU64 (

+;   IN UINT64   Operand,

+;   IN UINT64   CountIn

+;   )

+;

+; Routine Description:

+;  

+;   Left-shift a 64-bit value.

+;

+; Arguments:

+;

+;   Operand - the value to shift

+;   Count   - shift count

+;

+; Returns:

+;

+;   Operand << Count

+;------------------------------------------------------------------------------

+

+  push   ecx

+  ;

+  ; if (CountIn > 63) return 0;

+  ;

+  cmp    dword ptr CountIn[4], 0

+  jne    _LeftShiftU64_Overflow

+  mov    ecx, dword ptr CountIn[0]

+  cmp    ecx, 63

+  jbe    _LeftShiftU64_Calc

+  

+_LeftShiftU64_Overflow:

+  xor    eax, eax

+  xor    edx, edx

+  jmp    _LeftShiftU64_Done

+  

+_LeftShiftU64_Calc:

+  mov    eax, dword ptr Operand[0]

+  mov    edx, dword ptr Operand[4]

+  

+  shld   edx, eax, cl

+  shl    eax, cl

+  cmp    ecx, 32

+  jc     short _LeftShiftU64_Done

+  

+  mov    edx, eax

+  xor    eax, eax

+  

+_LeftShiftU64_Done:

+  pop    ecx

+  ret

+

+LeftShiftU64 ENDP

+

+

+RightShiftU64 PROC C Operand: QWORD, CountIn: QWORD

+

+;------------------------------------------------------------------------------

+; UINT64

+; RightShiftU64 (

+;   IN UINT64   Operand,

+;   IN UINT64   CountIn

+;   )

+;

+; Routine Description:

+;  

+;   Right-shift an unsigned 64-bit value.

+;

+; Arguments:

+;

+;   Operand - the value to shift

+;   Count   - shift count

+;

+; Returns:

+;

+;   Operand >> Count

+;------------------------------------------------------------------------------

+

+  push   ecx

+  ;

+  ; if (CountIn > 63) return 0;

+  ;

+  cmp    dword ptr CountIn[4], 0

+  jne    _RightShiftU64_Overflow

+  mov    ecx, dword ptr CountIn[0]

+  cmp    ecx, 63

+  jbe    _RightShiftU64_Calc

+  

+_RightShiftU64_Overflow:

+  xor    eax, eax

+  xor    edx, edx

+  jmp    _RightShiftU64_Done

+  

+_RightShiftU64_Calc:

+  mov    eax, dword ptr Operand[0]

+  mov    edx, dword ptr Operand[4]

+  

+  shrd   edx, eax, cl

+  shr    eax, cl

+  cmp    ecx, 32

+  jc     short _RightShiftU64_Done

+  

+  mov    eax, edx

+  xor    edx, edx

+  

+_RightShiftU64_Done:

+  pop    ecx

+  ret

+

+RightShiftU64 ENDP

+

+

+ARightShift64 PROC C Operand: QWORD, CountIn: QWORD

+

+;------------------------------------------------------------------------------

+; INT64

+; ARightShift64 (

+;   IN INT64  Operand,

+;   IN UINT64 CountIn

+;   )

+;

+; Routine Description:

+;  

+;   Arithmatic shift a 64 bit signed value.

+;

+; Arguments:

+;

+;   Operand - the value to shift

+;   Count   - shift count

+;

+; Returns:

+;

+;  Operand >> Count

+;------------------------------------------------------------------------------

+

+  push   ecx

+  ;

+  ; If they exceeded the max shift count, then return either 0 or all F's

+  ; depending on the sign bit.

+  ;

+  cmp    dword ptr CountIn[4], 0

+  jne    _ARightShiftU64_Overflow

+  mov    ecx, dword ptr CountIn[0]

+  cmp    ecx, 63

+  jbe    _ARightShiftU64_Calc

+  

+_ARightShiftU64_Overflow:

+  ;

+  ; Check the sign bit of Operand

+  ;

+  bt     dword ptr Operand[4], 31

+  jnc    _ARightShiftU64_Return_Zero

+  ;

+  ; return -1

+  ;

+  or     eax, 0FFFFFFFFh

+  or     edx, 0FFFFFFFFh

+  jmp    _ARightShiftU64_Done

+

+_ARightShiftU64_Return_Zero:

+  xor    eax, eax

+  xor    edx, edx

+  jmp    _ARightShiftU64_Done

+  

+_ARightShiftU64_Calc:

+  mov    eax, dword ptr Operand[0]

+  mov    edx, dword ptr Operand[4]

+

+  shrd   eax, edx, cl

+  sar    edx, cl

+  cmp    ecx, 32

+  jc     short _ARightShiftU64_Done

+

+  ;

+  ; if ecx >= 32, then eax = edx, and edx = sign bit

+  ;

+  mov    eax, edx

+  sar    edx, 31

+

+_ARightShiftU64_Done:

+  pop    ecx

+  ret

+

+ARightShift64 ENDP

+

+

+MulU64x64 PROC C  Value1: QWORD, Value2: QWORD, ResultHigh: DWORD

+

+;------------------------------------------------------------------------------

+; UINT64 

+; MulU64x64 (

+;   UINT64 Value1, 

+;   UINT64 Value2, 

+;   UINT64 *ResultHigh

+;   )

+;

+; Routine Description:

+; 

+;   Multiply two unsigned 64-bit values.

+;

+; Arguments:

+;

+;   Value1      - first value to multiply

+;   Value2      - value to multiply by Value1

+;   ResultHigh  - result to flag overflows

+;

+; Returns:

+; 

+;   Value1 * Value2

+;   The 128-bit result is the concatenation of *ResultHigh and the return value 

+;------------------------------------------------------------------------------

+

+  push   ebx

+  push   ecx

+  mov    ebx, ResultHigh           ; ebx points to the high 4 words of result

+  ;

+  ; The result consists of four double-words.

+  ; Here we assume their names from low to high: dw0, dw1, dw2, dw3

+  ;

+  mov    eax, dword ptr Value1[0]

+  mul    dword ptr Value2[0]

+  push   eax                       ; eax contains final result of dw0, push it

+  mov    ecx, edx                  ; ecx contains partial result of dw1

+  

+  mov    eax, dword ptr Value1[4]

+  mul    dword ptr Value2[0]

+  add    ecx, eax                  ; add eax to partial result of dw1

+  adc    edx, 0    

+  mov    dword ptr [ebx], edx      ; lower double-word of ResultHigh contains partial result of dw2

+    

+  mov    eax, dword ptr Value1[0]

+  mul    dword ptr Value2[4]

+  add    ecx, eax                  ; add eax to partial result of dw1

+  push   ecx                      ; ecx contains final result of dw1, push it

+  adc    edx, 0

+  mov    ecx, edx                  ; ecx contains partial result of dw2, together with ResultHigh

+

+  mov    eax, dword ptr Value1[4]

+  mul    dword ptr Value2[4]

+  add    ecx, eax                  ; add eax to partial result of dw2

+  adc    edx, 0

+  add    dword ptr [ebx], ecx      ; lower double-word of ResultHigh contains final result of dw2

+  adc    edx, 0

+  mov    dword ptr [ebx + 4], edx  ; high double-word of ResultHigh contains final result of dw3

+    

+  pop    edx                       ; edx contains the final result of dw1

+  pop    eax                       ; edx contains the final result of dw0

+  pop    ecx

+  pop    ebx

+  ret

+

+MulU64x64 ENDP

+

+

+MulS64x64  PROC C  Value1: QWORD, Value2: QWORD, ResultHigh: DWORD

+

+;------------------------------------------------------------------------------

+; INT64

+; MulS64x64 (

+;   INT64 Value1,

+;   INT64 Value2,

+;   INT64 *ResultHigh

+;   )

+;

+; Routine Description:

+;  

+;   Multiply two signed 64-bit values.

+;

+; Arguments:

+;

+;   Value1      - first value to multiply

+;   Value2      - value to multiply by Value1

+;   ResultHigh  - result to flag overflows

+;

+; Returns:

+;

+;   Value1 * Value2

+;   The 128-bit result is the concatenation of *ResultHigh and the return value 

+;------------------------------------------------------------------------------

+

+  push   ebx

+  push   ecx

+  mov    ebx, ResultHigh           ; ebx points to the high 4 words of result

+  xor    ecx, ecx                 ; the lowest bit of ecx flags the sign

+    

+  mov    edx, dword ptr Value1[4]

+  bt     edx, 31

+  jnc    short _MulS64x64_A_Positive

+  ;

+  ; a is negative

+  ;

+  mov    eax, dword ptr Value1[0]

+  not    edx

+  not    eax

+  add    eax, 1

+  adc    edx, 0

+  mov    dword ptr Value1[0], eax

+  mov    dword ptr Value1[4], edx

+  btc    ecx, 0

+    

+_MulS64x64_A_Positive:

+  mov    edx, dword ptr Value2[4]

+  bt     edx, 31

+  jnc    short _MulS64x64_B_Positive

+  ;

+  ; b is negative

+  ;

+  mov    eax, dword ptr Value2[0]

+  not    edx

+  not    eax

+  add    eax, 1

+  adc    edx, 0

+  mov    dword ptr Value2[0], eax

+  mov    dword ptr Value2[4], edx

+  btc    ecx, 0

+    

+_MulS64x64_B_Positive:

+  invoke MulU64x64, Value1, Value2, ResultHigh

+  bt     ecx, 0

+  jnc    short _MulS64x64_Done

+  ;

+  ;negate the result

+  ;

+  not    eax

+  not    edx

+  not    dword ptr [ebx]

+  not    dword ptr [ebx + 4]

+  add    eax, 1

+  adc    edx, 0

+  adc    dword ptr [ebx], 0

+  adc    dword ptr [ebx + 4], 0

+    

+_MulS64x64_Done:

+  pop    ecx

+  pop    ebx

+  ret

+

+MulS64x64 ENDP

+

+

+DivU64x64 PROC C  Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD, 

+

+;------------------------------------------------------------------------------

+; UINT64

+; DivU64x64 (

+;   IN  UINT64   Dividend,

+;   IN  UINT64   Divisor,

+;   OUT UINT64   *Remainder OPTIONAL,

+;   OUT UINT32   *Error

+;   )

+;

+; Routine Description:

+; 

+;   This routine allows a 64 bit value to be divided with a 64 bit value returns 

+;   64bit result and the Remainder

+;

+; Arguments:

+;

+;   Dividend    - dividend

+;   Divisor     - divisor

+;   ResultHigh  - result to flag overflows

+;   Error       - flag for error

+;

+; Returns:

+; 

+;   Dividend / Divisor

+;   Remainder = Dividend mod Divisor

+;------------------------------------------------------------------------------

+

+  push   ecx

+  

+  mov    eax, Error

+  mov    dword ptr [eax], 0 

+  

+  cmp    dword ptr Divisor[0], 0

+  jne    _DivU64x64_Valid

+  cmp    dword ptr Divisor[4], 0

+  jne    _DivU64x64_Valid

+  ;

+  ; the divisor is zero

+  ;

+  mov    dword ptr [eax], 1 

+  cmp    Remainder, 0

+  je     _DivU64x64_Invalid_Return

+  ;

+  ; fill the remainder if the pointer is not null

+  ;

+  mov    eax, Remainder

+  mov    dword ptr [eax], 0

+  mov    dword ptr [eax + 4], 80000000h

+  

+_DivU64x64_Invalid_Return:

+  xor    eax, eax

+  mov    edx, 80000000h

+  jmp    _DivU64x64_Done

+

+_DivU64x64_Valid:

+  ;

+  ; let edx and eax contain the intermediate result of remainder

+  ;

+  xor    edx, edx

+  xor    eax, eax

+  mov    ecx, 64

+  

+_DivU64x64_Wend:

+  ;

+  ; shift dividend left one

+  ;

+  shl    dword ptr Dividend[0], 1

+  rcl    dword ptr Dividend[4], 1    

+  ;

+  ; rotate intermediate result of remainder left one

+  ;

+  rcl    eax, 1

+  rcl    edx, 1 

+  

+  cmp    edx, dword ptr Divisor[4]

+  ja     _DivU64x64_Sub_Divisor

+  jb     _DivU64x64_Cont

+  cmp    eax, dword ptr Divisor[0]

+  jb     _DivU64x64_Cont

+  

+_DivU64x64_Sub_Divisor:

+  ;

+  ; If intermediate result of remainder is larger than

+  ; or equal to divisor, then set the lowest bit of dividend,

+  ; and subtract divisor from intermediate remainder

+  ;

+  bts    dword ptr Dividend[0], 0

+  sub    eax, dword ptr Divisor[0]

+  sbb    edx, dword ptr Divisor[4]

+  

+_DivU64x64_Cont:

+  loop   _DivU64x64_Wend

+  

+  cmp    Remainder, 0

+  je     _DivU64x64_Assign

+  mov    ecx, Remainder

+  mov    dword ptr [ecx], eax

+  mov    dword ptr [ecx + 4], edx

+ 

+_DivU64x64_Assign:

+  mov    eax, dword ptr Dividend[0]

+  mov    edx, dword ptr Dividend[4]

+  

+_DivU64x64_Done:

+  pop    ecx

+  ret

+  

+DivU64x64 ENDP

+

+DivS64x64 PROC C  Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD, 

+

+;------------------------------------------------------------------------------

+; INT64

+; DivU64x64 (

+;   IN  INT64   Dividend,

+;   IN  INT64   Divisor,

+;   OUT UINT64   *Remainder OPTIONAL,

+;   OUT UINT32   *Error

+;   )

+;

+; Routine Description:

+; 

+;   This routine allows a 64 bit signed value to be divided with a 64 bit 

+;   signed value returns 64bit result and the Remainder.

+;

+; Arguments:

+;

+;   Dividend    - dividend

+;   Divisor     - divisor

+;   ResultHigh  - result to flag overflows

+;   Error       - flag for error

+;

+; Returns:

+; 

+;   Dividend / Divisor

+;   Remainder = Dividend mod Divisor

+;------------------------------------------------------------------------------

+

+  push   ecx

+  

+  mov    eax, Error

+  mov    dword ptr [eax], 0 

+  

+  cmp    dword ptr Divisor[0], 0

+  jne    _DivS64x64_Valid

+  cmp    dword ptr Divisor[4], 0

+  jne    _DivS64x64_Valid

+  ;

+  ; the divisor is zero

+  ;

+  mov    dword ptr [eax], 1 

+  cmp    Remainder, 0

+  je     _DivS64x64_Invalid_Return

+  ;

+  ; fill the remainder if the pointer is not null

+  ;

+  mov    eax, Remainder

+  mov    dword ptr [eax], 0

+  mov    dword ptr [eax + 4], 80000000h

+  

+_DivS64x64_Invalid_Return:

+  xor    eax, eax

+  mov    edx, 80000000h

+  jmp    _DivS64x64_Done

+

+_DivS64x64_Valid:

+  ;

+  ; The lowest bit of ecx flags the sign of quotient,

+  ; The seconde lowest bit flags the sign of remainder

+  ;

+  xor    ecx, ecx                 

+  

+  mov    edx, dword ptr Dividend[4]

+  bt     edx, 31

+  jnc    short _DivS64x64_Dividend_Positive

+  ;

+  ; dividend is negative

+  ;

+  mov    eax, dword ptr Dividend[0]

+  not    edx

+  not    eax

+  add    eax, 1

+  adc    edx, 0

+  mov    dword ptr Dividend[0], eax

+  mov    dword ptr Dividend[4], edx

+  ;

+  ; set both the flags for signs of quotient and remainder

+  ;

+  btc    ecx, 0

+  btc    ecx, 1

+    

+_DivS64x64_Dividend_Positive:

+  mov    edx, dword ptr Divisor[4]

+  bt     edx, 31

+  jnc    short _DivS64x64_Divisor_Positive

+  ;

+  ; divisor is negative

+  ;

+  mov    eax, dword ptr Divisor[0]

+  not    edx

+  not    eax

+  add    eax, 1

+  adc    edx, 0

+  mov    dword ptr Divisor[0], eax

+  mov    dword ptr Divisor[4], edx

+  ;

+  ; just complement the flag for sign of quotient

+  ;

+  btc    ecx, 0

+    

+_DivS64x64_Divisor_Positive:

+  invoke DivU64x64, Dividend, Divisor, Remainder, Error

+  bt     ecx, 0

+  jnc    short _DivS64x64_Remainder

+  ;

+  ; negate the quotient

+  ;

+  not    eax

+  not    edx

+  add    eax, 1

+  adc    edx, 0

+    

+_DivS64x64_Remainder:

+  bt     ecx, 1

+  jnc    short _DivS64x64_Done

+  ;

+  ; negate the remainder

+  ;

+  mov    ecx, remainder

+  not    dword ptr [ecx]

+  not    dword ptr [ecx + 4]

+  add    dword ptr [ecx], 1

+  adc    dword ptr [ecx + 4], 0

+  

+_DivS64x64_Done:

+  pop    ecx

+  ret

+

+DivS64x64 ENDP

+

+END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/EbcLowLevel.s b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/EbcLowLevel.s
new file mode 100644
index 0000000..fe2ca3f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/EbcLowLevel.s
@@ -0,0 +1,167 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   EbcLowLevel.s

+//

+// Abstract:

+//

+//   Contains low level routines for the Virtual Machine implementation

+//   on an Itanium-based platform.

+//

+//

+//--

+

+.file  "EbcLowLevel.s"

+

+#define PROCEDURE_ENTRY(name)   .##text;            \

+                                .##type name, @function;    \

+                                .##proc name;           \

+name::

+

+#define PROCEDURE_EXIT(name)    .##endp name

+

+// Note: use of NESTED_SETUP requires number of locals (l) >= 3

+

+#define NESTED_SETUP(i,l,o,r) \

+         alloc loc1=ar##.##pfs,i,l,o,r ;\

+         mov loc0=b0

+

+#define NESTED_RETURN \

+         mov b0=loc0 ;\

+         mov ar##.##pfs=loc1 ;;\

+         br##.##ret##.##dpnt  b0;;

+

+

+//-----------------------------------------------------------------------------

+//++

+// EbcAsmLLCALLEX

+//

+//  Implements the low level EBC CALLEX instruction. Sets up the

+//  stack pointer, does the spill of function arguments, and

+//  calls the native function. On return it restores the original

+//  stack pointer and returns to the caller.

+//

+// Arguments : 

+//

+// On Entry :

+//    in0 = Address of native code to call

+//    in1 = New stack pointer

+//

+// Return Value: 

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+;// void EbcAsmLLCALLEX (UINTN FunctionAddr, UINTN EbcStackPointer)

+PROCEDURE_ENTRY(EbcAsmLLCALLEX)

+  NESTED_SETUP (2,6,8,0)

+

+  // NESTED_SETUP uses loc0 and loc1 for context save

+

+  //

+  // Save a copy of the EBC VM stack pointer

+  //

+  mov r8 = in1;;

+

+  //

+  // Copy stack arguments from EBC stack into registers. 

+  // Assume worst case and copy 8.

+  //

+  ld8   out0 = [r8], 8;;

+  ld8   out1 = [r8], 8;;

+  ld8   out2 = [r8], 8;;

+  ld8   out3 = [r8], 8;;

+  ld8   out4 = [r8], 8;;

+  ld8   out5 = [r8], 8;;

+  ld8   out6 = [r8], 8;;

+  ld8   out7 = [r8], 8;;

+

+  //

+  // Save the original stack pointer

+  //

+  mov   loc2 = r12;

+

+  //

+  // Save the gp

+  //

+  or    loc3 = r1, r0

+

+  //

+  // Set the new aligned stack pointer. Reserve space for the required 

+  // 16-bytes of scratch area as well.

+  //

+  add  r12 = 48, in1

+

+  //

+  // Now call the function. Load up the function address from the descriptor

+  // pointed to by in0. Then get the gp from the descriptor at the following

+  // address in the descriptor.

+  //

+  ld8   r31 = [in0], 8;;

+  ld8   r30 = [in0];;

+  mov   b1 = r31

+  mov   r1 = r30

+  (p0) br.call.dptk.many b0 = b1;;

+

+  //

+  // Restore the original stack pointer and gp

+  //

+  mov   r12 = loc2

+  or    r1 = loc3, r0

+

+  //

+  // Now return

+  //

+  NESTED_RETURN

+

+PROCEDURE_EXIT(EbcAsmLLCALLEX)

+

+//

+// UINTN EbcLLGetEbcEntryPoint(VOID)

+//

+// Description:

+//    Simply return, so that the caller retrieves the return register

+//    contents (R8). That's where the thunk-to-ebc code stuffed the

+//    EBC entry point.

+//

+PROCEDURE_ENTRY(EbcLLGetEbcEntryPoint)

+    br.ret.sptk  b0 ;;

+PROCEDURE_EXIT(EbcLLGetEbcEntryPoint)

+

+//

+// INT64 EbcLLGetReturnValue(VOID)

+//

+// Description:

+//    This function is called to get the value returned by native code

+//     to EBC. It simply returns because the return value should still

+//    be in the register, so the caller just gets the unmodified value.

+//

+PROCEDURE_ENTRY(EbcLLGetReturnValue)

+    br.ret.sptk  b0 ;;

+PROCEDURE_EXIT(EbcLLGetReturnValue)

+

+//

+// UINTN EbcLLGetStackPointer(VOID)

+//

+PROCEDURE_ENTRY(EbcLLGetStackPointer)

+    mov    r8 = r12 ;;

+    br.ret.sptk  b0 ;;

+    br.sptk.few b6 

+PROCEDURE_EXIT(EbcLLGetStackPointer)

+

+

+

+

+

+

+

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/EbcSupport.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/EbcSupport.c
new file mode 100644
index 0000000..50402aa
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/EbcSupport.c
@@ -0,0 +1,906 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EbcSupport.c

+

+Abstract:

+

+  This module contains EBC support routines that are customized based on

+  the target processor.

+

+--*/

+

+#include "EbcInt.h"

+#include "EbcExecute.h"

+

+#define VM_STACK_SIZE   (1024 * 32)

+

+#define EBC_THUNK_SIZE  128

+

+//

+// For code execution, thunks must be aligned on 16-byte boundary

+//

+#define EBC_THUNK_ALIGNMENT 16

+

+//

+// Per the IA-64 Software Conventions and Runtime Architecture Guide,

+// section 3.3.4, IPF stack must always be 16-byte aligned.

+//

+#define IPF_STACK_ALIGNMENT 16

+

+//

+// Opcodes for IPF instructions. We'll need to hand-create thunk code (stuffing

+// bits) to insert a jump to the interpreter.

+//

+#define OPCODE_NOP              (UINT64) 0x00008000000

+#define OPCODE_BR_COND_SPTK_FEW (UINT64) 0x00100000000

+#define OPCODE_MOV_BX_RX        (UINT64) 0x00E00100000

+

+//

+// Opcode for MOVL instruction

+//

+#define MOVL_OPCODE 0x06

+

+VOID

+EbcAsmLLCALLEX (

+  IN UINTN    CallAddr,

+  IN UINTN    EbcSp

+  );

+

+STATIC

+EFI_STATUS

+WriteBundle (

+  IN    VOID    *MemPtr,

+  IN    UINT8   Template,

+  IN    UINT64  Slot0,

+  IN    UINT64  Slot1,

+  IN    UINT64  Slot2

+  );

+

+STATIC

+VOID

+PushU64 (

+  VM_CONTEXT *VmPtr,

+  UINT64     Arg

+  )

+{

+  //

+  // Advance the VM stack down, and then copy the argument to the stack.

+  // Hope it's aligned.

+  //

+  VmPtr->R[0] -= sizeof (UINT64);

+  *(UINT64 *) VmPtr->R[0] = Arg;

+}

+

+UINT64

+EbcInterpret (

+  UINT64      Arg1,

+  ...

+  )

+{

+  //

+  // Create a new VM context on the stack

+  //

+  VM_CONTEXT  VmContext;

+  UINTN       Addr;

+  VA_LIST     List;

+  UINT64      Arg2;

+  UINT64      Arg3;

+  UINT64      Arg4;

+  UINT64      Arg5;

+  UINT64      Arg6;

+  UINT64      Arg7;

+  UINT64      Arg8;

+  UINTN       Arg9Addr;

+  //

+  // Get the EBC entry point from the processor register. Make sure you don't

+  // call any functions before this or you could mess up the register the

+  // entry point is passed in.

+  //

+  Addr = EbcLLGetEbcEntryPoint ();

+  //

+  // Need the args off the stack.

+  //

+  VA_START (List, Arg1);

+  Arg2      = VA_ARG (List, UINT64);

+  Arg3      = VA_ARG (List, UINT64);

+  Arg4      = VA_ARG (List, UINT64);

+  Arg5      = VA_ARG (List, UINT64);

+  Arg6      = VA_ARG (List, UINT64);

+  Arg7      = VA_ARG (List, UINT64);

+  Arg8      = VA_ARG (List, UINT64);

+  Arg9Addr  = (UINTN) List;

+  //

+  // Now clear out our context

+  //

+  ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));

+  //

+  // Set the VM instruction pointer to the correct location in memory.

+  //

+  VmContext.Ip = (VMIP) Addr;

+  //

+  // Initialize the stack pointer for the EBC. Get the current system stack

+  // pointer and adjust it down by the max needed for the interpreter.

+  //

+  Addr = (UINTN) Arg9Addr;

+  //

+  // NOTE: Eventually we should have the interpreter allocate memory

+  //       for stack space which it will use during its execution. This

+  //       would likely improve performance because the interpreter would

+  //       no longer be required to test each memory access and adjust

+  //       those reading from the stack gap.

+  //

+  // For IPF, the stack looks like (assuming 10 args passed)

+  //   arg10

+  //   arg9       (Bottom of high stack)

+  //   [ stack gap for interpreter execution ]

+  //   [ magic value for detection of stack corruption ]

+  //   arg8       (Top of low stack)

+  //   arg7....

+  //   arg1

+  //   [ 64-bit return address ]

+  //   [ ebc stack ]

+  // If the EBC accesses memory in the stack gap, then we assume that it's

+  // actually trying to access args9 and greater. Therefore we need to

+  // adjust memory accesses in this region to point above the stack gap.

+  //

+  VmContext.HighStackBottom = (UINTN) Addr;

+  //

+  // Now adjust the EBC stack pointer down to leave a gap for interpreter

+  // execution. Then stuff a magic value there.

+  //

+  VmContext.R[0] = (UINT64) Addr;

+  VmContext.R[0] -= VM_STACK_SIZE;

+  PushU64 (&VmContext, (UINT64) VM_STACK_KEY_VALUE);

+  VmContext.StackMagicPtr = (UINTN *) VmContext.R[0];

+  VmContext.LowStackTop   = (UINTN) VmContext.R[0];

+  //

+  // Push the EBC arguments on the stack. Does not matter that they may not

+  // all be valid.

+  //

+  PushU64 (&VmContext, Arg8);

+  PushU64 (&VmContext, Arg7);

+  PushU64 (&VmContext, Arg6);

+  PushU64 (&VmContext, Arg5);

+  PushU64 (&VmContext, Arg4);

+  PushU64 (&VmContext, Arg3);

+  PushU64 (&VmContext, Arg2);

+  PushU64 (&VmContext, Arg1);

+  //

+  // Push a bogus return address on the EBC stack because the

+  // interpreter expects one there. For stack alignment purposes on IPF,

+  // EBC return addresses are always 16 bytes. Push a bogus value as well.

+  //

+  PushU64 (&VmContext, 0);

+  PushU64 (&VmContext, 0xDEADBEEFDEADBEEF);

+  VmContext.StackRetAddr = (UINT64) VmContext.R[0];

+  //

+  // Begin executing the EBC code

+  //

+  EbcExecute (&VmContext);

+  //

+  // Return the value in R[7] unless there was an error

+  //

+  return (UINT64) VmContext.R[7];

+}

+

+UINT64

+ExecuteEbcImageEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  IPF implementation.

+

+  Begin executing an EBC image. The address of the entry point is passed

+  in via a processor register, so we'll need to make a call to get the

+  value.

+  

+Arguments:

+

+  ImageHandle   - image handle for the EBC application we're executing

+  SystemTable   - standard system table passed into an driver's entry point

+

+Returns:

+

+  The value returned by the EBC application we're going to run.

+

+--*/

+{

+  //

+  // Create a new VM context on the stack

+  //

+  VM_CONTEXT  VmContext;

+  UINTN       Addr;

+

+  //

+  // Get the EBC entry point from the processor register. Make sure you don't

+  // call any functions before this or you could mess up the register the

+  // entry point is passed in.

+  //

+  Addr = EbcLLGetEbcEntryPoint ();

+

+  //

+  // Now clear out our context

+  //

+  ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));

+

+  //

+  // Save the image handle so we can track the thunks created for this image

+  //

+  VmContext.ImageHandle = ImageHandle;

+  VmContext.SystemTable = SystemTable;

+

+  //

+  // Set the VM instruction pointer to the correct location in memory.

+  //

+  VmContext.Ip = (VMIP) Addr;

+

+  //

+  // Get the stack pointer. This is the bottom of the upper stack.

+  //

+  Addr                      = EbcLLGetStackPointer ();

+  VmContext.HighStackBottom = (UINTN) Addr;

+  VmContext.R[0]            = (INT64) Addr;

+

+  //

+  // Allocate stack space for the interpreter. Then put a magic value

+  // at the bottom so we can detect stack corruption.

+  //

+  VmContext.R[0] -= VM_STACK_SIZE;

+  PushU64 (&VmContext, (UINT64) VM_STACK_KEY_VALUE);

+  VmContext.StackMagicPtr = (UINTN *) (UINTN) VmContext.R[0];

+

+  //

+  // When we thunk to external native code, we copy the last 8 qwords from

+  // the EBC stack into the processor registers, and adjust the stack pointer

+  // up. If the caller is not passing 8 parameters, then we've moved the

+  // stack pointer up into the stack gap. If this happens, then the caller

+  // can mess up the stack gap contents (in particular our magic value).

+  // Therefore, leave another gap below the magic value. Pick 10 qwords down,

+  // just as a starting point.

+  //

+  VmContext.R[0] -= 10 * sizeof (UINT64);

+

+  //

+  // Align the stack pointer such that after pushing the system table,

+  // image handle, and return address on the stack, it's aligned on a 16-byte

+  // boundary as required for IPF.

+  //

+  VmContext.R[0] &= (INT64)~0x0f;

+  VmContext.LowStackTop = (UINTN) VmContext.R[0];

+  //

+  // Simply copy the image handle and system table onto the EBC stack.

+  // Greatly simplifies things by not having to spill the args

+  //

+  PushU64 (&VmContext, (UINT64) SystemTable);

+  PushU64 (&VmContext, (UINT64) ImageHandle);

+

+  //

+  // Interpreter assumes 64-bit return address is pushed on the stack.

+  // IPF does not do this so pad the stack accordingly. Also, a

+  // "return address" is 16 bytes as required for IPF stack alignments.

+  //

+  PushU64 (&VmContext, (UINT64) 0);

+  PushU64 (&VmContext, (UINT64) 0x1234567887654321);

+  VmContext.StackRetAddr = (UINT64) VmContext.R[0];

+

+  //

+  // Begin executing the EBC code

+  //

+  EbcExecute (&VmContext);

+

+  //

+  // Return the value in R[7] unless there was an error

+  //

+  return (UINT64) VmContext.R[7];

+}

+

+EFI_STATUS

+EbcCreateThunks (

+  IN EFI_HANDLE   ImageHandle,

+  IN VOID         *EbcEntryPoint,

+  OUT VOID        **Thunk,

+  IN  UINT32      Flags

+  )

+/*++

+

+Routine Description:

+

+  Create thunks for an EBC image entry point, or an EBC protocol service.

+  

+Arguments:

+

+  ImageHandle     - Image handle for the EBC image. If not null, then we're

+                    creating a thunk for an image entry point.

+  EbcEntryPoint   - Address of the EBC code that the thunk is to call

+  Thunk           - Returned thunk we create here

+  Flags           - Flags indicating options for creating the thunk

+  

+Returns:

+

+  Standard EFI status.

+  

+--*/

+{

+  UINT8       *Ptr;

+  UINT8       *ThunkBase;

+  UINT64      Addr;

+  UINT64        Code[3];    // Code in a bundle

+  UINT64        RegNum;     // register number for MOVL

+  UINT64        I;          // bits of MOVL immediate data

+  UINT64        Ic;         // bits of MOVL immediate data

+  UINT64        Imm5c;      // bits of MOVL immediate data

+  UINT64        Imm9d;      // bits of MOVL immediate data

+  UINT64        Imm7b;      // bits of MOVL immediate data

+  UINT64        Br;         // branch register for loading and jumping

+  UINT64      *Data64Ptr;

+  UINT32      ThunkSize;

+  UINT32      Size;

+  EFI_STATUS  Status;

+

+  //

+  // Check alignment of pointer to EBC code, which must always be aligned

+  // on a 2-byte boundary.

+  //

+  if ((UINT32) (UINTN) EbcEntryPoint & 0x01) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Allocate memory for the thunk. Make the (most likely incorrect) assumption

+  // that the returned buffer is not aligned, so round up to the next

+  // alignment size.

+  //

+  Size      = EBC_THUNK_SIZE + EBC_THUNK_ALIGNMENT - 1;

+  ThunkSize = Size;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  Size,

+                  (VOID *) &Ptr

+                  );

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Save the start address of the buffer.

+  //

+  ThunkBase = Ptr;

+

+  //

+  // Make sure it's aligned for code execution. If not, then

+  // round up.

+  //

+  if ((UINT32) (UINTN) Ptr & (EBC_THUNK_ALIGNMENT - 1)) {

+    Ptr = (UINT8 *) (((UINTN) Ptr + (EBC_THUNK_ALIGNMENT - 1)) &~ (UINT64) (EBC_THUNK_ALIGNMENT - 1));

+  }

+  //

+  // Return the pointer to the thunk to the caller to user as the

+  // image entry point.

+  //

+  *Thunk = (VOID *) Ptr;

+

+  //

+  // Clear out the thunk entry

+  // ZeroMem(Ptr, Size);

+  //

+  // For IPF, when you do a call via a function pointer, the function pointer

+  // actually points to a function descriptor which consists of a 64-bit

+  // address of the function, followed by a 64-bit gp for the function being

+  // called. See the the Software Conventions and Runtime Architecture Guide

+  // for details.

+  // So first off in our thunk, create a descriptor for our actual thunk code.

+  // This means we need to create a pointer to the thunk code (which follows

+  // the descriptor we're going to create), followed by the gp of the Vm

+  // interpret function we're going to eventually execute.

+  //

+  Data64Ptr = (UINT64 *) Ptr;

+

+  //

+  // Write the function's entry point (which is our thunk code that follows

+  // this descriptor we're creating).

+  //

+  *Data64Ptr = (UINT64) (Data64Ptr + 2);

+  //

+  // Get the gp from the descriptor for EbcInterpret and stuff it in our thunk

+  // descriptor.

+  //

+  *(Data64Ptr + 1) = *(UINT64 *) ((UINT64 *) (UINTN) EbcInterpret + 1);

+  //

+  // Advance our thunk data pointer past the descriptor. Since the

+  // descriptor consists of 16 bytes, the pointer is still aligned for

+  // IPF code execution (on 16-byte boundary).

+  //

+  Ptr += sizeof (UINT64) * 2;

+

+  //

+  // *************************** MAGIC BUNDLE ********************************

+  //

+  // Write magic code bundle for: movl r8 = 0xca112ebcca112ebc to help the VM

+  // to recognize it is a thunk.

+  //

+  Addr = (UINT64) 0xCA112EBCCA112EBC;

+

+  //

+  // Now generate the code bytes. First is nop.m 0x0

+  //

+  Code[0] = OPCODE_NOP;

+

+  //

+  // Next is simply Addr[62:22] (41 bits) of the address

+  //

+  Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;

+

+  //

+  // Extract bits from the address for insertion into the instruction

+  // i = Addr[63:63]

+  //

+  I = RightShiftU64 (Addr, 63) & 0x01;

+  //

+  // ic = Addr[21:21]

+  //

+  Ic = RightShiftU64 (Addr, 21) & 0x01;

+  //

+  // imm5c = Addr[20:16] for 5 bits

+  //

+  Imm5c = RightShiftU64 (Addr, 16) & 0x1F;

+  //

+  // imm9d = Addr[15:7] for 9 bits

+  //

+  Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;

+  //

+  // imm7b = Addr[6:0] for 7 bits

+  //

+  Imm7b = Addr & 0x7F;

+

+  //

+  // The EBC entry point will be put into r8, so r8 can be used here

+  // temporary. R8 is general register and is auto-serialized.

+  //

+  RegNum = 8;

+

+  //

+  // Next is jumbled data, including opcode and rest of address

+  //

+  Code[2] = LeftShiftU64 (Imm7b, 13)

+          | LeftShiftU64 (0x00, 20)   // vc

+          | LeftShiftU64 (Ic, 21)

+          | LeftShiftU64 (Imm5c, 22)

+          | LeftShiftU64 (Imm9d, 27)

+          | LeftShiftU64 (I, 36)

+          | LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)

+          | LeftShiftU64 ((RegNum & 0x7F), 6);

+

+  WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);

+

+  //

+  // *************************** FIRST BUNDLE ********************************

+  //

+  // Write code bundle for: movl r8 = EBC_ENTRY_POINT so we pass

+  // the ebc entry point in to the interpreter function via a processor

+  // register.

+  // Note -- we could easily change this to pass in a pointer to a structure

+  // that contained, among other things, the EBC image's entry point. But

+  // for now pass it directly.

+  //

+  Ptr += 16;

+  Addr = (UINT64) EbcEntryPoint;

+

+  //

+  // Now generate the code bytes. First is nop.m 0x0

+  //

+  Code[0] = OPCODE_NOP;

+

+  //

+  // Next is simply Addr[62:22] (41 bits) of the address

+  //

+  Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;

+

+  //

+  // Extract bits from the address for insertion into the instruction

+  // i = Addr[63:63]

+  //

+  I = RightShiftU64 (Addr, 63) & 0x01;

+  //

+  // ic = Addr[21:21]

+  //

+  Ic = RightShiftU64 (Addr, 21) & 0x01;

+  //

+  // imm5c = Addr[20:16] for 5 bits

+  //

+  Imm5c = RightShiftU64 (Addr, 16) & 0x1F;

+  //

+  // imm9d = Addr[15:7] for 9 bits

+  //

+  Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;

+  //

+  // imm7b = Addr[6:0] for 7 bits

+  //

+  Imm7b = Addr & 0x7F;

+

+  //

+  // Put the EBC entry point in r8, which is the location of the return value

+  // for functions.

+  //

+  RegNum = 8;

+

+  //

+  // Next is jumbled data, including opcode and rest of address

+  //

+  Code[2] = LeftShiftU64 (Imm7b, 13)

+          | LeftShiftU64 (0x00, 20)   // vc

+          | LeftShiftU64 (Ic, 21)

+          | LeftShiftU64 (Imm5c, 22)

+          | LeftShiftU64 (Imm9d, 27)

+          | LeftShiftU64 (I, 36)

+          | LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)

+          | LeftShiftU64 ((RegNum & 0x7F), 6);

+

+  WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);

+

+  //

+  // *************************** NEXT BUNDLE *********************************

+  //

+  // Write code bundle for:

+  //   movl rx = offset_of(EbcInterpret|ExecuteEbcImageEntryPoint)

+  //

+  // Advance pointer to next bundle, then compute the offset from this bundle

+  // to the address of the entry point of the interpreter.

+  //

+  Ptr += 16;

+  if (Flags & FLAG_THUNK_ENTRY_POINT) {

+    Addr = (UINT64) ExecuteEbcImageEntryPoint;

+  } else {

+    Addr = (UINT64) EbcInterpret;

+  }

+  //

+  // Indirection on Itanium-based systems

+  //

+  Addr = *(UINT64 *) Addr;

+

+  //

+  // Now write the code to load the offset into a register

+  //

+  Code[0] = OPCODE_NOP;

+

+  //

+  // Next is simply Addr[62:22] (41 bits) of the address

+  //

+  Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;

+

+  //

+  // Extract bits from the address for insertion into the instruction

+  // i = Addr[63:63]

+  //

+  I = RightShiftU64 (Addr, 63) & 0x01;

+  //

+  // ic = Addr[21:21]

+  //

+  Ic = RightShiftU64 (Addr, 21) & 0x01;

+  //

+  // imm5c = Addr[20:16] for 5 bits

+  //

+  Imm5c = RightShiftU64 (Addr, 16) & 0x1F;

+  //

+  // imm9d = Addr[15:7] for 9 bits

+  //

+  Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;

+  //

+  // imm7b = Addr[6:0] for 7 bits

+  //

+  Imm7b = Addr & 0x7F;

+

+  //

+  // Put it in r31, a scratch register

+  //

+  RegNum = 31;

+

+  //

+  // Next is jumbled data, including opcode and rest of address

+  //

+  Code[2] =   LeftShiftU64(Imm7b, 13)

+          | LeftShiftU64 (0x00, 20)   // vc

+          | LeftShiftU64 (Ic, 21)

+          | LeftShiftU64 (Imm5c, 22)

+          | LeftShiftU64 (Imm9d, 27)

+          | LeftShiftU64 (I, 36)

+          | LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)

+          | LeftShiftU64 ((RegNum & 0x7F), 6);

+

+  WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);

+

+  //

+  // *************************** NEXT BUNDLE *********************************

+  //

+  // Load branch register with EbcInterpret() function offset from the bundle

+  // address: mov b6 = RegNum

+  //

+  // See volume 3 page 4-29 of the Arch. Software Developer's Manual.

+  //

+  // Advance pointer to next bundle

+  //

+  Ptr += 16;

+  Code[0] = OPCODE_NOP;

+  Code[1] = OPCODE_NOP;

+  Code[2] = OPCODE_MOV_BX_RX;

+

+  //

+  // Pick a branch register to use. Then fill in the bits for the branch

+  // register and user register (same user register as previous bundle).

+  //

+  Br = 6;

+  Code[2] |= LeftShiftU64 (Br, 6);

+  Code[2] |= LeftShiftU64 (RegNum, 13);

+  WriteBundle ((VOID *) Ptr, 0x0d, Code[0], Code[1], Code[2]);

+

+  //

+  // *************************** NEXT BUNDLE *********************************

+  //

+  // Now do the branch:  (p0) br.cond.sptk.few b6

+  //

+  // Advance pointer to next bundle.

+  // Fill in the bits for the branch register (same reg as previous bundle)

+  //

+  Ptr += 16;

+  Code[0] = OPCODE_NOP;

+  Code[1] = OPCODE_NOP;

+  Code[2] = OPCODE_BR_COND_SPTK_FEW;

+  Code[2] |= LeftShiftU64 (Br, 13);

+  WriteBundle ((VOID *) Ptr, 0x1d, Code[0], Code[1], Code[2]);

+

+  //

+  // Add the thunk to our list of allocated thunks so we can do some cleanup

+  // when the image is unloaded. Do this last since the Add function flushes

+  // the instruction cache for us.

+  //

+  EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);

+

+  //

+  // Done

+  //

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+WriteBundle (

+  IN    VOID    *MemPtr,

+  IN    UINT8   Template,

+  IN    UINT64  Slot0,

+  IN    UINT64  Slot1,

+  IN    UINT64  Slot2

+  )

+/*++

+

+Routine Description:

+

+  Given raw bytes of Itanium based code, format them into a bundle and

+  write them out.

+  

+Arguments:

+

+  MemPtr    - pointer to memory location to write the bundles to

+  Template  - 5-bit template

+  Slot0-2   - instruction slot data for the bundle

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Pointer is not aligned

+                        - No more than 5 bits in template

+                        - More than 41 bits used in code

+  EFI_SUCCESS           - All data is written.

+

+--*/

+{

+  UINT8   *BPtr;

+  UINT32  Index;

+  UINT64  Low64;

+  UINT64  High64;

+

+  //

+  // Verify pointer is aligned

+  //

+  if ((UINT64) MemPtr & 0xF) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Verify no more than 5 bits in template

+  //

+  if (Template &~0x1F) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Verify max of 41 bits used in code

+  //

+  if ((Slot0 | Slot1 | Slot2) &~0x1ffffffffff) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Low64   = LeftShiftU64 (Slot1, 46) | LeftShiftU64 (Slot0, 5) | Template;

+  High64  = RightShiftU64 (Slot1, 18) | LeftShiftU64 (Slot2, 23);

+

+  //

+  // Now write it all out

+  //

+  BPtr = (UINT8 *) MemPtr;

+  for (Index = 0; Index < 8; Index++) {

+    *BPtr = (UINT8) Low64;

+    Low64 = RightShiftU64 (Low64, 8);

+    BPtr++;

+  }

+

+  for (Index = 0; Index < 8; Index++) {

+    *BPtr   = (UINT8) High64;

+    High64  = RightShiftU64 (High64, 8);

+    BPtr++;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EbcLLCALLEX (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        FuncAddr,

+  IN UINTN        NewStackPointer,

+  IN VOID         *FramePtr,

+  IN UINT8        Size

+  )

+/*++

+

+Routine Description:

+

+  This function is called to execute an EBC CALLEX instruction. 

+  The function check the callee's content to see whether it is common native

+  code or a thunk to another piece of EBC code.

+  If the callee is common native code, use EbcLLCAllEXASM to manipulate,

+  otherwise, set the VM->IP to target EBC code directly to avoid another VM

+  be startup which cost time and stack space.

+  

+Arguments:

+

+  VmPtr             - Pointer to a VM context.

+  FuncAddr          - Callee's address

+  NewStackPointer   - New stack pointer after the call

+  FramePtr          - New frame pointer after the call

+  Size              - The size of call instruction

+

+Returns:

+

+  None.

+  

+--*/

+{

+  UINTN    IsThunk;

+  UINTN    TargetEbcAddr;

+  UINTN    CodeOne18;

+  UINTN    CodeOne23;

+  UINTN    CodeTwoI;

+  UINTN    CodeTwoIc;

+  UINTN    CodeTwo7b;

+  UINTN    CodeTwo5c;

+  UINTN    CodeTwo9d;

+  UINTN    CalleeAddr;

+

+  IsThunk       = 1;

+  TargetEbcAddr = 0;

+

+  //

+  // FuncAddr points to the descriptor of the target instructions.

+  //

+  CalleeAddr = *((UINT64 *)FuncAddr);

+

+  //

+  // Processor specific code to check whether the callee is a thunk to EBC.

+  //

+  if (*((UINT64 *)CalleeAddr) != 0xBCCA000100000005) {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT64 *)CalleeAddr + 1) != 0x697623C1004A112E)  {

+    IsThunk = 0;

+    goto Action;

+  }

+

+  CodeOne18 = RightShiftU64 (*((UINT64 *)CalleeAddr + 2), 46) & 0x3FFFF;

+  CodeOne23 = (*((UINT64 *)CalleeAddr + 3)) & 0x7FFFFF;

+  CodeTwoI  = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 59) & 0x1;

+  CodeTwoIc = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 44) & 0x1;

+  CodeTwo7b = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 36) & 0x7F;

+  CodeTwo5c = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 45) & 0x1F;

+  CodeTwo9d = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 50) & 0x1FF;

+

+  TargetEbcAddr = CodeTwo7b

+                  | LeftShiftU64 (CodeTwo9d, 7)

+                  | LeftShiftU64 (CodeTwo5c, 16)

+                  | LeftShiftU64 (CodeTwoIc, 21)

+                  | LeftShiftU64 (CodeOne18, 22)

+                  | LeftShiftU64 (CodeOne23, 40)

+                  | LeftShiftU64 (CodeTwoI, 63)

+                  ;

+

+Action:

+  if (IsThunk == 1){

+    //

+    // The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and

+    // put our return address and frame pointer on the VM stack.

+    // Then set the VM's IP to new EBC code.

+    //

+    VmPtr->R[0] -= 8;

+    VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);

+    VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];

+    VmPtr->R[0] -= 8;

+    VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (VmPtr->Ip + Size));

+

+    VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;

+  } else {

+    //

+    // The callee is not a thunk to EBC, call native code.

+    //

+    EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);

+

+    //

+    // Get return value and advance the IP.

+    //

+    VmPtr->R[7] = EbcLLGetReturnValue ();

+    VmPtr->Ip += Size;

+  }

+}

+

+VOID

+EbcLLCALLEXNative (

+  IN UINTN    CallAddr,

+  IN UINTN    EbcSp,

+  IN VOID     *FramePtr

+  )

+/*++

+

+Routine Description:

+  Implements the EBC CALLEX instruction to call an external function, which

+  seems to be native code.

+

+  We'll copy the entire EBC stack frame down below itself in memory and use

+  that copy for passing parameters. 

+

+Arguments:

+  CallAddr    - address (function pointer) of function to call

+  EbcSp       - current EBC stack pointer

+  FramePtr    - current EBC frame pointer.

+

+Returns:

+  NA

+

+--*/

+{

+  UINTN FrameSize;

+  VOID  *Destination;

+  VOID  *Source;

+  //

+  // The stack for an EBC function looks like this:

+  //     FramePtr  (8)

+  //     RetAddr   (8)

+  //     Locals    (n)

+  //     Stack for passing args (m)

+  //

+  // Pad the frame size with 64 bytes because the low-level code we call

+  // will move the stack pointer up assuming worst-case 8 args in registers.

+  //

+  FrameSize   = (UINTN) FramePtr - (UINTN) EbcSp + 64;

+  Source      = (VOID *) EbcSp;

+  Destination = (VOID *) ((UINT8 *) EbcSp - FrameSize - IPF_STACK_ALIGNMENT);

+  Destination = (VOID *) ((UINTN) ((UINTN) Destination + IPF_STACK_ALIGNMENT - 1) &~((UINTN) IPF_STACK_ALIGNMENT - 1));

+  gBS->CopyMem (Destination, Source, FrameSize);

+  EbcAsmLLCALLEX ((UINTN) CallAddr, (UINTN) Destination);

+}

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/IpfMath.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/IpfMath.c
new file mode 100644
index 0000000..f35f1b9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/IpfMath.c
@@ -0,0 +1,375 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ipfmath.c

+

+Abstract:

+

+  Math routines for IPF.

+

+--*/

+

+UINT64

+LeftShiftU64 (

+  IN UINT64   Operand,

+  IN UINT64   Count

+  )

+/*++

+

+Routine Description:

+  

+  Left-shift a 64 bit value.

+

+Arguments:

+

+  Operand - 64-bit value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand << Count

+

+--*/

+{

+  if (Count > 63) {

+    return 0;

+  }

+

+  return Operand << Count;

+}

+

+UINT64

+RightShiftU64 (

+  IN UINT64   Operand,

+  IN UINT64   Count

+  )

+/*++

+

+Routine Description:

+  

+  Right-shift a 64 bit value.

+

+Arguments:

+

+  Operand - 64-bit value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand >> Count

+

+--*/

+{

+  if (Count > 63) {

+    return 0;

+  }

+

+  return Operand >> Count;

+}

+

+INT64

+ARightShift64 (

+  IN INT64   Operand,

+  IN UINT64  Count

+  )

+/*++

+

+Routine Description:

+  

+  Right-shift a 64 bit signed value.

+

+Arguments:

+

+  Operand - 64-bit value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand >> Count

+

+--*/

+{

+  if (Count > 63) {

+

+    if (Operand & (0x01 << 63)) {

+      return (INT64)~0;

+    }

+

+    return 0;

+  }

+

+  return Operand >> Count;

+}

+

+#if 0

+//

+// The compiler generates true assembly for these, so we don't need them.

+//

+INT32

+ARightShift32 (

+  IN INT32   Operand,

+  IN UINTN   Count

+  )

+/*++

+

+Routine Description:

+  

+  Right shift a 32-bit value

+

+Arguments:

+

+  Operand - value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand >> Count

+

+--*/

+{

+  return Operand >> (Count & 0x1f);

+}

+

+INT32

+MulS32x32 (

+  INT32 Value1,

+  INT32 Value2,

+  INT32 *ResultHigh

+  )

+/*++

+

+Routine Description:

+  

+  Multiply two signed 32-bit numbers.

+

+Arguments:

+

+  Value1      - first value to multiply

+  Value2      - value to multiply Value1 by

+  ResultHigh  - overflow

+

+Returns:

+

+  Value1 * Value2

+

+Notes:

+

+  The 64-bit result is the concatenation of *ResultHigh and the return value

+

+  The product fits in 32 bits if

+     (*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)

+                                     OR

+     (*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)

+

+--*/

+{

+  INT64 Rres64;

+  INT32 Result;

+

+  Res64       = (INT64) Value1 * (INT64) Value2;

+  *ResultHigh = (Res64 >> 32) & 0xffffffff;

+  Result      = Res64 & 0xffffffff;

+  return Result;

+}

+

+UINT32

+MulU32x32 (

+  UINT32 Value1,

+  UINT32 Value2,

+  UINT32 *ResultHigh

+  )

+/*++

+

+Routine Description:

+  

+  Multiply two unsigned 32-bit values.

+

+Arguments:

+

+  Value1      - first number

+  Value2      - number to multiply by Value1 

+  ResultHigh  - overflow

+

+Returns:

+

+  Value1 * Value2

+

+Notes:

+

+  The 64-bit result is the concatenation of *ResultHigh and the return value.

+  The product fits in 32 bits if *ResultHigh == 0x00000000

+

+--*/

+{

+  UINT64  Res64;

+  UINT32  Result;

+

+  Res64       = (INT64) Value1 * (INT64) Value2;

+  *ResultHigh = (Res64 >> 32) & 0xffffffff;

+  Result      = Res64 & 0xffffffff;

+  return Result;

+}

+

+INT32

+DivS32x32 (

+  INT32 Value1,

+  INT32 Value2,

+  INT32 *Remainder,

+  UINTN *error

+  )

+//

+// signed 32-bit by signed 32-bit divide; the 32-bit remainder is

+// in *Remainder and the quotient is the return value; *error = 1 if the

+// divisor is 0, and it is 1 otherwise

+//

+{

+  INT32 Result;

+

+  *error = 0;

+

+  if (Value2 == 0x0) {

+    *error      = 1;

+    Result      = 0x80000000;

+    *Remainder  = 0x80000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

+

+UINT32

+DivU32x32 (

+  UINT32  Value1,

+  UINT32  Value2,

+  UINT32  *Remainder,

+  UINTN   *Error

+  )

+//

+// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is

+// in *Remainder and the quotient is the return value; *error = 1 if the

+// divisor is 0, and it is 1 otherwise

+//

+{

+  UINT32  Result;

+

+  *Error = 0;

+

+  if (Value2 == 0x0) {

+    *Error      = 1;

+    Result      = 0x80000000;

+    *Remainder  = 0x80000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

+

+#endif

+

+INT64

+DivS64x64 (

+  INT64 Value1,

+  INT64 Value2,

+  INT64 *Remainder,

+  UINTN *Error

+  )

+/*++

+

+Routine Description:

+  

+  Divide two 64-bit signed values.

+

+Arguments:

+

+  Value1    - dividend

+  Value2    - divisor

+  Remainder - remainder of Value1/Value2

+  Error     - to flag errors (divide-by-0)

+

+Returns:

+

+  Value1 / Valu2

+

+Note:

+

+  The 64-bit remainder is in *Remainder and the quotient is the return value.

+  *Error = 1 if the divisor is 0, and it is 1 otherwise

+

+--*/

+{

+  INT64 Result;

+

+  *Error = 0;

+

+  if (Value2 == 0x0) {

+    *Error      = 1;

+    Result      = 0x8000000000000000;

+    *Remainder  = 0x8000000000000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

+

+UINT64

+DivU64x64 (

+  UINT64 Value1,

+  UINT64 Value2,

+  UINT64 *Remainder,

+  UINTN  *Error

+  )

+/*++

+

+Routine Description:

+  

+  Divide two 64-bit unsigned values.

+

+Arguments:

+

+  Value1    - dividend

+  Value2    - divisor

+  Remainder - remainder of Value1/Value2

+  Error     - to flag errors (divide-by-0)

+

+Returns:

+

+  Value1 / Valu2

+

+Note:

+

+  The 64-bit remainder is in *Remainder and the quotient is the return value.

+  *Error = 1 if the divisor is 0, and it is 1 otherwise

+

+--*/

+{

+  UINT64  Result;

+

+  *Error = 0;

+

+  if (Value2 == 0x0) {

+    *Error      = 1;

+    Result      = 0x8000000000000000;

+    *Remainder  = 0x8000000000000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/IpfMul.s b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/IpfMul.s
new file mode 100644
index 0000000..e887dd6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/Ipf/IpfMul.s
@@ -0,0 +1,144 @@
+///*++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+//Module Name:  

+//

+//  IpfMul.s

+//  

+//Abstract:

+//

+//  Low level routines for IPF multiply support

+//  

+//--*/  

+

+.file "IpfMul.s"

+.section .text

+

+  .proc MulS64x64#

+  .align 32

+  .global MulS64x64#

+  .align 32

+

+///*++

+//

+//Routine Description:

+//

+//  Multiply two 64-bit signed numbers.

+//

+//    

+//Arguments:

+//

+//  INT64 

+//  MulS64x64 (

+//    IN INT64 Value1, 

+//    IN INT64 Value2, 

+//    OUT INT64 *ResultHigh);

+//

+//Returns:

+//

+//  64-bit signed result

+//  

+//--*/

+

+MulS64x64:

+  // signed 64x64->128-bit multiply

+  // A in r32, B in r33, Q_hi stored in [r34], Q_lo returned in r8

+{ .mfi

+  alloc r31=ar.pfs,3,0,0,0  // r32-r34

+  nop.f 0

+  nop.i 0;;

+}

+{.mmi

+  setf.sig f6=r32

+  setf.sig f7=r33

+  nop.i 0;;

+}

+

+{.mfi

+  nop.m 0

+  xma.h f8=f6,f7,f0

+  nop.i 0

+}

+{.mfi

+  nop.m 0

+  xma.l f6=f6,f7,f0

+  nop.i 0;;

+}

+

+

+{.mmb

+  stf8 [r34]=f8

+  getf.sig r8=f6

+  br.ret.sptk b0;;

+}

+

+.endp MulS64x64

+

+  .proc MulU64x64#

+  .align 32

+  .global MulU64x64#

+  .align 32

+

+

+///*++

+//

+//Routine Description:

+//

+//  Multiply two 64-bit unsigned numbers.

+//

+//    

+//Arguments:

+//

+//  UINT64 

+//  MulU64x64 (

+//    IN UINT64 Value1, 

+//    IN UINT64 Value2, 

+//    OUT UINT64 *ResultHigh);

+//

+//Returns:

+//

+//  64-bit unsigned result

+//  

+//--*/

+MulU64x64:

+  // A in r32, B in r33, Q_hi stored in [r34], Q_lo returned in r8

+{ .mfi

+  alloc r31=ar.pfs,3,0,0,0  // r32-r34

+  nop.f 0

+  nop.i 0;;

+}

+{.mmi

+  setf.sig f6=r32

+  setf.sig f7=r33

+  nop.i 0;;

+}

+

+{.mfi

+  nop.m 0

+  xma.hu f8=f6,f7,f0

+  nop.i 0

+}

+{.mfi

+  nop.m 0

+  xma.l f6=f6,f7,f0

+  nop.i 0;;

+}

+

+

+{.mmb

+  stf8 [r34]=f8

+  getf.sig r8=f6

+  br.ret.sptk b0;;

+}

+

+.endp MulU64x64

+

+

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Ebc/Dxe/build.xml
new file mode 100644
index 0000000..93f107b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Ebc"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Ebc/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Ebc">

+      <GenBuild baseName="Ebc" mbdFilename="${MODULE_DIR}/Ebc.mbd" msaFilename="${MODULE_DIR}/Ebc.msa"/>

+   </target>

+   <target depends="Ebc_clean" name="clean"/>

+   <target depends="Ebc_cleanall" name="cleanall"/>

+   <target name="Ebc_clean">

+      <OutputDirSetup baseName="Ebc" mbdFilename="${MODULE_DIR}/Ebc.mbd" msaFilename="${MODULE_DIR}/Ebc.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Ebc_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Ebc_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Ebc_cleanall">

+      <OutputDirSetup baseName="Ebc" mbdFilename="${MODULE_DIR}/Ebc.mbd" msaFilename="${MODULE_DIR}/Ebc.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Ebc_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Ebc_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Ebc*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcLowLevel.asm b/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcLowLevel.asm
new file mode 100644
index 0000000..5939462
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcLowLevel.asm
@@ -0,0 +1,145 @@
+  page    ,132

+  title   VM ASSEMBLY LANGUAGE ROUTINES

+;****************************************************************************

+;*                                                                         

+;*  Copyright (c) 2006, Intel Corporation                                                         

+;*  All rights reserved. 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.             

+;*                                                                          

+;****************************************************************************

+;****************************************************************************

+;                                   REV 1.0

+;****************************************************************************

+;

+; Rev  Date      Description

+; ---  --------  ------------------------------------------------------------

+; 1.0  05/09/12  Initial creation of file.

+;

+;****************************************************************************

+                             

+;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

+; This code provides low level routines that support the Virtual Machine

+; for option ROMs. 

+;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

+

+;---------------------------------------------------------------------------

+; Equate files needed.

+;---------------------------------------------------------------------------

+

+text SEGMENT

+

+;---------------------------------------------------------------------------

+;;GenericPostSegment      SEGMENT USE16

+;---------------------------------------------------------------------------

+

+;****************************************************************************

+; EbcLLCALLEX

+;

+; This function is called to execute an EBC CALLEX instruction. 

+; This instruction requires that we thunk out to external native

+; code. For x64, we switch stacks, copy the arguments to the stack

+; and jump to the specified function. 

+; On return, we restore the stack pointer to its original location.

+;

+; Destroys no working registers.

+;****************************************************************************

+; VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)

+EbcLLCALLEXNative        PROC

+      push   rbp

+      push   rbx

+      mov    rbp, rsp

+      ; Function prolog

+      

+      ; Copy FuncAddr to a preserved register.

+      mov    rbx, rcx

+

+      ; Set stack pointer to new value

+      mov    rsp, rdx      

+      

+      ; Considering the worst case, load 4 potiential arguments

+      ; into registers.

+      mov    rcx, qword ptr [rsp]

+      mov    rdx, qword ptr [rsp+8h]

+      mov    r8,  qword ptr [rsp+10h]

+      mov    r9,  qword ptr [rsp+18h]

+

+      ; Now call the external routine

+      call  rbx

+      

+      ; Function epilog

+      mov      rsp, rbp

+      pop      rbx

+      pop      rbp

+      ret

+EbcLLCALLEXNative    ENDP

+

+

+; UINTN EbcLLGetEbcEntryPoint(VOID);

+; Routine Description:

+;   The VM thunk code stuffs an EBC entry point into a processor

+;   register. Since we can't use inline assembly to get it from

+;   the interpreter C code, stuff it into the return value 

+;   register and return.

+;

+; Arguments:

+;     None.

+;

+; Returns:

+;     The contents of the register in which the entry point is passed.

+;

+EbcLLGetEbcEntryPoint        PROC

+    ret

+EbcLLGetEbcEntryPoint    ENDP

+

+;/*++

+;

+;Routine Description:

+;  

+;  Return the caller's value of the stack pointer.

+;

+;Arguments:

+;

+;  None.

+;

+;Returns:

+;

+;  The current value of the stack pointer for the caller. We

+;  adjust it by 4 here because when they called us, the return address

+;  is put on the stack, thereby lowering it by 4 bytes.

+;

+;--*/

+

+; UINTN EbcLLGetStackPointer()            

+EbcLLGetStackPointer        PROC

+    mov    rax, rsp      ; get current stack pointer

+    ; Stack adjusted by this much when we were called,

+    ; For this function, it's 4.

+    add   rax, 4

+    ret

+EbcLLGetStackPointer    ENDP

+

+; UINT64 EbcLLGetReturnValue(VOID);

+; Routine Description:

+;   When EBC calls native, on return the VM has to stuff the return

+;   value into a VM register. It's assumed here that the value is still

+;    in the register, so simply return and the caller should get the

+;   return result properly.

+;

+; Arguments:

+;     None.

+;

+; Returns:

+;     The unmodified value returned by the native code.

+;

+EbcLLGetReturnValue   PROC

+    ret

+EbcLLGetReturnValue    ENDP

+

+text  ENDS

+END

+

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcSupport.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcSupport.c
new file mode 100644
index 0000000..d111f3c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcSupport.c
@@ -0,0 +1,579 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EbcSupport.c

+

+Abstract:

+

+  This module contains EBC support routines that are customized based on

+  the target x64 processor.

+

+--*/

+

+#include "EbcInt.h"

+#include "EbcExecute.h"

+

+//

+// NOTE: This is the stack size allocated for the interpreter

+//       when it executes an EBC image. The requirements can change

+//       based on whether or not a debugger is present, and other

+//       platform-specific configurations.

+//

+#define VM_STACK_SIZE   (1024 * 8)

+#define EBC_THUNK_SIZE  64

+

+STATIC

+VOID

+PushU64 (

+  VM_CONTEXT *VmPtr,

+  UINT64     Arg

+  )

+/*++

+

+Routine Description:

+

+  Push a 64 bit unsigned value to the VM stack.

+  

+Arguments:

+

+  VmPtr   -  The pointer to current VM context.

+  Arg     -  The value to be pushed

+

+Returns:

+

+  VOID

+  

+--*/

+{

+  //

+  // Advance the VM stack down, and then copy the argument to the stack.

+  // Hope it's aligned.

+  //

+  VmPtr->R[0] -= sizeof (UINT64);

+  *(UINT64 *) VmPtr->R[0] = Arg;

+  return;

+}

+

+STATIC

+UINT64

+EbcInterpret (

+  UINTN      Arg1,

+  UINTN      Arg2,

+  UINTN      Arg3,

+  UINTN      Arg4,

+  UINTN      Arg5

+  )

+/*++

+

+Routine Description:

+

+  Begin executing an EBC image. The address of the entry point is passed

+  in via a processor register, so we'll need to make a call to get the

+  value.

+  

+Arguments:

+

+  This is a thunk function. Microsoft x64 compiler only provide fast_call

+  calling convention, so the first four arguments are passed by rcx, rdx, 

+  r8, and r9, while other arguments are passed in stack.

+

+Returns:

+

+  The value returned by the EBC application we're going to run.

+  

+--*/

+{

+  //

+  // Create a new VM context on the stack

+  //

+  VM_CONTEXT  VmContext;

+  UINTN       Addr;

+

+  //

+  // Get the EBC entry point from the processor register.

+  // Don't call any function before getting the EBC entry

+  // point because this will collab the return register.

+  //

+  Addr = EbcLLGetEbcEntryPoint ();

+

+  //

+  // Now clear out our context

+  //

+  ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));

+

+  //

+  // Set the VM instruction pointer to the correct location in memory.

+  //

+  VmContext.Ip = (VMIP) Addr;

+

+  //

+  // Initialize the stack pointer for the EBC. Get the current system stack

+  // pointer and adjust it down by the max needed for the interpreter.

+  //

+  Addr            = EbcLLGetStackPointer ();

+

+  //

+  // Adjust the VM's stack pointer down.

+  //

+  VmContext.R[0]  = (UINT64) Addr;

+  VmContext.R[0] -= VM_STACK_SIZE;

+

+  //

+  // Align the stack on a natural boundary.

+  //

+  VmContext.R[0] &= ~(sizeof (UINTN) - 1);

+

+  //

+  // Put a magic value in the stack gap, then adjust down again.

+  //

+  *(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;

+  VmContext.StackMagicPtr             = (UINTN *) (UINTN) VmContext.R[0];

+

+  //

+  // The stack upper to LowStackTop is belong to the VM.

+  //

+  VmContext.LowStackTop   = (UINTN) VmContext.R[0];

+

+  //

+  // For the worst case, assume there are 4 arguments passed in registers, store

+  // them to VM's stack.

+  //

+  PushU64 (&VmContext, (UINT64) Arg4);

+  PushU64 (&VmContext, (UINT64) Arg3);

+  PushU64 (&VmContext, (UINT64) Arg2);

+  PushU64 (&VmContext, (UINT64) Arg1);

+

+  //

+  // Interpreter assumes 64-bit return address is pushed on the stack.

+  // The x64 does not do this so pad the stack accordingly.

+  //

+  PushU64 (&VmContext, (UINT64) 0);

+  PushU64 (&VmContext, (UINT64) 0x1234567887654321);

+

+  //

+  // For x64, this is where we say our return address is

+  //

+  VmContext.StackRetAddr  = (UINT64) VmContext.R[0];

+

+  //

+  // We need to keep track of where the EBC stack starts. This way, if the EBC

+  // accesses any stack variables above its initial stack setting, then we know

+  // it's accessing variables passed into it, which means the data is on the

+  // VM's stack.

+  // When we're called, on the stack (high to low) we have the parameters, the

+  // return address, then the saved ebp. Save the pointer to the return address.

+  // EBC code knows that's there, so should look above it for function parameters.

+  // The offset is the size of locals (VMContext + Addr + saved ebp).

+  // Note that the interpreter assumes there is a 16 bytes of return address on

+  // the stack too, so adjust accordingly.

+  //  VmContext.HighStackBottom = (UINTN)(Addr + sizeof (VmContext) + sizeof (Addr));

+  //

+  VmContext.HighStackBottom = (UINTN) &Arg5;

+

+  //

+  // Begin executing the EBC code

+  //

+  EbcExecute (&VmContext);

+

+  //

+  // Return the value in R[7] unless there was an error

+  //

+  return (UINT64) VmContext.R[7];

+}

+

+STATIC

+UINT64

+ExecuteEbcImageEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Begin executing an EBC image. The address of the entry point is passed

+  in via a processor register, so we'll need to make a call to get the

+  value.

+  

+Arguments:

+

+  ImageHandle   - image handle for the EBC application we're executing

+  SystemTable   - standard system table passed into an driver's entry point

+

+Returns:

+

+  The value returned by the EBC application we're going to run.

+

+--*/

+{

+  //

+  // Create a new VM context on the stack

+  //

+  VM_CONTEXT  VmContext;

+  UINTN       Addr;

+

+  //

+  // Get the EBC entry point from the processor register. Make sure you don't

+  // call any functions before this or you could mess up the register the

+  // entry point is passed in.

+  //

+  Addr = EbcLLGetEbcEntryPoint ();

+

+  //

+  // Now clear out our context

+  //

+  ZeroMem ((VOID *) &VmContext, sizeof (VM_CONTEXT));

+

+  //

+  // Save the image handle so we can track the thunks created for this image

+  //

+  VmContext.ImageHandle = ImageHandle;

+  VmContext.SystemTable = SystemTable;

+

+  //

+  // Set the VM instruction pointer to the correct location in memory.

+  //

+  VmContext.Ip = (VMIP) Addr;

+

+  //

+  // Initialize the stack pointer for the EBC. Get the current system stack

+  // pointer and adjust it down by the max needed for the interpreter.

+  //

+  Addr            = EbcLLGetStackPointer ();

+  VmContext.R[0]  = (UINT64) Addr;

+  VmContext.R[0] -= VM_STACK_SIZE;

+

+  //

+  // Put a magic value in the stack gap, then adjust down again

+  //

+  *(UINTN *) (UINTN) (VmContext.R[0]) = (UINTN) VM_STACK_KEY_VALUE;

+  VmContext.StackMagicPtr             = (UINTN *) (UINTN) VmContext.R[0];

+

+  //

+  // Align the stack on a natural boundary

+  VmContext.R[0] &= ~(sizeof(UINTN) - 1);

+  //

+  VmContext.LowStackTop   = (UINTN) VmContext.R[0];

+

+  //

+  // Simply copy the image handle and system table onto the EBC stack.

+  // Greatly simplifies things by not having to spill the args.

+  //

+  PushU64 (&VmContext, (UINT64) SystemTable);

+  PushU64 (&VmContext, (UINT64) ImageHandle);

+

+  //

+  // VM pushes 16-bytes for return address. Simulate that here.

+  //

+  PushU64 (&VmContext, (UINT64) 0);

+  PushU64 (&VmContext, (UINT64) 0x1234567887654321);

+

+  //

+  // For x64, this is where we say our return address is

+  //

+  VmContext.StackRetAddr  = (UINT64) VmContext.R[0];

+

+  //

+  // Entry function needn't access high stack context, simply

+  // put the stack pointer here.

+  //

+  VmContext.HighStackBottom = (UINTN) Addr;

+

+  //

+  // Begin executing the EBC code

+  //

+  EbcExecute (&VmContext);

+

+  //

+  // Return the value in R[7] unless there was an error

+  //

+  return (UINT64) VmContext.R[7];

+}

+

+EFI_STATUS

+EbcCreateThunks (

+  IN EFI_HANDLE           ImageHandle,

+  IN VOID                 *EbcEntryPoint,

+  OUT VOID                **Thunk,

+  IN  UINT32              Flags

+  )

+/*++

+

+Routine Description:

+

+  Create an IA32 thunk for the given EBC entry point.

+  

+Arguments:

+

+  ImageHandle     - Handle of image for which this thunk is being created

+  EbcEntryPoint   - Address of the EBC code that the thunk is to call

+  Thunk           - Returned thunk we create here

+

+Returns:

+

+  Standard EFI status.

+  

+--*/

+{

+  UINT8       *Ptr;

+  UINT8       *ThunkBase;

+  UINT32      I;

+  UINT64      Addr;

+  INT32       Size;

+  INT32       ThunkSize;

+  EFI_STATUS  Status;

+

+  //

+  // Check alignment of pointer to EBC code

+  //

+  if ((UINT32) (UINTN) EbcEntryPoint & 0x01) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Size      = EBC_THUNK_SIZE;

+  ThunkSize = Size;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  Size,

+                  (VOID *) &Ptr

+                  );

+  if (Status != EFI_SUCCESS) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  //  Print(L"Allocate TH: 0x%X\n", (UINT32)Ptr);

+  //

+  // Save the start address so we can add a pointer to it to a list later.

+  //

+  ThunkBase = Ptr;

+

+  //

+  // Give them the address of our buffer we're going to fix up

+  //

+  *Thunk = (VOID *) Ptr;

+

+  //

+  // Add a magic code here to help the VM recognize the thunk..

+  // mov rax, ca112ebccall2ebch  => 48 B8 BC 2E 11 CA BC 2E 11 CA

+  //

+  *Ptr = 0x48;

+  Ptr++;

+  Size--;

+  *Ptr = 0xB8;

+  Ptr++;

+  Size--;

+  Addr = (UINT64) 0xCA112EBCCA112EBC;

+  for (I = 0; I < sizeof (Addr); I++) {

+    *Ptr = (UINT8) (UINTN) Addr;

+    Addr >>= 8;

+    Ptr++;

+    Size--;

+  }

+

+  //

+  // Add code bytes to load up a processor register with the EBC entry point.

+  // mov rax, 123456789abcdef0h  => 48 B8 F0 DE BC 9A 78 56 34 12

+  // The first 8 bytes of the thunk entry is the address of the EBC

+  // entry point.

+  //

+  *Ptr = 0x48;

+  Ptr++;

+  Size--;

+  *Ptr = 0xB8;

+  Ptr++;

+  Size--;

+  Addr = (UINT64) EbcEntryPoint;

+  for (I = 0; I < sizeof (Addr); I++) {

+    *Ptr = (UINT8) (UINTN) Addr;

+    Addr >>= 8;

+    Ptr++;

+    Size--;

+  }

+

+  //

+  // Stick in a load of ecx with the address of appropriate VM function.

+  // Using r11 because it's a volatile register and won't be used in this

+  // point.

+  // mov r11 123456789abcdef0h  => 49 BB F0 DE BC 9A 78 56 34 12

+  //

+  if (Flags & FLAG_THUNK_ENTRY_POINT) {

+    Addr = (UINTN) ExecuteEbcImageEntryPoint;

+  } else {

+    Addr = (UINTN) EbcInterpret;

+  }

+

+  //

+  // mov r11 Addr => 0x49 0xBB

+  //

+  *Ptr = 0x49;

+  Ptr++;

+  Size--;

+  *Ptr = 0xBB;

+  Ptr++;

+  Size--;

+  for (I = 0; I < sizeof (Addr); I++) {

+    *Ptr = (UINT8) Addr;

+    Addr >>= 8;

+    Ptr++;

+    Size--;

+  }

+  //

+  // Stick in jump opcode bytes for jmp r11 => 0x41 0xFF 0xE3

+  //

+  *Ptr = 0x41;

+  Ptr++;

+  Size--;

+  *Ptr = 0xFF;

+  Ptr++;

+  Size--;

+  *Ptr = 0xE3;

+  Size--;

+

+  //

+  // Double check that our defined size is ok (application error)

+  //

+  if (Size < 0) {

+    ASSERT (FALSE);

+    return EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // Add the thunk to the list for this image. Do this last since the add

+  // function flushes the cache for us.

+  //

+  EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);

+

+  return EFI_SUCCESS;

+}

+

+VOID

+EbcLLCALLEX (

+  IN VM_CONTEXT   *VmPtr,

+  IN UINTN        FuncAddr,

+  IN UINTN        NewStackPointer,

+  IN VOID         *FramePtr,

+  IN UINT8        Size

+  )

+/*++

+

+Routine Description:

+

+  This function is called to execute an EBC CALLEX instruction. 

+  The function check the callee's content to see whether it is common native

+  code or a thunk to another piece of EBC code.

+  If the callee is common native code, use EbcLLCAllEXASM to manipulate,

+  otherwise, set the VM->IP to target EBC code directly to avoid another VM

+  be startup which cost time and stack space.

+  

+Arguments:

+

+  VmPtr             - Pointer to a VM context.

+  FuncAddr          - Callee's address

+  NewStackPointer   - New stack pointer after the call

+  FramePtr          - New frame pointer after the call

+  Size              - The size of call instruction

+

+Returns:

+

+  None.

+  

+--*/

+{

+  UINTN    IsThunk;

+  UINTN    TargetEbcAddr;

+

+  IsThunk       = 1;

+  TargetEbcAddr = 0;

+

+  //

+  // Processor specific code to check whether the callee is a thunk to EBC.

+  //

+  if (*((UINT8 *)FuncAddr) != 0x48) {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 1) != 0xB8) {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 2) != 0xBC)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 3) != 0x2E)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 4) != 0x11)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 5) != 0xCA)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 6) != 0xBC)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 7) != 0x2E)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 8) != 0x11)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 9) != 0xCA)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 10) != 0x48)  {

+    IsThunk = 0;

+    goto Action;

+  }

+  if (*((UINT8 *)FuncAddr + 11) != 0xB8)  {

+    IsThunk = 0;

+    goto Action;

+  }

+

+  CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + 12, 8);

+

+Action:

+  if (IsThunk == 1){

+    //

+    // The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and

+    // put our return address and frame pointer on the VM stack.

+    // Then set the VM's IP to new EBC code.

+    //

+    VmPtr->R[0] -= 8;

+    VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);

+    VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];

+    VmPtr->R[0] -= 8;

+    VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (VmPtr->Ip + Size));

+

+    VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;

+  } else {

+    //

+    // The callee is not a thunk to EBC, call native code.

+    //

+    EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);

+

+    //

+    // Get return value and advance the IP.

+    //

+    VmPtr->R[7] = EbcLLGetReturnValue ();

+    VmPtr->Ip += Size;

+  }

+}

+

diff --git a/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/x64Math.c b/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/x64Math.c
new file mode 100644
index 0000000..0842490
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Ebc/Dxe/x64/x64Math.c
@@ -0,0 +1,451 @@
+/*++

+

+Copyright (c) 2006 , Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  x64math.c

+

+Abstract:

+

+  Math routines for x64.

+

+--*/

+

+UINT64

+LeftShiftU64 (

+  IN UINT64   Operand,

+  IN UINT64   Count

+  )

+/*++

+

+Routine Description:

+  

+  Left-shift a 64 bit value.

+

+Arguments:

+

+  Operand - 64-bit value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand << Count

+

+--*/

+{

+  if (Count > 63) {

+    return 0;

+  }

+

+  return Operand << Count;

+}

+

+UINT64

+RightShiftU64 (

+  IN UINT64   Operand,

+  IN UINT64   Count

+  )

+/*++

+

+Routine Description:

+  

+  Right-shift a 64 bit value.

+

+Arguments:

+

+  Operand - 64-bit value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand >> Count

+

+--*/

+{

+  if (Count > 63) {

+    return 0;

+  }

+

+  return Operand >> Count;

+}

+

+INT64

+ARightShift64 (

+  IN INT64   Operand,

+  IN UINT64  Count

+  )

+/*++

+

+Routine Description:

+  

+  Right-shift a 64 bit signed value.

+

+Arguments:

+

+  Operand - 64-bit value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand >> Count

+

+--*/

+{

+  if (Count > 63) {

+

+    if (Operand & 0x8000000000000000ULL) {

+      return (INT64)~0;

+    }

+

+    return 0;

+  }

+

+  return Operand >> Count;

+}

+

+#if 0

+//

+// The compiler generates true assembly for these, so we don't need them.

+//

+INT32

+ARightShift32 (

+  IN INT32   Operand,

+  IN UINTN   Count

+  )

+/*++

+

+Routine Description:

+  

+  Right shift a 32-bit value

+

+Arguments:

+

+  Operand - value to shift

+  Count   - shift count

+

+Returns:

+

+  Operand >> Count

+

+--*/

+{

+  return Operand >> (Count & 0x1f);

+}

+

+INT32

+MulS32x32 (

+  INT32 Value1,

+  INT32 Value2,

+  INT32 *ResultHigh

+  )

+/*++

+

+Routine Description:

+  

+  Multiply two signed 32-bit numbers.

+

+Arguments:

+

+  Value1      - first value to multiply

+  Value2      - value to multiply Value1 by

+  ResultHigh  - overflow

+

+Returns:

+

+  Value1 * Value2

+

+Notes:

+

+  The 64-bit result is the concatenation of *ResultHigh and the return value

+

+  The product fits in 32 bits if

+     (*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)

+                                     OR

+     (*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)

+

+--*/

+{

+  INT64 Rres64;

+  INT32 Result;

+

+  Res64       = (INT64) Value1 * (INT64) Value2;

+  *ResultHigh = (Res64 >> 32) & 0xffffffff;

+  Result      = Res64 & 0xffffffff;

+  return Result;

+}

+

+UINT32

+MulU32x32 (

+  UINT32 Value1,

+  UINT32 Value2,

+  UINT32 *ResultHigh

+  )

+/*++

+

+Routine Description:

+  

+  Multiply two unsigned 32-bit values.

+

+Arguments:

+

+  Value1      - first number

+  Value2      - number to multiply by Value1 

+  ResultHigh  - overflow

+

+Returns:

+

+  Value1 * Value2

+

+Notes:

+

+  The 64-bit result is the concatenation of *ResultHigh and the return value.

+  The product fits in 32 bits if *ResultHigh == 0x00000000

+

+--*/

+{

+  UINT64  Res64;

+  UINT32  Result;

+

+  Res64       = (INT64) Value1 * (INT64) Value2;

+  *ResultHigh = (Res64 >> 32) & 0xffffffff;

+  Result      = Res64 & 0xffffffff;

+  return Result;

+}

+

+INT32

+DivS32x32 (

+  INT32 Value1,

+  INT32 Value2,

+  INT32 *Remainder,

+  UINTN *error

+  )

+//

+// signed 32-bit by signed 32-bit divide; the 32-bit remainder is

+// in *Remainder and the quotient is the return value; *error = 1 if the

+// divisor is 0, and it is 1 otherwise

+//

+{

+  INT32 Result;

+

+  *error = 0;

+

+  if (Value2 == 0x0) {

+    *error      = 1;

+    Result      = 0x80000000;

+    *Remainder  = 0x80000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

+

+UINT32

+DivU32x32 (

+  UINT32  Value1,

+  UINT32  Value2,

+  UINT32  *Remainder,

+  UINTN   *Error

+  )

+//

+// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is

+// in *Remainder and the quotient is the return value; *error = 1 if the

+// divisor is 0, and it is 1 otherwise

+//

+{

+  UINT32  Result;

+

+  *Error = 0;

+

+  if (Value2 == 0x0) {

+    *Error      = 1;

+    Result      = 0x80000000;

+    *Remainder  = 0x80000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

+

+#endif

+

+INT64

+MulS64x64 (

+  INT64 Value1,

+  INT64 Value2,

+  INT64 *ResultHigh

+  )

+/*++

+

+Routine Description:

+  

+  Multiply two signed 32-bit numbers.

+

+Arguments:

+

+  Value1      - first value to multiply

+  Value2      - value to multiply Value1 by

+  ResultHigh  - overflow

+

+Returns:

+

+  Value1 * Value2

+

+Notes:

+

+  The 64-bit result is the concatenation of *ResultHigh and the return value

+

+  The product fits in 32 bits if

+     (*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)

+                                     OR

+     (*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)

+

+--*/

+{

+  INT64 Result;

+  

+  Result  = Value1 * Value2;

+

+  return Result;

+}

+

+UINT64

+MulU64x64 (

+  UINT64 Value1,

+  UINT64 Value2,

+  UINT64 *ResultHigh

+  )

+/*++

+

+Routine Description:

+  

+  Multiply two unsigned 32-bit values.

+

+Arguments:

+

+  Value1      - first number

+  Value2      - number to multiply by Value1 

+  ResultHigh  - overflow

+

+Returns:

+

+  Value1 * Value2

+

+Notes:

+

+  The 64-bit result is the concatenation of *ResultHigh and the return value.

+  The product fits in 32 bits if *ResultHigh == 0x00000000

+

+--*/

+{

+  UINT64  Result;

+

+  Result  = Value1 * Value2;

+

+  return Result;

+}

+

+INT64

+DivS64x64 (

+  INT64 Value1,

+  INT64 Value2,

+  INT64 *Remainder,

+  UINTN *Error

+  )

+/*++

+

+Routine Description:

+  

+  Divide two 64-bit signed values.

+

+Arguments:

+

+  Value1    - dividend

+  Value2    - divisor

+  Remainder - remainder of Value1/Value2

+  Error     - to flag errors (divide-by-0)

+

+Returns:

+

+  Value1 / Valu2

+

+Note:

+

+  The 64-bit remainder is in *Remainder and the quotient is the return value.

+  *Error = 1 if the divisor is 0, and it is 1 otherwise

+

+--*/

+{

+  INT64 Result;

+

+  *Error = 0;

+

+  if (Value2 == 0x0) {

+    *Error      = 1;

+    Result      = 0x8000000000000000;

+    *Remainder  = 0x8000000000000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

+

+UINT64

+DivU64x64 (

+  UINT64 Value1,

+  UINT64 Value2,

+  UINT64 *Remainder,

+  UINTN  *Error

+  )

+/*++

+

+Routine Description:

+  

+  Divide two 64-bit unsigned values.

+

+Arguments:

+

+  Value1    - dividend

+  Value2    - divisor

+  Remainder - remainder of Value1/Value2

+  Error     - to flag errors (divide-by-0)

+

+Returns:

+

+  Value1 / Valu2

+

+Note:

+

+  The 64-bit remainder is in *Remainder and the quotient is the return value.

+  *Error = 1 if the divisor is 0, and it is 1 otherwise

+

+--*/

+{

+  UINT64  Result;

+

+  *Error = 0;

+

+  if (Value2 == 0x0) {

+    *Error      = 1;

+    Result      = 0x8000000000000000;

+    *Remainder  = 0x8000000000000000;

+  } else {

+    Result      = Value1 / Value2;

+    *Remainder  = Value1 - Result * Value2;

+  }

+

+  return Result;

+}

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.c b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.c
new file mode 100644
index 0000000..beb404f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.c
@@ -0,0 +1,754 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    EmuVariable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;

+

+UINT32

+EFIAPI

+ArrayLength (

+  IN CHAR16 *String

+  )

+/*++

+

+Routine Description:

+

+  Determine the length of null terminated char16 array.

+

+Arguments:

+

+  String    Null-terminated CHAR16 array pointer.

+

+Returns:

+

+  UINT32    Number of bytes in the string, including the double NULL at the end;

+

+--*/

+{

+  UINT32  Count;

+

+  if (NULL == String) {

+    return 0;

+  }

+

+  Count = 0;

+

+  while (0 != String[Count]) {

+    Count++;

+  }

+

+  return (Count * 2) + 2;

+}

+

+UINTN

+EFIAPI

+GetPadSize (

+  IN UINTN Value

+  )

+/*++

+

+Routine Description:

+

+  This function return the pad size for alignment

+

+Arguments:

+

+  Value  The value need to align

+

+Returns:

+

+  Pad size for value

+

+--*/

+{

+  //

+  // If alignment is 0 or 1, means no alignment required

+  //

+  if (ALIGNMENT == 0 || ALIGNMENT == 1) {

+    return 0;

+  }

+

+  return ALIGNMENT - (Value % ALIGNMENT);

+}

+

+VARIABLE_STORE_STATUS

+EFIAPI

+GetVariableStoreStatus (

+  IN VARIABLE_STORE_HEADER *VarStoreHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the variable name.

+

+Arguments:

+

+  VarStoreHeader  Pointer to the Variable Store Header.

+

+Returns:

+

+  EfiHealthy    Variable store is healthy

+  EfiRaw        Variable store is raw

+  EfiInvalid    Variable store is invalid

+

+--*/

+{

+  if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&

+      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&

+      VarStoreHeader->State == VARIABLE_STORE_HEALTHY

+      ) {

+

+    return EfiValid;

+  } else if (VarStoreHeader->Signature == 0xffffffff &&

+           VarStoreHeader->Size == 0xffffffff &&

+           VarStoreHeader->Format == 0xff &&

+           VarStoreHeader->State == 0xff

+          ) {

+

+    return EfiRaw;

+  } else {

+    return EfiInvalid;

+  }

+}

+

+UINT8 *

+EFIAPI

+GetVariableDataPtr (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the variable data.

+

+Arguments:

+

+  Variable            Pointer to the Variable Header.

+

+Returns:

+

+  UINT8*              Pointer to Variable Data

+

+--*/

+{

+  if (Variable->StartId != VARIABLE_DATA) {

+    return NULL;

+  }

+  //

+  // Be careful about pad size for alignment

+  //

+  return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GetPadSize (Variable->NameSize));

+}

+

+VARIABLE_HEADER *

+EFIAPI

+GetNextVariablePtr (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the next variable header.

+

+Arguments:

+

+  Variable                  Pointer to the Variable Header.

+

+Returns:

+

+  VARIABLE_HEADER*      Pointer to next variable header.

+

+--*/

+{

+  VARIABLE_HEADER *VarHeader;

+

+  if (Variable->StartId != VARIABLE_DATA) {

+    return NULL;

+  }

+  //

+  // Be careful about pad size for alignment

+  //

+  VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));

+

+  if (VarHeader->StartId != VARIABLE_DATA ||

+      (sizeof (VARIABLE_HEADER) + VarHeader->DataSize + VarHeader->NameSize) > MAX_VARIABLE_SIZE

+      ) {

+    return NULL;

+  }

+

+  return VarHeader;

+}

+

+VARIABLE_HEADER *

+EFIAPI

+GetEndPointer (

+  IN VARIABLE_STORE_HEADER       *VolHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the last variable memory pointer byte

+

+Arguments:

+

+  Variable                  Pointer to the Variable Header.

+

+Returns:

+

+  VARIABLE_HEADER*      Pointer to last unavailable Variable Header

+

+--*/

+{

+  //

+  // The end of variable store

+  //

+  return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size);

+}

+

+EFI_STATUS

+EFIAPI

+FindVariable (

+  IN  CHAR16                  *VariableName,

+  IN  EFI_GUID                *VendorGuid,

+  OUT VARIABLE_POINTER_TRACK  *PtrTrack,

+  IN  VARIABLE_GLOBAL         *Global

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                Name of the variable to be found

+  VendorGuid                  Vendor GUID to be found.

+  PtrTrack                    Variable Track Pointer structure that contains

+                              Variable Information.

+                              Contains the pointer of Variable header.

+  Global                      VARIABLE_GLOBAL pointer

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_HEADER       *Variable[2];

+  VARIABLE_STORE_HEADER *VariableStoreHeader[2];

+  UINTN                 Index;

+

+  //

+  // 0: Non-Volatile, 1: Volatile

+  //

+  VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);

+  VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);

+

+  //

+  // Start Pointers for the variable.

+  // Actual Data Pointer where data can be written.

+  //

+  Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);

+  Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);

+

+  if (VariableName[0] != 0 && VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the variable by walk through non-volatile and volatile variable store

+  //

+  for (Index = 0; Index < 2; Index++) {

+    PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);

+    PtrTrack->EndPtr    = GetEndPointer (VariableStoreHeader[Index]);

+

+    while ((Variable[Index] != NULL) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {

+      if (Variable[Index]->StartId == VARIABLE_DATA && Variable[Index]->State == VAR_ADDED) {

+        if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {

+          if (VariableName[0] == 0) {

+            PtrTrack->CurrPtr   = Variable[Index];

+            PtrTrack->Volatile  = (BOOLEAN) Index;

+            return EFI_SUCCESS;

+          } else {

+            if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {

+              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), ArrayLength (VariableName))) {

+                PtrTrack->CurrPtr   = Variable[Index];

+                PtrTrack->Volatile  = (BOOLEAN) Index;

+                return EFI_SUCCESS;

+              }

+            }

+          }

+        }

+      }

+

+      Variable[Index] = GetNextVariablePtr (Variable[Index]);

+    }

+  }

+  PtrTrack->CurrPtr = NULL;

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+GetVariable (

+  IN      CHAR16            *VariableName,

+  IN      EFI_GUID          * VendorGuid,

+  OUT     UINT32            *Attributes OPTIONAL,

+  IN OUT  UINTN             *DataSize,

+  OUT     VOID              *Data,

+  IN      VARIABLE_GLOBAL   * Global,

+  IN      UINT32            Instance

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                    Name of Variable to be found

+  VendorGuid                      Variable vendor GUID

+  Attributes OPTIONAL             Attribute value of the variable found

+  DataSize                        Size of Data found. If size is less than the

+                                  data, this value contains the required size.

+  Data                            Data pointer

+  Global                          Pointer to VARIABLE_GLOBAL structure

+  Instance                        Instance of the Firmware Volume.

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarDataSize;

+  EFI_STATUS              Status;

+

+  if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find existing variable

+  //

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get data size

+  //

+  VarDataSize = Variable.CurrPtr->DataSize;

+  if (*DataSize >= VarDataSize) {

+    CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);

+    if (Attributes) {

+      *Attributes = Variable.CurrPtr->Attributes;

+    }

+

+    *DataSize = VarDataSize;

+    return EFI_SUCCESS;

+  } else {

+    *DataSize = VarDataSize;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+GetNextVariableName (

+  IN OUT  UINTN             *VariableNameSize,

+  IN OUT  CHAR16            *VariableName,

+  IN OUT  EFI_GUID          *VendorGuid,

+  IN      VARIABLE_GLOBAL   *Global,

+  IN      UINT32            Instance

+  )

+/*++

+

+Routine Description:

+

+  This code Finds the Next available variable

+

+Arguments:

+

+  VariableNameSize            Size of the variable

+  VariableName                Pointer to variable name

+  VendorGuid                  Variable Vendor Guid

+  Global                      VARIABLE_GLOBAL structure pointer.

+  Instance                    FV instance

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarNameSize;

+  EFI_STATUS              Status;

+

+  if (VariableNameSize == NULL || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  while (TRUE) {

+    if (VariableName[0] != 0) {

+      //

+      // If variable name is not NULL, get next variable

+      //

+      Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);

+    }

+    //

+    // If both volatile and non-volatile variable store are parsed,

+    // return not found

+    //

+    if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {

+      Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));

+      if (Variable.Volatile) {

+        Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));

+        Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));

+      } else {

+        return EFI_NOT_FOUND;

+      }

+

+      Variable.CurrPtr = Variable.StartPtr;

+      if (Variable.CurrPtr->StartId != VARIABLE_DATA) {

+        continue;

+      }

+    }

+    //

+    // Variable is found

+    //

+    if (Variable.CurrPtr->StartId == VARIABLE_DATA && Variable.CurrPtr->State == VAR_ADDED) {

+      if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {

+        VarNameSize = Variable.CurrPtr->NameSize;

+        if (VarNameSize <= *VariableNameSize) {

+          CopyMem (

+            VariableName,

+            GET_VARIABLE_NAME_PTR (Variable.CurrPtr),

+            VarNameSize

+            );

+          CopyMem (

+            VendorGuid,

+            &Variable.CurrPtr->VendorGuid,

+            sizeof (EFI_GUID)

+            );

+          Status = EFI_SUCCESS;

+        } else {

+          Status = EFI_BUFFER_TOO_SMALL;

+        }

+

+        *VariableNameSize = VarNameSize;

+        return Status;

+      }

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+SetVariable (

+  IN CHAR16                  *VariableName,

+  IN EFI_GUID                *VendorGuid,

+  IN UINT32                  Attributes,

+  IN UINTN                   DataSize,

+  IN VOID                    *Data,

+  IN VARIABLE_GLOBAL         *Global,

+  IN UINTN                   *VolatileOffset,

+  IN UINTN                   *NonVolatileOffset,

+  IN UINT32                  Instance

+  )

+/*++

+

+Routine Description:

+

+  This code sets variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                    Name of Variable to be found

+  VendorGuid                      Variable vendor GUID

+  Attributes                      Attribute value of the variable found

+  DataSize                        Size of Data found. If size is less than the

+                                  data, this value contains the required size.

+  Data                            Data pointer

+  Global                          Pointer to VARIABLE_GLOBAL structure

+  VolatileOffset                  The offset of last volatile variable

+  NonVolatileOffset               The offset of last non-volatile variable

+  Instance                        Instance of the Firmware Volume.

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  EFI_STATUS              Status;

+  VARIABLE_HEADER         *NextVariable;

+  UINTN                   VarNameSize;

+  UINTN                   VarNameOffset;

+  UINTN                   VarDataOffset;

+  UINTN                   VarSize;

+

+  if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Status == EFI_INVALID_PARAMETER) {

+    return Status;

+  }

+  //

+  //  The size of the VariableName, including the Unicode Null in bytes plus

+  //  the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.

+  //

+  else if (sizeof (VARIABLE_HEADER) + (ArrayLength (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  //  Make sure if runtime bit is set, boot service bit is set also

+  //

+  else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS

+          ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Runtime but Attribute is not Runtime

+  //

+  else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Cannot set volatile variable in Runtime

+  //

+  else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Setting a data variable with no access, or zero DataSize attributes

+  // specified causes it to be deleted.

+  //

+  else if (DataSize == 0 || Attributes == 0) {

+    if (!EFI_ERROR (Status)) {

+      Variable.CurrPtr->State &= VAR_DELETED;

+      return EFI_SUCCESS;

+    }

+

+    return EFI_NOT_FOUND;

+  } else {

+    if (!EFI_ERROR (Status)) {

+      //

+      // If the variable is marked valid and the same data has been passed in

+      // then return to the caller immediately.

+      //

+      if (Variable.CurrPtr->DataSize == DataSize &&

+          !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)

+            ) {

+        return EFI_SUCCESS;

+      } else if (Variable.CurrPtr->State == VAR_ADDED) {

+        //

+        // Mark the old variable as in delete transition

+        //

+        Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;

+      }

+    }

+    //

+    // Create a new variable and copy the data.

+    //

+    VarNameOffset = sizeof (VARIABLE_HEADER);

+    VarNameSize   = ArrayLength (VariableName);

+    VarDataOffset = VarNameOffset + VarNameSize + GetPadSize (VarNameSize);

+    VarSize       = VarDataOffset + DataSize + GetPadSize (DataSize);

+

+    if (Attributes & EFI_VARIABLE_NON_VOLATILE) {

+      if ((UINT32) (VarSize +*NonVolatileOffset) >

+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size

+            ) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      NextVariable        = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);

+      *NonVolatileOffset  = *NonVolatileOffset + VarSize;

+    } else {

+      if (EfiAtRuntime ()) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if ((UINT32) (VarSize +*VolatileOffset) >

+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size

+            ) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      NextVariable    = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);

+      *VolatileOffset = *VolatileOffset + VarSize;

+    }

+

+    NextVariable->StartId     = VARIABLE_DATA;

+    NextVariable->Attributes  = Attributes;

+    NextVariable->State       = VAR_ADDED;

+    NextVariable->Reserved    = 0;

+

+    //

+    // There will be pad bytes after Data, the NextVariable->NameSize and

+    // NextVariable->NameSize should not include pad size so that variable

+    // service can get actual size in GetVariable

+    //

+    NextVariable->NameSize  = (UINT32)VarNameSize;

+    NextVariable->DataSize  = (UINT32)DataSize;

+

+    CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));

+    CopyMem (

+      (UINT8 *) ((UINTN) NextVariable + VarNameOffset),

+      VariableName,

+      VarNameSize

+      );

+    CopyMem (

+      (UINT8 *) ((UINTN) NextVariable + VarDataOffset),

+      Data,

+      DataSize

+      );

+

+    //

+    // Mark the old variable as deleted

+    //

+    if (!EFI_ERROR (Status)) {

+      Variable.CurrPtr->State &= VAR_DELETED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+InitializeVariableStore (

+  OUT EFI_PHYSICAL_ADDRESS  *VariableBase,

+  OUT UINTN                 *LastVariableOffset

+  )

+/*++

+

+Routine Description:

+  This function initializes variable store

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  VARIABLE_STORE_HEADER *VariableStore;

+

+  //

+  // Allocate memory for volatile variable store

+  //

+  VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (

+                                              VARIABLE_STORE_SIZE

+                                              );

+  if (NULL == VariableStore) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetMem (VariableStore, VARIABLE_STORE_SIZE, 0xff);

+

+  //

+  // Variable Specific Data

+  //

+  *VariableBase             = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;

+  *LastVariableOffset       = sizeof (VARIABLE_STORE_HEADER);

+

+  VariableStore->Signature  = VARIABLE_STORE_SIGNATURE;

+  VariableStore->Size       = VARIABLE_STORE_SIZE;

+  VariableStore->Format     = VARIABLE_STORE_FORMATTED;

+  VariableStore->State      = VARIABLE_STORE_HEALTHY;

+  VariableStore->Reserved   = 0;

+  VariableStore->Reserved1  = 0;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+VariableCommonInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  This function does common initialization for variable services

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Allocate memory for mVariableModuleGlobal

+  //

+  mVariableModuleGlobal = (ESAL_VARIABLE_GLOBAL *) AllocateRuntimePool (

+                                                    sizeof (ESAL_VARIABLE_GLOBAL)

+                                                    );

+  if (NULL == mVariableModuleGlobal) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Intialize volatile variable store

+  //

+  Status = InitializeVariableStore (

+            &mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase,

+            &mVariableModuleGlobal->VolatileLastVariableOffset

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Intialize non volatile variable store

+  //

+  Status = InitializeVariableStore (

+            &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,

+            &mVariableModuleGlobal->NonVolatileLastVariableOffset

+            );

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.dxs b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.dxs
new file mode 100644
index 0000000..51c93d7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.dxs
@@ -0,0 +1,25 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EmuVariable.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include "DxeDepex.h"

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.mbd b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.mbd
new file mode 100644
index 0000000..4cc2c20
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>EmuVariable</BaseName>

+    <Guid>CBD2E4D5-7068-4FF5-B866-9822B4AD8D60</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-23 16:05</Created>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Arch ArchType="IPF">

+      <Library>EdkDxeSalLib</Library>

+    </Arch>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.msa b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.msa
new file mode 100644
index 0000000..ca5d21b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.msa
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>EmuVariable</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>CBD2E4D5-7068-4FF5-B866-9822B4AD8D60</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-23 16:05</Created>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>EmuVariable.c</Filename>

+    <Filename>EmuVariable.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>InitVariable.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>InitVariable.c</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>InitVariable.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/InitVariable.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalVariableServices</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/InitVariable.c b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/InitVariable.c
new file mode 100644
index 0000000..0ad8664
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/InitVariable.c
@@ -0,0 +1,185 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  InitVariable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;

+

+EFI_STATUS

+EFIAPI

+RuntimeServiceGetVariable (

+  IN CHAR16        *VariableName,

+  IN EFI_GUID      * VendorGuid,

+  OUT UINT32       *Attributes OPTIONAL,

+  IN OUT UINTN     *DataSize,

+  OUT VOID         *Data

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return GetVariable (

+          VariableName,

+          VendorGuid,

+          Attributes OPTIONAL,

+          DataSize,

+          Data,

+          &mVariableModuleGlobal->VariableBase[Physical],

+          mVariableModuleGlobal->FvbInstance

+          );

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeServiceGetNextVariableName (

+  IN OUT UINTN     *VariableNameSize,

+  IN OUT CHAR16    *VariableName,

+  IN OUT EFI_GUID  *VendorGuid

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return GetNextVariableName (

+          VariableNameSize,

+          VariableName,

+          VendorGuid,

+          &mVariableModuleGlobal->VariableBase[Physical],

+          mVariableModuleGlobal->FvbInstance

+          );

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeServiceSetVariable (

+  IN CHAR16        *VariableName,

+  IN EFI_GUID      *VendorGuid,

+  IN UINT32        Attributes,

+  IN UINTN         DataSize,

+  IN VOID          *Data

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return SetVariable (

+          VariableName,

+          VendorGuid,

+          Attributes,

+          DataSize,

+          Data,

+          &mVariableModuleGlobal->VariableBase[Physical],

+          &mVariableModuleGlobal->VolatileLastVariableOffset,

+          &mVariableModuleGlobal->NonVolatileLastVariableOffset,

+          mVariableModuleGlobal->FvbInstance

+          );

+}

+

+VOID

+EFIAPI

+VariableClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase

+    );

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase

+    );

+  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);

+}

+

+EFI_STATUS

+EFIAPI

+VariableServiceInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_HANDLE  NewHandle;

+  EFI_STATUS  Status;

+

+  Status = VariableCommonInitialize (ImageHandle, SystemTable);

+  ASSERT_EFI_ERROR (Status);

+

+  SystemTable->RuntimeServices->GetVariable         = RuntimeServiceGetVariable;

+  SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName;

+  SystemTable->RuntimeServices->SetVariable         = RuntimeServiceSetVariable;

+

+  //

+  // Now install the Variable Runtime Architectural Protocol on a new handle

+  //

+  NewHandle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &NewHandle,

+                  &gEfiVariableArchProtocolGuid,

+                  NULL,

+                  &gEfiVariableWriteArchProtocolGuid,

+                  NULL,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/Ipf/InitVariable.c b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/Ipf/InitVariable.c
new file mode 100644
index 0000000..061e6db
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/Ipf/InitVariable.c
@@ -0,0 +1,167 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  IpfVariable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;

+

+SAL_RETURN_REGS

+EsalVariableCommonEntry (

+  IN  UINT64                                      FunctionId,

+  IN  UINT64                                      Arg2,

+  IN  UINT64                                      Arg3,

+  IN  UINT64                                      Arg4,

+  IN  UINT64                                      Arg5,

+  IN  UINT64                                      Arg6,

+  IN  UINT64                                      Arg7,

+  IN  UINT64                                      Arg8,

+  IN  SAL_EXTENDED_SAL_PROC                       ExtendedSalProc,

+  IN  BOOLEAN                                     VirtualMode,

+  IN  ESAL_VARIABLE_GLOBAL                        *Global

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  SAL_RETURN_REGS ReturnVal;

+

+  switch (FunctionId) {

+  case EsalGetVariable:

+    ReturnVal.Status = GetVariable (

+                        (CHAR16 *) Arg2,

+                        (EFI_GUID *) Arg3,

+                        (UINT32 *) Arg4,

+                        (UINTN *) Arg5,

+                        (VOID *) Arg6,

+                        &Global->VariableBase[VirtualMode],

+                        Global->FvbInstance

+                        );

+    return ReturnVal;

+

+  case EsalGetNextVariableName:

+    ReturnVal.Status = GetNextVariableName (

+                        (UINTN *) Arg2,

+                        (CHAR16 *) Arg3,

+                        (EFI_GUID *) Arg4,

+                        &Global->VariableBase[VirtualMode],

+                        Global->FvbInstance

+                        );

+    return ReturnVal;

+

+  case EsalSetVariable:

+    ReturnVal.Status = SetVariable (

+                        (CHAR16 *) Arg2,

+                        (EFI_GUID *) Arg3,

+                        (UINT32) Arg4,

+                        (UINTN) Arg5,

+                        (VOID *) Arg6,

+                        &Global->VariableBase[VirtualMode],

+                        (UINTN *) &Global->VolatileLastVariableOffset,

+                        (UINTN *) &Global->NonVolatileLastVariableOffset,

+                        Global->FvbInstance

+                        );

+    return ReturnVal;

+

+  default:

+    ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;

+    return ReturnVal;

+  }

+}

+

+

+VOID

+VariableClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  CopyMem (

+    &mVariableModuleGlobal->VariableBase[Virtual],

+    &mVariableModuleGlobal->VariableBase[Physical],

+    sizeof (VARIABLE_GLOBAL)

+    );

+

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Virtual].NonVolatileVariableBase

+    );

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Virtual].VolatileVariableBase

+    );

+  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);

+}

+

+EFI_STATUS

+VariableServiceInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = VariableCommonInitialize (ImageHandle, SystemTable);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  //  Register All the Functions with Extended Sal.

+  //

+  RegisterEsalClass (

+    &gEfiExtendedSalVariableServicesProtocolGuid,

+    mVariableModuleGlobal,

+    EsalVariableCommonEntry,

+    EsalGetVariable,

+    EsalVariableCommonEntry,

+    EsalGetNextVariableName,

+    EsalVariableCommonEntry,

+    EsalSetVariable,

+    NULL

+    );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/Variable.h b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/Variable.h
new file mode 100644
index 0000000..d1fd5e2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/Variable.h
@@ -0,0 +1,143 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.h

+  

+Abstract:

+

+--*/

+

+#ifndef _VARIABLE_H

+#define _VARIABLE_H

+

+//

+// Statements that include other header files

+//

+

+//

+// BugBug: We need relcate the head file.

+// 

+#include <Common/Variable.h>

+

+#if defined (MDE_CPU_IPF)

+#define ALIGNMENT  8

+#else

+#define ALIGNMENT  1

+#endif

+

+

+#define VARIABLE_STORE_SIZE (64 * 1024)

+#define SCRATCH_SIZE        (4 * 1024)

+

+//

+// Define GET_PAD_SIZE to optimize compiler

+//

+#if ((ALIGNMENT == 0) || (ALIGNMENT == 1))

+#define GET_PAD_SIZE(a) (0)

+#else

+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))

+#endif

+

+#define GET_VARIABLE_NAME_PTR(a)  (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))

+

+typedef enum {

+  Physical,

+  Virtual

+} VARIABLE_POINTER_TYPE;

+

+typedef struct {

+  VARIABLE_HEADER *CurrPtr;

+  VARIABLE_HEADER *EndPtr;

+  VARIABLE_HEADER *StartPtr;

+  BOOLEAN         Volatile;

+} VARIABLE_POINTER_TRACK;

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  VolatileVariableBase;

+  EFI_PHYSICAL_ADDRESS  NonVolatileVariableBase;

+} VARIABLE_GLOBAL;

+

+typedef struct {

+  VARIABLE_GLOBAL VariableBase[2];

+  UINTN           VolatileLastVariableOffset;

+  UINTN           NonVolatileLastVariableOffset;

+  UINT32          FvbInstance;

+} ESAL_VARIABLE_GLOBAL;

+

+//

+// Functions

+//

+EFI_STATUS

+EFIAPI

+VariableCommonInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+EFI_STATUS

+EFIAPI

+VariableServiceInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+VOID

+EFIAPI

+VariableClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GetVariable (

+  IN      CHAR16            *VariableName,

+  IN      EFI_GUID          * VendorGuid,

+  OUT     UINT32            *Attributes OPTIONAL,

+  IN OUT  UINTN             *DataSize,

+  OUT     VOID              *Data,

+  IN      VARIABLE_GLOBAL   * Global,

+  IN      UINT32            Instance

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GetNextVariableName (

+  IN OUT  UINTN             *VariableNameSize,

+  IN OUT  CHAR16            *VariableName,

+  IN OUT  EFI_GUID          *VendorGuid,

+  IN      VARIABLE_GLOBAL   *Global,

+  IN      UINT32            Instance

+  )

+;

+

+EFI_STATUS

+EFIAPI

+SetVariable (

+  IN CHAR16                  *VariableName,

+  IN EFI_GUID                *VendorGuid,

+  IN UINT32                  Attributes,

+  IN UINTN                   DataSize,

+  IN VOID                    *Data,

+  IN VARIABLE_GLOBAL         *Global,

+  IN UINTN                   *VolatileOffset,

+  IN UINTN                   *NonVolatileOffset,

+  IN UINT32                  Instance

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/build.xml b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/build.xml
new file mode 100644
index 0000000..11153e6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/EmuVariable/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EmuVariable"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/EmuVariable/RuntimeDxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EmuVariable">

+      <GenBuild baseName="EmuVariable" mbdFilename="${MODULE_DIR}/EmuVariable.mbd" msaFilename="${MODULE_DIR}/EmuVariable.msa"/>

+   </target>

+   <target depends="EmuVariable_clean" name="clean"/>

+   <target depends="EmuVariable_cleanall" name="cleanall"/>

+   <target name="EmuVariable_clean">

+      <OutputDirSetup baseName="EmuVariable" mbdFilename="${MODULE_DIR}/EmuVariable.mbd" msaFilename="${MODULE_DIR}/EmuVariable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EmuVariable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EmuVariable_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EmuVariable_cleanall">

+      <OutputDirSetup baseName="EmuVariable" mbdFilename="${MODULE_DIR}/EmuVariable.mbd" msaFilename="${MODULE_DIR}/EmuVariable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EmuVariable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EmuVariable_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EmuVariable*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c
new file mode 100644
index 0000000..0d20e88
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.c
@@ -0,0 +1,951 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.  

+

+

+Module Name:

+

+  FtwLite.c

+

+Abstract:

+

+  This is a simple fault tolerant write driver, based on PlatformFd library.

+  And it only supports write BufferSize <= SpareAreaLength.

+

+  This boot service only protocol provides fault tolerant write capability for 

+  block devices.  The protocol has internal non-volatile intermediate storage 

+  of the data and private information. It should be able to recover 

+  automatically from a critical fault, such as power failure. 

+

+Notes:

+

+  The implementation uses an FTW Lite (Fault Tolerant Write) Work Space. 

+  This work space is a memory copy of the work space on the Woring Block,

+  the size of the work space is the FTW_WORK_SPACE_SIZE bytes.

+

+--*/

+

+#include <FtwLite.h>

+

+//

+// In write function, we should check the target range to prevent the user

+// from writing Spare block and Working space directly.

+//

+//

+// Fault Tolerant Write Protocol API

+//

+EFI_STATUS

+EFIAPI

+FtwLiteWrite (

+  IN EFI_FTW_LITE_PROTOCOL                 *This,

+  IN EFI_HANDLE                            FvbHandle,

+  IN EFI_LBA                               Lba,

+  IN UINTN                                 Offset,

+  IN OUT UINTN                             *NumBytes,

+  IN VOID                                  *Buffer

+  )

+/*++

+

+Routine Description:

+    Starts a target block update. This function will record data about write 

+    in fault tolerant storage and will complete the write in a recoverable 

+    manner, ensuring at all times that either the original contents or 

+    the modified contents are available.

+

+Arguments:

+    This             - Calling context

+    FvbHandle        - The handle of FVB protocol that provides services for 

+                       reading, writing, and erasing the target block.

+    Lba              - The logical block address of the target block.  

+    Offset           - The offset within the target block to place the data.

+    NumBytes         - The number of bytes to write to the target block.

+    Buffer           - The data to write.

+

+Returns:

+    EFI_SUCCESS          - The function completed successfully

+    EFI_BAD_BUFFER_SIZE  - The write would span a target block, which is not 

+                           a valid action.

+    EFI_ACCESS_DENIED    - No writes have been allocated.

+    EFI_NOT_FOUND        - Cannot find FVB by handle.

+    EFI_OUT_OF_RESOURCES - Cannot allocate memory.

+    EFI_ABORTED          - The function could not complete successfully.

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice;

+  EFI_FTW_LITE_RECORD                 *Record;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  EFI_PHYSICAL_ADDRESS                FvbPhysicalAddress;

+  UINTN                               MyLength;

+  UINTN                               MyOffset;

+  UINTN                               MyBufferSize;

+  UINT8                               *MyBuffer;

+  UINTN                               SpareBufferSize;

+  UINT8                               *SpareBuffer;

+  UINTN                               Index;

+  UINT8                               *Ptr;

+  EFI_DEV_PATH_PTR                    DevPtr;

+

+  //

+  // Refresh work space and get last record

+  //

+  FtwLiteDevice = FTW_LITE_CONTEXT_FROM_THIS (This);

+  Status        = WorkSpaceRefresh (FtwLiteDevice);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+

+  Record = FtwLiteDevice->FtwLastRecord;

+

+  //

+  // Check the flags of last write record

+  //

+  if ((Record->WriteAllocated == FTW_VALID_STATE) || (Record->SpareCompleted == FTW_VALID_STATE)) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // IF former record has completed, THEN use next record

+  //

+  if (Record->WriteCompleted == FTW_VALID_STATE) {

+    Record++;

+    FtwLiteDevice->FtwLastRecord = Record;

+  }

+

+  MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;

+

+  //

+  // Check if the input data can fit within the target block

+  //

+  if ((Offset +*NumBytes) > FtwLiteDevice->SpareAreaLength) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+  //

+  // Check if there is enough free space for allocate a record

+  //

+  if ((MyOffset + WRITE_TOTAL_SIZE) > FtwLiteDevice->FtwWorkSpaceSize) {

+    Status = FtwReclaimWorkSpace (FtwLiteDevice);

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "FtwLite: Reclaim work space - %r", Status));

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // Get the FVB protocol by handle

+  //

+  Status = FtwGetFvbByHandle (FvbHandle, &Fvb);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Allocate a write record in workspace.

+  // Update Header->WriteAllocated as VALID

+  //

+  Status = FtwUpdateFvState (

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkSpaceLba,

+            FtwLiteDevice->FtwWorkSpaceBase + MyOffset,

+            WRITE_ALLOCATED

+            );

+

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Allocate record - %r\n", Status));

+    return EFI_ABORTED;

+  }

+

+  Record->WriteAllocated = FTW_VALID_STATE;

+

+  //

+  // Prepare data of write record, filling DevPath with memory mapped address.

+  //

+  DevPtr.MemMap                 = (MEMMAP_DEVICE_PATH *) &Record->DevPath;

+  DevPtr.MemMap->Header.Type    = HARDWARE_DEVICE_PATH;

+  DevPtr.MemMap->Header.SubType = HW_MEMMAP_DP;

+  SetDevicePathNodeLength (&DevPtr.MemMap->Header, sizeof (MEMMAP_DEVICE_PATH));

+

+  Status = Fvb->GetPhysicalAddress (Fvb, &FvbPhysicalAddress);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Get FVB physical address - %r\n", Status));

+    return EFI_ABORTED;

+  }

+

+  DevPtr.MemMap->MemoryType       = EfiMemoryMappedIO;

+  DevPtr.MemMap->StartingAddress  = FvbPhysicalAddress;

+  DevPtr.MemMap->EndingAddress    = FvbPhysicalAddress +*NumBytes;

+  //

+  // ignored!

+  //

+  Record->Lba       = Lba;

+  Record->Offset    = Offset;

+  Record->NumBytes  = *NumBytes;

+

+  //

+  // Write the record to the work space.

+  //

+  MyOffset  = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;

+  MyLength  = FTW_LITE_RECORD_SIZE;

+

+  Status = FtwLiteDevice->FtwFvBlock->Write (

+                                        FtwLiteDevice->FtwFvBlock,

+                                        FtwLiteDevice->FtwWorkSpaceLba,

+                                        FtwLiteDevice->FtwWorkSpaceBase + MyOffset,

+                                        &MyLength,

+                                        (UINT8 *) Record

+                                        );

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Record has been written to working block, then write data.

+  //

+  //

+  // Allocate a memory buffer

+  //

+  MyBufferSize  = FtwLiteDevice->SpareAreaLength;

+  MyBuffer      = AllocatePool (MyBufferSize);

+  if (MyBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Starting at Lba, if the number of the rest blocks on Fvb is less

+  // than NumberOfSpareBlock.

+  //

+  //

+  // Read all original data from target block to memory buffer

+  //

+  if (IsInWorkingBlock (FtwLiteDevice, Fvb, Lba)) {

+    //

+    // If target block falls into working block, we must follow the process of

+    // updating working block.

+    //

+    Ptr = MyBuffer;

+    for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+      MyLength = FtwLiteDevice->SizeOfSpareBlock;

+      Status = FtwLiteDevice->FtwFvBlock->Read (

+                                            FtwLiteDevice->FtwFvBlock,

+                                            FtwLiteDevice->FtwWorkBlockLba + Index,

+                                            0,

+                                            &MyLength,

+                                            Ptr

+                                            );

+      if (EFI_ERROR (Status)) {

+        gBS->FreePool (MyBuffer);

+        return EFI_ABORTED;

+      }

+

+      Ptr += MyLength;

+    }

+    //

+    // Update Offset by adding the offset from the start LBA of working block to

+    // the target LBA. The target block can not span working block!

+    //

+    Offset = (((UINTN) (Lba - FtwLiteDevice->FtwWorkBlockLba)) * FtwLiteDevice->SizeOfSpareBlock + Offset);

+    ASSERT ((Offset +*NumBytes) <= FtwLiteDevice->SpareAreaLength);

+

+  } else {

+

+    Ptr = MyBuffer;

+    for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+      MyLength  = FtwLiteDevice->SizeOfSpareBlock;

+      Status    = Fvb->Read (Fvb, Lba + Index, 0, &MyLength, Ptr);

+      if (EFI_ERROR (Status)) {

+        gBS->FreePool (MyBuffer);

+        return EFI_ABORTED;

+      }

+

+      Ptr += MyLength;

+    }

+  }

+  //

+  // Overwrite the updating range data with

+  // the input buffer content

+  //

+  CopyMem (MyBuffer + Offset, Buffer, *NumBytes);

+

+  //

+  // Try to keep the content of spare block

+  // Save spare block into a spare backup memory buffer (Sparebuffer)

+  //

+  SpareBufferSize = FtwLiteDevice->SpareAreaLength;

+  SpareBuffer     = AllocatePool (SpareBufferSize);

+  if (SpareBuffer == NULL) {

+    gBS->FreePool (MyBuffer);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Ptr = SpareBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    MyLength = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Read (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &MyLength,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (MyBuffer);

+      gBS->FreePool (SpareBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += MyLength;

+  }

+  //

+  // Write the memory buffer to spare block

+  // Don't forget to erase Flash first.

+  //

+  Status  = FtwEraseSpareBlock (FtwLiteDevice);

+  Ptr     = MyBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    MyLength = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Write (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &MyLength,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (MyBuffer);

+      gBS->FreePool (SpareBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += MyLength;

+  }

+  //

+  // Free MyBuffer

+  //

+  gBS->FreePool (MyBuffer);

+

+  //

+  // Set the SpareCompleteD in the FTW record,

+  //

+  MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;

+  Status = FtwUpdateFvState (

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkSpaceLba,

+            FtwLiteDevice->FtwWorkSpaceBase + MyOffset,

+            SPARE_COMPLETED

+            );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (SpareBuffer);

+    return EFI_ABORTED;

+  }

+

+  Record->SpareCompleted = FTW_VALID_STATE;

+

+  //

+  //  Since the content has already backuped in spare block, the write is

+  //  guaranteed to be completed with fault tolerant manner.

+  //

+  Status = FtwWriteRecord (FtwLiteDevice, Fvb);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (SpareBuffer);

+    return EFI_ABORTED;

+  }

+

+  Record++;

+  FtwLiteDevice->FtwLastRecord = Record;

+

+  //

+  // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.

+  //

+  Status  = FtwEraseSpareBlock (FtwLiteDevice);

+  Ptr     = SpareBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    MyLength = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Write (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &MyLength,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (SpareBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += MyLength;

+  }

+  //

+  // All success.

+  //

+  gBS->FreePool (SpareBuffer);

+

+  DEBUG (

+    (EFI_D_FTW_LITE,

+    "FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n",

+    Lba,

+    Offset,

+    *NumBytes)

+    );

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+FtwWriteRecord (

+  IN EFI_FTW_LITE_DEVICE                   *FtwLiteDevice,

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb

+  )

+/*++

+

+Routine Description:

+    Write a record with fault tolerant mannaer.

+    Since the content has already backuped in spare block, the write is 

+    guaranteed to be completed with fault tolerant manner.

+    

+Arguments:

+    FtwLiteDevice       - The private data of FTW_LITE driver

+    Fvb                 - The FVB protocol that provides services for 

+                          reading, writing, and erasing the target block.

+

+Returns:

+    EFI_SUCCESS         - The function completed successfully

+    EFI_ABORTED         - The function could not complete successfully

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_FTW_LITE_RECORD *Record;

+  EFI_LBA             WorkSpaceLbaOffset;  

+  UINTN               Offset;

+

+  //

+  // Spare Complete but Destination not complete,

+  // Recover the targt block with the spare block.

+  //

+  Record = FtwLiteDevice->FtwLastRecord;

+

+  //

+  // IF target block is working block, THEN Flush Spare Block To Working Block;

+  // ELSE IF target block is boot block, THEN Flush Spare Block To boot Block;

+  // ELSE flush spare block to normal target block.ENDIF

+  //

+  if (IsInWorkingBlock (FtwLiteDevice, Fvb, Record->Lba)) {

+    //

+    // If target block is working block, Attention:

+    // it's required to set SPARE_COMPLETED to spare block.

+    //

+    WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;

+    Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;

+    Status = FtwUpdateFvState (

+              FtwLiteDevice->FtwBackupFvb,

+              FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,

+              FtwLiteDevice->FtwWorkSpaceBase + Offset,

+              SPARE_COMPLETED

+              );

+    ASSERT_EFI_ERROR (Status);

+

+    Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);

+  } else if (IsBootBlock (FtwLiteDevice, Fvb, Record->Lba)) {

+    //

+    // Update boot block

+    //

+    Status = FlushSpareBlockToBootBlock (FtwLiteDevice);

+  } else {

+    //

+    // Update blocks other than working block or boot block

+    //

+    Status = FlushSpareBlockToTargetBlock (FtwLiteDevice, Fvb, Record->Lba);

+  }

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Set WriteCompleted flag in record

+  //

+  Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;

+  Status = FtwUpdateFvState (

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkSpaceLba,

+            FtwLiteDevice->FtwWorkSpaceBase + Offset,

+            WRITE_COMPLETED

+            );

+  ASSERT_EFI_ERROR (Status);

+

+  Record->WriteCompleted = FTW_VALID_STATE;

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+FtwRestart (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Restarts a previously interrupted write. The caller must provide the 

+    block protocol needed to complete the interrupted write.

+    

+Arguments:

+    FtwLiteDevice       - The private data of FTW_LITE driver

+    FvbHandle           - The handle of FVB protocol that provides services for 

+                          reading, writing, and erasing the target block.

+

+Returns:

+    EFI_SUCCESS         - The function completed successfully

+    EFI_ACCESS_DENIED   - No pending writes exist

+    EFI_NOT_FOUND       - FVB protocol not found by the handle

+    EFI_ABORTED         - The function could not complete successfully

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_FTW_LITE_RECORD                 *Record;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  EFI_DEV_PATH_PTR                    DevPathPtr;

+

+  //

+  // Spare Completed but Destination not complete,

+  // Recover the targt block with the spare block.

+  //

+  Record = FtwLiteDevice->FtwLastRecord;

+

+  //

+  // Only support memory mapped FVB device path by now.

+  //

+  DevPathPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath;

+  if (!((DevPathPtr.MemMap->Header.Type == HARDWARE_DEVICE_PATH) && (DevPathPtr.MemMap->Header.SubType == HW_MEMMAP_DP))

+      ) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Device Path is not memory mapped\n"));

+    return EFI_ABORTED;

+  }

+

+  Status = GetFvbByAddress (DevPathPtr.MemMap->StartingAddress, &Fvb);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  //  Since the content has already backuped in spare block, the write is

+  //  guaranteed to be completed with fault tolerant manner.

+  //

+  Status = FtwWriteRecord (FtwLiteDevice, Fvb);

+  DEBUG ((EFI_D_FTW_INFO, "FtwLite: Restart() - %r\n", Status));

+

+  Record++;

+  FtwLiteDevice->FtwLastRecord = Record;

+

+  //

+  // Erase Spare block

+  // This is restart, no need to keep spareblock content.

+  //

+  FtwEraseSpareBlock (FtwLiteDevice);

+

+  return Status;

+}

+

+

+EFI_STATUS

+FtwAbort (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Aborts all previous allocated writes.

+

+Arguments:

+    FtwLiteDevice    - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS      - The function completed successfully

+    EFI_ABORTED      - The function could not complete successfully.

+    EFI_NOT_FOUND    - No allocated writes exist.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Offset;

+

+  if (FtwLiteDevice->FtwLastRecord->WriteCompleted == FTW_VALID_STATE) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Update the complete state of the header as VALID and abort.

+  //

+  Offset = (UINT8 *) FtwLiteDevice->FtwLastRecord - FtwLiteDevice->FtwWorkSpace;

+  Status = FtwUpdateFvState (

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkSpaceLba,

+            FtwLiteDevice->FtwWorkSpaceBase + Offset,

+            WRITE_COMPLETED

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+

+  FtwLiteDevice->FtwLastRecord->WriteCompleted  = FTW_VALID_STATE;

+

+  Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);

+

+  //

+  // Erase the spare block

+  //

+  Status = FtwEraseSpareBlock (FtwLiteDevice);

+

+  DEBUG ((EFI_D_FTW_INFO, "FtwLite: Abort() success \n"));

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+InitializeFtwLite (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+  Routine Description: 

+    This function is the entry point of the Fault Tolerant Write driver.

+  

+  Arguments: 

+    ImageHandle   - EFI_HANDLE: A handle for the image that is initializing 

+                    this driver

+    SystemTable   - EFI_SYSTEM_TABLE: A pointer to the EFI system table

+        

+  Returns:  

+    EFI_SUCCESS           - FTW has finished the initialization

+    EFI_ABORTED           - FTW initialization error

+

+--*/

+{

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  UINTN                               Index;

+  EFI_HANDLE                          *HandleBuffer;

+  UINTN                               HandleCount;

+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;

+  EFI_PHYSICAL_ADDRESS                BaseAddress;

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice;

+  EFI_FTW_LITE_RECORD                 *Record;

+  UINTN                               Length;

+  EFI_STATUS                          Status;

+  UINTN                               Offset;

+  EFI_FLASH_MAP_ENTRY_DATA            *FlashMapEntry;

+  EFI_FV_BLOCK_MAP_ENTRY              *FvbMapEntry;

+  UINT32                              LbaIndex;

+  EFI_PEI_HOB_POINTERS                GuidHob;                  

+

+  //

+  // Allocate Private data of this driver,

+  // INCLUDING THE FtwWorkSpace[FTW_WORK_SPACE_SIZE].

+  //

+  FtwLiteDevice = NULL;

+  FtwLiteDevice = AllocatePool (sizeof (EFI_FTW_LITE_DEVICE) + FTW_WORK_SPACE_SIZE);

+  if (FtwLiteDevice != NULL) {

+    Status = EFI_SUCCESS;

+  } else {

+    Status = EFI_OUT_OF_RESOURCES;

+  }

+

+  ASSERT_EFI_ERROR (Status);

+

+  ZeroMem (FtwLiteDevice, sizeof (EFI_FTW_LITE_DEVICE));

+  FtwLiteDevice->Signature = FTW_LITE_DEVICE_SIGNATURE;

+

+  //

+  // Initialize other parameters, and set WorkSpace as FTW_ERASED_BYTE.

+  //

+  FtwLiteDevice->FtwWorkSpace     = (UINT8 *) (FtwLiteDevice + 1);

+  FtwLiteDevice->FtwWorkSpaceSize = FTW_WORK_SPACE_SIZE;

+  SetMem (

+    FtwLiteDevice->FtwWorkSpace,

+    FtwLiteDevice->FtwWorkSpaceSize,

+    FTW_ERASED_BYTE

+    );

+  FtwLiteDevice->FtwWorkSpaceHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FtwLiteDevice->FtwWorkSpace;

+

+  FtwLiteDevice->FtwLastRecord      = NULL;

+

+  FtwLiteDevice->SpareAreaLength  = 0;

+  FtwLiteDevice->WorkSpaceLength  = 0;

+

+  GuidHob.Raw = GetHobList ();

+  while (NULL != (GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw))) {

+    FlashMapEntry = (EFI_FLASH_MAP_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);

+    //

+    // Get the FTW work space Flash Map SUB area

+    //

+    if ((FlashMapEntry->AreaType == EFI_FLASH_AREA_FTW_STATE) && (FlashMapEntry->NumEntries == 1)) {

+      FtwLiteDevice->WorkSpaceAddress = FlashMapEntry->Entries[0].Base;

+      FtwLiteDevice->WorkSpaceLength  = (UINTN) FlashMapEntry->Entries[0].Length;

+    }

+    //

+    // Get the FTW backup SUB area

+    //

+    if ((FlashMapEntry->AreaType == EFI_FLASH_AREA_FTW_BACKUP) && (FlashMapEntry->NumEntries == 1)) {

+      FtwLiteDevice->SpareAreaAddress = FlashMapEntry->Entries[0].Base;

+      FtwLiteDevice->SpareAreaLength  = (UINTN) FlashMapEntry->Entries[0].Length;

+    }

+

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+

+  ASSERT ((FtwLiteDevice->WorkSpaceLength != 0) && (FtwLiteDevice->SpareAreaLength != 0));

+

+  //

+  // Locate FVB protocol

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiFirmwareVolumeBlockProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  ASSERT (HandleCount > 0);

+

+  FtwLiteDevice->FtwFvBlock       = NULL;

+  FtwLiteDevice->FtwBackupFvb     = NULL;

+  FtwLiteDevice->FtwWorkSpaceLba  = (EFI_LBA) (-1);

+  FtwLiteDevice->FtwSpareLba      = (EFI_LBA) (-1);

+  for (Index = 0; Index < HandleCount; Index += 1) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[Index],

+                    &gEfiFirmwareVolumeBlockProtocolGuid,

+                    (VOID **) &Fvb

+                    );

+    ASSERT_EFI_ERROR (Status);

+

+    Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress);

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) BaseAddress);

+

+    if ((FtwLiteDevice->WorkSpaceAddress >= BaseAddress) &&

+        (FtwLiteDevice->WorkSpaceAddress <= (BaseAddress + FwVolHeader->FvLength))

+        ) {

+      FtwLiteDevice->FtwFvBlock = Fvb;

+      //

+      // To get the LBA of work space

+      //

+      if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {

+        //

+        // FV may have multiple types of BlockLength

+        //

+        FvbMapEntry = &FwVolHeader->FvBlockMap[0];

+        while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->BlockLength == 0))) {

+          for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {

+            if (FtwLiteDevice->WorkSpaceAddress < (BaseAddress + FvbMapEntry->BlockLength * LbaIndex)) {

+              FtwLiteDevice->FtwWorkSpaceLba = LbaIndex - 1;

+              //

+              // Get the Work space size and Base(Offset)

+              //

+              FtwLiteDevice->FtwWorkSpaceSize = FtwLiteDevice->WorkSpaceLength;

+              FtwLiteDevice->FtwWorkSpaceBase = (UINTN) (FtwLiteDevice->WorkSpaceAddress - (BaseAddress + FvbMapEntry->BlockLength * (LbaIndex - 1)));

+              break;

+            }

+          }

+          //

+          // end for

+          //

+          FvbMapEntry++;

+        }

+        //

+        // end while

+        //

+      }

+    }

+

+    if ((FtwLiteDevice->SpareAreaAddress >= BaseAddress) &&

+        (FtwLiteDevice->SpareAreaAddress <= (BaseAddress + FwVolHeader->FvLength))

+        ) {

+      FtwLiteDevice->FtwBackupFvb = Fvb;

+      //

+      // To get the LBA of spare

+      //

+      if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {

+        //

+        // FV may have multiple types of BlockLength

+        //

+        FvbMapEntry = &FwVolHeader->FvBlockMap[0];

+        while (!((FvbMapEntry->NumBlocks == 0) && (FvbMapEntry->BlockLength == 0))) {

+          for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {

+            if (FtwLiteDevice->SpareAreaAddress < (BaseAddress + FvbMapEntry->BlockLength * LbaIndex)) {

+              //

+              // Get the NumberOfSpareBlock and SizeOfSpareBlock

+              //

+              FtwLiteDevice->FtwSpareLba        = LbaIndex - 1;

+              FtwLiteDevice->SizeOfSpareBlock   = FvbMapEntry->BlockLength;

+              FtwLiteDevice->NumberOfSpareBlock = FtwLiteDevice->SpareAreaLength / FtwLiteDevice->SizeOfSpareBlock;

+              //

+              // Check the range of spare area to make sure that it's in FV range

+              //

+              ASSERT ((FtwLiteDevice->FtwSpareLba + FtwLiteDevice->NumberOfSpareBlock) <= FvbMapEntry->NumBlocks);

+              break;

+            }

+          }

+

+          FvbMapEntry++;

+        }

+        //

+        // end while

+        //

+      }

+    }

+  }

+  //

+  // Calculate the start LBA of working block. Working block is an area which

+  // contains working space in its last block and has the same size as spare

+  // block, unless there are not enough blocks before the block that contains

+  // working space.

+  //

+  FtwLiteDevice->FtwWorkBlockLba = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->NumberOfSpareBlock + 1;

+  if ((INT64) (FtwLiteDevice->FtwWorkBlockLba) < 0) {

+    FtwLiteDevice->FtwWorkBlockLba = 0;

+  }

+

+  if ((FtwLiteDevice->FtwFvBlock == NULL) ||

+      (FtwLiteDevice->FtwBackupFvb == NULL) ||

+      (FtwLiteDevice->FtwWorkSpaceLba == (EFI_LBA) (-1)) ||

+      (FtwLiteDevice->FtwSpareLba == (EFI_LBA) (-1))

+      ) {

+    DEBUG ((EFI_D_ERROR, "FtwLite: Working or spare FVB not ready\n"));

+    ASSERT_EFI_ERROR (Status);

+  }

+  //

+  // Refresh workspace data from working block

+  //

+  Status = WorkSpaceRefresh (FtwLiteDevice);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // If the working block workspace is not valid, try the spare block

+  //

+  if (!IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace invalid, read from backup\n"));

+    //

+    // Read from spare block

+    //

+    Length = FtwLiteDevice->FtwWorkSpaceSize;

+    Status = FtwLiteDevice->FtwBackupFvb->Read (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba,

+                                            FtwLiteDevice->FtwWorkSpaceBase,

+                                            &Length,

+                                            FtwLiteDevice->FtwWorkSpace

+                                            );

+    ASSERT_EFI_ERROR (Status);

+

+    //

+    // If spare block is valid, then replace working block content.

+    //

+    if (IsValidWorkSpace (FtwLiteDevice->FtwWorkSpaceHeader)) {

+      Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart working block in Init() - %r\n", Status));

+      ASSERT_EFI_ERROR (Status);

+

+      FtwAbort (FtwLiteDevice);

+      //

+      // Refresh work space.

+      //

+      Status = WorkSpaceRefresh (FtwLiteDevice);

+      if (EFI_ERROR (Status)) {

+        return EFI_ABORTED;

+      }

+    } else {

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: Both are invalid, init workspace\n"));

+      //

+      // If both are invalid, then initialize work space.

+      //

+      SetMem (

+        FtwLiteDevice->FtwWorkSpace,

+        FtwLiteDevice->FtwWorkSpaceSize,

+        FTW_ERASED_BYTE

+        );

+      InitWorkSpaceHeader (FtwLiteDevice->FtwWorkSpaceHeader);

+      //

+      // Write to work space on the working block

+      //

+      Length = FtwLiteDevice->FtwWorkSpaceSize;

+      Status = FtwLiteDevice->FtwFvBlock->Write (

+                                            FtwLiteDevice->FtwFvBlock,

+                                            FtwLiteDevice->FtwWorkSpaceLba,

+                                            FtwLiteDevice->FtwWorkSpaceBase,

+                                            &Length,

+                                            FtwLiteDevice->FtwWorkSpace

+                                            );

+      if (EFI_ERROR (Status)) {

+        return EFI_ABORTED;

+      }

+    }

+  }

+  //

+  // Hook the protocol API

+  //

+  FtwLiteDevice->FtwLiteInstance.Write = FtwLiteWrite;

+

+  //

+  // Install protocol interface

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &FtwLiteDevice->Handle,

+                  &gEfiFaultTolerantWriteLiteProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &FtwLiteDevice->FtwLiteInstance

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // If (!SpareCompleted)  THEN  Abort to rollback.

+  //

+  if ((FtwLiteDevice->FtwLastRecord->WriteAllocated == FTW_VALID_STATE) &&

+      (FtwLiteDevice->FtwLastRecord->SpareCompleted != FTW_VALID_STATE)

+      ) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Init.. record not SpareCompleted, abort()\n"));

+    FtwAbort (FtwLiteDevice);

+  }

+  //

+  // if (SpareCompleted) THEN  Restart to fault tolerant write.

+  //

+  if ((FtwLiteDevice->FtwLastRecord->SpareCompleted == FTW_VALID_STATE) &&

+      (FtwLiteDevice->FtwLastRecord->WriteCompleted != FTW_VALID_STATE)

+      ) {

+

+    Status = FtwRestart (FtwLiteDevice);

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Restart last write - %r\n", Status));

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  //

+  // To check the workspace buffer behind last records is EMPTY or not.

+  // If it's not EMPTY, FTW_LITE also need to call reclaim().

+  //

+  Record  = FtwLiteDevice->FtwLastRecord;

+  Offset  = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;

+  if (FtwLiteDevice->FtwWorkSpace[Offset] != FTW_ERASED_BYTE) {

+    Offset += WRITE_TOTAL_SIZE;

+  }

+

+  if (!IsErasedFlashBuffer (

+        FTW_ERASE_POLARITY,

+        FtwLiteDevice->FtwWorkSpace + Offset,

+        FtwLiteDevice->FtwWorkSpaceSize - Offset

+        )) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace is dirty, call reclaim...\n"));

+    Status = FtwReclaimWorkSpace (FtwLiteDevice);

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: Workspace reclaim - %r\n", Status));

+      return EFI_ABORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs
new file mode 100644
index 0000000..f2a6221
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.

+

+

+Module Name:

+  

+    FtwLite.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+

+DEPENDENCY_START

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND EFI_ALTERNATE_FV_BLOCK_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h
new file mode 100644
index 0000000..8754827
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.h
@@ -0,0 +1,675 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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. 

+

+

+Module Name:

+

+  FtwLite.h

+

+Abstract:

+

+  This is a simple fault tolerant write driver, based on PlatformFd library.

+  And it only supports write BufferSize <= SpareAreaLength.

+

+  This boot service only protocol provides fault tolerant write capability for 

+  block devices.  The protocol has internal non-volatile intermediate storage 

+  of the data and private information. It should be able to recover 

+  automatically from a critical fault, such as power failure. 

+

+--*/

+

+#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_

+#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_

+

+#include <Common/FlashMap.h>

+#include <Common/WorkingBlockHeader.h>

+

+#define EFI_D_FTW_LITE  EFI_D_ERROR

+#define EFI_D_FTW_INFO  EFI_D_INFO

+

+//

+// Flash erase polarity is 1

+//

+#define FTW_ERASE_POLARITY  1

+

+#define FTW_VALID_STATE     0

+#define FTW_INVALID_STATE   1

+

+#define FTW_ERASED_BYTE     ((UINT8) (255))

+#define FTW_POLARITY_REVERT ((UINT8) (255))

+

+typedef struct {

+  UINT8         WriteAllocated : 1;

+  UINT8         SpareCompleted : 1;

+  UINT8         WriteCompleted : 1;

+  UINT8         Reserved : 5;

+#define WRITE_ALLOCATED 0x1

+#define SPARE_COMPLETED 0x2

+#define WRITE_COMPLETED 0x4

+

+  EFI_DEV_PATH  DevPath;

+  EFI_LBA       Lba;

+  UINTN         Offset;

+  UINTN         NumBytes;

+  //

+  // UINTN           SpareAreaOffset;

+  //

+} EFI_FTW_LITE_RECORD;

+

+#define FTW_LITE_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'T', 'W', 'L')

+

+//

+// MACRO for Block size.

+// Flash Erasing will do in block granularity.

+//

+#ifdef FV_BLOCK_SIZE

+#define FTW_BLOCK_SIZE  FV_BLOCK_SIZE

+#else

+#define FV_BLOCK_SIZE   0x10000

+#define FTW_BLOCK_SIZE  FV_BLOCK_SIZE

+#endif

+//

+// MACRO for FTW WORK SPACE Base & Size

+//

+#ifdef EFI_FTW_WORKING_OFFSET

+#define FTW_WORK_SPACE_BASE EFI_FTW_WORKING_OFFSET

+#else

+#define FTW_WORK_SPACE_BASE 0x00E000

+#endif

+

+#ifdef EFI_FTW_WORKING_LENGTH

+#define FTW_WORK_SPACE_SIZE EFI_FTW_WORKING_LENGTH

+#else

+#define FTW_WORK_SPACE_SIZE 0x002000

+#endif

+//

+// MACRO for FTW header and record

+//

+#define FTW_WORKING_QUEUE_SIZE  (FTW_WORK_SPACE_SIZE - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER))

+#define FTW_LITE_RECORD_SIZE    (sizeof (EFI_FTW_LITE_RECORD))

+#define WRITE_TOTAL_SIZE        FTW_LITE_RECORD_SIZE

+

+//

+// EFI Fault tolerant protocol private data structure

+//

+typedef struct {

+  UINTN                                   Signature;

+  EFI_HANDLE                              Handle;

+  EFI_FTW_LITE_PROTOCOL                   FtwLiteInstance;

+  EFI_PHYSICAL_ADDRESS                    WorkSpaceAddress;

+  UINTN                                   WorkSpaceLength;

+  EFI_PHYSICAL_ADDRESS                    SpareAreaAddress;

+  UINTN                                   SpareAreaLength;

+  UINTN                                   NumberOfSpareBlock; // Number of the blocks in spare block

+  UINTN                                   SizeOfSpareBlock;   // Block size in bytes of the blocks in spare block

+  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader;

+  EFI_FTW_LITE_RECORD                     *FtwLastRecord;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL      *FtwFvBlock;        // FVB of working block

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL      *FtwBackupFvb;      // FVB of spare block

+  EFI_LBA                                 FtwSpareLba;

+  EFI_LBA                                 FtwWorkBlockLba;    // Start LBA of working block

+  EFI_LBA                                 FtwWorkSpaceLba;    // Start LBA of working space

+  UINTN                                   FtwWorkSpaceBase;   // Offset from LBA start addr

+  UINTN                                   FtwWorkSpaceSize;

+  UINT8                                   *FtwWorkSpace;

+  //

+  // Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE],

+  // Allocated with EFI_FTW_LITE_DEVICE.

+  //

+} EFI_FTW_LITE_DEVICE;

+

+#define FTW_LITE_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_LITE_DEVICE, FtwLiteInstance, FTW_LITE_DEVICE_SIGNATURE)

+

+//

+// Driver entry point

+//

+EFI_STATUS

+EFIAPI

+InitializeFtwLite (

+  IN EFI_HANDLE                 ImageHandle,

+  IN EFI_SYSTEM_TABLE           *SystemTable

+  )

+/*++

+

+Routine Description:

+    This function is the entry point of the Fault Tolerant Write driver.

+

+Arguments:

+    ImageHandle   - EFI_HANDLE: A handle for the image that is initializing 

+                    this driver

+    SystemTable   - EFI_SYSTEM_TABLE: A pointer to the EFI system table

+

+Returns:

+    EFI_SUCCESS           - FTW has finished the initialization

+    EFI_ABORTED           - FTW initialization error

+

+--*/

+;

+

+//

+// Fault Tolerant Write Protocol API

+//

+EFI_STATUS

+EFIAPI

+FtwLiteWrite (

+  IN EFI_FTW_LITE_PROTOCOL                 *This,

+  IN EFI_HANDLE                            FvbHandle,

+  IN EFI_LBA                               Lba,

+  IN UINTN                                 Offset,

+  IN UINTN                                 *NumBytes,

+  IN VOID                                  *Buffer

+  )

+/*++

+

+Routine Description:

+    Starts a target block update. This function will record data about write 

+    in fault tolerant storage and will complete the write in a recoverable 

+    manner, ensuring at all times that either the original contents or 

+    the modified contents are available.

+

+Arguments:

+    This             - Calling context

+    FvbHandle        - The handle of FVB protocol that provides services for 

+                       reading, writing, and erasing the target block.

+    Lba              - The logical block address of the target block.  

+    Offset           - The offset within the target block to place the data.

+    NumBytes         - The number of bytes to write to the target block.

+    Buffer           - The data to write.

+

+Returns:

+    EFI_SUCCESS          - The function completed successfully

+    EFI_BAD_BUFFER_SIZE  - The write would span a target block, which is not 

+                           a valid action.

+    EFI_ACCESS_DENIED    - No writes have been allocated.

+    EFI_NOT_FOUND        - Cannot find FVB by handle.

+    EFI_OUT_OF_RESOURCES - Cannot allocate memory.

+    EFI_ABORTED          - The function could not complete successfully.

+

+--*/

+;

+

+//

+// Internal functions

+//

+EFI_STATUS

+FtwRestart (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Restarts a previously interrupted write. The caller must provide the 

+    block protocol needed to complete the interrupted write.

+

+Arguments:

+    FtwLiteDevice       - The private data of FTW_LITE driver

+    FvbHandle           - The handle of FVB protocol that provides services for 

+                          reading, writing, and erasing the target block.

+

+Returns:

+    EFI_SUCCESS         - The function completed successfully

+    EFI_ACCESS_DENIED   - No pending writes exist

+    EFI_NOT_FOUND       - FVB protocol not found by the handle

+    EFI_ABORTED         - The function could not complete successfully

+

+--*/

+;

+

+EFI_STATUS

+FtwAbort (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Aborts all previous allocated writes.

+

+Arguments:

+    FtwLiteDevice    - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS      - The function completed successfully

+    EFI_ABORTED      - The function could not complete successfully.

+    EFI_NOT_FOUND    - No allocated writes exist.

+

+--*/

+;

+

+

+EFI_STATUS

+FtwWriteRecord (

+  IN EFI_FTW_LITE_DEVICE                   *FtwLiteDevice,

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb

+  )

+/*++

+

+Routine Description:

+    Write a record with fault tolerant mannaer.

+    Since the content has already backuped in spare block, the write is 

+    guaranteed to be completed with fault tolerant manner.

+

+Arguments:

+    FtwLiteDevice       - The private data of FTW_LITE driver

+    Fvb                 - The FVB protocol that provides services for 

+                          reading, writing, and erasing the target block.

+

+Returns:

+    EFI_SUCCESS         - The function completed successfully

+    EFI_ABORTED         - The function could not complete successfully

+

+--*/

+;

+

+EFI_STATUS

+FtwEraseBlock (

+  IN EFI_FTW_LITE_DEVICE              *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+    To Erase one block. The size is FTW_BLOCK_SIZE

+

+Arguments:

+    FtwLiteDevice - Calling context

+    FvBlock       - FVB Protocol interface

+    Lba           - Lba of the firmware block

+

+Returns:

+    EFI_SUCCESS   - Block LBA is Erased successfully

+    Others        - Error occurs

+

+--*/

+;

+

+EFI_STATUS

+FtwEraseSpareBlock (

+  IN EFI_FTW_LITE_DEVICE   *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+

+  Erase spare block.

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+

+Returns:

+

+  Status code

+

+--*/

+;

+

+EFI_STATUS

+FtwGetFvbByHandle (

+  IN EFI_HANDLE                           FvBlockHandle,

+  OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  **FvBlock

+  )

+/*++

+

+Routine Description:

+    Retrive the proper FVB protocol interface by HANDLE.

+

+Arguments:

+    FvBlockHandle       - The handle of FVB protocol that provides services for 

+                          reading, writing, and erasing the target block.

+    FvBlock             - The interface of FVB protocol

+

+Returns:

+    EFI_SUCCESS         - The function completed successfully

+    EFI_ABORTED         - The function could not complete successfully

+--*/

+;

+

+EFI_STATUS

+GetFvbByAddress (

+  IN  EFI_PHYSICAL_ADDRESS               Address,

+  OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock

+  )

+/*++

+

+Routine Description:

+

+  Get firmware block by address.

+

+Arguments:

+

+  Address - Address specified the block

+  FvBlock - The block caller wanted

+

+Returns:

+

+  Status code

+

+  EFI_NOT_FOUND - Block not found

+

+--*/

+;

+

+BOOLEAN

+IsInWorkingBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+

+  Is it in working block?

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  FvBlock       - Fvb protocol instance

+  Lba           - The block specified

+

+Returns:

+

+  In working block or not

+

+--*/

+;

+

+BOOLEAN

+IsBootBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+

+  Check whether the block is a boot block.

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  FvBlock       - Fvb protocol instance

+  Lba           - Lba value

+

+Returns:

+

+  Is a boot block or not

+

+--*/

+;

+

+EFI_STATUS

+FlushSpareBlockToTargetBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Target block is accessed by FvBlock protocol interface. LBA is Lba.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+    FvBlock        - FVB Protocol interface to access target block

+    Lba            - Lba of the target block

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to target block

+    EFI_INVALID_PARAMETER    - Input parameter error

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+--*/

+;

+

+EFI_STATUS

+FlushSpareBlockToWorkingBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Working block is accessed by FTW working FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwWorkBlockLba.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to target block

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+Notes:

+    Since the working block header is important when FTW initializes, the 

+    state of the operation should be handled carefully. The Crc value is 

+    calculated without STATE element. 

+

+--*/

+;

+

+EFI_STATUS

+FlushSpareBlockToBootBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Boot block is accessed by BootFvb protocol interface. LBA is 0.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to boot block

+    EFI_INVALID_PARAMETER    - Input parameter error

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+Notes:

+

+--*/

+;

+

+EFI_STATUS

+FtwUpdateFvState (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  IN EFI_LBA                             Lba,

+  IN UINTN                               Offset,

+  IN UINT8                               NewBit

+  )

+/*++

+

+Routine Description:

+    Update a bit of state on a block device. The location of the bit is 

+    calculated by the (Lba, Offset, bit). Here bit is determined by the 

+    the name of a certain bit.

+

+Arguments:

+    FvBlock    - FVB Protocol interface to access SrcBlock and DestBlock

+    Lba        - Lba of a block

+    Offset     - Offset on the Lba

+    NewBit     - New value that will override the old value if it can be change

+

+Returns:

+    EFI_SUCCESS   - A state bit has been updated successfully

+    Others        - Access block device error.

+

+Notes:

+    Assume all bits of State are inside the same BYTE. 

+

+    EFI_ABORTED   - Read block fail

+--*/

+;

+

+EFI_STATUS

+FtwGetLastRecord (

+  IN  EFI_FTW_LITE_DEVICE  *FtwLiteDevice,

+  OUT EFI_FTW_LITE_RECORD  **FtwLastRecord

+  )

+/*++

+

+Routine Description:

+    Get the last Write record pointer. 

+    The last record is the record whose 'complete' state hasn't been set.

+    After all, this header may be a EMPTY header entry for next Allocate. 

+

+Arguments:

+    FtwLiteDevice   - Private data of this driver

+    FtwLastRecord   - Pointer to retrieve the last write record

+

+Returns:

+    EFI_SUCCESS     - Get the last write record successfully

+    EFI_ABORTED     - The FTW work space is damaged

+

+--*/

+;

+

+BOOLEAN

+IsErasedFlashBuffer (

+  IN BOOLEAN         Polarity,

+  IN UINT8           *Buffer,

+  IN UINTN           BufferSize

+  )

+/*++

+

+Routine Description:

+

+  Check whether a flash buffer is erased.

+

+Arguments:

+

+  Polarity    - All 1 or all 0

+  Buffer      - Buffer to check

+  BufferSize  - Size of the buffer

+

+Returns:

+

+  Erased or not.

+

+--*/

+;

+

+EFI_STATUS

+InitWorkSpaceHeader (

+  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader

+  )

+/*++

+

+Routine Description:

+    Initialize a work space when there is no work space.

+

+Arguments:

+    WorkingHeader - Pointer of working block header 

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+    EFI_ABORTED   - The function could not complete successfully.

+

+--*/

+;

+

+EFI_STATUS

+WorkSpaceRefresh (

+  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Read from working block to refresh the work space in memory.

+

+Arguments:

+    FtwLiteDevice     - Point to private data of FTW driver

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+    EFI_ABORTED   - The function could not complete successfully.

+

+--*/

+;

+

+BOOLEAN

+IsValidWorkSpace (

+  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader

+  )

+/*++

+

+Routine Description:

+    Check to see if it is a valid work space.

+

+Arguments:

+    WorkingHeader - Pointer of working block header 

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+    EFI_ABORTED   - The function could not complete successfully.

+

+--*/

+;

+

+EFI_STATUS

+CleanupWorkSpace (

+  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice,

+  IN OUT UINT8            *BlockBuffer,

+  IN UINTN                BufferSize

+  )

+/*++

+

+Routine Description:

+    Reclaim the work space. Get rid of all the completed write records

+    and write records in the Fault Tolerant work space.

+

+Arguments:

+    FtwLiteDevice   - Point to private data of FTW driver

+    FtwSpaceBuffer  - Buffer to contain the reclaimed clean data

+    BufferSize      - Size of the FtwSpaceBuffer

+

+Returns:

+    EFI_SUCCESS           - The function completed successfully

+    EFI_BUFFER_TOO_SMALL  - The FtwSpaceBuffer is too small

+    EFI_ABORTED           - The function could not complete successfully.

+

+--*/

+;

+

+EFI_STATUS

+FtwReclaimWorkSpace (

+  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Reclaim the work space on the working block.

+

+Arguments:

+    FtwLiteDevice     - Point to private data of FTW driver

+

+Returns:

+    EFI_SUCCESS           - The function completed successfully

+    EFI_OUT_OF_RESOURCES  - Allocate memory error

+    EFI_ABORTED           - The function could not complete successfully

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.mbd b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.mbd
new file mode 100644
index 0000000..a56e9de
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>FtwLite</BaseName>

+    <Guid>4C862FC6-0E54-4e36-8C8F-FF6F3167951F</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-22 14:11</Created>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa
new file mode 100644
index 0000000..e2b422f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.msa
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>FtwLite</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>4C862FC6-0E54-4e36-8C8F-FF6F3167951F</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-22 14:11</Created>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>FtwLite.c</Filename>

+    <Filename>FtwMisc.c</Filename>

+    <Filename>FtwWorkSpace.c</Filename>

+    <Filename>FtwLite.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/Ia32FtwMisc.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x64/x64FtwMisc.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/IpfFtwMisc.c</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>Ia32/Ia32FtwMisc.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">FaultTolerantWriteLite</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">PciRootBridgeIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="ALWAYS_CONSUMED" HobType="GUID_EXTENSION">

+      <Name>FlashMapHob</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+  </Hobs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FlashMapHob</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>SystemNvDataFv</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeFtwLite</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c
new file mode 100644
index 0000000..025ec33
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwMisc.c
@@ -0,0 +1,530 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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. 

+

+Module Name:

+

+  FtwMisc.c

+  

+Abstract:

+  

+  Internal functions to support fault tolerant write.

+

+Revision History

+

+--*/

+

+#include <FtwLite.h>

+

+BOOLEAN

+IsErasedFlashBuffer (

+  IN BOOLEAN         Polarity,

+  IN UINT8           *Buffer,

+  IN UINTN           BufferSize

+  )

+/*++

+

+Routine Description:

+

+  Check whether a flash buffer is erased.

+

+Arguments:

+

+  Polarity    - All 1 or all 0

+  Buffer      - Buffer to check

+  BufferSize  - Size of the buffer

+

+Returns:

+

+  Erased or not.

+

+--*/

+{

+  UINT8 ErasedValue;

+  UINT8 *Ptr;

+

+  if (Polarity) {

+    ErasedValue = 0xFF;

+  } else {

+    ErasedValue = 0;

+  }

+

+  Ptr = Buffer;

+  while (BufferSize--) {

+    if (*Ptr++ != ErasedValue) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+EFI_STATUS

+FtwEraseBlock (

+  IN EFI_FTW_LITE_DEVICE              *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+    To Erase one block. The size is FTW_BLOCK_SIZE

+

+Arguments:

+    FtwLiteDevice - Calling context

+    FvBlock       - FVB Protocol interface

+    Lba        - Lba of the firmware block

+

+Returns:

+    EFI_SUCCESS   - Block LBA is Erased successfully

+    Others        - Error occurs

+

+--*/

+{

+  return FvBlock->EraseBlocks (

+                    FvBlock,

+                    Lba,

+                    FtwLiteDevice->NumberOfSpareBlock,

+                    EFI_LBA_LIST_TERMINATOR

+                    );

+}

+

+EFI_STATUS

+FtwEraseSpareBlock (

+  IN EFI_FTW_LITE_DEVICE   *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+

+  Erase spare block.

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+

+Returns:

+

+  Status code

+

+--*/

+{

+  return FtwLiteDevice->FtwBackupFvb->EraseBlocks (

+                                        FtwLiteDevice->FtwBackupFvb,

+                                        FtwLiteDevice->FtwSpareLba,

+                                        FtwLiteDevice->NumberOfSpareBlock,

+                                        EFI_LBA_LIST_TERMINATOR

+                                        );

+}

+

+EFI_STATUS

+FtwGetFvbByHandle (

+  IN EFI_HANDLE                           FvBlockHandle,

+  OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  **FvBlock

+  )

+/*++

+

+Routine Description:

+    Retrive the proper FVB protocol interface by HANDLE.

+

+Arguments:

+    FvBlockHandle       - The handle of FVB protocol that provides services for 

+                          reading, writing, and erasing the target block.

+    FvBlock             - The interface of FVB protocol

+

+Returns:

+    EFI_SUCCESS         - The function completed successfully

+    EFI_ABORTED         - The function could not complete successfully

+--*/

+{

+  //

+  // To get the FVB protocol interface on the handle

+  //

+  return gBS->HandleProtocol (

+                FvBlockHandle,

+                &gEfiFirmwareVolumeBlockProtocolGuid,

+                (VOID **) FvBlock

+                );

+}

+

+EFI_STATUS

+GetFvbByAddress (

+  IN  EFI_PHYSICAL_ADDRESS               Address,

+  OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock

+  )

+/*++

+

+Routine Description:

+

+  Get firmware block by address.

+

+Arguments:

+

+  Address - Address specified the block

+  FvBlock - The block caller wanted

+

+Returns:

+

+  Status code

+

+  EFI_NOT_FOUND - Block not found

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_HANDLE                          *HandleBuffer;

+  UINTN                               HandleCount;

+  UINTN                               Index;

+  EFI_PHYSICAL_ADDRESS                FvbBaseAddress;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;

+

+  *FvBlock = NULL;

+  //

+  // Locate all handles of Fvb protocol

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiFirmwareVolumeBlockProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Search all FVB until find the right one

+  //

+  for (Index = 0; Index < HandleCount; Index += 1) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[Index],

+                    &gEfiFirmwareVolumeBlockProtocolGuid,

+                    (VOID **) &Fvb

+                    );

+    if (EFI_ERROR (Status)) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+    //

+    // Compare the address and select the right one

+    //

+    Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);

+    if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + (FwVolHeader->FvLength - 1)))) {

+      *FvBlock  = Fvb;

+      Status    = EFI_SUCCESS;

+      break;

+    }

+  }

+

+  gBS->FreePool (HandleBuffer);

+  return Status;

+}

+

+BOOLEAN

+IsInWorkingBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+

+  Is it in working block?

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  FvBlock       - Fvb protocol instance

+  Lba           - The block specified

+

+Returns:

+

+  In working block or not

+

+--*/

+{

+  //

+  // If matching the following condition, the target block is in working block.

+  // 1. Target block is on the FV of working block (Using the same FVB protocol instance).

+  // 2. Lba falls into the range of working block.

+  //

+  return (BOOLEAN)

+    (

+      (FvBlock == FtwLiteDevice->FtwFvBlock) &&

+      (Lba >= FtwLiteDevice->FtwWorkBlockLba) &&

+      (Lba <= FtwLiteDevice->FtwWorkSpaceLba)

+    );

+}

+

+EFI_STATUS

+FlushSpareBlockToTargetBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Target block is accessed by FvBlock protocol interface. LBA is Lba.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+    FvBlock        - FVB Protocol interface to access target block

+    Lba            - Lba of the target block

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to target block

+    EFI_INVALID_PARAMETER    - Input parameter error

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Length;

+  UINT8       *Buffer;

+  UINTN       Count;

+  UINT8       *Ptr;

+  UINTN       Index;

+

+  if ((FtwLiteDevice == NULL) || (FvBlock == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Allocate a memory buffer

+  //

+  Length  = FtwLiteDevice->SpareAreaLength;

+  Buffer  = AllocatePool (Length);

+  if (Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Read all content of spare block to memory buffer

+  //

+  Ptr = Buffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Count = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Read (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &Count,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (Buffer);

+      return Status;

+    }

+

+    Ptr += Count;

+  }

+  //

+  // Erase the target block

+  //

+  Status = FtwEraseBlock (FtwLiteDevice, FvBlock, Lba);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Buffer);

+    return EFI_ABORTED;

+  }

+  //

+  // Write memory buffer to block, using the FvbBlock protocol interface

+  //

+  Ptr = Buffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Count   = FtwLiteDevice->SizeOfSpareBlock;

+    Status  = FvBlock->Write (FvBlock, Lba + Index, 0, &Count, Ptr);

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status));

+      gBS->FreePool (Buffer);

+      return Status;

+    }

+

+    Ptr += Count;

+  }

+

+  gBS->FreePool (Buffer);

+

+  return Status;

+}

+

+EFI_STATUS

+FlushSpareBlockToWorkingBlock (

+  EFI_FTW_LITE_DEVICE          *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Working block is accessed by FTW working FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwWorkBlockLba.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to target block

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+Notes:

+    Since the working block header is important when FTW initializes, the 

+    state of the operation should be handled carefully. The Crc value is 

+    calculated without STATE element. 

+

+--*/

+{

+  EFI_STATUS                              Status;

+  UINTN                                   Length;

+  UINT8                                   *Buffer;

+  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;

+  EFI_LBA                                 WorkSpaceLbaOffset;

+  UINTN                                   Count;

+  UINT8                                   *Ptr;

+  UINTN                                   Index;

+

+  //

+  // Allocate a memory buffer

+  //

+  Length  = FtwLiteDevice->SpareAreaLength;

+  Buffer  = AllocatePool (Length);

+  if (Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // To  guarantee that the WorkingBlockValid is set on spare block

+  //

+  WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;

+  FtwUpdateFvState (

+    FtwLiteDevice->FtwBackupFvb,

+    FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,

+    FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),

+    WORKING_BLOCK_VALID

+    );

+  //

+  // Read from spare block to memory buffer

+  //

+  Ptr = Buffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Count = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Read (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &Count,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (Buffer);

+      return Status;

+    }

+

+    Ptr += Count;

+  }

+  //

+  // Clear the CRC and STATE, copy data from spare to working block.

+  //

+  WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) (Buffer + (UINTN) WorkSpaceLbaOffset * FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase);

+  InitWorkSpaceHeader (WorkingBlockHeader);

+  WorkingBlockHeader->WorkingBlockValid   = FTW_ERASE_POLARITY;

+  WorkingBlockHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;

+

+  //

+  // target block is working block, then

+  //   Set WorkingBlockInvalid in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER

+  //   before erase the working block.

+  //

+  //  Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,

+  //                            WorkingBlockInvalid);

+  // To skip Signature and Crc: sizeof(EFI_GUID)+sizeof(UINT32).

+  //

+  Status = FtwUpdateFvState (

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkSpaceLba,

+            FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),

+            WORKING_BLOCK_INVALID

+            );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Buffer);

+    return EFI_ABORTED;

+  }

+

+  FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockInvalid = FTW_VALID_STATE;

+

+  //

+  // Erase the working block

+  //

+  Status = FtwEraseBlock (

+            FtwLiteDevice,

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkBlockLba

+            );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Buffer);

+    return EFI_ABORTED;

+  }

+  //

+  // Write memory buffer to working block, using the FvbBlock protocol interface

+  //

+  Ptr = Buffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Count = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwFvBlock->Write (

+                                          FtwLiteDevice->FtwFvBlock,

+                                          FtwLiteDevice->FtwWorkBlockLba + Index,

+                                          0,

+                                          &Count,

+                                          Ptr

+                                          );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write block - %r\n", Status));

+      gBS->FreePool (Buffer);

+      return Status;

+    }

+

+    Ptr += Count;

+  }

+  //

+  // Since the memory buffer will not be used, free memory Buffer.

+  //

+  gBS->FreePool (Buffer);

+

+  //

+  // Update the VALID of the working block

+  //

+  // Offset = EFI_FIELD_OFFSET(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER,

+  //                           WorkingBlockValid);

+  // Hardcode offset sizeof(EFI_GUID)+sizeof(UINT32), to skip Signature and Crc

+  //

+  Status = FtwUpdateFvState (

+            FtwLiteDevice->FtwFvBlock,

+            FtwLiteDevice->FtwWorkSpaceLba,

+            FtwLiteDevice->FtwWorkSpaceBase + sizeof (EFI_GUID) + sizeof (UINT32),

+            WORKING_BLOCK_VALID

+            );

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+

+  FtwLiteDevice->FtwWorkSpaceHeader->WorkingBlockValid = FTW_VALID_STATE;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c
new file mode 100644
index 0000000..820655c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwWorkSpace.c
@@ -0,0 +1,567 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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. 

+

+Module Name:

+

+  FtwWorkSpace.c

+  

+Abstract:

+

+Revision History

+

+--*/

+

+

+#include <FtwLite.h>

+

+BOOLEAN

+IsValidWorkSpace (

+  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader

+  )

+/*++

+

+Routine Description:

+    Check to see if it is a valid work space.

+

+Arguments:

+    WorkingHeader - Pointer of working block header 

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+    EFI_ABORTED   - The function could not complete successfully.

+

+--*/

+{

+  EFI_STATUS                              Status;

+  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader;

+

+  ASSERT (WorkingHeader != NULL);

+  if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) {

+    return FALSE;

+  }

+  //

+  // Check signature with gEfiSystemNvDataFvGuid

+  //

+  if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {

+    return FALSE;

+  }

+  //

+  // Check the CRC of header

+  //

+  CopyMem (

+    &WorkingBlockHeader,

+    WorkingHeader,

+    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)

+    );

+

+  //

+  // Filter out the Crc and State fields

+  //

+  SetMem (

+    &WorkingBlockHeader.Crc,

+    sizeof (UINT32),

+    FTW_ERASED_BYTE

+    );

+  WorkingBlockHeader.WorkingBlockValid    = FTW_ERASE_POLARITY;

+  WorkingBlockHeader.WorkingBlockInvalid  = FTW_ERASE_POLARITY;

+

+  //

+  // Calculate the Crc of woking block header

+  //

+  Status = gBS->CalculateCrc32 (

+                  (UINT8 *) &WorkingBlockHeader,

+                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),

+                  &WorkingBlockHeader.Crc

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  if (WorkingBlockHeader.Crc != WorkingHeader->Crc) {

+    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Work block header CRC check error\n"));

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+EFI_STATUS

+InitWorkSpaceHeader (

+  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader

+  )

+/*++

+

+Routine Description:

+    Initialize a work space when there is no work space.

+

+Arguments:

+    WorkingHeader - Pointer of working block header 

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+    EFI_ABORTED   - The function could not complete successfully.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  ASSERT (WorkingHeader != NULL);

+

+  //

+  // Here using gEfiSystemNvDataFvGuid as the signature.

+  //

+  CopyMem (

+    &WorkingHeader->Signature,

+    &gEfiSystemNvDataFvGuid,

+    sizeof (EFI_GUID)

+    );

+  WorkingHeader->WriteQueueSize = FTW_WORKING_QUEUE_SIZE;

+

+  //

+  // Crc is calculated with all the fields except Crc and STATE

+  //

+  WorkingHeader->WorkingBlockValid    = FTW_ERASE_POLARITY;

+  WorkingHeader->WorkingBlockInvalid  = FTW_ERASE_POLARITY;

+  SetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE);

+

+  //

+  // Calculate the CRC value

+  //

+  Status = gBS->CalculateCrc32 (

+                  (UINT8 *) WorkingHeader,

+                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),

+                  &WorkingHeader->Crc

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Restore the WorkingBlockValid flag to VALID state

+  //

+  WorkingHeader->WorkingBlockValid    = FTW_VALID_STATE;

+  WorkingHeader->WorkingBlockInvalid  = FTW_INVALID_STATE;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FtwUpdateFvState (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  IN EFI_LBA                             Lba,

+  IN UINTN                               Offset,

+  IN UINT8                               NewBit

+  )

+/*++

+

+Routine Description:

+    Update a bit of state on a block device. The location of the bit is 

+    calculated by the (Lba, Offset, bit). Here bit is determined by the 

+    the name of a certain bit.

+

+Arguments:

+    FvBlock    - FVB Protocol interface to access SrcBlock and DestBlock

+    Lba        - Lba of a block

+    Offset     - Offset on the Lba

+    NewBit     - New value that will override the old value if it can be change

+

+Returns:

+    EFI_SUCCESS   - A state bit has been updated successfully

+    Others        - Access block device error.

+

+Notes:

+    Assume all bits of State are inside the same BYTE. 

+

+    EFI_ABORTED   - Read block fail

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       State;

+  UINTN       Length;

+

+  //

+  // Read state from device, assume State is only one byte.

+  //

+  Length  = sizeof (UINT8);

+  Status  = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+

+  State ^= FTW_POLARITY_REVERT;

+  State |= NewBit;

+  State ^= FTW_POLARITY_REVERT;

+

+  //

+  // Write state back to device

+  //

+  Length  = sizeof (UINT8);

+  Status  = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State);

+

+  return Status;

+}

+

+EFI_STATUS

+FtwGetLastRecord (

+  IN  EFI_FTW_LITE_DEVICE  *FtwLiteDevice,

+  OUT EFI_FTW_LITE_RECORD  **FtwLastRecord

+  )

+/*++

+

+Routine Description:

+    Get the last Write record pointer. 

+    The last record is the record whose 'complete' state hasn't been set.

+    After all, this header may be a EMPTY header entry for next Allocate. 

+

+Arguments:

+    FtwLiteDevice   - Private data of this driver

+    FtwLastRecord   - Pointer to retrieve the last write record

+

+Returns:

+    EFI_SUCCESS     - Get the last write record successfully

+    EFI_ABORTED     - The FTW work space is damaged

+

+--*/

+{

+  EFI_FTW_LITE_RECORD *Record;

+

+  Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1);

+  while (Record->WriteCompleted == FTW_VALID_STATE) {

+    //

+    // If Offset exceed the FTW work space boudary, return error.

+    //

+    if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) {

+      return EFI_ABORTED;

+    }

+

+    Record++;

+  }

+  //

+  // Last write record is found

+  //

+  *FtwLastRecord = Record;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WorkSpaceRefresh (

+  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Read from working block to refresh the work space in memory.

+

+Arguments:

+    FtwLiteDevice     - Point to private data of FTW driver

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+    EFI_ABORTED   - The function could not complete successfully.

+

+--*/

+{

+  EFI_STATUS          Status;

+  UINTN               Length;

+  UINTN               Offset;

+  EFI_FTW_LITE_RECORD *Record;

+

+  //

+  // Initialize WorkSpace as FTW_ERASED_BYTE

+  //

+  SetMem (

+    FtwLiteDevice->FtwWorkSpace,

+    FtwLiteDevice->FtwWorkSpaceSize,

+    FTW_ERASED_BYTE

+    );

+

+  //

+  // Read from working block

+  //

+  Length = FtwLiteDevice->FtwWorkSpaceSize;

+  Status = FtwLiteDevice->FtwFvBlock->Read (

+                                        FtwLiteDevice->FtwFvBlock,

+                                        FtwLiteDevice->FtwWorkSpaceLba,

+                                        FtwLiteDevice->FtwWorkSpaceBase,

+                                        &Length,

+                                        FtwLiteDevice->FtwWorkSpace

+                                        );

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Refresh the FtwLastRecord

+  //

+  Status  = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);

+

+  Record  = FtwLiteDevice->FtwLastRecord;

+  Offset  = (UINTN) (UINT8 *) Record - (UINTN) FtwLiteDevice->FtwWorkSpace;

+

+  //

+  // IF work space has error or Record is out of the workspace limit, THEN

+  //   call reclaim.

+  //

+  if (EFI_ERROR (Status) || (Offset + WRITE_TOTAL_SIZE >= FtwLiteDevice->FtwWorkSpaceSize)) {

+    //

+    // reclaim work space in working block.

+    //

+    Status = FtwReclaimWorkSpace (FtwLiteDevice);

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: Reclaim workspace - %r\n", Status));

+      return EFI_ABORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CleanupWorkSpace (

+  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice,

+  IN OUT UINT8            *FtwSpaceBuffer,

+  IN UINTN                BufferSize

+  )

+/*++

+

+Routine Description:

+    Reclaim the work space. Get rid of all the completed write records

+    and write records in the Fault Tolerant work space.

+

+Arguments:

+    FtwLiteDevice   - Point to private data of FTW driver

+    FtwSpaceBuffer  - Buffer to contain the reclaimed clean data

+    BufferSize      - Size of the FtwSpaceBuffer

+

+Returns:

+    EFI_SUCCESS           - The function completed successfully

+    EFI_BUFFER_TOO_SMALL  - The FtwSpaceBuffer is too small

+    EFI_ABORTED           - The function could not complete successfully.

+

+--*/

+{

+  UINTN               Length;

+  EFI_FTW_LITE_RECORD *Record;

+

+  //

+  // To check if the buffer is large enough

+  //

+  Length = FtwLiteDevice->FtwWorkSpaceSize;

+  if (BufferSize < Length) {

+    return EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // Clear the content of buffer that will save the new work space data

+  //

+  SetMem (FtwSpaceBuffer, Length, FTW_ERASED_BYTE);

+

+  //

+  // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer

+  //

+  CopyMem (

+    FtwSpaceBuffer,

+    FtwLiteDevice->FtwWorkSpaceHeader,

+    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)

+    );

+

+  //

+  // Get the last record

+  //

+  Record = FtwLiteDevice->FtwLastRecord;

+  if ((Record != NULL) && (Record->WriteAllocated == FTW_VALID_STATE) && (Record->WriteCompleted != FTW_VALID_STATE)) {

+    CopyMem (

+      (UINT8 *) FtwSpaceBuffer + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),

+      Record,

+      WRITE_TOTAL_SIZE

+      );

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FtwReclaimWorkSpace (

+  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Reclaim the work space on the working block.

+

+Arguments:

+    FtwLiteDevice     - Point to private data of FTW driver

+

+Returns:

+    EFI_SUCCESS           - The function completed successfully

+    EFI_OUT_OF_RESOURCES  - Allocate memory error

+    EFI_ABORTED           - The function could not complete successfully

+

+--*/

+{

+  EFI_STATUS                              Status;

+  UINT8                                   *TempBuffer;

+  UINTN                                   TempBufferSize;

+  UINT8                                   *Ptr;

+  UINTN                                   Length;

+  UINTN                                   Index;

+  UINTN                                   SpareBufferSize;

+  UINT8                                   *SpareBuffer;

+  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;

+

+  DEBUG ((EFI_D_FTW_LITE, "FtwLite: start to reclaim work space\n"));

+

+  //

+  // Read all original data from working block to a memory buffer

+  //

+  TempBufferSize = FtwLiteDevice->SpareAreaLength;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  TempBufferSize,

+                  (VOID **) &TempBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  ZeroMem (TempBuffer, TempBufferSize);

+

+  Ptr = TempBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Length = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwFvBlock->Read (

+                                          FtwLiteDevice->FtwFvBlock,

+                                          FtwLiteDevice->FtwWorkBlockLba + Index,

+                                          0,

+                                          &Length,

+                                          Ptr

+                                          );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (TempBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += Length;

+  }

+  //

+  // Clean up the workspace, remove all the completed records.

+  //

+  Ptr = TempBuffer +

+    ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) *

+    FtwLiteDevice->SizeOfSpareBlock +

+    FtwLiteDevice->FtwWorkSpaceBase;

+  Status = CleanupWorkSpace (

+            FtwLiteDevice,

+            Ptr,

+            FtwLiteDevice->FtwWorkSpaceSize

+            );

+

+  CopyMem (

+    FtwLiteDevice->FtwWorkSpace,

+    Ptr,

+    FtwLiteDevice->FtwWorkSpaceSize

+    );

+

+  Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);

+

+  //

+  // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID

+  //

+  WorkingBlockHeader                      = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr;

+  WorkingBlockHeader->WorkingBlockValid   = FTW_INVALID_STATE;

+  WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;

+

+  //

+  // Try to keep the content of spare block

+  // Save spare block into a spare backup memory buffer (Sparebuffer)

+  //

+  SpareBufferSize = FtwLiteDevice->SpareAreaLength;

+  SpareBuffer     = AllocatePool (SpareBufferSize);

+  if (SpareBuffer == NULL) {

+    gBS->FreePool (TempBuffer);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Ptr = SpareBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Length = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Read (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &Length,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (TempBuffer);

+      gBS->FreePool (SpareBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += Length;

+  }

+  //

+  // Write the memory buffer to spare block

+  //

+  Status  = FtwEraseSpareBlock (FtwLiteDevice);

+  Ptr     = TempBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Length = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Write (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &Length,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (TempBuffer);

+      gBS->FreePool (SpareBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += Length;

+  }

+  //

+  // Free TempBuffer

+  //

+  gBS->FreePool (TempBuffer);

+

+  //

+  // Write the spare block to working block

+  //

+  Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (SpareBuffer);

+    return Status;

+  }

+  //

+  // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.

+  //

+  Status  = FtwEraseSpareBlock (FtwLiteDevice);

+  Ptr     = SpareBuffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Length = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Write (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &Length,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (SpareBuffer);

+      return EFI_ABORTED;

+    }

+

+    Ptr += Length;

+  }

+

+  gBS->FreePool (SpareBuffer);

+

+  DEBUG ((EFI_D_FTW_LITE, "FtwLite: reclaim work space success\n"));

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c
new file mode 100644
index 0000000..80258f4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ia32/Ia32FtwMisc.c
@@ -0,0 +1,399 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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. 

+

+Module Name:

+

+  Ia32FtwMisc.c

+  

+Abstract:

+  

+   Ia32 platform related code to support FtwLite..

+

+Revision History

+

+--*/

+

+

+#include <FtwLite.h>

+

+//

+// MACROs for boot block update

+//

+#define BOOT_BLOCK_BASE 0xFFFF0000

+

+//

+// (LPC -- D31:F0)

+//

+#define LPC_BUS_NUMBER    0x00

+#define LPC_DEVICE_NUMBER 0x1F

+#define LPC_IF            0xF0

+//

+// Top swap

+//

+#define GEN_STATUS    0xD4

+#define TOP_SWAP_BIT  (1 << 13)

+

+STATIC

+UINT32

+ReadPciRegister (

+  IN UINT32                 Offset

+  )

+/*++

+

+Routine Description:

+

+  Read PCI register value.

+

+Arguments:

+

+  Offset  - Offset of the register

+

+Returns:

+

+  The value.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  UINT32                          Value;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+

+  Value   = 0;

+  Status  = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status));

+    return 0;

+  }

+

+  Status = PciRootBridgeIo->Pci.Read (

+                                  PciRootBridgeIo,

+                                  EfiPciWidthUint32,

+                                  EFI_PCI_ADDRESS (LPC_BUS_NUMBER,

+    LPC_DEVICE_NUMBER,

+    LPC_IF,

+    Offset),

+                                  1,

+                                  &Value

+                                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+STATIC

+EFI_STATUS

+GetSwapState (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice,

+  OUT BOOLEAN               *SwapState

+  )

+/*++

+

+Routine Description:

+

+  Get swap state

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  SwapState     - Swap state

+

+Returns:

+

+  EFI_SUCCESS - State successfully got

+

+--*/

+{

+  //

+  // Top swap status is 13 bit

+  //

+  *SwapState = (BOOLEAN) ((ReadPciRegister (GEN_STATUS) & TOP_SWAP_BIT) != 0);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+SetSwapState (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice,

+  IN  BOOLEAN               TopSwap

+  )

+/*++

+

+Routine Description:

+    Set swap state.

+

+Arguments:

+    FtwLiteDevice  - Indicates a pointer to the calling context.  

+    TopSwap        - New swap state

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+

+Note:

+    the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that

+    software will not be able to clear the Top-Swap bit until the system is

+    rebooted without GNT[A]# being pulled down.

+

+--*/

+{

+  UINT32                          GenStatus;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

+  EFI_STATUS                      Status;

+

+  //

+  // Top-Swap bit (bit 13, D31: F0, Offset D4h)

+  //

+  GenStatus = ReadPciRegister (GEN_STATUS);

+

+  //

+  // Set 13 bit, according to input NewSwapState

+  //

+  if (TopSwap) {

+    GenStatus |= TOP_SWAP_BIT;

+  } else {

+    GenStatus &= ~TOP_SWAP_BIT;

+  }

+

+  Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID **) &PciRootBridgeIo);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "FtwLite: Locate PCI root bridge io protocol - %r", Status));

+    return Status;

+  }

+  //

+  // Write back the GenStatus register

+  //

+  Status = PciRootBridgeIo->Pci.Write (

+                                  PciRootBridgeIo,

+                                  EfiPciWidthUint32,

+                                  EFI_PCI_ADDRESS (LPC_BUS_NUMBER,

+    LPC_DEVICE_NUMBER,

+    LPC_IF,

+    GEN_STATUS),

+                                  1,

+                                  &GenStatus

+                                  );

+

+  DEBUG_CODE (

+    if (TopSwap) {

+      DEBUG ((EFI_D_ERROR, "SAR: Set top swap\n"));

+    } else {

+      DEBUG ((EFI_D_ERROR, "SAR: Clear top swap\n"));

+    }

+  );

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsBootBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+

+  Check whether the block is a boot block.

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  FvBlock       - Fvb protocol instance

+  Lba           - Lba value

+

+Returns:

+

+  Is a boot block or not

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *BootFvb;

+

+  Status = GetFvbByAddress (BOOT_BLOCK_BASE, &BootFvb);

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+  //

+  // Compare the Fvb

+  //

+  return (BOOLEAN) (FvBlock == BootFvb);

+}

+

+EFI_STATUS

+FlushSpareBlockToBootBlock (

+  EFI_FTW_LITE_DEVICE      *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Boot block is accessed by BootFvb protocol interface. LBA is 0.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to boot block

+    EFI_INVALID_PARAMETER    - Input parameter error

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+Notes:

+    FTW will do extra work on boot block update.

+    FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL, 

+    which is produced by a chipset driver.

+

+    FTW updating boot block steps:

+    1. Erase top swap block (0xFFFE-0xFFFEFFFF) and write data to it ready

+    2. Read data from top swap block to memory buffer

+    3. SetSwapState(EFI_SWAPPED)

+    4. Erasing boot block (0xFFFF-0xFFFFFFFF)

+    5. Programming boot block until the boot block is ok.

+    6. SetSwapState(UNSWAPPED)

+

+    Notes:

+     1. Since the SwapState bit is saved in CMOS, FTW can restore and continue 

+     even in the scenario of power failure.

+     2. FTW shall not allow to update boot block when battery state is error.

+

+--*/

+{

+  EFI_STATUS                          Status;

+  UINTN                               Length;

+  UINT8                               *Buffer;

+  UINTN                               Count;

+  UINT8                               *Ptr;

+  UINTN                               Index;

+  BOOLEAN                             TopSwap;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *BootFvb;

+  EFI_LBA                             BootLba;

+

+  //

+  // Allocate a memory buffer

+  //

+  Length  = FtwLiteDevice->SpareAreaLength;

+  Buffer  = AllocatePool (Length);

+  if (Buffer == NULL) {

+  }

+  //

+  // Get TopSwap bit state

+  //

+  Status = GetSwapState (FtwLiteDevice, &TopSwap);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "FtwLite: Get Top Swapped status - %r\n", Status));

+    gBS->FreePool (Buffer);

+    return EFI_ABORTED;

+  }

+

+  if (TopSwap) {

+    //

+    // Get FVB of current boot block

+    //

+    Status = GetFvbByAddress (FtwLiteDevice->SpareAreaAddress + FTW_BLOCK_SIZE, &BootFvb);

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (Buffer);

+      return Status;

+    }

+    //

+    // Read data from current boot block

+    //

+    BootLba = 0;

+    Ptr     = Buffer;

+    for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+      Count = FtwLiteDevice->SizeOfSpareBlock;

+      Status = BootFvb->Read (

+                          BootFvb,

+                          BootLba + Index,

+                          0,

+                          &Count,

+                          Ptr

+                          );

+      if (EFI_ERROR (Status)) {

+        gBS->FreePool (Buffer);

+        return Status;

+      }

+

+      Ptr += Count;

+    }

+

+  } else {

+    //

+    // Read data from spare block

+    //

+    Ptr = Buffer;

+    for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+      Count = FtwLiteDevice->SizeOfSpareBlock;

+      Status = FtwLiteDevice->FtwBackupFvb->Read (

+                                              FtwLiteDevice->FtwBackupFvb,

+                                              FtwLiteDevice->FtwSpareLba + Index,

+                                              0,

+                                              &Count,

+                                              Ptr

+                                              );

+      if (EFI_ERROR (Status)) {

+        gBS->FreePool (Buffer);

+        return Status;

+      }

+

+      Ptr += Count;

+    }

+    //

+    // Set TopSwap bit

+    //

+    Status = SetSwapState (FtwLiteDevice, TRUE);

+    DEBUG ((EFI_D_ERROR, "FtwLite: Set Swap State - %r\n", Status));

+    ASSERT_EFI_ERROR (Status);

+  }

+  //

+  // Erase boot block. After setting TopSwap bit, it's spare block now!

+  //

+  Status = FtwEraseSpareBlock (FtwLiteDevice);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Buffer);

+    return EFI_ABORTED;

+  }

+  //

+  // Write memory buffer to currenet spare block

+  //

+  Ptr = Buffer;

+  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {

+    Count = FtwLiteDevice->SizeOfSpareBlock;

+    Status = FtwLiteDevice->FtwBackupFvb->Write (

+                                            FtwLiteDevice->FtwBackupFvb,

+                                            FtwLiteDevice->FtwSpareLba + Index,

+                                            0,

+                                            &Count,

+                                            Ptr

+                                            );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Write boot block - %r\n", Status));

+      gBS->FreePool (Buffer);

+      return Status;

+    }

+

+    Ptr += Count;

+  }

+

+  gBS->FreePool (Buffer);

+

+  //

+  // Clear TopSwap bit

+  //

+  Status = SetSwapState (FtwLiteDevice, FALSE);

+  DEBUG ((EFI_D_ERROR, "FtwLite: Clear Swap State - %r\n", Status));

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c
new file mode 100644
index 0000000..d31883b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/Ipf/IpfFtwMisc.c
@@ -0,0 +1,143 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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. 

+

+Module Name:

+

+  IpfFtwMisc.c

+  

+Abstract:

+  

+  Ipf platform related code to support FtwLite..

+

+Revision History

+

+--*/

+

+

+#include <FtwLite.h>

+

+//

+// MACROs for boot block update

+//

+#define BOOT_BLOCK_BASE

+

+STATIC

+EFI_STATUS

+GetSwapState (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice,

+  OUT BOOLEAN               *SwapState

+  )

+/*++

+

+Routine Description:

+

+  Get swap state

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  SwapState     - Swap state

+

+Returns:

+

+  EFI_SUCCESS - State successfully got

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+SetSwapState (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice,

+  IN  BOOLEAN               TopSwap

+  )

+/*++

+

+Routine Description:

+    Set swap state.

+

+Arguments:

+    FtwLiteDevice  - Indicates a pointer to the calling context.  

+    TopSwap        - New swap state

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+

+Note:

+    the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that

+    software will not be able to clear the Top-Swap bit until the system is

+    rebooted without GNT[A]# being pulled down.

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsBootBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+

+  Check whether the block is a boot block.

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  FvBlock       - Fvb protocol instance

+  Lba           - Lba value

+

+Returns:

+

+  Is a boot block or not

+

+--*/

+{

+  //

+  // IPF doesn't support safe bootblock update

+  // so treat bootblock as normal block

+  //

+  return FALSE;

+}

+

+EFI_STATUS

+FlushSpareBlockToBootBlock (

+  EFI_FTW_LITE_DEVICE      *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Boot block is accessed by BootFvb protocol interface. LBA is 0.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to boot block

+    EFI_INVALID_PARAMETER    - Input parameter error

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+Notes:

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/build.xml b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/build.xml
new file mode 100644
index 0000000..37d04b5
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="FtwLite"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="FtwLite">

+      <GenBuild baseName="FtwLite" mbdFilename="${MODULE_DIR}/FtwLite.mbd" msaFilename="${MODULE_DIR}/FtwLite.msa"/>

+   </target>

+   <target depends="FtwLite_clean" name="clean"/>

+   <target depends="FtwLite_cleanall" name="cleanall"/>

+   <target name="FtwLite_clean">

+      <OutputDirSetup baseName="FtwLite" mbdFilename="${MODULE_DIR}/FtwLite.mbd" msaFilename="${MODULE_DIR}/FtwLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/FtwLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/FtwLite_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="FtwLite_cleanall">

+      <OutputDirSetup baseName="FtwLite" mbdFilename="${MODULE_DIR}/FtwLite.mbd" msaFilename="${MODULE_DIR}/FtwLite.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/FtwLite_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/FtwLite_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**FtwLite*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c
new file mode 100644
index 0000000..067bfcf
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/x64/x64FtwMisc.c
@@ -0,0 +1,140 @@
+

+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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. 

+

+Module Name:

+

+  x64FtwMisc.c

+  

+Abstract:

+  

+  X64 platform related code to support FtwLite..

+

+Revision History

+

+--*/

+

+

+#include <FtwLite.h>

+

+//

+// MACROs for boot block update

+//

+#define BOOT_BLOCK_BASE

+

+STATIC

+EFI_STATUS

+GetSwapState (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice,

+  OUT BOOLEAN               *SwapState

+  )

+/*++

+

+Routine Description:

+

+  Get swap state

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  SwapState     - Swap state

+

+Returns:

+

+  EFI_SUCCESS - State successfully got

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+SetSwapState (

+  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice,

+  IN  BOOLEAN               TopSwap

+  )

+/*++

+

+Routine Description:

+    Set swap state.

+

+Arguments:

+    FtwLiteDevice  - Indicates a pointer to the calling context.  

+    TopSwap        - New swap state

+

+Returns:

+    EFI_SUCCESS   - The function completed successfully

+

+Note:

+    the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that

+    software will not be able to clear the Top-Swap bit until the system is

+    rebooted without GNT[A]# being pulled down.

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsBootBlock (

+  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice,

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,

+  EFI_LBA                             Lba

+  )

+/*++

+

+Routine Description:

+

+  Check whether the block is a boot block.

+

+Arguments:

+

+  FtwLiteDevice - Calling context

+  FvBlock       - Fvb protocol instance

+  Lba           - Lba value

+

+Returns:

+

+  Is a boot block or not

+

+--*/

+{

+  return FALSE;

+}

+

+EFI_STATUS

+FlushSpareBlockToBootBlock (

+  EFI_FTW_LITE_DEVICE      *FtwLiteDevice

+  )

+/*++

+

+Routine Description:

+    Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.

+    Spare block is accessed by FTW backup FVB protocol interface. LBA is 

+    FtwLiteDevice->FtwSpareLba.

+    Boot block is accessed by BootFvb protocol interface. LBA is 0.

+

+Arguments:

+    FtwLiteDevice  - The private data of FTW_LITE driver

+

+Returns:

+    EFI_SUCCESS              - Spare block content is copied to boot block

+    EFI_INVALID_PARAMETER    - Input parameter error

+    EFI_OUT_OF_RESOURCES     - Allocate memory error

+    EFI_ABORTED              - The function could not complete successfully

+

+Notes:

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c
new file mode 100644
index 0000000..dc7ed07
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.c
@@ -0,0 +1,234 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Crc32SectionExtract.c

+

+Abstract:

+

+  Implements GUIDed section extraction protocol interface with 

+  a specific GUID: CRC32.

+

+  Please refer to the Tiano File Image Format Specification, 

+  FV spec 0.3.6

+

+--*/

+

+

+#include <GuidedSection.h>

+#include <Crc32SectionExtract.h>

+

+EFI_STATUS

+InitializeCrc32GuidedSectionExtractionProtocol (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  );

+

+EFI_STATUS

+InitializeCrc32GuidedSectionExtractionProtocol (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+/*++

+

+Routine Description: 

+

+  Entry point of the CRC32 GUIDed section extraction protocol. 

+  Creates and initializes an instance of the GUIDed section 

+  extraction protocol with CRC32 GUID.

+

+Arguments:  

+

+  ImageHandle   EFI_HANDLE: A handle for the image that is initializing 

+                this driver

+  SystemTable   EFI_SYSTEM_TABLE: A pointer to the EFI system table        

+

+Returns:  

+

+  EFI_SUCCESS:          Driver initialized successfully

+  EFI_LOAD_ERROR:       Failed to Initialize or has been loaded 

+  EFI_OUT_OF_RESOURCES: Could not allocate needed resources

+

+--*/

+{

+  EFI_STATUS                              Status;

+  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL  *Crc32GuidedSep;

+  EFI_HANDLE                              Handle;

+

+  //

+  // Call all constructors per produced protocols

+  //

+  Status = GuidedSectionExtractionProtocolConstructor (

+            &Crc32GuidedSep,

+            (EFI_EXTRACT_GUIDED_SECTION) Crc32ExtractSection

+            );

+  if (EFI_ERROR (Status)) {

+    if (Crc32GuidedSep != NULL) {

+      gBS->FreePool (Crc32GuidedSep);

+    }

+

+    return Status;

+  }

+  //

+  // Pass in a NULL to install to a new handle

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiCrc32GuidedSectionExtractionProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  Crc32GuidedSep

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Crc32GuidedSep);

+    return EFI_LOAD_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+UINT32

+GetSectionLength (

+  IN EFI_COMMON_SECTION_HEADER  *CommonHeader

+  )

+/*++

+

+  Routine Description:

+    Get a length of section.

+

+  Parameters:

+    CommonHeader      -   Pointer to the common section header.

+

+  Return Value:

+    The length of the section, including the section header.

+

+--*/

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    CommonHeader - add argument and description to function comment

+{

+  UINT32  Size;

+

+  Size = *(UINT32 *) CommonHeader->Size & 0x00FFFFFF;

+

+  return Size;

+}

+

+STATIC

+EFI_STATUS

+Crc32ExtractSection (

+  IN  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL  *This,

+  IN  VOID                                    *InputSection,

+  OUT VOID                                    **OutputBuffer,

+  OUT UINTN                                   *OutputSize,

+  OUT UINT32                                  *AuthenticationStatus

+  )

+/*++

+

+  Routine Description:

+    This function reads and extracts contents of a section from an

+    encapsulating section.

+

+  Parameters:

+    This                    - Indicates the calling context.

+    InputSection            - Buffer containing the input GUIDed section 

+                              to be processed.

+    OutputBuffer            - *OutputBuffer is allocated from boot services

+                              pool memory and containing the new section

+                              stream. The caller is responsible for freeing

+                              this buffer.

+    AuthenticationStatus    - Pointer to a caller allocated UINT32 that

+                              indicates the authentication status of the

+                              output buffer

+

+  Return Value:

+    EFI_SUCCESS

+    EFI_OUT_OF_RESOURCES

+    EFI_INVALID_PARAMETER

+    EFI_NOT_AVAILABLE_YET

+

+--*/

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    This - add argument and description to function comment

+// TODO:    InputSection - add argument and description to function comment

+// TODO:    OutputBuffer - add argument and description to function comment

+// TODO:    OutputSize - add argument and description to function comment

+// TODO:    AuthenticationStatus - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                Status;

+  CRC32_SECTION_HEADER      *Crc32SectionHeader;

+  EFI_GUID_DEFINED_SECTION  *GuidedSectionHeader;

+  UINT8                     *Image;

+  UINT32                    Crc32Checksum;

+  VOID                      *DummyInterface;

+

+  if (OutputBuffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *OutputBuffer = NULL;

+

+  //

+  // Points to the section header

+  //

+  Crc32SectionHeader  = (CRC32_SECTION_HEADER *) InputSection;

+  GuidedSectionHeader = (EFI_GUID_DEFINED_SECTION *) InputSection;

+

+  //

+  // Check if the GUID is a CRC32 section GUID

+  //

+  if (!CompareGuid (

+        &(GuidedSectionHeader->SectionDefinitionGuid),

+        &gEfiCrc32GuidedSectionExtractionProtocolGuid

+        )) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Image = (UINT8 *) InputSection + (UINT32) (GuidedSectionHeader->DataOffset);

+  *OutputSize = GetSectionLength ((EFI_COMMON_SECTION_HEADER *) InputSection) - (UINT32) GuidedSectionHeader->DataOffset;

+

+  Status = gBS->AllocatePool (EfiBootServicesData, *OutputSize, OutputBuffer);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Implictly CRC32 GUIDed section should have STATUS_VALID bit set

+  //

+  ASSERT (GuidedSectionHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);

+  *AuthenticationStatus = EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED;

+

+  //

+  // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.

+  //

+  Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);

+  if (!EFI_ERROR (Status)) {

+    *AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE | EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE;

+  } else {

+    //

+    // Calculate CRC32 Checksum of Image

+    //

+    gBS->CalculateCrc32 (Image, *OutputSize, &Crc32Checksum);

+    if (Crc32Checksum != Crc32SectionHeader->CRC32Checksum) {

+      *AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_TEST_FAILED | EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED;

+    }

+  }

+

+  CopyMem (*OutputBuffer, Image, *OutputSize);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs
new file mode 100644
index 0000000..033ff94
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Crc32SectionExtraction.dxs

+

+Abstract:

+

+  Dependency expression file.

+  

+--*/  

+

+#include <AutoGen.h>  

+#include "DxeDepex.h"

+

+DEPENDENCY_START

+  EFI_RUNTIME_ARCH_PROTOCOL_GUID

+DEPENDENCY_END

+

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h
new file mode 100644
index 0000000..8e32d6d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.h
@@ -0,0 +1,65 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Crc32SectionExtract.h

+  

+Abstract:

+

+  Header file for Crc32SectionExtract.c

+  Please refer to Tiano File Image Format specification 

+  FV spec 0.3.6

+

+--*/

+

+#ifndef _CRC32_GUIDED_SECTION_EXTRACTION_H

+#define _CRC32_GUIDED_SECTION_EXTRACTION_H

+

+typedef struct {

+  EFI_GUID_DEFINED_SECTION  GuidedSectionHeader;

+  UINT32                    CRC32Checksum;

+} CRC32_SECTION_HEADER;

+

+//

+// Function prototype declarations

+//

+STATIC

+EFI_STATUS

+Crc32ExtractSection (

+  IN  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL  *This,

+  IN  VOID                                    *InputSection,

+  OUT VOID                                    **OutputBuffer,

+  OUT UINTN                                   *OutputSize,

+  OUT UINT32                                  *AuthenticationStatus

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  InputSection          - TODO: add argument description

+  OutputBuffer          - TODO: add argument description

+  OutputSize            - TODO: add argument description

+  AuthenticationStatus  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.mbd b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.mbd
new file mode 100644
index 0000000..67ea3cd
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.mbd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Crc32SectionExtract</BaseName>

+    <Guid>51C9F40C-5243-4473-B265-B3C8FFAFF9FA</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa
new file mode 100644
index 0000000..b8cb215
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Crc32SectionExtract</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>51C9F40C-5243-4473-B265-B3C8FFAFF9FA</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Crc32SectionExtract.c</Filename>

+    <Filename>Crc32SectionExtract.h</Filename>

+    <Filename>GuidedSection.c</Filename>

+    <Filename>GuidedSection.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">SecurityPolicy</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">Crc32GuidedSectionExtraction</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeCrc32GuidedSectionExtractionProtocol</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/GuidedSection.c b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/GuidedSection.c
new file mode 100644
index 0000000..3c3f22f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/GuidedSection.c
@@ -0,0 +1,75 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GuidedSection.c

+  

+Abstract:

+

+  GUIDed section extraction protocol implementation.  

+  This contains the common constructor of GUIDed section

+  extraction protocol. GUID specific implementation of each

+  GUIDed section extraction protocol can be found in other

+  files under the same directory.

+  

+  Please refer to the Tiano File Image Format Specification, 

+  FV spec 0.3.6

+  

+  Acronyms used       Meaning

+

+    

+--*/

+

+

+#include "Common/FirmwareFileSystem.h"

+

+EFI_STATUS

+GuidedSectionExtractionProtocolConstructor (

+  OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL      **GuidedSep,

+  IN  EFI_EXTRACT_GUIDED_SECTION                  ExtractSection

+  )

+/*++

+

+Routine Description:

+

+  Constructor for the GUIDed section extraction protocol.  Initializes

+  instance data.

+

+Arguments:

+

+  This      Instance to construct

+

+Returns:

+

+  EFI_SUCCESS:  Instance initialized.

+

+--*/

+// TODO:    GuidedSep - add argument and description to function comment

+// TODO:    ExtractSection - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  EFI_STATUS  Status;

+

+  *GuidedSep = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL),

+                  (VOID **) GuidedSep

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  (*GuidedSep)->ExtractSection = ExtractSection;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/GuidedSection.h b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/GuidedSection.h
new file mode 100644
index 0000000..1399edf
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/GuidedSection.h
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GuidedSection.h

+  

+Abstract:

+

+  Header file for GuidedSection.c

+  Please refer to Tiano File Image Format specification 

+  FV spec 0.3.6

+  

+--*/

+

+#ifndef _GUIDED_SECTION_EXTRACTION_H

+#define _GUIDED_SECTION_EXTRACTION_H

+

+//

+// Function prototype declarations

+//

+EFI_STATUS

+GuidedSectionExtractionProtocolConstructor (

+  OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL      **GuidedSep,

+  IN  EFI_EXTRACT_GUIDED_SECTION                  ExtractSection

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  GuidedSep       - TODO: add argument description

+  ExtractSection  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/build.xml b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/build.xml
new file mode 100644
index 0000000..774e588
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Crc32SectionExtract"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Crc32SectionExtract">

+      <GenBuild baseName="Crc32SectionExtract" mbdFilename="${MODULE_DIR}/Crc32SectionExtract.mbd" msaFilename="${MODULE_DIR}/Crc32SectionExtract.msa"/>

+   </target>

+   <target depends="Crc32SectionExtract_clean" name="clean"/>

+   <target depends="Crc32SectionExtract_cleanall" name="cleanall"/>

+   <target name="Crc32SectionExtract_clean">

+      <OutputDirSetup baseName="Crc32SectionExtract" mbdFilename="${MODULE_DIR}/Crc32SectionExtract.mbd" msaFilename="${MODULE_DIR}/Crc32SectionExtract.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Crc32SectionExtract_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Crc32SectionExtract_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Crc32SectionExtract_cleanall">

+      <OutputDirSetup baseName="Crc32SectionExtract" mbdFilename="${MODULE_DIR}/Crc32SectionExtract.mbd" msaFilename="${MODULE_DIR}/Crc32SectionExtract.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Crc32SectionExtract_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Crc32SectionExtract_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Crc32SectionExtract*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/Common.h b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/Common.h
new file mode 100644
index 0000000..7a1ab78
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/Common.h
@@ -0,0 +1,59 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    Common.h

+  

+Abstract:

+  The generic memory test driver definition

+

+--*/

+

+#ifndef _COMMON_H

+#define _COMMON_H

+

+//

+// Some global define

+//

+#define GENERIC_CACHELINE_SIZE  0x40

+

+//

+// The SPARSE_SPAN_SIZE size can not small then the MonoTestSize

+//

+#define TEST_BLOCK_SIZE   0x2000000

+#define QUICK_SPAN_SIZE   (TEST_BLOCK_SIZE >> 2)

+#define SPARSE_SPAN_SIZE  (TEST_BLOCK_SIZE >> 4)

+

+//

+// This structure records every nontested memory range parsed through GCD

+// service.

+//

+#define EFI_NONTESTED_MEMORY_RANGE_SIGNATURE  EFI_SIGNATURE_32 ('N', 'T', 'M', 'E')

+typedef struct {

+  UINTN                 Signature;

+  LIST_ENTRY            Link;

+  EFI_PHYSICAL_ADDRESS  StartAddress;

+  UINT64                Length;

+  UINT64                Capabilities;

+  BOOLEAN               Above4G;

+  BOOLEAN               AlreadyMapped;

+} NONTESTED_MEMORY_RANGE;

+

+#define NONTESTED_MEMORY_RANGE_FROM_LINK(link) \

+        CR(link, NONTESTED_MEMORY_RANGE, Link, EFI_NONTESTED_MEMORY_RANGE_SIGNATURE)

+

+//

+// This is the memory test driver's structure definition

+//

+#define EFI_GENERIC_MEMORY_TEST_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('G', 'E', 'M', 'T')

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.c b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.c
new file mode 100644
index 0000000..7bad347
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.c
@@ -0,0 +1,214 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  NullMemoryTest.c

+  

+Abstract:

+

+--*/

+

+

+#include "NullMemoryTest.h"

+

+//

+// Module global members

+//

+UINT64                            mTestedSystemMemory = 0;

+UINT64                            mTotalSystemMemory  = 0;

+EFI_HANDLE                        mGenericMemoryTestHandle;

+

+//

+// Driver entry here

+//

+EFI_GENERIC_MEMORY_TEST_PROTOCOL  mGenericMemoryTest = {

+  InitializeMemoryTest,

+  GenPerformMemoryTest,

+  GenMemoryTestFinished,

+  GenCompatibleRangeTest

+};

+

+EFI_STATUS

+EFIAPI

+GenericMemoryTestEntryPoint (

+  IN  EFI_HANDLE           ImageHandle,

+  IN  EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  The generic memory test driver's entry point, it can initialize private data

+  to default value

+

+Arguments:

+

+  ImageHandle of the loaded driver

+  Pointer to the System Table

+

+Returns:

+

+  Status

+

+  EFI_SUCCESS           - Protocol successfully installed

+  EFI_OUT_OF_RESOURCES  - Can not allocate protocol data structure in base

+                          memory

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Install the protocol

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &mGenericMemoryTestHandle,

+                  &gEfiGenericMemTestProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &mGenericMemoryTest

+                  );

+

+  return Status;

+}

+//

+// EFI_GENERIC_MEMORY_TEST_PROTOCOL implementation

+//

+EFI_STATUS

+EFIAPI

+InitializeMemoryTest (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL          *This,

+  IN  EXTENDMEM_COVERAGE_LEVEL                 Level,

+  OUT BOOLEAN                                  *RequireSoftECCInit

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  UINTN                           NumberOfDescriptors;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;

+  UINTN                           Index;

+

+  gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);

+  for (Index = 0; Index < NumberOfDescriptors; Index++) {

+    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved &&

+        (MemorySpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==

+          (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)

+          ) {

+      gDS->RemoveMemorySpace (

+            MemorySpaceMap[Index].BaseAddress,

+            MemorySpaceMap[Index].Length

+            );

+

+      gDS->AddMemorySpace (

+            EfiGcdMemoryTypeSystemMemory,

+            MemorySpaceMap[Index].BaseAddress,

+            MemorySpaceMap[Index].Length,

+            MemorySpaceMap[Index].Capabilities &~

+            (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)

+            );

+

+      mTestedSystemMemory += MemorySpaceMap[Index].Length;

+      mTotalSystemMemory += MemorySpaceMap[Index].Length;

+    } else if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {

+      mTotalSystemMemory += MemorySpaceMap[Index].Length;

+    }

+  }

+

+  gBS->FreePool (MemorySpaceMap);

+

+  *RequireSoftECCInit = FALSE;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GenPerformMemoryTest (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL          *This,

+  IN OUT UINT64                                *TestedMemorySize,

+  OUT UINT64                                   *TotalMemorySize,

+  OUT BOOLEAN                                  *ErrorOut,

+  IN BOOLEAN                                   TestAbort

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  *ErrorOut         = FALSE;

+  *TestedMemorySize = mTestedSystemMemory;

+  *TotalMemorySize  = mTotalSystemMemory;

+

+  return EFI_NOT_FOUND;

+

+}

+

+EFI_STATUS

+EFIAPI

+GenMemoryTestFinished (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GenCompatibleRangeTest (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL          *This,

+  IN  EFI_PHYSICAL_ADDRESS                     StartAddress,

+  IN  UINT64                                   Length

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR descriptor;

+

+  gDS->GetMemorySpaceDescriptor (StartAddress, &descriptor);

+

+  gDS->RemoveMemorySpace (StartAddress, Length);

+

+  gDS->AddMemorySpace (

+        EfiGcdMemoryTypeSystemMemory,

+        StartAddress,

+        Length,

+        descriptor.Capabilities &~(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)

+        );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.dxs b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.dxs
new file mode 100644
index 0000000..9f281b3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  NullMemoryTest.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.h b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.h
new file mode 100644
index 0000000..b4a0720
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.h
@@ -0,0 +1,65 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    NullMemoryTest.h

+  

+Abstract:

+  The generic memory test driver definition

+

+--*/

+

+#ifndef _NULL_MEMORY_TEST_H

+#define _NULL_MEMORY_TEST_H

+

+#include "Common.h"

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+InitializeMemoryTest (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL          *This,

+  IN  EXTENDMEM_COVERAGE_LEVEL                 Level,

+  OUT BOOLEAN                                  *RequireSoftECCInit

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GenPerformMemoryTest (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL          *This,

+  IN OUT UINT64                                *TestedMemorySize,

+  OUT UINT64                                   *TotalMemorySize,

+  OUT BOOLEAN                                  *ErrorOut,

+  IN BOOLEAN                                   TestAbort

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GenMemoryTestFinished (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GenCompatibleRangeTest (

+  IN EFI_GENERIC_MEMORY_TEST_PROTOCOL          *This,

+  IN  EFI_PHYSICAL_ADDRESS                     StartAddress,

+  IN  UINT64                                   Length

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.mbd b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.mbd
new file mode 100644
index 0000000..2b770fe
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>NullMemoryTest</BaseName>

+    <Guid>96B5C032-DF4C-4b6e-8232-438DCF448D0E</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>    

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeServicesTableLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>    

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.msa b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.msa
new file mode 100644
index 0000000..705bef6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.msa
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>NullMemoryTest</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>96B5C032-DF4C-4b6e-8232-438DCF448D0E</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeServicesTableLib</LibraryClass>            

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Common.h</Filename>

+    <Filename>NullMemoryTest.c</Filename>

+    <Filename>NullMemoryTest.h</Filename>

+    <Filename>NullMemoryTest.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">GenericMemTest</Protocol>    

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>GenericMemoryTestEntryPoint</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/build.xml b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/build.xml
new file mode 100644
index 0000000..0556891
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="NullMemoryTest"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/GenericMemoryTest/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="NullMemoryTest">

+      <GenBuild baseName="NullMemoryTest" mbdFilename="${MODULE_DIR}/NullMemoryTest.mbd" msaFilename="${MODULE_DIR}/NullMemoryTest.msa"/>

+   </target>

+   <target depends="NullMemoryTest_clean" name="clean"/>

+   <target depends="NullMemoryTest_cleanall" name="cleanall"/>

+   <target name="NullMemoryTest_clean">

+      <OutputDirSetup baseName="NullMemoryTest" mbdFilename="${MODULE_DIR}/NullMemoryTest.mbd" msaFilename="${MODULE_DIR}/NullMemoryTest.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/NullMemoryTest_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/NullMemoryTest_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="NullMemoryTest_cleanall">

+      <OutputDirSetup baseName="NullMemoryTest" mbdFilename="${MODULE_DIR}/NullMemoryTest.mbd" msaFilename="${MODULE_DIR}/NullMemoryTest.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/NullMemoryTest_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/NullMemoryTest_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**NullMemoryTest*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.c b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.c
new file mode 100644
index 0000000..e091ae1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.c
@@ -0,0 +1,154 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BaseMemoryTest.c

+  

+Abstract:

+  

+  The PEI memory test support

+

+--*/

+

+#include <BaseMemoryTest.h>

+#include <Library/ReportStatusCodeLib.h>

+

+static PEI_BASE_MEMORY_TEST_PPI mPeiBaseMemoryTestPpi = { BaseMemoryTest };

+

+static EFI_PEI_PPI_DESCRIPTOR   PpiListPeiBaseMemoryTest = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gPeiBaseMemoryTestPpiGuid,

+  &mPeiBaseMemoryTestPpi

+};

+

+EFI_STATUS

+EFIAPI

+PeiBaseMemoryTestInit (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+Description:

+

+  Entry point function of BaseMemoryTestInit Peim.

+

+Arguments:

+

+  PeiServices           - General purpose services available to every PEIM.

+  FfsHeader             - Ffs header pointer

+

+Returns:

+

+  Status                - Result of InstallPpi

+

+--*/  

+{

+  EFI_STATUS  Status;

+

+  Status = (**PeiServices).InstallPpi (PeiServices, &PpiListPeiBaseMemoryTest);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+BaseMemoryTest (

+  IN  EFI_PEI_SERVICES                   **PeiServices,

+  IN PEI_BASE_MEMORY_TEST_PPI            *This,

+  IN  EFI_PHYSICAL_ADDRESS               BeginAddress,

+  IN  UINT64                             MemoryLength,

+  IN  PEI_MEMORY_TEST_OP                 Operation,

+  OUT EFI_PHYSICAL_ADDRESS               *ErrorAddress

+  )

+/*++

+Description:

+

+  Test base memory.

+

+Arguments:

+

+  PeiServices   - General purpose services available to every PEIM.

+  This          - Pei memory test PPI pointer.

+  BeginAddress  - Beginning of the memory address to be checked.

+  MemoryLength  - Bytes of memory range to be checked.

+  Operation     - Type of memory check operation to be performed.

+  ErrorAddress  - Return the address of the error memory address.

+  ErrorAddress  - Address which has error when checked.

+

+Returns:

+

+  Status        - Result of InstallPpi

+

+--*/    

+{

+  UINT32                TestPattern;

+  UINT32                TestMask;

+  EFI_PHYSICAL_ADDRESS  TempAddress;

+  UINT32                SpanSize;

+

+  REPORT_STATUS_CODE (

+    EFI_PROGRESS_CODE,

+    EFI_COMPUTING_UNIT_MEMORY + EFI_CU_MEMORY_PC_TEST

+    );

+

+  TestPattern = TEST_PATTERN;

+  TestMask    = 0;

+  SpanSize    = 0;

+

+  //

+  // Make sure we don't try and test anything above the max physical address range

+  //

+  ASSERT_EFI_ERROR (BeginAddress + MemoryLength < EFI_MAX_ADDRESS);

+

+  switch (Operation) {

+  case Extensive:

+    SpanSize = 0x4;

+    break;

+

+  case Sparse:

+  case Quick:

+    SpanSize = COVER_SPAN;

+    break;

+

+  case Ignore:

+    goto Done;

+    break;

+  }

+  //

+  // Write the test pattern into memory range

+  //

+  TempAddress = BeginAddress;

+  while (TempAddress < BeginAddress + MemoryLength) {

+    (*(UINT32 *) (UINTN) TempAddress) = TestPattern;

+    TempAddress += SpanSize;

+  }

+  //

+  // Read pattern from memory and compare it

+  //

+  TempAddress = BeginAddress;

+  while (TempAddress < BeginAddress + MemoryLength) {

+    if ((*(UINT32 *) (UINTN) TempAddress) != TestPattern) {

+      *ErrorAddress = TempAddress;

+      REPORT_STATUS_CODE (

+        EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED,

+        EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UNCORRECTABLE

+        );

+

+      return EFI_DEVICE_ERROR;

+    }

+

+    TempAddress += SpanSize;

+  }

+

+Done:

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.h b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.h
new file mode 100644
index 0000000..15d6c61
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.h
@@ -0,0 +1,89 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BaseMemoryTest.h

+   

+Abstract:

+

+  Tiano PEIM to provide a PEI memory test service.

+

+--*/

+

+#ifndef _PEI_BASE_MEMORY_TEST_H_

+#define _PEI_BASE_MEMORY_TEST_H_

+

+#include <EdkPeim.h>

+

+//

+// Some global define

+//

+#define COVER_SPAN    0x40000

+#define TEST_PATTERN  0x5A5A5A5A

+

+EFI_STATUS

+EFIAPI

+PeiBaseMemoryTestInit (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  FfsHeader   - TODO: add argument description

+  PeiServices - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+BaseMemoryTest (

+  IN  EFI_PEI_SERVICES                   **PeiServices,

+  IN PEI_BASE_MEMORY_TEST_PPI            *This,

+  IN  EFI_PHYSICAL_ADDRESS               BeginAddress,

+  IN  UINT64                             MemoryLength,

+  IN  PEI_MEMORY_TEST_OP                 Operation,

+  OUT EFI_PHYSICAL_ADDRESS               *ErrorAddress

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PeiServices   - TODO: add argument description

+  This          - TODO: add argument description

+  BeginAddress  - TODO: add argument description

+  MemoryLength  - TODO: add argument description

+  Operation     - TODO: add argument description

+  ErrorAddress  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.mbd b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.mbd
new file mode 100644
index 0000000..59c52c9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.mbd
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PeiBaseMemoryTestInit</BaseName>

+    <Guid>736EB068-8C01-47c5-964B-1C57BD5D4D64</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>    

+    <Library>PeimEntryPoint</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.msa b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.msa
new file mode 100644
index 0000000..62ed783
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/BaseMemoryTest.msa
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PeiBaseMemoryTestInit</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>736EB068-8C01-47c5-964B-1C57BD5D4D64</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BaseMemoryTest.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">BaseMemoryTest</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeiBaseMemoryTestInit</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/build.xml b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/build.xml
new file mode 100644
index 0000000..cf6dfea
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/GenericMemoryTest/Pei/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiBaseMemoryTestInit"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/GenericMemoryTest/Pei"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiBaseMemoryTestInit">

+      <GenBuild baseName="PeiBaseMemoryTestInit" mbdFilename="${MODULE_DIR}/BaseMemoryTest.mbd" msaFilename="${MODULE_DIR}/BaseMemoryTest.msa"/>

+   </target>

+   <target depends="PeiBaseMemoryTestInit_clean" name="clean"/>

+   <target depends="PeiBaseMemoryTestInit_cleanall" name="cleanall"/>

+   <target name="PeiBaseMemoryTestInit_clean">

+      <OutputDirSetup baseName="PeiBaseMemoryTestInit" mbdFilename="${MODULE_DIR}/BaseMemoryTest.mbd" msaFilename="${MODULE_DIR}/BaseMemoryTest.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiBaseMemoryTestInit_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiBaseMemoryTestInit_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiBaseMemoryTestInit_cleanall">

+      <OutputDirSetup baseName="PeiBaseMemoryTestInit" mbdFilename="${MODULE_DIR}/BaseMemoryTest.mbd" msaFilename="${MODULE_DIR}/BaseMemoryTest.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiBaseMemoryTestInit_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiBaseMemoryTestInit_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiBaseMemoryTestInit*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.c b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.c
new file mode 100644
index 0000000..6e4350f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.c
@@ -0,0 +1,266 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MonotonicCounter.c

+

+Abstract:

+

+  Produced the Monotonic Counter Services as defined in the DXE CIS

+

+Revision History:

+

+--*/

+

+#include "MonotonicCounter.h"

+

+//

+// The Monotonic Counter Handle

+//

+EFI_HANDLE  mMonotonicCounterHandle = NULL;

+

+//

+// The current Monotonic count value

+//

+UINT64      mEfiMtc;

+

+

+//

+// Event to use to update the Mtc's high part when wrapping

+//

+EFI_EVENT   mEfiMtcEvent;

+

+//

+// EfiMtcName - Variable name of the MTC value

+//

+CHAR16      *mEfiMtcName = (CHAR16 *) L"MTC";

+

+//

+// EfiMtcGuid - Guid of the MTC value

+//

+EFI_GUID    mEfiMtcGuid = { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } };

+

+//

+// Worker functions

+//

+EFI_STATUS

+EFIAPI

+MonotonicCounterDriverGetNextMonotonicCount (

+  OUT UINT64  *Count

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_TPL OldTpl;

+

+  //

+  // Can not be called after ExitBootServices()

+  //

+  if (EfiAtRuntime ()) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Check input parameters

+  //

+  if (Count == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Update the monotonic counter with a lock

+  //

+  OldTpl  = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+  *Count  = mEfiMtc;

+  mEfiMtc++;

+  gBS->RestoreTPL (OldTpl);

+

+  //

+  // If the MSB bit of the low part toggled, then signal that the high

+  // part needs updated now

+  //

+  if ((((UINT32) mEfiMtc) ^ ((UINT32) *Count)) & 0x80000000) {

+    gBS->SignalEvent (mEfiMtcEvent);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+MonotonicCounterDriverGetNextHighMonotonicCount (

+  OUT UINT32  *HighCount

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+  EFI_TPL     OldTpl;

+

+  //

+  // Check input parameters

+  //

+  if (HighCount == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!EfiAtRuntime ()) {

+    //

+    // Use a lock if called before ExitBootServices()

+    //

+    OldTpl      = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+    *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;

+    mEfiMtc     = LShiftU64 (*HighCount, 32);

+    gBS->RestoreTPL (OldTpl);

+  } else {

+    *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;

+    mEfiMtc     = LShiftU64 (*HighCount, 32);

+  }

+  //

+  // Update the NvRam store to match the new high part

+  //

+  Status = gRT->SetVariable (

+                  mEfiMtcName,

+                  &mEfiMtcGuid,

+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,

+                  sizeof (UINT32),

+                  HighCount

+                  );

+

+  return Status;

+}

+

+VOID

+EFIAPI

+EfiMtcEventHandler (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  )

+/*++

+

+Routine Description:

+

+  Monotonic count event handler.  This handler updates the high monotonic count.

+

+Arguments:

+

+  Event         The event to handle

+  Context       The event context

+

+Returns:

+

+  EFI_SUCCESS       The event has been handled properly 

+  EFI_NOT_FOUND     An error occurred updating the variable.

+

+--*/

+{

+  UINT32  HighCount;

+

+  MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount);

+}

+

+EFI_STATUS

+EFIAPI

+MonotonicCounterDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT32      HighCount;

+  UINTN       BufferSize;

+

+  //

+  // Make sure the Monotonic Counter Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMonotonicCounterArchProtocolGuid);

+

+  //

+  // Initialize event to handle overflows

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  EfiMtcEventHandler,

+                  NULL,

+                  &mEfiMtcEvent

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Read the last high part

+  //

+  BufferSize = sizeof (UINT32);

+  Status = gRT->GetVariable (

+                  mEfiMtcName,

+                  &mEfiMtcGuid,

+                  NULL,

+                  &BufferSize,

+                  &HighCount

+                  );

+  if (EFI_ERROR (Status)) {

+    HighCount = 0;

+  }

+  //

+  // Set the current value

+  //

+  mEfiMtc = LShiftU64 (HighCount, 32);

+

+  //

+  // Increment the upper 32 bits for this boot

+  // Continue even if it fails.  It will only fail if the variable services are

+  // not functional.

+  //

+  Status = MonotonicCounterDriverGetNextHighMonotonicCount (&HighCount);

+

+  //

+  // Fill in the EFI Boot Services and EFI Runtime Services Monotonic Counter Fields

+  //

+  gBS->GetNextMonotonicCount      = MonotonicCounterDriverGetNextMonotonicCount;

+  gRT->GetNextHighMonotonicCount  = MonotonicCounterDriverGetNextHighMonotonicCount;

+

+  //

+  // Install the Monotonic Counter Architctural Protocol onto a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mMonotonicCounterHandle,

+                  &gEfiMonotonicCounterArchProtocolGuid,

+                  NULL,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.dxs b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.dxs
new file mode 100644
index 0000000..d32e028
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MonotonicCounter.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_VARIABLE_ARCH_PROTOCOL_GUID AND

+  EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.h b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.h
new file mode 100644
index 0000000..c86b15d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.h
@@ -0,0 +1,36 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MonotonicCounter.h

+

+Abstract:

+

+  Produces the Monotonic Counter services as defined in the DXE CIS

+

+--*/

+

+#ifndef _MONOTONIC_COUNTER_DRIVER_H_

+#define _MONOTONIC_COUNTER_DRIVER_H_

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+MonotonicCounterDriverInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.mbd b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.mbd
new file mode 100644
index 0000000..6a5fa71
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.mbd
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>MonotonicCounter</BaseName>

+    <Guid>AD608272-D07F-4964-801E-7BD3B7888652</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-22 14:36</Created>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Arch ArchType="IPF">

+      <Library>EdkDxeSalLib</Library>

+    </Arch>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.msa b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.msa
new file mode 100644
index 0000000..4290091
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/MonotonicCounter.msa
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>MonotonicCounter</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>AD608272-D07F-4964-801E-7BD3B7888652</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-22 14:36</Created>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MonotonicCounter.c</Filename>

+    <Filename>MonotonicCounter.h</Filename>

+    <Filename>MonotonicCounter.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">MonotonicCounter</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable Usage="PRIVATE">

+      <String>MTC</String>

+      <Guid>0xeb704011, 0x1402, 0x11d3, 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Variable>

+  </Variables>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>MonotonicCounterDriverInitialize</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <SetVirtualAddressMapCallBack></SetVirtualAddressMapCallBack>

+      <ExitBootServicesCallBack></ExitBootServicesCallBack>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/build.xml b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/build.xml
new file mode 100644
index 0000000..88115e4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/MonotonicCounter/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="MonotonicCounter"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/MonotonicCounter/RuntimeDxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="MonotonicCounter">

+      <GenBuild baseName="MonotonicCounter" mbdFilename="${MODULE_DIR}/MonotonicCounter.mbd" msaFilename="${MODULE_DIR}/MonotonicCounter.msa"/>

+   </target>

+   <target depends="MonotonicCounter_clean" name="clean"/>

+   <target depends="MonotonicCounter_cleanall" name="cleanall"/>

+   <target name="MonotonicCounter_clean">

+      <OutputDirSetup baseName="MonotonicCounter" mbdFilename="${MODULE_DIR}/MonotonicCounter.mbd" msaFilename="${MODULE_DIR}/MonotonicCounter.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/MonotonicCounter_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/MonotonicCounter_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="MonotonicCounter_cleanall">

+      <OutputDirSetup baseName="MonotonicCounter" mbdFilename="${MODULE_DIR}/MonotonicCounter.mbd" msaFilename="${MODULE_DIR}/MonotonicCounter.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/MonotonicCounter_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/MonotonicCounter_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**MonotonicCounter*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.mbd b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.mbd
new file mode 100644
index 0000000..2262fc6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>BC</BaseName>

+    <Guid>A3f436EA-A127-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.msa b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.msa
new file mode 100644
index 0000000..ec4a426
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.msa
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>BC</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>A3f436EA-A127-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>bc.c</Filename>

+    <Filename>pxe_bc_arp.c</Filename>

+    <Filename>pxe_bc_dhcp.c</Filename>

+    <Filename>pxe_bc_igmp.c</Filename>

+    <Filename>pxe_bc_ip.c</Filename>

+    <Filename>pxe_bc_mtftp.c</Filename>

+    <Filename>pxe_bc_udp.c</Filename>

+    <Filename>pxe_loadfile.c</Filename>

+    <Filename>dhcp.h</Filename>

+    <Filename>bc.h</Filename>

+    <Filename>ip.h</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>Print.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">Bis</Protocol>    

+    <Protocol Usage="BY_START">LoadFile</Protocol>

+    <Protocol Usage="SOMETIMES_PRODUCED">PxeBaseCodeCallBack</Protocol>

+    <Protocol Usage="TO_START">SimpleNetwork</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier2</Protocol>

+    <Protocol Usage="BY_START">PxeBaseCode</Protocol>

+  </Protocols>

+  <SystemTables>

+    <SystemTable Usage="SOMETIMES_CONSUMED">

+      <Entry>gEfiSmbiosTableGuid</Entry>

+    </SystemTable>

+  </SystemTables>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>SmbiosTable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeBCDriver</ModuleEntryPoint>

+      <ModuleUnloadImage></ModuleUnloadImage>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPxeBcDriverBinding</DriverBinding>

+      <ComponentName>gPxeBcComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/Bc.h b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/Bc.h
new file mode 100644
index 0000000..a391709
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/Bc.h
@@ -0,0 +1,499 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  bc.h

+

+Abstract:

+

+--*/

+

+#ifndef _BC_H

+#define _BC_H

+

+#ifndef EFI_MIN

+#define EFI_MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))

+#endif

+

+#define CALLBACK_INTERVAL             100 // ten times a second

+#define FILTER_BITS                   (EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP | \

+                     EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST | \

+                     EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS | \

+                     EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST \

+          )

+

+#define WAIT_TX_TIMEOUT               1000

+

+#define SUPPORT_IPV6                  0

+

+#define PXE_BASECODE_DEVICE_SIGNATURE EFI_SIGNATURE_32('p','x','e','d')

+

+//

+// Determine the classes of IPv4 address

+//

+#define  IS_CLASSA_IPADDR(x)  ((((EFI_IP_ADDRESS*)x)->v4.Addr[0] & 0x80) == 0x00) 

+#define  IS_CLASSB_IPADDR(x)  ((((EFI_IP_ADDRESS*)x)->v4.Addr[0] & 0xc0) == 0x80) 

+#define  IS_CLASSC_IPADDR(x)  ((((EFI_IP_ADDRESS*)x)->v4.Addr[0] & 0xe0) == 0xc0) 

+#define  IS_INADDR_UNICAST(x) ((IS_CLASSA_IPADDR(x) || IS_CLASSB_IPADDR(x) || IS_CLASSC_IPADDR(x)) && (((EFI_IP_ADDRESS*)x)->Addr[0] != 0) )

+

+//

+// Definitions for internet group management protocol version 2 message

+// structure

+// Per RFC 2236, November 1997

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8   Type;

+  UINT8   MaxRespTime;  // in tenths of a second

+  UINT16  Checksum;     // ones complement of ones complement sum of

+                        // 16 bit words of message

+  UINT32  GroupAddress; // for general query, all systems group,

+                        // for group specific, the group

+} IGMPV2_MESSAGE;

+

+#define IGMP_TYPE_QUERY                 0x11

+#define IGMP_TYPE_REPORT                0x16

+#define IGMP_TYPE_V1REPORT              0x12

+#define IGMP_TYPE_LEAVE_GROUP           0x17

+

+#define IGMP_DEFAULT_MAX_RESPONSE_TIME  10  // 10 second default

+#pragma pack()

+

+#define MAX_MCAST_GROUPS  8                 // most we allow ourselves to join at once

+#define MAX_OFFERS        16

+

+typedef struct {

+  UINTN                                     Signature;

+  EFI_LOCK                                  Lock;

+  BOOLEAN                                   ShowErrorMessages;

+  EFI_PXE_BASE_CODE_PROTOCOL                EfiBc;

+  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL       *CallbackProtocolPtr;

+  EFI_HANDLE                                Handle;

+

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiPtr;

+  EFI_SIMPLE_NETWORK_PROTOCOL               *SimpleNetwork;

+  UINT8                                     *TransmitBufferPtr;

+  UINT8                                     *ReceiveBufferPtr;

+  EFI_PXE_BASE_CODE_FUNCTION                Function;

+

+  UINTN                                     OldestArpEntry;

+  UINTN                                     MCastGroupCount;

+  EFI_EVENT                                 Igmpv1TimeoutEvent;

+  BOOLEAN                                   UseIgmpv1Reporting;

+  EFI_EVENT                                 IgmpGroupEvent[MAX_MCAST_GROUPS];

+  UINT16                                    RandomPort;

+

+#if SUPPORT_IPV6

+  //

+  // TBD

+  //

+#else

+  UINT32          MCastGroup[MAX_MCAST_GROUPS];

+#endif

+

+  BOOLEAN         GoodStationIp;

+  BOOLEAN         DidTransmit;

+  UINTN           IpLength;

+  VOID            *DhcpPacketBuffer;

+  UINTN           FileSize;

+  VOID            *BootServerReceiveBuffer;

+  EFI_IP_ADDRESS  ServerIp;

+

+  //

+  // work area

+  // for dhcp

+  //

+  VOID            *ReceiveBuffers;

+  VOID            *TransmitBuffer;

+  UINTN           NumOffersReceived;

+  UINT16          TotalSeconds;

+

+  //

+  // arrays for different types of offers

+  //

+  UINT8           ServerCount[4];

+  UINT8           OfferCount[4][MAX_OFFERS];

+  UINT8           GotBootp;

+  UINT8           GotProxy[4];

+  UINT8           BinlProxies[MAX_OFFERS];

+

+  UINT8           *ArpBuffer;

+  UINT8           *TftpAckBuffer;

+  UINT8           *TftpErrorBuffer;

+  IGMPV2_MESSAGE  IgmpMessage;

+  BOOLEAN         BigBlkNumFlag;

+  UINT8           Timeout;

+  UINT16          RandomSeed;

+} PXE_BASECODE_DEVICE;

+

+//

+// type index

+//

+#define DHCP_ONLY_IX      0

+#define PXE10_IX          1

+#define WfM11a_IX         2

+#define BINL_IX           3

+

+#define PXE_RND_PORT_LOW  2070

+

+#define PXE_MAX_PRINT_BUFFER 128

+

+//

+//

+//

+#define LOADFILE_DEVICE_SIGNATURE EFI_SIGNATURE_32('p','x','e','l')

+

+typedef struct {

+  UINTN                   Signature;

+  EFI_LOCK                Lock;

+  EFI_LOAD_FILE_PROTOCOL  LoadFile;

+  PXE_BASECODE_DEVICE     *Private;

+} LOADFILE_DEVICE;

+

+#define EFI_BASE_CODE_DEV_FROM_THIS(a)  CR (a, PXE_BASECODE_DEVICE, efi_bc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+#define EFI_LOAD_FILE_DEV_FROM_THIS(a)  CR (a, LOADFILE_DEVICE, LoadFile, LOADFILE_DEVICE_SIGNATURE)

+

+EFI_BIS_PROTOCOL                    *

+PxebcBisStart (

+  PXE_BASECODE_DEVICE     *Private,

+  BIS_APPLICATION_HANDLE  *BisAppHandle,

+  EFI_BIS_DATA            **BisDataSigInfo

+  )

+;

+

+VOID

+PxebcBisStop (

+  EFI_BIS_PROTOCOL        *Bis,

+  BIS_APPLICATION_HANDLE  BisAppHandle,

+  EFI_BIS_DATA            *BisDataSigInfo

+  )

+;

+

+BOOLEAN

+PxebcBisVerify (

+  PXE_BASECODE_DEVICE     *Private,

+  VOID                    *FileBuffer,

+  UINTN                   FileBufferLength,

+  VOID                    *CredentialBuffer,

+  UINTN                   CredentialBufferLength

+  )

+;

+

+BOOLEAN

+PxebcBisDetect (

+  PXE_BASECODE_DEVICE *Private

+  )

+;

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gPxeBcDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gPxeBcComponentName;

+

+//

+// //////////////////////////////////////////////////////////

+//

+// prototypes

+//

+EFI_STATUS

+EFIAPI

+InitializeBCDriver (

+  IN EFI_HANDLE                       ImageHandle,

+  IN EFI_SYSTEM_TABLE                 *SystemTable

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcStart (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,

+  IN BOOLEAN                          UseIpv6

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcStop (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       *This

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcDhcp (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,

+  IN BOOLEAN                          SortOffers

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcDiscover (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN UINT16                           Type,

+  IN UINT16                           *Layer,

+  IN BOOLEAN                          UseBis,

+  IN EFI_PXE_BASE_CODE_DISCOVER_INFO  * Info OPTIONAL

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcMtftp (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN EFI_PXE_BASE_CODE_TFTP_OPCODE    Operation,

+  IN OUT VOID                         *BufferPtr,

+  IN BOOLEAN                          Overwrite,

+  IN OUT UINT64                       *BufferSize,

+  IN UINTN                            *BlockSize OPTIONAL,

+  IN EFI_IP_ADDRESS                   * ServerIp,

+  IN UINT8                            *Filename,

+  IN EFI_PXE_BASE_CODE_MTFTP_INFO     * Info OPTIONAL,

+  IN BOOLEAN                          DontUseBuffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcUdpWrite (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,

+  IN UINT16                           OpFlags,

+  IN EFI_IP_ADDRESS                   *DestIp,

+  IN EFI_PXE_BASE_CODE_UDP_PORT       *DestPort,

+  IN EFI_IP_ADDRESS                   *GatewayIp, OPTIONAL

+  IN EFI_IP_ADDRESS                   *SrcIp, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *SrcPort, OPTIONAL

+  IN UINTN                            *HeaderSize, OPTIONAL

+  IN VOID                             *HeaderPtr, OPTIONAL

+  IN UINTN                            *BufferSize,

+  IN VOID                             *BufferPtr

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcUdpRead (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,

+  IN UINT16                           OpFlags,

+  IN OUT EFI_IP_ADDRESS               *DestIp, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *DestPort, OPTIONAL

+  IN OUT EFI_IP_ADDRESS               *SrcIp, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *SrcPort, OPTIONAL

+  IN UINTN                            *HeaderSize, OPTIONAL

+  IN VOID                             *HeaderPtr, OPTIONAL

+  IN OUT UINTN                        *BufferSize,

+  IN VOID                             *BufferPtr

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcArp (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN EFI_IP_ADDRESS                   * IpAddr,

+  IN EFI_MAC_ADDRESS                  * MacAddr OPTIONAL

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcIpFilter (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,

+  IN EFI_PXE_BASE_CODE_IP_FILTER      *NewFilter

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcSetParameters (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN BOOLEAN                          *NewAutoArp, OPTIONAL

+  IN BOOLEAN                          *NewSendGUID, OPTIONAL

+  IN UINT8                            *NewTTL, OPTIONAL

+  IN UINT8                            *NewToS, OPTIONAL

+  IN BOOLEAN                          *NewMakeCallback OPTIONAL

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcSetStationIP (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN EFI_IP_ADDRESS                   * NewStationIp, OPTIONAL

+  IN EFI_IP_ADDRESS                   * NewSubnetMask OPTIONAL

+  )

+;

+

+EFI_STATUS

+EFIAPI

+BcSetPackets (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  BOOLEAN                             *NewDhcpDiscoverValid, OPTIONAL

+  BOOLEAN                             *NewDhcpAckReceived, OPTIONAL

+  BOOLEAN                             *NewProxyOfferReceived, OPTIONAL

+  BOOLEAN                             *NewPxeDiscoverValid, OPTIONAL

+  BOOLEAN                             *NewPxeReplyReceived, OPTIONAL

+  BOOLEAN                             *NewPxeBisReplyReceived, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET         * NewDhcpDiscover, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET         * NewDhcpAck, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET         * NewProxyOffer, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET         * NewPxeDiscover, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET         * NewPxeReply, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET         * NewPxeBisReply OPTIONAL

+  )

+;

+

+EFI_STATUS

+EFIAPI

+LoadFile (

+  IN EFI_LOAD_FILE_PROTOCOL           *This,

+  IN EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN BOOLEAN                          BootPolicy,

+  IN OUT UINTN                        *BufferSize,

+  IN VOID                             *Buffer

+  )

+;

+

+EFI_STATUS

+PxeBcLibGetSmbiosSystemGuidAndSerialNumber (

+  IN  EFI_GUID    *SystemGuid,

+  OUT CHAR8       **SystemSerialNumber

+  )

+;

+

+UINTN

+EFIAPI

+AsciiPrint (

+  IN CONST CHAR8 *Format,

+  ...

+  )

+;

+

+//

+// Define SMBIOS tables.

+//

+#pragma pack(1)

+typedef struct {

+  UINT8   AnchorString[4];

+  UINT8   EntryPointStructureChecksum;

+  UINT8   EntryPointLength;

+  UINT8   MajorVersion;

+  UINT8   MinorVersion;

+  UINT16  MaxStructureSize;

+  UINT8   EntryPointRevision;

+  UINT8   FormattedArea[5];

+  UINT8   IntermediateAnchorString[5];

+  UINT8   IntermediateChecksum;

+  UINT16  TableLength;

+  UINT32  TableAddress;

+  UINT16  NumberOfSmbiosStructures;

+  UINT8   SmbiosBcdRevision;

+} SMBIOS_STRUCTURE_TABLE;

+

+//

+// Please note that SMBIOS structures can be odd byte aligned since the

+//  unformated section of each record is a set of arbitrary size strings.

+//

+typedef struct {

+  UINT8 Type;

+  UINT8 Length;

+  UINT8 Handle[2];

+} SMBIOS_HEADER;

+

+typedef UINT8 SMBIOS_STRING;

+

+typedef struct {

+  SMBIOS_HEADER Hdr;

+  SMBIOS_STRING Vendor;

+  SMBIOS_STRING BiosVersion;

+  UINT8         BiosSegment[2];

+  SMBIOS_STRING BiosReleaseDate;

+  UINT8         BiosSize;

+  UINT8         BiosCharacteristics[8];

+} SMBIOS_TYPE0;

+

+typedef struct {

+  SMBIOS_HEADER Hdr;

+  SMBIOS_STRING Manufacturer;

+  SMBIOS_STRING ProductName;

+  SMBIOS_STRING Version;

+  SMBIOS_STRING SerialNumber;

+

+  //

+  // always byte copy this data to prevent alignment faults!

+  //

+  EFI_GUID      Uuid;

+

+  UINT8         WakeUpType;

+} SMBIOS_TYPE1;

+

+typedef struct {

+  SMBIOS_HEADER Hdr;

+  SMBIOS_STRING Manufacturer;

+  SMBIOS_STRING ProductName;

+  SMBIOS_STRING Version;

+  SMBIOS_STRING SerialNumber;

+} SMBIOS_TYPE2;

+

+typedef struct {

+  SMBIOS_HEADER Hdr;

+  SMBIOS_STRING Manufacturer;

+  UINT8         Type;

+  SMBIOS_STRING Version;

+  SMBIOS_STRING SerialNumber;

+  SMBIOS_STRING AssetTag;

+  UINT8         BootupState;

+  UINT8         PowerSupplyState;

+  UINT8         ThermalState;

+  UINT8         SecurityStatus;

+  UINT8         OemDefined[4];

+} SMBIOS_TYPE3;

+

+typedef struct {

+  SMBIOS_HEADER Hdr;

+  UINT8         Socket;

+  UINT8         ProcessorType;

+  UINT8         ProcessorFamily;

+  SMBIOS_STRING ProcessorManufacture;

+  UINT8         ProcessorId[8];

+  SMBIOS_STRING ProcessorVersion;

+  UINT8         Voltage;

+  UINT8         ExternalClock[2];

+  UINT8         MaxSpeed[2];

+  UINT8         CurrentSpeed[2];

+  UINT8         Status;

+  UINT8         ProcessorUpgrade;

+  UINT8         L1CacheHandle[2];

+  UINT8         L2CacheHandle[2];

+  UINT8         L3CacheHandle[2];

+} SMBIOS_TYPE4;

+

+typedef union {

+  SMBIOS_HEADER *Hdr;

+  SMBIOS_TYPE0  *Type0;

+  SMBIOS_TYPE1  *Type1;

+  SMBIOS_TYPE2  *Type2;

+  SMBIOS_TYPE3  *Type3;

+  SMBIOS_TYPE4  *Type4;

+  UINT8         *Raw;

+} SMBIOS_STRUCTURE_POINTER;

+#pragma pack()

+

+#include "ip.h"

+#include "dhcp.h"

+#include "tftp.h"

+

+#endif /* _BC_H */

+

+/* EOF - bc.h */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/ComponentName.c
new file mode 100644
index 0000000..2c11dc4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/ComponentName.c
@@ -0,0 +1,160 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+

+#include "Bc.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+PxeBcComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+PxeBcComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gPxeBcComponentName = {

+  PxeBcComponentNameGetDriverName,

+  PxeBcComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"PXE Base Code Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+PxeBcComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gPxeBcComponentName.SupportedLanguages,

+          mPxeBcDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+PxeBcComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/Print.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/Print.c
new file mode 100644
index 0000000..4ea5cba
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/Print.c
@@ -0,0 +1,81 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+        Print.c

+

+Abstract:

+

+--*/

+

+

+#include <Bc.h>

+

+UINTN

+EFIAPI

+AsciiPrint (

+  IN CONST CHAR8 *Format,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Print function for a maximum of PXE_MAX_PRINT_BUFFER ascii 

+  characters.

+

+Arguments:

+

+  Format - Ascii format string see file header for more details.

+

+  ...    - Vararg list consumed by processing Format.

+

+Returns: 

+

+  Number of characters printed.

+

+--*/

+{

+  UINTN   Return;

+  VA_LIST Marker;

+  UINTN   Index;

+  UINTN   MaxIndex;

+  CHAR16  Buffer[PXE_MAX_PRINT_BUFFER];

+  CHAR16  UnicodeFormat[PXE_MAX_PRINT_BUFFER];

+

+  MaxIndex = AsciiStrLen ((CHAR8 *) Format);

+  if (MaxIndex > PXE_MAX_PRINT_BUFFER) {

+    //

+    // Format string was too long for use to process.

+    //

+    return 0;

+  }

+

+  for (Index = 0; Index < PXE_MAX_PRINT_BUFFER; Index++) {

+    UnicodeFormat[Index] = (CHAR16) Format[Index];

+  }

+

+  VA_START (Marker, Format);

+  Return = UnicodeVSPrint (Buffer, sizeof (Buffer), UnicodeFormat, Marker);

+  VA_END (Marker);

+

+  //

+  // Need to convert to Unicode to do an OutputString

+  //

+

+  if (gST->ConOut != NULL) {

+    //

+    // To be extra safe make sure ConOut has been initialized

+    //

+    gST->ConOut->OutputString (gST->ConOut, Buffer);

+  }

+

+  return Return;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c
new file mode 100644
index 0000000..c42cc9c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c
@@ -0,0 +1,2510 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+        bc.c

+

+Abstract:

+

+--*/

+

+#include "Bc.h"

+

+//

+//

+//

+EFI_STATUS

+EFIAPI

+PxeBcDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PxeBcDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PxeBcDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+extern

+VOID

+InitArpHeader (

+  VOID

+  );

+extern

+VOID

+OptionsStrucInit (

+  VOID

+  );

+

+//

+// helper routines

+//

+VOID

+CvtNum (

+  IN UINTN  Number,

+  IN UINT8  *Buffer,

+  IN INTN   Length

+  )

+/*++

+

+  Routine Description:

+    Convert number to ASCII value

+

+  Arguments:

+    Number              - Numeric value to convert to decimal ASCII value.

+    Buffer              - Buffer to place ASCII version of the Number

+    Length              - Length of Buffer.

+

+  Returns:

+    none                - none

+

+--*/

+{

+  UINTN Remainder;

+

+  while (Length--) {

+    Remainder = Number % 10;

+    Number /= 10;

+    Buffer[Length] = (UINT8) ('0' + Remainder);

+  }

+}

+

+VOID

+UtoA10 (

+  IN UINTN Number,

+  IN UINT8 *Buffer

+  )

+/*++

+

+  Routine Description:

+    Convert number to decimal ASCII value at Buffer location

+

+  Arguments:

+    Number              - Numeric value to convert to decimal ASCII value.

+    Buffer              - Buffer to place ASCII version of the Number

+

+  Returns:

+    none                - none

+

+--*/

+{

+  INTN  Index;

+  UINT8 BuffArray[31];

+

+  BuffArray[30] = 0;

+  CvtNum (Number, BuffArray, 30);

+

+  for (Index = 0; Index < 30; ++Index) {

+    if (BuffArray[Index] != '0') {

+      break;

+    }

+  }

+

+  CopyMem (Buffer, BuffArray + Index, 31 - Index);

+}

+

+UINTN

+AtoU (

+  IN UINT8 *Buffer

+  )

+/*++

+

+  Routine Description:

+    Convert ASCII numeric string to a UINTN value

+

+  Arguments:

+    Number              - Numeric value to convert to decimal ASCII value.

+    Buffer              - Buffer to place ASCII version of the Number

+

+  Returns:

+    Value                - UINTN value of the ASCII string.

+

+--*/

+{

+  UINTN Value;

+  INT8  Character;

+

+  Value     = 0;

+  Character = *Buffer++;

+  do {

+    Value     = Value * 10 + Character - '0';

+    Character = *Buffer++;

+  } while (Character);

+

+  return Value;

+}

+

+UINT64

+AtoU64 (

+  IN UINT8 *Buffer

+  )

+/*++

+

+  Routine Description:

+    Convert ASCII numeric string to a UINTN value

+

+  Arguments:

+    Number              - Numeric value to convert to decimal ASCII value.

+    Buffer              - Buffer to place ASCII version of the Number

+

+  Returns:

+    Value                - UINTN value of the ASCII string.

+

+--*/

+{

+  UINT64  Value;

+  UINT8   Character;

+

+  Value = 0;

+  while ((Character = *Buffer++) != '\0') {

+    Value = MultU64x32 (Value, 10) + (Character - '0');

+  }

+

+  return Value;

+}

+//

+// random number generator

+//

+#define RANDOM_MULTIPLIER   2053

+#define RANDOM_ADD_IN_VALUE 19

+

+VOID

+SeedRandom (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN UINT16               InitialSeed

+  )

+/*++

+

+  Routine Description:

+    Initialize the Seed for the random number generator

+

+  Arguments:

+

+  Returns:

+    none                - 

+

+--*/

+{

+  if (Private != NULL) {

+    Private->RandomSeed = InitialSeed;

+  }

+}

+

+UINT16

+Random (

+  IN PXE_BASECODE_DEVICE  *Private

+  )

+/*++

+

+  Routine Description:

+    Generate and return a pseudo-random number

+

+  Arguments:

+

+  Returns:

+    Number           - UINT16 random number

+

+--*/

+{

+  UINTN Number;

+

+  if (Private != NULL) {

+    Number = -(INTN) Private->RandomSeed * RANDOM_MULTIPLIER + RANDOM_ADD_IN_VALUE;

+

+    return Private->RandomSeed = (UINT16) Number;

+  } else {

+    return 0;

+  }

+}

+//

+// calculate the internet checksum (RFC 1071)

+// return 16 bit ones complement of ones complement sum of 16 bit words

+//

+UINT16

+IpChecksum (

+  IN UINT16 *Packet,

+  IN UINTN  Length

+  )

+/*++

+

+  Routine Description:

+    Calculate the internet checksum (see RFC 1071)

+

+  Arguments:

+    Packet             - Buffer which contains the data to be checksummed

+    Length             - Length to be checksummed

+

+  Returns:

+    Checksum           - Returns the 16 bit ones complement of 

+                         ones complement sum of 16 bit words

+

+--*/

+{

+  UINT32  Sum;

+  UINT8   Odd;

+

+  Sum = 0;

+  Odd = (UINT8) (Length & 1);

+  Length >>= 1;

+  while (Length--) {

+    Sum += *Packet++;

+  }

+

+  if (Odd) {

+    Sum += *(UINT8 *) Packet;

+  }

+

+  Sum = (Sum & 0xffff) + (Sum >> 16);

+  //

+  // in case above carried

+  //

+  Sum += Sum >> 16;

+

+  return (UINT16) (~ (UINT16) Sum);

+}

+

+UINT16

+IpChecksum2 (

+  IN UINT16 *Header,

+  IN UINTN  HeaderLen,

+  IN UINT16 *Message,

+  IN UINTN  MessageLen

+  )

+/*++

+

+  Routine Description:

+    Calculate the internet checksum (see RFC 1071)

+    on a non contiguous header and data

+

+  Arguments:

+    Header        - Buffer which contains the data to be checksummed

+    HeaderLen     - Length to be checksummed

+    Message       - Buffer which contains the data to be checksummed

+    MessageLen    - Length to be checksummed

+

+  Returns:

+    Checksum      - Returns the 16 bit ones complement of 

+                    ones complement sum of 16 bit words

+

+--*/

+{

+  UINT32  Sum;

+

+  Sum = (UINT16)~IpChecksum (Header, HeaderLen) + (UINT16)~IpChecksum (Message, MessageLen);

+

+  //

+  // in case above carried

+  //

+  Sum += Sum >> 16;

+

+  return (UINT16) (~ (UINT16) Sum);

+}

+

+UINT16

+UpdateChecksum (

+  IN UINT16 OldChksum,

+  IN UINT16 OldWord,

+  IN UINT16 NewWord

+  )

+/*++

+

+  Routine Description:

+    Adjust the internet checksum (see RFC 1071) on a single word update.

+

+  Arguments:

+    OldChkSum          - Checksum previously calculated

+    OldWord            - Value

+    NewWord            - New Value

+

+  Returns:

+    Checksum           - Returns the 16 bit ones complement of 

+                         ones complement sum of 16 bit words

+

+--*/

+{

+  UINT32  sum;

+

+  sum = ~OldChksum + NewWord - OldWord;

+  //

+  // in case above carried

+  //

+  sum += sum >> 16;

+  return (UINT16) (~ (UINT16) sum);

+}

+

+STATIC

+BOOLEAN

+SetMakeCallback (

+  IN PXE_BASECODE_DEVICE *Private

+  )

+/*++

+

+  Routine Description:

+    See if a callback is in play

+

+  Arguments:

+    Private                - Pointer to Pxe BaseCode Protocol

+

+  Returns:

+    0                  - Callbacks are active on the handle

+    1                  - Callbacks are not active on the handle                         

+

+--*/

+{

+  Private->EfiBc.Mode->MakeCallbacks = (BOOLEAN) (gBS->HandleProtocol (

+                                                        Private->Handle,

+                                                        &gEfiPxeBaseCodeCallbackProtocolGuid,

+                                                        (VOID *) &Private->CallbackProtocolPtr

+                                                        ) == EFI_SUCCESS);

+

+  DEBUG (

+    (EFI_D_INFO,

+    "\nMode->MakeCallbacks == %d  ",

+    Private->EfiBc.Mode->MakeCallbacks)

+    );

+

+  DEBUG (

+    (EFI_D_INFO,

+    "\nPrivate->CallbackProtocolPtr == %xh  ",

+    Private->CallbackProtocolPtr)

+    );

+

+  if (Private->CallbackProtocolPtr != NULL) {

+    DEBUG (

+      (EFI_D_INFO,

+      "\nCallbackProtocolPtr->Revision = %xh  ",

+      Private->CallbackProtocolPtr->Revision)

+      );

+

+    DEBUG (

+      (EFI_D_INFO,

+      "\nCallbackProtocolPtr->Callback = %xh  ",

+      Private->CallbackProtocolPtr->Callback)

+      );

+  }

+

+  return Private->EfiBc.Mode->MakeCallbacks;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+WaitForReceive (

+  IN PXE_BASECODE_DEVICE        *Private,

+  IN EFI_PXE_BASE_CODE_FUNCTION Function,

+  IN EFI_EVENT                  TimeoutEvent,

+  IN OUT UINTN                  *HeaderSizePtr,

+  IN OUT UINTN                  *BufferSizePtr,

+  IN OUT UINT16                 *ProtocolPtr

+  )

+/*++

+

+  Routine Description:

+    Routine which does an SNP->Receive over a timeout period and doing callbacks

+

+  Arguments:

+    Private       - Pointer to Pxe BaseCode Protocol

+    Function      - What PXE function to callback

+    TimeoutEvent  - Timer event that will trigger when we have waited too 

+                    long for an incoming packet

+    HeaderSizePtr - Pointer to the size of the Header size

+    BufferSizePtr - Pointer to the size of the Buffer size

+    ProtocolPtr   - The protocol to sniff for (namely, UDP/etc)

+

+  Returns:

+    0             - Something was returned

+    !0            - Like there was nothing to receive (EFI_TIMEOUT/NOT_READY)

+

+--*/

+{

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

+  EFI_PXE_CALLBACK            CallbackPtr;

+  EFI_STATUS                  StatCode;

+  EFI_EVENT                   CallbackEvent;

+

+  //

+  // Initialize pointer to SNP interface

+  //

+  SnpPtr = Private->SimpleNetwork;

+

+  //

+  // Initialize pointer to PxeBc callback routine - if any

+  //

+  CallbackPtr = (Private->EfiBc.Mode->MakeCallbacks) ? Private->CallbackProtocolPtr->Callback : NULL;

+

+  //

+  // Create callback event and set timer

+  //

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &CallbackEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // every 100 milliseconds

+  //

+  StatCode = gBS->SetTimer (

+                    CallbackEvent,

+                    TimerPeriodic,

+                    1000000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    gBS->CloseEvent (CallbackEvent);

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Loop until a packet is received or a receive error is detected or

+  // a callback abort is detected or a timeout event occurs.

+  //

+  for (;;)

+  {

+#if 0

+    //

+    // Check for received packet event.

+    //

+    if (!EFI_ERROR (gBS->CheckEvent (SnpPtr->WaitForPacket))) {

+      //

+      // Packet should be available.  Attempt to read it.

+      //

+      *BufferSizePtr = BUFFER_ALLOCATE_SIZE;

+

+      StatCode = SnpPtr->Receive (

+                          SnpPtr,

+                          HeaderSizePtr,

+                          BufferSizePtr,

+                          Private->ReceiveBufferPtr,

+                          0,

+                          0,

+                          ProtocolPtr

+                          );

+

+      if (EFI_ERROR (StatCode)) {

+        break;

+      }

+      //

+      // Packet was received.  Make received callback then return.

+      //

+      if (CallbackPtr != NULL) {

+        StatCode = CallbackPtr (

+                    Private->CallbackProtocolPtr,

+                    Function,

+                    TRUE,

+                    (UINT32) *BufferSizePtr,

+                    (EFI_PXE_BASE_CODE_PACKET *) Private->ReceiveBufferPtr

+                    );

+

+        if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {

+          StatCode = EFI_ABORTED;

+        } else {

+          StatCode = EFI_SUCCESS;

+        }

+      }

+

+      break;

+    }

+

+#else

+    //

+    // Poll for received packet.

+    //

+    *BufferSizePtr = BUFFER_ALLOCATE_SIZE;

+

+    StatCode = SnpPtr->Receive (

+                        SnpPtr,

+                        HeaderSizePtr,

+                        BufferSizePtr,

+                        Private->ReceiveBufferPtr,

+                        0,

+                        0,

+                        ProtocolPtr

+                        );

+

+    if (!EFI_ERROR (StatCode)) {

+      //

+      // Packet was received.  Make received callback then return.

+      //

+      if (CallbackPtr != NULL) {

+        StatCode = CallbackPtr (

+                    Private->CallbackProtocolPtr,

+                    Function,

+                    TRUE,

+                    (UINT32) *BufferSizePtr,

+                    (EFI_PXE_BASE_CODE_PACKET *) Private->ReceiveBufferPtr

+                    );

+

+        if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {

+          StatCode = EFI_ABORTED;

+        } else {

+          StatCode = EFI_SUCCESS;

+        }

+      }

+

+      break;

+    }

+

+    if (StatCode != EFI_NOT_READY) {

+      break;

+    }

+#endif

+    //

+    // Check for callback event.

+    //

+    if (!EFI_ERROR (gBS->CheckEvent (CallbackEvent))) {

+      //

+      // Make periodic callback if callback pointer is initialized.

+      //

+      if (CallbackPtr != NULL) {

+        StatCode = CallbackPtr (

+                    Private->CallbackProtocolPtr,

+                    Function,

+                    FALSE,

+                    0,

+                    NULL

+                    );

+

+        //

+        // Abort if directed to by callback routine.

+        //

+        if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {

+          StatCode = EFI_ABORTED;

+          break;

+        }

+      }

+    }

+    //

+    // Check for timeout event.

+    //

+    if (TimeoutEvent == 0) {

+      StatCode = EFI_TIMEOUT;

+      break;

+    }

+

+    if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {

+      StatCode = EFI_TIMEOUT;

+      break;

+    }

+    //

+    // Check IGMP timer events.

+    //

+    IgmpCheckTimers (Private);

+  }

+

+  gBS->CloseEvent (CallbackEvent);

+

+  return StatCode;

+}

+

+EFI_STATUS

+SendPacket (

+  PXE_BASECODE_DEVICE           *Private,

+  VOID                          *HeaderPtr,

+  VOID                          *PacketPtr,

+  INTN                          PacketLen,

+  VOID                          *HardwareAddr,

+  UINT16                        MediaProtocol,

+  IN EFI_PXE_BASE_CODE_FUNCTION Function

+  )

+/*++

+

+  Routine Description:

+    Routine which does an SNP->Transmit of a buffer

+

+  Arguments:

+    Private       - Pointer to Pxe BaseCode Protocol

+    HeaderPtr          - Pointer to the buffer 

+    PacketPtr          - Pointer to the packet to send

+    PacketLen        - The length of the entire packet to send

+    HardwareAddr        - Pointer to the MAC address of the destination

+    MediaProtocol - What type of frame to create (RFC 1700) - IE. Ethernet

+    Function      - What PXE function to callback

+

+  Returns:

+    0             - Something was sent

+    !0            - An error was encountered during sending of a packet

+

+--*/

+{

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

+  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;

+  EFI_PXE_CALLBACK            CallbackPtr;

+  EFI_STATUS                  StatCode;

+  EFI_EVENT                   TimeoutEvent;

+  UINT32                      IntStatus;

+  VOID                        *TxBuf;

+

+  //

+  //

+  //

+  CallbackPtr = Private->EfiBc.Mode->MakeCallbacks ? Private->CallbackProtocolPtr->Callback : 0;

+

+  SnpPtr      = Private->SimpleNetwork;

+  SnpModePtr  = SnpPtr->Mode;

+

+  //

+  // clear prior interrupt status

+  //

+  StatCode = SnpPtr->GetStatus (SnpPtr, &IntStatus, 0);

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nSendPacket()  Exit #1  %xh (%r)",

+      StatCode,

+      StatCode)

+      );

+    return StatCode;

+  }

+

+  Private->DidTransmit = FALSE;

+

+  if (CallbackPtr != NULL) {

+    if (CallbackPtr (

+          Private->CallbackProtocolPtr,

+          Function,

+          FALSE,

+          (UINT32) PacketLen,

+          PacketPtr

+          ) != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nSendPacket()  Exit #2  %xh (%r)",

+        EFI_ABORTED,

+        EFI_ABORTED)

+        );

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // put packet in transmit queue

+  // headersize should be zero if not filled in

+  //

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &TimeoutEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "Could not create transmit timeout event.  %r\n",

+      StatCode)

+      );

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // 5 milliseconds

+  //

+  StatCode = gBS->SetTimer (

+                    TimeoutEvent,

+                    TimerRelative,

+                    50000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "Could not set transmit timeout event timer.  %r\n",

+      StatCode)

+      );

+    gBS->CloseEvent (TimeoutEvent);

+    return EFI_DEVICE_ERROR;

+  }

+

+  for (;;) {

+    StatCode = SnpPtr->Transmit (

+                        SnpPtr,

+                        (UINTN) SnpPtr->Mode->MediaHeaderSize,

+                        (UINTN) (PacketLen + SnpPtr->Mode->MediaHeaderSize),

+                        HeaderPtr,

+                        &SnpModePtr->CurrentAddress,

+                        (EFI_MAC_ADDRESS *) HardwareAddr,

+                        &MediaProtocol

+                        );

+

+    if (StatCode != EFI_NOT_READY) {

+      break;

+    }

+

+    if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {

+      StatCode = EFI_TIMEOUT;

+      break;

+    }

+  }

+

+  gBS->CloseEvent (TimeoutEvent);

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nSendPacket()  Exit #3  %xh (%r)",

+      StatCode,

+      StatCode)

+      );

+    return StatCode;

+  }

+  //

+  // remove transmit buffer from snp's unused queue

+  // done this way in case someday things are buffered and we don't get it back

+  // immediately

+  //

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &TimeoutEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "Could not create transmit status timeout event.  %r\n",

+      StatCode)

+      );

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // 5 milliseconds

+  //

+  StatCode = gBS->SetTimer (

+                    TimeoutEvent,

+                    TimerRelative,

+                    50000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "Could not set transmit status timeout event timer.  %r\n",

+      StatCode)

+      );

+    gBS->CloseEvent (TimeoutEvent);

+    return EFI_DEVICE_ERROR;

+  }

+

+  for (;;) {

+    StatCode = SnpPtr->GetStatus (SnpPtr, &IntStatus, &TxBuf);

+

+    if (EFI_ERROR (StatCode)) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nSendPacket()  Exit #4  %xh (%r)",

+        StatCode,

+        StatCode)

+        );

+      break;

+    }

+

+    if (IntStatus & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT) {

+      Private->DidTransmit = TRUE;

+    }

+

+    if (TxBuf != NULL) {

+      break;

+    }

+

+    if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {

+      StatCode = EFI_TIMEOUT;

+      break;

+    }

+  }

+

+  gBS->CloseEvent (TimeoutEvent);

+

+  return StatCode;

+}

+//

+//

+//

+EFI_BIS_PROTOCOL *

+PxebcBisStart (

+  IN PXE_BASECODE_DEVICE      *Private,

+  OUT BIS_APPLICATION_HANDLE  *BisAppHandle,

+  OUT OPTIONAL EFI_BIS_DATA            **BisDataSigInfo

+  )

+/*++

+Routine description:

+  Locate BIS interface and if found, try to start it.

+

+Parameters:

+  Private := Pointer to PxeBc protocol

+  BisAppHandle := Pointer to BIS application handle storage

+  BisDataSigInfo := Pointer to BIS signature information storage

+Returns:

+--*/

+{

+  EFI_STATUS        EfiStatus;

+  EFI_HANDLE        BisHandleBuffer;

+  UINTN             BisHandleCount;

+  EFI_BIS_PROTOCOL  *BisPtr;

+  EFI_BIS_VERSION   BisInterfaceVersion;

+  BOOLEAN           BisCheckFlag;

+

+  BisHandleCount  = sizeof (EFI_HANDLE);

+  BisCheckFlag    = FALSE;

+

+  //

+  // Locate BIS protocol handle (if present).

+  // If BIS protocol handle is not found, return NULL.

+  //

+  DEBUG ((EFI_D_INFO, "\ngBS->LocateHandle()  "));

+

+  EfiStatus = gBS->LocateHandle (

+                    ByProtocol,

+                    &gEfiBisProtocolGuid,

+                    NULL,

+                    &BisHandleCount,

+                    &BisHandleBuffer

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    //

+    // Any error means that there is no BIS.

+    // Note - It could mean that there are more than

+    // one BIS protocols installed, but that scenario

+    // is not yet supported.

+    //

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxebcBisStart()""\n  gBS->LocateHandle()  %r (%xh)\n",

+      EfiStatus,

+      EfiStatus)

+      );

+

+    return NULL;

+  }

+

+  if (BisHandleCount != sizeof BisHandleBuffer) {

+    //

+    // This really should never happen, but I am paranoid.

+    //

+    DEBUG (

+      (EFI_D_NET,

+      "\nPxebcBisStart()  BisHandleCount != %d\n",

+      sizeof BisHandleBuffer)

+      );

+

+    return NULL;

+  }

+

+  DEBUG ((EFI_D_INFO, "BIS handle found."));

+

+  //

+  // Locate BIS protocol interface.

+  // If the BIS protocol interface cannot be found, return NULL.

+  //

+  DEBUG ((EFI_D_INFO, "\ngBS->HandleProtocol()  "));

+

+  EfiStatus = gBS->HandleProtocol (

+                    BisHandleBuffer,

+                    &gEfiBisProtocolGuid,

+                    (VOID **) &BisPtr

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxebcBisStart()""\n  gBS->HandleProtocol()  %r (%xh)\n",

+      EfiStatus,

+      EfiStatus)

+      );

+

+    return NULL;

+  }

+

+  if (BisPtr == NULL) {

+    //

+    // This really should never happen.

+    //

+    DEBUG (

+      (EFI_D_NET,

+      "\nPxebcBisStart()""\n  gBS->HandleProtocoL()  ""BIS protocol interface pointer is NULL!\n")

+      );

+

+    return NULL;

+  }

+

+  DEBUG ((EFI_D_INFO, "BIS protocol interface found."));

+

+  //

+  // Check that all of the BIS API function pointers are not NULL.

+  //

+  if (BisPtr->Initialize == NULL ||

+      BisPtr->Shutdown == NULL ||

+      BisPtr->Free == NULL ||

+      BisPtr->GetBootObjectAuthorizationCertificate == NULL ||

+      BisPtr->GetBootObjectAuthorizationCheckFlag == NULL ||

+      BisPtr->GetBootObjectAuthorizationUpdateToken == NULL ||

+      BisPtr->GetSignatureInfo == NULL ||

+      BisPtr->UpdateBootObjectAuthorization == NULL ||

+      BisPtr->VerifyBootObject == NULL ||

+      BisPtr->VerifyObjectWithCredential == NULL

+      ) {

+    DEBUG (

+      (

+      EFI_D_NET,

+      "\nPxebcBisStart()""\n  BIS protocol interface is invalid."

+      "\n  At least one BIS protocol function pointer is NULL.\n"

+      )

+      );

+

+    return NULL;

+  }

+  //

+  // Initialize BIS.

+  // If BIS does not initialize, return NULL.

+  //

+  DEBUG ((EFI_D_INFO, "\nBisPtr->Initialize()  "));

+

+  BisInterfaceVersion.Major = BIS_VERSION_1;

+

+  EfiStatus = BisPtr->Initialize (

+                        BisPtr,

+                        BisAppHandle,

+                        &BisInterfaceVersion,

+                        NULL

+                        );

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxebcBisStart()""\n  BisPtr->Initialize()  %r (%xh)\n",

+      EfiStatus,

+      EfiStatus)

+      );

+

+    return NULL;

+  }

+

+  DEBUG (

+    (EFI_D_INFO,

+    "  BIS version: %d.%d",

+    BisInterfaceVersion.Major,

+    BisInterfaceVersion.Minor)

+    );

+

+  //

+  // If the requested BIS API version is not supported,

+  // shutdown BIS and return NULL.

+  //

+  if (BisInterfaceVersion.Major != BIS_VERSION_1) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxebcBisStart()""\n  BIS version %d.%d not supported by PXE BaseCode.\n",

+      BisInterfaceVersion.Major,

+      BisInterfaceVersion.Minor)

+      );

+

+    BisPtr->Shutdown (*BisAppHandle);

+    return NULL;

+  }

+  //

+  // Get BIS check flag.

+  // If the BIS check flag cannot be read, shutdown BIS and return NULL.

+  //

+  DEBUG ((EFI_D_INFO, "\nBisPtr->GetBootObjectAuthorizationCheckFlag()  "));

+

+  EfiStatus = BisPtr->GetBootObjectAuthorizationCheckFlag (*BisAppHandle, &BisCheckFlag);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxebcBisStart()""\n  BisPtr->GetBootObjectAuthorizationCheckFlag()  %r (%xh)\n",

+      EfiStatus,

+      EfiStatus)

+      );

+

+    BisPtr->Shutdown (*BisAppHandle);

+    return NULL;

+  }

+  //

+  // If the BIS check flag is FALSE, shutdown BIS and return NULL.

+  //

+  if (!BisCheckFlag) {

+    DEBUG ((EFI_D_INFO, "\nBIS check flag is FALSE.\n"));

+    BisPtr->Shutdown (*BisAppHandle);

+    return NULL;

+  } else {

+    DEBUG ((EFI_D_INFO, "\nBIS check flag is TRUE."));

+  }

+  //

+  // Early out if caller does not want signature information.

+  //

+  if (BisDataSigInfo == NULL) {

+    return BisPtr;

+  }

+  //

+  // Get BIS signature information.

+  // If the signature information cannot be read or is invalid,

+  // shutdown BIS and return NULL.

+  //

+  DEBUG ((EFI_D_INFO, "\nBisPtr->GetSignatureInfo()  "));

+

+  EfiStatus = BisPtr->GetSignatureInfo (*BisAppHandle, BisDataSigInfo);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxebcBisStart()""\n  BisPtr_GetSignatureInfo()  %r (%xh)\n",

+      EfiStatus,

+      EfiStatus)

+      );

+

+    BisPtr->Shutdown (*BisAppHandle);

+    return NULL;

+  }

+

+  if (*BisDataSigInfo == NULL) {

+    //

+    // This should never happen.

+    //

+    DEBUG (

+      (EFI_D_NET,

+      "\nPxebcBisStart()""\n  BisPtr->GetSignatureInfo()  Data pointer is NULL!\n")

+      );

+

+    BisPtr->Shutdown (*BisAppHandle);

+    return NULL;

+  }

+

+  if ((*BisDataSigInfo)->Length < sizeof (EFI_BIS_SIGNATURE_INFO) ||

+      (*BisDataSigInfo)->Length % sizeof (EFI_BIS_SIGNATURE_INFO) ||

+      (*BisDataSigInfo)->Length > sizeof (EFI_BIS_SIGNATURE_INFO) * 63

+      ) {

+    //

+    // This should never happen.

+    //

+    DEBUG (

+      (EFI_D_NET,

+      "\nPxebcBisStart()""\n  BisPtr->GetSignatureInfo()  Invalid BIS siginfo length.\n")

+      );

+

+    BisPtr->Free (*BisAppHandle, *BisDataSigInfo);

+    BisPtr->Shutdown (*BisAppHandle);

+    return NULL;

+  }

+

+  return BisPtr;

+}

+

+VOID

+PxebcBisStop (

+  EFI_BIS_PROTOCOL        *BisPtr,

+  BIS_APPLICATION_HANDLE  BisAppHandle,

+  EFI_BIS_DATA            *BisDataSigInfo

+  )

+/*++

+Routine description:

+  Stop the BIS interface and release allocations.

+

+Parameters:

+  BisPtr := Pointer to BIS interface

+  BisAppHandle := BIS application handle

+  BisDataSigInfo := Pointer to BIS signature information data

+

+Returns:

+

+--*/

+{

+  if (BisPtr == NULL) {

+    return ;

+  }

+  //

+  // Free BIS allocated resources and shutdown BIS.

+  // Return TRUE - BIS support is officially detected.

+  //

+  if (BisDataSigInfo != NULL) {

+    BisPtr->Free (BisAppHandle, BisDataSigInfo);

+  }

+

+  BisPtr->Shutdown (BisAppHandle);

+}

+

+BOOLEAN

+PxebcBisVerify (

+  PXE_BASECODE_DEVICE *Private,

+  VOID                *FileBuffer,

+  UINTN               FileLength,

+  VOID                *CredentialBuffer,

+  UINTN               CredentialLength

+  )

+/*++

+Routine description:

+  Verify image and credential file.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  FileBuffer := Pointer to image buffer

+  FileLength := Image length in bytes

+  CredentialBuffer := Pointer to credential buffer

+  CredentialLength := Credential length in bytes

+

+Returns:

+  TRUE := verified

+  FALSE := not verified

+--*/

+{

+  EFI_BIS_PROTOCOL        *BisPtr;

+  BIS_APPLICATION_HANDLE  BisAppHandle;

+  EFI_BIS_DATA            FileData;

+  EFI_BIS_DATA            CredentialData;

+  EFI_STATUS              EfiStatus;

+  BOOLEAN                 IsVerified;

+

+  if (Private == NULL || FileBuffer == NULL || FileLength == 0 || CredentialBuffer == NULL || CredentialLength == 0) {

+    return FALSE;

+  }

+

+  BisPtr = PxebcBisStart (Private, &BisAppHandle, NULL);

+

+  if (BisPtr == NULL) {

+    return FALSE;

+  }

+

+  FileData.Length       = (UINT32) FileLength;

+  FileData.Data         = FileBuffer;

+  CredentialData.Length = (UINT32) CredentialLength;

+  CredentialData.Data   = CredentialBuffer;

+

+  EfiStatus = BisPtr->VerifyBootObject (

+                        BisAppHandle,

+                        &CredentialData,

+                        &FileData,

+                        &IsVerified

+                        );

+

+  PxebcBisStop (BisPtr, BisAppHandle, NULL);

+

+  return (BOOLEAN) ((EFI_ERROR (EfiStatus)) ? FALSE : (IsVerified ? TRUE : FALSE));

+}

+

+BOOLEAN

+PxebcBisDetect (

+  PXE_BASECODE_DEVICE *Private

+  )

+/*++

+Routine description:

+  Check for BIS interface presence.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+

+Returns:

+  TRUE := BIS present

+  FALSE := BIS not present

+--*/

+{

+  EFI_BIS_PROTOCOL        *BisPtr;

+  BIS_APPLICATION_HANDLE  BisAppHandle;

+  EFI_BIS_DATA            *BisDataSigInfo;

+

+  BisPtr = PxebcBisStart (Private, &BisAppHandle, &BisDataSigInfo);

+

+  if (BisPtr == NULL) {

+    return FALSE;

+  }

+

+  PxebcBisStop (BisPtr, BisAppHandle, BisDataSigInfo);

+

+  return TRUE;

+}

+

+VOID *BCNotifyReg;

+

+EFI_STATUS

+EFIAPI

+BcStart (

+  IN EFI_PXE_BASE_CODE_PROTOCOL *This,

+  IN BOOLEAN                    UseIPv6

+  )

+/*++

+

+  Routine Description:

+    Start and initialize the BaseCode protocol, Simple Network protocol and UNDI.

+

+  Arguments:

+    Private                - Pointer to Pxe BaseCode Protocol

+    UseIPv6            - Do we want to support IPv6?

+

+  Returns:

+    EFI_SUCCESS

+    EFI_INVALID_PARAMETER

+    EFI_UNSUPPORTED

+    EFI_ALREADY_STARTED

+    EFI_OUT_OF_RESOURCES

+    Status is also returned from SNP.Start() and SNP.Initialize().

+

+--*/

+{

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

+  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;

+  EFI_STATUS                  Status;

+  EFI_STATUS                  StatCode;

+  PXE_BASECODE_DEVICE         *Private;

+

+  //

+  // Lock the instance data

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  //

+  // Make sure BaseCode is not already started.

+  //

+  if (This->Mode->Started) {

+    DEBUG ((EFI_D_WARN, "\nBcStart()  BC is already started.\n"));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_ALREADY_STARTED;

+  }

+

+#if !SUPPORT_IPV6

+  //

+  // Fail if IPv6 is requested and not supported.

+  //

+  if (UseIPv6) {

+    DEBUG ((EFI_D_WARN, "\nBcStart()  IPv6 is not supported.\n"));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_UNSUPPORTED;

+  }

+#endif

+  //

+  // Setup shortcuts to SNP protocol and data structure.

+  //

+  SnpPtr      = Private->SimpleNetwork;

+  SnpModePtr  = SnpPtr->Mode;

+

+  //

+  // Start and initialize SNP.

+  //

+  if (SnpModePtr->State == EfiSimpleNetworkStopped) {

+    StatCode = (*SnpPtr->Start) (SnpPtr);

+

+    if (SnpModePtr->State != EfiSimpleNetworkStarted) {

+      DEBUG ((EFI_D_WARN, "\nBcStart()  Could not start SNP.\n"));

+      EfiReleaseLock (&Private->Lock);

+      return StatCode;

+    }

+  }

+  //

+  // acquire memory for mode and transmit/receive buffers

+  //

+  if (SnpModePtr->State == EfiSimpleNetworkStarted) {

+    StatCode = (*SnpPtr->Initialize) (SnpPtr, 0, 0);

+

+    if (SnpModePtr->State != EfiSimpleNetworkInitialized) {

+      DEBUG ((EFI_D_WARN, "\nBcStart()  Could not initialize SNP."));

+      EfiReleaseLock (&Private->Lock);

+      return StatCode;

+    }

+  }

+  //

+  // Dump debug info.

+  //

+  DEBUG ((EFI_D_INFO, "\nBC Start()"));

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->State                    %Xh",

+    SnpModePtr->State)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->HwAddressSize            %Xh",

+    SnpModePtr->HwAddressSize)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MediaHeaderSize          %Xh",

+    SnpModePtr->MediaHeaderSize)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MaxPacketSize            %Xh",

+    SnpModePtr->MaxPacketSize)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MacAddressChangeable     %Xh",

+    SnpModePtr->MacAddressChangeable)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MultipleTxSupported      %Xh",

+    SnpModePtr->MultipleTxSupported)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->CurrentAddress           %Xh",

+     *((UINTN *)&SnpModePtr->CurrentAddress))

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->BroadcastAddress         %Xh",

+    *((UINTN *)&SnpModePtr->BroadcastAddress))

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->PermanentAddress         %Xh",

+    *((UINTN *)&SnpModePtr->PermanentAddress))

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->NvRamSize                %Xh",

+    SnpModePtr->NvRamSize)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->NvRamAccessSize          %Xh",

+    SnpModePtr->NvRamAccessSize)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->ReceiveFilterMask        %Xh",

+    SnpModePtr->ReceiveFilterMask)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->ReceiveFilterSetting     %Xh",

+    SnpModePtr->ReceiveFilterSetting)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MCastFilterCount         %Xh",

+    SnpModePtr->MCastFilterCount)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MCastFilter              %Xh",

+    SnpModePtr->MCastFilter)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->IfType                   %Xh",

+    SnpModePtr->IfType)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MediaPresentSupported    %Xh",

+    SnpModePtr->MediaPresentSupported)

+    );

+  DEBUG (

+    (EFI_D_INFO,

+    "\nSnpModePtr->MediaPresent             %Xh",

+    SnpModePtr->MediaPresent)

+    );

+

+  //

+  // If media check is supported and there is no media,

+  // return error to caller.

+  //

+  if (SnpModePtr->MediaPresentSupported && !SnpModePtr->MediaPresent) {

+    DEBUG ((EFI_D_WARN, "\nBcStart()  Media not present.\n"));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NO_MEDIA;

+  }

+  //

+  // Allocate Tx/Rx buffers

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  BUFFER_ALLOCATE_SIZE,

+                  (VOID **) &Private->TransmitBufferPtr

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    ZeroMem (Private->TransmitBufferPtr, BUFFER_ALLOCATE_SIZE);

+  } else {

+    DEBUG ((EFI_D_NET, "\nBcStart()  Could not alloc TxBuf.\n"));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  BUFFER_ALLOCATE_SIZE,

+                  (VOID **) &Private->ReceiveBufferPtr

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    ZeroMem (Private->ReceiveBufferPtr, BUFFER_ALLOCATE_SIZE);

+  } else {

+    DEBUG ((EFI_D_NET, "\nBcStart()  Could not alloc RxBuf.\n"));

+    gBS->FreePool (Private->TransmitBufferPtr);

+    EfiReleaseLock (&Private->Lock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  256,

+                  (VOID **) &Private->TftpErrorBuffer

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Private->ReceiveBufferPtr);

+    gBS->FreePool (Private->TransmitBufferPtr);

+    EfiReleaseLock (&Private->Lock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->AllocatePool (EfiBootServicesData, 256, (VOID **) &Private->TftpAckBuffer);

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Private->TftpErrorBuffer);

+    gBS->FreePool (Private->ReceiveBufferPtr);

+    gBS->FreePool (Private->TransmitBufferPtr);

+    EfiReleaseLock (&Private->Lock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Initialize private BaseCode instance data

+  //

+  do {

+    Private->RandomPort = (UINT16) (Private->RandomPort + PXE_RND_PORT_LOW + Random (Private));

+  } while (Private->RandomPort < PXE_RND_PORT_LOW);

+

+  Private->Igmpv1TimeoutEvent = NULL;

+  Private->UseIgmpv1Reporting = TRUE;

+  Private->IpLength           = IP_ADDRESS_LENGTH (Private->EfiBc.Mode);

+

+  //

+  // Initialize Mode structure

+  //

+  //

+  // check for callback protocol and set boolean

+  //

+  SetMakeCallback (Private);

+  Private->EfiBc.Mode->Started              = TRUE;

+  Private->EfiBc.Mode->TTL                  = DEFAULT_TTL;

+  Private->EfiBc.Mode->ToS                  = DEFAULT_ToS;

+  Private->EfiBc.Mode->UsingIpv6            = UseIPv6;

+  Private->EfiBc.Mode->DhcpDiscoverValid    = FALSE;

+  Private->EfiBc.Mode->DhcpAckReceived      = FALSE;

+  Private->EfiBc.Mode->ProxyOfferReceived   = FALSE;

+  Private->EfiBc.Mode->PxeDiscoverValid     = FALSE;

+  Private->EfiBc.Mode->PxeReplyReceived     = FALSE;

+  Private->EfiBc.Mode->PxeBisReplyReceived  = FALSE;

+  Private->EfiBc.Mode->IcmpErrorReceived    = FALSE;

+  Private->EfiBc.Mode->TftpErrorReceived    = FALSE;

+  ZeroMem (&Private->EfiBc.Mode->StationIp, sizeof (EFI_IP_ADDRESS));

+  ZeroMem (&Private->EfiBc.Mode->SubnetMask, sizeof (EFI_IP_ADDRESS));

+  Private->EfiBc.Mode->IpFilter.Filters   = 0;

+  Private->EfiBc.Mode->IpFilter.IpCnt     = 0;

+  Private->EfiBc.Mode->ArpCacheEntries    = 0;

+  Private->EfiBc.Mode->RouteTableEntries  = 0;

+  ZeroMem (&Private->EfiBc.Mode->IcmpError, sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));

+  ZeroMem (&Private->EfiBc.Mode->TftpError, sizeof (EFI_PXE_BASE_CODE_TFTP_ERROR));

+

+  //

+  // Set to PXE_TRUE by the BC constructor if this BC implementation

+  // supports IPv6.

+  //

+  Private->EfiBc.Mode->Ipv6Supported = SUPPORT_IPV6;

+

+#if SUPPORT_IPV6

+  Private->EfiBc.Mode->Ipv6Available = Private->NiiPtr->Ipv6Supported;

+#else

+  Private->EfiBc.Mode->Ipv6Available = FALSE;

+#endif

+  //

+  // Set to TRUE by the BC constructor if this BC implementation

+  // supports BIS.

+  //

+  Private->EfiBc.Mode->BisSupported = TRUE;

+  Private->EfiBc.Mode->BisDetected  = PxebcBisDetect (Private);

+

+  //

+  // This field is set to PXE_TRUE by the BC Start() function.  When this

+  // field is PXE_TRUE, ARP packets are sent as needed to get IP and MAC

+  // addresses.  This can cause unexpected delays in the DHCP(), Discover()

+  // and MTFTP() functions.  Setting this to PXE_FALSE will cause these

+  // functions to fail if the required IP/MAC information is not in the

+  // ARP cache.  The value of this field can be changed by an application

+  // at any time.

+  //

+  Private->EfiBc.Mode->AutoArp = TRUE;

+

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+BcStop (

+  IN EFI_PXE_BASE_CODE_PROTOCOL *This

+  )

+/*++

+

+  Routine Description:

+    Stop the BaseCode protocol, Simple Network protocol and UNDI.

+

+  Arguments:

+    Private                - Pointer to Pxe BaseCode Protocol

+

+  Returns:

+

+    0                  - Successfully stopped

+    !0                 - Failed

+--*/

+{

+  //

+  // Lock the instance data

+  //

+  EFI_PXE_BASE_CODE_MODE      *PxebcMode;

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

+  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;

+  EFI_STATUS                  StatCode;

+  PXE_BASECODE_DEVICE         *Private;

+

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  PxebcMode   = Private->EfiBc.Mode;

+  SnpPtr      = Private->SimpleNetwork;

+  SnpModePtr  = SnpPtr->Mode;

+

+  //

+  // Issue BC command

+  //

+  StatCode = EFI_NOT_STARTED;

+

+  if (SnpModePtr->State == EfiSimpleNetworkInitialized) {

+    StatCode = (*SnpPtr->Shutdown) (SnpPtr);

+  }

+

+  if (SnpModePtr->State == EfiSimpleNetworkStarted) {

+    StatCode = (*SnpPtr->Stop) (SnpPtr);

+  }

+

+  if (Private->TransmitBufferPtr != NULL) {

+    gBS->FreePool (Private->TransmitBufferPtr);

+    Private->TransmitBufferPtr = NULL;

+  }

+

+  if (Private->ReceiveBufferPtr != NULL) {

+    gBS->FreePool (Private->ReceiveBufferPtr);

+    Private->ReceiveBufferPtr = NULL;

+  }

+

+  if (Private->ArpBuffer != NULL) {

+    gBS->FreePool (Private->ArpBuffer);

+    Private->ArpBuffer = NULL;

+  }

+

+  if (Private->TftpErrorBuffer != NULL) {

+    gBS->FreePool (Private->TftpErrorBuffer);

+    Private->TftpErrorBuffer = NULL;

+  }

+

+  if (Private->TftpAckBuffer != NULL) {

+    gBS->FreePool (Private->TftpAckBuffer);

+    Private->TftpAckBuffer = NULL;

+  }

+

+  if (Private->Igmpv1TimeoutEvent != NULL) {

+    gBS->CloseEvent (Private->Igmpv1TimeoutEvent);

+    Private->Igmpv1TimeoutEvent = NULL;

+  }

+

+  Private->FileSize             = 0;

+  Private->EfiBc.Mode->Started  = FALSE;

+

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+const IPV4_ADDR AllSystemsGroup = { { 224, 0, 0, 1 } };

+

+EFI_STATUS

+IpFilter (

+  IN PXE_BASECODE_DEVICE          *Private,

+  IN EFI_PXE_BASE_CODE_IP_FILTER  *Filter

+  )

+/*++

+

+  Routine Description:

+    Set up the IP filter

+

+  Arguments:

+    Private                - Pointer to Pxe BaseCode Protocol

+    Filter             - Pointer to the filter

+

+  Returns:

+

+    0                  - Successfully set the filter

+    !0                 - Failed

+--*/

+{

+  EFI_STATUS                  StatCode;

+  EFI_MAC_ADDRESS             MACadds[PXE_IP_FILTER_SIZE];

+  EFI_PXE_BASE_CODE_MODE      *PxebcMode;

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

+  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;

+  UINT32                      Enable;

+  UINT32                      Disable;

+  UINTN                       Index;

+  UINTN                       Index2;

+

+  PxebcMode   = Private->EfiBc.Mode;

+  SnpPtr      = Private->SimpleNetwork;

+  SnpModePtr  = SnpPtr->Mode;

+

+  //

+  // validate input parameters

+  // must have a filter

+  // must not have any extra filter bits set

+  //

+  if (Filter == NULL ||

+      (Filter->Filters &~FILTER_BITS)

+      //

+      // must not have a count which is too large or with no IP list

+      //

+      ||

+      (Filter->IpCnt && (!Filter->IpList || Filter->IpCnt > PXE_IP_FILTER_SIZE))

+      //

+      // must not have incompatible filters - promiscuous incompatible with anything else

+      //

+      ||

+      (

+        (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) &&

+      ((Filter->Filters &~EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) || Filter->IpCnt)

+    )

+      ) {

+    DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #1"));

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // promiscuous multicast incompatible with multicast in IP list

+  //

+  if (Filter->IpCnt && (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST)) {

+    for (Index = 0; Index < Filter->IpCnt; ++Index) {

+      if (IS_MULTICAST (&Filter->IpList[Index])) {

+        DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #2"));

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+  //

+  // leave groups for all those multicast which are no longer enabled

+  //

+  for (Index = 0; Index < PxebcMode->IpFilter.IpCnt; ++Index) {

+    if (!IS_MULTICAST (&PxebcMode->IpFilter.IpList[Index])) {

+      continue;

+    }

+

+    for (Index2 = 0; Index2 < Filter->IpCnt; ++Index2) {

+      if (!CompareMem (&PxebcMode->IpFilter.IpList[Index], &Filter->IpList[Index2], IP_ADDRESS_LENGTH (PxebcMode))) {

+        //

+        // still enabled

+        //

+        break;

+      }

+    }

+    //

+    // if we didn't find it, remove from group

+    //

+    if (Index2 == Filter->IpCnt) {

+      IgmpLeaveGroup (Private, &PxebcMode->IpFilter.IpList[Index]);

+    }

+  }

+  //

+  // set enable bits, convert multicast ip adds, join groups

+  // allways leave receive broadcast enabled at hardware layer

+  //

+  Index2 = 0;

+

+  if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) {

+    Enable = EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;

+  } else {

+    if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) {

+      Enable = EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;

+    } else {

+      Enable = EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;

+

+      for (Index = 0; Index < Filter->IpCnt; ++Index) {

+        CopyMem (&(PxebcMode->IpFilter.IpList[Index]), &(Filter->IpList[Index]), sizeof (EFI_IP_ADDRESS));

+

+        if (IS_MULTICAST (&Filter->IpList[Index])) {

+          EFI_IP_ADDRESS  *TmpIp;

+

+          Enable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;

+

+          //

+          // if this is the first group, add the all systems group to mcast list

+          //

+          if (!Index2)

+          {

+#if SUPPORT_IPV6

+            if (PxebcMode->UsingIpv6) {

+              //

+              // TBD

+              //

+            } else

+#endif

+              TmpIp = (EFI_IP_ADDRESS *) &AllSystemsGroup;

+            --Index;

+          } else {

+            TmpIp = (EFI_IP_ADDRESS *) &Filter->IpList[Index];

+          }

+          //

+          // get MAC address of IP

+          //

+          StatCode = (*SnpPtr->MCastIpToMac) (SnpPtr, PxebcMode->UsingIpv6, TmpIp, &MACadds[Index2++]);

+

+          if (EFI_ERROR (StatCode)) {

+            DEBUG (

+              (EFI_D_INFO,

+              "\nIpFilter()  Exit #2  %Xh (%r)",

+              StatCode,

+              StatCode)

+              );

+            return StatCode;

+          }

+        } else {

+          Enable |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;

+        }

+      }

+    }

+

+    if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) {

+      Enable |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;

+    }

+  }

+  //

+  // if nothing changed, just return

+  //

+  DEBUG (

+    (EFI_D_INFO,

+    "\nsnp->ReceiveFilterSetting == %Xh  Filter->IpCnt == %Xh",

+    SnpModePtr->ReceiveFilterSetting,

+    Filter->IpCnt)

+    );

+

+  if (SnpModePtr->ReceiveFilterSetting == Enable && !Filter->IpCnt) {

+    DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #4"));

+    return EFI_SUCCESS;

+  }

+  //

+  // disable those currently set but not set in new filter

+  //

+  Disable                   = SnpModePtr->ReceiveFilterSetting &~Enable;

+

+  StatCode                  = SnpPtr->ReceiveFilters (SnpPtr, Enable, Disable, FALSE, Index2, MACadds);

+

+  PxebcMode->IpFilter.IpCnt = Filter->IpCnt;

+

+  //

+  // join groups for all multicast in list

+  //

+  for (Index = 0; Index < Filter->IpCnt; ++Index) {

+    if (IS_MULTICAST (&Filter->IpList[Index])) {

+      IgmpJoinGroup (Private, &Filter->IpList[Index]);

+    }

+  }

+

+  DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #5  %Xh (%r)", StatCode, StatCode));

+

+  return StatCode;

+}

+

+EFI_STATUS

+EFIAPI

+BcIpFilter (

+  IN EFI_PXE_BASE_CODE_PROTOCOL  *This,

+  IN EFI_PXE_BASE_CODE_IP_FILTER *Filter

+  )

+/*++

+

+  Routine Description:

+    Call the IP filter

+

+  Arguments:

+    Private                - Pointer to Pxe BaseCode Protocol

+    Filter             - Pointer to the filter

+

+  Returns:

+

+    0                  - Successfully set the filter

+    !0                 - Failed

+--*/

+{

+  EFI_STATUS          StatCode;

+  PXE_BASECODE_DEVICE *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  if (Filter == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Issue BC command

+  //

+  StatCode = IpFilter (Private, Filter);

+

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+EFI_STATUS

+EFIAPI

+BcSetParameters (

+  EFI_PXE_BASE_CODE_PROTOCOL  *This,

+  BOOLEAN                     *AutoArpPtr,

+  BOOLEAN                     *SendGuidPtr,

+  UINT8                       *TimeToLivePtr,

+  UINT8                       *TypeOfServicePtr,

+  BOOLEAN                     *MakeCallbackPtr

+  )

+/*++

+

+  Routine Description:

+    Set the Base Code behavior parameters

+

+  Arguments:

+    This               - Pointer to Pxe BaseCode Protocol

+    AutoArpPtr           - Boolean to do ARP stuff

+    SendGuidPtr          - Boolean whether or not to send GUID info

+    TimeToLivePtr               - Value for Total time to live

+    TypeOfServicePtr               - Value for Type of Service

+    MakeCallbackPtr      - Boolean to determine if we make callbacks

+

+  Returns:

+

+    0                  - Successfully set the parameters

+    !0                 - Failed

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxebcMode;

+  EFI_GUID                TmpGuid;

+  CHAR8                   *SerialNumberPtr;

+  EFI_STATUS              StatCode;

+  PXE_BASECODE_DEVICE     *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  DEBUG ((EFI_D_INFO, "\nSetParameters()  Entry.  "));

+

+  PxebcMode = Private->EfiBc.Mode;

+  StatCode  = EFI_SUCCESS;

+

+  if (SendGuidPtr != NULL) {

+    if (*SendGuidPtr) {

+      if (PxeBcLibGetSmbiosSystemGuidAndSerialNumber (&TmpGuid, &SerialNumberPtr) != EFI_SUCCESS) {

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+

+  if (MakeCallbackPtr != NULL) {

+    if (*MakeCallbackPtr) {

+      if (!SetMakeCallback (Private)) {

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+

+    PxebcMode->MakeCallbacks = *MakeCallbackPtr;

+  }

+

+  if (AutoArpPtr != NULL) {

+    PxebcMode->AutoArp = *AutoArpPtr;

+  }

+

+  if (SendGuidPtr != NULL) {

+    PxebcMode->SendGUID = *SendGuidPtr;

+  }

+

+  if (TimeToLivePtr != NULL) {

+    PxebcMode->TTL = *TimeToLivePtr;

+  }

+

+  if (TypeOfServicePtr != NULL) {

+    PxebcMode->ToS = *TypeOfServicePtr;

+  }

+  //

+  // Unlock the instance data

+  //

+  DEBUG ((EFI_D_INFO, "\nSetparameters()  Exit = %xh  ", StatCode));

+

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+//

+// //////////////////////////////////////////////////////////

+//

+//  BC Set Station IP Routine

+//

+EFI_STATUS

+EFIAPI

+BcSetStationIP (

+  IN EFI_PXE_BASE_CODE_PROTOCOL *This,

+  IN EFI_IP_ADDRESS             *StationIpPtr,

+  IN EFI_IP_ADDRESS             *SubnetMaskPtr

+  )

+/*++

+

+  Routine Description:

+    Set the station IP address

+

+  Arguments:

+    This                 - Pointer to Pxe BaseCode Protocol

+    StationIpPtr         - Pointer to the requested IP address to set in base code

+    SubnetMaskPtr        - Pointer to the requested subnet mask for the base code

+

+  Returns:

+

+    EFI_SUCCESS          - Successfully set the parameters

+    EFI_NOT_STARTED      - BC has not started

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxebcMode;

+  EFI_STATUS              StatCode;

+  PXE_BASECODE_DEVICE     *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  PxebcMode = Private->EfiBc.Mode;

+

+  if (StationIpPtr != NULL) {

+    CopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));

+    Private->GoodStationIp = TRUE;

+  }

+

+  if (SubnetMaskPtr != NULL) {

+    CopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));

+  }

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+

+  return EFI_SUCCESS;

+}

+

+EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {

+  PxeBcDriverSupported,

+  PxeBcDriverStart,

+  PxeBcDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+PxeBcDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports Controller. Any Controller

+    than contains a Snp protocol can be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test.

+    RemainingDevicePath - Not used.

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_ALREADY_STARTED - This driver is already running on this device.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSimpleNetworkProtocolGuid,

+                  (VOID **) &SnpPtr,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiSimpleNetworkProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PxeBcDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Start the Base code driver.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test.

+    RemainingDevicePath - Not used.

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_ALREADY_STARTED - This driver is already running on this device.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS          Status;

+  PXE_BASECODE_DEVICE *Private;

+  LOADFILE_DEVICE     *pLF;

+

+  //

+  // Allocate structures needed by BaseCode and LoadFile protocols.

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (PXE_BASECODE_DEVICE),

+                  (VOID **) &Private

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    ZeroMem (Private, sizeof (PXE_BASECODE_DEVICE));

+  } else {

+    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc PXE_BASECODE_DEVICE structure.\n"));

+    return Status;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (LOADFILE_DEVICE),

+                  (VOID **) &pLF

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    ZeroMem (pLF, sizeof (LOADFILE_DEVICE));

+  } else {

+    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc LOADFILE_DEVICE structure.\n"));

+    gBS->FreePool (Private);

+    return Status;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_PXE_BASE_CODE_MODE),

+                  (VOID **) &Private->EfiBc.Mode

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    ZeroMem (Private->EfiBc.Mode, sizeof (EFI_PXE_BASE_CODE_MODE));

+  } else {

+    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc Mode structure.\n"));

+    gBS->FreePool (Private);

+    gBS->FreePool (pLF);

+    return Status;

+  }

+  //

+  // Lock access, just in case

+  //

+  EfiInitializeLock (&Private->Lock, EFI_TPL_CALLBACK);

+  EfiAcquireLock (&Private->Lock);

+

+  EfiInitializeLock (&pLF->Lock, EFI_TPL_CALLBACK);

+  EfiAcquireLock (&pLF->Lock);

+

+  //

+  // Initialize PXE structure

+  //

+  //

+  // First initialize the internal 'private' data that the application

+  // does not see.

+  //

+  Private->Signature  = PXE_BASECODE_DEVICE_SIGNATURE;

+  Private->Handle     = Controller;

+

+  //

+  // Get the NII interface

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                  (VOID **) &Private->NiiPtr,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                    (VOID **) &Private->NiiPtr,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto PxeBcError;

+    }

+  }

+  //

+  // Get the Snp interface

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSimpleNetworkProtocolGuid,

+                  (VOID **) &Private->SimpleNetwork,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto PxeBcError;

+  }

+

+  //

+  // Next, initialize the external 'public' data that

+  // the application does see.

+  //

+  Private->EfiBc.Revision       = EFI_PXE_BASE_CODE_INTERFACE_REVISION;

+  Private->EfiBc.Start          = BcStart;

+  Private->EfiBc.Stop           = BcStop;

+  Private->EfiBc.Dhcp           = BcDhcp;

+  Private->EfiBc.Discover       = BcDiscover;

+  Private->EfiBc.Mtftp          = BcMtftp;

+  Private->EfiBc.UdpWrite       = BcUdpWrite;

+  Private->EfiBc.UdpRead        = BcUdpRead;

+  Private->EfiBc.Arp            = BcArp;

+  Private->EfiBc.SetIpFilter    = BcIpFilter;

+  Private->EfiBc.SetParameters  = BcSetParameters;

+  Private->EfiBc.SetStationIp   = BcSetStationIP;

+  Private->EfiBc.SetPackets     = BcSetPackets;

+

+  //

+  // Initialize BaseCode Mode structure

+  //

+  Private->EfiBc.Mode->Started    = FALSE;

+  Private->EfiBc.Mode->TTL        = DEFAULT_TTL;

+  Private->EfiBc.Mode->ToS        = DEFAULT_ToS;

+  Private->EfiBc.Mode->UsingIpv6  = FALSE;

+  Private->EfiBc.Mode->AutoArp    = TRUE;

+

+  //

+  // Set to PXE_TRUE by the BC constructor if this BC

+  // implementation supports IPv6.

+  //

+  Private->EfiBc.Mode->Ipv6Supported = SUPPORT_IPV6;

+

+#if SUPPORT_IPV6

+  Private->EfiBc.Mode->Ipv6Available = Private->NiiPtr->Ipv6Supported;

+#else

+  Private->EfiBc.Mode->Ipv6Available = FALSE;

+#endif

+  //

+  // Set to TRUE by the BC constructor if this BC

+  // implementation supports BIS.

+  //

+  Private->EfiBc.Mode->BisSupported = TRUE;

+  Private->EfiBc.Mode->BisDetected  = PxebcBisDetect (Private);

+

+  //

+  // Initialize LoadFile structure.

+  //

+  pLF->Signature          = LOADFILE_DEVICE_SIGNATURE;

+  pLF->LoadFile.LoadFile  = LoadFile;

+  pLF->Private            = Private;

+

+  //

+  // Install protocol interfaces.

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Controller,

+                  &gEfiPxeBaseCodeProtocolGuid,

+                  &Private->EfiBc,

+                  &gEfiLoadFileProtocolGuid,

+                  &pLF->LoadFile,

+                  NULL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiSimpleNetworkProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+    goto PxeBcError;

+  }

+  //

+  // Release locks.

+  //

+  EfiReleaseLock (&pLF->Lock);

+  EfiReleaseLock (&Private->Lock);

+  return Status;

+

+PxeBcError: ;

+  gBS->FreePool (Private->EfiBc.Mode);

+  gBS->FreePool (Private);

+  gBS->FreePool (pLF);

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+PxeBcDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop the Base code driver.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test.

+    NumberOfChildren    - Not used

+    ChildHandleBuffer   - Not used

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_ALREADY_STARTED - This driver is already running on this device.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_LOAD_FILE_PROTOCOL  *LfProtocol;

+  LOADFILE_DEVICE         *LoadDevice;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiLoadFileProtocolGuid,

+                  (VOID **) &LfProtocol,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  LoadDevice = EFI_LOAD_FILE_DEV_FROM_THIS (LfProtocol);

+

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Controller,

+                  &gEfiLoadFileProtocolGuid,

+                  &LoadDevice->LoadFile,

+                  &gEfiPxeBaseCodeProtocolGuid,

+                  &LoadDevice->Private->EfiBc,

+                  NULL

+                  );

+

+  if (!EFI_ERROR (Status)) {

+

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiSimpleNetworkProtocolGuid,

+                    This->DriverBindingHandle,

+                    Controller

+                    );

+

+    gBS->FreePool (LoadDevice->Private->EfiBc.Mode);

+    gBS->FreePool (LoadDevice->Private);

+    gBS->FreePool (LoadDevice);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+InitializeBCDriver (

+  IN EFI_HANDLE       ImageHandle,

+  IN EFI_SYSTEM_TABLE *SystemTable

+  )

+/*++

+

+  Routine Description:

+    Initialize the base code drivers and install the driver binding

+

+  Arguments:

+    Standard EFI Image Entry

+

+  Returns:

+    EFI_SUCCESS         - This driver was successfully bound

+

+--*/

+{

+  InitArpHeader ();

+  OptionsStrucInit ();

+

+  return EFI_SUCCESS;

+}

+

+/* eof - bc.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/build.xml
new file mode 100644
index 0000000..e0b5ee6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BC"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Network/PxeBc/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BC">

+      <GenBuild baseName="BC" mbdFilename="${MODULE_DIR}/BC.mbd" msaFilename="${MODULE_DIR}/BC.msa"/>

+   </target>

+   <target depends="BC_clean" name="clean"/>

+   <target depends="BC_cleanall" name="cleanall"/>

+   <target name="BC_clean">

+      <OutputDirSetup baseName="BC" mbdFilename="${MODULE_DIR}/BC.mbd" msaFilename="${MODULE_DIR}/BC.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BC_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BC_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BC_cleanall">

+      <OutputDirSetup baseName="BC" mbdFilename="${MODULE_DIR}/BC.mbd" msaFilename="${MODULE_DIR}/BC.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BC_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BC_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BC*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/dhcp.h b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/dhcp.h
new file mode 100644
index 0000000..cd448b3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/dhcp.h
@@ -0,0 +1,627 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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 _DHCP_H

+#define _DHCP_H

+

+//

+// Definitions for DHCP version 4 UDP packet.

+// The field names in this structure are defined and described in RFC 2131.

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8   op;

+#define BOOTP_REQUEST 1

+#define BOOTP_REPLY   2

+

+  UINT8   htype;

+  UINT8   hlen;

+  UINT8   hops;

+  UINT32  xid;

+  UINT16  secs;

+  UINT16  flags;

+#define DHCP_BROADCAST_FLAG 0x8000

+

+  UINT32  ciaddr;

+  UINT32  yiaddr;

+  UINT32  siaddr;

+  UINT32  giaddr;

+  UINT8   chaddr[16];

+  UINT8   sname[64];

+  UINT8   file[128];

+  UINT8   options[312];

+#define OP_PAD                              0

+#define OP_END                              255

+#define OP_SUBNET_MASK                      1

+#define OP_TIME_OFFSET                      2

+#define OP_ROUTER_LIST                      3

+#define OP_TIME_SERVERS                     4

+#define OP_NAME_SERVERS                     5

+#define OP_DNS_SERVERS                      6

+#define OP_LOG_SERVERS                      7

+#define OP_COOKIE_SERVERS                   8

+#define OP_LPR_SREVERS                      9

+#define OP_IMPRESS_SERVERS                  10

+#define OP_RES_LOC_SERVERS                  11

+#define OP_HOST_NAME                        12

+#define OP_BOOT_FILE_SZ                     13

+#define OP_DUMP_FILE                        14

+#define OP_DOMAIN_NAME                      15

+#define OP_SWAP_SERVER                      16

+#define OP_ROOT_PATH                        17

+#define OP_EXTENSION_PATH                   18

+#define OP_IP_FORWARDING                    19

+#define OP_NON_LOCAL_SRC_RTE                20

+#define OP_POLICY_FILTER                    21

+#define OP_MAX_DATAGRAM_SZ                  22

+#define OP_DEFAULT_TTL                      23

+#define OP_MTU_AGING_TIMEOUT                24

+#define OP_MTU_SIZES                        25

+#define OP_MTU_TO_USE                       26

+#define OP_ALL_SUBNETS_LOCAL                27

+#define OP_BROADCAST_ADD                    28

+#define OP_PERFORM_MASK_DISCOVERY           29

+#define OP_RESPOND_TO_MASK_REQ              30

+#define OP_PERFORM_ROUTER_DISCOVERY         31

+#define OP_ROUTER_SOLICIT_ADDRESS           32

+#define OP_STATIC_ROUTER_LIST               33

+#define OP_USE_ARP_TRAILERS                 34

+#define OP_ARP_CACHE_TIMEOUT                35

+#define OP_ETHERNET_ENCAPSULATION           36

+#define OP_TCP_DEFAULT_TTL                  37

+#define OP_TCP_KEEP_ALIVE_INT               38

+#define OP_KEEP_ALIVE_GARBAGE               39

+#define OP_NIS_DOMAIN_NAME                  40

+#define OP_NIS_SERVERS                      41

+#define OP_NTP_SERVERS                      42

+#define OP_VENDOR_SPECIFIC                  43

+#define VEND_PXE_MTFTP_IP                   1

+#define VEND_PXE_MTFTP_CPORT                2

+#define VEND_PXE_MTFTP_SPORT                3

+#define VEND_PXE_MTFTP_TMOUT                4

+#define VEND_PXE_MTFTP_DELAY                5

+#define VEND_PXE_DISCOVERY_CONTROL          6

+#define VEND_PXE_DISCOVERY_MCAST_ADDR       7

+#define VEND_PXE_BOOT_SERVERS               8

+#define VEND_PXE_BOOT_MENU                  9

+#define VEND_PXE_BOOT_PROMPT                10

+#define VEND_PXE_MCAST_ADDRS_ALLOC          11

+#define VEND_PXE_CREDENTIAL_TYPES           12

+#define VEND_PXE_BOOT_ITEM                  71

+#define OP_NBNS_SERVERS                     44

+#define OP_NBDD_SERVERS                     45

+#define OP_NETBIOS_NODE_TYPE                46

+#define OP_NETBIOS_SCOPE                    47

+#define OP_XWINDOW_SYSTEM_FONT_SERVERS      48

+#define OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS  49

+#define OP_DHCP_REQ_IP_ADD                  50

+#define OP_DHCP_LEASE_TIME                  51

+#define OP_DHCP_OPTION_OVERLOAD             52

+#define OVLD_FILE                           1

+#define OVLD_SRVR_NAME                      2

+#define OP_DHCP_MESSAGE_TYPE                53

+#define DHCPDISCOVER                        1

+#define DHCPOFFER                           2

+#define DHCPREQUEST                         3

+#define DHCPDECLINE                         4

+#define DHCPACK                             5

+#define DHCPNAK                             6

+#define DHCPRELEASE                         7

+#define DHCPINFORM                          8

+#define OP_DHCP_SERVER_IP                   54

+#define OP_DHCP_PARM_REQ_LIST               55

+#define OP_DHCP_ERROR_MESSAGE               56

+#define OP_DHCP_MAX_MESSAGE_SZ              57

+#define OP_DHCP_RENEWAL_TIME                58

+#define OP_DHCP_REBINDING_TIME              59

+#define OP_DHCP_CLASS_IDENTIFIER            60

+#define OP_DHCP_CLIENT_IDENTIFIER           61

+#define OP_NISPLUS_DOMAIN_NAME              64

+#define OP_NISPLUS_SERVERS                  65

+#define OP_DHCP_TFTP_SERVER_NAME            66

+#define OP_DHCP_BOOTFILE                    67

+#define OP_MOBILE_IP_HOME_AGENTS            68

+#define OP_SMPT_SERVERS                     69

+#define OP_POP3_SERVERS                     70

+#define OP_NNTP_SERVERS                     71

+#define OP_WWW_SERVERS                      72

+#define OP_FINGER_SERVERS                   73

+#define OP_IRC_SERVERS                      74

+#define OP_STREET_TALK_SERVERS              75

+#define OP_STREET_TALK_DIR_ASSIST_SERVERS   76

+#define OP_NDS_SERVERS                      85

+#define OP_NDS_TREE_NAME                    86

+#define OP_NDS_CONTEXT                      87

+#define OP_DHCP_SYSTEM_ARCH                 93

+#define OP_DHCP_NETWORK_ARCH                94

+#define OP_DHCP_PLATFORM_ID                 97

+} DHCPV4_STRUCT;

+

+//

+// DHCPv4 option header

+//

+typedef struct {

+  UINT8 OpCode;

+  UINT8 Length;

+  //

+  // followed by Data[]

+  //

+} DHCPV4_OP_HEADER;

+

+//

+// Generic DHCPv4 option (header followed by data)

+//

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Data[1];

+} DHCPV4_OP_STRUCT;

+

+//

+// Maximum DHCP packet size on ethernet

+//

+#define MAX_DHCP_MSG_SZ (MAX_ENET_DATA_SIZE - sizeof (IPV4_HEADER) - sizeof (UDPV4_HEADER))

+

+//

+// Macros used in pxe_bc_dhcp.c and pxe_loadfile.c

+//

+#define DHCPV4_TRANSMIT_BUFFER  (*(DHCPV4_STRUCT *) (Private->TransmitBuffer))

+#define DHCPV4_OPTIONS_BUFFER   (*(struct optionsstr *) DHCPV4_TRANSMIT_BUFFER.options)

+

+#define DHCPV4_ACK_INDEX        0

+#define PXE_BINL_INDEX          1

+#define PXE_OFFER_INDEX         1

+#define PXE_ACK_INDEX           2

+#define PXE_BIS_INDEX           3

+

+#define DHCPV4_ACK_BUFFER       ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[DHCPV4_ACK_INDEX]

+#define PXE_BINL_BUFFER         ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_BINL_INDEX]

+#define PXE_OFFER_BUFFER        ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_OFFER_INDEX]

+#define PXE_ACK_BUFFER          ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_ACK_INDEX]

+#define PXE_BIS_BUFFER          ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_BIS_INDEX]

+

+#define DHCPV4_ACK_PACKET       DHCPV4_ACK_BUFFER.u.Dhcpv4

+#define PXE_BINL_PACKET         PXE_BINL_BUFFER.u.Dhcpv4

+#define PXE_OFFER_PACKET        PXE_OFFER_BUFFER.u.Dhcpv4

+#define PXE_ACK_PACKET          PXE_ACK_BUFFER.u.Dhcpv4

+#define PXE_BIS_PACKET          PXE_BIS_BUFFER.u.Dhcpv4

+

+//

+// network structure definitions

+//

+//

+// some option definitions

+//

+#define DHCPV4_OPTION_LENGTH(type)  (sizeof (type) - sizeof (DHCPV4_OP_HEADER))

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Type;

+} DHCPV4_OP_MESSAGE_TYPE;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Overload;

+} DHCPV4_OP_OVERLOAD;

+

+//

+// boot server list structure

+// one or more contained in a pxe boot servers structure

+//

+typedef struct {

+  UINT8             IpCount;

+  EFI_IPv4_ADDRESS  IpList[1];  // IP count of IPs

+} PXEV4_SERVER_LIST;

+

+typedef struct {

+  UINT8             IpCount;

+  EFI_IPv6_ADDRESS  IpList[1];  // IP count of IPs

+} PXEV6_SERVER_LIST;

+

+typedef union {

+  PXEV4_SERVER_LIST Ipv4List;

+  PXEV6_SERVER_LIST Ipv6List;

+} PXE_SERVER_LISTS;

+

+typedef struct {

+  UINT16            Type;

+  PXE_SERVER_LISTS  u;

+} PXE_SERVER_LIST;

+

+//

+// pxe boot servers structure

+//

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  PXE_SERVER_LIST   ServerList[1];  // one or more

+} PXE_OP_SERVER_LIST;

+

+//

+// pxe boot item structure

+//

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT16            Type;

+  UINT16            Layer;

+} PXE_OP_BOOT_ITEM;

+

+//

+// pxe boot menu item structure

+//

+typedef struct {

+  UINT16  Type;

+  UINT8   DataLen;

+  UINT8   Data[1];

+} PXE_BOOT_MENU_ENTRY;

+

+//

+// pxe boot menu structure

+//

+typedef struct {

+  DHCPV4_OP_HEADER    Header;

+  PXE_BOOT_MENU_ENTRY MenuItem[1];

+} PXE_OP_BOOT_MENU;

+

+//

+// pxe boot prompt structure

+//

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Timeout;

+  UINT8             Prompt[1];

+} PXE_OP_BOOT_PROMPT;

+

+#define PXE_BOOT_PROMPT_AUTO_SELECT 0

+#define PXE_BOOT_PROMPT_NO_TIMEOUT  255

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Class[1];

+} DHCPV4_OP_CLASS;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             File[1];

+} DHCPV4_OP_BOOTFILE;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             VendorOptions[1];

+} DHCPV4_OP_VENDOR_OPTIONS;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             MaxSize[2];

+} DHCPV4_OP_MAX_MESSAGE_SIZE;

+

+typedef struct {

+  UINT8 _OP_SUBNET_MASK;            /* 1 */

+  UINT8 _OP_TIME_OFFSET;            /* 2 */

+  UINT8 _OP_ROUTER_LIST;            /* 3 */

+  UINT8 _OP_TIME_SERVERS;           /* 4 */

+  UINT8 _OP_NAME_SERVERS;           /* 5 */

+  UINT8 _OP_DNS_SERVERS;            /* 6 */

+  UINT8 _OP_HOST_NAME;              /* 12 */

+  UINT8 _OP_BOOT_FILE_SZ;           /* 13 */

+  UINT8 _OP_DOMAIN_NAME;            /* 15 */

+  UINT8 _OP_ROOT_PATH;              /* 17 */

+  UINT8 _OP_EXTENSION_PATH;         /* 18 */

+  UINT8 _OP_MAX_DATAGRAM_SZ;        /* 22 */

+  UINT8 _OP_DEFAULT_TTL;            /* 23 */

+  UINT8 _OP_BROADCAST_ADD;          /* 28 */

+  UINT8 _OP_NIS_DOMAIN_NAME;        /* 40 */

+  UINT8 _OP_NIS_SERVERS;            /* 41 */

+  UINT8 _OP_NTP_SERVERS;            /* 42 */

+  UINT8 _OP_VENDOR_SPECIFIC;        /* 43 */

+  UINT8 _OP_DHCP_REQ_IP_ADD;        /* 50 */

+  UINT8 _OP_DHCP_LEASE_TIME;        /* 51 */

+  UINT8 _OP_DHCP_SERVER_IP;         /* 54 */

+  UINT8 _OP_DHCP_RENEWAL_TIME;      /* 58 */

+  UINT8 _OP_DHCP_REBINDING_TIME;    /* 59 */

+  UINT8 _OP_DHCP_CLASS_IDENTIFIER;  /* 60 */

+  UINT8 _OP_DHCP_TFTP_SERVER_NAME;  /* 66 */

+  UINT8 _OP_DHCP_BOOTFILE;          /* 67 */

+  UINT8 _OP_DHCP_PLATFORM_ID;       /* 97 */

+  UINT8 VendorOption128;            //      vendor option 128

+  UINT8 VendorOption129;            //      vendor option 129

+  UINT8 VendorOption130;            //      vendor option 130

+  UINT8 VendorOption131;            //      vendor option 131

+  UINT8 VendorOption132;            //      vendor option 132

+  UINT8 VendorOption133;            //      vendor option 133

+  UINT8 VendorOption134;            //      vendor option 134

+  UINT8 VendorOption135;            //      vendor option 135

+} DHCPV4_REQUESTED_OPTIONS_DATA;

+

+typedef struct {

+  DHCPV4_OP_HEADER              Header;

+  DHCPV4_REQUESTED_OPTIONS_DATA Data;

+} DHCPV4_OP_REQUESTED_OPTIONS;

+

+typedef struct opipstr {

+  DHCPV4_OP_HEADER  Header;

+  EFI_IPv4_ADDRESS  Ip;

+} DHCPV4_OP_IP_ADDRESS;

+

+//

+// ip list structure - e.g. router list

+//

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  EFI_IPv4_ADDRESS  IpList[1];

+} DHCPV4_OP_IP_LIST;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Type;

+  UINT8             Guid[sizeof (EFI_GUID)];

+} DHCPV4_OP_CLIENT_ID;

+

+//

+// special options start - someday obsolete ???

+//

+#define DHCPV4_OP_PLATFORM_ID DHCPV4_OP_CLIENT_ID

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             Type; // SNP = 2

+  UINT8             MajorVersion;

+  UINT8             MinorVersion;

+} DHCPV4_OP_NETWORK_INTERFACE;

+

+#define UNDI_TYPE 1

+#define SNP_TYPE  2

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  UINT16            Type;

+} DHCPV4_OP_ARCHITECTURE_TYPE;

+//

+// special options end - someday obsolete ???

+//

+typedef struct {

+  UINT8 ClassIdentifier[10];  // PXEClient:

+  UINT8 Lit2[5];              // Arch:

+  UINT8 ArchitectureType[5];  // 00000 - 65536

+  UINT8 Lit3[1];              // :

+  UINT8 InterfaceName[4];     // e.g. UNDI

+  UINT8 Lit4[1];              // :

+  UINT8 UndiMajor[3];         // 000 - 255

+  UINT8 UndiMinor[3];         // 000 - 255

+} DHCPV4_CLASS_ID_DATA;

+

+typedef struct {

+  DHCPV4_OP_HEADER      Header;

+  DHCPV4_CLASS_ID_DATA  Data;

+} DHCPV4_OP_CLASS_ID;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  EFI_IPv4_ADDRESS  Ip;

+} DHCPV4_OP_REQUESTED_IP;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  EFI_IPv4_ADDRESS  Ip;

+} DHCPV4_OP_SERVER_IP;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  EFI_IPv4_ADDRESS  Ip;

+} DHCPV4_OP_SUBNET_MASK;

+

+typedef struct {              // oppxedisctlstr {

+  DHCPV4_OP_HEADER  Header;

+  UINT8             ControlBits;

+} PXE_OP_DISCOVERY_CONTROL;

+

+#define DISABLE_BCAST   (1 << 0)

+#define DISABLE_MCAST   (1 << 1)

+#define USE_ACCEPT_LIST (1 << 2)

+#define USE_BOOTFILE    (1 << 3)

+

+#pragma pack()

+//

+// definitions of indices to populate option interest array

+//

+#define VEND_PXE_MTFTP_IP_IX              1                     // multicast IP address of bootfile for MTFTP listen

+#define VEND_PXE_MTFTP_CPORT_IX           2                     // UDP Port to monitor for MTFTP responses - Intel order

+#define VEND_PXE_MTFTP_SPORT_IX           3                     // Server UDP Port for MTFTP open - Intel order

+#define VEND_PXE_MTFTP_TMOUT_IX           4                     // Listen timeout - secs

+#define VEND_PXE_MTFTP_DELAY_IX           5                     // Transmission timeout - secs

+#define VEND_PXE_DISCOVERY_CONTROL_IX     6                     // bit field

+#define VEND_PXE_DISCOVERY_MCAST_ADDR_IX  7                     // boot server discovery multicast address

+#define VEND_PXE_BOOT_SERVERS_IX          8                     // list of boot servers of form tp(2) cnt(1) ips[cnt]

+#define VEND_PXE_BOOT_MENU_IX             9

+#define VEND_PXE_BOOT_PROMPT_IX           10

+#define VEND_PXE_MCAST_ADDRS_ALLOC_IX     0                     // not used by PXE client

+#define VEND_PXE_CREDENTIAL_TYPES_IX      11

+#define VEND_13_IX                        0                     // not used by PXE client

+#define VEND_14_IX                        0                     // not used by PXE client

+#define VEND_15_IX                        0                     // not used by PXE client

+#define VEND_16_IX                        0                     // not used by PXE client

+#define VEND_17_IX                        0                     // not used by PXE client

+#define VEND_18_IX                        0                     // not used by PXE client

+#define VEND_19_IX                        0                     // not used by PXE client

+#define VEND_20_IX                        0                     // not used by PXE client

+#define VEND_21_IX                        0                     // not used by PXE client

+#define VEND_22_IX                        0                     // not used by PXE client

+#define VEND_23_IX                        0                     // not used by PXE client

+#define VEND_24_IX                        0                     // not used by PXE client

+#define VEND_25_IX                        0                     // not used by PXE client

+#define VEND_26_IX                        0                     // not used by PXE client

+#define VEND_27_IX                        0                     // not used by PXE client

+#define VEND_28_IX                        0                     // not used by PXE client

+#define VEND_29_IX                        0                     // not used by PXE client

+#define VEND_30_IX                        0                     // not used by PXE client

+#define VEND_31_IX                        0                     // not used by PXE client

+#define VEND_32_IX                        0                     // not used by PXE client

+#define VEND_33_IX                        0                     // not used by PXE client

+#define VEND_34_IX                        0                     // not used by PXE client

+#define VEND_35_IX                        0                     // not used by PXE client

+#define VEND_36_IX                        0                     // not used by PXE client

+#define VEND_37_IX                        0                     // not used by PXE client

+#define VEND_38_IX                        0                     // not used by PXE client

+#define VEND_39_IX                        0                     // not used by PXE client

+#define VEND_40_IX                        0                     // not used by PXE client

+#define VEND_41_IX                        0                     // not used by PXE client

+#define VEND_42_IX                        0                     // not used by PXE client

+#define VEND_43_IX                        0                     // not used by PXE client

+#define VEND_44_IX                        0                     // not used by PXE client

+#define VEND_45_IX                        0                     // not used by PXE client

+#define VEND_46_IX                        0                     // not used by PXE client

+#define VEND_47_IX                        0                     // not used by PXE client

+#define VEND_48_IX                        0                     // not used by PXE client

+#define VEND_49_IX                        0                     // not used by PXE client

+#define VEND_50_IX                        0                     // not used by PXE client

+#define VEND_51_IX                        0                     // not used by PXE client

+#define VEND_52_IX                        0                     // not used by PXE client

+#define VEND_53_IX                        0                     // not used by PXE client

+#define VEND_54_IX                        0                     // not used by PXE client

+#define VEND_55_IX                        0                     // not used by PXE client

+#define VEND_56_IX                        0                     // not used by PXE client

+#define VEND_57_IX                        0                     // not used by PXE client

+#define VEND_58_IX                        0                     // not used by PXE client

+#define VEND_59_IX                        0                     // not used by PXE client

+#define VEND_60_IX                        0                     // not used by PXE client

+#define VEND_61_IX                        0                     // not used by PXE client

+#define VEND_62_IX                        0                     // not used by PXE client

+#define VEND_63_IX                        0                     // not used by PXE client

+#define VEND_64_IX                        0                     // not used by PXE client

+#define VEND_65_IX                        0                     // not used by PXE client

+#define VEND_66_IX                        0                     // not used by PXE client

+#define VEND_67_IX                        0                     // not used by PXE client

+#define VEND_68_IX                        0                     // not used by PXE client

+#define VEND_69_IX                        0                     // not used by PXE client

+#define VEND_70_IX                        0                     // not used by PXE client

+#define VEND_PXE_BOOT_ITEM_IX             12

+

+#define MAX_OUR_PXE_OPT                   VEND_PXE_BOOT_ITEM    // largest PXE option in which we are interested

+#define MAX_OUR_PXE_IX                    VEND_PXE_BOOT_ITEM_IX // largest PXE option index

+//

+// define various types by options that are sent

+//

+#define WfM11a_OPTS   ((1<<VEND_PXE_MTFTP_IP_IX) | \

+                      (1<<VEND_PXE_MTFTP_CPORT_IX) | \

+                      (1<<VEND_PXE_MTFTP_SPORT_IX) | \

+                      (1<<VEND_PXE_MTFTP_TMOUT_IX) | \

+                      (1<<VEND_PXE_MTFTP_DELAY_IX))

+

+#define DISCOVER_OPTS ((1<<VEND_PXE_DISCOVERY_CONTROL_IX) | \

+                      (1<<VEND_PXE_DISCOVERY_MCAST_ADDR_IX) | \

+                      (1<<VEND_PXE_BOOT_SERVERS_IX) | \

+                      (1<<VEND_PXE_BOOT_MENU_IX) | \

+                      (1<<VEND_PXE_BOOT_PROMPT_IX) | \

+                      (1<<VEND_PXE_BOOT_ITEM_IX))

+

+#define CREDENTIALS_OPT (1 << VEND_PXE_CREDENTIAL_TYPES_IX)

+

+//

+// definitions of indices to populate option interest array

+//

+#define OP_SUBNET_MASK_IX                     1

+#define OP_TIME_OFFSET_IX                     0 // not used by PXE client

+#define OP_ROUTER_LIST_IX                     2

+#define OP_TIME_SERVERS_IX                    0 // not used by PXE client

+#define OP_NAME_SERVERS_IX                    0 // not used by PXE client

+#define OP_DNS_SERVERS_IX                     0 // not used by PXE client

+#define OP_LOG_SERVERS_IX                     0 // not used by PXE client

+#define OP_COOKIE_SERVERS_IX                  0 // not used by PXE client

+#define OP_LPR_SREVERS_IX                     0 // not used by PXE client

+#define OP_IMPRESS_SERVERS_IX                 0 // not used by PXE client

+#define OP_RES_LOC_SERVERS_IX                 0 // not used by PXE client

+#define OP_HOST_NAME_IX                       0 // not used by PXE client

+#define OP_BOOT_FILE_SZ_IX                    9

+#define OP_DUMP_FILE_IX                       0 // not used by PXE client

+#define OP_DOMAIN_NAME_IX                     0 // not used by PXE client

+#define OP_SWAP_SERVER_IX                     0 // not used by PXE client

+#define OP_ROOT_PATH_IX                       0 // not used by PXE client

+#define OP_EXTENSION_PATH_IX                  0 // not used by PXE client

+#define OP_IP_FORWARDING_IX                   0 // not used by PXE client

+#define OP_NON_LOCAL_SRC_RTE_IX               0 // not used by PXE client

+#define OP_POLICY_FILTER_IX                   0 // not used by PXE client

+#define OP_MAX_DATAGRAM_SZ_IX                 0 // not used by PXE client

+#define OP_DEFAULT_TTL_IX                     0 // not used by PXE client

+#define OP_MTU_AGING_TIMEOUT_IX               0 // not used by PXE client

+#define OP_MTU_SIZES_IX                       0 // not used by PXE client

+#define OP_MTU_TO_USE_IX                      0 // not used by PXE client

+#define OP_ALL_SUBNETS_LOCAL_IX               0 // not used by PXE client

+#define OP_BROADCAST_ADD_IX                   0 // not used by PXE client

+#define OP_PERFORM_MASK_DISCOVERY_IX          0 // not used by PXE client

+#define OP_RESPOND_TO_MASK_REQ_IX             0 // not used by PXE client

+#define OP_PERFORM_ROUTER_DISCOVERY_IX        0 // not used by PXE client

+#define OP_ROUTER_SOLICIT_ADDRESS_IX          0 // not used by PXE client

+#define OP_STATIC_ROUTER_LIST_IX              0 // not used by PXE client

+#define OP_USE_ARP_TRAILERS_IX                0 // not used by PXE client

+#define OP_ARP_CACHE_TIMEOUT_IX               0 // not used by PXE client

+#define OP_ETHERNET_ENCAPSULATION_IX          0 // not used by PXE client

+#define OP_TCP_DEFAULT_TTL_IX                 0 // not used by PXE client

+#define OP_TCP_KEEP_ALIVE_INT_IX              0 // not used by PXE client

+#define OP_KEEP_ALIVE_GARBAGE_IX              0 // not used by PXE client

+#define OP_NIS_DOMAIN_NAME_IX                 0 // not used by PXE client

+#define OP_NIS_SERVERS_IX                     0 // not used by PXE client

+#define OP_NTP_SERVERS_IX                     0 // not used by PXE client

+#define OP_VENDOR_SPECIFIC_IX                 3

+#define OP_NBNS_SERVERS_IX                    0 // not used by PXE client

+#define OP_NBDD_SERVERS_IX                    0 // not used by PXE client

+#define OP_NETBIOS_NODE_TYPE_IX               0 // not used by PXE client

+#define OP_NETBIOS_SCOPE_IX                   0 // not used by PXE client

+#define OP_XWINDOW_SYSTEM_FONT_SERVERS_IX     0 // not used by PXE client

+#define OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS_IX 0 // not used by PXE client

+// DHCP option indices

+//

+#define OP_DHCP_REQ_IP_ADD_IX         0                 // not used by PXE client

+#define OP_DHCP_LEASE_TIME_IX         0                 // not used by PXE client

+#define OP_DHCP_OPTION_OVERLOAD_IX    4

+#define OP_DHCP_MESSAGE_TYPE_IX       5

+#define OP_DHCP_SERVER_IP_IX          6

+#define OP_DHCP_PARM_REQ_LIST_IX      0                 // not used by PXE client

+#define OP_DHCP_ERROR_MESSAGE_IX      0                 // not used by PXE client

+#define OP_DHCP_MAX_MESSAGE_SZ_IX     0                 // not used by PXE client

+#define OP_DHCP_RENEWAL_TIME_IX       0                 // not used by PXE client

+#define OP_DHCP_REBINDING_TIME_IX     0                 // not used by PXE client

+#define OP_DHCP_CLASS_IDENTIFIER_IX   7

+#define OP_DHCP_CLIENT_IDENTIFIER_IX  0                 // not used by PXE client

+#define OP_RESERVED62_IX              0                 // not used by PXE client

+#define OP_RESERVED63_IX              0                 // not used by PXE client

+#define OP_NISPLUS_DOMAIN_NAME_IX     0                 // not used by PXE client

+#define OP_NISPLUS_SERVERS_IX         0                 // not used by PXE client

+#define OP_DHCP_TFTP_SERVER_NAME_IX   0                 // not used by PXE client

+#define OP_DHCP_BOOTFILE_IX           8

+

+#define MAX_OUR_OPT                   OP_DHCP_BOOTFILE  // largest option in which we are interested

+#define MAX_OUR_IX                    OP_BOOT_FILE_SZ_IX

+

+typedef struct {

+  DHCPV4_OP_STRUCT  *PktOptAdds[MAX_OUR_IX];

+  DHCPV4_OP_STRUCT  *PxeOptAdds[MAX_OUR_PXE_IX];

+  UINT8             Status;

+} OPTION_POINTERS;

+

+typedef struct DhcpReceiveBufferStruct {

+  union {

+    UINT8         ReceiveBuffer[MAX_DHCP_MSG_SZ];

+    DHCPV4_STRUCT Dhcpv4;

+  } u;

+

+  OPTION_POINTERS OpAdds;

+} DHCP_RECEIVE_BUFFER;

+

+#define PXE_TYPE          (1 << 0)

+#define WfM11a_TYPE       (1 << 1)

+#define DISCOVER_TYPE     (1 << 2)

+#define CREDENTIALS_TYPE  (1 << 3)

+#define USE_THREE_BYTE    (1 << 4)

+

+#endif // _DHCP_H

+

+/* EOF - dhcp.h */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/hton.h b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/hton.h
new file mode 100644
index 0000000..b9000c1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/hton.h
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  hton.h

+

+Abstract:

+  Byte swapping macros.

+

+--*/

+

+#ifndef _HTON_H_

+#define _HTON_H_

+

+//

+// Only Intel order functions are defined at this time.

+//

+#define HTONS(v)  (UINT16) ((((v) << 8) & 0xff00) + (((v) >> 8) & 0x00ff))

+

+#define HTONL(v) \

+  (UINT32) ((((v) << 24) & 0xff000000) + (((v) << 8) & 0x00ff0000) + (((v) >> 8) & 0x0000ff00) + (((v) >> 24) & 0x000000ff))

+

+#define HTONLL(v) swap64 (v)

+

+#define U8PTR(na) ((UINT8 *) &(na))

+

+#define NTOHS(ns) ((UINT16) (((*U8PTR (ns)) << 8) +*(U8PTR (ns) + 1)))

+

+#define NTOHL(ns) \

+    ((UINT32) (((*U8PTR (ns)) << 24) + ((*(U8PTR (ns) + 1)) << 16) + ((*(U8PTR (ns) + 2)) << 8) +*(U8PTR (ns) + 3)))

+

+#endif /* _HTON_H_ */

+

+/* EOF - hton.h */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/ip.h b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/ip.h
new file mode 100644
index 0000000..fcfc264
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/ip.h
@@ -0,0 +1,741 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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 _IP_H_

+#define _IP_H_

+

+#include "hton.h"

+

+//

+// Client architecture types

+//

+#define IA64            2

+#define SYS_ARCH_EFI32  6

+

+//

+// portability macros

+//

+#define UDP_FILTER_MASK  (EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | \

+                         EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT | \

+                         EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP | \

+                         EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT | \

+                         EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER \

+          )

+

+#define PXE_BOOT_LAYER_MASK             0x7FFF

+#define PXE_BOOT_LAYER_INITIAL          0x0000

+#define PXE_BOOT_LAYER_CREDENTIAL_FLAG  0x8000

+#define MAX_BOOT_SERVERS                32

+

+//

+// macro to evaluate IP address as TRUE if it is a multicast IP address

+//

+#define IS_MULTICAST(ptr) ((*((UINT8 *) ptr) & 0xf0) == 0xe0)

+

+//

+// length macros

+//

+#define IP_ADDRESS_LENGTH(qp)   (((qp)->UsingIpv6) ? sizeof (EFI_IPv6_ADDRESS) : sizeof (EFI_IPv4_ADDRESS))

+

+#define MAX_FRAME_DATA_SIZE     1488

+#define ALLOCATE_SIZE(X)        (((X) + 7) & 0xfff8)

+#define MODE_ALLOCATE_SIZE      ALLOCATE_SIZE (sizeof (EFI_PXE_BASE_CODE_MODE))

+#define BUFFER_ALLOCATE_SIZE    (8192 + 512)

+#define ROUTER_ALLOCATE_SIZE    ALLOCATE_SIZE ((sizeof (EFI_PXE_BASE_CODE_ROUTE_ENTRY) * PXE_ROUTER_TABLE_SIZE))

+#define ARP_ALLOCATE_SIZE       ALLOCATE_SIZE ((sizeof (EFI_PXE_BASE_CODE_ARP_ENTRY) * PXE_ARP_CACHE_SIZE))

+#define FILTER_ALLOCATE_SIZE    ALLOCATE_SIZE ((sizeof (EFI_IP_ADDRESS) * PXE_IP_FILTER_SIZE))

+#define PXE_ARP_CACHE_SIZE      8

+#define PXE_ROUTER_TABLE_SIZE   8

+#define PXE_IP_FILTER_SIZE      8

+#define ICMP_ALLOCATE_SIZE      ALLOCATE_SIZE (sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR))

+#define TFTP_ERR_ALLOCATE_SIZE  ALLOCATE_SIZE (sizeof (EFI_PXE_BASE_CODE_TFTP_ERROR))

+

+//

+// DHCP discover/request packets are sent to this UDP port.  ProxyDHCP

+// servers listen on this port for DHCP discover packets that have a

+// class identifier (option 60) with 'PXEClient' in the first 9 bytes.

+// Bootservers also listen on this port for PXE broadcast discover

+// requests from PXE clients.

+//

+#define DHCP_SERVER_PORT  67

+

+//

+// When DHCP, proxyDHCP and Bootservers respond to DHCP and PXE broadcast

+// discover requests by broadcasting the reply packet, the packet is

+// broadcast to this port.

+//

+#define DHCP_CLIENT_PORT  68

+

+//

+// TFTP servers listen for TFTP open requests on this port.

+//

+#define TFTP_OPEN_PORT  69

+

+//

+// proxyDHCP and Bootservers listen on this port for a PXE unicast and/or

+// multicast discover requests from PXE clients.  A PXE discover request

+// looks like a DHCP discover or DHCP request packet.

+//

+#define PXE_DISCOVERY_PORT  4011

+

+//

+// This port is used by the PXE client/server protocol tests.

+//

+#define PXE_PORT_PXETEST_PORT 0x8080

+

+//

+// Definitions for Ethertype protocol numbers and interface types

+// Per RFC 1700,

+//

+#define PXE_PROTOCOL_ETHERNET_IP    0x0800

+#define PXE_PROTOCOL_ETHERNET_ARP   0x0806

+#define PXE_PROTOCOL_ETHERNET_RARP  0x8035

+

+#define PXE_IFTYPE_ETHERNET         0x01

+#define PXE_IFTYPE_TOKENRING        0x04

+#define PXE_IFTYPE_FIBRE_CHANNEL    0x12

+

+//

+// Definitions for internet protocol version 4 header

+// Per RFC 791, September 1981.

+//

+#define IPVER4  4

+

+#pragma pack(1) // make network structures packed byte alignment

+typedef union {

+  UINT8   B[4];

+  UINT32  L;

+} IPV4_ADDR;

+

+#define IPV4_HEADER_LENGTH(IpHeaderPtr) (((IpHeaderPtr)->VersionIhl & 0xf) << 2)

+

+#define SET_IPV4_VER_HDL(IpHeaderPtr, IpHeaderLen) { \

+    (IpHeaderPtr)->VersionIhl = (UINT8) ((IPVER4 << 4) | ((IpHeaderLen) >> 2)); \

+  }

+

+typedef struct {

+  UINT8     VersionIhl;

+  UINT8     TypeOfService;

+  UINT16    TotalLength;

+  UINT16    Id;

+  UINT16    FragmentFields;

+  UINT8     TimeToLive;

+  UINT8     Protocol;

+  UINT16    HeaderChecksum;

+  IPV4_ADDR SrcAddr;

+  IPV4_ADDR DestAddr;

+  //

+  // options are not implemented

+  //

+} IPV4_HEADER;

+

+#define IP_FRAG_RSVD    0x8000  // reserved bit - must be zero

+#define IP_NO_FRAG      0x4000  // do not fragment bit

+#define IP_MORE_FRAG    0x2000  // not last fragment

+#define IP_FRAG_OFF_MSK 0x1fff  // fragment offset in 8 byte chunks

+#define DEFAULT_RFC_TTL 64

+

+#define PROT_ICMP       1

+#define PROT_IGMP       2

+#define PROT_TCP        6

+#define PROT_UDP        17

+

+/*

+ * Definitions for internet control message protocol version 4 message

+ * structure.  Per RFC 792, September 1981.

+ */

+

+//

+// icmp header for all icmp messages

+//

+typedef struct {

+  UINT8   Type;     // message type

+  UINT8   Code;     // type specific - 0 for types we implement

+  UINT16  Checksum; // ones complement of ones complement sum of 16 bit words of message

+} ICMPV4_HEADER;

+

+#define ICMP_DEST_UNREACHABLE   3

+#define ICMP_SOURCE_QUENCH      4

+#define ICMP_REDIRECT           5

+#define ICMP_ECHO               8

+#define ICMP_ECHO_REPLY         0

+#define ICMP_ROUTER_ADV         9

+#define ICMP_ROUTER_SOLICIT     10

+#define ICMP_TIME_EXCEEDED      11

+#define ICMP_PARAMETER_PROBLEM  12

+#define ICMP_TIMESTAMP          13

+#define ICMP_TIMESTAMP_REPLY    14

+#define ICMP_INFO_REQ           15

+#define ICMP_INFO_REQ_REPLY     16

+#define ICMP_SUBNET_MASK_REQ    17

+#define ICMP_SUBNET_MASK_REPLY  18

+//

+// other ICMP message types ignored in this implementation

+//

+// icmp general messages

+//

+typedef struct {

+  ICMPV4_HEADER Header;

+  //

+  // generally unused except byte [0] for

+  // parameter problem message

+  //

+  UINT8         GenerallyUnused[4];

+  //

+  // original message ip header of plus 64

+  // bits of data

+  //

+  IPV4_HEADER   IpHeader;

+} ICMPV4_GENERAL_MESSAGE;

+

+//

+// icmp req/rply message header

+//

+typedef struct {

+  ICMPV4_HEADER Header;

+  UINT16        Id;

+  UINT16        SequenceNumber;

+} ICMPV4_REQUEST_REPLY_HEADER;

+

+//

+// icmp echo message

+//

+typedef struct {

+  ICMPV4_REQUEST_REPLY_HEADER Header;

+  UINT8                       EchoData[1];  // variable length data to be echoed

+} ICMPV4_ECHO_MESSAGE;

+

+//

+// icmp timestamp message - times are milliseconds since midnight UT -

+// if non std, set high order bit

+//

+typedef struct {

+  ICMPV4_REQUEST_REPLY_HEADER Header;

+  UINT32                      OriginalTime; // originating timestamp

+  UINT32                      ReceiveTime;  // receiving timestamp

+  UINT32                      TransmitTime; // transmitting timestamp

+} ICMPV4_TIMESTAMP_MESSAGE;

+

+//

+// icmp info request structure - fill in source and dest net ip address on reply

+//

+typedef struct {

+  ICMPV4_REQUEST_REPLY_HEADER Header;

+} ICMPV4_INFO_MESSAGE;

+

+//

+// Definitions for internet control message protocol version 4 message structure

+// Router discovery

+// Per RFC 1256, September 1991.

+//

+//

+// icmp router advertisement message

+//

+typedef struct {

+  ICMPV4_HEADER Header;

+  UINT8         NumberEntries;  // number of address entries

+  UINT8         EntrySize;      // number of 32 bit words per address entry

+  UINT16        Lifetime;       // seconds to consider info valid

+  UINT32        RouterIp;

+  UINT32        Preferance;

+} ICMPV4_ROUTER_ADVERTISE_MESSAGE;

+

+//

+// icmp router solicitation message

+//

+typedef struct {

+  ICMPV4_HEADER Header;

+  UINT32        Reserved;

+} ICMPV4_ROUTER_SOLICIT_MESSAGE;

+

+#define MAX_SOLICITATION_DELAY      1   //  1 second

+#define SOLICITATION_INTERVAL       3   //  3 seconds

+#define MAX_SOLICITATIONS           3   //  3 transmissions

+#define V1ROUTER_PRESENT_TIMEOUT    400 // 400 second timeout until v2 reports can be sent

+#define UNSOLICITED_REPORT_INTERVAL 10  // 10 seconds between unsolicited reports

+#define BROADCAST_IPv4              0xffffffff

+

+//

+// Definitions for address resolution protocol message structure

+// Per RFC 826, November 1982

+//

+typedef struct {

+  UINT16  HwType;     // hardware type - e.g. ethernet (1)

+  UINT16  ProtType;   // protocol type - for ethernet, 0x800 for IP

+  UINT8   HwAddLen;   // byte length of a hardware address (e.g. 6 for ethernet)

+  UINT8   ProtAddLen; // byte length of a protocol address (e.g. 4 for ipv4)

+  UINT16  OpCode;

+  //

+  // source and dest hw and prot addresses follow - see example below

+  //

+} ARP_HEADER;

+

+#define ETHERNET_ADD_SPC  1

+

+#define ETHER_TYPE_IP     0x800

+

+#define ARP_REQUEST       1

+#define ARP_REPLY         2

+

+//

+// generic ARP packet

+//

+typedef struct {

+  ARP_HEADER      ArpHeader;

+  EFI_MAC_ADDRESS SrcHardwareAddr;

+  EFI_IP_ADDRESS  SrcProtocolAddr;

+  EFI_MAC_ADDRESS DestHardwareAddr;

+  EFI_IP_ADDRESS  DestProtocolAddr;

+} ARP_PACKET;

+

+#define ENET_HWADDLEN   6

+#define IPV4_PROTADDLEN 4

+

+//

+// Definitions for user datagram protocol version 4 pseudo header & header

+// Per RFC 768, 28 August 1980

+//

+typedef struct {

+  IPV4_ADDR SrcAddr;      // source ip address

+  IPV4_ADDR DestAddr;     // dest ip address

+  UINT8     Zero;         // 0

+  UINT8     Protocol;     // protocol

+  UINT16    TotalLength;  // UDP length - sizeof udpv4hdr + data length

+} UDPV4_PSEUDO_HEADER;

+

+typedef struct {

+  UINT16  SrcPort;        // source port identifier

+  UINT16  DestPort;       // destination port identifier

+  UINT16  TotalLength;    // total length header plus data

+  //

+  // ones complement of ones complement sum of 16 bit

+  // words of pseudo header, UDP header, and data

+  // zero checksum is transmitted as -0 (ones comp)

+  // zero transmitted means checksum not computed

+  // data follows

+  //

+  UINT16  Checksum;      

+} UDPV4_HEADER;

+

+typedef struct {

+  UDPV4_PSEUDO_HEADER Udpv4PseudoHeader;

+  UDPV4_HEADER        Udpv4Header;

+} UDPV4_HEADERS;

+

+//

+// Definitions for transmission control protocol header

+// Per RFC 793, September, 1981

+//

+typedef struct {

+  IPV4_ADDR SrcAddr;      // source ip address

+  IPV4_ADDR DestAddr;     // dest ip address

+  UINT8     Zero;         // 0

+  UINT8     Protocol;     // protocol

+  UINT16    TotalLength;  // TCP length - TCP header length + data length

+} TCPV4_PSEUDO_HEADER;

+

+typedef struct {

+  UINT16  SrcPort;        // source port identifier

+  UINT16  DestPort;       // destination port identifier

+  UINT32  SeqNumber;      // Sequence number

+  UINT32  AckNumber;      // Acknowledgement Number

+  //

+  // Nibble of HLEN (length of header in 32-bit multiples)

+  // 6bits of RESERVED

+  // Nibble of Code Bits

+  //

+  UINT16  HlenResCode;

+  UINT16  Window;   // Software buffer size (sliding window size) in network-standard byte order

+  //

+  // ones complement of ones complement sum of 16 bit words of

+  // pseudo header, TCP header, and data

+  // zero checksum is transmitted as -0 (ones comp)

+  // zero transmitted means checksum not computed

+  //

+  UINT16  Checksum; 

+  UINT16  UrgentPointer;                // pointer to urgent data (allows sender to specify urgent data)

+} TCPV4_HEADER;

+

+typedef struct {

+  TCPV4_PSEUDO_HEADER Tcpv4PseudoHeader;

+  TCPV4_HEADER        Tcpv4Header;

+} TCPV4_HEADERS;

+

+typedef struct {

+  UINT8 Kind;                           // one of the following:

+  UINT8 Length;                         // total option length including Kind and Lth

+  UINT8 Data[1];                        // length = Lth - 2

+} TCPV4_OPTION;

+

+#define TCP_OP_END                0     // only used to pad to end of TCP header

+#define TCP_NOP                   1     // optional - may be used to pad between options to get alignment

+#define TCP_MAX_SEG               2     // maximum receive segment size - only send at initial connection request

+#define MAX_MEDIA_HDR_SIZE        64

+#define MIN_ENET_DATA_SIZE        64

+#define MAX_ENET_DATA_SIZE        1500  // temp def - make a network based var

+#define MAX_IPV4_PKT_SIZE         65535 // maximum IP packet size

+#define MAX_IPV4_DATA_SIZE        (MAX_IPV4_PKT_SIZE - sizeof (IPV4_HEADER))

+#define MAX_IPV4_FRAME_DATA_SIZE  (MAX_FRAME_DATA_SIZE - sizeof (IPV4_HEADER))

+#define REAS_IPV4_PKT_SIZE        576   // minimum IP packet size all IP host can handle

+#define REAS_IPV4_DATA_SIZE       (REAS_IPV4_PKT_SIZE - sizeof (IPV4_HEADER))

+

+//

+//

+//

+typedef union {

+  UINT8           Data[MAX_ENET_DATA_SIZE];

+  ICMPV4_HEADER   IcmpHeader;

+  IGMPV2_MESSAGE  IgmpMessage;

+  struct {

+    UDPV4_HEADER  UdpHeader;

+    UINT8         Data[1];

+  } Udp;

+  struct {

+    TCPV4_HEADER  TcpHeader;

+    UINT8         Data[1];

+  } Tcp;

+} PROTOCOL_UNION;

+

+//

+// out buffer structure

+//

+typedef struct {

+  UINT8           MediaHeader[MAX_MEDIA_HDR_SIZE];

+  IPV4_HEADER     IpHeader;

+  //

+  // following union placement only valid if no option IP header

+  //

+  PROTOCOL_UNION  u;

+} IPV4_BUFFER;

+

+typedef struct {

+  IPV4_HEADER     IpHeader;

+  //

+  // following union placement only valid if no option IP header

+  //

+  PROTOCOL_UNION  u;

+} IPV4_STRUCT;

+

+#pragma pack()  // reset to default

+  

+  ////////////////////////////////////////////////////////////

+//

+//  BC IP Filter Routine

+//

+EFI_STATUS

+IpFilter (

+  PXE_BASECODE_DEVICE            *Private,

+  IN EFI_PXE_BASE_CODE_IP_FILTER *Filter

+  )

+;

+

+//

+// //////////////////////////////////////////////////////////////////////

+//

+//  Udp Write Routine - called by base code - e.g. TFTP - already locked

+//

+EFI_STATUS

+UdpWrite (

+  IN PXE_BASECODE_DEVICE                      *Private,

+  IN UINT16                                   OpFlags,

+  IN EFI_IP_ADDRESS                           *DestIpPtr,

+  IN EFI_PXE_BASE_CODE_UDP_PORT               *DestPortptr,

+  IN EFI_IP_ADDRESS                           *GatewayIpPtr, OPTIONAL

+  IN EFI_IP_ADDRESS                           *SrcIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT           *SrcPortPtr, OPTIONAL

+  IN UINTN                                    *HeaderSizePtr, OPTIONAL

+  IN VOID                                     *HeaderPtr, OPTIONAL

+  IN UINTN                                    *BufferSizePtr,

+  IN VOID                                     *BufferPtr

+  )

+;

+

+//

+// /////////////////////////////////////////////////////////////////////

+//

+//  Udp Read Routine - called by base code - e.g. TFTP - already locked

+//

+EFI_STATUS

+UdpRead (

+  IN PXE_BASECODE_DEVICE            *Private,

+  IN UINT16                         OpFlags,

+  IN OUT EFI_IP_ADDRESS             *DestIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPorPtrt, OPTIONAL

+  IN OUT EFI_IP_ADDRESS             *SrcIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL

+  IN UINTN                          *HeaderSizePtr, OPTIONAL

+  IN VOID                           *HeaderPtr, OPTIONAL

+  IN OUT UINTN                      *BufferSizePtr,

+  IN VOID                           *BufferPtr,

+  IN EFI_EVENT                      TimeoutEvent

+  )

+;

+

+VOID

+IgmpLeaveGroup (

+  PXE_BASECODE_DEVICE *Private,

+  EFI_IP_ADDRESS      *

+  )

+;

+

+VOID

+IgmpJoinGroup (

+  PXE_BASECODE_DEVICE *Private,

+  EFI_IP_ADDRESS      *

+  )

+;

+

+//

+// convert number to zero filled ascii value of length lth

+//

+VOID

+CvtNum (

+  UINTN Number,

+  UINT8 *BufferPtr,

+  INTN  BufferLen

+  )

+;

+

+//

+// convert number to ascii string at ptr

+//

+VOID

+UtoA10 (

+  UINTN Number,

+  UINT8 *BufferPtr

+  )

+;

+

+//

+// convert ascii numeric string to UINTN

+//

+UINTN

+AtoU (

+  UINT8 *BufferPtr

+  )

+;

+

+UINT64

+AtoU64 (

+  UINT8 *BufferPtr

+  )

+;

+

+//

+// calculate the internet checksum (RFC 1071)

+// return 16 bit ones complement of ones complement sum of 16 bit words

+//

+UINT16

+IpChecksum (

+  UINT16 *MessagePtr,

+  UINTN  ByteLength

+  )

+;

+

+//

+// do checksum on non contiguous header and data

+//

+UINT16

+IpChecksum2 (

+  UINT16 *Header,

+  UINTN  HeaderLength,

+  UINT16 *Message,

+  UINTN  MessageLength

+  )

+;

+

+//

+// update checksum when only a single word changes

+//

+UINT16

+UpdateChecksum (

+  UINT16 OldChecksum,

+  UINT16 OldWord,

+  UINT16 NewWord

+  )

+;

+

+VOID

+SeedRandom (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN UINT16               InitialSeed

+  )

+;

+

+UINT16

+Random (

+  IN PXE_BASECODE_DEVICE  *Private

+  )

+;

+

+EFI_STATUS

+SendPacket (

+  PXE_BASECODE_DEVICE           *Private,

+  VOID                          *HeaderPtr,

+  VOID                          *PacketPtr,

+  INTN                          PacketLength,

+  VOID                          *HardwareAddress,

+  UINT16                        MediaProtocol,

+  IN EFI_PXE_BASE_CODE_FUNCTION Function

+  )

+;

+

+VOID

+HandleArpReceive (

+  PXE_BASECODE_DEVICE *Private,

+  ARP_PACKET          *ArpPacketPtr,

+  VOID                *HeaderPtr

+  )

+;

+

+VOID

+HandleIgmp (

+  PXE_BASECODE_DEVICE *Private,

+  IGMPV2_MESSAGE      *IgmpMessageptr,

+  UINTN               IgmpMessageLen

+  )

+;

+

+VOID

+IgmpCheckTimers (

+  PXE_BASECODE_DEVICE *Private

+  )

+;  // poll when doing a receive

+// return hw add of IP and TRUE if available, otherwise FALSE

+//

+BOOLEAN

+GetHwAddr (

+  IN PXE_BASECODE_DEVICE  *Private,

+  EFI_IP_ADDRESS          *ProtocolAddressPtr,

+  EFI_MAC_ADDRESS         *HardwareAddressPtr

+  )

+;

+

+EFI_STATUS

+DoArp (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN EFI_IP_ADDRESS       *ProtocolAddressPtr,

+  OUT EFI_MAC_ADDRESS     *HardwareAddressptr

+  )

+;

+

+BOOLEAN

+OnSameSubnet (

+  UINTN           IpAddressLen,

+  EFI_IP_ADDRESS  *Ip1,

+  EFI_IP_ADDRESS  *Ip2,

+  EFI_IP_ADDRESS  *SubnetMask

+  )

+;

+

+VOID

+IpAddRouter (

+  PXE_BASECODE_DEVICE *Private,

+  EFI_IP_ADDRESS      *RouterIp

+  )

+;

+

+#define Ip4AddRouter(Private, Ipv4Ptr)  IpAddRouter (Private, (EFI_IP_ADDRESS *) Ipv4Ptr)

+

+//

+// routine to send ipv4 packet

+// ipv4 + upper protocol header for length TotHdrLth in xmtbuf, ipv4 header length IpHdrLth

+// routine fills in ipv4hdr Ver_Hdl, TotLth, and Checksum, moves in Data, and gets dest MAC address

+//

+EFI_STATUS

+Ipv4Xmt (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT32                      GatewayIP,

+  UINTN                       IpHeaderLen,

+  UINTN                       TotalHeaderLen,

+  VOID                        *Data,

+  UINTN                       DataLen,

+  EFI_PXE_BASE_CODE_FUNCTION  Function

+  )

+;

+

+//

+// send ipv4 packet with ipv4 option

+//

+EFI_STATUS

+Ipv4SendWOp (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT32                      GatewayIP,

+  UINT8                       *MessagePtr,

+  UINTN                       MessageLth,

+  UINT8                       Protocol,

+  UINT8                       *Option,

+  UINTN                       OptionLen,

+  UINT32                      DestIp,

+  EFI_PXE_BASE_CODE_FUNCTION  Function

+  )

+;

+

+//

+// send MsgLth message at MsgPtr - higher level protocol header already in xmtbuf, length HdrSize

+//

+EFI_STATUS

+Ip4Send (

+  IN PXE_BASECODE_DEVICE  *Private,     // pointer to instance data

+  IN UINTN                MayFragment,  //

+  IN UINT8                Protocol,     // protocol

+  IN UINT32               SrcIp,        // Source IP address

+  IN UINT32               DestIp,       // Destination IP address

+  IN UINT32               GatewayIp,    // used if not NULL and needed

+  IN UINTN                HeaderSize,   // protocol header byte length

+  IN UINT8                *MsgPtr,      // pointer to data

+  IN UINTN                MsgLength

+  )

+;                                    // data byte length

+// receive up to MsgLth message into MsgPtr for protocol Prot

+// return message length, src/dest ips if select any, and pointer to protocol header

+//

+EFI_STATUS

+IpReceive (

+  IN PXE_BASECODE_DEVICE    *Private,   // pointer to instance data

+  UINT16                    OpFlags,    // Flags to determine if filtering on IP addresses

+  EFI_IP_ADDRESS            *SrcIpPtr,  // if filtering, O if accept any

+  EFI_IP_ADDRESS            *DstIpPtr,  // if filtering, O if accept any

+  UINT8                     Protocol,   // protocol

+  VOID                      *HeaderPtr, // address of where to put protocol header

+  UINTN                     HeaderSize, // protocol header byte length

+  UINT8                     *MsgPtr,    // pointer to data buffer

+  UINTN                     *MsgLenPtr, // pointer to data buffer length/ O - returned data length

+  IN EFI_EVENT              TimeoutEvent

+  )

+;

+

+#if 0

+VOID

+WaitForTxComplete (

+  IN PXE_BASECODE_DEVICE    *Private

+  )

+;

+#endif

+//

+// routine to cycle waiting for a receive or timeout

+//

+EFI_STATUS

+WaitForReceive (

+  IN PXE_BASECODE_DEVICE        *Private,

+  IN EFI_PXE_BASE_CODE_FUNCTION Function,

+  IN EFI_EVENT                  TimeoutEvent,

+  IN OUT UINTN                  *HeaderSizePtr,

+  IN OUT UINTN                  *BufferSizePtr,

+  IN OUT UINT16                 *ProtocolPtr

+  )

+;

+

+#endif /* _IP_H_ */

+

+/* EOF - ip.h */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_arp.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_arp.c
new file mode 100644
index 0000000..15a056a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_arp.c
@@ -0,0 +1,617 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  pxe_bc_arp.c

+

+Abstract:

+

+--*/

+

+

+#include "Bc.h"

+

+//

+// Definitions for ARP

+// Per RFC 826

+//

+STATIC ARP_HEADER ArpHeader;

+

+#pragma pack(1)

+STATIC struct {

+  UINT8       MediaHeader[14];

+  ARP_HEADER  ArpHeader;

+  UINT8       ArpData[64];

+} ArpReplyPacket;

+#pragma pack()

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+InitArpHeader (

+  VOID

+  )

+/*++

+Routine description:

+  Initialize ARP packet header.

+

+Parameters:

+  none

+

+Returns:

+  none

+

+--*/

+{

+  ArpHeader.HwType      = HTONS (ETHERNET_ADD_SPC);

+  ArpHeader.ProtType    = HTONS (ETHER_TYPE_IP);

+  ArpHeader.HwAddLen    = ENET_HWADDLEN;

+  ArpHeader.ProtAddLen  = IPV4_PROTADDLEN;

+  ArpHeader.OpCode      = HTONS (ARP_REQUEST);

+

+  CopyMem (&ArpReplyPacket.ArpHeader, &ArpHeader, sizeof (ARP_HEADER));

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+HandleArpReceive (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN ARP_PACKET           *ArpPacketPtr,

+  IN VOID                 *MediaHeader

+  )

+/*++

+Routine description:

+  Process ARP packet.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  ArpPacketPtr := Pointer to ARP packet

+  MediaHeader := Pointer to media header.

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  EFI_SIMPLE_NETWORK_MODE *SnpMode;

+  EFI_MAC_ADDRESS         TmpMacAddr;

+  UINTN                   Index;

+  UINT8                   *SrcHwAddr;

+  UINT8                   *SrcPrAddr;

+  UINT8                   *DstHwAddr;

+  UINT8                   *DstPrAddr;

+  UINT8                   *TmpPtr;

+

+  //

+  //

+  //

+  PxeBcMode = Private->EfiBc.Mode;

+  SnpMode   = Private->SimpleNetwork->Mode;

+

+  //

+  // For now only ethernet addresses are supported.

+  // This will need to be updated when other media

+  // layers are supported by PxeBc, Snp and UNDI.

+  //

+  if (ArpPacketPtr->ArpHeader.HwType != HTONS (ETHERNET_ADD_SPC)) {

+    return ;

+  }

+  //

+  // For now only IP protocol addresses are supported.

+  // This will need to be updated when other protocol

+  // types are supported by PxeBc, Snp and UNDI.

+  //

+  if (ArpPacketPtr->ArpHeader.ProtType != HTONS (ETHER_TYPE_IP)) {

+    return ;

+  }

+  //

+  // For now only SNP hardware address sizes are supported.

+  //

+  if (ArpPacketPtr->ArpHeader.HwAddLen != SnpMode->HwAddressSize) {

+    return ;

+  }

+  //

+  // For now only PxeBc protocol address sizes are supported.

+  //

+  if (ArpPacketPtr->ArpHeader.ProtAddLen != Private->IpLength) {

+    return ;

+  }

+  //

+  // Ignore out of range opcodes

+  //

+  switch (ArpPacketPtr->ArpHeader.OpCode) {

+  case HTONS (ARP_REPLY):

+  case HTONS (ARP_REQUEST):

+    break;

+

+  default:

+    return ;

+  }

+  //

+  // update entry in our ARP cache if we have it

+  //

+  SrcHwAddr = (UINT8 *) &ArpPacketPtr->SrcHardwareAddr;

+  SrcPrAddr = SrcHwAddr + SnpMode->HwAddressSize;

+

+  for (Index = 0; Index < PxeBcMode->ArpCacheEntries; ++Index) {

+    if (CompareMem (

+          &PxeBcMode->ArpCache[Index].IpAddr,

+          SrcPrAddr,

+          Private->IpLength

+          )) {

+      continue;

+    }

+

+    CopyMem (

+      &PxeBcMode->ArpCache[Index].MacAddr,

+      SrcHwAddr,

+      SnpMode->HwAddressSize

+      );

+

+    break;

+  }

+  //

+  // Done if ARP packet was not for us.

+  //

+  DstHwAddr = SrcPrAddr + Private->IpLength;

+  DstPrAddr = DstHwAddr + SnpMode->HwAddressSize;

+

+  if (CompareMem (DstPrAddr, &PxeBcMode->StationIp, Private->IpLength)) {

+    return ;

+    //

+    // not for us

+    //

+  }

+  //

+  // for us - if we did not update entry, add it

+  //

+  if (Index == PxeBcMode->ArpCacheEntries) {

+    //

+    // if we have a full table, get rid of oldest

+    //

+    if (Index == PXE_ARP_CACHE_SIZE) {

+      Index = Private->OldestArpEntry;

+

+      if (++Private->OldestArpEntry == PXE_ARP_CACHE_SIZE) {

+        Private->OldestArpEntry = 0;

+      }

+    } else {

+      ++PxeBcMode->ArpCacheEntries;

+    }

+

+    CopyMem (

+      &PxeBcMode->ArpCache[Index].MacAddr,

+      SrcHwAddr,

+      SnpMode->HwAddressSize

+      );

+

+    CopyMem (

+      &PxeBcMode->ArpCache[Index].IpAddr,

+      SrcPrAddr,

+      Private->IpLength

+      );

+  }

+  //

+  // if this is not a request or we don't yet have an IP, finished

+  //

+  if (ArpPacketPtr->ArpHeader.OpCode != HTONS (ARP_REQUEST) || !Private->GoodStationIp) {

+    return ;

+  }

+  //

+  // Assemble ARP reply.

+  //

+  //

+  // Create media header.  [ dest mac | src mac | prot ]

+  //

+  CopyMem (

+    &ArpReplyPacket.MediaHeader[0],

+    SrcHwAddr,

+    SnpMode->HwAddressSize

+    );

+

+  CopyMem (

+    &ArpReplyPacket.MediaHeader[SnpMode->HwAddressSize],

+    &SnpMode->CurrentAddress,

+    SnpMode->HwAddressSize

+    );

+

+  CopyMem (

+    &ArpReplyPacket.MediaHeader[2 * SnpMode->HwAddressSize],

+    &((UINT8 *) MediaHeader)[2 * SnpMode->HwAddressSize],

+    sizeof (UINT16)

+    );

+

+  //

+  // ARP reply header is almost filled in,

+  // just insert the correct opcode.

+  //

+  ArpReplyPacket.ArpHeader.OpCode = HTONS (ARP_REPLY);

+

+  //

+  // Now fill in ARP data.  [ src mac | src prot | dest mac | dest prot ]

+  //

+  TmpPtr = ArpReplyPacket.ArpData;

+  CopyMem (TmpPtr, &SnpMode->CurrentAddress, SnpMode->HwAddressSize);

+

+  TmpPtr += SnpMode->HwAddressSize;

+  CopyMem (TmpPtr, &PxeBcMode->StationIp, Private->IpLength);

+

+  TmpPtr += Private->IpLength;

+  CopyMem (TmpPtr, SrcHwAddr, SnpMode->HwAddressSize);

+

+  TmpPtr += SnpMode->HwAddressSize;

+  CopyMem (TmpPtr, SrcPrAddr, Private->IpLength);

+

+  //

+  // Now send out the ARP reply.

+  //

+  CopyMem (&TmpMacAddr, SrcHwAddr, sizeof (EFI_MAC_ADDRESS));

+

+  SendPacket (

+    Private,

+    &ArpReplyPacket.MediaHeader,

+    &ArpReplyPacket.ArpHeader,

+    sizeof (ARP_HEADER) + 2 * (Private->IpLength + SnpMode->HwAddressSize),

+    &TmpMacAddr,

+    PXE_PROTOCOL_ETHERNET_ARP,

+    EFI_PXE_BASE_CODE_FUNCTION_ARP

+    );

+

+  //

+  // Give time (100 microseconds) for ARP reply to get onto wire.

+  //

+  gBS->Stall (1000);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+BOOLEAN

+GetHwAddr (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN EFI_IP_ADDRESS       *ProtocolAddrPtr,

+  OUT EFI_MAC_ADDRESS     *HardwareAddrPtr

+  )

+/*++

+Routine description:

+  Locate IP address in ARP cache and return MAC address.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  ProtocolAddrPtr := Pointer to IP address

+  HardwareAddrPtr := Pointer to MAC address storage

+

+Returns:

+  TRUE := If IP address was found and MAC address was stored

+  FALSE := If IP address was not found

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  UINTN                   HardwareAddrLength;

+  UINTN                   Index;

+

+  PxeBcMode           = Private->EfiBc.Mode;

+  HardwareAddrLength  = Private->SimpleNetwork->Mode->HwAddressSize;

+

+  for (Index = 0; Index < PxeBcMode->ArpCacheEntries; ++Index) {

+    if (!CompareMem (

+          ProtocolAddrPtr,

+          &PxeBcMode->ArpCache[Index].IpAddr,

+          Private->IpLength

+          )) {

+      CopyMem (

+        HardwareAddrPtr,

+        &PxeBcMode->ArpCache[Index].MacAddr,

+        HardwareAddrLength

+        );

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+SendRequest (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN EFI_IP_ADDRESS       *ProtocolAddrPtr,

+  IN EFI_MAC_ADDRESS      *HardwareAddrPtr

+  )

+/*++

+Routine description:

+  Transmit ARP request packet

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  ProtocolAddrPtr := Pointer IP address to find

+  HardwareAddrPtr := Pointer to MAC address to find

+

+Returns:

+  EFI_SUCCESS := ARP request sent

+  other := ARP request could not be sent

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  EFI_SIMPLE_NETWORK_MODE *SnpMode;

+  ARP_PACKET              *ArpPacket;

+  EFI_STATUS              Status;

+  UINTN                   HardwareAddrLength;

+  UINT8                   *SrcProtocolAddrPtr;

+  UINT8                   *DestHardwareAddrptr;

+  UINT8                   *DestProtocolAddrPtr;

+

+  //

+  //

+  //

+  PxeBcMode           = Private->EfiBc.Mode;

+  SnpMode             = Private->SimpleNetwork->Mode;

+  HardwareAddrLength  = SnpMode->HwAddressSize;

+

+  //

+  // Allocate ARP buffer

+  //

+  if (Private->ArpBuffer == NULL) {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    SnpMode->MediaHeaderSize + sizeof (ARP_PACKET),

+                    (VOID **) &Private->ArpBuffer

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  ArpPacket = (VOID *) (Private->ArpBuffer + SnpMode->MediaHeaderSize);

+

+  //

+  // for now, only handle one kind of hw and pr address

+  //

+  ArpPacket->ArpHeader            = ArpHeader;

+  ArpPacket->ArpHeader.HwAddLen   = (UINT8) HardwareAddrLength;

+  ArpPacket->ArpHeader.ProtAddLen = (UINT8) Private->IpLength;

+

+  //

+  // rest more generic

+  //

+  SrcProtocolAddrPtr  = (UINT8 *) (&ArpPacket->SrcHardwareAddr) + HardwareAddrLength;

+  DestHardwareAddrptr = SrcProtocolAddrPtr + Private->IpLength;

+  DestProtocolAddrPtr = DestHardwareAddrptr + HardwareAddrLength;

+

+  CopyMem (DestProtocolAddrPtr, ProtocolAddrPtr, Private->IpLength);

+  CopyMem (DestHardwareAddrptr, HardwareAddrPtr, HardwareAddrLength);

+  CopyMem (SrcProtocolAddrPtr, &PxeBcMode->StationIp, Private->IpLength);

+  CopyMem (

+    &ArpPacket->SrcHardwareAddr,

+    &SnpMode->CurrentAddress,

+    HardwareAddrLength

+    );

+

+  return SendPacket (

+          Private,

+          Private->ArpBuffer,

+          ArpPacket,

+          sizeof (ARP_HEADER) + ((Private->IpLength + HardwareAddrLength) << 1),

+          &SnpMode->BroadcastAddress,

+          PXE_PROTOCOL_ETHERNET_ARP,

+          EFI_PXE_BASE_CODE_FUNCTION_ARP

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// check for address - if not there, send ARP request, wait and check again

+// not how it would be done in a full system

+//

+#define ARP_REQUEST_TIMEOUT_MS  500 // try for half a second

+  

+  ////////////////////////////////////////////////////////////

+//

+//  BC Arp Routine

+//

+EFI_STATUS

+EFIAPI

+BcArp (

+  IN EFI_PXE_BASE_CODE_PROTOCOL * This,

+  IN EFI_IP_ADDRESS             * ProtocolAddrPtr,

+  OUT EFI_MAC_ADDRESS           * HardwareAddrPtr OPTIONAL

+  )

+/*++

+Routine description:

+  PxeBc ARP API.

+

+Parameters:

+  This := Pointer to PxeBc interface

+  ProtocolAddrPtr := Pointer to IP address to find

+  HardwareAddrPtr := Pointer to MAC address found.

+

+Returns:

+--*/

+{

+  EFI_MAC_ADDRESS     Mac;

+  EFI_STATUS          StatCode;

+  PXE_BASECODE_DEVICE *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  DEBUG ((EFI_D_INFO, "\nBcArp()"));

+

+  //

+  // Issue BC command

+  //

+  if (ProtocolAddrPtr == NULL) {

+    DEBUG (

+      (EFI_D_INFO,

+      "\nBcArp()  Exit #1  %Xh (%r)",

+      EFI_INVALID_PARAMETER,

+      EFI_INVALID_PARAMETER)

+      );

+

+    EfiReleaseLock (&Private->Lock);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (HardwareAddrPtr == NULL) {

+    HardwareAddrPtr = &Mac;

+  }

+

+  ZeroMem (HardwareAddrPtr, Private->SimpleNetwork->Mode->HwAddressSize);

+

+  if (GetHwAddr (Private, ProtocolAddrPtr, HardwareAddrPtr)) {

+    DEBUG (

+      (EFI_D_INFO,

+      "\nBcArp()  Exit #2  %Xh (%r)",

+      EFI_SUCCESS,

+      EFI_SUCCESS)

+      );

+

+    EfiReleaseLock (&Private->Lock);

+    return EFI_SUCCESS;

+  }

+

+  StatCode = DoArp (Private, ProtocolAddrPtr, HardwareAddrPtr);

+

+  DEBUG ((EFI_D_INFO, "\nBcArp()  Exit #3  %Xh (%r)", StatCode, StatCode));

+

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+DoArp (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN EFI_IP_ADDRESS       *ProtocolAddrPtr,

+  OUT EFI_MAC_ADDRESS     *HardwareAddrPtr

+  )

+/*++

+Routine description:

+  Internal ARP implementation.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  ProtocolAddrPtr := Pointer to IP address to find

+  HardwareAddrPtr := Pointer to MAC address found

+

+Returns:

+  EFI_SUCCESS := MAC address found

+  other := MAC address could not be found

+--*/

+{

+  EFI_STATUS  StatCode;

+  EFI_EVENT   TimeoutEvent;

+  UINTN       HeaderSize;

+  UINTN       BufferSize;

+  UINT16      Protocol;

+

+  DEBUG ((EFI_D_INFO, "\nDoArp()"));

+

+  //

+  //

+  //

+  StatCode = SendRequest (Private, ProtocolAddrPtr, HardwareAddrPtr);

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG ((EFI_D_INFO, "\nDoArp()  Exit #1  %Xh (%r)", StatCode, StatCode));

+    return StatCode;

+  }

+  //

+  //

+  //

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &TimeoutEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    return StatCode;

+  }

+

+  StatCode = gBS->SetTimer (

+                    TimeoutEvent,

+                    TimerRelative,

+                    ARP_REQUEST_TIMEOUT_MS * 10000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return StatCode;

+  }

+  //

+  //

+  //

+  for (;;) {

+    StatCode = WaitForReceive (

+                Private,

+                EFI_PXE_BASE_CODE_FUNCTION_ARP,

+                TimeoutEvent,

+                &HeaderSize,

+                &BufferSize,

+                &Protocol

+                );

+

+    if (EFI_ERROR (StatCode)) {

+      break;

+    }

+

+    if (Protocol != PXE_PROTOCOL_ETHERNET_ARP) {

+      continue;

+    }

+

+    HandleArpReceive (

+      Private,

+      (ARP_PACKET *) (Private->ReceiveBufferPtr + HeaderSize),

+      Private->ReceiveBufferPtr

+      );

+

+    if (GetHwAddr (Private, ProtocolAddrPtr, HardwareAddrPtr)) {

+      break;

+    }

+  }

+

+  DEBUG (

+    (EFI_D_INFO,

+    "\nDoArp()  Exit #2  %Xh, (%r)",

+    StatCode,

+    StatCode)

+    );

+

+  gBS->CloseEvent (TimeoutEvent);

+

+  return StatCode;

+}

+

+/* eof - pxe_bc_arp.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
new file mode 100644
index 0000000..c493c99
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
@@ -0,0 +1,3332 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  pxe_bc_dhcp.c

+  

+Abstract:

+  DHCP and PXE discovery protocol implementations.

+

+--*/

+

+

+#include "Bc.h"

+

+STATIC EFI_PXE_BASE_CODE_UDP_PORT DhcpServerPort        = DHCP_SERVER_PORT;

+STATIC EFI_PXE_BASE_CODE_UDP_PORT DHCPClientPort        = DHCP_CLIENT_PORT;

+STATIC EFI_PXE_BASE_CODE_UDP_PORT PseudoDhcpServerPort  = PXE_DISCOVERY_PORT;

+#define PSEUDO_DHCP_CLIENT_PORT PseudoDhcpServerPort

+STATIC EFI_IP_ADDRESS             BroadcastIP       = { { 0xffffffff } };

+STATIC EFI_IP_ADDRESS             DefaultSubnetMask = { { 0xffffff00 } };

+

+typedef union {

+  DHCPV4_OP_STRUCT          *OpPtr;

+  PXE_OP_SERVER_LIST        *BootServersStr;

+  PXE_SERVER_LIST           *BootServerList;

+  PXE_BOOT_MENU_ENTRY       *BootMenuItem;

+  PXE_OP_DISCOVERY_CONTROL  *DiscoveryControl;

+  PXE_OP_BOOT_MENU          *BootMenu;

+  PXE_OP_BOOT_ITEM          *BootItem;

+  DHCPV4_OP_VENDOR_OPTIONS  *VendorOptions;

+  DHCPV4_OP_OVERLOAD        *Overload;

+  DHCPV4_OP_CLASS           *PxeClassStr;

+  DHCPV4_OP_SUBNET_MASK     *SubnetMaskStr;

+  DHCPV4_OP_MESSAGE_TYPE    *MessageType;

+  UINT8                     *BytePtr;

+} UNION_PTR;

+

+//

+// 1 for Itanium-based, 0 for IA32

+//

+#define IA64SZ    ((sizeof (UINTN) / sizeof (UINT32)) - 1)

+

+#define SYS_ARCH  (SYS_ARCH_EFI32 - (SYS_ARCH_EFI32 - IA64) * IA64SZ)

+

+#pragma pack(1)

+//

+// option structure for DHCPREQUEST at end of DISCOVER options

+// and for DHCPDECLINE

+//

+STATIC const struct requestopendstr {

+  DHCPV4_OP_REQUESTED_IP  OpReqIP;

+  DHCPV4_OP_SERVER_IP     DhcServerIpPtr;

+  UINT8                   End[1];

+}

+RequestOpEndStr = {

+  {

+    {

+      OP_DHCP_REQ_IP_ADD,

+      DHCPV4_OPTION_LENGTH(DHCPV4_OP_REQUESTED_IP)

+    }

+  },

+  {

+    {

+      OP_DHCP_SERVER_IP,

+      DHCPV4_OPTION_LENGTH(DHCPV4_OP_SERVER_IP)

+    }

+  },

+  {

+    OP_END

+  }

+};

+

+#define DHCP_REQ_OPTIONS  (*(struct requestopendstr *) DHCPV4_OPTIONS_BUFFER.End)

+

+PXE_OP_BOOT_ITEM                DefaultBootItem = {

+  {

+    VEND_PXE_BOOT_ITEM,

+    DHCPV4_OPTION_LENGTH(PXE_OP_BOOT_ITEM)

+  },

+    0, 0,

+};

+

+//

+// PXE discovery control default structure

+//

+STATIC PXE_OP_DISCOVERY_CONTROL DefaultDisCtl = {

+  { VEND_PXE_DISCOVERY_CONTROL, DHCPV4_OPTION_LENGTH(PXE_OP_DISCOVERY_CONTROL) },

+  0

+};

+

+//

+// PXE credentials option structure

+//

+typedef struct {

+  UINT8 c[4];

+} PXE_CREDENTIAL;

+

+typedef struct {

+  DHCPV4_OP_HEADER  Header;

+  PXE_CREDENTIAL    Credentials[1];

+} PXE_OP_CREDENTIAL_TYPES;

+

+//

+// option structure for PXE discover (without credentials)

+//

+typedef struct {            // discoveropendstr {

+  DHCPV4_OP_HEADER  Header; // vendor options

+  PXE_OP_BOOT_ITEM  BootItem;

+  UINT8             End[1]; // if credentials option, it starts here

+} PXE_DISCOVER_OPTIONS;

+

+#define DISCOVERoptions (*(PXE_DISCOVER_OPTIONS *) DHCPV4_OPTIONS_BUFFER.End)

+#define DISCREDoptions  (*(PXE_OP_CREDENTIAL_TYPES *) DISCOVERoptions.End)

+

+//

+// common option beginning for all our DHCP messages except

+// DHCPDECLINE and DHCPRELEASE

+//

+STATIC struct optionsstr {

+  UINT8                       DhcpCookie[4];

+  DHCPV4_OP_MESSAGE_TYPE      DhcpMessageType;

+  DHCPV4_OP_MAX_MESSAGE_SIZE  DhcpMaxMessageSize;

+  DHCPV4_OP_REQUESTED_OPTIONS DhcpRequestedOptions;

+  DHCPV4_OP_PLATFORM_ID       DhcpPlatformId;

+  DHCPV4_OP_NETWORK_INTERFACE DhcpNetworkInterface;

+  DHCPV4_OP_ARCHITECTURE_TYPE DhcpClientArchitecture;

+  DHCPV4_OP_CLASS_ID          DhcpClassIdentifier;

+  UINT8                       End[1];

+} DHCPOpStart;

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+OptionsStrucInit (

+  VOID

+  )

+{

+  DHCPOpStart.DhcpCookie[0] = 99;

+  DHCPOpStart.DhcpCookie[1] = 130;

+  DHCPOpStart.DhcpCookie[2] = 83;

+  DHCPOpStart.DhcpCookie[3] = 99;

+  DHCPOpStart.DhcpMessageType.Header.OpCode = OP_DHCP_MESSAGE_TYPE;

+  DHCPOpStart.DhcpMessageType.Header.Length = 1;

+  DHCPOpStart.DhcpMessageType.Type = DHCPDISCOVER;

+  DHCPOpStart.DhcpMaxMessageSize.Header.OpCode = OP_DHCP_MAX_MESSAGE_SZ;

+  DHCPOpStart.DhcpMaxMessageSize.Header.Length = 2;

+  DHCPOpStart.DhcpMaxMessageSize.MaxSize[0] = MAX_DHCP_MSG_SZ >> 8;

+  DHCPOpStart.DhcpMaxMessageSize.MaxSize[1] = MAX_DHCP_MSG_SZ & 0xff;

+  DHCPOpStart.DhcpRequestedOptions.Header.OpCode = OP_DHCP_PARM_REQ_LIST;

+  DHCPOpStart.DhcpRequestedOptions.Header.Length = sizeof (DHCPV4_REQUESTED_OPTIONS_DATA);

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_SUBNET_MASK = OP_SUBNET_MASK;                     /* 1 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_TIME_OFFSET = OP_TIME_OFFSET;                     /* 2 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_ROUTER_LIST = OP_ROUTER_LIST;                     /* 3 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_TIME_SERVERS = OP_TIME_SERVERS;                   /* 4 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_NAME_SERVERS = OP_NAME_SERVERS;                   /* 5 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DNS_SERVERS = OP_DNS_SERVERS;                     /* 6 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_HOST_NAME = OP_HOST_NAME;                         /* 12 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_BOOT_FILE_SZ = OP_BOOT_FILE_SZ;                   /* 13 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DOMAIN_NAME = OP_DOMAIN_NAME;                     /* 15 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_ROOT_PATH = OP_ROOT_PATH;                         /* 17 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_EXTENSION_PATH = OP_EXTENSION_PATH;               /* 18 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_MAX_DATAGRAM_SZ = OP_MAX_DATAGRAM_SZ;             /* 22 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DEFAULT_TTL = OP_DEFAULT_TTL;                     /* 23 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_BROADCAST_ADD = OP_BROADCAST_ADD;                 /* 28 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_NIS_DOMAIN_NAME = OP_NIS_DOMAIN_NAME;             /* 40 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_NIS_SERVERS = OP_NIS_SERVERS;                     /* 41 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_NTP_SERVERS = OP_NTP_SERVERS;                     /* 42 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_VENDOR_SPECIFIC = OP_VENDOR_SPECIFIC;             /* 43 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_REQ_IP_ADD = OP_DHCP_REQ_IP_ADD;             /* 50 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_LEASE_TIME = OP_DHCP_LEASE_TIME;             /* 51 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_SERVER_IP = OP_DHCP_SERVER_IP;               /* 54 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_RENEWAL_TIME = OP_DHCP_RENEWAL_TIME;         /* 58 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_REBINDING_TIME = OP_DHCP_REBINDING_TIME;     /* 59 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_CLASS_IDENTIFIER = OP_DHCP_CLASS_IDENTIFIER; /* 60 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_TFTP_SERVER_NAME = OP_DHCP_TFTP_SERVER_NAME; /* 66 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_BOOTFILE = OP_DHCP_BOOTFILE;                 /* 67 */

+  DHCPOpStart.DhcpRequestedOptions.Data._OP_DHCP_PLATFORM_ID = OP_DHCP_PLATFORM_ID;           /* 97 */

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption128 = 128;

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption129 = 129;

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption130 = 130;

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption131 = 131;

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption132 = 132;

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption133 = 133, DHCPOpStart.DhcpRequestedOptions.Data.VendorOption134 = 134;

+  DHCPOpStart.DhcpRequestedOptions.Data.VendorOption135 = 135;

+  DHCPOpStart.DhcpPlatformId.Header.OpCode              = OP_DHCP_PLATFORM_ID;

+  DHCPOpStart.DhcpPlatformId.Header.Length              = DHCPV4_OPTION_LENGTH (DHCPV4_OP_PLATFORM_ID);

+  DHCPOpStart.DhcpNetworkInterface.Header.OpCode        = OP_DHCP_NETWORK_ARCH;

+  DHCPOpStart.DhcpNetworkInterface.Header.Length        = DHCPV4_OPTION_LENGTH (DHCPV4_OP_NETWORK_INTERFACE);

+  DHCPOpStart.DhcpNetworkInterface.Type                 = 0;

+  DHCPOpStart.DhcpNetworkInterface.MajorVersion         = 0;

+  DHCPOpStart.DhcpNetworkInterface.MinorVersion         = 0;

+  DHCPOpStart.DhcpClientArchitecture.Header.OpCode      = OP_DHCP_SYSTEM_ARCH;

+  DHCPOpStart.DhcpClientArchitecture.Header.Length      = DHCPV4_OPTION_LENGTH (DHCPV4_OP_ARCHITECTURE_TYPE);

+  DHCPOpStart.DhcpClientArchitecture.Type               = HTONS (SYS_ARCH);

+  DHCPOpStart.DhcpClassIdentifier.Header.OpCode         = OP_DHCP_CLASS_IDENTIFIER;

+  DHCPOpStart.DhcpClassIdentifier.Header.Length         = sizeof (DHCPV4_CLASS_ID_DATA);

+  CopyMem (

+    DHCPOpStart.DhcpClassIdentifier.Data.ClassIdentifier,

+    "PXEClient:",

+    sizeof ("PXEClient:")

+    );

+  CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit2, "Arch:", sizeof ("Arch:"));

+  CopyMem (

+    DHCPOpStart.DhcpClassIdentifier.Data.ArchitectureType,

+    "xxxxx",

+    sizeof ("xxxxx")

+    );

+  CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit3, ":", sizeof (":"));

+  CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.InterfaceName, "XXXX", sizeof ("XXXX"));

+  CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.Lit4, ":", sizeof (":"));

+  CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.UndiMajor, "yyy", sizeof ("yyy"));

+  CopyMem (DHCPOpStart.DhcpClassIdentifier.Data.UndiMinor, "xxx", sizeof ("xxx"));

+  DHCPOpStart.End[0] = OP_END;

+};

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// DHCPDECLINE option structure

+//

+struct opdeclinestr {

+  UINT8                   DhcpCookie[4];

+  DHCPV4_OP_MESSAGE_TYPE  DhcpMessageType;

+  struct requestopendstr  OpDeclineEnd;

+};

+

+#define DHCPDECLINEoptions  (*(struct opdeclinestr *) DHCPV4_TRANSMIT_BUFFER.options)

+

+//

+// DHCPRELEASE option structure

+//

+struct opreleasestr {

+  UINT8                   DhcpCookie[4];

+  DHCPV4_OP_MESSAGE_TYPE  DhcpMessageType;

+  DHCPV4_OP_SERVER_IP     DhcServerIpPtr;

+  UINT8                   End[1];

+};

+

+#define DHCPRELEASEoptions  (*(struct opreleasestr *) DHCPV4_TRANSMIT_BUFFER.options)

+

+//

+// array of PXE vendor options in which we are interested

+// value 0 -> not of interest, else value is index into PXE OPTION array

+// option values from 1 to MAX_OUR_PXE_OPT

+//

+STATIC UINT8  ourPXEopts[MAX_OUR_PXE_OPT] = {

+  VEND_PXE_MTFTP_IP_IX,             // multicast IP address of bootfile for MTFTP listen

+  VEND_PXE_MTFTP_CPORT_IX,          // UDP Port to monitor for MTFTP responses - Intel order

+  VEND_PXE_MTFTP_SPORT_IX,          // Server UDP Port for MTFTP open - Intel order

+  VEND_PXE_MTFTP_TMOUT_IX,          // Listen timeout - secs

+  VEND_PXE_MTFTP_DELAY_IX,          // Transmission timeout - secs

+  VEND_PXE_DISCOVERY_CONTROL_IX,    // bit field

+  VEND_PXE_DISCOVERY_MCAST_ADDR_IX, // boot server discovery multicast address

+  VEND_PXE_BOOT_SERVERS_IX,         // list of boot servers of form tp(2) cnt(1) ips[cnt]

+  VEND_PXE_BOOT_MENU_IX,

+  VEND_PXE_BOOT_PROMPT_IX,

+  VEND_PXE_MCAST_ADDRS_ALLOC_IX,    // not used by client

+  VEND_PXE_CREDENTIAL_TYPES_IX,

+  VEND_13_IX,                       // not used by client

+  VEND_14_IX,                       // not used by client

+  VEND_15_IX,                       // not used by client

+  VEND_16_IX,                       // not used by client

+  VEND_17_IX,                       // not used by client

+  VEND_18_IX,                       // not used by client

+  VEND_19_IX,                       // not used by client

+  VEND_20_IX,                       // not used by client

+  VEND_21_IX,                       // not used by client

+  VEND_22_IX,                       // not used by client

+  VEND_23_IX,                       // not used by client

+  VEND_24_IX,                       // not used by client

+  VEND_25_IX,                       // not used by client

+  VEND_26_IX,                       // not used by client

+  VEND_27_IX,                       // not used by client

+  VEND_28_IX,                       // not used by client

+  VEND_29_IX,                       // not used by client

+  VEND_30_IX,                       // not used by client

+  VEND_31_IX,                       // not used by client

+  VEND_32_IX,                       // not used by client

+  VEND_33_IX,                       // not used by client

+  VEND_34_IX,                       // not used by client

+  VEND_35_IX,                       // not used by client

+  VEND_36_IX,                       // not used by client

+  VEND_37_IX,                       // not used by client

+  VEND_38_IX,                       // not used by client

+  VEND_39_IX,                       // not used by client

+  VEND_40_IX,                       // not used by client

+  VEND_41_IX,                       // not used by client

+  VEND_42_IX,                       // not used by client

+  VEND_43_IX,                       // not used by client

+  VEND_44_IX,                       // not used by client

+  VEND_45_IX,                       // not used by client

+  VEND_46_IX,                       // not used by client

+  VEND_47_IX,                       // not used by client

+  VEND_48_IX,                       // not used by client

+  VEND_49_IX,                       // not used by client

+  VEND_50_IX,                       // not used by client

+  VEND_51_IX,                       // not used by client

+  VEND_52_IX,                       // not used by client

+  VEND_53_IX,                       // not used by client

+  VEND_54_IX,                       // not used by client

+  VEND_55_IX,                       // not used by client

+  VEND_56_IX,                       // not used by client

+  VEND_57_IX,                       // not used by client

+  VEND_58_IX,                       // not used by client

+  VEND_59_IX,                       // not used by client

+  VEND_60_IX,                       // not used by client

+  VEND_61_IX,                       // not used by client

+  VEND_62_IX,                       // not used by client

+  VEND_63_IX,                       // not used by client

+  VEND_64_IX,                       // not used by client

+  VEND_65_IX,                       // not used by client

+  VEND_66_IX,                       // not used by client

+  VEND_67_IX,                       // not used by client

+  VEND_68_IX,                       // not used by client

+  VEND_69_IX,                       // not used by client

+  VEND_70_IX,                       // not used by client

+  VEND_PXE_BOOT_ITEM_IX

+};

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// array of options in which we are interested

+// value 0 -> not of interest, else value is index into OPTION array

+// option values from 1 to MAX_OUR_OPT

+//

+STATIC UINT8  OurDhcpOptions[MAX_OUR_OPT] = {

+  OP_SUBNET_MASK_IX,                      // OP_SUBNET_MASK   1   // data is the subnet mask

+  OP_TIME_OFFSET_IX,                      // OP_TIME_OFFSET   2   // data is the time offset of subnet to UTC in seconds

+  OP_ROUTER_LIST_IX,                      // OP_ROUTER_LIST   3   // list of routers on subnet

+  OP_TIME_SERVERS_IX,                     // OP_TIME_SERVERS  4   // list of time servers available

+  OP_NAME_SERVERS_IX,                     // OP_NAME_SERVERS  5   // list of name servers available

+  OP_DNS_SERVERS_IX,                      // OP_DNS_SERVERS   6   // list of DNS servers available

+  OP_LOG_SERVERS_IX,                      // OP_LOG_SERVERS   7

+  OP_COOKIE_SERVERS_IX,                   // OP_COOKIE_SERVERS    8

+  OP_LPR_SREVERS_IX,                      // OP_LPR_SREVERS   9

+  OP_IMPRESS_SERVERS_IX,                  // OP_IMPRESS_SERVERS   10

+  OP_RES_LOC_SERVERS_IX,                  // OP_RES_LOC_SERVERS   11

+  OP_HOST_NAME_IX,                        // OP_HOST_NAME 12  // client name

+  OP_BOOT_FILE_SZ_IX,                     // OP_BOOT_FILE_SZ  13  // number of 512 blocks of boot file

+  OP_DUMP_FILE_IX,                        // OP_DUMP_FILE 14  // path name of dump file if client crashes

+  OP_DOMAIN_NAME_IX,                      // OP_DOMAIN_NAME   15  // domain name to use

+  OP_SWAP_SERVER_IX,                      // OP_SWAP_SERVER   16

+  OP_ROOT_PATH_IX,                        // OP_ROOT_PATH 17  // path name containing root disk

+  OP_EXTENSION_PATH_IX,                   // OP_EXTENSION_PATH    18  // name of TFTP downloadable file of form of OP

+  OP_IP_FORWARDING_IX,                    // OP_IP_FORWARDING 19  // enable/disable IP packet forwarding

+  OP_NON_LOCAL_SRC_RTE_IX,                // OP_NON_LOCAL_SRC_RTE 20  // enable/disable non local source routing

+  OP_POLICY_FILTER_IX,                    // OP_POLICY_FILTER 21  // policy filters for non local source routing

+  OP_MAX_DATAGRAM_SZ_IX,                  // OP_MAX_DATAGRAM_SZ   22  // maximum datagram reassembly size

+  OP_DEFAULT_TTL_IX,                      // OP_DEFAULT_TTL   23  // default IP time to live

+  OP_MTU_AGING_TIMEOUT_IX,                // OP_MTU_AGING_TIMEOUT 24

+  OP_MTU_SIZES_IX,                        // OP_MTU_SIZES 25

+  OP_MTU_TO_USE_IX,                       // OP_MTU_TO_USE    26

+  OP_ALL_SUBNETS_LOCAL_IX,                // OP_ALL_SUBNETS_LOCAL 27

+  OP_BROADCAST_ADD_IX,                    // OP_BROADCAST_ADD 28  // broadcast address used on subnet

+  OP_PERFORM_MASK_DISCOVERY_IX,           // OP_PERFORM_MASK_DISCOVERY    29  // perform mask discovery using ICMP

+  OP_RESPOND_TO_MASK_REQ_IX,              // OP_RESPOND_TO_MASK_REQ   30  // respond to subnet mask requests using ICMP

+  OP_PERFORM_ROUTER_DISCOVERY_IX,         // OP_PERFORM_ROUTER_DISCOVERY  31

+  OP_ROUTER_SOLICIT_ADDRESS_IX,           // OP_ROUTER_SOLICIT_ADDRESS    32

+  OP_STATIC_ROUTER_LIST_IX,               // OP_STATIC_ROUTER_LIST    33  // list of dest/route pairs

+  OP_USE_ARP_TRAILERS_IX,                 // OP_USE_ARP_TRAILERS      34

+  OP_ARP_CACHE_TIMEOUT_IX,                // OP_ARP_CACHE_TIMEOUT 35

+  OP_ETHERNET_ENCAPSULATION_IX,           // OP_ETHERNET_ENCAPSULATION    36  // 0 -> RFC 894, 1 -> IEEE 802.3 (RFC 1042)

+  OP_TCP_DEFAULT_TTL_IX,                  // OP_TCP_DEFAULT_TTL   37  // default time to live when sending TCP segments

+  OP_TCP_KEEP_ALIVE_INT_IX,               // OP_TCP_KEEP_ALIVE_INT    38  // keep alive interval in seconds

+  OP_KEEP_ALIVE_GARBAGE_IX,               // OP_KEEP_ALIVE_GARBAGE    39

+  OP_NIS_DOMAIN_NAME_IX,                  // OP_NIS_DOMAIN_NAME   40

+  OP_NIS_SERVERS_IX,                      // OP_NIS_SERVERS   41

+  OP_NTP_SERVERS_IX,                      // OP_NTP_SERVERS   42

+  OP_VENDOR_SPECIFIC_IX,                  // OP_VENDOR_SPECIFIC   43

+  OP_NBNS_SERVERS_IX,                     // OP_NBNS_SERVERS  44

+  OP_NBDD_SERVERS_IX,                     // OP_NBDD_SERVERS  45

+  OP_NETBIOS_NODE_TYPE_IX,                // OP_NETBIOS_NODE_TYPE 46

+  OP_NETBIOS_SCOPE_IX,                    // OP_NETBIOS_SCOPE 47

+  OP_XWINDOW_SYSTEM_FONT_SERVERS_IX,      // OP_XWINDOW_SYSTEM_FONT_SERVERS   48

+  OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS_IX,  // OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS   49

+  OP_DHCP_REQ_IP_ADD_IX,                  // OP_DHCP_REQ_IP_ADD   50  // requested IP address - in DHCPDISCOVER

+  OP_DHCP_LEASE_TIME_IX,                  // OP_DHCP_LEASE_TIME   51  // lease time requested/granted

+  OP_DHCP_OPTION_OVERLOAD_IX,             // OP_DHCP_OPTION_OVERLOAD  52  // file/server name/both used to hold options

+  OP_DHCP_MESSAGE_TYPE_IX,                // OP_DHCP_MESSAGE_TYPE 53  // message type

+  OP_DHCP_SERVER_IP_IX,                   // OP_DHCP_SERVER_IP    54      // IP of server

+  OP_DHCP_PARM_REQ_LIST_IX,               // OP_DHCP_PARM_REQ_LIST    55  // list of requested parameters

+  OP_DHCP_ERROR_MESSAGE_IX,               // OP_DHCP_ERROR_MESSAGE    56  // in DHCPNAK or DECLINE messages

+  OP_DHCP_MAX_MESSAGE_SZ_IX,              // OP_DHCP_MAX_MESSAGE_SZ   57  // maximum DHCP message size client will accept

+  OP_DHCP_RENEWAL_TIME_IX,                // OP_DHCP_RENEWAL_TIME 58  // time in seconds before transitioning to RENEWING state

+  OP_DHCP_REBINDING_TIME_IX,              // OP_DHCP_REBINDING_TIME   59  // time in seconds before transitioning to REBINDING state

+  OP_DHCP_CLASS_IDENTIFIER_IX,            // OP_DHCP_CLASS_IDENTIFIER 60

+  OP_DHCP_CLIENT_IDENTIFIER_IX,           // OP_DHCP_CLIENT_IDENTIFIER    61

+  OP_RESERVED62_IX,                       // OP_RESERVED62

+  OP_RESERVED63_IX,                       // OP_RESERVED63

+  OP_NISPLUS_DOMAIN_NAME_IX,              // OP_NISPLUS_DOMAIN_NAME   64

+  OP_NISPLUS_SERVERS_IX,                  // OP_NISPLUS_SERVERS   65

+  OP_DHCP_TFTP_SERVER_NAME_IX,            // OP_DHCP_TFTP_SERVER_NAME 66

+  OP_DHCP_BOOTFILE_IX                     // OP_DHCP_BOOTFILE 67

+};

+

+#define RxBuf ((DHCP_RECEIVE_BUFFER *) (Private->ReceiveBuffers))

+

+#pragma pack()

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+CHAR8 *

+PxeBcLibGetSmbiosString (

+  IN  SMBIOS_STRUCTURE_POINTER  *Smbios,

+  IN  UINT16                    StringNumber

+  )

+/*++

+Routine description:

+  Return SMBIOS string given the string number.

+

+Arguments:

+  Smbios - Pointer to SMBIOS structure

+  StringNumber - String number to return. 0 is used to skip all strings and 

+    point to the next SMBIOS structure.

+

+Returns:

+  Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == 0

+--*/

+{

+  UINT16  Index;

+  CHAR8   *String;

+

+  //

+  // Skip over formatted section

+  //

+  String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length);

+

+  //

+  // Look through unformated section

+  //

+  for (Index = 1; Index <= StringNumber || StringNumber == 0; Index++) {

+    if (StringNumber == Index) {

+      return String;

+    }

+    //

+    // Skip string

+    //

+    for (; *String != 0; String++)

+      ;

+    String++;

+

+    if (*String == 0) {

+      //

+      // If double NULL then we are done.

+      //  Return pointer to next structure in Smbios.

+      //  if you pass in a 0 you will always get here

+      //

+      Smbios->Raw = (UINT8 *)++String;

+      return NULL;

+    }

+  }

+

+  return NULL;

+}

+

+EFI_STATUS

+PxeBcLibGetSmbiosSystemGuidAndSerialNumber (

+  IN  EFI_GUID  *SystemGuid,

+  OUT CHAR8     **SystemSerialNumber

+  )

+/*++

+

+Routine Description:

+  This function gets system guid and serial number from the smbios table

+

+Arguments:

+  SystemGuid         - The pointer of returned system guid

+  SystemSerialNumber - The pointer of returned system serial number

+

+Returns:

+  EFI_SUCCESS             - Successfully get the system guid and system serial number

+  EFI_NOT_FOUND           - Not find the SMBIOS table

+--*/

+{

+  EFI_STATUS                Status;

+  SMBIOS_STRUCTURE_TABLE    *SmbiosTable;

+  SMBIOS_STRUCTURE_POINTER  Smbios;

+  SMBIOS_STRUCTURE_POINTER  SmbiosEnd;

+  UINT16                    Index;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable);

+

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  Smbios.Hdr    = (SMBIOS_HEADER *) (UINTN) SmbiosTable->TableAddress;

+  SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength);

+

+  for (Index = 0; Index < SmbiosTable->TableLength; Index++) {

+    if (Smbios.Hdr->Type == 1) {

+      if (Smbios.Hdr->Length < 0x19) {

+        //

+        // Older version did not support Guid and Serial number

+        //

+        continue;

+      }

+      //

+      // SMBIOS tables are byte packed so we need to do a byte copy to

+      // prevend alignment faults on Itanium-based platform.

+      //

+      CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof (EFI_GUID));

+      *SystemSerialNumber = PxeBcLibGetSmbiosString (&Smbios, Smbios.Type1->SerialNumber);

+

+      return EFI_SUCCESS;

+    }

+    //

+    // Make Smbios point to the next record

+    //

+    PxeBcLibGetSmbiosString (&Smbios, 0);

+

+    if (Smbios.Raw >= SmbiosEnd.Raw) {

+      //

+      // SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e.

+      // given this we must double check against the lenght of

+      // the structure.

+      //

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// add router list to list

+//

+STATIC

+VOID

+Ip4AddRouterList (

+  PXE_BASECODE_DEVICE *Private,

+  DHCPV4_OP_IP_LIST   *IpListPtr

+  )

+{

+  EFI_IP_ADDRESS  TmpIp;

+  INTN            Index;

+  INTN            num;

+

+  if (IpListPtr == NULL) {

+    return ;

+  }

+

+  for (Index = 0, num = IpListPtr->Header.Length >> 2; Index < num; ++Index) {

+    CopyMem (&TmpIp, &IpListPtr->IpList[Index], 4);

+    Ip4AddRouter (Private, &TmpIp);

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// send ARP for our IP - fail if someone has it

+//

+STATIC

+BOOLEAN

+SetStationIP (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  EFI_MAC_ADDRESS DestMac;

+  EFI_STATUS      EfiStatus;

+

+  ZeroMem (&DestMac, sizeof DestMac);

+

+  if (GetHwAddr(Private, (EFI_IP_ADDRESS *)&DHCP_REQ_OPTIONS.OpReqIP.Ip, (EFI_MAC_ADDRESS *)&DestMac)

+    || DoArp(Private, (EFI_IP_ADDRESS *)&DHCP_REQ_OPTIONS.OpReqIP.Ip, (EFI_MAC_ADDRESS *)&DestMac) == EFI_SUCCESS) {

+    return FALSE;   // somebody else has this IP

+  }

+

+  CopyMem (

+    (EFI_IPv4_ADDRESS *) &Private->EfiBc.Mode->StationIp,

+    &DHCP_REQ_OPTIONS.OpReqIP.Ip,

+    sizeof (EFI_IPv4_ADDRESS)

+    );

+

+  Private->GoodStationIp = TRUE;

+

+  if (!Private->UseIgmpv1Reporting) {

+    return TRUE;

+  }

+

+  if (Private->Igmpv1TimeoutEvent != NULL) {

+    return TRUE;

+  }

+

+  EfiStatus = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &Private->Igmpv1TimeoutEvent

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    Private->Igmpv1TimeoutEvent = NULL;

+    return TRUE;

+  }

+

+  EfiStatus = gBS->SetTimer (

+                    Private->Igmpv1TimeoutEvent,

+                    TimerRelative,

+                    (UINT64) V1ROUTER_PRESENT_TIMEOUT * 10000000

+                    );  /* 400 seconds */

+

+  if (EFI_ERROR (EfiStatus)) {

+    gBS->CloseEvent (Private->Igmpv1TimeoutEvent);

+    Private->Igmpv1TimeoutEvent = NULL;

+  }

+

+  return TRUE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+AddRouters (

+  PXE_BASECODE_DEVICE *Private,

+  DHCP_RECEIVE_BUFFER *RxBufPtr

+  )

+{

+  Ip4AddRouter (Private, &RxBufPtr->u.Dhcpv4.giaddr);

+

+  Ip4AddRouterList (

+    Private,

+    (DHCPV4_OP_IP_LIST *) RxBufPtr->OpAdds.PktOptAdds[OP_ROUTER_LIST_IX - 1]

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+DoUdpWrite (

+  PXE_BASECODE_DEVICE         *Private,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_IP_ADDRESS              *ClientIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ClientPortPtr

+  )

+{

+  UINTN Len;

+

+  Len = sizeof DHCPV4_TRANSMIT_BUFFER;

+

+  return UdpWrite (

+          Private,

+          EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,

+          ServerIpPtr,

+          ServerPortPtr,

+          0,

+          ClientIpPtr,

+          ClientPortPtr,

+          0,

+          0,

+          &Len,

+          Private->TransmitBuffer

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// initialize the DHCP structure

+//

+typedef struct {

+  UINT8 x[4];

+} C4Str;

+

+STATIC

+VOID

+InitDhcpv4TxBuf (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  UINTN                   HwAddrLen;

+  UINT8                   *String;

+  CHAR8                   *SystemSerialNumber;

+  EFI_PXE_BASE_CODE_MODE  *PxebcMode;

+

+  PxebcMode = Private->EfiBc.Mode;

+

+  ZeroMem (&DHCPV4_TRANSMIT_BUFFER, sizeof (DHCPV4_STRUCT));

+  DHCPV4_TRANSMIT_BUFFER.op     = BOOTP_REQUEST;

+  DHCPV4_TRANSMIT_BUFFER.htype  = Private->SimpleNetwork->Mode->IfType;

+  DHCPV4_TRANSMIT_BUFFER.flags  = HTONS (DHCP_BROADCAST_FLAG);

+  CopyMem (&DHCPV4_OPTIONS_BUFFER, (VOID *) &DHCPOpStart, sizeof (DHCPOpStart));

+

+  //

+  // default to hardware address

+  //

+  HwAddrLen = Private->SimpleNetwork->Mode->HwAddressSize;

+

+  if (HwAddrLen > sizeof DHCPV4_TRANSMIT_BUFFER.chaddr) {

+    HwAddrLen = sizeof DHCPV4_TRANSMIT_BUFFER.chaddr;

+  }

+

+  String = (UINT8 *) &Private->SimpleNetwork->Mode->CurrentAddress;

+

+  if (PxeBcLibGetSmbiosSystemGuidAndSerialNumber (

+        (EFI_GUID *) DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid,

+        &SystemSerialNumber

+        ) == EFI_SUCCESS) {

+    if (PxebcMode->SendGUID) {

+      HwAddrLen = sizeof (EFI_GUID);

+      String    = (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid;

+    }

+  } else {

+    //

+    // GUID not yet set - send all 0xff's to show programable (via SetVariable)

+    // SetMem(DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid, sizeof(EFI_GUID), 0xff);

+    // GUID not yet set - send all 0's to show not programable

+    //

+    ZeroMem (DHCPV4_OPTIONS_BUFFER.DhcpPlatformId.Guid, sizeof (EFI_GUID));

+  }

+

+  DHCPV4_TRANSMIT_BUFFER.hlen = (UINT8) HwAddrLen;

+  CopyMem (DHCPV4_TRANSMIT_BUFFER.chaddr, String, HwAddrLen);

+

+  CvtNum (

+    SYS_ARCH,

+    (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.ArchitectureType,

+    sizeof DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.ArchitectureType

+    );

+

+  DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.Type                         = Private->NiiPtr->Type;

+  DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MajorVersion                 = Private->NiiPtr->MajorVer;

+  DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MinorVersion                 = Private->NiiPtr->MinorVer;

+

+  *(C4Str *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.InterfaceName = *(C4Str *) Private->NiiPtr->StringId;

+

+  CvtNum (

+    DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MajorVersion,

+    (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMajor,

+    sizeof DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMajor

+    );

+

+  CvtNum (

+    DHCPV4_OPTIONS_BUFFER.DhcpNetworkInterface.MinorVersion,

+    (UINT8 *) DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMinor,

+    sizeof DHCPV4_OPTIONS_BUFFER.DhcpClassIdentifier.Data.UndiMinor

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+UINT32

+DecodePxeOptions (

+  DHCP_RECEIVE_BUFFER *RxBufPtr,

+  UINT8               *ptr,

+  INTN                Len

+  )

+{

+  UINT8     Op;

+  UINT8     *EndPtr;

+  INTN      Index;

+  UNION_PTR LocalPtr;

+  UINT32    status;

+

+  status = 0;

+

+  for (EndPtr = ptr + Len; ptr < EndPtr; ptr += Len + 2) {

+    Op  = ptr[0];

+    Len = ptr[1];

+

+    switch (Op) {

+    case OP_PAD:

+      Len = -1;

+      break;

+

+    case OP_END:

+      return status;

+

+    default:

+      LocalPtr.BytePtr = ptr;

+      if (Op <= MAX_OUR_PXE_OPT) {

+        Index = ourPXEopts[Op - 1];

+        if (Index) {

+          RxBufPtr->OpAdds.PxeOptAdds[Index - 1] = LocalPtr.OpPtr;

+          status |= 1 << Index;

+          if (Index == VEND_PXE_BOOT_ITEM && LocalPtr.BootItem->Header.Length == 3) {

+            RxBufPtr->OpAdds.Status |= USE_THREE_BYTE;

+          }

+        }

+      }

+      break;

+    }

+  }

+

+  return status;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+DecodeOptions (

+  DHCP_RECEIVE_BUFFER *RxBufPtr,

+  UINT8               *ptr,

+  INTN                Len

+  )

+{

+  UINT8     Op;

+  UINT8     *EndPtr;

+  INTN      Index;

+  UNION_PTR LocalPtr;

+

+  for (EndPtr = ptr + Len; ptr < EndPtr; ptr += Len + 2) {

+    Op  = ptr[0];

+    Len = ptr[1];

+

+    switch (Op) {

+    case OP_PAD:

+      Len = -1;

+      break;

+

+    case OP_END:

+      return ;

+

+    default:

+      LocalPtr.BytePtr = ptr;

+      if (Op <= MAX_OUR_OPT) {

+        Index = OurDhcpOptions[Op - 1];

+        if (Index) {

+          RxBufPtr->OpAdds.PktOptAdds[Index - 1] = LocalPtr.OpPtr;

+          if (Index == OP_VENDOR_SPECIFIC_IX) {

+            UINT32  status;

+            status = DecodePxeOptions (

+                      RxBufPtr,

+                      (UINT8 *) LocalPtr.VendorOptions->VendorOptions,

+                      LocalPtr.VendorOptions->Header.Length

+                      );

+            if (status) {

+              RxBufPtr->OpAdds.Status |= PXE_TYPE;

+              //

+              // check for all the MTFTP info options present - any missing is a nogo

+              //

+              if ((status & WfM11a_OPTS) == WfM11a_OPTS) {

+                RxBufPtr->OpAdds.Status |= WfM11a_TYPE;

+              }

+

+              if (status & DISCOVER_OPTS) {

+                RxBufPtr->OpAdds.Status |= DISCOVER_TYPE;

+              }

+

+              if (status & CREDENTIALS_OPT) {

+                RxBufPtr->OpAdds.Status |= CREDENTIALS_TYPE;

+              }

+            }

+          }

+        }

+      }

+      break;

+    }

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+Parse (

+  DHCP_RECEIVE_BUFFER *RxBufPtr,

+  INTN                Len

+  )

+{

+  UNION_PTR LocalPtr;

+

+  //

+  // initialize

+  //

+  SetMem (&RxBufPtr->OpAdds, sizeof RxBufPtr->OpAdds, 0);

+

+  DecodeOptions (

+    RxBufPtr,

+    RxBufPtr->u.Dhcpv4.options + 4,

+    Len - (sizeof RxBufPtr->u.Dhcpv4 - sizeof RxBufPtr->u.Dhcpv4.options + 4)

+    );

+

+  LocalPtr.OpPtr = RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_OPTION_OVERLOAD_IX - 1];

+

+  if ((LocalPtr.OpPtr) && (LocalPtr.Overload->Overload & OVLD_SRVR_NAME)) {

+    DecodeOptions (RxBufPtr, RxBufPtr->u.Dhcpv4.sname, sizeof RxBufPtr->u.Dhcpv4.sname);

+  }

+

+  if (LocalPtr.OpPtr && (LocalPtr.Overload->Overload & OVLD_FILE)) {

+    DecodeOptions (RxBufPtr, RxBufPtr->u.Dhcpv4.file, sizeof RxBufPtr->u.Dhcpv4.file);

+  } else if (!RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] && RxBufPtr->u.Dhcpv4.file[0]) {

+    RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] = (DHCPV4_OP_STRUCT *) (RxBufPtr->u.Dhcpv4.file - sizeof (DHCPV4_OP_HEADER));

+

+    RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Header.Length = (UINT8) AsciiStrLen ((CHAR8 *)RxBufPtr->u.Dhcpv4.file);

+  }

+

+  LocalPtr.OpPtr = RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_CLASS_IDENTIFIER_IX - 1];

+

+  if ((LocalPtr.OpPtr) &&

+      LocalPtr.PxeClassStr->Header.Length >= 9 &&

+      !CompareMem (LocalPtr.PxeClassStr->Class, "PXEClient", 9)

+        ) {

+    RxBufPtr->OpAdds.Status |= PXE_TYPE;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+CopyParseRxBuf (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                RxBufIndex,

+  INTN                PacketIndex

+  )

+{

+  DHCP_RECEIVE_BUFFER *RxBufPtr;

+

+  RxBufPtr = &((DHCP_RECEIVE_BUFFER *) Private->DhcpPacketBuffer)[PacketIndex];

+

+  CopyMem (

+    &RxBufPtr->u.Dhcpv4,

+    &RxBuf[RxBufIndex].u.Dhcpv4,

+    sizeof (RxBuf[RxBufIndex].u.Dhcpv4)

+    );

+

+  Parse (RxBufPtr, sizeof RxBufPtr->u.ReceiveBuffer);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+CopyProxyRxBuf (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                RxBufIndex

+  )

+{

+  Private->EfiBc.Mode->ProxyOfferReceived = TRUE;

+  CopyParseRxBuf (Private, RxBufIndex, PXE_OFFER_INDEX);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+CopyParse (

+  PXE_BASECODE_DEVICE       *Private,

+  EFI_PXE_BASE_CODE_PACKET  *PacketPtr,

+  EFI_PXE_BASE_CODE_PACKET  *NewPacketPtr,

+  INTN                      Index

+  )

+{

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf;

+

+  DhcpRxBuf = &((DHCP_RECEIVE_BUFFER *) Private->DhcpPacketBuffer)[Index];

+

+  CopyMem (

+    (EFI_PXE_BASE_CODE_PACKET *) &DhcpRxBuf->u.Dhcpv4,

+    NewPacketPtr,

+    sizeof (*NewPacketPtr)

+    );

+

+  CopyMem (&*PacketPtr, &*NewPacketPtr, sizeof (*NewPacketPtr));

+

+  Parse (DhcpRxBuf, sizeof DhcpRxBuf->u.ReceiveBuffer);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+BOOLEAN

+AckEdit (

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf

+  )

+{

+  UNION_PTR LocalPtr;

+

+  LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1];

+

+  //

+  // check that an ACK

+  // if a DHCP type, must be DHCPOFFER and must have server id

+  //

+  return (BOOLEAN)

+    (

+      (LocalPtr.OpPtr) &&

+      (LocalPtr.MessageType->Type == DHCPACK) &&

+      DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1]

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// if a discover type packet, make sure all required fields are present

+//

+BOOLEAN

+DHCPOfferAckEdit (

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf

+  )

+{

+  PXE_OP_SERVER_LIST  *BootServerOpPtr;

+  UNION_PTR           LocalPtr;

+

+  if ((DhcpRxBuf->OpAdds.Status & DISCOVER_TYPE) == 0) {

+    return TRUE;

+  }

+

+  LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1];

+

+  if (LocalPtr.OpPtr == NULL) {

+    LocalPtr.OpPtr  = (DHCPV4_OP_STRUCT *) &DefaultDisCtl;

+    DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1] = (DHCPV4_OP_STRUCT *) &DefaultDisCtl;

+  }

+  //

+  // make sure all required fields are here

+  // if mucticast enabled, need multicast address

+  //

+  if (!(LocalPtr.DiscoveryControl->ControlBits & DISABLE_MCAST) &&

+      (!DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_MCAST_ADDR_IX - 1] || !IS_MULTICAST (((DHCPV4_OP_STRUCT *) DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_MCAST_ADDR_IX - 1])->Data))

+      ) {

+    return FALSE;

+    //

+    // missing required field

+    //

+  }

+  //

+  // if a list, it better be good

+  //

+  BootServerOpPtr = (PXE_OP_SERVER_LIST *) DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_SERVERS_IX - 1];

+

+  if (BootServerOpPtr != NULL) {

+    PXE_SERVER_LIST *BootServerListPtr;

+    INTN            ServerListLen;

+    INTN            ServerEntryLen;

+

+    BootServerListPtr = BootServerOpPtr->ServerList;

+    ServerListLen     = BootServerOpPtr->Header.Length;

+

+    do {

+      EFI_IPv4_ADDRESS  *IpListPtr;

+      INTN              IpCnt;

+

+      IpCnt           = BootServerListPtr->u.Ipv4List.IpCount;

+

+      ServerEntryLen  = sizeof (PXEV4_SERVER_LIST) + 2 + (IpCnt - 1) * sizeof (EFI_IPv4_ADDRESS);

+

+      if (ServerListLen < ServerEntryLen) {

+        //

+        // missing required field

+        //

+        return FALSE;

+      }

+

+      IpListPtr = BootServerListPtr->u.Ipv4List.IpList;

+

+      while (IpCnt--) {

+        if (IS_MULTICAST (IpListPtr)) {

+          //

+          // missing required field

+          //

+          return FALSE;

+        } else {

+          ++IpListPtr;

+        }

+      }

+

+      BootServerListPtr = (PXE_SERVER_LIST *) IpListPtr;

+    } while (ServerListLen -= ServerEntryLen);

+  }

+  //

+  // else there must be a list if use list enabled or multicast and

+  // broadcast disabled

+  //

+  else if ((LocalPtr.DiscoveryControl->ControlBits & USE_ACCEPT_LIST) ||

+           ((LocalPtr.DiscoveryControl->ControlBits & (DISABLE_MCAST | DISABLE_BCAST)) == (DISABLE_MCAST | DISABLE_BCAST))

+          ) {

+    //

+    // missing required field

+    //

+    return FALSE;

+  }

+  //

+  // if not USE_BOOTFILE or no bootfile given, must have menu stuff

+  //

+  if (!(LocalPtr.DiscoveryControl->ControlBits & USE_BOOTFILE) ||

+      !DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]

+      ) {

+    INTN  MenuLth;

+

+    LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_MENU_IX - 1];

+

+    if (LocalPtr.OpPtr == NULL || !DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_PROMPT_IX - 1]) {

+      //

+      // missing required field

+      //

+      return FALSE;

+    }

+    //

+    // make sure menu valid

+    //

+    MenuLth               = LocalPtr.BootMenu->Header.Length;

+    LocalPtr.BootMenuItem = LocalPtr.BootMenu->MenuItem;

+

+    do {

+      INTN  MenuItemLen;

+

+      MenuItemLen = LocalPtr.BootMenuItem->DataLen;

+

+      if (MenuItemLen == 0) {

+        //

+        // missing required field

+        //

+        return FALSE;

+      }

+

+      MenuItemLen += sizeof (*LocalPtr.BootMenuItem) - sizeof (LocalPtr.BootMenuItem->Data);

+

+      MenuLth -= MenuItemLen;

+      LocalPtr.BytePtr += MenuItemLen;

+    } while (MenuLth > 0);

+

+    if (MenuLth != 0) {

+      //

+      // missing required field

+      //

+      return FALSE;

+    }

+  }

+

+  if (!DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1]) {

+    DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1] = (DHCPV4_OP_STRUCT *) &DefaultBootItem;

+  }

+

+  return TRUE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+BOOLEAN

+DHCPAckEdit (

+  DHCP_RECEIVE_BUFFER *RxBufPtr

+  )

+{

+  return (BOOLEAN) (DHCPOfferAckEdit (RxBufPtr) ? AckEdit (RxBufPtr) : FALSE);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// get an offer/ack

+//

+EFI_STATUS

+GetOfferAck (

+  PXE_BASECODE_DEVICE          *Private,

+  BOOLEAN                     (*ExtraEdit)(DHCP_RECEIVE_BUFFER *DhcpRxBuf),

+  UINT16 OpFlags, // for Udp read

+  EFI_IP_ADDRESS *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT *ServerPortPtr,

+  EFI_IP_ADDRESS *ClientIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT *ClientPortPtr,

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf,

+  EFI_EVENT TimeoutEvent

+  )

+/*++

+Routine description:

+  Wait for an OFFER/ACK packet.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  ExtraEdit := Pointer to extra option checking function

+  OpFlags := UdpRead() option flags

+  ServerIpPtr := 

+  ServerPortPtr := 

+  ClientIpPtr := 

+  ClientPortPtr := 

+  DhcpRxBuf := 

+  TimeoutEvent :=

+

+Returns:

+--*/

+{

+  EFI_IP_ADDRESS  ServerIp;

+  EFI_STATUS      StatCode;

+  INTN            RxBufLen;

+

+  for (;;) {

+    //

+    // Wait until we get a UDP packet.

+    //

+    ZeroMem (&ServerIp, sizeof (EFI_IP_ADDRESS));

+    RxBufLen = sizeof RxBuf[0].u.ReceiveBuffer;

+

+    if ((StatCode = UdpRead (

+                      Private,

+                      OpFlags,

+                      ClientIpPtr,

+                      ClientPortPtr,

+                      ServerIpPtr,

+                      ServerPortPtr,

+                      0,

+                      0,

+                      (UINTN *) &RxBufLen,

+                      &DhcpRxBuf->u.Dhcpv4,

+                      TimeoutEvent

+                      )) != EFI_SUCCESS) {

+      if (StatCode == EFI_TIMEOUT) {

+        StatCode = EFI_NO_RESPONSE;

+      }

+

+      break;

+    }

+    //

+    // got a packet - see if a good offer

+    //

+    if (DhcpRxBuf->u.Dhcpv4.op != BOOTP_REPLY) {

+      continue;

+    }

+

+    if (DhcpRxBuf->u.Dhcpv4.xid != DHCPV4_TRANSMIT_BUFFER.xid) {

+      continue;

+    }

+

+    if (*(UINT32 *) DHCPV4_TRANSMIT_BUFFER.options != * (UINT32 *) DhcpRxBuf->u.Dhcpv4.options) {

+      continue;

+    }

+

+    if (*(UINT8 *) &DhcpRxBuf->u.Dhcpv4.yiaddr > 223) {

+      continue;

+    }

+

+    if (CompareMem (

+          DhcpRxBuf->u.Dhcpv4.chaddr,

+          DHCPV4_TRANSMIT_BUFFER.chaddr,

+          sizeof DhcpRxBuf->u.Dhcpv4.chaddr

+          )) {

+      //

+      // no good

+      //

+      continue;

+    }

+

+    Parse (DhcpRxBuf, RxBufLen);

+

+    if (!(*ExtraEdit) (DhcpRxBuf)) {

+      continue;

+    }

+    //

+    // Good DHCP packet.

+    //

+    StatCode = EFI_SUCCESS;

+    break;

+  }

+

+  return StatCode;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// get DHCPOFFER's

+//

+EFI_STATUS

+GetOffers (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  EFI_IP_ADDRESS  ClientIp;

+  EFI_IP_ADDRESS  ServerIp;

+  EFI_STATUS      StatCode;

+  EFI_EVENT       TimeoutEvent;

+  INTN            NumOffers;

+  INTN            Index;

+

+  //

+  //

+  //

+  ZeroMem (&ServerIp, sizeof (EFI_IP_ADDRESS));

+  NumOffers = 0;

+

+  for (Index = 0; Index < (sizeof Private->ServerCount) / sizeof Private->ServerCount[0]; ++Index) {

+    Private->ServerCount[Index] = 0;

+    Private->GotProxy[Index]    = 0;

+  }

+

+  Private->GotBootp               = 0;

+  //

+  // these we throw away

+  //

+  Private->GotProxy[DHCP_ONLY_IX] = 1;

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &TimeoutEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    return StatCode;

+  }

+

+  StatCode = gBS->SetTimer (

+                    TimeoutEvent,

+                    TimerRelative,

+                    Private->Timeout * 10000000 + 1000000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return StatCode;

+  }

+  //

+  // get offers

+  //

+  for (;;) {

+    DHCP_RECEIVE_BUFFER *DhcpRxBuf;

+    UNION_PTR           LocalPtr;

+

+    DhcpRxBuf = &RxBuf[NumOffers];

+

+    if ((

+          StatCode = GetOfferAck (

+                  Private,

+        DHCPOfferAckEdit,

+        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP |

+        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP |

+        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+        &ServerIp,

+        &DhcpServerPort,

+        &ClientIp,

+        &DHCPClientPort,

+        DhcpRxBuf,

+        TimeoutEvent

+        )

+) != EFI_SUCCESS

+        ) {

+      break;

+    }

+

+    LocalPtr.OpPtr = DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1];

+

+    //

+    // check type of offer

+    //

+    if (LocalPtr.OpPtr == NULL) {

+      //

+      // bootp - we only need one and make sure has bootfile

+      //

+      if (Private->GotBootp || !DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {

+        continue;

+      }

+

+      Private->GotBootp = (UINT8) (NumOffers + 1);

+    }

+    //

+    // if a DHCP type, must be DHCPOFFER and must have server id

+    //

+    else if (LocalPtr.MessageType->Type != DHCPOFFER || !DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1]) {

+      continue;

+    } else {

+      INTN  TypeIx;

+

+      //

+      // get type - PXE10, WfM11a, or BINL

+      //

+      if (DhcpRxBuf->OpAdds.Status & DISCOVER_TYPE) {

+        TypeIx = PXE10_IX;

+      } else if (DhcpRxBuf->OpAdds.Status & WfM11a_TYPE) {

+        //

+        // WfM - make sure it has a bootfile

+        //

+        if (!DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {

+          continue;

+        }

+

+        TypeIx = WfM11a_IX;

+      } else {

+        TypeIx = (DhcpRxBuf->OpAdds.Status & PXE_TYPE) ? BINL_IX : DHCP_ONLY_IX;

+      }

+      //

+      // check DHCP or proxy

+      //

+      if (DhcpRxBuf->u.Dhcpv4.yiaddr == 0) {

+        //

+        // proxy - only need one of each type if not BINL

+        // and must have at least PXE_TYPE

+        //

+        if (TypeIx == BINL_IX) {

+          Private->BinlProxies[Private->GotProxy[BINL_IX]++] = (UINT8) NumOffers;

+        } else if (Private->GotProxy[TypeIx]) {

+          continue;

+        } else {

+          Private->GotProxy[TypeIx] = (UINT8) (NumOffers + 1);

+        }

+      } else {

+        Private->OfferCount[TypeIx][Private->ServerCount[TypeIx]++] = (UINT8) NumOffers;

+      }

+    }

+

+    if (++NumOffers == MAX_OFFERS) {

+      break;

+    }

+  }

+

+  gBS->CloseEvent (TimeoutEvent);

+  Private->NumOffersReceived = NumOffers;

+

+  return (Private->NumOffersReceived) ? EFI_SUCCESS : EFI_NO_RESPONSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// send DHCPDECLINE

+//

+STATIC

+VOID

+DeclineOffer (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  EFI_PXE_BASE_CODE_MODE  *PxebcMode;

+  UINT16                  SaveSecs;

+

+  PxebcMode                     = Private->EfiBc.Mode;

+  SaveSecs                      = DHCPV4_TRANSMIT_BUFFER.secs;

+

+  DHCPV4_TRANSMIT_BUFFER.secs   = 0;

+  DHCPV4_TRANSMIT_BUFFER.flags  = 0;

+  SetMem (

+    DHCPV4_TRANSMIT_BUFFER.options + sizeof (struct opdeclinestr),

+    sizeof (DHCPOpStart) - sizeof (struct opdeclinestr),

+    OP_PAD

+    );

+  DHCPDECLINEoptions.DhcpMessageType.Type = DHCPDECLINE;

+  CopyMem (&DHCPDECLINEoptions.OpDeclineEnd, &DHCP_REQ_OPTIONS, sizeof (struct requestopendstr));

+  // DHCPDECLINEoptions.OpDeclineEnd         = DHCP_REQ_OPTIONS;

+

+  {

+    EFI_IP_ADDRESS  TmpIp;

+

+    CopyMem (&TmpIp, &DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip, sizeof TmpIp);

+

+    DoUdpWrite (

+      Private,

+      &TmpIp,

+      &DhcpServerPort,

+      &PxebcMode->StationIp,

+      &DHCPClientPort

+      );

+  }

+

+  InitDhcpv4TxBuf (Private);

+  DHCPV4_TRANSMIT_BUFFER.secs = SaveSecs;

+  Private->GoodStationIp      = FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// send DHCPRELEASE

+//

+STATIC

+BOOLEAN

+Release (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  EFI_PXE_BASE_CODE_MODE  *PxebcMode;

+  UINT16                  SaveSecs;

+  DHCPV4_OP_SERVER_IP     *Point;

+

+  PxebcMode                   = Private->EfiBc.Mode;

+  SaveSecs                    = DHCPV4_TRANSMIT_BUFFER.secs;

+  DHCPV4_TRANSMIT_BUFFER.secs = 0;

+

+  SetMem (

+    DHCPV4_TRANSMIT_BUFFER.options + sizeof (struct opreleasestr),

+    sizeof (DHCPOpStart) - sizeof (struct opreleasestr),

+    OP_PAD

+    );

+

+  DHCPRELEASEoptions.DhcpMessageType.Type = DHCPRELEASE;

+  Point = (DHCPV4_OP_SERVER_IP *) DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1];

+  CopyMem (

+    &DHCPRELEASEoptions.DhcServerIpPtr,

+    &Point,

+    sizeof DHCPRELEASEoptions.DhcServerIpPtr

+    );

+

+  DHCPRELEASEoptions.End[0] = OP_END;

+

+  {

+    EFI_IP_ADDRESS  TmpIp;

+

+    CopyMem (&TmpIp, &DHCPRELEASEoptions.DhcServerIpPtr.Ip, sizeof TmpIp);

+

+    DoUdpWrite (

+      Private,

+      &TmpIp,

+      &DhcpServerPort,

+      &PxebcMode->StationIp,

+      &DHCPClientPort

+      );

+  }

+

+  InitDhcpv4TxBuf (Private);

+

+  DHCPV4_TRANSMIT_BUFFER.secs = SaveSecs;

+  Private->GoodStationIp      = FALSE;

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+BOOLEAN

+GetBINLAck (

+  PXE_BASECODE_DEVICE *Private,

+  EFI_IP_ADDRESS      *ServerIpPtr

+  )

+{

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf;

+  EFI_STATUS          StatCode;

+  EFI_EVENT           TimeoutEvent;

+

+  //

+  //

+  //

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &TimeoutEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    return FALSE;

+  }

+

+  StatCode = gBS->SetTimer (

+                    TimeoutEvent,

+                    TimerRelative,

+                    Private->Timeout * 10000000 + 1000000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return FALSE;

+  }

+  //

+  //

+  //

+  DhcpRxBuf = &PXE_BINL_BUFFER;

+

+  for (;;) {

+    EFI_PXE_BASE_CODE_UDP_PORT  BINLSrvPort;

+

+    BINLSrvPort = 0;

+

+    if (GetOfferAck (

+          Private,

+          AckEdit,

+          EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+          ServerIpPtr,

+          &BINLSrvPort,

+          &Private->EfiBc.Mode->StationIp,

+          &PSEUDO_DHCP_CLIENT_PORT,

+          DhcpRxBuf,

+          TimeoutEvent

+          ) != EFI_SUCCESS) {

+      break;

+    }

+    //

+    // make sure from whom we wanted

+    //

+    if (!DhcpRxBuf->u.Dhcpv4.yiaddr && !CompareMem (

+                                          &ServerIpPtr->v4,

+                                          &((DHCPV4_OP_SERVER_IP *) DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,

+                                          sizeof (ServerIpPtr->v4)

+                                          )) {

+      gBS->CloseEvent (TimeoutEvent);

+      //

+      // got an ACK from server

+      //

+      return TRUE;

+    }

+  }

+

+  gBS->CloseEvent (TimeoutEvent);

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// make sure we can get BINL

+// send DHCPREQUEST to PXE server

+//

+STATIC

+BOOLEAN

+TryBINL (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                OfferIx

+  )

+{

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf;

+  EFI_IP_ADDRESS      ServerIp;

+  UINT16              SaveSecs;

+  INTN                Index;

+

+  DhcpRxBuf = &RxBuf[OfferIx];

+

+  //

+  // send DHCP request

+  // if fail return false

+  //

+  CopyMem (

+    ((EFI_IPv4_ADDRESS *) &ServerIp),

+    &((DHCPV4_OP_SERVER_IP *) DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,

+    sizeof (EFI_IPv4_ADDRESS)

+    );

+

+  //

+  // client IP address - filled in by client if it knows it

+  //

+  CopyMem (

+    ((EFI_IPv4_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr),

+    &DHCP_REQ_OPTIONS.OpReqIP.Ip,

+    sizeof (EFI_IPv4_ADDRESS)

+    );

+

+  SetMem (&DHCP_REQ_OPTIONS, sizeof DHCP_REQ_OPTIONS, OP_PAD);

+  DHCPV4_TRANSMIT_BUFFER.flags  = 0;

+  DHCPV4_OPTIONS_BUFFER.End[0]  = OP_END;

+  AddRouters (Private, DhcpRxBuf);

+  SaveSecs = DHCPV4_TRANSMIT_BUFFER.secs;

+

+  for (Index = 0; Index < 3; Private->TotalSeconds = (UINT16) (Private->TotalSeconds + Private->Timeout), ++Index) {

+    DHCPV4_TRANSMIT_BUFFER.secs = HTONS (Private->TotalSeconds);

+

+    //

+    // unicast DHCPREQUEST to PXE server

+    //

+    if (DoUdpWrite (

+          Private,

+          &ServerIp,

+          &PseudoDhcpServerPort,

+          (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,

+          &PSEUDO_DHCP_CLIENT_PORT

+          ) != EFI_SUCCESS) {

+      break;

+    }

+

+    if (!GetBINLAck (Private, &ServerIp)) {

+      continue;

+    }

+    //

+    // early exit failures

+    // make sure a good ACK

+    //

+    if (!DHCPOfferAckEdit (&PXE_BINL_BUFFER) || (

+          !(PXE_BINL_BUFFER.OpAdds.Status & DISCOVER_TYPE) && !PXE_BINL_BUFFER.OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]

+      )

+        ) {

+      break;

+    }

+

+    Private->EfiBc.Mode->ProxyOfferReceived = TRUE;

+    return TRUE;

+  }

+  //

+  // failed - reset seconds field, etc.

+  //

+  Private->EfiBc.Mode->RouteTableEntries = 0;

+  //

+  // reset

+  //

+  DHCPV4_TRANSMIT_BUFFER.secs = SaveSecs;

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+BOOLEAN

+TryFinishBINL (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                OfferIx

+  )

+{

+  if (TryBINL (Private, OfferIx)) {

+    return TRUE;

+  }

+

+  return Release (Private);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+BOOLEAN

+TryFinishProxyBINL (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  INTN  Index;

+

+  for (Index = 0; Index < Private->GotProxy[BINL_IX]; ++Index) {

+    if (TryBINL (Private, Private->BinlProxies[Index])) {

+      return TRUE;

+    }

+  }

+

+  return Release (Private);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// try to finish DORA - send DHCP request, wait for ACK, check with ARP

+//

+STATIC

+BOOLEAN

+TryFinishDORA (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                OfferIx

+  )

+{

+  DHCP_RECEIVE_BUFFER *DhcpRxBuf;

+  EFI_IP_ADDRESS      ClientIp;

+  EFI_IP_ADDRESS      ServerIp;

+  EFI_STATUS          StatCode;

+  UNION_PTR           LocalPtr;

+  EFI_EVENT           TimeoutEvent;

+

+  //

+  // send DHCP request

+  // if fail return false

+  //

+  DhcpRxBuf = &DHCPV4_ACK_BUFFER;

+  DHCPV4_OPTIONS_BUFFER.DhcpMessageType.Type  = DHCPREQUEST;

+  CopyMem (&DHCP_REQ_OPTIONS, &RequestOpEndStr, sizeof (RequestOpEndStr));

+//  DHCP_REQ_OPTIONS = RequestOpEndStr;

+  DHCP_REQ_OPTIONS.OpReqIP.Ip = *(EFI_IPv4_ADDRESS *) &RxBuf[OfferIx].u.Dhcpv4.yiaddr;

+

+  CopyMem (

+    &DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip,

+    &((DHCPV4_OP_SERVER_IP *) RxBuf[OfferIx].OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,

+    sizeof DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip

+    );

+

+  CopyMem (

+    Private->EfiBc.Mode->SubnetMask.Addr,

+    &DefaultSubnetMask,

+    4

+    );

+

+  //

+  // broadcast DHCPREQUEST

+  //

+  if (DoUdpWrite (

+        Private,

+        &BroadcastIP,

+        &DhcpServerPort,

+        (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,

+        &DHCPClientPort

+        ) != EFI_SUCCESS) {

+    return FALSE;

+  }

+  //

+  //

+  //

+  StatCode = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &TimeoutEvent

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    return FALSE;

+  }

+

+  StatCode = gBS->SetTimer (

+                    TimeoutEvent,

+                    TimerPeriodic,

+                    Private->Timeout * 10000000 + 1000000

+                    );

+

+  if (EFI_ERROR (StatCode)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return FALSE;

+  }

+  //

+  // wait for ACK

+  //

+  for (;;) {

+    if (GetOfferAck (

+          Private,

+          DHCPAckEdit,

+          EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP,

+          &ServerIp,

+          &DhcpServerPort,

+          &ClientIp,

+          &DHCPClientPort,

+          DhcpRxBuf,

+          TimeoutEvent

+          ) != EFI_SUCCESS) {

+      break;

+    }

+    //

+    // check type of response - need DHCPACK

+    //

+    if (CompareMem (

+          &DHCP_REQ_OPTIONS.OpReqIP.Ip,

+          &DhcpRxBuf->u.Dhcpv4.yiaddr,

+          sizeof (EFI_IPv4_ADDRESS)

+          ) || CompareMem (

+          &DHCP_REQ_OPTIONS.DhcServerIpPtr.Ip,

+          &((DHCPV4_OP_SERVER_IP *) DhcpRxBuf->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip,

+          sizeof (EFI_IPv4_ADDRESS)

+          )) {

+      continue;

+    }

+    //

+    // got ACK

+    // check with ARP that IP unused - good return true

+    //

+    if (!SetStationIP (Private)) {

+      //

+      // fail - send DHCPDECLINE and return false

+      //

+      DeclineOffer (Private);

+      break;

+    }

+

+    LocalPtr.OpPtr = DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_SUBNET_MASK_IX - 1];

+

+    if (LocalPtr.OpPtr != NULL) {

+      CopyMem (

+        (EFI_IPv4_ADDRESS *) &Private->EfiBc.Mode->SubnetMask,

+        &LocalPtr.SubnetMaskStr->Ip,

+        sizeof (EFI_IPv4_ADDRESS)

+        );

+    }

+

+    AddRouters (Private, DhcpRxBuf);

+    gBS->CloseEvent (TimeoutEvent);

+    return TRUE;

+  }

+

+  gBS->CloseEvent (TimeoutEvent);

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// try a DHCP server of appropriate type

+//

+STATIC

+BOOLEAN

+TryDHCPFinishDORA (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                TypeIx

+  )

+{

+  INTN  Index;

+

+  //

+  // go through the DHCP servers of the requested type

+  //

+  for (Index = 0; Index < Private->ServerCount[TypeIx]; ++Index) {

+    if (TryFinishDORA (Private, Index = Private->OfferCount[TypeIx][Index])) {

+      if (TypeIx == BINL_IX && !TryFinishBINL (Private, Index)) {

+        continue;

+      }

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// try a DHCP only server and a proxy of appropriate type

+//

+STATIC

+BOOLEAN

+TryProxyFinishDORA (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                TypeIx

+  )

+{

+  INTN  Index;

+

+  if (!Private->GotProxy[TypeIx]) {

+    //

+    // no proxies of the type wanted

+    //

+    return FALSE;

+  }

+  //

+  // go through the DHCP only servers

+  //

+  for (Index = 0; Index < Private->ServerCount[DHCP_ONLY_IX]; ++Index) {

+    if (TryFinishDORA (Private, Private->OfferCount[DHCP_ONLY_IX][Index])) {

+      if (TypeIx != BINL_IX) {

+        CopyProxyRxBuf (Private, Private->GotProxy[TypeIx] - 1);

+      } else if (!TryFinishProxyBINL (Private)) {

+        //

+        // if didn't work with this DHCP, won't work with any

+        //

+        return FALSE;

+      }

+

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// getting to the bottom of the barrel

+//

+STATIC

+BOOLEAN

+TryAnyWithBootfileFinishDORA (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  //

+  // try a DHCP only server who has a bootfile

+  //

+  UNION_PTR LocalPtr;

+  INTN      Index;

+

+  for (Index = 0; Index < Private->ServerCount[DHCP_ONLY_IX]; ++Index) {

+    INTN  offer;

+

+    offer = Private->OfferCount[DHCP_ONLY_IX][Index];

+

+    if (RxBuf[offer].OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] && TryFinishDORA (Private, offer)) {

+      return TRUE;

+    }

+  }

+  //

+  // really at bottom - see if be have any bootps

+  //

+  if (!Private->GotBootp) {

+    return FALSE;

+  }

+

+  DHCP_REQ_OPTIONS.OpReqIP.Ip = *(EFI_IPv4_ADDRESS *) &RxBuf[Private->GotBootp - 1].u.Dhcpv4.yiaddr;

+

+  if (!SetStationIP (Private)) {

+    return FALSE;

+  }

+  //

+  // treat BOOTP response as DHCP ACK packet

+  //

+  CopyParseRxBuf (Private, Private->GotBootp - 1, DHCPV4_ACK_INDEX);

+

+  LocalPtr.OpPtr = RxBuf[Private->GotBootp - 1].OpAdds.PktOptAdds[OP_SUBNET_MASK_IX - 1];

+

+  if (LocalPtr.OpPtr != NULL) {

+    *(EFI_IPv4_ADDRESS *) &Private->EfiBc.Mode->SubnetMask = LocalPtr.SubnetMaskStr->Ip;

+  }

+

+  return TRUE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+/* DoDhcpDora()

+ */

+STATIC

+EFI_STATUS

+DoDhcpDora (

+  PXE_BASECODE_DEVICE *Private,

+  BOOLEAN             SortOffers

+  )

+{

+  EFI_PXE_BASE_CODE_IP_FILTER Filter;

+  EFI_STATUS                  StatCode;

+  INTN                        NumOffers;

+

+  Filter.Filters  = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP | EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST;

+

+  Filter.IpCnt    = 0;

+  Filter.reserved = 0;

+

+  //

+  // set filter unicast or broadcast

+  //

+  if ((StatCode = IpFilter (Private, &Filter)) != EFI_SUCCESS) {

+    return StatCode;

+  }

+  //

+  // seed random number with hardware address

+  //

+  SeedRandom (Private, *(UINT16 *) &Private->SimpleNetwork->Mode->CurrentAddress);

+

+  for (Private->Timeout = 1;

+       Private->Timeout < 17;

+       Private->TotalSeconds = (UINT16) (Private->TotalSeconds + Private->Timeout), Private->Timeout <<= 1

+      ) {

+    INTN  Index;

+

+    InitDhcpv4TxBuf (Private);

+    DHCPV4_TRANSMIT_BUFFER.xid  = Random (Private);

+    DHCPV4_TRANSMIT_BUFFER.secs = HTONS (Private->TotalSeconds);

+

+    //

+    // broadcast DHCPDISCOVER

+    //

+    StatCode = DoUdpWrite (

+                Private,

+                &BroadcastIP,

+                &DhcpServerPort,

+                (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,

+                &DHCPClientPort

+                );

+

+    if (StatCode != EFI_SUCCESS) {

+      return StatCode;

+    }

+

+    CopyMem (

+      &Private->EfiBc.Mode->DhcpDiscover,

+      (EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_TRANSMIT_BUFFER,

+      sizeof (EFI_PXE_BASE_CODE_PACKET)

+      );

+

+    //

+    // get DHCPOFFER's

+    //

+    if ((StatCode = GetOffers (Private)) != EFI_SUCCESS) {

+      if (StatCode != EFI_NO_RESPONSE) {

+        return StatCode;

+      }

+

+      continue;

+    }

+    //

+    // select offer and reply DHCPREQUEST

+    //

+    if (SortOffers) {

+      if (TryDHCPFinishDORA(Private, PXE10_IX) || // try DHCP with PXE10

+        TryDHCPFinishDORA(Private, WfM11a_IX)  || // no - try with WfM

+        TryProxyFinishDORA(Private, PXE10_IX)  || // no - try DHCP only and proxy with PXE10

+        TryProxyFinishDORA(Private, WfM11a_IX) || // no - try DHCP only and proxy with WfM

+        TryDHCPFinishDORA(Private, BINL_IX)    || // no - try with WfM

+        TryProxyFinishDORA(Private, BINL_IX)   || // no - try DHCP only and proxy with PXE10

+        TryAnyWithBootfileFinishDORA(Private))

+      {

+        return EFI_SUCCESS;

+      }

+

+      continue;

+    }

+    //

+    // FIFO order

+    //

+    NumOffers = Private->NumOffersReceived;

+

+    for (Index = 0; Index < NumOffers; ++Index) {

+      //

+      // ignore proxies

+      //

+      if (!RxBuf[Index].u.Dhcpv4.yiaddr) {

+        continue;

+      }

+      //

+      // check if a bootp server

+      //

+      if (!RxBuf[Index].OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1]) {

+        //

+        // it is - just check ARP

+        //

+        if (!SetStationIP (Private)) {

+          continue;

+        }

+      }

+      //

+      // else check if a DHCP only server

+      //

+      else if (!(RxBuf[Index].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE | PXE_TYPE))) {

+        //

+        // it is a normal DHCP offer (without any PXE options), just finish the D.O.R.A by sending DHCP request.

+        //

+        if (!TryFinishDORA (Private, Index)) {

+          continue;

+        }

+      } else if (TryFinishDORA (Private, Index)) {

+        if (!(RxBuf[Index].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE)) && !TryFinishBINL (Private, Index)) {

+          continue;

+        }

+      }

+

+      DEBUG ((EFI_D_WARN, "\nDoDhcpDora()  Got packets.  "));

+      return EFI_SUCCESS;

+    }

+    //

+    // now look for DHCP onlys and a Proxy

+    //

+    for (Index = 0; Index < NumOffers; ++Index) {

+      INT8  Index2;

+

+      //

+      // ignore proxies, bootps, non DHCP onlys, and bootable DHCPS

+      //

+      if (!RxBuf[Index].u.Dhcpv4.yiaddr ||

+          !RxBuf[Index].OpAdds.PktOptAdds[OP_DHCP_MESSAGE_TYPE_IX - 1] ||

+          RxBuf[Index].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE | PXE_TYPE) ||

+          RxBuf[Index].OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]

+          ) {

+        continue;

+      }

+      //

+      // found non bootable DHCP only - try to find a proxy

+      //

+      for (Index2 = 0; Index2 < NumOffers; ++Index2) {

+        if (!RxBuf[Index2].u.Dhcpv4.yiaddr) {

+          if (!TryFinishDORA (Private, Index)) {

+            //

+            // DHCP no ACK

+            //

+            break;

+          }

+

+          if (RxBuf[Index2].OpAdds.Status & (DISCOVER_TYPE | WfM11a_TYPE)) {

+            CopyProxyRxBuf (Private, Index2);

+          } else if (!TryFinishBINL (Private, Index2)) {

+            continue;

+          }

+

+          DEBUG ((EFI_D_WARN, "\nDoDhcpDora()  Got packets.  "));

+          return EFI_SUCCESS;

+        }

+      }

+    }

+  }

+

+  return EFI_NO_RESPONSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// determine if the server ip is in the ip list

+//

+BOOLEAN

+InServerList (

+  EFI_IP_ADDRESS    *ServerIpPtr,

+  PXE_SERVER_LISTS  *ServerListPtr

+  )

+{

+  UINTN Index;

+

+  if (!ServerListPtr || !ServerListPtr->Ipv4List.IpCount) {

+    return TRUE;

+  }

+

+  for (Index = 0; Index < ServerListPtr->Ipv4List.IpCount; ++Index) {

+    if (!CompareMem (

+          ServerIpPtr,

+          &ServerListPtr->Ipv4List.IpList[Index],

+          sizeof (EFI_IPv4_ADDRESS)

+          )) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+BOOLEAN

+ExtractBootServerList (

+  UINT16            Type,

+  DHCPV4_OP_STRUCT  *ptr,

+  PXE_SERVER_LISTS  **ServerListPtr

+  )

+{

+  UNION_PTR LocalPtr;

+  INTN      ServerListLen;

+

+  LocalPtr.OpPtr  = ptr;

+  ServerListLen   = LocalPtr.BootServersStr->Header.Length;

+

+  //

+  // find type

+  //

+  LocalPtr.BootServerList = LocalPtr.BootServersStr->ServerList;

+

+  while (ServerListLen) {

+    INTN  ServerEntryLen;

+

+    ServerEntryLen = sizeof (PXEV4_SERVER_LIST) + 2 + (LocalPtr.BootServerList->u.Ipv4List.IpCount - 1) *

+    sizeof (EFI_IPv4_ADDRESS);

+

+    if (NTOHS (LocalPtr.BootServerList->Type) == Type) {

+      *ServerListPtr = &LocalPtr.BootServerList->u;

+      return TRUE;

+    }

+

+    (LocalPtr.BytePtr) += ServerEntryLen;

+    ServerListLen -= ServerEntryLen;

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+FreeMem (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  if (Private->TransmitBuffer != NULL) {

+    gBS->FreePool (Private->TransmitBuffer);

+    Private->TransmitBuffer = NULL;

+  }

+

+  if (Private->ReceiveBuffers != NULL) {

+    gBS->FreePool (Private->ReceiveBuffers);

+    Private->ReceiveBuffers = NULL;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+BOOLEAN

+GetMem (

+  PXE_BASECODE_DEVICE *Private

+  )

+{

+  EFI_STATUS  Status;

+

+  if (Private->DhcpPacketBuffer == NULL) {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (DHCP_RECEIVE_BUFFER) * (PXE_BIS_INDEX + 1),

+                    &Private->DhcpPacketBuffer

+                    );

+

+    if (EFI_ERROR (Status) || Private->DhcpPacketBuffer == NULL) {

+      Private->DhcpPacketBuffer = NULL;

+      FreeMem (Private);

+      return FALSE;

+    }

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_PXE_BASE_CODE_PACKET),

+                  &Private->TransmitBuffer

+                  );

+

+  if (EFI_ERROR (Status) || Private->TransmitBuffer == NULL) {

+    gBS->FreePool (Private->DhcpPacketBuffer);

+    Private->DhcpPacketBuffer = NULL;

+    Private->TransmitBuffer   = NULL;

+    FreeMem (Private);

+    return FALSE;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (DHCP_RECEIVE_BUFFER) * (MAX_OFFERS),

+                  &Private->ReceiveBuffers

+                  );

+

+  if (EFI_ERROR (Status) || Private->ReceiveBuffers == NULL) {

+    gBS->FreePool (Private->TransmitBuffer);

+    gBS->FreePool (Private->DhcpPacketBuffer);

+    Private->DhcpPacketBuffer = NULL;

+    Private->TransmitBuffer   = NULL;

+    Private->ReceiveBuffers   = NULL;

+    FreeMem (Private);

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+BcDhcp (

+  IN EFI_PXE_BASE_CODE_PROTOCOL *This,

+  IN BOOLEAN                    SortOffers

+  )

+/*++

+Routine description:

+  standard DHCP Discover/Offer/Request/Ack session

+  broadcast DHCPDISCOVER

+  receive DHCPOFFER's

+  broadcast DHCPREQUEST

+  receive DHCPACK

+  check (ARP) good IP

+

+Parameters:

+  This := Pointer to PxeBc interface

+  SortOffers := 

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_IP_FILTER Filter;

+  EFI_PXE_BASE_CODE_MODE      *PxebcMode;

+  PXE_BASECODE_DEVICE         *Private;

+  EFI_STATUS                  StatCode;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  Filter.Filters  = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;

+  Filter.IpCnt    = 0;

+  Filter.reserved = 0;

+

+  DEBUG ((EFI_D_INFO, "\nBcDhcp()  Enter.  "));

+

+  PxebcMode = Private->EfiBc.Mode;

+

+  if (!GetMem (Private)) {

+    DEBUG ((EFI_D_ERROR, "\nBcDhcp()  GetMem() failed.\n"));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  PxebcMode->DhcpDiscoverValid = FALSE;

+  PxebcMode->DhcpAckReceived = FALSE;

+  PxebcMode->ProxyOfferReceived = FALSE;

+

+  Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DHCP;

+

+  //

+  // Issue BC command

+  //

+  if (Private->TotalSeconds == 0) {

+    //

+    // put in seconds field of DHCP send packets

+    //

+    Private->TotalSeconds = 4;

+  }

+

+  if ((StatCode = DoDhcpDora (Private, SortOffers)) == EFI_SUCCESS) {

+    //

+    // success - copy packets

+    //

+    PxebcMode->DhcpDiscoverValid = PxebcMode->DhcpAckReceived = TRUE;

+

+    CopyMem (

+      &PxebcMode->DhcpAck,

+      (EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_ACK_PACKET,

+      sizeof (EFI_PXE_BASE_CODE_PACKET)

+      );

+

+    if (PxebcMode->ProxyOfferReceived) {

+      CopyMem (

+        &PxebcMode->ProxyOffer,

+        (EFI_PXE_BASE_CODE_PACKET *) &PXE_OFFER_PACKET,

+        sizeof (EFI_PXE_BASE_CODE_PACKET)

+        );

+    }

+  }

+  //

+  // set filter back to unicast

+  //

+  IpFilter (Private, &Filter);

+

+  FreeMem (Private);

+

+  //

+  // Unlock the instance data

+  //

+  DEBUG ((EFI_D_WARN, "\nBcDhcp()  Exit = %xh  ", StatCode));

+

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+BOOLEAN

+VerifyCredentialOption (

+  UINT8 *tx,

+  UINT8 *rx

+  )

+{

+  UINTN n;

+

+  //

+  // Fail verification if either pointer is NULL.

+  //

+  if (tx == NULL || rx == NULL) {

+    return FALSE;

+  }

+  //

+  // Fail verification if tx[0] is not a credential type option

+  // or if the length is zero or not a multiple of four.

+  //

+  if (tx[0] != VEND_PXE_CREDENTIAL_TYPES || tx[1] == 0 || tx[1] % 4 != 0) {

+    return FALSE;

+  }

+  //

+  // Fail verification if rx[0] is not a credential type option

+  // or if the length is not equal to four.

+  //

+  if (rx[0] != VEND_PXE_CREDENTIAL_TYPES || rx[1] != 4) {

+    return FALSE;

+  }

+  //

+  // Look through transmitted credential types for a copy

+  // of the received credential type.

+  //

+  for (n = 0; n < tx[1]; n += 4) {

+    if (!CompareMem (&tx[n + 2], &rx[2], 4)) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+DoDiscover (

+  PXE_BASECODE_DEVICE *Private,

+  UINT16              OpFlags,

+  IN UINT16           Type,

+  IN UINT16           *LayerPtr,

+  IN BOOLEAN          UseBis,

+  EFI_IP_ADDRESS      *DestPtr,

+  PXE_SERVER_LISTS    *ServerListPtr

+  )

+/*++

+Routine description: 

+  This function tries to complete the PXE Bootserver and/or boot image

+  discovery sequence.  When this command completes successfully, the

+  PXEdiscover and PXEreply fields in the BC instance data structure are

+  updated.  If the Info pointer is set to NULL, the discovery information

+  in the DHCPack and ProxyOffer packets must be valid and will be used. 

+  If Info is not set to NULL, the discovery methods in the Info field

+  must be set and will be used.  When discovering any layer number other

+  than zero (the credential flag does not count), only unicast discovery

+  is used.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  OpFlags := 

+  Type := 

+  LayerPtr := 

+  UseBis := 

+  DestPtr := 

+  ServerListPtr := 

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_UDP_PORT  ClientPort;

+  EFI_PXE_BASE_CODE_UDP_PORT  ServerPort;

+  EFI_PXE_BASE_CODE_MODE      *PxebcMode;

+  EFI_STATUS                  StatCode;

+  EFI_EVENT                   TimeoutEvent;

+  UINT8                       OpLen;

+

+  PxebcMode = Private->EfiBc.Mode;

+

+  if (DestPtr->Addr[0] == 0) {

+    DEBUG ((EFI_D_WARN, "\nDoDiscover()  !DestPtr->Addr[0]"));

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // seed random number with hardware address

+  //

+  SeedRandom (Private, *(UINT16 *) &Private->SimpleNetwork->Mode->CurrentAddress);

+

+  if (DestPtr->Addr[0] == BroadcastIP.Addr[0]) {

+    ClientPort  = DHCPClientPort;

+    ServerPort  = DhcpServerPort;

+  } else {

+    ClientPort  = PSEUDO_DHCP_CLIENT_PORT;

+    ServerPort  = PseudoDhcpServerPort;

+  }

+

+  if (UseBis) {

+    *LayerPtr |= PXE_BOOT_LAYER_CREDENTIAL_FLAG;

+  } else {

+    *LayerPtr &= PXE_BOOT_LAYER_MASK;

+  }

+

+  for (Private->Timeout = 1;

+       Private->Timeout < 5;

+       Private->TotalSeconds = (UINT16) (Private->TotalSeconds + Private->Timeout), ++Private->Timeout

+      ) {

+    InitDhcpv4TxBuf (Private);

+    //

+    // initialize DHCP message structure

+    //

+    DHCPV4_TRANSMIT_BUFFER.xid  = Random (Private);

+    DHCPV4_TRANSMIT_BUFFER.secs = HTONS (Private->TotalSeconds);

+    CopyMem (

+      &DHCPV4_TRANSMIT_BUFFER.ciaddr,

+      &PxebcMode->StationIp,

+      sizeof DHCPV4_TRANSMIT_BUFFER.ciaddr

+      );

+

+    DHCPV4_OPTIONS_BUFFER.DhcpMessageType.Type  = DHCPREQUEST;

+    DISCOVERoptions.Header.OpCode               = OP_VENDOR_SPECIFIC;

+    DISCOVERoptions.BootItem.Header.OpCode      = VEND_PXE_BOOT_ITEM;

+    DISCOVERoptions.BootItem.Header.Length      = DHCPV4_OPTION_LENGTH (PXE_OP_BOOT_ITEM);

+    DISCOVERoptions.BootItem.Type               = HTONS (Type);

+    DISCOVERoptions.BootItem.Layer              = HTONS (*LayerPtr);

+

+    if (UseBis) {

+      EFI_BIS_PROTOCOL        *BisPtr;

+      BIS_APPLICATION_HANDLE  BisAppHandle;

+      EFI_BIS_DATA            *BisDataSigInfo;

+      EFI_BIS_SIGNATURE_INFO  *BisSigInfo;

+      UINTN                   Index;

+      UINTN                   Index2;

+

+      BisPtr = PxebcBisStart (

+                Private,

+                &BisAppHandle,

+                &BisDataSigInfo

+                );

+

+      if (BisPtr == NULL) {

+        //

+        // %%TBD - In order to get here, BIS must have

+        // been present when PXEBC.Start() was called.

+        // BIS had to be shutdown/removed/damaged

+        // before PXEBC.Discover() was called.

+        // Do we need to document a specific error

+        // for this case?

+        //

+        return EFI_OUT_OF_RESOURCES;

+      }

+      //

+      // Compute number of credential types.

+      //

+      Index2                        = BisDataSigInfo->Length / sizeof (EFI_BIS_SIGNATURE_INFO);

+

+      DISCREDoptions.Header.OpCode  = VEND_PXE_CREDENTIAL_TYPES;

+

+      DISCREDoptions.Header.Length  = (UINT8) (Index2 * sizeof (PXE_CREDENTIAL));

+

+      OpLen = (UINT8) (DHCPV4_OPTION_LENGTH (PXE_DISCOVER_OPTIONS) + sizeof (DHCPV4_OP_HEADER) + DISCREDoptions.Header.Length);

+

+      BisSigInfo = (EFI_BIS_SIGNATURE_INFO *) BisDataSigInfo->Data;

+

+      for (Index = 0; Index < Index2; ++Index) {

+        UINT32  x;

+

+        CopyMem (&x, &BisSigInfo[Index], sizeof x);

+        x = HTONL (x);

+        CopyMem (&DISCREDoptions.Credentials[Index], &x, sizeof x);

+      }

+

+      PxebcBisStop (BisPtr, BisAppHandle, BisDataSigInfo);

+    } else {

+      OpLen = DHCPV4_OPTION_LENGTH (PXE_DISCOVER_OPTIONS);

+    }

+

+    DISCOVERoptions.Header.Length = OpLen;

+

+    ((UINT8 *) &DISCOVERoptions)[sizeof (DHCPV4_OP_HEADER) + OpLen - 1] = OP_END;

+    ((UINT8 *) &DISCOVERoptions)[sizeof (DHCPV4_OP_HEADER) + OpLen]     = OP_END;

+

+    StatCode = DoUdpWrite (

+                Private,

+                DestPtr,

+                &ServerPort,

+                (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,

+                &ClientPort

+                );

+

+    if (StatCode != EFI_SUCCESS) {

+      return StatCode;

+    }

+    //

+    //

+    //

+    StatCode = gBS->CreateEvent (

+                      EFI_EVENT_TIMER,

+                      EFI_TPL_CALLBACK,

+                      NULL,

+                      NULL,

+                      &TimeoutEvent

+                      );

+

+    if (EFI_ERROR (StatCode)) {

+      return StatCode;

+    }

+

+    StatCode = gBS->SetTimer (

+                      TimeoutEvent,

+                      TimerRelative,

+                      Private->Timeout * 10000000 + 1000000

+                      );

+

+    if (EFI_ERROR (StatCode)) {

+      gBS->CloseEvent (TimeoutEvent);

+      return StatCode;

+    }

+    //

+    // wait for ACK

+    //

+    for (;;) {

+      DHCP_RECEIVE_BUFFER *RxBufPtr;

+      UINT16              TmpType;

+      UINT16              TmpLayer;

+

+      RxBufPtr = UseBis ? &PXE_BIS_BUFFER : &PXE_ACK_BUFFER;

+      ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS));

+

+      if (GetOfferAck (

+            Private,

+            AckEdit,

+            OpFlags,

+            (EFI_IP_ADDRESS *) &Private->ServerIp,

+            0,

+            (EFI_IP_ADDRESS *) &DHCPV4_TRANSMIT_BUFFER.ciaddr,

+            &ClientPort,

+            RxBufPtr,

+            TimeoutEvent

+            ) != EFI_SUCCESS) {

+        break;

+      }

+      //

+      // check type of response - need PXEClient DHCPACK of proper type with bootfile

+      //

+      if (!(RxBufPtr->OpAdds.Status & PXE_TYPE) ||

+          (UseBis && (RxBufPtr->OpAdds.Status & USE_THREE_BYTE)) ||

+          !RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1] ||

+          !RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1] ||

+          !InServerList((EFI_IP_ADDRESS *)&((DHCPV4_OP_SERVER_IP *)RxBufPtr->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX-1])->Ip, ServerListPtr)) {

+

+        continue;

+      }

+

+      TmpType = TmpLayer = 0;

+

+      if (RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1]) {

+        TmpType = NTOHS (((PXE_OP_BOOT_ITEM *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1])->Type);

+

+        if (RxBufPtr->OpAdds.Status & USE_THREE_BYTE) {

+          TmpLayer = (UINT16) (((PXE_OP_BOOT_ITEM *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1])->Layer >> 8);

+        } else {

+          TmpLayer = NTOHS (((PXE_OP_BOOT_ITEM *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_ITEM_IX - 1])->Layer);

+        }

+      }

+

+      if (TmpType != Type) {

+        continue;

+      }

+

+      if (UseBis) {

+        if (!RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_CREDENTIAL_TYPES_IX - 1]) {

+          continue;

+        }

+

+        if (!VerifyCredentialOption (

+              (UINT8 *) &DISCREDoptions.Header,

+              (UINT8 *) RxBufPtr->OpAdds.PxeOptAdds[VEND_PXE_CREDENTIAL_TYPES_IX - 1]

+              )) {

+          continue;

+        }

+      }

+

+      *LayerPtr = TmpLayer;

+

+      if (UseBis) {

+        CopyMem (

+          &PxebcMode->PxeBisReply,

+          &RxBufPtr->u.Dhcpv4,

+          sizeof (EFI_PXE_BASE_CODE_PACKET)

+          );

+

+        PxebcMode->PxeBisReplyReceived = TRUE;

+

+        StatCode = DoDiscover (

+                    Private,

+                    EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+                    Type,

+                    LayerPtr,

+                    FALSE,

+                    &Private->ServerIp,

+                    0

+                    );

+

+        gBS->CloseEvent (TimeoutEvent);

+        return StatCode;

+      }

+

+      PxebcMode->PxeDiscoverValid = PxebcMode->PxeReplyReceived = TRUE;

+

+      CopyMem (

+        &PxebcMode->PxeDiscover,

+        &*(EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_TRANSMIT_BUFFER,

+        sizeof (*(EFI_PXE_BASE_CODE_PACKET *) &DHCPV4_TRANSMIT_BUFFER)

+        );

+

+      CopyMem (

+        &PxebcMode->PxeReply,

+        &*(EFI_PXE_BASE_CODE_PACKET *) &RxBufPtr->u.Dhcpv4,

+        sizeof (*(EFI_PXE_BASE_CODE_PACKET *) &RxBufPtr->u.Dhcpv4)

+        );

+

+      AddRouters (Private, RxBufPtr);

+

+      gBS->CloseEvent (TimeoutEvent);

+      return EFI_SUCCESS;

+    }

+

+    gBS->CloseEvent (TimeoutEvent);

+  }

+  //

+  // end for loop

+  //

+  return EFI_TIMEOUT;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+Discover (

+  PXE_BASECODE_DEVICE                 *Private,

+  IN UINT16                           Type,

+  IN UINT16                           *LayerPtr,

+  IN BOOLEAN                          UseBis,

+  IN EFI_PXE_BASE_CODE_DISCOVER_INFO  *DiscoverInfoPtr,

+  PXE_SERVER_LISTS                    *McastServerListPtr,

+  PXE_SERVER_LISTS                    *ServerListPtr

+  )

+/*++

+Routine Description:

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  Type := 

+  LayerPtr := 

+  UseBis := 

+  DiscoverInfoPtr := 

+  McastServerListPtr := 

+  ServerListPtr := 

+

+Returns:

+--*/

+{

+  EFI_IP_ADDRESS  DestIp;

+  EFI_STATUS      StatCode;

+

+  DEBUG ((EFI_D_INFO, "\nDiscover()  Type=%d  Layer=%d  ", Type, *LayerPtr));

+

+  if (UseBis) {

+    DEBUG ((EFI_D_INFO, "BIS  "));

+  }

+  //

+  // get dest IP addr - mcast, bcast, or unicast

+  //

+  if (DiscoverInfoPtr->UseMCast) {

+    DestIp.v4 = DiscoverInfoPtr->ServerMCastIp.v4;

+

+    DEBUG (

+      (EFI_D_INFO,

+      "\nDiscover()  MCast %d.%d.%d.%d  ",

+      DestIp.v4.Addr[0],

+      DestIp.v4.Addr[1],

+      DestIp.v4.Addr[2],

+      DestIp.v4.Addr[3])

+      );

+

+    if ((StatCode = DoDiscover (

+                      Private,

+                      EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+                      Type,

+                      LayerPtr,

+                      UseBis,

+                      &DestIp,

+                      McastServerListPtr

+                      )) != EFI_TIMEOUT) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nDiscover()  status == %r (%Xh)",

+        StatCode,

+        StatCode)

+        );

+

+      return StatCode;

+    }

+  }

+

+  if (DiscoverInfoPtr->UseBCast) {

+    DEBUG ((EFI_D_INFO, "\nDiscver()  BCast  "));

+

+    if ((StatCode = DoDiscover (

+                      Private,

+                      EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+                      Type,

+                      LayerPtr,

+                      UseBis,

+                      &BroadcastIP,

+                      McastServerListPtr

+                      )) != EFI_TIMEOUT) {

+

+      DEBUG ((EFI_D_WARN, "\nDiscover()  status == %r (%Xh)", StatCode, StatCode));

+

+      return StatCode;

+    }

+  }

+

+  if (DiscoverInfoPtr->UseUCast) {

+    UINTN Index;

+

+    DEBUG (

+      (EFI_D_INFO,

+      "\nDiscover()  UCast  IP#=%d  ",

+      ServerListPtr->Ipv4List.IpCount)

+      );

+

+    for (Index = 0; Index < ServerListPtr->Ipv4List.IpCount; ++Index) {

+      CopyMem (&DestIp, &ServerListPtr->Ipv4List.IpList[Index], 4);

+

+      DEBUG (

+        (EFI_D_INFO,

+        "\nDiscover()  UCast %d.%d.%d.%d  ",

+        DestIp.v4.Addr[0],

+        DestIp.v4.Addr[1],

+        DestIp.v4.Addr[2],

+        DestIp.v4.Addr[3])

+        );

+

+      if ((StatCode = DoDiscover (

+                        Private,

+                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+                        Type,

+                        LayerPtr,

+                        UseBis,

+                        &DestIp,

+                        0

+                        )) != EFI_TIMEOUT) {

+        DEBUG (

+          (EFI_D_WARN,

+          "\nDiscover()  status == %r (%Xh)",

+          StatCode,

+          StatCode)

+          );

+

+        return StatCode;

+      }

+    }

+  }

+

+  DEBUG ((EFI_D_WARN, "\nDiscover()  TIMEOUT"));

+

+  return EFI_TIMEOUT;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+/* BcDiscover()

+ */

+EFI_STATUS

+EFIAPI

+BcDiscover (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN UINT16                           Type,

+  IN UINT16                           *LayerPtr,

+  IN BOOLEAN                          UseBis,

+  IN EFI_PXE_BASE_CODE_DISCOVER_INFO  * DiscoverInfoPtr OPTIONAL

+  )

+/*++

+Routine description:

+

+Parameters:

+  This := 

+  Type := 

+  LayerPtr := 

+  UseBis := 

+  DiscoverInfoPtr := 

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_DISCOVER_INFO DefaultInfo;

+  EFI_PXE_BASE_CODE_MODE          *PxebcMode;

+  DHCP_RECEIVE_BUFFER             *DhcpRxBuf;

+  PXE_SERVER_LISTS                DefaultSrvList;

+  PXE_SERVER_LISTS                *ServerListPtr;

+  PXE_SERVER_LISTS                *McastServerListPtr;

+  EFI_STATUS                      Status;

+  UNION_PTR                       LocalPtr;

+  UINTN                           Index;

+  UINTN                           Index2;

+  BOOLEAN                         AcquiredSrvList;

+  EFI_STATUS                      StatCode;

+  PXE_BASECODE_DEVICE             *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  ServerListPtr       = NULL;

+  McastServerListPtr  = NULL;

+  AcquiredSrvList     = FALSE;

+

+  PxebcMode           = Private->EfiBc.Mode;

+

+  if (!GetMem (Private)) {

+    EfiReleaseLock (&Private->Lock);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  if (UseBis) {

+    if (!PxebcMode->BisSupported) {

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER;

+

+  if (Private->TotalSeconds == 0) {

+    //

+    // put in seconds field of DHCP send packets

+    //

+    Private->TotalSeconds = 4;

+  }

+

+  ZeroMem (&DefaultInfo, sizeof (EFI_PXE_BASE_CODE_DISCOVER_INFO));

+

+  //

+  // if layer number not zero, use previous discover

+  //

+  if (*LayerPtr != 0) {

+    DEBUG ((EFI_D_WARN, "\nBcDiscover()  layer != 0"));

+

+    if (DiscoverInfoPtr != NULL) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  layer != 0 && DiscoverInfoPtr != NULL\n"));

+

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (!PxebcMode->PxeDiscoverValid) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  layer != 0 && PxeDiscoverValid == 0\n"));

+

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (!PxebcMode->PxeReplyReceived) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  layer != 0 && PxeReplyReceived == 0\n"));

+

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (UseBis && !PxebcMode->PxeBisReplyReceived) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  layer != 0 && PxeBisReplyReceived == 0\n"));

+

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    DefaultInfo.UseUCast            = TRUE;

+    DiscoverInfoPtr                 = &DefaultInfo;

+

+    DefaultSrvList.Ipv4List.IpCount = 1;

+    CopyMem (&DefaultSrvList.Ipv4List.IpList[0], &Private->ServerIp, 4);

+

+    ServerListPtr = &DefaultSrvList;

+  }

+  //

+  // layer is zero - see if info is supplied or if we need to use info from a cached offer

+  //

+  else if (!DiscoverInfoPtr) {

+    //

+    // not supplied - generate it

+    // make sure that there is cached, appropriate information

+    // if neither DhcpAck packet nor ProxyOffer packet has pxe info, fail

+    //

+    DhcpRxBuf = (PxebcMode->ProxyOfferReceived) ? &PXE_OFFER_BUFFER : &DHCPV4_ACK_BUFFER;

+

+    if (!PxebcMode->DhcpAckReceived || !(DhcpRxBuf->OpAdds.Status & DISCOVER_TYPE)) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  !ack && !proxy"));

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    DiscoverInfoPtr = &DefaultInfo;

+

+    LocalPtr.OpPtr  = DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1];

+

+    //

+    // if multicast enabled, need multicast address

+    //

+    if (!(LocalPtr.DiscoveryControl->ControlBits & DISABLE_MCAST)) {

+      DefaultInfo.UseMCast = TRUE;

+

+      CopyMem (

+        ((EFI_IPv4_ADDRESS *) &DefaultInfo.ServerMCastIp),

+        &((DHCPV4_OP_IP_ADDRESS *) DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_MCAST_ADDR_IX - 1])->Ip,

+        sizeof (EFI_IPv4_ADDRESS)

+        );

+    }

+

+    DefaultInfo.UseBCast    = (BOOLEAN) ((LocalPtr.DiscoveryControl->ControlBits & DISABLE_BCAST) == 0);

+

+    DefaultInfo.MustUseList = (BOOLEAN) ((LocalPtr.DiscoveryControl->ControlBits & USE_ACCEPT_LIST) != 0);

+

+    DefaultInfo.UseUCast = (BOOLEAN)

+      (

+        (DefaultInfo.MustUseList) ||

+        ((LocalPtr.DiscoveryControl->ControlBits & (DISABLE_MCAST | DISABLE_BCAST)) == (DISABLE_MCAST | DISABLE_BCAST))

+      );

+

+    if ((DefaultInfo.UseUCast | DefaultInfo.MustUseList) && !ExtractBootServerList (

+                                                              Type,

+                                                              DhcpRxBuf->OpAdds.PxeOptAdds[VEND_PXE_BOOT_SERVERS_IX - 1],

+                                                              &ServerListPtr

+                                                              )) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  type not in list"));

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Info supplied - make SrvList if required

+  // if we use ucast discovery or must use list, there better be one

+  //

+  else if (DiscoverInfoPtr->UseUCast || DiscoverInfoPtr->MustUseList) {

+    //

+    // there better be a list

+    //

+    if (DiscoverInfoPtr->IpCnt == 0) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  no bootserver list"));

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // get its size

+    //

+    for (Index = Index2 = 0; Index < DiscoverInfoPtr->IpCnt; ++Index) {

+      if (DiscoverInfoPtr->SrvList[Index].Type == Type) {

+        if (DiscoverInfoPtr->SrvList[Index].AcceptAnyResponse) {

+          if (Index2 != 0) {

+            DEBUG ((EFI_D_WARN, "\nBcDiscover()  accept any?"));

+            EfiReleaseLock (&Private->Lock);

+            return EFI_INVALID_PARAMETER;

+          } else {

+            Index2                          = 1;

+            DefaultSrvList.Ipv4List.IpCount = 0;

+            ServerListPtr                   = &DefaultSrvList;

+            break;

+          }

+        } else {

+          ++Index2;

+        }

+      }

+    }

+

+    if (Index2 == 0) {

+      DEBUG ((EFI_D_WARN, "\nBcDiscover()  !Index2?"));

+      EfiReleaseLock (&Private->Lock);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (ServerListPtr == NULL) {

+      Status = gBS->AllocatePool (

+                      EfiBootServicesData,

+                      sizeof (PXEV4_SERVER_LIST) + (Index2 - 1) * sizeof (EFI_IPv4_ADDRESS),

+                      (VOID **) &ServerListPtr

+                      );

+

+      if (EFI_ERROR (Status) || ServerListPtr == NULL) {

+        ServerListPtr = NULL;

+        EfiReleaseLock (&Private->Lock);

+        return EFI_OUT_OF_RESOURCES;

+      }

+      //

+      // build an array of IP addresses from the server list

+      //

+      AcquiredSrvList                 = TRUE;

+      ServerListPtr->Ipv4List.IpCount = (UINT8) Index2;

+

+      for (Index = Index2 = 0; Index < DiscoverInfoPtr->IpCnt; ++Index) {

+        if (DiscoverInfoPtr->SrvList[Index].Type == Type) {

+          CopyMem (

+            &ServerListPtr->Ipv4List.IpList[Index2++],

+            &DiscoverInfoPtr->SrvList[Index].IpAddr.v4,

+            sizeof ServerListPtr->Ipv4List.IpList[0]

+            );

+        }

+      }

+    }

+  }

+

+  if (DiscoverInfoPtr->MustUseList) {

+    McastServerListPtr = ServerListPtr;

+  }

+

+  if (!(DiscoverInfoPtr->UseMCast || DiscoverInfoPtr->UseBCast || DiscoverInfoPtr->UseUCast)) {

+    DEBUG ((EFI_D_WARN, "\nBcDiscover()  Nothing to use!\n"));

+

+    EfiReleaseLock (&Private->Lock);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PxebcMode->PxeDiscoverValid = PxebcMode->PxeReplyReceived = PxebcMode->PxeBisReplyReceived = FALSE;

+

+  StatCode = Discover (

+              Private,

+              Type,

+              LayerPtr,

+              UseBis,

+              DiscoverInfoPtr,

+              McastServerListPtr,

+              ServerListPtr

+              );

+

+  if (AcquiredSrvList) {

+    gBS->FreePool (ServerListPtr);

+  }

+

+  FreeMem (Private);

+

+  //

+  // Unlock the instance data

+  //

+  DEBUG (

+    (EFI_D_INFO,

+    "\nBcDiscover()  status == %r (%Xh)\n",

+    StatCode,

+    StatCode)

+    );

+

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+BcSetPackets (

+  IN EFI_PXE_BASE_CODE_PROTOCOL   * This,

+  BOOLEAN                         *NewDhcpDiscoverValid, OPTIONAL

+  BOOLEAN                         *NewDhcpAckReceived, OPTIONAL

+  BOOLEAN                         *NewProxyOfferReceived, OPTIONAL

+  BOOLEAN                         *NewPxeDiscoverValid, OPTIONAL

+  BOOLEAN                         *NewPxeReplyReceived, OPTIONAL

+  BOOLEAN                         *NewPxeBisReplyReceived, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET     * NewDhcpDiscover, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET     * NewDhcpAck, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET     * NewProxyOffer, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET     * NewPxeDiscover, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET     * NewPxeReply, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET     * NewPxeBisReply OPTIONAL

+  )

+/*++

+Routine description:

+

+Parameters:

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxebcMode;

+  EFI_STATUS              Status;

+  EFI_STATUS              StatCode;

+  PXE_BASECODE_DEVICE     *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  PxebcMode = Private->EfiBc.Mode;

+

+  if (Private->DhcpPacketBuffer == NULL) {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (DHCP_RECEIVE_BUFFER) * (PXE_BIS_INDEX + 1),

+                    &Private->DhcpPacketBuffer

+                    );

+

+    if (EFI_ERROR (Status) || Private->DhcpPacketBuffer == NULL) {

+      Private->DhcpPacketBuffer = NULL;

+      EfiReleaseLock (&Private->Lock);

+      return EFI_OUT_OF_RESOURCES;

+    }

+  }

+  //

+  // Issue BC command

+  //

+  //

+  // reset

+  //

+  Private->FileSize = 0;

+  if (NewDhcpDiscoverValid != NULL) {

+    PxebcMode->DhcpDiscoverValid = *NewDhcpDiscoverValid;

+  }

+

+  if (NewDhcpAckReceived != NULL) {

+    PxebcMode->DhcpAckReceived = *NewDhcpAckReceived;

+  }

+

+  if (NewProxyOfferReceived != NULL) {

+    PxebcMode->ProxyOfferReceived = *NewProxyOfferReceived;

+  }

+

+  if (NewPxeDiscoverValid != NULL) {

+    PxebcMode->PxeDiscoverValid = *NewPxeDiscoverValid;

+  }

+

+  if (NewPxeReplyReceived != NULL) {

+    PxebcMode->PxeReplyReceived = *NewPxeReplyReceived;

+  }

+

+  if (NewPxeBisReplyReceived != NULL) {

+    PxebcMode->PxeBisReplyReceived = *NewPxeBisReplyReceived;

+  }

+

+  if (NewDhcpDiscover != NULL) {

+    CopyMem (

+      &PxebcMode->DhcpDiscover,

+      NewDhcpDiscover,

+      sizeof *NewDhcpDiscover

+      );

+  }

+

+  if (NewDhcpAck != NULL) {

+    CopyParse (Private, &PxebcMode->DhcpAck, NewDhcpAck, DHCPV4_ACK_INDEX);

+  }

+

+  if (NewProxyOffer != NULL) {

+    CopyParse (Private, &PxebcMode->ProxyOffer, NewProxyOffer, PXE_OFFER_INDEX);

+  }

+

+  if (NewPxeDiscover != NULL) {

+    CopyMem (

+      &PxebcMode->PxeDiscover,

+      NewPxeDiscover,

+      sizeof *NewPxeDiscover

+      );

+  }

+

+  if (NewPxeReply != NULL) {

+    CopyParse (Private, &PxebcMode->PxeReply, NewPxeReply, PXE_ACK_INDEX);

+  }

+

+  if (NewPxeBisReply != NULL) {

+    CopyParse (Private, &PxebcMode->PxeBisReply, NewPxeBisReply, PXE_BIS_INDEX);

+  }

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+  return EFI_SUCCESS;

+}

+

+/* eof - pxe_bc_dhcp.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_igmp.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_igmp.c
new file mode 100644
index 0000000..f4935b2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_igmp.c
@@ -0,0 +1,476 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+--*/

+

+

+

+

+#define RAND_MAX  0x10000

+#include "Bc.h"

+

+//

+// Definitions for internet group management protocol version 2 message

+// structure Per RFC 2236, November 1997

+//

+STATIC UINT8      RouterAlertOption[4]  = { 0x80 | 20, 4, 0, 0 };

+STATIC IPV4_ADDR  AllRoutersGroup       = { { 224, 0, 0, 2 } };

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+ClearGroupTimer (

+  PXE_BASECODE_DEVICE *Private,

+  UINTN               TimerId

+  )

+{

+  if (Private == NULL) {

+    return ;

+  }

+

+  if (TimerId >= Private->MCastGroupCount) {

+    return ;

+  }

+

+  if (Private->IgmpGroupEvent[TimerId] == NULL) {

+    return ;

+  }

+

+  gBS->CloseEvent (Private->IgmpGroupEvent[TimerId]);

+  Private->IgmpGroupEvent[TimerId] = NULL;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+SetGroupTimer (

+  PXE_BASECODE_DEVICE *Private,

+  UINTN               TimerId,

+  UINTN               MaxRespTime

+  )

+/*++

+Routine description:

+  Set IGMP response timeout value.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  TimerId := Timer ID#

+  MaxRespTime := Base response timeout value in tenths of seconds

+

+Returns:

+--*/

+{

+  EFI_STATUS  EfiStatus;

+

+  if (Private == NULL) {

+    return ;

+  }

+

+  if (TimerId >= Private->MCastGroupCount) {

+    return ;

+  }

+

+  if (Private->IgmpGroupEvent[TimerId] != NULL) {

+    gBS->CloseEvent (Private->IgmpGroupEvent[TimerId]);

+  }

+

+  EfiStatus = gBS->CreateEvent (

+                    EFI_EVENT_TIMER,

+                    EFI_TPL_CALLBACK,

+                    NULL,

+                    NULL,

+                    &Private->IgmpGroupEvent[TimerId]

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    Private->IgmpGroupEvent[TimerId] = NULL;

+    return ;

+  }

+

+  EfiStatus = gBS->SetTimer (

+                    Private->IgmpGroupEvent[TimerId],

+                    TimerRelative,

+                    MaxRespTime * 1000000 + Random (Private) % RAND_MAX

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    gBS->CloseEvent (Private->IgmpGroupEvent[TimerId]);

+    Private->IgmpGroupEvent[TimerId] = NULL;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+SendIgmpMessage (

+  PXE_BASECODE_DEVICE *Private,

+  UINT8               Type,

+  INTN                GroupId

+  )

+/*++

+Routine description:

+  Send an IGMP message

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  Type := Message type opcode

+  GroupId := Group ID#

+

+Returns:

+--*/

+{

+  Private->IgmpMessage.Type         = Type;

+  Private->IgmpMessage.MaxRespTime  = 0;

+  Private->IgmpMessage.Checksum     = 0;

+  Private->IgmpMessage.GroupAddress = Private->MCastGroup[GroupId];

+  Private->IgmpMessage.Checksum = IpChecksum (

+                                    (UINT16 *) &Private->IgmpMessage,

+                                    sizeof Private->IgmpMessage

+                                    );

+

+  Ipv4SendWOp (

+    Private,

+    0,

+    (UINT8 *) &Private->IgmpMessage,

+    sizeof Private->IgmpMessage,

+    PROT_IGMP,

+    RouterAlertOption,

+    sizeof RouterAlertOption,

+    ((Type == IGMP_TYPE_LEAVE_GROUP) ? AllRoutersGroup.L : Private->IgmpMessage.GroupAddress),

+    EFI_PXE_BASE_CODE_FUNCTION_IGMP

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+ReportIgmp (

+  PXE_BASECODE_DEVICE *Private,

+  INTN                GroupId

+  )

+/*++

+Routine description:

+  Send an IGMP report message.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  GroupId := Group ID#

+

+Returns:

+--*/

+{

+  //

+  // if version 1 querier, send v1 report

+  //

+  UINT8 Type;

+

+  if (Private->Igmpv1TimeoutEvent != NULL) {

+    if (!EFI_ERROR (gBS->CheckEvent (Private->Igmpv1TimeoutEvent))) {

+      gBS->CloseEvent (Private->Igmpv1TimeoutEvent);

+      Private->Igmpv1TimeoutEvent = NULL;

+      Private->UseIgmpv1Reporting = TRUE;

+    }

+  }

+

+  Type = (UINT8) (Private->UseIgmpv1Reporting ? IGMP_TYPE_V1REPORT : IGMP_TYPE_REPORT);

+

+  SendIgmpMessage (Private, Type, GroupId);

+  ClearGroupTimer (Private, GroupId);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+IgmpCheckTimers (

+  PXE_BASECODE_DEVICE *Private

+  )

+/*++

+Routine description:

+  Check IGMP timers and send reports for all groups that have expired.

+Parameters:

+  Private := Pointer to PxeBc interface

+

+Returns:

+--*/

+{

+  UINTN GroupId;

+

+  if (Private == NULL) {

+    return ;

+  }

+

+  for (GroupId = 0; GroupId < Private->MCastGroupCount; ++GroupId) {

+    if (Private->IgmpGroupEvent[GroupId] == NULL) {

+      continue;

+    }

+

+    if (!EFI_ERROR (gBS->CheckEvent (Private->IgmpGroupEvent[GroupId]))) {

+      //

+      // send a report

+      //

+      ReportIgmp (Private, GroupId);

+    }

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+INTN

+FindMulticastGroup (

+  PXE_BASECODE_DEVICE *Private,

+  UINT32              GroupAddress

+  )

+/*++

+Routine description:

+  Fund group ID# (index).

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  GroupAddress := Group multicast address

+

+Returns:

+  0 := Group not found

+  other := Group ID#

+--*/

+{

+  UINTN GroupId;

+

+  for (GroupId = 0; GroupId < Private->MCastGroupCount; ++GroupId) {

+    if (Private->MCastGroup[GroupId] == GroupAddress) {

+      return GroupId + 1;

+    }

+  }

+

+  return 0;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+IgmpJoinGroup (

+  PXE_BASECODE_DEVICE  *Private,

+  EFI_IP_ADDRESS       *GroupPtr

+  )

+/*++

+Routine description:

+  Join multicast group.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  GroupPtr := Pointer to group mutlicast IP address.

+

+Returns:

+--*/

+{

+  UINT32  Grp;

+

+  Grp = *(UINT32 *) GroupPtr;

+

+#if SUPPORT_IPV6

+  if (Private->EfiBc.Mode->UsingIpv6) {

+    //

+    // TBD

+    //

+  }

+#endif

+  //

+  // see if we already have it or if we can't take anymore

+  //

+  if (FindMulticastGroup (Private, Grp) || Private->MCastGroupCount == MAX_MCAST_GROUPS) {

+    return ;

+  }

+  //

+  // add the group

+  //

+  Private->MCastGroup[Private->MCastGroupCount] = Grp;

+

+  ReportIgmp (Private, Private->MCastGroupCount);

+  //

+  // send a report

+  // so it will get sent again per RFC 2236

+  //

+  SetGroupTimer (

+    Private,

+    Private->MCastGroupCount++,

+    UNSOLICITED_REPORT_INTERVAL * 10

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+IgmpLeaveGroup (

+  PXE_BASECODE_DEVICE       *Private,

+  EFI_IP_ADDRESS            *GroupPtr

+  )

+/*++

+Routine description:

+  Leave multicast group.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  GroupPtr := Mutlicast group IP address.

+

+Returns:

+--*/

+{

+  UINT32  Grp;

+  UINTN   GroupId;

+

+  Grp = *(UINT32 *) GroupPtr;

+

+#if SUPPORT_IPV6

+  if (Private->EfiBc.Mode->UsingIpv6) {

+    //

+    // TBD

+    //

+  }

+#endif

+  //

+  // if not in group, ignore

+  //

+  GroupId = FindMulticastGroup (Private, Grp);

+

+  if (GroupId == 0) {

+    return ;

+  }

+  //

+  // if not v1 querrier, send leave group IGMP message

+  //

+  if (Private->Igmpv1TimeoutEvent != NULL) {

+    if (!EFI_ERROR (gBS->CheckEvent (Private->Igmpv1TimeoutEvent))) {

+      gBS->CloseEvent (Private->Igmpv1TimeoutEvent);

+      Private->Igmpv1TimeoutEvent = NULL;

+      Private->UseIgmpv1Reporting = TRUE;

+    } else {

+      SendIgmpMessage (Private, IGMP_TYPE_LEAVE_GROUP, GroupId - 1);

+    }

+  }

+

+  while (GroupId < Private->MCastGroupCount) {

+    Private->MCastGroup[GroupId - 1]      = Private->MCastGroup[GroupId];

+    Private->IgmpGroupEvent[GroupId - 1]  = Private->IgmpGroupEvent[GroupId];

+    ++GroupId;

+  }

+

+  --Private->MCastGroupCount;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+HandleIgmp (

+  PXE_BASECODE_DEVICE *Private,

+  IGMPV2_MESSAGE      *IgmpMessagePtr,

+  UINTN               IgmpLength

+  )

+/*++

+Routine description:

+  Handle received IGMP packet

+

+Parameters:

+  Private         := Pointer to PxeBc interface

+  IgmpMessagePtr  := Pointer to IGMP packet

+  IgmpLength      := packet length in bytes

+

+Returns:

+--*/

+{

+  EFI_STATUS  EfiStatus;

+  UINTN       GroupId;

+  INTN        MaxRespTime;

+

+  if (Private == NULL) {

+    return ;

+  }

+

+  if (Private->MCastGroupCount == 0) {

+    //

+    // if we don't belong to any multicast groups, ignore

+    //

+    return ;

+  }

+  //

+  // verify checksum

+  //

+  if (IpChecksum ((UINT16 *) IgmpMessagePtr, IgmpLength)) {

+    //

+    // bad checksum - ignore packet

+    //

+    return ;

+  }

+

+  switch (IgmpMessagePtr->Type) {

+  case IGMP_TYPE_QUERY:

+    //

+    // if a version 1 querier, note the fact and set max resp time

+    //

+    MaxRespTime = IgmpMessagePtr->MaxRespTime;

+

+    if (MaxRespTime == 0) {

+      Private->UseIgmpv1Reporting = TRUE;

+

+      if (Private->Igmpv1TimeoutEvent != NULL) {

+        gBS->CloseEvent (Private->Igmpv1TimeoutEvent);

+      }

+

+      EfiStatus = gBS->CreateEvent (

+                        EFI_EVENT_TIMER,

+                        EFI_TPL_CALLBACK,

+                        NULL,

+                        NULL,

+                        &Private->Igmpv1TimeoutEvent

+                        );

+

+      if (EFI_ERROR (EfiStatus)) {

+        Private->Igmpv1TimeoutEvent = NULL;

+      } else {

+        EfiStatus = gBS->SetTimer (

+                          Private->Igmpv1TimeoutEvent,

+                          TimerRelative,

+                          (UINT64) V1ROUTER_PRESENT_TIMEOUT * 10000000

+                          );

+      }

+

+      MaxRespTime = IGMP_DEFAULT_MAX_RESPONSE_TIME * 10;

+    }

+    //

+    // if a general query (!GroupAddress), set all our group timers

+    //

+    if (!IgmpMessagePtr->GroupAddress) {

+      for (GroupId = 0; GroupId < Private->MCastGroupCount; ++GroupId) {

+        SetGroupTimer (Private, GroupId, MaxRespTime);

+      }

+    } else {

+      //

+      // specific query - set only specific group

+      //

+      GroupId = FindMulticastGroup (Private, IgmpMessagePtr->GroupAddress);

+

+      if (GroupId != 0) {

+        SetGroupTimer (Private, GroupId - 1, MaxRespTime);

+      }

+    }

+

+    break;

+

+  //

+  // if we have a timer running for this group, clear it

+  //

+  case IGMP_TYPE_V1REPORT:

+  case IGMP_TYPE_REPORT:

+    GroupId = FindMulticastGroup (Private, IgmpMessagePtr->GroupAddress);

+

+    if (GroupId != 0) {

+      ClearGroupTimer (Private, GroupId - 1);

+    }

+

+    break;

+  }

+}

+

+/* EOF - pxe_bc_igmp.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_ip.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_ip.c
new file mode 100644
index 0000000..e0e12ec
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_ip.c
@@ -0,0 +1,861 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  pxe_bc_ip.c

+

+Abstract:

+

+--*/

+

+

+#include "Bc.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+BOOLEAN

+OnSameSubnet (

+  IN UINTN           IpLength,

+  IN EFI_IP_ADDRESS  *Ip1,

+  IN EFI_IP_ADDRESS  *Ip2,

+  IN EFI_IP_ADDRESS  *SubnetMask

+  )

+/*++

+

+  Routine Description:

+    Check if two IP addresses are on the same subnet.

+

+  Arguments:

+    IpLength   - Length of IP address in bytes.

+    Ip1        - IP address to check.

+    Ip2        - IP address to check.

+    SubnetMask - Subnet mask to check with.

+

+  Returns:

+    TRUE       - IP addresses are on the same subnet.

+    FALSE      - IP addresses are on different subnets.

+

+--*/

+{

+  if (IpLength == 0 || Ip1 == NULL || Ip2 == NULL || SubnetMask == NULL) {

+    return FALSE;

+  }

+

+  while (IpLength-- != 0) {

+    if ((Ip1->v6.Addr[IpLength] ^ Ip2->v6.Addr[IpLength]) & SubnetMask->v6.Addr[IpLength]) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+IpAddRouter (

+  IN PXE_BASECODE_DEVICE *Private,

+  IN EFI_IP_ADDRESS      *RouterIpPtr

+  )

+/*++

+

+  Routine Description:

+    Add router to router table.

+

+  Arguments:

+    Private     - Pointer PxeBc instance data.

+    RouterIpPtr - Pointer to router IP address.

+

+  Returns:

+    Nothing

+

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  UINTN                   Index;

+

+  if (Private == NULL || RouterIpPtr == NULL) {

+    return ;

+  }

+

+  PxeBcMode = Private->EfiBc.Mode;

+

+  //

+  // if we are filled up or this is not on the same subnet, forget it

+  //

+  if ((PxeBcMode->RouteTableEntries == PXE_ROUTER_TABLE_SIZE) ||

+    !OnSameSubnet(Private->IpLength, &PxeBcMode->StationIp, RouterIpPtr, &PxeBcMode->SubnetMask)) {

+    return ;

+  }

+  //

+  // make sure we don't already have it

+  //

+  for (Index = 0; Index < PxeBcMode->RouteTableEntries; ++Index) {

+    if (!CompareMem (

+          &PxeBcMode->RouteTable[Index].GwAddr,

+          RouterIpPtr,

+          Private->IpLength

+          )) {

+      return ;

+    }

+  }

+  //

+  // keep it

+  //

+  ZeroMem (

+    &PxeBcMode->RouteTable[PxeBcMode->RouteTableEntries],

+    sizeof (EFI_PXE_BASE_CODE_ROUTE_ENTRY)

+    );

+

+  CopyMem (

+    &PxeBcMode->RouteTable[PxeBcMode->RouteTableEntries++].GwAddr,

+    RouterIpPtr,

+    Private->IpLength

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// return router ip to use for DestIp (0 if none)

+//

+STATIC

+EFI_IP_ADDRESS *

+GetRouterIp (

+  PXE_BASECODE_DEVICE *Private,

+  EFI_IP_ADDRESS      *DestIpPtr

+  )

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  UINTN                   Index;

+

+  if (Private == NULL || DestIpPtr == NULL) {

+    return NULL;

+  }

+

+  PxeBcMode = Private->EfiBc.Mode;

+

+  for (Index = 0; Index < PxeBcMode->RouteTableEntries; ++Index) {

+    if (OnSameSubnet (

+          Private->IpLength,

+          &PxeBcMode->RouteTable[Index].IpAddr,

+          DestIpPtr,

+          &PxeBcMode->RouteTable[Index].SubnetMask

+          )) {

+      return &PxeBcMode->RouteTable[Index].GwAddr;

+    }

+  }

+

+  return NULL;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// routine to send ipv4 packet

+// ipv4 header of length HdrLth in TransmitBufferPtr

+// routine fills in ipv4hdr Ver_Hdl, TotalLength, and Checksum, moves in Data

+// and gets dest MAC address

+//

+#define IP_TX_BUFFER  ((IPV4_BUFFER *) Private->TransmitBufferPtr)

+#define IP_TX_HEADER  IP_TX_BUFFER->IpHeader

+

+EFI_STATUS

+Ipv4Xmt (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT32                      GatewayIp,

+  UINTN                       IpHeaderLength,

+  UINTN                       TotalHeaderLength,

+  VOID                        *Data,

+  UINTN                       DataLength,

+  EFI_PXE_BASE_CODE_FUNCTION  Function

+  )

+{

+  EFI_MAC_ADDRESS             DestMac;

+  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;

+  EFI_PXE_BASE_CODE_MODE      *PxeBcMode;

+  EFI_STATUS                  StatCode;

+  UINTN                       PacketLength;

+

+  Snp           = Private->SimpleNetwork;

+  PxeBcMode     = Private->EfiBc.Mode;

+  StatCode      = EFI_SUCCESS;

+  PacketLength  = TotalHeaderLength + DataLength;

+

+  //

+  // get dest MAC address

+  // multicast - convert to hw equiv

+  // unicast on same net, use arp

+  // on different net, arp for router

+  //

+  if (IP_TX_HEADER.DestAddr.L == BROADCAST_IPv4) {

+    CopyMem (&DestMac, &Snp->Mode->BroadcastAddress, sizeof (DestMac));

+  } else if (IS_MULTICAST (&IP_TX_HEADER.DestAddr)) {

+    StatCode = (*Snp->MCastIpToMac) (Snp, PxeBcMode->UsingIpv6, (EFI_IP_ADDRESS *) &IP_TX_HEADER.DestAddr, &DestMac);

+  } else {

+    UINT32  Ip;

+

+    if (OnSameSubnet (

+          Private->IpLength,

+          &PxeBcMode->StationIp,

+          (EFI_IP_ADDRESS *) &IP_TX_HEADER.DestAddr,

+          &PxeBcMode->SubnetMask

+          )) {

+      Ip = IP_TX_HEADER.DestAddr.L;

+    } else if (GatewayIp != 0) {

+      Ip = GatewayIp;

+    } else {

+      EFI_IP_ADDRESS  *TmpIp;

+

+      TmpIp = GetRouterIp (Private, (EFI_IP_ADDRESS *) &IP_TX_HEADER.DestAddr);

+

+      if (TmpIp == NULL) {

+        DEBUG (

+          (EFI_D_WARN,

+          "\nIpv4Xmit()  Exit #1  %xh (%r)",

+          EFI_NO_RESPONSE,

+          EFI_NO_RESPONSE)

+          );

+

+        return EFI_NO_RESPONSE;

+        //

+        // no router

+        //

+      }

+

+      Ip = TmpIp->Addr[0];

+    }

+

+    if (!GetHwAddr (

+          Private,

+          (EFI_IP_ADDRESS *) &Ip,

+          (EFI_MAC_ADDRESS *) &DestMac

+          )) {

+      if (!PxeBcMode->AutoArp) {

+        DEBUG (

+          (EFI_D_WARN,

+          "\nIpv4Xmit()  Exit #2  %xh (%r)",

+          EFI_DEVICE_ERROR,

+          EFI_DEVICE_ERROR)

+          );

+

+        return EFI_DEVICE_ERROR;

+      } else {

+        StatCode = DoArp (

+                    Private,

+                    (EFI_IP_ADDRESS *) &Ip,

+                    (EFI_MAC_ADDRESS *) &DestMac

+                    );

+      }

+    }

+  }

+

+  if (EFI_ERROR (StatCode)) {

+    DEBUG ((EFI_D_WARN, "\nIpv4Xmit()  Exit #3  %xh (%r)", StatCode, StatCode));

+    return StatCode;

+  }

+  //

+  // fill in packet info

+  //

+  SET_IPV4_VER_HDL (&IP_TX_HEADER, IpHeaderLength);

+  IP_TX_HEADER.TotalLength    = HTONS (PacketLength);

+  IP_TX_HEADER.HeaderChecksum = IpChecksum ((UINT16 *) &IP_TX_HEADER, IpHeaderLength);

+  CopyMem (((UINT8 *) &IP_TX_HEADER) + TotalHeaderLength, Data, DataLength);

+

+  //

+  // send it

+  //

+  return SendPacket (

+          Private,

+          (UINT8 *) &IP_TX_HEADER - Snp->Mode->MediaHeaderSize,

+          &IP_TX_HEADER,

+          PacketLength,

+          &DestMac,

+          PXE_PROTOCOL_ETHERNET_IP,

+          Function

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// send ipv4 packet with option

+//

+EFI_STATUS

+Ipv4SendWOp (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT32                      GatewayIp,

+  UINT8                       *Msg,

+  UINTN                       MessageLength,

+  UINT8                       Prot,

+  UINT8                       *Option,

+  UINTN                       OptionLength,

+  UINT32                      DestIp,

+  EFI_PXE_BASE_CODE_FUNCTION  Function

+  )

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  UINTN                   HdrLth;

+

+  PxeBcMode = Private->EfiBc.Mode;

+  HdrLth    = sizeof (IPV4_HEADER) + OptionLength;

+

+  ZeroMem ((VOID *) &IP_TX_HEADER, sizeof (IPV4_HEADER));

+  IP_TX_HEADER.TimeToLive     = PxeBcMode->TTL;

+  IP_TX_HEADER.TypeOfService  = PxeBcMode->ToS;

+  IP_TX_HEADER.Protocol       = Prot;

+  IP_TX_HEADER.SrcAddr.L      = *(UINT32 *) &PxeBcMode->StationIp;

+  IP_TX_HEADER.DestAddr.L     = DestIp;

+  IP_TX_HEADER.Id             = Random (Private);

+  CopyMem (IP_TX_BUFFER->u.Data, Option, OptionLength);

+  return Ipv4Xmt (

+          Private,

+          GatewayIp,

+          HdrLth,

+          HdrLth,

+          Msg,

+          MessageLength,

+          Function

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// send MessageLength message at MessagePtr - higher level protocol header already in TransmitBufferPtr, length HdrSize

+//

+EFI_STATUS

+Ip4Send (

+  PXE_BASECODE_DEVICE                          *Private,  // pointer to instance data

+  UINTN               MayFrag,                            //

+  UINT8                                    Prot,          // protocol

+  UINT32                          SrcIp,                  // Source IP address

+  UINT32                 DestIp,                          // Destination IP address

+  UINT32              GatewayIp,                          // used if not NULL and needed

+  UINTN               HdrSize,                            // protocol header byte length

+  UINT8               *MessagePtr,                        // pointer to data

+  UINTN               MessageLength                       // data byte length

+  )

+{

+  EFI_STATUS  StatCode;

+  UINTN       TotDataLength;

+

+  TotDataLength = HdrSize + MessageLength;

+

+  if (TotDataLength > MAX_IPV4_DATA_SIZE) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nIp4Send()  Exit #1  %xh (%r)",

+      EFI_BAD_BUFFER_SIZE,

+      EFI_BAD_BUFFER_SIZE)

+      );

+

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  ZeroMem ((VOID *) &IP_TX_HEADER, sizeof (IPV4_HEADER));

+  IP_TX_HEADER.TimeToLive = DEFAULT_TTL;

+  IP_TX_HEADER.Protocol   = Prot;

+  IP_TX_HEADER.SrcAddr.L  = SrcIp;

+  IP_TX_HEADER.DestAddr.L = DestIp;

+  IP_TX_HEADER.Id         = Random (Private);

+

+  if (!MayFrag) {

+    *(UINT8 *) (&IP_TX_HEADER.FragmentFields) = IP_NO_FRAG >> 8;

+  }

+  //

+  // check for need to fragment

+  //

+  if (TotDataLength > MAX_IPV4_FRAME_DATA_SIZE) {

+    UINTN   DataLengthSent;

+    UINT16  FragmentOffset;

+

+    FragmentOffset = IP_MORE_FRAG;

+    //

+    // frag offset field

+    //

+    if (!MayFrag) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nIp4Send()  Exit #2  %xh (%r)",

+        EFI_BAD_BUFFER_SIZE,

+        EFI_BAD_BUFFER_SIZE)

+        );

+

+      return EFI_BAD_BUFFER_SIZE;

+    }

+    //

+    // send out in fragments - first includes upper level header

+    // all are max and include more frag bit except last

+    //

+    * (UINT8 *) (&IP_TX_HEADER.FragmentFields) = IP_MORE_FRAG >> 8;

+

+#define IPV4_FRAG_SIZE    (MAX_IPV4_FRAME_DATA_SIZE & 0xfff8)

+#define IPV4_FRAG_OFF_INC (IPV4_FRAG_SIZE >> 3)

+

+    DataLengthSent = IPV4_FRAG_SIZE - HdrSize;

+

+    StatCode = Ipv4Xmt (

+                Private,

+                GatewayIp,

+                sizeof (IPV4_HEADER),

+                sizeof (IPV4_HEADER) + HdrSize,

+                MessagePtr,

+                DataLengthSent,

+                Private->Function

+                );

+

+    if (EFI_ERROR (StatCode)) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nIp4Send()  Exit #3  %xh (%r)",

+        StatCode,

+        StatCode)

+        );

+

+      return StatCode;

+    }

+

+    MessagePtr += DataLengthSent;

+    MessageLength -= DataLengthSent;

+    FragmentOffset += IPV4_FRAG_OFF_INC;

+    IP_TX_HEADER.FragmentFields = HTONS (FragmentOffset);

+

+    while (MessageLength > IPV4_FRAG_SIZE) {

+      StatCode = Ipv4Xmt (

+                  Private,

+                  GatewayIp,

+                  sizeof (IPV4_HEADER),

+                  sizeof (IPV4_HEADER),

+                  MessagePtr,

+                  IPV4_FRAG_SIZE,

+                  Private->Function

+                  );

+

+      if (EFI_ERROR (StatCode)) {

+        DEBUG (

+          (EFI_D_WARN,

+          "\nIp4Send()  Exit #3  %xh (%r)",

+          StatCode,

+          StatCode)

+          );

+

+        return StatCode;

+      }

+

+      MessagePtr += IPV4_FRAG_SIZE;

+      MessageLength -= IPV4_FRAG_SIZE;

+      FragmentOffset += IPV4_FRAG_OFF_INC;

+      IP_TX_HEADER.FragmentFields = HTONS (FragmentOffset);

+    }

+

+    * (UINT8 *) (&IP_TX_HEADER.FragmentFields) &= ~(IP_MORE_FRAG >> 8);

+    HdrSize = 0;

+  }

+  //

+  // transmit

+  //

+  return Ipv4Xmt (

+          Private,

+          GatewayIp,

+          sizeof (IPV4_HEADER),

+          sizeof (IPV4_HEADER) + HdrSize,

+          MessagePtr,

+          MessageLength,

+          Private->Function

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// return true if dst IP in receive header matched with what's enabled

+//

+STATIC

+BOOLEAN

+IPgood (

+  PXE_BASECODE_DEVICE *Private,

+  IPV4_HEADER         *IpHeader

+  )

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  UINTN                   Index;

+

+  PxeBcMode = Private->EfiBc.Mode;

+

+  if (PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) {

+    return TRUE;

+  }

+

+  if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) &&

+      IS_MULTICAST (&IpHeader->DestAddr)

+        ) {

+    return TRUE;

+  }

+

+  if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) &&

+      PxeBcMode->StationIp.Addr[0] == IpHeader->DestAddr.L

+      ) {

+    return TRUE;

+  }

+

+  if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) && IpHeader->DestAddr.L == BROADCAST_IPv4) {

+    return TRUE;

+  }

+

+  for (Index = 0; Index < PxeBcMode->IpFilter.IpCnt; ++Index) {

+    if (IpHeader->DestAddr.L == PxeBcMode->IpFilter.IpList[Index].Addr[0]) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// receive up to MessageLength message into MessagePtr for protocol Prot

+// return message length, src/dest ips if select any, and pointer to protocol

+// header routine will filter based on source and/or dest ip if OpFlags set.

+//

+EFI_STATUS

+IpReceive (

+  PXE_BASECODE_DEVICE *Private,

+  PXE_OPFLAGS         OpFlags,

+  EFI_IP_ADDRESS      *SrcIpPtr,

+  EFI_IP_ADDRESS      *DestIpPtr,

+  UINT8               Prot,

+  VOID                *HeaderPtr,

+  UINTN               HdrSize,

+  UINT8               *MessagePtr,

+  UINTN               *MessageLengthPtr,

+  EFI_EVENT           TimeoutEvent

+  )

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  EFI_STATUS              StatCode;

+  UINTN                   ByteCount;

+  UINTN                   FragmentCount;

+  UINTN                   ExpectedPacketLength;

+  UINTN                   Id;

+  BOOLEAN                 GotFirstFragment;

+  BOOLEAN                 GotLastFragment;

+

+  DEBUG (

+    (EFI_D_NET,

+    "\nIpReceive()  Hdr=%Xh  HdrSz=%d  Data=%Xh  DataSz=%d",

+    HeaderPtr,

+    HdrSize,

+    MessagePtr,

+    *MessageLengthPtr)

+    );

+

+  PxeBcMode                     = Private->EfiBc.Mode;

+  PxeBcMode->IcmpErrorReceived  = FALSE;

+

+  ExpectedPacketLength          = 0;

+  GotFirstFragment              = FALSE;

+  GotLastFragment               = FALSE;

+  FragmentCount                 = 0;

+  ByteCount                     = 0;

+  Id = 0;

+

+  for (;;) {

+    IPV4_HEADER IpHdr;

+    UINTN       FFlds;

+    UINTN       TotalLength;

+    UINTN       FragmentOffset;

+    UINTN       HeaderSize;

+    UINTN       BufferSize;

+    UINTN       IpHeaderLength;

+    UINTN       DataLength;

+    UINT16      Protocol;

+    UINT8       *NextHdrPtr;

+    UINT8       *PacketPtr;

+

+    StatCode = WaitForReceive (

+                Private,

+                Private->Function,

+                TimeoutEvent,

+                &HeaderSize,

+                &BufferSize,

+                &Protocol

+                );

+

+    if (EFI_ERROR (StatCode)) {

+      return StatCode;

+    }

+

+    PacketPtr = Private->ReceiveBufferPtr + HeaderSize;

+

+    if (Protocol == PXE_PROTOCOL_ETHERNET_ARP) {

+      HandleArpReceive (

+        Private,

+        (ARP_PACKET *) PacketPtr,

+        Private->ReceiveBufferPtr

+        );

+

+      continue;

+    }

+

+    if (Protocol != PXE_PROTOCOL_ETHERNET_IP) {

+      continue;

+    }

+

+#if SUPPORT_IPV6

+    if (PxeBcMode->UsingIpv6) {

+      //

+      // TBD

+      //

+    }

+#endif

+

+#define IpRxHeader  ((IPV4_HEADER *) PacketPtr)

+

+    //

+    // filter for version & check sum

+    //

+    IpHeaderLength = IPV4_HEADER_LENGTH (IpRxHeader);

+

+    if ((IpRxHeader->VersionIhl >> 4) != IPVER4) {

+      continue;

+    }

+

+    if (IpChecksum ((UINT16 *) IpRxHeader, IpHeaderLength)) {

+      continue;

+    }

+

+    CopyMem (&IpHdr, IpRxHeader, sizeof (IpHdr));

+    //IpHdr       = *IpRxHeader;

+    TotalLength = NTOHS (IpHdr.TotalLength);

+

+    if (IpHdr.Protocol == PROT_TCP) {

+      //

+      // The NextHdrPtr is used to seed the header buffer we are passing back.

+      // That being the case, we want to see everything in pPkt which contains

+      // everything but the ethernet (or whatever) frame.  IP + TCP in this case.

+      //

+      DataLength  = TotalLength;

+      NextHdrPtr  = PacketPtr;

+    } else {

+      DataLength  = TotalLength - IpHeaderLength;

+      NextHdrPtr  = PacketPtr + IpHeaderLength;

+    }

+    //

+    // If this is an ICMP, it might not be for us.

+    // Double check the state of the IP stack and the

+    // packet fields before assuming it is an ICMP

+    // error.  ICMP requests are not supported by the

+    // PxeBc IP stack and should be ignored.

+    //

+    if (IpHdr.Protocol == PROT_ICMP) {

+      ICMPV4_HEADER *Icmpv4;

+

+      Icmpv4 = (ICMPV4_HEADER *) NextHdrPtr;

+

+      //

+      // For now only obvious ICMP error replies will be accepted by

+      // this stack.  This still makes us vulnerable to DoS attacks.

+      // But at least we will not be killed by DHCP daemons.

+      //

+      switch (Icmpv4->Type) {

+      case ICMP_REDIRECT:

+      case ICMP_ECHO:

+      case ICMP_ROUTER_ADV:

+      case ICMP_ROUTER_SOLICIT:

+      case ICMP_TIMESTAMP:

+      case ICMP_TIMESTAMP_REPLY:

+      case ICMP_INFO_REQ:

+      case ICMP_INFO_REQ_REPLY:

+      case ICMP_SUBNET_MASK_REQ:

+      case ICMP_SUBNET_MASK_REPLY:

+      default:

+        continue;

+

+      //

+      // %%TBD - This should be implemented.

+      //

+      case ICMP_ECHO_REPLY:

+        continue;

+

+      case ICMP_DEST_UNREACHABLE:

+      case ICMP_TIME_EXCEEDED:

+      case ICMP_PARAMETER_PROBLEM:

+      case ICMP_SOURCE_QUENCH:

+        PxeBcMode->IcmpErrorReceived = TRUE;

+

+        CopyMem (

+          &PxeBcMode->IcmpError,

+          NextHdrPtr,

+          sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)

+          );

+

+        DEBUG (

+          (EFI_D_NET,

+          "\nIpReceive()  Exit #1  %Xh (%r)",

+          EFI_ICMP_ERROR,

+          EFI_ICMP_ERROR)

+          );

+      }

+

+      return EFI_ICMP_ERROR;

+    }

+

+    if (IpHdr.Protocol == PROT_IGMP) {

+      HandleIgmp (Private, (IGMPV2_MESSAGE *) NextHdrPtr, DataLength);

+

+      DEBUG ((EFI_D_NET, "\n  IGMP"));

+      continue;

+    }

+    //

+    // check for protocol

+    //

+    if (IpHdr.Protocol != Prot) {

+      continue;

+    }

+    //

+    // do filtering

+    //

+    if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr && SrcIpPtr->Addr[0] != IpHdr.SrcAddr.L) {

+      DEBUG ((EFI_D_NET, "\n  Not expected source IP address."));

+      continue;

+    }

+

+    if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) {

+      if (!IPgood (Private, &IpHdr)) {

+        continue;

+      }

+    } else if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP)) {

+      if (DestIpPtr == NULL) {

+        if (PxeBcMode->StationIp.Addr[0] != IpHdr.DestAddr.L) {

+          continue;

+        }

+      } else if (DestIpPtr->Addr[0] != IpHdr.DestAddr.L) {

+        continue;

+      }

+    }

+    //

+    // get some data we need

+    //

+    FFlds           = NTOHS (IpHdr.FragmentFields);

+    FragmentOffset  = ((FFlds & IP_FRAG_OFF_MSK) << 3);

+

+    /* Keep count of fragments that belong to this session.

+     * If we get packets with a different IP ID number,

+     * ignore them.  Ignored packets should be handled

+     * by the upper level protocol.

+     */

+    if (FragmentCount == 0) {

+      Id = IpHdr.Id;

+

+      if (DestIpPtr != NULL) {

+        DestIpPtr->Addr[0] = IpHdr.DestAddr.L;

+      }

+

+      if (SrcIpPtr != NULL) {

+        SrcIpPtr->Addr[0] = IpHdr.SrcAddr.L;

+      }

+    } else {

+      if (IpHdr.Id != Id) {

+        continue;

+      }

+    }

+

+    ++FragmentCount;

+

+    /* Fragment management.

+     */

+    if (FragmentOffset == 0) {

+      /* This is the first fragment (may also be the

+       * only fragment).

+       */

+      GotFirstFragment = TRUE;

+

+      /* If there is a separate protocol header buffer,

+       * copy the header, adjust the data pointer and

+       * the data length.

+       */

+      if (HdrSize != 0) {

+        CopyMem (HeaderPtr, NextHdrPtr, HdrSize);

+

+        NextHdrPtr += HdrSize;

+        DataLength -= HdrSize;

+      }

+    } else {

+      /* If there is a separate protocol header buffer,

+       * adjust the fragment offset.

+       */

+      FragmentOffset -= HdrSize;

+    }

+

+    /* See if this is the last fragment.

+     */

+    if (!(FFlds & IP_MORE_FRAG)) {

+      //

+      // This is the last fragment (may also be the only fragment).

+      //

+      GotLastFragment = TRUE;

+

+      /* Compute the expected length of the assembled

+       * packet.  This will be used to decide if we

+       * have gotten all of the fragments.

+       */

+      ExpectedPacketLength = FragmentOffset + DataLength;

+    }

+

+    DEBUG (

+      (EFI_D_NET,

+      "\n  ID = %Xh  Off = %d  Len = %d",

+      Id,

+      FragmentOffset,

+      DataLength)

+      );

+

+    /* Check for receive buffer overflow.

+     */

+    if (FragmentOffset + DataLength > *MessageLengthPtr) {

+      /* There is not enough space in the receive

+       * buffer for the fragment.

+       */

+      DEBUG (

+        (EFI_D_NET,

+        "\nIpReceive()  Exit #3  %Xh (%r)",

+        EFI_BUFFER_TOO_SMALL,

+        EFI_BUFFER_TOO_SMALL)

+        );

+

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    /* Copy data into receive buffer.

+     */

+    if (DataLength != 0) {

+      DEBUG ((EFI_D_NET, "  To = %Xh", MessagePtr + FragmentOffset));

+

+      CopyMem (MessagePtr + FragmentOffset, NextHdrPtr, DataLength);

+      ByteCount += DataLength;

+    }

+

+    /* If we have seen the first and last fragments and

+     * the receive byte count is at least as large as the

+     * expected byte count, return SUCCESS.

+     *

+     * We could be tricked by receiving a fragment twice

+     * but the upper level protocol should figure this

+     * out.

+     */

+    if (GotFirstFragment && GotLastFragment && ByteCount >= ExpectedPacketLength) {

+      *MessageLengthPtr = ExpectedPacketLength;

+      return EFI_SUCCESS;

+    }

+  }

+}

+

+/* eof - pxe_bc_ip.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_mtftp.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_mtftp.c
new file mode 100644
index 0000000..e6e91c3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_mtftp.c
@@ -0,0 +1,2391 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    pxe_bc_mtftp.c

+

+Abstract:

+  TFTP and MTFTP (multicast TFTP) implementation.

+

+Revision History

+

+--*/

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// The following #define is used to create a version that does not wait to

+// open after a listen.  This is just for a special regression test of MTFTP

+// server to make sure multiple opens are handled correctly.  Normally this

+// next line should be a comment.

+// #define SpecialNowaitVersion    // comment out for normal operation

+//

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+

+#include "Bc.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+UINT64

+Swap64 (

+  UINT64 n

+  )

+{

+  union {

+    UINT64  n;

+    UINT8   b[8];

+  } u;

+

+  UINT8 t;

+

+  u.n     = n;

+

+  t       = u.b[0];

+  u.b[0]  = u.b[7];

+  u.b[7]  = t;

+

+  t       = u.b[1];

+  u.b[1]  = u.b[6];

+  u.b[6]  = t;

+

+  t       = u.b[2];

+  u.b[2]  = u.b[5];

+  u.b[5]  = t;

+

+  t       = u.b[3];

+  u.b[3]  = u.b[4];

+  u.b[4]  = t;

+

+  return u.n;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+TftpUdpRead (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT16                      Operation,

+  VOID                        *HeaderPtr,

+  UINTN                       *BufferSizePtr,

+  VOID                        *BufferPtr,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_IP_ADDRESS              *OurIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *OurPortPtr,

+  UINT16                      Timeout

+  )

+/*++

+Routine description:

+  Read TFTP packet.  If TFTP ERROR packet is read, fill in TFTP error

+  information in Mode structure and return TFTP_ERROR status.

+

+Parameters:

+  Private := 

+  Operation := 

+  HeaderPtr := 

+  BufferSizePtr := 

+  BufferPtr := 

+  ServerIpPtr := 

+  ServerPortPtr := 

+  OurIpPtr := 

+  OurPortPtr := 

+  Timeout := 

+

+Returns:

+  EFI_SUCCESS := 

+  EFI_TFTP_ERROR := 

+  other := 

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  EFI_STATUS              Status;

+  EFI_EVENT               TimeoutEvent;

+  UINTN                   HeaderSize;

+

+  //

+  //

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER,

+                  EFI_TPL_CALLBACK,

+                  NULL,

+                  NULL,

+                  &TimeoutEvent

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->SetTimer (

+                  TimeoutEvent,

+                  TimerRelative,

+                  Timeout * 10000000 + 1000000

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return Status;

+  }

+  //

+  //

+  //

+  HeaderSize = Private->BigBlkNumFlag ? sizeof (struct Tftpv4Ack8) : sizeof (struct Tftpv4Ack);

+

+#define ERROR_MESSAGE_PTR ((struct Tftpv4Error *) HeaderPtr)

+

+  Status = UdpRead (

+            Private,

+            Operation,

+            OurIpPtr,

+            OurPortPtr,

+            ServerIpPtr,

+            ServerPortPtr,

+            &HeaderSize,

+            HeaderPtr,

+            BufferSizePtr,

+            BufferPtr,

+            TimeoutEvent

+            );

+

+  if (Status != EFI_SUCCESS || ERROR_MESSAGE_PTR->OpCode != HTONS (TFTP_ERROR)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return Status;

+  }

+  //

+  // got an error packet

+  // write one byte error code followed by error message

+  //

+  PxeBcMode                       = Private->EfiBc.Mode;

+  PxeBcMode->TftpErrorReceived    = TRUE;

+  PxeBcMode->TftpError.ErrorCode  = (UINT8) NTOHS (ERROR_MESSAGE_PTR->ErrCode);

+  HeaderSize                      = EFI_MIN (*BufferSizePtr, sizeof PxeBcMode->TftpError.ErrorString);

+  CopyMem (PxeBcMode->TftpError.ErrorString, BufferPtr, HeaderSize);

+

+  gBS->CloseEvent (TimeoutEvent);

+  return EFI_TFTP_ERROR;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+VOID

+SendError (

+  PXE_BASECODE_DEVICE         *Private,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *OurPortPtr

+  )

+/*++

+Routine description:

+  Send TFTP ERROR message to TFTP server

+

+Parameters:

+  Private := 

+  ServerIpPtr := 

+  ServerPortPtr := 

+  OurPortPtr := 

+

+Returns:

+--*/

+{

+  struct Tftpv4Error  *ErrStr;

+  UINTN               Len;

+

+  ErrStr            = (VOID *) Private->TftpErrorBuffer;

+  Len               = sizeof *ErrStr;

+

+  ErrStr->OpCode    = HTONS (TFTP_ERROR);

+  ErrStr->ErrCode   = HTONS (TFTP_ERR_OPTION);

+  ErrStr->ErrMsg[0] = 0;

+

+  UdpWrite (

+    Private,

+    EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,

+    ServerIpPtr,

+    ServerPortPtr,

+    0,

+    0,

+    OurPortPtr,

+    0,

+    0,

+    &Len,

+    ErrStr

+    );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+SendAckAndGetData (

+  PXE_BASECODE_DEVICE         *Private,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_IP_ADDRESS              *ReplyIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *OurPortPtr,

+  UINT16                      Timeout,

+  UINTN                       *ReplyLenPtr,

+  UINT8                       *PxeBcMode,

+  UINT64                      *BlockNumPtr,

+  BOOLEAN                     AckOnly

+  )

+/*++

+Routine description:

+  Send TFTP ACK packet to server and read next DATA packet.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  ServerIpPtr := Pointer to TFTP server IP address

+  ServerPortPtr := Pointer to TFTP server UDP port

+  ReplyIpPtr := Pointer to TFTP DATA packet destination IP address

+  OurPortPtr := Pointer to TFTP client UDP port

+  Timeout := 

+  ReplyLenPtr := Pointer to packet length

+  PxeBcMode := Pointer to packet buffer

+  BlockNumPtr := Pointer to block number

+  AckOnly := TRUE == Send last ack - do not wait for reply

+

+Returns:

+--*/

+{

+  struct Tftpv4Data DataBuffer;

+  struct Tftpv4Ack  *Ack2Ptr;

+  struct Tftpv4Ack8 *Ack8Ptr;

+  EFI_STATUS        Status;

+  UINTN             Len;

+

+  Ack2Ptr = (VOID *) Private->TftpAckBuffer;

+  Ack8Ptr = (VOID *) Private->TftpAckBuffer;

+

+  if (Private->BigBlkNumFlag) {

+    Len               = sizeof (struct Tftpv4Ack8);

+

+    Ack8Ptr->OpCode   = HTONS (TFTP_ACK8);

+    Ack8Ptr->BlockNum = Swap64 (*BlockNumPtr);

+

+    Status = UdpWrite (

+              Private,

+              EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,

+              ServerIpPtr,

+              ServerPortPtr,

+              0,

+              0,

+              OurPortPtr,

+              0,

+              0,

+              &Len,

+              Ack8Ptr

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  } else {

+    Len               = sizeof (struct Tftpv4Ack);

+

+    Ack2Ptr->OpCode   = HTONS (TFTP_ACK);

+    Ack2Ptr->BlockNum = HTONS ((UINT16) *BlockNumPtr);

+

+    Status = UdpWrite (

+              Private,

+              EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,

+              ServerIpPtr,

+              ServerPortPtr,

+              0,

+              0,

+              OurPortPtr,

+              0,

+              0,

+              &Len,

+              Ack2Ptr

+              );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  if (AckOnly) {

+    //

+    // ACK of last packet.  This is just a courtesy.

+    // Do not wait for response.

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // read reply

+  //

+  Status = TftpUdpRead (

+            Private,

+            0,

+            &DataBuffer,

+            ReplyLenPtr,

+            PxeBcMode,

+            ServerIpPtr,

+            ServerPortPtr,

+            ReplyIpPtr,

+            OurPortPtr,

+            Timeout

+            );

+

+  if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {

+    return Status;

+  }

+  //

+  // got a good reply (so far)

+  // check for next data packet

+  //

+  if (!Private->BigBlkNumFlag && DataBuffer.Header.OpCode == HTONS (TFTP_DATA)) {

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      SendError (Private, ServerIpPtr, ServerPortPtr, OurPortPtr);

+    }

+

+    *BlockNumPtr = NTOHS (DataBuffer.Header.BlockNum);

+    return Status;

+  }

+

+  if (Private->BigBlkNumFlag && DataBuffer.Header.OpCode == HTONS (TFTP_DATA8)) {

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      SendError (Private, ServerIpPtr, ServerPortPtr, OurPortPtr);

+    }

+

+    *BlockNumPtr = Swap64 (*(UINT64 *) &DataBuffer.Header.BlockNum);

+    return Status;

+  }

+

+  return EFI_PROTOCOL_ERROR;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+LockStepReceive (

+  PXE_BASECODE_DEVICE         *Private,

+  UINTN                       PacketSize,

+  UINT64                      *BufferSizePtr,

+  UINT64                      Offset,

+  UINT8                       *BufferPtr,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_IP_ADDRESS              *ReplyIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *OurPortPtr,

+  UINT64                      LastBlock,

+  UINT16                      Timeout,

+  IN BOOLEAN                  DontUseBuffer

+  )

+/*++

+Routine description:

+  Read rest of file after successfull M/TFTP request.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  PacketSize := Pointer to packet size

+  BufferSizePtr := Pointer to buffer (file) size

+  Offset := Offset into buffer of next packet

+  BufferPtr := Pointer to receive buffer

+  ServerIpPtr := Pointer to TFTP server IP address

+  ServerPortPtr := Pointer to TFTP server UDP port

+  ReplyIpPtr := Pointer to TFTP DATA packet destination IP address

+  OurPortPtr := Pointer to TFTP client UDP port

+  LastBlock := Last block number received

+  Timeout := 

+  DontUseBuffer := TRUE == throw away data, just count # of bytes

+

+Returns:

+--*/

+{

+  EFI_STATUS  Status;

+  UINT64      BlockNum;

+  UINT64      BufferSize;

+  UINTN       Retries;

+  UINTN       SaveLen;

+  UINTN       ReplyLen;

+

+  ReplyLen  = PacketSize;

+  BlockNum  = LastBlock;

+

+  DEBUG ((EFI_D_INFO, "\nLockStepReceive()  PacketSize = %d", PacketSize));

+

+  if (DontUseBuffer) {

+    BufferSize = PacketSize;

+  } else {

+    BufferSize = *BufferSizePtr - Offset;

+    BufferPtr += Offset;

+  }

+

+  while (ReplyLen >= 512 && ReplyLen == PacketSize) {

+    if (BufferSize < PacketSize) {

+      ReplyLen = (UINTN) ((BufferSize > 0) ? BufferSize : 0);

+    }

+

+    SaveLen = ReplyLen;

+

+    //

+    // write an ack packet and get data - retry up to NUM_ACK_RETRIES on timeout

+    //

+    Retries = NUM_ACK_RETRIES;

+

+    do {

+      ReplyLen = SaveLen;

+

+      Status = SendAckAndGetData (

+                Private,

+                ServerIpPtr,

+                ServerPortPtr,

+                ReplyIpPtr,

+                OurPortPtr,

+                Timeout,

+                (UINTN *) &ReplyLen,

+                BufferPtr,

+                &BlockNum,

+                FALSE

+                );

+

+      if (!EFI_ERROR (Status) || Status == EFI_BUFFER_TOO_SMALL) {

+        if (BlockNum == LastBlock) {

+          DEBUG ((EFI_D_NET, "\nresend"));

+          //

+          // a resend - continue

+          //

+          Status = EFI_TIMEOUT;

+        } else if (Private->BigBlkNumFlag) {

+          if (BlockNum != ++LastBlock) {

+            DEBUG ((EFI_D_NET, "\nLockStepReceive()  Exit #1a"));

+            //

+            // not correct blocknum - error

+            //

+            return EFI_PROTOCOL_ERROR;

+          }

+        } else {

+          LastBlock = (LastBlock + 1) & 0xFFFF;

+          if (BlockNum != LastBlock) {

+            DEBUG ((EFI_D_NET, "\nLockStepReceive()  Exit #1b"));

+            return EFI_PROTOCOL_ERROR;

+            //

+            // not correct blocknum - error

+            //

+          }

+        }

+      }

+    } while (Status == EFI_TIMEOUT && --Retries);

+

+    if (EFI_ERROR (Status)) {

+      if (Status != EFI_BUFFER_TOO_SMALL) {

+        SendError (Private, ServerIpPtr, ServerPortPtr, OurPortPtr);

+      }

+

+      return Status;

+    }

+

+    if (DontUseBuffer) {

+      BufferSize += ReplyLen;

+    } else {

+      BufferPtr += ReplyLen;

+      BufferSize -= ReplyLen;

+    }

+  }

+  //

+  // while (ReplyLen == PacketSize);

+  //

+  if (DontUseBuffer) {

+    if (BufferSizePtr != NULL) {

+      *BufferSizePtr = (BufferSize - PacketSize);

+    }

+  } else {

+    *BufferSizePtr -= BufferSize;

+  }

+

+  /* Send ACK of last packet. */

+  ReplyLen = 0;

+

+  SendAckAndGetData (

+    Private,

+    ServerIpPtr,

+    ServerPortPtr,

+    ReplyIpPtr,

+    OurPortPtr,

+    Timeout,

+    (UINTN *) &ReplyLen,

+    BufferPtr,

+    &BlockNum,

+    TRUE

+    );

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// some literals

+//

+STATIC UINT8                      Mode[]          = MODE_BINARY;

+STATIC UINT8                      BlockSizeOp[]   = OP_BLKSIZE;

+STATIC UINT8                      TsizeOp[]       = OP_TFRSIZE;

+STATIC UINT8                      OverwriteOp[]   = OP_OVERWRITE;

+STATIC UINT8                      BigBlkNumOp[]   = OP_BIGBLKNUM;

+STATIC EFI_PXE_BASE_CODE_UDP_PORT TftpRequestPort = TFTP_OPEN_PORT;

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+UINT8 *

+FindOption (

+  UINT8 *OptionPtr,

+  INTN  OpLen,

+  UINT8 *OackPtr,

+  INTN  OackSize

+  )

+/*++

+Routine description:

+  Check TFTP OACK packet for option.

+

+Parameters:

+  OptionPtr := Pointer to option string to find

+  OpLen := Length of option string

+  OackPtr := Pointer to OACK data

+  OackSize := Length of OACK data

+

+Returns:

+  Pointer to value field if option found or NULL if not found.

+--*/

+{

+  if ((OackSize -= OpLen) <= 0) {

+    return NULL;

+  }

+

+  do {

+    if (!CompareMem (OackPtr, OptionPtr, OpLen)) {

+      return OackPtr + OpLen;

+    }

+

+    ++OackPtr;

+  } while (--OackSize);

+

+  return NULL;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+#define BKSZOP      1 // block size

+#define TSIZEOP     2 // transfer size

+#define OVERWRITEOP 4 // overwrite

+#define BIGBLKNUMOP 8 // big block numbers

+STATIC

+EFI_STATUS

+TftpRwReq (

+  UINT16                      Req,

+  UINT16                      Options,

+  PXE_BASECODE_DEVICE         *Private,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *OurPortPtr,

+  UINT8                       *FilenamePtr,

+  UINTN                       *PacketSizePtr,

+  VOID                        *Buffer

+  )

+/*++

+Routine description:

+  Send TFTP RRQ/WRQ packet.

+

+Parameters:

+  Req := Type of request to send

+  Options := One or more of the #define values above

+  Private := Pointer to PxeBc interface

+  ServerIpPtr := Pointer to TFTP server IP address

+  ServerPortPtr := Pointer to TFTP server UDP port

+  OurPortPtr := Pointer to TFTP client UDP port

+  FilenamePtr := Pointer to TFTP file or directory name

+  PacketSizePtr := Pointer to block size

+  Buffer := 

+

+Returns:

+--*/

+{

+  union {

+    UINT8             Data[514];

+    struct Tftpv4Req  ReqStr;

+  } *u;

+

+  UINT16  OpFlags;

+  INTN    Len;

+  INTN    TotalLen;

+  UINT8   *Ptr;

+

+  if (*OurPortPtr == 0) {

+    OpFlags = EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT;

+  } else {

+    OpFlags = EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT;

+  }

+  //

+  // build the basic request - opcode, filename, mode

+  //

+  u                 = Buffer;

+  u->ReqStr.OpCode  = HTONS (Req);

+  TotalLen = sizeof (Mode) + sizeof (u->ReqStr.OpCode) + (Len = 1 + AsciiStrLen ((CHAR8 *)FilenamePtr));

+

+  CopyMem (u->ReqStr.FileName, FilenamePtr, Len);

+  Ptr = (UINT8 *) (u->ReqStr.FileName + Len);

+

+  CopyMem (Ptr, Mode, sizeof (Mode));

+  Ptr += sizeof (Mode);

+

+  if (Options & BKSZOP) {

+    CopyMem (Ptr, BlockSizeOp, sizeof (BlockSizeOp));

+    UtoA10 (*PacketSizePtr, Ptr + sizeof (BlockSizeOp));

+

+    TotalLen += (Len = 1 + AsciiStrLen ((CHAR8 *)Ptr + sizeof (BlockSizeOp)) + sizeof (BlockSizeOp));

+

+    Ptr += Len;

+  }

+

+  if (Options & TSIZEOP) {

+    CopyMem (Ptr, TsizeOp, sizeof (TsizeOp));

+    CopyMem (Ptr + sizeof (TsizeOp), "0", 2);

+    TotalLen += sizeof (TsizeOp) + 2;

+    Ptr += sizeof (TsizeOp) + 2;

+  }

+

+  if (Options & OVERWRITEOP) {

+    CopyMem (Ptr, OverwriteOp, sizeof (OverwriteOp));

+    CopyMem (Ptr + sizeof (OverwriteOp), "1", 2);

+    TotalLen += sizeof (OverwriteOp) + 2;

+    Ptr += sizeof (OverwriteOp) + 2;

+  }

+

+  if (Options & BIGBLKNUMOP) {

+    CopyMem (Ptr, BigBlkNumOp, sizeof (BigBlkNumOp));

+    CopyMem (Ptr + sizeof (BigBlkNumOp), "8", 2);

+    TotalLen += sizeof (BigBlkNumOp) + 2;

+    Ptr += sizeof (BigBlkNumOp) + 2;

+  }

+  //

+  // send it

+  //

+  return UdpWrite (

+          Private,

+          OpFlags,

+          ServerIpPtr,

+          ServerPortPtr,

+          0,

+          0,

+          OurPortPtr,

+          0,

+          0,

+          (UINTN *) &TotalLen,

+          u

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+TftpRwReqwResp (

+  UINT16                      Req,

+  UINT16                      Options,

+  PXE_BASECODE_DEVICE         *Private,

+  VOID                        *HeaderPtr,

+  UINTN                       *PacketSizePtr,

+  UINTN                       *ReplyLenPtr,

+  VOID                        *BufferPtr,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerPortPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *ServerReplyPortPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  *OurPortPtr,

+  UINT8                       *FilenamePtr,

+  UINT16                      Timeout

+  )

+/*++

+Routine description:

+  Start TFTP session.  Issue request and wait for response.

+  Retry three times on error.  If failed using options,

+  retry three times w/o options on error.

+

+Parameters:

+  Req := TFTP request type

+  Options := TFTP option bits

+  Private := Pointer to PxeBc interface

+  HeaderPtr := 

+  PacketSizePtr := Pointer to block size

+  ReplyLenPtr := 

+  BufferPtr := 

+  ServerIpPtr := Pointer to TFTP server IP address

+  ServerPortPtr := Pointer to TFTP server UDP port

+  ServerReplyPortPtr := 

+  OurPortPtr := Pointer to TFTP client UDP Port

+  FilenamePtr := Pointer to file or directory name

+  Timeout := 

+

+Returns:

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       SaveReplyLen;

+  INTN        Retries;

+  UINT8       Buffer[514];

+

+  SaveReplyLen            = *ReplyLenPtr;

+  Retries                 = 3;

+  Private->BigBlkNumFlag  = FALSE;

+  *OurPortPtr             = 0;

+  //

+  // generate random

+  //

+  do {

+    if (*OurPortPtr != 0) {

+      if (++ *OurPortPtr == 0) {

+        *OurPortPtr = PXE_RND_PORT_LOW;

+      }

+    }

+    //

+    // send request from our Ip = StationIp

+    //

+    if ((Status = TftpRwReq (

+                    Req,

+                    Options,

+                    Private,

+                    ServerIpPtr,

+                    ServerPortPtr,

+                    OurPortPtr,

+                    FilenamePtr,

+                    PacketSizePtr,

+                    Buffer

+                    )) != EFI_SUCCESS) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nTftpRwReqwResp()  Exit #1  %xh (%r)",

+        Status,

+        Status)

+        );

+

+      return Status;

+    }

+    //

+    // read reply to our Ip = StationIp

+    //

+    *ReplyLenPtr = SaveReplyLen;

+

+    Status = TftpUdpRead (

+              Private,

+              EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT,

+              HeaderPtr,

+              ReplyLenPtr,

+              BufferPtr,

+              ServerIpPtr,

+              ServerReplyPortPtr,

+              0,

+              OurPortPtr,

+              Timeout

+              );

+  } while (Status == EFI_TIMEOUT && --Retries);

+

+  if (!Options || Status != EFI_TFTP_ERROR) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nTftpRwReqwResp()  Exit #2  %xh (%r)",

+      Status,

+      Status)

+      );

+    return Status;

+  }

+

+  Status = TftpRwReqwResp (

+            Req,

+            0,

+            Private,

+            HeaderPtr,

+            PacketSizePtr,

+            ReplyLenPtr,

+            BufferPtr,

+            ServerIpPtr,

+            ServerPortPtr,

+            ServerReplyPortPtr,

+            OurPortPtr,

+            FilenamePtr,

+            Timeout

+            );

+

+  DEBUG ((EFI_D_WARN, "\nTftpRwReqwResp()  Exit #3  %xh (%r)", Status, Status));

+

+  return Status;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// mtftp listen

+// read on mcast ip, cport, from sport, for data packet

+// returns success if gets multicast last packet or all up to last block

+// if not missing, then finished

+//

+STATIC

+EFI_STATUS

+MtftpListen (

+  PXE_BASECODE_DEVICE           *Private,

+  UINT64                        *BufferSizePtr,

+  UINT8                         *BufferPtr,

+  EFI_IP_ADDRESS                *ServerIpPtr,

+  EFI_PXE_BASE_CODE_MTFTP_INFO  *MtftpInfoPtr,

+  UINT64                        *StartBlockPtr,

+  UINTN                         *NumMissedPtr,

+  UINT16                        TransTimeout,

+  UINT16                        ListenTimeout,

+  UINT64                        FinalBlock,

+  IN BOOLEAN                    DontUseBuffer

+  )

+/*++

+Routine description:

+  Listen for MTFTP traffic and save desired packets.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  BufferSizePtr := 

+  BufferPtr := 

+  ServerIpPtr := Pointer to TFTP server IP address

+  MtftpInfoPtr := Pointer to MTFTP session information

+  StartBlockPtr := IN=first block we are looking for  OUT=first block received

+  NumMissedPtr := Number of blocks missed

+  TransTimeout := 

+  ListenTimeout := 

+  FinalBlock := 

+  DontUseBuffer := TRUE == throw packets away, just count bytes

+

+Returns:

+--*/

+{

+  EFI_STATUS        Status;

+  struct Tftpv4Ack  Header;

+  UINT64            Offset;

+  UINT64            BlockNum;

+  UINT64            LastBlockNum;

+  UINT64            BufferSize;

+  UINTN             NumMissed;

+  UINTN             PacketSize;

+  UINTN             SaveReplyLen;

+  UINTN             ReplyLen;

+  UINT16            Timeout;

+

+  LastBlockNum  = *StartBlockPtr;

+  Timeout       = ListenTimeout;

+  *NumMissedPtr = 0;

+  PacketSize    = 0;

+  BufferSize    = *BufferSizePtr;

+  ReplyLen      = MAX_TFTP_PKT_SIZE;;

+

+  //

+  // receive

+  //

+  do {

+    if ((SaveReplyLen = ReplyLen) > BufferSize) {

+      SaveReplyLen = (UINTN) BufferSize;

+    }

+

+    /* %%TBD - add big block number support */

+

+    //

+    // get data - loop on resends

+    //

+    do {

+      ReplyLen = SaveReplyLen;

+

+      if ((Status = TftpUdpRead (

+                      Private,

+                      0,

+                      &Header,

+                      &ReplyLen,

+                      BufferPtr,

+                      ServerIpPtr,

+                      &MtftpInfoPtr->SPort,

+                      &MtftpInfoPtr->MCastIp,

+                      &MtftpInfoPtr->CPort,

+                      Timeout

+                      )) != EFI_SUCCESS) {

+        return Status;

+      }

+      //

+      // make sure a data packet

+      //

+      if (Header.OpCode != HTONS (TFTP_DATA)) {

+        return EFI_PROTOCOL_ERROR;

+      }

+    } while ((BlockNum = NTOHS (Header.BlockNum)) == LastBlockNum);

+

+    //

+    // make sure still going up

+    //

+    if (LastBlockNum > BlockNum) {

+      return EFI_PROTOCOL_ERROR;

+    }

+

+    if (BlockNum - LastBlockNum > 0xFFFFFFFF) {

+      return EFI_PROTOCOL_ERROR;

+    } else {

+      NumMissed = (UINTN) (BlockNum - LastBlockNum - 1);

+    }

+

+    LastBlockNum = BlockNum;

+

+    //

+    // if first time through, some reinitialization

+    //

+    if (!PacketSize) {

+      *StartBlockPtr  = BlockNum;

+      PacketSize      = ReplyLen;

+      Timeout         = TransTimeout;

+    } else {

+      *NumMissedPtr = (UINT16) (*NumMissedPtr + NumMissed);

+    }

+    //

+    // if missed packets, update start block,

+    // etc. and move packet to proper place in buffer

+    //

+    if (NumMissed) {

+      *StartBlockPtr = BlockNum;

+      if (!DontUseBuffer) {

+        Offset = NumMissed * PacketSize;

+        CopyMem (BufferPtr + Offset, BufferPtr, ReplyLen);

+        BufferPtr += Offset;

+        BufferSize -= Offset;

+      }

+    }

+

+    if (!DontUseBuffer) {

+      BufferPtr += ReplyLen;

+      BufferSize -= ReplyLen;

+    }

+  } while (ReplyLen == PacketSize && BlockNum != FinalBlock);

+

+  *BufferSizePtr = BufferSize;

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+MtftpOpen (

+  PXE_BASECODE_DEVICE                                               * Private,

+  UINT64                                                            *BufferSizePtr,

+  UINT8                                                             *BufferPtr,

+  UINTN                                                             *PacketSizePtr,

+  EFI_IP_ADDRESS                                                    * ServerIpPtr,

+  UINT8                                                             *FilenamePtr,

+  EFI_PXE_BASE_CODE_MTFTP_INFO                                      * MtftpInfoPtr,

+  UINT8                                                             *CompletionStatusPtr,

+#define GOTUNI 1

+#define GOTMULTI 2

+  IN BOOLEAN                    DontUseBuffer

+  )

+/*++

+Routine description:

+  Open MTFTP session.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  BufferSizePtr := IN=buffer size  OUT=transfer size

+  BufferPtr := 

+  PacketSizePtr := 

+  ServerIpPtr := 

+  FilenamePtr := 

+  MtftpInfoPtr := 

+  CompletionStatusPtr := 

+  DontUseBuffer := 

+

+Returns:

+// mtftp open session

+// return code EFI_SUCCESS 

+//      and *CompletionStatusPtr = GOTUNI | GOTMULTI means done

+//      and *CompletionStatusPtr = GOTMULTI means got first two multicast packets, use listen for rest

+//      and *CompletionStatusPtr = 0 means did not get first two multicast packets, use listen for all

+//      (do not get = GOTUNI - returns NO_DATA go will go to TFTP session)

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_IP_ADDRESS    OurReplyIp;

+  struct Tftpv4Ack  Header;

+  INTN              ReplyLen;

+  INTN              Retries;

+  UINT8             *BufferPtr2;

+  UINT8             TmpBuf[514];

+

+  Retries         = NUM_MTFTP_OPEN_RETRIES;

+  BufferPtr2      = BufferPtr;

+  *PacketSizePtr  = (UINTN) (EFI_MIN (*BufferSizePtr, MAX_TFTP_PKT_SIZE));

+

+  do {

+    //

+    // send a read request

+    //

+    *CompletionStatusPtr = 0;

+

+    if ((Status = TftpRwReq (

+                    TFTP_RRQ,

+                    0,

+                    Private,

+                    ServerIpPtr,

+                    &MtftpInfoPtr->SPort,

+                    &MtftpInfoPtr->CPort,

+                    FilenamePtr,

+                    PacketSizePtr,

+                    TmpBuf

+                    )) != EFI_SUCCESS) {

+      return Status;

+    }

+

+    for (;;) {

+      //

+      // read reply

+      //

+      ZeroMem (&OurReplyIp, Private->IpLength);

+      ReplyLen = *PacketSizePtr;

+

+      if ((Status = TftpUdpRead (

+                      Private,

+                      EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER,

+                      &Header,

+                      (UINTN *) &ReplyLen,

+                      BufferPtr2,

+                      ServerIpPtr,

+                      &MtftpInfoPtr->SPort,

+                      &OurReplyIp,

+                      &MtftpInfoPtr->CPort,

+                      MtftpInfoPtr->TransmitTimeout

+                      )) == EFI_SUCCESS) {

+        //

+        // check for first data packet

+        //

+        if (Header.OpCode != HTONS (TFTP_DATA)) {

+          return EFI_PROTOCOL_ERROR;

+        }

+        //

+        // check block num

+        //

+        if (Header.BlockNum != HTONS (1)) {

+          //

+          // it's not first

+          // if we are not the primary client,

+          // we probably got first and now second

+          // multicast but no unicast, so

+          // *CompletionStatusPtr = GOTMULTI - if this is

+          // the second, can just go on to listen

+          // starting with 2 as the last block

+          // received

+          //

+          if (Header.BlockNum != HTONS (2)) {

+            //

+            // not second

+            //

+            *CompletionStatusPtr = 0;

+          }

+

+          return Status;

+        }

+

+        //

+        // now actual

+        //

+        *PacketSizePtr = ReplyLen;

+        //

+        // see if a unicast data packet

+        //

+        if (!CompareMem (

+              &OurReplyIp,

+              &Private->EfiBc.Mode->StationIp,

+              Private->IpLength

+              )) {

+          *CompletionStatusPtr |= GOTUNI;

+          //

+          // it is

+          // if already got multicast packet,

+          // got em both

+          //

+          if (*CompletionStatusPtr & GOTMULTI) {

+            break;

+          }

+        } else if (!CompareMem (

+                    &OurReplyIp,

+                    &MtftpInfoPtr->MCastIp,

+                    Private->IpLength

+                    )) {

+          //

+          // otherwise see if a multicast data packet

+          //

+          *CompletionStatusPtr |= GOTMULTI;

+          //

+          // it is

+          // got first - bump pointer so that if

+          // second multi comes along, we're OK

+          //

+          if (!DontUseBuffer) {

+            BufferPtr2 = (UINT8 *) BufferPtr + ReplyLen;

+          }

+          //

+          // if already got unicast packet,

+          // got em both

+          //

+          if (*CompletionStatusPtr & GOTUNI) {

+            break;

+          }

+        } else {

+          //

+          // else protocol error

+          //

+          return EFI_PROTOCOL_ERROR;

+        }

+      } else if (Status == EFI_TIMEOUT) {

+        //

+        // bad return code - if timed out, retry

+        //

+        break;

+      } else {

+        //

+        // else just bad - failed MTFTP open

+        //

+        return Status;

+      }

+    }

+  } while (Status == EFI_TIMEOUT && --Retries);

+

+  if (Status != EFI_SUCCESS) {

+    //

+    // open failed

+    //

+    return Status;

+  }

+  //

+  // got em both - go into receive mode

+  // routine to read rest of file after a successful open (TFTP or MTFTP)

+  // sends ACK and gets next data packet until short packet arrives,

+  // then sends ACK and (hopefully) times out

+  //

+  return LockStepReceive (

+          Private,

+          (UINT16) ReplyLen,

+          BufferSizePtr,

+          ReplyLen,

+          BufferPtr,

+          ServerIpPtr,

+          &MtftpInfoPtr->SPort,

+          &MtftpInfoPtr->MCastIp,

+          &MtftpInfoPtr->CPort,

+          1,

+          MtftpInfoPtr->TransmitTimeout,

+          DontUseBuffer

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+MtftpDownload (

+  PXE_BASECODE_DEVICE           *Private,

+  UINT64                        *BufferSizePtr,

+  UINT8                         *BufferPtr,

+  EFI_IP_ADDRESS                *ServerIpPtr,

+  UINT8                         *FilenamePtr,

+  EFI_PXE_BASE_CODE_MTFTP_INFO  *MtftpInfoPtr,

+  IN BOOLEAN                    DontUseBuffer

+  )

+/*++

+Routine description:

+// mtftp

+// loop

+//  listen

+//  if did not get any packets, try MTFTP open

+//  if got all packets, return

+//  compute listen timeout and loop

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  BufferSizePtr := 

+  BufferPtr := 

+  ServerIpPtr := 

+  FilenamePtr := 

+  MtftpInfoPtr := 

+  DontUseBuffer := 

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_IP_FILTER Filter;

+  EFI_STATUS                  Status;

+  UINT64                      StartBlock;

+  UINT64                      LastBlock;

+  UINT64                      LastStartBlock;

+  UINT64                      BufferSize;

+  UINTN                       Offset;

+  UINTN                       NumMissed;

+  UINT16                      TransTimeout;

+  UINT16                      ListenTimeout;

+  UINT8                       *BufferPtrLocal;

+

+  TransTimeout      = MtftpInfoPtr->TransmitTimeout;

+  ListenTimeout     = MtftpInfoPtr->ListenTimeout;

+  LastBlock         = 0;

+  LastStartBlock    = 0;

+  Offset            = 0;

+

+  Filter.Filters    = EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST;

+  Filter.IpCnt      = 2;

+  CopyMem (&Filter.IpList[0], &Private->EfiBc.Mode->StationIp, sizeof (EFI_IP_ADDRESS));

+  CopyMem (&Filter.IpList[1], &MtftpInfoPtr->MCastIp, sizeof (EFI_IP_ADDRESS));

+

+  if ((Status = IpFilter (Private, &Filter)) != EFI_SUCCESS) {

+    return Status;

+  }

+

+  for (;;) {

+    StartBlock  = LastStartBlock;

+    BufferSize  = *BufferSizePtr - Offset;

+

+    if (DontUseBuffer) {

+    //

+    // overwrie the temp buf

+    //

+      BufferPtrLocal = BufferPtr;

+    } else {

+      BufferPtrLocal = BufferPtr + Offset;

+

+    }

+    //

+    // special !!! do not leave enabled in saved version on Source Safe

+    // Following code put in in order to create a special version for regression

+    // test of MTFTP server to make sure it handles mulitple opens correctly.

+    // This code should NOT be enabled normally.

+    //

+#ifdef SpecialNowaitVersion

+#pragma message ("This is special version for MTFTP regression test")

+    if (StartBlock || !LastBlock)

+#endif

+      if (((Status = MtftpListen (

+                      Private,

+                      &BufferSize,

+                      BufferPtrLocal,

+                      ServerIpPtr,

+                      MtftpInfoPtr,

+                      &StartBlock,

+                      &NumMissed,

+                      TransTimeout,

+                      ListenTimeout,

+                      LastBlock,

+                      DontUseBuffer

+                      )) != EFI_SUCCESS) && (Status != EFI_TIMEOUT)) {

+        return Status;

+        //

+        // failed

+        //

+      }

+    //

+    // if none were received, start block is not reset

+    //

+    if (StartBlock == LastStartBlock) {

+      UINT8 CompStat;

+

+      //

+      // timed out with none received - try MTFTP open

+      //

+      if ((Status = MtftpOpen (

+                      Private,

+                      BufferSizePtr,

+                      BufferPtr,

+                      &Offset,

+                      ServerIpPtr,

+                      FilenamePtr,

+                      MtftpInfoPtr,

+                      &CompStat,

+                      DontUseBuffer

+                      )) != EFI_SUCCESS) {

+        //

+        // open failure - try TFTP

+        //

+        return Status;

+      }

+      //

+      // return code EFI_SUCCESS

+      // and *CompletionStatusPtr = GOTUNI | GOTMULTI means done

+      // and *CompletionStatusPtr = GOTMULTI means got first two multicast packets, use listen for rest

+      // and *CompletionStatusPtr = 0 means did not get first two multicast packets, use listen for all

+      // (do not get = GOTUNI - returns NO_DATA go will go to TFTP session)

+      //

+      if (CompStat == (GOTUNI | GOTMULTI)) {

+      //

+      // finished - got it all

+      //

+        return Status;

+      }

+

+      if (CompStat) {

+        //

+        // offset is two packet lengths

+        //

+        Offset <<= 1;

+        //

+        // last block received

+        //

+        LastStartBlock = 2;

+      } else {

+        Offset          = 0;

+        LastStartBlock  = 0;

+      }

+

+      ListenTimeout = TransTimeout;

+      continue;

+    }

+    //

+    // did we get the last block

+    //

+    if (Status == EFI_SUCCESS) {

+      //

+      // yes - set the file size if this was first time

+      //

+      if (!LastBlock) {

+        *BufferSizePtr -= BufferSize;

+      }

+      //

+      // if buffer was too small, finished

+      //

+      if (!DontUseBuffer) {

+        return EFI_BUFFER_TOO_SMALL;

+      }

+      //

+      // if we got them all, finished

+      //

+      if (!NumMissed && StartBlock == LastStartBlock + 1) {

+        return Status;

+      }

+      //

+      // did not get them all - set last block

+      //

+      LastBlock = (UINT16) (StartBlock - 1);

+    }

+    //

+    // compute listen timeout

+    //

+    ListenTimeout = (UINT16) ((NumMissed > MtftpInfoPtr->ListenTimeout) ? 0 : (MtftpInfoPtr->ListenTimeout - NumMissed));

+

+    //

+    // reset

+    //

+    Offset          = 0;

+    LastStartBlock  = 0;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+TftpInfo (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT64                      *BufferSizePtr,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  SrvPort,

+  UINT8                       *FilenamePtr,

+  UINTN                       *PacketSizePtr

+  )

+/*++

+Routine description:

+// TFTP info request routine

+// send read request with block size and transfer size options

+// get reply

+// send error to terminate session

+// if OACK received, set info

+

+Parameters:

+  Private := 

+  BufferSizePtr := 

+  ServerIpPtr := 

+  SrvPort := 

+  FilenamePtr := 

+  PacketSizePtr := 

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_UDP_PORT  OurPort;

+  EFI_PXE_BASE_CODE_UDP_PORT  ServerReplyPort;

+  EFI_STATUS                  Status;

+  UINT64                      BlockNum;

+  UINTN                       Offset;

+  UINTN                       ReplyLen;

+  UINT8                       *Ptr;

+

+  union {

+    struct Tftpv4Oack OAck2Ptr;

+    struct Tftpv4Ack  Ack2Ptr;

+    struct Tftpv4Data Datastr;

+  } u;

+

+  OurPort         = 0;

+  ServerReplyPort = 0;

+  ReplyLen        = sizeof (u.Datastr.Data);

+

+  //

+  // send a write request with the blocksize option -

+  // sets our IP and port - and receive reply - sets his port

+  // will retry operation up to 3 times if no response,

+  // and will retry without options on an error reply

+  //

+  if ((Status = TftpRwReqwResp (

+                  TFTP_RRQ,

+                  /* BIGBLKNUMOP | */BKSZOP | TSIZEOP,

+                  Private,

+                  &u,

+                  PacketSizePtr,

+                  &ReplyLen,

+                  u.Datastr.Data,

+                  ServerIpPtr,

+                  &SrvPort,

+                  &ServerReplyPort,

+                  &OurPort,

+                  FilenamePtr,

+                  REQ_RESP_TIMEOUT

+                  )) != EFI_SUCCESS) {

+    DEBUG ((EFI_D_WARN, "\nTftpInfo()  Exit #1"));

+    return Status;

+  }

+  //

+  // check for good OACK

+  //

+  if (u.OAck2Ptr.OpCode == HTONS (TFTP_OACK)) {

+    //

+    // now parse it for options

+    // bigblk#

+    //

+    Ptr = FindOption (

+            BigBlkNumOp,

+            sizeof (BigBlkNumOp),

+            u.OAck2Ptr.OpAck[0].Option,

+            ReplyLen + sizeof (u.Ack2Ptr.BlockNum)

+            );

+

+    if (Ptr != NULL) {

+      if (AtoU (Ptr) == 8) {

+        Private->BigBlkNumFlag = TRUE;

+      } else {

+        return EFI_PROTOCOL_ERROR;

+      }

+    }

+    //

+    // blksize

+    //

+    Ptr = FindOption (

+            BlockSizeOp,

+            sizeof (BlockSizeOp),

+            u.OAck2Ptr.OpAck[0].Option,

+            ReplyLen += sizeof (u.Ack2Ptr.BlockNum)

+            );

+

+    *PacketSizePtr = (Ptr) ? AtoU (Ptr) : 512;

+

+    //

+    // tsize

+    //

+    Ptr = FindOption (

+            TsizeOp,

+            sizeof (TsizeOp),

+            u.OAck2Ptr.OpAck[0].Option,

+            ReplyLen

+            );

+

+    if (Ptr != NULL) {

+      *BufferSizePtr = AtoU64 (Ptr);

+

+      //

+      // teminate session with error

+      //

+      SendError (Private, ServerIpPtr, &ServerReplyPort, &OurPort);

+

+      return EFI_SUCCESS;

+    }

+

+    Offset    = 0;

+    BlockNum  = 0;

+  } else {

+    //

+    // if MTFTP get filesize, return unsupported

+    //

+    if (SrvPort != TftpRequestPort) {

+      SendError (Private, ServerIpPtr, &ServerReplyPort, &OurPort);

+      DEBUG ((EFI_D_WARN, "\nTftpInfo()  Exit #3"));

+      return EFI_UNSUPPORTED;

+    }

+

+    Offset    = ReplyLen;

+    //

+    // last block received

+    //

+    BlockNum  = 1;

+  }

+  //

+  // does not support the option - do a download with no buffer

+  //

+  *BufferSizePtr = 0;

+

+  Status = LockStepReceive (

+            Private,

+            (UINT16) ReplyLen,

+            BufferSizePtr,

+            Offset,

+            (UINT8 *) &u,

+            ServerIpPtr,

+            &ServerReplyPort,

+            &Private->EfiBc.Mode->StationIp,

+            &OurPort,

+            BlockNum,

+            ACK_TIMEOUT,

+            TRUE

+            );

+

+  if (Status != EFI_SUCCESS) {

+    DEBUG ((EFI_D_WARN, "\nTftpInfo()  LockStepReceive() == %Xh", Status));

+  }

+

+  if (Status != EFI_BUFFER_TOO_SMALL) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+TftpDownload (

+  PXE_BASECODE_DEVICE         *Private,

+  UINT64                      *BufferSizePtr,

+  UINT8                       *BufferPtr,

+  EFI_IP_ADDRESS              *ServerIpPtr,

+  UINT8                       *FilenamePtr,

+  UINTN                       *PacketSizePtr,

+  EFI_PXE_BASE_CODE_UDP_PORT  SrvPort,

+  UINT16                      Req,

+  IN BOOLEAN                  DontUseBuffer

+  )

+/*++

+Routine description:

+// tftp read session

+// send read request

+// [get OACK

+//  send ACK]

+// loop

+//  get data

+//  send ACK

+//  while data size is max

+

+Parameters:

+  Private := 

+  BufferSizePtr := 

+  BufferPtr := 

+  ServerIpPtr := 

+  FilenamePtr := 

+  PacketSizePtr := 

+  SrvPort := 

+  Req := 

+  DontUseBuffer := 

+

+Returns:

+--*/

+{

+  EFI_PXE_BASE_CODE_UDP_PORT  OurPort;

+  EFI_PXE_BASE_CODE_UDP_PORT  ServerReplyPort;

+  EFI_STATUS                  Status;

+  UINT64                      Offset;

+  UINT64                      BlockNum;

+  UINTN                       ReplyLen;

+  UINT8                       *Ptr;

+

+  union {

+    struct Tftpv4Ack    Ack2Ptr;

+    struct Tftpv4Oack   OAck2Ptr;

+    struct Tftpv4Data   Data;

+    struct Tftpv4Ack8   Ack8Ptr;

+    struct Tftpv4Data8  Data8;

+  } U;

+

+  OurPort         = 0;

+  ServerReplyPort = 0;

+  ReplyLen        = (UINTN) ((*BufferSizePtr > 0xFFFF) ? 0xFFFF : *BufferSizePtr);

+

+  //

+  // send a read request with the blocksize option - sets our IP and port

+  // - and receive reply - sets his port will retry operation up to 3

+  // times if no response, and will retry without options on an error

+  // reply

+  //

+  if ((Status = TftpRwReqwResp (

+                  Req,

+                  /* BIGBLKNUMOP | */BKSZOP,

+                  Private,

+                  &U,

+                  PacketSizePtr,

+                  &ReplyLen,

+                  BufferPtr,

+                  ServerIpPtr,

+                  &SrvPort,

+                  &ServerReplyPort,

+                  &OurPort,

+                  FilenamePtr,

+                  REQ_RESP_TIMEOUT

+                  )) != EFI_SUCCESS) {

+    DEBUG ((EFI_D_WARN, "\nTftpDownload()  Exit #1  %xh (%r)", Status, Status));

+    return Status;

+  }

+  //

+  // check for OACK

+  //

+  if (U.OAck2Ptr.OpCode == HTONS (TFTP_OACK)) {

+    //

+    // get the OACK

+    //

+    CopyMem (U.Data.Data, BufferPtr, ReplyLen);

+

+    Ptr = FindOption (

+            BigBlkNumOp,

+            sizeof (BigBlkNumOp),

+            U.OAck2Ptr.OpAck[0].Option,

+            ReplyLen + sizeof (U.Ack2Ptr.BlockNum)

+            );

+

+    if (Ptr != NULL) {

+      if (AtoU (Ptr) == 8) {

+        Private->BigBlkNumFlag = TRUE;

+      } else {

+        return EFI_PROTOCOL_ERROR;

+      }

+    }

+    //

+    // now parse it for blocksize option

+    //

+    Ptr = FindOption (

+            BlockSizeOp,

+            sizeof (BlockSizeOp),

+            U.OAck2Ptr.OpAck[0].Option,

+            ReplyLen += sizeof (U.Ack2Ptr.BlockNum)

+            );

+

+    ReplyLen  = (Ptr != NULL) ? AtoU (Ptr) : 512;

+

+    Offset    = 0;

+    //

+    // last block received

+    //

+    BlockNum  = 0;

+  } else if (U.Ack2Ptr.OpCode != HTONS (TFTP_DATA) || U.Ack2Ptr.BlockNum != HTONS (1)) {

+    //

+    // or data

+    //

+    DEBUG ((EFI_D_WARN, "\nTftpDownload()  Exit #2  %xh (%r)", Status, Status));

+

+    return EFI_PROTOCOL_ERROR;

+  } else {

+    //

+    // got good data packet

+    //

+    Offset    = ReplyLen;

+    //

+    // last block received

+    //

+    BlockNum  = 1;

+  }

+

+  if (PacketSizePtr != NULL) {

+    *PacketSizePtr = ReplyLen;

+  }

+  //

+  // routine to read rest of file after a successful open (TFTP or MTFTP)

+  // sends ACK and gets next data packet until short packet arrives, then sends

+  // ACK and (hopefully) times out

+  // if first packet has been read, BufferPtr and BufferSize must reflect fact

+  //

+  Status = LockStepReceive (

+            Private,

+            ReplyLen,

+            BufferSizePtr,

+            Offset,

+            BufferPtr,

+            ServerIpPtr,

+            &ServerReplyPort,

+            &Private->EfiBc.Mode->StationIp,

+            &OurPort,

+            BlockNum,

+            ACK_TIMEOUT,

+            DontUseBuffer

+            );

+

+  if (Status != EFI_SUCCESS) {

+    DEBUG ((EFI_D_WARN, "\nTftpDownload()  Exit #3  %xh (%r)", Status, Status));

+

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      Status = TftpInfo (

+                Private,

+                BufferSizePtr,

+                ServerIpPtr,

+                SrvPort,

+                FilenamePtr,

+                PacketSizePtr

+                );

+

+      if (!EFI_ERROR (Status)) {

+        Status = EFI_BUFFER_TOO_SMALL;

+      }

+    }

+  }

+

+  return Status;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+TftpUpload (

+  PXE_BASECODE_DEVICE *Private,

+  UINT64              *BufferSizePtr,

+  VOID                *BufferPtr,

+  EFI_IP_ADDRESS      *ServerIpPtr,

+  UINT8               *FilenamePtr,

+  UINTN               *PacketSizePtr,

+  BOOLEAN             Overwrite

+  )

+/*++

+Routine description:

+// tftp write session

+// send write request

+// get OACK or ACK

+// loop

+//  send min (rest of data, max data packet)

+//  get ACK

+//  while data size is max

+

+Parameters:

+  Private := 

+  BufferSizePtr := 

+  BufferPtr := 

+  ServerIpPtr := 

+  FilenamePtr := 

+  PacketSizePtr := 

+  Overwrite := 

+

+Returns:

+--*/

+{

+  struct Tftpv4Ack            Header;

+  EFI_PXE_BASE_CODE_UDP_PORT  OurPort;

+  EFI_PXE_BASE_CODE_UDP_PORT  ServerReplyPort;

+  EFI_STATUS                  Status;

+  UINT64                      BlockNum;

+  UINT64                      TransferSize;

+  UINTN                       ReplyLen;

+  UINTN                       TransferLen;

+  UINT16                      Options;

+  UINT8                       *Ptr;

+

+  union {

+    struct Tftpv4Oack OAck2Ptr;

+    struct Tftpv4Ack  Ack2Ptr;

+    struct Tftpv4Data Datastr;

+  } u;

+

+  OurPort         = 0;

+  ServerReplyPort = 0;

+  TransferSize    = *BufferSizePtr;

+  ReplyLen        = sizeof (u.Datastr.Data);

+  Options         = (UINT16) ((Overwrite) ? OVERWRITEOP | BKSZOP : BKSZOP);

+

+  //

+  // send a write request with the blocksize option - sets our IP and port -

+  // and receive reply - sets his port

+  // will retry operation up to 3 times if no response, and will retry without

+  // options on an error reply

+  //

+  if ((Status = TftpRwReqwResp (

+                  TFTP_WRQ,

+                  Options,

+                  Private,

+                  &u,

+                  PacketSizePtr,

+                  &ReplyLen,

+                  u.Datastr.Data,

+                  ServerIpPtr,

+                  &TftpRequestPort,

+                  &ServerReplyPort,

+                  &OurPort,

+                  FilenamePtr,

+                  REQ_RESP_TIMEOUT

+                  )) != EFI_SUCCESS) {

+    return Status;

+  }

+  //

+  // check for OACK

+  //

+  if (u.OAck2Ptr.OpCode == HTONS (TFTP_OACK)) {

+    //

+    // parse it for blocksize option

+    //

+    Ptr = FindOption (

+            BlockSizeOp,

+            sizeof (BlockSizeOp),

+            u.OAck2Ptr.OpAck[0].Option,

+            ReplyLen += sizeof (u.Ack2Ptr.BlockNum)

+            );

+    *PacketSizePtr = (Ptr) ? AtoU (Ptr) : 512;

+  }

+  //

+  // or ACK

+  //

+  else if (u.Ack2Ptr.OpCode == HTONS (TFTP_ACK)) {

+    //

+    // option was not supported

+    //

+    *PacketSizePtr = 512;

+  } else {

+    return EFI_PROTOCOL_ERROR;

+  }

+  //

+  // loop

+  //

+  Header.OpCode   = HTONS (TFTP_DATA);

+  BlockNum        = 1;

+  Header.BlockNum = HTONS (1);

+

+  do {

+    UINTN HeaderSize;

+    INTN  Retries;

+

+    Retries     = NUM_ACK_RETRIES;

+    HeaderSize  = sizeof (Header);

+    TransferLen = (UINTN) (EFI_MIN (*PacketSizePtr, TransferSize));

+

+    //

+    // write a data packet and get an ack

+    //

+    do {

+      //

+      // write

+      //

+      if ((Status = UdpWrite (

+                      Private,

+                      EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,

+                      ServerIpPtr,

+                      &ServerReplyPort,

+                      0,

+                      0,

+                      &OurPort,

+                      &HeaderSize,

+                      &Header,

+                      &TransferLen,

+                      BufferPtr

+                      )) != EFI_SUCCESS) {

+        return Status;

+      }

+      //

+      // read reply

+      //

+      ReplyLen = sizeof (u.Datastr.Data);

+

+      if ((Status = TftpUdpRead (

+                      Private,

+                      0,

+                      &u,

+                      &ReplyLen,

+                      u.Datastr.Data,

+                      ServerIpPtr,

+                      &ServerReplyPort,

+                      0,

+                      &OurPort,

+                      ACK_TIMEOUT

+                      )) == EFI_SUCCESS) {

+        //

+        // check for ACK for this data packet

+        //

+        if (u.Ack2Ptr.OpCode != HTONS (TFTP_ACK)) {

+          return EFI_PROTOCOL_ERROR;

+        }

+

+        if (u.Ack2Ptr.BlockNum != Header.BlockNum) {

+          //

+          // not for this packet - continue

+          //

+          Status = EFI_TIMEOUT;

+        }

+      }

+    } while (Status == EFI_TIMEOUT && --Retries);

+

+    if (Status != EFI_SUCCESS) {

+      return Status;

+    }

+

+    BufferPtr = (VOID *) ((UINT8 *) (BufferPtr) + TransferLen);

+    TransferSize -= TransferLen;

+    ++BlockNum;

+    Header.BlockNum = HTONS ((UINT16) BlockNum);

+  } while (TransferLen == *PacketSizePtr);

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+PxeBcMtftp (

+  PXE_BASECODE_DEVICE               *Private,

+  IN EFI_PXE_BASE_CODE_TFTP_OPCODE  Operation,

+  UINT64                            *BufferSizePtr,

+  VOID                              *BufferPtr,

+  EFI_IP_ADDRESS                    *ServerIpPtr,

+  UINT8                             *FilenamePtr,

+  UINTN                             *PacketSizePtr,

+  IN EFI_PXE_BASE_CODE_MTFTP_INFO   *MtftpInfoPtr, OPTIONAL

+  IN BOOLEAN                        Overwrite,

+  IN BOOLEAN                        DontUseBuffer

+  )

+/*++

+Routine description:

+  MTFTP API entry point

+

+Parameters:

+  Private := 

+  Operation := 

+  BufferSizePtr := 

+  BufferPtr := 

+  ServerIpPtr := 

+  FilenamePtr := 

+  PacketSizePtr := 

+  MtftpInfoPtr := 

+  Overwrite := 

+  DontUseBuffer := 

+

+Returns:

+ *  EFI_INVALID_PARAMETER

+ *  EFI_OUT_OF_RESOURCES

+ *  EFI_BAD_BUFFER_SIZE

+ *  Status is also returned from IpFilter(), TftpInfo(), MtftpDownload(),

+ *  TftpDownload() and TftpUpload().

+--*/

+{

+  EFI_PXE_BASE_CODE_IP_FILTER Filter;

+  EFI_STATUS                  StatCode;

+  EFI_STATUS                  Status;

+  UINT64                      BufferSizeLocal;

+  UINTN                       PacketSize;

+  UINT8                       *BufferPtrLocal;

+

+  Filter.Filters  = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;

+  Filter.IpCnt    = 0;

+  Filter.reserved = 0;

+

+  /* No error has occurred, yet. */

+  Private->EfiBc.Mode->TftpErrorReceived = FALSE;

+

+  /* We must at least have an MTFTP server IP address and

+   * a pointer to the buffer size.

+   */

+  if (!ServerIpPtr || !BufferSizePtr) {

+    DEBUG ((EFI_D_WARN, "\nPxeBcMtftp()  Exit #1"));

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private->Function = EFI_PXE_BASE_CODE_FUNCTION_MTFTP;

+

+  //

+  // make sure filter set to unicast at start

+  //

+  if ((StatCode = IpFilter (Private, &Filter)) != EFI_SUCCESS) {

+    DEBUG (

+      (EFI_D_NET,

+      "\nPxeBcMtftp()  Exit  IpFilter() == %Xh",

+      StatCode)

+      );

+

+    return StatCode;

+  }

+  //

+  // set unset parms to default values

+  //

+  if (!PacketSizePtr) {

+    *(PacketSizePtr = &PacketSize) = MAX_TFTP_PKT_SIZE;

+  }

+

+  if (*PacketSizePtr > *BufferSizePtr) {

+    *PacketSizePtr = (UINTN) *BufferSizePtr;

+  }

+

+  if (*PacketSizePtr < MIN_TFTP_PKT_SIZE) {

+    *PacketSizePtr = MIN_TFTP_PKT_SIZE;

+  }

+

+  if (*PacketSizePtr > BUFFER_ALLOCATE_SIZE) {

+    *PacketSizePtr = BUFFER_ALLOCATE_SIZE;

+  }

+

+  if (*PacketSizePtr > MAX_TFTP_PKT_SIZE) {

+    *PacketSizePtr = MAX_TFTP_PKT_SIZE;

+  }

+

+  if (Operation == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE) {

+    StatCode = TftpInfo (

+                Private,

+                BufferSizePtr,

+                ServerIpPtr,

+                TftpRequestPort,

+                FilenamePtr,

+                PacketSizePtr

+                );

+

+    if (StatCode != EFI_SUCCESS) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nPxeBcMtftp()  Exit  TftpInfo() == %Xh",

+        StatCode)

+        );

+    }

+

+    return StatCode;

+  }

+

+  if (Operation == EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE) {

+    if (!MtftpInfoPtr || !MtftpInfoPtr->SPort) {

+      DEBUG ((EFI_D_WARN, "\nPxeBcMtftp()  Exit #2"));

+      return EFI_INVALID_PARAMETER;

+    } else {

+      StatCode = TftpInfo (

+                  Private,

+                  BufferSizePtr,

+                  ServerIpPtr,

+                  MtftpInfoPtr->SPort,

+                  FilenamePtr,

+                  PacketSizePtr

+                  );

+

+      gBS->Stall (10000);

+

+      if (StatCode != EFI_SUCCESS) {

+        DEBUG (

+          (EFI_D_WARN,

+          "\nPxeBcMtftp()  Exit  TftpInfo() == %Xh",

+          StatCode)

+          );

+      }

+

+      return StatCode;

+    }

+  }

+

+  if (!BufferPtr && !DontUseBuffer) {

+    //

+    // if dontusebuffer is false and no buffer???

+    //

+    DEBUG ((EFI_D_WARN, "\nPxeBcMtftp()  Exit #3"));

+    //

+    // DontUseBuffer can be true only for read_file operation

+    //

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (DontUseBuffer) {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    BUFFER_ALLOCATE_SIZE,

+                    (VOID **) &BufferPtrLocal

+                    );

+

+    if (EFI_ERROR (Status) || BufferPtrLocal == NULL) {

+      DEBUG ((EFI_D_NET, "\nPxeBcMtftp()  Exit #4"));

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    BufferSizeLocal = BUFFER_ALLOCATE_SIZE;

+  } else {

+    if (!*BufferSizePtr && Operation != EFI_PXE_BASE_CODE_TFTP_WRITE_FILE) {

+      DEBUG ((EFI_D_WARN, "\nPxeBcMtftp()  Exit #5"));

+      return EFI_BAD_BUFFER_SIZE;

+    }

+

+    BufferPtrLocal  = BufferPtr;

+    BufferSizeLocal = *BufferSizePtr;

+  }

+

+  switch (Operation) {

+  case EFI_PXE_BASE_CODE_MTFTP_READ_FILE:

+    if (FilenamePtr == NULL ||

+        MtftpInfoPtr == NULL ||

+        MtftpInfoPtr->MCastIp.Addr[0] == 0 ||

+        MtftpInfoPtr->SPort == 0 ||

+        MtftpInfoPtr->CPort == 0 ||

+        MtftpInfoPtr->ListenTimeout == 0 ||

+        MtftpInfoPtr->TransmitTimeout == 0

+        ) {

+      StatCode = EFI_INVALID_PARAMETER;

+      break;

+    }

+    //

+    // try MTFTP - if fails, drop into TFTP read

+    //

+    if ((StatCode = MtftpDownload (

+                      Private,

+                      &BufferSizeLocal,

+                      BufferPtrLocal,

+                      ServerIpPtr,

+                      FilenamePtr,

+                      MtftpInfoPtr,

+                      DontUseBuffer

+                      )) == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {

+      if (BufferSizePtr /* %% !DontUseBuffer */ ) {

+        *BufferSizePtr = BufferSizeLocal;

+      }

+

+      break;

+    }

+    //

+    // go back to unicast

+    //

+    if ((StatCode = IpFilter (Private, &Filter)) != EFI_SUCCESS) {

+      break;

+    }

+

+  /* fall thru */

+  case EFI_PXE_BASE_CODE_TFTP_READ_FILE:

+    if (FilenamePtr == NULL) {

+      StatCode = EFI_INVALID_PARAMETER;

+      break;

+    }

+

+    StatCode = TftpDownload (

+                Private,

+                &BufferSizeLocal,

+                BufferPtrLocal,

+                ServerIpPtr,

+                FilenamePtr,

+                PacketSizePtr,

+                TftpRequestPort,

+                TFTP_RRQ,

+                DontUseBuffer

+                );

+

+    if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {

+      if (BufferSizePtr /* !DontUseBuffer */ ) {

+        *BufferSizePtr = BufferSizeLocal;

+      }

+    }

+

+    break;

+

+  case EFI_PXE_BASE_CODE_TFTP_WRITE_FILE:

+    if (FilenamePtr == NULL || DontUseBuffer) {

+      //

+      // not a valid option

+      //

+      StatCode = EFI_INVALID_PARAMETER;

+      break;

+    }

+

+    StatCode = TftpUpload (

+                Private,

+                BufferSizePtr,

+                BufferPtr,

+                ServerIpPtr,

+                FilenamePtr,

+                PacketSizePtr,

+                Overwrite

+                );

+

+    if (StatCode != EFI_SUCCESS) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nPxeBcMtftp()  Exit #6  %xh (%r)",

+        StatCode,

+        StatCode)

+        );

+    }

+

+    return StatCode;

+

+  case EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY:

+    if (FilenamePtr == NULL || DontUseBuffer) {

+      //

+      // not a valid option

+      //

+      StatCode = EFI_INVALID_PARAMETER;

+      break;

+    }

+

+    StatCode = TftpDownload (

+                Private,

+                BufferSizePtr,

+                BufferPtr,

+                ServerIpPtr,

+                FilenamePtr,

+                PacketSizePtr,

+                TftpRequestPort,

+                TFTP_DIR,

+                DontUseBuffer

+                );

+

+    if (StatCode != EFI_SUCCESS) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nPxeBcMtftp()  Exit #7  %xh (%r)",

+        StatCode,

+        StatCode)

+        );

+    }

+

+    return StatCode;

+

+  case EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY:

+    if (DontUseBuffer) {

+      StatCode = EFI_INVALID_PARAMETER;

+      break;

+    }

+

+    if (MtftpInfoPtr == NULL || !MtftpInfoPtr->SPort) {

+      DEBUG (

+        (EFI_D_WARN,

+        "\nPxeBcMtftp()  Exit #9  %xh (%r)",

+        EFI_INVALID_PARAMETER,

+        EFI_INVALID_PARAMETER)

+        );

+

+      return EFI_INVALID_PARAMETER;

+    }

+

+    StatCode = TftpDownload (

+                Private,

+                BufferSizePtr,

+                BufferPtr,

+                ServerIpPtr,

+                (UINT8 *) "/",

+                PacketSizePtr,

+                MtftpInfoPtr->SPort,

+                TFTP_DIR,

+                DontUseBuffer

+                );

+

+    break;

+

+  default:

+    StatCode = EFI_INVALID_PARAMETER;

+  }

+

+  if (DontUseBuffer) {

+    gBS->FreePool (BufferPtrLocal);

+  }

+

+  if (StatCode != EFI_SUCCESS) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nPxeBcMtftp()  Exit #8  %xh (%r)",

+      StatCode,

+      StatCode)

+      );

+  }

+

+  gBS->Stall (10000);

+

+  return StatCode;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+BcMtftp (

+  IN EFI_PXE_BASE_CODE_PROTOCOL       * This,

+  IN EFI_PXE_BASE_CODE_TFTP_OPCODE    Operation,

+  IN OUT VOID                         *BufferPtr,

+  IN BOOLEAN                          Overwrite,

+  IN OUT UINT64                       *BufferSizePtr,

+  IN UINTN                            *BlockSizePtr OPTIONAL,

+  IN EFI_IP_ADDRESS                   * ServerIpPtr,

+  IN UINT8                            *FilenamePtr,

+  IN EFI_PXE_BASE_CODE_MTFTP_INFO     * MtftpInfoPtr OPTIONAL,

+  IN BOOLEAN                          DontUseBuffer

+  )

+/*++

+Routine description:

+  MTFTP API entry point.

+

+Parameters:

+  This := 

+  Operation := 

+  BufferPtr := 

+  Overwrite := 

+  BufferSizePtr := 

+  BlockSizePtr := 

+  ServerIpPtr := 

+  FilenamePtr := 

+  MtftpInfoPtr := 

+  DontUseBuffer := 

+

+Returns:

+ *  EFI_INVALID_PARAMETER

+ *  Status is also returned from PxeBcMtftp();

+--*/

+{

+  EFI_PXE_BASE_CODE_IP_FILTER Filter;

+  EFI_STATUS                  StatCode;

+  PXE_BASECODE_DEVICE         *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+  //

+  // Issue BC command

+  //

+  Filter.Filters  = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;

+  Filter.IpCnt    = 0;

+  Filter.reserved = 0;

+

+  DEBUG ((EFI_D_WARN, "\nBcMtftp()  Op=%d  Buf=%Xh", Operation, BufferPtr));

+

+  StatCode = PxeBcMtftp (

+              Private,

+              Operation,

+              BufferSizePtr,

+              BufferPtr,

+              ServerIpPtr,

+              FilenamePtr,

+              BlockSizePtr,

+              MtftpInfoPtr,

+              Overwrite,

+              DontUseBuffer

+              );

+

+  //

+  // restore to unicast

+  //

+  IpFilter (Private, &Filter);

+

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+/* eof - PxeBcMtftp.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_udp.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_udp.c
new file mode 100644
index 0000000..7d78295
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_udp.c
@@ -0,0 +1,577 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  pxe_bc_udp.c

+

+Abstract:

+

+--*/

+

+

+#include "Bc.h"

+

+//

+// //////////////////////////////////////////////////////////////////////

+//

+//  Udp Write Routine - called by base code - e.g. TFTP - already locked

+//

+EFI_STATUS

+UdpWrite (

+  IN PXE_BASECODE_DEVICE            *Private,

+  IN UINT16                         OpFlags,

+  IN EFI_IP_ADDRESS                 *DestIpPtr,

+  IN EFI_PXE_BASE_CODE_UDP_PORT     *DestPortPtr,

+  IN EFI_IP_ADDRESS                 *GatewayIpPtr, OPTIONAL

+  IN EFI_IP_ADDRESS                 *SrcIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL

+  IN UINTN                          *HeaderSizePtr, OPTIONAL

+  IN VOID                           *HeaderPtr, OPTIONAL

+  IN UINTN                          *BufferSizeptr,

+  IN VOID                           *BufferPtr

+  )

+/*++

+Routine description:

+  UDP write packet.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  OpFlags := 

+  DestIpPtr := 

+  DestPortPtr := 

+  GatewayIpPtr := 

+  SrcIpPtr := 

+  SrcPortPtr := 

+  HeaderSizePtr := 

+  HeaderPtr := 

+  BufferSizeptr := 

+  BufferPtr := 

+

+Returns:

+  EFI_SUCCESS := 

+  EFI_INVALID_PARAMETER := 

+  other := 

+--*/

+{

+  UINTN                       TotalLength;

+  UINTN                       HeaderSize;

+  EFI_PXE_BASE_CODE_UDP_PORT  DefaultSrcPort;

+

+  //

+  //

+  //

+  HeaderSize      = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;

+  DefaultSrcPort  = 0;

+

+  //

+  // check parameters

+  //

+  if (BufferSizeptr == NULL ||

+      BufferPtr == NULL ||

+      DestIpPtr == NULL ||

+      DestPortPtr == NULL ||

+      (HeaderSizePtr != NULL && *HeaderSizePtr == 0) ||

+      (HeaderSize != 0 && HeaderPtr == NULL) ||

+      (GatewayIpPtr != NULL && !IS_INADDR_UNICAST(GatewayIpPtr)) ||

+      (OpFlags &~(EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT))

+      ) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nUdpWrite()  Exit #1  %xh (%r)",

+      EFI_INVALID_PARAMETER,

+      EFI_INVALID_PARAMETER)

+      );

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  TotalLength = *BufferSizeptr + HeaderSize + sizeof (UDPV4_HEADER);

+

+  if (TotalLength > 0x0000ffff) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nUdpWrite()  Exit #2  %xh (%r)",

+      EFI_BAD_BUFFER_SIZE,

+      EFI_BAD_BUFFER_SIZE)

+      );

+

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (SrcIpPtr == NULL) {

+    SrcIpPtr = &Private->EfiBc.Mode->StationIp;

+  }

+

+  if (SrcPortPtr == NULL) {

+    SrcPortPtr = &DefaultSrcPort;

+    OpFlags |= EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT;

+  }

+

+  if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) {

+    *SrcPortPtr = Private->RandomPort;

+

+    if (++Private->RandomPort == 0) {

+      Private->RandomPort = PXE_RND_PORT_LOW;

+    }

+  }

+

+#define IpTxBuffer  ((IPV4_BUFFER *) Private->TransmitBufferPtr)

+  //

+  // build pseudo header and udp header in transmit buffer

+  //

+#define Udpv4Base ((UDPV4_HEADERS *) (IpTxBuffer->u.Data - sizeof (UDPV4_PSEUDO_HEADER)))

+

+  Udpv4Base->Udpv4PseudoHeader.SrcAddr.L    = SrcIpPtr->Addr[0];

+  Udpv4Base->Udpv4PseudoHeader.DestAddr.L   = DestIpPtr->Addr[0];

+  Udpv4Base->Udpv4PseudoHeader.Zero         = 0;

+  Udpv4Base->Udpv4PseudoHeader.Protocol     = PROT_UDP;

+  Udpv4Base->Udpv4PseudoHeader.TotalLength  = HTONS (TotalLength);

+  Udpv4Base->Udpv4Header.SrcPort            = HTONS (*SrcPortPtr);

+  Udpv4Base->Udpv4Header.DestPort           = HTONS (*DestPortPtr);

+  Udpv4Base->Udpv4Header.TotalLength        = Udpv4Base->Udpv4PseudoHeader.TotalLength;

+  Udpv4Base->Udpv4Header.Checksum           = 0;

+

+  if (HeaderSize != 0) {

+    CopyMem (IpTxBuffer->u.Udp.Data, HeaderPtr, HeaderSize);

+  }

+

+  HeaderSize += sizeof (UDPV4_HEADER);

+

+  Udpv4Base->Udpv4Header.Checksum = IpChecksum2 (

+                                      (UINT16 *) Udpv4Base,

+                                      HeaderSize + sizeof (UDPV4_PSEUDO_HEADER),

+                                      (UINT16 *) BufferPtr,

+                                      (UINT16) *BufferSizeptr

+                                      );

+

+  if (Udpv4Base->Udpv4Header.Checksum == 0) {

+    Udpv4Base->Udpv4Header.Checksum = 0xffff;

+    //

+    // transmit zero checksum as ones complement

+    //

+  }

+

+  return Ip4Send (

+          Private,

+          OpFlags,

+          PROT_UDP,

+          Udpv4Base->Udpv4PseudoHeader.SrcAddr.L,

+          Udpv4Base->Udpv4PseudoHeader.DestAddr.L,

+          (GatewayIpPtr) ? GatewayIpPtr->Addr[0] : 0,

+          HeaderSize,

+          BufferPtr,

+          *BufferSizeptr

+          );

+}

+//

+// //////////////////////////////////////////////////////////

+//

+//  BC Udp Write Routine

+//

+EFI_STATUS

+EFIAPI

+BcUdpWrite (

+  IN EFI_PXE_BASE_CODE_PROTOCOL     *This,

+  IN UINT16                         OpFlags,

+  IN EFI_IP_ADDRESS                 *DestIpPtr,

+  IN EFI_PXE_BASE_CODE_UDP_PORT     *DestPortPtr,

+  IN EFI_IP_ADDRESS                 *GatewayIpPtr, OPTIONAL

+  IN EFI_IP_ADDRESS                 *SrcIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL

+  IN UINTN                          *HeaderSizePtr, OPTIONAL

+  IN VOID                           *HeaderPtr, OPTIONAL

+  IN UINTN                          *BufferSizeptr,

+  IN VOID                           *BufferPtr

+  )

+/*++

+Routine description:

+  UDP write API entry point.

+

+Parameters:

+  This := Pointer to PxeBc interface.

+  OpFlags := 

+  DestIpPtr := 

+  DestPortPtr := 

+  GatewayIpPtr := 

+  SrcIpPtr := 

+  SrcPortPtr := 

+  HeaderSizePtr := 

+  HeaderPtr := 

+  BufferSizeptr := 

+  BufferPtr := 

+

+Returns:

+  EFI_SUCCESS := 

+  other := 

+--*/

+{

+  EFI_STATUS          StatCode;

+  PXE_BASECODE_DEVICE *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE;

+

+  //

+  // Issue BC command

+  //

+  StatCode = UdpWrite (

+              Private,

+              OpFlags,

+              DestIpPtr,

+              DestPortPtr,

+              GatewayIpPtr,

+              SrcIpPtr,

+              SrcPortPtr,

+              HeaderSizePtr,

+              HeaderPtr,

+              BufferSizeptr,

+              BufferPtr

+              );

+

+  //

+  // Unlock the instance data

+  //

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+//

+// /////////////////////////////////////////////////////////////////////

+//

+//  Udp Read Routine - called by base code - e.g. TFTP - already locked

+//

+EFI_STATUS

+UdpRead (

+  IN PXE_BASECODE_DEVICE            *Private,

+  IN UINT16                         OpFlags,

+  IN OUT EFI_IP_ADDRESS             *DestIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr, OPTIONAL

+  IN OUT EFI_IP_ADDRESS             *SrcIpPtr, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL

+  IN UINTN                          *HeaderSizePtr, OPTIONAL

+  IN VOID                           *HeaderPtr, OPTIONAL

+  IN OUT UINTN                      *BufferSizeptr,

+  IN VOID                           *BufferPtr,

+  EFI_EVENT                         TimeoutEvent

+  )

+/*++

+Routine description:

+  UDP read packet.

+

+Parameters:

+  Private := Pointer to PxeBc interface

+  OpFlags := 

+  DestIpPtr := 

+  DestPortPtr := 

+  SrcIpPtr := 

+  SrcPortPtr := 

+  HeaderSizePtr := 

+  HeaderPtr := 

+  BufferSizeptr := 

+  BufferPtr := 

+  TimeoutEvent :=

+

+Returns:

+  EFI_SUCCESS := 

+  EFI_INVALID_PARAMETER := 

+  other := 

+--*/

+{

+  EFI_STATUS      StatCode;

+  EFI_IP_ADDRESS  TmpSrcIp;

+  EFI_IP_ADDRESS  TmpDestIp;

+  UINTN           BufferSize;

+  UINTN           HeaderSize;

+

+  //

+  // combination structure of pseudo header/udp header

+  //

+#pragma pack (1)

+  struct {

+    UDPV4_PSEUDO_HEADER Udpv4PseudoHeader;

+    UDPV4_HEADER        Udpv4Header;

+    UINT8               ProtHdr[64];

+  } Hdrs;

+#pragma pack ()

+

+  HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;

+  //

+  // read [with filtering]

+  // check parameters

+  //

+  if (BufferSizeptr == NULL ||

+      BufferPtr == NULL ||

+      (HeaderSize != 0 && HeaderPtr == NULL) ||

+      (OpFlags &~UDP_FILTER_MASK)

+      //

+      // if filtering on a particular IP/Port, need it

+      //

+      ||

+      (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr == NULL) ||

+      (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && SrcPortPtr == NULL) ||

+      (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && DestPortPtr == NULL)

+      ) {

+    DEBUG ((EFI_D_INFO, "\nUdpRead()  Exit #1  Invalid Parameter"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // in case we loop

+  //

+  BufferSize = *BufferSizeptr;

+  //

+  // we need source and dest IPs for pseudo header

+  //

+  if (SrcIpPtr == NULL) {

+    SrcIpPtr = &TmpSrcIp;

+  }

+

+  if (DestIpPtr == NULL) {

+    DestIpPtr = &TmpDestIp;

+    CopyMem (&TmpDestIp, &Private->EfiBc.Mode->StationIp, sizeof (TmpDestIp));

+  }

+

+#if SUPPORT_IPV6

+  if (Private->EfiBc.Mode->UsingIpv6) {

+    //

+    // %%TBD

+    //

+  }

+#endif

+

+  for (;;) {

+    *BufferSizeptr = BufferSize;

+

+    StatCode = IpReceive (

+                Private,

+                OpFlags,

+                SrcIpPtr,

+                DestIpPtr,

+                PROT_UDP,

+                &Hdrs.Udpv4Header,

+                HeaderSize + sizeof Hdrs.Udpv4Header,

+                BufferPtr,

+                BufferSizeptr,

+                TimeoutEvent

+                );

+

+    if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {

+      UINT16  SPort;

+      UINT16  DPort;

+

+      SPort = NTOHS (Hdrs.Udpv4Header.SrcPort);

+      DPort = NTOHS (Hdrs.Udpv4Header.DestPort);

+

+      //

+      // do filtering

+      //

+      if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && *SrcPortPtr != SPort) {

+        continue;

+      }

+

+      if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && *DestPortPtr != DPort) {

+        continue;

+      }

+      //

+      // check checksum

+      //

+      if (StatCode == EFI_SUCCESS && Hdrs.Udpv4Header.Checksum) {

+        Hdrs.Udpv4PseudoHeader.SrcAddr.L    = SrcIpPtr->Addr[0];

+        Hdrs.Udpv4PseudoHeader.DestAddr.L   = DestIpPtr->Addr[0];

+        Hdrs.Udpv4PseudoHeader.Zero         = 0;

+        Hdrs.Udpv4PseudoHeader.Protocol     = PROT_UDP;

+        Hdrs.Udpv4PseudoHeader.TotalLength  = Hdrs.Udpv4Header.TotalLength;

+

+        if (Hdrs.Udpv4Header.Checksum == 0xffff) {

+          Hdrs.Udpv4Header.Checksum = 0;

+        }

+

+        if (IpChecksum2 (

+              (UINT16 *) &Hdrs.Udpv4PseudoHeader,

+              HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader) + sizeof (Hdrs.Udpv4Header),

+              (UINT16 *) BufferPtr,

+              *BufferSizeptr

+              )) {

+          DEBUG (

+            (EFI_D_INFO,

+            "\nUdpRead()  Hdrs.Udpv4PseudoHeader == %Xh",

+            &Hdrs.Udpv4PseudoHeader)

+            );

+          DEBUG (

+            (EFI_D_INFO,

+            "\nUdpRead()  Header size == %d",

+            HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader))

+            );

+          DEBUG (

+            (EFI_D_INFO,

+            "\nUdpRead()  BufferPtr == %Xh",

+            BufferPtr)

+            );

+          DEBUG (

+            (EFI_D_INFO,

+            "\nUdpRead()  Buffer size == %d",

+            *BufferSizeptr)

+            );

+          DEBUG ((EFI_D_INFO, "\nUdpRead()  Exit #2  Device Error"));

+          return EFI_DEVICE_ERROR;

+        }

+      }

+      //

+      // all passed

+      //

+      if (SrcPortPtr != NULL) {

+        *SrcPortPtr = SPort;

+      }

+

+      if (DestPortPtr != NULL) {

+        *DestPortPtr = DPort;

+      }

+

+      if (HeaderSize != 0) {

+        CopyMem (HeaderPtr, Hdrs.ProtHdr, HeaderSize);

+      }

+    }

+

+    switch (StatCode) {

+    case EFI_SUCCESS:

+    case EFI_TIMEOUT:

+      break;

+

+    default:

+      DEBUG (

+        (EFI_D_INFO,

+        "\nUdpRead()  Exit #3  %Xh %r",

+        StatCode,

+        StatCode)

+        );

+    }

+

+    return StatCode;

+  }

+}

+//

+// //////////////////////////////////////////////////////////

+//

+//  BC Udp Read Routine

+//

+EFI_STATUS

+EFIAPI

+BcUdpRead (

+  IN EFI_PXE_BASE_CODE_PROTOCOL     *This,

+  IN UINT16                         OpFlags,

+  IN OUT EFI_IP_ADDRESS             *DestIp, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL

+  IN OUT EFI_IP_ADDRESS             *SrcIp, OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL

+  IN UINTN                          *HeaderSize, OPTIONAL

+  IN VOID                           *HeaderPtr, OPTIONAL

+  IN OUT UINTN                      *BufferSize,

+  IN VOID                           *BufferPtr

+  )

+/*++

+Routine description:

+  UDP read API entry point.

+

+Parameters:

+  This := Pointer to PxeBc interface.

+  OpFlags := 

+  DestIpPtr := 

+  DestPortPtr := 

+  SrcIpPtr := 

+  SrcPortPtr := 

+  HeaderSizePtr := 

+  HeaderPtr := 

+  BufferSizeptr := 

+  BufferPtr := 

+

+Returns:

+  EFI_SUCCESS := 

+  other := 

+--*/

+{

+  EFI_STATUS          StatCode;

+  PXE_BASECODE_DEVICE *Private;

+

+  //

+  // Lock the instance data and make sure started

+  //

+  StatCode = EFI_SUCCESS;

+

+  if (This == NULL) {

+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

+

+  if (Private == NULL) {

+    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiAcquireLock (&Private->Lock);

+

+  if (This->Mode == NULL || !This->Mode->Started) {

+    DEBUG ((EFI_D_ERROR, "BC was not started."));

+    EfiReleaseLock (&Private->Lock);

+    return EFI_NOT_STARTED;

+  }

+

+  Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_READ;

+

+  //

+  // Issue BC command

+  //

+  StatCode = UdpRead (

+              Private,

+              OpFlags,

+              DestIp,

+              DestPort,

+              SrcIp,

+              SrcPort,

+              HeaderSize,

+              HeaderPtr,

+              BufferSize,

+              BufferPtr,

+              0

+              );

+

+  //

+  // Unlock the instance data and return

+  //

+  EfiReleaseLock (&Private->Lock);

+  return StatCode;

+}

+

+/* eof - pxe_bc_udp.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c
new file mode 100644
index 0000000..315c95a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c
@@ -0,0 +1,1697 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  pxe_loadfile.c

+  

+Abstract:

+  An implementation of the load file protocol for network devices.

+

+--*/

+

+

+#include "Bc.h"

+

+#define DO_MENU     (EFI_SUCCESS)

+#define NO_MENU     (DO_MENU + 1)

+#define LOCAL_BOOT  (EFI_ABORTED)

+#define AUTO_SELECT (NO_MENU)

+

+#define NUMBER_ROWS   25  // we set to mode 0

+#define MAX_MENULIST  23

+

+#define Ctl(x)  (0x1F & (x))

+

+typedef union {

+  DHCPV4_OP_STRUCT          *OpPtr;

+  PXE_BOOT_MENU_ENTRY       *CurrentMenuItemPtr;

+  PXE_OP_DISCOVERY_CONTROL  *DiscCtlOpStr;

+  PXE_OP_BOOT_MENU          *MenuPtr;

+  UINT8                     *BytePtr;

+} UNION_PTR;

+

+

+STATIC

+EFI_PXE_BASE_CODE_CALLBACK_STATUS

+EFIAPI

+bc_callback (

+  IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  * This,

+  IN EFI_PXE_BASE_CODE_FUNCTION           Function,

+  IN BOOLEAN                              Received,

+  IN UINT32                               PacketLength,

+  IN EFI_PXE_BASE_CODE_PACKET             * PacketPtr OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  PxeBc callback routine for status updates and aborts.

+

+Arguments:

+

+  This - Pointer to PxeBcCallback interface

+  Function - PxeBc function ID#

+  Received - Receive/transmit flag

+  PacketLength - Length of received packet (0 == idle callback)

+  PacketPtr - Pointer to received packet (NULL == idle callback)

+

+Returns:

+

+  EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE - 

+  EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT -

+  

+--*/

+{

+  STATIC UINTN  Propeller;

+

+  EFI_INPUT_KEY Key;

+  UINTN         Row;

+  UINTN         Col;

+

+  Propeller = 0;

+  //

+  // Resolve Warning 4 unreferenced parameter problem

+  //

+  This = This;

+

+  //

+  // Check for user abort.

+  //

+  if (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key) == EFI_SUCCESS) {

+    if (!Key.ScanCode) {

+      if (Key.UnicodeChar == Ctl ('c')) {

+        return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT;

+      }

+    } else if (Key.ScanCode == SCAN_ESC) {

+      return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT;

+    }

+  }

+  //

+  // Do nothing if this is a receive.

+  //

+  if (Received) {

+    return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;

+  }

+  //

+  // The display code is only for these functions.

+  //

+  switch (Function) {

+  case EFI_PXE_BASE_CODE_FUNCTION_MTFTP:

+    //

+    // If this is a transmit and not a M/TFTP open request,

+    // return now.  Do not print a dot for each M/TFTP packet

+    // that is sent, only for the open packets.

+    //

+    if (PacketLength != 0 && PacketPtr != NULL) {

+      if (PacketPtr->Raw[0x1C] != 0x00 || PacketPtr->Raw[0x1D] != 0x01) {

+        return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;

+      }

+    }

+

+    break;

+

+  case EFI_PXE_BASE_CODE_FUNCTION_DHCP:

+  case EFI_PXE_BASE_CODE_FUNCTION_DISCOVER:

+    break;

+

+  default:

+    return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;

+  }

+  //

+  // Display routines

+  //

+  if (PacketLength != 0 && PacketPtr != NULL) {

+    //

+    // Display a '.' when a packet is transmitted.

+    //

+    AsciiPrint (".");

+  } else if (PacketLength == 0 && PacketPtr == NULL) {

+    //

+    // Display a propeller when waiting for packets if at

+    // least 200 ms have passed.

+    //

+    Row = gST->ConOut->Mode->CursorRow;

+    Col = gST->ConOut->Mode->CursorColumn;

+

+    AsciiPrint ("%c", "/-\\|"[Propeller]);

+    gST->ConOut->SetCursorPosition (gST->ConOut, Col, Row);

+

+    Propeller = (Propeller + 1) & 3;

+  }

+

+  return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;

+}

+

+STATIC EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  _bc_callback = {

+  EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION,

+  &bc_callback

+};

+

+STATIC

+VOID

+PrintIpv4 (

+  UINT8 *Ptr

+  )

+/*++

+

+Routine Description:

+

+  Display an IPv4 address in dot notation.

+

+Arguments:

+

+  Ptr - Pointer to IPv4 address.

+

+Returns:

+

+  None

+  

+--*/

+{

+  if (Ptr != NULL) {

+    AsciiPrint ("%d.%d.%d.%d", Ptr[0], Ptr[1], Ptr[2], Ptr[3]);

+  }

+}

+

+STATIC

+VOID

+ShowMyInfo (

+  IN PXE_BASECODE_DEVICE *Private

+  )

+/*++

+

+Routine Description:

+

+  Display client and server IP information.

+

+Arguments:

+

+  Private - Pointer to PxeBc interface

+

+Returns:

+

+  None

+  

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;

+  UINTN                   Index;

+

+  //

+  // Do nothing if a NULL pointer is passed in.

+  //

+  if (Private == NULL) {

+    return ;

+  }

+  //

+  // Get pointer to PXE BaseCode mode structure

+  //

+  PxeBcMode = Private->EfiBc.Mode;

+

+  //

+  // Display client IP address

+  //

+  AsciiPrint ("\rCLIENT IP: ");

+  PrintIpv4 (PxeBcMode->StationIp.v4.Addr);

+

+  //

+  // Display subnet mask

+  //

+  AsciiPrint ("  MASK: ");

+  PrintIpv4 (PxeBcMode->SubnetMask.v4.Addr);

+

+  //

+  // Display DHCP and proxyDHCP IP addresses

+  //

+  if (PxeBcMode->ProxyOfferReceived) {

+    AsciiPrint ("\nDHCP IP: ");

+    PrintIpv4 (((DHCPV4_OP_SERVER_IP *) DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip.Addr);

+

+    AsciiPrint ("  PROXY IP: ");

+    PrintIpv4 (((DHCPV4_OP_SERVER_IP *) PXE_OFFER_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip.Addr);

+  } else {

+    AsciiPrint ("  DHCP IP: ");

+    PrintIpv4 (((DHCPV4_OP_SERVER_IP *) DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip.Addr);

+  }

+  //

+  // Display gateway IP addresses

+  //

+  for (Index = 0; Index < PxeBcMode->RouteTableEntries; ++Index) {

+    if ((Index % 3) == 0) {

+      AsciiPrint ("\r\nGATEWAY IP:");

+    }

+

+    AsciiPrint (" ");

+    PrintIpv4 (PxeBcMode->RouteTable[Index].GwAddr.v4.Addr);

+    AsciiPrint (" ");

+  }

+

+  AsciiPrint ("\n");

+}

+

+STATIC

+EFI_STATUS

+DoPrompt (

+  PXE_BASECODE_DEVICE *Private,

+  PXE_OP_BOOT_PROMPT  *BootPromptPtr

+  )

+/*++

+

+Routine Description:

+

+  Display prompt and wait for input.

+

+Arguments:

+

+  Private - Pointer to PxeBc interface

+  BootPromptPtr - Pointer to PXE boot prompt option

+

+Returns:

+

+  AUTO_SELECT - 

+  DO_MENU -

+  NO_MENU - 

+  LOCAL_BOOT - 

+  

+--*/

+{

+  EFI_STATUS  Status;

+  EFI_EVENT   TimeoutEvent;

+  EFI_EVENT   SecondsEvent;

+  INT32       SecColumn;

+  INT32       SecRow;

+  UINT8       SaveChar;

+  UINT8       SecsLeft;

+

+  //

+  // if auto select, just get right to it

+  //

+  if (BootPromptPtr->Timeout == PXE_BOOT_PROMPT_AUTO_SELECT) {

+    return AUTO_SELECT;

+  }

+  //

+  // if no timeout, go directly to display of menu

+  //

+  if (BootPromptPtr->Timeout == PXE_BOOT_PROMPT_NO_TIMEOUT) {

+    return DO_MENU;

+  }

+  //

+  //

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER,

+                  EFI_TPL_CALLBACK,

+                  NULL,

+                  NULL,

+                  &TimeoutEvent

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return DO_MENU;

+  }

+

+  Status = gBS->SetTimer (

+                  TimeoutEvent,

+                  TimerRelative,

+                  BootPromptPtr->Timeout * 10000000 + 100000

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return DO_MENU;

+  }

+  //

+  //

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER,

+                  EFI_TPL_CALLBACK,

+                  NULL,

+                  NULL,

+                  &SecondsEvent

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (TimeoutEvent);

+    return DO_MENU;

+  }

+

+  Status = gBS->SetTimer (

+                  SecondsEvent,

+                  TimerPeriodic,

+                  10000000

+                  );  /* 1 second */

+

+  if (EFI_ERROR (Status)) {

+    gBS->CloseEvent (SecondsEvent);

+    gBS->CloseEvent (TimeoutEvent);

+    return DO_MENU;

+  }

+  //

+  // display the prompt

+  // IMPORTANT!  This prompt is an ASCII character string that may

+  // not be terminated with a NULL byte.

+  //

+  SaveChar  = BootPromptPtr->Prompt[BootPromptPtr->Header.Length - 1];

+  BootPromptPtr->Prompt[BootPromptPtr->Header.Length - 1] = 0;

+

+  AsciiPrint ("%a ", BootPromptPtr->Prompt);

+  BootPromptPtr->Prompt[BootPromptPtr->Header.Length - 1] = SaveChar;

+

+  //

+  // wait until time expires or selection made - menu or local

+  //

+  SecColumn = gST->ConOut->Mode->CursorColumn;

+  SecRow    = gST->ConOut->Mode->CursorRow;

+  SecsLeft  = BootPromptPtr->Timeout;

+

+  gST->ConOut->SetCursorPosition (gST->ConOut, SecColumn, SecRow);

+  AsciiPrint ("(%d) ", SecsLeft);

+  

+  //

+  // set the default action to be AUTO_SELECT

+  //

+  Status = AUTO_SELECT;

+

+  while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {

+    EFI_INPUT_KEY Key;

+

+    if (!EFI_ERROR (gBS->CheckEvent (SecondsEvent))) {

+      --SecsLeft;

+      gST->ConOut->SetCursorPosition (gST->ConOut, SecColumn, SecRow);

+      AsciiPrint ("(%d) ", SecsLeft);

+    }

+

+    if (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key) == EFI_NOT_READY) {

+      UINT8       Buffer[512];

+      UINTN       BufferSize;

+      EFI_STATUS  Status;

+

+      BufferSize = sizeof Buffer;

+

+      Status = Private->EfiBc.UdpRead (

+                                &Private->EfiBc,

+                                EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP |

+                                EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT |

+                                EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT,

+                                NULL, /* dest ip */

+                                NULL, /* dest port */

+                                NULL, /* src ip */

+                                NULL, /* src port */

+                                NULL, /* hdr size */

+                                NULL, /* hdr ptr */

+                                &BufferSize,

+                                Buffer

+                                );

+

+      continue;

+    }

+

+    if (Key.ScanCode == 0) {

+      switch (Key.UnicodeChar) {

+      case Ctl ('c'):

+        Status = LOCAL_BOOT;

+        break;

+

+      case Ctl ('m'):

+      case 'm':

+      case 'M':

+        Status = DO_MENU;

+        break;

+

+      default:

+        continue;

+      }

+    } else {

+      switch (Key.ScanCode) {

+      case SCAN_F8:

+        Status = DO_MENU;

+        break;

+

+      case SCAN_ESC:

+        Status = LOCAL_BOOT;

+        break;

+

+      default:

+        continue;

+      }

+    }

+

+    break;

+  }

+

+  gBS->CloseEvent (SecondsEvent);

+  gBS->CloseEvent (TimeoutEvent);

+

+  gST->ConOut->SetCursorPosition (gST->ConOut, SecColumn, SecRow);

+  AsciiPrint ("     ");

+

+  return Status;

+}

+

+STATIC

+VOID

+PrintMenuItem (

+  PXE_BOOT_MENU_ENTRY *MenuItemPtr

+  )

+/*++

+

+Routine Description:

+

+  Display one menu item.

+

+Arguments:

+

+  MenuItemPtr - Pointer to PXE menu item option.

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT8 Length;

+  UINT8 SaveChar;

+

+  Length                    = (UINT8) EFI_MIN (70, MenuItemPtr->DataLen);

+  SaveChar                  = MenuItemPtr->Data[Length];

+

+  MenuItemPtr->Data[Length] = 0;

+  AsciiPrint ("     %a\n", MenuItemPtr->Data);

+  MenuItemPtr->Data[Length] = SaveChar;

+}

+

+STATIC

+EFI_STATUS

+DoMenu (

+  PXE_BASECODE_DEVICE *Private,

+  DHCP_RECEIVE_BUFFER *RxBufferPtr

+  )

+/*++

+

+Routine Description:

+

+  Display and process menu.

+

+Arguments:

+

+  Private - Pointer to PxeBc interface

+  RxBufferPtr - Pointer to receive buffer

+

+Returns:

+

+  NO_MENU - 

+  LOCAL_BOOT - 

+  

+--*/

+{

+  PXE_OP_DISCOVERY_CONTROL  *DiscoveryControlPtr;

+  PXE_BOOT_MENU_ENTRY       *MenuItemPtrs[MAX_MENULIST];

+  EFI_STATUS                Status;

+  UNION_PTR                 Ptr;

+  UINTN                     SaveNumRte;

+  UINTN                     TopRow;

+  UINTN                     MenuLth;

+  UINTN                     NumMenuItems;

+  UINTN                     Index;

+  UINTN                     Longest;

+  UINTN                     Selected;

+  UINT16                    Type;

+  UINT16                    Layer;

+  BOOLEAN                   Done;

+

+  Selected  = 0;

+  Layer     = 0;

+

+  DEBUG ((EFI_D_WARN, "\nDoMenu()  Enter."));

+

+  /* see if we have a menu/prompt */

+  if (!(RxBufferPtr->OpAdds.Status & DISCOVER_TYPE)) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nDoMenu()  No menu/prompt info.  OpAdds.Status == %xh  ",

+      RxBufferPtr->OpAdds.Status)

+      );

+

+    return NO_MENU;

+  }

+

+  DiscoveryControlPtr = (PXE_OP_DISCOVERY_CONTROL *) RxBufferPtr->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1];

+

+  //

+  // if not USE_BOOTFILE or no bootfile given, must have menu stuff

+  //

+  if ((DiscoveryControlPtr->ControlBits & USE_BOOTFILE) && RxBufferPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {

+    DEBUG ((EFI_D_WARN, "\nDoMenu()  DHCP w/ bootfile.  "));

+    return NO_MENU;

+  }

+  //

+  // do prompt & menu if necessary

+  //

+  Status = DoPrompt (Private, (PXE_OP_BOOT_PROMPT *) RxBufferPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_PROMPT_IX - 1]);

+

+  if (Status == LOCAL_BOOT) {

+    DEBUG ((EFI_D_WARN, "\nDoMenu()  DoPrompt() returned LOCAL_BOOT.  "));

+

+    return Status;

+  }

+

+  Ptr.BytePtr             = (UINT8 *) RxBufferPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_MENU_IX - 1];

+

+  MenuLth                 = Ptr.MenuPtr->Header.Length;

+  Ptr.CurrentMenuItemPtr  = Ptr.MenuPtr->MenuItem;

+

+  //

+  // build menu items array

+  //

+  for (Longest = NumMenuItems = Index = 0; Index < MenuLth && NumMenuItems <= MAX_MENULIST;) {

+    UINTN lth;

+

+    lth = Ptr.CurrentMenuItemPtr->DataLen + sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data);

+

+    MenuItemPtrs[NumMenuItems++] = Ptr.CurrentMenuItemPtr;

+

+    if (lth > Longest) {

+      //

+      // check if too long

+      //

+      if ((Longest = lth) > 70 + (sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data))) {

+        Longest = 70 + (sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data));

+      }

+    }

+

+    Index += lth;

+    Ptr.BytePtr += lth;

+  }

+

+  if (Status != AUTO_SELECT) {

+    UINT8 BlankBuf[75];

+

+    SetMem (BlankBuf, sizeof BlankBuf, ' ');

+    BlankBuf[Longest + 5 - (sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data))] = 0;

+    AsciiPrint ("\n");

+

+    //

+    // now put up menu

+    //

+    for (Index = 0; Index < NumMenuItems; ++Index) {

+      PrintMenuItem (MenuItemPtrs[Index]);

+    }

+

+    TopRow = gST->ConOut->Mode->CursorRow - NumMenuItems;

+

+    //

+    // now wait for a selection

+    //

+    Done = FALSE;

+    do {

+      //

+      // highlight selection

+      //

+      EFI_INPUT_KEY Key;

+      UINTN         NewSelected;

+

+      NewSelected = Selected;

+

+      //

+      // highlight selected row

+      //

+      gST->ConOut->SetAttribute (

+                    gST->ConOut,

+                    EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)

+                    );

+      gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + Selected);

+

+      AsciiPrint (" --->%a\r", BlankBuf);

+

+      PrintMenuItem (MenuItemPtrs[Selected]);

+      gST->ConOut->SetAttribute (

+                    gST->ConOut,

+                    EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)

+                    );

+      gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + NumMenuItems);

+

+      //

+      // wait for a keystroke

+      //

+      while (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key) == EFI_NOT_READY) {

+        UINT8 TmpBuf[512];

+        UINTN TmpBufLen;

+

+        TmpBufLen = sizeof TmpBuf;

+

+        Private->EfiBc.UdpRead (

+                        &Private->EfiBc,

+                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP |

+                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT |

+                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT,

+                        NULL, /* dest ip */

+                        NULL, /* dest port */

+                        NULL, /* src ip */

+                        NULL, /* src port */

+                        NULL, /* hdr size */

+                        NULL, /* hdr ptr */

+                        &TmpBufLen,

+                        TmpBuf

+                        );

+      }

+

+      if (!Key.ScanCode) {

+        switch (Key.UnicodeChar) {

+        case Ctl ('c'):

+          Key.ScanCode = SCAN_ESC;

+          break;

+

+        case Ctl ('j'): /* linefeed */

+        case Ctl ('m'): /* return */

+          Done = TRUE;

+          break;

+

+        case Ctl ('i'): /* tab */

+        case ' ':

+        case 'd':

+        case 'D':

+          Key.ScanCode = SCAN_DOWN;

+          break;

+

+        case Ctl ('h'): /* backspace */

+        case 'u':

+        case 'U':

+          Key.ScanCode = SCAN_UP;

+          break;

+

+        default:

+          Key.ScanCode = 0;

+        }

+      }

+

+      switch (Key.ScanCode) {

+      case SCAN_LEFT:

+      case SCAN_UP:

+        if (NewSelected) {

+          --NewSelected;

+        }

+

+        break;

+

+      case SCAN_DOWN:

+      case SCAN_RIGHT:

+        if (++NewSelected == NumMenuItems) {

+          --NewSelected;

+        }

+

+        break;

+

+      case SCAN_PAGE_UP:

+      case SCAN_HOME:

+        NewSelected = 0;

+        break;

+

+      case SCAN_PAGE_DOWN:

+      case SCAN_END:

+        NewSelected = NumMenuItems - 1;

+        break;

+

+      case SCAN_ESC:

+        return LOCAL_BOOT;

+      }

+

+      /* unhighlight last selected row */

+      gST->ConOut->SetCursorPosition (gST->ConOut, 5, TopRow + Selected);

+

+      AsciiPrint ("%a\r", BlankBuf);

+

+      PrintMenuItem (MenuItemPtrs[Selected]);

+

+      Selected = NewSelected;

+    } while (!Done);

+  }

+

+  SaveNumRte  = Private->EfiBc.Mode->RouteTableEntries;

+

+  Type        = NTOHS (MenuItemPtrs[Selected]->Type);

+

+  if (Type == 0) {

+    DEBUG ((EFI_D_WARN, "\nDoMenu()  Local boot selected.  "));

+    return LOCAL_BOOT;

+  }

+

+  AsciiPrint ("Discover");

+

+  Status = Private->EfiBc.Discover (

+                            &Private->EfiBc,

+                            Type,

+                            &Layer,

+                            (BOOLEAN) (Private->EfiBc.Mode->BisSupported && Private->EfiBc.Mode->BisDetected),

+                            0

+                            );

+

+  if (EFI_ERROR (Status)) {

+    AsciiPrint ("\r                    \r");

+

+    DEBUG (

+      (EFI_D_WARN,

+      "\nDoMenu()  Return w/ %xh (%r).",

+      Status,

+      Status)

+      );

+

+    return Status;

+  }

+

+  AsciiPrint ("\rBOOT_SERVER_IP: ");

+  PrintIpv4 ((UINT8 *) &Private->ServerIp);

+

+  for (Index = SaveNumRte; Index < Private->EfiBc.Mode->RouteTableEntries; ++Index) {

+    if ((Index % 3) == 0) {

+      AsciiPrint ("\r\nGATEWAY IP:");

+    }

+

+    AsciiPrint (" ");

+    PrintIpv4 ((UINT8 *) &Private->EfiBc.Mode->RouteTable[Index].GwAddr);

+    AsciiPrint (" ");

+  }

+

+  AsciiPrint ("\n");

+

+  DEBUG ((EFI_D_WARN, "\nDoMenu()  Return w/ EFI_SUCCESS.  "));

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+UINT16

+GetValue (

+  DHCPV4_OP_STRUCT *OpPtr

+  )

+/*++

+

+Routine Description:

+

+  Get value 8- or 16-bit value from DHCP option.

+

+Arguments:

+

+  OpPtr - Pointer to DHCP option

+

+Returns:

+

+  Value from DHCP option

+  

+--*/

+{

+  if (OpPtr->Header.Length == 1) {

+    return OpPtr->Data[0];

+  } else {

+    return NTOHS (OpPtr->Data);

+  }

+}

+

+STATIC

+UINT8 *

+_PxeBcFindOpt (

+  UINT8 *BufferPtr,

+  UINTN BufferLen,

+  UINT8 OpCode

+  )

+/*++

+

+Routine Description:

+

+  Locate opcode in buffer.

+

+Arguments:

+

+  BufferPtr - Pointer to buffer

+  BufferLen - Length of buffer

+  OpCode - Option number

+

+Returns:

+

+  Pointer to opcode, may be NULL

+  

+--*/

+{

+  if (BufferPtr == NULL) {

+    return NULL;

+  }

+

+  while (BufferLen != 0) {

+    if (*BufferPtr == OpCode) {

+      return BufferPtr;

+    }

+

+    switch (*BufferPtr) {

+    case OP_END:

+      return NULL;

+

+    case OP_PAD:

+      ++BufferPtr;

+      --BufferLen;

+      continue;

+    }

+

+    if ((UINTN) BufferLen <= (UINTN) 2 + BufferPtr[1]) {

+      return NULL;

+    }

+

+    BufferLen -= 2 + BufferPtr[1];

+    BufferPtr += 2 + BufferPtr[1];

+  }

+

+  return NULL;

+}

+

+UINT8 *

+PxeBcFindDhcpOpt (

+  EFI_PXE_BASE_CODE_PACKET  *PacketPtr,

+  UINT8                     OpCode

+  )

+/*++

+

+Routine Description:

+

+  Find option in packet

+

+Arguments:

+

+  PacketPtr - Pointer to packet

+  OpCode - option number

+

+Returns:

+

+  Pointer to option in packet

+  

+--*/

+{

+  UINTN PacketLen;

+  UINT8 Overload;

+  UINT8 *OptionBufferPtr;

+

+  //

+  //

+  //

+  PacketLen = 380;

+  Overload  = 0;

+

+  //

+  // Figure size of DHCP option space.

+  //

+  OptionBufferPtr = _PxeBcFindOpt (

+                      PacketPtr->Dhcpv4.DhcpOptions,

+                      380,

+                      OP_DHCP_MAX_MESSAGE_SZ

+                      );

+

+  if (OptionBufferPtr != NULL) {

+    if (OptionBufferPtr[1] == 2) {

+      UINT16  n;

+

+      CopyMem (&n, &OptionBufferPtr[2], 2);

+      PacketLen = HTONS (n);

+

+      if (PacketLen < sizeof (EFI_PXE_BASE_CODE_DHCPV4_PACKET)) {

+        PacketLen = 380;

+      } else {

+        PacketLen -= (PacketPtr->Dhcpv4.DhcpOptions - &PacketPtr->Dhcpv4.BootpOpcode) + 28;

+      }

+    }

+  }

+  //

+  // Look for option overloading.

+  //

+  OptionBufferPtr = _PxeBcFindOpt (

+                      PacketPtr->Dhcpv4.DhcpOptions,

+                      PacketLen,

+                      OP_DHCP_OPTION_OVERLOAD

+                      );

+

+  if (OptionBufferPtr != NULL) {

+    if (OptionBufferPtr[1] == 1) {

+      Overload = OptionBufferPtr[2];

+    }

+  }

+  //

+  // Look for caller's option.

+  //

+  OptionBufferPtr = _PxeBcFindOpt (

+                      PacketPtr->Dhcpv4.DhcpOptions,

+                      PacketLen,

+                      OpCode

+                      );

+

+  if (OptionBufferPtr != NULL) {

+    return OptionBufferPtr;

+  }

+

+  if (Overload & OVLD_FILE) {

+    OptionBufferPtr = _PxeBcFindOpt (PacketPtr->Dhcpv4.BootpBootFile, 128, OpCode);

+

+    if (OptionBufferPtr != NULL) {

+      return OptionBufferPtr;

+    }

+  }

+

+  if (Overload & OVLD_SRVR_NAME) {

+    OptionBufferPtr = _PxeBcFindOpt (PacketPtr->Dhcpv4.BootpSrvName, 64, OpCode);

+

+    if (OptionBufferPtr != NULL) {

+      return OptionBufferPtr;

+    }

+  }

+

+  return NULL;

+}

+

+STATIC

+EFI_STATUS

+DownloadFile (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN OUT UINT64           *BufferSize,

+  IN VOID                 *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Download file into buffer

+

+Arguments:

+

+  Private - Pointer to PxeBc interface

+  BufferSize - pointer to size of download buffer

+  Buffer - Pointer to buffer

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL -

+  EFI_NOT_FOUND -

+  EFI_PROTOCOL_ERROR -

+

+--*/

+{

+  EFI_PXE_BASE_CODE_MTFTP_INFO  MtftpInfo;

+  EFI_PXE_BASE_CODE_TFTP_OPCODE OpCode;

+  DHCP_RECEIVE_BUFFER           *RxBuf;

+  EFI_STATUS                    Status;

+  UINTN                         BlockSize;

+

+  RxBuf     = (DHCP_RECEIVE_BUFFER *) Private->BootServerReceiveBuffer;

+  BlockSize = 0x8000;

+

+  DEBUG ((EFI_D_WARN, "\nDownloadFile()  Enter."));

+

+  if (Buffer == NULL || *BufferSize == 0 || *BufferSize < Private->FileSize) {

+    if (Private->FileSize != 0) {

+      *BufferSize = Private->FileSize;

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    AsciiPrint ("\nTSize");

+

+    OpCode = EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE;

+  } else if (RxBuf->OpAdds.Status & WfM11a_TYPE) {

+    OpCode = EFI_PXE_BASE_CODE_MTFTP_READ_FILE;

+

+    ZeroMem (&MtftpInfo, sizeof MtftpInfo);

+

+    *(IPV4_ADDR *) &MtftpInfo.MCastIp = *(IPV4_ADDR *) RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_IP - 1]->Data;

+

+    CopyMem (

+      &MtftpInfo.CPort,

+      RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_CPORT - 1]->Data,

+      sizeof MtftpInfo.CPort

+      );

+

+    CopyMem (

+      &MtftpInfo.SPort,

+      RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_SPORT - 1]->Data,

+      sizeof MtftpInfo.SPort

+      );

+

+    MtftpInfo.ListenTimeout   = GetValue (RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_TMOUT - 1]);

+

+    MtftpInfo.TransmitTimeout = GetValue (RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_DELAY - 1]);

+

+    AsciiPrint ("\nMTFTP");

+  } else {

+    AsciiPrint ("\nTFTP");

+

+    OpCode = EFI_PXE_BASE_CODE_TFTP_READ_FILE;

+  }

+

+  Private->FileSize = 0;

+

+  RxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Data[RxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Header.Length] = 0;

+

+  Status = Private->EfiBc.Mtftp (

+                            &Private->EfiBc,

+                            OpCode,

+                            Buffer,

+                            FALSE,

+                            BufferSize,

+                            &BlockSize,

+                            &Private->ServerIp,

+                            (UINT8 *) RxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Data,

+                            &MtftpInfo,

+                            FALSE

+                            );

+

+  if (Status != EFI_SUCCESS && Status != EFI_BUFFER_TOO_SMALL) {

+    DEBUG ((EFI_D_WARN, "\nDownloadFile()  Exit #1 %Xh", Status));

+    return Status;

+  }

+

+  if (sizeof (UINTN) < sizeof (UINT64) && *BufferSize > 0xFFFFFFFF) {

+    Private->FileSize = 0xFFFFFFFF;

+  } else {

+    Private->FileSize = (UINTN) *BufferSize;

+  }

+

+  if (OpCode == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE) {

+    DEBUG ((EFI_D_WARN, "\nDownloadFile()  Exit #2"));

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_WARN, "\nDownloadFile()  Exit #3 %Xh", Status));

+    return Status;

+  }

+

+  if (Private->EfiBc.Mode->BisSupported && Private->EfiBc.Mode->BisDetected && Private->EfiBc.Mode->PxeBisReplyReceived) {

+    UINT64  CredentialLen;

+    UINTN   BlockSize;

+    UINT8   CredentialFilename[256];

+    UINT8   *op;

+    VOID    *CredentialBuffer;

+

+    //

+    // Get name of credential file.  It may be in the BOOTP

+    // bootfile field or a DHCP option.

+    //

+    ZeroMem (CredentialFilename, sizeof CredentialFilename);

+

+    op = PxeBcFindDhcpOpt (&Private->EfiBc.Mode->PxeBisReply, OP_DHCP_BOOTFILE);

+

+    if (op != NULL) {

+      if (op[1] == 0) {

+        /* No credential filename */

+        return EFI_NOT_FOUND;

+      }

+

+      CopyMem (CredentialFilename, &op[2], op[1]);

+    } else {

+      if (Private->EfiBc.Mode->PxeBisReply.Dhcpv4.BootpBootFile[0] == 0) {

+        /* No credential filename */

+        return EFI_NOT_FOUND;

+      }

+

+      CopyMem (CredentialFilename, &op[2], 128);

+    }

+    //

+    // Get size of credential file.  It may be available as a

+    // DHCP option.  If not, use the TFTP get file size.

+    //

+    CredentialLen = 0;

+

+    op            = PxeBcFindDhcpOpt (&Private->EfiBc.Mode->PxeBisReply, OP_BOOT_FILE_SZ);

+

+    if (op != NULL) {

+      /*

+       * This is actually the size of the credential file

+       * buffer.  The actual credential file size will be

+       * returned when we download the file.

+       */

+      if (op[1] == 2) {

+        UINT16  n;

+

+        CopyMem (&n, &op[2], 2);

+        CredentialLen = HTONS (n) * 512;

+      }

+    }

+

+    if (CredentialLen == 0) {

+      BlockSize = 8192;

+

+      Status = Private->EfiBc.Mtftp (

+                                &Private->EfiBc,

+                                EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,

+                                NULL,

+                                FALSE,

+                                &CredentialLen,

+                                &BlockSize,

+                                &Private->ServerIp,

+                                CredentialFilename,

+                                NULL,

+                                FALSE

+                                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      if (CredentialLen == 0) {

+        //

+        // %%TBD -- EFI error for invalid credential

+        // file.

+        //

+        return EFI_PROTOCOL_ERROR;

+      }

+    }

+    //

+    // Allocate credential file buffer.

+    //

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    (UINTN) CredentialLen,

+                    &CredentialBuffer

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Download credential file.

+    //

+    BlockSize = 8192;

+

+    Status = Private->EfiBc.Mtftp (

+                              &Private->EfiBc,

+                              EFI_PXE_BASE_CODE_TFTP_READ_FILE,

+                              CredentialBuffer,

+                              FALSE,

+                              &CredentialLen,

+                              &BlockSize,

+                              &Private->ServerIp,

+                              CredentialFilename,

+                              NULL,

+                              FALSE

+                              );

+

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (CredentialBuffer);

+      return Status;

+    }

+    //

+    // Verify credentials.

+    //

+    if (PxebcBisVerify (Private, Buffer, Private->FileSize, CredentialBuffer, (UINTN) CredentialLen)) {

+      Status = EFI_SUCCESS;

+    } else {

+      //

+      // %%TBD -- An EFI error code for failing credential verification.

+      //

+      Status = EFI_PROTOCOL_ERROR;

+    }

+

+    gBS->FreePool (CredentialBuffer);

+  }

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+LoadfileStart (

+  IN PXE_BASECODE_DEVICE  *Private,

+  IN OUT UINT64           *BufferSize,

+  IN VOID                 *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Start PXE DHCP.  Get DHCP and proxyDHCP information.

+  Display remote boot menu and prompt.  Select item from menu.

+

+Arguments:

+

+  Private - Pointer to PxeBc interface

+  BufferSize - Pointer to download buffer size

+  Buffer - Pointer to download buffer

+

+Returns:

+

+  EFI_SUCCESS - 

+  EFI_NOT_READY - 

+  

+--*/

+{

+  EFI_PXE_BASE_CODE_MODE      *PxeBcMode;

+  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;

+  EFI_SIMPLE_NETWORK_MODE     *SnpMode;

+  EFI_STATUS                  Status;

+  VOID                        *RxBuf;

+

+  DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Enter."));

+

+  //

+  // Try to start BaseCode, for now only IPv4 is supported

+  // so don't try to start using IPv6.

+  //

+  Status = Private->EfiBc.Start (&Private->EfiBc, FALSE);

+

+  if (EFI_ERROR (Status)) {

+    if (Status != EFI_ALREADY_STARTED) {

+      DEBUG ((EFI_D_NET, "\nLoadfileStart()  Exit  BC.Start() == %xh", Status));

+      return Status;

+    }

+  }

+  //

+  // Get pointers to PXE mode structure, SNP protocol structure

+  // and SNP mode structure.

+  //

+  PxeBcMode = Private->EfiBc.Mode;

+  Snp       = Private->SimpleNetwork;

+  SnpMode   = Snp->Mode;

+

+  //

+  // Display client MAC address, like 16-bit PXE ROMs

+  //

+  AsciiPrint ("\nCLIENT MAC ADDR: ");

+

+  {

+    UINTN Index;

+    UINTN hlen;

+

+    hlen = SnpMode->HwAddressSize;

+

+    for (Index = 0; Index < hlen; ++Index) {

+      AsciiPrint ("%02x ", SnpMode->CurrentAddress.Addr[Index]);

+    }

+  }

+

+  AsciiPrint ("\nDHCP");

+

+  Status = Private->EfiBc.Dhcp (&Private->EfiBc, TRUE);

+

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Exit  BC.Dhcp() == %Xh", Status));

+    AsciiPrint ("\r               \r");

+    return Status;

+  }

+

+  ShowMyInfo (Private);

+

+  RxBuf = PxeBcMode->ProxyOfferReceived ? &PXE_OFFER_BUFFER : &DHCPV4_ACK_BUFFER;

+#define RxBufferPtr ((DHCP_RECEIVE_BUFFER *) RxBuf)

+

+  Status = DoMenu (Private, RxBufferPtr);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // did a discovery - take info from discovery packet

+    //

+    RxBuf = &PXE_ACK_BUFFER;

+  } else if (Status == NO_MENU) {

+    //

+    // did not do a discovery - take info from rxbuf

+    //

+    Private->ServerIp.Addr[0] = RxBufferPtr->u.Dhcpv4.siaddr;

+

+    if (!(Private->ServerIp.Addr[0])) {

+      *(IPV4_ADDR *) &Private->ServerIp = *(IPV4_ADDR *) RxBufferPtr->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1]->Data;

+    }

+  } else {

+    DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Exit  DoMenu() == %Xh", Status));

+    return Status;

+  }

+

+  if (!RxBufferPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {

+    DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Exit  Not ready?"));

+    return EFI_NOT_READY;

+  }

+  //

+  // check for file size option sent

+  //

+  if (RxBufferPtr->OpAdds.PktOptAdds[OP_BOOT_FILE_SZ_IX - 1]) {

+    Private->FileSize = 512 * NTOHS (RxBufferPtr->OpAdds.PktOptAdds[OP_BOOT_FILE_SZ_IX - 1]->Data);

+  }

+

+  Private->BootServerReceiveBuffer  = RxBufferPtr;

+

+  Status = DownloadFile (Private, BufferSize, Buffer);

+

+  DEBUG (

+    (EFI_D_WARN,

+    "\nLoadfileStart()  Exit.  DownloadFile() = %Xh",

+    Status)

+    );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+LoadFile (

+  IN EFI_LOAD_FILE_PROTOCOL           *This,

+  IN EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN BOOLEAN                          BootPolicy,

+  IN OUT UINTN                        *BufferSize,

+  IN OUT VOID                         *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Loadfile interface for PxeBc interface

+

+Arguments:

+

+  This -  Pointer to Loadfile interface

+  FilePath - Not used and not checked

+  BootPolicy - Must be TRUE

+  BufferSize - Pointer to buffer size 

+  Buffer - Pointer to download buffer or NULL

+

+Returns:

+

+  EFI_INVALID_PARAMETER -

+  EFI_UNSUPPORTED -

+  EFI_SUCCESS -

+  EFI_BUFFER_TOO_SMALL -

+

+--*/

+{

+  LOADFILE_DEVICE *LoadfilePtr;

+  UINT64          TmpBufSz;

+  INT32           OrigMode;

+  INT32           OrigAttribute;

+  BOOLEAN         RemoveCallback;

+  BOOLEAN         NewMakeCallback;

+  EFI_STATUS      Status;

+  EFI_STATUS      TempStatus;

+  //

+  //

+  //

+  OrigMode        = gST->ConOut->Mode->Mode;

+  OrigAttribute   = gST->ConOut->Mode->Attribute;

+  RemoveCallback  = FALSE;

+

+  AsciiPrint ("Running LoadFile()\n");

+

+  //

+  // Resolve Warning 4 unreferenced parameter problem

+  //

+  FilePath = NULL;

+

+  //

+  // If either if these parameters are NULL, we cannot continue.

+  //

+  if (This == NULL || BufferSize == NULL) {

+    DEBUG ((EFI_D_WARN, "\nLoadFile()  This or BufferSize == NULL"));

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // We only support BootPolicy == TRUE

+  //

+  if (!BootPolicy) {

+    DEBUG ((EFI_D_WARN, "\nLoadFile()  BootPolicy == FALSE"));

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get pointer to LoadFile protocol structure.

+  //

+  LoadfilePtr = CR (This, LOADFILE_DEVICE, LoadFile, LOADFILE_DEVICE_SIGNATURE);

+

+  if (LoadfilePtr == NULL) {

+    DEBUG (

+      (EFI_D_NET,

+      "\nLoadFile()  Could not get pointer to LoadFile structure")

+      );

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Lock interface

+  //

+  EfiAcquireLock (&LoadfilePtr->Lock);

+

+  //

+  // Set console output mode and display attribute

+  //

+  if (OrigMode != 0) {

+    gST->ConOut->SetMode (gST->ConOut, 0);

+  }

+

+  gST->ConOut->SetAttribute (

+                gST->ConOut,

+                EFI_TEXT_ATTR (EFI_LIGHTGRAY,EFI_BLACK)

+                );

+

+  //

+  // See if BaseCode already has a Callback protocol attached.

+  // If there is none, attach our own Callback protocol.

+  //

+  Status = gBS->HandleProtocol (

+                  LoadfilePtr->Private->Handle,

+                  &gEfiPxeBaseCodeCallbackProtocolGuid,

+                  (VOID *) &LoadfilePtr->Private->CallbackProtocolPtr

+                  );

+

+  switch (Status) {

+  case EFI_SUCCESS:

+    //

+    // There is already a callback routine.  Do nothing.

+    //

+    DEBUG ((EFI_D_WARN, "\nLoadFile()  BC callback exists."));

+    break;

+

+  case EFI_UNSUPPORTED:

+    //

+    // No BaseCode Callback protocol found.  Add our own.

+    //

+    Status = gBS->InstallProtocolInterface (

+                    &LoadfilePtr->Private->Handle,

+                    &gEfiPxeBaseCodeCallbackProtocolGuid,

+                    EFI_NATIVE_INTERFACE,

+                    &_bc_callback

+                    );

+

+    DEBUG ((EFI_D_WARN, "\nLoadFile()  Callback install status == %xh", Status));

+

+    RemoveCallback = (BOOLEAN) (Status == EFI_SUCCESS);

+

+    if (LoadfilePtr->Private->EfiBc.Mode != NULL && LoadfilePtr->Private->EfiBc.Mode->Started) {

+      NewMakeCallback = TRUE;

+      LoadfilePtr->Private->EfiBc.SetParameters (

+                                    &LoadfilePtr->Private->EfiBc,

+                                    NULL,

+                                    NULL,

+                                    NULL,

+                                    NULL,

+                                    &NewMakeCallback

+                                    );

+    }

+

+    break;

+

+  default:

+    DEBUG ((EFI_D_WARN, "\nLoadFile()  Callback check status == %xh", Status));

+  }

+  //

+  // Check for starting or for continuing after already getting

+  // the file size.

+  //

+  if (LoadfilePtr->Private->FileSize == 0) {

+    TmpBufSz  = 0;

+    Status    = LoadfileStart (LoadfilePtr->Private, &TmpBufSz, Buffer);

+

+    if (sizeof (UINTN) < sizeof (UINT64) && TmpBufSz > 0xFFFFFFFF) {

+      *BufferSize = 0xFFFFFFFF;

+    } else {

+      *BufferSize = (UINTN) TmpBufSz;

+    }

+

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      //

+      // This is done so loadfile will work even if the boot manager

+      // did not make the first call with Buffer == NULL.

+      //

+      Buffer = NULL;

+    }

+  } else if (Buffer == NULL) {

+    DEBUG ((EFI_D_WARN, "\nLoadfile()  Get buffer size"));

+

+    //

+    // Continuing from previous LoadFile request.  Make sure there

+    // is a buffer and that it is big enough.

+    //

+    *BufferSize = LoadfilePtr->Private->FileSize;

+    Status      = EFI_BUFFER_TOO_SMALL;

+  } else {

+    DEBUG ((EFI_D_WARN, "\nLoadFile()  Download file"));

+

+    //

+    // Everything looks good, try to download the file.

+    //

+    TmpBufSz  = *BufferSize;

+    Status    = DownloadFile (LoadfilePtr->Private, &TmpBufSz, Buffer);

+

+    //

+    // Next call to loadfile will start DHCP process again.

+    //

+    LoadfilePtr->Private->FileSize = 0;

+  }

+  //

+  // If we added a callback protocol, now is the time to remove it.

+  //

+  if (RemoveCallback) {

+    NewMakeCallback = FALSE;

+    TempStatus = LoadfilePtr->Private->EfiBc.SetParameters (

+                                          &LoadfilePtr->Private->EfiBc,

+                                          NULL,

+                                          NULL,

+                                          NULL,

+                                          NULL,

+                                          &NewMakeCallback

+                                          );

+

+    if (TempStatus == EFI_SUCCESS) {

+      gBS->UninstallProtocolInterface (

+            LoadfilePtr->Private->Handle,

+            &gEfiPxeBaseCodeCallbackProtocolGuid,

+            &_bc_callback

+            );

+    }

+  }

+  //

+  // Restore display mode and attribute

+  //

+  if (OrigMode != 0) {

+    gST->ConOut->SetMode (gST->ConOut, OrigMode);

+  }

+

+  gST->ConOut->SetAttribute (gST->ConOut, OrigAttribute);

+

+  //

+  // Unlock interface

+  //

+  EfiReleaseLock (&LoadfilePtr->Lock);

+

+  DEBUG ((EFI_D_WARN, "\nBC.Loadfile()  Status == %xh\n", Status));

+

+  switch (Status) {

+  case EFI_SUCCESS:           /* 0 */

+    return EFI_SUCCESS;

+

+  case EFI_BUFFER_TOO_SMALL:  /* 5 */

+    //

+    // Error is only displayed when we are actually trying to

+    // download the boot image.

+    //

+    if (Buffer == NULL) {

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    AsciiPrint ("\nPXE-E05: Download buffer is smaller than requested file.\n");

+    break;

+

+  case EFI_DEVICE_ERROR:      /* 7 */

+    AsciiPrint ("\nPXE-E07: Network device error.  Check network connection.\n");

+    break;

+

+  case EFI_OUT_OF_RESOURCES:  /* 9 */

+    AsciiPrint ("\nPXE-E09: Could not allocate I/O buffers.\n");

+    break;

+

+  case EFI_NO_MEDIA:          /* 12 */

+    AsciiPrint ("\nPXE-E12: Could not detect network connection.  Check cable.\n");

+    break;

+

+  case EFI_NO_RESPONSE:       /* 16 */

+    AsciiPrint ("\nPXE-E16: Valid PXE offer not received.\n");

+    break;

+

+  case EFI_TIMEOUT:           /* 18 */

+    AsciiPrint ("\nPXE-E18: Timeout.  Server did not respond.\n");

+    break;

+

+  case EFI_ABORTED:           /* 21 */

+    AsciiPrint ("\nPXE-E21: Remote boot cancelled.\n");

+    break;

+

+  case EFI_ICMP_ERROR:        /* 22 */

+    AsciiPrint ("\nPXE-E22: Client received ICMP error from server.\n");

+

+    if (LoadfilePtr->Private->EfiBc.Mode == NULL) {

+      break;

+    }

+

+    if (!LoadfilePtr->Private->EfiBc.Mode->IcmpErrorReceived) {

+      break;

+    }

+

+    AsciiPrint (

+      "PXE-E98: Type: %xh  Code: %xh  ",

+      LoadfilePtr->Private->EfiBc.Mode->IcmpError.Type,

+      LoadfilePtr->Private->EfiBc.Mode->IcmpError.Code

+      );

+

+    switch (LoadfilePtr->Private->EfiBc.Mode->IcmpError.Type) {

+    case 0x03:

+      switch (LoadfilePtr->Private->EfiBc.Mode->IcmpError.Code) {

+      case 0x00:              /* net unreachable */

+        AsciiPrint ("Net unreachable");

+        break;

+

+      case 0x01:              /* host unreachable */

+        AsciiPrint ("Host unreachable");

+        break;

+

+      case 0x02:              /* protocol unreachable */

+        AsciiPrint ("Protocol unreachable");

+        break;

+

+      case 0x03:              /* port unreachable */

+        AsciiPrint ("Port unreachable");

+        break;

+

+      case 0x04:              /* Fragmentation needed */

+        AsciiPrint ("Fragmentation needed");

+        break;

+

+      case 0x05:              /* Source route failed */

+        AsciiPrint ("Source route failed");

+        break;

+      }

+

+      break;

+    }

+

+    AsciiPrint ("\n");

+

+    break;

+

+  case EFI_TFTP_ERROR:        /* 23 */

+    AsciiPrint ("\nPXE-E23: Client received TFTP error from server.\n");

+

+    if (LoadfilePtr->Private->EfiBc.Mode == NULL) {

+      break;

+    }

+

+    if (LoadfilePtr->Private->EfiBc.Mode->TftpErrorReceived) {

+      AsciiPrint (

+        "PXE-E98: Code: %xh  %a\n",

+        LoadfilePtr->Private->EfiBc.Mode->TftpError.ErrorCode,

+        LoadfilePtr->Private->EfiBc.Mode->TftpError.ErrorString

+        );

+    }

+

+    break;

+

+  default:

+    AsciiPrint ("\nPXE-E99: Unexpected network error: %xh\n", Status);

+  }

+

+  LoadfilePtr->Private->EfiBc.Stop (&LoadfilePtr->Private->EfiBc);

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/tftp.h b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/tftp.h
new file mode 100644
index 0000000..3cc0724
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeBc/Dxe/tftp.h
@@ -0,0 +1,153 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  tftp.h

+

+Abstract:

+

+--*/

+

+#ifndef __TFTP_H__

+#define __TFTP_H__

+

+//

+// Definitions for trivial file transfer protocol functionality with IP v4

+// Per RFC 1350, July 1992 and RFC 2347, 8, and 9, May 1998

+//

+#pragma pack(1)

+//

+// max and min packet sizes

+// (all data packets in transmission except last)

+//

+#define MAX_TFTP_PKT_SIZE (BUFFER_ALLOCATE_SIZE - 512)

+#define MIN_TFTP_PKT_SIZE 512

+

+//

+// TFTPv4 OpCodes

+//

+#define TFTP_RRQ    1 // read request

+#define TFTP_WRQ    2 // write request

+#define TFTP_DATA   3 // data

+#define TFTP_ACK    4 // acknowledgement

+#define TFTP_ERROR  5 // error packet

+#define TFTP_OACK   6 // option acknowledge

+#define TFTP_DIR    7 // read directory request

+#define TFTP_DATA8  8

+#define TFTP_ACK8   9

+

+//

+// request packet (read or write)

+// Fields shown (except file name) are not to be referenced directly,

+// since their placement is variable within a request packet.

+// All are null terminated case insensitive ascii strings.

+//

+struct Tftpv4Req {

+  UINT16  OpCode;       // TFTP Op code

+  UINT8   FileName[2];  // file name

+  UINT8   Mode[2];      // "netascii" or "octet"

+  struct {              // optionally, one or more option requests

+    UINT8 Option[2];    // option name

+    UINT8 Value[2];     // value requested

+  } OpReq[1];

+};

+

+//

+// modes

+//

+#define MODE_ASCII  "netascii"

+#define MODE_BINARY "octet"

+

+//

+// option strings

+//

+#define OP_BLKSIZE    "blksize"   // block size option

+#define OP_TIMEOUT    "timeout"   // time to wait before retransmitting

+#define OP_TFRSIZE    "tsize"     // total transfer size option

+#define OP_OVERWRITE  "overwrite" // overwrite file option

+#define OP_BIGBLKNUM  "bigblk#"   // big block number

+// See RFC 2347, 8, and 9 for more information on TFTP options

+// option acknowledge packet (optional)

+// options not acknowledged are rejected

+//

+struct Tftpv4Oack {

+  UINT16  OpCode;     // TFTP Op code

+  struct {            // optionally, one or more option acknowledgements

+    UINT8 Option[2];  // option name (of those requested)

+    UINT8 Value[2];   // value acknowledged

+  } OpAck[1];

+};

+

+//

+// acknowledge packet

+//

+struct Tftpv4Ack {

+  UINT16  OpCode; // TFTP Op code

+  UINT16  BlockNum;

+};

+

+//

+// data packet

+//

+struct Tftpv4Data {

+  struct Tftpv4Ack  Header;

+  UINT8             Data[512];

+};

+

+//

+// big block number ack packet

+//

+struct Tftpv4Ack8 {

+  UINT16  OpCode;

+  UINT64  BlockNum;

+};

+

+//

+// big block number data packet

+//

+struct Tftpv4Data8 {

+  struct Tftpv4Ack8 Header;

+  UINT8             Data[506];

+};

+

+//

+// error packet

+//

+struct Tftpv4Error {

+  UINT16  OpCode;     // TFTP Op code

+  UINT16  ErrCode;    // error code

+  UINT8   ErrMsg[1];  // error message (nul terminated)

+};

+

+#pragma pack()

+//

+// error codes

+//

+#define TFTP_ERR_UNDEF      0 //     Not defined, see error message (if any).

+#define TFTP_ERR_NOT_FOUND  1 //     File not found.

+#define TFTP_ERR_ACCESS     2 //     Access violation.

+#define TFTP_ERR_FULL       3 //     Disk full or allocation exceeded.

+#define TFTP_ERR_ILLEGAL    4 //     Illegal TFTP operation.

+#define TFTP_ERR_BAD_ID     5 //     Unknown transfer ID.

+#define TFTP_ERR_EXISTS     6 //     File already exists.

+#define TFTP_ERR_NO_USER    7 //     No such user.

+#define TFTP_ERR_OPTION     8 //     Option negotiation termination

+//

+// some defines

+//

+#define REQ_RESP_TIMEOUT        5 // Wait five seconds for request response.

+#define ACK_TIMEOUT             4 // Wait four seconds for ack response.

+#define NUM_ACK_RETRIES         3

+#define NUM_MTFTP_OPEN_RETRIES  3

+

+#endif /* __TFTP_H__ */

+

+/* EOF - tftp.h */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/ComponentName.c
new file mode 100644
index 0000000..b48b5d0
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/ComponentName.c
@@ -0,0 +1,169 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  ComponentName.c

+

+Abstract:

+  PxeDhcp4 component name protocol declarations

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+PxeDhcp4ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+PxeDhcp4ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gPxeDhcp4ComponentName = {

+  PxeDhcp4ComponentNameGetDriverName,

+  PxeDhcp4ComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mPxeDhcp4DriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"PXE DHCPv4 Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gPxeDhcp4ComponentName.SupportedLanguages,

+          mPxeDhcp4DriverNameTable,

+          DriverName

+          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+/* EOF - ComponentName.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.mbd b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.mbd
new file mode 100644
index 0000000..090884a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Dhcp4</BaseName>

+    <Guid>a46c3330-be36-4977-9d24-a7cf92eef0fe</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.msa b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.msa
new file mode 100644
index 0000000..f34c858
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.msa
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Dhcp4</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>a46c3330-be36-4977-9d24-a7cf92eef0fe</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ComponentName.c</Filename>

+    <Filename>PxeDhcp4.c</Filename>

+    <Filename>PxeDhcp4.h</Filename>

+    <Filename>PxeDhcp4InitSelect.c</Filename>

+    <Filename>PxeDhcp4Release.c</Filename>

+    <Filename>PxeDhcp4RenewRebind.c</Filename>

+    <Filename>PxeDhcp4Run.c</Filename>

+    <Filename>PxeDhcp4Setup.c</Filename>

+    <Filename>support.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">PxeDhcp4Callback</Protocol>

+    <Protocol Usage="BY_START">PxeDhcp4</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleNetwork</Protocol>

+    <Protocol Usage="TO_START">PxeBaseCode</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+      <ModuleUnloadImage></ModuleUnloadImage>

+    </Extern>

+    <Extern>

+      <DriverBinding>gPxeDhcp4DriverBinding</DriverBinding>

+      <ComponentName>gPxeDhcp4ComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.c
new file mode 100644
index 0000000..57a44a0
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.c
@@ -0,0 +1,342 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4.c

+  

+Abstract:

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// Prototypes

+// Driver model protocol interface

+//

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// PXE DHCP Protocol Interface

+//

+EFI_DRIVER_BINDING_PROTOCOL gPxeDhcp4DriverBinding = {

+  PxeDhcp4DriverBindingSupported,

+  PxeDhcp4DriverBindingStart,

+  PxeDhcp4DriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  * This,

+  IN EFI_HANDLE                   ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports ControllerHandle.  Any

+    ControllerHandle that contains a PxeBaseCode protocol can be

+    supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to test.

+    RemainingDevicePath - Not used.

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_ALREADY_STARTED - This driver is already running on this

+          device.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiPxeBaseCodeProtocolGuid,

+                  (VOID **) &PxeBc,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test.

+  //

+  return gBS->CloseProtocol (

+                ControllerHandle,

+                &gEfiPxeBaseCodeProtocolGuid,

+                This->DriverBindingHandle,

+                ControllerHandle

+                );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  * This,

+  IN EFI_HANDLE                   ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Start this driver on ControllerHandle by opening a PxeBaseCode

+    protocol and installing a PxeDhcp4 protocol on ControllerHandle.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    ControllerHandle    - Handle of device to bind driver to.

+    RemainingDevicePath - Not used, always produce all possible

+          children.

+

+  Returns:

+    EFI_SUCCESS         - This driver is added to ControllerHandle.

+    EFI_ALREADY_STARTED - This driver is already running on

+          ControllerHandle.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;

+  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;

+  PXE_DHCP4_PRIVATE_DATA      *Private;

+

+  //

+  // Connect to the PxeBaseCode interface on ControllerHandle.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiPxeBaseCodeProtocolGuid,

+                  (VOID **) &PxeBc,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // BaseCode has already grabbed the SimpleNetwork interface

+  // so just do a HandleProtocol() to get it.

+  //

+  Status = gBS->HandleProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleNetworkProtocolGuid,

+                  (VOID **) &Snp

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto error_exit;

+  }

+

+  ASSERT (Snp);

+

+  //

+  // Initialize the PXE DHCP device instance.

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (PXE_DHCP4_PRIVATE_DATA),

+                  (VOID **) &Private

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto error_exit;

+  }

+  //

+  //

+  //

+  ZeroMem (Private, sizeof (PXE_DHCP4_PRIVATE_DATA));

+

+  Private->Signature          = PXE_DHCP4_PRIVATE_DATA_SIGNATURE;

+  Private->PxeBc              = PxeBc;

+  Private->Snp                = Snp;

+  Private->Handle             = ControllerHandle;

+  Private->PxeDhcp4.Revision  = EFI_PXE_DHCP4_PROTOCOL_REVISION;

+  Private->PxeDhcp4.Run       = PxeDhcp4Run;

+  Private->PxeDhcp4.Setup     = PxeDhcp4Setup;

+  Private->PxeDhcp4.Init      = PxeDhcp4Init;

+  Private->PxeDhcp4.Select    = PxeDhcp4Select;

+  Private->PxeDhcp4.Renew     = PxeDhcp4Renew;

+  Private->PxeDhcp4.Rebind    = PxeDhcp4Rebind;

+  Private->PxeDhcp4.Release   = PxeDhcp4Release;

+  Private->PxeDhcp4.Data      = NULL;

+

+  //

+  // Install protocol interfaces for the PXE DHCP device.

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &ControllerHandle,

+                  &gEfiPxeDhcp4ProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &Private->PxeDhcp4

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    return Status;

+  }

+

+error_exit: ;

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiPxeBaseCodeProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return Status;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4DriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     ControllerHandle,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+  Routine Description:

+    Stop this driver on ControllerHandle by removing PXE DHCP

+    protocol and closing the PXE Base Code protocol on

+    ControllerHandle.

+

+  Arguments:

+    This              - Protocol instance pointer.

+    ControllerHandle  - Handle of device to stop driver on.

+    NumberOfChildren  - Not used.

+    ChildHandleBuffer - Not used.

+

+  Returns:

+    EFI_SUCCESS         - This driver is removed ControllerHandle.

+    other               - This driver was not removed from this

+          device.

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_PXE_DHCP4_PROTOCOL  *PxeDhcp4;

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiPxeDhcp4ProtocolGuid,

+                  (VOID **) &PxeDhcp4,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (PxeDhcp4);

+

+  //

+  // Release allocated resources

+  //

+  if (Private->PxeDhcp4.Data) {

+    gBS->FreePool (Private->PxeDhcp4.Data);

+    Private->PxeDhcp4.Data = NULL;

+  }

+  //

+  // Uninstall our protocol

+  //

+  Status = gBS->UninstallProtocolInterface (

+                  ControllerHandle,

+                  &gEfiPxeDhcp4ProtocolGuid,

+                  &Private->PxeDhcp4

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Close any consumed protocols

+  //

+  Status = gBS->CloseProtocol (

+                  ControllerHandle,

+                  &gEfiPxeBaseCodeProtocolGuid,

+                  This->DriverBindingHandle,

+                  ControllerHandle

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Release our private data

+  //

+  gBS->FreePool (Private);

+

+  return Status;

+}

+

+/* EOF - PxeDhcp4.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.h b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.h
new file mode 100644
index 0000000..136d392
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.h
@@ -0,0 +1,307 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4.h

+

+Abstract:

+  Common header for PxeDhcp4 protocol driver

+

+--*/

+#ifndef _PXEDHCP4_H

+#define _PXEDHCP4_H

+

+//

+// PxeDhcp4 protocol instance data

+//

+typedef struct {

+  //

+  // Signature field used to locate beginning of containment record.

+  //

+  UINTN Signature;

+

+#define PXE_DHCP4_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('p', 'x', 'D', '4')

+  //

+  // Device handle the protocol is bound to.

+  //

+  EFI_HANDLE                      Handle;

+

+  //

+  // Public PxeDhcp4 protocol interface.

+  //

+  EFI_PXE_DHCP4_PROTOCOL          PxeDhcp4;

+

+  //

+  // Consumed PxeBc, Snp and PxeDhcp4Callback protocol interfaces.

+  //

+  EFI_PXE_BASE_CODE_PROTOCOL      *PxeBc;

+  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;

+  EFI_PXE_DHCP4_CALLBACK_PROTOCOL *callback;

+

+  //

+  // PxeDhcp4 called function for PxeDhcp4Callback.

+  //

+  EFI_PXE_DHCP4_FUNCTION          function;

+

+  //

+  // Timeout event and flag for PxeDhcp4Callback.

+  //

+  EFI_EVENT                       TimeoutEvent;

+  BOOLEAN                         TimeoutOccurred;

+

+  //

+  // Periodic event and flag for PxeDhcp4Callback.

+  //

+  EFI_EVENT                       PeriodicEvent;

+  BOOLEAN                         PeriodicOccurred;

+

+  //

+  // DHCP server IP address.

+  //

+  UINT32                          ServerIp;

+

+  //

+  // DHCP renewal and rebinding times, in seconds.

+  //

+  UINT32                          RenewTime;

+  UINT32                          RebindTime;

+  UINT32                          LeaseTime;

+

+  //

+  // Number of offers received & allocated offer list.

+  //

+  UINTN                           offers;

+  DHCP4_PACKET                    *offer_list;

+

+  //

+  //

+  //

+  BOOLEAN                         StopPxeBc;

+

+} PXE_DHCP4_PRIVATE_DATA;

+

+#define PXE_DHCP4_PRIVATE_DATA_FROM_THIS(a) CR (a, PXE_DHCP4_PRIVATE_DATA, PxeDhcp4, PXE_DHCP4_PRIVATE_DATA_SIGNATURE)

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// Protocol function prototypes.

+//

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Run (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN OPTIONAL UINTN                  OpLen,

+  IN OPTIONAL VOID                   *OpList

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Setup (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN EFI_PXE_DHCP4_DATA     *Data

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Init (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout,

+  OUT UINTN                 *offer_list_entries,

+  OUT DHCP4_PACKET          **offer_list

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Select (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout,

+  IN DHCP4_PACKET           *offer_list

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Renew (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  UINTN                     seconds_timeout

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Rebind (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  UINTN                     seconds_timeout

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+PxeDhcp4Release (

+  IN EFI_PXE_DHCP4_PROTOCOL *This

+  )

+;

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// Support function prototypes.

+//

+extern

+UINT16

+htons (

+  UINTN n

+  )

+;

+

+extern

+UINT32

+htonl (

+  UINTN n

+  )

+;

+

+extern

+VOID

+EFIAPI

+timeout_notify (

+  IN EFI_EVENT Event,

+  IN VOID      *Context

+  )

+;

+

+extern

+VOID

+EFIAPI

+periodic_notify (

+  IN EFI_EVENT Event,

+  IN VOID      *Context

+  )

+;

+

+extern

+EFI_STATUS

+find_opt (

+  IN DHCP4_PACKET *Packet,

+  IN UINT8        OpCode,

+  IN UINTN        Skip,

+  OUT DHCP4_OP    **OpPtr

+  )

+;

+

+extern

+EFI_STATUS

+add_opt (

+  IN DHCP4_PACKET *Packet,

+  IN DHCP4_OP     *OpPtr

+  )

+;

+

+extern

+EFI_STATUS

+start_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN OPTIONAL EFI_IP_ADDRESS         *station_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *subnet_mask

+  )

+;

+

+extern

+VOID

+stop_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private

+  )

+;

+

+extern

+EFI_STATUS

+start_receive_events (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN UINTN                  seconds_timeout

+  )

+;

+

+extern

+VOID

+stop_receive_events (

+  IN PXE_DHCP4_PRIVATE_DATA *Private

+  )

+;

+

+extern

+EFI_STATUS

+tx_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN EFI_IP_ADDRESS         *dest_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *gateway_ip,

+  IN EFI_IP_ADDRESS         *src_ip,

+  IN VOID                   *buffer,

+  IN UINTN                  BufferSize

+  )

+;

+

+extern

+EFI_STATUS

+rx_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  OUT VOID                  *buffer,

+  OUT UINTN                 *BufferSize,

+  IN OUT EFI_IP_ADDRESS     *dest_ip,

+  IN OUT EFI_IP_ADDRESS     *src_ip,

+  IN UINT16                 op_flags

+  )

+;

+

+extern

+EFI_STATUS

+tx_rx_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN OUT EFI_IP_ADDRESS     *ServerIp,

+  IN OPTIONAL EFI_IP_ADDRESS         *gateway_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *client_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *subnet_mask,

+  IN DHCP4_PACKET           *tx_pkt,

+  OUT DHCP4_PACKET          *rx_pkt,

+  IN INTN

+    (

+  *rx_vfy)

+    (

+      IN PXE_DHCP4_PRIVATE_DATA *Private,

+      IN DHCP4_PACKET *tx_pkt,

+      IN DHCP4_PACKET *rx_pkt,

+      IN UINTN rx_pkt_size

+    ),

+  IN UINTN seconds_timeout

+  )

+;

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+

+//

+// Global variable definitions.

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gPxeDhcp4DriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gPxeDhcp4ComponentName;

+

+#endif /* _PXEDHCP4_H */

+

+/* EOF - PxeDhcp4.h */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4InitSelect.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4InitSelect.c
new file mode 100644
index 0000000..8b7cd28
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4InitSelect.c
@@ -0,0 +1,786 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4InitSelect.c

+  

+Abstract:

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+#define DebugPrint(x)

+//

+// #define DebugPrint(x) Aprint x

+//

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+INTN

+offer_verify (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN DHCP4_PACKET           *tx_pkt,

+  IN DHCP4_PACKET           *rx_pkt,

+  IN UINTN                  rx_pkt_size

+  )

+/*++

+  -2 = ignore, stop waiting

+  -1 = ignore, keep waiting

+  0 = accept, keep waiting

+  1 = accept, stop waiting

+--*/

+{

+  EFI_STATUS    EfiStatus;

+  DHCP4_PACKET  *tmp;

+  DHCP4_OP      *msg_type_op;

+  DHCP4_OP      *srvid_op;

+  UINT32        magik;

+

+  //

+  // Verify parameters.  Touch unused parameters to keep

+  // compiler happy.

+  //

+  ASSERT (Private);

+  ASSERT (rx_pkt);

+

+  if (Private == NULL || rx_pkt == NULL) {

+    return -2;

+  }

+

+  tx_pkt      = tx_pkt;

+  rx_pkt_size = rx_pkt_size;

+

+  //

+  // This may be a BOOTP Reply or DHCP Offer packet.

+  // If there is no DHCP magik number, assume that

+  // this is a BOOTP Reply packet.

+  //

+  magik = htonl (DHCP4_MAGIK_NUMBER);

+

+  while (!CompareMem (&rx_pkt->dhcp4.magik, &magik, 4)) {

+    //

+    // If there is no DHCP message type option, assume

+    // this is a BOOTP reply packet and cache it.

+    //

+    EfiStatus = find_opt (rx_pkt, DHCP4_MESSAGE_TYPE, 0, &msg_type_op);

+

+    if (EFI_ERROR (EfiStatus)) {

+      break;

+    }

+    //

+    // If there is a DHCP message type option, it must be a

+    // DHCP offer packet

+    //

+    if (msg_type_op->len != 1) {

+      return -1;

+    }

+

+    if (msg_type_op->data[0] != DHCP4_MESSAGE_TYPE_OFFER) {

+      return -1;

+    }

+    //

+    // There must be a server identifier option.

+    //

+    EfiStatus = find_opt (

+                  rx_pkt,

+                  DHCP4_SERVER_IDENTIFIER,

+                  0,

+                  &srvid_op

+                  );

+

+    if (EFI_ERROR (EfiStatus)) {

+      return -1;

+    }

+

+    if (srvid_op->len != 4) {

+      return -1;

+    }

+    //

+    // Good DHCP offer packet.

+    //

+    break;

+  }

+  //

+  // Good DHCP (or BOOTP) packet.  Cache it!

+  //

+  EfiStatus = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    (Private->offers + 1) * sizeof (DHCP4_PACKET),

+                    (VOID **) &tmp

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    return -2;

+  }

+

+  ASSERT (tmp);

+

+  if (Private->offers != 0) {

+    CopyMem (

+      tmp,

+      Private->offer_list,

+      Private->offers * sizeof (DHCP4_PACKET)

+      );

+

+    gBS->FreePool (Private->offer_list);

+  }

+

+  CopyMem (&tmp[Private->offers++], rx_pkt, sizeof (DHCP4_PACKET));

+

+  Private->offer_list = tmp;

+

+  return 0;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+INTN

+acknak_verify (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN DHCP4_PACKET           *tx_pkt,

+  IN DHCP4_PACKET           *rx_pkt,

+  IN UINTN                  rx_pkt_size

+  )

+/*++

+  -2 = ignore, stop waiting

+  -1 = ignore, keep waiting

+  0 = accept, keep waiting

+  1 = accept, stop waiting

+--*/

+{

+  EFI_STATUS  EfiStatus;

+  DHCP4_OP    *msg_type_op;

+  DHCP4_OP    *srvid_op;

+  DHCP4_OP    *renew_op;

+  DHCP4_OP    *rebind_op;

+  DHCP4_OP    *lease_time_op;

+  UINT32      magik;

+

+  //

+  // Verify parameters.  Touch unused parameters to

+  // keep compiler happy.

+  //

+  ASSERT (Private);

+  ASSERT (rx_pkt);

+

+  if (Private == NULL || rx_pkt == NULL) {

+    return -2;

+  }

+

+  tx_pkt      = tx_pkt;

+  rx_pkt_size = rx_pkt_size;

+

+  //

+  // This must be a DHCP Ack message.

+  //

+  magik = htonl (DHCP4_MAGIK_NUMBER);

+

+  if (CompareMem (&rx_pkt->dhcp4.magik, &magik, 4)) {

+    return -1;

+  }

+

+  EfiStatus = find_opt (rx_pkt, DHCP4_MESSAGE_TYPE, 0, &msg_type_op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    return -1;

+  }

+

+  if (msg_type_op->len != 1) {

+    return -1;

+  }

+

+  if (msg_type_op->data[0] != DHCP4_MESSAGE_TYPE_ACK) {

+    return -1;

+  }

+  //

+  // There must be a server identifier.

+  //

+  EfiStatus = find_opt (rx_pkt, DHCP4_SERVER_IDENTIFIER, 0, &srvid_op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    return -1;

+  }

+

+  if (srvid_op->len != 4) {

+    return -1;

+  }

+  //

+  // There should be a renewal time.

+  // If there is not, we will default to the 7/8 of the rebinding time.

+  //

+  EfiStatus = find_opt (rx_pkt, DHCP4_RENEWAL_TIME, 0, &renew_op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    renew_op = NULL;

+  } else if (renew_op->len != 4) {

+    renew_op = NULL;

+  }

+  //

+  // There should be a rebinding time.

+  // If there is not, we will default to 7/8 of the lease time.

+  //

+  EfiStatus = find_opt (rx_pkt, DHCP4_REBINDING_TIME, 0, &rebind_op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    rebind_op = NULL;

+  } else if (rebind_op->len != 4) {

+    rebind_op = NULL;

+  }

+  //

+  // There should be a lease time.

+  // If there is not, we will default to one week.

+  //

+  EfiStatus = find_opt (rx_pkt, DHCP4_LEASE_TIME, 0, &lease_time_op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    lease_time_op = NULL;

+  } else if (lease_time_op->len != 4) {

+    lease_time_op = NULL;

+  }

+  //

+  // Packet looks good.  Double check the renew, rebind and lease times.

+  //

+  CopyMem (&Private->ServerIp, srvid_op->data, 4);

+

+  if (renew_op != NULL) {

+    CopyMem (&Private->RenewTime, renew_op->data, 4);

+    Private->RenewTime = htonl (Private->RenewTime);

+  } else {

+    Private->RenewTime = 0;

+  }

+

+  if (rebind_op != NULL) {

+    CopyMem (&Private->RebindTime, rebind_op->data, 4);

+    Private->RebindTime = htonl (Private->RebindTime);

+  } else {

+    Private->RebindTime = 0;

+  }

+

+  if (lease_time_op != NULL) {

+    CopyMem (&Private->LeaseTime, lease_time_op->data, 4);

+    Private->LeaseTime = htonl (Private->LeaseTime);

+  } else {

+    Private->LeaseTime = 0;

+  }

+

+  if (Private->LeaseTime < 60) {

+    Private->LeaseTime = 7 * 86400;

+  }

+

+  if (Private->RebindTime < 52 || Private->RebindTime >= Private->LeaseTime) {

+    Private->RebindTime = Private->LeaseTime / 2 + Private->LeaseTime / 4 + Private->LeaseTime / 8;

+  }

+

+  if (Private->RenewTime < 45 || Private->RenewTime >= Private->RebindTime) {

+    Private->RenewTime = Private->RebindTime / 2 + Private->RebindTime / 4 + Private->RebindTime / 8;

+  }

+

+  return 1;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Init (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout,

+  OUT UINTN                 *Offers,

+  OUT DHCP4_PACKET          **OfferList

+  )

+{

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+  DHCP4_PACKET            offer;

+  EFI_IP_ADDRESS          bcast_ip;

+  EFI_STATUS              EfiStatus;

+

+  //

+  // Verify parameters and protocol state.

+  //

+  if (This == NULL ||

+      seconds_timeout < DHCP4_MIN_SECONDS ||

+      seconds_timeout > DHCP4_MAX_SECONDS ||

+      Offers == NULL ||

+      OfferList == NULL

+      ) {

+    //

+    // Return parameters are not initialized when

+    // parameters are invalid!

+    //

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Offers     = 0;

+  *OfferList  = NULL;

+

+  //

+  // Check protocol state.

+  //

+  if (This->Data == NULL) {

+    return EFI_NOT_STARTED;

+  }

+

+  if (!This->Data->SetupCompleted) {

+    return EFI_NOT_READY;

+  }

+

+#if 0

+  if (!is_good_discover (&This->Data->Discover)) {

+    //

+    // %%TBD - check discover packet fields

+    //

+  }

+#endif

+  //

+  // Get pointer to our instance data.

+  //

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Setup variables...

+  //

+  Private->offers     = 0;

+  Private->offer_list = NULL;

+

+  EfiStatus = gBS->HandleProtocol (

+                    Private->Handle,

+                    &gEfiPxeDhcp4CallbackProtocolGuid,

+                    (VOID *) &Private->callback

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    Private->callback = NULL;

+  }

+

+  Private->function = EFI_PXE_DHCP4_FUNCTION_INIT;

+

+  //

+  // Increment the transaction ID.

+  //

+  {

+    UINT32  xid;

+

+    CopyMem (&xid, &This->Data->Discover.dhcp4.xid, sizeof (UINT32));

+

+    xid = htonl (htonl (xid) + 1);

+

+    CopyMem (&This->Data->Discover.dhcp4.xid, &xid, sizeof (UINT32));

+  }

+  //

+  // Transmit discover and wait for offers...

+  //

+  SetMem (&bcast_ip, sizeof (EFI_IP_ADDRESS), 0xFF);

+

+  EfiStatus = tx_rx_udp (

+                Private,

+                &bcast_ip,

+                NULL,

+                NULL,

+                NULL,

+                &This->Data->Discover,

+                &offer,

+                &offer_verify,

+                seconds_timeout

+                );

+

+  if (EFI_ERROR (EfiStatus)) {

+    if (Private->offer_list) {

+      gBS->FreePool (Private->offer_list);

+    }

+

+    Private->offers     = 0;

+    Private->offer_list = NULL;

+    Private->callback   = NULL;

+

+    DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));

+    return EfiStatus;

+  }

+

+  *Offers                     = Private->offers;

+  *OfferList                  = Private->offer_list;

+

+  Private->offers             = 0;

+  Private->offer_list         = NULL;

+  Private->callback           = NULL;

+

+  This->Data->InitCompleted   = TRUE;

+  This->Data->SelectCompleted = FALSE;

+  This->Data->IsBootp         = FALSE;

+  This->Data->IsAck           = FALSE;

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Select (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout,

+  IN DHCP4_PACKET           *Offer

+  )

+{

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+  EFI_STATUS              EfiStatus;

+  DHCP4_PACKET            request;

+  DHCP4_PACKET            acknak;

+  EFI_IP_ADDRESS          bcast_ip;

+  EFI_IP_ADDRESS          zero_ip;

+  EFI_IP_ADDRESS          local_ip;

+  DHCP4_OP                *srvid;

+  DHCP4_OP                *op;

+  UINT32                  dhcp4_magik;

+  UINT8                   buf[16];

+  BOOLEAN                 is_bootp;

+

+  //

+  // Verify parameters.

+  //

+  if (This == NULL || seconds_timeout < DHCP4_MIN_SECONDS || seconds_timeout > DHCP4_MAX_SECONDS || Offer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Check protocol state.

+  //

+  if (This->Data == NULL) {

+    return EFI_NOT_STARTED;

+  }

+

+  if (!This->Data->SetupCompleted) {

+    return EFI_NOT_READY;

+  }

+  //

+  // Get pointer to instance data.

+  //

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+#if 0

+  if (!is_good_discover (&This->Data->Discover)) {

+    //

+    // %%TBD - check discover packet fields

+    //

+  }

+#endif

+  //

+  // Setup useful variables...

+  //

+  SetMem (&bcast_ip, sizeof (EFI_IP_ADDRESS), 0xFF);

+

+  ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));

+

+  ZeroMem (&local_ip, sizeof (EFI_IP_ADDRESS));

+  local_ip.v4.Addr[0]         = 127;

+  local_ip.v4.Addr[3]         = 1;

+

+  This->Data->SelectCompleted = FALSE;

+  This->Data->IsBootp         = FALSE;

+  This->Data->IsAck           = FALSE;

+

+  EfiStatus = gBS->HandleProtocol (

+                    Private->Handle,

+                    &gEfiPxeDhcp4CallbackProtocolGuid,

+                    (VOID *) &Private->callback

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    Private->callback = NULL;

+  }

+

+  Private->function = EFI_PXE_DHCP4_FUNCTION_SELECT;

+

+  //

+  // Verify offer packet fields.

+  //

+  if (Offer->dhcp4.op != BOOTP_REPLY) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Offer->dhcp4.htype != This->Data->Discover.dhcp4.htype) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Offer->dhcp4.hlen != This->Data->Discover.dhcp4.hlen) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (CompareMem (&Offer->dhcp4.xid, &This->Data->Discover.dhcp4.xid, 4)) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!CompareMem (&Offer->dhcp4.yiaddr, &bcast_ip, 4)) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!CompareMem (&Offer->dhcp4.yiaddr, &zero_ip, 4)) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!CompareMem (&Offer->dhcp4.yiaddr, &local_ip, 4)) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (CompareMem (

+        &Offer->dhcp4.chaddr,

+        &This->Data->Discover.dhcp4.chaddr,

+        16

+        )) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // DHCP option checks

+  //

+  dhcp4_magik = htonl (DHCP4_MAGIK_NUMBER);

+  is_bootp    = TRUE;

+

+  if (!CompareMem (&Offer->dhcp4.magik, &dhcp4_magik, 4)) {

+    //

+    // If present, DHCP message type must be offer.

+    //

+    EfiStatus = find_opt (Offer, DHCP4_MESSAGE_TYPE, 0, &op);

+

+    if (!EFI_ERROR (EfiStatus)) {

+      if (op->len != 1 || op->data[0] != DHCP4_MESSAGE_TYPE_OFFER) {

+        Private->callback = NULL;

+        return EFI_INVALID_PARAMETER;

+      }

+

+      is_bootp = FALSE;

+    }

+    //

+    // If present, DHCP max message size must be valid.

+    //

+    EfiStatus = find_opt (Offer, DHCP4_MAX_MESSAGE_SIZE, 0, &op);

+

+    if (!EFI_ERROR (EfiStatus)) {

+      if (op->len != 2 || ((op->data[0] << 8) | op->data[1]) < DHCP4_DEFAULT_MAX_MESSAGE_SIZE) {

+        Private->callback = NULL;

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+    //

+    // If present, DHCP server identifier must be valid.

+    //

+    EfiStatus = find_opt (Offer, DHCP4_SERVER_IDENTIFIER, 0, &op);

+

+    if (!EFI_ERROR (EfiStatus)) {

+      if (op->len != 4 || !CompareMem (op->data, &bcast_ip, 4) || !CompareMem (op->data, &zero_ip, 4)) {

+        Private->callback = NULL;

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+    //

+    // If present, DHCP subnet mask must be valid.

+    //

+    EfiStatus = find_opt (

+                  Offer,

+                  DHCP4_SUBNET_MASK,

+                  0,

+                  &op

+                  );

+

+    if (!EFI_ERROR (EfiStatus)) {

+      if (op->len != 4) {

+        Private->callback = NULL;

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+  //

+  // Early out for BOOTP.

+  //

+  This->Data->IsBootp = is_bootp;

+  if (is_bootp) {

+    //

+    // Copy offer packet to instance data.

+    //

+    CopyMem (&This->Data->Offer, Offer, sizeof (DHCP4_PACKET));

+

+    //

+    // Copy discover to request and offer to acknak.

+    //

+    CopyMem (

+      &This->Data->Request,

+      &This->Data->Discover,

+      sizeof (DHCP4_PACKET)

+      );

+

+    CopyMem (

+      &This->Data->AckNak,

+      &This->Data->Offer,

+      sizeof (DHCP4_PACKET)

+      );

+

+    //

+    // Set state flags.

+    //

+    This->Data->SelectCompleted = TRUE;

+    This->Data->IsAck           = TRUE;

+

+    Private->callback           = NULL;

+    return EFI_SUCCESS;

+  }

+  //

+  // Copy discover packet contents to request packet.

+  //

+  CopyMem (&request, &This->Data->Discover, sizeof (DHCP4_PACKET));

+

+  This->Data->IsAck = FALSE;

+

+  //

+  // Change DHCP message type from discover to request.

+  //

+  EfiStatus = find_opt (&request, DHCP4_MESSAGE_TYPE, 0, &op);

+

+  if (EFI_ERROR (EfiStatus) && EfiStatus != EFI_NOT_FOUND) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (EfiStatus == EFI_NOT_FOUND) {

+    EfiStatus = find_opt (&request, DHCP4_END, 0, &op);

+

+    if (EFI_ERROR (EfiStatus)) {

+      Private->callback = NULL;

+      return EFI_INVALID_PARAMETER;

+    }

+

+    op->op      = DHCP4_MESSAGE_TYPE;

+    op->len     = 1;

+

+    op->data[1] = DHCP4_END;

+  }

+

+  op->data[0] = DHCP4_MESSAGE_TYPE_REQUEST;

+

+  //

+  // Copy server identifier option from offer to request.

+  //

+  EfiStatus = find_opt (Offer, DHCP4_SERVER_IDENTIFIER, 0, &srvid);

+

+  if (EFI_ERROR (EfiStatus)) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (srvid->len != 4) {

+    Private->callback = NULL;

+    return EFI_INVALID_PARAMETER;

+  }

+

+  EfiStatus = add_opt (&request, srvid);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));

+    Private->callback = NULL;

+    return EfiStatus;

+  }

+  //

+  // Add requested IP address option to request packet.

+  //

+  op      = (DHCP4_OP *) buf;

+  op->op  = DHCP4_REQUESTED_IP_ADDRESS;

+  op->len = 4;

+  CopyMem (op->data, &Offer->dhcp4.yiaddr, 4);

+

+  EfiStatus = add_opt (&request, op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));

+    Private->callback = NULL;

+    return EfiStatus;

+  }

+  //

+  // Transimit DHCP request and wait for DHCP ack...

+  //

+  SetMem (&bcast_ip, sizeof (EFI_IP_ADDRESS), 0xFF);

+

+  EfiStatus = tx_rx_udp (

+                Private,

+                &bcast_ip,

+                NULL,

+                NULL,

+                NULL,

+                &request,

+                &acknak,

+                &acknak_verify,

+                seconds_timeout

+                );

+

+  if (EFI_ERROR (EfiStatus)) {

+    DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));

+    Private->callback = NULL;

+    return EfiStatus;

+  }

+  //

+  // Set Data->IsAck and return.

+  //

+  EfiStatus = find_opt (&acknak, DHCP4_MESSAGE_TYPE, 0, &op);

+

+  if (EFI_ERROR (EfiStatus)) {

+    Private->callback = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (op->len != 1) {

+    Private->callback = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (op->data[0]) {

+  case DHCP4_MESSAGE_TYPE_ACK:

+    This->Data->IsAck = TRUE;

+    break;

+

+  case DHCP4_MESSAGE_TYPE_NAK:

+    This->Data->IsAck = FALSE;

+    break;

+

+  default:

+    Private->callback = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Copy packets into instance data...

+  //

+  CopyMem (&This->Data->Offer, Offer, sizeof (DHCP4_PACKET));

+  CopyMem (&This->Data->Request, &request, sizeof (DHCP4_PACKET));

+  CopyMem (&This->Data->AckNak, &acknak, sizeof (DHCP4_PACKET));

+

+  This->Data->SelectCompleted = TRUE;

+

+  Private->callback           = NULL;

+  return EFI_SUCCESS;

+}

+

+/* eof - PxeDhcp4InitSelect.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Release.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Release.c
new file mode 100644
index 0000000..6086e55
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Release.c
@@ -0,0 +1,246 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4Release.c

+  

+Abstract:

+  Transmit release packet, free allocations and shutdown PxeDhcp4.

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Release (

+  IN EFI_PXE_DHCP4_PROTOCOL *This

+  )

+{

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+  EFI_IP_ADDRESS          ServerIp;

+  EFI_IP_ADDRESS          client_ip;

+  EFI_IP_ADDRESS          gateway_ip;

+  EFI_IP_ADDRESS          subnet_mask;

+  EFI_STATUS              efi_status;

+  DHCP4_OP                *op;

+  UINT8                   op_list[20];

+

+  //

+  // Check for invalid parameters.

+  //

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Release does nothing if the protocol has never been setup.

+  //

+  if (This->Data == NULL) {

+    return EFI_NOT_STARTED;

+  }

+  //

+  // Fail if we do not have valid instance data.

+  //

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // If this is a BOOTP session and there is not a DHCP Ack

+  // packet, just release storage and return.

+  //

+  if (This->Data->IsBootp || !This->Data->IsAck) {

+    gBS->FreePool (This->Data);

+    This->Data = NULL;

+

+    if (Private->StopPxeBc) {

+      Private->PxeBc->Stop (Private->PxeBc);

+    }

+

+    return EFI_SUCCESS;

+  }

+  //

+  // Build option list for DHCP Release packet.

+  // If any errors occur, just release storage and return.

+  //

+  //

+  // Message type is first.

+  //

+  op_list[0]  = DHCP4_MESSAGE_TYPE;

+  op_list[1]  = 1;

+  op_list[2]  = DHCP4_MESSAGE_TYPE_RELEASE;

+

+  //

+  // Followed by server identifier.

+  //

+  efi_status = find_opt (

+                &This->Data->Request,

+                DHCP4_SERVER_IDENTIFIER,

+                0,

+                &op

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    gBS->FreePool (This->Data);

+    This->Data = NULL;

+

+    if (Private->StopPxeBc) {

+      Private->PxeBc->Stop (Private->PxeBc);

+    }

+

+    return EFI_SUCCESS;

+  }

+

+  if (op->len != 4) {

+    gBS->FreePool (This->Data);

+    This->Data = NULL;

+

+    if (Private->StopPxeBc) {

+      Private->PxeBc->Stop (Private->PxeBc);

+    }

+

+    return EFI_SUCCESS;

+  }

+

+  CopyMem (&ServerIp, op->data, 4);

+

+  op_list[3]  = DHCP4_SERVER_IDENTIFIER;

+  op_list[4]  = 4;

+  CopyMem (&op_list[5], &ServerIp, 4);

+

+  //

+  // Followed by end.

+  //

+  op_list[9] = DHCP4_END;

+

+  //

+  // We need a subnet mask for IP stack operation.

+  //

+  efi_status = find_opt (

+                &This->Data->AckNak,

+                DHCP4_SUBNET_MASK,

+                0,

+                &op

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    gBS->FreePool (This->Data);

+    This->Data = NULL;

+

+    if (Private->StopPxeBc) {

+      Private->PxeBc->Stop (Private->PxeBc);

+    }

+

+    return EFI_SUCCESS;

+  }

+

+  if (op->len != 4) {

+    gBS->FreePool (This->Data);

+    This->Data = NULL;

+

+    if (Private->StopPxeBc) {

+      Private->PxeBc->Stop (Private->PxeBc);

+    }

+

+    return EFI_SUCCESS;

+  }

+

+  ZeroMem (&subnet_mask, sizeof (EFI_IP_ADDRESS));

+  CopyMem (&subnet_mask, op->data, 4);

+

+  //

+  // Gateway IP address may be needed.

+  //

+  ZeroMem (&gateway_ip, sizeof (EFI_IP_ADDRESS));

+  CopyMem (&gateway_ip, &This->Data->AckNak.dhcp4.giaddr, 4);

+

+  //

+  // Client IP address needed for IP stack operation.

+  //

+  ZeroMem (&client_ip, sizeof (EFI_IP_ADDRESS));

+  CopyMem (&client_ip, &This->Data->AckNak.dhcp4.yiaddr, 4);

+

+  //

+  // Enable UDP...

+  //

+  efi_status = start_udp (Private, &client_ip, &subnet_mask);

+

+  if (EFI_ERROR (efi_status)) {

+    gBS->FreePool (This->Data);

+    This->Data = NULL;

+

+    if (Private->StopPxeBc) {

+      Private->PxeBc->Stop (Private->PxeBc);

+    }

+

+    return efi_status;

+  }

+  //

+  // Gather information out of DHCP request packet needed for

+  // DHCP release packet.

+  //

+  //

+  // Setup DHCP Release packet.

+  //

+  CopyMem (&This->Data->Request.dhcp4.ciaddr, &client_ip, 4);

+

+  ZeroMem (&This->Data->Request.dhcp4.yiaddr, 12);

+

+  ZeroMem (&This->Data->Request.dhcp4.sname, 64 + 128);

+

+  This->Data->Request.dhcp4.hops  = 0;

+  This->Data->Request.dhcp4.secs  = 0;

+  This->Data->Request.dhcp4.flags = 0;

+

+  ZeroMem (

+    &This->Data->Request.dhcp4.options,

+    sizeof This->Data->Request.dhcp4.options

+    );

+

+  CopyMem (&This->Data->Request.dhcp4.options, op_list, 10);

+

+  //

+  // Transmit DHCP Release packet.

+  //

+  tx_udp (

+    Private,

+    &ServerIp,

+    &gateway_ip,

+    &client_ip,

+    &This->Data->Request,

+    DHCP4_MAX_PACKET_SIZE - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE)

+    );

+

+  gBS->Stall (1000000); /* 1/10th second */

+

+  //

+  // Shutdown PXE BaseCode and release local storage.

+  //

+  stop_udp (Private);

+

+  gBS->FreePool (This->Data);

+  This->Data = NULL;

+

+  if (Private->StopPxeBc) {

+    Private->PxeBc->Stop (Private->PxeBc);

+  }

+

+  return EFI_SUCCESS;

+}

+

+/* eof - PxeDhcp4Release.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4RenewRebind.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4RenewRebind.c
new file mode 100644
index 0000000..2905255
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4RenewRebind.c
@@ -0,0 +1,408 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4RenewRebind.c

+  

+Abstract:

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+INTN

+acknak_verify (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN DHCP4_PACKET           *tx_pkt,

+  IN DHCP4_PACKET           *rx_pkt,

+  IN UINTN                  rx_pkt_size

+  )

+/*++

+Routine Description:

+

+Parameters:

+

+Returns:

+  -2 = ignore, stop waiting

+  -1 = ignore, keep waiting

+  0 = accept, keep waiting

+  1 = accept, stop waiting

+--*/

+{

+  EFI_STATUS  efi_status;

+  DHCP4_OP    *msg_type_op;

+  DHCP4_OP    *srvid_op;

+  DHCP4_OP    *renew_op;

+  DHCP4_OP    *rebind_op;

+  DHCP4_OP    *lease_time_op;

+  UINT32      magik;

+

+  //

+  // Verify parameters.  Unused parameters are also touched

+  // to make the compiler happy.

+  //

+  ASSERT (Private);

+  ASSERT (rx_pkt);

+

+  if (Private == NULL || rx_pkt == NULL) {

+    return -2;

+  }

+

+  tx_pkt      = tx_pkt;

+  rx_pkt_size = rx_pkt_size;

+

+  //

+  // This must be a DHCP Ack message.

+  //

+  magik = htonl (DHCP4_MAGIK_NUMBER);

+

+  if (CompareMem (&rx_pkt->dhcp4.magik, &magik, 4)) {

+    return -1;

+  }

+

+  efi_status = find_opt (rx_pkt, DHCP4_MESSAGE_TYPE, 0, &msg_type_op);

+

+  if (EFI_ERROR (efi_status)) {

+    return -1;

+  }

+

+  if (msg_type_op->len != 1) {

+    return -1;

+  }

+

+  if (msg_type_op->data[0] != DHCP4_MESSAGE_TYPE_ACK) {

+    return -1;

+  }

+  //

+  // There must be a server identifier.

+  //

+  efi_status = find_opt (rx_pkt, DHCP4_SERVER_IDENTIFIER, 0, &srvid_op);

+

+  if (EFI_ERROR (efi_status)) {

+    return -1;

+  }

+

+  if (srvid_op->len != 4) {

+    return -1;

+  }

+  //

+  // There should be a renewal time.

+  // If there is not, we will default to the 7/8 of the rebinding time.

+  //

+  efi_status = find_opt (rx_pkt, DHCP4_RENEWAL_TIME, 0, &renew_op);

+

+  if (EFI_ERROR (efi_status)) {

+    renew_op = NULL;

+  } else if (renew_op->len != 4) {

+    renew_op = NULL;

+  }

+  //

+  // There should be a rebinding time.

+  // If there is not, we will default to 7/8 of the lease time.

+  //

+  efi_status = find_opt (rx_pkt, DHCP4_REBINDING_TIME, 0, &rebind_op);

+

+  if (EFI_ERROR (efi_status)) {

+    rebind_op = NULL;

+  } else if (rebind_op->len != 4) {

+    rebind_op = NULL;

+  }

+  //

+  // There should be a lease time.

+  // If there is not, we will default to one week.

+  //

+  efi_status = find_opt (rx_pkt, DHCP4_LEASE_TIME, 0, &lease_time_op);

+

+  if (EFI_ERROR (efi_status)) {

+    lease_time_op = NULL;

+  } else if (lease_time_op->len != 4) {

+    lease_time_op = NULL;

+  }

+  //

+  // Packet looks good.  Double check the renew, rebind and lease times.

+  //

+  CopyMem (&Private->ServerIp, srvid_op->data, 4);

+

+  if (renew_op != NULL) {

+    CopyMem (&Private->RenewTime, renew_op->data, 4);

+    Private->RenewTime = htonl (Private->RenewTime);

+  } else {

+    Private->RenewTime = 0;

+  }

+

+  if (rebind_op != NULL) {

+    CopyMem (&Private->RebindTime, rebind_op->data, 4);

+    Private->RebindTime = htonl (Private->RebindTime);

+  } else {

+    Private->RebindTime = 0;

+  }

+

+  if (lease_time_op != NULL) {

+    CopyMem (&Private->LeaseTime, lease_time_op->data, 4);

+    Private->LeaseTime = htonl (Private->LeaseTime);

+  } else {

+    Private->LeaseTime = 0;

+  }

+

+  if (Private->LeaseTime < 60) {

+    Private->LeaseTime = 7 * 86400;

+  }

+

+  if (Private->RebindTime < 52 || Private->RebindTime >= Private->LeaseTime) {

+    Private->RebindTime = Private->LeaseTime / 2 + Private->LeaseTime / 4 + Private->LeaseTime / 8;

+  }

+

+  if (Private->RenewTime < 45 || Private->RenewTime >= Private->RebindTime) {

+    Private->RenewTime = Private->RebindTime / 2 + Private->RebindTime / 4 + Private->RebindTime / 8;

+  }

+

+  return 1;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+STATIC

+EFI_STATUS

+EFIAPI

+renew_rebind (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout,

+  IN BOOLEAN                renew

+  )

+{

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+  EFI_IP_ADDRESS          ServerIp;

+  EFI_IP_ADDRESS          client_ip;

+  EFI_IP_ADDRESS          subnet_mask;

+  EFI_IP_ADDRESS          gateway_ip;

+  DHCP4_PACKET            Request;

+  DHCP4_PACKET            AckNak;

+  DHCP4_OP                *op;

+  EFI_STATUS              efi_status;

+

+  //

+  // Check for invalid parameters.

+  //

+  if (This == NULL || seconds_timeout < DHCP4_MIN_SECONDS || seconds_timeout > DHCP4_MAX_SECONDS) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Check for proper protocol state.

+  //

+  if (This->Data == NULL) {

+    return EFI_NOT_STARTED;

+  }

+

+  if (!This->Data->SelectCompleted) {

+    return EFI_NOT_READY;

+  }

+

+  if (This->Data->IsBootp) {

+    return EFI_SUCCESS;

+  }

+

+  if (!This->Data->IsAck) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Get pointer to instance data.

+  //

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Copy Discover packet to temporary request packet

+  // to be used for Renew/Rebind operation.

+  //

+  CopyMem (&Request, &This->Data->Discover, sizeof (DHCP4_PACKET));

+

+  CopyMem (&Request.dhcp4.ciaddr, &This->Data->AckNak.dhcp4.yiaddr, 4);

+

+  Request.dhcp4.flags = 0;  /* Reply does not need to be broadcast. */

+

+  //

+  // Change message type from discover to request.

+  //

+  efi_status = find_opt (&Request, DHCP4_MESSAGE_TYPE, 0, &op);

+

+  if (EFI_ERROR (efi_status)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (op->len != 1) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  op->data[0] = DHCP4_MESSAGE_TYPE_REQUEST;

+

+  //

+  // Need a subnet mask.

+  //

+  efi_status = find_opt (

+                &This->Data->AckNak,

+                DHCP4_SUBNET_MASK,

+                0,

+                &op

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (op->len != 4) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ZeroMem (&subnet_mask, sizeof (EFI_IP_ADDRESS));

+  CopyMem (&subnet_mask, op->data, 4);

+

+  //

+  // Need a server IP address (renew) or a broadcast

+  // IP address (rebind).

+  //

+  ZeroMem (&gateway_ip, sizeof (EFI_IP_ADDRESS));

+

+  if (renew) {

+    efi_status = find_opt (

+                  &This->Data->AckNak,

+                  DHCP4_SERVER_IDENTIFIER,

+                  0,

+                  &op

+                  );

+

+    if (EFI_ERROR (efi_status)) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (op->len != 4) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    ZeroMem (&ServerIp, sizeof (EFI_IP_ADDRESS));

+    CopyMem (&ServerIp, op->data, 4);

+

+    //

+    //

+    //

+    if (CompareMem (&This->Data->AckNak.dhcp4.giaddr, &gateway_ip, 4)) {

+      CopyMem (&gateway_ip, &This->Data->AckNak.dhcp4.giaddr, 4);

+    }

+  } else {

+    SetMem (&ServerIp, sizeof (EFI_IP_ADDRESS), 0xFF);

+  }

+  //

+  // Need a client IP address.

+  //

+  ZeroMem (&client_ip, sizeof (EFI_IP_ADDRESS));

+  CopyMem (&client_ip, &Request.dhcp4.ciaddr, 4);

+

+  //

+  //

+  //

+  efi_status = gBS->HandleProtocol (

+                      Private->Handle,

+                      &gEfiPxeDhcp4CallbackProtocolGuid,

+                      (VOID *) &Private->callback

+                      );

+

+  if (EFI_ERROR (efi_status)) {

+    Private->callback = NULL;

+  }

+

+  Private->function = renew ? EFI_PXE_DHCP4_FUNCTION_RENEW : EFI_PXE_DHCP4_FUNCTION_REBIND;

+

+  //

+  // Transimit DHCP request and wait for DHCP ack...

+  //

+  efi_status = tx_rx_udp (

+                Private,

+                &ServerIp,

+                &gateway_ip,

+                &client_ip,

+                &subnet_mask,

+                &Request,

+                &AckNak,

+                &acknak_verify,

+                seconds_timeout

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    Private->callback = NULL;

+    return efi_status;

+  }

+  //

+  // Copy server identifier, renewal time and rebinding time

+  // from temporary ack/nak packet into cached ack/nak packet.

+  //

+  efi_status = find_opt (

+                &This->Data->AckNak,

+                DHCP4_SERVER_IDENTIFIER,

+                0,

+                &op

+                );

+

+  if (!EFI_ERROR (efi_status)) {

+    if (op->len == 4) {

+      CopyMem (op->data, &Private->ServerIp, 4);

+    }

+  }

+

+  efi_status = find_opt (&This->Data->AckNak, DHCP4_RENEWAL_TIME, 0, &op);

+

+  if (!EFI_ERROR (efi_status)) {

+    if (op->len == 4) {

+      CopyMem (op->data, &Private->RenewTime, 4);

+    }

+  }

+

+  efi_status = find_opt (&This->Data->AckNak, DHCP4_REBINDING_TIME, 0, &op);

+

+  if (!EFI_ERROR (efi_status)) {

+    if (op->len == 4) {

+      CopyMem (op->data, &Private->RebindTime, 4);

+    }

+  }

+

+  Private->callback = NULL;

+  return efi_status;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Renew (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout

+  )

+{

+  return renew_rebind (This, seconds_timeout, TRUE);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Rebind (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN UINTN                  seconds_timeout

+  )

+{

+  return renew_rebind (This, seconds_timeout, FALSE);

+}

+

+/* eof - PxeDhcp4RenewRebind.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Run.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Run.c
new file mode 100644
index 0000000..50f97a8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Run.c
@@ -0,0 +1,196 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4Run.c

+  

+Abstract:

+  Simplified entry point for starting basic PxeDhcp4 client operation.

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Run (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN OPTIONAL UINTN                  OpLen,

+  IN OPTIONAL VOID                   *OpList

+  )

+{

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+  DHCP4_PACKET            *offer_list;

+  EFI_STATUS              efi_status;

+  EFI_IP_ADDRESS          zero_ip;

+  UINTN                   offers;

+  UINTN                   timeout;

+  UINTN                   n;

+  UINT16                  seconds;

+

+  //

+  // Validate parameters.

+  //

+  if (This == NULL || (OpLen != 0 && OpList == NULL) || (OpLen == 0 && OpList != NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  for (n = 0; n < OpLen;) {

+    switch (((UINT8 *) OpList)[n]) {

+    case DHCP4_PAD:

+      ++n;

+      continue;

+

+    case DHCP4_END:

+      ++n;

+      break;

+

+    default:

+      n += 2 + ((UINT8 *) OpList)[n + 1];

+      continue;

+    }

+

+    break;

+  }

+

+  if (n != OpLen) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Get pointer to instance data.

+  //

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Initialize DHCP discover packet.

+  //

+  efi_status = PxeDhcp4Setup (This, NULL);

+

+  if (EFI_ERROR (efi_status)) {

+    return efi_status;

+  }

+

+  for (n = 0; n < OpLen;) {

+    switch (((UINT8 *) OpList)[n]) {

+    case DHCP4_PAD:

+      ++n;

+      continue;

+

+    case DHCP4_END:

+      ++n;

+      break;

+

+    default:

+      efi_status = add_opt (

+                    &This->Data->Discover,

+                    (DHCP4_OP *) &(((UINT8 *) OpList)[n])

+                    );

+

+      if (EFI_ERROR (efi_status)) {

+        return efi_status;

+      }

+

+      n += 2 + ((UINT8 *) OpList)[n + 1];

+      continue;

+    }

+

+    break;

+  }

+  //

+  // Basic DHCP D.O.R.A.

+  // 1, 2, 4, 8, 16 & 32 second timeouts.

+  // Callback routine can be used to break out earlier.

+  //

+  ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));

+

+  for (timeout = 1;;) {

+    //

+    // Broadcast DHCP discover and wait for DHCP offers.

+    //

+    efi_status = PxeDhcp4Init (This, timeout, &offers, &offer_list);

+

+    switch (efi_status) {

+    case EFI_NO_RESPONSE:

+    case EFI_TIMEOUT:

+    case EFI_SUCCESS:

+      break;

+

+    case EFI_ABORTED:

+    default:

+      return efi_status;

+    }

+    //

+    // Try to select from each DHCP or BOOTP offer.

+    //

+    for (n = 0; n < offers; ++n) {

+      //

+      // Ignore proxyDHCP offers.

+      //

+      if (!CompareMem (&offer_list[n].dhcp4.yiaddr, &zero_ip, 4)) {

+        continue;

+      }

+      //

+      // Issue DHCP Request and wait for DHCP Ack/Nak.

+      //

+      efi_status = PxeDhcp4Select (

+                    This,

+                    timeout,

+                    &offer_list[n]

+                    );

+

+      if (EFI_ERROR (efi_status)) {

+        continue;

+      }

+      //

+      // Exit when we have got our DHCP Ack.

+      //

+      if (This->Data->IsAck) {

+        return EFI_SUCCESS;

+      }

+    }

+    //

+    // No DHCP Acks.  Release DHCP Offer list storage.

+    //

+    if (offer_list != NULL) {

+      gBS->FreePool (offer_list);

+      offer_list = NULL;

+    }

+    //

+    // Try again until we have used up >= DHCP4_MAX_SECONDS.

+    //

+    if ((timeout <<= 1) > DHCP4_MAX_SECONDS) {

+      if (!EFI_ERROR (efi_status)) {

+        efi_status = EFI_TIMEOUT;

+      }

+

+      return efi_status;

+    }

+    //

+    // Next timeout value.

+    //

+    CopyMem (&seconds, &This->Data->Discover.dhcp4.secs, 2);

+

+    seconds = htons (htons (seconds) + timeout);

+

+    CopyMem (&This->Data->Discover.dhcp4.secs, &seconds, 2);

+  }

+}

+

+/* eof - PxeDhcp4Run.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Setup.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Setup.c
new file mode 100644
index 0000000..09ba041
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Setup.c
@@ -0,0 +1,268 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PxeDhcp4Setup.c

+  

+Abstract:

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+EFIAPI

+PxeDhcp4Setup (

+  IN EFI_PXE_DHCP4_PROTOCOL *This,

+  IN EFI_PXE_DHCP4_DATA     *Data

+  )

+{

+  PXE_DHCP4_PRIVATE_DATA  *Private;

+  DHCP4_HEADER            *Packet;

+  EFI_STATUS              EfiStatus;

+  UINT8                   *OpLen;

+  UINT8                   *OpPtr;

+

+  //

+  // Return error if parameters are invalid.

+  //

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (This->Data != NULL) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Check contents of provided Data structure.

+  //

+  if (Data != NULL) {

+    //

+    // Do protocol state checks first.

+    //

+    if (Data->SelectCompleted) {

+      if (!Data->InitCompleted || !Data->SetupCompleted) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if (Data->IsBootp && !Data->IsAck) {

+        return EFI_INVALID_PARAMETER;

+      }

+    } else if (Data->InitCompleted) {

+      if (!Data->SetupCompleted || Data->IsBootp || Data->IsAck) {

+        return EFI_INVALID_PARAMETER;

+      }

+    } else if (Data->SetupCompleted) {

+      if (Data->IsBootp || Data->IsAck) {

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+    //

+    // Do packet content checks.

+    //

+    if (Data->SetupCompleted) {

+      //

+      // %%TBD - check discover packet

+      //

+    }

+

+    if (Data->SelectCompleted) {

+      if (Data->IsBootp) {

+        //

+        // %%TBD - check offer packet

+        //

+        if (CompareMem (

+              &Data->Discover,

+              &Data->Request,

+              sizeof (DHCP4_PACKET)

+              )) {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        if (CompareMem (

+              &Data->Offer,

+              &Data->AckNak,

+              sizeof (DHCP4_PACKET)

+              )) {

+          return EFI_INVALID_PARAMETER;

+        }

+      } else {

+        //

+        // %%TBD - check offer, request & acknak packets

+        //

+      }

+    }

+  }

+  //

+  // Allocate data structure.  Return error

+  // if there is not enough available memory.

+  //

+  EfiStatus = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (EFI_PXE_DHCP4_DATA),

+                    (VOID **) &This->Data

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    This->Data = NULL;

+    return EfiStatus;

+  }

+

+  if (This->Data == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Start PxeBc because we want to use its UdpWrite, UdpRead and

+  // SetFilter calls.

+  //

+  EfiStatus = Private->PxeBc->Start (Private->PxeBc, FALSE);

+

+  if (EFI_ERROR (EfiStatus)) {

+    if (EfiStatus != EFI_ALREADY_STARTED) {

+      gBS->FreePool (This->Data);

+      This->Data = NULL;

+      Private->PxeBc->Stop (Private->PxeBc);

+      return EfiStatus;

+    }

+

+    Private->StopPxeBc = FALSE;

+  } else {

+    Private->StopPxeBc = TRUE;

+  }

+  //

+  // Use new data.

+  //

+  if (Data != NULL) {

+    CopyMem (This->Data, Data, sizeof (EFI_PXE_DHCP4_DATA));

+    return EFI_SUCCESS;

+  }

+  //

+  // Initialize new public data structure.

+  //

+  ZeroMem (This->Data, sizeof (EFI_PXE_DHCP4_DATA));

+

+  //

+  // Fill in default DHCP discover packet.

+  // Check for MAC addresses of strange lengths, just in case.

+  //

+  Packet        = &This->Data->Discover.dhcp4;

+

+  Packet->op    = BOOTP_REQUEST;

+

+  Packet->htype = Private->Snp->Mode->IfType;

+

+  if (Private->Snp->Mode->HwAddressSize > 16) {

+    Packet->hlen = 16;

+  } else {

+    Packet->hlen = (UINT8) Private->Snp->Mode->HwAddressSize;

+  }

+

+  Packet->hops = 0; /* Set to zero per RFC 2131. */

+

+  if (Packet->hlen < sizeof Packet->xid) {

+    if (Packet->hlen != 0) {

+      CopyMem (

+        &Packet->xid,

+        &Private->Snp->Mode->CurrentAddress,

+        Packet->hlen

+        );

+    }

+  } else {

+    CopyMem (

+      &Packet->xid,

+      &Private->Snp->Mode->CurrentAddress.Addr[Packet->hlen - sizeof Packet->xid],

+      sizeof Packet->xid

+      );

+  }

+  //

+  // %%TBD - xid should be randomized

+  //

+  Packet->secs  = htons (DHCP4_INITIAL_SECONDS);

+

+  Packet->flags = htons (DHCP4_BROADCAST_FLAG);

+

+  if (Packet->hlen != 0) {

+    CopyMem (Packet->chaddr, &Private->Snp->Mode->CurrentAddress, Packet->hlen);

+  }

+

+  Packet->magik               = htonl (DHCP4_MAGIK_NUMBER);

+

+  OpPtr                       = Packet->options;

+

+  *OpPtr++                    = DHCP4_MESSAGE_TYPE;

+  *OpPtr++                    = 1;

+  *OpPtr++                    = DHCP4_MESSAGE_TYPE_DISCOVER;

+

+  *OpPtr++                    = DHCP4_MAX_MESSAGE_SIZE;

+  *OpPtr++                    = 2;

+  *OpPtr++                    = (UINT8) ((DHCP4_DEFAULT_MAX_MESSAGE_SIZE >> 8) & 0xFF);

+  *OpPtr++                    = (UINT8) (DHCP4_DEFAULT_MAX_MESSAGE_SIZE & 0xFF);

+

+  *OpPtr++                    = DHCP4_PARAMETER_REQUEST_LIST;

+  OpLen                       = OpPtr;

+  *OpPtr++                    = 0;

+  *OpPtr++                    = DHCP4_SUBNET_MASK;

+  *OpPtr++                    = DHCP4_TIME_OFFSET;

+  *OpPtr++                    = DHCP4_ROUTER_LIST;

+  *OpPtr++                    = DHCP4_TIME_SERVERS;

+  *OpPtr++                    = DHCP4_NAME_SERVERS;

+  *OpPtr++                    = DHCP4_DNS_SERVERS;

+  *OpPtr++                    = DHCP4_HOST_NAME;

+  *OpPtr++                    = DHCP4_BOOT_FILE_SIZE;

+  *OpPtr++                    = DHCP4_MESSAGE_TYPE;

+  *OpPtr++                    = DHCP4_DOMAIN_NAME;

+  *OpPtr++                    = DHCP4_ROOT_PATH;

+  *OpPtr++                    = DHCP4_EXTENSION_PATH;

+  *OpPtr++                    = DHCP4_MAX_DATAGRAM_SIZE;

+  *OpPtr++                    = DHCP4_DEFAULT_TTL;

+  *OpPtr++                    = DHCP4_BROADCAST_ADDRESS;

+  *OpPtr++                    = DHCP4_NIS_DOMAIN_NAME;

+  *OpPtr++                    = DHCP4_NIS_SERVERS;

+  *OpPtr++                    = DHCP4_NTP_SERVERS;

+  *OpPtr++                    = DHCP4_VENDOR_SPECIFIC;

+  *OpPtr++                    = DHCP4_REQUESTED_IP_ADDRESS;

+  *OpPtr++                    = DHCP4_LEASE_TIME;

+  *OpPtr++                    = DHCP4_SERVER_IDENTIFIER;

+  *OpPtr++                    = DHCP4_RENEWAL_TIME;

+  *OpPtr++                    = DHCP4_REBINDING_TIME;

+  *OpPtr++                    = DHCP4_CLASS_IDENTIFIER;

+  *OpPtr++                    = DHCP4_TFTP_SERVER_NAME;

+  *OpPtr++                    = DHCP4_BOOTFILE;

+  *OpPtr++                    = 128;

+  *OpPtr++                    = 129;

+  *OpPtr++                    = 130;

+  *OpPtr++                    = 131;

+  *OpPtr++                    = 132;

+  *OpPtr++                    = 133;

+  *OpPtr++                    = 134;

+  *OpPtr++                    = 135;

+  *OpLen                      = (UINT8) ((OpPtr - OpLen) - 1);

+

+  *OpPtr++                    = DHCP4_END;

+

+  This->Data->SetupCompleted  = TRUE;

+

+  return EFI_SUCCESS;

+}

+

+/* eof - PxeDhcp4Setup.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/build.xml
new file mode 100644
index 0000000..086aefc
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Dhcp4"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Network/PxeDhcp4/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Dhcp4">

+      <GenBuild baseName="Dhcp4" mbdFilename="${MODULE_DIR}/Dhcp4.mbd" msaFilename="${MODULE_DIR}/Dhcp4.msa"/>

+   </target>

+   <target depends="Dhcp4_clean" name="clean"/>

+   <target depends="Dhcp4_cleanall" name="cleanall"/>

+   <target name="Dhcp4_clean">

+      <OutputDirSetup baseName="Dhcp4" mbdFilename="${MODULE_DIR}/Dhcp4.mbd" msaFilename="${MODULE_DIR}/Dhcp4.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Dhcp4_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Dhcp4_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Dhcp4_cleanall">

+      <OutputDirSetup baseName="Dhcp4" mbdFilename="${MODULE_DIR}/Dhcp4.mbd" msaFilename="${MODULE_DIR}/Dhcp4.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Dhcp4_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Dhcp4_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Dhcp4*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c
new file mode 100644
index 0000000..50c9913
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c
@@ -0,0 +1,1126 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  support.c

+  

+Abstract:

+  Miscellaneous support routines for PxeDhcp4 protocol.

+

+--*/

+

+

+#include "PxeDhcp4.h"

+

+#define DebugPrint(x)

+//

+// #define DebugPrint(x) Aprint x

+//

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+UINT16

+htons (

+  UINTN n

+  )

+{

+  return (UINT16) ((n >> 8) | (n << 8));

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+UINT32

+htonl (

+  UINTN n

+  )

+{

+  return (UINT32) ((n >> 24) | ((n >> 8) & 0xFF00) | ((n & 0xFF00) << 8) | (n << 24));

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+EFIAPI

+timeout_notify (

+  IN EFI_EVENT Event,

+  IN VOID      *Context

+  )

+{

+  ASSERT (Context);

+

+  if (Context != NULL) {

+    ((PXE_DHCP4_PRIVATE_DATA *) Context)->TimeoutOccurred = TRUE;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+EFIAPI

+periodic_notify (

+  IN EFI_EVENT Event,

+  IN VOID      *Context

+  )

+{

+  ASSERT (Context);

+

+  if (Context != NULL) {

+    ((PXE_DHCP4_PRIVATE_DATA *) Context)->PeriodicOccurred = TRUE;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+find_opt (

+  IN DHCP4_PACKET *Packet,

+  IN UINT8        OpCode,

+  IN UINTN        Skip,

+  OUT DHCP4_OP    **OpPtr

+  )

+/*++

+Routine description:

+  Locate option inside DHCP packet.

+

+Parameters:

+  Packet := Pointer to DHCP packet structure.

+  OpCode := Option op-code to find.

+  Skip := Number of found op-codes to skip.

+  OpPtr := Pointer to found op-code pointer.

+

+Returns:

+  EFI_SUCCESS := Option was found

+  EFI_INVALID_PARAMETER := Packet == NULL || OpPtr == NULL

+  EFI_INVALID_PARAMETER := OpCode == DHCP4_PAD

+  EFI_INVALID_PARAMETER := OpCode == DHCP4_END && Skip != 0

+  EFI_INVALID_PARAMETER := DHCP magik number in Packet is not valid

+  EFI_NOT_FOUND := op-code was not found in packet

+  EFI_INVALID_PARAMETER := If present, DHCP_MAX_MESSAGE_SIZE option

+    does not have a valid value.

+--*/

+{

+  UINTN msg_size;

+  UINTN buf_len;

+  UINTN n;

+  UINT8 *buf;

+  UINT8 *end_ptr;

+  UINT8 overload;

+

+  //

+  // Verify parameters.

+  //

+  if (Packet == NULL || OpPtr == NULL || OpCode == DHCP4_PAD || (OpCode == DHCP4_END && Skip != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Packet->dhcp4.magik != htonl (DHCP4_MAGIK_NUMBER)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Initialize search variables.

+  //

+  *OpPtr    = NULL;

+

+  msg_size  = DHCP4_MAX_PACKET_SIZE - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE);

+

+  overload  = 0;

+  end_ptr   = NULL;

+

+  buf       = Packet->dhcp4.options;

+  buf_len   = msg_size - (Packet->dhcp4.options - Packet->raw);

+

+  //

+  // Start searching for requested option.

+  //

+  for (n = 0;;) {

+    //

+    // If match is found, decrement skip count and return

+    // when desired match is found.

+    //

+    if (buf[n] == OpCode) {

+      *OpPtr = (DHCP4_OP *) &buf[n];

+

+      if (Skip-- == 0) {

+        return EFI_SUCCESS;

+      }

+    }

+    //

+    // Skip past current option.  Check for option overload

+    // and message size options since these will affect the

+    // amount of data to be searched.

+    //

+    switch (buf[n]) {

+    case DHCP4_PAD:

+      //

+      // Remember the first pad byte of a group.  This

+      // could be the end of a badly formed packet.

+      //

+      if (end_ptr == NULL) {

+        end_ptr = &buf[n];

+      }

+

+      ++n;

+      break;

+

+    case DHCP4_END:

+      //

+      // If we reach the end we are done.

+      //

+      end_ptr = NULL;

+      return EFI_NOT_FOUND;

+

+    case DHCP4_OPTION_OVERLOAD:

+      //

+      // Remember the option overload value since it

+      // could cause the search to continue into

+      // the fname and sname fields.

+      //

+      end_ptr = NULL;

+

+      if (buf[n + 1] == 1) {

+        overload = buf[n + 2];

+      }

+

+      n += 2 + buf[n + 1];

+      break;

+

+    case DHCP4_MAX_MESSAGE_SIZE:

+      //

+      // Remember the message size value since it could

+      // change the amount of option buffer to search.

+      //

+      end_ptr = NULL;

+

+      if (buf[n + 1] == 2 && buf == Packet->dhcp4.options) {

+        msg_size = ((buf[n + 2] << 8) | buf[n + 3]) - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE);

+

+        if (msg_size < 328) {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        buf_len = msg_size - (Packet->dhcp4.options - Packet->raw);

+

+        if (n + 2 + buf[n + 1] > buf_len) {

+          return EFI_INVALID_PARAMETER;

+        }

+      }

+

+    /* fall thru */

+    default:

+      end_ptr = NULL;

+

+      n += 2 + buf[n + 1];

+    }

+    //

+    // Keep searching until the end of the buffer is reached.

+    //

+    if (n < buf_len) {

+      continue;

+    }

+    //

+    // Reached end of current buffer.  Check if we are supposed

+    // to search the fname and sname buffers.

+    //

+    if (buf == Packet->dhcp4.options &&

+        (overload == DHCP4_OVERLOAD_FNAME || overload == DHCP4_OVERLOAD_FNAME_AND_SNAME)

+        ) {

+      buf     = Packet->dhcp4.fname;

+      buf_len = 128;

+      n       = 0;

+      continue;

+    }

+

+    if (buf != Packet->dhcp4.sname && (overload == DHCP4_OVERLOAD_SNAME || overload == DHCP4_OVERLOAD_FNAME_AND_SNAME)) {

+      buf     = Packet->dhcp4.sname;

+      buf_len = 64;

+      n       = 0;

+      continue;

+    }

+    //

+    // End of last buffer reached.  If this was a search

+    // for the end of the options, go back to the start

+    // of the current pad block.

+    //

+    if (OpCode == DHCP4_END && end_ptr != NULL) {

+      *OpPtr = (DHCP4_OP *) end_ptr;

+      return EFI_SUCCESS;

+    }

+

+    return EFI_NOT_FOUND;

+  }

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+add_opt (

+  IN DHCP4_PACKET *Packet,

+  IN DHCP4_OP     *OpPtr

+  )

+/*++

+Routine description:

+  Add option to DHCP packet.

+

+Parameters:

+  Packet := Pointer to DHCP packet structure.

+  OpPtr := Pointer to DHCP option.

+

+Returns:

+  EFI_INVALID_PARAMETER := Packet == NULL || OpPtr == NULL

+  EFI_INVALID_PARAMETER := OpPtr->op == DHCP4_PAD || OpPtr->op == DHCP4_END

+  EFI_INVALID_PARAMETER := DHCP magik number in DHCP packet is not valid

+  EFI_INVALID_PARAMETER := If DHCP_MAX_MESSAGE_SIZE option is present and

+    is not valid

+  EFI_INVALID_PARAMETER := If DHCP_OPTION_OVERLOAD option is present and

+    is not valid

+  EFI_DEVICE_ERROR := Cannot determine end of packet

+  EFI_BUFFER_TOO_SMALL := Not enough room in packet to add option

+  EFI_SUCCESS := Option added to DHCP packet

+--*/

+{

+  EFI_STATUS  efi_status;

+  DHCP4_OP    *msg_size_op;

+  DHCP4_OP    *overload_op;

+  DHCP4_OP    *op;

+  UINTN       msg_size;

+  UINTN       buf_len;

+  UINT32      magik;

+  UINT8       *buf;

+

+  //

+  // Verify parameters.

+  //

+  ASSERT (Packet);

+  ASSERT (OpPtr);

+

+  if (Packet == NULL || OpPtr == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  switch (OpPtr->op) {

+  case DHCP4_PAD:

+  case DHCP4_END:

+    //

+    // No adding PAD or END.

+    //

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Check the DHCP magik number.

+  //

+  CopyMem (&magik, &Packet->dhcp4.magik, 4);

+

+  if (magik != htonl (DHCP4_MAGIK_NUMBER)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the DHCP message size option.

+  //

+  msg_size = DHCP4_DEFAULT_MAX_MESSAGE_SIZE;

+

+  efi_status = find_opt (

+                Packet,

+                DHCP4_MAX_MESSAGE_SIZE,

+                0,

+                &msg_size_op

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    if (efi_status != EFI_NOT_FOUND) {

+      DebugPrint (

+        ("%s:%d:%r\n",

+        __FILE__,

+        __LINE__,

+        efi_status)

+        );

+      return efi_status;

+    }

+

+    msg_size_op = NULL;

+  } else {

+    CopyMem (&msg_size, msg_size_op->data, 2);

+    msg_size = htons (msg_size);

+

+    if (msg_size < DHCP4_DEFAULT_MAX_MESSAGE_SIZE) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Find the DHCP option overload option.

+  //

+  efi_status = find_opt (

+                Packet,

+                DHCP4_OPTION_OVERLOAD,

+                0,

+                &overload_op

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    if (efi_status != EFI_NOT_FOUND) {

+      DebugPrint (

+        ("%s:%d:%r\n",

+        __FILE__,

+        __LINE__,

+        efi_status)

+        );

+      return efi_status;

+    }

+

+    overload_op = NULL;

+  } else {

+    if (overload_op->len != 1) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    switch (overload_op->data[0]) {

+    case 1:

+    case 2:

+    case 3:

+      break;

+

+    default:

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Find the end of the packet.

+  //

+  efi_status = find_opt (Packet, DHCP4_END, 0, &op);

+

+  if (EFI_ERROR (efi_status)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find which buffer the end is in.

+  //

+  if ((UINTN) op >= (UINTN) (buf = Packet->dhcp4.options)) {

+    buf_len = (msg_size - ((UINT8 *) &Packet->dhcp4.options - (UINT8 *) &Packet->raw)) - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE);

+  } else if ((UINTN) op >= (UINTN) (buf = Packet->dhcp4.fname)) {

+    buf_len = 128;

+  } else if ((UINTN) op >= (UINTN) (buf = Packet->dhcp4.sname)) {

+    buf_len = 64;

+  } else {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Add option to current buffer if there is no overlow.

+  //

+  if ((UINTN) ((&op->op - buf) + 3 + op->len) < buf_len) {

+    CopyMem (op, OpPtr, OpPtr->len + 2);

+

+    op->data[op->len] = DHCP4_END;

+

+    return EFI_SUCCESS;

+  }

+  //

+  // Error if there is no space for option.

+  //

+  return EFI_BUFFER_TOO_SMALL;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+start_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN OPTIONAL EFI_IP_ADDRESS         *StationIp,

+  IN OPTIONAL EFI_IP_ADDRESS         *SubnetMask

+  )

+/*++

+Routine description:

+  Setup PXE BaseCode UDP stack.

+

+Parameters:

+  Private := Pointer to PxeDhcp4 private data.

+  StationIp := Pointer to IP address or NULL if not known.

+  SubnetMask := Pointer to subnet mask or NULL if not known.

+

+Returns:

+  EFI_INVALID_PARAMETER := Private == NULL || Private->PxeBc == NULL

+  EFI_INVALID_PARAMETER := Only one of StationIp and SubnetMask is given

+  EFI_SUCCESS := UDP stack is ready

+  other := Error from PxeBc->SetIpFilter() or PxeBc->SetStationIp()

+--*/

+{

+  EFI_PXE_BASE_CODE_IP_FILTER bcast_filter;

+  EFI_STATUS                  efi_status;

+

+  //

+  //

+  //

+  ASSERT (Private);

+  ASSERT (Private->PxeBc);

+

+  if (Private == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Private->PxeBc == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (StationIp != NULL && SubnetMask == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (StationIp == NULL && SubnetMask != NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Setup broadcast receive filter...

+  //

+  ZeroMem (&bcast_filter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER));

+

+  bcast_filter.Filters  = EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST;

+  bcast_filter.IpCnt    = 0;

+

+  efi_status = Private->PxeBc->SetIpFilter (

+                                Private->PxeBc,

+                                &bcast_filter

+                                );

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    return efi_status;

+  }

+  //

+  // Configure station IP address and subnet mask...

+  //

+  efi_status = Private->PxeBc->SetStationIp (

+                                Private->PxeBc,

+                                StationIp,

+                                SubnetMask

+                                );

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+  }

+

+  return efi_status;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+stop_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private

+  )

+{

+  //

+  //

+  //

+  ASSERT (Private);

+  ASSERT (Private->PxeBc);

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+start_receive_events (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN UINTN                  SecondsTimeout

+  )

+/*++

+Routine description:

+  Create periodic and timeout receive events.

+

+Parameters:

+  Private := Pointer to PxeDhcp4 private data.

+  SecondsTimeout := Number of seconds to wait before timeout.

+

+Returns:

+--*/

+{

+  EFI_STATUS  efi_status;

+  UINTN       random;

+

+  //

+  //

+  //

+  ASSERT (Private);

+  ASSERT (SecondsTimeout);

+

+  if (Private == NULL || SecondsTimeout == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Need a bettern randomizer...

+  // For now adjust the timeout value by the least significant

+  // digit in the MAC address.

+  //

+  random = 0;

+

+  if (Private->PxeDhcp4.Data != NULL) {

+    if (Private->PxeDhcp4.Data->Discover.dhcp4.hlen != 0 && Private->PxeDhcp4.Data->Discover.dhcp4.hlen <= 16) {

+      random = 0xFFF & Private->PxeDhcp4.Data->Discover.dhcp4.chaddr[Private->PxeDhcp4.Data->Discover.dhcp4.hlen - 1];

+    }

+  }

+  //

+  // Setup timeout event and start timer.

+  //

+  efi_status = gBS->CreateEvent (

+                      EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                      EFI_TPL_NOTIFY,

+                      &timeout_notify,

+                      Private,

+                      &Private->TimeoutEvent

+                      );

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    return efi_status;

+  }

+

+  efi_status = gBS->SetTimer (

+                      Private->TimeoutEvent,

+                      TimerRelative,

+                      SecondsTimeout * 10000000 + random

+                      );

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    gBS->CloseEvent (Private->TimeoutEvent);

+    return efi_status;

+  }

+

+  Private->TimeoutOccurred = FALSE;

+

+  //

+  // Setup periodic event for callbacks

+  //

+  efi_status = gBS->CreateEvent (

+                      EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                      EFI_TPL_NOTIFY,

+                      &periodic_notify,

+                      Private,

+                      &Private->PeriodicEvent

+                      );

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    gBS->CloseEvent (Private->TimeoutEvent);

+    return efi_status;

+  }

+

+  efi_status = gBS->SetTimer (

+                      Private->PeriodicEvent,

+                      TimerPeriodic,

+                      1000000

+                      );  /* 1/10th second */

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    gBS->CloseEvent (Private->TimeoutEvent);

+    gBS->CloseEvent (Private->PeriodicEvent);

+    return efi_status;

+  }

+

+  Private->PeriodicOccurred = FALSE;

+

+  return EFI_SUCCESS;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+VOID

+stop_receive_events (

+  IN PXE_DHCP4_PRIVATE_DATA *Private

+  )

+{

+  //

+  //

+  //

+  ASSERT (Private);

+

+  if (Private == NULL) {

+    return ;

+  }

+  //

+  //

+  //

+  gBS->CloseEvent (Private->TimeoutEvent);

+  Private->TimeoutOccurred = FALSE;

+

+  //

+  //

+  //

+  gBS->CloseEvent (Private->PeriodicEvent);

+  Private->PeriodicOccurred = FALSE;

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+tx_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN EFI_IP_ADDRESS         *dest_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *gateway_ip,

+  IN EFI_IP_ADDRESS         *src_ip,

+  IN VOID                   *buffer,

+  IN UINTN                  BufferSize

+  )

+/*++

+Routine description:

+  Transmit DHCP packet.

+

+Parameters:

+  Private := Pointer to PxeDhcp4 private data

+  dest_ip := Pointer to destination IP address

+  gateway_ip := Pointer to gateway IP address or NULL

+  src_ip := Pointer to source IP address or NULL

+  buffer := Pointer to buffer to transmit

+  BufferSize := Size of buffer in bytes

+

+Returns:

+  EFI_INVALID_PARAMETER := Private == NULL || dest_ip == NULL ||

+    buffer == NULL || BufferSize < 300 || Private->PxeBc == NULL

+  EFI_SUCCESS := Buffer was transmitted

+  other := Return from PxeBc->UdpWrite()

+--*/

+{

+  EFI_PXE_BASE_CODE_UDP_PORT  dest_port;

+  EFI_PXE_BASE_CODE_UDP_PORT  src_port;

+  EFI_IP_ADDRESS              zero_ip;

+

+  //

+  //

+  //

+  ASSERT (Private);

+  ASSERT (dest_ip);

+  ASSERT (buffer);

+  ASSERT (BufferSize >= 300);

+

+  if (Private == NULL || dest_ip == NULL || buffer == NULL || BufferSize < 300) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ASSERT (Private->PxeBc);

+

+  if (Private->PxeBc == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Transmit DHCP discover packet...

+  //

+  ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));

+

+  if (src_ip == NULL) {

+    src_ip = &zero_ip;

+  }

+

+  dest_port = DHCP4_SERVER_PORT;

+  src_port  = DHCP4_CLIENT_PORT;

+

+  return Private->PxeBc->UdpWrite (

+                          Private->PxeBc,

+                          EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,

+                          dest_ip,

+                          &dest_port,

+                          gateway_ip,

+                          src_ip,

+                          &src_port,

+                          NULL,

+                          NULL,

+                          &BufferSize,

+                          buffer

+                          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+rx_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  OUT VOID                  *buffer,

+  IN OUT UINTN              *BufferSize,

+  IN OUT EFI_IP_ADDRESS     *dest_ip,

+  IN OUT EFI_IP_ADDRESS     *src_ip,

+  IN UINT16                 op_flags

+  )

+/*++

+Routine description:

+  Receive DHCP packet.

+

+Parameters:

+  Private := Pointer to PxeDhcp4 private data

+  buffer := Pointer to buffer to receive DHCP packet

+  BufferSize := Pointer to buffer size in bytes

+  dest_ip := Pointer to destination IP address

+  src_ip := Pointer to source IP address

+  op_flags := UDP receive operation flags

+

+Returns:

+  EFI_INVALID_PARAMETER := 

+  EFI_SUCCESS := Packet received

+  other := Return from PxeBc->UdpRead()

+--*/

+{

+  EFI_PXE_BASE_CODE_UDP_PORT  dest_port;

+  EFI_PXE_BASE_CODE_UDP_PORT  src_port;

+

+  //

+  //

+  //

+  ASSERT (Private);

+  ASSERT (buffer);

+  ASSERT (dest_ip);

+  ASSERT (src_ip);

+

+  if (Private == NULL || buffer == NULL || dest_ip == NULL || src_ip == NULL || BufferSize == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ASSERT (Private->PxeBc);

+

+  if (Private->PxeBc == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Check for packet

+  //

+  *BufferSize = sizeof (DHCP4_PACKET);

+

+  dest_port   = DHCP4_CLIENT_PORT;

+  src_port    = DHCP4_SERVER_PORT;

+

+  return Private->PxeBc->UdpRead (

+                          Private->PxeBc,

+                          op_flags,

+                          dest_ip,

+                          &dest_port,

+                          src_ip,

+                          &src_port,

+                          NULL,

+                          NULL,

+                          BufferSize,

+                          buffer

+                          );

+}

+

+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

+EFI_STATUS

+tx_rx_udp (

+  IN PXE_DHCP4_PRIVATE_DATA *Private,

+  IN OUT EFI_IP_ADDRESS     *ServerIp,

+  IN OPTIONAL EFI_IP_ADDRESS         *gateway_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *client_ip,

+  IN OPTIONAL EFI_IP_ADDRESS         *SubnetMask,

+  IN DHCP4_PACKET           *tx_pkt,

+  OUT DHCP4_PACKET          *rx_pkt,

+  IN INTN (*rx_vfy)(

+      IN PXE_DHCP4_PRIVATE_DATA *Private,

+      IN DHCP4_PACKET *tx_pkt,

+      IN DHCP4_PACKET *rx_pkt,

+      IN UINTN rx_pkt_size

+    ),

+  IN UINTN SecondsTimeout

+  )

+/*++

+Routine description:

+  Transmit DHCP packet and wait for replies.

+

+Parameters:

+  Private := Pointer to PxeDhcp4 private data

+  ServerIp := Pointer to server IP address

+  gateway_ip := Pointer to gateway IP address or NULL

+  client_ip := Pointer to client IP address or NULL

+  SubnetMask := Pointer to subnet mask or NULL

+  tx_pkt := Pointer to DHCP packet to transmit

+  rx_pkt := Pointer to DHCP packet receive buffer

+  rx_vfy := Pointer to DHCP packet receive verification routine

+  SecondsTimeout := Number of seconds until timeout

+

+Returns:

+  EFI_INVALID_PARAMETER := Private == NULL || ServerIp == NULL || 

+    tx_pkt == NULL || rx_pkt == NULL || rx_vfy == NULL || Private->PxeBc == NULL

+  EFI_ABORTED := Receive aborted

+  EFI_TIMEOUT := No packets received

+  EFI_SUCCESS := Packet(s) received

+  other := Returns from other PxeDhcp4 support routines

+--*/

+{

+  EFI_PXE_DHCP4_CALLBACK_STATUS CallbackStatus;

+  EFI_IP_ADDRESS                dest_ip;

+  EFI_IP_ADDRESS                src_ip;

+  EFI_STATUS                    efi_status;

+  DHCP4_OP                      *msg_size_op;

+  UINTN                         pkt_size;

+  UINTN                         n;

+  UINT16                        msg_size;

+  UINT16                        op_flags;

+  BOOLEAN                       done_flag;

+  BOOLEAN                       got_packet;

+

+  //

+  // Bad programmer check...

+  //

+  ASSERT (Private);

+  ASSERT (ServerIp);

+  ASSERT (tx_pkt);

+  ASSERT (rx_pkt);

+  ASSERT (rx_vfy);

+

+  if (Private == NULL || ServerIp == NULL || tx_pkt == NULL || rx_pkt == NULL || rx_vfy == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ASSERT (Private->PxeBc);

+

+  if (Private->PxeBc == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Enable UDP...

+  //

+  efi_status = start_udp (Private, client_ip, SubnetMask);

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    return efi_status;

+  }

+  //

+  // Get length of transmit packet...

+  //

+  msg_size = DHCP4_DEFAULT_MAX_MESSAGE_SIZE;

+

+  efi_status = find_opt (

+                tx_pkt,

+                DHCP4_MAX_MESSAGE_SIZE,

+                0,

+                &msg_size_op

+                );

+

+  if (!EFI_ERROR (efi_status)) {

+    CopyMem (&msg_size, msg_size_op->data, 2);

+

+    if ((msg_size = htons (msg_size)) < 328) {

+      msg_size = 328;

+    }

+  }

+  //

+  // Transmit packet...

+  //

+  efi_status = tx_udp (

+                Private,

+                ServerIp,

+                gateway_ip,

+                client_ip,

+                tx_pkt,

+                msg_size - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE)

+                );

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    stop_udp (Private);

+    return efi_status;

+  }

+  //

+  // Enable periodic and timeout events...

+  //

+  efi_status = start_receive_events (Private, SecondsTimeout);

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    stop_udp (Private);

+    return efi_status;

+  }

+  //

+  // Wait for packet(s)...

+  //

+#if 0

+  if (!client_ip) {

+    Aprint ("client_ip == NULL    ");

+  } else {

+    Aprint (

+      "client_ip == %d.%d.%d.%d    ",

+      client_ip->v4.Addr[0],

+      client_ip->v4.Addr[1],

+      client_ip->v4.Addr[2],

+      client_ip->v4.Addr[3]

+      );

+  }

+

+  if (!ServerIp) {

+    Aprint ("ServerIp == NULL\n");

+  } else {

+    Aprint (

+      "ServerIp == %d.%d.%d.%d\n",

+      ServerIp->v4.Addr[0],

+      ServerIp->v4.Addr[1],

+      ServerIp->v4.Addr[2],

+      ServerIp->v4.Addr[3]

+      );

+  }

+#endif

+

+  done_flag   = FALSE;

+  got_packet  = FALSE;

+

+  while (!done_flag) {

+    //

+    // Check for timeout event...

+    //

+    if (Private->TimeoutOccurred) {

+      efi_status = EFI_SUCCESS;

+      break;

+    }

+    //

+    // Check for periodic event...

+    //

+    if (Private->PeriodicOccurred && Private->callback != NULL) {

+      CallbackStatus = EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE;

+

+      if (Private->callback->Callback != NULL) {

+        CallbackStatus = (Private->callback->Callback) (&Private->PxeDhcp4, Private->function, 0, NULL);

+      }

+

+      switch (CallbackStatus) {

+      case EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE:

+        break;

+

+      case EFI_PXE_DHCP4_CALLBACK_STATUS_ABORT:

+      default:

+        stop_receive_events (Private);

+        stop_udp (Private);

+        return EFI_ABORTED;

+      }

+

+      Private->PeriodicOccurred = FALSE;

+    }

+    //

+    // Check for packet...

+    //

+    if (client_ip == NULL) {

+      SetMem (&dest_ip, sizeof (EFI_IP_ADDRESS), 0xFF);

+    } else {

+      CopyMem (&dest_ip, client_ip, sizeof (EFI_IP_ADDRESS));

+    }

+

+    SetMem (&src_ip, sizeof (EFI_IP_ADDRESS), 0xFF);

+

+    if (CompareMem (&src_ip, &ServerIp, sizeof (EFI_IP_ADDRESS))) {

+      ZeroMem (&src_ip, sizeof (EFI_IP_ADDRESS));

+      op_flags = EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP;

+    } else {

+      op_flags = 0;

+    }

+

+    efi_status = rx_udp (

+                  Private,

+                  rx_pkt,

+                  &pkt_size,

+                  &dest_ip,

+                  &src_ip,

+                  op_flags

+                  );

+

+    if (efi_status == EFI_TIMEOUT) {

+      efi_status = EFI_SUCCESS;

+      continue;

+    }

+

+    if (EFI_ERROR (efi_status)) {

+      break;

+    }

+    //

+    // Some basic packet sanity checks..

+    //

+    if (pkt_size < 300) {

+      continue;

+    }

+

+    if (rx_pkt->dhcp4.op != BOOTP_REPLY) {

+      continue;

+    }

+

+    if (tx_pkt->dhcp4.htype != rx_pkt->dhcp4.htype) {

+      continue;

+    }

+

+    if ((n = tx_pkt->dhcp4.hlen) != rx_pkt->dhcp4.hlen) {

+      continue;

+    }

+

+    if (CompareMem (&tx_pkt->dhcp4.xid, &rx_pkt->dhcp4.xid, 4)) {

+      continue;

+    }

+

+    if (n != 0) {

+      if (n >= 16) {

+        n = 16;

+      }

+

+      if (CompareMem (tx_pkt->dhcp4.chaddr, rx_pkt->dhcp4.chaddr, n)) {

+        continue;

+      }

+    }

+    //

+    // Internal callback packet verification...

+    //

+    switch ((*rx_vfy) (Private, tx_pkt, rx_pkt, pkt_size)) {

+    case -2:  /* ignore and stop */

+      stop_receive_events (Private);

+      stop_udp (Private);

+      return EFI_ABORTED;

+

+    case -1:  /* ignore and wait */

+      continue;

+

+    case 0:   /* accept and wait */

+      break;

+

+    case 1:   /* accept and stop */

+      done_flag = TRUE;

+      break;

+

+    default:

+      ASSERT (0);

+    }

+    //

+    // External callback packet verification...

+    //

+    CallbackStatus = EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE;

+

+    if (Private->callback != NULL) {

+      if (Private->callback->Callback != NULL) {

+        CallbackStatus = (Private->callback->Callback) (&Private->PxeDhcp4, Private->function, (UINT32) pkt_size, rx_pkt);

+      }

+    }

+

+    switch (CallbackStatus) {

+    case EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_CONTINUE:

+      continue;

+

+    case EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_ABORT:

+      done_flag = TRUE;

+      break;

+

+    case EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_ABORT:

+      stop_receive_events (Private);

+      stop_udp (Private);

+      return EFI_ABORTED;

+

+    case EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE:

+    default:

+      break;

+    }

+    //

+    // We did!  We did get a packet!

+    //

+    got_packet = TRUE;

+  }

+  //

+  //

+  //

+  stop_receive_events (Private);

+  stop_udp (Private);

+

+  if (EFI_ERROR (efi_status)) {

+    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));

+    return efi_status;

+  }

+

+  if (got_packet) {

+    return EFI_SUCCESS;

+  } else {

+    return EFI_TIMEOUT;

+  }

+}

+

+/* eof - support.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/ComponentName.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/ComponentName.c
new file mode 100644
index 0000000..3cc2d98
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/ComponentName.c
@@ -0,0 +1,160 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "Snp.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+SimpleNetworkComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gSimpleNetworkComponentName = {

+  SimpleNetworkComponentNameGetDriverName,

+  SimpleNetworkComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameTable[] = {

+  {

+    "eng",

+    (CHAR16 *) L"Simple Network Protocol Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gSimpleNetworkComponentName.SupportedLanguages,

+          mSimpleNetworkDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.mbd b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.mbd
new file mode 100644
index 0000000..293812b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>SNP</BaseName>

+    <Guid>A2f436EA-A127-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.msa b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.msa
new file mode 100644
index 0000000..24957ed
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.msa
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>SNP</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>A2f436EA-A127-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>callback.c</Filename>

+    <Filename>get_status.c</Filename>

+    <Filename>initialize.c</Filename>

+    <Filename>mcast_ip_to_mac.c</Filename>

+    <Filename>nvdata.c</Filename>

+    <Filename>receive.c</Filename>

+    <Filename>receive_filters.c</Filename>

+    <Filename>reset.c</Filename>

+    <Filename>shutdown.c</Filename>

+    <Filename>snp.c</Filename>

+    <Filename>snp.h</Filename>

+    <Filename>start.c</Filename>

+    <Filename>station_address.c</Filename>

+    <Filename>statistics.c</Filename>

+    <Filename>stop.c</Filename>

+    <Filename>transmit.c</Filename>

+    <Filename>WaitForPacket.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="BY_START">SimpleNetwork</Protocol>

+    <Protocol Usage="TO_START">PciIo</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier</Protocol>

+    <Protocol Usage="TO_START">NetworkInterfaceIdentifier2</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+      <ModuleUnloadImage></ModuleUnloadImage>

+    </Extern>

+    <Extern>

+      <DriverBinding>mSimpleNetworkDriverBinding</DriverBinding>

+      <ComponentName>gSimpleNetworkComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/Snp.h b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/Snp.h
new file mode 100644
index 0000000..05c5a8b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/Snp.h
@@ -0,0 +1,410 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+    snp.h

+

+Abstract:

+

+Revision history:

+    2000-Feb-03 M(f)J   Genesis.

+--*/

+#ifndef _SNP_H

+#define _SNP_H

+

+

+#include "IndustryStandard/pci22.h"

+

+#define SNP_DEBUG       0

+#define FOUR_GIGABYTES  (UINT64) 0x100000000ULL

+

+#if SNP_DEBUG

+#undef D_NET

+#define D_NET                 D_WARN

+#define SNP_PRINT(DebugInfo)  Print (DebugInfo)

+#else

+#define SNP_PRINT(DebugInfo)

+#endif

+

+#define SNP_DRIVER_SIGNATURE  EFI_SIGNATURE_32 ('s', 'n', 'd', 's')

+#define MAX_MAP_LENGTH        100

+

+#define PCI_BAR_IO_MASK       0x00000003

+#define PCI_BAR_IO_MODE       0x00000001

+

+#define PCI_BAR_MEM_MASK      0x0000000F

+#define PCI_BAR_MEM_MODE      0x00000000

+#define PCI_BAR_MEM_64BIT     0x00000004

+

+typedef struct {

+  UINT32                      Signature;

+  EFI_LOCK                    lock;

+

+  EFI_SIMPLE_NETWORK_PROTOCOL snp;

+  EFI_SIMPLE_NETWORK_MODE     mode;

+

+  EFI_HANDLE                  device_handle;

+  EFI_DEVICE_PATH_PROTOCOL    *device_path;

+

+  //

+  //  Local instance data needed by SNP driver

+  //

+  //  Pointer to S/W UNDI API entry point

+  //  This will be NULL for H/W UNDI

+  //

+  EFI_STATUS (*issue_undi32_command) (UINT64 cdb);

+

+  BOOLEAN               is_swundi;

+

+  //

+  // undi interface number, if one undi manages more nics

+  //

+  PXE_IFNUM             if_num;

+

+  //

+  //  Allocated tx/rx buffer that was passed to UNDI Initialize.

+  //

+  UINT32                tx_rx_bufsize;

+  VOID                  *tx_rx_buffer;

+  //

+  // mappable buffers for receive and fill header for undi3.0

+  // these will be used if the user buffers are above 4GB limit (instead of

+  // mapping the user buffers)

+  //

+  UINT8                 *receive_buf;

+  VOID                  *ReceiveBufUnmap;

+  UINT8                 *fill_hdr_buf;

+  VOID                  *FillHdrBufUnmap;

+

+  EFI_PCI_IO_PROTOCOL   *IoFncs;

+  UINT8                 IoBarIndex;

+  UINT8                 MemoryBarIndex;

+  BOOLEAN               IsOldUndi;  // true for EFI1.0 UNDI (3.0) drivers

+  //

+  // Buffers for command descriptor block, command parameter block

+  // and data block.

+  //

+  PXE_CDB               cdb;

+  VOID                  *cpb;

+  VOID                  *CpbUnmap;

+  VOID                  *db;

+

+  //

+  // UNDI structure, we need to remember the init info for a long time!

+  //

+  PXE_DB_GET_INIT_INFO  init_info;

+

+  VOID                  *SnpDriverUnmap;

+  //

+  // when ever we map an address, we must remember it's address and the un-map

+  // cookie so that we can unmap later

+  //

+  struct s_map_list {

+    EFI_PHYSICAL_ADDRESS  virt;

+    VOID                  *map_cookie;

+  } map_list[MAX_MAP_LENGTH];

+}

+SNP_DRIVER;

+

+#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, snp, SNP_DRIVER_SIGNATURE)

+

+//

+// Global Variables

+//

+extern EFI_COMPONENT_NAME_PROTOCOL  gSimpleNetworkComponentName;

+extern EFI_DRIVER_BINDING_PROTOCOL  gSimpleNetworkDriverBinding;

+

+//

+//  Virtual to physical mapping for all UNDI 3.0s.

+//

+extern struct                       s_v2p {

+  struct s_v2p          *next;

+  VOID                  *vaddr;

+  UINTN                 bsize;

+  EFI_PHYSICAL_ADDRESS  paddr;

+  VOID                  *unmap;

+}

+*_v2p;

+

+EFI_STATUS

+add_v2p (

+  struct s_v2p                  **v2p,

+  EFI_PCI_IO_PROTOCOL_OPERATION type,

+  VOID                          *vaddr,

+  UINTN                         bsize

+  )

+;

+

+EFI_STATUS

+find_v2p (

+  struct s_v2p **v2p,

+  VOID         *vaddr

+  )

+;

+

+EFI_STATUS

+del_v2p (

+  VOID *vaddr

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_block_30 (

+  IN UINT32 Enable

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_delay_30 (

+  IN UINT64 MicroSeconds

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_memio_30 (

+  IN UINT8      ReadOrWrite,

+  IN UINT8      NumBytes,

+  IN UINT64     MemOrPortAddress,

+  IN OUT UINT64 BufferPtr

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_v2p_30 (

+  IN UINT64     CpuAddr,

+  IN OUT UINT64 DeviceAddrPtr

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_block (

+  IN UINT64 UniqueId,

+  IN UINT32 Enable

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_delay (

+  IN UINT64 UniqueId,

+  IN UINT64 MicroSeconds

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_memio (

+  IN UINT64     UniqueId,

+  IN UINT8      ReadOrWrite,

+  IN UINT8      NumBytes,

+  IN UINT64     MemOrPortAddr,

+  IN OUT UINT64 BufferPtr

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_map (

+  IN UINT64     UniqueId,

+  IN UINT64     CpuAddr,

+  IN UINT32     NumBytes,

+  IN UINT32     Direction,

+  IN OUT UINT64 DeviceAddrPtr

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_unmap (

+  IN UINT64             UniqueId,

+  IN UINT64             CpuAddr,

+  IN UINT32             NumBytes,

+  IN UINT32             Direction,

+  IN UINT64 DeviceAddr  // not a pointer to device address

+  )

+;

+

+extern

+VOID

+snp_undi32_callback_sync (

+  IN UINT64             UniqueId,

+  IN UINT64             CpuAddr,

+  IN UINT32             NumBytes,

+  IN UINT32             Direction,

+  IN UINT64 DeviceAddr  // not a pointer to device address

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_start (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_stop (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_initialize (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN UINTN                       extra_rx_buffer_size OPTIONAL,

+  IN UINTN                       extra_tx_buffer_size OPTIONAL

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_reset (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *this,

+  IN BOOLEAN                      ExtendedVerification

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_shutdown (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_receive_filters (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN UINT32                      enable,

+  IN UINT32                      disable,

+  IN BOOLEAN                     reset_mcast_filter,

+  IN UINTN                       mcast_filter_count OPTIONAL,

+  IN EFI_MAC_ADDRESS             * mcast_filter OPTIONAL

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_station_address (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN BOOLEAN                     reset,

+  IN EFI_MAC_ADDRESS             *new OPTIONAL

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_statistics (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL  * this,

+  IN BOOLEAN                      reset,

+  IN OUT UINTN                    *statistics_size OPTIONAL,

+  IN OUT EFI_NETWORK_STATISTICS   * statistics_table OPTIONAL

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_mcast_ip_to_mac (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN BOOLEAN                     IPv6,

+  IN EFI_IP_ADDRESS              *IP,

+  OUT EFI_MAC_ADDRESS            *MAC

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_nvdata (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN BOOLEAN                     read_write,

+  IN UINTN                       offset,

+  IN UINTN                       buffer_size,

+  IN OUT VOID                    *buffer

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_get_status (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  OUT UINT32                     *interrupt_status OPTIONAL,

+  OUT VOID                       **tx_buffer OPTIONAL

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_transmit (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN UINTN                       header_size,

+  IN UINTN                       buffer_size,

+  IN VOID                        *buffer,

+  IN EFI_MAC_ADDRESS             * src_addr OPTIONAL,

+  IN EFI_MAC_ADDRESS             * dest_addr OPTIONAL,

+  IN UINT16                      *protocol OPTIONAL

+  )

+;

+

+extern

+EFI_STATUS

+EFIAPI

+snp_undi32_receive (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  OUT UINTN                      *header_size OPTIONAL,

+  IN OUT UINTN                   *buffer_size,

+  OUT VOID                       *buffer,

+  OUT EFI_MAC_ADDRESS            * src_addr OPTIONAL,

+  OUT EFI_MAC_ADDRESS            * dest_addr OPTIONAL,

+  OUT UINT16                     *protocol OPTIONAL

+  )

+;

+

+typedef

+EFI_STATUS

+(*issue_undi32_command) (

+  UINT64 cdb

+  );

+typedef

+VOID

+(*ptr) (

+  VOID

+  );

+

+#define SNP_MEM_PAGES(x)  (((x) - 1) / 4096 + 1)

+

+#if SNP_DEBUG

+extern

+VOID

+snp_wait_for_key (

+  VOID

+  )

+;

+#endif

+

+#endif /*  _SNP_H  */

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/WaitForPacket.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/WaitForPacket.c
new file mode 100644
index 0000000..51a3bb8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/WaitForPacket.c
@@ -0,0 +1,100 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  WaitForPacket.c

+

+Abstract:

+  Event handler to check for available packet.

+

+--*/

+

+

+#include "Snp.h"

+

+VOID

+EFIAPI

+SnpWaitForPacketNotify (

+  EFI_EVENT Event,

+  VOID      *SnpPtr

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  PXE_DB_GET_STATUS PxeDbGetStatus;

+

+  //

+  // Do nothing if either parameter is a NULL pointer.

+  //

+  if (Event == NULL || SnpPtr == NULL) {

+    return ;

+  }

+  //

+  // Do nothing if the SNP interface is not initialized.

+  //

+  switch (((SNP_DRIVER *) SnpPtr)->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+  case EfiSimpleNetworkStarted:

+  default:

+    return ;

+  }

+  //

+  // Fill in CDB for UNDI GetStatus().

+  //

+  ((SNP_DRIVER *) SnpPtr)->cdb.OpCode     = PXE_OPCODE_GET_STATUS;

+  ((SNP_DRIVER *) SnpPtr)->cdb.OpFlags    = 0;

+  ((SNP_DRIVER *) SnpPtr)->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  ((SNP_DRIVER *) SnpPtr)->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  ((SNP_DRIVER *) SnpPtr)->cdb.DBsize     = sizeof (UINT32) * 2;

+  ((SNP_DRIVER *) SnpPtr)->cdb.DBaddr     = (UINT64) (UINTN) (((SNP_DRIVER *) SnpPtr)->db);

+  ((SNP_DRIVER *) SnpPtr)->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  ((SNP_DRIVER *) SnpPtr)->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  ((SNP_DRIVER *) SnpPtr)->cdb.IFnum      = ((SNP_DRIVER *) SnpPtr)->if_num;

+  ((SNP_DRIVER *) SnpPtr)->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Clear contents of DB buffer.

+  //

+  ZeroMem (((SNP_DRIVER *) SnpPtr)->db, sizeof (UINT32) * 2);

+

+  //

+  // Issue UNDI command and check result.

+  //

+  (*((SNP_DRIVER *) SnpPtr)->issue_undi32_command) ((UINT64) (UINTN) &((SNP_DRIVER *) SnpPtr)->cdb);

+

+  if (((SNP_DRIVER *) SnpPtr)->cdb.StatCode != EFI_SUCCESS) {

+    return ;

+  }

+  //

+  // We might have a packet.  Check the receive length and signal

+  // the event if the length is not zero.

+  //

+  CopyMem (

+    &PxeDbGetStatus,

+    ((SNP_DRIVER *) SnpPtr)->db,

+    sizeof (UINT32) * 2

+    );

+

+  if (PxeDbGetStatus.RxFrameLen != 0) {

+    gBS->SignalEvent (Event);

+  }

+}

+

+/* eof - WaitForPacket.c */

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/build.xml
new file mode 100644
index 0000000..74b81f4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="SNP"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Network/Snp32_64/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="SNP">

+      <GenBuild baseName="SNP" mbdFilename="${MODULE_DIR}/SNP.mbd" msaFilename="${MODULE_DIR}/SNP.msa"/>

+   </target>

+   <target depends="SNP_clean" name="clean"/>

+   <target depends="SNP_cleanall" name="cleanall"/>

+   <target name="SNP_clean">

+      <OutputDirSetup baseName="SNP" mbdFilename="${MODULE_DIR}/SNP.mbd" msaFilename="${MODULE_DIR}/SNP.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/SNP_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/SNP_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="SNP_cleanall">

+      <OutputDirSetup baseName="SNP" mbdFilename="${MODULE_DIR}/SNP.mbd" msaFilename="${MODULE_DIR}/SNP.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/SNP_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/SNP_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**SNP*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/callback.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/callback.c
new file mode 100644
index 0000000..65a4d58
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/callback.c
@@ -0,0 +1,613 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+ callback.c

+

+Abstract:

+ This file contains two sets of callback routines for undi3.0 and undi3.1.

+ the callback routines for Undi3.1 have an extra parameter UniqueId which

+ stores the interface context for the NIC that snp is trying to talk..

+

+--*/

+

+

+#include "Snp.h"

+

+//

+// Global variables

+// these 2 global variables are used only for 3.0 undi. we could not place

+// them in the snp structure because we will not know which snp structure

+// in the callback context!

+//

+STATIC BOOLEAN              mInitializeLock = TRUE;

+STATIC EFI_LOCK             mLock;

+

+//

+// End Global variables

+//

+extern EFI_PCI_IO_PROTOCOL  *mPciIoFncs;

+

+VOID

+snp_undi32_callback_v2p_30 (

+  IN UINT64     CpuAddr,

+  IN OUT UINT64 DeviceAddrPtr

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ UNDI call this routine with a virtual or CPU address that SNP provided

+ to convert it to a physical or device address. Since EFI uses the identical

+ mapping, this routine returns the physical address same as the virtual address

+ for most of the addresses. an address above 4GB cannot generally be used as a

+ device address, it needs to be mapped to a lower physical address. This routine

+ does not call the map routine itself, but it assumes that the mapping was done

+ at the time of providing the address to UNDI. This routine just looks up the

+ address in a map table (which is the v2p structure chain)

+

+Arguments:

+ CpuAddr - virtual address of a buffer

+ DeviceAddrPtr - pointer to the physical address

+

+Returns:

+ void - The DeviceAddrPtr will contain 0 in case of any error

+

+--*/

+{

+  struct s_v2p  *v2p;

+  //

+  // Do nothing if virtual address is zero or physical pointer is NULL.

+  // No need to map if the virtual address is within 4GB limit since

+  // EFI uses identical mapping

+  //

+  if ((CpuAddr == 0) || (DeviceAddrPtr == 0)) {

+    DEBUG ((EFI_D_ERROR, "\nv2p: Null virtual address or physical pointer.\n"));

+    return ;

+  }

+

+  if (CpuAddr < FOUR_GIGABYTES) {

+    *(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;

+    return ;

+  }

+  //

+  // SNP creates a vaddr tp paddr mapping at the time of calling undi with any

+  // big address, this callback routine just looks up in the v2p list and

+  // returns the physical address for any given virtual address.

+  //

+  if (find_v2p (&v2p, (VOID *) (UINTN) CpuAddr) != EFI_SUCCESS) {

+    *(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;

+  } else {

+    *(UINT64 *) (UINTN) DeviceAddrPtr = v2p->paddr;

+  }

+}

+

+VOID

+snp_undi32_callback_block_30 (

+  IN UINT32 Enable

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ UNDI call this routine when it wants to have exclusive access to a critical

+ section of the code/data

+

+Arguments:

+ Enable - non-zero indicates acquire

+          zero indicates release

+

+Returns:

+ void

+--*/

+{

+  //

+  // tcpip was calling snp at tpl_notify and if we acquire a lock that was

+  // created at a lower level (TPL_CALLBACK) it gives an assert!

+  //

+  if (mInitializeLock) {

+    EfiInitializeLock (&mLock, EFI_TPL_NOTIFY);

+    mInitializeLock = FALSE;

+  }

+

+  if (Enable != 0) {

+    EfiAcquireLock (&mLock);

+  } else {

+    EfiReleaseLock (&mLock);

+  }

+}

+

+VOID

+snp_undi32_callback_delay_30 (

+  IN UINT64 MicroSeconds

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ UNDI call this routine with the number of micro seconds when it wants to

+ pause.

+

+Arguments:

+ MicroSeconds - number of micro seconds to pause, ususlly multiple of 10

+

+Returns:

+ void

+--*/

+{

+  if (MicroSeconds != 0) {

+    gBS->Stall ((UINTN) MicroSeconds);

+  }

+}

+

+VOID

+snp_undi32_callback_memio_30 (

+  IN UINT8      ReadOrWrite,

+  IN UINT8      NumBytes,

+  IN UINT64     Address,

+  IN OUT UINT64 BufferAddr

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ This is the IO routine for UNDI. This is not currently being used by UNDI3.0

+ because Undi3.0 uses io/mem offsets relative to the beginning of the device

+ io/mem address and so it needs to use the PCI_IO_FUNCTION that abstracts the

+ start of the device's io/mem addresses. Since SNP cannot retrive the context

+ of the undi3.0 interface it cannot use the PCI_IO_FUNCTION that specific for

+ that NIC and uses one global IO functions structure, this does not work.

+ This however works fine for EFI1.0 Undis because they use absolute addresses

+ for io/mem access.

+

+Arguments:

+  ReadOrWrite - indicates read or write, IO or Memory

+  NumBytes    - number of bytes to read or write

+  Address     - IO or memory address to read from or write to

+  BufferAddr  - memory location to read into or that contains the bytes

+                to write

+

+Returns:

+

+--*/

+{

+  EFI_PCI_IO_PROTOCOL_WIDTH Width;

+

+  switch (NumBytes) {

+  case 2:

+    Width = 1;

+    break;

+

+  case 4:

+    Width = 2;

+    break;

+

+  case 8:

+    Width = 3;

+    break;

+

+  default:

+    Width = 0;

+  }

+

+  switch (ReadOrWrite) {

+  case PXE_IO_READ:

+    mPciIoFncs->Io.Read (

+                    mPciIoFncs,

+                    Width,

+                    1,    // BAR 1, IO base address

+                    Address,

+                    1,    // count

+                    (VOID *) (UINTN) BufferAddr

+                    );

+    break;

+

+  case PXE_IO_WRITE:

+    mPciIoFncs->Io.Write (

+                    mPciIoFncs,

+                    Width,

+                    1,    // BAR 1, IO base address

+                    Address,

+                    1,    // count

+                    (VOID *) (UINTN) BufferAddr

+                    );

+    break;

+

+  case PXE_MEM_READ:

+    mPciIoFncs->Mem.Read (

+                      mPciIoFncs,

+                      Width,

+                      0,  // BAR 0, Memory base address

+                      Address,

+                      1,  // count

+                      (VOID *) (UINTN) BufferAddr

+                      );

+    break;

+

+  case PXE_MEM_WRITE:

+    mPciIoFncs->Mem.Write (

+                      mPciIoFncs,

+                      Width,

+                      0,  // BAR 0, Memory base address

+                      Address,

+                      1,  // count

+                      (VOID *) (UINTN) BufferAddr

+                      );

+    break;

+  }

+

+  return ;

+}

+//

+// New callbacks for 3.1:

+// there won't be a virtual2physical callback for UNDI 3.1 because undi3.1 uses

+// the MemMap call to map the required address by itself!

+//

+VOID

+snp_undi32_callback_block (

+  IN UINT64 UniqueId,

+  IN UINT32 Enable

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI3.1 at undi_start time.

+ UNDI call this routine when it wants to have exclusive access to a critical

+ section of the code/data

+

+Arguments:

+ UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store

+            Undi interface context (Undi does not read or write this variable)

+ Enable   - non-zero indicates acquire

+            zero indicates release

+

+Returns:

+ void

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  snp = (SNP_DRIVER *) (UINTN) UniqueId;

+  //

+  // tcpip was calling snp at tpl_notify and when we acquire a lock that was

+  // created at a lower level (TPL_CALLBACK) it gives an assert!

+  //

+  if (Enable != 0) {

+    EfiAcquireLock (&snp->lock);

+  } else {

+    EfiReleaseLock (&snp->lock);

+  }

+}

+

+VOID

+snp_undi32_callback_delay (

+  IN UINT64 UniqueId,

+  IN UINT64 MicroSeconds

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ UNDI call this routine with the number of micro seconds when it wants to

+ pause.

+

+Arguments:

+ MicroSeconds - number of micro seconds to pause, ususlly multiple of 10

+

+Returns:

+ void

+--*/

+{

+  if (MicroSeconds != 0) {

+    gBS->Stall ((UINTN) MicroSeconds);

+  }

+}

+

+/*

+ *  IO routine for UNDI start CPB.

+ */

+VOID

+snp_undi32_callback_memio (

+  UINT64 UniqueId,

+  UINT8  ReadOrWrite,

+  UINT8  NumBytes,

+  UINT64 Address,

+  UINT64 BufferAddr

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ This is the IO routine for UNDI3.1.

+

+Arguments:

+  ReadOrWrite - indicates read or write, IO or Memory

+  NumBytes    - number of bytes to read or write

+  Address     - IO or memory address to read from or write to

+  BufferAddr  - memory location to read into or that contains the bytes

+                to write

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER                *snp;

+  EFI_PCI_IO_PROTOCOL_WIDTH Width;

+

+  snp   = (SNP_DRIVER *) (UINTN) UniqueId;

+

+  Width = 0;

+  switch (NumBytes) {

+  case 2:

+    Width = 1;

+    break;

+

+  case 4:

+    Width = 2;

+    break;

+

+  case 8:

+    Width = 3;

+    break;

+  }

+

+  switch (ReadOrWrite) {

+  case PXE_IO_READ:

+    snp->IoFncs->Io.Read (

+                      snp->IoFncs,

+                      Width,

+                      snp->IoBarIndex,      // BAR 1 (for 32bit regs), IO base address

+                      Address,

+                      1,                    // count

+                      (VOID *) (UINTN) BufferAddr

+                      );

+    break;

+

+  case PXE_IO_WRITE:

+    snp->IoFncs->Io.Write (

+                      snp->IoFncs,

+                      Width,

+                      snp->IoBarIndex,      // BAR 1 (for 32bit regs), IO base address

+                      Address,

+                      1,                    // count

+                      (VOID *) (UINTN) BufferAddr

+                      );

+    break;

+

+  case PXE_MEM_READ:

+    snp->IoFncs->Mem.Read (

+                      snp->IoFncs,

+                      Width,

+                      snp->MemoryBarIndex,  // BAR 0, Memory base address

+                      Address,

+                      1,                    // count

+                      (VOID *) (UINTN) BufferAddr

+                      );

+    break;

+

+  case PXE_MEM_WRITE:

+    snp->IoFncs->Mem.Write (

+                      snp->IoFncs,

+                      Width,

+                      snp->MemoryBarIndex,  // BAR 0, Memory base address

+                      Address,

+                      1,                    // count

+                      (VOID *) (UINTN) BufferAddr

+                      );

+    break;

+  }

+

+  return ;

+}

+

+VOID

+snp_undi32_callback_map (

+  IN UINT64     UniqueId,

+  IN UINT64     CpuAddr,

+  IN UINT32     NumBytes,

+  IN UINT32     Direction,

+  IN OUT UINT64 DeviceAddrPtr

+  )

+/*++

+

+Routine Description:

+  This is a callback routine supplied to UNDI at undi_start time.

+  UNDI call this routine when it has to map a CPU address to a device

+  address.

+

+Arguments:

+  UniqueId      - This was supplied to UNDI at Undi_Start, SNP uses this to store

+                  Undi interface context (Undi does not read or write this variable)

+  CpuAddr       - Virtual address to be mapped!

+  NumBytes      - size of memory to be mapped

+  Direction     - direction of data flow for this memory's usage:

+                  cpu->device, device->cpu or both ways

+  DeviceAddrPtr - pointer to return the mapped device address

+

+Returns:

+  None

+

+--*/

+{

+  EFI_PHYSICAL_ADDRESS          *DevAddrPtr;

+  EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag;

+  UINTN                         BuffSize;

+  SNP_DRIVER                    *snp;

+  UINTN                         Index;

+  EFI_STATUS                    Status;

+

+  BuffSize    = (UINTN) NumBytes;

+  snp         = (SNP_DRIVER *) (UINTN) UniqueId;

+  DevAddrPtr  = (EFI_PHYSICAL_ADDRESS *) (UINTN) DeviceAddrPtr;

+

+  if (CpuAddr == 0) {

+    *DevAddrPtr = 0;

+    return ;

+  }

+

+  switch (Direction) {

+  case TO_AND_FROM_DEVICE:

+    DirectionFlag = EfiPciIoOperationBusMasterCommonBuffer;

+    break;

+

+  case FROM_DEVICE:

+    DirectionFlag = EfiPciIoOperationBusMasterWrite;

+    break;

+

+  case TO_DEVICE:

+    DirectionFlag = EfiPciIoOperationBusMasterRead;

+    break;

+

+  default:

+    *DevAddrPtr = 0;

+    //

+    // any non zero indicates error!

+    //

+    return ;

+  }

+  //

+  // find an unused map_list entry

+  //

+  for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {

+    if (snp->map_list[Index].virt == 0) {

+      break;

+    }

+  }

+

+  if (Index >= MAX_MAP_LENGTH) {

+    SNP_PRINT (L"SNP maplist is FULL\n");

+    *DevAddrPtr = 0;

+    return ;

+  }

+

+  snp->map_list[Index].virt = (EFI_PHYSICAL_ADDRESS) CpuAddr;

+

+  Status = snp->IoFncs->Map (

+                          snp->IoFncs,

+                          DirectionFlag,

+                          (VOID *) (UINTN) CpuAddr,

+                          &BuffSize,

+                          DevAddrPtr,

+                          &(snp->map_list[Index].map_cookie)

+                          );

+  if (Status != EFI_SUCCESS) {

+    *DevAddrPtr               = 0;

+    snp->map_list[Index].virt = 0;

+  }

+

+  return ;

+}

+

+VOID

+snp_undi32_callback_unmap (

+  IN UINT64 UniqueId,

+  IN UINT64 CpuAddr,

+  IN UINT32 NumBytes,

+  IN UINT32 Direction,

+  IN UINT64 DeviceAddr

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ UNDI call this routine when it wants to unmap an address that was previously

+ mapped using map callback

+

+Arguments:

+ UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store

+            Undi interface context (Undi does not read or write this variable)

+ CpuAddr  - Virtual address that was mapped!

+ NumBytes - size of memory mapped

+ Direction- direction of data flow for this memory's usage:

+            cpu->device, device->cpu or both ways

+ DeviceAddr - the mapped device address

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+  UINT16      Index;

+

+  snp = (SNP_DRIVER *) (UINTN) UniqueId;

+

+  for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {

+    if (snp->map_list[Index].virt == CpuAddr) {

+      break;

+    }

+  }

+

+  if (Index >= MAX_MAP_LENGTH)

+  {

+#if SNP_DEBUG

+    Print (L"SNP could not find a mapping, failed to unmap.\n");

+#endif

+    return ;

+  }

+

+  snp->IoFncs->Unmap (snp->IoFncs, snp->map_list[Index].map_cookie);

+  snp->map_list[Index].virt       = 0;

+  snp->map_list[Index].map_cookie = NULL;

+  return ;

+}

+

+VOID

+snp_undi32_callback_sync (

+  UINT64 UniqueId,

+  UINT64 CpuAddr,

+  UINT32 NumBytes,

+  UINT32 Direction,

+  UINT64 DeviceAddr

+  )

+/*++

+

+Routine Description:

+ This is a callback routine supplied to UNDI at undi_start time.

+ UNDI call this routine when it wants synchronize the virtual buffer contents

+ with the mapped buffer contents. The virtual and mapped buffers need not

+ correspond to the same physical memory (especially if the virtual address is

+ > 4GB). Depending on the direction for which the buffer is mapped, undi will

+ need to synchronize their contents whenever it writes to/reads from the buffer

+ using either the cpu address or the device address.

+

+ EFI does not provide a sync call, since virt=physical, we sould just do

+ the synchronization ourself here!

+

+Arguments:

+ UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store

+            Undi interface context (Undi does not read or write this variable)

+ CpuAddr  - Virtual address that was mapped!

+ NumBytes - size of memory mapped

+ Direction- direction of data flow for this memory's usage:

+            cpu->device, device->cpu or both ways

+ DeviceAddr - the mapped device address

+

+Returns:

+

+--*/

+{

+  if ((CpuAddr == 0) || (DeviceAddr == 0) || (NumBytes == 0)) {

+    return ;

+

+  }

+

+  switch (Direction) {

+  case FROM_DEVICE:

+    CopyMem ((UINT8 *) (UINTN) CpuAddr, (UINT8 *) (UINTN) DeviceAddr, NumBytes);

+    break;

+

+  case TO_DEVICE:

+    CopyMem ((UINT8 *) (UINTN) DeviceAddr, (UINT8 *) (UINTN) CpuAddr, NumBytes);

+    break;

+  }

+

+  return ;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/get_status.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/get_status.c
new file mode 100644
index 0000000..6d89d4c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/get_status.c
@@ -0,0 +1,193 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  get_status.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-03 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_getstatus (

+  SNP_DRIVER *snp,

+  UINT32     *InterruptStatusPtr,

+  VOID       **TransmitBufferListPtr

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to get the status of the interrupts, get the list of

+ transmit buffers that completed transmitting! 

+

+Arguments:

+ snp  - pointer to snp driver structure

+ InterruptStatusPtr - a non null pointer gets the interrupt status

+ TransmitBufferListPtrs - a non null ointer gets the list of pointers of previously 

+              transmitted buffers whose transmission was completed 

+              asynchrnously.

+              

+Returns:

+

+--*/

+{

+  PXE_DB_GET_STATUS *db;

+  UINT16            InterruptFlags;

+  UINT64            TempData;

+

+  db                = snp->db;

+  snp->cdb.OpCode   = PXE_OPCODE_GET_STATUS;

+

+  snp->cdb.OpFlags  = 0;

+

+  if (TransmitBufferListPtr != NULL) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;

+  }

+

+  if (InterruptStatusPtr != NULL) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_GET_INTERRUPT_STATUS;

+  }

+

+  snp->cdb.CPBsize  = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.CPBaddr  = PXE_CPBADDR_NOT_USED;

+

+  //

+  // size DB for return of one buffer

+  //

+  snp->cdb.DBsize = (UINT16) (((UINT16) (sizeof (PXE_DB_GET_STATUS)) - (UINT16) (sizeof db->TxBuffer)) + (UINT16) (sizeof db->TxBuffer[0]));

+

+  snp->cdb.DBaddr     = (UINT64) (UINTN) db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.get_status()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != EFI_SUCCESS) {

+    DEBUG (

+      (EFI_D_NET,

+      "\nsnp->undi.get_status()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatFlags)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // report the values back..

+  //

+  if (InterruptStatusPtr != NULL) {

+    InterruptFlags      = (UINT16) (snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK);

+

+    *InterruptStatusPtr = 0;

+

+    if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_RECEIVE) {

+      *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;

+    }

+

+    if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_TRANSMIT) {

+      *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;

+    }

+

+    if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_COMMAND) {

+      *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;

+    }

+

+    if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_SOFTWARE) {

+      *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;

+    }

+

+  }

+

+  if (TransmitBufferListPtr != NULL) {

+    *TransmitBufferListPtr =

+      (

+        (snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) ||

+        (snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY)

+      ) ? 0 : (VOID *) (UINTN) db->TxBuffer[0];

+

+    TempData = (UINT64) (UINTN) (*TransmitBufferListPtr);

+    if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {

+      del_v2p ((VOID *) (UINTN) (db->TxBuffer[0]));

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_get_status (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  OUT UINT32                     *InterruptStatusPtr OPTIONAL,

+  OUT VOID                       **TransmitBufferListPtr OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for getting the status

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_getstatus routine to actually get the undi status

+

+Arguments:

+ this  - context pointer

+ InterruptStatusPtr - a non null pointer gets the interrupt status

+ TransmitBufferListPtrs - a non null ointer gets the list of pointers of previously 

+              transmitted buffers whose transmission was completed 

+              asynchrnously.

+              

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (InterruptStatusPtr == NULL && TransmitBufferListPtr == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return pxe_getstatus (snp, InterruptStatusPtr, TransmitBufferListPtr);

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/initialize.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/initialize.c
new file mode 100644
index 0000000..cb80171
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/initialize.c
@@ -0,0 +1,244 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  initialize.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-09 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+VOID

+EFIAPI

+SnpWaitForPacketNotify (

+  IN EFI_EVENT  Event,

+  IN VOID       *SnpPtr

+  );

+

+EFI_STATUS

+pxe_init (

+  SNP_DRIVER *snp,

+  UINT16     CableDetectFlag

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to initialize the interface.

+

+Arguments:

+ snp  - pointer to snp driver structure

+ CableDetectFlag - Do/don't detect the cable (depending on what undi supports)

+

+Returns:

+

+--*/

+{

+  PXE_CPB_INITIALIZE  *cpb;

+  VOID                *addr;

+  EFI_STATUS          Status;

+

+  cpb = snp->cpb;

+  if (snp->tx_rx_bufsize != 0) {

+    Status = snp->IoFncs->AllocateBuffer (

+                            snp->IoFncs,

+                            AllocateAnyPages,

+                            EfiBootServicesData,

+                            SNP_MEM_PAGES (snp->tx_rx_bufsize),

+                            &addr,

+                            0

+                            );

+

+    if (Status != EFI_SUCCESS) {

+      DEBUG (

+        (EFI_D_ERROR,

+        "\nsnp->pxe_init()  AllocateBuffer  %xh (%r)\n",

+        Status,

+        Status)

+        );

+

+      return Status;

+    }

+

+    ASSERT (addr);

+

+    snp->tx_rx_buffer = addr;

+  }

+

+  cpb->MemoryAddr   = (UINT64) (UINTN) snp->tx_rx_buffer;

+

+  cpb->MemoryLength = snp->tx_rx_bufsize;

+

+  //

+  // let UNDI decide/detect these values

+  //

+  cpb->LinkSpeed      = 0;

+  cpb->TxBufCnt       = 0;

+  cpb->TxBufSize      = 0;

+  cpb->RxBufCnt       = 0;

+  cpb->RxBufSize      = 0;

+

+  cpb->DuplexMode         = PXE_DUPLEX_DEFAULT;

+

+  cpb->LoopBackMode       = LOOPBACK_NORMAL;

+

+  snp->cdb.OpCode     = PXE_OPCODE_INITIALIZE;

+  snp->cdb.OpFlags    = CableDetectFlag;

+

+  snp->cdb.CPBsize    = sizeof (PXE_CPB_INITIALIZE);

+  snp->cdb.DBsize     = sizeof (PXE_DB_INITIALIZE);

+

+  snp->cdb.CPBaddr    = (UINT64) (UINTN) snp->cpb;

+  snp->cdb.DBaddr     = (UINT64) (UINTN) snp->db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  DEBUG ((EFI_D_NET, "\nsnp->undi.initialize()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode == PXE_STATCODE_SUCCESS) {

+    snp->mode.State = EfiSimpleNetworkInitialized;

+

+    Status          = EFI_SUCCESS;

+  } else {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nsnp->undi.initialize()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    if (snp->tx_rx_buffer != NULL) {

+      snp->IoFncs->FreeBuffer (

+                    snp->IoFncs,

+                    SNP_MEM_PAGES (snp->tx_rx_bufsize),

+                    (VOID *) snp->tx_rx_buffer

+                    );

+    }

+

+    snp->tx_rx_buffer = NULL;

+

+    Status            = EFI_DEVICE_ERROR;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_initialize (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN UINTN                       extra_rx_buffer_size OPTIONAL,

+  IN UINTN                       extra_tx_buffer_size OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for initializing the interface

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_initialize routine to actually do the undi initialization

+

+Arguments:

+ this  - context pointer

+ extra_rx_buffer_size - optional parameter, indicates extra space for rx_buffers

+ extra_tx_buffer_size - optional parameter, indicates extra space for tx_buffers

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  EfiStatus;

+  SNP_DRIVER  *snp;

+

+  //

+  //

+  //

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  //

+  //

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkStarted:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkInitialized:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //

+  //

+  EfiStatus = gBS->CreateEvent (

+                    EFI_EVENT_NOTIFY_WAIT,

+                    EFI_TPL_NOTIFY,

+                    &SnpWaitForPacketNotify,

+                    snp,

+                    &snp->snp.WaitForPacket

+                    );

+

+  if (EFI_ERROR (EfiStatus)) {

+    snp->snp.WaitForPacket = NULL;

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //

+  //

+  snp->mode.MCastFilterCount      = 0;

+  snp->mode.ReceiveFilterSetting  = 0;

+  ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);

+  CopyMem (

+    &snp->mode.CurrentAddress,

+    &snp->mode.PermanentAddress,

+    sizeof (EFI_MAC_ADDRESS)

+    );

+

+  //

+  // Compute tx/rx buffer sizes based on UNDI init info and parameters.

+  //

+  snp->tx_rx_bufsize = (UINT32) (snp->init_info.MemoryRequired + extra_rx_buffer_size + extra_tx_buffer_size);

+

+  if (snp->mode.MediaPresentSupported) {

+    if (pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {

+      snp->mode.MediaPresent = TRUE;

+      return EFI_SUCCESS;

+    }

+  }

+

+  snp->mode.MediaPresent  = FALSE;

+

+  EfiStatus               = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);

+

+  if (EFI_ERROR (EfiStatus)) {

+    gBS->CloseEvent (snp->snp.WaitForPacket);

+  }

+

+  return EfiStatus;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/mcast_ip_to_mac.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/mcast_ip_to_mac.c
new file mode 100644
index 0000000..11b29f4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/mcast_ip_to_mac.c
@@ -0,0 +1,167 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  mcast_ip_to_mac.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-17 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_ip2mac (

+  IN SNP_DRIVER          *snp,

+  IN BOOLEAN             IPv6,

+  IN EFI_IP_ADDRESS      *IP,

+  IN OUT EFI_MAC_ADDRESS *MAC

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to convert an multicast IP address to a MAC address

+

+Arguments:

+  snp  - pointer to snp driver structure

+  IPv6  - flag to indicate if this is an ipv6 address

+  IP    - multicast IP address

+  MAC   - pointer to hold the return MAC address

+

+Returns:

+

+--*/

+{

+  PXE_CPB_MCAST_IP_TO_MAC *cpb;

+  PXE_DB_MCAST_IP_TO_MAC  *db;

+

+  cpb                 = snp->cpb;

+  db                  = snp->db;

+  snp->cdb.OpCode     = PXE_OPCODE_MCAST_IP_TO_MAC;

+  snp->cdb.OpFlags    = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);

+  snp->cdb.CPBsize    = sizeof (PXE_CPB_MCAST_IP_TO_MAC);

+  snp->cdb.DBsize     = sizeof (PXE_DB_MCAST_IP_TO_MAC);

+

+  snp->cdb.CPBaddr    = (UINT64) (UINTN) cpb;

+  snp->cdb.DBaddr     = (UINT64) (UINTN) db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  CopyMem (&cpb->IP, IP, sizeof (PXE_IP_ADDR));

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.mcast_ip_to_mac()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  switch (snp->cdb.StatCode) {

+  case PXE_STATCODE_SUCCESS:

+    break;

+

+  case PXE_STATCODE_INVALID_CPB:

+    return EFI_INVALID_PARAMETER;

+

+  case PXE_STATCODE_UNSUPPORTED:

+    DEBUG (

+      (EFI_D_NET,

+      "\nsnp->undi.mcast_ip_to_mac()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+    return EFI_UNSUPPORTED;

+

+  default:

+    //

+    // UNDI command failed.  Return EFI_DEVICE_ERROR

+    // to caller.

+    //

+    DEBUG (

+      (EFI_D_NET,

+      "\nsnp->undi.mcast_ip_to_mac()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  CopyMem (MAC, &db->MAC, sizeof (PXE_MAC_ADDR));

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_mcast_ip_to_mac (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN BOOLEAN                     IPv6,

+  IN EFI_IP_ADDRESS              *IP,

+  OUT EFI_MAC_ADDRESS            *MAC

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for converting a multicast IP address to

+ a MAC address.

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_ip2mac routine to actually do the conversion

+

+Arguments:

+  this  - context pointer

+  IPv6  - flag to indicate if this is an ipv6 address

+  IP    - multicast IP address

+  MAC   - pointer to hold the return MAC address

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  //

+  // Get pointer to SNP driver instance for *this.

+  //

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (IP == NULL || MAC == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return pxe_ip2mac (snp, IPv6, IP, MAC);

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/nvdata.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/nvdata.c
new file mode 100644
index 0000000..e9302da
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/nvdata.c
@@ -0,0 +1,183 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  nvdata.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-03 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_nvdata_read (

+  IN SNP_DRIVER *snp,

+  IN UINTN      RegOffset,

+  IN UINTN      NumBytes,

+  IN OUT VOID   *BufferPtr

+  )

+/*++

+

+Routine Description:

+ This routine calls Undi to read the desired number of eeprom bytes.

+

+Arguments:

+  snp  - pointer to the snp driver structure

+  RegOffset  - eeprom register value relative to the base address

+  NumBytes  - number of bytes to read

+  BufferPtr - pointer where to read into

+

+Returns:

+

+--*/

+{

+  PXE_DB_NVDATA *db;

+

+  db                  = snp->db;

+  snp->cdb.OpCode     = PXE_OPCODE_NVDATA;

+

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NVDATA_READ;

+

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+

+  snp->cdb.DBsize     = sizeof (PXE_DB_NVDATA);

+  snp->cdb.DBaddr     = (UINT64) (UINTN) db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.nvdata ()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  switch (snp->cdb.StatCode) {

+  case PXE_STATCODE_SUCCESS:

+    break;

+

+  case PXE_STATCODE_UNSUPPORTED:

+    DEBUG (

+      (EFI_D_NET,

+      "\nsnp->undi.nvdata()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_UNSUPPORTED;

+

+  default:

+    DEBUG (

+      (EFI_D_NET,

+      "\nsnp->undi.nvdata()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  CopyMem (BufferPtr, db->Data.Byte + RegOffset, NumBytes);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_nvdata (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN BOOLEAN                     ReadOrWrite,

+  IN UINTN                       RegOffset,

+  IN UINTN                       NumBytes,

+  IN OUT VOID                    *BufferPtr

+  )

+/*++

+

+Routine Description:

+ This is an interface call provided by SNP.

+ It does the basic checking on the input parameters and retrieves snp structure

+ and then calls the read_nvdata() call which does the actual reading

+

+Arguments:

+  this  - context pointer

+  ReadOrWrite - true for reading and false for writing

+  RegOffset  - eeprom register relative to the base

+  NumBytes - how many bytes to read

+  BufferPtr - address of memory to read into

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  //

+  // Get pointer to SNP driver instance for *this.

+  //

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Return error if the SNP is not initialized.

+  //

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Return error if non-volatile memory variables are not valid.

+  //

+  if (snp->mode.NvRamSize == 0 || snp->mode.NvRamAccessSize == 0) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Check for invalid parameter combinations.

+  //

+  if ((NumBytes == 0) ||

+      (BufferPtr == NULL) ||

+      (RegOffset >= snp->mode.NvRamSize) ||

+      (RegOffset + NumBytes > snp->mode.NvRamSize) ||

+      (NumBytes % snp->mode.NvRamAccessSize != 0) ||

+      (RegOffset % snp->mode.NvRamAccessSize != 0)

+      ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // check the implementation flags of undi if we can write the nvdata!

+  //

+  if (!ReadOrWrite) {

+    return EFI_UNSUPPORTED;

+  } else {

+    return pxe_nvdata_read (snp, RegOffset, NumBytes, BufferPtr);

+  }

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive.c
new file mode 100644
index 0000000..2d92dde
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive.c
@@ -0,0 +1,255 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+    receive.c

+

+Abstract:

+

+Revision history:

+    2000-Feb-03 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_receive (

+  SNP_DRIVER      *snp,

+  VOID            *BufferPtr,

+  UINTN           *BuffSizePtr,

+  UINTN           *HeaderSizePtr,

+  EFI_MAC_ADDRESS *SourceAddrPtr,

+  EFI_MAC_ADDRESS *DestinationAddrPtr,

+  UINT16          *ProtocolPtr

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to receive a packet and fills in the data in the

+ input pointers!

+ 

+Arguments:

+  snp  - pointer to snp driver structure

+  BufferPtr   - pointer to the memory for the received data

+  BuffSizePtr - is a pointer to the length of the buffer on entry and contains

+                the length of the received data on return

+  HeaderSizePtr - pointer to the header portion of the data received.

+  SourceAddrPtr    - optional parameter, is a pointer to contain the source

+                ethernet address on return

+  DestinationAddrPtr   - optional parameter, is a pointer to contain the destination

+                ethernet address on return

+  ProtocolPtr    - optional parameter, is a pointer to contain the protocol type

+                from the ethernet header on return

+

+

+Returns:

+

+--*/

+{

+  PXE_CPB_RECEIVE *cpb;

+  PXE_DB_RECEIVE  *db;

+  UINTN           buf_size;

+  UINT64          TempData;

+

+  cpb       = snp->cpb;

+  db        = snp->db;

+  buf_size  = *BuffSizePtr;

+  //

+  // IMPORTANT NOTE:

+  // In case of the older 3.0 UNDI, if the input buffer address is beyond 4GB,

+  // DO NOT call the map function on the given buffer, instead use

+  // a global buffer. The reason is that UNDI3.0 has some unnecessary check of

+  // making sure that all the addresses (whether or not they will be given

+  // to the NIC ) supplied to it are below 4GB. It may or may not use

+  // the mapped address after all (like in case of CPB and DB)!

+  // Instead of using the global buffer whose address is allocated within the

+  // 2GB limit if I start mapping the given buffer we lose the data, here is

+  // why!!!

+  // if our address is > 4GB, the map call creates another buffer below 2GB and

+  // copies data to/from the original buffer to the mapped buffer either at

+  // map time or unmap time depending on the map direction.

+  // UNDI will not complain since we already mapped the buffer to be

+  // within the 2GB limit but will not use (I know undi) the mapped address

+  // since it does not give the user buffers to the NIC's receive unit,

+  // It just copies the received packet into the user buffer using the virtual

+  // (CPU) address rather than the mapped (device or physical) address.

+  // When the UNDI call returns, if we then unmap the buffer, we will lose

+  // the contents because unmap copies the contents of the mapped buffer into

+  // the original buffer (since the direction is FROM_DEVICE) !!!

+  //

+  // this is not a problem in Undi 3.1 because this undi uses it's map callback

+  // routine to map a cpu address to device address and it does it only if

+  // it is giving the address to the device and unmaps it before using the cpu

+  // address!

+  //

+  TempData = (UINT64) (UINTN) BufferPtr;

+  if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {

+    cpb->BufferAddr = (UINT64) (UINTN) snp->receive_buf;

+    cpb->BufferLen  = (UINT32) (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);

+  } else {

+    cpb->BufferAddr = (UINT64) (UINTN) BufferPtr;

+    cpb->BufferLen  = (UINT32) *BuffSizePtr;

+  }

+

+  cpb->reserved       = 0;

+

+  snp->cdb.OpCode     = PXE_OPCODE_RECEIVE;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+

+  snp->cdb.CPBsize    = sizeof (PXE_CPB_RECEIVE);

+  snp->cdb.CPBaddr    = (UINT64) (UINTN) cpb;

+

+  snp->cdb.DBsize     = sizeof (PXE_DB_RECEIVE);

+  snp->cdb.DBaddr     = (UINT64) (UINTN) db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_INFO, "\nsnp->undi.receive ()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  switch (snp->cdb.StatCode) {

+  case PXE_STATCODE_SUCCESS:

+    break;

+

+  case PXE_STATCODE_NO_DATA:

+    DEBUG (

+      (EFI_D_INFO,

+      "\nsnp->undi.receive ()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_NOT_READY;

+

+  default:

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.receive()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  *BuffSizePtr = db->FrameLen;

+

+  if (HeaderSizePtr != NULL) {

+    *HeaderSizePtr = db->MediaHeaderLen;

+  }

+

+  if (SourceAddrPtr != NULL) {

+    CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);

+  }

+

+  if (DestinationAddrPtr != NULL) {

+    CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);

+  }

+

+  if (ProtocolPtr != NULL) {

+    *ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /*  we need to do the byte swapping */

+  }

+

+  TempData = (UINT64) (UINTN) BufferPtr;

+  if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {

+    CopyMem (BufferPtr, snp->receive_buf, snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);

+  }

+

+  return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_receive (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  OUT UINTN                      *HeaderSizePtr OPTIONAL,

+  IN OUT UINTN                   *BuffSizePtr,

+  OUT VOID                       *BufferPtr,

+  OUT EFI_MAC_ADDRESS            * SourceAddrPtr OPTIONAL,

+  OUT EFI_MAC_ADDRESS            * DestinationAddrPtr OPTIONAL,

+  OUT UINT16                     *ProtocolPtr OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for receiving network data.

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_receive routine to actually do the receive!

+

+Arguments:

+  this  - context pointer

+  HeaderSizePtr - optional parameter and is a pointer to the header portion of

+                the data received.

+  BuffSizePtr - is a pointer to the length of the buffer on entry and contains

+                the length of the received data on return

+  BufferPtr   - pointer to the memory for the received data

+  SourceAddrPtr    - optional parameter, is a pointer to contain the source

+                ethernet address on return

+  DestinationAddrPtr   - optional parameter, is a pointer to contain the destination

+                ethernet address on return

+  ProtocolPtr    - optional parameter, is a pointer to contain the protocol type

+                from the ethernet header on return

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (!snp->mode.ReceiveFilterSetting) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return pxe_receive (

+          snp,

+          BufferPtr,

+          BuffSizePtr,

+          HeaderSizePtr,

+          SourceAddrPtr,

+          DestinationAddrPtr,

+          ProtocolPtr

+          );

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive_filters.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive_filters.c
new file mode 100644
index 0000000..6e234de
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive_filters.c
@@ -0,0 +1,411 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  receive_filters.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-17 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_rcvfilter_enable (

+  SNP_DRIVER      *snp,

+  UINT32          EnableFlags,

+  UINTN           MCastAddressCount,

+  EFI_MAC_ADDRESS *MCastAddressList

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to enable the receive filters.

+

+Arguments:

+  snp  - pointer to snp driver structure

+  EnableFlags - bit mask for enabling the receive filters

+  MCastAddressCount - multicast address count for a new multicast address list

+  MCastAddressList  - list of new multicast addresses

+

+Returns:

+

+--*/

+{

+  snp->cdb.OpCode     = PXE_OPCODE_RECEIVE_FILTERS;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;

+  }

+

+  if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;

+  }

+

+  if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;

+  }

+

+  if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;

+  }

+

+  if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;

+  }

+

+  if (MCastAddressCount != 0) {

+    snp->cdb.CPBsize  = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));

+    snp->cdb.CPBaddr  = (UINT64) (UINTN) snp->cpb;

+    CopyMem (snp->cpb, MCastAddressList, snp->cdb.CPBsize);

+  }

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != EFI_SUCCESS) {

+    //

+    // UNDI command failed.  Return UNDI status to caller.

+    //

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.receive_filters()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    switch (snp->cdb.StatCode) {

+    case PXE_STATCODE_INVALID_CDB:

+    case PXE_STATCODE_INVALID_CPB:

+    case PXE_STATCODE_INVALID_PARAMETER:

+      return EFI_INVALID_PARAMETER;

+

+    case PXE_STATCODE_UNSUPPORTED:

+      return EFI_UNSUPPORTED;

+    }

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+pxe_rcvfilter_disable (

+  SNP_DRIVER *snp,

+  UINT32     DisableFlags,

+  BOOLEAN    ResetMCastList

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to disable the receive filters.

+

+Arguments:

+  snp  - pointer to snp driver structure

+  DisableFlags - bit mask for disabling the receive filters

+  ResetMCastList - boolean flag to reset/delete the multicast filter list

+

+Returns:

+

+--*/

+{

+  snp->cdb.OpCode     = PXE_OPCODE_RECEIVE_FILTERS;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  snp->cdb.OpFlags    = (UINT16) (DisableFlags ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);

+

+  if (ResetMCastList) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;

+  }

+

+  if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;

+  }

+

+  if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;

+  }

+

+  if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;

+  }

+

+  if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;

+  }

+

+  if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {

+    snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;

+  }

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != EFI_SUCCESS) {

+    //

+    // UNDI command failed.  Return UNDI status to caller.

+    //

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.receive_filters()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+pxe_rcvfilter_read (

+  SNP_DRIVER *snp

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to read the receive filters.

+

+Arguments:

+  snp  - pointer to snp driver structure

+

+Returns:

+

+--*/

+{

+  snp->cdb.OpCode   = PXE_OPCODE_RECEIVE_FILTERS;

+  snp->cdb.OpFlags  = PXE_OPFLAGS_RECEIVE_FILTER_READ;

+  snp->cdb.CPBsize  = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize   = (UINT16) (snp->mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));

+  snp->cdb.CPBaddr  = PXE_CPBADDR_NOT_USED;

+  if (snp->cdb.DBsize == 0) {

+    snp->cdb.DBaddr = (UINT64) NULL;

+  } else {

+    snp->cdb.DBaddr = (UINT64) (UINTN) snp->db;

+    ZeroMem (snp->db, snp->cdb.DBsize);

+  }

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != EFI_SUCCESS) {

+    //

+    // UNDI command failed.  Return UNDI status to caller.

+    //

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.receive_filters()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Convert UNDI32 StatFlags to EFI SNP filter flags.

+  //

+  snp->mode.ReceiveFilterSetting = 0;

+

+  if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {

+    snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;

+  }

+

+  if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {

+    snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;

+  }

+

+  if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {

+    snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;

+  }

+

+  if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {

+    snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;

+  }

+

+  if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {

+    snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;

+  }

+

+  CopyMem (snp->mode.MCastFilter, snp->db, snp->cdb.DBsize);

+

+  //

+  // Count number of active entries in multicast filter list.

+  //

+  {

+    EFI_MAC_ADDRESS ZeroMacAddr;

+

+    SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);

+

+    for (snp->mode.MCastFilterCount = 0;

+         snp->mode.MCastFilterCount < snp->mode.MaxMCastFilterCount;

+         snp->mode.MCastFilterCount++

+        ) {

+      if (CompareMem (

+            &snp->mode.MCastFilter[snp->mode.MCastFilterCount],

+            &ZeroMacAddr,

+            sizeof ZeroMacAddr

+            ) == 0) {

+        break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_receive_filters (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN UINT32                      EnableFlags,

+  IN UINT32                      DisableFlags,

+  IN BOOLEAN                     ResetMCastList,

+  IN UINTN                       MCastAddressCount OPTIONAL,

+  IN EFI_MAC_ADDRESS             * MCastAddressList OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for reading/enabling/disabling the

+ receive filters.

+ This routine basically retrieves snp structure, checks the SNP state and

+ checks the parameter validity, calls one of the above routines to actually

+ do the work

+

+Arguments:

+  this  - context pointer

+  EnableFlags - bit mask for enabling the receive filters

+  DisableFlags - bit mask for disabling the receive filters

+  ResetMCastList - boolean flag to reset/delete the multicast filter list

+  MCastAddressCount - multicast address count for a new multicast address list

+  MCastAddressList  - list of new multicast addresses

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+  EFI_STATUS  Status;

+

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // check if we are asked to enable or disable something that the UNDI

+  // does not even support!

+  //

+  if ((EnableFlags &~snp->mode.ReceiveFilterMask) != 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((DisableFlags &~snp->mode.ReceiveFilterMask) != 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (ResetMCastList) {

+    DisableFlags |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & snp->mode.ReceiveFilterMask;

+    MCastAddressCount = 0;

+    MCastAddressList  = NULL;

+  } else {

+    if (MCastAddressCount != 0) {

+      if (MCastAddressCount > snp->mode.MaxMCastFilterCount) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if (MCastAddressList == NULL) {

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+

+  if (EnableFlags == 0 && DisableFlags == 0 && !ResetMCastList && MCastAddressCount == 0) {

+    return EFI_SUCCESS;

+  }

+

+  if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastAddressCount == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((EnableFlags != 0) || (MCastAddressCount != 0)) {

+    Status = pxe_rcvfilter_enable (

+              snp,

+              EnableFlags,

+              MCastAddressCount,

+              MCastAddressList

+              );

+

+    if (Status != EFI_SUCCESS) {

+      return Status;

+    }

+  }

+

+  if ((DisableFlags != 0) || ResetMCastList) {

+    Status = pxe_rcvfilter_disable (snp, DisableFlags, ResetMCastList);

+

+    if (Status != EFI_SUCCESS) {

+      return Status;

+    }

+  }

+

+  return pxe_rcvfilter_read (snp);

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/reset.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/reset.c
new file mode 100644
index 0000000..a8dace6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/reset.c
@@ -0,0 +1,129 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  reset.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-09 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_reset (

+  SNP_DRIVER *snp

+  )

+/*++

+

+Routine Description:

+ This routine calls undi to reset the nic.

+

+Arguments:

+ snp - pointer to the snp driver structure

+

+Returns:

+ EFI_SUCCESSFUL for a successful completion

+ other for failed calls

+

+--*/

+{

+  snp->cdb.OpCode     = PXE_OPCODE_RESET;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.reset()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nsnp->undi32.reset()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    //

+    // UNDI could not be reset. Return UNDI error.

+    //

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_reset (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this,

+  IN BOOLEAN                     ExtendedVerification

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for resetting the NIC

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_reset routine to actually do the reset!

+

+Arguments:

+ this - context pointer

+ ExtendedVerification - not implemented

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  //

+  // Resolve Warning 4 unreferenced parameter problem

+  //

+  ExtendedVerification = 0;

+

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  return pxe_reset (snp);

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/shutdown.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/shutdown.c
new file mode 100644
index 0000000..5d7a4b2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/shutdown.c
@@ -0,0 +1,152 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  shutdown.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-14 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_shutdown (

+  IN SNP_DRIVER *snp

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to shut down the interface.

+

+Arguments:

+  snp  - pointer to snp driver structure

+

+Returns:

+

+--*/

+{

+  snp->cdb.OpCode     = PXE_OPCODE_SHUTDOWN;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.shutdown()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    //

+    // UNDI could not be shutdown. Return UNDI error.

+    //

+    DEBUG ((EFI_D_WARN, "\nsnp->undi.shutdown()  %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));

+

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Free allocated memory.

+  //

+  if (snp->tx_rx_buffer != NULL) {

+    snp->IoFncs->FreeBuffer (

+                  snp->IoFncs,

+                  SNP_MEM_PAGES (snp->tx_rx_bufsize),

+                  (VOID *) snp->tx_rx_buffer

+                  );

+  }

+

+  snp->tx_rx_buffer   = NULL;

+  snp->tx_rx_bufsize  = 0;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_shutdown (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for shutting down the interface

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_shutdown routine to actually do the undi shutdown

+

+Arguments:

+  this  - context pointer

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+  EFI_STATUS  status;

+

+  //

+  //

+  //

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //

+  //

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  //

+  //

+  status                          = pxe_shutdown (snp);

+

+  snp->mode.State                 = EfiSimpleNetworkStarted;

+  snp->mode.ReceiveFilterSetting  = 0;

+

+  snp->mode.MCastFilterCount      = 0;

+  snp->mode.ReceiveFilterSetting  = 0;

+  ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);

+  CopyMem (

+    &snp->mode.CurrentAddress,

+    &snp->mode.PermanentAddress,

+    sizeof (EFI_MAC_ADDRESS)

+    );

+

+  gBS->CloseEvent (snp->snp.WaitForPacket);

+

+  return status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.c
new file mode 100644
index 0000000..c193730
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.c
@@ -0,0 +1,1315 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+    snp.c

+

+Abstract:

+

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_start (

+  SNP_DRIVER *snp

+  );

+EFI_STATUS

+pxe_stop (

+  SNP_DRIVER *snp

+  );

+EFI_STATUS

+pxe_init (

+  SNP_DRIVER *snp,

+  UINT16     OpFlags

+  );

+EFI_STATUS

+pxe_shutdown (

+  SNP_DRIVER *snp

+  );

+EFI_STATUS

+pxe_get_stn_addr (

+  SNP_DRIVER *snp

+  );

+

+EFI_STATUS

+EFIAPI

+InitializeSnpNiiDriver (

+  IN EFI_HANDLE       image_handle,

+  IN EFI_SYSTEM_TABLE *system_table

+  );

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  );

+

+//

+// Simple Network Protocol Driver Global Variables

+//

+EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {

+  SimpleNetworkDriverSupported,

+  SimpleNetworkDriverStart,

+  SimpleNetworkDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+//

+//  Module global variables needed to support undi 3.0 interface

+//

+EFI_PCI_IO_PROTOCOL         *mPciIoFncs;

+struct s_v2p                *_v2p = NULL; // undi3.0 map_list head

+// End Global variables

+//

+EFI_STATUS

+add_v2p (

+  IN OUT struct s_v2p           **v2p,

+  EFI_PCI_IO_PROTOCOL_OPERATION type,

+  VOID                          *vaddr,

+  UINTN                         bsize

+  )

+/*++

+

+Routine Description:

+ This routine maps the given CPU address to a Device address. It creates a

+ an entry in the map list with the virtual and physical addresses and the 

+ un map cookie.

+

+Arguments:

+ v2p - pointer to return a map list node pointer.

+ type - the direction in which the data flows from the given virtual address

+        device->cpu or cpu->device or both ways.

+ vaddr - virtual address (or CPU address) to be mapped

+ bsize - size of the buffer to be mapped.

+

+Returns:

+

+  EFI_SUCEESS - routine has completed the mapping

+  other - error as indicated.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  if ((v2p == NULL) || (vaddr == NULL) || (bsize == 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (struct s_v2p),

+                  (VOID **) v2p

+                  );

+

+  if (Status != EFI_SUCCESS) {

+    return Status;

+  }

+

+  Status = mPciIoFncs->Map (

+                        mPciIoFncs,

+                        type,

+                        vaddr,

+                        &bsize,

+                        &(*v2p)->paddr,

+                        &(*v2p)->unmap

+                        );

+  if (Status != EFI_SUCCESS) {

+    gBS->FreePool (*v2p);

+    return Status;

+  }

+  (*v2p)->vaddr = vaddr;

+  (*v2p)->bsize = bsize;

+  (*v2p)->next  = _v2p;

+  _v2p          = *v2p;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+find_v2p (

+  struct s_v2p **v2p,

+  VOID         *vaddr

+  )

+/*++

+

+Routine Description:

+ This routine searches the linked list of mapped address nodes (for undi3.0 

+ interface) to find the node that corresponds to the given virtual address and

+ returns a pointer to that node.

+

+Arguments:

+ v2p - pointer to return a map list node pointer.

+ vaddr - virtual address (or CPU address) to be searched in the map list

+

+Returns:

+

+  EFI_SUCEESS - if a match found!

+  Other       - match not found

+

+--*/

+{

+  struct s_v2p  *v;

+

+  if (v2p == NULL || vaddr == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  for (v = _v2p; v != NULL; v = v->next) {

+    if (v->vaddr == vaddr) {

+      *v2p = v;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+del_v2p (

+  VOID *vaddr

+  )

+/*++

+

+Routine Description:

+ This routine unmaps the given virtual address and frees the memory allocated 

+ for the map list node corresponding to that address.

+ 

+Arguments:

+ vaddr - virtual address (or CPU address) to be unmapped

+

+Returns:

+ EFI_SUCEESS -  if successfully unmapped

+ Other - as indicated by the error

+

+

+--*/

+{

+  struct s_v2p  *v;

+  struct s_v2p  *t;

+  EFI_STATUS    Status;

+

+  if (vaddr == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (_v2p == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Is our node at the head of the list??

+  //

+  if ((v = _v2p)->vaddr == vaddr) {

+    _v2p    = _v2p->next;

+

+    Status  = mPciIoFncs->Unmap (mPciIoFncs, v->unmap);

+

+    gBS->FreePool (v);

+

+#if SNP_DEBUG

+    if (Status) {

+      Print (L"Unmap failed with status = %x\n", Status);

+    }

+#endif

+    return Status;

+  }

+

+  for (; v->next != NULL; v = t) {

+    if ((t = v->next)->vaddr == vaddr) {

+      v->next = t->next;

+      Status  = mPciIoFncs->Unmap (mPciIoFncs, t->unmap);

+      gBS->FreePool (t);

+#if SNP_DEBUG

+      if (Status) {

+        Print (L"Unmap failed with status = %x\n", Status);

+      }

+#endif

+      return Status;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+#if SNP_DEBUG

+VOID

+snp_wait_for_key (

+  VOID

+  )

+/*++

+

+Routine Description:

+ Wait for a key stroke, used for debugging purposes

+

+Arguments:

+ none

+

+Returns:

+ none

+

+--*/

+{

+  EFI_INPUT_KEY key;

+

+  Aprint ("\nPress any key to continue\n");

+

+  while (gST->ConIn->ReadKeyStroke (gST->ConIn, &key) == EFI_NOT_READY) {

+    ;

+  }

+}

+#endif

+

+STATIC

+EFI_STATUS

+issue_hwundi_command (

+  UINT64 cdb

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+#if SNP_DEBUG

+  Aprint ("\nissue_hwundi_command() - This should not be called!");

+  snp_wait_for_key ();

+#endif

+  if (cdb == 0) {

+    return EFI_INVALID_PARAMETER;

+

+  }

+  //

+  //  %%TBD - For now, nothing is done.

+  //

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+UINT8

+calc_8bit_cksum (

+  VOID  *ptr,

+  UINTN len

+  )

+/*++

+

+Routine Description:

+ Compute 8-bit checksum of a buffer.

+ 

+Arguments:

+ ptr - Pointer to buffer.

+ len - Length of buffer in bytes.

+

+Returns:

+ 8-bit checksum of all bytes in buffer.

+ If ptr is NULL or len is zero, zero is returned.

+

+--*/

+{

+  UINT8 *bptr;

+  UINT8 cksum;

+

+  bptr  = ptr;

+  cksum = 0;

+

+  if (ptr == NULL || len == 0) {

+    return 0;

+  }

+

+  while (len--) {

+    cksum = (UINT8) (cksum +*bptr++);

+  }

+

+  return cksum;

+}

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+  Routine Description:

+    Test to see if this driver supports Controller. Any Controller

+    that contains a Nii protocol can be supported.

+

+  Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to test.

+    RemainingDevicePath - Not used.

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    EFI_ALREADY_STARTED - This driver is already running on this device.

+    other               - This driver does not support this device.

+

+--*/

+{

+  EFI_STATUS                                Status;

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiProtocol;

+  PXE_UNDI                                  *pxe;

+  BOOLEAN                                   IsUndi31;

+

+  IsUndi31 = FALSE;

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                  (VOID **) &NiiProtocol,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED)

+  {

+#if SNP_DEBUG

+    Aprint ("Support(): Already Started. on handle %x\n", Controller);

+#endif

+    return EFI_ALREADY_STARTED;

+  }

+

+  if (!EFI_ERROR (Status))

+  {

+

+#if SNP_DEBUG

+    Aprint ("Support(): UNDI3.1 found on handle %x\n", Controller);

+    snp_wait_for_key ();

+#endif

+    IsUndi31 = TRUE;

+  } else {

+    //

+    // try the older 3.0 driver

+    //

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                    (VOID **) &NiiProtocol,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_BY_DRIVER

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+#if SNP_DEBUG

+    Aprint ("Support(): UNDI3.0 found on handle %x\n", Controller);

+    snp_wait_for_key ();

+#endif

+  }

+  //

+  // check the version, we don't want to connect to the undi16

+  //

+  if (NiiProtocol->Type != EfiNetworkInterfaceUndi) {

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+  //

+  // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.

+  //

+  if (NiiProtocol->ID & 0x0F) {

+    DEBUG ((EFI_D_NET, "\n!PXE structure is not paragraph aligned.\n"));

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+

+  pxe = (PXE_UNDI *) (UINTN) (NiiProtocol->ID);

+

+  //

+  //  Verify !PXE revisions.

+  //

+  if (pxe->hw.Signature != PXE_ROMID_SIGNATURE) {

+    DEBUG ((EFI_D_NET, "\n!PXE signature is not valid.\n"));

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+

+  if (pxe->hw.Rev < PXE_ROMID_REV) {

+    DEBUG ((EFI_D_NET, "\n!PXE.Rev is not supported.\n"));

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+

+  if (pxe->hw.MajorVer < PXE_ROMID_MAJORVER) {

+

+    DEBUG ((EFI_D_NET, "\n!PXE.MajorVer is not supported.\n"));

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+

+  } else if (pxe->hw.MajorVer == PXE_ROMID_MAJORVER && pxe->hw.MinorVer < PXE_ROMID_MINORVER) {

+    DEBUG ((EFI_D_NET, "\n!PXE.MinorVer is not supported."));

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+  //

+  // Do S/W UNDI specific checks.

+  //

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) == 0) {

+    if (pxe->sw.EntryPoint < pxe->sw.Len) {

+      DEBUG ((EFI_D_NET, "\n!PXE S/W entry point is not valid."));

+      Status = EFI_UNSUPPORTED;

+      goto Done;

+    }

+

+    if (pxe->sw.BusCnt == 0) {

+      DEBUG ((EFI_D_NET, "\n!PXE.BusCnt is zero."));

+      Status = EFI_UNSUPPORTED;

+      goto Done;

+    }

+  }

+

+  Status = EFI_SUCCESS;

+#if SNP_DEBUG

+  Aprint ("Support(): supported on %x\n", Controller);

+  snp_wait_for_key ();

+#endif

+

+Done:

+  if (IsUndi31) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+          This->DriverBindingHandle,

+          Controller

+          );

+

+  } else {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiNetworkInterfaceIdentifierProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+ called for any handle that we said "supported" in the above call!

+

+Arguments:

+    This                - Protocol instance pointer.

+    Controller          - Handle of device to start

+    RemainingDevicePath - Not used.

+

+  Returns:

+    EFI_SUCCESS         - This driver supports this device.

+    other               - This driver failed to start this device.

+

+--*/

+{

+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;

+  EFI_DEVICE_PATH_PROTOCOL                  *NiiDevicePath;

+  EFI_STATUS                                Status;

+  PXE_UNDI                                  *pxe;

+  SNP_DRIVER                                *snp;

+  VOID                                      *addr;

+  VOID                                      *addrUnmap;

+  EFI_PHYSICAL_ADDRESS                      paddr;

+  EFI_HANDLE                                Handle;

+  UINTN                                     Size;

+  BOOLEAN                                   UndiNew;

+  PXE_PCI_CONFIG_INFO                       ConfigInfo;

+  PCI_TYPE00                                *ConfigHeader;

+  UINT32                                    *TempBar;

+  UINT8                                     BarIndex;

+  PXE_STATFLAGS                             InitStatFlags;

+

+  DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier()  "));

+

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &NiiDevicePath,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->LocateDevicePath (

+                  &gEfiPciIoProtocolGuid,

+                  &NiiDevicePath,

+                  &Handle

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &mPciIoFncs,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the NII interface. look for 3.1 undi first, if it is not there

+  // then look for 3.0, validate the interface.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                  (VOID **) &Nii,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+    return Status;

+  }

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // probably not a 3.1 UNDI

+    //

+    UndiNew = TRUE;

+#if SNP_DEBUG

+    Aprint ("Start(): UNDI3.1 found\n");

+    snp_wait_for_key ();

+#endif

+  } else {

+    UndiNew = FALSE;

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                    (VOID **) &Nii,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_BY_DRIVER

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->CloseProtocol (

+            Controller,

+            &gEfiDevicePathProtocolGuid,

+            This->DriverBindingHandle,

+            Controller

+            );

+

+      return Status;

+    }

+

+#if SNP_DEBUG

+    Aprint ("Start(): UNDI3.0 found\n");

+    snp_wait_for_key ();

+#endif

+  }

+

+  pxe = (PXE_UNDI *) (UINTN) (Nii->ID);

+

+  if (calc_8bit_cksum (pxe, pxe->hw.Len) != 0) {

+    DEBUG ((EFI_D_NET, "\n!PXE checksum is not correct.\n"));

+    goto NiiError;

+  }

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED) != 0) {

+    //

+    //  We can get any packets.

+    //

+  } else if ((pxe->hw.Implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED) != 0) {

+    //

+    //  We need to be able to get broadcast packets for DHCP.

+    //  If we do not have promiscuous support, we must at least have

+    //  broadcast support or we cannot do DHCP!

+    //

+  } else {

+    DEBUG ((EFI_D_NET, "\nUNDI does not have promiscuous or broadcast support."));

+    goto NiiError;

+  }

+  //

+  // OK, we like this UNDI, and we know snp is not already there on this handle

+  // Allocate and initialize a new simple network protocol structure.

+  //

+  Status = mPciIoFncs->AllocateBuffer (

+                        mPciIoFncs,

+                        AllocateAnyPages,

+                        EfiBootServicesData,

+                        SNP_MEM_PAGES (sizeof (SNP_DRIVER)),

+                        &addr,

+                        0

+                        );

+

+  if (Status != EFI_SUCCESS) {

+    DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));

+    goto NiiError;

+  }

+

+  snp = (SNP_DRIVER *) (UINTN) addr;

+

+  if (!UndiNew) {

+    Size = SNP_MEM_PAGES (sizeof (SNP_DRIVER));

+

+    Status = mPciIoFncs->Map (

+                          mPciIoFncs,

+                          EfiPciIoOperationBusMasterCommonBuffer,

+                          addr,

+                          &Size,

+                          &paddr,

+                          &addrUnmap

+                          );

+

+    ASSERT (paddr);

+

+    DEBUG ((EFI_D_NET, "\nSNP_DRIVER @ %Xh, sizeof(SNP_DRIVER) == %d", addr, sizeof (SNP_DRIVER)));

+    snp                 = (SNP_DRIVER *) (UINTN) paddr;

+    snp->SnpDriverUnmap = addrUnmap;

+  }

+

+  ZeroMem (snp, sizeof (SNP_DRIVER));

+

+  snp->IoFncs     = mPciIoFncs;

+  snp->IsOldUndi  = (BOOLEAN) (!UndiNew);

+

+  snp->Signature  = SNP_DRIVER_SIGNATURE;

+

+  EfiInitializeLock (&snp->lock, EFI_TPL_NOTIFY);

+

+  snp->snp.Revision       = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;

+  snp->snp.Start          = snp_undi32_start;

+  snp->snp.Stop           = snp_undi32_stop;

+  snp->snp.Initialize     = snp_undi32_initialize;

+  snp->snp.Reset          = snp_undi32_reset;

+  snp->snp.Shutdown       = snp_undi32_shutdown;

+  snp->snp.ReceiveFilters = snp_undi32_receive_filters;

+  snp->snp.StationAddress = snp_undi32_station_address;

+  snp->snp.Statistics     = snp_undi32_statistics;

+  snp->snp.MCastIpToMac   = snp_undi32_mcast_ip_to_mac;

+  snp->snp.NvData         = snp_undi32_nvdata;

+  snp->snp.GetStatus      = snp_undi32_get_status;

+  snp->snp.Transmit       = snp_undi32_transmit;

+  snp->snp.Receive        = snp_undi32_receive;

+  snp->snp.WaitForPacket  = NULL;

+

+  snp->snp.Mode           = &snp->mode;

+

+  snp->tx_rx_bufsize      = 0;

+  snp->tx_rx_buffer       = NULL;

+

+  snp->if_num             = Nii->IfNum;

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) != 0) {

+    snp->is_swundi            = FALSE;

+    snp->issue_undi32_command = &issue_hwundi_command;

+  } else {

+    snp->is_swundi = TRUE;

+

+    if ((pxe->sw.Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR) != 0) {

+      snp->issue_undi32_command = (issue_undi32_command) (UINTN) pxe->sw.EntryPoint;

+    } else {

+      snp->issue_undi32_command = (issue_undi32_command) (UINTN) ((UINT8) (UINTN) pxe + pxe->sw.EntryPoint);

+    }

+  }

+  //

+  // Allocate a global CPB and DB buffer for this UNDI interface.

+  // we do this because:

+  //

+  // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be

+  // within 2GB limit, create them here and map them so that when undi calls

+  // v2p callback to check if the physical address is < 2gb, we will pass.

+  //

+  // -This is not a requirement for 3.1 or later UNDIs but the code looks

+  // simpler if we use the same cpb, db variables for both old and new undi

+  // interfaces from all the SNP interface calls (we don't map the buffers

+  // for the newer undi interfaces though)

+  // .

+  // -it is OK to allocate one global set of CPB, DB pair for each UNDI

+  // interface as EFI does not multi-task and so SNP will not be re-entered!

+  //

+  Status = mPciIoFncs->AllocateBuffer (

+                        mPciIoFncs,

+                        AllocateAnyPages,

+                        EfiBootServicesData,

+                        SNP_MEM_PAGES (4096),

+                        &addr,

+                        0

+                        );

+

+  if (Status != EFI_SUCCESS) {

+    DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));

+    goto Error_DeleteSNP;

+  }

+

+  if (snp->IsOldUndi) {

+    Size = SNP_MEM_PAGES (4096);

+

+    Status = mPciIoFncs->Map (

+                          mPciIoFncs,

+                          EfiPciIoOperationBusMasterCommonBuffer,

+                          addr,

+                          &Size,

+                          &paddr,

+                          &snp->CpbUnmap

+                          );

+

+    ASSERT (paddr);

+

+    snp->cpb  = (VOID *) (UINTN) paddr;

+    snp->db   = (VOID *) ((UINTN) paddr + 2048);

+  } else {

+    snp->cpb  = (VOID *) (UINTN) addr;

+    snp->db   = (VOID *) ((UINTN) addr + 2048);

+  }

+  //

+  // pxe_start call is going to give the callback functions to UNDI, these callback

+  // functions use the BarIndex values from the snp structure, so these must be initialized

+  // with default values before doing a pxe_start. The correct values can be obtained after

+  // getting the config information from UNDI

+  //

+  snp->MemoryBarIndex = 0;

+  snp->IoBarIndex     = 1;

+

+  //

+  // we need the undi init information many times in this snp code, just get it

+  // once here and store it in the snp driver structure. to get Init Info

+  // from UNDI we have to start undi first.

+  //

+  Status = pxe_start (snp);

+

+  if (Status != EFI_SUCCESS) {

+    goto Error_DeleteCPBDB;

+  }

+

+  snp->cdb.OpCode     = PXE_OPCODE_GET_INIT_INFO;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_DBADDR_NOT_USED;

+

+  snp->cdb.DBsize     = sizeof snp->init_info;

+  snp->cdb.DBaddr     = (UINT64) (UINTN) &snp->init_info;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  DEBUG ((EFI_D_NET, "\nsnp->undi.get_init_info()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  //

+  // Save the INIT Stat Code...

+  //

+  InitStatFlags = snp->cdb.StatFlags;

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    DEBUG ((EFI_D_NET, "\nsnp->undi.init_info()  %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));

+    pxe_stop (snp);

+    goto Error_DeleteCPBDB;

+  }

+

+  snp->cdb.OpCode     = PXE_OPCODE_GET_CONFIG_INFO;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_DBADDR_NOT_USED;

+

+  snp->cdb.DBsize     = sizeof ConfigInfo;

+  snp->cdb.DBaddr     = (UINT64) (UINTN) &ConfigInfo;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  DEBUG ((EFI_D_NET, "\nsnp->undi.get_config_info()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    DEBUG ((EFI_D_NET, "\nsnp->undi.config_info()  %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));

+    pxe_stop (snp);

+    goto Error_DeleteCPBDB;

+  }

+  //

+  // Find the correct BAR to do IO.

+  //

+  //

+  // Enumerate through the PCI BARs for the device to determine which one is

+  // the IO BAR.  Save the index of the BAR into the adapter info structure.

+  // for  regular 32bit BARs, 0 is memory mapped, 1 is io mapped

+  //

+  ConfigHeader  = (PCI_TYPE00 *) &ConfigInfo.Config.Byte[0];

+  TempBar       = (UINT32 *) &ConfigHeader->Device.Bar[0];

+  for (BarIndex = 0; BarIndex <= 5; BarIndex++) {

+    if ((*TempBar & PCI_BAR_MEM_MASK) == PCI_BAR_MEM_64BIT) {

+      //

+      // This is a 64-bit memory bar, skip this and the

+      // next bar as well.

+      //

+      TempBar++;

+    }

+

+    if ((*TempBar & PCI_BAR_IO_MASK) == PCI_BAR_IO_MODE) {

+      snp->IoBarIndex = BarIndex;

+      break;

+    }

+

+    TempBar++;

+  }

+

+  //

+  // We allocate 2 more global buffers for undi 3.0 interface. We use these

+  // buffers to pass to undi when the user buffers are beyond 4GB.

+  // UNDI 3.0 wants all the addresses passed to it to be

+  // within 2GB limit, create them here and map them so that when undi calls

+  // v2p callback to check if the physical address is < 2gb, we will pass.

+  //

+  // For 3.1 and later UNDIs, we do not do this because undi is

+  // going to call the map() callback if and only if it wants to use the

+  // device address for any address it receives.

+  //

+  if (snp->IsOldUndi) {

+    //

+    // buffer for receive

+    //

+    Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);

+    Status = mPciIoFncs->AllocateBuffer (

+                          mPciIoFncs,

+                          AllocateAnyPages,

+                          EfiBootServicesData,

+                          Size,

+                          &addr,

+                          0

+                          );

+

+    if (Status != EFI_SUCCESS) {

+      DEBUG ((EFI_D_ERROR, "\nCould not allocate receive buffer.\n"));

+      goto Error_DeleteCPBDB;

+    }

+

+    Status = mPciIoFncs->Map (

+                          mPciIoFncs,

+                          EfiPciIoOperationBusMasterCommonBuffer,

+                          addr,

+                          &Size,

+                          &paddr,

+                          &snp->ReceiveBufUnmap

+                          );

+

+    ASSERT (paddr);

+

+    snp->receive_buf = (UINT8 *) (UINTN) paddr;

+

+    //

+    // buffer for fill_header

+    //

+    Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen);

+    Status = mPciIoFncs->AllocateBuffer (

+                          mPciIoFncs,

+                          AllocateAnyPages,

+                          EfiBootServicesData,

+                          Size,

+                          &addr,

+                          0

+                          );

+

+    if (Status != EFI_SUCCESS) {

+      DEBUG ((EFI_D_ERROR, "\nCould not allocate fill_header buffer.\n"));

+      goto Error_DeleteRCVBuf;

+    }

+

+    Status = mPciIoFncs->Map (

+                          mPciIoFncs,

+                          EfiPciIoOperationBusMasterCommonBuffer,

+                          addr,

+                          &Size,

+                          &paddr,

+                          &snp->FillHdrBufUnmap

+                          );

+

+    ASSERT (paddr);

+    snp->fill_hdr_buf = (UINT8 *) (UINTN) paddr;

+  }

+  //

+  //  Initialize simple network protocol mode structure

+  //

+  snp->mode.State               = EfiSimpleNetworkStopped;

+  snp->mode.HwAddressSize       = snp->init_info.HWaddrLen;

+  snp->mode.MediaHeaderSize     = snp->init_info.MediaHeaderLen;

+  snp->mode.MaxPacketSize       = snp->init_info.FrameDataLen;

+  snp->mode.NvRamAccessSize     = snp->init_info.NvWidth;

+  snp->mode.NvRamSize           = snp->init_info.NvCount * snp->mode.NvRamAccessSize;

+  snp->mode.IfType              = snp->init_info.IFtype;

+  snp->mode.MaxMCastFilterCount = snp->init_info.MCastFilterCnt;

+  snp->mode.MCastFilterCount    = 0;

+

+  switch (InitStatFlags & PXE_STATFLAGS_CABLE_DETECT_MASK) {

+  case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED:

+    snp->mode.MediaPresentSupported = TRUE;

+    break;

+

+  case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED:

+  default:

+    snp->mode.MediaPresentSupported = FALSE;

+  }

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE) != 0) {

+    snp->mode.MacAddressChangeable = TRUE;

+  } else {

+    snp->mode.MacAddressChangeable = FALSE;

+  }

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED) != 0) {

+    snp->mode.MultipleTxSupported = TRUE;

+  } else {

+    snp->mode.MultipleTxSupported = FALSE;

+  }

+

+  snp->mode.ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) != 0) {

+    snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;

+

+  }

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED) != 0) {

+    snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;

+

+  }

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED) != 0) {

+    snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;

+

+  }

+

+  if ((pxe->hw.Implementation & PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED) != 0) {

+    snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;

+

+  }

+

+  if (pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) {

+    snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;

+

+  }

+

+  snp->mode.ReceiveFilterSetting = 0;

+

+  //

+  //  need to get the station address to save in the mode structure. we need to

+  // initialize the UNDI first for this.

+  //

+  snp->tx_rx_bufsize  = snp->init_info.MemoryRequired;

+  Status              = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);

+

+  if (Status) {

+    pxe_stop (snp);

+    goto Error_DeleteHdrBuf;

+  }

+

+  Status = pxe_get_stn_addr (snp);

+

+  if (Status != EFI_SUCCESS) {

+    DEBUG ((EFI_D_ERROR, "\nsnp->undi.get_station_addr()  failed.\n"));

+    pxe_shutdown (snp);

+    pxe_stop (snp);

+    goto Error_DeleteHdrBuf;

+  }

+

+  snp->mode.MediaPresent = FALSE;

+

+  //

+  // We should not leave UNDI started and initialized here. this DriverStart()

+  // routine must only find and attach the SNP interface to UNDI layer that it

+  // finds on the given handle!

+  // The UNDI layer will be started when upper layers call snp->start.

+  // How ever, this DriverStart() must fill up the snp mode structure which

+  // contains the MAC address of the NIC. For this reason we started and

+  // initialized UNDI here, now we are done, do a shutdown and stop of the

+  // UNDI interface!

+  //

+  pxe_shutdown (snp);

+  pxe_stop (snp);

+

+  //

+  //  add SNP to the undi handle

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &Controller,

+                  &gEfiSimpleNetworkProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &(snp->snp)

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    return Status;

+  }

+

+Error_DeleteHdrBuf:

+  if (snp->IsOldUndi) {

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          snp->FillHdrBufUnmap

+                          );

+    Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen);

+    mPciIoFncs->FreeBuffer (

+                  mPciIoFncs,

+                  Size,

+                  snp->fill_hdr_buf

+                  );

+  }

+

+Error_DeleteRCVBuf:

+  if (snp->IsOldUndi) {

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          snp->ReceiveBufUnmap

+                          );

+    Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);

+    mPciIoFncs->FreeBuffer (

+                  mPciIoFncs,

+                  Size,

+                  snp->receive_buf

+                  );

+

+  }

+

+Error_DeleteCPBDB:

+  if (snp->IsOldUndi) {

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          snp->CpbUnmap

+                          );

+  }

+

+  Status = mPciIoFncs->FreeBuffer (

+                        mPciIoFncs,

+                        SNP_MEM_PAGES (4096),

+                        snp->cpb

+                        );

+

+Error_DeleteSNP:

+  if (snp->IsOldUndi) {

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          snp->SnpDriverUnmap

+                          );

+  }

+

+  mPciIoFncs->FreeBuffer (

+                mPciIoFncs,

+                SNP_MEM_PAGES (sizeof (SNP_DRIVER)),

+                snp

+                );

+NiiError:

+  if (!UndiNew) {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiNetworkInterfaceIdentifierProtocolGuid,

+          This->DriverBindingHandle,

+          Controller

+          );

+  } else {

+    gBS->CloseProtocol (

+          Controller,

+          &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+          This->DriverBindingHandle,

+          Controller

+          );

+  }

+

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+SimpleNetworkDriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                     Controller,

+  IN  UINTN                          NumberOfChildren,

+  IN  EFI_HANDLE                     *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;

+  SNP_DRIVER                  *Snp;

+

+  //

+  // Get our context back.

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiSimpleNetworkProtocolGuid,

+                  (VOID **) &SnpProtocol,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol);

+

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiSimpleNetworkProtocolGuid,

+                  &Snp->snp

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (!Snp->IsOldUndi) {

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiNetworkInterfaceIdentifierProtocolGuid_31,

+                    This->DriverBindingHandle,

+                    Controller

+                    );

+  } else {

+    Status = gBS->CloseProtocol (

+                    Controller,

+                    &gEfiNetworkInterfaceIdentifierProtocolGuid,

+                    This->DriverBindingHandle,

+                    Controller

+                    );

+  }

+  

+  Status = gBS->CloseProtocol (

+                  Controller,

+                  &gEfiDevicePathProtocolGuid,

+                  This->DriverBindingHandle,

+                  Controller

+                  );

+

+  pxe_shutdown (Snp);

+  pxe_stop (Snp);

+

+  if (Snp->IsOldUndi) {

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          Snp->FillHdrBufUnmap

+                          );

+

+    mPciIoFncs->FreeBuffer (

+                  mPciIoFncs,

+                  SNP_MEM_PAGES (Snp->init_info.MediaHeaderLen),

+                  Snp->fill_hdr_buf

+                  );

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          Snp->ReceiveBufUnmap

+                          );

+

+    mPciIoFncs->FreeBuffer (

+                  mPciIoFncs,

+                  SNP_MEM_PAGES (Snp->init_info.MediaHeaderLen + Snp->init_info.FrameDataLen),

+                  Snp->receive_buf

+                  );

+

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          Snp->CpbUnmap

+                          );

+    Status = mPciIoFncs->Unmap (

+                          mPciIoFncs,

+                          Snp->SnpDriverUnmap

+                          );

+  }

+

+  mPciIoFncs->FreeBuffer (

+                mPciIoFncs,

+                SNP_MEM_PAGES (4096),

+                Snp->cpb

+                );

+

+  mPciIoFncs->FreeBuffer (

+                mPciIoFncs,

+                SNP_MEM_PAGES (sizeof (SNP_DRIVER)),

+                Snp

+                );

+

+  return Status;

+}

+

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/start.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/start.c
new file mode 100644
index 0000000..b21d8cb
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/start.c
@@ -0,0 +1,191 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  start.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-07 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_start (

+  SNP_DRIVER *snp

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to start the interface and changes the snp state!

+

+Arguments:

+  snp  - pointer to snp driver structure

+

+Returns:

+

+--*/

+{

+  PXE_CPB_START_30     *cpb;

+  PXE_CPB_START_31  *cpb_31;

+

+  cpb     = snp->cpb;

+  cpb_31  = snp->cpb;

+  //

+  // Initialize UNDI Start CDB for H/W UNDI

+  //

+  snp->cdb.OpCode     = PXE_OPCODE_START;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Make changes to H/W UNDI Start CDB if this is

+  // a S/W UNDI.

+  //

+  if (snp->is_swundi) {

+    if (snp->IsOldUndi) {

+      snp->cdb.CPBsize  = sizeof (PXE_CPB_START_30);

+      snp->cdb.CPBaddr  = (UINT64) (UINTN) cpb;

+

+      cpb->Delay        = (UINT64) &snp_undi32_callback_delay_30;

+      cpb->Block        = (UINT64) &snp_undi32_callback_block_30;

+

+      //

+      // Virtual == Physical.  This can be set to zero.

+      //

+      cpb->Virt2Phys  = (UINT64) &snp_undi32_callback_v2p_30;

+      cpb->Mem_IO     = (UINT64) &snp_undi32_callback_memio_30;

+    } else {

+      snp->cdb.CPBsize  = sizeof (PXE_CPB_START_31);

+      snp->cdb.CPBaddr  = (UINT64) (UINTN) cpb_31;

+

+      cpb_31->Delay     = (UINT64) &snp_undi32_callback_delay;

+      cpb_31->Block     = (UINT64) &snp_undi32_callback_block;

+

+      //

+      // Virtual == Physical.  This can be set to zero.

+      //

+      cpb_31->Virt2Phys = (UINT64) 0;

+      cpb_31->Mem_IO    = (UINT64) &snp_undi32_callback_memio;

+

+      cpb_31->Map_Mem   = (UINT64) &snp_undi32_callback_map;

+      cpb_31->UnMap_Mem = (UINT64) &snp_undi32_callback_unmap;

+      cpb_31->Sync_Mem  = (UINT64) &snp_undi32_callback_sync;

+

+      cpb_31->Unique_ID = (UINT64) (UINTN) snp;

+    }

+  }

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.start()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    //

+    // UNDI could not be started. Return UNDI error.

+    //

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.start()  %xh:%xh\n",

+      snp->cdb.StatCode,

+      snp->cdb.StatFlags)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set simple network state to Started and return success.

+  //

+  snp->mode.State = EfiSimpleNetworkStarted;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_start (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *This

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for starting the interface

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_start routine to actually do start undi interface

+

+Arguments:

+  This  - context pointer

+

+Returns:

+  EFI_INVALID_PARAMETER - "This" is Null

+                        - No SNP driver can be extracted from "This"

+  EFI_ALREADY_STARTED   - The state of SNP is EfiSimpleNetworkStarted

+                          or EfiSimpleNetworkInitialized

+  EFI_DEVICE_ERROR      - The state of SNP is other than EfiSimpleNetworkStarted,

+                          EfiSimpleNetworkInitialized, and EfiSimpleNetworkStopped

+  EFI_SUCCESS           - UNDI interface is succesfully started

+  Other                 - Error occurs while calling pxe_start function.

+  

+--*/

+{

+  SNP_DRIVER  *Snp;

+  EFI_STATUS  Status;

+  UINTN       Index;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);

+

+  if (Snp == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  switch (Snp->mode.State) {

+  case EfiSimpleNetworkStopped:

+    break;

+

+  case EfiSimpleNetworkStarted:

+  case EfiSimpleNetworkInitialized:

+    return EFI_ALREADY_STARTED;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  Status = pxe_start (Snp);

+  if (Status != EFI_SUCCESS) {

+    return Status;

+  }

+  //

+  // clear the map_list in SNP structure

+  //

+  for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {

+    Snp->map_list[Index].virt       = 0;

+    Snp->map_list[Index].map_cookie = 0;

+  }

+

+  Snp->mode.MCastFilterCount = 0;

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/station_address.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/station_address.c
new file mode 100644
index 0000000..b5d2c40
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/station_address.c
@@ -0,0 +1,248 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  station_address.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-17 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_get_stn_addr (

+  SNP_DRIVER *snp

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to read the MAC address of the NIC and updates the

+ mode structure with the address.

+

+Arguments:

+  snp  - pointer to snp driver structure

+

+Returns:

+ 

+--*/

+{

+  PXE_DB_STATION_ADDRESS  *db;

+

+  db                  = snp->db;

+  snp->cdb.OpCode     = PXE_OPCODE_STATION_ADDRESS;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_STATION_ADDRESS_READ;

+

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+

+  snp->cdb.DBsize     = sizeof (PXE_DB_STATION_ADDRESS);

+  snp->cdb.DBaddr     = (UINT64) (UINTN) db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.station_addr()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set new station address in SNP->Mode structure and return success.

+  //

+  CopyMem (

+    &(snp->mode.CurrentAddress),

+    &db->StationAddr,

+    snp->mode.HwAddressSize

+    );

+

+  CopyMem (

+    &snp->mode.BroadcastAddress,

+    &db->BroadcastAddr,

+    snp->mode.HwAddressSize

+    );

+

+  CopyMem (

+    &snp->mode.PermanentAddress,

+    &db->PermanentAddr,

+    snp->mode.HwAddressSize

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+pxe_set_stn_addr (

+  SNP_DRIVER      *snp,

+  EFI_MAC_ADDRESS *NewMacAddr

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to set a new MAC address for the NIC,

+

+Arguments:

+  snp  - pointer to snp driver structure

+  NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL

+               then this routine resets the mac address to the NIC's original

+               address.

+

+Returns:

+

+--*/

+{

+  PXE_CPB_STATION_ADDRESS *cpb;

+  PXE_DB_STATION_ADDRESS  *db;

+

+  cpb             = snp->cpb;

+  db              = snp->db;

+  snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;

+

+  if (NewMacAddr == NULL) {

+    snp->cdb.OpFlags  = PXE_OPFLAGS_STATION_ADDRESS_RESET;

+    snp->cdb.CPBsize  = PXE_CPBSIZE_NOT_USED;

+    snp->cdb.CPBaddr  = PXE_CPBADDR_NOT_USED;

+  } else {

+    snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;

+    //

+    // even though the OPFLAGS are set to READ, supplying a new address

+    // in the CPB will make undi change the mac address to the new one.

+    //

+    CopyMem (&cpb->StationAddr, NewMacAddr, snp->mode.HwAddressSize);

+

+    snp->cdb.CPBsize  = sizeof (PXE_CPB_STATION_ADDRESS);

+    snp->cdb.CPBaddr  = (UINT64) (UINTN) cpb;

+  }

+

+  snp->cdb.DBsize     = sizeof (PXE_DB_STATION_ADDRESS);

+  snp->cdb.DBaddr     = (UINT64) (UINTN) db;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.station_addr()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    //

+    // UNDI command failed.  Return UNDI status to caller.

+    //

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // read the changed address and save it in SNP->Mode structure

+  //

+  pxe_get_stn_addr (snp);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_station_address (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN BOOLEAN                     ResetFlag,

+  IN EFI_MAC_ADDRESS             * NewMacAddr OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for changing the NIC's mac address.

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the above routines to actually do the work

+

+Arguments:

+ this  - context pointer

+ NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL

+              then this routine resets the mac address to the NIC's original

+              address.

+ ResetFlag - If true, the mac address will change to NIC's original address

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+  EFI_STATUS  Status;

+

+  //

+  // Get pointer to SNP driver instance for *this.

+  //

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Return error if the SNP is not initialized.

+  //

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Check for invalid parameter combinations.

+  //

+  if (!ResetFlag && NewMacAddr == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (ResetFlag) {

+    Status = pxe_set_stn_addr (snp, NULL);

+  } else {

+    Status = pxe_set_stn_addr (snp, NewMacAddr);

+

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/statistics.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/statistics.c
new file mode 100644
index 0000000..1c148a7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/statistics.c
@@ -0,0 +1,193 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  statistics.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-17 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+EFIAPI

+snp_undi32_statistics (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN BOOLEAN                     ResetFlag,

+  IN OUT UINTN                   *StatTableSizePtr OPTIONAL,

+  IN OUT EFI_NETWORK_STATISTICS  * StatTablePtr OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for getting the NIC's statistics.

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_ routine to actually do the 

+

+Arguments:

+  this  - context pointer

+  ResetFlag - true to reset the NIC's statistics counters to zero.

+  StatTableSizePtr - pointer to the statistics table size

+  StatTablePtr - pointer to the statistics table 

+  

+Returns:

+

+--*/

+{

+  SNP_DRIVER        *snp;

+  PXE_DB_STATISTICS *db;

+  UINT64            *stp;

+  UINT64            mask;

+  UINTN             size;

+  UINTN             n;

+

+  //

+  // Get pointer to SNP driver instance for *this.

+  //

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Return error if the SNP is not initialized.

+  //

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // if we are not resetting the counters, we have to have a valid stat table

+  // with >0 size. if no reset, no table and no size, return success.

+  //

+  if (!ResetFlag && StatTableSizePtr == NULL) {

+    return StatTablePtr ? EFI_INVALID_PARAMETER : EFI_SUCCESS;

+  }

+  //

+  // Initialize UNDI Statistics CDB

+  //

+  snp->cdb.OpCode     = PXE_OPCODE_STATISTICS;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  if (ResetFlag) {

+    snp->cdb.OpFlags  = PXE_OPFLAGS_STATISTICS_RESET;

+    snp->cdb.DBsize   = PXE_DBSIZE_NOT_USED;

+    snp->cdb.DBaddr   = PXE_DBADDR_NOT_USED;

+    db                = snp->db;

+  } else {

+    snp->cdb.OpFlags                = PXE_OPFLAGS_STATISTICS_READ;

+    snp->cdb.DBsize                 = sizeof (PXE_DB_STATISTICS);

+    snp->cdb.DBaddr                 = (UINT64) (UINTN) (db = snp->db);

+  }

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.statistics()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  switch (snp->cdb.StatCode) {

+  case PXE_STATCODE_SUCCESS:

+    break;

+

+  case PXE_STATCODE_UNSUPPORTED:

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.statistics()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_UNSUPPORTED;

+

+  default:

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.statistics()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (ResetFlag) {

+    return EFI_SUCCESS;

+  }

+

+  if (StatTablePtr == NULL) {

+    *StatTableSizePtr = sizeof (EFI_NETWORK_STATISTICS);

+    return EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // Convert the UNDI statistics information to SNP statistics

+  // information.

+  //

+  ZeroMem (StatTablePtr, *StatTableSizePtr);

+  stp   = (UINT64 *) StatTablePtr;

+  size  = 0;

+

+  for (n = 0, mask = 1; n < 64; n++, mask = LShiftU64 (mask, 1), stp++) {

+    //

+    // There must be room for a full UINT64.  Partial

+    // numbers will not be stored.

+    //

+    if ((n + 1) * sizeof (UINT64) > *StatTableSizePtr) {

+      break;

+    }

+

+    if (db->Supported & mask) {

+      *stp  = db->Data[n];

+      size  = n + 1;

+    } else {

+      SetMem (stp, sizeof (UINT64), 0xFF);

+    }

+  }

+  //

+  // Compute size up to last supported statistic.

+  //

+  while (++n < 64) {

+    if (db->Supported & (mask = LShiftU64 (mask, 1))) {

+      size = n;

+    }

+  }

+

+  size *= sizeof (UINT64);

+

+  if (*StatTableSizePtr >= size) {

+    *StatTableSizePtr = size;

+    return EFI_SUCCESS;

+  } else {

+    *StatTableSizePtr = size;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/stop.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/stop.c
new file mode 100644
index 0000000..6abd07e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/stop.c
@@ -0,0 +1,120 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  stop.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-09 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_stop (

+  SNP_DRIVER *snp

+  )

+/*++

+

+Routine Description:

+ this routine calls undi to stop the interface and changes the snp state

+

+Arguments:

+  snp  - pointer to snp driver structure

+

+Returns:

+

+--*/

+{

+  snp->cdb.OpCode     = PXE_OPCODE_STOP;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;

+  snp->cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.stop()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {

+    DEBUG (

+      (EFI_D_WARN,

+      "\nsnp->undi.stop()  %xh:%xh\n",

+      snp->cdb.StatCode,

+      snp->cdb.StatFlags)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set simple network state to Started and return success.

+  //

+  snp->mode.State = EfiSimpleNetworkStopped;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_stop (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL *this

+  )

+/*++

+

+Routine Description:

+ This is the SNP interface routine for stopping the interface.

+ This routine basically retrieves snp structure, checks the SNP state and

+ calls the pxe_stop routine to actually stop the undi interface

+

+Arguments:

+  this  - context pointer

+

+Returns:

+

+--*/

+{

+  SNP_DRIVER  *snp;

+

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkStarted:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkInitialized:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  return pxe_stop (snp);

+}

diff --git a/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/transmit.c b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/transmit.c
new file mode 100644
index 0000000..404c75d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Network/Snp32_64/Dxe/transmit.c
@@ -0,0 +1,396 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module name:

+  

+    transmit.c

+

+Abstract:

+

+Revision history:

+  2000-Feb-03 M(f)J   Genesis.

+--*/

+

+

+#include "Snp.h"

+

+EFI_STATUS

+pxe_fillheader (

+  SNP_DRIVER      *snp,

+  VOID            *MacHeaderPtr,

+  UINTN           MacHeaderSize,

+  VOID            *BufferPtr,

+  UINTN           BufferLength,

+  EFI_MAC_ADDRESS *DestinationAddrPtr,

+  EFI_MAC_ADDRESS *SourceAddrPtr,

+  UINT16          *ProtocolPtr

+  )

+/*++

+

+Routine Description:

+ This routine calls undi to create the meadia header for the given data buffer.

+ 

+Arguments:

+ snp - pointer to SNP driver structure

+ MacHeaderPtr - address where the media header will be filled in.

+ MacHeaderSize - size of the memory at MacHeaderPtr

+ BufferPtr - data buffer pointer

+ BufferLength - Size of data in the BufferPtr

+ DestinationAddrPtr - address of the destination mac address buffer

+ SourceAddrPtr - address of the source mac address buffer

+ ProtocolPtr - address of the protocol type

+ 

+Returns:

+ EFI_SUCCESS - if successfully completed the undi call

+ Other - error return from undi call.

+ 

+--*/

+{

+  PXE_CPB_FILL_HEADER_FRAGMENTED  *cpb;

+  EFI_STATUS                      Status;

+  struct s_v2p                    *pkt_v2p;

+  UINT64                          TempData;

+

+  cpb = snp->cpb;

+  if (SourceAddrPtr) {

+    CopyMem (

+      (VOID *) cpb->SrcAddr,

+      (VOID *) SourceAddrPtr,

+      snp->mode.HwAddressSize

+      );

+  } else {

+    CopyMem (

+      (VOID *) cpb->SrcAddr,

+      (VOID *) &(snp->mode.CurrentAddress),

+      snp->mode.HwAddressSize

+      );

+  }

+

+  CopyMem (

+    (VOID *) cpb->DestAddr,

+    (VOID *) DestinationAddrPtr,

+    snp->mode.HwAddressSize

+    );

+

+  //

+  // we need to do the byte swapping

+  //

+  cpb->Protocol             = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);

+

+  cpb->PacketLen            = (UINT32) (BufferLength);

+  cpb->MediaHeaderLen       = (UINT16) MacHeaderSize;

+

+  cpb->FragCnt              = 2;

+  cpb->reserved             = 0;

+

+  cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) MacHeaderPtr;

+  cpb->FragDesc[0].FragLen  = (UINT32) MacHeaderSize;

+  cpb->FragDesc[1].FragAddr = (UINT64) (UINTN) BufferPtr;

+  cpb->FragDesc[1].FragLen  = (UINT32) BufferLength;

+

+  cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;

+

+  if (snp->IsOldUndi) {

+    TempData = (UINT64) (UINTN) MacHeaderPtr;

+    if (TempData >= FOUR_GIGABYTES) {

+      cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) snp->fill_hdr_buf;

+      cpb->FragDesc[0].FragLen  = (UINT32) snp->init_info.MediaHeaderLen;

+    }

+

+    TempData = (UINT64) (UINTN) (BufferPtr);

+    if (TempData >= FOUR_GIGABYTES) {

+      //

+      // Let the device just read this buffer

+      //

+      Status = add_v2p (

+                &pkt_v2p,

+                EfiPciIoOperationBusMasterRead,

+                BufferPtr,

+                BufferLength

+                );

+      if (Status != EFI_SUCCESS) {

+        return Status;

+      }

+      //

+      // give the virtual address to UNDI and it will call back on Virt2Phys

+      // to get the mapped address, if it needs it

+      //

+      cpb->FragDesc[1].FragLen = (UINT32) pkt_v2p->bsize;

+    }

+  }

+

+  snp->cdb.OpCode     = PXE_OPCODE_FILL_HEADER;

+  snp->cdb.OpFlags    = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;

+

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+

+  snp->cdb.CPBsize    = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);

+  snp->cdb.CPBaddr    = (UINT64) (UINTN) cpb;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header()  "));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  if (snp->IsOldUndi) {

+    TempData = (UINT64) (UINTN) (BufferPtr);

+    if (TempData >= FOUR_GIGABYTES) {

+      del_v2p (BufferPtr);

+    }

+    //

+    // if we used the global buffer for header, copy the contents

+    //

+    TempData = (UINT64) (UINTN) MacHeaderPtr;

+    if (TempData >= FOUR_GIGABYTES) {

+      CopyMem (

+        MacHeaderPtr,

+        snp->fill_hdr_buf,

+        snp->init_info.MediaHeaderLen

+        );

+    }

+  }

+

+  switch (snp->cdb.StatCode) {

+  case PXE_STATCODE_SUCCESS:

+    return EFI_SUCCESS;

+

+  case PXE_STATCODE_INVALID_PARAMETER:

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.fill_header()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_INVALID_PARAMETER;

+

+  default:

+    DEBUG (

+      (EFI_D_ERROR,

+      "\nsnp->undi.fill_header()  %xh:%xh\n",

+      snp->cdb.StatFlags,

+      snp->cdb.StatCode)

+      );

+

+    return EFI_DEVICE_ERROR;

+  }

+}

+

+EFI_STATUS

+pxe_transmit (

+  SNP_DRIVER *snp,

+  VOID       *BufferPtr,

+  UINTN      BufferLength

+  )

+/*++

+

+Routine Description:

+ This routine calls undi to transmit the given data buffer

+ 

+Arguments:

+ snp - pointer to SNP driver structure

+ BufferPtr - data buffer pointer

+ BufferLength - Size of data in the BufferPtr

+ 

+Returns:

+ EFI_SUCCESS - if successfully completed the undi call

+ Other - error return from undi call.

+ 

+--*/

+{

+  PXE_CPB_TRANSMIT  *cpb;

+  EFI_STATUS        Status;

+  struct s_v2p      *v2p;

+  UINT64            TempData;

+

+  cpb             = snp->cpb;

+  cpb->FrameAddr  = (UINT64) (UINTN) BufferPtr;

+  cpb->DataLen    = (UINT32) BufferLength;

+  

+  TempData = (UINT64) (UINTN) BufferPtr;

+  if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {

+    //

+    // we need to create a mapping now and give it to the undi when it calls

+    // the Virt2Phys on this address.

+    // this is a transmit, just map it for the device to READ

+    //

+    Status = add_v2p (

+              &v2p,

+              EfiPciIoOperationBusMasterRead,

+              BufferPtr,

+              BufferLength

+              );

+    if (Status != EFI_SUCCESS) {

+      return Status;

+    }

+

+    cpb->DataLen = (UINT32) v2p->bsize;

+  }

+

+  cpb->MediaheaderLen = 0;

+  cpb->reserved       = 0;

+

+  snp->cdb.OpFlags    = PXE_OPFLAGS_TRANSMIT_WHOLE;

+

+  snp->cdb.CPBsize    = sizeof (PXE_CPB_TRANSMIT);

+  snp->cdb.CPBaddr    = (UINT64) (UINTN) cpb;

+

+  snp->cdb.OpCode     = PXE_OPCODE_TRANSMIT;

+  snp->cdb.DBsize     = PXE_DBSIZE_NOT_USED;

+  snp->cdb.DBaddr     = PXE_DBADDR_NOT_USED;

+

+  snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;

+  snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;

+  snp->cdb.IFnum      = snp->if_num;

+  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

+

+  //

+  // Issue UNDI command and check result.

+  //

+  DEBUG ((EFI_D_NET, "\nsnp->undi.transmit()  "));

+  DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode  == %x", snp->cdb.OpCode));

+  DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %X", snp->cdb.CPBaddr));

+  DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr  == %X", snp->cdb.DBaddr));

+  DEBUG ((EFI_D_NET, "\ncpb->FrameAddr   == %X\n", cpb->FrameAddr));

+

+  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

+

+  DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit()  "));

+  DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));

+

+  //

+  // we will unmap the buffers in get_status call, not here

+  //

+  switch (snp->cdb.StatCode) {

+  case PXE_STATCODE_SUCCESS:

+    return EFI_SUCCESS;

+

+  case PXE_STATCODE_QUEUE_FULL:

+  case PXE_STATCODE_BUSY:

+    Status = EFI_NOT_READY;

+    break;

+

+  default:

+    Status = EFI_DEVICE_ERROR;

+  }

+

+  DEBUG (

+    (EFI_D_ERROR,

+    "\nsnp->undi.transmit()  %xh:%xh\n",

+    snp->cdb.StatFlags,

+    snp->cdb.StatCode)

+    );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+snp_undi32_transmit (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,

+  IN UINTN                       MacHeaderSize,

+  IN UINTN                       BufferLength,

+  IN VOID                        *BufferPtr,

+  IN EFI_MAC_ADDRESS             * SourceAddrPtr OPTIONAL,

+  IN EFI_MAC_ADDRESS             * DestinationAddrPtr OPTIONAL,

+  IN UINT16                      *ProtocolPtr OPTIONAL

+  )

+/*++

+

+Routine Description:

+ This is the snp interface routine for transmitting a packet. this routine 

+ basically retrieves the snp structure, checks the snp state and calls

+ pxe_fill_header and pxe_transmit calls to complete the transmission.

+ 

+Arguments:

+ this - pointer to SNP driver context

+ MacHeaderSize - size of the memory at MacHeaderPtr

+ BufferLength - Size of data in the BufferPtr

+ BufferPtr - data buffer pointer

+ SourceAddrPtr - address of the source mac address buffer

+ DestinationAddrPtr - address of the destination mac address buffer

+ ProtocolPtr - address of the protocol type

+ 

+Returns:

+ EFI_SUCCESS - if successfully completed the undi call

+ Other - error return from undi call.

+ 

+--*/

+{

+  SNP_DRIVER  *snp;

+  EFI_STATUS  Status;

+

+  if (this == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

+

+  if (snp == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  switch (snp->mode.State) {

+  case EfiSimpleNetworkInitialized:

+    break;

+

+  case EfiSimpleNetworkStopped:

+    return EFI_NOT_STARTED;

+

+  case EfiSimpleNetworkStarted:

+    return EFI_DEVICE_ERROR;

+

+  default:

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (BufferPtr == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferLength < snp->mode.MediaHeaderSize) {

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  //

+  // if the MacHeaderSize is non-zero, we need to fill up the header and for that

+  // we need the destination address and the protocol

+  //

+  if (MacHeaderSize != 0) {

+    if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    Status = pxe_fillheader (

+              snp,

+              BufferPtr,

+              MacHeaderSize,

+              (UINT8 *) BufferPtr + MacHeaderSize,

+              BufferLength - MacHeaderSize,

+              DestinationAddrPtr,

+              SourceAddrPtr,

+              ProtocolPtr

+              );

+

+    if (Status != EFI_SUCCESS) {

+      return Status;

+    }

+  }

+

+  return pxe_transmit (snp, BufferPtr, BufferLength);

+}

diff --git a/edk2/EdkModulePkg/Universal/PCD/Common/PcdCommon.c b/edk2/EdkModulePkg/Universal/PCD/Common/PcdCommon.c
new file mode 100644
index 0000000..1af93c1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Common/PcdCommon.c
@@ -0,0 +1,592 @@
+/** @file

+Common functions used by PCD PEIM and PCD DXE.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+

+Module Name: PcdCommon.c

+

+**/

+#include "PcdCommon.h"

+

+

+

+/**

+  The function retrieves the PCD data value according to

+  the PCD_DATA_TYPE specified.

+

+  @param[in] Type The PCD_DATA_TYPE used to interpret the data.

+  @param[in] InData The input data.

+  @param[in] OutData The output data.

+  @param[in] Len The length of the data; it is mainly used for PcdPointer type.

+

+  @retval VOID

+--*/

+VOID

+GetDataBasedOnType (

+  IN PCD_DATA_TYPE Type,

+  IN VOID          *InData,

+  OUT VOID         *OutData,

+  IN UINTN         Len

+  )

+{

+  if (Type == PcdPointer) {

+    //

+    // When the Type is PcdPointer, we are returning 

+    // the address of the internal buffer kpet by

+    // PCD database. Therefore, we treat OutData as

+    // a pointer to a "VOID *". Thus, the ugly type cast

+    // (VOID **) is used.

+    //

+

+    *((VOID **) OutData) = InData;

+  } else {

+    CopyMem (OutData, InData, Len);

+  }

+  

+  return;

+  

+}

+

+UINTN

+GetExtendedDataOffset (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN UINTN                     SkuIdx,

+  IN CONST PCD_DATABASE_HEADER *Info

+  )

+{

+  UINT8 *OffsetAddress;

+  UINTN Offset;

+

+  OffsetAddress = GetAbsoluteAddress (PcdIndex->ExtendedDataOffset, 

+                                      Info->ImageIndexOffset, 

+                                      Info

+                                      );

+

+  OffsetAddress += (SkuIdx * Info->ExtendedOffsetLength);

+

+

+  CopyMem (&Offset, OffsetAddress, Info->ExtendedOffsetLength);

+

+  return Offset;

+}

+

+

+

+VOID

+GetHiiDataProperty (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN UINTN                     SkuIdx,

+  IN CONST PCD_DATABASE_HEADER *Info,

+  OUT EFI_GUID                 **VariableGuid,

+  OUT UINT16                   **VariableName

+  )

+{

+  UINT16 NameOffset;

+  UINT16 GuidOffset;

+  UINT8  *HiiDataOffset;

+

+  HiiDataOffset = GetAbsoluteAddress (PcdIndex->HiiData, Info->ImageIndexOffset, Info);

+  HiiDataOffset += (SkuIdx * (Info->HiiGuidOffsetLength + Info->HiiVariableOffsetLength));

+

+  CopyMem (&GuidOffset, HiiDataOffset, Info->HiiGuidOffsetLength);

+  CopyMem (&NameOffset, HiiDataOffset + Info->HiiGuidOffsetLength, Info->HiiVariableOffsetLength);

+  

+  *VariableGuid  = (EFI_GUID *) GetAbsoluteAddress (GuidOffset * sizeof (EFI_GUID), Info->GuidTableOffset, Info);

+  *VariableName  = (UINT16 *)   GetAbsoluteAddress (NameOffset * sizeof (UINT16)  , Info->StringTableOffset, Info);

+  

+  return;

+}

+

+

+

+UINTN

+GetSkuIdIdx (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN CONST PCD_DATABASE_HEADER *Info

+  )

+{

+  UINT8      *SkuIdArray;

+  UINTN      SkuIdx;

+

+  SkuIdArray = GetAbsoluteAddress (PcdIndex->SkuIdArray, Info->ImageIndexOffset, Info);

+  

+  SkuIdx = 0;

+

+  if (PcdIndex->StateByte.SkuEnable) {

+

+     for (; SkuIdx < PcdIndex->SkuCount; SkuIdx++) {

+       if (SkuIdArray[SkuIdx] == Info->SkuId) {

+        break;

+       }

+     }

+

+     if (SkuIdx > PcdIndex->SkuCount) {

+       if (Info->SkuId == 0) {

+         //

+         // If no SKU_ID is set previously

+         // Just retrieve the first value

+         //

+         SkuIdx = 0;

+       } else {

+         //

+         // Just can't find the SKU_ID, ASSERT according to Spec.

+         //

+         ASSERT (FALSE);

+       }

+    }

+      

+  }

+

+  return SkuIdx;

+

+}

+

+

+

+/**

+  The function is the worker function to get the data of a PCD entry.

+

+  @param[in] PcdIndex The PCD Index.

+  @param[in] Info     The attributes of the PCD database.

+  @param[out] Data    The output data.

+

+  @retval VOID

+--*/

+UINT8*

+GetPcdDataPtr (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN CONST PCD_DATABASE_HEADER *Info

+  )

+{

+  UINTN      VariableDataSize;

+  VOID       *VariableData;

+  UINT16     *VariableName;

+  UINT8      *PcdData;

+  EFI_GUID   *VariableGuid;

+  EFI_STATUS Status;

+  UINTN      SkuIdx;

+  UINTN      ExtendedOffset;

+

+  //

+  // If Sku is not enalbed for this PCD Entry.

+  // SkuIdx 0 will be used to compute PcdData

+  //

+  SkuIdx = GetSkuIdIdx (PcdIndex, Info);

+

+  if (PcdIndex->StateByte.HiiEnable) {

+

+    GetHiiDataProperty (PcdIndex, SkuIdx, Info, &VariableGuid, &VariableName);

+

+    Status = GetHiiVariable (VariableGuid, VariableName, &VariableData, &VariableDataSize);

+    ASSERT_EFI_ERROR (Status);

+    ASSERT (VariableDataSize >= (PcdIndex->DatumSize + PcdIndex->ExtendedDataOffset));

+

+    PcdData = (UINT8 *) VariableData + PcdIndex->ExtendedDataOffset;

+

+    return PcdData;

+  }

+

+  //

+  // For VPD and Data type, we need the ExtendedOffset.

+  // So get it here.

+  //

+  ExtendedOffset = GetExtendedDataOffset (PcdIndex, SkuIdx, Info);

+

+  if (PcdIndex->StateByte.VpdEnable) {

+

+    PcdData = (VOID *) (Info->VpdStart + ExtendedOffset);

+    

+    return PcdData;

+  }

+

+  //

+  // For data type, we just need the pointer

+  //

+  PcdData = GetAbsoluteAddress (

+              ExtendedOffset,

+              Info->DataBufferOffset,

+              Info

+              );

+

+  return PcdData;

+

+}

+

+

+

+/**

+  The function locates the PCD_INDEX according to TokeNumber and GUID space given.

+

+  @param[in] TokenNumber The token number.

+  @param[in] Guid        The GUID token space.

+  @param[out] Info       The attributes of the PCD database.

+

+  @retval PCD_INDEX*     The PCD_INDEX found.

+--*/

+PCD_INDEX *

+FindPcdIndex (

+  IN   UINTN                     TokenNumber,

+  IN   CONST EFI_GUID            *Guid,

+  IN   CONST PCD_DATABASE_HEADER *Info,

+  OUT  UINTN                     *Index

+  )

+{

+  PCD_INDEX *PcdIndex;

+  UINTN     Idx;

+  EFI_GUID      *GuidSpace;

+

+  PcdIndex = (PCD_INDEX *) GetAbsoluteAddress (0, Info->PcdIndexOffset, Info);

+

+  for (Idx = 0; Idx < Info->EntryCount; Idx++, PcdIndex++) {

+    if (Index != NULL) {

+      *Index = Idx;

+    }

+    

+    if (PcdIndex->TokenNumber == TokenNumber) {

+      if (Guid == NULL) {

+        if (!PcdIndex->StateByte.ExtendedGuidPresent) {

+          return PcdIndex;

+        }

+      } else {

+        if (PcdIndex->StateByte.ExtendedGuidPresent) {

+          GuidSpace = (EFI_GUID *) GetAbsoluteAddress (PcdIndex->DynamicExGuid, Info->GuidTableOffset, Info);

+          if (CompareGuid (GuidSpace, Guid)) {

+            return PcdIndex;

+          }

+        }

+      }

+    }

+

+  }

+

+  if (Index != NULL) {

+    *Index = 0;

+  }

+  

+  return NULL;

+

+}

+

+

+

+/**

+  The function set the PCD Entry data value according to the

+  PCD_DATA_TYPE given.

+

+  @param[out] OutData The output data.

+  @param[in]  InData  The input data.

+  @param[in]  Len     The length of the data.

+

+

+  @retval EFI_SUCESS If data value is found according to SKU_ID.

+  @retval EFI_NOT_FOUND If not such a value is found.

+

+--*/

+VOID

+SetDataBasedOnType (

+  OUT VOID *       OutData,

+  IN CONST VOID *  InData,

+  IN UINTN         Len

+)

+{

+  CopyMem (OutData, InData, Len);

+

+  return;

+}

+

+

+

+/**

+  The function returns the actual address of item in the PCD

+  database according to its Segment and Offset.

+

+  @param[out] Offset        The offset within the segment.

+  @param[in]  SegmentStart  The starting address of the segment.

+  @param[in]  DatabaseStart The base address of the PCD DataBase.

+

+

+  @retval UINT8* The absolute address.

+

+--*/

+UINT8 *

+GetAbsoluteAddress (

+  IN UINTN                        Offset,

+  IN UINTN                        SegmentStart,

+  IN CONST PCD_DATABASE_HEADER    *DatabaseStart

+  )

+{

+  UINT8 *Address;

+

+  Address = (UINT8 *) DatabaseStart + SegmentStart + Offset;

+

+  return Address;

+}

+

+

+

+/**

+  The function retrieves the PCD data value according to

+  TokenNumber and Guid space given.

+

+  @param[in]  Database    The PCD Database Instance.

+  @param[in]  TokenNumber The token number.

+  @param[in]  Guid        The Guid space.

+  @param[in]  Type        The storage type.

+  @param[out] Data        The output data.

+

+  @retval VOID

+

+--*/

+VOID

+GetPcdEntryWorker (

+  IN CONST PCD_DATABASE_HEADER  *Info,

+  IN UINTN                      TokenNumber,

+  IN CONST EFI_GUID             *Guid,  OPTIONAL

+  IN PCD_DATA_TYPE              Type,

+  OUT VOID                      *Data

+  )

+{

+  PCD_INDEX         *PcdIndex;

+  UINT8             *PcdData;

+

+  ASSERT (Data != NULL);

+

+  //

+  // Find the PCD entry in list in memory first

+  //

+  PcdIndex = FindPcdIndex (TokenNumber, Guid, Info, NULL);

+

+  ASSERT (PcdIndex != NULL);

+

+  ASSERT (PcdIndex->StateByte.DataType == Type);

+

+  PcdData = GetPcdDataPtr (PcdIndex, Info);

+

+  GetDataBasedOnType (PcdIndex->StateByte.DataType, PcdData, Data, PcdIndex->DatumSize);

+

+  return;

+}

+

+

+

+/**

+  The function retrieves the PCD data value according to

+  TokenNumber and Guid space given.

+

+  @param[in]  Database    The PCD Database Instance.

+  @param[in]  TokenNumber The token number.

+  @param[in]  Guid        The Guid space.

+

+  @retval     UINTN       The size of the PCD Entry.

+

+--*/

+UINTN

+GetPcdEntrySizeWorker (

+  IN CONST PCD_DATABASE_HEADER  *Info,

+  IN UINTN                      TokenNumber,

+  IN CONST EFI_GUID             *Guid  OPTIONAL

+  )

+{

+  PCD_INDEX         *PcdIndex;

+

+  //

+  // Find the PCD entry in list in memory first

+  //

+  PcdIndex = FindPcdIndex (TokenNumber, Guid, Info, NULL);

+

+  ASSERT (PcdIndex != NULL);

+

+  return PcdIndex->DatumSize;

+

+}

+

+

+

+/**

+  The function checks if given GUID space match the record

+  in the PCD_INDEX.

+

+  @param[in]  Guid              The GUID space.

+  @param[in]  PcdIndex          The PCD_INDEX.

+  @param[in]  Info              The attribute of the PCD DATABASE.

+

+  @retval     TRUE              The GUID space match the record.

+  @retval     FALSE             Othewise.

+

+--*/

+BOOLEAN

+PeiImageIndexMatchGuidSpace (

+  IN  CONST EFI_GUID            *Guid,

+  IN  CONST PCD_INDEX           *PcdIndex,

+  IN  CONST PCD_DATABASE_HEADER *Info

+)

+{

+  EFI_GUID *GuidSpace;

+

+  if (PcdIndex->StateByte.ExtendedGuidPresent) {

+    GuidSpace = (EFI_GUID *) GetAbsoluteAddress (PcdIndex->DynamicExGuid, Info->GuidTableOffset, Info);

+    return CompareGuid (GuidSpace, Guid);

+  }

+

+  return FALSE;

+}

+

+

+/**

+  The function looks for the next PCD ENTRY.

+  If *TokenNumber is 0, the first TokenNumber in

+  the GUID token space is return.

+  If there is no next TokenNumber found,

+  *TokenNumber will be 0.

+

+  @param[in]      Database          The PCD Database Instance.

+  @param[in,out]  TokenNumber       The token number.

+  @param[in]      Guid              The Guid space.

+

+  @retval     EFI_NOT_FOUND     Can't find the PCD_ENTRY.

+  @retval     EFI_SUCCESS       Operation succesful.

+

+--*/

+EFI_STATUS

+GetNextTokenWorker (

+  IN CONST PCD_DATABASE_HEADER  *Info,

+  IN OUT UINTN                  *TokenNumber,

+  IN CONST EFI_GUID             *Guid     OPTIONAL

+  )

+{

+  PCD_INDEX         *PcdIndex;

+  UINTN             Idx;

+  BOOLEAN           Found;

+

+  Idx = 0;

+  Found = FALSE;

+  PcdIndex = (PCD_INDEX *) GetAbsoluteAddress (0, Info->PcdIndexOffset, Info);

+

+  while ((Idx < Info->EntryCount) && !Found) {

+    if (*TokenNumber == 0) {

+      if (Guid == NULL || PeiImageIndexMatchGuidSpace (Guid, PcdIndex, Info)) {

+        *TokenNumber = PcdIndex->TokenNumber;

+        return EFI_SUCCESS;

+      }

+    } else {

+      if (PcdIndex->TokenNumber == *TokenNumber) {

+        if (Guid == NULL || PeiImageIndexMatchGuidSpace (Guid, PcdIndex, Info)) {

+          Found = TRUE;

+        }

+      }

+    }

+

+    PcdIndex++;

+    Idx++;

+  }

+

+  //

+  // No PCD Entry in the database match the GUID space given.

+  //

+  if (*TokenNumber == 0) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Can't find the PCD Entry

+  //

+  if (!Found) {

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Move to the Next Entry

+  //

+  Idx++;

+  PcdIndex++;

+

+  //

+  // Now look for the Next TokenNumber

+  //

+  while (Idx < Info->EntryCount) {

+    if (Guid == NULL || PeiImageIndexMatchGuidSpace (Guid, PcdIndex, Info)) {

+      *TokenNumber = PcdIndex->TokenNumber;

+      return EFI_SUCCESS;

+    }

+    PcdIndex++;

+    Idx++;

+  }

+

+  //

+  // Reache the last TokeNumber.

+  //

+  *TokenNumber = 0;

+  return EFI_SUCCESS;

+}

+

+

+/**

+  The function is the worker function to set the data of a PCD entry.

+

+  @param[in] PcdIndex The PCD Index.

+  @param[in] Info     The attributes of the PCD database.

+  @param[in] Data     The input data.

+

+  @retval VOID

+--*/

+EFI_STATUS

+SetPcdData (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN CONST PCD_DATABASE_HEADER *Info,

+  IN CONST VOID                *Data

+  )

+{

+  UINT16     *VariableName;

+  UINT8      *PcdData;

+  EFI_GUID   *VariableGuid;

+  EFI_STATUS Status;

+  UINTN      SkuIdx;

+  UINTN      ExtendedOffset;

+

+  if (PcdIndex->StateByte.VpdEnable) {

+    ASSERT (FALSE);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  SkuIdx = GetSkuIdIdx (PcdIndex, Info);

+

+  //

+  // For Hii and Data type, we need the ExtendedOffset.

+  // So get it here.

+  //

+  ExtendedOffset = GetExtendedDataOffset (PcdIndex, SkuIdx, Info);

+

+  if (PcdIndex->StateByte.HiiEnable) {

+  	GetHiiDataProperty (PcdIndex, SkuIdx, Info, &VariableGuid, &VariableName);

+

+    Status = SetHiiVariable (VariableGuid,

+                            VariableName,

+                            Data,

+                            PcdIndex->DatumSize,

+                            ExtendedOffset

+                            );

+

+    return Status;

+  }

+

+

+  PcdData = GetAbsoluteAddress (

+              ExtendedOffset,

+              Info->DataBufferOffset,

+              Info

+              );

+

+  CopyMem (PcdData, Data, PcdIndex->DatumSize);

+

+  return EFI_SUCCESS;

+

+}

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Common/PcdCommon.h b/edk2/EdkModulePkg/Universal/PCD/Common/PcdCommon.h
new file mode 100644
index 0000000..f61aa5b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Common/PcdCommon.h
@@ -0,0 +1,386 @@
+/** @file

+Common functions used by PCD PEIM and PCD DXE.

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name: PcdCommon.h

+

+**/

+

+#ifndef __PCD_COMMON_H__

+#define __PCD_COMMON_H__

+

+//

+// Enumeration for PCD_DATA_TYPE

+//

+typedef enum {

+  PcdByte8,

+  PcdByte16,

+  PcdByte32,

+  PcdByte64,

+  PcdPointer,

+  PcdBoolean

+} PCD_DATA_TYPE;

+

+

+//

+// The definitions for Global PCD Length Fields

+//

+#define PCD_LENGTH_BIT8   0x01

+#define PCD_LENGTH_BIT16  0x02

+#define PCD_LENGTH_BIT24  0x03

+#define PCD_LENGTH_BIT32  0x04

+

+

+

+/*

+ * This data structure is used in <PCD_IMAGE> transverse

+ */

+typedef struct {

+  UINTN                EntryCount;

+  UINTN                GlobalOffsetLength;

+  UINTN                GlobalTokenLength;

+  UINTN                GlobalGuidTabIdxLength;

+  UINTN                GlobalDatumLength;

+  UINTN                GlobalStrTabIdxLength;

+  

+  CONST UINT8          *DataDefaultStart;

+  UINTN                DataDefaultLength;

+  UINTN                WholeDataDefaultLength;

+  CONST UINT8          *IndexStart;

+  UINTN                IndexLength;

+  CONST GUID           *GuidTableStart;

+  UINTN                GuidTableLength;

+  CONST UINT16         *StringTableStart;

+  UINTN                StringTableLength;

+  /* Length of the <PCD_IMAGE> in byte.

+     This info is from Section header

+     in FFS */

+  UINTN               ImageLength;

+  CONST UINT8         *ImageStart;

+

+} PCD_IMAGE_RECORD;

+

+

+

+typedef struct {

+  BOOLEAN       HiiEnable;

+  BOOLEAN       SkuEnable;

+  BOOLEAN       VpdEnable;

+  BOOLEAN       SkuDataArrayEnable;

+  PCD_DATA_TYPE DataType;

+  BOOLEAN       ExtendedGuidPresent;

+} PCD_STATEBYTE;

+

+

+

+typedef struct  {

+  //

+  // All Pointer's Offset in byte

+  //

+  UINT32           TokenNumber;

+  PCD_STATEBYTE    StateByte;

+  UINT32           HiiData;

+  UINT32           SkuIdArray;   //Pointer

+  UINT32           ExtendedDataOffset;

+  UINT32           DatumSize;

+  UINT16           DynamicExGuid; //Pointer

+  UINT8            SkuCount;

+} PCD_INDEX;

+

+

+

+/* 

+ * PCD Image Definition according PCD Specification 0.51. 

+ *

+ */

+#pragma pack(1)

+typedef struct {

+  UINT8 ImageLength[3]; 

+  //

+  // The length of PCD_FFS_ENCODING is included

+  // in ImageLength

+  //

+  UINT8 DataBufferLength[3];

+  UINT8 WholeDataBufferLength[3];

+  UINT8 PcdIndexLength[3];

+  UINT8 GuidTableLength[3];

+  //

+  // The StringTable can be computed using:

+  // ImageLength, DataBufferLength, PcdIndexLength, GuidTableLength,

+  // and length of PCD_FFS_ENCODING

+  //

+  UINT8 EntryCount[3];

+  UINT8 GlobalOffsetLength[1];

+  UINT8 GlobalTokenLength[1];

+  UINT8 GuidLength[1];

+  UINT8 GlobalDatumLength[1];

+  UINT8 GlobalStrTabIdxLength[1];

+} PCD_FFS_ENCODING;

+#pragma pack()

+

+

+  

+typedef struct {

+  UINTN      DatabaseLen;

+  UINTN      EntryCount;

+  UINTN      InfoLength;

+  UINTN      GuidTableOffset;

+  UINTN      PcdIndexOffset;

+  UINTN      StringTableOffset;

+  UINTN      CallbackTableOffset;

+  UINTN      ImageIndexOffset;

+  UINTN      DataBufferOffset;

+  UINTN      MaxCallbackNum;

+  UINTN      HiiVariableOffsetLength;

+  UINTN      HiiGuidOffsetLength;

+  UINTN      ExtendedOffsetLength;

+  UINT8      *VpdStart;

+  UINTN      SkuId;

+} PCD_DATABASE_HEADER;

+

+

+

+typedef struct {

+  PCD_DATABASE_HEADER Info;

+  EFI_GUID            GuidTable[1];

+} PCD_DATABASE;

+

+extern EFI_GUID gPcdDataBaseHobGuid;

+

+

+/**

+  The function returns the actual address of item in the PCD

+  database according to its Segment and Offset.

+

+  @param[out] Offset        The offset within the segment.

+  @param[in]  SegmentStart  The starting address of the segment.

+  @param[in]  DatabaseStart The base address of the PCD DataBase.

+  

+

+  @retval EFI_SUCESS If data value is found according to SKU_ID.

+  @retval EFI_NOT_FOUND If not such a value is found.

+

+--*/

+UINT8 *

+GetAbsoluteAddress (

+  IN UINTN        Offset, 

+  IN UINTN        SegmentStart, 

+  IN CONST VOID   *Base

+  )

+;

+

+

+

+/**

+  The function return the number of Unicode Character in a NULL terminated string.

+  The NULL is  NOT counted.

+  

+  @param[in] String The unicode string starts from an unaligned address.

+  

+  @retval UINTN     The number of Unicode characters.

+--*/

+UINTN

+GetUnalignedStrLen (

+  UINT16 *String

+);

+

+

+/**

+  The function retrieves the PCD data value according to 

+  TokenNumber and Guid space given.

+

+  @param[in]  Info        The PCD Database Info.

+  @param[in]  TokenNumber The token number.

+  @param[in]  Guid        The Guid space.

+  @param[in]  Type        The storage type.

+  @param[out] Data        The output data.

+

+  @retval VOID

+

+--*/

+VOID

+GetPcdEntryWorker (

+  IN     CONST PCD_DATABASE_HEADER  *Info,

+  IN     UINTN                      TokenNumber,

+  IN     CONST GUID                 *Guid,  OPTIONAL

+  IN     PCD_DATA_TYPE              Type,

+  OUT    VOID                       *Data

+  )

+;

+

+

+

+/**

+  The function retrieves the PCD data value according to 

+  TokenNumber and Guid space given.

+

+  @param[in]  Info        The PCD Database info.

+  @param[in]  TokenNumber The token number.

+  @param[in]  Guid        The Guid space.

+

+  @retval     UINTN       The size of the PCD Entry.

+

+--*/

+UINTN

+GetPcdEntrySizeWorker (

+  IN CONST PCD_DATABASE_HEADER  *Info,

+  IN UINTN                      TokenNumber,

+  IN CONST GUID                 *Guid  OPTIONAL

+  )

+;

+

+

+

+/**

+  The function looks for the next PCD ENTRY.

+  If *TokenNumber is 0, the first TokenNumber in

+  the GUID token space is return.

+  If there is no next TokenNumber found,

+  *TokenNumber will be 0.

+

+  @param[in]      Info              The PCD Database info.

+  @param[in,out]  TokenNumber       The token number.

+  @param[in]      Guid              The Guid space.

+  

+  @retval     EFI_NOT_FOUND     Can't find the PCD_ENTRY.

+  @retval     EFI_SUCCESS       Operation succesful.

+

+--*/

+EFI_STATUS

+GetNextTokenWorker (

+  IN CONST PCD_DATABASE_HEADER    *Info,

+  IN OUT UINTN                    *TokenNumber,

+  IN CONST GUID                   *Guid     OPTIONAL

+  )

+;

+

+

+

+/**

+  The function is the worker function to set the data of a PCD entry.

+  

+  @param[in] PcdIndex The PCD Index.

+  @param[in] Info     The attributes of the PCD database.

+  @param[in] Data     The input data.

+  

+  @retval VOID

+--*/

+EFI_STATUS

+SetPcdData (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN CONST PCD_DATABASE_HEADER *Info,

+  IN CONST VOID                *Data

+  )

+;

+

+

+/**

+  The function is provided by PCD PEIM and PCD DXE driver to

+  do the work of reading a HII variable from variable service.

+  

+  @param[in] VariableGuid     The Variable GUID.

+  @param[in] VariableName     The Variable Name.

+  @param[out] VariableData    The output data.

+  @param[out] VariableSize    The size of the variable.

+  

+  @retval EFI_SUCCESS         Operation successful.

+  @retval EFI_SUCCESS         Variablel not found.

+--*/

+EFI_STATUS

+GetHiiVariable (

+  IN  EFI_GUID     *VariableGuid,

+  IN  UINT16       *VariableName,

+  OUT VOID         **VariableData,

+  OUT UINTN        *VariableSize

+  )

+;

+

+

+

+/**

+  The function is provided by PCD PEIM and PCD DXE driver to

+  do the work of reading a HII variable from variable service.

+  

+  @param[in] VariableGuid     The Variable GUID.

+  @param[in] VariableName     The Variable Name.

+  @param[in] Data             The input data.

+  @param[out] VariableSize    The size of the variable.

+  @param[in] Offset           The offset of the variable data that a PCD entry will starts from.

+  

+  @retval EFI_SUCCESS         Operation successful.

+  @retval EFI_SUCCESS         Variablel not found.

+--*/

+EFI_STATUS

+SetHiiVariable (

+  IN  EFI_GUID     *VariableGuid,

+  IN  UINT16       *VariableName,

+  IN  CONST VOID   *Data,

+  IN  UINTN        VariableSize,

+  IN  UINTN        Offset

+  )

+;

+

+/**

+  The function locates the PCD_INDEX according to TokeNumber and GUID space given.

+

+  @param[in] TokenNumber The token number.

+  @param[in] Guid        The GUID token space.

+  @param[out] Info       The attributes of the PCD database.

+

+  @retval PCD_INDEX*     The PCD_INDEX found.

+--*/

+PCD_INDEX *

+FindPcdIndex (

+  IN   UINTN                     TokenNumber,

+  IN   CONST GUID                *Guid,

+  IN   CONST PCD_DATABASE_HEADER *Info,

+  OUT  UINTN                     *Index

+  )

+;

+

+/**

+  (WQBUGBUG: You must handle the new SKU_ID encoding.

+  The function is the worker function to get the data of a PCD entry.

+

+  @param[in] PcdIndex The PCD Index.

+  @param[in] Info     The attributes of the PCD database.

+  @param[out] Data    The output data.

+

+  @retval VOID

+--*/

+UINT8*

+GetPcdDataPtr (

+  IN CONST PCD_INDEX           *PcdIndex,

+  IN CONST PCD_DATABASE_HEADER *Info

+  )

+;

+

+/**

+  The function retrieves the PCD data value according to

+  the PCD_DATA_TYPE specified.

+

+  @param[in] Type The PCD_DATA_TYPE used to interpret the data.

+  @param[in] InData The input data.

+  @param[in] OutData The output data.

+  @param[in] Len The length of the data; it is mainly used for PcdPointer type.

+

+  @retval VOID

+--*/

+VOID

+GetDataBasedOnType (

+  IN PCD_DATA_TYPE Type,

+  IN VOID          *InData,

+  OUT VOID         *OutData,

+  IN UINTN         Len

+  )

+;

+#endif

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.c b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.c
new file mode 100644
index 0000000..64191a7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.c
@@ -0,0 +1,565 @@
+/** @file

+PCD DXE driver

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+

+Module Name: Pcd.c

+

+**/

+

+#include "Service.h"

+

+

+PCD_PROTOCOL mPcdInstance = {

+  DxePcdSetSku,

+

+  DxePcdGet8,

+  DxePcdGet16,

+  DxePcdGet32,

+  DxePcdGet64,

+  DxePcdGetPtr,

+  DxePcdGetBool,

+  DxePcdGetSize,

+

+  DxePcdGet8Ex,

+  DxePcdGet16Ex,

+  DxePcdGet32Ex,

+  DxePcdGet64Ex,

+  DxePcdGetPtrEx,

+  DxePcdGetBoolEx,

+  DxePcdGetSizeEx,

+

+  DxePcdSet8,

+  DxePcdSet16,

+  DxePcdSet32,

+  DxePcdSet64,

+  DxePcdSetPtr,

+  DxePcdSetBool,

+

+  DxePcdSet8Ex,

+  DxePcdSet16Ex,

+  DxePcdSet32Ex,

+  DxePcdSet64Ex,

+  DxePcdSetPtrEx,

+  DxePcdSetBoolEx,

+

+  DxeRegisterCallBackOnSet,

+  DxeUnRegisterCallBackOnSet,

+  DxePcdGetNextToken

+};

+

+

+//

+// Static global to reduce the code size

+//

+static EFI_HANDLE NewHandle = NULL;

+

+EFI_STATUS

+EFIAPI

+PcdDxeInit (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_STATUS          Status;

+

+  //

+  // Make sure the Pcd Protocol is not already installed in the system

+  //

+  

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid);

+  

+  BuildPcdDxeDataBase ();

+

+  //

+  // BugBug Check if PcdDatabase is already installed.

+  //

+  

+  Status = gBS->InstallProtocolInterface (

+                  &NewHandle,

+                  &gPcdProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &mPcdInstance

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+

+}

+

+

+VOID

+EFIAPI

+DxePcdSetSku (

+  IN  SKU_ID         SkuId

+  )

+{

+  mPcdDatabase->PeiDb.Init.SystemSkuId = SkuId;

+  

+  return;

+}

+

+

+

+UINT8

+EFIAPI

+DxePcdGet8 (

+  IN PCD_TOKEN_NUMBER         TokenNumber

+  )

+{

+  return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));

+}

+

+

+

+UINT16

+EFIAPI

+DxePcdGet16 (

+  IN PCD_TOKEN_NUMBER         TokenNumber

+  )

+{

+  return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));

+}

+

+

+

+UINT32

+EFIAPI

+DxePcdGet32 (

+  IN PCD_TOKEN_NUMBER         TokenNumber

+  )

+{

+  return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));

+}

+

+

+

+UINT64

+EFIAPI

+DxePcdGet64 (

+  IN PCD_TOKEN_NUMBER          TokenNumber

+  )

+{

+  return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64)));

+}

+

+

+

+VOID *

+EFIAPI

+DxePcdGetPtr (

+  IN PCD_TOKEN_NUMBER          TokenNumber

+  )

+{

+  return GetWorker (TokenNumber, 0);

+}

+

+

+

+BOOLEAN

+EFIAPI

+DxePcdGetBool (

+  IN PCD_TOKEN_NUMBER          TokenNumber

+  )

+{

+  return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));

+}

+

+

+

+UINTN

+EFIAPI

+DxePcdGetSize (

+  IN PCD_TOKEN_NUMBER          TokenNumber

+  )

+{

+  UINT16 * SizeTable;

+

+  SizeTable = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? mPcdDatabase->PeiDb.Init.SizeTable :

+                                                    mPcdDatabase->DxeDb.Init.SizeTable;

+

+

+  TokenNumber = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TokenNumber : (TokenNumber - PEI_LOCAL_TOKEN_NUMBER);

+

+  return SizeTable[TokenNumber];

+}

+

+

+

+UINT8

+EFIAPI

+DxePcdGet8Ex (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER      ExTokenNumber

+  )

+{

+  return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));

+}

+

+

+

+UINT16

+EFIAPI

+DxePcdGet16Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER     ExTokenNumber

+  )

+{

+  return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16)));

+}

+

+

+

+UINT32

+EFIAPI

+DxePcdGet32Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER      ExTokenNumber

+  )

+{

+  return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32)));

+}

+

+

+

+UINT64

+EFIAPI

+DxePcdGet64Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER      ExTokenNumber

+  )

+{

+  return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));

+}

+

+

+

+VOID *

+EFIAPI

+DxePcdGetPtrEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER      ExTokenNumber

+  )

+{

+  return ExGetWorker (Guid, ExTokenNumber, 0);

+}

+

+

+

+BOOLEAN

+EFIAPI

+DxePcdGetBoolEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER      ExTokenNumber

+  )

+{

+  return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN)));

+}

+

+

+

+UINTN

+EFIAPI

+DxePcdGetSizeEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER      ExTokenNumber

+  )

+{

+  return DxePcdGetSize(GetExPcdTokenNumber (Guid, ExTokenNumber));

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet8 (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT8              Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet16 (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT16             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet32 (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT32             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet64 (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT64             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetPtr (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINTN              SizeOfBuffer,

+  IN VOID               *Buffer

+  )

+{

+  return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetBool (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN BOOLEAN            Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet8Ex (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINT8                  Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet16Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber,

+  IN UINT16            Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet32Ex (

+  IN CONST EFI_GUID     *Guid,

+  IN PCD_TOKEN_NUMBER   ExTokenNumber,

+  IN UINT32             Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet64Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber,

+  IN UINT64            Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetPtrEx (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINTN                  SizeOfBuffer,

+  IN VOID                   *Buffer

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              Buffer, 

+                              SizeOfBuffer, 

+                              TRUE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetBoolEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              TRUE

+                              );

+}

+

+

+

+

+EFI_STATUS

+EFIAPI

+DxeRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+  )

+{

+  ASSERT (CallBackFunction != NULL);

+  

+  return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxeUnRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+  )

+{

+  ASSERT (CallBackFunction != NULL);

+  

+  return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+DxePcdGetNextToken (

+  IN CONST EFI_GUID         *Guid, OPTIONAL

+  IN OUT   PCD_TOKEN_NUMBER *TokenNumber

+  )

+{

+  PCD_TOKEN_NUMBER    ExTokenNumber;

+  

+  //

+  // Scan the local token space

+  //

+  if (Guid == NULL) {

+    (*TokenNumber)++;

+    if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {

+      return EFI_SUCCESS;

+    } else {

+      if (*TokenNumber >= PEI_NEX_TOKEN_NUMBER &&

+          *TokenNumber < PEI_LOCAL_TOKEN_NUMBER) {

+        //

+        // The first Non-Ex type Token Number for DXE PCD 

+        // database is PEI_LOCAL_TOKEN_NUMBER

+        //

+        *TokenNumber = PEI_LOCAL_TOKEN_NUMBER;

+        return EFI_SUCCESS;

+      } else if (*TokenNumber >= DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER) {

+        *TokenNumber = PCD_INVALID_TOKEN_NUMBER;

+        return EFI_SUCCESS;

+      }

+    }

+  }

+

+  if (PEI_EXMAP_TABLE_EMPTY && PEI_EXMAP_TABLE_EMPTY) {

+    *TokenNumber = (UINTN) PCD_INVALID_TOKEN_NUMBER;

+    return EFI_NOT_FOUND;

+  }

+

+  ExTokenNumber = *TokenNumber;

+  if (!PEI_EXMAP_TABLE_EMPTY) {

+    ExTokenNumber = ExGetNextTokeNumber (

+                        Guid,

+                        ExTokenNumber,

+                        mPcdDatabase->PeiDb.Init.GuidTable,

+                        sizeof(mPcdDatabase->PeiDb.Init.GuidTable),

+                        mPcdDatabase->PeiDb.Init.ExMapTable,

+                        sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)

+                        );

+  }

+

+  if (!DXE_EXMAP_TABLE_EMPTY) {

+    ExTokenNumber = ExGetNextTokeNumber (

+                        Guid,

+                        ExTokenNumber,

+                        mPcdDatabase->PeiDb.Init.GuidTable,

+                        sizeof(mPcdDatabase->PeiDb.Init.GuidTable),

+                        mPcdDatabase->PeiDb.Init.ExMapTable,

+                        sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)

+                        );

+  }

+

+  *TokenNumber = ExTokenNumber;

+

+  return EFI_SUCCESS;

+}

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.dxs b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.dxs
new file mode 100644
index 0000000..9e814a6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PcdEmulator.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.mbd b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.mbd
new file mode 100644
index 0000000..1623395
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PcdDxe</BaseName>

+    <Guid>80CF7257-87AB-47f9-A3FE-D50B76D89541</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>UefiLib</Library>

+    <Library>HiiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.msa b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.msa
new file mode 100644
index 0000000..b29d839
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/Pcd.msa
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PcdDxe</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>80CF7257-87AB-47f9-A3FE-D50B76D89541</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DxeIpl module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Service.c</Filename>

+    <Filename>Pcd.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Pcd</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="ALWAYS_CONSUMED" HobType="GUID_EXTENSION">

+      <Name>PcdDataBaseHob</Name>

+      <C_Name>gPcdDataBaseHobGuid</C_Name>

+      <Guid>0xea296d92, 0xb69,  0x423c, 0x8c, 0x28, 0x33, 0xb4, 0xe0, 0xa9, 0x12, 0x68</Guid>

+    </Hob>

+  </Hobs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PcdDataBaseHob</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PcdDxeInit</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+      <Token>0x0001000f</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdVpdBaseAddress</C_Name>

+      <Token>0x00010010</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/Service.c b/edk2/EdkModulePkg/Universal/PCD/Dxe/Service.c
new file mode 100644
index 0000000..00437f1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/Service.c
@@ -0,0 +1,719 @@
+/** @file

+Private functions used by PCD DXE driver.s

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+

+Module Name: Service.c

+

+**/

+#include "Service.h"

+

+

+//

+// Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h

+// Compression Algorithm will take care of the size optimization.

+//

+

+PCD_DATABASE * mPcdDatabase;

+

+LIST_ENTRY *mCallbackFnTable;

+

+VOID *

+GetWorker (

+  PCD_TOKEN_NUMBER  TokenNumber,

+  UINTN             GetSize

+  )

+{

+  UINT32              *LocalTokenNumberTable;

+  UINT16              *SizeTable;

+  BOOLEAN             IsPeiDb;

+  UINTN               Size;

+  UINT32              Offset;

+  EFI_GUID            *GuidTable;

+  UINT16              *StringTable;

+  EFI_GUID            *Guid;

+  UINT16              *Name;

+  VARIABLE_HEAD       *VariableHead;

+  EFI_STATUS          Status;

+  UINTN               DataSize;

+  VOID                *Data;

+  VPD_HEAD            *VpdHead;

+  UINT8               *PcdDb;

+  UINT16              StringTableIdx;      

+  UINT32              LocalTokenNumber;

+

+

+  ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);

+

+  Size = DxePcdGetSize (TokenNumber);

+  ASSERT (GetSize == Size || GetSize == 0);

+

+  

+  IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;

+

+  LocalTokenNumberTable  = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : 

+                                     mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;

+

+  SizeTable              = IsPeiDb ? mPcdDatabase->PeiDb.Init.SizeTable: 

+                                     mPcdDatabase->DxeDb.Init.SizeTable;

+

+  TokenNumber            = IsPeiDb ? TokenNumber :

+                                     TokenNumber - PEI_LOCAL_TOKEN_NUMBER;

+

+  LocalTokenNumber = LocalTokenNumberTable[TokenNumber];

+  

+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {

+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);

+  }

+

+  PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);

+  StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :

+                          mPcdDatabase->DxeDb.Init.StringTable;

+  

+  Offset     = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;

+  

+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {

+    case PCD_TYPE_VPD:

+      VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);

+      return (VOID *) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);

+      

+    case PCD_TYPE_HII:

+      GuidTable   = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :

+                              mPcdDatabase->DxeDb.Init.GuidTable;

+                              

+      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);

+      

+      Guid = &(GuidTable[VariableHead->GuidTableIndex]);

+      Name = &(StringTable[VariableHead->StringIndex]);

+

+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);

+      ASSERT_EFI_ERROR (Status);

+      ASSERT (DataSize >= (UINTN) (VariableHead->Offset + Size));

+

+      return (UINT8 *) Data + VariableHead->Offset;

+

+    case PCD_TYPE_STRING:

+      StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);

+      return (VOID *) &StringTable[StringTableIdx];

+

+    case PCD_TYPE_DATA:

+      return (VOID *) ((UINT8 *) PcdDb + Offset);

+      break;

+

+    default:

+      ASSERT (FALSE);

+      break;

+      

+  }

+

+  ASSERT (FALSE);

+      

+  return NULL;

+  

+}

+

+

+

+EFI_STATUS

+DxeRegisterCallBackWorker (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST GUID              *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+)

+{

+  CALLBACK_FN_ENTRY       *FnTableEntry;

+  LIST_ENTRY              *ListHead;

+  LIST_ENTRY              *ListNode;

+

+  if (Guid != NULL) {

+    TokenNumber = GetExPcdTokenNumber (Guid, TokenNumber);

+  }

+

+  ListHead = &mCallbackFnTable[TokenNumber];

+  ListNode = GetFirstNode (ListHead);

+

+  while (ListNode != ListHead) {

+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);

+

+    if (FnTableEntry->CallbackFn == CallBackFunction) {

+      //

+      // We only allow a Callback function to be register once

+      // for a TokenNumber. So just return EFI_SUCCESS

+      //

+      return EFI_SUCCESS;

+    }

+    ListNode = GetNextNode (ListHead, ListNode);

+  }

+

+  FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));

+  ASSERT (FnTableEntry != NULL);

+

+  FnTableEntry->CallbackFn = CallBackFunction;

+  InsertTailList (ListHead, &FnTableEntry->Node);

+  

+  return EFI_SUCCESS;

+}

+

+

+

+

+EFI_STATUS

+DxeUnRegisterCallBackWorker (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST GUID              *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+)

+{

+  CALLBACK_FN_ENTRY       *FnTableEntry;

+  LIST_ENTRY              *ListHead;

+  LIST_ENTRY              *ListNode;

+

+  if (Guid != NULL) {

+    TokenNumber = GetExPcdTokenNumber (Guid, TokenNumber);

+  }

+

+  ListHead = &mCallbackFnTable[TokenNumber];

+  ListNode = GetFirstNode (ListHead);

+

+  while (ListNode != ListHead) {

+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);

+

+    if (FnTableEntry->CallbackFn == CallBackFunction) {

+      //

+      // We only allow a Callback function to be register once

+      // for a TokenNumber. So we can safely remove the Node from

+      // the Link List and return EFI_SUCCESS.

+      //

+      RemoveEntryList (ListNode);

+      FreePool (FnTableEntry);

+      

+      return EFI_SUCCESS;

+    }

+    ListNode = GetNextNode (ListHead, ListNode);

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+

+

+PCD_TOKEN_NUMBER

+ExGetNextTokeNumber (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       TokenNumber,

+  IN EFI_GUID               *GuidTable,

+  IN UINTN                  SizeOfGuidTable,

+  IN DYNAMICEX_MAPPING      *ExMapTable,

+  IN UINTN                  SizeOfExMapTable

+  )

+{

+  EFI_GUID         *MatchGuid;

+  UINTN            Idx;

+  UINTN            GuidTableIdx;

+  BOOLEAN          Found;

+

+  MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);

+  if (MatchGuid == NULL) {

+    return PCD_INVALID_TOKEN_NUMBER;

+  }

+

+  Found = FALSE;

+  GuidTableIdx = MatchGuid - GuidTable;

+  for (Idx = 0; Idx < SizeOfExMapTable; Idx++) {

+    if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {

+      Found = TRUE;

+      break;

+    }

+  }

+

+  if (Found) {

+    if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {

+      return ExMapTable[Idx].ExTokenNumber;

+    }

+    

+    for ( ; Idx < SizeOfExMapTable; Idx++) {

+      if (ExMapTable[Idx].ExTokenNumber == TokenNumber) {

+        Idx++;

+        if (Idx == SizeOfExMapTable) {

+          //

+          // Exceed the length of ExMap Table

+          //

+          return PCD_INVALID_TOKEN_NUMBER;

+        } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {

+          //

+          // Found the next match

+          //

+          return ExMapTable[Idx].ExTokenNumber;

+        } else {

+          //

+          // Guid has been changed. It is the next Token Space Guid.

+          // We should flag no more TokenNumber.

+          //

+          return PCD_INVALID_TOKEN_NUMBER;

+        }

+      }

+    }

+  }

+  

+  return PCD_INVALID_TOKEN_NUMBER;

+}

+  

+

+

+

+VOID

+BuildPcdDxeDataBase (

+  VOID

+)

+{

+  PEI_PCD_DATABASE    *PeiDatabase;

+  EFI_HOB_GUID_TYPE   *GuidHob;

+  UINTN               Idx;

+

+  mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));

+  ASSERT (mPcdDatabase != NULL);

+

+  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);

+

+  if (GuidHob != NULL) {

+

+    //

+    // We will copy over the PEI phase's PCD Database.

+    // 

+    // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM

+    // should not be included at all. So the GuidHob could

+    // be NULL. If it is NULL, we just copy over the DXE Default

+    // Value to PCD Database.

+    //

+    

+    PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);

+    //

+    // Copy PCD Entries refereneced in PEI phase to PCD DATABASE

+    //

+    CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));

+  }

+

+  //

+  // Copy PCD Entries with default value to PCD DATABASE

+  //

+  CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));

+

+

+  //

+  // Initialized the Callback Function Table

+  //

+

+  if (PCD_TOTAL_TOKEN_NUMBER != 0) {

+    mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER);

+  }

+  

+  for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) {

+    InitializeListHead (&mCallbackFnTable[Idx]);

+  }

+    

+  return;

+}

+

+

+

+EFI_STATUS

+GetHiiVariable (

+  IN  EFI_GUID      *VariableGuid,

+  IN  UINT16        *VariableName,

+  OUT VOID          ** VariableData,

+  OUT UINTN         *VariableSize

+  )

+{

+  UINTN      Size;

+  EFI_STATUS Status;

+  VOID       *Buffer;

+

+  Status = EfiGetVariable (

+    (UINT16 *)VariableName,

+    VariableGuid,

+    NULL,

+    &Size,

+    NULL

+    );

+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

+

+  Buffer = AllocatePool (Size);

+

+  ASSERT (Buffer != NULL);

+

+  Status = EfiGetVariable (

+    VariableName,

+    VariableGuid,

+    NULL,

+    &Size,

+    Buffer

+    );

+

+  return Status;

+

+}

+

+

+UINT32

+GetSkuEnabledTokenNumber (

+  UINT32    LocalTokenNumber,

+  UINTN     Size,

+  BOOLEAN   IsPeiDb

+  ) 

+{

+  SKU_HEAD              *SkuHead;

+  SKU_ID                *SkuIdTable;

+  INTN                  i;

+  UINT8                 *Value;

+  SKU_ID                *PhaseSkuIdTable;

+  UINT8                 *PcdDb;

+

+  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);

+

+  PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;

+

+  SkuHead     = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));

+  Value       = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); 

+

+  PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :

+                              mPcdDatabase->DxeDb.Init.SkuIdTable;

+                              

+  SkuIdTable  = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];

+        

+  for (i = 0; i < SkuIdTable[0]; i++) {

+    if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {

+      break;

+    }

+  }

+  ASSERT (i < SkuIdTable[0]);

+

+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {

+    case PCD_TYPE_VPD:

+      Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);

+      return ((Value - PcdDb) | PCD_TYPE_VPD);

+

+    case PCD_TYPE_HII:

+      Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);

+      return ((Value - PcdDb) | PCD_TYPE_HII);

+      

+    case PCD_TYPE_DATA:

+      Value += Size * i;

+      return (Value - PcdDb);

+      

+    default:

+      ASSERT (FALSE);

+  }

+

+  ASSERT (FALSE);

+

+  return 0;

+  

+}

+

+

+

+

+

+VOID

+InvokeCallbackOnSet (

+  UINT32            ExTokenNumber,

+  CONST EFI_GUID    *Guid, OPTIONAL

+  UINTN             TokenNumber,

+  VOID              *Data,

+  UINTN             Size

+  )

+{

+  CALLBACK_FN_ENTRY       *FnTableEntry;

+  LIST_ENTRY              *ListHead;

+  LIST_ENTRY              *ListNode;

+

+  ListHead = &mCallbackFnTable[TokenNumber];

+  ListNode = GetFirstNode (ListHead);

+

+  while (ListNode != ListHead) {

+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);

+

+    FnTableEntry->CallbackFn(Guid, 

+                    (Guid == NULL) ? TokenNumber : ExTokenNumber,

+                    Data,

+                    Size);

+    

+    ListNode = GetNextNode (ListHead, ListNode);

+  }

+  

+  return;

+}

+

+

+

+

+EFI_STATUS

+SetWorker (

+  PCD_TOKEN_NUMBER        TokenNumber,

+  VOID                    *Data,

+  UINTN                   Size,

+  BOOLEAN                 PtrType

+  )

+{

+  UINT32              *LocalTokenNumberTable;

+  BOOLEAN             IsPeiDb;

+  UINT32              LocalTokenNumber;

+  EFI_GUID            *GuidTable;

+  UINT16              *StringTable;

+  EFI_GUID            *Guid;

+  UINT16              *Name;

+  VOID                *InternalData;

+  VARIABLE_HEAD       *VariableHead;

+  UINTN               Offset;

+  UINT8               *PcdDb;

+

+

+  ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);

+

+  if (PtrType) {

+    ASSERT (Size <= DxePcdGetSize (TokenNumber));

+  } else {

+    ASSERT (Size == DxePcdGetSize (TokenNumber));

+  }

+  

+  IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;

+

+  LocalTokenNumberTable  = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : 

+                                     mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;

+

+  if ((TokenNumber < PEI_NEX_TOKEN_NUMBER) ||

+      (TokenNumber >= PEI_LOCAL_TOKEN_NUMBER || TokenNumber < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER))) {

+    InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size);

+  }

+

+  TokenNumber = IsPeiDb ? TokenNumber

+                        : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;

+

+  LocalTokenNumber = LocalTokenNumberTable[TokenNumber];

+  

+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {

+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);

+  }

+

+  Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;

+

+  PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);

+

+  StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :

+                          mPcdDatabase->DxeDb.Init.StringTable;

+  

+  InternalData = PcdDb + Offset;

+

+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {

+    case PCD_TYPE_VPD:

+      ASSERT (FALSE);

+      return EFI_INVALID_PARAMETER;

+    

+    case PCD_TYPE_STRING:

+      CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, Size);

+      break;

+

+    case PCD_TYPE_HII:

+      //

+      // Bug Bug: Please implement this

+      //

+      GuidTable   = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :

+                              mPcdDatabase->DxeDb.Init.GuidTable;

+                              

+      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);

+      

+      Guid = &(GuidTable[VariableHead->GuidTableIndex]);

+      Name = &(StringTable[VariableHead->StringIndex]);

+

+      return EFI_SUCCESS;

+

+    case PCD_TYPE_DATA:

+      if (PtrType) {

+        CopyMem (InternalData, Data, Size);

+        return EFI_SUCCESS;

+      }

+

+      switch (Size) {

+        case sizeof(UINT8):

+          *((UINT8 *) InternalData) = *((UINT8 *) Data);

+          return EFI_SUCCESS;

+

+        case sizeof(UINT16):

+          *((UINT16 *) InternalData) = *((UINT16 *) Data);

+          return EFI_SUCCESS;

+

+        case sizeof(UINT32):

+          *((UINT32 *) InternalData) = *((UINT32 *) Data);

+          return EFI_SUCCESS;

+

+        case sizeof(UINT64):

+          *((UINT64 *) InternalData) = *((UINT64 *) Data);

+          return EFI_SUCCESS;

+

+        default:

+          ASSERT (FALSE);

+          return EFI_NOT_FOUND;

+      }

+

+    default:

+      ASSERT (FALSE);

+      break;

+    }

+      

+  ASSERT (FALSE);

+  return EFI_NOT_FOUND;

+}

+

+

+

+

+

+VOID *

+ExGetWorker (

+  IN CONST EFI_GUID         *Guid,

+  IN UINTN                  ExTokenNumber,

+  IN UINTN                  GetSize

+  ) 

+{

+  return GetWorker(GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);

+}

+

+

+

+

+

+EFI_STATUS

+ExSetWorker (

+  IN PCD_TOKEN_NUMBER     ExTokenNumber,

+  IN CONST EFI_GUID       *Guid,

+  VOID                    *Data,

+  UINTN                   SetSize,

+  BOOLEAN                 PtrType

+  )

+{

+  PCD_TOKEN_NUMBER        TokenNumber;

+  

+  TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);

+

+  InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, SetSize);

+

+  SetWorker (TokenNumber, Data, SetSize, PtrType);

+

+  return EFI_SUCCESS;

+  

+}

+

+

+

+

+EFI_STATUS

+SetHiiVariable (

+  IN  EFI_GUID     *VariableGuid,

+  IN  UINT16       *VariableName,

+  IN  CONST VOID   *Data,

+  IN  UINTN        DataSize,

+  IN  UINTN        Offset

+  )

+{

+  UINTN       Size;

+  VOID        *Buffer;

+  EFI_STATUS  Status;

+  UINT32      Attribute;

+

+  Size = 0;

+

+  Status = EfiGetVariable (

+    (UINT16 *)VariableName,

+    VariableGuid,

+    &Attribute,

+    &Size,

+    NULL

+    );

+

+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

+

+  Buffer = AllocatePool (Size);

+

+  ASSERT (Buffer != NULL);

+

+  Status = EfiGetVariable (

+    VariableName,

+    VariableGuid,

+    &Attribute,

+    &Size,

+    Buffer

+    );

+

+

+  CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);

+

+  return EfiSetVariable (

+    VariableName,

+    VariableGuid,

+    Attribute,

+    Size,

+    Buffer

+    );

+

+}

+

+

+

+

+

+PCD_TOKEN_NUMBER

+GetExPcdTokenNumber (

+  IN CONST EFI_GUID             *Guid,

+  IN PCD_TOKEN_NUMBER           ExTokenNumber

+  )

+{

+  UINT32              i;

+  DYNAMICEX_MAPPING   *ExMap;

+  EFI_GUID            *GuidTable;

+  EFI_GUID            *MatchGuid;

+  UINTN               MatchGuidIdx;

+

+  ExMap       = mPcdDatabase->PeiDb.Init.ExMapTable;

+  GuidTable   = mPcdDatabase->PeiDb.Init.GuidTable;

+  

+  MatchGuid   = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);

+  ASSERT (MatchGuid != NULL);

+

+  MatchGuidIdx = MatchGuid - GuidTable;

+  

+  for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {

+    if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&

+        (MatchGuidIdx == ExMap[i].ExGuidIndex)) {

+        return ExMap[i].LocalTokenNumber;

+

+    }

+  }

+  

+  ExMap       = mPcdDatabase->DxeDb.Init.ExMapTable;

+  GuidTable   = mPcdDatabase->DxeDb.Init.GuidTable;

+

+  MatchGuid   = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);

+  ASSERT (MatchGuid != NULL);

+

+  MatchGuidIdx = MatchGuid - GuidTable;

+  

+  for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {

+    if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&

+         (MatchGuidIdx == ExMap[i].ExGuidIndex)) {

+        return ExMap[i].LocalTokenNumber + PEI_LOCAL_TOKEN_NUMBER;

+    }

+  }

+

+  ASSERT (FALSE);

+

+  return 0;

+}

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/Service.h b/edk2/EdkModulePkg/Universal/PCD/Dxe/Service.h
new file mode 100644
index 0000000..af9fc42
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/Service.h
@@ -0,0 +1,419 @@
+/** @file

+Private functions used by PCD DXE driver.

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name: Service.h

+

+**/

+

+#ifndef _SERVICE_H

+#define _SERVICE_H

+

+//

+// Please make sure the PCD Serivce PEIM Version is consistent with

+// the version of PCD Database generation tool

+//

+#define PCD_DXE_SERVICE_DRIVER_VERSION      1

+

+//

+// PCD_DXE_DATABASE_GENTOOL_VERSION is defined in Autogen.h

+// and generated by PCD Database generation tool.

+//

+#if (PCD_DXE_SERVICE_PEIM_VERSION != PCD_DXE_DATABASE_GENTOOL_VERSION)

+  #error "Please make sure the version of PCD Service DXE Driver and PCD DXE Database Generation Tool matches"

+#endif

+

+

+typedef struct {

+  LIST_ENTRY              Node;

+  PCD_PROTOCOL_CALLBACK   CallbackFn;

+} CALLBACK_FN_ENTRY;

+

+#define CR_FNENTRY_FROM_LISTNODE(Record, Type, Field) _CR(Record, Type, Field)

+

+//

+// Internal Functions

+//

+

+EFI_STATUS

+SetWorker (

+  IN PCD_TOKEN_NUMBER          TokenNumber,

+  IN VOID                      *Data,

+  IN UINTN                     Size,

+  IN BOOLEAN                   PtrType

+  )

+;

+

+EFI_STATUS

+ExSetWorker (

+  IN PCD_TOKEN_NUMBER     ExTokenNumber,

+  IN CONST EFI_GUID       *Guid,

+  VOID                    *Data,

+  UINTN                   Size,

+  BOOLEAN                 PtrType

+  )

+;

+

+

+VOID *

+GetWorker (

+  PCD_TOKEN_NUMBER  TokenNumber,

+  UINTN             GetSize

+  )

+;

+

+VOID *

+ExGetWorker (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINTN                  GetSize

+  ) 

+;

+

+UINT32

+GetSkuEnabledTokenNumber (

+  UINT32 LocalTokenNumber,

+  UINTN  Size,

+  BOOLEAN IsPeiDb

+  ) 

+;

+

+EFI_STATUS

+GetHiiVariable (

+  IN  EFI_GUID      *VariableGuid,

+  IN  UINT16        *VariableName,

+  OUT VOID          **VariableData,

+  OUT UINTN         *VariableSize

+  )

+;

+

+EFI_STATUS

+DxeRegisterCallBackWorker (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+);

+

+EFI_STATUS

+DxeUnRegisterCallBackWorker (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+);

+

+VOID

+BuildPcdDxeDataBase (

+  VOID

+);

+

+

+PCD_TOKEN_NUMBER

+GetExPcdTokenNumber (

+  IN CONST EFI_GUID             *Guid,

+  IN PCD_TOKEN_NUMBER           ExTokenNumber

+  )

+;

+//

+// Protocol Interface function declaration.

+//

+VOID

+EFIAPI

+DxePcdSetSku (

+  IN  SKU_ID                  SkuId

+  )

+;

+

+

+UINT8

+EFIAPI

+DxePcdGet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT16

+EFIAPI

+DxePcdGet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT32

+EFIAPI

+DxePcdGet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT64

+EFIAPI

+DxePcdGet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+VOID *

+EFIAPI

+DxePcdGetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+BOOLEAN

+EFIAPI

+DxePcdGetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINTN

+EFIAPI

+DxePcdGetSize (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT8

+EFIAPI

+DxePcdGet8Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT16

+EFIAPI

+DxePcdGet16Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT32

+EFIAPI

+DxePcdGet32Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+

+UINT64

+EFIAPI

+DxePcdGet64Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+

+VOID *

+EFIAPI

+DxePcdGetPtrEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+BOOLEAN

+EFIAPI

+DxePcdGetBoolEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINTN

+EFIAPI

+DxePcdGetSizeEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16             Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32             Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet8Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet16Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet32Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32             Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSet64Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetPtrEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdSetBoolEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+;

+

+

+

+EFI_STATUS

+EFIAPI

+DxeRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxeUnRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+DxePcdGetNextToken (

+  IN CONST EFI_GUID               *Guid, OPTIONAL

+  IN OUT   PCD_TOKEN_NUMBER       *TokenNumber

+  )

+;

+

+PCD_TOKEN_NUMBER

+ExGetNextTokeNumber (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN EFI_GUID          *GuidTable,

+  IN UINTN             SizeOfGuidTable,

+  IN DYNAMICEX_MAPPING *ExMapTable,

+  IN UINTN             SizeOfExMapTable

+  )

+;

+

+extern EFI_GUID gPcdDataBaseHobGuid;

+

+extern PCD_DATABASE * mPcdDatabase;

+

+extern DXE_PCD_DATABASE_INIT gDXEPcdDbInit;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/PCD/Dxe/build.xml b/edk2/EdkModulePkg/Universal/PCD/Dxe/build.xml
new file mode 100644
index 0000000..4e27a1d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 
+All rights reserved. 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.-->
+<project basedir="." default="PcdDxe"><!--Apply external ANT tasks-->
+   <taskdef resource="GenBuild.tasks"/>
+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+   <property environment="env"/>
+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+   <property name="MODULE_RELATIVE_PATH" value="Universal/PCD/Dxe"/>
+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>
+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>
+   <target name="PcdDxe">
+      <GenBuild baseName="PcdDxe" mbdFilename="${MODULE_DIR}/Pcd.mbd" msaFilename="${MODULE_DIR}/Pcd.msa"/>
+   </target>
+   <target depends="PcdDxe_clean" name="clean"/>
+   <target depends="PcdDxe_cleanall" name="cleanall"/>
+   <target name="PcdDxe_clean">
+      <OutputDirSetup baseName="PcdDxe" mbdFilename="${MODULE_DIR}/Pcd.mbd" msaFilename="${MODULE_DIR}/Pcd.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/PcdDxe_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/PcdDxe_build.xml" target="clean"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+   </target>
+   <target name="PcdDxe_cleanall">
+      <OutputDirSetup baseName="PcdDxe" mbdFilename="${MODULE_DIR}/Pcd.mbd" msaFilename="${MODULE_DIR}/Pcd.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/PcdDxe_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/PcdDxe_build.xml" target="cleanall"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}"/>
+      <delete dir="${DEST_DIR_DEBUG}"/>
+      <delete>
+         <fileset dir="${BIN_DIR}" includes="**PcdDxe*"/>
+      </delete>
+   </target>
+</project>
diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.c b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.c
new file mode 100644
index 0000000..70b229e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.c
@@ -0,0 +1,619 @@
+/** @file PCD PEIM

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name: Pcd.c

+

+**/

+

+#include "Service.h"

+

+

+PCD_PPI mPcdPpiInstance = {

+  PeiPcdSetSku,

+

+  PeiPcdGet8,

+  PeiPcdGet16,          

+  PeiPcdGet32,          

+  PeiPcdGet64,          

+  PeiPcdGetPtr,         

+  PeiPcdGetBool,     

+  PeiPcdGetSize,

+

+  PeiPcdGet8Ex,

+  PeiPcdGet16Ex,          

+  PeiPcdGet32Ex,          

+  PeiPcdGet64Ex,          

+  PeiPcdGetPtrEx,         

+  PeiPcdGetBoolEx,     

+  PeiPcdGetSizeEx,

+  

+  PeiPcdSet8,

+  PeiPcdSet16,          

+  PeiPcdSet32,          

+  PeiPcdSet64,          

+  PeiPcdSetPtr,         

+  PeiPcdSetBool,     

+

+  PeiPcdSet8Ex,

+  PeiPcdSet16Ex,          

+  PeiPcdSet32Ex,          

+  PeiPcdSet64Ex,          

+  PeiPcdSetPtrEx,         

+  PeiPcdSetBoolEx,

+

+  PeiRegisterCallBackOnSet,

+  PcdUnRegisterCallBackOnSet,

+  PeiPcdGetNextToken

+};

+

+

+

+STATIC EFI_PEI_PPI_DESCRIPTOR  mPpiPCD = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gPcdPpiGuid,

+  &mPcdPpiInstance

+};

+

+

+

+EFI_STATUS

+EFIAPI

+PcdPeimInit (

+  IN EFI_FFS_FILE_HEADER      *FfsHeader,

+  IN EFI_PEI_SERVICES         **PeiServices

+  )

+{

+  EFI_STATUS Status;

+

+  BuildPcdDatabase ();

+  

+  Status = PeiCoreInstallPpi (&mPpiPCD);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+PeiPcdSetSku (

+  IN  SKU_ID                  SkuId

+  )

+{

+

+  GetPcdDatabase()->Init.SystemSkuId = SkuId;

+

+  return;

+}

+

+

+

+UINT8

+EFIAPI

+PeiPcdGet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));

+}

+

+

+

+UINT16

+EFIAPI

+PeiPcdGet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));

+}

+

+

+

+UINT32

+EFIAPI

+PeiPcdGet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));

+}

+

+

+

+UINT64

+EFIAPI

+PeiPcdGet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64)));

+}

+

+

+

+VOID *

+EFIAPI

+PeiPcdGetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return GetWorker (TokenNumber, 0);

+}

+

+

+

+BOOLEAN

+EFIAPI

+PeiPcdGetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));

+}

+

+

+

+UINTN

+EFIAPI

+PeiPcdGetSize (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);

+

+  return GetPcdDatabase()->Init.SizeTable[TokenNumber];

+}

+

+

+

+UINT8

+EFIAPI

+PeiPcdGet8Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber

+  )

+{

+  return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8)));

+}

+

+

+

+UINT16

+EFIAPI

+PeiPcdGet16Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber

+  )

+{

+  return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16)));

+}

+

+

+

+UINT32

+EFIAPI

+PeiPcdGet32Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber

+  )

+{

+  return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32)));

+}

+

+

+

+UINT64

+EFIAPI

+PeiPcdGet64Ex (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber

+  )

+{

+  return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64)));

+}

+

+

+

+VOID *

+EFIAPI

+PeiPcdGetPtrEx (

+  IN CONST EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  ExTokenNumber

+  )

+{

+  return ExGetWorker (Guid, ExTokenNumber, 0);

+}

+

+

+

+BOOLEAN

+EFIAPI

+PeiPcdGetBoolEx (

+  IN CONST  EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER                  ExTokenNumber

+  )

+{

+  return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN)));

+}

+

+

+

+UINTN

+EFIAPI

+PeiPcdGetSizeEx (

+  IN CONST  EFI_GUID        *Guid,

+  IN PCD_TOKEN_NUMBER                  ExTokenNumber

+  )

+{

+  return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber));

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet8 (

+  IN PCD_TOKEN_NUMBER             TokenNumber,

+  IN UINT8             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet16 (

+  IN PCD_TOKEN_NUMBER              TokenNumber,

+  IN UINT16             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet32 (

+  IN PCD_TOKEN_NUMBER              TokenNumber,

+  IN UINT32             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet64 (

+  IN PCD_TOKEN_NUMBER              TokenNumber,

+  IN UINT64             Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetPtr (

+  IN PCD_TOKEN_NUMBER              TokenNumber,

+  IN UINTN                         SizeOfBuffer,

+  IN VOID                          *Buffer

+  )

+{

+  return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetBool (

+  IN PCD_TOKEN_NUMBER              TokenNumber,

+  IN BOOLEAN            Value

+  )

+{

+  return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet8Ex (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINT8                  Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet16Ex (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINT16                 Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet32Ex (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINT32                 Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet64Ex (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINT64                 Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetPtrEx (

+  IN CONST EFI_GUID         *Guid,

+  IN PCD_TOKEN_NUMBER       ExTokenNumber,

+  IN UINTN                  SizeOfBuffer,

+  IN VOID                   *Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              Value, 

+                              SizeOfBuffer, 

+                              TRUE

+                              );

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetBoolEx (

+  IN CONST EFI_GUID       *Guid,

+  IN PCD_TOKEN_NUMBER     ExTokenNumber,

+  IN BOOLEAN              Value

+  )

+{

+  return          ExSetWorker(

+                              ExTokenNumber, 

+                              Guid,

+                              &Value, 

+                              sizeof (Value), 

+                              FALSE

+                              );

+}

+

+

+

+

+EFI_STATUS

+EFIAPI

+PeiRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER            ExTokenNumber,

+  IN  CONST EFI_GUID              *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK            CallBackFunction

+  )

+{

+  ASSERT (CallBackFunction != NULL);

+  

+  return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PcdUnRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER            ExTokenNumber,

+  IN  CONST EFI_GUID              *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK            CallBackFunction

+  )

+{

+  ASSERT (CallBackFunction != NULL);

+  

+  return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdGetNextToken (

+  IN CONST EFI_GUID               *Guid, OPTIONAL

+  IN OUT  PCD_TOKEN_NUMBER        *TokenNumber

+  )

+{

+  UINTN               GuidTableIdx;

+  PEI_PCD_DATABASE    *PeiPcdDb;

+  EFI_GUID            *MatchGuid;

+  DYNAMICEX_MAPPING   *ExMapTable;

+  UINTN               i;

+  BOOLEAN             Found;

+    

+  if (Guid == NULL) {

+    (*TokenNumber)++;

+

+    if (*TokenNumber >= PEI_NEX_TOKEN_NUMBER) {

+      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;

+    }

+    

+  } else {

+

+    if (PEI_EXMAP_TABLE_EMPTY) {

+      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;

+      return EFI_NOT_FOUND;

+    }

+    

+    //

+    // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order

+    // 1) ExGuid

+    // 2) ExTokenNumber

+    //

+    PeiPcdDb = GetPcdDatabase ();

+    

+    MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);

+

+    if (MatchGuid == NULL) {

+      *TokenNumber = (UINTN) PCD_INVALID_TOKEN_NUMBER;

+      return EFI_NOT_FOUND;

+    }

+

+    GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;

+

+    ExMapTable = PeiPcdDb->Init.ExMapTable;

+

+    Found = FALSE;

+    for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {

+      if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {

+        Found = TRUE;

+        break;

+      }

+    }

+

+    if (Found) {

+      if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {

+        *TokenNumber = ExMapTable[i].ExTokenNumber;

+         return EFI_SUCCESS;

+      }

+      

+      for ( ; ExMapTable[i].ExGuidIndex == GuidTableIdx; i++) {

+        if (ExMapTable[i].ExTokenNumber == *TokenNumber) {

+          i++;

+          if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {

+            *TokenNumber = ExMapTable[i].ExTokenNumber;

+            return EFI_SUCCESS;

+          } else {

+            *TokenNumber = (UINTN) PCD_INVALID_TOKEN_NUMBER;

+            return EFI_SUCCESS;

+          }

+        }

+      }

+

+      return EFI_NOT_FOUND;

+    }

+    

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_GUID *

+EFIAPI

+PeiPcdGetNextTokenSpaceGuid (

+  IN CONST EFI_GUID               *Guid

+  )

+{

+  UINTN               GuidTableIdx;

+  EFI_GUID            *MatchGuid;

+  PEI_PCD_DATABASE    *PeiPcdDb;

+  DYNAMICEX_MAPPING   *ExMapTable;

+  UINTN               i;

+  BOOLEAN             Found;

+

+  if (PEI_EXMAP_TABLE_EMPTY) {

+    return NULL;

+  }

+

+  //

+  // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order

+  // 1) ExGuid

+  // 2) ExTokenNumber

+  //

+  PeiPcdDb = GetPcdDatabase ();

+

+  MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);

+

+  if (MatchGuid == NULL) {

+    return NULL;

+  }

+  

+  GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;

+

+  ExMapTable = PeiPcdDb->Init.ExMapTable;

+

+  Found = FALSE;

+  for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {

+    if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {

+      Found = TRUE;

+      break;

+    }

+  }

+

+  if (Found) {

+    for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++ ) {

+      if (ExMapTable[i].ExGuidIndex != GuidTableIdx ) {

+        if (i < PEI_EXMAPPING_TABLE_SIZE) {

+          return &PeiPcdDb->Init.GuidTable[ExMapTable[i].ExGuidIndex];

+        } else {

+          return NULL;

+        }

+      }

+    }

+  }

+

+  return NULL;

+

+}

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.dxs b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.dxs
new file mode 100644
index 0000000..ea57997
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.dxs
@@ -0,0 +1,25 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PcdEmulator.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.mbd b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.mbd
new file mode 100644
index 0000000..816cf6f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PcdEmulatorPeim</BaseName>

+    <Guid>9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-24 18:54</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>BaseLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>PeiMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.msa b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.msa
new file mode 100644
index 0000000..60cd644
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/Pcd.msa
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PcdPeim</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for Pcd Database PEIM module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-24 18:54</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Pcd.dxs</Filename>

+    <Filename>Pcd.c</Filename>

+    <Filename>Service.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>PcdDataBaseHob</Name>

+      <C_Name>gPcdDataBaseHobGuid</C_Name>

+      <Guid>0xea296d92, 0xb69,  0x423c, 0x8c, 0x28, 0x33, 0xb4, 0xe0, 0xa9, 0x12, 0x68</Guid>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>PcdPeiCallbackFnTable</Name>

+      <C_Name>gPcdPeiCallbackFnTableHobGuid</C_Name>

+      <Guid>0xc625f4b2, 0xea09, 0x4675, 0x82, 0xd7, 0xba, 0x36, 0x82, 0x15, 0x7a, 0x14</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">Pcd</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">ReadOnlyVariable</Ppi>

+  </PPIs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PcdDataBaseHob</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PcdPeiCallbackFnTable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PcdPeimInit</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+      <Token>0x0001000f</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdVpdBaseAddress</C_Name>

+      <Token>0x00010010</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/Service.c b/edk2/EdkModulePkg/Universal/PCD/Pei/Service.c
new file mode 100644
index 0000000..62e2f9c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/Service.c
@@ -0,0 +1,533 @@
+/** @file

+Private functions used by PCD PEIM.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+

+Module Name: Service.c

+

+**/

+#include "Service.h"

+

+

+/**

+  The function registers the CallBackOnSet fucntion

+  according to TokenNumber and EFI_GUID space.

+

+  @param[in]  TokenNumber       The token number.

+  @param[in]  Guid              The GUID space.

+  @param[in]  CallBackFunction  The Callback function to be registered.

+

+  @retval EFI_SUCCESS If the Callback function is registered.

+  @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.

+--*/

+EFI_STATUS

+PeiRegisterCallBackWorker (

+  IN  PCD_TOKEN_NUMBER            ExTokenNumber,

+  IN  CONST EFI_GUID              *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK            CallBackFunction,

+  IN  BOOLEAN                     Register

+)

+{

+  EFI_HOB_GUID_TYPE       *GuidHob;

+  PCD_PPI_CALLBACK        *CallbackTable;

+  PCD_PPI_CALLBACK        Compare;

+  PCD_PPI_CALLBACK        Assign;

+  UINT32                  LocalTokenNumber;

+  PCD_TOKEN_NUMBER        TokenNumber;

+  UINTN                   Idx;

+

+  if (Guid == NULL) {

+    TokenNumber = ExTokenNumber;

+    ASSERT (TokenNumber < PEI_NEX_TOKEN_NUMBER);

+  } else {

+    TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);

+    ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);

+  }

+

+  LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];

+

+  ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);

+  ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);

+

+  GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);

+  ASSERT (GuidHob != NULL);

+  

+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);

+  CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));

+

+  Compare = Register? NULL: CallBackFunction;

+  Assign  = Register? CallBackFunction: NULL;

+

+

+  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {

+    if (CallbackTable[Idx] == Compare) {

+      CallbackTable[Idx] = Assign;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;

+

+}

+

+

+

+

+/**

+  The function builds the PCD database based on the

+  PCD_IMAGE on the flash.

+

+  @param[in] PcdImageOnFlash  The PCD image on flash.

+

+  @retval VOID

+--*/

+VOID

+BuildPcdDatabase (

+  VOID

+  )

+{

+  PEI_PCD_DATABASE  *Database;

+  VOID              *CallbackFnTable;

+  UINTN             SizeOfCallbackFnTable;

+  

+  Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));

+

+  ZeroMem (Database, sizeof (PEI_PCD_DATABASE));

+

+  //

+  // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE

+  //

+  

+  CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));

+

+  SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);

+

+  CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);

+  

+  ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);

+  

+  return;

+}

+

+

+

+/**

+  The function is provided by PCD PEIM and PCD DXE driver to

+  do the work of reading a HII variable from variable service.

+

+  @param[in] VariableGuid     The Variable GUID.

+  @param[in] VariableName     The Variable Name.

+  @param[out] VariableData    The output data.

+  @param[out] VariableSize    The size of the variable.

+

+  @retval EFI_SUCCESS         Operation successful.

+  @retval EFI_SUCCESS         Variablel not found.

+--*/

+EFI_STATUS

+GetHiiVariable (

+  IN  CONST EFI_GUID      *VariableGuid,

+  IN  UINT16              *VariableName,

+  OUT VOID                **VariableData,

+  OUT UINTN               *VariableSize

+  )

+{

+  UINTN      Size;

+  EFI_STATUS Status;

+  VOID       *Buffer;

+  EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;

+

+  Status = PeiCoreLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);

+  ASSERT_EFI_ERROR (Status);

+

+  Size = 0;

+

+  Status = VariablePpi->PeiGetVariable (

+                          GetPeiServicesTablePointer (),

+                          VariableName,

+                          (EFI_GUID *) VariableGuid,

+                          NULL,

+                          &Size,

+                          NULL

+                            );

+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

+

+  Status = PeiCoreAllocatePool (Size, &Buffer);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = VariablePpi->PeiGetVariable (

+                            GetPeiServicesTablePointer (),

+                            (UINT16 *) VariableName,

+                            (EFI_GUID *) VariableGuid,

+                            NULL,

+                            &Size,

+                            Buffer

+                            );

+  ASSERT_EFI_ERROR (Status);

+

+  *VariableSize = Size;

+  *VariableData = Buffer;

+

+  return EFI_SUCCESS;

+}

+

+

+UINT32

+GetSkuEnabledTokenNumber (

+  UINT32 LocalTokenNumber,

+  UINTN  Size

+  ) 

+{

+  PEI_PCD_DATABASE      *PeiPcdDb;

+  SKU_HEAD              *SkuHead;

+  SKU_ID                *SkuIdTable;

+  INTN                  i;

+  UINT8                 *Value;

+

+  PeiPcdDb = GetPcdDatabase ();

+

+  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);

+

+  SkuHead     = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));

+  Value       = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));

+  SkuIdTable  = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));

+        

+  for (i = 0; i < SkuIdTable[0]; i++) {

+    if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {

+      break;

+    }

+  }

+

+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {

+    case PCD_TYPE_VPD:

+      Value += sizeof(VPD_HEAD) * i;

+      return ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);

+

+    case PCD_TYPE_HII:

+      Value += sizeof(VARIABLE_HEAD) * i;

+      return ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);

+      

+    case PCD_TYPE_DATA:

+      Value += Size * i;

+      return (Value - (UINT8 *) PeiPcdDb);

+      

+    default:

+      ASSERT (FALSE);

+  }

+

+  ASSERT (FALSE);

+

+  return 0;

+  

+}

+

+

+

+

+VOID

+InvokeCallbackOnSet (

+  UINT32            ExTokenNumber,

+  CONST EFI_GUID    *Guid, OPTIONAL

+  UINTN             TokenNumber,

+  VOID              *Data,

+  UINTN             Size

+  )

+{

+  EFI_HOB_GUID_TYPE   *GuidHob;

+  PCD_PPI_CALLBACK    *CallbackTable;

+  UINTN               Idx;

+

+  if (Guid == NULL)

+    ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);

+

+  GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);

+  ASSERT (GuidHob != NULL);

+  

+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);

+

+  CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));

+

+  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {

+    if (CallbackTable[Idx] != NULL) {

+      CallbackTable[Idx] (Guid,

+                          (Guid == NULL)? TokenNumber: ExTokenNumber,

+                          Data,

+                          Size

+                          );

+    }

+  }

+  

+}

+

+

+

+

+EFI_STATUS

+SetWorker (

+  PCD_TOKEN_NUMBER    TokenNumber,

+  VOID                *Data,

+  UINTN               Size,

+  BOOLEAN             PtrType

+  )

+{

+  UINT32              LocalTokenNumber;

+  PEI_PCD_DATABASE    *PeiPcdDb;

+  UINT16              StringTableIdx;

+  UINTN               Offset;

+  VOID                *InternalData;

+

+  ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);

+    

+  PeiPcdDb = GetPcdDatabase ();

+

+  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];

+

+  if (PtrType) {

+    ASSERT (PeiPcdDb->Init.SizeTable[TokenNumber] >= Size);

+  } else {

+    ASSERT (PeiPcdDb->Init.SizeTable[TokenNumber] == Size);

+  }

+

+  //

+  // We only invoke the callback function for Dynamic Type PCD Entry.

+  // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX

+  // type PCD entry in ExSetWorker.

+  //

+  if (TokenNumber < PEI_NEX_TOKEN_NUMBER) {

+    InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size);

+  }

+

+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {

+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size);

+  }

+

+  Offset          = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;

+  InternalData    = (VOID *) ((UINT8 *) PeiPcdDb + Offset);

+  

+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {

+    case PCD_TYPE_VPD:

+    case PCD_TYPE_HII:

+    {

+      ASSERT (FALSE);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    case PCD_TYPE_STRING:

+      StringTableIdx = *((UINT16 *)InternalData);

+      CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, Size);

+      break;

+

+    case PCD_TYPE_DATA:

+    {

+      

+      if (PtrType) {

+        CopyMem (InternalData, Data, Size);

+        return EFI_SUCCESS;

+      }

+

+      switch (Size) {

+        case sizeof(UINT8):

+          *((UINT8 *) InternalData) = *((UINT8 *) Data);

+          return EFI_SUCCESS;

+

+        case sizeof(UINT16):

+          *((UINT16 *) InternalData) = *((UINT16 *) Data);

+          return EFI_SUCCESS;

+

+        case sizeof(UINT32):

+          *((UINT32 *) InternalData) = *((UINT32 *) Data);

+          return EFI_SUCCESS;

+

+        case sizeof(UINT64):

+          *((UINT64 *) InternalData) = *((UINT64 *) Data);

+          return EFI_SUCCESS;

+

+        default:

+          ASSERT (FALSE);

+          return EFI_NOT_FOUND;

+      }

+    }

+      

+  }

+

+  ASSERT (FALSE);

+  return EFI_NOT_FOUND;

+

+}

+

+

+

+

+EFI_STATUS

+ExSetWorker (

+  IN PCD_TOKEN_NUMBER     ExTokenNumber,

+  IN CONST EFI_GUID       *Guid,

+  VOID                    *Data,

+  UINTN                   Size,

+  BOOLEAN                 PtrType

+  )

+{

+  PCD_TOKEN_NUMBER          TokenNumber;

+

+  TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);

+

+  InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, Size);

+

+  SetWorker (TokenNumber, Data, Size, PtrType);

+

+  return EFI_SUCCESS;

+  

+}

+

+

+

+

+VOID *

+ExGetWorker (

+  IN CONST  EFI_GUID  *Guid,

+  IN PCD_TOKEN_NUMBER ExTokenNumber,

+  IN UINTN            GetSize

+  )

+{

+  return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);

+}

+

+

+

+

+VOID *

+GetWorker (

+  PCD_TOKEN_NUMBER    TokenNumber,

+  UINTN               GetSize

+  )

+{

+  UINT32              Offset;

+  EFI_GUID            *Guid;

+  UINT16              *Name;

+  VARIABLE_HEAD       *VariableHead;

+  EFI_STATUS          Status;

+  UINTN               DataSize;

+  VOID                *Data;

+  UINT16              *StringTable;

+  UINT16              StringTableIdx;

+  PEI_PCD_DATABASE    *PeiPcdDb;

+  UINT32              LocalTokenNumber;

+  UINTN               Size;

+

+  ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);

+

+  Size = PeiPcdGetSize(TokenNumber);

+  

+  ASSERT (GetSize == Size || GetSize == 0);

+

+  PeiPcdDb        = GetPcdDatabase ();

+

+  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];

+

+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {

+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size);

+  }

+

+  Offset      = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;

+  StringTable = PeiPcdDb->Init.StringTable;

+  

+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {

+    case PCD_TYPE_VPD:

+    {

+      VPD_HEAD *VpdHead;

+      VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);

+      return (VOID *) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);

+    }

+      

+    case PCD_TYPE_HII:

+    {

+      VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);

+      

+      Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);

+      Name = &StringTable[VariableHead->StringIndex];

+

+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);

+      ASSERT_EFI_ERROR (Status);

+      ASSERT (DataSize >= (UINTN) (VariableHead->Offset + Size));

+

+      return (VOID *) ((UINT8 *) Data + VariableHead->Offset);

+    }

+

+    case PCD_TYPE_DATA:

+      return (VOID *) ((UINT8 *)PeiPcdDb + Offset);

+      break;

+

+    case PCD_TYPE_STRING:

+      StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);

+      return (VOID *) (&StringTable[StringTableIdx]);

+

+    default:

+      ASSERT (FALSE);

+      break;

+      

+  }

+

+  ASSERT (FALSE);

+      

+  return NULL;

+  

+}

+

+

+PCD_TOKEN_NUMBER

+GetExPcdTokenNumber (

+  IN CONST EFI_GUID             *Guid,

+  IN UINT32                     ExTokenNumber

+  )

+{

+  UINT32              i;

+  DYNAMICEX_MAPPING   *ExMap;

+  EFI_GUID            *GuidTable;

+  EFI_GUID            *MatchGuid;

+  UINTN               MatchGuidIdx;

+  PEI_PCD_DATABASE    *PeiPcdDb;

+

+  PeiPcdDb    = GetPcdDatabase();

+  

+  ExMap       = PeiPcdDb->Init.ExMapTable;

+  GuidTable   = PeiPcdDb->Init.GuidTable;

+

+  MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);

+  ASSERT (MatchGuid != NULL);

+  

+  MatchGuidIdx = MatchGuid - GuidTable;

+  

+  for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {

+    if ((ExTokenNumber == ExMap[i].ExTokenNumber) && 

+        (MatchGuidIdx == ExMap[i].ExGuidIndex)) {

+      return ExMap[i].LocalTokenNumber;

+    }

+  }

+  

+  ASSERT (FALSE);

+  

+  return 0;

+}

+

+

+

+PEI_PCD_DATABASE *

+GetPcdDatabase (

+  VOID

+  )

+{

+  EFI_HOB_GUID_TYPE *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);

+  ASSERT (GuidHob != NULL);

+  

+  return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);

+}

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/Service.h b/edk2/EdkModulePkg/Universal/PCD/Pei/Service.h
new file mode 100644
index 0000000..df774c9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/Service.h
@@ -0,0 +1,390 @@
+/** @file

+Private functions used by PCD PEIM.

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name: Service.h

+

+**/

+

+#ifndef _SERVICE_H

+#define _SERVICE_H

+

+//

+// Please make sure the PCD Serivce PEIM Version is consistent with

+// the version of PCD Database generation tool

+//

+#define PCD_PEI_SERVICE_DRIVER_VERSION      1

+

+//

+// PCD_PEI_DATABASE_GENTOOL_VERSION is defined in Autogen.h

+// and generated by PCD Database generation tool.

+//

+#if (PCD_PEI_SERVICE_PEIM_VERSION != PCD_PEI_DATABASE_GENTOOL_VERSION)

+  #error "Please make sure the version of PCD Service PEIM and PCD PEI Database Generation Tool matches"

+#endif

+

+/* Internal Function definitions */

+

+PEI_PCD_DATABASE *

+GetPcdDatabase (

+  VOID

+  )

+;

+

+EFI_STATUS

+SetWorker (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN VOID               *Data,

+  IN UINTN              Size,

+  IN BOOLEAN            PtrType

+  )

+;

+

+EFI_STATUS

+ExSetWorker (

+  IN PCD_TOKEN_NUMBER     ExTokenNumber,

+  IN CONST EFI_GUID       *Guid,

+  IN VOID                 *Data,

+  IN UINTN                Size,

+  IN BOOLEAN              PtrType

+  )

+;

+

+VOID *

+GetWorker (

+  IN PCD_TOKEN_NUMBER     TokenNumber,

+  IN UINTN                GetSize

+  )

+;

+

+VOID *

+ExGetWorker (

+  IN CONST EFI_GUID   *Guid,

+  IN PCD_TOKEN_NUMBER ExTokenNumber,

+  IN UINTN            GetSize

+  )

+;

+

+typedef struct {

+  UINTN   TokenNumber;

+  UINTN   Size;

+  UINT32  LocalTokenNumberAlias;

+} EX_PCD_ENTRY_ATTRIBUTE;

+

+

+PCD_TOKEN_NUMBER

+GetExPcdTokenNumber (

+  IN CONST EFI_GUID             *Guid,

+  IN PCD_TOKEN_NUMBER           ExTokenNumber

+  )

+;

+

+

+

+

+EFI_STATUS

+PeiRegisterCallBackWorker (

+  IN  PCD_TOKEN_NUMBER   TokenNumber,

+  IN  CONST GUID         *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK   CallBackFunction,

+  IN  BOOLEAN            Register

+);

+

+

+

+

+VOID

+BuildPcdDatabase (

+  VOID

+  )

+;

+

+

+//

+// PPI Interface Implementation Declaration.

+//

+VOID

+EFIAPI

+PeiPcdSetSku (

+  IN  SKU_ID                  SkuId

+  )

+;

+

+

+UINT8

+EFIAPI

+PeiPcdGet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT16

+EFIAPI

+PeiPcdGet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT32

+EFIAPI

+PeiPcdGet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT64

+EFIAPI

+PeiPcdGet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+VOID *

+EFIAPI

+PeiPcdGetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+BOOLEAN

+EFIAPI

+PeiPcdGetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINTN

+EFIAPI

+PeiPcdGetSize (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT8

+EFIAPI

+PeiPcdGet8Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT16

+EFIAPI

+PeiPcdGet16Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+UINT32

+EFIAPI

+PeiPcdGet32Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINT64

+EFIAPI

+PeiPcdGet64Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+VOID *

+EFIAPI

+PeiPcdGetPtrEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+BOOLEAN

+EFIAPI

+PeiPcdGetBoolEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+UINTN

+EFIAPI

+PeiPcdGetSizeEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  )

+;

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet8Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+;

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet16Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet32Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSet64Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetPtrEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdSetBoolEx (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+;

+

+

+

+EFI_STATUS

+EFIAPI

+PeiRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK        CallBackFunction

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PcdUnRegisterCallBackOnSet (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK        CallBackFunction

+  )

+;

+

+

+EFI_STATUS

+EFIAPI

+PeiPcdGetNextToken (

+  IN CONST EFI_GUID           *Guid, OPTIONAL

+  IN OUT  PCD_TOKEN_NUMBER    *TokenNumber

+  )

+;

+

+extern EFI_GUID gPcdDataBaseHobGuid;

+

+extern EFI_GUID gPcdPeiCallbackFnTableHobGuid;

+

+extern PEI_PCD_DATABASE_INIT gPEIPcdDbInit;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/PCD/Pei/build.xml b/edk2/EdkModulePkg/Universal/PCD/Pei/build.xml
new file mode 100644
index 0000000..07aef0d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Pei/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 
+All rights reserved. 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.-->
+<project basedir="." default="PcdPeim"><!--Apply external ANT tasks-->
+   <taskdef resource="GenBuild.tasks"/>
+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+   <property environment="env"/>
+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+   <property name="MODULE_RELATIVE_PATH" value="Universal/PCD/Pei"/>
+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>
+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>
+   <target name="PcdPeim">
+      <GenBuild baseName="PcdPeim" mbdFilename="${MODULE_DIR}/Pcd.mbd" msaFilename="${MODULE_DIR}/Pcd.msa"/>
+   </target>
+   <target depends="PcdPeim_clean" name="clean"/>
+   <target depends="PcdPeim_cleanall" name="cleanall"/>
+   <target name="PcdPeim_clean">
+      <OutputDirSetup baseName="PcdPeim" mbdFilename="${MODULE_DIR}/Pcd.mbd" msaFilename="${MODULE_DIR}/Pcd.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/PcdPeim_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/PcdPeim_build.xml" target="clean"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+   </target>
+   <target name="PcdPeim_cleanall">
+      <OutputDirSetup baseName="PcdPeim" mbdFilename="${MODULE_DIR}/Pcd.mbd" msaFilename="${MODULE_DIR}/Pcd.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/PcdPeim_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/PcdPeim_build.xml" target="cleanall"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}"/>
+      <delete dir="${DEST_DIR_DEBUG}"/>
+      <delete>
+         <fileset dir="${BIN_DIR}" includes="**PcdPeim*"/>
+      </delete>
+   </target>
+</project>
diff --git a/edk2/EdkModulePkg/Universal/PCD/Test/PcdTest.c b/edk2/EdkModulePkg/Universal/PCD/Test/PcdTest.c
new file mode 100644
index 0000000..6f2a5f1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Test/PcdTest.c
@@ -0,0 +1,90 @@
+/** @file

+PCD TEST PEIM

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name: PcdTest.c

+

+**/

+#define GUID1 \

+  {0xF9349C58, 0xB767, 0x42c8, 0xB3, 0x6B, 0x41, 0x25, 0xDE, 0x3A, 0xEF, 0xEB}

+

+CONST GUID Guid1  = GUID1;

+

+

+EFI_STATUS

+EFIAPI

+OnsetCallback1 (

+  IN  CONST EFI_GUID  *Guid,

+  IN  UINT32          CallBackToken,

+  IN  VOID            *TokenData,

+  IN  UINTN           TokenDataSize

+  )

+{

+  DebugPrint (0x80000000, "In CallbackOnSet %x %d\n", * ((UINT32 *)TokenData), TokenDataSize);    

+  return EFI_SUCCESS;

+}

+

+

+VOID

+DoTest(

+  VOID

+  )

+{

+  UINT8     u8;

+  UINT16    u16;

+  UINT32    u32;

+  UINT64    u64;

+  PCD_TOKEN_NUMBER Token;

+  

+

+  LibPcdCallbackOnSet (NULL, PcdToken(PcdTestDynamicUint32), OnsetCallback1);

+  

+  u32 = 0xafafafaf;

+  PcdSet32(PcdTestDynamicUint32, u32);

+

+  u64 = 0xafafafaf00000000;

+  PcdSet64(PcdTestDynamicUint64, u64);

+

+  u8 = PcdGet8(PcdTestDynamicUint8);

+  u16 = PcdGet16(PcdTestDynamicUint16);

+

+

+  ASSERT (u8 == 0x01);

+  ASSERT (u16 == 0x1234);

+  ASSERT (u64 == PcdGet64(PcdTestDynamicUint64));

+  ASSERT (u32 == PcdGet32(PcdTestDynamicUint32));

+

+

+  Token = PCD_INVALID_TOKEN_NUMBER;

+

+  do {

+    Token = LibPcdGetNextToken (NULL, Token);

+    DebugPrint (EFI_D_ERROR, "Next Token Number is %d\n", Token);

+  } while (Token != PCD_INVALID_TOKEN_NUMBER);

+  

+  

+  return;

+}

+

+EFI_STATUS

+EFIAPI

+PcdTestPeimInit (

+  IN EFI_FFS_FILE_HEADER      *FfsHeader,

+  IN EFI_PEI_SERVICES         **PeiServices

+  )

+{

+

+  DoTest();

+  

+  return EFI_SUCCESS;

+}

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Test/PcdTest.dxs b/edk2/EdkModulePkg/Universal/PCD/Test/PcdTest.dxs
new file mode 100644
index 0000000..bf74296
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Test/PcdTest.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.dxs

+

+Abstract:

+

+  Dependency expression file for PcdTest PEIM.

+

+--*/  

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+  PCD_PPI_GUID

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkModulePkg/Universal/PCD/Test/PeiPcdTest.mbd b/edk2/EdkModulePkg/Universal/PCD/Test/PeiPcdTest.mbd
new file mode 100644
index 0000000..e601061
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Test/PeiPcdTest.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PeimPcdTesty</BaseName>

+    <Guid>7AB59E15-BA5A-4617-B562-BA428D002082</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-24 18:54</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>BaseLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>PeiMemoryAllocationLib</Library>

+    <Library>PeiPcdLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/PCD/Test/PeiPcdTest.msa b/edk2/EdkModulePkg/Universal/PCD/Test/PeiPcdTest.msa
new file mode 100644
index 0000000..b772e83
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Test/PeiPcdTest.msa
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PeimPcdTest</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>B5B62DC2-4420-403a-A068-6E126053A166</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for Pcd Database PEIM module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-24 18:54</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PcdTest.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>PcdDataBaseHob</Name>

+      <C_Name>gPcdDataBaseHobGuid</C_Name>

+      <Guid>0xea296d92, 0xb69,  0x423c, 0x8c, 0x28, 0x33, 0xb4, 0xe0, 0xa9, 0x12, 0x68</Guid>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>PcdPeiCallbackFnTable</Name>

+      <C_Name>gPcdPeiCallbackFnTableHobGuid</C_Name>

+      <Guid>0xc625f4b2, 0xea09, 0x4675, 0x82, 0xd7, 0xba, 0x36, 0x82, 0x15, 0x7a, 0x14</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">Pcd</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">ReadOnlyVariable</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PcdTestPeimInit</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+      <Token>0x0001000f</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint8</C_Name>

+      <Token>0x00011000</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint16</C_Name>

+      <Token>0x00011001</Token>

+      <DatumType>UINT16</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint32</C_Name>

+      <Token>0x00011002</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint64</C_Name>

+      <Token>0x00011003</Token>

+      <DatumType>UINT64</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicBoolean</C_Name>

+      <Token>0x00011004</Token>

+      <DatumType>BOOLEAN</DatumType>

+    </PcdData>

+  </PCDs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/PCD/Test/build.xml b/edk2/EdkModulePkg/Universal/PCD/Test/build.xml
new file mode 100644
index 0000000..bb1a962
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/PCD/Test/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 
+All rights reserved. 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.-->
+<project basedir="." default="PeimPcdTest"><!--Apply external ANT tasks-->
+   <taskdef resource="GenBuild.tasks"/>
+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+   <property environment="env"/>
+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+   <property name="MODULE_RELATIVE_PATH" value="Universal/PCD/Test"/>
+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>
+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>
+   <target name="PeimPcdTest">
+      <GenBuild baseName="PeimPcdTest" mbdFilename="${MODULE_DIR}/PeiPcdTest.mbd" msaFilename="${MODULE_DIR}/PeiPcdTest.msa"/>
+   </target>
+   <target depends="PeimPcdTest_clean" name="clean"/>
+   <target depends="PeimPcdTest_cleanall" name="cleanall"/>
+   <target name="PeimPcdTest_clean">
+      <OutputDirSetup baseName="PeimPcdTest" mbdFilename="${MODULE_DIR}/PeiPcdTest.mbd" msaFilename="${MODULE_DIR}/PeiPcdTest.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/PeimPcdTest_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/PeimPcdTest_build.xml" target="clean"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+   </target>
+   <target name="PeimPcdTest_cleanall">
+      <OutputDirSetup baseName="PeimPcdTest" mbdFilename="${MODULE_DIR}/PeiPcdTest.mbd" msaFilename="${MODULE_DIR}/PeiPcdTest.msa"/>
+      <if>
+         <available file="${DEST_DIR_OUTPUT}/PeimPcdTest_build.xml"/>
+         <then>
+            <ant antfile="${DEST_DIR_OUTPUT}/PeimPcdTest_build.xml" target="cleanall"/>
+         </then>
+      </if>
+      <delete dir="${DEST_DIR_OUTPUT}"/>
+      <delete dir="${DEST_DIR_DEBUG}"/>
+      <delete>
+         <fileset dir="${BIN_DIR}" includes="**PeimPcdTest*"/>
+      </delete>
+   </target>
+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c
new file mode 100644
index 0000000..675a550
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c
@@ -0,0 +1,124 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Crc32.c

+

+Abstract:

+

+  CalculateCrc32 Boot Services as defined in DXE CIS.

+

+  This Boot Services is in the Runtime Driver because this service is

+  also required by SetVirtualAddressMap() when the EFI System Table and

+  EFI Runtime Services Table are converted from physical address to 

+  virtual addresses.  This requires that the 32-bit CRC be recomputed.

+

+Revision History:

+

+--*/

+

+#include "Runtime.h"

+

+UINT32  mCrcTable[256];

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverCalculateCrc32 (

+  IN  VOID    *Data,

+  IN  UINTN   DataSize,

+  OUT UINT32  *CrcOut

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  UINT32  Crc;

+  UINTN   Index;

+  UINT8   *Ptr;

+

+  if (Data == NULL || DataSize == 0 || CrcOut == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Crc = 0xffffffff;

+  for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {

+    Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];

+  }

+

+  *CrcOut = Crc ^ 0xffffffff;

+  return EFI_SUCCESS;

+}

+

+UINT32

+ReverseBits (

+  UINT32  Value

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  UINTN   Index;

+  UINT32  NewValue;

+

+  NewValue = 0;

+  for (Index = 0; Index < 32; Index++) {

+    if (Value & (1 << Index)) {

+      NewValue = NewValue | (1 << (31 - Index));

+    }

+  }

+

+  return NewValue;

+}

+

+VOID

+RuntimeDriverInitializeCrc32Table (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  UINTN   TableEntry;

+  UINTN   Index;

+  UINT32  Value;

+

+  for (TableEntry = 0; TableEntry < 256; TableEntry++) {

+    Value = ReverseBits ((UINT32) TableEntry);

+    for (Index = 0; Index < 8; Index++) {

+      if (Value & 0x80000000) {

+        Value = (Value << 1) ^ 0x04c11db7;

+      } else {

+        Value = Value << 1;

+      }

+    }

+

+    mCrcTable[TableEntry] = ReverseBits (Value);

+  }

+}

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c
new file mode 100644
index 0000000..82d464a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c
@@ -0,0 +1,88 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeHotRelocateEx.c

+

+Abstract:

+

+    Stub to resolve the IPF hook that handles IPF specific relocation types

+

+

+Revision History

+

+--*/

+

+#include "Runtime.h"

+

+EFI_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+

+  Performs an Itanium-based platform specific relocation fixup

+

+Arguments:

+

+  Reloc      - Pointer to the relocation record

+

+  Fixup      - Pointer to the address to fix up

+

+  FixupData  - Pointer to a buffer to log the fixups

+

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  return EFI_SUCCESS;

+

+}

+

+//

+// Cache Flush Routine.

+//

+EFI_STATUS

+FlushCpuCache (

+  IN EFI_PHYSICAL_ADDRESS          Start,

+  IN UINT64                        Length

+  )

+/*++

+

+Routine Description:

+

+  Flush cache with specified range.

+

+Arguments:

+

+  Start   - Start address

+  Length  - Length in bytes

+

+Returns:

+

+  Status code

+  

+  EFI_SUCCESS - success

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c
new file mode 100644
index 0000000..ffc0aaf
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c
@@ -0,0 +1,242 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeHotRelocateEx.c

+

+Abstract:

+

+    Fixes IPF specific relocation types

+

+

+Revision History

+

+--*/

+

+#include "Runtime.h"

+#include "PeHotRelocateEx.h"

+

+EFI_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+

+  Performs an IPF specific relocation fixup

+

+Arguments:

+

+  Reloc      - Pointer to the relocation record

+

+  Fixup      - Pointer to the address to fix up

+

+  FixupData  - Pointer to a buffer to log the fixups

+

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT64  *F64;

+  UINT64  FixupVal;

+

+  switch ((*Reloc) >> 12) {

+  case EFI_IMAGE_REL_BASED_DIR64:

+    F64         = (UINT64 *) Fixup;

+    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));

+    if (*(UINT64 *) (*FixupData) == *F64) {

+      *F64 = *F64 + (UINT64) Adjust;

+    }

+

+    *FixupData = *FixupData + sizeof (UINT64);

+    break;

+

+  case EFI_IMAGE_REL_BASED_IA64_IMM64:

+    F64         = (UINT64 *) Fixup;

+    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));

+    if (*(UINT64 *) (*FixupData) == *F64) {

+      //

+      // Align it to bundle address before fixing up the

+      // 64-bit immediate value of the movl instruction.

+      //

+      //

+      Fixup     = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));

+      FixupVal  = (UINT64) 0;

+

+      //

+      // Extract the lower 32 bits of IMM64 from bundle

+      //

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,

+        IMM64_IMM7B_SIZE_X,

+        IMM64_IMM7B_INST_WORD_POS_X,

+        IMM64_IMM7B_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,

+        IMM64_IMM9D_SIZE_X,

+        IMM64_IMM9D_INST_WORD_POS_X,

+        IMM64_IMM9D_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,

+        IMM64_IMM5C_SIZE_X,

+        IMM64_IMM5C_INST_WORD_POS_X,

+        IMM64_IMM5C_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,

+        IMM64_IC_SIZE_X,

+        IMM64_IC_INST_WORD_POS_X,

+        IMM64_IC_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,

+        IMM64_IMM41a_SIZE_X,

+        IMM64_IMM41a_INST_WORD_POS_X,

+        IMM64_IMM41a_VAL_POS_X

+        );

+

+      //

+      // Update 64-bit address

+      //

+      FixupVal += Adjust;

+

+      //

+      // Insert IMM64 into bundle

+      //

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),

+        IMM64_IMM7B_SIZE_X,

+        IMM64_IMM7B_INST_WORD_POS_X,

+        IMM64_IMM7B_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),

+        IMM64_IMM9D_SIZE_X,

+        IMM64_IMM9D_INST_WORD_POS_X,

+        IMM64_IMM9D_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),

+        IMM64_IMM5C_SIZE_X,

+        IMM64_IMM5C_INST_WORD_POS_X,

+        IMM64_IMM5C_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),

+        IMM64_IC_SIZE_X,

+        IMM64_IC_INST_WORD_POS_X,

+        IMM64_IC_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),

+        IMM64_IMM41a_SIZE_X,

+        IMM64_IMM41a_INST_WORD_POS_X,

+        IMM64_IMM41a_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),

+        IMM64_IMM41b_SIZE_X,

+        IMM64_IMM41b_INST_WORD_POS_X,

+        IMM64_IMM41b_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),

+        IMM64_IMM41c_SIZE_X,

+        IMM64_IMM41c_INST_WORD_POS_X,

+        IMM64_IMM41c_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),

+        IMM64_SIGN_SIZE_X,

+        IMM64_SIGN_INST_WORD_POS_X,

+        IMM64_SIGN_VAL_POS_X

+        );

+

+      *(UINT64 *) (*FixupData) = *F64;

+    }

+

+    *FixupData = *FixupData + sizeof (UINT64);

+    break;

+

+  default:

+    DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+//

+// Cache Flush Routine.

+//

+EFI_STATUS

+FlushCpuCache (

+  IN EFI_PHYSICAL_ADDRESS          Start,

+  IN UINT64                        Length

+  )

+/*++

+

+Routine Description:

+

+  Flush cache with specified range.

+

+Arguments:

+

+  Start   - Start address

+  Length  - Length in bytes

+

+Returns:

+

+  Status code

+  

+  EFI_SUCCESS - success

+

+--*/

+{

+  SalFlushCache (Start, Length);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h
new file mode 100644
index 0000000..00c3c10
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h
@@ -0,0 +1,76 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeHotRelocateEx.h

+

+Abstract:

+

+    Fixes Intel Itanium(TM) specific relocation types

+

+

+Revision History

+

+--*/

+

+#ifndef _PEHOTRELOCATE_EX_H_

+#define _PEHOTRELOCATE_EX_H_

+

+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \

+  Value |= (((UINT64) ((*(Address) >> InstPos) & (((UINT64) 1 << Size) - 1))) << ValPos)

+

+#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \

+   * (UINT32 *) Address = \

+    (*(UINT32 *) Address &~(((1 << Size) - 1) << InstPos)) | \

+      ((UINT32) ((((UINT64) Value >> ValPos) & (((UINT64) 1 << Size) - 1))) << InstPos)

+

+#define IMM64_IMM7B_INST_WORD_X       3

+#define IMM64_IMM7B_SIZE_X            7

+#define IMM64_IMM7B_INST_WORD_POS_X   4

+#define IMM64_IMM7B_VAL_POS_X         0

+

+#define IMM64_IMM9D_INST_WORD_X       3

+#define IMM64_IMM9D_SIZE_X            9

+#define IMM64_IMM9D_INST_WORD_POS_X   18

+#define IMM64_IMM9D_VAL_POS_X         7

+

+#define IMM64_IMM5C_INST_WORD_X       3

+#define IMM64_IMM5C_SIZE_X            5

+#define IMM64_IMM5C_INST_WORD_POS_X   13

+#define IMM64_IMM5C_VAL_POS_X         16

+

+#define IMM64_IC_INST_WORD_X          3

+#define IMM64_IC_SIZE_X               1

+#define IMM64_IC_INST_WORD_POS_X      12

+#define IMM64_IC_VAL_POS_X            21

+

+#define IMM64_IMM41a_INST_WORD_X      1

+#define IMM64_IMM41a_SIZE_X           10

+#define IMM64_IMM41a_INST_WORD_POS_X  14

+#define IMM64_IMM41a_VAL_POS_X        22

+

+#define IMM64_IMM41b_INST_WORD_X      1

+#define IMM64_IMM41b_SIZE_X           8

+#define IMM64_IMM41b_INST_WORD_POS_X  24

+#define IMM64_IMM41b_VAL_POS_X        32

+

+#define IMM64_IMM41c_INST_WORD_X      2

+#define IMM64_IMM41c_SIZE_X           23

+#define IMM64_IMM41c_INST_WORD_POS_X  0

+#define IMM64_IMM41c_VAL_POS_X        40

+

+#define IMM64_SIGN_INST_WORD_X        3

+#define IMM64_SIGN_SIZE_X             1

+#define IMM64_SIGN_INST_WORD_POS_X    27

+#define IMM64_SIGN_VAL_POS_X          63

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c
new file mode 100644
index 0000000..4c2aeff
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c
@@ -0,0 +1,216 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PeHotRelocate.c

+

+Abstract:

+

+

+--*/

+

+#include "Runtime.h"

+

+STATIC

+VOID *

+RuntimePeImageAddress (

+  IN   RUNTIME_IMAGE_RELOCATION_DATA  *Image,

+  IN   UINTN                          Address

+  )

+/*++

+

+Routine Description:

+

+  Converts an image address to the loaded address

+

+Arguments:

+

+  Image         - The relocation data of the image being loaded

+

+  Address       - The address to be converted to the loaded address

+

+Returns:

+

+  NULL if the address can not be converted, otherwise, the converted address

+

+--*/

+{

+  if (Address >= (Image->ImageSize) << EFI_PAGE_SHIFT) {

+    return NULL;

+  }

+

+  return (CHAR8 *) ((UINTN) Image->ImageBase + Address);

+}

+

+VOID

+RelocatePeImageForRuntime (

+  RUNTIME_IMAGE_RELOCATION_DATA *Image

+  )

+{

+  CHAR8                     *OldBase;

+  CHAR8                     *NewBase;

+  EFI_IMAGE_DOS_HEADER      *DosHdr;

+  EFI_IMAGE_NT_HEADERS      *PeHdr;

+  UINT32                    NumberOfRvaAndSizes;

+  EFI_IMAGE_DATA_DIRECTORY  *DataDirectory;

+  EFI_IMAGE_DATA_DIRECTORY  *RelocDir;

+  EFI_IMAGE_BASE_RELOCATION *RelocBase;

+  EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;

+  UINT16                    *Reloc;

+  UINT16                    *RelocEnd;

+  CHAR8                     *Fixup;

+  CHAR8                     *FixupBase;

+  UINT16                    *F16;

+  UINT32                    *F32;

+  CHAR8                     *FixupData;

+  UINTN                     Adjust;

+  EFI_STATUS                Status;

+

+  OldBase = (CHAR8 *) ((UINTN) Image->ImageBase);

+  NewBase = (CHAR8 *) ((UINTN) Image->ImageBase);

+

+  Status  = RuntimeDriverConvertPointer (0, (VOID **) &NewBase);

+  ASSERT_EFI_ERROR (Status);

+

+  Adjust = (UINTN) NewBase - (UINTN) OldBase;

+

+  //

+  // Find the image's relocate dir info

+  //

+  DosHdr = (EFI_IMAGE_DOS_HEADER *) OldBase;

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // Valid DOS header so get address of PE header

+    //

+    PeHdr = (EFI_IMAGE_NT_HEADERS *) (((CHAR8 *) DosHdr) + DosHdr->e_lfanew);

+  } else {

+    //

+    // No Dos header so assume image starts with PE header.

+    //

+    PeHdr = (EFI_IMAGE_NT_HEADERS *) OldBase;

+  }

+

+  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {

+    //

+    // Not a valid PE image so Exit

+    //

+    return ;

+  }

+  //

+  // Get some data from the PE type dependent data

+  //

+  NumberOfRvaAndSizes = PeHdr->OptionalHeader.NumberOfRvaAndSizes;

+  DataDirectory       = &PeHdr->OptionalHeader.DataDirectory[0];

+

+  //

+  // Find the relocation block

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory

+  // is present in the image. You have to check the NumberOfRvaAndSizes in

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+    RelocDir      = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;

+    RelocBase     = RuntimePeImageAddress (Image, RelocDir->VirtualAddress);

+    RelocBaseEnd  = RuntimePeImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);

+  } else {

+    //

+    // Cannot find relocations, cannot continue

+    //

+    ASSERT (FALSE);

+    return ;

+  }

+

+  ASSERT (RelocBase != NULL && RelocBaseEnd != NULL);

+

+  //

+  // Run the whole relocation block. And re-fixup data that has not been

+  // modified. The FixupData is used to see if the image has been modified

+  // since it was relocated. This is so data sections that have been updated

+  // by code will not be fixed up, since that would set them back to

+  // defaults.

+  //

+  FixupData = Image->RelocationData;

+  while (RelocBase < RelocBaseEnd) {

+

+    Reloc     = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));

+    RelocEnd  = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);

+    FixupBase = (CHAR8 *) ((UINTN) Image->ImageBase) + RelocBase->VirtualAddress;

+

+    //

+    // Run this relocation record

+    //

+    while (Reloc < RelocEnd) {

+

+      Fixup = FixupBase + (*Reloc & 0xFFF);

+      switch ((*Reloc) >> 12) {

+

+      case EFI_IMAGE_REL_BASED_ABSOLUTE:

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGH:

+        F16 = (UINT16 *) Fixup;

+        if (*(UINT16 *) FixupData == *F16) {

+          *F16 = (UINT16) ((*F16 << 16) + ((UINT16) Adjust & 0xffff));

+        }

+

+        FixupData = FixupData + sizeof (UINT16);

+        break;

+

+      case EFI_IMAGE_REL_BASED_LOW:

+        F16 = (UINT16 *) Fixup;

+        if (*(UINT16 *) FixupData == *F16) {

+          *F16 = (UINT16) (*F16 + ((UINT16) Adjust & 0xffff));

+        }

+

+        FixupData = FixupData + sizeof (UINT16);

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHLOW:

+        F32       = (UINT32 *) Fixup;

+        FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));

+        if (*(UINT32 *) FixupData == *F32) {

+          *F32 = *F32 + (UINT32) Adjust;

+        }

+

+        FixupData = FixupData + sizeof (UINT32);

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHADJ:

+        //

+        // Not implemented, but not used in EFI 1.0

+        //

+        ASSERT (FALSE);

+        break;

+

+      default:

+        //

+        // Only Itanium requires ConvertPeImage_Ex

+        //

+        Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);

+        if (EFI_ERROR (Status)) {

+          return ;

+        }

+      }

+      //

+      // Next relocation record

+      //

+      Reloc += 1;

+    }

+    //

+    // next reloc block

+    //

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;

+  }

+

+  FlushCpuCache (Image->ImageBase, (UINT64) Image->ImageSize);

+}

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c
new file mode 100644
index 0000000..5a21d49
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c
@@ -0,0 +1,574 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Runtime.c

+

+Abstract:

+

+  Runtime Architectural Protocol as defined in the DXE CIS

+

+  This code is used to produce the EFI runtime virtual switch over

+

+  THIS IS VERY DANGEROUS CODE BE VERY CAREFUL IF YOU CHANGE IT

+

+  The transition for calling EFI Runtime functions in physical mode to calling

+  them in virtual mode is very very complex. Every pointer in needs to be 

+  converted from physical mode to virtual mode. Be very careful walking linked

+  lists! Then to make it really hard the code it's self needs be relocated into

+  the new virtual address space.

+

+  So here is the concept. The code in this module will never ever be called in

+  virtual mode. This is the code that collects the information needed to convert

+  to virtual mode (DXE core registers runtime stuff with this code). Since this 

+  code is used to fixup all runtime images, it CAN NOT fix it's self up. So some

+  code has to stay behind and that is us.

+

+  Also you need to be careful about when you allocate memory, as once we are in 

+  runtime (including our EVT_SIGNAL_EXIT_BOOT_SERVICES event) you can no longer 

+  allocate memory.

+

+  Any runtime driver that gets loaded before us will not be callable in virtual 

+  mode. This is due to the fact that the DXE core can not register the info 

+  needed with us. This is good, since it keeps the code in this file from 

+  getting registered.

+

+

+Revision History:

+

+  - Move the CalculateCrc32 function from Runtime Arch Protocol to Boot Service.

+  Runtime Arch Protocol definition no longer contains CalculateCrc32. Boot Service

+  Table now contains an item named CalculateCrc32.

+

+--*/

+

+

+#include "Runtime.h"

+

+//

+// This is a only short term solution.

+// There is a change coming to the Runtime AP that

+// will make it so the Runtime driver will not have to allocate any buffers. 

+//

+#define MAX_RUNTIME_IMAGE_NUM (64)

+#define MAX_RUNTIME_EVENT_NUM (64)

+RUNTIME_IMAGE_RELOCATION_DATA mRuntimeImageBuffer[MAX_RUNTIME_IMAGE_NUM];

+RUNTIME_NOTIFY_EVENT_DATA     mRuntimeEventBuffer[MAX_RUNTIME_EVENT_NUM];

+UINTN                         mRuntimeImageNumber;

+UINTN                         mRuntimeEventNumber;

+

+//

+// The handle onto which the Runtime Architectural Protocol instance is installed

+//

+EFI_HANDLE                    mRuntimeHandle = NULL;

+

+//

+// The Runtime Architectural Protocol instance produced by this driver

+//

+EFI_RUNTIME_ARCH_PROTOCOL     mRuntime = {

+  RuntimeDriverRegisterImage,

+  RuntimeDriverRegisterEvent

+};

+

+//

+// Global Variables

+//

+LIST_ENTRY                    mRelocationList             = INITIALIZE_LIST_HEAD_VARIABLE(mRelocationList);

+LIST_ENTRY                    mEventList                  = INITIALIZE_LIST_HEAD_VARIABLE(mEventList);

+BOOLEAN                       mEfiVirtualMode             = FALSE;

+EFI_GUID                      mLocalEfiUgaIoProtocolGuid  = EFI_UGA_IO_PROTOCOL_GUID;

+EFI_MEMORY_DESCRIPTOR         *mVirtualMap                = NULL;

+UINTN                         mVirtualMapDescriptorSize;

+UINTN                         mVirtualMapMaxIndex;

+

+EFI_LOADED_IMAGE_PROTOCOL     *mMyLoadedImage;

+

+//

+// Worker Functions

+//

+VOID

+RuntimeDriverCalculateEfiHdrCrc (

+  IN OUT EFI_TABLE_HEADER  *Hdr

+  )

+/*++

+

+Routine Description:

+

+  Calcualte the 32-bit CRC in a EFI table using the Runtime Drivers

+  internal function.  The EFI Boot Services Table can not be used because

+  the EFI Boot Services Table was destroyed at ExitBootServices()

+

+Arguments:

+

+  Hdr  - Pointer to an EFI standard header

+

+Returns:

+

+  None

+

+--*/

+{

+  UINT32  Crc;

+

+  Hdr->CRC32  = 0;

+

+  Crc         = 0;

+  RuntimeDriverCalculateCrc32 ((UINT8 *) Hdr, Hdr->HeaderSize, &Crc);

+  Hdr->CRC32 = Crc;

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverRegisterImage (

+  IN  EFI_RUNTIME_ARCH_PROTOCOL  *This,

+  IN  EFI_PHYSICAL_ADDRESS       ImageBase,

+  IN  UINTN                      ImageSize,

+  IN  VOID                       *RelocationData

+  )

+/*++

+

+Routine Description:

+

+  When a SetVirtualAddressMap() is performed all the runtime images loaded by 

+  DXE must be fixed up with the new virtual address map. To facilitate this the 

+  Runtime Architectural Protocol needs to be informed of every runtime driver 

+  that is registered.  All the runtime images loaded by DXE should be registered 

+  with this service by the DXE Core when ExitBootServices() is called.  The 

+  images that are registered with this service must have successfully been 

+  loaded into memory with the Boot Service LoadImage().  As a result, no 

+  parameter checking needs to be performed.

+

+Arguments:

+

+  This           - The EFI_RUNTIME_ARCH_PROTOCOL instance. 

+

+  ImageBase      - Start of image that has been loaded in memory. It is either 

+                   a pointer to the DOS or PE header of the image.

+

+  ImageSize      - Size of the image in bytes.

+

+  RelocationData - Information about the fixups that were performed on ImageBase 

+                   when it was loaded into memory. This information is needed 

+                   when the virtual mode fix-ups are reapplied so that data that 

+                   has been programmatically updated will not be fixed up. If 

+                   code updates a global variable the code is responsible for 

+                   fixing up the variable for virtual mode.

+

+Returns: 

+

+  EFI_SUCCESS          - The ImageBase has been registered.

+

+--*/

+{

+  RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage;

+

+  if (mMyLoadedImage->ImageBase == (VOID *) (UINTN) ImageBase) {

+    //

+    // We don't want to relocate our selves, as we only run in physical mode.

+    //

+    return EFI_SUCCESS;

+  }

+

+  RuntimeImage = &mRuntimeImageBuffer[mRuntimeImageNumber];

+  mRuntimeImageNumber++;

+  ASSERT (mRuntimeImageNumber < MAX_RUNTIME_IMAGE_NUM);

+

+  RuntimeImage->Valid           = TRUE;

+  RuntimeImage->ImageBase       = ImageBase;

+  RuntimeImage->ImageSize       = ImageSize;

+  RuntimeImage->RelocationData  = RelocationData;

+

+  InsertTailList (&mRelocationList, &RuntimeImage->Link);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverRegisterEvent (

+  IN EFI_RUNTIME_ARCH_PROTOCOL  *This,

+  IN UINT32                     Type,

+  IN EFI_TPL                    NotifyTpl,

+  IN EFI_EVENT_NOTIFY           NotifyFunction,

+  IN VOID                       *NotifyContext,

+  IN EFI_EVENT                  *Event

+  )

+/*++

+

+Routine Description:

+

+  This function is used to support the required runtime events. Currently only 

+  runtime events of type EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE needs to be 

+  registered with this service.  All the runtime events that exist in the DXE 

+  Core should be registered with this service when ExitBootServices() is called.  

+  All the events that are registered with this service must have been created 

+  with the Boot Service CreateEvent().  As a result, no parameter checking needs 

+  to be performed.

+

+Arguments:

+

+  This           - The EFI_RUNTIME_ARCH_PROTOCOL instance. 

+

+  Type           - The same as Type passed into CreateEvent().

+

+  NotifyTpl      - The same as NotifyTpl passed into CreateEvent().

+

+  NotifyFunction - The same as NotifyFunction passed into CreateEvent().

+

+  NotifyContext  - The same as NotifyContext passed into CreateEvent().

+

+  Event          - The EFI_EVENT returned by CreateEvent().  Event must be in 

+                   runtime memory.

+

+Returns: 

+

+  EFI_SUCCESS          - The Event has been registered.

+

+--*/

+{

+  RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent;

+

+  RuntimeEvent = &mRuntimeEventBuffer[mRuntimeEventNumber];

+  mRuntimeEventNumber++;

+  ASSERT (mRuntimeEventNumber < MAX_RUNTIME_EVENT_NUM);

+

+  RuntimeEvent->Type            = Type;

+  RuntimeEvent->NotifyTpl       = NotifyTpl;

+  RuntimeEvent->NotifyFunction  = NotifyFunction;

+  RuntimeEvent->NotifyContext   = NotifyContext;

+  RuntimeEvent->Event           = Event;

+

+  InsertTailList (&mEventList, &RuntimeEvent->Link);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverConvertPointer (

+  IN     UINTN  DebugDisposition,

+  IN OUT VOID   **ConvertAddress

+  )

+{

+  UINTN                 Address;

+  VOID                  *PlabelConvertAddress;

+  UINT64                VirtEndOfRange;

+  EFI_MEMORY_DESCRIPTOR *VirtEntry;

+  UINTN                 Index;

+

+  //

+  // Make sure ConvertAddress is a valid pointer

+  //

+  if (ConvertAddress == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Get the address to convert

+  //

+  Address = (UINTN) *ConvertAddress;

+

+  //

+  // If this is a null pointer, return if it's allowed

+  //

+  if (Address == 0) {

+    if (DebugDisposition & EFI_OPTIONAL_POINTER) {

+      return EFI_SUCCESS;

+    }

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PlabelConvertAddress  = NULL;

+  VirtEntry             = mVirtualMap;

+  for (Index = 0; Index < mVirtualMapMaxIndex; Index++) {

+    //

+    // To prevent the inclusion of 64-bit math functions a UINTN was placed in

+    //  front of VirtEntry->NumberOfPages to cast it to a 32-bit thing on IA-32

+    //  platforms. If you get this ASSERT remove the UINTN and do a 64-bit

+    //  multiply.

+    //

+    ASSERT ((VirtEntry->NumberOfPages < 0xffffffff) || (sizeof (UINTN) > 4));

+

+    if ((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {

+      if (Address >= VirtEntry->PhysicalStart) {

+        VirtEndOfRange = VirtEntry->PhysicalStart + (((UINTN) VirtEntry->NumberOfPages) * EFI_PAGE_SIZE);

+        if (Address < VirtEndOfRange) {

+          //

+          // Compute new address

+          //

+          *ConvertAddress = (VOID *) (Address - (UINTN) VirtEntry->PhysicalStart + (UINTN) VirtEntry->VirtualStart);

+          return EFI_SUCCESS;

+        } else if (Address < (VirtEndOfRange + 0x200000)) {

+          //

+          // On Itanium GP defines a window +/- 2 MB inside an image.

+          // The compiler may asign a GP value outside of the image. Thus

+          // it could fall out side of any of our valid regions

+          //

+          PlabelConvertAddress = (VOID *) (Address - (UINTN) VirtEntry->PhysicalStart + (UINTN) VirtEntry->VirtualStart);

+        }

+      }

+    }

+

+    VirtEntry = NextMemoryDescriptor (VirtEntry, mVirtualMapDescriptorSize);

+  }

+

+  if (DebugDisposition & EFI_IPF_GP_POINTER) {

+    //

+    // If it's an IPF GP and the GP was outside the image handle that case.

+    //

+    if (PlabelConvertAddress != NULL) {

+      *ConvertAddress = PlabelConvertAddress;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+RuntimeDriverConvertInternalPointer (

+  IN OUT VOID   **ConvertAddress

+  )

+{

+  return RuntimeDriverConvertPointer (0x0, ConvertAddress);

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverSetVirtualAddressMap (

+  IN UINTN                  MemoryMapSize,

+  IN UINTN                  DescriptorSize,

+  IN UINT32                 DescriptorVersion,

+  IN EFI_MEMORY_DESCRIPTOR  *VirtualMap

+  )

+{

+  RUNTIME_NOTIFY_EVENT_DATA     *RuntimeEvent;

+  RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage;

+  LIST_ENTRY                    *Link;

+  UINTN                         Index;

+  UINTN                         Index1;

+  EFI_DRIVER_OS_HANDOFF_HEADER  *DriverOsHandoffHeader;

+  EFI_DRIVER_OS_HANDOFF         *DriverOsHandoff;

+

+  //

+  // Can only switch to virtual addresses once the memory map is locked down,

+  // and can only set it once

+  //

+  if (!EfiAtRuntime () || mEfiVirtualMode) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Only understand the original descriptor format

+  //

+  if (DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION || DescriptorSize < sizeof (EFI_MEMORY_DESCRIPTOR)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // BugBug: Add code here to verify the memory map. We should

+  //  cache a copy of the system memory map in the EFI System Table

+  //  as a GUID pointer pair.

+  //

+  //

+  // Make sure all virtual translations are satisfied

+  //

+  mVirtualMapMaxIndex = MemoryMapSize / DescriptorSize;

+

+  //

+  // BugBug :The following code does not work hence commented out.

+  // Need to be replaced by something that works.

+  //

+  //  VirtEntry = VirtualMap;

+  //  for (Index = 0; Index < mVirtualMapMaxIndex; Index++) {

+  //    if (((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) &&

+  //        (VirtEntry->VirtualStart != 0) ) {

+  //        return EFI_NO_MAPPING;

+  //    }

+  //    VirtEntry = NextMemoryDescriptor(VirtEntry, DescriptorSize);

+  //  }

+  //

+  // We are now committed to go to virtual mode, so lets get to it!

+  //

+  mEfiVirtualMode = TRUE;

+

+  //

+  // ConvertPointer() needs this mVirtualMap to do the conversion. So set up

+  // globals we need to parse the virtual address map.

+  //

+  mVirtualMapDescriptorSize = DescriptorSize;

+  mVirtualMap               = VirtualMap;

+

+  //

+  // Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events.

+  // The core call RuntimeDriverRegisterEvent() for

+  // every runtime event and we stored them in the mEventList

+  //

+  //

+  // Currently the bug in StatusCode/RuntimeLib has been fixed, it will

+  // check whether in Runtime or not (this is judged by looking at

+  // mEfiAtRuntime global So this ReportStatusCode will work

+  //

+  REPORT_STATUS_CODE (

+          EFI_PROGRESS_CODE,

+          (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP)

+          );

+

+  //

+  // BugBug - Commented out for now because the status code driver is not

+  // ready for runtime yet. The Status Code driver calls data hub with does

+  // a bunch of Boot Service things (locks, AllocatePool) and hangs somewhere

+  // on the way.

+  //

+  //  ReportStatusCode (

+  //        EfiProgressCode,  EfiMaxErrorSeverity,

+  //        0x03, 0x01, 12, // ReadyToBoot Progress code

+  //        0x00, 30, L"ConvertPointer"

+  //        );

+  //

+  for (Link = mEventList.ForwardLink; Link != &mEventList; Link = Link->ForwardLink) {

+    RuntimeEvent = _CR (Link, RUNTIME_NOTIFY_EVENT_DATA, Link);

+    if ((RuntimeEvent->Type & EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {

+      RuntimeEvent->NotifyFunction (

+                      RuntimeEvent->Event,

+                      RuntimeEvent->NotifyContext

+                      );

+    }

+  }

+  //

+  // Relocate runtime images. Runtime images loaded before the runtime AP was

+  // started will not be relocated, since they would not have gotten registered.

+  // This includes the code in this file.

+  //

+  for (Link = mRelocationList.ForwardLink; Link != &mRelocationList; Link = Link->ForwardLink) {

+    RuntimeImage = _CR (Link, RUNTIME_IMAGE_RELOCATION_DATA, Link);

+    if (RuntimeImage->Valid) {

+      RelocatePeImageForRuntime (RuntimeImage);

+    }

+  }

+  //

+  // Convert all the Runtime Services except ConvertPointer() and SetVirtualAddressMap()

+  // and recompute the CRC-32

+  //

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetTime);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetTime);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetWakeupTime);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetWakeupTime);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ResetSystem);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextHighMonotonicCount);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetVariable);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetVariable);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextVariableName);

+  RuntimeDriverCalculateEfiHdrCrc (&gRT->Hdr);

+

+  //

+  // Convert the UGA OS Handoff Table if it is present in the Configuration Table

+  //

+  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {

+    if (CompareGuid (&mLocalEfiUgaIoProtocolGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {

+      DriverOsHandoffHeader = gST->ConfigurationTable[Index].VendorTable;

+      for (Index1 = 0; Index1 < DriverOsHandoffHeader->NumberOfEntries; Index1++) {

+        DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)

+          (

+            (UINTN) DriverOsHandoffHeader +

+            DriverOsHandoffHeader->HeaderSize +

+            Index1 *

+            DriverOsHandoffHeader->SizeOfEntries

+          );

+        RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &DriverOsHandoff->DevicePath);

+        RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &DriverOsHandoff->PciRomImage);

+      }

+

+      RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(gST->ConfigurationTable[Index].VendorTable));

+    }

+  }

+  //

+  // Convert the runtime fields of the EFI System Table and recompute the CRC-32

+  //

+  RuntimeDriverConvertInternalPointer ((VOID **) &gST->FirmwareVendor);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gST->ConfigurationTable);

+  RuntimeDriverConvertInternalPointer ((VOID **) &gST->RuntimeServices);

+  RuntimeDriverCalculateEfiHdrCrc (&gST->Hdr);

+

+  //

+  // At this point, gRT and gST are physical pointers, but the contents of these tables

+  // have been converted to runtime.

+  //

+  //

+  // mVirtualMap is only valid during SetVirtualAddressMap() call

+  //

+  mVirtualMap = NULL;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+/*++

+

+Routine Description:

+  Install Runtime AP. This code includes the EfiDriverLib, but it functions at

+  RT in physical mode. The only Lib services are gBS, gRT, and the DEBUG and

+  ASSERT macros (they do ReportStatusCode).

+

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+  EFI_SUCEESS - Runtime Driver Architectural Protocol Installed

+

+  Other       - Return value from gBS->InstallMultipleProtocolInterfaces

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // This image needs to be exclued from relocation for virtual mode, so cache

+  // a copy of the Loaded Image protocol to test later.

+  //

+  Status = gBS->HandleProtocol (

+                  ImageHandle,

+                  &gEfiLoadedImageProtocolGuid,

+                  (VOID **) &mMyLoadedImage

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Initialize the table used to compute 32-bit CRCs

+  //

+  RuntimeDriverInitializeCrc32Table ();

+

+  //

+  // Fill in the entries of the EFI Boot Services and EFI Runtime Services Tables

+  //

+  gBS->CalculateCrc32         = RuntimeDriverCalculateCrc32;

+  gRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap;

+  gRT->ConvertPointer       = RuntimeDriverConvertPointer;

+

+  //

+  // Install the Runtime Architectural Protocol onto a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mRuntimeHandle,

+                  &gEfiRuntimeArchProtocolGuid,

+                  &mRuntime,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  mRuntimeImageNumber = 0;

+  mRuntimeEventNumber = 0;

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs
new file mode 100644
index 0000000..42ca881
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Runtime.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h
new file mode 100644
index 0000000..3803a9d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h
@@ -0,0 +1,129 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Runtime.h

+

+Abstract:

+

+  Runtime Architectural Protocol as defined in the DXE CIS

+

+  This code is used to produce the EFI runtime virtual switch over

+

+--*/

+

+#ifndef _RUNTIME_H_

+#define _RUNTIME_H_

+

+//

+// Data structures

+//

+typedef struct {

+  LIST_ENTRY            Link;

+  BOOLEAN               Valid;

+  EFI_PHYSICAL_ADDRESS  ImageBase;

+  UINTN                 ImageSize;  // In no. of pages

+  VOID                  *RelocationData;

+} RUNTIME_IMAGE_RELOCATION_DATA;

+

+typedef struct {

+  LIST_ENTRY          Link;

+  IN UINT32           Type;

+  IN EFI_TPL          NotifyTpl;

+  IN EFI_EVENT_NOTIFY NotifyFunction;

+  IN VOID             *NotifyContext;

+  IN EFI_EVENT        Event;

+} RUNTIME_NOTIFY_EVENT_DATA;

+

+//

+// Function Prototypes

+//

+VOID

+RelocatePeImageForRuntime (

+  RUNTIME_IMAGE_RELOCATION_DATA  *Image

+  )

+;

+

+EFI_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+;

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverCalculateCrc32 (

+  IN  VOID    *Data,

+  IN  UINTN   DataSize,

+  OUT UINT32  *CrcOut

+  )

+;

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverRegisterImage (

+  IN  EFI_RUNTIME_ARCH_PROTOCOL         *This,

+  IN  EFI_PHYSICAL_ADDRESS              ImageBase,

+  IN  UINTN                             ImageSize,

+  IN  VOID                              *RelocationData

+  )

+;

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverRegisterEvent (

+  IN EFI_RUNTIME_ARCH_PROTOCOL          *This,

+  IN UINT32                             Type,

+  IN EFI_TPL                            NotifyTpl,

+  IN EFI_EVENT_NOTIFY                   NotifyFunction,

+  IN VOID                               *NotifyContext,

+  IN EFI_EVENT                          *Event

+  )

+;

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverConvertPointer (

+  IN     UINTN  DebugDisposition,

+  IN OUT VOID   **ConvertAddress

+  )

+;

+

+VOID

+RuntimeDriverInitializeCrc32Table (

+  VOID

+  )

+;

+

+EFI_STATUS

+EFIAPI

+RuntimeDriverInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+;

+

+

+//

+// Cache Flush Routine.

+//

+EFI_STATUS

+FlushCpuCache (

+  IN EFI_PHYSICAL_ADDRESS          Start,

+  IN UINT64                        Length

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd
new file mode 100644
index 0000000..19ac595
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Runtime</BaseName>

+    <Guid>B601F8C4-43B7-4784-95B1-F4226CB40CEE</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Arch ArchType="IPF">

+      <Library>EdkDxeSalLib</Library>

+    </Arch>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa
new file mode 100644
index 0000000..5c1b5e1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Runtime</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>B601F8C4-43B7-4784-95B1-F4226CB40CEE</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Runtime.dxs</Filename>

+    <Filename>PeHotRelocate.c</Filename>

+    <Filename>Runtime.c</Filename>

+    <Filename>Runtime.h</Filename>

+    <Filename>Crc32.c</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/PeHotRelocateEx.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x64/PeHotRelocateEx.c</Filename>

+      <Filename>x64/PeHotRelocateEx.h</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/PeHotRelocateEx.c</Filename>

+      <Filename>Ipf/PeHotRelocateEx.h</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Runtime</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>RuntimeDriverInitialize</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <SetVirtualAddressMapCallBack></SetVirtualAddressMapCallBack>

+      <ExitBootServicesCallBack></ExitBootServicesCallBack>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml
new file mode 100644
index 0000000..48f5fe7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Runtime"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Runtime/RuntimeDxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Runtime">

+      <GenBuild baseName="Runtime" mbdFilename="${MODULE_DIR}/Runtime.mbd" msaFilename="${MODULE_DIR}/Runtime.msa"/>

+   </target>

+   <target depends="Runtime_clean" name="clean"/>

+   <target depends="Runtime_cleanall" name="cleanall"/>

+   <target name="Runtime_clean">

+      <OutputDirSetup baseName="Runtime" mbdFilename="${MODULE_DIR}/Runtime.mbd" msaFilename="${MODULE_DIR}/Runtime.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Runtime_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Runtime_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Runtime_cleanall">

+      <OutputDirSetup baseName="Runtime" mbdFilename="${MODULE_DIR}/Runtime.mbd" msaFilename="${MODULE_DIR}/Runtime.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Runtime_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Runtime_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Runtime*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c
new file mode 100644
index 0000000..82d464a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c
@@ -0,0 +1,88 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeHotRelocateEx.c

+

+Abstract:

+

+    Stub to resolve the IPF hook that handles IPF specific relocation types

+

+

+Revision History

+

+--*/

+

+#include "Runtime.h"

+

+EFI_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+

+  Performs an Itanium-based platform specific relocation fixup

+

+Arguments:

+

+  Reloc      - Pointer to the relocation record

+

+  Fixup      - Pointer to the address to fix up

+

+  FixupData  - Pointer to a buffer to log the fixups

+

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+

+  EFI_SUCCESS

+

+--*/

+{

+  return EFI_SUCCESS;

+

+}

+

+//

+// Cache Flush Routine.

+//

+EFI_STATUS

+FlushCpuCache (

+  IN EFI_PHYSICAL_ADDRESS          Start,

+  IN UINT64                        Length

+  )

+/*++

+

+Routine Description:

+

+  Flush cache with specified range.

+

+Arguments:

+

+  Start   - Start address

+  Length  - Length in bytes

+

+Returns:

+

+  Status code

+  

+  EFI_SUCCESS - success

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c
new file mode 100644
index 0000000..4b4581d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c
@@ -0,0 +1,156 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SecurityStub.c

+

+Abstract:

+  

+  This driver supports platform security service

+

+--*/

+

+#include "SecurityStub.h"

+

+//

+// Handle for the Security Architectural Protocol instance produced by this driver

+//

+EFI_HANDLE                  mSecurityArchProtocolHandle = NULL;

+

+//

+// Security Architectural Protocol instance produced by this driver

+//

+EFI_SECURITY_ARCH_PROTOCOL  mSecurityStub = { 

+  SecurityStubAuthenticateState 

+};

+

+//

+// Worker functions

+//

+EFI_STATUS

+EFIAPI

+SecurityStubAuthenticateState (

+  IN EFI_SECURITY_ARCH_PROTOCOL  *This,

+  IN UINT32                      AuthenticationStatus,

+  IN EFI_DEVICE_PATH_PROTOCOL    *File

+  )

+/*++

+

+Routine Description:

+

+  The EFI_SECURITY_ARCH_PROTOCOL (SAP) is used to abstract platform-specific 

+  policy from the DXE core response to an attempt to use a file that returns a 

+  given status for the authentication check from the section extraction protocol.  

+

+  The possible responses in a given SAP implementation may include locking 

+  flash upon failure to authenticate, attestation logging for all signed drivers, 

+  and other exception operations.  The File parameter allows for possible logging 

+  within the SAP of the driver.

+

+  If File is NULL, then EFI_INVALID_PARAMETER is returned.

+

+  If the file specified by File with an authentication status specified by 

+  AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.

+

+  If the file specified by File with an authentication status specified by 

+  AuthenticationStatus is not safe for the DXE Core to use under any circumstances, 

+  then EFI_ACCESS_DENIED is returned.

+

+  If the file specified by File with an authentication status specified by 

+  AuthenticationStatus is not safe for the DXE Core to use right now, but it 

+  might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is 

+  returned.

+

+Arguments:

+

+  This                 - The EFI_SECURITY_ARCH_PROTOCOL instance.

+

+  AuthenticationStatus - This is the authentication type returned from the Section 

+                         Extraction protocol.  See the Section Extraction Protocol 

+                         Specification for details on this type.

+

+  File                 - This is a pointer to the device path of the file that is 

+                         being dispatched.  This will optionally be used for logging.

+

+Returns:

+

+  EFI_SUCCESS            - The file specified by File did authenticate, and the 

+                           platform policy dictates that the DXE Core may use File.

+

+  EFI_INVALID_PARAMETER  - File is NULL.

+

+  EFI_SECURITY_VIOLATION - The file specified by File did not authenticate, and 

+                           the platform policy dictates that File should be placed 

+                           in the untrusted state.   A file may be promoted from 

+                           the untrusted to the trusted state at a future time 

+                           with a call to the Trust() DXE Service.

+

+  EFI_ACCESS_DENIED      - The file specified by File did not authenticate, and 

+                           the platform policy dictates that File should not be 

+                           used for any purpose. 

+

+--*/

+{

+  if (File == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+SecurityStubInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initialize the state information for the Security Architectural Protocol

+

+Arguments:

+

+  ImageHandle of the loaded driver

+  Pointer to the System Table

+

+Returns:

+

+  Status

+

+  EFI_SUCCESS           - successful installation of the service

+  EFI_OUT_OF_RESOURCES  - cannot allocate protocol data structure

+  EFI_DEVICE_ERROR      - cannot create the timer service

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Make sure the Security Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiSecurityArchProtocolGuid);

+

+  //

+  // Install the Security Architectural Protocol onto a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mSecurityArchProtocolHandle,

+                  &gEfiSecurityArchProtocolGuid,

+                  &mSecurityStub,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs
new file mode 100644
index 0000000..bc3b419
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SecurityStub.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h
new file mode 100644
index 0000000..420afd1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h
@@ -0,0 +1,47 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SecurityStub.h

+

+Abstract:

+

+  Some definitions for Security Architectural Protocol stub driver

+

+--*/

+

+#ifndef _SECURITY_STUB_ARCH_PROTOCOL_H

+#define _SECURITY_STUB_ARCH_PROTOCOL_H

+

+

+

+//

+// Function prototypes

+//

+EFI_STATUS

+EFIAPI

+SecurityStubAuthenticateState (

+  IN EFI_SECURITY_ARCH_PROTOCOL          *This,

+  IN UINT32                              AuthenticationStatus,

+  IN  EFI_DEVICE_PATH_PROTOCOL           *File

+  )

+;

+

+EFI_STATUS

+EFIAPI

+SecurityStubInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.mbd b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.mbd
new file mode 100644
index 0000000..2dc6fe7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.mbd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>SecurityStub</BaseName>

+    <Guid>F80697E9-7FD6-4665-8646-88E33EF71DFC</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-22 19:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa
new file mode 100644
index 0000000..91566d0
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>SecurityStub</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>F80697E9-7FD6-4665-8646-88E33EF71DFC</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for SecurityStub module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-22 19:19</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>SecurityStub.dxs</Filename>

+    <Filename>SecurityStub.h</Filename>

+    <Filename>SecurityStub.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Security</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>SecurityStubInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/build.xml b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/build.xml
new file mode 100644
index 0000000..62347a3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Security/SecurityStub/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="SecurityStub"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Security/SecurityStub/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="SecurityStub">

+      <GenBuild baseName="SecurityStub" mbdFilename="${MODULE_DIR}/SecurityStub.mbd" msaFilename="${MODULE_DIR}/SecurityStub.msa"/>

+   </target>

+   <target depends="SecurityStub_clean" name="clean"/>

+   <target depends="SecurityStub_cleanall" name="cleanall"/>

+   <target name="SecurityStub_clean">

+      <OutputDirSetup baseName="SecurityStub" mbdFilename="${MODULE_DIR}/SecurityStub.mbd" msaFilename="${MODULE_DIR}/SecurityStub.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/SecurityStub_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/SecurityStub_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="SecurityStub_cleanall">

+      <OutputDirSetup baseName="SecurityStub" mbdFilename="${MODULE_DIR}/SecurityStub.mbd" msaFilename="${MODULE_DIR}/SecurityStub.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/SecurityStub_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/SecurityStub_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**SecurityStub*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/DebugAssert.c b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/DebugAssert.c
new file mode 100644
index 0000000..75f0ed1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/DebugAssert.c
@@ -0,0 +1,231 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DebugAssert.c

+

+Abstract:

+

+  Produce EfiDebugAssertProtocol to enable EfiUtilityLib to function.

+  The EfiUtilityLib is used by the EFI shell!

+

+--*/

+

+#include "StatusCode.h"

+

+EFI_STATUS

+EFIAPI

+StatusCodeDebugAssert (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN CHAR8                              *FileName,

+  IN INTN                               LineNumber,

+  IN CHAR8                              *Description

+  );

+

+EFI_STATUS

+EFIAPI

+StatusCodeDebugPrint (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN UINTN                              ErrorLevel,

+  IN CHAR8                              *Format,

+  IN VA_LIST                            Marker

+  );

+

+EFI_STATUS

+EFIAPI

+StatusCodePostCode (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          * This,

+  IN  UINT16                            PostCode,

+  IN  CHAR8                             *PostCodeString OPTIONAL

+  );

+

+EFI_STATUS

+EFIAPI

+StatusCodeGetErrorLevel (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN  UINTN                             *ErrorLevel

+  );

+

+EFI_STATUS

+EFIAPI

+StatusCodeSetErrorLevel (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN  UINTN                             ErrorLevel

+  );

+

+//

+// Protocol instance, there can be only one.

+//

+EFI_HANDLE                mHandle = NULL;

+EFI_DEBUG_ASSERT_PROTOCOL mDebugAssertProtocol = {

+  StatusCodeDebugAssert,

+  StatusCodeDebugPrint,

+  StatusCodePostCode,

+  StatusCodeGetErrorLevel,

+  StatusCodeSetErrorLevel

+};

+

+//

+// Function implementations

+//

+EFI_STATUS

+EFIAPI

+StatusCodeDebugAssert (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN CHAR8                              *FileName,

+  IN INTN                               LineNumber,

+  IN CHAR8                              *Description

+  )

+/*++

+

+Routine Description:

+

+  Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT

+  information. If Error Logging hub is not loaded CpuBreakpoint ().

+  

+Arguments:

+

+  This        - Protocol instance.

+  FileName    - File name of failing routine.

+  LineNumber  - Line number of failing ASSERT().

+  Description - Description, usually the assertion,

+

+Returns:

+

+  EFI_SUCCESS   The function always completes successfully.

+

+--*/

+{

+  DebugAssert (FileName, LineNumber, Description);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+StatusCodeDebugPrint (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN UINTN                              ErrorLevel,

+  IN CHAR8                              *Format,

+  IN VA_LIST                            Marker

+  )

+/*++

+

+Routine Description:

+

+  Worker function for DEBUG (). If Error Logging hub is loaded log ASSERT

+  information. If Error Logging hub is not loaded do nothing.

+  

+Arguments:

+

+  This       - Protocol Instance.

+  ErrorLevel - If error level is set do the debug print.

+  Format     - String to use for the print, followed by Print arguments.

+

+Returns:

+

+  EFI_SUCCESS   The function always completes successfully.

+

+--*/

+{

+  CHAR8  Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];

+

+  AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);

+  DebugPrint (ErrorLevel, Buffer);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+StatusCodeGetErrorLevel (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN  UINTN                             *ErrorLevel

+  )

+{

+  *ErrorLevel = PcdGet32(PcdDebugPrintErrorLevel);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+StatusCodeSetErrorLevel (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          *This,

+  IN  UINTN                             ErrorLevel

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+EFIAPI

+StatusCodePostCode (

+  IN EFI_DEBUG_ASSERT_PROTOCOL          * This,

+  IN  UINT16                            PostCode,

+  IN  CHAR8                             *PostCodeString OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Write the code to IO ports 80 and 81.

+

+Arguments:

+

+  This            - Protocol Instance.

+  PostCode        - Code to write

+  PostCodeString  - String, currently ignored.

+

+Returns:

+

+  EFI_SUCCESS   The function always completes successfully.

+

+--*/

+{

+  IoWrite8 (0x80, (UINT8) (PostCode & 0xff));

+  IoWrite8 (0x81, (UINT8) (PostCode >> 8));

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InstallStatusCodeDebugAssert (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Install the status code debug assert protocol

+

+Arguments:

+

+  None

+

+Returns:

+

+  Results of call to InstallProtocolInterface.

+

+--*/

+{

+

+  DEBUG_CODE (

+    gBS->InstallProtocolInterface (

+          &mHandle,

+          &gEfiDebugAssertProtocolGuid,

+          EFI_NATIVE_INTERFACE,

+          &mDebugAssertProtocol

+          );

+  );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ia32/Ia32StatusCode.c b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ia32/Ia32StatusCode.c
new file mode 100644
index 0000000..d2e1009
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ia32/Ia32StatusCode.c
@@ -0,0 +1,75 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  Ia32StatusCode.c

+

+Abstract:

+

+  Installs the ReportStatusCode runtime service.

+

+--*/

+

+#include "StatusCode.h"

+

+//

+//

+//

+EFI_HANDLE  gStatusCodeHandle = NULL;

+

+const EFI_STATUS_CODE_PROTOCOL gStatusCodeInstance = {

+  StatusCodeReportStatusCode

+};

+

+//

+// Define the driver entry point

+//

+EFI_STATUS

+EFIAPI

+InstallStatusCode (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Install the ReportStatusCode runtime service.

+

+Arguments:

+

+  ImageHandle     Image handle of the loaded driver

+  SystemTable     Pointer to the System Table

+

+Returns:

+

+  EFI_SUCCESS     The function always returns success.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Initialize RT status code

+  //

+  InitializeStatusCode (ImageHandle, SystemTable);

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &gStatusCodeHandle,

+                  &gEfiStatusCodeRuntimeProtocolGuid,

+                  &gStatusCodeInstance,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ia32/Ia32StatusCode.dxs b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ia32/Ia32StatusCode.dxs
new file mode 100644
index 0000000..6371258
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ia32/Ia32StatusCode.dxs
@@ -0,0 +1,26 @@
+#/*++

+#

+# Copyright (c) 2006, Intel Corporation                                                         

+# All rights reserved. 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.             

+# 

+# Module Name:

+#

+#   Ia32StatusCode.dxs

+#

+# Abstract:

+#

+#   Dependency expression source file.

+#  

+#--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_DATA_HUB_PROTOCOL_GUID AND EFI_CPU_IO_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ipf/IpfStatusCode.c b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ipf/IpfStatusCode.c
new file mode 100644
index 0000000..62564c0
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ipf/IpfStatusCode.c
@@ -0,0 +1,126 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  IpfStatusCode.c

+

+Abstract:

+

+  Contains the IPF installation function and an ESAL entry.

+

+--*/

+

+#include "StatusCode.h"

+

+SAL_RETURN_REGS

+ReportStatusCodeEsalServicesClassCommonEntry (

+  IN  UINT64                    FunctionId,

+  IN  UINT64                    Arg2,

+  IN  UINT64                    Arg3,

+  IN  UINT64                    Arg4,

+  IN  UINT64                    Arg5,

+  IN  UINT64                    Arg6,

+  IN  UINT64                    Arg7,

+  IN  UINT64                    Arg8,

+  IN  SAL_EXTENDED_SAL_PROC     ExtendedSalProc,

+  IN   BOOLEAN                  VirtualMode,

+  IN  VOID                      *Global

+  )

+/*++

+

+Routine Description:

+

+  Main entry for Extended SAL ReportStatusCode Services

+

+Arguments:

+

+  FunctionId        Function Id which needed to be called

+  Arg2              Efi status code type

+  Arg3              Efi status code value

+  Arg4              Instance number 

+  Arg5              Caller Id

+  Arg6              Efi status code data

+  Arg7              Not used       

+  Arg8              Not used       

+  ExtendedSalProc   Esal Proc pointer    

+  VirtualMode       If this function is called in virtual mode

+  Global            This module's global variable pointer

+  

+Returns:

+

+  SAL_RETURN_REGS

+

+--*/

+{

+  SAL_RETURN_REGS ReturnVal;

+

+  switch (FunctionId) {

+

+  case ReportStatusCodeService:

+    ReturnVal.Status = StatusCodeReportStatusCode (

+                        (EFI_STATUS_CODE_TYPE) Arg2,

+                        (EFI_STATUS_CODE_VALUE) Arg3,

+                        (UINT32) Arg4,

+                        (EFI_GUID *) Arg5,

+                        (EFI_STATUS_CODE_DATA *) Arg6

+                        );

+    break;

+

+  default:

+    ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;

+    break;

+  }

+

+  return ReturnVal;

+}

+

+EFI_STATUS

+EFIAPI

+InstallStatusCode (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Install the ReportStatusCode runtime service.

+

+Arguments:

+

+  ImageHandle     Image handle of the loaded driver

+  SystemTable     Pointer to the System Table

+

+Returns:

+

+  EFI_SUCCESS     The function always returns success.

+

+--*/

+{

+  //

+  // Initialize RT status code

+  //

+  InitializeStatusCode (ImageHandle, SystemTable);

+

+  //

+  // Initialize ESAL capabilities

+  //

+  RegisterEsalClass (

+    &gEfiExtendedSalStatusCodeServicesProtocolGuid,

+    NULL,

+    ReportStatusCodeEsalServicesClassCommonEntry,

+    StatusCode,

+    NULL

+    );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ipf/IpfStatusCode.dxs b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ipf/IpfStatusCode.dxs
new file mode 100644
index 0000000..aaa3efe
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/Ipf/IpfStatusCode.dxs
@@ -0,0 +1,27 @@
+#/*++

+#

+# Copyright (c) 2006, Intel Corporation                                                         

+# All rights reserved. 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.             

+# 

+# Module Name:

+#

+#   IpfStatusCode.dxs

+#

+# Abstract:

+#

+#   Dependency expression source file.

+#  

+#--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_DATA_HUB_PROTOCOL_GUID AND EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.c b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.c
new file mode 100644
index 0000000..13b6426
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.c
@@ -0,0 +1,172 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StatusCode.c

+

+Abstract:

+

+  Status Code Architectural Protocol implementation as defined in Tiano

+  Architecture Specification.

+

+  This driver also depends on the DataHub, and will log all status code info 

+  to the DataHub. Fatal Errors are Printed to Standard Error (StdErr) and not 

+  logged to the data hub (If you crash what good is the data in the data hub).

+

+  This driver has limited functionality at runtime and will not log to Data Hub

+  at runtime.

+

+  Notes:

+  This driver assumes the following ReportStatusCode strategy:

+  PEI       -> uses PeiReportStatusCode

+  DXE IPL   -> uses PeiReportStatusCode

+  early DXE -> uses PeiReportStatusCode via HOB

+  DXE       -> This driver

+  RT        -> This driver

+

+--*/

+

+#include "StatusCode.h"

+

+EFI_LOCK  mStatusCodeLock;

+BOOLEAN   mStatusCodeFlag = FALSE;

+

+//

+// Function implemenations

+//

+

+

+EFI_STATUS

+EFIAPI

+StatusCodeReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId,

+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Calls into the platform library which dispatches the platform specific

+  listeners. For NT environments we still call back into PEI because the 

+  ReportStatusCode functionality requires Win32 services and is built into

+  the SecMain.exe utility.

+

+Arguments:

+

+  (See Tiano Runtime Specification)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Acquire the lock required to update mStatusCodeFlag

+  //

+  Status = EfiAcquireLockOrFail (&mStatusCodeLock);

+  if (EFI_ERROR (Status)) {

+    //

+    // Check for reentrancy of the lock

+    //

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Check to see if we are already in the middle of a ReportStatusCode()

+  //

+  if (mStatusCodeFlag) {

+    EfiReleaseLock (&mStatusCodeLock);

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Set the flag to show we are in the middle of a ReportStatusCode()

+  //

+  mStatusCodeFlag = TRUE;

+

+  //

+  // Release the lock for updating mStatusCodeFlag

+  //

+  EfiReleaseLock (&mStatusCodeLock);

+

+  //

+  // Go do the work required to report a status code

+  //

+  RtPlatformReportStatusCode (CodeType, Value, Instance, CallerId, Data);

+

+  //

+  // Acquire the lock required to update mStatusCodeFlag

+  //

+  Status = EfiAcquireLockOrFail (&mStatusCodeLock);

+  if (EFI_ERROR (Status)) {

+    //

+    // Check for reentrancy of the lock

+    //

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Clear the flag to show we are no longer in the middle of a ReportStatusCode()

+  //

+  mStatusCodeFlag = FALSE;

+

+  //

+  // Release the lock for updating mStatusCodeFlag

+  //

+  EfiReleaseLock (&mStatusCodeLock);

+

+  return EFI_SUCCESS;

+}

+//

+// Protocol instance, there can be only one.

+//

+EFI_STATUS

+InitializeStatusCode (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Install Driver to produce Report Status Code Arch Protocol

+

+Arguments:

+

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+  EFI_SUCCESS - Logging Hub protocol installed

+  Other       - No protocol installed, unload driver.

+

+--*/

+{

+

+  EfiInitializeLock (&mStatusCodeLock, EFI_TPL_HIGH_LEVEL);

+

+  //

+  // Call the platform hook to initialize the different listeners.

+  //

+  RtPlatformStatusCodeInitialize ();

+

+  //

+  // Register a protocol that EfiUtilityLib can use to implement DEBUG () and ASSERT ()

+  // Macros.

+  //

+  InstallStatusCodeDebugAssert ();

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.h b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.h
new file mode 100644
index 0000000..cb4a4d9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.h
@@ -0,0 +1,64 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StatusCode.h

+

+Abstract:

+

+  EFI DXE/RT Status Code include file.

+

+--*/

+

+#ifndef _EFI_RUNTIME_STATUS_CODE_H_

+#define _EFI_RUNTIME_STATUS_CODE_H_

+

+//

+// Function prototypes

+//

+

+EFI_STATUS

+EFIAPI

+StatusCodeReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+EFI_STATUS

+InitializeStatusCode (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+EFI_STATUS

+InstallStatusCodeDebugAssert (

+  VOID

+  )

+;

+

+//

+// Driver entry point

+//

+EFI_STATUS

+EFIAPI

+InstallStatusCode (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.mbd b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.mbd
new file mode 100644
index 0000000..f4030f4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.mbd
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MbdHeader>
+    <BaseName>StatusCode</BaseName>
+    <Guid>9F455D3B-2B8A-4c06-960B-A71B9714B9CD</Guid>
+    <Version>0</Version>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-03-12 17:09</Created>
+    <Modified>2006-03-19 15:19</Modified>
+  </MbdHeader>
+  <Libraries>
+    <Library>UefiBootServicesTableLib</Library>
+    <Library>BaseLib</Library>
+    <Library>EdkDxeRuntimeDriverLib</Library>
+    <Library>UefiDriverEntryPoint</Library>
+    <Library>UefiLib</Library>
+    <Library>BasePrintLib</Library>
+    <Library>BaseDebugLibReportStatusCode</Library>
+    <Library>DxeIoLibCpuIo</Library>
+    <Library>BaseMemoryLib</Library>
+    <Library>DxeReportStatusCodeLib</Library>
+    <Library OverrideID="1111">EdkRtPlatformStatusCodeLib</Library>
+    <Library OverrideID="1111">EdkRtMemoryStatusCodeLib</Library>
+    <Library OverrideID="1111">EdkBsDataHubStatusCodeLib</Library>
+    <Library>DxeHobLib</Library>
+    <Library>DxeMemoryAllocationLib</Library>
+    <Library>EdkMemoryStatusCodeLib</Library>
+    
+    <Arch ArchType="IPF">
+      <Library>EdkDxeSalLib</Library>
+    </Arch>
+  </Libraries>
+  <BuildOptions ToolChain="MSFT">
+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+  </BuildOptions>
+</ModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.msa b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.msa
new file mode 100644
index 0000000..4e713ea
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.msa
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>StatusCode</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>9F455D3B-2B8A-4c06-960B-A71B9714B9CD</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkRtPlatformStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugAssert.c</Filename>

+    <Filename>StatusCode.c</Filename>

+    <Filename>StatusCode.h</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/Ia32StatusCode.c</Filename>

+      <Filename>Ia32/Ia32StatusCode.dxs</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x64/x64StatusCode.c</Filename>

+      <Filename>x64/x64StatusCode.dxs</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/IpfStatusCode.c</Filename>

+      <Filename>Ipf/IpfStatusCode.dxs</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DebugAssert</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalStatusCodeServices</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InstallStatusCode</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/build.xml b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/build.xml
new file mode 100644
index 0000000..7376068
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="StatusCode"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/StatusCode/RuntimeDxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="StatusCode">

+      <GenBuild baseName="StatusCode" mbdFilename="${MODULE_DIR}/StatusCode.mbd" msaFilename="${MODULE_DIR}/StatusCode.msa"/>

+   </target>

+   <target depends="StatusCode_clean" name="clean"/>

+   <target depends="StatusCode_cleanall" name="cleanall"/>

+   <target name="StatusCode_clean">

+      <OutputDirSetup baseName="StatusCode" mbdFilename="${MODULE_DIR}/StatusCode.mbd" msaFilename="${MODULE_DIR}/StatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/StatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/StatusCode_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="StatusCode_cleanall">

+      <OutputDirSetup baseName="StatusCode" mbdFilename="${MODULE_DIR}/StatusCode.mbd" msaFilename="${MODULE_DIR}/StatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/StatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/StatusCode_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**StatusCode*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/x64/x64StatusCode.c b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/x64/x64StatusCode.c
new file mode 100644
index 0000000..4c8ad0c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/x64/x64StatusCode.c
@@ -0,0 +1,75 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  x64StatusCode.c

+

+Abstract:

+

+  Installs the ReportStatusCode runtime service.

+

+--*/

+

+#include "StatusCode.h"

+

+//

+//

+//

+EFI_HANDLE  gStatusCodeHandle = NULL;

+

+const EFI_STATUS_CODE_PROTOCOL gStatusCodeInstance = {

+  StatusCodeReportStatusCode

+};

+

+//

+// Define the driver entry point

+//

+EFI_STATUS

+EFIAPI

+InstallStatusCode (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Install the ReportStatusCode runtime service.

+

+Arguments:

+

+  ImageHandle     Image handle of the loaded driver

+  SystemTable     Pointer to the System Table

+

+Returns:

+

+  EFI_SUCCESS     The function always returns success.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Initialize RT status code

+  //

+  InitializeStatusCode (ImageHandle, SystemTable);

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &gStatusCodeHandle,

+                  &gEfiStatusCodeRuntimeProtocolGuid,

+                  &gStatusCodeInstance,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/x64/x64StatusCode.dxs b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/x64/x64StatusCode.dxs
new file mode 100644
index 0000000..74cf23e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/StatusCode/RuntimeDxe/x64/x64StatusCode.dxs
@@ -0,0 +1,27 @@
+#/*++

+#

+# Copyright (c) 2006, Intel Corporation                                                         

+# All rights reserved. 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.             

+# 

+# Module Name:

+#

+#   x64StatusCode.dxs

+#

+# Abstract:

+#

+#   Dependency expression source file.

+#  

+#--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_DATA_HUB_PROTOCOL_GUID AND EFI_CPU_IO_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c
new file mode 100644
index 0000000..52dc12e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Fonts.c
@@ -0,0 +1,263 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Fonts.c

+

+Abstract:

+

+  This file contains the Glyph/Font processing code to the HII database.

+

+--*/

+

+

+#include "HiiDatabase.h"

+

+//

+// We only need to define a wide glyph, since we will seed the narrow glyph with EFI_NARROW_GLYPH size of

+// this data structure

+//

+UINT8 mUnknownGlyph[38] = {

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xAA,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xaa,

+  0x55,

+  0xAA

+};

+

+EFI_STATUS

+EFIAPI

+HiiGetGlyph (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     CHAR16             *Source,

+  IN OUT UINT16             *Index,

+  OUT    UINT8              **GlyphBuffer,

+  OUT    UINT16             *BitWidth,

+  IN OUT UINT32             *InternalStatus

+  )

+/*++

+

+Routine Description:

+  Translates a Unicode character into the corresponding font glyph.  

+  If the Source was pointing to a non-spacing character, the next Source[*Index]

+  character will be parsed and OR'd to the GlyphBuffer until a spacing character

+  is found in the Source.  Since non-spacing characters are considered to be the

+  same pixel width as a regular character their BitWidth will be reflected correctly

+  however due to their special attribute, they are considered to be zero advancing width.

+  This basically means that the cursor would not advance, thus the character that follows

+  it would overlay the non-spacing character.  The Index is modified to reflect both the

+  incoming array entry into the Source string but also the outgoing array entry after having

+  parsed the equivalent of a single Glyph's worth of data.

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_GLOBAL_DATA *GlobalData;

+  EFI_HII_DATA        *HiiData;

+  UINTN               Count;

+  BOOLEAN             Narrow;

+  UINTN               Location;

+  UINTN               SearchLocation;

+  UINTN               Value;

+  CHAR16              Character;

+  UINTN               Attributes;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  GlobalData      = HiiData->GlobalData;

+  Count           = sizeof (GlobalData->NarrowGlyphs->GlyphCol1);

+

+  Location        = *Index;

+  SearchLocation  = *Index;

+  Narrow          = TRUE;

+

+  if (Source[Location] == NARROW_CHAR || Source[Location] == WIDE_CHAR) {

+    *InternalStatus = 0;

+  }

+  //

+  // We don't know what glyph database to look in - let's figure it out

+  //

+  if (*InternalStatus == 0) {

+    //

+    // Determine if we are looking for narrow or wide glyph data

+    //

+    do {

+      if (Source[SearchLocation] == NARROW_CHAR || Source[SearchLocation] == WIDE_CHAR) {

+        //

+        // We found something that identifies what glyph database to look in

+        //

+        if (Source[SearchLocation] == WIDE_CHAR) {

+          Narrow          = FALSE;

+          *BitWidth       = WIDE_WIDTH;

+          *InternalStatus = WIDE_CHAR;

+          Location++;

+          break;

+        } else {

+          Narrow          = TRUE;

+          *BitWidth       = NARROW_WIDTH;

+          *InternalStatus = NARROW_CHAR;

+          Location++;

+          break;

+        }

+      }

+    } while (SearchLocation-- > 0);

+  }

+

+  if (*InternalStatus == NARROW_CHAR) {

+    Narrow    = TRUE;

+    *BitWidth = NARROW_WIDTH;

+  } else if (*InternalStatus == WIDE_CHAR) {

+    Narrow    = FALSE;

+    *BitWidth = WIDE_WIDTH;

+  } else {

+    //

+    // Without otherwise knowing what the width is narrow (e.g. someone passed in a string with index of 0

+    // we wouldn't be able to determine the width of the data.)

+    // BUGBUG - do we go to wide database and if exist, ignore narrow?  Check Unicode spec....

+    //

+    Narrow    = TRUE;

+    *BitWidth = NARROW_WIDTH;

+  }

+

+  Character = Source[Location];

+

+  if (Narrow) {

+    if (GlobalData->NarrowGlyphs[Character].UnicodeWeight != 0x0000) {

+      *GlyphBuffer  = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);

+      Attributes    = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;

+    } else {

+      //

+      // Glyph is uninitialized - return an error, but hand back the glyph

+      //

+      *GlyphBuffer  = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);

+      *Index        = (UINT16) (Location + 1);

+      return EFI_NOT_FOUND;

+    }

+  } else {

+    //

+    // Wide character

+    //

+    if (GlobalData->WideGlyphs[Character].UnicodeWeight != 0x0000) {

+      *GlyphBuffer  = (UINT8 *) (&GlobalData->WideGlyphs[Character]);

+      Attributes    = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;

+    } else {

+      //

+      // Glyph is uninitialized - return an error, but hand back the glyph

+      //

+      *GlyphBuffer  = (UINT8 *) (&GlobalData->WideGlyphs[Character]);

+      *Index        = (UINT16) (Location + 1);

+      return EFI_NOT_FOUND;

+    }

+  }

+  //

+  // This is a non-spacing character.  It will be followed by either more non-spacing

+  // characters or a regular character.  We need to OR together the data associated with each.

+  //

+  for (; Attributes != 0; Location++) {

+    //

+    // Character is the Unicode value which is the index into the Glyph array.

+    //

+    Character = Source[Location];

+

+    if (Narrow) {

+      for (Value = 0; Value != Count; Value++) {

+        *GlyphBuffer[Location + Value] |= GlobalData->NarrowGlyphs[Character].GlyphCol1[Value];

+      }

+

+      Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;

+    } else {

+      for (Value = 0; Value != Count; Value++) {

+        *GlyphBuffer[Location + Value] |= GlobalData->WideGlyphs[Character].GlyphCol1[Value];

+        *GlyphBuffer[Location + Value + Count] |= GlobalData->WideGlyphs[Character].GlyphCol2[Value];

+      }

+

+      Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;

+    }

+  }

+  //

+  // Source[*Index] should point to the next character to process

+  //

+  *Index = (UINT16) (Location + 1);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiGlyphToBlt (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     UINT8              *GlyphBuffer,

+  IN     EFI_UGA_PIXEL      Foreground,

+  IN     EFI_UGA_PIXEL      Background,

+  IN     UINTN              Count,

+  IN     UINTN              Width,

+  IN     UINTN              Height,

+  IN OUT EFI_UGA_PIXEL      *BltBuffer

+  )

+{

+  UINTN X;

+  UINTN Y;

+

+  //

+  // Convert Monochrome bitmap of the Glyph to BltBuffer structure

+  //

+  for (Y = 0; Y < Height; Y++) {

+    for (X = 0; X < Width; X++) {

+      if ((((EFI_NARROW_GLYPH *) GlyphBuffer)->GlyphCol1[Y] & (1 << X)) != 0) {

+        BltBuffer[Y * Width * Count + (Width - X - 1)] = Foreground;

+      } else {

+        BltBuffer[Y * Width * Count + (Width - X - 1)] = Background;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c
new file mode 100644
index 0000000..a0a9619
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Forms.c
@@ -0,0 +1,1564 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Forms.c

+

+Abstract:

+

+  This file contains the form processing code to the HII database.

+

+--*/

+

+

+#include "HiiDatabase.h"

+

+CHAR16*

+Ascii2Unicode (

+  OUT CHAR16         *UnicodeStr,

+  IN  CHAR8          *AsciiStr

+  )

+/*++

+  

+  Routine Description:

+

+    This function converts ASCII string to Unicode string.

+  

+  Arguments:

+

+    UnicodeStr     - NULL terminated Unicode output string.

+    AsciieStr      - NULL terminated ASCII input string.

+ 

+  Returns: 

+

+    Start of the Unicode ouput string.

+    

+--*/

+

+{

+  CHAR16      *Str = UnicodeStr;  

+  while (TRUE) {

+    *(UnicodeStr++) = (CHAR16) *AsciiStr;

+    if (*(AsciiStr++) == '\0') {

+      return Str;

+    }

+  }

+}

+

+CHAR8*

+Unicode2Ascii (

+  OUT CHAR8          *AsciiStr,

+  IN  CHAR16         *UnicodeStr

+  )

+/*++

+  

+  Routine Description:

+

+    This function converts Unicode string to ASCII string.

+  

+  Arguments:

+

+    AsciieStr      - NULL terminated ASCII output string.

+    UnicodeStr     - NULL terminated Unicode input string.

+ 

+  Returns: 

+

+    Start of the ASCII ouput string.

+    

+--*/

+

+{

+  CHAR8      *Str = AsciiStr;  

+  while (TRUE) {

+    *(AsciiStr++) = (CHAR8) *UnicodeStr;

+    if (*(UnicodeStr++) == '\0') {

+      return Str;

+    }

+  }

+}

+

+VOID

+ExtractDevicePathData (

+  IN     EFI_HII_DATA_TABLE   *DataTable,

+  IN     UINT8                *IfrData,

+  IN OUT UINT8                **ExportBufferPtr

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  UINT8 *ExportBuffer;

+

+  ExportBuffer = *ExportBufferPtr;

+

+  //

+  // BUGBUG - don't have devicepath data yet, setting dummy value

+  //

+  DataTable++;

+  ExportBuffer  = (UINT8 *) DataTable;

+  ((EFI_HII_DEVICE_PATH_PACK *) ExportBuffer)->Header.Type = EFI_HII_DEVICE_PATH;

+  ((EFI_HII_DEVICE_PATH_PACK *) ExportBuffer)->Header.Length = (UINT32) (sizeof (EFI_HII_DEVICE_PATH_PACK) + sizeof (EFI_DEVICE_PATH_PROTOCOL));

+

+  //

+  // BUGBUG - part of hack - skip the Device Path Pack.....place some data

+  //

+  ExportBuffer  = ExportBuffer + sizeof (EFI_HII_DEVICE_PATH_PACK);

+

+  ((EFI_DEVICE_PATH_PROTOCOL *) ExportBuffer)->Type     = EFI_END_ENTIRE_DEVICE_PATH;

+  ((EFI_DEVICE_PATH_PROTOCOL *) ExportBuffer)->SubType  = EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;

+

+  //

+  // BUGBUG - still part of hack....

+  //

+  ExportBuffer      = ExportBuffer + sizeof (EFI_DEVICE_PATH_PROTOCOL);

+  *ExportBufferPtr  = ExportBuffer;

+}

+

+VOID

+ExtractVariableData (

+  IN OUT EFI_HII_DATA_TABLE   *DataTable,

+  IN     UINT8                *IfrData,

+  IN OUT UINT8                **ExportBufferPtr

+  )

+/*++

+

+Routine Description:

+

+  This function extract the EFI_HII_VARIABLE_PACK portion from the 

+  each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.

+  

+Arguments:

+

+  DataTable       ¨C On input, this parameter point to the EFI_HII_DATA_TABLE structure

+                    of the final data buffer for the EFI_HII_EXPORT interface. This function

+                    update the NumberOfVariableData attribute.

+  IfrData         - It points to a staring address of a EFI_HII_IFR_PACK structure.

+  ExportBufferPtr ¨C On input, it points the starting address of the data buffer to 

+                    host the variable pack. On output, it is the starting address

+                    of data buffer for the next extraction operation.

+Returns: 

+

+  VOID

+  

+--*/

+{

+  EFI_HII_VARIABLE_PACK       *VariableContents;

+  UINT8                       *ExportBuffer;

+  UINTN                       Index;

+  UINTN                       Index2;

+  UINTN                       TempValue;

+  UINTN                       TempValue2;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  EFI_PHYSICAL_ADDRESS        CallbackHandle;

+  EFI_STATUS                  Status;

+  CHAR16                      *String;

+

+  FormCallback    = NULL;

+  CallbackHandle  = 0;

+  ExportBuffer    = *ExportBufferPtr;

+

+  for (Index = 0; IfrData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    VariableContents = (EFI_HII_VARIABLE_PACK *) ExportBuffer;

+

+    switch (IfrData[Index]) {

+    case EFI_IFR_FORM_SET_OP:

+      TempValue = EFI_HII_VARIABLE;

+      CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));

+      CopyMem (&TempValue, &((EFI_IFR_FORM_SET *) &IfrData[Index])->NvDataSize, sizeof (UINT16));

+

+      //

+      // If the variable has 0 size, do not process it

+      //

+      if (TempValue == 0) {

+        break;

+      }

+      //

+      // Add the size of the variable pack overhead.  Later, will also add the size of the

+      // name of the variable.

+      //

+      TempValue = TempValue + sizeof (EFI_HII_VARIABLE_PACK);

+

+      CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));

+      CopyMem (

+        &CallbackHandle,

+        &((EFI_IFR_FORM_SET *) &IfrData[Index])->CallbackHandle,

+        sizeof (EFI_PHYSICAL_ADDRESS)

+        );

+      if (CallbackHandle != 0) {

+        Status = gBS->HandleProtocol (

+                        (EFI_HANDLE) (UINTN) CallbackHandle,

+                        &gEfiFormCallbackProtocolGuid,

+                        (VOID *) &FormCallback

+                        );

+      }

+      //

+      // Since we have a "Setup" variable that wasn't specified by a variable op-code

+      // it will have a VariableId of 0.  All other variable op-codes will have a designation

+      // of VariableId 1+

+      //

+      TempValue = 0;

+      CopyMem (&VariableContents->VariableId, &TempValue, sizeof (UINT16));

+      CopyMem (&VariableContents->VariableGuid, &((EFI_IFR_FORM_SET *) &IfrData[Index])->Guid, sizeof (EFI_GUID));

+      TempValue = sizeof (SETUP_MAP_NAME);

+      CopyMem (&VariableContents->VariableNameLength, &TempValue, sizeof (UINT32));

+

+      //

+      // Add the size of the name to the Header Length

+      //

+      TempValue2 = 0;

+      CopyMem (&TempValue2, &VariableContents->Header.Length, sizeof (UINT32));

+      TempValue2 = TempValue + TempValue2;

+      CopyMem (&VariableContents->Header.Length, &TempValue2, sizeof (UINT32));

+

+      ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);

+      CopyMem (ExportBuffer, SETUP_MAP_NAME, sizeof (SETUP_MAP_NAME));

+      ExportBuffer = ExportBuffer + sizeof (SETUP_MAP_NAME);

+

+      CopyMem (&TempValue, &((EFI_IFR_FORM_SET *) &IfrData[Index])->NvDataSize, sizeof (UINT16));

+

+      if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {

+        Status = FormCallback->NvRead (

+                                 FormCallback,

+                                 (CHAR16 *) SETUP_MAP_NAME,

+                                 (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,

+                                 NULL,

+                                 &TempValue,

+                                 ExportBuffer

+                                 );

+      } else {

+        Status = gRT->GetVariable (

+                        (CHAR16 *) SETUP_MAP_NAME,

+                        (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,

+                        NULL,

+                        &TempValue,

+                        ExportBuffer

+                        );

+      }

+

+      ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + TempValue);

+      DataTable->NumberOfVariableData++;

+      break;

+

+    case EFI_IFR_VARSTORE_OP:

+      TempValue = EFI_HII_VARIABLE;

+      CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));

+      CopyMem (&TempValue, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Size, sizeof (UINT16));

+

+      //

+      // If the variable has 0 size, do not process it

+      //

+      if (TempValue == 0) {

+        break;

+      }

+      //

+      // Add the size of the variable pack overhead.  Later, will also add the size of the

+      // name of the variable.

+      //

+      TempValue = TempValue + sizeof (EFI_HII_VARIABLE_PACK);

+

+      CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));

+      CopyMem (&VariableContents->VariableId, &((EFI_IFR_VARSTORE *) &IfrData[Index])->VarId, sizeof (UINT16));

+      CopyMem (&VariableContents->VariableGuid, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Guid, sizeof (EFI_GUID));

+      TempValue = (UINTN) ((EFI_IFR_VARSTORE *) &IfrData[Index])->Header.Length - sizeof (EFI_IFR_VARSTORE);

+      TempValue = TempValue * 2;

+      CopyMem (&VariableContents->VariableNameLength, &TempValue, sizeof (UINT32));

+

+      //

+      // Add the size of the name to the Header Length

+      //

+      TempValue2 = 0;

+      CopyMem (&TempValue2, &VariableContents->Header.Length, sizeof (UINT32));

+      TempValue2 = TempValue + TempValue2;

+      CopyMem (&VariableContents->Header.Length, &TempValue2, sizeof (UINT32));

+

+      ExportBuffer  = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);

+      String        = (CHAR16 *) ExportBuffer;

+      for (Index2 = 0; Index2 < TempValue / 2; Index2++) {

+        ExportBuffer[Index2 * 2]      = IfrData[Index + sizeof (EFI_IFR_VARSTORE) + Index2];

+        ExportBuffer[Index2 * 2 + 1]  = 0;

+      }

+

+      ExportBuffer = ExportBuffer + TempValue;

+

+      CopyMem (&TempValue, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Size, sizeof (UINT16));

+

+      if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {

+        Status = FormCallback->NvRead (

+                                 FormCallback,

+                                 String,

+                                 (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,

+                                 NULL,

+                                 &TempValue,

+                                 ExportBuffer

+                                 );

+      } else {

+        Status = gRT->GetVariable (

+                        String,

+                        (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,

+                        NULL,

+                        &TempValue,

+                        ExportBuffer

+                        );

+      }

+

+      ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + TempValue);

+      DataTable->NumberOfVariableData++;

+      break;

+    }

+

+    Index = IfrData[Index + 1] + Index;

+  }

+  //

+  // If we have added a variable pack, add a dummy empty one to signify the end

+  //

+  if (ExportBuffer != *ExportBufferPtr) {

+    VariableContents  = (EFI_HII_VARIABLE_PACK *) ExportBuffer;

+    TempValue         = EFI_HII_VARIABLE;

+    CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));

+    TempValue = sizeof (EFI_HII_VARIABLE_PACK);

+    CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));

+    ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);

+  }

+

+  *ExportBufferPtr = ExportBuffer;

+}

+

+EFI_STATUS

+EFIAPI

+HiiExportDatabase (

+  IN     EFI_HII_PROTOCOL *This,

+  IN     EFI_HII_HANDLE   Handle,

+  IN OUT UINTN            *BufferSize,

+  OUT    VOID             *Buffer

+  )

+/*++

+

+Routine Description:

+  

+  This function allows a program to extract a form or form package that has 

+  previously been registered with the EFI HII database.

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_IFR_PACK          *FormPack;

+  UINT8                     *RawData;

+  UINT8                     *ExportBuffer;

+  EFI_HII_EXPORT_TABLE      *ExportTable;

+  EFI_HII_DATA_TABLE        *DataTable;

+  BOOLEAN                   InsufficientSize;

+  BOOLEAN                   VariableExist;

+  UINT16                    NumberOfHiiDataTables;

+  UINTN                     SizeNeeded;

+  UINTN                     Index;

+  UINTN                     VariableSize;

+  UINTN                     TempValue;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData               = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase        = HiiData->DatabaseHead;

+

+  FormPack              = NULL;

+  RawData               = NULL;

+  PackageInstance       = NULL;

+  InsufficientSize      = FALSE;

+  NumberOfHiiDataTables = 0;

+  VariableSize          = 0;

+  TempValue             = 0;

+  SizeNeeded            = sizeof (EFI_HII_EXPORT_TABLE);

+

+  //

+  // How many total tables are there?

+  //

+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    if ((Handle != 0) && (Handle != HandleDatabase->Handle)) {

+      continue;

+    }

+

+    VariableExist = FALSE;

+    NumberOfHiiDataTables++;

+    PackageInstance = HandleDatabase->Buffer;

+    if (PackageInstance == NULL) {

+      continue;

+    }

+    //

+    // Extract Size of Export Package

+    //

+    SizeNeeded = SizeNeeded + PackageInstance->IfrSize 

+                            + PackageInstance->StringSize

+                            + sizeof (EFI_HII_DATA_TABLE)

+                            + sizeof (EFI_HII_DEVICE_PATH_PACK);

+

+    //

+    // BUGBUG We aren't inserting Device path data yet

+    //

+    SizeNeeded = SizeNeeded + sizeof (EFI_DEVICE_PATH_PROTOCOL);

+

+    //

+    // Extract Size of Variable Data

+    //

+    if (PackageInstance->IfrSize > 0) {

+      FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+    } else {

+      //

+      // No IFR? No variable information

+      //

+      continue;

+    }

+

+    RawData = (UINT8 *) FormPack;

+

+    for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+      switch (RawData[Index]) {

+      case EFI_IFR_FORM_SET_OP:

+        CopyMem (&VariableSize, &((EFI_IFR_FORM_SET *) &RawData[Index])->NvDataSize, sizeof (UINT16));

+        SizeNeeded    = SizeNeeded + VariableSize + sizeof (SETUP_MAP_NAME) + sizeof (EFI_HII_VARIABLE_PACK);

+        VariableExist = TRUE;

+        break;

+

+      case EFI_IFR_VARSTORE_OP:

+        CopyMem (&VariableSize, &((EFI_IFR_VARSTORE *) &RawData[Index])->Size, sizeof (UINT16));

+        SizeNeeded = SizeNeeded + VariableSize + sizeof (EFI_HII_VARIABLE_PACK);

+        //

+        // We will be expanding the stored ASCII name to a Unicode string.  This will cause some memory overhead

+        // Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another

+        // instance of it.  Essentially, 2 ASCII strings == 1 Unicode string in size.

+        //

+        TempValue     = (UINTN) ((EFI_IFR_VARSTORE *) &RawData[Index])->Header.Length - sizeof (EFI_IFR_VARSTORE);

+        SizeNeeded    = SizeNeeded + TempValue * 2;

+        VariableExist = TRUE;

+        break;

+      }

+

+      Index = RawData[Index + 1] + Index;

+    }

+    //

+    // If a variable exists for this handle, add an additional variable pack overhead to

+    // indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs

+    //

+    if (VariableExist) {

+      SizeNeeded = SizeNeeded + sizeof (EFI_HII_VARIABLE_PACK);

+    }

+  }

+

+  if (SizeNeeded > *BufferSize) {

+    *BufferSize = SizeNeeded;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // Zero out the incoming buffer

+  //

+  ZeroMem (Buffer, *BufferSize);

+

+  //

+  // Cast the Buffer to EFI_HII_EXPORT_TABLE

+  //

+  ExportTable = (EFI_HII_EXPORT_TABLE *) Buffer;

+

+  //

+  // Set the Revision for the Export Table

+  //

+  CopyMem (&ExportTable->Revision, &gEfiHiiProtocolGuid, sizeof (EFI_GUID));

+

+  ExportBuffer    = (UINT8 *) (UINTN) (((UINT8 *) ExportTable) + sizeof (EFI_HII_EXPORT_TABLE));

+  HandleDatabase  = HiiData->DatabaseHead;

+

+  //

+  // Check numeric value against the head of the database

+  //

+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    DataTable       = (EFI_HII_DATA_TABLE *) ExportBuffer;

+    PackageInstance = HandleDatabase->Buffer;

+    //

+    // If not asking for a specific handle, export the entire database

+    //

+    if (Handle == 0) {

+      ExportTable->NumberOfHiiDataTables = NumberOfHiiDataTables;

+      CopyMem (&DataTable->PackageGuid, &PackageInstance->Guid, sizeof (EFI_GUID));

+      DataTable->HiiHandle        = PackageInstance->Handle;

+      DataTable->DevicePathOffset = (UINT32) (sizeof (EFI_HII_DATA_TABLE));

+

+      //

+      // Start Dumping DevicePath

+      //

+      ExtractDevicePathData (DataTable, RawData, &ExportBuffer);

+

+      if (((UINTN) ExportBuffer) == ((UINTN) DataTable)) {

+        //

+        // If there is no DevicePath information - set offset to 0 to signify the absence of data to parse

+        //

+        DataTable->DevicePathOffset = 0;

+      }

+

+      DataTable->VariableDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+      if (PackageInstance->IfrSize > 0) {

+        FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+

+        RawData   = (UINT8 *) FormPack;

+        TempValue = 0;

+

+        //

+        // Start dumping the Variable Data

+        //

+        ExtractVariableData (DataTable, RawData, &ExportBuffer);

+        DataTable->IfrDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+        if (DataTable->VariableDataOffset == DataTable->IfrDataOffset) {

+          DataTable->VariableDataOffset = 0;

+        }

+        //

+        // Start dumping the IFR data (Note:  It is in an IFR PACK)

+        //

+        CopyMem (ExportBuffer, &PackageInstance->IfrData, PackageInstance->IfrSize);

+        ExportBuffer                = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + PackageInstance->IfrSize);

+        DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+        //

+        // Start dumping the String data (Note:  It is in a String PACK)

+        //

+        if (PackageInstance->StringSize > 0) {

+          RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);

+          CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);

+          DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);

+

+          CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+          for (; TempValue != 0;) {

+            DataTable->NumberOfLanguages++;

+            ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;

+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+          }

+

+          ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);

+        } else {

+          DataTable->StringDataOffset = 0;

+        }

+      } else {

+        //

+        // No IFR? No variable information.  If Offset is 0, means there is none.  (Hmm - this might be prunable - no strings to export if no IFR - we always have a stub)

+        //

+        DataTable->VariableDataOffset = 0;

+        DataTable->IfrDataOffset      = 0;

+        DataTable->StringDataOffset   = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+        //

+        // Start dumping the String data - NOTE:  It is in String Pack form

+        //

+        if (PackageInstance->StringSize > 0) {

+          RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);

+          CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);

+          DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);

+

+          CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+          for (; TempValue != 0;) {

+            DataTable->NumberOfLanguages++;

+            ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;

+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+          }

+

+          ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);

+        } else {

+          DataTable->StringDataOffset = 0;

+        }

+      }

+    } else {

+      //

+      // Match the numeric value with the database entry - if matched, extract PackageInstance

+      //

+      if (Handle == HandleDatabase->Handle) {

+        PackageInstance                     = HandleDatabase->Buffer;

+        ExportTable->NumberOfHiiDataTables  = NumberOfHiiDataTables;

+        DataTable->HiiHandle                = PackageInstance->Handle;

+        CopyMem (&DataTable->PackageGuid, &PackageInstance->Guid, sizeof (EFI_GUID));

+

+        //

+        // Start Dumping DevicePath

+        //

+        ExtractDevicePathData (DataTable, RawData, &ExportBuffer);

+        DataTable->VariableDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+        if (PackageInstance->IfrSize > 0) {

+          FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+

+          RawData   = (UINT8 *) FormPack;

+          TempValue = 0;

+

+          //

+          // Start dumping the Variable Data

+          //

+          ExtractVariableData (DataTable, RawData, &ExportBuffer);

+          DataTable->IfrDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+          if (DataTable->VariableDataOffset == DataTable->IfrDataOffset) {

+            DataTable->VariableDataOffset = 0;

+          }

+          //

+          // Start dumping the IFR data

+          //

+          CopyMem (ExportBuffer, &PackageInstance->IfrData, PackageInstance->IfrSize);

+          ExportBuffer                = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + PackageInstance->IfrSize);

+          DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+          //

+          // Start dumping the String data - NOTE:  It is in String Pack form

+          //

+          if (PackageInstance->StringSize > 0) {

+            RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);

+            CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);

+            DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);

+

+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+            for (; TempValue != 0;) {

+              DataTable->NumberOfLanguages++;

+              ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;

+              CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+            }

+

+            ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);

+          } else {

+            DataTable->StringDataOffset = 0;

+          }

+        } else {

+          //

+          // No IFR? No variable information.  If Offset is 0, means there is none.

+          //

+          DataTable->VariableDataOffset = 0;

+          DataTable->IfrDataOffset      = 0;

+          DataTable->StringDataOffset   = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));

+

+          //

+          // Start dumping the String data - Note:  It is in String Pack form

+          //

+          if (PackageInstance->StringSize > 0) {

+            RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);

+            CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);

+            DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);

+

+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+            for (; TempValue != 0;) {

+              DataTable->NumberOfLanguages++;

+              ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;

+              CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));

+            }

+

+            ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);

+          } else {

+            DataTable->StringDataOffset = 0;

+          }

+        }

+        break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiGetForms (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     EFI_HII_HANDLE     Handle,

+  IN     EFI_FORM_ID        FormId,

+  IN OUT UINTN              *BufferLengthTemp,

+  OUT    UINT8              *Buffer

+  )

+/*++

+

+Routine Description:

+  

+  This function allows a program to extract a form or form package that has 

+  previously been registered with the EFI HII database.

+

+Arguments:

+  This         - A pointer to the EFI_HII_PROTOCOL instance.

+  

+  Handle       - Handle on which the form resides. Type EFI_HII_HANDLE is defined in 

+                 EFI_HII_PROTOCOL.NewPack() in the Packages section.

+            

+  FormId       - The ID of the form to return. If the ID is zero, the entire form package is returned.

+                 Type EFI_FORM_ID is defined in "Related Definitions" below.

+            

+  BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if

+                 the length was sufficient and, if it was not, the length that is required to fit the

+                 requested form(s).

+                  

+  Buffer       - The buffer designed to receive the form(s).

+

+Returns: 

+

+  EFI_SUCCESS           -  Buffer filled with the requested forms. BufferLength

+                           was updated.

+                           

+  EFI_INVALID_PARAMETER -  The handle is unknown.

+  

+  EFI_NOT_FOUND         -  A form on the requested handle cannot be found with the

+                           requested FormId.

+                           

+  EFI_BUFFER_TOO_SMALL  - The buffer provided was not large enough to allow the form to be stored.

+

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_IFR_PACK          *FormPack;

+  EFI_IFR_FORM              *Form;

+  EFI_IFR_OP_HEADER         *Location;

+  UINT16                    *BufferLength = (UINT16 *) BufferLengthTemp;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase  = HiiData->DatabaseHead;

+

+  PackageInstance = NULL;

+

+  //

+  // Check numeric value against the head of the database

+  //

+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    //

+    // Match the numeric value with the database entry - if matched, extract PackageInstance

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+      break;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (PackageInstance->IfrSize > 0) {

+    FormPack = (EFI_HII_IFR_PACK *) (&PackageInstance->IfrData);

+  } else {

+    //

+    // If there is no IFR data return an error

+    //

+    return EFI_NOT_FOUND;

+  }

+  //

+  // If requesting the entire Form Package

+  //

+  if (FormId == 0) {

+    //

+    // Return an error if buffer is too small

+    //

+    if (PackageInstance->IfrSize > *BufferLength || Buffer == NULL) {

+      *BufferLength = (UINT16) PackageInstance->IfrSize;

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    CopyMem (Buffer, FormPack, PackageInstance->IfrSize);

+    return EFI_SUCCESS;

+  } else {

+    FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+    Location  = (EFI_IFR_OP_HEADER *) FormPack;

+

+    //

+    // Look for the FormId requested

+    //

+    for (; Location->OpCode != EFI_IFR_END_FORM_SET_OP;) {

+      switch (Location->OpCode) {

+      case EFI_IFR_FORM_OP:

+        Form = (EFI_IFR_FORM *) Location;

+

+        //

+        // If we found a Form Op-code and it is of the correct Id, copy it and return

+        //

+        if (Form->FormId == FormId) {

+          if (Location->Length > *BufferLength || Buffer == NULL) {

+            *BufferLength = Location->Length;

+            return EFI_BUFFER_TOO_SMALL;

+          } else {

+            for (; Location->OpCode != EFI_IFR_END_FORM_OP;) {

+              CopyMem (Buffer, Location, Location->Length);

+              Buffer    = Buffer + Location->Length;

+              Location  = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+            }

+

+            CopyMem (Buffer, Location, Location->Length);

+            return EFI_SUCCESS;

+          }

+        }

+

+      default:

+        break;

+      }

+      //

+      // Go to the next Op-Code

+      //

+      Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// Helper functions to HiiGetDefaultImage()

+//

+

+STATIC

+UINT8*

+HiiGetDefaultImageInitPack (

+  IN OUT EFI_HII_VARIABLE_PACK_LIST  *VariablePackItem,

+  IN     EFI_IFR_VARSTORE            *VarStore

+  )

+/*++

+    

+  Routine Description:

+

+    Initialize the EFI_HII_VARIABLE_PACK_LIST structure and

+    prepare it ready to be used by HiiGetDefaultImagePopulateMap ().

+      

+  Arguments:

+

+    VariablePackItem     - Variable Package List.

+    VarStore             - IFR variable storage.

+   

+  Returns: 

+

+    Return the pointer to the Map space.

+      

+--*/

+{

+  CHAR16                *Name16;

+  CHAR8                 *Name8;

+  CHAR8                 *Map;

+  EFI_HII_VARIABLE_PACK *VariablePack;

+

+  //

+  // Set pointer the pack right after the node

+  //

+  VariablePackItem->VariablePack = (EFI_HII_VARIABLE_PACK *) (VariablePackItem + 1);

+  VariablePack                   = VariablePackItem->VariablePack;

+

+  //

+  // Copy the var name to VariablePackItem from VarStore

+  // Needs ASCII->Unicode conversion.

+  //

+  ASSERT (VarStore->Header.Length > sizeof (*VarStore));

+  Name8  = (CHAR8 *) (VarStore + 1);

+  Name16 = (CHAR16 *) (VariablePack + 1);

+  Ascii2Unicode (Name16, Name8);

+

+  //

+  // Compute the other fields of the VariablePackItem

+  //

+  VariablePack->VariableId         = VarStore->VarId;

+  CopyMem (&VariablePack->VariableGuid, &VarStore->Guid, sizeof (EFI_GUID));

+  VariablePack->VariableNameLength = (UINT32) ((StrLen (Name16) + 1) * 2);

+  VariablePack->Header.Length      = sizeof (*VariablePack) 

+                                              + VariablePack->VariableNameLength

+                                              + VarStore->Size;

+  //

+  // Return the pointer to the Map space.

+  //

+  Map = (CHAR8 *) Name16 + VariablePack->VariableNameLength;

+

+  return (UINT8 *)Map;

+}

+

+STATIC

+VOID

+HiiGetDefaultImagePopulateMap (

+  IN OUT UINT8                        *Map,  

+  IN     EFI_IFR_OP_HEADER            *FormSet,

+  IN     EFI_IFR_VARSTORE             *VarStore,

+  IN     UINTN                        DefaultMask

+  )

+/*++

+    

+  Routine Description:

+

+   Fill the Map with all the default values either from NV or Hii database.

+      

+  Arguments:

+

+   Map         - Memory pointer to hold the default values.

+   FormSet     - The starting EFI_IFR_OP_HEADER to begin retriving default values.

+   VarStore    - IFR variable storage.

+   DefaultMask - The mask used to get the default variable.

+   

+  Returns: 

+

+   VOID

+      

+--*/

+{

+  EFI_STATUS                     Status;

+  EFI_IFR_OP_HEADER              *IfrItem;

+  UINT16                         VarId;

+  EFI_IFR_VARSTORE_SELECT        *VarSelect;

+  EFI_IFR_ONE_OF_OPTION          *OneOfOpt;

+  EFI_IFR_CHECKBOX               *CheckBox;

+  EFI_IFR_NUMERIC                *Numeric;

+  UINTN                          Size;

+  UINTN                          SizeTmp;

+  EFI_IFR_NV_DATA                *IfrNvData;

+  EFI_GUID                       Guid;

+  CHAR16                         *Name16;

+  CHAR8                          *Name8;  

+  EFI_HANDLE                      CallbackHandle;

+  EFI_FORM_CALLBACK_PROTOCOL     *FormCallbackProt;

+

+  //

+  // Get the Map's Name/Guid/Szie from the Varstore.

+  // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.

+  //

+  ASSERT (VarStore->Header.Length >= sizeof (*VarStore));

+  Name8  = (CHAR8 *) (VarStore + 1);

+  Name16 = AllocateZeroPool ((VarStore->Header.Length - sizeof (*VarStore)) * sizeof (CHAR16));

+  Ascii2Unicode (Name16, Name8);

+  CopyMem (&Guid, &VarStore->Guid, sizeof(EFI_GUID));

+  Size = VarStore->Size;

+

+  //

+  // First, check if the map exists in the NV. If so, get it from NV and exit.

+  //

+  if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {

+    //

+    // Check if Manufaturing Defaults exist in the NV.

+    //

+    Status = EfiLibHiiVariableOverrideBySuffix (

+                  HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE,

+                  Name16,

+                  &Guid,

+                  Size,

+                  Map

+                  );

+  } else {

+    //

+    // All other cases default to Defaults. Check if Defaults exist in the NV.

+    //

+    Status = EfiLibHiiVariableOverrideBySuffix (

+                  HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE,

+                  Name16,

+                  &Guid,

+                  Size,

+                  Map

+                  );

+  }

+  if (!EFI_ERROR (Status)) {

+    //

+    // Either Defaults/Manufacturing variable exists and appears to be valid. 

+    // The map is read, exit w/ success now.

+    //

+    gBS->FreePool (Name16);

+    return;

+  }

+

+  //

+  // First, prime the map with what already is in the NV.

+  // This is needed to cover a situation where the IFR does not contain all the 

+  // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.

+  // Ignore status. Either it gets read or not. 

+  //  

+  FormCallbackProt = NULL;

+  CopyMem (&CallbackHandle, &((EFI_IFR_FORM_SET*) FormSet)->CallbackHandle, sizeof (CallbackHandle));

+  if (CallbackHandle != NULL) {

+    Status = gBS->HandleProtocol (

+                    (EFI_HANDLE) (UINTN) CallbackHandle,

+                    &gEfiFormCallbackProtocolGuid,

+                    (VOID *) &FormCallbackProt

+                    );

+  }

+  if ((NULL != FormCallbackProt) && (NULL != FormCallbackProt->NvRead)) {

+    //

+    // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.

+    //

+    SizeTmp = 0;

+    Status = FormCallbackProt->NvRead (

+                    FormCallbackProt,

+                    Name16,

+                    &Guid,

+                    0,

+                    &SizeTmp,

+                    NULL

+                    );

+    if ((EFI_BUFFER_TOO_SMALL == Status) && (SizeTmp == Size)) {

+      Status = FormCallbackProt->NvRead (

+                      FormCallbackProt,

+                      Name16,

+                      &Guid,

+                      0,

+                      &SizeTmp,

+                      Map

+                      );

+      ASSERT_EFI_ERROR (Status);

+      ASSERT (SizeTmp == Size);

+    }

+  } else {

+    //

+    // No callback available for this formset, read straight from NV. Deliberately ignore the Status. 

+    // The buffer will only be written if variable exists nd has correct size.

+    //

+    Status = EfiLibHiiVariableRetrieveFromNv (

+                    Name16,

+                    &Guid,

+                    Size,

+                    (VOID **) &Map

+                    );

+  }

+

+  //

+  // Iterate all IFR statements and for applicable, retrieve the default into the Map.

+  //

+  for (IfrItem = FormSet, VarId = 0; 

+       IfrItem->OpCode != EFI_IFR_END_FORM_SET_OP; 

+       IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8*) IfrItem + IfrItem->Length)

+      ) {

+

+    //

+    // Observe VarStore switch.

+    //

+    if (EFI_IFR_VARSTORE_SELECT_OP == IfrItem->OpCode) {

+      VarSelect = (EFI_IFR_VARSTORE_SELECT *) IfrItem;

+      VarId = VarSelect->VarId;

+      continue;

+    }

+

+

+    //

+    // Skip opcodes that reference other VarStore than that specific to current map.

+    // 

+    if (VarId != VarStore->VarId) {

+      continue;

+    }

+    

+    //

+    // Extract the default value from this opcode if applicable, and apply it to the map.

+    //

+    IfrNvData = (EFI_IFR_NV_DATA *) IfrItem;

+    switch (IfrItem->OpCode) {

+

+      case EFI_IFR_ONE_OF_OP:

+        ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);

+        //

+        // Get to the first EFI_IFR_ONE_OF_OPTION_OP

+        //

+        IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8*) IfrItem + IfrItem->Length); 

+        ASSERT (EFI_IFR_ONE_OF_OPTION_OP == IfrItem->OpCode);

+

+        OneOfOpt = (EFI_IFR_ONE_OF_OPTION *)IfrItem;

+        //

+        // In the worst case, the first will be the default.

+        //

+        CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);

+

+        while (EFI_IFR_ONE_OF_OPTION_OP == IfrItem->OpCode) {

+

+          OneOfOpt = (EFI_IFR_ONE_OF_OPTION *)IfrItem;

+            if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {

+              if (0 != (OneOfOpt->Flags & EFI_IFR_FLAG_MANUFACTURING)) {

+                //

+                // In the worst case, the first will be the default.

+                //

+                CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);

+                break;

+              }

+            } else {

+              if (OneOfOpt->Flags & EFI_IFR_FLAG_DEFAULT) {

+                //

+                // In the worst case, the first will be the default.

+                //

+                CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);

+                break;

+              }

+            }

+

+          IfrItem = (EFI_IFR_OP_HEADER *)((UINT8*)IfrItem + IfrItem->Length);

+        }

+        continue;

+        break;

+

+      case EFI_IFR_CHECKBOX_OP:

+        ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);

+        CheckBox = (EFI_IFR_CHECK_BOX *)IfrItem;        

+        if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {

+          if (0 != (CheckBox->Flags & EFI_IFR_FLAG_MANUFACTURING)) {

+            *(UINT8 *) (Map + IfrNvData->QuestionId) = TRUE;

+          }

+        } else {

+          if (CheckBox->Flags & EFI_IFR_FLAG_DEFAULT) {

+            *(UINT8 *) (Map + IfrNvData->QuestionId) = TRUE;

+          }

+        }

+        break;

+

+      case EFI_IFR_NUMERIC_OP:

+        ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);

+        Numeric = (EFI_IFR_NUMERIC *) IfrItem;

+        CopyMem (Map + IfrNvData->QuestionId, &Numeric->Default, IfrNvData->StorageWidth);

+        break;

+

+      case EFI_IFR_ORDERED_LIST_OP:

+      case EFI_IFR_PASSWORD_OP:

+      case EFI_IFR_STRING_OP:

+        //

+        // No support for default value for these opcodes.

+        //

+      break;

+    }

+  }

+

+  gBS->FreePool (Name16);

+

+}

+

+

+EFI_STATUS

+EFIAPI

+HiiGetDefaultImage (

+  IN     EFI_HII_PROTOCOL            *This,

+  IN     EFI_HII_HANDLE              Handle,

+  IN     UINTN                       DefaultMask,

+  OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList

+  )

+/*++

+    

+  Routine Description:

+

+  This function allows a program to extract the NV Image 

+  that represents the default storage image

+      

+  Arguments:

+    This             - A pointer to the EFI_HII_PROTOCOL instance.

+    Handle           - The HII handle from which will have default data retrieved.

+    UINTN            - Mask used to retrieve the default image.

+    VariablePackList - Callee allocated, tightly-packed, link list data 

+                         structure that contain all default varaible packs

+                         from the Hii Database.

+    

+  Returns: 

+    EFI_NOT_FOUND         - If Hii database does not contain any default images.

+    EFI_INVALID_PARAMETER - Invalid input parameter.

+    EFI_SUCCESS           - Operation successful.

+      

+--*/

+{

+  EFI_HII_HANDLE_DATABASE        *HandleDatabase;

+  EFI_HII_PACKAGE_INSTANCE       *PackageInstance;

+  EFI_IFR_OP_HEADER              *FormSet;

+  EFI_IFR_OP_HEADER              *IfrItem;

+  EFI_IFR_VARSTORE               *VarStore;

+  EFI_IFR_VARSTORE               *VarStoreDefault;

+  UINTN                          SetupMapNameSize;

+  UINTN                          SizeOfMaps;

+  EFI_HII_VARIABLE_PACK_LIST     *PackList;

+  EFI_HII_VARIABLE_PACK_LIST     *PackListNext;  

+  EFI_HII_VARIABLE_PACK_LIST     *PackListLast;

+  UINT8                          *Map;

+

+

+  //

+  // Find the IFR pack from the handle. Then get the formset from the pack.

+  //

+  PackageInstance = NULL;

+  HandleDatabase  = (EFI_HII_DATA_FROM_THIS (This))->DatabaseHead;

+  for ( ; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+      break;

+    }

+  }

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  FormSet = (EFI_IFR_OP_HEADER *) ((UINT8 *) &PackageInstance->IfrData + sizeof (EFI_HII_IFR_PACK));

+

+  //

+  // Get the sizes of all the VARSTOREs in this VFR.

+  // Then allocate enough space for all of them plus all maps

+  //

+  SizeOfMaps = 0;

+  IfrItem    = FormSet;

+  while (EFI_IFR_END_FORM_SET_OP != IfrItem->OpCode) {

+

+    if (EFI_IFR_VARSTORE_OP == IfrItem->OpCode) {

+      VarStore = (EFI_IFR_VARSTORE *) IfrItem;

+      //

+      // Size of the map

+      //

+      SizeOfMaps += VarStore->Size; 

+      //

+      // add the size of the string, in Unicode

+      //

+      SizeOfMaps += (VarStore->Header.Length - sizeof (*VarStore)) * 2; 

+      //

+      // Space for node

+      //

+      SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK);      

+      //

+      // Space for linked list node 

+      //

+      SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK_LIST); 

+    }

+

+    IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrItem + IfrItem->Length);

+  }

+

+  //

+  // If the FormSet OpCode has a non-zero NvDataSize. There is a default 

+  // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.

+  //

+  SetupMapNameSize = StrLen (SETUP_MAP_NAME) + 1;

+  VarStoreDefault  = AllocateZeroPool (sizeof (*VarStoreDefault) + SetupMapNameSize);

+

+  if (0 != ((EFI_IFR_FORM_SET*)FormSet)->NvDataSize) {

+

+    VarStoreDefault->Header.OpCode = EFI_IFR_VARSTORE_OP;

+    VarStoreDefault->Header.Length = (UINT8) (sizeof (*VarStoreDefault) + SetupMapNameSize);

+    Unicode2Ascii ((CHAR8 *) (VarStoreDefault + 1), SETUP_MAP_NAME);

+    CopyMem (&VarStoreDefault->Guid, &((EFI_IFR_FORM_SET*) FormSet)->Guid, sizeof (EFI_GUID));

+    VarStoreDefault->VarId = 0;

+    VarStoreDefault->Size = ((EFI_IFR_FORM_SET*) FormSet)->NvDataSize;

+

+    //

+    // Size of the map

+    //

+    SizeOfMaps += VarStoreDefault->Size; 

+    //

+    // add the size of the string

+    //

+    SizeOfMaps += sizeof (SETUP_MAP_NAME); 

+    //

+    // Space for node

+    //

+    SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK);      

+    //

+    // Space for linked list node 

+    //

+    SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK_LIST); 

+  }

+

+  if (0 == SizeOfMaps) {

+    //

+    // The IFR does not have any explicit or default map(s).

+    //

+    return EFI_NOT_FOUND; 

+  }

+

+  //

+  // Allocate the return buffer

+  //

+  PackList = AllocateZeroPool (SizeOfMaps);

+  ASSERT (NULL != PackList); 

+

+  PackListNext = PackList;

+  PackListLast = PackList;

+

+  //

+  // Handle the default map first, if any.

+  //

+  if (0 != VarStoreDefault->Size) {

+

+    Map = HiiGetDefaultImageInitPack (PackListNext, VarStoreDefault);

+

+    HiiGetDefaultImagePopulateMap (Map, FormSet, VarStoreDefault, DefaultMask);

+

+    PackListNext->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *) ((UINT8 *) PackListNext->VariablePack + PackListNext->VariablePack->Header.Length);

+    PackListLast = PackListNext;

+    PackListNext = PackListNext->NextVariablePack;

+  }

+

+

+  //

+  // Handle the explicit varstore(s)

+  //

+  IfrItem = FormSet;

+  while (EFI_IFR_END_FORM_SET_OP != IfrItem->OpCode) {

+

+    if (EFI_IFR_VARSTORE_OP == IfrItem->OpCode) {

+

+      Map = HiiGetDefaultImageInitPack (PackListNext, (EFI_IFR_VARSTORE *) IfrItem);

+

+      HiiGetDefaultImagePopulateMap (Map, FormSet, (EFI_IFR_VARSTORE *) IfrItem, DefaultMask);

+

+      PackListNext->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *) ((UINT8 *) PackListNext->VariablePack + PackListNext->VariablePack->Header.Length);

+      PackListLast = PackListNext;

+      PackListNext = PackListNext->NextVariablePack;

+    }

+

+    IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrItem + IfrItem->Length);

+  }

+

+  PackListLast->NextVariablePack = NULL;

+  *VariablePackList = PackList;

+  

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+HiiUpdateForm (

+  IN EFI_HII_PROTOCOL       *This,

+  IN EFI_HII_HANDLE         Handle,

+  IN EFI_FORM_LABEL         Label,

+  IN BOOLEAN                AddData,

+  IN EFI_HII_UPDATE_DATA    *Data

+  )

+/*++

+

+Routine Description:

+  This function allows the caller to update a form that has 

+  previously been registered with the EFI HII database.

+

+Arguments:

+  Handle     - Hii Handle associated with the Formset to modify

+  Label      - Update information starting immediately after this label in the IFR

+  AddData    - If TRUE, add data.  If FALSE, remove data

+  Data       - If adding data, this is the pointer to the data to add

+

+Returns: 

+  EFI_SUCCESS - Update success.

+  Other       - Update fail.

+

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_IFR_PACK          *FormPack;

+  EFI_IFR_OP_HEADER         *Location;

+  EFI_IFR_OP_HEADER         *DataLocation;

+  UINT8                     *OtherBuffer;

+  UINT8                     *TempBuffer;

+  UINT8                     *OrigTempBuffer;

+  UINTN                     TempBufferSize;

+  UINTN                     Index;

+

+  OtherBuffer = NULL;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase  = HiiData->DatabaseHead;

+

+  PackageInstance = NULL;

+

+  //

+  // Check numeric value against the head of the database

+  //

+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    //

+    // Match the numeric value with the database entry - if matched, extract PackageInstance

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+      break;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Calculate and allocate space for retrieval of IFR data

+  //

+  DataLocation    = (EFI_IFR_OP_HEADER *) &Data->Data;

+  TempBufferSize  = (CHAR8 *) (&PackageInstance->IfrData) - (CHAR8 *) (PackageInstance);

+

+  for (Index = 0; Index < Data->DataCount; Index++) {

+    TempBufferSize += DataLocation->Length;

+    DataLocation = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (DataLocation) + DataLocation->Length);

+  }

+

+  TempBufferSize += PackageInstance->IfrSize + PackageInstance->StringSize;

+

+  TempBuffer      = AllocateZeroPool (TempBufferSize);

+  OrigTempBuffer  = TempBuffer;

+

+  //

+  // We update only packages with IFR information in it

+  //

+  if (PackageInstance->IfrSize == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CopyMem (

+    TempBuffer,

+    PackageInstance,

+    ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER) - (CHAR8 *) (PackageInstance))

+    );

+

+  TempBuffer = TempBuffer + ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER) - (CHAR8 *) (PackageInstance));

+

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+  Location  = (EFI_IFR_OP_HEADER *) FormPack;

+

+  //

+  // Look for the FormId requested

+  //

+  for (; Location->OpCode != EFI_IFR_END_FORM_SET_OP;) {

+    switch (Location->OpCode) {

+    case EFI_IFR_FORM_SET_OP:

+      //

+      // If the FormSet has an update pending, pay attention.

+      //

+      if (Data->FormSetUpdate) {

+        ((EFI_IFR_FORM_SET *) Location)->CallbackHandle = Data->FormCallbackHandle;

+      }

+

+      CopyMem (TempBuffer, Location, Location->Length);

+      TempBuffer = TempBuffer + Location->Length;

+      break;

+

+    case EFI_IFR_FORM_OP:

+      //

+      // If the Form has an update pending, pay attention.

+      //

+      if (Data->FormUpdate) {

+        ((EFI_IFR_FORM *) Location)->FormTitle = Data->FormTitle;

+      }

+

+      CopyMem (TempBuffer, Location, Location->Length);

+      TempBuffer = TempBuffer + Location->Length;

+      break;

+

+    case EFI_IFR_LABEL_OP:

+      //

+      // If the label does not match the requested update point, ignore it

+      //

+      if (((EFI_IFR_LABEL *) Location)->LabelId != Label) {

+        //

+        // Copy the label

+        //

+        CopyMem (TempBuffer, Location, Location->Length);

+        TempBuffer = TempBuffer + Location->Length;

+

+        //

+        // Go to the next Op-Code

+        //

+        Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+        continue;

+      }

+

+      if (AddData) {

+        //

+        // Copy the label

+        //

+        CopyMem (TempBuffer, Location, Location->Length);

+        TempBuffer = TempBuffer + Location->Length;

+

+        //

+        // Add the DataCount amount of opcodes to TempBuffer

+        //

+        DataLocation = (EFI_IFR_OP_HEADER *) &Data->Data;

+        for (Index = 0; Index < Data->DataCount; Index++) {

+          CopyMem (TempBuffer, DataLocation, DataLocation->Length);

+          ((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize += DataLocation->Length;

+          OtherBuffer = ((UINT8 *) &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->StringSize + sizeof (UINTN));

+          CopyMem (OtherBuffer, &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize, 2);

+          TempBuffer    = TempBuffer + DataLocation->Length;

+          DataLocation  = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (DataLocation) + DataLocation->Length);

+        }

+        //

+        // Go to the next Op-Code

+        //

+        Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+        continue;

+      } else {

+        //

+        // Copy the label

+        //

+        CopyMem (TempBuffer, Location, Location->Length);

+        TempBuffer  = TempBuffer + Location->Length;

+        Location    = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+

+        //

+        // Remove the DataCount amount of opcodes unless we run into an end of form or a label

+        //

+        for (Index = 0; Index < Data->DataCount; Index++) {

+          //

+          // If we are about to skip an end form - bail out, since that is illegal

+          //

+          if ((Location->OpCode == EFI_IFR_END_FORM_OP) || (Location->OpCode == EFI_IFR_LABEL_OP)) {

+            break;

+          }

+          //

+          // By skipping Location entries, we are in effect not copying what was previously there

+          //

+          ((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize -= Location->Length;

+          OtherBuffer = ((UINT8 *) &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->StringSize + sizeof (UINTN));

+          CopyMem (OtherBuffer, &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize, 2);

+          Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+        }

+      }

+

+    default:

+      CopyMem (TempBuffer, Location, Location->Length);

+      TempBuffer = TempBuffer + Location->Length;

+      break;

+    }

+    //

+    // Go to the next Op-Code

+    //

+    Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+  }

+  //

+  // Copy the last op-code left behind from the for loop

+  //

+  CopyMem (TempBuffer, Location, Location->Length);

+

+  //

+  // Advance to beginning of strings and copy them

+  //

+  TempBuffer  = TempBuffer + Location->Length;

+  Location    = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);

+  CopyMem (TempBuffer, Location, PackageInstance->StringSize);

+

+  //

+  // Free the old buffer, and assign into our database the latest buffer

+  //

+  gBS->FreePool (HandleDatabase->Buffer);

+  HandleDatabase->Buffer = OrigTempBuffer;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c
new file mode 100644
index 0000000..ce34eff
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.c
@@ -0,0 +1,413 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  HiiDatabase.c

+

+Abstract:

+

+  This file contains the entry code to the HII database.

+

+--*/

+

+#include "HiiDatabase.h"

+

+EFI_STATUS

+EFIAPI

+InitializeHiiDatabase (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+  Initialize HII Database

+  

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns: 

+  EFI_SUCCESS - Setup loaded.

+  other       - Setup Error

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_HII_DATA        *HiiData;

+  EFI_HII_GLOBAL_DATA *GlobalData;

+  EFI_HANDLE          *HandleBuffer;

+  EFI_HANDLE          Handle;

+  UINTN               HandleCount;

+  UINTN               Index;

+

+  //

+  // There will be only one HII Database in the system

+  // If there is another out there, someone is trying to install us

+  // again.  Fail that scenario.

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+

+  //

+  // If there was no error, assume there is an installation and fail to load

+  //

+  if (!EFI_ERROR (Status)) {

+    if (HandleBuffer != NULL) {

+      gBS->FreePool (HandleBuffer);

+    }

+

+    return EFI_DEVICE_ERROR;

+  }

+

+  HiiData = AllocatePool (sizeof (EFI_HII_DATA));

+

+  ASSERT (HiiData);

+

+  GlobalData = AllocateZeroPool (sizeof (EFI_HII_GLOBAL_DATA));

+

+  ASSERT (GlobalData);

+

+  //

+  // Seed the Font Database with a known non-character glyph

+  //

+  for (Index = 0; Index <= MAX_GLYPH_COUNT; Index++) {

+    //

+    // Seeding the UnicodeWeight with 0 signifies that it is uninitialized

+    //

+    GlobalData->NarrowGlyphs[Index].UnicodeWeight = 0;

+    GlobalData->WideGlyphs[Index].UnicodeWeight   = 0;

+    GlobalData->NarrowGlyphs[Index].Attributes    = 0;

+    GlobalData->WideGlyphs[Index].Attributes      = 0;

+    CopyMem (GlobalData->NarrowGlyphs[Index].GlyphCol1, &mUnknownGlyph, NARROW_GLYPH_ARRAY_SIZE);

+    CopyMem (GlobalData->WideGlyphs[Index].GlyphCol1, &mUnknownGlyph, WIDE_GLYPH_ARRAY_SIZE);

+  }

+  //

+  // Fill in HII data

+  //

+  HiiData->Signature                        = EFI_HII_DATA_SIGNATURE;

+  HiiData->GlobalData                       = GlobalData;

+  HiiData->GlobalData->SystemKeyboardUpdate = FALSE;

+  HiiData->DatabaseHead                     = NULL;

+  HiiData->Hii.NewPack                      = HiiNewPack;

+  HiiData->Hii.RemovePack                   = HiiRemovePack;

+  HiiData->Hii.FindHandles                  = HiiFindHandles;

+  HiiData->Hii.ExportDatabase               = HiiExportDatabase;

+  HiiData->Hii.GetGlyph                     = HiiGetGlyph;

+  HiiData->Hii.GetPrimaryLanguages          = HiiGetPrimaryLanguages;

+  HiiData->Hii.GetSecondaryLanguages        = HiiGetSecondaryLanguages;

+  HiiData->Hii.NewString                    = HiiNewString;

+  HiiData->Hii.GetString                    = HiiGetString;

+  HiiData->Hii.ResetStrings                 = HiiResetStrings;

+  HiiData->Hii.TestString                   = HiiTestString;

+  HiiData->Hii.GetLine                      = HiiGetLine;

+  HiiData->Hii.GetForms                     = HiiGetForms;

+  HiiData->Hii.GetDefaultImage              = HiiGetDefaultImage;

+  HiiData->Hii.UpdateForm                   = HiiUpdateForm;

+  HiiData->Hii.GetKeyboardLayout            = HiiGetKeyboardLayout;

+  HiiData->Hii.GlyphToBlt                   = HiiGlyphToBlt;

+

+  //

+  // Install protocol interface

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiHiiProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &HiiData->Hii

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+HiiFindHandles (

+  IN     EFI_HII_PROTOCOL *This,

+  IN OUT UINT16           *HandleBufferLength,

+  OUT    EFI_HII_HANDLE   Handle[1]

+  )

+/*++

+

+Routine Description:

+  Determines the handles that are currently active in the database.

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_GLOBAL_DATA     *GlobalData;

+  EFI_HII_HANDLE_DATABASE *Database;

+  EFI_HII_DATA            *HiiData;

+  UINTN                   HandleCount;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData     = EFI_HII_DATA_FROM_THIS (This);

+

+  GlobalData  = HiiData->GlobalData;

+

+  Database    = HiiData->DatabaseHead;

+

+  if (Database == NULL) {

+    *HandleBufferLength = 0;

+    return EFI_NOT_FOUND;

+  }

+

+  for (HandleCount = 0; Database != NULL; HandleCount++) {

+    Database = Database->NextHandleDatabase;

+  }

+  //

+  // Is there a sufficient buffer for the data being passed back?

+  //

+  if (*HandleBufferLength >= (sizeof (EFI_HII_HANDLE) * HandleCount)) {

+    Database = HiiData->DatabaseHead;

+

+    //

+    // Copy the Head information

+    //

+    if (Database->Handle != 0) {

+      CopyMem (&Handle[0], &Database->Handle, sizeof (EFI_HII_HANDLE));

+      Database = Database->NextHandleDatabase;

+    }

+    //

+    // Copy more data if appropriate

+    //

+    for (HandleCount = 1; Database != NULL; HandleCount++) {

+      CopyMem (&Handle[HandleCount], &Database->Handle, sizeof (EFI_HII_HANDLE));

+      Database = Database->NextHandleDatabase;

+    }

+

+    *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);

+    return EFI_SUCCESS;

+  } else {

+    //

+    // Insufficient buffer length

+    //

+    *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);

+    return EFI_BUFFER_TOO_SMALL;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+HiiGetPrimaryLanguages (

+  IN  EFI_HII_PROTOCOL      *This,

+  IN  EFI_HII_HANDLE        Handle,

+  OUT EFI_STRING            *LanguageString

+  )

+/*++

+

+Routine Description:

+  

+  This function allows a program to determine what the primary languages that are supported on a given handle.

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  UINTN                     Count;

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_STRING_PACK       *StringPack;

+  EFI_HII_STRING_PACK       *Location;

+  UINT32                    Length;

+  RELOFST                   Token;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  PackageInstance = NULL;

+  //

+  // Find matching handle in the handle database. Then get the package instance.

+  //

+  for (HandleDatabase = HiiData->DatabaseHead;

+       HandleDatabase != NULL;

+       HandleDatabase = HandleDatabase->NextHandleDatabase

+      ) {

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);

+

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (StringPackageInstance->IfrSize > 0) {

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);

+  } else {

+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);

+  }

+

+  Location = StringPack;

+  //

+  // Remember that the string packages are formed into contiguous blocks of language data.

+  //

+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  for (Count = 0; Length != 0; Count = Count + 3) {

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  }

+

+  *LanguageString = AllocateZeroPool (2 * (Count + 1));

+

+  ASSERT (*LanguageString);

+

+  StringPack = (EFI_HII_STRING_PACK *) Location;

+

+  //

+  // Copy the 6 bytes to LanguageString - keep concatenating it.  Shouldn't we just store uint8's since the ISO

+  // standard defines the lettering as all US English characters anyway?  Save a few bytes.

+  //

+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  for (Count = 0; Length != 0; Count = Count + 3) {

+    CopyMem (&Token, &StringPack->LanguageNameString, sizeof (RELOFST));

+    CopyMem (*LanguageString + Count, (VOID *) ((CHAR8 *) (StringPack) + Token), 6);

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiGetSecondaryLanguages (

+  IN  EFI_HII_PROTOCOL      *This,

+  IN  EFI_HII_HANDLE        Handle,

+  IN  CHAR16                *PrimaryLanguage,

+  OUT EFI_STRING            *LanguageString

+  )

+/*++

+

+Routine Description:

+  

+  This function allows a program to determine which secondary languages are supported 

+  on a given handle for a given primary language.

+

+  Arguments:

+

+Returns: 

+

+--*/

+{

+  UINTN                     Count;

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_STRING_PACK       *StringPack;

+  EFI_HII_STRING_PACK       *Location;

+  RELOFST                   Token;

+  UINT32                    Length;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData = EFI_HII_DATA_FROM_THIS (This);

+  //

+  // Check numeric value against the head of the database

+  //

+  PackageInstance = NULL;

+  for (HandleDatabase = HiiData->DatabaseHead;

+       HandleDatabase != NULL;

+       HandleDatabase = HandleDatabase->NextHandleDatabase

+      ) {

+    //

+    // Match the numeric value with the database entry - if matched, extract PackageInstance

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);

+

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (StringPackageInstance->IfrSize > 0) {

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);

+  } else {

+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);

+  }

+

+  Location = StringPack;

+

+  //

+  // Remember that the string packages are formed into contiguous blocks of language data.

+  //

+  for (; StringPack->Header.Length != 0;) {

+    //

+    // Find the PrimaryLanguage being requested

+    //

+    Token = StringPack->LanguageNameString;

+    if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + Token), PrimaryLanguage, 3) == 0) {

+      //

+      // Now that we found the primary, the secondary languages will follow immediately

+      // or the next character is a NULL if there are no secondary languages.  We determine

+      // the number by getting the stringsize based on the StringPack origination + the LanguageNameString

+      // offset + 6 (which is the size of the first 3 letter ISO primary language name).  If we get 2, there

+      // are no secondary languages (2 = null-terminator).

+      //

+      Count           = StrSize ((VOID *) ((CHAR8 *) (StringPack) + Token + 6));

+

+      *LanguageString = AllocateZeroPool (2 * (Count + 1));

+

+      ASSERT (*LanguageString);

+

+      CopyMem (*LanguageString, (VOID *) ((CHAR8 *) (StringPack) + Token + 6), Count);

+      break;

+    }

+

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);

+  }

+

+  return EFI_SUCCESS;

+}

+

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs
new file mode 100644
index 0000000..86c8ac4
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  HiiDatabase.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h
new file mode 100644
index 0000000..c50cd95
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.h
@@ -0,0 +1,302 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  HiiDatabase.h

+

+Abstract:

+

+  This file contains global defines and prototype definitions 

+  for the HII database.

+

+--*/

+

+#ifndef _HIIDATABASE_H

+#define _HIIDATABASE_H

+

+//

+// HII Database Global data

+//

+#define EFI_HII_DATA_SIGNATURE            EFI_SIGNATURE_32 ('H', 'i', 'i', 'P')

+

+#define MAX_GLYPH_COUNT                   65535

+#define NARROW_GLYPH_ARRAY_SIZE           19

+#define WIDE_GLYPH_ARRAY_SIZE             38

+

+#define SETUP_MAP_NAME                              L"Setup"

+#define HII_VARIABLE_SUFFIX_USER_DATA               L"UserSavedData"

+#define HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE        L"DefaultOverride"

+#define HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE  L"ManufacturingOverride"

+

+typedef struct _EFI_HII_HANDLE_DATABASE {

+  VOID                            *Buffer;        // Actual buffer pointer

+  EFI_HII_HANDLE                  Handle;         // Monotonically increasing value to signify the value returned to caller

+  UINT32                          NumberOfTokens; // The initial number of tokens when first registered

+  struct _EFI_HII_HANDLE_DATABASE *NextHandleDatabase;

+} EFI_HII_HANDLE_DATABASE;

+

+typedef struct {

+  EFI_NARROW_GLYPH    NarrowGlyphs[MAX_GLYPH_COUNT];

+  EFI_WIDE_GLYPH      WideGlyphs[MAX_GLYPH_COUNT];

+  EFI_KEY_DESCRIPTOR  SystemKeyboardLayout[106];

+  EFI_KEY_DESCRIPTOR  OverrideKeyboardLayout[106];

+  BOOLEAN             SystemKeyboardUpdate;       // Has the SystemKeyboard been updated?

+} EFI_HII_GLOBAL_DATA;

+

+typedef struct {

+  UINTN                   Signature;

+

+  EFI_HII_GLOBAL_DATA     *GlobalData;

+  EFI_HII_HANDLE_DATABASE *DatabaseHead;          // Head of the Null-terminated singly-linked list of handles.

+  EFI_HII_PROTOCOL        Hii;

+} EFI_HII_DATA;

+

+typedef struct {

+  EFI_HII_HANDLE      Handle;

+  EFI_GUID            Guid;

+  EFI_HII_HANDLE_PACK HandlePack;

+  UINTN               IfrSize;

+  UINTN               StringSize;

+  EFI_HII_IFR_PACK    *IfrData;                   // All the IFR data stored here

+  EFI_HII_STRING_PACK *StringData;                // All the String data stored at &IfrData + IfrSize (StringData is just a label - never referenced)

+} EFI_HII_PACKAGE_INSTANCE;

+

+typedef struct {

+  EFI_HII_PACK_HEADER   Header;

+  EFI_IFR_FORM_SET      FormSet;

+  EFI_IFR_END_FORM_SET  EndFormSet;

+} EFI_FORM_SET_STUB;

+

+#define EFI_HII_DATA_FROM_THIS(a) CR (a, EFI_HII_DATA, Hii, EFI_HII_DATA_SIGNATURE)

+

+#define NARROW_WIDTH              8

+#define WIDE_WIDTH                16

+

+extern UINT8  mUnknownGlyph[38];

+

+//

+// Prototypes

+//

+EFI_STATUS

+GetPackSize (

+  IN  VOID                *Pack,

+  OUT UINTN               *PackSize,

+  OUT UINT32              *NumberOfTokens

+  )

+;

+

+EFI_STATUS

+ValidatePack (

+  IN   EFI_HII_PROTOCOL          *This,

+  IN   EFI_HII_PACKAGE_INSTANCE  *PackageInstance,

+  OUT  EFI_HII_PACKAGE_INSTANCE  **StringPackageInstance,

+  OUT  UINT32                    *TotalStringCount

+  )

+;

+

+//

+// Public Interface Prototypes

+//

+EFI_STATUS

+EFIAPI

+InitializeHiiDatabase (

+  IN EFI_HANDLE             ImageHandle,

+  IN EFI_SYSTEM_TABLE       *SystemTable

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiNewPack (

+  IN  EFI_HII_PROTOCOL      *This,

+  IN  EFI_HII_PACKAGES      *PackageList,

+  OUT EFI_HII_HANDLE        *Handle

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiRemovePack (

+  IN EFI_HII_PROTOCOL    *This,

+  IN EFI_HII_HANDLE      Handle

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiFindHandles (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN OUT UINT16              *HandleBufferLength,

+  OUT    EFI_HII_HANDLE      *Handle

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiExportDatabase (

+  IN     EFI_HII_PROTOCOL *This,

+  IN     EFI_HII_HANDLE   Handle,

+  IN OUT UINTN            *BufferSize,

+  OUT    VOID             *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetGlyph (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     CHAR16              *Source,

+  IN OUT UINT16              *Index,

+  OUT    UINT8               **GlyphBuffer,

+  OUT    UINT16              *BitWidth,

+  IN OUT UINT32              *InternalStatus

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGlyphToBlt (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     UINT8              *GlyphBuffer,

+  IN     EFI_UGA_PIXEL      Foreground,

+  IN     EFI_UGA_PIXEL      Background,

+  IN     UINTN              Count,

+  IN     UINTN              Width,

+  IN     UINTN              Height,

+  IN OUT EFI_UGA_PIXEL      *BltBuffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiNewString (

+  IN     EFI_HII_PROTOCOL        *This,

+  IN     CHAR16                  *Language,

+  IN     EFI_HII_HANDLE          Handle,

+  IN OUT STRING_REF              *Reference,

+  IN     CHAR16                  *NewString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetString (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     EFI_HII_HANDLE      Handle,

+  IN     STRING_REF          Token,

+  IN     BOOLEAN             Raw,

+  IN     CHAR16              *LanguageString,

+  IN OUT UINTN               *BufferLength,

+  OUT    EFI_STRING          StringBuffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiResetStrings (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     EFI_HII_HANDLE      Handle

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiTestString (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     CHAR16              *StringToTest,

+  IN OUT UINT32              *FirstMissing,

+  OUT    UINT32              *GlyphBufferSize

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetPrimaryLanguages (

+  IN  EFI_HII_PROTOCOL      *This,

+  IN  EFI_HII_HANDLE        Handle,

+  OUT EFI_STRING            *LanguageString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetSecondaryLanguages (

+  IN  EFI_HII_PROTOCOL      *This,

+  IN  EFI_HII_HANDLE        Handle,

+  IN  CHAR16                *PrimaryLanguage,

+  OUT EFI_STRING            *LanguageString

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetLine (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     EFI_HII_HANDLE      Handle,

+  IN     STRING_REF          Token,

+  IN OUT UINT16              *Index,

+  IN     UINT16              LineWidth,

+  IN     CHAR16              *LanguageString,

+  IN OUT UINT16              *BufferLength,

+  OUT    EFI_STRING          StringBuffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetForms (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     EFI_HII_HANDLE      Handle,

+  IN     EFI_FORM_ID         FormId,

+  IN OUT UINTN               *BufferLength,

+  OUT    UINT8               *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetDefaultImage (

+  IN     EFI_HII_PROTOCOL           *This,

+  IN     EFI_HII_HANDLE             Handle,

+  IN     UINTN                      DefaultMask,

+  OUT    EFI_HII_VARIABLE_PACK_LIST **VariablePackList

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiUpdateForm (

+  IN EFI_HII_PROTOCOL       *This,

+  IN EFI_HII_HANDLE         Handle,

+  IN EFI_FORM_LABEL         Label,

+  IN BOOLEAN                AddData,

+  IN EFI_HII_UPDATE_DATA    *Data

+  )

+;

+

+EFI_STATUS

+EFIAPI

+HiiGetKeyboardLayout (

+  IN     EFI_HII_PROTOCOL    *This,

+  OUT    UINT16              *DescriptorCount,

+  OUT    EFI_KEY_DESCRIPTOR  *Descriptor

+  )

+;

+

+EFI_STATUS

+HiiCompareLanguage (

+  IN  CHAR16                *LanguageStringLocation,

+  IN  CHAR16                *Language

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd
new file mode 100644
index 0000000..03f2ed9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>HiiDatabase</BaseName>

+    <Guid>FCD337AB-B1D3-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>EdkIfrSupportLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa
new file mode 100644
index 0000000..9193278
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/HiiDatabase.msa
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>HiiDatabase</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>FCD337AB-B1D3-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkIfrSupportLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>HiiDatabase.c</Filename>

+    <Filename>HiiDatabase.h</Filename>

+    <Filename>Forms.c</Filename>

+    <Filename>Strings.c</Filename>

+    <Filename>Package.c</Filename>

+    <Filename>Fonts.c</Filename>

+    <Filename>Keyboard.c</Filename>

+    <Filename>HiiDatabase.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FormCallback</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable Usage="ALWAYS_CONSUMED">

+      <String>L"Lang"</String>

+      <Guid Usage="ALWAYS_CONSUMED">

+        0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }

+      </Guid>

+    </Variable>

+  </Variables>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>GlobalVariable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeHiiDatabase</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c
new file mode 100644
index 0000000..8e9417f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Keyboard.c
@@ -0,0 +1,43 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Keyboard.c

+

+Abstract:

+

+  This file contains the keyboard processing code to the HII database.

+

+--*/

+

+

+#include "HiiDatabase.h"

+

+EFI_STATUS

+EFIAPI

+HiiGetKeyboardLayout (

+  IN     EFI_HII_PROTOCOL   *This,

+  OUT    UINT16             *DescriptorCount,

+  OUT    EFI_KEY_DESCRIPTOR *Descriptor

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c
new file mode 100644
index 0000000..3e9e536
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Package.c
@@ -0,0 +1,677 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Package.c

+

+Abstract:

+

+  This file contains the package processing code to the HII database.

+

+--*/

+

+

+#include "HiiDatabase.h"

+

+EFI_STATUS

+GetPackSize (

+  IN  VOID                *Pack,

+  OUT UINTN               *PackSize,

+  OUT UINT32              *NumberOfTokens

+  )

+/*++

+

+Routine Description:

+  Determines the passed in Pack's size and returns the value.

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_STRING_PACK *StringPack;

+  UINT16              Type;

+  UINT32              Length;

+

+  *PackSize = 0;

+

+  Type      = EFI_HII_IFR;

+  if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {

+    //

+    // The header contains the full IFR length

+    //

+    CopyMem (&Length, &((EFI_HII_PACK_HEADER *) Pack)->Length, sizeof (Length));

+    *PackSize = (UINTN) Length;

+    return EFI_SUCCESS;

+  }

+

+  Type = EFI_HII_STRING;

+  if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {

+    //

+    // The header contains the STRING package length

+    // The assumption is that the strings for all languages

+    // are a contiguous block of data and there is a series of

+    // these package instances which will terminate with a NULL package

+    // instance.

+    //

+    StringPack = (EFI_HII_STRING_PACK *) Pack;

+

+    //

+    // There may be multiple instances packed together of strings

+    // so we must walk the self describing structures until we encounter

+    // the NULL structure to determine the full size.

+    //

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));

+    if (NumberOfTokens != NULL) {

+      CopyMem (NumberOfTokens, &StringPack->NumStringPointers, sizeof (UINT32));

+    }

+

+    while (Length != 0) {

+      *PackSize   = *PackSize + Length;

+      StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) StringPack + Length);

+      CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));

+    }

+    //

+    // Encountered a length of 0, so let's add the space for the NULL terminator

+    // pack's length and call it done.

+    //

+    *PackSize = *PackSize + sizeof (EFI_HII_STRING_PACK);

+    return EFI_SUCCESS;

+  }

+  //

+  // We only determine the size of the non-global Package types.

+  // If neither IFR or STRING data were found, return an error

+  //

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+ValidatePack (

+  IN   EFI_HII_PROTOCOL          *This,

+  IN   EFI_HII_PACKAGE_INSTANCE  *PackageInstance,

+  OUT  EFI_HII_PACKAGE_INSTANCE  **StringPackageInstance,

+  OUT  UINT32                    *TotalStringCount

+  )

+/*++

+

+Routine Description:

+  Verifies that the package instance is using the correct handle for string operations.

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_PACKAGE_INSTANCE  *HandlePackageInstance;

+  UINT8                     *RawData;

+  EFI_GUID                  Guid;

+  EFI_HII_IFR_PACK          *FormPack;

+  UINTN                     Index;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase  = HiiData->DatabaseHead;

+  ZeroMem (&Guid, sizeof (EFI_GUID));

+

+  *StringPackageInstance = PackageInstance;

+

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (PackageInstance->IfrSize > 0) {

+    FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+  } else {

+    //

+    // If there is no IFR data assume the caller knows what they are doing.

+    //

+    return EFI_SUCCESS;

+  }

+

+  RawData = (UINT8 *) FormPack;

+

+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    if (RawData[Index] == EFI_IFR_FORM_SET_OP) {

+      //

+      // Cache the guid for this formset

+      //

+      CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));

+      break;

+    }

+

+    Index = RawData[Index + 1] + Index;

+  }

+  //

+  // If there is no string package, and the PackageInstance->IfrPack.Guid and PackageInstance->Guid are

+  // different, we should return the correct handle for the caller to use for strings.

+  //

+  if ((PackageInstance->StringSize == 0) && (!CompareGuid (&Guid, &PackageInstance->Guid))) {

+    //

+    // Search the database for a handle that matches the PackageInstance->Guid

+    //

+    for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+      //

+      // Get Ifrdata and extract the Guid for it

+      //

+      HandlePackageInstance = HandleDatabase->Buffer;

+

+      ASSERT (HandlePackageInstance->IfrSize != 0);

+

+      FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&HandlePackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));

+      RawData   = (UINT8 *) FormPack;

+

+      for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {

+        if (RawData[Index] == EFI_IFR_FORM_SET_OP) {

+          //

+          // Cache the guid for this formset

+          //

+          CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));

+          break;

+        }

+

+        Index = RawData[Index + 1] + Index;

+      }

+      //

+      // If the Guid from the new handle matches the original Guid referenced in the original package data

+      // return the appropriate package instance data to use.

+      //

+      if (CompareGuid (&Guid, &PackageInstance->Guid)) {

+        if (TotalStringCount != NULL) {

+          *TotalStringCount = HandleDatabase->NumberOfTokens;

+        }

+

+        *StringPackageInstance = HandlePackageInstance;

+      }

+    }

+    //

+    // end for

+    //

+  } else {

+    return EFI_SUCCESS;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiNewPack (

+  IN  EFI_HII_PROTOCOL    *This,

+  IN  EFI_HII_PACKAGES    *Packages,

+  OUT EFI_HII_HANDLE      *Handle

+  )

+/*++

+

+Routine Description:

+

+  Extracts the various packs from a package list.

+  

+Arguments:

+

+  This      - Pointer of HII protocol.

+  Packages  - Pointer of HII packages.

+  Handle    - Handle value to be returned.

+

+Returns: 

+

+  EFI_SUCCESS           - Pacakges has added to HII database successfully.

+  EFI_INVALID_PARAMETER - Invalid parameter.

+

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_HANDLE_DATABASE   *Database;

+  EFI_HII_PACK_HEADER       *PackageHeader;

+  EFI_HII_GLOBAL_DATA       *GlobalData;

+  EFI_HII_IFR_PACK          *IfrPack;

+  EFI_HII_STRING_PACK       *StringPack;

+  EFI_HII_FONT_PACK         *FontPack;

+  EFI_HII_KEYBOARD_PACK     *KeyboardPack;

+  EFI_STATUS                Status;

+  UINTN                     IfrSize;

+  UINTN                     StringSize;

+  UINTN                     TotalStringSize;

+  UINTN                     InstanceSize;

+  UINTN                     Count;

+  UINTN                     Index;

+  UINT16                    Member;

+  EFI_GUID                  Guid;

+  EFI_FORM_SET_STUB         FormSetStub;

+  UINT8                     *Location;

+  UINT16                    Unicode;

+  UINT16                    NumWideGlyphs;

+  UINT16                    NumNarrowGlyphs;

+  UINT32                    NumberOfTokens;

+  UINT32                    TotalTokenNumber;

+  UINT8                     *Local;

+  EFI_NARROW_GLYPH          *NarrowGlyph;

+  EFI_WIDE_GLYPH            *WideGlyph;

+

+  if (Packages->NumberOfPackages == 0 || This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData           = EFI_HII_DATA_FROM_THIS (This);

+

+  GlobalData        = HiiData->GlobalData;

+

+  Database          = HiiData->DatabaseHead;

+

+  PackageInstance   = NULL;

+  IfrPack           = NULL;

+  StringPack        = NULL;

+  InstanceSize      = 0;

+  IfrSize           = 0;

+  StringSize        = 0;

+  TotalStringSize   = 0;

+  NumberOfTokens    = 0;

+  TotalTokenNumber  = 0;

+

+  //

+  // Search through the passed in Packages for the IfrPack and any StringPack.

+  //

+  for (Index = 0; Index < Packages->NumberOfPackages; Index++) {

+

+    PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));

+

+    switch (PackageHeader->Type) {

+    case EFI_HII_IFR:

+      //

+      // There shoule be only one Ifr package.

+      //

+      ASSERT (IfrPack == NULL);

+      IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;

+      break;

+

+    case EFI_HII_STRING:

+      StringPack = (EFI_HII_STRING_PACK *) PackageHeader;

+      //

+      // Sending me a String Package. Get its size.

+      //

+      Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);

+      ASSERT (!EFI_ERROR (Status));

+

+      //

+      // The size which GetPackSize() returns include the null terminator. So if multiple

+      // string packages are passed in, merge all these packages, and only pad one null terminator.

+      //

+      if (TotalStringSize > 0) {

+        TotalStringSize -= sizeof (EFI_HII_STRING_PACK);

+      }

+

+      TotalStringSize += StringSize;

+      TotalTokenNumber += NumberOfTokens;

+      break;

+    }

+  }

+  //

+  // If sending a StringPack without an IfrPack, you must include a GuidId

+  //

+  if ((StringPack != NULL) && (IfrPack == NULL)) {

+    if (Packages->GuidId == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // If passing in an IfrPack and a GuidId is provided, ensure they are the same value.

+  //

+  if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {

+    Location  = ((UINT8 *) IfrPack);

+    Location  = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));

+

+    //

+    // Advance to the Form Set Op-code

+    //

+    for (Count = 0; ((EFI_IFR_OP_HEADER *) &Location[Count])->OpCode != EFI_IFR_FORM_SET_OP;) {

+      Count = Count + ((EFI_IFR_OP_HEADER *) &Location[Count])->Length;

+    }

+    //

+    // Copy to local variable

+    //

+    CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));

+

+    //

+    // Check to see if IfrPack->Guid != GuidId

+    //

+    if (!CompareGuid (&Guid, Packages->GuidId)) {

+      //

+      // If a string package is present, the GUIDs should have agreed.  Return an error

+      //

+      if (StringPack != NULL) {

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+  //

+  // If someone is passing in a string only, create a dummy IfrPack with a Guid

+  // to enable future searching of this data.

+  //

+  if ((IfrPack == NULL) && (StringPack != NULL)) {

+    ZeroMem (&FormSetStub, sizeof (FormSetStub));

+

+    FormSetStub.Header.Type           = EFI_HII_IFR;

+    FormSetStub.Header.Length         = sizeof (EFI_FORM_SET_STUB);

+

+    FormSetStub.FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;

+    FormSetStub.FormSet.Header.Length = (UINT8) sizeof (EFI_IFR_FORM_SET);

+    //

+    // Dummy string

+    //

+    FormSetStub.FormSet.FormSetTitle  = 0x02;

+    CopyMem (&FormSetStub.FormSet.Guid, Packages->GuidId, sizeof (EFI_GUID));

+

+    FormSetStub.EndFormSet.Header.OpCode  = EFI_IFR_END_FORM_SET_OP;

+    FormSetStub.EndFormSet.Header.Length  = (UINT8) sizeof (EFI_IFR_END_FORM_SET);

+    IfrPack = (EFI_HII_IFR_PACK *) &FormSetStub;

+  }

+

+  if (IfrPack != NULL) {

+    //

+    // Sending me an IFR Package. Get its size.

+    //

+    Status = GetPackSize ((VOID *) IfrPack, &IfrSize, NULL);

+    ASSERT (!EFI_ERROR (Status));

+  }

+  //

+  // Prepare the internal package instace buffer to store package data.

+  //

+  InstanceSize = IfrSize + TotalStringSize;

+

+  if (InstanceSize != 0) {

+    PackageInstance = AllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));

+

+    ASSERT (PackageInstance);

+

+    //

+    // If there is no DatabaseHead allocated - allocate one

+    //

+    if (HiiData->DatabaseHead == NULL) {

+      HiiData->DatabaseHead = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));

+      ASSERT (HiiData->DatabaseHead);

+    }

+    //

+    // If the head is being used (Handle is non-zero), allocate next Database and

+    // add it to the linked-list

+    //

+    if (HiiData->DatabaseHead->Handle != 0) {

+      HandleDatabase = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));

+

+      ASSERT (HandleDatabase);

+

+      for (; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase)

+        ;

+

+      //

+      // We are sitting on the Database entry which contains the null Next pointer.  Fix it.

+      //

+      Database->NextHandleDatabase = HandleDatabase;

+

+    }

+

+    Database = HiiData->DatabaseHead;

+

+    //

+    // Initialize this instance data

+    //

+    for (*Handle = 1; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase) {

+      //

+      // Since the first Database instance will have a passed back handle of 1, we will continue

+      // down the linked list of entries until we encounter the end of the linked list.  Each time

+      // we go down one level deeper, increment the handle value that will be passed back.

+      //

+      if (Database->Handle >= *Handle) {

+        *Handle = Database->Handle + 1;

+      }

+    }

+

+    PackageInstance->Handle     = *Handle;

+    PackageInstance->IfrSize    = IfrSize;

+    PackageInstance->StringSize = TotalStringSize;

+    if (Packages->GuidId != NULL) {

+      CopyMem (&PackageInstance->Guid, Packages->GuidId, sizeof (EFI_GUID));

+    }

+

+    Database->Buffer              = PackageInstance;

+    Database->Handle              = PackageInstance->Handle;

+    Database->NumberOfTokens      = TotalTokenNumber;

+    Database->NextHandleDatabase  = NULL;

+  }

+  //

+  // Copy the Ifr package data into package instance.

+  //

+  if (IfrSize > 0) {

+    CopyMem (&PackageInstance->IfrData, IfrPack, IfrSize);

+  }

+  //

+  // Main loop to store package data into HII database.

+  //

+  StringSize      = 0;

+  TotalStringSize = 0;

+

+  for (Index = 0; Index < Packages->NumberOfPackages; Index++) {

+

+    PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));

+

+    switch (PackageHeader->Type) {

+    case EFI_HII_STRING:

+      StringPack = (EFI_HII_STRING_PACK *) PackageHeader;

+      //

+      // The size which GetPackSize() returns include the null terminator. So if multiple

+      // string packages are passed in, merge all these packages, and only pad one null terminator.

+      //

+      if (TotalStringSize > 0) {

+        TotalStringSize -= sizeof (EFI_HII_STRING_PACK);

+      }

+

+      GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);

+      CopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);

+

+      TotalStringSize += StringSize;

+      break;

+

+    case EFI_HII_HANDLES:

+      CopyMem (&PackageInstance->HandlePack, PackageHeader, sizeof (EFI_HII_HANDLE_PACK));

+      break;

+

+    case EFI_HII_FONT:

+      FontPack = (EFI_HII_FONT_PACK *) PackageHeader;

+      //

+      // Add whatever narrow glyphs were passed to us if undefined

+      //

+      CopyMem (&NumNarrowGlyphs, &FontPack->NumberOfNarrowGlyphs, sizeof (UINT16));

+      for (Count = 0; Count <= NumNarrowGlyphs; Count++) {

+        Local       = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) + (sizeof (EFI_NARROW_GLYPH)) * Count;

+        NarrowGlyph = (EFI_NARROW_GLYPH *) Local;

+        CopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));

+        //

+        // If the glyph is already defined, do not overwrite it.  It is what it is.

+        //

+        CopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));

+        if (Unicode == 0) {

+          CopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));

+        }

+      }

+      //

+      // Add whatever wide glyphs were passed to us if undefined

+      //

+      CopyMem (&NumWideGlyphs, &FontPack->NumberOfWideGlyphs, sizeof (UINT16));

+      for (Count = 0; Count <= NumWideGlyphs; Count++) {

+        Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) +

+          (sizeof (EFI_NARROW_GLYPH)) *

+          NumNarrowGlyphs;

+        WideGlyph = (EFI_WIDE_GLYPH *) Local;

+        CopyMem (

+          &Member,

+          (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),

+          sizeof (UINT16)

+          );

+        //

+        // If the glyph is already defined, do not overwrite it.  It is what it is.

+        //

+        CopyMem (&Unicode, &GlobalData->WideGlyphs[Member].UnicodeWeight, sizeof (UINT16));

+        if (Unicode == 0) {

+          Local = (UINT8*)(&FontPack->NumberOfWideGlyphs + sizeof(UINT8)) + (sizeof(EFI_NARROW_GLYPH)) * NumNarrowGlyphs;

+          WideGlyph = (EFI_WIDE_GLYPH *) Local;

+          CopyMem (

+            &GlobalData->WideGlyphs[Member],

+            (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),

+            sizeof (EFI_WIDE_GLYPH)

+            );

+        }

+      }

+      break;

+

+    case EFI_HII_KEYBOARD:

+      KeyboardPack = (EFI_HII_KEYBOARD_PACK *) PackageHeader;

+      //

+      // Sending me a Keyboard Package

+      //

+      if (KeyboardPack->DescriptorCount > 105) {

+        return EFI_INVALID_PARAMETER;

+      }

+      //

+      // If someone updates the Descriptors with a count of 0, blow aware the overrides.

+      //

+      if (KeyboardPack->DescriptorCount == 0) {

+        ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);

+      }

+

+      if (KeyboardPack->DescriptorCount < 106 && KeyboardPack->DescriptorCount > 0) {

+        //

+        // If SystemKeyboard was updated already, then steer changes to the override database

+        //

+        if (GlobalData->SystemKeyboardUpdate) {

+          ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);

+          for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {

+            CopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));

+            CopyMem (

+              &GlobalData->OverrideKeyboardLayout[Member],

+              &KeyboardPack->Descriptor[Count],

+              sizeof (EFI_KEY_DESCRIPTOR)

+              );

+          }

+        } else {

+          //

+          // SystemKeyboard was never updated, so this is likely the keyboard driver setting the System database.

+          //

+          ZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);

+          for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {

+            CopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));

+            CopyMem (

+              &GlobalData->SystemKeyboardLayout[Member],

+              &KeyboardPack->Descriptor[Count],

+              sizeof (EFI_KEY_DESCRIPTOR)

+              );

+          }

+          //

+          // Just updated the system keyboard database, reflect that in the global flag.

+          //

+          GlobalData->SystemKeyboardUpdate = TRUE;

+        }

+      }

+      break;

+

+    default:

+      break;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiRemovePack (

+  IN EFI_HII_PROTOCOL    *This,

+  IN EFI_HII_HANDLE      Handle

+  )

+/*++

+

+Routine Description:

+  Removes the various packs from a Handle

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_HANDLE_DATABASE   *PreviousHandleDatabase;

+  UINTN                     Count;

+

+  if (This == NULL || Handle == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase  = HiiData->DatabaseHead;

+  PackageInstance = NULL;

+

+  //

+  // Initialize the Previous with the Head of the Database

+  //

+  PreviousHandleDatabase = HandleDatabase;

+

+  for (Count = 0; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    //

+    // Match the numeric value with the database entry - if matched,

+    // free the package instance and apply fix-up to database linked list

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+

+      //

+      // Free the Package Instance

+      //

+      gBS->FreePool (PackageInstance);

+

+      //

+      // If this was the only Handle in the database

+      //

+      if (HiiData->DatabaseHead == HandleDatabase) {

+        HiiData->DatabaseHead = NULL;

+      }

+      //

+      // Make the parent->Next point to the current->Next

+      //

+      PreviousHandleDatabase->NextHandleDatabase = HandleDatabase->NextHandleDatabase;

+      gBS->FreePool (HandleDatabase);

+      return EFI_SUCCESS;

+    }

+    //

+    // If this was not the HandleDatabase entry we were looking for, cache it just in case the next one is

+    //

+    PreviousHandleDatabase = HandleDatabase;

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c
new file mode 100644
index 0000000..742a01d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/Strings.c
@@ -0,0 +1,1276 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Strings.c

+

+Abstract:

+

+  This file contains the string processing code to the HII database.

+

+--*/

+

+

+#include "HiiDatabase.h"

+

+VOID

+AsciiToUnicode (

+  IN    UINT8     *Lang,

+  IN    UINT16    *Language

+  )

+{

+  UINT8 Count;

+

+  //

+  // Convert the ASCII Lang variable to a Unicode Language variable

+  //

+  for (Count = 0; Count < 3; Count++) {

+    Language[Count] = (CHAR16) Lang[Count];

+  }

+}

+

+EFI_STATUS

+EFIAPI

+HiiTestString (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     CHAR16             *StringToTest,

+  IN OUT UINT32             *FirstMissing,

+  OUT    UINT32             *GlyphBufferSize

+  )

+/*++

+

+Routine Description:

+  Test if all of the characters in a string have corresponding font characters.

+  

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_HII_GLOBAL_DATA *GlobalData;

+  EFI_HII_DATA        *HiiData;

+  UINTN               Count;

+  BOOLEAN             Narrow;

+  UINTN               Location;

+  UINT8               GlyphCol1[19];

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData     = EFI_HII_DATA_FROM_THIS (This);

+

+  GlobalData  = HiiData->GlobalData;

+  Count       = 0;

+  Narrow      = TRUE;

+

+  ZeroMem (GlyphCol1, sizeof (GlyphCol1));

+

+  //

+  // Walk through the string until you hit the null terminator

+  //

+  for (; StringToTest[*FirstMissing] != 0x00; (*FirstMissing)++) {

+    Location = *FirstMissing;

+    //

+    // Rewind through the string looking for a glyph width identifier

+    //

+    for (; Location != 0; Location--) {

+      if (StringToTest[Location] == NARROW_CHAR || StringToTest[Location] == WIDE_CHAR) {

+        //

+        // We found something that identifies what glyph database to look in

+        //

+        if (StringToTest[Location] == WIDE_CHAR) {

+          Narrow = FALSE;

+        } else {

+          Narrow = TRUE;

+        }

+      }

+    }

+

+    if (Narrow) {

+      if (CompareMem (

+          GlobalData->NarrowGlyphs[StringToTest[*FirstMissing]].GlyphCol1,

+          &mUnknownGlyph,

+          NARROW_GLYPH_ARRAY_SIZE

+          ) == 0

+          ) {

+        //

+        // Break since this glyph isn't defined

+        //

+        return EFI_NOT_FOUND;

+      }

+    } else {

+      //

+      // Can compare wide glyph against only GlyphCol1 since GlyphCol1 and GlyphCol2 are contiguous - just give correct size

+      //

+      if (CompareMem (

+          GlobalData->WideGlyphs[StringToTest[*FirstMissing]].GlyphCol1,

+          &mUnknownGlyph,

+          WIDE_GLYPH_ARRAY_SIZE

+          ) == 0

+          ) {

+        //

+        // Break since this glyph isn't defined

+        //

+        return EFI_NOT_FOUND;

+      }

+    }

+

+    Count++;

+  }

+

+  if (Narrow) {

+    *GlyphBufferSize = (UINT32) (Count * sizeof (EFI_NARROW_GLYPH));

+  } else {

+    *GlyphBufferSize = (UINT32) (Count * sizeof (EFI_WIDE_GLYPH));

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+HiiNewString2 (

+  IN     EFI_HII_PROTOCOL       *This,

+  IN     CHAR16                 *Language,

+  IN     EFI_HII_HANDLE         Handle,

+  IN OUT STRING_REF             *Reference,

+  IN     CHAR16                 *NewString,

+  IN     BOOLEAN                ResetStrings

+  )

+/*++

+

+Routine Description:

+

+  This function allows a new String to be added to an already existing String Package.

+  We will make a buffer the size of the package + EfiStrSize of the new string.  We will

+  copy the string package that first gets changed and the following language packages until

+  we encounter the NULL string package.  All this time we will ensure that the offsets have

+  been adjusted.  

+

+Arguments:

+  

+  This         -  Pointer to the HII protocol.

+  Language     -  Pointer to buffer which contains the language code of this NewString.

+  Handle       -  Handle of the package instance to be processed.

+  Reference    -  The token number for the string. If 0, new string token to be returned through this parameter.

+  NewString    -  Buffer pointer for the new string. 

+  ResetStrings -  Indicate if we are resetting a string.

+  

+Returns: 

+

+  EFI_SUCCESS            - The string has been added or reset to Hii database.

+  EFI_INVALID_PARAMETER  - Some parameter passed in is invalid.

+

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_STRING_PACK       *StringPack;

+  EFI_HII_STRING_PACK       *NewStringPack;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_PACKAGE_INSTANCE  *NewBuffer;

+  UINT8                     *Location;

+  UINT8                     *StringLocation;

+  RELOFST                   *StringPointer;

+  UINTN                     Count;

+  UINTN                     Size;

+  UINTN                     Index;

+  UINTN                     SecondIndex;

+  BOOLEAN                   AddString;

+  EFI_STATUS                Status;

+  UINTN                     Increment;

+  UINTN                     StringCount;

+  UINT32                    TotalStringCount;

+  UINT32                    OriginalStringCount;

+  RELOFST                   StringSize;

+  UINT32                    Length;

+  RELOFST                   Offset;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData             = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase      = HiiData->DatabaseHead;

+  PackageInstance     = NULL;

+  AddString           = FALSE;

+  Increment           = 0;

+  StringCount         = 0;

+  TotalStringCount    = 0;

+  OriginalStringCount = 0;

+

+  //

+  // Check numeric value against the head of the database

+  //

+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    //

+    // Match the numeric value with the database entry - if matched, extract PackageInstance

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+      if (ResetStrings) {

+        TotalStringCount = HandleDatabase->NumberOfTokens;

+      }

+      break;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = ValidatePack (This, PackageInstance, &StringPackageInstance, &TotalStringCount);

+

+  //

+  // This sets Count to 0 or the size of the IfrData.  We intend to use Count as an offset value

+  //

+  Count = StringPackageInstance->IfrSize;

+

+  //

+  // This is the size of the complete series of string packs

+  //

+  Size = StringPackageInstance->StringSize;

+

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (StringPackageInstance->IfrSize > 0) {

+    Location = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;

+  } else {

+    Location = (UINT8 *) (&StringPackageInstance->IfrData);

+  }

+  //

+  // We allocate a buffer which is big enough for both adding and resetting string.

+  // The size is slightly larger than the real size of the packages when we are resetting a string.

+  //

+  NewBuffer = AllocateZeroPool (

+                sizeof (EFI_HII_PACKAGE_INSTANCE) -

+                2 * sizeof (VOID *) +

+                StringPackageInstance->IfrSize +

+                StringPackageInstance->StringSize +

+                sizeof (RELOFST) +

+                StrSize (NewString)

+                );

+  ASSERT (NewBuffer);

+

+  //

+  // Copy data to new buffer

+  //

+  NewBuffer->Handle   = StringPackageInstance->Handle;

+  NewBuffer->IfrSize  = StringPackageInstance->IfrSize;

+

+  //

+  // The worst case scenario for sizing is that we are adding a new string (not replacing one) and there was not a string

+  // package to begin with.

+  //

+  NewBuffer->StringSize = StringPackageInstance->StringSize + StrSize (NewString) + sizeof (EFI_HII_STRING_PACK);

+

+  if (StringPackageInstance->IfrSize > 0) {

+    CopyMem (&NewBuffer->IfrData, &StringPackageInstance->IfrData, StringPackageInstance->IfrSize);

+  }

+

+  StringPack = (EFI_HII_STRING_PACK *) Location;

+

+  //

+  // There may be multiple instances packed together of strings

+  // so we must walk the self describing structures until we encounter

+  // what we are looking for.  In the meantime, copy everything we encounter

+  // to the new buffer.

+  //

+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  for (; Length != 0;) {

+    //

+    // If passed in Language ISO value is in this string pack's language string

+    // then we are dealing with the strings we want.

+    //

+    CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));

+    Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);

+

+    if (!EFI_ERROR (Status)) {

+      break;

+    }

+

+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);

+

+    Count       = Count + Length;

+    StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  }

+  //

+  // Found the language pack to update on a particular handle

+  // We need to Copy the Contents of this pack and adjust the offset values associated

+  // with adding/changing a string.  This is a particular piece of code that screams for

+  // it being prone to programming error.

+  //

+  //

+  // Copy the string package up to the string data

+  //

+  StringPointer = (RELOFST *) (StringPack + 1);

+  CopyMem (

+    ((CHAR8 *) (&NewBuffer->IfrData) + Count),

+    StringPack,

+    (UINTN) ((UINTN) (StringPointer) - (UINTN) (StringPack))

+    );

+

+  //

+  // Determine the number of StringPointers

+  //

+  if (!ResetStrings) {

+    CopyMem (&TotalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));

+  } else {

+    //

+    // If we are resetting the strings, use the original value when exported

+    //

+    CopyMem (&OriginalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));

+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString -=

+      (

+        (RELOFST) (OriginalStringCount - TotalStringCount) *

+        sizeof (RELOFST)

+      );

+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName -=

+      (

+        (RELOFST) (OriginalStringCount - TotalStringCount) *

+        sizeof (RELOFST)

+      );

+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers  = TotalStringCount;

+    *Reference = (STRING_REF) (TotalStringCount);

+  }

+  //

+  // If the token value is not valid, error out

+  //

+  if ((*Reference >= TotalStringCount) && !ResetStrings) {

+    gBS->FreePool (NewBuffer);

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // If Reference is 0, update it with what the new token reference will be and turn the AddString flag on

+  //

+  if (*Reference == 0) {

+    *Reference  = (STRING_REF) (TotalStringCount);

+    AddString   = TRUE;

+  }

+

+  if (AddString) {

+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString += sizeof (RELOFST);

+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName += sizeof (RELOFST);

+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers++;

+  }

+  //

+  // Increment offset by amount of copied data

+  //

+  Count = Count + ((UINTN) (StringPointer) - (UINTN) StringPack);

+

+  for (Index = 0; Index < TotalStringCount; Index++) {

+    //

+    // If we are pointing to the size of the changing string value

+    // then cache the old string value so you know what the difference is

+    //

+    if (Index == *Reference) {

+      CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));

+

+      StringLocation = ((UINT8 *) (StringPack) + Offset);

+      for (SecondIndex = 0;

+           (StringLocation[SecondIndex] != 0) || (StringLocation[SecondIndex + 1] != 0);

+           SecondIndex = SecondIndex + 2

+          )

+        ;

+      SecondIndex = SecondIndex + 2;

+

+      Size        = SecondIndex;

+

+      //

+      // NewString is a passed in local string which is assumed to be aligned

+      //

+      Size = StrSize (NewString) - Size;

+    }

+    //

+    // If we are about to copy the offset of the string that follows the changed string make

+    // sure that the offsets are adjusted accordingly

+    //

+    if ((Index > *Reference) && !ResetStrings) {

+      CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));

+      Offset = (RELOFST) (Offset + Size);

+      CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));

+    }

+    //

+    // If we are adding a string that means we will have an extra string pointer that will affect all string offsets

+    //

+    if (AddString) {

+      CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));

+      Offset = (UINT32) (Offset + sizeof (RELOFST));

+      CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));

+    }

+    //

+    // If resetting the strings, we need to reduce the offset by the difference in the strings

+    //

+    if (ResetStrings) {

+      CopyMem (&Length, &StringPointer[Index], sizeof (RELOFST));

+      Length = Length - ((RELOFST) (OriginalStringCount - TotalStringCount) * sizeof (RELOFST));

+      CopyMem (&StringPointer[Index], &Length, sizeof (RELOFST));

+    }

+    //

+    // Notice that if the string was being added as a new token, we don't have to worry about the

+    // offsets changing in the other indexes

+    //

+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringPointer[Index], sizeof (RELOFST));

+    Count = Count + sizeof (RELOFST);

+    StringCount++;

+  }

+  //

+  // If we are adding a new string the above for loop did not copy the offset for us

+  //

+  if (AddString) {

+    //

+    // Since the Index is pointing to the beginning of the first string, we need to gather the size of the previous

+    // offset's string and create an offset to our new string.

+    //

+    CopyMem (&Offset, &StringPointer[Index - 1], sizeof (RELOFST));

+    StringLocation  = (UINT8 *) StringPack;

+    StringLocation  = StringLocation + Offset - sizeof (RELOFST);

+

+    //

+    // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues

+    //

+    for (Length = 0;

+         (StringLocation[Length] != 0) || (StringLocation[Length + 1] != 0);

+         Length = (RELOFST) (Length + 2)

+        )

+      ;

+    Length      = (RELOFST) (Length + 2);

+

+    StringSize  = (RELOFST) (Offset + Length);

+

+    //

+    // Copy the new string offset

+    //

+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringSize, sizeof (RELOFST));

+    Count = Count + sizeof (RELOFST);

+

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+    Length = Length + sizeof (RELOFST);

+    CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));

+  }

+  //

+  // Set Location to the First String

+  //

+  if (ResetStrings) {

+    Index = OriginalStringCount;

+  }

+  //

+  // Set Location to the First String

+  //

+  Location  = (UINT8 *) &StringPointer[Index];

+  Index     = 0;

+

+  //

+  // Keep copying strings until you run into two CHAR16's in a row that are NULL

+  //

+  do {

+    if ((*Reference == Increment) && !AddString) {

+      StringLocation = ((UINT8 *) (&NewBuffer->IfrData) + Count);

+      CopyMem (StringLocation, NewString, StrSize (NewString));

+

+      //

+      // Advance the destination location by Count number of bytes

+      //

+      Count = Count + StrSize (NewString);

+

+      //

+      // Add the difference between the new string and the old string to the length

+      //

+      CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+

+      //

+      // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues

+      //

+      StringLocation = (UINT8 *) &Location[Index];

+      for (Offset = 0;

+           (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);

+           Offset = (RELOFST) (Offset + 2)

+          )

+        ;

+      Offset  = (RELOFST) (Offset + 2);

+

+      Length  = Length + (UINT32) StrSize (NewString) - Offset;

+

+      CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));

+    } else {

+      StringLocation = (UINT8 *) &Location[Index];

+      for (Offset = 0;

+           (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);

+           Offset = (RELOFST) (Offset + 2)

+          )

+        ;

+      Offset = (RELOFST) (Offset + 2);

+

+      CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringLocation, Offset);

+

+      //

+      // Advance the destination location by Count number of bytes

+      //

+      Count = Count + Offset;

+    }

+    //

+    // Retrieve the number of characters to advance the index - should land at beginning of next string

+    //

+    Index = Index + Offset;

+    Increment++;

+    StringCount--;

+    Offset = 0;

+  } while (StringCount > 0);

+

+  //

+  // If we are adding a new string, then the above do/while will not suffice

+  //

+  if (AddString) {

+    Offset = (RELOFST) StrSize (NewString);

+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), NewString, Offset);

+

+    Count = Count + StrSize (NewString);

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+    Length = Length + (UINT32) StrSize (NewString);

+    CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));

+  }

+

+  if (ResetStrings) {

+    //

+    // Skip the remainder of strings in the string package

+    //

+    StringCount = OriginalStringCount - TotalStringCount;

+

+    while (StringCount > 0) {

+      StringLocation = (UINT8 *) &Location[Index];

+      for (Offset = 0;

+           (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);

+           Offset = (RELOFST) (Offset + 2)

+          )

+        ;

+      Offset  = (RELOFST) (Offset + 2);

+      Index   = Index + Offset;

+      StringCount--;

+

+      //

+      // Adjust the size of the string pack by the string size we just skipped.

+      // Also reduce the length by the size of a RelativeOffset value since we

+      // obviously would have skipped that as well.

+      //

+      CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+      Length = Length - Offset - sizeof (RELOFST);

+      CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));

+    }

+  }

+

+  StringPack = (EFI_HII_STRING_PACK *) &Location[Index];

+

+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  for (; Length != 0;) {

+

+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);

+

+    Count       = Count + Length;

+    StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  }

+  //

+  // Copy the null terminator to the new buffer

+  //

+  CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, sizeof (EFI_HII_STRING_PACK));

+

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (StringPackageInstance->IfrSize > 0) {

+    Location      = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;

+    StringPack    = (EFI_HII_STRING_PACK *) Location;

+    Location      = (UINT8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize;

+    NewStringPack = (EFI_HII_STRING_PACK *) Location;

+  } else {

+    StringPack    = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);

+    NewStringPack = (EFI_HII_STRING_PACK *) (&NewBuffer->IfrData);

+  }

+

+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  for (; Length != 0;) {

+    //

+    // Since we updated the old version of the string data as we moved things over

+    // And we had a chicken-egg problem with the data we copied, let's post-fix the new

+    // buffer with accurate length data.

+    //

+    CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));

+    CopyMem (&NewStringPack->Header.Length, &StringPack->Header.Length, sizeof (UINT32));

+    CopyMem (&StringPack->Header.Length, &Count, sizeof (UINT32));

+

+    CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));

+    NewStringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (NewStringPack) + Count);

+    CopyMem (&Count, &StringPack->Header.Length, sizeof (UINT32));

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Count);

+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  }

+

+  GetPackSize ((VOID *) ((CHAR8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize), &NewBuffer->StringSize, NULL);

+

+  //

+  // Search through the handles until the requested handle is found.

+  //

+  for (HandleDatabase = HiiData->DatabaseHead;

+       HandleDatabase->Handle != 0;

+       HandleDatabase = HandleDatabase->NextHandleDatabase

+      ) {

+    if (HandleDatabase->Handle == StringPackageInstance->Handle) {

+      //

+      // Free the previous buffer associated with this handle, and assign the new buffer to the handle

+      //

+      gBS->FreePool (HandleDatabase->Buffer);

+      HandleDatabase->Buffer = NewBuffer;

+      break;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiNewString (

+  IN     EFI_HII_PROTOCOL       *This,

+  IN     CHAR16                 *Language,

+  IN     EFI_HII_HANDLE         Handle,

+  IN OUT STRING_REF             *Reference,

+  IN     CHAR16                 *NewString

+  )

+/*++

+

+Routine Description:

+  This function allows a new String to be added to an already existing String Package.

+  We will make a buffer the size of the package + StrSize of the new string.  We will

+  copy the string package that first gets changed and the following language packages until

+  we encounter the NULL string package.  All this time we will ensure that the offsets have

+  been adjusted.  

+

+Arguments:

+  

+Returns: 

+

+--*/

+{

+  UINTN       Index;

+  CHAR16      *LangCodes;

+  CHAR16      Lang[4];

+  STRING_REF  OriginalValue;

+  EFI_STATUS  Status;

+

+  //

+  // To avoid a warning 4 uninitialized variable warning

+  //

+  Status = EFI_SUCCESS;

+

+  Status = HiiGetPrimaryLanguages (

+            This,

+            Handle,

+            &LangCodes

+            );

+

+  if (!EFI_ERROR (Status)) {

+    OriginalValue = *Reference;

+

+    if (Language == NULL) {

+      for (Index = 0; LangCodes[Index] != 0; Index += 3) {

+        *Reference = OriginalValue;

+        CopyMem (Lang, &LangCodes[Index], 6);

+        Lang[3] = 0;

+        Status = HiiNewString2 (

+                  This,

+                  Lang,

+                  Handle,

+                  Reference,

+                  NewString,

+                  FALSE

+                  );

+

+      }

+    } else {

+      Status = HiiNewString2 (

+                This,

+                Language,

+                Handle,

+                Reference,

+                NewString,

+                FALSE

+                );

+    }

+

+    gBS->FreePool (LangCodes);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+HiiResetStrings (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     EFI_HII_HANDLE     Handle

+  )

+/*++

+

+Routine Description:

+  

+    This function removes any new strings that were added after the initial string export for this handle.

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  UINTN       Index;

+  CHAR16      *LangCodes;

+  CHAR16      Lang[4];

+  STRING_REF  Reference;

+  CHAR16      NewString;

+  EFI_STATUS  Status;

+

+  Reference = 1;

+  NewString = 0;

+

+  HiiGetPrimaryLanguages (

+    This,

+    Handle,

+    &LangCodes

+    );

+

+  for (Index = 0; LangCodes[Index] != 0; Index += 3) {

+    CopyMem (Lang, &LangCodes[Index], 6);

+    Lang[3] = 0;

+    Status = HiiNewString2 (

+              This,

+              Lang,

+              Handle,

+              &Reference,

+              &NewString,

+              TRUE

+              );

+

+  }

+

+  gBS->FreePool (LangCodes);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+HiiGetString (

+  IN     EFI_HII_PROTOCOL    *This,

+  IN     EFI_HII_HANDLE      Handle,

+  IN     STRING_REF          Token,

+  IN     BOOLEAN             Raw,

+  IN     CHAR16              *LanguageString,

+  IN OUT UINTN               *BufferLengthTemp,

+  OUT    EFI_STRING          StringBuffer

+  )

+/*++

+

+Routine Description:

+  

+  This function extracts a string from a package already registered with the EFI HII database.

+

+Arguments:

+  This            - A pointer to the EFI_HII_PROTOCOL instance.

+  Handle          - The HII handle on which the string resides.

+  Token           - The string token assigned to the string.

+  Raw             - If TRUE, the string is returned unedited in the internal storage format described

+                    above. If false, the string returned is edited by replacing <cr> with <space> 

+                    and by removing special characters such as the <wide> prefix.

+  LanguageString  - Pointer to a NULL-terminated string containing a single ISO 639-2 language

+                    identifier, indicating the language to print. If the LanguageString is empty (starts

+                    with a NULL), the default system language will be used to determine the language.

+  BufferLength    - Length of the StringBuffer. If the status reports that the buffer width is too

+                    small, this parameter is filled with the length of the buffer needed.

+  StringBuffer    - The buffer designed to receive the characters in the string. Type EFI_STRING is

+                    defined in String.

+

+Returns: 

+  EFI_INVALID_PARAMETER - If input parameter is invalid.

+  EFI_BUFFER_TOO_SMALL  - If the *BufferLength is too small.

+  EFI_SUCCESS           - Operation is successful.

+  

+--*/

+{

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_STRING_PACK       *StringPack;

+  RELOFST                   *StringPointer;

+  EFI_STATUS                Status;

+  UINTN                     DataSize;

+  CHAR8                     Lang[3];

+  CHAR16                    Language[3];

+  UINT32                    Length;

+  UINTN                     Count;

+  RELOFST                   Offset;

+  UINT16                    *Local;

+  UINT16                    Zero;

+  UINT16                    Narrow;

+  UINT16                    Wide;

+  UINT16                    NoBreak;

+  BOOLEAN                   LangFound;

+  UINT16                    *BufferLength = (UINT16 *) BufferLengthTemp;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  LangFound       = TRUE;

+

+  DataSize        = sizeof (Lang);

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  PackageInstance = NULL;

+  Zero            = 0;

+  Narrow          = NARROW_CHAR;

+  Wide            = WIDE_CHAR;

+  NoBreak         = NON_BREAKING_CHAR;

+

+  //

+  // Check numeric value against the head of the database

+  //

+  for (HandleDatabase = HiiData->DatabaseHead;

+       HandleDatabase != NULL;

+       HandleDatabase = HandleDatabase->NextHandleDatabase

+      ) {

+    //

+    // Match the numeric value with the database entry - if matched, extract PackageInstance

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+      break;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);

+

+  //

+  // If there is no specified language, assume the system default language

+  //

+  if (LanguageString == NULL) {

+    //

+    // Get system default language

+    //

+    Status = gRT->GetVariable (

+                    (CHAR16 *) L"Lang",

+                    &gEfiGlobalVariableGuid,

+                    NULL,

+                    &DataSize,

+                    Lang

+                    );

+

+    if (EFI_ERROR (Status)) {

+      //

+      // If Lang doesn't exist, just use the first language you find

+      //

+      LangFound = FALSE;

+      goto LangNotFound;

+    }

+    //

+    // Convert the ASCII Lang variable to a Unicode Language variable

+    //

+    AsciiToUnicode ((UINT8 *)Lang, Language);

+  } else {

+    //

+    // Copy input ISO value to Language variable

+    //

+    CopyMem (Language, LanguageString, 6);

+  }

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+LangNotFound:

+  if (StringPackageInstance->IfrSize > 0) {

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);

+  } else {

+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);

+  }

+  //

+  // If Token is 0, extract entire string package

+  //

+  if (Token == 0) {

+    //

+    // Compute the entire string pack length, including all languages' and the terminating pack's.

+    //

+    Length = 0;

+    while (0 != StringPack->Header.Length) {

+      Length += StringPack->Header.Length;

+      StringPack = (VOID*)(((UINT8*)StringPack) + StringPack->Header.Length);

+    }

+    //

+    // Back to the start of package.

+    //

+    StringPack = (VOID*)(((UINT8*)StringPack) - Length); 

+    //

+    // Terminating zero sub-pack.

+    //

+    Length += sizeof (EFI_HII_STRING_PACK); 

+

+    //

+    // If trying to get the entire string package and have insufficient space.  Return error.

+    //

+    if (Length > *BufferLength || StringBuffer == NULL) {

+      *BufferLength = (UINT16)Length;

+      return EFI_BUFFER_TOO_SMALL;

+    }

+    //

+    // Copy the Pack to the caller's buffer.

+    //

+    *BufferLength = (UINT16)Length;

+    CopyMem (StringBuffer, StringPack, Length);

+

+    return EFI_SUCCESS;

+  }

+  //

+  // There may be multiple instances packed together of strings

+  // so we must walk the self describing structures until we encounter

+  // what we are looking for, and then extract the string we are looking for

+  //

+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+  for (; Length != 0;) {

+    //

+    // If passed in Language ISO value is in this string pack's language string

+    // then we are dealing with the strings we want.

+    //

+    CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));

+    Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);

+

+    //

+    // If we cannot find the lang variable, we skip this check and use the first language available

+    //

+    if (LangFound) {

+      if (EFI_ERROR (Status)) {

+        StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);

+        CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));

+        continue;

+      }

+    }

+

+    StringPointer = (RELOFST *) (StringPack + 1);

+

+    //

+    // We have the right string package - size it, and copy it to the StringBuffer

+    //

+    if (Token >= StringPack->NumStringPointers) {

+      return EFI_INVALID_PARAMETER;

+    } else {

+      CopyMem (&Offset, &StringPointer[Token], sizeof (RELOFST));

+    }

+    //

+    // Since StringPack is a packed structure, we need to determine the string's

+    // size safely, thus byte-wise.  Post-increment the size to include the null-terminator

+    //

+    Local = (UINT16 *) ((CHAR8 *) (StringPack) + Offset);

+    for (Count = 0; CompareMem (&Local[Count], &Zero, 2); Count++)

+      ;

+    Count++;

+

+    Count = Count * sizeof (CHAR16);;

+

+    if (*BufferLength >= Count && StringBuffer != NULL) {

+      //

+      // Copy the string to the user's buffer

+      //

+      if (Raw) {

+        CopyMem (StringBuffer, Local, Count);

+      } else {

+        for (Count = 0; CompareMem (Local, &Zero, 2); Local++) {

+          //

+          // Skip "Narraw, Wide, NoBreak"

+          //

+          if (CompareMem (Local, &Narrow,  2) &&

+              CompareMem (Local, &Wide,    2) && 

+              CompareMem (Local, &NoBreak, 2)) {          

+            CopyMem (&StringBuffer[Count++], Local, 2);          

+          }        

+        } 

+        //

+        // Add "NULL" at the end.

+        //

+        CopyMem (&StringBuffer[Count], &Zero, 2);

+        Count++;

+        Count *= sizeof (CHAR16);

+      }

+

+      *BufferLength = (UINT16) Count;

+      return EFI_SUCCESS;

+    } else {

+      *BufferLength = (UINT16) Count;

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+  }

+

+  LangFound = FALSE;

+  goto LangNotFound;

+}

+

+EFI_STATUS

+EFIAPI

+HiiGetLine (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     EFI_HII_HANDLE     Handle,

+  IN     STRING_REF         Token,

+  IN OUT UINT16             *Index,

+  IN     UINT16             LineWidth,

+  IN     CHAR16             *LanguageString,

+  IN OUT UINT16             *BufferLength,

+  OUT    EFI_STRING         StringBuffer

+  )

+/*++

+

+Routine Description:

+

+  This function allows a program to extract a part of a string of not more than a given width.  

+  With repeated calls, this allows a calling program to extract "lines" of text that fit inside 

+  columns.  The effort of measuring the fit of strings inside columns is localized to this call.

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  UINTN                     Count;

+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;

+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;

+  EFI_HII_DATA              *HiiData;

+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;

+  EFI_HII_STRING_PACK       *StringPack;

+  RELOFST                   *StringPointer;

+  CHAR16                    *Location;

+  EFI_STATUS                Status;

+  UINTN                     DataSize;

+  CHAR8                     Lang[3];

+  CHAR16                    Language[3];

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  HiiData         = EFI_HII_DATA_FROM_THIS (This);

+

+  HandleDatabase  = HiiData->DatabaseHead;

+

+  PackageInstance = NULL;

+  DataSize        = 4;

+

+  //

+  // Check numeric value against the head of the database

+  //

+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {

+    //

+    // Match the numeric value with the database entry - if matched, extract PackageInstance

+    //

+    if (Handle == HandleDatabase->Handle) {

+      PackageInstance = HandleDatabase->Buffer;

+    }

+  }

+  //

+  // No handle was found - error condition

+  //

+  if (PackageInstance == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);

+

+  //

+  // If there is no specified language, assume the system default language

+  //

+  if (LanguageString == NULL) {

+    //

+    // Get system default language

+    //

+    Status = gRT->GetVariable (

+                    (CHAR16 *) L"Lang",

+                    &gEfiGlobalVariableGuid,

+                    NULL,

+                    &DataSize,

+                    Lang

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Convert the ASCII Lang variable to a Unicode Language variable

+    //

+    AsciiToUnicode ((UINT8 *)Lang, Language);

+  } else {

+    //

+    // Copy input ISO value to Language variable

+    //

+    CopyMem (Language, LanguageString, 6);

+  }

+  //

+  // Based on if there is IFR data in this package instance, determine

+  // what the location is of the beginning of the string data.

+  //

+  if (StringPackageInstance->IfrSize > 0) {

+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);

+  } else {

+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);

+  }

+

+  StringPointer = (RELOFST *) (StringPack + 1);

+

+  //

+  // There may be multiple instances packed together of strings

+  // so we must walk the self describing structures until we encounter

+  // what we are looking for, and then extract the string we are looking for

+  //

+  for (; StringPack->Header.Length != 0;) {

+    //

+    // If passed in Language ISO value is in this string pack's language string

+    // then we are dealing with the strings we want.

+    //

+    Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language);

+

+    if (EFI_ERROR (Status)) {

+      StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);

+      continue;

+    }

+

+    Location = (CHAR16 *) ((CHAR8 *) (StringPack) + StringPointer[Token] +*Index * 2);

+

+    //

+    // If the size of the remaining string is less than the LineWidth

+    // then copy the entire thing

+    //

+    if (StrSize (Location) <= LineWidth) {

+      if (*BufferLength >= StrSize (Location)) {

+        StrCpy (StringBuffer, Location);

+        return EFI_SUCCESS;

+      } else {

+        *BufferLength = (UINT16) StrSize (Location);

+        return EFI_BUFFER_TOO_SMALL;

+      }

+    } else {

+      //

+      // Rewind the string from the maximum size until we see a space the break the line

+      //

+      for (Count = LineWidth; Location[Count] != 0x0020; Count--)

+        ;

+

+      //

+      // Put the index at the next character

+      //

+      *Index = (UINT16) (Count + 1);

+

+      if (*BufferLength >= Count) {

+        StrnCpy (StringBuffer, Location, Count);

+        return EFI_SUCCESS;

+      } else {

+        *BufferLength = (UINT16) Count;

+        return EFI_BUFFER_TOO_SMALL;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+HiiCompareLanguage (

+  IN  CHAR16                *LanguageStringLocation,

+  IN  CHAR16                *Language

+  )

+{

+  UINT8   *Local;

+  UINTN   Index;

+  CHAR16  *InputString;

+  CHAR16  *OriginalInputString;

+

+  //

+  // Allocate a temporary buffer for InputString

+  //

+  InputString = AllocateZeroPool (0x100);

+

+  ASSERT (InputString);

+

+  OriginalInputString = InputString;

+

+  Local               = (UINT8 *) LanguageStringLocation;

+

+  //

+  // Determine the size of this packed string safely (e.g. access by byte), post-increment

+  // to include the null-terminator

+  //

+  for (Index = 0; Local[Index] != 0; Index = Index + 2)

+    ;

+  //

+  // MARMAR  Index = Index + 2;

+  //

+  // This is a packed structure that this location comes from, so let's make sure

+  // the value is aligned by copying it to a local variable and working on it.

+  //

+  CopyMem (InputString, LanguageStringLocation, Index);

+

+  for (Index = 0; Index < 3; Index++) {

+    InputString[Index]  = (CHAR16) (InputString[Index] | 0x20);

+    Language[Index]     = (CHAR16) (Language[Index] | 0x20);

+  }

+  //

+  // If the Language is the same return success

+  //

+  if (CompareMem (LanguageStringLocation, Language, 6) == 0) {

+    gBS->FreePool (InputString);

+    return EFI_SUCCESS;

+  }

+  //

+  // Skip the first three letters that comprised the primary language,

+  // see if what is being compared against is a secondary language

+  //

+  InputString = InputString + 3;

+

+  //

+  // If the Language is not the same as the Primary language, see if there are any

+  // secondary languages, and if there are see if we have a match.  If not, return an error.

+  //

+  for (Index = 0; InputString[Index] != 0; Index = Index + 3) {

+    //

+    // Getting in here means we have a secondary language

+    //

+    if (CompareMem (&InputString[Index], Language, 6) == 0) {

+      gBS->FreePool (InputString);

+      return EFI_SUCCESS;

+    }

+  }

+  //

+  // If nothing was found, return the error

+  //

+  gBS->FreePool (OriginalInputString);

+  return EFI_NOT_FOUND;

+

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml
new file mode 100644
index 0000000..f39f754
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/HiiDataBase/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="HiiDatabase"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/UserInterface/HiiDataBase/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="HiiDatabase">

+      <GenBuild baseName="HiiDatabase" mbdFilename="${MODULE_DIR}/HiiDatabase.mbd" msaFilename="${MODULE_DIR}/HiiDatabase.msa"/>

+   </target>

+   <target depends="HiiDatabase_clean" name="clean"/>

+   <target depends="HiiDatabase_cleanall" name="cleanall"/>

+   <target name="HiiDatabase_clean">

+      <OutputDirSetup baseName="HiiDatabase" mbdFilename="${MODULE_DIR}/HiiDatabase.mbd" msaFilename="${MODULE_DIR}/HiiDatabase.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/HiiDatabase_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/HiiDatabase_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="HiiDatabase_cleanall">

+      <OutputDirSetup baseName="HiiDatabase" mbdFilename="${MODULE_DIR}/HiiDatabase.mbd" msaFilename="${MODULE_DIR}/HiiDatabase.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/HiiDatabase_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/HiiDatabase_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**HiiDatabase*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Boolean.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Boolean.c
new file mode 100644
index 0000000..c7bcb88
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Boolean.c
@@ -0,0 +1,1360 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Boolean.c

+

+Abstract:

+

+  This routine will evaluate the IFR inconsistency data to determine if

+  something is a valid entry for a particular expression

+

+--*/

+

+#include "Setup.h"

+#include "Ui.h"

+

+//

+// Global stack used to evaluate boolean expresions

+//

+BOOLEAN *mBooleanEvaluationStack    = (BOOLEAN) 0;

+BOOLEAN *mBooleanEvaluationStackEnd = (BOOLEAN) 0;

+

+STATIC

+VOID

+GrowBooleanStack (

+  IN OUT BOOLEAN  **Stack,

+  IN     UINTN    StackSizeInBoolean

+  )

+/*++

+

+Routine Description:

+

+  Grow size of the boolean stack

+

+Arguments:

+

+  Stack     - Old stack on the way in and new stack on the way out

+

+  StackSizeInBoolean - New size of the stack

+

+Returns:

+

+  NONE 

+

+--*/

+{

+  BOOLEAN *NewStack;

+

+  NewStack = AllocatePool (StackSizeInBoolean * sizeof (BOOLEAN));

+  ASSERT (NewStack != NULL);

+

+  if (*Stack != NULL) {

+    //

+    // Copy to Old Stack to the New Stack

+    //

+    CopyMem (

+      NewStack,

+      mBooleanEvaluationStack,

+      (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN)

+      );

+

+    //

+    // Make the Stack pointer point to the old data in the new stack

+    //

+    *Stack = NewStack + (*Stack - mBooleanEvaluationStack);

+

+    //

+    // Free The Old Stack

+    //

+    gBS->FreePool (mBooleanEvaluationStack);

+  }

+

+  mBooleanEvaluationStack     = NewStack;

+  mBooleanEvaluationStackEnd  = NewStack + StackSizeInBoolean;

+}

+

+VOID

+InitializeBooleanEvaluator (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Allocate a global stack for boolean processing.

+

+Arguments:

+

+  NONE 

+

+Returns:

+

+  NONE 

+

+--*/

+{

+  BOOLEAN *NullStack;

+

+  NullStack = NULL;

+  GrowBooleanStack (&NullStack, 0x1000);

+}

+

+STATIC

+VOID

+PushBool (

+  IN OUT BOOLEAN  **Stack,

+  IN BOOLEAN      BoolResult

+  )

+/*++

+

+Routine Description:

+

+  Push an element onto the Boolean Stack

+

+Arguments:

+

+  Stack      - Current stack location.

+  BoolResult - BOOLEAN to push.

+

+Returns:

+

+  None.

+

+--*/

+{

+  CopyMem (*Stack, &BoolResult, sizeof (BOOLEAN));

+  *Stack += 1;

+

+  if (*Stack >= mBooleanEvaluationStackEnd) {

+    //

+    // If we run out of stack space make a new one that is 2X as big. Copy

+    // the old data into the new stack and update Stack to point to the old

+    // data in the new stack.

+    //

+    GrowBooleanStack (

+      Stack,

+      (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN) * 2

+      );

+  }

+}

+

+STATIC

+BOOLEAN

+PopBool (

+  IN OUT BOOLEAN **Stack

+  )

+/*++

+

+Routine Description:

+

+  Pop an element from the Boolean stack.

+

+Arguments:

+

+  Stack - Current stack location

+

+Returns:

+

+  Top of the BOOLEAN stack.

+

+--*/

+{

+  BOOLEAN ReturnValue;

+

+  *Stack -= 1;

+  CopyMem (&ReturnValue, *Stack, sizeof (BOOLEAN));

+  return ReturnValue;

+}

+

+EFI_STATUS

+GrowBooleanExpression (

+  IN      EFI_INCONSISTENCY_DATA  *InconsistentTags,

+  OUT     VOID                    **BooleanExpression,

+  IN OUT  UINTN                   *BooleanExpressionLength

+  )

+{

+  UINT8 *NewExpression;

+

+  NewExpression = AllocatePool (*BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA));

+  ASSERT (NewExpression != NULL);

+

+  if (*BooleanExpression != NULL) {

+    //

+    // Copy Old buffer to the New buffer

+    //

+    CopyMem (NewExpression, *BooleanExpression, *BooleanExpressionLength);

+

+    CopyMem (&NewExpression[*BooleanExpressionLength], InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));

+

+    //

+    // Free The Old buffer

+    //

+    gBS->FreePool (*BooleanExpression);

+  } else {

+    //

+    // Copy data into new buffer

+    //

+    CopyMem (NewExpression, InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));

+  }

+

+  *BooleanExpressionLength  = *BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA);

+  *BooleanExpression        = (VOID *) NewExpression;

+  return EFI_SUCCESS;

+}

+

+VOID

+CreateBooleanExpression (

+  IN  EFI_FILE_FORM_TAGS    *FileFormTags,

+  IN  UINT16                Value,

+  IN  UINT16                Id,

+  IN  BOOLEAN               Complex,

+  OUT VOID                  **BooleanExpression,

+  OUT UINTN                 *BooleanExpressionLength

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  UINTN                   Count;

+  EFI_INCONSISTENCY_DATA  *InconsistentTags;

+  EFI_INCONSISTENCY_DATA  FakeInconsistentTags;

+

+  InconsistentTags = FileFormTags->InconsistentTags;

+

+  //

+  // Did we run into a question that contains the Id we are looking for?

+  //

+  for (Count = 0; InconsistentTags->Operand != 0xFF; Count++) {

+

+    //

+    // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well

+    // as ideqid etc. but they have no coresponding id, so we reserve this value.

+    //

+    if (InconsistentTags->QuestionId1 == Id ||

+        InconsistentTags->QuestionId1 == INVALID_OFFSET_VALUE - 1) {

+      //

+      // If !Complex - means evaluate a single if/endif expression

+      //

+      if (!Complex) {

+        //

+        // If the ConsistencyId does not match the expression we are looking for

+        // skip to the next consistency database entry

+        //

+        if (InconsistentTags->ConsistencyId != Value) {

+          goto NextEntry;

+        }

+      }

+      //

+      // We need to rewind to the beginning of the Inconsistent expression

+      //

+      for (;

+           (InconsistentTags->Operand != EFI_IFR_INCONSISTENT_IF_OP) &&

+             (InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP) &&

+             (InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP);

+              ) {

+        InconsistentTags = InconsistentTags->Previous;

+      }

+      //

+      // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards

+      //

+      GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);

+      InconsistentTags = InconsistentTags->Next;

+

+      //

+      // Keep growing until we hit the End expression op-code or we hit the beginning of another

+      // consistency check like grayout/suppress

+      //

+      for (;

+           InconsistentTags->Operand != EFI_IFR_END_IF_OP &&

+           InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP &&

+           InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP;

+            ) {

+        GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);

+        InconsistentTags = InconsistentTags->Next;

+      }

+      //

+      // Store the EndExpression Op-code

+      //

+      GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);

+    }

+

+NextEntry:

+    if (InconsistentTags->Next != NULL) {

+      //

+      // Skip to next entry

+      //

+      InconsistentTags = InconsistentTags->Next;

+    }

+  }

+

+  FakeInconsistentTags.Operand = 0;

+

+  //

+  // Add one last expression which will signify we have definitely hit the end

+  //

+  GrowBooleanExpression (&FakeInconsistentTags, BooleanExpression, BooleanExpressionLength);

+}

+

+EFI_STATUS

+BooleanVariableWorker (

+  IN     CHAR16                   *VariableName,

+  IN     EFI_VARIABLE_DEFINITION  *VariableDefinition,

+  IN     BOOLEAN                  *StackPtr,

+  IN OUT UINTN                    *SizeOfVariable,

+  IN OUT VOID                     **VariableData

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = gRT->GetVariable (

+                  VariableName,

+                  &VariableDefinition->Guid,

+                  NULL,

+                  SizeOfVariable,

+                  *VariableData

+                  );

+

+  if (EFI_ERROR (Status)) {

+

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      *VariableData = AllocatePool (*SizeOfVariable);

+      ASSERT (*VariableData != NULL);

+

+      Status = gRT->GetVariable (

+                      VariableName,

+                      &VariableDefinition->Guid,

+                      NULL,

+                      SizeOfVariable,

+                      *VariableData

+                      );

+    }

+

+    if (Status == EFI_NOT_FOUND) {

+      //

+      // This is a serious flaw, we must have some standard result if a variable

+      // is not found.  Our default behavior must either be return a TRUE or FALSE

+      // since there is nothing else we can really do.  Therefore, my crystal ball

+      // says I will return a FALSE

+      //

+      PushBool (&StackPtr, FALSE);

+    }

+  }

+

+  return Status;

+}

+

+UINT8

+PredicateIfrType (

+  IN  EFI_INCONSISTENCY_DATA      *Iterator

+  )

+/*++

+

+Routine Description:

+  This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or

+  less than 1.88 which is legacy.

+

+Arguments:

+  Iterator    - The pointer to inconsistency tags

+

+Returns:

+

+  0x2         - If IFR is not legacy

+

+  0x1         - If IFR is legacy

+

+--*/

+{

+  //

+  // legacy Ifr cover the states:

+  // Not ...

+  // Operand Opcode Operand

+  //

+  // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,

+  // and Opcode means AND or OR.

+  //

+  if (Iterator->Operand == EFI_IFR_NOT_OP   ||

+      Iterator->Operand == 0) {

+    return 0x1;

+  } else if (Iterator->Operand == EFI_IFR_EQ_VAR_VAL_OP ||

+             Iterator->Operand == EFI_IFR_EQ_ID_VAL_OP  ||

+             Iterator->Operand == EFI_IFR_EQ_ID_ID_OP   ||

+             Iterator->Operand == EFI_IFR_EQ_ID_LIST_OP) {

+    Iterator++;

+    if (Iterator->Operand == EFI_IFR_AND_OP ||

+        Iterator->Operand == EFI_IFR_OR_OP) {

+      Iterator--;

+      return 0x1;

+    }

+    Iterator--;

+  }

+  return 0x2;

+}

+

+VOID

+PostOrderEvaluate (

+  IN      EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN      UINT16                      Width,

+  IN OUT  EFI_INCONSISTENCY_DATA      **PIterator,

+  IN OUT  BOOLEAN                     **StackPtr

+  )

+/*++

+

+Routine Description:

+  PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,

+  which generate Operand Operand Opcode type Ifr.

+  PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,

+  FALSE, >=, >, (, ) are supported.

+

+Arguments:

+

+  FileFormTags     - The pointer to the tags of the form

+

+  Width            - Width of Operand, recognized every iteration

+

+  PIterator        - The pointer to inconsistency tags

+

+  StackPtr         - The pointer to the evaluation stack

+

+Returns:

+

+  TRUE             - If value is valid

+

+  FALSE            - If value is not valid

+

+--*/

+{

+  BOOLEAN                 Operator;

+  BOOLEAN                 Operator2;

+  UINT16                  *MapBuffer;

+  UINT16                  *MapBuffer2;

+  UINT16                  MapValue;

+  UINT16                  MapValue2;

+  UINTN                   SizeOfVariable;

+  CHAR16                  VariableName[40];

+  VOID                    *VariableData;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+  EFI_STATUS              Status;

+  UINTN                   Index;

+  BOOLEAN                 PushValue;

+

+  Operator        = FALSE;

+  Operator2       = FALSE;

+  MapBuffer       = NULL;

+  MapBuffer2      = NULL;

+  MapValue        = 0;

+  MapValue2       = 0;

+  VariableData    = NULL;

+

+  while (TRUE) {

+    if ((*PIterator)->Operand == 0) {

+      return;

+    }

+

+    Width = (*PIterator)->Width;

+

+    // 

+    //  Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.

+    //

+    if ((*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE &&

+        (*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE - 1) {

+      ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber, Width, (*PIterator)->QuestionId1, (VOID **) &MapBuffer);

+      ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber2, Width, (*PIterator)->QuestionId2, (VOID **) &MapBuffer2);

+      if (MapBuffer != NULL) {

+        if (Width == 2) {

+          MapValue = *MapBuffer;

+        } else {

+          MapValue = (UINT8) *MapBuffer;

+        }

+

+        gBS->FreePool (MapBuffer);

+      }

+

+      if (MapBuffer2 != NULL) {

+        if (Width == 2) {

+          MapValue2 = *MapBuffer2;

+        } else {

+          MapValue2 = (UINT8) *MapBuffer2;

+        }

+

+        gBS->FreePool (MapBuffer2);

+      }

+    }

+

+    switch ((*PIterator)->Operand) {

+    case EFI_IFR_EQ_VAR_VAL_OP:

+      UnicodeValueToString (

+        VariableName, 

+        FALSE, 

+        (UINTN) (*PIterator)->QuestionId1, 

+        (sizeof (VariableName) / sizeof (VariableName[0]))

+        );

+

+      SizeOfVariable = 0;

+

+      ExtractRequestedNvMap (FileFormTags, (*PIterator)->VariableNumber, &VariableDefinition);

+

+      Status = BooleanVariableWorker (

+                VariableName,

+                VariableDefinition,

+                *StackPtr,

+                &SizeOfVariable,

+                &VariableData

+                );

+

+      if (!EFI_ERROR (Status)) {

+        if (SizeOfVariable == 1) {

+          CopyMem (&MapValue, VariableData, 1);

+        } else {

+          CopyMem (&MapValue, VariableData, 2);

+        }

+

+        //

+        // Do operation after knowing the compare operator.

+        //

+        MapValue2 = (*PIterator)->Value;

+        (*PIterator)++;

+        if ((*PIterator)->Operand == EFI_IFR_GT_OP) {

+          PushValue = (BOOLEAN) (MapValue > MapValue2);

+        } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {

+          PushValue = (BOOLEAN) (MapValue >= MapValue2);

+        } else {

+          (*PIterator)--;

+          PushValue = (BOOLEAN) (MapValue == MapValue2);

+        }

+        PushBool (StackPtr, PushValue);

+      }

+

+      break;

+

+    case EFI_IFR_EQ_ID_VAL_OP:

+      //

+      // Do operation after knowing the compare operator.

+      //

+      MapValue2 = (*PIterator)->Value;

+      (*PIterator)++;

+      if ((*PIterator)->Operand == EFI_IFR_GT_OP) {

+        PushValue = (BOOLEAN) (MapValue > MapValue2);

+      } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {

+        PushValue = (BOOLEAN) (MapValue >= MapValue2);

+      } else {

+        (*PIterator)--;

+        PushValue = (BOOLEAN) (MapValue == MapValue2);

+      }

+      PushBool (StackPtr, PushValue);

+      break;

+

+    case EFI_IFR_EQ_ID_ID_OP:

+      //

+      // Do operation after knowing the compare operator.

+      //

+      (*PIterator)++;

+      if ((*PIterator)->Operand == EFI_IFR_GT_OP) {

+        PushValue = (BOOLEAN) (MapValue > MapValue2);

+      } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {

+        PushValue = (BOOLEAN) (MapValue >= MapValue2);

+      } else {

+        (*PIterator)--;

+        PushValue = (BOOLEAN) (MapValue == MapValue2);

+      }

+      PushBool (StackPtr, PushValue);

+      break;

+

+    case EFI_IFR_EQ_ID_LIST_OP:

+      for (Index = 0; Index < (*PIterator)->ListLength; Index++) {

+        Operator = (BOOLEAN) (MapValue == (*PIterator)->ValueList[Index]);

+        if (Operator) {

+          break;

+        }

+      }

+

+      PushBool (StackPtr, Operator);

+      break;

+

+    case EFI_IFR_TRUE_OP:

+      PushBool (StackPtr, TRUE);

+      break;

+

+    case EFI_IFR_FALSE_OP:

+      PushBool (StackPtr, FALSE);

+      break;

+

+    case EFI_IFR_AND_OP:

+      Operator  = PopBool (StackPtr);

+      Operator2 = PopBool (StackPtr);

+      PushBool (StackPtr, (BOOLEAN) (Operator && Operator2));

+      break;

+    case EFI_IFR_OR_OP:

+      Operator  = PopBool (StackPtr);

+      Operator2 = PopBool (StackPtr);

+      PushBool (StackPtr, (BOOLEAN) (Operator || Operator2));

+      break;

+    case EFI_IFR_NOT_OP:

+      Operator  = PopBool (StackPtr);

+      PushBool (StackPtr, !Operator);

+      break;

+

+    case EFI_IFR_SUPPRESS_IF_OP:

+    case EFI_IFR_GRAYOUT_IF_OP:

+    case EFI_IFR_INCONSISTENT_IF_OP:

+    default:

+      //

+      // Return to the previous tag if runs out of boolean expression.

+      //

+      (*PIterator)--;

+      return;

+    }

+    (*PIterator)++;

+  }

+}

+

+BOOLEAN

+ValueIsNotValid (

+  IN  BOOLEAN                     Complex,

+  IN  UINT16                      Value,

+  IN  EFI_TAG                     *Tag,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  STRING_REF                  *PopUp

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+Returns:

+

+  TRUE - If value is valid

+

+  FALSE - If value is not valid

+

+--*/

+{

+  BOOLEAN                 *StackPtr;

+  EFI_INCONSISTENCY_DATA  *Iterator;

+  BOOLEAN                 Operator;

+  BOOLEAN                 Operator2;

+  UINTN                   Index;

+  VOID                    *BooleanExpression;

+  UINTN                   BooleanExpressionLength;

+  BOOLEAN                 NotOperator;

+  BOOLEAN                 OrOperator;

+  BOOLEAN                 AndOperator;

+  BOOLEAN                 ArtificialEnd;

+  UINT16                  *MapBuffer;

+  UINT16                  *MapBuffer2;

+  UINT16                  MapValue;

+  UINT16                  MapValue2;

+  UINTN                   SizeOfVariable;

+  CHAR16                  VariableName[40];

+  VOID                    *VariableData;

+  EFI_STATUS              Status;

+  UINT16                  Id;

+  UINT16                  Width;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+  BOOLEAN                 CosmeticConsistency;

+  UINT8                   IsLegacy;

+

+  VariableData            = NULL;

+  BooleanExpressionLength = 0;

+  BooleanExpression       = NULL;

+  Operator                = FALSE;

+  ArtificialEnd           = FALSE;

+  CosmeticConsistency     = TRUE;

+  IsLegacy                = 0;

+

+  Id                      = Tag->Id;

+  if (Tag->StorageWidth == 1) {

+    Width = 1;

+  } else {

+    Width = 2;

+  }

+  CreateBooleanExpression (FileFormTags, Value, Id, Complex, &BooleanExpression, &BooleanExpressionLength);

+

+  if (mBooleanEvaluationStack == 0) {

+    InitializeBooleanEvaluator ();

+  }

+

+  if (BooleanExpression == NULL) {

+    return FALSE;

+  }

+

+  StackPtr    = mBooleanEvaluationStack;

+  Iterator    = BooleanExpression;

+  MapBuffer   = NULL;

+  MapBuffer2  = NULL;

+  MapValue    = 0;

+  MapValue2   = 0;

+

+  while (TRUE) {

+    NotOperator = FALSE;

+    OrOperator  = FALSE;

+    AndOperator = FALSE;

+

+    if (Iterator->Operand == 0) {

+      return Operator;

+    }

+

+    // 

+    //  Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.

+    //

+    if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE &&

+        Iterator->QuestionId1 != INVALID_OFFSET_VALUE-1) {

+      ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);

+      ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);

+      if (MapBuffer != NULL) {

+        if (Width == 2) {

+          MapValue = *MapBuffer;

+        } else {

+          MapValue = (UINT8) *MapBuffer;

+        }

+

+        gBS->FreePool (MapBuffer);

+      }

+

+      if (MapBuffer2 != NULL) {

+        if (Width == 2) {

+          MapValue2 = *MapBuffer2;

+        } else {

+          MapValue2 = (UINT8) *MapBuffer2;

+        }

+

+        gBS->FreePool (MapBuffer2);

+      }

+    }

+

+    switch (Iterator->Operand) {

+    case EFI_IFR_SUPPRESS_IF_OP:

+      //

+      // Must have hit a suppress followed by a grayout or vice-versa

+      //

+      if (ArtificialEnd) {

+        ArtificialEnd = FALSE;

+        Operator      = PopBool (&StackPtr);

+        if (Operator) {

+          Tag->Suppress = TRUE;

+        }

+

+        return Operator;

+      }

+

+      ArtificialEnd = TRUE;

+      *PopUp        = Iterator->Popup;

+      break;

+

+    case EFI_IFR_GRAYOUT_IF_OP:

+      //

+      // Must have hit a suppress followed by a grayout or vice-versa

+      //

+      if (ArtificialEnd) {

+        ArtificialEnd = FALSE;

+        Operator      = PopBool (&StackPtr);

+        if (Operator) {

+          Tag->GrayOut = TRUE;

+        }

+

+        return Operator;

+      }

+

+      ArtificialEnd = TRUE;

+      *PopUp        = Iterator->Popup;

+      break;

+

+    case EFI_IFR_INCONSISTENT_IF_OP:

+      CosmeticConsistency = FALSE;

+      *PopUp              = Iterator->Popup;

+      break;

+

+    //

+    // In the case of external variable values, we must read the variable which is

+    // named by the human readable version of the OpCode->VariableId and the guid of the formset

+    //

+    case EFI_IFR_EQ_VAR_VAL_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+

+      UnicodeValueToString (

+        VariableName, 

+        FALSE, 

+        (UINTN) Iterator->QuestionId1, 

+        (sizeof (VariableName) / sizeof (VariableName[0]))

+        );

+

+      SizeOfVariable = 0;

+

+      ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

+

+      Status = BooleanVariableWorker (

+                VariableName,

+                VariableDefinition,

+                StackPtr,

+                &SizeOfVariable,

+                &VariableData

+                );

+

+      if (!EFI_ERROR (Status)) {

+        if (SizeOfVariable == 1) {

+          CopyMem (&MapValue, VariableData, 1);

+        } else {

+          CopyMem (&MapValue, VariableData, 2);

+        }

+

+        PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));

+      }

+

+      break;

+

+    case EFI_IFR_EQ_ID_VAL_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+

+      PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));

+      break;

+

+    case EFI_IFR_EQ_ID_ID_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+

+      PushBool (&StackPtr, (BOOLEAN) (MapValue == MapValue2));

+      break;

+

+    case EFI_IFR_EQ_ID_LIST_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+

+      for (Index = 0; Index < Iterator->ListLength; Index++) {

+        Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);

+        if (Operator) {

+          break;

+        }

+      }

+

+      PushBool (&StackPtr, Operator);

+      break;

+

+    case EFI_IFR_AND_OP:

+      Iterator++;

+      if (Iterator->Operand == EFI_IFR_NOT_OP) {

+        NotOperator = TRUE;

+        Iterator++;

+      }

+

+      if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {

+        ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);

+        ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);

+        if (MapBuffer != NULL) {

+          if (Width == 2) {

+            MapValue = *MapBuffer;

+          } else {

+            MapValue = (UINT8) *MapBuffer;

+          }

+

+          gBS->FreePool (MapBuffer);

+        }

+

+        if (MapBuffer2 != NULL) {

+          if (Width == 2) {

+            MapValue2 = *MapBuffer2;

+          } else {

+            MapValue2 = (UINT8) *MapBuffer2;

+          }

+

+          gBS->FreePool (MapBuffer2);

+        }

+      }

+

+      switch (Iterator->Operand) {

+      case EFI_IFR_EQ_ID_VAL_OP:

+        //

+        // If Not - flip the results

+        //

+        if (NotOperator) {

+          Operator = (BOOLEAN)!(MapValue == Iterator->Value);

+        } else {

+          Operator = (BOOLEAN) (MapValue == Iterator->Value);

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      //

+      // In the case of external variable values, we must read the variable which is

+      // named by the human readable version of the OpCode->VariableId and the guid of the formset

+      //

+      case EFI_IFR_EQ_VAR_VAL_OP:

+        UnicodeValueToString (

+          VariableName, 

+          FALSE, 

+          (UINTN) Iterator->QuestionId1, 

+          (sizeof (VariableName) / sizeof (VariableName[0]))

+          );

+

+        SizeOfVariable = 0;

+

+        ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

+

+        Status = BooleanVariableWorker (

+                  VariableName,

+                  VariableDefinition,

+                  StackPtr,

+                  &SizeOfVariable,

+                  &VariableData

+                  );

+

+        if (!EFI_ERROR (Status)) {

+          if (SizeOfVariable == 1) {

+            CopyMem (&MapValue, VariableData, 1);

+          } else {

+            CopyMem (&MapValue, VariableData, 2);

+          }

+          //

+          // If Not - flip the results

+          //

+          if (NotOperator) {

+            PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));

+          } else {

+            PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));

+          }

+        }

+        break;

+

+      case EFI_IFR_EQ_ID_ID_OP:

+        //

+        // If Not - flip the results

+        //

+        if (NotOperator) {

+          Operator = (BOOLEAN)!(MapValue == MapValue2);

+        } else {

+          Operator = (BOOLEAN) (MapValue == MapValue2);

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      case EFI_IFR_EQ_ID_LIST_OP:

+        for (Index = 0; Index < Iterator->ListLength; Index++) {

+          //

+          // If Not - flip the results

+          //

+          if (NotOperator) {

+            Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);

+          } else {

+            Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);

+          }

+          //

+          // If We are trying to make sure that MapValue != Item[x], keep looking through

+          // the list to make sure we don't equal any other items

+          //

+          if (Operator && NotOperator) {

+            continue;

+          }

+          //

+          // If MapValue == Item, then we have succeeded (first found is good enough)

+          //

+          if (Operator) {

+            break;

+          }

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      default:

+        return FALSE;

+      }

+

+      Operator  = PopBool (&StackPtr);

+      Operator2 = PopBool (&StackPtr);

+      PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));

+      break;

+

+    case EFI_IFR_OR_OP:

+      Iterator++;

+      if (Iterator->Operand == EFI_IFR_NOT_OP) {

+        NotOperator = TRUE;

+        Iterator++;

+      }

+

+      if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {

+        ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);

+        ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);

+        if (MapBuffer != NULL) {

+          if (Width == 2) {

+            MapValue = *MapBuffer;

+          } else {

+            MapValue = (UINT8) *MapBuffer;

+          }

+

+          gBS->FreePool (MapBuffer);

+        }

+

+        if (MapBuffer2 != NULL) {

+          if (Width == 2) {

+            MapValue2 = *MapBuffer2;

+          } else {

+            MapValue2 = (UINT8) *MapBuffer2;

+          }

+

+          gBS->FreePool (MapBuffer2);

+        }

+      }

+

+      switch (Iterator->Operand) {

+      case EFI_IFR_EQ_ID_VAL_OP:

+        //

+        // If Not - flip the results

+        //

+        if (NotOperator) {

+          Operator = (BOOLEAN)!(MapValue == Iterator->Value);

+        } else {

+          Operator = (BOOLEAN) (MapValue == Iterator->Value);

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      //

+      // In the case of external variable values, we must read the variable which is

+      // named by the human readable version of the OpCode->VariableId and the guid of the formset

+      //

+      case EFI_IFR_EQ_VAR_VAL_OP:

+        UnicodeValueToString (

+          VariableName, 

+          FALSE, 

+          (UINTN) Iterator->QuestionId1, 

+          (sizeof (VariableName) / sizeof (VariableName[0]))

+          );

+

+        SizeOfVariable = 0;

+

+        ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

+

+        Status = BooleanVariableWorker (

+                  VariableName,

+                  VariableDefinition,

+                  StackPtr,

+                  &SizeOfVariable,

+                  &VariableData

+                  );

+

+        if (!EFI_ERROR (Status)) {

+          if (SizeOfVariable == 1) {

+            CopyMem (&MapValue, VariableData, 1);

+          } else {

+            CopyMem (&MapValue, VariableData, 2);

+          }

+          //

+          // If Not - flip the results

+          //

+          if (NotOperator) {

+            PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));

+          } else {

+            PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));

+          }

+        }

+        break;

+

+      case EFI_IFR_EQ_ID_ID_OP:

+        //

+        // If Not - flip the results

+        //

+        if (NotOperator) {

+          Operator = (BOOLEAN)!(MapValue == MapValue2);

+        } else {

+          Operator = (BOOLEAN) (MapValue == MapValue2);

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      case EFI_IFR_EQ_ID_LIST_OP:

+        for (Index = 0; Index < Iterator->ListLength; Index++) {

+          //

+          // If Not - flip the results

+          //

+          if (NotOperator) {

+            Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);

+          } else {

+            Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);

+          }

+          //

+          // If We are trying to make sure that MapValue != Item[x], keep looking through

+          // the list to make sure we don't equal any other items

+          //

+          if (Operator && NotOperator) {

+            continue;

+          }

+          //

+          // If MapValue == Item, then we have succeeded (first found is good enough)

+          //

+          if (Operator) {

+            break;

+          }

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      default:

+        return FALSE;

+      }

+

+      Operator  = PopBool (&StackPtr);

+      Operator2 = PopBool (&StackPtr);

+      PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));

+      break;

+

+    case EFI_IFR_NOT_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+

+      //

+      // I don't need to set the NotOperator (I know that I have to NOT this in this case

+      //

+      Iterator++;

+

+      if (Iterator->Operand == EFI_IFR_OR_OP) {

+        OrOperator = TRUE;

+        Iterator++;

+      }

+

+      if (Iterator->Operand == EFI_IFR_AND_OP) {

+        AndOperator = TRUE;

+        Iterator++;

+      }

+

+      if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {

+        ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);

+        ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);

+        if (MapBuffer != NULL) {

+          if (Width == 2) {

+            MapValue = *MapBuffer;

+          } else {

+            MapValue = (UINT8) *MapBuffer;

+          }

+

+          gBS->FreePool (MapBuffer);

+        }

+

+        if (MapBuffer2 != NULL) {

+          if (Width == 2) {

+            MapValue2 = *MapBuffer2;

+          } else {

+            MapValue2 = (UINT8) *MapBuffer2;

+          }

+

+          gBS->FreePool (MapBuffer2);

+        }

+      }

+

+      switch (Iterator->Operand) {

+      case EFI_IFR_EQ_ID_VAL_OP:

+        Operator = (BOOLEAN)!(MapValue == Iterator->Value);

+        PushBool (&StackPtr, Operator);

+        break;

+

+      //

+      // In the case of external variable values, we must read the variable which is

+      // named by the human readable version of the OpCode->VariableId and the guid of the formset

+      //

+      case EFI_IFR_EQ_VAR_VAL_OP:

+        UnicodeValueToString (

+          VariableName, 

+          FALSE, 

+          (UINTN) Iterator->QuestionId1, 

+          (sizeof (VariableName) / sizeof (VariableName[0]))

+          );

+

+        SizeOfVariable = 0;

+

+        ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

+

+        Status = BooleanVariableWorker (

+                  VariableName,

+                  VariableDefinition,

+                  StackPtr,

+                  &SizeOfVariable,

+                  &VariableData

+                  );

+

+        if (!EFI_ERROR (Status)) {

+          if (SizeOfVariable == 1) {

+            CopyMem (&MapValue, VariableData, 1);

+          } else {

+            CopyMem (&MapValue, VariableData, 2);

+          }

+

+          PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));

+        }

+        break;

+

+      case EFI_IFR_EQ_ID_ID_OP:

+        Operator = (BOOLEAN)!(MapValue == MapValue2);

+        PushBool (&StackPtr, Operator);

+        break;

+

+      case EFI_IFR_EQ_ID_LIST_OP:

+        for (Index = 0; Index < Iterator->ListLength; Index++) {

+          Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);

+          if (Operator) {

+            continue;

+          }

+        }

+

+        PushBool (&StackPtr, Operator);

+        break;

+

+      default:

+        return FALSE;

+      }

+

+      Operator  = PopBool (&StackPtr);

+      Operator2 = PopBool (&StackPtr);

+

+      if (OrOperator) {

+        PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));

+      }

+

+      if (AndOperator) {

+        PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));

+      }

+

+      if (!OrOperator && !AndOperator) {

+        PushBool (&StackPtr, Operator);

+      }

+      break;

+    

+    case EFI_IFR_TRUE_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+      break;

+

+    case EFI_IFR_FALSE_OP:

+      //

+      // To check whether Ifr is legacy. Once every boolean expression.

+      //

+      if (IsLegacy == 0) {

+        IsLegacy = PredicateIfrType (Iterator);

+      }

+      if (IsLegacy == 0x2) {

+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);

+        break;

+      }

+      break;

+

+    case EFI_IFR_END_IF_OP:

+      Operator = PopBool (&StackPtr);

+      //

+      // If there is an error, return, otherwise keep looking - there might

+      // be another test that causes an error

+      //

+      if (Operator) {

+        if (Complex && CosmeticConsistency) {

+          return EFI_SUCCESS;

+        } else {

+          return Operator;

+        }

+      } else {

+        //

+        // If not doing a global consistency check, the endif is the REAL terminator of this operation

+        // This is used for grayout/suppress operations.  InconsistentIf is a global operation so the EndIf is

+        // not the end-all be-all of terminators.

+        //

+        if (!Complex) {

+          return Operator;

+        }

+        break;

+      }

+

+    default:

+      //

+      // Must have hit a non-consistency related op-code after a suppress/grayout

+      //

+      if (ArtificialEnd) {

+        ArtificialEnd = FALSE;

+        Operator      = PopBool (&StackPtr);

+        return Operator;

+      }

+

+      return FALSE;

+    }

+

+    Iterator++;

+  }

+

+  return FALSE;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Colors.h b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Colors.h
new file mode 100644
index 0000000..c1f5441
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Colors.h
@@ -0,0 +1,54 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Colors.h

+

+Abstract:

+

+

+Revision History

+

+--*/

+

+#ifndef _COLORS_H

+#define _COLORS_H

+

+//

+// Screen Color Settings

+//

+#define PICKLIST_HIGHLIGHT_TEXT       EFI_WHITE

+#define PICKLIST_HIGHLIGHT_BACKGROUND EFI_BACKGROUND_CYAN

+#define TITLE_TEXT                    EFI_WHITE

+#define TITLE_BACKGROUND              EFI_BACKGROUND_BLUE

+#define KEYHELP_TEXT                  EFI_LIGHTGRAY

+#define KEYHELP_BACKGROUND            EFI_BACKGROUND_BLACK

+#define SUBTITLE_TEXT                 EFI_BLUE

+#define SUBTITLE_BACKGROUND           EFI_BACKGROUND_LIGHTGRAY

+#define BANNER_TEXT                   EFI_BLUE

+#define BANNER_BACKGROUND             EFI_BACKGROUND_LIGHTGRAY

+#define FIELD_TEXT                    EFI_BLACK

+#define FIELD_TEXT_GRAYED             EFI_DARKGRAY

+#define FIELD_BACKGROUND              EFI_BACKGROUND_LIGHTGRAY

+#define FIELD_TEXT_HIGHLIGHT          EFI_LIGHTGRAY

+#define FIELD_BACKGROUND_HIGHLIGHT    EFI_BACKGROUND_BLACK

+#define POPUP_TEXT                    EFI_LIGHTGRAY

+#define POPUP_BACKGROUND              EFI_BACKGROUND_BLUE

+#define POPUP_INVERSE_TEXT            EFI_LIGHTGRAY

+#define POPUP_INVERSE_BACKGROUND      EFI_BACKGROUND_BLACK

+#define HELP_TEXT                     EFI_BLUE

+#define ERROR_TEXT                    EFI_RED | EFI_BRIGHT

+#define INFO_TEXT                     EFI_YELLOW | EFI_BRIGHT

+#define ARROW_TEXT                    EFI_RED | EFI_BRIGHT

+#define ARROW_BACKGROUND              EFI_BACKGROUND_LIGHTGRAY

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.c
new file mode 100644
index 0000000..5f3823c
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.c
@@ -0,0 +1,631 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  DriverSample.c

+

+Abstract:

+

+  This is an example of how a driver might export data to the HII protocol to be 

+  later utilized by the Setup Protocol

+

+--*/

+

+#include "DriverSample.h"

+

+#define DISPLAY_ONLY_MY_ITEM  0x0001

+

+#define STRING_PACK_GUID \

+  { \

+    0x8160a85f, 0x934d, 0x468b, { 0xa2, 0x35, 0x72, 0x89, 0x59, 0x14, 0xf6, 0xfc } \

+  }

+

+EFI_GUID  mFormSetGuid    = FORMSET_GUID;

+EFI_GUID  mStringPackGuid = STRING_PACK_GUID; 

+

+EFI_STATUS

+EFIAPI

+DriverCallback (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *Data,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+/*++

+

+Routine Description:

+

+  This is the function that is called to provide results data to the driver.  This data

+  consists of a unique key which is used to identify what data is either being passed back

+  or being asked for. 

+

+Arguments:

+

+  KeyValue -        A unique value which is sent to the original exporting driver so that it

+                    can identify the type of data to expect.  The format of the data tends to

+                    vary based on the op-code that geerated the callback.

+

+  Data -            A pointer to the data being sent to the original exporting driver.

+

+Returns: 

+

+--*/

+{

+  EFI_CALLBACK_INFO       *Private;

+  EFI_HII_UPDATE_DATA     *UpdateData;

+  EFI_STATUS              Status;

+  UINT8                   *Location;

+  EFI_HII_CALLBACK_PACKET *DataPacket;

+  UINT16                  Value;

+  CHAR16                  VariableName[40];

+  STATIC UINT16           QuestionId = 0;

+  IFR_OPTION              *OptionList;

+  UINTN                   Index;

+  MyIfrNVData             NVStruc;

+

+  Private     = EFI_CALLBACK_INFO_FROM_THIS (This);

+

+  //

+  // This should tell me the first offset AFTER the end of the compiled NV map

+  // If op-code results are not going to be saved to NV locations ensure the QuestionId

+  // is beyond the end of the NVRAM mapping.

+  //

+  if (QuestionId == 0) {

+    QuestionId = sizeof (MyIfrNVData);

+  }

+

+  ZeroMem (VariableName, (sizeof (CHAR16) * 40));

+

+  switch (KeyValue) {

+  case 0x0001:

+    //

+    // Create a small boot order list

+    //

+    QuestionId = (UINT16) ((UINTN) (&NVStruc.BootOrder) - (UINTN) (&NVStruc));

+

+    //

+    // Need some memory for OptionList. Allow for up to 8 options.

+    //

+    OptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 8);

+

+    //

+    // Allocate space for creation of Buffer

+    //

+    UpdateData = AllocateZeroPool (0x1000);

+

+    //

+    // Remove all the op-codes starting with Label 0x2222 to next Label (second label is for convenience

+    // so we don't have to keep track of how many op-codes we added or subtracted.  The rules for removal

+    // of op-codes are simply that the removal will always stop as soon as a label or the end of a form is

+    // encountered.  Therefore, giving a large obnoxious count such as below takes care of other complexities.

+    //

+    UpdateData->DataCount = 0xFF;

+

+    //

+    // Delete set of op-codes

+    //

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x2222,

+                    FALSE,  // If we aren't adding, we are deleting

+                    UpdateData

+                    );

+

+    //

+    // Create 3 options

+    //

+    for (Index = 0; Index < 3; Index++) {

+      OptionList[Index].StringToken = (UINT16) (STR_BOOT_OPTION1 + Index);

+      OptionList[Index].Value       = (UINT16) (Index + 1);

+      OptionList[Index].Flags       = RESET_REQUIRED;

+    }

+

+    CreateOrderedListOpCode (

+      QuestionId,                               // Question ID

+      8,                                        // Max Entries

+      (UINT16) STRING_TOKEN (STR_BOOT_OPTIONS), // Token value for the Prompt

+      (UINT16) STRING_TOKEN (STR_NULL_STRING),  // Token value for the Help

+      OptionList,

+      3,

+      &UpdateData->Data                         // Buffer location to place op-codes

+      );

+

+    //

+    // For one-of/ordered lists commands, they really consist of 2 op-codes (a header and a footer)

+    // Each option within a one-of/ordered list is also an op-code

+    // So this example has 5 op-codes it is adding since we have a one-of header + 3 options + one-of footer

+    //

+    UpdateData->DataCount = 0x5;

+

+    //

+    // Add one op-code

+    //

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x2222,

+                    TRUE,

+                    UpdateData

+                    );

+

+    gBS->FreePool (UpdateData);

+    gBS->FreePool (OptionList);

+    break;

+

+  case 0x0002:

+    //

+    // Create a large boot order list

+    //

+    QuestionId = (UINT16) ((UINTN) (&NVStruc.BootOrder) - (UINTN) (&NVStruc));

+

+    //

+    // Need some memory for OptionList. Allow for up to 8 options.

+    //

+    OptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 8);

+

+    //

+    // Allocate space for creation of Buffer

+    //

+    UpdateData = AllocateZeroPool (0x1000);

+

+    //

+    // Remove all the op-codes starting with Label 0x2222 to next Label (second label is for convenience

+    // so we don't have to keep track of how many op-codes we added or subtracted

+    //

+    UpdateData->DataCount = 0xFF;

+

+    //

+    // Delete one op-code

+    //

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x2222,

+                    FALSE,

+                    UpdateData

+                    );

+

+    //

+    // Create 4 options

+    //

+    for (Index = 0; Index < 4; Index++) {

+      OptionList[Index].StringToken = (UINT16) (STR_BOOT_OPTION1 + Index);

+      OptionList[Index].Value       = (UINT16) (Index + 1);

+      OptionList[Index].Flags       = RESET_REQUIRED;

+    }

+

+    CreateOrderedListOpCode (

+      QuestionId,                               // Question ID

+      8,                                        // Max Entries

+      (UINT16) STRING_TOKEN (STR_BOOT_OPTIONS), // Token value for the Prompt

+      (UINT16) STRING_TOKEN (STR_NULL_STRING),  // Token value for the Help

+      OptionList,

+      4,

+      &UpdateData->Data                         // Buffer location to place op-codes

+      );

+

+    //

+    // For one-of commands, they really consist of 2 op-codes (a header and a footer)

+    // Each option within a one-of is also an op-code

+    // So this example has 6 op-codes it is adding since we have a one-of header + 4 options + one-of footer

+    //

+    UpdateData->DataCount = 0x6;

+

+    //

+    // Add one op-code

+    //

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x2222,

+                    TRUE,

+                    UpdateData

+                    );

+

+    gBS->FreePool (UpdateData);

+    gBS->FreePool (OptionList);

+    break;

+

+  case 0x1234:

+    //

+    // Allocate space for creation of Buffer

+    //

+    QuestionId = (UINT16) ((UINTN) (&NVStruc.DynamicCheck));

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    0x1000,

+                    (VOID **) &UpdateData

+                    );

+

+    ZeroMem (UpdateData, 0x1000);

+

+    Location                        = (UINT8 *) &UpdateData->Data;

+

+    UpdateData->FormSetUpdate       = TRUE;

+    UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->CallbackHandle;

+    UpdateData->FormUpdate          = FALSE;

+    UpdateData->FormTitle           = 0;

+    UpdateData->DataCount           = 2;

+

+    CreateGotoOpCode (

+      1,

+      STR_GOTO_FORM1,                                   // Token value for the Prompt

+      0,                                                // Goto Help

+      0,                                                // Flags

+      0,                                                // Key

+      &UpdateData->Data                                 // Buffer location to place op-codes

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) &UpdateData->Data)->Length;

+

+    CreateCheckBoxOpCode (

+      QuestionId,                                       // Question ID

+      1,                                                // Data width (BOOLEAN = 1)

+      (UINT16) STRING_TOKEN (STR_CHECK_DYNAMIC_PROMPT), // Token value for the Prompt

+      (UINT16) STRING_TOKEN (STR_CHECK_DYNAMIC_HELP),   // Token value for the Help

+      EFI_IFR_FLAG_INTERACTIVE,                         // Flags

+      0x1236,   // Key

+      Location  // Buffer location to place op-codes

+      );

+

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x1234,

+                    TRUE,

+                    UpdateData

+                    );

+

+    gBS->FreePool (UpdateData);

+    QuestionId++;

+    break;

+

+  case 0x1235:

+    //

+    // Allocate space for creation of Buffer

+    //

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    0x1000,

+                    (VOID **)&UpdateData

+                    );

+

+    ZeroMem (UpdateData, 0x1000);

+

+    //

+    // Initialize DataPacket with information intended to remove all

+    // previously created op-codes in the dynamic page

+    //

+    UpdateData->FormSetUpdate       = FALSE;

+    UpdateData->FormCallbackHandle  = 0;

+    UpdateData->FormUpdate          = FALSE;

+    UpdateData->FormTitle           = 0;

+    //

+    // Unlikely to be more than 0xff op-codes in the dynamic page to remove

+    //

+    UpdateData->DataCount           = 0xff;

+    UpdateData->Data = NULL;

+

+    //

+    // Remove all op-codes from dynamic page

+    //

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x1234,  // Label 0x1234

+                    FALSE,                    // Remove Op-codes (will never remove form/endform)

+                    UpdateData                // Significant value is UpdateData->DataCount

+                    );

+

+    UpdateData->FormSetUpdate       = FALSE;

+    UpdateData->FormCallbackHandle  = 0;

+    UpdateData->FormUpdate          = FALSE;

+    UpdateData->FormTitle           = 0;

+    UpdateData->DataCount           = 1;

+

+    CreateGotoOpCode (

+      1,

+      STR_GOTO_FORM1,                         // Token value for the Prompt

+      0,                                      // Goto Help

+      0,                                      // Flags

+      0,                                      // Key

+      &UpdateData->Data                       // Buffer location to place op-codes

+      );

+

+    Private->Hii->UpdateForm (

+                    Private->Hii,

+                    Private->RegisteredHandle,

+                    (EFI_FORM_LABEL) 0x1234,

+                    TRUE,

+                    UpdateData

+                    );

+

+    gBS->FreePool (UpdateData);

+    break;

+

+  case 0x1236:

+    //

+    // If I hit the checkbox, I enter this case statement...

+    //

+    //

+    // Since I am returning an error (for test purposes) I need to pass in the string for the error

+    // I will allocate space for the return value.  If an error occurs (which is the case) I can simply return

+    // an error and fill in the string parameter, otherwise, I will return information in the DataArray structure.

+    // The browser will free this packet structure

+    //

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (EFI_HII_CALLBACK_PACKET) + sizeof (SAMPLE_STRING) + 2,

+                    (VOID **) Packet

+                    );

+

+    ZeroMem (*Packet, sizeof (EFI_HII_CALLBACK_PACKET) + sizeof (SAMPLE_STRING) + 2);

+

+    //

+    // Assign the buffer address to DataPacket

+    //

+    DataPacket = *Packet;

+

+    StrCpy (DataPacket->String, (CHAR16 *) SAMPLE_STRING);

+    return EFI_DEVICE_ERROR;

+

+  case 0x1237:

+

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (EFI_HII_CALLBACK_PACKET) + 2,

+                    (VOID **) Packet

+                    );

+

+    ZeroMem (*Packet, sizeof (EFI_HII_CALLBACK_PACKET) + 2);

+

+    //

+    // Assign the buffer address to DataPacket

+    //

+    DataPacket                        = *Packet;

+

+    DataPacket->DataArray.EntryCount  = 1;

+    DataPacket->DataArray.NvRamMap    = NULL;

+    ((EFI_IFR_DATA_ENTRY *) (&DataPacket->DataArray + 1))->Flags = EXIT_REQUIRED;

+    break;

+

+  case 0x1555:

+    Value = 0x0001;

+    UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);

+

+    Status = gRT->SetVariable (

+                    VariableName,

+                    &mFormSetGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    2,

+                    (VOID *) &Value

+                    );

+    break;

+

+  case 0x1556:

+    Value = 0x1000;

+    UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);

+

+    Status = gRT->SetVariable (

+                    VariableName,

+                    &mFormSetGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    2,

+                    (VOID *) &Value

+                    );

+    break;

+

+  case 0x1557:

+    Value = 0x0000;

+    UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);

+

+    Status = gRT->SetVariable (

+                    VariableName,

+                    &mFormSetGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    2,

+                    (VOID *) &Value

+                    );

+    break;

+

+  default:

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DriverSampleInit (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  )

+{

+  EFI_STATUS          Status;

+  EFI_HII_PROTOCOL    *Hii;

+  //

+  //  EFI_FORM_BROWSER_PROTOCOL       *FormConfig;

+  //

+  EFI_HII_PACKAGES    *PackageList;

+  EFI_HII_HANDLE      HiiHandle;

+  STRING_REF          TokenToUpdate;

+  STRING_REF          TokenToUpdate2;

+  STRING_REF          TokenToUpdate3;

+  CHAR16              *NewString;

+  EFI_HII_UPDATE_DATA *UpdateData;

+  EFI_CALLBACK_INFO   *CallbackInfo;

+  EFI_HANDLE          Handle;

+  EFI_SCREEN_DESCRIPTOR   Screen;

+

+  ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));

+

+  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);

+

+  //

+  // Remove 3 characters from top and bottom

+  //

+  Screen.TopRow     = 3;

+  Screen.BottomRow  = Screen.BottomRow - 3;

+

+  //

+  // There should only be one HII protocol

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  (VOID **) &Hii

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;;

+  }

+

+  /*

+  //

+  // There should only be one Form Configuration protocol

+  //

+  Status = gBS->LocateProtocol (

+                 &gEfiFormBrowserProtocolGuid, 

+                 NULL, 

+                 &FormConfig

+                 );

+  if (EFI_ERROR (Status)) {

+    return Status;;

+  }

+*/

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_CALLBACK_INFO),

+                  (VOID **) &CallbackInfo

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;

+  CallbackInfo->Hii       = Hii;

+

+  //

+  // This example does not implement worker functions for the NV accessor functions.  Only a callback evaluator

+  //

+  CallbackInfo->DriverCallback.NvRead   = NULL;

+  CallbackInfo->DriverCallback.NvWrite  = NULL;

+  CallbackInfo->DriverCallback.Callback = DriverCallback;

+

+  //

+  // Install protocol interface

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiFormCallbackProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &CallbackInfo->DriverCallback

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  CallbackInfo->CallbackHandle  = Handle;

+

+  PackageList                   = PreparePackages (1, &mStringPackGuid, DriverSampleStrings);

+  Status                        = Hii->NewPack (Hii, PackageList, &HiiHandle);

+  gBS->FreePool (PackageList);

+

+  PackageList = PreparePackages (1, &mStringPackGuid, InventoryBin);

+  Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);

+  gBS->FreePool (PackageList);

+

+  PackageList = PreparePackages (1, &mStringPackGuid, VfrBin);

+  Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);

+  gBS->FreePool (PackageList);

+

+  CallbackInfo->RegisteredHandle = HiiHandle;

+

+  //

+  // Very simple example of how one would update a string that is already

+  // in the HII database

+  //

+  TokenToUpdate = (STRING_REF) STR_CPU_STRING2;

+  NewString     = (CHAR16 *) L"700 Mhz";

+

+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate, NewString);

+

+  //

+  // Add a string - if 0 will be updated with new Token number

+  //

+  TokenToUpdate = (STRING_REF) 0;

+

+  //

+  // Add a string - if 0 will be updated with new Token number

+  //

+  TokenToUpdate2 = (STRING_REF) 0;

+

+  //

+  // Add a string - if 0 will be updated with new Token number

+  //

+  TokenToUpdate3 = (STRING_REF) 0;

+

+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate, (CHAR16 *) L"Desired Speed");

+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate2, (CHAR16 *) L"5 Thz");

+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate3, (CHAR16 *) L"This is next year's desired speed - right?");

+

+  //

+  // Allocate space for creation of Buffer

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  0x1000,

+                  (VOID **) &UpdateData

+                  );

+

+  ZeroMem (UpdateData, 0x1000);

+

+  //

+  // Flag update pending in FormSet

+  //

+  UpdateData->FormSetUpdate = TRUE;

+  //

+  // Register CallbackHandle data for FormSet

+  //

+  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackInfo->CallbackHandle;

+  UpdateData->FormUpdate  = FALSE;

+  UpdateData->FormTitle   = 0;

+  UpdateData->DataCount   = 1;

+

+  CreateTextOpCode (TokenToUpdate, TokenToUpdate2, TokenToUpdate3, 0, 0, &UpdateData->Data);

+

+  Hii->UpdateForm (Hii, HiiHandle, (EFI_FORM_LABEL) 100, TRUE, UpdateData);

+

+  gBS->FreePool (UpdateData);

+

+  //

+  // Example of how to display only the item we sent to HII

+  //

+  if (DISPLAY_ONLY_MY_ITEM == 0x0001) {

+    //

+    // Have the browser pull out our copy of the data, and only display our data

+    //

+    //    Status = FormConfig->SendForm (FormConfig, TRUE, HiiHandle, NULL, NULL, NULL, &Screen, NULL);

+    //

+  } else {

+    //

+    // Have the browser pull out all the data in the HII Database and display it.

+    //

+    //    Status = FormConfig->SendForm (FormConfig, TRUE, 0, NULL, NULL, NULL, NULL, NULL);

+    //

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.h b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.h
new file mode 100644
index 0000000..b1534e8
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.h
@@ -0,0 +1,60 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DriverSample.h

+

+Abstract:

+

+

+Revision History

+

+--*/

+

+#ifndef _DRIVER_SAMPLE_H

+#define _DRIVER_SAMPLE_H

+

+

+#include "NVDataStruc.h"

+

+//

+// This is the generated header file which includes whatever needs to be exported (strings + IFR)

+//

+#include "DriverSampleStrDefs.h"

+

+extern UINT8  VfrBin[];

+//

+// extern UINT8 VfrStringsStr[];

+//

+extern UINT8  InventoryBin[];

+//

+// extern UINT8 InventoryStringsStr[];

+//

+extern UINT8  DriverSampleStrings[];

+

+#define SAMPLE_STRING               L"This is an error!"

+

+#define EFI_CALLBACK_INFO_SIGNATURE EFI_SIGNATURE_32 ('C', 'l', 'b', 'k')

+

+typedef struct {

+  UINTN                       Signature;

+  EFI_HANDLE                  CallbackHandle;

+  EFI_FORM_CALLBACK_PROTOCOL  DriverCallback;

+  UINT16                      *KeyList;

+  VOID                        *FormBuffer;

+  EFI_HII_HANDLE              RegisteredHandle;

+  EFI_HII_PROTOCOL            *Hii;

+} EFI_CALLBACK_INFO;

+

+#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, DriverCallback, EFI_CALLBACK_INFO_SIGNATURE)

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.mbd b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.mbd
new file mode 100644
index 0000000..c77f09b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>DriverSample</BaseName>

+    <Guid>FE3542FE-C1D3-4EF8-657C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibNull</Library>

+    <Library>BasePrintLib</Library>

+    <Library>EdkGraphicsLib</Library>

+    <Library>EdkIfrSupportLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>HiiLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.msa b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.msa
new file mode 100644
index 0000000..ab43a63
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/DriverSample.msa
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>DriverSample</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>FE3542FE-C1D3-4EF8-657C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkGraphicsLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkIfrSupportLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>InventoryStrings.uni</Filename>

+    <Filename>Inventory.vfr</Filename>

+    <Filename>VfrStrings.uni</Filename>

+    <Filename>Vfr.vfr</Filename>

+    <Filename>DriverSample.c</Filename>

+    <Filename>DriverSample.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">UgaDraw</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">OEMBadging</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolume</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ConsoleControl</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">FormCallback</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable Usage="ALWAYS_PRODUCED">

+      <String>L"256"</String>

+      <Guid>0xA04A27f4, 0xDF00, 0x4D42, { 0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D }</Guid>

+    </Variable>

+  </Variables>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>GlobalVariable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>DriverSampleInit</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/Inventory.vfr b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/Inventory.vfr
new file mode 100644
index 0000000..ff8a6aa
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/Inventory.vfr
@@ -0,0 +1,123 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   Inventory.vfr 

+// 

+// Abstract:

+// 

+//   Sample Inventory Data.

+// 

+// Revision History: 

+// 

+// --*/

+

+#include "DriverSampleStrDefs.h"

+

+#define INVENTORY_GUID    { 0xb3f56470, 0x6141, 0x4621, { 0x8f, 0x19, 0x70, 0x4e, 0x57, 0x7a, 0xa9, 0xe8 } }

+ 

+formset 

+  guid     = INVENTORY_GUID,

+  title    = STRING_TOKEN(STR_INV_FORM_SET_TITLE),

+  help     = STRING_TOKEN(STR_INV_FORM_SET_HELP),

+  class    = 0x04,      

+  subclass = 0x03,

+

+  form formid = 1,

+       title  = STRING_TOKEN(STR_INV_FORM1_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code

+  

+  	text 

+      help   = STRING_TOKEN(STR_INV_VERSION_HELP),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT2),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT3),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT4),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+    subtitle text = STRING_TOKEN(STR_INV_EMPTY_STRING);

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT5),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT6),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT7),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT8),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT9),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT10),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT11),

+	    text   = STRING_TOKEN(STR_INV_EMPTY_STRING),

+      flags  = 0,

+      key    = 0;

+

+    subtitle text = STRING_TOKEN(STR_INV_EMPTY_STRING);

+

+    subtitle text = STRING_TOKEN(STR_INV_VERSION_TEXT12);

+

+  endform;

+

+endformset;

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/InventoryStrings.uni b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/InventoryStrings.uni
new file mode 100644
index 0000000..4946b4a
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/InventoryStrings.uni
Binary files differ
diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/NVDataStruc.h b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/NVDataStruc.h
new file mode 100644
index 0000000..01369eb
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/NVDataStruc.h
@@ -0,0 +1,62 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  NVDataStruc.h 

+ 

+Abstract:

+ 

+  NVData structure used by the sample driver

+ 

+Revision History: 

+ 

+--*/

+

+#ifndef _NVDATASTRUC_H

+#define _NVDATASTRUC_H

+

+#define FORMSET_GUID \

+  { \

+    0xA04A27f4, 0xDF00, 0x4D42, { 0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D } \

+  }

+

+#define INVENTORY_GUID \

+  { \

+    0xb3f56470, 0x6141, 0x4621, { 0x8f, 0x19, 0x70, 0x4e, 0x57, 0x7a, 0xa9, 0xe8 } \

+  }

+

+#define VAR_EQ_TEST_NAME  0x100

+

+#pragma pack(1)

+typedef struct {

+  UINT16  WhatIsThePassword[20];

+  UINT16  WhatIsThePassword2[20];

+  UINT16  MyStringData[20];

+  UINT16  SomethingHiddenForHtml;

+  UINT8   HowOldAreYouInYearsManual;

+  UINT16  HowTallAreYouManual;

+  UINT8   HowOldAreYouInYears;

+  UINT16  HowTallAreYou;

+  UINT8   MyFavoriteNumber;

+  UINT8   TestLateCheck;

+  UINT8   TestLateCheck2;

+  UINT8   QuestionAboutTreeHugging;

+  UINT8   ChooseToActivateNuclearWeaponry;

+  UINT8   SuppressGrayOutSomething;

+  UINT8   OrderedList[8];

+  UINT8   BootOrder[8];

+  UINT8   BootOrderLarge;

+  UINT8   DynamicCheck;

+} MyIfrNVData;

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/Vfr.vfr b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/Vfr.vfr
new file mode 100644
index 0000000..6509a66
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/Vfr.vfr
@@ -0,0 +1,622 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   Vfr.vfr 

+// 

+// Abstract:

+// 

+//   Sample Setup formset

+// 

+// Revision History: 

+// 

+// --*/

+

+

+#include "DriverSampleStrDefs.h" 

+ 

+#include "NVDataStruc.h"

+

+

+typedef struct {

+  UINT8         Field8;

+  UINT16        Field16;

+  UINT8         OrderedList[3];

+} MyIfrNVData2;

+

+typedef struct {

+  UINT8         Field8;

+  UINT16        Field16;

+  UINT8         OrderedList[3];

+} MyIfrNVData3;

+

+#define MY_TEXT_KEY                 0x100 

+

+#define LABEL_1_VALUE               0x01

+#define LABEL_2_VALUE               0x1000

+#define LABEL_UPDATE_BBS            0x2222

+#define LABEL_END_UPDATE_BBS        0x2223

+

+formset 

+  guid     = FORMSET_GUID,

+  title    = STRING_TOKEN(STR_FORM_SET_TITLE),  

+  help     = STRING_TOKEN(STR_FORM_SET_TITLE_HELP), 

+  class    = 0x10,      

+  subclass = 0,

+

+  varstore MyIfrNVData2, key = 0x1234, name = MY_DATA2, guid = FORMSET_GUID;

+

+

+  varstore MyIfrNVData3, key = 0x4321, name = MY_DATA3, guid = FORMSET_GUID;

+

+  form formid = 1,

+       title  = STRING_TOKEN(STR_FORM1_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code

+  

+    subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT);

+

+    subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2);

+

+    banner 

+      title = STRING_TOKEN(STR_BANNER_TITLE),

+      line  1,

+      align center;

+    

+    banner 

+      title = STRING_TOKEN(STR_BANNER_TITLE),

+      line  2,

+      align left;

+

+    banner 

+      title = STRING_TOKEN(STR_BANNER_TITLE),

+      line  2,

+      align right;

+

+  	text 

+      help   = STRING_TOKEN(STR_TEXT_HELP),  

+      text   = STRING_TOKEN(STR_CPU_STRING),

+	    text   = STRING_TOKEN(STR_CPU_STRING2),

+      flags  = 0,

+      key    = 0;

+

+  	text 

+      help   = STRING_TOKEN(STR_EXIT_TEXT),  

+      text   = STRING_TOKEN(STR_EXIT_TEXT), 

+	    text   = STRING_TOKEN(STR_EXIT_TEXT),

+      flags  = INTERACTIVE,

+      key    = 0x1237;

+

+    oneof varid  = MyIfrNVData.SuppressGrayOutSomething,

+      prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),

+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT4), value = 0x0, flags = 0; 

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT5), value = 0x1, flags = 0;

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT6), value = 0x2, flags = DEFAULT;

+    endoneof;

+

+    oneof varid  = MyIfrNVData.BootOrderLarge,

+      prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),

+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  

+      option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0x0, flags = INTERACTIVE, key = 1; 

+      option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 0x1, flags = INTERACTIVE | DEFAULT, key = 2;

+    endoneof;

+

+    grayoutif  ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;

+    suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x0;

+      label 0;

+      checkbox varid    = MyIfrNVData.ChooseToActivateNuclearWeaponry,

+              prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),

+              help     = STRING_TOKEN(STR_CHECK_BOX_HELP),  

+              flags    = 1,                  // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value.  1 = ON, 0 = off

+              key      = 0,

+      endcheckbox;

+    endif;

+

+

+    //

+    // Ordered list: 

+    //   sizeof(MyIfrNVData) storage must be UINT8 array, and

+    //   size written for the variable must be size of the entire

+    //   variable.

+    //

+    //

+    suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x0;

+      label LABEL_UPDATE_BBS;

+      orderedlist

+                varid       = MyIfrNVData.BootOrder,

+                prompt      = STRING_TOKEN(STR_BOOT_OPTIONS),

+                help        = STRING_TOKEN(STR_NULL_STRING),

+                option text = STRING_TOKEN(STR_BOOT_OPTION2), value = 2, flags = RESET_REQUIRED;

+                option text = STRING_TOKEN(STR_BOOT_OPTION1), value = 1, flags = RESET_REQUIRED;

+                option text = STRING_TOKEN(STR_BOOT_OPTION3), value = 3, flags = RESET_REQUIRED;

+                option text = STRING_TOKEN(STR_BOOT_OPTION4), value = 4, flags = RESET_REQUIRED;

+      endlist;      

+      label LABEL_END_UPDATE_BBS;

+    endif;

+ 

+    suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x2;

+      orderedlist    

+        varid       = MyIfrNVData.OrderedList,

+        prompt      = STRING_TOKEN(STR_TEST_OPCODE),

+        help        = STRING_TOKEN(STR_TEXT_HELP),  

+        option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 4, flags = RESET_REQUIRED;

+        option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 3, flags = RESET_REQUIRED;

+        option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 2, flags = RESET_REQUIRED;

+        option text = STRING_TOKEN(STR_TEXT_HELP),    value = 1, flags = RESET_REQUIRED;

+      endlist;

+    endif;

+     

+    label 100;

+

+    goto 0x1234, 

+      prompt  = STRING_TOKEN(STR_GOTO_DYNAMIC), 

+      help    = STRING_TOKEN(STR_GOTO_HELP),

+      flags   = INTERACTIVE, 

+      key     = 0x1234;

+

+    goto 0x1234, 

+      prompt  = STRING_TOKEN(STR_GOTO_DYNAMIC2), 

+      help    = STRING_TOKEN(STR_GOTO_HELP),

+      flags   = INTERACTIVE, 

+      key     = 0x1235;

+    

+    //

+    // VARSTORE tests

+    //

+    // Till now, been using variable NvData (must be reserved)

+    // now we do a varselect for variable NvData3

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqid MyIfrNVData3.Field16 == MyIfrNVData3.Field16

+    endif;

+    // now we do a varselect_pair for variable NvData2 and NvData3

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqid MyIfrNVData2.Field16 == MyIfrNVData3.Field16

+    endif;

+

+

+    // now we do a varselect_pair for variable NvData and NvData2

+//    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+//      ideqid MyIfrNVData2.Field16 == MyIfrNVData.TestLateCheck

+//    endif;

+

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqid MyIfrNVData.TestLateCheck == MyIfrNVData.TestLateCheck2

+    endif;

+

+    oneof varid  = MyIfrNVData.TestLateCheck,

+      prompt      = STRING_TOKEN(STR_TEST_OPCODE),

+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = LATE_CHECK | RESET_REQUIRED;

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = LATE_CHECK | DEFAULT | RESET_REQUIRED;

+    endoneof;

+

+    oneof varid  = MyIfrNVData.TestLateCheck2,

+      prompt      = STRING_TOKEN(STR_TEST_OPCODE2),

+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = LATE_CHECK | DEFAULT | RESET_REQUIRED;

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = LATE_CHECK | RESET_REQUIRED;

+

+    endoneof;

+

+    oneof varid  = MyIfrNVData.QuestionAboutTreeHugging,

+      prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),

+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = RESET_REQUIRED;

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = DEFAULT | RESET_REQUIRED;

+      option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 0x03, flags = RESET_REQUIRED;

+

+    endoneof;

+

+    string    varid    = MyIfrNVData.MyStringData,

+              prompt   = STRING_TOKEN(STR_MY_STRING_PROMPT2),

+              help     = STRING_TOKEN(STR_MY_STRING_HELP2),

+              flags    = INTERACTIVE,

+              key      = 0x1234,

+              minsize  = 6,

+              maxsize  = 0x14,

+    endstring; 

+

+  	text 

+      help   = STRING_TOKEN(STR_GRAYOUT_TEST),  

+      text   = STRING_TOKEN(STR_GRAYOUT_TEST),

+	    text   = STRING_TOKEN(STR_GRAYOUT_TEST),

+      flags  = INTERACTIVE,

+      key    = 0x1555;

+

+  	text 

+      help   = STRING_TOKEN(STR_SUPPRESS_TEST),  

+      text   = STRING_TOKEN(STR_SUPPRESS_TEST),

+	    text   = STRING_TOKEN(STR_SUPPRESS_TEST),

+      flags  = INTERACTIVE,

+      key    = 0x1556;

+

+  	text 

+      help   = STRING_TOKEN(STR_CLEAR_TEST),  

+      text   = STRING_TOKEN(STR_CLEAR_TEST),

+	    text   = STRING_TOKEN(STR_CLEAR_TEST),

+      flags  = INTERACTIVE,

+      key    = 0x1557;

+

+    grayoutif  vareqval var(VAR_EQ_TEST_NAME) == 0x1;

+    suppressif vareqval var(VAR_EQ_TEST_NAME) == 0x1000; 

+      label 30;

+      checkbox varid    = MyIfrNVData.ChooseToActivateNuclearWeaponry,

+              prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),

+              help     = STRING_TOKEN(STR_CHECK_BOX_HELP),  

+              flags    = 1,

+              key      = 0,

+      endcheckbox;

+    endif;

+

+

+    numeric varid   = MyIfrNVData.HowOldAreYouInYearsManual, 

+            prompt  = STRING_TOKEN(STR_NUMERIC_MANUAL_PROMPT),

+            help    = STRING_TOKEN(STR_NUMERIC_HELP0),

+            minimum = 0,

+            maximum = 0xf0,      // 0xf0 = 240 in decimal

+            step    = 0,         // Stepping of 0 equates to a manual entering

+                                 // of a value, otherwise it will auto-increment

+                                 // with a left/right arrow

+            default = 21, 

+

+    endnumeric;

+

+    numeric varid   = MyIfrNVData.HowTallAreYouManual, 

+            prompt  = STRING_TOKEN(STR_TALL_MANUAL_PROMPT),

+            help    = STRING_TOKEN(STR_NUMERIC_HELP1),

+            minimum = 0,

+            maximum = 300,

+            step    = 0,         // Stepping of 0 equates to a manual entering

+                                 // of a value, otherwise it will auto-increment

+                                 // with a left/right arrow

+            default = 175, 

+

+    endnumeric;

+

+    inventory

+      help    = STRING_TOKEN(STR_INVENTORY_HELP),

+      text    = STRING_TOKEN(STR_INVENTORY_TEXT1),

+      text    = STRING_TOKEN(STR_INVENTORY_TEXT2);

+

+      

+    restore defaults,

+      formid  = 4,

+      prompt  = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT),

+      help    = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP),

+      flags   = 0,

+      key     = 0;

+

+    save defaults,

+      formid  = 4,

+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),

+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),

+      flags   = 0,

+      key     = 0;

+

+    // 

+    // Case with no flags or key

+    //

+    save defaults,

+      formid  = 4,

+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),

+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP);

+    //

+    // Case with no key

+    //

+    save defaults,

+      formid  = 4,

+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),

+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),

+      flags   = 0;

+    //

+    // Case with no flags

+    //

+    save defaults,

+      formid  = 4,

+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),

+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),

+      key     = 0;

+

+    label LABEL_2_VALUE;

+

+    grayoutif  ideqval MyIfrNVData.HowOldAreYouInYearsManual == 23 AND ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;

+    numeric varid   = MyIfrNVData.HowOldAreYouInYears,   

+            prompt  = STRING_TOKEN(STR_NUMERIC_PROMPT),

+            help    = STRING_TOKEN(STR_NUMERIC_HELP2),

+            minimum = 0,

+            maximum = 243,

+            step    = 3,

+            default = 18,

+

+    endnumeric;

+

+    label LABEL_1_VALUE;

+

+    //

+    // Numeric with no step or default specified

+    //

+    numeric varid   = MyIfrNVData.HowTallAreYou, 

+            prompt  = STRING_TOKEN(STR_NUMERIC_PROMPT1),

+            help    = STRING_TOKEN(STR_NUMERIC_HELP3),

+            minimum = 0,

+            maximum = 190,

+    //        step    = 1,       // Stepping of 1 if not specified

+    //        default = minimum; // if not specified

+    endnumeric;

+    endif;

+

+    string    varid    = MyIfrNVData.MyStringData,

+              prompt   = STRING_TOKEN(STR_MY_STRING_PROMPT),

+              help     = STRING_TOKEN(STR_MY_STRING_HELP),

+              minsize  = 6,

+              maxsize  = 0x14,

+    endstring; 

+        

+    password  varid    = MyIfrNVData.WhatIsThePassword,

+              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),

+              help     = STRING_TOKEN(STR_PASSWORD_HELP),

+              minsize  = 6,

+              maxsize  = 20, // new opcode 

+              encoding = 1,

+    endpassword; 

+    password  varid    = MyIfrNVData.WhatIsThePassword2,

+              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),

+              help     = STRING_TOKEN(STR_PASSWORD_HELP),

+              minsize  = 6,

+              maxsize  = 20, // new opcode 

+              encoding = 1,

+    endpassword; 

+    //

+    // Test with flags and key fields

+    //

+    password  varid    = MyIfrNVData.WhatIsThePassword,

+              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),

+              help     = STRING_TOKEN(STR_PASSWORD_HELP),

+              flags    = INTERACTIVE,

+              key      = 0x2000,

+              minsize  = 6,

+              maxsize  = 20, // new opcode 

+              encoding = 1,

+    endpassword;

+

+    goto 2, 

+      prompt = STRING_TOKEN(STR_GOTO_FORM2), //SecondSetupPage  // this too has no end-op and basically it's a jump to a form ONLY

+      help   = STRING_TOKEN(STR_GOTO_HELP);

+

+    goto 3, 

+      prompt = STRING_TOKEN(STR_GOTO_FORM3), //ThirdSetupPage  // this too has no end-op and basically it's a jump to a form ONLY

+      help   = STRING_TOKEN(STR_GOTO_HELP);

+

+  endform;

+

+  form formid = 2,               // SecondSetupPage, 

+       title = STRING_TOKEN(STR_FORM2_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code

+

+

+    date    year varid  = Date.Year,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+            help        = STRING_TOKEN(STR_DATE_YEAR_HELP),

+            minimum     = 1998,

+            maximum     = 2099,

+            step        = 1,

+            default     = 2004,

+

+            month varid = Date.Month,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+            help        = STRING_TOKEN(STR_DATE_MONTH_HELP),

+            minimum     = 1,

+            maximum     = 12,

+            step        = 1,

+            default     = 1,

+

+            day varid   = Date.Day,          // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+            help        = STRING_TOKEN(STR_DATE_DAY_HELP),

+            minimum     = 1,

+            maximum     = 31,

+            step        = 0x1,

+            default     = 1,

+

+    enddate;

+

+    time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_TIME_PROMPT),

+            help        = STRING_TOKEN(STR_TIME_HOUR_HELP),

+            minimum     = 0,

+            maximum     = 23,

+            step        = 1,

+            default     = 0,

+

+            minute varid  = Time.Minutes,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),

+            help          = STRING_TOKEN(STR_TIME_MINUTE_HELP),

+            minimum       = 0,

+            maximum       = 59,

+            step          = 1,

+            default       = 0,

+

+            second varid  = Time.Seconds,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),

+            help          = STRING_TOKEN(STR_TIME_SECOND_HELP),

+            minimum       = 0,

+            maximum       = 59,

+            step          = 1,

+            default       = 0,

+

+    endtime;

+

+    date    year varid  = Date.Year,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+            help        = STRING_TOKEN(STR_DATE_YEAR_HELP),

+            minimum     = 1939,

+            maximum     = 2101,

+            step        = 1,

+            default     = 1964,

+

+            month varid = Date.Month,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+            help        = STRING_TOKEN(STR_DATE_MONTH_HELP),

+            minimum     = 1,

+            maximum     = 12,

+            step        = 1,

+            default     = 1,

+

+            day varid   = Date.Day,          // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+            help        = STRING_TOKEN(STR_DATE_DAY_HELP),

+            minimum     = 1,

+            maximum     = 31,

+            step        = 0x1,

+            default     = 1,

+

+    enddate;

+

+    time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt      = STRING_TOKEN(STR_TIME_PROMPT),

+            help        = STRING_TOKEN(STR_TIME_HOUR_HELP),

+            minimum     = 0,

+            maximum     = 23,

+            step        = 1,

+            default     = 0,

+

+            minute varid  = Time.Minutes,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),

+            help          = STRING_TOKEN(STR_TIME_MINUTE_HELP),

+            minimum       = 0,

+            maximum       = 59,

+            step          = 1,

+            default       = 0,

+

+            second varid  = Time.Seconds,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from

+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),

+            help          = STRING_TOKEN(STR_TIME_SECOND_HELP),

+            minimum       = 0,

+            maximum       = 59,

+            step          = 1,

+            default       = 0,

+

+    endtime;

+

+    grayoutif 

+      ideqval Date.Day == 21

+      AND

+      ideqval Date.Month == 8;

+    

+    hidden  value = 32, key = 0x7777;

+

+    endif; // grayoutif

+

+    suppressif

+      ideqval Date.Day == 8

+      AND

+      ideqval Date.Month == 21; 

+    

+    hidden  value = 32, key = 0x7777;

+

+    endif; // suppressif

+

+

+    hidden  value = 32, key = 0x1234;

+

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqval MyIfrNVData.HowOldAreYouInYearsManual == 4

+    endif;

+     

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqvallist MyIfrNVData.HowOldAreYouInYearsManual == 1 2 3 4

+    endif;

+

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqid MyIfrNVData.HowOldAreYouInYearsManual == MyIfrNVData.MyFavoriteNumber

+    endif;

+

+//    grayoutif 

+//

+// If the day is 31 AND months is any of the following 2, 4, 6, 9, 11

+//

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqval Date.Day == 31 

+      AND

+      ideqvallist Date.Month == 2 4 6 9 11

+    endif;

+

+//

+// If the day is 30 AND month is 2

+//

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqval Date.Day == 30

+      AND

+      ideqval Date.Month == 2

+    endif;

+

+//

+// If the day is 29 AND month is 2 AND it year is NOT a leapyear

+//

+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),

+      ideqval Date.Day == 0x1D

+      AND

+      ideqval Date.Month == 2 

+      AND

+      NOT

+      ideqvallist Date.Year == 2004 2008 20012 20016 2020 2024 2028 2032 2036

+    endif;

+

+    checkbox varid    = MyIfrNVData.ChooseToActivateNuclearWeaponry,

+            prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),

+            help     = STRING_TOKEN(STR_CHECK_BOX_HELP),  

+            flags    = 1,

+            key      = 0,

+    endcheckbox;

+

+    text  

+      help = STRING_TOKEN(STR_TEXT_HELP),  

+      text = STRING_TOKEN(STR_TEXT_TEXT_1);

+    

+    text 

+      help   = STRING_TOKEN(STR_TEXT_HELP),  

+      text   = STRING_TOKEN(STR_TEXT_TEXT_1),

+      text   = STRING_TOKEN(STR_TEXT_TEXT_2),

+      flags  = 0,

+      key    = MY_TEXT_KEY;

+         

+    goto 1, 

+      prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage  // this too has no end-op and basically it's a jump to a form ONLY

+      help   = STRING_TOKEN(STR_GOTO_HELP);

+

+  endform;

+

+  form formid = 3, title = STRING_TOKEN(STR_FORM3_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code

+

+    grayoutif  ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;

+      text  

+        help = STRING_TOKEN(STR_TEXT_HELP),  

+        text = STRING_TOKEN(STR_TEXT_TEXT_1);

+        

+    endif; //end grayoutif

+    

+    text  

+      help = STRING_TOKEN(STR_TEXT_HELP),  

+      text = STRING_TOKEN(STR_TEXT_TEXT_1);

+    

+  endform;

+  

+  form formid = 4, title = STRING_TOKEN(STR_FORM3_TITLE);

+

+  endform;

+

+  form formid = 0x1234,            // Dynamically created page, 

+       title = STRING_TOKEN(STR_DYNAMIC_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code

+

+    label 0x1234;

+

+  endform;

+

+endformset;

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/VfrStrings.uni b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/VfrStrings.uni
new file mode 100644
index 0000000..9e9dbf5
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/VfrStrings.uni
Binary files differ
diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/build.xml b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/build.xml
new file mode 100644
index 0000000..5cc8859
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/DriverSample/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DriverSample"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/UserInterface/SetupBrowser/Dxe/DriverSample"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DriverSample">

+      <GenBuild baseName="DriverSample" mbdFilename="${MODULE_DIR}/DriverSample.mbd" msaFilename="${MODULE_DIR}/DriverSample.msa"/>

+   </target>

+   <target depends="DriverSample_clean" name="clean"/>

+   <target depends="DriverSample_cleanall" name="cleanall"/>

+   <target name="DriverSample_clean">

+      <OutputDirSetup baseName="DriverSample" mbdFilename="${MODULE_DIR}/DriverSample.mbd" msaFilename="${MODULE_DIR}/DriverSample.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DriverSample_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DriverSample_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DriverSample_cleanall">

+      <OutputDirSetup baseName="DriverSample" mbdFilename="${MODULE_DIR}/DriverSample.mbd" msaFilename="${MODULE_DIR}/DriverSample.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DriverSample_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DriverSample_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DriverSample*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c
new file mode 100644
index 0000000..d84fcf0
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c
@@ -0,0 +1,1580 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  InputHandler.C

+

+Abstract:

+  

+  Implementation for handling user input from the User Interface

+

+Revision History

+

+--*/

+

+#include "Setup.h"

+#include "Ui.h"

+#include "Colors.h"

+

+#ifndef EFI_MAX

+#define EFI_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))

+#endif

+

+EFI_STATUS

+ReadString (

+  IN  UI_MENU_OPTION              *MenuOption,

+  OUT CHAR16                      *StringPtr

+  )

+{

+  EFI_STATUS    Status;

+  EFI_INPUT_KEY Key;

+  CHAR16        NullCharacter;

+  UINTN         ScreenSize;

+  EFI_TAG       *Tag;

+  CHAR16        Space[2];

+  CHAR16        KeyPad[2];

+  BOOLEAN       SelectionComplete;

+  CHAR16        *TempString;

+  CHAR16        *BufferedString;

+  UINTN         Index;

+  UINTN         Count;

+  UINTN         Start;

+  UINTN         Top;

+  CHAR16        *PromptForDataString;

+  UINTN         DimensionsWidth;

+  UINTN         DimensionsHeight;

+  BOOLEAN       CursorVisible;

+

+  DimensionsWidth     = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

+  DimensionsHeight    = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

+

+  PromptForDataString = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);

+

+  NullCharacter       = CHAR_NULL;

+  ScreenSize          = GetStringWidth (PromptForDataString) / 2;

+  Tag                 = MenuOption->ThisTag;

+  Space[0]            = L' ';

+  Space[1]            = CHAR_NULL;

+  SelectionComplete   = FALSE;

+

+  TempString          = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2);

+  ASSERT (TempString);

+

+  if (ScreenSize < (Tag->Maximum / (UINTN) 2)) {

+    ScreenSize = Tag->Maximum / 2;

+  }

+

+  if ((ScreenSize + 2) > DimensionsWidth) {

+    ScreenSize = DimensionsWidth - 2;

+  }

+

+  BufferedString = AllocateZeroPool (ScreenSize * 2);

+  ASSERT (BufferedString);

+

+  Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1;

+  Top   = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;

+

+  //

+  // Display prompt for string

+  //

+  CreatePopUp (ScreenSize, 4, &NullCharacter, PromptForDataString, Space, &NullCharacter);

+

+  gBS->FreePool (PromptForDataString);

+

+  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));

+

+  CursorVisible = gST->ConOut->Mode->CursorVisible;

+  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

+

+  do {

+    Status = WaitForKeyStroke (&Key);

+

+    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));

+    switch (Key.UnicodeChar) {

+    case CHAR_NULL:

+      switch (Key.ScanCode) {

+      case SCAN_LEFT:

+        break;

+

+      case SCAN_RIGHT:

+        break;

+

+      case SCAN_ESC:

+        gBS->FreePool (TempString);

+        gBS->FreePool (BufferedString);

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);

+        return EFI_DEVICE_ERROR;

+

+      default:

+        break;

+      }

+

+      break;

+

+    case CHAR_CARRIAGE_RETURN:

+      if (GetStringWidth (StringPtr) >= MenuOption->ThisTag->Minimum) {

+        SelectionComplete = TRUE;

+        gBS->FreePool (TempString);

+        gBS->FreePool (BufferedString);

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);

+        return EFI_SUCCESS;

+      } else {

+        ScreenSize = GetStringWidth (gMiniString) / 2;

+        CreatePopUp (ScreenSize, 4, &NullCharacter, gMiniString, gPressEnter, &NullCharacter);

+        //

+        // Simply create a popup to tell the user that they had typed in too few characters.

+        // To save code space, we can then treat this as an error and return back to the menu.

+        //

+        do {

+          Status = WaitForKeyStroke (&Key);

+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

+        gBS->FreePool (TempString);

+        gBS->FreePool (BufferedString);

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);

+        return EFI_DEVICE_ERROR;

+      }

+

+      break;

+

+    case CHAR_BACKSPACE:

+      if (StringPtr[0] != CHAR_NULL) {

+        for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {

+          TempString[Index] = StringPtr[Index];

+        }

+        //

+        // Effectively truncate string by 1 character

+        //

+        TempString[Index - 1] = CHAR_NULL;

+        StrCpy (StringPtr, TempString);

+      }

+

+    default:

+      //

+      // If it is the beginning of the string, don't worry about checking maximum limits

+      //

+      if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {

+        StrnCpy (StringPtr, &Key.UnicodeChar, 1);

+        StrnCpy (TempString, &Key.UnicodeChar, 1);

+      } else if ((GetStringWidth (StringPtr) < MenuOption->ThisTag->Maximum) && (Key.UnicodeChar != CHAR_BACKSPACE)) {

+        KeyPad[0] = Key.UnicodeChar;

+        KeyPad[1] = CHAR_NULL;

+        StrCat (StringPtr, KeyPad);

+        StrCat (TempString, KeyPad);

+      }

+      //

+      // If the width of the input string is now larger than the screen, we nee to

+      // adjust the index to start printing portions of the string

+      //

+      SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');

+

+      PrintStringAt (Start + 1, Top + 3, BufferedString);

+

+      if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {

+        Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;

+      } else {

+        Index = 0;

+      }

+

+      for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {

+        BufferedString[Count] = StringPtr[Index];

+      }

+

+      PrintStringAt (Start + 1, Top + 3, BufferedString);

+      break;

+    }

+

+    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+    gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);

+  } while (!SelectionComplete);

+  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+  gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);

+  return Status;

+}

+

+EFI_STATUS

+ReadPassword (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  BOOLEAN                     PromptForPassword,

+  IN  EFI_TAG                     *Tag,

+  IN  EFI_IFR_DATA_ARRAY          *PageData,

+  IN  BOOLEAN                     SecondEntry,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  OUT CHAR16                      *StringPtr

+  )

+{

+  EFI_STATUS                  Status;

+  UINTN                       PasswordSize;

+  UINTN                       ScreenSize;

+  CHAR16                      NullCharacter;

+  CHAR16                      Space[2];

+  EFI_INPUT_KEY               Key;

+  CHAR16                      KeyPad[2];

+  UINTN                       Index;

+  UINTN                       Start;

+  UINTN                       Top;

+  CHAR16                      *TempString;

+  CHAR16                      *TempString2;

+  BOOLEAN                     Confirmation;

+  BOOLEAN                     ConfirmationComplete;

+  EFI_HII_CALLBACK_PACKET     *Packet;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  EFI_VARIABLE_DEFINITION     *VariableDefinition;

+  UINTN                       DimensionsWidth;

+  UINTN                       DimensionsHeight;

+  EFI_IFR_DATA_ENTRY          *DataEntry;

+

+  DimensionsWidth       = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

+  DimensionsHeight      = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

+

+  VariableDefinition    = NULL;

+  PasswordSize          = 0;

+  NullCharacter         = CHAR_NULL;

+  Space[0]              = L' ';

+  Space[1]              = CHAR_NULL;

+  Confirmation          = FALSE;

+  ConfirmationComplete  = FALSE;

+  Status                = EFI_SUCCESS;

+  FormCallback          = NULL;

+  Packet                = NULL;

+

+  //

+  // Remember that dynamic pages in an environment where all pages are not

+  // dynamic require us to call back to the user to give them an opportunity

+  // to register fresh information in the HII database so that we can extract it.

+  //

+  Status = gBS->HandleProtocol (

+                  (VOID *) (UINTN) MenuOption->Tags[0].CallbackHandle,

+                  &gEfiFormCallbackProtocolGuid,

+                  (VOID **) &FormCallback

+                  );

+

+  TempString  = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2);

+  TempString2 = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2);

+

+  ASSERT (TempString);

+  ASSERT (TempString2);

+

+  if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) {

+    //

+    // Password requires a callback to determine if a password exists

+    //

+    DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1);

+    DataEntry->OpCode  = EFI_IFR_PASSWORD_OP;

+    DataEntry->Length  = 3;

+

+    ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);

+

+    //

+    // The user is about to be prompted with a password field, Data = 0 (Return Status determines the type of prompt)

+    //

+    DataEntry->Data  = (VOID *) (UINTN) (UINT8) (0 + SecondEntry * 2);

+    PageData->NvRamMap    = VariableDefinition->NvRamMap;

+

+    if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+      Status = FormCallback->Callback (

+                              FormCallback,

+                              Tag->Key,

+                              PageData,

+                              &Packet

+                              );

+    }

+    //

+    // If error on return, continue with the reading of a typed in password to verify user knows password

+    // If no error, there is no password set, so prompt for new password

+    // if the previous callback was to verify the user knew password, and user typed it correctly - should return no error

+    //

+    if (!EFI_ERROR (Status)) {

+      PromptForPassword = FALSE;

+

+      //

+      // Simulate this as the second entry into this routine for an interactive behavior

+      //

+      SecondEntry = TRUE;

+    } else if (Status == EFI_NOT_READY) {

+Error:

+      if (Packet != NULL) {

+        //

+        // Upon error, we will likely receive a string to print out

+        // Display error popup

+        //

+        ScreenSize = EFI_MAX(GetStringWidth (Packet->String), GetStringWidth (gPressEnter)) / 2;

+        CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter);

+        gBS->FreePool (Packet);

+

+        do {

+          Status = WaitForKeyStroke (&Key);

+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

+      }

+

+      gBS->FreePool (TempString);

+      gBS->FreePool (TempString2);

+      return EFI_NOT_READY;

+    }

+  }

+

+  do {

+    //

+    // Display PopUp Screen

+    //

+    ScreenSize = GetStringWidth (gPromptForNewPassword) / 2;

+    if (GetStringWidth (gConfirmPassword) / 2 > ScreenSize) {

+      ScreenSize = GetStringWidth (gConfirmPassword) / 2;

+    }

+

+    Start = (DimensionsWidth - ScreenSize - 4) / 2 + gScreenDimensions.LeftColumn + 2;

+    Top   = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;

+

+    if (!Confirmation) {

+      if (PromptForPassword) {

+        CreatePopUp (ScreenSize, 4, &NullCharacter, gPromptForPassword, Space, &NullCharacter);

+      } else {

+        CreatePopUp (ScreenSize, 4, &NullCharacter, gPromptForNewPassword, Space, &NullCharacter);

+      }

+    } else {

+      CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmPassword, Space, &NullCharacter);

+      StringPtr[0] = CHAR_NULL;

+    }

+

+    do {

+      Status = WaitForKeyStroke (&Key);

+

+      switch (Key.UnicodeChar) {

+      case CHAR_NULL:

+        if (Key.ScanCode == SCAN_ESC) {

+          return EFI_NOT_READY;

+        }

+

+        ConfirmationComplete = FALSE;

+        break;

+

+      case CHAR_CARRIAGE_RETURN:

+        if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) {

+          //

+          // User just typed a string in

+          //

+          DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1);

+          DataEntry->OpCode = EFI_IFR_PASSWORD_OP;

+

+          //

+          // If the user just typed in a password, Data = 1

+          // If the user just typed in a password to confirm the previous password, Data = 2

+          //

+          if (!Confirmation) {

+            DataEntry->Length  = 3;

+            DataEntry->Data    = (VOID *) (UINTN) (UINT8) (1 + SecondEntry * 2);

+

+            if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+              Status = FormCallback->Callback (

+                                      FormCallback,

+                                      Tag->Key,

+                                      PageData,

+                                      &Packet

+                                      );

+            }

+

+            DataEntry->Length  = sizeof (EFI_IFR_DATA_ENTRY);

+            DataEntry->Data    = (VOID *) TempString;

+          } else {

+            DataEntry->Length  = 3;

+            DataEntry->Data    = (VOID *) (UINTN) (UINT8) (2 + SecondEntry * 2);

+

+            if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+              Status = FormCallback->Callback (

+                                      FormCallback,

+                                      Tag->Key,

+                                      PageData,

+                                      &Packet

+                                      );

+            }

+

+            DataEntry->Length  = sizeof (EFI_IFR_DATA_ENTRY);

+            DataEntry->Data    = (VOID *) TempString2;

+          }

+

+          if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+            Status = FormCallback->Callback (

+                                    FormCallback,

+                                    Tag->Key,

+                                    PageData,

+                                    &Packet

+                                    );

+          }

+          //

+          // If this was the confirmation round of callbacks

+          // and an error comes back, display an error

+          //

+          if (Confirmation) {

+            if (EFI_ERROR (Status)) {

+              if (Packet->String == NULL) {

+                ScreenSize = EFI_MAX (GetStringWidth (gConfirmError), GetStringWidth (gPressEnter)) / 2;

+                CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter);

+              } else {

+                ScreenSize = EFI_MAX (GetStringWidth (Packet->String), GetStringWidth (gPressEnter)) / 2;

+                CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter);

+                gBS->FreePool (Packet);

+              }

+

+              StringPtr[0] = CHAR_NULL;

+              do {

+                Status = WaitForKeyStroke (&Key);

+

+                if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {

+                  gBS->FreePool (TempString);

+                  gBS->FreePool (TempString2);

+                  return EFI_NOT_READY;

+                }

+              } while (1);

+            } else {

+              gBS->FreePool (TempString);

+              gBS->FreePool (TempString2);

+              return EFI_NOT_READY;

+            }

+          } else {

+            //

+            // User typed a string in and it wasn't valid somehow from the callback

+            // For instance, callback may have said that some invalid characters were contained in the string

+            //

+            if (Status == EFI_NOT_READY) {

+              goto Error;

+            }

+

+            if (PromptForPassword && EFI_ERROR (Status)) {

+              gBS->FreePool (TempString);

+              gBS->FreePool (TempString2);

+              return EFI_DEVICE_ERROR;

+            }

+          }

+        }

+

+        if (Confirmation) {

+          //

+          // Compare tempstring and tempstring2, if the same, return with StringPtr success

+          // Otherwise, kick and error box, and return an error

+          //

+          if (StrCmp (TempString, TempString2) == 0) {

+            gBS->FreePool (TempString);

+            gBS->FreePool (TempString2);

+            return EFI_SUCCESS;

+          } else {

+            ScreenSize = EFI_MAX (GetStringWidth (gConfirmError), GetStringWidth (gPressEnter)) / 2;

+            CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter);

+            StringPtr[0] = CHAR_NULL;

+            do {

+              Status = WaitForKeyStroke (&Key);

+              if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {

+                gBS->FreePool (TempString);

+                gBS->FreePool (TempString2);

+                return EFI_DEVICE_ERROR;

+              }

+            } while (1);

+          }

+        }

+

+        if (PromptForPassword) {

+          //

+          // I was asked for a password, return it back in StringPtr

+          //

+          gBS->FreePool (TempString);

+          gBS->FreePool (TempString2);

+          return EFI_SUCCESS;

+        } else {

+          //

+          // If the two passwords were not the same kick an error popup

+          //

+          Confirmation          = TRUE;

+          ConfirmationComplete  = TRUE;

+          break;

+        }

+

+      case CHAR_BACKSPACE:

+        if (StringPtr[0] != CHAR_NULL) {

+          if (!Confirmation) {

+            for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {

+              TempString[Index] = StringPtr[Index];

+            }

+            //

+            // Effectively truncate string by 1 character

+            //

+            TempString[Index - 1] = CHAR_NULL;

+            StrCpy (StringPtr, TempString);

+          } else {

+            for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {

+              TempString2[Index] = StringPtr[Index];

+            }

+            //

+            // Effectively truncate string by 1 character

+            //

+            TempString2[Index - 1] = CHAR_NULL;

+            StrCpy (StringPtr, TempString2);

+          }

+

+          ConfirmationComplete = FALSE;

+        } else {

+          ConfirmationComplete = FALSE;

+        }

+

+      //

+      // Must be a character we are interested in!

+      //

+      default:

+        if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {

+          if (!Confirmation) {

+            StrnCpy (StringPtr, &Key.UnicodeChar, 1);

+            StrnCpy (TempString, &Key.UnicodeChar, 1);

+          } else {

+            StrnCpy (StringPtr, &Key.UnicodeChar, 1);

+            StrnCpy (TempString2, &Key.UnicodeChar, 1);

+            ConfirmationComplete = FALSE;

+          }

+        } else if ((GetStringWidth (StringPtr) / 2 <= (UINTN) (MenuOption->ThisTag->Maximum - 1) / 2) &&

+                 (Key.UnicodeChar != CHAR_BACKSPACE)

+                ) {

+          KeyPad[0] = Key.UnicodeChar;

+          KeyPad[1] = CHAR_NULL;

+          if (!Confirmation) {

+            StrCat (StringPtr, KeyPad);

+            StrCat (TempString, KeyPad);

+          } else {

+            StrCat (StringPtr, KeyPad);

+            StrCat (TempString2, KeyPad);

+          }

+        }

+

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));

+        for (Index = 1; Index < ScreenSize; Index++) {

+          PrintCharAt (Start + Index, Top + 3, L' ');

+        }

+

+        gST->ConOut->SetCursorPosition (

+                      gST->ConOut,

+                      (DimensionsWidth - GetStringWidth (StringPtr) / 2) / 2 + gScreenDimensions.LeftColumn,

+                      Top + 3

+                      );

+        for (Index = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++) {

+          PrintChar (L'*');

+        }

+

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+        break;

+      }

+      //

+      // end switch

+      //

+    } while (!ConfirmationComplete);

+

+  } while (1);

+  gBS->FreePool (TempString);

+  gBS->FreePool (TempString2);

+  return Status;

+}

+

+VOID

+EncodePassword (

+  IN  CHAR16                      *Password,

+  IN  UINT8                       MaxSize

+  )

+{

+  UINTN   Index;

+  UINTN   Loop;

+  CHAR16  *Buffer;

+  CHAR16  *Key;

+

+  Key     = (CHAR16 *) L"MAR10648567";

+  Buffer  = AllocateZeroPool (MaxSize);

+

+  ASSERT (Buffer);

+

+  for (Index = 0; Key[Index] != 0; Index++) {

+    for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {

+      Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);

+    }

+  }

+

+  CopyMem (Password, Buffer, MaxSize);

+

+  gBS->FreePool (Buffer);

+  return ;

+}

+

+EFI_STATUS

+GetNumericInput (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  BOOLEAN                     ManualInput,

+  IN  EFI_TAG                     *Tag,

+  IN  UINTN                       NumericType,

+  OUT UINT16                      *Value

+  )

+/*++

+

+Routine Description:

+

+  This routine reads a numeric value from the user input.  

+

+Arguments:

+

+  MenuOption       -  Pointer to the current input menu.

+

+  FileFormTagsHead -  Pointer to the root of formset.

+

+  ManualInput      -  If the input is manual or not.

+

+  Tag              -  Pointer to all the attributes and values associated with a tag.

+                 

+  Value            -  Pointer to the numeric value that is going to be read.

+

+Returns: 

+

+  EFI_SUCCESS       - If numerical input is read successfully

+  EFI_DEVICE_ERROR  - If operation fails

+  

+--*/

+{

+  EFI_INPUT_KEY           Key;

+  BOOLEAN                 SelectionComplete;

+  UINTN                   Column;

+  UINTN                   Row;

+  CHAR16                  FormattedNumber[6];

+  UINTN                   PreviousNumber[6];

+  INTN                    Number;

+  UINTN                   Count;

+  UINT16                  BackupValue;

+  STRING_REF              PopUp;

+  CHAR16                  NullCharacter;

+  CHAR16                  *StringPtr;

+  EFI_FILE_FORM_TAGS      *FileFormTags;

+  EFI_STATUS              Status;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+  UINTN                   Loop;

+

+  NullCharacter     = CHAR_NULL;

+  StringPtr         = NULL;

+  Column            = MenuOption->OptCol;

+  Row               = MenuOption->Row;

+  Number            = 0;

+  PreviousNumber[0] = 0;

+  Count             = 0;

+  SelectionComplete = FALSE;

+  BackupValue       = Tag->Value;

+  FileFormTags      = FileFormTagsHead;

+

+  if (ManualInput) {

+    PrintAt (Column, Row, (CHAR16 *) L"[     ]");

+    Column++;

+    if (Tag->Operand != EFI_IFR_TIME_OP) {

+      *Value = BackupValue;

+    }

+  }

+  //

+  // First time we enter this handler, we need to check to see if

+  // we were passed an increment or decrement directive

+  //

+  do {

+    Key.UnicodeChar = CHAR_NULL;

+    if (gDirection != 0) {

+      Key.ScanCode  = gDirection;

+      gDirection    = 0;

+      goto TheKey2;

+    }

+

+    Status = WaitForKeyStroke (&Key);

+

+TheKey2:

+    switch (Key.UnicodeChar) {

+    case '+':

+    case '-':

+      if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {

+        Key.UnicodeChar = CHAR_NULL;

+        if (Key.UnicodeChar == '+') {

+          Key.ScanCode = SCAN_RIGHT;

+        } else {

+          Key.ScanCode = SCAN_LEFT;

+        }

+

+        goto TheKey2;

+      }

+      break;

+

+    case CHAR_NULL:

+      switch (Key.ScanCode) {

+      case SCAN_LEFT:

+      case SCAN_RIGHT:

+        if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {

+          //

+          // By setting this value, we will return back to the caller.

+          // We need to do this since an auto-refresh will destroy the adjustment

+          // based on what the real-time-clock is showing.  So we always commit

+          // upon changing the value.

+          //

+          gDirection = SCAN_DOWN;

+        }

+

+        if (!ManualInput) {

+          Tag->Value = *Value;

+          if (Key.ScanCode == SCAN_LEFT) {

+            Number = *Value - Tag->Step;

+            if (Number < Tag->Minimum) {

+              Number = Tag->Minimum;

+            }

+          } else if (Key.ScanCode == SCAN_RIGHT) {

+            Number = *Value + Tag->Step;

+            if (Number > Tag->Maximum) {

+              Number = Tag->Maximum;

+            }

+          }

+

+          Tag->Value  = (UINT16) Number;

+          *Value      = (UINT16) Number;

+          UnicodeValueToString (

+            FormattedNumber, 

+            FALSE, 

+            (UINTN) Number, 

+            (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+            );

+          Number = (UINT16) GetStringWidth (FormattedNumber);

+

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+          if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {

+            for (Loop = 0; Loop < (UINTN) ((Number >= 8) ? 4 : 2); Loop++) {

+              PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, (CHAR16 *) L" ");

+            }

+          } else {

+            for (Loop = 0; Loop < gOptionBlockWidth; Loop++) {

+              PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, (CHAR16 *) L" ");

+            }

+          }

+

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT);

+

+          if ((MenuOption->Col + gPromptBlockWidth + 1) == MenuOption->OptCol) {

+            PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);

+            Column = MenuOption->OptCol + 1;

+          }

+          //

+          // If Number looks like "3", convert it to "03/"

+          //

+          if (Number == 4 && (NumericType == DATE_NUMERIC)) {

+            FormattedNumber[3]  = FormattedNumber[1];

+            FormattedNumber[2]  = DATE_SEPARATOR;

+            FormattedNumber[1]  = FormattedNumber[0];

+            FormattedNumber[0]  = L'0';

+            Number              = 8;

+          }

+          //

+          // If Number looks like "13", convert it to "13/"

+          //

+          if (Number == 6 && (NumericType == DATE_NUMERIC)) {

+            FormattedNumber[3]  = FormattedNumber[2];

+            FormattedNumber[2]  = DATE_SEPARATOR;

+            Number              = 8;

+          }

+

+          if (Number == 4 &&

+              (NumericType == TIME_NUMERIC) &&

+              (MenuOption->Col + gPromptBlockWidth + 8) != MenuOption->OptCol

+              ) {

+            FormattedNumber[3]  = FormattedNumber[1];

+            FormattedNumber[2]  = TIME_SEPARATOR;

+            FormattedNumber[1]  = FormattedNumber[0];

+            FormattedNumber[0]  = L'0';

+            Number              = 8;

+          }

+

+          if (Number == 4 &&

+              (NumericType == TIME_NUMERIC) &&

+              (MenuOption->Col + gPromptBlockWidth + 8) == MenuOption->OptCol

+              ) {

+            FormattedNumber[3]  = FormattedNumber[1];

+            FormattedNumber[2]  = RIGHT_NUMERIC_DELIMITER;

+            FormattedNumber[1]  = FormattedNumber[0];

+            FormattedNumber[0]  = L'0';

+            Number              = 8;

+          }

+

+          PrintStringAt (Column, Row, FormattedNumber);

+          if (Number == 10 && (NumericType == DATE_NUMERIC)) {

+            PrintChar (RIGHT_NUMERIC_DELIMITER);

+          }

+

+          if (NumericType == REGULAR_NUMERIC) {

+            PrintChar (RIGHT_NUMERIC_DELIMITER);

+          }

+        }

+        break;

+

+      case SCAN_UP:

+      case SCAN_DOWN:

+        goto EnterCarriageReturn;

+

+      case SCAN_ESC:

+        return EFI_DEVICE_ERROR;

+

+      default:

+        break;

+      }

+

+      break;

+

+EnterCarriageReturn:

+

+    case CHAR_CARRIAGE_RETURN:

+      //

+      // Check to see if the Value is something reasonable against consistency limitations.

+      // If not, let's kick the error specified.

+      //

+      //

+      // This gives us visibility to the FileFormTags->NvRamMap to check things

+      // ActiveIfr is a global maintained by the menuing code to ensure that we

+      // are pointing to the correct formset's file data.

+      //

+      for (Count = 0; Count < gActiveIfr; Count++) {

+        FileFormTags = FileFormTags->NextFile;

+      }

+

+      ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);

+

+      CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], &Tag->Value, Tag->StorageWidth);

+

+      //

+      // Data associated with a NULL device (in the fake NV storage)

+      //

+      if (Tag->StorageWidth == (UINT16) 0) {

+        CopyMem (&VariableDefinition->FakeNvRamMap[Tag->StorageStart], &Tag->Value, 2);

+      }

+      //

+      // If a late check is required save off the information.  This is used when consistency checks

+      // are required, but certain values might be bound by an impossible consistency check such as

+      // if two questions are bound by consistency checks and each only has two possible choices, there

+      // would be no way for a user to switch the values.  Thus we require late checking.

+      //

+      if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) {

+        CopyMem (&Tag->OldValue, &BackupValue, Tag->StorageWidth);

+      } else {

+        //

+        // In theory, passing the value and the Id are sufficient to determine what needs

+        // to be done.  The Id is the key to look for the entry needed in the Inconsistency

+        // database.  That will yields operand and ID data - and since the ID's correspond

+        // to the NV storage, we can determine the values for other IDs there.

+        //

+        if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) {

+          if (PopUp == 0x0000) {

+            SelectionComplete = TRUE;

+            break;

+          }

+

+          StringPtr = GetToken (PopUp, MenuOption->Handle);

+

+          CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter);

+

+          do {

+            Status = WaitForKeyStroke (&Key);

+

+            switch (Key.UnicodeChar) {

+

+            case CHAR_CARRIAGE_RETURN:

+              SelectionComplete = TRUE;

+              gBS->FreePool (StringPtr);

+              break;

+

+            default:

+              break;

+            }

+          } while (!SelectionComplete);

+

+          Tag->Value  = BackupValue;

+          *Value      = BackupValue;

+

+          CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], &Tag->Value, Tag->StorageWidth);

+

+          //

+          // Data associated with a NULL device (in the fake NV storage)

+          //

+          if (Tag->StorageWidth == (UINT16) 0) {

+            CopyMem (&VariableDefinition->FakeNvRamMap[Tag->StorageStart], &Tag->Value, 2);

+          }

+

+          return EFI_DEVICE_ERROR;

+        }

+      }

+

+      return EFI_SUCCESS;

+      break;

+

+    case CHAR_BACKSPACE:

+      if (ManualInput) {

+        if (Count == 0) {

+          break;

+        }

+        //

+        // Remove a character

+        //

+        Number  = PreviousNumber[Count - 1];

+        *Value  = (UINT16) Number;

+        UpdateStatusBar (INPUT_ERROR, Tag->Flags, FALSE);

+        Count--;

+        Column--;

+        PrintAt (Column, Row, (CHAR16 *) L" ");

+      }

+      break;

+

+    default:

+      if (ManualInput) {

+        if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {

+          UpdateStatusBar (INPUT_ERROR, Tag->Flags, TRUE);

+          break;

+        }

+        //

+        // If Count 0-4 is complete, there is no way more is valid

+        //

+        if (Count > 4) {

+          break;

+        }

+        //

+        // Someone typed something valid!

+        //

+        if (Count != 0) {

+          Number = Number * 10 + (Key.UnicodeChar - L'0');

+        } else {

+          Number = Key.UnicodeChar - L'0';

+        }

+

+        if (Number > Tag->Maximum) {

+          UpdateStatusBar (INPUT_ERROR, Tag->Flags, TRUE);

+          Number = PreviousNumber[Count];

+          break;

+        } else {

+          UpdateStatusBar (INPUT_ERROR, Tag->Flags, FALSE);

+        }

+

+        Count++;

+

+        PreviousNumber[Count] = Number;

+        *Value                = (UINT16) Number;

+        Tag->Value            = (UINT16) Number;

+

+        PrintCharAt (Column, Row, Key.UnicodeChar);

+        Column++;

+      }

+      break;

+    }

+  } while (!SelectionComplete);

+  return EFI_SUCCESS;

+}

+//

+// Notice that this is at least needed for the ordered list manipulation.

+// Left/Right doesn't make sense for this op-code

+//

+EFI_STATUS

+GetSelectionInputPopUp (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  EFI_TAG                     *Tag,

+  IN  UINTN                       ValueCount,

+  OUT UINT16                      *Value,

+  OUT UINT16                      *KeyValue

+  )

+{

+  EFI_STATUS    Status;

+  EFI_INPUT_KEY Key;

+  UINTN         Index;

+  UINTN         TempIndex;

+  CHAR16        *StringPtr;

+  CHAR16        *TempStringPtr;

+  UINT16        Token;

+  UINTN         Index2;

+  UINTN         TopOptionIndex;

+  UINTN         HighlightPosition;

+  UINTN         Start;

+  UINTN         End;

+  UINTN         Top;

+  UINTN         Bottom;

+  UINT16        TempValue;

+  UINTN         Count;

+  UINTN         PopUpMenuLines;

+  UINTN         MenuLinesInView;

+  UINTN         PopUpWidth;

+  CHAR16        Character;

+  UINTN         FirstOption;

+  BOOLEAN       FirstOptionFoundFlag;

+  INT32         SavedAttribute;

+  EFI_TAG       TagBackup;

+  UINT8         *ValueArray;

+  UINT8         *ValueArrayBackup;

+  UINT8         ValueBackup;

+  BOOLEAN       Initialized;

+  BOOLEAN       KeyInitialized;

+  BOOLEAN       ShowDownArrow;

+  BOOLEAN       ShowUpArrow;

+  UINTN         DimensionsWidth;

+  UINTN         DimensionsHeight;

+

+  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

+  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

+

+  TempValue         = 0;

+  TempIndex         = 0;

+  ValueArray        = (UINT8 *) Value;

+  ValueArrayBackup  = NULL;

+  Initialized       = FALSE;

+  KeyInitialized    = FALSE;

+  ShowDownArrow     = FALSE;

+  ShowUpArrow       = FALSE;

+

+  if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+    ValueArrayBackup = AllocateZeroPool (Tag->StorageWidth);

+    ASSERT (ValueArrayBackup != NULL);

+    CopyMem (ValueArrayBackup, ValueArray, ValueCount);

+    TempValue = *(UINT8 *) (ValueArray);

+    if (ValueArray[0] != 0x00) {

+      Initialized = TRUE;

+    }

+

+    for (Index = 0; ValueArray[Index] != 0x00; Index++)

+      ;

+    ValueCount = Index;

+  } else {

+    TempValue = *Value;

+  }

+

+  Count                 = 0;

+  PopUpWidth            = 0;

+

+  FirstOption           = MenuOption->TagIndex;

+  FirstOptionFoundFlag  = FALSE;

+

+  StringPtr             = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);

+  ASSERT (StringPtr);

+

+  //

+  // Initialization for "One of" pop-up menu

+  //

+  //

+  // Get the number of one of options present and its size

+  //

+  for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; Index++) {

+    if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP &&

+        !MenuOption->Tags[Index].Suppress) {

+      if (!FirstOptionFoundFlag) {

+        FirstOption           = Index;

+        FirstOptionFoundFlag  = TRUE;

+      }

+

+      Count++;

+      Token = MenuOption->Tags[Index].Text;

+

+      //

+      // If this is an ordered list that is initialized

+      //

+      if (Initialized) {

+        for (ValueBackup = (UINT8) MenuOption->TagIndex;

+             MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_OP;

+             ValueBackup++

+            ) {

+          if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) {

+            StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle);

+            break;

+          }

+        }

+      } else {

+        StringPtr = GetToken (Token, MenuOption->Handle);

+      }

+

+      if (StrLen (StringPtr) > PopUpWidth) {

+        PopUpWidth = StrLen (StringPtr);

+      }

+

+      gBS->FreePool (StringPtr);

+    }

+  }

+  //

+  // Perform popup menu initialization.

+  //

+  PopUpMenuLines  = Count;

+  PopUpWidth      = PopUpWidth + POPUP_PAD_SPACE_COUNT;

+

+  SavedAttribute  = gST->ConOut->Mode->Attribute;

+  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

+

+  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {

+    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;

+  }

+

+  Start           = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;

+  End             = Start + PopUpWidth + POPUP_FRAME_WIDTH;

+  Top             = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;

+  Bottom          = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT;

+

+  MenuLinesInView = Bottom - Top - 1;

+  if (MenuLinesInView >= PopUpMenuLines) {

+    Top     = Top + (MenuLinesInView - PopUpMenuLines) / 2;

+    Bottom  = Top + PopUpMenuLines + 1;

+  } else {

+    TempValue     = MenuOption->Tags[MenuOption->TagIndex + 1].Value;

+    ShowDownArrow = TRUE;

+  }

+

+  TopOptionIndex    = 1;

+  HighlightPosition = 0;

+  do {

+    if (Initialized) {

+      for (Index = MenuOption->TagIndex, Index2 = 0; Index2 < ValueCount; Index++, Index2++) {

+        //

+        // Set the value for the item we are looking for

+        //

+        Count = ValueArrayBackup[Index2];

+

+        //

+        // If we hit the end of the Array, we are complete

+        //

+        if (Count == 0) {

+          break;

+        }

+

+        if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+          for (ValueBackup = (UINT8) MenuOption->TagIndex;

+               MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP;

+               ValueBackup++

+              ) {

+            //

+            // We just found what we are looking for

+            //

+            if (MenuOption->Tags[ValueBackup].Value == Count) {

+              //

+              // As long as the two indexes aren't the same, we have

+              // two different op-codes we need to swap internally

+              //

+              if (Index != ValueBackup) {

+                //

+                // Backup destination tag, then copy source to destination, then copy backup to source location

+                //

+                CopyMem (&TagBackup, &MenuOption->Tags[Index], sizeof (EFI_TAG));

+                CopyMem (&MenuOption->Tags[Index], &MenuOption->Tags[ValueBackup], sizeof (EFI_TAG));

+                CopyMem (&MenuOption->Tags[ValueBackup], &TagBackup, sizeof (EFI_TAG));

+              } else {

+                //

+                // If the indexes are the same, then the op-code is where he belongs

+                //

+              }

+            }

+          }

+        } else {

+          //

+          // Since this wasn't an option op-code (likely the ordered list op-code) decerement Index2

+          //

+          Index2--;

+        }

+      }

+    }

+    //

+    // Clear that portion of the screen

+    //

+    ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);

+

+    //

+    // Draw "One of" pop-up menu

+    //

+    Character = (CHAR16) BOXDRAW_DOWN_RIGHT;

+    PrintCharAt (Start, Top, Character);

+    for (Index = Start; Index + 2 < End; Index++) {

+      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {

+        Character = (CHAR16) GEOMETRICSHAPE_UP_TRIANGLE;

+      } else {

+        Character = (CHAR16) BOXDRAW_HORIZONTAL;

+      }

+

+      PrintChar (Character);

+    }

+

+    Character = (CHAR16) BOXDRAW_DOWN_LEFT;

+    PrintChar (Character);

+    Character = (CHAR16) BOXDRAW_VERTICAL;

+    for (Index = Top + 1; Index < Bottom; Index++) {

+      PrintCharAt (Start, Index, Character);

+      PrintCharAt (End - 1, Index, Character);

+    }

+    //

+    // Display the One of options

+    //

+    Index2 = Top + 1;

+    for (Index = MenuOption->TagIndex + TopOptionIndex;

+         (MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP) && (Index2 < Bottom);

+         Index++

+        ) {

+      if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+        Token = MenuOption->Tags[Index].Text;

+        if (Initialized) {

+          for (ValueBackup = (UINT8) MenuOption->TagIndex;

+               MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP;

+               ValueBackup++

+              ) {

+            if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) {

+              StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle);

+              break;

+            }

+          }

+        } else {

+          ValueBackup = (UINT8) Index;

+          StringPtr   = GetToken (Token, MenuOption->Handle);

+        }

+        //

+        // If the string occupies multiple lines, truncate it to fit in one line,

+        // and append a "..." for indication.

+        //

+        if (StrLen (StringPtr) > (PopUpWidth - 1)) {

+          TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));

+          CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));

+          gBS->FreePool (StringPtr);

+          StringPtr = TempStringPtr;

+          StrCat (StringPtr, (CHAR16 *) L"...");

+        }

+        //

+        // Code to display the text should go here. Follwed by the [*]

+        //

+        if (MenuOption->Tags[ValueBackup].Suppress == TRUE) {

+          //

+          // Don't show the one, so decrease the Index2 for balance

+          //

+          Index2--;

+        } else if (MenuOption->Tags[ValueBackup].GrayOut == TRUE) {

+          //

+          // Gray Out the one

+          //

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | POPUP_BACKGROUND);

+          PrintStringAt (Start + 2, Index2, StringPtr);

+          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

+        } else if (MenuOption->Tags[ValueBackup].Value == TempValue) {

+          //

+          // Highlight the selected one

+          //

+          gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);

+          PrintStringAt (Start + 2, Index2, StringPtr);

+          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

+          HighlightPosition = Index2;

+        } else {

+          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

+          PrintStringAt (Start + 2, Index2, StringPtr);

+        }

+

+        gBS->FreePool (StringPtr);

+        Index2 = Index2 + 1;

+      }

+    }

+

+    Character = (CHAR16) BOXDRAW_UP_RIGHT;

+    PrintCharAt (Start, Bottom, Character);

+    for (Index = Start; Index + 2 < End; Index++) {

+      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {

+        Character = (CHAR16) GEOMETRICSHAPE_DOWN_TRIANGLE;

+      } else {

+        Character = (CHAR16) BOXDRAW_HORIZONTAL;

+      }

+

+      PrintChar (Character);

+    }

+

+    Character = (CHAR16) BOXDRAW_UP_LEFT;

+    PrintChar (Character);

+    //

+    // Get User selection and change TempValue if necessary

+    //

+    //

+    // Stop: One of pop-up menu

+    //

+    Key.UnicodeChar = CHAR_NULL;

+    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {

+      Key.ScanCode  = gDirection;

+      gDirection    = 0;

+      goto TheKey;

+    }

+

+    if (!KeyInitialized) {

+      if (MenuOption->ThisTag->Operand == EFI_IFR_ONE_OF_OP) {

+        *KeyValue = MenuOption->Tags[MenuOption->TagIndex + 1].Key;

+      } else {

+        *KeyValue = MenuOption->ThisTag->Key;

+      }

+

+      KeyInitialized = TRUE;

+    }

+

+    Status = WaitForKeyStroke (&Key);

+

+TheKey:

+    switch (Key.UnicodeChar) {

+    case '+':

+    case '-':

+      //

+      // If an ordered list op-code, we will allow for a popup of +/- keys

+      // to create an ordered list of items

+      //

+      if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+        if (Key.UnicodeChar == '+') {

+          if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) {

+            //

+            // Highlight reaches the top of the popup window, scroll one menu item.

+            //

+            TopOptionIndex--;

+            ShowDownArrow = TRUE;

+          }

+

+          if (TopOptionIndex == 1) {

+            ShowUpArrow = FALSE;

+          }

+        } else {

+          if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) {

+            //

+            // Highlight reaches the bottom of the popup window, scroll one menu item.

+            //

+            TopOptionIndex++;

+            ShowUpArrow = TRUE;

+          }

+

+          if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) {

+            ShowDownArrow = FALSE;

+          }

+        }

+

+        for (Index = MenuOption->TagIndex + TopOptionIndex;

+             MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP;

+             Index++

+            ) {

+          if (MenuOption->Tags[Index].Operand == EFI_IFR_ORDERED_LIST_OP) {

+            continue;

+          }

+

+          if (Key.UnicodeChar == '+') {

+            TempIndex = Index - 1;

+          } else {

+            TempIndex = Index + 1;

+          }

+          //

+          // Is this the current tag we are on?

+          //

+          if (MenuOption->Tags[Index].Value == TempValue) {

+            //

+            // Is this prior tag a valid choice?  If not, bail out

+            //

+            if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+              //

+              // Copy the destination tag to the local variable

+              //

+              CopyMem (&TagBackup, &MenuOption->Tags[TempIndex], sizeof (EFI_TAG));

+              //

+              // Copy the current tag to the tag location before us

+              //

+              CopyMem (&MenuOption->Tags[TempIndex], &MenuOption->Tags[Index], sizeof (EFI_TAG));

+              //

+              // Copy the backed up tag to the current location

+              //

+              CopyMem (&MenuOption->Tags[Index], &TagBackup, sizeof (EFI_TAG));

+

+              //

+              // Adjust the array of values

+              //

+              for (Index = 0; Index < ValueCount; Index++) {

+                if (ValueArrayBackup[Index] == (UINT8) TempValue) {

+                  if (Key.UnicodeChar == '+') {

+                    if (Index == 0) {

+                      //

+                      // It is the top of the array already

+                      //

+                      break;

+                    }

+

+                    TempIndex = Index - 1;

+                  } else {

+                    if ((Index + 1) == ValueCount) {

+                      //

+                      // It is the bottom of the array already

+                      //

+                      break;

+                    }

+

+                    TempIndex = Index + 1;

+                  }

+

+                  ValueBackup                 = ValueArrayBackup[TempIndex];

+                  ValueArrayBackup[TempIndex] = ValueArrayBackup[Index];

+                  ValueArrayBackup[Index]     = ValueBackup;

+                  Initialized                 = TRUE;

+                  break;

+                }

+              }

+              break;

+            } else {

+              break;

+            }

+          }

+        }

+      }

+      break;

+

+    case CHAR_NULL:

+      switch (Key.ScanCode) {

+      case SCAN_UP:

+      case SCAN_DOWN:

+        if (Key.ScanCode == SCAN_UP) {

+          if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) {

+            //

+            // Highlight reaches the top of the popup window, scroll one menu item.

+            //

+            TopOptionIndex--;

+            ShowDownArrow = TRUE;

+          }

+

+          if (TopOptionIndex == 1) {

+            ShowUpArrow = FALSE;

+          }

+        } else {

+          if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) {

+            //

+            // Highlight reaches the bottom of the popup window, scroll one menu item.

+            //

+            TopOptionIndex++;

+            ShowUpArrow = TRUE;

+          }

+

+          if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) {

+            ShowDownArrow = FALSE;

+          }

+        }

+

+        for (Index = MenuOption->TagIndex + TopOptionIndex;

+             MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP;

+             Index++

+            ) {

+          if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+            if (Initialized) {

+              for (Index = 0; (ValueArrayBackup[Index] != TempValue) && (Index < ValueCount); Index++)

+                ;

+

+              //

+              // Did we hit the end of the array?  Either get the first TempValue or the next one

+              //

+              if (Key.ScanCode == SCAN_UP) {

+                if (Index == 0) {

+                  TempValue = ValueArrayBackup[0];

+                } else {

+                  TempValue = ValueArrayBackup[Index - 1];

+                }

+              } else {

+                if ((Index + 1) == ValueCount) {

+                  TempValue = ValueArrayBackup[Index];

+                } else {

+                  TempValue = ValueArrayBackup[Index + 1];

+                }

+              }

+              break;

+            } else {

+              if (Key.ScanCode == SCAN_UP) {

+                TempIndex = Index - 1;

+                

+                //

+                // Keep going until meets meaningful tag.

+                //

+                while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP  &&

+                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP        &&

+                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP)

+                       ||

+                       (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP  &&

+                         (MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) {

+                  TempIndex--;

+                }

+              } else {

+                TempIndex = Index + 1;

+

+                //

+                // Keep going until meets meaningful tag.

+                //

+                while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP  &&

+                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP        &&

+                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP)

+                       ||

+                       (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP  &&

+                         (MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) {

+                  TempIndex++;

+                }

+              }

+              //

+              // The option value is the same as what is stored in NV store.  This is where we take action

+              //

+              if (MenuOption->Tags[Index].Value == TempValue) {

+                //

+                // Only if the previous op-code is an option can we select it, otherwise we are at the left-most option

+                //

+                if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+                  TempValue = MenuOption->Tags[TempIndex].Value;

+                  *KeyValue = MenuOption->Tags[TempIndex].Key;

+                } else {

+                  TempValue = MenuOption->Tags[Index].Value;

+                  *KeyValue = MenuOption->Tags[Index].Key;

+                }

+                break;

+              }

+            }

+          }

+        }

+        break;

+

+      case SCAN_ESC:

+        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

+        if (ValueArrayBackup != NULL) {

+          gBS->FreePool (ValueArrayBackup);

+        }

+

+        return EFI_DEVICE_ERROR;

+

+      default:

+        break;

+      }

+

+      break;

+

+    case CHAR_CARRIAGE_RETURN:

+      //

+      // return the current selection

+      //

+      if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+        CopyMem (ValueArray, ValueArrayBackup, ValueCount);

+        gBS->FreePool (ValueArrayBackup);

+      } else {

+        *Value = TempValue;

+      }

+

+      gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

+      return EFI_SUCCESS;

+

+    default:

+      break;

+    }

+  } while (1);

+

+  gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WaitForKeyStroke (

+  OUT  EFI_INPUT_KEY           *Key

+  )

+{

+  EFI_STATUS  Status;

+

+  do {

+    UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);

+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);

+  } while (EFI_ERROR(Status));

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Presentation.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Presentation.c
new file mode 100644
index 0000000..cf3d000
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Presentation.c
@@ -0,0 +1,1481 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+        Presentation.c

+

+Abstract:

+

+  Some presentation routines.

+

+Revision History:

+

+--*/

+

+#include "Setup.h"

+#include "Ui.h"

+#include "Colors.h"

+

+VOID

+ClearLines (

+  UINTN                                       LeftColumn,

+  UINTN                                       RightColumn,

+  UINTN                                       TopRow,

+  UINTN                                       BottomRow,

+  UINTN                                       TextAttribute

+  )

+{

+  CHAR16  *Buffer;

+  UINTN   Row;

+

+  //

+  // For now, allocate an arbitrarily long buffer

+  //

+  Buffer = AllocateZeroPool (0x10000);

+  ASSERT (Buffer != NULL);

+

+  //

+  // Set foreground and background as defined

+  //

+  gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);

+

+  //

+  // Much faster to buffer the long string instead of print it a character at a time

+  //

+  SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');

+

+  //

+  // Clear the desired area with the appropriate foreground/background

+  //

+  for (Row = TopRow; Row <= BottomRow; Row++) {

+    PrintStringAt (LeftColumn, Row, Buffer);

+  }

+

+  gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);

+

+  gBS->FreePool (Buffer);

+  return ;

+}

+

+VOID

+NewStrCat (

+  CHAR16                                      *Destination,

+  CHAR16                                      *Source

+  )

+{

+  UINTN Length;

+

+  for (Length = 0; Destination[Length] != 0; Length++)

+    ;

+

+  //

+  // We now have the length of the original string

+  // We can safely assume for now that we are concatenating a narrow value to this string.

+  // For instance, the string is "XYZ" and cat'ing ">"

+  // If this assumption changes, we need to make this routine a bit more complex

+  //

+  Destination[Length] = (CHAR16) NARROW_CHAR;

+  Length++;

+

+  StrCpy (Destination + Length, Source);

+}

+

+UINTN

+GetStringWidth (

+  CHAR16                                      *String

+  )

+{

+  UINTN Index;

+  UINTN Count;

+  UINTN IncrementValue;

+

+  Index           = 0;

+  Count           = 0;

+  IncrementValue  = 1;

+

+  do {

+    //

+    // Advance to the null-terminator or to the first width directive

+    //

+    for (;

+         (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);

+         Index++, Count = Count + IncrementValue

+        )

+      ;

+

+    //

+    // We hit the null-terminator, we now have a count

+    //

+    if (String[Index] == 0) {

+      break;

+    }

+    //

+    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed

+    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)

+    //

+    if (String[Index] == NARROW_CHAR) {

+      //

+      // Skip to the next character

+      //

+      Index++;

+      IncrementValue = 1;

+    } else {

+      //

+      // Skip to the next character

+      //

+      Index++;

+      IncrementValue = 2;

+    }

+  } while (String[Index] != 0);

+

+  //

+  // Increment by one to include the null-terminator in the size

+  //

+  Count++;

+

+  return Count * sizeof (CHAR16);

+}

+

+VOID

+DisplayPageFrame (

+  VOID

+  )

+{

+  UINTN             Index;

+  UINT8             Line;

+  UINT8             Alignment;

+  CHAR16            Character;

+  CHAR16            *Buffer;

+  CHAR16            *StrFrontPageBanner;

+  EFI_SCREEN_DESCRIPTOR LocalScreen;

+  UINTN             Row;

+

+  ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));

+  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);

+  ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);

+

+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));

+

+  //

+  // For now, allocate an arbitrarily long buffer

+  //

+  Buffer = AllocateZeroPool (0x10000);

+  ASSERT (Buffer != NULL);

+

+  Character = (CHAR16) BOXDRAW_HORIZONTAL;

+

+  for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {

+    Buffer[Index] = Character;

+  }

+

+  if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {

+    //

+    //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);

+    //

+    ClearLines (

+      LocalScreen.LeftColumn,

+      LocalScreen.RightColumn,

+      LocalScreen.TopRow,

+      FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,

+      BANNER_TEXT | BANNER_BACKGROUND

+      );

+    //

+    //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {

+    //

+    for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {

+      //

+      //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {

+      //

+      for (Alignment = (UINT8) LocalScreen.LeftColumn;

+           Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;

+           Alignment++

+          ) {

+        if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) {

+          StrFrontPageBanner = GetToken (

+                                BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn],

+                                FrontPageHandle

+                                );

+        } else {

+          continue;

+        }

+

+        switch (Alignment - LocalScreen.LeftColumn) {

+        case 0:

+          //

+          // Handle left column

+          //

+          PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);

+          break;

+

+        case 1:

+          //

+          // Handle center column

+          //

+          PrintStringAt (

+            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,

+            Line,

+            StrFrontPageBanner

+            );

+          break;

+

+        case 2:

+          //

+          // Handle right column

+          //

+          PrintStringAt (

+            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,

+            Line,

+            StrFrontPageBanner

+            );

+          break;

+        }

+

+        gBS->FreePool (StrFrontPageBanner);

+      }

+    }

+  }

+

+  ClearLines (

+    LocalScreen.LeftColumn,

+    LocalScreen.RightColumn,

+    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,

+    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,

+    KEYHELP_TEXT | KEYHELP_BACKGROUND

+    );

+

+  if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {

+    ClearLines (

+      LocalScreen.LeftColumn,

+      LocalScreen.RightColumn,

+      LocalScreen.TopRow,

+      LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,

+      TITLE_TEXT | TITLE_BACKGROUND

+      );

+    //

+    // Print Top border line

+    // +------------------------------------------------------------------------------+

+    // ?                                                                             ?

+    // +------------------------------------------------------------------------------+

+    //

+    Character = (CHAR16) BOXDRAW_DOWN_RIGHT;

+

+    PrintChar (Character);

+    PrintString (Buffer);

+

+    Character = (CHAR16) BOXDRAW_DOWN_LEFT;

+    PrintChar (Character);

+

+    Character = (CHAR16) BOXDRAW_VERTICAL;

+    for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {

+      PrintCharAt (LocalScreen.LeftColumn, Row, Character);

+      PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);

+    }

+

+    Character = (CHAR16) BOXDRAW_UP_RIGHT;

+    PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);

+    PrintString (Buffer);

+

+    Character = (CHAR16) BOXDRAW_UP_LEFT;

+    PrintChar (Character);

+

+    if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {

+      //

+      // Print Bottom border line

+      // +------------------------------------------------------------------------------+

+      // ?                                                                             ?

+      // +------------------------------------------------------------------------------+

+      //

+      Character = (CHAR16) BOXDRAW_DOWN_RIGHT;

+      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);

+

+      PrintString (Buffer);

+

+      Character = (CHAR16) BOXDRAW_DOWN_LEFT;

+      PrintChar (Character);

+      Character = (CHAR16) BOXDRAW_VERTICAL;

+      for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;

+           Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;

+           Row++

+          ) {

+        PrintCharAt (LocalScreen.LeftColumn, Row, Character);

+        PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);

+      }

+

+      Character = (CHAR16) BOXDRAW_UP_RIGHT;

+      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);

+

+      PrintString (Buffer);

+

+      Character = (CHAR16) BOXDRAW_UP_LEFT;

+      PrintChar (Character);

+    }

+  }

+

+  gBS->FreePool (Buffer);

+

+}

+

+/*

++------------------------------------------------------------------------------+

+?F2=Previous Page                 Setup Page                                  ?

++------------------------------------------------------------------------------+

+

+    

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

++------------------------------------------------------------------------------+

+?F1=Scroll Help                 F9=Reset to Defaults        F10=Save and Exit ?

+| ^"=Move Highlight          <Spacebar> Toggles Checkbox   Esc=Discard Changes |

++------------------------------------------------------------------------------+

+*/

+UI_MENU_OPTION *

+DisplayForm (

+  OUT UI_MENU_OPTION              *Selection,

+  IN  UINT16                      FormHandle,

+  IN  UINT16                      TitleToken,

+  IN  EFI_FORM_TAGS               FormTags,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  UINT8                       *CallbackData

+  )

+{

+  CHAR16              *StringPtr;

+  UINTN               Index;

+  UINTN               Count;

+  UINT16              MenuItemCount;

+  EFI_HII_HANDLE      Handle;

+  UINT16              FormId;

+  STRING_REF          String;

+  EFI_FILE_FORM_TAGS  *FileFormTags;

+  BOOLEAN             SuppressIf;

+  BOOLEAN             Suppress;

+  BOOLEAN             GrayOut;

+  BOOLEAN             Conditional;

+  EFI_SCREEN_DESCRIPTOR   LocalScreen;

+  UINT16              Width;

+  UINTN               ArrayEntry;

+  CHAR16              *OutputString;

+

+  Handle        = Selection->Handle;

+  FormId        = 0;

+  String        = 0;

+  MenuItemCount = 0;

+  ArrayEntry    = 0;

+  OutputString  = NULL;

+

+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));

+

+  //

+  // If we hit a F2 (previous) we already nuked the menu and are simply carrying around what information we need

+  //

+  if (Selection->Previous) {

+    Selection->Previous = FALSE;

+  } else {

+    UiFreeMenu ();

+    UiInitMenu ();

+  }

+

+  StringPtr = GetToken (TitleToken, Handle);

+

+  if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {

+    gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);

+    PrintStringAt (

+      (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,

+      LocalScreen.TopRow + 1,

+      StringPtr

+      );

+  }

+

+  if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {

+    gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);

+

+    //

+    // Display the infrastructure strings

+    //

+    if (!IsListEmpty (&gMenuList)) {

+      PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString);

+    }

+

+    PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString);

+    PrintStringAt (

+      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,

+      LocalScreen.BottomRow - 4,

+      gFunctionNineString

+      );

+    PrintStringAt (

+      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,

+      LocalScreen.BottomRow - 4,

+      gFunctionTenString

+      );

+    PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);

+    PrintStringAt (

+      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,

+      LocalScreen.BottomRow - 3,

+      gEscapeString

+      );

+  }

+  //

+  // Remove Buffer allocated for StringPtr after it has been used.

+  //

+  gBS->FreePool (StringPtr);

+

+  for (Index = 0; FormTags.Tags[Index].Operand != EFI_IFR_END_FORM_OP; Index++) {

+    GrayOut       = FALSE;

+    Suppress      = FALSE;

+    SuppressIf    = FALSE;

+    Conditional   = FALSE;

+    FileFormTags  = FileFormTagsHead;

+

+    if (FormTags.Tags[Index].Operand == EFI_IFR_FORM_OP) {

+      FormId = FormTags.Tags[Index].Id;

+    }

+    //

+    // This gives us visibility to the FileFormTags->NvRamMap to check things

+    // ActiveIfr is a global maintained by the menuing code to ensure that we

+    // are pointing to the correct formset's file data.

+    //

+    for (Count = 0; Count < gActiveIfr; Count++) {

+      FileFormTags = FileFormTags->NextFile;

+    }

+    //

+    //  GrayoutIf [SuppressIf]

+    //    <BOOLEANS>

+    //      OpCode(s)

+    //  EndIf

+    //

+    //  SuppressIf [GrayoutIf]

+    //    <BOOLEANS>

+    //      OpCode(s)

+    //  EndIf

+    //

+    Count = 0;

+

+    do {

+      switch (FormTags.Tags[Index].Operand) {

+      case EFI_IFR_SUPPRESS_IF_OP:

+        SuppressIf = TRUE;

+

+      case EFI_IFR_GRAYOUT_IF_OP:

+

+        Conditional = TRUE;

+

+        //

+        // Advance to the next op-code

+        //

+        Index++;

+

+        //

+        // We are now pointing to the beginning of the consistency checking.  Let's fast forward

+        // through the AND/OR/NOT data to come up with some meaningful ID data.

+        //

+        for (;

+             FormTags.Tags[Index].Operand == EFI_IFR_AND_OP   ||

+             FormTags.Tags[Index].Operand == EFI_IFR_OR_OP    ||

+             FormTags.Tags[Index].Operand == EFI_IFR_GT_OP    ||

+             FormTags.Tags[Index].Operand == EFI_IFR_GE_OP    ||

+             FormTags.Tags[Index].Operand == EFI_IFR_NOT_OP;

+           Index++

+            )

+          ;

+

+        //

+        // We need to walk through the consistency checks until we hit the end of the consistency

+        // FALSE means evaluate this single expression

+        // The ConsistencyId refers to which expression in the Consistency database to use

+        //

+        if (SuppressIf) {

+          Suppress = ValueIsNotValid (

+                      FALSE,

+                      FormTags.Tags[Index].ConsistencyId,

+                      &FormTags.Tags[Index],

+                      FileFormTags,

+                      &String

+                      );

+          SuppressIf = FALSE;

+        } else {

+          GrayOut = ValueIsNotValid (

+                      FALSE,

+                      FormTags.Tags[Index].ConsistencyId,

+                      &FormTags.Tags[Index],

+                      FileFormTags,

+                      &String

+                      );

+        }

+        //

+        // Advance to the end of the expression (Will land us at a grayoutif/suppressif or the op-code being affected)

+        //

+        for (;

+             FormTags.Tags[Index].Operand == EFI_IFR_EQ_ID_VAL_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_EQ_VAR_VAL_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_EQ_ID_ID_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_EQ_ID_LIST_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_NOT_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_AND_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_OR_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_TRUE_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_FALSE_OP ||

+             FormTags.Tags[Index].Operand == EFI_IFR_GT_OP    ||

+             FormTags.Tags[Index].Operand == EFI_IFR_GE_OP    ||

+             FormTags.Tags[Index].Operand == EFI_IFR_LABEL_OP;

+           Index++

+            )

+          ;

+        break;

+

+      default:

+        goto GetOut;

+      }

+      //

+      // Do this two times (at most will see a suppress and grayout combination

+      //

+      Count++;

+    } while (Count < 2);

+

+GetOut:

+    do {

+      if (GrayOut) {

+        FormTags.Tags[Index].GrayOut = TRUE;

+      } else {

+        FormTags.Tags[Index].GrayOut = FALSE;

+      }

+      if (Suppress && FormTags.Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+        //

+        // Only need .Suppress field when the tag is a one_of_option. For other cases, omit them directly.

+        //

+        FormTags.Tags[Index].Suppress = TRUE;

+      } else {

+        FormTags.Tags[Index].Suppress = FALSE;

+      }

+

+      if ((

+            FormTags.Tags[Index].NumberOfLines > 0 ||

+            FormTags.Tags[Index].Operand == EFI_IFR_DATE_OP ||

+            FormTags.Tags[Index].Operand == EFI_IFR_TIME_OP

+          ) &&

+          !Suppress

+          ) {

+

+        StringPtr = GetToken (FormTags.Tags[Index].Text, Handle);

+

+        Width     = GetWidth (&FormTags.Tags[Index], Handle);

+

+        //

+        // This data can be retrieved over and over again.  Therefore, reset to original values

+        // before processing otherwise things will start growing linearly

+        //

+        if (FormTags.Tags[Index].NumberOfLines > 1) {

+          FormTags.Tags[Index].NumberOfLines = 1;

+        }

+

+        for (Count = 0; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {

+          //

+          // If there is more string to process print on the next row and increment the Skip value

+          //

+          if (StrLen (&StringPtr[ArrayEntry])) {

+            FormTags.Tags[Index].NumberOfLines++;

+          }

+

+          gBS->FreePool (OutputString);

+        }

+

+        ArrayEntry = 0;

+

+        //

+        // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do

+        // it in UiFreeMenu.

+        //

+        UiAddSubMenuOption (StringPtr, Handle, FormTags.Tags, Index, FormId, MenuItemCount);

+        MenuItemCount++;

+      }

+      //

+      // Keep processing menu entries based on the resultant suppress/grayout results until we hit an end-if

+      //

+      Index++;

+    } while (FormTags.Tags[Index].Operand != EFI_IFR_END_IF_OP && Conditional);

+

+    //

+    // We advanced the index for the above conditional, rewind it to keep harmony with the for loop logic

+    //

+    Index--;

+  }

+

+  Selection = UiDisplayMenu (TRUE, FileFormTagsHead, (EFI_IFR_DATA_ARRAY *) CallbackData);

+

+  return Selection;

+}

+

+VOID

+InitializeBrowserStrings (

+  VOID

+  )

+{

+  gFunctionOneString    = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle);

+  gFunctionTwoString    = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle);

+  gFunctionNineString   = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);

+  gFunctionTenString    = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);

+  gEnterString          = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);

+  gEnterCommitString    = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);

+  gEscapeString         = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);

+  gMoveHighlight        = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);

+  gMakeSelection        = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);

+  gNumericInput         = GetToken (STRING_TOKEN (NUMERIC_INPUT), gHiiHandle);

+  gToggleCheckBox       = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);

+  gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);

+  gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);

+  gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);

+  gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);

+  gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);

+  gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);

+  gAreYouSure           = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);

+  gYesResponse          = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);

+  gNoResponse           = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);

+  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);

+  gPlusString           = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);

+  gMinusString          = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);

+  gAdjustNumber         = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);

+  return ;

+}

+

+VOID

+UpdateKeyHelp (

+  IN  UI_MENU_OPTION              *Selection,

+  IN  BOOLEAN                     Selected

+  )

+/*++

+Routine Description:

+  Update key's help imformation

+

+Arguments:

+  Selection C The form that current display

+  Selected C  Whether or not a tag be selected

+

+Returns:

+  None

+--*/

+{

+  UINTN             SecCol;

+  UINTN             ThdCol;

+  UINTN             LeftColumnOfHelp;

+  UINTN             RightColumnOfHelp;

+  UINTN             TopRowOfHelp;

+  UINTN             BottomRowOfHelp;

+  UINTN             StartColumnOfHelp;

+  EFI_SCREEN_DESCRIPTOR LocalScreen;

+

+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));

+

+  SecCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;

+  ThdCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;

+

+  StartColumnOfHelp = LocalScreen.LeftColumn + 2;

+  LeftColumnOfHelp  = LocalScreen.LeftColumn + 1;

+  RightColumnOfHelp = LocalScreen.RightColumn - 2;

+  TopRowOfHelp      = LocalScreen.BottomRow - 4;

+  BottomRowOfHelp   = LocalScreen.BottomRow - 3;

+

+  if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) {

+    return ;

+  }

+

+  gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);

+

+  switch (Selection->ThisTag->Operand) {

+  case EFI_IFR_ORDERED_LIST_OP:

+  case EFI_IFR_ONE_OF_OP:

+  case EFI_IFR_NUMERIC_OP:

+  case EFI_IFR_TIME_OP:

+  case EFI_IFR_DATE_OP:

+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);

+

+    if (!Selected) {

+      if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {

+        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);

+        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);

+        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);

+        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);

+

+      }

+

+      if ((Selection->ThisTag->Operand == EFI_IFR_DATE_OP) || (Selection->ThisTag->Operand == EFI_IFR_TIME_OP)) {

+        PrintAt (

+          StartColumnOfHelp,

+          BottomRowOfHelp,

+          (CHAR16 *) L"%c%c%c%c%s",

+          ARROW_UP,

+          ARROW_DOWN,

+          ARROW_RIGHT,

+          ARROW_LEFT,

+          gMoveHighlight

+          );

+        PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);

+      } else {

+        PrintAt (StartColumnOfHelp, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);

+        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);

+      }

+    } else {

+      PrintStringAt (StartColumnOfHelp, BottomRowOfHelp, gEnterCommitString);

+

+      //

+      // If it is a selected numeric with manual input, display different message

+      //

+      if ((Selection->ThisTag->Operand == EFI_IFR_NUMERIC_OP) && (Selection->ThisTag->Step == 0)) {

+        PrintStringAt (SecCol, TopRowOfHelp, gNumericInput);

+      } else if (Selection->ThisTag->Operand != EFI_IFR_ORDERED_LIST_OP) {

+        PrintAt (SecCol, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);

+      }

+

+      if (Selection->ThisTag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);

+        PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);

+      }

+

+      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);

+    }

+    break;

+

+  case EFI_IFR_CHECKBOX_OP:

+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);

+

+    if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {

+      PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);

+      PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);

+      PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);

+      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);

+    }

+

+    PrintAt (StartColumnOfHelp, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);

+    PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);

+    break;

+

+  case EFI_IFR_REF_OP:

+  case EFI_IFR_PASSWORD_OP:

+  case EFI_IFR_STRING_OP:

+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);

+

+    if (!Selected) {

+      if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {

+        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);

+        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);

+        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);

+        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);

+      }

+

+      PrintAt (StartColumnOfHelp, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);

+      PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);

+    } else {

+      if (Selection->ThisTag->Operand != EFI_IFR_REF_OP) {

+        PrintStringAt (

+          (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,

+          BottomRowOfHelp,

+          gEnterCommitString

+          );

+        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);

+      }

+    }

+    break;

+  }

+

+}

+

+VOID

+ExtractFormHandle (

+  IN  UI_MENU_OPTION              *Selection,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  UINTN                       IdValue,

+  OUT UINT16                      *FormHandle,

+  OUT UINT16                      *TitleToken,

+  OUT EFI_FORM_TAGS               *FormTags

+  )

+{

+  UINTN               Index;

+  EFI_FILE_FORM_TAGS  *FileFormTags;

+  EFI_FORM_TAGS       LocalTags;

+

+  FileFormTags = FileFormTagsHead;

+

+  //

+  // Advance FileFormTags to the correct file's tag information.

+  // For instance, if Selection->IfrNumber is 3, that means the 4th

+  // file (0-based) in the FileFormTags linked-list contains the tag

+  // information.

+  //

+  for (Index = 0; Index < Selection->IfrNumber; Index++) {

+    FileFormTags = FileFormTags->NextFile;

+  }

+

+  LocalTags = FileFormTags->FormTags;

+

+  if (IdValue == 0) {

+    //

+    // Advance Index to the first FormOp tag information

+    //

+    for (Index = 0; FileFormTags->FormTags.Tags[Index].Operand != EFI_IFR_FORM_OP; Index++)

+      ;

+  } else {

+    //

+    // Advance Index to the FormOp with the correct ID value

+    //

+    for (; LocalTags.Next != NULL; LocalTags = *LocalTags.Next) {

+      for (Index = 0; LocalTags.Tags[Index].Operand != EFI_IFR_FORM_OP; Index++)

+        ;

+      if (LocalTags.Tags[Index].Id == IdValue) {

+        break;

+      }

+    }

+  }

+  //

+  // return the Form Id, Text, and the File's FormTags structure

+  //

+  *FormHandle = LocalTags.Tags[Index].Id;

+  *TitleToken = LocalTags.Tags[Index].Text;

+  *FormTags   = LocalTags;

+  return ;

+}

+

+EFI_STATUS

+UpdateNewTagData (

+  IN  UINT8                                     *FormData,

+  IN  UINT16                                    ConsistencyId,

+  IN  UINT16                                    CurrentVariable,

+  IN  EFI_FORM_TAGS                             *FormTags,

+  OUT EFI_FILE_FORM_TAGS                        *FileFormTags

+  )

+{

+  EFI_STATUS  Status;

+  UINT16      Index;

+  UINT16      QuestionIndex;

+  UINT16      NumberOfTags;

+  INT16       CurrTag;

+  UINT8       TagLength;

+  UINTN       Count;

+  BOOLEAN     Finished;

+

+  //

+  // Initialize some Index variable and Status

+  //

+  Count         = 0;

+  QuestionIndex = 0;

+  NumberOfTags  = 1;

+  Index         = 0;

+  Status        = EFI_SUCCESS;

+  Finished      = FALSE;

+

+  //

+  // Determine the number of tags for the first form

+  //

+  GetTagCount (&FormData[Index], &NumberOfTags);

+

+  //

+  // Allocate memory for our tags on the first form

+  //

+  FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));

+  ASSERT (FormTags->Tags != NULL);

+

+  for (CurrTag = 0; FormData[Index] != EFI_IFR_END_FORM_SET_OP; CurrTag++) {

+    //

+    // Operand = IFR OpCode

+    //

+    FormTags->Tags[CurrTag].Operand = FormData[Index];

+

+    //

+    // Assume for now 0 lines occupied by this OpCode

+    //

+    FormTags->Tags[CurrTag].NumberOfLines = 0;

+

+    //

+    // Determine the length of the Tag so we can later skip to the next tag in the form

+    //

+    //

+    // get the length

+    //

+    TagLength = FormData[Index + 1];

+    //

+    // Operate on the Found OpCode

+    //

+    switch (FormData[Index]) {

+

+    case EFI_IFR_FORM_OP:

+    case EFI_IFR_SUBTITLE_OP:

+    case EFI_IFR_TEXT_OP:

+    case EFI_IFR_REF_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      break;

+

+    case EFI_IFR_VARSTORE_SELECT_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      CopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) &FormData[Index])->VarId, sizeof (UINT16));

+      break;

+

+    case EFI_IFR_END_FORM_OP:

+      FormTags->Tags[CurrTag].Operand       = FormData[Index];

+      FormTags->Tags[CurrTag].NumberOfLines = 0;

+

+      Finished = TRUE;

+      break;

+

+    case EFI_IFR_ORDERED_LIST_OP:

+    case EFI_IFR_ONE_OF_OP:

+      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);

+

+      //

+      // Store away the CurrTag since what follows will be the answer that we

+      // need to place into the appropriate location in the tag array

+      //

+      //

+      // record for setting default later

+      //

+      QuestionIndex = (UINT16) CurrTag;

+      break;

+

+    case EFI_IFR_ONE_OF_OPTION_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      FormTags->Tags[QuestionIndex].Key = ((EFI_IFR_ONE_OF_OPTION *) &FormData[Index])->Key;

+      FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & EFI_IFR_FLAG_RESET_REQUIRED);

+      break;

+

+    case EFI_IFR_CHECKBOX_OP:

+      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      break;

+

+    case EFI_IFR_NUMERIC_OP:

+      GetNumericHeader (&FormTags->Tags[CurrTag], FormData, Index, (UINT16) 1, FileFormTags, CurrentVariable);

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      break;

+

+    case EFI_IFR_DATE_OP:

+      //

+      // Date elements come in as a Year, Month, Day.  We need to process them as a country-based

+      // Order.  It is much easier to do it here than anywhere else.

+      //

+      // For US standards - we want Month/Day/Year, thus we advance "i" +1, +2, +0 while CurrTag is +0, +1, +2

+      //

+      GetNumericHeader (

+        &FormTags->Tags[CurrTag],

+        FormData,

+        (UINT16) (Index + TagLength),

+        (UINT16) 0,

+        FileFormTags,

+        CurrentVariable

+        );

+

+      //

+      // The current language selected + the Date operand

+      //

+      FormTags->Tags[CurrTag + 1].Operand = FormData[Index];

+      GetNumericHeader (

+        &FormTags->Tags[CurrTag + 1],

+        FormData,

+        (UINT16) (Index + TagLength + FormData[Index + TagLength + 1]),

+        (UINT16) 0,

+        FileFormTags,

+        CurrentVariable

+        );

+

+      //

+      // The current language selected + the Date operand

+      //

+      FormTags->Tags[CurrTag + 2].Operand = FormData[Index];

+      GetNumericHeader (&FormTags->Tags[CurrTag + 2], FormData, Index, (UINT16) 1, FileFormTags, CurrentVariable);

+

+      CurrTag   = (INT16) (CurrTag + 2);

+

+      Index     = (UINT16) (Index + TagLength);

+      //

+      // get the length

+      //

+      TagLength = FormData[Index + 1];

+      Index     = (UINT16) (Index + TagLength);

+      //

+      // get the length

+      //

+      TagLength = FormData[Index + 1];

+      break;

+

+    case EFI_IFR_TIME_OP:

+      GetNumericHeader (&FormTags->Tags[CurrTag], FormData, Index, (UINT16) 0, FileFormTags, CurrentVariable);

+

+      if (Count == 2) {

+        //

+        // Override the GetQuestionHeader information - date/time are treated very differently

+        //

+        FormTags->Tags[CurrTag].NumberOfLines = 1;

+        Count = 0;

+      } else {

+        //

+        // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines

+        // associated with them, and the third has 1 line to allow to space beyond the choice.

+        //

+        Count++;

+      }

+      break;

+

+    case EFI_IFR_PASSWORD_OP:

+    case EFI_IFR_STRING_OP:

+      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      break;

+

+    case EFI_IFR_INCONSISTENT_IF_OP:

+    case EFI_IFR_SUPPRESS_IF_OP:

+    case EFI_IFR_GRAYOUT_IF_OP:

+      ConsistencyId++;

+      break;

+

+    case EFI_IFR_EQ_ID_VAL_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;

+      break;

+

+    case EFI_IFR_EQ_VAR_VAL_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;

+      break;

+

+    case EFI_IFR_EQ_ID_ID_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;

+      break;

+

+    case EFI_IFR_AND_OP:

+    case EFI_IFR_OR_OP:

+    case EFI_IFR_NOT_OP:

+    case EFI_IFR_TRUE_OP:

+    case EFI_IFR_FALSE_OP:

+    case EFI_IFR_GT_OP:

+    case EFI_IFR_GE_OP:

+      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;

+      break;

+

+    case EFI_IFR_EQ_ID_LIST_OP:

+      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

+

+      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;

+      break;

+

+    default:

+      break;

+    }

+    //

+    // End of switch

+    //

+    if (Finished) {

+      break;

+    }

+    //

+    // Per spec., we ignore ops that we don't know how to deal with.  Skip to next tag

+    //

+    Index = (UINT16) (Index + TagLength);

+  }

+  //

+  // End of Index

+  //

+  return Status;

+}

+

+VOID

+ExtractDynamicFormHandle (

+  IN  UI_MENU_OPTION              *Selection,

+  IN  UINT8                       *CallbackData,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  UINTN                       IdValue,

+  OUT UINT16                      *FormHandle,

+  OUT UINT16                      *TitleToken,

+  OUT EFI_FORM_TAGS               *FormTags

+  )

+/*++

+

+Routine Description:

+

+  The function does the most of the works when the EFI_TAG that

+  user selects on is EFI_IFR_FLAG_INTERACTIVE or EFI_IFR_PASSWORD_OP:

+  invoke CallBack, update the new form data.

+  

+Arguments:

+  

+  Selection         - The current selection of the form.

+  CallbackData      - The pointer to host the data passed back by the callback function.

+  FileFormTagsHead  - Prompt string token of the one-of box

+  IdValue           - The current page number.

+  FormHandle        - Output the  the handle of the form.

+  TitleToken        - Output the  TitleToken of the new page.

+  FormTags          - Output the  FormFags of the new page.

+  

+Returns: 

+  VOID

+  

+--*/

+{

+  UINTN                       Index;

+  UINTN                       BackupIndex;

+  EFI_FILE_FORM_TAGS          *FileFormTags;

+  EFI_FORM_TAGS               *LocalTags;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  EFI_STATUS                  Status;

+  UINTN                       Length;

+  UINT8                       *Buffer;

+  EFI_PHYSICAL_ADDRESS        CallbackHandle;

+  EFI_GUID                    TagGuid;

+  UINT16                      TargetPage;

+  EFI_HII_CALLBACK_PACKET     *Packet;

+  UINTN                       ScreenSize;

+  CHAR16                      NullCharacter;

+  EFI_INPUT_KEY               Key;

+  UINT16                      ConsistencyId;

+  UINT16                      CurrentVariable;

+  EFI_VARIABLE_DEFINITION     *VariableDefinition;

+  EFI_IFR_DATA_ENTRY          *DataEntry;

+

+  VariableDefinition  = NULL;

+  NullCharacter       = CHAR_NULL;

+

+  CurrentVariable     = 0;

+  FileFormTags        = FileFormTagsHead;

+  Length              = 0;

+  CallbackHandle      = 0;

+  TargetPage          = (UINT16) IdValue;

+  Packet              = NULL;

+  ConsistencyId       = 0;

+

+  //

+  // Advance FileFormTags to the correct file's tag information.

+  // For instance, if Selection->IfrNumber is 3, that means the 4th

+  // file (0-based) in the FileFormTags linked-list contains the tag

+  // information.

+  //

+  for (Index = 0; Index < Selection->IfrNumber; Index++) {

+    FileFormTags = FileFormTags->NextFile;

+  }

+

+  LocalTags = &FileFormTags->FormTags;

+

+  //

+  // Advance Index to the FormOp with the correct ID value

+  //

+  for (; LocalTags->Next != NULL; LocalTags = LocalTags->Next) {

+    if ((LocalTags->Tags[0].CallbackHandle != 0) && (CallbackHandle == 0)) {

+      CallbackHandle = LocalTags->Tags[0].CallbackHandle;

+      CopyMem (&TagGuid, &LocalTags->Tags[0].GuidValue, sizeof (EFI_GUID));

+    }

+

+    for (Index = 0; LocalTags->Tags[Index].Operand != EFI_IFR_FORM_OP; Index++)

+      ;

+    if (LocalTags->Tags[Index].Id == IdValue) {

+      break;

+    }

+  }

+  //

+  // If we are going to callback on a non-goto opcode, make sure we don't change pages

+  //

+  if (Selection->ThisTag->Operand != EFI_IFR_REF_OP) {

+    TargetPage = Selection->FormId;

+  }

+  //

+  // The first tag below should be the form op-code.  We need to store away the

+  // current variable setting to ensure if we have to reload the page, that we

+  // can correctly restore the values for the active variable

+  //

+  CurrentVariable = Selection->Tags[0].VariableNumber;

+

+  //

+  // Remember that dynamic pages in an environment where all pages are not

+  // dynamic require us to call back to the user to give them an opportunity

+  // to register fresh information in the HII database so that we can extract it.

+  //

+  Status = gBS->HandleProtocol (

+                  (VOID *) (UINTN) CallbackHandle,

+                  &gEfiFormCallbackProtocolGuid,

+                  (VOID **) &FormCallback

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (LocalTags->Tags);

+    return ;

+  }

+

+  ExtractRequestedNvMap (FileFormTags, CurrentVariable, &VariableDefinition);

+

+  if (Selection->ThisTag->Flags & (EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS)) {

+    ((EFI_IFR_DATA_ARRAY *) CallbackData)->NvRamMap = VariableDefinition->NvRamMap;

+  } else {

+    ((EFI_IFR_DATA_ARRAY *) CallbackData)->NvRamMap = NULL;

+  }

+

+  if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+    Status = FormCallback->Callback (

+                            FormCallback,

+                            Selection->ThisTag->Key,

+                            (EFI_IFR_DATA_ARRAY *) CallbackData,

+                            &Packet

+                            );

+  }

+

+  if (EFI_ERROR (Status)) {

+    //

+    // Restore Previous Value

+    //

+    CopyMem (

+      &VariableDefinition->NvRamMap[Selection->ThisTag->StorageStart],

+      gPreviousValue,

+      Selection->ThisTag->StorageWidth

+      );

+

+    if (Packet != NULL) {

+      //

+      // Upon error, we will likely receive a string to print out

+      //

+      ScreenSize = GetStringWidth (Packet->String) / 2;

+

+      //

+      // Display error popup

+      //

+      CreatePopUp (ScreenSize, 3, &NullCharacter, Packet->String, &NullCharacter);

+

+      do {

+        Status = WaitForKeyStroke (&Key);

+      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

+    } else {

+      UpdateStatusBar (INPUT_ERROR, (UINT8) 0, TRUE);

+    }

+

+  } else {

+    if (Packet != NULL) {

+      //

+      // We need to on a non-error, look in the outbound Packet for information and update the NVRAM

+      // location associated with the op-code specified there.  This is used on single op-code instances

+      // and not for when a hyperlink sent us a whole page of data.

+      //

+      DataEntry = (EFI_IFR_DATA_ENTRY *) (&Packet->DataArray + 1);

+      if (Packet->DataArray.EntryCount == 1) {

+        switch (DataEntry->OpCode) {

+        case EFI_IFR_STRING_OP:

+        case EFI_IFR_NUMERIC_OP:

+        case EFI_IFR_ORDERED_LIST_OP:

+        case EFI_IFR_ONE_OF_OP:

+        case EFI_IFR_CHECKBOX_OP:

+          CopyMem (

+            &VariableDefinition->NvRamMap[Selection->ThisTag->StorageStart],

+            &DataEntry->Data,

+            Selection->ThisTag->StorageWidth

+            );

+          break;

+

+        case EFI_IFR_NV_ACCESS_COMMAND:

+          CopyMem (

+            &VariableDefinition->NvRamMap[((EFI_IFR_NV_DATA *) Packet)->QuestionId],

+            ((EFI_IFR_NV_DATA *) Packet) + 1,

+            ((EFI_IFR_NV_DATA *) Packet)->StorageWidth

+            );

+          break;

+

+        }

+

+        if (DataEntry->Flags & RESET_REQUIRED) {

+          gResetRequired = TRUE;

+        }

+

+        if (DataEntry->Flags & EXIT_REQUIRED) {

+          gExitRequired = TRUE;

+        }

+

+        if (DataEntry->Flags & SAVE_REQUIRED) {

+          gSaveRequired = TRUE;

+        }

+

+        if (DataEntry->Flags & NV_CHANGED) {

+          gNvUpdateRequired = TRUE;

+        }

+

+        if (DataEntry->Flags & NV_NOT_CHANGED) {

+          gNvUpdateRequired = FALSE;

+        }

+      }

+    }

+  }

+

+  if (Packet != NULL) {

+    gBS->FreePool (Packet);

+  }

+

+  for (BackupIndex = 0; LocalTags->Tags[BackupIndex].Operand != EFI_IFR_END_FORM_OP; BackupIndex++) {

+    switch (LocalTags->Tags[BackupIndex].Operand) {

+    case EFI_IFR_EQ_VAR_VAL_OP:

+    case EFI_IFR_EQ_ID_VAL_OP:

+    case EFI_IFR_EQ_ID_ID_OP:

+    case EFI_IFR_AND_OP:

+    case EFI_IFR_OR_OP:

+    case EFI_IFR_NOT_OP:

+    case EFI_IFR_TRUE_OP:

+    case EFI_IFR_FALSE_OP:

+    case EFI_IFR_GT_OP:

+    case EFI_IFR_GE_OP:

+    case EFI_IFR_EQ_ID_LIST_OP:

+      //

+      // If we encountered a ConsistencyId value, on this page they will be incremental

+      // So register the first value we encounter.  We will pass this in when we re-create this page

+      //

+      if ((LocalTags->Tags[BackupIndex].ConsistencyId != 0) && (ConsistencyId == 0)) {

+        ConsistencyId = (UINT16) (LocalTags->Tags[BackupIndex].ConsistencyId - 1);

+      }

+      break;

+    }

+  }

+  //

+  // Delete the buffer associated with previous dynamic page

+  // We will re-allocate a buffer....

+  //

+  gBS->FreePool (LocalTags->Tags);

+

+  Length  = 0xF000;

+  Buffer  = AllocateZeroPool (Length);

+  ASSERT (Buffer != NULL);

+

+  //

+  // Get the form that was updated by the callback

+  //

+  Hii->GetForms (

+        Hii,

+        Selection->Handle,

+        TargetPage,

+        &Length,

+        Buffer

+        );

+

+  //

+  // Ok, we have the new page.....now we must purge the old page and re-allocate

+  // the tag page with the new data

+  //

+  UpdateNewTagData (

+    Buffer,

+    ConsistencyId,

+    CurrentVariable,

+    LocalTags,

+    FileFormTags

+    );

+

+  //

+  // return the Form Id, Text, and the File's FormTags structure

+  //

+  *FormHandle                       = LocalTags->Tags[0].Id;

+  *TitleToken                       = LocalTags->Tags[0].Text;

+  *FormTags                         = *LocalTags;

+

+  FormTags->Tags[0].CallbackHandle  = CallbackHandle;

+  CopyMem (&FormTags->Tags[0].GuidValue, &TagGuid, sizeof (EFI_GUID));

+

+  return ;

+}

+

+UI_MENU_OPTION *

+SetupBrowser (

+  IN  UI_MENU_OPTION              *Selection,

+  IN  BOOLEAN                     Callback,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  UINT8                       *CallbackData

+  )

+{

+  UINT16        FormHandle;

+  UINT16        TitleToken;

+  EFI_FORM_TAGS FormTags;

+

+  gEntryNumber  = -1;

+  gLastOpr      = FALSE;

+  //

+  // Displays the Header and Footer borders

+  //

+  DisplayPageFrame ();

+

+  //

+  // Id of 0 yields the getting of the top form whatever the ID is.  Usually the first form in the IFR

+  //

+  ExtractFormHandle (Selection, FileFormTagsHead, 0, &FormHandle, &TitleToken, &FormTags);

+

+  Selection = DisplayForm (Selection, FormHandle, TitleToken, FormTags, FileFormTagsHead, CallbackData);

+

+  //

+  // If selection is null use the former selection

+  //

+  if (Selection == NULL) {

+    return Selection;

+  }

+

+  if (Callback) {

+    return Selection;

+  }

+

+  while (Selection->Tags != NULL) {

+    if (Selection->Previous) {

+      ExtractFormHandle (Selection, FileFormTagsHead, Selection->FormId, &FormHandle, &TitleToken, &FormTags);

+    } else {

+      //

+      // True if a hyperlink/jump is selected

+      //

+      if (Selection->ThisTag->Operand == EFI_IFR_REF_OP && Selection->ThisTag->Id != 0x0000) {

+        if (Selection->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE) {

+          ExtractDynamicFormHandle (

+            Selection,

+            CallbackData,

+            FileFormTagsHead,

+            Selection->ThisTag->Id,

+            &FormHandle,

+            &TitleToken,

+            &FormTags

+            );

+          goto DisplayPage;

+        } else {

+          ExtractFormHandle (Selection, FileFormTagsHead, Selection->ThisTag->Id, &FormHandle, &TitleToken, &FormTags);

+          goto DisplayPage;

+        }

+      }

+

+      if ((Selection->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE) &&

+          (Selection->ThisTag->Operand != EFI_IFR_PASSWORD_OP)

+          ) {

+        ExtractDynamicFormHandle (

+          Selection,

+          CallbackData,

+          FileFormTagsHead,

+          Selection->FormId,

+          &FormHandle,

+          &TitleToken,

+          &FormTags

+          );

+      } else {

+        ExtractFormHandle (Selection, FileFormTagsHead, Selection->FormId, &FormHandle, &TitleToken, &FormTags);

+      }

+    }

+

+DisplayPage:

+    //

+    // Displays the Header and Footer borders

+    //

+    DisplayPageFrame ();

+

+    Selection = DisplayForm (Selection, FormHandle, TitleToken, FormTags, FileFormTagsHead, CallbackData);

+

+    if (Selection == NULL) {

+      break;

+    }

+  };

+

+  return Selection;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Print.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Print.c
new file mode 100644
index 0000000..a051b47
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Print.c
@@ -0,0 +1,338 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Print.c

+

+Abstract:

+

+  Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very

+  simple implemenation of SPrint() and Print() to support debug. 

+

+  You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a 

+  time. This makes the implementation very simple.

+

+  VSPrint, Print, SPrint format specification has the follwoing form

+

+  %type

+

+  type:

+    'S','s' - argument is an Unicode string

+    'c' - argument is an ascii character

+    '%' - Print a %

+

+--*/

+

+#include "Print.h"

+

+STATIC

+UINTN

+_IPrint (

+  IN UINTN                            Column,

+  IN UINTN                            Row,

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL     *Out,

+  IN CHAR16                           *fmt,

+  IN VA_LIST                          args

+  )

+//

+// Display string worker for: Print, PrintAt, IPrint, IPrintAt

+//

+{

+  CHAR16  *Buffer;

+  CHAR16  *BackupBuffer;

+  UINTN   Index;

+  UINTN   PreviousIndex;

+

+  //

+  // For now, allocate an arbitrarily long buffer

+  //

+  Buffer        = AllocateZeroPool (0x10000);

+  BackupBuffer  = AllocateZeroPool (0x10000);

+  ASSERT (Buffer);

+  ASSERT (BackupBuffer);

+

+  if (Column != (UINTN) -1) {

+    Out->SetCursorPosition (Out, Column, Row);

+  }

+

+  UnicodeVSPrint (Buffer, 0x10000, fmt, args);

+

+  Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;

+

+  Out->SetAttribute (Out, Out->Mode->Attribute);

+

+  Index         = 0;

+  PreviousIndex = 0;

+

+  do {

+    for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {

+      BackupBuffer[Index] = Buffer[Index];

+    }

+

+    if (Buffer[Index] == 0) {

+      break;

+    }

+    //

+    // Null-terminate the temporary string

+    //

+    BackupBuffer[Index] = 0;

+

+    //

+    // Print this out, we are about to switch widths

+    //

+    Out->OutputString (Out, &BackupBuffer[PreviousIndex]);

+

+    //

+    // Preserve the current index + 1, since this is where we will start printing from next

+    //

+    PreviousIndex = Index + 1;

+

+    //

+    // We are at a narrow or wide character directive.  Set attributes and strip it and print it

+    //

+    if (Buffer[Index] == NARROW_CHAR) {

+      //

+      // Preserve bits 0 - 6 and zero out the rest

+      //

+      Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;

+      Out->SetAttribute (Out, Out->Mode->Attribute);

+    } else {

+      //

+      // Must be wide, set bit 7 ON

+      //

+      Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;

+      Out->SetAttribute (Out, Out->Mode->Attribute);

+    }

+

+    Index++;

+

+  } while (Buffer[Index] != 0);

+

+  //

+  // We hit the end of the string - print it

+  //

+  Out->OutputString (Out, &BackupBuffer[PreviousIndex]);

+

+  gBS->FreePool (Buffer);

+  gBS->FreePool (BackupBuffer);

+  return EFI_SUCCESS;

+}

+

+UINTN

+Print (

+  IN CHAR16   *fmt,

+  ...

+  )

+/*++

+

+Routine Description:

+

+    Prints a formatted unicode string to the default console

+

+Arguments:

+

+    fmt         - Format string

+

+Returns:

+

+    Length of string printed to the console

+

+--*/

+{

+  VA_LIST args;

+

+  VA_START (args, fmt);

+  return _IPrint ((UINTN) -1, (UINTN) -1, gST->ConOut, fmt, args);

+}

+

+UINTN

+PrintString (

+  CHAR16       *String

+  )

+/*++

+

+Routine Description:

+

+  Prints a unicode string to the default console,

+  using L"%s" format.

+

+Arguments:

+

+  String      - String pointer.

+

+Returns:

+

+  Length of string printed to the console

+

+--*/

+{

+  return Print ((CHAR16 *) L"%s", String);

+}

+

+UINTN

+PrintChar (

+  CHAR16       Character

+  )

+/*++

+

+Routine Description:

+

+  Prints a chracter to the default console,

+  using L"%c" format.

+

+Arguments:

+

+  Character   - Character to print.

+

+Returns:

+

+  Length of string printed to the console.

+

+--*/

+{

+  return Print ((CHAR16 *) L"%c", Character);

+}

+

+/*

+UINTN

+PrintToken (

+  IN EFI_HII_HANDLE   Handle,

+  IN UINT16           Token,

+  IN CHAR16           *Language,

+  ...

+  )

+{

+  VA_LIST             args;

+  UINTN               NumberOfHiiHandles;

+  EFI_HANDLE          *HandleBuffer;

+  EFI_HII_PROTOCOL    *Hii;

+

+  //

+  // There should only be one HII image

+  //

+  Status = gBS->LocateHandleBuffer (

+                 ByProtocol, 

+                 &gEfiHiiProtocolGuid, 

+                 NULL,

+                 &NumberOfHiiHandles, 

+                 &HandleBuffer

+                 );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Retrieve the Hii protocol interface

+  //

+  Status = gBS->HandleProtocol (

+                 HandleBuffer[0], 

+                 &gEfiHiiProtocolGuid, 

+                 &Hii

+                 );

+

+  Hii->GetString (Hii, Handle, Token, FALSE, Language, 

+

+  VA_START (args, fmt);

+  return _IPrint ((UINTN) -1, (UINTN) -1, gST->ConOut, fmt, args);

+}

+

+*/

+UINTN

+PrintAt (

+  IN UINTN     Column,

+  IN UINTN     Row,

+  IN CHAR16    *fmt,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  Prints a formatted unicode string to the default console, at 

+  the supplied cursor position

+

+Arguments:

+

+  Column, Row - The cursor position to print the string at

+

+  fmt         - Format string

+

+Returns:

+

+  Length of string printed to the console

+

+--*/

+{

+  VA_LIST args;

+

+  VA_START (args, fmt);

+  return _IPrint (Column, Row, gST->ConOut, fmt, args);

+}

+

+UINTN

+PrintStringAt (

+  IN UINTN     Column,

+  IN UINTN     Row,

+  CHAR16       *String

+  )

+/*++

+

+Routine Description:

+

+  Prints a unicode string to the default console, at 

+  the supplied cursor position, using L"%s" format.

+

+Arguments:

+

+  Column, Row - The cursor position to print the string at

+

+  String      - String pointer.

+

+Returns:

+

+  Length of string printed to the console

+

+--*/

+{

+  return PrintAt (Column, Row, (CHAR16 *) L"%s", String);

+}

+

+UINTN

+PrintCharAt (

+  IN UINTN     Column,

+  IN UINTN     Row,

+  CHAR16       Character

+  )

+/*++

+

+Routine Description:

+

+  Prints a chracter to the default console, at 

+  the supplied cursor position, using L"%c" format.

+

+Arguments:

+

+  Column, Row - The cursor position to print the string at

+

+  Character   - Character to print.

+

+Returns:

+

+  Length of string printed to the console.

+

+--*/

+{

+  return PrintAt (Column, Row, (CHAR16 *) L"%c", Character);

+}

+

+

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Print.h b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Print.h
new file mode 100644
index 0000000..86feb88
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Print.h
@@ -0,0 +1,37 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Print.h

+

+Abstract:

+

+  Private data for Print.c

+

+--*/

+

+#ifndef _PRINT_H_

+#define _PRINT_H_

+

+#define LEFT_JUSTIFY  0x01

+#define PREFIX_SIGN   0x02

+#define PREFIX_BLANK  0x04

+#define COMMA_TYPE    0x08

+#define LONG_TYPE     0x10

+#define PREFIX_ZERO   0x20

+

+//

+// Largest number of characters that can be printed out.

+//

+#define EFI_DRIVER_LIB_MAX_PRINT_BUFFER (80 * 4)

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/ProcessOptions.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/ProcessOptions.c
new file mode 100644
index 0000000..8a878bc
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/ProcessOptions.c
@@ -0,0 +1,1677 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ProcessOptions.c

+

+Abstract:

+  

+  Implementation for handling the User Interface option processing.

+

+Revision History

+

+--*/

+

+#include "Setup.h"

+#include "Ui.h"

+

+EFI_STATUS

+ExtractRequestedNvMap (

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  UINT16                      VariableId,

+  OUT EFI_VARIABLE_DEFINITION     **VariableDefinition

+  )

+{

+  *VariableDefinition = FileFormTags->VariableDefinitions;

+

+  //

+  // Extract the data from the NV variable - consumer will free the buffer.

+  //

+  for (; *VariableDefinition != NULL; *VariableDefinition = (*VariableDefinition)->Next) {

+    //

+    // If there is a variable with this ID return with EFI_SUCCESS

+    //

+    if (!CompareMem (&(*VariableDefinition)->VariableId, &VariableId, sizeof (UINT16))) {

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+ExtractNvValue (

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  UINT16                      VariableId,

+  IN  UINT16                      VariableSize,

+  IN  UINT16                      OffsetValue,

+  OUT VOID                        **Buffer

+  )

+{

+  EFI_STATUS              Status;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+

+  Status = ExtractRequestedNvMap (FileFormTags, VariableId, &VariableDefinition);

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // Allocate sufficient space for the data and copy it into the outgoing buffer

+    //

+    if (VariableSize != 0) {

+      *Buffer = AllocateZeroPool (VariableSize);

+      ASSERT (*Buffer != NULL);

+      CopyMem (*Buffer, &VariableDefinition->NvRamMap[OffsetValue], VariableSize);

+    }

+    return EFI_SUCCESS;

+  }

+

+  return Status;

+}

+

+VOID

+AdjustNvMap (

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  UI_MENU_OPTION              *MenuOption

+  )

+{

+  CHAR8                   *NvRamMap;

+  UINTN                   SizeRequired;

+  UINTN                   Index;

+  UINTN                   CachedStart;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+

+  CachedStart   = 0;

+

+  SizeRequired  = MenuOption->ThisTag->StorageStart + MenuOption->ThisTag->StorageWidth;

+

+  ExtractRequestedNvMap (FileFormTags, MenuOption->Tags->VariableNumber, &VariableDefinition);

+

+  //

+  // We arrived here because the current NvRamMap is too small for the new op-code to store things and

+  // we need to adjust the buffer to support this.

+  //

+  NvRamMap = AllocateZeroPool (SizeRequired + 1);

+  ASSERT (NvRamMap != NULL);

+

+  //

+  // Copy current NvRamMap to the new NvRamMap

+  //

+  CopyMem (NvRamMap, VariableDefinition->NvRamMap, VariableDefinition->VariableFakeSize);

+

+  //

+  // Remember, the only time we come here is because we are in the NVPlus section of the NvRamMap

+  //

+  for (Index = MenuOption->TagIndex;

+       (MenuOption->Tags[Index].Operand != EFI_IFR_END_FORM_OP) && (MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP);

+       Index++

+      ) {

+

+    switch (MenuOption->Tags[Index].Operand) {

+    case EFI_IFR_ORDERED_LIST_OP:

+    case EFI_IFR_ONE_OF_OP:

+      CachedStart = MenuOption->Tags[Index].StorageStart;

+      break;

+

+    case EFI_IFR_ONE_OF_OPTION_OP:

+      if (MenuOption->Tags[Index].Flags & EFI_IFR_FLAG_DEFAULT) {

+        CopyMem (&NvRamMap[CachedStart], &MenuOption->Tags[Index].Value, 2);

+      }

+      break;

+

+    case EFI_IFR_CHECKBOX_OP:

+      CopyMem (&NvRamMap[MenuOption->Tags[Index].StorageStart], &MenuOption->Tags[Index].Flags, 1);

+      break;

+

+    case EFI_IFR_NUMERIC_OP:

+    case EFI_IFR_DATE_OP:

+    case EFI_IFR_TIME_OP:

+    case EFI_IFR_STRING_OP:

+    case EFI_IFR_PASSWORD_OP:

+      CopyMem (

+        &NvRamMap[MenuOption->Tags[Index].StorageStart],

+        &MenuOption->Tags[Index].Value,

+        MenuOption->Tags[Index].StorageWidth

+        );

+      break;

+

+    }

+  }

+

+  gBS->FreePool (VariableDefinition->NvRamMap);

+  VariableDefinition->NvRamMap          = NvRamMap;

+  VariableDefinition->VariableFakeSize  = (UINT16) SizeRequired;

+}

+

+EFI_STATUS

+ProcessOptions (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  BOOLEAN                     Selected,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  EFI_IFR_DATA_ARRAY          *PageData,

+  OUT CHAR16                      **OptionString

+  )

+{

+  EFI_STATUS                  Status;

+  CHAR16                      *StringPtr;

+  UINTN                       Index;

+  UINTN                       CachedIndex;

+  EFI_FILE_FORM_TAGS          *FileFormTags;

+  EFI_TAG                     *Tag;

+  CHAR16                      FormattedNumber[6];

+  UINT16                      Number;

+  UINT16                      Value;

+  UINT16                      *ValueArray;

+  UINT16                      *NvRamMap;

+  CHAR8                       *TmpNvRamMap;

+  UINTN                       Default;

+  UINTN                       StringCount;

+  CHAR16                      Character[2];

+  UINTN                       Count;

+  EFI_TIME                    Time;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  STRING_REF                  PopUp;

+  CHAR16                      NullCharacter;

+  EFI_INPUT_KEY               Key;

+  EFI_VARIABLE_DEFINITION     *VariableDefinition;

+  BOOLEAN                     OrderedList;

+  BOOLEAN                     Initialized;

+  UINT16                      KeyValue;

+  BOOLEAN                     Skip;

+

+  FileFormTags = FileFormTagsHead;

+

+  for (Index = 0; Index < MenuOption->IfrNumber; Index++) {

+    FileFormTags = FileFormTags->NextFile;

+  }

+

+  OrderedList         = FALSE;

+  Initialized         = FALSE;

+  ValueArray          = NULL;

+  VariableDefinition  = NULL;

+  Skip                = FALSE;

+

+  ZeroMem (&Time, sizeof (EFI_TIME));

+

+  StringPtr = (CHAR16 *) L"\0";

+  Tag       = MenuOption->ThisTag;

+  ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);

+

+  if (Tag->StorageStart > VariableDefinition->VariableSize) {

+    NvRamMap = (UINT16 *) &VariableDefinition->FakeNvRamMap[Tag->StorageStart];

+  } else {

+    NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+  }

+

+  StringCount   = 0;

+  Character[1]  = 0;

+  Count         = 0;

+  Default       = 0;

+  NullCharacter = CHAR_NULL;

+  FormCallback  = NULL;

+

+  if (MenuOption->ThisTag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+    OrderedList = TRUE;

+    if (((UINT8 *) NvRamMap)[0] != 0x00) {

+      Initialized = TRUE;

+    }

+  }

+

+  ZeroMem (FormattedNumber, 12);

+

+  Status = gBS->HandleProtocol (

+                  (VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,

+                  &gEfiFormCallbackProtocolGuid,

+                  (VOID **) &FormCallback

+                  );

+

+  if (*OptionString != NULL) {

+    gBS->FreePool (*OptionString);

+    *OptionString = NULL;

+  }

+

+  switch (Tag->Operand) {

+

+  case EFI_IFR_ORDERED_LIST_OP:

+  case EFI_IFR_ONE_OF_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    CachedIndex = MenuOption->TagIndex;

+

+    //

+    // search for EFI_IFR_ONE_OF_OPTION_OP until you hit the EFI_IFR_END_ONE_OF_OP,

+    // each of the .Text in the options are going to be what gets displayed.  Break each into 26 char chunks

+    // when hit right/left arrow allows for selection - then repopulate Tag[TagIndex] with the choice

+    //

+    for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; Index++) {

+      //

+      // We found an option - which assumedly has a string.  We will eventually have to support

+      // wrapping of strings.  For now, let's pretend they don't wrap and code that up.

+      //

+      // Count how many strings there are

+      //

+      if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+        //

+        // If one of the options for the one-of has an interactive flag, back-define the oneof to have one too

+        //

+        if (MenuOption->Tags[Index].Flags & EFI_IFR_FLAG_INTERACTIVE) {

+          MenuOption->Tags[CachedIndex].Flags = (UINT8) (MenuOption->Tags[CachedIndex].Flags | EFI_IFR_FLAG_INTERACTIVE);

+        }

+

+        StringCount++;

+      }

+    }

+    //

+    // We now know how many strings we will have, so we can allocate the

+    // space required for the array or strings.

+    //

+    *OptionString = AllocateZeroPool (StringCount * (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);

+    ASSERT (*OptionString);

+

+    //

+    // Add left delimeter to string

+    //

+    *OptionString[0] = LEFT_ONEOF_DELIMITER;

+

+    //

+    // Retrieve the current OneOf value

+    //

+    if (Selected) {

+      //

+      // Auto selection from list

+      //

+      Value = 0;

+      //

+      // Copy current setting to the seed Value

+      //

+      if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+        ValueArray = AllocateZeroPool (MenuOption->ThisTag->StorageWidth);

+        ASSERT (ValueArray != NULL);

+        CopyMem (ValueArray, NvRamMap, MenuOption->ThisTag->StorageWidth);

+      } else {

+        CopyMem (&Value, NvRamMap, MenuOption->ThisTag->StorageWidth);

+        CopyMem (gPreviousValue, NvRamMap, MenuOption->ThisTag->StorageWidth);

+      }

+

+      Number = Value;

+      if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+        Status = GetSelectionInputPopUp (MenuOption, Tag, MenuOption->ThisTag->StorageWidth, ValueArray, &KeyValue);

+      } else {

+        Status = GetSelectionInputPopUp (MenuOption, Tag, 1, &Value, &KeyValue);

+      }

+

+      if (!EFI_ERROR (Status)) {

+        if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+          CopyMem (NvRamMap, ValueArray, MenuOption->ThisTag->StorageWidth);

+          gBS->FreePool (ValueArray);

+        } else {

+          //

+          // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+          //

+          CopyMem (NvRamMap, &Value, Tag->StorageWidth);

+          MenuOption->ThisTag->Key = KeyValue;

+        }

+        //

+        // If a late check is required save off the information.  This is used when consistency checks

+        // are required, but certain values might be bound by an impossible consistency check such as

+        // if two questions are bound by consistency checks and each only has two possible choices, there

+        // would be no way for a user to switch the values.  Thus we require late checking.

+        //

+        if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) {

+          CopyMem (&Tag->OldValue, &Value, Tag->StorageWidth);

+        } else {

+          //

+          // In theory, passing the value and the Id are sufficient to determine what needs

+          // to be done.  The Id is the key to look for the entry needed in the Inconsistency

+          // database.  That will yields operand and ID data - and since the ID's correspond

+          // to the NV storage, we can determine the values for other IDs there.

+          //

+          if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) {

+            if (PopUp == 0x0000) {

+              //

+              // Restore Old Value

+              //

+              if (!Tag->Suppress && !Tag->GrayOut) {

+                CopyMem (NvRamMap, &Number, MenuOption->ThisTag->StorageWidth);

+              }

+              break;

+            }

+

+            StringPtr = GetToken (PopUp, MenuOption->Handle);

+

+            CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter);

+

+            do {

+              Status = WaitForKeyStroke (&Key);

+

+              switch (Key.UnicodeChar) {

+

+              case CHAR_CARRIAGE_RETURN:

+                //

+                // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+                //

+                CopyMem (NvRamMap, &Number, MenuOption->ThisTag->StorageWidth);

+                gBS->FreePool (StringPtr);

+                break;

+

+              default:

+                break;

+              }

+            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

+          }

+        }

+

+        UpdateStatusBar (NV_UPDATE_REQUIRED, Tag->Flags, TRUE);

+      } else {

+        if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {

+          gBS->FreePool (ValueArray);

+        }

+

+        return EFI_SUCCESS;

+      }

+    } else {

+      for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; Index++) {

+        //

+        // We found an option - which assumedly has a string.  We will eventually have to support

+        // wrapping of strings.  For now, let's pretend they don't wrap and code that up.

+        //

+        if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {

+          if (OrderedList) {

+            if (!Initialized) {

+              //

+              // If the first entry is invalid, then the "default" settings are based on what is reflected

+              // in the order of the op-codes

+              //

+              ((UINT8 *) NvRamMap)[Index - MenuOption->TagIndex - 1] = (UINT8) MenuOption->Tags[Index].Value;

+            }

+            //

+            // Only display 3 lines of stuff at most

+            //

+            if ((Index - MenuOption->TagIndex) > ORDERED_LIST_SIZE) {

+              break;

+            }

+

+            if (((Index - MenuOption->TagIndex) != 1) && !Skip) {

+              Character[0] = LEFT_ONEOF_DELIMITER;

+              NewStrCat (OptionString[0], Character);

+            }

+

+            MenuOption->ThisTag->NumberOfLines = (UINT16) (Index - MenuOption->TagIndex);

+            if (!Initialized) {

+              StringPtr = GetToken (MenuOption->Tags[Index].Text, MenuOption->Handle);

+            } else {

+              for (Value = (UINT16) (MenuOption->TagIndex + 1);

+                   MenuOption->Tags[Value].Operand != EFI_IFR_END_ONE_OF_OP;

+                   Value++

+                  ) {

+                if (MenuOption->Tags[Value].Value == ((UINT8 *) NvRamMap)[Index - MenuOption->TagIndex - 1]) {

+                  StringPtr = GetToken (MenuOption->Tags[Value].Text, MenuOption->Handle);

+                  break;

+                }

+              }

+

+              if (MenuOption->Tags[Value].Operand == EFI_IFR_END_ONE_OF_OP) {

+                Skip = TRUE;

+                continue;

+              }

+            }

+

+            Skip = FALSE;

+            NewStrCat (OptionString[0], StringPtr);

+            Character[0] = RIGHT_ONEOF_DELIMITER;

+            NewStrCat (OptionString[0], Character);

+            Character[0] = CHAR_CARRIAGE_RETURN;

+            NewStrCat (OptionString[0], Character);

+

+            //

+            // Remove Buffer allocated for StringPtr after it has been used.

+            //

+            gBS->FreePool (StringPtr);

+          } else {

+            //

+            // The option value is the same as what is stored in NV store.  Print this.

+            //

+            if (!CompareMem (&(MenuOption->Tags[Index].Value), NvRamMap, MenuOption->ThisTag->StorageWidth)) {

+              StringPtr = GetToken (MenuOption->Tags[Index].Text, MenuOption->Handle);

+              NewStrCat (OptionString[0], StringPtr);

+              Character[0] = RIGHT_ONEOF_DELIMITER;

+              NewStrCat (OptionString[0], Character);

+              //

+              // Remove Buffer allocated for StringPtr after it has been used.

+              //

+              gBS->FreePool (StringPtr);

+              Default = 0;

+              break;

+            }

+

+            if ((MenuOption->Tags[Index].Flags & EFI_IFR_FLAG_DEFAULT) == 1) {

+              Default = MenuOption->Tags[Index].Text;

+              Value   = MenuOption->Tags[Index].Value;

+            };

+          }

+        }

+      }

+      //

+      // We didn't find a value that matched a setting in the NVRAM Map - display default - set default

+      //

+      if (Default != 0) {

+        //

+        // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+        //

+        CopyMem (NvRamMap, &Value, MenuOption->ThisTag->StorageWidth);

+

+        StringPtr = GetToken ((UINT16) Default, MenuOption->Handle);

+        NewStrCat (OptionString[0], StringPtr);

+        Character[0] = RIGHT_ONEOF_DELIMITER;

+        NewStrCat (OptionString[0], Character);

+        //

+        // Remove Buffer allocated for StringPtr after it has been used.

+        //

+        gBS->FreePool (StringPtr);

+      }

+    }

+    break;

+

+  case EFI_IFR_CHECKBOX_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    Default = Tag->Flags & 1;

+    //

+    // If hit spacebar, set or unset Tag[TagIndex].Flags based on it's previous value - BOOLEAN

+    //

+    *OptionString = AllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);

+    ASSERT (*OptionString);

+

+    //

+    // Since Checkboxes are BOOLEAN values, bit 0 of the Flags bit defines the default option, therefore, if

+    // the default option (only one option for checkboxes) is on, then the default value is on.  Tag.Default is not

+    // an active field for Checkboxes.

+    //

+    StrnCpy (OptionString[0], (CHAR16 *) LEFT_CHECKBOX_DELIMITER, 1);

+

+    //

+    // Since this is a BOOLEAN operation, flip bit 0 upon selection

+    //

+    if (Selected) {

+      Tag->Value          = (UINT16) (Tag->Value ^ 1);

+      *(UINT8 *) NvRamMap = (UINT8) (Tag->Value & 1);

+      UpdateStatusBar (NV_UPDATE_REQUIRED, Tag->Flags, TRUE);

+    }

+

+    if ((*(UINT8 *) NvRamMap & 1) == 0x01) {

+      NewStrCat (OptionString[0], (CHAR16 *) CHECK_ON);

+      //

+      // If someone reset default variables - we may need to reload from our NvMapping....

+      //

+      Tag->Value = *(UINT8 *) NvRamMap;

+    } else {

+      //

+      // If someone reset default variables - we may need to reload from our NvMapping....

+      //

+      NewStrCat (OptionString[0], (CHAR16 *) CHECK_OFF);

+      Tag->Value = *(UINT8 *) NvRamMap;

+    }

+

+    NewStrCat (OptionString[0], (CHAR16 *) RIGHT_CHECKBOX_DELIMITER);

+    NewStrCat (OptionString[0], StringPtr);

+    break;

+

+  case EFI_IFR_NUMERIC_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    *OptionString = AllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);

+    ASSERT (*OptionString);

+

+    //

+    // Add left delimeter to string

+    //

+    *OptionString[0] = LEFT_NUMERIC_DELIMITER;

+

+    //

+    // Retrieve the current numeric value

+    //

+    if (Selected) {

+      //

+      // Go ask for input

+      //

+      if (Tag->Step == 0) {

+        //

+        // Manual Input

+        //

+        Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, REGULAR_NUMERIC, &Number);

+        if (!EFI_ERROR (Status)) {

+          CopyMem (gPreviousValue, NvRamMap, MenuOption->ThisTag->StorageWidth);

+          UpdateStatusBar (NV_UPDATE_REQUIRED, Tag->Flags, TRUE);

+

+          //

+          // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+          //

+          CopyMem (NvRamMap, &Number, MenuOption->ThisTag->StorageWidth);

+        } else {

+          return EFI_SUCCESS;

+        }

+      } else {

+        //

+        // Auto selection from list

+        //

+        if ((((Tag->StorageWidth == 1) && (UINT8) (*NvRamMap) > Tag->Maximum) || ((UINT8) (*NvRamMap) < Tag->Minimum)) ||

+            (((Tag->StorageWidth == 2) && *NvRamMap > Tag->Maximum) || (*NvRamMap < Tag->Minimum))

+            ) {

+          //

+          // Seed Number with valid value if currently invalid

+          //

+          Number = Tag->Default;

+        } else {

+          if (Tag->StorageWidth == 1) {

+            Number = (UINT8) (*NvRamMap);

+          } else {

+            Number = *NvRamMap;

+          }

+        }

+

+        Status = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, REGULAR_NUMERIC, &Number);

+        if (!EFI_ERROR (Status)) {

+          CopyMem (gPreviousValue, NvRamMap, MenuOption->ThisTag->StorageWidth);

+          UpdateStatusBar (NV_UPDATE_REQUIRED, Tag->Flags, TRUE);

+

+          //

+          // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+          //

+          CopyMem (NvRamMap, &Number, MenuOption->ThisTag->StorageWidth);

+        } else {

+          return EFI_SUCCESS;

+        }

+      }

+    } else {

+      if (((Tag->StorageWidth == 1) && (UINT8) (*NvRamMap) <= Tag->Maximum && (UINT8) (*NvRamMap) >= Tag->Minimum) ||

+          ((Tag->StorageWidth == 2) && *NvRamMap <= Tag->Maximum && *NvRamMap >= Tag->Minimum)

+          ) {

+        if (Tag->StorageWidth == 1) {

+          Number = (UINT8) (*NvRamMap);

+        } else {

+          Number = *NvRamMap;

+        }

+        UnicodeValueToString (

+          FormattedNumber, 

+          FALSE, 

+          (UINTN) Number, 

+          (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+          );

+        Number = (UINT16) GetStringWidth (FormattedNumber);

+        StrnCpy (OptionString[0] + 1, FormattedNumber, Number);

+      } else {

+        //

+        // If *NvRamMap isn't within parameters, set it to within parameters

+        //

+        //

+        // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+        //

+        CopyMem (NvRamMap, &Tag->Default, MenuOption->ThisTag->StorageWidth);

+        Number = Tag->Default;

+

+        UnicodeValueToString (

+          FormattedNumber, 

+          FALSE, 

+          (UINTN) Number, 

+          (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+          );

+        Number = (UINT16) GetStringWidth (FormattedNumber);

+        StrnCpy (OptionString[0] + 1, FormattedNumber, Number);

+      }

+

+      *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;

+      NewStrCat (OptionString[0] + (Number / 2) + 1, StringPtr);

+    }

+    break;

+

+  case EFI_IFR_DATE_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    Status = gRT->GetTime (&Time, NULL);

+    if (EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    }

+    //

+    // This for loop advances Index till it points immediately after a date entry.  We can then

+    // subtract MenuOption->TagIndex from Index and find out relative to the start of the Date

+    // structure which field we were in.  For instance, if TagIndex was 52, and we advanced Index

+    // to 53 and found it to no longer point to a date operand, we were pointing to the last of 3

+    // date operands.

+    //

+    //

+    // This has BUGBUG potential....fix this - if someone wants to ask two DATE questions in a row.....code

+    // against such silliness.

+    //

+    // Also, we want to internationalize the order of the date information.  We need to code for it as well.

+    //

+    for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand == EFI_IFR_DATE_OP; Index++)

+      ;

+

+    //

+    // Count 0 = We entered on the first Date operand

+    // Count 1 = We entered on the second Date operand

+    // Count 2 = We entered on the third Date operand

+    //

+    Count = 3 - (Index - MenuOption->TagIndex);

+    if (Count > 2) {

+      return EFI_SUCCESS;

+    }

+    //

+    // This is similar to numerics, except for the following:

+    // We will under normal circumstances get 3 consecutive calls

+    // to process this opcodes data.

+    //

+    *OptionString = AllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);

+    ASSERT (*OptionString);

+

+    switch (Count) {

+    case 0:

+      if (Selected) {

+        Number = (UINT16) Time.Month;

+

+        if (Tag->Step == 0) {

+          MenuOption->OptCol++;

+          Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, DATE_NUMERIC, &Number);

+        } else {

+          //

+          // Seed value with current setting

+          //

+          Tag->Value  = (UINT16) Time.Month;

+          Status      = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, DATE_NUMERIC, &Number);

+        }

+

+        if (!EFI_ERROR (Status)) {

+          Time.Month = (UINT8) Number;

+          gRT->SetTime (&Time);

+        }

+      }

+

+      VariableDefinition->FakeNvRamMap[Tag->Id] = Time.Month;

+      *OptionString[0]                          = LEFT_NUMERIC_DELIMITER;

+

+      UnicodeValueToString (

+        FormattedNumber, 

+        FALSE, 

+        (UINTN) Time.Month, 

+        (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+        );

+      Number = (UINT16) GetStringWidth (FormattedNumber);

+

+      if (Number == 4) {

+        FormattedNumber[2]  = FormattedNumber[1];

+        FormattedNumber[1]  = FormattedNumber[0];

+        FormattedNumber[0]  = L'0';

+        Number              = 6;

+      }

+

+      StrnCpy (OptionString[0] + 1, FormattedNumber, Number);

+      *(OptionString[0] + Number / 2) = DATE_SEPARATOR;

+      StrCat (OptionString[0] + (Number / 2) + 1, StringPtr);

+      break;

+

+    case 1:

+      if (Selected) {

+        Number = (UINT16) Time.Day;

+

+        if (Tag->Step == 0) {

+          Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, DATE_NUMERIC, &Number);

+        } else {

+          //

+          // Seed value with current setting

+          //

+          Tag->Value  = (UINT16) Time.Day;

+          Status      = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, DATE_NUMERIC, &Number);

+        }

+

+        if (!EFI_ERROR (Status)) {

+          Time.Day = (UINT8) Number;

+          gRT->SetTime (&Time);

+        }

+      }

+

+      VariableDefinition->FakeNvRamMap[Tag->Id] = Time.Day;

+      SetUnicodeMem (OptionString[0], 4, L' ');

+

+      UnicodeValueToString (

+        FormattedNumber, 

+        FALSE, 

+        (UINTN) Time.Day, 

+        (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+        );

+      Number = (UINT16) GetStringWidth (FormattedNumber);

+      if (Number == 4) {

+        FormattedNumber[2]  = FormattedNumber[1];

+        FormattedNumber[1]  = FormattedNumber[0];

+        FormattedNumber[0]  = L'0';

+        Number              = 6;

+      }

+

+      StrnCpy (OptionString[0] + 4, FormattedNumber, Number);

+      *(OptionString[0] + Number / 2 + 3) = DATE_SEPARATOR;

+      StrCat (OptionString[0] + (Number / 2) + 4, StringPtr);

+      break;

+

+    case 2:

+      if (Selected) {

+        Number = (UINT16) Time.Year;

+

+        if (Tag->Step == 0) {

+          Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, DATE_NUMERIC, &Number);

+        } else {

+          //

+          // Seed value with current setting

+          //

+          Status = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, DATE_NUMERIC, &Number);

+        }

+

+        if (!EFI_ERROR (Status)) {

+          Time.Year = (UINT16) Number;

+          gRT->SetTime (&Time);

+        }

+      }

+

+      Tag->Value  = (UINT16) Time.Year;

+      VariableDefinition->FakeNvRamMap[Tag->Id]     = (UINT8) Tag->Value;

+      VariableDefinition->FakeNvRamMap[Tag->Id + 1] = (UINT8) (Tag->Value >> 8);

+      SetUnicodeMem (OptionString[0], 7, L' ');

+      UnicodeValueToString (

+        FormattedNumber, 

+        FALSE, 

+        (UINTN) Time.Year, 

+        (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+        );

+      Number = (UINT16) GetStringWidth (FormattedNumber);

+      StrnCpy (OptionString[0] + 7, FormattedNumber, Number);

+      *(OptionString[0] + Number / 2 + 6) = RIGHT_NUMERIC_DELIMITER;

+      StrCat (OptionString[0] + (Number / 2) + 7, StringPtr);

+      break;

+    }

+

+    break;

+

+  //

+  // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG

+  // We need to add code to support the NVRam storage version of Date - this is the 1% case where someone

+  // might want to set an alarm and actually preserve the data in NVRam so a driver can pick up the instruction

+  // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG

+  //

+  case EFI_IFR_TIME_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    Status = gRT->GetTime (&Time, NULL);

+    if (EFI_ERROR (Status)) {

+      return EFI_SUCCESS;

+    }

+    //

+    // This is similar to numerics, except for the following:

+    // We will under normal circumstances get 3 consecutive calls

+    // to process this opcodes data.

+    //

+    *OptionString = AllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);

+    ASSERT (*OptionString);

+

+    //

+    // This for loop advances Index till it points immediately after a date entry.  We can then

+    // subtract MenuOption->TagIndex from Index and find out relative to the start of the Date

+    // structure which field we were in.  For instance, if TagIndex was 52, and we advanced Index

+    // to 53 and found it to no longer point to a date operand, we were pointing to the last of 3

+    // date operands.

+    //

+    for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand == EFI_IFR_TIME_OP; Index++)

+      ;

+    //

+    // Count 0 = We entered on the first Date operand

+    // Count 1 = We entered on the second Date operand

+    // Count 2 = We entered on the third Date operand

+    //

+    Count = 3 - (Index - MenuOption->TagIndex);

+    if (Count > 2) {

+      return EFI_SUCCESS;

+    }

+

+    switch (Count) {

+    case 0:

+      Number = Time.Hour;

+      break;

+

+    case 1:

+      Number = Time.Minute;

+      break;

+

+    case 2:

+      Number = Time.Second;

+    }

+    //

+    // Retrieve the current numeric value

+    //

+    if (Selected) {

+      //

+      // Go ask for input

+      //

+      if (Tag->Step == 0) {

+        //

+        // Manual Input

+        //

+        Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, TIME_NUMERIC, &Number);

+        if (!EFI_ERROR (Status)) {

+          *NvRamMap       = Number;

+          Time.Nanosecond = 0;

+          gRT->SetTime (&Time);

+        } else {

+          return EFI_SUCCESS;

+        }

+      } else {

+        //

+        // Auto selection from list

+        //

+        Status = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, TIME_NUMERIC, &Number);

+        if (!EFI_ERROR (Status)) {

+          *NvRamMap = Number;

+        } else {

+          return EFI_SUCCESS;

+        }

+      }

+

+      switch (Count) {

+      case 0:

+        Time.Hour = (UINT8) Number;

+        break;

+

+      case 1:

+        Time.Minute = (UINT8) Number;

+        break;

+

+      case 2:

+        Time.Second = (UINT8) Number;

+      }

+

+      Time.Nanosecond = 0;

+      gRT->SetTime (&Time);

+    } else {

+      switch (Count) {

+      case 0:

+        *OptionString[0] = LEFT_NUMERIC_DELIMITER;

+        UnicodeValueToString (

+          FormattedNumber, 

+          FALSE, 

+          (UINTN) Time.Hour, 

+          (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+          );

+        Number = (UINT16) GetStringWidth (FormattedNumber);

+        if (Number == 4) {

+          FormattedNumber[2]  = FormattedNumber[1];

+          FormattedNumber[1]  = FormattedNumber[0];

+          FormattedNumber[0]  = L'0';

+          Number              = 6;

+        }

+

+        StrnCpy (OptionString[0] + 1, FormattedNumber, Number);

+        *(OptionString[0] + Number / 2) = TIME_SEPARATOR;

+        StrCat (OptionString[0] + (Number / 2) + 1, StringPtr);

+        break;

+

+      case 1:

+        SetUnicodeMem (OptionString[0], 4, L' ');

+        UnicodeValueToString (

+          FormattedNumber, 

+          FALSE, 

+          (UINTN) Time.Minute, 

+          (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+          );

+        Number = (UINT16) GetStringWidth (FormattedNumber);

+        if (Number == 4) {

+          FormattedNumber[2]  = FormattedNumber[1];

+          FormattedNumber[1]  = FormattedNumber[0];

+          FormattedNumber[0]  = L'0';

+          Number              = 6;

+        }

+

+        StrnCpy (OptionString[0] + 4, FormattedNumber, Number);

+        *(OptionString[0] + Number / 2 + 3) = TIME_SEPARATOR;

+        StrCat (OptionString[0] + (Number / 2) + 4, StringPtr);

+        break;

+

+      case 2:

+        SetUnicodeMem (OptionString[0], 7, L' ');

+        UnicodeValueToString (

+          FormattedNumber, 

+          FALSE, 

+          (UINTN) Time.Second, 

+          (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))

+          );

+        Number = (UINT16) GetStringWidth (FormattedNumber);

+        if (Number == 4) {

+          FormattedNumber[2]  = FormattedNumber[1];

+          FormattedNumber[1]  = FormattedNumber[0];

+          FormattedNumber[0]  = L'0';

+          Number              = 6;

+        }

+

+        StrnCpy (OptionString[0] + 7, FormattedNumber, Number);

+        *(OptionString[0] + Number / 2 + 6) = RIGHT_NUMERIC_DELIMITER;

+        StrCat (OptionString[0] + (Number / 2) + 7, StringPtr);

+        break;

+      }

+      //

+      // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG

+      // We need to add code to support the NVRam storage version of Date - this is the 1% case where someone

+      // might want to set an alarm and actually preserve the data in NVRam so a driver can pick up the instruction

+      // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG

+      //

+    }

+    break;

+

+  case EFI_IFR_STRING_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    *OptionString = AllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);

+    ASSERT (*OptionString);

+

+    if (Selected) {

+      StringPtr = AllocateZeroPool (Tag->Maximum);

+      ASSERT (StringPtr);

+

+      Status = ReadString (MenuOption, StringPtr);

+

+      if (!EFI_ERROR (Status)) {

+        CopyMem (gPreviousValue, NvRamMap, MenuOption->ThisTag->StorageWidth);

+        CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], StringPtr, Tag->StorageWidth);

+

+        UpdateStatusBar (NV_UPDATE_REQUIRED, Tag->Flags, TRUE);

+      }

+

+      gBS->FreePool (StringPtr);

+      return Status;

+    } else {

+      for (Index = 0; Index < gOptionBlockWidth; Index++) {

+        if (VariableDefinition->NvRamMap[Tag->StorageStart + (Index * 2)] != 0x0000) {

+          CopyMem (OptionString[0] + Index, &VariableDefinition->NvRamMap[Tag->StorageStart + (Index * 2)], 2);

+        } else {

+          if (Index == 0) {

+            *(OptionString[0] + Index)      = '_';

+            *(OptionString[0] + 1 + Index)  = 0;

+          }

+          break;

+        }

+      }

+

+      return Status;

+    }

+

+  case EFI_IFR_PASSWORD_OP:

+    //

+    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically

+    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust

+    // the NvMap so that we can properly display the information

+    //

+    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {

+      AdjustNvMap (FileFormTags, MenuOption);

+      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+    }

+

+    if (Selected) {

+      StringPtr = AllocateZeroPool (Tag->Maximum);

+      ASSERT (StringPtr);

+

+      //

+      // If interactive, read the password and do the appropriate callbacks in that routine.

+      // Since interactive passwords assume to handle the password data in a separate variable

+      // storage, we don't need to do more than what is below for password callbacks

+      //

+      if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) {

+        MenuOption->Tags[0].CallbackHandle  = FileFormTags->FormTags.Tags[0].CallbackHandle;

+        Status = ReadPassword (MenuOption, TRUE, Tag, PageData, FALSE, FileFormTags, StringPtr);

+        ZeroMem (StringPtr, Tag->Maximum);

+

+        if (EFI_ERROR (Status)) {

+          if (Status == EFI_NOT_READY) {

+            gBS->FreePool (StringPtr);

+            return EFI_SUCCESS;

+          }

+        }

+

+        Status = ReadPassword (MenuOption, TRUE, Tag, PageData, TRUE, FileFormTags, StringPtr);

+        gBS->FreePool (StringPtr);

+        return EFI_SUCCESS;

+      }

+

+      for (Index = 0; Index < Tag->Maximum; Index++) {

+        if (VariableDefinition->NvRamMap[Tag->StorageStart + Index] != 0x00) {

+          //

+          // There is something there!  Prompt for password

+          //

+          Status = ReadPassword (MenuOption, TRUE, Tag, PageData, FALSE, FileFormTags, StringPtr);

+          if (EFI_ERROR (Status)) {

+            gBS->FreePool (StringPtr);

+            return EFI_SUCCESS;

+          }

+

+          if (Tag->Encoding == 1) {

+            EncodePassword (StringPtr, (UINT8) Tag->Maximum);

+            Status = CompareMem (StringPtr, &VariableDefinition->NvRamMap[Tag->StorageStart], Tag->Maximum);

+          } else {

+            Status = CompareMem (StringPtr, &VariableDefinition->NvRamMap[Tag->StorageStart], Tag->Maximum);

+          }

+

+          if (Status != 0) {

+            gBS->FreePool (StringPtr);

+            return EFI_SUCCESS;

+          } else {

+            break;

+          }

+        }

+      }

+      //

+      // Clean the string

+      //

+      ZeroMem (StringPtr, Tag->Maximum);

+

+      //

+      // No password set!  Go ahead and prompt the user for a password.

+      //

+      Status = ReadPassword (MenuOption, FALSE, Tag, PageData, FALSE, FileFormTags, StringPtr);

+

+      if (EFI_ERROR (Status)) {

+        //

+        // User couldn't figure out how to type two identical passwords

+        //

+        gBS->FreePool (StringPtr);

+        return EFI_SUCCESS;

+      }

+      //

+      // Very simple example of how one MIGHT do password encoding

+      //

+      if (Tag->Encoding == 1) {

+        EncodePassword (StringPtr, (UINT8) Tag->Maximum);

+      }

+

+      TmpNvRamMap = AllocatePool (VariableDefinition->VariableSize);

+      ASSERT (TmpNvRamMap != NULL);

+

+      Count = VariableDefinition->VariableSize;

+

+      if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {

+        Status = FormCallback->NvRead (

+                                FormCallback,

+                                VariableDefinition->VariableName,

+                                &VariableDefinition->Guid,

+                                NULL,

+                                &Count,

+                                (VOID *) TmpNvRamMap

+                                );

+      } else {

+        Status = gRT->GetVariable (

+                        VariableDefinition->VariableName,

+                        &VariableDefinition->Guid,

+                        NULL,

+                        &Count,

+                        (VOID *) TmpNvRamMap

+                        );

+      }

+

+      CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], StringPtr, Tag->StorageWidth);

+      CopyMem (&TmpNvRamMap[Tag->StorageStart], StringPtr, Tag->StorageWidth);

+

+      if ((FormCallback != NULL) && (FormCallback->NvWrite != NULL)) {

+        Status = FormCallback->NvWrite (

+                                FormCallback,

+                                VariableDefinition->VariableName,

+                                &VariableDefinition->Guid,

+                                EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                                VariableDefinition->VariableSize,

+                                (VOID *) TmpNvRamMap,

+                                &gResetRequired

+                                );

+      } else {

+        Status = gRT->SetVariable (

+                        VariableDefinition->VariableName,

+                        &VariableDefinition->Guid,

+                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                        VariableDefinition->VariableSize,

+                        (VOID *) TmpNvRamMap

+                        );

+      }

+

+      gBS->FreePool (TmpNvRamMap);

+      gBS->FreePool (StringPtr);

+      break;

+    }

+

+  default:

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+ProcessHelpString (

+  IN  CHAR16                      *StringPtr,

+  OUT CHAR16                      **FormattedString,

+  IN  UINTN                       RowCount

+  )

+{

+  UINTN CurrIndex;

+  UINTN PrevIndex;

+  UINTN SearchIndex;

+  UINTN PrevSearchIndex;

+  UINTN StringCount;

+  UINTN PageCount;

+

+  StringCount = 0;

+  PrevIndex   = 0;

+  CurrIndex   = gHelpBlockWidth - 1;

+

+  if (*FormattedString != NULL) {

+    gBS->FreePool (*FormattedString);

+    *FormattedString = NULL;

+  }

+

+  for (; CurrIndex > PrevIndex; CurrIndex--) {

+    //

+    // In the case where the string ended and a new one is immediately after it

+    // we need to check for the null-terminator and reset the CurrIndex

+    //

+    SearchIndex     = CurrIndex;

+    PrevSearchIndex = PrevIndex;

+

+    for (; SearchIndex > PrevSearchIndex; PrevSearchIndex++) {

+      if ((StringPtr[PrevSearchIndex] == CHAR_NULL) || (StringPtr[PrevSearchIndex] == CHAR_LINEFEED)) {

+        CurrIndex = PrevSearchIndex;

+        break;

+      }

+

+      if (StringPtr[PrevSearchIndex] == CHAR_CARRIAGE_RETURN) {

+        if (StringPtr[PrevSearchIndex + 1] == CHAR_LINEFEED) {

+          //

+          // Found a "\n",advance to the next new line.

+          //

+          CurrIndex = PrevSearchIndex + 1;

+          break;

+        } else {

+          //

+          // Found a "\r",return to the start of the current line.

+          //

+          PrevIndex = PrevSearchIndex + 1;

+          CurrIndex = PrevSearchIndex + gHelpBlockWidth;

+          continue;

+        }

+      }

+    }

+

+    //

+    // End of the string, thus stop counting.

+    //

+    if (StringPtr[CurrIndex] == CHAR_NULL) {

+      StringCount++;

+      break;

+    }

+    //

+    // The premise is that for every HELP_BLOCK_WIDTH we rewind

+    // until we find the first space.  That is the delimiter for

+    // the string, and we will then advance our CurrIndex another

+    // HELP_BLOCK_WIDTH and continue the process breaking the larger

+    // string into chunks that fit within the HELP_BLOCK_WIDTH requirements.

+    //

+    if (StringPtr[CurrIndex] == CHAR_SPACE) {

+      //

+      // How many strings have been found?

+      //

+      StringCount++;

+      PrevIndex = CurrIndex + 1;

+      CurrIndex = CurrIndex + gHelpBlockWidth;

+    }

+    //

+    // Found a Linefeed, advance to the next line.

+    //

+    if (StringPtr[CurrIndex] == CHAR_LINEFEED) {

+      StringCount++;

+      PrevIndex = CurrIndex + 1;

+      CurrIndex = CurrIndex + gHelpBlockWidth;

+    }

+  }

+  //

+  // endfor

+  //

+  // Round the value up one (doesn't hurt)

+  //

+  StringCount++;

+

+  //

+  // Determine the number of pages this help string occupies

+  //

+  PageCount = StringCount / RowCount;

+  if (StringCount % RowCount > 0) {

+    PageCount++;

+  }

+  //

+  // Convert the PageCount into lines so we can allocate the correct buffer size

+  //

+  StringCount = PageCount * RowCount;

+

+  //

+  // We now know how many strings we will have, so we can allocate the

+  // space required for the array or strings.

+  //

+  *FormattedString = AllocateZeroPool ((StringCount) * (gHelpBlockWidth + 1) * 2);

+  ASSERT (*FormattedString);

+

+  StringCount = 0;

+  PrevIndex   = 0;

+  CurrIndex   = gHelpBlockWidth - 1;

+

+  for (; CurrIndex > PrevIndex; CurrIndex--) {

+    //

+    // In the case where the string ended and a new one is immediately after it

+    // we need to check for the null-terminator and reset the CurrIndex

+    //

+    SearchIndex     = CurrIndex;

+    PrevSearchIndex = PrevIndex;

+

+    for (; SearchIndex > PrevSearchIndex; PrevSearchIndex++) {

+      if ((StringPtr[PrevSearchIndex] == CHAR_NULL) || (StringPtr[PrevSearchIndex] == CHAR_LINEFEED)) {

+        CurrIndex = PrevSearchIndex;

+        break;

+      }

+

+      if (StringPtr[PrevSearchIndex] == CHAR_CARRIAGE_RETURN) {

+        if (StringPtr[PrevSearchIndex + 1] == CHAR_LINEFEED) {

+          //

+          // Found a "\n",advance to the next new line.

+          //

+          CurrIndex = PrevSearchIndex + 1;

+          break;

+        } else {

+          //

+          // Found a "\r",return to the start of the current line.

+          //

+          PrevIndex = PrevSearchIndex + 1;

+          CurrIndex = PrevSearchIndex + gHelpBlockWidth;

+          continue;

+        }

+      }

+    }

+

+    //

+    // End of the string, thus stop counting.

+    //

+    if (StringPtr[CurrIndex] == CHAR_NULL) {

+      //

+      // Copy the fragment to the FormattedString buffer

+      //

+      StrnCpy ((FormattedString[0] + StringCount * gHelpBlockWidth), &StringPtr[PrevIndex], CurrIndex - PrevIndex);

+      StringCount++;

+      break;

+    }

+    //

+    // The premise is that for every HELP_BLOCK_WIDTH we rewind

+    // until we find the first space.  That is the delimiter for

+    // the string, and we will then advance our CurrIndex another

+    // HELP_BLOCK_WIDTH and continue the process breaking the larger

+    // string into chunks that fit within the HELP_BLOCK_WIDTH requirements.

+    //

+    if (StringPtr[CurrIndex] == CHAR_SPACE) {

+      //

+      // Copy the fragment to the FormattedString buffer

+      //

+      StrnCpy ((FormattedString[0] + StringCount * gHelpBlockWidth), &StringPtr[PrevIndex], CurrIndex - PrevIndex);

+      StringCount++;

+      PrevIndex = CurrIndex + 1;

+      CurrIndex = CurrIndex + gHelpBlockWidth;

+    }

+    //

+    // Found a LineFeed, advance to the next line.

+    //

+    if (StringPtr[CurrIndex] == CHAR_LINEFEED) {

+      StringPtr[CurrIndex] = CHAR_SPACE;

+      //

+      // "\n" is represented as CHAR_CARRIAGE_RETURN + CHAR_LINEFEED,check this.

+      //

+      if (StringPtr[CurrIndex - 1] == CHAR_CARRIAGE_RETURN) {

+        StringPtr[CurrIndex - 1] = CHAR_SPACE;

+      }

+

+      StrnCpy ((FormattedString[0] + StringCount * gHelpBlockWidth), &StringPtr[PrevIndex], CurrIndex - PrevIndex);

+      StringCount++;

+      PrevIndex = CurrIndex + 1;

+      CurrIndex = CurrIndex + gHelpBlockWidth;

+    }

+  }

+  //

+  // endfor

+  //

+  return ;

+}

+

+VOID

+IfrToFormTag (

+  IN  UINT8               OpCode,

+  IN  EFI_TAG             *TargetTag,

+  IN  VOID                *FormData,

+  EFI_VARIABLE_DEFINITION *VariableDefinitionsHead

+  )

+{

+  UINT16                  TempValue;

+  CHAR16                  *VariableName;

+  CHAR8                   *AsciiString;

+  EFI_VARIABLE_DEFINITION *VariableDefinitions;

+  EFI_VARIABLE_DEFINITION *PreviousVariableDefinitions;

+  STATIC UINT16           VariableSize;

+  EFI_GUID                Guid;

+  STATIC UINT16           CurrentVariable;

+  STATIC UINT16           CurrentVariable2;

+  UINTN                   Index;

+

+  switch (OpCode) {

+  case EFI_IFR_FORM_OP:

+    CopyMem (&TargetTag->Id, &((EFI_IFR_FORM *) FormData)->FormId, sizeof (UINT16));

+    CopyMem (&TargetTag->Text, &((EFI_IFR_FORM *) FormData)->FormTitle, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    if (VariableDefinitionsHead != NULL) {

+      VariableName = AllocateZeroPool (12);

+      ASSERT (VariableName != NULL);

+      CopyMem (VariableName, L"Setup", 12);

+      VariableDefinitionsHead->VariableName = VariableName;

+      VariableDefinitionsHead->VariableSize = VariableSize;

+      CopyMem (&VariableDefinitionsHead->Guid, &Guid, sizeof (EFI_GUID));

+    }

+    break;

+

+  case EFI_IFR_SUBTITLE_OP:

+    TargetTag->NumberOfLines = 1;

+    CopyMem (&TargetTag->Text, &((EFI_IFR_SUBTITLE *) FormData)->SubTitle, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_TEXT_OP:

+    TargetTag->NumberOfLines = 1;

+    CopyMem (&TargetTag->Text, &((EFI_IFR_TEXT *) FormData)->Text, sizeof (UINT16));

+    CopyMem (&TargetTag->Help, &((EFI_IFR_TEXT *) FormData)->Help, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+

+    //

+    // To optimize the encoding size, certain opcodes have optional fields such as those

+    // inside the if() statement.  If the encoded length is the complete size, then we

+    // know we have valid data encoded that we want to integrate

+    //

+    if (((EFI_IFR_TEXT *) FormData)->Header.Length == sizeof (EFI_IFR_TEXT)) {

+      //

+      // Text has no help associated with it, but in case there is a second entry due to

+      // dynamic/interactive flags being active, bring this data over.

+      //

+      CopyMem (&TargetTag->TextTwo, &((EFI_IFR_TEXT *) FormData)->TextTwo, sizeof (UINT16));

+      TargetTag->Flags = ((EFI_IFR_TEXT *) FormData)->Flags;

+      CopyMem (&TargetTag->Key, &((EFI_IFR_TEXT *) FormData)->Key, sizeof (UINT16));

+    }

+    break;

+

+  case EFI_IFR_ONE_OF_OPTION_OP:

+    CopyMem (&TargetTag->Text, &((EFI_IFR_ONE_OF_OPTION *) FormData)->Option, sizeof (UINT16));

+    CopyMem (&TargetTag->Value, &((EFI_IFR_ONE_OF_OPTION *) FormData)->Value, sizeof (UINT16));

+    TargetTag->Flags = ((EFI_IFR_ONE_OF_OPTION *) FormData)->Flags;

+    CopyMem (&TargetTag->Key, &((EFI_IFR_ONE_OF_OPTION *) FormData)->Key, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_CHECKBOX_OP:

+    TargetTag->Flags          = ((EFI_IFR_CHECKBOX *) FormData)->Flags;

+    TargetTag->ResetRequired  = (BOOLEAN) (TargetTag->Flags & EFI_IFR_FLAG_RESET_REQUIRED);

+    CopyMem (&TargetTag->Key, &((EFI_IFR_CHECKBOX *) FormData)->Key, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_NUMERIC_OP:

+    TargetTag->Flags = ((EFI_IFR_NUMERIC *) FormData)->Flags;

+    CopyMem (&TargetTag->Key, &((EFI_IFR_NUMERIC *) FormData)->Key, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_STRING_OP:

+    TempValue = 0;

+    CopyMem (&TempValue, &((EFI_IFR_STRING *) FormData)->MinSize, sizeof (UINT8));

+    TempValue = (UINT16) (TempValue * 2);

+    CopyMem (&TargetTag->Minimum, &TempValue, sizeof (UINT16));

+

+    CopyMem (&TempValue, &((EFI_IFR_STRING *) FormData)->MaxSize, sizeof (UINT8));

+    TempValue = (UINT16) (TempValue * 2);

+    CopyMem (&TargetTag->Maximum, &TempValue, sizeof (UINT16));

+    CopyMem (&TargetTag->StorageWidth, &TempValue, sizeof (UINT16));

+    TargetTag->Flags          = (UINT8) (((EFI_IFR_STRING *) FormData)->Flags);

+    TargetTag->ResetRequired  = (BOOLEAN) (TargetTag->Flags & EFI_IFR_FLAG_RESET_REQUIRED);

+    CopyMem (&TargetTag->Key, &((EFI_IFR_STRING *) FormData)->Key, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_PASSWORD_OP:

+    TempValue = 0;

+    CopyMem (&TempValue, &((EFI_IFR_PASSWORD *) FormData)->MinSize, sizeof (UINT8));

+    TempValue = (UINT16) (TempValue * 2);

+    CopyMem (&TargetTag->Minimum, &TempValue, sizeof (UINT16));

+

+    CopyMem (&TempValue, &((EFI_IFR_PASSWORD *) FormData)->MaxSize, sizeof (UINT8));

+    TempValue = (UINT16) (TempValue * 2);

+    CopyMem (&TargetTag->Maximum, &TempValue, sizeof (UINT16));

+    CopyMem (&TargetTag->StorageWidth, &TempValue, sizeof (UINT16));

+    TargetTag->Flags          = ((EFI_IFR_PASSWORD *) FormData)->Flags;

+    TargetTag->ResetRequired  = (BOOLEAN) (TargetTag->Flags & EFI_IFR_FLAG_RESET_REQUIRED);

+    CopyMem (&TargetTag->Key, &((EFI_IFR_PASSWORD *) FormData)->Key, sizeof (UINT16));

+    CopyMem (&TargetTag->Encoding, &((EFI_IFR_PASSWORD *) FormData)->Encoding, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_VARSTORE_OP:

+    //

+    // It should NEVER be NULL

+    //

+    if (VariableDefinitionsHead == NULL) {

+      break;

+    }

+

+    VariableDefinitions = VariableDefinitionsHead;

+

+    //

+    // Advance VariableDefinitions to the last entry

+    //

+    for (; VariableDefinitions != NULL; VariableDefinitions = VariableDefinitions->Next) {

+      PreviousVariableDefinitions = VariableDefinitions;

+      //

+      // If there is a variable with this GUID and ID already, we need to bail out

+      //

+      if (!CompareMem (&VariableDefinitions->Guid, &((EFI_IFR_VARSTORE *) FormData)->Guid, sizeof (EFI_GUID)) &&

+          !CompareMem (&VariableDefinitions->VariableId, &((EFI_IFR_VARSTORE *) FormData)->VarId, sizeof (UINT16))

+            ) {

+        return ;

+      }

+

+      if (VariableDefinitions->Next == NULL) {

+        break;

+      }

+    }

+    //

+    // If the last entry has a variable in it already, allocate a new entry and use it

+    //

+    if (VariableDefinitions->VariableName != NULL) {

+      VariableDefinitions->Next = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));

+      ASSERT (VariableDefinitions->Next != NULL);

+      PreviousVariableDefinitions   = VariableDefinitions;

+      VariableDefinitions           = VariableDefinitions->Next;

+      VariableDefinitions->Previous = PreviousVariableDefinitions;

+    }

+    //

+    // Copy the Variable data to our linked list

+    //

+    CopyMem (&VariableDefinitions->VariableId, &((EFI_IFR_VARSTORE *) FormData)->VarId, sizeof (UINT16));

+    CopyMem (&VariableDefinitions->VariableSize, &((EFI_IFR_VARSTORE *) FormData)->Size, sizeof (UINT16));

+    CopyMem (&VariableDefinitions->Guid, &((EFI_IFR_VARSTORE *) FormData)->Guid, sizeof (EFI_GUID));

+

+    //

+    // The ASCII String which is immediately past the EFI_IFR_VARSTORE is inferred by the structure definition

+    // due to it being variable sized.  There are rules preventing it from being > 40 characters long and should

+    // be enforced by the compiler.

+    //

+    AsciiString                       = (CHAR8 *) (&((EFI_IFR_VARSTORE *) FormData)->Size);

+    AsciiString                       = AsciiString + 2;

+    VariableDefinitions->VariableName = AllocateZeroPool ((AsciiStrLen (AsciiString) + 1) * 2);

+    ASSERT (VariableDefinitions->VariableName != NULL);

+    for (Index = 0; AsciiString[Index] != 0; Index++) {

+      VariableDefinitions->VariableName[Index] = (CHAR16) AsciiString[Index];

+    }

+

+    VariableDefinitions->VariableName[Index] = 0;

+

+    //

+    // Propogate the tag information for this op-code

+    //

+    CopyMem (&TargetTag->VariableNumber, &((EFI_IFR_VARSTORE *) FormData)->VarId, sizeof (UINT16));

+    CopyMem (&TargetTag->GuidValue, &((EFI_IFR_VARSTORE *) FormData)->Guid, sizeof (EFI_GUID));

+    CopyMem (&TargetTag->StorageWidth, &((EFI_IFR_VARSTORE *) FormData)->Size, sizeof (UINT16));

+    CopyMem (&TargetTag->Maximum, &((EFI_IFR_VARSTORE *) FormData)->Size, sizeof (UINT16));

+    break;

+

+  case EFI_IFR_VARSTORE_SELECT_OP:

+    CopyMem (&TargetTag->VariableNumber, &((EFI_IFR_VARSTORE_SELECT *) FormData)->VarId, sizeof (UINT16));

+    CopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) FormData)->VarId, sizeof (UINT16));

+    CurrentVariable2 = CurrentVariable;

+    break;

+

+  case EFI_IFR_VARSTORE_SELECT_PAIR_OP:

+    CopyMem (&TargetTag->VariableNumber, &((EFI_IFR_VARSTORE_SELECT_PAIR *) FormData)->VarId, sizeof (UINT16));

+    CopyMem (

+      &TargetTag->VariableNumber2,

+      &((EFI_IFR_VARSTORE_SELECT_PAIR *) FormData)->SecondaryVarId,

+      sizeof (UINT16)

+      );

+    CopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT_PAIR *) FormData)->VarId, sizeof (UINT16));

+    CopyMem (&CurrentVariable2, &((EFI_IFR_VARSTORE_SELECT_PAIR *) FormData)->SecondaryVarId, sizeof (UINT16));

+    break;

+

+  case EFI_IFR_REF_OP:

+    TargetTag->NumberOfLines = 1;

+    CopyMem (&TargetTag->Id, &((EFI_IFR_REF *) FormData)->FormId, sizeof (UINT16));

+    CopyMem (&TargetTag->Key, &((EFI_IFR_REF *) FormData)->Key, sizeof (UINT16));

+    CopyMem (&TargetTag->Text, &((EFI_IFR_REF *) FormData)->Prompt, sizeof (UINT16));

+    CopyMem (&TargetTag->Help, &((EFI_IFR_REF *) FormData)->Help, sizeof (UINT16));

+    TargetTag->Flags          = ((EFI_IFR_REF *) FormData)->Flags;

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_EQ_ID_VAL_OP:

+    CopyMem (&TargetTag->Value, &((EFI_IFR_EQ_ID_VAL *) FormData)->Value, sizeof (UINT16));

+    CopyMem (&TargetTag->Id, &((EFI_IFR_EQ_ID_VAL *) FormData)->QuestionId, sizeof (UINT16));

+    TargetTag->StorageWidth   = ((EFI_IFR_EQ_ID_VAL *) FormData)->Width;

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_EQ_VAR_VAL_OP:

+    CopyMem (&TargetTag->Value, &((EFI_IFR_EQ_VAR_VAL *) FormData)->Value, sizeof (UINT16));

+    CopyMem (&TargetTag->Id, &((EFI_IFR_EQ_VAR_VAL *) FormData)->VariableId, sizeof (UINT16));

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_EQ_ID_ID_OP:

+    CopyMem (&TargetTag->Id, &((EFI_IFR_EQ_ID_ID *) FormData)->QuestionId1, sizeof (UINT16));

+    CopyMem (&TargetTag->Id2, &((EFI_IFR_EQ_ID_ID *) FormData)->QuestionId2, sizeof (UINT16));

+    TargetTag->StorageWidth   = ((EFI_IFR_EQ_ID_ID *) FormData)->Width;

+    TargetTag->VariableNumber = CurrentVariable;

+    TargetTag->VariableNumber = CurrentVariable2;

+    break;

+

+  case EFI_IFR_EQ_ID_LIST_OP:

+    CopyMem (&TargetTag->Id, &((EFI_IFR_EQ_ID_LIST *) FormData)->QuestionId, sizeof (UINT16));

+    CopyMem (&TargetTag->Id2, &((EFI_IFR_EQ_ID_LIST *) FormData)->ListLength, sizeof (UINT16));

+    TargetTag->StorageWidth = ((EFI_IFR_EQ_ID_LIST *) FormData)->Width;

+

+    TargetTag->IntList      = AllocateZeroPool (TargetTag->Id2 * sizeof (UINT16));

+    ASSERT (TargetTag->IntList);

+

+    for (TempValue = 0; TempValue < TargetTag->Id2; TempValue++) {

+      CopyMem (

+        &TargetTag->IntList[TempValue],

+        &((EFI_IFR_EQ_ID_LIST *) FormData)->ValueList[TempValue],

+        sizeof (UINT16)

+        );

+    }

+

+    TargetTag->VariableNumber = CurrentVariable;

+    break;

+

+  case EFI_IFR_FORM_SET_OP:

+    CopyMem (&VariableSize, &((EFI_IFR_FORM_SET *) FormData)->NvDataSize, sizeof (UINT16));

+    CopyMem (&Guid, &((EFI_IFR_FORM_SET *) FormData)->Guid, sizeof (EFI_GUID));

+    //

+    // If there is a size specified in the formste, we will establish a "default" variable

+    //

+    if (VariableDefinitionsHead != NULL) {

+      VariableName = AllocateZeroPool (12);

+      ASSERT (VariableName != NULL);

+      CopyMem (VariableName, L"Setup", 12);

+      VariableDefinitionsHead->VariableName = VariableName;

+      VariableDefinitionsHead->VariableSize = VariableSize;

+      CopyMem (&VariableDefinitionsHead->Guid, &Guid, sizeof (EFI_GUID));

+    }

+    break;

+

+  case EFI_IFR_END_FORM_SET_OP:

+    CurrentVariable   = 0;

+    CurrentVariable2  = 0;

+    break;

+  }

+

+  return ;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Setup.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Setup.c
new file mode 100644
index 0000000..f62bc12
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Setup.c
@@ -0,0 +1,2217 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+        Setup.c

+

+Abstract:

+

+  Entry and initialization module for the browser

+

+Revision History:

+--*/

+

+#include "Setup.h"

+#include "Ui.h"

+

+FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {

+  //

+  // Boot Manager

+  //

+  {

+    {

+      0x847bc3fe, 

+      0xb974,

+      0x446d,

+      {

+        0x94,

+        0x49,

+        0x5a,

+        0xd5,

+        0x41,

+        0x2e,

+        0x99,

+        0x3b

+      }

+    },

+    NONE_FUNCTION_KEY_SETTING

+  },

+  //

+  // Device Manager

+  //

+  {

+    {

+      0x3ebfa8e6,

+      0x511d,

+      0x4b5b,

+      {

+        0xa9,

+        0x5f,

+        0xfb,

+        0x38,

+        0x26,

+        0xf,

+        0x1c,

+        0x27

+      }

+    },

+    NONE_FUNCTION_KEY_SETTING

+  },

+  //

+  // BMM Formset.

+  //

+  {

+    {

+      0x642237c7,

+      0x35d4,

+      0x472d,

+      {

+        0x83,

+        0x65,

+        0x12,

+        0xe0,

+        0xcc,

+        0xf2,

+        0x7a,

+        0x22

+      }

+    },

+    NONE_FUNCTION_KEY_SETTING

+  },

+  //

+  // BMM File Explorer Formset.

+  //

+  {

+    {

+      0x1f2d63e1,

+      0xfebd,

+      0x4dc7,

+      {

+        0x9c,

+        0xc5,

+        0xba,

+        0x2b,

+        0x1c,

+        0xef,

+        0x9c,

+        0x5b

+      }

+    },

+    NONE_FUNCTION_KEY_SETTING

+  },

+};

+

+EFI_STATUS

+InitializeBinaryStructures (

+  IN  EFI_HII_HANDLE                           *Handle,

+  IN  BOOLEAN                                  UseDatabase,

+  IN  EFI_IFR_PACKET                           *Packet,

+  IN  UINT8                                    *NvMapOverride,

+  IN  UINTN                                    NumberOfIfrImages,

+  EFI_FILE_FORM_TAGS                           **FileFormTagsHead

+  );

+

+EFI_STATUS

+InitializeTagStructures (

+  IN  EFI_IFR_BINARY                            *BinaryData,

+  OUT EFI_FILE_FORM_TAGS                        *FileFormTags

+  );

+

+UI_MENU_OPTION        *

+DisplayHomePage (

+  IN UINTN                                    NumberOfIfrImages,

+  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead,

+  IN UINT8                                    *CallbackData

+  );

+

+EFI_STATUS

+GetIfrBinaryData (

+  IN EFI_HII_PROTOCOL *Hii,

+  IN EFI_HII_HANDLE   HiiHandle,

+  IN EFI_IFR_PACKET   *Packet,

+  IN EFI_IFR_BINARY   *BinaryData

+  );

+

+EFI_STATUS

+InstallPrint (

+  VOID

+  );

+

+EFI_STATUS

+EFIAPI

+SendForm (

+  IN EFI_FORM_BROWSER_PROTOCOL        * This,

+  IN BOOLEAN                          UseDatabase,

+  IN EFI_HII_HANDLE                   * Handle,

+  IN UINTN                            HandleCount,

+  IN EFI_IFR_PACKET                   * Packet,

+  IN EFI_HANDLE                       CallbackHandle,

+  IN UINT8                            *NvMapOverride,

+  IN EFI_SCREEN_DESCRIPTOR            *ScreenDimensions, OPTIONAL

+  OUT BOOLEAN                         *ResetRequired OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  This is the routine which an external caller uses to direct the browser

+  where to obtain it's information.  

+

+Arguments:

+

+  UseDatabase -     If set to TRUE, then all information is retrieved from the HII database handle specified

+                    If set to FALSE, then the passed in Packet and CallbackHandle is used and Handle is ignored

+

+  Handle -          A pointer to an array of Handles.  If HandleCount > 1 we display a list of the formsets for the handles specified

+

+  HandleCount -     The number of Handles specified in Handle.

+

+  Packet -          Valid only if UseDatabase is FALSE.  Packet defines the pages being passed into

+                    the browser.  This is composed of IFR data as well as String information.

+

+  CallbackHandle -  The handle which contains the calling driver's EFI_FORM_CALLBACK_PROTOCOL interface.

+

+  ScreenDimenions - This allows the browser to be called so that it occupies a portion of the physical screen instead of

+                    dynamically determining the screen dimensions.

+

+  NvMapOverride -   This buffer is used only when there is no NV variable to define the current settings and the caller

+                    needs to provide to the browser the current settings for the "fake" NV variable.  If used, no saving

+                    of an NV variable will be possible.  This parameter is also ignored if HandleCount > 1.

+

+Returns: 

+

+--*/

+{

+  EFI_FORM_CONFIGURATION_DATA *FormData;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  EFI_FILE_FORM_TAGS          *FileFormTagsHead;

+  UI_MENU_OPTION              *Selection;

+  UI_MENU_OPTION              *AltSelection;

+  EFI_STATUS                  Status;

+  BOOLEAN                     Callback;

+  VOID                        *CallbackData;

+  EFI_HII_HANDLE              BackupHandle;

+

+  ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));

+

+  gPreviousValue  = AllocatePool (0x1000);

+  CallbackData    = AllocatePool (0x10000);

+  ASSERT (gPreviousValue != NULL);

+  ASSERT (CallbackData != NULL);

+

+  do {

+    //

+    // Seed the dimensions in the global

+    //

+    gST->ConOut->QueryMode (

+                  gST->ConOut,

+                  gST->ConOut->Mode->Mode,

+                  &gScreenDimensions.RightColumn,

+                  &gScreenDimensions.BottomRow

+                  );

+

+    if (ScreenDimensions != NULL) {

+      //

+      // Check local dimension vs. global dimension.

+      //

+      if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||

+          (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)

+          ) {

+        return EFI_INVALID_PARAMETER;

+      } else {

+        //

+        // Local dimension validation.

+        //

+        if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&

+            (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&

+            ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&

+            (

+              (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +

+            SCROLL_ARROW_HEIGHT *

+            2 +

+            FRONT_PAGE_HEADER_HEIGHT +

+            FOOTER_HEIGHT +

+            1

+          )

+            ) {

+          CopyMem (&gScreenDimensions, ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));

+        } else {

+          return EFI_INVALID_PARAMETER;

+        }

+      }

+    }

+

+    gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);

+    gHelpBlockWidth   = gOptionBlockWidth;

+    gPromptBlockWidth = gOptionBlockWidth;

+

+    //

+    // Initialize the strings for the browser, upon exit of the browser, the strings will be freed

+    //

+    InitializeBrowserStrings ();

+

+    gFunctionKeySetting = DEFAULT_FUNCTION_KEY_SETTING;

+    gClassOfVfr         = EFI_SETUP_APPLICATION_SUBCLASS;

+    gResetRequired      = FALSE;

+    gExitRequired       = FALSE;

+    gSaveRequired       = FALSE;

+    gNvUpdateRequired   = FALSE;

+    gActiveIfr          = 0;

+    gConsistencyId      = 0;

+    gPriorMenuEntry     = 0;

+    BackupHandle        = *Handle;

+    gMenuRefreshHead    = NULL;

+    ASSERT (CallbackData);

+    ZeroMem (CallbackData, 0x10000);

+

+    //

+    // We can recurse through this and might need to re-allocate this particular buffer

+    //

+    if (gPreviousValue == NULL) {

+      gPreviousValue = AllocatePool (0x1000);

+      ASSERT (gPreviousValue != NULL);

+    }

+

+    FormData      = EFI_FORM_DATA_FROM_THIS (This);

+    Callback      = FALSE;

+    FormCallback  = NULL;

+

+    if (CallbackHandle != NULL) {

+      //

+      // Retrieve the Callback protocol interface

+      //

+      Status = gBS->HandleProtocol (

+                      CallbackHandle,

+                      &gEfiFormCallbackProtocolGuid,

+                      (VOID **) &FormCallback

+                      );

+

+      if (EFI_ERROR (Status)) {

+        gBS->FreePool (CallbackData);

+        return Status;;

+      }

+

+      Callback = TRUE;

+    }

+    //

+    // Initializes all the internal state structures for all IFR images in system

+    //

+    Status = InitializeBinaryStructures (Handle, UseDatabase, Packet, NvMapOverride, HandleCount, &FileFormTagsHead);

+

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (CallbackData);

+      return Status;

+    }

+    //

+    // Beginning of the Presentation of the Data

+    //

+    if (UseDatabase && (HandleCount > 1)) {

+      Selection = DisplayHomePage (HandleCount, FileFormTagsHead, CallbackData);

+    } else {

+      //

+      // If passing something specific, we know there is only one Ifr

+      //

+      Selection = AllocateZeroPool (sizeof (UI_MENU_OPTION));

+      ASSERT (Selection != NULL);

+      Selection->IfrNumber  = 0;

+      Selection->Handle     = Handle[0];

+      UiInitMenu ();

+    }

+

+    UiInitMenuList ();

+

+    if (UseDatabase && (HandleCount > 1)) {

+      if (Selection == NULL) {

+        gBS->FreePool (CallbackData);

+        return EFI_SUCCESS;

+      }

+    }

+    //

+    // Launch the setup browser with the user's selection information

+    //

+    AltSelection = SetupBrowser (Selection, Callback, FileFormTagsHead, CallbackData);

+

+    //

+    // If the caller cares about Reset status, we can return to the caller if something happened that required a reset

+    //

+    if (ResetRequired != NULL) {

+      *ResetRequired = gResetRequired;

+    }

+

+    if (Callback && (AltSelection != NULL)) {

+      if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+        Status = FormCallback->Callback (

+                                FormCallback,

+                                AltSelection->ThisTag->Key,

+                                CallbackData,

+                                (EFI_HII_CALLBACK_PACKET **) &Packet

+                                );

+      }

+    }

+

+    *Handle = BackupHandle;

+

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (CallbackData);

+      return Status;

+    }

+

+    if (Callback && (AltSelection == NULL)) {

+      gBS->FreePool (CallbackData);

+      return Status;

+    }

+

+    if (UseDatabase && (HandleCount > 1)) {

+    } else {

+

+      if (gBinaryDataHead->UnRegisterOnExit) {

+        Hii->RemovePack (Hii, Handle[0]);

+      }

+

+      if (Callback &&

+        ((AltSelection->ThisTag->SubClass == EFI_FRONT_PAGE_SUBCLASS) ||

+        (AltSelection->ThisTag->SubClass == EFI_SINGLE_USE_SUBCLASS))) {

+        //

+        // If this is the FrontPage, return after every selection

+        //

+        gBS->FreePool (Selection);

+        UiFreeMenu ();

+

+        //

+        // Clean up the allocated data buffers

+        //

+        FreeData (FileFormTagsHead, NULL, NULL);

+

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+        gST->ConOut->ClearScreen (gST->ConOut);

+

+        gBS->FreePool (CallbackData);

+        return EFI_SUCCESS;

+      }

+

+      gBS->FreePool (Selection);

+      UiFreeMenu ();

+

+      //

+      // Clean up the allocated data buffers

+      //

+      FreeData (FileFormTagsHead, NULL, NULL);

+

+      gST->ConOut->ClearScreen (gST->ConOut);

+

+      if (!Callback) {

+        gBS->FreePool (CallbackData);

+        return EFI_SUCCESS;

+      }

+    }

+

+  } while (!EFI_ERROR (Status));

+

+  gBS->FreePool (CallbackData);

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+InitializeSetup (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+  Initialize Setup

+  

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns: 

+  EFI_SUCCESS - Setup loaded.

+  other       - Setup Error

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_FORM_CONFIGURATION_DATA *FormData;

+  EFI_FORM_BROWSER_PROTOCOL   *FormBrowser;

+  EFI_HANDLE                  Handle;

+  EFI_HII_PACKAGES            *PackageList;

+

+  //

+  // There will be only one FormConfig in the system

+  // If there is another out there, someone is trying to install us

+  // again.  Fail that scenario.

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiFormBrowserProtocolGuid,

+                  NULL,

+                  (VOID **) &FormBrowser

+                  );

+

+  gFirstIn = TRUE;

+

+  //

+  // If there was no error, assume there is an installation and fail to load

+  //

+  if (!EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  FormData = AllocatePool (sizeof (EFI_FORM_CONFIGURATION_DATA));

+

+  if (FormData == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Fill in HII data

+  //

+  FormData->Signature               = EFI_FORM_DATA_SIGNATURE;

+  FormData->FormConfig.SendForm     = SendForm;

+  FormData->FormConfig.CreatePopUp  = CreateDialog;

+

+  //

+  // There should only be one HII image

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  (VOID **) &FormData->Hii

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  Hii         = FormData->Hii;

+

+  PackageList = PreparePackages (1, &gEfiFormBrowserProtocolGuid, SetupBrowserStrings);

+

+  Status      = Hii->NewPack (Hii, PackageList, &gHiiHandle);

+

+  gBS->FreePool (PackageList);

+

+  //

+  // Install protocol interface

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiFormBrowserProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &FormData->FormConfig

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  BannerData = AllocateZeroPool (sizeof (BANNER_DATA));

+  ASSERT (BannerData != NULL);

+

+  Status = InstallPrint ();

+  return Status;

+}

+

+VOID

+GetQuestionHeader (

+  IN  EFI_TAG             *Tag,

+  IN  UINT8               *RawFormSet,

+  IN  UINT16              Index,

+  IN  EFI_FILE_FORM_TAGS  *FileFormTags,

+  IN  UINT16              CurrentVariable

+  )

+/*++

+

+Routine Description:

+  Initialize question tag's members.

+

+Arguments:

+  Tag              - Pointer of the current EFI_TAG structure.

+  RawFormSet       - Pointer of the formset raw data.

+  Index            - Offset of the current opcode in the Ifr raw data.

+  FileFormTags     - Pointer of current EFI_FILE_FORM_TAGS structure.

+  CurrentVariable  - Current variable number.

+           

+Returns:

+  None.

+--*/

+{

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+

+  Tag->NumberOfLines  = 1;

+  Tag->VariableNumber = CurrentVariable;

+  CopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));

+  CopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));

+  CopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));

+  CopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));

+  CopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));

+

+  VariableDefinition = FileFormTags->VariableDefinitions;

+

+  for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {

+    //

+    // Have we found the correct variable for the request?

+    //

+    if (CurrentVariable == VariableDefinition->VariableId) {

+      if (VariableDefinition->VariableSize < (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {

+        VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);

+      }

+

+      if (VariableDefinition->NvRamMap != NULL) {

+        //

+        // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise

+        // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)

+        //

+        if (Tag->StorageWidth == (UINT16) 1) {

+          CopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));

+        }

+

+        if (Tag->StorageWidth == (UINT16) 2) {

+          Index = (UINT16)

+            (

+              VariableDefinition->NvRamMap[Tag->StorageStart] +

+              (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)

+            );

+          CopyMem (&Tag->Value, &Index, sizeof (UINT16));

+        }

+      } else {

+        Index = 0;

+        CopyMem (&Tag->Value, &Index, sizeof (UINT16));

+      }

+      break;

+    } else {

+      continue;

+    }

+  }

+}

+

+VOID

+GetNumericHeader (

+  IN  EFI_TAG             *Tag,

+  IN  UINT8               *RawFormSet,

+  IN  UINT16              Index,

+  IN  UINT16              NumberOfLines,

+  IN  EFI_FILE_FORM_TAGS  *FileFormTags,

+  IN  UINT16              CurrentVariable

+  )

+/*++

+

+Routine Description:

+  Initialize numeric tag's members.

+

+Arguments:

+  Tag              - Pointer of the current EFI_TAG structure.

+  RawFormSet       - Pointer of the formset raw data.

+  Index            - Offset of the current opcode in the Ifr raw data.

+  NumberOfLines    - Number of lines this opcode occupied.

+  FileFormTags     - Pointer of current EFI_FILE_FORM_TAGS structure.

+  CurrentVariable  - Current variable number.

+           

+Returns:

+  None.

+--*/

+{

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+

+  Tag->NumberOfLines  = NumberOfLines;

+  Tag->VariableNumber = CurrentVariable;

+  CopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));

+  CopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));

+  CopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));

+  CopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));

+  CopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));

+  CopyMem (&Tag->Minimum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Minimum, sizeof (UINT16));

+  CopyMem (&Tag->Maximum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Maximum, sizeof (UINT16));

+  CopyMem (&Tag->Step, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Step, sizeof (UINT16));

+  CopyMem (&Tag->Default, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Default, sizeof (UINT16));

+  Tag->ResetRequired  = (BOOLEAN) (((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Flags & EFI_IFR_FLAG_RESET_REQUIRED);

+

+  VariableDefinition  = FileFormTags->VariableDefinitions;

+

+  for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {

+    //

+    // Have we found the correct variable for the request?

+    //

+    if (CurrentVariable == VariableDefinition->VariableId) {

+      if (VariableDefinition->VariableSize <= (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {

+        if (Tag->StorageWidth == 0) {

+          VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + 2);

+        } else {

+          VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);

+        }

+      }

+

+      if (VariableDefinition->NvRamMap != NULL) {

+        //

+        // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise

+        // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)

+        //

+        if (Tag->StorageWidth == (UINT16) 1) {

+          CopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));

+        }

+

+        if (Tag->StorageWidth == (UINT16) 2) {

+          Index = (UINT16)

+            (

+              VariableDefinition->NvRamMap[Tag->StorageStart] +

+                (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)

+            );

+          CopyMem (&Tag->Value, &Index, sizeof (UINT16));

+        }

+      } else {

+        CopyMem (&Tag->Value, &Tag->Default, sizeof (UINT16));

+      }

+      break;

+    } else {

+      continue;

+    }

+  }

+}

+

+VOID

+GetTagCount (

+  IN      UINT8                                 *RawFormSet,

+  IN OUT  UINT16                                *NumberOfTags

+  )

+{

+  UINT16  Index;

+

+  //

+  // Assume on entry we are pointing to an OpCode - reasonably this should

+  // be a FormOp since the purpose is to count the tags in a particular Form.

+  //

+  for (Index = 0; RawFormSet[Index] != EFI_IFR_END_FORM_OP;) {

+    //

+    // If we encounter the end of a form set, bail out

+    //

+    if (RawFormSet[Index] == EFI_IFR_END_FORM_SET_OP) {

+      break;

+    }

+    //

+    // We treat date/time internally as three op-codes

+    //

+    if (RawFormSet[Index] == EFI_IFR_DATE_OP || RawFormSet[Index] == EFI_IFR_TIME_OP) {

+      *NumberOfTags = (UINT16) (*NumberOfTags + 3);

+    } else {

+      //

+      // Assume that we could have no more tags than op-codes

+      //

+      (*NumberOfTags)++;

+    }

+

+    Index = (UINT16) (Index + RawFormSet[Index + 1]);

+  }

+  //

+  // Increase the tag count by one so it is inclusive of the end_form_op

+  //

+  (*NumberOfTags)++;

+}

+

+VOID

+AddNextInconsistentTag (

+  IN OUT  EFI_INCONSISTENCY_DATA  **InconsistentTagsPtr

+  )

+/*++

+

+Routine Description:

+  Initialize the next inconsistent tag data and add it to the inconsistent tag list.

+  

+Arguments:

+ InconsistentTagsPtr   - Pointer of the inconsistent tag's pointer.

+

+Returns: 

+  None.

+

+--*/

+{

+  EFI_INCONSISTENCY_DATA  *PreviousInconsistentTags;

+  EFI_INCONSISTENCY_DATA  *InconsistentTags;

+

+  InconsistentTags = *InconsistentTagsPtr;

+  //

+  // We just hit the end of an inconsistent expression.  Let's allocate the ->Next structure

+  //

+  InconsistentTags->Next = AllocatePool (sizeof (EFI_INCONSISTENCY_DATA));

+  ASSERT (InconsistentTags->Next != NULL);

+

+  //

+  // Preserve current Tag entry

+  //

+  PreviousInconsistentTags  = InconsistentTags;

+

+  InconsistentTags          = InconsistentTags->Next;

+

+  //

+  // This will zero on the entry including the ->Next so I don't have to do it

+  //

+  ZeroMem (InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));

+

+  //

+  // Point our Previous field to the previous entry

+  //

+  InconsistentTags->Previous  = PreviousInconsistentTags;

+

+  *InconsistentTagsPtr        = InconsistentTags;

+

+  return ;

+}

+

+EFI_STATUS

+InitializeTagStructures (

+  IN  EFI_IFR_BINARY                            *BinaryData,

+  OUT EFI_FILE_FORM_TAGS                        *FileFormTags

+  )

+{

+  EFI_STATUS              Status;

+  UINT8                   *RawFormSet;

+  UINT16                  Index;

+  UINT16                  QuestionIndex;

+  UINT16                  NumberOfTags;

+  INT16                   CurrTag;

+  UINT8                   TagLength;

+  EFI_FORM_TAGS           *FormTags;

+  EFI_FORM_TAGS           *SavedFormTags;

+  EFI_INCONSISTENCY_DATA  *InconsistentTags;

+  EFI_VARIABLE_DEFINITION *VariableDefinitions;

+  UINTN                   Count;

+  UINT16                  Class;

+  UINT16                  SubClass;

+  UINT16                  TempValue;

+  UINT16                  CurrentVariable;

+  UINT16                  CurrentVariable2;

+

+  //

+  // Initialize some Index variable and Status

+  //

+  Count             = 0;

+  Class             = 0;

+  SubClass          = 0;

+  CurrentVariable   = 0;

+  CurrentVariable2  = 0;

+  QuestionIndex     = 0;

+  NumberOfTags      = 1;

+  Status            = EFI_SUCCESS;

+  FormTags          = &FileFormTags->FormTags;

+  FormTags->Next    = NULL;

+  if (FileFormTags->InconsistentTags == NULL) {

+    InconsistentTags = NULL;

+  } else {

+    InconsistentTags = FileFormTags->InconsistentTags;

+  }

+

+  if (FileFormTags->VariableDefinitions == NULL) {

+    VariableDefinitions = NULL;

+  } else {

+    VariableDefinitions = FileFormTags->VariableDefinitions;

+  }

+  //

+  // RawFormSet now points to the beginning of the forms portion of

+  // the specific IFR Binary.

+  //

+  RawFormSet = (UINT8 *) BinaryData->FormBinary;

+

+  //

+  // Determine the number of tags for the first form

+  //

+  GetTagCount (&RawFormSet[0], &NumberOfTags);

+

+  SavedFormTags = FormTags;

+

+  if (FormTags->Tags != NULL) {

+    do {

+      //

+      // Advance FormTags to the last entry

+      //

+      for (; FormTags->Next != NULL; FormTags = FormTags->Next)

+        ;

+

+      //

+      // Walk through each of the tags and free the IntList allocation

+      //

+      for (Index = 0; Index < NumberOfTags; Index++) {

+        if (FormTags->Tags[Index].IntList != NULL) {

+          gBS->FreePool (FormTags->Tags[Index].IntList);

+        }

+      }

+

+      gBS->FreePool (FormTags->Tags);

+      gBS->FreePool (FormTags->Next);

+      FormTags->Next  = NULL;

+      FormTags->Tags  = NULL;

+

+      FormTags        = SavedFormTags;

+

+    } while (FormTags->Next != NULL);

+  }

+

+  Index = 0;

+

+  //

+  // Test for an allocated buffer.  If already allocated this is due to having called this routine

+  // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+  // the tag structure with current values from the NV

+  //

+  if (FormTags->Tags == NULL) {

+    //

+    // Allocate memory for our tags on the first form

+    //

+    FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));

+    ASSERT (FormTags->Tags);

+  }

+  //

+  // Test for an allocated buffer.  If already allocated this is due to having called this routine

+  // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+  // the tag structure with current values from the NV

+  //

+  if (InconsistentTags == NULL) {

+    //

+    // We just hit the end of an inconsistent expression.  Let's allocate the ->Next structure

+    //

+    InconsistentTags = AllocateZeroPool (sizeof (EFI_INCONSISTENCY_DATA));

+    ASSERT (InconsistentTags != NULL);

+

+    FileFormTags->InconsistentTags = InconsistentTags;

+  }

+

+  ZeroMem (FormTags->Tags, NumberOfTags * sizeof (EFI_TAG));

+

+  for (CurrTag = 0; RawFormSet[Index] != EFI_IFR_END_FORM_SET_OP; CurrTag++) {

+    //

+    // Operand = IFR OpCode

+    //

+    FormTags->Tags[CurrTag].Operand = RawFormSet[Index];

+

+    //

+    // Assume for now 0 lines occupied by this OpCode

+    //

+    FormTags->Tags[CurrTag].NumberOfLines = 0;

+

+    FormTags->Tags[CurrTag].Class         = Class;

+    FormTags->Tags[CurrTag].SubClass      = SubClass;

+

+    //

+    // Determine the length of the Tag so we can later skip to the next tag in the form

+    //

+    TagLength = RawFormSet[Index + 1];

+    //

+    // get the length

+    //

+    // Operate on the Found OpCode

+    //

+    switch (RawFormSet[Index]) {

+

+    case EFI_IFR_FORM_OP:

+      //

+      // If there was no variable op-code defined, create a dummy entry for one

+      //

+      if (FileFormTags->VariableDefinitions == NULL) {

+        FileFormTags->VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));

+        ASSERT (FileFormTags->VariableDefinitions != NULL);

+        IfrToFormTag (

+          RawFormSet[Index],

+          &FormTags->Tags[CurrTag],

+          (VOID *) &RawFormSet[Index],

+          FileFormTags->VariableDefinitions

+          );

+      } else {

+        IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      }

+      break;

+

+    case EFI_IFR_SUBTITLE_OP:

+    case EFI_IFR_TEXT_OP:

+    case EFI_IFR_REF_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      break;

+

+    case EFI_IFR_VARSTORE_OP:

+      if (FileFormTags->VariableDefinitions == NULL) {

+        VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));

+        ASSERT (VariableDefinitions != NULL);

+        FileFormTags->VariableDefinitions = VariableDefinitions;

+      }

+

+      IfrToFormTag (

+        RawFormSet[Index],

+        &FormTags->Tags[CurrTag],

+        (VOID *) &RawFormSet[Index],

+        FileFormTags->VariableDefinitions

+        );

+      break;

+

+    case EFI_IFR_VARSTORE_SELECT_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      CopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) &RawFormSet[Index])->VarId, sizeof (UINT16));

+      CurrentVariable2 = CurrentVariable;

+      break;

+

+    case EFI_IFR_VARSTORE_SELECT_PAIR_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      CopyMem(&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT_PAIR *)&RawFormSet[Index])->VarId, sizeof (UINT16));

+      CopyMem (

+        &CurrentVariable2,

+        &((EFI_IFR_VARSTORE_SELECT_PAIR *) &RawFormSet[Index])->SecondaryVarId,

+        sizeof (UINT16)

+        );

+      break;

+

+    case EFI_IFR_END_FORM_OP:

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (FormTags->Next == NULL) {

+        //

+        // We just hit the end of a form.  Let's allocate the ->Next structure

+        //

+        FormTags->Next = AllocatePool (sizeof (EFI_FORM_TAGS));

+        ASSERT (FormTags->Next);

+      }

+

+      FormTags = FormTags->Next;

+      ZeroMem (FormTags, sizeof (EFI_FORM_TAGS));

+

+      //

+      // Reset the tag count to one

+      //

+      NumberOfTags = 1;

+

+      //

+      // Reset the CurrTag value (it will be incremented, after this case statement

+      // so set to a negative one so that we get the desired effect.)  Fish can beat me later.

+      //

+      CurrTag = -1;

+

+      //

+      // Determine the number of tags after this form.  If this is the last

+      // form, then we will count the endformset and preserve that information

+      // in the tag structure.

+      //

+      GetTagCount (&RawFormSet[Index + TagLength], &NumberOfTags);

+

+      //

+      // Allocate memory for our tags

+      //

+      FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));

+      ASSERT (FormTags->Tags);

+      break;

+

+    //

+    // Two types of tags constitute the One Of question: a one-of header and

+    // several one-of options.

+    //

+    case EFI_IFR_ONE_OF_OP:

+    case EFI_IFR_ORDERED_LIST_OP:

+      GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);

+

+      //

+      // Store away the CurrTag since what follows will be the answer that we

+      // need to place into the appropriate location in the tag array

+      //

+      //

+      // record for setting default later

+      //

+      QuestionIndex = (UINT16) CurrTag;

+      break;

+

+    case EFI_IFR_ONE_OF_OPTION_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      FormTags->Tags[QuestionIndex].Flags = ((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Flags;

+      CopyMem (

+        &FormTags->Tags[QuestionIndex].Key,

+        &((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Key,

+        sizeof (UINT16)

+        );

+      FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & EFI_IFR_FLAG_RESET_REQUIRED);

+      break;

+

+    case EFI_IFR_CHECKBOX_OP:

+      GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      break;

+

+    case EFI_IFR_NUMERIC_OP:

+      GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      break;

+

+    case EFI_IFR_DATE_OP:

+      //

+      // Date elements come in as a Year, Month, Day.  We need to process them as a country-based

+      // Order.  It is much easier to do it here than anywhere else.

+      //

+      // For US standards - we want Month/Day/Year, thus we advance "Index" +1, +2, +0 while CurrTag is +0, +1, +2

+      //

+      GetNumericHeader (

+        &FormTags->Tags[CurrTag],

+        RawFormSet,

+        (UINT16) (Index + TagLength),

+        (UINT16) 0,

+        FileFormTags,

+        CurrentVariable

+        );

+

+      //

+      // The current language selected + the Date operand

+      //

+      FormTags->Tags[CurrTag + 1].Operand = RawFormSet[Index];

+      GetNumericHeader (

+        &FormTags->Tags[CurrTag + 1],

+        RawFormSet,

+        (UINT16) (Index + TagLength + RawFormSet[Index + TagLength + 1]),

+        (UINT16) 0,

+        FileFormTags,

+        CurrentVariable

+        );

+

+      //

+      // The current language selected + the Date operand

+      //

+      FormTags->Tags[CurrTag + 2].Operand = RawFormSet[Index];

+      GetNumericHeader (&FormTags->Tags[CurrTag + 2], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);

+

+      CurrTag   = (INT16) (CurrTag + 2);

+

+      Index     = (UINT16) (Index + TagLength);

+      //

+      // get the length

+      //

+      TagLength = RawFormSet[Index + 1];

+      Index     = (UINT16) (Index + TagLength);

+      //

+      // get the length

+      //

+      TagLength = RawFormSet[Index + 1];

+      break;

+

+    case EFI_IFR_TIME_OP:

+      GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 0, FileFormTags, CurrentVariable);

+

+      if (Count == 2) {

+        //

+        // Override the GetQuestionHeader information - date/time are treated very differently

+        //

+        FormTags->Tags[CurrTag].NumberOfLines = 1;

+        Count = 0;

+      } else {

+        //

+        // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines

+        // associated with them, and the third has 1 line to allow to space beyond the choice.

+        //

+        Count++;

+      }

+      break;

+

+    case EFI_IFR_PASSWORD_OP:

+    case EFI_IFR_STRING_OP:

+      GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      break;

+

+    case EFI_IFR_SUPPRESS_IF_OP:

+    case EFI_IFR_GRAYOUT_IF_OP:

+      InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;

+      gConsistencyId++;

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;

+      InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_FORM_SET_OP:

+      CopyMem (

+        &FormTags->Tags[CurrTag].GuidValue,

+        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Guid,

+        sizeof (EFI_GUID)

+        );

+      CopyMem (

+        &FormTags->Tags[CurrTag].CallbackHandle,

+        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->CallbackHandle,

+        sizeof (EFI_PHYSICAL_ADDRESS)

+        );

+      CopyMem (&FormTags->Tags[CurrTag].Class, &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class, sizeof (UINT8));

+      CopyMem (

+        &FormTags->Tags[CurrTag].SubClass,

+        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass,

+        sizeof (UINT8)

+        );

+      CopyMem (

+        &FormTags->Tags[CurrTag].NvDataSize,

+        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->NvDataSize,

+        sizeof (UINT16)

+        );

+      Class     = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class;

+      SubClass  = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass;

+      //

+      // If the formset has a size value, that means someone must be using this, so create a variable

+      // We also shall reserve the formid of 0 for this specific purpose.

+      //

+      if ((FileFormTags->VariableDefinitions == NULL) && (FormTags->Tags[CurrTag].NvDataSize > 0)) {

+        FileFormTags->VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));

+        ASSERT (FileFormTags->VariableDefinitions != NULL);

+        IfrToFormTag (

+          RawFormSet[Index],

+          &FormTags->Tags[CurrTag],

+          (VOID *) &RawFormSet[Index],

+          FileFormTags->VariableDefinitions

+          );

+      } else {

+        IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+      }

+      break;

+

+    case EFI_IFR_BANNER_OP:

+      if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {

+        TempValue = 0;

+        CopyMem (&TempValue, &((EFI_IFR_BANNER *) &RawFormSet[Index])->Alignment, sizeof (UINT8));

+        //

+        // If this is the special timeout value, we will dynamically figure out where to put it

+        // Also the least significant byte refers to the TimeOut desired.

+        //

+        if (TempValue == EFI_IFR_BANNER_TIMEOUT) {

+          CopyMem (&FrontPageTimeOutTitle, &((EFI_IFR_BANNER *) &RawFormSet[Index])->Title, sizeof (UINT16));

+          if (FrontPageTimeOutValue != (INT16) -1) {

+            CopyMem (&FrontPageTimeOutValue, &((EFI_IFR_BANNER *) &RawFormSet[Index])->LineNumber, sizeof (UINT16));

+          }

+          break;

+        }

+

+        CopyMem (

+          &BannerData->Banner[((EFI_IFR_BANNER *) &RawFormSet[Index])->LineNumber][

+          ((EFI_IFR_BANNER *) &RawFormSet[Index])->Alignment],

+          &((EFI_IFR_BANNER *) &RawFormSet[Index])->Title,

+          sizeof (STRING_REF)

+          );

+      }

+      break;

+

+    case EFI_IFR_INCONSISTENT_IF_OP:

+      CopyMem (

+        &FormTags->Tags[CurrTag].Text,

+        &((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Popup,

+        sizeof (UINT16)

+        );

+      gConsistencyId++;

+

+      InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;

+      CopyMem (&InconsistentTags->Popup, &((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Popup, sizeof (UINT16));

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      InconsistentTags->QuestionId1     = INVALID_OFFSET_VALUE;

+      InconsistentTags->QuestionId2     = INVALID_OFFSET_VALUE;

+

+      InconsistentTags->VariableNumber  = CurrentVariable;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_EQ_ID_VAL_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+

+      InconsistentTags->Operand = ((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->Header.OpCode;

+      CopyMem (&InconsistentTags->Value, &((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->Value, sizeof (UINT16));

+      CopyMem (

+        &InconsistentTags->QuestionId1,

+        &((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->QuestionId,

+        sizeof (UINT16)

+        );

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      InconsistentTags->Width               = FormTags->Tags[CurrTag].StorageWidth;

+      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;

+      InconsistentTags->ConsistencyId       = gConsistencyId;

+      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;

+

+      InconsistentTags->VariableNumber      = CurrentVariable;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_EQ_VAR_VAL_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+

+      InconsistentTags->Operand = ((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->Header.OpCode;

+      CopyMem (&InconsistentTags->Value, &((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->Value, sizeof (UINT16));

+      CopyMem (

+        &InconsistentTags->QuestionId1,

+        &((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->VariableId,

+        sizeof (UINT16)

+        );

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;

+      InconsistentTags->ConsistencyId       = gConsistencyId;

+      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;

+

+      InconsistentTags->VariableNumber      = CurrentVariable;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_EQ_ID_ID_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+

+      InconsistentTags->Operand = ((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->Header.OpCode;

+      CopyMem (

+        &InconsistentTags->QuestionId1,

+        &((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->QuestionId1,

+        sizeof (UINT16)

+        );

+      CopyMem (

+        &InconsistentTags->QuestionId2,

+        &((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->QuestionId2,

+        sizeof (UINT16)

+        );

+

+      InconsistentTags->Width               = FormTags->Tags[CurrTag].StorageWidth;

+      InconsistentTags->ConsistencyId       = gConsistencyId;

+      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;

+

+      InconsistentTags->VariableNumber      = CurrentVariable;

+      InconsistentTags->VariableNumber2     = CurrentVariable2;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_AND_OP:

+    case EFI_IFR_OR_OP:

+    case EFI_IFR_NOT_OP:

+    case EFI_IFR_GT_OP:

+    case EFI_IFR_GE_OP:

+    case EFI_IFR_TRUE_OP:

+    case EFI_IFR_FALSE_OP:

+      InconsistentTags->Operand = ((EFI_IFR_NOT *) &RawFormSet[Index])->Header.OpCode;

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      

+      //

+      // Reserve INVALID_OFFSET_VALUE - 1 for TRUE or FALSE because they are inconsistency tags also, but

+      // have no coresponding id. The examination of id is needed by evaluating boolean expression.

+      //

+      if (RawFormSet[Index] == EFI_IFR_TRUE_OP ||

+          RawFormSet[Index] == EFI_IFR_FALSE_OP) {

+        InconsistentTags->QuestionId1         = INVALID_OFFSET_VALUE - 1;

+      } else {

+        InconsistentTags->QuestionId1         = INVALID_OFFSET_VALUE;

+      }

+      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;

+      InconsistentTags->ConsistencyId       = gConsistencyId;

+      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_EQ_ID_LIST_OP:

+      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+

+      InconsistentTags->Operand = ((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->Header.OpCode;

+      CopyMem (

+        &InconsistentTags->QuestionId1,

+        &((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->QuestionId,

+        sizeof (UINT16)

+        );

+      CopyMem (

+        &InconsistentTags->ListLength,

+        &((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->ListLength,

+        sizeof (UINT16)

+        );

+      InconsistentTags->ValueList = FormTags->Tags[CurrTag].IntList;

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      InconsistentTags->Width               = FormTags->Tags[CurrTag].StorageWidth;

+      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;

+      InconsistentTags->ConsistencyId       = gConsistencyId;

+      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_END_IF_OP:

+      InconsistentTags->Operand = ((EFI_IFR_END_EXPR *) &RawFormSet[Index])->Header.OpCode;

+

+      //

+      // Since this op-code doesn't use the next field(s), initialize them with something invalid.

+      // Unfortunately 0 is a valid offset value for a QuestionId

+      //

+      InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;

+      InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;

+

+      //

+      // Test for an allocated buffer.  If already allocated this is due to having called this routine

+      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize

+      // the tag structure with current values from the NV

+      //

+      if (InconsistentTags->Next == NULL) {

+        AddNextInconsistentTag (&InconsistentTags);

+        break;

+      }

+

+      InconsistentTags = InconsistentTags->Next;

+      break;

+

+    case EFI_IFR_END_ONE_OF_OP:

+      break;

+

+    default:

+      break;

+    }

+    //

+    // End of switch

+    //

+    // Per spec., we ignore ops that we don't know how to deal with.  Skip to next tag

+    //

+    Index = (UINT16) (Index + TagLength);

+  }

+  //

+  // End of Index

+  //

+  // When we eventually exit, make sure we mark the last tag with an op-code

+  //

+  FormTags->Tags[CurrTag].Operand = RawFormSet[Index];

+

+  IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);

+

+  //

+  // Place this as an end of the database marker

+  //

+  InconsistentTags->Operand = 0xFF;

+

+  //

+  // This is the Head of the linked list of pages.  Each page is an array of tags

+  //

+  FormTags          = &FileFormTags->FormTags;

+  InconsistentTags  = FileFormTags->InconsistentTags;

+

+  for (; InconsistentTags->Operand != 0xFF;) {

+    if (InconsistentTags->QuestionId1 != INVALID_OFFSET_VALUE) {

+      //

+      // Search the tags for the tag which corresponds to this ID

+      //

+      for (CurrTag = 0; FormTags->Tags[0].Operand != EFI_IFR_END_FORM_SET_OP; CurrTag++) {

+        //

+        // If we hit the end of a form, go to the next set of Tags.

+        // Remember - EndFormSet op-codes sit on their own page after an end form.

+        //

+        if (FormTags->Tags[CurrTag].Operand == EFI_IFR_END_FORM_OP) {

+          //

+          // Reset the CurrTag value (it will be incremented, after this case statement

+          // so set to a negative one so that we get the desired effect.)  Fish can beat me later.

+          //

+          CurrTag   = -1;

+          FormTags  = FormTags->Next;

+          continue;

+        }

+

+        if (FormTags->Tags[CurrTag].Id == InconsistentTags->QuestionId1) {

+          FormTags->Tags[CurrTag].Consistency++;

+        }

+      }

+    }

+

+    FormTags = &FileFormTags->FormTags;

+

+    if (InconsistentTags->QuestionId2 != INVALID_OFFSET_VALUE) {

+      //

+      // Search the tags for the tag which corresponds to this ID

+      //

+      for (CurrTag = 0; FormTags->Tags[CurrTag].Operand != EFI_IFR_END_FORM_SET_OP; CurrTag++) {

+        //

+        // If we hit the end of a form, go to the next set of Tags.

+        // Remember - EndFormSet op-codes sit on their own page after an end form.

+        //

+        if (FormTags->Tags[CurrTag].Operand == EFI_IFR_END_FORM_OP) {

+          //

+          // Reset the CurrTag value (it will be incremented, after this case statement

+          // so set to a negative one so that we get the desired effect.)  Fish can beat me later.

+          //

+          CurrTag   = -1;

+          FormTags  = FormTags->Next;

+          continue;

+        }

+

+        if (FormTags->Tags[CurrTag].Id == InconsistentTags->QuestionId2) {

+          FormTags->Tags[CurrTag].Consistency++;

+        }

+      }

+    }

+

+    InconsistentTags = InconsistentTags->Next;

+  }

+

+  return Status;

+}

+

+VOID

+InitPage (

+  VOID

+  )

+{

+  CHAR16  *HomePageString;

+  CHAR16  *HomeEscapeString;

+

+  //

+  // Displays the Header and Footer borders

+  //

+  DisplayPageFrame ();

+

+  HomePageString    = GetToken (STRING_TOKEN (HOME_PAGE_TITLE), gHiiHandle);

+  HomeEscapeString  = GetToken (STRING_TOKEN (HOME_ESCAPE_STRING), gHiiHandle);

+

+  gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);

+  //

+  //  PrintStringAt ((gScreenDimensions.RightColumn - GetStringWidth(HomePageString)/2)/2, 1, HomePageString);

+  //

+  PrintStringAt (

+    (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - GetStringWidth (HomePageString) / 2) / 2,

+    1,

+    HomePageString

+    );

+  PrintAt (

+    gScreenDimensions.LeftColumn + 2,

+    gScreenDimensions.BottomRow - 3,

+    (CHAR16 *) L"%c%c%s",

+    ARROW_UP,

+    ARROW_DOWN,

+    gMoveHighlight

+    );

+  PrintAt (

+    gScreenDimensions.RightColumn - (GetStringWidth (HomeEscapeString) / 2) - 2,

+    gScreenDimensions.BottomRow - 3,

+    (CHAR16 *) L" %s",

+    HomeEscapeString

+    );

+  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+  gBS->FreePool (HomeEscapeString);

+  gBS->FreePool (HomePageString);

+

+  return ;

+}

+

+CHAR16 *

+GetToken (

+  IN  STRING_REF                              Token,

+  IN  EFI_HII_HANDLE                          HiiHandle

+  )

+/*++

+

+Routine Description:

+  

+  Get the string based on the TokenID and HII Handle.

+

+Arguments:

+

+  Token       - The Token ID.

+  HiiHandle   - Handle of Ifr to be fetched.

+           

+Returns:

+

+  The output string.

+

+--*/

+{

+  CHAR16      *Buffer;

+  UINTN       BufferLength;

+  EFI_STATUS  Status;

+

+  //

+  // Set default string size assumption at no more than 256 bytes

+  //

+  BufferLength  = 0x100;

+

+  Buffer        = AllocateZeroPool (BufferLength);

+  ASSERT (Buffer != NULL);

+

+  Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);

+

+  if (EFI_ERROR (Status)) {

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      //

+      // Free the old pool

+      //

+      gBS->FreePool (Buffer);

+

+      //

+      // Allocate new pool with correct value

+      //

+      Buffer = AllocatePool (BufferLength);

+      ASSERT (Buffer != NULL);

+

+      Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);

+

+      if (!EFI_ERROR (Status)) {

+        return Buffer;

+      }

+    }

+

+    ASSERT_EFI_ERROR (Status);

+  }

+

+  return Buffer;

+}

+

+EFI_STATUS

+PopulateHomePage (

+  IN UINTN                                    NumberOfIfrImages,

+  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead

+  )

+{

+  EFI_STATUS          Status;

+  UINTN               Index;

+  EFI_IFR_BINARY      *IfrBinary;

+  CHAR16              *StringPtr;

+  EFI_FILE_FORM_TAGS  *FileFormTags;

+  EFI_FORM_TAGS       LocalTags;

+

+  FileFormTags = FileFormTagsHead;

+

+  UiInitMenu ();

+

+  Status = EFI_SUCCESS;

+

+  //

+  // If there are no images

+  //

+  if (NumberOfIfrImages == 0) {

+    Status = EFI_NO_MEDIA;

+    return Status;

+  }

+  //

+  // IfrBinary points to the beginning of the Binary data linked-list

+  //

+  IfrBinary = gBinaryDataHead;

+

+  //

+  // Print the entries which were in the default language.

+  //

+  for (Index = 0; Index < NumberOfIfrImages; Index++) {

+    LocalTags = FileFormTags->FormTags;

+

+    //

+    // Populate the Menu

+    //

+    StringPtr = GetToken (IfrBinary->TitleToken, IfrBinary->Handle);

+

+    //

+    // If the default language doesn't exist, don't add a menu option yet

+    //

+    if (StringPtr[0] != CHAR_NULL) {

+      //

+      // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do

+      // it in UiFreeMenu.

+      //

+      UiAddMenuOption (StringPtr, IfrBinary->Handle, LocalTags.Tags, IfrBinary->FormBinary, Index);

+    }

+    //

+    // Advance to the next HII handle

+    //

+    IfrBinary     = IfrBinary->Next;

+    FileFormTags  = FileFormTags->NextFile;

+  }

+

+  return Status;

+}

+

+UI_MENU_OPTION *

+DisplayHomePage (

+  IN UINTN                                    NumberOfIfrImages,

+  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead,

+  IN UINT8                                    *CallbackData

+  )

+{

+  EFI_STATUS      Status;

+  UI_MENU_OPTION  *Selection;

+

+  //

+  // This prints the basic home page template which the user sees

+  //

+  InitPage ();

+

+  Status = PopulateHomePage (NumberOfIfrImages, FileFormTagsHead);

+

+  if (EFI_ERROR (Status)) {

+    Selection = NULL;

+    return Selection;

+  }

+

+  Selection = UiDisplayMenu (FALSE, FileFormTagsHead, (EFI_IFR_DATA_ARRAY *) CallbackData);

+

+  return Selection;

+}

+

+EFI_STATUS

+InitializeBinaryStructures (

+  IN  EFI_HII_HANDLE                        *Handle,

+  IN  BOOLEAN                               UseDatabase,

+  IN  EFI_IFR_PACKET                        *Packet,

+  IN  UINT8                                 *NvMapOverride,

+  IN  UINTN                                 NumberOfIfrImages,

+  OUT EFI_FILE_FORM_TAGS                    **FileFormTagsHead

+  )

+{

+  UINTN                       HandleIndex;

+  EFI_STATUS                  Status;

+  EFI_IFR_BINARY              *BinaryData;

+  EFI_FILE_FORM_TAGS          *FileFormTags;

+  UINTN                       SizeOfNvStore;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  EFI_VARIABLE_DEFINITION     *VariableDefinition;

+  EFI_VARIABLE_DEFINITION     *OverrideDefinition;

+  VOID                        *NvMap;

+  UINTN                       NvMapSize;

+  EFI_HII_VARIABLE_PACK_LIST  *NvMapListHead;

+  EFI_HII_VARIABLE_PACK_LIST  *NvMapListNode;

+

+  //

+  // Initialize some variables to avoid warnings

+  //

+  BinaryData        = NULL;

+  *FileFormTagsHead = NULL;

+  FileFormTags      = NULL;

+  gBinaryDataHead   = NULL;

+  Status            = EFI_SUCCESS;

+  FormCallback      = NULL;

+  NvMap             = NULL;

+  NvMapSize         = 0;

+

+  if (NumberOfIfrImages > 1) {

+    NvMapOverride = NULL;

+  }

+

+  for (HandleIndex = 0; HandleIndex < NumberOfIfrImages; HandleIndex += 1) {

+    //

+    // If the buffers are uninitialized, allocate them, otherwise work on the ->Next members

+    //

+    if ((BinaryData == NULL) || (FileFormTags == NULL)) {

+      //

+      // Allocate memory for our Binary Data

+      //

+      BinaryData = AllocateZeroPool (sizeof (EFI_IFR_BINARY));

+      ASSERT (BinaryData);

+

+      //

+      // Preserve the Head of what will be a linked-list.

+      //

+      gBinaryDataHead       = BinaryData;

+      gBinaryDataHead->Next = NULL;

+

+      if (UseDatabase) {

+        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);

+      } else {

+        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);

+      }

+      //

+      // Allocate memory for our File Form Tags

+      //

+      FileFormTags = AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));

+      ASSERT (FileFormTags);

+

+      //

+      // Preserve the Head of what will be a linked-list.

+      //

+      *FileFormTagsHead             = FileFormTags;

+      (*FileFormTagsHead)->NextFile = NULL;

+

+    } else {

+      //

+      // Allocate memory for our Binary Data linked-list

+      // Each handle represents a Binary and we will store that data away.

+      //

+      BinaryData->Next = AllocateZeroPool (sizeof (EFI_IFR_BINARY));

+      ASSERT (BinaryData->Next);

+

+      BinaryData        = BinaryData->Next;

+      BinaryData->Next  = NULL;

+

+      if (UseDatabase) {

+        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);

+      } else {

+        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);

+      }

+

+      if (EFI_ERROR (Status)) {

+        return EFI_DEVICE_ERROR;

+      }

+      //

+      // Allocate memory for our FileFormTags linked-list

+      // Each allocation reserves handle represents a Binary and we will store that data away.

+      //

+      FileFormTags->NextFile = AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));

+      ASSERT (FileFormTags->NextFile);

+

+      FileFormTags = FileFormTags->NextFile;

+    }

+    //

+    // endif

+    //

+    // Tag Structure Initialization

+    //

+    Status              = InitializeTagStructures (BinaryData, FileFormTags);

+

+    VariableDefinition  = FileFormTags->VariableDefinitions;

+

+    //

+    // Allocate memory for our NVRAM Maps for all of our variables

+    //

+    for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {

+      //

+      // Pad the fake variable size accordingly - this value should reflect the size of information that is not accounted by

+      // the mainstream NVRAM variable such as DATE/TIME information that the browser needs to track but is saved to an RTC

+      //

+      VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableSize + VariableDefinition->VariableFakeSize);

+

+      //

+      // In the case where a file has no "real" NV data, we should pad the buffer accordingly

+      //

+      if (VariableDefinition->VariableSize == 0) {

+        if (VariableDefinition->VariableFakeSize != 0) {

+          VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableFakeSize);

+          ASSERT (VariableDefinition->NvRamMap != NULL);

+        }

+      } else {

+        VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableSize);

+        ASSERT (VariableDefinition->NvRamMap != NULL);

+      }

+

+      if (VariableDefinition->VariableFakeSize != 0) {

+        VariableDefinition->FakeNvRamMap = AllocateZeroPool (VariableDefinition->VariableFakeSize);

+        ASSERT (VariableDefinition->FakeNvRamMap != NULL);

+      }

+    }

+

+    Status = gBS->HandleProtocol (

+                    (VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,

+                    &gEfiFormCallbackProtocolGuid,

+                    (VOID **) &FormCallback

+                    );

+

+    //

+    // Since we might have multiple variables, if there is an NvMapOverride we need to use the EFI_VARIABLE_DEFINITION

+    // information as the information that we pass back and forth.  NOTE that callbacks that are initiated will only have the

+    // NVRAM data refreshed based on the op-code that initiated the callback.  In other words, we will pass to the caller a single

+    // NVRAM map for a single variable based on the op-code that the user selected.

+    //

+    if (NvMapOverride != NULL) {

+      VariableDefinition  = FileFormTags->VariableDefinitions;

+      OverrideDefinition  = ((EFI_VARIABLE_DEFINITION *) NvMapOverride);

+

+      //

+      // Search through the variable definitions.  There should be sufficient passed in settings for the variable op-codes specified

+      //

+      for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {

+        if ((!CompareMem (VariableDefinition->VariableName, L"Setup", 10)) && (VariableDefinition->Next == NULL)) {

+          if (VariableDefinition->VariableSize != 0) {

+            CopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableSize);

+          } else {

+            CopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableFakeSize);

+          }

+          break;

+        } else {

+          VariableDefinition->NvRamMap = OverrideDefinition->NvRamMap;

+        }

+        //

+        // There should NEVER be a ->Next for VariableDefinition and a NULL ->Next for the OverrideDefinition

+        //

+        ASSERT (OverrideDefinition->Next);

+        OverrideDefinition = OverrideDefinition->Next;

+      }

+    } else {

+      VariableDefinition = FileFormTags->VariableDefinitions;

+

+      //

+      // Search through the variable definitions.  There should be sufficient passed in settings for the variable op-codes specified

+      //

+      for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {

+        SizeOfNvStore = VariableDefinition->VariableSize;

+

+        //

+        // Getting the NvStore and placing it into our Global Data

+        //

+        if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {

+          Status = FormCallback->NvRead (

+                                  FormCallback,

+                                  VariableDefinition->VariableName,

+                                  &VariableDefinition->Guid,

+                                  NULL,

+                                  &SizeOfNvStore,

+                                  (VOID *) VariableDefinition->NvRamMap

+                                  );

+        } else {

+          Status = gRT->GetVariable (

+                          VariableDefinition->VariableName,

+                          &VariableDefinition->Guid,

+                          NULL,

+                          &SizeOfNvStore,

+                          (VOID *) VariableDefinition->NvRamMap

+                          );

+        }

+

+        if (EFI_ERROR (Status)) {

+          //

+          // If there is a variable that exists already and it is larger than what we calculated the

+          // storage needs to be, we must assume the variable size from GetVariable is correct and not

+          // allow the truncation of the variable.  It is very possible that the user who created the IFR

+          // we are cracking is not referring to a variable that was in a previous map, however we cannot

+          // allow it's truncation.

+          //

+          if (Status == EFI_BUFFER_TOO_SMALL) {

+            //

+            // If the buffer was too small, we should have the expanded size requirement in SizeOfNvStore now.

+            //

+            VariableDefinition->VariableSize = (UINT16) SizeOfNvStore;

+

+            //

+            // Free the buffer that was allocated that was too small

+            //

+            gBS->FreePool (VariableDefinition->NvRamMap);

+            gBS->FreePool (VariableDefinition->FakeNvRamMap);

+

+            VariableDefinition->NvRamMap = AllocateZeroPool (SizeOfNvStore);

+            VariableDefinition->FakeNvRamMap = AllocateZeroPool (SizeOfNvStore + VariableDefinition->VariableFakeSize);

+            ASSERT (VariableDefinition->NvRamMap);

+            ASSERT (VariableDefinition->FakeNvRamMap);

+

+            if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {

+              Status = FormCallback->NvRead (

+                                      FormCallback,

+                                      VariableDefinition->VariableName,

+                                      &VariableDefinition->Guid,

+                                      NULL,

+                                      &SizeOfNvStore,

+                                      (VOID *) VariableDefinition->NvRamMap

+                                      );

+            } else {

+              Status = gRT->GetVariable (

+                              VariableDefinition->VariableName,

+                              &VariableDefinition->Guid,

+                              NULL,

+                              &SizeOfNvStore,

+                              (VOID *) VariableDefinition->NvRamMap

+                              );

+            }

+          }

+          //

+          // if the variable was not found, we will retrieve default values

+          //

+          if (Status == EFI_NOT_FOUND) {

+        

+            if (0 == CompareMem (VariableDefinition->VariableName, L"Setup", 10)) {

+

+              NvMapListHead = NULL;

+              

+              Status = Hii->GetDefaultImage (Hii, Handle[HandleIndex], EFI_IFR_FLAG_DEFAULT, &NvMapListHead);

+

+              if (!EFI_ERROR (Status)) {

+                ASSERT_EFI_ERROR (NULL != NvMapListHead);

+                

+                NvMapListNode = NvMapListHead;

+                

+                while (NULL != NvMapListNode) {

+                  if (VariableDefinition->VariableId == NvMapListNode->VariablePack->VariableId) {

+                    NvMap     = (VOID *) ((CHAR8 *) NvMapListNode->VariablePack + sizeof (EFI_HII_VARIABLE_PACK) + NvMapListNode->VariablePack->VariableNameLength);

+                    NvMapSize = NvMapListNode->VariablePack->Header.Length  - sizeof (EFI_HII_VARIABLE_PACK) - NvMapListNode->VariablePack->VariableNameLength;

+                    break;

+                    }

+                  NvMapListNode = NvMapListNode->NextVariablePack;

+                }

+                

+                //

+                // Free the buffer that was allocated.

+                //

+                gBS->FreePool (VariableDefinition->NvRamMap);

+                gBS->FreePool (VariableDefinition->FakeNvRamMap);

+                

+                //

+                // Allocate, copy the NvRamMap.

+                //

+                VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize - VariableDefinition->VariableSize);

+                VariableDefinition->VariableSize = (UINT16) NvMapSize;

+                VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + VariableDefinition->VariableSize);

+                

+                VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableSize);

+                VariableDefinition->FakeNvRamMap = AllocateZeroPool (NvMapSize + VariableDefinition->VariableFakeSize);

+

+                CopyMem (VariableDefinition->NvRamMap, NvMap, NvMapSize);

+                gBS->FreePool (NvMapListHead);

+              }

+

+            }

+            Status = EFI_SUCCESS;

+          }

+        }

+      }

+    }

+

+    InitializeTagStructures (BinaryData, FileFormTags);

+  }

+  //

+  // endfor

+  //

+  return Status;

+}

+

+EFI_STATUS

+GetIfrBinaryData (

+  IN      EFI_HII_PROTOCOL *Hii,

+  IN      EFI_HII_HANDLE   HiiHandle,

+  IN      EFI_IFR_PACKET   *Packet,

+  IN OUT  EFI_IFR_BINARY   *BinaryData

+  )

+/*++

+

+Routine Description:

+  Fetch the Ifr binary data.

+

+Arguments:

+  Hii         - Point to HII protocol.

+  HiiHandle   - Handle of Ifr to be fetched.

+  Packet      - Pointer to IFR packet.

+  BinaryData  - Buffer to copy the string into

+           

+Returns:

+  Returns the number of CHAR16 characters that were copied into the OutputString buffer.

+

+

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_HII_PACKAGES  *PackageList;

+  UINTN             BufferSize;

+  VOID              *Buffer;

+  UINT8             *RawFormBinary;

+  EFI_IFR_FORM_SET  *FormOp;

+  UINT16            Index;

+  UINT16            Index2;

+  UINT16            TitleToken;

+

+  //

+  // Initialize the TitleToken to 0 just in case not found

+  //

+  TitleToken = 0;

+

+  //

+  // Try for a 32K Buffer

+  //

+  BufferSize = 0x8000;

+

+  //

+  // Allocate memory for our Form binary

+  //

+  Buffer = AllocateZeroPool (BufferSize);

+  ASSERT (Buffer);

+

+  if (Packet == NULL) {

+    Status = Hii->GetForms (Hii, HiiHandle, 0, &BufferSize, Buffer);

+

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+

+      gBS->FreePool (Buffer);

+

+      //

+      // Allocate memory for our Form binary

+      //

+      Buffer = AllocatePool (BufferSize);

+      ASSERT (Buffer);

+

+      Status = Hii->GetForms (Hii, HiiHandle, 0, &BufferSize, Buffer);

+    }

+  } else {

+    //

+    // Copies the data to local usable buffer

+    //

+    CopyMem (Buffer, Packet->IfrData, Packet->IfrData->Header.Length);

+

+    //

+    // Register the string data with HII

+    //

+    PackageList = PreparePackages (2, NULL, Packet->IfrData, Packet->StringData);

+

+    Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);

+

+    gBS->FreePool (PackageList);

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // We now have the IFR binary in our Buffer

+  //

+  BinaryData->IfrPackage  = Buffer;

+  RawFormBinary           = (UINT8 *) ((CHAR8 *) (Buffer) + sizeof (EFI_HII_PACK_HEADER));

+  BinaryData->FormBinary  = (UINT8 *) ((CHAR8 *) (Buffer) + sizeof (EFI_HII_PACK_HEADER));

+  BinaryData->Handle      = HiiHandle;

+

+  //

+  // If a packet was passed in, remove the string data when exiting.

+  //

+  if (Packet != NULL) {

+    BinaryData->UnRegisterOnExit = TRUE;

+  } else {

+    BinaryData->UnRegisterOnExit = FALSE;

+  }

+  //

+  // Walk through the FormSet Opcodes looking for the FormSet opcode

+  // If we hit EFI_IFR_END_SET_OP we know we hit the end of the FormSet.

+  //

+  for (Index = 0; RawFormBinary[Index] != EFI_IFR_END_FORM_SET_OP;) {

+    FormOp  = (EFI_IFR_FORM_SET *) &RawFormBinary[Index];

+    Index   = (UINT16) (Index + FormOp->Header.Length);

+

+    if (FormOp->Header.OpCode == EFI_IFR_FORM_SET_OP) {

+      TitleToken = FormOp->FormSetTitle;

+      //

+      // If displaying FrontPage - set the flag signifying it

+      //

+      switch (FormOp->SubClass) {

+      case EFI_FRONT_PAGE_SUBCLASS:

+        FrontPageHandle = HiiHandle;

+

+      default:

+        gClassOfVfr = FormOp->SubClass;

+      }

+      //

+      // Match GUID to find out the function key setting. If match fail, use the default setting.

+      //

+      for (Index2 = 0; Index2 < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index2++) {

+        if (CompareGuid ((EFI_GUID *)(UINTN)&FormOp->Guid, &(gFunctionKeySettingTable[Index2].FormSetGuid))) {

+          //

+          // Update the function key setting.

+          //

+          gFunctionKeySetting = gFunctionKeySettingTable[Index2].KeySetting;

+          //

+          // Function key prompt can not be displayed if the function key has been disabled.

+          //

+          if ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE) {

+            gFunctionOneString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);

+          }

+

+          if ((gFunctionKeySetting & FUNCTION_TWO) != FUNCTION_TWO) {

+            gFunctionTwoString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);

+          }

+

+          if ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE) {

+            gFunctionNineString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);

+          }

+

+          if ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN) {

+            gFunctionTenString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);

+          }

+        }

+      }

+    }

+  }

+

+  BinaryData->TitleToken = TitleToken;

+

+  return Status;

+}

+

+EFI_HANDLE          PrintHandle     = NULL;

+EFI_PRINT_PROTOCOL  mPrintProtocol  = { UnicodeVSPrint };

+

+EFI_STATUS

+InstallPrint (

+  VOID

+  )

+{

+  return gBS->InstallProtocolInterface (

+                &PrintHandle,

+                &gEfiPrintProtocolGuid,

+                EFI_NATIVE_INTERFACE,

+                &mPrintProtocol

+                );

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Setup.h b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Setup.h
new file mode 100644
index 0000000..6089d76
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Setup.h
@@ -0,0 +1,504 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Setup.h

+

+Abstract:

+

+

+Revision History

+

+--*/

+

+#ifndef _SETUP_H

+#define _SETUP_H

+

+//

+// This is the generated header file which includes whatever needs to be exported (strings + IFR)

+//

+#include "SetupBrowserStrDefs.h"

+extern UINT8  SetupBrowserStrings[];

+

+//

+// Screen definitions

+//

+#define BANNER_HEIGHT                 4

+#define BANNER_COLUMNS                3

+

+#define FRONT_PAGE_HEADER_HEIGHT      4

+#define NONE_FRONT_PAGE_HEADER_HEIGHT 3

+#define LEFT_SKIPPED_COLUMNS          4

+#define FOOTER_HEIGHT                 4

+#define STATUS_BAR_HEIGHT             1

+#define SCROLL_ARROW_HEIGHT           1

+#define POPUP_PAD_SPACE_COUNT         5

+#define POPUP_FRAME_WIDTH             2

+

+

+#define EFI_SETUP_APPLICATION_SUBCLASS    0x00

+#define EFI_GENERAL_APPLICATION_SUBCLASS  0x01

+#define EFI_FRONT_PAGE_SUBCLASS           0x02

+#define EFI_SINGLE_USE_SUBCLASS           0x03  // Used to display a single entity and then exit

+//

+// Definition for function key setting

+//

+#define NONE_FUNCTION_KEY_SETTING     0

+#define DEFAULT_FUNCTION_KEY_SETTING  (FUNCTION_ONE | FUNCTION_TWO | FUNCTION_NINE | FUNCTION_TEN)

+

+#define FUNCTION_ONE                  (1 << 0)

+#define FUNCTION_TWO                  (1 << 1)

+#define FUNCTION_NINE                 (1 << 2)

+#define FUNCTION_TEN                  (1 << 3)

+

+typedef struct {

+  EFI_GUID  FormSetGuid;

+  UINTN     KeySetting;

+} FUNCTIION_KEY_SETTING;

+

+//

+// Character definitions

+//

+#define CHAR_SPACE              0x0020

+#define UPPER_LOWER_CASE_OFFSET 0x20

+

+//

+// Time definitions

+//

+#define ONE_SECOND  10000000

+

+//

+// Display definitions

+//

+#define LEFT_HYPER_DELIMITER      L'<'

+#define RIGHT_HYPER_DELIMITER     L'>'

+

+#define LEFT_ONEOF_DELIMITER      L'<'

+#define RIGHT_ONEOF_DELIMITER     L'>'

+

+#define LEFT_NUMERIC_DELIMITER    L'['

+#define RIGHT_NUMERIC_DELIMITER   L']'

+

+#define LEFT_CHECKBOX_DELIMITER   L"["

+#define RIGHT_CHECKBOX_DELIMITER  L"]"

+

+#define CHECK_ON                  L"X"

+#define CHECK_OFF                 L" "

+

+#define TIME_SEPARATOR            L':'

+#define DATE_SEPARATOR            L'/'

+

+#define YES_ANSWER                L'Y'

+#define NO_ANSWER                 L'N'

+

+//

+// Up to how many lines does the ordered list display

+//

+#define ORDERED_LIST_SIZE 4

+

+//

+// This is the Input Error Message

+//

+#define INPUT_ERROR 1

+

+//

+// This is the NV RAM update required Message

+//

+#define NV_UPDATE_REQUIRED  2

+

+//

+// Refresh the Status Bar with flags

+//

+#define REFRESH_STATUS_BAR  0xff

+

+//

+// This width is basically the sum of the prompt and option widths

+//

+#define QUESTION_BLOCK_WIDTH  50

+

+//

+// Width of the Language Description (Using ISO-639-2 3 ASCII letter standard)

+//

+#define LANG_DESC_WIDTH 3

+

+//

+// Maximum Number of Binaries we can see

+//

+#define MAX_BINARIES  255

+

+//

+// Invalid Handle

+//

+#define EFI_HII_INVALID_HANDLE  0xFFFF

+

+//

+// Invalid Offset Value

+//

+#define INVALID_OFFSET_VALUE  0xFFFF

+

+struct StringPart {

+  struct StringPart *Next;

+  CHAR8             String[QUESTION_BLOCK_WIDTH + 2];

+};

+

+//

+// The tag definition defines the data associated with a tag (an operation

+// in the IFR lingo).  The tag is thus a modified union of all the data

+// required for tags.  The user should be careful to only rely upon information

+// relevant to that tag as the contents of other fields is undefined.

+//

+// The intent here is for this to be all of the data associated with a particular tag.

+// Some of this data is extracted from the IFR and left alone.  Other data will be derived

+// when the page is selected (since that's the first time we really know what language the

+// page is to be displayed in) and still other data will vary based on the selection.

+// If you'd like to consider alternatives, let me know.  This structure has grown somewhat organically.

+// It gets a new item stuffed in it when a new item is needed.  When I finally decided I needed the

+// StringPart structure, items got added here, for example.

+//

+typedef struct {

+  UINT8                 Operand;        // The operand (first byte) of the variable length tag.

+  EFI_GUID              GuidValue;      // Primarily for FormSet data

+  EFI_PHYSICAL_ADDRESS  CallbackHandle;

+  UINT16                Class;

+  UINT16                SubClass;

+  UINT16                NumberOfLines;  // The number of lines the tag takes up on the page.  Adjusted when we display the page as it can change from language to language.

+  UINT16                PageLine;

+  UINT16                PageColumn;

+  UINT16                OptionWidth;    // The option can be wider than the column usually associated with options.  This is the width on the last option line

+  STRING_REF            Text;           // Used for title, subtitle, prompt, etc.  This is the string token associated with the string.  This token is language independent.

+  STRING_REF            TextTwo;        // Used for title, subtitle, prompt, etc.  This is the string token associated with the string.  This token is language independent.

+  STRING_REF            Help;           // Null means no help  Same as above but for languages.

+  UINT16                Consistency;    // Do we need to check this opcode against consistency?  If > 0, yes.

+  UINT16                Id;

+  UINT16                Id2;            // The questions (mainly) have identifiers associated with them.  These are filled in from the IFR tags and used by e.g. the RPN calculations. (com1 is set to, versus com2 is set to)

+  //

+  // These are the three values that are created to determine where in the variable the data is stored.  This should, in general,

+  // be allocated by the build tool.  The one major issue is, once storage is allocated for something, it can't be reallocated or we will get a mess.

+  //

+  UINT16                StorageStart;

+  //

+  // These are the three values that are created to determine where in the variable the data is stored.  This should, in general,

+  // be allocated by the build tool.  The one major issue is, once storage is allocated for something, it can't be reallocated or we will get a mess.

+  //

+  UINT8                 StorageWidth; 

+  //

+  // These are the three values that are created to determine where in the variable the data is stored.  This should, in general,

+  // be allocated by the build tool.  The one major issue is, once storage is allocated for something, it can't be reallocated or we will get a mess.

+  //

+  UINT16                Value;

+  //

+  // (Default or current)

+  //

+  UINT8                 Flags;        

+  UINT16                Key;

+  //

+  // Used to preserve a value during late consistency checking

+  //

+  UINT16                OldValue;     

+  UINT16                Minimum;

+  UINT16                Maximum;

+  UINT16                Step;

+  UINT16                Default;

+  UINT16                NvDataSize;

+  UINT16                ConsistencyId;

+  BOOLEAN               GrayOut;

+  BOOLEAN               Suppress;

+  UINT16                Encoding;     // Data from the tags.  The first three are used by the numeric input.  Encoding is used by the password stuff (a placeholder today - may go away).

+  UINT16                *IntList;     // List of the values possible for a list question

+  //

+  // The string is obtained from the string list and formatted into lines and the lines are held in this linked list.

+  // If we have more than a screen's worth of items, we will end up with cases where we have to display the last couple

+  // lines of a tag's string above the currently selected one, or, display a few lines of a tag at the bottom of a screen.

+  //

+  struct StringPart     *StringList;  

+  BOOLEAN               ResetRequired;    // Primarily used to determine if a reset is required by changing this op-code.

+  UINT16                VariableNumber;   // Used to define which variable the StorageStart will be pertinent for (0-based)  For single variable VFR this will always be 0.

+  //

+  // Used to define which variable the StorageStart will be pertinent for (0-based)  This is used for boolean check of ID versus ID

+  // so that a user can compare the value of one variable.field content versus another variable.field content.

+  //

+  UINT16                VariableNumber2;  

+} EFI_TAG;

+

+#define EFI_FORM_DATA_SIGNATURE EFI_SIGNATURE_32 ('F', 'o', 'r', 'm')

+

+typedef struct {

+  UINTN                     Signature;

+

+  EFI_HII_PROTOCOL          *Hii;

+  EFI_FORM_BROWSER_PROTOCOL FormConfig;

+} EFI_FORM_CONFIGURATION_DATA;

+

+#define EFI_FORM_DATA_FROM_THIS(a)  CR (a, EFI_FORM_CONFIGURATION_DATA, FormConfig, EFI_FORM_DATA_SIGNATURE)

+

+typedef struct _EFI_VARIABLE_DEFINITION {

+  CHAR8                           *NvRamMap;

+  CHAR8                           *FakeNvRamMap;    // This is where the storage for NULL devices go (e.g. RTC)

+  EFI_GUID                        Guid;

+  UINT16                          VariableId;

+  UINT16                          VariableSize;

+  UINT16                          VariableFakeSize; // For dynamically created and NULL device options, this is the latest size

+  CHAR16                          *VariableName;

+  struct _EFI_VARIABLE_DEFINITION *Next;

+  struct _EFI_VARIABLE_DEFINITION *Previous;

+} EFI_VARIABLE_DEFINITION;

+

+typedef struct {

+  UINT32      Length;                               // Length in bytes between beginning of struc and end of Strings

+  CHAR8       LanguageCode[4];                      // ISO-639-2 language code with a null-terminator

+  RELOFST     PrintableLanguageName;                // Translated name of the Language, "English"/"Espanol" etc

+  UINT32      Attributes;                           // If on, the language is intended to be printed right to left.  The default (off) is to print left to right.

+  RELOFST     StringsPointers[1];                   // Pointing to string offset from beginning of String Binary

+  EFI_STRING  Strings[1];                           // Array of String Entries.  Note the number of entries for Strings and StringsPointers will be the same

+} EFI_LANGUAGE_SET;

+

+//

+// This encapsulates all the pointers associated with found IFR binaries

+//

+typedef struct _EFI_IFR_BINARY {

+  struct _EFI_IFR_BINARY  *Next;

+  VOID                    *IfrPackage;  // Handy for use in freeing the data later since this is the header of the buffer

+  VOID                    *FormBinary;

+  EFI_HII_HANDLE          Handle;

+  STRING_REF              TitleToken;

+  BOOLEAN                 UnRegisterOnExit;

+} EFI_IFR_BINARY;

+

+//

+// This encapsulates all the questions (tags) for a particular Form Set

+//

+typedef struct _EFI_FORM_TAGS {

+  struct _EFI_FORM_TAGS *Next;

+  EFI_TAG               *Tags;

+} EFI_FORM_TAGS;

+

+//

+// This is the database of all inconsistency data.  Each op-code associated

+// with inconsistency will be tracked here.  This optimizes the search requirement

+// since we will back mark the main tag structure with the op-codes that have reference

+// to inconsistency data.  This way when parsing the main tag structure and encountering

+// the inconsistency mark - we can search this database to know what the inconsistency

+// parameters are for that entry.

+//

+typedef struct _EFI_INCONSISTENCY_DATA {

+  struct _EFI_INCONSISTENCY_DATA  *Next;

+  struct _EFI_INCONSISTENCY_DATA  *Previous;

+  UINT8                           Operand;

+  STRING_REF                      Popup;

+  UINT16                          QuestionId1;

+  UINT16                          QuestionId2;

+  UINT16                          Value;

+  UINT16                          ListLength;

+  UINT16                          ConsistencyId;

+  UINT16                          *ValueList;

+  UINT16                          VariableNumber;

+  UINT16                          VariableNumber2;

+  UINT8                           Width;

+} EFI_INCONSISTENCY_DATA;

+

+//

+// Encapsulating all found Tag information from all sources

+// Each encapsulation also contains the NvRamMap buffer and the Size of the NV store

+//

+typedef struct _EFI_FILE_FORM_TAGS {

+  struct _EFI_FILE_FORM_TAGS  *NextFile;

+  EFI_INCONSISTENCY_DATA      *InconsistentTags;

+  EFI_VARIABLE_DEFINITION     *VariableDefinitions;

+  EFI_FORM_TAGS               FormTags;

+} EFI_FILE_FORM_TAGS;

+

+typedef struct {

+  STRING_REF  Banner[BANNER_HEIGHT][BANNER_COLUMNS];

+} BANNER_DATA;

+

+//

+// Head of the Binary structures

+//

+EFI_IFR_BINARY    *gBinaryDataHead;

+

+//

+// The IFR binary that the user chose to run

+//

+UINTN             gActiveIfr;

+

+EFI_HII_PROTOCOL  *Hii;

+

+VOID              *CachedNVEntry;

+BANNER_DATA       *BannerData;

+EFI_HII_HANDLE    FrontPageHandle;

+STRING_REF        FrontPageTimeOutTitle;

+INT16             FrontPageTimeOutValue;

+UINTN             gClassOfVfr;

+UINTN             gFunctionKeySetting;

+BOOLEAN           gResetRequired;

+BOOLEAN           gExitRequired;

+BOOLEAN           gSaveRequired;

+BOOLEAN           gNvUpdateRequired;

+UINT16            gConsistencyId;

+UINTN             gPriorMenuEntry;

+EFI_HII_HANDLE    gHiiHandle;

+BOOLEAN           gFirstIn;

+VOID              *gPreviousValue;

+UINT16            gDirection;

+EFI_SCREEN_DESCRIPTOR gScreenDimensions;

+BOOLEAN           gUpArrow;

+BOOLEAN           gDownArrow;

+BOOLEAN           gTimeOnScreen;

+BOOLEAN           gDateOnScreen;

+

+//

+// Browser Global Strings

+//

+CHAR16            *gFunctionOneString;

+CHAR16            *gFunctionTwoString;

+CHAR16            *gFunctionNineString;

+CHAR16            *gFunctionTenString;

+CHAR16            *gEnterString;

+CHAR16            *gEnterCommitString;

+CHAR16            *gEscapeString;

+CHAR16            *gMoveHighlight;

+CHAR16            *gMakeSelection;

+CHAR16            *gNumericInput;

+CHAR16            *gToggleCheckBox;

+CHAR16            *gPromptForPassword;

+CHAR16            *gPromptForNewPassword;

+CHAR16            *gConfirmPassword;

+CHAR16            *gConfirmError;

+CHAR16            *gPressEnter;

+CHAR16            *gEmptyString;

+CHAR16            *gAreYouSure;

+CHAR16            *gYesResponse;

+CHAR16            *gNoResponse;

+CHAR16            *gMiniString;

+CHAR16            *gPlusString;

+CHAR16            *gMinusString;

+CHAR16            *gAdjustNumber;

+

+CHAR16            gPromptBlockWidth;

+CHAR16            gOptionBlockWidth;

+CHAR16            gHelpBlockWidth;

+

+//

+// Global Procedure Defines

+//

+VOID

+InitializeBrowserStrings (

+  VOID

+  )

+;

+

+UINTN

+Print (

+  IN CHAR16                         *fmt,

+  ...

+  )

+;

+

+UINTN

+PrintString (

+  CHAR16       *String

+  )

+;

+

+UINTN

+PrintChar (

+  CHAR16       Character

+  )

+;

+

+UINTN

+PrintAt (

+  IN UINTN     Column,

+  IN UINTN     Row,

+  IN CHAR16    *fmt,

+  ...

+  )

+;

+

+UINTN

+PrintStringAt (

+  IN UINTN     Column,

+  IN UINTN     Row,

+  CHAR16       *String

+  )

+;

+

+UINTN

+PrintCharAt (

+  IN UINTN     Column,

+  IN UINTN     Row,

+  CHAR16       Character

+  )

+;

+

+VOID

+DisplayPageFrame (

+  VOID

+  )

+;

+

+CHAR16            *

+GetToken (

+  IN  STRING_REF                              IfrBinaryTitle,

+  IN  EFI_HII_HANDLE                          HiiHandle

+  )

+;

+

+VOID

+GetTagCount (

+  IN      UINT8                                 *RawFormSet,

+  IN OUT  UINT16                                *NumberOfTags

+  )

+;

+

+VOID

+GetNumericHeader (

+  IN  EFI_TAG             *Tag,

+  IN  UINT8               *RawFormSet,

+  IN  UINT16              Index,

+  IN  UINT16              NumberOfLines,

+  IN  EFI_FILE_FORM_TAGS  *FileFormTags,

+  IN  UINT16              CurrentVariable

+  )

+;

+

+VOID

+GetQuestionHeader (

+  IN  EFI_TAG             *Tag,

+  IN  UINT8               *RawFormSet,

+  IN  UINT16              Index,

+  IN  EFI_FILE_FORM_TAGS  *FileFormTags,

+  IN  UINT16              CurrentVariable

+  )

+;

+

+VOID

+CreateSharedPopUp (

+  IN  UINTN                       RequestedWidth,

+  IN  UINTN                       NumberOfLines,

+  IN  CHAR16                      **ArrayOfStrings

+  )

+;

+

+EFI_STATUS

+CreateDialog (

+  IN  UINTN                       NumberOfLines,

+  IN  BOOLEAN                     HotKey,

+  IN  UINTN                       MaximumStringSize,

+  OUT CHAR16                      *StringBuffer,

+  OUT EFI_INPUT_KEY               *KeyValue,

+  IN  CHAR16                      *String,

+  ...

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.mbd b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.mbd
new file mode 100644
index 0000000..6a3eec1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>SetupBrowser</BaseName>

+    <Guid>EBf342FE-B1D3-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseDebugLibNull</Library>    

+    <Library>BaseMemoryLib</Library>

+    <Library>BasePrintLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>EdkGraphicsLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>HiiLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.msa b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.msa
new file mode 100644
index 0000000..ec9e5d6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowser.msa
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>SetupBrowser</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>EBf342FE-B1D3-4EF8-957C-8048606FF670</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkIfrSupportLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkGraphicsLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>SetupBrowserStr.uni</Filename>

+    <Filename>Setup.c</Filename>

+    <Filename>Setup.h</Filename>

+    <Filename>Boolean.c</Filename>

+    <Filename>InputHandler.c</Filename>

+    <Filename>Print.c</Filename>

+    <Filename>Print.h</Filename>

+    <Filename>Presentation.c</Filename>

+    <Filename>ProcessOptions.c</Filename>

+    <Filename>Ui.c</Filename>

+    <Filename>Ui.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FormCallback</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">FormBrowser</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">Print</Protocol>

+  </Protocols>

+  <Events>

+    <CreateEvents>

+      <Event>

+        <C_Name>EFI_EVENT_TIMER</C_Name>

+      </Event>

+    </CreateEvents>

+  </Events>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeSetup</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowserStr.uni b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowserStr.uni
new file mode 100644
index 0000000..1dfd924
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/SetupBrowserStr.uni
Binary files differ
diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c
new file mode 100644
index 0000000..0d512fd
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c
@@ -0,0 +1,3143 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ui.c

+

+Abstract:

+   

+  Implementation for UI.

+

+Revision History

+

+--*/

+

+#include "Setup.h"

+#include "Ui.h"

+#include "Colors.h"

+

+//

+// Implementation

+//

+VOID

+SetUnicodeMem (

+  IN VOID   *Buffer,

+  IN UINTN  Size,

+  IN CHAR16 Value

+  )

+/*++

+

+Routine Description:

+

+  Set Buffer to Value for Size bytes.

+

+Arguments:

+

+  Buffer  - Memory to set.

+

+  Size    - Number of bytes to set

+

+  Value   - Value of the set operation.

+

+Returns:

+

+  None

+

+--*/

+{

+  CHAR16  *Ptr;

+

+  Ptr = Buffer;

+  while (Size--) {

+    *(Ptr++) = Value;

+  }

+}

+

+VOID

+UiInitMenu (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Initialize Menu option list.

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  InitializeListHead (&Menu);

+}

+

+VOID

+UiInitMenuList (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Initialize Menu option list.

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  InitializeListHead (&gMenuList);

+}

+

+VOID

+UiRemoveMenuListEntry (

+  IN  UI_MENU_OPTION    *Selection,

+  OUT UI_MENU_OPTION    **PreviousSelection

+  )

+/*++

+

+Routine Description:

+  Remove Menu option list.

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  UI_MENU_LIST  *UiMenuList;

+

+  *PreviousSelection = AllocateZeroPool (sizeof (UI_MENU_OPTION));

+  ASSERT (*PreviousSelection != NULL);

+

+  if (!IsListEmpty (&gMenuList)) {

+    UiMenuList                      = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);

+    (*PreviousSelection)->IfrNumber = UiMenuList->Selection.IfrNumber;

+    (*PreviousSelection)->FormId    = UiMenuList->Selection.FormId;

+    (*PreviousSelection)->Tags      = UiMenuList->Selection.Tags;

+    (*PreviousSelection)->ThisTag   = UiMenuList->Selection.ThisTag;

+    (*PreviousSelection)->Handle    = UiMenuList->Selection.Handle;

+    gEntryNumber                    = UiMenuList->FormerEntryNumber;

+    RemoveEntryList (&UiMenuList->MenuLink);

+    gBS->FreePool (UiMenuList);

+  }

+}

+

+VOID

+UiFreeMenuList (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Free Menu option linked list.

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  UI_MENU_LIST  *UiMenuList;

+

+  while (!IsListEmpty (&gMenuList)) {

+    UiMenuList = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);

+    RemoveEntryList (&UiMenuList->MenuLink);

+    gBS->FreePool (UiMenuList);

+  }

+}

+

+VOID

+UiAddMenuListEntry (

+  IN UI_MENU_OPTION   *Selection

+  )

+/*++

+

+Routine Description:

+  Add one menu entry to the linked lst

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  UI_MENU_LIST  *UiMenuList;

+

+  UiMenuList = AllocateZeroPool (sizeof (UI_MENU_LIST));

+  ASSERT (UiMenuList != NULL);

+

+  UiMenuList->Signature = UI_MENU_LIST_SIGNATURE;

+  CopyMem (&UiMenuList->Selection, Selection, sizeof (UI_MENU_OPTION));

+

+  InsertHeadList (&gMenuList, &UiMenuList->MenuLink);

+}

+

+VOID

+UiFreeMenu (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Free Menu option linked list.

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  UI_MENU_OPTION  *MenuOption;

+

+  while (!IsListEmpty (&Menu)) {

+    MenuOption = CR (Menu.ForwardLink, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+    RemoveEntryList (&MenuOption->Link);

+

+    //

+    // We allocated space for this description when we did a GetToken, free it here

+    //

+    gBS->FreePool (MenuOption->Description);

+    gBS->FreePool (MenuOption);

+  }

+}

+

+VOID

+UpdateDateAndTime (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Refresh screen with current date and/or time based on screen context

+

+Arguments:

+           

+Returns:

+

+--*/

+{

+  CHAR16              *OptionString;

+  MENU_REFRESH_ENTRY  *MenuRefreshEntry;

+  UINTN               Index;

+  UINTN               Loop;

+

+  OptionString = NULL;

+

+  if (gMenuRefreshHead != NULL) {

+

+    MenuRefreshEntry = gMenuRefreshHead;

+

+    do {

+      gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);

+      ProcessOptions (MenuRefreshEntry->MenuOption, FALSE, MenuRefreshEntry->FileFormTagsHead, NULL, &OptionString);

+

+      if (OptionString != NULL) {

+        //

+        // If leading spaces on OptionString - remove the spaces

+        //

+        for (Index = 0; OptionString[Index] == L' '; Index++)

+          ;

+

+        for (Loop = 0; OptionString[Index] != CHAR_NULL; Index++) {

+          OptionString[Loop] = OptionString[Index];

+          Loop++;

+        }

+

+        OptionString[Loop] = CHAR_NULL;

+

+        PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);

+      }

+

+      MenuRefreshEntry = MenuRefreshEntry->Next;

+

+    } while (MenuRefreshEntry != NULL);

+  }

+

+  if (OptionString != NULL) {

+    gBS->FreePool (OptionString);

+  }

+}

+

+EFI_STATUS

+UiWaitForSingleEvent (

+  IN EFI_EVENT                Event,

+  IN UINT64                   Timeout OPTIONAL

+  )

+/*++

+

+Routine Description:

+  Wait for a given event to fire, or for an optional timeout to expire.

+

+Arguments:

+  Event            - The event to wait for

+

+  Timeout          - An optional timeout value in 100 ns units.

+

+Returns:

+

+  EFI_SUCCESS      - Event fired before Timeout expired.

+  EFI_TIME_OUT     - Timout expired before Event fired.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+  EFI_EVENT   TimerEvent;

+  EFI_EVENT   WaitList[2];

+

+  if (Timeout) {

+    //

+    // Create a timer event

+    //

+    Status = gBS->CreateEvent (EFI_EVENT_TIMER, 0, NULL, NULL, &TimerEvent);

+    if (!EFI_ERROR (Status)) {

+      //

+      // Set the timer event

+      //

+      gBS->SetTimer (

+            TimerEvent,

+            TimerRelative,

+            Timeout

+            );

+

+      //

+      // Wait for the original event or the timer

+      //

+      WaitList[0] = Event;

+      WaitList[1] = TimerEvent;

+      Status      = gBS->WaitForEvent (2, WaitList, &Index);

+      gBS->CloseEvent (TimerEvent);

+

+      //

+      // If the timer expired, change the return to timed out

+      //

+      if (!EFI_ERROR (Status) && Index == 1) {

+        Status = EFI_TIMEOUT;

+      }

+    }

+  } else {

+    //

+    // Update screen every second

+    //

+    Timeout = ONE_SECOND;

+

+    do {

+      Status = gBS->CreateEvent (EFI_EVENT_TIMER, 0, NULL, NULL, &TimerEvent);

+

+      //

+      // Set the timer event

+      //

+      gBS->SetTimer (

+            TimerEvent,

+            TimerRelative,

+            Timeout

+            );

+

+      //

+      // Wait for the original event or the timer

+      //

+      WaitList[0] = Event;

+      WaitList[1] = TimerEvent;

+      Status      = gBS->WaitForEvent (2, WaitList, &Index);

+

+      //

+      // If the timer expired, update anything that needs a refresh and keep waiting

+      //

+      if (!EFI_ERROR (Status) && Index == 1) {

+        Status = EFI_TIMEOUT;

+        UpdateDateAndTime ();

+      }

+

+      gBS->CloseEvent (TimerEvent);

+    } while (Status == EFI_TIMEOUT);

+  }

+

+  return Status;

+}

+

+VOID

+UiAddMenuOption (

+  IN CHAR16         *String,

+  IN EFI_HII_HANDLE Handle,

+  IN EFI_TAG        *Tags,

+  IN VOID           *FormBinary,

+  IN UINTN          IfrNumber

+  )

+/*++

+

+Routine Description:

+  Add one menu option by specified description and context.

+

+Arguments:

+  String - String description for this option.

+  Context - Context data for entry.

+           

+Returns:

+

+--*/

+{

+  UI_MENU_OPTION  *MenuOption;

+

+  MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));

+  ASSERT (MenuOption);

+

+  MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;

+  MenuOption->Description = String;

+  MenuOption->Handle      = Handle;

+  MenuOption->FormBinary  = FormBinary;

+  MenuOption->IfrNumber   = IfrNumber;

+  MenuOption->Skip        = 1;

+  MenuOption->Tags        = Tags;

+  MenuOption->TagIndex    = 0;

+  MenuOption->ThisTag     = &(MenuOption->Tags[MenuOption->TagIndex]);

+  MenuOption->EntryNumber = (UINT16) IfrNumber;

+

+  InsertTailList (&Menu, &MenuOption->Link);

+}

+

+VOID

+UiAddSubMenuOption (

+  IN CHAR16           *String,

+  IN EFI_HII_HANDLE   Handle,

+  IN EFI_TAG          *Tags,

+  IN UINTN            TagIndex,

+  IN UINT16           FormId,

+  IN UINT16           MenuItemCount

+  )

+/*++

+

+Routine Description:

+  Add one menu option by specified description and context.

+

+Arguments:

+  String - String description for this option.

+  Context - Context data for entry.

+           

+Returns:

+

+--*/

+{

+  UI_MENU_OPTION  *MenuOption;

+

+  MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));

+  ASSERT (MenuOption);

+

+  MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;

+  MenuOption->Description = String;

+  MenuOption->Handle      = Handle;

+  MenuOption->Skip        = Tags[TagIndex].NumberOfLines;

+  MenuOption->IfrNumber   = gActiveIfr;

+  MenuOption->Tags        = Tags;

+  MenuOption->TagIndex    = TagIndex;

+  MenuOption->ThisTag     = &(MenuOption->Tags[MenuOption->TagIndex]);

+  MenuOption->Consistency = Tags[TagIndex].Consistency;

+  MenuOption->FormId      = FormId;

+  MenuOption->GrayOut     = Tags[TagIndex].GrayOut;

+  MenuOption->EntryNumber = MenuItemCount;

+

+  InsertTailList (&Menu, &MenuOption->Link);

+}

+

+EFI_STATUS

+CreateDialog (

+  IN  UINTN                       NumberOfLines,

+  IN  BOOLEAN                     HotKey,

+  IN  UINTN                       MaximumStringSize,

+  OUT CHAR16                      *StringBuffer,

+  OUT EFI_INPUT_KEY               *KeyValue,

+  IN  CHAR16                      *String,

+  ...

+  )

+/*++

+

+Routine Description:

+  Routine used to abstract a generic dialog interface and return the selected key or string

+

+Arguments:

+  NumberOfLines -     The number of lines for the dialog box

+  HotKey -            Defines whether a single character is parsed (TRUE) and returned in KeyValue 

+                      or a string is returned in StringBuffer.  Two special characters are considered when entering a string, a SCAN_ESC and

+                      an CHAR_CARRIAGE_RETURN.  SCAN_ESC terminates string input and returns

+  MaximumStringSize - The maximum size in bytes of a typed in string (each character is a CHAR16) and the minimum string returned is two bytes

+  StringBuffer -      The passed in pointer to the buffer which will hold the typed in string if HotKey is FALSE

+  KeyValue -          The EFI_KEY value returned if HotKey is TRUE..

+  String -            Pointer to the first string in the list

+  ... -               A series of (quantity == NumberOfLines) text strings which will be used to construct the dialog box

+           

+Returns:

+  EFI_SUCCESS -           Displayed dialog and received user interaction

+  EFI_INVALID_PARAMETER - One of the parameters was invalid (e.g. (StringBuffer == NULL) && (HotKey == FALSE))

+  EFI_DEVICE_ERROR -      User typed in an ESC character to exit the routine

+

+--*/

+{

+  VA_LIST       Marker;

+  UINTN         Count;

+  EFI_INPUT_KEY Key;

+  UINTN         LargestString;

+  CHAR16        *TempString;

+  CHAR16        *BufferedString;

+  CHAR16        *StackString;

+  CHAR16        KeyPad[2];

+  UINTN         Start;

+  UINTN         Top;

+  UINTN         Index;

+  EFI_STATUS    Status;

+  BOOLEAN       SelectionComplete;

+  UINTN         InputOffset;

+  UINTN         CurrentAttribute;

+  UINTN         DimensionsWidth;

+  UINTN         DimensionsHeight;

+

+  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

+  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

+

+  SelectionComplete = FALSE;

+  InputOffset       = 0;

+  TempString        = AllocateZeroPool (MaximumStringSize * 2);

+  BufferedString    = AllocateZeroPool (MaximumStringSize * 2);

+  CurrentAttribute  = gST->ConOut->Mode->Attribute;

+

+  ASSERT (TempString);

+  ASSERT (BufferedString);

+

+  VA_START (Marker, String);

+

+  //

+  // Zero the outgoing buffer

+  //

+  ZeroMem (StringBuffer, MaximumStringSize);

+

+  if (HotKey) {

+    if (KeyValue == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+  } else {

+    if (StringBuffer == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Disable cursor

+  //

+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

+

+  LargestString = (GetStringWidth (String) / 2);

+

+  if (LargestString == L' ') {

+    InputOffset = 1;

+  }

+  //

+  // Determine the largest string in the dialog box

+  // Notice we are starting with 1 since String is the first string

+  //

+  for (Count = 1; Count < NumberOfLines; Count++) {

+    StackString = VA_ARG (Marker, CHAR16 *);

+

+    if (StackString[0] == L' ') {

+      InputOffset = Count + 1;

+    }

+

+    if ((GetStringWidth (StackString) / 2) > LargestString) {

+      //

+      // Size of the string visually and subtract the width by one for the null-terminator

+      //

+      LargestString = (GetStringWidth (StackString) / 2);

+    }

+  }

+

+  Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;

+  Top   = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;

+

+  Count = 0;

+

+  //

+  // Display the Popup

+  //

+  CreateSharedPopUp (LargestString, NumberOfLines, &String);

+

+  //

+  // Take the first key typed and report it back?

+  //

+  if (HotKey) {

+    Status = WaitForKeyStroke (&Key);

+    CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));

+

+  } else {

+    do {

+      Status = WaitForKeyStroke (&Key);

+

+      switch (Key.UnicodeChar) {

+      case CHAR_NULL:

+        switch (Key.ScanCode) {

+        case SCAN_ESC:

+          gBS->FreePool (TempString);

+          gBS->FreePool (BufferedString);

+          gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);

+          gST->ConOut->EnableCursor (gST->ConOut, TRUE);

+          return EFI_DEVICE_ERROR;

+

+        default:

+          break;

+        }

+

+        break;

+

+      case CHAR_CARRIAGE_RETURN:

+        SelectionComplete = TRUE;

+        gBS->FreePool (TempString);

+        gBS->FreePool (BufferedString);

+        gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);

+        gST->ConOut->EnableCursor (gST->ConOut, TRUE);

+        return EFI_SUCCESS;

+        break;

+

+      case CHAR_BACKSPACE:

+        if (StringBuffer[0] != CHAR_NULL) {

+          for (Index = 0; StringBuffer[Index] != CHAR_NULL; Index++) {

+            TempString[Index] = StringBuffer[Index];

+          }

+          //

+          // Effectively truncate string by 1 character

+          //

+          TempString[Index - 1] = CHAR_NULL;

+          StrCpy (StringBuffer, TempString);

+        }

+

+      default:

+        //

+        // If it is the beginning of the string, don't worry about checking maximum limits

+        //

+        if ((StringBuffer[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {

+          StrnCpy (StringBuffer, &Key.UnicodeChar, 1);

+          StrnCpy (TempString, &Key.UnicodeChar, 1);

+        } else if ((GetStringWidth (StringBuffer) < MaximumStringSize) && (Key.UnicodeChar != CHAR_BACKSPACE)) {

+          KeyPad[0] = Key.UnicodeChar;

+          KeyPad[1] = CHAR_NULL;

+          StrCat (StringBuffer, KeyPad);

+          StrCat (TempString, KeyPad);

+        }

+        //

+        // If the width of the input string is now larger than the screen, we nee to

+        // adjust the index to start printing portions of the string

+        //

+        SetUnicodeMem (BufferedString, LargestString, L' ');

+

+        PrintStringAt (Start + 1, Top + InputOffset, BufferedString);

+

+        if ((GetStringWidth (StringBuffer) / 2) > (DimensionsWidth - 2)) {

+          Index = (GetStringWidth (StringBuffer) / 2) - DimensionsWidth + 2;

+        } else {

+          Index = 0;

+        }

+

+        for (Count = 0; Index + 1 < GetStringWidth (StringBuffer) / 2; Index++, Count++) {

+          BufferedString[Count] = StringBuffer[Index];

+        }

+

+        PrintStringAt (Start + 1, Top + InputOffset, BufferedString);

+        break;

+      }

+    } while (!SelectionComplete);

+  }

+

+  gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);

+  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

+  return EFI_SUCCESS;

+}

+

+VOID

+CreateSharedPopUp (

+  IN  UINTN                       RequestedWidth,

+  IN  UINTN                       NumberOfLines,

+  IN  CHAR16                      **ArrayOfStrings

+  )

+{

+  UINTN   Index;

+  UINTN   Count;

+  CHAR16  Character;

+  UINTN   Start;

+  UINTN   End;

+  UINTN   Top;

+  UINTN   Bottom;

+  CHAR16  *String;

+

+  UINTN   DimensionsWidth;

+  UINTN   DimensionsHeight;

+

+  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

+  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

+

+  Count             = 0;

+

+  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

+

+  if ((RequestedWidth + 2) > DimensionsWidth) {

+    RequestedWidth = DimensionsWidth - 2;

+  }

+  //

+  // Subtract the PopUp width from total Columns, allow for one space extra on

+  // each end plus a border.

+  //

+  Start     = (DimensionsWidth - RequestedWidth - 2) / 2 + gScreenDimensions.LeftColumn + 1;

+  End       = Start + RequestedWidth + 1;

+

+  Top       = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;

+  Bottom    = Top + NumberOfLines + 2;

+

+  Character = (CHAR16) BOXDRAW_DOWN_RIGHT;

+  PrintCharAt (Start, Top, Character);

+  Character = (CHAR16) BOXDRAW_HORIZONTAL;

+  for (Index = Start; Index + 2 < End; Index++) {

+    PrintChar (Character);

+  }

+

+  Character = (CHAR16) BOXDRAW_DOWN_LEFT;

+  PrintChar (Character);

+  Character = (CHAR16) BOXDRAW_VERTICAL;

+  for (Index = Top; Index + 2 < Bottom; Index++) {

+    String = ArrayOfStrings[Count];

+    Count++;

+

+    //

+    // This will clear the background of the line - we never know who might have been

+    // here before us.  This differs from the next clear in that it used the non-reverse

+    // video for normal printing.

+    //

+    if (GetStringWidth (String) / 2 > 1) {

+      ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);

+    }

+    //

+    // Passing in a space results in the assumption that this is where typing will occur

+    //

+    if (String[0] == L' ') {

+      ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);

+    }

+    //

+    // Passing in a NULL results in a blank space

+    //

+    if (String[0] == CHAR_NULL) {

+      ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);

+    }

+

+    PrintStringAt (

+      ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,

+      Index + 1,

+      String

+      );

+    gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

+    PrintCharAt (Start, Index + 1, Character);

+    PrintCharAt (End - 1, Index + 1, Character);

+  }

+

+  Character = (CHAR16) BOXDRAW_UP_RIGHT;

+  PrintCharAt (Start, Bottom - 1, Character);

+  Character = (CHAR16) BOXDRAW_HORIZONTAL;

+  for (Index = Start; Index + 2 < End; Index++) {

+    PrintChar (Character);

+  }

+

+  Character = (CHAR16) BOXDRAW_UP_LEFT;

+  PrintChar (Character);

+}

+

+VOID

+CreatePopUp (

+  IN  UINTN                       RequestedWidth,

+  IN  UINTN                       NumberOfLines,

+  IN  CHAR16                      *ArrayOfStrings,

+  ...

+  )

+{

+  CreateSharedPopUp (RequestedWidth, NumberOfLines, &ArrayOfStrings);

+}

+

+VOID

+UpdateStatusBar (

+  IN  UINTN                       MessageType,

+  IN  UINT8                       Flags,

+  IN  BOOLEAN                     State

+  )

+{

+  UINTN           Index;

+  STATIC BOOLEAN  InputError;

+  CHAR16          *NvUpdateMessage;

+  CHAR16          *InputErrorMessage;

+

+  NvUpdateMessage   = GetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), gHiiHandle);

+  InputErrorMessage = GetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), gHiiHandle);

+

+  switch (MessageType) {

+  case INPUT_ERROR:

+    if (State) {

+      gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);

+      PrintStringAt (

+        gScreenDimensions.LeftColumn + gPromptBlockWidth,

+        gScreenDimensions.BottomRow - 1,

+        InputErrorMessage

+        );

+      InputError = TRUE;

+    } else {

+      gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT);

+      for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {

+        PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, (CHAR16 *) L"  ");

+      }

+

+      InputError = FALSE;

+    }

+    break;

+

+  case NV_UPDATE_REQUIRED:

+    if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {

+      if (State) {

+        gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);

+        PrintStringAt (

+          gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth,

+          gScreenDimensions.BottomRow - 1,

+          NvUpdateMessage

+          );

+        gResetRequired    = (BOOLEAN) (gResetRequired | (Flags & RESET_REQUIRED));

+

+        gNvUpdateRequired = TRUE;

+      } else {

+        gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT);

+        for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) {

+          PrintAt (

+            (gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + Index),

+            gScreenDimensions.BottomRow - 1,

+            (CHAR16 *) L"  "

+            );

+        }

+

+        gNvUpdateRequired = FALSE;

+      }

+    }

+    break;

+

+  case REFRESH_STATUS_BAR:

+    if (InputError) {

+      UpdateStatusBar (INPUT_ERROR, Flags, TRUE);

+    }

+

+    if (gNvUpdateRequired) {

+      UpdateStatusBar (NV_UPDATE_REQUIRED, Flags, TRUE);

+    }

+    break;

+

+  default:

+    break;

+  }

+

+  gBS->FreePool (InputErrorMessage);

+  gBS->FreePool (NvUpdateMessage);

+  return ;

+}

+

+VOID

+FreeData (

+  IN EFI_FILE_FORM_TAGS           *FileFormTagsHead,

+  IN CHAR16                       *FormattedString,

+  IN CHAR16                       *OptionString

+  )

+/*++

+

+Routine Description:

+  

+  Used to remove the allocated data instances

+

+Arguments:

+             

+Returns:

+

+--*/

+{

+  EFI_FILE_FORM_TAGS      *FileForm;

+  EFI_FILE_FORM_TAGS      *PreviousFileForm;

+  EFI_FORM_TAGS           *FormTags;

+  EFI_FORM_TAGS           *PreviousFormTags;

+  EFI_IFR_BINARY          *IfrBinary;

+  EFI_IFR_BINARY          *PreviousIfrBinary;

+  EFI_INCONSISTENCY_DATA  *Inconsistent;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+  EFI_VARIABLE_DEFINITION *PreviousVariableDefinition;

+  VOID                    *Buffer;

+  UINTN                   Index;

+

+  FileForm = FileFormTagsHead;

+

+  if (FormattedString != NULL) {

+    gBS->FreePool (FormattedString);

+  }

+

+  if (OptionString != NULL) {

+    gBS->FreePool (OptionString);

+  }

+

+  for (; FileForm != NULL;) {

+    PreviousFileForm = NULL;

+

+    //

+    // Advance FileForm to the last entry

+    //

+    for (; FileForm->NextFile != NULL; FileForm = FileForm->NextFile) {

+      PreviousFileForm = FileForm;

+    }

+

+    FormTags = &FileForm->FormTags;

+

+    for (; FormTags != NULL;) {

+      FormTags          = &FileForm->FormTags;

+      PreviousFormTags  = NULL;

+

+      //

+      // Advance FormTags to the last entry

+      //

+      for (; FormTags->Next != NULL; FormTags = FormTags->Next) {

+        PreviousFormTags = FormTags;

+      }

+      //

+      // Walk through each of the tags and free the IntList allocation

+      //

+      for (Index = 0; FormTags->Tags[Index].Operand != EFI_IFR_END_FORM_OP; Index++) {

+        //

+        // It is more than likely that the very last page will contain an end formset

+        //

+        if (FormTags->Tags[Index].Operand == EFI_IFR_END_FORM_SET_OP) {

+          break;

+        }

+

+        if (FormTags->Tags[Index].IntList != NULL) {

+          gBS->FreePool (FormTags->Tags[Index].IntList);

+        }

+      }

+

+      if (PreviousFormTags != NULL) {

+        gBS->FreePool (FormTags->Tags);

+        FormTags = PreviousFormTags;

+        gBS->FreePool (FormTags->Next);

+        FormTags->Next = NULL;

+      } else {

+        gBS->FreePool (FormTags->Tags);

+        FormTags = NULL;

+      }

+    }

+    //

+    // Last FileForm entry's Inconsistent database

+    //

+    Inconsistent = FileForm->InconsistentTags;

+

+    //

+    // Advance Inconsistent to the last entry

+    //

+    for (; Inconsistent->Next != NULL; Inconsistent = Inconsistent->Next)

+      ;

+

+    for (; Inconsistent != NULL;) {

+      //

+      // Preserve the Previous pointer

+      //

+      Buffer = (VOID *) Inconsistent->Previous;

+

+      //

+      // Free the current entry

+      //

+      gBS->FreePool (Inconsistent);

+

+      //

+      // Restore the Previous pointer

+      //

+      Inconsistent = (EFI_INCONSISTENCY_DATA *) Buffer;

+    }

+

+    VariableDefinition = FileForm->VariableDefinitions;

+

+    for (; VariableDefinition != NULL;) {

+      VariableDefinition          = FileForm->VariableDefinitions;

+      PreviousVariableDefinition  = NULL;

+

+      //

+      // Advance VariableDefinitions to the last entry

+      //

+      for (; VariableDefinition->Next != NULL; VariableDefinition = VariableDefinition->Next) {

+        PreviousVariableDefinition = VariableDefinition;

+      }

+

+      gBS->FreePool (VariableDefinition->VariableName);

+      gBS->FreePool (VariableDefinition->NvRamMap);

+      gBS->FreePool (VariableDefinition->FakeNvRamMap);

+

+      if (PreviousVariableDefinition != NULL) {

+        VariableDefinition = PreviousVariableDefinition;

+        gBS->FreePool (VariableDefinition->Next);

+        VariableDefinition->Next = NULL;

+      } else {

+        gBS->FreePool (VariableDefinition);

+        VariableDefinition = NULL;

+      }

+    }

+

+    if (PreviousFileForm != NULL) {

+      FileForm = PreviousFileForm;

+      gBS->FreePool (FileForm->NextFile);

+      FileForm->NextFile = NULL;

+    } else {

+      gBS->FreePool (FileForm);

+      FileForm = NULL;

+    }

+  }

+

+  IfrBinary = gBinaryDataHead;

+

+  for (; IfrBinary != NULL;) {

+    IfrBinary         = gBinaryDataHead;

+    PreviousIfrBinary = NULL;

+

+    //

+    // Advance IfrBinary to the last entry

+    //

+    for (; IfrBinary->Next != NULL; IfrBinary = IfrBinary->Next) {

+      PreviousIfrBinary = IfrBinary;

+    }

+

+    gBS->FreePool (IfrBinary->IfrPackage);

+

+    if (PreviousIfrBinary != NULL) {

+      IfrBinary = PreviousIfrBinary;

+      gBS->FreePool (IfrBinary->Next);

+      IfrBinary->Next = NULL;

+    } else {

+      gBS->FreePool (IfrBinary);

+      IfrBinary = NULL;

+    }

+  }

+

+  gBS->FreePool (gPreviousValue);

+  gPreviousValue = NULL;

+

+  //

+  // Free Browser Strings

+  //

+  gBS->FreePool (gPressEnter);

+  gBS->FreePool (gConfirmError);

+  gBS->FreePool (gConfirmPassword);

+  gBS->FreePool (gPromptForNewPassword);

+  gBS->FreePool (gPromptForPassword);

+  gBS->FreePool (gToggleCheckBox);

+  gBS->FreePool (gNumericInput);

+  gBS->FreePool (gMakeSelection);

+  gBS->FreePool (gMoveHighlight);

+  gBS->FreePool (gEscapeString);

+  gBS->FreePool (gEnterCommitString);

+  gBS->FreePool (gEnterString);

+  gBS->FreePool (gFunctionOneString);

+  gBS->FreePool (gFunctionTwoString);

+  gBS->FreePool (gFunctionNineString);

+  gBS->FreePool (gFunctionTenString);

+  return ;

+}

+

+BOOLEAN

+SelectionsAreValid (

+  IN  UI_MENU_OPTION               *MenuOption,

+  IN  EFI_FILE_FORM_TAGS           *FileFormTagsHead

+  )

+/*++

+

+Routine Description:

+  Initiate late consistency checks against the current page.  

+

+Arguments:

+  None

+           

+Returns:

+

+--*/

+{

+  LIST_ENTRY              *Link;

+  EFI_TAG                 *Tag;

+  EFI_FILE_FORM_TAGS      *FileFormTags;

+  CHAR16                  *StringPtr;

+  CHAR16                  NullCharacter;

+  EFI_STATUS              Status;

+  UINTN                   Index;

+  UINT16                  *NvRamMap;

+  STRING_REF              PopUp;

+  EFI_INPUT_KEY           Key;

+  EFI_VARIABLE_DEFINITION *VariableDefinition;

+

+  StringPtr     = (CHAR16 *) L"\0";

+  NullCharacter = CHAR_NULL;

+

+  FileFormTags  = FileFormTagsHead;

+

+  for (Index = 0; Index < MenuOption->IfrNumber; Index++) {

+    FileFormTags = FileFormTags->NextFile;

+  }

+

+  for (Link = Menu.ForwardLink; Link != &Menu; Link = Link->ForwardLink) {

+    MenuOption  = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+    Tag         = MenuOption->ThisTag;

+

+    ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);

+    NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];

+

+    //

+    // If the op-code has a late check, ensure consistency checks are now applied

+    //

+    if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) {

+      if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) {

+        if (PopUp != 0x0000) {

+          StringPtr = GetToken (PopUp, MenuOption->Handle);

+

+          CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter);

+

+          do {

+            Status = WaitForKeyStroke (&Key);

+

+            switch (Key.UnicodeChar) {

+

+            case CHAR_CARRIAGE_RETURN:

+              //

+              // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth

+              //

+              CopyMem (NvRamMap, &Tag->OldValue, Tag->StorageWidth);

+              gBS->FreePool (StringPtr);

+              break;

+

+            default:

+              break;

+            }

+          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

+        }

+

+        return FALSE;

+      }

+    }

+  }

+

+  return TRUE;

+}

+

+UINT16

+GetWidth (

+  IN EFI_TAG                        *Tag,

+  IN EFI_HII_HANDLE                 Handle

+  )

+/*++

+

+Routine Description:

+  Get the supported width for a particular op-code

+

+Arguments:

+  Tag - The Tag structure passed in.

+  Handle - The handle in the HII database being used

+  

+Returns:

+  Returns the number of CHAR16 characters that is support.

+

+

+--*/

+{

+  CHAR16  *String;

+  UINTN   Size;

+

+  Size = 0x00;

+

+  //

+  // See if the second text parameter is really NULL

+  //

+  if ((Tag->Operand == EFI_IFR_TEXT_OP) && (Tag->TextTwo != 0)) {

+    String  = GetToken (Tag->TextTwo, Handle);

+    Size    = StrLen (String);

+    gBS->FreePool (String);

+  }

+

+  if ((Tag->Operand == EFI_IFR_SUBTITLE_OP) ||

+      (Tag->Operand == EFI_IFR_REF_OP) ||

+      (Tag->Operand == EFI_IFR_PASSWORD_OP) ||

+      (Tag->Operand == EFI_IFR_STRING_OP) ||

+      (Tag->Operand == EFI_IFR_INVENTORY_OP) ||

+      //

+      // Allow a wide display if text op-code and no secondary text op-code

+      //

+      ((Tag->Operand == EFI_IFR_TEXT_OP) && (Size == 0x0000))

+      ) {

+    return (UINT16) (gPromptBlockWidth + gOptionBlockWidth);

+  } else {

+    return (UINT16) gPromptBlockWidth;

+  }

+}

+

+UINT16

+GetLineByWidth (

+  IN      CHAR16                      *InputString,

+  IN      UINT16                      LineWidth,

+  IN OUT  UINTN                       *Index,

+  OUT     CHAR16                      **OutputString

+  )

+/*++

+

+Routine Description:

+  Will copy LineWidth amount of a string in the OutputString buffer and return the

+  number of CHAR16 characters that were copied into the OutputString buffer.

+

+Arguments:

+  InputString - String description for this option.

+  LineWidth - Width of the desired string to extract in CHAR16 characters

+  Index - Where in InputString to start the copy process

+  OutputString - Buffer to copy the string into

+           

+Returns:

+  Returns the number of CHAR16 characters that were copied into the OutputString buffer.

+

+

+--*/

+{

+  static BOOLEAN  Finished;

+  UINT16          Count;

+  UINT16          Count2;

+

+  if (Finished) {

+    Finished = FALSE;

+    return (UINT16) 0;

+  }

+

+  Count         = LineWidth;

+  Count2        = 0;

+

+  *OutputString = AllocateZeroPool (((UINTN) (LineWidth + 1) * 2));

+

+  //

+  // Ensure we have got a valid buffer

+  //

+  if (*OutputString != NULL) {

+    //

+    // Fast-forward the string and see if there is a carriage-return in the string

+    //

+    for (; (InputString[*Index + Count2] != CHAR_CARRIAGE_RETURN) && (Count2 != LineWidth); Count2++)

+      ;

+

+    //

+    // Copy the desired LineWidth of data to the output buffer.

+    // Also make sure that we don't copy more than the string.

+    // Also make sure that if there are linefeeds, we account for them.

+    //

+    if ((StrSize (&InputString[*Index]) <= ((UINTN) (LineWidth + 1) * 2)) &&

+        (StrSize (&InputString[*Index]) <= ((UINTN) (Count2 + 1) * 2))

+        ) {

+      //

+      // Convert to CHAR16 value and show that we are done with this operation

+      //

+      LineWidth = (UINT16) ((StrSize (&InputString[*Index]) - 2) / 2);

+      if (LineWidth != 0) {

+        Finished = TRUE;

+      }

+    } else {

+      if (Count2 == LineWidth) {

+        //

+        // Rewind the string from the maximum size until we see a space to break the line

+        //

+        for (; (InputString[*Index + LineWidth] != CHAR_SPACE) && (LineWidth != 0); LineWidth--)

+          ;

+        if (LineWidth == 0) {

+          LineWidth = Count;

+        }

+      } else {

+        LineWidth = Count2;

+      }

+    }

+

+    CopyMem (*OutputString, &InputString[*Index], LineWidth * 2);

+

+    //

+    // If currently pointing to a space, increment the index to the first non-space character

+    //

+    for (;

+         (InputString[*Index + LineWidth] == CHAR_SPACE) || (InputString[*Index + LineWidth] == CHAR_CARRIAGE_RETURN);

+         (*Index)++

+        )

+      ;

+    *Index = (UINT16) (*Index + LineWidth);

+    return LineWidth;

+  } else {

+    return (UINT16) 0;

+  }

+}

+

+VOID

+UpdateOptionSkipLines (

+  IN EFI_IFR_DATA_ARRAY           *PageData,

+  IN UI_MENU_OPTION               *MenuOption,

+  IN EFI_FILE_FORM_TAGS           *FileFormTagsHead,

+  IN CHAR16                       **OptionalString,

+  IN UINTN                        SkipValue

+  )

+{

+  UINTN   Index;

+  UINTN   Loop;

+  UINT16  Width;

+  UINTN   Row;

+  UINTN   OriginalRow;

+  CHAR16  *OutputString;

+  CHAR16  *OptionString;

+

+  Row           = 0;

+  OptionString  = *OptionalString;

+  OutputString  = NULL;

+

+  ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);

+

+  if (OptionString != NULL) {

+    //

+    // If leading spaces on OptionString - remove the spaces

+    //

+    for (Index = 0; OptionString[Index] == L' '; Index++)

+    ;

+

+    for (Loop = 0; OptionString[Index] != CHAR_NULL; Index++) {

+      OptionString[Loop] = OptionString[Index];

+      Loop++;

+    }

+

+    OptionString[Loop]  = CHAR_NULL;

+

+    Width               = (UINT16) gOptionBlockWidth;

+

+    OriginalRow         = Row;

+

+    for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {

+      //

+      // If there is more string to process print on the next row and increment the Skip value

+      //

+      if (StrLen (&OptionString[Index])) {

+        if (SkipValue == 0) {

+          Row++;

+          //

+          // Since the Number of lines for this menu entry may or may not be reflected accurately

+          // since the prompt might be 1 lines and option might be many, and vice versa, we need to do

+          // some testing to ensure we are keeping this in-sync.

+          //

+          // If the difference in rows is greater than or equal to the skip value, increase the skip value

+          //

+          if ((Row - OriginalRow) >= MenuOption->Skip) {

+            MenuOption->Skip++;

+          }

+        }

+      }

+

+      gBS->FreePool (OutputString);

+      if (SkipValue != 0) {

+        SkipValue--;

+      }

+    }

+

+    Row = OriginalRow;

+  }

+

+  *OptionalString = OptionString;

+}

+//

+// Search table for UiDisplayMenu()

+//

+SCAN_CODE_TO_SCREEN_OPERATION     gScanCodeToOperation[] = {

+  { SCAN_UP,        UiUp },

+  { SCAN_DOWN,      UiDown },

+  { SCAN_PAGE_UP,   UiPageUp },

+  { SCAN_PAGE_DOWN, UiPageDown},

+  { SCAN_ESC,       UiReset},

+  { SCAN_F2,        UiPrevious},

+  { SCAN_LEFT,      UiLeft },

+  { SCAN_RIGHT,     UiRight },

+  { SCAN_F9,        UiDefault},

+  { SCAN_F10,       UiSave }

+};

+

+SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {

+  { UiNoOperation,  CfUiNoOperation },

+  { UiDefault,      CfUiDefault },

+  { UiSelect,       CfUiSelect },

+  { UiUp,           CfUiUp},

+  { UiDown,         CfUiDown },

+  { UiLeft,         CfUiLeft },

+  { UiRight,        CfUiRight },

+  { UiReset,        CfUiReset },

+  { UiSave,         CfUiSave },

+  { UiPrevious,     CfUiPrevious },

+  { UiPageUp,       CfUiPageUp },

+  { UiPageDown,     CfUiPageDown }

+};

+

+UI_MENU_OPTION *

+UiDisplayMenu (

+  IN  BOOLEAN                      SubMenu,

+  IN  EFI_FILE_FORM_TAGS           *FileFormTagsHead,

+  OUT EFI_IFR_DATA_ARRAY           *PageData

+  )

+/*++

+

+Routine Description:

+  Display menu and wait for user to select one menu option, then return it.

+  If AutoBoot is enabled, then if user doesn't select any option,

+  after period of time, it will automatically return the first menu option.

+

+Arguments:

+  SubMenu          - Indicate is sub menu.

+  FileFormTagsHead - A pointer to the EFI_FILE_FORM_TAGS structure.

+  PageData         - A pointer to the EFI_IFR_DATA_ARRAY.

+           

+Returns:

+  Return the pointer of the menu which selected, 

+  otherwise return NULL.

+

+--*/

+{

+  INTN                        SkipValue;

+  INTN                        Difference;

+  INTN                        OldSkipValue;

+  UINTN                       Row;

+  UINTN                       Col;

+  UINTN                       Temp;

+  UINTN                       Temp2;

+  UINTN                       TopRow;

+  UINTN                       BottomRow;

+  UINTN                       OriginalRow;

+  UINTN                       Index;

+  UINTN                       DataAndTimeLineNumberPad;

+  UINT32                      Count;

+  INT16                       OriginalTimeOut;

+  UINT8                       *Location;

+  UINT16                      Width;

+  CHAR16                      *StringPtr;

+  CHAR16                      *OptionString;

+  CHAR16                      *OutputString;

+  CHAR16                      *FormattedString;

+  CHAR16                      YesResponse;

+  CHAR16                      NoResponse;

+  BOOLEAN                     NewLine;

+  BOOLEAN                     Repaint;

+  BOOLEAN                     SavedValue;

+  EFI_STATUS                  Status;

+  UI_MENU_LIST                *UiMenuList;

+  EFI_INPUT_KEY               Key;

+  LIST_ENTRY                  *Link;

+  LIST_ENTRY                  *NewPos;

+  LIST_ENTRY                  *TopOfScreen;

+  LIST_ENTRY                  *SavedListEntry;

+  UI_MENU_OPTION              *Selection;

+  UI_MENU_OPTION              *MenuOption;

+  UI_MENU_OPTION              *NextMenuOption;

+  UI_MENU_OPTION              *SavedMenuOption;

+  UI_MENU_OPTION              *PreviousMenuOption;

+  EFI_IFR_BINARY              *IfrBinary;

+  UI_CONTROL_FLAG             ControlFlag;

+  EFI_SCREEN_DESCRIPTOR           LocalScreen;

+  EFI_FILE_FORM_TAGS          *FileFormTags;

+  MENU_REFRESH_ENTRY          *MenuRefreshEntry;

+  MENU_REFRESH_ENTRY          *OldMenuRefreshEntry;

+  UI_SCREEN_OPERATION         ScreenOperation;

+  EFI_VARIABLE_DEFINITION     *VariableDefinition;

+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;

+  EFI_HII_VARIABLE_PACK_LIST  *NvMapListHead;

+  EFI_HII_VARIABLE_PACK_LIST  *NvMapListNode;

+  VOID                        *NvMap;

+  UINTN                       NvMapSize;

+

+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));

+

+  VariableDefinition  = NULL;

+  Status              = EFI_SUCCESS;

+  FormattedString     = NULL;

+  OptionString        = NULL;

+  ScreenOperation     = UiNoOperation;

+  NewLine             = TRUE;

+  FormCallback        = NULL;

+  FileFormTags        = NULL;

+  OutputString        = NULL;

+  gUpArrow            = FALSE;

+  gDownArrow          = FALSE;

+  SkipValue           = 0;

+  OldSkipValue        = 0;

+  MenuRefreshEntry    = gMenuRefreshHead;

+  OldMenuRefreshEntry = gMenuRefreshHead;

+  NextMenuOption      = NULL;

+  PreviousMenuOption  = NULL;

+  SavedMenuOption     = NULL;

+  IfrBinary           = NULL;

+  NvMap               = NULL;

+  NvMapSize           = 0;

+

+  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));

+

+  if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {

+    TopRow  = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;

+    Row     = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;

+  } else {

+    TopRow  = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;

+    Row     = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;

+  }

+

+  if (SubMenu) {

+    Col = LocalScreen.LeftColumn;

+  } else {

+    Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS;

+  }

+

+  BottomRow   = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT - SCROLL_ARROW_HEIGHT - 1;

+

+  TopOfScreen = Menu.ForwardLink;

+  Repaint     = TRUE;

+  MenuOption  = NULL;

+

+  //

+  // Get user's selection

+  //

+  Selection = NULL;

+  NewPos    = Menu.ForwardLink;

+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

+

+  UpdateStatusBar (REFRESH_STATUS_BAR, (UINT8) 0, TRUE);

+

+  ControlFlag = CfInitialization;

+

+  while (TRUE) {

+    switch (ControlFlag) {

+    case CfInitialization:

+      ControlFlag = CfCheckSelection;

+      if (gExitRequired) {

+        ScreenOperation = UiReset;

+        ControlFlag     = CfScreenOperation;

+      } else if (gSaveRequired) {

+        ScreenOperation = UiSave;

+        ControlFlag     = CfScreenOperation;

+      } else if (IsListEmpty (&Menu)) {

+        ControlFlag = CfReadKey;

+      }

+      break;

+

+    case CfCheckSelection:

+      if (Selection != NULL) {

+        ControlFlag = CfExit;

+      } else {

+        ControlFlag = CfRepaint;

+      }

+

+      FileFormTags = FileFormTagsHead;

+      break;

+

+    case CfRepaint:

+      ControlFlag = CfRefreshHighLight;

+

+      if (Repaint) {

+        //

+        // Display menu

+        //

+        SavedMenuOption = MenuOption;

+        gDownArrow      = FALSE;

+        gUpArrow        = FALSE;

+        Row             = TopRow;

+

+        Temp            = SkipValue;

+        Temp2           = SkipValue;

+

+        ClearLines (

+          LocalScreen.LeftColumn,

+          LocalScreen.RightColumn,

+          TopRow - SCROLL_ARROW_HEIGHT,

+          BottomRow + SCROLL_ARROW_HEIGHT,

+          FIELD_TEXT | FIELD_BACKGROUND

+          );

+

+        while (gMenuRefreshHead != NULL) {

+          OldMenuRefreshEntry = gMenuRefreshHead->Next;

+

+          gBS->FreePool (gMenuRefreshHead);

+

+          gMenuRefreshHead = OldMenuRefreshEntry;

+        }

+

+        for (Link = TopOfScreen; Link != &Menu; Link = Link->ForwardLink) {

+          MenuOption          = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          MenuOption->Row     = Row;

+          OriginalRow         = Row;

+          MenuOption->Col     = Col;

+          MenuOption->OptCol  = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;

+

+          if (SubMenu) {

+            if (MenuOption->ThisTag->GrayOut) {

+              gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);

+            } else {

+              if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) {

+                gST->ConOut->SetAttribute (gST->ConOut, SUBTITLE_TEXT | FIELD_BACKGROUND);

+              }

+            }

+

+            Width       = GetWidth (MenuOption->ThisTag, MenuOption->Handle);

+

+            OriginalRow = Row;

+

+            for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {

+              if ((Temp == 0) && (Row <= BottomRow)) {

+                PrintStringAt (Col, Row, OutputString);

+              }

+              //

+              // If there is more string to process print on the next row and increment the Skip value

+              //

+              if (StrLen (&MenuOption->Description[Index])) {

+                if (Temp == 0) {

+                  Row++;

+                }

+              }

+

+              gBS->FreePool (OutputString);

+              if (Temp != 0) {

+                Temp--;

+              }

+            }

+

+            Temp  = 0;

+

+            Row   = OriginalRow;

+

+            gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+            ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);

+

+            if (OptionString != NULL) {

+              //

+              // If leading spaces on OptionString - remove the spaces

+              //

+              for (Index = 0; OptionString[Index] == L' '; Index++) {

+                MenuOption->OptCol++;

+              }

+

+              for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {

+                OptionString[Count] = OptionString[Index];

+                Count++;

+              }

+

+              OptionString[Count] = CHAR_NULL;

+

+              //

+              // If this is a date or time op-code and is used to reflect an RTC, register the op-code

+              //

+                if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||

+                     MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP) &&

+                    (MenuOption->ThisTag->StorageStart >= FileFormTags->FormTags.Tags[0].NvDataSize)) {

+

+                if (gMenuRefreshHead == NULL) {

+                  MenuRefreshEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));

+                  ASSERT (MenuRefreshEntry != NULL);

+                  MenuRefreshEntry->MenuOption        = MenuOption;

+                  MenuRefreshEntry->FileFormTagsHead  = FileFormTagsHead;

+                  MenuRefreshEntry->CurrentColumn     = MenuOption->OptCol;

+                  MenuRefreshEntry->CurrentRow        = MenuOption->Row;

+                  MenuRefreshEntry->CurrentAttribute  = FIELD_TEXT | FIELD_BACKGROUND;

+                  gMenuRefreshHead                    = MenuRefreshEntry;

+                } else {

+                  //

+                  // Advance to the last entry

+                  //

+                  for (MenuRefreshEntry = gMenuRefreshHead;

+                       MenuRefreshEntry->Next != NULL;

+                       MenuRefreshEntry = MenuRefreshEntry->Next

+                      )

+                    ;

+                  MenuRefreshEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));

+                  ASSERT (MenuRefreshEntry->Next != NULL);

+                  MenuRefreshEntry                    = MenuRefreshEntry->Next;

+                  MenuRefreshEntry->MenuOption        = MenuOption;

+                  MenuRefreshEntry->FileFormTagsHead  = FileFormTagsHead;

+                  MenuRefreshEntry->CurrentColumn     = MenuOption->OptCol;

+                  MenuRefreshEntry->CurrentRow        = MenuOption->Row;

+                  MenuRefreshEntry->CurrentAttribute  = FIELD_TEXT | FIELD_BACKGROUND;

+                }

+              }

+

+              Width       = (UINT16) gOptionBlockWidth;

+

+              OriginalRow = Row;

+

+              for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {

+                if ((Temp2 == 0) && (Row <= BottomRow)) {

+                  PrintStringAt (MenuOption->OptCol, Row, OutputString);

+                }

+                //

+                // If there is more string to process print on the next row and increment the Skip value

+                //

+                if (StrLen (&OptionString[Index])) {

+                  if (Temp2 == 0) {

+                    Row++;

+                    //

+                    // Since the Number of lines for this menu entry may or may not be reflected accurately

+                    // since the prompt might be 1 lines and option might be many, and vice versa, we need to do

+                    // some testing to ensure we are keeping this in-sync.

+                    //

+                    // If the difference in rows is greater than or equal to the skip value, increase the skip value

+                    //

+                    if ((Row - OriginalRow) >= MenuOption->Skip) {

+                      MenuOption->Skip++;

+                    }

+                  }

+                }

+

+                gBS->FreePool (OutputString);

+                if (Temp2 != 0) {

+                  Temp2--;

+                }

+              }

+

+              Temp2 = 0;

+              Row   = OriginalRow;

+            }

+            //

+            // If this is a text op with secondary text information

+            //

+            if ((MenuOption->ThisTag->Operand == EFI_IFR_TEXT_OP) && (MenuOption->ThisTag->TextTwo != 0)) {

+              StringPtr   = GetToken (MenuOption->ThisTag->TextTwo, MenuOption->Handle);

+

+              Width       = (UINT16) gOptionBlockWidth;

+

+              OriginalRow = Row;

+

+              for (Index = 0; GetLineByWidth (StringPtr, Width, &Index, &OutputString) != 0x0000;) {

+                if ((Temp == 0) && (Row <= BottomRow)) {

+                  PrintStringAt (MenuOption->OptCol, Row, OutputString);

+                }

+                //

+                // If there is more string to process print on the next row and increment the Skip value

+                //

+                if (StrLen (&StringPtr[Index])) {

+                  if (Temp2 == 0) {

+                    Row++;

+                    //

+                    // Since the Number of lines for this menu entry may or may not be reflected accurately

+                    // since the prompt might be 1 lines and option might be many, and vice versa, we need to do

+                    // some testing to ensure we are keeping this in-sync.

+                    //

+                    // If the difference in rows is greater than or equal to the skip value, increase the skip value

+                    //

+                    if ((Row - OriginalRow) >= MenuOption->Skip) {

+                      MenuOption->Skip++;

+                    }

+                  }

+                }

+

+                gBS->FreePool (OutputString);

+                if (Temp2 != 0) {

+                  Temp2--;

+                }

+              }

+

+              Row = OriginalRow;

+              gBS->FreePool (StringPtr);

+            }

+          } else {

+            //

+            // For now, assume left-justified 72 width max setup entries

+            //

+            PrintStringAt (Col, Row, MenuOption->Description);

+          }

+          //

+          // Tracker 6210 - need to handle the bottom of the display

+          //

+          if (MenuOption->Skip > 1) {

+            Row += MenuOption->Skip - SkipValue;

+            SkipValue = 0;

+          } else {

+            Row += MenuOption->Skip;

+          }

+

+          if (Row > BottomRow) {

+            if (!ValueIsScroll (FALSE, Link)) {

+              gDownArrow = TRUE;

+            }

+

+            Row = BottomRow + 1;

+            break;

+          }

+        }

+

+        if (!ValueIsScroll (TRUE, TopOfScreen)) {

+          gUpArrow = TRUE;

+        }

+

+        if (gUpArrow) {

+          gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);

+          PrintAt (

+            LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,

+            TopRow - SCROLL_ARROW_HEIGHT,

+            (CHAR16 *) L"%c",

+            ARROW_UP

+            );

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+        }

+

+        if (gDownArrow) {

+          gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);

+          PrintAt (

+            LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,

+            BottomRow + SCROLL_ARROW_HEIGHT,

+            (CHAR16 *) L"%c",

+            ARROW_DOWN

+            );

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+        }

+

+        if (SavedMenuOption != NULL) {

+          MenuOption = SavedMenuOption;

+        }

+      }

+      break;

+

+    case CfRefreshHighLight:

+      ControlFlag = CfUpdateHelpString;

+      //

+      // Repaint flag is normally reset when finish processing CfUpdateHelpString. Temporarily

+      // reset Repaint flag because we may break halfway and skip CfUpdateHelpString processing.

+      //

+      SavedValue  = Repaint;

+      Repaint     = FALSE;

+

+      if (NewPos != NULL) {

+        gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);

+        if (SubMenu) {

+          if (gLastOpr && (gEntryNumber != -1)) {

+            MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+            if (gEntryNumber != MenuOption->EntryNumber) {

+              ScreenOperation = UiDown;

+              ControlFlag     = CfScreenOperation;

+              break;

+            } else {

+              gLastOpr = FALSE;

+            }

+          }

+

+          ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+          if (OptionString != NULL) {

+            //

+            // If leading spaces on OptionString - remove the spaces

+            //

+            for (Index = 0; OptionString[Index] == L' '; Index++)

+              ;

+

+            for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {

+              OptionString[Count] = OptionString[Index];

+              Count++;

+            }

+

+            OptionString[Count] = CHAR_NULL;

+

+            Width               = (UINT16) gOptionBlockWidth;

+

+            OriginalRow         = MenuOption->Row;

+

+            for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {

+              if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {

+                PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);

+              }

+              //

+              // If there is more string to process print on the next row and increment the Skip value

+              //

+              if (StrLen (&OptionString[Index])) {

+                MenuOption->Row++;

+              }

+

+              gBS->FreePool (OutputString);

+            }

+

+            MenuOption->Row = OriginalRow;

+          } else {

+            if (NewLine) {

+              if (MenuOption->ThisTag->GrayOut) {

+                gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);

+              } else {

+                if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) {

+                  gST->ConOut->SetAttribute (gST->ConOut, SUBTITLE_TEXT | FIELD_BACKGROUND);

+                }

+              }

+

+              OriginalRow = MenuOption->Row;

+              Width       = GetWidth (MenuOption->ThisTag, MenuOption->Handle);

+

+              for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {

+                if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {

+                  PrintStringAt (Col, MenuOption->Row, OutputString);

+                }

+                //

+                // If there is more string to process print on the next row and increment the Skip value

+                //

+                if (StrLen (&MenuOption->Description[Index])) {

+                  MenuOption->Row++;

+                }

+

+                gBS->FreePool (OutputString);

+              }

+

+              MenuOption->Row = OriginalRow;

+              gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+            }

+          }

+        } else {

+          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+          gST->ConOut->OutputString (gST->ConOut, MenuOption->Description);

+        }

+

+        MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+        if ((gPriorMenuEntry != 0) && (MenuOption->EntryNumber != gPriorMenuEntry) && (NewPos->ForwardLink != &Menu)) {

+          ScreenOperation = UiDown;

+          ControlFlag     = CfScreenOperation;

+          break;

+        } else {

+          gPriorMenuEntry = 0;

+        }

+        //

+        // This is only possible if we entered this page and the first menu option is

+        // a "non-menu" item.  In that case, force it UiDown

+        //

+        if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut) {

+          //

+          // If we previously hit an UP command and we are still sitting on a text operation

+          // we must continue going up

+          //

+          if (ScreenOperation == UiUp) {

+            ControlFlag = CfScreenOperation;

+            break;

+          } else {

+            ScreenOperation = UiDown;

+            ControlFlag     = CfScreenOperation;

+            break;

+          }

+        }

+        //

+        // Set reverse attribute

+        //

+        gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT);

+        gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);

+

+        //

+        // Assuming that we have a refresh linked-list created, lets annotate the

+        // appropriate entry that we are highlighting with its new attribute.  Just prior to this

+        // lets reset all of the entries' attribute so we do not get multiple highlights in he refresh

+        //

+        if (gMenuRefreshHead != NULL) {

+          for (MenuRefreshEntry = gMenuRefreshHead; MenuRefreshEntry != NULL; MenuRefreshEntry = MenuRefreshEntry->Next) {

+            MenuRefreshEntry->CurrentAttribute = FIELD_TEXT | FIELD_BACKGROUND;

+            if (MenuRefreshEntry->MenuOption == MenuOption) {

+              MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT;

+            }

+          }

+        }

+

+        if (SubMenu) {

+          ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);

+          if (OptionString != NULL) {

+            //

+            // If leading spaces on OptionString - remove the spaces

+            //

+            for (Index = 0; OptionString[Index] == L' '; Index++)

+              ;

+

+            for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {

+              OptionString[Count] = OptionString[Index];

+              Count++;

+            }

+

+            OptionString[Count] = CHAR_NULL;

+

+            Width               = (UINT16) gOptionBlockWidth;

+

+            OriginalRow         = MenuOption->Row;

+

+            for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {

+              if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {

+                PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);

+              }

+              //

+              // If there is more string to process print on the next row and increment the Skip value

+              //

+              if (StrLen (&OptionString[Index])) {

+                MenuOption->Row++;

+              }

+

+              gBS->FreePool (OutputString);

+            }

+

+            MenuOption->Row = OriginalRow;

+          } else {

+            if (NewLine) {

+              OriginalRow = MenuOption->Row;

+

+              Width       = GetWidth (MenuOption->ThisTag, MenuOption->Handle);

+

+              for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {

+                if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {

+                  PrintStringAt (Col, MenuOption->Row, OutputString);

+                }

+                //

+                // If there is more string to process print on the next row and increment the Skip value

+                //

+                if (StrLen (&MenuOption->Description[Index])) {

+                  MenuOption->Row++;

+                }

+

+                gBS->FreePool (OutputString);

+              }

+

+              MenuOption->Row = OriginalRow;

+

+            }

+          }

+

+          if (((NewPos->ForwardLink != &Menu) && (ScreenOperation == UiDown)) ||

+              ((NewPos->BackLink != &Menu) && (ScreenOperation == UiUp)) ||

+              (ScreenOperation == UiNoOperation)

+              ) {

+            UpdateKeyHelp (MenuOption, FALSE);

+          }

+        } else {

+          gST->ConOut->OutputString (gST->ConOut, MenuOption->Description);

+        }

+        //

+        // Clear reverse attribute

+        //

+        gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);

+      }

+      //

+      // Repaint flag will be used when process CfUpdateHelpString, so restore its value

+      // if we didn't break halfway when process CfRefreshHighLight.

+      //

+      Repaint = SavedValue;

+      break;

+

+    case CfUpdateHelpString:

+      ControlFlag = CfPrepareToReadKey;

+

+        if (SubMenu && 

+            (Repaint || NewLine || 

+             (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||

+             (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) && 

+            !(gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS)) {

+        //

+        // Don't print anything if it is a NULL help token

+        //

+        if (MenuOption->ThisTag->Help == 0x00000000) {

+          StringPtr = (CHAR16 *) L"\0";

+        } else {

+          StringPtr = GetToken (MenuOption->ThisTag->Help, MenuOption->Handle);

+        }

+

+        ProcessHelpString (StringPtr, &FormattedString, BottomRow - TopRow);

+

+        gST->ConOut->SetAttribute (gST->ConOut, HELP_TEXT | FIELD_BACKGROUND);

+

+        for (Index = 0; Index < BottomRow - TopRow; Index++) {

+          //

+          // Pad String with spaces to simulate a clearing of the previous line

+          //

+          for (; GetStringWidth (&FormattedString[Index * gHelpBlockWidth]) / 2 < gHelpBlockWidth;) {

+            StrCat (&FormattedString[Index * gHelpBlockWidth], (CHAR16 *) L" ");

+          }

+

+          PrintStringAt (

+            LocalScreen.RightColumn - gHelpBlockWidth,

+            Index + TopRow,

+            &FormattedString[Index * gHelpBlockWidth]

+            );

+        }

+      }

+      //

+      // Reset this flag every time we finish using it.

+      //

+      Repaint = FALSE;

+      NewLine = FALSE;

+      break;

+

+    case CfPrepareToReadKey:

+      ControlFlag = CfReadKey;

+

+      for (Index = 0; Index < MenuOption->IfrNumber; Index++) {

+        FileFormTags = FileFormTags->NextFile;

+      }

+

+      ScreenOperation = UiNoOperation;

+

+      Status = gBS->HandleProtocol (

+                      (VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,

+                      &gEfiFormCallbackProtocolGuid,

+                      (VOID **) &FormCallback

+                      );

+

+      break;

+

+    case CfReadKey:

+      ControlFlag     = CfScreenOperation;

+

+      OriginalTimeOut = FrontPageTimeOutValue;

+      do {

+        if (FrontPageTimeOutValue >= 0 && (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) && FrontPageTimeOutValue != (INT16) -1) {

+          //

+          // Remember that if set to 0, must immediately boot an option

+          //

+          if (FrontPageTimeOutValue == 0) {

+            FrontPageTimeOutValue = 0xFFFF;

+            Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+            if (EFI_ERROR (Status)) {

+              Status = EFI_TIMEOUT;

+            }

+            break;

+          }

+

+          Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);

+          if (Status == EFI_TIMEOUT) {

+            EFI_IFR_DATA_ENTRY *DataEntry;

+

+            DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1);

+

+            PageData->EntryCount  = 1;

+            Count                 = (UINT32) ((OriginalTimeOut - FrontPageTimeOutValue) * 100 / OriginalTimeOut);

+            CopyMem (&DataEntry->Data, &Count, sizeof (UINT32));

+

+            if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+              FormCallback->Callback (

+                              FormCallback,

+                              0xFFFF,

+                              (EFI_IFR_DATA_ARRAY *) PageData,

+                              NULL

+                              );

+            }

+            //

+            // Count down 1 second

+            //

+            FrontPageTimeOutValue--;

+

+          } else {

+            ASSERT (!EFI_ERROR (Status));

+            PageData->EntryCount = 0;

+            if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {

+              FormCallback->Callback (

+                              FormCallback,

+                              0xFFFE,

+                              (EFI_IFR_DATA_ARRAY *) PageData,

+                              NULL

+                              );

+            }

+

+            FrontPageTimeOutValue = 0xFFFF;

+          }

+        } else {

+          //

+          // Wait for user's selection, no auto boot

+          //

+          Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);

+        }

+      } while (Status == EFI_TIMEOUT);

+

+      if (gFirstIn) {

+        gFirstIn = FALSE;

+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+        DisableQuietBoot ();

+      }

+

+      if (Status == EFI_TIMEOUT) {

+        Key.UnicodeChar = CHAR_CARRIAGE_RETURN;

+      } else {

+        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+        //

+        // if we encounter error, continue to read another key in.

+        //

+        if (EFI_ERROR (Status)) {

+          ControlFlag = CfReadKey;

+          continue;

+        }

+      }

+

+      switch (Key.UnicodeChar) {

+      case CHAR_CARRIAGE_RETURN:

+        Selection       = MenuOption;

+        ScreenOperation = UiSelect;

+        gDirection      = 0;

+        break;

+

+      //

+      // We will push the adjustment of these numeric values directly to the input handler

+      //

+      case '+':

+      case '-':

+        if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {

+

+          if (Key.UnicodeChar == '+') {

+            gDirection = SCAN_RIGHT;

+          } else {

+            gDirection = SCAN_LEFT;

+          }

+

+          Status = ProcessOptions (MenuOption, TRUE, FileFormTagsHead, NULL, &OptionString);

+        }

+        break;

+

+      case '^':

+        ScreenOperation = UiUp;

+        break;

+

+      case 'V':

+      case 'v':

+        ScreenOperation = UiDown;

+        break;

+

+      case ' ':

+        if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {

+          if (SubMenu) {

+            if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !(MenuOption->ThisTag->GrayOut)) {

+              gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);

+              gST->ConOut->OutputString (gST->ConOut, MenuOption->Description);

+              Selection       = MenuOption;

+              ScreenOperation = UiSelect;

+            }

+          }

+        }

+        break;

+

+      case CHAR_NULL:

+        if (((Key.ScanCode == SCAN_F1) && ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE)) ||

+            ((Key.ScanCode == SCAN_F2) && ((gFunctionKeySetting & FUNCTION_TWO) != FUNCTION_TWO)) ||

+            ((Key.ScanCode == SCAN_F9) && ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE)) ||

+            ((Key.ScanCode == SCAN_F10) && ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN))

+            ) {

+          //

+          // If the function key has been disabled, just ignore the key.

+          //

+        } else {

+          for (Index = 0; Index < sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]); Index++) {

+            if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {

+              if ((Key.ScanCode == SCAN_F9) || (Key.ScanCode == SCAN_F10)) {

+                if (SubMenu) {

+                  ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;

+                }

+              } else {

+                ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;

+              }

+            }

+          }

+        }

+        break;

+      }

+      break;

+

+    case CfScreenOperation:

+      IfrBinary = gBinaryDataHead;

+

+      //

+      // Advance to the Ifr we are using

+      //

+      for (Index = 0; Index < gActiveIfr; Index++) {

+        IfrBinary = IfrBinary->Next;

+      }

+

+      if (ScreenOperation != UiPrevious && ScreenOperation != UiReset) {

+        //

+        // If the screen has no menu items, and the user didn't select UiPrevious, or UiReset

+        // ignore the selection and go back to reading keys.

+        //

+        if (IsListEmpty (&Menu)) {

+          ControlFlag = CfReadKey;

+          break;

+        }

+        //

+        // if there is nothing logical to place a cursor on, just move on to wait for a key.

+        //

+        for (Link = Menu.ForwardLink; Link != &Menu; Link = Link->ForwardLink) {

+          NextMenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          if (!(NextMenuOption->ThisTag->GrayOut) && (NextMenuOption->ThisTag->Operand != EFI_IFR_SUBTITLE_OP)) {

+            break;

+          }

+        }

+

+        if (Link == &Menu) {

+          ControlFlag = CfPrepareToReadKey;

+          break;

+        }

+      }

+

+      for (Index = 0;

+           Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);

+           Index++

+          ) {

+        if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {

+          ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;

+        }

+      }

+

+      break;

+

+    case CfUiPrevious:

+      ControlFlag = CfCheckSelection;

+      //

+      // Check for tags that might have LATE_CHECK enabled.  If they do, we can't switch pages or save NV data.

+      //

+      if (MenuOption != NULL) {

+        if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {

+          Selection = NULL;

+          Repaint   = TRUE;

+          break;

+        }

+      }

+

+      if (IsListEmpty (&gMenuList)) {

+        Selection = NULL;

+        if (IsListEmpty (&Menu)) {

+          ControlFlag = CfReadKey;

+        }

+        break;

+      }

+

+      gLastOpr = TRUE;

+

+      while (gMenuRefreshHead != NULL) {

+        OldMenuRefreshEntry = gMenuRefreshHead->Next;

+

+        gBS->FreePool (gMenuRefreshHead);

+

+        gMenuRefreshHead = OldMenuRefreshEntry;

+      }

+      //

+      // Remove the Cached page entry, free and init the menus, flag Selection as jumping to previous page and a valid Tag

+      //

+      if (SubMenu) {

+        UiRemoveMenuListEntry (MenuOption, &Selection);

+        Selection->Previous = TRUE;

+        UiFreeMenu ();

+        UiInitMenu ();

+      }

+

+      gActiveIfr = Selection->IfrNumber;

+      return Selection;

+

+    case CfUiSelect:

+      ControlFlag = CfCheckSelection;

+

+      ExtractRequestedNvMap (FileFormTags, MenuOption->ThisTag->VariableNumber, &VariableDefinition);

+

+      if (SubMenu) {

+        if ((MenuOption->ThisTag->Operand == EFI_IFR_TEXT_OP && 

+            !(MenuOption->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE)) ||

+            (MenuOption->ThisTag->GrayOut) ||

+            (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||

+            (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {

+            Selection = NULL;

+            break;

+          }

+

+        NewLine = TRUE;

+        UpdateKeyHelp (MenuOption, TRUE);

+        Status = ProcessOptions (MenuOption, TRUE, FileFormTagsHead, PageData, &OptionString);

+

+        if (EFI_ERROR (Status)) {

+          Selection = NULL;

+          Repaint   = TRUE;

+          break;

+        }

+

+        if (OptionString != NULL) {

+          PrintStringAt (LocalScreen.LeftColumn + gPromptBlockWidth + 1, MenuOption->Row, OptionString);

+        }

+

+        if (MenuOption->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE) {

+          Selection = MenuOption;

+        }

+

+        if (Selection == NULL) {

+          break;

+        }

+

+        Location = (UINT8 *) &PageData->EntryCount;

+

+        //

+        // If not a goto, dump single piece of data, otherwise dump everything

+        //

+        if (Selection->ThisTag->Operand == EFI_IFR_REF_OP) {

+          //

+          // Check for tags that might have LATE_CHECK enabled.  If they do, we can't switch pages or save NV data.

+          //

+          if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {

+            Selection = NULL;

+            Repaint   = TRUE;

+            break;

+          }

+

+          UiAddMenuListEntry (Selection);

+          gPriorMenuEntry = 0;

+

+          //

+          // Now that we added a menu entry specific to a goto, we can always go back when someone hits the UiPrevious

+          //

+          UiMenuList                    = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);

+          UiMenuList->FormerEntryNumber = MenuOption->EntryNumber;

+

+          gLastOpr                      = FALSE;

+

+          //

+          // Rewind to the beginning of the menu

+          //

+          for (; NewPos->BackLink != &Menu; NewPos = NewPos->BackLink)

+            ;

+

+          //

+          // Get Total Count of Menu entries

+          //

+          for (Count = 1; NewPos->ForwardLink != &Menu; NewPos = NewPos->ForwardLink) {

+            Count++;

+          }

+          //

+          // Rewind to the beginning of the menu

+          //

+          for (; NewPos->BackLink != &Menu; NewPos = NewPos->BackLink)

+            ;

+

+          //

+          // Copy the number of entries being described to the PageData location

+          //

+          CopyMem (&Location[0], &Count, sizeof (UINT32));

+

+          for (Index = 4; NewPos->ForwardLink != &Menu; Index = Index + MenuOption->ThisTag->StorageWidth + 2) {

+

+            MenuOption          = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+            Location[Index]     = MenuOption->ThisTag->Operand;

+            Location[Index + 1] = (UINT8) (MenuOption->ThisTag->StorageWidth + 4);

+            CopyMem (

+              &Location[Index + 4],

+              &VariableDefinition->NvRamMap[MenuOption->ThisTag->StorageStart],

+              MenuOption->ThisTag->StorageWidth

+              );

+            NewPos = NewPos->ForwardLink;

+          }

+        } else {

+

+          gPriorMenuEntry = MenuOption->EntryNumber;

+

+          Count           = 1;

+

+          //

+          // Copy the number of entries being described to the PageData location

+          //

+          CopyMem (&Location[0], &Count, sizeof (UINT32));

+

+          //

+          // Start at PageData[4] since the EntryCount is a UINT32

+          //

+          Index = 4;

+

+          //

+          // Copy data to destination

+          //

+          Location[Index]     = MenuOption->ThisTag->Operand;

+          Location[Index + 1] = (UINT8) (MenuOption->ThisTag->StorageWidth + 4);

+          CopyMem (

+            &Location[Index + 4],

+            &VariableDefinition->NvRamMap[MenuOption->ThisTag->StorageStart],

+            MenuOption->ThisTag->StorageWidth

+            );

+        }

+      }

+      break;

+

+    case CfUiReset:

+      ControlFlag = CfCheckSelection;

+      gLastOpr    = FALSE;

+      if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {

+        break;

+      }

+      //

+      // If NV flag is up, prompt user

+      //

+      if (gNvUpdateRequired) {

+        Status      = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+

+        YesResponse = gYesResponse[0];

+        NoResponse  = gNoResponse[0];

+

+        do {

+          CreateDialog (3, TRUE, 0, NULL, &Key, gEmptyString, gAreYouSure, gEmptyString);

+        } while

+        (

+          (Key.ScanCode != SCAN_ESC) &&

+          ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&

+          ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))

+        );

+

+        //

+        // If the user hits the YesResponse key

+        //

+        if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {

+        } else {

+          Repaint = TRUE;

+          NewLine = TRUE;

+          break;

+        }

+      }

+      //

+      // Check for tags that might have LATE_CHECK enabled.  If they do, we can't switch pages or save NV data.

+      //

+      if (MenuOption != NULL) {

+        if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {

+          Selection = NULL;

+          Repaint   = TRUE;

+          NewLine   = TRUE;

+          break;

+        }

+      }

+

+      gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

+      gST->ConOut->EnableCursor (gST->ConOut, TRUE);

+

+      if (SubMenu) {

+        UiFreeMenuList ();

+        gST->ConOut->ClearScreen (gST->ConOut);

+        return NULL;

+      }

+

+      UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);

+      UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->Flags, FALSE);

+

+      if (IfrBinary->UnRegisterOnExit) {

+        Hii->RemovePack (Hii, MenuOption->Handle);

+      }

+

+      UiFreeMenu ();

+

+      //

+      // Clean up the allocated data buffers

+      //

+      FreeData (FileFormTagsHead, FormattedString, OptionString);

+

+      gST->ConOut->ClearScreen (gST->ConOut);

+      return NULL;

+

+    case CfUiLeft:

+      ControlFlag = CfCheckSelection;

+      if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {

+        if (MenuOption->Skip == 1) {

+          //

+          // In the tail of the Date/Time op-code set, go left.

+          //

+          NewPos = NewPos->BackLink;

+        } else {

+          //

+          // In the middle of the Data/Time op-code set, go left.

+          //

+          NextMenuOption = CR (NewPos->ForwardLink, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          if (NextMenuOption->Skip == 1) {

+            NewPos = NewPos->BackLink;

+          }

+        }

+      }

+      break;

+

+    case CfUiRight:

+      ControlFlag = CfCheckSelection;

+      if ((MenuOption->Skip == 0) &&

+          ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP))

+          ) {

+        //

+        // We are in the head or middle of the Date/Time op-code set, advance right.

+        //

+        NewPos = NewPos->ForwardLink;

+      }

+      break;

+

+    case CfUiUp:

+      ControlFlag = CfCheckSelection;

+

+      if (NewPos->BackLink != &Menu) {

+        NewLine = TRUE;

+        //

+        // Adjust Date/Time position before we advance forward.

+        //

+        AdjustDateAndTimePosition (TRUE, &NewPos);

+

+        //

+        // Caution that we have already rewind to the top, don't go backward in this situation.

+        //

+        if (NewPos->BackLink != &Menu) {

+          NewPos = NewPos->BackLink;

+        }

+

+        PreviousMenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+        //

+        // Since the behavior of hitting the up arrow on a Date/Time op-code is intended

+        // to be one that back to the previous set of op-codes, we need to advance to the sencond

+        // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate

+        // checking can be done.

+        //

+        DataAndTimeLineNumberPad = AdjustDateAndTimePosition (TRUE, &NewPos);

+

+        if (SubMenu) {

+          //

+          // If the previous MenuOption contains a display-only op-code, skip to the next one

+          //

+          if (PreviousMenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || PreviousMenuOption->ThisTag->GrayOut) {

+            //

+            // This is ok as long as not at the end of the list

+            //

+            if (NewPos->BackLink == &Menu) {

+              //

+              // If we are at the start of the list, then this list must start with a display only

+              // piece of data, so do not allow the backward motion

+              //

+              ScreenOperation = UiDown;

+

+              if (PreviousMenuOption->Row <= TopRow) {

+                if (TopOfScreen->BackLink != &Menu) {

+                  TopOfScreen = TopOfScreen->BackLink;

+                  Repaint     = TRUE;

+                }

+              }

+

+              UpdateStatusBar (INPUT_ERROR, PreviousMenuOption->ThisTag->Flags, FALSE);

+              break;

+            }

+          }

+        }

+        //

+        // Check the previous menu entry to see if it was a zero-length advance.  If it was,

+        // don't worry about a redraw.

+        //

+        if ((MenuOption->Row - PreviousMenuOption->Skip - DataAndTimeLineNumberPad < TopRow) ||

+            (PreviousMenuOption->Skip > MenuOption->Row)

+            ) {

+          do {

+            if (TopOfScreen->BackLink == &Menu) {

+              break;

+            }

+

+            Repaint = TRUE;

+

+            //

+            // Is the current top of screen a zero-advance op-code?

+            // If so, keep moving forward till we hit a >0 advance op-code

+            //

+            SavedMenuOption = CR (TopOfScreen->BackLink, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+            TopOfScreen     = TopOfScreen->BackLink;

+          } while (SavedMenuOption->Skip == 0);

+          //

+          // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.

+          //

+          AdjustDateAndTimePosition (TRUE, &TopOfScreen);

+        }

+

+        UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);

+      } else {

+        if (SubMenu) {

+          SavedMenuOption = MenuOption;

+          MenuOption      = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut) {

+            //

+            // If we are at the end of the list and sitting on a text op, we need to more forward

+            //

+            ScreenOperation = UiDown;

+            ControlFlag     = CfScreenOperation;

+            break;

+          }

+

+          MenuOption = SavedMenuOption;

+        }

+      }

+      break;

+

+    case CfUiPageUp:

+      ControlFlag     = CfCheckSelection;

+

+      SavedListEntry  = NewPos;

+      Link            = TopOfScreen;

+      for (Index = BottomRow; Index >= TopRow + 1; Index -= MenuOption->Skip) {

+        if (Link->BackLink == &Menu) {

+          TopOfScreen = Link;

+          Link        = SavedListEntry;

+          MenuOption  = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          break;

+        }

+

+        NewLine         = TRUE;

+        Repaint         = TRUE;

+        Link            = Link->BackLink;

+        MenuOption      = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+        TopOfScreen     = Link;

+        SavedListEntry  = Link;

+      }

+

+      NewPos = Link;

+

+      //

+      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.

+      // Don't do this when we are already in the first page.

+      //

+      if (Repaint) {

+        AdjustDateAndTimePosition (TRUE, &TopOfScreen);

+        AdjustDateAndTimePosition (TRUE, &NewPos);

+        MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+      }

+      break;

+

+    case CfUiPageDown:

+      ControlFlag     = CfCheckSelection;

+

+      SavedListEntry  = NewPos;

+      Link            = TopOfScreen;

+      NewPos          = TopOfScreen;

+      for (Index = TopRow; Index <= BottomRow - 1; Index += MenuOption->Skip) {

+        if (NewPos->ForwardLink == &Menu) {

+          NewPos      = SavedListEntry;

+          MenuOption  = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          Link        = TopOfScreen;

+          NewLine     = FALSE;

+          Repaint     = FALSE;

+          break;

+        }

+

+        NewLine     = TRUE;

+        Repaint     = TRUE;

+        MenuOption  = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+        NewPos      = NewPos->ForwardLink;

+        Link        = NewPos;

+      }

+

+      TopOfScreen = Link;

+

+      //

+      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.

+      // Don't do this when we are already in the last page.

+      //

+      if (Repaint) {

+        AdjustDateAndTimePosition (TRUE, &TopOfScreen);

+        AdjustDateAndTimePosition (TRUE, &NewPos);

+        MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+      }

+      break;

+

+    case CfUiDown:

+      ControlFlag = CfCheckSelection;

+      //

+      // Since the behavior of hitting the down arrow on a Date/Time op-code is intended

+      // to be one that progresses to the next set of op-codes, we need to advance to the last

+      // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate

+      // checking can be done.  The only other logic we need to introduce is that if a Date/Time

+      // op-code is the last entry in the menu, we need to rewind back to the first op-code of

+      // the Date/Time op-code.

+      //

+      DataAndTimeLineNumberPad = AdjustDateAndTimePosition (FALSE, &NewPos);

+

+      if (NewPos->ForwardLink != &Menu) {

+        NewLine         = TRUE;

+        NewPos          = NewPos->ForwardLink;

+        NextMenuOption  = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+        if (SubMenu) {

+          //

+          // If the next MenuOption contains a display-only op-code, skip to the next one

+          // Also if the next MenuOption is date or time,

+          //

+          if (NextMenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || NextMenuOption->ThisTag->GrayOut) {

+            //

+            // This is ok as long as not at the end of the list

+            //

+            if (NewPos == &Menu) {

+              //

+              // If we are at the end of the list, then this list must end with a display only

+              // piece of data, so do not allow the forward motion

+              //

+              UpdateStatusBar (INPUT_ERROR, NextMenuOption->ThisTag->Flags, FALSE);

+              NewPos          = NewPos->BackLink;

+              ScreenOperation = UiUp;

+              break;

+            }

+          }

+        }

+        //

+        // An option might be multi-line, so we need to reflect that data in the overall skip value

+        //

+        UpdateOptionSkipLines (PageData, NextMenuOption, FileFormTagsHead, &OptionString, SkipValue);

+

+        if (NextMenuOption->Skip > 1) {

+          Temp = MenuOption->Row + MenuOption->Skip + NextMenuOption->Skip - 1;

+        } else {

+          Temp = MenuOption->Row + MenuOption->Skip + DataAndTimeLineNumberPad;

+        }

+        //

+        // If we are going to scroll

+        //

+        if (Temp > BottomRow) {

+          do {

+            //

+            // Is the current top of screen a zero-advance op-code?

+            // If so, keep moving forward till we hit a >0 advance op-code

+            //

+            SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+            //

+            // If bottom op-code is more than one line or top op-code is more than one line

+            //

+            if ((NextMenuOption->Skip > 1) || (MenuOption->Skip > 1)) {

+              //

+              // Is the bottom op-code greater than or equal in size to the top op-code?

+              //

+              if ((Temp - BottomRow) >= (SavedMenuOption->Skip - OldSkipValue)) {

+                //

+                // Skip the top op-code

+                //

+                TopOfScreen     = TopOfScreen->ForwardLink;

+                Difference      = (Temp - BottomRow) - (SavedMenuOption->Skip - OldSkipValue);

+

+                OldSkipValue    = Difference;

+

+                SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+                //

+                // If we have a remainder, skip that many more op-codes until we drain the remainder

+                //

+                for (;

+                     Difference >= (INTN) SavedMenuOption->Skip;

+                     Difference = Difference - (INTN) SavedMenuOption->Skip

+                    ) {

+                  //

+                  // Since the Difference is greater than or equal to this op-code's skip value, skip it

+                  //

+                  TopOfScreen     = TopOfScreen->ForwardLink;

+                  SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+                  if (Difference < (INTN) SavedMenuOption->Skip) {

+                    Difference = SavedMenuOption->Skip - Difference - 1;

+                    break;

+                  } else {

+                    if (Difference == (INTN) SavedMenuOption->Skip) {

+                      TopOfScreen     = TopOfScreen->ForwardLink;

+                      SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+                      Difference      = SavedMenuOption->Skip - Difference;

+                      break;

+                    }

+                  }

+                }

+                //

+                // Since we will act on this op-code in the next routine, and increment the

+                // SkipValue, set the skips to one less than what is required.

+                //

+                SkipValue = Difference - 1;

+

+              } else {

+                //

+                // Since we will act on this op-code in the next routine, and increment the

+                // SkipValue, set the skips to one less than what is required.

+                //

+                SkipValue = OldSkipValue + (Temp - BottomRow) - 1;

+              }

+            } else {

+              if ((OldSkipValue + 1) == (INTN) SavedMenuOption->Skip) {

+                TopOfScreen = TopOfScreen->ForwardLink;

+                break;

+              } else {

+                SkipValue = OldSkipValue;

+              }

+            }

+            //

+            // If the op-code at the top of the screen is more than one line, let's not skip it yet

+            // Let's set a skip flag to smoothly scroll the top of the screen.

+            //

+            if (SavedMenuOption->Skip > 1) {

+              if (SavedMenuOption == NextMenuOption) {

+                SkipValue = 0;

+              } else {

+                SkipValue++;

+              }

+            } else {

+              SkipValue   = 0;

+              TopOfScreen = TopOfScreen->ForwardLink;

+            }

+          } while (SavedMenuOption->Skip == 0);

+

+          Repaint       = TRUE;

+          OldSkipValue  = SkipValue;

+        }

+

+        UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);

+

+      } else {

+        if (SubMenu) {

+          SavedMenuOption = MenuOption;

+          MenuOption      = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+          if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut) {

+            //

+            // If we are at the end of the list and sitting on a text op, we need to more forward

+            //

+            ScreenOperation = UiUp;

+            ControlFlag     = CfScreenOperation;

+            break;

+          }

+

+          MenuOption = SavedMenuOption;

+          //

+          // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.

+          //

+          AdjustDateAndTimePosition (TRUE, &NewPos);

+        }

+      }

+      break;

+

+    case CfUiSave:

+      ControlFlag = CfCheckSelection;

+      //

+      // Check for tags that might have LATE_CHECK enabled.  If they do, we can't switch pages or save NV data.

+      //

+      if (MenuOption != NULL) {

+        if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {

+          Selection = NULL;

+          Repaint   = TRUE;

+          break;

+        }

+      }

+      //

+      // If callbacks are active, and the callback has a Write method, try to use it

+      //

+      if (FileFormTags->VariableDefinitions->VariableName == NULL) {

+        if ((FormCallback != NULL) && (FormCallback->NvWrite != NULL)) {

+          Status = FormCallback->NvWrite (

+                                  FormCallback,

+                                  (CHAR16 *) L"Setup",

+                                  &FileFormTags->FormTags.Tags[0].GuidValue,

+                                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                                  VariableDefinition->VariableSize,

+                                  (VOID *) VariableDefinition->NvRamMap,

+                                  &gResetRequired

+                                  );

+

+        } else {

+          Status = gRT->SetVariable (

+                          (CHAR16 *) L"Setup",

+                          &FileFormTags->FormTags.Tags[0].GuidValue,

+                          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                          VariableDefinition->VariableSize,

+                          (VOID *) VariableDefinition->NvRamMap

+                          );

+        }

+      } else {

+        VariableDefinition = FileFormTags->VariableDefinitions;

+

+        for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {

+          if ((FormCallback != NULL) && (FormCallback->NvWrite != NULL)) {

+            Status = FormCallback->NvWrite (

+                                    FormCallback,

+                                    VariableDefinition->VariableName,

+                                    &VariableDefinition->Guid,

+                                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                                    VariableDefinition->VariableSize,

+                                    (VOID *) VariableDefinition->NvRamMap,

+                                    &gResetRequired

+                                    );

+

+          } else {

+            Status = gRT->SetVariable (

+                            VariableDefinition->VariableName,

+                            &VariableDefinition->Guid,

+                            EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                            VariableDefinition->VariableSize,

+                            (VOID *) VariableDefinition->NvRamMap

+                            );

+          }

+        }

+      }

+

+      UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);

+      UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->Flags, FALSE);

+      break;

+

+    case CfUiDefault:

+      ControlFlag = CfCheckSelection;

+

+      NvMapListHead = NULL;

+

+      Status = Hii->GetDefaultImage (Hii, MenuOption->Handle, EFI_IFR_FLAG_DEFAULT, &NvMapListHead);

+

+      if (!EFI_ERROR (Status)) {

+        ASSERT_EFI_ERROR (NULL != NvMapListHead);

+        

+        NvMapListNode = NvMapListHead;

+        

+        while (NULL != NvMapListNode) {

+          if (FileFormTags->VariableDefinitions->VariableId == NvMapListNode->VariablePack->VariableId) {

+            NvMap     = (VOID *) ((CHAR8 *) NvMapListNode->VariablePack + sizeof (EFI_HII_VARIABLE_PACK) + NvMapListNode->VariablePack->VariableNameLength);

+            NvMapSize = NvMapListNode->VariablePack->Header.Length  - sizeof (EFI_HII_VARIABLE_PACK) - NvMapListNode->VariablePack->VariableNameLength;

+            break;

+            }

+          NvMapListNode = NvMapListNode->NextVariablePack;

+        }

+        

+        //

+        // Free the buffer that was allocated.

+        //

+        gBS->FreePool (FileFormTags->VariableDefinitions->NvRamMap);

+        gBS->FreePool (FileFormTags->VariableDefinitions->FakeNvRamMap);

+        

+        //

+        // Allocate, copy the NvRamMap.

+        //

+        FileFormTags->VariableDefinitions->VariableFakeSize = (UINT16) (FileFormTags->VariableDefinitions->VariableFakeSize - FileFormTags->VariableDefinitions->VariableSize);

+        FileFormTags->VariableDefinitions->VariableSize = (UINT16) NvMapSize;

+        FileFormTags->VariableDefinitions->VariableFakeSize = (UINT16) (FileFormTags->VariableDefinitions->VariableFakeSize + FileFormTags->VariableDefinitions->VariableSize);

+        

+        FileFormTags->VariableDefinitions->NvRamMap = AllocateZeroPool (FileFormTags->VariableDefinitions->VariableSize);

+        FileFormTags->VariableDefinitions->FakeNvRamMap = AllocateZeroPool (NvMapSize + FileFormTags->VariableDefinitions->VariableFakeSize);

+

+        CopyMem (FileFormTags->VariableDefinitions->NvRamMap, NvMap, NvMapSize);

+        gBS->FreePool (NvMapListHead);

+      }

+

+      UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->Flags, TRUE);

+      Repaint = TRUE;

+      //

+      // After the repaint operation, we should refresh the highlight.

+      //

+      NewLine = TRUE;

+      break;

+

+    case CfUiNoOperation:

+      ControlFlag = CfCheckSelection;

+      break;

+

+    case CfExit:

+      while (gMenuRefreshHead != NULL) {

+        OldMenuRefreshEntry = gMenuRefreshHead->Next;

+

+        gBS->FreePool (gMenuRefreshHead);

+

+        gMenuRefreshHead = OldMenuRefreshEntry;

+      }

+

+      gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row + 4);

+      gST->ConOut->EnableCursor (gST->ConOut, TRUE);

+      gST->ConOut->OutputString (gST->ConOut, (CHAR16 *) L"\n");

+

+      gActiveIfr = MenuOption->IfrNumber;

+      return Selection;

+

+    default:

+      break;

+    }

+  }

+}

+

+BOOLEAN

+ValueIsScroll (

+  IN  BOOLEAN                 Direction,

+  IN  LIST_ENTRY              *CurrentPos

+  )

+/*++

+

+Routine Description:

+  Determine if the menu is the last menu that can be selected. 

+

+Arguments:

+  Direction - the scroll direction. False is down. True is up.

+           

+Returns:

+  FALSE -- the menu isn't the last menu that can be selected.

+  TRUE  -- the menu is the last menu that can be selected.

+--*/

+{

+  LIST_ENTRY      *Temp;

+  UI_MENU_OPTION  *MenuOption;

+  MenuOption  = NULL;

+

+  Temp        = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;

+

+  if (Temp == &Menu) {

+    return TRUE;

+  }

+

+  for (; Temp != &Menu; Temp = Direction ? Temp->BackLink : Temp->ForwardLink) {

+    MenuOption = CR (Temp, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+    if (!(MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut)) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+UINTN

+AdjustDateAndTimePosition (

+  IN  BOOLEAN                 DirectionUp,

+  IN  LIST_ENTRY              **CurrentPosition

+  )

+/*++

+Routine Description:

+  Adjust Data and Time tag position accordingly.

+  Data format :      [01/02/2004]      [11:22:33]

+  Line number :        0  0    1         0  0  1

+

+Arguments:

+  Direction - the up or down direction. False is down. True is up.

+  CurrentPos - Current position.

+           

+Returns:

+  Return line number to pad. It is possible that we stand on a zero-advance 

+  data or time opcode, so pad one line when we judge if we are going to scroll outside.

+--*/

+{

+  UINTN           Count;

+  LIST_ENTRY      *NewPosition;

+  UI_MENU_OPTION  *MenuOption;

+  UINTN           PadLineNumber;

+

+  PadLineNumber = 0;

+  NewPosition   = *CurrentPosition;

+  MenuOption    = CR (NewPosition, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+

+  if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {

+    //

+    // Calculate the distance from current position to the last Date/Time op-code.

+    //

+    Count = 0;

+    while (MenuOption->ThisTag->NumberOfLines == 0) {

+      Count++;

+      NewPosition   = NewPosition->ForwardLink;

+      MenuOption    = CR (NewPosition, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);

+      PadLineNumber = 1;

+    }

+

+    NewPosition = *CurrentPosition;

+    if (DirectionUp) {

+      //

+      // Since the behavior of hitting the up arrow on a Date/Time op-code is intended

+      // to be one that back to the previous set of op-codes, we need to advance to the first

+      // Date/Time op-code and leave the remaining logic in CfUiUp intact so the appropriate

+      // checking can be done.

+      //

+      while (Count++ < 2) {

+        NewPosition = NewPosition->BackLink;

+      }

+    } else {

+      //

+      // Since the behavior of hitting the down arrow on a Date/Time op-code is intended

+      // to be one that progresses to the next set of op-codes, we need to advance to the last

+      // Date/Time op-code and leave the remaining logic in CfUiDown intact so the appropriate

+      // checking can be done.

+      //

+      while (Count-- > 0) {

+        NewPosition = NewPosition->ForwardLink;

+      }

+    }

+

+    *CurrentPosition = NewPosition;

+  }

+

+  return PadLineNumber;

+}

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.h b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.h
new file mode 100644
index 0000000..522f4ce
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.h
@@ -0,0 +1,435 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ui.h 

+

+Abstract:

+

+  Head file UI

+

+Revision History

+

+--*/

+

+#ifndef _UI_H

+#define _UI_H

+

+//

+// Globals

+//

+#define REGULAR_NUMERIC 0

+#define TIME_NUMERIC    1

+#define DATE_NUMERIC    2

+

+typedef enum {

+  UiNoOperation,

+  UiDefault,

+  UiSelect,

+  UiUp,

+  UiDown,

+  UiLeft,

+  UiRight,

+  UiReset,

+  UiSave,

+  UiPrevious,

+  UiPageUp,

+  UiPageDown,

+  UiMaxOperation

+} UI_SCREEN_OPERATION;

+

+typedef enum {

+  CfInitialization,

+  CfCheckSelection,

+  CfRepaint,

+  CfRefreshHighLight,

+  CfUpdateHelpString,

+  CfPrepareToReadKey,

+  CfReadKey,

+  CfScreenOperation,

+  CfUiPrevious,

+  CfUiSelect,

+  CfUiReset,

+  CfUiLeft,

+  CfUiRight,

+  CfUiUp,

+  CfUiPageUp,

+  CfUiPageDown,

+  CfUiDown,

+  CfUiSave,

+  CfUiDefault,

+  CfUiNoOperation,

+  CfExit,

+  CfMaxControlFlag

+} UI_CONTROL_FLAG;

+

+#define UI_MENU_OPTION_SIGNATURE  EFI_SIGNATURE_32 ('u', 'i', 'm', 'm')

+#define UI_MENU_LIST_SIGNATURE    EFI_SIGNATURE_32 ('u', 'i', 'm', 'l')

+

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      Link;

+

+  UINTN           Row;

+  UINTN           Col;

+  UINTN           OptCol;

+  CHAR16          *Description;

+  UINTN           Skip;

+

+  UINTN           IfrNumber;

+  VOID            *FormBinary;

+  EFI_HII_HANDLE  Handle;

+  EFI_TAG         *Tags;

+  UINTN           TagIndex;

+  EFI_TAG         *ThisTag;

+  UINT16          FormId;

+  BOOLEAN         Previous;

+  UINT16          EntryNumber;

+  UINT16          Consistency;

+  BOOLEAN         GrayOut;

+} UI_MENU_OPTION;

+

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      MenuLink;

+

+  UI_MENU_OPTION  Selection;

+  UINTN           FormerEntryNumber;

+} UI_MENU_LIST;

+

+typedef struct _MENU_REFRESH_ENTRY {

+  struct _MENU_REFRESH_ENTRY  *Next;

+  EFI_FILE_FORM_TAGS          *FileFormTagsHead;

+  UINTN                       CurrentColumn;

+  UINTN                       CurrentRow;

+  UINTN                       CurrentAttribute;

+  UI_MENU_OPTION              *MenuOption;  // Describes the entry needing an update

+} MENU_REFRESH_ENTRY;

+

+typedef struct {

+  UINT16              ScanCode;

+  UI_SCREEN_OPERATION ScreenOperation;

+} SCAN_CODE_TO_SCREEN_OPERATION;

+

+typedef struct {

+  UI_SCREEN_OPERATION ScreenOperation;

+  UI_CONTROL_FLAG     ControlFlag;

+} SCREEN_OPERATION_T0_CONTROL_FLAG;

+

+LIST_ENTRY          Menu;

+LIST_ENTRY          gMenuList;

+MENU_REFRESH_ENTRY  *gMenuRefreshHead;

+

+INTN                gEntryNumber;

+BOOLEAN             gLastOpr;

+//

+// Global Functions

+//

+VOID

+UiInitMenu (

+  VOID

+  )

+;

+

+VOID

+UiInitMenuList (

+  VOID

+  )

+;

+

+VOID

+UiRemoveMenuListEntry (

+  IN  UI_MENU_OPTION    *Selection,

+  OUT UI_MENU_OPTION    **PreviousSelection

+  )

+;

+

+VOID

+UiFreeMenuList (

+  VOID

+  )

+;

+

+VOID

+UiAddMenuListEntry (

+  IN UI_MENU_OPTION   *Selection

+  )

+;

+

+VOID

+UiFreeMenu (

+  VOID

+  )

+;

+

+VOID

+UiAddMenuOption (

+  IN CHAR16         *String,

+  IN EFI_HII_HANDLE Handle,

+  IN EFI_TAG        *Tag,

+  IN VOID           *FormBinary,

+  IN UINTN          IfrNumber

+  )

+;

+

+VOID

+UiAddSubMenuOption (

+  IN CHAR16           *String,

+  IN EFI_HII_HANDLE   Handle,

+  IN EFI_TAG          *Tag,

+  IN UINTN            TagIndex,

+  IN UINT16           FormId,

+  IN UINT16           MenuItemCount

+  )

+;

+

+UI_MENU_OPTION      *

+UiDisplayMenu (

+  IN  BOOLEAN                      SubMenu,

+  IN  EFI_FILE_FORM_TAGS           *FileFormTagsHead,

+  OUT EFI_IFR_DATA_ARRAY           *PageData

+  )

+;

+

+VOID

+InitPage (

+  VOID

+  )

+;

+

+UI_MENU_OPTION      *

+SetupBrowser (

+  IN  UI_MENU_OPTION              *Selection,

+  IN  BOOLEAN                     Callback,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  UINT8                       *CallbackData

+  )

+;

+

+

+VOID

+SetUnicodeMem (

+  IN VOID   *Buffer,

+  IN UINTN  Size,

+  IN CHAR16 Value

+  )

+;

+

+EFI_STATUS

+UiWaitForSingleEvent (

+  IN EFI_EVENT                Event,

+  IN UINT64                   Timeout OPTIONAL

+  )

+;

+

+VOID

+CreatePopUp (

+  IN  UINTN                       ScreenWidth,

+  IN  UINTN                       NumberOfLines,

+  IN  CHAR16                      *ArrayOfStrings,

+  ...

+  )

+;

+

+EFI_STATUS

+ReadString (

+  IN  UI_MENU_OPTION              *MenuOption,

+  OUT CHAR16                      *StringPtr

+  )

+;

+

+EFI_STATUS

+ReadPassword (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  BOOLEAN                     PromptForPassword,

+  IN  EFI_TAG                     *Tag,

+  IN  EFI_IFR_DATA_ARRAY          *PageData,

+  IN  BOOLEAN                     SecondEntry,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  OUT CHAR16                      *StringPtr

+  )

+;

+

+VOID

+EncodePassword (

+  IN  CHAR16                      *Password,

+  IN  UINT8                       MaxSize

+  )

+;

+

+EFI_STATUS

+GetSelectionInputPopUp (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  EFI_TAG                     *Tag,

+  IN  UINTN                       ValueCount,

+  OUT UINT16                      *Value,

+  OUT UINT16                      *KeyValue

+  )

+;

+

+EFI_STATUS

+GetSelectionInputLeftRight (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  EFI_TAG                     *Tag,

+  IN  UINTN                       ValueCount,

+  OUT UINT16                      *Value

+  )

+;

+

+EFI_STATUS

+GetNumericInput (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  BOOLEAN                     ManualInput,

+  IN  EFI_TAG                     *Tag,

+  IN  UINTN                       NumericType,

+  OUT UINT16                      *Value

+  )

+;

+

+VOID

+UpdateStatusBar (

+  IN  UINTN                       MessageType,

+  IN  UINT8                       Flags,

+  IN  BOOLEAN                     State

+  )

+;

+

+EFI_STATUS

+ProcessOptions (

+  IN  UI_MENU_OPTION              *MenuOption,

+  IN  BOOLEAN                     Selected,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,

+  IN  EFI_IFR_DATA_ARRAY          *PageData,

+  OUT CHAR16                      **OptionString

+  )

+;

+

+VOID

+ProcessHelpString (

+  IN  CHAR16                      *StringPtr,

+  OUT CHAR16                      **FormattedString,

+  IN  UINTN                       RowCount

+  )

+;

+

+VOID

+UpdateKeyHelp (

+  IN  UI_MENU_OPTION              *Selection,

+  IN  BOOLEAN                     Selected

+  )

+;

+

+BOOLEAN

+ValueIsNotValid (

+  IN  BOOLEAN                     Complex,

+  IN  UINT16                      Value,

+  IN  EFI_TAG                     *Tag,

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  STRING_REF                  *PopUp

+  )

+;

+

+VOID

+FreeData (

+  IN EFI_FILE_FORM_TAGS            *FileFormTagsHead,

+  IN CHAR16                        *FormattedString,

+  IN CHAR16                        *OptionString

+  )

+;

+

+VOID

+ClearLines (

+  UINTN                                       LeftColumn,

+  UINTN                                       RightColumn,

+  UINTN                                       TopRow,

+  UINTN                                       BottomRow,

+  UINTN                                       TextAttribute

+  )

+;

+

+UINTN

+GetStringWidth (

+  CHAR16                                      *String

+  )

+;

+

+UINT16

+GetLineByWidth (

+  IN      CHAR16                      *InputString,

+  IN      UINT16                      LineWidth,

+  IN OUT  UINTN                       *Index,

+  OUT     CHAR16                      **OutputString

+  )

+;

+

+UINT16

+GetWidth (

+  IN EFI_TAG                          *Tag,

+  IN EFI_HII_HANDLE                   Handle

+  )

+;

+

+VOID

+NewStrCat (

+  CHAR16                                      *Destination,

+  CHAR16                                      *Source

+  )

+;

+

+VOID

+IfrToFormTag (

+  IN  UINT8               OpCode,

+  IN  EFI_TAG             *TargetTag,

+  IN  VOID                *FormData,

+  EFI_VARIABLE_DEFINITION *VariableDefinitionsHead

+  )

+;

+

+EFI_STATUS

+ExtractNvValue (

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  UINT16                      VariableId,

+  IN  UINT16                      VariableSize,

+  IN  UINT16                      OffsetValue,

+  OUT VOID                        **Buffer

+  )

+;

+

+EFI_STATUS

+ExtractRequestedNvMap (

+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,

+  IN  UINT16                      VariableId,

+  OUT EFI_VARIABLE_DEFINITION     **VariableDefinition

+  )

+;

+

+BOOLEAN

+ValueIsScroll (

+  IN  BOOLEAN                 Direction,

+  IN  LIST_ENTRY              *CurrentPos

+  )

+;

+

+UINTN

+AdjustDateAndTimePosition (

+  IN  BOOLEAN                 DirectionUp,

+  IN  LIST_ENTRY              **CurrentPosition

+  )

+;

+

+EFI_STATUS

+WaitForKeyStroke (

+  OUT  EFI_INPUT_KEY           *Key

+  )

+;

+#endif // _UI_H

diff --git a/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/build.xml b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/build.xml
new file mode 100644
index 0000000..8e3b5c5
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="SetupBrowser"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/UserInterface/SetupBrowser/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="SetupBrowser">

+      <GenBuild baseName="SetupBrowser" mbdFilename="${MODULE_DIR}/SetupBrowser.mbd" msaFilename="${MODULE_DIR}/SetupBrowser.msa"/>

+   </target>

+   <target depends="SetupBrowser_clean" name="clean"/>

+   <target depends="SetupBrowser_cleanall" name="cleanall"/>

+   <target name="SetupBrowser_clean">

+      <OutputDirSetup baseName="SetupBrowser" mbdFilename="${MODULE_DIR}/SetupBrowser.mbd" msaFilename="${MODULE_DIR}/SetupBrowser.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/SetupBrowser_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/SetupBrowser_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="SetupBrowser_cleanall">

+      <OutputDirSetup baseName="SetupBrowser" mbdFilename="${MODULE_DIR}/SetupBrowser.mbd" msaFilename="${MODULE_DIR}/SetupBrowser.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/SetupBrowser_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/SetupBrowser_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**SetupBrowser*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Ia32/VarMachine.h b/edk2/EdkModulePkg/Universal/Variable/Pei/Ia32/VarMachine.h
new file mode 100644
index 0000000..83031e9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Ia32/VarMachine.h
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  VarMachine.h

+  

+Abstract:

+

+  Variable Machine Type

+

+--*/

+

+#ifndef _VAR_MACHINE_H

+#define _VAR_MACHINE_H

+

+#define ALIGNMENT 1

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Ipf/VarMachine.h b/edk2/EdkModulePkg/Universal/Variable/Pei/Ipf/VarMachine.h
new file mode 100644
index 0000000..c5b5753
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Ipf/VarMachine.h
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  VarMachine.h

+  

+Abstract:

+

+  Variable Machine Type

+

+--*/

+

+#ifndef _VAR_MACHINE_H

+#define _VAR_MACHINE_H

+

+#define ALIGNMENT 8

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.c b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.c
new file mode 100644
index 0000000..b2286c1
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.c
@@ -0,0 +1,563 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.c

+

+Abstract:

+

+  Framework PEIM to provide the Variable functionality

+

+--*/

+

+

+#include <Ppi/ReadOnlyVariable.h>

+#include <Variable.h>

+#include <Library/BaseLib.h>

+

+//

+// Module globals

+//

+static EFI_PEI_READ_ONLY_VARIABLE_PPI mVariablePpi = {

+  PeiGetVariable,

+  PeiGetNextVariableName

+};

+

+static EFI_PEI_PPI_DESCRIPTOR     mPpiListVariable = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiPeiReadOnlyVariablePpiGuid,

+  &mVariablePpi

+};

+

+EFI_GUID gEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;

+

+EFI_STATUS

+EFIAPI

+PeimInitializeVariableServices (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Provide the functionality of the variable services.

+

+Arguments:

+  

+  FfsHeadher  - The FFS file header

+  PeiServices - General purpose services available to every PEIM.

+

+Returns:

+

+  Status -  EFI_SUCCESS if the interface could be successfully

+            installed

+

+--*/

+{

+  //

+  // Publish the variable capability to other modules

+  //

+  return (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable);

+

+}

+

+VARIABLE_HEADER *

+GetNextVariablePtr (

+  IN VARIABLE_HEADER  *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code checks if variable header is valid or not.

+

+Arguments:

+  Variable       Pointer to the Variable Header.

+

+Returns:

+  TRUE            Variable header is valid.

+  FALSE           Variable header is not valid.

+

+--*/

+{

+  return (VARIABLE_HEADER *) ((UINTN) GET_VARIABLE_DATA_PTR (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));

+}

+

+BOOLEAN

+EFIAPI

+IsValidVariableHeader (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code checks if variable header is valid or not.

+

+Arguments:

+  Variable              Pointer to the Variable Header.

+

+Returns:

+  TRUE            Variable header is valid.

+  FALSE           Variable header is not valid.

+

+--*/

+{

+  if (Variable == NULL ||

+      Variable->StartId != VARIABLE_DATA ||

+      (sizeof (VARIABLE_HEADER) + Variable->DataSize + Variable->NameSize) > MAX_VARIABLE_SIZE

+      ) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+VARIABLE_STORE_STATUS

+EFIAPI

+GetVariableStoreStatus (

+  IN VARIABLE_STORE_HEADER *VarStoreHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the variable name.

+

+Arguments:

+

+  VarStoreHeader  Pointer to the Variable Store Header.

+

+Returns:

+

+  EfiRaw        Variable store is raw

+  EfiValid      Variable store is valid

+  EfiInvalid    Variable store is invalid

+

+--*/

+{

+  if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&

+      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&

+      VarStoreHeader->State == VARIABLE_STORE_HEALTHY

+      ) {

+

+    return EfiValid;

+  }

+

+  if (VarStoreHeader->Signature == 0xffffffff &&

+      VarStoreHeader->Size == 0xffffffff &&

+      VarStoreHeader->Format == 0xff &&

+      VarStoreHeader->State == 0xff

+      ) {

+

+    return EfiRaw;

+  } else {

+    return EfiInvalid;

+  }

+}

+

+EFI_STATUS

+CompareWithValidVariable (

+  IN  VARIABLE_HEADER         *Variable,

+  IN  CHAR16                  *VariableName,

+  IN  EFI_GUID                *VendorGuid,

+  OUT VARIABLE_POINTER_TRACK  *PtrTrack

+  )

+/*++

+

+Routine Description:

+

+  This function compares a variable with variable entries in database

+

+Arguments:

+

+  Variable       - Pointer to the variable in our database

+  VariableName   - Name of the variable to compare to 'Variable'

+  VendorGuid     - GUID of the variable to compare to 'Variable'

+  PtrTrack       - Variable Track Pointer structure that contains

+                   Variable Information.

+

+Returns:

+

+  EFI_SUCCESS    - Found match variable

+  EFI_NOT_FOUND  - Variable not found

+ 

+--*/

+{

+  if (VariableName[0] == 0) {

+    PtrTrack->CurrPtr = Variable;

+    return EFI_SUCCESS;

+  } else {

+    //

+    // Don't use CompareGuid function here for performance reasons.

+    // Instead we compare the GUID a UINT32 at a time and branch

+    // on the first failed comparison.

+    //

+    if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&

+        (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&

+        (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&

+        (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])

+        ) {

+      if (!StrCmp (VariableName, GET_VARIABLE_NAME_PTR (Variable))) {

+        PtrTrack->CurrPtr = Variable;

+        return EFI_SUCCESS;

+      }

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+FindVariable (

+  IN EFI_PEI_SERVICES         **PeiServices,

+  IN  CHAR16                  *VariableName,

+  IN  EFI_GUID                *VendorGuid,

+  OUT VARIABLE_POINTER_TRACK  *PtrTrack

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Non-Volatile)

+

+Arguments:

+

+  PeiServices    - General purpose services available to every PEIM.

+  VariableName   - Name of the variable to be found

+  VendorGuid     - Vendor GUID to be found.

+  PtrTrack       - Variable Track Pointer structure that contains

+                   Variable Information.

+

+Returns:

+

+  EFI_SUCCESS      - Variable found successfully

+  EFI_NOT_FOUND    - Variable not found

+  EFI_INVALID_PARAMETER  - Invalid variable name

+

+--*/

+{

+  PEI_FLASH_MAP_PPI       *FlashMapPpi;

+  EFI_FLASH_SUBAREA_ENTRY *VariableStoreEntry;

+  UINT32                  NumEntries;

+  EFI_HOB_GUID_TYPE       *GuidHob;

+  VARIABLE_STORE_HEADER   *VariableStoreHeader;

+  VARIABLE_HEADER         *Variable;

+

+  EFI_STATUS              Status;

+

+  VARIABLE_HEADER         *MaxIndex;

+  VARIABLE_INDEX_TABLE    *IndexTable;

+  UINT32                  Count;

+

+  if (VariableName != 0 && VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // No Variable Address equals zero, so 0 as initial value is safe.

+  //

+  MaxIndex = 0;

+  

+  GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid);

+  if (GuidHob == NULL) {

+    IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));

+    IndexTable->Length      = 0;

+    IndexTable->StartPtr    = NULL;

+    IndexTable->EndPtr      = NULL;

+    IndexTable->GoneThrough = 0;

+  } else {

+    IndexTable = GET_GUID_HOB_DATA (GuidHob);

+    for (Count = 0; Count < IndexTable->Length; Count++)

+    {

+#if ALIGNMENT <= 1

+      MaxIndex = (VARIABLE_HEADER *) (UINTN) (IndexTable->Index[Count] + ((UINTN) IndexTable->StartPtr & 0xFFFF0000));

+#else

+#if ALIGNMENT >= 4

+          MaxIndex = (VARIABLE_HEADER *) (UINTN) ((((UINT32)IndexTable->Index[Count]) << 2) + ((UINT32)(UINTN)IndexTable->StartPtr & 0xFFFC0000) );       

+#endif

+#endif

+      if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {

+        PtrTrack->StartPtr  = IndexTable->StartPtr;

+        PtrTrack->EndPtr    = IndexTable->EndPtr;

+

+        return EFI_SUCCESS;

+      }

+    }

+

+    if (IndexTable->GoneThrough) {

+      return EFI_NOT_FOUND;

+    }

+  }

+  //

+  // If not found in HOB, then let's start from the MaxIndex we've found.

+  //

+  if (MaxIndex != NULL) {

+    Variable = GetNextVariablePtr (MaxIndex);

+  } else {

+    if (IndexTable->StartPtr || IndexTable->EndPtr) {

+      Variable = IndexTable->StartPtr;

+    } else {

+      //

+      // Locate FlashMap PPI

+      //

+      Status = (**PeiServices).LocatePpi (

+                                PeiServices,

+                                &gPeiFlashMapPpiGuid,

+                                0,

+                                NULL,

+                                (VOID **) &FlashMapPpi

+                                );

+      ASSERT_EFI_ERROR (Status);

+

+      //

+      // Get flash area info for variables

+      //

+      Status = FlashMapPpi->GetAreaInfo (

+                              PeiServices,

+                              FlashMapPpi,

+                              EFI_FLASH_AREA_EFI_VARIABLES,

+                              NULL,

+                              &NumEntries,

+                              &VariableStoreEntry

+                              );

+

+      //

+      //  Currently only one non-volatile variable store is supported

+      //

+      if (NumEntries != 1) {

+        return EFI_UNSUPPORTED;

+      }

+

+      VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) (VariableStoreEntry->Base);

+

+      if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {

+        return EFI_UNSUPPORTED;

+      }

+

+      if (~VariableStoreHeader->Size == 0) {

+        return EFI_NOT_FOUND;

+      }

+      //

+      // Find the variable by walk through non-volatile variable store

+      //

+      IndexTable->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader + 1);

+      IndexTable->EndPtr    = (VARIABLE_HEADER *) ((UINTN) VariableStoreHeader + VariableStoreHeader->Size);

+

+      //

+      // Start Pointers for the variable.

+      // Actual Data Pointer where data can be written.

+      //

+      Variable = IndexTable->StartPtr;

+    }

+  }

+  //

+  // Find the variable by walk through non-volatile variable store

+  //

+  PtrTrack->StartPtr  = IndexTable->StartPtr;

+  PtrTrack->EndPtr    = IndexTable->EndPtr;

+

+  while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {

+    if (Variable->State == VAR_ADDED) {

+      //

+      // Record Variable in VariableIndex HOB

+      //

+      if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME)

+      {

+#if ALIGNMENT <= 1

+        IndexTable->Index[IndexTable->Length++] = (UINT16) (UINTN) Variable;

+#else

+#if ALIGNMENT >= 4

+            IndexTable->Index[IndexTable->Length++] = (UINT16) (((UINT32)(UINTN) Variable) >> 2);

+#endif

+#endif

+      }

+

+      if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {

+        return EFI_SUCCESS;

+      }

+    }

+

+    Variable = GetNextVariablePtr (Variable);

+  }

+  //

+  // If gone through the VariableStore, that means we never find in Firmware any more.

+  //

+  if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {

+    IndexTable->GoneThrough = 1;

+  }

+

+  PtrTrack->CurrPtr = NULL;

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+PeiGetVariable (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     * VendorGuid,

+  OUT UINT32                      *Attributes OPTIONAL,

+  IN OUT UINTN                    *DataSize,

+  OUT VOID                        *Data

+  )

+/*++

+

+Routine Description:

+

+  Provide the read variable functionality of the variable services.

+

+Arguments:

+

+  PeiServices - General purpose services available to every PEIM.

+

+  VariableName     - The variable name

+

+  VendorGuid       - The vendor's GUID

+

+  Attributes       - Pointer to the attribute

+

+  DataSize         - Size of data

+

+  Data             - Pointer to data

+

+Returns:

+

+  EFI_SUCCESS           - The interface could be successfully installed

+

+  EFI_NOT_FOUND         - The variable could not be discovered

+

+  EFI_BUFFER_TOO_SMALL  - The caller buffer is not large enough

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarDataSize;

+  EFI_STATUS              Status;

+

+  if (VariableName == NULL || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find existing variable

+  //

+  Status = FindVariable (PeiServices, VariableName, VendorGuid, &Variable);

+

+  if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {

+    return Status;

+  }

+  //

+  // Get data size

+  //

+  VarDataSize = Variable.CurrPtr->DataSize;

+  if (*DataSize >= VarDataSize) {

+    (*PeiServices)->CopyMem (Data, GET_VARIABLE_DATA_PTR (Variable.CurrPtr), VarDataSize);

+

+    if (Attributes != NULL) {

+      *Attributes = Variable.CurrPtr->Attributes;

+    }

+

+    *DataSize = VarDataSize;

+    return EFI_SUCCESS;

+  } else {

+    *DataSize = VarDataSize;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+PeiGetNextVariableName (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  )

+/*++

+

+Routine Description:

+

+  Provide the get next variable functionality of the variable services.

+

+Arguments:

+

+  PeiServices        - General purpose services available to every PEIM.

+  VariabvleNameSize  - The variable name's size.

+  VariableName       - A pointer to the variable's name.

+  VendorGuid         - A pointer to the EFI_GUID structure.

+

+  VariableNameSize - Size of the variable name

+

+  VariableName     - The variable name

+

+  VendorGuid       - The vendor's GUID

+

+Returns:

+

+  EFI_SUCCESS - The interface could be successfully installed

+

+  EFI_NOT_FOUND - The variable could not be discovered

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarNameSize;

+  EFI_STATUS              Status;

+

+  if (VariableName == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (PeiServices, VariableName, VendorGuid, &Variable);

+

+  if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {

+    return Status;

+  }

+

+  if (VariableName[0] != 0) {

+    //

+    // If variable name is not NULL, get next variable

+    //

+    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);

+  }

+

+  while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {

+    if (IsValidVariableHeader (Variable.CurrPtr)) {

+      if (Variable.CurrPtr->State == VAR_ADDED) {

+        VarNameSize = (UINTN) Variable.CurrPtr->NameSize;

+        if (VarNameSize <= *VariableNameSize) {

+          (*PeiServices)->CopyMem (VariableName, GET_VARIABLE_NAME_PTR (Variable.CurrPtr), VarNameSize);

+

+          (*PeiServices)->CopyMem (VendorGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));

+

+          Status = EFI_SUCCESS;

+        } else {

+          Status = EFI_BUFFER_TOO_SMALL;

+        }

+

+        *VariableNameSize = VarNameSize;

+        return Status;

+        //

+        // Variable is found

+        //

+      } else {

+        Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);

+      }

+    } else {

+      break;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.dxs b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.dxs
new file mode 100644
index 0000000..d16ad10
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.dxs

+

+Abstract:

+

+  Dependency expression file for Variable PEIM.

+

+--*/  

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+  PEI_FLASH_MAP_PPI_GUID

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.h b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.h
new file mode 100644
index 0000000..2a6f861
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.h
@@ -0,0 +1,154 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.h

+   

+Abstract:

+

+  Tiano PEIM to provide the variable functionality

+

+--*/

+

+#ifndef _PEI_VARIABLE_H

+#define _PEI_VARIABLE_H

+

+//

+// BugBug: We need relcate the head file.

+// 

+#include <Common/Variable.h>

+

+#define ALIGNMENT 1

+

+//

+// Define GET_PAD_SIZE to optimize compiler

+//

+#if ((ALIGNMENT == 0) || (ALIGNMENT == 1))

+#define GET_PAD_SIZE(a) (0)

+#else

+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))

+#endif

+

+#define GET_VARIABLE_NAME_PTR(a)  (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))

+

+#define GET_VARIABLE_DATA_PTR(a) \

+  (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (a) + (a)->NameSize + GET_PAD_SIZE ((a)->NameSize))

+

+typedef struct {

+  VARIABLE_HEADER *CurrPtr;

+  VARIABLE_HEADER *EndPtr;

+  VARIABLE_HEADER *StartPtr;

+} VARIABLE_POINTER_TRACK;

+

+#define VARIABLE_INDEX_TABLE_VOLUME 122

+

+#define EFI_VARIABLE_INDEX_TABLE_GUID \

+  { 0x8cfdb8c8, 0xd6b2, 0x40f3, { 0x8e, 0x97, 0x02, 0x30, 0x7c, 0xc9, 0x8b, 0x7c } }

+

+typedef struct {

+  UINT16          Length;

+  UINT16          GoneThrough;

+  VARIABLE_HEADER *EndPtr;

+  VARIABLE_HEADER *StartPtr;

+  UINT16          Index[VARIABLE_INDEX_TABLE_VOLUME];

+} VARIABLE_INDEX_TABLE;

+

+extern EFI_GUID gEfiVariableIndexTableGuid;

+

+//

+// Functions

+//

+EFI_STATUS

+EFIAPI

+PeimInitializeVariableServices (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  FfsHeader   - TODO: add argument description

+  PeiServices - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiGetVariable (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     * VendorGuid,

+  OUT UINT32                      *Attributes OPTIONAL,

+  IN OUT UINTN                    *DataSize,

+  OUT VOID                        *Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PeiServices   - TODO: add argument description

+  VariableName  - TODO: add argument description

+  VendorGuid    - TODO: add argument description

+  Attributes    - TODO: add argument description

+  DataSize      - TODO: add argument description

+  Data          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+PeiGetNextVariableName (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PeiServices       - TODO: add argument description

+  VariableNameSize  - TODO: add argument description

+  VariableName      - TODO: add argument description

+  VendorGuid        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif // _PEI_VARIABLE_H

diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.mbd b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.mbd
new file mode 100644
index 0000000..df87f46
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+  <MbdHeader>
+    <BaseName>PeiVariable</BaseName>
+    <Guid>34C8C28F-B61C-45a2-8F2E-89E46BECC63B</Guid>
+    <Version>0</Version>
+    <Description>FIX ME!</Description>
+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+    <License>
+      All rights reserved. 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.
+    </License>
+    <Created>2006-03-12 17:09</Created>
+    <Modified>2006-03-19 15:19</Modified>
+  </MbdHeader>
+  <Libraries>
+    <Library>PeiReportStatusCodeLib</Library>
+    <Library>BaseDebugLibReportStatusCode</Library>
+    <Library>BaseLib</Library>
+    <Library>PeiMemoryLib</Library>
+    <Library>PeiCoreLib</Library>
+    <Library OverrideID="4444">PeiServicesTablePointerLib</Library>
+    <Library>PeiHobLib</Library>
+    <Library>PeimEntryPoint</Library>
+  </Libraries>
+  <BuildOptions ToolChain="MSFT">
+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+  </BuildOptions>
+</ModuleBuildDescription>
diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.msa b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.msa
new file mode 100644
index 0000000..bf33125
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/Variable.msa
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PeiVariable</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>34C8C28F-B61C-45a2-8F2E-89E46BECC63B</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Variable.c</Filename>

+    <Filename>Variable.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">FlashMap</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">ReadOnlyVariable</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimInitializeVariableServices</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/build.xml b/edk2/EdkModulePkg/Universal/Variable/Pei/build.xml
new file mode 100644
index 0000000..95255e7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiVariable"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Variable/Pei"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiVariable">

+      <GenBuild baseName="PeiVariable" mbdFilename="${MODULE_DIR}/Variable.mbd" msaFilename="${MODULE_DIR}/Variable.msa"/>

+   </target>

+   <target depends="PeiVariable_clean" name="clean"/>

+   <target depends="PeiVariable_cleanall" name="cleanall"/>

+   <target name="PeiVariable_clean">

+      <OutputDirSetup baseName="PeiVariable" mbdFilename="${MODULE_DIR}/Variable.mbd" msaFilename="${MODULE_DIR}/Variable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiVariable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiVariable_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiVariable_cleanall">

+      <OutputDirSetup baseName="PeiVariable" mbdFilename="${MODULE_DIR}/Variable.mbd" msaFilename="${MODULE_DIR}/Variable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiVariable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiVariable_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiVariable*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/Pei/x64/VarMachine.h b/edk2/EdkModulePkg/Universal/Variable/Pei/x64/VarMachine.h
new file mode 100644
index 0000000..83031e9
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/Pei/x64/VarMachine.h
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  VarMachine.h

+  

+Abstract:

+

+  Variable Machine Type

+

+--*/

+

+#ifndef _VAR_MACHINE_H

+#define _VAR_MACHINE_H

+

+#define ALIGNMENT 1

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.c b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.c
new file mode 100644
index 0000000..beb404f
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.c
@@ -0,0 +1,754 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    EmuVariable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;

+

+UINT32

+EFIAPI

+ArrayLength (

+  IN CHAR16 *String

+  )

+/*++

+

+Routine Description:

+

+  Determine the length of null terminated char16 array.

+

+Arguments:

+

+  String    Null-terminated CHAR16 array pointer.

+

+Returns:

+

+  UINT32    Number of bytes in the string, including the double NULL at the end;

+

+--*/

+{

+  UINT32  Count;

+

+  if (NULL == String) {

+    return 0;

+  }

+

+  Count = 0;

+

+  while (0 != String[Count]) {

+    Count++;

+  }

+

+  return (Count * 2) + 2;

+}

+

+UINTN

+EFIAPI

+GetPadSize (

+  IN UINTN Value

+  )

+/*++

+

+Routine Description:

+

+  This function return the pad size for alignment

+

+Arguments:

+

+  Value  The value need to align

+

+Returns:

+

+  Pad size for value

+

+--*/

+{

+  //

+  // If alignment is 0 or 1, means no alignment required

+  //

+  if (ALIGNMENT == 0 || ALIGNMENT == 1) {

+    return 0;

+  }

+

+  return ALIGNMENT - (Value % ALIGNMENT);

+}

+

+VARIABLE_STORE_STATUS

+EFIAPI

+GetVariableStoreStatus (

+  IN VARIABLE_STORE_HEADER *VarStoreHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the variable name.

+

+Arguments:

+

+  VarStoreHeader  Pointer to the Variable Store Header.

+

+Returns:

+

+  EfiHealthy    Variable store is healthy

+  EfiRaw        Variable store is raw

+  EfiInvalid    Variable store is invalid

+

+--*/

+{

+  if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&

+      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&

+      VarStoreHeader->State == VARIABLE_STORE_HEALTHY

+      ) {

+

+    return EfiValid;

+  } else if (VarStoreHeader->Signature == 0xffffffff &&

+           VarStoreHeader->Size == 0xffffffff &&

+           VarStoreHeader->Format == 0xff &&

+           VarStoreHeader->State == 0xff

+          ) {

+

+    return EfiRaw;

+  } else {

+    return EfiInvalid;

+  }

+}

+

+UINT8 *

+EFIAPI

+GetVariableDataPtr (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the variable data.

+

+Arguments:

+

+  Variable            Pointer to the Variable Header.

+

+Returns:

+

+  UINT8*              Pointer to Variable Data

+

+--*/

+{

+  if (Variable->StartId != VARIABLE_DATA) {

+    return NULL;

+  }

+  //

+  // Be careful about pad size for alignment

+  //

+  return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GetPadSize (Variable->NameSize));

+}

+

+VARIABLE_HEADER *

+EFIAPI

+GetNextVariablePtr (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the next variable header.

+

+Arguments:

+

+  Variable                  Pointer to the Variable Header.

+

+Returns:

+

+  VARIABLE_HEADER*      Pointer to next variable header.

+

+--*/

+{

+  VARIABLE_HEADER *VarHeader;

+

+  if (Variable->StartId != VARIABLE_DATA) {

+    return NULL;

+  }

+  //

+  // Be careful about pad size for alignment

+  //

+  VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));

+

+  if (VarHeader->StartId != VARIABLE_DATA ||

+      (sizeof (VARIABLE_HEADER) + VarHeader->DataSize + VarHeader->NameSize) > MAX_VARIABLE_SIZE

+      ) {

+    return NULL;

+  }

+

+  return VarHeader;

+}

+

+VARIABLE_HEADER *

+EFIAPI

+GetEndPointer (

+  IN VARIABLE_STORE_HEADER       *VolHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the last variable memory pointer byte

+

+Arguments:

+

+  Variable                  Pointer to the Variable Header.

+

+Returns:

+

+  VARIABLE_HEADER*      Pointer to last unavailable Variable Header

+

+--*/

+{

+  //

+  // The end of variable store

+  //

+  return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size);

+}

+

+EFI_STATUS

+EFIAPI

+FindVariable (

+  IN  CHAR16                  *VariableName,

+  IN  EFI_GUID                *VendorGuid,

+  OUT VARIABLE_POINTER_TRACK  *PtrTrack,

+  IN  VARIABLE_GLOBAL         *Global

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                Name of the variable to be found

+  VendorGuid                  Vendor GUID to be found.

+  PtrTrack                    Variable Track Pointer structure that contains

+                              Variable Information.

+                              Contains the pointer of Variable header.

+  Global                      VARIABLE_GLOBAL pointer

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_HEADER       *Variable[2];

+  VARIABLE_STORE_HEADER *VariableStoreHeader[2];

+  UINTN                 Index;

+

+  //

+  // 0: Non-Volatile, 1: Volatile

+  //

+  VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);

+  VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);

+

+  //

+  // Start Pointers for the variable.

+  // Actual Data Pointer where data can be written.

+  //

+  Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);

+  Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);

+

+  if (VariableName[0] != 0 && VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the variable by walk through non-volatile and volatile variable store

+  //

+  for (Index = 0; Index < 2; Index++) {

+    PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);

+    PtrTrack->EndPtr    = GetEndPointer (VariableStoreHeader[Index]);

+

+    while ((Variable[Index] != NULL) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {

+      if (Variable[Index]->StartId == VARIABLE_DATA && Variable[Index]->State == VAR_ADDED) {

+        if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {

+          if (VariableName[0] == 0) {

+            PtrTrack->CurrPtr   = Variable[Index];

+            PtrTrack->Volatile  = (BOOLEAN) Index;

+            return EFI_SUCCESS;

+          } else {

+            if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {

+              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), ArrayLength (VariableName))) {

+                PtrTrack->CurrPtr   = Variable[Index];

+                PtrTrack->Volatile  = (BOOLEAN) Index;

+                return EFI_SUCCESS;

+              }

+            }

+          }

+        }

+      }

+

+      Variable[Index] = GetNextVariablePtr (Variable[Index]);

+    }

+  }

+  PtrTrack->CurrPtr = NULL;

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+GetVariable (

+  IN      CHAR16            *VariableName,

+  IN      EFI_GUID          * VendorGuid,

+  OUT     UINT32            *Attributes OPTIONAL,

+  IN OUT  UINTN             *DataSize,

+  OUT     VOID              *Data,

+  IN      VARIABLE_GLOBAL   * Global,

+  IN      UINT32            Instance

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                    Name of Variable to be found

+  VendorGuid                      Variable vendor GUID

+  Attributes OPTIONAL             Attribute value of the variable found

+  DataSize                        Size of Data found. If size is less than the

+                                  data, this value contains the required size.

+  Data                            Data pointer

+  Global                          Pointer to VARIABLE_GLOBAL structure

+  Instance                        Instance of the Firmware Volume.

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarDataSize;

+  EFI_STATUS              Status;

+

+  if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find existing variable

+  //

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get data size

+  //

+  VarDataSize = Variable.CurrPtr->DataSize;

+  if (*DataSize >= VarDataSize) {

+    CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);

+    if (Attributes) {

+      *Attributes = Variable.CurrPtr->Attributes;

+    }

+

+    *DataSize = VarDataSize;

+    return EFI_SUCCESS;

+  } else {

+    *DataSize = VarDataSize;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+GetNextVariableName (

+  IN OUT  UINTN             *VariableNameSize,

+  IN OUT  CHAR16            *VariableName,

+  IN OUT  EFI_GUID          *VendorGuid,

+  IN      VARIABLE_GLOBAL   *Global,

+  IN      UINT32            Instance

+  )

+/*++

+

+Routine Description:

+

+  This code Finds the Next available variable

+

+Arguments:

+

+  VariableNameSize            Size of the variable

+  VariableName                Pointer to variable name

+  VendorGuid                  Variable Vendor Guid

+  Global                      VARIABLE_GLOBAL structure pointer.

+  Instance                    FV instance

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarNameSize;

+  EFI_STATUS              Status;

+

+  if (VariableNameSize == NULL || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  while (TRUE) {

+    if (VariableName[0] != 0) {

+      //

+      // If variable name is not NULL, get next variable

+      //

+      Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);

+    }

+    //

+    // If both volatile and non-volatile variable store are parsed,

+    // return not found

+    //

+    if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {

+      Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));

+      if (Variable.Volatile) {

+        Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));

+        Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));

+      } else {

+        return EFI_NOT_FOUND;

+      }

+

+      Variable.CurrPtr = Variable.StartPtr;

+      if (Variable.CurrPtr->StartId != VARIABLE_DATA) {

+        continue;

+      }

+    }

+    //

+    // Variable is found

+    //

+    if (Variable.CurrPtr->StartId == VARIABLE_DATA && Variable.CurrPtr->State == VAR_ADDED) {

+      if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {

+        VarNameSize = Variable.CurrPtr->NameSize;

+        if (VarNameSize <= *VariableNameSize) {

+          CopyMem (

+            VariableName,

+            GET_VARIABLE_NAME_PTR (Variable.CurrPtr),

+            VarNameSize

+            );

+          CopyMem (

+            VendorGuid,

+            &Variable.CurrPtr->VendorGuid,

+            sizeof (EFI_GUID)

+            );

+          Status = EFI_SUCCESS;

+        } else {

+          Status = EFI_BUFFER_TOO_SMALL;

+        }

+

+        *VariableNameSize = VarNameSize;

+        return Status;

+      }

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+SetVariable (

+  IN CHAR16                  *VariableName,

+  IN EFI_GUID                *VendorGuid,

+  IN UINT32                  Attributes,

+  IN UINTN                   DataSize,

+  IN VOID                    *Data,

+  IN VARIABLE_GLOBAL         *Global,

+  IN UINTN                   *VolatileOffset,

+  IN UINTN                   *NonVolatileOffset,

+  IN UINT32                  Instance

+  )

+/*++

+

+Routine Description:

+

+  This code sets variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                    Name of Variable to be found

+  VendorGuid                      Variable vendor GUID

+  Attributes                      Attribute value of the variable found

+  DataSize                        Size of Data found. If size is less than the

+                                  data, this value contains the required size.

+  Data                            Data pointer

+  Global                          Pointer to VARIABLE_GLOBAL structure

+  VolatileOffset                  The offset of last volatile variable

+  NonVolatileOffset               The offset of last non-volatile variable

+  Instance                        Instance of the Firmware Volume.

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  EFI_STATUS              Status;

+  VARIABLE_HEADER         *NextVariable;

+  UINTN                   VarNameSize;

+  UINTN                   VarNameOffset;

+  UINTN                   VarDataOffset;

+  UINTN                   VarSize;

+

+  if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Status == EFI_INVALID_PARAMETER) {

+    return Status;

+  }

+  //

+  //  The size of the VariableName, including the Unicode Null in bytes plus

+  //  the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.

+  //

+  else if (sizeof (VARIABLE_HEADER) + (ArrayLength (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  //  Make sure if runtime bit is set, boot service bit is set also

+  //

+  else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS

+          ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Runtime but Attribute is not Runtime

+  //

+  else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Cannot set volatile variable in Runtime

+  //

+  else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Setting a data variable with no access, or zero DataSize attributes

+  // specified causes it to be deleted.

+  //

+  else if (DataSize == 0 || Attributes == 0) {

+    if (!EFI_ERROR (Status)) {

+      Variable.CurrPtr->State &= VAR_DELETED;

+      return EFI_SUCCESS;

+    }

+

+    return EFI_NOT_FOUND;

+  } else {

+    if (!EFI_ERROR (Status)) {

+      //

+      // If the variable is marked valid and the same data has been passed in

+      // then return to the caller immediately.

+      //

+      if (Variable.CurrPtr->DataSize == DataSize &&

+          !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)

+            ) {

+        return EFI_SUCCESS;

+      } else if (Variable.CurrPtr->State == VAR_ADDED) {

+        //

+        // Mark the old variable as in delete transition

+        //

+        Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;

+      }

+    }

+    //

+    // Create a new variable and copy the data.

+    //

+    VarNameOffset = sizeof (VARIABLE_HEADER);

+    VarNameSize   = ArrayLength (VariableName);

+    VarDataOffset = VarNameOffset + VarNameSize + GetPadSize (VarNameSize);

+    VarSize       = VarDataOffset + DataSize + GetPadSize (DataSize);

+

+    if (Attributes & EFI_VARIABLE_NON_VOLATILE) {

+      if ((UINT32) (VarSize +*NonVolatileOffset) >

+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size

+            ) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      NextVariable        = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);

+      *NonVolatileOffset  = *NonVolatileOffset + VarSize;

+    } else {

+      if (EfiAtRuntime ()) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if ((UINT32) (VarSize +*VolatileOffset) >

+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size

+            ) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      NextVariable    = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);

+      *VolatileOffset = *VolatileOffset + VarSize;

+    }

+

+    NextVariable->StartId     = VARIABLE_DATA;

+    NextVariable->Attributes  = Attributes;

+    NextVariable->State       = VAR_ADDED;

+    NextVariable->Reserved    = 0;

+

+    //

+    // There will be pad bytes after Data, the NextVariable->NameSize and

+    // NextVariable->NameSize should not include pad size so that variable

+    // service can get actual size in GetVariable

+    //

+    NextVariable->NameSize  = (UINT32)VarNameSize;

+    NextVariable->DataSize  = (UINT32)DataSize;

+

+    CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));

+    CopyMem (

+      (UINT8 *) ((UINTN) NextVariable + VarNameOffset),

+      VariableName,

+      VarNameSize

+      );

+    CopyMem (

+      (UINT8 *) ((UINTN) NextVariable + VarDataOffset),

+      Data,

+      DataSize

+      );

+

+    //

+    // Mark the old variable as deleted

+    //

+    if (!EFI_ERROR (Status)) {

+      Variable.CurrPtr->State &= VAR_DELETED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+InitializeVariableStore (

+  OUT EFI_PHYSICAL_ADDRESS  *VariableBase,

+  OUT UINTN                 *LastVariableOffset

+  )

+/*++

+

+Routine Description:

+  This function initializes variable store

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  VARIABLE_STORE_HEADER *VariableStore;

+

+  //

+  // Allocate memory for volatile variable store

+  //

+  VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (

+                                              VARIABLE_STORE_SIZE

+                                              );

+  if (NULL == VariableStore) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetMem (VariableStore, VARIABLE_STORE_SIZE, 0xff);

+

+  //

+  // Variable Specific Data

+  //

+  *VariableBase             = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;

+  *LastVariableOffset       = sizeof (VARIABLE_STORE_HEADER);

+

+  VariableStore->Signature  = VARIABLE_STORE_SIGNATURE;

+  VariableStore->Size       = VARIABLE_STORE_SIZE;

+  VariableStore->Format     = VARIABLE_STORE_FORMATTED;

+  VariableStore->State      = VARIABLE_STORE_HEALTHY;

+  VariableStore->Reserved   = 0;

+  VariableStore->Reserved1  = 0;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+VariableCommonInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  This function does common initialization for variable services

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Allocate memory for mVariableModuleGlobal

+  //

+  mVariableModuleGlobal = (ESAL_VARIABLE_GLOBAL *) AllocateRuntimePool (

+                                                    sizeof (ESAL_VARIABLE_GLOBAL)

+                                                    );

+  if (NULL == mVariableModuleGlobal) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Intialize volatile variable store

+  //

+  Status = InitializeVariableStore (

+            &mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase,

+            &mVariableModuleGlobal->VolatileLastVariableOffset

+            );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Intialize non volatile variable store

+  //

+  Status = InitializeVariableStore (

+            &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,

+            &mVariableModuleGlobal->NonVolatileLastVariableOffset

+            );

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.dxs b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.dxs
new file mode 100644
index 0000000..51c93d7
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.dxs
@@ -0,0 +1,25 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EmuVariable.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include "DxeDepex.h"

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.mbd b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.mbd
new file mode 100644
index 0000000..4cc2c20
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>EmuVariable</BaseName>

+    <Guid>CBD2E4D5-7068-4FF5-B866-9822B4AD8D60</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-23 16:05</Created>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Arch ArchType="IPF">

+      <Library>EdkDxeSalLib</Library>

+    </Arch>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.msa b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.msa
new file mode 100644
index 0000000..1bc77e6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.msa
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>EmuVariable</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>CBD2E4D5-7068-4FF5-B866-9822B4AD8D60</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-23 16:05</Created>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>EmuVariable.c</Filename>

+    <Filename>EmuVariable.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>../Ia32/Ia32Variable.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>../x64/x64Variable.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>../Ipf/IpfVariable.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalVariableServices</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/build.xml b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/build.xml
new file mode 100644
index 0000000..11ad9af
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EmuVariable"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Variable/RuntimeDxe/Emu"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="EmuVariable">

+      <GenBuild baseName="EmuVariable" mbdFilename="${MODULE_DIR}/EmuVariable.mbd" msaFilename="${MODULE_DIR}/EmuVariable.msa"/>

+   </target>

+   <target depends="EmuVariable_clean" name="clean"/>

+   <target depends="EmuVariable_cleanall" name="cleanall"/>

+   <target name="EmuVariable_clean">

+      <OutputDirSetup baseName="EmuVariable" mbdFilename="${MODULE_DIR}/EmuVariable.mbd" msaFilename="${MODULE_DIR}/EmuVariable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EmuVariable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EmuVariable_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EmuVariable_cleanall">

+      <OutputDirSetup baseName="EmuVariable" mbdFilename="${MODULE_DIR}/EmuVariable.mbd" msaFilename="${MODULE_DIR}/EmuVariable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/EmuVariable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/EmuVariable_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EmuVariable*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Ia32Variable.dxs b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Ia32Variable.dxs
new file mode 100644
index 0000000..821e27d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Ia32Variable.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ia32Variable.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND

+  EFI_ALTERNATE_FV_BLOCK_GUID             AND

+  EFI_FTW_LITE_PROTOCOL_GUID

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c
new file mode 100644
index 0000000..0ad8664
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c
@@ -0,0 +1,185 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  InitVariable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;

+

+EFI_STATUS

+EFIAPI

+RuntimeServiceGetVariable (

+  IN CHAR16        *VariableName,

+  IN EFI_GUID      * VendorGuid,

+  OUT UINT32       *Attributes OPTIONAL,

+  IN OUT UINTN     *DataSize,

+  OUT VOID         *Data

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return GetVariable (

+          VariableName,

+          VendorGuid,

+          Attributes OPTIONAL,

+          DataSize,

+          Data,

+          &mVariableModuleGlobal->VariableBase[Physical],

+          mVariableModuleGlobal->FvbInstance

+          );

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeServiceGetNextVariableName (

+  IN OUT UINTN     *VariableNameSize,

+  IN OUT CHAR16    *VariableName,

+  IN OUT EFI_GUID  *VendorGuid

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return GetNextVariableName (

+          VariableNameSize,

+          VariableName,

+          VendorGuid,

+          &mVariableModuleGlobal->VariableBase[Physical],

+          mVariableModuleGlobal->FvbInstance

+          );

+}

+

+EFI_STATUS

+EFIAPI

+RuntimeServiceSetVariable (

+  IN CHAR16        *VariableName,

+  IN EFI_GUID      *VendorGuid,

+  IN UINT32        Attributes,

+  IN UINTN         DataSize,

+  IN VOID          *Data

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  return SetVariable (

+          VariableName,

+          VendorGuid,

+          Attributes,

+          DataSize,

+          Data,

+          &mVariableModuleGlobal->VariableBase[Physical],

+          &mVariableModuleGlobal->VolatileLastVariableOffset,

+          &mVariableModuleGlobal->NonVolatileLastVariableOffset,

+          mVariableModuleGlobal->FvbInstance

+          );

+}

+

+VOID

+EFIAPI

+VariableClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase

+    );

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase

+    );

+  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);

+}

+

+EFI_STATUS

+EFIAPI

+VariableServiceInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_HANDLE  NewHandle;

+  EFI_STATUS  Status;

+

+  Status = VariableCommonInitialize (ImageHandle, SystemTable);

+  ASSERT_EFI_ERROR (Status);

+

+  SystemTable->RuntimeServices->GetVariable         = RuntimeServiceGetVariable;

+  SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName;

+  SystemTable->RuntimeServices->SetVariable         = RuntimeServiceSetVariable;

+

+  //

+  // Now install the Variable Runtime Architectural Protocol on a new handle

+  //

+  NewHandle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &NewHandle,

+                  &gEfiVariableArchProtocolGuid,

+                  NULL,

+                  &gEfiVariableWriteArchProtocolGuid,

+                  NULL,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Ipf/InitVariable.c b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Ipf/InitVariable.c
new file mode 100644
index 0000000..061e6db
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Ipf/InitVariable.c
@@ -0,0 +1,167 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  IpfVariable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;

+

+SAL_RETURN_REGS

+EsalVariableCommonEntry (

+  IN  UINT64                                      FunctionId,

+  IN  UINT64                                      Arg2,

+  IN  UINT64                                      Arg3,

+  IN  UINT64                                      Arg4,

+  IN  UINT64                                      Arg5,

+  IN  UINT64                                      Arg6,

+  IN  UINT64                                      Arg7,

+  IN  UINT64                                      Arg8,

+  IN  SAL_EXTENDED_SAL_PROC                       ExtendedSalProc,

+  IN  BOOLEAN                                     VirtualMode,

+  IN  ESAL_VARIABLE_GLOBAL                        *Global

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  SAL_RETURN_REGS ReturnVal;

+

+  switch (FunctionId) {

+  case EsalGetVariable:

+    ReturnVal.Status = GetVariable (

+                        (CHAR16 *) Arg2,

+                        (EFI_GUID *) Arg3,

+                        (UINT32 *) Arg4,

+                        (UINTN *) Arg5,

+                        (VOID *) Arg6,

+                        &Global->VariableBase[VirtualMode],

+                        Global->FvbInstance

+                        );

+    return ReturnVal;

+

+  case EsalGetNextVariableName:

+    ReturnVal.Status = GetNextVariableName (

+                        (UINTN *) Arg2,

+                        (CHAR16 *) Arg3,

+                        (EFI_GUID *) Arg4,

+                        &Global->VariableBase[VirtualMode],

+                        Global->FvbInstance

+                        );

+    return ReturnVal;

+

+  case EsalSetVariable:

+    ReturnVal.Status = SetVariable (

+                        (CHAR16 *) Arg2,

+                        (EFI_GUID *) Arg3,

+                        (UINT32) Arg4,

+                        (UINTN) Arg5,

+                        (VOID *) Arg6,

+                        &Global->VariableBase[VirtualMode],

+                        (UINTN *) &Global->VolatileLastVariableOffset,

+                        (UINTN *) &Global->NonVolatileLastVariableOffset,

+                        Global->FvbInstance

+                        );

+    return ReturnVal;

+

+  default:

+    ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;

+    return ReturnVal;

+  }

+}

+

+

+VOID

+VariableClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  CopyMem (

+    &mVariableModuleGlobal->VariableBase[Virtual],

+    &mVariableModuleGlobal->VariableBase[Physical],

+    sizeof (VARIABLE_GLOBAL)

+    );

+

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Virtual].NonVolatileVariableBase

+    );

+  EfiConvertPointer (

+    0x0,

+    (VOID **) &mVariableModuleGlobal->VariableBase[Virtual].VolatileVariableBase

+    );

+  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);

+}

+

+EFI_STATUS

+VariableServiceInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = VariableCommonInitialize (ImageHandle, SystemTable);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  //  Register All the Functions with Extended Sal.

+  //

+  RegisterEsalClass (

+    &gEfiExtendedSalVariableServicesProtocolGuid,

+    mVariableModuleGlobal,

+    EsalVariableCommonEntry,

+    EsalGetVariable,

+    EsalVariableCommonEntry,

+    EsalGetNextVariableName,

+    EsalVariableCommonEntry,

+    EsalSetVariable,

+    NULL

+    );

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/IpfVariable.dxs b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/IpfVariable.dxs
new file mode 100644
index 0000000..a11dae6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/IpfVariable.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  IpfVariable.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EXTENDED_SAL_BOOT_SERVICE_PROTOCOL_GUID          AND 

+  EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID AND

+  EFI_FTW_LITE_PROTOCOL_GUID

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c
new file mode 100644
index 0000000..0d91520
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -0,0 +1,1311 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.c

+

+Abstract:

+

+Revision History

+

+--*/

+

+#include "Variable.h"

+#include "reclaim.h"

+

+//

+// Don't use module globals after the SetVirtualAddress map is signaled

+//

+ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;

+

+UINT32

+EFIAPI

+ArrayLength (

+  IN CHAR16 *String

+  )

+/*++

+

+Routine Description:

+

+  Determine the length of null terminated char16 array.

+

+Arguments:

+

+  String    Null-terminated CHAR16 array pointer.

+

+Returns:

+

+  UINT32    Number of bytes in the string, including the double NULL at the end;

+

+--*/

+{

+  UINT32  Count;

+

+  if (NULL == String) {

+    return 0;

+  }

+

+  Count = 0;

+

+  while (0 != String[Count]) {

+    Count++;

+  }

+

+  return (Count * 2) + 2;

+}

+

+BOOLEAN

+EFIAPI

+IsValidVariableHeader (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code checks if variable header is valid or not.

+

+Arguments:

+  Variable              Pointer to the Variable Header.

+

+Returns:

+  TRUE            Variable header is valid.

+  FALSE           Variable header is not valid.

+

+--*/

+{

+  if (Variable == NULL ||

+      Variable->StartId != VARIABLE_DATA ||

+      (sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize) > MAX_VARIABLE_SIZE

+      ) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+EFI_STATUS

+EFIAPI

+UpdateVariableStore (

+  IN  VARIABLE_GLOBAL         *Global,

+  IN  BOOLEAN                 Volatile,

+  IN  BOOLEAN                 SetByIndex,

+  IN  UINTN                   Instance,

+  IN  UINTN                   DataPtrIndex,

+  IN  UINT32                  DataSize,

+  IN  UINT8                   *Buffer

+  )

+/*++

+

+Routine Description:

+

+  This function writes data to the FWH at the correct LBA even if the LBAs

+  are fragmented.

+

+Arguments:

+

+  Global            Pointer to VARAIBLE_GLOBAL structure

+  Volatile          If the Variable is Volatile or Non-Volatile

+  SetByIndex        TRUE: Target pointer is given as index

+                    FALSE: Target pointer is absolute

+  Instance          Instance of FV Block services

+  DataPtrIndex      Pointer to the Data from the end of VARIABLE_STORE_HEADER

+                    structure

+  DataSize          Size of data to be written.

+  Buffer            Pointer to the buffer from which data is written

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  EFI_FV_BLOCK_MAP_ENTRY      *PtrBlockMapEntry;

+  UINTN                       BlockIndex2;

+  UINTN                       LinearOffset;

+  UINTN                       CurrWriteSize;

+  UINTN                       CurrWritePtr;

+  UINT8                       *CurrBuffer;

+  EFI_LBA                     LbaNumber;

+  UINTN                       Size;

+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;

+  VARIABLE_STORE_HEADER       *VolatileBase;

+  EFI_PHYSICAL_ADDRESS        FvVolHdr;

+  EFI_PHYSICAL_ADDRESS        DataPtr;

+  EFI_STATUS                  Status;

+

+  FwVolHeader = NULL;

+  DataPtr     = DataPtrIndex;

+

+  //

+  // Check if the Data is Volatile

+  //

+  if (!Volatile) {

+    EfiFvbGetPhysicalAddress (Instance, &FvVolHdr);

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr);

+    //

+    // Data Pointer should point to the actual Address where data is to be

+    // written

+    //

+    if (SetByIndex) {

+      DataPtr += Global->NonVolatileVariableBase;

+    }

+

+    if ((DataPtr + DataSize) >= ((EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) FwVolHeader + FwVolHeader->FvLength))) {

+      return EFI_INVALID_PARAMETER;

+    }

+  } else {

+    //

+    // Data Pointer should point to the actual Address where data is to be

+    // written

+    //

+    VolatileBase = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);

+    if (SetByIndex) {

+      DataPtr += Global->VolatileVariableBase;

+    }

+

+    if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // If Volatile Variable just do a simple mem copy.

+  //

+  if (Volatile) {

+    CopyMem ((UINT8 *) ((UINTN) DataPtr), Buffer, DataSize);

+    return EFI_SUCCESS;

+  }

+  //

+  // If we are here we are dealing with Non-Volatile Variables

+  //

+  LinearOffset  = (UINTN) FwVolHeader;

+  CurrWritePtr  = (UINTN) DataPtr;

+  CurrWriteSize = DataSize;

+  CurrBuffer    = Buffer;

+  LbaNumber     = 0;

+

+  if (CurrWritePtr < LinearOffset) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {

+    for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {

+      //

+      // Check to see if the Variable Writes are spanning through multiple

+      // blocks.

+      //

+      if ((CurrWritePtr >= LinearOffset) && (CurrWritePtr < LinearOffset + PtrBlockMapEntry->BlockLength)) {

+        if ((CurrWritePtr + CurrWriteSize) <= (LinearOffset + PtrBlockMapEntry->BlockLength)) {

+          Status = EfiFvbWriteBlock (

+                    Instance,

+                    LbaNumber,

+                    (UINTN) (CurrWritePtr - LinearOffset),

+                    &CurrWriteSize,

+                    CurrBuffer

+                    );

+          if (EFI_ERROR (Status)) {

+            return Status;

+          }

+        } else {

+          Size = (UINT32) (LinearOffset + PtrBlockMapEntry->BlockLength - CurrWritePtr);

+          Status = EfiFvbWriteBlock (

+                    Instance,

+                    LbaNumber,

+                    (UINTN) (CurrWritePtr - LinearOffset),

+                    &Size,

+                    CurrBuffer

+                    );

+          if (EFI_ERROR (Status)) {

+            return Status;

+          }

+

+          CurrWritePtr  = LinearOffset + PtrBlockMapEntry->BlockLength;

+          CurrBuffer    = CurrBuffer + Size;

+          CurrWriteSize = CurrWriteSize - Size;

+        }

+      }

+

+      LinearOffset += PtrBlockMapEntry->BlockLength;

+      LbaNumber++;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+VARIABLE_STORE_STATUS

+EFIAPI

+GetVariableStoreStatus (

+  IN VARIABLE_STORE_HEADER *VarStoreHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the current status of Variable Store.

+

+Arguments:

+

+  VarStoreHeader  Pointer to the Variable Store Header.

+

+Returns:

+

+  EfiRaw        Variable store status is raw

+  EfiValid      Variable store status is valid

+  EfiInvalid    Variable store status is invalid  

+

+--*/

+{

+  if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&

+      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&

+      VarStoreHeader->State == VARIABLE_STORE_HEALTHY

+      ) {

+

+    return EfiValid;

+  } else if (VarStoreHeader->Signature == 0xffffffff &&

+           VarStoreHeader->Size == 0xffffffff &&

+           VarStoreHeader->Format == 0xff &&

+           VarStoreHeader->State == 0xff

+          ) {

+

+    return EfiRaw;

+  } else {

+    return EfiInvalid;

+  }

+}

+

+UINT8 *

+EFIAPI

+GetVariableDataPtr (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the variable data.

+

+Arguments:

+

+  Variable            Pointer to the Variable Header.

+

+Returns:

+

+  UINT8*              Pointer to Variable Data

+

+--*/

+{

+  //

+  // Be careful about pad size for alignment

+  //

+  return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));

+}

+

+VARIABLE_HEADER *

+EFIAPI

+GetNextVariablePtr (

+  IN  VARIABLE_HEADER   *Variable

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the next variable header.

+

+Arguments:

+

+  Variable              Pointer to the Variable Header.

+

+Returns:

+

+  VARIABLE_HEADER*      Pointer to next variable header.

+

+--*/

+{

+  if (!IsValidVariableHeader (Variable)) {

+    return NULL;

+  }

+  //

+  // Be careful about pad size for alignment

+  //

+  return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));

+}

+

+VARIABLE_HEADER *

+EFIAPI

+GetEndPointer (

+  IN VARIABLE_STORE_HEADER       *VarStoreHeader

+  )

+/*++

+

+Routine Description:

+

+  This code gets the pointer to the last variable memory pointer byte

+

+Arguments:

+

+  VarStoreHeader        Pointer to the Variable Store Header.

+

+Returns:

+

+  VARIABLE_HEADER*      Pointer to last unavailable Variable Header

+

+--*/

+{

+  //

+  // The end of variable store

+  //

+  return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size);

+}

+

+EFI_STATUS

+EFIAPI

+Reclaim (

+  IN  EFI_PHYSICAL_ADDRESS  VariableBase,

+  OUT UINTN                 *LastVariableOffset,

+  IN  BOOLEAN               IsVolatile

+  )

+/*++

+

+Routine Description:

+

+  Variable store garbage collection and reclaim operation

+

+Arguments:

+

+  VariableBase                Base address of variable store

+  LastVariableOffset          Offset of last variable

+  IsVolatile                  The variable store is volatile or not,

+                              if it is non-volatile, need FTW

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_HEADER       *Variable;

+  VARIABLE_HEADER       *NextVariable;

+  VARIABLE_STORE_HEADER *VariableStoreHeader;

+  UINT8                 *ValidBuffer;

+  UINTN                 ValidBufferSize;

+  UINTN                 VariableSize;

+  UINT8                 *CurrPtr;

+  EFI_STATUS            Status;

+

+  VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);

+

+  //

+  // Start Pointers for the variable.

+  //

+  Variable        = (VARIABLE_HEADER *) (VariableStoreHeader + 1);

+

+  ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);

+

+  while (IsValidVariableHeader (Variable)) {

+    NextVariable = GetNextVariablePtr (Variable);

+    if (Variable->State == VAR_ADDED) {

+      VariableSize = (UINTN) NextVariable - (UINTN) Variable;

+      ValidBufferSize += VariableSize;

+    }

+

+    Variable = NextVariable;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  ValidBufferSize,

+                  (VOID **) &ValidBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  SetMem (ValidBuffer, ValidBufferSize, 0xff);

+

+  CurrPtr = ValidBuffer;

+

+  //

+  // Copy variable store header

+  //

+  CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));

+  CurrPtr += sizeof (VARIABLE_STORE_HEADER);

+

+  //

+  // Start Pointers for the variable.

+  //

+  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);

+

+  while (IsValidVariableHeader (Variable)) {

+    NextVariable = GetNextVariablePtr (Variable);

+    if (Variable->State == VAR_ADDED) {

+      VariableSize = (UINTN) NextVariable - (UINTN) Variable;

+      CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);

+      CurrPtr += VariableSize;

+    }

+

+    Variable = NextVariable;

+  }

+

+  if (IsVolatile) {

+    //

+    // If volatile variable store, just copy valid buffer

+    //

+    SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);

+    CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, ValidBufferSize);

+    *LastVariableOffset = ValidBufferSize;

+    Status              = EFI_SUCCESS;

+  } else {

+    //

+    // If non-volatile variable store, perform FTW here.

+    //

+    Status = FtwVariableSpace (

+              VariableBase,

+              ValidBuffer,

+              ValidBufferSize

+              );

+    if (!EFI_ERROR (Status)) {

+      *LastVariableOffset = ValidBufferSize;

+    }

+  }

+

+  gBS->FreePool (ValidBuffer);

+

+  if (EFI_ERROR (Status)) {

+    *LastVariableOffset = 0;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+FindVariable (

+  IN  CHAR16                  *VariableName,

+  IN  EFI_GUID                *VendorGuid,

+  OUT VARIABLE_POINTER_TRACK  *PtrTrack,

+  IN  VARIABLE_GLOBAL         *Global

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                Name of the variable to be found

+  VendorGuid                  Vendor GUID to be found.

+  PtrTrack                    Variable Track Pointer structure that contains

+                              Variable Information.

+                              Contains the pointer of Variable header.

+  Global                      VARIABLE_GLOBAL pointer

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_HEADER       *Variable[2];

+  VARIABLE_STORE_HEADER *VariableStoreHeader[2];

+  UINTN                 Index;

+

+  //

+  // 0: Non-Volatile, 1: Volatile

+  //

+  VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);

+  VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);

+

+  //

+  // Start Pointers for the variable.

+  // Actual Data Pointer where data can be written.

+  //

+  Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);

+  Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);

+

+  if (VariableName[0] != 0 && VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the variable by walk through non-volatile and volatile variable store

+  //

+  for (Index = 0; Index < 2; Index++) {

+    PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);

+    PtrTrack->EndPtr    = GetEndPointer (VariableStoreHeader[Index]);

+

+    while (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {

+      if (Variable[Index]->State == VAR_ADDED) {

+        if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {

+          if (VariableName[0] == 0) {

+            PtrTrack->CurrPtr   = Variable[Index];

+            PtrTrack->Volatile  = (BOOLEAN) Index;

+            return EFI_SUCCESS;

+          } else {

+            if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {

+              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), ArrayLength (VariableName))) {

+                PtrTrack->CurrPtr   = Variable[Index];

+                PtrTrack->Volatile  = (BOOLEAN) Index;

+                return EFI_SUCCESS;

+              }

+            }

+          }

+        }

+      }

+

+      Variable[Index] = GetNextVariablePtr (Variable[Index]);

+    }

+    //

+    // While (...)

+    //

+  }

+  //

+  // for (...)

+  //

+  PtrTrack->CurrPtr = NULL;

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+GetVariable (

+  IN      CHAR16            *VariableName,

+  IN      EFI_GUID          * VendorGuid,

+  OUT     UINT32            *Attributes OPTIONAL,

+  IN OUT  UINTN             *DataSize,

+  OUT     VOID              *Data,

+  IN      VARIABLE_GLOBAL   * Global,

+  IN      UINT32            Instance

+  )

+/*++

+

+Routine Description:

+

+  This code finds variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                    Name of Variable to be found

+  VendorGuid                      Variable vendor GUID

+  Attributes OPTIONAL             Attribute value of the variable found

+  DataSize                        Size of Data found. If size is less than the

+                                  data, this value contains the required size.

+  Data                            Data pointer

+  Global                          Pointer to VARIABLE_GLOBAL structure

+  Instance                        Instance of the Firmware Volume.

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarDataSize;

+  EFI_STATUS              Status;

+

+  if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find existing variable

+  //

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get data size

+  //

+  VarDataSize = Variable.CurrPtr->DataSize;

+  if (*DataSize >= VarDataSize) {

+    if (Data == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);

+    if (Attributes != NULL) {

+      *Attributes = Variable.CurrPtr->Attributes;

+    }

+

+    *DataSize = VarDataSize;

+    return EFI_SUCCESS;

+  } else {

+    *DataSize = VarDataSize;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+GetNextVariableName (

+  IN OUT  UINTN             *VariableNameSize,

+  IN OUT  CHAR16            *VariableName,

+  IN OUT  EFI_GUID          *VendorGuid,

+  IN      VARIABLE_GLOBAL   *Global,

+  IN      UINT32            Instance

+  )

+/*++

+

+Routine Description:

+

+  This code Finds the Next available variable

+

+Arguments:

+

+  VariableNameSize            Size of the variable

+  VariableName                Pointer to variable name

+  VendorGuid                  Variable Vendor Guid

+  Global                      VARIABLE_GLOBAL structure pointer.

+  Instance                    FV instance

+

+Returns:

+

+  EFI STATUS

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  UINTN                   VarNameSize;

+  EFI_STATUS              Status;

+

+  if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (VariableName[0] != 0) {

+    //

+    // If variable name is not NULL, get next variable

+    //

+    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);

+  }

+

+  while (TRUE) {

+    //

+    // If both volatile and non-volatile variable store are parsed,

+    // return not found

+    //

+    if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {

+      Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));

+      if (Variable.Volatile) {

+        Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));

+        Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));

+      } else {

+        return EFI_NOT_FOUND;

+      }

+

+      Variable.CurrPtr = Variable.StartPtr;

+      if (!IsValidVariableHeader (Variable.CurrPtr)) {

+        continue;

+      }

+    }

+    //

+    // Variable is found

+    //

+    if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {

+      if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {

+        VarNameSize = Variable.CurrPtr->NameSize;

+        if (VarNameSize <= *VariableNameSize) {

+          CopyMem (

+            VariableName,

+            GET_VARIABLE_NAME_PTR (Variable.CurrPtr),

+            VarNameSize

+            );

+          CopyMem (

+            VendorGuid,

+            &Variable.CurrPtr->VendorGuid,

+            sizeof (EFI_GUID)

+            );

+          Status = EFI_SUCCESS;

+        } else {

+          Status = EFI_BUFFER_TOO_SMALL;

+        }

+

+        *VariableNameSize = VarNameSize;

+        return Status;

+      }

+    }

+

+    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+SetVariable (

+  IN CHAR16                  *VariableName,

+  IN EFI_GUID                *VendorGuid,

+  IN UINT32                  Attributes,

+  IN UINTN                   DataSize,

+  IN VOID                    *Data,

+  IN VARIABLE_GLOBAL         *Global,

+  IN UINTN                   *VolatileOffset,

+  IN UINTN                   *NonVolatileOffset,

+  IN UINT32                  Instance

+  )

+/*++

+

+Routine Description:

+

+  This code sets variable in storage blocks (Volatile or Non-Volatile)

+

+Arguments:

+

+  VariableName                    Name of Variable to be found

+  VendorGuid                      Variable vendor GUID

+  Attributes                      Attribute value of the variable found

+  DataSize                        Size of Data found. If size is less than the

+                                  data, this value contains the required size.

+  Data                            Data pointer

+  Global                          Pointer to VARIABLE_GLOBAL structure

+  VolatileOffset                  The offset of last volatile variable

+  NonVolatileOffset               The offset of last non-volatile variable

+  Instance                        Instance of the Firmware Volume.

+

+Returns:

+

+  EFI STATUS

+  EFI_INVALID_PARAMETER           - Invalid parameter

+  EFI_SUCCESS                     - Set successfully

+  EFI_OUT_OF_RESOURCES            - Resource not enough to set variable

+  EFI_NOT_FOUND                   - Not found

+

+--*/

+{

+  VARIABLE_POINTER_TRACK  Variable;

+  EFI_STATUS              Status;

+  VARIABLE_HEADER         *NextVariable;

+  UINTN                   VarNameSize;

+  UINTN                   VarNameOffset;

+  UINTN                   VarDataOffset;

+  UINTN                   VarSize;

+  UINT8                   State;

+  BOOLEAN                 Reclaimed;

+

+  Reclaimed = FALSE;

+

+  if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);

+

+  if (Status == EFI_INVALID_PARAMETER) {

+    return Status;

+  }

+  //

+  //  The size of the VariableName, including the Unicode Null in bytes plus

+  //  the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.

+  //

+  else if (sizeof (VARIABLE_HEADER) + ArrayLength (VariableName) + DataSize > MAX_VARIABLE_SIZE) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  //  Make sure if runtime bit is set, boot service bit is set also

+  //

+  else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS

+          ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Runtime but Attribute is not Runtime

+  //

+  else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Cannot set volatile variable in Runtime

+  //

+  else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Setting a data variable with no access, or zero DataSize attributes

+  // specified causes it to be deleted.

+  //

+  else if (DataSize == 0 || Attributes == 0) {

+    if (!EFI_ERROR (Status)) {

+      State = Variable.CurrPtr->State;

+      State &= VAR_DELETED;

+

+      Status = UpdateVariableStore (

+                Global,

+                Variable.Volatile,

+                FALSE,

+                Instance,

+                (UINTN) &Variable.CurrPtr->State,

+                sizeof (UINT8),

+                &State

+                );

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      return EFI_SUCCESS;

+    }

+

+    return EFI_NOT_FOUND;

+  } else {

+    if (!EFI_ERROR (Status)) {

+      //

+      // If the variable is marked valid and the same data has been passed in

+      // then return to the caller immediately.

+      //

+      if (Variable.CurrPtr->DataSize == DataSize &&

+          !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)

+            ) {

+        return EFI_SUCCESS;

+      } else if (Variable.CurrPtr->State == VAR_ADDED) {

+        //

+        // Mark the old variable as in delete transition

+        //

+        State = Variable.CurrPtr->State;

+        State &= VAR_IN_DELETED_TRANSITION;

+

+        Status = UpdateVariableStore (

+                  Global,

+                  Variable.Volatile,

+                  FALSE,

+                  Instance,

+                  (UINTN) &Variable.CurrPtr->State,

+                  sizeof (UINT8),

+                  &State

+                  );

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+      }

+    }

+    //

+    // Create a new variable and copy the data.

+    //

+    // Tricky part: Use scratch data area at the end of volatile variable store

+    // as a temporary storage.

+    //

+    NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));

+

+    SetMem (NextVariable, SCRATCH_SIZE, 0xff);

+

+    NextVariable->StartId     = VARIABLE_DATA;

+    NextVariable->Attributes  = Attributes;

+    //

+    // NextVariable->State = VAR_ADDED;

+    //

+    NextVariable->Reserved  = 0;

+    VarNameOffset           = sizeof (VARIABLE_HEADER);

+    VarNameSize             = ArrayLength (VariableName);

+    CopyMem (

+      (UINT8 *) ((UINTN) NextVariable + VarNameOffset),

+      VariableName,

+      VarNameSize

+      );

+    VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);

+    CopyMem (

+      (UINT8 *) ((UINTN) NextVariable + VarDataOffset),

+      Data,

+      DataSize

+      );

+    CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));

+    //

+    // There will be pad bytes after Data, the NextVariable->NameSize and

+    // NextVariable->DataSize should not include pad size so that variable

+    // service can get actual size in GetVariable

+    //

+    NextVariable->NameSize  = (UINT32)VarNameSize;

+    NextVariable->DataSize  = (UINT32)DataSize;

+

+    //

+    // The actual size of the variable that stores in storage should

+    // include pad size.

+    //

+    VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);

+    if (Attributes & EFI_VARIABLE_NON_VOLATILE) {

+      if ((UINT32) (VarSize +*NonVolatileOffset) >

+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size

+            ) {

+        if (EfiAtRuntime ()) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+        //

+        // Perform garbage collection & reclaim operation

+        //

+        Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE);

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+        //

+        // If still no enough space, return out of resources

+        //

+        if ((UINT32) (VarSize +*NonVolatileOffset) >

+              ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size

+              ) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+        

+        Reclaimed = TRUE;

+      }

+      //

+      // Three steps

+      // 1. Write variable header

+      // 2. Write variable data

+      // 3. Set variable state to valid

+      //

+      //

+      // Step 1:

+      //

+      Status = UpdateVariableStore (

+                Global,

+                FALSE,

+                TRUE,

+                Instance,

+                *NonVolatileOffset,

+                sizeof (VARIABLE_HEADER),

+                (UINT8 *) NextVariable

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+      //

+      // Step 2:

+      //

+      Status = UpdateVariableStore (

+                Global,

+                FALSE,

+                TRUE,

+                Instance,

+                *NonVolatileOffset + sizeof (VARIABLE_HEADER),

+                (UINT32) VarSize - sizeof (VARIABLE_HEADER),

+                (UINT8 *) NextVariable + sizeof (VARIABLE_HEADER)

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+      //

+      // Step 3:

+      //

+      NextVariable->State = VAR_ADDED;

+      Status = UpdateVariableStore (

+                Global,

+                FALSE,

+                TRUE,

+                Instance,

+                *NonVolatileOffset,

+                sizeof (VARIABLE_HEADER),

+                (UINT8 *) NextVariable

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      *NonVolatileOffset = *NonVolatileOffset + VarSize;

+

+    } else {

+      if (EfiAtRuntime ()) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      if ((UINT32) (VarSize +*VolatileOffset) >

+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size

+            ) {

+        //

+        // Perform garbage collection & reclaim operation

+        //

+        Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE);

+        if (EFI_ERROR (Status)) {

+          return Status;

+        }

+        //

+        // If still no enough space, return out of resources

+        //

+        if ((UINT32) (VarSize +*VolatileOffset) >

+              ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size

+              ) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+        

+        Reclaimed = TRUE;

+      }

+

+      NextVariable->State = VAR_ADDED;

+      Status = UpdateVariableStore (

+                Global,

+                TRUE,

+                TRUE,

+                Instance,

+                *VolatileOffset,

+                (UINT32) VarSize,

+                (UINT8 *) NextVariable

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      *VolatileOffset = *VolatileOffset + VarSize;

+    }

+    //

+    // Mark the old variable as deleted

+    //

+    if (!Reclaimed && !EFI_ERROR (Status) && Variable.CurrPtr != NULL) {

+      State = Variable.CurrPtr->State;

+      State &= VAR_DELETED;

+

+      Status = UpdateVariableStore (

+                Global,

+                Variable.Volatile,

+                FALSE,

+                Instance,

+                (UINTN) &Variable.CurrPtr->State,

+                sizeof (UINT8),

+                &State

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+VariableCommonInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  This function does common initialization for variable services

+

+Arguments:

+

+  ImageHandle   - The firmware allocated handle for the EFI image.

+  SystemTable   - A pointer to the EFI System Table.

+

+Returns:

+  

+  Status code.

+  

+  EFI_NOT_FOUND     - Variable store area not found.

+  EFI_UNSUPPORTED   - Currently only one non-volatile variable store is supported.

+  EFI_SUCCESS       - Variable services successfully initialized.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  EFI_FIRMWARE_VOLUME_HEADER      *FwVolHeader;

+  CHAR8                           *CurrPtr;

+  VARIABLE_STORE_HEADER           *VolatileVariableStore;

+  VARIABLE_STORE_HEADER           *VariableStoreHeader;

+  VARIABLE_HEADER                 *NextVariable;

+  UINT32                          Instance;

+  EFI_PHYSICAL_ADDRESS            FvVolHdr;

+

+  EFI_FLASH_MAP_ENTRY_DATA        *FlashMapEntryData;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;

+  EFI_FLASH_SUBAREA_ENTRY         VariableStoreEntry;

+  UINT64                          BaseAddress;

+  UINT64                          Length;

+  UINTN                           Index;

+  UINT8                           Data;

+  EFI_PEI_HOB_POINTERS            GuidHob;

+

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  sizeof (ESAL_VARIABLE_GLOBAL),

+                  (VOID **) &mVariableModuleGlobal

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Allocate memory for volatile variable store

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  VARIABLE_STORE_SIZE + SCRATCH_SIZE,

+                  (VOID **) &VolatileVariableStore

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (mVariableModuleGlobal);

+    return Status;

+  }

+

+  SetMem (VolatileVariableStore, VARIABLE_STORE_SIZE + SCRATCH_SIZE, 0xff);

+

+  //

+  //  Variable Specific Data

+  //

+  mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;

+  mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER);

+

+  VolatileVariableStore->Signature                  = VARIABLE_STORE_SIGNATURE;

+  VolatileVariableStore->Size                       = VARIABLE_STORE_SIZE;

+  VolatileVariableStore->Format                     = VARIABLE_STORE_FORMATTED;

+  VolatileVariableStore->State                      = VARIABLE_STORE_HEALTHY;

+  VolatileVariableStore->Reserved                   = 0;

+  VolatileVariableStore->Reserved1                  = 0;

+

+  //

+  // Get non volatile varaible store

+  //

+

+  FlashMapEntryData = NULL;

+

+  GuidHob.Raw = GetHobList ();

+  while (NULL != (GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw))) {

+    FlashMapEntryData = (EFI_FLASH_MAP_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);

+

+    if (FlashMapEntryData->AreaType == EFI_FLASH_AREA_EFI_VARIABLES) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+

+  if (NULL == GuidHob.Raw || FlashMapEntryData == NULL) {

+    gBS->FreePool (mVariableModuleGlobal);

+    gBS->FreePool (VolatileVariableStore);

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Currently only one non-volatile variable store is supported

+  //

+  if (FlashMapEntryData->NumEntries != 1) {

+    gBS->FreePool (mVariableModuleGlobal);

+    gBS->FreePool (VolatileVariableStore);

+    return EFI_UNSUPPORTED;

+  }

+

+  CopyMem (&VariableStoreEntry, &FlashMapEntryData->Entries[0], sizeof (VariableStoreEntry));

+

+  //

+  // Mark the variable storage region of the FLASH as RUNTIME

+  //

+  BaseAddress = VariableStoreEntry.Base & (~EFI_PAGE_MASK);

+  Length      = VariableStoreEntry.Length + (VariableStoreEntry.Base - BaseAddress);

+  Length      = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);

+

+  Status      = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (mVariableModuleGlobal);

+    gBS->FreePool (VolatileVariableStore);

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = gDS->SetMemorySpaceAttributes (

+                  BaseAddress,

+                  Length,

+                  GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (mVariableModuleGlobal);

+    gBS->FreePool (VolatileVariableStore);

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get address of non volatile variable store base

+  //

+  mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase = VariableStoreEntry.Base;

+

+  //

+  // Check Integrity

+  //

+  //

+  // Find the Correct Instance of the FV Block Service.

+  //

+  Instance  = 0;

+  CurrPtr   = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase);

+  while (EfiFvbGetPhysicalAddress (Instance, &FvVolHdr) == EFI_SUCCESS) {

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr);

+    if (CurrPtr >= (CHAR8 *) FwVolHeader && CurrPtr < (((CHAR8 *) FwVolHeader) + FwVolHeader->FvLength)) {

+      mVariableModuleGlobal->FvbInstance = Instance;

+      break;

+    }

+

+    Instance++;

+  }

+

+  VariableStoreHeader = (VARIABLE_STORE_HEADER *) CurrPtr;

+  if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {

+    if (~VariableStoreHeader->Size == 0) {

+      Status = UpdateVariableStore (

+                &mVariableModuleGlobal->VariableBase[Physical],

+                FALSE,

+                FALSE,

+                mVariableModuleGlobal->FvbInstance,

+                (UINTN) &VariableStoreHeader->Size,

+                sizeof (UINT32),

+                (UINT8 *) &VariableStoreEntry.Length

+                );

+

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    }

+

+    mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr);

+    //

+    // Parse non-volatile variable data and get last variable offset

+    //

+    NextVariable  = (VARIABLE_HEADER *) (CurrPtr + sizeof (VARIABLE_STORE_HEADER));

+    Status        = EFI_SUCCESS;

+

+    while (IsValidVariableHeader (NextVariable)) {

+      NextVariable = GetNextVariablePtr (NextVariable);

+    }

+

+    mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) CurrPtr;

+

+    //

+    // Check if the free area is really free.

+    //

+    for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) {

+      Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase)[Index];

+      if (Data != 0xff) {

+        //

+        // There must be something wrong in variable store, do reclaim operation.

+        //

+        Status = Reclaim (

+                  mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,

+                  &mVariableModuleGlobal->NonVolatileLastVariableOffset,

+                  FALSE

+                  );

+        break;

+      }

+    }

+  }

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (mVariableModuleGlobal);

+    gBS->FreePool (VolatileVariableStore);

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.h
new file mode 100644
index 0000000..d1fd5e2
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.h
@@ -0,0 +1,143 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.h

+  

+Abstract:

+

+--*/

+

+#ifndef _VARIABLE_H

+#define _VARIABLE_H

+

+//

+// Statements that include other header files

+//

+

+//

+// BugBug: We need relcate the head file.

+// 

+#include <Common/Variable.h>

+

+#if defined (MDE_CPU_IPF)

+#define ALIGNMENT  8

+#else

+#define ALIGNMENT  1

+#endif

+

+

+#define VARIABLE_STORE_SIZE (64 * 1024)

+#define SCRATCH_SIZE        (4 * 1024)

+

+//

+// Define GET_PAD_SIZE to optimize compiler

+//

+#if ((ALIGNMENT == 0) || (ALIGNMENT == 1))

+#define GET_PAD_SIZE(a) (0)

+#else

+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))

+#endif

+

+#define GET_VARIABLE_NAME_PTR(a)  (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))

+

+typedef enum {

+  Physical,

+  Virtual

+} VARIABLE_POINTER_TYPE;

+

+typedef struct {

+  VARIABLE_HEADER *CurrPtr;

+  VARIABLE_HEADER *EndPtr;

+  VARIABLE_HEADER *StartPtr;

+  BOOLEAN         Volatile;

+} VARIABLE_POINTER_TRACK;

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  VolatileVariableBase;

+  EFI_PHYSICAL_ADDRESS  NonVolatileVariableBase;

+} VARIABLE_GLOBAL;

+

+typedef struct {

+  VARIABLE_GLOBAL VariableBase[2];

+  UINTN           VolatileLastVariableOffset;

+  UINTN           NonVolatileLastVariableOffset;

+  UINT32          FvbInstance;

+} ESAL_VARIABLE_GLOBAL;

+

+//

+// Functions

+//

+EFI_STATUS

+EFIAPI

+VariableCommonInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+EFI_STATUS

+EFIAPI

+VariableServiceInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+VOID

+EFIAPI

+VariableClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GetVariable (

+  IN      CHAR16            *VariableName,

+  IN      EFI_GUID          * VendorGuid,

+  OUT     UINT32            *Attributes OPTIONAL,

+  IN OUT  UINTN             *DataSize,

+  OUT     VOID              *Data,

+  IN      VARIABLE_GLOBAL   * Global,

+  IN      UINT32            Instance

+  )

+;

+

+EFI_STATUS

+EFIAPI

+GetNextVariableName (

+  IN OUT  UINTN             *VariableNameSize,

+  IN OUT  CHAR16            *VariableName,

+  IN OUT  EFI_GUID          *VendorGuid,

+  IN      VARIABLE_GLOBAL   *Global,

+  IN      UINT32            Instance

+  )

+;

+

+EFI_STATUS

+EFIAPI

+SetVariable (

+  IN CHAR16                  *VariableName,

+  IN EFI_GUID                *VendorGuid,

+  IN UINT32                  Attributes,

+  IN UINTN                   DataSize,

+  IN VOID                    *Data,

+  IN VARIABLE_GLOBAL         *Global,

+  IN UINTN                   *VolatileOffset,

+  IN UINTN                   *NonVolatileOffset,

+  IN UINT32                  Instance

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.mbd b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.mbd
new file mode 100644
index 0000000..6a5be9d
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.mbd
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Variable</BaseName>

+    <Guid>CBD2E4D5-7068-4FF5-B462-9822B4AD8D60</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>DxeServicesTableLib</Library>

+    <Library>BaseDebugLibNull</Library>

+    <Library>BasePrintLib</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>EdkFvbServiceLib</Library>

+    <Arch ArchType="IPF">

+      <Library>EdkDxeSalLib</Library>

+    </Arch>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.msa b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.msa
new file mode 100644
index 0000000..23685ff
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.msa
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Variable</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>CBD2E4D5-7068-4FF5-B462-9822B4AD8D60</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkFvbServiceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Variable.c</Filename>

+    <Filename>reclaim.c</Filename>

+    <Arch ArchType="IA32">

+      <Filename>InitVariable.c</Filename>

+      <Filename>Ia32Variable.dxs</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>InitVariable.c</Filename>

+      <Filename>x64Variable.dxs</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>InitVariable.c</Filename>

+      <Filename>x64Variable.dxs</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/InitVariable.c</Filename>

+      <Filename>IpfVariable.dxs</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FaultTolerantWriteLite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">CpuIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FvbExtension</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FaultTolerantWriteLite</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">CpuIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FvbExtension</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalVariableServices</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FlashMapHob</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>Hob</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>SystemNvData</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>AlternateFvBlock</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <SetVirtualAddressMapCallBack>VariableClassAddressChangeEvent</SetVirtualAddressMapCallBack>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/build.xml b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/build.xml
new file mode 100644
index 0000000..5e948e3
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Variable"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/Variable/RuntimeDxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Variable">

+      <GenBuild baseName="Variable" mbdFilename="${MODULE_DIR}/Variable.mbd" msaFilename="${MODULE_DIR}/Variable.msa"/>

+   </target>

+   <target depends="Variable_clean" name="clean"/>

+   <target depends="Variable_cleanall" name="cleanall"/>

+   <target name="Variable_clean">

+      <OutputDirSetup baseName="Variable" mbdFilename="${MODULE_DIR}/Variable.mbd" msaFilename="${MODULE_DIR}/Variable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Variable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Variable_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Variable_cleanall">

+      <OutputDirSetup baseName="Variable" mbdFilename="${MODULE_DIR}/Variable.mbd" msaFilename="${MODULE_DIR}/Variable.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Variable_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Variable_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Variable*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.c b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.c
new file mode 100644
index 0000000..a4bcdd6
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.c
@@ -0,0 +1,240 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  reclaim.c

+  

+Abstract:

+  

+  Handles non-volatile variable store garbage collection, using FTW

+  (Fault Tolerant Write) protocol.

+

+Revision History

+

+--*/

+

+#include "reclaim.h"

+#include "Common/Variable.h"

+

+EFI_STATUS

+GetFvbHandleByAddress (

+  IN  EFI_PHYSICAL_ADDRESS   Address,

+  OUT EFI_HANDLE             *FvbHandle

+  )

+{

+  EFI_STATUS                          Status;

+  EFI_HANDLE                          *HandleBuffer;

+  UINTN                               HandleCount;

+  UINTN                               Index;

+  EFI_PHYSICAL_ADDRESS                FvbBaseAddress;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;

+

+  *FvbHandle = NULL;

+  //

+  // Locate all handles of Fvb protocol

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiFirmwareVolumeBlockProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Get the FVB to access variable store

+  //

+  for (Index = 0; Index < HandleCount; Index += 1) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[Index],

+                    &gEfiFirmwareVolumeBlockProtocolGuid,

+                    (VOID **) &Fvb

+                    );

+    if (EFI_ERROR (Status)) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+    //

+    // Compare the address and select the right one

+    //

+    Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);

+    if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) {

+      *FvbHandle  = HandleBuffer[Index];

+      Status      = EFI_SUCCESS;

+      break;

+    }

+  }

+

+  gBS->FreePool (HandleBuffer);

+  return Status;

+}

+

+EFI_STATUS

+GetLbaAndOffsetByAddress (

+  IN  EFI_PHYSICAL_ADDRESS   Address,

+  OUT EFI_LBA                *Lba,

+  OUT UINTN                  *Offset

+  )

+{

+  EFI_STATUS                          Status;

+  EFI_HANDLE                          FvbHandle;

+  EFI_PHYSICAL_ADDRESS                FvbBaseAddress;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;

+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;

+  EFI_FV_BLOCK_MAP_ENTRY              *FvbMapEntry;

+  UINT32                              LbaIndex;

+

+  *Lba    = (EFI_LBA) (-1);

+  *Offset = 0;

+

+  //

+  // Get the proper FVB

+  //

+  Status = GetFvbHandleByAddress (Address, &FvbHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->HandleProtocol (

+                  FvbHandle,

+                  &gEfiFirmwareVolumeBlockProtocolGuid,

+                  (VOID **) &Fvb

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get the Base Address of FV

+  //

+  Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);

+

+  //

+  // Get the (LBA, Offset) of Address

+  //

+  if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) {

+    if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {

+      //

+      // BUGBUG: Assume one FV has one type of BlockLength

+      //

+      FvbMapEntry = &FwVolHeader->FvBlockMap[0];

+      for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {

+        if (Address < (FvbBaseAddress + FvbMapEntry->BlockLength * LbaIndex)) {

+          //

+          // Found the (Lba, Offset)

+          //

+          *Lba    = LbaIndex - 1;

+          *Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->BlockLength * (LbaIndex - 1)));

+          return EFI_SUCCESS;

+        }

+      }

+    }

+  }

+

+  return EFI_ABORTED;

+}

+

+EFI_STATUS

+FtwVariableSpace (

+  IN EFI_PHYSICAL_ADDRESS   VariableBase,

+  IN UINT8                  *Buffer,

+  IN UINTN                  BufferSize

+  )

+/*++

+

+Routine Description:

+    Write a buffer to Variable space, in the working block.

+

+Arguments:

+    FvbHandle        - Indicates a handle to FVB to access variable store

+    Buffer           - Point to the input buffer

+    BufferSize       - The number of bytes of the input Buffer

+

+Returns:

+    EFI_SUCCESS            - The function completed successfully

+    EFI_ABORTED            - The function could not complete successfully

+    EFI_NOT_FOUND          - Locate FVB protocol by handle fails

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_HANDLE            FvbHandle;

+  EFI_FTW_LITE_PROTOCOL *FtwLiteProtocol;

+  EFI_LBA               VarLba;

+  UINTN                 VarOffset;

+  UINT8                 *FtwBuffer;

+  UINTN                 FtwBufferSize;

+

+  //

+  // Locate fault tolerant write protocol

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiFaultTolerantWriteLiteProtocolGuid,

+                  NULL,

+                  (VOID **) &FtwLiteProtocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Locate Fvb handle by address

+  //

+  Status = GetFvbHandleByAddress (VariableBase, &FvbHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Get LBA and Offset by address

+  //

+  Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Prepare for the variable data

+  //

+  FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;

+  Status        = gBS->AllocatePool (EfiRuntimeServicesData, FtwBufferSize, (VOID **) &FtwBuffer);

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);

+  CopyMem (FtwBuffer, Buffer, BufferSize);

+

+  //

+  // FTW write record

+  //

+  Status = FtwLiteProtocol->Write (

+                              FtwLiteProtocol,

+                              FvbHandle,

+                              VarLba,         // LBA

+                              VarOffset,      // Offset

+                              &FtwBufferSize, // NumBytes,

+                              FtwBuffer

+                              );

+

+  gBS->FreePool (FtwBuffer);

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.h b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.h
new file mode 100644
index 0000000..7bc1020
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.h
@@ -0,0 +1,45 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  reclaim.h

+  

+Abstract:

+  

+  Definitions for non-volatile variable store garbage collection

+

+Revision History

+

+--*/

+

+#ifndef _VAR_RECLAIM_H

+#define _VAR_RECLAIM_H

+

+//

+// Functions

+//

+EFI_STATUS

+GetFvbHandleByAddress (

+  IN  EFI_PHYSICAL_ADDRESS   VariableStoreBase,

+  OUT EFI_HANDLE             *FvbHandle

+  )

+;

+

+EFI_STATUS

+FtwVariableSpace (

+  IN EFI_PHYSICAL_ADDRESS   VariableBaseAddress,

+  IN UINT8                  *Buffer,

+  IN UINTN                  BufferSize

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/x64Variable.dxs b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/x64Variable.dxs
new file mode 100644
index 0000000..c9f2f69
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/Variable/RuntimeDxe/x64Variable.dxs
@@ -0,0 +1,26 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  x64Variable.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/

+#include <AutoGen.h>

+#include "DxeDepex.h"

+

+DEPENDENCY_START

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND EFI_ALTERNATE_FV_BLOCK_GUID

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.c b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.c
new file mode 100644
index 0000000..b54b25e
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.c
@@ -0,0 +1,310 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WatchDogTimer.c

+

+Abstract:

+

+ Generic watchdog timer implemenetation using EFI APIs

+

+Revision History

+

+--*/

+

+#include "WatchDogTimer.h"

+

+//

+// Handle for the Watchdog Timer Architectural Protocol instance produced by this driver

+//

+EFI_HANDLE                        mWatchdogTimerHandle = NULL;

+

+//

+// The Watchdog Timer Architectural Protocol instance produced by this driver

+//

+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  mWatchdogTimer = {

+  WatchdogTimerDriverRegisterHandler,

+  WatchdogTimerDriverSetTimerPeriod,

+  WatchdogTimerDriverGetTimerPeriod

+};

+

+//

+// The watchdog timer period in 100 nS units

+//

+UINT64                            mWatchdogTimerPeriod = 0;

+

+//

+// The notification function to call if the watchdig timer fires

+//

+EFI_WATCHDOG_TIMER_NOTIFY         mWatchdogTimerNotifyFunction = NULL;

+

+//

+// The one-shot timer event that is armed when the watchdog timer is enabled

+//

+EFI_EVENT                         mWatchdogTimerEvent;

+

+//

+// Worker Functions

+//

+VOID

+EFIAPI

+WatchdogTimerDriverExpires (

+  IN EFI_EVENT    Timer,

+  IN VOID         *Context

+  )

+/*++

+

+  Routine Description:

+

+    Notification function that is called if the watchdog timer is fired.  If a 

+    handler has been registered with the Watchdog Timer Architectural Protocol,

+    then that handler is called passing in the time period that has passed that

+    cause the watchdog timer to fire.  Then, a call to the Runtime Service 

+    ResetSystem() is made to reset the platform.

+    

+  Arguments:

+

+    Timer   - The one-shot timer event that was signaled when the watchdog timer 

+              expired.

+

+    Context - The context that was registered when the event Timer was created.

+

+  Returns:

+

+    None.

+

+--*/

+{

+  //

+  // Report error code before exiting

+  //

+  REPORT_STATUS_CODE (

+        EFI_ERROR_CODE | EFI_ERROR_MINOR,

+        (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_TIMER_EXPIRED)

+        );

+

+  //

+  // If a notification function has been registered, then call it

+  //

+  if (mWatchdogTimerNotifyFunction != NULL) {

+    mWatchdogTimerNotifyFunction (mWatchdogTimerPeriod);

+  }

+  //

+  // Reset the platform

+  //

+  gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, 0, NULL);

+}

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverRegisterHandler (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_WATCHDOG_TIMER_NOTIFY         NotifyFunction

+  )

+/*++

+

+Routine Description:

+

+  This function registers a handler that is to be invoked when the watchdog 

+  timer fires.  By default, the EFI_WATCHDOG_TIMER protocol will call the 

+  Runtime Service ResetSystem() when the watchdog timer fires.  If a 

+  NotifyFunction is registered, then the NotifyFunction will be called before 

+  the Runtime Service ResetSystem() is called.  If NotifyFunction is NULL, then 

+  the watchdog handler is unregistered.  If a watchdog handler is registered, 

+  then EFI_SUCCESS is returned.  If an attempt is made to register a handler 

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.  

+  If an attempt is made to uninstall a handler when a handler is not installed, 

+  then return EFI_INVALID_PARAMETER.

+

+Arguments:

+

+  This           - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+

+  NotifyFunction - The function to call when the watchdog timer fires.  If this

+                   is NULL, then the handler will be unregistered.

+

+Returns: 

+

+  EFI_SUCCESS           - The watchdog timer handler was registered or 

+                          unregistered.

+

+  EFI_ALREADY_STARTED   - NotifyFunction is not NULL, and a handler is already 

+                          registered.

+

+  EFI_INVALID_PARAMETER - NotifyFunction is NULL, and a handler was not 

+                          previously registered.

+

+--*/

+{

+  if (NotifyFunction == NULL && mWatchdogTimerNotifyFunction == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (NotifyFunction != NULL && mWatchdogTimerNotifyFunction != NULL) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  mWatchdogTimerNotifyFunction = NotifyFunction;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverSetTimerPeriod (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                            TimerPeriod

+  )

+/*++

+

+Routine Description:

+

+  This function sets the amount of time to wait before firing the watchdog 

+  timer to TimerPeriod 100 nS units.  If TimerPeriod is 0, then the watchdog 

+  timer is disabled.

+

+Arguments:

+

+  This        - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+

+  TimerPeriod - The amount of time in 100 nS units to wait before the watchdog 

+                timer is fired.  If TimerPeriod is zero, then the watchdog 

+                timer is disabled.

+  

+Returns: 

+

+  EFI_SUCCESS      - The watchdog timer has been programmed to fire in Time 

+                     100 nS units.

+

+  EFI_DEVICE_ERROR - A watchdog timer could not be programmed due to a device 

+                     error.

+

+--*/

+{

+  mWatchdogTimerPeriod = TimerPeriod;

+

+  return gBS->SetTimer (

+                mWatchdogTimerEvent,

+                (mWatchdogTimerPeriod == 0) ? TimerCancel : TimerRelative,

+                mWatchdogTimerPeriod

+                );

+}

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverGetTimerPeriod (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                            *TimerPeriod

+  )

+/*++

+

+Routine Description:

+

+  This function retrieves the amount of time the system will wait before firing 

+  the watchdog timer.  This period is returned in TimerPeriod, and EFI_SUCCESS 

+  is returned.  If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned.

+

+Arguments:

+

+  This        - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+

+  TimerPeriod - A pointer to the amount of time in 100 nS units that the system 

+                will wait before the watchdog timer is fired.  If TimerPeriod of

+                zero is returned, then the watchdog timer is disabled.

+  

+Returns: 

+

+  EFI_SUCCESS           - The amount of time that the system will wait before 

+                          firing the watchdog timer was returned in TimerPeriod.

+

+  EFI_INVALID_PARAMETER - TimerPeriod is NULL.

+

+--*/

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = mWatchdogTimerPeriod;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initialize the Watchdog Timer Architectural Protocol driver

+

+Arguments:

+

+  ImageHandle - ImageHandle of the loaded driver

+

+  SystemTable - Pointer to the System Table

+

+Returns:

+

+  EFI_SUCCESS           - Timer Architectural Protocol created

+

+  EFI_OUT_OF_RESOURCES  - Not enough resources available to initialize driver.

+  

+  EFI_DEVICE_ERROR      - A device error occured attempting to initialize the driver.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  REPORT_STATUS_CODE (

+        EFI_PROGRESS_CODE,

+        (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_BEGIN)

+        );

+  //

+  // Make sure the Watchdog Timer Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);

+

+  //

+  // Create the timer event used to implement a simple watchdog timer

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_NOTIFY,

+                  WatchdogTimerDriverExpires,

+                  NULL,

+                  &mWatchdogTimerEvent

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Install the Watchdog Timer Arch Protocol onto a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mWatchdogTimerHandle,

+                  &gEfiWatchdogTimerArchProtocolGuid,

+                  &mWatchdogTimer,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  REPORT_STATUS_CODE (

+        EFI_PROGRESS_CODE,

+        (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_END)

+        );

+

+  return Status;

+}

diff --git a/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.dxs b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.dxs
new file mode 100644
index 0000000..da8c297
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WatchDogTimer.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_TIMER_ARCH_PROTOCOL_GUID

+DEPENDENCY_END

+

diff --git a/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.h b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.h
new file mode 100644
index 0000000..bb1936b
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.h
@@ -0,0 +1,62 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WatchDogTimer.h

+

+Abstract:

+

+ Generic watchdog timer implemenetation using EFI APIs

+

+Revision History

+

+--*/

+

+#ifndef _WATCHDOG_TIMER_H_

+#define _WATCHDOG_TIMER_H_

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverRegisterHandler (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_WATCHDOG_TIMER_NOTIFY         NotifyFunction

+  )

+;

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverSetTimerPeriod (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                            TimerPeriod

+  )

+;

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverGetTimerPeriod (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                            *TimerPeriod

+  )

+;

+

+EFI_STATUS

+EFIAPI

+WatchdogTimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+;

+

+#endif

diff --git a/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.mbd b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.mbd
new file mode 100644
index 0000000..17bd6ea
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WatchDogTimer</BaseName>

+    <Guid>F099D67F-71AE-4c36-B2A3-DCEB0EB2B7D8</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Modified>2006-03-19 15:19</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.msa b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.msa
new file mode 100644
index 0000000..b18df96
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WatchDogTimer</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>F099D67F-71AE-4c36-B2A3-DCEB0EB2B7D8</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-12 17:09</Created>

+    <Updated>2006-03-19 15:19</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WatchDogTimer.c</Filename>

+    <Filename>WatchDogTimer.h</Filename>

+    <Filename>WatchDogTimer.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">StatusCode</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">WatchdogTimer</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>WatchdogTimerDriverInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/build.xml b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/build.xml
new file mode 100644
index 0000000..976ba17
--- /dev/null
+++ b/edk2/EdkModulePkg/Universal/WatchdogTimer/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WatchDogTimer"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Universal/WatchdogTimer/Dxe"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="WatchDogTimer">

+      <GenBuild baseName="WatchDogTimer" mbdFilename="${MODULE_DIR}/WatchDogTimer.mbd" msaFilename="${MODULE_DIR}/WatchDogTimer.msa"/>

+   </target>

+   <target depends="WatchDogTimer_clean" name="clean"/>

+   <target depends="WatchDogTimer_cleanall" name="cleanall"/>

+   <target name="WatchDogTimer_clean">

+      <OutputDirSetup baseName="WatchDogTimer" mbdFilename="${MODULE_DIR}/WatchDogTimer.mbd" msaFilename="${MODULE_DIR}/WatchDogTimer.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/WatchDogTimer_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/WatchDogTimer_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WatchDogTimer_cleanall">

+      <OutputDirSetup baseName="WatchDogTimer" mbdFilename="${MODULE_DIR}/WatchDogTimer.mbd" msaFilename="${MODULE_DIR}/WatchDogTimer.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/WatchDogTimer_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/WatchDogTimer_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WatchDogTimer*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkModulePkg/build.xml b/edk2/EdkModulePkg/build.xml
new file mode 100644
index 0000000..a5df7f3
--- /dev/null
+++ b/edk2/EdkModulePkg/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+ 

+<project default="buildfpd" basedir=".">

+  <!-- Apply external ANT tasks -->

+  <taskdef resource="net/sf/antcontrib/antlib.xml" />

+  <taskdef resource="GenBuild.tasks" />

+  

+  <property environment="env" />  

+  <property name="WORKSPACE_DIR" value="${env.WORKSPACE}" />

+  <property name="PACKAGE" value="EdkModulePkg" />

+  <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}/EdkModulePkg" />

+  <property name="BUILD_MODE" value="PACKAGE" />

+  

+  <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml" />

+  

+  <target name="buildfpd" depends="init, fpdparser, builds" />

+  

+  <target name="init">

+    <if>

+      <not>

+        <isset property="env.WORKSPACE" />

+      </not>

+      <then>

+        <fail message="WORKSPACE environmental variable not set." />

+      </then>

+    </if>

+    <ToolChainSetup confPath="${WORKSPACE_DIR}/Tools/Conf" />

+  </target>

+

+  <target name="tools">

+    <ant antfile="${WORKSPACE_DIR}/Tools/Source/TianoTools/build.xml" />

+  </target>

+  

+  <target name="fpdparser" unless="FPD_File">

+    <FPDParser fpdfilename="EdkModulePkg.fpd" />

+  </target>

+  

+  <target name="builds" depends="fpdparser">

+    <ant antfile="${PACKAGE_DIR}/build.out.xml" />

+  </target>

+  

+  <!-- clean. -->

+  <target name="clean" depends="init">

+    <if>

+      <available file="${PACKAGE_DIR}/build.out.xml" />

+      <then>

+        <ant antfile="${PACKAGE_DIR}/build.out.xml" target="clean" />

+      </then>

+    </if>

+  </target>

+  

+  <!-- clean All. -->

+  <target name="cleanall" depends="init">

+    <if>

+      <available file="${PACKAGE_DIR}/build.out.xml" />

+      <then>

+        <ant antfile="${PACKAGE_DIR}/build.out.xml" target="cleanall" />

+        <delete file="${PACKAGE_DIR}/build.out.xml" />

+      </then>

+    </if>

+    <delete dir="${PACKAGE_DIR}/Build/FV" />

+  </target>

+  

+</project>

diff --git a/edk2/EdkModulePkg/genbuildfile.xml b/edk2/EdkModulePkg/genbuildfile.xml
new file mode 100644
index 0000000..77702ef
--- /dev/null
+++ b/edk2/EdkModulePkg/genbuildfile.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+ 

+<project default="workspace" basedir=".">

+  <taskdef resource="GenBuild.tasks" />

+  

+  <target name="workspace">

+    <bf recursive="true" />

+  </target>

+</project>

diff --git a/edk2/EdkNt32Pkg/Build/AprioriList.mbd b/edk2/EdkNt32Pkg/Build/AprioriList.mbd
new file mode 100644
index 0000000..a45c093
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Build/AprioriList.mbd
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>AprioriList</BaseName>

+    <Guid>0xfc510ee7, 0xffdc, 0x11d4, 0xbd, 0x41, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Build/AprioriList.msa b/edk2/EdkNt32Pkg/Build/AprioriList.msa
new file mode 100644
index 0000000..3790d2f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Build/AprioriList.msa
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>AprioriList</BaseName>

+    <ModuleType>USER_DEFINED</ModuleType>

+    <ComponentType>APRIORI</ComponentType>

+    <Guid>0xfc510ee7, 0xffdc, 0x11d4, 0xbd, 0x41, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for creating an Apriori file.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <SourceFiles>

+    <Filename>$(BUILD_DIR)\Fv\$(FV).apr</Filename>

+  </SourceFiles>

+  <Includes>

+  </Includes>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Build/Nt32Common.xml b/edk2/EdkNt32Pkg/Build/Nt32Common.xml
new file mode 100644
index 0000000..7d996fe
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Build/Nt32Common.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<root>

+  <Ffs type="APPLICATION">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_PE32"/>

+        <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+        <Section SectionType="EFI_SECTION_VERSION"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+  <Ffs type="FILE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_RAW"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="Apriori">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_RAW"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="Logo, Logo.Logo">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_RAW"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+  <Ffs type="RAWFILE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_RAW"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_RAW"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="Legacy16">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_RAW"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+  <Ffs type="BINARY">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_RAW"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+  <Ffs type="PE32_PEIM.TE_PEIM">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/>

+      <Section SectionType="EFI_SECTION_TE"/>

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="Config.Config">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_RAW"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_RAW"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="BS_DRIVER.Ifr_Bin">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_DRIVER"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_PEI_DEPEX"/>

+        <Section SectionType="EFI_SECTION_PE32"/>

+        <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+        <Section SectionType="EFI_SECTION_VERSION"/>

+        <Section SectionType="EFI_SECTION_RAW"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+

+

+  <Ffs type="PEI_CORE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEI_CORE"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_PE32"/>

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="PE32_PEIM">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/>

+      <Section SectionType="EFI_SECTION_PE32"/>

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="PE32_PEIM.Relocatable">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/>

+      <Section SectionType="EFI_SECTION_PE32"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="PE32_PEIM.CompressPEIM">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/>

+      <Sections EncapsulationType="Compress">

+        <Section SectionType="EFI_SECTION_PE32"/>

+        <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+        <Section SectionType="EFI_SECTION_VERSION"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+  <Ffs type="COMBINED_PEIM_DRIVER">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/>

+      <Section SectionType="EFI_SECTION_UNKNOW"/>

+      <Section SectionType="EFI_SECTION_PE32"/>

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="DXE_CORE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_DXE_CORE"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Section SectionType="EFI_SECTION_PE32"/>

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/>

+    </Sections>

+  </Ffs>

+  <Ffs type="BS_DRIVER, RT_DRIVER, SAL_RT_DRIVER, BS_DRIVER_EFI, RT_DRIVER_EFI, APPLICATION_EFI">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_DRIVER"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_DXE_DEPEX"/>

+        <Section SectionType="EFI_SECTION_PE32"/>

+        <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+        <Section SectionType="EFI_SECTION_VERSION"/>

+      </Sections>

+    </Sections>

+  </Ffs>

+

+  <Ffs type="Microcode">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_RAW"/>

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE"/>

+    <Sections>

+      <Section SectionType="EFI_SECTION_RAW"/>

+    </Sections>

+  </Ffs>

+</root>

diff --git a/edk2/EdkNt32Pkg/Build/component.def b/edk2/EdkNt32Pkg/Build/component.def
new file mode 100644
index 0000000..1e84846
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Build/component.def
@@ -0,0 +1,12 @@
+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+

+LIBRARY

+EXPORTS

+   InitializeDriver=_ModuleEntryPoint

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ComponentName.c
new file mode 100644
index 0000000..f854499
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ComponentName.c
@@ -0,0 +1,141 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "ConPlatform.h"

+#include "ComponentName.h"

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gConPlatformComponentName = {

+  ConPlatformComponentNameGetDriverName,

+  ConPlatformComponentNameGetControllerName,

+  "eng"

+};

+

+STATIC EFI_UNICODE_STRING_TABLE mConPlatformDriverNameTable[] = {

+  {

+    "eng",

+    L"Platform Console Management Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+ConPlatformComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+           Language,

+           gConPlatformComponentName.SupportedLanguages,

+           mConPlatformDriverNameTable,

+           DriverName

+           );

+}

+

+EFI_STATUS

+EFIAPI

+ConPlatformComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language 

+                       specified by Language from the point of view of the 

+                       driver specified by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid 

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently 

+                            managing the controller specified by 

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/ComponentName.h b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ComponentName.h
new file mode 100644
index 0000000..3bada84
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ComponentName.h
@@ -0,0 +1,44 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ComponentName.h

+    

+Abstract:

+

+--*/

+

+#ifndef CON_MANAGE_COMPONENT_NAME_H_

+#define CON_MANAGE_COMPONENT_NAME_H_

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+ConPlatformComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+ConPlatformComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.c b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.c
new file mode 100644
index 0000000..4b7d279
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.c
@@ -0,0 +1,811 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ConPlatform.c

+    

+Abstract:

+

+--*/

+

+#include "ConPlatform.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding = {

+  ConPlatformTextInDriverBindingSupported,

+  ConPlatformTextInDriverBindingStart,

+  ConPlatformDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {

+  ConPlatformTextOutDriverBindingSupported,

+  ConPlatformTextOutDriverBindingStart,

+  ConPlatformDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextInDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Supported 

+

+Arguments:

+  (Standard DriverBinding Protocol Supported() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  return ConPlatformDriverBindingSupported (

+          This,

+          ControllerHandle,

+          RemainingDevicePath,

+          &gEfiSimpleTextInProtocolGuid

+          );

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextOutDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+  Supported 

+

+Arguments:

+  (Standard DriverBinding Protocol Supported() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  return ConPlatformDriverBindingSupported (

+          This,

+          ControllerHandle,

+          RemainingDevicePath,

+          &gEfiSimpleTextOutProtocolGuid

+          );

+}

+

+EFI_STATUS

+ConPlatformDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath,

+  IN  EFI_GUID                     *ProtocolGuid

+  )

+/*++

+

+Routine Description:

+  Supported 

+

+Arguments:

+  (Standard DriverBinding Protocol Supported() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS  Status;

+  VOID        *Interface;

+

+  //

+  // Test to see if this is a physical device by checking to see if

+  // it has a Device Path Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Test to see if this device supports the Simple Text Output Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  ProtocolGuid,

+                  (VOID **) &Interface,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        ControllerHandle,

+        ProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextInDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+  (Standard DriverBinding Protocol Start() function)

+

+Returns:

+

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;

+

+  //

+  // Get the Device Path Protocol so the environment variables can be updated

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &DevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Open the Simple Input Protocol BY_DRIVER

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextInProtocolGuid,

+                  (VOID **) &TextIn,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Check the device handle, if it is a hot plug device,

+  // do not put the device path into ConInDev, and install

+  // gEfiConsoleInDeviceGuid to the device handle directly.

+  // The policy is, make hot plug device plug in and play immediately.

+  //

+  if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {

+    gBS->InstallMultipleProtocolInterfaces (

+          &ControllerHandle,

+          &gEfiConsoleInDeviceGuid,

+          NULL,

+          NULL

+          );

+  } else {

+    //

+    // Append the device path to the ConInDev environment variable

+    //

+    ConPlatformUpdateDeviceVariable (

+      VarConsoleInpDev,

+      DevicePath,

+      APPEND

+      );

+

+    //

+    // If the device path is an instance in the ConIn environment variable,

+    // then install EfiConsoleInDeviceGuid onto ControllerHandle

+    //

+    Status = ConPlatformUpdateDeviceVariable (

+              VarConsoleInp,

+              DevicePath,

+              CHECK

+              );

+

+    if (!EFI_ERROR (Status)) {

+      gBS->InstallMultipleProtocolInterfaces (

+            &ControllerHandle,

+            &gEfiConsoleInDeviceGuid,

+            NULL,

+            NULL

+            );

+    } else {

+      gBS->CloseProtocol (

+            ControllerHandle,

+            &gEfiSimpleTextInProtocolGuid,

+            This->DriverBindingHandle,

+            ControllerHandle

+            );

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextOutDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+  (Standard DriverBinding Protocol Start() function)

+

+Returns:

+

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

+

+  BOOLEAN                       NeedClose;

+

+  NeedClose = TRUE;

+

+  //

+  // Get the Device Path Protocol so the environment variables can be updated

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID **) &DevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Open the Simple Text Output Protocol BY_DRIVER

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &TextOut,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Check the device handle, if it is a hot plug device,

+  // do not put the device path into ConOutDev and StdErrDev,

+  // and install gEfiConsoleOutDeviceGuid to the device handle directly.

+  // The policy is, make hot plug device plug in and play immediately.

+  //

+  if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {

+    gBS->InstallMultipleProtocolInterfaces (

+          &ControllerHandle,

+          &gEfiConsoleOutDeviceGuid,

+          NULL,

+          NULL

+          );

+  } else {

+    //

+    // Append the device path to the ConOutDev environment variable

+    //

+    ConPlatformUpdateDeviceVariable (

+      VarConsoleOutDev,

+      DevicePath,

+      APPEND

+      );

+    //

+    // Append the device path to the StdErrDev environment variable

+    //

+    ConPlatformUpdateDeviceVariable (

+      VarErrorOutDev,

+      DevicePath,

+      APPEND

+      );

+

+    //

+    // If the device path is an instance in the ConOut environment variable,

+    // then install EfiConsoleOutDeviceGuid onto ControllerHandle

+    //

+    Status = ConPlatformUpdateDeviceVariable (

+              VarConsoleOut,

+              DevicePath,

+              CHECK

+              );

+    if (!EFI_ERROR (Status)) {

+      NeedClose = FALSE;

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &ControllerHandle,

+                      &gEfiConsoleOutDeviceGuid,

+                      NULL,

+                      NULL

+                      );

+    }

+    //

+    // If the device path is an instance in the StdErr environment variable,

+    // then install EfiStandardErrorDeviceGuid onto ControllerHandle

+    //

+    Status = ConPlatformUpdateDeviceVariable (

+              VarErrorOut,

+              DevicePath,

+              CHECK

+              );

+    if (!EFI_ERROR (Status)) {

+      NeedClose = FALSE;

+      gBS->InstallMultipleProtocolInterfaces (

+            &ControllerHandle,

+            &gEfiStandardErrorDeviceGuid,

+            NULL,

+            NULL

+            );

+    }

+

+    if (NeedClose) {

+      gBS->CloseProtocol (

+            ControllerHandle,

+            &gEfiSimpleTextOutProtocolGuid,

+            This->DriverBindingHandle,

+            ControllerHandle

+            );

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  (Standard DriverBinding Protocol Stop() function)

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+

+  //

+  // hot plug device is not included into the console associated variables,

+  // so no need to check variable for those hot plug devices.

+  //

+  if (!IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {

+    //

+    // Get the Device Path Protocol so the environment variables can be updated

+    //

+    Status = gBS->OpenProtocol (

+                    ControllerHandle,

+                    &gEfiDevicePathProtocolGuid,

+                    (VOID **) &DevicePath,

+                    This->DriverBindingHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+      //

+      // Remove DevicePath from ConInDev, ConOutDev, and StdErrDev

+      //

+      ConPlatformUpdateDeviceVariable (

+        VarConsoleInpDev,

+        DevicePath,

+        DELETE

+        );

+      ConPlatformUpdateDeviceVariable (

+        VarConsoleOutDev,

+        DevicePath,

+        DELETE

+        );

+      ConPlatformUpdateDeviceVariable (

+        VarErrorOutDev,

+        DevicePath,

+        DELETE

+        );

+    }

+  }

+  //

+  // Uninstall the Console Device GUIDs from Controller Handle

+  //

+  ConPlatformUnInstallProtocol (

+    This,

+    ControllerHandle,

+    &gEfiConsoleInDeviceGuid

+    );

+

+  ConPlatformUnInstallProtocol (

+    This,

+    ControllerHandle,

+    &gEfiConsoleOutDeviceGuid

+    );

+

+  ConPlatformUnInstallProtocol (

+    This,

+    ControllerHandle,

+    &gEfiStandardErrorDeviceGuid

+    );

+

+  //

+  // Close the Simple Input and Simple Text Output Protocols

+  //

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiSimpleTextInProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiSimpleTextOutProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return EFI_SUCCESS;

+}

+

+VOID

+ConPlatformUnInstallProtocol (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_GUID                     *ProtocolGuid

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  ProtocolGuid,

+                  NULL,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    gBS->UninstallMultipleProtocolInterfaces (

+          Handle,

+          ProtocolGuid,

+          NULL,

+          NULL

+          );

+  }

+

+  return ;

+}

+

+VOID *

+ConPlatformGetVariable (

+  IN  CHAR16    *Name

+  )

+/*++

+

+Routine Description:

+  Read the EFI variable (Name) and return a dynamically allocated

+  buffer, and the size of the buffer. On failure return NULL.

+

+Arguments:

+  Name       - String part of EFI variable name

+

+Returns:

+  Dynamically allocated memory that contains a copy of the EFI variable.

+  Caller is repsoncible freeing the buffer.

+

+  NULL - Variable was not read

+  

+--*/

+{

+  EFI_STATUS  Status;

+  VOID        *Buffer;

+  UINTN       BufferSize;

+

+  BufferSize  = 0;

+  Buffer      = NULL;

+

+  //

+  // Test to see if the variable exists.  If it doesn't reuturn NULL

+  //

+  Status = gRT->GetVariable (

+                  Name,

+                  &gEfiGlobalVariableGuid,

+                  NULL,

+                  &BufferSize,

+                  Buffer

+                  );

+

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    //

+    // Allocate the buffer to return

+    //

+    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    //

+    // Read variable into the allocated buffer.

+    //

+    Status = gRT->GetVariable (

+                    Name,

+                    &gEfiGlobalVariableGuid,

+                    NULL,

+                    &BufferSize,

+                    Buffer

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (Buffer);

+      Buffer = NULL;

+    }

+  }

+

+  return Buffer;

+}

+

+EFI_STATUS

+ConPlatformMatchDevicePaths (

+  IN  EFI_DEVICE_PATH_PROTOCOL  * Multi,

+  IN  EFI_DEVICE_PATH_PROTOCOL  * Single,

+  IN  EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath OPTIONAL,

+  IN  BOOLEAN                   Delete

+  )

+/*++

+

+Routine Description:

+  Function compares a device path data structure to that of all the nodes of a

+  second device path instance.

+

+Arguments:

+  Multi        - A pointer to a multi-instance device path data structure.

+

+  Single       - A pointer to a single-instance device path data structure.

+  

+  NewDevicePath - If Delete is TRUE, this parameter must not be null, and it

+                  points to the remaining device path data structure. 

+                  (remaining device path = Multi - Single.)

+  

+  Delete        - If TRUE, means removing Single from Multi.

+                  If FALSE, the routine just check whether Single matches 

+                  with any instance in Multi.

+

+Returns:

+

+  The function returns EFI_SUCCESS if the Single is contained within Multi.  

+  Otherwise, EFI_NOT_FOUND is returned.

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath1;

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath2;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;

+  UINTN                     Size;

+

+  //

+  // The passed in DevicePath should not be NULL

+  //

+  if ((!Multi) || (!Single)) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // if performing Delete operation, the NewDevicePath must not be NULL.

+  //

+  TempDevicePath1 = NULL;

+

+  DevicePath      = Multi;

+  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);

+

+  //

+  // search for the match of 'Single' in 'Multi'

+  //

+  while (DevicePathInst) {

+    if (CompareMem (Single, DevicePathInst, Size) == 0) {

+      if (!Delete) {

+        gBS->FreePool (DevicePathInst);

+        return EFI_SUCCESS;

+      }

+    } else {

+      if (Delete) {

+        TempDevicePath2 = AppendDevicePathInstance (

+                            TempDevicePath1,

+                            DevicePathInst

+                            );

+        gBS->FreePool (TempDevicePath1);

+        TempDevicePath1 = TempDevicePath2;

+      }

+    }

+

+    gBS->FreePool (DevicePathInst);

+    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);

+  }

+

+  if (Delete) {

+    *NewDevicePath = TempDevicePath1;

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+ConPlatformUpdateDeviceVariable (

+  IN  CHAR16                    *VariableName,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN  CONPLATFORM_VAR_OPERATION Operation

+  )

+/*++

+

+Routine Description:

+  

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *VariableDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *NewVariableDevicePath;

+

+  VariableDevicePath    = NULL;

+  NewVariableDevicePath = NULL;

+

+  //

+  // Get Variable according to variable name.

+  // The memory for Variable is allocated within ConPlatformGetVarible(),

+  // it is the caller's responsibility to free the memory before return.

+  //

+  VariableDevicePath = ConPlatformGetVariable (VariableName);

+

+  if (Operation != DELETE) {

+

+    Status = ConPlatformMatchDevicePaths (

+              VariableDevicePath,

+              DevicePath,

+              NULL,

+              FALSE

+              );

+

+    if ((Operation == CHECK) || (!EFI_ERROR (Status))) {

+      //

+      // The device path is already in the variable

+      //

+      gBS->FreePool (VariableDevicePath);

+

+      return Status;

+    }

+    //

+    // The device path is not in variable. Append DevicePath to the

+    // environment variable that is a multi-instance device path.

+    //

+    Status = EFI_SUCCESS;

+    NewVariableDevicePath = AppendDevicePathInstance (

+                              VariableDevicePath,

+                              DevicePath

+                              );

+    if (NewVariableDevicePath == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+    }

+

+  } else {

+    //

+    // Remove DevicePath from the environment variable that

+    // is a multi-instance device path.

+    //

+    Status = ConPlatformMatchDevicePaths (

+              VariableDevicePath,

+              DevicePath,

+              &NewVariableDevicePath,

+              TRUE

+              );

+  }

+

+  gBS->FreePool (VariableDevicePath);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gRT->SetVariable (

+                  VariableName,

+                  &gEfiGlobalVariableGuid,

+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                  GetDevicePathSize (NewVariableDevicePath),

+                  NewVariableDevicePath

+                  );

+

+  gBS->FreePool (NewVariableDevicePath);

+

+  return Status;

+}

+

+BOOLEAN

+IsHotPlugDevice (

+  EFI_HANDLE    DriverBindingHandle,

+  EFI_HANDLE    ControllerHandle

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiHotPlugDeviceGuid,

+                  NULL,

+                  DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.h b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.h
new file mode 100644
index 0000000..41b0256
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.h
@@ -0,0 +1,126 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    ConPlatform.h

+    

+Abstract:

+

+--*/

+

+#ifndef CON_MANAGE_H_

+#define CON_MANAGE_H_

+

+//

+//

+//

+#define VarConsoleInpDev  L"ConInDev"

+#define VarConsoleInp     L"ConIn"

+#define VarConsoleOutDev  L"ConOutDev"

+#define VarConsoleOut     L"ConOut"

+#define VarErrorOutDev    L"ErrOutDev"

+#define VarErrorOut       L"ErrOut"

+

+typedef enum {

+  CHECK,

+  APPEND,

+  DELETE

+} CONPLATFORM_VAR_OPERATION;

+

+EFI_STATUS

+ConPlatformDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath,

+  IN  EFI_GUID                     *ProtocolGuid

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextInDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextOutDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextInDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformTextOutDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+ConPlatformDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  );

+

+VOID

+ConPlatformUnInstallProtocol (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_GUID                     *ProtocolGuid

+  );

+

+VOID *

+ConPlatformGetVariable (

+  IN  CHAR16              *Name

+  );

+

+EFI_STATUS

+ConPlatformMatchDevicePaths (

+  IN  EFI_DEVICE_PATH_PROTOCOL  * Multi,

+  IN  EFI_DEVICE_PATH_PROTOCOL  * Single,

+  IN  EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath OPTIONAL,

+  IN  BOOLEAN                   Delete

+  );

+

+EFI_STATUS

+ConPlatformUpdateDeviceVariable (

+  IN  CHAR16                    *VariableName,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN  CONPLATFORM_VAR_OPERATION Operation

+  );

+

+BOOLEAN

+IsHotPlugDevice (

+  EFI_HANDLE    DriverBindingHandle,

+  EFI_HANDLE    ControllerHandle

+  );

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.mbd b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.mbd
new file mode 100644
index 0000000..6aaa245
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>ConPlatform</BaseName>

+    <Guid>51ccf399-4fdf-4e55-a45b-e123f84d456a</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:06</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.msa b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.msa
new file mode 100644
index 0000000..2344c17
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/ConPlatform.msa
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>ConPlatform</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>51ccf399-4fdf-4e55-a45b-e123f84d456a</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:06</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ConPlatform.c</Filename>

+    <Filename>ConPlatform.h</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">SimpleTextOut</Protocol>

+    <Protocol Usage="TO_START">SimpleTextIn</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+  </Protocols>

+  <Variables>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ConInDev</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ConIn</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ConOutDev</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ConOut</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ErrOutDev</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+    <Variable Usage="SOMETIMES_CONSUMED">

+      <String>ErrOut</String>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Variable>

+  </Variables>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_PRODUCED">

+      <C_Name>ConsoleInDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_PRODUCED">

+      <C_Name>ConsoleOutDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_PRODUCED">

+      <C_Name>StandardErrorDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>HotPlugDevice</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>GlobalVariable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gConPlatformTextInDriverBinding</DriverBinding>

+      <ComponentName>gConPlatformComponentName</ComponentName>

+    </Extern>

+    <Extern>

+      <DriverBinding>gConPlatformTextOutDriverBinding</DriverBinding>

+      <ComponentName>gConPlatformComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/ConPlatform/build.xml b/edk2/EdkNt32Pkg/Dxe/ConPlatform/build.xml
new file mode 100644
index 0000000..52d84eb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/ConPlatform/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="ConPlatform"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\ConPlatform"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="ConPlatform">

+      <GenBuild baseName="ConPlatform" mbdFilename="${MODULE_DIR}\ConPlatform.mbd" msaFilename="${MODULE_DIR}\ConPlatform.msa"/>

+   </target>

+   <target depends="ConPlatform_clean" name="clean"/>

+   <target depends="ConPlatform_cleanall" name="cleanall"/>

+   <target name="ConPlatform_clean">

+      <OutputDirSetup baseName="ConPlatform" mbdFilename="${MODULE_DIR}\ConPlatform.mbd" msaFilename="${MODULE_DIR}\ConPlatform.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\ConPlatform_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\ConPlatform_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="ConPlatform_cleanall">

+      <OutputDirSetup baseName="ConPlatform" mbdFilename="${MODULE_DIR}\ConPlatform.mbd" msaFilename="${MODULE_DIR}\ConPlatform.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\ConPlatform_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\ConPlatform_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**ConPlatform*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBaseBoardManufacturer.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBaseBoardManufacturer.uni
new file mode 100644
index 0000000..14a6893
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBaseBoardManufacturer.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBaseBoardManufacturerData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBaseBoardManufacturerData.c
new file mode 100644
index 0000000..9536c88
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBaseBoardManufacturerData.c
@@ -0,0 +1,57 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscBaseBoardManufacturerData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer) = {

+  STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER),

+  STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME),

+  STRING_TOKEN(STR_MISC_BASE_BOARD_VERSION),

+  STRING_TOKEN(STR_MISC_BASE_BOARD_SERIAL_NUMBER),

+  STRING_TOKEN(STR_MISC_BASE_BOARD_ASSET_TAG),

+  STRING_TOKEN(STR_MISC_BASE_BOARD_CHASSIS_LOCATION),

+  {                         // BaseBoardFeatureFlags

+    1,                      // Motherboard

+    0,                      // RequiresDaughterCard

+    0,                      // Removable

+    1,                      // Replaceable,

+    0,                      // HotSwappable

+    0,                      // Reserved

+  },

+  EfiBaseBoardTypeUnknown,  // BaseBoardType

+  {                         // BaseBoardChassisLink

+    EFI_MISC_SUBCLASS_GUID, // ProducerName

+    1,                      // Instance

+    1,                      // SubInstance

+  },

+  0,                        // BaseBoardNumberLinks

+  {                         // LinkN

+    EFI_MISC_SUBCLASS_GUID, // ProducerName

+    1,                      // Instance

+    1,                      // SubInstance

+  },

+};

+

+/* eof - MiscBaseBoardManufacturerData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosLanguageData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosLanguageData.c
new file mode 100644
index 0000000..652acac
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosLanguageData.c
@@ -0,0 +1,45 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscBiosLanguageData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA, NumberOfInstallableLangauges) = {

+  1,    // NumberOfInstallableLanguages

+  {     // LanguageFlags

+    0,  // AbbreviatedLanguageFormat

+    0   // Reserved

+  },

+  0     // CurrentLanguageNumber

+};

+

+//

+//

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA, SystemLanguageString) = {

+  0,                              // LanguageId

+  STR_MISC_SYSTEM_LANGUAGE_STRING // SystemLanguageString

+};

+

+/* eof - MiscBiosLanguageData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosVendor.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosVendor.uni
new file mode 100644
index 0000000..b1e7e52
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosVendor.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosVendorData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosVendorData.c
new file mode 100644
index 0000000..3187aba
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBiosVendorData.c
@@ -0,0 +1,88 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscBiosVendorData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_BIOS_VENDOR_DATA, MiscBiosVendor) = {

+  STRING_TOKEN(STR_MISC_BIOS_VENDOR),       // BiosVendor

+  STRING_TOKEN(STR_MISC_BIOS_VERSION),      // BiosVersion

+  STRING_TOKEN(STR_MISC_BIOS_RELEASE_DATE), // BiosReleaseDate

+  0xBABE, // BiosStartingAddress

+  {       // BiosPhysicalDeviceSize

+    2,    // Value

+    3,    // Exponent

+  },

+  {       // BiosCharacteristics1

+    0,    // Reserved1                         :2

+    0,    // Unknown                           :1

+    1,    // BiosCharacteristicsNotSupported   :1

+    0,    // IsaIsSupported                    :1

+    0,    // McaIsSupported                    :1

+    0,    // EisaIsSupported                   :1

+    0,    // PciIsSupported                    :1

+    0,    // PcmciaIsSupported                 :1

+    0,    // PlugAndPlayIsSupported            :1

+    0,    // ApmIsSupported                    :1

+    0,    // BiosIsUpgradable                  :1

+    0,    // BiosShadowingAllowed              :1

+    0,    // VlVesaIsSupported                 :1

+    0,    // EscdSupportIsAvailable            :1

+    0,    // BootFromCdIsSupported             :1

+    0,    // SelectableBootIsSupported         :1

+    0,    // RomBiosIsSocketed                 :1

+    0,    // BootFromPcmciaIsSupported         :1

+    0,    // EDDSpecificationIsSupported       :1

+    0,    // JapaneseNecFloppyIsSupported      :1

+    0,    // JapaneseToshibaFloppyIsSupported  :1

+    0,    // Floppy525_360IsSupported          :1

+    0,    // Floppy525_12IsSupported           :1

+    0,    // Floppy35_720IsSupported           :1

+    0,    // Floppy35_288IsSupported           :1

+    0,    // PrintScreenIsSupported            :1

+    0,    // Keyboard8042IsSupported           :1

+    0,    // SerialIsSupported                 :1

+    0,    // PrinterIsSupported                :1

+    0,    // CgaMonoIsSupported                :1

+    0,    // NecPc98                           :1

+    0,    // AcpiIsSupported                   :1

+    0,    // UsbLegacyIsSupported              :1

+    0,    // AgpIsSupported                    :1

+    0,    // I20BootIsSupported                :1

+    0,    // Ls120BootIsSupported              :1

+    0,    // AtapiZipDriveBootIsSupported      :1

+    0,    // Boot1394IsSupported               :1

+    0,    // SmartBatteryIsSupported           :1

+    0,    // BiosBootSpecIsSupported           :1

+    0,    // FunctionKeyNetworkBootIsSupported :1

+    0     // Reserved                          :22

+  },

+  {       // BiosCharacteristics2

+    0,    // BiosReserved                      :16

+    0,    // SystemReserved                    :16

+    0     // Reserved                          :32

+  },

+};

+

+/* eof - MiscBiosVendorData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBootInformationData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBootInformationData.c
new file mode 100644
index 0000000..1bf280b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscBootInformationData.c
@@ -0,0 +1,33 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscBootInformationData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_BOOT_INFORMATION_STATUS_DATA, BootInformationStatus) = {

+  EfiBootInformationStatusNoError,  // BootInformationStatus

+  0                                 // BootInformationData

+};

+

+/* eof - MiscBootInformationData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscChassisManufacturer.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscChassisManufacturer.uni
new file mode 100644
index 0000000..67bee85
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscChassisManufacturer.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscChassisManufacturerData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscChassisManufacturerData.c
new file mode 100644
index 0000000..5c657ee
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscChassisManufacturerData.c
@@ -0,0 +1,45 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscChassisManufacturerData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Chassis Manufacturer data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_CHASSIS_MANUFACTURER_DATA, MiscChassisManufacturer) = {

+  STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER),  // ChassisManufactrurer

+  STRING_TOKEN(STR_MISC_CHASSIS_VERSION),       // ChassisVersion

+  STRING_TOKEN(STR_MISC_CHASSIS_SERIAL_NUMBER), // ChassisSerialNumber

+  STRING_TOKEN(STR_MISC_CHASSIS_ASSET_TAG),     // ChassisAssetTag

+  {                               // ChassisTypeStatus

+    EfiMiscChassisTypeOther,      // ChassisType

+    0,                            // ChassisLockPresent

+    0                             // Reserved

+  },

+  EfiChassisStateOther,           // ChassisBootupState

+  EfiChassisStateOther,           // ChassisPowerSupplyState

+  EfiChassisStateOther,           // ChassisThermalState

+  EfiChassisSecurityStatusOther,  // ChassisSecurityState

+  0                               // ChassisOemDefined

+};

+

+/* eof - MiscChassisManufacaturerData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscDevicePath.h b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscDevicePath.h
new file mode 100644
index 0000000..1568e27
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscDevicePath.h
@@ -0,0 +1,175 @@
+/*++

+ 

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscDevicePath.h

+

+Abstract:

+

+  Misc class required EFI Device Path definitions (Ports, slots & 

+  onboard devices)

+

+--*/

+

+#ifndef _MISC_DEVICE_PATH_H

+#define _MISC_DEVICE_PATH_H

+

+

+#pragma pack(1)

+//

+// USB

+//

+

+/* For reference:

+#define USB1_1_STR  "ACPI(PNP0A03,0)/PCI(1D,0)."

+#define USB1_2_STR  "ACPI(PNP0A03,0)/PCI(1D,1)."

+#define USB1_3_STR  "ACPI(PNP0A03,0)/PCI(1D,2)."

+#define USB2_1_STR  "ACPI(PNP0A03,0)/PCI(1D,7)." 

+*/

+

+//

+// #define acpi { 0x02, 0x01, 0x00, 0x0C, 0x0a0341d0, 0x00000000 }

+// #define pci( device,function)  { 0x01, 0x01, 0x00, 0x06, device, function }

+// #define end  { 0xFF, 0xFF, 0x00, 0x04 }

+//

+#define ACPI \

+  { \

+    ACPI_DEVICE_PATH, ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \

+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID (0x0A03), 0 \

+  }

+#define PCI(device, function) \

+  { \

+    HARDWARE_DEVICE_PATH, HW_PCI_DP, (UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) \

+      ((sizeof (PCI_DEVICE_PATH)) >> 8), function, device \

+  }

+#define END \

+  { \

+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, END_DEVICE_PATH_LENGTH, 0 \

+  }

+

+#define LPC(eisaid, function) \

+  { \

+    ACPI_DEVICE_PATH, ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \

+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID (eisaid), function \

+  }

+

+//

+// Shanmu >> moved to TianoDevicePath.h

+//

+

+/*

+typedef struct _USB_PORT_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} USB_PORT_DEVICE_PATH;

+

+

+//IDE ??I am not sure. Should this be ATAPI_DEVICE_PATH

+typedef struct _IDE_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} IDE_DEVICE_PATH;

+

+//RMC Connector

+typedef struct _RMC_CONN_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      PciBridgeDevicePath;

+  PCI_DEVICE_PATH      PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} RMC_CONN_DEVICE_PATH;

+

+//static RMC_CONN_DEVICE_PATH mRmcConnDevicePath = { acpi, pci( 0x1E,0x00 ),pci( 0x0A,0x00 ), end };

+

+//RIDE

+typedef struct _RIDE_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      PciBridgeDevicePath;

+  PCI_DEVICE_PATH      PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} RIDE_DEVICE_PATH;

+

+//static RIDE_DEVICE_PATH mRideDevicePath = { acpi, pci( 0x1E,0x00 ),pci( 0x02,0x00 ), end };

+

+//Gigabit NIC

+//typedef struct _GB_NIC_DEVICE_PATH

+//{

+//  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+//  PCI_DEVICE_PATH            PciBridgeDevicePath;

+//  PCI_DEVICE_PATH            PciXBridgeDevicePath;

+//  PCI_DEVICE_PATH            PciXBusDevicePath;

+//  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+//} GB_NIC_DEVICE_PATH;

+

+//static GB_NIC_DEVICE_PATH mGbNicDevicePath = { acpi, pci( 0x03,0x00 ),pci( 0x1F,0x00 ),pci( 0x07,0x00 ), end };

+

+

+//P/S2 Connector

+typedef struct _PS2_CONN_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH    LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} PS2_CONN_DEVICE_PATH;

+

+//static PS2_CONN_DEVICE_PATH mPs2KeyboardDevicePath   = { acpi, pci( 0x1F,0x00 ),lpc( 0x0303,0 ), end };

+//static PS2_CONN_DEVICE_PATH mPs2MouseDevicePath      = { acpi, pci( 0x1F,0x00 ),lpc( 0x0303,1 ), end };

+

+//Serial Port Connector

+typedef struct _SERIAL_CONN_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH    LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} SERIAL_CONN_DEVICE_PATH;

+

+//static SERIAL_CONN_DEVICE_PATH mCom1DevicePath   = { acpi, pci( 0x1F,0x00 ),lpc( 0x0501,0 ), end };

+//static SERIAL_CONN_DEVICE_PATH mCom2DevicePath   = { acpi, pci( 0x1F,0x00 ),lpc( 0x0501,1 ), end };

+

+//Parallel Port Connector

+typedef struct _PARALLEL_CONN_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH    LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} PARALLEL_CONN_DEVICE_PATH;

+

+//static PARALLEL_CONN_DEVICE_PATH mLpt1DevicePath   = { acpi, pci( 0x1F,0x00 ),lpc( 0x0401,0 ), end };

+

+//Floopy Connector

+typedef struct _FLOOPY_CONN_DEVICE_PATH

+{

+  ACPI_HID_DEVICE_PATH    PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH      LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH    LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} FLOOPY_CONN_DEVICE_PATH;

+

+//static FLOOPY_CONN_DEVICE_PATH mFloopyADevicePath   = { acpi, pci( 0x1F,0x00 ),lpc( 0x0604,0 ), end };

+//static FLOOPY_CONN_DEVICE_PATH mFloopyBDevicePath   = { acpi, pci( 0x1F,0x00 ),lpc( 0x0604,1 ), end };

+

+*/

+

+//

+// End Shanmu

+//

+#pragma pack()

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscNumberOfInstallableLanguagesData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscNumberOfInstallableLanguagesData.c
new file mode 100644
index 0000000..0084259
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscNumberOfInstallableLanguagesData.c
@@ -0,0 +1,37 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscNumberOfInstallableLanguagesData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA, NumberOfInstallableLanguages) = {

+  1,    // NumberOfInstallableLanguages

+  {     // LanguageFlags

+    0,  // AbbreviatedLanguageFormat

+    0   // Reserved

+  },

+  0,    // CurrentLanguageNumber

+};

+

+/* eof - MiscNumberOfInstallableLanguagesData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOemString.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOemString.uni
new file mode 100644
index 0000000..fb79bdb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOemString.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOemStringData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOemStringData.c
new file mode 100644
index 0000000..fdfbd1f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOemStringData.c
@@ -0,0 +1,32 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    MiscOemStringData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_OEM_STRING_DATA, OemString) = {

+  STRING_TOKEN(STR_MISC_OEM_STRING)

+};

+

+/* eof - MiscOemStringData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDevice.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDevice.uni
new file mode 100644
index 0000000..b24529b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDevice.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDeviceData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDeviceData.c
new file mode 100644
index 0000000..e7fa04a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDeviceData.c
@@ -0,0 +1,36 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscOnboardDeviceData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE_DATA, MiscOnboardDevice) = {

+  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_DESCRIPTION),  // OnBoardDeviceDescription

+  {                             // OnBoardDeviceStatus

+    EfiOnBoardDeviceTypeOther,  // DeviceType

+    0,                          // DeviceEnabled

+    0                           // Reserved

+  },

+  0                             // OnBoardDevicePath

+};

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDeviceFunction.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDeviceFunction.c
new file mode 100644
index 0000000..d96b6cc
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscOnboardDeviceFunction.c
@@ -0,0 +1,164 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscOnboardDeviceFunction.c

+  

+Abstract: 

+

+  Onboard device information boot time changes.

+  Misc. subclass type 8.

+  SMBIOS type 10.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+#include "winntio/winntio.h"

+#include "winntthunk/winntthunk.h"

+

+#pragma pack(1)

+

+typedef struct _VENDOR_DEVICE {

+  EFI_DEVICE_PATH_PROTOCOL  Platform;

+  EFI_GUID                  PlatformGuid;

+  EFI_DEVICE_PATH_PROTOCOL  Device;

+  EFI_GUID                  DeviceGuid;

+  UINT8                     DeviceData[4];

+  EFI_DEVICE_PATH_PROTOCOL  End;

+

+} VENDOR_DEVICE;

+#pragma pack()

+

+MISC_SUBCLASS_TABLE_FUNCTION (

+  MiscOnboardDeviceVideo

+  )

+/*++

+Description:

+

+  This function makes boot time changes to the contents of the

+  MiscOnboardDevice structure.

+

+Parameters:

+

+  RecordType

+    Type of record to be processed from the Data Table.

+    mMiscSubclassDataTable[].RecordType

+

+  RecordLen

+    Size of static RecordData from the Data Table.

+    mMiscSubclassDataTable[].RecordLen

+

+  RecordData

+    Pointer to copy of RecordData from the Data Table.  Changes made

+    to this copy will be written to the Data Hub but will not alter

+    the contents of the static Data Table.

+

+  LogRecordData

+    Set *LogRecordData to TRUE to log RecordData to Data Hub.

+    Set *LogRecordData to FALSE when there is no more data to log.

+

+Returns:

+

+  EFI_SUCCESS

+    All parameters were valid and *RecordData and *LogRecordData have

+    been set.

+

+  EFI_UNSUPPORTED

+    Unexpected RecordType value.

+

+  EFI_INVALID_PARAMETER

+    One of the following parameter conditions was true:

+      RecordLen was zero.

+      RecordData was NULL.

+      LogRecordData was NULL.

+--*/

+{

+  STATIC VENDOR_DEVICE  mVideoDevicePath = {

+    {

+      HARDWARE_DEVICE_PATH,

+      HW_VENDOR_DP,

+      0x14

+    },

+    EFI_WIN_NT_THUNK_PROTOCOL_GUID,

+    {

+      HARDWARE_DEVICE_PATH,

+      HW_VENDOR_DP,

+      0x18

+    },

+    EFI_WIN_NT_UGA_GUID,

+    0,

+    0,

+    0,

+    0,

+    END

+  };

+

+  STATIC BOOLEAN        Done = FALSE;

+

+  //

+  // First check for invalid parameters.

+  //

+  if (RecordLen == 0 || RecordData == NULL || LogRecordData == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Then check for unsupported RecordType.

+  //

+  if (RecordType != EFI_MISC_ONBOARD_DEVICE_DATA_RECORD_NUMBER) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Is this the first time through this function?

+  //

+  if (!Done) {

+    //

+    // Yes, this is the first time.  Inspect/Change the contents of the

+    // RecordData structure.

+    //

+    //

+    // Any time changes?

+    //

+    // %%TBD

+    //

+    // Set Done flag to TRUE for next pass through this function.

+    // Set *LogRecordData to TRUE so data will get logged to Data Hub.

+    //

+    switch (((EFI_MISC_ONBOARD_DEVICE_DATA *) RecordData)->OnBoardDeviceDescription) {

+    case STR_MISC_ONBOARD_DEVICE_VIDEO_DESCRIPTION:

+      {

+        CopyMem (

+          &((EFI_MISC_ONBOARD_DEVICE_DATA *) RecordData)->OnBoardDevicePath,

+          &mVideoDevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mVideoDevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_DEVICE_PATH_PROTOCOL) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mVideoDevicePath);

+      }

+      break;

+    }

+

+    Done            = TRUE;

+    *LogRecordData  = TRUE;

+  } else {

+    //

+    // No, this is the second time.  Reset the state of the Done flag

+    // to FALSE and tell the data logger that there is no more data

+    // to be logged for this record type.  If any memory allocations

+    // were made by earlier passes, they must be released now.

+    //

+    Done            = FALSE;

+    *LogRecordData  = FALSE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/* eof - MiscOnboardDeviceFunction.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignator.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignator.uni
new file mode 100644
index 0000000..b6a617b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignator.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignatorData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignatorData.c
new file mode 100644
index 0000000..d886a9d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignatorData.c
@@ -0,0 +1,99 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscPortInternalConnectorDesignatorData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortInternalConnectorDesignator) = {

+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR),  // PortInternalConnectorDesignator

+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_CONNECTOR_DESIGNATOR),  // PortExternalConnectorDesignator

+  EfiPortConnectorTypeOther,  // PortInternalConnectorType

+  EfiPortConnectorTypeOther,  // PortExternalConnectorType

+  EfiPortTypeNone,            // PortType

+  0                           // PortPath

+};

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortKeyboard) = {

+  STRING_TOKEN (STR_MISC_PORT_INTERNAL_KEYBOARD),   // PortInternalConnectorDesignator

+  STRING_TOKEN (STR_MISC_PORT_EXTERNAL_KEYBOARD),   // PortExternalConnectorDesignator

+  EfiPortConnectorTypeNone, // PortInternalConnectorType

+  EfiPortConnectorTypePS2,  // PortExternalConnectorType

+  EfiPortTypeKeyboard,      // PortType

+  // mPs2KbyboardDevicePath                          // PortPath

+  //

+  0

+};

+

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortMouse) = {

+  STRING_TOKEN (STR_MISC_PORT_INTERNAL_MOUSE),      // PortInternalConnectorDesignator

+  STRING_TOKEN (STR_MISC_PORT_EXTERNAL_MOUSE),      // PortExternalConnectorDesignator

+  EfiPortConnectorTypeNone, // PortInternalConnectorType

+  EfiPortConnectorTypePS2,  // PortExternalConnectorType

+  EfiPortTypeMouse,         // PortType

+  // mPs2MouseDevicePath                // PortPath

+  //

+  0

+};

+

+

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortCom1) = {

+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_COM1),

+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_COM1),

+  EfiPortConnectorTypeNone,

+  EfiPortConnectorTypeDB9Female,

+  EfiPortTypeSerial16550ACompatible,

+  0

+};

+

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortCom2) = {

+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_COM2),

+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_COM2),

+  EfiPortConnectorTypeNone,

+  EfiPortConnectorTypeDB9Female,

+  EfiPortTypeSerial16550ACompatible,

+  0

+};

+

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortExtensionPower) = {

+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_EXTENSION_POWER),

+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_EXTENSION_POWER),

+  EfiPortConnectorTypeOther,

+  EfiPortConnectorTypeNone,

+  EfiPortTypeOther,

+  0

+};

+

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortFloppy) = {

+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_FLOPPY),

+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_FLOPPY),

+  EfiPortConnectorTypeOnboardFloppy,

+  EfiPortConnectorTypeNone,

+  EfiPortTypeOther,

+  0

+};

+

+/* eof - MiscPortInternalConnectorDesignatorData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignatorFunction.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignatorFunction.c
new file mode 100644
index 0000000..a57c18c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscPortInternalConnectorDesignatorFunction.c
@@ -0,0 +1,266 @@
+/*++

+ 

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscPortInternalConnectorDesignatorFunction.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+//

+//

+MISC_SUBCLASS_TABLE_FUNCTION (

+  MiscPortInternalConnectorDesignator

+  )

+/*++

+Description:

+

+  This function makes boot time changes to the contents of the

+  MiscPortConnectorInformation (Type 8).

+

+Parameters:

+

+  RecordType

+    Type of record to be processed from the Data Table.

+    mMiscSubclassDataTable[].RecordType

+

+  RecordLen

+    Size of static RecordData from the Data Table.

+    mMiscSubclassDataTable[].RecordLen

+

+  RecordData

+    Pointer to copy of RecordData from the Data Table.  Changes made

+    to this copy will be written to the Data Hub but will not alter

+    the contents of the static Data Table.

+

+  LogRecordData

+    Set *LogRecordData to TRUE to log RecordData to Data Hub.

+    Set *LogRecordData to FALSE when there is no more data to log.

+

+Returns:

+

+  EFI_SUCCESS

+    All parameters were valid and *RecordData and *LogRecordData have

+    been set.

+

+  EFI_UNSUPPORTED

+    Unexpected RecordType value.

+

+  EFI_INVALID_PARAMETER

+    One of the following parameter conditions was true:

+      RecordLen was zero.

+      RecordData was NULL.

+      LogRecordData was NULL.

+--*/

+{

+  STATIC BOOLEAN                    Done                    = FALSE;

+  STATIC PS2_CONN_DEVICE_PATH       mPs2KeyboardDevicePath  = { ACPI, PCI (0x1F, 0x00), LPC (0x0303, 0), END };

+  STATIC PS2_CONN_DEVICE_PATH       mPs2MouseDevicePath     = { ACPI, PCI (0x1F, 0x00), LPC (0x0303, 1), END };

+  STATIC SERIAL_CONN_DEVICE_PATH    mCom1DevicePath         = { ACPI, PCI (0x1F, 0x00), LPC (0x0501, 0), END };

+  STATIC SERIAL_CONN_DEVICE_PATH    mCom2DevicePath         = { ACPI, PCI (0x1F, 0x00), LPC (0x0501, 1), END };

+  STATIC PARALLEL_CONN_DEVICE_PATH  mLpt1DevicePath         = { ACPI, PCI (0x1F, 0x00), LPC (0x0401, 0), END };

+  STATIC FLOOPY_CONN_DEVICE_PATH    mFloopyADevicePath      = { ACPI, PCI (0x1F, 0x00), LPC (0x0604, 0), END };

+  STATIC FLOOPY_CONN_DEVICE_PATH    mFloopyBDevicePath      = { ACPI, PCI (0x1F, 0x00), LPC (0x0604, 1), END };

+  STATIC USB_PORT_DEVICE_PATH       mUsb0DevicePath         = { ACPI, PCI (0x1d, 0x00), END };

+  STATIC USB_PORT_DEVICE_PATH       mUsb1DevicePath         = { ACPI, PCI (0x1d, 0x01), END };

+  STATIC USB_PORT_DEVICE_PATH       mUsb2DevicePath         = { ACPI, PCI (0x1d, 0x02), END };

+  STATIC USB_PORT_DEVICE_PATH       mUsb3DevicePath         = { ACPI, PCI (0x1d, 0x07), END };

+  STATIC IDE_DEVICE_PATH            mIdeDevicePath          = { ACPI, PCI (0x1F, 0x01), END };

+  STATIC GB_NIC_DEVICE_PATH         mGbNicDevicePath        = { ACPI, PCI( 0x03,0x00 ),PCI( 0x1F,0x00 ),PCI( 0x07,0x00 ), END };

+  EFI_DEVICE_PATH_PROTOCOL          EndDevicePath           = END;

+

+  //

+  // First check for invalid parameters.

+  //

+  // Shanmu >> to fix the Device Path Issue...

+  // if (RecordLen == 0 || RecordData == NULL || LogRecordData == NULL) {

+  //

+  if (*RecordLen == 0 || RecordData == NULL || LogRecordData == NULL) {

+    //

+    // End Shanmu

+    //

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Then check for unsupported RecordType.

+  //

+  if (RecordType != EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Is this the first time through this function?

+  //

+  if (!Done) {

+    //

+    // Yes, this is the first time.  Inspect/Change the contents of the

+    // RecordData structure.

+    //

+    //

+    // Device path is only updated here as it was not taking that in static data

+    //

+    // Shanmu >> to fix the Device Path Issue...

+    //

+

+    /*

+    switch (((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortInternalConnectorDesignator) 

+    {

+      case STR_MISC_PORT_INTERNAL_MOUSE:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mPs2MouseDevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_KEYBOARD:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mPs2KeyboardDevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_COM1:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mCom1DevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_COM2:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mCom2DevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_LPT1:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mLpt1DevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_USB1:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mUsb0DevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_USB2:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mUsb1DevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_USB3:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mUsb2DevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_NETWORK:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mGbNicDevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_FLOPPY:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mFloopyADevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_IDE1:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mIdeDevicePath);          

+        }break;

+      case STR_MISC_PORT_INTERNAL_IDE2:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = *((EFI_DEVICE_PATH_PROTOCOL*)&mIdeDevicePath);          

+        }break;

+      default:

+        {

+          (EFI_DEVICE_PATH_PROTOCOL)((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *)RecordData)->PortPath = EndDevicePath;

+        }break;    

+    }

+    */

+    switch (((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortInternalConnectorDesignator) {

+    case STR_MISC_PORT_INTERNAL_MOUSE:

+      {

+        CopyMem (

+          &((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortPath,

+          &mPs2MouseDevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mPs2MouseDevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_MISC_PORT_DEVICE_PATH) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mPs2MouseDevicePath);

+      }

+      break;

+

+    case STR_MISC_PORT_INTERNAL_KEYBOARD:

+      {

+        CopyMem (

+          &((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortPath,

+          &mPs2KeyboardDevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mPs2KeyboardDevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_MISC_PORT_DEVICE_PATH) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mPs2KeyboardDevicePath);

+      }

+      break;

+

+    case STR_MISC_PORT_INTERNAL_COM1:

+      {

+        CopyMem (

+          &((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortPath,

+          &mCom1DevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mCom1DevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_MISC_PORT_DEVICE_PATH) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mCom1DevicePath);

+      }

+      break;

+

+    case STR_MISC_PORT_INTERNAL_COM2:

+      {

+        CopyMem (

+          &((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortPath,

+          &mCom2DevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mCom2DevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_MISC_PORT_DEVICE_PATH) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mCom2DevicePath);

+      }

+      break;

+

+    case STR_MISC_PORT_INTERNAL_FLOPPY:

+      {

+        CopyMem (

+          &((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortPath,

+          &mFloopyADevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mFloopyADevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_MISC_PORT_DEVICE_PATH) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mFloopyADevicePath);

+      }

+      break;

+

+    default:

+      {

+        CopyMem (

+          &((EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) RecordData)->PortPath,

+          &EndDevicePath,

+          GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &EndDevicePath)

+          );

+        *RecordLen = *RecordLen - sizeof (EFI_MISC_PORT_DEVICE_PATH) + GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &EndDevicePath);

+      }

+      break;

+    }

+    //

+    // End Shanmu

+    //

+    // Set Done flag to TRUE for next pass through this function.

+    // Set *LogRecordData to TRUE so data will get logged to Data Hub.

+    //

+    Done            = TRUE;

+    *LogRecordData  = TRUE;

+  } else {

+    //

+    // No, this is the second time.  Reset the state of the Done flag

+    // to FALSE and tell the data logger that there is no more data

+    // to be logged for this record type.  If any memory allocations

+    // were made by earlier passes, they must be released now.

+    //

+    Done            = FALSE;

+    *LogRecordData  = FALSE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/* eof - MiscSystemManufacturerFunction.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscResetCapabilitiesData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscResetCapabilitiesData.c
new file mode 100644
index 0000000..6e0c1bb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscResetCapabilitiesData.c
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    MiscResetCapabilitiesData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_RESET_CAPABILITIES, MiscResetCapabilities) = {

+  {     // ResetCapabilities

+    0,  // Status

+    0,  // BootOption

+    0,  // BootOptionOnLimit

+    0,  // WatchdogTimerPresent

+    0   // Reserved

+  },

+  0,    // ResetCount

+  0,    // ResetLimit

+  0,    // ResetTimerInterval

+  0     // ResetTimeout

+};

+

+/* eof - MiscResetCapabilities.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.dxs b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.dxs
new file mode 100644
index 0000000..8698317
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSubclassDriver.dxs

+

+Abstract:

+

+  Dependency expression file for MiscSubclass Driver.

+  

+--*/

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_DATA_HUB_PROTOCOL_GUID AND EFI_HII_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.h b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.h
new file mode 100644
index 0000000..32f591f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.h
@@ -0,0 +1,104 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSubclassDriver.h

+

+Abstract:

+

+  Header file for MiscSubclass Driver.

+

+--*/

+

+#ifndef _MISC_SUBCLASS_DRIVER_H

+#define _MISC_SUBCLASS_DRIVER_H

+

+

+#include <MiscDevicePath.h>

+

+//

+// Autogen string file

+//

+#include <MiscSubclassStrDefs.h>

+

+//

+// Data table entry update function.

+//

+typedef 

+EFI_STATUS 

+(EFIAPI EFI_MISC_SUBCLASS_DATA_FUNCTION) (

+  IN UINT16                         RecordType,

+  IN UINT32                         *RecordLen,

+  IN OUT EFI_MISC_SUBCLASS_RECORDS  *RecordData,

+  OUT BOOLEAN                       *LogRecordData

+  );

+

+//

+// Data table entry definition.

+//

+typedef struct {

+  UINT16                          RecordType;

+  UINT32                          RecordLen;

+  VOID                            *RecordData;

+  EFI_MISC_SUBCLASS_DATA_FUNCTION *Function;

+} EFI_MISC_SUBCLASS_DATA_TABLE;

+

+//

+// Data Table extern definitions.

+//

+#define MISC_SUBCLASS_TABLE_EXTERNS(NAME1, NAME2) \

+  extern NAME1 NAME2 ## Data; \

+  extern EFI_MISC_SUBCLASS_DATA_FUNCTION NAME2 ## Function

+

+//

+// Data Table entries

+//

+#define MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(NAME1, NAME2) { \

+	  NAME1 ##  _RECORD_NUMBER, sizeof (NAME1 ## _DATA), &NAME2 ## Data, NULL \

+  }

+

+#define MISC_SUBCLASS_TABLE_ENTRY_FUNCTION_ONLY(NAME1, NAME2) \

+  { \

+    NAME1 ##  _RECORD_NUMBER, 0, NULL, &NAME2 ## Function \

+  }

+

+#define MISC_SUBCLASS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2, NAME3) \

+  { \

+    NAME1 ##  _RECORD_NUMBER, sizeof (NAME1 ## _DATA), &NAME2 ## Data, &NAME3 ## Function \

+  }

+

+//

+// Global definition macros.

+//

+#define MISC_SUBCLASS_TABLE_DATA(NAME1, NAME2)  NAME1 NAME2 ## Data

+

+#define MISC_SUBCLASS_TABLE_FUNCTION(NAME2) \

+  EFI_STATUS EFIAPI NAME2 ## Function ( \

+  IN UINT16 RecordType, \

+  IN UINT32 *RecordLen, \

+  IN OUT EFI_MISC_SUBCLASS_RECORDS * RecordData, \

+  OUT BOOLEAN *LogRecordData \

+  )

+

+//

+// Data Table Array

+//

+extern EFI_MISC_SUBCLASS_DATA_TABLE mMiscSubclassDataTable[];

+

+//

+// Data Table Array Entries

+//

+extern UINTN  mMiscSubclassDataTableEntries;

+

+#endif /* _MISC_SUBCLASS_DRIVER_H */

+

+/* eof - MiscSubclassDriver.h */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.mbd b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.mbd
new file mode 100644
index 0000000..921c5c5
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>MiscSubclass</BaseName>

+    <Guid>4A9B9DB8-EC62-4A92-818F-8AA0246D246E</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:07</Created>

+    <Modified>2006-03-23 13:50</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>HiiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.msa b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.msa
new file mode 100644
index 0000000..3c47d82
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.msa
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>MiscSubclass</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>4A9B9DB8-EC62-4A92-818F-8AA0246D246E</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for MiscSubclass Driver module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:07</Created>

+    <Updated>2006-03-23 13:50</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MiscSubclassDriver.uni</Filename>

+    <Filename>MiscSubclassDriver.h</Filename>

+    <Filename>MiscSubclassDriverEntryPoint.c</Filename>

+    <Filename>MiscSubclassDriverDataTable.c</Filename>

+    <Filename>MiscBaseBoardManufacturerData.c</Filename>

+    <Filename>MiscBiosVendorData.c</Filename>

+    <Filename>MiscBootInformationData.c</Filename>

+    <Filename>MiscChassisManufacturerData.c</Filename>

+    <Filename>MiscNumberOfInstallableLanguagesData.c</Filename>

+    <Filename>MiscOemStringData.c</Filename>

+    <Filename>MiscOnboardDeviceData.c</Filename>

+    <Filename>MiscPortInternalConnectorDesignatorData.c</Filename>

+    <Filename>MiscResetCapabilitiesData.c</Filename>

+    <Filename>MiscSystemLanguageStringData.c</Filename>

+    <Filename>MiscSystemManufacturerData.c</Filename>

+    <Filename>MiscSystemManufacturerFunction.c</Filename>

+    <Filename>MiscSystemOptionStringData.c</Filename>

+    <Filename>MiscSystemSlotDesignationData.c</Filename>

+    <Filename>MiscPortInternalConnectorDesignatorFunction.c</Filename>

+    <Filename>MiscSubclassDriver.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DataHub</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>

+    <ProtocolNotify Usage="SOMETIMES_CONSUMED">WinNtIo</ProtocolNotify>

+  </Protocols>

+  <DataHubs>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscPortKeyboard</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscPortMouse</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscPortCom1</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscPortCom2</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscBiosVendor</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscSystemManufacturer</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscBaseBoardManufacturer</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscChassisManufacturer</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">MiscSystemSlotDesignation</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">OemString</DataHubRecord>

+    <DataHubRecord Usage="ALWAYS_PRODUCED">SystemOptionString</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">ProcessorSubClassData</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_PRODUCED">MemorySubClassData</DataHubRecord>

+  </DataHubs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>MiscSubClass</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>ProcessorSubClass</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>MemoryProducer</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>MemorySubClass</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>WinNtMemory</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>MiscSubclassDriverEntryPoint</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.uni
new file mode 100644
index 0000000..1d6899c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriverDataTable.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriverDataTable.c
new file mode 100644
index 0000000..c2d1496
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriverDataTable.c
@@ -0,0 +1,103 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSubclassDriverDataTable.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// External definitions referenced by Data Table entries.

+//

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_CHASSIS_MANUFACTURER_DATA,

+  MiscChassisManufacturer

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_BIOS_VENDOR_DATA,

+  MiscBiosVendor

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_SYSTEM_MANUFACTURER_DATA,

+  MiscSystemManufacturer

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_BASE_BOARD_MANUFACTURER_DATA,

+  MiscBaseBoardManufacturer

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA,

+  MiscPortInternalConnectorDesignator

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA,

+  MiscPortKeyboard

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA,

+  MiscPortMouse

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA,

+  MiscPortCom1

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA,

+  MiscPortCom2

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA,

+  MiscSystemSlotDesignation

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_ONBOARD_DEVICE_DATA,

+  MiscOnboardDevice

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_OEM_STRING_DATA,

+  OemString

+  );

+MISC_SUBCLASS_TABLE_EXTERNS (

+  EFI_MISC_SYSTEM_OPTION_STRING_DATA,

+  SystemOptionString

+  );

+

+//

+// Data Table.

+//

+EFI_MISC_SUBCLASS_DATA_TABLE  mMiscSubclassDataTable[] = {

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_AND_FUNCTION(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortKeyboard, MiscPortInternalConnectorDesignator),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_AND_FUNCTION(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortMouse, MiscPortInternalConnectorDesignator),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_AND_FUNCTION(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortCom1, MiscPortInternalConnectorDesignator),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_AND_FUNCTION(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortCom2, MiscPortInternalConnectorDesignator),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_BIOS_VENDOR, MiscBiosVendor),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_SYSTEM_MANUFACTURER, MiscSystemManufacturer),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_BASE_BOARD_MANUFACTURER, MiscBaseBoardManufacturer),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_CHASSIS_MANUFACTURER, MiscChassisManufacturer),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlotDesignation),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_OEM_STRING, OemString),

+  MISC_SUBCLASS_TABLE_ENTRY_DATA_ONLY(EFI_MISC_SYSTEM_OPTION_STRING, SystemOptionString),

+};

+

+//

+// Number of Data Table entries.

+//

+UINTN mMiscSubclassDataTableEntries = (sizeof mMiscSubclassDataTable) / sizeof (EFI_MISC_SUBCLASS_DATA_TABLE);

+

+/* eof - MiscSubclassDriverDataTable.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriverEntryPoint.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriverEntryPoint.c
new file mode 100644
index 0000000..f0e09a6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriverEntryPoint.c
@@ -0,0 +1,518 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSubclassDriverEntryPoint.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+

+extern UINT8  MiscSubclassStrings[];

+

+VOID

+EFIAPI

+WinNtIoProtocolNotifyFunction (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  );

+

+//

+//

+//

+EFI_STATUS

+LogRecordDataToDataHub (

+  EFI_DATA_HUB_PROTOCOL *DataHub,

+  UINT32                RecordType,

+  UINT32                RecordLen,

+  VOID                  *RecordData

+  )

+/*++

+Description:

+

+Parameters:

+

+  DataHub

+    %%TBD

+

+  RecordType

+    %%TBD

+

+  RecordLen

+    %%TBD

+

+  RecordData

+    %%TBD

+

+Returns:

+

+  EFI_INVALID_PARAMETER

+

+  EFI_SUCCESS

+

+  Other Data Hub errors

+

+--*/

+{

+  EFI_MISC_SUBCLASS_DRIVER_DATA MiscSubclass;

+  EFI_STATUS                    EfiStatus;

+

+  //

+  // Do nothing if data parameters are not valid.

+  //

+  if (RecordLen == 0 || RecordData == NULL) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "RecordLen == %d  RecordData == %xh\n",

+      RecordLen,

+      RecordData)

+      );

+

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Assemble Data Hub record.

+  //

+  MiscSubclass.Header.Version     = EFI_MISC_SUBCLASS_VERSION;

+  MiscSubclass.Header.HeaderSize  = sizeof (EFI_SUBCLASS_TYPE1_HEADER);

+  MiscSubclass.Header.Instance    = 1;

+  MiscSubclass.Header.SubInstance = 1;

+  MiscSubclass.Header.RecordType  = RecordType;

+

+  CopyMem (

+    &MiscSubclass.Record,

+    RecordData,

+    RecordLen

+    );

+

+  //

+  // Log Data Hub record.

+  //

+  EfiStatus = DataHub->LogData (

+                        DataHub,

+                        &gEfiMiscSubClassGuid,

+                        &gEfiMiscSubClassGuid,

+                        EFI_DATA_RECORD_CLASS_DATA,

+                        &MiscSubclass,

+                        sizeof (EFI_SUBCLASS_TYPE1_HEADER) + RecordLen

+                        );

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG (

+      (EFI_D_ERROR,

+      "LogData(%d bytes) == %r\n",

+      sizeof (EFI_SUBCLASS_TYPE1_HEADER) + RecordLen,

+      EfiStatus)

+      );

+  }

+

+  return EfiStatus;

+}

+

+

+EFI_STATUS

+EFIAPI

+MiscSubclassDriverEntryPoint (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+Description:

+

+  Standard EFI driver point.  This driver parses the mMiscSubclassDataTable

+  structure and reports any generated data to the DataHub.

+

+Arguments:

+

+  ImageHandle

+    Handle for the image of this driver

+

+  SystemTable

+    Pointer to the EFI System Table

+

+Returns:

+

+  EFI_SUCCESS

+    The data was successfully reported to the Data Hub.

+

+--*/

+{

+  EFI_MISC_SUBCLASS_DRIVER_DATA RecordData;

+  EFI_DATA_HUB_PROTOCOL         *DataHub;

+  EFI_HII_PROTOCOL              *Hii;

+  EFI_HII_PACKAGES              *PackageList;

+  EFI_HII_HANDLE                HiiHandle;

+  EFI_STATUS                    EfiStatus;

+  UINTN                         Index;

+  BOOLEAN                       LogRecordData;

+  EFI_EVENT                     Event;

+  VOID                          *Registration;

+

+

+  //

+  // Initialize constant portion of subclass header.

+  //

+  RecordData.Header.Version     = EFI_MISC_SUBCLASS_VERSION;

+  RecordData.Header.HeaderSize  = sizeof (EFI_SUBCLASS_TYPE1_HEADER);

+  RecordData.Header.Instance    = 1;

+  RecordData.Header.SubInstance = 1;

+

+  //

+  // Locate data hub protocol.

+  //

+  EfiStatus = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG ((EFI_D_ERROR, "Could not locate DataHub protocol.  %r\n", EfiStatus));

+    return EfiStatus;

+  } else if (DataHub == NULL) {

+    DEBUG ((EFI_D_ERROR, "LocateProtocol(DataHub) returned NULL pointer!\n"));

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Locate hii protocol.

+  //

+  EfiStatus = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG ((EFI_D_ERROR, "Could not locate Hii protocol.  %r\n", EfiStatus));

+    return EfiStatus;

+  } else if (Hii == NULL) {

+    DEBUG ((EFI_D_ERROR, "LocateProtocol(Hii) returned NULL pointer!\n"));

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Add our default strings to the HII database. They will be modified later.

+  //

+  PackageList = PreparePackages (1, &gEfiMiscSubClassGuid, MiscSubclassStrings);

+  EfiStatus   = Hii->NewPack (Hii, PackageList, &HiiHandle);

+  gBS->FreePool (PackageList);

+

+  if (EFI_ERROR (EfiStatus)) {

+    DEBUG ((EFI_D_ERROR, "Could not log default strings to Hii.  %r\n", EfiStatus));

+    return EfiStatus;

+  }

+  //

+  //

+  //

+  for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {

+    //

+    // Stupidity check!  Do nothing if RecordLen is zero.

+    // %%TBD - Should this be an error or a mechanism for ignoring

+    // records in the Data Table?

+    //

+    if (mMiscSubclassDataTable[Index].RecordLen == 0) {

+      DEBUG (

+        (EFI_D_ERROR,

+        "mMiscSubclassDataTable[%d].RecordLen == 0\n",

+        Index)

+        );

+

+      continue;

+    }

+    //

+    // Initialize per-record portion of subclass header and

+    // copy static data into data portion of subclass record.

+    //

+    RecordData.Header.RecordType = mMiscSubclassDataTable[Index].RecordType;

+

+    if (mMiscSubclassDataTable[Index].RecordData == NULL) {

+      ZeroMem (

+        &RecordData.Record,

+        mMiscSubclassDataTable[Index].RecordLen

+        );

+    } else {

+      CopyMem (

+        &RecordData.Record,

+        mMiscSubclassDataTable[Index].RecordData,

+        mMiscSubclassDataTable[Index].RecordLen

+        );

+    }

+    //

+    // If the entry does not have a function pointer, just log the data.

+    //

+    if (mMiscSubclassDataTable[Index].Function == NULL) {

+      //

+      // Log RecordData to Data Hub.

+      //

+      EfiStatus = DataHub->LogData (

+                            DataHub,

+                            &gEfiMiscSubClassGuid,

+                            &gEfiMiscSubClassGuid,

+                            EFI_DATA_RECORD_CLASS_DATA,

+                            &RecordData,

+                            sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen

+                            );

+

+      if (EFI_ERROR (EfiStatus)) {

+        DEBUG (

+          (EFI_D_ERROR,

+          "LogData(%d bytes) == %r\n",

+          sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,

+          EfiStatus)

+          );

+      }

+

+      continue;

+    }

+    //

+    // The entry has a valid function pointer.

+    // Keep calling the function and logging data until there

+    // is no more data to log.

+    //

+    for (;;) {

+      //

+      //

+      //

+      EfiStatus = (*mMiscSubclassDataTable[Index].Function)

+        (

+          mMiscSubclassDataTable[Index].RecordType, &mMiscSubclassDataTable[Index].RecordLen, &RecordData.Record, &

+            LogRecordData

+        );

+

+      //

+      //

+      //

+      if (EFI_ERROR (EfiStatus)) {

+        break;

+      }

+

+      if (!LogRecordData) {

+        break;

+      }

+      //

+      //

+      //

+      EfiStatus = DataHub->LogData (

+                            DataHub,

+                            &gEfiMiscSubClassGuid,

+                            &gEfiMiscSubClassGuid,

+                            EFI_DATA_RECORD_CLASS_DATA,

+                            &RecordData,

+                            sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen

+                            );

+

+      if (EFI_ERROR (EfiStatus)) {

+        DEBUG (

+          (EFI_D_ERROR,

+          "LogData(%d bytes) == %r\n",

+          sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,

+          EfiStatus)

+          );

+      }

+    }

+  }

+  //

+  // Install notify function to fetch memory data through WinNtIo protocol and store to data hub.

+  //

+  EfiStatus = gBS->CreateEvent (

+                    EFI_EVENT_NOTIFY_SIGNAL,

+                    EFI_TPL_CALLBACK,

+                    WinNtIoProtocolNotifyFunction,

+                    ImageHandle,

+                    &Event

+                    );

+  ASSERT (!EFI_ERROR (EfiStatus));

+

+  EfiStatus = gBS->RegisterProtocolNotify (

+                    &gEfiWinNtIoProtocolGuid,

+                    Event,

+                    &Registration

+                    );

+  ASSERT (!EFI_ERROR (EfiStatus));

+

+  return EFI_SUCCESS;

+}

+

+UINTN

+Atoi (

+  CHAR16  *String

+  )

+/*++

+

+Routine Description:

+  Convert a unicode string to a UINTN

+

+Arguments:

+  String - Unicode string.

+

+Returns: 

+  UINTN of the number represented by String.  

+

+--*/

+{

+  UINTN   Number;

+  CHAR16  *Str;

+

+  //

+  // skip preceeding white space

+  //

+  Str = String;

+  while ((*Str) && (*Str == ' ' || *Str == '"')) {

+    Str++;

+  }

+  //

+  // Convert ot a Number

+  //

+  Number = 0;

+  while (*Str != '\0') {

+    if ((*Str >= '0') && (*Str <= '9')) {

+      Number = (Number * 10) +*Str - '0';

+    } else {

+      break;

+    }

+

+    Str++;

+  }

+

+  return Number;

+}

+

+VOID

+EFIAPI

+WinNtIoProtocolNotifyFunction (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  )

+/*++

+

+Routine Description:

+  This function will log memory size data to data hub.

+

+Arguments:

+Event        - Event whose notification function is being invoked.

+Context      - Pointer to the notification function's context.

+

+Returns:

+    EFI_STATUS.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData;

+  EFI_DATA_RECORD_HEADER          *Record;

+  EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;

+  UINTN                           HandleCount;

+  UINTN                           HandleIndex;

+  UINT64                          MonotonicCount;

+  BOOLEAN                         RecordFound;

+  EFI_HANDLE                      *HandleBuffer;

+  EFI_WIN_NT_IO_PROTOCOL          *WinNtIo;

+  EFI_DATA_HUB_PROTOCOL           *DataHub;

+  UINT64                          TotalMemorySize;

+

+  DataHub         = NULL;

+  MonotonicCount  = 0;

+  RecordFound     = FALSE;

+

+  //

+  // Retrieve the list of all handles from the handle database.

+  //

+  Status = gBS->LocateHandleBuffer (

+                  AllHandles,

+                  &gEfiWinNtIoProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+  //

+  // Locate DataHub protocol.

+  //

+  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+  //

+  // Search the Handle array to find the meory size information.

+  //

+  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {

+    Status = gBS->OpenProtocol (

+                    HandleBuffer[HandleIndex],

+                    &gEfiWinNtIoProtocolGuid,

+                    &WinNtIo,

+                    Context,

+                    NULL,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&

+        CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtMemoryGuid)

+          ) {

+      //

+      // Check if this record has been stored in data hub.

+      //

+      do {

+        Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);

+        if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {

+          DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);

+          if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&

+              (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)

+              ) {

+            RecordFound = TRUE;

+          }

+        }

+      } while (MonotonicCount != 0);

+

+      if (RecordFound) {

+        RecordFound = FALSE;

+        continue;

+      }

+      //

+      // Initialize data record.

+      //

+      MemorySubClassData.Header.Instance    = 1;

+      MemorySubClassData.Header.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;

+      MemorySubClassData.Header.RecordType  = EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER;

+

+      TotalMemorySize                       = (UINT64) Atoi (WinNtIo->EnvString);

+

+      MemorySubClassData.Record.ArrayStartAddress.MemoryArrayStartAddress               = 0;

+      MemorySubClassData.Record.ArrayStartAddress.MemoryArrayEndAddress                 = LShiftU64 (TotalMemorySize, 20) - 1;

+      MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.ProducerName  = gEfiMemoryProducerGuid;

+      MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.Instance      = 1;

+      MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;

+      MemorySubClassData.Record.ArrayStartAddress.MemoryArrayPartitionWidth = 0;

+

+      //

+      // Store memory size data record to data hub.

+      //

+      Status = DataHub->LogData (

+                          DataHub,

+                          &gEfiMemorySubClassGuid,

+                          &gEfiMemoryProducerGuid,

+                          EFI_DATA_RECORD_CLASS_DATA,

+                          &MemorySubClassData,

+                          sizeof (EFI_SUBCLASS_TYPE1_HEADER) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS_DATA)

+                          );

+    }

+

+    gBS->CloseProtocol (

+          HandleBuffer[HandleIndex],

+          &gEfiWinNtIoProtocolGuid,

+          Context,

+          NULL

+          );

+  }

+}

+

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemLanguageString.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemLanguageString.uni
new file mode 100644
index 0000000..36dacf0
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemLanguageString.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemLanguageStringData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemLanguageStringData.c
new file mode 100644
index 0000000..ef52513
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemLanguageStringData.c
@@ -0,0 +1,33 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSystemLanguageStringData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA, SystemLanguageString) = {

+  0,

+  STRING_TOKEN(STR_MISC_SYSTEM_LANGUAGE_STRING)

+};

+

+/* eof - MiscSystemLanguageStringData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturer.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturer.uni
new file mode 100644
index 0000000..204588e
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturer.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturerData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturerData.c
new file mode 100644
index 0000000..be53e39
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturerData.c
@@ -0,0 +1,55 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSystemManufacturerData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) System Manufacturer data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_SYSTEM_MANUFACTURER_DATA, MiscSystemManufacturer)

+= {

+  STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER),

+  // SystemManufactrurer

+  STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME),

+  // SystemProductName

+  STRING_TOKEN(STR_MISC_SYSTEM_VERSION),

+  // SystemVersion

+  STRING_TOKEN(STR_MISC_SYSTEM_SERIAL_NUMBER),

+  // SystemSerialNumber

+  {

+    0xbadfaced,

+    0xdead,

+    0xbeef,

+    0x13,

+    0x13,

+    0x13,

+    0x13,

+    0x13,

+    0x13,

+    0x13,

+    0x13

+  },

+  // SystemUuid

+  EfiSystemWakeupTypePowerSwitch  // SystemWakeupType

+};

+

+/* eof - MiscSystemManufacturerData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturerFunction.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturerFunction.c
new file mode 100644
index 0000000..ddd749b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemManufacturerFunction.c
@@ -0,0 +1,122 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSystemManufacturerFunction.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+//

+//

+MISC_SUBCLASS_TABLE_FUNCTION (

+  MiscSystemManufacturer

+  )

+/*++

+Description:

+

+  This function makes boot time changes to the contents of the

+  MiscSystemManufacturer (Type 13).

+

+Parameters:

+

+  RecordType

+    Type of record to be processed from the Data Table.

+    mMiscSubclassDataTable[].RecordType

+

+  RecordLen

+    Size of static RecordData from the Data Table.

+    mMiscSubclassDataTable[].RecordLen

+

+  RecordData

+    Pointer to copy of RecordData from the Data Table.  Changes made

+    to this copy will be written to the Data Hub but will not alter

+    the contents of the static Data Table.

+

+  LogRecordData

+    Set *LogRecordData to TRUE to log RecordData to Data Hub.

+    Set *LogRecordData to FALSE when there is no more data to log.

+

+Returns:

+

+  EFI_SUCCESS

+    All parameters were valid and *RecordData and *LogRecordData have

+    been set.

+

+  EFI_UNSUPPORTED

+    Unexpected RecordType value.

+

+  EFI_INVALID_PARAMETER

+    One of the following parameter conditions was true:

+      RecordLen was zero.

+      RecordData was NULL.

+      LogRecordData was NULL.

+--*/

+{

+  STATIC BOOLEAN  Done = FALSE;

+

+  //

+  // First check for invalid parameters.

+  //

+  if (*RecordLen == 0 || RecordData == NULL || LogRecordData == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Then check for unsupported RecordType.

+  //

+  if (RecordType != EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Is this the first time through this function?

+  //

+  if (!Done) {

+    //

+    // Yes, this is the first time.  Inspect/Change the contents of the

+    // RecordData structure.

+    //

+    //

+    // Set system GUID.

+    //

+    // ((EFI_MISC_SYSTEM_MANUFACTURER_DATA *)RecordData)->SystemUuid = %%TBD

+    //

+    // Set power-on type.

+    //

+    // ((EFI_MISC_SYSTEM_MANUFACTURER_DATA *)RecordData)->SystemWakeupType = %%TBD

+    //

+    // Set Done flag to TRUE for next pass through this function.

+    // Set *LogRecordData to TRUE so data will get logged to Data Hub.

+    //

+    Done            = TRUE;

+    *LogRecordData  = TRUE;

+  } else {

+    //

+    // No, this is the second time.  Reset the state of the Done flag

+    // to FALSE and tell the data logger that there is no more data

+    // to be logged for this record type.  If any memory allocations

+    // were made by earlier passes, they must be released now.

+    //

+    Done            = FALSE;

+    *LogRecordData  = FALSE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/* eof - MiscSystemManufacturerFunction.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemOptionString.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemOptionString.uni
new file mode 100644
index 0000000..617578d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemOptionString.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemOptionStringData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemOptionStringData.c
new file mode 100644
index 0000000..8c00350
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemOptionStringData.c
@@ -0,0 +1,32 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MiscSystemOptionStringData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_SYSTEM_OPTION_STRING_DATA, SystemOptionString) = {

+  STRING_TOKEN(STR_MISC_SYSTEM_OPTION_STRING)

+};

+

+/* eof - MiscSystemOptionStringData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemSlotDesignation.uni b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemSlotDesignation.uni
new file mode 100644
index 0000000..f279ff9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemSlotDesignation.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemSlotDesignationData.c b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemSlotDesignationData.c
new file mode 100644
index 0000000..d5e1474
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/MiscSystemSlotDesignationData.c
@@ -0,0 +1,52 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    MiscSystemSlotDesignationData.c

+  

+Abstract: 

+

+  This driver parses the mMiscSubclassDataTable structure and reports

+  any generated data to the DataHub.

+

+--*/

+

+#include "MiscSubclassDriver.h"

+

+//

+// Static (possibly build generated) Bios Vendor data.

+//

+MISC_SUBCLASS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotDesignation) = {

+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_DESIGNATION),   // SlotDesignation

+  EfiSlotTypeOther,         // SlotType

+  EfiSlotDataBusWidthOther, // SlotDataBusWidth

+  EfiSlotUsageOther,        // SlotUsage

+  EfiSlotLengthOther,       // SlotLength

+  0,                        // SlotId

+  {                         // SlotCharacteristics

+    0,                      // CharacteristicsUnknown  :1;

+    0,                      // Provides50Volts         :1;

+    0,                      // Provides33Volts         :1;

+    0,                      // SharedSlot              :1;

+    0,                      // PcCard16Supported       :1;

+    0,                      // CardBusSupported        :1;

+    0,                      // ZoomVideoSupported      :1;

+    0,                      // ModemRingResumeSupported:1;

+    0,                      // PmeSignalSupported      :1;

+    0,                      // HotPlugDevicesSupported :1;

+    0,                      // SmbusSignalSupported    :1;

+    0                       // Reserved                :21;

+  },

+  0                         // SlotDevicePath

+};

+

+/* eof - MiscSystemSlotsData.c */

diff --git a/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/build.xml b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/build.xml
new file mode 100644
index 0000000..7265194
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/Nt32Platform/MiscSubclass/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="MiscSubclass"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\Nt32Platform\MiscSubclass"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="MiscSubclass">

+      <GenBuild baseName="MiscSubclass" mbdFilename="${MODULE_DIR}\MiscSubclassDriver.mbd" msaFilename="${MODULE_DIR}\MiscSubclassDriver.msa"/>

+   </target>

+   <target depends="MiscSubclass_clean" name="clean"/>

+   <target depends="MiscSubclass_cleanall" name="cleanall"/>

+   <target name="MiscSubclass_clean">

+      <OutputDirSetup baseName="MiscSubclass" mbdFilename="${MODULE_DIR}\MiscSubclassDriver.mbd" msaFilename="${MODULE_DIR}\MiscSubclassDriver.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\MiscSubclass_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\MiscSubclass_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="MiscSubclass_cleanall">

+      <OutputDirSetup baseName="MiscSubclass" mbdFilename="${MODULE_DIR}\MiscSubclassDriver.mbd" msaFilename="${MODULE_DIR}\MiscSubclassDriver.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\MiscSubclass_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\MiscSubclass_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**MiscSubclass*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.c b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.c
new file mode 100644
index 0000000..38863b8
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.c
@@ -0,0 +1,557 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PcdEmulator.c

+

+Abstract:

+  Platform Configuration Database (PCD) Protocol

+

+--*/

+

+#include <PcdEmulator.h>

+

+UINTN                    mSkuId = 0;

+

+STATIC UINTN 

+GetPcdDataEntryCount (

+	VOID

+) {

+	return gEmulatedPcdDatabaseEx->Count;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetSku (

+  IN  UINTN             SkuId

+  )

+{

+  mSkuId = SkuId;

+  return EFI_SUCCESS;

+}

+

+UINT8

+EFIAPI

+PcdEmulatorGet8 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 1);

+

+  return (UINT8)Pcd->Datum;

+}

+

+UINT16

+EFIAPI

+PcdEmulatorGet16 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 2);

+

+  return (UINT16)Pcd->Datum;

+}

+

+UINT32

+EFIAPI

+PcdEmulatorGet32 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 4);

+

+  return (UINT32)Pcd->Datum;

+}

+

+UINT64

+EFIAPI

+PcdEmulatorGet64 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == sizeof (UINT64));

+

+  return (UINT64)Pcd->Datum;

+}

+

+VOID *

+EFIAPI

+PcdEmulatorGetPtr (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  return (VOID *)(UINTN)Pcd->ExtendedData;

+}

+

+BOOLEAN

+EFIAPI

+PcdEmulatorGetBoolean (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 1);

+

+  return (BOOLEAN)Pcd->Datum;

+}

+

+UINTN

+EFIAPI

+PcdEmulatorGetSize (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  return Pcd->DatumSize;

+}

+

+UINT8

+EFIAPI

+PcdEmulatorGet8Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINT16

+EFIAPI

+PcdEmulatorGet16Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINT32

+EFIAPI

+PcdEmulatorGet32Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINT64

+EFIAPI

+PcdEmulatorGet64Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+VOID *

+EFIAPI

+PcdEmulatorGetPtrEx (

+  IN  CONST EFI_GUID    *PcdDataBaseName,

+  IN  UINTN             TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+BOOLEAN

+EFIAPI

+PcdEmulatorGetBooleanEx (

+  IN  CONST EFI_GUID    *PcdDataBaseName,

+  IN  UINTN             TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINTN

+EFIAPI

+PcdEmulatorGetSizeEx (

+  IN  CONST EFI_GUID    *PcdDataBaseName,

+  IN  UINTN             TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  return Pcd->DatumSize;

+}

+

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet8 (

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{  

+

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  ASSERT (Pcd->DatumSize == sizeof (UINT8));

+

+  Pcd->Datum = Value;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet16 (

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet32 (

+  IN UINTN              TokenNumber,

+  IN UINT32             Value

+  )

+{  

+

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  ASSERT (Pcd->DatumSize == sizeof (UINT32));

+

+  Pcd->Datum = Value;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet64 (

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetPtr (

+  IN UINTN             TokenNumber,

+  IN CONST VOID        *Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetBoolean (

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet8Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet16Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet32Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT32             Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet64Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetPtrEx (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN CONST VOID        *Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetBooleanEx (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorCallBackOnSet (

+  IN  UINTN               TokenNumber,

+  IN  CONST EFI_GUID      *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK  CallBackFunction

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  if (Pcd->CallBackListSize == Pcd->CallBackEntries) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Pcd->CallBackList[Pcd->CallBackEntries++] = CallBackFunction;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorUnregisterCallBackOnSet (

+  IN  UINTN                         TokenNumber,

+  IN  CONST EFI_GUID                *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK         CallBackfunction

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+  UINT32                 Index;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  for (Index = 0; Index < Pcd->CallBackListSize; Index++) {

+    if (Pcd->CallBackList[Index] == CallBackfunction) {

+      Pcd->CallBackList[Index] = NULL;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorGetNextToken (

+  IN  CONST EFI_GUID      *Guid, OPTIONAL

+  IN  UINTN    *Token

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+  EMULATED_PCD_ENTRY_EX  *LastPcdEntry;

+

+  if (*Token == PCD_INVALID_TOKEN) {

+    //

+    // BugBug: Due to variable size array, ensure we convert this to a reasonable database

+    //         that can accomodate array references for simplicity's sake

+    *Token = gEmulatedPcdEntryEx[0].Token;

+    return EFI_SUCCESS;

+  }

+

+  Pcd = GetPcdEntry (*Token);

+  if (Pcd == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  LastPcdEntry = gEmulatedPcdEntryEx + GetPcdDataEntryCount ();

+  if (++Pcd >= LastPcdEntry) {

+    return EFI_NOT_FOUND;

+  }

+  

+  *Token = Pcd->Token;

+  return EFI_SUCCESS;

+}

+

+PCD_PROTOCOL mPcdProtocolInstance = {

+  PcdEmulatorSetSku,

+

+  PcdEmulatorGet8,

+  PcdEmulatorGet16,          

+  PcdEmulatorGet32,          

+  PcdEmulatorGet64,          

+  PcdEmulatorGetPtr,         

+  PcdEmulatorGetBoolean,     

+  PcdEmulatorGetSize,

+

+  PcdEmulatorGet8Ex,

+  PcdEmulatorGet16Ex,          

+  PcdEmulatorGet32Ex,          

+  PcdEmulatorGet64Ex,          

+  PcdEmulatorGetPtrEx,         

+  PcdEmulatorGetBooleanEx,     

+  PcdEmulatorGetSizeEx,

+  

+  PcdEmulatorSet8,

+  PcdEmulatorSet16,          

+  PcdEmulatorSet32,          

+  PcdEmulatorSet64,          

+  PcdEmulatorSetPtr,         

+  PcdEmulatorSetBoolean,     

+

+  PcdEmulatorSet8Ex,

+  PcdEmulatorSet16Ex,          

+  PcdEmulatorSet32Ex,          

+  PcdEmulatorSet64Ex,          

+  PcdEmulatorSetPtrEx,         

+  PcdEmulatorSetBooleanEx,     

+

+  PcdEmulatorCallBackOnSet,

+  PcdEmulatorUnregisterCallBackOnSet,

+  PcdEmulatorGetNextToken

+};

+

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorEntry (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+  EFI_HOB_GUID_TYPE       *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gPcdHobGuid);

+  gEmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) GET_GUID_HOB_DATA(GuidHob);

+  ASSERT (gEmulatedPcdDatabaseEx != NULL);

+  gEmulatedPcdEntryEx = gEmulatedPcdDatabaseEx->Entry;

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ImageHandle,

+                  &gPcdProtocolGuid, &mPcdProtocolInstance,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+  return Status;

+}

+

+

+EMULATED_PCD_ENTRY_EX *

+GetPcdEntry (

+  IN      UINTN    TokenNumber

+  )

+{

+  UINTN Index;

+  UINTN Count;

+

+  Count = GetPcdDataEntryCount ();

+  for (Index = 0; Index < Count; Index++) {

+    if (gEmulatedPcdEntryEx[Index].Token == TokenNumber) {

+      return &gEmulatedPcdEntryEx[Index];

+    }

+  }

+  return NULL;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.dxs b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.dxs
new file mode 100644
index 0000000..9e814a6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PcdEmulator.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.h b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.h
new file mode 100644
index 0000000..b49afb1
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.h
@@ -0,0 +1,43 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PcdEmulator.h

+

+Abstract:

+  Platform Configuration Database (PCD) 

+

+--*/

+

+#ifndef __PCD_EMULATOR_H__

+#define __PCD_EMULATOR_H__

+

+

+

+//

+// BugBug: Not very sure, where to put this "extern"

+//

+extern GUID gPcdHobGuid;

+

+//

+// BugBug: Hack max number of callbacks per token

+//

+#define MAX_PCD_CALLBACK  0x10

+

+EMULATED_PCD_ENTRY_EX     *gEmulatedPcdEntryEx;

+EMULATED_PCD_DATABASE_EX     *gEmulatedPcdDatabaseEx;

+

+EMULATED_PCD_ENTRY_EX *

+GetPcdEntry (

+  IN      UINTN    TokenNumber

+  );

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.mbd b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.mbd
new file mode 100644
index 0000000..9300069
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PcdEmulator</BaseName>

+    <Guid>80CF7257-87AB-47f9-A3FE-D50B76D89541</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>UefiLib</Library>

+    <Library>HiiLib</Library>

+    <Library>DxeWinNtLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.msa b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.msa
new file mode 100644
index 0000000..9ec3834
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/PcdEmulator.msa
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PcdEmulator</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>80CF7257-87AB-47f9-A3FE-D50B76D89541</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DxeIpl module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PcdEmulator.c</Filename>

+    <Filename>PcdEmulator.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Pcd</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="ALWAYS_CONSUMED" HobType="GUID_EXTENSION">

+      <Name>PcdDataBase</Name>

+      <C_Name>gPcdHobGuid</C_Name>

+      <Guid>0x582e7ca1, 0x68cd, 0x4d44, 0xb4, 0x3b, 0xf2, 0x98, 0xed, 0x58, 0x7b, 0xa6</Guid>

+    </Hob>

+  </Hobs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PcdHob</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PcdEmulatorEntry</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/PcdEmulator/build.xml b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/build.xml
new file mode 100644
index 0000000..603876b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PcdEmulator/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PcdEmulator"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\PcdEmulator"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="PcdEmulator">

+      <GenBuild baseName="PcdEmulator" mbdFilename="${MODULE_DIR}\PcdEmulator.mbd" msaFilename="${MODULE_DIR}\PcdEmulator.msa"/>

+   </target>

+   <target depends="PcdEmulator_clean" name="clean"/>

+   <target depends="PcdEmulator_cleanall" name="cleanall"/>

+   <target name="PcdEmulator_clean">

+      <OutputDirSetup baseName="PcdEmulator" mbdFilename="${MODULE_DIR}\PcdEmulator.mbd" msaFilename="${MODULE_DIR}\PcdEmulator.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\PcdEmulator_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\PcdEmulator_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PcdEmulator_cleanall">

+      <OutputDirSetup baseName="PcdEmulator" mbdFilename="${MODULE_DIR}\PcdEmulator.mbd" msaFilename="${MODULE_DIR}\PcdEmulator.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\PcdEmulator_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\PcdEmulator_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PcdEmulator*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/BdsPlatform.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/BdsPlatform.c
new file mode 100644
index 0000000..d1edef3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/BdsPlatform.c
@@ -0,0 +1,517 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsPlatform.c

+

+Abstract:

+

+  This file include all platform action which can be customized

+  by IBV/OEM.

+

+--*/

+

+#include "Generic/Bds.h"

+#include "BdsPlatform.h"

+#include "Generic/String.h"

+#include "Generic/Language.h"

+#include "Generic/FrontPage.h"

+

+CHAR16  mFirmwareVendor[] = L"TianoCore.org";

+

+//

+// BDS Platform Functions

+//

+VOID

+PlatformBdsInit (

+  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData

+  )

+/*++

+

+Routine Description:

+

+  Platform Bds init. Incude the platform firmware vendor, revision

+  and so crc check.

+

+Arguments:

+

+  PrivateData  - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance

+

+Returns:

+

+  None.

+

+--*/

+{

+  //

+  // set firmwarevendor, here can be IBV/OEM customize

+  //

+  gST->FirmwareVendor = AllocateRuntimeCopyPool (

+                          sizeof (mFirmwareVendor),

+                          &mFirmwareVendor

+                          );

+  ASSERT (gST->FirmwareVendor != NULL);

+

+  gST->FirmwareRevision = EFI_FIRMWARE_REVISION;

+

+  //

+  // Fixup Tasble CRC after we updated Firmware Vendor and Revision

+  //

+  gBS->CalculateCrc32 ((VOID *) gST, sizeof (EFI_SYSTEM_TABLE), &gST->Hdr.CRC32);

+

+  //

+  // Initialize the platform specific string and language

+  //

+  InitializeStringSupport ();

+  InitializeLanguage (TRUE);

+  InitializeFrontPage (FALSE);

+

+}

+

+EFI_STATUS

+PlatformBdsConnectConsole (

+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole

+  )

+/*++

+

+Routine Description:

+

+  Connect the predefined platform default console device. Always try to find

+  and enable the vga device if have.

+

+Arguments:

+

+  PlatformConsole         - Predfined platform default console device array.

+ 

+Returns:

+

+  EFI_SUCCESS             - Success connect at least one ConIn and ConOut 

+                            device, there must have one ConOut device is 

+                            active vga device.

+  

+  EFI_STATUS              - Return the status of 

+                            BdsLibConnectAllDefaultConsoles ()

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+

+  Index   = 0;

+  Status  = EFI_SUCCESS;

+

+  //

+  // Have chance to connect the platform default console,

+  // the platform default console is the minimue device group

+  // the platform should support

+  //

+  while (PlatformConsole[Index].DevicePath != NULL) {

+    //

+    // Update the console variable with the connect type

+    //

+    if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {

+      BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);

+    }

+

+    if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {

+      BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);

+    }

+

+    if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {

+      BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);

+    }

+

+    Index++;

+  }

+  //

+  // Connect the all the default console with current cosole variable

+  //

+  Status = BdsLibConnectAllDefaultConsoles ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+PlatformBdsConnectSequence (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Connect with predeined platform connect sequence, 

+  the OEM/IBV can customize with their own connect sequence.

+  

+Arguments:

+

+  None.

+ 

+Returns:

+

+  None.

+  

+--*/

+{

+  UINTN Index;

+

+  Index = 0;

+

+  //

+  // Here we can get the customized platform connect sequence

+  // Notes: we can connect with new variable which record the

+  // last time boots connect device path sequence

+  //

+  while (gPlatformConnectSequence[Index] != NULL) {

+    //

+    // Build the platform boot option

+    //

+    BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);

+    Index++;

+  }

+

+}

+

+VOID

+PlatformBdsGetDriverOption (

+  IN OUT LIST_ENTRY              *BdsDriverLists

+  )

+/*++

+

+Routine Description:

+

+  Load the predefined driver option, OEM/IBV can customize this

+  to load their own drivers

+  

+Arguments:

+

+  BdsDriverLists  - The header of the driver option link list.

+ 

+Returns:

+

+  None.

+  

+--*/

+{

+  UINTN Index;

+

+  Index = 0;

+

+  //

+  // Here we can get the customized platform driver option

+  //

+  while (gPlatformDriverOption[Index] != NULL) {

+    //

+    // Build the platform boot option

+    //

+    BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");

+    Index++;

+  }

+

+}

+

+VOID

+PlatformBdsDiagnostics (

+  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,

+  IN BOOLEAN                     QuietBoot

+  )

+/*++

+

+Routine Description:

+

+  Perform the platform diagnostic, such like test memory. OEM/IBV also

+  can customize this fuction to support specific platform diagnostic.

+  

+Arguments:

+

+  MemoryTestLevel  - The memory test intensive level

+  

+  QuietBoot        - Indicate if need to enable the quiet boot

+ 

+Returns:

+

+  None.

+  

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Here we can decide if we need to show

+  // the diagnostics screen

+  // Notes: this quiet boot code should be remove

+  // from the graphic lib

+  //

+  if (QuietBoot) {

+    EnableQuietBoot (&gEfiUgaSplashProtocolGuid);

+    //

+    // Perform system diagnostic

+    //

+    Status = BdsMemoryTest (MemoryTestLevel);

+    if (EFI_ERROR (Status)) {

+      DisableQuietBoot ();

+    }

+

+    return ;

+  }

+  //

+  // Perform system diagnostic

+  //

+  Status = BdsMemoryTest (MemoryTestLevel);

+}

+

+VOID

+PlatformBdsPolicyBehavior (

+  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData,

+  IN OUT LIST_ENTRY                  *DriverOptionList,

+  IN OUT LIST_ENTRY                  *BootOptionList

+  )

+/*++

+

+Routine Description:

+

+  The function will excute with as the platform policy, current policy

+  is driven by boot mode. IBV/OEM can customize this code for their specific

+  policy action.

+  

+Arguments:

+

+  PrivateData      - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance

+  

+  DriverOptionList - The header of the driver option link list

+  

+  BootOptionList   - The header of the boot option link list

+ 

+Returns:

+

+  None.

+  

+--*/

+{

+  EFI_STATUS  Status;

+  UINT16      Timeout;

+

+  //

+  // Init the time out value

+  //

+  Timeout = BdsLibGetTimeout ();

+

+  //

+  // Load the driver option as the driver option list

+  //

+  PlatformBdsGetDriverOption (DriverOptionList);

+

+  //

+  // Get current Boot Mode

+  //

+  Status = BdsLibGetBootMode (&PrivateData->BootMode);

+

+  //

+  // Go the different platform policy with different boot mode

+  // Notes: this part code can be change with the table policy

+  //

+  switch (PrivateData->BootMode) {

+

+  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:

+  case BOOT_WITH_MINIMAL_CONFIGURATION:

+    //

+    // In no-configuration boot mode, we can connect the

+    // console directly.

+    //

+    BdsLibConnectAllDefaultConsoles ();

+    PlatformBdsDiagnostics (IGNORE, TRUE);

+

+    //

+    // Perform some platform specific connect sequence

+    //

+    PlatformBdsConnectSequence ();

+

+    //

+    // Notes: current time out = 0 can not enter the

+    // front page

+    //

+    PlatformBdsEnterFrontPage (Timeout, FALSE);

+

+    //

+    // Check the boot option with the boot option list

+    //

+    BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");

+    break;

+

+  case BOOT_ON_FLASH_UPDATE:

+    //

+    // Boot with the specific configuration

+    //

+    PlatformBdsConnectConsole (gPlatformConsole);

+    PlatformBdsDiagnostics (EXTENSIVE, FALSE);

+    BdsLibConnectAll ();

+    ProcessCapsules (BOOT_ON_FLASH_UPDATE);

+    break;

+

+  case BOOT_IN_RECOVERY_MODE:

+    //

+    // In recovery mode, just connect platform console

+    // and show up the front page

+    //

+    PlatformBdsConnectConsole (gPlatformConsole);

+    PlatformBdsDiagnostics (EXTENSIVE, FALSE);

+

+    //

+    // In recovery boot mode, we still enter to the

+    // frong page now

+    //

+    PlatformBdsEnterFrontPage (Timeout, FALSE);

+    break;

+

+  case BOOT_WITH_FULL_CONFIGURATION:

+  case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:

+  case BOOT_WITH_DEFAULT_SETTINGS:

+  default:

+    //

+    // Connect platform console

+    //

+    Status = PlatformBdsConnectConsole (gPlatformConsole);

+    if (EFI_ERROR (Status)) {

+      //

+      // Here OEM/IBV can customize with defined action

+      //

+      PlatformBdsNoConsoleAction ();

+    }

+

+    PlatformBdsDiagnostics (IGNORE, TRUE);

+

+    //

+    // Perform some platform specific connect sequence

+    //

+    PlatformBdsConnectSequence ();

+

+    //

+    // Give one chance to enter the setup if we

+    // have the time out

+    //

+    PlatformBdsEnterFrontPage (Timeout, FALSE);

+

+    //

+    // Here we have enough time to do the enumeration of boot device

+    //

+    BdsLibEnumerateAllBootOption (BootOptionList);

+    break;

+  }

+

+  return ;

+

+}

+

+VOID

+PlatformBdsBootSuccess (

+  IN  BDS_COMMON_OPTION *Option

+  )

+/*++

+

+Routine Description:

+  

+  Hook point after a boot attempt succeeds. We don't expect a boot option to

+  return, so the EFI 1.0 specification defines that you will default to an

+  interactive mode and stop processing the BootOrder list in this case. This

+  is alos a platform implementation and can be customized by IBV/OEM.

+

+Arguments:

+

+  Option - Pointer to Boot Option that succeeded to boot.

+

+Returns:

+  

+  None.

+

+--*/

+{

+  CHAR16  *TmpStr;

+

+  //

+  // If Boot returned with EFI_SUCCESS and there is not in the boot device

+  // select loop then we need to pop up a UI and wait for user input.

+  //

+  TmpStr = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));

+  if (TmpStr != NULL) {

+    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);

+    gBS->FreePool (TmpStr);

+  }

+}

+

+VOID

+PlatformBdsBootFail (

+  IN  BDS_COMMON_OPTION  *Option,

+  IN  EFI_STATUS         Status,

+  IN  CHAR16             *ExitData,

+  IN  UINTN              ExitDataSize

+  )

+/*++

+

+Routine Description:

+  

+  Hook point after a boot attempt fails.

+

+Arguments:

+  

+  Option - Pointer to Boot Option that failed to boot.

+

+  Status - Status returned from failed boot.

+

+  ExitData - Exit data returned from failed boot.

+

+  ExitDataSize - Exit data size returned from failed boot.

+

+Returns:

+  

+  None.

+

+--*/

+{

+  CHAR16  *TmpStr;

+

+  //

+  // If Boot returned with failed status then we need to pop up a UI and wait

+  // for user input.

+  //

+  TmpStr = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));

+  if (TmpStr != NULL) {

+    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);

+    gBS->FreePool (TmpStr);

+  }

+

+}

+

+EFI_STATUS

+PlatformBdsNoConsoleAction (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  This function is remained for IBV/OEM to do some platform action,

+  if there no console device can be connected.

+

+Arguments:

+  

+  None.

+  

+Returns:

+  

+  EFI_SUCCESS      - Direct return success now.

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/BdsPlatform.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/BdsPlatform.h
new file mode 100644
index 0000000..f3679fb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/BdsPlatform.h
@@ -0,0 +1,140 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name: 

+

+  BdsPlatform.h

+

+Abstract:

+

+  Head file for BDS Platform specific code

+

+--*/

+

+#ifndef _BDS_PLATFORM_H

+#define _BDS_PLATFORM_H

+

+#include "IndustryStandard/Pci22.h"

+

+extern BDS_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];

+extern EFI_DEVICE_PATH_PROTOCOL   *gPlatformConnectSequence[];

+extern EFI_DEVICE_PATH_PROTOCOL   *gPlatformDriverOption[];

+

+#define gEndEntire \

+  { \

+    END_DEVICE_PATH_TYPE,\

+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\

+    END_DEVICE_PATH_LENGTH,\

+    0\

+  }

+

+typedef struct {

+  VENDOR_DEVICE_PATH  VendorDevicePath;

+  UINT32              Instance;

+} WIN_NT_VENDOR_DEVICE_PATH_NODE;

+

+//

+// Below is the platform console device path

+//

+typedef struct {

+  VENDOR_DEVICE_PATH              NtBus;

+  WIN_NT_VENDOR_DEVICE_PATH_NODE  SerialDevice;

+  UART_DEVICE_PATH                Uart;

+  VENDOR_DEVICE_PATH              TerminalType;

+  EFI_DEVICE_PATH_PROTOCOL        End;

+} NT_ISA_SERIAL_DEVICE_PATH;

+

+typedef struct {

+  VENDOR_DEVICE_PATH              NtBus;

+  WIN_NT_VENDOR_DEVICE_PATH_NODE  NtUgaDevice;

+  EFI_DEVICE_PATH_PROTOCOL        End;

+} NT_PLATFORM_UGA_DEVICE_PATH;

+

+//

+// Platform BDS Functions

+//

+VOID

+PlatformBdsInit (

+  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData

+  )

+;

+

+VOID

+PlatformBdsPolicyBehavior (

+  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData,

+  IN LIST_ENTRY                      *DriverOptionList,

+  IN LIST_ENTRY                      *BootOptionList

+  )

+;

+

+VOID

+PlatformBdsGetDriverOption (

+  IN LIST_ENTRY               *BdsDriverLists

+  )

+;

+

+EFI_STATUS

+BdsMemoryTest (

+  EXTENDMEM_COVERAGE_LEVEL Level

+  )

+;

+

+EFI_STATUS

+PlatformBdsShowProgress (

+  EFI_UGA_PIXEL TitleForeground,

+  EFI_UGA_PIXEL TitleBackground,

+  CHAR16        *Title,

+  EFI_UGA_PIXEL ProgressColor,

+  UINTN         Progress,

+  UINTN         PreviousValue

+  )

+;

+

+VOID

+PlatformBdsConnectSequence (

+  VOID

+  )

+;

+

+VOID

+PlatformBdsBootFail (

+  IN  BDS_COMMON_OPTION  *Option,

+  IN  EFI_STATUS         Status,

+  IN  CHAR16             *ExitData,

+  IN  UINTN              ExitDataSize

+  )

+;

+

+VOID

+PlatformBdsBootSuccess (

+  IN  BDS_COMMON_OPTION *Option

+  )

+;

+

+EFI_STATUS

+ProcessCapsules (

+  EFI_BOOT_MODE BootMode

+  )

+;

+

+EFI_STATUS

+PlatformBdsConnectConsole (

+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole

+  )

+;

+

+EFI_STATUS

+PlatformBdsNoConsoleAction (

+  VOID

+  )

+;

+

+#endif // _BDS_PLATFORM_H

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Bds.dxs b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Bds.dxs
new file mode 100644
index 0000000..6647561
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Bds.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Bds.dxs

+

+Abstract:

+

+  Dependency expression source file.  This driver produces an arch protocol, so

+  must dipatch early.

+  

+--*/

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_HII_PROTOCOL_GUID

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Bds.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Bds.h
new file mode 100644
index 0000000..2d9d199
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Bds.h
@@ -0,0 +1,83 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Bds.h

+

+Abstract:

+

+  Head file for BDS Architectural Protocol implementation

+

+Revision History

+

+--*/

+

+#ifndef _BDS_H

+#define _BDS_H

+

+//

+// Bds AP Context data

+//

+#define EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE  EFI_SIGNATURE_32 ('B', 'd', 's', 'A')

+typedef struct {

+  UINTN                     Signature;

+

+  EFI_HANDLE                Handle;

+

+  EFI_BDS_ARCH_PROTOCOL     Bds;

+

+  //

+  // Save the current boot mode

+  //

+  EFI_BOOT_MODE             BootMode;

+

+  //

+  // Set true if boot with default settings

+  //

+  BOOLEAN                   DefaultBoot;

+

+  //

+  // The system default timeout for choose the boot option

+  //

+  UINT16                    TimeoutDefault;

+

+  //

+  // Memory Test Level

+  //

+  EXTENDMEM_COVERAGE_LEVEL  MemoryTestLevel;

+

+} EFI_BDS_ARCH_PROTOCOL_INSTANCE;

+

+#define EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS(_this) \

+  CR (_this, \

+      EFI_BDS_ARCH_PROTOCOL_INSTANCE, \

+      Bds, \

+      EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE \

+      )

+

+//

+// Prototypes

+//

+EFI_STATUS

+EFIAPI

+BdsInitialize (

+  IN EFI_HANDLE                     ImageHandle,

+  IN EFI_SYSTEM_TABLE               *SystemTable

+  );

+

+EFI_STATUS

+EFIAPI

+BdsEntry (

+  IN  EFI_BDS_ARCH_PROTOCOL *This

+  );

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BdsEntry.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BdsEntry.c
new file mode 100644
index 0000000..ddd6b4f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BdsEntry.c
@@ -0,0 +1,356 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsEntry.c

+

+Abstract:

+

+  The entry of the bds

+

+--*/

+

+#include "Bds.h"

+#include "BdsPlatform.h"

+#include "FrontPage.h"

+

+EFI_BDS_ARCH_PROTOCOL_INSTANCE  gBdsInstanceTemplate = {

+  EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,

+  NULL,

+  BdsEntry,

+  0xFFFF,

+  TRUE,

+  EXTENSIVE

+};

+

+UINT16                          *mBootNext = NULL;

+

+EFI_HANDLE                      mBdsImageHandle;

+

+EFI_STATUS

+EFIAPI

+BdsInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Install Boot Device Selection Protocol

+

+Arguments:

+  

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+  EFI_SUCEESS - BDS has finished initializing.

+                Rerun the 

+                dispatcher and recall BDS.Entry

+

+  Other       - Return value from EfiLibAllocatePool()

+                or gBS->InstallProtocolInterface

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  mBdsImageHandle = ImageHandle;

+

+  //

+  // Install protocol interface

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &gBdsInstanceTemplate.Handle,

+                  &gEfiBdsArchProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &gBdsInstanceTemplate.Bds

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+VOID

+BdsBootDeviceSelect (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  In the loop of attempt to boot for the boot order

+

+Arguments:

+  

+  None.

+

+Returns:

+

+  None.

+  

+--*/

+{

+  EFI_STATUS        Status;

+  LIST_ENTRY        *Link;

+  BDS_COMMON_OPTION *BootOption;

+  UINTN             ExitDataSize;

+  CHAR16            *ExitData;

+  UINT16            Timeout;

+  LIST_ENTRY        BootLists;

+  CHAR16            Buffer[20];

+  BOOLEAN           BootNextExist;

+  LIST_ENTRY        *LinkBootNext;

+

+  //

+  // Got the latest boot option

+  //

+  BootNextExist = FALSE;

+  LinkBootNext  = NULL;

+  InitializeListHead (&BootLists);

+

+  //

+  // First check the boot next option

+  //

+  ZeroMem (Buffer, sizeof (Buffer));

+

+  if (mBootNext != NULL) {

+    //

+    // Indicate we have the boot next variable, so this time

+    // boot will always have this boot option

+    //

+    BootNextExist = TRUE;

+

+    //

+    // Clear the this variable so it's only exist in this time boot

+    //

+    gRT->SetVariable (

+          L"BootNext",

+          &gEfiGlobalVariableGuid,

+          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+          0,

+          mBootNext

+          );

+

+    //

+    // Add the boot next boot option

+    //

+    UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);

+    BootOption = BdsLibVariableToOption (&BootLists, Buffer);

+  }

+  //

+  // Parse the boot order to get boot option

+  //

+  BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");

+  Link = BootLists.ForwardLink;

+

+  //

+  // Parameter check, make sure the loop will be valid

+  //

+  if (Link == NULL) {

+    return ;

+  }

+  //

+  // Here we make the boot in a loop, every boot success will

+  // return to the front page

+  //

+  for (;;) {

+    //

+    // Check the boot option list first

+    //

+    if (Link == &BootLists) {

+      //

+      // There are two ways to enter here:

+      // 1. There is no active boot option, give user chance to

+      //    add new boot option

+      // 2. All the active boot option processed, and there is no

+      //    one is success to boot, then we back here to allow user

+      //    add new active boot option

+      //

+      Timeout = 0xffff;

+      PlatformBdsEnterFrontPage (Timeout, FALSE);

+      InitializeListHead (&BootLists);

+      BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");

+      Link = BootLists.ForwardLink;

+      continue;

+    }

+    //

+    // Get the boot option from the link list

+    //

+    BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

+

+    //

+    // According to EFI Specification, if a load option is not marked

+    // as LOAD_OPTION_ACTIVE, the boot manager will not automatically

+    // load the option.

+    //

+    if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {

+      //

+      // skip the header of the link list, becuase it has no boot option

+      //

+      Link = Link->ForwardLink;

+      continue;

+    }

+    //

+    // Make sure the boot option device path connected,

+    // but ignore the BBS device path

+    //

+    if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {

+      //

+      // Notes: the internal shell can not been connected with device path

+      // so we do not check the status here

+      //

+      BdsLibConnectDevicePath (BootOption->DevicePath);

+    }

+    //

+    // All the driver options should have been processed since

+    // now boot will be performed.

+    //

+    PERF_END (0, BDS_TOK, NULL, 0);

+    Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);

+    if (EFI_ERROR (Status)) {

+      //

+      // Call platform action to indicate the boot fail

+      //

+      PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);

+

+      //

+      // Check the next boot option

+      //

+      Link = Link->ForwardLink;

+

+    } else {

+      //

+      // Call platform action to indicate the boot success

+      //

+      PlatformBdsBootSuccess (BootOption);

+

+      //

+      // Boot success, then stop process the boot order, and

+      // present the boot manager menu, front page

+      //

+      Timeout = 0xffff;

+      PlatformBdsEnterFrontPage (Timeout, FALSE);

+

+      //

+      // Rescan the boot option list, avoid pertential risk of the boot

+      // option change in front page

+      //

+      if (BootNextExist) {

+        LinkBootNext = BootLists.ForwardLink;

+      }

+

+      InitializeListHead (&BootLists);

+      if (LinkBootNext != NULL) {

+        //

+        // Reserve the boot next option

+        //

+        InsertTailList (&BootLists, LinkBootNext);

+      }

+

+      BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");

+      Link = BootLists.ForwardLink;

+    }

+  }

+

+  return ;

+

+}

+

+EFI_STATUS

+EFIAPI

+BdsEntry (

+  IN EFI_BDS_ARCH_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  Service routine for BdsInstance->Entry(). Devices are connected, the 

+  consoles are initialized, and the boot options are tried. 

+

+Arguments:

+

+  This - Protocol Instance structure.

+

+Returns:

+

+  EFI_SUCEESS - BDS->Entry has finished executing. 

+                

+--*/

+{

+  EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData;

+  LIST_ENTRY                      DriverOptionList;

+  LIST_ENTRY                      BootOptionList;

+  UINTN                           BootNextSize;

+

+  //

+  // Insert the performance probe

+  //

+  PERF_END (0, DXE_TOK, NULL, 0);

+  PERF_START (0, BDS_TOK, NULL, 0);

+

+  //

+  // Initialize the global system boot option and driver option

+  //

+  InitializeListHead (&DriverOptionList);

+  InitializeListHead (&BootOptionList);

+

+  //

+  // Get the BDS private data

+  //

+  PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);

+

+  //

+  // Do the platform init, can be customized by OEM/IBV

+  //

+  PERF_START (0, "PlatformBds", "BDS", 0);

+  PlatformBdsInit (PrivateData);

+

+  //

+  // Set up the device list based on EFI 1.1 variables

+  // process Driver#### and Load the driver's in the

+  // driver option list

+  //

+  BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");

+  if (!IsListEmpty (&DriverOptionList)) {

+    BdsLibLoadDrivers (&DriverOptionList);

+  }

+  //

+  // Check if we have the boot next option

+  //

+  mBootNext = BdsLibGetVariableAndSize (

+                L"BootNext",

+                &gEfiGlobalVariableGuid,

+                &BootNextSize

+                );

+

+  //

+  // Setup some platform policy here

+  //

+  PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);

+  PERF_END (0, L"PlatformBds", L"BDS", 0);

+

+  //

+  // BDS select the boot device to load OS

+  //

+  BdsBootDeviceSelect ();

+

+  //

+  // Only assert here since this is the right behavior, we should never

+  // return back to DxeCore.

+  //

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BBSsupport.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BBSsupport.c
new file mode 100644
index 0000000..a33be4b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BBSsupport.c
@@ -0,0 +1,1515 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                          

+All rights reserved. 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.             

+

+Module Name:

+

+  BBSsupport.c

+

+Abstract:

+

+  This function deal with the legacy boot option, it create, delete

+  and manage the legacy boot option, all legacy boot option is getting from

+  the legacy BBS table.

+

+--*/

+

+#include "BBSsupport.h"

+

+EFI_DEVICE_PATH_PROTOCOL  EndDevicePath[] = {

+  END_DEVICE_PATH_TYPE,

+  END_ENTIRE_DEVICE_PATH_SUBTYPE,

+  END_DEVICE_PATH_LENGTH,

+  0

+};

+

+VOID

+AsciiToUnicodeSize (

+  IN UINT8              *a,

+  IN UINTN              Size,

+  OUT UINT16            *u

+  )

+{

+  UINTN i;

+

+  i = 0;

+  while (a[i] != 0) {

+    u[i] = (CHAR16) a[i];

+    if (i == Size) {

+      u[i] = 0;

+      break;

+    }

+

+    i++;

+  }

+}

+

+VOID

+BdsBuildLegacyDevNameString (

+  IN BBS_TABLE                 *CurBBSEntry,

+  IN UINTN                     Index,

+  IN UINTN                     BufSize,

+  OUT CHAR16                   *BootString

+  )

+{

+  CHAR16  *Fmt;

+  CHAR16  *Type;

+  UINT8   *StringDesc;

+  CHAR16  temp[80];

+

+  switch (Index) {

+  //

+  // Primary Master

+  //

+  case 1:

+    Fmt = L"Primary Master %s";

+    break;

+

+ //

+ // Primary Slave

+ //

+  case 2:

+    Fmt = L"Primary Slave %s";

+    break;

+

+  //

+  // Secondary Master

+  //

+  case 3:

+    Fmt = L"Secondary Master %s";

+    break;

+

+  //

+  // Secondary Slave

+  //

+  case 4:

+    Fmt = L"Secondary Slave %s";

+    break;

+

+  default:

+    Fmt = L"%s";

+    break;

+  }

+

+  switch (CurBBSEntry->DeviceType) {

+  case BBS_FLOPPY:

+    Type = L"Floppy";

+    break;

+

+  case BBS_HARDDISK:

+    Type = L"Harddisk";

+    break;

+

+  case BBS_CDROM:

+    Type = L"CDROM";

+    break;

+

+  case BBS_PCMCIA:

+    Type = L"PCMCIAe";

+    break;

+

+  case BBS_USB:

+    Type = L"USB";

+    break;

+

+  case BBS_EMBED_NETWORK:

+    Type = L"Network";

+    break;

+

+  case BBS_BEV_DEVICE:

+    Type = L"BEVe";

+    break;

+

+  case BBS_UNKNOWN:

+  default:

+    Type = L"Unknown";

+    break;

+  }

+  //

+  // If current BBS entry has its description then use it.

+  //

+  StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);

+  if (NULL != StringDesc) {

+    //

+    // Only get fisrt 32 characters, this is suggested by BBS spec

+    //

+    AsciiToUnicodeSize (StringDesc, 32, temp);

+    Fmt   = L"%s";

+    Type  = temp;

+  }

+

+  UnicodeSPrint (BootString, BufSize, Fmt, Type);

+}

+

+EFI_STATUS

+BdsCreateLegacyBootOption (

+  IN BBS_TABLE                        *CurrentBbsEntry,

+  IN EFI_DEVICE_PATH_PROTOCOL         *CurrentBbsDevPath,

+  IN UINTN                            Index,

+  IN OUT UINT16                       **BootOrderList,

+  IN OUT UINTN                        *BootOrderListSize

+  )

+{

+  EFI_STATUS  Status;

+  UINT16      CurrentBootOptionNo;

+  UINT16      BootString[10];

+  UINT16      BootDesc[100];

+  UINT16      *NewBootOrderList;

+  UINTN       BufferSize;

+  VOID        *Buffer;

+  UINT8       *Ptr;

+  UINT16      CurrentBbsDevPathSize;

+  UINTN       BootOrderIndex;

+  UINTN       BootOrderLastIndex;

+  UINTN       ArrayIndex;

+  BOOLEAN     IndexNotFound;

+

+  if (NULL == (*BootOrderList)) {

+    CurrentBootOptionNo = 0;

+  } else {

+    for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {

+      IndexNotFound = TRUE;

+      for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {

+        if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {

+          IndexNotFound = FALSE;

+          break;

+        }

+      }

+

+      if (!IndexNotFound) {

+        continue;

+      } else {

+        break;

+      }

+    }

+

+    CurrentBootOptionNo = (UINT16) ArrayIndex;

+  }

+

+  UnicodeSPrint (

+    BootString,

+    sizeof (BootString),

+    L"Boot%04x",

+    CurrentBootOptionNo

+    );

+

+  BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);

+

+  CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));

+

+  BufferSize = sizeof (UINT32) +

+    sizeof (UINT16) +

+    StrSize (BootDesc) +

+    CurrentBbsDevPathSize +

+    sizeof (BBS_TABLE) +

+    sizeof (UINT16);

+

+  Buffer = AllocateZeroPool (BufferSize);

+  if (Buffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Ptr               = (UINT8 *) Buffer;

+

+  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;

+  Ptr += sizeof (UINT32);

+

+  *((UINT16 *) Ptr) = CurrentBbsDevPathSize;

+  Ptr += sizeof (UINT16);

+

+  CopyMem (

+    Ptr,

+    BootDesc,

+    StrSize (BootDesc)

+    );

+  Ptr += StrSize (BootDesc);

+

+  CopyMem (

+    Ptr,

+    CurrentBbsDevPath,

+    CurrentBbsDevPathSize

+    );

+  Ptr += CurrentBbsDevPathSize;

+

+  CopyMem (

+    Ptr,

+    CurrentBbsEntry,

+    sizeof (BBS_TABLE)

+    );

+

+  Ptr += sizeof (BBS_TABLE);

+  *((UINT16 *) Ptr) = (UINT16) Index;

+

+  Status = gRT->SetVariable (

+                  BootString,

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  BufferSize,

+                  Buffer

+                  );

+

+  SafeFreePool (Buffer);

+  Buffer = NULL;

+

+  NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));

+  if (NULL == NewBootOrderList) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  if (NULL != *BootOrderList) {

+    CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);

+  }

+

+  BootOrderLastIndex                    = (UINTN) (*BootOrderListSize / sizeof (UINT16));

+  NewBootOrderList[BootOrderLastIndex]  = CurrentBootOptionNo;

+  *BootOrderListSize += sizeof (UINT16);

+  *BootOrderList = NewBootOrderList;

+

+  return Status;

+}

+

+BOOLEAN

+BdsIsLegacyBootOption (

+  IN UINT8                 *BootOptionVar,

+  OUT BBS_TABLE            **BbsEntry,

+  OUT UINT16               *BbsIndex

+  )

+{

+  UINT8                     *Ptr;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  BOOLEAN                   Ret;

+  UINT16                    DevPathLen;

+

+  Ptr = BootOptionVar;

+  Ptr += sizeof (UINT32);

+  DevPathLen = *(UINT16 *) Ptr;

+  Ptr += sizeof (UINT16);

+  Ptr += StrSize ((UINT16 *) Ptr);

+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;

+  if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {

+    Ptr += DevPathLen;

+    *BbsEntry = (BBS_TABLE *) Ptr;

+    Ptr += sizeof (BBS_TABLE);

+    *BbsIndex = *(UINT16 *) Ptr;

+    Ret       = TRUE;

+  } else {

+    *BbsEntry = NULL;

+    Ret       = FALSE;

+  }

+

+  return Ret;

+}

+

+EFI_STATUS

+BdsDeleteBootOption (

+  IN UINTN                       OptionNumber,

+  IN OUT UINT16                  *BootOrder,

+  IN OUT UINTN                   *BootOrderSize

+  )

+{

+  UINT16      BootOption[100];

+  UINTN       Index;

+  EFI_STATUS  Status;

+  UINTN       Index2Del;

+

+  Status    = EFI_SUCCESS;

+  Index2Del = 0;

+

+  UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);

+  Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);

+  //

+  // adjust boot order array

+  //

+  for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {

+    if (BootOrder[Index] == OptionNumber) {

+      Index2Del = Index;

+      break;

+    }

+  }

+

+  if (Index != *BootOrderSize / sizeof (UINT16)) {

+    for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {

+      if (Index >= Index2Del) {

+        BootOrder[Index] = BootOrder[Index + 1];

+      }

+    }

+

+    *BootOrderSize -= sizeof (UINT16);

+  }

+

+  return Status;

+

+}

+

+EFI_STATUS

+BdsDeleteAllInvalidLegacyBootOptions (

+  VOID

+  )

+{

+  UINT16                    *BootOrder;

+  UINT8                     *BootOptionVar;

+  UINTN                     BootOrderSize;

+  UINTN                     BootOptionSize;

+  EFI_STATUS                Status;

+  UINT16                    HddCount;

+  UINT16                    BbsCount;

+  HDD_INFO                  *LocalHddInfo;

+  BBS_TABLE                 *LocalBbsTable;

+  BBS_TABLE                 *BbsEntry;

+  UINT16                    BbsIndex;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  UINTN                     Index;

+  UINT16                    BootOption[10];

+

+  Status        = EFI_SUCCESS;

+  BootOrder     = NULL;

+  BootOrderSize = 0;

+  HddCount      = 0;

+  BbsCount      = 0;

+  LocalHddInfo  = NULL;

+  LocalBbsTable = NULL;

+  BbsEntry      = NULL;

+

+  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  LegacyBios->GetBbsInfo (

+                LegacyBios,

+                &HddCount,

+                &LocalHddInfo,

+                &BbsCount,

+                &LocalBbsTable

+                );

+

+  BootOrder = BdsLibGetVariableAndSize (

+                L"BootOrder",

+                &gEfiGlobalVariableGuid,

+                &BootOrderSize

+                );

+  if (NULL == BootOrder) {

+    return EFI_NOT_FOUND;

+  }

+

+  Index = 0;

+  while (Index < BootOrderSize / sizeof (UINT16)) {

+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);

+    BootOptionVar = BdsLibGetVariableAndSize (

+                      BootOption,

+                      &gEfiGlobalVariableGuid,

+                      &BootOptionSize

+                      );

+    if (NULL == BootOptionVar) {

+      SafeFreePool (BootOrder);

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {

+      SafeFreePool (BootOptionVar);

+      Index++;

+      continue;

+    }

+

+    if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||

+        (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM) ||

+         (LocalBbsTable[BbsIndex].BootPriority == BBS_LOWEST_PRIORITY)) &&

+         LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) {

+      Index++;

+      continue;

+    }

+

+    SafeFreePool (BootOptionVar);

+    //

+    // should delete

+    //

+    BdsDeleteBootOption (

+      BootOrder[Index],

+      BootOrder,

+      &BootOrderSize

+      );

+  }

+

+  if (BootOrderSize) {

+    Status = gRT->SetVariable (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    BootOrderSize,

+                    BootOrder

+                    );

+  } else {

+    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);

+  }

+

+  SafeFreePool (BootOrder);

+

+  return Status;

+}

+

+BOOLEAN

+BdsFindLegacyBootOptionByDevType (

+  IN UINT16                 *BootOrder,

+  IN UINTN                  BootOptionNum,

+  IN UINT16                 DevType,

+  OUT UINT32                *Attribute,

+  OUT UINT16                *BbsIndex,

+  OUT UINTN                 *OptionNumber

+  )

+{

+  UINTN     Index;

+  UINTN     BootOrderIndex;

+  UINT16    BootOption[100];

+  UINTN     BootOptionSize;

+  UINT8     *BootOptionVar;

+  BBS_TABLE *BbsEntry;

+  BOOLEAN   Found;

+

+  BbsEntry  = NULL;

+  Found     = FALSE;

+

+  if (NULL == BootOrder) {

+    return Found;

+  }

+

+  for (BootOrderIndex = 0; BootOrderIndex < BootOptionNum; BootOrderIndex++) {

+    Index = (UINTN) BootOrder[BootOrderIndex];

+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", Index);

+    BootOptionVar = BdsLibGetVariableAndSize (

+                      BootOption,

+                      &gEfiGlobalVariableGuid,

+                      &BootOptionSize

+                      );

+    if (NULL == BootOptionVar) {

+      continue;

+    }

+

+    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {

+      SafeFreePool (BootOptionVar);

+      continue;

+    }

+

+    if (BbsEntry->DeviceType != DevType) {

+      SafeFreePool (BootOptionVar);

+      continue;

+    }

+

+    *Attribute    = *(UINT32 *) BootOptionVar;

+    *OptionNumber = Index;

+    Found         = TRUE;

+    SafeFreePool (BootOptionVar);

+    break;

+  }

+

+  return Found;

+}

+

+EFI_STATUS

+BdsCreateOneLegacyBootOption (

+  IN BBS_TABLE              *BbsItem,

+  IN UINTN                  Index,

+  IN OUT UINT16             **BootOrderList,

+  IN OUT UINTN              *BootOrderListSize

+  )

+{

+  BBS_BBS_DEVICE_PATH       BbsDevPathNode;

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;

+

+  DevPath                       = NULL;

+

+  BbsDevPathNode.Header.Type    = BBS_DEVICE_PATH;

+  BbsDevPathNode.Header.SubType = BBS_BBS_DP;

+  SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));

+  BbsDevPathNode.DeviceType = BbsItem->DeviceType;

+  CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));

+

+  DevPath = AppendDevicePathNode (

+              EndDevicePath,

+              (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode

+              );

+  if (NULL == DevPath) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = BdsCreateLegacyBootOption (

+            BbsItem,

+            DevPath,

+            Index,

+            BootOrderList,

+            BootOrderListSize

+            );

+  BbsItem->BootPriority = 0x00;

+

+  gBS->FreePool (DevPath);

+

+  return Status;

+}

+

+EFI_STATUS

+BdsAddNonExistingLegacyBootOptions (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Add the legacy boot options from BBS table if they do not exist.

+

+Arguments:

+

+  None.

+

+Returns:

+

+  EFI_SUCCESS       - The boot options are added successfully or they are already in boot options.

+  others            - An error occurred when creating legacy boot options.

+

+--*/

+{

+  UINT16                    *BootOrder;

+  UINTN                     BootOrderSize;

+  EFI_STATUS                Status;

+  UINT16                    HddCount;

+  UINT16                    BbsCount;

+  HDD_INFO                  *LocalHddInfo;

+  BBS_TABLE                 *LocalBbsTable;

+  UINT16                    BbsIndex;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  UINTN                     Index;

+  UINT32                    Attribute;

+  UINTN                     OptionNumber;

+  BOOLEAN                   Ret;

+

+  BootOrder     = NULL;

+  HddCount      = 0;

+  BbsCount      = 0;

+  LocalHddInfo  = NULL;

+  LocalBbsTable = NULL;

+

+  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  LegacyBios->GetBbsInfo (

+                LegacyBios,

+                &HddCount,

+                &LocalHddInfo,

+                &BbsCount,

+                &LocalBbsTable

+                );

+

+  BootOrder = BdsLibGetVariableAndSize (

+                L"BootOrder",

+                &gEfiGlobalVariableGuid,

+                &BootOrderSize

+                );

+  if (NULL == BootOrder) {

+    BootOrderSize = 0;

+  }

+

+  for (Index = 0; Index < BbsCount; Index++) {

+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||

+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)

+        ) {

+      continue;

+    }

+

+    Ret = BdsFindLegacyBootOptionByDevType (

+            BootOrder,

+            BootOrderSize / sizeof (UINT16),

+            LocalBbsTable[Index].DeviceType,

+            &Attribute,

+            &BbsIndex,

+            &OptionNumber

+            );

+    if (Ret && (Attribute & LOAD_OPTION_ACTIVE) != 0) {

+      continue;

+    }

+

+    if (Ret) {

+      if (Index != BbsIndex) {

+        BdsDeleteBootOption (

+          OptionNumber,

+          BootOrder,

+          &BootOrderSize

+          );

+      } else {

+        continue;

+      }

+    }

+    //

+    // Not found such type of legacy device in boot options or we found but it's disabled

+    // so we have to create one and put it to the tail of boot order list

+    //

+    Status = BdsCreateOneLegacyBootOption (

+              &LocalBbsTable[Index],

+              Index,

+              &BootOrder,

+              &BootOrderSize

+              );

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+  }

+

+  if (BootOrderSize > 0) {

+    Status = gRT->SetVariable (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    BootOrderSize,

+                    BootOrder

+                    );

+  } else {

+    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);

+  }

+

+  if (BootOrder != NULL) {

+    SafeFreePool (BootOrder);

+  }

+

+  return Status;

+}

+

+UINT16 *

+BdsFillDevOrderBuf (

+  IN BBS_TABLE                    *BbsTable,

+  IN BBS_TYPE                     BbsType,

+  IN UINTN                        BbsCount,

+  IN UINT16                       *Buf

+  )

+{

+  UINTN Index;

+

+  for (Index = 0; Index < BbsCount; Index++) {

+    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {

+      continue;

+    }

+

+    if (BbsTable[Index].DeviceType != BbsType) {

+      continue;

+    }

+

+    *Buf = (UINT16) (Index & 0xFF);

+    Buf++;

+  }

+

+  return Buf;

+}

+

+EFI_STATUS

+BdsCreateDevOrder (

+  IN BBS_TABLE                  *BbsTable,

+  IN UINT16                     BbsCount

+  )

+{

+  UINTN       Index;

+  UINTN       FDCount;

+  UINTN       HDCount;

+  UINTN       CDCount;

+  UINTN       NETCount;

+  UINTN       BEVCount;

+  UINTN       TotalSize;

+  UINTN       HeaderSize;

+  UINT8       *DevOrder;

+  UINT8       *Ptr;

+  EFI_STATUS  Status;

+

+  FDCount     = 0;

+  HDCount     = 0;

+  CDCount     = 0;

+  NETCount    = 0;

+  BEVCount    = 0;

+  TotalSize   = 0;

+  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);

+  DevOrder    = NULL;

+  Ptr         = NULL;

+  Status      = EFI_SUCCESS;

+

+  for (Index = 0; Index < BbsCount; Index++) {

+    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {

+      continue;

+    }

+

+    switch (BbsTable[Index].DeviceType) {

+    case BBS_FLOPPY:

+      FDCount++;

+      break;

+

+    case BBS_HARDDISK:

+      HDCount++;

+      break;

+

+    case BBS_CDROM:

+      CDCount++;

+      break;

+

+    case BBS_EMBED_NETWORK:

+      NETCount++;

+      break;

+

+    case BBS_BEV_DEVICE:

+      BEVCount++;

+      break;

+

+    default:

+      break;

+    }

+  }

+

+  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);

+  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);

+  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);

+  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);

+  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);

+

+  DevOrder = AllocateZeroPool (TotalSize);

+  if (NULL == DevOrder) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Ptr                 = DevOrder;

+

+  *((BBS_TYPE *) Ptr) = BBS_FLOPPY;

+  Ptr += sizeof (BBS_TYPE);

+  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+  if (FDCount) {

+    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, (UINT16 *) Ptr);

+  }

+

+  *((BBS_TYPE *) Ptr) = BBS_HARDDISK;

+  Ptr += sizeof (BBS_TYPE);

+  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+  if (HDCount) {

+    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, (UINT16 *) Ptr);

+  }

+

+  *((BBS_TYPE *) Ptr) = BBS_CDROM;

+  Ptr += sizeof (BBS_TYPE);

+  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+  if (CDCount) {

+    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, (UINT16 *) Ptr);

+  }

+

+  *((BBS_TYPE *) Ptr) = BBS_EMBED_NETWORK;

+  Ptr += sizeof (BBS_TYPE);

+  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+  if (NETCount) {

+    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, (UINT16 *) Ptr);

+  }

+

+  *((BBS_TYPE *) Ptr) = BBS_BEV_DEVICE;

+  Ptr += sizeof (BBS_TYPE);

+  *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+  if (BEVCount) {

+    Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, (UINT16 *) Ptr);

+  }

+

+  Status = gRT->SetVariable (

+                  VarLegacyDevOrder,

+                  &EfiLegacyDevOrderGuid,

+                  VAR_FLAG,

+                  TotalSize,

+                  DevOrder

+                  );

+  SafeFreePool (DevOrder);

+

+  return Status;

+}

+

+EFI_STATUS

+BdsUpdateLegacyDevOrder (

+  VOID

+  )

+/*++

+Format of LegacyDevOrder variable:

+|-----------------------------------------------------------------------------------------------------------------

+| BBS_FLOPPY | Length | Index0 | Index1 | ... | BBS_HARDDISK | Length | Index0 | Index1 | ... | BBS_CDROM | Length | Index0 | ...

+|-----------------------------------------------------------------------------------------------------------------

+

+Length is a 16 bit integer, it indicates how many Indexes follows, including the size of itself.

+Index# is a 16 bit integer, the low byte of it stands for the index in BBS table

+           the high byte of it only have two value 0 and 0xFF, 0xFF means this device has been

+           disabled by user.

+--*/

+{

+  UINT8                     *DevOrder;

+  UINT8                     *NewDevOrder;

+  UINTN                     DevOrderSize;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  EFI_STATUS                Status;

+  UINT16                    HddCount;

+  UINT16                    BbsCount;

+  HDD_INFO                  *LocalHddInfo;

+  BBS_TABLE                 *LocalBbsTable;

+  UINTN                     Index;

+  UINTN                     Index2;

+  UINTN                     *Idx;

+  UINTN                     FDCount;

+  UINTN                     HDCount;

+  UINTN                     CDCount;

+  UINTN                     NETCount;

+  UINTN                     BEVCount;

+  UINTN                     TotalSize;

+  UINTN                     HeaderSize;

+  UINT8                     *Ptr;

+  UINT8                     *NewPtr;

+  UINT16                    *NewFDPtr;

+  UINT16                    *NewHDPtr;

+  UINT16                    *NewCDPtr;

+  UINT16                    *NewNETPtr;

+  UINT16                    *NewBEVPtr;

+  UINT16                    *NewDevPtr;

+  UINT16                    Length;

+  UINT16                    tmp;

+  UINTN                     FDIndex;

+  UINTN                     HDIndex;

+  UINTN                     CDIndex;

+  UINTN                     NETIndex;

+  UINTN                     BEVIndex;

+

+  LocalHddInfo  = NULL;

+  LocalBbsTable = NULL;

+  Idx           = NULL;

+  FDCount       = 0;

+  HDCount       = 0;

+  CDCount       = 0;

+  NETCount      = 0;

+  BEVCount      = 0;

+  TotalSize     = 0;

+  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);

+  FDIndex       = 0;

+  HDIndex       = 0;

+  CDIndex       = 0;

+  NETIndex      = 0;

+  BEVIndex      = 0;

+  NewDevPtr     = NULL;

+

+  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  LegacyBios->GetBbsInfo (

+                LegacyBios,

+                &HddCount,

+                &LocalHddInfo,

+                &BbsCount,

+                &LocalBbsTable

+                );

+

+  DevOrder = (UINT8 *) BdsLibGetVariableAndSize (

+                        VarLegacyDevOrder,

+                        &EfiLegacyDevOrderGuid,

+                        &DevOrderSize

+                        );

+  if (NULL == DevOrder) {

+    return BdsCreateDevOrder (LocalBbsTable, BbsCount);

+  }

+  //

+  // First we figure out how many boot devices with same device type respectively

+  //

+  for (Index = 0; Index < BbsCount; Index++) {

+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||

+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) ||

+        (LocalBbsTable[Index].BootPriority == BBS_LOWEST_PRIORITY)

+        ) {

+      continue;

+    }

+

+    switch (LocalBbsTable[Index].DeviceType) {

+    case BBS_FLOPPY:

+      FDCount++;

+      break;

+

+    case BBS_HARDDISK:

+      HDCount++;

+      break;

+

+    case BBS_CDROM:

+      CDCount++;

+      break;

+

+    case BBS_EMBED_NETWORK:

+      NETCount++;

+      break;

+

+    case BBS_BEV_DEVICE:

+      BEVCount++;

+      break;

+

+    default:

+      break;

+    }

+  }

+

+  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));

+  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));

+  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));

+  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));

+  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));

+

+  NewDevOrder = AllocateZeroPool (TotalSize);

+  if (NULL == NewDevOrder) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NewFDPtr  = (UINT16 *) (NewDevOrder + HeaderSize);

+  NewHDPtr  = (UINT16 *) ((UINT8 *) NewFDPtr + FDCount * sizeof (UINT16) + HeaderSize);

+  NewCDPtr  = (UINT16 *) ((UINT8 *) NewHDPtr + HDCount * sizeof (UINT16) + HeaderSize);

+  NewNETPtr = (UINT16 *) ((UINT8 *) NewCDPtr + CDCount * sizeof (UINT16) + HeaderSize);

+  NewBEVPtr = (UINT16 *) ((UINT8 *) NewNETPtr + NETCount * sizeof (UINT16) + HeaderSize);

+

+  //

+  // copy FD

+  //

+  Ptr                     = DevOrder;

+  NewPtr                  = NewDevOrder;

+  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);

+  Ptr += sizeof (BBS_TYPE);

+  NewPtr += sizeof (BBS_TYPE);

+  Length                = *((UINT16 *) Ptr);

+  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+

+  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {

+    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||

+        LocalBbsTable[*Ptr].DeviceType != BBS_FLOPPY

+        ) {

+      Ptr += sizeof (UINT16);

+      continue;

+    }

+

+    NewFDPtr[FDIndex] = *(UINT16 *) Ptr;

+    FDIndex++;

+    Ptr += sizeof (UINT16);

+  }

+  //

+  // copy HD

+  //

+  NewPtr                  = (UINT8 *) NewHDPtr - HeaderSize;

+  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);

+  Ptr += sizeof (BBS_TYPE);

+  NewPtr += sizeof (BBS_TYPE);

+  Length                = *((UINT16 *) Ptr);

+  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+

+  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {

+    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||

+        LocalBbsTable[*Ptr].DeviceType != BBS_HARDDISK

+        ) {

+      Ptr += sizeof (UINT16);

+      continue;

+    }

+

+    NewHDPtr[HDIndex] = *(UINT16 *) Ptr;

+    HDIndex++;

+    Ptr += sizeof (UINT16);

+  }

+  //

+  // copy CD

+  //

+  NewPtr                  = (UINT8 *) NewCDPtr - HeaderSize;

+  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);

+  Ptr += sizeof (BBS_TYPE);

+  NewPtr += sizeof (BBS_TYPE);

+  Length                = *((UINT16 *) Ptr);

+  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+

+  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {

+    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||

+        LocalBbsTable[*Ptr].DeviceType != BBS_CDROM

+        ) {

+      Ptr += sizeof (UINT16);

+      continue;

+    }

+

+    NewCDPtr[CDIndex] = *(UINT16 *) Ptr;

+    CDIndex++;

+    Ptr += sizeof (UINT16);

+  }

+  //

+  // copy NET

+  //

+  NewPtr                  = (UINT8 *) NewNETPtr - HeaderSize;

+  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);

+  Ptr += sizeof (BBS_TYPE);

+  NewPtr += sizeof (BBS_TYPE);

+  Length                = *((UINT16 *) Ptr);

+  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+

+  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {

+    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||

+        LocalBbsTable[*Ptr].DeviceType != BBS_EMBED_NETWORK

+        ) {

+      Ptr += sizeof (UINT16);

+      continue;

+    }

+

+    NewNETPtr[NETIndex] = *(UINT16 *) Ptr;

+    NETIndex++;

+    Ptr += sizeof (UINT16);

+  }

+  //

+  // copy BEV

+  //

+  NewPtr                  = (UINT8 *) NewBEVPtr - HeaderSize;

+  *((BBS_TYPE *) NewPtr)  = *((BBS_TYPE *) Ptr);

+  Ptr += sizeof (BBS_TYPE);

+  NewPtr += sizeof (BBS_TYPE);

+  Length                = *((UINT16 *) Ptr);

+  *((UINT16 *) NewPtr)  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));

+  Ptr += sizeof (UINT16);

+

+  for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {

+    if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||

+        LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||

+        LocalBbsTable[*Ptr].DeviceType != BBS_BEV_DEVICE

+        ) {

+      Ptr += sizeof (UINT16);

+      continue;

+    }

+

+    NewBEVPtr[BEVIndex] = *(UINT16 *) Ptr;

+    BEVIndex++;

+    Ptr += sizeof (UINT16);

+  }

+

+  for (Index = 0; Index < BbsCount; Index++) {

+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||

+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) ||

+        (LocalBbsTable[Index].BootPriority == BBS_LOWEST_PRIORITY)

+        ) {

+      continue;

+    }

+

+    switch (LocalBbsTable[Index].DeviceType) {

+    case BBS_FLOPPY:

+      Idx       = &FDIndex;

+      NewDevPtr = NewFDPtr;

+      break;

+

+    case BBS_HARDDISK:

+      Idx       = &HDIndex;

+      NewDevPtr = NewHDPtr;

+      break;

+

+    case BBS_CDROM:

+      Idx       = &CDIndex;

+      NewDevPtr = NewCDPtr;

+      break;

+

+    case BBS_EMBED_NETWORK:

+      Idx       = &NETIndex;

+      NewDevPtr = NewNETPtr;

+      break;

+

+    case BBS_BEV_DEVICE:

+      Idx       = &BEVIndex;

+      NewDevPtr = NewBEVPtr;

+      break;

+

+    default:

+      Idx = NULL;

+      break;

+    }

+    //

+    // at this point we have copied those valid indexes to new buffer

+    // and we should check if there is any new appeared boot device

+    //

+    if (Idx) {

+      for (Index2 = 0; Index2 < *Idx; Index2++) {

+        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {

+          break;

+        }

+      }

+

+      if (Index2 == *Idx) {

+        //

+        // Index2 == *Idx means we didn't find Index

+        // so Index is a new appeared device's index in BBS table

+        // save it.

+        //

+        NewDevPtr[*Idx] = (UINT16) (Index & 0xFF);

+        (*Idx)++;

+      }

+    }

+  }

+

+  if (FDCount) {

+    //

+    // Just to make sure that disabled indexes are all at the end of the array

+    //

+    for (Index = 0; Index < FDIndex - 1; Index++) {

+      if (0xFF00 != (NewFDPtr[Index] & 0xFF00)) {

+        continue;

+      }

+

+      for (Index2 = Index + 1; Index2 < FDIndex; Index2++) {

+        if (0 == (NewFDPtr[Index2] & 0xFF00)) {

+          tmp               = NewFDPtr[Index];

+          NewFDPtr[Index]   = NewFDPtr[Index2];

+          NewFDPtr[Index2]  = tmp;

+          break;

+        }

+      }

+    }

+  }

+

+  if (HDCount) {

+    //

+    // Just to make sure that disabled indexes are all at the end of the array

+    //

+    for (Index = 0; Index < HDIndex - 1; Index++) {

+      if (0xFF00 != (NewHDPtr[Index] & 0xFF00)) {

+        continue;

+      }

+

+      for (Index2 = Index + 1; Index2 < HDIndex; Index2++) {

+        if (0 == (NewHDPtr[Index2] & 0xFF00)) {

+          tmp               = NewHDPtr[Index];

+          NewHDPtr[Index]   = NewHDPtr[Index2];

+          NewHDPtr[Index2]  = tmp;

+          break;

+        }

+      }

+    }

+  }

+

+  if (CDCount) {

+    //

+    // Just to make sure that disabled indexes are all at the end of the array

+    //

+    for (Index = 0; Index < CDIndex - 1; Index++) {

+      if (0xFF00 != (NewCDPtr[Index] & 0xFF00)) {

+        continue;

+      }

+

+      for (Index2 = Index + 1; Index2 < CDIndex; Index2++) {

+        if (0 == (NewCDPtr[Index2] & 0xFF00)) {

+          tmp               = NewCDPtr[Index];

+          NewCDPtr[Index]   = NewCDPtr[Index2];

+          NewCDPtr[Index2]  = tmp;

+          break;

+        }

+      }

+    }

+  }

+

+  if (NETCount) {

+    //

+    // Just to make sure that disabled indexes are all at the end of the array

+    //

+    for (Index = 0; Index < NETIndex - 1; Index++) {

+      if (0xFF00 != (NewNETPtr[Index] & 0xFF00)) {

+        continue;

+      }

+

+      for (Index2 = Index + 1; Index2 < NETIndex; Index2++) {

+        if (0 == (NewNETPtr[Index2] & 0xFF00)) {

+          tmp               = NewNETPtr[Index];

+          NewNETPtr[Index]  = NewNETPtr[Index2];

+          NewNETPtr[Index2] = tmp;

+          break;

+        }

+      }

+    }

+  }

+

+  if (BEVCount) {

+    //

+    // Just to make sure that disabled indexes are all at the end of the array

+    //

+    for (Index = 0; Index < BEVIndex - 1; Index++) {

+      if (0xFF00 != (NewBEVPtr[Index] & 0xFF00)) {

+        continue;

+      }

+

+      for (Index2 = Index + 1; Index2 < BEVIndex; Index2++) {

+        if (0 == (NewBEVPtr[Index2] & 0xFF00)) {

+          tmp               = NewBEVPtr[Index];

+          NewBEVPtr[Index]  = NewBEVPtr[Index2];

+          NewBEVPtr[Index2] = tmp;

+          break;

+        }

+      }

+    }

+  }

+

+  SafeFreePool (DevOrder);

+

+  Status = gRT->SetVariable (

+                  VarLegacyDevOrder,

+                  &EfiLegacyDevOrderGuid,

+                  VAR_FLAG,

+                  TotalSize,

+                  NewDevOrder

+                  );

+  SafeFreePool (NewDevOrder);

+

+  return Status;

+}

+

+EFI_STATUS

+BdsSetBootPriority4SameTypeDev (

+  IN UINT16                                              DeviceType,

+  IN OUT BBS_TABLE                                       *LocalBbsTable,

+  IN OUT UINT16                                          *Priority

+  )

+/*++

+DeviceType           - BBS_FLOPPY, BBS_HARDDISK, BBS_CDROM and so on

+LocalBbsTable       - BBS table instance

+Priority                 - As input arg, it is the start point of boot priority, as output arg, it is the start point of boot

+                              priority can be used next time.

+--*/

+{

+  UINT8   *DevOrder;

+

+  UINT8   *OrigBuffer;

+  UINT16  *DevIndex;

+  UINTN   DevOrderSize;

+  UINTN   DevCount;

+  UINTN   Index;

+

+  DevOrder = BdsLibGetVariableAndSize (

+              VarLegacyDevOrder,

+              &EfiLegacyDevOrderGuid,

+              &DevOrderSize

+              );

+  if (NULL == DevOrder) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  OrigBuffer = DevOrder;

+  while (DevOrder < OrigBuffer + DevOrderSize) {

+    if (DeviceType == * (BBS_TYPE *) DevOrder) {

+      break;

+    }

+

+    DevOrder += sizeof (BBS_TYPE);

+    DevOrder += *(UINT16 *) DevOrder;

+  }

+

+  if (DevOrder >= OrigBuffer + DevOrderSize) {

+    SafeFreePool (OrigBuffer);

+    return EFI_NOT_FOUND;

+  }

+

+  DevOrder += sizeof (BBS_TYPE);

+  DevCount  = (*((UINT16 *) DevOrder) - sizeof (UINT16)) / sizeof (UINT16);

+  DevIndex  = (UINT16 *) (DevOrder + sizeof (UINT16));

+  //

+  // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.

+  //

+  for (Index = 0; Index < DevCount; Index++) {

+    if ((DevIndex[Index] & 0xFF00) == 0xFF00) {

+      //

+      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;

+      //

+    } else {

+      LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = *Priority;

+      (*Priority)++;

+    }

+  }

+

+  SafeFreePool (OrigBuffer);

+  return EFI_SUCCESS;

+}

+

+VOID

+PrintBbsTable (

+  IN BBS_TABLE                      *LocalBbsTable

+  )

+{

+  UINT16  Idx;

+

+  DEBUG ((EFI_D_ERROR, "\n"));

+  DEBUG ((EFI_D_ERROR, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));

+  DEBUG ((EFI_D_ERROR, "=============================================\n"));

+  for (Idx = 0; Idx < MAX_BBS_ENTRIES; Idx++) {

+    if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||

+        (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||

+        (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)

+        ) {

+      continue;

+    }

+

+    DEBUG (

+      (EFI_D_ERROR,

+      " %02x: %04x %02x/%02x/%02x %02x/02%x %04x %04x %04x:%04x\n",

+      (UINTN) Idx,

+      (UINTN) LocalBbsTable[Idx].BootPriority,

+      (UINTN) LocalBbsTable[Idx].Bus,

+      (UINTN) LocalBbsTable[Idx].Device,

+      (UINTN) LocalBbsTable[Idx].Function,

+      (UINTN) LocalBbsTable[Idx].Class,

+      (UINTN) LocalBbsTable[Idx].SubClass,

+      (UINTN) LocalBbsTable[Idx].DeviceType,

+      (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,

+      (UINTN) LocalBbsTable[Idx].BootHandlerSegment,

+      (UINTN) LocalBbsTable[Idx].BootHandlerOffset,

+      (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),

+      (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))

+      );

+  }

+

+  DEBUG ((EFI_D_ERROR, "\n"));

+}

+

+EFI_STATUS

+BdsRefreshBbsTableForBoot (

+  IN BDS_COMMON_OPTION        *Entry

+  )

+{

+  EFI_STATUS                Status;

+  UINT16                    HddCount;

+  UINT16                    BbsCount;

+  HDD_INFO                  *LocalHddInfo;

+  BBS_TABLE                 *LocalBbsTable;

+  UINT16                    DevType;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  UINTN                     Index;

+  UINT16                    Priority;

+  UINT16                    *BootOrder;

+  UINTN                     BootOrderSize;

+  UINT8                     *BootOptionVar;

+  UINTN                     BootOptionSize;

+  UINT16                    BootOption[100];

+  UINT8                     *Ptr;

+  UINT16                    DevPathLen;

+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;

+

+  HddCount      = 0;

+  BbsCount      = 0;

+  LocalHddInfo  = NULL;

+  LocalBbsTable = NULL;

+  DevType       = BBS_UNKNOWN;

+

+  Status        = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  LegacyBios->GetBbsInfo (

+                LegacyBios,

+                &HddCount,

+                &LocalHddInfo,

+                &BbsCount,

+                &LocalBbsTable

+                );

+  //

+  // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY

+  // We will set them according to the settings setup by user

+  //

+  for (Index = 0; Index < BbsCount; Index++) {

+    if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||

+        (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||

+         (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {

+      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;

+    }

+  }

+  //

+  // boot priority always starts at 0

+  //

+  Priority = 0;

+  if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {

+    //

+    // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.

+    //

+    DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;

+    Status = BdsSetBootPriority4SameTypeDev (

+              DevType,

+              LocalBbsTable,

+              &Priority

+              );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  //

+  // we have to set the boot priority for other BBS entries with different device types

+  //

+  BootOrder = (UINT16 *) BdsLibGetVariableAndSize (

+                          L"BootOrder",

+                          &gEfiGlobalVariableGuid,

+                          &BootOrderSize

+                          );

+  for (Index = 0; BootOrder && Index < BootOrderSize / sizeof (UINT16); Index++) {

+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);

+    BootOptionVar = BdsLibGetVariableAndSize (

+                      BootOption,

+                      &gEfiGlobalVariableGuid,

+                      &BootOptionSize

+                      );

+    if (NULL == BootOptionVar) {

+      continue;

+    }

+

+    Ptr = BootOptionVar;

+

+    Ptr += sizeof (UINT32);

+    DevPathLen = *(UINT16 *) Ptr;

+    Ptr += sizeof (UINT16);

+    Ptr += StrSize ((UINT16 *) Ptr);

+    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;

+    if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {

+      SafeFreePool (BootOptionVar);

+      continue;

+    }

+

+    Ptr += DevPathLen;

+    if (DevType == ((BBS_TABLE *) Ptr)->DeviceType) {

+      //

+      // We don't want to process twice for a device type

+      //

+      SafeFreePool (BootOptionVar);

+      continue;

+    }

+

+    Status = BdsSetBootPriority4SameTypeDev (

+              ((BBS_TABLE *) Ptr)->DeviceType,

+              LocalBbsTable,

+              &Priority

+              );

+    SafeFreePool (BootOptionVar);

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+  }

+

+  if (BootOrder) {

+    SafeFreePool (BootOrder);

+  }

+  //

+  // For debug

+  //

+  PrintBbsTable (LocalBbsTable);

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BBSsupport.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BBSsupport.h
new file mode 100644
index 0000000..37778f4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BBSsupport.h
@@ -0,0 +1,83 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BBSsupport.h

+

+Abstract:

+

+  declares interface functions

+

+Revision History

+

+--*/

+

+#ifndef _EFI_BDS_BBS_SUPPORT_H

+#define _EFI_BDS_BBS_SUPPORT_H

+

+#include "Generic/BootMaint/BootMaint.h"

+

+#ifdef EFI32

+#define REFRESH_LEGACY_BOOT_OPTIONS \

+        BdsDeleteAllInvalidLegacyBootOptions ();\

+        BdsAddNonExistingLegacyBootOptions (); \

+        BdsUpdateLegacyDevOrder ()

+#else

+#define REFRESH_LEGACY_BOOT_OPTIONS

+#endif

+

+VOID

+BdsBuildLegacyDevNameString (

+  IN BBS_TABLE                     *CurBBSEntry,

+  IN UINTN                         Index,

+  IN UINTN                         BufSize,

+  OUT CHAR16                       *BootString

+  );

+

+EFI_STATUS

+BdsDeleteAllInvalidLegacyBootOptions (

+  VOID

+  );

+

+EFI_STATUS

+BdsAddNonExistingLegacyBootOptions (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Add the legacy boot options from BBS table if they do not exist.

+

+Arguments:

+

+  None.

+

+Returns:

+

+  EFI_SUCCESS       - The boot options are added successfully or they are already in boot options.

+  others            - An error occurred when creating legacy boot options.

+

+--*/

+;

+

+EFI_STATUS

+BdsUpdateLegacyDevOrder (

+  VOID

+  );

+

+EFI_STATUS

+BdsRefreshBbsTableForBoot (

+  IN BDS_COMMON_OPTION        *Entry

+  );

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BmLib.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BmLib.c
new file mode 100644
index 0000000..201339e
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BmLib.c
@@ -0,0 +1,626 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  bmlib.c

+    

+AgBStract:

+

+  Boot Maintainence Helper functions

+

+--*/

+

+#include "bootmaint.h"

+

+EFI_STATUS

+EfiLibLocateProtocol (

+  IN  EFI_GUID    *ProtocolGuid,

+  OUT VOID        **Interface

+  )

+/*++

+

+Routine Description:

+

+  Find the first instance of this Protocol 

+  in the system and return it's interface

+

+Arguments:

+

+  ProtocolGuid    - Provides the protocol to search for

+  Interface       - On return, a pointer to the first interface 

+                    that matches ProtocolGuid

+

+Returns:

+

+  EFI_SUCCESS     - A protocol instance matching ProtocolGuid was found

+

+  EFI_NOT_FOUND   - No protocol instances were found that match ProtocolGuid

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (

+                  ProtocolGuid,

+                  NULL,

+                  Interface

+                  );

+  return Status;

+}

+

+EFI_FILE_HANDLE

+EfiLibOpenRoot (

+  IN EFI_HANDLE                   DeviceHandle

+  )

+/*++

+

+Routine Description:

+

+  Function opens and returns a file handle to the root directory of a volume.

+

+Arguments:

+

+  DeviceHandle         - A handle for a device

+

+Returns:

+  

+  A valid file handle or NULL is returned

+

+--*/

+{

+  EFI_STATUS                      Status;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;

+  EFI_FILE_HANDLE                 File;

+

+  File = NULL;

+

+  //

+  // File the file system interface to the device

+  //

+  Status = gBS->HandleProtocol (

+                  DeviceHandle,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  (VOID *) &Volume

+                  );

+

+  //

+  // Open the root directory of the volume

+  //

+  if (!EFI_ERROR (Status)) {

+    Status = Volume->OpenVolume (

+                      Volume,

+                      &File

+                      );

+  }

+  //

+  // Done

+  //

+  return EFI_ERROR (Status) ? NULL : File;

+}

+

+BOOLEAN

+EfiGrowBuffer (

+  IN OUT EFI_STATUS   *Status,

+  IN OUT VOID         **Buffer,

+  IN UINTN            BufferSize

+  )

+/*++

+

+Routine Description:

+

+    Helper function called as part of the code needed

+    to allocate the proper sized buffer for various 

+    EFI interfaces.

+

+Arguments:

+

+    Status      - Current status

+

+    Buffer      - Current allocated buffer, or NULL

+

+    BufferSize  - Current buffer size needed

+    

+Returns:

+    

+    TRUE - if the buffer was reallocated and the caller 

+    should try the API again.

+

+--*/

+{

+  BOOLEAN TryAgain;

+

+  //

+  // If this is an initial request, buffer will be null with a new buffer size

+  //

+  if (!*Buffer && BufferSize) {

+    *Status = EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // If the status code is "buffer too small", resize the buffer

+  //

+  TryAgain = FALSE;

+  if (*Status == EFI_BUFFER_TOO_SMALL) {

+

+    SafeFreePool (*Buffer);

+

+    *Buffer = AllocateZeroPool (BufferSize);

+

+    if (*Buffer) {

+      TryAgain = TRUE;

+    } else {

+      *Status = EFI_OUT_OF_RESOURCES;

+    }

+  }

+  //

+  // If there's an error, free the buffer

+  //

+  if (!TryAgain && EFI_ERROR (*Status) && *Buffer) {

+    SafeFreePool (*Buffer);

+    *Buffer = NULL;

+  }

+

+  return TryAgain;

+}

+

+VOID *

+EfiLibGetVariable (

+  IN CHAR16               *Name,

+  IN EFI_GUID             *VendorGuid

+  )

+/*++

+

+Routine Description:

+  Function returns the value of the specified variable.

+

+Arguments:

+  Name                - A Null-terminated Unicode string that is 

+                        the name of the vendor's variable.

+

+  VendorGuid          - A unique identifier for the vendor.

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN VarSize;

+

+  return BdsLibGetVariableAndSize (Name, VendorGuid, &VarSize);

+}

+

+EFI_STATUS

+EfiLibDeleteVariable (

+  IN CHAR16   *VarName,

+  IN EFI_GUID *VarGuid

+  )

+/*++

+

+Routine Description:

+  Function deletes the variable specified by VarName and VarGuid.

+

+Arguments:

+  VarName              - A Null-terminated Unicode string that is 

+                         the name of the vendor's variable.

+

+  VendorGuid           - A unique identifier for the vendor.

+

+Returns:

+

+  EFI_SUCCESS          - The variable was found and removed

+

+  EFI_UNSUPPORTED      - The variable store was inaccessible

+

+  EFI_OUT_OF_RESOURCES - The temporary buffer was not available

+

+  EFI_NOT_FOUND        - The variable was not found

+

+--*/

+{

+  VOID        *VarBuf;

+  EFI_STATUS  Status;

+

+  VarBuf  = EfiLibGetVariable (VarName, VarGuid);

+  Status  = EFI_NOT_FOUND;

+

+  if (VarBuf) {

+    //

+    // Delete variable from Storage

+    //

+    Status = gRT->SetVariable (VarName, VarGuid, VAR_FLAG, 0, NULL);

+    ASSERT (!EFI_ERROR (Status));

+    SafeFreePool (VarBuf);

+  }

+

+  return Status;

+}

+

+EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *

+EfiLibFileSystemVolumeLabelInfo (

+  IN EFI_FILE_HANDLE      FHand

+  )

+/*++

+

+Routine Description:

+

+  Function gets the file system information from an open file descriptor, 

+  and stores it in a buffer allocated from pool.

+

+Arguments:

+

+  Fhand         - A file handle

+

+Returns:

+  

+  A pointer to a buffer with file information or NULL is returned

+

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;

+  UINTN                             BufferSize;

+  //

+  // Initialize for GrowBuffer loop

+  //

+  Buffer      = NULL;

+  BufferSize  = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;

+

+  //

+  // Call the real function

+  //

+  while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {

+    Status = FHand->GetInfo (

+                      FHand,

+                      &gEfiFileSystemVolumeLabelInfoIdGuid,

+                      &BufferSize,

+                      Buffer

+                      );

+  }

+

+  return Buffer;

+}

+

+CHAR16 *

+EfiStrDuplicate (

+  IN CHAR16   *Src

+  )

+{

+  CHAR16  *Dest;

+  UINTN   Size;

+

+  Size  = StrSize (Src);

+  Dest  = AllocateZeroPool (Size);

+  ASSERT (Dest != NULL);

+  if (Dest) {

+    CopyMem (Dest, Src, Size);

+  }

+

+  return Dest;

+}

+

+EFI_FILE_INFO *

+EfiLibFileInfo (

+  IN EFI_FILE_HANDLE      FHand

+  )

+/*++

+

+Routine Description:

+

+  Function gets the file information from an open file descriptor, and stores it 

+  in a buffer allocated from pool.

+

+Arguments:

+

+  Fhand         - A file handle

+

+Returns:

+  

+  A pointer to a buffer with file information or NULL is returned

+

+--*/

+{

+  EFI_STATUS    Status;

+  EFI_FILE_INFO *Buffer;

+  UINTN         BufferSize;

+

+  //

+  // Initialize for GrowBuffer loop

+  //

+  Buffer      = NULL;

+  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;

+

+  //

+  // Call the real function

+  //

+  while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {

+    Status = FHand->GetInfo (

+                      FHand,

+                      &gEfiFileInfoGuid,

+                      &BufferSize,

+                      Buffer

+                      );

+  }

+

+  return Buffer;

+}

+

+UINTN

+EfiDevicePathInstanceCount (

+  IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath

+  )

+/*++

+

+Routine Description:

+  Function is used to determine the number of device path instances 

+  that exist in a device path.

+

+Arguments:

+  DevicePath           - A pointer to a device path data structure.

+

+Returns:

+

+  This function counts and returns the number of device path instances 

+  in DevicePath.

+

+--*/

+{

+  UINTN Count;

+  UINTN Size;

+

+  Count = 0;

+  while (GetNextDevicePathInstance (&DevicePath, &Size)) {

+    Count += 1;

+  }

+

+  return Count;

+}

+

+VOID *

+EfiReallocatePool (

+  IN VOID                 *OldPool,

+  IN UINTN                OldSize,

+  IN UINTN                NewSize

+  )

+/*++

+

+Routine Description:

+  Adjusts the size of a previously allocated buffer.

+

+Arguments:

+  OldPool               - A pointer to the buffer whose size is being adjusted.

+  OldSize               - The size of the current buffer.

+  NewSize               - The size of the new buffer.

+

+Returns:

+

+  EFI_SUCEESS           - The requested number of bytes were allocated.

+

+  EFI_OUT_OF_RESOURCES  - The pool requested could not be allocated.

+

+  EFI_INVALID_PARAMETER - The buffer was invalid.

+

+--*/

+{

+  VOID  *NewPool;

+

+  NewPool = NULL;

+  if (NewSize) {

+    NewPool = AllocateZeroPool (NewSize);

+  }

+

+  if (OldPool) {

+    if (NewPool) {

+      CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);

+    }

+

+    SafeFreePool (OldPool);

+  }

+

+  return NewPool;

+}

+

+EFI_STATUS

+EfiLibGetStringFromToken (

+  IN      EFI_GUID                  *ProducerGuid,

+  IN      STRING_REF                Token,

+  OUT     CHAR16                    **String

+  )

+/*++

+

+Routine Description:

+  

+  Acquire the string associated with the ProducerGuid and return it.

+

+Arguments:

+  

+  ProducerGuid - The Guid to search the HII database for

+  Token        - The token value of the string to extract

+  String       - The string that is extracted

+  

+Returns:

+

+  EFI_SUCCESS           -  Buffer filled with the requested forms. BufferLength

+                           was updated.

+  EFI_BUFFER_TOO_SMALL  -  The buffer provided was not large enough to allow the form to be stored.

+

+--*/

+{

+  EFI_STATUS        Status;

+  UINT16            HandleBufferLength;

+  EFI_HII_HANDLE    *HiiHandleBuffer;

+  UINTN             StringBufferLength;

+  UINTN             NumberOfHiiHandles;

+  UINTN             Index;

+  UINT16            Length;

+  EFI_GUID          HiiGuid;

+  EFI_HII_PROTOCOL  *Hii;

+

+  HandleBufferLength  = 0x1000;

+  HiiHandleBuffer     = NULL;

+  Status = gBS->LocateProtocol (

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  &Hii

+                  );

+  if (EFI_ERROR (Status)) {

+    *String = NULL;

+    return Status;

+  }

+  //

+  // Get all the Hii handles

+  //

+  HiiHandleBuffer = AllocateZeroPool (HandleBufferLength);

+  ASSERT (HiiHandleBuffer != NULL);

+

+  Status = Hii->FindHandles (Hii, &HandleBufferLength, HiiHandleBuffer);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get the Hii Handle that matches the StructureNode->ProducerName

+  //

+  NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);

+  for (Index = 0; Index < NumberOfHiiHandles; Index++) {

+    Length = 0;

+    Status = ExtractDataFromHiiHandle (

+              HiiHandleBuffer[Index],

+              &Length,

+              NULL,

+              &HiiGuid

+              );

+    if (CompareGuid (ProducerGuid, &HiiGuid)) {

+      break;

+    }

+  }

+  //

+  // Find the string based on the current language

+  //

+  StringBufferLength  = 0x100;

+  *String             = AllocateZeroPool (0x100);

+  ASSERT (*String != NULL);

+

+  Status = Hii->GetString (

+                  Hii,

+                  HiiHandleBuffer[Index],

+                  Token,

+                  FALSE,

+                  NULL,

+                  &StringBufferLength,

+                  *String

+                  );

+

+  gBS->FreePool (HiiHandleBuffer);

+

+  return Status;

+}

+

+BOOLEAN

+TimeCompare (

+  IN EFI_TIME               *FirstTime,

+  IN EFI_TIME               *SecondTime

+  )

+/*++

+

+Routine Description:

+  Compare two EFI_TIME data.

+

+Arguments:

+

+  FirstTime         - A pointer to the first EFI_TIME data.

+  SecondTime        - A pointer to the second EFI_TIME data.

+

+Returns:

+  TRUE              The FirstTime is not later than the SecondTime.

+  FALSE             The FirstTime is later than the SecondTime.

+  

+--*/

+{

+  if (FirstTime->Year != SecondTime->Year) {

+    return (BOOLEAN) (FirstTime->Year < SecondTime->Year);

+  } else if (FirstTime->Month != SecondTime->Month) {

+    return (BOOLEAN) (FirstTime->Month < SecondTime->Month);

+  } else if (FirstTime->Day != SecondTime->Day) {

+    return (BOOLEAN) (FirstTime->Day < SecondTime->Day);

+  } else if (FirstTime->Hour != SecondTime->Hour) {

+    return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);

+  } else if (FirstTime->Minute != SecondTime->Minute) {

+    return (BOOLEAN) (FirstTime->Minute < FirstTime->Minute);

+  } else if (FirstTime->Second != SecondTime->Second) {

+    return (BOOLEAN) (FirstTime->Second < SecondTime->Second);

+  }

+

+  return (BOOLEAN) (FirstTime->Nanosecond <= SecondTime->Nanosecond);

+}

+

+UINT16 *

+EfiLibStrFromDatahub (

+  IN EFI_DEVICE_PATH_PROTOCOL                 *DevPath

+  )

+{

+  EFI_STATUS                                  Status;

+  UINT16                                      *Desc;

+  EFI_DATA_HUB_PROTOCOL                       *Datahub;

+  UINT64                                      Count;

+  EFI_DATA_RECORD_HEADER                      *Record;

+  EFI_SUBCLASS_TYPE1_HEADER                   *DataHdr;

+  EFI_GUID                                    MiscGuid = EFI_MISC_SUBCLASS_GUID;

+  EFI_MISC_ONBOARD_DEVICE_DATA                *ob;

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *Port;

+  EFI_TIME                                    CurTime;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiDataHubProtocolGuid,

+                  NULL,

+                  &Datahub

+                  );

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+

+  Status = gRT->GetTime (&CurTime, NULL);

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+

+  Count = 0;

+  do {

+    Status = Datahub->GetNextRecord (Datahub, &Count, NULL, &Record);

+

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA && CompareGuid (&Record->DataRecordGuid, &MiscGuid)) {

+      //

+      // This record is what we need

+      //

+      DataHdr = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);

+      if (EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER == DataHdr->RecordType) {

+        ob = (EFI_MISC_ONBOARD_DEVICE_DATA *) (DataHdr + 1);

+        if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL *) &ob->OnBoardDevicePath, DevPath)) {

+          EfiLibGetStringFromToken (&Record->ProducerName, ob->OnBoardDeviceDescription, &Desc);

+          return Desc;

+        }

+      }

+

+      if (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER == DataHdr->RecordType) {

+        Port = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) (DataHdr + 1);

+        if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL *) &Port->PortPath, DevPath)) {

+          EfiLibGetStringFromToken (&Record->ProducerName, Port->PortExternalConnectorDesignator, &Desc);

+          return Desc;

+        }

+      }

+    }

+

+  } while (TimeCompare (&Record->LogTime, &CurTime) && Count != 0);

+

+  return NULL;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c
new file mode 100644
index 0000000..c4b3211
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c
@@ -0,0 +1,1305 @@
+/*++ 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BootMaint.c

+    

+Abstract:

+

+  Boot Maintainence Main File

+

+--*/

+

+#include "Generic/Bds.h"

+#include "BootMaint.h"

+#include "BdsStrDefs.h"

+#include "formguid.h"

+

+//

+// Form binary for Boot Maintenance

+//

+extern UINT8    bmBin[];

+extern UINT8    FEBin[];

+extern EFI_GUID gBdsStringPackGuid;

+extern BOOLEAN  gConnectAllHappened;

+

+EFI_GUID        EfiLegacyDevOrderGuid = EFI_LEGACY_DEV_ORDER_VARIABLE_GUID;

+

+VOID

+InitAllMenu (

+  IN  BMM_CALLBACK_DATA    *CallbackData

+  );

+

+VOID

+FreeAllMenu (

+  VOID

+  );

+

+EFI_STATUS

+CreateMenuStringToken (

+  IN BMM_CALLBACK_DATA                *CallbackData,

+  IN EFI_HII_HANDLE                   HiiHandle,

+  IN BM_MENU_OPTION                   *MenuOption

+  )

+/*++

+Routine Description:

+

+  Create string tokens for a menu from its help strings and display strings

+

+Arguments:

+

+  HiiHandle       - Hii Handle of the package to be updated.

+  

+  MenuOption      - The Menu whose string tokens need to be created

+

+Returns:

+

+  EFI_SUCCESS     - string tokens created successfully

+  

+  others          - contain some errors

+  

+--*/

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINTN         Index;

+

+  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);

+    CallbackData->Hii->NewString (

+                        CallbackData->Hii,

+                        NULL,

+                        HiiHandle,

+                        &NewMenuEntry->DisplayStringToken,

+                        NewMenuEntry->DisplayString

+                        );

+

+    if (NULL == NewMenuEntry->HelpString) {

+      NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;

+    } else {

+      CallbackData->Hii->NewString (

+                          CallbackData->Hii,

+                          NULL,

+                          HiiHandle,

+                          &NewMenuEntry->HelpStringToken,

+                          NewMenuEntry->HelpString

+                          );

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+DriverCallback (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *Data,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+/*++

+Routine Description:

+

+  Callback Function for boot maintenance utility user interface interaction.

+

+Arguments:

+

+  This            - File explorer callback protocol pointer.     

+  KeyValue        - Key value to identify the type of data to expect.

+  Data            - A pointer to the data being sent to the original exporting driver.

+  Packet          - A pointer to a packet of information which a driver passes back to the browser.

+

+Returns:

+

+  EFI_SUCCESS     - Callback ended successfully.

+  Others          - Contain some errors.

+  

+--*/

+{

+  BMM_CALLBACK_DATA *Private;

+  BM_MENU_ENTRY     *NewMenuEntry;

+  BMM_FAKE_NV_DATA  *CurrentFakeNVMap;

+  EFI_STATUS        Status;

+  UINTN             OldValue;

+  UINTN             NewValue;

+  UINTN             Number;

+  UINTN             Pos;

+  UINTN             Bit;

+  UINT16            NewValuePos;

+  UINT16            Index2;

+  UINT16            Index;

+  UINT8             *OldLegacyDev;

+  UINT8             *NewLegacyDev;

+  UINT8             *Location;

+  UINT8             *DisMap;

+  FORM_ID           FormId;

+

+  OldValue                        = 0;

+  NewValue                        = 0;

+  Number                          = 0;

+  OldLegacyDev                    = NULL;

+  NewLegacyDev                    = NULL;

+  NewValuePos                     = 0;

+  DisMap                          = NULL;

+

+  Private                         = BMM_CALLBACK_DATA_FROM_THIS (This);

+  UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->BmmCallbackHandle;

+  CurrentFakeNVMap                = (BMM_FAKE_NV_DATA *) Data->NvRamMap;

+  Private->BmmFakeNvData          = CurrentFakeNVMap;

+  Location                        = (UINT8 *) &UpdateData->Data;

+

+  UpdatePageId (Private, KeyValue);

+

+  //

+  // need to be subtituded.

+  //

+  // Update Select FD/HD/CD/NET/BEV Order Form

+  //

+  if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||

+      FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||

+      FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||

+      FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||

+      FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||

+      ((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&

+      (KeyValue >= LEGACY_FD_QUESTION_ID) &&

+       (KeyValue < (LEGACY_BEV_QUESTION_ID + 100)) )

+      ) {

+

+    DisMap  = Private->BmmOldFakeNVData.DisableMap;

+

+    FormId  = Private->BmmPreviousPageId;

+    if (FormId == FORM_BOOT_SETUP_ID) {

+      FormId = Private->BmmCurrentPageId;

+    }

+

+    switch (FormId) {

+    case FORM_SET_FD_ORDER_ID:

+      Number        = (UINT16) LegacyFDMenu.MenuNumber;

+      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyFD;

+      NewLegacyDev  = CurrentFakeNVMap->LegacyFD;

+      break;

+

+    case FORM_SET_HD_ORDER_ID:

+      Number        = (UINT16) LegacyHDMenu.MenuNumber;

+      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyHD;

+      NewLegacyDev  = CurrentFakeNVMap->LegacyHD;

+      break;

+

+    case FORM_SET_CD_ORDER_ID:

+      Number        = (UINT16) LegacyCDMenu.MenuNumber;

+      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyCD;

+      NewLegacyDev  = CurrentFakeNVMap->LegacyCD;

+      break;

+

+    case FORM_SET_NET_ORDER_ID:

+      Number        = (UINT16) LegacyNETMenu.MenuNumber;

+      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyNET;

+      NewLegacyDev  = CurrentFakeNVMap->LegacyNET;

+      break;

+

+    case FORM_SET_BEV_ORDER_ID:

+      Number        = (UINT16) LegacyBEVMenu.MenuNumber;

+      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyBEV;

+      NewLegacyDev  = CurrentFakeNVMap->LegacyBEV;

+      break;

+

+    default:

+      break;

+    }

+    //

+    //  First, find the different position

+    //  if there is change, it should be only one

+    //

+    for (Index = 0; Index < Number; Index++) {

+      if (OldLegacyDev[Index] != NewLegacyDev[Index]) {

+        OldValue  = OldLegacyDev[Index];

+        NewValue  = NewLegacyDev[Index];

+        break;

+      }

+    }

+

+    if (Index != Number) {

+      //

+      // there is change, now process

+      //

+      if (0xFF == NewValue) {

+        //

+        // This item will be disable

+        // Just move the items behind this forward to overlap it

+        //

+        Pos = OldValue / 8;

+        Bit = 7 - (OldValue % 8);

+        DisMap[Pos] |= (UINT8) (1 << Bit);

+        for (Index2 = Index; Index2 < Number - 1; Index2++) {

+          NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];

+        }

+

+        NewLegacyDev[Index2] = 0xFF;

+      } else {

+        for (Index2 = 0; Index2 < Number; Index2++) {

+          if (Index2 == Index) {

+            continue;

+          }

+

+          if (OldLegacyDev[Index2] == NewValue) {

+            //

+            // If NewValue is in OldLegacyDev array

+            // remember its old position

+            //

+            NewValuePos = Index2;

+            break;

+          }

+        }

+

+        if (Index2 != Number) {

+          //

+          // We will change current item to an existing item

+          // (It's hard to describe here, please read code, it's like a cycle-moving)

+          //

+          for (Index2 = NewValuePos; Index2 != Index;) {

+            if (NewValuePos < Index) {

+              NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];

+              Index2++;

+            } else {

+              NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];

+              Index2--;

+            }

+          }

+        } else {

+          //

+          // If NewValue is not in OldlegacyDev array, we are changing to a disabled item

+          // so we should modify DisMap to reflect the change

+          //

+          Pos = NewValue / 8;

+          Bit = 7 - (NewValue % 8);

+          DisMap[Pos] &= ~ (UINT8) (1 << Bit);

+          if (0xFF != OldValue) {

+            //

+            // Because NewValue is a item that was disabled before

+            // so after changing the OldValue should be disabled

+            // actually we are doing a swap of enable-disable states of two items

+            //

+            Pos = OldValue / 8;

+            Bit = 7 - (OldValue % 8);

+            DisMap[Pos] |= (UINT8) (1 << Bit);

+          }

+        }

+      }

+      //

+      // To prevent DISABLE appears in the middle of the list

+      // we should perform a re-ordering

+      //

+      Index = 0;

+      while (Index < Number) {

+        if (0xFF != NewLegacyDev[Index]) {

+          Index++;

+          continue;

+        }

+

+        Index2 = Index;

+        Index2++;

+        while (Index2 < Number) {

+          if (0xFF != NewLegacyDev[Index2]) {

+            break;

+          }

+

+          Index2++;

+        }

+

+        if (Index2 < Number) {

+          NewLegacyDev[Index]   = NewLegacyDev[Index2];

+          NewLegacyDev[Index2]  = 0xFF;

+        }

+

+        Index++;

+      }

+

+      CopyMem (

+        OldLegacyDev,

+        NewLegacyDev,

+        Number

+        );

+    }

+  }

+

+  if (KeyValue < FILE_OPTION_OFFSET) {

+    if (KeyValue < NORMAL_GOTO_OFFSET) {

+      switch (KeyValue) {

+      case KEY_VALUE_BOOT_FROM_FILE:

+        Private->FeCurrentState = BOOT_FROM_FILE_STATE;

+

+        //

+        // Exit Bmm main formset to send File Explorer formset.

+        //

+        CreateCallbackPacket (Packet, EXIT_REQUIRED);

+

+        break;

+

+      case FORM_BOOT_ADD_ID:

+        Private->FeCurrentState = ADD_BOOT_OPTION_STATE;

+

+        //

+        // Exit Bmm main formset to send File Explorer formset.

+        //

+        CreateCallbackPacket (Packet, EXIT_REQUIRED);

+        break;

+

+      case FORM_DRV_ADD_FILE_ID:

+        Private->FeCurrentState = ADD_DRIVER_OPTION_STATE;

+

+        //

+        // Exit Bmm main formset to send File Explorer formset.

+        //

+        CreateCallbackPacket (Packet, EXIT_REQUIRED);

+

+        break;

+

+      case FORM_DRV_ADD_HANDLE_ID:

+        CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);

+        UpdateDrvAddHandlePage (Private);

+        break;

+

+      case FORM_BOOT_DEL_ID:

+        CleanUpPage (FORM_BOOT_DEL_ID, Private);

+        UpdateBootDelPage (Private);

+        break;

+

+      case FORM_BOOT_CHG_ID:

+      case FORM_DRV_CHG_ID:

+        UpdatePageBody (KeyValue, Private);

+        break;

+

+      case FORM_DRV_DEL_ID:

+        CleanUpPage (FORM_DRV_DEL_ID, Private);

+        UpdateDrvDelPage (Private);

+        break;

+

+      case FORM_BOOT_NEXT_ID:

+        CleanUpPage (FORM_BOOT_NEXT_ID, Private);

+        UpdateBootNextPage (Private);

+        break;

+

+      case FORM_TIME_OUT_ID:

+        CleanUpPage (FORM_TIME_OUT_ID, Private);

+        UpdateTimeOutPage (Private);

+        break;

+

+      case FORM_RESET:

+        gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);

+        return EFI_UNSUPPORTED;

+

+      case FORM_CON_IN_ID:

+      case FORM_CON_OUT_ID:

+      case FORM_CON_ERR_ID:

+        UpdatePageBody (KeyValue, Private);

+        break;

+

+      case FORM_CON_COM_ID:

+        CleanUpPage (FORM_CON_COM_ID, Private);

+        UpdateConCOMPage (Private);

+        break;

+

+      case FORM_SET_FD_ORDER_ID:

+      case FORM_SET_HD_ORDER_ID:

+      case FORM_SET_CD_ORDER_ID:

+      case FORM_SET_NET_ORDER_ID:

+      case FORM_SET_BEV_ORDER_ID:

+        CleanUpPage (KeyValue, Private);

+        UpdateSetLegacyDeviceOrderPage (KeyValue, Private);

+        break;

+

+      case KEY_VALUE_SAVE_AND_EXIT:

+      case KEY_VALUE_NO_SAVE_AND_EXIT:

+

+        if (KeyValue == KEY_VALUE_SAVE_AND_EXIT) {

+          Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);

+          if (EFI_ERROR (Status)) {

+            return Status;

+          }

+        } else if (KeyValue == KEY_VALUE_NO_SAVE_AND_EXIT) {

+          DiscardChangeHandler (Private, CurrentFakeNVMap);

+        }

+        //

+        // Tell browser not to ask for confirmation of changes,

+        // since we have already applied or discarded.

+        //

+        CreateCallbackPacket (Packet, NV_NOT_CHANGED);

+        break;

+

+      default:

+        break;

+      }

+    } else if ((KeyValue >= TERMINAL_OPTION_OFFSET) && (KeyValue < CONSOLE_OPTION_OFFSET)) {

+      Index2                    = (UINT16) (KeyValue - TERMINAL_OPTION_OFFSET);

+      Private->CurrentTerminal  = Index2;

+

+      CleanUpPage (FORM_CON_COM_SETUP_ID, Private);

+      UpdateTerminalPage (Private);

+

+    } else if (KeyValue >= HANDLE_OPTION_OFFSET) {

+      Index2                  = (UINT16) (KeyValue - HANDLE_OPTION_OFFSET);

+

+      NewMenuEntry            = BOpt_GetMenuEntry (&DriverMenu, Index2);

+      Private->HandleContext  = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;

+

+      CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);

+

+      Private->MenuEntry                  = NewMenuEntry;

+      Private->LoadContext->FilePathList  = Private->HandleContext->DevicePath;

+

+      UpdateDriverAddHandleDescPage (Private);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+ApplyChangeHandler (

+  IN  BMM_CALLBACK_DATA               *Private,

+  IN  BMM_FAKE_NV_DATA                *CurrentFakeNVMap,

+  IN  FORM_ID                         FormId

+  )

+/*++

+

+Routine Description:

+

+  Function handling request to apply changes for BMM pages.

+

+Arguments:

+

+  Private          - Pointer to callback data buffer.

+  CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM

+  FormId           - ID of the form which has sent the request to apply change.

+

+Returns:

+

+  EFI_SUCCESS      - Change successfully applied.

+  Other            - Error occurs while trying to apply changes.

+

+--*/

+{

+  BM_CONSOLE_CONTEXT  *NewConsoleContext;

+  BM_TERMINAL_CONTEXT *NewTerminalContext;

+  BM_LOAD_CONTEXT     *NewLoadContext;

+  BM_MENU_ENTRY       *NewMenuEntry;

+  EFI_STATUS          Status;

+  UINT16              Index;

+

+  Status = EFI_SUCCESS;

+

+  switch (FormId) {

+  case FORM_SET_FD_ORDER_ID:

+  case FORM_SET_HD_ORDER_ID:

+  case FORM_SET_CD_ORDER_ID:

+  case FORM_SET_NET_ORDER_ID:

+  case FORM_SET_BEV_ORDER_ID:

+    Var_UpdateBBSOption (Private);

+    break;

+

+  case FORM_BOOT_DEL_ID:

+    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+      NewMenuEntry            = BOpt_GetMenuEntry (&BootOptionMenu, Index);

+      NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+      NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];

+    }

+

+    Var_DelBootOption ();

+    break;

+

+  case FORM_DRV_DEL_ID:

+    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {

+      NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);

+      NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+      NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];

+    }

+

+    Var_DelDriverOption ();

+    break;

+

+  case FORM_BOOT_CHG_ID:

+    Status = Var_UpdateBootOrder (Private);

+    break;

+

+  case FORM_DRV_CHG_ID:

+    Status = Var_UpdateDriverOrder (Private);

+    break;

+

+  case FORM_TIME_OUT_ID:

+    Status = gRT->SetVariable (

+                    L"Timeout",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    sizeof (UINT16),

+                    &(CurrentFakeNVMap->BootTimeOut)

+                    );

+    if (EFI_ERROR (Status)) {

+      goto Error;

+    }

+

+    Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;

+    break;

+

+  case FORM_BOOT_NEXT_ID:

+    Status = Var_UpdateBootNext (Private);

+    break;

+

+  case FORM_CON_COM_ID:

+    NewMenuEntry                      = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);

+

+    NewTerminalContext                = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+

+    NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;

+    NewTerminalContext->BaudRate      = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;

+    NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;

+    NewTerminalContext->DataBits      = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;

+    NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;

+    NewTerminalContext->StopBits      = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;

+    NewTerminalContext->ParityIndex   = CurrentFakeNVMap->COMParity;

+    NewTerminalContext->Parity        = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;

+    NewTerminalContext->TerminalType  = CurrentFakeNVMap->COMTerminalType;

+

+    ChangeTerminalDevicePath (

+      NewTerminalContext->DevicePath,

+      FALSE

+      );

+

+    Var_UpdateConsoleInpOption ();

+    Var_UpdateConsoleOutOption ();

+    Var_UpdateErrorOutOption ();

+    break;

+

+  case FORM_CON_IN_ID:

+    for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {

+      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);

+      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;

+      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];

+    }

+

+    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+      NewMenuEntry                = BOpt_GetMenuEntry (&TerminalMenu, Index);

+      NewTerminalContext          = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+      NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];

+    }

+

+    Var_UpdateConsoleInpOption ();

+    break;

+

+  case FORM_CON_OUT_ID:

+    for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {

+      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);

+      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;

+      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];

+    }

+

+    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+      NewMenuEntry                  = BOpt_GetMenuEntry (&TerminalMenu, Index);

+      NewTerminalContext            = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+      NewTerminalContext->IsConOut  = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];

+    }

+

+    Var_UpdateConsoleOutOption ();

+    break;

+

+  case FORM_CON_ERR_ID:

+    for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {

+      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);

+      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;

+      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];

+    }

+

+    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+      NewMenuEntry                  = BOpt_GetMenuEntry (&TerminalMenu, Index);

+      NewTerminalContext            = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+      NewTerminalContext->IsStdErr  = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];

+    }

+

+    Var_UpdateErrorOutOption ();

+    break;

+

+  case FORM_DRV_ADD_HANDLE_DESC_ID:

+    Status = Var_UpdateDriverOption (

+               Private,

+               Private->BmmHiiHandle,

+               CurrentFakeNVMap->DriverAddHandleDesc,

+               CurrentFakeNVMap->DriverAddHandleOptionalData,

+               CurrentFakeNVMap->DriverAddForceReconnect

+               );

+    if (EFI_ERROR (Status)) {

+      goto Error;

+    }

+

+    BOpt_GetDriverOptions (Private);

+    CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);

+    break;

+

+  default:

+    break;

+  }

+

+Error:

+  return Status;

+}

+

+VOID

+DiscardChangeHandler (

+  IN  BMM_CALLBACK_DATA               *Private,

+  IN  BMM_FAKE_NV_DATA                *CurrentFakeNVMap

+  )

+{

+  UINT16  Index;

+

+  switch (Private->BmmPreviousPageId) {

+  case FORM_BOOT_CHG_ID:

+  case FORM_DRV_CHG_ID:

+    CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);

+    break;

+

+  case FORM_BOOT_DEL_ID:

+    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+      CurrentFakeNVMap->BootOptionDel[Index] = 0x00;

+    }

+    break;

+

+  case FORM_DRV_DEL_ID:

+    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {

+      CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;

+    }

+    break;

+

+  case FORM_BOOT_NEXT_ID:

+    CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;

+    break;

+

+  case FORM_TIME_OUT_ID:

+    CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;

+    break;

+

+  case FORM_DRV_ADD_HANDLE_DESC_ID:

+  case FORM_DRV_ADD_FILE_ID:

+  case FORM_DRV_ADD_HANDLE_ID:

+    CurrentFakeNVMap->DriverAddHandleDesc[0]          = 0x0000;

+    CurrentFakeNVMap->DriverAddHandleOptionalData[0]  = 0x0000;

+    break;

+

+  default:

+    break;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+NvWrite (

+  IN     EFI_FORM_CALLBACK_PROTOCOL              *This,

+  IN     CHAR16                                  *VariableName,

+  IN     EFI_GUID                                *VendorGuid,

+  OUT    UINT32                                  Attributes OPTIONAL,

+  IN OUT UINTN                                   DataSize,

+  OUT    VOID                                    *Buffer,

+  OUT    BOOLEAN                                 *ResetRequired

+  )

+{

+  //

+  // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InitializeBM (

+  VOID

+  )

+/*++

+Routine Description:

+

+  Initialize the Boot Maintenance Utitliy

+

+Arguments:

+

+  ImageHandle     - caller provided handle

+  

+  SystemTable     - caller provided system tables

+

+Returns:

+

+  EFI_SUCCESS     - utility ended successfully

+  

+  others          - contain some errors

+  

+--*/

+{

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  EFI_HII_PACKAGES          *PackageList;

+  BMM_CALLBACK_DATA         *BmmCallbackInfo;

+  EFI_HII_PROTOCOL          *Hii;

+  EFI_HII_HANDLE            HiiHandle;

+  EFI_STATUS                Status;

+  EFI_HANDLE                Handle;

+  UINT8                     *Ptr;

+  UINT8                     *Location;

+

+  Status      = EFI_SUCCESS;

+  UpdateData  = NULL;

+  //

+  // Initialize EfiUtilityLib and EfiDriverLib

+  // Since many functions in UtilityLib must be used and

+  // SetupBrowser use DriverLib

+  //

+  //

+  // There should be only one EFI_HII_PROTOCOL Image

+  //

+  Status = EfiLibLocateProtocol (&gEfiHiiProtocolGuid, &Hii);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Create CallbackData structures for Driver Callback

+  //

+  BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));

+  if (!BmmCallbackInfo) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Create LoadOption in BmmCallbackInfo for Driver Callback

+  //

+  Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));

+  if (!Ptr) {

+    SafeFreePool (BmmCallbackInfo);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Initialize Bmm callback data.

+  //

+  BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;

+  Ptr += sizeof (BM_LOAD_CONTEXT);

+

+  BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;

+  Ptr += sizeof (BM_FILE_CONTEXT);

+

+  BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;

+  Ptr += sizeof (BM_HANDLE_CONTEXT);

+

+  BmmCallbackInfo->MenuEntry      = (BM_MENU_ENTRY *) Ptr;

+

+  BmmCallbackInfo->BmmFakeNvData  = &BmmCallbackInfo->BmmOldFakeNVData;

+

+  ZeroMem (BmmCallbackInfo->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));

+

+  BmmCallbackInfo->Signature                  = BMM_CALLBACK_DATA_SIGNATURE;

+  BmmCallbackInfo->Hii                        = Hii;

+  BmmCallbackInfo->BmmDriverCallback.NvRead   = NULL;

+  BmmCallbackInfo->BmmDriverCallback.NvWrite  = NvWrite;

+  BmmCallbackInfo->BmmDriverCallback.Callback = DriverCallback;

+  BmmCallbackInfo->BmmPreviousPageId          = FORM_MAIN_ID;

+  BmmCallbackInfo->BmmCurrentPageId           = FORM_MAIN_ID;

+  BmmCallbackInfo->FeDriverCallback.NvRead    = NULL;

+  BmmCallbackInfo->FeDriverCallback.NvWrite   = NvWrite;

+  BmmCallbackInfo->FeDriverCallback.Callback  = FileExplorerCallback;

+  BmmCallbackInfo->FeCurrentState             = INACTIVE_STATE;

+  BmmCallbackInfo->FeDisplayContext           = UNKNOWN_CONTEXT;

+

+  //

+  // Install bmm callback protocol interface

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiFormCallbackProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &BmmCallbackInfo->BmmDriverCallback

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  BmmCallbackInfo->BmmCallbackHandle = Handle;

+

+  //

+  // Install file explorer callback protocol interface

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiFormCallbackProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &BmmCallbackInfo->FeDriverCallback

+                  );

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  BmmCallbackInfo->FeCallbackHandle = Handle;

+

+  //

+  // Post our VFR to the HII database.

+  //

+  PackageList = PreparePackages (1, &gBdsStringPackGuid, bmBin);

+  Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);

+  gBS->FreePool (PackageList);

+

+  BmmCallbackInfo->BmmHiiHandle = HiiHandle;

+

+  PackageList                   = PreparePackages (1, &gBdsStringPackGuid, FEBin);

+  Status                        = Hii->NewPack (Hii, PackageList, &HiiHandle);

+  gBS->FreePool (PackageList);

+

+  BmmCallbackInfo->FeHiiHandle = HiiHandle;

+

+  //

+  // Allocate space for creation of Buffer

+  //

+  UpdateData = AllocateZeroPool (UPDATE_DATA_SIZE);

+  if (!UpdateData) {

+    SafeFreePool (BmmCallbackInfo->LoadContext);

+    SafeFreePool (BmmCallbackInfo);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Initialize UpdateData structure

+  //

+  RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) BmmCallbackInfo->BmmCallbackHandle, FALSE, 0, 0);

+

+  Location = (UINT8 *) &UpdateData->Data;

+

+  InitializeStringDepository ();

+

+  InitAllMenu (BmmCallbackInfo);

+

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);

+  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);

+

+  UpdateBootDelPage (BmmCallbackInfo);

+  UpdateDrvDelPage (BmmCallbackInfo);

+

+  if (TerminalMenu.MenuNumber > 0) {

+    BmmCallbackInfo->CurrentTerminal = 0;

+    UpdateTerminalPage (BmmCallbackInfo);

+  }

+

+  Location  = (UINT8 *) &UpdateData->Data;

+  Status    = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);

+  if (!EFI_ERROR (Status)) {

+    //

+    // If LegacyBios Protocol is installed, add 3 tags about legacy boot option

+    // in BootOption form: legacy FD/HD/CD/NET/BEV

+    //

+    UpdateData->DataCount = 5;

+    CreateGotoOpCode (

+      FORM_SET_FD_ORDER_ID,

+      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),

+      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      FORM_SET_FD_ORDER_ID,

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+    CreateGotoOpCode (

+      FORM_SET_HD_ORDER_ID,

+      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),

+      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      FORM_SET_HD_ORDER_ID,

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+    CreateGotoOpCode (

+      FORM_SET_CD_ORDER_ID,

+      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),

+      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      FORM_SET_CD_ORDER_ID,

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+    CreateGotoOpCode (

+      FORM_SET_NET_ORDER_ID,

+      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),

+      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      FORM_SET_NET_ORDER_ID,

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+    CreateGotoOpCode (

+      FORM_SET_BEV_ORDER_ID,

+      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),

+      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      FORM_SET_BEV_ORDER_ID,

+      Location

+      );

+

+    Hii->UpdateForm (

+          Hii,

+          BmmCallbackInfo->BmmHiiHandle,

+          (EFI_FORM_LABEL) FORM_BOOT_LEGACY_DEVICE_ID,

+          TRUE,

+          UpdateData

+          );

+  }

+  //

+  // Dispatch BMM main formset and File Explorer formset.

+  //

+  FormSetDispatcher (BmmCallbackInfo);

+

+  Hii->ResetStrings (Hii, HiiHandle);

+

+  CleanUpStringDepository ();

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  FreeAllMenu ();

+

+  SafeFreePool (BmmCallbackInfo->LoadContext);

+  BmmCallbackInfo->LoadContext = NULL;

+  SafeFreePool (BmmCallbackInfo);

+  BmmCallbackInfo = NULL;

+  SafeFreePool (UpdateData);

+  UpdateData = NULL;

+

+  return Status;

+}

+

+VOID

+InitAllMenu (

+  IN  BMM_CALLBACK_DATA    *CallbackData

+  )

+{

+  InitializeListHead (&BootOptionMenu.Head);

+  InitializeListHead (&DriverOptionMenu.Head);

+  BOpt_GetBootOptions (CallbackData);

+  BOpt_GetDriverOptions (CallbackData);

+  BOpt_GetLegacyOptions ();

+  InitializeListHead (&FsOptionMenu.Head);

+  BOpt_FindDrivers ();

+  InitializeListHead (&DirectoryMenu.Head);

+  InitializeListHead (&ConsoleInpMenu.Head);

+  InitializeListHead (&ConsoleOutMenu.Head);

+  InitializeListHead (&ConsoleErrMenu.Head);

+  InitializeListHead (&TerminalMenu.Head);

+  LocateSerialIo ();

+  GetAllConsoles ();

+}

+

+VOID

+FreeAllMenu (

+  VOID

+  )

+{

+  BOpt_FreeMenu (&DirectoryMenu);

+  BOpt_FreeMenu (&FsOptionMenu);

+  BOpt_FreeMenu (&BootOptionMenu);

+  BOpt_FreeMenu (&DriverOptionMenu);

+  BOpt_FreeMenu (&DriverMenu);

+  BOpt_FreeLegacyOptions ();

+  FreeAllConsoles ();

+}

+

+VOID

+InitializeStringDepository (

+  VOID

+  )

+/*++

+Routine Description:

+  Intialize all the string depositories.

+

+Arguments:

+  None.

+

+Returns:

+  None.  

+--*/

+{

+  STRING_DEPOSITORY *StringDepository;

+  StringDepository              = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);

+  FileOptionStrDepository       = StringDepository++;

+  ConsoleOptionStrDepository    = StringDepository++;

+  BootOptionStrDepository       = StringDepository++;

+  BootOptionHelpStrDepository   = StringDepository++;

+  DriverOptionStrDepository     = StringDepository++;

+  DriverOptionHelpStrDepository = StringDepository++;

+  TerminalStrDepository         = StringDepository;

+}

+

+STRING_REF

+GetStringTokenFromDepository (

+  IN   BMM_CALLBACK_DATA     *CallbackData,

+  IN   STRING_DEPOSITORY     *StringDepository

+  )

+/*++

+Routine Description:

+  Fetch a usable string node from the string depository and return the string token.

+

+Arguments:

+  StringDepository       - Pointer of the string depository.

+

+Returns:

+  STRING_REF             - String token.

+--*/

+{

+  STRING_LIST_NODE  *CurrentListNode;

+  STRING_LIST_NODE  *NextListNode;

+

+  CurrentListNode = StringDepository->CurrentNode;

+

+  if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {

+    //

+    // Fetch one reclaimed node from the list.

+    //

+    NextListNode = StringDepository->CurrentNode->Next;

+  } else {

+    //

+    // If there is no usable node in the list, update the list.

+    //

+    NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));

+

+    CallbackData->Hii->NewString (

+                        CallbackData->Hii,

+                        NULL,

+                        CallbackData->BmmHiiHandle,

+                        &(NextListNode->StringToken),

+                        L" "

+                        );

+

+    ASSERT (NextListNode->StringToken != 0);

+

+    StringDepository->TotalNodeNumber++;

+

+    if (NULL == CurrentListNode) {

+      StringDepository->ListHead = NextListNode;

+    } else {

+      CurrentListNode->Next = NextListNode;

+    }

+  }

+

+  StringDepository->CurrentNode = NextListNode;

+

+  return StringDepository->CurrentNode->StringToken;

+}

+

+VOID

+ReclaimStringDepository (

+  VOID

+  )

+/*++

+Routine Description:

+  Reclaim string depositories by moving the current node pointer to list head..

+

+Arguments:

+  None.

+

+Returns:

+  None.

+--*/

+{

+  UINTN             DepositoryIndex;

+  STRING_DEPOSITORY *StringDepository;

+

+  StringDepository = FileOptionStrDepository;

+  for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {

+    StringDepository->CurrentNode = StringDepository->ListHead;

+    StringDepository++;

+  }

+}

+

+VOID

+CleanUpStringDepository (

+  VOID

+  )

+/*++

+Routine Description:

+  Release resource for all the string depositories.

+

+Arguments:

+  None.

+

+Returns:

+  None.

+--*/

+{

+  UINTN             NodeIndex;

+  UINTN             DepositoryIndex;

+  STRING_LIST_NODE  *CurrentListNode;

+  STRING_LIST_NODE  *NextListNode;

+  STRING_DEPOSITORY *StringDepository;

+

+  //

+  // Release string list nodes.

+  //

+  StringDepository = FileOptionStrDepository;

+  for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {

+    CurrentListNode = StringDepository->ListHead;

+    for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {

+      NextListNode = CurrentListNode->Next;

+      SafeFreePool (CurrentListNode);

+      CurrentListNode = NextListNode;

+    }

+

+    StringDepository++;

+  }

+  //

+  // Release string depository.

+  //

+  SafeFreePool (FileOptionStrDepository);

+}

+

+EFI_STATUS

+BdsStartBootMaint (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Start boot maintenance manager

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+  LIST_ENTRY  BdsBootOptionList;

+

+  InitializeListHead (&BdsBootOptionList);

+

+  //

+  // Connect all prior to entering the platform setup menu.

+  //

+  if (!gConnectAllHappened) {

+    BdsLibConnectAllDriversToAllControllers ();

+    gConnectAllHappened = TRUE;

+  }

+  //

+  // Have chance to enumerate boot device

+  //

+  BdsLibEnumerateAllBootOption (&BdsBootOptionList);

+

+  //

+  // Init the BMM

+  //

+  Status = InitializeBM ();

+

+  return Status;

+}

+

+EFI_STATUS

+FormSetDispatcher (

+  IN  BMM_CALLBACK_DATA    *CallbackData

+  )

+/*++

+

+Routine Description:

+  Dispatch BMM formset and FileExplorer formset.

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_FORM_BROWSER_PROTOCOL *FormConfig;

+  UINT8                     *Location;

+  EFI_STATUS                Status;

+  UINTN                     Index;

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_FILE_CONTEXT           *NewFileContext;

+

+  Location        = NULL;

+  Index           = 0;

+  NewMenuEntry    = NULL;

+  NewFileContext  = NULL;

+

+  //

+  // There should only be one Form Configuration protocol

+  //

+  Status = EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid, &FormConfig);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  while (1) {

+    UpdatePageId (CallbackData, FORM_MAIN_ID);

+

+    Status = FormConfig->SendForm (

+                          FormConfig,

+                          TRUE,

+                          &(CallbackData->BmmHiiHandle),

+                          1,

+                          NULL,

+                          NULL,

+                          (UINT8 *) CallbackData->BmmFakeNvData,

+                          NULL,

+                          NULL

+                          );

+

+    ReclaimStringDepository ();

+

+    //

+    // When this Formset returns, check if we are going to explore files.

+    //

+    if (INACTIVE_STATE != CallbackData->FeCurrentState) {

+      UpdateFileExplorer (CallbackData, 0);

+

+      Status = FormConfig->SendForm (

+                            FormConfig,

+                            TRUE,

+                            &(CallbackData->FeHiiHandle),

+                            1,

+                            NULL,

+                            NULL,

+                            NULL,

+                            NULL,

+                            NULL

+                            );

+

+      CallbackData->FeCurrentState    = INACTIVE_STATE;

+      CallbackData->FeDisplayContext  = UNKNOWN_CONTEXT;

+      ReclaimStringDepository ();

+    } else {

+      break;

+    }

+  }

+

+  return Status;

+}

+

+VOID

+CreateCallbackPacket (

+  OUT EFI_HII_CALLBACK_PACKET         **Packet,

+  IN  UINT16                          Flags

+  )

+{

+  *Packet = (EFI_HII_CALLBACK_PACKET *) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);

+  ASSERT (*Packet != NULL);

+

+  (*Packet)->DataArray.EntryCount   = 1;

+  (*Packet)->DataArray.NvRamMap     = NULL;

+  ((EFI_IFR_DATA_ENTRY *) (&((*Packet)->DataArray) + 1))->Flags  = Flags;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.h
new file mode 100644
index 0000000..1e0dc8d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.h
@@ -0,0 +1,1161 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  bootmaint.h

+

+Abstract:

+

+Revision History

+

+--*/

+

+#ifndef _BOOT_MAINT_H

+#define _BOOT_MAINT_H

+

+#include "BdsStrDefs.h"

+#include "Generic/BootMaint/BBSsupport.h"

+

+//

+// Constants which are variable names used to access variables

+//

+#define VarLegacyDevOrder L"LegacyDevOrder"

+

+//

+// Guid of a NV Variable which store the information about the

+// FD/HD/CD/NET/BEV order

+//

+#define EFI_LEGACY_DEV_ORDER_VARIABLE_GUID \

+  { \

+    0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52 } \

+  }

+

+//

+// String Contant

+//

+#define StrFloppy       L"Floppy Drive #%02x"

+#define StrHardDisk     L"HardDisk Drive #%02x"

+#define StrCDROM        L"ATAPI CDROM Drive #%02x"

+#define StrNET          L"NET Drive #%02x"

+#define StrBEV          L"BEV Drive #%02x"

+#define StrFloppyHelp   L"Select Floppy Drive #%02x"

+#define StrHardDiskHelp L"Select HardDisk Drive #%02x"

+#define StrCDROMHelp    L"Select ATAPI CDROM Drive #%02x"

+#define StrNETHelp      L"NET Drive #%02x"

+#define StrBEVHelp      L"BEV Drive #%02x"

+

+//

+// Constant will be used in display and file system navigation

+//

+#define UPDATE_DATA_SIZE        0x100000

+#define MAX_BBS_OFFSET          0xE000

+#define NET_OPTION_OFFSET       0xD800

+#define BEV_OPTION_OFFSET       0xD000

+#define FD_OPTION_OFFSET        0xC000

+#define HD_OPTION_OFFSET        0xB000

+#define CD_OPTION_OFFSET        0xA000

+#define FILE_OPTION_OFFSET      0x8000

+#define FILE_OPTION_MASK        0x7FFF

+#define HANDLE_OPTION_OFFSET    0x7000

+#define CONSOLE_OPTION_OFFSET   0x0A00

+#define TERMINAL_OPTION_OFFSET  0x0700

+#define NORMAL_GOTO_OFFSET      0x0100

+#define MAX_STRING_TOKEN_COUNT  0x00FF

+//

+// Variable created with this flag will be "Efi:...."

+//

+#define VAR_FLAG  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE

+

+//

+// Define Maxmim characters that will be accepted

+//

+#define MAX_CHAR      480

+#define MAX_CHAR_SIZE (MAX_CHAR * 2)

+

+//

+// Check to see if current build support option active feature of

+// some driver option

+//

+#ifndef LOAD_OPTION_ACTIVE

+#define LOAD_OPTION_ACTIVE  0x00000001

+#endif

+//

+// Check to see if current build support force reconnect feature of

+// some driver option

+//

+#ifndef LOAD_OPTION_FORCE_RECONNECT

+#define LOAD_OPTION_FORCE_RECONNECT 0x00000002

+#endif

+//

+// Below are the form ids for display, form id is used as callback key value,

+// some key value definitions are also defined here. By defining this enum type,

+// We can easy know where we are. The int to UINT16 convertion should be ok because

+// there is a MAXIMUM_FORM_ID which in within the range of UINT16.

+//

+typedef enum {

+  IplRelative,

+  BcvRelative

+} BBS_TYPE;

+

+typedef enum {

+  FORM_RESERVED_ID                    = 0,

+  FORM_MAIN_ID,                         // 0x0001

+  FORM_BOOT_ADD_ID,                     // 0x0002

+  FORM_BOOT_DEL_ID,                     // 0x0003

+  FORM_BOOT_CHG_ID,                     // 0x0004

+  FORM_DRV_ADD_ID,                      // 0x0005

+  FORM_DRV_DEL_ID,                      // 0x0006

+  FORM_DRV_CHG_ID,                      // 0x0007

+  FORM_CON_MAIN_ID,                     // 0x0008

+  FORM_CON_IN_ID,                       // 0x0009

+  FORM_CON_OUT_ID,                      // 0x000A

+  FORM_CON_ERR_ID,                      // 0x000B

+  FORM_FILE_SEEK_ID,                    // 0x000C

+  FORM_FILE_NEW_SEEK_ID,                // 0x000D

+  FORM_DRV_ADD_FILE_ID,                 // 0x000E

+  FORM_DRV_ADD_HANDLE_ID,               // 0x000F

+  FORM_DRV_ADD_HANDLE_DESC_ID,          // 0x0010

+  FORM_BOOT_NEXT_ID,                    // 0x0011

+  FORM_TIME_OUT_ID,                     // 0x0012

+  FORM_RESET,                           // 0x0013

+  FORM_BOOT_SETUP_ID,                   // 0x0014

+  FORM_DRIVER_SETUP_ID,                 // 0x0015

+  FORM_BOOT_LEGACY_DEVICE_ID,           // 0x0016

+  FORM_CON_COM_ID,                      // 0x0017

+  FORM_CON_COM_SETUP_ID,                // 0x0018

+  FORM_SET_FD_ORDER_ID,                 // 0x0019

+  FORM_SET_HD_ORDER_ID,                 // 0x001A

+  FORM_SET_CD_ORDER_ID,                 // 0x001B

+  FORM_SET_NET_ORDER_ID,                // 0x001C

+  FORM_SET_BEV_ORDER_ID,                // 0x001D

+  FORM_FILE_EXPLORER_ID,                // 0x001E

+  FORM_BOOT_ADD_DESCRIPTION_ID,         // 0x001F

+  FORM_DRIVER_ADD_FILE_DESCRIPTION_ID,  // 0x0020

+} FORM_ID;

+

+#define MAXIMUM_FORM_ID                 0x007F

+

+#define KEY_VALUE_COM_SET_BAUD_RATE     0x0080

+#define KEY_VALUE_COM_SET_DATA_BITS     0x0081

+#define KEY_VALUE_COM_SET_STOP_BITS     0x0082

+#define KEY_VALUE_COM_SET_PARITY        0x0083

+#define KEY_VALUE_COM_SET_TERMI_TYPE    0x0084

+#define KEY_VALUE_MAIN_BOOT_NEXT        0x0085

+#define KEY_VALUE_BOOT_ADD_DESC_DATA    0x0086

+#define KEY_VALUE_BOOT_ADD_OPT_DATA     0x0087

+#define KEY_VALUE_DRIVER_ADD_DESC_DATA  0x0088

+#define KEY_VALUE_DRIVER_ADD_OPT_DATA   0x0089

+#define KEY_VALUE_SAVE_AND_EXIT         0x0090

+#define KEY_VALUE_NO_SAVE_AND_EXIT      0x0091

+#define KEY_VALUE_BOOT_FROM_FILE        0x0092

+

+#define MAXIMUM_NORMAL_KEY_VALUE        NORMAL_GOTO_OFFSET

+//

+// Below are the number of options in Baudrate, Databits,

+// Parity and Stopbits selection for serial ports.

+//

+#define BM_COM_ATTR_BUADRATE  19

+#define BM_COM_ATTR_DATABITS  4

+#define BM_COM_ATTR_PARITY    5

+#define BM_COM_ATTR_STOPBITS  3

+

+//

+// Callback function helper

+//

+#define BMM_CALLBACK_DATA_SIGNATURE     EFI_SIGNATURE_32 ('C', 'b', 'c', 'k')

+#define BMM_CALLBACK_DATA_FROM_THIS(a)  CR (a, BMM_CALLBACK_DATA, BmmDriverCallback, BMM_CALLBACK_DATA_SIGNATURE)

+

+#define FE_CALLBACK_DATA_FROM_THIS(a)   CR (a, BMM_CALLBACK_DATA, FeDriverCallback, BMM_CALLBACK_DATA_SIGNATURE)

+

+//

+// Enumeration type definition

+//

+typedef enum {

+  PC_ANSI                             = 0,

+  VT_100,

+  VT_100_PLUS,

+  VT_UTF8

+} TYPE_OF_TERMINAL;

+

+typedef enum {

+  COM1                                = 0,

+  COM2,

+  UNKNOW_COM

+} TYPE_OF_COM;

+

+typedef enum {

+  CONIN                               = 0,

+  CONOUT,

+  CONERR,

+  UNKNOWN_CON

+} TYPE_OF_CON;

+

+typedef enum {

+  BAUDRATE                            = 0,

+  DATABITS,

+  PARITY,

+  STOPBITS,

+  UNKNOW_ATTR

+} TYPE_OF_ATTRIBUTE;

+

+typedef enum {

+  MANNER_GOTO                         = 0,

+  MANNER_CHECK,

+  MANNER_ONEOF,

+  MANNER_USER_DEFINE

+} TYPE_OF_UPATE_MANNER;

+

+typedef enum {

+  INACTIVE_STATE                      = 0,

+  BOOT_FROM_FILE_STATE,

+  ADD_BOOT_OPTION_STATE,

+  ADD_DRIVER_OPTION_STATE,

+  UNKNOWN_STATE

+} FILE_EXPLORER_STATE;

+

+typedef enum {

+  FILE_SYSTEM,

+  DIRECTORY,

+  UNKNOWN_CONTEXT

+} FILE_EXPLORER_DISPLAY_CONTEXT;

+

+//

+// All of the signatures that will be used in list structure

+//

+#define BM_MENU_OPTION_SIGNATURE      'menu'

+#define BM_LOAD_OPTION_SIGNATURE      'load'

+#define BM_CONSOLE_OPTION_SIGNATURE   'cnsl'

+#define BM_FILE_OPTION_SIGNATURE      'file'

+#define BM_HANDLE_OPTION_SIGNATURE    'hndl'

+#define BM_TERMINAL_OPTION_SIGNATURE  'trml'

+#define BM_MENU_ENTRY_SIGNATURE       'entr'

+

+#define BM_LOAD_CONTEXT_SELECT        0x0

+#define BM_CONSOLE_CONTEXT_SELECT     0x1

+#define BM_FILE_CONTEXT_SELECT        0x2

+#define BM_HANDLE_CONTEXT_SELECT      0x3

+#define BM_TERMINAL_CONTEXT_SELECT    0x5

+

+#define BM_CONSOLE_IN_CONTEXT_SELECT  0x6

+#define BM_CONSOLE_OUT_CONTEXT_SELECT 0x7

+#define BM_CONSOLE_ERR_CONTEXT_SELECT 0x8

+#define BM_LEGACY_DEV_CONTEXT_SELECT  0x9

+

+//

+// Question Id that will be used to create question

+// all these values are computed from the structure

+// defined below

+//

+#define QUESTION_ID(Field)              ((UINTN) &(((BMM_FAKE_NV_DATA *) 0)->Field))

+

+#define BOOT_TIME_OUT_QUESTION_ID       QUESTION_ID (BootTimeOut)

+#define BOOT_NEXT_QUESTION_ID           QUESTION_ID (BootNext)

+#define COM1_BAUD_RATE_QUESTION_ID      QUESTION_ID (COM1BaudRate)

+#define COM1_DATA_RATE_QUESTION_ID      QUESTION_ID (COM1DataRate)

+#define COM1_STOP_BITS_QUESTION_ID      QUESTION_ID (COM1StopBits)

+#define COM1_PARITY_QUESTION_ID         QUESTION_ID (COM1Parity)

+#define COM1_TERMINAL_QUESTION_ID       QUESTION_ID (COM2TerminalType)

+#define COM2_BAUD_RATE_QUESTION_ID      QUESTION_ID (COM2BaudRate)

+#define COM2_DATA_RATE_QUESTION_ID      QUESTION_ID (COM2DataRate)

+#define COM2_STOP_BITS_QUESTION_ID      QUESTION_ID (COM2StopBits)

+#define COM2_PARITY_QUESTION_ID         QUESTION_ID (COM2Parity)

+#define COM2_TERMINAL_QUESTION_ID       QUESTION_ID (COM2TerminalType)

+#define DRV_ADD_HANDLE_DESC_QUESTION_ID QUESTION_ID (DriverAddHandleDesc)

+#define DRV_ADD_ACTIVE_QUESTION_ID      QUESTION_ID (DriverAddActive)

+#define DRV_ADD_RECON_QUESTION_ID       QUESTION_ID (DriverAddForceReconnect)

+#define CON_IN_COM1_QUESTION_ID         QUESTION_ID (ConsoleInputCOM1)

+#define CON_IN_COM2_QUESTION_ID         QUESTION_ID (ConsoleInputCOM2)

+#define CON_OUT_COM1_QUESTION_ID        QUESTION_ID (ConsoleOutputCOM1)

+#define CON_OUT_COM2_QUESTION_ID        QUESTION_ID (ConsoleOutputCOM2)

+#define CON_ERR_COM1_QUESTION_ID        QUESTION_ID (ConsoleErrorCOM1)

+#define CON_ERR_COM2_QUESTION_ID        QUESTION_ID (ConsoleErrorCOM2)

+#define CON_DEVICE_QUESTION_ID          QUESTION_ID (ConsoleCheck)

+#define OPTION_ORDER_QUESTION_ID        QUESTION_ID (OptionOrder)

+#define DRIVER_OPTION_ORDER_QUESTION_ID QUESTION_ID (DriverOptionToBeDeleted)

+#define BOOT_OPTION_DEL_QUESTION_ID     QUESTION_ID (BootOptionDel)

+#define DRIVER_OPTION_DEL_QUESTION_ID   QUESTION_ID (DriverOptionDel)

+#define DRIVER_ADD_OPTION_QUESTION_ID   QUESTION_ID (DriverAddHandleOptionalData)

+#define COM_BAUD_RATE_QUESTION_ID       QUESTION_ID (COMBaudRate)

+#define COM_DATA_RATE_QUESTION_ID       QUESTION_ID (COMDataRate)

+#define COM_STOP_BITS_QUESTION_ID       QUESTION_ID (COMStopBits)

+#define COM_PARITY_QUESTION_ID          QUESTION_ID (COMParity)

+#define COM_TERMINAL_QUESTION_ID        QUESTION_ID (COMTerminalType)

+#define LEGACY_FD_QUESTION_ID           QUESTION_ID (LegacyFD)

+#define LEGACY_HD_QUESTION_ID           QUESTION_ID (LegacyHD)

+#define LEGACY_CD_QUESTION_ID           QUESTION_ID (LegacyCD)

+#define LEGACY_NET_QUESTION_ID          QUESTION_ID (LegacyNET)

+#define LEGACY_BEV_QUESTION_ID          QUESTION_ID (LegacyBEV)

+

+#define STRING_DEPOSITORY_NUMBER        8

+

+//

+// #pragma pack(1)

+//

+// Serial Ports attributes, first one is the value for

+// return from callback function, stringtoken is used to

+// display the value properly

+//

+typedef struct {

+  UINTN   Value;

+  UINT16  StringToken;

+} COM_ATTR;

+

+//

+// This is the structure that will be used to store the

+// question's current value. Use it at initialize time to

+// set default value for each question. When using at run

+// time, this map is returned by the callback function,

+// so dynamically changing the question's value will be

+// possible through this mechanism

+//

+typedef struct {

+  //

+  // Three questions displayed at the main page

+  // for Timeout, BootNext Variables respectively

+  //

+  UINT16  BootTimeOut;

+  UINT16  BootNext;

+

+  //

+  // This is the COM1 Attributes value storage

+  //

+  UINT8   COM1BaudRate;

+  UINT8   COM1DataRate;

+  UINT8   COM1StopBits;

+  UINT8   COM1Parity;

+  UINT8   COM1TerminalType;

+

+  //

+  // This is the COM2 Attributes value storage

+  //

+  UINT8   COM2BaudRate;

+  UINT8   COM2DataRate;

+  UINT8   COM2StopBits;

+  UINT8   COM2Parity;

+  UINT8   COM2TerminalType;

+

+  //

+  // Driver Option Add Handle page storage

+  //

+  UINT16  DriverAddHandleDesc[75];

+  UINT16  DriverAddHandleOptionalData[75];

+  UINT8   DriverAddActive;

+  UINT8   DriverAddForceReconnect;

+

+  //

+  // Console Input/Output/Errorout using COM port check storage

+  //

+  UINT8   ConsoleInputCOM1;

+  UINT8   ConsoleInputCOM2;

+  UINT8   ConsoleOutputCOM1;

+  UINT8   ConsoleOutputCOM2;

+  UINT8   ConsoleErrorCOM1;

+  UINT8   ConsoleErrorCOM2;

+

+  //

+  // At most 100 input/output/errorout device for console storage

+  //

+  UINT8   ConsoleCheck[100];

+

+  //

+  // Boot or Driver Option Order storage

+  //

+  UINT8   OptionOrder[100];

+  UINT8   DriverOptionToBeDeleted[100];

+

+  //

+  // Boot Option Delete storage

+  //

+  UINT8   BootOptionDel[100];

+  UINT8   DriverOptionDel[100];

+

+  //

+  // This is the Terminal Attributes value storage

+  //

+  UINT8   COMBaudRate;

+  UINT8   COMDataRate;

+  UINT8   COMStopBits;

+  UINT8   COMParity;

+  UINT8   COMTerminalType;

+

+  //

+  // Legacy Device Order Selection Storage

+  //

+  UINT8   LegacyFD[100];

+  UINT8   LegacyHD[100];

+  UINT8   LegacyCD[100];

+  UINT8   LegacyNET[100];

+  UINT8   LegacyBEV[100];

+

+  //

+  // We use DisableMap array to record the enable/disable state of each boot device

+  // It should be taken as a bit array, from left to right there are totally 256 bits

+  // the most left one stands for BBS table item 0, and the most right one stands for item 256

+  // If the bit is 1, it means the boot device has been disabled.

+  //

+  UINT8   DisableMap[32];

+

+  //

+  //  UINT16                    PadArea[10];

+  //

+} BMM_FAKE_NV_DATA;

+

+typedef struct {

+  UINT16  DescriptionData[75];

+  UINT16                    OptionalData[127];

+  UINT8   Active;

+  UINT8   ForceReconnect;

+} FILE_EXPLORER_NV_DATA;

+

+typedef struct {

+  BBS_TYPE  BbsType;

+  //

+  // Length = sizeof (UINT16) + SIZEOF (Data)

+  //

+  UINT16    Length;

+  UINT16    *Data;

+} BM_LEGACY_DEV_ORDER_CONTEXT;

+

+typedef struct {

+  UINT64                    BaudRate;

+  UINT8                     DataBits;

+  UINT8                     Parity;

+  UINT8                     StopBits;

+

+  UINT8                     BaudRateIndex;

+  UINT8                     DataBitsIndex;

+  UINT8                     ParityIndex;

+  UINT8                     StopBitsIndex;

+

+  UINT8                     IsConIn;

+  UINT8                     IsConOut;

+  UINT8                     IsStdErr;

+  UINT8                     TerminalType;

+

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+} BM_TERMINAL_CONTEXT;

+

+typedef struct {

+  BOOLEAN                   IsBootNext;

+  BOOLEAN                   LoadOptionModified;

+  BOOLEAN                   Deleted;

+

+  BOOLEAN                   IsLegacy;

+  BOOLEAN                   IsActive;

+  BOOLEAN                   ForceReconnect;

+  UINTN                     OptionalDataSize;

+

+  UINTN                     LoadOptionSize;

+  UINT8                     *LoadOption;

+

+  UINT32                    Attributes;

+  UINT16                    FilePathListLength;

+  UINT16                    *Description;

+  EFI_DEVICE_PATH_PROTOCOL  *FilePathList;

+  UINT8                     *OptionalData;

+

+  UINT16                    BbsIndex;

+} BM_LOAD_CONTEXT;

+

+typedef struct {

+  BBS_TABLE *BbsTable;

+  UINTN     Index;

+  UINTN     BbsCount;

+  UINT16    *Description;

+} BM_LEGACY_DEVICE_CONTEXT;

+

+typedef struct {

+

+  BOOLEAN                   IsActive;

+

+  BOOLEAN                   IsTerminal;

+

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+} BM_CONSOLE_CONTEXT;

+

+typedef struct {

+  EFI_HANDLE                        Handle;

+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;

+  EFI_FILE_HANDLE                   FHandle;

+  UINT16                            *FileName;

+  EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Info;

+

+  BOOLEAN                           IsRoot;

+  BOOLEAN                           IsDir;

+  BOOLEAN                           IsRemovableMedia;

+  BOOLEAN                           IsLoadFile;

+  BOOLEAN                           IsBootLegacy;

+} BM_FILE_CONTEXT;

+

+typedef struct {

+  EFI_HANDLE                Handle;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+} BM_HANDLE_CONTEXT;

+

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      Head;

+  UINTN           MenuNumber;

+} BM_MENU_OPTION;

+

+typedef struct {

+  UINTN           Signature;

+  LIST_ENTRY      Link;

+  UINTN           OptionNumber;

+  UINT16          *DisplayString;

+  UINT16          *HelpString;

+  STRING_REF      DisplayStringToken;

+  STRING_REF      HelpStringToken;

+  UINTN           ContextSelection;

+  VOID            *VariableContext;

+} BM_MENU_ENTRY;

+

+typedef struct {

+  //

+  // Shared callback data.

+  //

+  UINTN                         Signature;

+  EFI_HII_PROTOCOL              *Hii;

+  BM_MENU_ENTRY                 *MenuEntry;

+  BM_HANDLE_CONTEXT             *HandleContext;

+  BM_FILE_CONTEXT               *FileContext;

+  BM_LOAD_CONTEXT               *LoadContext;

+  BM_TERMINAL_CONTEXT           *TerminalContext;

+  UINTN                         CurrentTerminal;

+  BBS_TYPE                      BbsType;

+

+  //

+  // BMM main formset callback data.

+  //

+  EFI_HII_HANDLE                BmmHiiHandle;

+  EFI_HANDLE                    BmmCallbackHandle;

+  EFI_FORM_CALLBACK_PROTOCOL    BmmDriverCallback;

+  FORM_ID                       BmmCurrentPageId;

+  FORM_ID                       BmmPreviousPageId;

+  BOOLEAN                       BmmAskSaveOrNot;

+  BMM_FAKE_NV_DATA              *BmmFakeNvData;

+  BMM_FAKE_NV_DATA              BmmOldFakeNVData;

+

+  //

+  // File explorer formset callback data.

+  //

+  EFI_HII_HANDLE                FeHiiHandle;

+  EFI_HANDLE                    FeCallbackHandle;

+  EFI_FORM_CALLBACK_PROTOCOL    FeDriverCallback;

+  FILE_EXPLORER_STATE           FeCurrentState;

+  FILE_EXPLORER_DISPLAY_CONTEXT FeDisplayContext;

+} BMM_CALLBACK_DATA;

+

+typedef struct _STRING_LIST_NODE {

+  STRING_REF                StringToken;

+  struct _STRING_LIST_NODE  *Next;

+} STRING_LIST_NODE;

+

+typedef struct _STRING_DEPOSITORY {

+  UINTN             TotalNodeNumber;

+  STRING_LIST_NODE  *CurrentNode;

+  STRING_LIST_NODE  *ListHead;

+} STRING_DEPOSITORY;

+

+//

+// #pragma pack()

+//

+// For initializing File System menu

+//

+EFI_STATUS

+BOpt_FindFileSystem (

+  IN BMM_CALLBACK_DATA          *CallbackData

+  )

+;

+

+//

+// For cleaning up File System menu

+//

+VOID

+BOpt_FreeFileSystem (

+  VOID

+  )

+;

+

+//

+// For initializing File Navigation menu

+//

+EFI_STATUS

+BOpt_FindFiles (

+  IN BMM_CALLBACK_DATA          *CallbackData,

+  IN BM_MENU_ENTRY              *MenuEntry

+  )

+;

+

+//

+// For cleaning up File Navigation menu

+//

+VOID

+BOpt_FreeFiles (

+  VOID

+  )

+;

+

+//

+// For Initializing handle navigation menu

+//

+EFI_STATUS

+BOpt_FindDrivers (

+  VOID

+  )

+;

+

+//

+// For Cleaning up handle navigation menu

+//

+VOID

+BOpt_FreeDrivers();

+

+//

+// For initializing Boot Option menu

+//

+EFI_STATUS

+BOpt_GetBootOptions (

+  IN  BMM_CALLBACK_DATA         *CallbackData

+  );

+

+//

+// For Initializing Driver option menu

+//

+EFI_STATUS

+BOpt_GetDriverOptions (

+  IN  BMM_CALLBACK_DATA         *CallbackData

+  );

+

+//

+// For Cleaning up boot option menu

+//

+VOID

+BOpt_FreeBootOptions ();

+

+//

+// For cleaning up driver option menu

+//

+VOID

+BOpt_FreeDriverOptions();

+

+//

+// For Initializing HD/FD/CD/NET/BEV option menu

+//

+EFI_STATUS

+BOpt_GetLegacyOptions();

+

+//

+// For cleaning up driver option menu

+//

+VOID

+BOpt_FreeLegacyOptions();

+

+//

+// this function is used to take place of all other free menu actions

+//

+VOID

+BOpt_FreeMenu (

+  BM_MENU_OPTION        *FreeMenu

+  );

+

+

+//

+// Following are the helper functions used

+//

+CHAR16                            *

+BOpt_AppendFileName (

+  IN  CHAR16  *Str1,

+  IN  CHAR16  *Str2

+  );

+

+BOOLEAN

+BOpt_IsEfiImageName (

+  IN UINT16  *FileName

+  );

+

+BOOLEAN

+BOpt_IsEfiApp (

+  IN EFI_FILE_HANDLE Dir,

+  IN UINT16          *FileName

+  );

+

+//

+// Get current unused boot option number

+//

+UINT16

+BOpt_GetBootOptionNumber ();

+

+//

+// Get current unused driver option number

+//

+UINT16

+BOpt_GetDriverOptionNumber ();

+

+BM_MENU_ENTRY                     *

+BOpt_CreateMenuEntry (

+  UINTN           MenuType

+  );

+

+VOID

+BOpt_DestroyMenuEntry (

+  BM_MENU_ENTRY         *MenuEntry

+  );

+

+BM_MENU_ENTRY                     *

+BOpt_GetMenuEntry (

+  BM_MENU_OPTION      *MenuOption,

+  UINTN               MenuNumber

+  );

+

+//

+// a helper function used to free pool type memory

+//

+VOID

+SafeFreePool (

+  IN VOID *Buffer

+  );

+

+//

+// Locate all serial io devices for console

+//

+EFI_STATUS

+LocateSerialIo ();

+

+//

+// Initializing Console menu

+//

+EFI_STATUS

+GetAllConsoles();

+

+//

+// Cleaning up console menu

+//

+EFI_STATUS

+FreeAllConsoles();

+

+VOID

+ChangeVariableDevicePath (

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+); 

+

+EFI_STATUS

+ChangeTerminalDevicePath (

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  BOOLEAN                   ChangeTerminal

+);

+//

+// Variable operation by menu selection

+//

+EFI_STATUS

+Var_UpdateBootOption (

+  IN  BMM_CALLBACK_DATA                   *CallbackData,

+  IN  FILE_EXPLORER_NV_DATA               *NvRamMap

+  );

+

+EFI_STATUS

+Var_DelBootOption ();

+

+EFI_STATUS

+Var_ChangeBootOrder ();

+

+EFI_STATUS

+Var_UpdateDriverOption (

+  IN  BMM_CALLBACK_DATA         *CallbackData,

+  IN  EFI_HII_HANDLE            HiiHandle,

+  IN  UINT16                    *DescriptionData,

+  IN  UINT16                    *OptionalData,

+  IN  UINT8                     ForceReconnect

+  );

+

+EFI_STATUS

+Var_DelDriverOption ();

+

+EFI_STATUS

+Var_ChangeDriverOrder ();

+

+EFI_STATUS

+Var_UpdateConsoleInpOption ();

+

+EFI_STATUS

+Var_UpdateConsoleOutOption ();

+

+EFI_STATUS

+Var_UpdateErrorOutOption ();

+

+VOID

+Var_UpdateAllConsoleOption ();

+

+EFI_STATUS

+Var_UpdateBootNext (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  );

+

+EFI_STATUS

+Var_UpdateBootOrder (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  );

+

+EFI_STATUS

+Var_UpdateDriverOrder (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  );

+

+EFI_STATUS

+Var_UpdateBBSOption (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  );

+

+//

+// Following are page create and refresh functions

+//

+VOID

+RefreshUpdateData (

+  IN BOOLEAN                          FormSetUpdate,

+  IN EFI_PHYSICAL_ADDRESS             FormCallbackHandle,

+  IN BOOLEAN                          FormUpdate,

+  IN STRING_REF                       FormTitle,

+  IN UINT16                           DataCount

+  );

+

+VOID

+CleanUpPage (

+  IN EFI_FORM_LABEL                   LabelId,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+EFI_STATUS

+UpdatePage (

+  IN BMM_CALLBACK_DATA                *CallbackData,

+  IN BM_MENU_OPTION                   *UpdatingMenu,

+  IN UINT16                           UpdatingPage,

+  IN UINT16                           UpdatingManner,

+  IN UINT16                           QuestionIdStart,

+  IN UINT16                           GotoForm,

+  IN UINT16                           GotoAlternateForm,

+  IN STRING_REF                       DisplayTokenStart,

+  IN STRING_REF                       HelpTokenStart,

+  IN UINT16                           KeyValueStart

+  );

+

+VOID

+UpdateBootAddPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateBootDelPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateDrvAddFilePage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateDrvAddHandlePage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateDrvDelPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateDriverAddHandleDescPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateBootTimeOut (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateConInPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateConOutPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateStdErrPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdatePageBody (

+  IN UINT16                           UpdatePageId,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateCOM1Page (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateCOM2Page (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateBootOrderPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateDriverOrderPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateBootNextPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateTimeOutPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateTerminalPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateConCOMPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  );

+

+VOID

+UpdateSetLegacyDeviceOrderPage (

+  IN UINT16                           UpdatePageId,

+  IN BMM_CALLBACK_DATA                *CallbackData

+);

+

+EFI_STATUS

+BootLegacy (

+  IN  UINT16  BbsType,

+  IN  UINT16  BbsFlag

+);

+

+BM_MENU_ENTRY                     *

+GetCurrentTerminal (

+  UINTN       TerminalNumber

+);

+

+EFI_FILE_HANDLE

+EfiLibOpenRoot (

+  IN EFI_HANDLE       DeviceHandle

+  );

+

+EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *

+EfiLibFileSystemVolumeLabelInfo (

+  IN EFI_FILE_HANDLE      FHand

+  );

+

+EFI_FILE_INFO                     *

+EfiLibFileInfo (

+  IN EFI_FILE_HANDLE      FHand

+  );

+

+CHAR16                            *

+DevicePathToStr (

+  EFI_DEVICE_PATH_PROTOCOL     *DevPath

+  );

+

+EFI_STATUS

+EfiLibLocateProtocol (

+  IN  EFI_GUID        *ProtocolGuid,

+  OUT VOID            **Interface

+  );

+

+VOID                              *

+EfiReallocatePool (

+  IN VOID                 *OldPool,

+  IN UINTN                OldSize,

+  IN UINTN                NewSize

+  );

+

+CHAR16                            *

+DevicePathToStr (

+  EFI_DEVICE_PATH_PROTOCOL     *DevPath

+  );

+

+VOID                              *

+BdsLibGetVariableAndSize (

+  IN CHAR16               *Name,

+  IN EFI_GUID             *VendorGuid,

+  OUT UINTN               *VarSize

+  );

+

+EFI_STATUS

+EfiLibDeleteVariable (

+  IN CHAR16   *VarName,

+  IN EFI_GUID *VarGuid

+  );

+

+CHAR16                            *

+EfiStrDuplicate (

+  IN CHAR16   *Src

+  );

+

+BOOLEAN

+EfiLibMatchDevicePaths (

+  IN  EFI_DEVICE_PATH_PROTOCOL *Multi,

+  IN  EFI_DEVICE_PATH_PROTOCOL *Single

+  );

+

+UINTN

+EfiDevicePathInstanceCount (

+  IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath

+  );

+

+EFI_STATUS

+CreateMenuStringToken (

+  IN BMM_CALLBACK_DATA                *CallbackData,

+  IN EFI_HII_HANDLE                   HiiHandle,

+  IN BM_MENU_OPTION                   *MenuOption

+  );

+

+UINT16                            *

+EfiLibStrFromDatahub (

+  IN EFI_DEVICE_PATH_PROTOCOL                 *DevPath

+  );

+

+VOID                              *

+GetLegacyBootOptionVar (

+  IN  UINTN                            DeviceType,

+  OUT UINTN                            *OptionIndex,

+  OUT UINTN                            *OptionSize

+ );

+

+EFI_STATUS

+InitializeBM (

+  VOID

+  );

+

+EFI_STATUS

+BdsStartBootMaint (

+  VOID

+  );

+

+VOID

+InitializeStringDepository ();

+

+STRING_REF

+GetStringTokenFromDepository (

+  IN   BMM_CALLBACK_DATA     *CallbackData,

+  IN   STRING_DEPOSITORY     *StringDepository

+  ) ;

+

+VOID

+ReclaimStringDepository (

+  VOID

+  );

+

+VOID

+CleanUpStringDepository (

+  VOID

+  );

+

+EFI_STATUS

+ApplyChangeHandler (

+  IN  BMM_CALLBACK_DATA               *Private,

+  IN  BMM_FAKE_NV_DATA                *CurrentFakeNVMap,

+  IN  FORM_ID                         FormId

+  );

+

+VOID

+DiscardChangeHandler (

+  IN  BMM_CALLBACK_DATA               *Private,

+  IN  BMM_FAKE_NV_DATA                *CurrentFakeNVMap

+  );

+

+VOID

+UpdatePageId (

+  BMM_CALLBACK_DATA              *Private,

+  UINT16                         NewPageId

+  );

+

+EFI_STATUS

+BootThisFile (

+  IN BM_FILE_CONTEXT                   *FileContext

+  );

+

+BOOLEAN

+UpdateFileExplorer (

+  IN BMM_CALLBACK_DATA            *CallbackData,

+  IN UINT16                       KeyValue

+  );

+

+EFI_STATUS

+EFIAPI

+FileExplorerCallback (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *Data,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  );

+

+EFI_STATUS

+FormSetDispatcher (

+  IN  BMM_CALLBACK_DATA    *CallbackData

+  );

+

+VOID CreateCallbackPacket (

+  OUT EFI_HII_CALLBACK_PACKET         **Packet,

+  IN  UINT16                          Flags

+  );

+

+//

+// Global variable in this program (defined in data.c)

+//

+extern BM_MENU_OPTION             BootOptionMenu;

+extern BM_MENU_OPTION             DriverOptionMenu;

+extern BM_MENU_OPTION             FsOptionMenu;

+extern BM_MENU_OPTION             ConsoleInpMenu;

+extern BM_MENU_OPTION             ConsoleOutMenu;

+extern BM_MENU_OPTION             ConsoleErrMenu;

+extern BM_MENU_OPTION             DirectoryMenu;

+extern BM_MENU_OPTION             DriverMenu;

+extern BM_MENU_OPTION             TerminalMenu;

+extern BM_MENU_OPTION             LegacyFDMenu;

+extern BM_MENU_OPTION             LegacyHDMenu;

+extern BM_MENU_OPTION             LegacyCDMenu;

+extern BM_MENU_OPTION             LegacyNETMenu;

+extern BM_MENU_OPTION             LegacyBEVMenu;

+extern UINT16                     TerminalType[];

+extern COM_ATTR                   BaudRateList[19];

+extern COM_ATTR                   DataBitsList[4];

+extern COM_ATTR                   ParityList[5];

+extern COM_ATTR                   StopBitsList[3];

+extern EFI_GUID                   Guid[4];

+extern EFI_HII_UPDATE_DATA        *UpdateData;

+extern STRING_DEPOSITORY          *FileOptionStrDepository;

+extern STRING_DEPOSITORY          *ConsoleOptionStrDepository;

+extern STRING_DEPOSITORY          *BootOptionStrDepository;

+extern STRING_DEPOSITORY          *BootOptionHelpStrDepository;

+extern STRING_DEPOSITORY          *DriverOptionStrDepository;

+extern STRING_DEPOSITORY          *DriverOptionHelpStrDepository;

+extern STRING_DEPOSITORY          *TerminalStrDepository;

+extern EFI_DEVICE_PATH_PROTOCOL   EndDevicePath[];

+extern EFI_GUID                   EfiLegacyDevOrderGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootOption.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootOption.c
new file mode 100644
index 0000000..3c21b12
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootOption.c
@@ -0,0 +1,1668 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  bootoption.c

+  

+Abstract:

+

+  Provide boot option support for Application "BootMaint"

+

+  Include file system navigation, system handle selection

+

+  Boot option manipulation

+  

+Revision History

+

+--*/

+

+#include "bootmaint.h"

+#include "BBSsupport.h"

+

+BM_MENU_ENTRY *

+BOpt_CreateMenuEntry (

+  UINTN           MenuType

+  )

+/*++

+

+Routine Description

+  Create Menu Entry for future use, make all types together

+  in order to reduce code size

+

+Arguments:

+  MenuType            Use this parameter to identify current

+                      Menu type

+

+Returns:

+  NULL                Cannot allocate memory for current menu 

+                      entry

+  Others              A valid pointer pointing to the allocated

+                      memory pool for current menu entry

+

+--*/

+{

+  BM_MENU_ENTRY *MenuEntry;

+  UINTN         ContextSize;

+

+  switch (MenuType) {

+  case BM_LOAD_CONTEXT_SELECT:

+    ContextSize = sizeof (BM_LOAD_CONTEXT);

+    break;

+

+  case BM_FILE_CONTEXT_SELECT:

+    ContextSize = sizeof (BM_FILE_CONTEXT);

+    break;

+

+  case BM_CONSOLE_CONTEXT_SELECT:

+    ContextSize = sizeof (BM_CONSOLE_CONTEXT);

+    break;

+

+  case BM_TERMINAL_CONTEXT_SELECT:

+    ContextSize = sizeof (BM_TERMINAL_CONTEXT);

+    break;

+

+  case BM_HANDLE_CONTEXT_SELECT:

+    ContextSize = sizeof (BM_HANDLE_CONTEXT);

+    break;

+

+  case BM_LEGACY_DEV_CONTEXT_SELECT:

+    ContextSize = sizeof (BM_LEGACY_DEVICE_CONTEXT);

+    break;

+

+  default:

+    ContextSize = 0;

+    break;

+

+  }

+

+  if (0 == ContextSize) {

+    return NULL;

+  }

+

+  MenuEntry = AllocateZeroPool (sizeof (BM_MENU_ENTRY));

+  if (NULL == MenuEntry) {

+    return MenuEntry;

+  }

+

+  MenuEntry->VariableContext = AllocateZeroPool (ContextSize);

+  if (NULL == MenuEntry->VariableContext) {

+    SafeFreePool (MenuEntry);

+    MenuEntry = NULL;

+    return MenuEntry;

+  }

+

+  MenuEntry->Signature        = BM_MENU_ENTRY_SIGNATURE;

+  MenuEntry->ContextSelection = MenuType;

+  return MenuEntry;

+}

+

+VOID

+BOpt_DestroyMenuEntry (

+  BM_MENU_ENTRY         *MenuEntry

+  )

+/*++

+  Routine Description :

+    Destroy the menu entry passed in

+

+  Arguments :

+    The menu entry need to be destroyed

+

+  Returns :

+    None

+

+--*/

+{

+  BM_LOAD_CONTEXT           *LoadContext;

+  BM_FILE_CONTEXT           *FileContext;

+  BM_CONSOLE_CONTEXT        *ConsoleContext;

+  BM_TERMINAL_CONTEXT       *TerminalContext;

+  BM_HANDLE_CONTEXT         *HandleContext;

+  BM_LEGACY_DEVICE_CONTEXT  *LegacyDevContext;

+

+  //

+  //  Select by the type in Menu entry for current context type

+  //

+  switch (MenuEntry->ContextSelection) {

+  case BM_LOAD_CONTEXT_SELECT:

+    LoadContext = (BM_LOAD_CONTEXT *) MenuEntry->VariableContext;

+    SafeFreePool (LoadContext->FilePathList);

+    SafeFreePool (LoadContext->LoadOption);

+    SafeFreePool (LoadContext->OptionalData);

+    SafeFreePool (LoadContext);

+    break;

+

+  case BM_FILE_CONTEXT_SELECT:

+    FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;

+

+    if (!FileContext->IsRoot) {

+      SafeFreePool (FileContext->DevicePath);

+    } else {

+      if (FileContext->FHandle != NULL) {

+        FileContext->FHandle->Close (FileContext->FHandle);

+      }

+    }

+

+    SafeFreePool (FileContext->FileName);

+    SafeFreePool (FileContext->Info);

+    SafeFreePool (FileContext);

+    break;

+

+  case BM_CONSOLE_CONTEXT_SELECT:

+    ConsoleContext = (BM_CONSOLE_CONTEXT *) MenuEntry->VariableContext;

+    SafeFreePool (ConsoleContext->DevicePath);

+    SafeFreePool (ConsoleContext);

+    break;

+

+  case BM_TERMINAL_CONTEXT_SELECT:

+    TerminalContext = (BM_TERMINAL_CONTEXT *) MenuEntry->VariableContext;

+    SafeFreePool (TerminalContext->DevicePath);

+    SafeFreePool (TerminalContext);

+    break;

+

+  case BM_HANDLE_CONTEXT_SELECT:

+    HandleContext = (BM_HANDLE_CONTEXT *) MenuEntry->VariableContext;

+    SafeFreePool (HandleContext);

+    break;

+

+  case BM_LEGACY_DEV_CONTEXT_SELECT:

+    LegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) MenuEntry->VariableContext;

+    SafeFreePool (LegacyDevContext);

+

+  default:

+    break;

+  }

+

+  SafeFreePool (MenuEntry->DisplayString);

+  if (NULL != MenuEntry->HelpString) {

+    SafeFreePool (MenuEntry->HelpString);

+  }

+

+  SafeFreePool (MenuEntry);

+}

+

+BM_MENU_ENTRY *

+BOpt_GetMenuEntry (

+  BM_MENU_OPTION      *MenuOption,

+  UINTN               MenuNumber

+  )

+/*++

+  Rountine Description :

+    Use this routine to get one particular menu entry in specified 

+    menu

+

+  Arguments :

+    MenuOption        The menu that we will search 

+

+    MenuNumber        The menunubmer that we want

+

+  Returns :

+    The desired menu entry

+

+--*/

+{

+  BM_MENU_ENTRY   *NewMenuEntry;

+  UINTN           Index;

+  LIST_ENTRY      *List;

+

+  if (MenuNumber >= MenuOption->MenuNumber) {

+    return NULL;

+  }

+

+  List = MenuOption->Head.ForwardLink;

+  for (Index = 0; Index < MenuNumber; Index++) {

+    List = List->ForwardLink;

+  }

+

+  NewMenuEntry = CR (List, BM_MENU_ENTRY, Link, BM_MENU_ENTRY_SIGNATURE);

+

+  return NewMenuEntry;

+}

+

+EFI_STATUS

+BOpt_FindFileSystem (

+  IN BMM_CALLBACK_DATA          *CallbackData

+  )

+/*++

+

+Routine Description

+  Find file systems for current Extensible Firmware

+  Including Handles that support Simple File System

+  protocol, Load File protocol.

+

+  Building up the FileSystem Menu for user selection

+  All file system will be stored in FsOptionMenu 

+  for future use.

+

+Arguments:

+  CallbackData           -   BMM context data

+

+Returns:

+  EFI_SUCCESS            -   Success find the file system

+  EFI_OUT_OF_RESOURCES   -   Can not create menu entry

+

+--*/

+{

+  UINTN                     NoSimpleFsHandles;

+  UINTN                     NoLoadFileHandles;

+  EFI_HANDLE                *SimpleFsHandle;

+  EFI_HANDLE                *LoadFileHandle;

+  UINT16                    *VolumeLabel;

+  EFI_BLOCK_IO_PROTOCOL     *BlkIo;

+  UINTN                     Index;

+  EFI_STATUS                Status;

+  BM_MENU_ENTRY             *MenuEntry;

+  BM_FILE_CONTEXT           *FileContext;

+  UINT16                    *TempStr;

+  UINTN                     OptionNumber;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  UINT16                    DeviceType;

+  BBS_BBS_DEVICE_PATH       BbsDevicePathNode;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  BOOLEAN                   RemovableMedia;

+

+

+  NoSimpleFsHandles = 0;

+  NoLoadFileHandles = 0;

+  OptionNumber      = 0;

+  InitializeListHead (&FsOptionMenu.Head);

+

+  //

+  // Locate Handles that support Simple File System protocol

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  NULL,

+                  &NoSimpleFsHandles,

+                  &SimpleFsHandle

+                  );

+  if (!EFI_ERROR (Status)) {

+    //

+    // Find all the instances of the File System prototocol

+    //

+    for (Index = 0; Index < NoSimpleFsHandles; Index++) {

+      Status = gBS->HandleProtocol (

+                      SimpleFsHandle[Index],

+                      &gEfiBlockIoProtocolGuid,

+                      &BlkIo

+                      );

+      if (EFI_ERROR (Status)) {

+        //

+        // If no block IO exists assume it's NOT a removable media

+        //

+        RemovableMedia = FALSE;

+      } else {

+        //

+        // If block IO exists check to see if it's remobable media

+        //

+        RemovableMedia = BlkIo->Media->RemovableMedia; 

+      }

+

+      //

+      // Allocate pool for this load option

+      //

+      MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);

+      if (NULL == MenuEntry) {

+        SafeFreePool (SimpleFsHandle);    

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;

+            

+      FileContext->Handle     = SimpleFsHandle[Index];

+      MenuEntry->OptionNumber = Index;

+      FileContext->FHandle    = EfiLibOpenRoot (FileContext->Handle);

+      if (!FileContext->FHandle) {

+        BOpt_DestroyMenuEntry (MenuEntry);

+        continue;

+      }

+

+      MenuEntry->HelpString = DevicePathToStr (DevicePathFromHandle (FileContext->Handle));

+      FileContext->Info = EfiLibFileSystemVolumeLabelInfo (FileContext->FHandle);

+      FileContext->FileName = EfiStrDuplicate (L"\\");

+      FileContext->DevicePath = FileDevicePath (

+                                  FileContext->Handle,

+                                  FileContext->FileName

+                                  );

+      FileContext->IsDir            = TRUE;

+      FileContext->IsRoot           = TRUE;

+      FileContext->IsRemovableMedia = FALSE;

+      FileContext->IsLoadFile       = FALSE;

+

+      //

+      // Get current file system's Volume Label

+      //

+      if (FileContext->Info == NULL) {

+        VolumeLabel = L"NO FILE SYSTEM INFO";

+      } else {

+        if (FileContext->Info->VolumeLabel == NULL) {

+          VolumeLabel = L"NULL VOLUME LABEL";

+        } else {

+          VolumeLabel = FileContext->Info->VolumeLabel;

+          if (*VolumeLabel == 0x0000) {

+            VolumeLabel = L"NO VOLUME LABEL";

+          }

+        }

+      }

+

+      TempStr                   = MenuEntry->HelpString;

+      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);

+      ASSERT (MenuEntry->DisplayString != NULL);

+      UnicodeSPrint (

+        MenuEntry->DisplayString,

+        MAX_CHAR,

+        L"%s, [%s]",

+        VolumeLabel,

+        TempStr

+        );

+      OptionNumber++;

+      InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);      

+    }

+  }

+

+  if (NoSimpleFsHandles != 0) {

+    SafeFreePool (SimpleFsHandle);

+  }

+  //

+  // Searching for handles that support Load File protocol

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiLoadFileProtocolGuid,

+                  NULL,

+                  &NoLoadFileHandles,

+                  &LoadFileHandle

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    for (Index = 0; Index < NoLoadFileHandles; Index++) {

+      MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);

+      if (NULL == MenuEntry) {

+        SafeFreePool (LoadFileHandle);    

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      FileContext                   = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;

+      FileContext->IsRemovableMedia = FALSE;

+      FileContext->IsLoadFile       = TRUE;

+      FileContext->Handle           = LoadFileHandle[Index];

+      FileContext->IsRoot           = TRUE;

+

+      FileContext->DevicePath = DevicePathFromHandle (FileContext->Handle);

+

+      MenuEntry->HelpString     = DevicePathToStr (FileContext->DevicePath);

+

+      TempStr                   = MenuEntry->HelpString;

+      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);

+      ASSERT (MenuEntry->DisplayString != NULL);

+      UnicodeSPrint (

+        MenuEntry->DisplayString,

+        MAX_CHAR,

+        L"Load File [%s]",

+        TempStr

+        );

+

+      MenuEntry->OptionNumber = OptionNumber;

+      OptionNumber++;

+      InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);

+    }

+  }

+

+  if (NoLoadFileHandles != 0) {

+    SafeFreePool (LoadFileHandle);

+  }

+

+  //

+  // Add Legacy Boot Option Support Here

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiLegacyBiosProtocolGuid,

+                  NULL,

+                  &LegacyBios

+                  );

+  if (!EFI_ERROR (Status)) {

+

+    for (Index = BBS_TYPE_FLOPPY; Index <= BBS_TYPE_EMBEDDED_NETWORK; Index++) {

+      MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);

+      if (NULL == MenuEntry) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      FileContext                       = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;

+

+      FileContext->IsRemovableMedia     = FALSE;

+      FileContext->IsLoadFile           = TRUE;

+      FileContext->IsBootLegacy         = TRUE;

+      DeviceType                        = (UINT16) Index;

+      BbsDevicePathNode.Header.Type     = BBS_DEVICE_PATH;

+      BbsDevicePathNode.Header.SubType  = BBS_BBS_DP;

+      SetDevicePathNodeLength (

+        &BbsDevicePathNode.Header,

+        sizeof (BBS_BBS_DEVICE_PATH)

+        );

+      BbsDevicePathNode.DeviceType  = DeviceType;

+      BbsDevicePathNode.StatusFlag  = 0;

+      BbsDevicePathNode.String[0]   = 0;

+      DevicePath = AppendDevicePathNode (

+                    EndDevicePath,

+                    (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevicePathNode

+                    );

+

+      FileContext->DevicePath   = DevicePath;

+      MenuEntry->HelpString     = DevicePathToStr (FileContext->DevicePath);

+

+      TempStr                   = MenuEntry->HelpString;

+      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);

+      ASSERT (MenuEntry->DisplayString != NULL);

+      UnicodeSPrint (

+        MenuEntry->DisplayString,

+        MAX_CHAR,

+        L"Boot Legacy [%s]",

+        TempStr

+        );

+      MenuEntry->OptionNumber = OptionNumber;

+      OptionNumber++;

+      InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);

+    }

+  }

+  //

+  // Remember how many file system options are here

+  //

+  FsOptionMenu.MenuNumber = OptionNumber;

+  return EFI_SUCCESS;

+}

+

+VOID

+BOpt_FreeMenu (

+  BM_MENU_OPTION        *FreeMenu

+  )

+/*++

+

+Routine Description

+  Free resources allocated in Allocate Rountine

+

+Arguments:

+  FreeMenu        Menu to be freed

+

+Returns:

+  VOID

+  

+--*/

+{

+  BM_MENU_ENTRY *MenuEntry;

+  while (!IsListEmpty (&FreeMenu->Head)) {

+    MenuEntry = CR (

+                  FreeMenu->Head.ForwardLink,

+                  BM_MENU_ENTRY,

+                  Link,

+                  BM_MENU_ENTRY_SIGNATURE

+                  );

+    RemoveEntryList (&MenuEntry->Link);

+    BOpt_DestroyMenuEntry (MenuEntry);

+  }

+}

+

+EFI_STATUS

+BOpt_FindFiles (

+  IN BMM_CALLBACK_DATA          *CallbackData,

+  IN BM_MENU_ENTRY              *MenuEntry

+  )

+/*++

+

+Routine Description

+  Find files under current directory

+  All files and sub-directories in current directory

+  will be stored in DirectoryMenu for future use.

+

+Arguments:

+  FileOption   -- Pointer for Dir to explore

+

+Returns:

+  TRUE         -- Get files from current dir successfully

+  FALSE        -- Can't get files from current dir

+

+--*/

+{

+  EFI_FILE_HANDLE NewDir;

+  EFI_FILE_HANDLE Dir;

+  EFI_FILE_INFO   *DirInfo;

+  UINTN           BufferSize;

+  UINTN           DirBufferSize;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_FILE_CONTEXT *FileContext;

+  BM_FILE_CONTEXT *NewFileContext;

+  UINTN           Pass;

+  EFI_STATUS      Status;

+  UINTN           OptionNumber;

+

+  FileContext   = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;

+  Dir           = FileContext->FHandle;

+  OptionNumber  = 0;

+  //

+  // Open current directory to get files from it

+  //

+  Status = Dir->Open (

+                  Dir,

+                  &NewDir,

+                  FileContext->FileName,

+                  EFI_FILE_READ_ONLY,

+                  0

+                  );

+  if (!FileContext->IsRoot) {

+    Dir->Close (Dir);

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  DirInfo = EfiLibFileInfo (NewDir);

+  if (!DirInfo) {

+    return EFI_NOT_FOUND;

+  }

+

+  if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  FileContext->DevicePath = FileDevicePath (

+                              FileContext->Handle,

+                              FileContext->FileName

+                              );

+

+  DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;

+  DirInfo       = AllocateZeroPool (DirBufferSize);

+  if (!DirInfo) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Get all files in current directory

+  // Pass 1 to get Directories

+  // Pass 2 to get files that are EFI images

+  //

+  for (Pass = 1; Pass <= 2; Pass++) {

+    NewDir->SetPosition (NewDir, 0);

+    for (;;) {

+      BufferSize  = DirBufferSize;

+      Status      = NewDir->Read (NewDir, &BufferSize, DirInfo);

+      if (EFI_ERROR (Status) || BufferSize == 0) {

+        break;

+      }

+

+      if ((DirInfo->Attribute & EFI_FILE_DIRECTORY && Pass == 2) ||

+          (!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && Pass == 1)

+          ) {

+        //

+        // Pass 1 is for Directories

+        // Pass 2 is for file names

+        //

+        continue;

+      }

+

+      if (!(BOpt_IsEfiImageName (DirInfo->FileName) || DirInfo->Attribute & EFI_FILE_DIRECTORY)) {

+        //

+        // Slip file unless it is a directory entry or a .EFI file

+        //

+        continue;

+      }

+

+      NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);

+      if (NULL == NewMenuEntry) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      NewFileContext          = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;

+      NewFileContext->Handle  = FileContext->Handle;

+      NewFileContext->FileName = BOpt_AppendFileName (

+                                  FileContext->FileName,

+                                  DirInfo->FileName

+                                  );

+      NewFileContext->FHandle = NewDir;

+      NewFileContext->DevicePath = FileDevicePath (

+                                    NewFileContext->Handle,

+                                    NewFileContext->FileName

+                                    );

+      NewMenuEntry->HelpString = NULL;

+

+      MenuEntry->DisplayStringToken = GetStringTokenFromDepository (

+                                        CallbackData,

+                                        FileOptionStrDepository

+                                        );

+

+      NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);

+

+      if (NewFileContext->IsDir) {

+        BufferSize                  = StrLen (DirInfo->FileName) * 2 + 6;

+        NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize);

+

+        UnicodeSPrint (

+          NewMenuEntry->DisplayString,

+          BufferSize,

+          L"<%s>",

+          DirInfo->FileName

+          );

+

+      } else {

+        NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName);

+      }

+

+      NewFileContext->IsRoot            = FALSE;

+      NewFileContext->IsLoadFile        = FALSE;

+      NewFileContext->IsRemovableMedia  = FALSE;

+

+      NewMenuEntry->OptionNumber        = OptionNumber;

+      OptionNumber++;

+      InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link);

+    }

+  }

+

+  DirectoryMenu.MenuNumber = OptionNumber;

+  SafeFreePool (DirInfo);

+  return TRUE;

+}

+

+EFI_STATUS

+BOpt_GetLegacyOptions (

+  VOID

+  )

+/*++

+Routine Description:

+  

+  Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().

+    

+Arguments:

+  None

+

+Returns:

+  The device info of legacy device.

+  

+--*/

+{

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_LEGACY_DEVICE_CONTEXT  *NewLegacyDevContext;

+  EFI_STATUS                Status;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  UINT16                    HddCount;

+  HDD_INFO                  *HddInfo;

+  UINT16                    BbsCount;

+  BBS_TABLE                 *BbsTable;

+  UINTN                     Index;

+  CHAR16                    DescString[100];

+  UINTN                     FDNum;

+  UINTN                     HDNum;

+  UINTN                     CDNum;

+  UINTN                     NETNum;

+  UINTN                     BEVNum;

+

+  NewMenuEntry  = NULL;

+  HddInfo       = NULL;

+  BbsTable      = NULL;

+  BbsCount      = 0;

+

+  //

+  // Initialize Bbs Table Context from BBS info data

+  //

+  InitializeListHead (&LegacyFDMenu.Head);

+  InitializeListHead (&LegacyHDMenu.Head);

+  InitializeListHead (&LegacyCDMenu.Head);

+  InitializeListHead (&LegacyNETMenu.Head);

+  InitializeListHead (&LegacyBEVMenu.Head);

+

+  Status = gBS->LocateProtocol (

+                  &gEfiLegacyBiosProtocolGuid,

+                  NULL,

+                  &LegacyBios

+                  );

+  if (!EFI_ERROR (Status)) {

+    Status = LegacyBios->GetBbsInfo (

+                          LegacyBios,

+                          &HddCount,

+                          &HddInfo,

+                          &BbsCount,

+                          &BbsTable

+                          );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  FDNum   = 0;

+  HDNum   = 0;

+  CDNum   = 0;

+  NETNum  = 0;

+  BEVNum  = 0;

+

+  for (Index = 0; Index < BbsCount; Index++) {

+    if ((BBS_IGNORE_ENTRY == BbsTable[Index].BootPriority) ||

+        (BBS_DO_NOT_BOOT_FROM == BbsTable[Index].BootPriority) ||

+        (BBS_LOWEST_PRIORITY == BbsTable[Index].BootPriority)

+        ) {

+      continue;

+    }

+

+    NewMenuEntry = BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT);

+    if (NULL == NewMenuEntry) {

+      break;

+    }

+

+    NewLegacyDevContext           = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;

+    NewLegacyDevContext->BbsTable = &BbsTable[Index];

+    NewLegacyDevContext->Index    = Index;

+    NewLegacyDevContext->BbsCount = BbsCount;

+    BdsBuildLegacyDevNameString (

+      &BbsTable[Index],

+      Index,

+      sizeof (DescString),

+      DescString

+      );

+    NewLegacyDevContext->Description = AllocateZeroPool (StrSize (DescString));

+    if (NULL == NewLegacyDevContext->Description) {

+      break;

+    }

+

+    CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));

+    NewMenuEntry->DisplayString = NewLegacyDevContext->Description;

+    NewMenuEntry->HelpString    = NULL;

+

+    switch (BbsTable[Index].DeviceType) {

+    case BBS_FLOPPY:

+      InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link);

+      FDNum++;

+      break;

+

+    case BBS_HARDDISK:

+      InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link);

+      HDNum++;

+      break;

+

+    case BBS_CDROM:

+      InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link);

+      CDNum++;

+      break;

+

+    case BBS_EMBED_NETWORK:

+      InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link);

+      NETNum++;

+      break;

+

+    case BBS_BEV_DEVICE:

+      InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link);

+      BEVNum++;

+      break;

+    }

+  }

+

+  if (Index != BbsCount) {

+    BOpt_FreeLegacyOptions ();

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  LegacyFDMenu.MenuNumber   = FDNum;

+  LegacyHDMenu.MenuNumber   = HDNum;

+  LegacyCDMenu.MenuNumber   = CDNum;

+  LegacyNETMenu.MenuNumber  = NETNum;

+  LegacyBEVMenu.MenuNumber  = BEVNum;

+  return EFI_SUCCESS;

+}

+

+VOID

+BOpt_FreeLegacyOptions (

+  VOID

+  )

+{

+  BOpt_FreeMenu (&LegacyFDMenu);

+  BOpt_FreeMenu (&LegacyHDMenu);

+  BOpt_FreeMenu (&LegacyCDMenu);

+  BOpt_FreeMenu (&LegacyNETMenu);

+  BOpt_FreeMenu (&LegacyBEVMenu);

+}

+

+EFI_STATUS

+BOpt_GetBootOptions (

+  IN  BMM_CALLBACK_DATA         *CallbackData

+  )

+/*++

+

+Routine Description:

+  

+  Build the BootOptionMenu according to BootOrder Variable.

+  This Routine will access the Boot#### to get EFI_LOAD_OPTION 

+  

+Arguments:

+  None

+

+Returns:

+  The number of the Var Boot####

+  

+--*/

+{

+  UINTN                     Index;

+  UINT16                    BootString[10];

+  UINT8                     *LoadOptionFromVar;

+  UINT8                     *LoadOption;

+  UINTN                     BootOptionSize;

+  BOOLEAN                   BootNextFlag;

+  UINT16                    *BootOrderList;

+  UINTN                     BootOrderListSize;

+  UINT16                    *BootNext;

+  UINTN                     BootNextSize;

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_LOAD_CONTEXT           *NewLoadContext;

+  UINT8                     *LoadOptionPtr;

+  UINTN                     StringSize;

+  UINTN                     OptionalDataSize;

+  UINT8                     *LoadOptionEnd;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  UINTN                     MenuCount;

+  UINT8                     *Ptr;

+

+  MenuCount         = 0;

+  BootOrderListSize = 0;

+  BootNextSize      = 0;

+  BootOrderList     = NULL;

+  BootNext          = NULL;

+  LoadOptionFromVar = NULL;

+  BOpt_FreeMenu (&BootOptionMenu);

+  InitializeListHead (&BootOptionMenu.Head);

+

+  //

+  // Get the BootOrder from the Var

+  //

+  BootOrderList = BdsLibGetVariableAndSize (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    &BootOrderListSize

+                    );

+

+  //

+  // Get the BootNext from the Var

+  //

+  BootNext = BdsLibGetVariableAndSize (

+              L"BootNext",

+              &gEfiGlobalVariableGuid,

+              &BootNextSize

+              );

+

+  if (BootNext) {

+    if (BootNextSize != sizeof (UINT16)) {

+      SafeFreePool (BootNext);

+      BootNext = NULL;

+    }

+  }

+

+  for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {

+    UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", BootOrderList[Index]);

+    //

+    //  Get all loadoptions from the VAR

+    //

+    LoadOptionFromVar = BdsLibGetVariableAndSize (

+                          BootString,

+                          &gEfiGlobalVariableGuid,

+                          &BootOptionSize

+                          );

+    if (!LoadOptionFromVar) {

+      continue;

+    }

+

+    LoadOption = AllocateZeroPool (BootOptionSize);

+    if (!LoadOption) {

+      continue;

+    }

+

+    CopyMem (LoadOption, LoadOptionFromVar, BootOptionSize);

+    SafeFreePool (LoadOptionFromVar);

+

+    if (BootNext) {

+      BootNextFlag = (BOOLEAN) (*BootNext == BootOrderList[Index]);

+    } else {

+      BootNextFlag = FALSE;

+    }

+

+    if (0 == (*((UINT32 *) LoadOption) & LOAD_OPTION_ACTIVE)) {

+      SafeFreePool (LoadOption);

+      continue;

+    }

+    //

+    // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly.

+    // the buffer allocated already should be freed before returning.

+    //

+    NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);

+    if (NULL == NewMenuEntry) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    NewLoadContext                      = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+

+    LoadOptionPtr                       = LoadOption;

+    LoadOptionEnd                       = LoadOption + BootOptionSize;

+

+    NewMenuEntry->OptionNumber          = BootOrderList[Index];

+    NewLoadContext->LoadOptionModified  = FALSE;

+    NewLoadContext->Deleted             = FALSE;

+    NewLoadContext->IsBootNext          = BootNextFlag;

+

+    //

+    // Is a Legacy Device?

+    //

+    Ptr = (UINT8 *) LoadOption;

+

+    //

+    // Attribute = *(UINT32 *)Ptr;

+    //

+    Ptr += sizeof (UINT32);

+

+    //

+    // FilePathSize = *(UINT16 *)Ptr;

+    //

+    Ptr += sizeof (UINT16);

+

+    //

+    // Description = (CHAR16 *)Ptr;

+    //

+    Ptr += StrSize ((CHAR16 *) Ptr);

+

+    //

+    // Now Ptr point to Device Path

+    //

+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;

+    if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {

+      NewLoadContext->IsLegacy = TRUE;

+    } else {

+      NewLoadContext->IsLegacy = FALSE;

+    }

+    //

+    // LoadOption is a pointer type of UINT8

+    // for easy use with following LOAD_OPTION

+    // embedded in this struct

+    //

+    NewLoadContext->LoadOption      = LoadOption;

+    NewLoadContext->LoadOptionSize  = BootOptionSize;

+

+    NewLoadContext->Attributes      = *(UINT32 *) LoadOptionPtr;

+    NewLoadContext->IsActive        = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE);

+

+    NewLoadContext->ForceReconnect  = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);

+

+    LoadOptionPtr += sizeof (UINT32);

+

+    NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;

+    LoadOptionPtr += sizeof (UINT16);

+

+    StringSize                  = StrSize ((UINT16 *) LoadOptionPtr);

+    NewLoadContext->Description = AllocateZeroPool (StringSize);

+    ASSERT (NewLoadContext->Description != NULL);

+    CopyMem (

+      NewLoadContext->Description,

+      (UINT16 *) LoadOptionPtr,

+      StringSize

+      );

+    NewMenuEntry->DisplayString = NewLoadContext->Description;

+

+    LoadOptionPtr += StringSize;

+

+    NewLoadContext->FilePathList = AllocateZeroPool (NewLoadContext->FilePathListLength);

+    ASSERT (NewLoadContext->FilePathList != NULL);

+    CopyMem (

+      NewLoadContext->FilePathList,

+      (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr,

+      NewLoadContext->FilePathListLength

+      );

+

+    NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);

+    NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (

+                                        CallbackData,

+                                        BootOptionStrDepository

+                                        );

+    NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (

+                                      CallbackData,

+                                      BootOptionHelpStrDepository

+                                      );

+    LoadOptionPtr += NewLoadContext->FilePathListLength;

+

+    if (LoadOptionPtr < LoadOptionEnd) {

+      OptionalDataSize = BootOptionSize -

+        sizeof (UINT32) -

+        sizeof (UINT16) -

+        StringSize -

+        NewLoadContext->FilePathListLength;

+

+      NewLoadContext->OptionalData = AllocateZeroPool (OptionalDataSize);

+      ASSERT (NewLoadContext->OptionalData != NULL);

+      CopyMem (

+        NewLoadContext->OptionalData,

+        LoadOptionPtr,

+        OptionalDataSize

+        );

+

+      NewLoadContext->OptionalDataSize = OptionalDataSize;

+    }

+

+    InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);

+    MenuCount++;

+  }

+

+  SafeFreePool (BootNext);

+  SafeFreePool (BootOrderList);

+  BootOptionMenu.MenuNumber = MenuCount;

+  return MenuCount;

+}

+

+CHAR16 *

+BOpt_AppendFileName (

+  IN  CHAR16  *Str1,

+  IN  CHAR16  *Str2

+  )

+/*++

+

+Routine Description

+  Append file name to existing file name.

+

+Arguments:

+  Str1  -   existing file name

+  Str2  -   file name to be appended

+

+Returns:

+  Allocate a new string to hold the appended result.

+  Caller is responsible to free the returned string.

+

+--*/

+{

+  UINTN   Size1;

+  UINTN   Size2;

+  CHAR16  *Str;

+  CHAR16  *Ptr;

+  CHAR16  *LastSlash;

+

+  Size1 = StrSize (Str1);

+  Size2 = StrSize (Str2);

+  Str   = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));

+  ASSERT (Str != NULL);

+

+  StrCat (Str, Str1);

+  if (!((*Str == '\\') && (*(Str + 1) == 0))) {

+    StrCat (Str, L"\\");

+  }

+

+  StrCat (Str, Str2);

+

+  Ptr       = Str;

+  LastSlash = Str;

+  while (*Ptr != 0) {

+    if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) != 0) {

+      //

+      // Convert \Name\..\ to \

+      // DO NOT convert the .. if it is at the end of the string. This will

+      // break the .. behavior in changing directories.

+      //

+      StrCpy (LastSlash, Ptr + 3);

+      Ptr = LastSlash;

+    } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {

+      //

+      // Convert a \.\ to a \

+      //

+      StrCpy (Ptr, Ptr + 2);

+      Ptr = LastSlash;

+    } else if (*Ptr == '\\') {

+      LastSlash = Ptr;

+    }

+

+    Ptr++;

+  }

+

+  return Str;

+}

+

+BOOLEAN

+BOpt_IsEfiImageName (

+  IN UINT16  *FileName

+  )

+/*++

+

+Routine Description

+  Check whether current FileName point to a valid 

+  Efi Image File.

+

+Arguments:

+  FileName  -   File need to be checked.

+

+Returns:

+  TRUE  -   Is Efi Image

+  FALSE -   Not a valid Efi Image

+  

+--*/

+{

+  //

+  // Search for ".efi" extension

+  //

+  while (*FileName) {

+    if (FileName[0] == '.') {

+      if (FileName[1] == 'e' || FileName[1] == 'E') {

+        if (FileName[2] == 'f' || FileName[2] == 'F') {

+          if (FileName[3] == 'i' || FileName[3] == 'I') {

+            return TRUE;

+          } else if (FileName[3] == 0x0000) {

+            return FALSE;

+          }

+        } else if (FileName[2] == 0x0000) {

+          return FALSE;

+        }

+      } else if (FileName[1] == 0x0000) {

+        return FALSE;

+      }

+    }

+

+    FileName += 1;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+BOpt_IsEfiApp (

+  IN EFI_FILE_HANDLE Dir,

+  IN UINT16          *FileName

+  )

+/*++

+

+Routine Description:

+  Check whether current FileName point to a valid Efi Application

+  

+Arguments:

+  Dir       -   Pointer to current Directory

+  FileName  -   Pointer to current File name.

+  

+Returns:

+  TRUE      -   Is a valid Efi Application

+  FALSE     -   not a valid Efi Application

+  

+--*/

+{

+  UINTN                       BufferSize;

+  EFI_IMAGE_DOS_HEADER        DosHdr;

+  EFI_IMAGE_NT_HEADERS        PeHdr;

+  EFI_IMAGE_OPTIONAL_HEADER32 *PeOpt32;

+  EFI_IMAGE_OPTIONAL_HEADER64 *PeOpt64;

+  UINT16                      Subsystem;

+  EFI_FILE_HANDLE             File;

+  EFI_STATUS                  Status;

+

+  Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);

+

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);

+  File->Read (File, &BufferSize, &DosHdr);

+  if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    File->Close (File);

+    return FALSE;

+  }

+

+  File->SetPosition (File, DosHdr.e_lfanew);

+  BufferSize = sizeof (EFI_IMAGE_NT_HEADERS);

+  File->Read (File, &BufferSize, &PeHdr);

+  if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {

+    File->Close (File);

+    return FALSE;

+  }

+  //

+  // Determine PE type and read subsytem

+  // BugBug : We should be using EFI_IMAGE_MACHINE_TYPE_SUPPORTED (machine)

+  // macro to detect the machine type.

+  // We should not be using  EFI_IMAGE_OPTIONAL_HEADER32 and

+  // EFI_IMAGE_OPTIONAL_HEADER64

+  //

+  if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+    PeOpt32   = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr.OptionalHeader);

+    Subsystem = PeOpt32->Subsystem;

+  } else if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {

+    PeOpt64   = (EFI_IMAGE_OPTIONAL_HEADER64 *) &(PeHdr.OptionalHeader);

+    Subsystem = PeOpt64->Subsystem;

+  } else {

+    return FALSE;

+  }

+

+  if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {

+    File->Close (File);

+    return TRUE;

+  } else {

+    File->Close (File);

+    return FALSE;

+  }

+}

+

+EFI_STATUS

+BOpt_FindDrivers (

+  VOID

+  )

+/*++

+

+Routine Description

+  Find drivers that will be added as Driver#### variables from handles

+  in current system environment

+  All valid handles in the system except those consume SimpleFs, LoadFile

+  are stored in DriverMenu for future use.

+  

+Arguments:

+  None

+

+Returns:

+  EFI_SUCCESS

+  Others

+

+--*/

+{

+  UINTN                           NoDevicePathHandles;

+  EFI_HANDLE                      *DevicePathHandle;

+  UINTN                           Index;

+  EFI_STATUS                      Status;

+  BM_MENU_ENTRY                   *NewMenuEntry;

+  BM_HANDLE_CONTEXT               *NewHandleContext;

+  EFI_HANDLE                      CurHandle;

+  UINTN                           OptionNumber;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;

+  EFI_LOAD_FILE_PROTOCOL          *LoadFile;

+

+  SimpleFs  = NULL;

+  LoadFile  = NULL;

+

+  InitializeListHead (&DriverMenu.Head);

+

+  //

+  // At first, get all handles that support Device Path

+  // protocol which is the basic requirement for

+  // Driver####

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiDevicePathProtocolGuid,

+                  NULL,

+                  &NoDevicePathHandles,

+                  &DevicePathHandle

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  OptionNumber = 0;

+  for (Index = 0; Index < NoDevicePathHandles; Index++) {

+    CurHandle = DevicePathHandle[Index];

+

+    //

+    //  Check whether this handle support

+    //  driver binding

+    //

+    Status = gBS->HandleProtocol (

+                    CurHandle,

+                    &gEfiSimpleFileSystemProtocolGuid,

+                    &SimpleFs

+                    );

+    if (Status == EFI_SUCCESS) {

+      continue;

+    }

+

+    Status = gBS->HandleProtocol (

+                    CurHandle,

+                    &gEfiLoadFileProtocolGuid,

+                    &LoadFile

+                    );

+    if (Status == EFI_SUCCESS) {

+      continue;

+    }

+

+    NewMenuEntry = BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT);

+    if (NULL == NewMenuEntry) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    NewHandleContext              = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;

+    NewHandleContext->Handle      = CurHandle;

+    NewHandleContext->DevicePath  = DevicePathFromHandle (CurHandle);

+    NewMenuEntry->DisplayString = DevicePathToStr (NewHandleContext->DevicePath);

+    NewMenuEntry->HelpString    = NULL;

+    NewMenuEntry->OptionNumber  = OptionNumber;

+    OptionNumber++;

+    InsertTailList (&DriverMenu.Head, &NewMenuEntry->Link);

+

+  }

+

+  DriverMenu.MenuNumber = OptionNumber;

+  return EFI_SUCCESS;

+}

+

+UINT16

+BOpt_GetBootOptionNumber (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Get the Option Number that does not used 

+  

+Arguments:

+

+Returns:

+  The Option Number

+  

+--*/

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        *BootOrderList;

+  UINTN         BootOrderListSize;

+  UINT16        Number;

+  UINTN         Index;

+  UINTN         Index2;

+  BOOLEAN       Found;

+  CHAR16        StrTemp[100];

+  UINT16        *OptionBuffer;

+  UINTN         OptionSize;

+

+  BootOrderListSize = 0;

+  BootOrderList     = NULL;

+

+  BootOrderList = BdsLibGetVariableAndSize (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    &BootOrderListSize

+                    );

+  if (BootOrderList) {

+    //

+    // already have Boot####

+    //

+    // AlreadyBootNumbers = BootOrderListSize / sizeof(UINT16);

+    //

+    for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {

+      Found = TRUE;

+      for (Index2 = 0; Index2 < BootOptionMenu.MenuNumber; Index2++) {

+        NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index2);

+        if (Index == NewMenuEntry->OptionNumber) {

+          Found = FALSE;

+          break;

+        }

+      }

+

+      if (Found) {

+  	   UnicodeSPrint (StrTemp, 100, L"Boot%04x", Index);

+  	   DEBUG((EFI_D_ERROR,"INdex= %s\n", StrTemp));

+       OptionBuffer = BdsLibGetVariableAndSize (

+                StrTemp,

+                &gEfiGlobalVariableGuid,

+                &OptionSize

+                );

+      if (NULL == OptionBuffer) 

+        break;

+      }

+    }

+    //

+    // end for Index

+    //

+    Number = (UINT16) Index;

+  } else {

+    //

+    // No Boot####

+    //

+    Number = 0;

+  }

+

+  return Number;

+}

+

+UINT16

+BOpt_GetDriverOptionNumber (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Get the Option Number that does not used 

+  

+Arguments:

+

+Returns:

+  The Option Number

+  

+--*/

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        *DriverOrderList;

+  UINTN         DriverOrderListSize;

+  UINT16        Number;

+  UINTN         Index;

+  UINTN         Index2;

+  BOOLEAN       Found;

+

+  DriverOrderListSize = 0;

+  DriverOrderList     = NULL;

+

+  DriverOrderList = BdsLibGetVariableAndSize (

+                      L"DriverOrder",

+                      &gEfiGlobalVariableGuid,

+                      &DriverOrderListSize

+                      );

+  if (DriverOrderList) {

+    //

+    // already have Driver####

+    //

+    // AlreadyDriverNumbers = DriverOrderListSize / sizeof(UINT16);

+    //

+    for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {

+      Found = TRUE;

+      for (Index2 = 0; Index2 < DriverOptionMenu.MenuNumber; Index2++) {

+        NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index2);

+        if (Index == NewMenuEntry->OptionNumber) {

+          Found = FALSE;

+          break;

+        }

+      }

+

+      if (Found) {

+        break;

+      }

+    }

+    //

+    // end for Index

+    //

+    Number = (UINT16) Index;

+  } else {

+    //

+    // No Driver####

+    //

+    Number = 0;

+  }

+

+  return Number;

+}

+

+EFI_STATUS

+BOpt_GetDriverOptions (

+  IN  BMM_CALLBACK_DATA         *CallbackData

+  )

+/*++

+

+Routine Description:

+  Build up all DriverOptionMenu

+  

+Arguments:

+

+Returns:

+  The Option Number

+  

+--*/

+{

+  UINTN           Index;

+  UINT16          DriverString[12];

+  UINT8           *LoadOptionFromVar;

+  UINT8           *LoadOption;

+  UINTN           DriverOptionSize;

+

+  UINT16          *DriverOrderList;

+  UINTN           DriverOrderListSize;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+  UINT8           *LoadOptionPtr;

+  UINTN           StringSize;

+  UINTN           OptionalDataSize;

+  UINT8           *LoadOptionEnd;

+

+  DriverOrderListSize = 0;

+  DriverOrderList     = NULL;

+  DriverOptionSize    = 0;

+  LoadOptionFromVar   = NULL;

+  BOpt_FreeMenu (&DriverOptionMenu);

+  InitializeListHead (&DriverOptionMenu.Head);

+  //

+  // Get the DriverOrder from the Var

+  //

+  DriverOrderList = BdsLibGetVariableAndSize (

+                      L"DriverOrder",

+                      &gEfiGlobalVariableGuid,

+                      &DriverOrderListSize

+                      );

+

+  for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {

+    UnicodeSPrint (

+      DriverString,

+      sizeof (DriverString),

+      L"Driver%04x",

+      DriverOrderList[Index]

+      );

+    //

+    //  Get all loadoptions from the VAR

+    //

+    LoadOptionFromVar = BdsLibGetVariableAndSize (

+                          DriverString,

+                          &gEfiGlobalVariableGuid,

+                          &DriverOptionSize

+                          );

+    if (!LoadOptionFromVar) {

+      continue;

+    }

+

+    LoadOption = AllocateZeroPool (DriverOptionSize);

+    if (!LoadOption) {

+      continue;

+    }

+

+    CopyMem (LoadOption, LoadOptionFromVar, DriverOptionSize);

+    SafeFreePool (LoadOptionFromVar);

+

+    NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);

+    if (NULL == NewMenuEntry) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    NewLoadContext                      = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+    LoadOptionPtr                       = LoadOption;

+    LoadOptionEnd                       = LoadOption + DriverOptionSize;

+    NewMenuEntry->OptionNumber          = DriverOrderList[Index];

+    NewLoadContext->LoadOptionModified  = FALSE;

+    NewLoadContext->Deleted             = FALSE;

+    NewLoadContext->IsLegacy            = FALSE;

+

+    //

+    // LoadOption is a pointer type of UINT8

+    // for easy use with following LOAD_OPTION

+    // embedded in this struct

+    //

+    NewLoadContext->LoadOption      = LoadOption;

+    NewLoadContext->LoadOptionSize  = DriverOptionSize;

+

+    NewLoadContext->Attributes      = *(UINT32 *) LoadOptionPtr;

+    NewLoadContext->IsActive        = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE);

+

+    NewLoadContext->ForceReconnect  = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);

+

+    LoadOptionPtr += sizeof (UINT32);

+

+    NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;

+    LoadOptionPtr += sizeof (UINT16);

+

+    StringSize                  = StrSize ((UINT16 *) LoadOptionPtr);

+    NewLoadContext->Description = AllocateZeroPool (StringSize);

+    ASSERT (NewLoadContext->Description != NULL);

+    CopyMem (

+      NewLoadContext->Description,

+      (UINT16 *) LoadOptionPtr,

+      StringSize

+      );

+    NewMenuEntry->DisplayString = NewLoadContext->Description;

+

+    LoadOptionPtr += StringSize;

+

+    NewLoadContext->FilePathList = AllocateZeroPool (NewLoadContext->FilePathListLength);

+    ASSERT (NewLoadContext->FilePathList != NULL);

+    CopyMem (

+      NewLoadContext->FilePathList,

+      (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr,

+      NewLoadContext->FilePathListLength

+      );

+

+    NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);

+    NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (

+                                        CallbackData,

+                                        DriverOptionStrDepository

+                                        );

+    NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (

+                                      CallbackData,

+                                      DriverOptionHelpStrDepository

+                                      );

+    LoadOptionPtr += NewLoadContext->FilePathListLength;

+

+    if (LoadOptionPtr < LoadOptionEnd) {

+      OptionalDataSize = DriverOptionSize -

+        sizeof (UINT32) -

+        sizeof (UINT16) -

+        StringSize -

+        NewLoadContext->FilePathListLength;

+

+      NewLoadContext->OptionalData = AllocateZeroPool (OptionalDataSize);

+      ASSERT (NewLoadContext->OptionalData != NULL);

+      CopyMem (

+        NewLoadContext->OptionalData,

+        LoadOptionPtr,

+        OptionalDataSize

+        );

+

+      NewLoadContext->OptionalDataSize = OptionalDataSize;

+    }

+

+    InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);

+

+  }

+

+  SafeFreePool (DriverOrderList);

+  DriverOptionMenu.MenuNumber = Index;

+  return EFI_SUCCESS;

+

+}

+

+VOID

+SafeFreePool (

+  IN VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+  Wrap original FreePool gBS call

+  in order to decrease code length

+  

+Arguments:

+

+Returns:

+

+--*/

+{

+  if (Buffer != NULL) {

+    gBS->FreePool (Buffer);

+    Buffer = NULL;

+  }

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/ConsoleOption.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/ConsoleOption.c
new file mode 100644
index 0000000..9deb5fa
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/ConsoleOption.c
@@ -0,0 +1,840 @@
+/*++

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    consoleoption.c

+    

+Abstract:

+

+    handles console redirection from boot manager

+

+

+Revision History

+

+--*/

+

+#include "bootmaint.h"

+

+EFI_DEVICE_PATH_PROTOCOL  *

+DevicePathInstanceDup (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath

+  );

+

+EFI_STATUS

+UpdateComAttributeFromVariable (

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  );

+

+EFI_STATUS

+ChangeTerminalDevicePath (

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  BOOLEAN                   ChangeTerminal

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *Node;

+  EFI_DEVICE_PATH_PROTOCOL  *Node1;

+  ACPI_HID_DEVICE_PATH      *Acpi;

+  UART_DEVICE_PATH          *Uart;

+  UART_DEVICE_PATH          *Uart1;

+  UINTN                     Com;

+  UINT32                    Match;

+  BM_TERMINAL_CONTEXT       *NewTerminalContext;

+  BM_MENU_ENTRY             *NewMenuEntry;

+

+  Match = EISA_PNP_ID (0x0501);

+  Node  = DevicePath;

+  Node  = NextDevicePathNode (Node);

+  Com   = 0;

+  while (!IsDevicePathEnd (Node)) {

+    if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {

+      Acpi = (ACPI_HID_DEVICE_PATH *) Node;

+      if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {

+        CopyMem (&Com, &Acpi->UID, sizeof (UINT32));

+      }

+    }

+

+    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+    if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {

+      Uart = (UART_DEVICE_PATH *) Node;

+      CopyMem (

+        &Uart->BaudRate,

+        &NewTerminalContext->BaudRate,

+        sizeof (UINT64)

+        );

+

+      CopyMem (

+        &Uart->DataBits,

+        &NewTerminalContext->DataBits,

+        sizeof (UINT8)

+        );

+

+      CopyMem (

+        &Uart->Parity,

+        &NewTerminalContext->Parity,

+        sizeof (UINT8)

+        );

+

+      CopyMem (

+        &Uart->StopBits,

+        &NewTerminalContext->StopBits,

+        sizeof (UINT8)

+        );

+      //

+      // Change the device path in the ComPort

+      //

+      if (ChangeTerminal) {

+        Node1 = NewTerminalContext->DevicePath;

+        Node1 = NextDevicePathNode (Node1);

+        while (!IsDevicePathEnd (Node1)) {

+          if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {

+            Uart1 = (UART_DEVICE_PATH *) Node1;

+            CopyMem (

+              &Uart1->BaudRate,

+              &NewTerminalContext->BaudRate,

+              sizeof (UINT64)

+              );

+

+            CopyMem (

+              &Uart1->DataBits,

+              &NewTerminalContext->DataBits,

+              sizeof (UINT8)

+              );

+

+            CopyMem (

+              &Uart1->Parity,

+              &NewTerminalContext->Parity,

+              sizeof (UINT8)

+              );

+

+            CopyMem (

+              &Uart1->StopBits,

+              &NewTerminalContext->StopBits,

+              sizeof (UINT8)

+              );

+            break;

+          }

+          //

+          // end if

+          //

+          Node1 = NextDevicePathNode (Node1);

+        }

+        //

+        // end while

+        //

+        break;

+      }

+    }

+

+    Node = NextDevicePathNode (Node);

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+VOID

+ChangeVariableDevicePath (

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *Node;

+  ACPI_HID_DEVICE_PATH      *Acpi;

+  UART_DEVICE_PATH          *Uart;

+  UINTN                     Com;

+  UINT32                    Match;

+  BM_TERMINAL_CONTEXT       *NewTerminalContext;

+  BM_MENU_ENTRY             *NewMenuEntry;

+

+  Match = EISA_PNP_ID (0x0501);

+  Node  = DevicePath;

+  Node  = NextDevicePathNode (Node);

+  Com   = 0;

+  while (!IsDevicePathEnd (Node)) {

+    if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {

+      Acpi = (ACPI_HID_DEVICE_PATH *) Node;

+      if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {

+        CopyMem (&Com, &Acpi->UID, sizeof (UINT32));

+      }

+    }

+

+    if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {

+      NewMenuEntry = BOpt_GetMenuEntry (

+                      &TerminalMenu,

+                      Com

+                      );

+      NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+      Uart                = (UART_DEVICE_PATH *) Node;

+      CopyMem (

+        &Uart->BaudRate,

+        &NewTerminalContext->BaudRate,

+        sizeof (UINT64)

+        );

+

+      CopyMem (

+        &Uart->DataBits,

+        &NewTerminalContext->DataBits,

+        sizeof (UINT8)

+        );

+

+      CopyMem (

+        &Uart->Parity,

+        &NewTerminalContext->Parity,

+        sizeof (UINT8)

+        );

+

+      CopyMem (

+        &Uart->StopBits,

+        &NewTerminalContext->StopBits,

+        sizeof (UINT8)

+        );

+    }

+

+    Node = NextDevicePathNode (Node);

+  }

+

+  return ;

+}

+

+BOOLEAN

+IsTerminalDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath,

+  OUT TYPE_OF_TERMINAL         *Termi,

+  OUT UINTN                    *Com

+  );

+

+EFI_STATUS

+LocateSerialIo (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Build a list containing all serial devices 

+  

+Arguments:

+  

+Returns:

+  

+--*/

+{

+  UINT8                     *Ptr;

+  UINTN                     Index;

+  UINTN                     Index2;

+  UINTN                     NoHandles;

+  EFI_HANDLE                *Handles;

+  EFI_STATUS                Status;

+  ACPI_HID_DEVICE_PATH      *Acpi;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  UINT32                    Match;

+  EFI_SERIAL_IO_PROTOCOL    *SerialIo;

+  EFI_DEVICE_PATH_PROTOCOL  *OutDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *InpDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *ErrDevicePath;

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_TERMINAL_CONTEXT       *NewTerminalContext;

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  VENDOR_DEVICE_PATH        Vendor;

+  //

+  // Get all handles that have SerialIo protocol installed

+  //

+  InitializeListHead (&TerminalMenu.Head);

+  TerminalMenu.MenuNumber = 0;

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiSerialIoProtocolGuid,

+                  NULL,

+                  &NoHandles,

+                  &Handles

+                  );

+  if (EFI_ERROR (Status)) {

+    //

+    // No serial ports present

+    //

+    return EFI_UNSUPPORTED;

+  }

+

+  for (Index = 0; Index < NoHandles; Index++) {

+    //

+    // Check to see whether the handle has DevicePath Protocol installed

+    //

+    gBS->HandleProtocol (

+          Handles[Index],

+          &gEfiDevicePathProtocolGuid,

+          &DevicePath

+          );

+    Ptr = (UINT8 *) DevicePath;

+    while (*Ptr != END_DEVICE_PATH_TYPE) {

+      Ptr++;

+    }

+

+    Ptr   = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);

+    Acpi  = (ACPI_HID_DEVICE_PATH *) Ptr;

+    Match = EISA_PNP_ID (0x0501);

+

+    if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {

+      NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);

+      if (!NewMenuEntry) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+      CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));

+      NewTerminalContext->DevicePath = DevicePathInstanceDup (DevicePath);

+      //

+      // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!

+      // coz' the misc data for each platform is not correct, actually it's the device path stored in

+      // datahub which is not completed, so a searching for end of device path will enter a

+      // dead-loop.

+      //

+      NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);

+      if (NULL == NewMenuEntry->DisplayString) {

+        NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);

+      }

+

+      NewMenuEntry->HelpString = NULL;

+

+      gBS->HandleProtocol (

+            Handles[Index],

+            &gEfiSerialIoProtocolGuid,

+            &SerialIo

+            );

+

+      CopyMem (

+        &NewTerminalContext->BaudRate,

+        &SerialIo->Mode->BaudRate,

+        sizeof (UINT64)

+        );

+

+      CopyMem (

+        &NewTerminalContext->DataBits,

+        &SerialIo->Mode->DataBits,

+        sizeof (UINT8)

+        );

+

+      CopyMem (

+        &NewTerminalContext->Parity,

+        &SerialIo->Mode->Parity,

+        sizeof (UINT8)

+        );

+

+      CopyMem (

+        &NewTerminalContext->StopBits,

+        &SerialIo->Mode->StopBits,

+        sizeof (UINT8)

+        );

+      InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);

+      TerminalMenu.MenuNumber++;

+    }

+  }

+  //

+  // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var

+  //

+  OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);

+  InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);

+  ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);

+  if (OutDevicePath) {

+    UpdateComAttributeFromVariable (OutDevicePath);

+  }

+

+  if (InpDevicePath) {

+    UpdateComAttributeFromVariable (InpDevicePath);

+  }

+

+  if (ErrDevicePath) {

+    UpdateComAttributeFromVariable (ErrDevicePath);

+  }

+

+  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewTerminalContext                = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+

+    NewTerminalContext->TerminalType  = 0;

+    NewTerminalContext->IsConIn       = FALSE;

+    NewTerminalContext->IsConOut      = FALSE;

+    NewTerminalContext->IsStdErr      = FALSE;

+

+    Vendor.Header.Type                = MESSAGING_DEVICE_PATH;

+    Vendor.Header.SubType             = MSG_VENDOR_DP;

+

+    for (Index2 = 0; Index2 < 4; Index2++) {

+      CopyMem (&Vendor.Guid, &Guid[Index2], sizeof (EFI_GUID));

+      SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));

+      NewDevicePath = AppendDevicePathNode (

+                        NewTerminalContext->DevicePath,

+                        (EFI_DEVICE_PATH_PROTOCOL *) &Vendor

+                        );

+      SafeFreePool (NewMenuEntry->HelpString);

+      //

+      // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);

+      // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;

+      //

+      NewMenuEntry->HelpString = NULL;

+

+      if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {

+        NewTerminalContext->IsConOut      = TRUE;

+        NewTerminalContext->TerminalType  = (UINT8) Index2;

+      }

+

+      if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {

+        NewTerminalContext->IsConIn       = TRUE;

+        NewTerminalContext->TerminalType  = (UINT8) Index2;

+      }

+

+      if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {

+        NewTerminalContext->IsStdErr      = TRUE;

+        NewTerminalContext->TerminalType  = (UINT8) Index2;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UpdateComAttributeFromVariable (

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+/*++

+

+Routine Description:

+  Update Com Ports attributes from DevicePath

+  

+Arguments:

+  DevicePath  -   DevicePath that contains Com ports

+  

+Returns:

+  

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *Node;

+  EFI_DEVICE_PATH_PROTOCOL  *SerialNode;

+  ACPI_HID_DEVICE_PATH      *Acpi;

+  UART_DEVICE_PATH          *Uart;

+  UART_DEVICE_PATH          *Uart1;

+  UINT32                    Match;

+  UINTN                     TerminalNumber;

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_TERMINAL_CONTEXT       *NewTerminalContext;

+  UINTN                     Index;

+

+  Match           = EISA_PNP_ID (0x0501);

+  Node            = DevicePath;

+  Node            = NextDevicePathNode (Node);

+  TerminalNumber  = 0;

+  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+    while (!IsDevicePathEnd (Node)) {

+      if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {

+        Acpi = (ACPI_HID_DEVICE_PATH *) Node;

+        if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {

+          CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));

+        }

+      }

+

+      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {

+        Uart          = (UART_DEVICE_PATH *) Node;

+        NewMenuEntry  = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);

+        if (NULL == NewMenuEntry) {

+          return EFI_NOT_FOUND;

+        }

+

+        NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+        CopyMem (

+          &NewTerminalContext->BaudRate,

+          &Uart->BaudRate,

+          sizeof (UINT64)

+          );

+

+        CopyMem (

+          &NewTerminalContext->DataBits,

+          &Uart->DataBits,

+          sizeof (UINT8)

+          );

+

+        CopyMem (

+          &NewTerminalContext->Parity,

+          &Uart->Parity,

+          sizeof (UINT8)

+          );

+

+        CopyMem (

+          &NewTerminalContext->StopBits,

+          &Uart->StopBits,

+          sizeof (UINT8)

+          );

+

+        SerialNode  = NewTerminalContext->DevicePath;

+        SerialNode  = NextDevicePathNode (SerialNode);

+        while (!IsDevicePathEnd (SerialNode)) {

+          if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {

+            //

+            // Update following device paths according to

+            // previous acquired uart attributes

+            //

+            Uart1 = (UART_DEVICE_PATH *) SerialNode;

+            CopyMem (

+              &Uart1->BaudRate,

+              &NewTerminalContext->BaudRate,

+              sizeof (UINT64)

+              );

+

+            CopyMem (

+              &Uart1->DataBits,

+              &NewTerminalContext->DataBits,

+              sizeof (UINT8)

+              );

+            CopyMem (

+              &Uart1->Parity,

+              &NewTerminalContext->Parity,

+              sizeof (UINT8)

+              );

+            CopyMem (

+              &Uart1->StopBits,

+              &NewTerminalContext->StopBits,

+              sizeof (UINT8)

+              );

+

+            break;

+          }

+

+          SerialNode = NextDevicePathNode (SerialNode);

+        }

+        //

+        // end while

+        //

+      }

+

+      Node = NextDevicePathNode (Node);

+    }

+    //

+    // end while

+    //

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_DEVICE_PATH_PROTOCOL *

+DevicePathInstanceDup (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath

+  )

+/*++

+

+Routine Description:

+  Function creates a device path data structure that identically matches the 

+  device path passed in.

+

+Arguments:

+  DevPath      - A pointer to a device path data structure.

+

+Returns:

+

+  The new copy of DevPath is created to identically match the input.  

+  Otherwise, NULL is returned.

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevPath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;

+  EFI_DEVICE_PATH_PROTOCOL  *Temp;

+  UINT8                     *Ptr;

+  UINTN                     Size;

+

+  //

+  // get the size of an instance from the input

+  //

+  Temp            = DevPath;

+  DevicePathInst  = GetNextDevicePathInstance (&Temp, &Size);

+

+  //

+  // Make a copy and set proper end type

+  //

+  NewDevPath = NULL;

+  if (Size) {

+    NewDevPath = AllocateZeroPool (Size);

+    ASSERT (NewDevPath != NULL);

+  }

+

+  if (NewDevPath) {

+    CopyMem (NewDevPath, DevicePathInst, Size);

+    Ptr = (UINT8 *) NewDevPath;

+    Ptr += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);

+    Temp = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;

+    SetDevicePathEndNode (Temp);

+  }

+

+  return NewDevPath;

+}

+

+EFI_STATUS

+GetConsoleMenu (

+  IN UINTN              ConsoleMenuType

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *AllDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *MultiDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;

+  UINTN                     Size;

+  UINTN                     AllCount;

+  UINTN                     Index;

+  UINTN                     Index2;

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_CONSOLE_CONTEXT        *NewConsoleContext;

+  BM_TERMINAL_CONTEXT       *NewTerminalContext;

+  TYPE_OF_TERMINAL          Terminal;

+  BM_MENU_ENTRY             *NewTerminalMenuEntry;

+  UINTN                     Com;

+  BM_MENU_OPTION            *ConsoleMenu;

+

+  DevicePath    = NULL;

+  AllDevicePath = NULL;

+  AllCount      = 0;

+  switch (ConsoleMenuType) {

+  case BM_CONSOLE_IN_CONTEXT_SELECT:

+    ConsoleMenu = &ConsoleInpMenu;

+    DevicePath = EfiLibGetVariable (

+                  L"ConIn",

+                  &gEfiGlobalVariableGuid

+                  );

+

+    AllDevicePath = EfiLibGetVariable (

+                      L"ConInDev",

+                      &gEfiGlobalVariableGuid

+                      );

+    break;

+

+  case BM_CONSOLE_OUT_CONTEXT_SELECT:

+    ConsoleMenu = &ConsoleOutMenu;

+    DevicePath = EfiLibGetVariable (

+                  L"ConOut",

+                  &gEfiGlobalVariableGuid

+                  );

+

+    AllDevicePath = EfiLibGetVariable (

+                      L"ConOutDev",

+                      &gEfiGlobalVariableGuid

+                      );

+    break;

+

+  case BM_CONSOLE_ERR_CONTEXT_SELECT:

+    ConsoleMenu = &ConsoleErrMenu;

+    DevicePath = EfiLibGetVariable (

+                  L"ErrOut",

+                  &gEfiGlobalVariableGuid

+                  );

+

+    AllDevicePath = EfiLibGetVariable (

+                      L"ErrOutDev",

+                      &gEfiGlobalVariableGuid

+                      );

+    break;

+

+  default:

+    return EFI_UNSUPPORTED;

+  }

+

+  if (NULL == AllDevicePath) {

+    return EFI_NOT_FOUND;

+  }

+

+  InitializeListHead (&ConsoleMenu->Head);

+

+  AllCount                = EfiDevicePathInstanceCount (AllDevicePath);

+  ConsoleMenu->MenuNumber = 0;

+  //

+  // Following is menu building up for Console Out Devices

+  //

+  MultiDevicePath = AllDevicePath;

+  Index2          = 0;

+  for (Index = 0; Index < AllCount; Index++) {

+    DevicePathInst  = GetNextDevicePathInstance (&MultiDevicePath, &Size);

+

+    NewMenuEntry    = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);

+    if (NULL == NewMenuEntry) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    NewConsoleContext             = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;

+    NewMenuEntry->OptionNumber    = Index2;

+

+    NewConsoleContext->DevicePath = DevicePathInstanceDup (DevicePathInst);

+    NewMenuEntry->DisplayString   = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);

+    if (NULL == NewMenuEntry->DisplayString) {

+      NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);

+    }

+

+    NewConsoleContext->IsTerminal = IsTerminalDevicePath (

+                                      NewConsoleContext->DevicePath,

+                                      &Terminal,

+                                      &Com

+                                      );

+

+    NewConsoleContext->IsActive = BdsLibMatchDevicePaths (

+                                    DevicePath,

+                                    NewConsoleContext->DevicePath

+                                    );

+    NewTerminalMenuEntry  = NULL;

+    NewTerminalContext    = NULL;

+

+    if (NewConsoleContext->IsTerminal) {

+      BOpt_DestroyMenuEntry (NewMenuEntry);

+    } else {

+      Index2++;

+      ConsoleMenu->MenuNumber++;

+      InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetAllConsoles (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu

+

+Arguments:

+  

+Returns:

+  EFI_SUCCESS 

+  Others

+  

+--*/

+{

+  GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);

+  GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);

+  GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FreeAllConsoles (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu

+

+Arguments:

+  

+Returns:

+  EFI_SUCCESS 

+  Others

+  

+--*/

+{

+  BOpt_FreeMenu (&ConsoleOutMenu);

+  BOpt_FreeMenu (&ConsoleInpMenu);

+  BOpt_FreeMenu (&ConsoleErrMenu);

+  BOpt_FreeMenu (&TerminalMenu);

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsTerminalDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath,

+  OUT TYPE_OF_TERMINAL         *Termi,

+  OUT UINTN                    *Com

+  )

+/*++

+

+Routine Description:

+  Test whether DevicePath is a valid Terminal

+

+Arguments:

+  DevicePath  -   DevicePath to be checked

+  Termi       -   If is terminal, give its type

+  Com         -   If is Com Port, give its type

+  

+Returns:

+  TRUE        -   If DevicePath point to a Terminal

+  FALSE

+  

+--*/

+{

+  UINT8                 *Ptr;

+  BOOLEAN               IsTerminal;

+  VENDOR_DEVICE_PATH    *Vendor;

+  ACPI_HID_DEVICE_PATH  *Acpi;

+  UINT32                Match;

+  EFI_GUID              TempGuid;

+

+  IsTerminal = FALSE;

+

+  //

+  // Parse the Device Path, should be change later!!!

+  //

+  Ptr = (UINT8 *) DevicePath;

+  while (*Ptr != END_DEVICE_PATH_TYPE) {

+    Ptr++;

+  }

+

+  Ptr     = Ptr - sizeof (VENDOR_DEVICE_PATH);

+  Vendor  = (VENDOR_DEVICE_PATH *) Ptr;

+

+  //

+  // There are four kinds of Terminal types

+  // check to see whether this devicepath

+  // is one of that type

+  //

+  CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID));

+

+  if (CompareGuid (&TempGuid, &Guid[0])) {

+    *Termi      = PC_ANSI;

+    IsTerminal  = TRUE;

+  } else {

+    if (CompareGuid (&TempGuid, &Guid[1])) {

+      *Termi      = VT_100;

+      IsTerminal  = TRUE;

+    } else {

+      if (CompareGuid (&TempGuid, &Guid[2])) {

+        *Termi      = VT_100_PLUS;

+        IsTerminal  = TRUE;

+      } else {

+        if (CompareGuid (&TempGuid, &Guid[3])) {

+          *Termi      = VT_UTF8;

+          IsTerminal  = TRUE;

+        } else {

+          IsTerminal = FALSE;

+        }

+      }

+    }

+  }

+

+  if (!IsTerminal) {

+    return FALSE;

+  }

+

+  Ptr   = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);

+  Acpi  = (ACPI_HID_DEVICE_PATH *) Ptr;

+  Match = EISA_PNP_ID (0x0501);

+  if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {

+    CopyMem (Com, &Acpi->UID, sizeof (UINT32));

+  } else {

+    return FALSE;

+  }

+

+  return TRUE;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Data.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Data.c
new file mode 100644
index 0000000..3c0c1cc
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Data.c
@@ -0,0 +1,324 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  data.c

+    

+Abstract:

+

+  Define some data used for Boot Maint

+

+Revision History

+

+--*/

+

+#include "bootmaint.h"

+

+EFI_HII_UPDATE_DATA *UpdateData;

+STRING_DEPOSITORY   *FileOptionStrDepository;

+STRING_DEPOSITORY   *ConsoleOptionStrDepository;

+STRING_DEPOSITORY   *BootOptionStrDepository;

+STRING_DEPOSITORY   *BootOptionHelpStrDepository;

+STRING_DEPOSITORY   *DriverOptionStrDepository;

+STRING_DEPOSITORY   *DriverOptionHelpStrDepository;

+STRING_DEPOSITORY   *TerminalStrDepository;

+

+//

+// Terminal type string token storage

+//

+UINT16              TerminalType[] = {

+  STRING_TOKEN(STR_COM_TYPE_0),

+  STRING_TOKEN(STR_COM_TYPE_1),

+  STRING_TOKEN(STR_COM_TYPE_2),

+  STRING_TOKEN(STR_COM_TYPE_3),

+};

+

+//

+// File system selection menu

+//

+BM_MENU_OPTION      FsOptionMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Console Input Device Selection Menu

+//

+BM_MENU_OPTION      ConsoleInpMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Console Output Device Selection Menu

+//

+BM_MENU_OPTION      ConsoleOutMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Error Output Device Selection Menu

+//

+BM_MENU_OPTION      ConsoleErrMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Boot Option from variable Menu

+//

+BM_MENU_OPTION      BootOptionMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Driver Option from variable menu

+//

+BM_MENU_OPTION      DriverOptionMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Legacy FD Info from LegacyBios.GetBbsInfo()

+//

+BM_MENU_OPTION      LegacyFDMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Legacy HD Info from LegacyBios.GetBbsInfo()

+//

+BM_MENU_OPTION      LegacyHDMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Legacy CD Info from LegacyBios.GetBbsInfo()

+//

+BM_MENU_OPTION      LegacyCDMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Legacy NET Info from LegacyBios.GetBbsInfo()

+//

+BM_MENU_OPTION      LegacyNETMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Legacy NET Info from LegacyBios.GetBbsInfo()

+//

+BM_MENU_OPTION      LegacyBEVMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Files and sub-directories in current directory menu

+//

+BM_MENU_OPTION      DirectoryMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Handles in current system selection menu

+//

+BM_MENU_OPTION      DriverMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+BM_MENU_OPTION      TerminalMenu = {

+  BM_MENU_OPTION_SIGNATURE,

+  NULL,

+  0

+};

+

+//

+// Value and string token correspondency for BaudRate

+//

+COM_ATTR            BaudRateList[19] = {

+  {

+    115200,

+    STRING_TOKEN(STR_COM_BAUD_RATE_0)

+  },

+  {

+    57600,

+    STRING_TOKEN(STR_COM_BAUD_RATE_1)

+  },

+  {

+    38400,

+    STRING_TOKEN(STR_COM_BAUD_RATE_2)

+  },

+  {

+    19200,

+    STRING_TOKEN(STR_COM_BAUD_RATE_3)

+  },

+  {

+    9600,

+    STRING_TOKEN(STR_COM_BAUD_RATE_4)

+  },

+  {

+    7200,

+    STRING_TOKEN(STR_COM_BAUD_RATE_5)

+  },

+  {

+    4800,

+    STRING_TOKEN(STR_COM_BAUD_RATE_6)

+  },

+  {

+    3600,

+    STRING_TOKEN(STR_COM_BAUD_RATE_7)

+  },

+  {

+    2400,

+    STRING_TOKEN(STR_COM_BAUD_RATE_8)

+  },

+  {

+    2000,

+    STRING_TOKEN(STR_COM_BAUD_RATE_9)

+  },

+  {

+    1800,

+    STRING_TOKEN(STR_COM_BAUD_RATE_10)

+  },

+  {

+    1200,

+    STRING_TOKEN(STR_COM_BAUD_RATE_11)

+  },

+  {

+    600,

+    STRING_TOKEN(STR_COM_BAUD_RATE_12)

+  },

+  {

+    300,

+    STRING_TOKEN(STR_COM_BAUD_RATE_13)

+  },

+  {

+    150,

+    STRING_TOKEN(STR_COM_BAUD_RATE_14)

+  },

+  {

+    134,

+    STRING_TOKEN(STR_COM_BAUD_RATE_15)

+  },

+  {

+    110,

+    STRING_TOKEN(STR_COM_BAUD_RATE_16)

+  },

+  {

+    75,

+    STRING_TOKEN(STR_COM_BAUD_RATE_17)

+  },

+  {

+    50,

+    STRING_TOKEN(STR_COM_BAUD_RATE_18)

+  }

+};

+

+//

+// Value and string token correspondency for DataBits

+//

+COM_ATTR            DataBitsList[4] = {

+  {

+    5,

+    STRING_TOKEN(STR_COM_DATA_BITS_0)

+  },

+  {

+    6,

+    STRING_TOKEN(STR_COM_DATA_BITS_1)

+  },

+  {

+    7,

+    STRING_TOKEN(STR_COM_DATA_BITS_2)

+  },

+  {

+    8,

+    STRING_TOKEN(STR_COM_DATA_BITS_3)

+  }

+};

+

+//

+// Value and string token correspondency for Parity

+//

+COM_ATTR            ParityList[5] = {

+  {

+    NoParity,

+    STRING_TOKEN(STR_COM_PAR_0)

+  },

+  {

+    EvenParity,

+    STRING_TOKEN(STR_COM_PAR_1)

+  },

+  {

+    OddParity,

+    STRING_TOKEN(STR_COM_PAR_2)

+  },

+  {

+    MarkParity,

+    STRING_TOKEN(STR_COM_PAR_3)

+  },

+  {

+    SpaceParity,

+    STRING_TOKEN(STR_COM_PAR_4)

+  }

+};

+

+//

+// Value and string token correspondency for Baudreate

+//

+COM_ATTR            StopBitsList[3] = {

+  {

+    OneStopBit,

+    STRING_TOKEN(STR_COM_STOP_BITS_0)

+  },

+  {

+    OneFiveStopBits,

+    STRING_TOKEN(STR_COM_STOP_BITS_1)

+  },

+  {

+    TwoStopBits,

+    STRING_TOKEN(STR_COM_STOP_BITS_2)

+  }

+};

+

+//

+// Guid for messaging path, used in Serial port setting.

+//

+EFI_GUID            Guid[4] = {

+  DEVICE_PATH_MESSAGING_PC_ANSI,

+  DEVICE_PATH_MESSAGING_VT_100,

+  DEVICE_PATH_MESSAGING_VT_100_PLUS,

+  DEVICE_PATH_MESSAGING_VT_UTF8

+};

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FE.vfr b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FE.vfr
new file mode 100644
index 0000000..998a4a6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FE.vfr
@@ -0,0 +1,138 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   FE.vfr 

+// 

+// Abstract:

+// 

+//   File Explorer Formset

+// 

+// Revision History: 

+// 

+// --*/

+

+#include "BdsStrDefs.h" 

+#include "formguid.h"

+

+#pragma pack(1)

+typedef struct {

+  UINT16                    DescriptionData[75];

+  UINT16                    OptionalData[127];

+  UINT8                     Active;

+  UINT8                     ForceReconnect;  

+} FILE_EXPLORER_NV_DATA;

+#pragma pack()

+

+#define FORM_FILE_EXPLORER_ID                 0x001E

+#define FORM_BOOT_ADD_DESCRIPTION_ID          0x001F

+#define FORM_DRIVER_ADD_FILE_DESCRIPTION_ID   0x0020

+#define KEY_VALUE_SAVE_AND_EXIT               0x0090

+#define KEY_VALUE_NO_SAVE_AND_EXIT            0x0091

+

+

+

+formset 

+  guid = FILE_EXPLORE_FORMSET_GUID,

+  title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE),

+  help = STRING_TOKEN(STR_NULL_STRING),

+  class = 0,

+  subclass = 0,

+

+  form formid = FORM_FILE_EXPLORER_ID,

+       title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE);

+

+       label FORM_FILE_EXPLORER_ID;

+  endform;

+  

+  form formid = FORM_BOOT_ADD_DESCRIPTION_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_ADD_DESC_TITLE);

+       

+       label FORM_BOOT_ADD_DESCRIPTION_ID;

+

+       subtitle  text = STRING_TOKEN(STR_NULL_STRING);

+       

+       string    varid    = FILE_EXPLORER_NV_DATA.DescriptionData,

+                 prompt   = STRING_TOKEN(STR_LOAD_OPTION_DESC),

+                 help     = STRING_TOKEN(STR_NULL_STRING),

+                 minsize  = 6,

+                 maxsize  = 75,

+       endstring;

+

+       string    varid    = FILE_EXPLORER_NV_DATA.OptionalData,

+       		prompt   = STRING_TOKEN(STR_OPTIONAL_DATA),

+       		help     = STRING_TOKEN(STR_NULL_STRING),

+       		minsize  = 0,

+       		maxsize  = 120,

+       endstring;

+

+       text 

+         help   = STRING_TOKEN(STR_SAVE_AND_EXIT),  

+         text   = STRING_TOKEN(STR_SAVE_AND_EXIT), 

+         text   = STRING_TOKEN(STR_NULL_STRING),

+         flags  = INTERACTIVE | NV_ACCESS,

+         key    = KEY_VALUE_SAVE_AND_EXIT;

+             

+       text 

+         help   = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),  

+         text   = STRING_TOKEN(STR_NO_SAVE_AND_EXIT), 

+         text   = STRING_TOKEN(STR_NULL_STRING),

+         flags  = INTERACTIVE | NV_ACCESS,

+         key    = KEY_VALUE_NO_SAVE_AND_EXIT;

+    

+  endform;

+

+  form formid = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_ADD_DESC_TITLE);

+       

+       label FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;

+       

+       subtitle  text = STRING_TOKEN(STR_NULL_STRING);

+

+       string    varid    = FILE_EXPLORER_NV_DATA.DescriptionData,

+                 prompt   = STRING_TOKEN(STR_LOAD_OPTION_DESC),

+                 help     = STRING_TOKEN(STR_NULL_STRING),

+                 minsize  = 6,

+                 maxsize  = 75,

+       endstring;

+

+       string    varid    = FILE_EXPLORER_NV_DATA.OptionalData,

+                 prompt   = STRING_TOKEN(STR_OPTIONAL_DATA),

+                 help     = STRING_TOKEN(STR_NULL_STRING),

+                 minsize  = 0,

+                 maxsize  = 120,

+       endstring; 

+       

+       checkbox varid    = FILE_EXPLORER_NV_DATA.ForceReconnect,

+               prompt   = STRING_TOKEN(STR_LOAD_OPTION_FORCE_RECON),

+               help     = STRING_TOKEN(STR_LOAD_OPTION_FORCE_RECON),  

+               flags    = 1,

+               key      = 0,

+       endcheckbox;

+

+       text 

+         help   = STRING_TOKEN(STR_SAVE_AND_EXIT),  

+         text   = STRING_TOKEN(STR_SAVE_AND_EXIT), 

+         text   = STRING_TOKEN(STR_NULL_STRING),

+         flags  = INTERACTIVE | NV_ACCESS,

+         key    = KEY_VALUE_SAVE_AND_EXIT;

+      

+       text 

+         help   = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),  

+         text   = STRING_TOKEN(STR_NO_SAVE_AND_EXIT), 

+         text   = STRING_TOKEN(STR_NULL_STRING),

+         flags  = INTERACTIVE | NV_ACCESS,

+         key    = KEY_VALUE_NO_SAVE_AND_EXIT;

+               

+  endform;

+  

+endformset;
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c
new file mode 100644
index 0000000..0c8c74c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c
@@ -0,0 +1,335 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FileExplorer.c

+    

+AgBStract:

+

+  File explorer related functions.

+

+--*/

+

+#include "Generic/Bds.h"

+#include "bootmaint.h"

+#include "BdsPlatform.h"

+

+VOID

+UpdateFileExplorePage (

+  IN BMM_CALLBACK_DATA            *CallbackData,

+  BM_MENU_OPTION                  *MenuOption

+  )

+/*++

+Routine Description:

+  Update the File Explore page.

+

+Arguments:

+  MenuOption      - Pointer to menu options to display.

+

+Returns:

+  None.

+

+--*/

+{

+  UINT8           *Location;

+  UINTN           Index;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_FILE_CONTEXT *NewFileContext;

+  FORM_ID         FormId;

+

+  NewMenuEntry    = NULL;

+  NewFileContext  = NULL;

+  FormId          = 0;

+

+  //

+  // Clean up file explore page.

+  //

+  RefreshUpdateData (FALSE, 0, FALSE, 0, 0xff);

+

+  //

+  // Remove all op-codes from dynamic page

+  //

+  CallbackData->Hii->UpdateForm (

+                      CallbackData->Hii,

+                      CallbackData->FeHiiHandle,

+                      FORM_FILE_EXPLORER_ID,

+                      FALSE,

+                      UpdateData

+                      );

+

+  RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 0);

+

+  Location = (UINT8 *) &UpdateData->Data;

+

+  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {

+    NewMenuEntry    = BOpt_GetMenuEntry (MenuOption, Index);

+    NewFileContext  = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;

+

+    if (NewFileContext->IsBootLegacy) {

+      continue;

+    }

+

+    if ((NewFileContext->IsDir) || (BOOT_FROM_FILE_STATE == CallbackData->FeCurrentState)) {

+      //

+      // Create Text opcode for directory, also create Text opcode for file in BOOT_FROM_FILE_STATE.

+      //

+      CreateTextOpCode (

+        NewMenuEntry->DisplayStringToken,

+        STR_NULL_STRING,

+        STR_NULL_STRING,

+        EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+        (UINT16) (FILE_OPTION_OFFSET + Index),

+        Location

+        );

+    } else {

+      //

+      // Create Goto opcode for file in ADD_BOOT_OPTION_STATE or ADD_DRIVER_OPTION_STATE.

+      //

+      if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {

+        FormId = FORM_BOOT_ADD_DESCRIPTION_ID;

+      } else if (ADD_DRIVER_OPTION_STATE == CallbackData->FeCurrentState) {

+        FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;

+      }

+

+      CreateGotoOpCode (

+        FormId,

+        NewMenuEntry->DisplayStringToken,

+        STRING_TOKEN (STR_NULL_STRING),

+        EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+        (UINT16) (FILE_OPTION_OFFSET + Index),

+        Location

+        );

+    }

+

+    UpdateData->DataCount++;

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  }

+

+  CallbackData->Hii->UpdateForm (

+                      CallbackData->Hii,

+                      CallbackData->FeHiiHandle,

+                      FORM_FILE_EXPLORER_ID,

+                      TRUE,

+                      UpdateData

+                      );

+}

+

+BOOLEAN

+UpdateFileExplorer (

+  IN BMM_CALLBACK_DATA            *CallbackData,

+  IN UINT16                       KeyValue

+  )

+/*++

+

+Routine Description:

+  Update the file explower page with the refershed file system.

+

+Arguments:

+  CallbackData  -   BMM context data

+  KeyValue        - Key value to identify the type of data to expect.

+

+Returns:

+  TRUE          - Inform the caller to create a callback packet to exit file explorer.

+  FALSE         - Indicate that there is no need to exit file explorer.

+

+--*/

+{

+  UINT16          FileOptionMask;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_FILE_CONTEXT *NewFileContext;

+  FORM_ID         FormId;

+  BOOLEAN         ExitFileExplorer;

+

+  NewMenuEntry      = NULL;

+  NewFileContext    = NULL;

+  ExitFileExplorer  = FALSE;

+

+  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue);

+

+  if (UNKNOWN_CONTEXT == CallbackData->FeDisplayContext) {

+    //

+    // First in, display file system.

+    //

+    BOpt_FreeMenu (&FsOptionMenu);

+    BOpt_FindFileSystem (CallbackData);

+    CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);

+

+    UpdateFileExplorePage (CallbackData, &FsOptionMenu);

+

+    CallbackData->FeDisplayContext = FILE_SYSTEM;

+  } else {

+    if (FILE_SYSTEM == CallbackData->FeDisplayContext) {

+      NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);

+    } else if (DIRECTORY == CallbackData->FeDisplayContext) {

+      NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);

+    }

+

+    CallbackData->FeDisplayContext  = DIRECTORY;

+

+    NewFileContext                  = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;

+

+    if (NewFileContext->IsDir ) {

+      RemoveEntryList (&NewMenuEntry->Link);

+      BOpt_FreeMenu (&DirectoryMenu);

+      BOpt_FindFiles (CallbackData, NewMenuEntry);

+      CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);

+      BOpt_DestroyMenuEntry (NewMenuEntry);

+

+      UpdateFileExplorePage (CallbackData, &DirectoryMenu);

+

+    } else {

+      switch (CallbackData->FeCurrentState) {

+      case BOOT_FROM_FILE_STATE:

+        //

+        // Here boot from file

+        //

+        BootThisFile (NewFileContext);

+        ExitFileExplorer = TRUE;

+        break;

+

+      case ADD_BOOT_OPTION_STATE:

+      case ADD_DRIVER_OPTION_STATE:

+        if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {

+          FormId = FORM_BOOT_ADD_DESCRIPTION_ID;

+        } else {

+          FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;

+        }

+

+        CallbackData->MenuEntry = NewMenuEntry;

+        CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;

+

+        //

+        // Clean up file explore page.

+        //

+        RefreshUpdateData (FALSE, 0, FALSE, 0, 1);

+

+        //

+        // Remove the Subtitle op-code.

+        //

+        CallbackData->Hii->UpdateForm (

+                            CallbackData->Hii,

+                            CallbackData->FeHiiHandle,

+                            FormId,

+                            FALSE,

+                            UpdateData

+                            );

+

+        //

+        // Create Subtitle op-code for the display string of the option.

+        //

+        RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 1);

+

+        CreateSubTitleOpCode (

+          NewMenuEntry->DisplayStringToken,

+          &UpdateData->Data

+          );

+

+        CallbackData->Hii->UpdateForm (

+                            CallbackData->Hii,

+                            CallbackData->FeHiiHandle,

+                            FormId,

+                            TRUE,

+                            UpdateData

+                            );

+        break;

+

+      default:

+        break;

+      }

+    }

+  }

+

+  return ExitFileExplorer;

+}

+

+EFI_STATUS

+EFIAPI

+FileExplorerCallback (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *Data,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+/*++

+Routine Description:

+  Callback Function for file exploration and file interaction.

+

+Arguments:

+  This            - File explorer callback protocol pointer.     

+  KeyValue        - Key value to identify the type of data to expect.

+  Data            - A pointer to the data being sent to the original exporting driver.

+  Packet          - A pointer to a packet of information which a driver passes back to the browser.

+

+Returns:

+  EFI_SUCCESS     - Callback ended successfully.

+  Others          - Contain some errors.

+  

+--*/

+{

+  BMM_CALLBACK_DATA     *Private;

+  FILE_EXPLORER_NV_DATA *NvRamMap;

+  EFI_STATUS            Status;

+

+  Status                          = EFI_SUCCESS;

+  Private                         = FE_CALLBACK_DATA_FROM_THIS (This);

+  UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->FeCallbackHandle;

+  NvRamMap                        = (FILE_EXPLORER_NV_DATA *) Data->NvRamMap;

+

+  if (KEY_VALUE_SAVE_AND_EXIT == KeyValue) {

+    //

+    // Apply changes and exit formset.

+    //

+    if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {

+      Status = Var_UpdateBootOption (Private, NvRamMap);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      BOpt_GetBootOptions (Private);

+      CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);

+    } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {

+      Status = Var_UpdateDriverOption (

+                Private,

+                Private->FeHiiHandle,

+                NvRamMap->DescriptionData,

+                NvRamMap->OptionalData,

+                NvRamMap->ForceReconnect

+                );

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      BOpt_GetDriverOptions (Private);

+      CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);

+    }

+

+    CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);

+  } else if (KEY_VALUE_NO_SAVE_AND_EXIT == KeyValue) {

+    //

+    // Discard changes and exit formset.

+    //

+    NvRamMap->OptionalData[0]     = 0x0000;

+    NvRamMap->DescriptionData[0]  = 0x0000;

+    CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);

+  } else if (KeyValue < FILE_OPTION_OFFSET) {

+    //

+    // Exit File Explorer formset.

+    //

+    CreateCallbackPacket (Packet, EXIT_REQUIRED);

+  } else {

+    if (UpdateFileExplorer (Private, KeyValue)) {

+      CreateCallbackPacket (Packet, EXIT_REQUIRED);

+    }

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FormGuid.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FormGuid.h
new file mode 100644
index 0000000..3d4cd4a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FormGuid.h
@@ -0,0 +1,32 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation

+// All rights reserved. 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.

+//

+// Module Name:

+//

+//   formguid.h

+//

+// Abstract:

+//

+//   Formset guids for Boot Maintenance Manager

+//

+// Revision History:

+//

+// --*/

+//

+#define MAIN_FORMSET_GUID \

+  { \

+    0x642237c7, 0x35d4, 0x472d, { 0x83, 0x65, 0x12, 0xe0, 0xcc, 0xf2, 0x7a, 0x22 } \

+  }

+

+#define FILE_EXPLORE_FORMSET_GUID \

+  { \

+    0x1f2d63e1, 0xfebd, 0x4dc7, { 0x9c, 0xc5, 0xba, 0x2b, 0x1c, 0xef, 0x9c, 0x5b } \

+  }

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/UpdatePage.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/UpdatePage.c
new file mode 100644
index 0000000..65ee289
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/UpdatePage.c
@@ -0,0 +1,1275 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  UpdatePage.c

+    

+AgBStract:

+

+  Dynamically Update the pages

+

+--*/

+

+#include "Generic/Bds.h"

+#include "bootmaint.h"

+#include "BdsPlatform.h"

+

+EFI_GUID gTerminalDriverGuid = {

+  0x10634d8e, 0x1c05, 0x46cb, 0xbb, 0xc, 0x5a, 0xfd, 0xc8, 0x29, 0xa8, 0xc8

+};

+

+VOID

+RefreshUpdateData (

+  IN BOOLEAN                      FormSetUpdate,

+  IN EFI_PHYSICAL_ADDRESS         FormCallbackHandle,

+  IN BOOLEAN                      FormUpdate,

+  IN STRING_REF                   FormTitle,

+  IN UINT16                       DataCount

+  )

+/*++

+Routine Description:

+  Refresh the global UpdateData structure.

+

+Arguments:

+  FormSetUpdate      - If TRUE, next variable is significant

+  FormCallbackHandle - If not 0, will update FormSet with this info

+  FormUpdate         - If TRUE, next variable is significant

+  FormTitle          - If not 0, will update Form with this info

+  DataCount          - The number of Data entries in this structure

+

+Returns:

+  None.

+--*/

+{

+  UpdateData->FormSetUpdate = FormSetUpdate;

+  if (FormSetUpdate) {

+    ASSERT (0 != FormCallbackHandle);

+    UpdateData->FormCallbackHandle = FormCallbackHandle;

+  }

+

+  UpdateData->FormUpdate  = FALSE;

+  UpdateData->FormTitle   = FormTitle;

+  UpdateData->DataCount   = DataCount;

+}

+

+VOID

+UpdatePageStart (

+  IN BMM_CALLBACK_DATA                *CallbackData,

+  IN OUT UINT8                        **CurrentLocation

+  )

+{

+  RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->BmmCallbackHandle, FALSE, 0, 0);

+

+  if (!(CallbackData->BmmAskSaveOrNot)) {

+    //

+    // Add a "Go back to main page" tag in front of the form when there are no

+    // "Apply changes" and "Discard changes" tags in the end of the form.

+    //

+    CreateGotoOpCode (

+      FORM_MAIN_ID,

+      STRING_TOKEN (STR_FORM_GOTO_MAIN),

+      STRING_TOKEN (STR_FORM_GOTO_MAIN),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      FORM_MAIN_ID,

+      *CurrentLocation

+      );

+

+    UpdateData->DataCount++;

+

+    *CurrentLocation = *CurrentLocation + ((EFI_IFR_OP_HEADER *) (*CurrentLocation))->Length;

+  }

+

+}

+

+VOID

+UpdatePageEnd (

+  IN BMM_CALLBACK_DATA                *CallbackData,

+  IN UINT8                            *CurrentLocation

+  )

+{

+  //

+  // Create the "Apply changes" and "Discard changes" tags.

+  //

+  if (CallbackData->BmmAskSaveOrNot) {

+    CreateGotoOpCode (

+      FORM_MAIN_ID,

+      STRING_TOKEN (STR_SAVE_AND_EXIT),

+      STRING_TOKEN (STR_NULL_STRING),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      KEY_VALUE_SAVE_AND_EXIT,

+      CurrentLocation

+      );

+

+    UpdateData->DataCount++;

+

+    CurrentLocation = CurrentLocation + ((EFI_IFR_OP_HEADER *) CurrentLocation)->Length;

+

+    CreateGotoOpCode (

+      FORM_MAIN_ID,

+      STRING_TOKEN (STR_NO_SAVE_AND_EXIT),

+      STRING_TOKEN (STR_NULL_STRING),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      KEY_VALUE_NO_SAVE_AND_EXIT,

+      CurrentLocation

+      );

+

+    UpdateData->DataCount++;

+  }

+  //

+  // Ensure user can return to the main page.

+  //

+  if (0 == UpdateData->DataCount) {

+    CreateGotoOpCode (

+      FORM_MAIN_ID,

+      STRING_TOKEN (STR_NO_SAVE_AND_EXIT),

+      STRING_TOKEN (STR_NULL_STRING),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      KEY_VALUE_NO_SAVE_AND_EXIT,

+      CurrentLocation

+      );

+

+    UpdateData->DataCount++;

+  }

+

+  CallbackData->Hii->UpdateForm (

+                      CallbackData->Hii,

+                      CallbackData->BmmHiiHandle,

+                      CallbackData->BmmCurrentPageId,

+                      TRUE,

+                      UpdateData

+                      );

+}

+

+VOID

+CleanUpPage (

+  IN EFI_FORM_LABEL                   LabelId,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  RefreshUpdateData (FALSE, 0, FALSE, 0, 0xff);

+

+  //

+  // Remove all op-codes from dynamic page

+  //

+  CallbackData->Hii->UpdateForm (

+                      CallbackData->Hii,

+                      CallbackData->BmmHiiHandle,

+                      LabelId,

+                      FALSE,

+                      UpdateData

+                      );

+}

+

+EFI_STATUS

+BootThisFile (

+  IN BM_FILE_CONTEXT                   *FileContext

+  )

+{

+  EFI_STATUS        Status;

+  UINTN             ExitDataSize;

+  CHAR16            *ExitData;

+  BDS_COMMON_OPTION *Option;

+

+  Status                  = gBS->AllocatePool (EfiBootServicesData, sizeof (BDS_COMMON_OPTION), &Option);

+  Option->Description     = FileContext->FileName;

+  Option->DevicePath      = FileContext->DevicePath;

+  Option->LoadOptionsSize = 0;

+  Option->LoadOptions     = NULL;

+

+  //

+  // Since current no boot from removable media directly is allowed */

+  //

+  gST->ConOut->ClearScreen (gST->ConOut);

+

+  ExitDataSize  = 0;

+

+  Status        = BdsLibBootViaBootOption (Option, Option->DevicePath, &ExitDataSize, &ExitData);

+

+  return Status;

+

+}

+

+VOID

+UpdateConCOMPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        Index;

+  UINT8         *Location;

+  EFI_STATUS    Status;

+  VOID        	*Interface;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = FALSE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  Status = EfiLibLocateProtocol (&gTerminalDriverGuid, &Interface);

+  if (!EFI_ERROR (Status)) {

+    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+      NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);

+ 

+      CreateGotoOpCode (

+        FORM_CON_COM_SETUP_ID,

+        NewMenuEntry->DisplayStringToken,

+        STRING_TOKEN (STR_NULL_STRING),

+        EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+        (UINT16) (TERMINAL_OPTION_OFFSET + Index),

+        Location

+        );

+      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+      UpdateData->DataCount++;

+    }

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateBootDelPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+  UINT16          Index;

+  UINT8           *Location;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);

+

+  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+    NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);

+    NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+    if (NewLoadContext->IsLegacy) {

+      continue;

+    }

+

+    NewLoadContext->Deleted = FALSE;

+    CallbackData->BmmFakeNvData->BootOptionDel[Index] = 0x00;

+

+    CreateCheckBoxOpCode (

+      (UINT16) (BOOT_OPTION_DEL_QUESTION_ID + Index),

+      (UINT8) 1,

+      NewMenuEntry->DisplayStringToken,

+      NewMenuEntry->HelpStringToken,

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      (UINT16) BOOT_OPTION_DEL_QUESTION_ID,

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+    UpdateData->DataCount++;

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateDrvAddHandlePage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        Index;

+  UINT8         *Location;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = FALSE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);

+

+    CreateGotoOpCode (

+      FORM_DRV_ADD_HANDLE_DESC_ID,

+      NewMenuEntry->DisplayStringToken,

+      STRING_TOKEN (STR_NULL_STRING),

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      (UINT16) (HANDLE_OPTION_OFFSET + Index),

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+    UpdateData->DataCount++;

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateDrvDelPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+  UINT16          Index;

+  UINT8           *Location;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &DriverOptionMenu);

+

+  for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {

+    NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);

+

+    NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+    NewLoadContext->Deleted = FALSE;

+    CallbackData->BmmFakeNvData->DriverOptionDel[Index] = 0x00;

+

+    CreateCheckBoxOpCode (

+      (UINT16) (DRIVER_OPTION_DEL_QUESTION_ID + Index),

+      (UINT8) 1,

+      NewMenuEntry->DisplayStringToken,

+      NewMenuEntry->HelpStringToken,

+      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+      (UINT16) DRIVER_OPTION_DEL_QUESTION_ID,

+      Location

+      );

+

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+    UpdateData->DataCount++;

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateDriverAddHandleDescPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT8         *Location;

+

+  Location  = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmFakeNvData->DriverAddActive          = 0x01;

+  CallbackData->BmmFakeNvData->DriverAddForceReconnect  = 0x00;

+  CallbackData->BmmAskSaveOrNot                         = TRUE;

+  NewMenuEntry = CallbackData->MenuEntry;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  UpdateData->DataCount += (UINT16) 4;

+

+  CreateSubTitleOpCode (

+    NewMenuEntry->DisplayStringToken,

+    Location

+    );

+

+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+  CreateStringOpCode (

+    DRV_ADD_HANDLE_DESC_QUESTION_ID,

+    (UINT8) 150,

+    STRING_TOKEN (STR_LOAD_OPTION_DESC),

+    STRING_TOKEN (STR_NULL_STRING),

+    6,

+    75,

+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+    KEY_VALUE_DRIVER_ADD_DESC_DATA,

+    Location

+    );

+

+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+  CreateCheckBoxOpCode (

+    DRV_ADD_RECON_QUESTION_ID,

+    (UINT8) 1,

+    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),

+    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),

+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+    DRV_ADD_RECON_QUESTION_ID,

+    Location

+    );

+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+  CreateStringOpCode (

+    DRIVER_ADD_OPTION_QUESTION_ID,

+    (UINT8) 150,

+    STRING_TOKEN (STR_OPTIONAL_DATA),

+    STRING_TOKEN (STR_NULL_STRING),

+    6,

+    75,

+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+    KEY_VALUE_DRIVER_ADD_OPT_DATA,

+    Location

+    );

+

+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateConsolePage (

+  IN UINT16                           UpdatePageId,

+  IN BM_MENU_OPTION                   *ConsoleMenu,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY       *NewMenuEntry;

+  BM_CONSOLE_CONTEXT  *NewConsoleContext;

+  BM_TERMINAL_CONTEXT *NewTerminalContext;

+  UINT16              Index;

+  UINT16              Index2;

+  UINT8               *Location;

+  UINT8               CheckFlags;

+  EFI_STATUS          Status;

+  VOID        	      *Interface;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {

+    NewMenuEntry      = BOpt_GetMenuEntry (ConsoleMenu, Index);

+    NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;

+    CheckFlags        = EFI_IFR_FLAG_INTERACTIVE;

+    if (NewConsoleContext->IsActive) {

+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+      CallbackData->BmmFakeNvData->ConsoleCheck[Index] = TRUE;

+    } else {

+      CallbackData->BmmFakeNvData->ConsoleCheck[Index] = FALSE;

+    }

+

+    CreateCheckBoxOpCode (

+      (UINT16) (CON_DEVICE_QUESTION_ID + Index),

+      (UINT8) 1,

+      NewMenuEntry->DisplayStringToken,

+      NewMenuEntry->HelpStringToken,

+      CheckFlags,

+      (UINT16) (CONSOLE_OPTION_OFFSET + Index),

+      Location

+      );

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+    UpdateData->DataCount++;

+  }

+

+  Status = EfiLibLocateProtocol (&gTerminalDriverGuid, &Interface);

+  if (!EFI_ERROR (Status)) {

+    for (Index2 = 0; Index2 < TerminalMenu.MenuNumber; Index2++) {

+      CheckFlags          = EFI_IFR_FLAG_INTERACTIVE;

+      NewMenuEntry        = BOpt_GetMenuEntry (&TerminalMenu, Index2);

+      NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+

+      if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||

+          (NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||

+          (NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))

+          ) {

+        CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+        CallbackData->BmmFakeNvData->ConsoleCheck[Index] = TRUE;

+      } else {

+        CallbackData->BmmFakeNvData->ConsoleCheck[Index] = FALSE;

+      }

+

+      CreateCheckBoxOpCode (

+        (UINT16) (CON_DEVICE_QUESTION_ID + Index),

+        (UINT8) 1,

+        NewMenuEntry->DisplayStringToken,

+        NewMenuEntry->HelpStringToken,

+        CheckFlags,

+        (UINT16) (CONSOLE_OPTION_OFFSET + Index),

+        Location

+        );

+      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+      UpdateData->DataCount++;

+      Index++;

+    }

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateOrderPage (

+  IN UINT16                           UpdatePageId,

+  IN BM_MENU_OPTION                   *OptionMenu,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        Index;

+  UINT8         *Location;

+  IFR_OPTION    *IfrOptionList;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);

+

+  ZeroMem (CallbackData->BmmFakeNvData->OptionOrder, 100);

+

+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * OptionMenu->MenuNumber);

+  if (NULL == IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);

+    IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken;

+    IfrOptionList[Index].Value = (UINT16) (NewMenuEntry->OptionNumber + 1);

+    IfrOptionList[Index].OptionString = NULL;

+    CallbackData->BmmFakeNvData->OptionOrder[Index] = (UINT8) (IfrOptionList[Index].Value);

+  }

+

+  if (OptionMenu->MenuNumber > 0) {

+    CreateOrderedListOpCode (

+      (UINT16) OPTION_ORDER_QUESTION_ID,

+      (UINT8) 100,

+      STRING_TOKEN (STR_CHANGE_ORDER),

+      STRING_TOKEN (STR_CHANGE_ORDER),

+      IfrOptionList,

+      OptionMenu->MenuNumber,

+      Location

+      );

+

+    for (Index = 0; Index < OptionMenu->MenuNumber + 2; Index++) {

+      Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+    }

+

+    UpdateData->DataCount = (UINT16) (UpdateData->DataCount + OptionMenu->MenuNumber + 2);

+  }

+

+  SafeFreePool (IfrOptionList);

+

+  UpdatePageEnd (CallbackData, Location);

+

+  CopyMem (

+    CallbackData->BmmOldFakeNVData.OptionOrder,

+    CallbackData->BmmFakeNvData->OptionOrder,

+    100

+    );

+}

+

+VOID

+UpdateBootNextPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  UINT8           *Location;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+  IFR_OPTION      *IfrOptionList;

+  UINTN           NumberOfOptions;

+  UINT16          Index;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  IfrOptionList                 = NULL;

+  NumberOfOptions               = BootOptionMenu.MenuNumber;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);

+

+  if (NumberOfOptions > 0) {

+    UpdateData->DataCount = (UINT8) (UpdateData->DataCount + NumberOfOptions);

+    IfrOptionList = AllocateZeroPool ((NumberOfOptions + 1) * sizeof (IFR_OPTION));

+

+    ASSERT (IfrOptionList);

+

+    CallbackData->BmmFakeNvData->BootNext = (UINT16) (BootOptionMenu.MenuNumber);

+

+    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+      NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);

+      NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+      if (NewLoadContext->IsBootNext) {

+        IfrOptionList[Index].Flags            = EFI_IFR_FLAG_DEFAULT | EFI_IFR_FLAG_INTERACTIVE;

+        CallbackData->BmmFakeNvData->BootNext = Index;

+      } else {

+        IfrOptionList[Index].Flags = EFI_IFR_FLAG_INTERACTIVE;

+      }

+

+      IfrOptionList[Index].Key          = (UINT16) KEY_VALUE_MAIN_BOOT_NEXT;

+      IfrOptionList[Index].Value        = Index;

+      IfrOptionList[Index].StringToken  = NewMenuEntry->DisplayStringToken;

+      IfrOptionList[Index].OptionString = NULL;

+    }

+

+    IfrOptionList[Index].Key          = (UINT16) KEY_VALUE_MAIN_BOOT_NEXT;

+    IfrOptionList[Index].Value        = Index;

+    IfrOptionList[Index].StringToken  = STRING_TOKEN (STR_NONE);

+    IfrOptionList[Index].Flags        = EFI_IFR_FLAG_INTERACTIVE;

+    if (CallbackData->BmmFakeNvData->BootNext == Index) {

+      IfrOptionList[Index].Flags |= EFI_IFR_FLAG_DEFAULT;

+    }

+

+    IfrOptionList[Index].OptionString = NULL;

+

+    CreateOneOfOpCode (

+      (UINT16) BOOT_NEXT_QUESTION_ID,

+      (UINT8) 2,

+      STRING_TOKEN (STR_BOOT_NEXT),

+      STRING_TOKEN (STR_BOOT_NEXT_HELP),

+      IfrOptionList,

+      (UINTN) (NumberOfOptions + 1),

+      Location

+      );

+    Location  = Location + (NumberOfOptions + 2) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+    Location  = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+    UpdateData->DataCount += 3;

+    SafeFreePool (IfrOptionList);

+    IfrOptionList = NULL;

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateTimeOutPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  UINT8   *Location;

+  UINT16  BootTimeOut;

+

+  Location                      = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  BootTimeOut = BdsLibGetTimeout ();

+

+  CreateNumericOpCode (

+    (UINT16) BOOT_TIME_OUT_QUESTION_ID,

+    (UINT8) 2,

+    STRING_TOKEN (STR_NUM_AUTO_BOOT),

+    STRING_TOKEN (STR_HLP_AUTO_BOOT),

+    0,

+    65535,

+    0,

+    10,

+    0,

+    0,

+    Location

+    );

+

+  CallbackData->BmmFakeNvData->BootTimeOut = (UINT16) BootTimeOut;

+  UpdateData->DataCount++;

+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdateTerminalPage (

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  UINT16              Index;

+  UINT8               *Location;

+  UINT8               CheckFlags;

+  IFR_OPTION          *IfrOptionList;

+  BM_MENU_ENTRY       *NewMenuEntry;

+  BM_TERMINAL_CONTEXT *NewTerminalContext;

+

+  ZeroMem (UpdateData, UPDATE_DATA_SIZE);

+  Location = (UINT8 *) &UpdateData->Data;

+  UpdatePageStart (CallbackData, &Location);

+

+  NewMenuEntry = BOpt_GetMenuEntry (

+                  &TerminalMenu,

+                  CallbackData->CurrentTerminal

+                  );

+

+  if (!NewMenuEntry) {

+    return ;

+  }

+

+  NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+

+  IfrOptionList       = AllocateZeroPool (sizeof (IFR_OPTION) * 19);

+  if (!IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < 19; Index++) {

+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;

+    if (NewTerminalContext->BaudRate == (UINT64) (BaudRateList[Index].Value)) {

+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+      NewTerminalContext->BaudRateIndex         = (UINT8) Index;

+      CallbackData->BmmFakeNvData->COMBaudRate  = NewTerminalContext->BaudRateIndex;

+    }

+

+    IfrOptionList[Index].Flags        = CheckFlags;

+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_BAUD_RATE;

+    IfrOptionList[Index].StringToken  = BaudRateList[Index].StringToken;

+    IfrOptionList[Index].Value        = Index;

+  }

+

+  CreateOneOfOpCode (

+    (UINT16) COM_BAUD_RATE_QUESTION_ID,

+    (UINT8) 1,

+    STRING_TOKEN (STR_COM_BAUD_RATE),

+    STRING_TOKEN (STR_COM_BAUD_RATE),

+    IfrOptionList,

+    19,

+    Location

+    );

+

+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);

+  UpdateData->DataCount += 2;

+

+  SafeFreePool (IfrOptionList);

+

+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 4);

+  if (!IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < 4; Index++) {

+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;

+

+    if (NewTerminalContext->DataBits == DataBitsList[Index].Value) {

+      NewTerminalContext->DataBitsIndex         = (UINT8) Index;

+      CallbackData->BmmFakeNvData->COMDataRate  = NewTerminalContext->DataBitsIndex;

+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+    }

+

+    IfrOptionList[Index].Flags        = CheckFlags;

+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_DATA_BITS;

+    IfrOptionList[Index].StringToken  = DataBitsList[Index].StringToken;

+    IfrOptionList[Index].Value        = Index;

+  }

+

+  CreateOneOfOpCode (

+    (UINT16) COM_DATA_RATE_QUESTION_ID,

+    (UINT8) 1,

+    STRING_TOKEN (STR_COM_DATA_BITS),

+    STRING_TOKEN (STR_COM_DATA_BITS),

+    IfrOptionList,

+    4,

+    Location

+    );

+

+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);

+  UpdateData->DataCount += 2;

+

+  SafeFreePool (IfrOptionList);

+

+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 5);

+  if (!IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < 5; Index++) {

+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;

+    if (NewTerminalContext->Parity == ParityList[Index].Value) {

+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+      NewTerminalContext->ParityIndex         = (UINT8) Index;

+      CallbackData->BmmFakeNvData->COMParity  = NewTerminalContext->ParityIndex;

+    }

+

+    IfrOptionList[Index].Flags        = CheckFlags;

+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_PARITY;

+    IfrOptionList[Index].StringToken  = ParityList[Index].StringToken;

+    IfrOptionList[Index].Value        = Index;

+  }

+

+  CreateOneOfOpCode (

+    (UINT16) COM_PARITY_QUESTION_ID,

+    (UINT8) 1,

+    STRING_TOKEN (STR_COM_PARITY),

+    STRING_TOKEN (STR_COM_PARITY),

+    IfrOptionList,

+    5,

+    Location

+    );

+

+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);

+  UpdateData->DataCount += 2;

+

+  SafeFreePool (IfrOptionList);

+

+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 3);

+  if (!IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < 3; Index++) {

+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;

+    if (NewTerminalContext->StopBits == StopBitsList[Index].Value) {

+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+      NewTerminalContext->StopBitsIndex         = (UINT8) Index;

+      CallbackData->BmmFakeNvData->COMStopBits  = NewTerminalContext->StopBitsIndex;

+    }

+

+    IfrOptionList[Index].Flags        = CheckFlags;

+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_STOP_BITS;

+    IfrOptionList[Index].StringToken  = StopBitsList[Index].StringToken;

+    IfrOptionList[Index].Value        = Index;

+  }

+

+  CreateOneOfOpCode (

+    (UINT16) COM_STOP_BITS_QUESTION_ID,

+    (UINT8) 1,

+    STRING_TOKEN (STR_COM_STOP_BITS),

+    STRING_TOKEN (STR_COM_STOP_BITS),

+    IfrOptionList,

+    3,

+    Location

+    );

+

+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);

+  UpdateData->DataCount += 2;

+

+  SafeFreePool (IfrOptionList);

+

+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 4);

+  if (!IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < 4; Index++) {

+    CheckFlags = EFI_IFR_FLAG_INTERACTIVE;

+    if (NewTerminalContext->TerminalType == Index) {

+      CheckFlags |= EFI_IFR_FLAG_DEFAULT;

+      CallbackData->BmmFakeNvData->COMTerminalType = NewTerminalContext->TerminalType;

+    }

+

+    IfrOptionList[Index].Flags        = CheckFlags;

+    IfrOptionList[Index].Key          = KEY_VALUE_COM_SET_TERMI_TYPE;

+    IfrOptionList[Index].StringToken  = (STRING_REF) TerminalType[Index];

+    IfrOptionList[Index].Value        = Index;

+  }

+

+  CreateOneOfOpCode (

+    (UINT16) COM_TERMINAL_QUESTION_ID,

+    (UINT8) 1,

+    STRING_TOKEN (STR_COM_TERMI_TYPE),

+    STRING_TOKEN (STR_COM_TERMI_TYPE),

+    IfrOptionList,

+    4,

+    Location

+    );

+

+  Location              = Location + (Index + 1) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+  Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdateData->DataCount = (UINT8) (UpdateData->DataCount + Index);

+  UpdateData->DataCount += 2;

+

+  SafeFreePool (IfrOptionList);

+

+  CreateGotoOpCode (

+    FORM_MAIN_ID,

+    STRING_TOKEN (STR_SAVE_AND_EXIT),

+    STRING_TOKEN (STR_NULL_STRING),

+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+    KEY_VALUE_SAVE_AND_EXIT,

+    Location

+    );

+

+  Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+  UpdateData->DataCount++;

+

+  CreateGotoOpCode (

+    FORM_MAIN_ID,

+    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),

+    STRING_TOKEN (STR_NULL_STRING),

+    EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,

+    KEY_VALUE_NO_SAVE_AND_EXIT,

+    Location

+    );

+

+  UpdateData->DataCount++;

+

+  CallbackData->Hii->UpdateForm (

+                      CallbackData->Hii,

+                      CallbackData->BmmHiiHandle,

+                      (EFI_FORM_LABEL) FORM_CON_COM_SETUP_ID,

+                      TRUE,

+                      UpdateData

+                      );

+

+}

+

+VOID

+UpdatePageBody (

+  IN UINT16                           UpdatePageId,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  CleanUpPage (UpdatePageId, CallbackData);

+  switch (UpdatePageId) {

+  case FORM_CON_IN_ID:

+    UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);

+    break;

+

+  case FORM_CON_OUT_ID:

+    UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);

+    break;

+

+  case FORM_CON_ERR_ID:

+    UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);

+    break;

+

+  case FORM_BOOT_CHG_ID:

+    UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);

+    break;

+

+  case FORM_DRV_CHG_ID:

+    UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);

+    break;

+

+  default:

+    break;

+  }

+}

+

+VOID *

+GetLegacyBootOptionVar (

+  IN  UINTN                            DeviceType,

+  OUT UINTN                            *OptionIndex,

+  OUT UINTN                            *OptionSize

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  VOID                      *OptionBuffer;

+  UINTN                     OrderSize;

+  UINTN                     Index;

+  UINT32                    Attribute;

+  UINT16                    *OrderBuffer;

+  CHAR16                    StrTemp[100];

+  UINT16                    FilePathSize;

+  CHAR16                    *Description;

+  UINT8                     *Ptr;

+  UINT8                     *OptionalData;

+

+  //

+  // Get Boot Option number from the size of BootOrder

+  //

+  OrderBuffer = BdsLibGetVariableAndSize (

+                  L"BootOrder",

+                  &gEfiGlobalVariableGuid,

+                  &OrderSize

+                  );

+

+  for (Index = 0; Index < OrderSize / sizeof (UINT16); Index++) {

+    UnicodeSPrint (StrTemp, 100, L"Boot%04x", OrderBuffer[Index]);

+    OptionBuffer = BdsLibGetVariableAndSize (

+                    StrTemp,

+                    &gEfiGlobalVariableGuid,

+                    OptionSize

+                    );

+    if (NULL == OptionBuffer) {

+      continue;

+    }

+

+    Ptr       = (UINT8 *) OptionBuffer;

+    Attribute = *(UINT32 *) Ptr;

+    Ptr += sizeof (UINT32);

+

+    FilePathSize = *(UINT16 *) Ptr;

+    Ptr += sizeof (UINT16);

+

+    Description = (CHAR16 *) Ptr;

+    Ptr += StrSize ((CHAR16 *) Ptr);

+

+    //

+    // Now Ptr point to Device Path

+    //

+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;

+    Ptr += FilePathSize;

+

+    //

+    // Now Ptr point to Optional Data

+    //

+    OptionalData = Ptr;

+

+    if ((DeviceType == ((BBS_TABLE *) OptionalData)->DeviceType) &&

+        (BBS_DEVICE_PATH == DevicePath->Type) &&

+        (BBS_BBS_DP == DevicePath->SubType)

+        ) {

+      *OptionIndex = OrderBuffer[Index];

+      SafeFreePool (OrderBuffer);

+      return OptionBuffer;

+    } else {

+      SafeFreePool (OptionBuffer);

+    }

+  }

+

+  SafeFreePool (OrderBuffer);

+  return NULL;

+}

+

+VOID

+UpdateSetLegacyDeviceOrderPage (

+  IN UINT16                           UpdatePageId,

+  IN BMM_CALLBACK_DATA                *CallbackData

+  )

+{

+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;

+  BM_MENU_OPTION              *OptionMenu;

+  BM_MENU_ENTRY               *NewMenuEntry;

+  IFR_OPTION                  *IfrOptionList;

+  STRING_REF                  StrRef;

+  STRING_REF                  StrRefHelp;

+  BBS_TYPE                    BbsType;

+  UINTN                       VarSize;

+  UINTN                       Pos;

+  UINTN                       Bit;

+  UINT16                      Index;

+  UINT16                      Index2;

+  UINT16                      Key;

+  CHAR16                      String[100];

+  CHAR16                      *TypeStr;

+  CHAR16                      *TypeStrHelp;

+  UINT16                      VarDevOrder;

+  UINT8                       *Location;

+  UINT8                       *VarData;

+  UINT8                       *OriginalPtr;

+  UINT8                       *LegacyOrder;

+  UINT8                       *OldData;

+  UINT8                       *DisMap;

+

+  OptionMenu                    = NULL;

+  Key = 0;

+  StrRef = 0;

+  StrRefHelp = 0;

+  TypeStr = NULL;

+  TypeStrHelp = NULL;

+  BbsType = BBS_FLOPPY;

+  LegacyOrder = NULL;

+  OldData = NULL;

+  DisMap = NULL;

+

+  Location = (UINT8 *) &UpdateData->Data;

+  CallbackData->BmmAskSaveOrNot = TRUE;

+

+  UpdatePageStart (CallbackData, &Location);

+

+  DisMap = CallbackData->BmmOldFakeNVData.DisableMap;

+

+  SetMem (DisMap, 32, 0);

+  //

+  // Create oneof option list

+  //

+  switch (UpdatePageId) {

+  case FORM_SET_FD_ORDER_ID:

+    OptionMenu  = (BM_MENU_OPTION *) &LegacyFDMenu;

+    Key         = LEGACY_FD_QUESTION_ID;

+    TypeStr     = StrFloppy;

+    TypeStrHelp = StrFloppyHelp;

+    BbsType     = BBS_FLOPPY;

+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyFD;

+    OldData     = CallbackData->BmmOldFakeNVData.LegacyFD;

+    break;

+

+  case FORM_SET_HD_ORDER_ID:

+    OptionMenu  = (BM_MENU_OPTION *) &LegacyHDMenu;

+    Key         = LEGACY_HD_QUESTION_ID;

+    TypeStr     = StrHardDisk;

+    TypeStrHelp = StrHardDiskHelp;

+    BbsType     = BBS_HARDDISK;

+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyHD;

+    OldData     = CallbackData->BmmOldFakeNVData.LegacyHD;

+    break;

+

+  case FORM_SET_CD_ORDER_ID:

+    OptionMenu  = (BM_MENU_OPTION *) &LegacyCDMenu;

+    Key         = LEGACY_CD_QUESTION_ID;

+    TypeStr     = StrCDROM;

+    TypeStrHelp = StrCDROMHelp;

+    BbsType     = BBS_CDROM;

+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyCD;

+    OldData     = CallbackData->BmmOldFakeNVData.LegacyCD;

+    break;

+

+  case FORM_SET_NET_ORDER_ID:

+    OptionMenu  = (BM_MENU_OPTION *) &LegacyNETMenu;

+    Key         = LEGACY_NET_QUESTION_ID;

+    TypeStr     = StrNET;

+    TypeStrHelp = StrNETHelp;

+    BbsType     = BBS_EMBED_NETWORK;

+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyNET;

+    OldData     = CallbackData->BmmOldFakeNVData.LegacyNET;

+    break;

+

+  case FORM_SET_BEV_ORDER_ID:

+    OptionMenu  = (BM_MENU_OPTION *) &LegacyBEVMenu;

+    Key         = LEGACY_BEV_QUESTION_ID;

+    TypeStr     = StrBEV;

+    TypeStrHelp = StrBEVHelp;

+    BbsType     = BBS_BEV_DEVICE;

+    LegacyOrder = CallbackData->BmmFakeNvData->LegacyBEV;

+    OldData     = CallbackData->BmmOldFakeNVData.LegacyBEV;

+    break;

+

+  }

+

+  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);

+

+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * (OptionMenu->MenuNumber + 1));

+  if (NULL == IfrOptionList) {

+    return ;

+  }

+

+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {

+    NewMenuEntry                = BOpt_GetMenuEntry (OptionMenu, Index);

+    IfrOptionList[Index].Flags  = EFI_IFR_FLAG_INTERACTIVE;

+    if (0 == Index) {

+      IfrOptionList[Index].Flags |= EFI_IFR_FLAG_DEFAULT;

+    }

+

+    IfrOptionList[Index].Key          = Key;

+    IfrOptionList[Index].StringToken  = NewMenuEntry->DisplayStringToken;

+    IfrOptionList[Index].Value        = (UINT16) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->Index;

+    IfrOptionList[Index].OptionString = NULL;

+  }

+  //

+  // for item "Disabled"

+  //

+  IfrOptionList[Index].Flags        = EFI_IFR_FLAG_INTERACTIVE;

+  IfrOptionList[Index].Key          = Key;

+  IfrOptionList[Index].StringToken  = STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE);

+  IfrOptionList[Index].Value        = 0xFF;

+  IfrOptionList[Index].OptionString = NULL;

+

+  //

+  // Get Device Order from variable

+  //

+  VarData = BdsLibGetVariableAndSize (

+              VarLegacyDevOrder,

+              &EfiLegacyDevOrderGuid,

+              &VarSize

+              );

+

+  if (NULL != VarData) {

+    OriginalPtr = VarData;

+    DevOrder    = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;

+    while (VarData < VarData + VarSize) {

+      if (DevOrder->BbsType == BbsType) {

+        break;

+      }

+

+      VarData += sizeof (BBS_TYPE);

+      VarData += *(UINT16 *) VarData;

+      DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;

+    }

+    //

+    // Create oneof tag here for FD/HD/CD #1 #2

+    //

+    for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {

+      for (Index2 = 0; Index2 <= OptionMenu->MenuNumber; Index2++) {

+        IfrOptionList[Index2].Key = (UINT16) (Key + Index);

+      }

+      //

+      // Create the string for oneof tag

+      //

+      UnicodeSPrint (String, sizeof (String), TypeStr, Index);

+      StrRef = 0;

+      CallbackData->Hii->NewString (

+                          CallbackData->Hii,

+                          NULL,

+                          CallbackData->BmmHiiHandle,

+                          &StrRef,

+                          String

+                          );

+

+      UnicodeSPrint (String, sizeof (String), TypeStrHelp, Index);

+      StrRefHelp = 0;

+      CallbackData->Hii->NewString (

+                          CallbackData->Hii,

+                          NULL,

+                          CallbackData->BmmHiiHandle,

+                          &StrRefHelp,

+                          String

+                          );

+

+      CreateOneOfOpCode (

+        (UINT16) (Key + Index),

+        (UINT8) 1,

+        StrRef,

+        StrRefHelp,

+        IfrOptionList,

+        OptionMenu->MenuNumber + 1,

+        Location

+        );

+

+      VarDevOrder = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16));

+

+      if (0xFF00 == (VarDevOrder & 0xFF00)) {

+        LegacyOrder[Index]  = 0xFF;

+        Pos                 = (VarDevOrder & 0xFF) / 8;

+        Bit                 = 7 - ((VarDevOrder & 0xFF) % 8);

+        DisMap[Pos] |= (UINT8) (1 << Bit);

+      } else {

+        LegacyOrder[Index] = (UINT8) (VarDevOrder & 0xFF);

+      }

+

+      Location              = Location + (OptionMenu->MenuNumber + 2) * ((EFI_IFR_OP_HEADER *) Location)->Length;

+      Location              = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+      UpdateData->DataCount = (UINT16) (UpdateData->DataCount + (OptionMenu->MenuNumber + 3));

+    }

+  }

+

+  CopyMem (

+    OldData,

+    LegacyOrder,

+    100

+    );

+

+  if (IfrOptionList != NULL) {

+    SafeFreePool (IfrOptionList);

+    IfrOptionList = NULL;

+  }

+

+  UpdatePageEnd (CallbackData, Location);

+}

+

+VOID

+UpdatePageId (

+  BMM_CALLBACK_DATA              *Private,

+  UINT16                         NewPageId

+  )

+{

+  UINT16  FileOptionMask;

+

+  FileOptionMask = (UINT16) (FILE_OPTION_MASK & NewPageId);

+

+  if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {

+    //

+    // If we select a handle to add driver option, advance to the add handle description page.

+    //

+    NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;

+  } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {

+    //

+    // Return to main page after "Save Changes" or "Discard Changes".

+    //

+    NewPageId = FORM_MAIN_ID;

+  }

+

+  if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {

+    Private->BmmPreviousPageId  = Private->BmmCurrentPageId;

+    Private->BmmCurrentPageId   = NewPageId;

+  }

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Variable.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Variable.c
new file mode 100644
index 0000000..d0c5c9b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Variable.c
@@ -0,0 +1,1279 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Variable.c

+

+Abstract:

+

+  Variable operation that will be used by bootmaint

+

+--*/

+

+#include "Generic/Bds.h"

+#include "bootmaint.h"

+#include "bdsplatform.h"

+

+EFI_STATUS

+Var_DelBootOption (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Delete Boot Option that represent a Deleted state in BootOptionMenu.

+  After deleting this boot option, call Var_ChangeBootOrder to

+  make sure BootOrder is in valid state.

+  

+Arguments:

+  LoadOption -- Pointer to the boot option that to be deleted

+

+Returns:

+  EFI_SUCCESS

+  Others

+  

+--*/

+{

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+

+  UINT16          BootString[10];

+  EFI_STATUS      Status;

+  UINTN           Index;

+  UINTN           Index2;

+

+  Status  = EFI_SUCCESS;

+  Index2  = 0;

+  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+    if (!NewLoadContext->Deleted) {

+      continue;

+    }

+

+    UnicodeSPrint (

+      BootString,

+      sizeof (BootString),

+      L"Boot%04x",

+      NewMenuEntry->OptionNumber

+      );

+

+    EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);

+    Index2++;

+    //

+    // If current Load Option is the same as BootNext,

+    // must delete BootNext in order to make sure

+    // there will be no panic on next boot

+    //

+    if (NewLoadContext->IsBootNext) {

+      EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);

+    }

+

+    RemoveEntryList (&NewMenuEntry->Link);

+    BOpt_DestroyMenuEntry (NewMenuEntry);

+    NewMenuEntry = NULL;

+  }

+

+  BootOptionMenu.MenuNumber -= Index2;

+

+  Status = Var_ChangeBootOrder ();

+  return Status;

+}

+

+EFI_STATUS

+Var_ChangeBootOrder (

+  VOID

+  )

+/*++

+

+Routine Description:

+  After any operation on Boot####, there will be a discrepancy in BootOrder.

+  Since some are missing but in BootOrder, while some are present but are 

+  not reflected by BootOrder. Then a function rebuild BootOrder from 

+  scratch by content from BootOptionMenu is needed.

+  

+Arguments:

+

+Returns:

+  EFI_SUCCESS

+  Others

+  

+--*/

+{

+

+  EFI_STATUS    Status;

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        *BootOrderList;

+  UINT16        *BootOrderListPtr;

+  UINTN         BootOrderListSize;

+  UINTN         Index;

+

+  BootOrderList     = NULL;

+  BootOrderListSize = 0;

+

+  //

+  // First check whether BootOrder is present in current configuration

+  //

+  BootOrderList = BdsLibGetVariableAndSize (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    &BootOrderListSize

+                    );

+

+  //

+  // If exists, delete it to hold new BootOrder

+  //

+  if (BootOrderList) {

+    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);

+    SafeFreePool (BootOrderList);

+    BootOrderList = NULL;

+  }

+  //

+  // Maybe here should be some check method to ensure that

+  // no new added boot options will be added

+  // but the setup engine now will give only one callback

+  // that is to say, user are granted only one chance to

+  // decide whether the boot option will be added or not

+  // there should be no indictor to show whether this

+  // is a "new" boot option

+  //

+  BootOrderListSize = BootOptionMenu.MenuNumber;

+

+  if (BootOrderListSize > 0) {

+    BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));

+    ASSERT (BootOrderList != NULL);

+    BootOrderListPtr = BootOrderList;

+

+    //

+    // Get all current used Boot#### from BootOptionMenu.

+    // OptionNumber in each BM_LOAD_OPTION is really its

+    // #### value.

+    //

+    for (Index = 0; Index < BootOrderListSize; Index++) {

+      NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);

+      *BootOrderList  = (UINT16) NewMenuEntry->OptionNumber;

+      BootOrderList++;

+    }

+

+    BootOrderList = BootOrderListPtr;

+

+    //

+    // After building the BootOrderList, write it back

+    //

+    Status = gRT->SetVariable (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    BootOrderListSize * sizeof (UINT16),

+                    BootOrderList

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+Var_DelDriverOption (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Delete Load Option that represent a Deleted state in BootOptionMenu.

+  After deleting this Driver option, call Var_ChangeDriverOrder to

+  make sure DriverOrder is in valid state.

+  

+Arguments:

+  LoadOption -- Pointer to the Driver option that to be deleted

+

+Returns:

+  EFI_SUCCESS

+  Others

+  

+--*/

+{

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+

+  UINT16          DriverString[12];

+  EFI_STATUS      Status;

+  UINTN           Index;

+  UINTN           Index2;

+

+  Status  = EFI_SUCCESS;

+  Index2  = 0;

+  for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+    if (!NewLoadContext->Deleted) {

+      continue;

+    }

+

+    UnicodeSPrint (

+      DriverString,

+      sizeof (DriverString),

+      L"Driver%04x",

+      NewMenuEntry->OptionNumber

+      );

+

+    EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);

+    Index2++;

+

+    RemoveEntryList (&NewMenuEntry->Link);

+    BOpt_DestroyMenuEntry (NewMenuEntry);

+    NewMenuEntry = NULL;

+  }

+

+  DriverOptionMenu.MenuNumber -= Index2;

+

+  Status = Var_ChangeDriverOrder ();

+  return Status;

+}

+

+EFI_STATUS

+Var_ChangeDriverOrder (

+  VOID

+  )

+/*++

+

+Routine Description:

+  After any operation on Driver####, there will be a discrepancy in 

+  DriverOrder. Since some are missing but in DriverOrder, while some 

+  are present but are not reflected by DriverOrder. Then a function 

+  rebuild DriverOrder from scratch by content from DriverOptionMenu is 

+  needed.

+  

+Arguments:

+

+Returns:

+  EFI_SUCCESS

+  Others

+  

+--*/

+{

+  EFI_STATUS    Status;

+  BM_MENU_ENTRY *NewMenuEntry;

+  UINT16        *DriverOrderList;

+  UINT16        *DriverOrderListPtr;

+  UINTN         DriverOrderListSize;

+  UINTN         Index;

+

+  DriverOrderList     = NULL;

+  DriverOrderListSize = 0;

+

+  //

+  // First check whether DriverOrder is present in current configuration

+  //

+  DriverOrderList = BdsLibGetVariableAndSize (

+                      L"DriverOrder",

+                      &gEfiGlobalVariableGuid,

+                      &DriverOrderListSize

+                      );

+

+  //

+  // If exists, delete it to hold new DriverOrder

+  //

+  if (DriverOrderList) {

+    EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);

+    SafeFreePool (DriverOrderList);

+    DriverOrderList = NULL;

+  }

+

+  DriverOrderListSize = DriverOptionMenu.MenuNumber;

+

+  if (DriverOrderListSize > 0) {

+    DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));

+    ASSERT (DriverOrderList != NULL);

+    DriverOrderListPtr = DriverOrderList;

+

+    //

+    // Get all current used Driver#### from DriverOptionMenu.

+    // OptionNumber in each BM_LOAD_OPTION is really its

+    // #### value.

+    //

+    for (Index = 0; Index < DriverOrderListSize; Index++) {

+      NewMenuEntry      = BOpt_GetMenuEntry (&DriverOptionMenu, Index);

+      *DriverOrderList  = (UINT16) NewMenuEntry->OptionNumber;

+      DriverOrderList++;

+    }

+

+    DriverOrderList = DriverOrderListPtr;

+

+    //

+    // After building the DriverOrderList, write it back

+    //

+    Status = gRT->SetVariable (

+                    L"DriverOrder",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    DriverOrderListSize * sizeof (UINT16),

+                    DriverOrderList

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+VOID

+Var_UpdateAllConsoleOption (

+  VOID

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *OutDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *InpDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *ErrDevicePath;

+  EFI_STATUS                Status;

+

+  OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);

+  InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);

+  ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);

+  if (OutDevicePath) {

+    ChangeVariableDevicePath (OutDevicePath);

+    Status = gRT->SetVariable (

+                    L"ConOut",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    GetDevicePathSize (OutDevicePath),

+                    OutDevicePath

+                    );

+    ASSERT (!EFI_ERROR (Status));

+  }

+

+  if (InpDevicePath) {

+    ChangeVariableDevicePath (InpDevicePath);

+    Status = gRT->SetVariable (

+                    L"ConIn",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    GetDevicePathSize (InpDevicePath),

+                    InpDevicePath

+                    );

+    ASSERT (!EFI_ERROR (Status));

+  }

+

+  if (ErrDevicePath) {

+    ChangeVariableDevicePath (ErrDevicePath);

+    Status = gRT->SetVariable (

+                    L"ErrOut",

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    GetDevicePathSize (ErrDevicePath),

+                    ErrDevicePath

+                    );

+    ASSERT (!EFI_ERROR (Status));

+  }

+}

+

+EFI_STATUS

+Var_UpdateConsoleOption (

+  IN UINT16                     *ConsoleName,

+  IN BM_MENU_OPTION             *ConsoleMenu,

+  IN UINT16                     UpdatePageId

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;

+  BM_MENU_ENTRY             *NewMenuEntry;

+  BM_CONSOLE_CONTEXT        *NewConsoleContext;

+  BM_TERMINAL_CONTEXT       *NewTerminalContext;

+  EFI_STATUS                Status;

+  VENDOR_DEVICE_PATH        Vendor;

+  EFI_DEVICE_PATH_PROTOCOL  *TerminalDevicePath;

+  UINTN                     Index;

+  UINT16                    *Temp;

+

+  ConDevicePath = EfiLibGetVariable (ConsoleName, &gEfiGlobalVariableGuid);

+  if (ConDevicePath != NULL) {

+    EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);

+    SafeFreePool (ConDevicePath);

+    ConDevicePath = NULL;

+  };

+

+  //

+  // First add all console input device to it from console input menu

+  //

+  for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;

+    if (NewConsoleContext->IsActive) {

+      ConDevicePath = AppendDevicePathInstance (

+                        ConDevicePath,

+                        NewConsoleContext->DevicePath

+                        );

+    }

+  }

+

+  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

+    if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||

+        (NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||

+        (NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))

+        ) {

+      Vendor.Header.Type    = MESSAGING_DEVICE_PATH;

+      Vendor.Header.SubType = MSG_VENDOR_DP;

+      CopyMem (

+        &Vendor.Guid,

+        &Guid[NewTerminalContext->TerminalType],

+        sizeof (EFI_GUID)

+        );

+      SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));

+      TerminalDevicePath = AppendDevicePathNode (

+                            NewTerminalContext->DevicePath,

+                            (EFI_DEVICE_PATH_PROTOCOL *) &Vendor

+                            );

+      ChangeTerminalDevicePath (TerminalDevicePath, TRUE);

+      Temp = DevicePathToStr (TerminalDevicePath);

+      ConDevicePath = AppendDevicePathInstance (

+                        ConDevicePath,

+                        TerminalDevicePath

+                        );

+    }

+  }

+

+  if (ConDevicePath) {

+    Status = gRT->SetVariable (

+                    ConsoleName,

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    GetDevicePathSize (ConDevicePath),

+                    ConDevicePath

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+Var_UpdateConsoleInpOption (

+  VOID

+  )

+{

+  return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);

+}

+

+EFI_STATUS

+Var_UpdateConsoleOutOption (

+  VOID

+  )

+{

+  return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);

+}

+

+EFI_STATUS

+Var_UpdateErrorOutOption (

+  VOID

+  )

+{

+  return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);

+}

+

+EFI_STATUS

+Var_UpdateDriverOption (

+  IN  BMM_CALLBACK_DATA         *CallbackData,

+  IN  EFI_HII_HANDLE            HiiHandle,

+  IN  UINT16                    *DescriptionData,

+  IN  UINT16                    *OptionalData,

+  IN  UINT8                     ForceReconnect

+  )

+{

+  UINT16          Index;

+  UINT16          *DriverOrderList;

+  UINT16          *NewDriverOrderList;

+  UINT16          DriverString[12];

+  UINTN           DriverOrderListSize;

+  VOID            *Buffer;

+  UINTN           BufferSize;

+  UINT8           *Ptr;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+  BOOLEAN         OptionalDataExist;

+  EFI_STATUS      Status;

+

+  OptionalDataExist = FALSE;

+

+  Index             = BOpt_GetDriverOptionNumber ();

+  UnicodeSPrint (

+    DriverString,

+    sizeof (DriverString),

+    L"Driver%04x",

+    Index

+    );

+

+  if (*DescriptionData == 0x0000) {

+    StrCpy (DescriptionData, DriverString);

+  }

+

+  BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);

+

+  if (*OptionalData != 0x0000) {

+    OptionalDataExist = TRUE;

+    BufferSize += StrSize (OptionalData);

+  }

+

+  Buffer = AllocateZeroPool (BufferSize);

+  if (NULL == Buffer) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);

+  if (NULL == NewMenuEntry) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NewLoadContext                  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+  NewLoadContext->Deleted         = FALSE;

+  NewLoadContext->LoadOptionSize  = BufferSize;

+  Ptr = (UINT8 *) Buffer;

+  NewLoadContext->LoadOption = Ptr;

+  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);

+  NewLoadContext->Attributes = *((UINT32 *) Ptr);

+  NewLoadContext->IsActive = TRUE;

+  NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);

+

+  Ptr += sizeof (UINT32);

+  *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);

+  NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);

+

+  Ptr += sizeof (UINT16);

+  CopyMem (

+    Ptr,

+    DescriptionData,

+    StrSize (DescriptionData)

+    );

+

+  NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));

+  ASSERT (NewLoadContext->Description != NULL);

+  NewMenuEntry->DisplayString = NewLoadContext->Description;

+  CopyMem (

+    NewLoadContext->Description,

+    (VOID *) Ptr,

+    StrSize (DescriptionData)

+    );

+

+  Ptr += StrSize (DescriptionData);

+  CopyMem (

+    Ptr,

+    CallbackData->LoadContext->FilePathList,

+    GetDevicePathSize (CallbackData->LoadContext->FilePathList)

+    );

+

+  NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));

+  ASSERT (NewLoadContext->FilePathList != NULL);

+

+  CopyMem (

+    NewLoadContext->FilePathList,

+    (VOID *) Ptr,

+    GetDevicePathSize (CallbackData->LoadContext->FilePathList)

+    );

+

+  NewMenuEntry->HelpString    = DevicePathToStr (NewLoadContext->FilePathList);

+  NewMenuEntry->OptionNumber  = Index;

+  NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (

+                                      CallbackData,

+                                      DriverOptionStrDepository

+                                      );

+  CallbackData->Hii->NewString (

+                      CallbackData->Hii,

+                      NULL,

+                      HiiHandle,

+                      &NewMenuEntry->DisplayStringToken,

+                      NewMenuEntry->DisplayString

+                      );

+

+  NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (

+                                    CallbackData,

+                                    DriverOptionHelpStrDepository

+                                    );

+  CallbackData->Hii->NewString (

+                      CallbackData->Hii,

+                      NULL,

+                      HiiHandle,

+                      &NewMenuEntry->HelpStringToken,

+                      NewMenuEntry->HelpString

+                      );

+

+  if (OptionalDataExist) {

+    Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);

+

+    CopyMem (

+      Ptr,

+      OptionalData,

+      StrSize (OptionalData)

+      );

+  }

+

+  Status = gRT->SetVariable (

+                  DriverString,

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  BufferSize,

+                  Buffer

+                  );

+  DriverOrderList = BdsLibGetVariableAndSize (

+                      L"DriverOrder",

+                      &gEfiGlobalVariableGuid,

+                      &DriverOrderListSize

+                      );

+  NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));

+  ASSERT (NewDriverOrderList != NULL);

+  CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);

+  NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;

+  if (DriverOrderList != NULL) {

+    EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);

+  }

+

+  Status = gRT->SetVariable (

+                  L"DriverOrder",

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  DriverOrderListSize + sizeof (UINT16),

+                  NewDriverOrderList

+                  );

+  SafeFreePool (DriverOrderList);

+  DriverOrderList = NULL;

+  SafeFreePool (NewDriverOrderList);

+  NewDriverOrderList = NULL;

+  InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);

+  DriverOptionMenu.MenuNumber++;

+

+  *DescriptionData  = 0x0000;

+  *OptionalData     = 0x0000;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+Var_UpdateBootOption (

+  IN  BMM_CALLBACK_DATA                   *CallbackData,

+  IN  FILE_EXPLORER_NV_DATA               *NvRamMap

+  )

+{

+  UINT16          *BootOrderList;

+  UINT16          *NewBootOrderList;

+  UINTN           BootOrderListSize;

+  UINT16          BootString[10];

+  VOID            *Buffer;

+  UINTN           BufferSize;

+  UINT8           *Ptr;

+  UINT16          Index;

+  BM_MENU_ENTRY   *NewMenuEntry;

+  BM_LOAD_CONTEXT *NewLoadContext;

+  BOOLEAN         OptionalDataExist;

+  EFI_STATUS      Status;

+

+  OptionalDataExist = FALSE;

+

+  Index             = BOpt_GetBootOptionNumber ();

+  UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);

+

+  if (NvRamMap->DescriptionData[0] == 0x0000) {

+    StrCpy (NvRamMap->DescriptionData, BootString);

+  }

+

+  BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);

+

+  if (NvRamMap->OptionalData[0] != 0x0000) {

+    OptionalDataExist = TRUE;

+    BufferSize += StrSize (NvRamMap->OptionalData);

+  }

+

+  Buffer = AllocateZeroPool (BufferSize);

+  if (NULL == Buffer) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);

+  if (NULL == NewMenuEntry) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NewLoadContext                  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+  NewLoadContext->Deleted         = FALSE;

+  NewLoadContext->LoadOptionSize  = BufferSize;

+  Ptr = (UINT8 *) Buffer;

+  NewLoadContext->LoadOption = Ptr;

+  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;

+  NewLoadContext->Attributes = *((UINT32 *) Ptr);

+  NewLoadContext->IsActive = TRUE;

+  NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);

+

+  Ptr += sizeof (UINT32);

+  *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);

+  NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);

+  Ptr += sizeof (UINT16);

+

+  CopyMem (

+    Ptr,

+    NvRamMap->DescriptionData,

+    StrSize (NvRamMap->DescriptionData)

+    );

+

+  NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));

+  ASSERT (NewLoadContext->Description != NULL);

+

+  NewMenuEntry->DisplayString = NewLoadContext->Description;

+  CopyMem (

+    NewLoadContext->Description,

+    (VOID *) Ptr,

+    StrSize (NvRamMap->DescriptionData)

+    );

+

+  Ptr += StrSize (NvRamMap->DescriptionData);

+  CopyMem (

+    Ptr,

+    CallbackData->LoadContext->FilePathList,

+    GetDevicePathSize (CallbackData->LoadContext->FilePathList)

+    );

+

+  NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));

+  ASSERT (NewLoadContext->FilePathList != NULL);

+

+  CopyMem (

+    NewLoadContext->FilePathList,

+    (VOID *) Ptr,

+    GetDevicePathSize (CallbackData->LoadContext->FilePathList)

+    );

+

+  NewMenuEntry->HelpString    = DevicePathToStr (NewLoadContext->FilePathList);

+  NewMenuEntry->OptionNumber  = Index;

+  NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (

+                                      CallbackData,

+                                      BootOptionStrDepository

+                                      );

+  CallbackData->Hii->NewString (

+                      CallbackData->Hii,

+                      NULL,

+                      CallbackData->FeHiiHandle,

+                      &NewMenuEntry->DisplayStringToken,

+                      NewMenuEntry->DisplayString

+                      );

+

+  NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (

+                                    CallbackData,

+                                    BootOptionHelpStrDepository

+                                    );

+

+  CallbackData->Hii->NewString (

+                      CallbackData->Hii,

+                      NULL,

+                      CallbackData->FeHiiHandle,

+                      &NewMenuEntry->HelpStringToken,

+                      NewMenuEntry->HelpString

+                      );

+

+  if (OptionalDataExist) {

+    Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);

+

+    CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));

+  }

+

+  Status = gRT->SetVariable (

+                  BootString,

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  BufferSize,

+                  Buffer

+                  );

+

+  BootOrderList = BdsLibGetVariableAndSize (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    &BootOrderListSize

+                    );

+

+  NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));

+  ASSERT (NewBootOrderList != NULL);

+  CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);

+  NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;

+

+  if (BootOrderList != NULL) {

+    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);

+  }

+

+  Status = gRT->SetVariable (

+                  L"BootOrder",

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  BootOrderListSize + sizeof (UINT16),

+                  NewBootOrderList

+                  );

+

+  SafeFreePool (BootOrderList);

+  BootOrderList = NULL;

+  SafeFreePool (NewBootOrderList);

+  NewBootOrderList = NULL;

+  InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);

+  BootOptionMenu.MenuNumber++;

+

+  NvRamMap->DescriptionData[0]  = 0x0000;

+  NvRamMap->OptionalData[0]     = 0x0000;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+Var_UpdateBootNext (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  )

+{

+  BM_MENU_ENTRY     *NewMenuEntry;

+  BM_LOAD_CONTEXT   *NewLoadContext;

+  BMM_FAKE_NV_DATA  *CurrentFakeNVMap;

+  UINT16            Index;

+  EFI_STATUS        Status;

+

+  Status            = EFI_SUCCESS;

+  CurrentFakeNVMap  = CallbackData->BmmFakeNvData;

+  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+    NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);

+    if (NULL == NewMenuEntry) {

+      return EFI_NOT_FOUND;

+    }

+

+    NewLoadContext              = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+    NewLoadContext->IsBootNext  = FALSE;

+  }

+

+  if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {

+    EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);

+    return EFI_SUCCESS;

+  }

+

+  NewMenuEntry = BOpt_GetMenuEntry (

+                  &BootOptionMenu,

+                  CurrentFakeNVMap->BootNext

+                  );

+  if (NULL == NewMenuEntry) {

+    return EFI_NOT_FOUND;

+  }

+

+  NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;

+  Status = gRT->SetVariable (

+                  L"BootNext",

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  sizeof (UINT16),

+                  &NewMenuEntry->OptionNumber

+                  );

+  NewLoadContext->IsBootNext              = TRUE;

+  CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;

+  return Status;

+}

+

+EFI_STATUS

+Var_UpdateBootOrder (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  )

+{

+  EFI_STATUS  Status;

+  UINT16      Index;

+  UINT16      *BootOrderList;

+  UINT16      *NewBootOrderList;

+  UINTN       BootOrderListSize;

+  UINT8       *Map;

+

+  BootOrderList     = NULL;

+  BootOrderListSize = 0;

+

+  //

+  // First check whether BootOrder is present in current configuration

+  //

+  BootOrderList = BdsLibGetVariableAndSize (

+                    L"BootOrder",

+                    &gEfiGlobalVariableGuid,

+                    &BootOrderListSize

+                    );

+

+  NewBootOrderList = AllocateZeroPool (BootOrderListSize);

+  if (!NewBootOrderList) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Map = AllocateZeroPool (BootOrderListSize / sizeof (UINT16));

+  if (!Map) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // If exists, delete it to hold new BootOrder

+  //

+  if (BootOrderList) {

+    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);

+  }

+

+  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {

+    NewBootOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;

+  }

+

+  Status = gRT->SetVariable (

+                  L"BootOrder",

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  BootOrderListSize,

+                  NewBootOrderList

+                  );

+  SafeFreePool (BootOrderList);

+  SafeFreePool (NewBootOrderList);

+  SafeFreePool (Map);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  BOpt_FreeMenu (&BootOptionMenu);

+  BOpt_GetBootOptions (CallbackData);

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+Var_UpdateDriverOrder (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  )

+{

+  EFI_STATUS  Status;

+  UINT16      Index;

+  UINT16      *DriverOrderList;

+  UINT16      *NewDriverOrderList;

+  UINTN       DriverOrderListSize;

+

+  DriverOrderList     = NULL;

+  DriverOrderListSize = 0;

+

+  //

+  // First check whether DriverOrder is present in current configuration

+  //

+  DriverOrderList = BdsLibGetVariableAndSize (

+                      L"DriverOrder",

+                      &gEfiGlobalVariableGuid,

+                      &DriverOrderListSize

+                      );

+

+  NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);

+

+  if (!NewDriverOrderList) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // If exists, delete it to hold new DriverOrder

+  //

+  if (DriverOrderList) {

+    EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);

+  }

+

+  for (Index = 0; Index < DriverOrderListSize; Index++) {

+    NewDriverOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;

+  }

+

+  Status = gRT->SetVariable (

+                  L"DriverOrder",

+                  &gEfiGlobalVariableGuid,

+                  VAR_FLAG,

+                  DriverOrderListSize,

+                  NewDriverOrderList

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  SafeFreePool (DriverOrderList);

+

+  BOpt_FreeMenu (&DriverOptionMenu);

+  BOpt_GetDriverOptions (CallbackData);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+Var_UpdateBBSOption (

+  IN BMM_CALLBACK_DATA            *CallbackData

+  )

+{

+  UINTN                       Index;

+  UINTN                       Index2;

+  VOID                        *BootOptionVar;

+  CHAR16                      VarName[100];

+  UINTN                       OptionSize;

+  UINT16                      FilePathSize;

+  UINT8                       *Ptr;

+  EFI_STATUS                  Status;

+  CHAR16                      DescString[100];

+  UINTN                       NewOptionSize;

+  UINT8                       *NewOptionPtr;

+  UINT8                       *TempPtr;

+  UINT32                      *Attribute;

+

+  BM_MENU_OPTION              *OptionMenu;

+  BM_LEGACY_DEVICE_CONTEXT    *LegacyDeviceContext;

+  UINT8                       *LegacyDev;

+  UINT8                       *VarData;

+  UINTN                       VarSize;

+  BM_MENU_ENTRY               *NewMenuEntry;

+  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;

+  UINT8                       *OriginalPtr;

+  UINT8                       *DisMap;

+  UINTN                       Pos;

+  UINTN                       Bit;

+  UINT16                      *NewOrder;

+  UINT16                      Tmp;

+

+  LegacyDeviceContext = NULL;

+  DisMap              = NULL;

+  NewOrder            = NULL;

+

+  if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {

+    OptionMenu            = (BM_MENU_OPTION *) &LegacyFDMenu;

+    LegacyDev             = CallbackData->BmmFakeNvData->LegacyFD;

+    CallbackData->BbsType = BBS_FLOPPY;

+  } else {

+    if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {

+      OptionMenu            = (BM_MENU_OPTION *) &LegacyHDMenu;

+      LegacyDev             = CallbackData->BmmFakeNvData->LegacyHD;

+      CallbackData->BbsType = BBS_HARDDISK;

+    } else {

+      if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {

+        OptionMenu            = (BM_MENU_OPTION *) &LegacyCDMenu;

+        LegacyDev             = CallbackData->BmmFakeNvData->LegacyCD;

+        CallbackData->BbsType = BBS_CDROM;

+      } else {

+        if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {

+          OptionMenu            = (BM_MENU_OPTION *) &LegacyNETMenu;

+          LegacyDev             = CallbackData->BmmFakeNvData->LegacyNET;

+          CallbackData->BbsType = BBS_EMBED_NETWORK;

+        } else {

+          OptionMenu            = (BM_MENU_OPTION *) &LegacyBEVMenu;

+          LegacyDev             = CallbackData->BmmFakeNvData->LegacyBEV;

+          CallbackData->BbsType = BBS_BEV_DEVICE;

+        }

+      }

+    }

+  }

+

+  DisMap  = CallbackData->BmmOldFakeNVData.DisableMap;

+  Status  = EFI_SUCCESS;

+

+  //

+  // Find the first device's context

+  // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext

+  // because we just use it to fill the desc string, and user can not see the string in UI

+  //

+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {

+    NewMenuEntry        = BOpt_GetMenuEntry (OptionMenu, Index);

+    LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;

+    if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {

+      DEBUG ((EFI_D_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));

+      break;

+    }

+  }

+  //

+  // Update the Variable "LegacyDevOrder"

+  //

+  VarData = (UINT8 *) BdsLibGetVariableAndSize (

+                        VarLegacyDevOrder,

+                        &EfiLegacyDevOrderGuid,

+                        &VarSize

+                        );

+

+  if (NULL == VarData) {

+    return EFI_NOT_FOUND;

+  }

+

+  OriginalPtr = VarData;

+  DevOrder    = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;

+

+  while (VarData < VarData + VarSize) {

+    if (DevOrder->BbsType == CallbackData->BbsType) {

+      break;

+    }

+

+    VarData += sizeof (BBS_TYPE);

+    VarData += *(UINT16 *) VarData;

+    DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;

+  }

+

+  if (VarData >= VarData + VarSize) {

+    SafeFreePool (OriginalPtr);

+    return EFI_NOT_FOUND;

+  }

+

+  NewOrder = (UINT16 *) AllocateZeroPool (DevOrder->Length - sizeof (UINT16));

+  if (NULL == NewOrder) {

+    SafeFreePool (VarData);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {

+    if (0xFF == LegacyDev[Index]) {

+      break;

+    }

+

+    NewOrder[Index] = LegacyDev[Index];

+  }

+  //

+  // Only the enable/disable state of each boot device with same device type can be changed,

+  // so we can count on the index information in DevOrder.

+  // DisMap bit array is the only reliable source to check a device's en/dis state,

+  // so we use DisMap to set en/dis state of each item in NewOrder array

+  //

+  for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {

+    Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));

+    Tmp &= 0xFF;

+    Pos = Tmp / 8;

+    Bit = 7 - (Tmp % 8);

+    if (DisMap[Pos] & (1 << Bit)) {

+      NewOrder[Index] = (UINT16) (0xFF00 | Tmp);

+      Index++;

+    }

+  }

+

+  CopyMem (

+    (UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),

+    NewOrder,

+    DevOrder->Length - sizeof (UINT16)

+    );

+  SafeFreePool (NewOrder);

+

+  Status = gRT->SetVariable (

+                  VarLegacyDevOrder,

+                  &EfiLegacyDevOrderGuid,

+                  VAR_FLAG,

+                  VarSize,

+                  OriginalPtr

+                  );

+

+  SafeFreePool (OriginalPtr);

+

+  //

+  // Update Optional Data of Boot####

+  //

+  BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);

+

+  if (NULL != BootOptionVar) {

+    CopyMem (

+      DescString,

+      LegacyDeviceContext->Description,

+      StrSize (LegacyDeviceContext->Description)

+      );

+

+    NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) + sizeof (BBS_TABLE) + sizeof (UINT16);

+

+    UnicodeSPrint (VarName, 100, L"Boot%04x", Index);

+

+    Ptr       = BootOptionVar;

+

+    Attribute = (UINT32 *) Ptr;

+    *Attribute |= LOAD_OPTION_ACTIVE;

+    if (0xFF == LegacyDev[0]) {

+      //

+      // Disable this legacy boot option

+      //

+      *Attribute &= ~LOAD_OPTION_ACTIVE;

+    }

+

+    Ptr += sizeof (UINT32);

+

+    FilePathSize = *(UINT16 *) Ptr;

+    Ptr += sizeof (UINT16);

+

+    NewOptionSize += FilePathSize;

+

+    NewOptionPtr = AllocateZeroPool (NewOptionSize);

+    if (NULL == NewOptionPtr) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    TempPtr = NewOptionPtr;

+

+    //

+    // Copy previous option data to new option except the description string

+    //

+    CopyMem (

+      TempPtr,

+      BootOptionVar,

+      sizeof (UINT32) + sizeof (UINT16)

+      );

+

+    TempPtr += (sizeof (UINT32) + sizeof (UINT16));

+

+    CopyMem (

+      TempPtr,

+      DescString,

+      StrSize (DescString)

+      );

+

+    TempPtr += StrSize (DescString);

+

+    //

+    // Description = (CHAR16 *)Ptr;

+    //

+    Ptr += StrSize ((CHAR16 *) Ptr);

+

+    CopyMem (

+      TempPtr,

+      Ptr,

+      FilePathSize

+      );

+

+    TempPtr += FilePathSize;

+

+    //

+    // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;

+    //

+    Ptr += FilePathSize;

+

+    //

+    // Now Ptr point to optional data, i.e. Bbs Table

+    //

+    CopyMem (

+      TempPtr,

+      LegacyDeviceContext->BbsTable,

+      sizeof (BBS_TABLE)

+      );

+

+    TempPtr += sizeof (BBS_TABLE);

+    *((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;

+

+    Status = gRT->SetVariable (

+                    VarName,

+                    &gEfiGlobalVariableGuid,

+                    VAR_FLAG,

+                    NewOptionSize,

+                    NewOptionPtr

+                    );

+

+    SafeFreePool (NewOptionPtr);

+    SafeFreePool (BootOptionVar);

+  }

+

+  BOpt_GetBootOptions (CallbackData);

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/bm.vfr b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/bm.vfr
new file mode 100644
index 0000000..e907e18
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/bm.vfr
@@ -0,0 +1,495 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   bm.vfr 

+// 

+// Abstract:

+// 

+//   Boot Maintenance Utility Formset

+// 

+// Revision History: 

+// 

+// --*/

+

+#include "BdsStrDefs.h" 

+#include "formguid.h"

+

+#pragma pack(1)

+

+//

+// This is the structure that will be used to store the 

+// question's current value. Use it at initialize time to 

+// set default value for each question. When using at run

+// time, this map is returned by the callback function,

+// so dynamically changing the question's value will be

+// possible through this mechanism

+//

+typedef struct {

+

+//

+// Three questions displayed at the main page

+// for Timeout, BootNext Variables respectively

+//

+  UINT16                    BootTimeOut;

+  UINT16                    BootNext;

+

+//

+// This is the COM1 Attributes value storage

+//

+  UINT8                     COM1BaudRate;

+  UINT8                     COM1DataRate;

+  UINT8                     COM1StopBits;

+  UINT8                     COM1Parity;

+  UINT8                     COM1TerminalType;

+  

+//

+// This is the COM2 Attributes value storage

+//

+  UINT8                     COM2BaudRate;

+  UINT8                     COM2DataRate;

+  UINT8                     COM2StopBits;

+  UINT8                     COM2Parity;

+  UINT8                     COM2TerminalType;

+

+// 

+// Driver Option Add Handle page storage

+//

+  UINT16                    DriverAddHandleDesc[100];

+  UINT16                    DriverAddHandleOptionalData[100];

+  UINT8                     DriverAddActive;

+  UINT8                     DriverAddForceReconnect;

+  

+//

+// Console Input/Output/Errorout using COM port check storage

+//

+  UINT8                     ConsoleInputCOM1;

+  UINT8                     ConsoleInputCOM2;

+  UINT8                     ConsoleOutputCOM1;

+  UINT8                     ConsoleOutputCOM2;

+  UINT8                     ConsoleErrorCOM1;

+  UINT8                     ConsoleErrorCOM2;

+

+//

+// At most 100 input/output/errorout device for console storage

+//

+  UINT8                     ConsoleCheck[100];

+

+//

+// Boot or Driver Option Order storage

+//

+  UINT8                     OptionOrder[100];

+  UINT8                     DriverOptionToBeDeleted[100];

+

+//

+// Boot Option Delete storage

+// 

+  UINT8                     BootOptionDel[100];

+  UINT8                     DriverOptionDel[100];

+  

+//

+// This is the Terminal Attributes value storage

+//

+  UINT8                     COMBaudRate;

+  UINT8                     COMDataRate;

+  UINT8                     COMStopBits;

+  UINT8                     COMParity;

+  UINT8                     COMTerminalType;

+  

+//

+// Legacy Device Order Selection Storage

+//

+  UINT8                     LegacyFD[100];

+  UINT8                     LegacyHD[100];

+  UINT8                     LegacyCD[100];

+  UINT8                     LegacyNET[100];

+  UINT8                     LegacyBEV[100];

+} BMM_FAKE_NV_DATA;

+#pragma pack()

+

+

+#define FORM_MAIN_ID                         0x0001

+#define FORM_BOOT_ADD_ID                     0x0002

+#define FORM_BOOT_DEL_ID                     0x0003

+#define FORM_BOOT_CHG_ID                     0x0004

+#define FORM_DRV_ADD_ID                      0x0005

+#define FORM_DRV_DEL_ID                      0x0006

+#define FORM_DRV_CHG_ID                      0x0007

+#define FORM_CON_MAIN_ID                     0x0008

+#define FORM_CON_IN_ID                       0x0009

+#define FORM_CON_OUT_ID                      0x000A

+#define FORM_CON_ERR_ID                      0x000B

+#define FORM_FILE_SEEK_ID                    0x000C

+#define FORM_FILE_NEW_SEEK_ID                0x000D

+#define FORM_DRV_ADD_FILE_ID                 0x000E

+#define FORM_DRV_ADD_HANDLE_ID               0x000F

+#define FORM_DRV_ADD_HANDLE_DESC_ID          0x0010

+#define FORM_BOOT_NEXT_ID                    0x0011

+#define FORM_TIME_OUT_ID                     0x0012

+#define FORM_RESET                           0x0013

+#define FORM_BOOT_SETUP_ID                   0x0014

+#define FORM_DRIVER_SETUP_ID                 0x0015

+#define FORM_BOOT_LEGACY_DEVICE_ID           0x0016

+#define FORM_CON_COM_ID                      0x0017

+#define FORM_CON_COM_SETUP_ID                0x0018

+#define FORM_SET_FD_ORDER_ID                 0x0019

+#define FORM_SET_HD_ORDER_ID                 0x001A

+#define FORM_SET_CD_ORDER_ID                 0x001B

+#define FORM_SET_NET_ORDER_ID                0x001C

+#define FORM_SET_BEV_ORDER_ID                0x001D

+									

+#define KEY_VALUE_BOOT_FROM_FILE             0x0092

+

+formset 

+  guid = MAIN_FORMSET_GUID,

+  title = STRING_TOKEN(STR_FORM_MAIN_TITLE),  // uint8 opcode, uint8 length, guid Handle, uint16 Title

+  help = STRING_TOKEN(STR_NULL_STRING),

+  class = 0,      

+  subclass = 0,

+

+  form formid = FORM_MAIN_ID,

+       title = STRING_TOKEN(STR_FORM_MAIN_TITLE);

+

+    goto FORM_BOOT_SETUP_ID,

+         prompt = STRING_TOKEN(STR_FORM_BOOT_SETUP_TITLE),

+         help = STRING_TOKEN(STR_FORM_BOOT_SETUP_HELP),

+         flags = INTERACTIVE | NV_ACCESS,

+         key = FORM_BOOT_SETUP_ID;

+

+    subtitle text = STRING_TOKEN(STR_NULL_STRING);

+

+    goto FORM_DRIVER_SETUP_ID,

+         prompt = STRING_TOKEN(STR_FORM_DRIVER_SETUP_TITLE),

+         help = STRING_TOKEN(STR_FORM_DRIVER_SETUP_HELP),

+         flags = INTERACTIVE | NV_ACCESS,

+         key = FORM_DRIVER_SETUP_ID;

+

+    subtitle text = STRING_TOKEN(STR_NULL_STRING);

+

+    goto FORM_CON_MAIN_ID,

+         prompt = STRING_TOKEN(STR_FORM_CON_MAIN_TITLE),

+         help = STRING_TOKEN(STR_FORM_CON_MAIN_HELP),

+         flags = INTERACTIVE | NV_ACCESS,

+         key = FORM_CON_MAIN_ID;

+   

+    subtitle text = STRING_TOKEN(STR_NULL_STRING);

+

+    text 

+         help   = STRING_TOKEN(STR_BOOT_FROM_FILE_HELP),  

+         text   = STRING_TOKEN(STR_BOOT_FROM_FILE),

+         text   = STRING_TOKEN(STR_NULL_STRING),

+         flags  = INTERACTIVE | NV_ACCESS,

+         key    = KEY_VALUE_BOOT_FROM_FILE;

+

+    subtitle text = STRING_TOKEN(STR_NULL_STRING);

+

+//    label FORM_MAIN_ID;

+

+    goto FORM_BOOT_NEXT_ID,

+         prompt = STRING_TOKEN(STR_FORM_BOOT_NEXT_TITLE),

+         help = STRING_TOKEN(STR_FORM_BOOT_NEXT_HELP),

+         flags = INTERACTIVE | NV_ACCESS,

+         key = FORM_BOOT_NEXT_ID;            

+

+    goto FORM_TIME_OUT_ID,

+         prompt = STRING_TOKEN(STR_FORM_TIME_OUT_TITLE),

+         help = STRING_TOKEN(STR_FORM_TIME_OUT_HELP),

+         flags = INTERACTIVE | NV_ACCESS,

+         key = FORM_TIME_OUT_ID;

+         

+    subtitle text = STRING_TOKEN(STR_NULL_STRING);

+

+    goto FORM_MAIN_ID,

+         prompt = STRING_TOKEN(STR_RESET),

+         help = STRING_TOKEN(STR_RESET),

+         flags = INTERACTIVE | NV_ACCESS,

+         key = FORM_RESET;

+         

+  endform;       

+

+  form formid = FORM_BOOT_SETUP_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_SETUP_TITLE);

+

+       goto FORM_MAIN_ID,

+            prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+            help = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_MAIN_ID;

+

+       goto FORM_BOOT_ADD_ID,

+            prompt = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE),

+            help = STRING_TOKEN(STR_FORM_BOOT_ADD_HELP),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_BOOT_ADD_ID;

+      

+       goto FORM_BOOT_DEL_ID,

+            prompt = STRING_TOKEN(STR_FORM_BOOT_DEL_TITLE),

+            help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_BOOT_DEL_ID;

+       

+       goto FORM_BOOT_CHG_ID,

+            prompt = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE),

+            help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_BOOT_CHG_ID;

+

+       subtitle text = STRING_TOKEN(STR_NULL_STRING);

+       //

+	   // We will add "Select Legacy Boot Floppy Drive" and "Select Legacy Boot Hard Drive" 

+	   // here dynamically

+	   //

+       label FORM_BOOT_LEGACY_DEVICE_ID;

+

+  endform;       

+

+  form formid = FORM_DRIVER_SETUP_ID,

+       title = STRING_TOKEN(STR_FORM_DRIVER_SETUP_TITLE);

+

+       goto FORM_MAIN_ID,

+            prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+            help = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_MAIN_ID;

+

+       goto FORM_DRV_ADD_ID,

+            prompt = STRING_TOKEN(STR_FORM_DRV_ADD_TITLE),

+            help = STRING_TOKEN(STR_FORM_DRV_ADD_HELP),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_DRV_ADD_ID;

+     

+       goto FORM_DRV_DEL_ID,

+            prompt = STRING_TOKEN(STR_FORM_DRV_DEL_TITLE),

+            help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_DRV_DEL_ID;

+       

+       goto FORM_DRV_CHG_ID,

+            prompt = STRING_TOKEN(STR_FORM_DRV_CHG_TITLE),

+            help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_DRV_CHG_ID;

+  endform;       

+

+  form formid = FORM_BOOT_ADD_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE);

+

+       label FORM_BOOT_ADD_ID;

+  endform;

+

+  form formid = FORM_BOOT_DEL_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_DEL_TITLE);

+

+       label FORM_BOOT_DEL_ID;

+  endform;

+

+  form formid = FORM_BOOT_CHG_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE);

+

+       label FORM_BOOT_CHG_ID;

+       

+       //

+       // This tag is added for bypassing issue of setup browser

+       // setup browser could not support dynamic form very well.

+       //

+       checkbox varid    = BMM_FAKE_NV_DATA.OptionOrder[0],

+           prompt   = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE),

+           help     = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE),  

+           flags    = 1,

+           key      = 0,

+       endcheckbox;

+      

+  endform;

+

+  form formid = FORM_BOOT_NEXT_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_NEXT_TITLE);

+

+       label FORM_BOOT_NEXT_ID;

+  endform;

+  

+  form formid = FORM_TIME_OUT_ID,

+       title = STRING_TOKEN(STR_FORM_TIME_OUT_TITLE);

+       

+       label FORM_TIME_OUT_ID;

+  endform;

+  

+  form formid = FORM_DRV_ADD_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_ADD_TITLE);

+

+       goto FORM_MAIN_ID,

+            prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+            help = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_MAIN_ID;

+              

+       goto FORM_DRV_ADD_FILE_ID,

+            prompt = STRING_TOKEN(STR_FORM_DRV_ADD_FILE_TITLE),

+            help = STRING_TOKEN(STR_FORM_DRV_ADD_FILE_TITLE),

+            flags = INTERACTIVE | NV_ACCESS,

+            key = FORM_DRV_ADD_FILE_ID;

+

+  endform;

+

+  form formid = FORM_DRV_DEL_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_DEL_TITLE);

+

+       label FORM_DRV_DEL_ID;

+

+  endform;

+

+  form formid = FORM_DRV_CHG_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_CHG_TITLE);

+

+       label FORM_DRV_CHG_ID;

+      

+       //

+       // This tag is added for bypassing issue of setup browser

+       // setup browser could not support dynamic form very well.

+       //

+       checkbox varid    = BMM_FAKE_NV_DATA.OptionOrder[0],

+           prompt   = STRING_TOKEN(STR_FORM_DRV_CHG_TITLE),

+           help     = STRING_TOKEN(STR_FORM_DRV_CHG_TITLE),  

+           flags    = 1,

+           key      = 0,

+       endcheckbox;

+       

+  endform;

+

+  form formid = FORM_CON_MAIN_ID,

+       title = STRING_TOKEN(STR_FORM_CON_MAIN_TITLE);

+

+       goto FORM_MAIN_ID,

+       prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+       help = STRING_TOKEN(STR_FORM_GOTO_MAIN),

+       flags = INTERACTIVE | NV_ACCESS,

+       key = FORM_MAIN_ID;

+

+       goto FORM_CON_IN_ID,

+       prompt = STRING_TOKEN(STR_FORM_CON_IN_TITLE),

+       help = STRING_TOKEN(STR_FORM_CON_IN_HELP),

+       flags = INTERACTIVE | NV_ACCESS,

+       key = FORM_CON_IN_ID;

+

+       goto FORM_CON_OUT_ID,

+       prompt = STRING_TOKEN(STR_FORM_CON_OUT_TITLE),

+       help = STRING_TOKEN(STR_FORM_CON_OUT_HELP),

+       flags = INTERACTIVE | NV_ACCESS,

+       key = FORM_CON_OUT_ID;

+  

+       goto FORM_CON_ERR_ID,

+       prompt = STRING_TOKEN(STR_FORM_STD_ERR_TITLE),

+       help = STRING_TOKEN(STR_FORM_STD_ERR_HELP),

+       flags = INTERACTIVE | NV_ACCESS,

+       key = FORM_CON_ERR_ID;

+

+       goto FORM_CON_COM_ID,

+       prompt = STRING_TOKEN(STR_FORM_COM_TITLE),

+       help = STRING_TOKEN(STR_FORM_COM_HELP),

+       flags = INTERACTIVE | NV_ACCESS,

+       key = FORM_CON_COM_ID;

+  endform;

+

+  form formid = FORM_CON_COM_ID,

+       title = STRING_TOKEN(STR_FORM_COM_TITLE);

+

+       label FORM_CON_COM_ID;

+  endform;

+

+  form formid = FORM_CON_COM_SETUP_ID,

+       title = STRING_TOKEN(STR_CON_COM_SETUP);

+

+       label FORM_CON_COM_SETUP_ID;

+  endform;

+

+  form formid = FORM_FILE_SEEK_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE);

+

+       label FORM_FILE_SEEK_ID;

+  endform;

+

+  form formid = FORM_FILE_NEW_SEEK_ID,

+       title = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE);

+

+       label FORM_FILE_NEW_SEEK_ID;

+  endform;

+

+  form formid = FORM_DRV_ADD_FILE_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_ADD_FILE_TITLE);

+

+       label FORM_DRV_ADD_FILE_ID;

+  endform;

+

+  form formid = FORM_DRV_ADD_HANDLE_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_ADD_HANDLE_TITLE);

+

+       label FORM_DRV_ADD_HANDLE_ID;

+  endform;     

+

+  form formid = FORM_DRV_ADD_HANDLE_DESC_ID,

+       title = STRING_TOKEN(STR_FORM_DRV_ADD_DESC_TITLE);

+

+       label FORM_DRV_ADD_HANDLE_DESC_ID;

+

+  endform;

+

+  form formid = FORM_CON_IN_ID,

+       title = STRING_TOKEN(STR_FORM_CON_IN_TITLE);

+

+       label FORM_CON_IN_ID;

+

+  endform;

+

+  form formid = FORM_CON_OUT_ID,

+       title = STRING_TOKEN(STR_FORM_CON_OUT_TITLE);

+

+       label FORM_CON_OUT_ID;

+

+  endform;

+

+  form formid = FORM_CON_ERR_ID,

+       title = STRING_TOKEN(STR_FORM_STD_ERR_TITLE);

+

+       label FORM_CON_ERR_ID;

+

+  endform;

+

+  form formid = FORM_SET_FD_ORDER_ID,

+       title = STRING_TOKEN(STR_FORM_SET_FD_ORDER_TITLE);

+

+       label FORM_SET_FD_ORDER_ID;

+  endform;

+  

+  form formid = FORM_SET_HD_ORDER_ID,

+       title = STRING_TOKEN(STR_FORM_SET_HD_ORDER_TITLE);

+

+       label FORM_SET_HD_ORDER_ID;

+  endform;

+

+  form formid = FORM_SET_CD_ORDER_ID,

+       title = STRING_TOKEN(STR_FORM_SET_CD_ORDER_TITLE);

+

+       label FORM_SET_CD_ORDER_ID;

+  endform;

+

+  form formid = FORM_SET_NET_ORDER_ID,

+       title = STRING_TOKEN(STR_FORM_SET_NET_ORDER_TITLE);

+

+       label FORM_SET_NET_ORDER_ID;

+  endform;

+

+  form formid = FORM_SET_BEV_ORDER_ID,

+       title = STRING_TOKEN(STR_FORM_SET_BEV_ORDER_TITLE);

+

+       label FORM_SET_BEV_ORDER_ID;

+  endform;

+

+endformset;

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/bmstring.uni b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/bmstring.uni
new file mode 100644
index 0000000..f646d8b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/bmstring.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c
new file mode 100644
index 0000000..d90cfaa
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c
@@ -0,0 +1,333 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name: 

+

+  BootManager.c

+

+Abstract:

+

+  The platform boot manager reference implement

+

+--*/

+#include "BootManager.h"

+

+UINT16                            mKeyInput;

+LIST_ENTRY                        *mBootOptionsList;

+BDS_COMMON_OPTION                 *gOption;

+EFI_HII_HANDLE                    gBootManagerHandle;

+EFI_HANDLE                        BootManagerCallbackHandle;

+EFI_FORM_CALLBACK_PROTOCOL        BootManagerCallback;

+EFI_GUID                          gBmGuid = BOOT_MANAGER_GUID;

+

+extern EFI_FORM_BROWSER_PROTOCOL  *gBrowser;

+extern UINT8                      BootManagerVfrBin[];

+extern UINT8                      BdsStrings[];

+extern BOOLEAN                    gConnectAllHappened;

+

+EFI_STATUS

+EFIAPI

+BootManagerCallbackRoutine (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *DataArray,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+/*++

+

+Routine Description:

+

+  This is the function that is called to provide results data to the driver.  This data

+  consists of a unique key which is used to identify what data is either being passed back

+  or being asked for. 

+

+Arguments:

+

+  KeyValue -        A unique value which is sent to the original exporting driver so that it

+                    can identify the type of data to expect.  The format of the data tends to

+                    vary based on the op-code that geerated the callback.

+

+  Data -            A pointer to the data being sent to the original exporting driver.

+

+Returns: 

+

+--*/

+{

+  BDS_COMMON_OPTION       *Option;

+  LIST_ENTRY              *Link;

+  UINT16                  KeyCount;

+  EFI_HII_CALLBACK_PACKET *DataPacket;

+

+  //

+  // Initialize the key count

+  //

+  KeyCount = 0;

+

+  for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {

+    Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

+

+    KeyCount++;

+

+    gOption = Option;

+

+    //

+    // Is this device the one chosen?

+    //

+    if (KeyCount == KeyValue) {

+      //

+      // Assigning the returned Key to a global allows the original routine to know what was chosen

+      //

+      mKeyInput = KeyValue;

+

+      *Packet   = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);

+      ASSERT (*Packet != NULL);

+

+      //

+      // Assign the buffer address to DataPacket

+      //

+      DataPacket                        = *Packet;

+

+      DataPacket->DataArray.EntryCount  = 1;

+      DataPacket->DataArray.NvRamMap    = NULL;

+      ((EFI_IFR_DATA_ENTRY *) (((EFI_IFR_DATA_ARRAY *)DataPacket) + 1))->Flags = EXIT_REQUIRED | NV_NOT_CHANGED;

+      return EFI_SUCCESS;

+    } else {

+      continue;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+CallBootManager (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Hook to enable UI timeout override behavior.

+

+Arguments:

+  BdsDeviceList - Device List that BDS needs to connect.

+

+  Entry - Pointer to current Boot Entry.

+

+Returns:

+  NONE

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_HII_PACKAGES    *PackageList;

+  BDS_COMMON_OPTION   *Option;

+  LIST_ENTRY          *Link;

+  EFI_HII_UPDATE_DATA *UpdateData;

+  CHAR16              *ExitData;

+  UINTN               ExitDataSize;

+  STRING_REF          Token;

+  STRING_REF          LastToken;

+  EFI_INPUT_KEY       Key;

+  UINT8               *Location;

+  EFI_GUID            BmGuid;

+  LIST_ENTRY          BdsBootOptionList;

+

+  gOption = NULL;

+  InitializeListHead (&BdsBootOptionList);

+

+  //

+  // Connect all prior to entering the platform setup menu.

+  //

+  if (!gConnectAllHappened) {

+    BdsLibConnectAllDriversToAllControllers ();

+    gConnectAllHappened = TRUE;

+  }

+  //

+  // BugBug: Here we can not remove the legacy refresh macro, so we need

+  // get the boot order every time from "BootOrder" variable.

+  // Recreate the boot option list base on the BootOrder variable

+  //

+  BdsLibEnumerateAllBootOption (&BdsBootOptionList);

+

+  //

+  // This GUID must be the same as what is defined in BootManagerVfr.vfr

+  //

+  BmGuid            = gBmGuid;

+

+  mBootOptionsList  = &BdsBootOptionList;

+

+  //

+  // Post our VFR to the HII database

+  //

+  PackageList = PreparePackages (2, &BmGuid, BootManagerVfrBin, BdsStrings);

+  Status      = Hii->NewPack (Hii, PackageList, &gBootManagerHandle);

+  gBS->FreePool (PackageList);

+

+  //

+  // This example does not implement worker functions

+  // for the NV accessor functions.  Only a callback evaluator

+  //

+  BootManagerCallback.NvRead    = NULL;

+  BootManagerCallback.NvWrite   = NULL;

+  BootManagerCallback.Callback  = BootManagerCallbackRoutine;

+

+  //

+  // Install protocol interface

+  //

+  BootManagerCallbackHandle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &BootManagerCallbackHandle,

+                  &gEfiFormCallbackProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &BootManagerCallback

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  LastToken = 0;

+  Hii->NewString (Hii, NULL, gBootManagerHandle, &LastToken, L" ");

+

+  //

+  // Allocate space for creation of UpdateData Buffer

+  //

+  UpdateData = AllocateZeroPool (0x1000);

+  ASSERT (UpdateData != NULL);

+

+  //

+  // Flag update pending in FormSet

+  //

+  UpdateData->FormSetUpdate = TRUE;

+  //

+  // Register CallbackHandle data for FormSet

+  //

+  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) BootManagerCallbackHandle;

+  UpdateData->FormUpdate  = FALSE;

+  UpdateData->FormTitle   = 0;

+  UpdateData->DataCount   = 1;

+

+  //

+  // Create blank space.  Since when we update the contents of IFR data at a label, it is

+  // inserted at the location of the label.  So if you want to add a string with an empty

+  // space afterwards, you need to add the space first and then the string like below.

+  //

+  Status = CreateSubTitleOpCode (

+            LastToken,        // Token Value for the string

+            &UpdateData->Data // Buffer containing created op-code

+            );

+

+  Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);

+

+  //

+  // Create "Boot Option Menu" title

+  //

+  Status = CreateSubTitleOpCode (

+            STRING_TOKEN (STR_BOOT_OPTION_BANNER),  // Token Value for the string

+            &UpdateData->Data                       // Buffer containing created op-code

+            );

+

+  Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);

+

+  Token                 = LastToken;

+  mKeyInput             = 0;

+

+  UpdateData->DataCount = 0;

+  Location              = (UINT8 *) &UpdateData->Data;

+

+  for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {

+    Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

+

+    //

+    // At this stage we are creating a menu entry, thus the Keys are reproduceable

+    //

+    mKeyInput++;

+    Token++;

+

+    Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);

+

+    //

+    // If we got an error it is almost certainly due to the token value being invalid.

+    // Therefore we will set the Token to 0 to automatically add a token.

+    //

+    if (EFI_ERROR (Status)) {

+      Token   = 0;

+      Status  = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);

+    }

+

+    Status = CreateGotoOpCode (

+              0x1000, // Form ID

+              Token,  // Token Value for the string

+              0,      // Help String (none)

+              EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,  // The Op-Code flags

+              mKeyInput,                                          // The Key to get a callback on

+              Location  // Buffer containing created op-code

+              );

+

+    UpdateData->DataCount++;

+    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

+

+  }

+

+  Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0001, TRUE, UpdateData);

+

+  UpdateData->DataCount = 1;

+

+  //

+  // Create "Boot Option Menu" title

+  //

+  Status = CreateSubTitleOpCode (

+            STRING_TOKEN (STR_HELP_FOOTER), // Token Value for the string

+            &UpdateData->Data               // Buffer containing created op-code

+            );

+

+  Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);

+

+  Status = CreateSubTitleOpCode (

+            LastToken,                      // Token Value for the string

+            &UpdateData->Data               // Buffer containing created op-code

+            );

+

+  Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);

+

+  gBS->FreePool (UpdateData);

+

+  ASSERT (gBrowser);

+

+  gBrowser->SendForm (gBrowser, TRUE, &gBootManagerHandle, 1, NULL, NULL, NULL, NULL, NULL);

+

+  Hii->ResetStrings (Hii, gBootManagerHandle);

+

+  if (gOption == NULL) {

+    return ;

+  }

+  //

+  // BugBug: This code looks repeated from the BDS. Need to save code space.

+  //

+

+  //

+  // parse the selected option

+  //

+  Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);

+

+  if (!EFI_ERROR (Status)) {

+    PlatformBdsBootSuccess (gOption);

+  } else {

+    PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);

+    gST->ConOut->OutputString (

+                  gST->ConOut,

+                  GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))

+                  );

+

+    //

+    // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);

+    //

+

+    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+  }

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.h
new file mode 100644
index 0000000..3a90932
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.h
@@ -0,0 +1,50 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name: 

+

+  BootManager.h

+

+Abstract:

+

+  The platform boot manager reference implement

+

+Revision History

+

+--*/

+

+#ifndef _EFI_BOOT_MANAGER_H

+#define _EFI_BOOT_MANAGER_H

+

+#include "Generic/Bds.h"

+#include "BdsPlatform.h"

+#include "Generic/String.h"

+

+EFI_STATUS

+EFIAPI

+BootManagerCallbackRoutine (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *DataArray,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  );

+

+VOID

+CallBootManager (

+  VOID

+);

+

+#define BOOT_MANAGER_GUID \

+  { \

+    0x847bc3fe, 0xb974, 0x446d, {0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b } \

+  }

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManagerStrings.uni b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManagerStrings.uni
new file mode 100644
index 0000000..e875cfb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManagerStrings.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManagerVfr.Vfr b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManagerVfr.Vfr
new file mode 100644
index 0000000..7fb193a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManagerVfr.Vfr
@@ -0,0 +1,55 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   BootManager.vfr 

+// 

+// Abstract:

+// 

+//   Browser formset.

+// 

+// Revision History: 

+// 

+// --*/

+

+#include "BdsStrDefs.h"

+

+#define FORMSET_GUID  { 0x847bc3fe, 0xb974, 0x446d, { 0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b } } 

+

+#define BOOT_MANAGER_HEADER		 0x00

+#define BOOT_MANAGER_LABEL		 0x01

+#define BOOT_MANAGER_TAIL		 0x02

+

+

+#define BOOT_MANAGER_CLASS       0x00

+#define BOOT_MANAGER_SUBCLASS    0x01

+

+formset 

+  guid     = FORMSET_GUID,

+  title    = STRING_TOKEN(STR_BM_BANNER),  

+  help     = STRING_TOKEN(STR_LAST_STRING),

+  class    = BOOT_MANAGER_CLASS,      

+  subclass = BOOT_MANAGER_SUBCLASS,

+

+  form formid = 0x1000,

+       title  = STRING_TOKEN(STR_BM_BANNER);

+

+    label BOOT_MANAGER_HEADER;

+    label BOOT_MANAGER_LABEL;

+    //

+    // This is where we will dynamically add choices for the Boot Manager

+    //

+

+    label BOOT_MANAGER_TAIL;

+  endform;

+

+endformset;

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Capsules.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Capsules.c
new file mode 100644
index 0000000..b33af03
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Capsules.c
@@ -0,0 +1,213 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Capsules.c

+

+Abstract:

+

+  BDS routines to handle capsules.

+

+--*/

+

+

+#include <Common/FlashMap.H>

+

+VOID

+BdsLockFv (

+  IN EFI_CPU_IO_PROTOCOL          *CpuIo,

+  IN EFI_FLASH_SUBAREA_ENTRY      *FlashEntry

+  );

+

+VOID

+BdsLockFv (

+  IN EFI_CPU_IO_PROTOCOL          *CpuIo,

+  IN EFI_FLASH_SUBAREA_ENTRY      *FlashEntry

+  )

+{

+  EFI_FV_BLOCK_MAP_ENTRY      *BlockMap;

+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

+  UINT64                      BaseAddress;

+  UINT8                       Data;

+  UINT32                      BlockLength;

+  UINTN                       Index;

+

+  BaseAddress = FlashEntry->Base - 0x400000 + 2;

+  FvHeader    = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (FlashEntry->Base));

+  BlockMap    = &(FvHeader->FvBlockMap[0]);

+

+  while ((BlockMap->NumBlocks != 0) && (BlockMap->BlockLength != 0)) {

+    BlockLength = BlockMap->BlockLength;

+    for (Index = 0; Index < BlockMap->NumBlocks; Index++) {

+      CpuIo->Mem.Read (

+                  CpuIo,

+                  EfiCpuIoWidthUint8,

+                  BaseAddress,

+                  1,

+                  &Data

+                  );

+      Data = (UINT8) (Data | 0x3);

+      CpuIo->Mem.Write (

+                  CpuIo,

+                  EfiCpuIoWidthUint8,

+                  BaseAddress,

+                  1,

+                  &Data

+                  );

+      BaseAddress += BlockLength;

+    }

+

+    BlockMap++;

+  }

+}

+

+VOID

+BdsLockNonUpdatableFlash (

+  VOID

+  )

+{

+  EFI_FLASH_MAP_ENTRY_DATA  *FlashMapEntryData;

+  EFI_PEI_HOB_POINTERS      GuidHob;

+  EFI_STATUS                Status;

+  EFI_CPU_IO_PROTOCOL       *CpuIo;

+

+  Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, &CpuIo);

+  ASSERT_EFI_ERROR (Status);

+  

+  GuidHob.Raw = GetHobList ();

+  while ((GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw)) != NULL) {

+    FlashMapEntryData = (EFI_FLASH_MAP_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);

+

+    //

+    // Get the variable store area

+    //

+    if ((FlashMapEntryData->AreaType == EFI_FLASH_AREA_RECOVERY_BIOS) ||

+        (FlashMapEntryData->AreaType == EFI_FLASH_AREA_MAIN_BIOS)

+        ) {

+      BdsLockFv (CpuIo, &(FlashMapEntryData->Entries[0]));

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+

+  return ;

+}

+

+EFI_STATUS

+ProcessCapsules (

+  EFI_BOOT_MODE BootMode

+  )

+/*++

+

+Routine Description:

+

+  This routine is called to see if there are any capsules we need to process.

+  If the boot mode is not UPDATE, then we do nothing. Otherwise find the

+  capsule HOBS and produce firmware volumes for them via the DXE service.

+  Then call the dispatcher to dispatch drivers from them. Finally, check

+  the status of the updates.

+

+Arguments:

+

+  BootMode - the current boot mode

+

+Returns:

+  

+  EFI_INVALID_PARAMETER - boot mode is not correct for an update

+

+Note:

+ 

+ This function should be called by BDS in case we need to do some

+ sort of processing even if there is no capsule to process. We

+ need to do this if an earlier update went awry and we need to

+ clear the capsule variable so on the next reset PEI does not see it and 

+ think there is a capsule available.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_HOB_CAPSULE_VOLUME      *CvHob;

+  EFI_PHYSICAL_ADDRESS        BaseAddress;

+  UINT64                      Length;

+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;

+  EFI_HANDLE                  FvProtocolHandle;

+

+  //

+  // We don't do anything else if the boot mode is not flash-update

+  //

+  if (BootMode != BOOT_ON_FLASH_UPDATE) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Only one capsule HOB allowed.

+  //

+  CvHob = GetFirstHob (EFI_HOB_TYPE_CV);

+  if (CvHob == NULL) {

+    //

+    // We didn't find a hob, so had no errors.

+    //

+    BdsLockNonUpdatableFlash ();

+    return EFI_SUCCESS;

+  }

+  

+  BaseAddress = CvHob->BaseAddress;

+  Length      = CvHob->Length;

+

+  Status      = EFI_SUCCESS;

+  //

+  // Now walk the capsule and call the core to process each

+  // firmware volume in it.

+  //

+  while (Length != 0) {

+    //

+    // Point to the next firmware volume header, and then

+    // call the DXE service to process it.

+    //

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;

+    if (FwVolHeader->FvLength > Length) {

+      //

+      // Notes: need to stuff this status somewhere so that the

+      // error can be detected at OS runtime

+      //

+      Status = EFI_VOLUME_CORRUPTED;

+      break;

+    }

+

+    Status = gDS->ProcessFirmwareVolume (

+                    (VOID *) (UINTN) BaseAddress,

+                    (UINTN) FwVolHeader->FvLength,

+                    &FvProtocolHandle

+                    );

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+    //

+    // Call the dispatcher to dispatch any drivers from the produced firmware volume

+    //

+    gDS->Dispatch ();

+    //

+    // On to the next FV in the capsule

+    //

+    Length -= FwVolHeader->FvLength;

+    BaseAddress = (EFI_PHYSICAL_ADDRESS) ((UINTN) BaseAddress + FwVolHeader->FvLength);

+    //

+    // Notes: when capsule spec is finalized, if the requirement is made to

+    // have each FV in a capsule aligned, then we will need to align the

+    // BaseAddress and Length here.

+    //

+  }

+   

+

+  BdsLockNonUpdatableFlash ();

+

+  return Status;

+}

+

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c
new file mode 100644
index 0000000..0e73a4e
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c
@@ -0,0 +1,482 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name: 

+

+  DeviceManager.c

+

+Abstract:

+

+  The platform device manager reference implement

+

+--*/

+#include "DeviceManager.h"

+

+STATIC UINT16                     mTokenCount;

+EFI_FRONTPAGE_CALLBACK_INFO       FPCallbackInfo;

+extern UINTN                      gCallbackKey;

+extern EFI_FORM_BROWSER_PROTOCOL  *gBrowser;

+extern EFI_GUID                   gBdsStringPackGuid;

+extern BOOLEAN                    gConnectAllHappened;

+

+STRING_REF                        gStringTokenTable[] = {

+  STR_VIDEO_DEVICE,

+  STR_NETWORK_DEVICE,

+  STR_INPUT_DEVICE,

+  STR_ON_BOARD_DEVICE,

+  STR_OTHER_DEVICE,

+  STR_EMPTY_STRING,

+  0xFFFF

+};

+

+EFI_STATUS

+EFIAPI

+DeviceManagerCallbackRoutine (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *DataArray,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+/*++

+

+Routine Description:

+

+  This is the function that is called to provide results data to the driver.  This data

+  consists of a unique key which is used to identify what data is either being passed back

+  or being asked for. 

+

+Arguments:

+

+  KeyValue -        A unique value which is sent to the original exporting driver so that it

+                    can identify the type of data to expect.  The format of the data tends to

+                    vary based on the op-code that geerated the callback.

+

+  Data -            A pointer to the data being sent to the original exporting driver.

+

+Returns: 

+

+--*/

+{

+  //

+  // The KeyValue corresponds in this case to the handle which was requested to be displayed

+  //

+  EFI_FRONTPAGE_CALLBACK_INFO *CallbackInfo;

+

+  CallbackInfo = EFI_FP_CALLBACK_DATA_FROM_THIS (This);

+  switch (KeyValue) {

+  case 0x2000:

+    CallbackInfo->Data.VideoBIOS = (UINT8) (UINTN) (((EFI_IFR_DATA_ENTRY *)(DataArray + 1))->Data);

+    gRT->SetVariable (

+          L"VBIOS",

+          &gEfiGlobalVariableGuid,

+          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+          sizeof (UINT8),

+          &CallbackInfo->Data.VideoBIOS

+          );

+    break;

+

+  default:

+    break;

+  }

+

+  gCallbackKey = KeyValue;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InitializeDeviceManager (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialize HII information for the FrontPage

+

+Arguments:

+  None

+            

+Returns:

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_HII_PACKAGES    *PackageList;

+  EFI_HII_UPDATE_DATA *UpdateData;

+

+  //

+  // Allocate space for creation of UpdateData Buffer

+  //

+  UpdateData = AllocateZeroPool (0x1000);

+  ASSERT (UpdateData != NULL);

+

+  PackageList = PreparePackages (1, &gBdsStringPackGuid, DeviceManagerVfrBin);

+  Status      = Hii->NewPack (Hii, PackageList, &FPCallbackInfo.DevMgrHiiHandle);

+  gBS->FreePool (PackageList);

+

+  //

+  // This example does not implement worker functions for the NV accessor functions.  Only a callback evaluator

+  //

+  FPCallbackInfo.Signature                = EFI_FP_CALLBACK_DATA_SIGNATURE;

+  FPCallbackInfo.DevMgrCallback.NvRead    = NULL;

+  FPCallbackInfo.DevMgrCallback.NvWrite   = NULL;

+  FPCallbackInfo.DevMgrCallback.Callback  = DeviceManagerCallbackRoutine;

+

+  //

+  // Install protocol interface

+  //

+  FPCallbackInfo.CallbackHandle = NULL;

+

+  Status = gBS->InstallProtocolInterface (

+                  &FPCallbackInfo.CallbackHandle,

+                  &gEfiFormCallbackProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &FPCallbackInfo.DevMgrCallback

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Flag update pending in FormSet

+  //

+  UpdateData->FormSetUpdate = TRUE;

+  //

+  // Register CallbackHandle data for FormSet

+  //

+  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FPCallbackInfo.CallbackHandle;

+  //

+  // Simply registering the callback handle

+  //

+  Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);

+

+  gBS->FreePool (UpdateData);

+  return Status;

+}

+

+EFI_STATUS

+CallDeviceManager (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Call the browser and display the device manager

+

+Arguments:

+  

+  None

+  

+Returns:

+  EFI_SUCCESS            - Operation is successful.

+  EFI_INVALID_PARAMETER  - If the inputs to SendForm function is not valid.

+  

+--*/

+{

+  EFI_STATUS          Status;

+  UINTN               BufferSize;

+  UINTN               Count;

+  EFI_HII_HANDLE      Index;

+  UINT8               *Buffer;

+  EFI_IFR_FORM_SET    *FormSetData;

+  CHAR16              *String;

+  UINTN               StringLength;

+  EFI_HII_UPDATE_DATA *UpdateData;

+  STRING_REF          Token;

+  STRING_REF          TokenHelp;

+  IFR_OPTION          *IfrOptionList;

+  UINT8               *VideoOption;

+  UINTN               VideoOptionSize;

+  EFI_HII_HANDLE      *HiiHandles;

+  UINT16              HandleBufferLength;

+

+  IfrOptionList       = NULL;

+  VideoOption         = NULL;

+  HandleBufferLength  = 0;

+

+  //

+  // Connect all prior to entering the platform setup menu.

+  //

+  if (!gConnectAllHappened) {

+    BdsLibConnectAllDriversToAllControllers ();

+    gConnectAllHappened = TRUE;

+  }

+  //

+  // Allocate space for creation of UpdateData Buffer

+  //

+  UpdateData = AllocateZeroPool (0x1000);

+  ASSERT (UpdateData != NULL);

+

+  Status        = EFI_SUCCESS;

+  Buffer        = NULL;

+  FormSetData   = NULL;

+  gCallbackKey  = 0;

+  if (mTokenCount == 0) {

+    Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &mTokenCount, L" ");

+  }

+

+  Token     = mTokenCount;

+  TokenHelp = (UINT16) (Token + 1);

+

+  //

+  // Reset the menu

+  //

+  for (Index = 0, Count = 1; Count < 0x10000; Count <<= 1, Index++) {

+    //

+    // We will strip off all previous menu entries

+    //

+    UpdateData->DataCount = 0xFF;

+

+    //

+    // Erase entries on this label

+    //

+    Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, FALSE, UpdateData);

+

+    //

+    // Did we reach the end of the Token Table?

+    //

+    if (gStringTokenTable[Index] == 0xFFFF) {

+      break;

+    }

+

+    CreateSubTitleOpCode (gStringTokenTable[Index], &UpdateData->Data);

+    //

+    // Add a single menu item - in this case a subtitle for the device type

+    //

+    UpdateData->DataCount = 1;

+

+    //

+    // Add default title for this label

+    //

+    Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);

+  }

+  //

+  // Add a space and an exit string.  Remember since we add things at the label and push other things beyond the

+  // label down, we add this in reverse order

+  //

+  CreateSubTitleOpCode (STRING_TOKEN (STR_EXIT_STRING), &UpdateData->Data);

+  Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);

+  CreateSubTitleOpCode (STR_EMPTY_STRING, &UpdateData->Data);

+  Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);

+

+  HiiHandles = AllocateZeroPool (HandleBufferLength);

+  Hii->FindHandles (Hii, &HandleBufferLength, HiiHandles);

+

+  for (Index = 1, BufferSize = 0; Index < HandleBufferLength; Index++) {

+    //

+    // Am not initializing Buffer since the first thing checked is the size

+    // this way I can get the real buffersize in the smallest code size

+    //

+    Status = Hii->GetForms (Hii, Index, 0, &BufferSize, Buffer);

+

+    if (Status != EFI_NOT_FOUND) {

+      //

+      // BufferSize should have the real size of the forms now

+      //

+      Buffer = AllocateZeroPool (BufferSize);

+      ASSERT (Buffer != NULL);

+

+      //

+      // Am not initializing Buffer since the first thing checked is the size

+      // this way I can get the real buffersize in the smallest code size

+      //

+      Status = Hii->GetForms (Hii, Index, 0, &BufferSize, Buffer);

+

+      //

+      // Skip EFI_HII_PACK_HEADER, advance to EFI_IFR_FORM_SET data.

+      //

+      FormSetData = (EFI_IFR_FORM_SET *) (Buffer + sizeof (EFI_HII_PACK_HEADER));

+

+      //

+      // If this formset belongs in the device manager, add it to the menu

+      //

+      if (FormSetData->Class != EFI_NON_DEVICE_CLASS) {

+

+        StringLength  = 0x1000;

+        String        = AllocateZeroPool (StringLength);

+        ASSERT (String != NULL);

+

+        Status  = Hii->GetString (Hii, Index, FormSetData->FormSetTitle, TRUE, NULL, &StringLength, String);

+        Status  = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &Token, String);

+

+        //

+        // If token value exceeded real token value - we need to add a new token values

+        //

+        if (Status == EFI_INVALID_PARAMETER) {

+          Token     = 0;

+          TokenHelp = 0;

+          Status    = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &Token, String);

+        }

+

+        StringLength = 0x1000;

+        if (FormSetData->Help == 0) {

+          TokenHelp = 0;

+        } else {

+          Status = Hii->GetString (Hii, Index, FormSetData->Help, TRUE, NULL, &StringLength, String);

+          if (StringLength == 0x02) {

+            TokenHelp = 0;

+          } else {

+            Status = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &TokenHelp, String);

+            if (Status == EFI_INVALID_PARAMETER) {

+              TokenHelp = 0;

+              Status    = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &TokenHelp, String);

+            }

+          }

+        }

+

+        gBS->FreePool (String);

+

+        CreateGotoOpCode (

+          0x1000,     // Device Manager Page

+          Token,      // Description String Token

+          TokenHelp,  // Description Help String Token

+          EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,  // Flag designating callback is active

+          (UINT16) Index,                                     // Callback key value

+          &UpdateData->Data                                   // Buffer to fill with op-code

+          );

+

+        //

+        // In the off-chance that we have lots of extra tokens allocated to the DeviceManager

+        // this ensures we are fairly re-using the tokens instead of constantly growing the token

+        // storage for this one handle.  If we incremented the token value beyond what it normally

+        // would use, we will fall back into the error path which seeds the token value with a 0

+        // so that we can correctly add a token value.

+        //

+        if (TokenHelp == 0) {

+          //

+          // Since we didn't add help, only advance Token by 1

+          //

+          Token++;

+        } else {

+          Token     = (UINT16) (Token + 2);

+          TokenHelp = (UINT16) (TokenHelp + 2);

+        }

+        //

+        // This for loop basically will take the Class value which is a bitmask and

+        // update the form for every active bit.  There will be a label at each bit

+        // location.  So if someone had a device which a class of EFI_DISK_DEVICE_CLASS |

+        // EFI_ON_BOARD_DEVICE_CLASS, this routine will unwind that mask and drop the menu entry

+        // on each corresponding label.

+        //

+        for (Count = 1; Count < 0x10000; Count <<= 1) {

+          //

+          // This is an active bit, so update the form

+          //

+          if (FormSetData->Class & Count) {

+            Hii->UpdateForm (

+                  Hii,

+                  FPCallbackInfo.DevMgrHiiHandle,

+                  (EFI_FORM_LABEL) (FormSetData->Class & Count),

+                  TRUE,

+                  UpdateData

+                  );

+          }

+        }

+      }

+

+      BufferSize = 0;

+      //

+      // Reset Buffer pointer to original location

+      //

+      gBS->FreePool (Buffer);

+    }

+  }

+  //

+  // Add oneof for video BIOS selection

+  //

+  VideoOption = BdsLibGetVariableAndSize (

+                  L"VBIOS",

+                  &gEfiGlobalVariableGuid,

+                  &VideoOptionSize

+                  );

+  if (NULL == VideoOption) {

+    FPCallbackInfo.Data.VideoBIOS = 0;

+  } else {

+    FPCallbackInfo.Data.VideoBIOS = VideoOption[0];

+    gBS->FreePool (VideoOption);

+  }

+

+  ASSERT (FPCallbackInfo.Data.VideoBIOS <= 1);

+

+  Status = gBS->AllocatePool (EfiBootServicesData, 2 * sizeof (IFR_OPTION), &IfrOptionList);

+  if (IfrOptionList != NULL) {

+    IfrOptionList[0].Flags        = EFI_IFR_FLAG_INTERACTIVE;

+    IfrOptionList[0].Key          = SET_VIDEO_BIOS_TYPE_QUESTION_ID + 0x2000;

+    IfrOptionList[0].StringToken  = STRING_TOKEN (STR_ONE_OF_PCI);

+    IfrOptionList[0].Value        = 0;

+    IfrOptionList[0].OptionString = NULL;

+    IfrOptionList[1].Flags        = EFI_IFR_FLAG_INTERACTIVE;

+    IfrOptionList[1].Key          = SET_VIDEO_BIOS_TYPE_QUESTION_ID + 0x2000;

+    IfrOptionList[1].StringToken  = STRING_TOKEN (STR_ONE_OF_AGP);

+    IfrOptionList[1].Value        = 1;

+    IfrOptionList[1].OptionString = NULL;

+    IfrOptionList[FPCallbackInfo.Data.VideoBIOS].Flags |= EFI_IFR_FLAG_DEFAULT;

+

+    CreateOneOfOpCode (

+      SET_VIDEO_BIOS_TYPE_QUESTION_ID,

+      (UINT8) 1,

+      STRING_TOKEN (STR_ONE_OF_VBIOS),

+      STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),

+      IfrOptionList,

+      2,

+      &UpdateData->Data

+      );

+

+    UpdateData->DataCount = 4;

+    Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) EFI_VBIOS_CLASS, TRUE, UpdateData);

+    gBS->FreePool (IfrOptionList);

+  }

+

+  Status = gBrowser->SendForm (

+                      gBrowser,

+                      TRUE,                             // Use the database

+                      &FPCallbackInfo.DevMgrHiiHandle,  // The HII Handle

+                      1,

+                      NULL,

+                      FPCallbackInfo.CallbackHandle,

+                      (UINT8 *) &FPCallbackInfo.Data,

+                      NULL,

+                      NULL

+                      );

+

+  Hii->ResetStrings (Hii, FPCallbackInfo.DevMgrHiiHandle);

+

+  //

+  // We will have returned from processing a callback - user either hit ESC to exit, or selected

+  // a target to display

+  //

+  if (gCallbackKey != 0 && gCallbackKey < 0x2000) {

+    Status = gBrowser->SendForm (

+                        gBrowser,

+                        TRUE,                             // Use the database

+                        (EFI_HII_HANDLE *) &gCallbackKey, // The HII Handle

+                        1,

+                        NULL,

+                        NULL,                             // This is the handle that the interface to the callback was installed on

+                        NULL,

+                        NULL,

+                        NULL

+                        );

+

+    //

+    // Force return to Device Manager

+    //

+    gCallbackKey = 4;

+  }

+

+  if (gCallbackKey >= 0x2000) {

+    gCallbackKey = 4;

+  }

+

+  gBS->FreePool (UpdateData);

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.h
new file mode 100644
index 0000000..dd6d935
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.h
@@ -0,0 +1,59 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name: 

+

+  DeviceManager.c

+

+Abstract:

+

+  The platform device manager reference implement

+

+Revision History

+

+--*/

+

+#ifndef _DEVICE_MANAGER_H

+#define _DEVICE_MANAGER_H

+

+#include "Generic/FrontPage.h"

+

+#define EFI_NON_DEVICE_CLASS              0x00  // Useful when you do not want something in the Device Manager

+#define EFI_DISK_DEVICE_CLASS             0x01

+#define EFI_VIDEO_DEVICE_CLASS            0x02

+#define EFI_NETWORK_DEVICE_CLASS          0x04

+#define EFI_INPUT_DEVICE_CLASS            0x08

+#define EFI_ON_BOARD_DEVICE_CLASS         0x10

+#define EFI_OTHER_DEVICE_CLASS            0x20

+

+EFI_STATUS

+EFIAPI

+DeviceManagerCallbackRoutine (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *DataArray,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+;

+

+EFI_STATUS

+InitializeDeviceManager (

+  VOID

+  )

+;

+

+EFI_STATUS

+CallDeviceManager (

+  VOID

+  )

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManagerStrings.uni b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManagerStrings.uni
new file mode 100644
index 0000000..f549ff2
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManagerStrings.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManagerVfr.Vfr b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManagerVfr.Vfr
new file mode 100644
index 0000000..5497c6d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManagerVfr.Vfr
@@ -0,0 +1,75 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   DeviceManagerVfr.vfr 

+// 

+// Abstract:

+// 

+//   Device Manager formset.

+// 

+// Revision History: 

+// 

+// --*/

+

+#include "BdsStrDefs.h"

+

+#define FORMSET_GUID  { 0x3ebfa8e6, 0x511d, 0x4b5b, { 0xa9, 0x5f, 0xfb, 0x38, 0x26, 0xf, 0x1c, 0x27 } }

+

+#define EFI_DISK_DEVICE_CLASS              0x01

+#define EFI_VIDEO_DEVICE_CLASS             0x02

+#define EFI_NETWORK_DEVICE_CLASS           0x04

+#define EFI_INPUT_DEVICE_CLASS             0x08

+#define EFI_ON_BOARD_DEVICE_CLASS          0x10

+#define EFI_OTHER_DEVICE_CLASS             0x20

+#define EFI_VBIOS_CLASS                    0x40

+

+#define DEVICE_MANAGER_CLASS               0x0000

+#define FRONT_PAGE_SUBCLASS		             0x0003

+

+formset 

+  guid     = FORMSET_GUID,

+  title    = STRING_TOKEN(STR_DEVICE_MANAGER_TITLE),  

+  help     = STRING_TOKEN(STR_EMPTY_STRING),

+  class    = DEVICE_MANAGER_CLASS,      

+  subclass = FRONT_PAGE_SUBCLASS,

+

+  form formid = 0x1000,

+       title  = STRING_TOKEN(STR_DEVICE_MANAGER_TITLE);

+

+    //

+    // This is where devices get added to the device manager hierarchy

+    //

+    subtitle text = STRING_TOKEN(STR_DISK_DEVICE);

+    label EFI_DISK_DEVICE_CLASS;

+

+    subtitle text = STRING_TOKEN(STR_VIDEO_DEVICE);

+    label EFI_VIDEO_DEVICE_CLASS;

+

+    subtitle text = STRING_TOKEN(STR_NETWORK_DEVICE);

+    label EFI_NETWORK_DEVICE_CLASS;

+

+    subtitle text = STRING_TOKEN(STR_INPUT_DEVICE);

+    label EFI_INPUT_DEVICE_CLASS;

+

+    subtitle text = STRING_TOKEN(STR_ON_BOARD_DEVICE);

+    label EFI_ON_BOARD_DEVICE_CLASS;

+

+    subtitle text = STRING_TOKEN(STR_OTHER_DEVICE);

+    label EFI_OTHER_DEVICE_CLASS;

+    

+    subtitle text = STRING_TOKEN(STR_EMPTY_STRING);

+    label EFI_VBIOS_CLASS;

+    

+  endform;

+endformset;

+

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c
new file mode 100644
index 0000000..69b2fb5
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c
@@ -0,0 +1,888 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FrontPage.c

+

+Abstract:

+

+  FrontPage routines to handle the callbacks and browser calls

+  

+--*/

+

+#include "Bds.h"

+#include "BdsPlatform.h"

+#include "FrontPage.h"

+#include "String.h"

+

+EFI_GUID                    mProcessorSubClass  = EFI_PROCESSOR_SUBCLASS_GUID;

+EFI_GUID                    mMemorySubClass     = EFI_MEMORY_SUBCLASS_GUID;

+EFI_GUID                    mMiscSubClass       = EFI_MISC_SUBCLASS_GUID;

+

+UINT16                      mLastSelection;

+EFI_HII_HANDLE              gFrontPageHandle;

+EFI_HANDLE                  FrontPageCallbackHandle;

+EFI_FORM_CALLBACK_PROTOCOL  FrontPageCallback;

+EFI_FORM_BROWSER_PROTOCOL   *gBrowser;

+UINTN                       gCallbackKey;

+BOOLEAN                     gConnectAllHappened = FALSE;

+

+extern EFI_HII_HANDLE       gFrontPageHandle;

+extern EFI_GUID             gBdsStringPackGuid;

+

+EFI_STATUS

+EFIAPI

+FrontPageCallbackRoutine (

+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,

+  IN UINT16                           KeyValue,

+  IN EFI_IFR_DATA_ARRAY               *DataArray,

+  OUT EFI_HII_CALLBACK_PACKET         **Packet

+  )

+/*++

+

+Routine Description:

+

+  This is the function that is called to provide results data to the driver.  This data

+  consists of a unique key which is used to identify what data is either being passed back

+  or being asked for. 

+

+Arguments:

+

+  KeyValue -        A unique value which is sent to the original exporting driver so that it

+                    can identify the type of data to expect.  The format of the data tends to

+                    vary based on the op-code that geerated the callback.

+

+  Data -            A pointer to the data being sent to the original exporting driver.

+

+Returns: 

+

+--*/

+{

+  CHAR16        *LanguageString;

+  UINTN         Count;

+  CHAR16        UnicodeLang[3];

+  CHAR8         Lang[3];

+  EFI_STATUS    Status;

+  UINTN         Index;

+  CHAR16        *TmpStr;

+  EFI_UGA_PIXEL Foreground;

+  EFI_UGA_PIXEL Background;

+  EFI_UGA_PIXEL Color;

+

+  SetMem (&Foreground, sizeof (EFI_UGA_PIXEL), 0xff);

+  SetMem (&Background, sizeof (EFI_UGA_PIXEL), 0x0);

+  SetMem (&Color, sizeof (EFI_UGA_PIXEL), 0xff);

+

+  Count = 0;

+

+  //

+  // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can

+  // describe to their customers in documentation how to find their setup information (namely

+  // under the device manager and specific buckets)

+  //

+  switch (KeyValue) {

+  case 0x0001:

+    //

+    // This is the continue - clear the screen and return an error to get out of FrontPage loop

+    //

+    gCallbackKey = 1;

+    break;

+

+  case 0x1234:

+    //

+    // Collect the languages from what our current Language support is based on our VFR

+    //

+    Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);

+

+    //

+    // Based on the DataArray->Data->Data value, we can determine

+    // which language was chosen by the user

+    //

+    for (Index = 0; Count != (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray + 1))->Data); Index += 3) {

+      Count++;

+    }

+    //

+    // Preserve the choice the user made

+    //

+    mLastSelection = (UINT16) Count;

+

+    //

+    // The Language (in Unicode format) the user chose

+    //

+    CopyMem (UnicodeLang, &LanguageString[Index], 6);

+

+    //

+    // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations

+    // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.

+    //

+    for (Index = 0; Index < 3; Index++) {

+      Lang[Index] = (CHAR8) UnicodeLang[Index];

+    }

+

+    Status = gRT->SetVariable (

+                    L"Lang",

+                    &gEfiGlobalVariableGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    3,

+                    Lang

+                    );

+

+    gBS->FreePool (LanguageString);

+    gCallbackKey = 2;

+    break;

+

+  case 0x1064:

+    //

+    // Boot Manager

+    //

+    gCallbackKey = 3;

+    break;

+

+  case 0x8567:

+    //

+    // Device Manager

+    //

+    gCallbackKey = 4;

+    break;

+

+  case 0x9876:

+    //

+    // Boot Maintenance Manager

+    //

+    gCallbackKey = 5;

+    break;

+

+  case 0xFFFE:

+

+    break;

+

+  case 0xFFFF:

+    //

+    // FrontPage TimeOut Callback

+    //

+    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));

+    if (TmpStr != NULL) {

+      PlatformBdsShowProgress (

+        Foreground,

+        Background,

+        TmpStr,

+        Color,

+        (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray+1))->Data),

+        0

+        );

+      gBS->FreePool (TmpStr);

+    }

+    break;

+

+  default:

+    gCallbackKey = 0;

+    break;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+InitializeFrontPage (

+  BOOLEAN                         ReInitializeStrings

+  )

+/*++

+

+Routine Description:

+  

+  Initialize HII information for the FrontPage

+

+Arguments:

+  None

+            

+Returns:

+  EFI_SUCCESS       - The operation is successful.

+  EFI_DEVICE_ERROR  - If the dynamic opcode creation failed.

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_HII_PACKAGES    *PackageList;

+  EFI_HII_UPDATE_DATA *UpdateData;

+  IFR_OPTION          *OptionList;

+  CHAR16              *LanguageString;

+  UINTN               OptionCount;

+  UINTN               Index;

+  STRING_REF          Token;

+  UINT16              Key;

+  CHAR8               AsciiLang[4];

+  CHAR16              UnicodeLang[4];

+  CHAR16              Lang[4];

+  CHAR16              *StringBuffer;

+  UINTN               BufferSize;

+  UINT8               *TempBuffer;

+

+  UpdateData  = NULL;

+  OptionList  = NULL;

+

+  if (ReInitializeStrings) {

+    //

+    // BugBug: Dont' use a goto

+    //

+    goto ReInitStrings;

+  }

+  //

+  // Go ahead and initialize the Device Manager

+  //

+  InitializeDeviceManager ();

+

+  //

+  // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here

+  //

+  TempBuffer    = (UINT8 *) FrontPageVfrBin;

+  TempBuffer    = TempBuffer + sizeof (EFI_HII_PACK_HEADER);

+  TempBuffer    = (UINT8 *) &((EFI_IFR_FORM_SET *) TempBuffer)->NvDataSize;

+  *TempBuffer   = 1;

+

+  gCallbackKey  = 0;

+

+  PackageList   = PreparePackages (1, &gBdsStringPackGuid, FrontPageVfrBin);

+

+  Status        = Hii->NewPack (Hii, PackageList, &gFrontPageHandle);

+

+  gBS->FreePool (PackageList);

+

+  //

+  // There will be only one FormConfig in the system

+  // If there is another out there, someone is trying to install us

+  // again.  Fail that scenario.

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiFormBrowserProtocolGuid,

+                  NULL,

+                  &gBrowser

+                  );

+

+  //

+  // This example does not implement worker functions

+  // for the NV accessor functions.  Only a callback evaluator

+  //

+  FrontPageCallback.NvRead    = NULL;

+  FrontPageCallback.NvWrite   = NULL;

+  FrontPageCallback.Callback  = FrontPageCallbackRoutine;

+

+  //

+  // Install protocol interface

+  //

+  FrontPageCallbackHandle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &FrontPageCallbackHandle,

+                  &gEfiFormCallbackProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &FrontPageCallback

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+ReInitStrings:

+  //

+  // BugBug: This logic is in BdsInitLanguage. It should not be in two places!

+  //

+  BufferSize = 4;

+  Status = gRT->GetVariable (

+                  L"Lang",

+                  &gEfiGlobalVariableGuid,

+                  NULL,

+                  &BufferSize,

+                  AsciiLang

+                  );

+

+  for (Index = 0; Index < 3; Index++) {

+    UnicodeLang[Index] = (CHAR16) AsciiLang[Index];

+  }

+

+  UnicodeLang[3] = 0;

+

+  //

+  // Allocate space for creation of UpdateData Buffer

+  //

+  UpdateData = AllocateZeroPool (0x1000);

+  ASSERT (UpdateData != NULL);

+

+  OptionList = AllocateZeroPool (0x1000);

+  ASSERT (OptionList != NULL);

+

+  //

+  // Flag update pending in FormSet

+  //

+  UpdateData->FormSetUpdate = TRUE;

+  //

+  // Register CallbackHandle data for FormSet

+  //

+  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FrontPageCallbackHandle;

+  UpdateData->FormUpdate  = FALSE;

+  UpdateData->FormTitle   = 0;

+  UpdateData->DataCount   = 1;

+

+  //

+  // Collect the languages from what our current Language support is based on our VFR

+  //

+  Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);

+

+  OptionCount = 0;

+

+  //

+  // Try for a 512 byte Buffer

+  //

+  BufferSize = 0x200;

+

+  //

+  // Allocate memory for our Form binary

+  //

+  StringBuffer = AllocateZeroPool (BufferSize);

+  ASSERT (StringBuffer != NULL);

+

+  for (Index = 0; LanguageString[Index] != 0; Index += 3) {

+    Token = 0;

+    CopyMem (Lang, &LanguageString[Index], 6);

+    Lang[3] = 0;

+

+    if (!StrCmp (Lang, UnicodeLang)) {

+      mLastSelection = (UINT16) OptionCount;

+    }

+

+    Status = Hii->GetString (Hii, gStringPackHandle, 1, TRUE, Lang, &BufferSize, StringBuffer);

+    Hii->NewString (Hii, NULL, gStringPackHandle, &Token, StringBuffer);

+    CopyMem (&OptionList[OptionCount].StringToken, &Token, sizeof (UINT16));

+    CopyMem (&OptionList[OptionCount].Value, &OptionCount, sizeof (UINT16));

+    Key = 0x1234;

+    CopyMem (&OptionList[OptionCount].Key, &Key, sizeof (UINT16));

+    OptionList[OptionCount].Flags = EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS;

+    OptionCount++;

+  }

+

+  gBS->FreePool (LanguageString);

+

+  if (ReInitializeStrings) {

+    gBS->FreePool (StringBuffer);

+    gBS->FreePool (OptionList);

+    return EFI_SUCCESS;

+  }

+

+  Status = CreateOneOfOpCode (

+            FRONT_PAGE_QUESTION_ID,                               // Question ID

+            FRONT_PAGE_DATA_WIDTH,                                // Data Width

+            (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT),      // Prompt Token

+            (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), // Help Token

+            OptionList,       // List of Options

+            OptionCount,      // Number of Options

+            &UpdateData->Data // Data Buffer

+            );

+

+  //

+  // Assign the number of options and the oneof and endoneof op-codes to count

+  //

+  UpdateData->DataCount = (UINT8) (OptionCount + 2);

+

+  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);

+

+  gBS->FreePool (UpdateData);

+  //

+  // gBS->FreePool (OptionList);

+  //

+  gBS->FreePool (StringBuffer);

+  return Status;

+}

+

+EFI_STATUS

+CallFrontPage (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Call the browser and display the front page

+

+Arguments:

+  

+  None

+  

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       FakeNvRamMap[1];

+

+  //

+  // Begin waiting for USER INPUT

+  //

+  REPORT_STATUS_CODE (

+        EFI_PROGRESS_CODE,

+        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)

+        );

+

+  FakeNvRamMap[0] = (UINT8) mLastSelection;

+  Status = gBrowser->SendForm (

+                      gBrowser,

+                      TRUE,                     // Use the database

+                      &gFrontPageHandle,        // The HII Handle

+                      1,

+                      NULL,

+                      FrontPageCallbackHandle,  // This is the handle that the interface to the callback was installed on

+                      FakeNvRamMap,

+                      NULL,

+                      NULL

+                      );

+

+  Hii->ResetStrings (Hii, gFrontPageHandle);

+

+  return Status;

+}

+

+EFI_STATUS

+GetStringFromToken (

+  IN      EFI_GUID                  *ProducerGuid,

+  IN      STRING_REF                Token,

+  OUT     CHAR16                    **String

+  )

+/*++

+

+Routine Description:

+  

+  Acquire the string associated with the ProducerGuid and return it.

+

+Arguments:

+  

+  ProducerGuid - The Guid to search the HII database for

+  Token - The token value of the string to extract

+  String - The string that is extracted

+  

+Returns:

+

+  EFI_SUCCESS - The function returns EFI_SUCCESS always.

+

+--*/

+{

+  EFI_STATUS      Status;

+  UINT16          HandleBufferLength;

+  EFI_HII_HANDLE  *HiiHandleBuffer;

+  UINTN           StringBufferLength;

+  UINTN           NumberOfHiiHandles;

+  UINTN           Index;

+  UINT16          Length;

+  EFI_GUID        HiiGuid;

+

+  HandleBufferLength  = 0x1000;

+  HiiHandleBuffer     = NULL;

+

+  //

+  // Get all the Hii handles

+  //

+  HiiHandleBuffer = AllocateZeroPool (HandleBufferLength);

+

+  Status          = Hii->FindHandles (Hii, &HandleBufferLength, HiiHandleBuffer);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get the Hii Handle that matches the StructureNode->ProducerName

+  //

+  NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);

+  for (Index = 0; Index < NumberOfHiiHandles; Index++) {

+    Length = 0;

+    Status = ExtractDataFromHiiHandle (

+              HiiHandleBuffer[Index],

+              &Length,

+              NULL,

+              &HiiGuid

+              );

+    if (CompareGuid (ProducerGuid, &HiiGuid)) {

+      break;

+    }

+  }

+  //

+  // Find the string based on the current language

+  //

+  StringBufferLength  = 0x100;

+  *String             = AllocateZeroPool (0x100);

+  Status = Hii->GetString (

+                  Hii,

+                  HiiHandleBuffer[Index],

+                  Token,

+                  FALSE,

+                  NULL,

+                  &StringBufferLength,

+                  *String

+                  );

+

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (*String);

+    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));

+  }

+

+  gBS->FreePool (HiiHandleBuffer);

+  return EFI_SUCCESS;

+}

+

+VOID

+ConvertProcessorToString (

+  IN  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,

+  OUT CHAR16                            **String

+  )

+/*++

+

+Routine Description:

+  

+  Convert Processor Frequency Data to a string

+

+Arguments:

+  

+  ProcessorFrequency - The frequency data to process

+  String - The string that is created

+  

+Returns:

+

+--*/

+{

+  CHAR16  *StringBuffer;

+  UINTN   Index;

+  UINT32  FreqMhz;

+

+  if (ProcessorFrequency->Exponent >= 6) {

+    FreqMhz = ProcessorFrequency->Value;

+    for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {

+      FreqMhz *= 10;

+    }

+  } else {

+    FreqMhz = 0;

+  }

+

+  StringBuffer = AllocateZeroPool (0x20);

+  ASSERT (StringBuffer != NULL);

+  Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);

+  StrCat (StringBuffer, L".");

+  UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);

+  StrCat (StringBuffer, L" GHz");

+

+  *String = (CHAR16 *) StringBuffer;

+

+  return ;

+}

+

+VOID

+ConvertMemorySizeToString (

+  IN  UINT32          MemorySize,

+  OUT CHAR16          **String

+  )

+/*++

+

+Routine Description:

+  

+  Convert Memory Size to a string

+

+Arguments:

+  

+  MemorySize - The size of the memory to process

+  String - The string that is created

+  

+Returns:

+

+--*/

+{

+  CHAR16  *StringBuffer;

+

+  StringBuffer = AllocateZeroPool (0x20);

+  ASSERT (StringBuffer != NULL);

+  UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);

+  StrCat (StringBuffer, L" MB RAM");

+

+  *String = (CHAR16 *) StringBuffer;

+

+  return ;

+}

+

+VOID

+UpdateFrontPageStrings (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Update the banner information for the Front Page based on DataHub information

+

+Arguments:

+  

+  None

+  

+Returns:

+

+--*/

+{

+  EFI_STATUS                        Status;

+  STRING_REF                        TokenToUpdate;

+  CHAR16                            *NewString;

+  UINT64                            MonotonicCount;

+  EFI_DATA_HUB_PROTOCOL             *DataHub;

+  EFI_DATA_RECORD_HEADER            *Record;

+  EFI_SUBCLASS_TYPE1_HEADER         *DataHeader;

+  EFI_MISC_BIOS_VENDOR_DATA         *BiosVendor;

+  EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemManufacturer;

+  EFI_PROCESSOR_VERSION_DATA        *ProcessorVersion;

+  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;

+  EFI_MEMORY_ARRAY_START_ADDRESS_DATA *MemoryArray;

+  CHAR8                             LangCode[3];

+  CHAR16                            Lang[3];

+  UINTN                             Size;

+  UINTN                             Index;

+  BOOLEAN                           Find[5];

+

+  ZeroMem (Find, sizeof (Find));

+

+  //

+  // Update Front Page strings

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiDataHubProtocolGuid,

+                  NULL,

+                  &DataHub

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  Size = 3;

+

+  Status = gRT->GetVariable (

+                  L"Lang",

+                  &gEfiGlobalVariableGuid,

+                  NULL,

+                  &Size,

+                  LangCode

+                  );

+

+  for (Index = 0; Index < 3; Index++) {

+    Lang[Index] = (CHAR16) LangCode[Index];

+  }

+

+  MonotonicCount  = 0;

+  Record          = NULL;

+  do {

+    Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);

+    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {

+      DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);

+      if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&

+          (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)

+          ) {

+        BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);

+        GetStringFromToken (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);

+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_BIOS_VERSION;

+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);

+        gBS->FreePool (NewString);

+        Find[0] = TRUE;

+      }

+

+      if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&

+          (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)

+          ) {

+        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);

+        GetStringFromToken (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);

+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_COMPUTER_MODEL;

+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);

+        gBS->FreePool (NewString);

+        Find[1] = TRUE;

+      }

+

+      if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&

+          (DataHeader->RecordType == ProcessorVersionRecordType)

+          ) {

+        ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);

+        GetStringFromToken (&Record->ProducerName, *ProcessorVersion, &NewString);

+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_MODEL;

+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);

+        gBS->FreePool (NewString);

+        Find[2] = TRUE;

+      }

+

+      if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&

+          (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)

+          ) {

+        ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);

+        ConvertProcessorToString (ProcessorFrequency, &NewString);

+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_SPEED;

+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);

+        gBS->FreePool (NewString);

+        Find[3] = TRUE;

+      }

+

+      if (CompareGuid (&Record->DataRecordGuid, &mMemorySubClass) &&

+          (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)

+          ) {

+        MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);

+        ConvertMemorySizeToString((UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - 

+                                  MemoryArray->MemoryArrayStartAddress + 1), 20)),

+                                  &NewString);

+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_MEMORY_SIZE;

+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);

+        gBS->FreePool (NewString);

+        Find[4] = TRUE;

+      }

+    }

+  } while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));

+

+  return ;

+}

+

+VOID

+PlatformBdsEnterFrontPage (

+  IN UINT16                       TimeoutDefault,

+  IN BOOLEAN                      ConnectAllHappened

+  )

+/*++

+

+Routine Description:

+  This function is the main entry of the platform setup entry.

+  The function will present the main menu of the system setup, 

+  this is the platform reference part and can be customize.

+  

+Arguments:

+  TimeoutDefault     - The fault time out value before the system

+                       continue to boot.

+  ConnectAllHappened - The indicater to check if the connect all have

+                       already happended.

+  

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_HII_UPDATE_DATA           *UpdateData;

+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;

+

+  //

+  // Indicate if we need connect all in the platform setup

+  //

+  if (ConnectAllHappened) {

+    gConnectAllHappened = TRUE;

+  }

+  //

+  // Allocate space for creation of Buffer

+  //

+  UpdateData = AllocateZeroPool (0x1000);

+  ASSERT (UpdateData != NULL);

+

+  UpdateData->FormSetUpdate       = FALSE;

+  UpdateData->FormCallbackHandle  = 0;

+  UpdateData->FormUpdate          = FALSE;

+  UpdateData->FormTitle           = 0;

+  UpdateData->DataCount           = 1;

+

+  //

+  // Remove Banner Op-code if any at this label

+  //

+  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, FALSE, UpdateData);

+

+  //

+  // Create Banner Op-code which reflects correct timeout value

+  //

+  CreateBannerOpCode (

+    STRING_TOKEN (STR_TIME_OUT_PROMPT),

+    TimeoutDefault,

+    (UINT8) EFI_IFR_BANNER_TIMEOUT,

+    &UpdateData->Data

+    );

+

+  //

+  // Add Banner Op-code at this label

+  //

+  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, TRUE, UpdateData);

+

+  do {

+

+    InitializeFrontPage (TRUE);

+

+    //

+    // Update Front Page strings

+    //

+    UpdateFrontPageStrings ();

+

+    gCallbackKey = 0;

+    PERF_START (0, "BdsTimeOut", "BDS", 0);

+    Status = CallFrontPage ();

+    PERF_END (0, "BdsTimeOut", "BDS", 0);

+

+    //

+    // If gCallbackKey is greater than 1 and less or equal to 5,

+    // it will lauch configuration utilities.

+    // 2 = set language

+    // 3 = boot manager

+    // 4 = device manager

+    // 5 = boot maintainenance manager

+    //

+    if ((gCallbackKey > 0x0001) && (gCallbackKey <= 0x0005)) {

+      REPORT_STATUS_CODE (

+            EFI_PROGRESS_CODE,

+            (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)

+            );

+    }

+    //

+    // Based on the key that was set, we can determine what to do

+    //

+    switch (gCallbackKey) {

+    //

+    // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can

+    // describe to their customers in documentation how to find their setup information (namely

+    // under the device manager and specific buckets)

+    //

+    // These entries consist of the Continue, Select language, Boot Manager, and Device Manager

+    //

+    case 0x0001:

+      //

+      // User hit continue

+      //

+      break;

+

+    case 0x0002:

+      //

+      // User made a language setting change - display front page again

+      //

+      break;

+

+    case 0x0003:

+      //

+      // User chose to run the Boot Manager

+      //

+      CallBootManager ();

+      break;

+

+    case 0x0004:

+      //

+      // Display the Device Manager

+      //

+      do {

+        CallDeviceManager();

+      } while (gCallbackKey == 4);

+      break;

+

+    case 0x0005:

+      //

+      // Display the Boot Maintenance Manager

+      //

+      BdsStartBootMaint ();

+      break;

+    }

+

+  } while ((Status == EFI_SUCCESS) && (gCallbackKey != 1));

+

+  //

+  // Automatically load current entry

+  // Note: The following lines of code only execute when Auto boot

+  // takes affect

+  //

+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl);

+  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);

+

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.h
new file mode 100644
index 0000000..82aa380
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.h
@@ -0,0 +1,100 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FrontPage.h

+

+Abstract:

+

+  FrontPage routines to handle the callbacks and browser calls

+

+Revision History

+

+--*/

+

+#ifndef _FRONT_PAGE_H

+#define _FRONT_PAGE_H

+

+#include "Generic/DeviceMngr/DeviceManager.h"

+#include "Generic/BootMaint/bootmaint.h"

+#include "Generic/BootMngr/BootManager.h"

+

+//

+// This is the VFR compiler generated header file which defines the

+// string identifiers.

+//

+#include "BdsStrDefs.h"

+#define EFI_DISK_DEVICE_CLASS           0x01

+#define EFI_VIDEO_DEVICE_CLASS          0x02

+#define EFI_NETWORK_DEVICE_CLASS        0x04

+#define EFI_INPUT_DEVICE_CLASS          0x08

+#define EFI_ON_BOARD_DEVICE_CLASS       0x10

+#define EFI_OTHER_DEVICE_CLASS          0x20

+#define EFI_VBIOS_CLASS                 0x40

+

+#define SET_VIDEO_BIOS_TYPE_QUESTION_ID 0x00

+

+#pragma pack(1)

+typedef struct {

+  UINT8 VideoBIOS;

+} MyDevMgrIfrNVData;

+#pragma pack()

+

+#define EFI_FP_CALLBACK_DATA_SIGNATURE  EFI_SIGNATURE_32 ('F', 'P', 'C', 'B')

+#define EFI_FP_CALLBACK_DATA_FROM_THIS(a) \

+  CR (a, \

+      EFI_FRONTPAGE_CALLBACK_INFO, \

+      DevMgrCallback, \

+      EFI_FP_CALLBACK_DATA_SIGNATURE \

+      )

+

+typedef struct {

+  UINTN                       Signature;

+  MyDevMgrIfrNVData           Data;

+  EFI_HII_HANDLE              DevMgrHiiHandle;

+  EFI_HANDLE                  CallbackHandle;

+  EFI_FORM_CALLBACK_PROTOCOL  DevMgrCallback;

+} EFI_FRONTPAGE_CALLBACK_INFO;

+

+//

+// These are the VFR compiler generated data representing our VFR data.

+//

+// BugBug: we should put g in front of these tool generated globals.

+//         maybe even gVrf would be a better prefix

+//

+extern UINT8  FrontPageVfrBin[];

+extern UINT8  FrontPageStringsStr[];

+extern UINT8  DeviceManagerVfrBin[];

+extern UINT8  DeviceManagerStringsStr[];

+

+#define FRONT_PAGE_QUESTION_ID  0x0000

+#define FRONT_PAGE_DATA_WIDTH   0x01

+

+EFI_STATUS

+InitializeFrontPage (

+  IN BOOLEAN    ReInitializeStrings

+  );

+

+BOOLEAN

+TimeCompare (

+  IN EFI_TIME               *FirstTime,

+  IN EFI_TIME               *SecondTime

+  );

+

+VOID

+PlatformBdsEnterFrontPage (

+  IN UINT16                 TimeoutDefault,

+  IN BOOLEAN                ConnectAllHappened

+  );

+

+#endif // _FRONT_PAGE_H_

+

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPageStrings.uni b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPageStrings.uni
new file mode 100644
index 0000000..76dbdcf
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPageStrings.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPageVfr.Vfr b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPageVfr.Vfr
new file mode 100644
index 0000000..77efd2d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPageVfr.Vfr
@@ -0,0 +1,159 @@
+// *++

+//

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//   FrontPageVfr.vfr 

+// 

+// Abstract:

+// 

+//   Browser formset.

+// 

+// Revision History: 

+// 

+// --*/

+

+#include "BdsStrDefs.h"

+

+#define FORMSET_GUID  { 0x9e0c30bc, 0x3f06, 0x4ba6, { 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe } }

+

+#define FRONT_PAGE_ITEM_ONE    0x0001

+#define FRONT_PAGE_ITEM_TWO    0x0002

+#define FRONT_PAGE_ITEM_THREE  0x0003

+#define FRONT_PAGE_ITEM_FOUR   0x0004

+#define FRONT_PAGE_ITEM_FIVE   0x0005

+

+#define FRONT_PAGE_TIMEOUT     0xFFFF

+#define FRONT_PAGE_CLASS       0x0000

+#define FRONT_PAGE_SUBCLASS    0x0002

+

+formset 

+  guid     = FORMSET_GUID,

+  title    = STRING_TOKEN(STR_FRONT_PAGE_TITLE),  

+  help     = STRING_TOKEN(STR_NULL_STRING),

+  class    = FRONT_PAGE_CLASS,      

+  subclass = FRONT_PAGE_SUBCLASS,

+

+  form formid = 0x1000,

+       title  = STRING_TOKEN(STR_FRONT_PAGE_TITLE);

+

+    banner 

+      title = STRING_TOKEN(STR_FRONT_PAGE_COMPUTER_MODEL),

+      line  0,

+      align left;

+    

+    banner 

+      title = STRING_TOKEN(STR_FRONT_PAGE_CPU_MODEL),

+      line  1,

+      align left;

+    

+    banner 

+      title = STRING_TOKEN(STR_FRONT_PAGE_CPU_SPEED),

+      line  1,

+      align right;

+    

+    banner 

+      title = STRING_TOKEN(STR_FRONT_PAGE_BIOS_VERSION),

+      line  2,

+      align left;

+    

+    banner 

+      title = STRING_TOKEN(STR_FRONT_PAGE_MEMORY_SIZE),

+      line  2,

+      align right;

+

+//    banner 

+//      title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_0_LEFT),

+//      line  0,

+//      align left;

+    

+//    banner 

+//      title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_0_RIGHT),

+//      line  0,

+//      align right;

+    

+//    banner 

+//      title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_1_LEFT),

+//      line  1,

+//      align left;

+    

+//    banner 

+//      title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_1_RIGHT),

+//      line  1,

+//      align right;

+    

+//    banner 

+//      title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_2_LEFT),

+//      line  2,

+//      align left;

+    

+//    banner 

+//      title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_3_LEFT),

+//      line  3,

+//      align left;

+

+    goto FRONT_PAGE_ITEM_ONE, 

+      prompt  = STRING_TOKEN(STR_CONTINUE_PROMPT), 

+      help    = STRING_TOKEN(STR_CONTINUE_HELP),

+      flags   = INTERACTIVE | NV_ACCESS, 

+      key     = 0x0001;

+

+    label FRONT_PAGE_ITEM_TWO;

+    //

+    // This is where we will dynamically add a OneOf type op-code to select Languages from the

+    // currently available choices

+    //

+

+    goto FRONT_PAGE_ITEM_THREE, 

+      prompt  = STRING_TOKEN(STR_BOOT_MANAGER), 

+      help    = STRING_TOKEN(STR_BOOT_MANAGER_HELP),

+      flags   = INTERACTIVE | NV_ACCESS, 

+      key     = 0x1064;

+

+    goto FRONT_PAGE_ITEM_FOUR, 

+      prompt  = STRING_TOKEN(STR_DEVICE_MANAGER), 

+      help    = STRING_TOKEN(STR_DEVICE_MANAGER_HELP),

+      flags   = INTERACTIVE | NV_ACCESS, 

+      key     = 0x8567;

+

+    goto FRONT_PAGE_ITEM_FIVE, 

+      prompt  = STRING_TOKEN(STR_BOOT_MAINT_MANAGER), 

+      help    = STRING_TOKEN(STR_BOOT_MAINT_MANAGER_HELP),

+      flags   = INTERACTIVE | NV_ACCESS, 

+      key     = 0x9876;

+

+    label FRONT_PAGE_TIMEOUT;

+//  If one wanted to hard-code a value one could do it below, but our implementation follows EFI architecture

+//  and honors the TimeOut NV variable

+//

+//    banner

+//      title = STRING_TOKEN(STR_TIME_OUT_PROMPT),

+//      timeout = 0x000A;

+    

+  endform;

+

+  form formid = FRONT_PAGE_ITEM_ONE,

+       title  = STRING_TOKEN(STR_FRONT_PAGE_TITLE);  

+  endform;

+

+  form formid = FRONT_PAGE_ITEM_THREE,

+       title  = STRING_TOKEN(STR_FRONT_PAGE_TITLE);  

+  endform;

+

+  form formid = FRONT_PAGE_ITEM_FOUR,

+       title  = STRING_TOKEN(STR_FRONT_PAGE_TITLE);  

+  endform;

+

+  form formid = FRONT_PAGE_ITEM_FIVE,

+       title  = STRING_TOKEN(STR_FRONT_PAGE_TITLE);  

+  endform;

+

+endformset;

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Language.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Language.c
new file mode 100644
index 0000000..21d61f1
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Language.c
@@ -0,0 +1,431 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  language.c

+

+Abstract:

+

+ Language settings

+  

+Revision History

+

+--*/

+

+#include "String.h"

+#include "Language.h"

+

+#define NARROW_GLYPH_NUMBER 8

+#define WIDE_GLYPH_NUMBER   75

+

+//

+// Default language code, currently is English

+//

+CHAR8 *mDefaultLangCode = "eng";

+

+typedef struct {

+  EFI_HII_FONT_PACK FixedLength;

+  EFI_NARROW_GLYPH  NarrowArray[NARROW_GLYPH_NUMBER];

+  EFI_WIDE_GLYPH    WideArray[WIDE_GLYPH_NUMBER];

+} FONT_PACK;

+

+FONT_PACK mFontPack = {

+  sizeof (EFI_HII_FONT_PACK) + (NARROW_GLYPH_NUMBER * sizeof (EFI_NARROW_GLYPH)) + (WIDE_GLYPH_NUMBER * sizeof (EFI_WIDE_GLYPH)),

+  EFI_HII_FONT,

+  NARROW_GLYPH_NUMBER,

+  WIDE_GLYPH_NUMBER,

+  {     // Narrow Glyphs

+    {

+      0x05d0,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x4E,

+        0x6E,

+        0x62,

+        0x32,

+        0x32,

+        0x3C,

+        0x68,

+        0x4C,

+        0x4C,

+        0x46,

+        0x76,

+        0x72,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x05d1,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x78,

+        0x7C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x7E,

+        0x7E,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x05d2,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x78,

+        0x7C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x1C,

+        0x3E,

+        0x66,

+        0x66,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x05d3,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x7E,

+        0x7E,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x05d4,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x7C,

+        0x7E,

+        0x06,

+        0x06,

+        0x06,

+        0x06,

+        0x66,

+        0x66,

+        0x66,

+        0x66,

+        0x66,

+        0x66,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x05d5,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x3C,

+        0x3C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x0C,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x05d6,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x38,

+        0x38,

+        0x1E,

+        0x1E,

+        0x18,

+        0x18,

+        0x18,

+        0x18,

+        0x18,

+        0x18,

+        0x18,

+        0x18,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    },

+    {

+      0x0000,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      }

+    }

+  },

+  {     // Wide Glyphs

+    {

+      0x0020,

+      0x00,

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      },

+      {

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00,

+        0x00

+      },

+      {

+        0x00,

+        0x00,

+        0x00

+      }

+    },  //

+  }

+};

+

+VOID

+ExportFonts (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Routine to export glyphs to the HII database.  This is in addition to whatever is defined in the Graphics Console driver.

+

+Arguments:

+  None

+            

+Returns:

+

+--*/

+{

+  EFI_HII_HANDLE    HiiHandle;

+  EFI_HII_PACKAGES  *PackageList;

+

+  PackageList = PreparePackages (1, NULL, &mFontPack);

+  //

+  // Register our Fonts into the global database

+  //

+  HiiHandle = 0;

+  Hii->NewPack (Hii, PackageList, &HiiHandle);

+

+  gBS->FreePool (PackageList);

+}

+

+VOID

+InitializeLanguage (

+  BOOLEAN LangCodesSettingRequired

+  )

+/*++

+

+Routine Description:

+  Determine the current language that will be used 

+  based on language related EFI Variables

+

+Arguments:

+  LangCodesSettingRequired - If required to set LangCode variable

+            

+Returns:

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+  UINTN       Size;

+  CHAR8       LangCode[ISO_639_2_ENTRY_SIZE];

+  CHAR8       *LangCodes;

+  CHAR16      *LanguageString;

+

+  LanguageString  = NULL;

+  LangCodes       = NULL;

+

+  ExportFonts ();

+

+  //

+  // Collect the languages from what our current Language support is based on our VFR

+  //

+  Hii->GetPrimaryLanguages (Hii, gStringPackHandle, &LanguageString);

+

+  LangCodes = AllocatePool (StrLen (LanguageString));

+  ASSERT (LangCodes);

+

+  //

+  // Convert LanguageString from Unicode to EFI defined ASCII LangCodes

+  //

+  for (Index = 0; LanguageString[Index] != 0x0000; Index++) {

+    LangCodes[Index] = (CHAR8) LanguageString[Index];

+  }

+

+  LangCodes[Index] = 0;

+

+  if (LangCodesSettingRequired) {

+    Status = gRT->SetVariable (

+                    L"LangCodes",

+                    &gEfiGlobalVariableGuid,

+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    AsciiStrLen (LangCodes),

+                    LangCodes

+                    );

+  }

+  //

+  // Find current LangCode from Lang NV Variable

+  //

+  Size = ISO_639_2_ENTRY_SIZE;

+  Status = gRT->GetVariable (

+                  L"Lang",

+                  &gEfiGlobalVariableGuid,

+                  NULL,

+                  &Size,

+                  &LangCode

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    Status = EFI_NOT_FOUND;

+    for (Index = 0; LangCodes[Index] != 0; Index += ISO_639_2_ENTRY_SIZE) {

+      if (CompareMem (&LangCodes[Index], LangCode, ISO_639_2_ENTRY_SIZE) == 0) {

+        Status = EFI_SUCCESS;

+        break;

+      }

+    }

+  }

+  //

+  // If we cannot get language code from Lang variable,

+  // or LangCode cannot be found from language table,

+  // set the mDefaultLangCode to Lang variable.

+  //

+  if (EFI_ERROR (Status)) {

+    Status = gRT->SetVariable (

+                    L"Lang",

+                    &gEfiGlobalVariableGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    ISO_639_2_ENTRY_SIZE,

+                    mDefaultLangCode

+                    );

+  }

+

+  if (LangCodes) {

+    gBS->FreePool (LangCodes);

+  }

+

+  if (LanguageString != NULL) {

+    gBS->FreePool (LanguageString);

+  }

+

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Language.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Language.h
new file mode 100644
index 0000000..6b6d887
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Language.h
@@ -0,0 +1,36 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Language.h

+

+Abstract:

+  

+  Language setting

+

+Revision History

+

+--*/

+

+#ifndef _LANGUAGE_H

+#define _LANGUAGE_H

+

+#ifndef ISO_639_2_ENTRY_SIZE

+#define ISO_639_2_ENTRY_SIZE  3

+#endif

+

+VOID

+InitializeLanguage (

+  BOOLEAN LangCodesSettingRequired

+  );

+

+#endif // _LANGUAGE_H_

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c
new file mode 100644
index 0000000..f1fedf3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c
@@ -0,0 +1,386 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MemoryTest.c

+

+Abstract:

+

+  Perform the platform memory test

+

+--*/

+

+#include "bds.h"

+#include "BdsPlatform.h"

+#include "String.h"

+

+//

+// BDS Platform Functions

+//

+EFI_STATUS

+PlatformBdsShowProgress (

+  IN EFI_UGA_PIXEL TitleForeground,

+  IN EFI_UGA_PIXEL TitleBackground,

+  IN CHAR16        *Title,

+  IN EFI_UGA_PIXEL ProgressColor,

+  IN UINTN         Progress,

+  IN UINTN         PreviousValue

+  )

+/*++

+

+Routine Description:

+  

+  Show progress bar with title above it. It only works in UGA mode.

+

+Arguments:

+  

+  TitleForeground - Foreground color for Title.

+  TitleBackground - Background color for Title.

+  Title           - Title above progress bar.

+  ProgressColor   - Progress bar color.

+  Progress        - Progress (0-100)

+

+Returns: 

+  

+  EFI_STATUS      - Success update the progress bar

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  UINT32                SizeOfX;

+  UINT32                SizeOfY;

+  UINT32                ColorDepth;

+  UINT32                RefreshRate;

+  EFI_UGA_PIXEL         Color;

+  UINTN                 BlockHeight;

+  UINTN                 BlockWidth;

+  UINTN                 BlockNum;

+  UINTN                 PosX;

+  UINTN                 PosY;

+  UINTN                 Index;

+

+  if (Progress > 100) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = gBS->HandleProtocol (

+                  gST->ConsoleOutHandle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &UgaDraw

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Status = UgaDraw->GetMode (

+                      UgaDraw,

+                      &SizeOfX,

+                      &SizeOfY,

+                      &ColorDepth,

+                      &RefreshRate

+                      );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  BlockWidth  = SizeOfX / 100;

+  BlockHeight = SizeOfY / 50;

+

+  BlockNum    = Progress;

+

+  PosX        = 0;

+  PosY        = SizeOfY * 48 / 50;

+

+  if (BlockNum == 0) {

+    //

+    // Clear progress area

+    //

+    SetMem (&Color, sizeof (EFI_UGA_PIXEL), 0x0);

+

+    Status = UgaDraw->Blt (

+                        UgaDraw,

+                        &Color,

+                        EfiUgaVideoFill,

+                        0,

+                        0,

+                        0,

+                        PosY - GLYPH_HEIGHT - 1,

+                        SizeOfX,

+                        SizeOfY - (PosY - GLYPH_HEIGHT - 1),

+                        SizeOfX * sizeof (EFI_UGA_PIXEL)

+                        );

+  }

+  //

+  // Show progress by drawing blocks

+  //

+  for (Index = PreviousValue; Index < BlockNum; Index++) {

+    PosX = Index * BlockWidth;

+    Status = UgaDraw->Blt (

+                        UgaDraw,

+                        &ProgressColor,

+                        EfiUgaVideoFill,

+                        0,

+                        0,

+                        PosX,

+                        PosY,

+                        BlockWidth - 1,

+                        BlockHeight,

+                        (BlockWidth) * sizeof (EFI_UGA_PIXEL)

+                        );

+  }

+

+  PrintXY (

+    (SizeOfX - StrLen (Title) * GLYPH_WIDTH) / 2,

+    PosY - GLYPH_HEIGHT - 1,

+    &TitleForeground,

+    &TitleBackground,

+    Title

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsMemoryTest (

+  IN EXTENDMEM_COVERAGE_LEVEL Level

+  )

+/*++

+

+Routine Description:

+  

+  Perform the memory test base on the memory test intensive level, 

+  and update the memory resource.

+

+Arguments:

+  

+  Level  - The memory test intensive level.

+

+Returns: 

+  

+  EFI_STATUS      - Success test all the system memory and update

+                    the memory resource

+                    

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_STATUS                        InitStatus;

+  EFI_STATUS                        KeyStatus;

+  EFI_STATUS                        ReturnStatus;

+  BOOLEAN                           RequireSoftECCInit;

+  EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;

+  UINT64                            TestedMemorySize;

+  UINT64                            TotalMemorySize;

+  UINTN                             TestPercent;

+  UINT64                            PreviousValue;

+  BOOLEAN                           ErrorOut;

+  BOOLEAN                           TestAbort;

+  EFI_INPUT_KEY                     Key;

+  CHAR16                            StrPercent[16];

+  CHAR16                            *StrTotalMemory;

+  CHAR16                            *Pos;

+  CHAR16                            *TmpStr;

+  EFI_UGA_PIXEL                     Foreground;

+  EFI_UGA_PIXEL                     Background;

+  EFI_UGA_PIXEL                     Color;

+  UINT8                             Value;

+  UINTN                             DataSize;

+  UINT32                            Attributes;

+

+  ReturnStatus = EFI_SUCCESS;

+  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));

+

+  Pos = AllocatePool (128);

+

+  if (Pos == NULL) {

+    return ReturnStatus;

+  }

+

+  StrTotalMemory    = Pos;

+

+  TestedMemorySize  = 0;

+  TotalMemorySize   = 0;

+  PreviousValue     = 0;

+  ErrorOut          = FALSE;

+  TestAbort         = FALSE;

+

+  SetMem (&Foreground, sizeof (EFI_UGA_PIXEL), 0xff);

+  SetMem (&Background, sizeof (EFI_UGA_PIXEL), 0x0);

+  SetMem (&Color, sizeof (EFI_UGA_PIXEL), 0xff);

+

+  RequireSoftECCInit = FALSE;

+

+  gST->ConOut->ClearScreen (gST->ConOut);

+  gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);

+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

+

+  Status = gBS->LocateProtocol (

+                  &gEfiGenericMemTestProtocolGuid,

+                  NULL,

+                  &GenMemoryTest

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (Pos);

+    return EFI_SUCCESS;

+  }

+

+  InitStatus = GenMemoryTest->MemoryTestInit (

+                                GenMemoryTest,

+                                Level,

+                                &RequireSoftECCInit

+                                );

+  if (InitStatus == EFI_NO_MEDIA) {

+    //

+    // The PEI codes also have the relevant memory test code to check the memory,

+    // it can select to test some range of the memory or all of them. If PEI code

+    // checks all the memory, this BDS memory test will has no not-test memory to

+    // do the test, and then the status of EFI_NO_MEDIA will be returned by

+    // "MemoryTestInit". So it does not need to test memory again, just return.

+    //

+    gBS->FreePool (Pos);

+    return EFI_SUCCESS;

+  }

+

+  gST->ConOut->SetCursorPosition (gST->ConOut, 0, 2);

+  TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));

+

+  if (TmpStr != NULL) {

+    gST->ConOut->OutputString (gST->ConOut, TmpStr);

+    gBS->FreePool (TmpStr);

+  }

+

+  do {

+    Status = GenMemoryTest->PerformMemoryTest (

+                              GenMemoryTest,

+                              &TestedMemorySize,

+                              &TotalMemorySize,

+                              &ErrorOut,

+                              TestAbort

+                              );

+    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {

+      TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));

+      if (TmpStr != NULL) {

+        PrintXY (10, 10, NULL, NULL, TmpStr);

+        gST->ConOut->SetCursorPosition (gST->ConOut, 0, 4);

+        gST->ConOut->OutputString (gST->ConOut, TmpStr);

+        gBS->FreePool (TmpStr);

+      }

+

+      ASSERT (0);

+    }

+

+    TestPercent = (UINTN) DivU64x32 (

+                            DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),

+                            (UINTN)DivU64x32 (TotalMemorySize, 16)

+                            );

+    if (TestPercent != PreviousValue) {

+      UnicodeValueToString (StrPercent, 0, TestPercent, 0);

+      gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);

+      TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));

+      if (TmpStr != NULL) {

+        BdsLibOutputStrings (gST->ConOut, StrPercent, TmpStr, NULL);

+        gBS->FreePool (TmpStr);

+      }

+

+      TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));

+      if (TmpStr != NULL) {

+        PlatformBdsShowProgress (

+          Foreground,

+          Background,

+          TmpStr,

+          Color,

+          TestPercent,

+          (UINTN) PreviousValue

+          );

+        gBS->FreePool (TmpStr);

+      }

+    }

+

+    PreviousValue = TestPercent;

+

+    KeyStatus     = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+    if (Key.ScanCode == SCAN_ESC) {

+      if (!RequireSoftECCInit) {

+        TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));

+        if (TmpStr != NULL) {

+          PlatformBdsShowProgress (

+            Foreground,

+            Background,

+            TmpStr,

+            Color,

+            100,

+            (UINTN) PreviousValue

+            );

+          gBS->FreePool (TmpStr);

+        }

+

+        gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);

+        gST->ConOut->OutputString (gST->ConOut, L"100");

+        Status = GenMemoryTest->Finished (GenMemoryTest);

+        goto Done;

+      }

+

+      TestAbort = TRUE;

+    }

+  } while (Status != EFI_NOT_FOUND);

+

+  Status = GenMemoryTest->Finished (GenMemoryTest);

+

+Done:

+  UnicodeValueToString (StrTotalMemory, COMMA_TYPE, (UINTN) TotalMemorySize, 0);

+  if (StrTotalMemory[0] == L',') {

+    StrTotalMemory++;

+  }

+

+  TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));

+  if (TmpStr != NULL) {

+    StrCat (StrTotalMemory, TmpStr);

+    gBS->FreePool (TmpStr);

+  }

+

+  gST->ConOut->ClearScreen (gST->ConOut);

+  gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);

+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

+  gST->ConOut->OutputString (gST->ConOut, StrTotalMemory);

+  PlatformBdsShowProgress (

+    Foreground,

+    Background,

+    StrTotalMemory,

+    Color,

+    100,

+    (UINTN) PreviousValue

+    );

+

+  gBS->FreePool (Pos);

+

+  DataSize = sizeof (Value);

+  Status = gRT->GetVariable (

+                  L"BootState",

+                  &gEfiBootStateGuid,

+                  &Attributes,

+                  &DataSize,

+                  &Value

+                  );

+

+  if (EFI_ERROR (Status)) {

+    Value = 1;

+    gRT->SetVariable (

+          L"BootState",

+          &gEfiBootStateGuid,

+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,

+          sizeof (Value),

+          &Value

+          );

+  }

+

+  return ReturnStatus;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/String.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/String.c
new file mode 100644
index 0000000..412b7f8
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/String.c
@@ -0,0 +1,133 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  string.c

+

+Abstract:

+

+  String support

+

+Revision History

+

+--*/

+

+#include "Bds.h"

+#include "String.h"

+#include "Language.h"

+

+extern UINT8  BdsStrings[];

+

+EFI_GUID      gBdsStringPackGuid = { 0x7bac95d3, 0xddf, 0x42f3, 0x9e, 0x24, 0x7c, 0x64, 0x49, 0x40, 0x37, 0x9a };

+

+EFI_STATUS

+InitializeStringSupport (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Initialize HII global accessor for string support

+

+Arguments:

+  None

+

+Returns:

+  String from ID.

+

+--*/

+{

+  EFI_STATUS        Status;

+  EFI_HII_PACKAGES  *PackageList;

+  //

+  // There should only ever be one HII protocol

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiHiiProtocolGuid,

+                  NULL,

+                  &Hii

+                  );

+  if (!EFI_ERROR (Status)) {

+    PackageList = PreparePackages (1, &gBdsStringPackGuid, BdsStrings);

+    Status      = Hii->NewPack (Hii, PackageList, &gStringPackHandle);

+    gBS->FreePool (PackageList);

+  }

+

+  return Status;

+}

+

+CHAR16 *

+GetStringById (

+  IN  STRING_REF   Id

+  )

+/*++

+

+Routine Description:

+

+  Get string by string id from HII Interface

+

+Arguments:

+

+  Id       - String ID.

+           

+Returns:

+

+  CHAR16 * - String from ID.

+  NULL     - If error occurs.

+

+--*/

+{

+  CHAR16      *String;

+  UINTN       StringLength;

+  EFI_STATUS  Status;

+

+  //

+  // Set default string size assumption at no more than 256 bytes

+  //

+  StringLength  = 0x100;

+

+  String        = AllocateZeroPool (StringLength);

+  if (String == NULL) {

+    //

+    // If this happens, we are oh-so-dead, but return a NULL in any case.

+    //

+    return NULL;

+  }

+  //

+  // Get the current string for the current Language

+  //

+  Status = Hii->GetString (Hii, gStringPackHandle, Id, FALSE, NULL, &StringLength, String);

+  if (EFI_ERROR (Status)) {

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      //

+      // Free the old pool

+      //

+      gBS->FreePool (String);

+

+      //

+      // Allocate new pool with correct value

+      //

+      String = AllocatePool (StringLength);

+      ASSERT (String != NULL);

+

+      Status = Hii->GetString (Hii, gStringPackHandle, Id, FALSE, NULL, &StringLength, String);

+      if (!EFI_ERROR (Status)) {

+        return String;

+      }

+    }

+

+    return NULL;

+  }

+

+  return String;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/String.h b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/String.h
new file mode 100644
index 0000000..0800feb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/String.h
@@ -0,0 +1,59 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  string.h

+

+Abstract:

+  

+  String support

+

+Revision History

+

+--*/

+

+#ifndef _STRING_H_

+#define _STRING_H_

+

+//

+// This is the VFR compiler generated header file which defines the

+// string identifiers.

+//

+#include "BdsStrDefs.h"

+

+//

+// String Definition Guid for BDS Platform

+//

+#define EFI_BDS_PLATFORM_GUID \

+  { \

+    0x7777E939, 0xD57E, 0x4DCB, {0xA0, 0x8E, 0x64, 0xD7, 0x98, 0x57, 0x1E, 0x0F } \

+  }

+

+EFI_HII_HANDLE    gStringPackHandle;

+EFI_HII_PROTOCOL  *Hii;

+

+CHAR16            *

+GetStringById (

+  IN  STRING_REF   Id

+  );

+

+EFI_STATUS

+InitializeStringSupport (

+  VOID

+  );

+

+EFI_STATUS

+CallFrontPage (

+  VOID

+  );

+

+#endif // _STRING_H_

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Strings.uni b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Strings.uni
new file mode 100644
index 0000000..41a6b9a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/Generic/Strings.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformBds.mbd b/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformBds.mbd
new file mode 100644
index 0000000..cda7d5b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformBds.mbd
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Bds</BaseName>

+    <Guid>A6F691AC-31C8-4444-854C-E2C1A6950F92</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:04</Created>

+    <Modified>2006-03-23 14:14</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>UefiRuntimeServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeServicesTableLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>EdkGenericBdsLib</Library>

+    <Library>BasePrintLib</Library>

+    <Library>EdkGraphicsLib</Library>

+    <Library>EdkIfrSupportLib</Library>

+    <Library>HiiLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+    <Library>BasePerformanceLibNull</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+    <Option>DPX_SOURCE = ${PLATFORM_BDS_FILE_PATH}\Bds.dxs</Option>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformBds.msa b/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformBds.msa
new file mode 100644
index 0000000..0ee2dfc
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformBds.msa
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Bds</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>A6F691AC-31C8-4444-854C-E2C1A6950F92</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DxeIpl module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:04</Created>

+    <Updated>2006-03-23 14:14</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkGraphicsLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkIfrSupportLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkGenericBdsLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PlatformData.c</Filename>

+    <Filename>BdsPlatform.c</Filename>

+    <Filename>Generic\BdsEntry.c</Filename>

+    <Filename>Generic\FrontPage.c</Filename>

+    <Filename>Generic\FrontPageStrings.uni</Filename>

+    <Filename>Generic\FrontPageVfr.vfr</Filename>

+    <Filename>Generic\Language.c</Filename>

+    <Filename>Generic\String.c</Filename>

+    <Filename>Generic\Strings.uni</Filename>

+    <Filename>Generic\Capsules.c</Filename>

+    <Filename>Generic\MemoryTest.c</Filename>

+    <Filename>Generic\BootMaint\BmString.uni</Filename>

+    <Filename>Generic\BootMaint\bm.vfr</Filename>

+    <Filename>Generic\BootMaint\BmLib.c</Filename>

+    <Filename>Generic\BootMaint\BootOption.c</Filename>

+    <Filename>Generic\BootMaint\ConsoleOption.c</Filename>

+    <Filename>Generic\BootMaint\Data.c</Filename>

+    <Filename>Generic\BootMaint\Variable.c</Filename>

+    <Filename>Generic\BootMaint\UpdatePage.c</Filename>

+    <Filename>Generic\BootMaint\BBSsupport.c</Filename>

+    <Filename>Generic\BootMaint\BootMaint.c</Filename>

+    <Filename>Generic\BootMaint\FileExplorer.c</Filename>

+    <Filename>Generic\BootMaint\FE.vfr</Filename>

+    <Filename>Generic\BootMngr\BootManager.c</Filename>

+    <Filename>Generic\BootMngr\BootManagerStrings.uni</Filename>

+    <Filename>Generic\BootMngr\BootManagerVfr.Vfr</Filename>

+    <Filename>Generic\DeviceMngr\DeviceManager.c</Filename>

+    <Filename>Generic\DeviceMngr\DeviceManagerStrings.uni</Filename>

+    <Filename>Generic\DeviceMngr\DeviceManagerVfr.Vfr</Filename>

+    <Filename>Generic\Bds.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Bds</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">LegacyBios</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">UgaSplash</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Hii</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FormCallback</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">DataHub</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FormBrowser</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ConsoleControl</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">CpuIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">UgaDraw</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadFile</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleFileSystem</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">BlockIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SerialIo</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">GenericMemTest</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">Cpu</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">DriverBinding</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="SOMETIMES_CONSUMED" HobType="GUID_EXTENSION">

+      <Name>FlashMapEntryData</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+    <Hob Usage="SOMETIMES_CONSUMED" HobType="CAPSULE_VOLUME"></Hob>

+  </Hobs>

+  <DataHubs>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">BiosVendor</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">SystemManufacturer</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">ProcessorVersion</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">ProcessorFrequency</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">MemoryArray</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">SerialIoDevice</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_CONSUMED">SerialIoPort</DataHubRecord>

+  </DataHubs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>BootState</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>GlobalVariable</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FlashMapHob</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FileSystemVolumeLabelInfoId</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FileInfo</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>BdsInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformData.c b/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformData.c
new file mode 100644
index 0000000..e9885b7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/PlatformData.c
@@ -0,0 +1,182 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name: 

+

+  PlatformData.c

+

+Abstract:

+  

+  Defined the platform specific device path which will be used by

+  platform Bbd to perform the platform policy connect.

+

+--*/

+

+#include "Generic/Bds.h"

+#include "BdsPlatform.h"

+

+//

+// Predefined platform default time out value

+//

+UINT16                      gPlatformBootTimeOutDefault = 10;

+

+//

+// Platform specific keyboard device path

+//

+NT_PLATFORM_UGA_DEVICE_PATH gUgaDevicePath0 = {

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    EFI_WIN_NT_THUNK_PROTOCOL_GUID

+  },

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)),

+    (UINT8) ((sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)) >> 8),

+    EFI_WIN_NT_UGA_GUID,

+    0

+  },

+  gEndEntire

+};

+

+NT_PLATFORM_UGA_DEVICE_PATH gUgaDevicePath1 = {

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    EFI_WIN_NT_THUNK_PROTOCOL_GUID

+  },

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)),

+    (UINT8) ((sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)) >> 8),

+    EFI_WIN_NT_UGA_GUID,

+    1

+  },

+  gEndEntire

+};

+

+//

+// Platform specific serial device path

+//

+NT_ISA_SERIAL_DEVICE_PATH   gNtSerialDevicePath0 = {

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    EFI_WIN_NT_THUNK_PROTOCOL_GUID

+  },

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)),

+    (UINT8) ((sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)) >> 8),

+    EFI_WIN_NT_SERIAL_PORT_GUID

+  },

+  {

+    MESSAGING_DEVICE_PATH,

+    MSG_UART_DP,

+    (UINT8) (sizeof (UART_DEVICE_PATH)),

+    (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8),

+    0,

+    115200,

+    8,

+    1,

+    1

+  },

+  {

+    MESSAGING_DEVICE_PATH,

+    MSG_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    DEVICE_PATH_MESSAGING_PC_ANSI

+  },

+  gEndEntire

+};

+

+NT_ISA_SERIAL_DEVICE_PATH   gNtSerialDevicePath1 = {

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    EFI_WIN_NT_THUNK_PROTOCOL_GUID

+  },

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)),

+    (UINT8) ((sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)) >> 8),

+    EFI_WIN_NT_SERIAL_PORT_GUID,

+    1

+  },

+  {

+    MESSAGING_DEVICE_PATH,

+    MSG_UART_DP,

+    (UINT8) (sizeof (UART_DEVICE_PATH)),

+    (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8),

+    0,

+    115200,

+    8,

+    1,

+    1

+  },

+  {

+    MESSAGING_DEVICE_PATH,

+    MSG_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    DEVICE_PATH_MESSAGING_PC_ANSI

+  },

+  gEndEntire

+};

+

+//

+// Predefined platform default console device path

+//

+BDS_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {

+  {

+    (EFI_DEVICE_PATH_PROTOCOL *) &gNtSerialDevicePath0,

+    (CONSOLE_OUT | CONSOLE_IN)

+  },

+  {

+    (EFI_DEVICE_PATH_PROTOCOL *) &gNtSerialDevicePath1,

+    (CONSOLE_OUT | CONSOLE_IN)

+  },

+  {

+    (EFI_DEVICE_PATH_PROTOCOL *) &gUgaDevicePath0,

+    (CONSOLE_OUT | CONSOLE_IN)

+  },

+  {

+    (EFI_DEVICE_PATH_PROTOCOL *) &gUgaDevicePath1,

+    (CONSOLE_OUT | CONSOLE_IN)

+  },

+  {

+    NULL,

+    0

+  }

+};

+

+//

+// Predefined platform specific driver option

+//

+EFI_DEVICE_PATH_PROTOCOL    *gPlatformDriverOption[] = { NULL };

+

+//

+// Predefined platform connect sequence

+//

+EFI_DEVICE_PATH_PROTOCOL    *gPlatformConnectSequence[] = { NULL };

diff --git a/edk2/EdkNt32Pkg/Dxe/PlatformBds/build.xml b/edk2/EdkNt32Pkg/Dxe/PlatformBds/build.xml
new file mode 100644
index 0000000..d30fd98
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/PlatformBds/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Bds"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\PlatformBds"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Bds">

+      <GenBuild baseName="Bds" mbdFilename="${MODULE_DIR}\PlatformBds.mbd" msaFilename="${MODULE_DIR}\PlatformBds.msa"/>

+   </target>

+   <target depends="Bds_clean" name="clean"/>

+   <target depends="Bds_cleanall" name="cleanall"/>

+   <target name="Bds_clean">

+      <OutputDirSetup baseName="Bds" mbdFilename="${MODULE_DIR}\PlatformBds.mbd" msaFilename="${MODULE_DIR}\PlatformBds.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Bds_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Bds_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Bds_cleanall">

+      <OutputDirSetup baseName="Bds" mbdFilename="${MODULE_DIR}\PlatformBds.mbd" msaFilename="${MODULE_DIR}\PlatformBds.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Bds_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Bds_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Bds*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/ComponentName.c
new file mode 100644
index 0000000..a24f6da
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/ComponentName.c
@@ -0,0 +1,187 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "WinNtBlockIo.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtBlockIoComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gWinNtBlockIoComponentName = {

+  WinNtBlockIoComponentNameGetDriverName,

+  WinNtBlockIoComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mWinNtBlockIoDriverNameTable[] = {

+  { "eng", L"Windows Block I/O Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gWinNtBlockIoComponentName.SupportedLanguages,

+          mWinNtBlockIoDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;

+  WIN_NT_BLOCK_IO_PRIVATE *Private;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  &BlockIo,

+                  gWinNtBlockIoDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);

+

+  return LookupUnicodeString (

+          Language,

+          gWinNtBlockIoComponentName.SupportedLanguages,

+          Private->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/DriverConfiguration.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/DriverConfiguration.c
new file mode 100644
index 0000000..672ea5f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/DriverConfiguration.c
@@ -0,0 +1,338 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  DriverConfiguration.c

+

+Abstract:

+

+--*/

+

+#include "WinNtBlockIo.h"

+

+//

+// EFI Driver Configuration Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverConfigurationSetOptions (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  CHAR8                                                  *Language,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverConfigurationOptionsValid (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL               *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle  OPTIONAL

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverConfigurationForceDefaults (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  UINT32                                                 DefaultType,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  );

+

+//

+// EFI Driver Configuration Protocol

+//

+EFI_DRIVER_CONFIGURATION_PROTOCOL gWinNtBlockIoDriverConfiguration = {

+  WinNtBlockIoDriverConfigurationSetOptions,

+  WinNtBlockIoDriverConfigurationOptionsValid,

+  WinNtBlockIoDriverConfigurationForceDefaults,

+  LANGUAGESUPPORTED

+};

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverConfigurationSetOptions (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  CHAR8                                                  *Language,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  )

+/*++

+

+  Routine Description:

+    Allows the user to set controller specific options for a controller that a

+    driver is currently managing.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.

+    ControllerHandle - The handle of the controller to set options on.

+    ChildHandle      - The handle of the child controller to set options on.  This

+                       is an optional parameter that may be NULL.  It will be NULL

+                       for device drivers, and for a bus drivers that wish to set

+                       options for the bus controller.  It will not be NULL for a

+                       bus driver that wishes to set options for one of its child

+                       controllers.

+    Language         - A pointer to a three character ISO 639-2 language identifier.

+                       This is the language of the user interface that should be

+                       presented to the user, and it must match one of the languages

+                       specified in SupportedLanguages.  The number of languages

+                       supported by a driver is up to the driver writer.

+    ActionRequired   - A pointer to the action that the calling agent is required

+                       to perform when this function returns.  See "Related

+                       Definitions" for a list of the actions that the calling

+                       agent is required to perform prior to accessing

+                       ControllerHandle again.

+

+  Returns:

+    EFI_SUCCESS           - The driver specified by This successfully set the

+                            configuration options for the controller specified

+                            by ControllerHandle..

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ActionRequired is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support setting

+                            configuration options for the controller specified by

+                            ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the

+                            language specified by Language.

+    EFI_DEVICE_ERROR      - A device error occurred while attempt to set the

+                            configuration options for the controller specified

+                            by ControllerHandle and ChildHandle.

+    EFI_OUT_RESOURCES     - There are not enough resources available to set the

+                            configuration options for the controller specified

+                            by ControllerHandle and ChildHandle.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+  CHAR8                 *SupportedLanguage;

+

+  SupportedLanguage = This->SupportedLanguages;

+

+  Status            = EFI_UNSUPPORTED;

+  while (*SupportedLanguage != 0) {

+    if (AsciiStrnCmp (Language, SupportedLanguage, 3) == 0) {

+      Status = EFI_SUCCESS;

+    }

+

+    SupportedLanguage += 3;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (ActionRequired == NULL || ControllerHandle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Validate controller handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &BlockIo,

+                  gWinNtBlockIoDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiWinNtIoProtocolGuid,

+          gWinNtBlockIoDriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status == EFI_UNSUPPORTED) {

+    return Status;

+  } else if (Status != EFI_ALREADY_STARTED) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *ActionRequired = EfiDriverConfigurationActionNone;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverConfigurationOptionsValid (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL               *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle  OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Tests to see if a controller's current configuration options are valid.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.

+    ControllerHandle - The handle of the controller to test if it's current

+                       configuration options are valid.

+    ChildHandle      - The handle of the child controller to test if it's current

+                       configuration options are valid.  This is an optional

+                       parameter that may be NULL.  It will be NULL for device

+                       drivers.  It will also be NULL for a bus drivers that wish

+                       to test the configuration options for the bus controller.

+                       It will not be NULL for a bus driver that wishes to test

+                       configuration options for one of its child controllers.

+

+  Returns:

+    EFI_SUCCESS           - The controller specified by ControllerHandle and

+                            ChildHandle that is being managed by the driver

+                            specified by This has a valid set of  configuration

+                            options.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently

+                            managing the controller specified by ControllerHandle

+                            and ChildHandle.

+    EFI_DEVICE_ERROR      - The controller specified by ControllerHandle and

+                            ChildHandle that is being managed by the driver

+                            specified by This has an invalid set of configuration

+                            options.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (ControllerHandle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Validate controller handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &BlockIo,

+                  gWinNtBlockIoDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiWinNtIoProtocolGuid,

+          gWinNtBlockIoDriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status == EFI_UNSUPPORTED) {

+    return Status;

+  } else if (Status != EFI_ALREADY_STARTED) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverConfigurationForceDefaults (

+  IN  EFI_DRIVER_CONFIGURATION_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                             ControllerHandle,

+  IN  EFI_HANDLE                                             ChildHandle  OPTIONAL,

+  IN  UINT32                                                 DefaultType,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED               *ActionRequired

+  )

+/*++

+

+  Routine Description:

+    Forces a driver to set the default configuration options for a controller.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.

+    ControllerHandle - The handle of the controller to force default configuration options on.

+    ChildHandle      - The handle of the child controller to force default configuration options on  This is an optional parameter that may be NULL.  It will be NULL for device drivers.  It will also be NULL for a bus drivers that wish to force default configuration options for the bus controller.  It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers.

+    DefaultType      - The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle.  See Table 9-1 for legal values.  A DefaultType of 0x00000000 must be supported by this protocol.

+    ActionRequired   - A pointer to the action that the calling agent is required to perform when this function returns.  See "Related Definitions" in Section 9.1for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again.

+

+  Returns:

+    EFI_SUCCESS           - The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ActionRequired is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the configuration type specified by DefaultType.

+    EFI_DEVICE_ERROR      - A device error occurred while attempt to force the default configuration options on the controller specified by  ControllerHandle and ChildHandle.

+    EFI_OUT_RESOURCES     - There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (ActionRequired == NULL || ControllerHandle == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Validate controller handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &BlockIo,

+                  gWinNtBlockIoDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiWinNtIoProtocolGuid,

+          gWinNtBlockIoDriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status == EFI_UNSUPPORTED) {

+    return Status;

+  } else if (Status != EFI_ALREADY_STARTED) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *ActionRequired = EfiDriverConfigurationActionNone;

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/DriverDiagnostics.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/DriverDiagnostics.c
new file mode 100644
index 0000000..dd81578
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/DriverDiagnostics.c
@@ -0,0 +1,186 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  DriverDiagnostics.c

+

+Abstract:

+

+--*/

+

+#include "WinNtBlockIo.h"

+

+//

+// EFI Driver Diagnostics Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverDiagnosticsRunDiagnostics (

+  IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,

+  IN  EFI_HANDLE                                    ControllerHandle,

+  IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,

+  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,

+  IN  CHAR8                                         *Language,

+  OUT EFI_GUID                                      **ErrorType,

+  OUT UINTN                                         *BufferSize,

+  OUT CHAR16                                        **Buffer

+  );

+

+//

+// EFI Driver Diagnostics Protocol

+//

+EFI_DRIVER_DIAGNOSTICS_PROTOCOL gWinNtBlockIoDriverDiagnostics = {

+  WinNtBlockIoDriverDiagnosticsRunDiagnostics,

+  LANGUAGESUPPORTED

+};

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverDiagnosticsRunDiagnostics (

+  IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,

+  IN  EFI_HANDLE                                    ControllerHandle,

+  IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,

+  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,

+  IN  CHAR8                                         *Language,

+  OUT EFI_GUID                                      **ErrorType,

+  OUT UINTN                                         *BufferSize,

+  OUT CHAR16                                        **Buffer

+  )

+/*++

+

+  Routine Description:

+    Runs diagnostics on a controller.

+

+  Arguments:

+    This             - A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance.

+    ControllerHandle - The handle of the controller to run diagnostics on.

+    ChildHandle      - The handle of the child controller to run diagnostics on

+                       This is an optional parameter that may be NULL.  It will

+                       be NULL for device drivers.  It will also be NULL for a

+                       bus drivers that wish to run diagnostics on the bus

+                       controller.  It will not be NULL for a bus driver that

+                       wishes to run diagnostics on one of its child controllers.

+    DiagnosticType   - Indicates type of diagnostics to perform on the controller

+                       specified by ControllerHandle and ChildHandle.   See

+                       "Related Definitions" for the list of supported types.

+    Language         - A pointer to a three character ISO 639-2 language

+                       identifier.  This is the language in which the optional

+                       error message should be returned in Buffer, and it must

+                       match one of the languages specified in SupportedLanguages.

+                       The number of languages supported by a driver is up to

+                       the driver writer.

+    ErrorType        - A GUID that defines the format of the data returned in

+                       Buffer.

+    BufferSize       - The size, in bytes, of the data returned in Buffer.

+    Buffer           - A buffer that contains a Null-terminated Unicode string

+                       plus some additional data whose format is defined by

+                       ErrorType.  Buffer is allocated by this function with

+                       AllocatePool(), and it is the caller's responsibility

+                       to free it with a call to FreePool().

+

+  Returns:

+    EFI_SUCCESS           - The controller specified by ControllerHandle and

+                            ChildHandle passed the diagnostic.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid

+                            EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ErrorType is NULL.

+    EFI_INVALID_PARAMETER - BufferType is NULL.

+    EFI_INVALID_PARAMETER - Buffer is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support

+                            running diagnostics for the controller specified

+                            by ControllerHandle and ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the

+                            type of diagnostic specified by DiagnosticType.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the

+                            language specified by Language.

+    EFI_OUT_OF_RESOURCES  - There are not enough resources available to complete

+                            the diagnostics.

+    EFI_OUT_OF_RESOURCES  - There are not enough resources available to return

+                            the status information in ErrorType, BufferSize,

+                            and Buffer.

+    EFI_DEVICE_ERROR      - The controller specified by ControllerHandle and

+                            ChildHandle did not pass the diagnostic.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+  CHAR8                 *SupportedLanguage;

+

+  if (Language         == NULL ||

+      ErrorType        == NULL ||

+      Buffer           == NULL ||

+      ControllerHandle == NULL ||

+      BufferSize       == NULL) {

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  SupportedLanguage = This->SupportedLanguages;

+

+  Status            = EFI_UNSUPPORTED;

+  while (*SupportedLanguage != 0) {

+    if (AsciiStrnCmp (Language, SupportedLanguage, 3) == 0) {

+      Status = EFI_SUCCESS;

+      break;

+    }

+

+    SupportedLanguage += 3;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  *ErrorType  = NULL;

+  *BufferSize = 0;

+  if (DiagnosticType != EfiDriverDiagnosticTypeStandard) {

+    *ErrorType  = &gEfiBlockIoProtocolGuid;

+    *BufferSize = 0x60;

+    gBS->AllocatePool (EfiBootServicesData, (UINTN) (*BufferSize), Buffer);

+    CopyMem (*Buffer, L"Windows Block I/O Driver Diagnostics Failed\n", *BufferSize);

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Validate controller handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &BlockIo,

+                  gWinNtBlockIoDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiWinNtIoProtocolGuid,

+          gWinNtBlockIoDriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status == EFI_UNSUPPORTED) {

+    return Status;

+  } else if (Status != EFI_ALREADY_STARTED) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.c
new file mode 100644
index 0000000..2f65092
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.c
@@ -0,0 +1,1085 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  WinNtBlockIo.c

+

+Abstract:

+

+  Produce block IO abstractions for real devices on your PC using Win32 APIs.

+  The configuration of what devices to mount or emulate comes from NT

+  environment variables. The variables must be visible to the Microsoft*

+  Developer Studio for them to work.

+

+  <F>ixed       - Fixed disk like a hard drive.

+  <R>emovable   - Removable media like a floppy or CD-ROM.

+  Read <O>nly   - Write protected device.

+  Read <W>rite  - Read write device.

+  <block count> - Decimal number of blocks a device supports.

+  <block size>  - Decimal number of bytes per block.

+

+  NT envirnonment variable contents. '<' and '>' are not part of the variable,

+  they are just used to make this help more readable. There should be no

+  spaces between the ';'. Extra spaces will break the variable. A '!' is

+  used to seperate multiple devices in a variable.

+

+  EFI_WIN_NT_VIRTUAL_DISKS =

+    <F | R><O | W>;<block count>;<block size>[!...]

+

+  EFI_WIN_NT_PHYSICAL_DISKS =

+    <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]

+

+  Virtual Disks: These devices use a file to emulate a hard disk or removable

+                 media device.

+

+    Thus a 20 MB emulated hard drive would look like:

+    EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512

+

+    A 1.44MB emulated floppy with a block size of 1024 would look like:

+    EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024

+

+  Physical Disks: These devices use NT to open a real device in your system

+

+    Thus a 120 MB floppy would look like:

+    EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512

+

+    Thus a standard CD-ROM floppy would look like:

+    EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048

+

+

+  * Other names and brands may be claimed as the property of others.

+

+--*/

+

+#include "WinNtBlockIo.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gWinNtBlockIoDriverBinding = {

+  WinNtBlockIoDriverBindingSupported,

+  WinNtBlockIoDriverBindingStart,

+  WinNtBlockIoDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS              Status;

+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure the WinNtThunkProtocol is valid

+  //

+  Status = EFI_UNSUPPORTED;

+  if (WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {

+

+    //

+    // Check the GUID to see if this is a handle type the driver supports

+    //

+    if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtVirtualDisksGuid) ||

+        CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtPhysicalDisksGuid) ) {

+      Status = EFI_SUCCESS;

+    }

+  }

+

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        Handle,

+        &gEfiWinNtIoProtocolGuid,

+        This->DriverBindingHandle,

+        Handle

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS                  Status;

+  EFI_WIN_NT_IO_PROTOCOL      *WinNtIo;

+  WIN_NT_RAW_DISK_DEVICE_TYPE DiskType;

+  UINT16                      Buffer[FILENAME_BUFFER_SIZE];

+  CHAR16                      *Str;

+  BOOLEAN                     RemovableMedia;

+  BOOLEAN                     WriteProtected;

+  UINTN                       NumberOfBlocks;

+  UINTN                       BlockSize;

+

+  //

+  // Grab the protocols we need

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Set DiskType

+  //

+  if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtVirtualDisksGuid)) {

+    DiskType = EfiWinNtVirtualDisks;

+  } else if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtPhysicalDisksGuid)) {

+    DiskType = EfiWinNtPhysicalDisks;

+  } else {

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+

+  Status  = EFI_NOT_FOUND;

+  Str     = WinNtIo->EnvString;

+  if (DiskType == EfiWinNtVirtualDisks) {

+    WinNtIo->WinNtThunk->SPrintf (

+                          Buffer,

+                          L"Diskfile%d",

+                          WinNtIo->InstanceNumber

+                          );

+  } else {

+    if (*Str >= 'A' && *Str <= 'Z' || *Str >= 'a' && *Str <= 'z') {

+      WinNtIo->WinNtThunk->SPrintf (Buffer, L"\\\\.\\%c:", *Str);

+    } else {

+      WinNtIo->WinNtThunk->SPrintf (Buffer, L"\\\\.\\PHYSICALDRIVE%c", *Str);

+    }

+

+    Str++;

+    if (*Str != ':') {

+      Status = EFI_NOT_FOUND;

+      goto Done;

+    }

+

+    Str++;

+  }

+

+  if (*Str == 'R' || *Str == 'F') {

+    RemovableMedia = (BOOLEAN) (*Str == 'R');

+    Str++;

+    if (*Str == 'O' || *Str == 'W') {

+      WriteProtected  = (BOOLEAN) (*Str == 'O');

+      Str             = GetNextElementPastTerminator (Str, ';');

+

+      NumberOfBlocks  = Atoi (Str);

+      if (NumberOfBlocks != 0) {

+        Str       = GetNextElementPastTerminator (Str, ';');

+        BlockSize = Atoi (Str);

+        if (BlockSize != 0) {

+          //

+          // If we get here the variable is valid so do the work.

+          //

+          Status = WinNtBlockIoCreateMapping (

+                    WinNtIo,

+                    Handle,

+                    Buffer,

+                    WriteProtected,

+                    RemovableMedia,

+                    NumberOfBlocks,

+                    BlockSize,

+                    DiskType

+                    );

+

+        }

+      }

+    }

+  }

+

+Done:

+  if (EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          Handle,

+          &gEfiWinNtIoProtocolGuid,

+          This->DriverBindingHandle,

+          Handle

+          );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  EFI_UNSUPPORTED - TODO: Add description for return value

+

+--*/

+{

+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;

+  EFI_STATUS              Status;

+  WIN_NT_BLOCK_IO_PRIVATE *Private;

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiBlockIoProtocolGuid,

+                  &BlockIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);

+

+  //

+  // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.

+  //         We could pass in our image handle or FLAG our open to be closed via

+  //         Unistall (== to saying any CloseProtocol will close our open)

+  //

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Private->EfiHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  &Private->BlockIo,

+                  NULL

+                  );

+  if (!EFI_ERROR (Status)) {

+

+    Status = gBS->CloseProtocol (

+                    Handle,

+                    &gEfiWinNtIoProtocolGuid,

+                    This->DriverBindingHandle,

+                    Handle

+                    );

+

+    //

+    // Shut down our device

+    //

+    Private->WinNtThunk->CloseHandle (Private->NtHandle);

+

+    //

+    // Free our instance data

+    //

+    FreeUnicodeStringTable (Private->ControllerNameTable);

+

+    gBS->FreePool (Private);

+  }

+

+  return Status;

+}

+

+STATIC

+CHAR16 *

+GetNextElementPastTerminator (

+  IN  CHAR16  *EnvironmentVariable,

+  IN  CHAR16  Terminator

+  )

+/*++

+

+Routine Description:

+

+  Worker function to parse environment variables.

+

+Arguments:

+  EnvironmentVariable - Envirnment variable to parse.

+

+  Terminator          - Terminator to parse for.

+

+Returns:

+

+  Pointer to next eliment past the first occurence of Terminator or the '\0'

+  at the end of the string.

+

+--*/

+{

+  CHAR16  *Ptr;

+

+  for (Ptr = EnvironmentVariable; *Ptr != '\0'; Ptr++) {

+    if (*Ptr == Terminator) {

+      Ptr++;

+      break;

+    }

+  }

+

+  return Ptr;

+}

+

+STATIC

+EFI_STATUS

+WinNtBlockIoCreateMapping (

+  IN EFI_WIN_NT_IO_PROTOCOL             *WinNtIo,

+  IN EFI_HANDLE                         EfiDeviceHandle,

+  IN CHAR16                             *Filename,

+  IN BOOLEAN                            ReadOnly,

+  IN BOOLEAN                            RemovableMedia,

+  IN UINTN                              NumberOfBlocks,

+  IN UINTN                              BlockSize,

+  IN WIN_NT_RAW_DISK_DEVICE_TYPE        DeviceType

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  WinNtIo         - TODO: add argument description

+  EfiDeviceHandle - TODO: add argument description

+  Filename        - TODO: add argument description

+  ReadOnly        - TODO: add argument description

+  RemovableMedia  - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+  BlockSize       - TODO: add argument description

+  DeviceType      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;

+  WIN_NT_BLOCK_IO_PRIVATE *Private;

+  UINTN                   Index;

+

+  WinNtIo->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS);

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (WIN_NT_BLOCK_IO_PRIVATE),

+                  &Private

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  EfiInitializeLock (&Private->Lock, EFI_TPL_NOTIFY);

+

+  Private->WinNtThunk = WinNtIo->WinNtThunk;

+

+  Private->Signature  = WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE;

+  Private->LastBlock  = NumberOfBlocks - 1;

+  Private->BlockSize  = BlockSize;

+

+  for (Index = 0; Filename[Index] != 0; Index++) {

+    Private->Filename[Index] = Filename[Index];

+  }

+

+  Private->Filename[Index]      = 0;

+

+  Private->ReadMode             = GENERIC_READ | (ReadOnly ? 0 : GENERIC_WRITE);

+  Private->ShareMode            = FILE_SHARE_READ | FILE_SHARE_WRITE;

+

+  Private->NumberOfBlocks       = NumberOfBlocks;

+  Private->DeviceType           = DeviceType;

+  Private->NtHandle             = INVALID_HANDLE_VALUE;

+

+  Private->ControllerNameTable  = NULL;

+

+  AddUnicodeString (

+    "eng",

+    gWinNtBlockIoComponentName.SupportedLanguages,

+    &Private->ControllerNameTable,

+    Private->Filename

+    );

+

+  BlockIo = &Private->BlockIo;

+  BlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;

+  BlockIo->Media = &Private->Media;

+  BlockIo->Media->BlockSize = Private->BlockSize;

+  BlockIo->Media->LastBlock = Private->NumberOfBlocks - 1;

+  BlockIo->Media->MediaId = 0;;

+

+  BlockIo->Reset = WinNtBlockIoResetBlock;

+  BlockIo->ReadBlocks = WinNtBlockIoReadBlocks;

+  BlockIo->WriteBlocks = WinNtBlockIoWriteBlocks;

+  BlockIo->FlushBlocks = WinNtBlockIoFlushBlocks;

+

+  BlockIo->Media->ReadOnly = ReadOnly;

+  BlockIo->Media->RemovableMedia = RemovableMedia;

+  BlockIo->Media->LogicalPartition = FALSE;

+  BlockIo->Media->MediaPresent = TRUE;

+  BlockIo->Media->WriteCaching = FALSE;

+

+  if (DeviceType == EfiWinNtVirtualDisks) {

+    BlockIo->Media->IoAlign = 1;

+

+    //

+    // Create a file to use for a virtual disk even if it does not exist.

+    //

+    Private->OpenMode = OPEN_ALWAYS;

+  } else if (DeviceType == EfiWinNtPhysicalDisks) {

+    //

+    // Physical disk and floppy devices require 4 byte alignment.

+    //

+    BlockIo->Media->IoAlign = 4;

+

+    //

+    // You can only open a physical device if it exists.

+    //

+    Private->OpenMode = OPEN_EXISTING;

+  } else {

+    ASSERT (FALSE);

+  }

+

+  Private->EfiHandle  = EfiDeviceHandle;

+  Status              = WinNtBlockIoOpenDevice (Private);

+  if (!EFI_ERROR (Status)) {

+

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &Private->EfiHandle,

+                    &gEfiBlockIoProtocolGuid,

+                    &Private->BlockIo,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      FreeUnicodeStringTable (Private->ControllerNameTable);

+      gBS->FreePool (Private);

+    }

+

+    DEBUG ((EFI_D_INIT, "BlockDevice added: %s\n", Filename));

+  }

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+WinNtBlockIoOpenDevice (

+  WIN_NT_BLOCK_IO_PRIVATE                 *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS            Status;

+  UINT64                FileSize;

+  UINT64                EndOfFile;

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+

+  BlockIo = &Private->BlockIo;

+  EfiAcquireLock (&Private->Lock);

+

+  //

+  // If the device is already opened, close it

+  //

+  if (Private->NtHandle != INVALID_HANDLE_VALUE) {

+    BlockIo->Reset (BlockIo, FALSE);

+  }

+

+  //

+  // Open the device

+  //

+  Private->NtHandle = Private->WinNtThunk->CreateFile (

+                                            Private->Filename,

+                                            Private->ReadMode,

+                                            Private->ShareMode,

+                                            NULL,

+                                            Private->OpenMode,

+                                            0,

+                                            NULL

+                                            );

+

+  Status = Private->WinNtThunk->GetLastError ();

+

+  if (Private->NtHandle == INVALID_HANDLE_VALUE) {

+    DEBUG ((EFI_D_INFO, "PlOpenBlock: Could not open %s, %x\n", Private->Filename, Private->WinNtThunk->GetLastError ()));

+    BlockIo->Media->MediaPresent  = FALSE;

+    Status                        = EFI_NO_MEDIA;

+    goto Done;

+  }

+

+  if (!BlockIo->Media->MediaPresent) {

+    //

+    // BugBug: try to emulate if a CD appears - notify drivers to check it out

+    //

+    BlockIo->Media->MediaPresent = TRUE;

+    EfiReleaseLock (&Private->Lock);

+    EfiAcquireLock (&Private->Lock);

+  }

+

+  //

+  // get the size of the file

+  //

+  Status = SetFilePointer64 (Private, 0, &FileSize, FILE_END);

+

+  if (EFI_ERROR (Status)) {

+    FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);

+    if (Private->DeviceType == EfiWinNtVirtualDisks) {

+      DEBUG ((EFI_D_ERROR, "PlOpenBlock: Could not get filesize of %s\n", Private->Filename));

+      Status = EFI_UNSUPPORTED;

+      goto Done;

+    }

+  }

+

+  if (Private->NumberOfBlocks == 0) {

+    Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize);

+  }

+

+  EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);

+

+  if (FileSize != EndOfFile) {

+    //

+    // file is not the proper size, change it

+    //

+    DEBUG ((EFI_D_INIT, "PlOpenBlock: Initializing block device: %hs\n", Private->Filename));

+

+    //

+    // first set it to 0

+    //

+    SetFilePointer64 (Private, 0, NULL, FILE_BEGIN);

+    Private->WinNtThunk->SetEndOfFile (Private->NtHandle);

+

+    //

+    // then set it to the needed file size (OS will zero fill it)

+    //

+    SetFilePointer64 (Private, EndOfFile, NULL, FILE_BEGIN);

+    Private->WinNtThunk->SetEndOfFile (Private->NtHandle);

+  }

+

+  DEBUG ((EFI_D_INIT, "%HPlOpenBlock: opened %s%N\n", Private->Filename));

+  Status = EFI_SUCCESS;

+

+Done:

+  if (EFI_ERROR (Status)) {

+    if (Private->NtHandle != INVALID_HANDLE_VALUE) {

+      BlockIo->Reset (BlockIo, FALSE);

+    }

+  }

+

+  EfiReleaseLock (&Private->Lock);

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+WinNtBlockIoError (

+  IN WIN_NT_BLOCK_IO_PRIVATE      *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_BLOCK_IO_PROTOCOL *BlockIo;

+  EFI_STATUS            Status;

+  BOOLEAN               ReinstallBlockIoFlag;

+

+  BlockIo = &Private->BlockIo;

+

+  switch (Private->WinNtThunk->GetLastError ()) {

+

+  case ERROR_NOT_READY:

+    Status                        = EFI_NO_MEDIA;

+    BlockIo->Media->ReadOnly      = FALSE;

+    BlockIo->Media->MediaPresent  = FALSE;

+    ReinstallBlockIoFlag          = FALSE;

+    break;

+

+  case ERROR_WRONG_DISK:

+    BlockIo->Media->ReadOnly      = FALSE;

+    BlockIo->Media->MediaPresent  = TRUE;

+    BlockIo->Media->MediaId += 1;

+    ReinstallBlockIoFlag  = TRUE;

+    Status                = EFI_MEDIA_CHANGED;

+    break;

+

+  case ERROR_WRITE_PROTECT:

+    BlockIo->Media->ReadOnly  = TRUE;

+    ReinstallBlockIoFlag      = FALSE;

+    Status                    = EFI_WRITE_PROTECTED;

+    break;

+

+  default:

+    ReinstallBlockIoFlag  = FALSE;

+    Status                = EFI_DEVICE_ERROR;

+    break;

+  }

+

+  if (ReinstallBlockIoFlag) {

+    BlockIo->Reset (BlockIo, FALSE);

+

+    gBS->ReinstallProtocolInterface (

+          Private->EfiHandle,

+          &gEfiBlockIoProtocolGuid,

+          BlockIo,

+          BlockIo

+          );

+  }

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+WinNtBlockIoReadWriteCommon (

+  IN  WIN_NT_BLOCK_IO_PRIVATE     *Private,

+  IN UINT32                       MediaId,

+  IN EFI_LBA                      Lba,

+  IN UINTN                        BufferSize,

+  IN VOID                         *Buffer,

+  IN CHAR8                        *CallerName

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private     - TODO: add argument description

+  MediaId     - TODO: add argument description

+  Lba         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+  CallerName  - TODO: add argument description

+

+Returns:

+

+  EFI_NO_MEDIA - TODO: Add description for return value

+  EFI_MEDIA_CHANGED - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+  EFI_BAD_BUFFER_SIZE - TODO: Add description for return value

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       BlockSize;

+  UINT64      LastBlock;

+  INT64       DistanceToMove;

+  UINT64      DistanceMoved;

+

+  if (Private->NtHandle == INVALID_HANDLE_VALUE) {

+    Status = WinNtBlockIoOpenDevice (Private);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  if (!Private->Media.MediaPresent) {

+    DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName));

+    return EFI_NO_MEDIA;

+  }

+

+  if (Private->Media.MediaId != MediaId) {

+    return EFI_MEDIA_CHANGED;

+  }

+

+  if ((UINT32) Buffer % Private->Media.IoAlign != 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Verify buffer size

+  //

+  BlockSize = Private->BlockSize;

+  if (BufferSize == 0) {

+    DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName));

+    return EFI_SUCCESS;

+  }

+

+  if ((BufferSize % BlockSize) != 0) {

+    DEBUG ((EFI_D_INIT, "%s: Invalid read size\n", CallerName));

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  LastBlock = Lba + (BufferSize / BlockSize) - 1;

+  if (LastBlock > Private->LastBlock) {

+    DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n"));

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Seek to End of File

+  //

+  DistanceToMove = MultU64x32 (Lba, BlockSize);

+  Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, FILE_BEGIN);

+

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n"));

+    return WinNtBlockIoError (Private);

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoReadBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN UINT32                 MediaId,

+  IN EFI_LBA                Lba,

+  IN UINTN                  BufferSize,

+  OUT VOID                  *Buffer

+  )

+/*++

+

+  Routine Description:

+    Read BufferSize bytes from Lba into Buffer.

+

+  Arguments:

+    This       - Protocol instance pointer.

+    MediaId    - Id of the media, changes every time the media is replaced.

+    Lba        - The starting Logical Block Address to read from

+    BufferSize - Size of Buffer, must be a multiple of device block size.

+    Buffer     - Buffer containing read data

+

+  Returns:

+    EFI_SUCCESS           - The data was read correctly from the device.

+    EFI_DEVICE_ERROR      - The device reported an error while performing the read.

+    EFI_NO_MEDIA          - There is no media in the device.

+    EFI_MEDIA_CHANGED     - The MediaId does not matched the current device.

+    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the

+                            device.

+    EFI_INVALID_PARAMETER - The read request contains device addresses that are not

+                            valid for the device.

+

+--*/

+{

+  WIN_NT_BLOCK_IO_PRIVATE *Private;

+  BOOL                    Flag;

+  EFI_STATUS              Status;

+  DWORD                   BytesRead;

+

+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  Status  = WinNtBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "WinNtReadBlocks");

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Flag = Private->WinNtThunk->ReadFile (Private->NtHandle, Buffer, (DWORD) BufferSize, (LPDWORD) &BytesRead, NULL);

+  if (!Flag || (BytesRead != BufferSize)) {

+    DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed. (%d)\n", Private->WinNtThunk->GetLastError ()));

+    return WinNtBlockIoError (Private);

+  }

+

+  //

+  // If we wrote then media is present.

+  //

+  This->Media->MediaPresent = TRUE;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoWriteBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN UINT32                 MediaId,

+  IN EFI_LBA                Lba,

+  IN UINTN                  BufferSize,

+  IN VOID                   *Buffer

+  )

+/*++

+

+  Routine Description:

+    Write BufferSize bytes from Lba into Buffer.

+

+  Arguments:

+    This       - Protocol instance pointer.

+    MediaId    - Id of the media, changes every time the media is replaced.

+    Lba        - The starting Logical Block Address to read from

+    BufferSize - Size of Buffer, must be a multiple of device block size.

+    Buffer     - Buffer containing read data

+

+  Returns:

+    EFI_SUCCESS           - The data was written correctly to the device.

+    EFI_WRITE_PROTECTED   - The device can not be written to.

+    EFI_DEVICE_ERROR      - The device reported an error while performing the write.

+    EFI_NO_MEDIA          - There is no media in the device.

+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.

+    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the

+                            device.

+    EFI_INVALID_PARAMETER - The write request contains a LBA that is not

+                            valid for the device.

+

+--*/

+{

+  WIN_NT_BLOCK_IO_PRIVATE *Private;

+  UINTN                   BytesWritten;

+  BOOL                    Flag;

+  EFI_STATUS              Status;

+

+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  Status  = WinNtBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "WinNtWriteBlocks");

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Flag = Private->WinNtThunk->WriteFile (Private->NtHandle, Buffer, (DWORD) BufferSize, (LPDWORD) &BytesWritten, NULL);

+  if (!Flag || (BytesWritten != BufferSize)) {

+    DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed. (%d)\n", Private->WinNtThunk->GetLastError ()));

+    return WinNtBlockIoError (Private);

+  }

+

+  //

+  // If the write succeeded, we are not write protected and media is present.

+  //

+  This->Media->MediaPresent = TRUE;

+  This->Media->ReadOnly     = FALSE;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoFlushBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This

+  )

+/*++

+

+  Routine Description:

+    Flush the Block Device.

+

+  Arguments:

+    This             - Protocol instance pointer.

+

+  Returns:

+    EFI_SUCCESS      - All outstanding data was written to the device

+    EFI_DEVICE_ERROR - The device reported an error while writting back the data

+    EFI_NO_MEDIA     - There is no media in the device.

+

+--*/

+{

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoResetBlock (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN BOOLEAN                ExtendedVerification

+  )

+/*++

+

+  Routine Description:

+    Reset the Block Device.

+

+  Arguments:

+    This                 - Protocol instance pointer.

+    ExtendedVerification - Driver may perform diagnostics on reset.

+

+  Returns:

+    EFI_SUCCESS           - The device was reset.

+    EFI_DEVICE_ERROR      - The device is not functioning properly and could

+                            not be reset.

+

+--*/

+{

+  WIN_NT_BLOCK_IO_PRIVATE *Private;

+

+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private->NtHandle != INVALID_HANDLE_VALUE) {

+    Private->WinNtThunk->CloseHandle (Private->NtHandle);

+    Private->NtHandle = INVALID_HANDLE_VALUE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+UINTN

+Atoi (

+  CHAR16  *String

+  )

+/*++

+

+Routine Description:

+

+  Convert a unicode string to a UINTN

+

+Arguments:

+

+  String - Unicode string.

+

+Returns:

+

+  UINTN of the number represented by String.

+

+--*/

+{

+  UINTN   Number;

+  CHAR16  *Str;

+

+  //

+  // skip preceeding white space

+  //

+  Str = String;

+  while ((*Str) && (*Str == ' ')) {

+    Str++;

+  }

+  //

+  // Convert ot a Number

+  //

+  Number = 0;

+  while (*Str != '\0') {

+    if ((*Str >= '0') && (*Str <= '9')) {

+      Number = (Number * 10) +*Str - '0';

+    } else {

+      break;

+    }

+

+    Str++;

+  }

+

+  return Number;

+}

+

+EFI_STATUS

+SetFilePointer64 (

+  IN  WIN_NT_BLOCK_IO_PRIVATE    *Private,

+  IN  INT64                      DistanceToMove,

+  OUT UINT64                     *NewFilePointer,

+  IN  DWORD                      MoveMethod

+  )

+/*++

+

+This function extends the capability of SetFilePointer to accept 64 bit parameters

+

+--*/

+// TODO: function comment is missing 'Routine Description:'

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    Private - add argument and description to function comment

+// TODO:    DistanceToMove - add argument and description to function comment

+// TODO:    NewFilePointer - add argument and description to function comment

+// TODO:    MoveMethod - add argument and description to function comment

+{

+  EFI_STATUS    Status;

+  LARGE_INTEGER LargeInt;

+  UINT32        ErrorCode;

+

+  LargeInt.QuadPart = DistanceToMove;

+  Status            = EFI_SUCCESS;

+

+  LargeInt.LowPart = Private->WinNtThunk->SetFilePointer (

+                                            Private->NtHandle,

+                                            LargeInt.LowPart,

+                                            &LargeInt.HighPart,

+                                            MoveMethod

+                                            );

+

+  if (LargeInt.LowPart == -1 &&

+      (ErrorCode = Private->WinNtThunk->GetLastError ()) != NO_ERROR) {

+    Status = EFI_INVALID_PARAMETER;

+  }

+

+  if (NewFilePointer != NULL) {

+    *NewFilePointer = LargeInt.QuadPart;

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.h
new file mode 100644
index 0000000..59d4b54
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.h
@@ -0,0 +1,471 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtBlockIo.h

+

+Abstract:

+

+  Produce block IO abstractions for real devices on your PC using Win32 APIs.

+  The configuration of what devices to mount or emulate comes from NT 

+  environment variables. The variables must be visible to the Microsoft* 

+  Developer Studio for them to work.

+

+  * Other names and brands may be claimed as the property of others.

+

+--*/

+

+#ifndef _WIN_NT_BLOCK_IO_H_

+#define _WIN_NT_BLOCK_IO_H_

+

+

+

+#define FILENAME_BUFFER_SIZE  80

+

+//

+// Language supported for driverconfiguration protocol

+//

+#define LANGUAGESUPPORTED "eng"

+

+typedef enum {

+  EfiWinNtVirtualDisks,

+  EfiWinNtPhysicalDisks,

+  EifWinNtMaxTypeDisks

+} WIN_NT_RAW_DISK_DEVICE_TYPE;

+

+#define WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 'b', 'k')

+typedef struct {

+  UINTN                       Signature;

+

+  EFI_LOCK                    Lock;

+

+  CHAR16                      Filename[FILENAME_BUFFER_SIZE];

+  UINTN                       ReadMode;

+  UINTN                       ShareMode;

+  UINTN                       OpenMode;

+

+  HANDLE                      NtHandle;

+  WIN_NT_RAW_DISK_DEVICE_TYPE DeviceType;

+

+  UINT64                      LastBlock;

+  UINTN                       BlockSize;

+  UINT64                      NumberOfBlocks;

+

+  EFI_HANDLE                  EfiHandle;

+  EFI_BLOCK_IO_PROTOCOL       BlockIo;

+  EFI_BLOCK_IO_MEDIA          Media;

+

+  EFI_UNICODE_STRING_TABLE    *ControllerNameTable;

+

+  EFI_WIN_NT_THUNK_PROTOCOL   *WinNtThunk;

+

+} WIN_NT_BLOCK_IO_PRIVATE;

+

+#define WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \

+         CR(a, WIN_NT_BLOCK_IO_PRIVATE, BlockIo, WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE)

+

+#define LIST_BUFFER_SIZE  512

+

+//

+// Block I/O Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL        gWinNtBlockIoDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL        gWinNtBlockIoComponentName;

+extern EFI_DRIVER_CONFIGURATION_PROTOCOL  gWinNtBlockIoDriverConfiguration;

+extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL    gWinNtBlockIoDriverDiagnostics;

+

+//

+// EFI Driver Binding Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtBlockIoDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Block IO protocol member functions

+//

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoReadBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN UINT32                 MediaId,

+  IN EFI_LBA                Lba,

+  IN UINTN                  BufferSize,

+  OUT VOID                  *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  Lba         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoWriteBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN UINT32                 MediaId,

+  IN EFI_LBA                Lba,

+  IN UINTN                  BufferSize,

+  IN VOID                   *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  MediaId     - TODO: add argument description

+  Lba         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoFlushBlocks (

+  IN EFI_BLOCK_IO_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtBlockIoResetBlock (

+  IN EFI_BLOCK_IO_PROTOCOL  *This,

+  IN BOOLEAN                ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Private Worker functions

+//

+STATIC

+EFI_STATUS

+WinNtBlockIoCreateMapping (

+  IN EFI_WIN_NT_IO_PROTOCOL             *WinNtIo,

+  IN EFI_HANDLE                         EfiDeviceHandle,

+  IN CHAR16                             *Filename,

+  IN BOOLEAN                            ReadOnly,

+  IN BOOLEAN                            RemovableMedia,

+  IN UINTN                              NumberOfBlocks,

+  IN UINTN                              BlockSize,

+  IN WIN_NT_RAW_DISK_DEVICE_TYPE        DeviceType

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  WinNtIo         - TODO: add argument description

+  EfiDeviceHandle - TODO: add argument description

+  Filename        - TODO: add argument description

+  ReadOnly        - TODO: add argument description

+  RemovableMedia  - TODO: add argument description

+  NumberOfBlocks  - TODO: add argument description

+  BlockSize       - TODO: add argument description

+  DeviceType      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+WinNtBlockIoReadWriteCommon (

+  IN  WIN_NT_BLOCK_IO_PRIVATE *Private,

+  IN UINT32                   MediaId,

+  IN EFI_LBA                  Lba,

+  IN UINTN                    BufferSize,

+  IN VOID                     *Buffer,

+  IN CHAR8                    *CallerName

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private     - TODO: add argument description

+  MediaId     - TODO: add argument description

+  Lba         - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+  CallerName  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+WinNtBlockIoError (

+  IN WIN_NT_BLOCK_IO_PRIVATE      *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+WinNtBlockIoOpenDevice (

+  WIN_NT_BLOCK_IO_PRIVATE         *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+CHAR16                                    *

+GetNextElementPastTerminator (

+  IN  CHAR16  *EnvironmentVariable,

+  IN  CHAR16  Terminator

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  EnvironmentVariable - TODO: add argument description

+  Terminator          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+

+EFI_STATUS

+SetFilePointer64 (

+  IN  WIN_NT_BLOCK_IO_PRIVATE    *Private,

+  IN  INT64                      DistanceToMove,

+  OUT UINT64                     *NewFilePointer,

+  IN  DWORD                      MoveMethod

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private         - TODO: add argument description

+  DistanceToMove  - TODO: add argument description

+  NewFilePointer  - TODO: add argument description

+  MoveMethod      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+UINTN

+Atoi (

+  CHAR16  *String

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  String  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.mbd
new file mode 100644
index 0000000..078350a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtBlockIo</BaseName>

+    <Guid>F479E147-A125-11d4-BCFC-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>UefiDebugLibStdErr</Library>

+    <Library>BasePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.msa
new file mode 100644
index 0000000..8ff369c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.msa
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtBlockIo</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>F479E147-A125-11d4-BCFC-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtBlockIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtBlockIo.h</Filename>

+    <Filename>WinNtBlockIo.c</Filename>

+    <Filename>ComponentName.c</Filename>

+    <Filename>DriverConfiguration.c</Filename>

+    <Filename>DriverDiagnostics.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">WinNtIo</Protocol>

+    <Protocol Usage="BY_START">BlockIo</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtVirtualDisks</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>WinNtPhysicalDisks</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gWinNtBlockIoDriverBinding</DriverBinding>

+      <ComponentName>gWinNtBlockIoComponentName</ComponentName>

+      <DriverDiag>gWinNtBlockIoDriverDiagnostics</DriverDiag>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/build.xml
new file mode 100644
index 0000000..b03cad7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/BlockIo/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtBlockIo"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Bus\BlockIo"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtBlockIo">

+      <GenBuild baseName="WinNtBlockIo" mbdFilename="${MODULE_DIR}\WinNtBlockIo.mbd" msaFilename="${MODULE_DIR}\WinNtBlockIo.msa"/>

+   </target>

+   <target depends="WinNtBlockIo_clean" name="clean"/>

+   <target depends="WinNtBlockIo_cleanall" name="cleanall"/>

+   <target name="WinNtBlockIo_clean">

+      <OutputDirSetup baseName="WinNtBlockIo" mbdFilename="${MODULE_DIR}\WinNtBlockIo.mbd" msaFilename="${MODULE_DIR}\WinNtBlockIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtBlockIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtBlockIo_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtBlockIo_cleanall">

+      <OutputDirSetup baseName="WinNtBlockIo" mbdFilename="${MODULE_DIR}\WinNtBlockIo.mbd" msaFilename="${MODULE_DIR}\WinNtBlockIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtBlockIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtBlockIo_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtBlockIo*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ComponentName.c
new file mode 100644
index 0000000..d10f9ab
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ComponentName.c
@@ -0,0 +1,187 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "Console.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtConsoleComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gWinNtConsoleComponentName = {

+  WinNtConsoleComponentNameGetDriverName,

+  WinNtConsoleComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mWinNtConsoleDriverNameTable[] = {

+  { "eng", L"Windows Text Console Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gWinNtConsoleComponentName.SupportedLanguages,

+          mWinNtConsoleDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                      Status;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *SimpleTextOut;

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get out context back

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &SimpleTextOut,

+                  gWinNtConsoleDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (SimpleTextOut);

+

+  return LookupUnicodeString (

+          Language,

+          gWinNtConsoleComponentName.SupportedLanguages,

+          Private->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/Console.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/Console.c
new file mode 100644
index 0000000..0bc344c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/Console.c
@@ -0,0 +1,307 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Console.c

+

+Abstract:

+

+  Console based on Win32 APIs. 

+

+--*/

+

+#include "Console.h"

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  );

+

+EFI_DRIVER_BINDING_PROTOCOL gWinNtConsoleDriverBinding = {

+  WinNtConsoleDriverBindingSupported,

+  WinNtConsoleDriverBindingStart,

+  WinNtConsoleDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS              Status;

+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure that the WinNt Thunk Protocol is valid

+  //

+  Status = EFI_UNSUPPORTED;

+  if (WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {

+

+    //

+    // Check the GUID to see if this is a handle type the driver supports

+    //

+    if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtConsoleGuid)) {

+      Status = EFI_SUCCESS;

+    }

+  }

+

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        Handle,

+        &gEfiWinNtIoProtocolGuid,

+        This->DriverBindingHandle,

+        Handle

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS                      Status;

+  EFI_WIN_NT_IO_PROTOCOL          *WinNtIo;

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  //

+  // Grab the IO abstraction we need to get any work done

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA),

+                  &Private

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  ZeroMem (Private, sizeof (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA));

+

+  Private->Signature  = WIN_NT_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE;

+  Private->Handle     = Handle;

+  Private->WinNtIo    = WinNtIo;

+  Private->WinNtThunk = WinNtIo->WinNtThunk;

+

+  WinNtSimpleTextOutOpenWindow (Private);

+  WinNtSimpleTextInAttachToWindow (Private);

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Handle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &Private->SimpleTextOut,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &Private->SimpleTextIn,

+                  NULL

+                  );

+  if (!EFI_ERROR (Status)) {

+    return Status;

+  }

+

+Done:

+  gBS->CloseProtocol (

+        Handle,

+        &gEfiWinNtIoProtocolGuid,

+        This->DriverBindingHandle,

+        Handle

+        );

+  if (Private != NULL) {

+

+    FreeUnicodeStringTable (Private->ControllerNameTable);

+

+    if (Private->NtOutHandle != NULL) {

+      Private->WinNtThunk->CloseHandle (Private->NtOutHandle);

+    }

+

+    if (Private->SimpleTextIn.WaitForKey != NULL) {

+      gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);

+    }

+

+    gBS->FreePool (Private);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtConsoleDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  EFI_UNSUPPORTED - TODO: Add description for return value

+

+--*/

+{

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL    *SimpleTextOut;

+  EFI_STATUS                      Status;

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  //

+  // Kick people off our interface???

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &SimpleTextOut,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (SimpleTextOut);

+

+  ASSERT (Private->Handle == Handle);

+

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Handle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  &Private->SimpleTextOut,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &Private->SimpleTextIn,

+                  NULL

+                  );

+  if (!EFI_ERROR (Status)) {

+

+    //

+    // Shut down our device

+    //

+    Status = gBS->CloseProtocol (

+                    Handle,

+                    &gEfiWinNtIoProtocolGuid,

+                    This->DriverBindingHandle,

+                    Handle

+                    );

+

+    Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);

+    ASSERT_EFI_ERROR (Status);

+

+    Private->WinNtThunk->CloseHandle (Private->NtOutHandle);

+    //

+    // DO NOT close Private->NtInHandle. It points to StdIn and not

+    //  the Private->NtOutHandle is StdIn and should not be closed!

+    //

+    FreeUnicodeStringTable (Private->ControllerNameTable);

+

+    gBS->FreePool (Private);

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/Console.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/Console.h
new file mode 100644
index 0000000..1c8a26b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/Console.h
@@ -0,0 +1,512 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Console.h

+

+Abstract:

+

+  Console based on Win32 APIs.

+

+  This file attaches a SimpleTextIn protocol to a previously open window.

+  

+  The constructor for this protocol depends on an open window. Currently

+  the SimpleTextOut protocol creates a window when it's constructor is called.

+  Thus this code must run after the constructor for the SimpleTextOut 

+  protocol

+  

+--*/

+

+#ifndef _CONSOLE_H_

+#define _CONSOLE_H_

+

+

+

+#define WIN_NT_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE \

+          EFI_SIGNATURE_32('N','T','s','c')

+

+typedef struct {

+  UINT64                        Signature;

+

+  EFI_HANDLE                    Handle;

+

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  SimpleTextOut;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE   SimpleTextOutMode;

+

+  EFI_WIN_NT_IO_PROTOCOL        *WinNtIo;

+  EFI_WIN_NT_THUNK_PROTOCOL     *WinNtThunk;

+

+  //

+  // SimpleTextOut Private Data including Win32 types.

+  //

+  HANDLE                        NtOutHandle;

+  HANDLE                        NtInHandle;

+

+  COORD                         MaxScreenSize;

+  COORD                         Possition;

+  WORD                          Attribute;

+  BOOLEAN                       CursorEnable;

+

+  EFI_SIMPLE_TEXT_IN_PROTOCOL   SimpleTextIn;

+

+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;

+

+} WIN_NT_SIMPLE_TEXT_PRIVATE_DATA;

+

+#define WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS(a) \

+         CR(a, WIN_NT_SIMPLE_TEXT_PRIVATE_DATA, SimpleTextOut, WIN_NT_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE)

+

+#define WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS(a) \

+         CR(a, WIN_NT_SIMPLE_TEXT_PRIVATE_DATA, SimpleTextIn, WIN_NT_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE)

+

+//

+// Console Globale Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtConsoleDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtConsoleComponentName;

+

+typedef struct {

+  UINTN ColumnsX;

+  UINTN RowsY;

+} WIN_NT_SIMPLE_TEXT_OUT_MODE;

+

+//

+// Simple Text Out protocol member functions

+//

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutReset (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL     *This,

+  IN BOOLEAN                          ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutOutputString (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN CHAR16                         *String

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  String  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutTestString (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN CHAR16                         *String

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  String  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutQueryMode (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN UINTN                          ModeNumber,

+  OUT UINTN                         *Columns,

+  OUT UINTN                         *Rows

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  ModeNumber  - TODO: add argument description

+  Columns     - TODO: add argument description

+  Rows        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutSetMode (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN UINTN                          ModeNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  ModeNumber  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutSetAttribute (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN UINTN                          Attribute

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Attribute - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutClearScreen (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutSetCursorPosition (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN UINTN                          Column,

+  IN UINTN                          Row

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Column  - TODO: add argument description

+  Row     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutEnableCursor (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN BOOLEAN                        Enable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Enable  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Simple Text Out constructor and destructor.

+//

+EFI_STATUS

+WinNtSimpleTextOutOpenWindow (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WinNtSimpleTextOutCloseWindow (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Console - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Simple Text In protocol member functions.

+//

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextInReset (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  IN BOOLEAN                              ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextInReadKeyStroke (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  OUT EFI_INPUT_KEY                       *Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+  Key   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+VOID

+EFIAPI

+WinNtSimpleTextInWaitForKey (

+  IN EFI_EVENT          Event,

+  IN VOID               *Context

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Event   - TODO: add argument description

+  Context - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Simple Text In constructor

+//

+EFI_STATUS

+WinNtSimpleTextInAttachToWindow (

+  IN  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Main Entry Point

+//

+EFI_STATUS

+EFIAPI

+InitializeWinNtConsole (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+AppendDevicePathInstanceToVar (

+  IN  CHAR16                    *VariableName,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  VariableName        - TODO: add argument description

+  DevicePathInstance  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleIn.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleIn.c
new file mode 100644
index 0000000..3af1ce6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleIn.c
@@ -0,0 +1,361 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConsoleIn.c

+

+Abstract:

+

+  Console based on Win32 APIs. 

+

+  This file attaches a SimpleTextIn protocol to a previously open window.

+  

+  The constructor for this protocol depends on an open window. Currently

+  the SimpleTextOut protocol creates a window when it's constructor is called.

+  Thus this code must run after the constructor for the SimpleTextOut 

+  protocol

+  

+--*/

+

+#include "Console.h"

+

+//

+// Private worker functions

+//

+STATIC

+EFI_STATUS

+WinNtSimpleTextInCheckKey (

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA  *Private

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextInReset (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  IN BOOLEAN                              ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private = WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+WinNtConvertInputRecordToEfiKey (

+  IN  INPUT_RECORD    *InputRecord,

+  OUT EFI_INPUT_KEY   *Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  InputRecord - TODO: add argument description

+  Key         - TODO: add argument description

+

+Returns:

+

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  //

+  // Make sure InputRecord is an event that represents a keypress

+  //

+  if (InputRecord->EventType == KEY_EVENT) {

+    if (!InputRecord->Event.KeyEvent.bKeyDown) {

+      return EFI_NOT_READY;

+    }

+  } else {

+    return EFI_NOT_READY;

+  }

+  

+  //

+  // Check to see if we should return a scan code in place of Unicode character.

+  //

+  Key->ScanCode     = 0;

+  Key->UnicodeChar  = 0;

+  if ((InputRecord->Event.KeyEvent.dwControlKeyState & (NUMLOCK_ON | ENHANCED_KEY)) != NUMLOCK_ON) {

+    //

+    // Only check these scan codes if num lock is off.

+    //

+    switch (InputRecord->Event.KeyEvent.wVirtualScanCode) {

+      case 0x48: Key->ScanCode = SCAN_UP;         break;

+      case 0x50: Key->ScanCode = SCAN_DOWN;       break;

+      case 0x4d: Key->ScanCode = SCAN_RIGHT;      break;

+      case 0x4b: Key->ScanCode = SCAN_LEFT;       break;

+      case 0x47: Key->ScanCode = SCAN_HOME;       break;

+      case 0x4F: Key->ScanCode = SCAN_END;        break;

+      case 0x52: Key->ScanCode = SCAN_INSERT;     break;

+      case 0x53: Key->ScanCode = SCAN_DELETE;     break;

+      case 0x49: Key->ScanCode = SCAN_PAGE_UP;    break;

+      case 0x51: Key->ScanCode = SCAN_PAGE_DOWN;  break;

+    }

+  }

+

+  switch (InputRecord->Event.KeyEvent.wVirtualScanCode) {

+    case 0x3b: Key->ScanCode = SCAN_F1;   break;

+    case 0x3c: Key->ScanCode = SCAN_F2;   break;

+    case 0x3d: Key->ScanCode = SCAN_F3;   break;

+    case 0x3e: Key->ScanCode = SCAN_F4;   break;

+    case 0x3f: Key->ScanCode = SCAN_F5;   break;

+    case 0x40: Key->ScanCode = SCAN_F6;   break;

+    case 0x41: Key->ScanCode = SCAN_F7;   break;

+    case 0x42: Key->ScanCode = SCAN_F8;   break;

+    case 0x43: Key->ScanCode = SCAN_F9;   break;

+    case 0x44: Key->ScanCode = SCAN_F10;  break;

+    case 0x01: Key->ScanCode = SCAN_ESC;  break;

+  }

+

+  //

+  // If there's a scan code pass it, and don't pass the char code

+  //

+  if (Key->ScanCode == 0) {

+    Key->UnicodeChar = InputRecord->Event.KeyEvent.uChar.UnicodeChar;

+    if (Key->UnicodeChar == 0) {

+      return EFI_NOT_READY;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextInReadKeyStroke (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  OUT EFI_INPUT_KEY                       *Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+  Key   - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_NOT_READY - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS                      Status;

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+  INPUT_RECORD                    InputRecord;

+  DWORD                           NtEventCount;

+

+  Private = WIN_NT_SIMPLE_TEXT_IN_PRIVATE_DATA_FROM_THIS (This);

+

+  Status  = WinNtSimpleTextInCheckKey (Private);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  do {

+

+    if (!Private->WinNtThunk->ReadConsoleInput (Private->NtInHandle, &InputRecord, 1, &NtEventCount)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    if (NtEventCount == 0) {

+      return EFI_NOT_READY;

+    }

+

+    //

+    // Convert the Input Record to an EFI Keystroke.

+    //

+    Status = WinNtConvertInputRecordToEfiKey (&InputRecord, Key);

+  } while (EFI_ERROR (Status));

+

+  return Status;

+}

+

+STATIC

+VOID

+EFIAPI

+WinNtSimpleTextInWaitForKey (

+  IN EFI_EVENT          Event,

+  IN VOID               *Context

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Event   - TODO: add argument description

+  Context - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+  EFI_STATUS                      Status;

+

+  Private = (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *) Context;

+  Status  = WinNtSimpleTextInCheckKey (Private);

+  if (!EFI_ERROR (Status)) {

+    gBS->SignalEvent (Event);

+  }

+}

+

+STATIC

+EFI_STATUS

+WinNtSimpleTextInCheckKey (

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA   *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  INPUT_RECORD  *InputRecord;

+  DWORD         NtEventCount;

+  DWORD         ActualNtEventCount;

+  EFI_STATUS    Status;

+  BOOLEAN       Success;

+  UINTN         Index;

+  EFI_INPUT_KEY Key;

+

+  InputRecord   = NULL;

+  NtEventCount  = 0;

+  Private->WinNtThunk->GetNumberOfConsoleInputEvents (Private->NtInHandle, &NtEventCount);

+  if (NtEventCount == 0) {

+    Status = EFI_NOT_READY;

+    goto Done;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (INPUT_RECORD) * NtEventCount,

+                  &InputRecord

+                  );

+  if (EFI_ERROR (Status)) {

+    Status = EFI_NOT_READY;

+    goto Done;

+  }

+

+  Success = (BOOLEAN) Private->WinNtThunk->PeekConsoleInput (

+                                            Private->NtInHandle,

+                                            InputRecord,

+                                            NtEventCount,

+                                            &ActualNtEventCount

+                                            );

+  if (!Success) {

+    Status = EFI_NOT_READY;

+    goto Done;

+  }

+

+  Status = EFI_NOT_READY;

+  for (Index = 0; Index < (UINTN) ActualNtEventCount; Index++) {

+    //

+    // Convert the Input Record to an EFI Keystroke.

+    //

+    Status = WinNtConvertInputRecordToEfiKey (&InputRecord[Index], &Key);

+    if (!EFI_ERROR (Status)) {

+      Status = EFI_SUCCESS;

+      goto Done;

+    }

+  }

+

+Done:

+  if (InputRecord != NULL) {

+    gBS->FreePool (InputRecord);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+WinNtSimpleTextInAttachToWindow (

+  IN  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  Private->NtInHandle                 = Private->WinNtThunk->GetStdHandle (STD_INPUT_HANDLE);

+

+  Private->SimpleTextIn.Reset         = WinNtSimpleTextInReset;

+  Private->SimpleTextIn.ReadKeyStroke = WinNtSimpleTextInReadKeyStroke;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  WinNtSimpleTextInWaitForKey,

+                  Private,

+                  &Private->SimpleTextIn.WaitForKey

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleOut.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleOut.c
new file mode 100644
index 0000000..cab3768
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/ConsoleOut.c
@@ -0,0 +1,638 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ConsoleOut.c

+

+Abstract:

+

+  Console based on Win32 APIs. 

+

+  This file creates an Win32 window and attaches a SimpleTextOut protocol.

+

+--*/

+

+#include "Console.h"

+//

+// Private worker functions.

+//

+

+STATIC

+VOID

+WinNtSimpleTextOutScrollScreen (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console

+  );

+

+STATIC

+VOID

+WinNtSimpleTextOutPutChar (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA     *Console,

+  IN      CHAR16                              Char

+  );

+

+//

+// Modeule Global for Simple Text Out Mode.

+//

+#define MAX_SIMPLE_TEXT_OUT_MODE  \

+        (sizeof(mWinNtSimpleTextOutSupportedModes)/sizeof(WIN_NT_SIMPLE_TEXT_OUT_MODE))

+

+STATIC WIN_NT_SIMPLE_TEXT_OUT_MODE  mWinNtSimpleTextOutSupportedModes[] = {

+  { 80, 25 },         

+  { 80, 50 },         

+  { 80, 43 },         

+  { 100, 100 },       

+  { 100, 999 }         

+};

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutReset (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL         *This,

+  IN BOOLEAN                              ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  WinNtSimpleTextOutSetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));

+

+  WinNtSimpleTextOutSetMode (This, 0);

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutOutputString (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN CHAR16                                 *String

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  String  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+  CHAR16                          *Str;

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  for (Str = String; *Str != '\0'; Str++) {

+    switch (*Str) {

+    case '\n':

+      if (Private->Possition.Y == (Private->MaxScreenSize.Y - 1)) {

+        WinNtSimpleTextOutScrollScreen (Private);

+      }

+

+      if (Private->Possition.Y < (Private->MaxScreenSize.Y - 1)) {

+        Private->Possition.Y++;

+        This->Mode->CursorRow++;

+      }

+      break;

+

+    case '\r':

+      Private->Possition.X      = 0;

+      This->Mode->CursorColumn  = 0;

+      break;

+

+    case '\b':

+      if (Private->Possition.X > 0) {

+        Private->Possition.X--;

+        This->Mode->CursorColumn--;

+      }

+      break;

+

+    default:

+      WinNtSimpleTextOutPutChar (Private, *Str);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+VOID

+WinNtSimpleTextOutPutChar (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA   *Console,

+  IN      CHAR16                            Char

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Console - TODO: add argument description

+  Char    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  SMALL_RECT  Region;

+  COORD       StrCoordinate;

+  COORD       StrSize;

+  CHAR_INFO   CharInfo;

+  BOOL        Flag;

+

+  CharInfo.Char.UnicodeChar = Char;

+  CharInfo.Attributes       = Console->Attribute;

+

+  StrSize.X                 = 1;

+  StrSize.Y                 = 1;

+  StrCoordinate.X           = 0;

+  StrCoordinate.Y           = 0;

+

+  Region.Left               = (INT16) Console->Possition.X;

+  Region.Top                = (INT16) Console->Possition.Y;

+  Region.Right              = (INT16) (Console->Possition.X + 1);

+  Region.Bottom             = (INT16) Console->Possition.Y;

+

+  Console->WinNtThunk->WriteConsoleOutput (

+                        Console->NtOutHandle,

+                        &CharInfo,

+                        StrSize,

+                        StrCoordinate,

+                        &Region

+                        );

+

+  if (Console->Possition.X >= (Console->MaxScreenSize.X - 1)) {

+    //

+    // If you print off the end wrap around

+    //

+    Console->SimpleTextOut.OutputString (&Console->SimpleTextOut, L"\n\r");

+  } else {

+    Console->Possition.X++;

+    Console->SimpleTextOut.Mode->CursorColumn++;

+  }

+

+  Flag = Console->WinNtThunk->SetConsoleCursorPosition (Console->NtOutHandle, Console->Possition);

+}

+

+STATIC

+VOID

+WinNtSimpleTextOutScrollScreen (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Console - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  SMALL_RECT  Scroll;

+  CHAR_INFO   CharInfo;

+  COORD       Origin;

+

+  CharInfo.Char.UnicodeChar = ' ';

+  CharInfo.Attributes       = Console->Attribute;

+

+  Origin.X                  = 0;

+  Origin.Y                  = 0;

+

+  Scroll.Top                = 1;

+  Scroll.Left               = 0;

+  Scroll.Right              = (INT16) Console->MaxScreenSize.X;

+  Scroll.Bottom             = (INT16) Console->MaxScreenSize.Y;

+

+  Console->WinNtThunk->ScrollConsoleScreenBuffer (

+                        Console->NtOutHandle,

+                        &Scroll,

+                        NULL,

+                        Origin,

+                        &CharInfo

+                        );

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutTestString (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN CHAR16                                 *String

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  String  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  // BugBug: The correct answer would be a function of what code pages

+  //         are currently loaded? For now we will just return success.

+  //

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutQueryMode (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  ModeNumber,

+  OUT UINTN                                 *Columns,

+  OUT UINTN                                 *Rows

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  ModeNumber  - TODO: add argument description

+  Columns     - TODO: add argument description

+  Rows        - TODO: add argument description

+

+Returns:

+

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  if (ModeNumber > MAX_SIMPLE_TEXT_OUT_MODE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Columns  = mWinNtSimpleTextOutSupportedModes[ModeNumber].ColumnsX;

+  *Rows     = mWinNtSimpleTextOutSupportedModes[ModeNumber].RowsY;

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutSetMode (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  ModeNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  ModeNumber  - TODO: add argument description

+

+Returns:

+

+  EFI_INVALID_PARAMETER - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  if (ModeNumber > MAX_SIMPLE_TEXT_OUT_MODE) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private->MaxScreenSize.X  = (WORD) mWinNtSimpleTextOutSupportedModes[ModeNumber].ColumnsX;

+  Private->MaxScreenSize.Y  = (WORD) mWinNtSimpleTextOutSupportedModes[ModeNumber].RowsY;

+

+  Private->WinNtThunk->SetConsoleScreenBufferSize (Private->NtOutHandle, Private->MaxScreenSize);

+  Private->WinNtThunk->SetConsoleActiveScreenBuffer (Private->NtOutHandle);

+

+  This->Mode->Mode = (INT32) ModeNumber;

+

+  This->EnableCursor (This, TRUE);

+  This->ClearScreen (This);

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutSetAttribute (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN UINTN                          Attribute

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This      - TODO: add argument description

+  Attribute - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private               = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  Private->Attribute    = (WORD) Attribute;

+  This->Mode->Attribute = (INT32) Attribute;

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutClearScreen (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+  DWORD                           ConsoleWindow;

+

+  Private = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  This->SetCursorPosition (This, 0, 0);

+

+  Private->WinNtThunk->FillConsoleOutputCharacter (

+                        Private->NtOutHandle,

+                        ' ',

+                        Private->MaxScreenSize.X * Private->MaxScreenSize.Y,

+                        Private->Possition,

+                        &ConsoleWindow

+                        );

+  Private->WinNtThunk->FillConsoleOutputAttribute (

+                        Private->NtOutHandle,

+                        Private->Attribute,

+                        Private->MaxScreenSize.X * Private->MaxScreenSize.Y,

+                        Private->Possition,

+                        &ConsoleWindow

+                        );

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutSetCursorPosition (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  Column,

+  IN UINTN                                  Row

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Column  - TODO: add argument description

+  Row     - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+

+  Private                   = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+

+  Private->Possition.X      = (WORD) Column;

+  This->Mode->CursorColumn  = (INT32) Column;

+

+  Private->Possition.Y      = (WORD) Row;

+  This->Mode->CursorRow     = (INT32) Row;

+  Private->WinNtThunk->SetConsoleCursorPosition (Private->NtOutHandle, Private->Possition);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSimpleTextOutEnableCursor (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This,

+  IN BOOLEAN                        Enable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Enable  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

+  CONSOLE_CURSOR_INFO             Info;

+

+  Private                   = WIN_NT_SIMPLE_TEXT_OUT_PRIVATE_DATA_FROM_THIS (This);

+  Private->CursorEnable     = Enable;

+  This->Mode->CursorVisible = Enable;

+

+  Private->WinNtThunk->GetConsoleCursorInfo (Private->NtOutHandle, &Info);

+  Info.bVisible = Enable;

+  Private->WinNtThunk->SetConsoleCursorInfo (Private->NtOutHandle, &Info);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WinNtSimpleTextOutOpenWindow (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *SimpleTextOut;

+  CHAR16                        *WindowName;

+

+  WindowName          = Private->WinNtIo->EnvString;

+  Private->Attribute  = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;

+  if (*WindowName == '?') {

+    Private->Attribute  = BACKGROUND_RED | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;

+    WindowName          = L"EFI Emulator Error Console";

+  }

+

+  AddUnicodeString (

+    "eng",

+    gWinNtConsoleComponentName.SupportedLanguages,

+    &Private->ControllerNameTable,

+    WindowName

+    );

+

+  //

+  // Fill in protocol member functions

+  //

+  SimpleTextOut                     = &Private->SimpleTextOut;

+  SimpleTextOut->Reset              = WinNtSimpleTextOutReset;

+  SimpleTextOut->OutputString       = WinNtSimpleTextOutOutputString;

+  SimpleTextOut->TestString         = WinNtSimpleTextOutTestString;

+  SimpleTextOut->QueryMode          = WinNtSimpleTextOutQueryMode;

+  SimpleTextOut->SetMode            = WinNtSimpleTextOutSetMode;

+  SimpleTextOut->SetAttribute       = WinNtSimpleTextOutSetAttribute;

+  SimpleTextOut->ClearScreen        = WinNtSimpleTextOutClearScreen;

+  SimpleTextOut->SetCursorPosition  = WinNtSimpleTextOutSetCursorPosition;

+  SimpleTextOut->EnableCursor       = WinNtSimpleTextOutEnableCursor;

+

+  //

+  // Initialize SimpleTextOut protocol mode structure

+  //

+  SimpleTextOut->Mode             = &Private->SimpleTextOutMode;

+  SimpleTextOut->Mode->MaxMode    = MAX_SIMPLE_TEXT_OUT_MODE;

+  SimpleTextOut->Mode->Attribute  = (INT32) Private->Attribute;

+

+  //

+  // Open the window an initialize it!

+  //

+  Private->NtOutHandle = Private->WinNtThunk->CreateConsoleScreenBuffer (

+                                                GENERIC_WRITE | GENERIC_READ,

+                                                FILE_SHARE_WRITE | FILE_SHARE_READ,

+                                                NULL,

+                                                CONSOLE_TEXTMODE_BUFFER,

+                                                NULL

+                                                );

+  Private->WinNtThunk->SetConsoleTitle (WindowName);

+

+  return SimpleTextOut->SetMode (SimpleTextOut, 0);

+}

+

+EFI_STATUS

+WinNtSimpleTextOutCloseWindow (

+  IN OUT  WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Console

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Console - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  Console->WinNtThunk->CloseHandle (Console->NtOutHandle);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/WinNtConsole.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/WinNtConsole.mbd
new file mode 100644
index 0000000..566a748
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/WinNtConsole.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtConsole</BaseName>

+    <Guid>263631d7-5836-4b74-be48-ee22e92ce5d3</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>UefiDebugLibStdErr</Library>

+    <Library>BasePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/WinNtConsole.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/WinNtConsole.msa
new file mode 100644
index 0000000..00fb469
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/WinNtConsole.msa
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtConsole</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>263631d7-5836-4b74-be48-ee22e92ce5d3</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtConsole module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Console.h</Filename>

+    <Filename>Console.c</Filename>

+    <Filename>ConsoleIn.c</Filename>

+    <Filename>ConsoleOut.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">WinNtIo</Protocol>

+    <Protocol Usage="BY_START">SimpleTextOut</Protocol>

+    <Protocol Usage="BY_START">SimpleTextIn</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtConsole</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gWinNtConsoleDriverBinding</DriverBinding>

+      <ComponentName>gWinNtConsoleComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/build.xml
new file mode 100644
index 0000000..9d227c7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Console/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtConsole"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Bus\Console"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtConsole">

+      <GenBuild baseName="WinNtConsole" mbdFilename="${MODULE_DIR}\WinNtConsole.mbd" msaFilename="${MODULE_DIR}\WinNtConsole.msa"/>

+   </target>

+   <target depends="WinNtConsole_clean" name="clean"/>

+   <target depends="WinNtConsole_cleanall" name="cleanall"/>

+   <target name="WinNtConsole_clean">

+      <OutputDirSetup baseName="WinNtConsole" mbdFilename="${MODULE_DIR}\WinNtConsole.mbd" msaFilename="${MODULE_DIR}\WinNtConsole.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtConsole_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtConsole_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtConsole_cleanall">

+      <OutputDirSetup baseName="WinNtConsole" mbdFilename="${MODULE_DIR}\WinNtConsole.mbd" msaFilename="${MODULE_DIR}\WinNtConsole.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtConsole_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtConsole_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtConsole*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/ComponentName.c
new file mode 100644
index 0000000..8205786
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/ComponentName.c
@@ -0,0 +1,187 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "WinNtSerialIo.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtSerialIoComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtSerialIoComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gWinNtSerialIoComponentName = {

+  WinNtSerialIoComponentNameGetDriverName,

+  WinNtSerialIoComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mWinNtSerialIoDriverNameTable[] = {

+  { "eng", L"Windows Serial I/O Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+WinNtSerialIoComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gWinNtSerialIoComponentName.SupportedLanguages,

+          mWinNtSerialIoDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSerialIoComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                    Status;

+  EFI_SERIAL_IO_PROTOCOL        *SerialIo;

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+

+  //

+  // This is a bus driver, so ChildHandle must not be NULL.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ChildHandle,

+                  &gEfiSerialIoProtocolGuid,

+                  &SerialIo,

+                  gWinNtSerialIoDriverBinding.DriverBindingHandle,

+                  ChildHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo);

+

+  return LookupUnicodeString (

+          Language,

+          gWinNtSerialIoComponentName.SupportedLanguages,

+          Private->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.c
new file mode 100644
index 0000000..38c03a8
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.c
@@ -0,0 +1,1410 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtSerialIo.c

+

+Abstract:

+

+  Our DriverBinding member functions operate on the handles

+  created by the NT Bus driver.

+

+  Handle(1) - WinNtIo - DevicePath(1)

+

+  If a serial port is added to the system this driver creates a new handle. 

+  The new handle is required, since the serial device must add an UART device

+  pathnode.

+

+  Handle(2) - SerialIo - DevicePath(1)\UART

+

+  The driver then adds a gEfiWinNtSerialPortGuid as a protocol to Handle(1).

+  The instance data for this protocol is the private data used to create

+  Handle(2).

+

+  Handle(1) - WinNtIo - DevicePath(1) - WinNtSerialPort

+

+  If the driver is unloaded Handle(2) is removed from the system and 

+  gEfiWinNtSerialPortGuid is removed from Handle(1).

+

+  Note: Handle(1) is any handle created by the Win NT Bus driver that is passed

+  into the DriverBinding member functions of this driver. This driver requires

+  a Handle(1) to contain a WinNtIo protocol, a DevicePath protocol, and 

+  the TypeGuid in the WinNtIo must be gEfiWinNtSerialPortGuid. 

+  

+  If Handle(1) contains a gEfiWinNtSerialPortGuid protocol then the driver is 

+  loaded on the device.

+

+--*/

+

+#include "WinNtSerialIo.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gWinNtSerialIoDriverBinding = {

+  WinNtSerialIoDriverBindingSupported,

+  WinNtSerialIoDriverBindingStart,

+  WinNtSerialIoDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+  EFI_WIN_NT_IO_PROTOCOL    *WinNtIo;

+  UART_DEVICE_PATH          *UartNode;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        Handle,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        Handle

+        );

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure that the WinNt Thunk Protocol is valid

+  //

+  if (WinNtIo->WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {

+    Status = EFI_UNSUPPORTED;

+    goto Error;

+  }

+  

+  //

+  // Check the GUID to see if this is a handle type the driver supports

+  //

+  if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtSerialPortGuid)) {

+    Status = EFI_UNSUPPORTED;

+    goto Error;

+  }

+

+  if (RemainingDevicePath != NULL) {

+    Status    = EFI_UNSUPPORTED;

+    UartNode  = (UART_DEVICE_PATH *) RemainingDevicePath;

+    if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||

+        UartNode->Header.SubType != MSG_UART_DP ||

+        DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL *)UartNode) != sizeof(UART_DEVICE_PATH)) {

+      goto Error;

+    }

+    if (UartNode->BaudRate < 0 || UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {

+      goto Error;

+    }

+    if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {

+      goto Error;

+    }

+    if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {

+      goto Error;

+    }

+    if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {

+      goto Error;

+    }

+    if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {

+      goto Error;

+    }

+    if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {

+      goto Error;

+    }

+    Status = EFI_SUCCESS;

+  }

+

+Error:

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        Handle,

+        &gEfiWinNtIoProtocolGuid,

+        This->DriverBindingHandle,

+        Handle

+        );

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                          Status;

+  EFI_WIN_NT_IO_PROTOCOL              *WinNtIo;

+  WIN_NT_SERIAL_IO_PRIVATE_DATA       *Private;

+  HANDLE                              NtHandle;

+  UART_DEVICE_PATH                    Node;

+  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;

+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;

+  UINTN                               EntryCount;

+  UINTN                               Index;

+  EFI_SERIAL_IO_PROTOCOL              *SerialIo;

+

+  Private   = NULL;

+  NtHandle  = INVALID_HANDLE_VALUE;

+

+  //

+  // Grab the protocols we need

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  //

+  // Grab the IO abstraction we need to get any work done

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    gBS->CloseProtocol (

+          Handle,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          Handle

+          );

+    return Status;

+  }

+

+  if (Status == EFI_ALREADY_STARTED) {

+

+    if (RemainingDevicePath == NULL) {

+      return EFI_SUCCESS;

+    }

+

+    //

+    // Make sure a child handle does not already exist.  This driver can only

+    // produce one child per serial port.

+    //

+    Status = gBS->OpenProtocolInformation (

+                    Handle,

+                    &gEfiWinNtIoProtocolGuid,

+                    &OpenInfoBuffer,

+                    &EntryCount

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = EFI_ALREADY_STARTED;

+    for (Index = 0; Index < EntryCount; Index++) {

+      if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {

+        Status = gBS->OpenProtocol (

+                        OpenInfoBuffer[Index].ControllerHandle,

+                        &gEfiSerialIoProtocolGuid,

+                        &SerialIo,

+                        This->DriverBindingHandle,

+                        Handle,

+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                        );

+        if (!EFI_ERROR (Status)) {

+          CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH));

+          Status = SerialIo->SetAttributes (

+                              SerialIo,

+                              Node.BaudRate,

+                              SerialIo->Mode->ReceiveFifoDepth,

+                              SerialIo->Mode->Timeout,

+                              Node.Parity,

+                              Node.DataBits,

+                              Node.StopBits

+                              );

+        }

+        break;

+      }

+    }

+

+    gBS->FreePool (OpenInfoBuffer);

+    return Status;

+  }

+

+  //

+  // Check to see if we can access the hardware device. If it's Open in NT we

+  // will not get access.

+  //

+  NtHandle = WinNtIo->WinNtThunk->CreateFile (

+                                    WinNtIo->EnvString,

+                                    GENERIC_READ | GENERIC_WRITE,

+                                    0,

+                                    NULL,

+                                    OPEN_EXISTING,

+                                    0,

+                                    NULL

+                                    );

+  if (NtHandle == INVALID_HANDLE_VALUE) {

+    Status = EFI_DEVICE_ERROR;

+    goto Error;

+  }

+

+  //

+  // Construct Private data

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA),

+                  &Private

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  //

+  // This signature must be valid before any member function is called

+  //

+  Private->Signature              = WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE;

+  Private->NtHandle               = NtHandle;

+  Private->ControllerHandle       = Handle;

+  Private->Handle                 = NULL;

+  Private->WinNtThunk             = WinNtIo->WinNtThunk;

+  Private->ParentDevicePath       = ParentDevicePath;

+  Private->ControllerNameTable    = NULL;

+

+  Private->SoftwareLoopbackEnable = FALSE;

+  Private->HardwareLoopbackEnable = FALSE;

+  Private->HardwareFlowControl    = FALSE;

+  Private->Fifo.First             = 0;

+  Private->Fifo.Last              = 0;

+  Private->Fifo.Surplus           = SERIAL_MAX_BUFFER_SIZE;

+

+  AddUnicodeString (

+    "eng",

+    gWinNtSerialIoComponentName.SupportedLanguages,

+    &Private->ControllerNameTable,

+    WinNtIo->EnvString

+    );

+

+  Private->SerialIo.Revision      = SERIAL_IO_INTERFACE_REVISION;

+  Private->SerialIo.Reset         = WinNtSerialIoReset;

+  Private->SerialIo.SetAttributes = WinNtSerialIoSetAttributes;

+  Private->SerialIo.SetControl    = WinNtSerialIoSetControl;

+  Private->SerialIo.GetControl    = WinNtSerialIoGetControl;

+  Private->SerialIo.Write         = WinNtSerialIoWrite;

+  Private->SerialIo.Read          = WinNtSerialIoRead;

+  Private->SerialIo.Mode          = &Private->SerialIoMode;

+

+  if (RemainingDevicePath != NULL) {

+    //

+    // Match the configuration of the RemainingDevicePath. IsHandleSupported()

+    // already checked to make sure the RemainingDevicePath contains settings

+    // that we can support.

+    //

+    CopyMem (&Private->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH));

+  } else {

+    //

+    // Build the device path by appending the UART node to the ParentDevicePath

+    // from the WinNtIo handle. The Uart setings are zero here, since

+    // SetAttribute() will update them to match the default setings.

+    //

+    ZeroMem (&Private->UartDevicePath, sizeof (UART_DEVICE_PATH));

+    Private->UartDevicePath.Header.Type     = MESSAGING_DEVICE_PATH;

+    Private->UartDevicePath.Header.SubType  = MSG_UART_DP;

+    SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));

+  }

+

+  //

+  // Build the device path by appending the UART node to the ParentDevicePath

+  // from the WinNtIo handle. The Uart setings are zero here, since

+  // SetAttribute() will update them to match the current setings.

+  //

+  Private->DevicePath = AppendDevicePathNode (

+                          ParentDevicePath,

+                          (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath

+                          );

+  if (Private->DevicePath == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+

+  //

+  // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.

+  //

+  Private->SerialIoMode.ControlMask       = SERIAL_CONTROL_MASK;

+  Private->SerialIoMode.Timeout           = SERIAL_TIMEOUT_DEFAULT;

+  Private->SerialIoMode.BaudRate          = Private->UartDevicePath.BaudRate;

+  Private->SerialIoMode.ReceiveFifoDepth  = SERIAL_FIFO_DEFAULT;

+  Private->SerialIoMode.DataBits          = Private->UartDevicePath.DataBits;

+  Private->SerialIoMode.Parity            = Private->UartDevicePath.Parity;

+  Private->SerialIoMode.StopBits          = Private->UartDevicePath.StopBits;

+

+  //

+  // Issue a reset to initialize the COM port

+  //

+  Status = Private->SerialIo.Reset (&Private->SerialIo);

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  //

+  // Create new child handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Private->Handle,

+                  &gEfiSerialIoProtocolGuid,

+                  &Private->SerialIo,

+                  &gEfiDevicePathProtocolGuid,

+                  Private->DevicePath,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  //

+  // Open For Child Device

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Private->Handle,

+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  return EFI_SUCCESS;

+

+Error:

+  //

+  // Use the Stop() function to free all resources allocated in Start()

+  //

+  if (Private != NULL) {

+    if (Private->Handle != NULL) {

+      This->Stop (This, Handle, 1, &Private->Handle);

+    } else {

+      if (NtHandle != INVALID_HANDLE_VALUE) {

+        Private->WinNtThunk->CloseHandle (NtHandle);

+      }

+

+      if (Private->DevicePath != NULL) {

+        gBS->FreePool (Private->DevicePath);

+      }

+

+      FreeUnicodeStringTable (Private->ControllerNameTable);

+

+      gBS->FreePool (Private);

+    }

+  }

+

+  This->Stop (This, Handle, 0, NULL);

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  EFI_STATUS                    Status;

+  UINTN                         Index;

+  BOOLEAN                       AllChildrenStopped;

+  EFI_SERIAL_IO_PROTOCOL        *SerialIo;

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  EFI_WIN_NT_IO_PROTOCOL        *WinNtIo;

+

+  //

+  // Complete all outstanding transactions to Controller.

+  // Don't allow any new transaction to Controller to be started.

+  //

+

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    Status = gBS->CloseProtocol (

+                    Handle,

+                    &gEfiWinNtIoProtocolGuid,

+                    This->DriverBindingHandle,

+                    Handle

+                    );

+    Status = gBS->CloseProtocol (

+                    Handle,

+                    &gEfiDevicePathProtocolGuid,

+                    This->DriverBindingHandle,

+                    Handle

+                    );

+    return Status;

+  }

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+    Status = gBS->OpenProtocol (

+                    ChildHandleBuffer[Index],

+                    &gEfiSerialIoProtocolGuid,

+                    &SerialIo,

+                    This->DriverBindingHandle,

+                    Handle,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+      Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo);

+

+      ASSERT (Private->Handle == ChildHandleBuffer[Index]);

+

+      Status = gBS->CloseProtocol (

+                      Handle,

+                      &gEfiWinNtIoProtocolGuid,

+                      This->DriverBindingHandle,

+                      ChildHandleBuffer[Index]

+                      );

+

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      ChildHandleBuffer[Index],

+                      &gEfiSerialIoProtocolGuid,

+                      &Private->SerialIo,

+                      &gEfiDevicePathProtocolGuid,

+                      Private->DevicePath,

+                      NULL

+                      );

+

+      if (EFI_ERROR (Status)) {

+        gBS->OpenProtocol (

+              Handle,

+              &gEfiWinNtIoProtocolGuid,

+              (VOID **) &WinNtIo,

+              This->DriverBindingHandle,

+              ChildHandleBuffer[Index],

+              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+              );

+      } else {

+        Private->WinNtThunk->CloseHandle (Private->NtHandle);

+

+        gBS->FreePool (Private->DevicePath);

+

+        FreeUnicodeStringTable (Private->ControllerNameTable);

+

+        gBS->FreePool (Private);

+      }

+    }

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// Serial IO Protocol member functions

+//

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoReset (

+  IN EFI_SERIAL_IO_PROTOCOL *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  EFI_TPL                       Tpl;

+

+  Tpl     = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  Private->WinNtThunk->PurgeComm (

+                        Private->NtHandle,

+                        PURGE_TXCLEAR | PURGE_RXCLEAR

+                        );

+

+  gBS->RestoreTPL (Tpl);

+

+  return This->SetAttributes (

+                This,

+                This->Mode->BaudRate,

+                This->Mode->ReceiveFifoDepth,

+                This->Mode->Timeout,

+                This->Mode->Parity,

+                (UINT8) This->Mode->DataBits,

+                This->Mode->StopBits

+                );

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoSetAttributes (

+  IN EFI_SERIAL_IO_PROTOCOL *This,

+  IN UINT64                 BaudRate,

+  IN UINT32                 ReceiveFifoDepth,

+  IN UINT32                 Timeout,

+  IN EFI_PARITY_TYPE        Parity,

+  IN UINT8                  DataBits,

+  IN EFI_STOP_BITS_TYPE     StopBits

+  )

+/*++

+

+Routine Description:

+

+  This function is used to set the attributes.

+

+Arguments:

+

+  This              - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.    

+  BaudRate          - The Baud rate of the serial device.

+  ReceiveFifoDepth  - The request depth of fifo on receive side.

+  Timeout           - the request timeout for a single charact.

+  Parity            - The type of parity used in serial device.

+  DataBits          - Number of deata bits used in serial device.

+  StopBits          - Number of stop bits used in serial device.

+

+Returns:

+  Status code

+

+  None

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                    Status;

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  COMMTIMEOUTS                  PortTimeOuts;

+  DWORD                         ConvertedTime;

+  BOOL                          Result;

+  EFI_DEVICE_PATH_PROTOCOL      *NewDevicePath;

+  EFI_TPL                       Tpl;

+

+  Tpl     = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  //  Some of our arguments have defaults if a null value is passed in, and

+  //   we must set the default values if a null argument is passed in.

+  //

+  if (BaudRate == 0) {

+    BaudRate = SERIAL_BAUD_DEFAULT;

+  }

+

+  if (ReceiveFifoDepth == 0) {

+    ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;

+  }

+

+  if (Timeout == 0) {

+    Timeout = SERIAL_TIMEOUT_DEFAULT;

+  }

+

+  if (Parity == DefaultParity) {

+    Parity = NoParity;

+  }

+

+  if (DataBits == 0) {

+    DataBits = SERIAL_DATABITS_DEFAULT;

+  }

+

+  if (StopBits == DefaultStopBits) {

+    StopBits = OneStopBit;

+  }

+  //

+  // See if the new attributes already match the current attributes

+  //

+  if (Private->UartDevicePath.BaudRate       == BaudRate         &&

+      Private->UartDevicePath.DataBits       == DataBits         &&

+      Private->UartDevicePath.Parity         == Parity           &&

+      Private->UartDevicePath.StopBits       == StopBits         &&

+      Private->SerialIoMode.ReceiveFifoDepth == ReceiveFifoDepth &&

+      Private->SerialIoMode.Timeout          == Timeout             ) {

+    gBS->RestoreTPL(Tpl);

+    return EFI_SUCCESS;

+  }

+

+  //

+  //  Get current values from NT

+  //

+  ZeroMem (&Private->NtDCB, sizeof (DCB));

+  Private->NtDCB.DCBlength = sizeof (DCB);

+

+  if (!Private->WinNtThunk->GetCommState (Private->NtHandle, &Private->NtDCB)) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialSetAttributes: GetCommState %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Map EFI com setting to NT

+  //

+  Private->NtDCB.BaudRate         = ConvertBaud2Nt (BaudRate);

+  Private->NtDCB.ByteSize         = ConvertData2Nt (DataBits);

+  Private->NtDCB.Parity           = ConvertParity2Nt (Parity);

+  Private->NtDCB.StopBits         = ConvertStop2Nt (StopBits);

+

+  Private->NtDCB.fBinary          = TRUE;

+  Private->NtDCB.fParity          = Private->NtDCB.Parity == NOPARITY ? FALSE : TRUE;

+  Private->NtDCB.fOutxCtsFlow     = FALSE;

+  Private->NtDCB.fOutxDsrFlow     = FALSE;

+  Private->NtDCB.fDtrControl      = DTR_CONTROL_ENABLE;

+  Private->NtDCB.fDsrSensitivity  = FALSE;

+  Private->NtDCB.fOutX            = FALSE;

+  Private->NtDCB.fInX             = FALSE;

+  Private->NtDCB.fRtsControl      = RTS_CONTROL_ENABLE;

+  Private->NtDCB.fNull            = FALSE;

+

+  //

+  //  Set new values

+  //

+  Result = Private->WinNtThunk->SetCommState (Private->NtHandle, &Private->NtDCB);

+  if (!Result) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommState %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  //  Set com port read/write timeout values

+  //

+  ConvertedTime = ConvertTime2Nt (Timeout);

+  PortTimeOuts.ReadIntervalTimeout = MAXDWORD;

+  PortTimeOuts.ReadTotalTimeoutMultiplier = 0;

+  PortTimeOuts.ReadTotalTimeoutConstant = ConvertedTime;

+  PortTimeOuts.WriteTotalTimeoutMultiplier = ConvertedTime == 0 ? 1 : ConvertedTime;

+  PortTimeOuts.WriteTotalTimeoutConstant = 0;

+

+  if (!Private->WinNtThunk->SetCommTimeouts (Private->NtHandle, &PortTimeOuts)) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommTimeouts %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  //  Update mode

+  //

+  Private->SerialIoMode.BaudRate          = BaudRate;

+  Private->SerialIoMode.ReceiveFifoDepth  = ReceiveFifoDepth;

+  Private->SerialIoMode.Timeout           = Timeout;

+  Private->SerialIoMode.Parity            = Parity;

+  Private->SerialIoMode.DataBits          = DataBits;

+  Private->SerialIoMode.StopBits          = StopBits;

+

+  //

+  // See if Device Path Node has actually changed

+  //

+  if (Private->UartDevicePath.BaudRate     == BaudRate &&

+      Private->UartDevicePath.DataBits     == DataBits &&

+      Private->UartDevicePath.Parity       == Parity   &&

+      Private->UartDevicePath.StopBits     == StopBits    ) {

+    gBS->RestoreTPL(Tpl);

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Update the device path

+  //

+  Private->UartDevicePath.BaudRate  = BaudRate;

+  Private->UartDevicePath.DataBits  = DataBits;

+  Private->UartDevicePath.Parity    = (UINT8) Parity;

+  Private->UartDevicePath.StopBits  = (UINT8) StopBits;

+

+  NewDevicePath = AppendDevicePathNode (

+                    Private->ParentDevicePath,

+                    (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath

+                    );

+  if (NewDevicePath == NULL) {

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (Private->Handle != NULL) {

+    Status = gBS->ReinstallProtocolInterface (

+                    Private->Handle,

+                    &gEfiDevicePathProtocolGuid,

+                    Private->DevicePath,

+                    NewDevicePath

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->RestoreTPL (Tpl);

+      return Status;

+    }

+  }

+

+  if (Private->DevicePath != NULL) {

+    gBS->FreePool (Private->DevicePath);

+  }

+

+  Private->DevicePath = NewDevicePath;

+

+  gBS->RestoreTPL (Tpl);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoSetControl (

+  IN EFI_SERIAL_IO_PROTOCOL *This,

+  IN UINT32                 Control

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Control - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  BOOL                          Result;

+  DCB                           Dcb;

+  EFI_TPL                       Tpl;

+

+  Tpl     = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  Result  = Private->WinNtThunk->GetCommState (Private->NtHandle, &Dcb);

+

+  if (!Result) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialSetControl: GetCommState %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  Dcb.fRtsControl                 = RTS_CONTROL_DISABLE;

+  Dcb.fDtrControl                 = DTR_CONTROL_DISABLE;

+  Private->HardwareFlowControl    = FALSE;

+  Private->SoftwareLoopbackEnable = FALSE;

+  Private->HardwareLoopbackEnable = FALSE;

+

+  if (Control & EFI_SERIAL_REQUEST_TO_SEND) {

+    Dcb.fRtsControl = RTS_CONTROL_ENABLE;

+  }

+

+  if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {

+    Dcb.fDtrControl = DTR_CONTROL_ENABLE;

+  }

+

+  if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {

+    Private->HardwareFlowControl = TRUE;

+  }

+

+  if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) {

+    Private->SoftwareLoopbackEnable = TRUE;

+  }

+

+  if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) {

+    Private->HardwareLoopbackEnable = TRUE;

+  }

+

+  Result = Private->WinNtThunk->SetCommState (

+                                  Private->NtHandle,

+                                  &Dcb

+                                  );

+

+  if (!Result) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialSetControl: SetCommState %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  gBS->RestoreTPL (Tpl);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoGetControl (

+  IN  EFI_SERIAL_IO_PROTOCOL  *This,

+  OUT UINT32                  *Control

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Control - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  DWORD                         ModemStatus;

+  DWORD                         Errors;

+  UINT32                        Bits;

+  DCB                           Dcb;

+  EFI_TPL                       Tpl;

+

+  Tpl     = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  //  Get modem status

+  //

+  if (!Private->WinNtThunk->GetCommModemStatus (Private->NtHandle, &ModemStatus)) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  Bits = 0;

+  if (ModemStatus & MS_CTS_ON) {

+    Bits |= EFI_SERIAL_CLEAR_TO_SEND;

+  }

+

+  if (ModemStatus & MS_DSR_ON) {

+    Bits |= EFI_SERIAL_DATA_SET_READY;

+  }

+

+  if (ModemStatus & MS_RING_ON) {

+    Bits |= EFI_SERIAL_RING_INDICATE;

+  }

+

+  if (ModemStatus & MS_RLSD_ON) {

+    Bits |= EFI_SERIAL_CARRIER_DETECT;

+  }

+  

+  //

+  // Get ctrl status

+  //

+  if (!Private->WinNtThunk->GetCommState (Private->NtHandle, &Dcb)) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialGetControl: GetCommState %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (Dcb.fDtrControl == DTR_CONTROL_ENABLE) {

+    Bits |= EFI_SERIAL_DATA_TERMINAL_READY;

+  }

+

+  if (Dcb.fRtsControl == RTS_CONTROL_ENABLE) {

+    Bits |= EFI_SERIAL_REQUEST_TO_SEND;

+  }

+

+  if (Private->HardwareFlowControl) {

+    Bits |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;

+  }

+

+  if (Private->SoftwareLoopbackEnable) {

+    Bits |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;

+  }

+

+  if (Private->HardwareLoopbackEnable) {

+    Bits |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;

+  }

+  

+  //

+  //  Get input buffer status

+  //

+  if (!Private->WinNtThunk->ClearCommError (Private->NtHandle, &Errors, &Private->NtComStatus)) {

+    Private->NtError = Private->WinNtThunk->GetLastError ();

+    DEBUG ((EFI_D_ERROR, "SerialGetControl: ClearCommError %d\n", Private->NtError));

+    gBS->RestoreTPL (Tpl);

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (Private->NtComStatus.cbInQue == 0) {

+    Bits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;

+  }

+

+  *Control = Bits;

+

+  gBS->RestoreTPL (Tpl);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoWrite (

+  IN EFI_SERIAL_IO_PROTOCOL   *This,

+  IN OUT UINTN                *BufferSize,

+  IN VOID                     *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  UINT8                         *ByteBuffer;

+  UINTN                         TotalBytesWritten;

+  DWORD                         BytesToGo;

+  DWORD                         BytesWritten;

+  BOOL                          Result;

+  UINT32                        Index;

+  UINT32                        Control;

+  EFI_TPL                       Tpl;

+

+  Tpl               = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Private           = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  ByteBuffer        = (UINT8 *) Buffer;

+  TotalBytesWritten = 0;

+

+  if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {

+    for (Index = 0; Index < *BufferSize; Index++) {

+      if (IsaSerialFifoAdd (&Private->Fifo, ByteBuffer[Index]) == EFI_SUCCESS) {

+        TotalBytesWritten++;

+      } else {

+        break;

+      }

+    }

+  } else {

+    BytesToGo = (DWORD) (*BufferSize);

+

+    do {

+      if (Private->HardwareFlowControl) {

+        //

+        // Send RTS

+        //

+        WinNtSerialIoGetControl (&Private->SerialIo, &Control);

+        Control |= EFI_SERIAL_REQUEST_TO_SEND;

+        WinNtSerialIoSetControl (&Private->SerialIo, Control);

+      }

+      

+      //

+      //  Do the write

+      //

+      Result = Private->WinNtThunk->WriteFile (

+                                      Private->NtHandle,

+                                      &ByteBuffer[TotalBytesWritten],

+                                      BytesToGo,

+                                      &BytesWritten,

+                                      NULL

+                                      );

+

+      if (Private->HardwareFlowControl) {

+        //

+        // Assert RTS

+        //

+        WinNtSerialIoGetControl (&Private->SerialIo, &Control);

+        Control &= ~ (UINT32) EFI_SERIAL_REQUEST_TO_SEND;

+        WinNtSerialIoSetControl (&Private->SerialIo, Control);

+      }

+

+      TotalBytesWritten += BytesWritten;

+      BytesToGo -= BytesWritten;

+      if (!Result) {

+        Private->NtError = Private->WinNtThunk->GetLastError ();

+        DEBUG ((EFI_D_ERROR, "SerialWrite: FileWrite %d\n", Private->NtError));

+        *BufferSize = TotalBytesWritten;

+        gBS->RestoreTPL (Tpl);

+        return EFI_DEVICE_ERROR;

+      }

+    } while (BytesToGo > 0);

+  }

+

+  *BufferSize = TotalBytesWritten;

+

+  gBS->RestoreTPL (Tpl);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoRead (

+  IN  EFI_SERIAL_IO_PROTOCOL  *This,

+  IN  OUT UINTN               *BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  EFI_DEVICE_ERROR - TODO: Add description for return value

+

+--*/

+{

+  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;

+  BOOL                          Result;

+  DWORD                         BytesRead;

+  EFI_STATUS                    Status;

+  UINT32                        Index;

+  UINT8                         Data;

+  UINT32                        Control;

+  EFI_TPL                       Tpl;

+

+  Tpl     = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

+

+  //

+  //  Do the read

+  //

+  if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {

+    for (Index = 0, BytesRead = 0; Index < *BufferSize; Index++) {

+      if (IsaSerialFifoRemove (&Private->Fifo, &Data) == EFI_SUCCESS) {

+        ((UINT8 *) Buffer)[Index] = Data;

+        BytesRead++;

+      } else {

+        break;

+      }

+    }

+  } else {

+    if (Private->HardwareFlowControl) {

+      WinNtSerialIoGetControl (&Private->SerialIo, &Control);

+      Control |= EFI_SERIAL_DATA_TERMINAL_READY;

+      WinNtSerialIoSetControl (&Private->SerialIo, Control);

+    }

+

+    Result = Private->WinNtThunk->ReadFile (

+                                    Private->NtHandle,

+                                    Buffer,

+                                    (DWORD) *BufferSize,

+                                    &BytesRead,

+                                    NULL

+                                    );

+

+    if (Private->HardwareFlowControl) {

+      WinNtSerialIoGetControl (&Private->SerialIo, &Control);

+      Control &= ~ (UINT32) EFI_SERIAL_DATA_TERMINAL_READY;

+      WinNtSerialIoSetControl (&Private->SerialIo, Control);

+    }

+

+    if (!Result) {

+      Private->NtError = Private->WinNtThunk->GetLastError ();

+      gBS->RestoreTPL (Tpl);

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  if (BytesRead != *BufferSize) {

+    Status = EFI_TIMEOUT;

+  } else {

+    Status = EFI_SUCCESS;

+  }

+

+  *BufferSize = (UINTN) BytesRead;

+

+  gBS->RestoreTPL (Tpl);

+

+  return Status;

+}

+

+BOOLEAN

+IsaSerialFifoFull (

+  IN SERIAL_DEV_FIFO *Fifo

+  )

+/*++

+

+  Routine Description:

+  Detect whether specific FIFO is full or not

+  

+  Arguments:

+  Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO

+    

+  Returns:

+  TRUE:  the FIFO is full

+  FALSE: the FIFO is not full

+

+--*/

+{

+  if (Fifo->Surplus == 0) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+IsaSerialFifoEmpty (

+  IN SERIAL_DEV_FIFO *Fifo

+  )

+/*++

+

+  Routine Description:

+  Detect whether specific FIFO is empty or not

+  

+  Arguments:

+    Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO

+    

+  Returns:

+    TRUE:  the FIFO is empty

+    FALSE: the FIFO is not empty

+

+--*/

+{

+  if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+IsaSerialFifoAdd (

+  IN SERIAL_DEV_FIFO *Fifo,

+  IN UINT8           Data

+  )

+/*++

+

+  Routine Description:

+  Add data to specific FIFO

+  

+  Arguments:

+    Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO

+    Data  UINT8: the data added to FIFO  

+  

+  Returns:

+    EFI_SUCCESS:  Add data to specific FIFO successfully

+    EFI_OUT_RESOURCE: Failed to add data because FIFO is already full 

+

+--*/

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  //

+  // if FIFO full can not add data

+  //

+  if (IsaSerialFifoFull (Fifo)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // FIFO is not full can add data

+  //

+  Fifo->Data[Fifo->Last] = Data;

+  Fifo->Surplus--;

+  Fifo->Last++;

+  if (Fifo->Last >= SERIAL_MAX_BUFFER_SIZE) {

+    Fifo->Last = 0;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+IsaSerialFifoRemove (

+  IN  SERIAL_DEV_FIFO *Fifo,

+  OUT UINT8           *Data

+  )

+/*++

+

+  Routine Description:

+  Remove data from specific FIFO

+  

+  Arguments:

+    Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO

+    Data  UINT8*: the data removed from FIFO  

+  

+  Returns:

+    EFI_SUCCESS:  Remove data from specific FIFO successfully

+    EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty

+

+--*/

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+{

+  //

+  // if FIFO is empty, no data can remove

+  //

+  if (IsaSerialFifoEmpty (Fifo)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // FIFO is not empty, can remove data

+  //

+  *Data = Fifo->Data[Fifo->First];

+  Fifo->Surplus++;

+  Fifo->First++;

+  if (Fifo->First >= SERIAL_MAX_BUFFER_SIZE) {

+    Fifo->First = 0;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.h
new file mode 100644
index 0000000..79e905c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.h
@@ -0,0 +1,513 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtSerialIo.h

+

+Abstract:

+

+

+--*/

+

+#ifndef _WIN_NT_SERIAL_IO_

+#define _WIN_NT_SERIAL_IO_

+

+

+

+#define SERIAL_MAX_BUFFER_SIZE  256

+#define TIMEOUT_STALL_INTERVAL  10

+

+typedef struct {

+  UINT32  First;

+  UINT32  Last;

+  UINT32  Surplus;

+  UINT8   Data[SERIAL_MAX_BUFFER_SIZE];

+} SERIAL_DEV_FIFO;

+

+#define WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 's', 'i')

+typedef struct {

+  UINT64                    Signature;

+

+  //

+  // Protocol data for the new handle we are going to add

+  //

+  EFI_HANDLE                Handle;

+  EFI_SERIAL_IO_PROTOCOL    SerialIo;

+  EFI_SERIAL_IO_MODE        SerialIoMode;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+

+  //

+  // Private Data

+  //

+  EFI_HANDLE                ControllerHandle;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+  UART_DEVICE_PATH          UartDevicePath;

+  EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;

+

+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;

+

+  //

+  // Private NT type Data;

+  //

+  HANDLE                    NtHandle;

+  DCB                       NtDCB;

+  DWORD                     NtError;

+  COMSTAT                   NtComStatus;

+

+  BOOLEAN                   SoftwareLoopbackEnable;

+  BOOLEAN                   HardwareFlowControl;

+  BOOLEAN                   HardwareLoopbackEnable;

+

+  SERIAL_DEV_FIFO           Fifo;

+

+} WIN_NT_SERIAL_IO_PRIVATE_DATA;

+

+#define WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS(a) \

+         CR(a, WIN_NT_SERIAL_IO_PRIVATE_DATA, SerialIo, WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE)

+

+//

+// Global Protocol Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtSerialIoDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtSerialIoComponentName;

+

+//

+// Macros to convert EFI serial types to NT serial types.

+//

+

+//

+// one second

+//

+#define SERIAL_TIMEOUT_DEFAULT  (1000 * 1000) 

+#define SERIAL_BAUD_DEFAULT     115200

+#define SERIAL_FIFO_DEFAULT     14

+#define SERIAL_DATABITS_DEFAULT 8

+#define SERIAL_PARITY_DEFAULT   DefaultParity

+#define SERIAL_STOPBITS_DEFAULT DefaultStopBits

+

+#define SERIAL_CONTROL_MASK     (EFI_SERIAL_CLEAR_TO_SEND       | \

+                                 EFI_SERIAL_DATA_SET_READY      | \

+                                 EFI_SERIAL_RING_INDICATE       | \

+                                 EFI_SERIAL_CARRIER_DETECT      | \

+                                 EFI_SERIAL_REQUEST_TO_SEND     | \

+                                 EFI_SERIAL_DATA_TERMINAL_READY | \

+                                 EFI_SERIAL_INPUT_BUFFER_EMPTY)

+

+#define ConvertBaud2Nt(x)       (DWORD) x

+#define ConvertData2Nt(x)       (BYTE) x

+

+#define ConvertParity2Nt(x)              \

+    (BYTE) (                             \

+    x == DefaultParity ? NOPARITY    :   \

+    x == NoParity      ? NOPARITY    :   \

+    x == EvenParity    ? EVENPARITY  :   \

+    x == OddParity     ? ODDPARITY   :   \

+    x == MarkParity    ? MARKPARITY  :   \

+    x == SpaceParity   ? SPACEPARITY : 0 \

+    )

+

+#define ConvertStop2Nt(x)                 \

+    (BYTE) (                                \

+    x == DefaultParity   ? ONESTOPBIT   :   \

+    x == OneFiveStopBits ? ONE5STOPBITS :   \

+    x == TwoStopBits     ? TWOSTOPBITS  : 0 \

+    )

+

+#define ConvertTime2Nt(x) ((x) / 1000)

+

+//

+// 115400 baud with rounding errors

+//

+#define SERIAL_PORT_MAX_BAUD_RATE 115400  

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+InitializeWinNtSerialIo (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    Handle,

+  IN  UINTN                         NumberOfChildren,

+  IN  EFI_HANDLE                    *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoReset (

+  IN EFI_SERIAL_IO_PROTOCOL *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoSetAttributes (

+  IN EFI_SERIAL_IO_PROTOCOL *This,

+  IN UINT64                 BaudRate,

+  IN UINT32                 ReceiveFifoDepth,

+  IN UINT32                 Timeout,

+  IN EFI_PARITY_TYPE        Parity,

+  IN UINT8                  DataBits,

+  IN EFI_STOP_BITS_TYPE     StopBits

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  BaudRate          - TODO: add argument description

+  ReceiveFifoDepth  - TODO: add argument description

+  Timeout           - TODO: add argument description

+  Parity            - TODO: add argument description

+  DataBits          - TODO: add argument description

+  StopBits          - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoSetControl (

+  IN EFI_SERIAL_IO_PROTOCOL *This,

+  IN UINT32                 Control

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Control - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoGetControl (

+  IN  EFI_SERIAL_IO_PROTOCOL  *This,

+  OUT UINT32                  *Control

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This    - TODO: add argument description

+  Control - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoWrite (

+  IN EFI_SERIAL_IO_PROTOCOL   *This,

+  IN OUT UINTN                *BufferSize,

+  IN VOID                     *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSerialIoRead (

+  IN  EFI_SERIAL_IO_PROTOCOL  *This,

+  IN  OUT UINTN               *BufferSize,

+  OUT VOID                    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsaSerialFifoFull (

+  IN SERIAL_DEV_FIFO *Fifo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Fifo  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+BOOLEAN

+IsaSerialFifoEmpty (

+  IN SERIAL_DEV_FIFO *Fifo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Fifo  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IsaSerialFifoAdd (

+  IN SERIAL_DEV_FIFO *Fifo,

+  IN UINT8           Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Fifo  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IsaSerialFifoRemove (

+  IN  SERIAL_DEV_FIFO *Fifo,

+  OUT UINT8           *Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Fifo  - TODO: add argument description

+  Data  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+IsaSerialReceiveTransmit (

+  WIN_NT_SERIAL_IO_PRIVATE_DATA     *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.mbd
new file mode 100644
index 0000000..a5b19f9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtSerialIo</BaseName>

+    <Guid>6B41B553-A649-11d4-BD02-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:02</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>UefiDebugLibStdErr</Library>

+    <Library>BasePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.msa
new file mode 100644
index 0000000..fb39a80
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.msa
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtSerialIo</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>6B41B553-A649-11d4-BD02-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtSerialIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:02</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtSerialIo.h</Filename>

+    <Filename>WinNtSerialIo.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">WinNtIo</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="BY_START">SerialIo</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtSerialPort</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gWinNtSerialIoDriverBinding</DriverBinding>

+      <ComponentName>gWinNtSerialIoComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/build.xml
new file mode 100644
index 0000000..7114d3b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SerialIo/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtSerialIo"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Bus\SerialIo"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtSerialIo">

+      <GenBuild baseName="WinNtSerialIo" mbdFilename="${MODULE_DIR}\WinNtSerialIo.mbd" msaFilename="${MODULE_DIR}\WinNtSerialIo.msa"/>

+   </target>

+   <target depends="WinNtSerialIo_clean" name="clean"/>

+   <target depends="WinNtSerialIo_cleanall" name="cleanall"/>

+   <target name="WinNtSerialIo_clean">

+      <OutputDirSetup baseName="WinNtSerialIo" mbdFilename="${MODULE_DIR}\WinNtSerialIo.mbd" msaFilename="${MODULE_DIR}\WinNtSerialIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtSerialIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtSerialIo_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtSerialIo_cleanall">

+      <OutputDirSetup baseName="WinNtSerialIo" mbdFilename="${MODULE_DIR}\WinNtSerialIo.mbd" msaFilename="${MODULE_DIR}\WinNtSerialIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtSerialIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtSerialIo_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtSerialIo*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/ComponentName.c
new file mode 100644
index 0000000..de4abd7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/ComponentName.c
@@ -0,0 +1,193 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "WinNtSimpleFileSystem.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                                        *This,

+  IN  EFI_HANDLE                                                         ControllerHandle,

+  IN  EFI_HANDLE                                                         ChildHandle        OPTIONAL,

+  IN  CHAR8                                                              *Language,

+  OUT CHAR16                                                             **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gWinNtSimpleFileSystemComponentName = {

+  WinNtSimpleFileSystemComponentNameGetDriverName,

+  WinNtSimpleFileSystemComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mWinNtSimpleFileSystemDriverNameTable[] = {

+  {

+    "eng",

+    L"Windows Simple File System Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gWinNtSimpleFileSystemComponentName.SupportedLanguages,

+          mWinNtSimpleFileSystemDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                                        *This,

+  IN  EFI_HANDLE                                                         ControllerHandle,

+  IN  EFI_HANDLE                                                         ChildHandle        OPTIONAL,

+  IN  CHAR8                                                              *Language,

+  OUT CHAR16                                                             **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *SimpleFileSystem;

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  &SimpleFileSystem,

+                  gWinNtSimpleFileSystemDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);

+

+  return LookupUnicodeString (

+          Language,

+          gWinNtSimpleFileSystemComponentName.SupportedLanguages,

+          Private->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.c
new file mode 100644
index 0000000..5552bc2
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.c
@@ -0,0 +1,2615 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtSimpleFileSystem.c

+

+Abstract:

+

+  Produce Simple File System abstractions for directories on your PC using Win32 APIs.

+  The configuration of what devices to mount or emulate comes from NT 

+  environment variables. The variables must be visible to the Microsoft* 

+  Developer Studio for them to work.

+

+  * Other names and brands may be claimed as the property of others.

+

+--*/

+

+#include "WinNtSimpleFileSystem.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = {

+  WinNtSimpleFileSystemDriverBindingSupported,

+  WinNtSimpleFileSystemDriverBindingStart,

+  WinNtSimpleFileSystemDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+

+CHAR16 *

+EfiStrChr (

+  IN CHAR16   *Str,

+  IN CHAR16   Chr

+  )

+/*++

+

+Routine Description:

+

+  Locate the first occurance of a character in a string.

+

+Arguments:

+

+  Str - Pointer to NULL terminated unicode string.

+  Chr - Character to locate.

+

+Returns:

+

+  If Str is NULL, then NULL is returned.

+  If Chr is not contained in Str, then NULL is returned.

+  If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.

+

+--*/

+{

+  if (Str == NULL) {

+    return Str;

+  }

+

+  while (*Str != '\0' && *Str != Chr) {

+    ++Str;

+  }

+

+  return (*Str == Chr) ? Str : NULL;

+}

+

+BOOLEAN

+IsZero (

+  IN VOID   *Buffer,

+  IN UINTN  Length

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Buffer  - TODO: add argument description

+  Length  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  if (Buffer == NULL || Length == 0) {

+    return FALSE;

+  }

+

+  if (*(UINT8 *) Buffer != 0) {

+    return FALSE;

+  }

+

+  if (Length > 1) {

+    if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+VOID

+CutPrefix (

+  IN  CHAR16  *Str,

+  IN  UINTN   Count

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Str   - TODO: add argument description

+  Count - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  CHAR16  *Pointer;

+

+  if (StrLen (Str) < Count) {

+    ASSERT (0);

+  }

+

+  for (Pointer = Str; *(Pointer + Count); Pointer++) {

+    *Pointer = *(Pointer + Count);

+  }

+

+  *Pointer = *(Pointer + Count);

+}

+

+

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Check to see if the driver supports a given controller.

+

+Arguments:

+

+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.

+

+  ControllerHandle    - EFI handle of the controller to test.

+

+  RemainingDevicePath - Pointer to remaining portion of a device path.

+

+Returns:

+

+  EFI_SUCCESS         - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver

+                        specified by This.

+

+  EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by

+                        the driver specified by This.

+

+  EFI_ACCESS_DENIED   - The device specified by ControllerHandle and RemainingDevicePath is already being managed by

+                        a different driver or an application that requires exclusive access.

+

+  EFI_UNSUPPORTED     - The device specified by ControllerHandle and RemainingDevicePath is not supported by the

+                        driver specified by This.

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure GUID is for a File System handle.

+  //

+  Status = EFI_UNSUPPORTED;

+  if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {

+    Status = EFI_SUCCESS;

+  }

+

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiWinNtIoProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  Starts a device controller or a bus controller.

+

+Arguments:

+

+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.

+

+  ControllerHandle    - EFI handle of the controller to start.

+

+  RemainingDevicePath - Pointer to remaining portion of a device path.

+

+Returns:

+

+  EFI_SUCCESS           - The device or bus controller has been started.

+

+  EFI_DEVICE_ERROR      - The device could not be started due to a device failure.

+

+  EFI_OUT_OF_RESOURCES  - The request could not be completed due to lack of resources.

+

+--*/

+{

+  EFI_STATUS                        Status;

+  EFI_WIN_NT_IO_PROTOCOL            *WinNtIo;

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;

+

+  Private = NULL;

+

+  //

+  // Open the IO Abstraction(s) needed

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Validate GUID

+  //

+  if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE),

+                  &Private

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Private->Signature  = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;

+  Private->WinNtThunk = WinNtIo->WinNtThunk;

+

+  Private->FilePath = WinNtIo->EnvString;

+

+  Private->VolumeLabel      = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (L"EFI_EMULATED"),

+                  &Private->VolumeLabel

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  StrCpy (Private->VolumeLabel, L"EFI_EMULATED");

+

+  Private->SimpleFileSystem.Revision    = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;

+  Private->SimpleFileSystem.OpenVolume  = WinNtSimpleFileSystemOpenVolume;

+

+  Private->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS);

+

+  Private->ControllerNameTable = NULL;

+

+  AddUnicodeString (

+    "eng",

+    gWinNtSimpleFileSystemComponentName.SupportedLanguages,

+    &Private->ControllerNameTable,

+    WinNtIo->EnvString

+    );

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ControllerHandle,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  &Private->SimpleFileSystem,

+                  NULL

+                  );

+

+Done:

+  if (EFI_ERROR (Status)) {

+

+    if (Private != NULL) {

+

+      FreeUnicodeStringTable (Private->ControllerNameTable);

+

+      gBS->FreePool (Private);

+    }

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiWinNtIoProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.

+

+  ControllerHandle  - A handle to the device to be stopped.

+

+  NumberOfChildren  - The number of child device handles in ChildHandleBuffer.

+

+  ChildHandleBuffer - An array of child device handles to be freed.

+

+Returns:

+

+  EFI_SUCCESS       - The device has been stopped.

+

+  EFI_DEVICE_ERROR  - The device could not be stopped due to a device failure.

+

+--*/

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *SimpleFileSystem;

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  &SimpleFileSystem,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);

+

+  //

+  // Uninstall the Simple File System Protocol from ControllerHandle

+  //

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  ControllerHandle,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  &Private->SimpleFileSystem,

+                  NULL

+                  );

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->CloseProtocol (

+                    ControllerHandle,

+                    &gEfiWinNtIoProtocolGuid,

+                    This->DriverBindingHandle,

+                    ControllerHandle

+                    );

+  }

+

+  if (!EFI_ERROR (Status)) {

+    //

+    // Free our instance data

+    //

+    FreeUnicodeStringTable (Private->ControllerNameTable);

+

+    gBS->FreePool (Private);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemOpenVolume (

+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,

+  OUT EFI_FILE                        **Root

+  )

+/*++

+

+Routine Description:

+

+  Open the root directory on a volume.

+

+Arguments:

+

+  This  - A pointer to the volume to open.

+

+  Root  - A pointer to storage for the returned opened file handle of the root directory.

+

+Returns:

+

+  EFI_SUCCESS           - The volume was opened.

+

+  EFI_UNSUPPORTED       - The volume does not support the requested file system type.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.

+

+  EFI_ACCESS_DENIED     - The service denied access to the file.

+

+  EFI_OUT_OF_RESOURCES  - The file volume could not be opened due to lack of resources.

+

+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;

+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;

+

+  if (This == NULL || Root == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private     = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);

+

+  PrivateFile = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (WIN_NT_EFI_FILE_PRIVATE),

+                  &PrivateFile

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  PrivateFile->FileName = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (Private->FilePath),

+                  &PrivateFile->FileName

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  PrivateFile->FilePath = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (Private->FilePath),

+                  &PrivateFile->FilePath

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  StrCpy (PrivateFile->FilePath, Private->FilePath);

+  StrCpy (PrivateFile->FileName, PrivateFile->FilePath);

+  PrivateFile->Signature            = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE;

+  PrivateFile->WinNtThunk           = Private->WinNtThunk;

+  PrivateFile->SimpleFileSystem     = This;

+  PrivateFile->IsRootDirectory      = TRUE;

+  PrivateFile->IsDirectoryPath      = TRUE;

+  PrivateFile->IsOpenedByRead       = TRUE;

+  PrivateFile->EfiFile.Revision     = EFI_FILE_HANDLE_REVISION;

+  PrivateFile->EfiFile.Open         = WinNtSimpleFileSystemOpen;

+  PrivateFile->EfiFile.Close        = WinNtSimpleFileSystemClose;

+  PrivateFile->EfiFile.Delete       = WinNtSimpleFileSystemDelete;

+  PrivateFile->EfiFile.Read         = WinNtSimpleFileSystemRead;

+  PrivateFile->EfiFile.Write        = WinNtSimpleFileSystemWrite;

+  PrivateFile->EfiFile.GetPosition  = WinNtSimpleFileSystemGetPosition;

+  PrivateFile->EfiFile.SetPosition  = WinNtSimpleFileSystemSetPosition;

+  PrivateFile->EfiFile.GetInfo      = WinNtSimpleFileSystemGetInfo;

+  PrivateFile->EfiFile.SetInfo      = WinNtSimpleFileSystemSetInfo;

+  PrivateFile->EfiFile.Flush        = WinNtSimpleFileSystemFlush;

+  PrivateFile->LHandle              = INVALID_HANDLE_VALUE;

+  PrivateFile->DirHandle            = INVALID_HANDLE_VALUE;

+  PrivateFile->IsValidFindBuf       = FALSE;

+  

+  *Root = &PrivateFile->EfiFile;

+

+  Status = EFI_SUCCESS;

+

+Done:

+  if (EFI_ERROR (Status)) {

+    if (PrivateFile) {

+      if (PrivateFile->FileName) {

+        gBS->FreePool (PrivateFile->FileName);

+      }

+

+      if (PrivateFile->FilePath) {

+        gBS->FreePool (PrivateFile->FilePath);

+      }

+

+      gBS->FreePool (PrivateFile);

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemOpen (

+  IN  EFI_FILE  *This,

+  OUT EFI_FILE  **NewHandle,

+  IN  CHAR16    *FileName,

+  IN  UINT64    OpenMode,

+  IN  UINT64    Attributes

+  )

+/*++

+

+Routine Description:

+

+  Open a file relative to the source file location.

+

+Arguments:

+

+  This        - A pointer to the source file location.

+

+  NewHandle   - Pointer to storage for the new file handle.

+

+  FileName    - Pointer to the file name to be opened.

+

+  OpenMode    - File open mode information.

+

+  Attributes  - File creation attributes.

+

+Returns:

+

+  EFI_SUCCESS           - The file was opened.

+

+  EFI_NOT_FOUND         - The file could not be found in the volume.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.

+

+  EFI_WRITE_PROTECTED   - The volume or file is write protected.

+

+  EFI_ACCESS_DENIED     - The service denied access to the file.

+

+  EFI_OUT_OF_RESOURCES  - Not enough resources were available to open the file.

+

+  EFI_VOLUME_FULL       - There is not enough space left to create the new file.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_FILE                          *Root;

+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;

+  WIN_NT_EFI_FILE_PRIVATE           *NewPrivateFile;

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;

+  EFI_STATUS                        Status;

+  CHAR16                            *RealFileName;

+  CHAR16                            *TempFileName;

+  CHAR16                            *ParseFileName;

+  CHAR16                            *GuardPointer;

+  CHAR16                            TempChar;

+  DWORD                             LastError;

+  UINTN                             Count;

+  BOOLEAN                           TrailingDash;

+  BOOLEAN                           LoopFinish;

+  UINTN                             InfoSize;

+  EFI_FILE_INFO                     *Info;

+

+  TrailingDash = FALSE;

+

+  //

+  // Check for obvious invalid parameters.

+  //

+  if (This == NULL || NewHandle == NULL || FileName == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  switch (OpenMode) {

+  case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:

+    if (Attributes &~EFI_FILE_VALID_ATTR) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (Attributes & EFI_FILE_READ_ONLY) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+  //

+  // fall through

+  //

+  case EFI_FILE_MODE_READ:

+  case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  //

+  //

+  PrivateFile     = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+  PrivateRoot     = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);

+  NewPrivateFile  = NULL;

+

+  //

+  // BUGBUG: assume an open of root

+  // if current location, return current data

+  //

+  if (StrCmp (FileName, L"\\") == 0 || (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {

+    //

+    // BUGBUG: assume an open root

+    //

+OpenRoot:

+    Status          = WinNtSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);

+    NewPrivateFile  = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);

+    goto Done;

+  }

+

+  if (FileName[StrLen (FileName) - 1] == L'\\') {

+    TrailingDash                        = TRUE;

+    FileName[StrLen (FileName) - 1]  = 0;

+  }

+

+  //

+  // Attempt to open the file

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (WIN_NT_EFI_FILE_PRIVATE),

+                  &NewPrivateFile

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE));

+

+  NewPrivateFile->FilePath = NULL;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (PrivateFile->FileName),

+                  &NewPrivateFile->FilePath

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  if (PrivateFile->IsDirectoryPath) {

+    StrCpy (NewPrivateFile->FilePath, PrivateFile->FileName);

+  } else {

+    StrCpy (NewPrivateFile->FilePath, PrivateFile->FilePath);

+  }

+

+  NewPrivateFile->FileName = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (NewPrivateFile->FilePath) + StrSize (L"\\") + StrSize (FileName),

+                  &NewPrivateFile->FileName

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  if (*FileName == L'\\') {

+    StrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath);

+    StrCat (NewPrivateFile->FileName, L"\\");

+    StrCat (NewPrivateFile->FileName, FileName + 1);

+  } else {

+    StrCpy (NewPrivateFile->FileName, NewPrivateFile->FilePath);

+    StrCat (NewPrivateFile->FileName, L"\\");

+    StrCat (NewPrivateFile->FileName, FileName);

+  }

+

+  //

+  // Get rid of . and .., except leading . or ..

+  //

+

+  //

+  // GuardPointer protect simplefilesystem root path not be destroyed

+  //

+  GuardPointer  = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath);

+

+  LoopFinish    = FALSE;

+

+  while (!LoopFinish) {

+

+    LoopFinish = TRUE;

+

+    for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {

+      if (*ParseFileName == L'.' &&

+          (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == L'\\') &&

+          *(ParseFileName - 1) == L'\\'

+          ) {

+

+        //

+        // cut \.

+        //

+        CutPrefix (ParseFileName - 1, 2);

+        LoopFinish = FALSE;

+        break;

+      }

+

+      if (*ParseFileName == L'.' &&

+          *(ParseFileName + 1) == L'.' &&

+          (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == L'\\') &&

+          *(ParseFileName - 1) == L'\\'

+          ) {

+

+        ParseFileName--;

+        Count = 3;

+

+        while (ParseFileName != GuardPointer) {

+          ParseFileName--;

+          Count++;

+          if (*ParseFileName == L'\\') {

+            break;

+          }

+        }

+

+        //

+        // cut \.. and its left directory

+        //

+        CutPrefix (ParseFileName, Count);

+        LoopFinish = FALSE;

+        break;

+      }

+    }

+  }

+

+  if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {

+    NewPrivateFile->IsRootDirectory = TRUE;

+    gBS->FreePool (NewPrivateFile->FilePath);

+    gBS->FreePool (NewPrivateFile->FileName);

+    gBS->FreePool (NewPrivateFile);

+    goto OpenRoot;

+  }

+

+  RealFileName = NewPrivateFile->FileName;

+  while (EfiStrChr (RealFileName, L'\\') != NULL) {

+    RealFileName = EfiStrChr (RealFileName, L'\\') + 1;

+  }

+

+  TempChar            = *(RealFileName - 1);

+  *(RealFileName - 1) = 0;

+

+  gBS->FreePool (NewPrivateFile->FilePath);

+  NewPrivateFile->FilePath = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (NewPrivateFile->FileName),

+                  &NewPrivateFile->FilePath

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  StrCpy (NewPrivateFile->FilePath, NewPrivateFile->FileName);

+

+  *(RealFileName - 1)             = TempChar;

+

+  NewPrivateFile->IsRootDirectory = FALSE;

+

+  //

+  // Test whether file or directory

+  //

+  if (OpenMode & EFI_FILE_MODE_CREATE) {

+    if (Attributes & EFI_FILE_DIRECTORY) {

+      NewPrivateFile->IsDirectoryPath = TRUE;

+    } else {

+      NewPrivateFile->IsDirectoryPath = FALSE;

+    }

+  } else {

+    NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;

+    NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (

+                                                            NewPrivateFile->FileName,

+                                                            GENERIC_READ,

+                                                            FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                            NULL,

+                                                            OPEN_EXISTING,

+                                                            0,

+                                                            NULL

+                                                            );

+

+    if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) {

+      NewPrivateFile->IsDirectoryPath = FALSE;

+      NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);

+    } else {

+      NewPrivateFile->IsDirectoryPath = TRUE;

+    }

+

+    NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;

+  }

+

+  if (OpenMode & EFI_FILE_MODE_WRITE) {

+    NewPrivateFile->IsOpenedByRead = FALSE;

+  } else {

+    NewPrivateFile->IsOpenedByRead = TRUE;

+  }

+

+  Status = EFI_SUCCESS;

+

+  //

+  // deal with directory

+  //

+  if (NewPrivateFile->IsDirectoryPath) {

+

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    StrSize (NewPrivateFile->FileName) + StrSize (L"\\*"),

+                    &TempFileName

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    StrCpy (TempFileName, NewPrivateFile->FileName);

+

+    if ((OpenMode & EFI_FILE_MODE_CREATE)) {

+      //

+      // Create a directory

+      //

+      if (!NewPrivateFile->WinNtThunk->CreateDirectory (TempFileName, NULL)) {

+

+        LastError = PrivateFile->WinNtThunk->GetLastError ();

+        if (LastError != ERROR_ALREADY_EXISTS) {

+          gBS->FreePool (TempFileName);

+          Status = EFI_ACCESS_DENIED;

+          goto Done;

+        }

+      }

+    }

+

+    NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (

+                                                              TempFileName,

+                                                              NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),

+                                                              FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                              NULL,

+                                                              OPEN_EXISTING,

+                                                              FILE_FLAG_BACKUP_SEMANTICS,

+                                                              NULL

+                                                              );

+

+    if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) {

+

+      NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (

+                                                                TempFileName,

+                                                                GENERIC_READ,

+                                                                FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                                NULL,

+                                                                OPEN_EXISTING,

+                                                                FILE_FLAG_BACKUP_SEMANTICS,

+                                                                NULL

+                                                                );

+

+      if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) {

+        NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->DirHandle);

+        NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE;

+        Status                    = EFI_ACCESS_DENIED;

+      } else {

+        Status = EFI_NOT_FOUND;

+      }

+

+      goto Done;

+    }

+

+    //

+    // Find the first file under it

+    //

+    StrCat (TempFileName, L"\\*");

+    NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->FindFirstFile (TempFileName, &NewPrivateFile->FindBuf);

+

+    if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+      NewPrivateFile->IsValidFindBuf = FALSE;

+    } else {

+      NewPrivateFile->IsValidFindBuf = TRUE;

+    }

+  } else {

+    //

+    // deal with file

+    //

+    if (!NewPrivateFile->IsOpenedByRead) {

+      NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (

+                                                              NewPrivateFile->FileName,

+                                                              GENERIC_READ | GENERIC_WRITE,

+                                                              FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                              NULL,

+                                                              (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,

+                                                              0,

+                                                              NULL

+                                                              );

+

+      if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+        NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (

+                                                                NewPrivateFile->FileName,

+                                                                GENERIC_READ,

+                                                                FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                                NULL,

+                                                                OPEN_EXISTING,

+                                                                0,

+                                                                NULL

+                                                                );

+

+        if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+          Status = EFI_NOT_FOUND;

+        } else {

+          Status = EFI_ACCESS_DENIED;

+          NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);

+          NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;

+        }

+      }

+    } else {

+      NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (

+                                                              NewPrivateFile->FileName,

+                                                              GENERIC_READ,

+                                                              FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                              NULL,

+                                                              OPEN_EXISTING,

+                                                              0,

+                                                              NULL

+                                                              );

+

+      if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+        Status = EFI_NOT_FOUND;

+      }

+    }

+  }

+

+  if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) {

+    //

+    // Set the attribute

+    //

+    InfoSize  = 0;

+    Info      = NULL;

+

+    Status    = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);

+

+    if (Status != EFI_BUFFER_TOO_SMALL) {

+      Status = EFI_DEVICE_ERROR;

+      goto Done;

+    }

+

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    InfoSize,

+                    &Info

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);

+

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    Info->Attribute = Attributes;

+

+    WinNtSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);

+  }

+

+Done: ;

+  if (TrailingDash) {

+    FileName[StrLen (FileName) + 1]  = 0;

+    FileName[StrLen (FileName)]      = L'\\';

+  }

+

+  if (EFI_ERROR (Status)) {

+    if (NewPrivateFile) {

+      if (NewPrivateFile->FileName) {

+        gBS->FreePool (NewPrivateFile->FileName);

+      }

+

+      if (NewPrivateFile->FilePath) {

+        gBS->FreePool (NewPrivateFile->FilePath);

+      }

+

+      gBS->FreePool (NewPrivateFile);

+    }

+  } else {

+    *NewHandle = &NewPrivateFile->EfiFile;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemClose (

+  IN EFI_FILE  *This

+  )

+/*++

+

+Routine Description:

+

+  Close the specified file handle.

+

+Arguments:

+

+  This  - Pointer to a returned opened file handle.

+

+Returns:

+

+  EFI_SUCCESS - The file handle has been closed.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {

+    if (PrivateFile->IsDirectoryPath) {

+      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);

+    } else {

+      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);

+    }

+

+    PrivateFile->LHandle = INVALID_HANDLE_VALUE;

+  }

+

+  if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {

+    PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);

+    PrivateFile->DirHandle = INVALID_HANDLE_VALUE;

+  }

+

+  if (PrivateFile->FileName) {

+    gBS->FreePool (PrivateFile->FileName);

+  }

+

+  gBS->FreePool (PrivateFile);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDelete (

+  IN EFI_FILE  *This

+  )

+/*++

+

+Routine Description:

+

+  Close and delete a file.

+

+Arguments:

+

+  This  - Pointer to a returned opened file handle.

+

+Returns:

+

+  EFI_SUCCESS             - The file handle was closed and deleted.

+

+  EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS              Status;

+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  Status      = EFI_WARN_DELETE_FAILURE;

+

+  if (PrivateFile->IsDirectoryPath) {

+    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {

+      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);

+    }

+

+    if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {

+      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);

+      PrivateFile->DirHandle = INVALID_HANDLE_VALUE;

+    }

+

+    if (PrivateFile->WinNtThunk->RemoveDirectory (PrivateFile->FileName)) {

+      Status = EFI_SUCCESS;

+    }

+  } else {

+    PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);

+    PrivateFile->LHandle = INVALID_HANDLE_VALUE;

+

+    if (!PrivateFile->IsOpenedByRead) {

+      if (PrivateFile->WinNtThunk->DeleteFile (PrivateFile->FileName)) {

+        Status = EFI_SUCCESS;

+      }

+    }

+  }

+

+  gBS->FreePool (PrivateFile->FileName);

+  gBS->FreePool (PrivateFile);

+

+  return Status;

+}

+

+STATIC

+VOID

+WinNtSystemTimeToEfiTime (

+  IN SYSTEMTIME             *SystemTime,

+  IN TIME_ZONE_INFORMATION  *TimeZone,

+  OUT EFI_TIME              *Time

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SystemTime  - TODO: add argument description

+  TimeZone    - TODO: add argument description

+  Time        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  Time->Year        = (UINT16) SystemTime->wYear;

+  Time->Month       = (UINT8) SystemTime->wMonth;

+  Time->Day         = (UINT8) SystemTime->wDay;

+  Time->Hour        = (UINT8) SystemTime->wHour;

+  Time->Minute      = (UINT8) SystemTime->wMinute;

+  Time->Second      = (UINT8) SystemTime->wSecond;

+  Time->Nanosecond  = (UINT32) SystemTime->wMilliseconds * 1000000;

+  Time->TimeZone    = (INT16) TimeZone->Bias;

+

+  if (TimeZone->StandardDate.wMonth) {

+    Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemRead (

+  IN     EFI_FILE  *This,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Read data from a file.

+

+Arguments:

+

+  This        - Pointer to a returned open file handle.

+

+  BufferSize  - On input, the size of the Buffer.  On output, the number of bytes stored in the Buffer.

+

+  Buffer      - Pointer to the first byte of the read Buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The data was read.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.

+

+  EFI_BUFFER_TOO_SMALL  - The supplied buffer size was too small to store the current directory entry.

+                          *BufferSize has been updated with the size needed to complete the request.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;

+  EFI_STATUS              Status;

+  UINTN                   Size;

+  UINTN                   NameSize;

+  UINTN                   ResultSize;

+  UINTN                   Index;

+  SYSTEMTIME              SystemTime;

+  EFI_FILE_INFO           *Info;

+  WCHAR                   *pw;

+  TIME_ZONE_INFORMATION   TimeZone;

+  EFI_FILE_INFO           *FileInfo;

+  UINT64                  Pos;

+  UINT64                  FileSize;

+  UINTN                   FileInfoSize;

+

+  if (This == NULL || BufferSize == NULL || Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (!PrivateFile->IsDirectoryPath) {

+

+    if (This->GetPosition (This, &Pos) != EFI_SUCCESS) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO;

+    gBS->AllocatePool (

+          EfiBootServicesData,

+          FileInfoSize,

+          &FileInfo

+          );

+

+    Status = This->GetInfo (

+                    This,

+                    &gEfiFileInfoGuid,

+                    &FileInfoSize,

+                    FileInfo

+                    );

+

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      gBS->FreePool (FileInfo);

+      gBS->AllocatePool (

+            EfiBootServicesData,

+            FileInfoSize,

+            &FileInfo

+            );

+      Status = This->GetInfo (

+                      This,

+                      &gEfiFileInfoGuid,

+                      &FileInfoSize,

+                      FileInfo

+                      );

+    }

+

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    FileSize = FileInfo->FileSize;

+

+    gBS->FreePool (FileInfo);

+

+    if (Pos >= FileSize) {

+      *BufferSize = 0;

+      if (Pos == FileSize) {

+        return EFI_SUCCESS;

+      } else {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+

+    return PrivateFile->WinNtThunk->ReadFile (

+                                      PrivateFile->LHandle,

+                                      Buffer,

+                                      *BufferSize,

+                                      BufferSize,

+                                      NULL

+                                      ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Read on a directory.  Perform a find next

+  //

+  if (!PrivateFile->IsValidFindBuf) {

+    *BufferSize = 0;

+    return EFI_SUCCESS;

+  }

+

+  Size        = SIZE_OF_EFI_FILE_INFO;

+

+  NameSize    = StrSize (PrivateFile->FindBuf.cFileName);

+

+  ResultSize  = Size + NameSize;

+

+  Status      = EFI_BUFFER_TOO_SMALL;

+

+  if (*BufferSize >= ResultSize) {

+    Status  = EFI_SUCCESS;

+

+    Info    = Buffer;

+    ZeroMem (Info, ResultSize);

+

+    Info->Size = ResultSize;

+

+    PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);

+

+    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (

+                              &PrivateFile->FindBuf.ftCreationTime,

+                              &PrivateFile->FindBuf.ftCreationTime

+                              );

+

+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftCreationTime, &SystemTime);

+

+    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->CreateTime);

+

+    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (

+                              &PrivateFile->FindBuf.ftLastWriteTime,

+                              &PrivateFile->FindBuf.ftLastWriteTime

+                              );

+

+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftLastWriteTime, &SystemTime);

+

+    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->ModificationTime);

+

+    Info->FileSize      = PrivateFile->FindBuf.nFileSizeLow;

+

+    Info->PhysicalSize  = PrivateFile->FindBuf.nFileSizeLow;

+

+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {

+      Info->Attribute |= EFI_FILE_ARCHIVE;

+    }

+

+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {

+      Info->Attribute |= EFI_FILE_HIDDEN;

+    }

+

+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {

+      Info->Attribute |= EFI_FILE_SYSTEM;

+    }

+

+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {

+      Info->Attribute |= EFI_FILE_READ_ONLY;

+    }

+

+    if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

+      Info->Attribute |= EFI_FILE_DIRECTORY;

+    }

+

+    NameSize  = NameSize / sizeof (WCHAR);

+

+    pw        = (WCHAR *) (((CHAR8 *) Buffer) + Size);

+

+    for (Index = 0; Index < NameSize; Index++) {

+      pw[Index] = PrivateFile->FindBuf.cFileName[Index];

+    }

+

+    if (PrivateFile->WinNtThunk->FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) {

+      PrivateFile->IsValidFindBuf = TRUE;

+    } else {

+      PrivateFile->IsValidFindBuf = FALSE;

+    }

+  }

+

+  *BufferSize = ResultSize;

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemWrite (

+  IN     EFI_FILE  *This,

+  IN OUT UINTN     *BufferSize,

+  IN     VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Write data to a file.

+

+Arguments:

+

+  This        - Pointer to an opened file handle.

+

+  BufferSize  - On input, the number of bytes in the Buffer to write to the file.  On output, the number of bytes

+                of data written to the file.

+

+  Buffer      - Pointer to the first by of data in the buffer to write to the file.

+

+Returns:

+

+  EFI_SUCCESS           - The data was written to the file.

+

+  EFI_UNSUPPORTED       - Writes to an open directory are not supported.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.

+

+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.

+

+  EFI_ACCESS_DENIED     - The file was opened read-only.

+

+  EFI_VOLUME_FULL       - The volume is full.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;

+

+  if (This == NULL || BufferSize == NULL || Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (PrivateFile->IsDirectoryPath) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (PrivateFile->IsOpenedByRead) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  return PrivateFile->WinNtThunk->WriteFile (

+                                    PrivateFile->LHandle,

+                                    Buffer,

+                                    *BufferSize,

+                                    BufferSize,

+                                    NULL

+                                    ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;

+

+  //

+  // bugbug: need to access windows error reporting

+  //

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemSetPosition (

+  IN EFI_FILE  *This,

+  IN UINT64    Position

+  )

+/*++

+

+Routine Description:

+

+  Set a file's current position.

+

+Arguments:

+

+  This      - Pointer to an opened file handle.

+

+  Position  - The byte position from the start of the file to set.

+

+Returns:

+

+  EFI_SUCCESS     - The file position has been changed.

+

+  EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS              Status;

+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;

+  UINT32                  PosLow;

+  UINT32                  PosHigh;

+  CHAR16                  *FileName;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  if (PrivateFile->IsDirectoryPath) {

+    if (Position != 0) {

+      return EFI_UNSUPPORTED;

+    }

+

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    StrSize (PrivateFile->FileName) + StrSize (L"\\*"),

+                    &FileName

+                    );

+

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    StrCpy (FileName, PrivateFile->FileName);

+    StrCat (FileName, L"\\*");

+

+    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {

+      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);

+    }

+

+    PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (FileName, &PrivateFile->FindBuf);

+

+    if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+      PrivateFile->IsValidFindBuf = FALSE;

+    } else {

+      PrivateFile->IsValidFindBuf = TRUE;

+    }

+

+    gBS->FreePool (FileName);

+

+    Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS;

+  } else {

+    if (Position == (UINT64) -1) {

+      PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) 0, NULL, FILE_END);

+    } else {

+      PosHigh = (UINT32) RShiftU64 (Position, 32);

+

+      PosLow  = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, &PosHigh, FILE_BEGIN);

+    }

+

+    Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemGetPosition (

+  IN  EFI_FILE  *This,

+  OUT UINT64    *Position

+  )

+/*++

+

+Routine Description:

+

+  Get a file's current position.

+

+Arguments:

+

+  This      - Pointer to an opened file handle.

+

+  Position  - Pointer to storage for the current position.

+

+Returns:

+

+  EFI_SUCCESS     - The file position has been reported.

+

+  EFI_UNSUPPORTED - Not valid for directories.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS              Status;

+  WIN_NT_EFI_FILE_PRIVATE *PrivateFile;

+  INT32                   PositionHigh;

+  UINT64                  PosHigh64;

+

+  if (This == NULL || Position == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile   = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  PositionHigh  = 0;

+  PosHigh64     = 0;

+

+  if (PrivateFile->IsDirectoryPath) {

+

+    return EFI_UNSUPPORTED;

+

+  } else {

+

+    PositionHigh = 0;

+    *Position = PrivateFile->WinNtThunk->SetFilePointer (

+                                          PrivateFile->LHandle,

+                                          0,

+                                          &PositionHigh,

+                                          FILE_CURRENT

+                                          );

+

+    Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    PosHigh64 = PositionHigh;

+    *Position += LShiftU64 (PosHigh64, 32);

+  }

+

+Done:

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+WinNtSimpleFileSystemFileInfo (

+  IN     WIN_NT_EFI_FILE_PRIVATE  *PrivateFile,

+  IN OUT UINTN                    *BufferSize,

+  OUT    VOID                     *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PrivateFile - TODO: add argument description

+  BufferSize  - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS                  Status;

+  UINTN                       Size;

+  UINTN                       NameSize;

+  UINTN                       ResultSize;

+  EFI_FILE_INFO               *Info;

+  BY_HANDLE_FILE_INFORMATION  FileInfo;

+  SYSTEMTIME                  SystemTime;

+  CHAR16                      *RealFileName;

+  CHAR16                      *TempPointer;

+

+  Size        = SIZE_OF_EFI_FILE_INFO;

+  NameSize    = StrSize (PrivateFile->FileName);

+  ResultSize  = Size + NameSize;

+

+  Status      = EFI_BUFFER_TOO_SMALL;

+  if (*BufferSize >= ResultSize) {

+    Status  = EFI_SUCCESS;

+

+    Info    = Buffer;

+    ZeroMem (Info, ResultSize);

+

+    Info->Size = ResultSize;

+    PrivateFile->WinNtThunk->GetFileInformationByHandle (

+                              PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,

+                              &FileInfo

+                              );

+    Info->FileSize      = FileInfo.nFileSizeLow;

+    Info->PhysicalSize  = Info->FileSize;

+

+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftCreationTime, &SystemTime);

+    Info->CreateTime.Year   = SystemTime.wYear;

+    Info->CreateTime.Month  = (UINT8) SystemTime.wMonth;

+    Info->CreateTime.Day    = (UINT8) SystemTime.wDay;

+    Info->CreateTime.Hour   = (UINT8) SystemTime.wHour;

+    Info->CreateTime.Minute = (UINT8) SystemTime.wMinute;

+    Info->CreateTime.Second = (UINT8) SystemTime.wSecond;

+

+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastAccessTime, &SystemTime);

+    Info->LastAccessTime.Year   = SystemTime.wYear;

+    Info->LastAccessTime.Month  = (UINT8) SystemTime.wMonth;

+    Info->LastAccessTime.Day    = (UINT8) SystemTime.wDay;

+    Info->LastAccessTime.Hour   = (UINT8) SystemTime.wHour;

+    Info->LastAccessTime.Minute = (UINT8) SystemTime.wMinute;

+    Info->LastAccessTime.Second = (UINT8) SystemTime.wSecond;

+

+    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastWriteTime, &SystemTime);

+    Info->ModificationTime.Year   = SystemTime.wYear;

+    Info->ModificationTime.Month  = (UINT8) SystemTime.wMonth;

+    Info->ModificationTime.Day    = (UINT8) SystemTime.wDay;

+    Info->ModificationTime.Hour   = (UINT8) SystemTime.wHour;

+    Info->ModificationTime.Minute = (UINT8) SystemTime.wMinute;

+    Info->ModificationTime.Second = (UINT8) SystemTime.wSecond;

+

+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {

+      Info->Attribute |= EFI_FILE_ARCHIVE;

+    }

+

+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {

+      Info->Attribute |= EFI_FILE_HIDDEN;

+    }

+

+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {

+      Info->Attribute |= EFI_FILE_READ_ONLY;

+    }

+

+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {

+      Info->Attribute |= EFI_FILE_SYSTEM;

+    }

+

+    if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

+      Info->Attribute |= EFI_FILE_DIRECTORY;

+    }

+

+    if (PrivateFile->IsDirectoryPath) {

+      Info->Attribute |= EFI_FILE_DIRECTORY;

+    }

+

+    RealFileName  = PrivateFile->FileName;

+    TempPointer   = RealFileName;

+

+    while (*TempPointer) {

+      if (*TempPointer == '\\') {

+        RealFileName = TempPointer + 1;

+      }

+

+      TempPointer++;

+    }

+

+    if (PrivateFile->IsRootDirectory) {

+      *((CHAR8 *) Buffer + Size) = 0;

+    } else {

+      CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize);

+    }

+  }

+

+  *BufferSize = ResultSize;

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemGetInfo (

+  IN     EFI_FILE  *This,

+  IN     EFI_GUID  *InformationType,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Return information about a file or volume.

+

+Arguments:

+

+  This            - Pointer to an opened file handle.

+

+  InformationType - GUID describing the type of information to be returned.

+

+  BufferSize      - On input, the size of the information buffer.  On output, the number of bytes written to the

+                    information buffer.

+

+  Buffer          - Pointer to the first byte of the information buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The requested information has been written into the buffer.

+

+  EFI_UNSUPPORTED       - The InformationType is not known.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.

+

+  EFI_BUFFER_TOO_SMALL  - The buffer size was too small to contain the requested information.  The buffer size has

+                          been updated with the size needed to complete the requested operation.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  EFI_STATUS                        Status;

+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;

+  EFI_FILE_SYSTEM_INFO              *FileSystemInfoBuffer;

+  UINT32                            SectorsPerCluster;

+  UINT32                            BytesPerSector;

+  UINT32                            FreeClusters;

+  UINT32                            TotalClusters;

+  UINT32                            BytesPerCluster;

+  CHAR16                            *DriveName;

+  BOOLEAN                           DriveNameFound;

+  BOOL                              NtStatus;

+  UINTN                             Index;

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;

+

+  if (This == NULL || InformationType == NULL || BufferSize == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+  PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);

+

+  Status      = EFI_UNSUPPORTED;

+

+  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {

+    Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer);

+  }

+

+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {

+    if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {

+      *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    FileSystemInfoBuffer            = (EFI_FILE_SYSTEM_INFO *) Buffer;

+    FileSystemInfoBuffer->Size      = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);

+    FileSystemInfoBuffer->ReadOnly  = FALSE;

+

+    //

+    // Try to get the drive name

+    //

+    DriveName       = NULL;

+    DriveNameFound  = FALSE;

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    StrSize (PrivateFile->FilePath) + 1,

+                    &DriveName

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    StrCpy (DriveName, PrivateFile->FilePath);

+    for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) {

+      ;

+    }

+

+    if (DriveName[Index] == ':') {

+      DriveName[Index + 1]  = '\\';

+      DriveName[Index + 2]  = 0;

+      DriveNameFound        = TRUE;

+    } else if (DriveName[0] == '\\' && DriveName[1] == '\\') {

+      for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {

+        ;

+      }

+

+      if (DriveName[Index] == '\\') {

+        DriveNameFound = TRUE;

+        for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {

+          ;

+        }

+

+        DriveName[Index]      = '\\';

+        DriveName[Index + 1]  = 0;

+      }

+    }

+

+    //

+    // Try GetDiskFreeSpace first

+    //

+    NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace (

+                                          DriveNameFound ? DriveName : NULL,

+                                          &SectorsPerCluster,

+                                          &BytesPerSector,

+                                          &FreeClusters,

+                                          &TotalClusters

+                                          );

+    if (DriveName) {

+      gBS->FreePool (DriveName);

+    }

+

+    if (NtStatus) {

+      //

+      // Succeeded

+      //

+      BytesPerCluster                   = BytesPerSector * SectorsPerCluster;

+      FileSystemInfoBuffer->VolumeSize  = MultU64x32 (TotalClusters, BytesPerCluster);

+      FileSystemInfoBuffer->FreeSpace   = MultU64x32 (FreeClusters, BytesPerCluster);

+      FileSystemInfoBuffer->BlockSize   = BytesPerCluster;

+

+    } else {

+      //

+      // try GetDiskFreeSpaceEx then

+      //

+      FileSystemInfoBuffer->BlockSize = 0;

+      NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpaceEx (

+                                            PrivateFile->FilePath,

+                                            (PULARGE_INTEGER) (&FileSystemInfoBuffer->FreeSpace),

+                                            (PULARGE_INTEGER) (&FileSystemInfoBuffer->VolumeSize),

+                                            NULL

+                                            );

+      if (!NtStatus) {

+        return EFI_DEVICE_ERROR;

+      }

+    }

+

+    StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel);

+    *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);

+    Status      = EFI_SUCCESS;

+  }

+

+  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {

+    if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {

+      *BufferSize = StrSize (PrivateRoot->VolumeLabel);

+      return EFI_BUFFER_TOO_SMALL;

+    }

+

+    StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel);

+    *BufferSize = StrSize (PrivateRoot->VolumeLabel);

+    Status      = EFI_SUCCESS;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemSetInfo (

+  IN EFI_FILE         *This,

+  IN EFI_GUID         *InformationType,

+  IN UINTN            BufferSize,

+  IN VOID             *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Set information about a file or volume.

+

+Arguments:

+

+  This            - Pointer to an opened file handle.

+

+  InformationType - GUID identifying the type of information to set.

+

+  BufferSize      - Number of bytes of data in the information buffer.

+

+  Buffer          - Pointer to the first byte of data in the information buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The file or volume information has been updated.

+

+  EFI_UNSUPPORTED       - The information identifier is not recognised.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.

+

+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.

+

+  EFI_ACCESS_DENIED     - The file was opened read-only.

+

+  EFI_VOLUME_FULL       - The volume is full.

+

+  EFI_BAD_BUFFER_SIZE   - The buffer size is smaller than the type indicated by InformationType.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;

+  WIN_NT_EFI_FILE_PRIVATE           *PrivateFile;

+  EFI_FILE_INFO                     *OldFileInfo;

+  EFI_FILE_INFO                     *NewFileInfo;

+  EFI_STATUS                        Status;

+  UINTN                             OldInfoSize;

+  INTN                              NtStatus;

+  UINT32                            NewAttr;

+  UINT32                            OldAttr;

+  CHAR16                            *OldFileName;

+  CHAR16                            *NewFileName;

+  CHAR16                            *TempFileName;

+  CHAR16                            *CharPointer;

+  BOOLEAN                           AttrChangeFlag;

+  BOOLEAN                           NameChangeFlag;

+  BOOLEAN                           SizeChangeFlag;

+  BOOLEAN                           TimeChangeFlag;

+  UINT64                            CurPos;

+  SYSTEMTIME                        NewCreationSystemTime;

+  SYSTEMTIME                        NewLastAccessSystemTime;

+  SYSTEMTIME                        NewLastWriteSystemTime;

+  FILETIME                          NewCreationFileTime;

+  FILETIME                          NewLastAccessFileTime;

+  FILETIME                          NewLastWriteFileTime;

+  WIN32_FIND_DATA                   FindBuf;

+  EFI_FILE_SYSTEM_INFO              *NewFileSystemInfo;

+

+  //

+  // Check for invalid parameters.

+  //

+  if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Initialise locals.

+  //

+  PrivateFile               = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+  PrivateRoot               = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);

+

+  Status                    = EFI_UNSUPPORTED;

+  OldFileInfo               = NewFileInfo = NULL;

+  OldFileName               = NewFileName = NULL;

+  AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;

+

+  //

+  // Set file system information.

+  //

+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {

+    if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {

+      return EFI_BAD_BUFFER_SIZE;

+    }

+

+    NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;

+

+    gBS->FreePool (PrivateRoot->VolumeLabel);

+

+    PrivateRoot->VolumeLabel = NULL;

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    StrSize (NewFileSystemInfo->VolumeLabel),

+                    &PrivateRoot->VolumeLabel

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel);

+

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Set volume label information.

+  //

+  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {

+    if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {

+      return EFI_BAD_BUFFER_SIZE;

+    }

+

+    StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer);

+

+    return EFI_SUCCESS;

+  }

+

+  if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (BufferSize < SIZE_OF_EFI_FILE_INFO) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  //

+  // Set file/directory information.

+  //

+

+  //

+  // Check for invalid set file information parameters.

+  //

+  NewFileInfo = (EFI_FILE_INFO *) Buffer;

+

+  if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) ||

+      (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||

+      (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)

+      ) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // bugbug: - This is not safe.  We need something like EfiStrMaxSize()

+  // that would have an additional parameter that would be the size

+  // of the string array just in case there are no NULL characters in

+  // the string array.

+  //

+  //

+  // Get current file information so we can determine what kind

+  // of change request this is.

+  //

+  OldInfoSize = 0;

+  Status      = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL);

+

+  if (Status != EFI_BUFFER_TOO_SMALL) {

+    Status = EFI_DEVICE_ERROR;

+    goto Done;

+  }

+

+  Status = gBS->AllocatePool (EfiBootServicesData, OldInfoSize, &OldFileInfo);

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo);

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  StrSize (PrivateFile->FileName),

+                  &OldFileName

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  StrCpy (OldFileName, PrivateFile->FileName);

+

+  //

+  // Make full pathname from new filename and rootpath.

+  //

+  if (NewFileInfo->FileName[0] == '\\') {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    StrSize (PrivateRoot->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName),

+                    &NewFileName

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    StrCpy (NewFileName, PrivateRoot->FilePath);

+    StrCat (NewFileName, L"\\");

+    StrCat (NewFileName, NewFileInfo->FileName + 1);

+  } else {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    StrSize (PrivateFile->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName),

+                    &NewFileName

+                    );

+

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    StrCpy (NewFileName, PrivateFile->FilePath);

+    StrCat (NewFileName, L"\\");

+    StrCat (NewFileName, NewFileInfo->FileName);

+  }

+

+  //

+  // Is there an attribute change request?

+  //

+  if (NewFileInfo->Attribute != OldFileInfo->Attribute) {

+    if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {

+      Status = EFI_INVALID_PARAMETER;

+      goto Done;

+    }

+

+    AttrChangeFlag = TRUE;

+  }

+

+  //

+  // Is there a name change request?

+  // bugbug: - Need EfiStrCaseCmp()

+  //

+  if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {

+    NameChangeFlag = TRUE;

+  }

+

+  //

+  // Is there a size change request?

+  //

+  if (NewFileInfo->FileSize != OldFileInfo->FileSize) {

+    SizeChangeFlag = TRUE;

+  }

+

+  //

+  // Is there a time stamp change request?

+  //

+  if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&

+      CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))

+        ) {

+    TimeChangeFlag = TRUE;

+  } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&

+           CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))

+            ) {

+    TimeChangeFlag = TRUE;

+  } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&

+           CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))

+            ) {

+    TimeChangeFlag = TRUE;

+  }

+

+  //

+  // All done if there are no change requests being made.

+  //

+  if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {

+    Status = EFI_SUCCESS;

+    goto Done;

+  }

+

+  //

+  // Set file or directory information.

+  //

+  OldAttr = PrivateFile->WinNtThunk->GetFileAttributes (OldFileName);

+

+  //

+  // Name change.

+  //

+  if (NameChangeFlag) {

+    //

+    // Close the handles first

+    //

+    if (PrivateFile->IsOpenedByRead) {

+      Status = EFI_ACCESS_DENIED;

+      goto Done;

+    }

+

+    for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {

+    }

+

+    if (*CharPointer != 0) {

+      Status = EFI_ACCESS_DENIED;

+      goto Done;

+    }

+

+    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {

+      if (PrivateFile->IsDirectoryPath) {

+        PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);

+      } else {

+        PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);

+        PrivateFile->LHandle = INVALID_HANDLE_VALUE;

+      }

+    }

+

+    if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {

+      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);

+      PrivateFile->DirHandle = INVALID_HANDLE_VALUE;

+    }

+

+    NtStatus = PrivateFile->WinNtThunk->MoveFile (OldFileName, NewFileName);

+

+    if (NtStatus) {

+      //

+      // modify file name

+      //

+      gBS->FreePool (PrivateFile->FileName);

+

+      Status = gBS->AllocatePool (

+                      EfiBootServicesData,

+                      StrSize (NewFileName),

+                      &PrivateFile->FileName

+                      );

+

+      if (EFI_ERROR (Status)) {

+        goto Done;

+      }

+

+      StrCpy (PrivateFile->FileName, NewFileName);

+

+      Status = gBS->AllocatePool (

+                      EfiBootServicesData,

+                      StrSize (NewFileName) + StrSize (L"\\*"),

+                      &TempFileName

+                      );

+

+      StrCpy (TempFileName, NewFileName);

+

+      if (!PrivateFile->IsDirectoryPath) {

+        PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (

+                                                          TempFileName,

+                                                          PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,

+                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                          NULL,

+                                                          OPEN_EXISTING,

+                                                          0,

+                                                          NULL

+                                                          );

+

+        gBS->FreePool (TempFileName);

+

+        //

+        //  Flush buffers just in case

+        //

+        if (PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) == 0) {

+          Status = EFI_DEVICE_ERROR;

+          goto Done;

+        }

+      } else {

+        PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (

+                                                            TempFileName,

+                                                            PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,

+                                                            FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                            NULL,

+                                                            OPEN_EXISTING,

+                                                            FILE_FLAG_BACKUP_SEMANTICS,

+                                                            NULL

+                                                            );

+

+        StrCat (TempFileName, L"\\*");

+        PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);

+

+        gBS->FreePool (TempFileName);

+      }

+    } else {

+Reopen: ;

+      Status    = EFI_DEVICE_ERROR;

+

+      NtStatus  = PrivateFile->WinNtThunk->SetFileAttributes (OldFileName, OldAttr);

+

+      if (!NtStatus) {

+        goto Done;

+      }

+

+      Status = gBS->AllocatePool (

+                      EfiBootServicesData,

+                      StrSize (OldFileName) + StrSize (L"\\*"),

+                      &TempFileName

+                      );

+

+      StrCpy (TempFileName, OldFileName);

+

+      if (!PrivateFile->IsDirectoryPath) {

+        PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (

+                                                          TempFileName,

+                                                          PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,

+                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                          NULL,

+                                                          OPEN_EXISTING,

+                                                          0,

+                                                          NULL

+                                                          );

+      } else {

+        PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (

+                                                            TempFileName,

+                                                            PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,

+                                                            FILE_SHARE_READ | FILE_SHARE_WRITE,

+                                                            NULL,

+                                                            OPEN_EXISTING,

+                                                            FILE_FLAG_BACKUP_SEMANTICS,

+                                                            NULL

+                                                            );

+

+        StrCat (TempFileName, L"\\*");

+        PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);

+      }

+

+      gBS->FreePool (TempFileName);

+

+      goto Done;

+

+    }

+  }

+

+  //

+  //  Size change

+  //

+  if (SizeChangeFlag) {

+    if (PrivateFile->IsDirectoryPath) {

+      Status = EFI_UNSUPPORTED;

+      goto Done;

+    }

+

+    if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {

+      Status = EFI_ACCESS_DENIED;

+      goto Done;

+    }

+

+    Status = This->GetPosition (This, &CurPos);

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    Status = This->SetPosition (This, NewFileInfo->FileSize);

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+

+    if (PrivateFile->WinNtThunk->SetEndOfFile (PrivateFile->LHandle) == 0) {

+      Status = EFI_DEVICE_ERROR;

+      goto Done;

+    }

+

+    Status = This->SetPosition (This, CurPos);

+    if (EFI_ERROR (Status)) {

+      goto Done;

+    }

+  }

+

+  //

+  // Time change

+  //

+  if (TimeChangeFlag) {

+

+    NewCreationSystemTime.wYear         = NewFileInfo->CreateTime.Year;

+    NewCreationSystemTime.wMonth        = NewFileInfo->CreateTime.Month;

+    NewCreationSystemTime.wDay          = NewFileInfo->CreateTime.Day;

+    NewCreationSystemTime.wHour         = NewFileInfo->CreateTime.Hour;

+    NewCreationSystemTime.wMinute       = NewFileInfo->CreateTime.Minute;

+    NewCreationSystemTime.wSecond       = NewFileInfo->CreateTime.Second;

+    NewCreationSystemTime.wMilliseconds = 0;

+

+    if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (

+                                    &NewCreationSystemTime,

+                                    &NewCreationFileTime

+                                    )) {

+      goto Done;

+    }

+

+    NewLastAccessSystemTime.wYear         = NewFileInfo->LastAccessTime.Year;

+    NewLastAccessSystemTime.wMonth        = NewFileInfo->LastAccessTime.Month;

+    NewLastAccessSystemTime.wDay          = NewFileInfo->LastAccessTime.Day;

+    NewLastAccessSystemTime.wHour         = NewFileInfo->LastAccessTime.Hour;

+    NewLastAccessSystemTime.wMinute       = NewFileInfo->LastAccessTime.Minute;

+    NewLastAccessSystemTime.wSecond       = NewFileInfo->LastAccessTime.Second;

+    NewLastAccessSystemTime.wMilliseconds = 0;

+

+    if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (

+                                    &NewLastAccessSystemTime,

+                                    &NewLastAccessFileTime

+                                    )) {

+      goto Done;

+    }

+

+    NewLastWriteSystemTime.wYear          = NewFileInfo->ModificationTime.Year;

+    NewLastWriteSystemTime.wMonth         = NewFileInfo->ModificationTime.Month;

+    NewLastWriteSystemTime.wDay           = NewFileInfo->ModificationTime.Day;

+    NewLastWriteSystemTime.wHour          = NewFileInfo->ModificationTime.Hour;

+    NewLastWriteSystemTime.wMinute        = NewFileInfo->ModificationTime.Minute;

+    NewLastWriteSystemTime.wSecond        = NewFileInfo->ModificationTime.Second;

+    NewLastWriteSystemTime.wMilliseconds  = 0;

+

+    if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (

+                                    &NewLastWriteSystemTime,

+                                    &NewLastWriteFileTime

+                                    )) {

+      goto Done;

+    }

+

+    if (!PrivateFile->WinNtThunk->SetFileTime (

+                                    PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,

+                                    &NewCreationFileTime,

+                                    &NewLastAccessFileTime,

+                                    &NewLastWriteFileTime

+                                    )) {

+      Status = EFI_DEVICE_ERROR;

+      goto Done;

+    }

+

+  }

+

+  //

+  // No matter about AttrChangeFlag, Attribute must be set.

+  // Because operation before may cause attribute change.

+  //

+  NewAttr = OldAttr;

+

+  if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) {

+    NewAttr |= FILE_ATTRIBUTE_ARCHIVE;

+  } else {

+    NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE;

+  }

+

+  if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) {

+    NewAttr |= FILE_ATTRIBUTE_HIDDEN;

+  } else {

+    NewAttr &= ~FILE_ATTRIBUTE_HIDDEN;

+  }

+

+  if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) {

+    NewAttr |= FILE_ATTRIBUTE_SYSTEM;

+  } else {

+    NewAttr &= ~FILE_ATTRIBUTE_SYSTEM;

+  }

+

+  if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {

+    NewAttr |= FILE_ATTRIBUTE_READONLY;

+  } else {

+    NewAttr &= ~FILE_ATTRIBUTE_READONLY;

+  }

+

+  NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (NewFileName, NewAttr);

+

+  if (!NtStatus) {

+    goto Reopen;

+  }

+

+Done:

+  if (OldFileInfo != NULL) {

+    gBS->FreePool (OldFileInfo);

+  }

+

+  if (OldFileName != NULL) {

+    gBS->FreePool (OldFileName);

+  }

+

+  if (NewFileName != NULL) {

+    gBS->FreePool (NewFileName);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemFlush (

+  IN EFI_FILE  *This

+  )

+/*++

+

+Routine Description:

+

+  Flush all modified data to the media.

+

+Arguments:

+

+  This  - Pointer to an opened file handle.

+

+Returns:

+

+  EFI_SUCCESS           - The data has been flushed.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures have been corrupted.

+

+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.

+

+  EFI_ACCESS_DENIED     - The file was opened read-only.

+

+  EFI_VOLUME_FULL       - The volume is full.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  BY_HANDLE_FILE_INFORMATION  FileInfo;

+  WIN_NT_EFI_FILE_PRIVATE     *PrivateFile;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

+

+  if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (PrivateFile->IsDirectoryPath) {

+    return EFI_SUCCESS;

+  }

+

+  if (PrivateFile->IsOpenedByRead) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  PrivateFile->WinNtThunk->GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo);

+

+  if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  return PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR;

+

+  //

+  // bugbug: - Use Windows error reporting.

+  //

+}

+

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.h
new file mode 100644
index 0000000..eeb373d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.h
@@ -0,0 +1,587 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtSimpleFileSystem.h

+

+Abstract:

+

+  Produce Simple File System abstractions for a directory on your PC using Win32 APIs.

+  The configuration of what devices to mount or emulate comes from NT 

+  environment variables. The variables must be visible to the Microsoft* 

+  Developer Studio for them to work.

+

+  * Other names and brands may be claimed as the property of others.

+

+--*/

+

+#ifndef _WIN_NT_SIMPLE_FILE_SYSTEM_H_

+#define _WIN_NT_SIMPLE_FILE_SYSTEM_H_

+

+

+

+#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 'f', 's')

+

+typedef struct {

+  UINTN                           Signature;

+  EFI_WIN_NT_THUNK_PROTOCOL       *WinNtThunk;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;

+  CHAR16                          *FilePath;

+  CHAR16                          *VolumeLabel;

+  EFI_UNICODE_STRING_TABLE        *ControllerNameTable;

+} WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE;

+

+#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE, \

+      SimpleFileSystem, \

+      WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \

+      )

+

+#define WIN_NT_EFI_FILE_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('l', 'o', 'f', 's')

+

+typedef struct {

+  UINTN                           Signature;

+  EFI_WIN_NT_THUNK_PROTOCOL       *WinNtThunk;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;

+  EFI_FILE                        EfiFile;

+  HANDLE                          LHandle;

+  HANDLE                          DirHandle;

+  BOOLEAN                         IsRootDirectory;

+  BOOLEAN                         IsDirectoryPath;

+  BOOLEAN                         IsOpenedByRead;

+  CHAR16                          *FilePath;

+  WCHAR                           *FileName;

+  BOOLEAN                         IsValidFindBuf;

+  WIN32_FIND_DATA                 FindBuf;

+} WIN_NT_EFI_FILE_PRIVATE;

+

+#define WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      WIN_NT_EFI_FILE_PRIVATE, \

+      EfiFile, \

+      WIN_NT_EFI_FILE_PRIVATE_SIGNATURE \

+      )

+

+//

+// Global Protocol Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtSimpleFileSystemDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtSimpleFileSystemComponentName;

+

+//

+// Driver Binding protocol member functions

+//

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Check to see if the driver supports a given controller.

+

+Arguments:

+

+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.

+

+  ControllerHandle    - EFI handle of the controller to test.

+

+  RemainingDevicePath - Pointer to remaining portion of a device path.

+

+Returns:

+

+  EFI_SUCCESS         - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver

+                        specified by This.

+

+  EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by

+                        the driver specified by This.

+

+  EFI_ACCESS_DENIED   - The device specified by ControllerHandle and RemainingDevicePath is already being managed by

+                        a different driver or an application that requires exclusive access.

+

+  EFI_UNSUPPORTED     - The device specified by ControllerHandle and RemainingDevicePath is not supported by the

+                        driver specified by This.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,

+  IN  EFI_HANDLE                    ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Starts a device controller or a bus controller.

+

+Arguments:

+

+  This                - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.

+

+  ControllerHandle    - EFI handle of the controller to start.

+

+  RemainingDevicePath - Pointer to remaining portion of a device path.

+

+Returns:

+

+  EFI_SUCCESS           - The device or bus controller has been started.

+

+  EFI_DEVICE_ERROR      - The device could not be started due to a device failure.

+

+  EFI_OUT_OF_RESOURCES  - The request could not be completed due to lack of resources.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.

+

+  ControllerHandle  - A handle to the device to be stopped.

+

+  NumberOfChildren  - The number of child device handles in ChildHandleBuffer.

+

+  ChildHandleBuffer - An array of child device handles to be freed.

+

+Returns:

+

+  EFI_SUCCESS       - The device has been stopped.

+

+  EFI_DEVICE_ERROR  - The device could not be stopped due to a device failure.

+

+--*/

+;

+

+//

+// Simple File System protocol member functions

+//

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemOpenVolume (

+  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,

+  OUT EFI_FILE                        **Root

+  )

+/*++

+

+Routine Description:

+

+  Open the root directory on a volume.

+

+Arguments:

+

+  This  - A pointer to the volume to open.

+

+  Root  - A pointer to storage for the returned opened file handle of the root directory.

+

+Returns:

+

+  EFI_SUCCESS           - The volume was opened.

+

+  EFI_UNSUPPORTED       - The volume does not support the requested file system type.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.

+

+  EFI_ACCESS_DENIED     - The service denied access to the file.

+

+  EFI_OUT_OF_RESOURCES  - The file volume could not be opened due to lack of resources.

+

+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemOpen (

+  IN  EFI_FILE  *This,

+  OUT EFI_FILE  **NewHandle,

+  IN  CHAR16    *FileName,

+  IN  UINT64    OpenMode,

+  IN  UINT64    Attributes

+  )

+/*++

+

+Routine Description:

+

+  Open a file relative to the source file location.

+

+Arguments:

+

+  This        - A pointer to the source file location.

+

+  NewHandle   - Pointer to storage for the new file handle.

+

+  FileName    - Pointer to the file name to be opened.

+

+  OpenMode    - File open mode information.

+

+  Attributes  - File creation attributes.

+

+Returns:

+

+  EFI_SUCCESS           - The file was opened.

+

+  EFI_NOT_FOUND         - The file could not be found in the volume.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_MEDIA_CHANGED     - The device has new media or the media is no longer supported.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.

+

+  EFI_WRITE_PROTECTED   - The volume or file is write protected.

+

+  EFI_ACCESS_DENIED     - The service denied access to the file.

+

+  EFI_OUT_OF_RESOURCES  - Not enough resources were available to open the file.

+

+  EFI_VOLUME_FULL       - There is not enough space left to create the new file.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemClose (

+  IN EFI_FILE  *This

+  )

+/*++

+

+Routine Description:

+

+  Close the specified file handle.

+

+Arguments:

+

+  This  - Pointer to a returned opened file handle.

+

+Returns:

+

+  EFI_SUCCESS - The file handle has been closed.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemDelete (

+  IN EFI_FILE  *This

+  )

+/*++

+

+Routine Description:

+

+  Close and delete a file.

+

+Arguments:

+

+  This  - Pointer to a returned opened file handle.

+

+Returns:

+

+  EFI_SUCCESS             - The file handle was closed and deleted.

+

+  EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemRead (

+  IN     EFI_FILE  *This,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Read data from a file.

+

+Arguments:

+

+  This        - Pointer to a returned open file handle.

+

+  BufferSize  - On input, the size of the Buffer.  On output, the number of bytes stored in the Buffer.

+

+  Buffer      - Pointer to the first byte of the read Buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The data was read.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupted.

+

+  EFI_BUFFER_TOO_SMALL  - The supplied buffer size was too small to store the current directory entry.

+                          *BufferSize has been updated with the size needed to complete the request.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemWrite (

+  IN     EFI_FILE  *This,

+  IN OUT UINTN     *BufferSize,

+  IN     VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Write data to a file.

+

+Arguments:

+

+  This        - Pointer to an opened file handle.

+

+  BufferSize  - On input, the number of bytes in the Buffer to write to the file.  On output, the number of bytes

+                of data written to the file.

+

+  Buffer      - Pointer to the first by of data in the buffer to write to the file.

+

+Returns:

+

+  EFI_SUCCESS           - The data was written to the file.

+

+  EFI_UNSUPPORTED       - Writes to an open directory are not supported.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.

+

+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.

+

+  EFI_ACCESS_DENIED     - The file was opened read-only.

+

+  EFI_VOLUME_FULL       - The volume is full.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemSetPosition (

+  IN EFI_FILE  *This,

+  IN UINT64    Position

+  )

+/*++

+

+Routine Description:

+

+  Set a file's current position.

+

+Arguments:

+

+  This      - Pointer to an opened file handle.

+

+  Position  - The byte position from the start of the file to set.

+

+Returns:

+

+  EFI_SUCCESS     - The file position has been changed.

+

+  EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemGetPosition (

+  IN  EFI_FILE  *This,

+  OUT UINT64    *Position

+  )

+/*++

+

+Routine Description:

+

+  Get a file's current position.

+

+Arguments:

+

+  This      - Pointer to an opened file handle.

+

+  Position  - Pointer to storage for the current position.

+

+Returns:

+

+  EFI_SUCCESS     - The file position has been reported.

+

+  EFI_UNSUPPORTED - Not valid for directories.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemGetInfo (

+  IN     EFI_FILE  *This,

+  IN     EFI_GUID  *InformationType,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Return information about a file or volume.

+

+Arguments:

+

+  This            - Pointer to an opened file handle.

+

+  InformationType - GUID describing the type of information to be returned.

+

+  BufferSize      - On input, the size of the information buffer.  On output, the number of bytes written to the

+                    information buffer.

+

+  Buffer          - Pointer to the first byte of the information buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The requested information has been written into the buffer.

+

+  EFI_UNSUPPORTED       - The InformationType is not known.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.

+

+  EFI_BUFFER_TOO_SMALL  - The buffer size was too small to contain the requested information.  The buffer size has

+                          been updated with the size needed to complete the requested operation.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemSetInfo (

+  IN EFI_FILE  *This,

+  IN EFI_GUID  *InformationType,

+  IN UINTN     BufferSize,

+  IN VOID      *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Set information about a file or volume.

+

+Arguments:

+

+  This            - Pointer to an opened file handle.

+

+  InformationType - GUID identifying the type of information to set.

+

+  BufferSize      - Number of bytes of data in the information buffer.

+

+  Buffer          - Pointer to the first byte of data in the information buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The file or volume information has been updated.

+

+  EFI_UNSUPPORTED       - The information identifier is not recognised.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures are corrupt.

+

+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.

+

+  EFI_ACCESS_DENIED     - The file was opened read-only.

+

+  EFI_VOLUME_FULL       - The volume is full.

+

+  EFI_BAD_BUFFER_SIZE   - The buffer size is smaller than the type indicated by InformationType.

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtSimpleFileSystemFlush (

+  IN EFI_FILE  *This

+  )

+/*++

+

+Routine Description:

+

+  Flush all modified data to the media.

+

+Arguments:

+

+  This  - Pointer to an opened file handle.

+

+Returns:

+

+  EFI_SUCCESS           - The data has been flushed.

+

+  EFI_NO_MEDIA          - The device has no media.

+

+  EFI_DEVICE_ERROR      - The device reported an error.

+

+  EFI_VOLUME_CORRUPTED  - The file system structures have been corrupted.

+

+  EFI_WRITE_PROTECTED   - The file, directory, volume, or device is write protected.

+

+  EFI_ACCESS_DENIED     - The file was opened read-only.

+

+  EFI_VOLUME_FULL       - The volume is full.

+

+--*/

+;

+

+#endif /* _WIN_NT_SIMPLE_FILE_SYSTEM_H_ */

+

+/* eof - WinNtSimpleFileSystem.h */

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.mbd
new file mode 100644
index 0000000..3a3e784
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtSimpleFileSystem</BaseName>

+    <Guid>9C25E18B-76BA-43da-A132-DBB0997CEFEF</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>UefiDebugLibStdErr</Library>

+    <Library>BasePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.msa
new file mode 100644
index 0000000..d737d65
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.msa
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtSimpleFileSystem</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>9C25E18B-76BA-43da-A132-DBB0997CEFEF</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtSimpleFileSystem module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtSimpleFileSystem.h</Filename>

+    <Filename>WinNtSimpleFileSystem.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">WinNtIo</Protocol>

+    <Protocol Usage="BY_START">SimpleFileSystem</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtFileSystem</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>FileSystemInfo</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>FileInfo</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>FileSystemVolumeLabelInfoId</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gWinNtSimpleFileSystemDriverBinding</DriverBinding>

+      <ComponentName>gWinNtSimpleFileSystemComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/build.xml
new file mode 100644
index 0000000..fc39519
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtSimpleFileSystem"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Bus\SimpleFileSystem"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtSimpleFileSystem">

+      <GenBuild baseName="WinNtSimpleFileSystem" mbdFilename="${MODULE_DIR}\WinNtSimpleFileSystem.mbd" msaFilename="${MODULE_DIR}\WinNtSimpleFileSystem.msa"/>

+   </target>

+   <target depends="WinNtSimpleFileSystem_clean" name="clean"/>

+   <target depends="WinNtSimpleFileSystem_cleanall" name="cleanall"/>

+   <target name="WinNtSimpleFileSystem_clean">

+      <OutputDirSetup baseName="WinNtSimpleFileSystem" mbdFilename="${MODULE_DIR}\WinNtSimpleFileSystem.mbd" msaFilename="${MODULE_DIR}\WinNtSimpleFileSystem.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtSimpleFileSystem_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtSimpleFileSystem_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtSimpleFileSystem_cleanall">

+      <OutputDirSetup baseName="WinNtSimpleFileSystem" mbdFilename="${MODULE_DIR}\WinNtSimpleFileSystem.mbd" msaFilename="${MODULE_DIR}\WinNtSimpleFileSystem.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtSimpleFileSystem_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtSimpleFileSystem_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtSimpleFileSystem*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/ComponentName.c
new file mode 100644
index 0000000..7b9c297
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/ComponentName.c
@@ -0,0 +1,187 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "WinNtUga.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtUgaComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtUgaComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gWinNtUgaComponentName = {

+  WinNtUgaComponentNameGetDriverName,

+  WinNtUgaComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mWinNtUgaDriverNameTable[] = {

+  { "eng", L"Windows Universal Graphics Adapter Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+WinNtUgaComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gWinNtUgaComponentName.SupportedLanguages,

+          mWinNtUgaDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+WinNtUgaComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  UGA_PRIVATE_DATA      *Private;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &UgaDraw,

+                  gWinNtUgaDriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (UgaDraw);

+

+  return LookupUnicodeString (

+          Language,

+          gWinNtUgaComponentName.SupportedLanguages,

+          Private->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.h
new file mode 100644
index 0000000..defe391
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.h
@@ -0,0 +1,363 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtUga.h

+

+Abstract:

+

+  Private data for the Uga driver that is bound to the WinNt Thunk protocol 

+

+--*/

+

+#ifndef _WIN_NT_UGA_H_

+#define _WIN_NT_UGA_H_

+

+

+

+#define MAX_Q 256

+

+typedef struct {

+  UINTN         Front;

+  UINTN         Rear;

+  UINTN         Count;

+  EFI_INPUT_KEY Q[MAX_Q];

+} UGA_QUEUE_FIXED;

+

+#define WIN_NT_UGA_CLASS_NAME       L"WinNtUgaWindow"

+

+#define UGA_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('S', 'g', 'o', 'N')

+typedef struct {

+  UINT64                      Signature;

+

+  EFI_HANDLE                  Handle;

+  EFI_UGA_DRAW_PROTOCOL       UgaDraw;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL SimpleTextIn;

+

+  EFI_WIN_NT_THUNK_PROTOCOL   *WinNtThunk;

+

+  EFI_UNICODE_STRING_TABLE    *ControllerNameTable;

+

+  //

+  // UGA Private Data for GetMode ()

+  //

+  UINT32                      HorizontalResolution;

+  UINT32                      VerticalResolution;

+  UINT32                      ColorDepth;

+  UINT32                      RefreshRate;

+

+  //

+  // UGA Private Data knowing when to start hardware

+  //

+  BOOLEAN                     HardwareNeedsStarting;

+

+  CHAR16                      *WindowName;

+  CHAR16                      Buffer[160];

+

+  HANDLE                      ThreadInited; // Semaphore

+  HANDLE                      ThreadHandle; // Thread

+  DWORD                       ThreadId;

+

+  HWND                        WindowHandle;

+  WNDCLASSEX                  WindowsClass;

+

+  //

+  // This screen is used to redraw the scree when windows events happen. It's

+  // updated in the main thread and displayed in the windows thread.

+  //

+  BITMAPV4HEADER              *VirtualScreenInfo;

+  RGBQUAD                     *VirtualScreen;

+

+  EFI_UGA_PIXEL               *FillLine;

+

+  //

+  // Keyboard Queue used by Simple Text In. WinProc thread adds, and main

+  // thread removes.

+  //

+  CRITICAL_SECTION            QCriticalSection;

+  UGA_QUEUE_FIXED             Queue;

+

+} UGA_PRIVATE_DATA;

+

+#define UGA_DRAW_PRIVATE_DATA_FROM_THIS(a)  \

+         CR(a, UGA_PRIVATE_DATA, UgaDraw, UGA_PRIVATE_DATA_SIGNATURE)

+

+#define UGA_PRIVATE_DATA_FROM_TEXT_IN_THIS(a)  \

+         CR(a, UGA_PRIVATE_DATA, SimpleTextIn, UGA_PRIVATE_DATA_SIGNATURE)

+

+//

+// Global Protocol Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtUgaDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtUgaComponentName;

+

+//

+// Uga Hardware abstraction internal worker functions

+//

+EFI_STATUS

+WinNtUgaSupported (

+  IN  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  WinNtIo - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WinNtUgaConstructor (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WinNtUgaDestructor (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// EFI 1.1 driver model prototypes for Win NT UGA

+//

+

+EFI_STATUS

+EFIAPI

+WinNtUgaInitialize (

+  IN EFI_HANDLE            ImageHandle,

+  IN EFI_SYSTEM_TABLE      *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtUgaDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtUgaDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtUgaDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+UgaPrivateAddQ (

+  IN  UGA_PRIVATE_DATA    *Private,

+  IN  EFI_INPUT_KEY       Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Key     - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WinNtUgaInitializeSimpleTextInForWindow (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WinNtUgaDestroySimpleTextInForWindow (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+UINTN

+Atoi (

+  IN  CHAR16  *String

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  String  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.mbd
new file mode 100644
index 0000000..18add2f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtUga</BaseName>

+    <Guid>AB248E8D-ABE1-11d4-BD0D-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>UefiDebugLibStdErr</Library>

+    <Library>BasePrintLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.msa
new file mode 100644
index 0000000..f1eae5d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUga.msa
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtUga</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>AB248E8D-ABE1-11d4-BD0D-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for UGA module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtUga.h</Filename>

+    <Filename>WinNtUgaInput.c</Filename>

+    <Filename>WinNtUgaDriver.c</Filename>

+    <Filename>WinNtUgaScreen.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="TO_START">WinNtIo</Protocol>

+    <Protocol Usage="BY_START">UgaDraw</Protocol>

+    <Protocol Usage="BY_START">SimpleTextIn</Protocol>

+  </Protocols>

+  <Events>

+    <CreateEvents>

+      <Event Usage="SOMETIMES_CONSUMED" EventGroup="EVENT_GROUP_EXIT_BOOT_SERVICES">

+        <C_Name>gEfiEventExitBootServicesGuid</C_Name>

+        <Guid>0x27abf055, 0xb1b8, 0x4c26, 0x80, 0x48, 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf</Guid>

+      </Event>

+    </CreateEvents>

+  </Events>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtUga</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gWinNtUgaDriverBinding</DriverBinding>

+      <ComponentName>gWinNtUgaComponentName</ComponentName>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaDriver.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaDriver.c
new file mode 100644
index 0000000..58908d9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaDriver.c
@@ -0,0 +1,343 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtUgaDriver.c

+

+Abstract:

+

+  This file implements the EFI 1.1 Device Driver model requirements for UGA

+

+  UGA is short hand for Universal Graphics Abstraction protocol.

+

+  This file is a verision of UgaIo the uses WinNtThunk system calls as an IO 

+  abstraction. For a PCI device WinNtIo would be replaced with

+  a PCI IO abstraction that abstracted a specific PCI device. 

+

+--*/

+

+#include "WinNtUga.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gWinNtUgaDriverBinding = {

+  WinNtUgaDriverBindingSupported,

+  WinNtUgaDriverBindingStart,

+  WinNtUgaDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+

+EFI_STATUS

+EFIAPI

+WinNtUgaDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+{

+  EFI_STATUS              Status;

+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;

+

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = WinNtUgaSupported (WinNtIo);

+

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        Handle,

+        &gEfiWinNtIoProtocolGuid,

+        This->DriverBindingHandle,

+        Handle

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtUgaDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Handle,

+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;

+  EFI_STATUS              Status;

+  UGA_PRIVATE_DATA        *Private;

+

+  //

+  // Grab the protocols we need

+  //

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Allocate Private context data for SGO inteface.

+  //

+  Private = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (UGA_PRIVATE_DATA),

+                  &Private

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+  //

+  // Set up context record

+  //

+  Private->Signature            = UGA_PRIVATE_DATA_SIGNATURE;

+  Private->Handle               = Handle;

+  Private->WinNtThunk           = WinNtIo->WinNtThunk;

+

+  Private->ControllerNameTable  = NULL;

+

+  AddUnicodeString (

+    "eng",

+    gWinNtUgaComponentName.SupportedLanguages,

+    &Private->ControllerNameTable,

+    WinNtIo->EnvString

+    );

+

+  Private->WindowName = WinNtIo->EnvString;

+

+  Status              = WinNtUgaConstructor (Private);

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+  //

+  // Publish the Uga interface to the world

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Private->Handle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &Private->UgaDraw,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &Private->SimpleTextIn,

+                  NULL

+                  );

+

+Done:

+  if (EFI_ERROR (Status)) {

+

+    gBS->CloseProtocol (

+          Handle,

+          &gEfiWinNtIoProtocolGuid,

+          This->DriverBindingHandle,

+          Handle

+          );

+

+    if (Private != NULL) {

+      //

+      // On Error Free back private data

+      //

+      if (Private->ControllerNameTable != NULL) {

+        FreeUnicodeStringTable (Private->ControllerNameTable);

+      }

+

+      gBS->FreePool (Private);

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtUgaDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    Handle - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_NOT_STARTED - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  EFI_STATUS            Status;

+  UGA_PRIVATE_DATA      *Private;

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &UgaDraw,

+                  This->DriverBindingHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    //

+    // If the UGA interface does not exist the driver is not started

+    //

+    return EFI_NOT_STARTED;

+  }

+

+  //

+  // Get our private context information

+  //

+  Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (UgaDraw);

+

+  //

+  // Remove the SGO interface from the system

+  //

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Private->Handle,

+                  &gEfiUgaDrawProtocolGuid,

+                  &Private->UgaDraw,

+                  &gEfiSimpleTextInProtocolGuid,

+                  &Private->SimpleTextIn,

+                  NULL

+                  );

+  if (!EFI_ERROR (Status)) {

+    //

+    // Shutdown the hardware

+    //

+    Status = WinNtUgaDestructor (Private);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    gBS->CloseProtocol (

+          Handle,

+          &gEfiWinNtIoProtocolGuid,

+          This->DriverBindingHandle,

+          Handle

+          );

+

+    //

+    // Free our instance data

+    //

+    FreeUnicodeStringTable (Private->ControllerNameTable);

+

+    gBS->FreePool (Private);

+

+  }

+

+  return Status;

+}

+

+UINTN

+Atoi (

+  CHAR16  *String

+  )

+/*++

+

+Routine Description:

+

+  Convert a unicode string to a UINTN

+

+Arguments:

+

+  String - Unicode string.

+

+Returns: 

+

+  UINTN of the number represented by String.  

+

+--*/

+{

+  UINTN   Number;

+  CHAR16  *Str;

+

+  //

+  // skip preceeding white space

+  //

+  Str = String;

+  while ((*Str) && (*Str == ' ' || *Str == '"')) {

+    Str++;

+  }

+

+  //

+  // Convert ot a Number

+  //

+  Number = 0;

+  while (*Str != '\0') {

+    if ((*Str >= '0') && (*Str <= '9')) {

+      Number = (Number * 10) +*Str - '0';

+    } else {

+      break;

+    }

+

+    Str++;

+  }

+

+  return Number;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaInput.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaInput.c
new file mode 100644
index 0000000..19bca36
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaInput.c
@@ -0,0 +1,411 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtUgaInput.c

+

+Abstract:

+

+  This file produces the Simple Text In for an Uga window. 

+

+  This stuff is linked at the hip to the Window, since the window

+  processing is done in a thread kicked off in WinNtUgaImplementation.c

+

+  Since the window information is processed in an other thread we need

+  a keyboard Queue to pass data about. The Simple Text In code just 

+  takes data off the Queue. The WinProc message loop takes keyboard input

+  and places it in the Queue.

+

+--*/

+

+#include "WinNtUga.h"

+

+EFI_STATUS

+UgaPrivateCreateQ (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  Private->WinNtThunk->InitializeCriticalSection (&Private->QCriticalSection);

+

+  Private->Queue.Front  = 0;

+  Private->Queue.Rear   = MAX_Q - 1;

+  Private->Queue.Count  = 0;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UgaPrivateDestroyQ (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  Private->Queue.Count = 0;

+  Private->WinNtThunk->DeleteCriticalSection (&Private->QCriticalSection);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UgaPrivateAddQ (

+  IN  UGA_PRIVATE_DATA    *Private,

+  IN  EFI_INPUT_KEY       Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Key     - TODO: add argument description

+

+Returns:

+

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);

+

+  if (Private->Queue.Count == MAX_Q) {

+    Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);

+    return EFI_NOT_READY;

+  }

+

+  Private->Queue.Rear                   = (Private->Queue.Rear + 1) % MAX_Q;

+  Private->Queue.Q[Private->Queue.Rear] = Key;

+  Private->Queue.Count++;

+

+  Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UgaPrivateDeleteQ (

+  IN  UGA_PRIVATE_DATA    *Private,

+  OUT EFI_INPUT_KEY       *Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+  Key     - TODO: add argument description

+

+Returns:

+

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  Private->WinNtThunk->EnterCriticalSection (&Private->QCriticalSection);

+

+  if (Private->Queue.Count == 0) {

+    Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);

+    return EFI_NOT_READY;

+  }

+

+  *Key                  = Private->Queue.Q[Private->Queue.Front];

+  Private->Queue.Front  = (Private->Queue.Front + 1) % MAX_Q;

+  Private->Queue.Count--;

+

+  Private->WinNtThunk->LeaveCriticalSection (&Private->QCriticalSection);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UgaPrivateCheckQ (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  EFI_NOT_READY - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  if (Private->Queue.Count == 0) {

+    return EFI_NOT_READY;

+  }

+

+  return EFI_SUCCESS;

+}

+

+//

+// Simple Text In implementation.

+//

+

+EFI_STATUS

+EFIAPI

+WinNtUgaSimpleTextInReset (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  IN BOOLEAN                              ExtendedVerification

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                  - TODO: add argument description

+  ExtendedVerification  - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  UGA_PRIVATE_DATA  *Private;

+  EFI_INPUT_KEY     Key;

+  EFI_TPL           OldTpl;

+

+  Private = UGA_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);

+

+  //

+  // Enter critical section

+  //

+  OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  //

+  // A reset is draining the Queue

+  //

+  while (UgaPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)

+    ;

+

+  //

+  // Leave critical section and return

+  //

+  gBS->RestoreTPL (OldTpl);

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtUgaSimpleTextInReadKeyStroke (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  OUT EFI_INPUT_KEY                       *Key

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+  Key   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UGA_PRIVATE_DATA  *Private;

+  EFI_STATUS        Status;

+  EFI_TPL           OldTpl;

+

+  Private = UGA_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);

+

+  //

+  // Enter critical section

+  //

+  OldTpl  = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Status  = UgaPrivateCheckQ (Private);

+  if (!EFI_ERROR (Status)) {

+    //

+    // If a Key press exists try and read it.

+    //

+    Status = UgaPrivateDeleteQ (Private, Key);

+  }

+

+  //

+  // Leave critical section and return

+  //

+  gBS->RestoreTPL (OldTpl);

+

+  return Status;

+}

+

+STATIC

+VOID

+EFIAPI

+WinNtUgaSimpleTextInWaitForKey (

+  IN EFI_EVENT          Event,

+  IN VOID               *Context

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Event   - TODO: add argument description

+  Context - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  UGA_PRIVATE_DATA  *Private;

+  EFI_STATUS        Status;

+  EFI_TPL           OldTpl;

+

+  Private = (UGA_PRIVATE_DATA *) Context;

+

+  //

+  // Enter critical section

+  //

+  OldTpl  = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+  Status  = UgaPrivateCheckQ (Private);

+  if (!EFI_ERROR (Status)) {

+    //

+    // If a there is a key in the queue signal our event.

+    //

+    gBS->SignalEvent (Event);

+  } else {

+    //

+    // We need to sleep or NT will schedule this thread with such high

+    // priority that WinProc thread will never run and we will not see

+    // keyboard input. This Sleep makes the syste run 10x faster, so don't

+    // remove it.

+    //

+    Private->WinNtThunk->Sleep (1);

+  }

+

+  //

+  // Leave critical section and return

+  //

+  gBS->RestoreTPL (OldTpl);

+}

+

+EFI_STATUS

+WinNtUgaInitializeSimpleTextInForWindow (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  UgaPrivateCreateQ (Private);

+

+  //

+  // Initialize Simple Text In protoocol

+  //

+  Private->SimpleTextIn.Reset         = WinNtUgaSimpleTextInReset;

+  Private->SimpleTextIn.ReadKeyStroke = WinNtUgaSimpleTextInReadKeyStroke;

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_WAIT,

+                  EFI_TPL_NOTIFY,

+                  WinNtUgaSimpleTextInWaitForKey,

+                  Private,

+                  &Private->SimpleTextIn.WaitForKey

+                  );

+

+  return Status;

+}

+

+EFI_STATUS

+WinNtUgaDestroySimpleTextInForWindow (

+  IN  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  UgaPrivateDestroyQ (Private);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaScreen.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaScreen.c
new file mode 100644
index 0000000..ed35a01
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/WinNtUgaScreen.c
@@ -0,0 +1,992 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    WinNtUgaScreen.c

+

+Abstract:

+

+  This file produces the graphics abstration of UGA. It is called by 

+  WinNtUgaDriver.c file which deals with the EFI 1.1 driver model. 

+  This file just does graphics.

+

+--*/

+

+#include "WinNtUga.h"

+

+EFI_WIN_NT_THUNK_PROTOCOL *mWinNt;

+DWORD                     mTlsIndex         = TLS_OUT_OF_INDEXES;

+DWORD                     mTlsIndexUseCount = 0;  // lets us know when we can free mTlsIndex.

+static EFI_EVENT          mUgaScreenExitBootServicesEvent;

+

+EFI_STATUS

+WinNtUgaStartWindow (

+  IN  UGA_PRIVATE_DATA    *Private,

+  IN  UINT32              HorizontalResolution,

+  IN  UINT32              VerticalResolution,

+  IN  UINT32              ColorDepth,

+  IN  UINT32              RefreshRate

+  );

+

+STATIC

+VOID

+EFIAPI

+KillNtUgaThread (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  );

+

+//

+// UGA Protocol Member Functions

+//

+

+EFI_STATUS

+EFIAPI

+WinNtUgaGetMode (

+  EFI_UGA_DRAW_PROTOCOL *This,

+  UINT32                *HorizontalResolution,

+  UINT32                *VerticalResolution,

+  UINT32                *ColorDepth,

+  UINT32                *RefreshRate

+  )

+/*++

+

+  Routine Description:

+    Return the current video mode information.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    HorizontalResolution  - Current video horizontal resolution in pixels

+    VerticalResolution    - Current video Vertical resolution in pixels

+    ColorDepth            - Current video color depth in bits per pixel

+    RefreshRate           - Current video refresh rate in Hz.

+

+  Returns:

+    EFI_SUCCESS     - Mode information returned.

+    EFI_NOT_STARTED - Video display is not initialized. Call SetMode () 

+    EFI_INVALID_PARAMETER - One of the input args was NULL.

+

+--*/

+// TODO:    ADD IN/OUT description here

+{

+  UGA_PRIVATE_DATA  *Private;

+

+  Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private->HardwareNeedsStarting) {

+    return EFI_NOT_STARTED;

+  }

+

+  if ((HorizontalResolution == NULL) ||

+      (VerticalResolution   == NULL) ||

+      (ColorDepth           == NULL) ||

+      (RefreshRate          == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *HorizontalResolution = Private->HorizontalResolution;

+  *VerticalResolution   = Private->VerticalResolution;

+  *ColorDepth           = Private->ColorDepth;

+  *RefreshRate          = Private->RefreshRate;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtUgaSetMode (

+  EFI_UGA_DRAW_PROTOCOL *This,

+  UINT32                HorizontalResolution,

+  UINT32                VerticalResolution,

+  UINT32                ColorDepth,

+  UINT32                RefreshRate

+  )

+/*++

+

+  Routine Description:

+    Return the current video mode information.

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    HorizontalResolution  - Current video horizontal resolution in pixels

+    VerticalResolution    - Current video Vertical resolution in pixels

+    ColorDepth            - Current video color depth in bits per pixel

+    RefreshRate           - Current video refresh rate in Hz.

+

+  Returns:

+    EFI_SUCCESS     - Mode information returned.

+    EFI_NOT_STARTED - Video display is not initialized. Call SetMode () 

+    EFI_INVALID_PARAMETER - One of the input args was NULL.

+

+--*/

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    ADD IN/OUT description here

+{

+  EFI_STATUS        Status;

+  UGA_PRIVATE_DATA  *Private;

+  EFI_UGA_PIXEL     Fill;

+  EFI_UGA_PIXEL     *NewFillLine;

+  RECT              Rect;

+  UINTN             Size;

+  UINTN             Width;

+  UINTN             Height;

+

+  Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);

+

+  if (Private->HardwareNeedsStarting) {

+    Status = WinNtUgaStartWindow (

+              Private,

+              HorizontalResolution,

+              VerticalResolution,

+              ColorDepth,

+              RefreshRate

+              );

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    Private->HardwareNeedsStarting = FALSE;

+  } else {

+    //

+    // Change the resolution and resize of the window

+    //

+

+    //

+    // Free the old buffer. We do not save the content of the old buffer since the

+    // screen is to be cleared anyway. Clearing the screen is required by the EFI spec.

+    // See EFI spec chepter 10.5-EFI_UGA_DRAW_PROTOCOL.SetMode()

+    //

+    Private->WinNtThunk->HeapFree (Private->WinNtThunk->GetProcessHeap (), 0, Private->VirtualScreenInfo);

+

+    //

+    // Allocate DIB frame buffer directly from NT for performance enhancement

+    // This buffer is the virtual screen/frame buffer. This buffer is not the

+    // same a a frame buffer. The first row of this buffer will be the bottom

+    // line of the image. This is an artifact of the way we draw to the screen.

+    //

+    Size = HorizontalResolution * VerticalResolution * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER);

+    Private->VirtualScreenInfo = Private->WinNtThunk->HeapAlloc (

+                                                        Private->WinNtThunk->GetProcessHeap (),

+                                                        HEAP_ZERO_MEMORY,

+                                                        Size

+                                                        );

+

+    //

+    // Update the virtual screen info data structure

+    //

+    Private->VirtualScreenInfo->bV4Size           = sizeof (BITMAPV4HEADER);

+    Private->VirtualScreenInfo->bV4Width          = HorizontalResolution;

+    Private->VirtualScreenInfo->bV4Height         = VerticalResolution;

+    Private->VirtualScreenInfo->bV4Planes         = 1;

+    Private->VirtualScreenInfo->bV4BitCount       = 32;

+    //

+    // uncompressed

+    //

+    Private->VirtualScreenInfo->bV4V4Compression  = BI_RGB;

+

+    //

+    // The rest of the allocated memory block is the virtual screen buffer

+    //

+    Private->VirtualScreen = (RGBQUAD *) (Private->VirtualScreenInfo + 1);

+

+    //

+    // Use the AdjuctWindowRect fuction to calculate the real width and height

+    // of the new window including the border and caption

+    //

+    Rect.left   = 0;

+    Rect.top    = 0;

+    Rect.right  = HorizontalResolution;

+    Rect.bottom = VerticalResolution;

+

+    Private->WinNtThunk->AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);

+

+    Width   = Rect.right - Rect.left;

+    Height  = Rect.bottom - Rect.top;

+

+    //

+    // Retrieve the original window position information

+    //

+    Private->WinNtThunk->GetWindowRect (Private->WindowHandle, &Rect);

+

+    //

+    // Adjust the window size

+    //

+    Private->WinNtThunk->MoveWindow (Private->WindowHandle, Rect.left, Rect.top, Width, Height, TRUE);

+

+  }

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_UGA_PIXEL) * HorizontalResolution,

+                  &NewFillLine

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (Private->FillLine != NULL) {

+    gBS->FreePool (Private->FillLine);

+  }

+

+  Private->FillLine             = NewFillLine;

+

+  Private->HorizontalResolution = HorizontalResolution;

+  Private->VerticalResolution   = VerticalResolution;

+  Private->ColorDepth           = ColorDepth;

+  Private->RefreshRate          = RefreshRate;

+

+  Fill.Red                      = 0x00;

+  Fill.Green                    = 0x00;

+  Fill.Blue                     = 0x00;

+  This->Blt (

+          This,

+          &Fill,

+          EfiUgaVideoFill,

+          0,

+          0,

+          0,

+          0,

+          HorizontalResolution,

+          VerticalResolution,

+          HorizontalResolution * sizeof (EFI_UGA_PIXEL)

+          );

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtUgaBlt (

+  IN  EFI_UGA_DRAW_PROTOCOL                   *This,

+  IN  EFI_UGA_PIXEL                           *BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION                   BltOperation,

+  IN  UINTN                                   SourceX,

+  IN  UINTN                                   SourceY,

+  IN  UINTN                                   DestinationX,

+  IN  UINTN                                   DestinationY,

+  IN  UINTN                                   Width,

+  IN  UINTN                                   Height,

+  IN  UINTN                                   Delta         OPTIONAL

+  )

+/*++

+

+  Routine Description:

+    Blt pixels from the rectangle (Width X Height) formed by the BltBuffer

+    onto the graphics screen starting a location (X, Y). (0, 0) is defined as

+    the upper left hand side of the screen. (X, Y) can be outside of the 

+    current screen geometry and the BltBuffer will be cliped when it is 

+    displayed. X and Y can be negative or positive. If Width or Height is 

+    bigger than the current video screen the image will be clipped.

+

+  Arguments:

+    This          - Protocol instance pointer.

+    X             - X location on graphics screen. 

+    Y             - Y location on the graphics screen.

+    Width         - Width of BltBuffer.

+    Height        - Hight of BltBuffer

+    BltOperation  - Operation to perform on BltBuffer and video memory

+    BltBuffer     - Buffer containing data to blt into video buffer. This 

+                    buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)

+    SourceX       - If the BltOperation is a EfiCopyBlt this is the source

+                    of the copy. For other BLT operations this argument is not

+                    used.

+    SourceX       - If the BltOperation is a EfiCopyBlt this is the source

+                    of the copy. For other BLT operations this argument is not

+                    used.

+      

+  Returns:

+    EFI_SUCCESS           - The palette is updated with PaletteArray.

+    EFI_INVALID_PARAMETER - BltOperation is not valid.

+    EFI_DEVICE_ERROR      - A hardware error occured writting to the video 

+                             buffer.

+

+--*/

+// TODO:    SourceY - add argument and description to function comment

+// TODO:    DestinationX - add argument and description to function comment

+// TODO:    DestinationY - add argument and description to function comment

+// TODO:    Delta - add argument and description to function comment

+{

+  UGA_PRIVATE_DATA  *Private;

+  EFI_TPL           OriginalTPL;

+  UINTN             DstY;

+  UINTN             SrcY;

+  RGBQUAD           *VScreen;

+  RGBQUAD           *VScreenSrc;

+  EFI_UGA_PIXEL     *Blt;

+  UINTN             Index;

+  RECT              Rect;

+  EFI_UGA_PIXEL     *FillPixel;

+

+  Private = UGA_DRAW_PRIVATE_DATA_FROM_THIS (This);

+

+  if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Width == 0 || Height == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // If Delta is zero, then the entire BltBuffer is being used, so Delta

+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,

+  // the number of bytes in each row can be computed.

+  //

+  if (Delta == 0) {

+    Delta = Width * sizeof (EFI_UGA_PIXEL);

+  }

+

+  //

+  // We need to fill the Virtual Screen buffer with the blt data.

+  // The virtual screen is upside down, as the first row is the bootom row of

+  // the image.

+  //

+

+  if (BltOperation == EfiUgaVideoToBltBuffer) {

+

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    if (SourceY + Height > Private->VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (SourceX + Width > Private->HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // We have to raise to TPL Notify, so we make an atomic write the frame buffer.

+    // We would not want a timer based event (Cursor, ...) to come in while we are

+    // doing this operation.

+    //

+    OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {

+      Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + DestinationX * sizeof (EFI_UGA_PIXEL));

+      VScreen = &Private->VirtualScreen[(Private->VerticalResolution - SrcY - 1) * Private->HorizontalResolution + SourceX];

+      CopyMem (Blt, VScreen, sizeof (EFI_UGA_PIXEL) * Width);

+    }

+  } else {

+    //

+    // BltBuffer to Video: Source is BltBuffer, destination is Video

+    //

+    if (DestinationY + Height > Private->VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (DestinationX + Width > Private->HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    //

+    // We have to raise to TPL Notify, so we make an atomic write the frame buffer.

+    // We would not want a timer based event (Cursor, ...) to come in while we are

+    // doing this operation.

+    //

+    OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);

+

+    if (BltOperation == EfiUgaVideoFill) {

+      FillPixel = BltBuffer;

+      for (Index = 0; Index < Width; Index++) {

+        Private->FillLine[Index] = *FillPixel;

+      }

+    }

+

+    for (Index = 0; Index < Height; Index++) {

+      if (DestinationY <= SourceY) {

+        SrcY  = SourceY + Index;

+        DstY  = DestinationY + Index;

+      } else {

+        SrcY  = SourceY + Height - Index - 1;

+        DstY  = DestinationY + Height - Index - 1;

+      }

+

+      VScreen = &Private->VirtualScreen[(Private->VerticalResolution - DstY - 1) * Private->HorizontalResolution + DestinationX];

+      switch (BltOperation) {

+      case EfiUgaBltBufferToVideo:

+        Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + SourceX * sizeof (EFI_UGA_PIXEL));

+        CopyMem (VScreen, Blt, Width * sizeof (EFI_UGA_PIXEL));

+        break;

+

+      case EfiUgaVideoToVideo:

+        VScreenSrc = &Private->VirtualScreen[(Private->VerticalResolution - SrcY - 1) * Private->HorizontalResolution + SourceX];

+        CopyMem (VScreen, VScreenSrc, Width * sizeof (EFI_UGA_PIXEL));

+        break;

+

+      case EfiUgaVideoFill:

+        CopyMem (VScreen, Private->FillLine, Width * sizeof (EFI_UGA_PIXEL));

+        break;

+      }

+    }

+  }

+

+  if (BltOperation != EfiUgaVideoToBltBuffer) {

+    //

+    // Mark the area we just blted as Invalid so WM_PAINT will update.

+    //

+    Rect.left   = DestinationX;

+    Rect.top    = DestinationY;

+    Rect.right  = DestinationX + Width;

+    Rect.bottom = DestinationY + Height;

+    Private->WinNtThunk->InvalidateRect (Private->WindowHandle, &Rect, FALSE);

+

+    //

+    // Send the WM_PAINT message to the thread that is drawing the window. We

+    // are in the main thread and the window drawing is in a child thread.

+    // There is a child thread per window. We have no CriticalSection or Mutex

+    // since we write the data and the other thread displays the data. While

+    // we may miss some data for a short period of time this is no different than

+    // a write combining on writes to a frame buffer.

+    //

+  

+    Private->WinNtThunk->UpdateWindow (Private->WindowHandle);

+  }

+

+  gBS->RestoreTPL (OriginalTPL);

+

+  return EFI_SUCCESS;

+}

+

+

+//

+// Construction and Destruction functions

+//

+

+EFI_STATUS

+WinNtUgaSupported (

+  IN  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    WinNtIo - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  //

+  // Check to see if the IO abstraction represents a device type we support.

+  //

+  // This would be replaced a check of PCI subsystem ID, etc.

+  //

+  if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtUgaGuid)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+LRESULT

+CALLBACK

+WinNtUgaThreadWindowProc (

+  IN  HWND    hwnd,

+  IN  UINT    iMsg,

+  IN  WPARAM  wParam,

+  IN  LPARAM  lParam

+  )

+/*++

+

+Routine Description:

+  Win32 Windows event handler. 

+

+Arguments:

+  See Win32 Book

+

+Returns:

+  See Win32 Book

+

+--*/

+// TODO:    hwnd - add argument and description to function comment

+// TODO:    iMsg - add argument and description to function comment

+// TODO:    wParam - add argument and description to function comment

+// TODO:    lParam - add argument and description to function comment

+{

+  UGA_PRIVATE_DATA  *Private;

+  UINTN             Size;

+  HDC               Handle;

+  PAINTSTRUCT       PaintStruct;

+  LPARAM            Index;

+  EFI_INPUT_KEY     Key;

+

+  //

+  // BugBug - if there are two instances of this DLL in memory (such as is

+  // the case for ERM), the correct instance of this function may not be called.

+  // This also means that the address of the mTlsIndex value will be wrong, and

+  // the value may be wrong too.

+  //

+

+

+  //

+  // Use mTlsIndex global to get a Thread Local Storage version of Private.

+  // This works since each Uga protocol has a unique Private data instance and

+  // a unique thread.

+  //

+  Private = mWinNt->TlsGetValue (mTlsIndex);

+  ASSERT (NULL != Private);

+

+  switch (iMsg) {

+  case WM_CREATE:

+    Size = Private->HorizontalResolution * Private->VerticalResolution * sizeof (RGBQUAD);

+

+    //

+    // Allocate DIB frame buffer directly from NT for performance enhancement

+    // This buffer is the virtual screen/frame buffer. This buffer is not the

+    // same a a frame buffer. The first fow of this buffer will be the bottom

+    // line of the image. This is an artifact of the way we draw to the screen.

+    //

+    Private->VirtualScreenInfo = Private->WinNtThunk->HeapAlloc (

+                                                        Private->WinNtThunk->GetProcessHeap (),

+                                                        HEAP_ZERO_MEMORY,

+                                                        Size

+                                                        );

+

+    Private->VirtualScreenInfo->bV4Size           = sizeof (BITMAPV4HEADER);

+    Private->VirtualScreenInfo->bV4Width          = Private->HorizontalResolution;

+    Private->VirtualScreenInfo->bV4Height         = Private->VerticalResolution;

+    Private->VirtualScreenInfo->bV4Planes         = 1;

+    Private->VirtualScreenInfo->bV4BitCount       = 32;

+    //

+    // uncompressed

+    //

+    Private->VirtualScreenInfo->bV4V4Compression  = BI_RGB;

+    Private->VirtualScreen = (RGBQUAD *) (Private->VirtualScreenInfo + 1);

+    return 0;

+

+  case WM_PAINT:

+    //

+    // I have not found a way to convert hwnd into a Private context. So for

+    // now we use this API to convert hwnd to Private data.

+    //

+

+    Handle = mWinNt->BeginPaint (hwnd, &PaintStruct);

+

+    mWinNt->SetDIBitsToDevice (

+              Handle,                                     // Destination Device Context

+              0,                                          // Destination X - 0

+              0,                                          // Destination Y - 0

+              Private->HorizontalResolution,              // Width

+              Private->VerticalResolution,                // Height

+              0,                                          // Source X

+              0,                                          // Source Y

+              0,                                          // DIB Start Scan Line

+              Private->VerticalResolution,                // Number of scan lines

+              Private->VirtualScreen,                     // Address of array of DIB bits

+              (BITMAPINFO *) Private->VirtualScreenInfo,  // Address of structure with bitmap info

+              DIB_RGB_COLORS                              // RGB or palette indexes

+              );

+

+    mWinNt->EndPaint (hwnd, &PaintStruct);

+    return 0;

+

+  //

+  // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case

+  //

+  case WM_SYSKEYDOWN:

+    Key.ScanCode = 0;

+    switch (wParam) {

+    case VK_F10:

+      Key.ScanCode    = SCAN_F10;

+      Key.UnicodeChar = 0;

+      UgaPrivateAddQ (Private, Key);

+      return 0;

+    }

+    break;

+

+  case WM_KEYDOWN:

+    Key.ScanCode = 0;

+    switch (wParam) {

+    case VK_HOME:       Key.ScanCode = SCAN_HOME;       break;

+    case VK_END:        Key.ScanCode = SCAN_END;        break;

+    case VK_LEFT:       Key.ScanCode = SCAN_LEFT;       break;

+    case VK_RIGHT:      Key.ScanCode = SCAN_RIGHT;      break;

+    case VK_UP:         Key.ScanCode = SCAN_UP;         break;

+    case VK_DOWN:       Key.ScanCode = SCAN_DOWN;       break;

+    case VK_DELETE:     Key.ScanCode = SCAN_DELETE;     break;

+    case VK_INSERT:     Key.ScanCode = SCAN_INSERT;     break;

+    case VK_PRIOR:      Key.ScanCode = SCAN_PAGE_UP;    break;

+    case VK_NEXT:       Key.ScanCode = SCAN_PAGE_DOWN;  break;

+    case VK_ESCAPE:     Key.ScanCode = SCAN_ESC;        break;

+

+    case VK_F1:   Key.ScanCode = SCAN_F1;   break;

+    case VK_F2:   Key.ScanCode = SCAN_F2;   break;

+    case VK_F3:   Key.ScanCode = SCAN_F3;   break;

+    case VK_F4:   Key.ScanCode = SCAN_F4;   break;

+    case VK_F5:   Key.ScanCode = SCAN_F5;   break;

+    case VK_F6:   Key.ScanCode = SCAN_F6;   break;

+    case VK_F7:   Key.ScanCode = SCAN_F7;   break;

+    case VK_F8:   Key.ScanCode = SCAN_F8;   break;

+    case VK_F9:   Key.ScanCode = SCAN_F9;   break;

+    }

+

+    if (Key.ScanCode != 0) {

+      Key.UnicodeChar = 0;

+      UgaPrivateAddQ (Private, Key);

+    }

+

+    return 0;

+

+  case WM_CHAR:

+    //

+    // The ESC key also generate WM_CHAR.

+    //

+    if (wParam == 0x1B) {

+      return 0;

+    }

+

+    for (Index = 0; Index < (lParam & 0xffff); Index++) {

+      if (wParam != 0) {

+        Key.UnicodeChar = (CHAR16) wParam;

+        Key.ScanCode    = 0;

+        UgaPrivateAddQ (Private, Key);

+      }

+    }

+

+    return 0;

+

+  case WM_CLOSE:

+    //

+    // This close message is issued by user, core is not aware of this,

+    // so don't release the window display resource, just hide the window.

+    //

+    Private->WinNtThunk->ShowWindow (Private->WindowHandle, SW_HIDE);

+    return 0;

+

+  case WM_DESTROY:

+    mWinNt->DestroyWindow (hwnd);

+    mWinNt->PostQuitMessage (0);

+

+    mWinNt->HeapFree (Private->WinNtThunk->GetProcessHeap (), 0, Private->VirtualScreenInfo);

+

+    mWinNt->ExitThread (0);

+    return 0;

+

+  default:

+    break;

+  };

+

+  return mWinNt->DefWindowProc (hwnd, iMsg, wParam, lParam);

+}

+

+DWORD

+WINAPI

+WinNtUgaThreadWinMain (

+  LPVOID    lpParameter

+  )

+/*++

+

+Routine Description:

+

+  This thread simulates the end of WinMain () aplication. Each Winow nededs

+  to process it's events. The messages are dispatched to 

+  WinNtUgaThreadWindowProc ().

+

+  Be very careful sine WinNtUgaThreadWinMain () and WinNtUgaThreadWindowProc ()

+  are running in a seperate thread. We have to do this to process the events.

+

+Arguments:

+

+  lpParameter - Handle of window to manage.

+

+Returns:

+

+  if a WM_QUIT message is returned exit.

+

+--*/

+{

+  MSG               Message;

+  UGA_PRIVATE_DATA  *Private;

+  ATOM              Atom;

+  RECT              Rect;

+

+  Private = (UGA_PRIVATE_DATA *) lpParameter;

+  ASSERT (NULL != Private);

+

+  //

+  // Since each thread has unique private data, save the private data in Thread

+  // Local Storage slot. Then the shared global mTlsIndex can be used to get

+  // thread specific context.

+  //

+  Private->WinNtThunk->TlsSetValue (mTlsIndex, Private);

+

+  Private->ThreadId                   = Private->WinNtThunk->GetCurrentThreadId ();

+

+  Private->WindowsClass.cbSize        = sizeof (WNDCLASSEX);

+  Private->WindowsClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

+  Private->WindowsClass.lpfnWndProc   = WinNtUgaThreadWindowProc;

+  Private->WindowsClass.cbClsExtra    = 0;

+  Private->WindowsClass.cbWndExtra    = 0;

+  Private->WindowsClass.hInstance     = NULL;

+  Private->WindowsClass.hIcon         = Private->WinNtThunk->LoadIcon (NULL, IDI_APPLICATION);

+  Private->WindowsClass.hCursor       = Private->WinNtThunk->LoadCursor (NULL, IDC_ARROW);

+  Private->WindowsClass.hbrBackground = (HBRUSH) COLOR_WINDOW;

+  Private->WindowsClass.lpszMenuName  = NULL;

+  Private->WindowsClass.lpszClassName = WIN_NT_UGA_CLASS_NAME;

+  Private->WindowsClass.hIconSm       = Private->WinNtThunk->LoadIcon (NULL, IDI_APPLICATION);

+

+  //

+  // This call will fail after the first time, but thats O.K. since we only need

+  // WIN_NT_UGA_CLASS_NAME to exist to create the window.

+  //

+  // Note: Multiple instances of this DLL will use the same instance of this

+  // Class, including the callback function, unless the Class is unregistered and

+  // successfully registered again.

+  //

+  Atom = Private->WinNtThunk->RegisterClassEx (&Private->WindowsClass);

+

+  //

+  // Setting Rect values to allow for the AdjustWindowRect to provide

+  // us the correct sizes for the client area when doing the CreateWindowEx

+  //

+  Rect.top    = 0;

+  Rect.bottom = Private->VerticalResolution;

+  Rect.left   = 0;

+  Rect.right  = Private->HorizontalResolution;

+

+  Private->WinNtThunk->AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0);

+

+  Private->WindowHandle = Private->WinNtThunk->CreateWindowEx (

+                                                0,

+                                                WIN_NT_UGA_CLASS_NAME,

+                                                Private->WindowName,

+                                                WS_OVERLAPPEDWINDOW,

+                                                CW_USEDEFAULT,

+                                                CW_USEDEFAULT,

+                                                Rect.right - Rect.left,

+                                                Rect.bottom - Rect.top,

+                                                NULL,

+                                                NULL,

+                                                NULL,

+                                                &Private

+                                                );

+

+  //

+  // The reset of this thread is the standard winows program. We need a sperate

+  // thread since we must process the message loop to make windows act like

+  // windows.

+  //

+

+  Private->WinNtThunk->ShowWindow (Private->WindowHandle, SW_SHOW);

+  Private->WinNtThunk->UpdateWindow (Private->WindowHandle);

+

+  //

+  // Let the main thread get some work done

+  //

+  Private->WinNtThunk->ReleaseSemaphore (Private->ThreadInited, 1, NULL);

+

+  //

+  // This is the message loop that all Windows programs need.

+  //

+  while (Private->WinNtThunk->GetMessage (&Message, Private->WindowHandle, 0, 0)) {

+    Private->WinNtThunk->TranslateMessage (&Message);

+    Private->WinNtThunk->DispatchMessage (&Message);

+  }

+

+  return Message.wParam;

+}

+

+EFI_STATUS

+WinNtUgaStartWindow (

+  IN  UGA_PRIVATE_DATA    *Private,

+  IN  UINT32              HorizontalResolution,

+  IN  UINT32              VerticalResolution,

+  IN  UINT32              ColorDepth,

+  IN  UINT32              RefreshRate

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Private               - TODO: add argument description

+  HorizontalResolution  - TODO: add argument description

+  VerticalResolution    - TODO: add argument description

+  ColorDepth            - TODO: add argument description

+  RefreshRate           - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_STATUS          Status;

+  DWORD               NewThreadId;

+

+

+  mWinNt  = Private->WinNtThunk;

+

+  //

+  // Initialize a Thread Local Storge variable slot. We use TLS to get the

+  // correct Private data instance into the windows thread.

+  //

+  if (mTlsIndex == TLS_OUT_OF_INDEXES) {

+    ASSERT (0 == mTlsIndexUseCount);

+    mTlsIndex = Private->WinNtThunk->TlsAlloc ();

+  }

+

+  //

+  // always increase the use count!

+  //

+  mTlsIndexUseCount++;

+

+  Private->HorizontalResolution = HorizontalResolution;

+  Private->VerticalResolution   = VerticalResolution;

+

+  //

+  // Register to be notified on exit boot services so we can destroy the window.

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,

+                  EFI_TPL_CALLBACK,

+                  KillNtUgaThread,

+                  Private,

+                  &mUgaScreenExitBootServicesEvent

+                  );

+

+  Private->ThreadInited = Private->WinNtThunk->CreateSemaphore (NULL, 0, 1, NULL);

+  Private->ThreadHandle = Private->WinNtThunk->CreateThread (

+                                                NULL,

+                                                0,

+                                                WinNtUgaThreadWinMain,

+                                                (VOID *) Private,

+                                                0,

+                                                &NewThreadId

+                                                );

+

+  //

+  // The other thread has entered the windows message loop so we can

+  // continue our initialization.

+  //

+  Private->WinNtThunk->WaitForSingleObject (Private->ThreadInited, INFINITE);

+  Private->WinNtThunk->CloseHandle (Private->ThreadInited);

+

+  return Status;

+}

+

+EFI_STATUS

+WinNtUgaConstructor (

+  UGA_PRIVATE_DATA    *Private

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Private - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+

+  Private->UgaDraw.GetMode        = WinNtUgaGetMode;

+  Private->UgaDraw.SetMode        = WinNtUgaSetMode;

+  Private->UgaDraw.Blt            = WinNtUgaBlt;

+

+  Private->HardwareNeedsStarting  = TRUE;

+  Private->FillLine               = NULL;

+

+  WinNtUgaInitializeSimpleTextInForWindow (Private);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WinNtUgaDestructor (

+  UGA_PRIVATE_DATA     *Private

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    Private - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINT32  UnregisterReturn;

+

+  if (!Private->HardwareNeedsStarting) {

+    //

+    // BugBug: Shutdown Uga Hardware and any child devices.

+    //

+    Private->WinNtThunk->SendMessage (Private->WindowHandle, WM_DESTROY, 0, 0);

+    Private->WinNtThunk->CloseHandle (Private->ThreadHandle);

+

+    mTlsIndexUseCount--;

+

+    //

+    // The callback function for another window could still be called,

+    // so we need to make sure there are no more users of mTlsIndex.

+    //

+    if (0 == mTlsIndexUseCount) {

+      ASSERT (TLS_OUT_OF_INDEXES != mTlsIndex);

+

+      Private->WinNtThunk->TlsFree (mTlsIndex);

+      mTlsIndex = TLS_OUT_OF_INDEXES;

+

+      UnregisterReturn = Private->WinNtThunk->UnregisterClass (

+                                                Private->WindowsClass.lpszClassName,

+                                                Private->WindowsClass.hInstance

+                                                );

+    }

+

+    WinNtUgaDestroySimpleTextInForWindow (Private);

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+VOID

+EFIAPI

+KillNtUgaThread (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+/*++

+

+Routine Description:

+  

+  This is the UGA screen's callback notification function for exit-boot-services. 

+  All we do here is call WinNtUgaDestructor().

+

+Arguments:

+

+  Event   - not used

+  Context - pointer to the Private structure.

+

+Returns:

+

+  None.

+

+--*/

+{

+  EFI_STATUS  Status;

+  Status = WinNtUgaDestructor (Context);

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/build.xml
new file mode 100644
index 0000000..4d5022a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/Uga/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtUga"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Bus\Uga"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtUga">

+      <GenBuild baseName="WinNtUga" mbdFilename="${MODULE_DIR}\WinNtUga.mbd" msaFilename="${MODULE_DIR}\WinNtUga.msa"/>

+   </target>

+   <target depends="WinNtUga_clean" name="clean"/>

+   <target depends="WinNtUga_cleanall" name="cleanall"/>

+   <target name="WinNtUga_clean">

+      <OutputDirSetup baseName="WinNtUga" mbdFilename="${MODULE_DIR}\WinNtUga.mbd" msaFilename="${MODULE_DIR}\WinNtUga.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtUga_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtUga_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtUga_cleanall">

+      <OutputDirSetup baseName="WinNtUga" mbdFilename="${MODULE_DIR}\WinNtUga.mbd" msaFilename="${MODULE_DIR}\WinNtUga.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtUga_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtUga_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtUga*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/ComponentName.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/ComponentName.c
new file mode 100644
index 0000000..7dee4bd
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/ComponentName.c
@@ -0,0 +1,187 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ComponentName.c

+

+Abstract:

+

+--*/

+

+#include "WinNtBusDriver.h"

+

+//

+// EFI Component Name Functions

+//

+EFI_STATUS

+EFIAPI

+WinNtBusDriverComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+EFI_COMPONENT_NAME_PROTOCOL     gWinNtBusDriverComponentName = {

+  WinNtBusDriverComponentNameGetDriverName,

+  WinNtBusDriverComponentNameGetControllerName,

+  "eng"

+};

+

+static EFI_UNICODE_STRING_TABLE mWinNtBusDriverNameTable[] = {

+  { "eng", L"Windows Bus Driver" },

+  { NULL , NULL }

+};

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  Arguments:

+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    Language   - A pointer to a three character ISO 639-2 language identifier.

+                 This is the language of the driver name that that the caller 

+                 is requesting, and it must match one of the languages specified

+                 in SupportedLanguages.  The number of languages supported by a 

+                 driver is up to the driver writer.

+    DriverName - A pointer to the Unicode string to return.  This Unicode string

+                 is the name of the driver specified by This in the language 

+                 specified by Language.

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the Driver specified by This

+                            and the language specified by Language was returned 

+                            in DriverName.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - DriverName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  return LookupUnicodeString (

+          Language,

+          gWinNtBusDriverComponentName.SupportedLanguages,

+          mWinNtBusDriverNameTable,

+          DriverName

+          );

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+/*++

+

+  Routine Description:

+    Retrieves a Unicode string that is the user readable name of the controller

+    that is being managed by an EFI Driver.

+

+  Arguments:

+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+    ControllerHandle - The handle of a controller that the driver specified by 

+                       This is managing.  This handle specifies the controller 

+                       whose name is to be returned.

+    ChildHandle      - The handle of the child controller to retrieve the name 

+                       of.  This is an optional parameter that may be NULL.  It 

+                       will be NULL for device drivers.  It will also be NULL 

+                       for a bus drivers that wish to retrieve the name of the 

+                       bus controller.  It will not be NULL for a bus driver 

+                       that wishes to retrieve the name of a child controller.

+    Language         - A pointer to a three character ISO 639-2 language 

+                       identifier.  This is the language of the controller name 

+                       that that the caller is requesting, and it must match one

+                       of the languages specified in SupportedLanguages.  The 

+                       number of languages supported by a driver is up to the 

+                       driver writer.

+    ControllerName   - A pointer to the Unicode string to return.  This Unicode

+                       string is the name of the controller specified by 

+                       ControllerHandle and ChildHandle in the language specified

+                       by Language from the point of view of the driver specified

+                       by This. 

+

+  Returns:

+    EFI_SUCCESS           - The Unicode string for the user readable name in the 

+                            language specified by Language for the driver 

+                            specified by This was returned in DriverName.

+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+    EFI_INVALID_PARAMETER - Language is NULL.

+    EFI_INVALID_PARAMETER - ControllerName is NULL.

+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing 

+                            the controller specified by ControllerHandle and 

+                            ChildHandle.

+    EFI_UNSUPPORTED       - The driver specified by This does not support the 

+                            language specified by Language.

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;

+  WIN_NT_IO_DEVICE        *Private;

+

+  //

+  // This is a bus driver, so ChildHandle can not be NULL.

+  //

+  if (ChildHandle == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get our context back

+  //

+  Status = gBS->OpenProtocol (

+                  ChildHandle,

+                  &gEfiWinNtIoProtocolGuid,

+                  &WinNtIo,

+                  gWinNtBusDriverBinding.DriverBindingHandle,

+                  ChildHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  Private = WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo);

+

+  return LookupUnicodeString (

+          Language,

+          gWinNtBusDriverComponentName.SupportedLanguages,

+          Private->ControllerNameTable,

+          ControllerName

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.c
new file mode 100644
index 0000000..eb07157
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.c
@@ -0,0 +1,744 @@
+/*+++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtBusDriver.c

+

+Abstract:

+

+This following section documents the envirnoment variables for the Win NT 

+build.  These variables are used to define the (virtual) hardware 

+configuration of the NT environment

+

+A ! can be used to seperate multiple instances in a variable. Each 

+instance represents a seperate hardware device. 

+

+EFI_WIN_NT_PHYSICAL_DISKS - maps to drives on your system

+EFI_WIN_NT_VIRTUAL_DISKS  - maps to a device emulated by a file

+EFI_WIN_NT_FILE_SYSTEM    - mouts a directory as a file system

+EFI_WIN_NT_CONSOLE        - make a logical comand line window (only one!)

+EFI_WIN_NT_UGA            - Builds UGA Windows of Width and Height

+EFI_WIN_NT_SERIAL_PORT    - maps physical serial ports

+

+ <F>ixed       - Fixed disk like a hard drive.

+ <R>emovable   - Removable media like a floppy or CD-ROM.

+ Read <O>nly   - Write protected device.

+ Read <W>rite  - Read write device.

+ <block count> - Decimal number of blocks a device supports.

+ <block size>  - Decimal number of bytes per block.

+

+ NT envirnonment variable contents. '<' and '>' are not part of the variable, 

+ they are just used to make this help more readable. There should be no 

+ spaces between the ';'. Extra spaces will break the variable. A '!' is  

+ used to seperate multiple devices in a variable.

+

+ EFI_WIN_NT_VIRTUAL_DISKS = 

+   <F | R><O | W>;<block count>;<block size>[!...]

+

+ EFI_WIN_NT_PHYSICAL_DISKS =

+   <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]

+

+ Virtual Disks: These devices use a file to emulate a hard disk or removable

+                media device. 

+                

+   Thus a 20 MB emulated hard drive would look like:

+   EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512

+

+   A 1.44MB emulated floppy with a block size of 1024 would look like:

+   EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024

+

+ Physical Disks: These devices use NT to open a real device in your system

+

+   Thus a 120 MB floppy would look like:

+   EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512

+

+   Thus a standard CD-ROM floppy would look like:

+   EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048

+

+ EFI_WIN_NT_FILE_SYSTEM = 

+   <directory path>[!...]

+

+   Mounting the two directories C:\FOO and C:\BAR would look like:

+   EFI_WIN_NT_FILE_SYSTEM=c:\foo!c:\bar

+

+ EFI_WIN_NT_CONSOLE = 

+   <window title>

+

+   Declaring a text console window with the title "My EFI Console" woild look like:

+   EFI_WIN_NT_CONSOLE=My EFI Console

+

+ EFI_WIN_NT_UGA = 

+   <width> <height>[!...]

+

+   Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:

+   Example : EFI_WIN_NT_UGA=800 600!1024 768

+

+ EFI_WIN_NT_SERIAL_PORT = 

+   <port name>[!...]

+

+   Declaring two serial ports on COM1 and COM2 would look like:

+   Example : EFI_WIN_NT_SERIAL_PORT=COM1!COM2

+

+ EFI_WIN_NT_PASS_THROUGH =

+   <BaseAddress>;<Bus#>;<Device#>;<Function#>

+

+   Declaring a base address of 0xE0000000 (used for PCI Express devices)

+   and having NT32 talk to a device located at bus 0, device 1, function 0:

+   Example : EFI_WIN_NT_PASS_THROUGH=E000000;0;1;0

+

+---*/

+

+#include "WinNtBusDriver.h"

+//#include "PciHostBridge.h"

+

+//

+// Define GUID for the WinNt Bus Driver

+//

+static EFI_GUID gWinNtBusDriverGuid = {

+  0x419f582, 0x625, 0x4531, 0x8a, 0x33, 0x85, 0xa9, 0x96, 0x5c, 0x95, 0xbc

+};

+

+//

+// DriverBinding protocol global

+//

+EFI_DRIVER_BINDING_PROTOCOL           gWinNtBusDriverBinding = {

+  WinNtBusDriverBindingSupported,

+  WinNtBusDriverBindingStart,

+  WinNtBusDriverBindingStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+#define NT_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(NT_PCD_ENTRY))

+

+//

+// Table to map NT Environment variable to the GUID that should be in

+// device path.

+//

+static NT_PCD_ENTRY  mPcdEnvironment[] = {

+  PcdToken(PcdWinNtConsole),       &gEfiWinNtConsoleGuid,

+  PcdToken(PcdWinNtUga),           &gEfiWinNtUgaGuid,

+  PcdToken(PcdWinNtSerialPort),    &gEfiWinNtSerialPortGuid,

+  PcdToken(PcdWinNtFileSystem),    &gEfiWinNtFileSystemGuid,

+  PcdToken(PcdWinNtVirtualDisk),   &gEfiWinNtVirtualDisksGuid,

+  PcdToken(PcdWinNtPhysicalDisk),  &gEfiWinNtPhysicalDisksGuid,

+  PcdToken(PcdWinNtCpuModel),      &gEfiWinNtCPUModelGuid,

+  PcdToken(PcdWinNtCpuSpeed),      &gEfiWinNtCPUSpeedGuid,

+  PcdToken(PcdWinNtMemorySize),    &gEfiWinNtMemoryGuid

+};

+

+VOID *

+AllocateMemory (

+  IN  UINTN   Size

+  )

+{

+  EFI_STATUS  Status;

+  VOID        *Buffer;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  Size,

+                  (VOID *)&Buffer

+                  );

+  if (EFI_ERROR (Status)) {

+    ASSERT (FALSE);

+    return NULL;

+  }

+  return Buffer;

+}

+

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverBindingSupported (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ControllerHandle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+  EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;

+  UINTN                     Index;

+

+  //

+  // Check the contents of the first Device Path Node of RemainingDevicePath to make sure

+  // it is a legal Device Path Node for this bus driver's children.

+  //

+  if (RemainingDevicePath != NULL) {

+    if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||

+        RemainingDevicePath->SubType != HW_VENDOR_DP ||

+        DevicePathNodeLength(RemainingDevicePath) != sizeof(WIN_NT_VENDOR_DEVICE_PATH_NODE)) {

+      return EFI_UNSUPPORTED;

+    }

+

+    for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {

+      if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {

+        break;

+      }

+    }

+

+    if (Index >= NT_PCD_ARRAY_SIZE) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  

+  //

+  // Open the IO Abstraction(s) needed to perform the supported test

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiDevicePathProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtThunkProtocolGuid,

+                  &WinNtThunk,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (Status == EFI_ALREADY_STARTED) {

+    return EFI_SUCCESS;

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Since we call through WinNtThunk we need to make sure it's valid

+  //

+  Status = EFI_SUCCESS;

+  if (WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {

+    Status = EFI_UNSUPPORTED;

+  }

+

+  //

+  // Close the I/O Abstraction(s) used to perform the supported test

+  //

+  gBS->CloseProtocol (

+        ControllerHandle,

+        &gEfiWinNtThunkProtocolGuid,

+        This->DriverBindingHandle,

+        ControllerHandle

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverBindingStart (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ControllerHandle - add argument and description to function comment

+// TODO:    RemainingDevicePath - add argument and description to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                      Status;

+  EFI_STATUS                      InstallStatus;

+  EFI_WIN_NT_THUNK_PROTOCOL       *WinNtThunk;

+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;

+  WIN_NT_BUS_DEVICE               *WinNtBusDevice;

+  WIN_NT_IO_DEVICE                *WinNtDevice;

+  UINTN                           Index;

+  CHAR16                          *StartString;

+  CHAR16                          *SubString;

+  UINT16                          Count;

+  UINTN                           StringSize;

+  UINT16                          ComponentName[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH];

+  WIN_NT_VENDOR_DEVICE_PATH_NODE  *Node;

+  BOOLEAN                         CreateDevice;

+  CHAR16                          *TempStr;

+  CHAR16                          *PcdTempStr;

+  UINTN                           TempStrSize;

+

+  //

+  // Test Feature Set and Binary Patchable Case

+  //

+  if (FeaturePcdGet (PcdWinNtFeatureFlag1)) {

+  	TempStrSize = PatchPcdGet32(PcdWinNtBinaryPatch1) + PatchPcdGet32(PcdWinNtBinaryPatch2);

+  }

+  

+  if (0) {

+    //

+    // Test Dynamic and DynamicEx 

+    // (Please add PcdWinNtConsole in "WinNtBusDriver.inf" before enable this code!!!)

+    //

+    PcdTempStr = PcdGetPtr (PcdWinNtConsole);

+  }

+

+  //

+  // Test Dynamic Set and Dynamic Set Ex

+  //

+  PcdSet32 (PcdWinNtDynamicUINT32, 2006);

+

+  Status = EFI_UNSUPPORTED;

+

+  //

+  // Grab the protocols we need

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiDevicePathProtocolGuid,

+                  &ParentDevicePath,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiWinNtThunkProtocolGuid,

+                  &WinNtThunk,

+                  This->DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {

+    return Status;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData,

+                    sizeof (WIN_NT_BUS_DEVICE),

+                    (VOID *) &WinNtBusDevice

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    WinNtBusDevice->Signature           = WIN_NT_BUS_DEVICE_SIGNATURE;

+    WinNtBusDevice->ControllerNameTable = NULL;

+

+    AddUnicodeString (

+      "eng",

+      gWinNtBusDriverComponentName.SupportedLanguages,

+      &WinNtBusDevice->ControllerNameTable,

+      L"Windows Bus Controller"

+      );

+

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &ControllerHandle,

+                    &gWinNtBusDriverGuid,

+                    WinNtBusDevice,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);

+      gBS->FreePool (WinNtBusDevice);

+      return Status;

+    }

+  }

+

+  //

+  // Loop on the Variable list. Parse each variable to produce a set of handles that

+  // represent virtual hardware devices.

+  //

+  InstallStatus   = EFI_NOT_FOUND;

+  for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {

+    PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);

+    ASSERT (PcdTempStr != NULL);

+

+    TempStrSize = StrLen (PcdTempStr);

+    TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);

+    StrCpy (TempStr, PcdTempStr);

+

+    StartString = TempStr;

+

+    //

+    // Parse the envirnment variable into sub strings using '!' as a delimator.

+    // Each substring needs it's own handle to be added to the system. This code

+    // does not understand the sub string. Thats the device drivers job.

+    //

+    Count = 0;

+    while (*StartString != '\0') {

+

+      //

+      // Find the end of the sub string

+      //

+      SubString = StartString;

+      while (*SubString != '\0' && *SubString != '!') {

+        SubString++;

+      }

+

+      if (*SubString == '!') {

+        //

+        // Replace token with '\0' to make sub strings. If this is the end

+        //  of the string SubString will already point to NULL.

+        //

+        *SubString = '\0';

+        SubString++;

+      }

+

+      CreateDevice = TRUE;

+      if (RemainingDevicePath != NULL) {

+        CreateDevice  = FALSE;

+        Node          = (WIN_NT_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;

+        if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&

+            Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&

+            DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)

+            ) {

+          if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&

+              Node->Instance == Count

+              ) {

+            CreateDevice = TRUE;

+          }

+        }

+      }

+

+      if (CreateDevice) {

+

+        //

+        // Allocate instance structure, and fill in parent information.

+        //

+        WinNtDevice = AllocateMemory (sizeof (WIN_NT_IO_DEVICE));

+        if (WinNtDevice == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+

+        WinNtDevice->Handle             = NULL;

+        WinNtDevice->ControllerHandle   = ControllerHandle;

+        WinNtDevice->ParentDevicePath   = ParentDevicePath;

+

+        WinNtDevice->WinNtIo.WinNtThunk = WinNtThunk;

+

+        //

+        // Plus 2 to account for the NULL at the end of the Unicode string

+        //

+        StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);

+        WinNtDevice->WinNtIo.EnvString = AllocateMemory (StringSize);

+        if (WinNtDevice->WinNtIo.EnvString != NULL) {

+          CopyMem (WinNtDevice->WinNtIo.EnvString, StartString, StringSize);

+        }

+

+        WinNtDevice->ControllerNameTable = NULL;

+

+        WinNtThunk->SPrintf (ComponentName, L"%s", WinNtDevice->WinNtIo.EnvString);

+

+        WinNtDevice->DevicePath = WinNtBusCreateDevicePath (

+                                    ParentDevicePath,

+                                    mPcdEnvironment[Index].DevicePathGuid,

+                                    Count

+                                    );

+        if (WinNtDevice->DevicePath == NULL) {

+          gBS->FreePool (WinNtDevice);

+          return EFI_OUT_OF_RESOURCES;

+        }

+

+        AddUnicodeString (

+          "eng",

+          gWinNtBusDriverComponentName.SupportedLanguages,

+          &WinNtDevice->ControllerNameTable,

+          ComponentName

+          );

+

+        WinNtDevice->WinNtIo.TypeGuid       = mPcdEnvironment[Index].DevicePathGuid;

+        WinNtDevice->WinNtIo.InstanceNumber = Count;

+

+        WinNtDevice->Signature              = WIN_NT_IO_DEVICE_SIGNATURE;

+

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &WinNtDevice->Handle,

+                        &gEfiDevicePathProtocolGuid,

+                        WinNtDevice->DevicePath,

+                        &gEfiWinNtIoProtocolGuid,

+                        &WinNtDevice->WinNtIo,

+                        NULL

+                        );

+        if (EFI_ERROR (Status)) {

+          FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);

+          gBS->FreePool (WinNtDevice);

+        } else {

+          //

+          // Open For Child Device

+          //

+          Status = gBS->OpenProtocol (

+                          ControllerHandle,

+                          &gEfiWinNtThunkProtocolGuid,

+                          &WinNtThunk,

+                          This->DriverBindingHandle,

+                          WinNtDevice->Handle,

+                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+                          );

+          if (!EFI_ERROR (Status)) {

+            InstallStatus = EFI_SUCCESS;

+          }

+        }

+      }

+

+      //

+      // Parse Next sub string. This will point to '\0' if we are at the end.

+      //

+      Count++;

+      StartString = SubString;

+    }

+

+    gBS->FreePool (TempStr);

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+    None

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    ControllerHandle - add argument and description to function comment

+// TODO:    NumberOfChildren - add argument and description to function comment

+// TODO:    ChildHandleBuffer - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS                Status;

+  UINTN                     Index;

+  BOOLEAN                   AllChildrenStopped;

+  EFI_WIN_NT_IO_PROTOCOL    *WinNtIo;

+  WIN_NT_BUS_DEVICE         *WinNtBusDevice;

+  WIN_NT_IO_DEVICE          *WinNtDevice;

+  EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;

+

+  //

+  // Complete all outstanding transactions to Controller.

+  // Don't allow any new transaction to Controller to be started.

+  //

+

+  if (NumberOfChildren == 0) {

+    //

+    // Close the bus driver

+    //

+    Status = gBS->OpenProtocol (

+                    ControllerHandle,

+                    &gWinNtBusDriverGuid,

+                    &WinNtBusDevice,

+                    This->DriverBindingHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    gBS->UninstallMultipleProtocolInterfaces (

+          ControllerHandle,

+          &gWinNtBusDriverGuid,

+          WinNtBusDevice,

+          NULL

+          );

+

+    FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);

+

+    gBS->FreePool (WinNtBusDevice);

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiWinNtThunkProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiDevicePathProtocolGuid,

+          This->DriverBindingHandle,

+          ControllerHandle

+          );

+    return EFI_SUCCESS;

+  }

+

+  AllChildrenStopped = TRUE;

+

+  for (Index = 0; Index < NumberOfChildren; Index++) {

+

+    Status = gBS->OpenProtocol (

+                    ChildHandleBuffer[Index],

+                    &gEfiWinNtIoProtocolGuid,

+                    &WinNtIo,

+                    This->DriverBindingHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (!EFI_ERROR (Status)) {

+

+      WinNtDevice = WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo);

+

+      Status = gBS->CloseProtocol (

+                      ControllerHandle,

+                      &gEfiWinNtThunkProtocolGuid,

+                      This->DriverBindingHandle,

+                      WinNtDevice->Handle

+                      );

+

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      WinNtDevice->Handle,

+                      &gEfiDevicePathProtocolGuid,

+                      WinNtDevice->DevicePath,

+                      &gEfiWinNtIoProtocolGuid,

+                      &WinNtDevice->WinNtIo,

+                      NULL

+                      );

+

+      if (EFI_ERROR (Status)) {

+        gBS->OpenProtocol (

+              ControllerHandle,

+              &gEfiWinNtThunkProtocolGuid,

+              (VOID **) &WinNtThunk,

+              This->DriverBindingHandle,

+              WinNtDevice->Handle,

+              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER

+              );

+      } else {

+        //

+        // Close the child handle

+        //

+        FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);

+        gBS->FreePool (WinNtDevice);

+      }

+    }

+

+    if (EFI_ERROR (Status)) {

+      AllChildrenStopped = FALSE;

+    }

+  }

+

+  if (!AllChildrenStopped) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_DEVICE_PATH_PROTOCOL *

+WinNtBusCreateDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath,

+  IN  EFI_GUID                  *Guid,

+  IN  UINT16                    InstanceNumber

+  )

+/*++

+

+Routine Description:

+  Create a device path node using Guid and InstanceNumber and append it to

+  the passed in RootDevicePath

+

+Arguments:

+  RootDevicePath - Root of the device path to return.

+

+  Guid           - GUID to use in vendor device path node.

+

+  InstanceNumber - Instance number to use in the vendor device path. This

+                    argument is needed to make sure each device path is unique.

+

+Returns:

+

+  EFI_DEVICE_PATH_PROTOCOL 

+

+--*/

+{

+  WIN_NT_VENDOR_DEVICE_PATH_NODE  DevicePath;

+

+  DevicePath.VendorDevicePath.Header.Type     = HARDWARE_DEVICE_PATH;

+  DevicePath.VendorDevicePath.Header.SubType  = HW_VENDOR_DP;

+  SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE));

+

+  //

+  // The GUID defines the Class

+  //

+  CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));

+

+  //

+  // Add an instance number so we can make sure there are no Device Path

+  // duplication.

+  //

+  DevicePath.Instance = InstanceNumber;

+

+  return AppendDevicePathNode (

+          RootDevicePath,

+          (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath

+          );

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.h
new file mode 100644
index 0000000..414465b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.h
@@ -0,0 +1,297 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtBusDriver.h

+

+Abstract:

+

+This following section documents the envirnoment variables for the Win NT 

+build.  These variables are used to define the (virtual) hardware 

+configuration of the NT environment

+

+A ! can be used to seperate multiple instances in a variable. Each 

+instance represents a seperate hardware device. 

+

+EFI_WIN_NT_PHYSICAL_DISKS - maps to drives on your system

+EFI_WIN_NT_VIRTUAL_DISKS  - maps to a device emulated by a file

+EFI_WIN_NT_FILE_SYSTEM    - mouts a directory as a file system

+EFI_WIN_NT_CONSOLE        - make a logical comand line window (only one!)

+EFI_WIN_NT_UGA            - Builds UGA Windows of Width and Height

+EFI_WIN_NT_SERIAL_PORT    - maps physical serial ports

+EFI_WIN_NT_PASS_THRU      - associates a device with our PCI support

+

+ <F>ixed       - Fixed disk like a hard drive.

+ <R>emovable   - Removable media like a floppy or CD-ROM.

+ Read <O>nly   - Write protected device.

+ Read <W>rite  - Read write device.

+ <block count> - Decimal number of blocks a device supports.

+ <block size>  - Decimal number of bytes per block.

+

+ NT envirnonment variable contents. '<' and '>' are not part of the variable, 

+ they are just used to make this help more readable. There should be no 

+ spaces between the ';'. Extra spaces will break the variable. A '!' is  

+ used to seperate multiple devices in a variable.

+

+ EFI_WIN_NT_VIRTUAL_DISKS = 

+   <F | R><O | W>;<block count>;<block size>[!...]

+

+ EFI_WIN_NT_PHYSICAL_DISKS =

+   <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]

+

+ Virtual Disks: These devices use a file to emulate a hard disk or removable

+                media device. 

+                

+   Thus a 20 MB emulated hard drive would look like:

+   EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512

+

+   A 1.44MB emulated floppy with a block size of 1024 would look like:

+   EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024

+

+ Physical Disks: These devices use NT to open a real device in your system

+

+   Thus a 120 MB floppy would look like:

+   EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512

+

+   Thus a standard CD-ROM floppy would look like:

+   EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048

+

+ EFI_WIN_NT_FILE_SYSTEM = 

+   <directory path>[!...]

+

+   Mounting the two directories C:\FOO and C:\BAR would look like:

+   EFI_WIN_NT_FILE_SYSTEM=c:\foo!c:\bar

+

+ EFI_WIN_NT_CONSOLE = 

+   <window title>

+

+   Declaring a text console window with the title "My EFI Console" woild look like:

+   EFI_WIN_NT_CONSOLE=My EFI Console

+

+ EFI_WIN_NT_UGA = 

+   <width> <height>[!...]

+

+   Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:

+   Example : EFI_WIN_NT_UGA=800 600!1024 768

+

+ EFI_WIN_NT_SERIAL_PORT = 

+   <port name>[!...]

+

+   Declaring two serial ports on COM1 and COM2 would look like:

+   Example : EFI_WIN_NT_SERIAL_PORT=COM1!COM2

+

+ EFI_WIN_NT_PASS_THROUGH =

+   <BaseAddress>;<Bus#>;<Device#>;<Function#>

+

+   Declaring a base address of 0xE0000000 (used for PCI Express devices)

+   and having NT32 talk to a device located at bus 0, device 1, function 0:

+   Example : EFI_WIN_NT_PASS_THROUGH=E000000;0;1;0

+

+---*/

+

+#ifndef __NT_BUS_DRIVER_H__

+#define __NT_BUS_DRIVER_H__

+

+

+

+//

+// WinNt Bus Driver Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gWinNtBusDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gWinNtBusDriverComponentName;

+

+//

+// WinNt Bus Controller Structure

+//

+#define WIN_NT_BUS_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 'B', 'D')

+

+typedef struct {

+  UINT64                    Signature;

+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;

+} WIN_NT_BUS_DEVICE;

+

+//

+// WinNt Child Device Controller Structure

+//

+#define WIN_NT_IO_DEVICE_SIGNATURE  EFI_SIGNATURE_32 ('N', 'T', 'V', 'D')

+

+typedef struct {

+  UINT64                    Signature;

+  EFI_HANDLE                Handle;

+  EFI_WIN_NT_IO_PROTOCOL    WinNtIo;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+

+  //

+  // Private data about the parent

+  //

+  EFI_HANDLE                ControllerHandle;

+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

+

+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;

+

+} WIN_NT_IO_DEVICE;

+

+#define WIN_NT_IO_DEVICE_FROM_THIS(a) \

+  CR(a, WIN_NT_IO_DEVICE, WinNtIo, WIN_NT_IO_DEVICE_SIGNATURE)

+

+//

+// This is the largest env variable we can parse

+//

+#define MAX_NT_ENVIRNMENT_VARIABLE_LENGTH 512

+

+typedef struct {

+  UINTN               Token;

+  EFI_GUID            *DevicePathGuid;

+} NT_PCD_ENTRY;

+

+typedef struct {

+  VENDOR_DEVICE_PATH  VendorDevicePath;

+  UINT32              Instance;

+} WIN_NT_VENDOR_DEVICE_PATH_NODE;

+

+EFI_STATUS

+EFIAPI

+CpuIoInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// Driver Binding Protocol function prototypes

+//

+EFI_STATUS

+EFIAPI

+WinNtBusDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Handle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  Handle              - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     ParentHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This                - TODO: add argument description

+  ParentHandle        - TODO: add argument description

+  RemainingDevicePath - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtBusDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Handle,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This              - TODO: add argument description

+  Handle            - TODO: add argument description

+  NumberOfChildren  - TODO: add argument description

+  ChildHandleBuffer - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// WinNt Bus Driver private worker functions

+//

+EFI_DEVICE_PATH_PROTOCOL  *

+WinNtBusCreateDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath,

+  IN  EFI_GUID                  *Guid,

+  IN  UINT16                    InstanceNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  RootDevicePath  - TODO: add argument description

+  Guid            - TODO: add argument description

+  InstanceNumber  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.mbd
new file mode 100644
index 0000000..eb50771
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtBusDriver</BaseName>

+    <Guid>BD7E9A27-D6C5-416a-B245-5F507D95B2BD</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:02</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>UefiDriverModelLib</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxePcdLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+    <Library>UefiDevicePathLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.msa
new file mode 100644
index 0000000..9bc94bf
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.msa
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtBusDriver</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>BD7E9A27-D6C5-416a-B245-5F507D95B2BD</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtBusDriver module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:02</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtBusDriver.h</Filename>

+    <Filename>WinNtBusDriver.c</Filename>

+    <Filename>ComponentName.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="BY_START">WinNtIo</Protocol>

+    <Protocol Usage="TO_START">WinNtThunk</Protocol>

+    <Protocol Usage="TO_START">DevicePath</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Pcd</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtVirtualDisks</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtPhysicalDisks</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtFileSystem</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtSerialPort</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtUga</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtConsole</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtMemory</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtCPUModel</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>WinNtCPUSpeed</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <DriverBinding>gWinNtBusDriverBinding</DriverBinding>

+      <ComponentName>gWinNtBusDriverComponentName</ComponentName>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtConsole</C_Name>

+      <Token>0x0000100a</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtUga</C_Name>

+      <Token>0x00001003</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtSerialPort</C_Name>

+      <Token>0x00001002</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtFileSystem</C_Name>

+      <Token>0x00001004</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtVirtualDisk</C_Name>

+      <Token>0x00001001</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtPhysicalDisk</C_Name>

+      <Token>0x00001000</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtCpuModel</C_Name>

+      <Token>0x00001007</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtCpuSpeed</C_Name>

+      <Token>0x00001008</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtMemorySize</C_Name>

+      <Token>0x00001005</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdWinNtBinaryPatch1</C_Name>

+      <Token>0x0001000b</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdWinNtBinaryPatch2</C_Name>

+      <Token>0x0001000c</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FEATURE_FLAG">

+      <C_Name>PcdWinNtFeatureFlag1</C_Name>

+      <Token>0x0001000d</Token>

+      <DatumType>BOOLEAN</DatumType>

+    </PcdData>

+    <PcdData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtDynamicUINT32</C_Name>

+      <Token>0x0001000e</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/build.xml
new file mode 100644
index 0000000..93d853b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtBusDriver"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Bus\WinNtBusDriver"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtBusDriver">

+      <GenBuild baseName="WinNtBusDriver" mbdFilename="${MODULE_DIR}\WinNtBusDriver.mbd" msaFilename="${MODULE_DIR}\WinNtBusDriver.msa"/>

+   </target>

+   <target depends="WinNtBusDriver_clean" name="clean"/>

+   <target depends="WinNtBusDriver_cleanall" name="cleanall"/>

+   <target name="WinNtBusDriver_clean">

+      <OutputDirSetup baseName="WinNtBusDriver" mbdFilename="${MODULE_DIR}\WinNtBusDriver.mbd" msaFilename="${MODULE_DIR}\WinNtBusDriver.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtBusDriver_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtBusDriver_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtBusDriver_cleanall">

+      <OutputDirSetup baseName="WinNtBusDriver" mbdFilename="${MODULE_DIR}\WinNtBusDriver.mbd" msaFilename="${MODULE_DIR}\WinNtBusDriver.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtBusDriver_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtBusDriver_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtBusDriver*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.c
new file mode 100644
index 0000000..394ca6e
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.c
@@ -0,0 +1,129 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  Metronome.c

+

+Abstract:

+

+  NT Emulation Metronome Architectural Protocol Driver as defined in DXE CIS

+

+--*/

+

+#include "Metronome.h"

+

+//

+// Global Variables

+//

+EFI_METRONOME_ARCH_PROTOCOL mMetronome = {

+  WinNtMetronomeDriverWaitForTick,

+  TICK_PERIOD

+};

+

+//

+// Worker Functions

+//

+

+EFI_STATUS

+EFIAPI

+WinNtMetronomeDriverWaitForTick (

+  IN EFI_METRONOME_ARCH_PROTOCOL  *This,

+  IN UINT32                       TickNumber

+  )

+/*++

+

+Routine Description:

+

+  The WaitForTick() function waits for the number of ticks specified by

+  TickNumber from a known time source in the platform.  If TickNumber of

+  ticks are detected, then EFI_SUCCESS is returned.  The actual time passed

+  between entry of this function and the first tick is between 0 and

+  TickPeriod 100 nS units.  If you want to guarantee that at least TickPeriod

+  time has elapsed, wait for two ticks.  This function waits for a hardware

+  event to determine when a tick occurs.  It is possible for interrupt

+  processing, or exception processing to interrupt the execution of the

+  WaitForTick() function.  Depending on the hardware source for the ticks, it

+  is possible for a tick to be missed.  This function cannot guarantee that

+  ticks will not be missed.  If a timeout occurs waiting for the specified

+  number of ticks, then EFI_TIMEOUT is returned.

+

+Arguments:

+

+  This       - The EFI_METRONOME_ARCH_PROTOCOL instance.

+  TickNumber - Number of ticks to wait.

+

+Returns:

+

+  EFI_SUCCESS - The wait for the number of ticks specified by TickNumber

+                succeeded.

+

+--*/

+{

+  UINT64  SleepTime;

+

+  //

+  // Calculate the time to sleep.  Win API smallest unit to sleep is 1 millisec

+  // Tick Period is in 100ns units, divide by 10000 to convert to ms

+  //

+  SleepTime = DivU64x32 (MultU64x32 ((UINT64) TickNumber, TICK_PERIOD) + 9999, 10000);

+  gWinNt->Sleep ((UINT32) SleepTime);

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+WinNtMetronomeDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initialize the Metronome Architectural Protocol driver

+

+Arguments:

+

+  ImageHandle - ImageHandle of the loaded driver

+

+

+  SystemTable - Pointer to the System Table

+

+Returns:

+

+  EFI_SUCCESS           - Metronome Architectural Protocol created

+

+  EFI_OUT_OF_RESOURCES  - Not enough resources available to initialize driver.

+

+  EFI_DEVICE_ERROR      - A device error occured attempting to initialize the driver.

+

+--*/

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE  Handle;

+

+

+  //

+  // Install the Metronome Architectural Protocol onto a new handle

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiMetronomeArchProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &mMetronome

+                  );

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.dxs b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.dxs
new file mode 100644
index 0000000..d11f48a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Metronome.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.h
new file mode 100644
index 0000000..d89a149
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.h
@@ -0,0 +1,84 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Metronome.h

+

+Abstract:

+

+  NT Emulation Metronome Architectural Protocol Driver as defined in DXE CIS

+

+--*/

+

+#ifndef _NT_THUNK_METRONOME_H_

+#define _NT_THUNK_METRONOME_H_

+

+

+

+//

+// Period of on tick in 100 nanosecond units

+//

+#define TICK_PERIOD 2000

+

+//

+// Function Prototypes

+//

+

+EFI_STATUS

+EFIAPI

+WinNtMetronomeDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtMetronomeDriverWaitForTick (

+  IN EFI_METRONOME_ARCH_PROTOCOL  *This,

+  IN UINT32                       TickNumber

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  TickNumber  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.mbd
new file mode 100644
index 0000000..f510b42
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Metronome</BaseName>

+    <Guid>154CAB4A-52B5-46CD-99C3-4368ABBACFFD</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeWinNtLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.msa
new file mode 100644
index 0000000..abaeca9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/Metronome.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Metronome</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>154CAB4A-52B5-46CD-99C3-4368ABBACFFD</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Metronome module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Metronome.c</Filename>

+    <Filename>Metronome.h</Filename>

+    <Filename>Metronome.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Metronome</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>WinNtMetronomeDriverInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/build.xml
new file mode 100644
index 0000000..5922fac
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Metronome/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Metronome"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Chipset\Metronome"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Metronome">

+      <GenBuild baseName="Metronome" mbdFilename="${MODULE_DIR}\Metronome.mbd" msaFilename="${MODULE_DIR}\Metronome.msa"/>

+   </target>

+   <target depends="Metronome_clean" name="clean"/>

+   <target depends="Metronome_cleanall" name="cleanall"/>

+   <target name="Metronome_clean">

+      <OutputDirSetup baseName="Metronome" mbdFilename="${MODULE_DIR}\Metronome.mbd" msaFilename="${MODULE_DIR}\Metronome.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Metronome_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Metronome_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Metronome_cleanall">

+      <OutputDirSetup baseName="Metronome" mbdFilename="${MODULE_DIR}\Metronome.mbd" msaFilename="${MODULE_DIR}\Metronome.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Metronome_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Metronome_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Metronome*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.c
new file mode 100644
index 0000000..b705ee6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.c
@@ -0,0 +1,391 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  RealTimeClock.c

+

+Abstract:

+

+  NT Emulation Architectural Protocol Driver as defined in Tiano

+

+--*/

+

+

+

+BOOLEAN

+DayValid (

+  IN  EFI_TIME  *Time

+  );

+

+BOOLEAN

+IsLeapYear (

+  IN EFI_TIME   *Time

+  );

+

+EFI_STATUS

+RtcTimeFieldsValid (

+  IN EFI_TIME *Time

+  );

+

+EFI_STATUS

+EFIAPI

+InitializeRealTimeClock (

+  IN EFI_HANDLE                          ImageHandle,

+  IN EFI_SYSTEM_TABLE                    *SystemTable

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtGetTime (

+  OUT EFI_TIME                                 *Time,

+  OUT EFI_TIME_CAPABILITIES                    *Capabilities OPTIONAL

+  )

+/*++

+

+Routine Description:

+  Service routine for RealTimeClockInstance->GetTime 

+

+Arguments:

+

+  Time          - A pointer to storage that will receive a snapshot of the current time.

+

+  Capabilities  - A pointer to storage that will receive the capabilities of the real time clock

+                  in the platform. This includes the real time clock's resolution and accuracy.  

+                  All reported device capabilities are rounded up.  This is an OPTIONAL argument.

+

+Returns:

+

+  EFI_SUCEESS   - The underlying GetSystemTime call occurred and returned

+                  Note that in the NT32 emulation, the GetSystemTime call has no return value

+                  thus you will always receive a EFI_SUCCESS on this.

+

+--*/

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  SYSTEMTIME            SystemTime;

+  TIME_ZONE_INFORMATION TimeZone;

+

+  //

+  // Check parameter for null pointer

+  //

+  if (Time == NULL) {

+    return EFI_INVALID_PARAMETER;

+

+  }

+

+  gWinNt->GetLocalTime (&SystemTime);

+  gWinNt->GetTimeZoneInformation (&TimeZone);

+

+  Time->Year        = (UINT16) SystemTime.wYear;

+  Time->Month       = (UINT8) SystemTime.wMonth;

+  Time->Day         = (UINT8) SystemTime.wDay;

+  Time->Hour        = (UINT8) SystemTime.wHour;

+  Time->Minute      = (UINT8) SystemTime.wMinute;

+  Time->Second      = (UINT8) SystemTime.wSecond;

+  Time->Nanosecond  = (UINT32) (SystemTime.wMilliseconds * 1000000);

+  Time->TimeZone    = (INT16) TimeZone.Bias;

+

+  if (Capabilities != NULL) {

+    Capabilities->Resolution  = 1;

+    Capabilities->Accuracy    = 50000000;

+    Capabilities->SetsToZero  = FALSE;

+  }

+

+  Time->Daylight = 0;

+  if (TimeZone.StandardDate.wMonth) {

+    Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSetTime (

+  IN EFI_TIME   *Time

+  )

+/*++

+

+Routine Description:

+  Service routine for RealTimeClockInstance->SetTime 

+

+Arguments:

+

+  Time          - A pointer to storage containing the time and date information to

+                  program into the real time clock.

+

+Returns:

+

+  EFI_SUCEESS           - The operation completed successfully.

+                  

+  EFI_INVALID_PARAMETER - One of the fields in Time is out of range.

+

+  EFI_DEVICE_ERROR      - The operation could not be complete due to a device error.

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  TIME_ZONE_INFORMATION TimeZone;

+  EFI_STATUS            Status;

+  SYSTEMTIME            SystemTime;

+  BOOL                  Flag;

+

+  if (Time == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Make sure that the time fields are valid

+  //

+  Status = RtcTimeFieldsValid (Time);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Set Daylight savings time information and Time Zone

+  //

+  gWinNt->GetTimeZoneInformation (&TimeZone);

+  TimeZone.StandardDate.wMonth  = Time->Daylight;

+  TimeZone.Bias                 = Time->TimeZone;

+  gWinNt->SetTimeZoneInformation (&TimeZone);

+

+  SystemTime.wYear          = Time->Year;

+  SystemTime.wMonth         = Time->Month;

+  SystemTime.wDay           = Time->Day;

+  SystemTime.wHour          = Time->Hour;

+  SystemTime.wMinute        = Time->Minute;

+  SystemTime.wSecond        = Time->Second;

+  SystemTime.wMilliseconds  = (INT16) (Time->Nanosecond / 1000000);

+

+  Flag                      = gWinNt->SetLocalTime (&SystemTime);

+

+  if (!Flag) {

+    return EFI_DEVICE_ERROR;

+  } else {

+    return EFI_SUCCESS;

+  }

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtGetWakeupTime (

+  OUT BOOLEAN        *Enabled,

+  OUT BOOLEAN        *Pending,

+  OUT EFI_TIME       *Time

+  )

+/*++

+

+Routine Description:

+  Service routine for RealTimeClockInstance->GetWakeupTime

+

+Arguments:

+  This          - Indicates the protocol instance structure.

+

+  Enabled       - Indicates if the alarm is currently enabled or disabled.

+

+  Pending       - Indicates if the alarm signal is pending and requires

+                  acknowledgement.

+

+  Time          - The current alarm setting.

+

+Returns:

+

+  EFI_SUCEESS           - The operation completed successfully.

+                  

+  EFI_DEVICE_ERROR      - The operation could not be complete due to a device error.

+

+  EFI_UNSUPPORTED       - The operation is not supported on this platform.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSetWakeupTime (

+  IN BOOLEAN      Enable,

+  OUT EFI_TIME    *Time

+  )

+/*++

+

+Routine Description:

+  Service routine for RealTimeClockInstance->SetWakeupTime

+

+Arguments:

+

+  Enabled       - Enable or disable the wakeup alarm.

+

+  Time          - If enable is TRUE, the time to set the wakup alarm for.

+                  If enable is FALSE, then this parameter is optional, and

+                  may be NULL.

+

+Returns:

+

+  EFI_SUCEESS           - The operation completed successfully.

+                  

+  EFI_DEVICE_ERROR      - The operation could not be complete due to a device error.

+

+  EFI_INVALID_PARAMETER - A field in Time is out of range.

+

+  EFI_UNSUPPORTED       - The operation is not supported on this platform.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+EFIAPI

+InitializeRealTimeClock (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+/*++

+

+Routine Description:

+  Install Real Time Clock Protocol 

+

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+

+  EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table

+

+--*/

+// TODO:    ImageHandle - add argument and description to function comment

+// TODO:    SystemTable - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE  Handle;

+

+

+  SystemTable->RuntimeServices->GetTime       = WinNtGetTime;

+  SystemTable->RuntimeServices->SetTime       = WinNtSetTime;

+  SystemTable->RuntimeServices->GetWakeupTime = WinNtGetWakeupTime;

+  SystemTable->RuntimeServices->SetWakeupTime = WinNtSetWakeupTime;

+

+  Handle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Handle,

+                  &gEfiRealTimeClockArchProtocolGuid,

+                  NULL,

+                  NULL

+                  );

+  return Status;

+}

+

+EFI_STATUS

+RtcTimeFieldsValid (

+  IN EFI_TIME *Time

+  )

+/*++

+

+Routine Description:

+

+  Arguments:

+ 

+  Returns: 

+--*/

+// TODO:    Time - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  if (Time->Year < 1998 ||

+      Time->Year > 2099 ||

+      Time->Month < 1 ||

+      Time->Month > 12 ||

+      (!DayValid (Time)) ||

+      Time->Hour > 23 ||

+      Time->Minute > 59 ||

+      Time->Second > 59 ||

+      Time->Nanosecond > 999999999 ||

+      (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) ||

+      (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))

+      ) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+DayValid (

+  IN  EFI_TIME  *Time

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Time  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+

+  INTN  DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

+

+  if (Time->Day < 1 ||

+      Time->Day > DayOfMonth[Time->Month - 1] ||

+      (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))

+      ) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+BOOLEAN

+IsLeapYear (

+  IN EFI_TIME   *Time

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Time  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  if (Time->Year % 4 == 0) {

+    if (Time->Year % 100 == 0) {

+      if (Time->Year % 400 == 0) {

+        return TRUE;

+      } else {

+        return FALSE;

+      }

+    } else {

+      return TRUE;

+    }

+  } else {

+    return FALSE;

+  }

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.dxs b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.dxs
new file mode 100644
index 0000000..01f441c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  RealTimeClock.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.mbd
new file mode 100644
index 0000000..2eeac01
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>RealTimeClock</BaseName>

+    <Guid>27F05AF5-1644-4EF4-8944-48C4F75675A0</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>DxeWinNtLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.msa
new file mode 100644
index 0000000..5522fb4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.msa
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>RealTimeClock</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>27F05AF5-1644-4EF4-8944-48C4F75675A0</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for RealTimeClock module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>RealTimeClock.c</Filename>

+    <Filename>RealTimeClock.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">RealTimeClock</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeRealTimeClock</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/build.xml
new file mode 100644
index 0000000..b649e11
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/RealTimeClock/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="RealTimeClock"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Chipset\RealTimeClock"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="RealTimeClock">

+      <GenBuild baseName="RealTimeClock" mbdFilename="${MODULE_DIR}\RealTimeClock.mbd" msaFilename="${MODULE_DIR}\RealTimeClock.msa"/>

+   </target>

+   <target depends="RealTimeClock_clean" name="clean"/>

+   <target depends="RealTimeClock_cleanall" name="cleanall"/>

+   <target name="RealTimeClock_clean">

+      <OutputDirSetup baseName="RealTimeClock" mbdFilename="${MODULE_DIR}\RealTimeClock.mbd" msaFilename="${MODULE_DIR}\RealTimeClock.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\RealTimeClock_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\RealTimeClock_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="RealTimeClock_cleanall">

+      <OutputDirSetup baseName="RealTimeClock" mbdFilename="${MODULE_DIR}\RealTimeClock.mbd" msaFilename="${MODULE_DIR}\RealTimeClock.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\RealTimeClock_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\RealTimeClock_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**RealTimeClock*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.dxs b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.dxs
new file mode 100644
index 0000000..5dfb191a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Reset.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.mbd
new file mode 100644
index 0000000..817bc4e
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Reset</BaseName>

+    <Guid>BA929954-35B0-4dd3-90CD-9634BD7E1CF1</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeWinNtLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.msa
new file mode 100644
index 0000000..440d2b0
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/Reset.msa
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Reset</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>BA929954-35B0-4dd3-90CD-9634BD7E1CF1</Guid>

+    <Version>0</Version>

+    <Abstract>description of file contents</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Reset.c</Filename>

+    <Filename>Reset.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Reset</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeNtReset</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/build.xml
new file mode 100644
index 0000000..f924c6b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Reset"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Chipset\Reset"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Reset">

+      <GenBuild baseName="Reset" mbdFilename="${MODULE_DIR}\Reset.mbd" msaFilename="${MODULE_DIR}\Reset.msa"/>

+   </target>

+   <target depends="Reset_clean" name="clean"/>

+   <target depends="Reset_cleanall" name="cleanall"/>

+   <target name="Reset_clean">

+      <OutputDirSetup baseName="Reset" mbdFilename="${MODULE_DIR}\Reset.mbd" msaFilename="${MODULE_DIR}\Reset.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Reset_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Reset_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Reset_cleanall">

+      <OutputDirSetup baseName="Reset" mbdFilename="${MODULE_DIR}\Reset.mbd" msaFilename="${MODULE_DIR}\Reset.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Reset_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Reset_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Reset*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/reset.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/reset.c
new file mode 100644
index 0000000..d1b841d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Reset/reset.c
@@ -0,0 +1,121 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+ Reset.c

+

+Abstract:

+

+  Reset Architectural Protocol as defined in Tiano under NT Emulation

+

+--*/

+

+

+

+EFI_STATUS

+EFIAPI

+InitializeNtReset (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtResetSystem (

+  IN EFI_RESET_TYPE   ResetType,

+  IN EFI_STATUS       ResetStatus,

+  IN UINTN            DataSize,

+  IN CHAR16           *ResetData OPTIONAL

+  );

+

+

+EFI_STATUS

+EFIAPI

+InitializeNtReset (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+

+Arguments:

+

+  ImageHandle of the loaded driver

+  Pointer to the System Table

+

+Returns:

+

+  Status

+--*/

+// TODO:    SystemTable - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE  Handle;

+

+  SystemTable->RuntimeServices->ResetSystem = WinNtResetSystem;

+

+  Handle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Handle,

+                  &gEfiResetArchProtocolGuid,

+                  NULL,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtResetSystem (

+  IN EFI_RESET_TYPE   ResetType,

+  IN EFI_STATUS       ResetStatus,

+  IN UINTN            DataSize,

+  IN CHAR16           *ResetData OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ResetType   - TODO: add argument description

+  ResetStatus - TODO: add argument description

+  DataSize    - TODO: add argument description

+  ResetData   - TODO: add argument description

+

+Returns:

+

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  //

+  // BUGBUG Need to kill all console windows later

+  //

+  //

+  // Discard ResetType, always return 0 as exit code

+  //

+  gWinNt->ExitProcess (0);

+

+  //

+  // Should never go here

+  //

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.c
new file mode 100644
index 0000000..18779a6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.c
@@ -0,0 +1,597 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Timer.c

+

+Abstract:

+

+  NT Emulation Timer Architectural Protocol Driver as defined in DXE CIS

+

+  This Timer module uses an NT Thread to simulate the timer-tick driven

+  timer service.  In the future, the Thread creation should possibly be 

+  abstracted by the CPU architectural protocol

+

+--*/

+

+#include "Timer.h"

+

+//

+// Pointer to the CPU Architectural Protocol instance

+//

+EFI_CPU_ARCH_PROTOCOL   *mCpu;

+

+//

+// The Timer Architectural Protocol that this driver produces

+//

+EFI_TIMER_ARCH_PROTOCOL mTimer = {

+  WinNtTimerDriverRegisterHandler,

+  WinNtTimerDriverSetTimerPeriod,

+  WinNtTimerDriverGetTimerPeriod,

+  WinNtTimerDriverGenerateSoftInterrupt

+};

+

+//

+// Define a global that we can use to shut down the NT timer thread when

+// the timer is canceled.

+//

+BOOLEAN                 mCancelTimerThread = FALSE;

+

+//

+// The notification function to call on every timer interrupt

+//

+EFI_TIMER_NOTIFY        mTimerNotifyFunction = NULL;

+

+//

+// The current period of the timer interrupt

+//

+UINT64                  mTimerPeriod;

+

+//

+// The thread handle for this driver

+//

+HANDLE                  mNtMainThreadHandle;

+

+//

+// The timer value from the last timer interrupt

+//

+UINT32                  mNtLastTick;

+

+//

+// Critical section used to update varibles shared between the main thread and

+// the timer interrupt thread.

+//

+CRITICAL_SECTION        mNtCriticalSection;

+

+//

+// Worker Functions

+//

+UINT                    mMMTimerThreadID = 0;

+

+VOID

+CALLBACK

+MMTimerThread (

+  UINT  wTimerID,

+  UINT  msg,

+  DWORD dwUser,

+  DWORD dw1,

+  DWORD dw2

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  wTimerID  - TODO: add argument description

+  msg       - TODO: add argument description

+  dwUser    - TODO: add argument description

+  dw1       - TODO: add argument description

+  dw2       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+{

+  EFI_TPL           OriginalTPL;

+  UINT32            CurrentTick;

+  UINT32            Delta;

+  EFI_TIMER_NOTIFY  CallbackFunction;

+  BOOLEAN           InterruptState;

+

+  if (!mCancelTimerThread) {

+  

+    //

+    //  Suspend the main thread until we are done

+    //

+

+    gWinNt->SuspendThread (mNtMainThreadHandle);

+

+    //

+    // If the timer thread is being canceled, then bail immediately.

+    // We check again here because there's a small window of time from when

+    // this thread was kicked off and when we suspended the main thread above.

+    //

+    if (mCancelTimerThread) {

+      gWinNt->ResumeThread (mNtMainThreadHandle);

+      gWinNt->timeKillEvent (wTimerID);

+      mMMTimerThreadID = 0;

+      return ;

+    }

+

+    mCpu->GetInterruptState (mCpu, &InterruptState);

+    while (!InterruptState) {

+      //

+      //  Resume the main thread

+      //

+      gWinNt->ResumeThread (mNtMainThreadHandle);

+

+      //

+      //  Wait for interrupts to be enabled.

+      //

+      mCpu->GetInterruptState (mCpu, &InterruptState);

+      while (!InterruptState) {

+        gWinNt->Sleep (0);

+        mCpu->GetInterruptState (mCpu, &InterruptState);

+      }

+       

+      //

+      //  Suspend the main thread until we are done

+      //

+      gWinNt->SuspendThread (mNtMainThreadHandle);

+      mCpu->GetInterruptState (mCpu, &InterruptState);

+    }

+

+    //

+    //  Get the current system tick

+    //

+    CurrentTick = gWinNt->GetTickCount ();

+    Delta       = CurrentTick - mNtLastTick;

+    mNtLastTick = CurrentTick;

+

+    //

+    //  If delay was more then 1 second, ignore it (probably debugging case)

+    //

+    if (Delta < 1000) {

+

+      OriginalTPL = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

+

+      //

+      //  Inform the firmware of an "timer interrupt".  The time

+      //  expired since the last call is 10,000 times the number

+      //  of ms.  (or 100ns units)

+      //

+      gWinNt->EnterCriticalSection (&mNtCriticalSection);

+      CallbackFunction = mTimerNotifyFunction;

+      gWinNt->LeaveCriticalSection (&mNtCriticalSection);

+

+      //

+      // Only invoke the callback function if a Non-NULL handler has been

+      // registered. Assume all other handlers are legal.

+      //

+      if (CallbackFunction != NULL) {

+        CallbackFunction ((UINT64) (Delta * 10000));

+      }

+

+      gBS->RestoreTPL (OriginalTPL);

+

+    }

+

+    //

+    //  Resume the main thread

+    //

+    gWinNt->ResumeThread (mNtMainThreadHandle);

+  } else {

+    gWinNt->timeKillEvent (wTimerID);

+    mMMTimerThreadID = 0;

+  }

+

+}

+

+UINT

+CreateNtTimer (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+   It is used to emulate a platform 

+  timer-driver interrupt handler.  

+

+Returns:

+

+  Timer ID

+

+--*/

+// TODO: function comment is missing 'Arguments:'

+{

+  UINT32  SleepCount;

+

+  //

+  //  Set our thread priority higher than the "main" thread.

+  //

+  gWinNt->SetThreadPriority (

+            gWinNt->GetCurrentThread (),

+            THREAD_PRIORITY_HIGHEST

+            );

+

+  //

+  //  Calc the appropriate interval

+  //

+  gWinNt->EnterCriticalSection (&mNtCriticalSection);

+  SleepCount = (UINT32) (mTimerPeriod + 5000) / 10000;

+  gWinNt->LeaveCriticalSection (&mNtCriticalSection);

+

+  return gWinNt->timeSetEvent (

+                  SleepCount,

+                  0,

+                  MMTimerThread,

+                  (DWORD_PTR) NULL,

+                  TIME_PERIODIC | TIME_KILL_SYNCHRONOUS | TIME_CALLBACK_FUNCTION

+                  );

+

+}

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL           *This,

+  IN EFI_TIMER_NOTIFY                  NotifyFunction

+  )

+/*++

+

+Routine Description:

+

+  This function registers the handler NotifyFunction so it is called every time 

+  the timer interrupt fires.  It also passes the amount of time since the last 

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the 

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is 

+  returned.  If the CPU does not support registering a timer interrupt handler, 

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler 

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.  

+  If an attempt is made to unregister a handler when a handler is not registered, 

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to 

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR 

+  is returned.

+

+Arguments:

+

+  This           - The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  NotifyFunction - The function to call when a timer interrupt fires.  This 

+                   function executes at TPL_HIGH_LEVEL.  The DXE Core will 

+                   register a handler for the timer interrupt, so it can know 

+                   how much time has passed.  This information is used to 

+                   signal timer based events.  NULL will unregister the handler.

+

+Returns: 

+

+  EFI_SUCCESS           - The timer handler was registered.

+

+  EFI_UNSUPPORTED       - The platform does not support timer interrupts.

+

+  EFI_ALREADY_STARTED   - NotifyFunction is not NULL, and a handler is already 

+                          registered.

+

+  EFI_INVALID_PARAMETER - NotifyFunction is NULL, and a handler was not 

+                          previously registered.

+

+  EFI_DEVICE_ERROR      - The timer handler could not be registered.

+

+--*/

+{

+  //

+  // Check for invalid parameters

+  //

+  if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  //

+  // Use Critical Section to update the notification function that is

+  // used from the timer interrupt thread.

+  //

+  gWinNt->EnterCriticalSection (&mNtCriticalSection);

+

+  mTimerNotifyFunction = NotifyFunction;

+

+  gWinNt->LeaveCriticalSection (&mNtCriticalSection);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+/*++

+

+Routine Description:

+

+  This function adjusts the period of timer interrupts to the value specified 

+  by TimerPeriod.  If the timer period is updated, then the selected timer 

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If 

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.  

+  If an error occurs while attempting to update the timer period, then the 

+  timer hardware will be put back in its state prior to this call, and 

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt 

+  is disabled.  This is not the same as disabling the CPU's interrupts.  

+  Instead, it must either turn off the timer hardware, or it must adjust the 

+  interrupt controller so that a CPU interrupt is not generated when the timer 

+  interrupt fires. 

+

+Arguments:

+

+  This        - The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  TimerPeriod - The rate to program the timer interrupt in 100 nS units.  If 

+                the timer hardware is not programmable, then EFI_UNSUPPORTED is 

+                returned.  If the timer is programmable, then the timer period 

+                will be rounded up to the nearest timer period that is supported 

+                by the timer hardware.  If TimerPeriod is set to 0, then the 

+                timer interrupts will be disabled.

+

+Returns: 

+

+  EFI_SUCCESS      - The timer period was changed.

+

+  EFI_UNSUPPORTED  - The platform cannot change the period of the timer interrupt.

+

+  EFI_DEVICE_ERROR - The timer period could not be changed due to a device error.

+

+--*/

+{

+

+  //

+  // If TimerPeriod is 0, then the timer thread should be canceled

+  //

+  if (TimerPeriod == 0) {

+    //

+    // Cancel the timer thread

+    //

+    gWinNt->EnterCriticalSection (&mNtCriticalSection);

+

+    mCancelTimerThread = TRUE;

+

+    gWinNt->LeaveCriticalSection (&mNtCriticalSection);

+

+    //

+    // Wait for the timer thread to exit

+    //

+

+    if (mMMTimerThreadID) {

+      gWinNt->timeKillEvent (mMMTimerThreadID);

+    }

+

+    mMMTimerThreadID = 0;

+

+    //

+    // Update the timer period

+    //

+    gWinNt->EnterCriticalSection (&mNtCriticalSection);

+

+    mTimerPeriod = TimerPeriod;

+

+    gWinNt->LeaveCriticalSection (&mNtCriticalSection);

+

+    //

+    // NULL out the thread handle so it will be re-created if the timer is enabled again

+    //

+

+  } else if ((TimerPeriod > TIMER_MINIMUM_VALUE) && (TimerPeriod < TIMER_MAXIMUM_VALUE)) {

+    //

+    // If the TimerPeriod is valid, then create and/or adjust the period of the timer thread

+    //

+    gWinNt->EnterCriticalSection (&mNtCriticalSection);

+

+    mTimerPeriod        = TimerPeriod;

+

+    mCancelTimerThread  = FALSE;

+

+    gWinNt->LeaveCriticalSection (&mNtCriticalSection);

+

+    //

+    //  Get the starting tick location if we are just starting the timer thread

+    //

+    mNtLastTick = gWinNt->GetTickCount ();

+

+    if (mMMTimerThreadID) {

+      gWinNt->timeKillEvent (mMMTimerThreadID);

+    }

+

+    mMMTimerThreadID  = 0;

+

+    mMMTimerThreadID  = CreateNtTimer ();

+

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL            *This,

+  OUT UINT64                            *TimerPeriod

+  )

+/*++

+

+Routine Description:

+

+  This function retrieves the period of timer interrupts in 100 ns units, 

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod 

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is 

+  returned, then the timer is currently disabled.

+

+Arguments:

+

+  This        - The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  TimerPeriod - A pointer to the timer period to retrieve in 100 ns units.  If 

+                0 is returned, then the timer is currently disabled.

+

+Returns: 

+

+  EFI_SUCCESS           - The timer period was returned in TimerPeriod.

+

+  EFI_INVALID_PARAMETER - TimerPeriod is NULL.

+

+--*/

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = mTimerPeriod;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  This function generates a soft timer interrupt. If the platform does not support soft 

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. 

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() 

+  service, then a soft timer interrupt will be generated. If the timer interrupt is 

+  enabled when this service is called, then the registered handler will be invoked. The 

+  registered handler should not be able to distinguish a hardware-generated timer 

+  interrupt from a software-generated timer interrupt.

+

+Arguments:

+

+  This  -  The EFI_TIMER_ARCH_PROTOCOL instance.

+

+Returns: 

+

+  EFI_SUCCESS       - The soft timer interrupt was generated.

+

+  EFI_UNSUPPORTEDT  - The platform does not support the generation of soft timer interrupts.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initialize the Timer Architectural Protocol driver

+

+Arguments:

+

+  ImageHandle - ImageHandle of the loaded driver

+

+  SystemTable - Pointer to the System Table

+

+Returns:

+

+  EFI_SUCCESS           - Timer Architectural Protocol created

+

+  EFI_OUT_OF_RESOURCES  - Not enough resources available to initialize driver.

+  

+  EFI_DEVICE_ERROR      - A device error occured attempting to initialize the driver.

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       Result;

+  EFI_HANDLE  Handle;

+

+  //

+  // Make sure the Timer Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);

+

+  //

+  // Get the CPU Architectural Protocol instance

+  //

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, &mCpu);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  //  Get our handle so the timer tick thread can suspend

+  //

+  Result = gWinNt->DuplicateHandle (

+                    gWinNt->GetCurrentProcess (),

+                    gWinNt->GetCurrentThread (),

+                    gWinNt->GetCurrentProcess (),

+                    &mNtMainThreadHandle,

+                    0,

+                    FALSE,

+                    DUPLICATE_SAME_ACCESS

+                    );

+  if (Result == 0) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Initialize Critical Section used to update variables shared between the main

+  // thread and the timer interrupt thread.

+  //

+  gWinNt->InitializeCriticalSection (&mNtCriticalSection);

+

+  //

+  // Start the timer thread at the default timer period

+  //

+  Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);

+  if (EFI_ERROR (Status)) {

+    gWinNt->DeleteCriticalSection (&mNtCriticalSection);

+    return Status;

+  }

+

+  //

+  // Install the Timer Architectural Protocol onto a new handle

+  //

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  &gEfiTimerArchProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &mTimer

+                  );

+  if (EFI_ERROR (Status)) {

+    //

+    // Cancel the timer

+    //

+    mTimer.SetTimerPeriod (&mTimer, 0);

+    gWinNt->DeleteCriticalSection (&mNtCriticalSection);

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.dxs b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.dxs
new file mode 100644
index 0000000..6e66383
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Timer.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/ 

+

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_CPU_ARCH_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.h
new file mode 100644
index 0000000..218ece6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.h
@@ -0,0 +1,162 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Timer.h

+

+Abstract:

+

+  NT Emulation Architectural Protocol Driver as defined in Tiano.

+  This Timer module uses an NT Thread to simulate the timer-tick driven

+  timer service.

+

+--*/

+

+#ifndef _TIMER_H_

+#define _TIMER_H_

+

+

+

+

+//

+// Legal timer value range in 100 ns units

+//

+#define TIMER_MINIMUM_VALUE 0

+#define TIMER_MAXIMUM_VALUE (0x100000000 - 1)

+

+//

+// Default timer value in 100 ns units (10 ms)

+//

+#define DEFAULT_TIMER_TICK_DURATION 100000

+

+//

+// Function Prototypes

+//

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageHandle - TODO: add argument description

+  SystemTable - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This            - TODO: add argument description

+  NotifyFunction  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  TimerPeriod - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This        - TODO: add argument description

+  TimerPeriod - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+WinNtTimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  This  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.mbd
new file mode 100644
index 0000000..3b8602d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Timer</BaseName>

+    <Guid>C3811036-710B-4E39-8CF1-0AF9BE3A8198</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeHobLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>HiiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>DxeWinNtLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.msa
new file mode 100644
index 0000000..c4e2325
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/Timer.msa
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Timer</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>C3811036-710B-4E39-8CF1-0AF9BE3A8198</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Timer module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Timer.h</Filename>

+    <Filename>Timer.c</Filename>

+    <Filename>Timer.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Timer</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">Cpu</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>WinNtTimerDriverInitialize</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/build.xml
new file mode 100644
index 0000000..fac1fa40
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Chipset/Timer/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Timer"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Chipset\Timer"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Timer">

+      <GenBuild baseName="Timer" mbdFilename="${MODULE_DIR}\Timer.mbd" msaFilename="${MODULE_DIR}\Timer.msa"/>

+   </target>

+   <target depends="Timer_clean" name="clean"/>

+   <target depends="Timer_cleanall" name="cleanall"/>

+   <target name="Timer_clean">

+      <OutputDirSetup baseName="Timer" mbdFilename="${MODULE_DIR}\Timer.mbd" msaFilename="${MODULE_DIR}\Timer.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Timer_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Timer_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Timer_cleanall">

+      <OutputDirSetup baseName="Timer" mbdFilename="${MODULE_DIR}\Timer.mbd" msaFilename="${MODULE_DIR}\Timer.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Timer_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Timer_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Timer*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.c
new file mode 100644
index 0000000..8633327
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.c
@@ -0,0 +1,736 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Cpu.c

+

+Abstract:

+

+  NT Emulation Architectural Protocol Driver as defined in Tiano.

+  This CPU module abstracts the interrupt subsystem of a platform and

+  the CPU-specific setjump/long pair.  Other services are not implemented

+  in this driver.

+

+--*/

+

+#include "CpuDriver.h"

+

+//

+// This is the VFR compiler generated header file which defines the

+// string identifiers.

+//

+#include STRING_DEFINES_FILE

+

+#define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100

+

+EFI_STATUS

+EFIAPI

+InitializeCpu (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+VOID

+EFIAPI

+WinNtIoProtocolNotifyFunction (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  );

+

+typedef union {

+  EFI_CPU_DATA_RECORD *DataRecord;

+  UINT8               *Raw;

+} EFI_CPU_DATA_RECORD_BUFFER;

+

+EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader = {

+  EFI_PROCESSOR_SUBCLASS_VERSION,       // Version

+  sizeof (EFI_SUBCLASS_TYPE1_HEADER),   // Header Size

+  0,                                    // Instance, Initialize later

+  EFI_SUBCLASS_INSTANCE_NON_APPLICABLE, // SubInstance

+  0                                     // RecordType, Initialize later

+};

+

+//

+// Service routines for the driver

+//

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtFlushCpuDataCache (

+  IN EFI_CPU_ARCH_PROTOCOL  *This,

+  IN EFI_PHYSICAL_ADDRESS   Start,

+  IN UINT64                 Length,

+  IN EFI_CPU_FLUSH_TYPE     FlushType

+  )

+/*++

+

+Routine Description:

+

+  This routine would provide support for flushing the CPU data cache.

+  In the case of NT emulation environment, this flushing is not necessary and

+  is thus not implemented.

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+  Start adddress in memory to flush

+  Length of memory to flush

+  Flush type

+

+Returns:

+

+  Status

+    EFI_SUCCESS

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    FlushType - add argument and description to function comment

+// TODO:    EFI_UNSUPPORTED - add return value to function comment

+{

+  if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {

+    //

+    // Only WB flush is supported. We actually need do nothing on NT emulator

+    // environment. Classify this to follow EFI spec

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // Other flush types are not supported by NT emulator

+  //

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtEnableInterrupt (

+  IN EFI_CPU_ARCH_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  This routine provides support for emulation of the interrupt enable of the

+  the system.  For our purposes, CPU enable is just a BOOLEAN that the Timer 

+  Architectural Protocol observes in order to defer behaviour while in its

+  emulated interrupt, or timer tick.

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+

+Returns:

+

+  Status

+    EFI_SUCCESS

+

+--*/

+// TODO:    This - add argument and description to function comment

+{

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+

+  Private                 = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);

+  Private->InterruptState = TRUE;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtDisableInterrupt (

+  IN EFI_CPU_ARCH_PROTOCOL  *This

+  )

+/*++

+

+Routine Description:

+

+  This routine provides support for emulation of the interrupt disable of the

+  the system.  For our purposes, CPU enable is just a BOOLEAN that the Timer 

+  Architectural Protocol observes in order to defer behaviour while in its

+  emulated interrupt, or timer tick.

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+

+Returns:

+

+  Status

+    EFI_SUCCESS

+

+--*/

+// TODO:    This - add argument and description to function comment

+{

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+

+  Private                 = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);

+  Private->InterruptState = FALSE;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtGetInterruptState (

+  IN EFI_CPU_ARCH_PROTOCOL  *This,

+  OUT BOOLEAN               *State

+  )

+/*++

+

+Routine Description:

+

+  This routine provides support for emulation of the interrupt disable of the

+  the system.  For our purposes, CPU enable is just a BOOLEAN that the Timer 

+  Architectural Protocol observes in order to defer behaviour while in its

+  emulated interrupt, or timer tick.

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+

+Returns:

+

+  Status

+    EFI_SUCCESS

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    State - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+

+  if (State == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);

+  *State  = Private->InterruptState;

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtInit (

+  IN EFI_CPU_ARCH_PROTOCOL  *This,

+  IN EFI_CPU_INIT_TYPE      InitType

+  )

+/*++

+

+Routine Description:

+

+  This routine would support generation of a CPU INIT.  At 

+  present, this code does not provide emulation.  

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+  INIT Type

+

+Returns:

+

+  Status

+    EFI_UNSUPPORTED - not yet implemented

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    InitType - add argument and description to function comment

+{

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+

+  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtRegisterInterruptHandler (

+  IN EFI_CPU_ARCH_PROTOCOL      *This,

+  IN EFI_EXCEPTION_TYPE         InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler

+  )

+/*++

+

+Routine Description:

+

+  This routine would support registration of an interrupt handler.  At 

+  present, this code does not provide emulation.  

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+  Pointer to interrupt handlers

+  Interrupt type

+

+Returns:

+

+  Status

+    EFI_UNSUPPORTED - not yet implemented

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    InterruptType - add argument and description to function comment

+// TODO:    InterruptHandler - add argument and description to function comment

+{

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+

+  //

+  // Do parameter checking for EFI spec conformance

+  //

+  if (InterruptType < 0 || InterruptType > 0xff) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Do nothing for Nt32 emulation

+  //

+  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtGetTimerValue (

+  IN  EFI_CPU_ARCH_PROTOCOL *This,

+  IN  UINT32                TimerIndex,

+  OUT UINT64                *TimerValue,

+  OUT UINT64                *TimerPeriod OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  This routine would support querying of an on-CPU timer.  At present, 

+  this code does not provide timer emulation.  

+

+Arguments:

+

+  This        - Pointer to CPU Architectural Protocol interface

+  TimerIndex  - Index of given CPU timer

+  TimerValue  - Output of the timer

+  TimerPeriod - Output of the timer period

+

+Returns:

+

+  EFI_UNSUPPORTED       - not yet implemented

+  EFI_INVALID_PARAMETER - TimeValue is NULL

+

+--*/

+{

+  if (TimerValue == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // No timer supported

+  //

+  return EFI_UNSUPPORTED;

+}

+

+STATIC

+EFI_STATUS

+EFIAPI

+WinNtSetMemoryAttributes (

+  IN EFI_CPU_ARCH_PROTOCOL  *This,

+  IN EFI_PHYSICAL_ADDRESS   BaseAddress,

+  IN UINT64                 Length,

+  IN UINT64                 Attributes

+  )

+/*++

+

+Routine Description:

+

+  This routine would support querying of an on-CPU timer.  At present, 

+  this code does not provide timer emulation.  

+

+Arguments:

+

+  Pointer to CPU Architectural Protocol interface

+  Start address of memory region

+  The size in bytes of the memory region

+  The bit mask of attributes to set for the memory region

+

+Returns:

+

+  Status

+    EFI_UNSUPPORTED - not yet implemented

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    BaseAddress - add argument and description to function comment

+// TODO:    Length - add argument and description to function comment

+// TODO:    Attributes - add argument and description to function comment

+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+{

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+

+  //

+  // Check for invalid parameter for Spec conformance

+  //

+  if (Length == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Do nothing for Nt32 emulation

+  //

+  Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);

+  return EFI_UNSUPPORTED;

+}

+

+

+EFI_STATUS

+EFIAPI

+InitializeCpu (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+  Initialize the state information for the CPU Architectural Protocol

+

+Arguments:

+

+  ImageHandle of the loaded driver

+  Pointer to the System Table

+

+Returns:

+

+  Status

+

+  EFI_SUCCESS           - protocol instance can be published 

+  EFI_OUT_OF_RESOURCES  - cannot allocate protocol data structure

+  EFI_DEVICE_ERROR      - cannot create the thread

+

+--*/

+// TODO:    SystemTable - add argument and description to function comment

+{

+  EFI_STATUS                Status;

+  EFI_EVENT                 Event;

+  CPU_ARCH_PROTOCOL_PRIVATE *Private;

+  VOID                      *Registration;

+

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (CPU_ARCH_PROTOCOL_PRIVATE),

+                  &Private

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  Private->Signature                    = CPU_ARCH_PROT_PRIVATE_SIGNATURE;

+  Private->Cpu.FlushDataCache           = WinNtFlushCpuDataCache;

+  Private->Cpu.EnableInterrupt          = WinNtEnableInterrupt;

+  Private->Cpu.DisableInterrupt         = WinNtDisableInterrupt;

+  Private->Cpu.GetInterruptState        = WinNtGetInterruptState;

+  Private->Cpu.Init                     = WinNtInit;

+  Private->Cpu.RegisterInterruptHandler = WinNtRegisterInterruptHandler;

+  Private->Cpu.GetTimerValue            = WinNtGetTimerValue;

+  Private->Cpu.SetMemoryAttributes      = WinNtSetMemoryAttributes;

+

+  Private->Cpu.NumberOfTimers           = 0;

+  Private->Cpu.DmaBufferAlignment       = 4;

+

+  Private->InterruptState               = TRUE;

+

+  Private->CpuIo.Mem.Read   = CpuMemoryServiceRead;

+  Private->CpuIo.Mem.Write  = CpuMemoryServiceWrite;

+  Private->CpuIo.Io.Read    = CpuIoServiceRead;

+  Private->CpuIo.Io.Write   = CpuIoServiceWrite;

+

+

+  Private->Handle                       = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Private->Handle,

+                  &gEfiCpuArchProtocolGuid,   &Private->Cpu,

+                  &gEfiCpuIoProtocolGuid,     &Private->CpuIo,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Install notify function to store processor data to HII database and data hub.

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  EFI_TPL_CALLBACK,

+                  WinNtIoProtocolNotifyFunction,

+                  ImageHandle,

+                  &Event

+                  );

+  ASSERT (!EFI_ERROR (Status));

+

+  Status = gBS->RegisterProtocolNotify (

+                  &gEfiWinNtIoProtocolGuid,

+                  Event,

+                  &Registration

+                  );

+  ASSERT (!EFI_ERROR (Status));

+

+  //

+  // Should be at EFI_D_INFO, but lets us now things are running

+  //

+  DEBUG ((EFI_D_ERROR, "CPU Architectural Protocol Loaded\n"));

+

+

+  

+  return Status;

+}

+

+UINTN

+Atoi (

+  CHAR16  *String

+  )

+/*++

+

+Routine Description:

+  Convert a unicode string to a UINTN

+

+Arguments:

+  String - Unicode string.

+

+Returns: 

+  UINTN of the number represented by String.  

+

+--*/

+{

+  UINTN   Number;

+  CHAR16  *Str;

+

+  //

+  // skip preceeding white space

+  //

+  Str = String;

+  while ((*Str) && (*Str == ' ' || *Str == '"')) {

+    Str++;

+  }

+  //

+  // Convert ot a Number

+  //

+  Number = 0;

+  while (*Str != '\0') {

+    if ((*Str >= '0') && (*Str <= '9')) {

+      Number = (Number * 10) +*Str - '0';

+    } else {

+      break;

+    }

+

+    Str++;

+  }

+

+  return Number;

+}

+

+VOID

+EFIAPI

+WinNtIoProtocolNotifyFunction (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  )

+/*++

+

+Routine Description:

+  This function will log processor version and frequency data to data hub.

+

+Arguments:

+  Event        - Event whose notification function is being invoked.

+  Context      - Pointer to the notification function's context.

+

+Returns:

+  None.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_CPU_DATA_RECORD_BUFFER  RecordBuffer;

+  EFI_DATA_RECORD_HEADER      *Record;

+  EFI_SUBCLASS_TYPE1_HEADER   *DataHeader;

+  UINT32                      HeaderSize;

+  UINT32                      TotalSize;

+  UINTN                       HandleCount;

+  UINTN                       HandleIndex;

+  UINT64                      MonotonicCount;

+  BOOLEAN                     RecordFound;

+  EFI_HANDLE                  *HandleBuffer;

+  EFI_WIN_NT_IO_PROTOCOL      *WinNtIo;

+  EFI_DATA_HUB_PROTOCOL       *DataHub;

+  EFI_HII_PROTOCOL            *Hii;

+  EFI_HII_HANDLE              StringHandle;

+  EFI_HII_PACKAGES            *PackageList;

+  STRING_REF                  Token;

+

+  DataHub         = NULL;

+  Token           = 0;

+  MonotonicCount  = 0;

+  RecordFound     = FALSE;

+

+  //

+  // Retrieve the list of all handles from the handle database

+  //

+  Status = gBS->LocateHandleBuffer (

+                  AllHandles,

+                  &gEfiWinNtIoProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+  //

+  // Locate HII protocol

+  //

+  Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+  //

+  // Locate DataHub protocol.

+  //

+  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+  //

+  // Initialize data record header

+  //

+  mCpuDataRecordHeader.Instance = 1;

+  HeaderSize                    = sizeof (EFI_SUBCLASS_TYPE1_HEADER);

+

+  RecordBuffer.Raw              = AllocatePool (HeaderSize + EFI_CPU_DATA_MAXIMUM_LENGTH);

+  if (RecordBuffer.Raw == NULL) {

+    return ;

+  }

+

+  CopyMem (RecordBuffer.Raw, &mCpuDataRecordHeader, HeaderSize);

+

+  //

+  // Search the Handle array to find the CPU model and speed information

+  //

+  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {

+    Status = gBS->OpenProtocol (

+                    HandleBuffer[HandleIndex],

+                    &gEfiWinNtIoProtocolGuid,

+                    &WinNtIo,

+                    Context,

+                    NULL,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&

+        CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtCPUModelGuid)

+          ) {

+      //

+      // Check if this record has been stored in data hub

+      //

+      do {

+        Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);

+        if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {

+          DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);

+          if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&

+              (DataHeader->RecordType == ProcessorVersionRecordType)

+              ) {

+            RecordFound = TRUE;

+          }

+        }

+      } while (MonotonicCount != 0);

+

+      if (RecordFound) {

+        RecordFound = FALSE;

+        continue;

+      }

+      //

+      // Initialize strings to HII database

+      //

+      PackageList = PreparePackages (1, &gEfiProcessorProducerGuid, STRING_ARRAY_NAME);

+

+      Status      = Hii->NewPack (Hii, PackageList, &StringHandle);

+      ASSERT (!EFI_ERROR (Status));

+

+      gBS->FreePool (PackageList);

+

+      //

+      // Store processor version data record to data hub

+      //

+      Status = Hii->NewString (Hii, NULL, StringHandle, &Token, WinNtIo->EnvString);

+      ASSERT (!EFI_ERROR (Status));

+

+      RecordBuffer.DataRecord->DataRecordHeader.RecordType      = ProcessorVersionRecordType;

+      RecordBuffer.DataRecord->VariableRecord.ProcessorVersion  = Token;

+      TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_VERSION_DATA);

+

+      Status = DataHub->LogData (

+                          DataHub,

+                          &gEfiProcessorSubClassGuid,

+                          &gEfiProcessorProducerGuid,

+                          EFI_DATA_RECORD_CLASS_DATA,

+                          RecordBuffer.Raw,

+                          TotalSize

+                          );

+    }

+

+    if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&

+        CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtCPUSpeedGuid)

+          ) {

+      //

+      // Check if this record has been stored in data hub

+      //

+      do {

+        Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);

+        if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {

+          DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);

+          if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&

+              (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)

+              ) {

+            RecordFound = TRUE;

+          }

+        }

+      } while (MonotonicCount != 0);

+

+      if (RecordFound) {

+        RecordFound = FALSE;

+        continue;

+      }

+      //

+      // Store CPU frequency data record to data hub

+      //

+      RecordBuffer.DataRecord->DataRecordHeader.RecordType                    = ProcessorCoreFrequencyRecordType;

+      RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Value    = (UINT16) Atoi (WinNtIo->EnvString);

+      RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Exponent = 6;

+      TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA);

+

+      Status = DataHub->LogData (

+                          DataHub,

+                          &gEfiProcessorSubClassGuid,

+                          &gEfiProcessorProducerGuid,

+                          EFI_DATA_RECORD_CLASS_DATA,

+                          RecordBuffer.Raw,

+                          TotalSize

+                          );

+

+      gBS->FreePool (RecordBuffer.Raw);

+    }

+

+    gBS->CloseProtocol (

+          HandleBuffer[HandleIndex],

+          &gEfiWinNtIoProtocolGuid,

+          Context,

+          NULL

+          );

+  }

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.dxs b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.dxs
new file mode 100644
index 0000000..4f87af4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Cpu.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/ 

+

+#include <AutoGen.h> 

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  EFI_DATA_HUB_PROTOCOL_GUID  AND

+  EFI_HII_PROTOCOL_GUID

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.mbd
new file mode 100644
index 0000000..f2d25fe
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Cpu</BaseName>

+    <Guid>ee993080-5197-4d4e-b63c-f1f7413e33ce</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-23 16:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>UefiLib</Library>

+    <Library>HiiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+    <Option>C_STD_FLAGS = ${C_STD_FLAGS} /DSTRING_ARRAY_NAME=${BASE_NAME}Strings</Option>

+    <Option>C_STD_FLAGS = ${C_STD_FLAGS} /DSTRING_DEFINES_FILE=\"${BASE_NAME}StrDefs.h\"</Option>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.msa
new file mode 100644
index 0000000..ce20d91
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Cpu.msa
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Cpu</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>ee993080-5197-4d4e-b63c-f1f7413e33ce</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Cpu module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-23 16:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Strings.uni</Filename>

+    <Filename>CpuDriver.h</Filename>

+    <Filename>Cpu.c</Filename>

+    <Filename>CpuIo.c</Filename>

+    <Filename>Cpu.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">Cpu</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">CpuIo</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">Hii</Protocol>

+    <Protocol Usage="SOMETIMES_CONSUMED">DataHub</Protocol>

+    <ProtocolNotify Usage="SOMETIMES_CONSUMED">WinNtIo</ProtocolNotify>

+  </Protocols>

+  <DataHubs>

+    <DataHubRecord Usage="SOMETIMES_PRODUCED">ProcessorVersion</DataHubRecord>

+    <DataHubRecord Usage="SOMETIMES_PRODUCED">ProcessorCoreFrequency</DataHubRecord>

+  </DataHubs>

+  <Guids>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>ProcessorProducer</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>ProcessorSubClass</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>WinNtCPUModel</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="SOMETIMES_CONSUMED">

+      <C_Name>WinNtCPUSpeed</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeCpu</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/CpuDriver.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/CpuDriver.h
new file mode 100644
index 0000000..e5b952f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/CpuDriver.h
@@ -0,0 +1,97 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CpuDriver.h

+

+Abstract:

+

+  NT Emulation Architectural Protocol Driver as defined in Tiano.

+

+--*/

+

+#ifndef _CPU_ARCHITECTURAL_PROTOCOL_DRIVER_H_

+#define _CPU_ARCHITECTURAL_PROTOCOL_DRIVER_H_

+

+

+

+extern UINT8  STRING_ARRAY_NAME[];

+

+//

+// Internal Data Structures

+//

+#define CPU_ARCH_PROT_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('c', 'a', 'p', 'd')

+

+typedef struct {

+  UINTN                 Signature;

+  EFI_HANDLE            Handle;

+

+  EFI_CPU_ARCH_PROTOCOL Cpu;

+  EFI_CPU_IO_PROTOCOL   CpuIo;

+

+  //

+  // Local Data for CPU interface goes here

+  //

+  CRITICAL_SECTION      NtCriticalSection;

+  BOOLEAN               InterruptState;

+

+} CPU_ARCH_PROTOCOL_PRIVATE;

+

+#define CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      CPU_ARCH_PROTOCOL_PRIVATE, \

+      Cpu, \

+      CPU_ARCH_PROT_PRIVATE_SIGNATURE \

+      )

+

+EFI_STATUS

+EFIAPI

+CpuMemoryServiceRead (

+  IN  EFI_CPU_IO_PROTOCOL               *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *Buffer

+  );

+

+EFI_STATUS

+EFIAPI

+CpuMemoryServiceWrite (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *Buffer

+  );

+

+EFI_STATUS

+EFIAPI

+CpuIoServiceRead (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            UserAddress,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *UserBuffer

+  );

+

+EFI_STATUS

+EFIAPI

+CpuIoServiceWrite (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            UserAddress,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *UserBuffer

+  );

+

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/CpuIo.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/CpuIo.c
new file mode 100644
index 0000000..4aaa431
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/CpuIo.c
@@ -0,0 +1,335 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CpuIo.c

+

+Abstract:

+

+  This is the code that publishes the CPU I/O Protocol.

+  The intent herein is to have a single I/O service that can load

+  as early as possible, extend into runtime, and be layered upon by 

+  the implementations of architectural protocols and the PCI Root

+  Bridge I/O Protocol.

+

+--*/

+

+#include <CpuDriver.h>

+

+#define IA32_MAX_IO_ADDRESS   0xFFFF

+#define IA32_MAX_MEM_ADDRESS  0xFFFFFFFF

+

+EFI_CPU_IO_PROTOCOL mCpuIoProtocol;

+

+EFI_STATUS

+CpuIoCheckAddressRange (

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  VOID                              *Buffer,

+  IN  UINT64                            Limit

+  );

+

+EFI_STATUS

+EFIAPI

+CpuMemoryServiceRead (

+  IN  EFI_CPU_IO_PROTOCOL               *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Perform the Memory Access Read service for the CPU I/O Protocol

+

+Arguments:

+

+  Pointer to an instance of the CPU I/O Protocol

+  Width of the Memory Access

+  Address of the Memory access

+  Count of the number of accesses to perform

+  Pointer to the buffer to read or write from memory

+

+Returns:

+

+  Status

+

+  EFI_SUCCESS             - The data was read from or written to the EFI 

+                            System.

+  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.

+  EFI_INVALID_PARAMETER   - Buffer is NULL.

+  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.

+  EFI_UNSUPPORTED         - The address range specified by Address, Width, 

+                            and Count is not valid for this EFI System.

+

+--*/

+// TODO:    This - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+

+  if (!Buffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Do nothing for Nt32 version

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CpuMemoryServiceWrite (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Perform the Memory Access Read service for the CPU I/O Protocol

+

+Arguments:

+

+  Pointer to an instance of the CPU I/O Protocol

+  Width of the Memory Access

+  Address of the Memory access

+  Count of the number of accesses to perform

+  Pointer to the buffer to read or write from memory

+

+Returns:

+

+  Status

+

+  EFI_SUCCESS             - The data was read from or written to the EFI System.

+  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.

+  EFI_INVALID_PARAMETER   - Buffer is NULL.

+  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.

+  EFI_UNSUPPORTED         - The address range specified by Address, Width, and 

+                            Count is not valid for this EFI System.

+

+--*/

+// TODO:    This - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+

+  if (!Buffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Do nothing for Nt32 version

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CpuIoServiceRead (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            UserAddress,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *UserBuffer

+  )

+/*++

+

+Routine Description:

+  

+  This is the service that implements the I/O read

+

+Arguments:

+

+  Pointer to an instance of the CPU I/O Protocol

+  Width of the Memory Access

+  Address of the I/O access

+  Count of the number of accesses to perform

+  Pointer to the buffer to read or write from I/O space

+

+Returns:

+

+  Status

+  EFI_SUCCESS             - The data was read from or written to the EFI System.

+  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.

+  EFI_INVALID_PARAMETER   - Buffer is NULL.

+  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.

+  EFI_UNSUPPORTED         - The address range specified by Address, Width, and 

+                            Count is not valid for this EFI System.

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    UserAddress - add argument and description to function comment

+// TODO:    UserBuffer - add argument and description to function comment

+{

+  UINTN       Address;

+  EFI_STATUS  Status;

+

+  if (!UserBuffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Address = (UINTN) UserAddress;

+

+  if (Width >= EfiCpuIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Do nothing for Nt32 version

+  //

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CpuIoServiceWrite (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            UserAddress,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *UserBuffer

+  )

+/*++

+

+Routine Description:

+

+  

+  This is the service that implements the I/O Write

+

+Arguments:

+

+  Pointer to an instance of the CPU I/O Protocol

+  Width of the Memory Access

+  Address of the I/O access

+  Count of the number of accesses to perform

+  Pointer to the buffer to read or write from I/O space

+

+Returns:

+

+  Status

+

+  Status

+  EFI_SUCCESS             - The data was read from or written to the EFI System.

+  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.

+  EFI_INVALID_PARAMETER   - Buffer is NULL.

+  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.

+  EFI_UNSUPPORTED         - The address range specified by Address, Width, and 

+                            Count is not valid for this EFI System.

+

+--*/

+// TODO:    This - add argument and description to function comment

+// TODO:    UserAddress - add argument and description to function comment

+// TODO:    UserBuffer - add argument and description to function comment

+{

+  UINTN       Address;

+  EFI_STATUS  Status;

+

+  if (!UserBuffer) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Address = (UINTN) UserAddress;

+

+  if (Width >= EfiCpuIoWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Do nothing for Nt32 version

+  //

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+CpuIoCheckAddressRange (

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  VOID                              *Buffer,

+  IN  UINT64                            Limit

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Width   - TODO: add argument description

+  Address - TODO: add argument description

+  Count   - TODO: add argument description

+  Buffer  - TODO: add argument description

+  Limit   - TODO: add argument description

+

+Returns:

+

+  EFI_UNSUPPORTED - TODO: Add description for return value

+  EFI_UNSUPPORTED - TODO: Add description for return value

+  EFI_UNSUPPORTED - TODO: Add description for return value

+  EFI_SUCCESS - TODO: Add description for return value

+

+--*/

+{

+  UINTN AlignMask;

+

+  if (Address > Limit) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // For FiFo type, the target address won't increase during the access, so treat count as 1

+  //

+  if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {

+    Count = 1;

+  }

+

+  Width = Width & 0x03;

+  if (Address - 1 + (1 << Width) * Count > Limit) {

+    return EFI_UNSUPPORTED;

+  }

+

+  AlignMask = (1 << Width) - 1;

+  if ((UINTN) Buffer & AlignMask) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Strings.uni b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Strings.uni
new file mode 100644
index 0000000..fd70fb9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/Strings.uni
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/build.xml
new file mode 100644
index 0000000..91fe4e4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/Cpu/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Cpu"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\Cpu"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Cpu">

+      <GenBuild baseName="Cpu" mbdFilename="${MODULE_DIR}\Cpu.mbd" msaFilename="${MODULE_DIR}\Cpu.msa"/>

+   </target>

+   <target depends="Cpu_clean" name="clean"/>

+   <target depends="Cpu_cleanall" name="cleanall"/>

+   <target name="Cpu_clean">

+      <OutputDirSetup baseName="Cpu" mbdFilename="${MODULE_DIR}\Cpu.mbd" msaFilename="${MODULE_DIR}\Cpu.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Cpu_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Cpu_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Cpu_cleanall">

+      <OutputDirSetup baseName="Cpu" mbdFilename="${MODULE_DIR}\Cpu.mbd" msaFilename="${MODULE_DIR}\Cpu.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Cpu_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Cpu_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Cpu*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.c b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.c
new file mode 100644
index 0000000..b1f139f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.c
@@ -0,0 +1,87 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtThunk.c

+

+Abstract:

+

+  Produce WinNtThunk protocol and it's associated device path and controller 

+  state protocols. WinNtThunk is to the NT emulation environment as 

+  PCI_ROOT_BRIGE is to real hardware. The WinNtBusDriver is the child of this

+  driver.

+

+  Since we are a root hardware abstraction we do not install a Driver Binding

+  protocol on this handle. This driver can only support one one WinNtThunk protocol

+  in the system, since the device path is hard coded.

+

+--*/

+

+#include "WinNtThunk.h"

+

+//

+// WinNtThunk Device Path Protocol Instance

+//

+static WIN_NT_THUNK_DEVICE_PATH mWinNtThunkDevicePath = {

+  {

+    HARDWARE_DEVICE_PATH,

+    HW_VENDOR_DP,

+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),

+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),

+    EFI_WIN_NT_THUNK_PROTOCOL_GUID,

+  },

+  {

+    END_DEVICE_PATH_TYPE,

+    END_ENTIRE_DEVICE_PATH_SUBTYPE,

+    END_DEVICE_PATH_LENGTH,

+    0

+  }

+};

+

+

+EFI_STATUS

+EFIAPI

+InitializeWinNtThunk (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+/*++

+

+Routine Description:

+  Install WinNtThunk Protocol and it's associated Device Path protocol

+

+Arguments:

+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

+

+Returns:

+  EFI_SUCEESS - WinNtThunk protocol is added or error status from 

+                gBS->InstallMultiProtocolInterfaces().

+

+--*/

+// TODO:    ImageHandle - add argument and description to function comment

+// TODO:    SystemTable - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE  ControllerHandle;

+

+  ControllerHandle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ControllerHandle,

+                  &gEfiWinNtThunkProtocolGuid,

+                  gWinNt,

+                  &gEfiDevicePathProtocolGuid,

+                  &mWinNtThunkDevicePath,

+                  NULL

+                  );

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.dxs b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.dxs
new file mode 100644
index 0000000..8a59515
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtThunk.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.h b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.h
new file mode 100644
index 0000000..6f474b3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.h
@@ -0,0 +1,30 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtThunk.h

+

+Abstract:

+

+--*/

+

+// TODO: add protective #ifndef

+

+

+//

+// WinNtThunk Device Path Protocol Instance Type

+//

+typedef struct {

+  VENDOR_DEVICE_PATH        Vendor;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} WIN_NT_THUNK_DEVICE_PATH;

+

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.mbd b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.mbd
new file mode 100644
index 0000000..01f9f6d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.mbd
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtThunk</BaseName>

+    <Guid>0C95A916-A006-11d4-BCFA-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiMemoryLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>DxeWinNtLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.msa b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.msa
new file mode 100644
index 0000000..47b6423
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/WinNtThunk.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtThunk</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>BS_DRIVER</ComponentType>

+    <Guid>0C95A916-A006-11d4-BCFA-0080C73C8881</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtThunk module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtThunk.h</Filename>

+    <Filename>WinNtThunk.c</Filename>

+    <Filename>WinNtThunk.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_PRODUCED">WinNtThunk</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">DevicePath</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeWinNtThunk</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/build.xml b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/build.xml
new file mode 100644
index 0000000..938e55f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Dxe/WinNtThunk/WinNtThunk/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtThunk"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Dxe\WinNtThunk\WinNtThunk"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtThunk">

+      <GenBuild baseName="WinNtThunk" mbdFilename="${MODULE_DIR}\WinNtThunk.mbd" msaFilename="${MODULE_DIR}\WinNtThunk.msa"/>

+   </target>

+   <target depends="WinNtThunk_clean" name="clean"/>

+   <target depends="WinNtThunk_cleanall" name="cleanall"/>

+   <target name="WinNtThunk_clean">

+      <OutputDirSetup baseName="WinNtThunk" mbdFilename="${MODULE_DIR}\WinNtThunk.mbd" msaFilename="${MODULE_DIR}\WinNtThunk.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtThunk_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtThunk_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtThunk_cleanall">

+      <OutputDirSetup baseName="WinNtThunk" mbdFilename="${MODULE_DIR}\WinNtThunk.mbd" msaFilename="${MODULE_DIR}\WinNtThunk.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtThunk_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtThunk_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtThunk*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/EdkNt32Pkg.spd b/edk2/EdkNt32Pkg/EdkNt32Pkg.spd
new file mode 100644
index 0000000..ce03c47
--- /dev/null
+++ b/edk2/EdkNt32Pkg/EdkNt32Pkg.spd
@@ -0,0 +1,380 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <SpdHeader>

+    <PackageName>EdkNt32Pkg</PackageName>

+    <Guid>0fb2aa2d-10d5-40a5-a9dc-060c12a4a3f3</Guid>

+    <Version>0.3</Version>

+    <Abstract>This is the NT32 Emulation Environment Platform</Abstract>

+    <Description>Reference platform implementation using an emulator.</Description>

+    <Copyright>Copyright (c) 2006,  Intel Corporation.</Copyright>

+    <License>

+      All rights reserved.

+      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.

+    </License>

+    <Created>2006-02-22 13:25</Created>

+    <Updated>2006-03-22 16:18</Updated>

+    <URL>http://www.TianoCore.org</URL>

+    <PackageType>SOURCE</PackageType>

+    <ReadOnly>true</ReadOnly>

+    <RePackage>false</RePackage>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </SpdHeader>

+  <LibraryClassDeclarations>

+    <LibraryClassDeclaration>

+      <LibraryClass>EdkGenericBdsLib</LibraryClass>

+      <IncludeHeader>Include/Library/EdkGenericBdsLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>WinNtLib</LibraryClass>

+      <IncludeHeader>Include/Library/WinNtLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+  </LibraryClassDeclarations>

+  <MsaFiles>

+  <!--

+    <MsaFile>

+      <Filename>Build/AprioriList.msa</Filename>

+    </MsaFile>

+    -->

+    <MsaFile>

+      <Filename>Dxe/ConPlatform/ConPlatform.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/Nt32Platform/MiscSubclass/MiscSubclassDriver.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/PcdEmulator/PcdEmulator.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/PlatformBds/PlatformBds.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Bus/BlockIo/WinNtBlockIo.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Bus/Console/WinNtConsole.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Bus/SerialIo/WinNtSerialIo.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Bus/Uga/WinNtUga.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Chipset/Metronome/Metronome.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Chipset/RealTimeClock/RealTimeClock.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Chipset/Reset/Reset.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Chipset/Timer/Timer.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/Cpu/Cpu.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Dxe/WinNtThunk/WinNtThunk/WinNtThunk.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeWinNtLib/DxeWinNtLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/EdkGenericBdsLib/EdkGenericBdsLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Logo/Logo.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/Autoscan/WinNtAutoScan.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/BootMode/BootMode.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/FirmwareVolume/WinNtFwh.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/FlashMap/FlashMap.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/MonoStatusCode/Nt32/MonoStatusCode.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/PcdEmulator/PcdEmulator.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Pei/WinNtStuff/WinNtStuff.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>RuntimeDxe/FvbServices/Nt32Fwh.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Sec/SecMain.msa</Filename>

+    </MsaFile>

+  </MsaFiles>

+  <PackageHeaders>

+    <IncludeHeader ModuleType="SEC">Include/WinNtPeim.h</IncludeHeader>

+    <IncludeHeader ModuleType="PEIM">Include/WinNtPeim.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_DRIVER">Include/WinNtDxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_RUNTIME_DRIVER">Include/WinNtDxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_SMM_DRIVER">Include/WinNtDxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_SAL_DRIVER">Include/WinNtDxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="UEFI_DRIVER">Include/WinNtDxe.h</IncludeHeader>

+  </PackageHeaders>

+  <GuidDeclarations>

+    <Entry Name="WinNtVirtualDisks">

+      <C_Name>gEfiWinNtVirtualDisksGuid</C_Name>

+      <Guid>0xc95a928, 0xa006, 0x11d4, 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtPhysicalDisks">

+      <C_Name>gEfiWinNtPhysicalDisksGuid</C_Name>

+      <Guid>0xc95a92f, 0xa006, 0x11d4, 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtFileSystem">

+      <C_Name>gEfiWinNtFileSystemGuid</C_Name>

+      <Guid>0xc95a935, 0xa006, 0x11d4, 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtSerialPort">

+      <C_Name>gEfiWinNtSerialPortGuid</C_Name>

+      <Guid>0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtUga">

+      <C_Name>gEfiWinNtUgaGuid</C_Name>

+      <Guid>0xab248e99, 0xabe1, 0x11d4, 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtConsole">

+      <C_Name>gEfiWinNtConsoleGuid</C_Name>

+      <Guid>0xba73672c, 0xa5d3, 0x11d4, 0xbd, 0x00, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtMemory">

+      <C_Name>gEfiWinNtMemoryGuid</C_Name>

+      <Guid>0x99042912, 0x122a, 0x11d4, 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtCPUModel">

+      <C_Name>gEfiWinNtCPUModelGuid</C_Name>

+      <Guid>0xbee9b6ce, 0x2f8a, 0x11d4, 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtCPUSpeed">

+      <C_Name>gEfiWinNtCPUSpeedGuid</C_Name>

+      <Guid>0xd4f29055, 0xe1fb, 0x11d4, 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNPassThrough">

+      <C_Name>gEfiWinNtPassThroughGuid</C_Name>

+      <Guid>0xcc664eb8, 0x3c24, 0x4086, 0xb6, 0xf6, 0x34, 0xe8, 0x56, 0xbc, 0xe3, 0x6e</Guid>

+    </Entry>

+    <Entry Name="PcdHob">

+      <C_Name>gPcdHobGuid</C_Name>

+      <Guid>0x582e7ca1, 0x68cd, 0x4d44, 0xb4, 0x3b, 0xf2, 0x98, 0xed, 0x58, 0x7b, 0xa6</Guid>

+    </Entry>

+  </GuidDeclarations>

+  <ProtocolDeclarations>

+    <Entry Name="WinNtIo">

+      <C_Name>gEfiWinNtIoProtocolGuid</C_Name>

+      <Guid>0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="WinNtThunk">

+      <C_Name>gEfiWinNtThunkProtocolGuid</C_Name>

+      <Guid>0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+  </ProtocolDeclarations>

+  <PpiDeclarations>

+    <Entry Name="NtAutoScan">

+      <C_Name>gPeiNtAutoScanPpiGuid</C_Name>

+      <Guid>0xdce384d, 0x7c, 0x4ba5, 0x94, 0xbd, 0x0f, 0x6e, 0xb6, 0x4d, 0x2a, 0xa9</Guid>

+    </Entry>

+    <Entry Name="NtFwh">

+      <C_Name>gNtFwhPpiGuid</C_Name>

+      <Guid>0x4e76928f, 0x50ad, 0x4334, 0xb0, 0x6b, 0xa8, 0x42, 0x13, 0x10, 0x8a, 0x57</Guid>

+    </Entry>

+    <Entry Name="NtPeiLoadFile">

+      <C_Name>gNtPeiLoadFilePpiGuid</C_Name>

+      <Guid>0xfd0c65eb, 0x405, 0x4cd2, 0x8a, 0xee, 0xf4, 0x00, 0xef, 0x13, 0xba, 0xc2</Guid>

+    </Entry>

+    <Entry Name="NtThunk">

+      <C_Name>gPeiNtThunkPpiGuid</C_Name>

+      <Guid>0x98c281e5, 0xf906, 0x43dd, 0xa9, 0x2b, 0xb0, 0x03, 0xbf, 0x27, 0x65, 0xda</Guid>

+    </Entry>

+  </PpiDeclarations>

+  <PcdDefinitions>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumAsciiStringLength</C_Name>

+      <Token>0x00000002</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumLinkedListLength</C_Name>

+      <Token>0x00000003</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdSpinLockTimeout</C_Name>

+      <Token>0x00000004</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>10000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0x0f</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>0x80000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+      <Token>0x00000007</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0x07</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0xAF</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0xAF</DefaultValue>

+    </PcdEntry>    

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+      <Token>0x00000009</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtPhysicalDisk</C_Name>

+      <Token>0x00001000</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"FW;40960;512"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtVirtualDisk</C_Name>

+      <Token>0x00001001</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"FW;40960;512"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtSerialPort</C_Name>

+      <Token>0x00001002</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"COM1!COM2"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtUga</C_Name>

+      <Token>0x00001003</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"UGA Window 1!UGA Window 2"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtFileSystem</C_Name>

+      <Token>0x00001004</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L".!C:\\D\\work\\Remodel\\mdk\\EdkShellBinPkg\\bin\\ia32\\Apps"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtMemorySize</C_Name>

+      <Token>0x00001005</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"64!64"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdWinNtMemorySizeForSecMain</C_Name>

+      <Token>0x00001005</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"64!64"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdWinNtBootMode</C_Name>

+      <Token>0x00001006</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtCpuModel</C_Name>

+      <Token>0x00001007</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"Intel(R) Processor Model"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtCpuSpeed</C_Name>

+      <Token>0x00001008</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"3000"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdWinNtFirmwareVolume</C_Name>

+      <Token>0x00001009</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"..\\..\\Fv\\Fv_Recovery.fd"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtConsole</C_Name>

+      <Token>0x0000100a</Token>

+      <DatumType>VOID*</DatumType>

+      <DefaultValue>L"Bus Driver Console Window"</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdRothmanTest</C_Name>

+      <Token>0x0000100b</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>0</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdWinNtBinaryPatch1</C_Name>

+      <Token>0x0001000b</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>0x1234</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdWinNtBinaryPatch2</C_Name>

+      <Token>0x0001000c</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>0x5678</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FEATURE_FLAG">

+      <C_Name>PcdWinNtFeatureFlag1</C_Name>

+      <Token>0x0001000d</Token>

+      <DatumType>BOOLEAN</DatumType>

+      <DefaultValue>0x1</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="DYNAMIC">

+      <C_Name>PcdWinNtDynamicUINT32</C_Name>

+      <Token>0x0001000e</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>0x0</DefaultValue>

+    </PcdEntry>

+  </PcdDefinitions>

+</PackageSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Include/Common/WinNTInclude.h b/edk2/EdkNt32Pkg/Include/Common/WinNTInclude.h
new file mode 100644
index 0000000..a8d31c3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Common/WinNTInclude.h
@@ -0,0 +1,71 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+  WinNtLib.h

+

+Abstract:

+  Public include file for the WinNt Library

+

+--*/

+

+#ifndef __WIN_NT_INCLUDE_H__

+#define __WIN_NT_INCLUDE_H__

+

+//

+// Win32 include files do not compile clean with /W4, so we use the warning

+// pragma to suppress the warnings for Win32 only. This way our code can stil

+// compile at /W4 (highest warning level) with /WX (warnings cause build

+// errors).

+//

+#pragma warning(disable : 4115)

+#pragma warning(disable : 4201)

+#pragma warning(disable : 4214)

+#pragma warning(disable : 4028)

+#pragma warning(disable : 4133)

+

+#define GUID  _WINNT_DUP_GUID_____

+#define _LIST_ENTRY  _WINNT_DUP_LIST_ENTRY_FORWARD

+#define LIST_ENTRY   _WINNT_DUP_LIST_ENTRY

+#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement

+#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement

+#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64

+#undef UNALIGNED

+#undef CONST

+#undef VOID

+

+#include "windows.h"

+

+#undef GUID

+#undef _LIST_ENTRY

+#undef LIST_ENTRY

+#undef InterlockedIncrement

+#undef InterlockedDecrement

+#undef InterlockedCompareExchange64

+#undef InterlockedCompareExchangePointer

+

+#define VOID void

+

+//

+// Prevent collisions with Windows API name macros that deal with Unicode/Not issues

+//

+#undef LoadImage

+#undef CreateEvent

+

+//

+// Set the warnings back on as the EFI code must be /W4.

+//

+#pragma warning(default : 4115)

+#pragma warning(default : 4201)

+#pragma warning(default : 4214)

+

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/FlashLayout.h b/edk2/EdkNt32Pkg/Include/FlashLayout.h
new file mode 100644
index 0000000..5a95961
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/FlashLayout.h
@@ -0,0 +1,64 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FlashLayout.h

+   

+Abstract:

+

+  Platform specific flash layout

+

+  BugBug: We need a better way

+

+--*/

+

+#ifndef __EFI_FLASH_LAYOUT__

+#define __EFI_FLASH_LAYOUT__

+

+//

+// Firmware Volume Information for Nt32

+// adding one working block before FFS FV,

+// and another one for spare block behind FFS FV

+//

+//

+// Note: When block number is changed in .dsc file,

+//       this value should be changed accordingly!!!

+//

+#define FIRMWARE_BLOCK_NUMBER                         0x28

+

+#define EFI_WINNT_FIRMWARE_OFFSET                     0x0

+#define EFI_WINNT_FIRMWARE_LENGTH                     (0x10000 * FIRMWARE_BLOCK_NUMBER)

+

+#define EFI_WINNT_RUNTIME_UPDATABLE_OFFSET            (EFI_WINNT_FIRMWARE_OFFSET + EFI_WINNT_FIRMWARE_LENGTH)

+

+#define EFI_WINNT_RUNTIME_UPDATABLE_LENGTH            0x10000

+

+#define EFI_WINNT_FTW_SPARE_BLOCK_OFFSET              (EFI_WINNT_RUNTIME_UPDATABLE_OFFSET + EFI_WINNT_RUNTIME_UPDATABLE_LENGTH)

+

+#define EFI_WINNT_FTW_SPARE_BLOCK_LENGTH              0x10000

+

+#define EFI_WINNT_RUNTIME_UPDATABLE_FV_HEADER_LENGTH  0x48

+

+#define EFI_VARIABLE_STORE_OFFSET                     (EFI_WINNT_RUNTIME_UPDATABLE_OFFSET + EFI_WINNT_RUNTIME_UPDATABLE_FV_HEADER_LENGTH)

+

+#define EFI_VARIABLE_STORE_LENGTH                     (0x00C000 - EFI_WINNT_RUNTIME_UPDATABLE_FV_HEADER_LENGTH)

+

+#define EFI_EVENT_LOG_OFFSET                          (EFI_VARIABLE_STORE_OFFSET + EFI_VARIABLE_STORE_LENGTH)

+

+#define EFI_EVENT_LOG_LENGTH                          0x002000

+

+#define EFI_FTW_WORKING_OFFSET                        (EFI_EVENT_LOG_OFFSET + EFI_EVENT_LOG_LENGTH)

+

+#define EFI_FTW_WORKING_LENGTH                        0x002000

+

+#endif

+

diff --git a/edk2/EdkNt32Pkg/Include/Ppi/NtAutoscan.h b/edk2/EdkNt32Pkg/Include/Ppi/NtAutoscan.h
new file mode 100644
index 0000000..6098819
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Ppi/NtAutoscan.h
@@ -0,0 +1,66 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  NtAutoscan.h

+

+Abstract:

+

+Nt Autoscan PPI

+

+--*/

+

+#ifndef __NT_PEI_AUTOSCAN_H__

+#define __NT_PEI_AUTOSCAN_H__

+

+#include <WinNtDxe.h>

+

+#define PEI_NT_AUTOSCAN_PPI_GUID \

+  { \

+    0xdce384d, 0x7c, 0x4ba5, {0x94, 0xbd, 0xf, 0x6e, 0xb6, 0x4d, 0x2a, 0xa9 } \

+  }

+

+typedef

+EFI_STATUS

+(EFIAPI *PEI_NT_AUTOSCAN) (

+  IN  UINTN                 Index,

+  OUT EFI_PHYSICAL_ADDRESS  * MemoryBase,

+  OUT UINT64                *MemorySize

+  );

+

+/*++

+

+Routine Description:

+  This service is called from Index == 0 until it returns EFI_UNSUPPORTED.

+  It allows discontiguous memory regions to be supported by the emulator.

+  It uses gSystemMemory[] and gSystemMemoryCount that were created by

+  parsing the Windows environment variable EFI_MEMORY_SIZE.

+  The size comes from the varaible and the address comes from the call to

+  WinNtOpenFile. 

+

+Arguments:

+  Index      - Which memory region to use

+  MemoryBase - Return Base address of memory region

+  MemorySize - Return size in bytes of the memory region

+

+Returns:

+  EFI_SUCCESS - If memory region was mapped

+  EFI_UNSUPPORTED - If Index is not supported

+

+--*/

+typedef struct {

+  PEI_NT_AUTOSCAN NtAutoScan;

+} PEI_NT_AUTOSCAN_PPI;

+

+extern EFI_GUID gPeiNtAutoScanPpiGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/Ppi/NtFwh.h b/edk2/EdkNt32Pkg/Include/Ppi/NtFwh.h
new file mode 100644
index 0000000..90b4109
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Ppi/NtFwh.h
@@ -0,0 +1,62 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  NtFwh.h

+

+Abstract:

+

+  WinNt FWH PPI as defined in Tiano

+

+--*/

+

+#ifndef __NT_PEI_FWH_H__

+#define __NT_PEI_FWH_H__

+

+#include <WinNtDxe.h>

+

+#define NT_FWH_PPI_GUID \

+  { \

+    0x4e76928f, 0x50ad, 0x4334, {0xb0, 0x6b, 0xa8, 0x42, 0x13, 0x10, 0x8a, 0x57 } \

+  }

+

+typedef

+EFI_STATUS

+(EFIAPI *NT_FWH_INFORMATION) (

+  IN     UINTN                  Index,

+  IN OUT EFI_PHYSICAL_ADDRESS   * FdBase,

+  IN OUT UINT64                 *FdSize

+  );

+

+/*++

+

+Routine Description:

+  Return the FD Size and base address. Since the FD is loaded from a 

+  file into Windows memory only the SEC will know it's address.

+

+Arguments:

+  Index  - Which FD, starts at zero.

+  FdSize - Size of the FD in bytes

+  FdBase - Start address of the FD. Assume it points to an FV Header

+

+Returns:

+  EFI_SUCCESS     - Return the Base address and size of the FV

+  EFI_UNSUPPORTED - Index does nto map to an FD in the system

+

+--*/

+typedef struct {

+  NT_FWH_INFORMATION  NtFwh;

+} NT_FWH_PPI;

+

+extern EFI_GUID gNtFwhPpiGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/Ppi/NtPeiLoadFile.h b/edk2/EdkNt32Pkg/Include/Ppi/NtPeiLoadFile.h
new file mode 100644
index 0000000..622e01a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Ppi/NtPeiLoadFile.h
@@ -0,0 +1,65 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+ NtPeiLoadFile.h

+

+Abstract:

+

+  WinNt Load File PPI.

+

+  When the PEI core is done it calls the DXE IPL via PPI

+

+--*/

+

+#ifndef __NT_PEI_LOAD_FILE_H__

+#define __NT_PEI_LOAD_FILE_H__

+

+#include <WinNtDxe.h>

+

+#define NT_PEI_LOAD_FILE_GUID \

+  { \

+    0xfd0c65eb, 0x405, 0x4cd2, {0x8a, 0xee, 0xf4, 0x0, 0xef, 0x13, 0xba, 0xc2 } \

+  }

+

+typedef

+EFI_STATUS

+(EFIAPI *NT_PEI_LOAD_FILE) (

+  VOID                  *Pe32Data,

+  EFI_PHYSICAL_ADDRESS  *ImageAddress,

+  UINT64                *ImageSize,

+  EFI_PHYSICAL_ADDRESS  *EntryPoint

+  );

+

+/*++

+

+Routine Description:

+  Loads and relocates a PE/COFF image into memory.

+

+Arguments:

+  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated

+  ImageAddress     - The base address of the relocated PE/COFF image

+  ImageSize        - The size of the relocated PE/COFF image

+  EntryPoint       - The entry point of the relocated PE/COFF image

+

+Returns:

+  EFI_SUCCESS   - The file was loaded and relocated

+  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file

+

+--*/

+typedef struct {

+  NT_PEI_LOAD_FILE  PeiLoadFileService;

+} NT_PEI_LOAD_FILE_PPI;

+

+extern EFI_GUID gNtPeiLoadFilePpiGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/Ppi/NtThunk.h b/edk2/EdkNt32Pkg/Include/Ppi/NtThunk.h
new file mode 100644
index 0000000..782c510
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Ppi/NtThunk.h
@@ -0,0 +1,56 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  NtThunk.h

+

+Abstract:

+

+  WinNt Thunk interface PPI

+

+--*/

+

+#ifndef __NT_PEI_WIN_NT_THUNK_H__

+#define __NT_PEI_WIN_NT_THUNK_H__

+

+#include <WinNtDxe.h>

+

+#define PEI_NT_THUNK_PPI_GUID \

+  { \

+    0x98c281e5, 0xf906, 0x43dd, {0xa9, 0x2b, 0xb0, 0x3, 0xbf, 0x27, 0x65, 0xda } \

+  }

+

+typedef

+VOID *

+(EFIAPI *PEI_NT_THUNK_INTERFACE) (

+  VOID

+  );

+

+/*++

+

+Routine Description:

+  Export of EFI_WIN_NT_THUNK_PROTOCOL from the Windows SEC.

+

+Arguments:

+  InterfaceBase - Address of the EFI_WIN_NT_THUNK_PROTOCOL

+

+Returns:

+  EFI_SUCCESS - Data returned

+

+--*/

+typedef struct {

+  PEI_NT_THUNK_INTERFACE  NtThunk;

+} PEI_NT_THUNK_PPI;

+

+extern EFI_GUID gPeiNtThunkPpiGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/Protocol/WinNtIo.h b/edk2/EdkNt32Pkg/Include/Protocol/WinNtIo.h
new file mode 100644
index 0000000..85d99fe
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Protocol/WinNtIo.h
@@ -0,0 +1,141 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtIo.h

+

+Abstract:

+

+--*/

+

+#ifndef __WIN_NT_IO_H__

+#define __WIN_NT_IO_H__

+

+#define EFI_WIN_NT_IO_PROTOCOL_GUID \

+  { 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+typedef struct {

+  EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;

+  EFI_GUID                  *TypeGuid;

+  CHAR16                    *EnvString;

+  UINT16                    InstanceNumber;

+} EFI_WIN_NT_IO_PROTOCOL;

+

+

+extern EFI_GUID gEfiWinNtIoProtocolGuid;

+

+//

+// The following GUIDs are used in EFI_WIN_NT_IO_PROTOCOL_GUID

+// Device paths. They map 1:1 with NT envirnment variables. The variables

+// define what virtual hardware the emulator/WinNtBusDriver will produce.

+//

+//

+// EFI_WIN_NT_VIRTUAL_DISKS

+//

+#define EFI_WIN_NT_VIRTUAL_DISKS_GUID \

+  { \

+    0xc95a928, 0xa006, 0x11d4, {0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtVirtualDisksGuid;

+

+//

+// EFI_WIN_NT_PHYSICAL_DISKS

+//

+#define EFI_WIN_NT_PHYSICAL_DISKS_GUID \

+  { \

+    0xc95a92f, 0xa006, 0x11d4, {0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtPhysicalDisksGuid;

+

+//

+// EFI_WIN_NT_FILE_SYSTEM

+//

+#define EFI_WIN_NT_FILE_SYSTEM_GUID \

+  { \

+    0xc95a935, 0xa006, 0x11d4, {0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtFileSystemGuid;

+

+//

+// EFI_WIN_NT_SERIAL_PORT

+//

+#define EFI_WIN_NT_SERIAL_PORT_GUID \

+  { \

+    0xc95a93d, 0xa006, 0x11d4, {0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtSerialPortGuid;

+

+//

+// EFI_WIN_NT_UGA

+//

+#define EFI_WIN_NT_UGA_GUID \

+  { \

+    0xab248e99, 0xabe1, 0x11d4, {0xbd, 0xd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtUgaGuid;

+

+//

+// EFI_WIN_NT_CONSOLE

+//

+#define EFI_WIN_NT_CONSOLE_GUID \

+  { \

+    0xba73672c, 0xa5d3, 0x11d4, {0xbd, 0x0, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtConsoleGuid;

+

+//

+// EFI_WIN_NT_MEMORY

+//

+#define EFI_WIN_NT_MEMORY_GUID \

+  { \

+    0x99042912, 0x122a, 0x11d4, {0xbd, 0xd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtMemoryGuid;

+

+//

+// EFI_WIN_NT_CPU_MODEL

+//

+#define EFI_WIN_NT_CPU_MODEL_GUID \

+  { \

+    0xbee9b6ce, 0x2f8a, 0x11d4, {0xbd, 0xd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtCPUModelGuid;

+

+//

+// EFI_WIN_NT_CPU_SPEED

+//

+#define EFI_WIN_NT_CPU_SPEED_GUID \

+  { \

+    0xd4f29055, 0xe1fb, 0x11d4, {0xbd, 0xd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gEfiWinNtCPUSpeedGuid;

+

+//

+// EFI_WIN_NT_PASS_THROUGH

+//

+#define EFI_WIN_NT_PASS_THROUGH_GUID \

+  { \

+    0xcc664eb8, 0x3c24, 0x4086, {0xb6, 0xf6, 0x34, 0xe8, 0x56, 0xbc, 0xe3, 0x6e } \

+  }

+

+extern EFI_GUID gEfiWinNtPassThroughGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/Protocol/WinNtThunk.h b/edk2/EdkNt32Pkg/Include/Protocol/WinNtThunk.h
new file mode 100644
index 0000000..6ebc93f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/Protocol/WinNtThunk.h
@@ -0,0 +1,1264 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtThunk.h

+

+Abstract:

+

+  This protocol allows an EFI driver (DLL) in the NT emulation envirnment

+  to make Win32 API calls.

+

+  NEVER make a Win32 call directly, always make the call via this protocol.

+

+  There are no This pointers on the protocol member functions as they map

+  exactly into Win32 system calls.

+

+  YOU MUST include EfiWinNT.h in place of Efi.h to make this file compile.

+

+--*/

+

+#ifndef __WIN_NT_THUNK_H__

+#define __WIN_NT_THUNK_H__

+

+#define EFI_WIN_NT_THUNK_PROTOCOL_GUID \

+  { 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtSleep) (

+  DWORD Milliseconds

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtSuspendThread) (

+  HANDLE hThread

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtGetCurrentThread) (

+  VOID

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtGetCurrentThreadId) (

+  VOID

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtGetCurrentProcess) (

+  VOID

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtCreateThread) (

+  LPSECURITY_ATTRIBUTES   lpThreadAttributes,

+  DWORD                   dwStackSize,

+  LPTHREAD_START_ROUTINE  lpStartAddress,

+  LPVOID                  lpParameter,

+  DWORD                   dwCreationFlags,

+  LPDWORD                 lpThreadId

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtTerminateThread) (

+  HANDLE hThread,

+  DWORD  dwExitCode

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSendMessage) (

+  HWND    hWnd,

+  UINT    Msg,

+  WPARAM  wParam,

+  LPARAM  lParam

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtExitThread) (

+  DWORD   dwExitCode

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtResumeThread) (

+  HANDLE hThread

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetThreadPriority) (

+  HANDLE    hThread,

+  INTN      nPriority

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtInitializeCriticalSection) (

+  LPCRITICAL_SECTION lpCriticalSection

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtDeleteCriticalSection) (

+  LPCRITICAL_SECTION lpCriticalSection

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtEnterCriticalSection) (

+  LPCRITICAL_SECTION lpCriticalSection

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtLeaveCriticalSection) (

+  LPCRITICAL_SECTION lpCriticalSection

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtTlsAlloc) (

+  VOID

+  );

+

+typedef

+WINBASEAPI

+LPVOID

+(WINAPI *WinNtTlsGetValue) (

+  DWORD dwTlsIndex

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtTlsSetValue) (

+  DWORD  dwTlsIndex,

+  LPVOID lpTlsValue

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtTlsFree) (

+  DWORD dwTlsIndex

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtCreateSemaphore) (

+  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

+  LONG                  lInitialCount,

+  LONG                  lMaximumCount,

+  LPCWSTR               lpName

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtWaitForSingleObject) (

+  HANDLE  hHandle,

+  DWORD   dwMilliseconds

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtReleaseSemaphore) (

+  HANDLE  hSemaphore,

+  LONG    lReleaseCount,

+  LPLONG  lpPreviousCount

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtDuplicateHandle) (

+  HANDLE   hSourceProcessHandle,

+  HANDLE   hSourceHandle,

+  HANDLE   hTargetProcessHandle,

+  LPHANDLE lpTargetHandle,

+  DWORD    dwDesiredAccess,

+  BOOL     bInheritHandle,

+  DWORD    dwOptions

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtCreateConsoleScreenBuffer) (

+  DWORD                       DesiredAccess,

+  DWORD                       ShareMode,

+  CONST SECURITY_ATTRIBUTES   *SecurityAttributes,

+  DWORD                       Flags,

+  LPVOID                      ScreenBufferData

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetConsoleScreenBufferSize) (

+  HANDLE  ConsoleOutput,

+  COORD   Size

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetConsoleActiveScreenBuffer) (

+  HANDLE  ConsoleOutput

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFillConsoleOutputAttribute) (

+  HANDLE  ConsoleOutput,

+  WORD    Attribute,

+  DWORD   Length,

+  COORD   WriteCoord,

+  LPDWORD NumberOfAttrsWritten

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFillConsoleOutputCharacter) (

+  HANDLE  ConsoleOutput,

+  TCHAR   Character,

+  DWORD   Length,

+  COORD   WriteCoord,

+  LPDWORD NumberOfCharsWritten

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtWriteConsoleOutput) (

+  HANDLE          ConsoleOutput,

+  CONST CHAR_INFO *Buffer,

+  COORD           BufferSize,

+  COORD           BufferCoord,

+  PSMALL_RECT     WriteRegion

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtScrollConsoleScreenBuffer) (

+  HANDLE            ConsoleOutput,

+  CONST SMALL_RECT  *ScrollRectangle,

+  CONST SMALL_RECT  *ClipRectangle,

+  COORD             DestinationOrigin,

+  CONST CHAR_INFO   *Fill

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetConsoleTitleW) (

+  LPCTSTR   ConsoleTitle

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetConsoleCursorInfo) (

+  HANDLE                ConsoleOutput,

+  PCONSOLE_CURSOR_INFO  ConsoleCursorInfo

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetConsoleCursorInfo) (

+  HANDLE                      ConsoleOutput,

+  CONST CONSOLE_CURSOR_INFO   *ConsoleCursorInfo

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetPriorityClass) (

+  HANDLE  Process,

+  DWORD   PriorityClass

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtWriteConsoleInput) (

+  HANDLE              ConsoleInput,

+  CONST INPUT_RECORD  *Buffer,

+  DWORD               Legnth,

+  LPDWORD             NumberOfEventsWritten

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetNumberOfConsoleInputEvents) (

+  HANDLE              ConsoleInput,

+  LPDWORD             NumberOfEvents

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtGetStdHandle) (

+  DWORD   StdHandle

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtReadConsoleInput) (

+  HANDLE              ConsoleInput,

+  PINPUT_RECORD       Buffer,

+  DWORD               Length,

+  LPDWORD             NumberOfEventsRead

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtPeekConsoleInput) (

+  HANDLE              ConsoleInput,

+  PINPUT_RECORD       Buffer,

+  DWORD               Length,

+  LPDWORD             NumberOfEventsRead

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetConsoleCursorPosition) (

+  HANDLE              ConsoleInput,

+  COORD               CursorPosition

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtCreateFile) (

+  LPCWSTR               FileName,

+  DWORD                 DesiredAccess,

+  DWORD                 SharedMode,

+  LPSECURITY_ATTRIBUTES SecurityAttributes,

+  DWORD                 CreationDisposition,

+  DWORD                 FlagsAndAttributes,

+  HANDLE                TemplateFile

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtDeviceIoControl) (

+  HANDLE                DeviceHandle,

+  DWORD                 IoControlCode,

+  LPVOID                InBuffer,

+  DWORD                 InBufferSize,

+  LPVOID                OutBuffer,

+  DWORD                 OutBufferSize,

+  LPDWORD               BytesReturned,

+  LPOVERLAPPED          Overlapped

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtCreateDirectory) (

+  LPCWSTR               PathName,

+  LPSECURITY_ATTRIBUTES SecurityAttributes

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtRemoveDirectory) (

+  LPCWSTR               PathName

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtGetFileAttributes) (

+  LPCWSTR               FileName

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetFileAttributes) (

+  LPCWSTR               FileName,

+  DWORD                 FileAttributes

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtCreateFileMapping) (

+  HANDLE                  FileHandle,

+  LPSECURITY_ATTRIBUTES   Attributes,

+  DWORD                   Protect,

+  DWORD                   MaximumSizeHigh,

+  DWORD                   MaximumSizeLow,

+  LPCTSTR                 Name

+  );

+

+typedef

+WINBASEAPI

+LPVOID

+(WINAPI *WinNtMapViewOfFileEx) (

+  HANDLE                  FileHandle,

+  DWORD                   DesiredAccess,

+  DWORD                   FileOffsetHigh,

+  DWORD                   FileOffsetLow,

+  DWORD                   NumberOfBytesToMap,

+  LPVOID                  BaseAddress

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtGetEnvironmentVariable) (

+  LPCTSTR Name,

+  LPTSTR  Buffer,

+  DWORD   Size

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtCloseHandle) (

+  HANDLE    Object

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtSetFilePointer) (

+  HANDLE    FileHandle,

+  LONG      DistanceToMove,

+  PLONG     DistanceToHoveHigh,

+  DWORD     MoveMethod

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetEndOfFile) (

+  HANDLE    FileHandle

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtReadFile) (

+  HANDLE        FileHandle,

+  LPVOID        Buffer,

+  DWORD         NumberOfBytesToRead,

+  LPDWORD       NumberOfBytesRead,

+  LPOVERLAPPED  Overlapped

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtWriteFile) (

+  HANDLE        FileHandle,

+  LPCVOID       Buffer,

+  DWORD         NumberOfBytesToWrite,

+  LPDWORD       NumberOfBytesWritten,

+  LPOVERLAPPED  Overlapped

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetFileInformationByHandle) (

+  HANDLE                      FileHandle,

+  BY_HANDLE_FILE_INFORMATION  *FileInfo

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetDiskFreeSpace) (

+  LPCTSTR     RootPathName,

+  LPDWORD     SectorsPerCluster,

+  LPDWORD     BytesPerSector,

+  LPDWORD     NumberOfFreeClusters,

+  LPDWORD     TotalNumberOfClusters

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetDiskFreeSpaceEx) (

+  LPCTSTR             DirectoryName,

+  PULARGE_INTEGER     FreeBytesAvailable,

+  PULARGE_INTEGER     TotalNumberOfBytes,

+  PULARGE_INTEGER     TotoalNumberOfFreeBytes

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtMoveFile) (

+  LPCTSTR     ExistingFileName,

+  LPCTSTR     NewFileName

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetFileTime) (

+  HANDLE      FileHandle,

+  FILETIME    *CreationTime,

+  FILETIME    *LastAccessTime,

+  FILETIME    *LastWriteTime

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSystemTimeToFileTime) (

+  SYSTEMTIME  * SystemTime,

+  FILETIME    * FileTime

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtDeleteFile) (

+  LPCTSTR   FileName

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFlushFileBuffers) (

+  HANDLE

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtGetLastError) (

+  VOID

+  );

+

+typedef

+WINBASEAPI

+UINT

+(WINAPI *WinNtSetErrorMode) (

+  UINT  Mode

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtGetTickCount) (

+  VOID

+  );

+

+typedef

+WINBASEAPI

+HMODULE

+(WINAPI *WinNtLoadLibraryEx) (

+  LPCTSTR LibFileName,

+  HANDLE  FileHandle,

+  DWORD   Flags

+  );

+

+typedef

+WINBASEAPI

+FARPROC

+(WINAPI *WinNtGetProcAddress) (

+  HMODULE Module,

+  LPCSTR  ProcName

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtGetTimeZoneInformation) (

+  LPTIME_ZONE_INFORMATION timeZoneInformation

+  );

+

+typedef

+WINBASEAPI

+MMRESULT

+(WINAPI *WinNttimeSetEvent) (

+  UINT           uDelay,

+  UINT           uResolution,

+  LPTIMECALLBACK lpTimeProc,

+  DWORD_PTR      dwUser,

+  UINT           fuEvent

+  );

+

+typedef

+WINBASEAPI

+MMRESULT

+(WINAPI *WinNttimeKillEvent) (

+  UINT           uTimerID

+  );

+

+typedef

+WINBASEAPI

+DWORD

+(WINAPI *WinNtSetTimeZoneInformation) (

+  LPTIME_ZONE_INFORMATION timeZoneInformation

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtGetSystemTime) (

+  LPSYSTEMTIME        SystemTime

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetSystemTime) (

+  CONST SYSTEMTIME    *SystemTime

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtGetLocalTime) (

+  LPSYSTEMTIME        SystemTime

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetLocalTime) (

+  CONST SYSTEMTIME    *SystemTime

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFileTimeToLocalFileTime) (

+  CONST FILETIME  *FileTime,

+  LPFILETIME      LocalFileTime

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFileTimeToSystemTime) (

+  CONST FILETIME  *FileTime,

+  LPSYSTEMTIME    SystemTime

+  );

+

+typedef

+WINBASEAPI

+HANDLE

+(WINAPI *WinNtFindFirstFile) (

+  LPCTSTR           FileName,

+  LPWIN32_FIND_DATA FindFileData

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFindNextFile) (

+  HANDLE            FindFile,

+  LPWIN32_FIND_DATA FindFileData

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFindClose) (

+  HANDLE            FindFile

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetCommState) (

+  HANDLE  FileHandle,

+  LPDCB   DCB

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetCommState) (

+  HANDLE  FileHandle,

+  LPDCB   DCB

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetCommState) (

+  HANDLE  FileHandle,

+  LPDCB   DCB

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtSetCommTimeouts) (

+  HANDLE          FileHandle,

+  LPCOMMTIMEOUTS  CommTimeouts

+  );

+

+typedef

+WINBASEAPI

+VOID

+(WINAPI *WinNtExitProcess) (

+  UINT uExitCode  // exit code for all threads

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtPurgeComm) (

+  HANDLE  FileHandle,

+  DWORD   Flags

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtEscapeCommFunction) (

+  HANDLE  FileHandle,

+  DWORD   Func

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtGetCommModemStatus) (

+  HANDLE  FileHandle,

+  LPDWORD ModemStat

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtClearCommError) (

+  HANDLE    FileHandle,

+  LPDWORD   Errors,

+  LPCOMSTAT Stat

+  );

+

+typedef

+WINUSERAPI

+INT32

+(WINAPIV *WinNtSprintf) (

+  LPWSTR    Buffer,

+  LPCWSTR   String,

+  ...

+  );

+

+typedef

+WINUSERAPI

+HWND

+(WINAPI *WinNtGetDesktopWindow) (

+  VOID

+  );

+

+typedef

+WINUSERAPI

+HWND

+(WINAPI *WinNtGetForegroundWindow) (

+  VOID

+  );

+

+typedef

+WINUSERAPI

+HWND

+(WINAPI *WinNtCreateWindowEx) (

+  DWORD     dwExStyle,

+  LPCTSTR   lpClassName,

+  LPCTSTR   lpWindowName,

+  DWORD     dwStyle,

+  INT32     x,

+  INT32     y,

+  INT32     nWidth,

+  INT32     nHeight,

+  HWND      hWndParent,

+  HMENU     hMenu,

+  HINSTANCE hInstance,

+  LPVOID    *lpParam

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtUpdateWindow) (

+  HWND      hWnd

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtShowWindow) (

+  HWND        hWnd,

+  INT32       nCmdShow

+  );

+

+typedef

+WINGDIAPI

+BOOL

+(WINAPI *WinNtDestroyWindow) (

+  HWND    hWnd

+  );

+

+typedef

+WINUSERAPI

+HDC

+(WINAPI *WinNtGetWindowDC) (

+  HWND    hWnd

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtGetClientRect) (

+  HWND    hWnd,

+  LPRECT  lpRect

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtAdjustWindowRect) (

+  LPRECT  lpRect,

+  DWORD   dwStyle,

+  BOOL    bMenu

+  );

+

+typedef

+WINGDIAPI

+INT32

+(WINAPI *WinNtSetDIBitsToDevice) (

+  HDC,

+  INT32,

+  INT32,

+  DWORD,

+  DWORD,

+  INT32,

+  INT32,

+  UINT,

+  UINT,

+  CONST VOID       *,

+  CONST BITMAPINFO *,

+  UINT

+  );

+

+typedef

+WINGDIAPI

+BOOL

+(WINAPI *WinNtBitBlt) (

+  HDC,

+  INT32,

+  INT32,

+  INT32,

+  INT32,

+  HDC,

+  INT32,

+  INT32,

+  DWORD

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtInvalidateRect) (

+  HWND        hWnd,

+  CONST RECT  *lpRect,

+  BOOL        bErase

+  );

+

+typedef

+WINUSERAPI

+HDC

+(WINAPI *WinNtGetDC) (

+  HWND    hWnd

+  );

+

+typedef

+WINUSERAPI

+INT32

+(WINAPI *WinNtReleaseDC) (

+  HWND    hWnd,

+  HDC     hDC

+  );

+

+typedef

+WINUSERAPI

+ATOM

+(WINAPI *WinNtRegisterClassEx) (

+  CONST   WNDCLASSEX *

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtUnregisterClass) (

+  LPCTSTR   lpClassName,

+  HINSTANCE hInstance

+  );

+

+typedef

+WINUSERAPI

+HDC

+(WINAPI *WinNtBeginPaint) (

+  HWND          hWnd,

+  LPPAINTSTRUCT lpPaint

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtEndPaint) (

+  HWND                hWnd,

+  CONST PAINTSTRUCT   *lpPaint

+  );

+

+typedef

+WINUSERAPI

+VOID

+(WINAPI *WinNtPostQuitMessage) (

+  INT32   nExitCode

+  );

+

+typedef

+WINUSERAPI

+LRESULT

+(WINAPI *WinNtDefWindowProc) (

+  HWND    hWnd,

+  UINT    Msg,

+  WPARAM  wParam,

+  LPARAM  lParam

+  );

+

+typedef

+WINUSERAPI

+HICON

+(WINAPI *WinNtLoadIcon) (

+  HINSTANCE hInstance,

+  LPCTSTR   lpIconName

+  );

+

+typedef

+WINUSERAPI

+HCURSOR

+(WINAPI *WinNtLoadCursor) (

+  HINSTANCE   hInstance,

+  LPCTSTR     lpCursorName

+  );

+

+typedef

+WINGDIAPI

+HGDIOBJ

+(WINAPI *WinNtGetStockObject) (

+  INT32

+  );

+

+typedef

+WINGDIAPI

+BOOL

+(WINAPI *WinNtSetViewportOrgEx) (

+  HDC,

+  INT32,

+  INT32,

+  LPPOINT

+  );

+

+typedef

+WINGDIAPI

+BOOL

+(WINAPI *WinNtSetWindowOrgEx) (

+  HDC,

+  INT32,

+  INT32,

+  LPPOINT

+  );

+typedef

+WINGDIAPI

+BOOL

+(WINAPI *WinNtMoveWindow) (

+  HWND,

+  INT32,

+  INT32,

+  INT32,

+  INT32,

+  BOOL

+  );

+

+typedef

+WINGDIAPI

+BOOL

+(WINAPI *WinNtGetWindowRect) (

+  HWND,

+  LPRECT

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtGetMessage) (

+  LPMSG     lpMsg,

+  HWND      hWnd,

+  UINT      wMsgFilterMin,

+  UINT      wMsgFilterMax

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtTranslateMessage) (

+  CONST MSG *lpMsg

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtDispatchMessage) (

+  CONST MSG *lpMsg

+  );

+

+typedef

+WINUSERAPI

+HANDLE

+(WINAPI *WinNtGetProcessHeap) ();

+

+typedef

+WINUSERAPI

+LPVOID

+(WINAPI *WinNtHeapAlloc) (

+  HANDLE  hHeap,

+  DWORD   dwFlags,

+  SIZE_T  dwBytes

+  );

+

+typedef

+WINUSERAPI

+BOOL

+(WINAPI *WinNtHeapFree) (

+  HANDLE  hHeap,

+  DWORD   dwFlags,

+  LPVOID  lpMem

+  );

+

+typedef

+WINBASEAPI

+BOOL

+(WINAPI *WinNtFreeLibrary) (

+  HANDLE  ModHandle

+  );

+//

+//

+//

+

+#define EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE EFI_SIGNATURE_32 ('N', 'T', 'T', 'T')

+

+typedef struct {

+  UINT64                              Signature;

+

+  //

+  // Win32 Process APIs

+  //

+  WinNtGetProcAddress                 GetProcAddress;

+  WinNtGetTickCount                   GetTickCount;

+  WinNtLoadLibraryEx                  LoadLibraryEx;

+  WinNtFreeLibrary                    FreeLibrary;

+

+  WinNtSetPriorityClass               SetPriorityClass;

+  WinNtSetThreadPriority              SetThreadPriority;

+  WinNtSleep                          Sleep;

+

+  WinNtSuspendThread                  SuspendThread;

+  WinNtGetCurrentThread               GetCurrentThread;

+  WinNtGetCurrentThreadId             GetCurrentThreadId;

+  WinNtGetCurrentProcess              GetCurrentProcess;

+  WinNtCreateThread                   CreateThread;

+  WinNtTerminateThread                TerminateThread;

+  WinNtSendMessage                    SendMessage;

+  WinNtExitThread                     ExitThread;

+  WinNtResumeThread                   ResumeThread;

+  WinNtDuplicateHandle                DuplicateHandle;

+

+  //

+  // Wint32 Mutex primitive

+  //

+  WinNtInitializeCriticalSection      InitializeCriticalSection;

+  WinNtEnterCriticalSection           EnterCriticalSection;

+  WinNtLeaveCriticalSection           LeaveCriticalSection;

+  WinNtDeleteCriticalSection          DeleteCriticalSection;

+  WinNtTlsAlloc                       TlsAlloc;

+  WinNtTlsFree                        TlsFree;

+  WinNtTlsSetValue                    TlsSetValue;

+  WinNtTlsGetValue                    TlsGetValue;

+  WinNtCreateSemaphore                CreateSemaphore;

+  WinNtWaitForSingleObject            WaitForSingleObject;

+  WinNtReleaseSemaphore               ReleaseSemaphore;

+

+  //

+  // Win32 Console APIs

+  //

+  WinNtCreateConsoleScreenBuffer      CreateConsoleScreenBuffer;

+  WinNtFillConsoleOutputAttribute     FillConsoleOutputAttribute;

+  WinNtFillConsoleOutputCharacter     FillConsoleOutputCharacter;

+  WinNtGetConsoleCursorInfo           GetConsoleCursorInfo;

+  WinNtGetNumberOfConsoleInputEvents  GetNumberOfConsoleInputEvents;

+  WinNtPeekConsoleInput               PeekConsoleInput;

+  WinNtScrollConsoleScreenBuffer      ScrollConsoleScreenBuffer;

+  WinNtReadConsoleInput               ReadConsoleInput;

+

+  WinNtSetConsoleActiveScreenBuffer   SetConsoleActiveScreenBuffer;

+  WinNtSetConsoleCursorInfo           SetConsoleCursorInfo;

+  WinNtSetConsoleCursorPosition       SetConsoleCursorPosition;

+  WinNtSetConsoleScreenBufferSize     SetConsoleScreenBufferSize;

+  WinNtSetConsoleTitleW               SetConsoleTitleW;

+  WinNtWriteConsoleInput              WriteConsoleInput;

+  WinNtWriteConsoleOutput             WriteConsoleOutput;

+

+  //

+  // Win32 File APIs

+  //

+  WinNtCreateFile                     CreateFile;

+  WinNtDeviceIoControl                DeviceIoControl;

+  WinNtCreateDirectory                CreateDirectory;

+  WinNtRemoveDirectory                RemoveDirectory;

+  WinNtGetFileAttributes              GetFileAttributes;

+  WinNtSetFileAttributes              SetFileAttributes;

+  WinNtCreateFileMapping              CreateFileMapping;

+  WinNtCloseHandle                    CloseHandle;

+  WinNtDeleteFile                     DeleteFile;

+  WinNtFindFirstFile                  FindFirstFile;

+  WinNtFindNextFile                   FindNextFile;

+  WinNtFindClose                      FindClose;

+  WinNtFlushFileBuffers               FlushFileBuffers;

+  WinNtGetEnvironmentVariable         GetEnvironmentVariable;

+  WinNtGetLastError                   GetLastError;

+  WinNtSetErrorMode                   SetErrorMode;

+  WinNtGetStdHandle                   GetStdHandle;

+  WinNtMapViewOfFileEx                MapViewOfFileEx;

+  WinNtReadFile                       ReadFile;

+  WinNtSetEndOfFile                   SetEndOfFile;

+  WinNtSetFilePointer                 SetFilePointer;

+  WinNtWriteFile                      WriteFile;

+  WinNtGetFileInformationByHandle     GetFileInformationByHandle;

+  WinNtGetDiskFreeSpace               GetDiskFreeSpace;

+  WinNtGetDiskFreeSpaceEx             GetDiskFreeSpaceEx;

+  WinNtMoveFile                       MoveFile;

+  WinNtSetFileTime                    SetFileTime;

+  WinNtSystemTimeToFileTime           SystemTimeToFileTime;

+

+  //

+  // Win32 Time APIs

+  //

+  WinNtFileTimeToLocalFileTime        FileTimeToLocalFileTime;

+  WinNtFileTimeToSystemTime           FileTimeToSystemTime;

+  WinNtGetSystemTime                  GetSystemTime;

+  WinNtSetSystemTime                  SetSystemTime;

+  WinNtGetLocalTime                   GetLocalTime;

+  WinNtSetLocalTime                   SetLocalTime;

+  WinNtGetTimeZoneInformation         GetTimeZoneInformation;

+  WinNtSetTimeZoneInformation         SetTimeZoneInformation;

+  WinNttimeSetEvent                   timeSetEvent;

+  WinNttimeKillEvent                  timeKillEvent;

+

+  //

+  // Win32 Serial APIs

+  //

+  WinNtClearCommError                 ClearCommError;

+  WinNtEscapeCommFunction             EscapeCommFunction;

+  WinNtGetCommModemStatus             GetCommModemStatus;

+  WinNtGetCommState                   GetCommState;

+  WinNtSetCommState                   SetCommState;

+  WinNtPurgeComm                      PurgeComm;

+  WinNtSetCommTimeouts                SetCommTimeouts;

+

+  WinNtExitProcess                    ExitProcess;

+

+  WinNtSprintf                        SPrintf;

+

+  WinNtGetDesktopWindow               GetDesktopWindow;

+  WinNtGetForegroundWindow            GetForegroundWindow;

+  WinNtCreateWindowEx                 CreateWindowEx;

+  WinNtShowWindow                     ShowWindow;

+  WinNtUpdateWindow                   UpdateWindow;

+  WinNtDestroyWindow                  DestroyWindow;

+  WinNtInvalidateRect                 InvalidateRect;

+  WinNtGetWindowDC                    GetWindowDC;

+  WinNtGetClientRect                  GetClientRect;

+  WinNtAdjustWindowRect               AdjustWindowRect;

+  WinNtSetDIBitsToDevice              SetDIBitsToDevice;

+  WinNtBitBlt                         BitBlt;

+  WinNtGetDC                          GetDC;

+  WinNtReleaseDC                      ReleaseDC;

+  WinNtRegisterClassEx                RegisterClassEx;

+  WinNtUnregisterClass                UnregisterClass;

+

+  WinNtBeginPaint                     BeginPaint;

+  WinNtEndPaint                       EndPaint;

+  WinNtPostQuitMessage                PostQuitMessage;

+  WinNtDefWindowProc                  DefWindowProc;

+  WinNtLoadIcon                       LoadIcon;

+  WinNtLoadCursor                     LoadCursor;

+  WinNtGetStockObject                 GetStockObject;

+  WinNtSetViewportOrgEx               SetViewportOrgEx;

+  WinNtSetWindowOrgEx                 SetWindowOrgEx;

+  WinNtMoveWindow                     MoveWindow;

+  WinNtGetWindowRect                  GetWindowRect;

+

+  WinNtGetMessage                     GetMessage;

+  WinNtTranslateMessage               TranslateMessage;

+  WinNtDispatchMessage                DispatchMessage;

+

+  WinNtGetProcessHeap                 GetProcessHeap;

+  WinNtHeapAlloc                      HeapAlloc;

+  WinNtHeapFree                       HeapFree;

+

+} EFI_WIN_NT_THUNK_PROTOCOL;

+

+extern EFI_GUID gEfiWinNtThunkProtocolGuid;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/WinNtDxe.h b/edk2/EdkNt32Pkg/Include/WinNtDxe.h
new file mode 100644
index 0000000..d82b2a2
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/WinNtDxe.h
@@ -0,0 +1,38 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  WinNtLib.h

+

+Abstract:

+  Public include file for the WinNt Library

+

+--*/

+

+#ifndef __WIN_NT_DXE_H__

+#define __WIN_NT_DXE_H__

+

+#include <Ppi/NtPeiLoadFile.h>

+#include <Ppi/NtAutoscan.h>

+#include <Ppi/NtThunk.h>

+#include <Ppi/NtFwh.h>

+

+//

+// This forces Windows.h WIN32 include file to be included

+//  it's needed for WinNtThunk.h

+//  WinNtIo.h depends on WinNtThunk.h

+//

+#include <Common/WinNtInclude.h>

+

+#include <Protocol/WinNtThunk.h>

+#include <Protocol/WinNtIo.h>

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/WinNtPeim.h b/edk2/EdkNt32Pkg/Include/WinNtPeim.h
new file mode 100644
index 0000000..0b2240b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/WinNtPeim.h
@@ -0,0 +1,36 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  WinNtLib.h

+

+Abstract:

+  Public include file for the WinNt Library

+

+--*/

+

+#ifndef __WIN_NT_PEIM_H__

+#define __WIN_NT_PEIM_H__

+

+#include <Ppi/NtPeiLoadFile.h>

+#include <Ppi/NtAutoscan.h>

+#include <Ppi/NtThunk.h>

+#include <Ppi/NtFwh.h>

+

+//

+// This forces Windows.h WIN32 include file to be included

+//  it's needed for WinNtThunk.h

+//

+#include <Common/WinNtInclude.h>

+

+#include <Protocol/WinNtThunk.h>

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h b/edk2/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h
new file mode 100644
index 0000000..3f01119
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h
@@ -0,0 +1,332 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsLib.h

+

+Abstract:

+

+  BDS library definition, include the file and data structure

+

+--*/

+

+#ifndef _BDS_LIB_H_

+#define _BDS_LIB_H_

+

+extern EFI_HANDLE mBdsImageHandle;

+

+//

+// Constants which are variable names used to access variables

+//

+#define VarLegacyDevOrder L"LegacyDevOrder"

+

+//

+// Data structures and defines

+//

+#define FRONT_PAGE_QUESTION_ID  0x0000

+#define FRONT_PAGE_DATA_WIDTH   0x01

+

+//

+// ConnectType

+//

+#define CONSOLE_OUT 0x00000001

+#define STD_ERROR   0x00000002

+#define CONSOLE_IN  0x00000004

+#define CONSOLE_ALL (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)

+

+//

+// Load Option Attributes defined in EFI Specification

+//

+#define LOAD_OPTION_ACTIVE              0x00000001

+#define LOAD_OPTION_FORCE_RECONNECT     0x00000002

+#define IS_LOAD_OPTION_TYPE(_c, _Mask)  (BOOLEAN) (((_c) & (_Mask)) != 0)

+

+//

+// Define Maxmim characters that will be accepted

+//

+#define MAX_CHAR            480

+#define MAX_CHAR_SIZE       (MAX_CHAR * 2)

+

+#define MIN_ALIGNMENT_SIZE  4

+#define ALIGN_SIZE(a)       ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)

+

+//

+// This data structure is the part of BDS_CONNECT_ENTRY that we can hard code.

+//

+#define BDS_LOAD_OPTION_SIGNATURE EFI_SIGNATURE_32 ('B', 'd', 'C', 'O')

+

+typedef struct {

+

+  UINTN                     Signature;

+  LIST_ENTRY                Link;

+

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+

+  CHAR16                    *OptionName;

+  UINTN                     OptionNumber;

+  UINT16                    BootCurrent;

+  UINT32                    Attribute;

+  CHAR16                    *Description;

+  VOID                      *LoadOptions;

+  UINT32                    LoadOptionsSize;

+

+} BDS_COMMON_OPTION;

+

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  UINTN                     ConnectType;

+} BDS_CONSOLE_CONNECT_ENTRY;

+

+//

+// Lib Functions

+//

+

+//

+// Bds boot relate lib functions

+//

+EFI_STATUS

+BdsLibUpdateBootOrderList (

+  IN  LIST_ENTRY                 *BdsOptionList,

+  IN  CHAR16                     *VariableName

+  );

+

+VOID

+BdsLibBootNext (

+  VOID

+  );

+

+EFI_STATUS

+BdsLibBootViaBootOption (

+  IN  BDS_COMMON_OPTION             * Option,

+  IN  EFI_DEVICE_PATH_PROTOCOL      * DevicePath,

+  OUT UINTN                         *ExitDataSize,

+  OUT CHAR16                        **ExitData OPTIONAL

+  );

+

+EFI_STATUS

+BdsLibEnumerateAllBootOption (

+  IN OUT LIST_ENTRY    *BdsBootOptionList

+  );

+

+VOID

+BdsLibBuildOptionFromHandle (

+  IN  EFI_HANDLE      Handle,

+  IN  LIST_ENTRY      *BdsBootOptionList

+  );

+

+VOID

+BdsLibBuildOptionFromShell (

+  IN  EFI_HANDLE                 Handle,

+  IN  LIST_ENTRY                 *BdsBootOptionList

+  );

+

+//

+// Bds misc lib functions

+//

+UINT16

+BdsLibGetTimeout (

+  VOID

+  );

+

+EFI_STATUS

+BdsLibGetBootMode (

+  OUT EFI_BOOT_MODE       *BootMode

+  );

+

+VOID

+BdsLibLoadDrivers (

+  IN  LIST_ENTRY          *BdsDriverLists

+  );

+

+EFI_STATUS

+BdsLibBuildOptionFromVar (

+  IN  LIST_ENTRY          *BdsCommonOptionList,

+  IN  CHAR16              *VariableName

+  );

+

+VOID                      *

+BdsLibGetVariableAndSize (

+  IN  CHAR16              *Name,

+  IN  EFI_GUID            *VendorGuid,

+  OUT UINTN               *VariableSize

+  );

+

+EFI_STATUS

+BdsLibOutputStrings (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *ConOut,

+  ...

+  );

+

+BDS_COMMON_OPTION         *

+BdsLibVariableToOption (

+  IN OUT LIST_ENTRY               *BdsCommonOptionList,

+  IN CHAR16                       *VariableName

+  );

+

+EFI_STATUS

+BdsLibRegisterNewOption (

+  IN  LIST_ENTRY                     *BdsOptionList,

+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,

+  IN  CHAR16                         *String,

+  IN  CHAR16                         *VariableName

+  );

+

+//

+// Bds connect or disconnect driver lib funcion

+//

+VOID

+BdsLibConnectAllDriversToAllControllers (

+  VOID

+  );

+

+VOID

+BdsLibConnectAll (

+  VOID

+  );

+

+EFI_STATUS

+BdsLibConnectDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect

+  );

+

+EFI_STATUS

+BdsLibConnectAllEfi (

+  VOID

+  );

+

+EFI_STATUS

+BdsLibDisconnectAllEfi (

+  VOID

+  );

+

+//

+// Bds console relate lib functions

+//

+VOID

+BdsLibConnectAllConsoles (

+  VOID

+  );

+

+EFI_STATUS

+BdsLibConnectAllDefaultConsoles (

+  VOID

+  );

+

+EFI_STATUS

+BdsLibUpdateConsoleVariable (

+  IN  CHAR16                    *ConVarName,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath

+  );

+

+EFI_STATUS

+BdsLibConnectConsoleVariable (

+  IN  CHAR16                 *ConVarName

+  );

+

+//

+// Bds device path relate lib functions

+//

+EFI_DEVICE_PATH_PROTOCOL  *

+BdsLibUnpackDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath

+  );

+

+BOOLEAN

+BdsLibMatchDevicePaths (

+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single

+  );

+

+CHAR16                    *

+DevicePathToStr (

+  EFI_DEVICE_PATH_PROTOCOL     *DevPath

+  );

+

+VOID                      *

+EfiLibGetVariable (

+  IN CHAR16               *Name,

+  IN EFI_GUID             *VendorGuid

+  );

+

+//

+// Internal definitions

+//

+typedef struct {

+  CHAR16  *str;

+  UINTN   len;

+  UINTN   maxlen;

+} POOL_PRINT;

+

+typedef struct {

+  UINT8 Type;

+  UINT8 SubType;

+  VOID (*Function) (POOL_PRINT *, VOID *);

+} DEVICE_PATH_STRING_TABLE;

+

+//

+// Internal functions

+//

+EFI_STATUS

+BdsBootByDiskSignatureAndPartition (

+  IN  BDS_COMMON_OPTION          * Option,

+  IN  HARDDRIVE_DEVICE_PATH      * HardDriveDevicePath,

+  IN  UINT32                     LoadOptionsSize,

+  IN  VOID                       *LoadOptions,

+  OUT UINTN                      *ExitDataSize,

+  OUT CHAR16                     **ExitData OPTIONAL

+  );

+

+//

+// Notes: EFI 64 shadow all option rom

+//

+#ifdef EFI64

+#define EFI64_SHADOW_ALL_LEGACY_ROM() ShadowAllOptionRom ();

+VOID

+ShadowAllOptionRom();

+#else

+#define EFI64_SHADOW_ALL_LEGACY_ROM()

+#endif

+

+//

+// BBS support macros and functions

+//

+#ifdef EFI32

+#define REFRESH_LEGACY_BOOT_OPTIONS \

+        BdsDeleteAllInvalidLegacyBootOptions ();\

+        BdsAddNonExistingLegacyBootOptions (); \

+        BdsUpdateLegacyDevOrder ()

+#else

+#define REFRESH_LEGACY_BOOT_OPTIONS

+#endif

+

+EFI_STATUS

+BdsDeleteAllInvalidLegacyBootOptions (

+  VOID

+  );

+

+EFI_STATUS

+BdsAddNonExistingLegacyBootOptions (

+  VOID

+  );

+

+EFI_STATUS

+BdsUpdateLegacyDevOrder (

+  VOID

+  );

+

+EFI_STATUS

+BdsRefreshBbsTableForBoot (

+  IN BDS_COMMON_OPTION        *Entry

+  );

+

+#endif // _BDS_LIB_H_

diff --git a/edk2/EdkNt32Pkg/Include/library/WinNtLib.h b/edk2/EdkNt32Pkg/Include/library/WinNtLib.h
new file mode 100644
index 0000000..b9bccfc
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Include/library/WinNtLib.h
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtLib.h

+

+Abstract:

+

+  Public include file for the WinNt Library

+

+--*/

+

+#ifndef __WIN_NT_LIB_H__

+#define __WIN_NT_LIB_H__

+

+extern EFI_WIN_NT_THUNK_PROTOCOL  *gWinNt;

+

+#endif
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.mbd b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.mbd
new file mode 100644
index 0000000..a054a89
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeWinNtLib</BaseName>

+    <Guid>f6b5871d-5226-41b3-a569-3ff893fdc7bc</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-31 13:20</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.msa b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.msa
new file mode 100644
index 0000000..0747c75
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeWinNtLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>f6b5871d-5226-41b3-a569-3ff893fdc7bc</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-31 13:20</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">WinNtLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">WinNtThunk</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>WinNtLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Library/DxeWinNtLib/WinNtLib.c b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/WinNtLib.c
new file mode 100644
index 0000000..9010d8a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/WinNtLib.c
@@ -0,0 +1,48 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtLib.c

+

+Abstract:

+

+  WinNt Library 

+

+--*/

+

+

+

+EFI_WIN_NT_THUNK_PROTOCOL *gWinNt;

+

+EFI_STATUS

+WinNtLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_HOB_GUID_TYPE        *GuidHob;

+

+  GuidHob = GetFirstGuidHob (&gEfiWinNtThunkProtocolGuid);

+  ASSERT (GuidHob != NULL);

+  gWinNt = (EFI_WIN_NT_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));

+  ASSERT (gWinNt != NULL);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Library/DxeWinNtLib/build.xml b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/build.xml
new file mode 100644
index 0000000..5d4ab2c
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/DxeWinNtLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeWinNtLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library\DxeWinNtLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="DxeWinNtLib">

+      <GenBuild baseName="DxeWinNtLib" mbdFilename="${MODULE_DIR}\DxeWinNtLib.mbd" msaFilename="${MODULE_DIR}\DxeWinNtLib.msa"/>

+   </target>

+   <target depends="DxeWinNtLib_clean" name="clean"/>

+   <target depends="DxeWinNtLib_cleanall" name="cleanall"/>

+   <target name="DxeWinNtLib_clean">

+      <OutputDirSetup baseName="DxeWinNtLib" mbdFilename="${MODULE_DIR}\DxeWinNtLib.mbd" msaFilename="${MODULE_DIR}\DxeWinNtLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\DxeWinNtLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\DxeWinNtLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeWinNtLib_cleanall">

+      <OutputDirSetup baseName="DxeWinNtLib" mbdFilename="${MODULE_DIR}\DxeWinNtLib.mbd" msaFilename="${MODULE_DIR}\DxeWinNtLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\DxeWinNtLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\DxeWinNtLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeWinNtLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c
new file mode 100644
index 0000000..c9b1eed
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsBoot.c
@@ -0,0 +1,795 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsBoot.c

+

+Abstract:

+

+  BDS Lib functions which relate with create or process the boot

+  option.

+

+--*/

+#include "Performance.h"

+

+BOOLEAN mEnumBootDevice = FALSE;

+

+EFI_STATUS

+BdsLibDoLegacyBoot (

+  IN  BDS_COMMON_OPTION           *Option

+  )

+/*++

+

+Routine Description:

+ 

+  Boot the legacy system with the boot option

+

+Arguments:

+

+  Option           - The legacy boot option which have BBS device path

+

+Returns:

+

+  EFI_UNSUPPORTED  - There is no legacybios protocol, do not support

+                     legacy boot.

+                         

+  EFI_STATUS       - Return the status of LegacyBios->LegacyBoot ().

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+

+  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);

+  if (EFI_ERROR (Status)) {

+    //

+    // If no LegacyBios protocol we do not support legacy boot

+    //

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Notes: if we seperate the int 19, then we don't need to refresh BBS

+  //

+  BdsRefreshBbsTableForBoot (Option);

+

+  //

+  // Write boot to OS performance data to a file

+  //

+  PERF_CODE (

+    WriteBootToOsPerformanceData ();

+  );

+

+

+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Legacy Boot: %S\n", Option->Description));

+  return LegacyBios->LegacyBoot (

+                      LegacyBios,

+                      (BBS_BBS_DEVICE_PATH *) Option->DevicePath,

+                      Option->LoadOptionsSize,

+                      Option->LoadOptions

+                      );

+}

+

+EFI_STATUS

+BdsLibBootViaBootOption (

+  IN  BDS_COMMON_OPTION             * Option,

+  IN  EFI_DEVICE_PATH_PROTOCOL      * DevicePath,

+  OUT UINTN                         *ExitDataSize,

+  OUT CHAR16                        **ExitData OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Process the boot option follow the EFI 1.1 specification and 

+  special treat the legacy boot option with BBS_DEVICE_PATH.

+

+Arguments:

+

+  Option       - The boot option need to be processed

+  

+  DevicePath   - The device path which describe where to load 

+                 the boot image or the legcy BBS device path 

+                 to boot the legacy OS

+

+  ExitDataSize - Returned directly from gBS->StartImage ()

+

+  ExitData     - Returned directly from gBS->StartImage ()

+

+Returns:

+

+  EFI_SUCCESS   - Status from gBS->StartImage (),

+                  or BdsBootByDiskSignatureAndPartition ()

+

+  EFI_NOT_FOUND - If the Device Path is not found in the system

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_HANDLE                Handle;

+  EFI_HANDLE                ImageHandle;

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *FilePath;

+  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;

+  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;

+

+  *ExitDataSize = 0;

+  *ExitData     = NULL;

+

+  //

+  // Notes: put EFI64 ROM Shadow Solution

+  //

+  EFI64_SHADOW_ALL_LEGACY_ROM ();

+

+  //

+  // Notes: this code can be remove after the s3 script table

+  // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or

+  // EFI_EVENT_SIGNAL_LEGACY_BOOT

+  //

+  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, &AcpiS3Save);

+  if (!EFI_ERROR (Status)) {

+    AcpiS3Save->S3Save (AcpiS3Save, NULL);

+  }

+  //

+  // If it's Device Path that starts with a hard drive path,

+  // this routine will do the booting.

+  //

+  Status = BdsBootByDiskSignatureAndPartition (

+            Option,

+            (HARDDRIVE_DEVICE_PATH *) DevicePath,

+            Option->LoadOptionsSize,

+            Option->LoadOptions,

+            ExitDataSize,

+            ExitData

+            );

+  if (!EFI_ERROR (Status)) {

+    //

+    // If we found a disk signature and partition device path return success

+    //

+    return EFI_SUCCESS;

+  }

+

+  EfiSignalEventReadyToBoot ();

+

+  //

+  // Set Boot Current

+  //

+  gRT->SetVariable (

+        L"BootCurrent",

+        &gEfiGlobalVariableGuid,

+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+        sizeof (UINT16),

+        &Option->BootCurrent

+        );

+

+  if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&

+      (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)

+    ) {

+    //

+    // Check to see if we should legacy BOOT. If yes then do the legacy boot

+    //

+    return BdsLibDoLegacyBoot (Option);

+  }

+

+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Booting EFI 1.1 way %S\n", Option->Description));

+

+  Status = gBS->LoadImage (

+                  TRUE,

+                  mBdsImageHandle,

+                  DevicePath,

+                  NULL,

+                  0,

+                  &ImageHandle

+                  );

+

+  //

+  // If we didn't find an image, we may need to load the default

+  // boot behavior for the device.

+  //

+  if (EFI_ERROR (Status)) {

+    //

+    // Find a Simple File System protocol on the device path. If the remaining

+    // device path is set to end then no Files are being specified, so try

+    // the removable media file name.

+    //

+    TempDevicePath = DevicePath;

+    Status = gBS->LocateDevicePath (

+                    &gEfiSimpleFileSystemProtocolGuid,

+                    &TempDevicePath,

+                    &Handle

+                    );

+    if (!EFI_ERROR (Status) && IsDevicePathEnd (TempDevicePath)) {

+      FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);

+      if (FilePath) {

+        Status = gBS->LoadImage (

+                        TRUE,

+                        mBdsImageHandle,

+                        FilePath,

+                        NULL,

+                        0,

+                        &ImageHandle

+                        );

+        if (EFI_ERROR (Status)) {

+          //

+          // The DevicePath failed, and it's not a valid

+          // removable media device.

+          //

+          goto Done;

+        }

+      }

+    } else {

+      Status = EFI_NOT_FOUND;

+    }

+  }

+

+  if (EFI_ERROR (Status)) {

+    //

+    // It there is any error from the Boot attempt exit now.

+    //

+    goto Done;

+  }

+  //

+  // Provide the image with it's load options

+  //

+  Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, &ImageInfo);

+  ASSERT_EFI_ERROR (Status);

+

+  if (Option->LoadOptionsSize != 0) {

+    ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;

+    ImageInfo->LoadOptions      = Option->LoadOptions;

+  }

+  //

+  // Before calling the image, enable the Watchdog Timer for

+  // the 5 Minute period

+  //

+  gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);

+

+  Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);

+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Image Return Status = %r\n", Status));

+

+  //

+  // Clear the Watchdog Timer after the image returns

+  //

+  gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);

+

+Done:

+  //

+  // Clear Boot Current

+  //

+  gRT->SetVariable (

+        L"BootCurrent",

+        &gEfiGlobalVariableGuid,

+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+        0,

+        &Option->BootCurrent

+        );

+

+  return Status;

+}

+

+EFI_STATUS

+BdsBootByDiskSignatureAndPartition (

+  IN  BDS_COMMON_OPTION          * Option,

+  IN  HARDDRIVE_DEVICE_PATH      * HardDriveDevicePath,

+  IN  UINT32                     LoadOptionsSize,

+  IN  VOID                       *LoadOptions,

+  OUT UINTN                      *ExitDataSize,

+  OUT CHAR16                     **ExitData OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Check to see if a hard ware device path was passed in. If it was then search

+  all the block IO devices for the passed in hard drive device path. 

+  

+Arguments:

+

+  Option - The current processing boot option.

+

+  HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard

+                        drive device path.

+

+  LoadOptionsSize - Passed into gBS->StartImage ()

+                    via the loaded image protocol.

+

+  LoadOptions     - Passed into gBS->StartImage ()

+                    via the loaded image protocol.

+

+  ExitDataSize - returned directly from gBS->StartImage ()

+

+  ExitData     - returned directly from gBS->StartImage ()

+

+Returns:

+

+  EFI_SUCCESS   - Status from gBS->StartImage (),

+                  or BootByDiskSignatureAndPartition ()

+                  

+  EFI_NOT_FOUND - If the Device Path is not found in the system

+

+--*/

+{

+  EFI_STATUS                Status;

+  UINTN                     BlockIoHandleCount;

+  EFI_HANDLE                *BlockIoBuffer;

+  EFI_DEVICE_PATH_PROTOCOL  *BlockIoDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *BlockIoHdDevicePath;

+  HARDDRIVE_DEVICE_PATH     *TmpHdPath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  UINTN                     Index;

+  BOOLEAN                   DevicePathMatch;

+  HARDDRIVE_DEVICE_PATH     *TempPath;

+

+  *ExitDataSize = 0;

+  *ExitData     = NULL;

+

+  if ( !((DevicePathType (&HardDriveDevicePath->Header) == MEDIA_DEVICE_PATH) &&

+          (DevicePathSubType (&HardDriveDevicePath->Header) == MEDIA_HARDDRIVE_DP))

+        ) {

+    //

+    // If the HardDriveDevicePath does not start with a Hard Drive Device Path

+    // exit.

+    //

+    return EFI_NOT_FOUND;

+  }

+  //

+  // The boot device have already been connected

+  //

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);

+  if (EFI_ERROR (Status) || BlockIoHandleCount == 0) {

+    //

+    // If there was an error or there are no device handles that support

+    // the BLOCK_IO Protocol, then return.

+    //

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Loop through all the device handles that support the BLOCK_IO Protocol

+  //

+  for (Index = 0; Index < BlockIoHandleCount; Index++) {

+

+    Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);

+    if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {

+      continue;

+    }

+    //

+    // Make PreviousDevicePath == the device path node before the end node

+    //

+    DevicePath          = BlockIoDevicePath;

+    BlockIoHdDevicePath = NULL;

+

+    //

+    // find HardDriver device path node

+    //

+    while (!IsDevicePathEnd (DevicePath)) {

+      if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && 

+          (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)

+          ) {

+        BlockIoHdDevicePath = DevicePath;

+        break;

+      }

+

+      DevicePath = NextDevicePathNode (DevicePath);

+    }

+

+    if (BlockIoHdDevicePath == NULL) {

+      continue;

+    }

+    //

+    // See if the harddrive device path in blockio matches the orig Hard Drive Node

+    //

+    DevicePathMatch = FALSE;

+

+    TmpHdPath       = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePath;

+    TempPath        = (HARDDRIVE_DEVICE_PATH *) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);

+

+    //

+    // Only several fields will be checked. NOT whole NODE

+    //

+    if ( TmpHdPath->PartitionNumber == TempPath->PartitionNumber &&

+        TmpHdPath->MBRType == TempPath->MBRType &&

+        TmpHdPath->SignatureType == TempPath->SignatureType &&

+        CompareGuid ((EFI_GUID *) TmpHdPath->Signature, (EFI_GUID *) TempPath->Signature)) {

+      //

+      // Get the matched device path

+      //

+      DevicePathMatch = TRUE;

+    }

+    //

+    // Only do the boot, when devicepath match

+    //

+    if (DevicePathMatch) {

+      //

+      // Combine the Block IO and Hard Drive Device path together and try

+      // to boot from it.

+      //

+      DevicePath    = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);

+      NewDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);

+

+      //

+      // Recursive boot with new device path

+      //

+      Status = BdsLibBootViaBootOption (Option, NewDevicePath, ExitDataSize, ExitData);

+      if (!EFI_ERROR (Status)) {

+        break;

+      }

+    }

+  }

+

+  gBS->FreePool (BlockIoBuffer);

+  return Status;

+}

+

+EFI_STATUS

+BdsLibEnumerateAllBootOption (

+  IN OUT LIST_ENTRY      *BdsBootOptionList

+  )

+/*++

+

+Routine Description:

+

+  This function will enumerate all possible boot device in the system,

+  it will only excute once of every boot.

+

+Arguments:

+

+  BdsBootOptionList - The header of the link list which indexed all

+                      current boot options

+

+Returns:

+

+  EFI_SUCCESS - Finished all the boot device enumerate and create

+                the boot option base on that boot device

+

+--*/

+{

+  EFI_STATUS                    Status;

+  UINT16                        BootOptionNumber;

+  UINTN                         NumberFileSystemHandles;

+  EFI_HANDLE                    *FileSystemHandles;

+  UINTN                         NumberBlkIoHandles;

+  EFI_HANDLE                    *BlkIoHandles;

+  EFI_BLOCK_IO_PROTOCOL         *BlkIo;

+  UINTN                         Index;

+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;

+  UINTN                         NumberLoadFileHandles;

+  EFI_HANDLE                    *LoadFileHandles;

+  VOID                          *ProtocolInstance;

+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;

+  UINTN                         FvHandleCount;

+  EFI_HANDLE                    *FvHandleBuffer;

+  EFI_FV_FILETYPE               Type;

+  UINTN                         Size;

+  EFI_FV_FILE_ATTRIBUTES        Attributes;

+  UINT32                        AuthenticationStatus;

+

+  BootOptionNumber = 0;

+

+  //

+  // If the boot device enumerate happened, just get the boot

+  // device from the boot order variable

+  //

+  if (mEnumBootDevice) {

+    BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");

+    return EFI_SUCCESS;

+  }

+  //

+  // Notes: this dirty code is to get the legacy boot option from the

+  // BBS table and create to variable as the EFI boot option, it should

+  // be removed after the CSM can provide legacy boot option directly

+  //

+  REFRESH_LEGACY_BOOT_OPTIONS;

+

+  //

+  // Check all the block IO to create boot option

+  //

+  gBS->LocateHandleBuffer (

+        ByProtocol,

+        &gEfiBlockIoProtocolGuid,

+        NULL,

+        &NumberBlkIoHandles,

+        &BlkIoHandles

+        );

+  for (Index = 0; Index < NumberBlkIoHandles; Index++) {

+    Status = gBS->HandleProtocol (

+                    BlkIoHandles[Index],

+                    &gEfiBlockIoProtocolGuid,

+                    (VOID **) &BlkIo

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    if (!BlkIo->Media->RemovableMedia) {

+      //

+      // Skip fixed Media device on first loop interration

+      //

+      continue;

+    }

+

+    DevicePath = DevicePathFromHandle (BlkIoHandles[Index]);

+    if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && 

+        (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)

+        ) {

+      //

+      // Build the boot option

+      //

+      BdsLibBuildOptionFromHandle (BlkIoHandles[Index], BdsBootOptionList);

+      BootOptionNumber++;

+    }

+  }

+

+  if (NumberBlkIoHandles) {

+    gBS->FreePool (BlkIoHandles);

+  }

+  //

+  // Parse Fixed Disk Devices.

+  //

+  gBS->LocateHandleBuffer (

+        ByProtocol,

+        &gEfiSimpleFileSystemProtocolGuid,

+        NULL,

+        &NumberFileSystemHandles,

+        &FileSystemHandles

+        );

+  for (Index = 0; Index < NumberFileSystemHandles; Index++) {

+    Status = gBS->HandleProtocol (

+                    FileSystemHandles[Index],

+                    &gEfiBlockIoProtocolGuid,

+                    (VOID **) &BlkIo

+                    );

+    if (!EFI_ERROR (Status)) {

+      if (BlkIo->Media->RemovableMedia) {

+        //

+        // If the file system handle supports a BlkIo protocol,

+        // skip the removable media devices

+        //

+        continue;

+      }

+    }

+

+    DevicePath = DevicePathFromHandle (FileSystemHandles[Index]);

+    if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && 

+        (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)

+        ) {

+      //

+      // If the FileSystem protocol does not contain a BlkIo protocol,

+      // then build it

+      //

+      BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList);

+      BootOptionNumber++;

+    }

+  }

+

+  if (NumberFileSystemHandles) {

+    gBS->FreePool (FileSystemHandles);

+  }

+  //

+  // Parse Network Boot Device

+  //

+  gBS->LocateHandleBuffer (

+        ByProtocol,

+        &gEfiSimpleNetworkProtocolGuid,

+        NULL,

+        &NumberLoadFileHandles,

+        &LoadFileHandles

+        );

+  for (Index = 0; Index < NumberLoadFileHandles; Index++) {

+    Status = gBS->HandleProtocol (

+                    LoadFileHandles[Index],

+                    &gEfiLoadFileProtocolGuid,

+                    (VOID **) &ProtocolInstance

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList);

+    BootOptionNumber++;

+  }

+

+  if (NumberLoadFileHandles) {

+    gBS->FreePool (LoadFileHandles);

+  }

+  //

+  // Check if we have on flash shell

+  //

+  gBS->LocateHandleBuffer (

+        ByProtocol,

+        &gEfiFirmwareVolumeProtocolGuid,

+        NULL,

+        &FvHandleCount,

+        &FvHandleBuffer

+        );

+  for (Index = 0; Index < FvHandleCount; Index++) {

+    gBS->HandleProtocol (

+          FvHandleBuffer[Index],

+          &gEfiFirmwareVolumeProtocolGuid,

+          (VOID **) &Fv

+          );

+

+    Status = Fv->ReadFile (

+                  Fv,

+                  &gEfiShellFileGuid,

+                  NULL,

+                  &Size,

+                  &Type,

+                  &Attributes,

+                  &AuthenticationStatus

+                  );

+    if (EFI_ERROR (Status)) {

+      //

+      // Skip if no shell file in the FV

+      //

+      continue;

+    }

+    //

+    // Build the shell boot option

+    //

+    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);

+    BootOptionNumber++;

+  }

+

+  if (FvHandleCount) {

+    gBS->FreePool (FvHandleBuffer);

+  }

+  //

+  // Make sure every boot only have one time

+  // boot device enumerate

+  //

+  BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");

+  mEnumBootDevice = TRUE;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+BdsLibBuildOptionFromHandle (

+  IN  EFI_HANDLE             Handle,

+  IN  LIST_ENTRY             *BdsBootOptionList

+  )

+/*++

+

+Routine Description:

+  

+  Build the boot option with the handle parsed in

+  

+Arguments:

+

+  Handle - The handle which present the device path to create boot option

+  

+  BdsBootOptionList - The header of the link list which indexed all current

+                      boot options

+

+Returns:

+

+  VOID

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  CHAR16                    *TempString;

+

+  DevicePath  = DevicePathFromHandle (Handle);

+  TempString  = DevicePathToStr (DevicePath);

+

+  //

+  // Create and register new boot option

+  //

+  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, TempString, L"BootOrder");

+}

+

+VOID

+BdsLibBuildOptionFromShell (

+  IN EFI_HANDLE              Handle,

+  IN OUT LIST_ENTRY          *BdsBootOptionList

+  )

+/*++

+

+Routine Description:

+  

+  Build the on flash shell boot option with the handle parsed in

+  

+Arguments:

+

+  Handle - The handle which present the device path to create on flash shell

+           boot option

+  

+  BdsBootOptionList - The header of the link list which indexed all current

+                      boot options

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;

+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;

+

+  DevicePath = DevicePathFromHandle (Handle);

+

+  //

+  // Build the shell device path

+  //

+  EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid);

+  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);

+

+  //

+  // Create and register the shell boot option

+  //

+  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"Internal EFI Shell", L"BootOrder");

+

+}

+

+VOID

+BdsLibBootNext (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Boot from the EFI1.1 spec defined "BootNext" variable

+  

+Arguments:

+

+  None

+  

+Returns:

+

+  None

+

+--*/

+{

+  UINT16            *BootNext;

+  UINTN             BootNextSize;

+  CHAR16            Buffer[20];

+  BDS_COMMON_OPTION *BootOption;

+  LIST_ENTRY        TempList;

+  UINTN             ExitDataSize;

+  CHAR16            *ExitData;

+

+  //

+  // Init the boot option name buffer and temp link list

+  //

+  InitializeListHead (&TempList);

+  ZeroMem (Buffer, sizeof (Buffer));

+

+  BootNext = BdsLibGetVariableAndSize (

+              L"BootNext",

+              &gEfiGlobalVariableGuid,

+              &BootNextSize

+              );

+

+  //

+  // Clear the boot next variable first

+  //

+  if (BootNext != NULL) {

+    gRT->SetVariable (

+          L"BootNext",

+          &gEfiGlobalVariableGuid,

+          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+          0,

+          BootNext

+          );

+

+    //

+    // Start to build the boot option and try to boot

+    //

+    UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);

+    BootOption = BdsLibVariableToOption (&TempList, Buffer);

+    BdsLibConnectDevicePath (BootOption->DevicePath);

+    BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);

+  }

+

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConnect.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConnect.c
new file mode 100644
index 0000000..9c649f1
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConnect.c
@@ -0,0 +1,357 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsConnect.c

+

+Abstract:

+

+  BDS Lib functions which relate with connect the device

+

+--*/

+

+VOID

+BdsLibConnectAll (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  This function will connect all the system driver to controller

+  first, and then special connect the default console, this make

+  sure all the system controller avialbe and the platform default

+  console connected.

+  

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  //

+  // Connect the platform console first

+  //

+  BdsLibConnectAllDefaultConsoles ();

+

+  //

+  // Generic way to connect all the drivers

+  //

+  BdsLibConnectAllDriversToAllControllers ();

+

+  //

+  // Here we have the assumption that we have already had

+  // platform default console

+  //

+  BdsLibConnectAllDefaultConsoles ();

+}

+

+VOID

+BdsLibGenericConnectAll (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  This function will connect all the system drivers to all controllers

+  first, and then connect all the console devices the system current 

+  have. After this we should get all the device work and console avariable

+  if the system have console device.

+  

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  //

+  // Most generic way to connect all the drivers

+  //

+  BdsLibConnectAllDriversToAllControllers ();

+  BdsLibConnectAllConsoles ();

+}

+

+EFI_STATUS

+BdsLibConnectDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect

+  )

+/*++

+

+Routine Description:

+  This function will create all handles associate with every device

+  path node. If the handle associate with one device path node can not

+  be created success, then still give one chance to do the dispatch,

+  which load the missing drivers if possible.

+  

+Arguments:

+

+  DevicePathToConnect  - The device path which will be connected, it can

+                         be a multi-instance device path

+

+Returns:

+

+  EFI_SUCCESS          - All handles associate with every device path 

+                         node have been created

+  

+  EFI_OUT_OF_RESOURCES - There is no resource to create new handles

+  

+  EFI_NOT_FOUND        - Create the handle associate with one device 

+                         path node failed

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *Instance;

+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *Next;

+  EFI_HANDLE                Handle;

+  EFI_HANDLE                PreviousHandle;

+  UINTN                     Size;

+

+  if (DevicePathToConnect == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  DevicePath        = DuplicateDevicePath (DevicePathToConnect);

+  CopyOfDevicePath  = DevicePath;

+  if (DevicePath == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  do {

+    //

+    // The outer loop handles multi instance device paths.

+    // Only console variables contain multiple instance device paths.

+    //

+    // After this call DevicePath points to the next Instance

+    //

+    Instance  = GetNextDevicePathInstance (&DevicePath, &Size);

+    Next      = Instance;

+    while (!IsDevicePathEndType (Next)) {

+      Next = NextDevicePathNode (Next);

+    }

+

+    SetDevicePathEndNode (Next);

+

+    //

+    // Start the real work of connect with RemainingDevicePath

+    //

+    PreviousHandle = NULL;

+    do {

+      //

+      // Find the handle that best matches the Device Path. If it is only a

+      // partial match the remaining part of the device path is returned in

+      // RemainingDevicePath.

+      //

+      RemainingDevicePath = Instance;

+      Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);

+

+      if (!EFI_ERROR (Status)) {

+        if (Handle == PreviousHandle) {

+          //

+          // If no forward progress is made try invoking the Dispatcher.

+          // A new FV may have been added to the system an new drivers

+          // may now be found.

+          // Status == EFI_SUCCESS means a driver was dispatched

+          // Status == EFI_NOT_FOUND means no new drivers were dispatched

+          //

+          Status = gDS->Dispatch ();

+        }

+

+        if (!EFI_ERROR (Status)) {

+          PreviousHandle = Handle;

+          //

+          // Connect all drivers that apply to Handle and RemainingDevicePath,

+          // the Recursive flag is FALSE so only one level will be expanded.

+          //

+          // Do not check the connect status here, if the connect controller fail,

+          // then still give the chance to do dispatch, because partial

+          // RemainingDevicepath may be in the new FV

+          //

+          // 1. If the connect fail, RemainingDevicepath and handle will not

+          //    change, so next time will do the dispatch, then dispatch's status

+          //    will take effect

+          // 2. If the connect success, the RemainingDevicepath and handle will

+          //    change, then avoid the dispatch, we have chance to continue the

+          //    next connection

+          //

+          gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);

+        }

+      }

+      //

+      // Loop until RemainingDevicePath is an empty device path

+      //

+    } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));

+

+  } while (DevicePath != NULL);

+

+  if (CopyOfDevicePath != NULL) {

+    gBS->FreePool (CopyOfDevicePath);

+  }

+  //

+  // All handle with DevicePath exists in the handle database

+  //

+  return Status;

+}

+

+EFI_STATUS

+BdsLibConnectAllEfi (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function will connect all current system handles recursively. The

+  connection will finish until every handle's child handle created if it have.

+  

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_SUCCESS          - All handles and it's child handle have been connected

+  

+  EFI_STATUS           - Return the status of gBS->LocateHandleBuffer(). 

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       HandleCount;

+  EFI_HANDLE  *HandleBuffer;

+  UINTN       Index;

+

+  Status = gBS->LocateHandleBuffer (

+                  AllHandles,

+                  NULL,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);

+  }

+

+  gBS->FreePool (HandleBuffer);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLibDisconnectAllEfi (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function will disconnect all current system handles. The disconnection

+  will finish until every handle have been disconnected.

+  

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_SUCCESS          - All handles have been disconnected

+  

+  EFI_STATUS           - Return the status of gBS->LocateHandleBuffer(). 

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       HandleCount;

+  EFI_HANDLE  *HandleBuffer;

+  UINTN       Index;

+

+  //

+  // Disconnect all

+  //

+  Status = gBS->LocateHandleBuffer (

+                  AllHandles,

+                  NULL,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);

+  }

+

+  gBS->FreePool (HandleBuffer);

+

+  return EFI_SUCCESS;

+}

+

+VOID

+BdsLibConnectAllDriversToAllControllers (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Connects all drivers to all controllers. 

+  This function make sure all the current system driver will manage

+  the correspoinding controllers if have. And at the same time, make

+  sure all the system controllers have driver to manage it if have. 

+  

+Arguments:

+  

+  None

+  

+Returns:

+  

+  None

+  

+--*/

+{

+  EFI_STATUS  Status;

+

+  do {

+    //

+    // Connect All EFI 1.10 drivers following EFI 1.10 algorithm

+    //

+    BdsLibConnectAllEfi ();

+

+    //

+    // Check to see if it's possible to dispatch an more DXE drivers.

+    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.

+    // If anything is Dispatched Status == EFI_SUCCESS and we will try

+    // the connect again.

+    //

+    Status = gDS->Dispatch ();

+

+  } while (!EFI_ERROR (Status));

+

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c
new file mode 100644
index 0000000..721d743
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c
@@ -0,0 +1,370 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsConsole.c

+

+Abstract:

+

+  BDS Lib functions which contain all the code to connect console device

+

+--*/

+

+EFI_STATUS

+BdsLibUpdateConsoleVariable (

+  IN  CHAR16                    *ConVarName,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath

+  )

+/*++

+

+Routine Description:

+

+  This function update console variable based on ConVarName, it can 

+  add or remove one specific console device path from the variable

+

+Arguments:

+

+  ConVarName   - Console related variable name, ConIn, ConOut, ErrOut.

+

+  CustomizedConDevicePath - The console device path which will be added to

+                            the console variable ConVarName, this parameter

+                            can not be multi-instance.

+

+  ExclusiveDevicePath     - The console device path which will be removed

+                            from the console variable ConVarName, this

+                            parameter can not be multi-instance.

+

+Returns:

+

+  EFI_UNSUPPORTED         - Add or remove the same device path.

+  

+  EFI_SUCCESS             - Success add or remove the device path from 

+                            the console variable.

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;

+  UINTN                     DevicePathSize;

+  EFI_DEVICE_PATH_PROTOCOL  *Instance;

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+

+  VarConsole      = NULL;

+  DevicePathSize  = 0;

+  NewDevicePath   = NULL;

+  Status          = EFI_UNSUPPORTED;

+

+  //

+  // Notes: check the device path point, here should check

+  // with compare memory

+  //

+  if (CustomizedConDevicePath == ExclusiveDevicePath) {

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Delete the ExclusiveDevicePath from current default console

+  //

+  VarConsole = BdsLibGetVariableAndSize (

+                ConVarName,

+                &gEfiGlobalVariableGuid,

+                &DevicePathSize

+                );

+

+  if (ExclusiveDevicePath != NULL && VarConsole != NULL) {

+    if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {

+

+      Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);

+

+      while (VarConsole != NULL) {

+        if (CompareMem (

+              Instance,

+              ExclusiveDevicePath,

+              DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)

+              ) == 0) {

+          //

+          // Remove the match part

+          //

+          NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);

+          break;

+        } else {

+          //

+          // Continue the next instance

+          //

+          NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);

+        }

+

+        Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);

+      }

+      //

+      // Reset the console variable with new device path

+      //

+      gRT->SetVariable (

+            ConVarName,

+            &gEfiGlobalVariableGuid,

+            EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+            GetDevicePathSize (NewDevicePath),

+            NewDevicePath

+            );

+    }

+  }

+  //

+  // Try to append customized device path

+  //

+  VarConsole = BdsLibGetVariableAndSize (

+                ConVarName,

+                &gEfiGlobalVariableGuid,

+                &DevicePathSize

+                );

+

+  if (CustomizedConDevicePath != NULL) {

+    if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {

+      //

+      // In the first check, the default console variable will be null,

+      // just append current customized device path

+      //

+      VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);

+

+      //

+      // Update the variable of the default console

+      //

+      gRT->SetVariable (

+            ConVarName,

+            &gEfiGlobalVariableGuid,

+            EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+            GetDevicePathSize (VarConsole),

+            VarConsole

+            );

+    }

+  }

+

+  return EFI_SUCCESS;

+

+}

+

+EFI_STATUS

+BdsLibConnectConsoleVariable (

+  IN  CHAR16                 *ConVarName

+  )

+/*++

+

+Routine Description:

+

+  Connect the console device base on the variable ConVarName, if

+  device path of the ConVarName is multi-instance device path, if

+  anyone of the instances is connected success, then this function

+  will return success.

+

+Arguments:

+

+  ConVarName   - Console related variable name, ConIn, ConOut, ErrOut.

+

+Returns:

+

+  EFI_NOT_FOUND           - There is not any console devices connected success

+  

+  EFI_SUCCESS             - Success connect any one instance of the console

+                            device path base on the variable ConVarName.

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;

+  UINTN                     VariableSize;

+  EFI_DEVICE_PATH_PROTOCOL  *Instance;

+  EFI_DEVICE_PATH_PROTOCOL  *Next;

+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;

+  UINTN                     Size;

+  BOOLEAN                   DeviceExist;

+

+  Status      = EFI_SUCCESS;

+  DeviceExist = FALSE;

+

+  //

+  // Check if the console variable exist

+  //

+  StartDevicePath = BdsLibGetVariableAndSize (

+                      ConVarName,

+                      &gEfiGlobalVariableGuid,

+                      &VariableSize

+                      );

+  if (StartDevicePath == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);

+  do {

+    //

+    // Check every instance of the console variable

+    //

+    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);

+    Next      = Instance;

+    while (!IsDevicePathEndType (Next)) {

+      Next = NextDevicePathNode (Next);

+    }

+

+    SetDevicePathEndNode (Next);

+

+    //

+    // Connect the instance device path

+    //

+    Status = BdsLibConnectDevicePath (Instance);

+    if (EFI_ERROR (Status)) {

+      //

+      // Delete the instance from the console varialbe

+      //

+      BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);

+    } else {

+      DeviceExist = TRUE;

+    }

+

+  } while (CopyOfDevicePath != NULL);

+

+  gBS->FreePool (StartDevicePath);

+

+  if (DeviceExist == FALSE) {

+    return EFI_NOT_FOUND;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+BdsLibConnectAllConsoles (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function will search every simpletxt devive in current system,

+  and make every simpletxt device as pertantial console device.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                Status;

+  UINTN                     Index;

+  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;

+  UINTN                     HandleCount;

+  EFI_HANDLE                *HandleBuffer;

+

+  Index         = 0;

+  HandleCount   = 0;

+  HandleBuffer  = NULL;

+  ConDevicePath = NULL;

+

+  //

+  // Update all the console varables

+  //

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiSimpleTextInProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  for (Index = 0; Index < HandleCount; Index++) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[Index],

+                    &gEfiDevicePathProtocolGuid,

+                    (VOID **) &ConDevicePath

+                    );

+    BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);

+  }

+

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  for (Index = 0; Index < HandleCount; Index++) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[Index],

+                    &gEfiDevicePathProtocolGuid,

+                    (VOID **) &ConDevicePath

+                    );

+    BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);

+    BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);

+  }

+  //

+  // Connect all console variables

+  //

+  BdsLibConnectAllDefaultConsoles ();

+

+}

+

+EFI_STATUS

+BdsLibConnectAllDefaultConsoles (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function will connect console device base on the console 

+  device variable ConIn, ConOut and ErrOut.

+

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_SUCCESS      - At least one of the ConIn and ConOut device have

+                     been connected success.

+                     

+  EFI_STATUS       - Return the status of BdsLibConnectConsoleVariable ().

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH_PROTOCOL  *VarErrout;

+  UINTN                     DevicePathSize;

+

+  //

+  // Connect all default console variables

+  //

+  Status = BdsLibConnectConsoleVariable (L"ConIn");

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = BdsLibConnectConsoleVariable (L"ConOut");

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Special treat the err out device, becaues the null

+  // err out var is legal.

+  //

+  VarErrout = BdsLibGetVariableAndSize (

+                L"ErrOut",

+                &gEfiGlobalVariableGuid,

+                &DevicePathSize

+                );

+  if (VarErrout != NULL) {

+    BdsLibConnectConsoleVariable (L"ErrOut");

+  }

+

+  return EFI_SUCCESS;

+

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c
new file mode 100644
index 0000000..576ae72
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c
@@ -0,0 +1,764 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BdsMisc.c

+

+Abstract:

+

+  Misc BDS library function

+

+--*/

+

+extern UINT16 gPlatformBootTimeOutDefault;

+

+UINT16

+BdsLibGetTimeout (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Return the default value for system Timeout variable.

+

+Arguments:

+

+  None

+

+Returns:

+  

+  Timeout value.

+

+--*/

+{

+  UINT16      Timeout;

+  UINTN       Size;

+  EFI_STATUS  Status;

+

+  //

+  // Return Timeout variable or 0xffff if no valid

+  // Timeout variable exists.

+  //

+  Size    = sizeof (UINT16);

+  Status  = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);

+  if (!EFI_ERROR (Status)) {

+    return Timeout;

+  }

+  //

+  // To make the current EFI Automatic-Test activity possible, just add

+  // following code to make AutoBoot enabled when this variable is not

+  // present.

+  // This code should be removed later.

+  //

+  Timeout = gPlatformBootTimeOutDefault;

+

+  //

+  // Notes: Platform should set default variable if non exists on all error cases!!!

+  //

+  Status = gRT->SetVariable (

+                  L"Timeout",

+                  &gEfiGlobalVariableGuid,

+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+                  sizeof (UINT16),

+                  &Timeout

+                  );

+  return Timeout;

+}

+

+VOID

+BdsLibLoadDrivers (

+  IN LIST_ENTRY               *BdsDriverLists

+  )

+/*++

+

+Routine Description:

+  

+  The function will go through the driver optoin link list, load and start

+  every driver the driver optoin device path point to.

+

+Arguments:

+

+  BdsDriverLists   - The header of the current driver option link list

+

+Returns:

+  

+  None

+

+--*/

+{

+  EFI_STATUS                Status;

+  LIST_ENTRY                *Link;

+  BDS_COMMON_OPTION         *Option;

+  EFI_HANDLE                ImageHandle;

+  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;

+  UINTN                     ExitDataSize;

+  CHAR16                    *ExitData;

+  BOOLEAN                   ReconnectAll;

+

+  ReconnectAll = FALSE;

+

+  //

+  // Process the driver option

+  //

+  for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {

+    Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

+    //

+    // If a load option is not marked as LOAD_OPTION_ACTIVE,

+    // the boot manager will not automatically load the option.

+    //

+    if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {

+      continue;

+    }

+    //

+    // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,

+    // then all of the EFI drivers in the system will be disconnected and

+    // reconnected after the last driver load option is processed.

+    //

+    if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {

+      ReconnectAll = TRUE;

+    }

+    //

+    // Make sure the driver path is connected.

+    //

+    BdsLibConnectDevicePath (Option->DevicePath);

+

+    //

+    // Load and start the image that Driver#### describes

+    //

+    Status = gBS->LoadImage (

+                    FALSE,

+                    mBdsImageHandle,

+                    Option->DevicePath,

+                    NULL,

+                    0,

+                    &ImageHandle

+                    );

+

+    if (!EFI_ERROR (Status)) {

+      gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, &ImageInfo);

+

+      //

+      // Verify whether this image is a driver, if not,

+      // exit it and continue to parse next load option

+      //

+      if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {

+        gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);

+        continue;

+      }

+

+      if (Option->LoadOptionsSize != 0) {

+        ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;

+        ImageInfo->LoadOptions      = Option->LoadOptions;

+      }

+      //

+      // Before calling the image, enable the Watchdog Timer for

+      // the 5 Minute period

+      //

+      gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);

+

+      Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);

+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Driver Return Status = %r\n", Status));

+

+      //

+      // Clear the Watchdog Timer after the image returns

+      //

+      gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);

+    }

+  }

+  //

+  // Process the LOAD_OPTION_FORCE_RECONNECT driver option

+  //

+  if (ReconnectAll) {

+    BdsLibDisconnectAllEfi ();

+    BdsLibConnectAll ();

+  }

+

+}

+

+EFI_STATUS

+BdsLibRegisterNewOption (

+  IN  LIST_ENTRY                     *BdsOptionList,

+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,

+  IN  CHAR16                         *String,

+  IN  CHAR16                         *VariableName

+  )

+/*++

+

+Routine Description:

+  

+  This function will register the new boot#### or driver#### option base on

+  the VariableName. The new registered boot#### or driver#### will be linked

+  to BdsOptionList and also update to the VariableName. After the boot#### or

+  driver#### updated, the BootOrder or DriverOrder will also be updated.

+

+Arguments:

+

+  BdsOptionList    - The header of the boot#### or driver#### link list

+  

+  DevicePath       - The device path which the boot####

+                     or driver#### option present

+                     

+  String           - The description of the boot#### or driver####

+  

+  VariableName     - Indicate if the boot#### or driver#### option

+

+Returns:

+  

+  EFI_SUCCESS      - The boot#### or driver#### have been success registered

+  

+  EFI_STATUS       - Return the status of gRT->SetVariable ().

+

+--*/

+{

+  EFI_STATUS                Status;

+  UINTN                     Index;

+  UINT16                    MaxOptionNumber;

+  UINT16                    RegisterOptionNumber;

+  UINT16                    *TempOptionPtr;

+  UINTN                     TempOptionSize;

+  UINT16                    *OptionOrderPtr;

+  VOID                      *OptionPtr;

+  UINTN                     OptionSize;

+  UINT8                     *TempPtr;

+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;

+  CHAR16                    *Description;

+  CHAR16                    OptionName[10];

+  BOOLEAN                   UpdateBootDevicePath;

+

+  OptionPtr             = NULL;

+  OptionSize            = 0;

+  TempPtr               = NULL;

+  OptionDevicePath      = NULL;

+  Description           = NULL;

+  MaxOptionNumber       = 0;

+  OptionOrderPtr        = NULL;

+  UpdateBootDevicePath  = FALSE;

+  ZeroMem (OptionName, sizeof (OptionName));

+

+  TempOptionSize = 0;

+  TempOptionPtr = BdsLibGetVariableAndSize (

+                    VariableName,

+                    &gEfiGlobalVariableGuid,

+                    &TempOptionSize

+                    );

+  //

+  // Compare with current option variable

+  //

+  for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {

+    //

+    // Got the max option#### number

+    //

+    if (MaxOptionNumber < TempOptionPtr[Index]) {

+      MaxOptionNumber = TempOptionPtr[Index];

+    }

+

+    if (*VariableName == 'B') {

+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);

+    } else {

+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);

+    }

+

+    OptionPtr = BdsLibGetVariableAndSize (

+                  OptionName,

+                  &gEfiGlobalVariableGuid,

+                  &OptionSize

+                  );

+    TempPtr = OptionPtr;

+    TempPtr += sizeof (UINT32) + sizeof (UINT16);

+    Description = (CHAR16 *) TempPtr;

+    TempPtr += StrSize ((CHAR16 *) TempPtr);

+    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;

+

+    //

+    // Notes: the description may will change base on the GetStringToken

+    //

+    if (CompareMem (Description, String, StrSize (Description)) == 0) {

+      if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {

+        //

+        // Got the option, so just return

+        //

+        gBS->FreePool (OptionPtr);

+        gBS->FreePool (TempOptionPtr);

+        return EFI_SUCCESS;

+      } else {

+        //

+        // Boot device path changed, need update.

+        //

+        UpdateBootDevicePath = TRUE;

+        break;

+      }

+    }

+

+    gBS->FreePool (OptionPtr);

+  }

+

+  OptionSize          = sizeof (UINT32) + sizeof (UINT16) + StrSize (String) + GetDevicePathSize (DevicePath);

+  OptionPtr           = AllocateZeroPool (OptionSize);

+  TempPtr             = OptionPtr;

+  *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;

+  TempPtr += sizeof (UINT32);

+  *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);

+  TempPtr += sizeof (UINT16);

+  CopyMem (TempPtr, String, StrSize (String));

+  TempPtr += StrSize (String);

+  CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));

+

+  if (UpdateBootDevicePath) {

+    //

+    // The number in option#### to be updated

+    //

+    RegisterOptionNumber = TempOptionPtr[Index];

+  } else {

+    //

+    // The new option#### number

+    //

+    RegisterOptionNumber = MaxOptionNumber + 1;

+  }

+

+  if (*VariableName == 'B') {

+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);

+  } else {

+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);

+  }

+

+  Status = gRT->SetVariable (

+                  OptionName,

+                  &gEfiGlobalVariableGuid,

+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+                  OptionSize,

+                  OptionPtr

+                  );

+  if (EFI_ERROR (Status) || UpdateBootDevicePath) {

+    gBS->FreePool (OptionPtr);

+    gBS->FreePool (TempOptionPtr);

+    return Status;

+  }

+

+  gBS->FreePool (OptionPtr);

+

+  //

+  // Update the option order variable

+  //

+  OptionOrderPtr = AllocateZeroPool ((Index + 1) * sizeof (UINT16));

+  CopyMem (OptionOrderPtr, TempOptionPtr, Index * sizeof (UINT16));

+  OptionOrderPtr[Index] = RegisterOptionNumber;

+  Status = gRT->SetVariable (

+                  VariableName,

+                  &gEfiGlobalVariableGuid,

+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+                  (Index + 1) * sizeof (UINT16),

+                  OptionOrderPtr

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePool (TempOptionPtr);

+    gBS->FreePool (OptionOrderPtr);

+    return Status;

+  }

+

+  gBS->FreePool (TempOptionPtr);

+  gBS->FreePool (OptionOrderPtr);

+

+  return EFI_SUCCESS;

+}

+

+BDS_COMMON_OPTION *

+BdsLibVariableToOption (

+  IN OUT LIST_ENTRY               *BdsCommonOptionList,

+  IN  CHAR16                      *VariableName

+  )

+/*++

+

+Routine Description:

+

+  Build the boot#### or driver#### option from the VariableName, the 

+  build boot#### or driver#### will also be linked to BdsCommonOptionList

+  

+Arguments:

+

+  BdsCommonOptionList - The header of the boot#### or driver#### option link list

+

+  VariableName - EFI Variable name indicate if it is boot#### or driver####

+

+Returns:

+

+  BDS_COMMON_OPTION    - Get the option just been created

+

+  NULL                 - Failed to get the new option

+

+--*/

+{

+  UINT32                    Attribute;

+  UINT16                    FilePathSize;

+  UINT8                     *Variable;

+  UINT8                     *TempPtr;

+  UINTN                     VariableSize;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  BDS_COMMON_OPTION         *Option;

+  VOID                      *LoadOptions;

+  UINT32                    LoadOptionsSize;

+  CHAR16                    *Description;

+

+  //

+  // Read the variable. We will never free this data.

+  //

+  Variable = BdsLibGetVariableAndSize (

+              VariableName,

+              &gEfiGlobalVariableGuid,

+              &VariableSize

+              );

+  if (Variable == NULL) {

+    return NULL;

+  }

+  //

+  // Notes: careful defined the variable of Boot#### or

+  // Driver####, consider use some macro to abstract the code

+  //

+  //

+  // Get the option attribute

+  //

+  TempPtr   = Variable;

+  Attribute = *(UINT32 *) Variable;

+  TempPtr += sizeof (UINT32);

+

+  //

+  // Get the option's device path size

+  //

+  FilePathSize = *(UINT16 *) TempPtr;

+  TempPtr += sizeof (UINT16);

+

+  //

+  // Get the option's description string

+  //

+  Description = (CHAR16 *) TempPtr;

+

+  //

+  // Get the option's description string size

+  //

+  TempPtr += StrSize ((CHAR16 *) TempPtr);

+

+  //

+  // Get the option's device path

+  //

+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;

+  TempPtr += FilePathSize;

+

+  LoadOptions     = TempPtr;

+  LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));

+

+  //

+  // The Console variables may have multiple device paths, so make

+  // an Entry for each one.

+  //

+  Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));

+  if (Option == NULL) {

+    return NULL;

+  }

+

+  Option->Signature   = BDS_LOAD_OPTION_SIGNATURE;

+  Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));

+  CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));

+  Option->Attribute   = Attribute;

+  Option->Description = AllocateZeroPool (StrSize (Description));

+  CopyMem (Option->Description, Description, StrSize (Description));

+  Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);

+  CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);

+  Option->LoadOptionsSize = LoadOptionsSize;

+

+  //

+  // Insert active entry to BdsDeviceList

+  //

+  if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {

+    InsertTailList (BdsCommonOptionList, &Option->Link);

+    gBS->FreePool (Variable);

+    return Option;

+  }

+

+  gBS->FreePool (Variable);

+  gBS->FreePool (Option);

+  return NULL;

+

+}

+

+EFI_STATUS

+BdsLibBuildOptionFromVar (

+  IN  LIST_ENTRY                  *BdsCommonOptionList,

+  IN  CHAR16                      *VariableName

+  )

+/*++

+

+Routine Description:

+

+  Process BootOrder, or DriverOrder variables, by calling

+  BdsLibVariableToOption () for each UINT16 in the variables.

+

+Arguments:

+

+  BdsCommonOptionList - The header of the option list base on variable

+                        VariableName

+

+  VariableName - EFI Variable name indicate the BootOrder or DriverOrder

+

+Returns:

+

+  EFI_SUCCESS - Success create the boot option or driver option list

+

+  EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list

+

+--*/

+{

+  UINT16            *OptionOrder;

+  UINTN             OptionOrderSize;

+  UINTN             Index;

+  BDS_COMMON_OPTION *Option;

+  CHAR16            OptionName[20];

+

+  //

+  // Zero Buffer in order to get all BOOT#### variables

+  //

+  ZeroMem (OptionName, sizeof (OptionName));

+

+  //

+  // Read the BootOrder, or DriverOrder variable.

+  //

+  OptionOrder = BdsLibGetVariableAndSize (

+                  VariableName,

+                  &gEfiGlobalVariableGuid,

+                  &OptionOrderSize

+                  );

+  if (OptionOrder == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {

+    if (*VariableName == 'B') {

+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);

+    } else {

+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);

+    }

+    Option              = BdsLibVariableToOption (BdsCommonOptionList, OptionName);

+    Option->BootCurrent = OptionOrder[Index];

+

+  }

+

+  gBS->FreePool (OptionOrder);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLibGetBootMode (

+  OUT EFI_BOOT_MODE       *BootMode

+  )

+/*++

+

+Routine Description:

+

+  Get boot mode by looking up configuration table and parsing HOB list

+

+Arguments:

+

+  BootMode - Boot mode from PEI handoff HOB.

+

+Returns:

+

+  EFI_SUCCESS - Successfully get boot mode

+  

+  EFI_NOT_FOUND - Can not find the current system boot mode

+

+--*/

+{

+  EFI_HOB_HANDOFF_INFO_TABLE        *HobList;

+

+  HobList = GetHobList ();

+  ASSERT (HobList->Header.HobType == EFI_HOB_TYPE_HANDOFF);

+  *BootMode = HobList->BootMode;

+

+  return EFI_SUCCESS;

+}

+

+VOID *

+BdsLibGetVariableAndSize (

+  IN  CHAR16              *Name,

+  IN  EFI_GUID            *VendorGuid,

+  OUT UINTN               *VariableSize

+  )

+/*++

+

+Routine Description:

+

+  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated

+  buffer, and the size of the buffer. If failure return NULL.

+

+Arguments:

+

+  Name       - String part of EFI variable name

+

+  VendorGuid - GUID part of EFI variable name

+

+  VariableSize - Returns the size of the EFI variable that was read

+

+Returns:

+

+  Dynamically allocated memory that contains a copy of the EFI variable.

+  Caller is responsible freeing the buffer.

+

+  NULL - Variable was not read

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINTN       BufferSize;

+  VOID        *Buffer;

+

+  Buffer = NULL;

+

+  //

+  // Pass in a zero size buffer to find the required buffer size.

+  //

+  BufferSize  = 0;

+  Status      = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    //

+    // Allocate the buffer to return

+    //

+    Buffer = AllocateZeroPool (BufferSize);

+    if (Buffer == NULL) {

+      return NULL;

+    }

+    //

+    // Read variable into the allocated buffer.

+    //

+    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);

+    if (EFI_ERROR (Status)) {

+      BufferSize = 0;

+    }

+  }

+

+  *VariableSize = BufferSize;

+  return Buffer;

+}

+

+BOOLEAN

+BdsLibMatchDevicePaths (

+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,

+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single

+  )

+/*++

+

+Routine Description:

+

+  Function compares a device path data structure to that of all the nodes of a

+  second device path instance.

+

+Arguments:

+

+  Multi        - A pointer to a multi-instance device path data structure.

+

+  Single       - A pointer to a single-instance device path data structure.

+

+Returns:

+

+  TRUE   - If the Single is contained within Multi

+  

+  FALSE  - The Single is not match within Multi

+  

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;

+  UINTN                     Size;

+

+  if (!Multi || !Single) {

+    return FALSE;

+  }

+

+  DevicePath      = Multi;

+  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);

+  Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);

+

+  //

+  // Search for the match of 'Single' in 'Multi'

+  //

+  while (DevicePathInst != NULL) {

+    //

+    // If the single device path is found in multiple device paths,

+    // return success

+    //

+    if (Size == 0) {

+      return FALSE;

+    }

+

+    if (CompareMem (Single, DevicePathInst, Size) == 0) {

+      return TRUE;

+    }

+

+    gBS->FreePool (DevicePathInst);

+    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);

+    Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+BdsLibOutputStrings (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *ConOut,

+  ...

+  )

+/*++

+

+Routine Description:

+

+  This function prints a series of strings.

+

+Arguments:

+

+  ConOut               - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL

+

+  ...                  - A variable argument list containing series of strings,

+                         the last string must be NULL.

+

+Returns:

+

+  EFI_SUCCESS          - Success print out the string using ConOut.

+  

+  EFI_STATUS           - Return the status of the ConOut->OutputString ().

+

+--*/

+{

+  VA_LIST     args;

+  EFI_STATUS  Status;

+  CHAR16      *String;

+

+  Status = EFI_SUCCESS;

+  VA_START (args, ConOut);

+

+  while (!EFI_ERROR (Status)) {

+    //

+    // If String is NULL, then it's the end of the list

+    //

+    String = VA_ARG (args, CHAR16 *);

+    if (!String) {

+      break;

+    }

+

+    Status = ConOut->OutputString (ConOut, String);

+

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/DevicePath.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/DevicePath.c
new file mode 100644
index 0000000..de85410
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/DevicePath.c
@@ -0,0 +1,988 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DevicePath.c

+

+Abstract:

+

+  BDS internal function define the default device path string, it can be

+  replaced by platform device path.

+

+--*/

+

+

+#ifdef TIANO_EXTENSION_FLAG

+EFI_GUID  UnknownDeviceGuid           = UNKNOWN_DEVICE_GUID;

+#endif 

+

+EFI_GUID  mEfiWinNtThunkProtocolGuid  = EFI_WIN_NT_THUNK_PROTOCOL_GUID;

+EFI_GUID  mEfiWinNtUgaGuid            = EFI_WIN_NT_UGA_GUID;

+EFI_GUID  mEfiWinNtSerialPortGuid     = EFI_WIN_NT_SERIAL_PORT_GUID;

+EFI_GUID  mEfiMsgPcAnsiGuid           = DEVICE_PATH_MESSAGING_PC_ANSI;

+EFI_GUID  mEfiMsgVt100Guid            = DEVICE_PATH_MESSAGING_VT_100;

+EFI_GUID  mEfiMsgVt100PlusGuid        = DEVICE_PATH_MESSAGING_VT_100_PLUS;

+EFI_GUID  mEfiMsgVt100Utf8Guid        = DEVICE_PATH_MESSAGING_VT_UTF8;

+

+VOID *

+ReallocatePool (

+  IN VOID                 *OldPool,

+  IN UINTN                OldSize,

+  IN UINTN                NewSize

+  )

+/*++

+

+Routine Description:

+

+  Adjusts the size of a previously allocated buffer.

+

+Arguments:

+

+  OldPool               - A pointer to the buffer whose size is being adjusted.

+

+  OldSize               - The size of the current buffer.

+

+  NewSize               - The size of the new buffer.

+

+Returns:

+

+  EFI_SUCEESS           - The requested number of bytes were allocated.

+

+  EFI_OUT_OF_RESOURCES  - The pool requested could not be allocated.

+

+  EFI_INVALID_PARAMETER - The buffer was invalid.

+

+--*/

+{

+  VOID  *NewPool;

+

+  NewPool = NULL;

+  if (NewSize) {

+    NewPool = AllocateZeroPool (NewSize);

+  }

+

+  if (OldPool) {

+    if (NewPool) {

+      CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);

+    }

+

+    gBS->FreePool (OldPool);

+  }

+

+  return NewPool;

+}

+

+CHAR16 *

+CatPrint (

+  IN OUT POOL_PRINT   *Str,

+  IN CHAR16           *fmt,

+  ...

+  )

+/*++

+

+Routine Description:

+

+    Concatenates a formatted unicode string to allocated pool.  

+    The caller must free the resulting buffer.

+

+Arguments:

+

+    Str         - Tracks the allocated pool, size in use, and 

+                  amount of pool allocated.

+

+    fmt         - The format string

+

+Returns:

+

+    Allocated buffer with the formatted string printed in it.  

+    The caller must free the allocated buffer.   The buffer

+    allocation is not packed.

+

+--*/

+{

+  UINT16  *AppendStr;

+  VA_LIST args;

+  UINTN   strsize;

+

+  AppendStr = AllocateZeroPool (0x1000);

+  if (AppendStr == NULL) {

+    return Str->str;

+  }

+

+  VA_START (args, fmt);

+  UnicodeVSPrint (AppendStr, 0x1000, fmt, args);

+  VA_END (args);

+  if (NULL == Str->str) {

+    strsize   = StrSize (AppendStr);

+    Str->str  = AllocateZeroPool (strsize);

+    ASSERT (Str->str != NULL);

+  } else {

+    strsize = StrSize (AppendStr) + StrSize (Str->str) - sizeof (UINT16);

+    Str->str = ReallocatePool (

+                Str->str,

+                StrSize (Str->str),

+                strsize

+                );

+    ASSERT (Str->str != NULL);

+  }

+

+  Str->maxlen = MAX_CHAR * sizeof (UINT16);

+  if (strsize < Str->maxlen) {

+    StrCat (Str->str, AppendStr);

+    Str->len = strsize - sizeof (UINT16);

+  }

+

+  gBS->FreePool (AppendStr);

+  return Str->str;

+}

+

+EFI_DEVICE_PATH_PROTOCOL *

+BdsLibUnpackDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath

+  )

+/*++

+

+Routine Description:

+

+  Function unpacks a device path data structure so that all the nodes

+  of a device path are naturally aligned.

+

+Arguments:

+

+  DevPath        - A pointer to a device path data structure

+

+Returns:

+

+  If the memory for the device path is successfully allocated, then a 

+  pointer to the new device path is returned.  Otherwise, NULL is returned.

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *Src;

+  EFI_DEVICE_PATH_PROTOCOL  *Dest;

+  EFI_DEVICE_PATH_PROTOCOL  *NewPath;

+  UINTN                     Size;

+

+  //

+  // Walk device path and round sizes to valid boundries

+  //

+  Src   = DevPath;

+  Size  = 0;

+  for (;;) {

+    Size += DevicePathNodeLength (Src);

+    Size += ALIGN_SIZE (Size);

+

+    if (IsDevicePathEnd (Src)) {

+      break;

+    }

+

+    Src = NextDevicePathNode (Src);

+  }

+  //

+  // Allocate space for the unpacked path

+  //

+  NewPath = AllocateZeroPool (Size);

+  if (NewPath) {

+

+    ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);

+

+    //

+    // Copy each node

+    //

+    Src   = DevPath;

+    Dest  = NewPath;

+    for (;;) {

+      Size = DevicePathNodeLength (Src);

+      CopyMem (Dest, Src, Size);

+      Size += ALIGN_SIZE (Size);

+      SetDevicePathNodeLength (Dest, Size);

+      Dest->Type |= EFI_DP_TYPE_UNPACKED;

+      Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);

+

+      if (IsDevicePathEnd (Src)) {

+        break;

+      }

+

+      Src = NextDevicePathNode (Src);

+    }

+  }

+

+  return NewPath;

+}

+

+VOID

+DevPathPci (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  PCI_DEVICE_PATH *Pci;

+

+  Pci = DevPath;

+  CatPrint (Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);

+}

+

+VOID

+DevPathPccard (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  PCCARD_DEVICE_PATH  *Pccard;

+

+  Pccard = DevPath;

+  CatPrint (Str, L"Pcmcia(Function%x)", Pccard->FunctionNumber);

+}

+

+VOID

+DevPathMemMap (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  MEMMAP_DEVICE_PATH  *MemMap;

+

+  MemMap = DevPath;

+  CatPrint (

+    Str,

+    L"MemMap(%d:%.lx-%.lx)",

+    MemMap->MemoryType,

+    MemMap->StartingAddress,

+    MemMap->EndingAddress

+    );

+}

+

+VOID

+DevPathController (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  CONTROLLER_DEVICE_PATH  *Controller;

+

+  Controller = DevPath;

+  CatPrint (Str, L"Ctrl(%d)", Controller->ControllerNumber);

+}

+

+VOID

+DevPathVendor (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+/*++

+

+Routine Description:

+

+  Convert Vendor device path to device name

+

+Arguments:

+

+  Str     - The buffer store device name

+  DevPath - Pointer to vendor device path

+

+Returns:

+

+  When it return, the device name have been stored in *Str.

+

+--*/

+{

+  VENDOR_DEVICE_PATH  *Vendor;

+  CHAR16              *Type;

+  INT32               *Temp;

+

+  Vendor  = DevPath;

+  Temp    = (INT32 *) (&Vendor->Guid);

+

+  switch (DevicePathType (&Vendor->Header)) {

+  case HARDWARE_DEVICE_PATH:

+    //

+    // If the device is a winntbus device, we will give it a readable device name.

+    //

+    if (CompareGuid (&Vendor->Guid, &mEfiWinNtThunkProtocolGuid)) {

+      CatPrint (Str, L"%s", L"WinNtBus");

+      return ;

+    } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtUgaGuid)) {

+      CatPrint (Str, L"%s", L"UGA");

+      return ;

+    } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtSerialPortGuid)) {

+      CatPrint (Str, L"%s", L"Serial");

+      return ;

+    } else {

+      Type = L"Hw";

+      break;

+    }

+

+  case MESSAGING_DEVICE_PATH:

+    //

+    // If the device is a winntbus device, we will give it a readable device name.

+    //

+    if (CompareGuid (&Vendor->Guid, &mEfiMsgPcAnsiGuid)) {

+      CatPrint (Str, L"%s", L"PC-ANSI");

+      return ;

+    } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100Guid)) {

+      CatPrint (Str, L"%s", L"VT100");

+      return ;

+    } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100PlusGuid)) {

+      CatPrint (Str, L"%s", L"VT100+");

+      return ;

+    } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100Utf8Guid)) {

+      CatPrint (Str, L"%s", L"VT100-UTF8");

+      return ;

+    } else {

+      Type = L"Msg";

+      break;

+    }

+

+  case MEDIA_DEVICE_PATH:

+    Type = L"Media";

+    break;

+

+  default:

+    Type = L"?";

+    break;

+  }

+

+  CatPrint (Str, L"Ven%s(%g)", Type, &Vendor->Guid);

+}

+

+VOID

+DevPathAcpi (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  ACPI_HID_DEVICE_PATH  *Acpi;

+

+  Acpi = DevPath;

+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {

+    CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);

+  } else {

+    CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);

+  }

+}

+

+VOID

+DevPathAtapi (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  ATAPI_DEVICE_PATH *Atapi;

+

+  Atapi = DevPath;

+  CatPrint (

+    Str,

+    L"Ata(%s,%s)",

+    Atapi->PrimarySecondary ? L"Secondary" : L"Primary",

+    Atapi->SlaveMaster ? L"Slave" : L"Master"

+    );

+}

+

+VOID

+DevPathScsi (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  SCSI_DEVICE_PATH  *Scsi;

+

+  Scsi = DevPath;

+  CatPrint (Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);

+}

+

+VOID

+DevPathFibre (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  FIBRECHANNEL_DEVICE_PATH  *Fibre;

+

+  Fibre = DevPath;

+  CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);

+}

+

+VOID

+DevPath1394 (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  F1394_DEVICE_PATH *F1394;

+

+  F1394 = DevPath;

+  CatPrint (Str, L"1394(%g)", &F1394->Guid);

+}

+

+VOID

+DevPathUsb (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  USB_DEVICE_PATH *Usb;

+

+  Usb = DevPath;

+  CatPrint (Str, L"Usb(%x, %x)", Usb->ParentPortNumber, Usb->InterfaceNumber);

+}

+

+VOID

+DevPathUsbClass (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  USB_CLASS_DEVICE_PATH *UsbClass;

+

+  UsbClass = DevPath;

+  CatPrint (

+    Str,

+    L"Usb Class(%x, %x, %x, %x, %x)",

+    UsbClass->VendorId,

+    UsbClass->ProductId,

+    UsbClass->DeviceClass,

+    UsbClass->DeviceSubClass,

+    UsbClass->DeviceProtocol

+    );

+}

+

+VOID

+DevPathI2O (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  I2O_DEVICE_PATH *I2O;

+

+  I2O = DevPath;

+  CatPrint (Str, L"I2O(%x)", I2O->Tid);

+}

+

+VOID

+DevPathMacAddr (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  MAC_ADDR_DEVICE_PATH  *MAC;

+  UINTN                 HwAddressSize;

+  UINTN                 Index;

+

+  MAC           = DevPath;

+

+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);

+  if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {

+    HwAddressSize = 6;

+  }

+

+  CatPrint (Str, L"Mac(");

+

+  for (Index = 0; Index < HwAddressSize; Index++) {

+    CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);

+  }

+

+  CatPrint (Str, L")");

+}

+

+VOID

+DevPathIPv4 (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  IPv4_DEVICE_PATH  *IP;

+

+  IP = DevPath;

+  CatPrint (

+    Str,

+    L"IPv4(%d.%d.%d.%d:%d)",

+    IP->RemoteIpAddress.Addr[0],

+    IP->RemoteIpAddress.Addr[1],

+    IP->RemoteIpAddress.Addr[2],

+    IP->RemoteIpAddress.Addr[3],

+    IP->RemotePort

+    );

+}

+

+VOID

+DevPathIPv6 (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  IPv6_DEVICE_PATH  *IP;

+

+  IP = DevPath;

+  CatPrint (Str, L"IP-v6(not-done)");

+}

+

+VOID

+DevPathInfiniBand (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  INFINIBAND_DEVICE_PATH  *InfiniBand;

+

+  InfiniBand = DevPath;

+  CatPrint (Str, L"InfiniBand(not-done)");

+}

+

+VOID

+DevPathUart (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  UART_DEVICE_PATH  *Uart;

+  CHAR8             Parity;

+

+  Uart = DevPath;

+  switch (Uart->Parity) {

+  case 0:

+    Parity = 'D';

+    break;

+

+  case 1:

+    Parity = 'N';

+    break;

+

+  case 2:

+    Parity = 'E';

+    break;

+

+  case 3:

+    Parity = 'O';

+    break;

+

+  case 4:

+    Parity = 'M';

+    break;

+

+  case 5:

+    Parity = 'S';

+    break;

+

+  default:

+    Parity = 'x';

+    break;

+  }

+

+  if (Uart->BaudRate == 0) {

+    CatPrint (Str, L"Uart(DEFAULT %c", Parity);

+  } else {

+    CatPrint (Str, L"Uart(%d %c", Uart->BaudRate, Parity);

+  }

+

+  if (Uart->DataBits == 0) {

+    CatPrint (Str, L"D");

+  } else {

+    CatPrint (Str, L"%d", Uart->DataBits);

+  }

+

+  switch (Uart->StopBits) {

+  case 0:

+    CatPrint (Str, L"D)");

+    break;

+

+  case 1:

+    CatPrint (Str, L"1)");

+    break;

+

+  case 2:

+    CatPrint (Str, L"1.5)");

+    break;

+

+  case 3:

+    CatPrint (Str, L"2)");

+    break;

+

+  default:

+    CatPrint (Str, L"x)");

+    break;

+  }

+}

+

+VOID

+DevPathHardDrive (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  HARDDRIVE_DEVICE_PATH *Hd;

+

+  Hd = DevPath;

+  switch (Hd->SignatureType) {

+  case SIGNATURE_TYPE_MBR:

+    CatPrint (

+      Str,

+      L"HD(Part%d,Sig%08x)",

+      Hd->PartitionNumber,

+      *((UINT32 *) (&(Hd->Signature[0])))

+      );

+    break;

+

+  case SIGNATURE_TYPE_GUID:

+    CatPrint (

+      Str,

+      L"HD(Part%d,Sig%g)",

+      Hd->PartitionNumber,

+      (EFI_GUID *) &(Hd->Signature[0])

+      );

+    break;

+

+  default:

+    CatPrint (

+      Str,

+      L"HD(Part%d,MBRType=%02x,SigType=%02x)",

+      Hd->PartitionNumber,

+      Hd->MBRType,

+      Hd->SignatureType

+      );

+    break;

+  }

+}

+

+VOID

+DevPathCDROM (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  CDROM_DEVICE_PATH *Cd;

+

+  Cd = DevPath;

+  CatPrint (Str, L"CDROM(Entry%x)", Cd->BootEntry);

+}

+

+VOID

+DevPathFilePath (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  FILEPATH_DEVICE_PATH  *Fp;

+

+  Fp = DevPath;

+  CatPrint (Str, L"%s", Fp->PathName);

+}

+

+VOID

+DevPathMediaProtocol (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;

+

+  MediaProt = DevPath;

+  CatPrint (Str, L"%g", &MediaProt->Protocol);

+}

+

+VOID

+DevPathFvFilePath (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;

+

+  FvFilePath = DevPath;

+  CatPrint (Str, L"%g", &FvFilePath->NameGuid);

+}

+

+VOID

+DevPathBssBss (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  BBS_BBS_DEVICE_PATH *Bbs;

+  CHAR16              *Type;

+

+  Bbs = DevPath;

+  switch (Bbs->DeviceType) {

+  case BBS_TYPE_FLOPPY:

+    Type = L"Floppy";

+    break;

+

+  case BBS_TYPE_HARDDRIVE:

+    Type = L"Harddrive";

+    break;

+

+  case BBS_TYPE_CDROM:

+    Type = L"CDROM";

+    break;

+

+  case BBS_TYPE_PCMCIA:

+    Type = L"PCMCIA";

+    break;

+

+  case BBS_TYPE_USB:

+    Type = L"Usb";

+    break;

+

+  case BBS_TYPE_EMBEDDED_NETWORK:

+    Type = L"Net";

+    break;

+

+  default:

+    Type = L"?";

+    break;

+  }

+  //

+  // Since current Print function hasn't implemented %a (for ansi string)

+  // we will only print Unicode strings.

+  //

+  CatPrint (Str, L"Legacy-%s", Type);

+}

+

+VOID

+DevPathEndInstance (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  CatPrint (Str, L",");

+}

+

+VOID

+DevPathNodeUnknown (

+  IN OUT POOL_PRINT       *Str,

+  IN VOID                 *DevPath

+  )

+{

+  CatPrint (Str, L"?");

+}

+

+DEVICE_PATH_STRING_TABLE  DevPathTable[] = {

+  HARDWARE_DEVICE_PATH,

+  HW_PCI_DP,

+  DevPathPci,

+  HARDWARE_DEVICE_PATH,

+  HW_PCCARD_DP,

+  DevPathPccard,

+  HARDWARE_DEVICE_PATH,

+  HW_MEMMAP_DP,

+  DevPathMemMap,

+  HARDWARE_DEVICE_PATH,

+  HW_VENDOR_DP,

+  DevPathVendor,

+  HARDWARE_DEVICE_PATH,

+  HW_CONTROLLER_DP,

+  DevPathController,

+  ACPI_DEVICE_PATH,

+  ACPI_DP,

+  DevPathAcpi,

+  MESSAGING_DEVICE_PATH,

+  MSG_ATAPI_DP,

+  DevPathAtapi,

+  MESSAGING_DEVICE_PATH,

+  MSG_SCSI_DP,

+  DevPathScsi,

+  MESSAGING_DEVICE_PATH,

+  MSG_FIBRECHANNEL_DP,

+  DevPathFibre,

+  MESSAGING_DEVICE_PATH,

+  MSG_1394_DP,

+  DevPath1394,

+  MESSAGING_DEVICE_PATH,

+  MSG_USB_DP,

+  DevPathUsb,

+  MESSAGING_DEVICE_PATH,

+  MSG_USB_CLASS_DP,

+  DevPathUsbClass,

+  MESSAGING_DEVICE_PATH,

+  MSG_I2O_DP,

+  DevPathI2O,

+  MESSAGING_DEVICE_PATH,

+  MSG_MAC_ADDR_DP,

+  DevPathMacAddr,

+  MESSAGING_DEVICE_PATH,

+  MSG_IPv4_DP,

+  DevPathIPv4,

+  MESSAGING_DEVICE_PATH,

+  MSG_IPv6_DP,

+  DevPathIPv6,

+  MESSAGING_DEVICE_PATH,

+  MSG_INFINIBAND_DP,

+  DevPathInfiniBand,

+  MESSAGING_DEVICE_PATH,

+  MSG_UART_DP,

+  DevPathUart,

+  MESSAGING_DEVICE_PATH,

+  MSG_VENDOR_DP,

+  DevPathVendor,

+  MEDIA_DEVICE_PATH,

+  MEDIA_HARDDRIVE_DP,

+  DevPathHardDrive,

+  MEDIA_DEVICE_PATH,

+  MEDIA_CDROM_DP,

+  DevPathCDROM,

+  MEDIA_DEVICE_PATH,

+  MEDIA_VENDOR_DP,

+  DevPathVendor,

+  MEDIA_DEVICE_PATH,

+  MEDIA_FILEPATH_DP,

+  DevPathFilePath,

+  MEDIA_DEVICE_PATH,

+  MEDIA_PROTOCOL_DP,

+  DevPathMediaProtocol,

+

+#if (EFI_SPECIFICATION_VERSION < 0x00020000)

+  MEDIA_DEVICE_PATH,

+  MEDIA_FV_FILEPATH_DP,

+  DevPathFvFilePath,

+#endif

+

+  BBS_DEVICE_PATH,

+  BBS_BBS_DP,

+  DevPathBssBss,

+  END_DEVICE_PATH_TYPE,

+  END_INSTANCE_DEVICE_PATH_SUBTYPE,

+  DevPathEndInstance,

+  0,

+  0,

+  NULL

+};

+

+CHAR16 *

+DevicePathToStr (

+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath

+  )

+/*++

+

+  Turns the Device Path into a printable string.  Allcoates

+  the string from pool.  The caller must SafeFreePool the returned

+  string.

+

+--*/

+{

+  POOL_PRINT                Str;

+  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;

+  VOID (*DumpNode) (POOL_PRINT *, VOID *);

+

+  UINTN Index;

+  UINTN NewSize;

+

+  ZeroMem (&Str, sizeof (Str));

+

+  if (DevPath == NULL) {

+    goto Done;

+  }

+  //

+  // Unpacked the device path

+  //

+  DevPath = BdsLibUnpackDevicePath (DevPath);

+  ASSERT (DevPath);

+

+  //

+  // Process each device path node

+  //

+  DevPathNode = DevPath;

+  while (!IsDevicePathEnd (DevPathNode)) {

+    //

+    // Find the handler to dump this device path node

+    //

+    DumpNode = NULL;

+    for (Index = 0; DevPathTable[Index].Function; Index += 1) {

+

+      if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&

+          DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType

+          ) {

+        DumpNode = DevPathTable[Index].Function;

+        break;

+      }

+    }

+    //

+    // If not found, use a generic function

+    //

+    if (!DumpNode) {

+      DumpNode = DevPathNodeUnknown;

+    }

+    //

+    //  Put a path seperator in if needed

+    //

+    if (Str.len && DumpNode != DevPathEndInstance) {

+      CatPrint (&Str, L"/");

+    }

+    //

+    // Print this node of the device path

+    //

+    DumpNode (&Str, DevPathNode);

+

+    //

+    // Next device path node

+    //

+    DevPathNode = NextDevicePathNode (DevPathNode);

+  }

+  //

+  // Shrink pool used for string allocation

+  //

+  gBS->FreePool (DevPath);

+

+Done:

+  NewSize = (Str.len + 1) * sizeof (CHAR16);

+  Str.str = ReallocatePool (Str.str, NewSize, NewSize);

+  ASSERT (Str.str != NULL);

+  Str.str[Str.len] = 0;

+  return Str.str;

+}

+

+EFI_DEVICE_PATH_PROTOCOL *

+LibDuplicateDevicePathInstance (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath

+  )

+/*++

+

+Routine Description:

+

+  Function creates a device path data structure that identically matches the 

+  device path passed in.

+

+Arguments:

+

+  DevPath      - A pointer to a device path data structure.

+

+Returns:

+

+  The new copy of DevPath is created to identically match the input.  

+  Otherwise, NULL is returned.

+

+--*/

+{

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevPath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;

+  EFI_DEVICE_PATH_PROTOCOL  *Temp;

+  UINTN                     Size;

+

+  //

+  // get the size of an instance from the input

+  //

+  Temp            = DevPath;

+  DevicePathInst  = GetNextDevicePathInstance (&Temp, &Size);

+

+  //

+  // Make a copy

+  //

+  NewDevPath = NULL;

+  if (Size) {

+    NewDevPath = AllocateZeroPool (Size);

+    ASSERT (NewDevPath != NULL);

+  }

+

+  if (NewDevPath) {

+    CopyMem (NewDevPath, DevicePathInst, Size);

+  }

+

+  return NewDevPath;

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/EdkGenericBdsLib.mbd b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/EdkGenericBdsLib.mbd
new file mode 100644
index 0000000..ca083fe
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/EdkGenericBdsLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkGenericBdsLib</BaseName>

+    <Guid>1ec995b2-d15b-44f6-abd2-050ea7dd37d2</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:00</Created>

+    <Modified>2006-03-23 12:01</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/EdkGenericBdsLib.msa b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/EdkGenericBdsLib.msa
new file mode 100644
index 0000000..598eca4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/EdkGenericBdsLib.msa
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkGenericBdsLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>1ec995b2-d15b-44f6-abd2-050ea7dd37d2</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 17:00</Created>

+    <Updated>2006-03-23 12:01</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkGenericBdsLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PerformanceLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BdsBoot.c</Filename>

+    <Filename>BdsConsole.c</Filename>

+    <Filename>BdsConnect.c</Filename>

+    <Filename>DevicePath.c</Filename>

+    <Filename>Performance.c</Filename>

+    <Filename>BdsMisc.c</Filename>

+    <Arch ArchType="IPF">

+      <Filename>Ipf\ShadowRom.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolume</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">AcpiS3Save</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleTextOut</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleTextIn</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SimpleNetwork</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>ShellFile</C_Name>

+    </GuidEntry>

+  </Guids>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Ipf/ShadowRom.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Ipf/ShadowRom.c
new file mode 100644
index 0000000..44a643d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Ipf/ShadowRom.c
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  ShadowRom.c

+

+Abstract:

+

+  Shadow all option rom

+

+Revision History

+

+--*/

+

+#include "Tiano.h"

+#include "EfiDriverLib.h"

+

+#include EFI_PROTOCOL_DEFINITION (LegacyBios)

+

+UINT8 mShadowRomFlag = 0;

+

+VOID

+ShadowAllOptionRom()

+{

+  EFI_STATUS                Status;

+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

+  //

+  // Rom shadow only do once.

+  //

+  if (mShadowRomFlag == 0) {

+    Status = gBS->LocateProtocol (

+                    &gEfiLegacyBiosProtocolGuid,

+                    NULL,

+                    &LegacyBios

+                    );

+    if (!EFI_ERROR (Status)) {

+      LegacyBios->PrepareToBootEfi (LegacyBios, NULL, NULL);

+    }

+

+    mShadowRomFlag = 1;

+  }

+

+  return ;

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.c b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.c
new file mode 100644
index 0000000..320d6b7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.c
@@ -0,0 +1,426 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Performance.c

+

+Abstract:

+

+  This file include the file which can help to get the system

+  performance, all the function will only include if the performance

+  switch is set.

+

+--*/

+

+#include "Performance.h"

+

+VOID

+ClearDebugRegisters (

+  VOID

+  )

+{

+  AsmWriteDr0 (0);

+  AsmWriteDr1 (0);

+}

+

+STATIC

+VOID

+GetShortPdbFileName (

+  CHAR8  *PdbFileName,

+  CHAR8  *GaugeString

+  )

+/*++

+

+Routine Description:

+  

+Arguments:

+

+Returns:

+

+--*/

+{

+  UINTN Index;

+  UINTN Index1;

+  UINTN StartIndex;

+  UINTN EndIndex;

+

+  if (PdbFileName == NULL) {

+    AsciiStrCpy (GaugeString, " ");

+  } else {

+    StartIndex = 0;

+    for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)

+      ;

+

+    for (Index = 0; PdbFileName[Index] != 0; Index++) {

+      if (PdbFileName[Index] == '\\') {

+        StartIndex = Index + 1;

+      }

+

+      if (PdbFileName[Index] == '.') {

+        EndIndex = Index;

+      }

+    }

+

+    Index1 = 0;

+    for (Index = StartIndex; Index < EndIndex; Index++) {

+      GaugeString[Index1] = PdbFileName[Index];

+      Index1++;

+      if (Index1 == PERF_TOKEN_LENGTH - 1) {

+        break;

+      }

+    }

+

+    GaugeString[Index1] = 0;

+  }

+

+  return ;

+}

+

+STATIC

+CHAR8 *

+GetPdbPath (

+  VOID *ImageBase

+  )

+/*++

+

+Routine Description:

+

+  Located PDB path name in PE image

+

+Arguments:

+

+  ImageBase - base of PE to search

+

+Returns:

+

+  Pointer into image at offset of PDB file name if PDB file name is found,

+  Otherwise a pointer to an empty string.

+

+--*/

+{

+  CHAR8                           *PdbPath;

+  UINT32                          DirCount;

+  EFI_IMAGE_DOS_HEADER            *DosHdr;

+  EFI_IMAGE_NT_HEADERS            *NtHdr;

+  EFI_IMAGE_OPTIONAL_HEADER       *OptionalHdr;

+  EFI_IMAGE_DATA_DIRECTORY        *DirectoryEntry;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;

+  VOID                            *CodeViewEntryPointer;

+

+  CodeViewEntryPointer  = NULL;

+  PdbPath               = NULL;

+  DosHdr                = ImageBase;

+

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    NtHdr           = (EFI_IMAGE_NT_HEADERS *) ((UINT8 *) DosHdr + DosHdr->e_lfanew);

+    OptionalHdr     = (VOID *) &NtHdr->OptionalHeader;

+    DirectoryEntry  = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+    if (DirectoryEntry->VirtualAddress != 0) {

+      for (DirCount = 0;

+           (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;

+           DirCount++

+          ) {

+        DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));

+        if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+          CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase);

+          switch (*(UINT32 *) CodeViewEntryPointer) {

+          case CODEVIEW_SIGNATURE_NB10:

+            PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);

+            break;

+

+          case CODEVIEW_SIGNATURE_RSDS:

+            PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);

+            break;

+

+          default:

+            break;

+          }

+        }

+      }

+    }

+  }

+

+  return PdbPath;

+}

+

+STATIC

+VOID

+GetNameFromHandle (

+  IN  EFI_HANDLE     Handle,

+  OUT CHAR8          *GaugeString

+  )

+{

+  EFI_STATUS                  Status;

+  EFI_LOADED_IMAGE_PROTOCOL   *Image;

+  CHAR8                       *PdbFileName;

+  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;

+

+  AsciiStrCpy (GaugeString, " ");

+

+  //

+  // Get handle name from image protocol

+  //

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiLoadedImageProtocolGuid,

+                  &Image

+                  );

+

+  if (EFI_ERROR (Status)) {

+    Status = gBS->OpenProtocol (

+                    Handle,

+                    &gEfiDriverBindingProtocolGuid,

+                    (VOID **) &DriverBinding,

+                    NULL,

+                    NULL,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      return ;

+    }

+    //

+    // Get handle name from image protocol

+    //

+    Status = gBS->HandleProtocol (

+                    DriverBinding->ImageHandle,

+                    &gEfiLoadedImageProtocolGuid,

+                    &Image

+                    );

+  }

+

+  PdbFileName = GetPdbPath (Image->ImageBase);

+

+  if (PdbFileName != NULL) {

+    GetShortPdbFileName (PdbFileName, GaugeString);

+  }

+

+  return ;

+}

+

+

+

+VOID

+WriteBootToOsPerformanceData (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Allocates a block of memory and writes performance data of booting to OS into it.

+

+Arguments:

+  

+  None

+  

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                Status;

+  EFI_CPU_ARCH_PROTOCOL     *Cpu;

+  EFI_PHYSICAL_ADDRESS      mAcpiLowMemoryBase;

+  UINT32                    mAcpiLowMemoryLength;

+  UINT32                    LimitCount;

+  PERF_HEADER               mPerfHeader;

+  PERF_DATA                 mPerfData;

+  EFI_HANDLE                *Handles;

+  UINTN                     NoHandles;

+  CHAR8                     GaugeString[PERF_TOKEN_LENGTH];

+  UINT8                     *Ptr;

+  UINT32                    mIndex;

+  UINT64                    Ticker;

+  UINT64                    Freq;

+  UINT32                    Duration;

+  UINT64                    CurrentTicker;

+  UINT64                    TimerPeriod;

+  UINTN                     LogEntryKey;

+  CONST VOID                *Handle;

+  CONST CHAR8               *Token;

+  CONST CHAR8               *Module;

+  UINT64                    StartTicker;

+  UINT64                    EndTicker;

+

+  //

+  // Retrive time stamp count as early as possilbe

+  //

+  Ticker = AsmReadTsc ();

+

+  //

+  // Allocate a block of memory that contain performance data to OS

+  //

+  Status = gBS->AllocatePages (

+                  AllocateAnyPages,

+                  EfiACPIReclaimMemory,

+                  4,

+                  &mAcpiLowMemoryBase

+                  );

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+

+  mAcpiLowMemoryLength  = 0x1000;

+

+  Ptr                   = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));

+  LimitCount            = (mAcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);

+

+  //

+  // Initialize performance data structure

+  //

+  ZeroMem (&mPerfHeader, sizeof (PERF_HEADER));

+

+  //

+  // Get CPU frequency

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiCpuArchProtocolGuid,

+                  NULL,

+                  &Cpu

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePages (mAcpiLowMemoryBase, 1);

+    return ;

+  }

+  //

+  // Get Cpu Frequency

+  //

+  Status = Cpu->GetTimerValue (Cpu, 0, &(CurrentTicker), &TimerPeriod);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePages (mAcpiLowMemoryBase, 1);

+    return ;

+  }

+

+  Freq                = DivU64x32 (1000000000000, (UINTN) TimerPeriod);

+

+  mPerfHeader.CpuFreq = Freq;

+

+  //

+  // Record BDS raw performance data

+  //

+  mPerfHeader.BDSRaw = Ticker;

+

+  //

+  // Put Detailed performance data into memory

+  //

+  Handles = NULL;

+  Status = gBS->LocateHandleBuffer (

+                  AllHandles,

+                  NULL,

+                  NULL,

+                  &NoHandles,

+                  &Handles

+                  );

+  if (EFI_ERROR (Status)) {

+    gBS->FreePages (mAcpiLowMemoryBase, 1);

+    return ;

+  }

+  //

+  // Get DXE drivers performance

+  //

+  for (mIndex = 0; mIndex < NoHandles; mIndex++) {

+    Ticker = 0;

+    LogEntryKey = 0;

+    while ((LogEntryKey = GetPerformanceMeasurement (

+                            LogEntryKey,

+                            &Handle,

+                            &Token,

+                            &Module,

+                            &StartTicker,

+                            &EndTicker)) != 0) {

+      if ((Handle == Handles[mIndex]) && (StartTicker < EndTicker)) {

+        Ticker += (EndTicker - StartTicker);

+      }

+    }

+

+    Duration = (UINT32) DivU64x32 (

+                          Ticker,

+                          (UINT32) Freq

+                          );

+

+    if (Duration > 0) {

+      ZeroMem (&mPerfData, sizeof (PERF_DATA));

+

+      GetNameFromHandle (Handles[mIndex], GaugeString);

+

+      AsciiStrCpy (mPerfData.Token, GaugeString);

+      mPerfData.Duration = Duration;

+

+      CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));

+      Ptr += sizeof (PERF_DATA);

+

+      mPerfHeader.Count++;

+      if (mPerfHeader.Count == LimitCount) {

+        goto Done;

+      }

+    }

+  }

+

+  gBS->FreePool (Handles);

+

+  //

+  // Get inserted performance data

+  //

+  LogEntryKey = 0;

+  while ((LogEntryKey = GetPerformanceMeasurement (

+                          LogEntryKey,

+                          &Handle,

+                          &Token,

+                          &Module,

+                          &StartTicker,

+                          &EndTicker)) != 0) {

+    if ((Handle == NULL) && (StartTicker <= EndTicker)) {

+

+      ZeroMem (&mPerfData, sizeof (PERF_DATA));

+

+      AsciiStrnCpy (mPerfData.Token, Token, DXE_PERFORMANCE_STRING_SIZE);

+      mPerfData.Duration = (UINT32) DivU64x32 (

+                                      EndTicker - StartTicker,

+                                      (UINT32) Freq

+                                      );

+

+      CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));

+      Ptr += sizeof (PERF_DATA);

+

+      mPerfHeader.Count++;

+      if (mPerfHeader.Count == LimitCount) {

+        goto Done;

+      }

+    }

+  }

+

+Done:

+

+  ClearDebugRegisters ();

+

+  mPerfHeader.Signiture = 0x66726550;

+

+  //

+  // Put performance data to memory

+  //

+  CopyMem (

+    (UINT32 *) (UINT32) mAcpiLowMemoryBase,

+    &mPerfHeader,

+    sizeof (PERF_HEADER)

+    );

+

+  gRT->SetVariable (

+        L"PerfDataMemAddr",

+        &gEfiGlobalVariableGuid,

+        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+        sizeof (UINT32),

+        (VOID *) &mAcpiLowMemoryBase

+        );

+

+  return ;

+}

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.h b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.h
new file mode 100644
index 0000000..e7f80ab
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/Performance.h
@@ -0,0 +1,55 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Performance.h

+

+Abstract:

+

+  This file included the performance relete function header and 

+  definition.

+

+--*/

+

+#ifndef _PERF_H_

+#define _PERF_H_

+

+#define PERF_TOKEN_LENGTH       28

+#define PERF_PEI_ENTRY_MAX_NUM  50

+

+typedef struct {

+  CHAR8   Token[PERF_TOKEN_LENGTH];

+  UINT32  Duration;

+} PERF_DATA;

+

+typedef struct {

+  UINT64        BootToOs;

+  UINT64        S3Resume;

+  UINT32        S3EntryNum;

+  PERF_DATA     S3Entry[PERF_PEI_ENTRY_MAX_NUM];

+  UINT64        CpuFreq;

+  UINT64        BDSRaw;

+  UINT32        Count;

+  UINT32        Signiture;

+} PERF_HEADER;

+

+VOID

+WriteBootToOsPerformanceData (

+  VOID

+  );

+

+VOID

+ClearDebugRegisters (

+  VOID

+  );

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/build.xml b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/build.xml
new file mode 100644
index 0000000..ad30c96
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkGenericBdsLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkGenericBdsLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library\EdkGenericBdsLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="EdkGenericBdsLib">

+      <GenBuild baseName="EdkGenericBdsLib" mbdFilename="${MODULE_DIR}\EdkGenericBdsLib.mbd" msaFilename="${MODULE_DIR}\EdkGenericBdsLib.msa"/>

+   </target>

+   <target depends="EdkGenericBdsLib_clean" name="clean"/>

+   <target depends="EdkGenericBdsLib_cleanall" name="cleanall"/>

+   <target name="EdkGenericBdsLib_clean">

+      <OutputDirSetup baseName="EdkGenericBdsLib" mbdFilename="${MODULE_DIR}\EdkGenericBdsLib.mbd" msaFilename="${MODULE_DIR}\EdkGenericBdsLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\EdkGenericBdsLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\EdkGenericBdsLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkGenericBdsLib_cleanall">

+      <OutputDirSetup baseName="EdkGenericBdsLib" mbdFilename="${MODULE_DIR}\EdkGenericBdsLib.mbd" msaFilename="${MODULE_DIR}\EdkGenericBdsLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\EdkGenericBdsLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\EdkGenericBdsLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkGenericBdsLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.mbd b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.mbd
new file mode 100644
index 0000000..8e23782
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>EdkNt32PeiPeCoffGetEntryPointLib</BaseName>

+    <Guid>434b164e-5fa6-4a3d-bc04-02da2a4eeb26</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.msa b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.msa
new file mode 100644
index 0000000..70d94bf
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/EdkNt32PeiPeCoffGetEntryPointLib.msa
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>EdkNt32PeiPeCoffGetEntryPointLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>434b164e-5fa6-4a3d-bc04-02da2a4eeb26</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeCoffGetEntryPointLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeCoffGetEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">NtPeiLoadFile</Ppi>

+  </PPIs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
new file mode 100644
index 0000000..ed64158
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
@@ -0,0 +1,75 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  PeCoffGetEntryPoint.c

+

+Abstract:

+

+  Tiano PE/COFF loader

+

+Revision History

+

+--*/

+

+

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetEntryPoint (

+  IN     VOID  *Pe32Data,

+  IN OUT VOID  **EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  Loads a PE/COFF image into memory

+

+Arguments:

+

+  Pe32Data   - Pointer to a PE/COFF Image

+

+  EntryPoint - Pointer to the entry point of the PE/COFF image

+

+Returns:

+

+  EFI_SUCCESS            if the EntryPoint was returned

+  EFI_INVALID_PARAMETER  if the EntryPoint could not be found from Pe32Data

+

+--*/

+{

+  EFI_STATUS              Status;

+  EFI_PEI_PPI_DESCRIPTOR  *PpiDescriptor;

+  NT_PEI_LOAD_FILE_PPI    *PeiNtService;

+  EFI_PHYSICAL_ADDRESS    ImageAddress;

+  UINT64                  ImageSize;

+  EFI_PHYSICAL_ADDRESS    ImageEntryPoint;

+

+  Status = PeiCoreLocatePpi (

+             &gNtPeiLoadFilePpiGuid,

+             0,

+             &PpiDescriptor,

+             &PeiNtService

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = PeiNtService->PeiLoadFileService (

+                           Pe32Data,

+                           &ImageAddress,

+                           &ImageSize,

+                           &ImageEntryPoint

+                           );

+  *EntryPoint = (VOID*)(UINTN)ImageEntryPoint;

+  return Status;

+}
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/build.xml b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/build.xml
new file mode 100644
index 0000000..c558a9b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="EdkNt32PeiPeCoffGetEntryPointLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library\EdkNt32PeiPeCoffGetEntryPointLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="EdkNt32PeiPeCoffGetEntryPointLib">

+      <GenBuild baseName="EdkNt32PeiPeCoffGetEntryPointLib" mbdFilename="${MODULE_DIR}\EdkNt32PeiPeCoffGetEntryPointLib.mbd" msaFilename="${MODULE_DIR}\EdkNt32PeiPeCoffGetEntryPointLib.msa"/>

+   </target>

+   <target depends="EdkNt32PeiPeCoffGetEntryPointLib_clean" name="clean"/>

+   <target depends="EdkNt32PeiPeCoffGetEntryPointLib_cleanall" name="cleanall"/>

+   <target name="EdkNt32PeiPeCoffGetEntryPointLib_clean">

+      <OutputDirSetup baseName="EdkNt32PeiPeCoffGetEntryPointLib" mbdFilename="${MODULE_DIR}\EdkNt32PeiPeCoffGetEntryPointLib.mbd" msaFilename="${MODULE_DIR}\EdkNt32PeiPeCoffGetEntryPointLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\EdkNt32PeiPeCoffGetEntryPointLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\EdkNt32PeiPeCoffGetEntryPointLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="EdkNt32PeiPeCoffGetEntryPointLib_cleanall">

+      <OutputDirSetup baseName="EdkNt32PeiPeCoffGetEntryPointLib" mbdFilename="${MODULE_DIR}\EdkNt32PeiPeCoffGetEntryPointLib.mbd" msaFilename="${MODULE_DIR}\EdkNt32PeiPeCoffGetEntryPointLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\EdkNt32PeiPeCoffGetEntryPointLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\EdkNt32PeiPeCoffGetEntryPointLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**EdkNt32PeiPeCoffGetEntryPointLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoader.c b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoader.c
new file mode 100644
index 0000000..d06e57a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoader.c
@@ -0,0 +1,51 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  TianoPeCoffLoader.c

+

+Abstract:

+

+  Wrap the Base PE/COFF loader with the PE COFF Protocol

+

+

+--*/

+

+

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL  *mPeiEfiPeiPeCoffLoader;

+

+EFI_STATUS

+PeCoffLoaderConstructor (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = (*PeiServices)->LocatePpi (

+                            PeiServices,

+                            &gEfiPeiPeCoffLoaderGuid,

+                            0,

+                            NULL,

+                            &mPeiEfiPeiPeCoffLoader

+                            );

+  return Status;

+}

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL *

+EFIAPI

+GetPeCoffLoaderProtocol (

+  )

+{

+  return mPeiEfiPeiPeCoffLoader;

+}

diff --git a/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.mbd b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.mbd
new file mode 100644
index 0000000..233d7d3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>Nt32PeCoffLoaderLib</BaseName>

+    <Guid>3c5702f2-9b17-4273-b60c-b96e6cd13066</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-31 13:20</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.msa b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.msa
new file mode 100644
index 0000000..7015fc4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.msa
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>Nt32PeCoffLoaderLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>3c5702f2-9b17-4273-b60c-b96e6cd13066</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-31 13:20</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">EdkPeCoffLoaderLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Nt32PeCoffLoader.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">PeCoffLoader</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <Constructor>PeCoffLoaderConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/build.xml b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/build.xml
new file mode 100644
index 0000000..1ca1244
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Library/Nt32PeCoffLoaderLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Nt32PeCoffLoaderLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library\Nt32PeCoffLoaderLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Nt32PeCoffLoaderLib">

+      <GenBuild baseName="Nt32PeCoffLoaderLib" mbdFilename="${MODULE_DIR}\Nt32PeCoffLoaderLib.mbd" msaFilename="${MODULE_DIR}\Nt32PeCoffLoaderLib.msa"/>

+   </target>

+   <target depends="Nt32PeCoffLoaderLib_clean" name="clean"/>

+   <target depends="Nt32PeCoffLoaderLib_cleanall" name="cleanall"/>

+   <target name="Nt32PeCoffLoaderLib_clean">

+      <OutputDirSetup baseName="Nt32PeCoffLoaderLib" mbdFilename="${MODULE_DIR}\Nt32PeCoffLoaderLib.mbd" msaFilename="${MODULE_DIR}\Nt32PeCoffLoaderLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Nt32PeCoffLoaderLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Nt32PeCoffLoaderLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Nt32PeCoffLoaderLib_cleanall">

+      <OutputDirSetup baseName="Nt32PeCoffLoaderLib" mbdFilename="${MODULE_DIR}\Nt32PeCoffLoaderLib.mbd" msaFilename="${MODULE_DIR}\Nt32PeCoffLoaderLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Nt32PeCoffLoaderLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Nt32PeCoffLoaderLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Nt32PeCoffLoaderLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Logo/Logo.mbd b/edk2/EdkNt32Pkg/Logo/Logo.mbd
new file mode 100644
index 0000000..346ff12
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Logo/Logo.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Logo</BaseName>

+    <Guid>7BB28B99-61BB-11D5-9A5D-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Logo/Logo.msa b/edk2/EdkNt32Pkg/Logo/Logo.msa
new file mode 100644
index 0000000..aae557a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Logo/Logo.msa
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Logo</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LOGO</ComponentType>

+    <Guid>7BB28B99-61BB-11D5-9A5D-0090273FC14D</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for creating a Logo file.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <SourceFiles>

+    <Filename FileType="Graphics">Logo.bmp</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <BuildOptions>

+    <Option>BUILD_TYPE=CUSTOM_BUILD</Option>

+  </BuildOptions>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Logo/Logo_build.xml b/edk2/EdkNt32Pkg/Logo/Logo_build.xml
new file mode 100644
index 0000000..bbc8b00
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Logo/Logo_build.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="Logo" default="main" basedir="." >

+  <!-- Apply external ANT task -->

+  <taskdef resource="frameworktasks.tasks" /> 

+  <taskdef resource="cpptasks.tasks" /> 

+  <typedef resource="cpptasks.types" /> 

+  <taskdef resource="net/sf/antcontrib/antlib.xml" />

+  <property environment="env" />

+  <!-- All Properties --> 

+  <property name="BASE_NAME" value="Logo" /> 

+  

+  <!-- Default target --> 

+  <target name="main" depends="libraries, sourcefiles, sections, output" /> 

+  <!-- Compile all dependency Library instances. --> 

+  <target name="libraries" />

+

+  <target name="sourcefiles">

+    <copy file="${MODULE_DIR}\Logo.bmp" 

+      tofile="${DEST_DIR_OUTPUT}\Logo.bmp" />

+    <!--

+    <Build_Graphics FILENAME="logo" FILEPATH="." FILEEXT="bmp"></Build_Graphics>

+    -->

+  </target>

+  

+  <target name="sections">

+    <OnDependency>

+      <sourcefiles>

+        <file name="${DEST_DIR_OUTPUT}\logo.bmp"/>

+      </sourcefiles>

+      <targetfiles>

+        <file name="${DEST_DIR_OUTPUT}\Logo.bin"/>

+      </targetfiles>

+      

+      <sequential>

+        <gensection inputfile="${DEST_DIR_OUTPUT}\logo.bmp" 

+          outputfile="${DEST_DIR_OUTPUT}\Logo.bin" 

+          sectiontype="EFI_SECTION_RAW" />

+      </sequential>

+    </OnDependency>

+  </target>

+

+  <target name="output">

+    <OnDependency>

+      <sourcefiles>

+        <file name="${DEST_DIR_OUTPUT}\Logo.bin"/>

+      </sourcefiles>

+      <targetfiles>

+        <file name="${BIN_DIR}\7BB28B99-61BB-11D5-9A5D-0090273FC14D-Logo.FFS"/>

+      </targetfiles>

+      

+      <sequential>

+        <genffsfile BaseName="Logo" ffsATTRIBCHECKSUM="TRUE"

+          ffsFILETYPE="EFI_FV_FILETYPE_FREEFORM" fileGuid="7BB28B99-61BB-11D5-9A5D-0090273FC14D"

+          outputDir="${BIN_DIR}">

+          <compress compressName="dummy">

+            <tool outputPath="${DEST_DIR_OUTPUT}" toolName="${WORKSPACE_DIR}\Tools\Bin\GenCRC32Section">

+              <input file="${DEST_DIR_OUTPUT}\Logo.bin" />

+            </tool>

+          </compress>

+        </genffsfile>

+      </sequential>

+    </OnDependency>

+  </target>

+    

+</project>

diff --git a/edk2/EdkNt32Pkg/Logo/build.xml b/edk2/EdkNt32Pkg/Logo/build.xml
new file mode 100644
index 0000000..f9828f3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Logo/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Logo"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Logo"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="Logo">

+      <GenBuild baseName="Logo" mbdFilename="${MODULE_DIR}\Logo.mbd" msaFilename="${MODULE_DIR}\Logo.msa"/>

+   </target>

+   <target depends="Logo_clean" name="clean"/>

+   <target depends="Logo_cleanall" name="cleanall"/>

+   <target name="Logo_clean">

+      <OutputDirSetup baseName="Logo" mbdFilename="${MODULE_DIR}\Logo.mbd" msaFilename="${MODULE_DIR}\Logo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Logo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Logo_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Logo_cleanall">

+      <OutputDirSetup baseName="Logo" mbdFilename="${MODULE_DIR}\Logo.mbd" msaFilename="${MODULE_DIR}\Logo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\Logo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\Logo_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Logo*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Logo/logo.bmp b/edk2/EdkNt32Pkg/Logo/logo.bmp
new file mode 100644
index 0000000..3e85229
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Logo/logo.bmp
Binary files differ
diff --git a/edk2/EdkNt32Pkg/Nt32.fpd b/edk2/EdkNt32Pkg/Nt32.fpd
new file mode 100644
index 0000000..0f944c4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Nt32.fpd
@@ -0,0 +1,11305 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<FrameworkPlatformDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <PlatformHeader>

+    <PlatformName>NT32</PlatformName>

+    <GuidValue>eb216561-961f-47ee-9ef9-ca426ef547c2</GuidValue>

+    <Version>0.3</Version>

+    <Abstract>EFI/Framework Emulation Platform</Abstract>

+    <Description>

+      The Emulation Platform can be used to debug individual modules, prior to creating

+      a real platform. This also provides an example for how an FPD is created.

+    </Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-02-23 18:21</CreatedDate>

+    <ModifiedDate>2006-06-03 20:20</ModifiedDate>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>

+  </PlatformHeader>

+  <Flash>

+    <FlashDefinitionFile>FlashMap.fdf</FlashDefinitionFile>

+    <FvImages>

+      <!-- Global Variables -->

+      <NameValue Name="FV_RECOVERY_BASE_ADDRESS" Value="0xFFD80000"/>

+      <NameValue Name="FV_MAIN_BASE_ADDRESS" Value="0xFFF00000"/>

+      <!-- Define Valid Image Names -->

+      <FvImage Type="ValidImageNames">

+        <FvImageNames>FV_RECOVERY</FvImageNames>

+        <!-- <FvImageNames>FV_FILE</FvImageNames> This is not defined for Nt32 -->

+        <FvImageNames>NV_STORAGE</FvImageNames>

+      </FvImage>

+      <!-- Define Attributes for on or more Images Names -->

+      <FvImage Type="Attributes">

+        <FvImageNames>FV_RECOVERY</FvImageNames>

+        <FvImageNames>NV_STORAGE</FvImageNames>

+        <FvImageNames>FV_FILE</FvImageNames>

+        <FvImageOptions>

+          <NameValue Name="EFI_ERASE_POLARITY" Value="1"/>

+          <Enable>EFI_READ_DISABLED_CAP</Enable>

+          <Enable>EFI_READ_ENABLED_CAP</Enable>

+          <Enable>EFI_READ_STATUS</Enable>

+          <Enable>EFI_WRITE_DISABLED_CAP</Enable>

+          <Enable>EFI_WRITE_ENABLED_CAP</Enable>

+          <Enable>EFI_WRITE_STATUS</Enable>

+          <Enable>EFI_LOCK_CAP</Enable>

+          <Enable>EFI_LOCK_STATUS</Enable>

+          <Enable>EFI_MEMORY_MAPPED</Enable>

+          <Enable>EFI_ALIGNMENT_CAP</Enable>

+          <Enable>EFI_ALIGNMENT_2</Enable>

+          <Enable>EFI_ALIGNMENT_4</Enable>

+          <Enable>EFI_ALIGNMENT_8</Enable>

+          <Enable>EFI_ALIGNMENT_16</Enable>

+          <Enable>EFI_ALIGNMENT_32</Enable>

+          <Enable>EFI_ALIGNMENT_64</Enable>

+          <Enable>EFI_ALIGNMENT_128</Enable>

+          <Enable>EFI_ALIGNMENT_256</Enable>

+          <Enable>EFI_ALIGNMENT_512</Enable>

+          <Enable>EFI_ALIGNMENT_1K</Enable>

+          <Enable>EFI_ALIGNMENT_2K</Enable>

+          <Enable>EFI_ALIGNMENT_4K</Enable>

+          <Enable>EFI_ALIGNMENT_8K</Enable>

+          <Enable>EFI_ALIGNMENT_16K</Enable>

+          <Enable>EFI_ALIGNMENT_32K</Enable>

+          <Enable>EFI_ALIGNMENT_64K</Enable>

+          <Disable>EFI_STICKY_WRITE</Disable>

+        </FvImageOptions>

+      </FvImage>

+      <!-- Define Components for one or more Image Names -->

+      <FvImage Type="Components">

+        <FvImageNames>NV_STORAGE</FvImageNames>

+        <FvImageOptions>

+          <NameValue Name="EFI_NV_VARIABLE" Value="0xC000"/>

+          <NameValue Name="EFI_NV_EVENT_LOG" Value="0x2000"/>

+          <NameValue Name="EFI_NV_FTW_WORKING" Value="0x2000"/>

+          <NameValue Name="EFI_NV_FTW_SPARE" Value="0x10000"/>

+        </FvImageOptions>

+      </FvImage>

+      <!-- Define Options for Individual Image Names -->

+      <FvImageName Name="FV_RECOVERY">

+        <FvImageOptions>

+          <NameValue Name="EFI_BASE_ADDRESS" Value="${FV_RECOVERY_BASE_ADDRESS}"/>

+          <NameValue Name="EFI_FILE_NAME" Value="FV_RECOVERY.fv"/>

+          <NameValue Name="EFI_NUM_BLOCKS" Value="0x28"/>

+          <NameValue Name="EFI_BLOCK_SIZE" Value="0x10000"/>

+        </FvImageOptions>

+      </FvImageName>

+      <FvImageName Name="FV_FILE">

+        <FvImageOptions>

+          <NameValue Name="EFI_BASE_ADDRESS" Value="0x00000000"/>

+          <NameValue Name="EFI_FILE_NAME" Value="${FV_FILENAME}.fv"/>

+          <NameValue Name="EFI_SYM_FILE_NAME" Value="${FV_FILENAME}.sym"/>

+          <NameValue Name="EFI_NUM_BLOCKS" Value="0x2"/>

+          <NameValue Name="EFI_BLOCK_SIZE" Value="0x10000"/>

+        </FvImageOptions>

+      </FvImageName>

+      <FvImageName Name="NV_STORAGE">

+        <FvImageOptions>

+          <NameValue Name="EFI_BASE_ADDRESS" Value="0xFFFC0000"/>

+          <NameValue Name="EFI_FILE_NAME" Value="${FV_FILENAME}.fv"/>

+          <NameValue Name="EFI_NUM_BLOCKS" Value="0x2"/>

+          <NameValue Name="EFI_BLOCK_SIZE" Value="0x10000"/>

+          <NameValue Name="EFI_FV_GUID" Value="fff12b8d-7696-4c8b-a985-2747075b4f50"/>

+        </FvImageOptions>

+      </FvImageName>

+    </FvImages>

+    <Capsules>

+      <Capsule>

+        <CapsuleId>A</CapsuleId>

+        <CapsuleOptions>

+          <NameValue Name="EFI_BASE_ADDRESS" Value="${FV_RECOVERY_BASE_ADDRESS}"/>

+          <NameValue Name="EFI_FILE_NAME" Value="Capsule_A.fv"/>

+          <NameValue Name="EFI_NUM_BLOCKS" Value="0x28"/>

+          <NameValue Name="EFI_BLOCK_SIZE" Value="0x10000"/>

+        </CapsuleOptions>

+      </Capsule>

+    </Capsules>

+  </Flash>

+  <TianoImage>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SecMain"/>

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiMain">

+        <Includes>

+          <Arch ArchType="IA32">

+            <PackageName>EdkNt32Pkg</PackageName>

+          </Arch>

+        </Includes>

+        <Libraries>

+          <Arch ArchType="IA32">

+            <Library OverrideID="6666">EdkNt32PeiPeCoffGetEntryPointLib</Library>

+          </Arch>

+        </Libraries>

+      </ModuleSA>

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdPeim"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="MonoStatusCode"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="BootMode"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiFlashMap"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiBaseMemoryTestInit"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiVariable"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtAutoScan"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtFwh"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtStuff"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DxeIpl">

+        <Libraries>

+          <Arch ArchType="IA32">

+            <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>

+          </Arch>

+        </Libraries>

+      </ModuleSA>

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DxeMain"/>

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdDxe"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Crc32SectionExtract"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Cpu"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Metronome"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Timer"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="RealTimeClock"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Reset"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Bds"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WatchDogTimer"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Runtime"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="MonotonicCounter"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="StatusCode"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="FwBlockService"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="FtwLite"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Variable"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="SecurityStub"/>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugPort"/>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugSupport"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ConPlatform"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ConSplitter"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="GraphicsConsole"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Terminal"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DataHub"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DataHubStdErr"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DiskIo"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DiskIoPartition"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Ebc"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="NullMemoryTest"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="HiiDatabase"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Partition"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Logo"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PciBus"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="SetupBrowser"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DriverSample"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="English"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="AtapiPassThru"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="CirrusLogic5430UgaDraw"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="IdeBus"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Uhci"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ScsiBus"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ScsiDisk"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbBot"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbBus"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbCbi0"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbCbi1"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbKb"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbMassStorage"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbMouse"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="BC"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Dhcp4"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="SNP"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtThunk"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtBusDriver"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtBlockIo"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtConsole"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtSerialIo"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtSimpleFileSystem"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtUga"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="MiscSubclass"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Shell"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Fat"/>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="HelloWorld"/>

+    </DXE_DRIVERS>

+  </TianoImage>

+  <FrameworkModules>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="SecMain">

+        <PcdBuildDeclarations>

+            <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtCpuModel</C_Name>

+            <Token>0x00001007</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>48</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"Intel(R) Processor Model"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdWinNtFirmwareVolume</C_Name>

+            <Token>0x00001009</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>44</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"..\\..\\Fv\\Fv_Recovery.fd"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdWinNtBootMode</C_Name>

+            <Token>0x00001006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtMemorySize</C_Name>

+            <Token>0x00001005</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>10</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"64!64"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdWinNtMemorySizeForSecMain</C_Name>

+            <Token>0x00001005</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>10</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>L"64!64"</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiMain">

+        <Includes>

+          <Arch ArchType="IA32">

+            <PackageName>EdkNt32Pkg</PackageName>

+          </Arch>

+        </Includes>

+        <Libraries>

+          <Arch ArchType="IA32">

+            <Library OverrideID="6666">EdkNt32PeiPeCoffGetEntryPointLib</Library>

+          </Arch>

+        </Libraries>

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdPeim">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+            <Token>0x0001000f</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x8</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdVpdBaseAddress</C_Name>

+            <Token>0x00010010</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x0</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeimPcdTest">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdTestDynamicUint8</C_Name>

+            <Token>0x00011000</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x1</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdTestDynamicUint16</C_Name>

+            <Token>0x00011001</Token>

+            <DatumType>UINT16</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>2</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x1234</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdTestDynamicUint32</C_Name>

+            <Token>0x00011002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>NoDefault</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdTestDynamicUint64</C_Name>

+            <Token>0x00011003</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>8</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>NoDefault</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdTestDynamicBoolean</C_Name>

+            <Token>0x00011004</Token>

+            <DatumType>BOOLEAN</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>NoDefault</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>      

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="MonoStatusCode">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="BootMode">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiFlashMap">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiBaseMemoryTestInit">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PeiVariable">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtAutoScan">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtFwh">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtStuff">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DxeIpl">

+        <Libraries>

+          <Arch ArchType="IA32">

+            <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>

+          </Arch>

+        </Libraries>

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DxeMain">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PcdDxe">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>

+            <Token>0x0001000f</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x8</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdVpdBaseAddress</C_Name>

+            <Token>0x00010010</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x0</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Crc32SectionExtract">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Cpu">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Metronome">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Timer">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="RealTimeClock">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Reset">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Bds">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WatchDogTimer">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Runtime">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="MonotonicCounter">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="StatusCode">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="FwBlockService">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="FtwLite">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Variable">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="SecurityStub">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugPort">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DebugSupport">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ConPlatform">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ConSplitter">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="GraphicsConsole">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Terminal">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DataHub">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DataHubStdErr">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DiskIo">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DiskIoPartition">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Ebc">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="NullMemoryTest">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="HiiDatabase">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Partition">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Logo">

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="PciBus">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="SetupBrowser">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="DriverSample">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="English">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="AtapiPassThru">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="CirrusLogic5430UgaDraw">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="IdeBus">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Uhci">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ScsiBus">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="ScsiDisk">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbBot">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbBus">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbCbi0">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbCbi1">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbKb">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbMassStorage">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="UsbMouse">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="BC">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Dhcp4">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="SNP">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtThunk">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtBusDriver">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtMemorySize</C_Name>

+            <Token>0x00001005</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>10</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"64!64"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtPhysicalDisk</C_Name>

+            <Token>0x00001000</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>24</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"FW;40960;512"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtVirtualDisk</C_Name>

+            <Token>0x00001001</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>24</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"FW;40960;512"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtSerialPort</C_Name>

+            <Token>0x00001002</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>20</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>L"COM1!COM2"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtUga</C_Name>

+            <Token>0x00001003</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>50</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"UGA Window 1!UGA Window 2"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtCpuModel</C_Name>

+            <Token>0x00001007</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>48</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"Intel(R) Processor Model"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtFileSystem</C_Name>

+            <Token>0x00001004</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>120</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L".!C:\\D\\work\\Remodel\\mdk\\EdkShellBinPkg\\bin\\ia32\\Apps"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtConsole</C_Name>

+            <Token>0x0000100a</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>50</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>L"Bus Driver Console Window"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtCpuSpeed</C_Name>

+            <Token>0x00001008</Token>

+            <DatumType>VOID*</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>8</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>L"3000"</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FEATURE_FLAG">

+            <C_Name>PcdWinNtFeatureFlag1</C_Name>

+            <Token>0x0001000d</Token>

+            <DatumType>BOOLEAN</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x1</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdWinNtBinaryPatch1</C_Name>

+            <Token>0x0001000b</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x1234</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdWinNtBinaryPatch2</C_Name>

+            <Token>0x0001000c</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x5678</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="DYNAMIC">

+            <C_Name>PcdWinNtDynamicUINT32</C_Name>

+            <Token>0x0001000e</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0x0</DefaultValue>

+          </PcdBuildData>

+          

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtBlockIo">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtConsole">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtSerialIo">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtSimpleFileSystem">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="WinNtUga">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="MiscSubclass">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Shell">

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="Fat">

+      </ModuleSA>

+      <ModuleSA Arch="IA32" FvBinding="FV_RECOVERY" ModuleName="HelloWorld">

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x1f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>

+    </DXE_DRIVERS>

+  </FrameworkModules>

+  <PcdDynamicBuildDeclarations>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtMemorySize</C_Name>

+      <Token>0x00001005</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>10</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L"64!64"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtCpuModel</C_Name>

+      <Token>0x00001007</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>48</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L"Intel(R) Processor Model"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtPhysicalDisk</C_Name>

+      <Token>0x00001000</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>24</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L"FW;40960;512"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtVirtualDisk</C_Name>

+      <Token>0x00001001</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>24</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L"FW;40960;512"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtFileSystem</C_Name>

+      <Token>0x00001004</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>120</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L".!C:\\D\\work\\Remodel\\mdk\\EdkShellBinPkg\\bin\\ia32\\Apps"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtSerialPort</C_Name>

+      <Token>0x00001002</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>20</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L"COM1!COM2"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtConsole</C_Name>

+      <Token>0x0000100a</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>50</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <DefaultValue>L"Bus Driver Console Window"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtUga</C_Name>

+      <Token>0x00001003</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>50</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <DefaultValue>L"UGA Window 1!UGA Window 2"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint8</C_Name>

+      <Token>0x00011000</Token>

+      <DatumType>UINT8</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>1</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>0x1</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint16</C_Name>

+      <Token>0x00011001</Token>

+      <DatumType>UINT16</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>2</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>0x1234</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint32</C_Name>

+      <Token>0x00011002</Token>

+      <DatumType>UINT32</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>4</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>NoDefault</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicUint64</C_Name>

+      <Token>0x00011003</Token>

+      <DatumType>UINT64</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>8</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>NoDefault</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdTestDynamicBoolean</C_Name>

+      <Token>0x00011004</Token>

+      <DatumType>BOOLEAN</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>1</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>NoDefault</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtCpuSpeed</C_Name>

+      <Token>0x00001008</Token>

+      <DatumType>VOID*</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>8</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>L"3000"</DefaultValue>

+    </PcdBuildData>

+    <PcdBuildData ItemType="DYNAMIC">

+      <C_Name>PcdWinNtDynamicUINT32</C_Name>

+      <Token>0x0001000e</Token>

+      <DatumType>UINT32</DatumType>

+      <HiiEnable>false</HiiEnable>

+      <VpdEnable>false</VpdEnable>

+      <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+      <SkuEnable>false</SkuEnable>

+      <SkuDataArrayEnable>false</SkuDataArrayEnable>

+      <MaxSku>0x00</MaxSku>

+      <SkuId>0x00</SkuId>

+      <DatumSize>4</DatumSize>

+      <VariableGuid>0</VariableGuid>

+      <VariableName>L""</VariableName>

+      <DataOffset>0</DataOffset>

+      <GuidOffset>0</GuidOffset>

+      <DefaultValue>0x0</DefaultValue>

+    </PcdBuildData>

+  </PcdDynamicBuildDeclarations>

+  <BuildOptions>

+    <OutputDirectory IntermediateDirectories="UNIFIED"/>

+    <Option>CC_FLAGS="/nologo", "/W4", "/WX", "/GX", "/Gy", "/c", "/D EFI_MONOSHELL", "/D UNICODE", "/D EFI_DEBUG", "/D EFI_PEI_REPORT_STATUS_CODE_ON", "/Zi", "/D EFI32", "/DEFI_NT_EMULATOR", "/DNEW_PEI_HOBS", "/Odiyb2", "/GL", "/G7", "/Gy", "/DSTRING_ARRAY_NAME=${BASE_NAME}Strings", "/DSTRING_DEFINES_FILE=\"${BASE_NAME}StrDefs.h\""</Option>

+    <Option>LIB_FLAGS = "/NOLOGO", "/LTCG"</Option>

+    <Option>LINK_FLAGS = "/NOLOGO", "/SUBSYSTEM:CONSOLE", "/DEF:${PLATFORM_DIR}\Build\component.def", "/NODEFAULTLIB", "/IGNORE:4086", "/OPT:REF", "/MAP", "/DEBUG", "/MACHINE:I386", "/LTCG", "/DLL"</Option>

+    <Option>ASM_FLAGS = "/nologo", "/W3", "/WX", "/c", "/coff", "/DEFI32", "/DDEBUG", "/Cx", "/Zd", "/Zi", "/DEFI_NT_EMULATOR"</Option>

+  </BuildOptions>

+</FrameworkPlatformDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoScan.mbd b/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoScan.mbd
new file mode 100644
index 0000000..c6a123d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoScan.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtAutoScan</BaseName>

+    <Guid>BE0FEABA-3443-4919-9F3A-2D4216329EA9</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoScan.msa b/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoScan.msa
new file mode 100644
index 0000000..887eaf6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoScan.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtAutoScan</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>BE0FEABA-3443-4919-9F3A-2D4216329EA9</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtAutoScan module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtAutoScan.c</Filename>

+    <Filename>WinNtAutoscan.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="RESOURCE_DESCRIPTOR">

+      <Name>EFI_RESOURCE_SYSTEM_MEMORY</Name>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="CPU"></Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">NtAutoScan</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">BaseMemoryTest</Ppi>

+    <Ppi Usage="ALWAYS_PRODUCED">MemoryDiscovered</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimInitializeWinNtAutoScan</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoscan.dxs b/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoscan.dxs
new file mode 100644
index 0000000..5b3af0e
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/Autoscan/WinNtAutoscan.dxs
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtAutoscan.dxs

+

+Abstract:

+

+  Dependency expression file for WinNtAutoscan.

+

+--*/  

+

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+  PEI_NT_AUTOSCAN_PPI_GUID AND EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI AND PEI_BASE_MEMORY_TEST_GUID

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkNt32Pkg/Pei/Autoscan/WinntAutoscan.c b/edk2/EdkNt32Pkg/Pei/Autoscan/WinntAutoscan.c
new file mode 100644
index 0000000..c465ce6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/Autoscan/WinntAutoscan.c
@@ -0,0 +1,132 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  WinNtAutoscan.c

+

+Abstract:

+  Tiano PEIM to abstract memory auto-scan in a Windows NT environment.

+

+Revision History

+

+--*/

+

+EFI_STATUS

+EFIAPI

+PeimInitializeWinNtAutoScan (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+  Perform a call-back into the SEC simulator to get a memory value

+

+Arguments:

+  FfsHeader   - General purpose data available to every PEIM

+  PeiServices - General purpose services available to every PEIM.

+    

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PEI_PPI_DESCRIPTOR      *PpiDescriptor;

+  PEI_NT_AUTOSCAN_PPI         *PeiNtService;

+  UINT64                      MemorySize;

+  EFI_PHYSICAL_ADDRESS        MemoryBase;

+  PEI_BASE_MEMORY_TEST_PPI    *MemoryTestPpi;

+  EFI_PHYSICAL_ADDRESS        ErrorAddress;

+  UINTN                       Index;

+  EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;

+

+

+  DEBUG ((EFI_D_ERROR, "NT 32 Autoscan PEIM Loaded\n"));

+

+  //

+  // Get the PEI NT Autoscan PPI

+  //

+  Status = (**PeiServices).LocatePpi (

+                            PeiServices,

+                            &gPeiNtAutoScanPpiGuid, // GUID

+                            0,                      // INSTANCE

+                            &PpiDescriptor,         // EFI_PEI_PPI_DESCRIPTOR

+                            &PeiNtService           // PPI

+                            );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get the Memory Test PPI

+  //

+  Status = (**PeiServices).LocatePpi (

+                            PeiServices,

+                            &gPeiBaseMemoryTestPpiGuid,

+                            0,

+                            NULL,

+                            &MemoryTestPpi

+                            );

+  ASSERT_EFI_ERROR (Status);

+

+  Index = 0;

+  do {

+    Status = PeiNtService->NtAutoScan (Index, &MemoryBase, &MemorySize);

+    if (!EFI_ERROR (Status)) {

+      Attributes =

+        (

+          EFI_RESOURCE_ATTRIBUTE_PRESENT |

+          EFI_RESOURCE_ATTRIBUTE_INITIALIZED |

+          EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |

+          EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |

+          EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |

+          EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE

+        );

+

+      if (Index == 0) {

+        //

+        // For the first area register it as PEI tested memory

+        //

+        Status = MemoryTestPpi->BaseMemoryTest (

+                                  PeiServices,

+                                  MemoryTestPpi,

+                                  MemoryBase,

+                                  MemorySize,

+                                  Quick,

+                                  &ErrorAddress

+                                  );

+        ASSERT_EFI_ERROR (Status);

+

+        //

+        // Register the "tested" memory with the PEI Core

+        //

+        Status = (**PeiServices).InstallPeiMemory (PeiServices, MemoryBase, MemorySize);

+        ASSERT_EFI_ERROR (Status);

+

+        Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED;

+      }

+      

+      BuildResourceDescriptorHob (

+        EFI_RESOURCE_SYSTEM_MEMORY,

+        Attributes,

+        MemoryBase,

+        MemorySize

+        );

+    }

+    Index++;

+  } while (!EFI_ERROR (Status));

+

+  //

+  // Build the CPU hob with 36-bit addressing and 16-bits of IO space.

+  //

+  BuildCpuHob (36, 16);

+  

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Pei/Autoscan/build.xml b/edk2/EdkNt32Pkg/Pei/Autoscan/build.xml
new file mode 100644
index 0000000..bdbd4c9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/Autoscan/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtAutoScan"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\Autoscan"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtAutoScan">

+      <GenBuild baseName="WinNtAutoScan" mbdFilename="${MODULE_DIR}\WinNtAutoScan.mbd" msaFilename="${MODULE_DIR}\WinNtAutoScan.msa"/>

+   </target>

+   <target depends="WinNtAutoScan_clean" name="clean"/>

+   <target depends="WinNtAutoScan_cleanall" name="cleanall"/>

+   <target name="WinNtAutoScan_clean">

+      <OutputDirSetup baseName="WinNtAutoScan" mbdFilename="${MODULE_DIR}\WinNtAutoScan.mbd" msaFilename="${MODULE_DIR}\WinNtAutoScan.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtAutoScan_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtAutoScan_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtAutoScan_cleanall">

+      <OutputDirSetup baseName="WinNtAutoScan" mbdFilename="${MODULE_DIR}\WinNtAutoScan.mbd" msaFilename="${MODULE_DIR}\WinNtAutoScan.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtAutoScan_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtAutoScan_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtAutoScan*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.c b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.c
new file mode 100644
index 0000000..955c759
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.c
@@ -0,0 +1,85 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BootMode.c

+   

+Abstract:

+

+  Tiano PEIM to provide the platform support functionality within Windows

+

+--*/

+

+

+

+//

+// Module globals

+//

+EFI_PEI_PPI_DESCRIPTOR  mPpiListBootMode = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiPeiMasterBootModePpiGuid,

+  NULL

+};

+

+EFI_PEI_PPI_DESCRIPTOR  mPpiListRecoveryBootMode = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiPeiBootInRecoveryModePpiGuid,

+  NULL

+};

+

+EFI_STATUS

+EFIAPI

+InitializeBootMode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Peform the boot mode determination logic

+

+Arguments:

+

+  PeiServices - General purpose services available to every PEIM.

+    

+Returns:

+

+  Status -  EFI_SUCCESS if the boot mode could be set

+

+--*/

+// TODO:    FfsHeader - add argument and description to function comment

+{

+  EFI_STATUS  Status;

+  UINTN       BootMode;

+

+  DEBUG ((EFI_D_ERROR, "NT32 Boot Mode PEIM Loaded\n"));

+

+  //

+  // Let's assume things are OK if not told otherwise

+  // Should we read an environment variable in order to easily change this?

+  //

+  BootMode  = BOOT_WITH_FULL_CONFIGURATION;

+

+  Status    = (**PeiServices).SetBootMode (PeiServices, (UINT8) BootMode);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = (**PeiServices).InstallPpi (PeiServices, &mPpiListBootMode);

+  ASSERT_EFI_ERROR (Status);

+

+  if (BootMode == BOOT_IN_RECOVERY_MODE) {

+    Status = (**PeiServices).InstallPpi (PeiServices, &mPpiListRecoveryBootMode);

+    ASSERT_EFI_ERROR (Status);

+  }

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.dxs b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.dxs
new file mode 100644
index 0000000..fd91a09
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.dxs
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  BootMode.dxs

+

+Abstract:

+

+  Dependency expression file for BootMode.

+

+--*/  

+

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.mbd b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.mbd
new file mode 100644
index 0000000..5dd1a6f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.mbd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>BootMode</BaseName>

+    <Guid>B7611005-1F26-45ba-A3DB-01F39DDB2785</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.msa b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.msa
new file mode 100644
index 0000000..bbc56e6
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/BootMode/BootMode.msa
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>BootMode</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>B7611005-1F26-45ba-A3DB-01F39DDB2785</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for Fwh module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BootMode.c</Filename>

+    <Filename>BootMode.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="SOMETIMES_PRODUCED">BootInRecoveryMode</Ppi>

+    <Ppi Usage="ALWAYS_PRODUCED">MasterBootMode</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InitializeBootMode</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/BootMode/build.xml b/edk2/EdkNt32Pkg/Pei/BootMode/build.xml
new file mode 100644
index 0000000..cd67235
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/BootMode/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BootMode"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\BootMode"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="BootMode">

+      <GenBuild baseName="BootMode" mbdFilename="${MODULE_DIR}\BootMode.mbd" msaFilename="${MODULE_DIR}\BootMode.msa"/>

+   </target>

+   <target depends="BootMode_clean" name="clean"/>

+   <target depends="BootMode_cleanall" name="cleanall"/>

+   <target name="BootMode_clean">

+      <OutputDirSetup baseName="BootMode" mbdFilename="${MODULE_DIR}\BootMode.mbd" msaFilename="${MODULE_DIR}\BootMode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\BootMode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\BootMode_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BootMode_cleanall">

+      <OutputDirSetup baseName="BootMode" mbdFilename="${MODULE_DIR}\BootMode.mbd" msaFilename="${MODULE_DIR}\BootMode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\BootMode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\BootMode_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BootMode*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.dxs b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.dxs
new file mode 100644
index 0000000..6270ef0
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.dxs
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtFwh.dxs

+

+Abstract:

+

+  Dependency expression file for WinNtFwh PEIM.

+

+--*/  

+

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+  NT_FWH_PPI_GUID AND EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.mbd b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.mbd
new file mode 100644
index 0000000..3c61664
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtFwh</BaseName>

+    <Guid>F0384FFD-8633-452f-9010-F6B7D2EAE2F1</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-23 10:33</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.msa b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.msa
new file mode 100644
index 0000000..e70d4dd
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinNtFwh.msa
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtFwh</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>F0384FFD-8633-452f-9010-F6B7D2EAE2F1</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtFwh module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-23 10:33</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtFwh.c</Filename>

+    <Filename>WinNtFwh.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="FIRMWARE_VOLUME">

+      <Name>FvRecovery.fv</Name>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="RESOURCE_DESCRIPTOR">

+      <Name>EFI_RESOURCE_FIRMWARE_DEVICE</Name>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="FIRMWARE_VOLUME">

+      <Name>NVSTORAGE.fv</Name>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">NtFwh</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimInitializeWinNtFwh</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinntFwh.c b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinntFwh.c
new file mode 100644
index 0000000..3764cb7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/WinntFwh.c
@@ -0,0 +1,123 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  WinNtFwh.c

+    

+Abstract:

+  PEIM to abstract construction of firmware volume in a Windows NT environment.

+

+Revision History

+

+--*/

+

+

+#include <FlashLayout.h>

+

+

+EFI_STATUS

+EFIAPI

+PeimInitializeWinNtFwh (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+  Perform a call-back into the SEC simulator to get address of the Firmware Hub

+

+Arguments:

+  FfsHeader   - Ffs Header availible to every PEIM

+  PeiServices - General purpose services available to every PEIM.

+    

+Returns:

+  None

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PEI_PPI_DESCRIPTOR      *PpiDescriptor;

+  NT_FWH_PPI                  *FwhPpi;

+  EFI_PHYSICAL_ADDRESS        FdBase;

+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

+  UINT64                      FdSize;

+  UINTN                       Index;

+

+  DEBUG ((EFI_D_ERROR, "NT 32 Firmware Volume PEIM Loaded\n"));

+

+  //

+  // Get the Fwh Information PPI

+  //

+  Status = (**PeiServices).LocatePpi (

+                            PeiServices,

+                            &gNtFwhPpiGuid, // GUID

+                            0,              // INSTANCE

+                            &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR

+                            &FwhPpi         // PPI

+                            );

+  ASSERT_EFI_ERROR (Status);

+

+  Index = 0;

+  do {

+    //

+    // Get information about all the FD's in the system

+    //

+    Status = FwhPpi->NtFwh (Index, &FdBase, &FdSize);

+    if (!EFI_ERROR (Status)) {

+      //

+      // Assume the FD starts with an FV header

+      //

+      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FdBase;

+

+      //

+      // Make an FV Hob for the first FV in the FD

+      //

+      BuildFvHob (FdBase, FvHeader->FvLength);

+

+      if (Index == 0) {

+        //

+        // Assume the first FD was produced by the NT32.DSC

+        //  All these strange offests are needed to keep in

+        //  sync with the FlashMap and NT32.dsc file

+        //

+        BuildResourceDescriptorHob (

+          EFI_RESOURCE_FIRMWARE_DEVICE,

+          (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),

+          FdBase,

+          (FvHeader->FvLength + EFI_WINNT_RUNTIME_UPDATABLE_LENGTH + EFI_WINNT_FTW_SPARE_BLOCK_LENGTH)

+          );

+

+        //

+        // Hard code the address of the spare block and variable services.

+        //  Assume it's a hard coded offset from FV0 in FD0.

+        //

+        FdBase  = FdBase + EFI_WINNT_RUNTIME_UPDATABLE_OFFSET;

+        FdSize  = EFI_WINNT_RUNTIME_UPDATABLE_LENGTH + EFI_WINNT_FTW_SPARE_BLOCK_LENGTH;

+

+        BuildFvHob (FdBase, FdSize);

+      } else {

+        //

+        // For other FD's just map them in.

+        //

+        BuildResourceDescriptorHob (

+          EFI_RESOURCE_FIRMWARE_DEVICE,

+          (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),

+          FdBase,

+          FdSize

+          );

+      }

+    }

+

+    Index++;

+  } while (!EFI_ERROR (Status));

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Pei/FirmwareVolume/build.xml b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/build.xml
new file mode 100644
index 0000000..7aa147b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FirmwareVolume/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtFwh"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\FirmwareVolume"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtFwh">

+      <GenBuild baseName="WinNtFwh" mbdFilename="${MODULE_DIR}\WinNtFwh.mbd" msaFilename="${MODULE_DIR}\WinNtFwh.msa"/>

+   </target>

+   <target depends="WinNtFwh_clean" name="clean"/>

+   <target depends="WinNtFwh_cleanall" name="cleanall"/>

+   <target name="WinNtFwh_clean">

+      <OutputDirSetup baseName="WinNtFwh" mbdFilename="${MODULE_DIR}\WinNtFwh.mbd" msaFilename="${MODULE_DIR}\WinNtFwh.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtFwh_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtFwh_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtFwh_cleanall">

+      <OutputDirSetup baseName="WinNtFwh" mbdFilename="${MODULE_DIR}\WinNtFwh.mbd" msaFilename="${MODULE_DIR}\WinNtFwh.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtFwh_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtFwh_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtFwh*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.c b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.c
new file mode 100644
index 0000000..a8f7ba0
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.c
@@ -0,0 +1,273 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FlashMap.c

+   

+Abstract:

+

+  PEIM to build GUIDed HOBs for platform specific flash map

+

+--*/

+

+

+#include <FlashLayout.h>

+

+EFI_STATUS

+EFIAPI

+GetAreaInfo (

+  IN  EFI_PEI_SERVICES            **PeiServices,

+  IN PEI_FLASH_MAP_PPI            *This,

+  IN  EFI_FLASH_AREA_TYPE         AreaType,

+  IN  EFI_GUID                    *AreaTypeGuid,

+  OUT UINT32                      *NumEntries,

+  OUT EFI_FLASH_SUBAREA_ENTRY     **Entries

+  );

+

+EFI_STATUS

+EFIAPI

+MemoryDiscoveredPpiNotifyCallback (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,

+  IN VOID                       *Ppi

+  );

+

+//

+// Module globals

+//

+static PEI_FLASH_MAP_PPI      mFlashMapPpi = { GetAreaInfo };

+

+static EFI_PEI_PPI_DESCRIPTOR mPpiListFlashMap = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gPeiFlashMapPpiGuid,

+  &mFlashMapPpi

+};

+

+static EFI_FLASH_AREA_DATA    mFlashAreaData[] = {

+  //

+  // Variable area

+  //

+  {

+    EFI_VARIABLE_STORE_OFFSET,

+    EFI_VARIABLE_STORE_LENGTH,

+    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,

+    EFI_FLASH_AREA_EFI_VARIABLES

+  },

+  //

+  // FTW spare (backup) block

+  //

+  {

+    EFI_WINNT_FTW_SPARE_BLOCK_OFFSET,

+    EFI_WINNT_FTW_SPARE_BLOCK_LENGTH,

+    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,

+    EFI_FLASH_AREA_FTW_BACKUP

+  },

+  //

+  // FTW private working (state) area

+  //

+  {

+    EFI_FTW_WORKING_OFFSET,

+    EFI_FTW_WORKING_LENGTH,

+    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,

+    EFI_FLASH_AREA_FTW_STATE

+  },

+  //

+  // Recovery FV

+  //

+  {

+    EFI_WINNT_FIRMWARE_OFFSET,

+    EFI_WINNT_FIRMWARE_LENGTH,

+    EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV,

+    EFI_FLASH_AREA_RECOVERY_BIOS

+  },

+  //

+  // System Non-Volatile Storage FV

+  //

+  {

+    EFI_WINNT_RUNTIME_UPDATABLE_OFFSET,

+    EFI_WINNT_RUNTIME_UPDATABLE_LENGTH + EFI_WINNT_FTW_SPARE_BLOCK_LENGTH,

+    EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV,

+    EFI_FLASH_AREA_GUID_DEFINED

+  },

+};

+

+

+EFI_STATUS

+EFIAPI

+PeimInitializeFlashMap (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+  Build GUIDed HOBs for platform specific flash map

+  

+Arguments:

+  FfsHeader   - A pointer to the EFI_FFS_FILE_HEADER structure.

+  PeiServices - General purpose services available to every PEIM.

+    

+Returns:

+  EFI_STATUS

+

+--*/

+// TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS              Status;

+  NT_FWH_PPI              *NtFwhPpi;

+  EFI_PEI_PPI_DESCRIPTOR  *PpiDescriptor;

+  EFI_PHYSICAL_ADDRESS    FdBase;

+  UINT64                  FdSize;

+  UINTN                   NumOfHobData;

+  UINTN                   Index;

+  EFI_FLASH_AREA_HOB_DATA FlashHobData;

+

+  DEBUG ((EFI_D_ERROR, "NT 32 Flash Map PEIM Loaded\n"));

+

+  //

+  // Install FlashMap PPI

+  //

+  Status = PeiCoreInstallPpi (&mPpiListFlashMap);

+  ASSERT_EFI_ERROR (Status);

+

+

+  //

+  // Get the Fwh Information PPI

+  //

+  Status = PeiCoreLocatePpi (

+            &gNtFwhPpiGuid, // GUID

+            0,              // INSTANCE

+            &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR

+            &NtFwhPpi       // PPI

+            );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Assume that FD0 contains the Flash map.

+  //

+  Status = NtFwhPpi->NtFwh (0, &FdBase, &FdSize);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get number of types

+  //

+  NumOfHobData = sizeof (mFlashAreaData) / sizeof (EFI_FLASH_AREA_DATA);

+

+  //

+  // Build flash area entries as GUIDed HOBs.

+  //

+  for (Index = 0; Index < NumOfHobData; Index++) {

+    (*PeiServices)->SetMem (&FlashHobData, sizeof (EFI_FLASH_AREA_HOB_DATA), 0);

+

+    FlashHobData.AreaType               = mFlashAreaData[Index].AreaType;

+    FlashHobData.NumberOfEntries        = 1;

+    FlashHobData.SubAreaData.Attributes = mFlashAreaData[Index].Attributes;

+    FlashHobData.SubAreaData.Base       = FdBase + (EFI_PHYSICAL_ADDRESS) (UINTN) mFlashAreaData[Index].Base;

+    FlashHobData.SubAreaData.Length     = (EFI_PHYSICAL_ADDRESS) (UINTN) mFlashAreaData[Index].Length;

+

+    switch (FlashHobData.AreaType) {

+    case EFI_FLASH_AREA_RECOVERY_BIOS:

+    case EFI_FLASH_AREA_MAIN_BIOS:

+      (*PeiServices)->CopyMem (

+                        &FlashHobData.AreaTypeGuid,

+                        &gEfiFirmwareFileSystemGuid,

+                        sizeof (EFI_GUID)

+                        );

+      (*PeiServices)->CopyMem (

+                        &FlashHobData.SubAreaData.FileSystem,

+                        &gEfiFirmwareVolumeBlockProtocolGuid,

+                        sizeof (EFI_GUID)

+                        );

+      break;

+

+    case EFI_FLASH_AREA_GUID_DEFINED:

+      (*PeiServices)->CopyMem (

+                        &FlashHobData.AreaTypeGuid,

+                        &gEfiSystemNvDataHobGuid,

+                        sizeof (EFI_GUID)

+                        );

+      (*PeiServices)->CopyMem (

+                        &FlashHobData.SubAreaData.FileSystem,

+                        &gEfiFirmwareVolumeBlockProtocolGuid,

+                        sizeof (EFI_GUID)

+                        );

+      break;

+

+    default:

+      break;

+    }

+

+    BuildGuidDataHob (

+      &gEfiFlashMapHobGuid,

+      &FlashHobData,

+      sizeof (EFI_FLASH_AREA_HOB_DATA)

+      );

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+GetAreaInfo (

+  IN  EFI_PEI_SERVICES            **PeiServices,

+  IN PEI_FLASH_MAP_PPI            *This,

+  IN  EFI_FLASH_AREA_TYPE         AreaType,

+  IN  EFI_GUID                    *AreaTypeGuid,

+  OUT UINT32                      *NumEntries,

+  OUT EFI_FLASH_SUBAREA_ENTRY     **Entries

+  )

+/*++

+

+  Routine Description:    

+    Implementation of Flash Map PPI

+    

+--*/

+// TODO: function comment is missing 'Arguments:'

+// TODO: function comment is missing 'Returns:'

+// TODO:    PeiServices - add argument and description to function comment

+// TODO:    This - add argument and description to function comment

+// TODO:    AreaType - add argument and description to function comment

+// TODO:    AreaTypeGuid - add argument and description to function comment

+// TODO:    NumEntries - add argument and description to function comment

+// TODO:    Entries - add argument and description to function comment

+// TODO:    EFI_SUCCESS - add return value to function comment

+// TODO:    EFI_NOT_FOUND - add return value to function comment

+{

+  EFI_STATUS                    Status;

+  EFI_PEI_HOB_POINTERS          Hob;

+  EFI_HOB_FLASH_MAP_ENTRY_TYPE  *FlashMapEntry;

+

+  Status = PeiCoreGetHobList (&Hob.Raw);

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && CompareGuid (&Hob.Guid->Name, &gEfiFlashMapHobGuid)) {

+      FlashMapEntry = (EFI_HOB_FLASH_MAP_ENTRY_TYPE *) Hob.Raw;

+      if (AreaType == FlashMapEntry->AreaType) {

+        if (AreaType == EFI_FLASH_AREA_GUID_DEFINED) {

+          if (!CompareGuid (AreaTypeGuid, &FlashMapEntry->AreaTypeGuid)) {

+            continue;

+          }

+        }

+

+        *NumEntries = FlashMapEntry->NumEntries;

+        *Entries    = FlashMapEntry->Entries;

+        return EFI_SUCCESS;

+      }

+    }

+

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+

+  return EFI_NOT_FOUND;

+}

diff --git a/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.dxs b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.dxs
new file mode 100644
index 0000000..0c197de
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    FlashMap.dxs

+

+Abstract:

+

+  Dependency expression file for FindFv.

+

+--*/  

+

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+ TRUE

+DEPENDENCY_END

+

diff --git a/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.mbd b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.mbd
new file mode 100644
index 0000000..8c38ee9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PeiFlashMap</BaseName>

+    <Guid>681F3771-6F1D-42DE-9AA2-F82BBCDBC5F9</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-23 10:43</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.msa b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.msa
new file mode 100644
index 0000000..f347ca4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FlashMap/FlashMap.msa
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PeiFlashMap</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>681F3771-6F1D-42DE-9AA2-F82BBCDBC5F9</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for FlashMap PEI module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-23 10:43</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>FlashMap.c</Filename>

+    <Filename>FlashMap.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>VariableArea</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>FtwBackupBlock</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>FtwStateArea</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>RecoveryBios</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>SystemNvDataHob</Name>

+      <C_Name>gEfiFlashMapHobGuid</C_Name>

+      <Guid>0xb091e7d2, 0x5a0, 0x4198, 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">FlashMap</Ppi>

+    <Ppi Usage="ALWAYS_CONSUMED">NtFwh</Ppi>

+  </PPIs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FlashMapHob</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FirmwareFileSystem</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>SystemNvDataHob</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimInitializeFlashMap</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/FlashMap/build.xml b/edk2/EdkNt32Pkg/Pei/FlashMap/build.xml
new file mode 100644
index 0000000..b388551
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/FlashMap/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiFlashMap"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\FlashMap"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="PeiFlashMap">

+      <GenBuild baseName="PeiFlashMap" mbdFilename="${MODULE_DIR}\FlashMap.mbd" msaFilename="${MODULE_DIR}\FlashMap.msa"/>

+   </target>

+   <target depends="PeiFlashMap_clean" name="clean"/>

+   <target depends="PeiFlashMap_cleanall" name="cleanall"/>

+   <target name="PeiFlashMap_clean">

+      <OutputDirSetup baseName="PeiFlashMap" mbdFilename="${MODULE_DIR}\FlashMap.mbd" msaFilename="${MODULE_DIR}\FlashMap.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\PeiFlashMap_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\PeiFlashMap_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiFlashMap_cleanall">

+      <OutputDirSetup baseName="PeiFlashMap" mbdFilename="${MODULE_DIR}\FlashMap.mbd" msaFilename="${MODULE_DIR}\FlashMap.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\PeiFlashMap_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\PeiFlashMap_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiFlashMap*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.c b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.c
new file mode 100644
index 0000000..27c73f5
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.c
@@ -0,0 +1,150 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MonoStatusCode.c

+

+Abstract:

+

+  PEIM to provide the status code functionality, to aid in system debug.

+  It includes output to 0x80 port and/or to serial port.  

+  This PEIM is monolithic. Different platform should provide different library.

+

+--*/

+

+#include "MonoStatusCode.h"

+

+//

+// Module globals

+//

+// 

+EFI_PEI_PROGRESS_CODE_PPI     mStatusCodePpi      = { PlatformReportStatusCode };

+

+EFI_PEI_PPI_DESCRIPTOR  mPpiListStatusCode = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiPeiStatusCodePpiGuid,

+  &mStatusCodePpi

+};

+

+//

+// Function implemenations

+//

+EFI_STATUS

+EFIAPI

+TranslateDxeStatusCodeToPeiStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Translate from a DXE status code interface into a PEI-callable

+  interface, making the PEI the least common denominator..

+

+Arguments:

+

+  Same as DXE ReportStatusCode RT service

+  

+Returns:

+

+  None

+

+--*/

+{

+  return PlatformReportStatusCode (NULL, CodeType, Value, Instance, CallerId, Data);

+}

+

+EFI_STATUS

+EFIAPI

+InitializeDxeReportStatusCode (

+  IN EFI_PEI_SERVICES       **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Build a hob describing the status code listener that has been installed.

+  This will be used by DXE code until a runtime status code listener is 

+  installed.

+

+Arguments:

+

+  PeiServices      - General purpose services available to every PEIM.

+    

+Returns:

+

+  Status -  EFI_SUCCESS if the interface could be successfully

+            installed

+

+--*/

+{

+  VOID        *Instance;

+  VOID        *HobData;

+

+  Instance = (VOID *) (UINTN) TranslateDxeStatusCodeToPeiStatusCode;

+

+  HobData = BuildGuidDataHob (

+              &gEfiStatusCodeRuntimeProtocolGuid,

+              &Instance,

+              sizeof (VOID *)

+              );

+

+  ASSERT (HobData != NULL);

+  return EFI_SUCCESS;

+}

+

+VOID

+EFIAPI

+InitializeMonoStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Initialize the platform status codes and publish the platform status code 

+  PPI.

+

+Arguments:

+

+  FfsHeader   - FV this PEIM was loaded from.

+  PeiServices - General purpose services available to every PEIM.

+    

+Returns:

+

+  Status -  EFI_SUCCESS

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Initialize status code listeners.

+  //

+  PlatformInitializeStatusCode (FfsHeader, PeiServices);

+

+  //

+  // Publish the status code capability to other modules

+  //

+  Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiListStatusCode);

+

+  ASSERT_EFI_ERROR (Status);

+

+  DEBUG ((EFI_D_ERROR, "\nMono Status Code PEIM Loaded\n"));

+

+  return ;

+}

diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.dxs b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.dxs
new file mode 100644
index 0000000..3c86da0
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.dxs
@@ -0,0 +1,28 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MonoStatusCode.dxs

+

+Abstract:

+

+  Dependency expression file for monolithic Status Code PEIM.

+  

+--*/  

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+   TRUE

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.h b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.h
new file mode 100644
index 0000000..38a9022
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/MonoStatusCode.h
@@ -0,0 +1,111 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  MonoStatusCode.h

+   

+Abstract:

+

+  Monolithic single PEIM to provide the status code functionality.

+  The PEIM is a blend of libraries that correspond to the different status code

+  listeners that a platform installs.

+

+--*/

+

+#ifndef _MONO_STATUS_CODE_H_

+#define _MONO_STATUS_CODE_H_

+

+//

+// Platform specific function Declarations.  These must be implemented in a

+// subdirectory named PlatformName in a file named PlatformStatusCode.c.

+// See D845GRG\PlatformStatusCode.c for an example of a simple status code

+// implementation.

+// See Nt32\PlatformStatusCode.c for an example of a status code implementation

+// that relocates itself into memory.

+//

+//

+// This is the driver entry point and must be defined.

+//

+EFI_STATUS

+EFIAPI

+InstallMonoStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+;

+

+//

+// This is the platform function to initialize the listeners desired by the

+// platform.

+//

+VOID

+PlatformInitializeStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+;

+

+//

+// This is the platform function that calls all of the listeners desired by the

+// platform.

+//

+EFI_STATUS

+EFIAPI

+PlatformReportStatusCode (

+  IN EFI_PEI_SERVICES         **PeiServices,

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+//

+// Platform independent function Declarations

+//

+//

+// Initialize the status code listeners and publish the status code PPI.

+//

+VOID

+EFIAPI

+InitializeMonoStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+;

+

+//

+// Convert a DXE status code call into a PEI status code call.

+//

+EFI_STATUS

+EFIAPI

+TranslateDxeStatusCodeToPeiStatusCode (

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+;

+

+//

+// Publish a HOB that contains the listener to be used by DXE.

+//

+EFI_STATUS

+EFIAPI

+InitializeDxeReportStatusCode (

+  IN EFI_PEI_SERVICES       **PeiServices

+  )

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/MonoStatusCode.mbd b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/MonoStatusCode.mbd
new file mode 100644
index 0000000..f48b4c7
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/MonoStatusCode.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>MonoStatusCode</BaseName>

+    <Guid>1501614E-0E6C-4ef4-8B8F-C276CDFB646F</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>PeimEntryPoint</Library>

+    <Library>EdkMemoryStatusCodeLib</Library>

+    <Library>PeiCoreLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/MonoStatusCode.msa b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/MonoStatusCode.msa
new file mode 100644
index 0000000..cd131d0
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/MonoStatusCode.msa
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>MonoStatusCode</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>1501614E-0E6C-4ef4-8B8F-C276CDFB646F</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">EdkMemoryStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>..\MonoStatusCode.c</Filename>

+    <Filename>..\MonoStatusCode.h</Filename>

+    <Filename>PlatformStatusCode.c</Filename>

+    <Filename>..\MonoStatusCode.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="SOMETIMES_CONSUMED">StatusCode</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="SOMETIMES_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>TranslateDxeStatusCodeToPeiStatusCode</Name>

+      <C_Name>gEfiStatusCodeRuntimeProtocolGuid</C_Name>

+      <Guid>0xd2b2b828, 0x826, 0x48a7, 0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">StatusCode</Ppi>

+    <Ppi Usage="SOMETIMES_CONSUMED">FvFileLoader</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>InstallMonoStatusCode</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/PlatformStatusCode.c b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/PlatformStatusCode.c
new file mode 100644
index 0000000..fcbe864
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/PlatformStatusCode.c
@@ -0,0 +1,164 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PlatformStatusCode.c 

+   

+Abstract:

+

+  Contains NT32 specific implementations required to use status codes.

+

+--*/

+

+#include "../MonoStatusCode.h"

+

+

+BOOLEAN gRunningFromMemory = FALSE;

+//

+// Platform definitions

+//

+EFI_PEI_REPORT_STATUS_CODE  mSecReportStatusCode = NULL;

+

+extern EFI_PEI_PROGRESS_CODE_PPI  mStatusCodePpi;

+

+//

+// Function implementations

+//

+EFI_STATUS

+EFIAPI

+PlatformReportStatusCode (

+  IN EFI_PEI_SERVICES         **PeiServices,

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  Call all status code listeners in the MonoStatusCode.

+

+Arguments:

+

+  Same as ReportStatusCode service

+  

+Returns:

+

+  EFI_SUCCESS     Always returns success.

+

+--*/

+{

+  if (mSecReportStatusCode != NULL) {

+    mSecReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId, Data);

+  }

+  MemoryReportStatusCode (CodeType, Value, Instance, CallerId, Data);

+  return EFI_SUCCESS;

+}

+

+VOID

+PlatformInitializeStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Initialize the status code listeners.  This consists of locating the 

+  listener produced by SecMain.exe.

+

+Arguments:

+

+  FfsHeader   - FV this PEIM was loaded from.

+  PeiServices - General purpose services available to every PEIM.

+

+Returns:

+

+  None

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PEI_PROGRESS_CODE_PPI   *ReportStatusCodePpi;

+  EFI_PEI_PPI_DESCRIPTOR      *ReportStatusCodeDescriptor;

+

+  //

+  // Cache the existing status code listener installed by the SEC core.

+  // We should actually do a heap allocate, install a PPI, etc, but since we

+  // know that we are running from a DLL, we can use global variables, and

+  // directly update the status code PPI descriptor

+  //

+  //

+  // Locate SEC status code PPI

+  //

+  Status = (*PeiServices)->LocatePpi (

+                            PeiServices,

+                            &gEfiPeiStatusCodePpiGuid,

+                            0,

+                            &ReportStatusCodeDescriptor,

+                            &ReportStatusCodePpi

+                            );

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+

+  mSecReportStatusCode            = ReportStatusCodePpi->ReportStatusCode;

+  ReportStatusCodeDescriptor->Ppi = &mStatusCodePpi;

+

+  //

+  // Always initialize memory status code listener.

+  //

+  MemoryStatusCodeInitialize (FfsHeader, PeiServices);

+

+}

+

+EFI_STATUS

+EFIAPI

+InstallMonoStatusCode (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Install the PEIM.  Publish the DXE callback as well.

+

+Arguments:

+

+  FfsHeader   - FV this PEIM was loaded from.

+  PeiServices - General purpose services available to every PEIM.

+

+Returns:

+

+  EFI_SUCCESS   The function always returns success.

+

+--*/

+{

+  if (!gRunningFromMemory) {

+    //

+    // First pass, running from flash, initialize everything

+    //

+    InitializeMonoStatusCode (FfsHeader, PeiServices);

+  } else {

+    //

+    // Second pass, running from memory, initialize memory listener and

+    // publish the DXE listener in a HOB.

+    //

+    MemoryStatusCodeInitialize (FfsHeader, PeiServices);

+    InitializeDxeReportStatusCode (PeiServices);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/build.xml b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/build.xml
new file mode 100644
index 0000000..e6c8551
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/MonoStatusCode/Nt32/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="MonoStatusCode"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\MonoStatusCode\Nt32"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="MonoStatusCode">

+      <GenBuild baseName="MonoStatusCode" mbdFilename="${MODULE_DIR}\MonoStatusCode.mbd" msaFilename="${MODULE_DIR}\MonoStatusCode.msa"/>

+   </target>

+   <target depends="MonoStatusCode_clean" name="clean"/>

+   <target depends="MonoStatusCode_cleanall" name="cleanall"/>

+   <target name="MonoStatusCode_clean">

+      <OutputDirSetup baseName="MonoStatusCode" mbdFilename="${MODULE_DIR}\MonoStatusCode.mbd" msaFilename="${MODULE_DIR}\MonoStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\MonoStatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\MonoStatusCode_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="MonoStatusCode_cleanall">

+      <OutputDirSetup baseName="MonoStatusCode" mbdFilename="${MODULE_DIR}\MonoStatusCode.mbd" msaFilename="${MODULE_DIR}\MonoStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\MonoStatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\MonoStatusCode_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**MonoStatusCode*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.c b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.c
new file mode 100644
index 0000000..69261b9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.c
@@ -0,0 +1,657 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PcdEmulator.c

+

+Abstract:

+  Platform Configuration Database (PCD) Service PEIM

+

+--*/

+

+#include <PcdEmulator.h>

+

+//

+// BugBug: PEI early phase does not support global variable!!!

+//         This is only a temperary solution.

+//

+

+UINTN                    mSkuId = 0;

+

+

+STATIC EMULATED_PCD_DATABASE_EX *

+GetPcdDataBaseEx (

+  VOID

+) {

+  EFI_HOB_GUID_TYPE         *GuidHob;

+  EMULATED_PCD_DATABASE_EX  *EmulatedPcdDatabaseEx;

+

+  GuidHob = GetFirstGuidHob (&gPcdHobGuid);

+  EmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) GET_GUID_HOB_DATA(GuidHob);

+

+  return EmulatedPcdDatabaseEx;

+}

+

+STATIC UINTN 

+GetPcdDataBaseExEntryCount (

+	EMULATED_PCD_DATABASE_EX * Database

+) {

+	return Database->Count;

+}

+

+STATIC UINTN 

+GetPcdDataBaseExSize (

+	EMULATED_PCD_DATABASE_EX * Database

+) {

+	UINTN Size;

+	

+	Size = sizeof (Database->Count)

+			+ (sizeof (Database->Entry[0]) * Database->Count);

+			

+	return Size;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetSku (

+  IN  UINTN             SkuId

+  )

+{

+  mSkuId = SkuId;

+  return EFI_SUCCESS;

+}

+

+UINT8

+EFIAPI

+PcdEmulatorGet8 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 1);

+

+  return (UINT8)Pcd->Datum;

+}

+

+UINT16

+EFIAPI

+PcdEmulatorGet16 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 2);

+

+  return (UINT16)Pcd->Datum;

+}

+

+UINT32

+EFIAPI

+PcdEmulatorGet32 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 4);

+

+  return (UINT32)Pcd->Datum;

+}

+

+UINT64

+EFIAPI

+PcdEmulatorGet64 (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == sizeof (UINT64));

+

+  return (UINT64)Pcd->Datum;

+}

+

+VOID *

+EFIAPI

+PcdEmulatorGetPtr (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  return (VOID *)(UINTN)Pcd->ExtendedData;

+}

+

+BOOLEAN

+EFIAPI

+PcdEmulatorGetBoolean (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  ASSERT (Pcd->DatumSize == 1);

+

+  return (BOOLEAN)Pcd->Datum;

+}

+

+UINTN

+EFIAPI

+PcdEmulatorGetSize (

+  IN  UINTN  TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  return Pcd->DatumSize;

+}

+

+UINT8

+EFIAPI

+PcdEmulatorGet8Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINT16

+EFIAPI

+PcdEmulatorGet16Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINT32

+EFIAPI

+PcdEmulatorGet32Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINT64

+EFIAPI

+PcdEmulatorGet64Ex (

+  IN  CONST EFI_GUID      *PcdDataBaseName,

+  IN  UINTN               TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+VOID *

+EFIAPI

+PcdEmulatorGetPtrEx (

+  IN  CONST EFI_GUID    *PcdDataBaseName,

+  IN  UINTN             TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+BOOLEAN

+EFIAPI

+PcdEmulatorGetBooleanEx (

+  IN  CONST EFI_GUID    *PcdDataBaseName,

+  IN  UINTN             TokenNumber

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+UINTN

+EFIAPI

+PcdEmulatorGetSizeEx (

+  IN  CONST EFI_GUID    *PcdDataBaseName,

+  IN  UINTN             TokenNumber

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+  return Pcd->DatumSize;

+}

+

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet8 (

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{  

+

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  ASSERT (Pcd->DatumSize == sizeof (UINT8));

+

+  Pcd->Datum = Value;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet16 (

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet32 (

+  IN UINTN              TokenNumber,

+  IN UINT32             Value

+  )

+{  

+

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  ASSERT (Pcd->DatumSize == sizeof (UINT32));

+

+  Pcd->Datum = Value;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet64 (

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetPtr (

+  IN UINTN             TokenNumber,

+  IN CONST VOID        *Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetBoolean (

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet8Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet16Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet32Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT32             Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSet64Ex (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetPtrEx (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN CONST VOID        *Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorSetBooleanEx (

+  IN CONST EFI_GUID    *Guid,

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{  

+

+  ASSERT (FALSE);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorCallBackOnSet (

+  IN  UINTN               TokenNumber,

+  IN  CONST EFI_GUID      *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK    CallBackFunction

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  if (Pcd->CallBackListSize == Pcd->CallBackEntries) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Pcd->CallBackList[Pcd->CallBackEntries++] = CallBackFunction;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorUnregisterCallBackOnSet (

+  IN  UINTN                   TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK        CallBackfunction

+  )

+{

+  EMULATED_PCD_ENTRY_EX  *Pcd;

+  UINT32                 Index;

+

+  Pcd = GetPcdEntry (TokenNumber);

+  ASSERT (Pcd != NULL);

+

+  for (Index = 0; Index < Pcd->CallBackListSize; Index++) {

+    if (Pcd->CallBackList[Index] == CallBackfunction) {

+      Pcd->CallBackList[Index] = NULL;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+PcdEmulatorGetNextToken (

+  IN  CONST EFI_GUID      *Guid, OPTIONAL

+  IN  UINTN               *Token

+  )

+{

+  EMULATED_PCD_ENTRY_EX    *Pcd;

+  EMULATED_PCD_ENTRY_EX    *LastPcdEntry;

+  EMULATED_PCD_DATABASE_EX *PcdDatabase;

+  EMULATED_PCD_ENTRY_EX    *PcdEntry;

+

+  PcdDatabase = GetPcdDataBaseEx ();  

+  PcdEntry    = PcdDatabase->Entry;

+

+  if (*Token == PCD_INVALID_TOKEN) {

+    //

+    // BugBug: Due to variable size array, ensure we convert this to a reasonable database

+    //         that can accomodate array references for simplicity's sake

+    *Token = PcdEntry[0].Token;

+    return EFI_SUCCESS;

+  }

+

+  Pcd = GetPcdEntry (*Token);

+  if (Pcd == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  LastPcdEntry = PcdEntry + GetPcdDataBaseExEntryCount (PcdDatabase);

+  if (++Pcd >= LastPcdEntry) {

+    return EFI_NOT_FOUND;

+  }

+  

+  *Token = Pcd->Token;

+  return EFI_SUCCESS;

+}

+

+PCD_PPI mPcdPpiInstance = {

+  PcdEmulatorSetSku,

+

+  PcdEmulatorGet8,

+  PcdEmulatorGet16,          

+  PcdEmulatorGet32,          

+  PcdEmulatorGet64,          

+  PcdEmulatorGetPtr,         

+  PcdEmulatorGetBoolean,     

+  PcdEmulatorGetSize,

+

+  PcdEmulatorGet8Ex,

+  PcdEmulatorGet16Ex,          

+  PcdEmulatorGet32Ex,          

+  PcdEmulatorGet64Ex,          

+  PcdEmulatorGetPtrEx,         

+  PcdEmulatorGetBooleanEx,     

+  PcdEmulatorGetSizeEx,

+  

+  PcdEmulatorSet8,

+  PcdEmulatorSet16,          

+  PcdEmulatorSet32,          

+  PcdEmulatorSet64,          

+  PcdEmulatorSetPtr,         

+  PcdEmulatorSetBoolean,     

+

+  PcdEmulatorSet8Ex,

+  PcdEmulatorSet16Ex,          

+  PcdEmulatorSet32Ex,          

+  PcdEmulatorSet64Ex,          

+  PcdEmulatorSetPtrEx,         

+  PcdEmulatorSetBooleanEx,     

+

+  PcdEmulatorCallBackOnSet,

+  PcdEmulatorUnregisterCallBackOnSet,

+  PcdEmulatorGetNextToken

+};

+

+STATIC EFI_PEI_PPI_DESCRIPTOR     mPpiPCD = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gPcdPpiGuid,

+  &mPcdPpiInstance

+};

+

+EFI_STATUS

+EFIAPI

+PeimPcdEmulatorEntry (

+  IN EFI_FFS_FILE_HEADER      *FfsHeader,

+  IN EFI_PEI_SERVICES         **PeiServices

+  )

+{

+  EFI_STATUS                  Status;

+  UINTN                       Index;

+  UINTN                       Count;

+  UINTN                       Calculation;

+  UINT8                       *AllocatedBuffer;

+  EMULATED_PCD_DATABASE_EX    *EmulatedPcdDatabaseEx;

+  EMULATED_PCD_ENTRY_EX       *EmulatedPcdEntryEx;

+

+  //

+  // BugBug: Normally, we would read an FFS file for this data

+  // We need to remember, that when we read the FFS file, items such as the VariableName will not be encoded as a pointer

+  // but as an array of content.  In this emulation, our init is encoding this data as a pointer.

+  // In the FFS version, we will depend on the proper Entry Count in the FFS data since the structures will

+  // now be variable length.

+  //

+  //

+

+  //

+  // We should now read from the FFS file into the cache - for now, we fake this.

+  //

+  Count = GetPcdDataBaseSize () / sizeof (EMULATED_PCD_ENTRY);

+

+  //

+  // Let's now determine how big of a buffer we need for our database

+  // For the FFS version, we need to calculate/consider the VariableName/ExtendedData size!!!

+  //

+  Calculation = sizeof (UINTN) + (Count * sizeof (EMULATED_PCD_ENTRY_EX));

+

+  EmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) BuildGuidHob (&gPcdHobGuid, Calculation);

+

+  EmulatedPcdDatabaseEx->Count = Count;

+  EmulatedPcdEntryEx    = EmulatedPcdDatabaseEx->Entry;

+

+  AllocatedBuffer = AllocatePool (Count * sizeof (PCD_PPI_CALLBACK) * MAX_PCD_CALLBACK);

+  ASSERT (AllocatedBuffer != NULL);  

+

+  for (Index = 0; Index < Count; Index++) {

+    //

+    // Copy from source to our own allocated buffer - normally an FFS read

+    //

+    (*PeiServices)->CopyMem (

+                      (VOID *) (EmulatedPcdEntryEx + Index),

+                      (VOID *) (gEmulatedPcdEntry + Index),

+                      sizeof (EMULATED_PCD_ENTRY)

+                      );

+

+    //

+    // All the CallBackList worker functions refer to this CallBackList as CallBackList[CallbackEntry]

+    // so we seed the same buffer address here.

+    //

+    EmulatedPcdEntryEx[Index].CallBackList = (PCD_PPI_CALLBACK *)AllocatedBuffer;

+    AllocatedBuffer+= (sizeof (PCD_PPI_CALLBACK) * MAX_PCD_CALLBACK);

+    EmulatedPcdEntryEx[Index].CallBackEntries  = 0;

+    EmulatedPcdEntryEx[Index].CallBackListSize = MAX_PCD_CALLBACK;

+  }

+

+  //

+  // Install PCD service PPI

+  //

+  Status = PeiCoreInstallPpi (&mPpiPCD);

+

+  ASSERT_EFI_ERROR (Status);

+  return Status;

+}

+

+

+EMULATED_PCD_ENTRY_EX *

+GetPcdEntry (

+  IN      UINTN    TokenNumber

+  )

+{

+  UINTN                     Index;

+  UINTN                     Count;

+  EMULATED_PCD_DATABASE_EX  *EmulatedPcdDatabaseEx;

+  EMULATED_PCD_ENTRY_EX     *EmulatedPcdEntryEx;

+

+  CpuBreakpoint (); 

+

+  EmulatedPcdDatabaseEx = GetPcdDataBaseEx ();  

+  //

+  // BugBug: This Count will change when we flip over to FFS version

+  //

+  Count = EmulatedPcdDatabaseEx->Count;

+  EmulatedPcdEntryEx = EmulatedPcdDatabaseEx->Entry;

+  for (Index = 0; Index < Count; Index++) {

+    if (EmulatedPcdEntryEx[Index].Token == TokenNumber) {

+      return &EmulatedPcdEntryEx[Index];

+    }

+  }

+  return NULL;

+}

+

+

diff --git a/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.dxs b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.dxs
new file mode 100644
index 0000000..ea57997
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.dxs
@@ -0,0 +1,25 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PcdEmulator.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <DxeDepex.h>

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END

diff --git a/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.h b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.h
new file mode 100644
index 0000000..e97c2a1
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.h
@@ -0,0 +1,53 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  PcdEmulator.h

+

+Abstract:

+  Platform Configuration Database (PCD) 

+

+--*/

+

+#ifndef __PCD_EMULATOR_H__

+#define __PCD_EMULATOR_H__

+

+

+

+//

+// BugBug: Not very sure, where to put this "extern"

+//

+extern GUID gPcdHobGuid;

+

+//

+// BugBug: Hack max number of callbacks per token

+//

+#define MAX_PCD_CALLBACK  0x10

+

+extern EMULATED_PCD_ENTRY		       gEmulatedPcdEntry[];

+

+UINTN

+GetPcdDataBaseSize (

+  VOID

+  );

+

+EMULATED_PCD_ENTRY_EX *

+GetPcdEntry (

+  IN      UINTN    TokenNumber

+  );

+

+EFI_STATUS

+InstallMyHob (

+  IN EFI_PEI_SERVICES          **PeiServices,

+  IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,

+  IN VOID                      *Ppi

+  );

+#endif

diff --git a/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.mbd b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.mbd
new file mode 100644
index 0000000..816cf6f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.mbd
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>PcdEmulatorPeim</BaseName>

+    <Guid>9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-24 18:54</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>BaseLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>PeiMemoryAllocationLib</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.msa b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.msa
new file mode 100644
index 0000000..ad11084
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/PcdEmulator/PcdEmulator.msa
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>PcdEmulatorPeim</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for PcdEmulator PEIM module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-24 18:54</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PcdEmulator.dxs</Filename>

+    <Filename>PcdEmulator.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>PcdDataBase</Name>

+      <C_Name>gPcdHobGuid</C_Name>

+      <Guid>0x582e7ca1, 0x68cd, 0x4d44, 0xb4, 0x3b, 0xf2, 0x98, 0xed, 0x58, 0x7b, 0xa6</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">Pcd</Ppi>

+  </PPIs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>PcdHob</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimPcdEmulatorEntry</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/PcdEmulator/build.xml b/edk2/EdkNt32Pkg/Pei/PcdEmulator/build.xml
new file mode 100644
index 0000000..86e0d1f
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/PcdEmulator/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PcdEmulatorPeim"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\PcdEmulator"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="PcdEmulatorPeim">

+      <GenBuild baseName="PcdEmulatorPeim" mbdFilename="${MODULE_DIR}\PcdEmulator.mbd" msaFilename="${MODULE_DIR}\PcdEmulator.msa"/>

+   </target>

+   <target depends="PcdEmulatorPeim_clean" name="clean"/>

+   <target depends="PcdEmulatorPeim_cleanall" name="cleanall"/>

+   <target name="PcdEmulatorPeim_clean">

+      <OutputDirSetup baseName="PcdEmulatorPeim" mbdFilename="${MODULE_DIR}\PcdEmulator.mbd" msaFilename="${MODULE_DIR}\PcdEmulator.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\PcdEmulatorPeim_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\PcdEmulatorPeim_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PcdEmulatorPeim_cleanall">

+      <OutputDirSetup baseName="PcdEmulatorPeim" mbdFilename="${MODULE_DIR}\PcdEmulator.mbd" msaFilename="${MODULE_DIR}\PcdEmulator.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\PcdEmulatorPeim_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\PcdEmulatorPeim_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PcdEmulatorPeim*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.dxs b/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.dxs
new file mode 100644
index 0000000..107ddee
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.dxs
@@ -0,0 +1,29 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtStuff.dxs

+

+Abstract:

+

+  Dependency expression file for WinNtStuff PEIM.

+

+--*/  

+

+#include <AutoGen.h>

+#include <PeimDepex.h>

+

+DEPENDENCY_START

+  PEI_NT_THUNK_PPI_GUID AND EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID

+DEPENDENCY_END

+

+

diff --git a/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.mbd b/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.mbd
new file mode 100644
index 0000000..ab862ef
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>WinNtStuff</BaseName>

+    <Guid>D3AAD8DC-3A48-46ac-B1C7-28A9D3CF6755</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>PeimEntryPoint</Library>

+    <Library>PeiMemoryLib</Library>

+    <Library>PeiCoreLib</Library>

+    <Library>PeiServicesTablePointerLib</Library>

+    <Library>PeiHobLib</Library>

+    <Library>PeiReportStatusCodeLib</Library>

+    <Library>BaseDebugLibReportStatusCode</Library>

+    <Library>BaseLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.msa b/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.msa
new file mode 100644
index 0000000..2890c9d
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/WinNtStuff/WinNtStuff.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>WinNtStuff</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>PE32_PEIM</ComponentType>

+    <Guid>D3AAD8DC-3A48-46ac-B1C7-28A9D3CF6755</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for WinNtStuff module</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>WinNtStuff.c</Filename>

+    <Filename>WinNtStuff.dxs</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">WinNtThunk</Protocol>

+  </Protocols>

+  <Hobs>

+    <Hob Usage="ALWAYS_PRODUCED" HobType="GUID_EXTENSION">

+      <Name>WinNtThunkProtocol</Name>

+      <C_Name>gEfiWinNtThunkProtocolGuid</C_Name>

+      <Guid>0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Hob>

+  </Hobs>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">NtThunk</Ppi>

+  </PPIs>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>PeimInitializeWinNtStuff</ModuleEntryPoint>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Pei/WinNtStuff/build.xml b/edk2/EdkNt32Pkg/Pei/WinNtStuff/build.xml
new file mode 100644
index 0000000..885bacb
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/WinNtStuff/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="WinNtStuff"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Pei\WinNtStuff"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="WinNtStuff">

+      <GenBuild baseName="WinNtStuff" mbdFilename="${MODULE_DIR}\WinNtStuff.mbd" msaFilename="${MODULE_DIR}\WinNtStuff.msa"/>

+   </target>

+   <target depends="WinNtStuff_clean" name="clean"/>

+   <target depends="WinNtStuff_cleanall" name="cleanall"/>

+   <target name="WinNtStuff_clean">

+      <OutputDirSetup baseName="WinNtStuff" mbdFilename="${MODULE_DIR}\WinNtStuff.mbd" msaFilename="${MODULE_DIR}\WinNtStuff.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtStuff_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtStuff_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="WinNtStuff_cleanall">

+      <OutputDirSetup baseName="WinNtStuff" mbdFilename="${MODULE_DIR}\WinNtStuff.mbd" msaFilename="${MODULE_DIR}\WinNtStuff.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\WinNtStuff_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\WinNtStuff_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**WinNtStuff*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/Pei/WinNtStuff/winntstuff.c b/edk2/EdkNt32Pkg/Pei/WinNtStuff/winntstuff.c
new file mode 100644
index 0000000..4685928
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Pei/WinNtStuff/winntstuff.c
@@ -0,0 +1,73 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    WinNtStuff.c

+    

+Abstract:

+

+    Tiano PEIM to abstract construction of firmware volume in a Windows NT environment.

+

+Revision History

+

+--*/

+

+

+

+EFI_STATUS

+EFIAPI

+PeimInitializeWinNtStuff (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+/*++

+

+Routine Description:

+

+  Perform a call-back into the SEC simulator to get NT Stuff

+

+Arguments:

+

+  PeiServices - General purpose services available to every PEIM.

+    

+Returns:

+

+  None

+

+--*/

+// TODO:    FfsHeader - add argument and description to function comment

+{

+  EFI_STATUS              Status;

+  EFI_PEI_PPI_DESCRIPTOR  *PpiDescriptor;

+  PEI_NT_THUNK_PPI        *PeiNtService;

+  VOID                    *Ptr;

+

+  DEBUG ((EFI_D_ERROR, "NT 32 WinNT Stuff PEIM Loaded\n"));

+

+  Status = (**PeiServices).LocatePpi (

+                            PeiServices,

+                            &gPeiNtThunkPpiGuid,  // GUID

+                            0,                    // INSTANCE

+                            &PpiDescriptor,       // EFI_PEI_PPI_DESCRIPTOR

+                            &PeiNtService         // PPI

+                            );

+  ASSERT_EFI_ERROR (Status);

+

+  Ptr = PeiNtService->NtThunk ();

+

+  BuildGuidDataHob (

+    &gEfiWinNtThunkProtocolGuid,         // Guid

+    &Ptr,                                // Buffer

+    sizeof (VOID *)                      // Sizeof Buffer

+    );

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/FWBlockService.c b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/FWBlockService.c
new file mode 100644
index 0000000..e22a323
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/FWBlockService.c
@@ -0,0 +1,1939 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FWBlockService.c

+    

+Abstract:

+

+Revision History

+

+--*/

+

+#include "FWBlockService.h"

+#include "EfiFlashMap.h"

+#include EFI_GUID_DEFINITION (FlashMapHob)

+

+ESAL_FWB_GLOBAL         *mFvbModuleGlobal;

+

+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {

+  FVB_DEVICE_SIGNATURE,

+  {

+    {

+      {

+        HARDWARE_DEVICE_PATH,

+        HW_MEMMAP_DP,

+        {

+          sizeof (MEMMAP_DEVICE_PATH),

+          0

+        }

+      },

+      EfiMemoryMappedIO,

+      0,

+      0,

+    },

+    {

+      END_DEVICE_PATH_TYPE,

+      END_ENTIRE_DEVICE_PATH_SUBTYPE,

+      {

+        sizeof (EFI_DEVICE_PATH_PROTOCOL),

+        0

+      }

+    }

+  },

+  0,

+  {

+    FvbProtocolGetAttributes,

+    FvbProtocolSetAttributes,

+    FvbProtocolGetPhysicalAddress,

+    FvbProtocolGetBlockSize,

+    FvbProtocolRead,

+    FvbProtocolWrite,

+    FvbProtocolEraseBlocks,

+    NULL

+  },

+  {

+    FvbExtendProtocolEraseCustomBlockRange

+  }

+};

+

+EFI_DRIVER_ENTRY_POINT (FvbInitialize)

+

+

+VOID

+EFIAPI

+FvbVirtualddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Fixup internal data so that EFI and SAL can be call in virtual mode.

+  Call the passed in Child Notify event and convert the mFvbModuleGlobal

+  date items to there virtual address.

+

+  mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]  - Physical copy of instance data

+  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]   - Virtual pointer to common 

+                                                instance data.

+

+Arguments:

+

+  (Standard EFI notify event - EFI_EVENT_NOTIFY)

+

+Returns: 

+

+  None

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  UINTN               Index;

+

+  EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);

+

+  //

+  // Convert the base address of all the instances

+  //

+  Index       = 0;

+  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];

+  while (Index < mFvbModuleGlobal->NumFv) {

+    EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);

+    EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &FwhInstance->FvWriteBase[FVB_VIRTUAL]);

+    FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) + FwhInstance->VolumeHeader.HeaderLength

+                    + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)));

+    Index++;

+  }

+

+  EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);

+  EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal);

+}

+

+VOID

+FvbMemWrite8 (

+  IN  UINT64                              Dest,

+  IN  UINT8                               Byte

+  )

+{

+  EfiMemWrite (EfiCpuIoWidthUint8, Dest, 1, &Byte);

+

+  return ;

+}

+

+EFI_STATUS

+GetFvbInstance (

+  IN  UINTN                               Instance,

+  IN  ESAL_FWB_GLOBAL                     *Global,

+  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  FwhInstance           - The EFI_FW_VOL_INSTANCE fimrware instance structure

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhRecord;

+

+  if (Instance >= Global->NumFv) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the right instance of the FVB private data

+  //

+  FwhRecord = Global->FvInstance[Virtual];

+  while (Instance > 0) {

+    FwhRecord = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhRecord) + FwhRecord->VolumeHeader.HeaderLength 

+                     + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)));

+    Instance--;

+  }

+

+  *FwhInstance = FwhRecord;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *Address,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  Address               - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 

+                          that on successful return, contains the base address

+                          of the firmware volume. 

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+  *Address = FwhInstance->FvBase[Virtual];

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          returned

+  Attributes            - Output buffer which contains attributes

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+  *Attributes = FwhInstance->VolumeHeader.Attributes;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbGetLbaAddress (

+  IN  UINTN                               Instance,

+  IN  EFI_LBA                             Lba,

+  OUT UINTN                               *LbaAddress,

+  OUT UINTN                               *LbaWriteAddress,

+  OUT UINTN                               *LbaLength,

+  OUT UINTN                               *NumOfBlocks,

+  IN  ESAL_FWB_GLOBAL                     *Global,

+  IN  BOOLEAN                             Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves the starting address of an LBA in an FV

+

+Arguments:

+  Instance              - The FV instance which the Lba belongs to

+  Lba                   - The logical block address

+  LbaAddress            - On output, contains the physical starting address 

+                          of the Lba

+  LbaWriteAddress       - On output, contains the physical starting address

+                          of the Lba for writing

+  LbaLength             - On output, contains the length of the block

+  NumOfBlocks           - A pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  UINT32                  NumBlocks;

+  UINT32                  BlockLength;

+  UINTN                   Offset;

+  EFI_LBA                 StartLba;

+  EFI_LBA                 NextLba;

+  EFI_FW_VOL_INSTANCE     *FwhInstance;

+  EFI_FV_BLOCK_MAP_ENTRY  *BlockMap;

+  EFI_STATUS              Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+

+  StartLba  = 0;

+  Offset    = 0;

+  BlockMap  = &(FwhInstance->VolumeHeader.FvBlockMap[0]);

+

+  //

+  // Parse the blockmap of the FV to find which map entry the Lba belongs to

+  //

+  while (TRUE) {

+    NumBlocks   = BlockMap->NumBlocks;

+    BlockLength = BlockMap->BlockLength;

+

+    if (NumBlocks == 0 || BlockLength == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    NextLba = StartLba + NumBlocks;

+

+    //

+    // The map entry found

+    //

+    if (Lba >= StartLba && Lba < NextLba) {

+      Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);

+      if (LbaAddress) {

+        *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;

+      }

+

+      if (LbaWriteAddress) {

+        *LbaWriteAddress = FwhInstance->FvWriteBase[Virtual] + Offset;

+      }

+

+      if (LbaLength) {

+        *LbaLength = BlockLength;

+      }

+

+      if (NumOfBlocks) {

+        *NumOfBlocks = (UINTN) (NextLba - Lba);

+      }

+

+      return EFI_SUCCESS;

+    }

+

+    StartLba  = NextLba;

+    Offset    = Offset + NumBlocks * BlockLength;

+    BlockMap++;

+  }

+}

+

+EFI_STATUS

+FvbReadBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Reads specified number of bytes into a buffer from the specified block

+

+Arguments:

+  Instance              - The FV instance to be read from

+  Lba                   - The logical block address to be read from

+  BlockOffset           - Offset into the block at which to begin reading

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes read

+  Buffer                - Pointer to a caller allocated buffer that will be

+                          used to hold the data read

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes returned

+                          in Buffer

+  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be read

+  EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL

+

+--*/

+{

+  EFI_FVB_ATTRIBUTES  Attributes;

+  UINTN               LbaAddress;

+  UINTN               LbaLength;

+  EFI_STATUS          Status;

+

+  //

+  // Check for invalid conditions

+  //

+  if ((NumBytes == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (*NumBytes == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, NULL, &LbaLength, NULL, Global, Virtual);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Check if the FV is read enabled

+  //

+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);

+

+  if ((Attributes & EFI_FVB_READ_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Perform boundary checks and adjust NumBytes

+  //

+  if (BlockOffset > LbaLength) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (LbaLength < (*NumBytes + BlockOffset)) {

+    *NumBytes = (UINT32) (LbaLength - BlockOffset);

+    Status    = EFI_BAD_BUFFER_SIZE;

+  }

+

+  EfiMemRead (EfiCpuIoWidthUint8, LbaAddress + BlockOffset, (UINTN) *NumBytes, Buffer);

+

+  return Status;

+}

+

+EFI_STATUS

+FlashFdWrite (

+  IN  UINTN                               WriteAddress,

+  IN  UINTN                               Address,

+  IN OUT UINTN                            *NumBytes,

+  IN  UINT8                               *Buffer,

+  IN  UINTN                               LbaLength

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the address

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  UINT8       *Src;

+  UINT8       *Dest;

+  UINTN       Count;

+  EFI_STATUS  Status;

+  UINT8       HubCommand;

+  UINT8       HubData;

+  UINTN       RetryTimes;

+

+  Status = EFI_SUCCESS;

+

+  EnableFvbWrites (TRUE);

+

+  //

+  // Grab the lock before entering critical code section

+  //

+  // bugbug

+  // Commented out since locking mechanisium is not correctly implemented

+  // on IA32 so that it will assert in runtime environment.

+  //

+  //  EfiAcquireLock(&(FwhInstance->FvbDevLock));

+  //

+  // Write data one byte at a time, don't write if the src and dest bytes match

+  //

+  Dest  = (UINT8 *) WriteAddress;

+  Src   = Buffer;

+

+  for (Count = 0; Count < *NumBytes; Count++, Dest++, Src++) {

+

+    HubCommand = FWH_WRITE_SETUP_COMMAND;

+    FvbMemWrite8 ((UINT64) ((UINTN) Dest), HubCommand);

+    FvbMemWrite8 ((UINT64) ((UINTN) Dest), *Src);

+    HubCommand = FWH_READ_STATUS_COMMAND;

+    FvbMemWrite8 ((UINT64) ((UINTN) Dest), HubCommand);

+

+    //

+    // Device error if time out occurs

+    //

+    RetryTimes = 0;

+    while (RetryTimes < FVB_MAX_RETRY_TIMES) {

+      EfiMemRead (EfiCpuIoWidthUint8, (UINT64) ((UINTN) Dest), 0x1, &HubData);

+      if (HubData & FWH_WRITE_STATE_STATUS) {

+        break;

+      }

+

+      RetryTimes++;

+    }

+

+    if (RetryTimes >= FVB_MAX_RETRY_TIMES) {

+      *NumBytes = Count;

+      Status    = EFI_DEVICE_ERROR;

+      break;

+    }

+  }

+  //

+  // Clear status register

+  //

+  HubCommand = FWH_CLEAR_STATUS_COMMAND;

+  FvbMemWrite8 ((UINT64) ((UINTN) Dest), HubCommand);

+

+  //

+  // Issue read array command to return the FWH state machine to the

+  // normal operational state

+  //

+  HubCommand = FWH_READ_ARRAY_COMMAND;

+  FvbMemWrite8 ((UINT64) ((UINTN) WriteAddress), HubCommand);

+  //

+  // Flush the changed area to make the cache consistent

+  //

+  EfiCpuFlushCache (WriteAddress, *NumBytes);

+

+  //

+  // End of critical code section, release lock.

+  //

+  //  EfiReleaseLock(&(FwhInstance->FvbDevLock));

+  //

+  EnableFvbWrites (FALSE);

+

+  return Status;

+}

+

+EFI_STATUS

+FlashFdErase (

+  IN UINTN                                WriteAddress,

+  IN UINTN                                Address,

+  IN UINTN                                LbaLength

+  )

+/*++

+

+Routine Description:

+  Erase a certain block from address LbaWriteAddress

+

+Arguments:

+

+Returns: 

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT8       HubCommand;

+  UINT8       HubData;

+  UINTN       RetryTimes;

+

+  Status = EFI_SUCCESS;

+

+  EnableFvbWrites (TRUE);

+

+  //

+  // Grab the lock before entering critical code section

+  //

+  //  EfiAcquireLock(&(FwhInstance->FvbDevLock));

+  //

+  // Send erase commands to FWH

+  //

+  HubCommand = FWH_BLOCK_ERASE_SETUP_COMMAND;

+  FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);

+  HubCommand = FWH_BLOCK_ERASE_CONFIRM_COMMAND;

+  FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);

+  HubCommand = FWH_READ_STATUS_COMMAND;

+  FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);

+

+  //

+  // Wait for completion. Indicated by FWH_WRITE_STATE_STATUS bit becoming 0

+  // Device error if time out occurs

+  //

+  RetryTimes = 0;

+  while (RetryTimes < FVB_MAX_RETRY_TIMES) {

+    EfiMemRead (EfiCpuIoWidthUint8, (UINT64) WriteAddress, 0x1, &HubData);

+    if (HubData & FWH_WRITE_STATE_STATUS) {

+      break;

+    }

+

+    RetryTimes++;

+  }

+

+  if (RetryTimes >= FVB_MAX_RETRY_TIMES) {

+    Status = EFI_DEVICE_ERROR;

+  }

+  //

+  // Clear status register

+  //

+  HubCommand = FWH_CLEAR_STATUS_COMMAND;

+  FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);

+

+  //

+  // Issue read array command to return the FWH state machine to the normal op state

+  //

+  HubCommand = FWH_READ_ARRAY_COMMAND;

+  FvbMemWrite8 ((UINT64) ((UINTN) WriteAddress), HubCommand);

+

+  EfiCpuFlushCache (Address, LbaLength);

+

+  //

+  // End of critical code section, release lock.

+  //

+  //  EfiReleaseLock(&(FwhInstance->FvbDevLock));

+  //

+  EnableFvbWrites (FALSE);

+

+  return Status;

+}

+

+EFI_STATUS

+FvbWriteBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the block

+

+Arguments:

+  Instance              - The FV instance to be written to

+  Lba                   - The starting logical block index to write to

+  BlockOffset           - Offset into the block at which to begin writing

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes actually written

+  Buffer                - Pointer to a caller allocated buffer that contains

+                          the source for the write

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was written successfully

+  EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes

+                          actually written

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written

+  EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL

+

+--*/

+{

+  EFI_FVB_ATTRIBUTES  Attributes;

+  UINTN               LbaAddress;

+  UINTN               LbaWriteAddress;

+  UINTN               LbaLength;

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_STATUS          Status;

+  EFI_STATUS          ReturnStatus;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Writes are enabled in the init routine itself

+  //

+  if (!FwhInstance->WriteEnabled) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Check for invalid conditions

+  //

+  if ((NumBytes == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (*NumBytes == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Check if the FV is write enabled

+  //

+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);

+

+  if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Perform boundary checks and adjust NumBytes

+  //

+  if (BlockOffset > LbaLength) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (LbaLength < (*NumBytes + BlockOffset)) {

+    *NumBytes = (UINT32) (LbaLength - BlockOffset);

+    Status    = EFI_BAD_BUFFER_SIZE;

+  }

+

+  ReturnStatus = FlashFdWrite (

+                  LbaWriteAddress + BlockOffset,

+                  LbaAddress,

+                  NumBytes,

+                  Buffer,

+                  LbaLength

+                  );

+  if (EFI_ERROR (ReturnStatus)) {

+    return ReturnStatus;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+FvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a firmware volume block

+

+Arguments:

+  Instance              - The FV instance to be erased

+  Lba                   - The logical block index to be erased

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The erase request was successfully completed

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+

+  EFI_FVB_ATTRIBUTES  Attributes;

+  UINTN               LbaAddress;

+  UINTN               LbaWriteAddress;

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  UINTN               LbaLength;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Writes are enabled in the init routine itself

+  //

+  if (!FwhInstance->WriteEnabled) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Check if the FV is write enabled

+  //

+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);

+

+  if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Get the starting address of the block for erase. For debug reasons,

+  // LbaWriteAddress may not be the same as LbaAddress.

+  //

+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return FlashFdErase (

+          LbaWriteAddress,

+          LbaAddress,

+          LbaLength

+          );

+}

+

+EFI_STATUS

+FvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  Instance              - The FV instance to be erased

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetStartLba        - Offset into the last block at which to end erasing

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was erased successfully

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_LBA Index;

+  UINTN   LbaSize;

+  UINTN   ScratchLbaSizeData;

+

+  //

+  // First LBA.

+  //

+  FvbGetLbaAddress (Instance, StartLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);

+

+  //

+  // Use the scratch space as the intermediate buffer to transfer data

+  // Back up the first LBA in scratch space.

+  //

+  FvbReadBlock (Instance, StartLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);

+

+  //

+  // erase now

+  //

+  FvbEraseBlock (Instance, StartLba, Global, Virtual);

+  ScratchLbaSizeData = OffsetStartLba;

+

+  //

+  // write the data back to the first block

+  //

+  if (ScratchLbaSizeData > 0) {

+    FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);

+  }

+  //

+  // Middle LBAs

+  //

+  if (LastLba > (StartLba + 1)) {

+    for (Index = (StartLba + 1); Index <= (LastLba - 1); Index++) {

+      FvbEraseBlock (Instance, Index, Global, Virtual);

+    }

+  }

+  //

+  // Last LBAs, the same as first LBAs

+  //

+  if (LastLba > StartLba) {

+    FvbGetLbaAddress (Instance, LastLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);

+    FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);

+    FvbEraseBlock (Instance, LastLba, Global, Virtual);

+  }

+

+  ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);

+

+  return FvbWriteBlock (

+          Instance,

+          LastLba,

+          (OffsetLastLba + 1),

+          &ScratchLbaSizeData,

+          Global->FvbScratchSpace[Virtual],

+          Global,

+          Virtual

+          );

+}

+

+EFI_STATUS

+FvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN OUT EFI_FVB_ATTRIBUTES               *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the 

+  input parameter, and returns the new setting of the volume

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          modified

+  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 

+                          containing the desired firmware volume settings.

+                          On successful return, it contains the new settings

+                          of the firmware volume

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_ACCESS_DENIED     - The volume setting is locked and cannot be modified

+  EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are

+                          in conflict with the capabilities as declared in the

+                          firmware volume header

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_FVB_ATTRIBUTES  OldAttributes;

+  EFI_FVB_ATTRIBUTES  *AttribPtr;

+  UINT32              Capabilities;

+  UINT32              OldStatus;

+  UINT32              NewStatus;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+

+  AttribPtr     = (EFI_FVB_ATTRIBUTES *) &(FwhInstance->VolumeHeader.Attributes);

+  OldAttributes = *AttribPtr;

+  Capabilities  = OldAttributes & EFI_FVB_CAPABILITIES;

+  OldStatus     = OldAttributes & EFI_FVB_STATUS;

+  NewStatus     = *Attributes & EFI_FVB_STATUS;

+

+  //

+  // If firmware volume is locked, no status bit can be updated

+  //

+  if (OldAttributes & EFI_FVB_LOCK_STATUS) {

+    if (OldStatus ^ NewStatus) {

+      return EFI_ACCESS_DENIED;

+    }

+  }

+  //

+  // Test read disable

+  //

+  if ((Capabilities & EFI_FVB_READ_DISABLED_CAP) == 0) {

+    if ((NewStatus & EFI_FVB_READ_STATUS) == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test read enable

+  //

+  if ((Capabilities & EFI_FVB_READ_ENABLED_CAP) == 0) {

+    if (NewStatus & EFI_FVB_READ_STATUS) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test write disable

+  //

+  if ((Capabilities & EFI_FVB_WRITE_DISABLED_CAP) == 0) {

+    if ((NewStatus & EFI_FVB_WRITE_STATUS) == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test write enable

+  //

+  if ((Capabilities & EFI_FVB_WRITE_ENABLED_CAP) == 0) {

+    if (NewStatus & EFI_FVB_WRITE_STATUS) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test lock

+  //

+  if ((Capabilities & EFI_FVB_LOCK_CAP) == 0) {

+    if (NewStatus & EFI_FVB_LOCK_STATUS) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  *AttribPtr  = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB_STATUS));

+  *AttribPtr  = (*AttribPtr) | NewStatus;

+  *Attributes = *AttribPtr;

+

+  return EFI_SUCCESS;

+}

+//

+// FVB protocol APIs

+//

+EFI_STATUS

+EFIAPI

+FvbProtocolGetPhysicalAddress (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the physical address of the device.

+

+Arguments:

+

+  This                  - Calling context

+  Address               - Output buffer containing the address.

+

+Returns:

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetBlockSize (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN  EFI_LBA                                     Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieve the size of a logical block

+

+Arguments:

+  This                  - Calling context

+  Lba                   - Indicates which block to return the size for.

+  BlockSize             - A pointer to a caller allocated UINTN in which

+                          the size of the block is returned

+  NumOfBlocks           - a pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbGetLbaAddress (

+          FvbDevice->Instance,

+          Lba,

+          NULL,

+          NULL,

+          BlockSize,

+          NumOfBlocks,

+          mFvbModuleGlobal,

+          EfiGoneVirtual ()

+          );

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+/*++

+

+Routine Description:

+    Retrieves Volume attributes.  No polarity translations are done.

+

+Arguments:

+    This                - Calling context

+    Attributes          - output buffer which contains attributes

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolSetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN OUT EFI_FVB_ATTRIBUTES                       *Attributes

+  )

+/*++

+

+Routine Description:

+  Sets Volume attributes. No polarity translations are done.

+

+Arguments:

+  This                  - Calling context

+  Attributes            - output buffer which contains attributes

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolEraseBlocks (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  ...  

+  )

+/*++

+

+Routine Description:

+

+  The EraseBlock() function erases one or more blocks as denoted by the 

+  variable argument list. The entire parameter list of blocks must be verified

+  prior to erasing any blocks.  If a block is requested that does not exist 

+  within the associated firmware volume (it has a larger index than the last 

+  block of the firmware volume), the EraseBlock() function must return

+  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

+

+Arguments:

+  This                  - Calling context

+  ...                   - Starting LBA followed by Number of Lba to erase. 

+                          a -1 to terminate the list.

+

+Returns: 

+  EFI_SUCCESS           - The erase request was successfully completed

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+  EFI_FW_VOL_INSTANCE     *FwhInstance;

+  UINTN                   NumOfBlocks;

+  VA_LIST                 args;

+  EFI_LBA                 StartingLba;

+  UINTN                   NumOfLba;

+  EFI_STATUS              Status;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());

+  ASSERT_EFI_ERROR (Status);

+

+  NumOfBlocks = FwhInstance->NumOfBlocks;

+

+  VA_START (args, This);

+

+  do {

+    StartingLba = VA_ARG (args, EFI_LBA);

+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {

+      break;

+    }

+

+    NumOfLba = VA_ARG (args, UINT32);

+

+    //

+    // Check input parameters

+    //

+    if ((NumOfLba == 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) {

+      VA_END (args);

+      return EFI_INVALID_PARAMETER;

+    }

+  } while (1);

+

+  VA_END (args);

+

+  VA_START (args, This);

+  do {

+    StartingLba = VA_ARG (args, EFI_LBA);

+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {

+      break;

+    }

+

+    NumOfLba = VA_ARG (args, UINT32);

+

+    while (NumOfLba > 0) {

+      Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());

+      if (EFI_ERROR (Status)) {

+        VA_END (args);

+        return Status;

+      }

+

+      StartingLba++;

+      NumOfLba--;

+    }

+

+  } while (1);

+

+  VA_END (args);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolWrite (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Writes data beginning at Lba:Offset from FV. The write terminates either

+  when *NumBytes of data have been written, or when a block boundary is

+  reached.  *NumBytes is updated to reflect the actual number of bytes

+  written. The write opertion does not include erase. This routine will

+  attempt to write only the specified bytes. If the writes do not stick,

+  it will return an error.

+

+Arguments:

+  This                  - Calling context

+  Lba                   - Block in which to begin write

+  Offset                - Offset in the block at which to begin write

+  NumBytes              - On input, indicates the requested write size. On

+                          output, indicates the actual number of bytes written

+  Buffer                - Buffer containing source data for the write.

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was written successfully

+  EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes

+                          actually written

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written

+  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL

+

+--*/

+{

+

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolRead (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Reads data beginning at Lba:Offset from FV. The Read terminates either

+  when *NumBytes of data have been read, or when a block boundary is

+  reached.  *NumBytes is updated to reflect the actual number of bytes

+  written. The write opertion does not include erase. This routine will

+  attempt to write only the specified bytes. If the writes do not stick,

+  it will return an error.

+

+Arguments:

+  This                  - Calling context

+  Lba                   - Block in which to begin Read

+  Offset                - Offset in the block at which to begin Read

+  NumBytes              - On input, indicates the requested write size. On

+                          output, indicates the actual number of bytes Read

+  Buffer                - Buffer containing source data for the Read.

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes returned

+                          in Buffer

+  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be read

+  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL

+

+--*/

+{

+

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+//

+// FVB Extension Protocols

+//

+EFI_STATUS

+EFIAPI

+FvbExtendProtocolEraseCustomBlockRange (

+  IN EFI_FVB_EXTENSION_PROTOCOL           *This,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  This                  - Calling context

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetStartLba        - Offset into the last block at which to end erasing

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was erased successfully

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_EXTEND_DEVICE_FROM_THIS (This);

+

+  return FvbEraseCustomBlockRange (

+          FvbDevice->Instance,

+          StartLba,

+          OffsetStartLba,

+          LastLba,

+          OffsetLastLba,

+          mFvbModuleGlobal,

+          EfiGoneVirtual ()

+          );

+}

+

+STATIC

+EFI_STATUS

+ValidateFvHeader (

+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader

+  )

+/*++

+

+Routine Description:

+  Check the integrity of firmware volume header

+

+Arguments:

+  FwVolHeader           - A pointer to a firmware volume header

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume is consistent

+  EFI_NOT_FOUND         - The firmware volume has corrupted. So it is not an FV

+

+--*/

+{

+  UINT16  *Ptr;

+  UINT16  HeaderLength;

+  UINT16  Checksum;

+

+  //

+  // Verify the header revision, header signature, length

+  // Length of FvBlock cannot be 2**64-1

+  // HeaderLength cannot be an odd number

+  //

+  if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||

+      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||

+      (FwVolHeader->FvLength == ((UINTN) -1)) ||

+      ((FwVolHeader->HeaderLength & 0x01) != 0)

+      ) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Verify the header checksum

+  //

+  HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);

+  Ptr           = (UINT16 *) FwVolHeader;

+  Checksum      = 0;

+  while (HeaderLength > 0) {

+    Checksum = *Ptr++;

+    HeaderLength--;

+  }

+

+  if (Checksum != 0) {

+    return EFI_NOT_FOUND;

+  }

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+FvbGetCfiSupported (

+  IN UINTN                              LbaAddress

+  )

+/*++

+

+Routine Description:

+  Check if the firmware volume is CFI typed flash

+

+Arguments:

+  LbaAddress            - The physical address of the firmware volume

+

+Returns: 

+  TRUE                  - CFI supported

+  FALSE                 - CFI un-supported

+

+--*/

+{

+  UINT8   HubData[8];

+  UINT8   HubCommand;

+  BOOLEAN Supported;

+

+  Supported = TRUE;

+

+  //

+  //  Issue CFI Query (98h) to address 55h

+  //

+  HubCommand = CFI_QUERY;

+  FvbMemWrite8 ((LbaAddress + 0x55), HubCommand);

+  //

+  //  x8 device in 8-bit mode?

+  //

+  EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x10), 0x3, &HubData);

+  if (!EfiCompareMem (HubData, "QRY", 3)) {

+    goto Done;

+  }

+  //

+  //  paired x8 devices?

+  //

+  EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x20), 0x6, &HubData);

+  if (!EfiCompareMem (HubData, "QQRRYY", 6)) {

+    goto Done;

+  }

+  //

+  //  x16 device in 16-bit mode?

+  //

+  EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x20), 0x4, &HubData);

+  if ((!EfiCompareMem (&HubData[0], "R", 2)) && (!EfiCompareMem (&HubData[2], "Q", 2))) {

+    goto Done;

+  }

+  //

+  //  x16 device in 8-bit mode?

+  //

+  EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x20), 0x3, &HubData);

+  if (!EfiCompareMem (HubData, "QQR", 3)) {

+    goto Done;

+  }

+  //

+  // 2 x16 devices in 8-bit mode (paired chip configuration)?

+  //

+  EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x40), 0x6, &HubData);

+  if (!EfiCompareMem (HubData, "QQQQRR", 6)) {

+    goto Done;

+  }

+  //

+  //  x32 device in 8-bit mode

+  //

+  EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x40), 0x5, &HubData);

+  if (!EfiCompareMem (HubData, "QQQQR", 5)) {

+    goto Done;

+  }

+  //

+  // x32 device in 32-bit mode

+  //

+  if ((!EfiCompareMem (&HubData[0], "R", 2)) && (((UINT16) HubData[2]) == 0) && (HubData[4] == 'Q')) {

+    goto Done;

+  }

+  //

+  //  If it got to here, CFI is not supported

+  //

+  Supported = FALSE;

+

+Done:

+  //

+  // Bug Fix #4071:

+  //   Issue command FWH_READ_ARRAY_COMMAND (0xff) at the end of this service to

+  //   guarantee that the FWH is back in read mode again

+  //

+  HubCommand = FWH_READ_ARRAY_COMMAND;

+  FvbMemWrite8 (LbaAddress, HubCommand);

+

+  return Supported;

+}

+

+EFI_STATUS

+GetFvbHeader (

+  VOID                                **HobList,

+  EFI_FIRMWARE_VOLUME_HEADER          **FwVolHeader,

+  EFI_PHYSICAL_ADDRESS                *BaseAddress,

+  BOOLEAN                             *WriteBack

+  )

+{

+  EFI_STATUS                Status;

+  VOID                      *Buffer;

+  EFI_FLASH_MAP_ENTRY_DATA  *FlashMapEntry;

+  EFI_FLASH_SUBAREA_ENTRY   *FlashMapSubEntry;

+

+  Status        = EFI_SUCCESS;

+  *FwVolHeader  = NULL;

+  *WriteBack    = FALSE;

+

+  Status        = GetNextGuidHob (HobList, &gEfiFlashMapHobGuid, &Buffer, NULL);

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  FlashMapEntry     = (EFI_FLASH_MAP_ENTRY_DATA *) Buffer;

+  FlashMapSubEntry  = &FlashMapEntry->Entries[0];

+  //

+  // Check if it is a "FVB" area

+  //

+  if (!EfiCompareGuid (&FlashMapSubEntry->FileSystem, &gEfiFirmwareVolumeBlockProtocolGuid)) {

+    return Status;

+  }

+  //

+  // Check if it is a "real" flash

+  //

+  if (FlashMapSubEntry->Attributes != (EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV)) {

+    return Status;

+  }

+

+  *BaseAddress = FlashMapSubEntry->Base;

+  DEBUG ((EFI_D_ERROR, "FlashMap HOB: BaseAddress = 0x%lx\n", *BaseAddress));

+

+  *FwVolHeader  = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (*BaseAddress);

+  Status        = ValidateFvHeader (*FwVolHeader);

+  if (EFI_ERROR (Status)) {

+    //

+    // Get FvbInfo

+    //

+    *WriteBack = TRUE;

+    DEBUG ((EFI_D_ERROR, "BaseAddress = 0x%lx\n", BaseAddress));

+    Status = GetFvbInfo (*BaseAddress, FwVolHeader);

+    DEBUG ((EFI_D_ERROR, "Fvb: FV header invalid, GetFvbInfo - %r\n", Status));

+    ASSERT_EFI_ERROR (Status);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+FvbInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  This function does common initialization for FVB services

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_FW_VOL_INSTANCE                 *FwhInstance;

+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;

+  VOID                                *HobList;

+  VOID                                *FirmwareVolumeHobList;

+  UINT32                              BufferSize;

+  EFI_FV_BLOCK_MAP_ENTRY              *PtrBlockMapEntry;

+  UINTN                               LbaAddress;

+  UINT8                               Data;

+  UINTN                               BlockIndex2;

+  BOOLEAN                             WriteEnabled;

+  BOOLEAN                             WriteLocked;

+  EFI_HANDLE                          FwbHandle;

+  EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *OldFwbInterface;

+  EFI_DEVICE_PATH_PROTOCOL            *TempFwbDevicePath;

+  FV_DEVICE_PATH                      TempFvbDevicePathData;

+  UINT32                              MaxLbaSize;

+  BOOLEAN                             CfiEnabled;

+  EFI_PHYSICAL_ADDRESS                BaseAddress;

+  BOOLEAN                             WriteBack;

+  UINTN                               NumOfBlocks;

+  UINTN                               HeaderLength;

+

+  INITIALIZE_SCRIPT (ImageHandle, SystemTable);

+

+  EfiInitializeRuntimeDriverLib (ImageHandle, SystemTable, FvbVirtualddressChangeEvent);

+

+  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);

+  HeaderLength = 0;

+  //

+  // No FV HOBs found

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Allocate runtime services data for global variable, which contains

+  // the private data of all firmware volume block instances

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  sizeof (ESAL_FWB_GLOBAL),

+                  &mFvbModuleGlobal

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  EnablePlatformFvb ();

+  EnableFvbWrites (TRUE);

+

+  //

+  // Calculate the total size for all firmware volume block instances

+  //

+  BufferSize            = 0;

+  FirmwareVolumeHobList = HobList;

+  do {

+    Status = GetFvbHeader (&FirmwareVolumeHobList, &FwVolHeader, &BaseAddress, &WriteBack);

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (FwVolHeader) {

+      BufferSize += (FwVolHeader->HeaderLength + sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER));

+    }

+  } while (TRUE);

+

+  //

+  // Only need to allocate once. There is only one copy of physical memory for

+  // the private data of each FV instance. But in virtual mode or in physical

+  // mode, the address of the the physical memory may be different.

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  BufferSize,

+                  &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Make a virtual copy of the FvInstance pointer.

+  //

+  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];

+  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;

+

+  mFvbModuleGlobal->NumFv                   = 0;

+  FirmwareVolumeHobList                     = HobList;

+

+  MaxLbaSize = 0;

+

+  //

+  // Fill in the private data of each firmware volume block instance

+  //

+  do {

+    Status = GetFvbHeader (&FirmwareVolumeHobList, &FwVolHeader, &BaseAddress, &WriteBack);

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (!FwVolHeader) {

+      continue;

+    }

+

+    EfiCopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);

+    FwVolHeader                       = &(FwhInstance->VolumeHeader);

+

+    FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;

+    FwhInstance->FvBase[FVB_VIRTUAL]  = (UINTN) BaseAddress;

+

+    //

+    // FwhInstance->FvWriteBase may not be the same as FwhInstance->FvBase

+    //

+    PlatformGetFvbWriteBase (

+      (UINTN) BaseAddress,

+      (UINTN *) &(FwhInstance->FvWriteBase[FVB_PHYSICAL]),

+      &WriteEnabled

+      );

+    //

+    // Every pointer should have a virtual copy.

+    //

+    FwhInstance->FvWriteBase[FVB_VIRTUAL] = FwhInstance->FvWriteBase[FVB_PHYSICAL];

+

+    FwhInstance->WriteEnabled             = WriteEnabled;

+    EfiInitializeLock (&(FwhInstance->FvbDevLock), EFI_TPL_HIGH_LEVEL);

+

+    LbaAddress  = (UINTN) FwhInstance->FvWriteBase[0];

+    NumOfBlocks = 0;

+    WriteLocked = FALSE;

+

+    if (WriteEnabled) {

+      CfiEnabled = FvbGetCfiSupported (LbaAddress);

+      for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {

+

+        for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {

+

+          if (SetPlatformFvbLock (LbaAddress)) {

+            //

+            // Clear all write-lock and read-lock HW bits

+            // For sync3, the software will enforce the protection

+            //

+            if (CfiEnabled) {

+              Data = CFI_BLOCK_LOCK_UNLOCK;

+              FvbMemWrite8 (LbaAddress, Data);

+              Data = CFI_BLOCK_UNLOCK_CONFIRM;

+              FvbMemWrite8 (LbaAddress, Data);

+              while (TRUE) {

+                EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 2), 1, &Data);

+                if (Data & 0x80) {

+                  break;

+                }

+              }

+

+              Data = FWH_READ_ARRAY_COMMAND;

+              FvbMemWrite8 (LbaAddress, Data);

+            } else {

+              EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress - 0x400000 + 2), 0x1, &Data);

+              //

+              // bugbug: lock down is block based, not FV based. Here we assume that

+              // the FV is locked if one of its block is locked

+              //

+              if ((Data & FWH_WRITE_LOCK) && (Data & FWH_LOCK_DOWN)) {

+                //

+                // the flash is locked and locked down

+                //

+                WriteLocked = TRUE;

+              } else {

+                Data &= ~(FWH_WRITE_LOCK | FWH_READ_LOCK | FWH_LOCK_DOWN);

+

+                //

+                // Save boot script for S3 resume

+                //

+                SCRIPT_MEM_WRITE (

+                  EFI_ACPI_S3_RESUME_SCRIPT_TABLE,

+                  EfiBootScriptWidthUint8,

+                  (UINT64) (LbaAddress - 0x400000 + 2),

+                  1,

+                  &Data

+                  );

+

+                FvbMemWrite8 ((LbaAddress - 0x400000 + 2), Data);

+              }

+            }

+          }

+

+          LbaAddress += PtrBlockMapEntry->BlockLength;

+        }

+        //

+        // Get the maximum size of a block. The size will be used to allocate

+        // buffer for Scratch space, the intermediate buffer for FVB extension

+        // protocol

+        //

+        if (MaxLbaSize < PtrBlockMapEntry->BlockLength) {

+          MaxLbaSize = PtrBlockMapEntry->BlockLength;

+        }

+

+        NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;

+      }

+      //

+      //  Write back a healthy FV header

+      //

+      if (WriteBack && (!WriteLocked)) {

+        Status = FlashFdErase (

+                  (UINTN) FwhInstance->FvWriteBase[0],

+                  (UINTN) BaseAddress,

+                  FwVolHeader->FvBlockMap->BlockLength

+                  );

+

+        HeaderLength = (UINTN) FwVolHeader->HeaderLength;

+        Status = FlashFdWrite (

+                  (UINTN) FwhInstance->FvWriteBase[0],

+                  (UINTN) BaseAddress,

+                  (UINTN *) &HeaderLength,

+                  (UINT8 *) FwVolHeader,

+                  FwVolHeader->FvBlockMap->BlockLength

+                  );

+                  

+        FwVolHeader->HeaderLength = (UINT16) HeaderLength;         

+        DEBUG ((EFI_D_ERROR, "Fvb: FV header invalid, write back - %r\n", Status));

+      }

+    }

+    //

+    // The total number of blocks in the FV.

+    //

+    FwhInstance->NumOfBlocks = NumOfBlocks;

+

+    //

+    // If the FV is write locked, set the appropriate attributes

+    //

+    if (WriteLocked) {

+      //

+      // write disabled

+      //

+      FwhInstance->VolumeHeader.Attributes &= ~EFI_FVB_WRITE_STATUS;

+      //

+      // lock enabled

+      //

+      FwhInstance->VolumeHeader.Attributes |= EFI_FVB_LOCK_STATUS;

+    }

+    //

+    // Add a FVB Protocol Instance

+    //

+    Status = gBS->AllocatePool (

+                    EfiRuntimeServicesData,

+                    sizeof (EFI_FW_VOL_BLOCK_DEVICE),

+                    &FvbDevice

+                    );

+    ASSERT_EFI_ERROR (Status);

+

+    EfiCopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));

+

+    FvbDevice->Instance = mFvbModuleGlobal->NumFv;

+    mFvbModuleGlobal->NumFv++;

+

+    //

+    // Set up the devicepath

+    //

+    FvbDevice->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;

+    FvbDevice->DevicePath.MemMapDevPath.EndingAddress   = BaseAddress + (FwVolHeader->FvLength - 1);

+

+    //

+    // Find a handle with a matching device path that has supports FW Block protocol

+    //

+    TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData;

+    EfiCopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH));

+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);

+    if (EFI_ERROR (Status)) {

+      //

+      // LocateDevicePath fails so install a new interface and device path

+      //

+      FwbHandle = NULL;

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &FwbHandle,

+                      &gEfiFirmwareVolumeBlockProtocolGuid,

+                      &FvbDevice->FwVolBlockInstance,

+                      &gEfiDevicePathProtocolGuid,

+                      &FvbDevice->DevicePath,

+                      NULL

+                      );

+      ASSERT_EFI_ERROR (Status);

+    } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {

+      //

+      // Device allready exists, so reinstall the FVB protocol

+      //

+      Status = gBS->HandleProtocol (

+                      FwbHandle,

+                      &gEfiFirmwareVolumeBlockProtocolGuid,

+                      &OldFwbInterface

+                      );

+      ASSERT_EFI_ERROR (Status);

+

+      Status = gBS->ReinstallProtocolInterface (

+                      FwbHandle,

+                      &gEfiFirmwareVolumeBlockProtocolGuid,

+                      OldFwbInterface,

+                      &FvbDevice->FwVolBlockInstance

+                      );

+      ASSERT_EFI_ERROR (Status);

+

+    } else {

+      //

+      // There was a FVB protocol on an End Device Path node

+      //

+      ASSERT (FALSE);

+    }

+    //

+    // Install FVB Extension Protocol on the same handle

+    //

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &FwbHandle,

+                    &gEfiFvbExtensionProtocolGuid,

+                    &FvbDevice->FvbExtension,

+                    &gEfiAlternateFvBlockGuid,

+                    NULL,

+                    NULL

+                    );

+

+    ASSERT_EFI_ERROR (Status);

+

+    FwhInstance = (EFI_FW_VOL_INSTANCE *)

+      (

+        (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +

+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))

+      );

+  } while (TRUE);

+

+  //

+  // Allocate for scratch space, an intermediate buffer for FVB extention

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  MaxLbaSize,

+                  &mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];

+

+  FvbSpecificInitialize (mFvbModuleGlobal);

+

+  return EnableFvbWrites (FALSE);

+}

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/FwBlockService.h b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/FwBlockService.h
new file mode 100644
index 0000000..1fad9bd
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/FwBlockService.h
@@ -0,0 +1,324 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwBlockService.h

+  

+Abstract:

+

+  Firmware volume block driver for Intel Firmware Hub (FWH) device

+

+--*/

+

+#ifndef _FW_BLOCK_SERVICE_H

+#define _FW_BLOCK_SERVICE_H

+

+//

+// Statements that include other header files

+//

+#include "Tiano.h"

+#include "EfiFirmwareVolumeHeader.h"

+#include "EfiRuntimeLib.h"

+#include "EfiHobLib.h"

+#include "EfiScriptLib.h"

+

+#include EFI_PROTOCOL_PRODUCER (FirmwareVolumeBlock)

+#include EFI_PROTOCOL_PRODUCER (FvbExtension)

+#include EFI_GUID_DEFINITION (AlternateFvBlock)

+#include EFI_GUID_DEFINITION (Hob)

+#include EFI_GUID_DEFINITION (DxeServices)

+#include EFI_PROTOCOL_CONSUMER (CpuIo)

+

+#define FVB_MAX_RETRY_TIMES             10000000

+#define FWH_BLOCK_ERASE_SETUP_COMMAND   0x20

+#define FWH_BLOCK_ERASE_CONFIRM_COMMAND 0xd0

+#define FWH_READ_STATUS_COMMAND         0x70

+#define FWH_CLEAR_STATUS_COMMAND        0x50

+#define FWH_READ_ARRAY_COMMAND          0xff

+#define FWH_WRITE_SETUP_COMMAND         0x40

+#define FWH_OPEN_FEATURE_SPACE_COMMAND  0x91

+#define FWH_READ_LOCK                   (1 << 2)

+#define FWH_WRITE_LOCK                  (1 << 1)

+#define FWH_LOCK_DOWN                   1

+#define FWH_WRITE_STATE_STATUS          (1 << 7)

+#define FWH_ERASE_STATUS                (1 << 5)

+#define FWH_PROGRAM_STATUS              (1 << 4)

+#define FWH_VPP_STATUS                  (1 << 3)

+#define STALL_TIME                      5

+#define FWH_ERASE_STATUS_BITS           (FWH_ERASE_STATUS || FWH_VPP_STATUS)

+#define FWH_WRITE_STATUS_BITS           (FWH_WRITE_STATUS || FWH_VPP_STATUS)

+#define CFI_BLOCK_LOCK_UNLOCK           0x60

+#define CFI_BLOCK_LOCK_CONFIRM          1

+#define CFI_BLOCK_UNLOCK_CONFIRM        0xD0

+#define CFI_QUERY                       0x98

+

+//

+// BugBug: Add documentation here for data structure!!!!

+//

+#define FVB_PHYSICAL  0

+#define FVB_VIRTUAL   1

+

+typedef struct {

+  EFI_LOCK                    FvbDevLock;

+  UINTN                       FvBase[2];

+  UINTN                       FvWriteBase[2];

+  UINTN                       NumOfBlocks;

+  BOOLEAN                     WriteEnabled;

+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;

+} EFI_FW_VOL_INSTANCE;

+

+typedef struct {

+  UINT32              NumFv;

+  EFI_FW_VOL_INSTANCE *FvInstance[2];

+  UINT8               *FvbScratchSpace[2];

+} ESAL_FWB_GLOBAL;

+

+//

+// Fvb Protocol instance data

+//

+#define FVB_DEVICE_FROM_THIS(a)         CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)

+#define FVB_EXTEND_DEVICE_FROM_THIS(a)  CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)

+#define FVB_DEVICE_SIGNATURE            EFI_SIGNATURE_32 ('F', 'V', 'B', 'C')

+

+typedef struct {

+  MEMMAP_DEVICE_PATH        MemMapDevPath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;

+} FV_DEVICE_PATH;

+

+typedef struct {

+  UINTN                               Signature;

+  FV_DEVICE_PATH                      DevicePath;

+  UINTN                               Instance;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance;

+  EFI_FVB_EXTENSION_PROTOCOL          FvbExtension;

+} EFI_FW_VOL_BLOCK_DEVICE;

+

+EFI_STATUS

+GetFvbInfo (

+  IN  EFI_PHYSICAL_ADDRESS              FvBaseAddress,

+  OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo

+  )

+;

+

+EFI_STATUS

+EnableFvbWrites (

+  IN  BOOLEAN   EnableWrites

+  )

+;

+

+EFI_STATUS

+PlatformGetFvbWriteBase (

+  IN  UINTN     CurrentBaseAddress,

+  IN  UINTN     *NewBaseAddress,

+  IN  BOOLEAN   *WriteEnabled

+  )

+;

+

+EFI_STATUS

+EnablePlatformFvb (

+  VOID

+  )

+;

+

+BOOLEAN

+SetPlatformFvbLock (

+  IN UINTN  LbaAddress

+  )

+;

+

+EFI_STATUS

+FvbReadBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbWriteBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN OUT EFI_FVB_ATTRIBUTES               *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *Address,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+

+VOID

+EFIAPI

+FvbClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+;

+

+EFI_STATUS

+FvbSpecificInitialize (

+  IN  ESAL_FWB_GLOBAL   *mFvbModuleGlobal

+  )

+;

+

+EFI_STATUS

+FvbGetLbaAddress (

+  IN  UINTN                               Instance,

+  IN  EFI_LBA                             Lba,

+  OUT UINTN                               *LbaAddress,

+  OUT UINTN                               *LbaWriteAddress,

+  OUT UINTN                               *LbaLength,

+  OUT UINTN                               *NumOfBlocks,

+  IN  ESAL_FWB_GLOBAL                     *Global,

+  IN  BOOLEAN                             Virtual

+  )

+;

+

+EFI_STATUS

+FvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+//

+// Protocol APIs

+//

+EFI_STATUS

+EFIAPI

+FvbProtocolGetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolSetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN OUT EFI_FVB_ATTRIBUTES                       *Attributes

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetPhysicalAddress (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetBlockSize (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN  EFI_LBA                                     Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolRead (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolWrite (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolEraseBlocks (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  ...

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbExtendProtocolEraseCustomBlockRange (

+  IN EFI_FVB_EXTENSION_PROTOCOL           *This,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/ia32/Ia32Fwh.c b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/ia32/Ia32Fwh.c
new file mode 100644
index 0000000..00998f8
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Common/ia32/Ia32Fwh.c
@@ -0,0 +1,42 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Ia32Fwh.c

+    

+Abstract:

+

+Revision History

+

+--*/

+

+#include "FWBlockService.h"

+

+EFI_STATUS

+FvbSpecificInitialize (

+  IN  ESAL_FWB_GLOBAL   *mFvbModuleGlobal

+  )

+/*++

+

+Routine Description:

+  Additional initialize code for IA32 platform.

+

+Arguments:

+  ESAL_FWB_GLOBAL       - Global pointer that points to the instance data

+

+Returns: 

+  EFI_SUCCESS

+

+--*/

+{

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.dxs b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.dxs
new file mode 100644
index 0000000..3cb3112
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.dxs
@@ -0,0 +1,27 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    Nt32Fwh.dxs

+

+Abstract:

+

+  Dependency expression source file.

+  

+--*/  

+#include <AutoGen.h>

+#include <DxeDepex.h>

+

+

+DEPENDENCY_START

+  TRUE

+DEPENDENCY_END
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.mbd b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.mbd
new file mode 100644
index 0000000..7f83760
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.mbd
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>FwBlockService</BaseName>

+    <Guid>BDFE5FAA-2A35-44bb-B17A-8084D4E2B9E9</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>UefiBootServicesTableLib</Library>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>UefiLib</Library>

+    <Library>UefiDriverEntryPoint</Library>

+    <Library>DxeReportStatusCodeLib</Library>

+    <Library>DxeServicesTableLib</Library>

+    <Library>BaseDebugLibNull</Library>

+    <Library>EdkDxePrintLib</Library>

+    <Library>EdkDxeRuntimeDriverLib</Library>

+    <Library>DxeHobLib</Library>

+    <Library>DxeMemoryAllocationLib</Library>

+  </Libraries>

+  <BuildOptions ToolChain="MSFT">

+    <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>

+  </BuildOptions>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.msa b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.msa
new file mode 100644
index 0000000..5e7b2d3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/Nt32Fwh.msa
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>FwBlockService</BaseName>

+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>

+    <ComponentType>RT_DRIVER</ComponentType>

+    <Guid>BDFE5FAA-2A35-44bb-B17A-8084D4E2B9E9</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for DiskIo module.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>Nt32Fwh.dxs</Filename>

+    <Arch ArchType="IA32">

+      <Filename>nt32\FwBlockService.c</Filename>

+      <Filename>nt32\FwBlockService.h</Filename>

+      <Filename>nt32\FvbInfo.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="SOMETIMES_PRODUCED">DevicePath</Protocol>

+    <Protocol Usage="SOMETIMES_PRODUCED">FirmwareVolumeBlock</Protocol>

+    <Protocol Usage="ALWAYS_PRODUCED">FvbExtension</Protocol>

+  </Protocols>

+  <Events>

+    <CreateEvents>

+      <Event Usage="ALWAYS_CONSUMED" EventGroup="EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE">

+        <C_Name>gEfiEventVirtualAddressChangeGuid</C_Name>

+        <Guid>0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96</Guid>

+      </Event>

+    </CreateEvents>

+  </Events>

+  <Hobs>

+    <Hob Usage="ALWAYS_CONSUMED" HobType="FIRMWARE_VOLUME"></Hob>

+  </Hobs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_PRODUCED">

+      <C_Name>AlternateFvBlock</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint>FvbInitialize</ModuleEntryPoint>

+    </Extern>

+    <Extern>

+      <SetVirtualAddressMapCallBack></SetVirtualAddressMapCallBack>

+      <ExitBootServicesCallBack></ExitBootServicesCallBack>

+    </Extern>

+  </Externs>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/build.xml b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/build.xml
new file mode 100644
index 0000000..60d06c4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="FwBlockService"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="RuntimeDxe\FvbServices"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="FwBlockService">

+      <GenBuild baseName="FwBlockService" mbdFilename="${MODULE_DIR}\Nt32Fwh.mbd" msaFilename="${MODULE_DIR}\Nt32Fwh.msa"/>

+   </target>

+   <target depends="FwBlockService_clean" name="clean"/>

+   <target depends="FwBlockService_cleanall" name="cleanall"/>

+   <target name="FwBlockService_clean">

+      <OutputDirSetup baseName="FwBlockService" mbdFilename="${MODULE_DIR}\Nt32Fwh.mbd" msaFilename="${MODULE_DIR}\Nt32Fwh.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\FwBlockService_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\FwBlockService_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="FwBlockService_cleanall">

+      <OutputDirSetup baseName="FwBlockService" mbdFilename="${MODULE_DIR}\Nt32Fwh.mbd" msaFilename="${MODULE_DIR}\Nt32Fwh.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\FwBlockService_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\FwBlockService_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**FwBlockService*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FWBlockService.c b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FWBlockService.c
new file mode 100644
index 0000000..1f2f8fd
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FWBlockService.c
@@ -0,0 +1,1493 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FWBlockService.c

+    

+Abstract:

+

+Revision History

+

+--*/

+

+#include "FWBlockService.h"

+

+ESAL_FWB_GLOBAL         *mFvbModuleGlobal;

+

+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {

+  FVB_DEVICE_SIGNATURE,

+  {

+    {

+      {

+        HARDWARE_DEVICE_PATH,

+        HW_MEMMAP_DP,

+        {

+          sizeof (MEMMAP_DEVICE_PATH),

+          0

+        }

+      },

+      EfiMemoryMappedIO,

+      0,

+      0,

+    },

+    {

+      END_DEVICE_PATH_TYPE,

+      END_ENTIRE_DEVICE_PATH_SUBTYPE,

+      {

+        sizeof (EFI_DEVICE_PATH_PROTOCOL),

+        0

+      }

+    }

+  },

+  0,

+  {

+    FvbProtocolGetAttributes,

+    FvbProtocolSetAttributes,

+    FvbProtocolGetPhysicalAddress,

+    FvbProtocolGetBlockSize,

+    FvbProtocolRead,

+    FvbProtocolWrite,

+    FvbProtocolEraseBlocks,

+    NULL

+  },

+  {

+    FvbExtendProtocolEraseCustomBlockRange

+  }

+};

+

+

+

+VOID

+EFIAPI

+FvbVirtualddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+/*++

+

+Routine Description:

+

+  Fixup internal data so that EFI and SAL can be call in virtual mode.

+  Call the passed in Child Notify event and convert the mFvbModuleGlobal

+  date items to there virtual address.

+

+  mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]  - Physical copy of instance data

+  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]   - Virtual pointer to common 

+                                                instance data.

+

+Arguments:

+

+  (Standard EFI notify event - EFI_EVENT_NOTIFY)

+

+Returns: 

+

+  None

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  UINTN               Index;

+

+  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);

+

+  //

+  // Convert the base address of all the instances

+  //

+  Index       = 0;

+  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];

+  while (Index < mFvbModuleGlobal->NumFv) {

+    EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);

+    FwhInstance = (EFI_FW_VOL_INSTANCE *)

+      (

+        (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +

+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))

+      );

+    Index++;

+  }

+

+  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);

+  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);

+}

+

+EFI_STATUS

+GetFvbInstance (

+  IN  UINTN                               Instance,

+  IN  ESAL_FWB_GLOBAL                     *Global,

+  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  FwhInstance           - The EFI_FW_VOL_INSTANCE fimrware instance structure

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhRecord;

+

+  if (Instance >= Global->NumFv) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the right instance of the FVB private data

+  //

+  FwhRecord = Global->FvInstance[Virtual];

+  while (Instance > 0) {

+    FwhRecord = (EFI_FW_VOL_INSTANCE *)

+      (

+        (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +

+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))

+      );

+    Instance--;

+  }

+

+  *FwhInstance = FwhRecord;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *Address,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves the physical address of a memory mapped FV

+

+Arguments:

+  Instance              - The FV instance whose base address is going to be

+                          returned

+  Address               - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 

+                          that on successful return, contains the base address

+                          of the firmware volume. 

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+  *Address = FwhInstance->FvBase[Virtual];

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          returned

+  Attributes            - Output buffer which contains attributes

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+  *Attributes = FwhInstance->VolumeHeader.Attributes;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbGetLbaAddress (

+  IN  UINTN                               Instance,

+  IN  EFI_LBA                             Lba,

+  OUT UINTN                               *LbaAddress,

+  OUT UINTN                               *LbaLength,

+  OUT UINTN                               *NumOfBlocks,

+  IN  ESAL_FWB_GLOBAL                     *Global,

+  IN  BOOLEAN                             Virtual

+  )

+/*++

+

+Routine Description:

+  Retrieves the starting address of an LBA in an FV

+

+Arguments:

+  Instance              - The FV instance which the Lba belongs to

+  Lba                   - The logical block address

+  LbaAddress            - On output, contains the physical starting address 

+                          of the Lba

+  LbaLength             - On output, contains the length of the block

+  NumOfBlocks           - A pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  UINT32                  NumBlocks;

+  UINT32                  BlockLength;

+  UINTN                   Offset;

+  EFI_LBA                 StartLba;

+  EFI_LBA                 NextLba;

+  EFI_FW_VOL_INSTANCE     *FwhInstance;

+  EFI_FV_BLOCK_MAP_ENTRY  *BlockMap;

+  EFI_STATUS              Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+

+  StartLba  = 0;

+  Offset    = 0;

+  BlockMap  = &(FwhInstance->VolumeHeader.FvBlockMap[0]);

+

+  //

+  // Parse the blockmap of the FV to find which map entry the Lba belongs to

+  //

+  while (TRUE) {

+    NumBlocks   = BlockMap->NumBlocks;

+    BlockLength = BlockMap->BlockLength;

+

+    if (NumBlocks == 0 || BlockLength == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    NextLba = StartLba + NumBlocks;

+

+    //

+    // The map entry found

+    //

+    if (Lba >= StartLba && Lba < NextLba) {

+      Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);

+      if (LbaAddress != NULL) {

+        *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;

+      }

+

+      if (LbaLength != NULL) {

+        *LbaLength = BlockLength;

+      }

+

+      if (NumOfBlocks != NULL) {

+        *NumOfBlocks = (UINTN) (NextLba - Lba);

+      }

+

+      return EFI_SUCCESS;

+    }

+

+    StartLba  = NextLba;

+    Offset    = Offset + NumBlocks * BlockLength;

+    BlockMap++;

+  }

+}

+

+EFI_STATUS

+FvbReadBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Reads specified number of bytes into a buffer from the specified block

+

+Arguments:

+  Instance              - The FV instance to be read from

+  Lba                   - The logical block address to be read from

+  BlockOffset           - Offset into the block at which to begin reading

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes read

+  Buffer                - Pointer to a caller allocated buffer that will be

+                          used to hold the data read

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes returned

+                          in Buffer

+  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be read

+  EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL

+

+--*/

+{

+  EFI_FVB_ATTRIBUTES  Attributes;

+  UINTN               LbaAddress;

+  UINTN               LbaLength;

+  EFI_STATUS          Status;

+

+  //

+  // Check for invalid conditions

+  //

+  if ((NumBytes == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (*NumBytes == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Check if the FV is read enabled

+  //

+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);

+

+  if ((Attributes & EFI_FVB_READ_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Perform boundary checks and adjust NumBytes

+  //

+  if (BlockOffset > LbaLength) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (LbaLength < (*NumBytes + BlockOffset)) {

+    *NumBytes = (UINT32) (LbaLength - BlockOffset);

+    Status    = EFI_BAD_BUFFER_SIZE;

+  }

+

+  CopyMem (Buffer, (UINT8 *) (LbaAddress + BlockOffset), (UINTN) (*NumBytes));

+

+  return Status;

+}

+

+EFI_STATUS

+FvbWriteBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Writes specified number of bytes from the input buffer to the block

+

+Arguments:

+  Instance              - The FV instance to be written to

+  Lba                   - The starting logical block index to write to

+  BlockOffset           - Offset into the block at which to begin writing

+  NumBytes              - Pointer that on input contains the total size of

+                          the buffer. On output, it contains the total number

+                          of bytes actually written

+  Buffer                - Pointer to a caller allocated buffer that contains

+                          the source for the write

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was written successfully

+  EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes

+                          actually written

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written

+  EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL

+

+--*/

+{

+  EFI_FVB_ATTRIBUTES  Attributes;

+  UINTN               LbaAddress;

+  UINTN               LbaLength;

+  EFI_STATUS          Status;

+

+  //

+  // Check for invalid conditions

+  //

+  if ((NumBytes == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (*NumBytes == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Check if the FV is write enabled

+  //

+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);

+

+  if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Perform boundary checks and adjust NumBytes

+  //

+  if (BlockOffset > LbaLength) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (LbaLength < (*NumBytes + BlockOffset)) {

+    *NumBytes = (UINT32) (LbaLength - BlockOffset);

+    Status    = EFI_BAD_BUFFER_SIZE;

+  }

+  //

+  // Write data

+  //

+  CopyMem ((UINT8 *) (LbaAddress + BlockOffset), Buffer, (UINTN) (*NumBytes));

+

+  return Status;

+}

+

+EFI_STATUS

+FvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a firmware volume block

+

+Arguments:

+  Instance              - The FV instance to be erased

+  Lba                   - The logical block index to be erased

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The erase request was successfully completed

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+

+  EFI_FVB_ATTRIBUTES  Attributes;

+  UINTN               LbaAddress;

+  UINTN               LbaLength;

+  EFI_STATUS          Status;

+  UINT8               Data;

+

+  //

+  // Check if the FV is write enabled

+  //

+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);

+

+  if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {

+    return EFI_ACCESS_DENIED;

+  }

+  //

+  // Get the starting address of the block for erase.

+  //

+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if ((Attributes & EFI_FVB_ERASE_POLARITY) != 0) {

+    Data = 0xFF;

+  } else {

+    Data = 0x0;

+  }

+

+  SetMem ((UINT8 *) LbaAddress, LbaLength, Data);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FvbEraseCustomBlockRange (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  Instance              - The FV instance to be erased

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetStartLba        - Offset into the last block at which to end erasing

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was erased successfully

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+  EFI_INVALID_PARAMETER - Instance not found

+

+--*/

+{

+  EFI_LBA Index;

+  UINTN   LbaSize;

+  UINTN   ScratchLbaSizeData;

+

+  //

+  // First LBA

+  //

+  FvbGetLbaAddress (Instance, StartLba, NULL, &LbaSize, NULL, Global, Virtual);

+

+  //

+  // Use the scratch space as the intermediate buffer to transfer data

+  // Back up the first LBA in scratch space.

+  //

+  FvbReadBlock (Instance, StartLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);

+

+  //

+  // erase now

+  //

+  FvbEraseBlock (Instance, StartLba, Global, Virtual);

+  ScratchLbaSizeData = OffsetStartLba;

+

+  //

+  // write the data back to the first block

+  //

+  if (ScratchLbaSizeData > 0) {

+    FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);

+  }

+  //

+  // Middle LBAs

+  //

+  if (LastLba > (StartLba + 1)) {

+    for (Index = (StartLba + 1); Index <= (LastLba - 1); Index++) {

+      FvbEraseBlock (Instance, Index, Global, Virtual);

+    }

+  }

+  //

+  // Last LBAs, the same as first LBAs

+  //

+  if (LastLba > StartLba) {

+    FvbGetLbaAddress (Instance, LastLba, NULL, &LbaSize, NULL, Global, Virtual);

+    FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);

+    FvbEraseBlock (Instance, LastLba, Global, Virtual);

+  }

+

+  ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);

+

+  return FvbWriteBlock (

+          Instance,

+          LastLba,

+          (OffsetLastLba + 1),

+          &ScratchLbaSizeData,

+          Global->FvbScratchSpace[Virtual],

+          Global,

+          Virtual

+          );

+}

+

+EFI_STATUS

+FvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN OUT EFI_FVB_ATTRIBUTES               *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+/*++

+

+Routine Description:

+  Modifies the current settings of the firmware volume according to the 

+  input parameter, and returns the new setting of the volume

+

+Arguments:

+  Instance              - The FV instance whose attributes is going to be 

+                          modified

+  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 

+                          containing the desired firmware volume settings.

+                          On successful return, it contains the new settings

+                          of the firmware volume

+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all

+                          instance data

+  Virtual               - Whether CPU is in virtual or physical mode

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+  EFI_ACCESS_DENIED     - The volume setting is locked and cannot be modified

+  EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are

+                          in conflict with the capabilities as declared in the

+                          firmware volume header

+

+--*/

+{

+  EFI_FW_VOL_INSTANCE *FwhInstance;

+  EFI_FVB_ATTRIBUTES  OldAttributes;

+  EFI_FVB_ATTRIBUTES  *AttribPtr;

+  UINT32              Capabilities;

+  UINT32              OldStatus;

+  UINT32              NewStatus;

+  EFI_STATUS          Status;

+

+  //

+  // Find the right instance of the FVB private data

+  //

+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);

+  ASSERT_EFI_ERROR (Status);

+

+  AttribPtr     = (EFI_FVB_ATTRIBUTES *) &(FwhInstance->VolumeHeader.Attributes);

+  OldAttributes = *AttribPtr;

+  Capabilities  = OldAttributes & EFI_FVB_CAPABILITIES;

+  OldStatus     = OldAttributes & EFI_FVB_STATUS;

+  NewStatus     = *Attributes & EFI_FVB_STATUS;

+

+  //

+  // If firmware volume is locked, no status bit can be updated

+  //

+  if (OldAttributes & EFI_FVB_LOCK_STATUS) {

+    if (OldStatus ^ NewStatus) {

+      return EFI_ACCESS_DENIED;

+    }

+  }

+  //

+  // Test read disable

+  //

+  if ((Capabilities & EFI_FVB_READ_DISABLED_CAP) == 0) {

+    if ((NewStatus & EFI_FVB_READ_STATUS) == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test read enable

+  //

+  if ((Capabilities & EFI_FVB_READ_ENABLED_CAP) == 0) {

+    if (NewStatus & EFI_FVB_READ_STATUS) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test write disable

+  //

+  if ((Capabilities & EFI_FVB_WRITE_DISABLED_CAP) == 0) {

+    if ((NewStatus & EFI_FVB_WRITE_STATUS) == 0) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test write enable

+  //

+  if ((Capabilities & EFI_FVB_WRITE_ENABLED_CAP) == 0) {

+    if (NewStatus & EFI_FVB_WRITE_STATUS) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Test lock

+  //

+  if ((Capabilities & EFI_FVB_LOCK_CAP) == 0) {

+    if (NewStatus & EFI_FVB_LOCK_STATUS) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  *AttribPtr  = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB_STATUS));

+  *AttribPtr  = (*AttribPtr) | NewStatus;

+  *Attributes = *AttribPtr;

+

+  return EFI_SUCCESS;

+}

+//

+// FVB protocol APIs

+//

+EFI_STATUS

+EFIAPI

+FvbProtocolGetPhysicalAddress (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the physical address of the device.

+

+Arguments:

+

+  This                  - Calling context

+  Address               - Output buffer containing the address.

+

+Returns:

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetBlockSize (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN  EFI_LBA                                     Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+/*++

+

+Routine Description:

+  Retrieve the size of a logical block

+

+Arguments:

+  This                  - Calling context

+  Lba                   - Indicates which block to return the size for.

+  BlockSize             - A pointer to a caller allocated UINTN in which

+                          the size of the block is returned

+  NumOfBlocks           - a pointer to a caller allocated UINTN in which the

+                          number of consecutive blocks starting with Lba is

+                          returned. All blocks in this range have a size of

+                          BlockSize

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbGetLbaAddress (

+          FvbDevice->Instance,

+          Lba,

+          NULL,

+          BlockSize,

+          NumOfBlocks,

+          mFvbModuleGlobal,

+          EfiGoneVirtual ()

+          );

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+/*++

+

+Routine Description:

+    Retrieves Volume attributes.  No polarity translations are done.

+

+Arguments:

+    This                - Calling context

+    Attributes          - output buffer which contains attributes

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolSetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN OUT EFI_FVB_ATTRIBUTES                       *Attributes

+  )

+/*++

+

+Routine Description:

+  Sets Volume attributes. No polarity translations are done.

+

+Arguments:

+  This                  - Calling context

+  Attributes            - output buffer which contains attributes

+

+Returns: 

+  EFI_SUCCESS           - Successfully returns

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolEraseBlocks (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  ...  

+  )

+/*++

+

+Routine Description:

+

+  The EraseBlock() function erases one or more blocks as denoted by the 

+  variable argument list. The entire parameter list of blocks must be verified

+  prior to erasing any blocks.  If a block is requested that does not exist 

+  within the associated firmware volume (it has a larger index than the last 

+  block of the firmware volume), the EraseBlock() function must return

+  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

+

+Arguments:

+  This                  - Calling context

+  ...                   - Starting LBA followed by Number of Lba to erase. 

+                          a -1 to terminate the list.

+

+Returns: 

+  EFI_SUCCESS           - The erase request was successfully completed

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+  EFI_FW_VOL_INSTANCE     *FwhInstance;

+  UINTN                   NumOfBlocks;

+  VA_LIST                 args;

+  EFI_LBA                 StartingLba;

+  UINTN                   NumOfLba;

+  EFI_STATUS              Status;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());

+  ASSERT_EFI_ERROR (Status);

+

+  NumOfBlocks = FwhInstance->NumOfBlocks;

+

+  VA_START (args, This);

+

+  do {

+    StartingLba = VA_ARG (args, EFI_LBA);

+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {

+      break;

+    }

+

+    NumOfLba = VA_ARG (args, UINT32);

+

+    //

+    // Check input parameters

+    //

+    if (NumOfLba == 0) {

+      VA_END (args);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if ((StartingLba + NumOfLba) > NumOfBlocks) {

+      return EFI_INVALID_PARAMETER;

+    }

+  } while (1);

+

+  VA_END (args);

+

+  VA_START (args, This);

+  do {

+    StartingLba = VA_ARG (args, EFI_LBA);

+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {

+      break;

+    }

+

+    NumOfLba = VA_ARG (args, UINT32);

+

+    while (NumOfLba > 0) {

+      Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());

+      if (EFI_ERROR (Status)) {

+        VA_END (args);

+        return Status;

+      }

+

+      StartingLba++;

+      NumOfLba--;

+    }

+

+  } while (1);

+

+  VA_END (args);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolWrite (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Writes data beginning at Lba:Offset from FV. The write terminates either

+  when *NumBytes of data have been written, or when a block boundary is

+  reached.  *NumBytes is updated to reflect the actual number of bytes

+  written. The write opertion does not include erase. This routine will

+  attempt to write only the specified bytes. If the writes do not stick,

+  it will return an error.

+

+Arguments:

+  This                  - Calling context

+  Lba                   - Block in which to begin write

+  Offset                - Offset in the block at which to begin write

+  NumBytes              - On input, indicates the requested write size. On

+                          output, indicates the actual number of bytes written

+  Buffer                - Buffer containing source data for the write.

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was written successfully

+  EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes

+                          actually written

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written

+  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL

+

+--*/

+{

+

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+

+EFI_STATUS

+EFIAPI

+FvbProtocolRead (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Reads data beginning at Lba:Offset from FV. The Read terminates either

+  when *NumBytes of data have been read, or when a block boundary is

+  reached.  *NumBytes is updated to reflect the actual number of bytes

+  written. The write opertion does not include erase. This routine will

+  attempt to write only the specified bytes. If the writes do not stick,

+  it will return an error.

+

+Arguments:

+  This                  - Calling context

+  Lba                   - Block in which to begin Read

+  Offset                - Offset in the block at which to begin Read

+  NumBytes              - On input, indicates the requested write size. On

+                          output, indicates the actual number of bytes Read

+  Buffer                - Buffer containing source data for the Read.

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was read successfully and 

+                          contents are in Buffer

+  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,

+                          NumBytes contains the total number of bytes returned

+                          in Buffer

+  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be read

+  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL

+

+--*/

+{

+

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_DEVICE_FROM_THIS (This);

+

+  return FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());

+}

+//

+// FVB Extension Protocols

+//

+EFI_STATUS

+EFIAPI

+FvbExtendProtocolEraseCustomBlockRange (

+  IN EFI_FVB_EXTENSION_PROTOCOL           *This,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+/*++

+

+Routine Description:

+  Erases and initializes a specified range of a firmware volume

+

+Arguments:

+  This                  - Calling context

+  StartLba              - The starting logical block index to be erased

+  OffsetStartLba        - Offset into the starting block at which to 

+                          begin erasing

+  LastLba               - The last logical block index to be erased

+  OffsetStartLba        - Offset into the last block at which to end erasing

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume was erased successfully

+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state

+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and 

+                          could not be written. Firmware device may have been

+                          partially erased

+

+--*/

+{

+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

+

+  FvbDevice = FVB_EXTEND_DEVICE_FROM_THIS (This);

+

+  return FvbEraseCustomBlockRange (

+          FvbDevice->Instance,

+          StartLba,

+          OffsetStartLba,

+          LastLba,

+          OffsetLastLba,

+          mFvbModuleGlobal,

+          EfiGoneVirtual ()

+          );

+}

+

+STATIC

+EFI_STATUS

+ValidateFvHeader (

+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader

+  )

+/*++

+

+Routine Description:

+  Check the integrity of firmware volume header

+

+Arguments:

+  FwVolHeader           - A pointer to a firmware volume header

+

+Returns: 

+  EFI_SUCCESS           - The firmware volume is consistent

+  EFI_NOT_FOUND         - The firmware volume has corrupted. So it is not an FV

+

+--*/

+{

+  UINT16  *Ptr;

+  UINT16  HeaderLength;

+  UINT16  Checksum;

+

+  //

+  // Verify the header revision, header signature, length

+  // Length of FvBlock cannot be 2**64-1

+  // HeaderLength cannot be an odd number

+  //

+  if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||

+      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||

+      (FwVolHeader->FvLength == ((UINTN) -1)) ||

+      ((FwVolHeader->HeaderLength & 0x01) != 0)

+      ) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Verify the header checksum

+  //

+  HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);

+  Ptr           = (UINT16 *) FwVolHeader;

+  Checksum      = 0;

+  while (HeaderLength > 0) {

+    Checksum = *Ptr++;

+    HeaderLength--;

+  }

+

+  if (Checksum != 0) {

+    return EFI_NOT_FOUND;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+FvbInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+/*++

+

+Routine Description:

+  This function does common initialization for FVB services

+

+Arguments:

+

+Returns:

+

+--*/

+{

+  EFI_STATUS                          Status;

+  EFI_FW_VOL_INSTANCE                 *FwhInstance;

+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;

+  EFI_DXE_SERVICES                    *DxeServices;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     Descriptor;

+  UINT32                              BufferSize;

+  EFI_FV_BLOCK_MAP_ENTRY              *PtrBlockMapEntry;

+  EFI_HANDLE                          FwbHandle;

+  EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *OldFwbInterface;

+  EFI_DEVICE_PATH_PROTOCOL            *TempFwbDevicePath;

+  FV_DEVICE_PATH                      TempFvbDevicePathData;

+  UINT32                              MaxLbaSize;

+  EFI_PHYSICAL_ADDRESS                BaseAddress;

+  UINT64                              Length;

+  UINTN                               NumOfBlocks;

+  EFI_PEI_HOB_POINTERS                FvHob;

+

+   //

+  // Get the DXE services table

+  //

+  DxeServices = gDS;

+

+  //

+  // Allocate runtime services data for global variable, which contains

+  // the private data of all firmware volume block instances

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  sizeof (ESAL_FWB_GLOBAL),

+                  &mFvbModuleGlobal

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Calculate the total size for all firmware volume block instances

+  //

+  BufferSize            = 0;

+

+  FvHob.Raw = GetHobList ();

+  while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {

+    BaseAddress = FvHob.FirmwareVolume->BaseAddress;

+    Length      = FvHob.FirmwareVolume->Length;

+    //

+    // Check if it is a "real" flash

+    //

+    Status = DxeServices->GetMemorySpaceDescriptor (

+                            BaseAddress,

+                            &Descriptor

+                            );

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {

+      FvHob.Raw = GET_NEXT_HOB (FvHob);

+      continue;

+    }

+

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;

+    Status      = ValidateFvHeader (FwVolHeader);

+    if (EFI_ERROR (Status)) {

+      //

+      // Get FvbInfo

+      //

+      Status = GetFvbInfo (Length, &FwVolHeader);

+      if (EFI_ERROR (Status)) {

+        FvHob.Raw = GET_NEXT_HOB (FvHob);

+        continue;

+      }

+    }

+

+    BufferSize += (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER));

+    FvHob.Raw = GET_NEXT_HOB (FvHob);

+  }

+

+  //

+  // Only need to allocate once. There is only one copy of physical memory for

+  // the private data of each FV instance. But in virtual mode or in physical

+  // mode, the address of the the physical memory may be different.

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  BufferSize,

+                  &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Make a virtual copy of the FvInstance pointer.

+  //

+  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];

+  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;

+

+  mFvbModuleGlobal->NumFv                   = 0;

+  MaxLbaSize = 0;

+

+  FvHob.Raw = GetHobList ();

+  while (NULL != (FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw))) {

+    BaseAddress = FvHob.FirmwareVolume->BaseAddress;

+    Length      = FvHob.FirmwareVolume->Length;

+    //

+    // Check if it is a "real" flash

+    //

+    Status = DxeServices->GetMemorySpaceDescriptor (

+                            BaseAddress,

+                            &Descriptor

+                            );

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {

+      FvHob.Raw = GET_NEXT_HOB (FvHob);

+      continue;

+    }

+

+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;

+    Status      = ValidateFvHeader (FwVolHeader);

+    if (EFI_ERROR (Status)) {

+      //

+      // Get FvbInfo to provide in FwhInstance.

+      //

+      Status = GetFvbInfo (Length, &FwVolHeader);

+      if (EFI_ERROR (Status)) {

+        FvHob.Raw = GET_NEXT_HOB (FvHob);

+        continue;

+      }

+      //

+      //  Write healthy FV header back.

+      //

+      CopyMem (

+        (VOID *) (UINTN) BaseAddress,

+        (VOID *) FwVolHeader,

+        FwVolHeader->HeaderLength

+        );

+    }

+

+    FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;

+    FwhInstance->FvBase[FVB_VIRTUAL]  = (UINTN) BaseAddress;

+

+    CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);

+    FwVolHeader = &(FwhInstance->VolumeHeader);

+    EfiInitializeLock (&(FwhInstance->FvbDevLock), EFI_TPL_HIGH_LEVEL);

+

+    NumOfBlocks = 0;

+

+    for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {

+      //

+      // Get the maximum size of a block. The size will be used to allocate

+      // buffer for Scratch space, the intermediate buffer for FVB extension

+      // protocol

+      //

+      if (MaxLbaSize < PtrBlockMapEntry->BlockLength) {

+        MaxLbaSize = PtrBlockMapEntry->BlockLength;

+      }

+

+      NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;

+    }

+    //

+    // The total number of blocks in the FV.

+    //

+    FwhInstance->NumOfBlocks = NumOfBlocks;

+

+    //

+    // Add a FVB Protocol Instance

+    //

+    Status = gBS->AllocatePool (

+                    EfiRuntimeServicesData,

+                    sizeof (EFI_FW_VOL_BLOCK_DEVICE),

+                    &FvbDevice

+                    );

+    ASSERT_EFI_ERROR (Status);

+

+    CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));

+

+    FvbDevice->Instance = mFvbModuleGlobal->NumFv;

+    mFvbModuleGlobal->NumFv++;

+

+    //

+    // Set up the devicepath

+    //

+    FvbDevice->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;

+    FvbDevice->DevicePath.MemMapDevPath.EndingAddress   = BaseAddress + (FwVolHeader->FvLength - 1);

+

+    //

+    // Find a handle with a matching device path that has supports FW Block protocol

+    //

+    TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData;

+    CopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH));

+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);

+    if (EFI_ERROR (Status)) {

+      //

+      // LocateDevicePath fails so install a new interface and device path

+      //

+      FwbHandle = NULL;

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &FwbHandle,

+                      &gEfiFirmwareVolumeBlockProtocolGuid,

+                      &FvbDevice->FwVolBlockInstance,

+                      &gEfiDevicePathProtocolGuid,

+                      &FvbDevice->DevicePath,

+                      NULL

+                      );

+      ASSERT_EFI_ERROR (Status);

+    } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {

+      //

+      // Device allready exists, so reinstall the FVB protocol

+      //

+      Status = gBS->HandleProtocol (

+                      FwbHandle,

+                      &gEfiFirmwareVolumeBlockProtocolGuid,

+                      &OldFwbInterface

+                      );

+      ASSERT_EFI_ERROR (Status);

+

+      Status = gBS->ReinstallProtocolInterface (

+                      FwbHandle,

+                      &gEfiFirmwareVolumeBlockProtocolGuid,

+                      OldFwbInterface,

+                      &FvbDevice->FwVolBlockInstance

+                      );

+      ASSERT_EFI_ERROR (Status);

+

+    } else {

+      //

+      // There was a FVB protocol on an End Device Path node

+      //

+      ASSERT (FALSE);

+    }

+    //

+    // Install FVB Extension Protocol on the same handle

+    //

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &FwbHandle,

+                    &gEfiFvbExtensionProtocolGuid,

+                    &FvbDevice->FvbExtension,

+                    &gEfiAlternateFvBlockGuid,

+                    NULL,

+                    NULL

+                    );

+

+    ASSERT_EFI_ERROR (Status);

+

+    FwhInstance = (EFI_FW_VOL_INSTANCE *)

+      (

+        (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +

+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))

+      );

+

+    FvHob.Raw = GET_NEXT_HOB (FvHob);

+  }

+

+  //

+  // Allocate for scratch space, an intermediate buffer for FVB extention

+  //

+  Status = gBS->AllocatePool (

+                  EfiRuntimeServicesData,

+                  MaxLbaSize,

+                  &mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FvbInfo.c b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FvbInfo.c
new file mode 100644
index 0000000..d079423
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FvbInfo.c
@@ -0,0 +1,125 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FvbInfo.c

+

+Abstract:

+

+  Defines data structure that is the volume header found.These data is intent

+  to decouple FVB driver with FV header.

+

+--*/

+

+#include "FlashLayout.h"

+

+#define FIRMWARE_BLOCK_SIZE 0x10000

+

+typedef struct {

+  UINT64                      FvLength;

+  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;

+  //

+  // EFI_FV_BLOCK_MAP_ENTRY    ExtraBlockMap[n];//n=0

+  //

+  EFI_FV_BLOCK_MAP_ENTRY      End[1];

+} EFI_FVB_MEDIA_INFO;

+

+#define FVB_MEDIA_BLOCK_SIZE    FIRMWARE_BLOCK_SIZE

+#define RECOVERY_BOIS_BLOCK_NUM FIRMWARE_BLOCK_NUMBER

+#define SYSTEM_NV_BLOCK_NUM     2

+

+EFI_FVB_MEDIA_INFO  mPlatformFvbMediaInfo[] = {

+  //

+  // Recovery BOIS FVB

+  //

+  {

+    EFI_WINNT_FIRMWARE_LENGTH,

+    {

+      {

+        0,

+      },  // ZeroVector[16]

+      EFI_FIRMWARE_FILE_SYSTEM_GUID,

+      FVB_MEDIA_BLOCK_SIZE * RECOVERY_BOIS_BLOCK_NUM,

+      EFI_FVH_SIGNATURE,

+      EFI_FVB_READ_ENABLED_CAP |

+        EFI_FVB_READ_STATUS |

+        EFI_FVB_WRITE_ENABLED_CAP |

+        EFI_FVB_WRITE_STATUS |

+        EFI_FVB_ERASE_POLARITY,

+      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),

+      0,  // CheckSum

+      {

+        0,

+      },  // Reserved[3]

+      1,  // Revision

+      {

+        RECOVERY_BOIS_BLOCK_NUM,

+        FVB_MEDIA_BLOCK_SIZE,

+      }

+    },

+    {

+      0,

+      0

+    }

+  },

+  //

+  // Systen NvStorage FVB

+  //

+  {

+    EFI_WINNT_RUNTIME_UPDATABLE_LENGTH + EFI_WINNT_FTW_SPARE_BLOCK_LENGTH,

+    {

+      {

+        0,

+      },  // ZeroVector[16]

+      EFI_SYSTEM_NV_DATA_HOB_GUID,

+      FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,

+      EFI_FVH_SIGNATURE,

+      EFI_FVB_READ_ENABLED_CAP |

+        EFI_FVB_READ_STATUS |

+        EFI_FVB_WRITE_ENABLED_CAP |

+        EFI_FVB_WRITE_STATUS |

+        EFI_FVB_ERASE_POLARITY,

+      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),

+      0,  // CheckSum

+      {

+        0,

+      },  // Reserved[3]

+      1,  // Revision

+      {

+        SYSTEM_NV_BLOCK_NUM,

+        FVB_MEDIA_BLOCK_SIZE,

+      }

+    },

+    {

+      0,

+      0

+    }

+  }

+};

+

+EFI_STATUS

+GetFvbInfo (

+  IN  UINT64                        FvLength,

+  OUT EFI_FIRMWARE_VOLUME_HEADER    **FvbInfo

+  )

+{

+  UINTN Index;

+

+  for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {

+    if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {

+      *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

diff --git a/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FwBlockService.h b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FwBlockService.h
new file mode 100644
index 0000000..6f949d3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/RuntimeDxe/FvbServices/nt32/FwBlockService.h
@@ -0,0 +1,238 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FwBlockService.h

+  

+Abstract:

+

+  Firmware volume block driver for Intel Firmware Hub (FWH) device

+

+--*/

+

+#ifndef _FW_BLOCK_SERVICE_H

+#define _FW_BLOCK_SERVICE_H

+

+//

+// BugBug: Add documentation here for data structure!!!!

+//

+#define FVB_PHYSICAL  0

+#define FVB_VIRTUAL   1

+

+typedef struct {

+  EFI_LOCK                    FvbDevLock;

+  UINTN                       FvBase[2];

+  UINTN                       NumOfBlocks;

+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;

+} EFI_FW_VOL_INSTANCE;

+

+typedef struct {

+  UINT32              NumFv;

+  EFI_FW_VOL_INSTANCE *FvInstance[2];

+  UINT8               *FvbScratchSpace[2];

+} ESAL_FWB_GLOBAL;

+

+//

+// Fvb Protocol instance data

+//

+#define FVB_DEVICE_FROM_THIS(a)         CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)

+#define FVB_EXTEND_DEVICE_FROM_THIS(a)  CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)

+#define FVB_DEVICE_SIGNATURE            EFI_SIGNATURE_32 ('F', 'V', 'B', 'N')

+

+typedef struct {

+  MEMMAP_DEVICE_PATH        MemMapDevPath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;

+} FV_DEVICE_PATH;

+

+typedef struct {

+  UINTN                               Signature;

+  FV_DEVICE_PATH                      DevicePath;

+  UINTN                               Instance;

+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance;

+  EFI_FVB_EXTENSION_PROTOCOL          FvbExtension;

+} EFI_FW_VOL_BLOCK_DEVICE;

+

+EFI_STATUS

+GetFvbInfo (

+  IN  UINT64                            FvLength,

+  OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo

+  )

+;

+

+EFI_STATUS

+FvbReadBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbWriteBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN UINTN                                BlockOffset,

+  IN OUT UINTN                            *NumBytes,

+  IN UINT8                                *Buffer,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbEraseBlock (

+  IN UINTN                                Instance,

+  IN EFI_LBA                              Lba,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbSetVolumeAttributes (

+  IN UINTN                                Instance,

+  IN OUT EFI_FVB_ATTRIBUTES               *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbGetVolumeAttributes (

+  IN UINTN                                Instance,

+  OUT EFI_FVB_ATTRIBUTES                  *Attributes,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+FvbGetPhysicalAddress (

+  IN UINTN                                Instance,

+  OUT EFI_PHYSICAL_ADDRESS                *Address,

+  IN ESAL_FWB_GLOBAL                      *Global,

+  IN BOOLEAN                              Virtual

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+;

+

+

+VOID

+EFIAPI

+FvbClassAddressChangeEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+;

+

+EFI_STATUS

+FvbGetLbaAddress (

+  IN  UINTN                               Instance,

+  IN  EFI_LBA                             Lba,

+  OUT UINTN                               *LbaAddress,

+  OUT UINTN                               *LbaLength,

+  OUT UINTN                               *NumOfBlocks,

+  IN  ESAL_FWB_GLOBAL                     *Global,

+  IN  BOOLEAN                             Virtual

+  )

+;

+

+//

+// Protocol APIs

+//

+EFI_STATUS

+EFIAPI

+FvbProtocolGetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolSetAttributes (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN OUT EFI_FVB_ATTRIBUTES                       *Attributes

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetPhysicalAddress (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolGetBlockSize (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN  EFI_LBA                                     Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumOfBlocks

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolRead (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolWrite (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbProtocolEraseBlocks (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,

+  ...

+  )

+;

+

+EFI_STATUS

+EFIAPI

+FvbExtendProtocolEraseCustomBlockRange (

+  IN EFI_FVB_EXTENSION_PROTOCOL           *This,

+  IN EFI_LBA                              StartLba,

+  IN UINTN                                OffsetStartLba,

+  IN EFI_LBA                              LastLba,

+  IN UINTN                                OffsetLastLba

+  )

+;

+

+#endif

diff --git a/edk2/EdkNt32Pkg/Sec/FwVol.c b/edk2/EdkNt32Pkg/Sec/FwVol.c
new file mode 100644
index 0000000..25ebe07
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/FwVol.c
@@ -0,0 +1,314 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  FwVol.c

+

+Abstract:

+  A simple FV stack so the SEC can extract the SEC Core from an

+  FV.

+

+--*/

+

+#include "SecMain.h"

+

+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \

+  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))

+

+EFI_FFS_FILE_STATE

+GetFileState (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+  Returns the highest bit set of the State field

+

+Arguments:

+  ErasePolarity   - Erase Polarity  as defined by EFI_FVB_ERASE_POLARITY

+                    in the Attributes field.

+  FfsHeader       - Pointer to FFS File Header.

+

+Returns:

+  Returns the highest bit in the State field

+

+--*/

+{

+  EFI_FFS_FILE_STATE  FileState;

+  EFI_FFS_FILE_STATE  HighestBit;

+

+  FileState = FfsHeader->State;

+

+  if (ErasePolarity != 0) {

+    FileState = (EFI_FFS_FILE_STATE)~FileState;

+  }

+

+  HighestBit = 0x80;

+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {

+    HighestBit >>= 1;

+  }

+

+  return HighestBit;

+}

+

+UINT8

+CalculateHeaderChecksum (

+  IN EFI_FFS_FILE_HEADER  *FileHeader

+  )

+/*++

+

+Routine Description:

+  Calculates the checksum of the header of a file.

+

+Arguments:

+  FileHeader       - Pointer to FFS File Header.

+

+Returns:

+  Checksum of the header.

+  

+--*/

+{

+  UINT8 *ptr;

+  UINTN Index;

+  UINT8 Sum;

+

+  Sum = 0;

+  ptr = (UINT8 *) FileHeader;

+

+  for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) {

+    Sum = (UINT8) (Sum + ptr[Index]);

+    Sum = (UINT8) (Sum + ptr[Index + 1]);

+    Sum = (UINT8) (Sum + ptr[Index + 2]);

+    Sum = (UINT8) (Sum + ptr[Index + 3]);

+  }

+

+  for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) {

+    Sum = (UINT8) (Sum + ptr[Index]);

+  }

+  //

+  // State field (since this indicates the different state of file).

+  //

+  Sum = (UINT8) (Sum - FileHeader->State);

+  //

+  // Checksum field of the file is not part of the header checksum.

+  //

+  Sum = (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File);

+

+  return Sum;

+}

+

+EFI_STATUS

+SecFfsFindNextFile (

+  IN EFI_FV_FILETYPE             SearchType,

+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching file in the

+    FFS volume as defined by SearchType. The search starts from FileHeader inside

+    the Firmware Volume defined by FwVolHeader.

+

+Arguments:

+    SearchType - Filter to find only files of this type.

+                 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.

+    FwVolHeader - Pointer to the FV header of the volume to search.

+                  This parameter must point to a valid FFS volume.

+    FileHeader  - Pointer to the current file from which to begin searching.

+                  This pointer will be updated upon return to reflect the file

+                  found.

+

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+{

+  EFI_FFS_FILE_HEADER *FfsFileHeader;

+  UINT32              FileLength;

+  UINT32              FileOccupiedSize;

+  UINT32              FileOffset;

+  UINT64              FvLength;

+  UINT8               ErasePolarity;

+  UINT8               FileState;

+

+  FvLength = FwVolHeader->FvLength;

+  if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {

+    ErasePolarity = 1;

+  } else {

+    ErasePolarity = 0;

+  }

+  //

+  // If FileHeader is not specified (NULL) start with the first file in the

+  // firmware volume.  Otherwise, start from the FileHeader.

+  //

+  if (*FileHeader == NULL) {

+    FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);

+  } else {

+    //

+    // Length is 24 bits wide so mask upper 8 bits

+    // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.

+    //

+    FileLength        = *(UINT32 *) (*FileHeader)->Size & 0x00FFFFFF;

+    FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);

+    FfsFileHeader     = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize);

+  }

+

+  FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader);

+

+  while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {

+    //

+    // Get FileState which is the highest bit of the State

+    //

+    FileState = GetFileState (ErasePolarity, FfsFileHeader);

+

+    switch (FileState) {

+

+    case EFI_FILE_HEADER_INVALID:

+      FileOffset += sizeof (EFI_FFS_FILE_HEADER);

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));

+      break;

+

+    case EFI_FILE_DATA_VALID:

+    case EFI_FILE_MARKED_FOR_UPDATE:

+      if (CalculateHeaderChecksum (FfsFileHeader) == 0) {

+        FileLength        = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;

+        FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);

+

+        if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {

+

+          *FileHeader = FfsFileHeader;

+

+          return EFI_SUCCESS;

+        }

+

+        FileOffset += FileOccupiedSize;

+        FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);

+      } else {

+        return EFI_NOT_FOUND;

+      }

+      break;

+

+    case EFI_FILE_DELETED:

+      FileLength        = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;

+      FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);

+      FileOffset += FileOccupiedSize;

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);

+      break;

+

+    default:

+      return EFI_NOT_FOUND;

+

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+SecFfsFindSectionData (

+  IN EFI_SECTION_TYPE      SectionType,

+  IN EFI_FFS_FILE_HEADER   *FfsFileHeader,

+  IN OUT VOID              **SectionData

+  )

+/*++

+

+Routine Description:

+    Given the input file pointer, search for the next matching section in the

+    FFS volume.

+

+Arguments:

+    SearchType    - Filter to find only sections of this type.

+    FfsFileHeader - Pointer to the current file to search.

+    SectionData   - Pointer to the Section matching SectionType in FfsFileHeader.

+                     NULL if section not found

+

+Returns:

+    EFI_NOT_FOUND - No files matching the search criteria were found

+    EFI_SUCCESS

+

+--*/

+{

+  UINT32                    FileSize;

+  EFI_COMMON_SECTION_HEADER *Section;

+  UINT32                    SectionLength;

+  UINT32                    ParsedLength;

+

+  //

+  // Size is 24 bits wide so mask upper 8 bits.

+  //    Does not include FfsFileHeader header size

+  // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.

+  //

+  Section   = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);

+  FileSize  = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;

+  FileSize -= sizeof (EFI_FFS_FILE_HEADER);

+

+  *SectionData  = NULL;

+  ParsedLength  = 0;

+  while (ParsedLength < FileSize) {

+    if (Section->Type == SectionType) {

+      *SectionData = (VOID *) (Section + 1);

+      return EFI_SUCCESS;

+    }

+    //

+    // Size is 24 bits wide so mask upper 8 bits.

+    // SectionLength is adjusted it is 4 byte aligned.

+    // Go to the next section

+    //

+    SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF;

+    SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);

+

+    ParsedLength += SectionLength;

+    Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+SecFfsFindPeiCore (

+  IN  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  OUT VOID                        **Pe32Data

+  )

+/*++

+

+Routine Description:

+  Given the pointer to the Firmware Volume Header find the SEC

+  core and return it's PE32 image.

+

+Arguments:

+  FwVolHeader - Pointer to memory mapped FV

+  Pe32Data - Pointer to SEC PE32 iamge.

+ 

+Returns:  

+  EFI_SUCCESS - Pe32Data is valid

+  other       - Failure

+

+--*/

+{

+  EFI_STATUS          Status;

+  EFI_FFS_FILE_HEADER *FileHeader;

+  EFI_FV_FILETYPE     SearchType;

+

+  SearchType  = EFI_FV_FILETYPE_PEI_CORE;

+  FileHeader  = NULL;

+  do {

+    Status = SecFfsFindNextFile (SearchType, FwVolHeader, &FileHeader);

+    if (!EFI_ERROR (Status)) {

+      Status = SecFfsFindSectionData (EFI_SECTION_PE32, FileHeader, Pe32Data);

+      return Status;

+    }

+  } while (!EFI_ERROR (Status));

+

+  return Status;

+}

diff --git a/edk2/EdkNt32Pkg/Sec/SecMain.c b/edk2/EdkNt32Pkg/Sec/SecMain.c
new file mode 100644
index 0000000..26f10c4
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/SecMain.c
@@ -0,0 +1,1169 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+

+  SecMain.c

+

+Abstract:

+  WinNt emulator of SEC phase. It's really a Win32 application, but this is

+  Ok since all the other modules for NT32 are NOT Win32 applications.

+

+  This program processes Windows environment variables and figures out

+  what the memory layout will be, how may FD's will be loaded and also

+  what the boot mode is.

+

+  The SEC registers a set of services with the SEC core. gPrivateDispatchTable

+  is a list of PPI's produced by the SEC that are availble for usage in PEI.

+

+  This code produces 128 K of temporary memory for the PEI stack by opening a

+  Windows file and mapping it directly to memory addresses.

+

+  The system.cmd script is used to set windows environment variables that drive

+  the configuration opitons of the SEC.

+

+--*/

+

+#include "SecMain.h"

+

+//

+// Globals

+//

+EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE  mPeiEfiPeiPeCoffLoaderInstance = {

+  {

+    SecNt32PeCoffGetImageInfo,

+    SecNt32PeCoffLoadImage,

+    SecNt32PeCoffRelocateImage,

+    SecNt32PeCoffUnloadimage

+  },

+  NULL

+};

+

+

+

+EFI_PEI_PE_COFF_LOADER_PROTOCOL           *gPeiEfiPeiPeCoffLoader = &mPeiEfiPeiPeCoffLoaderInstance.PeCoff;

+

+NT_PEI_LOAD_FILE_PPI                      mSecNtLoadFilePpi     = { SecWinNtPeiLoadFile };

+

+PEI_NT_AUTOSCAN_PPI                       mSecNtAutoScanPpi     = { SecWinNtPeiAutoScan };

+

+PEI_NT_THUNK_PPI                          mSecWinNtThunkPpi     = { SecWinNtWinNtThunkAddress };

+

+EFI_PEI_PROGRESS_CODE_PPI                 mSecStatusCodePpi     = { SecPeiReportStatusCode };

+

+NT_FWH_PPI                                mSecFwhInformationPpi = { SecWinNtFdAddress };

+

+

+EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI,

+    &gEfiPeiPeCoffLoaderGuid,

+    NULL

+  },

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI,

+    &gNtPeiLoadFilePpiGuid,

+    &mSecNtLoadFilePpi

+  },

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI,

+    &gPeiNtAutoScanPpiGuid,

+    &mSecNtAutoScanPpi

+  },

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI,

+    &gPeiNtThunkPpiGuid,

+    &mSecWinNtThunkPpi

+  },

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI,

+    &gEfiPeiStatusCodePpiGuid,

+    &mSecStatusCodePpi

+  },

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,

+    &gNtFwhPpiGuid,

+    &mSecFwhInformationPpi

+  }

+};

+

+

+//

+// Default information about where the FD is located.

+//  This array gets filled in with information from EFI_FIRMWARE_VOLUMES

+//  EFI_FIRMWARE_VOLUMES is a Windows environment variable set by system.cmd.

+//  The number of array elements is allocated base on parsing

+//  EFI_FIRMWARE_VOLUMES and the memory is never freed.

+//

+UINTN                                     gFdInfoCount = 0;

+NT_FD_INFO                                *gFdInfo;

+

+//

+// Array that supports seperate memory rantes.

+//  The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.

+//  The number of array elements is allocated base on parsing

+//  EFI_MEMORY_SIZE and the memory is never freed.

+//

+UINTN                                     gSystemMemoryCount = 0;

+NT_SYSTEM_MEMORY                          *gSystemMemory;

+

+

+UINTN                   mPdbNameModHandleArraySize = 0;

+PDB_NAME_TO_MOD_HANDLE  *mPdbNameModHandleArray = NULL;

+

+

+

+

+INTN

+EFIAPI

+main (

+  IN  INTN  Argc,

+  IN  CHAR8 **Argv,

+  IN  CHAR8 **Envp

+  )

+/*++

+

+Routine Description:

+  Main entry point to SEC for WinNt. This is a Windows program

+

+Arguments:

+  Argc - Number of command line arguments

+  Argv - Array of command line argument strings

+  Envp - Array of environmemt variable strings

+

+Returns:

+  0 - Normal exit

+  1 - Abnormal exit

+

+--*/

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  InitialStackMemory;

+  UINT64                InitialStackMemorySize;

+  UINTN                 Index;

+  UINTN                 Index1;

+  UINTN                 Index2;

+  UINTN                 PeiIndex;

+  CHAR16                *FileName;

+  CHAR16                *FileNamePtr;

+  BOOLEAN               Done;

+  VOID                  *PeiCoreFile;

+  CHAR16                *MemorySizeStr;

+  CHAR16                *FirmwareVolumesStr;

+

+  MemorySizeStr      = (CHAR16 *)PcdGetPtr (PcdWinNtMemorySizeForSecMain);

+  FirmwareVolumesStr = (CHAR16 *)PcdGetPtr (PcdWinNtFirmwareVolume);

+

+  printf ("\nEDK SEC Main NT Emulation Environment from www.TianoCore.org\n");

+

+  //

+  // Make some Windows calls to Set the process to the highest priority in the

+  //  idle class. We need this to have good performance.

+  //

+  SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);

+  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);

+

+  //

+  // Allocate space for gSystemMemory Array

+  //

+  gSystemMemoryCount  = CountSeperatorsInString (MemorySizeStr, '!') + 1;

+  gSystemMemory       = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));

+  if (gSystemMemory == NULL) {

+    printf ("ERROR : Can not allocate memory for %s.  Exiting.\n", MemorySizeStr);

+    exit (1);

+  }

+  //

+  // Allocate space for gSystemMemory Array

+  //

+  gFdInfoCount  = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;

+  gFdInfo       = calloc (gFdInfoCount, sizeof (NT_FD_INFO));

+  if (gFdInfo == NULL) {

+    printf ("ERROR : Can not allocate memory for %s.  Exiting.\n", FirmwareVolumesStr);

+    exit (1);

+  }

+  //

+  // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)

+  //

+  printf ("  BootMode 0x%02x\n", FixedPcdGet32 (PcdWinNtBootMode));

+

+  //

+  // Open up a 128K file to emulate temp memory for PEI.

+  //  on a real platform this would be SRAM, or using the cache as RAM.

+  //  Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping

+  //

+  InitialStackMemory      = 0;

+  InitialStackMemorySize  = 0x20000;

+  Status = WinNtOpenFile (

+            L"SecStack",

+            (UINT32) InitialStackMemorySize,

+            OPEN_ALWAYS,

+            &InitialStackMemory,

+            &InitialStackMemorySize

+            );

+  if (EFI_ERROR (Status)) {

+    printf ("ERROR : Can not open SecStack Exiting\n");

+    exit (1);

+  }

+

+  printf ("  SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);

+

+  //

+  // Open All the firmware volumes and remember the info in the gFdInfo global

+  //

+  FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16));

+  if (FileNamePtr == NULL) {

+    printf ("ERROR : Can not allocate memory for firmware volume string\n");

+    exit (1);

+  }

+

+  StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr);

+

+  for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL; !Done; Index++) {

+    FileName = FileNamePtr;

+    for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)

+      ;

+    if (FileNamePtr[Index1] == 0) {

+      Done = TRUE;

+    } else {

+      FileNamePtr[Index1]  = '\0';

+      FileNamePtr = FileNamePtr + Index1 + 1;

+    }

+

+    //

+    // Open the FD and remmeber where it got mapped into our processes address space

+    //

+    Status = WinNtOpenFile (

+              FileName,

+              0,

+              OPEN_EXISTING,

+              &gFdInfo[Index].Address,

+              &gFdInfo[Index].Size

+              );

+    if (EFI_ERROR (Status)) {

+      printf ("ERROR : Can not open Firmware Device File %S (%r).  Exiting.\n", FileName, Status);

+      exit (1);

+    }

+

+    printf ("  FD loaded from");

+    //

+    // printf can't print filenames directly as the \ gets interperted as an

+    //  escape character.

+    //

+    for (Index2 = 0; FileName[Index2] != '\0'; Index2++) {

+      printf ("%c", FileName[Index2]);

+    }

+

+    if (PeiCoreFile == NULL) {

+      //

+      // Assume the beginning of the FD is an FV and look for the PEI Core.

+      // Load the first one we find.

+      //

+      Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);

+      if (!EFI_ERROR (Status)) {

+        PeiIndex = Index;

+        printf (" contains SEC Core");

+      }

+    }

+

+    printf ("\n");

+  }

+  //

+  // Calculate memory regions and store the information in the gSystemMemory

+  //  global for later use. The autosizing code will use this data to

+  //  map this memory into the SEC process memory space.

+  //

+  for (Index = 0, Done = FALSE; !Done; Index++) {

+    //

+    // Save the size of the memory and make a Unicode filename SystemMemory00, ...

+    //

+    gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000;

+    _snwprintf (gSystemMemory[Index].FileName, NT_SYSTEM_MEMORY_FILENAME_SIZE, L"SystemMemory%02d", Index);

+

+    //

+    // Find the next region

+    //

+    for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)

+      ;

+    if (MemorySizeStr[Index1] == 0) {

+      Done = TRUE;

+    }

+

+    MemorySizeStr = MemorySizeStr + Index1 + 1;

+  }

+

+  printf ("\n");

+

+  //

+  // Hand off to PEI Core

+  //

+  SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);

+

+  //

+  // If we get here, then the PEI Core returned. This is an error as PEI should

+  //  always hand off to DXE.

+  //

+  printf ("ERROR : PEI Core returned\n");

+  exit (1);

+}

+

+EFI_STATUS

+WinNtOpenFile (

+  IN  CHAR16                    *FileName,

+  IN  UINT32                    MapSize,

+  IN  DWORD                     CreationDisposition,

+  IN OUT  EFI_PHYSICAL_ADDRESS  *BaseAddress,

+  OUT UINT64                    *Length

+  )

+/*++

+

+Routine Description:

+  Opens and memory maps a file using WinNt services. If BaseAddress is non zero

+  the process will try and allocate the memory starting at BaseAddress.

+

+Arguments:

+  FileName            - The name of the file to open and map

+  MapSize             - The amount of the file to map in bytes

+  CreationDisposition - The flags to pass to CreateFile().  Use to create new files for

+                        memory emulation, and exiting files for firmware volume emulation

+  BaseAddress         - The base address of the mapped file in the user address space.

+                         If passed in as NULL the a new memory region is used.

+                         If passed in as non NULL the request memory region is used for

+                          the mapping of the file into the process space.

+  Length              - The size of the mapped region in bytes

+

+Returns:

+  EFI_SUCCESS      - The file was opened and mapped.

+  EFI_NOT_FOUND    - FileName was not found in the current directory

+  EFI_DEVICE_ERROR - An error occured attempting to map the opened file

+

+--*/

+{

+  HANDLE  NtFileHandle;

+  HANDLE  NtMapHandle;

+  VOID    *VirtualAddress;

+  UINTN   FileSize;

+

+  //

+  // Use Win API to open/create a file

+  //

+  NtFileHandle = CreateFile (

+                  FileName,

+                  GENERIC_READ | GENERIC_WRITE,

+                  FILE_SHARE_READ,

+                  NULL,

+                  CreationDisposition,

+                  FILE_ATTRIBUTE_NORMAL,

+                  NULL

+                  );

+  if (NtFileHandle == INVALID_HANDLE_VALUE) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Map the open file into a memory range

+  //

+  NtMapHandle = CreateFileMapping (

+                  NtFileHandle,

+                  NULL,

+                  PAGE_READWRITE,

+                  0,

+                  MapSize,

+                  NULL

+                  );

+  if (NtMapHandle == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Get the virtual address (address in the emulator) of the mapped file

+  //

+  VirtualAddress = MapViewOfFileEx (

+                    NtMapHandle,

+                    FILE_MAP_ALL_ACCESS,

+                    0,

+                    0,

+                    MapSize,

+                    (LPVOID) (UINTN) *BaseAddress

+                    );

+  if (VirtualAddress == NULL) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  if (MapSize == 0) {

+    //

+    // Seek to the end of the file to figure out the true file size.

+    //

+    FileSize = SetFilePointer (

+                NtFileHandle,

+                0,

+                NULL,

+                FILE_END

+                );

+    if (FileSize == -1) {

+      return EFI_DEVICE_ERROR;

+    }

+

+    *Length = (UINT64) FileSize;

+  } else {

+    *Length = (UINT64) MapSize;

+  }

+

+  *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAddress;

+

+  return EFI_SUCCESS;

+}

+

+#define BYTES_PER_RECORD  512

+

+EFI_STATUS

+EFIAPI

+SecPeiReportStatusCode (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_STATUS_CODE_TYPE       CodeType,

+  IN EFI_STATUS_CODE_VALUE      Value,

+  IN UINT32                     Instance,

+  IN EFI_GUID                   * CallerId,

+  IN EFI_STATUS_CODE_DATA       * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  This routine produces the ReportStatusCode PEI service. It's passed

+  up to the PEI Core via a PPI. T

+

+  This code currently uses the NT clib printf. This does not work the same way

+  as the EFI Print (), as %t, %g, %s as Unicode are not supported.

+

+Arguments:

+  (see EFI_PEI_REPORT_STATUS_CODE)

+

+Returns:

+  EFI_SUCCESS - Always return success

+

+--*/

+// TODO:    PeiServices - add argument and description to function comment

+// TODO:    CodeType - add argument and description to function comment

+// TODO:    Value - add argument and description to function comment

+// TODO:    Instance - add argument and description to function comment

+// TODO:    CallerId - add argument and description to function comment

+// TODO:    Data - add argument and description to function comment

+{

+  CHAR8           *Format;

+  EFI_DEBUG_INFO  *DebugInfo;

+  VA_LIST         Marker;

+  CHAR8           PrintBuffer[BYTES_PER_RECORD * 2];

+  CHAR8           *Filename;

+  CHAR8           *Description;

+  UINT32          LineNumber;

+

+  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {

+    //

+    // This supports DEBUG () marcos

+    // Data format

+    //  EFI_STATUS_CODE_DATA

+    //  EFI_DEBUG_INFO

+    //

+    // The first 12 * UINT64 bytes of the string are really an

+    // arguement stack to support varargs on the Format string.

+    //

+    if (Data != NULL) {

+      DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);

+      Marker    = (VA_LIST) (DebugInfo + 1);

+      Format    = (CHAR8 *) (((UINT64 *) Marker) + 12);

+

+      AsciiVSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);

+      printf (PrintBuffer);

+    } else {

+      printf ("DEBUG <null>\n");

+    }

+  }

+

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&

+      ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)

+      ) {

+    if (Data != NULL && ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {

+      //

+      // Support ASSERT () macro

+      //

+      printf ("ASSERT %s(%d): %s\n", Filename, LineNumber, Description);

+    } else {

+      printf ("ASSERT <null>\n");

+    }

+    CpuBreakpoint ();

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+VOID

+SecLoadFromCore (

+  IN  UINTN   LargestRegion,

+  IN  UINTN   LargestRegionSize,

+  IN  UINTN   BootFirmwareVolumeBase,

+  IN  VOID    *PeiCorePe32File

+  )

+/*++

+

+Routine Description:

+  This is the service to load the PEI Core from the Firmware Volume

+

+Arguments:

+  LargestRegion           - Memory to use for PEI.

+  LargestRegionSize       - Size of Memory to use for PEI

+  BootFirmwareVolumeBase  - Start of the Boot FV

+  PeiCorePe32File         - PEI Core PE32

+

+Returns:

+  Success means control is transfered and thus we should never return

+

+--*/

+{

+  EFI_STATUS                  Status;

+  EFI_PHYSICAL_ADDRESS        TopOfMemory;

+  VOID                        *TopOfStack;

+  UINT64                      PeiCoreSize;

+  EFI_PHYSICAL_ADDRESS        PeiCoreEntryPoint;

+  EFI_PHYSICAL_ADDRESS        PeiImageAddress;

+  EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartup;

+

+  //

+  // Compute Top Of Memory for Stack and PEI Core Allocations

+  //

+  TopOfMemory = LargestRegion + ((LargestRegionSize) & (~15));

+

+  //

+  // Allocate 128KB for the Stack

+  //

+  TopOfStack  = (VOID *) (UINTN) (TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR));

+  TopOfMemory = TopOfMemory - STACK_SIZE;

+

+  //

+  // Patch value in dispatch table values

+  //

+  gPrivateDispatchTable[0].Ppi = gPeiEfiPeiPeCoffLoader;

+

+  //

+  // Bind this information into the SEC hand-off state

+  //

+  PeiStartup = (EFI_PEI_STARTUP_DESCRIPTOR *) (UINTN) TopOfStack;

+  PeiStartup->DispatchTable      = (EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable;

+  PeiStartup->SizeOfCacheAsRam   = STACK_SIZE;

+  PeiStartup->BootFirmwareVolume = BootFirmwareVolumeBase;

+

+  //

+  // Load the PEI Core from a Firmware Volume

+  //

+  Status = SecWinNtPeiLoadFile (

+            PeiCorePe32File,

+            &PeiImageAddress,

+            &PeiCoreSize,

+            &PeiCoreEntryPoint

+            );

+  if (EFI_ERROR (Status)) {

+    return ;

+  }

+  //

+  // Transfer control to the PEI Core

+  //

+  SwitchStack (

+    (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,

+    PeiStartup,

+    NULL,

+    TopOfStack

+    );

+  //

+  // If we get here, then the PEI Core returned.  This is an error

+  //

+  return ;

+}

+

+EFI_STATUS

+EFIAPI

+SecWinNtPeiAutoScan (

+  IN  UINTN                 Index,

+  OUT EFI_PHYSICAL_ADDRESS  *MemoryBase,

+  OUT UINT64                *MemorySize

+  )

+/*++

+

+Routine Description:

+  This service is called from Index == 0 until it returns EFI_UNSUPPORTED.

+  It allows discontiguous memory regions to be supported by the emulator.

+  It uses gSystemMemory[] and gSystemMemoryCount that were created by

+  parsing the Windows environment variable EFI_MEMORY_SIZE.

+  The size comes from the varaible and the address comes from the call to

+  WinNtOpenFile.

+

+Arguments:

+  Index      - Which memory region to use

+  MemoryBase - Return Base address of memory region

+  MemorySize - Return size in bytes of the memory region

+

+Returns:

+  EFI_SUCCESS - If memory region was mapped

+  EFI_UNSUPPORTED - If Index is not supported

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  if (Index >= gSystemMemoryCount) {

+    return EFI_UNSUPPORTED;

+  }

+

+  *MemoryBase = 0;

+  Status = WinNtOpenFile (

+            gSystemMemory[Index].FileName,

+            (UINT32) gSystemMemory[Index].Size,

+            OPEN_ALWAYS,

+            MemoryBase,

+            MemorySize

+            );

+

+  gSystemMemory[Index].Memory = *MemoryBase;

+

+  return Status;

+}

+

+VOID *

+EFIAPI

+SecWinNtWinNtThunkAddress (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Since the SEC is the only Windows program in stack it must export

+  an interface to do Win API calls. That's what the WinNtThunk address

+  is for. gWinNt is initailized in WinNtThunk.c.

+

+Arguments:

+  InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);

+  InterfaceBase - Address of the gWinNt global

+

+Returns:

+  EFI_SUCCESS - Data returned

+

+--*/

+{

+  return gWinNt;

+}

+

+

+EFI_STATUS

+EFIAPI

+SecWinNtPeiLoadFile (

+  IN  VOID                    *Pe32Data,

+  IN  EFI_PHYSICAL_ADDRESS    *ImageAddress,

+  IN  UINT64                  *ImageSize,

+  IN  EFI_PHYSICAL_ADDRESS    *EntryPoint

+  )

+/*++

+

+Routine Description:

+  Loads and relocates a PE/COFF image into memory.

+

+Arguments:

+  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated

+  ImageAddress     - The base address of the relocated PE/COFF image

+  ImageSize        - The size of the relocated PE/COFF image

+  EntryPoint       - The entry point of the relocated PE/COFF image

+

+Returns:

+  EFI_SUCCESS   - The file was loaded and relocated

+  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file

+

+--*/

+{

+  EFI_STATUS                            Status;

+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;

+

+  ZeroMem (&ImageContext, sizeof (ImageContext));

+  ImageContext.Handle     = Pe32Data;

+

+  ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) SecImageRead;

+

+  Status                  = gPeiEfiPeiPeCoffLoader->GetImageInfo (gPeiEfiPeiPeCoffLoader, &ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Allocate space in NT (not emulator) memory. Extra space is for alignment

+  //

+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) malloc ((UINTN) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)));

+  if (ImageContext.ImageAddress == 0) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Align buffer on section boundry

+  //

+  ImageContext.ImageAddress += ImageContext.SectionAlignment;

+  ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);

+

+  Status = gPeiEfiPeiPeCoffLoader->LoadImage (gPeiEfiPeiPeCoffLoader, &ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gPeiEfiPeiPeCoffLoader->RelocateImage (gPeiEfiPeiPeCoffLoader, &ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // BugBug: Flush Instruction Cache Here when CPU Lib is ready

+  //

+

+  *ImageAddress = ImageContext.ImageAddress;

+  *ImageSize    = ImageContext.ImageSize;

+  *EntryPoint   = ImageContext.EntryPoint;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+SecWinNtFdAddress (

+  IN     UINTN                 Index,

+  IN OUT EFI_PHYSICAL_ADDRESS  *FdBase,

+  IN OUT UINT64                *FdSize

+  )

+/*++

+

+Routine Description:

+  Return the FD Size and base address. Since the FD is loaded from a

+  file into Windows memory only the SEC will know it's address.

+

+Arguments:

+  Index  - Which FD, starts at zero.

+  FdSize - Size of the FD in bytes

+  FdBase - Start address of the FD. Assume it points to an FV Header

+

+Returns:

+  EFI_SUCCESS     - Return the Base address and size of the FV

+  EFI_UNSUPPORTED - Index does nto map to an FD in the system

+

+--*/

+{

+  if (Index >= gFdInfoCount) {

+    return EFI_UNSUPPORTED;

+  }

+

+  *FdBase = gFdInfo[Index].Address;

+  *FdSize = gFdInfo[Index].Size;

+

+  if (*FdBase == 0 && *FdSize == 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+SecImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

+

+Arguments:

+  FileHandle - The handle to the PE/COFF file

+  FileOffset - The offset, in bytes, into the file to read

+  ReadSize   - The number of bytes to read from the file starting at FileOffset

+  Buffer     - A pointer to the buffer to read the data into.

+

+Returns:

+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

+

+--*/

+{

+  CHAR8 *Destination8;

+  CHAR8 *Source8;

+  UINTN Length;

+

+  Destination8  = Buffer;

+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);

+  Length        = *ReadSize;

+  while (Length--) {

+    *(Destination8++) = *(Source8++);

+  }

+

+  return EFI_SUCCESS;

+}

+

+CHAR16 *

+AsciiToUnicode (

+  IN  CHAR8   *Ascii,

+  IN  UINTN   *StrLen OPTIONAL

+  )

+/*++

+

+Routine Description:

+  Convert the passed in Ascii string to Unicode.

+  Optionally return the length of the strings.

+

+Arguments:

+  Ascii   - Ascii string to convert

+  StrLen  - Length of string

+

+Returns:

+  Pointer to malloc'ed Unicode version of Ascii

+

+--*/

+{

+  UINTN   Index;

+  CHAR16  *Unicode;

+

+  //

+  // Allocate a buffer for unicode string

+  //

+  for (Index = 0; Ascii[Index] != '\0'; Index++)

+    ;

+  Unicode = malloc ((Index + 1) * sizeof (CHAR16));

+  if (Unicode == NULL) {

+    return NULL;

+  }

+

+  for (Index = 0; Ascii[Index] != '\0'; Index++) {

+    Unicode[Index] = (CHAR16) Ascii[Index];

+  }

+

+  Unicode[Index] = '\0';

+

+  if (StrLen != NULL) {

+    *StrLen = Index;

+  }

+

+  return Unicode;

+}

+

+UINTN

+CountSeperatorsInString (

+  IN  const CHAR16   *String,

+  IN  CHAR16         Seperator

+  )

+/*++

+

+Routine Description:

+  Count the number of seperators in String

+

+Arguments:

+  String    - String to process

+  Seperator - Item to count

+

+Returns:

+  Number of Seperator in String

+

+--*/

+{

+  UINTN Count;

+

+  for (Count = 0; *String != '\0'; String++) {

+    if (*String == Seperator) {

+      Count++;

+    }

+  }

+

+  return Count;

+}

+

+

+EFI_STATUS

+AddModHandle (

+  IN  PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext,

+  IN  VOID                                 *ModHandle

+  )

+/*++

+

+Routine Description:

+  Store the ModHandle in an array indexed by the Pdb File name.

+  The ModHandle is needed to unload the image. 

+

+Arguments:

+  ImageContext - Input data returned from PE Laoder Library. Used to find the 

+                 .PDB file name of the PE Image.

+  ModHandle    - Returned from LoadLibraryEx() and stored for call to 

+                 FreeLibrary().

+

+Returns:

+  EFI_SUCCESS - ModHandle was stored. 

+

+--*/

+{

+  UINTN                   Index;

+  PDB_NAME_TO_MOD_HANDLE  *Array;

+  UINTN                   PreviousSize;

+

+

+  Array = mPdbNameModHandleArray;

+  for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {

+    if (Array->PdbPointer == NULL) {

+      //

+      // Make a copy of the stirng and store the ModHandle

+      //

+      Array->PdbPointer = malloc (strlen (ImageContext->PdbPointer) + 1);

+      ASSERT (Array->PdbPointer != NULL);

+

+      strcpy (Array->PdbPointer, ImageContext->PdbPointer);

+      Array->ModHandle = ModHandle;

+      return EFI_SUCCESS;

+    }

+  }

+  

+  //

+  // No free space in mPdbNameModHandleArray so grow it by 

+  // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires. realloc will

+  // copy the old values to the new locaiton. But it does

+  // not zero the new memory area.

+  //

+  PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE);

+  mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE;

+

+  mPdbNameModHandleArray = realloc (mPdbNameModHandleArray, mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE));

+  if (mPdbNameModHandleArray == NULL) {

+    ASSERT (FALSE);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  memset (mPdbNameModHandleArray + PreviousSize, 0, MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (PDB_NAME_TO_MOD_HANDLE));

+ 

+  return AddModHandle (ImageContext, ModHandle);

+}

+

+

+VOID *

+RemoveModeHandle (

+  IN  PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+/*++

+

+Routine Description:

+  Return the ModHandle and delete the entry in the array.

+

+Arguments:

+  ImageContext - Input data returned from PE Laoder Library. Used to find the 

+                 .PDB file name of the PE Image.

+

+Returns:

+  ModHandle - ModHandle assoicated with ImageContext is returned

+  NULL      - No ModHandle associated with ImageContext

+

+--*/

+{

+  UINTN                   Index;

+  PDB_NAME_TO_MOD_HANDLE  *Array;

+

+  if (ImageContext->PdbPointer == NULL) {

+    //

+    // If no PDB pointer there is no ModHandle so return NULL

+    //

+    return NULL;

+  }

+

+  Array = mPdbNameModHandleArray;

+  for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {

+    if ((Array->PdbPointer != NULL) && (strcmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) {

+      //

+      // If you find a match return it and delete the entry

+      //

+      free (Array->PdbPointer);

+      Array->PdbPointer = NULL;

+      return Array->ModHandle;

+    }

+  }

+

+  return NULL;

+}

+

+

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffGetImageInfo (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = PeCoffLoaderGetImageInfo (ImageContext);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  switch (ImageContext->ImageType) {

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:

+    ImageContext->ImageCodeMemoryType = EfiLoaderCode;

+    ImageContext->ImageDataMemoryType = EfiLoaderData;

+    break;

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:

+    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;

+    ImageContext->ImageDataMemoryType = EfiBootServicesData;

+    break;

+

+  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:

+  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:

+    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;

+    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;

+    break;

+

+  default:

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+    return RETURN_UNSUPPORTED;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffLoadImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = PeCoffLoaderLoadImage (ImageContext);

+  return Status;

+}

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffRelocateImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  EFI_STATUS        Status;

+  VOID              *DllEntryPoint;

+  CHAR16            *DllFileName;

+  HMODULE           Library;

+  UINTN             Index;

+

+

+  Status = PeCoffLoaderRelocateImage (ImageContext);

+  if (EFI_ERROR (Status)) {

+    //

+    // We could not relocated the image in memory properly

+    //

+    return Status;

+  }

+

+  //

+  // If we load our own PE COFF images the Windows debugger can not source

+  //  level debug our code. If a valid PDB pointer exists usw it to load

+  //  the *.dll file as a library using Windows* APIs. This allows 

+  //  source level debug. The image is still loaded and reloaced

+  //  in the Framework memory space like on a real system (by the code above),

+  //  but the entry point points into the DLL loaded by the code bellow. 

+  //

+

+  DllEntryPoint = NULL;

+

+  //

+  // Load the DLL if it's not an EBC image.

+  //

+  if ((ImageContext->PdbPointer != NULL) &&

+      (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {

+    //

+    // Convert filename from ASCII to Unicode

+    //

+    DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index);

+

+    //

+    // Check that we have a valid filename

+    //

+    if (Index < 5 || DllFileName[Index - 4] != '.') {

+      free (DllFileName);

+

+      //

+      // Never return an error if PeCoffLoaderRelocateImage() succeeded.

+      // The image will run, but we just can't source level debug. If we

+      // return an error the image will not run.

+      //

+      return EFI_SUCCESS;

+    }

+    //

+    // Replace .PDB with .DLL on the filename

+    //

+    DllFileName[Index - 3]  = 'D';

+    DllFileName[Index - 2]  = 'L';

+    DllFileName[Index - 1]  = 'L';

+

+    //

+    // Load the .DLL file into the user process's address space for source 

+    // level debug

+    //

+    Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);

+    if (Library != NULL) {

+      //

+      // InitializeDriver is the entry point we put in all our EFI DLL's. The

+      // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() supresses the 

+      // normal DLL entry point of DllMain, and prevents other modules that are

+      // referenced in side the DllFileName from being loaded. There is no error 

+      // checking as the we can point to the PE32 image loaded by Tiano. This 

+      // step is only needed for source level debuging

+      //

+      DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver");

+

+    }

+

+    if ((Library != NULL) && (DllEntryPoint != NULL)) {

+      AddModHandle (ImageContext, Library);

+      ImageContext->EntryPoint  = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;

+      wprintf (L"LoadLibraryEx (%s,\n               NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName);

+    } else {

+      wprintf (L"WARNING: No source level debug %s. \n", DllFileName);

+    }

+

+    free (DllFileName);

+  }

+

+  //

+  // Never return an error if PeCoffLoaderRelocateImage() succeeded.

+  // The image will run, but we just can't source level debug. If we

+  // return an error the image will not run.

+  //

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffUnloadimage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,

+  IN PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  )

+{

+  VOID *ModHandle;

+

+  ModHandle = RemoveModeHandle (ImageContext);

+  if (ModHandle != NULL) {

+    FreeLibrary (ModHandle);

+  }

+  return EFI_SUCCESS;

+}

+

+VOID

+_ModuleEntryPoint (

+  VOID

+  )

+{

+}

diff --git a/edk2/EdkNt32Pkg/Sec/SecMain.h b/edk2/EdkNt32Pkg/Sec/SecMain.h
new file mode 100644
index 0000000..7943b83
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/SecMain.h
@@ -0,0 +1,570 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name:

+  SecMain.h

+

+Abstract:

+  Include file for Windows API based SEC

+

+--*/

+

+#include <stdio.h>

+

+

+#define STACK_SIZE                0x20000      

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  Address;

+  UINT64                Size;

+} NT_FD_INFO;

+

+#define NT_SYSTEM_MEMORY_FILENAME_SIZE  40

+

+typedef struct {

+  CHAR16                FileName[NT_SYSTEM_MEMORY_FILENAME_SIZE];

+  EFI_PHYSICAL_ADDRESS  Memory;

+  UINT64                Size;

+} NT_SYSTEM_MEMORY;

+

+

+#define MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE 0x100

+

+typedef struct {

+  CHAR8   *PdbPointer;

+  VOID    *ModHandle;

+} PDB_NAME_TO_MOD_HANDLE;

+

+

+

+

+EFI_STATUS

+EFIAPI

+SecWinNtPeiLoadFile (

+  VOID                  *Pe32Data,  // TODO: add IN/OUT modifier to Pe32Data

+  EFI_PHYSICAL_ADDRESS  *ImageAddress,  // TODO: add IN/OUT modifier to ImageAddress

+  UINT64                *ImageSize,  // TODO: add IN/OUT modifier to ImageSize

+  EFI_PHYSICAL_ADDRESS  *EntryPoint  // TODO: add IN/OUT modifier to EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Pe32Data      - TODO: add argument description

+  ImageAddress  - TODO: add argument description

+  ImageSize     - TODO: add argument description

+  EntryPoint    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecWinNtPeiAutoScan (

+  IN  UINTN                 Index,

+  OUT EFI_PHYSICAL_ADDRESS  *MemoryBase,

+  OUT UINT64                *MemorySize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Index       - TODO: add argument description

+  MemoryBase  - TODO: add argument description

+  MemorySize  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID *

+EFIAPI

+SecWinNtWinNtThunkAddress (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  InterfaceSize - TODO: add argument description

+  InterfaceBase - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecWinNtWinNtFwhAddress (

+  IN OUT UINT64                *FwhSize,

+  IN OUT EFI_PHYSICAL_ADDRESS  *FwhBase

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  FwhSize - TODO: add argument description

+  FwhBase - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecPeiReportStatusCode (

+  IN EFI_PEI_SERVICES         **PeiServices,

+  IN EFI_STATUS_CODE_TYPE     CodeType,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 * CallerId,

+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PeiServices - TODO: add argument description

+  CodeType    - TODO: add argument description

+  Value       - TODO: add argument description

+  Instance    - TODO: add argument description

+  CallerId    - TODO: add argument description

+  Data        - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+INTN

+EFIAPI

+main (

+  IN  INTN  Argc,

+  IN  CHAR8 **Argv,

+  IN  CHAR8 **Envp

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Argc  - TODO: add argument description

+  Argv  - TODO: add argument description

+  Envp  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+WinNtOpenFile (

+  CHAR16                *FileName,

+  UINT32                MapSize,

+  DWORD                 CreationDispostion,

+  EFI_PHYSICAL_ADDRESS  *BaseAddress,

+  UINT64                *Length

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  FileName            - TODO: add argument description

+  MapSize             - TODO: add argument description

+  CreationDispostion  - TODO: add argument description

+  BaseAddress         - TODO: add argument description

+  Length              - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+VOID

+SecLoadFromCore (

+  IN  UINTN   LargestRegion,

+  IN  UINTN   LargestRegionSize,

+  IN  UINTN   BootFirmwareVolumeBase,

+  IN  VOID    *PeiCoreFile

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  LargestRegion           - TODO: add argument description

+  LargestRegionSize       - TODO: add argument description

+  BootFirmwareVolumeBase  - TODO: add argument description

+  PeiCoreFile             - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SecLoadFile (

+  IN  VOID                    *Pe32Data,

+  IN  EFI_PHYSICAL_ADDRESS    *ImageAddress,

+  IN  UINT64                  *ImageSize,

+  IN  EFI_PHYSICAL_ADDRESS    *EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Pe32Data      - TODO: add argument description

+  ImageAddress  - TODO: add argument description

+  ImageSize     - TODO: add argument description

+  EntryPoint    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SecFfsFindPeiCore (

+  IN  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  OUT VOID                        **Pe32Data

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  FwVolHeader - TODO: add argument description

+  Pe32Data    - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SecFfsFindNextFile (

+  IN EFI_FV_FILETYPE             SearchType,

+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SearchType  - TODO: add argument description

+  FwVolHeader - TODO: add argument description

+  FileHeader  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+SecFfsFindSectionData (

+  IN EFI_SECTION_TYPE      SectionType,

+  IN EFI_FFS_FILE_HEADER   *FfsFileHeader,

+  IN OUT VOID              **SectionData

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  SectionType   - TODO: add argument description

+  FfsFileHeader - TODO: add argument description

+  SectionData   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecWinNtPeCoffLoaderLoadAsDll (

+  IN CHAR8    *PdbFileName,

+  IN VOID     **ImageEntryPoint,

+  OUT VOID    **ModHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  PdbFileName     - TODO: add argument description

+  ImageEntryPoint - TODO: add argument description

+  ModHandle       - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecWinNtPeCoffLoaderFreeLibrary (

+  OUT VOID    *ModHandle

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ModHandle - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecWinNtFdAddress (

+  IN     UINTN                 Index,

+  IN OUT EFI_PHYSICAL_ADDRESS  *FdBase,

+  IN OUT UINT64                *FdSize

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Index   - TODO: add argument description

+  FdBase  - TODO: add argument description

+  FdSize  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+GetImageReadFunction (

+  IN PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN EFI_PHYSICAL_ADDRESS                  *TopOfMemory

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  ImageContext  - TODO: add argument description

+  TopOfMemory   - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  FileHandle  - TODO: add argument description

+  FileOffset  - TODO: add argument description

+  ReadSize    - TODO: add argument description

+  Buffer      - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+CHAR16                            *

+AsciiToUnicode (

+  IN  CHAR8   *Ascii,

+  IN  UINTN   *StrLen OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  Ascii   - TODO: add argument description

+  StrLen  - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+UINTN

+CountSeperatorsInString (

+  IN  const CHAR16   *String,

+  IN  CHAR16   Seperator

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  String    - TODO: add argument description

+  Seperator - TODO: add argument description

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffGetImageInfo (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffLoadImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffRelocateImage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+EFI_STATUS

+EFIAPI

+SecNt32PeCoffUnloadimage (

+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,

+  IN PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext

+  );

+

+

+typedef struct {

+  EFI_PEI_PE_COFF_LOADER_PROTOCOL PeCoff;

+  VOID                            *ModHandle;

+} EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE;

+

+extern EFI_WIN_NT_THUNK_PROTOCOL  *gWinNt;

diff --git a/edk2/EdkNt32Pkg/Sec/SecMain.mbd b/edk2/EdkNt32Pkg/Sec/SecMain.mbd
new file mode 100644
index 0000000..f310571
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/SecMain.mbd
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>SecMain</BaseName>

+    <Guid>4b837b03-6587-4d19-b82b-edfad836c0a0</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdHeader>

+  <Libraries>

+    <Library>BaseLib</Library>

+    <Library>BaseMemoryLib</Library>

+    <Library>BasePeCoffLib</Library>

+    <Library>BasePrintLib</Library>

+    <Library>BaseReportStatusCodeLibNull</Library>

+    <Library>BaseDebugLibNull</Library>

+  </Libraries>

+</ModuleBuildDescription>

diff --git a/edk2/EdkNt32Pkg/Sec/SecMain.msa b/edk2/EdkNt32Pkg/Sec/SecMain.msa
new file mode 100644
index 0000000..158b75b
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/SecMain.msa
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>SecMain</BaseName>

+    <ModuleType>SEC</ModuleType>

+    <ComponentType>SEC</ComponentType>

+    <Guid>4b837b03-6587-4d19-b82b-edfad836c0a0</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for NT32 Sec.Warning the [sources.*] does not work like you think!If you add a file you need to update the makefile in the NT32 build tipSEC_OBJECTS needs to get the OBJ of the new C file added in.We keep [sources.*] synced up with SEC_OBJECTS so dependencies workproperly.Libraries.Common does not work you must update SEC_OBJECTS in the platformmakefile</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-14 17:04</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeCoffLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>SecMain.c</Filename>

+    <Filename>FwVol.c</Filename>

+    <Filename>WinNtThunk.c</Filename>

+    <Filename>SecMain.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+    <PackageName>EdkModulePkg</PackageName>

+    <PackageName>EdkNt32Pkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="ALWAYS_PRODUCED">NtThunk</Ppi>

+    <Ppi Usage="ALWAYS_PRODUCED">NtAutoScan</Ppi>

+    <Ppi Usage="ALWAYS_PRODUCED">NtFwh</Ppi>

+    <Ppi Usage="ALWAYS_PRODUCED">StatusCode</Ppi>

+    <Ppi Usage="ALWAYS_PRODUCED">NtPeiLoadFile</Ppi>

+  </PPIs>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_PRODUCED">

+      <C_Name>PeiPeCoffLoader</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdWinNtMemorySizeForSecMain</C_Name>

+      <Token>0x00001005</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdWinNtFirmwareVolume</C_Name>

+      <Token>0x00001009</Token>

+      <DatumType>VOID*</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdWinNtBootMode</C_Name>

+      <Token>0x00001006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+  <BuildOptions>

+    <Option>BUILD_TYPE=CUSTOM_BUILD</Option>

+  </BuildOptions>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkNt32Pkg/Sec/SecMain_build.xml b/edk2/EdkNt32Pkg/Sec/SecMain_build.xml
new file mode 100644
index 0000000..b0436d3
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/SecMain_build.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="SecMain" default="main" basedir="." >

+  <!-- Apply external ANT task -->

+  <taskdef resource="frameworktasks.tasks" /> 

+  <taskdef resource="cpptasks.tasks" /> 

+  <typedef resource="cpptasks.types" /> 

+  <taskdef resource="net/sf/antcontrib/antlib.xml" />

+  <property environment="env" />

+  <!-- All Properties --> 

+  <property name="BASE_NAME" value="SecMain" /> 

+  

+  <!-- Default target --> 

+  <target name="main" depends="libraries, sourcefiles, sections, output" /> 

+  <!-- Compile all dependency Library instances. --> 

+

+  <target name="libraries">

+    <ant antfile="${WORKSPACE_DIR}\MdePkg\Library\BaseLib\build.xml" inheritAll="false" target="BaseLib">

+      <property name="WORKSPACE_DIR" value="${WORKSPACE_DIR}" /> 

+      <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}\MdePkg/" /> 

+      <property name="ARCH" value="${ARCH}" /> 

+      <property name="TARGET" value="${TARGET}" /> 

+      <property name="PACKAGE" value="MdePkg" /> 

+    </ant>

+    <ant antfile="${WORKSPACE_DIR}\MdePkg\Library\BaseMemoryLib\build.xml" inheritAll="false" target="BaseMemoryLib">

+      <property name="WORKSPACE_DIR" value="${WORKSPACE_DIR}" /> 

+      <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}\MdePkg/" /> 

+      <property name="ARCH" value="${ARCH}" /> 

+      <property name="TARGET" value="${TARGET}" /> 

+      <property name="PACKAGE" value="MdePkg" /> 

+    </ant>

+    <ant antfile="${WORKSPACE_DIR}\MdePkg\Library\BasePrintLib\build.xml" inheritAll="false" target="BasePrintLib">

+      <property name="WORKSPACE_DIR" value="${WORKSPACE_DIR}" /> 

+      <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}\MdePkg/" /> 

+      <property name="ARCH" value="${ARCH}" /> 

+      <property name="TARGET" value="${TARGET}" /> 

+      <property name="PACKAGE" value="MdePkg" /> 

+    </ant>

+    <ant antfile="${WORKSPACE_DIR}\MdePkg\Library\BasePeCoffLib\build.xml" inheritAll="false" target="BasePeCoffLib">

+      <property name="WORKSPACE_DIR" value="${WORKSPACE_DIR}" /> 

+      <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}\MdePkg/" /> 

+      <property name="ARCH" value="${ARCH}" /> 

+      <property name="TARGET" value="${TARGET}" /> 

+      <property name="PACKAGE" value="MdePkg" /> 

+    </ant>

+    <ant antfile="${WORKSPACE_DIR}\MdePkg\Library\BaseReportStatusCodeLibNull\build.xml" inheritAll="false" target="BaseReportStatusCodeLibNull">

+      <property name="WORKSPACE_DIR" value="${WORKSPACE_DIR}" /> 

+      <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}\MdePkg/" /> 

+      <property name="ARCH" value="${ARCH}" /> 

+      <property name="TARGET" value="${TARGET}" /> 

+      <property name="PACKAGE" value="MdePkg" /> 

+    </ant>

+    <ant antfile="${WORKSPACE_DIR}\MdePkg\Library\BaseDebugLibNull\build.xml" inheritAll="false" target="BaseDebugLibNull">

+      <property name="WORKSPACE_DIR" value="${WORKSPACE_DIR}" /> 

+      <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}\MdePkg/" /> 

+      <property name="ARCH" value="${ARCH}" /> 

+      <property name="TARGET" value="${TARGET}" /> 

+      <property name="PACKAGE" value="MdePkg" /> 

+    </ant>

+    <Expand />

+  </target>

+  <target name="sourcefiles">

+      <Build_AUTOGEN FILENAME="AutoGen" FILEPATH=".">

+         <EXTRA.INC>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include\${ARCH}"/>

+            <includepath path="${DEST_DIR_DEBUG}"/>

+         </EXTRA.INC>

+       </Build_AUTOGEN>

+      <Build_C_Code FILENAME="FwVol" FILEPATH=".">

+         <EXTRA.INC>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include\${ARCH}"/>

+            <includepath path="${DEST_DIR_DEBUG}"/>

+         </EXTRA.INC>

+      </Build_C_Code>

+      <Build_C_Code FILENAME="WinNtThunk" FILEPATH=".">

+         <EXTRA.INC>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include\${ARCH}"/>

+            <includepath path="${DEST_DIR_DEBUG}"/>

+         </EXTRA.INC>

+      </Build_C_Code>

+      <Build_C_Code FILENAME="SecMain" FILEPATH=".">

+         <EXTRA.INC>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\MdePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkModulePkg\Include\${ARCH}"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include"/>

+            <includepath path="${WORKSPACE_DIR}\EdkNt32Pkg\Include\${ARCH}"/>

+            <includepath path="${DEST_DIR_DEBUG}"/>

+         </EXTRA.INC>

+      </Build_C_Code>

+    </target>

+    <target name="sections" />

+    <target name="output" >

+      <echo message="##Entering Output!" />

+      

+      <OnDependency>

+        <sourcefiles>

+          <file list="${OBJECTS}"/>

+          <file list="${LIBS}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${BIN_DIR}\SecMain.exe"/>

+        </targetfiles>

+        

+        <sequential>

+          <shellscript shell="cmd.exe" tmpsuffix=".cmd">

+            <arg line="/c"/>

+            <arg line="call"/>

+            "${LINK}" /LIBPATH:"${env.MSVCDir}\Lib" /LIBPATH:"${env.MSVCDir}\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MsvcRt.lib Gdi32.lib User32.lib Winmm.lib ${OBJECTS} ${LIBS} /base:0x10000000 /out:${BIN_DIR}\SecMain.exe /pdb:${DEST_DIR_DEBUG}\SecMain.pdb

+          </shellscript>

+        </sequential>

+      </OnDependency>

+      <!--      

+      <cc userdefine="on">

+        <command type="LINK">

+          <argument value="/LIBPATH:&quot;${env.MSVCDir}\Lib&quot; /LIBPATH:&quot;${env.MSVCDir}\PlatformSdk\Lib&quot;" />

+          <argument value="/NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG" />

+          <argument value="Kernel32.lib MsvcRt.lib Gdi32.lib User32.lib Winmm.lib" />

+          <argument value="${OBJECTS}" />

+          <argument value="${LIBS}" />

+          <argument value="/base:0x10000000 /out:${BIN_DIR}\SecMain.exe /pdb:${DEST_DIR_DEBUG}\SecMain.pdb" />

+      </command>

+    </cc>

+    -->

+  </target>

+  <target name="clean" ></target>

+

+  <target name="cleanAll"></target>

+</project>

diff --git a/edk2/EdkNt32Pkg/Sec/WinNtThunk.c b/edk2/EdkNt32Pkg/Sec/WinNtThunk.c
new file mode 100644
index 0000000..d064fae
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/WinNtThunk.c
@@ -0,0 +1,178 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  WinNtThunk.c

+

+Abstract:

+

+  Since the SEC is the only windows program in our emulation we 

+  must use a Tiano mechanism to export Win32 APIs to other modules.

+  This is the role of the EFI_WIN_NT_THUNK_PROTOCOL.

+

+  The mWinNtThunkTable exists so that a change to EFI_WIN_NT_THUNK_PROTOCOL

+  will cause an error in initializing the array if all the member functions

+  are not added. It looks like adding a element to end and not initializing

+  it may cause the table to be initaliized with the members at the end being

+  set to zero. This is bad as jumping to zero will case the NT32 to crash.

+  

+  All the member functions in mWinNtThunkTable are Win32

+  API calls, so please reference Microsoft documentation. 

+

+

+  gWinNt is a a public exported global that contains the initialized

+  data.

+

+--*/

+

+#include "SecMain.h"

+

+//

+// This pragma is needed for all the DLL entry points to be asigned to the array.

+//  if warning 4232 is not dissabled a warning will be generated as a DLL entry

+//  point could be modified dynamically. The SEC does not do that, so we must

+//  disable the warning so we can compile the SEC. The previous method was to

+//  asign each element in code. The disadvantage to that approach is it's harder

+//  to tell if all the elements have been initailized properly.

+//

+#pragma warning(disable : 4232)

+

+EFI_WIN_NT_THUNK_PROTOCOL mWinNtThunkTable = {

+  EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE,

+  GetProcAddress,

+  GetTickCount,

+  LoadLibraryEx,

+  FreeLibrary,

+  SetPriorityClass,

+  SetThreadPriority,

+  Sleep,

+  SuspendThread,

+  GetCurrentThread,

+  GetCurrentThreadId,

+  GetCurrentProcess,

+  CreateThread,

+  TerminateThread,

+  SendMessage,

+  ExitThread,

+  ResumeThread,

+  DuplicateHandle,

+  InitializeCriticalSection,

+  EnterCriticalSection,

+  LeaveCriticalSection,

+  DeleteCriticalSection,

+  TlsAlloc,

+  TlsFree,

+  TlsSetValue,

+  TlsGetValue,

+  CreateSemaphore,

+  WaitForSingleObject,

+  ReleaseSemaphore,

+  CreateConsoleScreenBuffer,

+  FillConsoleOutputAttribute,

+  FillConsoleOutputCharacter,

+  GetConsoleCursorInfo,

+  GetNumberOfConsoleInputEvents,

+  PeekConsoleInput,

+  ScrollConsoleScreenBuffer,

+  ReadConsoleInput,

+  SetConsoleActiveScreenBuffer,

+  SetConsoleCursorInfo,

+  SetConsoleCursorPosition,

+  SetConsoleScreenBufferSize,

+  SetConsoleTitleW,

+  WriteConsoleInput,

+  WriteConsoleOutput,

+  CreateFile,

+  DeviceIoControl,

+  CreateDirectory,

+  RemoveDirectory,

+  GetFileAttributes,

+  SetFileAttributes,

+  CreateFileMapping,

+  CloseHandle,

+  DeleteFile,

+  FindFirstFile,

+  FindNextFile,

+  FindClose,

+  FlushFileBuffers,

+  GetEnvironmentVariable,

+  GetLastError,

+  SetErrorMode,

+  GetStdHandle,

+  MapViewOfFileEx,

+  ReadFile,

+  SetEndOfFile,

+  SetFilePointer,

+  WriteFile,

+  GetFileInformationByHandle,

+  GetDiskFreeSpace,

+  GetDiskFreeSpaceEx,

+  MoveFile,

+  SetFileTime,

+  SystemTimeToFileTime,

+  FileTimeToLocalFileTime,

+  FileTimeToSystemTime,

+  GetSystemTime,

+  SetSystemTime,

+  GetLocalTime,

+  SetLocalTime,

+  GetTimeZoneInformation,

+  SetTimeZoneInformation,

+  timeSetEvent,

+  timeKillEvent,

+  ClearCommError,

+  EscapeCommFunction,

+  GetCommModemStatus,

+  GetCommState,

+  SetCommState,

+  PurgeComm,

+  SetCommTimeouts,

+  ExitProcess,

+  swprintf,

+  GetDesktopWindow,

+  GetForegroundWindow,

+  CreateWindowEx,

+  ShowWindow,

+  UpdateWindow,

+  DestroyWindow,

+  InvalidateRect,

+  GetWindowDC,

+  GetClientRect,

+  AdjustWindowRect,

+  SetDIBitsToDevice,

+  BitBlt,

+  GetDC,

+  ReleaseDC,

+  RegisterClassEx,

+  UnregisterClass,

+  BeginPaint,

+  EndPaint,

+  PostQuitMessage,

+  DefWindowProc,

+  LoadIcon,

+  LoadCursor,

+  GetStockObject,

+  SetViewportOrgEx,

+  SetWindowOrgEx,

+  MoveWindow,

+  GetWindowRect,

+  GetMessage,

+  TranslateMessage,

+  DispatchMessage,

+  GetProcessHeap,

+  HeapAlloc,

+  HeapFree

+};

+

+#pragma warning(default : 4232)

+

+EFI_WIN_NT_THUNK_PROTOCOL *gWinNt = &mWinNtThunkTable;

diff --git a/edk2/EdkNt32Pkg/Sec/build.xml b/edk2/EdkNt32Pkg/Sec/build.xml
new file mode 100644
index 0000000..4140a8a
--- /dev/null
+++ b/edk2/EdkNt32Pkg/Sec/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="SecMain"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Sec"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>

+   <target name="SecMain">

+      <GenBuild baseName="SecMain" mbdFilename="${MODULE_DIR}\SecMain.mbd" msaFilename="${MODULE_DIR}\SecMain.msa"/>

+   </target>

+   <target depends="SecMain_clean" name="clean"/>

+   <target depends="SecMain_cleanall" name="cleanall"/>

+   <target name="SecMain_clean">

+      <OutputDirSetup baseName="SecMain" mbdFilename="${MODULE_DIR}\SecMain.mbd" msaFilename="${MODULE_DIR}\SecMain.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\SecMain_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\SecMain_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="SecMain_cleanall">

+      <OutputDirSetup baseName="SecMain" mbdFilename="${MODULE_DIR}\SecMain.mbd" msaFilename="${MODULE_DIR}\SecMain.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}\SecMain_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}\SecMain_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**SecMain*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkNt32Pkg/build.xml b/edk2/EdkNt32Pkg/build.xml
new file mode 100644
index 0000000..d6ca4b8
--- /dev/null
+++ b/edk2/EdkNt32Pkg/build.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+ 

+<project default="buildfpd" basedir=".">

+  <!-- Apply external ANT tasks -->

+  <taskdef resource="net/sf/antcontrib/antlib.xml" />

+  <taskdef resource="GenBuild.tasks" />

+  

+  <property environment="env" />  

+  <property name="WORKSPACE_DIR" value="${env.WORKSPACE}" />

+  <property name="PLATFORM" value="NT32" />

+  <property name="PLATFORM_DIR" value="${WORKSPACE_DIR}\EdkNt32Pkg" />

+  <property name="BUILD_MODE" value="PLATFORM" />

+  <property name="COMMON_FILE" value="${PLATFORM_DIR}\Build\Nt32Common.xml" />  

+  

+  <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml" />

+  

+  <target name="buildfpd" depends="init, fpdparser, builds, fds" />

+  

+  <target name="init">

+    <if>

+      <not>

+        <isset property="env.WORKSPACE" />

+      </not>

+      <then>

+        <fail message="WORKSPACE environmental variable not set." />

+      </then>

+    </if>

+    <ToolChainSetup confPath="${WORKSPACE_DIR}\Tools\Conf" />

+  </target>

+

+  <target name="tools">

+    <ant antfile="${WORKSPACE_DIR}\Tools\Source\TianoTools\build.xml" />

+  </target>

+  

+  <target name="fpdparser" unless="FPD_File">

+    <FPDParser fpdfilename="Nt32.fpd" />

+  </target>

+  

+  <target name="builds" depends="fpdparser">

+    <ant antfile="${PLATFORM_DIR}\build.out.xml" />

+  </target>

+  

+  <target name="fds" depends="builds">

+    <concat destfile="${PLATFORM_DIR}\Build\FV\FV_RECOVERY.fd" binary="true" >

+      <fileset dir="${PLATFORM_DIR}\Build\FV" includes="*.fv" />

+    </concat>

+  </target>

+

+  <!-- this is only needed for Nt32 target exe generation --> 

+  <target name="run">

+    <if>

+      <available file="${WORKSPACE_DIR}\EdkNt32Pkg\Build\DEBUG\IA32\SecMain.exe" />

+      <then>

+        <shellscript shell="cmd.exe" tmpsuffix=".bat">

+          <arg value="/c"/>

+          <arg value="call"/>

+          cd ${WORKSPACE_DIR}\EdkNt32Pkg\Build\DEBUG\IA32

+          SecMain.exe

+        </shellscript>

+      </then>

+      <else>

+        <echo message="#################################################################"/>

+        <echo message="#################################################################"/>

+        <echo message="#"/>

+        <echo message="#  You must build the executable first, just type ant"/>

+        <echo message="#"/>

+        <echo message="#################################################################"/>

+        <echo message="#################################################################"/>

+      </else>

+    </if>

+  </target>

+

+  <!-- clean. -->

+  <target name="clean" depends="init">

+    <if>

+      <available file="${PLATFORM_DIR}\build.out.xml" />

+      <then>

+        <ant antfile="${PLATFORM_DIR}\build.out.xml" target="clean" />

+      </then>

+    </if>

+  </target>

+  

+  <!-- clean All. -->

+  <target name="cleanall" depends="init">

+    <if>

+      <available file="${PLATFORM_DIR}\build.out.xml" />

+      <then>

+        <ant antfile="${PLATFORM_DIR}\build.out.xml" target="cleanall" />

+        <delete file="${PLATFORM_DIR}\build.out.xml" />

+      </then>

+    </if>

+    <delete dir="${PLATFORM_DIR}\Build\FV" />

+  </target>

+  

+</project>

diff --git a/edk2/EdkNt32Pkg/genbuildfile.xml b/edk2/EdkNt32Pkg/genbuildfile.xml
new file mode 100644
index 0000000..77702ef
--- /dev/null
+++ b/edk2/EdkNt32Pkg/genbuildfile.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+ 

+<project default="workspace" basedir=".">

+  <taskdef resource="GenBuild.tasks" />

+  

+  <target name="workspace">

+    <bf recursive="true" />

+  </target>

+</project>

diff --git a/edk2/EdkNt32Pkg/run.cmd b/edk2/EdkNt32Pkg/run.cmd
new file mode 100644
index 0000000..167cfc9
--- /dev/null
+++ b/edk2/EdkNt32Pkg/run.cmd
@@ -0,0 +1,18 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@echo off

+pushd .

+cd Build\DEBUG\IA32

+SecMain.exe

+popd

+@echo on

+

diff --git a/edk2/EdkShellBinPkg/EdkShellBinPkg.spd b/edk2/EdkShellBinPkg/EdkShellBinPkg.spd
new file mode 100644
index 0000000..85c5004
--- /dev/null
+++ b/edk2/EdkShellBinPkg/EdkShellBinPkg.spd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <SpdHeader>

+    <PackageName>EdkShellBinPkg</PackageName>

+    <Guid>d4266a1b-1d38-4116-93ae-60dc3e2012a6</Guid>

+    <Version>0.3</Version>

+    <Abstract>Reference package showing multiple binaries</Abstract>

+    <Description>This package contains multiple binary drivers, using only one MSA, one MBD and a single SPD.</Description>

+    <Copyright>Copyright (c) 2006,  Intel Corporation.</Copyright>

+    <License>

+      All rights reserved.

+      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.

+    </License>

+    <Created>2006-03-05 10:13</Created>

+    <Updated>2006-03-18 20:23</Updated>

+    <URL>http://www.TianoCore.org</URL>

+    <PackageType>BINARY</PackageType>

+    <ReadOnly>true</ReadOnly>

+    <RePackage>false</RePackage>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </SpdHeader>

+  <MsaFiles>

+    <MsaFile>

+      <Filename>bin/Shell.msa</Filename>

+    </MsaFile>

+  </MsaFiles>

+</PackageSurfaceArea>

diff --git a/edk2/EdkShellBinPkg/bin/Shell.mbd b/edk2/EdkShellBinPkg/bin/Shell.mbd
new file mode 100644
index 0000000..ad7211e
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/Shell.mbd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdHeader>

+    <BaseName>Shell</BaseName>

+    <Guid>c57ad6b7-0515-40a8-9d21-551652854e37</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>

+		  This is a binary package containing multiple binary files, however there is

+			only a single MSA and MBD file.

+		

+</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 20:56</Created>

+  </MbdHeader>

+</ModuleBuildDescription>

diff --git a/edk2/EdkShellBinPkg/bin/Shell.msa b/edk2/EdkShellBinPkg/bin/Shell.msa
new file mode 100644
index 0000000..e997def
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/Shell.msa
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>Shell</BaseName>

+    <ModuleType>UEFI_APPLICATION</ModuleType>

+    <ComponentType>APPLICATION</ComponentType>

+    <Guid>c57ad6b7-0515-40a8-9d21-551652854e37</Guid>

+    <Version>0x00090000</Version>

+    <Abstract>Component description file for EFI Shell module.</Abstract>

+    <Description>

+		  This is a binary package containing multiple binary files, however there is

+			only a single MSA and MBD file.

+    </Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 20:56</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <SourceFiles>

+    <Filename Path="ia32" FileType="EFI">Shell_Full.efi</Filename>

+    <!--

+    <Arch ArchType="IA32">

+      <Filename Path="ia32" FileType="EFI">Shell_Full.efi</Filename>

+    </Arch>

+    -->

+    <Arch ArchType="IPF">

+      <Filename Path="ipf">Shell_Full.efi</Filename>

+    </Arch>

+  </SourceFiles>

+</ModuleSurfaceArea>

diff --git a/edk2/EdkShellBinPkg/bin/build.xml b/edk2/EdkShellBinPkg/bin/build.xml
new file mode 100644
index 0000000..fed916a
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="Shell"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="bin"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="Shell">

+      <GenBuild baseName="Shell" mbdFilename="${MODULE_DIR}/Shell.mbd" msaFilename="${MODULE_DIR}/Shell.msa"/>

+   </target>

+   <target depends="Shell_clean" name="clean"/>

+   <target depends="Shell_cleanall" name="cleanall"/>

+   <target name="Shell_clean">

+      <OutputDirSetup baseName="Shell" mbdFilename="${MODULE_DIR}/Shell.mbd" msaFilename="${MODULE_DIR}/Shell.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Shell_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Shell_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="Shell_cleanall">

+      <OutputDirSetup baseName="Shell" mbdFilename="${MODULE_DIR}/Shell.mbd" msaFilename="${MODULE_DIR}/Shell.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/Shell_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/Shell_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**Shell*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Attrib.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Attrib.efi
new file mode 100644
index 0000000..c3a45f2
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Attrib.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Cls.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Cls.efi
new file mode 100644
index 0000000..489a678
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Cls.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Cp.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Cp.efi
new file mode 100644
index 0000000..af8be91
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Cp.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Date.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Date.efi
new file mode 100644
index 0000000..ea0a802
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Date.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Dblk.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Dblk.efi
new file mode 100644
index 0000000..055dedf
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Dblk.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Devices.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Devices.efi
new file mode 100644
index 0000000..40af8f2
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Devices.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Devtree.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Devtree.efi
new file mode 100644
index 0000000..7ec5ad3
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Devtree.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Drivers.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Drivers.efi
new file mode 100644
index 0000000..5523691
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Drivers.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Drvcfg.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Drvcfg.efi
new file mode 100644
index 0000000..c3fba1f
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Drvcfg.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Drvdiag.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Drvdiag.efi
new file mode 100644
index 0000000..7ec7aeb
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Drvdiag.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Guid.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Guid.efi
new file mode 100644
index 0000000..00ec9a0
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Guid.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/IpConfig.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/IpConfig.efi
new file mode 100644
index 0000000..d121b0a
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/IpConfig.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Load.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Load.efi
new file mode 100644
index 0000000..0c1459f
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Load.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/LoadPciRom.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/LoadPciRom.efi
new file mode 100644
index 0000000..0a14c71
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/LoadPciRom.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Ls.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Ls.efi
new file mode 100644
index 0000000..606099b
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Ls.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Mkdir.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Mkdir.efi
new file mode 100644
index 0000000..79ddd6d
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Mkdir.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Mount.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Mount.efi
new file mode 100644
index 0000000..43e4c22
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Mount.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Mv.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Mv.efi
new file mode 100644
index 0000000..fa4b309
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Mv.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/NShell.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/NShell.efi
new file mode 100644
index 0000000..9d1b2d1
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/NShell.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Openinfo.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Openinfo.efi
new file mode 100644
index 0000000..b73b3e6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Openinfo.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Resets.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Resets.efi
new file mode 100644
index 0000000..ec6a92a
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Resets.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Rm.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Rm.efi
new file mode 100644
index 0000000..17fe4be
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Rm.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/SmbiosView.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/SmbiosView.efi
new file mode 100644
index 0000000..b571eee
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/SmbiosView.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/TelnetMgmt.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/TelnetMgmt.efi
new file mode 100644
index 0000000..9183f3b
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/TelnetMgmt.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Time.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Time.efi
new file mode 100644
index 0000000..2266815
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Time.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Touch.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Touch.efi
new file mode 100644
index 0000000..af485b3
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Touch.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Type.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Type.efi
new file mode 100644
index 0000000..1c73377
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Type.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Unload.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Unload.efi
new file mode 100644
index 0000000..6817348
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Unload.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Ver.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Ver.efi
new file mode 100644
index 0000000..c4f6bef
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Ver.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/Vol.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/Vol.efi
new file mode 100644
index 0000000..ed1272c
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/Vol.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/comp.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/comp.efi
new file mode 100644
index 0000000..a07d009
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/comp.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/dmem.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/dmem.efi
new file mode 100644
index 0000000..21fd2bd
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/dmem.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/dmpstore.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/dmpstore.efi
new file mode 100644
index 0000000..ff5d478
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/dmpstore.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/edit.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/edit.efi
new file mode 100644
index 0000000..d3bc52a
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/edit.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/eficompress.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/eficompress.efi
new file mode 100644
index 0000000..17dc9b3
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/eficompress.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/efidecompress.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/efidecompress.efi
new file mode 100644
index 0000000..8b51021
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/efidecompress.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/err.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/err.efi
new file mode 100644
index 0000000..ffc65b6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/err.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/hexedit.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/hexedit.efi
new file mode 100644
index 0000000..ca7d54d
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/hexedit.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/legacyboot.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/legacyboot.efi
new file mode 100644
index 0000000..98e49c3
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/legacyboot.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/loadfv.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/loadfv.efi
new file mode 100644
index 0000000..9c24b10
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/loadfv.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/mem.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/mem.efi
new file mode 100644
index 0000000..551ea79
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/mem.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/memmap.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/memmap.efi
new file mode 100644
index 0000000..e7ac7d5
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/memmap.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/mm.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/mm.efi
new file mode 100644
index 0000000..564ed82
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/mm.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/mode.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/mode.efi
new file mode 100644
index 0000000..004e0f4
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/mode.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/pci.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/pci.efi
new file mode 100644
index 0000000..e10e432
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/pci.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/sermode.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/sermode.efi
new file mode 100644
index 0000000..a2f66b4
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/sermode.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/stall.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/stall.efi
new file mode 100644
index 0000000..5884e51
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/stall.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Apps/timezone.efi b/edk2/EdkShellBinPkg/bin/ia32/Apps/timezone.efi
new file mode 100644
index 0000000..625b4fc
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Apps/timezone.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Shell.efi b/edk2/EdkShellBinPkg/bin/ia32/Shell.efi
new file mode 100644
index 0000000..a1aa709
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Shell.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ia32/Shell_Full.efi b/edk2/EdkShellBinPkg/bin/ia32/Shell_Full.efi
new file mode 100644
index 0000000..b908937
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ia32/Shell_Full.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Attrib.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Attrib.efi
new file mode 100644
index 0000000..589c2d8
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Attrib.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Cls.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Cls.efi
new file mode 100644
index 0000000..84f3401
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Cls.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Cp.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Cp.efi
new file mode 100644
index 0000000..3137ac6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Cp.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Date.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Date.efi
new file mode 100644
index 0000000..77631c6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Date.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Dblk.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Dblk.efi
new file mode 100644
index 0000000..553fce5
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Dblk.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Devices.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Devices.efi
new file mode 100644
index 0000000..840ab76
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Devices.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Devtree.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Devtree.efi
new file mode 100644
index 0000000..09e9d2b
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Devtree.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Drivers.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Drivers.efi
new file mode 100644
index 0000000..7b41202
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Drivers.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Drvcfg.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Drvcfg.efi
new file mode 100644
index 0000000..b50987f
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Drvcfg.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Drvdiag.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Drvdiag.efi
new file mode 100644
index 0000000..8ab4ee0
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Drvdiag.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Guid.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Guid.efi
new file mode 100644
index 0000000..cd72023
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Guid.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/IpConfig.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/IpConfig.efi
new file mode 100644
index 0000000..b421610
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/IpConfig.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Load.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Load.efi
new file mode 100644
index 0000000..ee5b2f9
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Load.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/LoadPciRom.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/LoadPciRom.efi
new file mode 100644
index 0000000..892787fd
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/LoadPciRom.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Ls.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Ls.efi
new file mode 100644
index 0000000..2c05194
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Ls.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Mkdir.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Mkdir.efi
new file mode 100644
index 0000000..f738570
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Mkdir.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Mount.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Mount.efi
new file mode 100644
index 0000000..a26a5cd
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Mount.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Mv.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Mv.efi
new file mode 100644
index 0000000..8410dca
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Mv.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/NShell.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/NShell.efi
new file mode 100644
index 0000000..a14252c
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/NShell.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Openinfo.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Openinfo.efi
new file mode 100644
index 0000000..3b44847
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Openinfo.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Resets.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Resets.efi
new file mode 100644
index 0000000..b2cd154
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Resets.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Rm.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Rm.efi
new file mode 100644
index 0000000..bba6bbc
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Rm.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/SmbiosView.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/SmbiosView.efi
new file mode 100644
index 0000000..95c7d9f
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/SmbiosView.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/TelnetMgmt.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/TelnetMgmt.efi
new file mode 100644
index 0000000..4c0158c
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/TelnetMgmt.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Time.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Time.efi
new file mode 100644
index 0000000..1944c91
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Time.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Touch.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Touch.efi
new file mode 100644
index 0000000..ed652a5
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Touch.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Type.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Type.efi
new file mode 100644
index 0000000..c7ad4ab
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Type.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Unload.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Unload.efi
new file mode 100644
index 0000000..03f637a
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Unload.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Ver.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Ver.efi
new file mode 100644
index 0000000..846421f
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Ver.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/Vol.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/Vol.efi
new file mode 100644
index 0000000..dfc3219
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/Vol.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/comp.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/comp.efi
new file mode 100644
index 0000000..49ef20e
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/comp.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/dmem.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/dmem.efi
new file mode 100644
index 0000000..1ec5813
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/dmem.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/dmpstore.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/dmpstore.efi
new file mode 100644
index 0000000..79ed4c4
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/dmpstore.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/edit.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/edit.efi
new file mode 100644
index 0000000..dd21c66
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/edit.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/eficompress.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/eficompress.efi
new file mode 100644
index 0000000..89328be
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/eficompress.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/efidecompress.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/efidecompress.efi
new file mode 100644
index 0000000..565cccc
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/efidecompress.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/err.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/err.efi
new file mode 100644
index 0000000..1b59ba6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/err.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/hexedit.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/hexedit.efi
new file mode 100644
index 0000000..d8001e3
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/hexedit.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/mem.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/mem.efi
new file mode 100644
index 0000000..5a3cc91
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/mem.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/memmap.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/memmap.efi
new file mode 100644
index 0000000..61fbe7e
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/memmap.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/mm.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/mm.efi
new file mode 100644
index 0000000..f0e06b6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/mm.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/mode.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/mode.efi
new file mode 100644
index 0000000..3ba30ca
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/mode.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/pci.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/pci.efi
new file mode 100644
index 0000000..9fe76ef
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/pci.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/sermode.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/sermode.efi
new file mode 100644
index 0000000..8e33a0d
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/sermode.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/stall.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/stall.efi
new file mode 100644
index 0000000..8a4202e
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/stall.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Apps/timezone.efi b/edk2/EdkShellBinPkg/bin/ipf/Apps/timezone.efi
new file mode 100644
index 0000000..d1cc96e
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Apps/timezone.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Shell.efi b/edk2/EdkShellBinPkg/bin/ipf/Shell.efi
new file mode 100644
index 0000000..b908937
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Shell.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/bin/ipf/Shell_Full.efi b/edk2/EdkShellBinPkg/bin/ipf/Shell_Full.efi
new file mode 100644
index 0000000..b4b6cc6
--- /dev/null
+++ b/edk2/EdkShellBinPkg/bin/ipf/Shell_Full.efi
Binary files differ
diff --git a/edk2/EdkShellBinPkg/genbuildfile.xml b/edk2/EdkShellBinPkg/genbuildfile.xml
new file mode 100644
index 0000000..81a2900
--- /dev/null
+++ b/edk2/EdkShellBinPkg/genbuildfile.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?> 

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="workspace" basedir=".">

+  <taskdef resource="GenBuild.tasks" />

+  

+  <target name="workspace">

+    <bf recursive="true" />

+  </target>

+</project>

diff --git a/edk2/MdePkg/Include/Base.h b/edk2/MdePkg/Include/Base.h
new file mode 100644
index 0000000..99ed686
--- /dev/null
+++ b/edk2/MdePkg/Include/Base.h
@@ -0,0 +1,28 @@
+/** @file

+

+  Root include file for Mde Package Base type modules

+

+  This is the include file for any module of type base. Base modules only use 

+  types defined via this include file and can be ported easily to any 

+  environment. There are a set of base libraries in the Mde Package that can

+  be used to implement base modules.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __BASE_H__

+#define __BASE_H__

+

+#include <Common/BaseTypes.h>

+#include <Common/EfiImage.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/BaseTypes.h b/edk2/MdePkg/Include/Common/BaseTypes.h
new file mode 100644
index 0000000..86c3c71
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/BaseTypes.h
@@ -0,0 +1,206 @@
+/** @file

+  Processor or Compiler specific defines for all supported processors.

+

+  This file is stand alone self consistent set of definitions. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BaseTypes.h

+

+**/

+

+#ifndef __BASE_TYPES_H__

+#define __BASE_TYPES_H__

+

+//

+// Include processor specific binding

+//

+#include <ProcessorBind.h>

+

+#define MEMORY_FENCE()  MemoryFence ()

+#define BREAKPOINT()    CpuBreakpoint ()

+#define DEADLOOP()      CpuDeadLoop ()

+

+typedef struct {

+  UINT32  Data1;

+  UINT16  Data2;

+  UINT16  Data3;

+  UINT8   Data4[8];

+} GUID;

+

+

+//

+// Modifiers to absract standard types to aid in debug of problems

+//

+#define CONST     const

+#define STATIC    static

+#define VOID      void

+

+//

+// Modifiers for Data Types used to self document code.

+// This concept is borrowed for UEFI specification.

+//

+#ifndef IN

+//

+// Some other envirnments use this construct, so #ifndef to prevent

+// mulitple definition.

+//

+#define IN

+#define OUT

+#define OPTIONAL

+#endif

+

+//

+// Constants. They may exist in other build structures, so #ifndef them.

+//

+#ifndef TRUE

+//

+// BugBug: UEFI specification claims 1 and 0. We are concerned about the 

+//  complier portability so we did it this way.

+//

+#define TRUE  ((BOOLEAN)(1==1))

+#endif

+

+#ifndef FALSE

+#define FALSE ((BOOLEAN)(0==1))

+#endif

+

+#ifndef NULL

+#define NULL  ((VOID *) 0)

+#endif

+

+//

+//  Support for variable length argument lists using the ANSI standard.

+//  

+//  Since we are using the ANSI standard we used the standard nameing and

+//  did not folow the coding convention

+//

+//  VA_LIST  - typedef for argument list.

+//  VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.

+//  VA_END (VA_LIST Marker) - Clear Marker

+//  VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argumnet from

+//    the ... list. You must know the size and pass it in this macro.

+//

+//  example:

+//

+//  UINTN

+//  ExampleVarArg (

+//    IN UINTN  NumberOfArgs,

+//    ...

+//    )

+//  {

+//    VA_LIST Marker;

+//    UINTN   Index;

+//    UINTN   Result;

+//

+//    //

+//    // Initialize the Marker

+//    //

+//    VA_START (Marker, NumberOfArgs);

+//    for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {

+//      //

+//      // The ... list is a series of UINTN values, so average them up.

+//      //

+//      Result += VA_ARG (Marker, UINTN);

+//    }

+//

+//    VA_END (Marker);

+//    return Result

+//  }

+//

+

+#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))

+

+//

+// Also support coding convention rules for var arg macros

+//

+#ifndef VA_START

+

+typedef CHAR8 *VA_LIST;

+#define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v))

+#define VA_ARG(ap, t)   (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t)))

+#define VA_END(ap)      (ap = (VA_LIST) 0)

+

+#endif

+

+///

+///  CONTAINING_RECORD - returns a pointer to the structure

+///      from one of it's elements.

+///

+#define _CR(Record, TYPE, Field)  ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))

+

+///

+///  ALIGN_POINTER - aligns a pointer to the lowest boundry

+///

+#define ALIGN_POINTER(p, s) ((VOID *) ((p) + (((s) - ((UINTN) (p))) & ((s) - 1))))

+

+///

+///  ALIGN_VARIABLE - aligns a variable up to the next natural boundry for int size of a processor

+///

+#define ALIGN_VARIABLE(Value, Adjustment) \

+  Adjustment = 0U; \

+  if ((UINTN) (Value) % sizeof (UINTN)) { \

+    (Adjustment) = (UINTN)(sizeof (UINTN) - ((UINTN) (Value) % sizeof (UINTN))); \

+  } \

+  (Value) = (UINTN)((UINTN) (Value) + (UINTN) (Adjustment))

+

+//

+// EFI Error Codes common to all execution phases

+//

+

+typedef INTN RETURN_STATUS;

+

+///

+/// Set the upper bit to indicate EFI Error.

+///

+#define ENCODE_ERROR(a)              (MAX_BIT | (a))

+

+#define ENCODE_WARNING(a)            (a)

+#define RETURN_ERROR(a)              ((a) < 0)

+

+#define RETURN_SUCCESS               0

+#define RETURN_LOAD_ERROR            ENCODE_ERROR (1)

+#define RETURN_INVALID_PARAMETER     ENCODE_ERROR (2)

+#define RETURN_UNSUPPORTED           ENCODE_ERROR (3)

+#define RETURN_BAD_BUFFER_SIZE       ENCODE_ERROR (4)

+#define RETURN_BUFFER_TOO_SMALL      ENCODE_ERROR (5)

+#define RETURN_NOT_READY             ENCODE_ERROR (6)

+#define RETURN_DEVICE_ERROR          ENCODE_ERROR (7)

+#define RETURN_WRITE_PROTECTED       ENCODE_ERROR (8)

+#define RETURN_OUT_OF_RESOURCES      ENCODE_ERROR (9)

+#define RETURN_VOLUME_CORRUPTED      ENCODE_ERROR (10)

+#define RETURN_VOLUME_FULL           ENCODE_ERROR (11)

+#define RETURN_NO_MEDIA              ENCODE_ERROR (12)

+#define RETURN_MEDIA_CHANGED         ENCODE_ERROR (13)

+#define RETURN_NOT_FOUND             ENCODE_ERROR (14)

+#define RETURN_ACCESS_DENIED         ENCODE_ERROR (15)

+#define RETURN_NO_RESPONSE           ENCODE_ERROR (16)

+#define RETURN_NO_MAPPING            ENCODE_ERROR (17)

+#define RETURN_TIMEOUT               ENCODE_ERROR (18)

+#define RETURN_NOT_STARTED           ENCODE_ERROR (19)

+#define RETURN_ALREADY_STARTED       ENCODE_ERROR (20)

+#define RETURN_ABORTED               ENCODE_ERROR (21)

+#define RETURN_ICMP_ERROR            ENCODE_ERROR (22)

+#define RETURN_TFTP_ERROR            ENCODE_ERROR (23)

+#define RETURN_PROTOCOL_ERROR        ENCODE_ERROR (24)

+#define RETURN_INCOMPATIBLE_VERSION  ENCODE_ERROR (25)

+#define RETURN_SECURITY_VIOLATION    ENCODE_ERROR (26)

+#define RETURN_CRC_ERROR             ENCODE_ERROR (27)

+#define RETURN_END_OF_MEDIA          ENCODE_ERROR (28)

+#define RETURN_END_OF_FILE           ENCODE_ERROR (31)

+

+#define RETURN_WARN_UNKNOWN_GLYPH    ENCODE_WARNING (1)

+#define RETURN_WARN_DELETE_FAILURE   ENCODE_WARNING (2)

+#define RETURN_WARN_WRITE_FAILURE    ENCODE_WARNING (3)

+#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4)

+

+typedef UINT64 PHYSICAL_ADDRESS;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/BootMode.h b/edk2/MdePkg/Include/Common/BootMode.h
new file mode 100644
index 0000000..2f2c516
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/BootMode.h
@@ -0,0 +1,37 @@
+/** @file

+  This includes for the Boot mode information.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BootMode.h

+

+  @par Revision Reference:

+  These definitions are from PeiCis 0.91 spec.

+

+**/

+

+#ifndef __EFI_BOOT_MODE_H__

+#define __EFI_BOOT_MODE_H__

+

+#define BOOT_WITH_FULL_CONFIGURATION                  0x00

+#define BOOT_WITH_MINIMAL_CONFIGURATION               0x01

+#define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES        0x02

+#define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03

+#define BOOT_WITH_DEFAULT_SETTINGS                    0x04

+#define BOOT_ON_S4_RESUME                             0x05

+#define BOOT_ON_S5_RESUME                             0x06

+#define BOOT_ON_S2_RESUME                             0x10

+#define BOOT_ON_S3_RESUME                             0x11

+#define BOOT_ON_FLASH_UPDATE                          0x12

+#define BOOT_IN_RECOVERY_MODE                         0x20

+#define BOOT_IN_RECOVERY_MODE_MASK                    0x40

+#define BOOT_SPECIAL_MASK                             0x80

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/BootScript.h b/edk2/MdePkg/Include/Common/BootScript.h
new file mode 100644
index 0000000..12bcc5b
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/BootScript.h
@@ -0,0 +1,198 @@
+/** @file

+  This file declares the related BootScript definitions and some SMBus definitions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BootScript.h

+

+  @par Revision Reference:

+  These definitions are defined in BootScript Spec 0.91 and SmBus PPI spec 0.9.

+

+**/

+

+#ifndef _EFI_SCRIPT_H_

+#define _EFI_SCRIPT_H_

+

+#define EFI_ACPI_S3_RESUME_SCRIPT_TABLE               0x00

+

+//

+// Boot Script Opcode Definitions

+//

+

+#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE               0x00

+#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE          0x01

+#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE              0x02

+#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE         0x03

+#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE       0x04

+#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE  0x05

+#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE          0x06

+#define EFI_BOOT_SCRIPT_STALL_OPCODE                  0x07

+#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE               0x08

+

+#define EFI_BOOT_SCRIPT_TABLE_OPCODE                  0xAA

+#define EFI_BOOT_SCRIPT_TERMINATE_OPCODE              0xFF

+

+//

+// EFI Boot Script Width

+//

+typedef enum {

+  EfiBootScriptWidthUint8,

+  EfiBootScriptWidthUint16,

+  EfiBootScriptWidthUint32,

+  EfiBootScriptWidthUint64,

+  EfiBootScriptWidthFifoUint8,

+  EfiBootScriptWidthFifoUint16,

+  EfiBootScriptWidthFifoUint32,

+  EfiBootScriptWidthFifoUint64,

+  EfiBootScriptWidthFillUint8,

+  EfiBootScriptWidthFillUint16,

+  EfiBootScriptWidthFillUint32,

+  EfiBootScriptWidthFillUint64,

+  EfiBootScriptWidthMaximum

+} EFI_BOOT_SCRIPT_WIDTH;

+

+//

+// EFI Smbus Device Address, Smbus Device Command, Smbus Operation

+//

+typedef struct {

+  UINTN SmbusDeviceAddress : 7;

+} EFI_SMBUS_DEVICE_ADDRESS;

+

+typedef UINTN EFI_SMBUS_DEVICE_COMMAND;

+

+typedef enum _EFI_SMBUS_OPERATION

+{

+  EfiSmbusQuickRead,

+  EfiSmbusQuickWrite,

+  EfiSmbusReceiveByte,

+  EfiSmbusSendByte,

+  EfiSmbusReadByte,

+  EfiSmbusWriteByte,

+  EfiSmbusReadWord,

+  EfiSmbusWriteWord,

+  EfiSmbusReadBlock,

+  EfiSmbusWriteBlock,

+  EfiSmbusProcessCall,

+  EfiSmbusBWBRProcessCall

+} EFI_SMBUS_OPERATION;

+

+//

+// Boot Script Opcode Header Structure Definitions

+//

+

+typedef struct {

+  UINT16  OpCode;

+  UINT8   Length;

+} EFI_BOOT_SCRIPT_GENERIC_HEADER;

+

+typedef struct {

+  UINT16  OpCode;

+  UINT8   Length;

+  UINT16  Version;

+  UINT32  TableLength;

+  UINT16  Reserved[2];

+} EFI_BOOT_SCRIPT_TABLE_HEADER;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+} EFI_BOOT_SCRIPT_COMMON_HEADER;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+  UINTN                 Count;

+  UINT64                Address;

+} EFI_BOOT_SCRIPT_IO_WRITE;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+  UINT64                Address;

+} EFI_BOOT_SCRIPT_IO_READ_WRITE;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+  UINTN                 Count;

+  UINT64                Address;

+} EFI_BOOT_SCRIPT_MEM_WRITE;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+  UINT64                Address;

+} EFI_BOOT_SCRIPT_MEM_READ_WRITE;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+  UINTN                 Count;

+  UINT64                Address;

+} EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_BOOT_SCRIPT_WIDTH Width;

+  UINT64                Address;

+} EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE;

+

+typedef struct {

+  UINT16                    OpCode;

+  UINT8                     Length;

+  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;

+  EFI_SMBUS_DEVICE_COMMAND  Command;

+  EFI_SMBUS_OPERATION       Operation;

+  BOOLEAN                   PecCheck;

+  UINTN                     DataSize;

+} EFI_BOOT_SCRIPT_SMBUS_EXECUTE;

+

+typedef struct {

+  UINT16  OpCode;

+  UINT8   Length;

+  UINTN   Duration;

+} EFI_BOOT_SCRIPT_STALL;

+

+typedef struct {

+  UINT16                OpCode;

+  UINT8                 Length;

+  EFI_PHYSICAL_ADDRESS  EntryPoint;

+} EFI_BOOT_SCRIPT_DISPATCH;

+

+typedef struct {

+  UINT16  OpCode;

+  UINT8   Length;

+} EFI_BOOT_SCRIPT_TERMINATE;

+

+typedef union {

+  EFI_BOOT_SCRIPT_GENERIC_HEADER        *Header;

+  EFI_BOOT_SCRIPT_TABLE_HEADER          *TableInfo;

+  EFI_BOOT_SCRIPT_IO_WRITE              *IoWrite;

+  EFI_BOOT_SCRIPT_IO_READ_WRITE         *IoReadWrite;

+  EFI_BOOT_SCRIPT_MEM_WRITE             *MemWrite;

+  EFI_BOOT_SCRIPT_MEM_READ_WRITE        *MemReadWrite;

+  EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE      *PciWrite;

+  EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE *PciReadWrite;

+  EFI_BOOT_SCRIPT_SMBUS_EXECUTE         *SmbusExecute;

+  EFI_BOOT_SCRIPT_STALL                 *Stall;

+  EFI_BOOT_SCRIPT_DISPATCH              *Dispatch;

+  EFI_BOOT_SCRIPT_TERMINATE             *Terminate;

+  EFI_BOOT_SCRIPT_COMMON_HEADER         *CommonHeader;

+  UINT8                                 *Raw;

+} BOOT_SCRIPT_POINTERS;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/Capsule.h b/edk2/MdePkg/Include/Common/Capsule.h
new file mode 100644
index 0000000..0434fdf
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/Capsule.h
@@ -0,0 +1,67 @@
+/** @file

+  Defines for the EFI Capsule functionality.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Capsule.h

+

+  @par Revision Reference:

+  These definitions are from Capsule Spec Version 0.9.

+

+**/

+

+#ifndef _EFI_CAPSULE_H_

+#define _EFI_CAPSULE_H_

+

+//

+// Bits in the flags field of the capsule header

+//

+#define EFI_CAPSULE_HEADER_FLAG_SETUP 0x00000001  // supports setup changes

+

+

+#define CAPSULE_BLOCK_DESCRIPTOR_SIGNATURE  EFI_SIGNATURE_32 ('C', 'B', 'D', 'S')

+

+//

+// An array of these describe the blocks that make up a capsule for

+// a capsule update.

+//

+typedef struct {

+  UINT64                Length;     // length of the data block

+  EFI_PHYSICAL_ADDRESS  Data;       // physical address of the data block

+  UINT32                Signature;  // CBDS

+  UINT32                CheckSum;   // to sum this structure to 0

+} EFI_CAPSULE_BLOCK_DESCRIPTOR;

+

+typedef struct {

+  EFI_GUID  OemGuid;

+  UINT32    HeaderSize;

+  //

+  // UINT8                       OemHdrData[];

+  //

+} EFI_CAPSULE_OEM_HEADER;

+

+typedef struct {

+  EFI_GUID  CapsuleGuid;

+  UINT32    HeaderSize;

+  UINT32    Flags;

+  UINT32    CapsuleImageSize;

+  UINT32    SequenceNumber;

+  EFI_GUID  InstanceId;

+  UINT32    OffsetToSplitInformation;

+  UINT32    OffsetToCapsuleBody;

+  UINT32    OffsetToOemDefinedHeader;

+  UINT32    OffsetToAuthorInformation;

+  UINT32    OffsetToRevisionInformation;

+  UINT32    OffsetToShortDescription;

+  UINT32    OffsetToLongDescription;

+  UINT32    OffsetToApplicableDevices;

+} EFI_CAPSULE_HEADER;

+

+#endif // #ifndef _EFI_CAPSULE_H_

diff --git a/edk2/MdePkg/Include/Common/DataHubRecords.h b/edk2/MdePkg/Include/Common/DataHubRecords.h
new file mode 100644
index 0000000..0bc8f23
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/DataHubRecords.h
@@ -0,0 +1,1847 @@
+/** @file

+  This file defines GUIDs and associated data structures for records 

+  posted to the Data Hub. 

+  The producers of these records use these definitions to construct 

+  records.

+  The consumers of these records use these definitions to retrieve,

+  filter and parse records.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DataHubRecords.h

+

+  @par Revision Reference:

+  DataHubRecord.h include all data hub sub class defitions from Cache subclass 

+  spec 0.9, DataHub SubClass spec 0.9, Memory SubClass Spec 0.9, Processor 

+  Subclass spec 0.9,Misc SubClass spec 0.9.

+

+**/

+

+#ifndef _DATAHUB_RECORDS_H_

+#define _DATAHUB_RECORDS_H_

+

+#define EFI_PROCESSOR_SUBCLASS_VERSION    0x00010000

+

+

+#pragma pack(1)

+

+typedef struct _USB_PORT_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} USB_PORT_DEVICE_PATH;

+

+//

+// IDE

+//

+typedef struct _IDE_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} IDE_DEVICE_PATH;

+

+//

+// RMC Connector

+//

+typedef struct _RMC_CONN_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} RMC_CONN_DEVICE_PATH;

+

+//

+// RIDE

+//

+typedef struct _RIDE_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} RIDE_DEVICE_PATH;

+

+//

+// Gigabit NIC

+//

+typedef struct _GB_NIC_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           PciBridgeDevicePath;

+  PCI_DEVICE_PATH           PciXBridgeDevicePath;

+  PCI_DEVICE_PATH           PciXBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} GB_NIC_DEVICE_PATH;

+

+//

+// P/S2 Connector

+//

+typedef struct _PS2_CONN_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH      LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} PS2_CONN_DEVICE_PATH;

+

+//

+// Serial Port Connector

+//

+typedef struct _SERIAL_CONN_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH      LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} SERIAL_CONN_DEVICE_PATH;

+

+//

+// Parallel Port Connector

+//

+typedef struct _PARALLEL_CONN_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH      LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} PARALLEL_CONN_DEVICE_PATH;

+

+//

+// Floopy Connector

+//

+typedef struct _FLOOPY_CONN_DEVICE_PATH {

+  ACPI_HID_DEVICE_PATH      PciRootBridgeDevicePath;

+  PCI_DEVICE_PATH           LpcBridgeDevicePath;

+  ACPI_HID_DEVICE_PATH      LpcBusDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;

+} FLOOPY_CONN_DEVICE_PATH;

+

+typedef union _EFI_MISC_PORT_DEVICE_PATH {

+  USB_PORT_DEVICE_PATH      UsbDevicePath;

+  IDE_DEVICE_PATH           IdeDevicePath;

+  RMC_CONN_DEVICE_PATH      RmcConnDevicePath;

+  RIDE_DEVICE_PATH          RideDevicePath;

+  GB_NIC_DEVICE_PATH        GbNicDevicePath;

+  PS2_CONN_DEVICE_PATH      Ps2ConnDevicePath;

+  SERIAL_CONN_DEVICE_PATH   SerialConnDevicePath;

+  PARALLEL_CONN_DEVICE_PATH ParallelConnDevicePath;

+  FLOOPY_CONN_DEVICE_PATH   FloppyConnDevicePath;

+} EFI_MISC_PORT_DEVICE_PATH;

+

+#pragma pack()

+

+//

+// String Token Definition

+//

+#define EFI_STRING_TOKEN    UINT16

+

+typedef struct {

+  UINT32    Version;

+  UINT32    HeaderSize;

+  UINT16    Instance;

+  UINT16    SubInstance;

+  UINT32    RecordType;    

+} EFI_SUBCLASS_TYPE1_HEADER;

+

+typedef struct {

+  EFI_GUID    ProducerName;

+  UINT16      Instance;

+  UINT16      SubInstance;

+} EFI_INTER_LINK_DATA;

+

+

+//

+// EXP data

+//

+

+typedef struct {

+  UINT16    Value;

+  UINT16    Exponent;

+} EFI_EXP_BASE2_DATA;

+

+

+typedef EFI_EXP_BASE10_DATA   EFI_PROCESSOR_MAX_CORE_FREQUENCY_DATA;

+

+typedef EFI_EXP_BASE10_DATA   EFI_PROCESSOR_MAX_FSB_FREQUENCY_DATA;

+

+typedef EFI_EXP_BASE10_DATA   EFI_PROCESSOR_CORE_FREQUENCY_DATA;

+

+typedef EFI_EXP_BASE10_DATA  *EFI_PROCESSOR_CORE_FREQUENCY_LIST_DATA;

+

+typedef EFI_EXP_BASE10_DATA  *EFI_PROCESSOR_FSB_FREQUENCY_LIST_DATA;

+

+typedef EFI_EXP_BASE10_DATA   EFI_PROCESSOR_FSB_FREQUENCY_DATA;

+

+typedef STRING_REF            EFI_PROCESSOR_VERSION_DATA;

+

+typedef STRING_REF            EFI_PROCESSOR_MANUFACTURER_DATA;

+

+typedef STRING_REF            EFI_PROCESSOR_SERIAL_NUMBER_DATA;

+

+typedef STRING_REF            EFI_PROCESSOR_ASSET_TAG_DATA;

+

+typedef struct {

+  UINT32  ProcessorSteppingId:4;

+  UINT32  ProcessorModel:     4;

+  UINT32  ProcessorFamily:    4;

+  UINT32  ProcessorType:      2;

+  UINT32  ProcessorReserved1: 2;

+  UINT32  ProcessorXModel:    4;

+  UINT32  ProcessorXFamily:   8;

+  UINT32  ProcessorReserved2: 4;

+} EFI_PROCESSOR_SIGNATURE;

+

+typedef struct {

+  UINT32  ProcessorBrandIndex :8;

+  UINT32  ProcessorClflush    :8;

+  UINT32  ProcessorReserved   :8;

+  UINT32  ProcessorDfltApicId :8;

+} EFI_PROCESSOR_MISC_INFO;

+

+typedef struct {

+  UINT32  ProcessorFpu:       1;

+  UINT32  ProcessorVme:       1;

+  UINT32  ProcessorDe:        1;

+  UINT32  ProcessorPse:       1;

+  UINT32  ProcessorTsc:       1;

+  UINT32  ProcessorMsr:       1;

+  UINT32  ProcessorPae:       1;

+  UINT32  ProcessorMce:       1;

+  UINT32  ProcessorCx8:       1;

+  UINT32  ProcessorApic:      1;

+  UINT32  ProcessorReserved1: 1;

+  UINT32  ProcessorSep:       1;

+  UINT32  ProcessorMtrr:      1;

+  UINT32  ProcessorPge:       1;

+  UINT32  ProcessorMca:       1;

+  UINT32  ProcessorCmov:      1;

+  UINT32  ProcessorPat:       1;

+  UINT32  ProcessorPse36:     1;

+  UINT32  ProcessorPsn:       1;

+  UINT32  ProcessorClfsh:     1;

+  UINT32  ProcessorReserved2: 1;

+  UINT32  ProcessorDs:        1;

+  UINT32  ProcessorAcpi:      1;

+  UINT32  ProcessorMmx:       1;

+  UINT32  ProcessorFxsr:      1;

+  UINT32  ProcessorSse:       1;

+  UINT32  ProcessorSse2:      1;

+  UINT32  ProcessorSs:        1;

+  UINT32  ProcessorReserved3: 1;

+  UINT32  ProcessorTm:        1;

+  UINT32  ProcessorReserved4: 2;

+} EFI_PROCESSOR_FEATURE_FLAGS;

+

+typedef struct {

+  EFI_PROCESSOR_SIGNATURE     Signature;

+  EFI_PROCESSOR_MISC_INFO     MiscInfo;

+  UINT32                      Reserved;

+  EFI_PROCESSOR_FEATURE_FLAGS FeatureFlags;

+} EFI_PROCESSOR_ID_DATA;

+

+typedef enum {

+  EfiProcessorOther    = 1,

+  EfiProcessorUnknown  = 2,

+  EfiCentralProcessor  = 3,

+  EfiMathProcessor     = 4,

+  EfiDspProcessor      = 5,

+  EfiVideoProcessor    = 6

+} EFI_PROCESSOR_TYPE_DATA;

+

+typedef enum {

+  EfiProcessorFamilyOther               = 1,

+  EfiProcessorFamilyUnknown             = 2,

+  EfiProcessorFamily8086                = 3,

+  EfiProcessorFamily80286               = 4,

+  EfiProcessorFamilyIntel386            = 5,

+  EfiProcessorFamilyIntel486            = 6,

+  EfiProcessorFamily8087                = 7,

+  EfiProcessorFamily80287               = 8,

+  EfiProcessorFamily80387               = 9,

+  EfiProcessorFamily80487               = 0x0A,

+  EfiProcessorFamilyPentium             = 0x0B,

+  EfiProcessorFamilyPentiumPro          = 0x0C,

+  EfiProcessorFamilyPentiumII           = 0x0D,

+  EfiProcessorFamilyPentiumMMX          = 0x0E,

+  EfiProcessorFamilyCeleron             = 0x0F,

+  EfiProcessorFamilyPentiumIIXeon       = 0x10,

+  EfiProcessorFamilyPentiumIII          = 0x11,

+  EfiProcessorFamilyM1                  = 0x12,

+  EfiProcessorFamilyM1Reserved1         = 0x13,

+  EfiProcessorFamilyM1Reserved2         = 0x14,

+  EfiProcessorFamilyM1Reserved3         = 0x15,

+  EfiProcessorFamilyM1Reserved4         = 0x16,

+  EfiProcessorFamilyM1Reserved5         = 0x17,

+  EfiProcessorFamilyM1Reserved6         = 0x18,

+  EfiProcessorFamilyK5                  = 0x19,

+  EfiProcessorFamilyK5Reserved1         = 0x1A,

+  EfiProcessorFamilyK5Reserved2         = 0x1B,

+  EfiProcessorFamilyK5Reserved3         = 0x1C,

+  EfiProcessorFamilyK5Reserved4         = 0x1D,

+  EfiProcessorFamilyK5Reserved5         = 0x1E,

+  EfiProcessorFamilyK5Reserved6         = 0x1F,

+  EfiProcessorFamilyPowerPC             = 0x20,

+  EfiProcessorFamilyPowerPC601          = 0x21,

+  EfiProcessorFamilyPowerPC603          = 0x22,

+  EfiProcessorFamilyPowerPC603Plus      = 0x23,

+  EfiProcessorFamilyPowerPC604          = 0x24,

+  EfiProcessorFamilyAlpha2              = 0x30,

+  EfiProcessorFamilyMips                = 0x40,

+  EfiProcessorFamilySparc               = 0x50,

+  EfiProcessorFamily68040               = 0x60,

+  EfiProcessorFamily68xxx               = 0x61,

+  EfiProcessorFamily68000               = 0x62,

+  EfiProcessorFamily68010               = 0x63,

+  EfiProcessorFamily68020               = 0x64,

+  EfiProcessorFamily68030               = 0x65,

+  EfiProcessorFamilyHobbit              = 0x70,

+  EfiProcessorFamilyWeitek              = 0x80,

+  EfiProcessorFamilyPARISC              = 0x90,

+  EfiProcessorFamilyV30                 = 0xA0,

+  EfiProcessorFamilyPentiumIIIXeon      = 0xB0,

+  EfiProcessorFamilyPentiumIIISpeedStep = 0xB1,

+  EfiProcessorFamilyPentium4            = 0xB2,

+  EfiProcessorFamilyIntelXeon           = 0xB3,

+  EfiProcessorFamilyAS400               = 0xB4,

+  EfiProcessorFamilyIntelXeonMP         = 0xB5,

+  EfiProcessorFamilyAMDAthlonXP         = 0xB6,

+  EfiProcessorFamilyAMDAthlonMP         = 0xB7,

+  EfiProcessorFamilyIBM390              = 0xC8,

+  EfiProcessorFamilyG4                  = 0xC9,

+  EfiProcessorFamilyG5                  = 0xCA,

+  EfiProcessorFamilyi860                = 0xFA,

+  EfiProcessorFamilyi960                = 0xFB

+} EFI_PROCESSOR_FAMILY_DATA;

+

+typedef EFI_EXP_BASE10_DATA EFI_PROCESSOR_VOLTAGE_DATA;

+

+typedef EFI_PHYSICAL_ADDRESS EFI_PROCESSOR_APIC_BASE_ADDRESS_DATA;

+

+typedef UINT32 EFI_PROCESSOR_APIC_ID_DATA;

+

+typedef UINT32 EFI_PROCESSOR_APIC_VERSION_NUMBER_DATA;

+

+typedef enum {

+  EfiProcessorIa32Microcode    = 1,

+  EfiProcessorIpfPalAMicrocode = 2,

+  EfiProcessorIpfPalBMicrocode = 3

+} EFI_PROCESSOR_MICROCODE_TYPE;

+

+typedef struct {

+  EFI_PROCESSOR_MICROCODE_TYPE  ProcessorMicrocodeType;

+  UINT32                        ProcessorMicrocodeRevisionNumber;

+} EFI_PROCESSOR_MICROCODE_REVISION_DATA;

+

+typedef struct {

+  UINT32      CpuStatus                 :3;

+  UINT32      Reserved1                 :3;

+  UINT32      SocketPopulated           :1;

+  UINT32      Reserved2                 :1;

+  UINT32      ApicEnable                :1;

+  UINT32      BootApplicationProcessor  :1;

+  UINT32      Reserved3                 :22;

+} EFI_PROCESSOR_STATUS_DATA;

+

+typedef enum {

+  EfiCpuStatusUnknown        = 0,

+  EfiCpuStatusEnabled        = 1,

+  EfiCpuStatusDisabledByUser = 2,

+  EfiCpuStatusDisabledbyBios = 3,

+  EfiCpuStatusIdle           = 4,

+  EfiCpuStatusOther          = 7

+} EFI_CPU_STATUS;

+

+typedef enum {

+  EfiProcessorSocketOther            = 1,

+  EfiProcessorSocketUnknown          = 2,

+  EfiProcessorSocketDaughterBoard    = 3,

+  EfiProcessorSocketZIF              = 4,

+  EfiProcessorSocketReplacePiggyBack = 5,

+  EfiProcessorSocketNone             = 6,

+  EfiProcessorSocketLIF              = 7,

+  EfiProcessorSocketSlot1            = 8,

+  EfiProcessorSocketSlot2            = 9,

+  EfiProcessorSocket370Pin           = 0xA,

+  EfiProcessorSocketSlotA            = 0xB,

+  EfiProcessorSocketSlotM            = 0xC,

+  EfiProcessorSocket423              = 0xD,

+  EfiProcessorSocketA462             = 0xE,

+  EfiProcessorSocket478              = 0xF,

+  EfiProcessorSocket754              = 0x10,

+  EfiProcessorSocket940              = 0x11,

+  EfiProcessorSocketLG775            = 0x12

+

+} EFI_PROCESSOR_SOCKET_TYPE_DATA;

+

+typedef STRING_REF EFI_PROCESSOR_SOCKET_NAME_DATA;

+

+typedef EFI_INTER_LINK_DATA EFI_CACHE_ASSOCIATION_DATA;

+

+typedef enum {

+  EfiProcessorHealthy        = 1,

+  EfiProcessorPerfRestricted = 2,

+  EfiProcessorFuncRestricted = 3

+} EFI_PROCESSOR_HEALTH_STATUS;  

+

+typedef UINTN   EFI_PROCESSOR_PACKAGE_NUMBER_DATA;

+

+

+typedef enum {

+  ProcessorCoreFrequencyRecordType     = 1,

+  ProcessorFsbFrequencyRecordType      = 2,

+  ProcessorVersionRecordType           = 3,

+  ProcessorManufacturerRecordType      = 4,

+  ProcessorSerialNumberRecordType      = 5,

+  ProcessorIdRecordType                = 6,

+  ProcessorTypeRecordType              = 7,

+  ProcessorFamilyRecordType            = 8,

+  ProcessorVoltageRecordType           = 9,

+  ProcessorApicBaseAddressRecordType   = 10,

+  ProcessorApicIdRecordType            = 11,

+  ProcessorApicVersionNumberRecordType = 12,

+  CpuUcodeRevisionDataRecordType       = 13,

+  ProcessorStatusRecordType            = 14,

+  ProcessorSocketTypeRecordType        = 15,

+  ProcessorSocketNameRecordType        = 16,

+  CacheAssociationRecordType           = 17,

+  ProcessorMaxCoreFrequencyRecordType  = 18,

+  ProcessorAssetTagRecordType          = 19,

+  ProcessorMaxFsbFrequencyRecordType   = 20,

+  ProcessorPackageNumberRecordType     = 21,

+  ProcessorCoreFrequencyListRecordType = 22,

+  ProcessorFsbFrequencyListRecordType  = 23,

+  ProcessorHealthStatusRecordType      = 24

+} EFI_CPU_VARIABLE_RECORD_TYPE;

+

+typedef union {

+  EFI_PROCESSOR_CORE_FREQUENCY_LIST_DATA  ProcessorCoreFrequencyList;

+  EFI_PROCESSOR_FSB_FREQUENCY_LIST_DATA   ProcessorFsbFrequencyList;

+  EFI_PROCESSOR_SERIAL_NUMBER_DATA        ProcessorSerialNumber;

+  EFI_PROCESSOR_CORE_FREQUENCY_DATA       ProcessorCoreFrequency;

+  EFI_PROCESSOR_FSB_FREQUENCY_DATA        ProcessorFsbFrequency;

+  EFI_PROCESSOR_MAX_CORE_FREQUENCY_DATA   ProcessorMaxCoreFrequency;

+  EFI_PROCESSOR_MAX_FSB_FREQUENCY_DATA    ProcessorMaxFsbFrequency;

+  EFI_PROCESSOR_VERSION_DATA              ProcessorVersion;

+  EFI_PROCESSOR_MANUFACTURER_DATA         ProcessorManufacturer;

+  EFI_PROCESSOR_ID_DATA                   ProcessorId;

+  EFI_PROCESSOR_TYPE_DATA                 ProcessorType;

+  EFI_PROCESSOR_FAMILY_DATA               ProcessorFamily;

+  EFI_PROCESSOR_VOLTAGE_DATA              ProcessorVoltage;

+  EFI_PROCESSOR_APIC_BASE_ADDRESS_DATA    ProcessorApicBase;

+  EFI_PROCESSOR_APIC_ID_DATA              ProcessorApicId;

+  EFI_PROCESSOR_APIC_VERSION_NUMBER_DATA  ProcessorApicVersionNumber;

+  EFI_PROCESSOR_MICROCODE_REVISION_DATA   CpuUcodeRevisionData;

+  EFI_PROCESSOR_STATUS_DATA               ProcessorStatus;

+  EFI_PROCESSOR_SOCKET_TYPE_DATA          ProcessorSocketType;

+  EFI_PROCESSOR_SOCKET_NAME_DATA          ProcessorSocketName;

+  EFI_PROCESSOR_ASSET_TAG_DATA            ProcessorAssetTag;

+  EFI_PROCESSOR_HEALTH_STATUS             ProcessorHealthStatus;

+  EFI_PROCESSOR_PACKAGE_NUMBER_DATA       ProcessorPackageNumber;

+} EFI_CPU_VARIABLE_RECORD;

+

+typedef struct {

+  EFI_SUBCLASS_TYPE1_HEADER      DataRecordHeader;

+  EFI_CPU_VARIABLE_RECORD        VariableRecord;

+} EFI_CPU_DATA_RECORD;

+

+#define EFI_CACHE_SUBCLASS_VERSION    0x00010000

+

+

+typedef EFI_EXP_BASE2_DATA  EFI_CACHE_SIZE_DATA;

+

+typedef EFI_EXP_BASE2_DATA  EFI_MAXIMUM_CACHE_SIZE_DATA;

+

+typedef EFI_EXP_BASE10_DATA EFI_CACHE_SPEED_DATA;

+

+typedef STRING_REF          EFI_CACHE_SOCKET_DATA;

+

+typedef struct {

+  UINT32  Other         :1;

+  UINT32  Unknown       :1;

+  UINT32  NonBurst      :1;

+  UINT32  Burst         :1;

+  UINT32  PipelineBurst :1;

+  UINT32  Asynchronous  :1;

+  UINT32  Synchronous   :1;

+  UINT32  Reserved      :25;

+} EFI_CACHE_SRAM_TYPE_DATA;

+

+typedef enum {  

+  EfiCacheErrorOther     = 1,

+  EfiCacheErrorUnknown   = 2,

+  EfiCacheErrorNone      = 3,

+  EfiCacheErrorParity    = 4,

+  EfiCacheErrorSingleBit = 5,

+  EfiCacheErrorMultiBit  = 6

+} EFI_CACHE_ERROR_TYPE_DATA;

+

+typedef enum {  

+  EfiCacheTypeOther       = 1,

+  EfiCacheTypeUnknown     = 2,

+  EfiCacheTypeInstruction = 3,

+  EfiCacheTypeData        = 4,

+  EfiCacheTypeUnified     = 5

+} EFI_CACHE_TYPE_DATA;

+

+typedef enum {  

+  EfiCacheAssociativityOther        = 1,

+  EfiCacheAssociativityUnknown      = 2,

+  EfiCacheAssociativityDirectMapped = 3,

+  EfiCacheAssociativity2Way         = 4,

+  EfiCacheAssociativity4Way         = 5,

+  EfiCacheAssociativityFully        = 6,

+  EfiCacheAssociativity8Way         = 7,

+  EfiCacheAssociativity16Way        = 8

+} EFI_CACHE_ASSOCIATIVITY_DATA;

+

+typedef struct {  

+  UINT32    Level           :3;

+  UINT32    Socketed        :1;

+  UINT32    Reserved2       :1;

+  UINT32    Location        :2;

+  UINT32    Enable          :1;

+  UINT32    OperationalMode :2;

+  UINT32    Reserved1       :22;

+} EFI_CACHE_CONFIGURATION_DATA;

+

+#define EFI_CACHE_L1      1

+#define EFI_CACHE_L2      2

+#define EFI_CACHE_L3      3

+#define EFI_CACHE_L4      4

+#define EFI_CACHE_LMAX    EFI_CACHE_L4

+

+#define EFI_CACHE_SOCKETED      1

+#define EFI_CACHE_NOT_SOCKETED  0

+

+typedef enum {

+  EfiCacheInternal = 0,

+  EfiCacheExternal = 1,

+  EfiCacheReserved = 2,

+  EfiCacheUnknown  = 3

+} EFI_CACHE_LOCATION;

+  

+#define EFI_CACHE_ENABLED    1

+#define EFI_CACHE_DISABLED   0

+

+typedef enum {

+  EfiCacheWriteThrough = 0,

+  EfiCacheWriteBack    = 1,

+  EfiCacheDynamicMode  = 2,

+  EfiCacheUnknownMode  = 3

+} EFI_CACHE_OPERATIONAL_MODE;

+

+

+

+typedef enum {

+  CacheSizeRecordType              = 1,

+  MaximumSizeCacheRecordType       = 2,

+  CacheSpeedRecordType             = 3,

+  CacheSocketRecordType            = 4,

+  CacheSramTypeRecordType          = 5,

+  CacheInstalledSramTypeRecordType = 6,

+  CacheErrorTypeRecordType         = 7,

+  CacheTypeRecordType              = 8,

+  CacheAssociativityRecordType     = 9,

+  CacheConfigRecordType            = 10

+} EFI_CACHE_VARIABLE_RECORD_TYPE;

+

+

+typedef union {

+  EFI_CACHE_SIZE_DATA             CacheSize;

+  EFI_MAXIMUM_CACHE_SIZE_DATA     MaximumCacheSize;

+  EFI_CACHE_SPEED_DATA            CacheSpeed;

+  EFI_CACHE_SOCKET_DATA           CacheSocket;

+  EFI_CACHE_SRAM_TYPE_DATA        CacheSramType;

+  EFI_CACHE_SRAM_TYPE_DATA        CacheInstalledSramType;

+  EFI_CACHE_ERROR_TYPE_DATA       CacheErrorType;

+  EFI_CACHE_TYPE_DATA             CacheType;

+  EFI_CACHE_ASSOCIATIVITY_DATA    CacheAssociativity;

+  EFI_CACHE_CONFIGURATION_DATA    CacheConfig;

+  EFI_CACHE_ASSOCIATION_DATA      CacheAssociation;

+} EFI_CACHE_VARIABLE_RECORD;

+

+typedef struct {

+   EFI_SUBCLASS_TYPE1_HEADER      DataRecordHeader;

+   EFI_CACHE_VARIABLE_RECORD      VariableRecord;  

+} EFI_CACHE_DATA_RECORD;

+  

+#define EFI_MEMORY_SUBCLASS_VERSION     0x0100

+

+

+#define EFI_MEMORY_SIZE_RECORD_NUMBER                 0x00000001

+

+typedef enum _EFI_MEMORY_REGION_TYPE {

+  EfiMemoryRegionMemory                       = 0x01,

+  EfiMemoryRegionReserved                     = 0x02,

+  EfiMemoryRegionAcpi                         = 0x03,

+  EfiMemoryRegionNvs                          = 0x04

+} EFI_MEMORY_REGION_TYPE;

+

+typedef struct {

+  UINT32                      ProcessorNumber;

+  UINT16                      StartBusNumber;

+  UINT16                      EndBusNumber;

+  EFI_MEMORY_REGION_TYPE      MemoryRegionType;

+  EFI_EXP_BASE2_DATA          MemorySize;

+  EFI_PHYSICAL_ADDRESS        MemoryStartAddress;

+} EFI_MEMORY_SIZE_DATA;

+

+

+#define EFI_MEMORY_ARRAY_LOCATION_RECORD_NUMBER       0x00000002

+

+typedef enum _EFI_MEMORY_ARRAY_LOCATION {

+  EfiMemoryArrayLocationOther                 = 0x01,

+  EfiMemoryArrayLocationUnknown               = 0x02,

+  EfiMemoryArrayLocationSystemBoard           = 0x03,

+  EfiMemoryArrayLocationIsaAddonCard          = 0x04,

+  EfiMemoryArrayLocationEisaAddonCard         = 0x05,

+  EfiMemoryArrayLocationPciAddonCard          = 0x06,

+  EfiMemoryArrayLocationMcaAddonCard          = 0x07,

+  EfiMemoryArrayLocationPcmciaAddonCard       = 0x08,

+  EfiMemoryArrayLocationProprietaryAddonCard  = 0x09,

+  EfiMemoryArrayLocationNuBus                 = 0x0A,

+  EfiMemoryArrayLocationPc98C20AddonCard      = 0xA0,

+  EfiMemoryArrayLocationPc98C24AddonCard      = 0xA1,

+  EfiMemoryArrayLocationPc98EAddonCard        = 0xA2,

+  EfiMemoryArrayLocationPc98LocalBusAddonCard = 0xA3

+} EFI_MEMORY_ARRAY_LOCATION;

+

+typedef enum _EFI_MEMORY_ARRAY_USE {

+  EfiMemoryArrayUseOther                      = 0x01,

+  EfiMemoryArrayUseUnknown                    = 0x02,

+  EfiMemoryArrayUseSystemMemory               = 0x03,

+  EfiMemoryArrayUseVideoMemory                = 0x04,

+  EfiMemoryArrayUseFlashMemory                = 0x05,

+  EfiMemoryArrayUseNonVolatileRam             = 0x06,

+  EfiMemoryArrayUseCacheMemory                = 0x07,

+} EFI_MEMORY_ARRAY_USE;

+

+typedef enum _EFI_MEMORY_ERROR_CORRECTION {

+  EfiMemoryErrorCorrectionOther               = 0x01,

+  EfiMemoryErrorCorrectionUnknown             = 0x02,

+  EfiMemoryErrorCorrectionNone                = 0x03,

+  EfiMemoryErrorCorrectionParity              = 0x04,

+  EfiMemoryErrorCorrectionSingleBitEcc        = 0x05,

+  EfiMemoryErrorCorrectionMultiBitEcc         = 0x06,

+  EfiMemoryErrorCorrectionCrc                 = 0x07,

+} EFI_MEMORY_ERROR_CORRECTION;

+

+typedef struct {

+  EFI_MEMORY_ARRAY_LOCATION   MemoryArrayLocation;

+  EFI_MEMORY_ARRAY_USE        MemoryArrayUse;

+  EFI_MEMORY_ERROR_CORRECTION MemoryErrorCorrection;

+  EFI_EXP_BASE2_DATA          MaximumMemoryCapacity;

+  UINT16                      NumberMemoryDevices;

+} EFI_MEMORY_ARRAY_LOCATION_DATA;

+

+

+#define EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER           0x00000003

+

+typedef enum _EFI_MEMORY_FORM_FACTOR {

+  EfiMemoryFormFactorOther                    = 0x01,

+  EfiMemoryFormFactorUnknown                  = 0x02,

+  EfiMemoryFormFactorSimm                     = 0x03,

+  EfiMemoryFormFactorSip                      = 0x04,

+  EfiMemoryFormFactorChip                     = 0x05,

+  EfiMemoryFormFactorDip                      = 0x06,

+  EfiMemoryFormFactorZip                      = 0x07,

+  EfiMemoryFormFactorProprietaryCard          = 0x08,

+  EfiMemoryFormFactorDimm                     = 0x09,

+  EfiMemoryFormFactorTsop                     = 0x0A,

+  EfiMemoryFormFactorRowOfChips               = 0x0B,

+  EfiMemoryFormFactorRimm                     = 0x0C,

+  EfiMemoryFormFactorSodimm                   = 0x0D,

+  EfiMemoryFormFactorSrimm                    = 0x0E

+} EFI_MEMORY_FORM_FACTOR;

+

+typedef enum _EFI_MEMORY_ARRAY_TYPE {

+  EfiMemoryTypeOther                          = 0x01,

+  EfiMemoryTypeUnknown                        = 0x02,

+  EfiMemoryTypeDram                           = 0x03,

+  EfiMemoryTypeEdram                          = 0x04,

+  EfiMemoryTypeVram                           = 0x05,

+  EfiMemoryTypeSram                           = 0x06,

+  EfiMemoryTypeRam                            = 0x07,

+  EfiMemoryTypeRom                            = 0x08,

+  EfiMemoryTypeFlash                          = 0x09,

+  EfiMemoryTypeEeprom                         = 0x0A,

+  EfiMemoryTypeFeprom                         = 0x0B,

+  EfiMemoryTypeEprom                          = 0x0C,

+  EfiMemoryTypeCdram                          = 0x0D,

+  EfiMemoryType3Dram                          = 0x0E,

+  EfiMemoryTypeSdram                          = 0x0F,

+  EfiMemoryTypeSgram                          = 0x10,

+  EfiMemoryTypeRdram                          = 0x11,

+  EfiMemoryTypeDdr                            = 0x12

+} EFI_MEMORY_ARRAY_TYPE;

+

+typedef struct {

+  UINT32                      Reserved        :1;

+  UINT32                      Other           :1;

+  UINT32                      Unknown         :1;

+  UINT32                      FastPaged       :1;

+  UINT32                      StaticColumn    :1;

+  UINT32                      PseudoStatic    :1;

+  UINT32                      Rambus          :1;

+  UINT32                      Synchronous     :1;

+  UINT32                      Cmos            :1;

+  UINT32                      Edo             :1;

+  UINT32                      WindowDram      :1;

+  UINT32                      CacheDram       :1;

+  UINT32                      Nonvolatile     :1;

+  UINT32                      Reserved1       :19;

+} EFI_MEMORY_TYPE_DETAIL;

+

+typedef enum {

+  EfiMemoryStateEnabled      = 0,

+  EfiMemoryStateUnknown      = 1,

+  EfiMemoryStateUnsupported  = 2,

+  EfiMemoryStateError        = 3,

+  EfiMemoryStateAbsent       = 4,

+  EfiMemoryStateDisabled     = 5,

+  EfiMemoryStatePartial      = 6

+} EFI_MEMORY_STATE;

+

+typedef struct {

+  STRING_REF                  MemoryDeviceLocator;

+  STRING_REF                  MemoryBankLocator;

+  STRING_REF                  MemoryManufacturer;

+  STRING_REF                  MemorySerialNumber;

+  STRING_REF                  MemoryAssetTag;

+  STRING_REF                  MemoryPartNumber;

+  EFI_INTER_LINK_DATA         MemoryArrayLink;

+  EFI_INTER_LINK_DATA         MemorySubArrayLink;

+  UINT16                      MemoryTotalWidth;

+  UINT16                      MemoryDataWidth;

+  EFI_EXP_BASE2_DATA          MemoryDeviceSize;

+  EFI_MEMORY_FORM_FACTOR      MemoryFormFactor;

+  UINT8                       MemoryDeviceSet;

+  EFI_MEMORY_ARRAY_TYPE       MemoryType;

+  EFI_MEMORY_TYPE_DETAIL      MemoryTypeDetail;

+  EFI_EXP_BASE10_DATA         MemorySpeed;

+  EFI_MEMORY_STATE            MemoryState;

+} EFI_MEMORY_ARRAY_LINK_DATA;

+

+

+#define EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER  0x00000004

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS        MemoryArrayStartAddress;

+  EFI_PHYSICAL_ADDRESS        MemoryArrayEndAddress;

+  EFI_INTER_LINK_DATA         PhysicalMemoryArrayLink;

+  UINT16                      MemoryArrayPartitionWidth;

+} EFI_MEMORY_ARRAY_START_ADDRESS_DATA;

+

+

+#define EFI_MEMORY_DEVICE_START_ADDRESS_RECORD_NUMBER 0x00000005

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS        MemoryDeviceStartAddress;

+  EFI_PHYSICAL_ADDRESS        MemoryDeviceEndAddress;

+  EFI_INTER_LINK_DATA         PhysicalMemoryDeviceLink;

+  EFI_INTER_LINK_DATA         PhysicalMemoryArrayLink;

+  UINT8                       MemoryDevicePartitionRowPosition;

+  UINT8                       MemoryDeviceInterleavePosition;

+  UINT8                       MemoryDeviceInterleaveDataDepth;

+} EFI_MEMORY_DEVICE_START_ADDRESS_DATA;

+

+

+//

+//  Memory. Channel Device Type -  SMBIOS Type 37

+//

+

+#define EFI_MEMORY_CHANNEL_TYPE_RECORD_NUMBER         0x00000006

+

+typedef enum _EFI_MEMORY_CHANNEL_TYPE {

+  EfiMemoryChannelTypeOther                   = 1,

+  EfiMemoryChannelTypeUnknown                 = 2,

+  EfiMemoryChannelTypeRambus                  = 3,

+  EfiMemoryChannelTypeSyncLink                = 4

+} EFI_MEMORY_CHANNEL_TYPE;

+

+typedef struct {

+  EFI_MEMORY_CHANNEL_TYPE     MemoryChannelType;

+  UINT8                       MemoryChannelMaximumLoad;

+  UINT8                       MemoryChannelDeviceCount;

+} EFI_MEMORY_CHANNEL_TYPE_DATA;

+

+#define EFI_MEMORY_CHANNEL_DEVICE_RECORD_NUMBER       0x00000007

+

+typedef struct {

+  UINT8                       DeviceId;

+  EFI_INTER_LINK_DATA         DeviceLink;

+  UINT8                       MemoryChannelDeviceLoad;

+} EFI_MEMORY_CHANNEL_DEVICE_DATA;

+

+

+

+typedef union _EFI_MEMORY_SUBCLASS_RECORDS {

+  EFI_MEMORY_SIZE_DATA                  SizeData;

+  EFI_MEMORY_ARRAY_LOCATION_DATA        ArrayLocationData;

+  EFI_MEMORY_ARRAY_LINK_DATA            ArrayLink;

+  EFI_MEMORY_ARRAY_START_ADDRESS_DATA   ArrayStartAddress;

+  EFI_MEMORY_DEVICE_START_ADDRESS_DATA  DeviceStartAddress;

+  EFI_MEMORY_CHANNEL_TYPE_DATA          ChannelTypeData;

+  EFI_MEMORY_CHANNEL_DEVICE_DATA        ChannelDeviceData;

+} EFI_MEMORY_SUBCLASS_RECORDS;

+

+typedef struct {

+  EFI_SUBCLASS_TYPE1_HEADER             Header;

+  EFI_MEMORY_SUBCLASS_RECORDS           Record;

+} EFI_MEMORY_SUBCLASS_DRIVER_DATA;

+

+#define EFI_MISC_SUBCLASS_VERSION     0x0100

+

+#pragma pack(1)

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Last PCI Bus Number

+//

+#define EFI_MISC_LAST_PCI_BUS_RECORD_NUMBER  0x00000001

+

+typedef struct {

+  UINT8   LastPciBus;

+} EFI_MISC_LAST_PCI_BUS_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. BIOS Vendor - SMBIOS Type 0

+//

+#define EFI_MISC_BIOS_VENDOR_RECORD_NUMBER  0x00000002

+

+typedef struct {

+  UINT32  Reserved1                         :2;

+  UINT32  Unknown                           :1;

+  UINT32  BiosCharacteristicsNotSupported   :1;

+  UINT32  IsaIsSupported                    :1;

+  UINT32  McaIsSupported                    :1;

+  UINT32  EisaIsSupported                   :1;

+  UINT32  PciIsSupported                    :1;

+  UINT32  PcmciaIsSupported                 :1;

+  UINT32  PlugAndPlayIsSupported            :1;

+  UINT32  ApmIsSupported                    :1;

+  UINT32  BiosIsUpgradable                  :1;

+  UINT32  BiosShadowingAllowed              :1;

+  UINT32  VlVesaIsSupported                 :1;

+  UINT32  EscdSupportIsAvailable            :1;

+  UINT32  BootFromCdIsSupported             :1;

+  UINT32  SelectableBootIsSupported         :1;

+  UINT32  RomBiosIsSocketed                 :1;

+  UINT32  BootFromPcmciaIsSupported         :1;

+  UINT32  EDDSpecificationIsSupported       :1;

+  UINT32  JapaneseNecFloppyIsSupported      :1;

+  UINT32  JapaneseToshibaFloppyIsSupported  :1;

+  UINT32  Floppy525_360IsSupported          :1;

+  UINT32  Floppy525_12IsSupported           :1;

+  UINT32  Floppy35_720IsSupported           :1;

+  UINT32  Floppy35_288IsSupported           :1;

+  UINT32  PrintScreenIsSupported            :1;

+  UINT32  Keyboard8042IsSupported           :1;

+  UINT32  SerialIsSupported                 :1;

+  UINT32  PrinterIsSupported                :1;

+  UINT32  CgaMonoIsSupported                :1;

+  UINT32  NecPc98                           :1;

+  UINT32  AcpiIsSupported                   :1;

+  UINT32  UsbLegacyIsSupported              :1;

+  UINT32  AgpIsSupported                    :1;

+  UINT32  I20BootIsSupported                :1;

+  UINT32  Ls120BootIsSupported              :1;

+  UINT32  AtapiZipDriveBootIsSupported      :1;

+  UINT32  Boot1394IsSupported               :1;

+  UINT32  SmartBatteryIsSupported           :1;

+  UINT32  BiosBootSpecIsSupported           :1;

+  UINT32  FunctionKeyNetworkBootIsSupported :1;

+  UINT32  Reserved                          :22;

+} EFI_MISC_BIOS_CHARACTERISTICS;

+

+typedef struct {

+  UINT32  BiosReserved                      :16;

+  UINT32  SystemReserved                    :16;

+  UINT32  Reserved                          :32;

+} EFI_MISC_BIOS_CHARACTERISTICS_EXTENSION;

+

+typedef struct {

+  STRING_REF                      BiosVendor;

+  STRING_REF                      BiosVersion;

+  STRING_REF                      BiosReleaseDate;

+  EFI_PHYSICAL_ADDRESS            BiosStartingAddress;

+  EFI_EXP_BASE2_DATA              BiosPhysicalDeviceSize;

+  EFI_MISC_BIOS_CHARACTERISTICS   BiosCharacteristics1;

+  EFI_MISC_BIOS_CHARACTERISTICS_EXTENSION  BiosCharacteristics2;

+} EFI_MISC_BIOS_VENDOR_DATA;       

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. System Manufacturer - SMBIOS Type 1

+//

+#define EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER 0x00000003

+

+typedef enum {  

+  EfiSystemWakeupTypeReserved        = 0,

+  EfiSystemWakeupTypeOther           = 1,

+  EfiSystemWakeupTypeUnknown         = 2,

+  EfiSystemWakeupTypeApmTimer        = 3,

+  EfiSystemWakeupTypeModemRing       = 4,

+  EfiSystemWakeupTypeLanRemote       = 5,

+  EfiSystemWakeupTypePowerSwitch     = 6,

+  EfiSystemWakeupTypePciPme          = 7,

+  EfiSystemWakeupTypeAcPowerRestored = 8,

+} EFI_MISC_SYSTEM_WAKEUP_TYPE;

+

+typedef struct {

+  STRING_REF                      SystemManufacturer;

+  STRING_REF                      SystemProductName;

+  STRING_REF                      SystemVersion;

+  STRING_REF                      SystemSerialNumber;

+  EFI_GUID                        SystemUuid;

+  EFI_MISC_SYSTEM_WAKEUP_TYPE     SystemWakeupType;

+} EFI_MISC_SYSTEM_MANUFACTURER_DATA;       

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Base Board Manufacturer - SMBIOS Type 2

+//

+#define EFI_MISC_BASE_BOARD_MANUFACTURER_RECORD_NUMBER 0x00000004

+

+typedef struct {

+  UINT32  Motherboard           :1;

+  UINT32  RequiresDaughterCard  :1;

+  UINT32  Removable             :1;

+  UINT32  Replaceable           :1;

+  UINT32  HotSwappable          :1;

+  UINT32  Reserved              :27;

+} EFI_BASE_BOARD_FEATURE_FLAGS;

+

+typedef enum {  

+  EfiBaseBoardTypeUnknown                = 1,

+  EfiBaseBoardTypeOther                  = 2,

+  EfiBaseBoardTypeServerBlade            = 3,

+  EfiBaseBoardTypeConnectivitySwitch     = 4,

+  EfiBaseBoardTypeSystemManagementModule = 5,

+  EfiBaseBoardTypeProcessorModule        = 6,

+  EfiBaseBoardTypeIOModule               = 7,

+  EfiBaseBoardTypeMemoryModule           = 8,

+  EfiBaseBoardTypeDaughterBoard          = 9,

+  EfiBaseBoardTypeMotherBoard            = 0xA,

+  EfiBaseBoardTypeProcessorMemoryModule  = 0xB,

+  EfiBaseBoardTypeProcessorIOModule      = 0xC,

+  EfiBaseBoardTypeInterconnectBoard      = 0xD,

+} EFI_BASE_BOARD_TYPE;

+

+typedef struct {

+  STRING_REF                      BaseBoardManufacturer;

+  STRING_REF                      BaseBoardProductName;

+  STRING_REF                      BaseBoardVersion;

+  STRING_REF                      BaseBoardSerialNumber;

+  STRING_REF                      BaseBoardAssetTag;

+  STRING_REF                      BaseBoardChassisLocation;

+  EFI_BASE_BOARD_FEATURE_FLAGS    BaseBoardFeatureFlags;

+  EFI_BASE_BOARD_TYPE             BaseBoardType;

+  EFI_INTER_LINK_DATA             BaseBoardChassisLink;

+  UINT32                          BaseBoardNumberLinks;

+  EFI_INTER_LINK_DATA             LinkN;

+} EFI_MISC_BASE_BOARD_MANUFACTURER_DATA;       

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. System/Chassis Enclosure - SMBIOS Type 3

+//

+#define EFI_MISC_CHASSIS_MANUFACTURER_RECORD_NUMBER  0x00000005

+

+typedef enum {  

+  EfiMiscChassisTypeOther               = 0x1,

+  EfiMiscChassisTypeUnknown             = 0x2,

+  EfiMiscChassisTypeDeskTop             = 0x3,

+  EfiMiscChassisTypeLowProfileDesktop   = 0x4,

+  EfiMiscChassisTypePizzaBox            = 0x5,

+  EfiMiscChassisTypeMiniTower           = 0x6,

+  EfiMiscChassisTypeTower               = 0x7,

+  EfiMiscChassisTypePortable            = 0x8,

+  EfiMiscChassisTypeLapTop              = 0x9,

+  EfiMiscChassisTypeNotebook            = 0xA,

+  EfiMiscChassisTypeHandHeld            = 0xB,

+  EfiMiscChassisTypeDockingStation      = 0xC,

+  EfiMiscChassisTypeAllInOne            = 0xD,

+  EfiMiscChassisTypeSubNotebook         = 0xE,

+  EfiMiscChassisTypeSpaceSaving         = 0xF,

+  EfiMiscChassisTypeLunchBox            = 0x10,

+  EfiMiscChassisTypeMainServerChassis   = 0x11,

+  EfiMiscChassisTypeExpansionChassis    = 0x12,

+  EfiMiscChassisTypeSubChassis          = 0x13,

+  EfiMiscChassisTypeBusExpansionChassis = 0x14,

+  EfiMiscChassisTypePeripheralChassis   = 0x15,

+  EfiMiscChassisTypeRaidChassis         = 0x16,

+  EfiMiscChassisTypeRackMountChassis    = 0x17,

+  EfiMiscChassisTypeSealedCasePc        = 0x18,

+  EfiMiscChassisMultiSystemChassis      = 0x19,

+} EFI_MISC_CHASSIS_TYPE;

+

+typedef struct {

+  UINT32  ChassisType       :16;

+  UINT32  ChassisLockPresent:1;

+  UINT32  Reserved          :15;

+} EFI_MISC_CHASSIS_STATUS;

+

+typedef enum {  

+  EfiChassisStateOther           = 0x01,

+  EfiChassisStateUnknown         = 0x02,

+  EfiChassisStateSafe            = 0x03,

+  EfiChassisStateWarning         = 0x04,

+  EfiChassisStateCritical        = 0x05,

+  EfiChassisStateNonRecoverable  = 0x06,

+} EFI_MISC_CHASSIS_STATE;

+

+typedef enum {  

+  EfiChassisSecurityStatusOther                          = 0x01,

+  EfiChassisSecurityStatusUnknown                        = 0x02,

+  EfiChassisSecurityStatusNone                           = 0x03,

+  EfiChassisSecurityStatusExternalInterfaceLockedOut     = 0x04,

+  EfiChassisSecurityStatusExternalInterfaceLockedEnabled = 0x05,

+} EFI_MISC_CHASSIS_SECURITY_STATE;

+

+typedef struct {

+  UINT32  RecordType  :1;

+  UINT32  Reserved    :24;

+} EFI_MISC_ELEMENT_TYPE;

+

+typedef struct {

+  EFI_MISC_ELEMENT_TYPE   ChassisElementType;

+  EFI_INTER_LINK_DATA     ChassisElementStructure;

+  EFI_BASE_BOARD_TYPE     ChassisBaseBoard;

+  UINT32                  ChassisElementMinimum;

+  UINT32                  ChassisElementMaximum;

+} EFI_MISC_ELEMENTS; 

+

+typedef struct {

+  STRING_REF                      ChassisManufacturer;

+  STRING_REF                      ChassisVersion;

+  STRING_REF                      ChassisSerialNumber;

+  STRING_REF                      ChassisAssetTag;

+  EFI_MISC_CHASSIS_STATUS         ChassisType;

+  EFI_MISC_CHASSIS_STATE          ChassisBootupState;

+  EFI_MISC_CHASSIS_STATE          ChassisPowerSupplyState;

+  EFI_MISC_CHASSIS_STATE          ChassisThermalState;

+  EFI_MISC_CHASSIS_SECURITY_STATE ChassisSecurityState;

+  UINT32                          ChassisOemDefined;

+  UINT32                          ChassisHeight;

+  UINT32                          ChassisNumberPowerCords;

+  UINT32                          ChassisElementCount;

+  UINT32                          ChassisElementRecordLength;//

+  EFI_MISC_ELEMENTS               ChassisElements;

+} EFI_MISC_CHASSIS_MANUFACTURER_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Port Connector Information - SMBIOS Type 8

+//

+#define EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER 0x00000006

+

+typedef enum {  

+  EfiPortConnectorTypeNone                   = 0x00,

+  EfiPortConnectorTypeCentronics             = 0x01,

+  EfiPortConnectorTypeMiniCentronics         = 0x02,

+  EfiPortConnectorTypeProprietary            = 0x03,

+  EfiPortConnectorTypeDB25Male               = 0x04,

+  EfiPortConnectorTypeDB25Female             = 0x05,

+  EfiPortConnectorTypeDB15Male               = 0x06,

+  EfiPortConnectorTypeDB15Female             = 0x07,

+  EfiPortConnectorTypeDB9Male                = 0x08,

+  EfiPortConnectorTypeDB9Female              = 0x09,

+  EfiPortConnectorTypeRJ11                   = 0x0A,

+  EfiPortConnectorTypeRJ45                   = 0x0B,

+  EfiPortConnectorType50PinMiniScsi          = 0x0C,

+  EfiPortConnectorTypeMiniDin                = 0x0D,

+  EfiPortConnectorTypeMicriDin               = 0x0E,

+  EfiPortConnectorTypePS2                    = 0x0F,

+  EfiPortConnectorTypeInfrared               = 0x10,

+  EfiPortConnectorTypeHpHil                  = 0x11,

+  EfiPortConnectorTypeUsb                    = 0x12,

+  EfiPortConnectorTypeSsaScsi                = 0x13,

+  EfiPortConnectorTypeCircularDin8Male       = 0x14,

+  EfiPortConnectorTypeCircularDin8Female     = 0x15,

+  EfiPortConnectorTypeOnboardIde             = 0x16,

+  EfiPortConnectorTypeOnboardFloppy          = 0x17,

+  EfiPortConnectorType9PinDualInline         = 0x18,

+  EfiPortConnectorType25PinDualInline        = 0x19,

+  EfiPortConnectorType50PinDualInline        = 0x1A,

+  EfiPortConnectorType68PinDualInline        = 0x1B,

+  EfiPortConnectorTypeOnboardSoundInput      = 0x1C,

+  EfiPortConnectorTypeMiniCentronicsType14   = 0x1D,

+  EfiPortConnectorTypeMiniCentronicsType26   = 0x1E,

+  EfiPortConnectorTypeHeadPhoneMiniJack      = 0x1F,

+  EfiPortConnectorTypeBNC                    = 0x20,

+  EfiPortConnectorType1394                   = 0x21,

+  EfiPortConnectorTypePC98                   = 0xA0,

+  EfiPortConnectorTypePC98Hireso             = 0xA1,

+  EfiPortConnectorTypePCH98                  = 0xA2,

+  EfiPortConnectorTypePC98Note               = 0xA3,

+  EfiPortConnectorTypePC98Full               = 0xA4,

+  EfiPortConnectorTypeOther                  = 0xFF,

+} EFI_MISC_PORT_CONNECTOR_TYPE;

+

+typedef enum {  

+  EfiPortTypeNone                      = 0x00,

+  EfiPortTypeParallelXtAtCompatible    = 0x01,

+  EfiPortTypeParallelPortPs2           = 0x02,

+  EfiPortTypeParallelPortEcp           = 0x03,

+  EfiPortTypeParallelPortEpp           = 0x04,

+  EfiPortTypeParallelPortEcpEpp        = 0x05,

+  EfiPortTypeSerialXtAtCompatible      = 0x06,

+  EfiPortTypeSerial16450Compatible     = 0x07,

+  EfiPortTypeSerial16550Compatible     = 0x08,

+  EfiPortTypeSerial16550ACompatible    = 0x09,

+  EfiPortTypeScsi                      = 0x0A,

+  EfiPortTypeMidi                      = 0x0B,

+  EfiPortTypeJoyStick                  = 0x0C,

+  EfiPortTypeKeyboard                  = 0x0D,

+  EfiPortTypeMouse                     = 0x0E,

+  EfiPortTypeSsaScsi                   = 0x0F,

+  EfiPortTypeUsb                       = 0x10,

+  EfiPortTypeFireWire                  = 0x11,

+  EfiPortTypePcmciaTypeI               = 0x12,

+  EfiPortTypePcmciaTypeII              = 0x13,

+  EfiPortTypePcmciaTypeIII             = 0x14,

+  EfiPortTypeCardBus                   = 0x15,

+  EfiPortTypeAccessBusPort             = 0x16,

+  EfiPortTypeScsiII                    = 0x17,

+  EfiPortTypeScsiWide                  = 0x18,

+  EfiPortTypePC98                      = 0x19,

+  EfiPortTypePC98Hireso                = 0x1A,

+  EfiPortTypePCH98                     = 0x1B,

+  EfiPortTypeVideoPort                 = 0x1C,

+  EfiPortTypeAudioPort                 = 0x1D,

+  EfiPortTypeModemPort                 = 0x1E,

+  EfiPortTypeNetworkPort               = 0x1F,

+  EfiPortType8251Compatible            = 0xA0,

+  EfiPortType8251FifoCompatible        = 0xA1,

+  EfiPortTypeOther                     = 0xFF,

+} EFI_MISC_PORT_TYPE;

+

+typedef struct {

+  STRING_REF                    PortInternalConnectorDesignator;

+  STRING_REF                    PortExternalConnectorDesignator;

+  EFI_MISC_PORT_CONNECTOR_TYPE  PortInternalConnectorType;

+  EFI_MISC_PORT_CONNECTOR_TYPE  PortExternalConnectorType;

+  EFI_MISC_PORT_TYPE            PortType;

+  EFI_MISC_PORT_DEVICE_PATH     PortPath;

+} EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA;      

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. System Slots - SMBIOS Type 9

+//

+#define EFI_MISC_SYSTEM_SLOT_DESIGNATION_RECORD_NUMBER 0x00000007

+

+typedef enum {  

+  EfiSlotTypeOther                        = 0x01,

+  EfiSlotTypeUnknown                      = 0x02,

+  EfiSlotTypeIsa                          = 0x03,

+  EfiSlotTypeMca                          = 0x04,

+  EfiSlotTypeEisa                         = 0x05,

+  EfiSlotTypePci                          = 0x06,

+  EfiSlotTypePcmcia                       = 0x07,

+  EfiSlotTypeVlVesa                       = 0x08,

+  EfiSlotTypeProprietary                  = 0x09,

+  EfiSlotTypeProcessorCardSlot            = 0x0A,

+  EfiSlotTypeProprietaryMemoryCardSlot    = 0x0B,

+  EfiSlotTypeIORiserCardSlot              = 0x0C,

+  EfiSlotTypeNuBus                        = 0x0D,

+  EfiSlotTypePci66MhzCapable              = 0x0E,

+  EfiSlotTypeAgp                          = 0x0F,

+  EfiSlotTypeApg2X                        = 0x10,

+  EfiSlotTypeAgp4X                        = 0x11,

+  EfiSlotTypePciX                         = 0x12,

+  EfiSlotTypeAgp4x                        = 0x13,

+  EfiSlotTypePC98C20                      = 0xA0,

+  EfiSlotTypePC98C24                      = 0xA1,

+  EfiSlotTypePC98E                        = 0xA2,

+  EfiSlotTypePC98LocalBus                 = 0xA3,

+  EfiSlotTypePC98Card                     = 0xA4,

+} EFI_MISC_SLOT_TYPE;

+

+typedef enum {  

+  EfiSlotDataBusWidthOther      = 0x01,

+  EfiSlotDataBusWidthUnknown    = 0x02,

+  EfiSlotDataBusWidth8Bit       = 0x03,

+  EfiSlotDataBusWidth16Bit      = 0x04,

+  EfiSlotDataBusWidth32Bit      = 0x05,

+  EfiSlotDataBusWidth64Bit      = 0x06,

+  EfiSlotDataBusWidth128Bit     = 0x07,

+} EFI_MISC_SLOT_DATA_BUS_WIDTH;

+

+typedef enum {  

+  EfiSlotUsageOther     = 1,

+  EfiSlotUsageUnknown   = 2,

+  EfiSlotUsageAvailable = 3,

+  EfiSlotUsageInUse     = 4,

+} EFI_MISC_SLOT_USAGE;

+  

+typedef enum {  

+  EfiSlotLengthOther   = 1,

+  EfiSlotLengthUnknown = 2,

+  EfiSlotLengthShort   = 3,

+  EfiSlotLengthLong    = 4

+} EFI_MISC_SLOT_LENGTH;

+

+typedef struct {

+  UINT32  CharacteristicsUnknown  :1;

+  UINT32  Provides50Volts         :1;

+  UINT32  Provides33Volts         :1;

+  UINT32  SharedSlot              :1;

+  UINT32  PcCard16Supported       :1;

+  UINT32  CardBusSupported        :1;

+  UINT32  ZoomVideoSupported      :1;

+  UINT32  ModemRingResumeSupported:1;

+  UINT32  PmeSignalSupported      :1;

+  UINT32  HotPlugDevicesSupported :1;

+  UINT32  SmbusSignalSupported    :1;

+  UINT32  Reserved                :21;

+} EFI_MISC_SLOT_CHARACTERISTICS;

+

+typedef struct {

+  STRING_REF                    SlotDesignation;

+  EFI_MISC_SLOT_TYPE            SlotType;

+  EFI_MISC_SLOT_DATA_BUS_WIDTH  SlotDataBusWidth;

+  EFI_MISC_SLOT_USAGE           SlotUsage;

+  EFI_MISC_SLOT_LENGTH          SlotLength;

+  UINT16                        SlotId;

+  EFI_MISC_SLOT_CHARACTERISTICS SlotCharacteristics;

+  EFI_DEVICE_PATH_PROTOCOL      SlotDevicePath;

+} EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA;      

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Onboard Device - SMBIOS Type 10

+//

+#define EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER 0x00000008

+

+typedef enum {  

+  EfiOnBoardDeviceTypeOther          = 1,

+  EfiOnBoardDeviceTypeUnknown        = 2,

+  EfiOnBoardDeviceTypeVideo          = 3,

+  EfiOnBoardDeviceTypeScsiController = 4,

+  EfiOnBoardDeviceTypeEthernet       = 5,

+  EfiOnBoardDeviceTypeTokenRing      = 6,

+  EfiOnBoardDeviceTypeSound          = 7,

+} EFI_MISC_ONBOARD_DEVICE_TYPE;

+

+typedef struct {

+  UINT32  DeviceType    :16;

+  UINT32  DeviceEnabled :1;

+  UINT32  Reserved      :15;

+} EFI_MISC_ONBOARD_DEVICE_STATUS;

+

+typedef struct {

+  STRING_REF                           OnBoardDeviceDescription;

+  EFI_MISC_ONBOARD_DEVICE_STATUS       OnBoardDeviceStatus;

+  EFI_DEVICE_PATH_PROTOCOL             OnBoardDevicePath;

+} EFI_MISC_ONBOARD_DEVICE_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. BIOS Language Information - SMBIOS Type 11

+//

+#define EFI_MISC_OEM_STRING_RECORD_NUMBER 0x00000009

+

+typedef struct {

+  STRING_REF                          OemStringRef[1];

+} EFI_MISC_OEM_STRING_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. System Options - SMBIOS Type 12

+//

+typedef struct {

+  STRING_REF                          SystemOptionStringRef[1];

+} EFI_MISC_SYSTEM_OPTION_STRING_DATA;      

+

+#define EFI_MISC_SYSTEM_OPTION_STRING_RECORD_NUMBER 0x0000000A

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Number of Installable Languages - SMBIOS Type 13

+//

+#define EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_RECORD_NUMBER 0x0000000B

+

+typedef struct {

+  UINT32                              AbbreviatedLanguageFormat :1;

+  UINT32                              Reserved                  :31;

+} EFI_MISC_LANGUAGE_FLAGS;

+

+typedef struct {

+  UINT16                              NumberOfInstallableLanguages;

+  EFI_MISC_LANGUAGE_FLAGS             LanguageFlags;

+  UINT16                              CurrentLanguageNumber;

+} EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA;       

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. System Language String

+//

+#define EFI_MISC_SYSTEM_LANGUAGE_STRING_RECORD_NUMBER 0x0000000C

+

+typedef struct {

+  UINT16                              LanguageId;

+  STRING_REF                          SystemLanguageString;

+} EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA;      

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Group Associations - SMBIOS Type 14

+//

+#define EFI_MISC_GROUP_NAME_RECORD_NUMBER          0x0000000D

+

+typedef struct {

+  STRING_REF               GroupName;

+  UINT16                   NumberGroupItems;

+  UINT16                   GroupId;

+} EFI_MISC_GROUP_NAME_DATA;  

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Group Item Set Element

+//

+#define EFI_MISC_GROUP_ITEM_SET_RECORD_NUMBER      0x0000000E

+

+typedef struct {

+  EFI_GUID                 SubClass;         

+  EFI_INTER_LINK_DATA      GroupLink;

+  UINT16                   GroupId;

+  UINT16                   GroupElementId;

+} EFI_MISC_GROUP_ITEM_SET_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+//  Misc. Pointing Device Type - SMBIOS Type 21

+//

+#define EFI_MISC_POINTING_DEVICE_TYPE_RECORD_NUMBER 0x0000000F

+

+typedef enum { 

+  EfiPointingDeviceTypeOther         = 0x01,

+  EfiPointingDeviceTypeUnknown       = 0x02,

+  EfiPointingDeviceTypeMouse         = 0x03,

+  EfiPointingDeviceTypeTrackBall     = 0x04,

+  EfiPointingDeviceTypeTrackPoint    = 0x05,

+  EfiPointingDeviceTypeGlidePoint    = 0x06,

+  EfiPointingDeviceTouchPad          = 0x07,

+  EfiPointingDeviceTouchScreen       = 0x08,

+  EfiPointingDeviceOpticalSensor     = 0x09,

+} EFI_MISC_POINTING_DEVICE_TYPE;

+

+typedef enum {  

+  EfiPointingDeviceInterfaceOther              = 0x01,

+  EfiPointingDeviceInterfaceUnknown            = 0x02,

+  EfiPointingDeviceInterfaceSerial             = 0x03,

+  EfiPointingDeviceInterfacePs2                = 0x04,

+  EfiPointingDeviceInterfaceInfrared           = 0x05,

+  EfiPointingDeviceInterfaceHpHil              = 0x06,

+  EfiPointingDeviceInterfaceBusMouse           = 0x07,

+  EfiPointingDeviceInterfaceADB                = 0x08,

+  EfiPointingDeviceInterfaceBusMouseDB9        = 0xA0,

+  EfiPointingDeviceInterfaceBusMouseMicroDin   = 0xA1,

+  EfiPointingDeviceInterfaceUsb                = 0xA2,

+} EFI_MISC_POINTING_DEVICE_INTERFACE;

+

+typedef struct {

+  EFI_MISC_POINTING_DEVICE_TYPE       PointingDeviceType;

+  EFI_MISC_POINTING_DEVICE_INTERFACE  PointingDeviceInterface;

+  UINT16                              NumberPointingDeviceButtons;

+  EFI_DEVICE_PATH_PROTOCOL            PointingDevicePath;

+} EFI_MISC_PORTING_DEVICE_TYPE_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Portable Battery - SMBIOS Type 22

+//

+#define EFI_MISC_BATTERY_LOCATION_RECORD_NUMBER  0x00000010

+

+typedef enum { 

+  EfiBatteryDeviceChemistryTypeOther               = 0x01,

+  EfiBatteryDeviceChemistryTypeUnknown             = 0x02,

+  EfiBatteryDeviceChemistryTypeLeadAcid            = 0x03,

+  EfiBatteryDeviceChemistryTypeNickelCadmium       = 0x04,

+  EfiBatteryDeviceChemistryTypeNickelMetalHydride  = 0x05,

+  EfiBatteryDeviceChemistryTypeLithiumIon          = 0x06,

+  EfiBatteryDeviceChemistryTypeZincAir             = 0x07,

+  EfiBatteryDeviceChemistryTypeLithiumPolymer      = 0x08,

+} EFI_MISC_BATTERY_DEVICE_CHEMISTRY;

+

+typedef struct  {

+  UINT32 Date              :5;

+  UINT32 Month             :4;

+  UINT32 Year              :7;

+  UINT32 Reserved          :16;

+} EFI_MISC_BATTERY_SBDS_MANUFACTURE_DATE;

+

+typedef struct {

+  STRING_REF                         BatteryLocation;

+  STRING_REF                         BatteryManufacturer;

+  STRING_REF                         BatteryManufactureDate;

+  STRING_REF                         BatterySerialNumber;

+  STRING_REF                         BatteryDeviceName;

+  STRING_REF                         BatterySbdsVersionNumber;

+  STRING_REF                         BatterySbdsDeviceChemistry;

+  EFI_MISC_BATTERY_DEVICE_CHEMISTRY  BatteryDeviceChemistry;

+  EFI_EXP_BASE10_DATA                BatteryDesignCapacity;

+  EFI_EXP_BASE10_DATA                BatteryDesignVoltage;

+  UINT16                             BatteryMaximumError;

+  UINT16                             BatterySbdsSerialNumber;

+  EFI_MISC_BATTERY_SBDS_MANUFACTURE_DATE

+                                     BatterySbdsManufacturingDate;

+  UINT32                             BatteryOemSpecific;

+} EFI_MISC_BATTERY_LOCATION_DATA;   

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Reset Capabilities - SMBIOS Type 23

+//

+#define EFI_MISC_RESET_CAPABILITIES_RECORD_NUMBER 0x00000011

+

+typedef struct {

+  UINT32  Status              :1;

+  UINT32  BootOption          :2;

+  UINT32  BootOptionOnLimit   :2;

+  UINT32  WatchdogTimerPresent:1;

+  UINT32  Reserved            :26;

+} EFI_MISC_RESET_CAPABILITIES_TYPE;

+

+typedef struct {

+  EFI_MISC_RESET_CAPABILITIES_TYPE  ResetCapabilities;

+  UINT16                            ResetCount;

+  UINT16                            ResetLimit;

+  UINT16                            ResetTimerInterval;

+  UINT16                            ResetTimeout;

+} EFI_MISC_RESET_CAPABILITIES;

+ 

+typedef struct {

+    EFI_MISC_RESET_CAPABILITIES   ResetCapabilities;

+    UINT16                        ResetCount;

+    UINT16                        ResetLimit;

+    UINT16                        ResetTimerInterval;

+    UINT16                        ResetTimeout;

+} EFI_MISC_RESET_CAPABILITIES_DATA;       

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Hardware Security - SMBIOS Type 24

+//

+#define EFI_MISC_HARDWARE_SECURITY_RECORD_NUMBER 0x00000012

+

+typedef enum {

+  EfiHardwareSecurityStatusDisabled       = 0,

+  EfiHardwareSecurityStatusEnabled        = 1,

+  EfiHardwareSecurityStatusNotImplemented = 2,

+  EfiHardwareSecurityStatusUnknown        = 3

+} EFI_MISC_HARDWARE_SECURITY_STATUS; 

+

+typedef struct {

+  EFI_MISC_HARDWARE_SECURITY_STATUS   FrontPanelResetStatus       :2;  

+  EFI_MISC_HARDWARE_SECURITY_STATUS   AdministratorPasswordStatus :2;  

+  EFI_MISC_HARDWARE_SECURITY_STATUS   KeyboardPasswordStatus      :2;  

+  EFI_MISC_HARDWARE_SECURITY_STATUS   PowerOnPasswordStatus       :2;  

+  EFI_MISC_HARDWARE_SECURITY_STATUS   Reserved                    :24;  

+} EFI_MISC_HARDWARE_SECURITY_SETTINGS;

+

+typedef struct {

+  EFI_MISC_HARDWARE_SECURITY_SETTINGS HardwareSecuritySettings;

+} EFI_MISC_HARDWARE_SECURITY_SETTINGS_DATA;       

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// System Power Controls - SMBIOS Type 25

+//

+#define EFI_MISC_SCHEDULED_POWER_ON_MONTH_RECORD_NUMBER  0x00000013

+

+typedef struct {

+  UINT16             ScheduledPoweronMonth;

+  UINT16             ScheduledPoweronDayOfMonth;

+  UINT16             ScheduledPoweronHour;

+  UINT16             ScheduledPoweronMinute;

+  UINT16             ScheduledPoweronSecond;

+} EFI_MISC_SCHEDULED_POWER_ON_MONTH_DATA;  

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Voltage Probe - SMBIOS Type 26

+//

+#define EFI_MISC_VOLTAGE_PROBE_DESCRIPTION_RECORD_NUMBER  0x00000014

+

+typedef struct {

+  UINT32 VoltageProbeSite        :5;

+  UINT32 VoltageProbeStatus      :3;

+  UINT32 Reserved                :24;

+} EFI_MISC_VOLTAGE_PROBE_LOCATION;

+

+typedef struct {

+  STRING_REF                      VoltageProbeDescription;

+  EFI_MISC_VOLTAGE_PROBE_LOCATION VoltageProbeLocation;

+  EFI_EXP_BASE10_DATA             VoltageProbeMaximumValue;

+  EFI_EXP_BASE10_DATA             VoltageProbeMinimumValue;

+  EFI_EXP_BASE10_DATA             VoltageProbeResolution;

+  EFI_EXP_BASE10_DATA             VoltageProbeTolerance;

+  EFI_EXP_BASE10_DATA             VoltageProbeAccuracy;

+  EFI_EXP_BASE10_DATA             VoltageProbeNominalValue;

+  EFI_EXP_BASE10_DATA             MDLowerNoncriticalThreshold;

+  EFI_EXP_BASE10_DATA             MDUpperNoncriticalThreshold;

+  EFI_EXP_BASE10_DATA             MDLowerCriticalThreshold;

+  EFI_EXP_BASE10_DATA             MDUpperCriticalThreshold;

+  EFI_EXP_BASE10_DATA             MDLowerNonrecoverableThreshold;

+  EFI_EXP_BASE10_DATA             MDUpperNonrecoverableThreshold;

+  UINT32                          VoltageProbeOemDefined;

+} EFI_MISC_VOLTAGE_PROBE_DESCRIPTION_DATA; 

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Cooling Device - SMBIOS Type 27

+//

+#define EFI_MISC_COOLING_DEVICE_TEMP_LINK_RECORD_NUMBER   0x00000015

+

+typedef struct {

+  UINT32 CoolingDevice                 :5;

+  UINT32 CoolingDeviceStatus           :3;

+  UINT32 Reserved                      :24;

+} EFI_MISC_COOLING_DEVICE_TYPE;

+

+typedef struct {

+  EFI_MISC_COOLING_DEVICE_TYPE   CoolingDeviceType;

+  EFI_INTER_LINK_DATA            CoolingDeviceTemperatureLink;

+  UINT16                         CoolingDeviceUnitGroup;

+  EFI_EXP_BASE10_DATA            CoolingDeviceNominalSpeed;

+  UINT32                         CoolingDeviceOemDefined;

+} EFI_MISC_COOLING_DEVICE_TEMP_LINK_DATA; 

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Temperature Probe - SMBIOS Type 28

+//

+#define EFI_MISC_TEMPERATURE_PROBE_DESCRIPTION_RECORD_NUMBER   0x00000016

+

+typedef struct {

+  UINT32 TemperatureProbeSite          :5;

+  UINT32 TemperatureProbeStatus        :3;

+  UINT32 Reserved                      :24;

+} EFI_MISC_TEMPERATURE_PROBE_LOCATION;

+

+typedef struct {

+  STRING_REF               TemperatureProbeDescription;

+  EFI_MISC_TEMPERATURE_PROBE_LOCATION

+                           TemperatureProbeLocation;

+  EFI_EXP_BASE10_DATA      TemperatureProbeMaximumValue;

+  EFI_EXP_BASE10_DATA      TemperatureProbeMinimumValue;

+  EFI_EXP_BASE10_DATA      TemperatureProbeResolution;

+  EFI_EXP_BASE10_DATA      TemperatureProbeTolerance;

+  EFI_EXP_BASE10_DATA      TemperatureProbeAccuracy;

+  EFI_EXP_BASE10_DATA      TemperatureProbeNominalValue; 

+  EFI_EXP_BASE10_DATA      MDLowerNoncriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDUpperNoncriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDLowerCriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDUpperCriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDLowerNonrecoverableThreshold;

+  EFI_EXP_BASE10_DATA      MDUpperNonrecoverableThreshold;

+  UINT32                   TemperatureProbeOemDefined;

+} EFI_MISC_TEMPERATURE_PROBE_DESCRIPTION_DATA;  

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Electrical Current Probe - SMBIOS Type 29

+//

+

+#define EFI_MISC_ELECTRICAL_CURRENT_PROBE_DESCRIPTION_RECORD_NUMBER  0x00000017

+

+typedef struct {

+  UINT32 ElectricalCurrentProbeSite    :5;

+  UINT32 ElectricalCurrentProbeStatus  :3;

+  UINT32 Reserved                      :24;

+} EFI_MISC_ELECTRICAL_CURRENT_PROBE_LOCATION;

+

+typedef struct {

+  STRING_REF               ElectricalCurrentProbeDescription;

+  EFI_MISC_ELECTRICAL_CURRENT_PROBE_LOCATION

+                           ElectricalCurrentProbeLocation;

+  EFI_EXP_BASE10_DATA      ElectricalCurrentProbeMaximumValue;

+  EFI_EXP_BASE10_DATA      ElectricalCurrentProbeMinimumValue;

+  EFI_EXP_BASE10_DATA      ElectricalCurrentProbeResolution;

+  EFI_EXP_BASE10_DATA      ElectricalCurrentProbeTolerance;

+  EFI_EXP_BASE10_DATA      ElectricalCurrentProbeAccuracy;

+  EFI_EXP_BASE10_DATA      ElectricalCurrentProbeNominalValue;

+  EFI_EXP_BASE10_DATA      MDLowerNoncriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDUpperNoncriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDLowerCriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDUpperCriticalThreshold;

+  EFI_EXP_BASE10_DATA      MDLowerNonrecoverableThreshold;

+  EFI_EXP_BASE10_DATA      MDUpperNonrecoverableThreshold;

+  UINT32                   ElectricalCurrentProbeOemDefined;

+} EFI_MISC_ELECTRICAL_CURRENT_PROBE_DESCRIPTION_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Out-of-Band Remote Access - SMBIOS Type 30

+//

+

+#define EFI_MISC_REMOTE_ACCESS_MANUFACTURER_DESCRIPTION_RECORD_NUMBER  0x00000018

+

+typedef struct  {

+  UINT32 InboundConnectionEnabled            :1;

+  UINT32 OutboundConnectionEnabled           :1;

+  UINT32 Reserved                            :30;

+} EFI_MISC_REMOTE_ACCESS_CONNECTIONS;

+

+typedef struct {

+  STRING_REF                             RemoteAccessManufacturerNameDescription;

+  EFI_MISC_REMOTE_ACCESS_CONNECTIONS     RemoteAccessConnections;

+} EFI_MISC_REMOTE_ACCESS_MANUFACTURER_DESCRIPTION_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. BIS Entry Point - SMBIOS Type 31

+//

+#define EFI_MISC_BIS_ENTRY_POINT_RECORD_NUMBER          0x00000019

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS       BisEntryPoint;

+} EFI_MISC_BIS_ENTRY_POINT_DATA;    

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Misc. Boot Information - SMBIOS Type 32

+//

+#define EFI_MISC_BOOT_INFORMATION_STATUS_RECORD_NUMBER  0x0000001A

+

+typedef enum {  

+  EfiBootInformationStatusNoError                  = 0x00,

+  EfiBootInformationStatusNoBootableMedia          = 0x01,

+  EfiBootInformationStatusNormalOSFailedLoading    = 0x02,

+  EfiBootInformationStatusFirmwareDetectedFailure  = 0x03,

+  EfiBootInformationStatusOSDetectedFailure        = 0x04,

+  EfiBootInformationStatusUserRequestedBoot        = 0x05,

+  EfiBootInformationStatusSystemSecurityViolation  = 0x06,

+  EfiBootInformationStatusPreviousRequestedImage   = 0x07,

+  EfiBootInformationStatusWatchdogTimerExpired     = 0x08,

+  EfiBootInformationStatusStartReserved            = 0x09,

+  EfiBootInformationStatusStartOemSpecific         = 0x80,

+  EfiBootInformationStatusStartProductSpecific     = 0xC0,

+} EFI_MISC_BOOT_INFORMATION_STATUS_DATA_TYPE;

+

+typedef struct {

+  EFI_MISC_BOOT_INFORMATION_STATUS_DATA_TYPE BootInformationStatus;

+  UINT8                                      BootInformationData[9];

+} EFI_MISC_BOOT_INFORMATION_STATUS_DATA;

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Management Device - SMBIOS Type 34

+//

+#define EFI_MISC_MANAGEMENT_DEVICE_DESCRIPTION_RECORD_NUMBER   0x0000001B

+

+typedef enum { 

+  EfiManagementDeviceTypeOther      = 0x01,

+  EfiManagementDeviceTypeUnknown    = 0x02,

+  EfiManagementDeviceTypeLm75       = 0x03,

+  EfiManagementDeviceTypeLm78       = 0x04,

+  EfiManagementDeviceTypeLm79       = 0x05,

+  EfiManagementDeviceTypeLm80       = 0x06,

+  EfiManagementDeviceTypeLm81       = 0x07,

+  EfiManagementDeviceTypeAdm9240    = 0x08,

+  EfiManagementDeviceTypeDs1780     = 0x09,

+  EfiManagementDeviceTypeMaxim1617  = 0x0A,

+  EfiManagementDeviceTypeGl518Sm    = 0x0B,

+  EfiManagementDeviceTypeW83781D    = 0x0C,

+  EfiManagementDeviceTypeHt82H791   = 0x0D,

+} EFI_MISC_MANAGEMENT_DEVICE_TYPE;

+

+typedef enum { 

+  EfiManagementDeviceAddressTypeOther   = 1,

+  EfiManagementDeviceAddressTypeUnknown = 2,

+  EfiManagementDeviceAddressTypeIOPort  = 3,

+  EfiManagementDeviceAddressTypeMemory  = 4,

+  EfiManagementDeviceAddressTypeSmbus   = 5

+} EFI_MISC_MANAGEMENT_DEVICE_ADDRESS_TYPE;

+

+typedef struct {

+  STRING_REF                       ManagementDeviceDescription;

+  EFI_MISC_MANAGEMENT_DEVICE_TYPE  ManagementDeviceType;

+  UINTN                            ManagementDeviceAddress;

+  EFI_MISC_MANAGEMENT_DEVICE_ADDRESS_TYPE

+                                   ManagementDeviceAddressType;

+} EFI_MISC_MANAGEMENT_DEVICE_DESCRIPTION_DATA; 

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// Management Device Component - SMBIOS Type 35

+//

+

+#define EFI_MISC_MANAGEMENT_DEVICE_COMPONENT_DESCRIPTION_RECORD_NUMBER  0x0000001C

+

+typedef struct {

+  STRING_REF               ManagementDeviceComponentDescription;

+  EFI_INTER_LINK_DATA      ManagementDeviceLink;

+  EFI_INTER_LINK_DATA      ManagementDeviceComponentLink; 

+} EFI_MISC_MANAGEMENT_DEVICE_COMPONENT_DESCRIPTION_DATA; 

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// IPMI Data Record - SMBIOS Type 38

+//

+typedef enum {  

+  EfiIpmiOther = 0,

+  EfiIpmiKcs   = 1,

+  EfiIpmiSmic  = 2,

+  EfiIpmiBt    = 3,

+} EFI_MISC_IPMI_INTERFACE_TYPE;

+

+typedef struct {

+  UINT16  IpmiSpecLeastSignificantDigit:4;

+  UINT16  IpmiSpecMostSignificantDigit: 4;

+  UINT16  Reserved:                     8;

+} EFI_MISC_IPMI_SPECIFICATION_REVISION;

+

+typedef struct {

+  EFI_MISC_IPMI_INTERFACE_TYPE          IpmiInterfaceType;

+  EFI_MISC_IPMI_SPECIFICATION_REVISION  IpmiSpecificationRevision;

+  UINT16                                IpmiI2CSlaveAddress;

+  UINT16                                IpmiNvDeviceAddress;

+  UINT64                                IpmiBaseAddress;

+  EFI_DEVICE_PATH_PROTOCOL              IpmiDevicePath;

+} EFI_MISC_IPMI_INTERFACE_TYPE_DATA;

+       

+#define EFI_MISC_IPMI_INTERFACE_TYPE_RECORD_NUMBER  0x0000001D

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+//System Power supply Record - SMBIOS Type 39

+//

+typedef struct {

+  UINT16  PowerSupplyHotReplaceable  :1;

+  UINT16  PowerSupplyPresent         :1;

+  UINT16  PowerSupplyUnplugged       :1;

+  UINT16  InputVoltageRangeSwitch    :4;

+  UINT16  PowerSupplyStatus          :3;

+  UINT16  PowerSupplyType            :4;

+  UINT16  Reserved                   :2;

+} POWER_SUPPLY_CHARACTERISTICS;

+

+typedef struct {

+  UINT16                          PowerUnitGroup;

+  STRING_REF                      PowerSupplyLocation;

+  STRING_REF                      PowerSupplyDeviceName;

+  STRING_REF                      PowerSupplyManufacturer;

+  STRING_REF                      PowerSupplySerialNumber;

+  STRING_REF                      PowerSupplyAssetTagNumber;

+  STRING_REF                      PowerSupplyModelPartNumber;

+  STRING_REF                      PowerSupplyRevisionLevel;

+  UINT16                          PowerSupplyMaxPowerCapacity;

+  POWER_SUPPLY_CHARACTERISTICS    PowerSupplyCharacteristics;

+  EFI_INTER_LINK_DATA             PowerSupplyInputVoltageProbeLink;

+  EFI_INTER_LINK_DATA             PowerSupplyCoolingDeviceLink;

+  EFI_INTER_LINK_DATA             PowerSupplyInputCurrentProbeLink;

+} EFI_MISC_SYSTEM_POWER_SUPPLY_DATA;

+

+#define EFI_MISC_SYSTEM_POWER_SUPPLY_RECORD_NUMBER 0x0000001E

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+// OEM Data Record - SMBIOS Type 0x80-0xFF

+//

+typedef struct {

+  UINT8       Type;

+  UINT8       Length;

+  UINT16      Handle;

+} SMBIOS_STRUCTURE_HDR;

+

+typedef struct {

+  SMBIOS_STRUCTURE_HDR          Header;

+  UINT8                         RawData[1];

+} EFI_MISC_SMBIOS_STRUCT_ENCAPSULATION_DATA; 

+

+#define EFI_MISC_SMBIOS_STRUCT_ENCAP_RECORD_NUMBER  0x0000001F 

+

+//

+//////////////////////////////////////////////////////////////////////////////

+//

+typedef union {

+  EFI_MISC_LAST_PCI_BUS_DATA                         LastPciBus;

+  EFI_MISC_BIOS_VENDOR_DATA                          MiscBiosVendor;

+  EFI_MISC_SYSTEM_MANUFACTURER_DATA                  MiscSystemManufacturer;

+  EFI_MISC_BASE_BOARD_MANUFACTURER_DATA              MiscBaseBoardManufacturer;

+  EFI_MISC_CHASSIS_MANUFACTURER_DATA                 MiscChassisManufacturer;  

+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA   MiscPortInternalConnectorDesignator;

+  EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA              MiscSystemSlotDesignation;

+  EFI_MISC_ONBOARD_DEVICE_DATA                       MiscOnboardDevice;

+  EFI_MISC_OEM_STRING_DATA                           MiscOemString;

+  EFI_MISC_SYSTEM_OPTION_STRING_DATA                 MiscOptionString;

+  EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA      NumberOfInstallableLanguages;

+  EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA               MiscSystemLanguageString;  

+  EFI_MISC_GROUP_NAME_DATA                           MiscGroupNameData;

+  EFI_MISC_GROUP_ITEM_SET_DATA                       MiscGroupItemSetData;

+  EFI_MISC_PORTING_DEVICE_TYPE_DATA                  MiscPortingDeviceTypeData;

+  EFI_MISC_RESET_CAPABILITIES_DATA                   MiscResetCapablilitiesData;

+  EFI_MISC_HARDWARE_SECURITY_SETTINGS_DATA           MiscHardwareSecuritySettingsData;  

+  EFI_MISC_SCHEDULED_POWER_ON_MONTH_DATA             MiscScheduledPowerOnMonthData;

+  EFI_MISC_VOLTAGE_PROBE_DESCRIPTION_DATA            MiscVoltagePorbeDescriptionData;

+  EFI_MISC_COOLING_DEVICE_TEMP_LINK_DATA             MiscCoolingDeviceTempLinkData;

+  EFI_MISC_TEMPERATURE_PROBE_DESCRIPTION_DATA        MiscTemperatureProbeDescriptionData;   

+  EFI_MISC_ELECTRICAL_CURRENT_PROBE_DESCRIPTION_DATA MiscElectricalCurrentProbeDescriptionData;

+  EFI_MISC_REMOTE_ACCESS_MANUFACTURER_DESCRIPTION_DATA

+                                                     MiscRemoteAccessManufacturerDescriptionData;

+  EFI_MISC_BIS_ENTRY_POINT_DATA                      MiscBisEntryPoint;

+  EFI_MISC_BOOT_INFORMATION_STATUS_DATA              MiscBootInformationStatus;

+  EFI_MISC_MANAGEMENT_DEVICE_DESCRIPTION_DATA        MiscMangementDeviceDescriptionData;

+  EFI_MISC_MANAGEMENT_DEVICE_COMPONENT_DESCRIPTION_DATA

+                                                     MiscmangementDeviceComponentDescriptionData;

+  EFI_MISC_IPMI_INTERFACE_TYPE_DATA                  MiscIpmiInterfaceTypeData;

+  EFI_MISC_SYSTEM_POWER_SUPPLY_DATA                  MiscPowerSupplyInfo;

+  EFI_MISC_SMBIOS_STRUCT_ENCAPSULATION_DATA          MiscSmbiosStructEncapsulation;  

+} EFI_MISC_SUBCLASS_RECORDS;

+

+//

+//

+//

+typedef struct {

+  EFI_SUBCLASS_TYPE1_HEADER       Header;

+  EFI_MISC_SUBCLASS_RECORDS       Record;

+} EFI_MISC_SUBCLASS_DRIVER_DATA;

+

+#pragma pack()

+

+//

+// Sub Class Header type1

+//

+

+#define EFI_SUBCLASS_INSTANCE_RESERVED       0

+#define EFI_SUBCLASS_INSTANCE_NON_APPLICABLE 0xFFFF  //16 bit

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Common/Dependency.h b/edk2/MdePkg/Include/Common/Dependency.h
new file mode 100644
index 0000000..744027d
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/Dependency.h
@@ -0,0 +1,50 @@
+/** @file

+  This module contains data specific to dependency expressions

+  and local function prototypes.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Dependency.h

+

+**/

+

+#ifndef __DEPENDENCY_H__

+#define __DEPENDENCY_H__

+

+/// EFI_DEP_BEFORE       - If present, this must be the first and only opcode

+#define EFI_DEP_BEFORE        0x00

+

+/// EFI_DEP_AFTER        - If present, this must be the first and only opcode

+#define EFI_DEP_AFTER         0x01

+

+#define EFI_DEP_PUSH          0x02

+#define EFI_DEP_AND           0x03

+#define EFI_DEP_OR            0x04

+#define EFI_DEP_NOT           0x05

+#define EFI_DEP_TRUE          0x06

+#define EFI_DEP_FALSE         0x07

+#define EFI_DEP_END           0x08

+

+/// EFI_DEP_SOR          - If present, this must be the first opcode

+#define EFI_DEP_SOR           0x09

+

+///

+/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression

+///                        to save time.  A EFI_DEP_PUSH is evauated one an

+///                        replaced with EFI_DEP_REPLACE_TRUE

+///

+#define EFI_DEP_REPLACE_TRUE  0xff

+

+///

+/// Define the initial size of the dependency expression evaluation stack

+///

+#define DEPEX_STACK_SIZE_INCREMENT  0x1000

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/EfiImage.h b/edk2/MdePkg/Include/Common/EfiImage.h
new file mode 100644
index 0000000..ebe251e
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/EfiImage.h
@@ -0,0 +1,698 @@
+/** @file

+  EFI image format for PE32+. Please note some data structures are different

+  for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64

+

+  @bug Fix text - doc as defined in MSFT EFI specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EfiImage.h

+

+**/

+

+#ifndef __EFI_IMAGE_H__

+#define __EFI_IMAGE_H__

+

+//

+// PE32+ Subsystem type for EFI images

+//

+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION         10

+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11

+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      12

+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER      13

+

+//

+// BugBug: Need to get a real answer for this problem. This is not in the

+//         PE specification.

+//

+//         A SAL runtime driver does not get fixed up when a transition to

+//         virtual mode is made. In all other cases it should be treated

+//         like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image

+//

+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER  13

+

+//

+// PE32+ Machine type for EFI images

+//

+#define IMAGE_FILE_MACHINE_I386     0x014c

+#define IMAGE_FILE_MACHINE_IA64     0x0200

+#define IMAGE_FILE_MACHINE_EBC      0x0EBC

+#define IMAGE_FILE_MACHINE_X64      0x8664

+//

+// Support old names for backward compatible

+//

+#define EFI_IMAGE_MACHINE_IA32      IMAGE_FILE_MACHINE_I386 

+#define EFI_IMAGE_MACHINE_IA64      IMAGE_FILE_MACHINE_IA64  

+#define EFI_IMAGE_MACHINE_IPF       IMAGE_FILE_MACHINE_IA64  

+#define EFI_IMAGE_MACHINE_EBC       IMAGE_FILE_MACHINE_EBC  

+#define EFI_IMAGE_MACHINE_X64       IMAGE_FILE_MACHINE_X64

+

+#define EFI_IMAGE_DOS_SIGNATURE     0x5A4D      // MZ

+#define EFI_IMAGE_OS2_SIGNATURE     0x454E      // NE

+#define EFI_IMAGE_OS2_SIGNATURE_LE  0x454C      // LE

+#define EFI_IMAGE_NT_SIGNATURE      0x00004550  // PE00

+#define EFI_IMAGE_EDOS_SIGNATURE    0x44454550  // PEED

+

+///

+/// PE images can start with an optional DOS header, so if an image is run

+///  under DOS it can print an error message.

+///

+typedef struct {

+  UINT16  e_magic;    // Magic number

+  UINT16  e_cblp;     // Bytes on last page of file

+  UINT16  e_cp;       // Pages in file

+  UINT16  e_crlc;     // Relocations

+  UINT16  e_cparhdr;  // Size of header in paragraphs

+  UINT16  e_minalloc; // Minimum extra paragraphs needed

+  UINT16  e_maxalloc; // Maximum extra paragraphs needed

+  UINT16  e_ss;       // Initial (relative) SS value

+  UINT16  e_sp;       // Initial SP value

+  UINT16  e_csum;     // Checksum

+  UINT16  e_ip;       // Initial IP value

+  UINT16  e_cs;       // Initial (relative) CS value

+  UINT16  e_lfarlc;   // File address of relocation table

+  UINT16  e_ovno;     // Overlay number

+  UINT16  e_res[4];   // Reserved words

+  UINT16  e_oemid;    // OEM identifier (for e_oeminfo)

+  UINT16  e_oeminfo;  // OEM information; e_oemid specific

+  UINT16  e_res2[10]; // Reserved words

+  UINT32  e_lfanew;   // File address of new exe header

+} EFI_IMAGE_DOS_HEADER;

+

+///

+/// File header format.

+///

+typedef struct {

+  UINT16  Machine;

+  UINT16  NumberOfSections;

+  UINT32  TimeDateStamp;

+  UINT32  PointerToSymbolTable;

+  UINT32  NumberOfSymbols;

+  UINT16  SizeOfOptionalHeader;

+  UINT16  Characteristics;

+} EFI_IMAGE_FILE_HEADER;

+

+#define EFI_IMAGE_SIZEOF_FILE_HEADER        20

+

+#define EFI_IMAGE_FILE_RELOCS_STRIPPED      0x0001  // Relocation info stripped from file.

+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE     0x0002  // File is executable  (i.e. no unresolved externel references).

+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED   0x0004  // Line nunbers stripped from file.

+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED  0x0008  // Local symbols stripped from file.

+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO    0x0080  // Bytes of machine word are reversed.

+#define EFI_IMAGE_FILE_32BIT_MACHINE        0x0100  // 32 bit word machine.

+#define EFI_IMAGE_FILE_DEBUG_STRIPPED       0x0200  // Debugging info stripped from file in .DBG file

+#define EFI_IMAGE_FILE_SYSTEM               0x1000  // System File.

+#define EFI_IMAGE_FILE_DLL                  0x2000  // File is a DLL.

+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI    0x8000  // Bytes of machine word are reversed.

+#define EFI_IMAGE_FILE_MACHINE_UNKNOWN      0

+#define EFI_IMAGE_FILE_MACHINE_I386         0x14c   // Intel 386.

+#define EFI_IMAGE_FILE_MACHINE_R3000        0x162   // MIPS* little-endian, 0540 big-endian

+#define EFI_IMAGE_FILE_MACHINE_R4000        0x166   // MIPS* little-endian

+#define EFI_IMAGE_FILE_MACHINE_ALPHA        0x184   // Alpha_AXP*

+#define EFI_IMAGE_FILE_MACHINE_POWERPC      0x1F0   // IBM* PowerPC Little-Endian

+#define EFI_IMAGE_FILE_MACHINE_TAHOE        0x7cc   // Intel EM machine

+//

+// * Other names and brands may be claimed as the property of others.

+//

+

+///

+/// Directory format.

+///

+typedef struct {

+  UINT32  VirtualAddress;

+  UINT32  Size;

+} EFI_IMAGE_DATA_DIRECTORY;

+

+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16

+

+typedef struct {

+  UINT16  Magic;

+  UINT8   MajorLinkerVersion;

+  UINT8   MinorLinkerVersion;

+  UINT32  SizeOfCode;

+  UINT32  SizeOfInitializedData;

+  UINT32  SizeOfUninitializedData;

+  UINT32  AddressOfEntryPoint;

+  UINT32  BaseOfCode;

+  UINT32  BaseOfData;

+  UINT32  BaseOfBss;

+  UINT32  GprMask;

+  UINT32  CprMask[4];

+  UINT32  GpValue;

+} EFI_IMAGE_ROM_OPTIONAL_HEADER;

+

+#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC      0x107

+#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER  sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)

+

+typedef struct {

+  EFI_IMAGE_FILE_HEADER         FileHeader;

+  EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;

+} EFI_IMAGE_ROM_HEADERS;

+

+///

+/// @attention

+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64

+/// are for use ONLY by tools.  All proper EFI code MUST use

+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!

+///

+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b

+

+typedef struct {

+  //

+  // Standard fields.

+  //

+  UINT16                    Magic;

+  UINT8                     MajorLinkerVersion;

+  UINT8                     MinorLinkerVersion;

+  UINT32                    SizeOfCode;

+  UINT32                    SizeOfInitializedData;

+  UINT32                    SizeOfUninitializedData;

+  UINT32                    AddressOfEntryPoint;

+  UINT32                    BaseOfCode;

+  UINT32                    BaseOfData;

+  //

+  // NT additional fields.

+  //

+  UINT32                    ImageBase;

+  UINT32                    SectionAlignment;

+  UINT32                    FileAlignment;

+  UINT16                    MajorOperatingSystemVersion;

+  UINT16                    MinorOperatingSystemVersion;

+  UINT16                    MajorImageVersion;

+  UINT16                    MinorImageVersion;

+  UINT16                    MajorSubsystemVersion;

+  UINT16                    MinorSubsystemVersion;

+  UINT32                    Win32VersionValue;

+  UINT32                    SizeOfImage;

+  UINT32                    SizeOfHeaders;

+  UINT32                    CheckSum;

+  UINT16                    Subsystem;

+  UINT16                    DllCharacteristics;

+  UINT32                    SizeOfStackReserve;

+  UINT32                    SizeOfStackCommit;

+  UINT32                    SizeOfHeapReserve;

+  UINT32                    SizeOfHeapCommit;

+  UINT32                    LoaderFlags;

+  UINT32                    NumberOfRvaAndSizes;

+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];

+} EFI_IMAGE_OPTIONAL_HEADER32;

+

+///

+/// @attention

+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64

+/// are for use ONLY by tools.  All proper EFI code MUST use

+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!

+///

+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b

+

+typedef struct {

+  //

+  // Standard fields.

+  //

+  UINT16                    Magic;

+  UINT8                     MajorLinkerVersion;

+  UINT8                     MinorLinkerVersion;

+  UINT32                    SizeOfCode;

+  UINT32                    SizeOfInitializedData;

+  UINT32                    SizeOfUninitializedData;

+  UINT32                    AddressOfEntryPoint;

+  UINT32                    BaseOfCode;

+  //

+  // NT additional fields.

+  //

+  UINT64                    ImageBase;

+  UINT32                    SectionAlignment;

+  UINT32                    FileAlignment;

+  UINT16                    MajorOperatingSystemVersion;

+  UINT16                    MinorOperatingSystemVersion;

+  UINT16                    MajorImageVersion;

+  UINT16                    MinorImageVersion;

+  UINT16                    MajorSubsystemVersion;

+  UINT16                    MinorSubsystemVersion;

+  UINT32                    Win32VersionValue;

+  UINT32                    SizeOfImage;

+  UINT32                    SizeOfHeaders;

+  UINT32                    CheckSum;

+  UINT16                    Subsystem;

+  UINT16                    DllCharacteristics;

+  UINT64                    SizeOfStackReserve;

+  UINT64                    SizeOfStackCommit;

+  UINT64                    SizeOfHeapReserve;

+  UINT64                    SizeOfHeapCommit;

+  UINT32                    LoaderFlags;

+  UINT32                    NumberOfRvaAndSizes;

+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];

+} EFI_IMAGE_OPTIONAL_HEADER64;

+

+///

+/// @attention

+/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY

+/// by tools.  All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!

+///

+typedef struct {

+  UINT32                      Signature;

+  EFI_IMAGE_FILE_HEADER       FileHeader;

+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;

+} EFI_IMAGE_NT_HEADERS32;

+

+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)

+

+typedef struct {

+  UINT32                      Signature;

+  EFI_IMAGE_FILE_HEADER       FileHeader;

+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;

+} EFI_IMAGE_NT_HEADERS64;

+

+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)

+

+//

+// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the

+// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build.  Same for

+// EFI_IMAGE_NT_HEADERS.  These definitions MUST be used by ALL EFI code.

+//

+#if   defined (MDE_CPU_IA32)

+

+typedef EFI_IMAGE_OPTIONAL_HEADER32     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS32          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \

+  (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))

+

+#elif defined (MDE_CPU_IPF)

+

+typedef EFI_IMAGE_OPTIONAL_HEADER64     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS64          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \

+  (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC))

+

+#elif defined (MDE_CPU_X64)

+

+typedef EFI_IMAGE_OPTIONAL_HEADER64     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS64          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \

+  (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))

+

+#elif defined (MDE_CPU_EBC)

+

+//

+// This is just to make sure you can cross compile with the EBC compiiler.

+// It does not make sense to have a PE loader coded in EBC. You need to 

+// understand the basic 

+//

+typedef EFI_IMAGE_OPTIONAL_HEADER64     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS64          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)

+

+#else

+#error Unknown Processor Type

+#endif

+

+

+#define EFI_IMAGE_FIRST_SECTION(ntheader) \

+    ( \

+      (EFI_IMAGE_SECTION_HEADER *) \

+        ( \

+          (UINT32) ntheader + \

+          FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \

+          ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \

+        ) \

+    )

+

+//

+// Subsystem Values

+//

+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN     0

+#define EFI_IMAGE_SUBSYSTEM_NATIVE      1

+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2

+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.

+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI     5

+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI   7

+

+//

+// Directory Entries

+//

+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT      0

+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT      1

+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE    2

+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION   3

+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY    4

+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC   5

+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG       6

+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT   7

+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR   8

+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS         9

+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10

+

+//

+// Section header format.

+//

+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8

+

+typedef struct {

+  UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];

+  union {

+    UINT32  PhysicalAddress;

+    UINT32  VirtualSize;

+  } Misc;

+  UINT32  VirtualAddress;

+  UINT32  SizeOfRawData;

+  UINT32  PointerToRawData;

+  UINT32  PointerToRelocations;

+  UINT32  PointerToLinenumbers;

+  UINT16  NumberOfRelocations;

+  UINT16  NumberOfLinenumbers;

+  UINT32  Characteristics;

+} EFI_IMAGE_SECTION_HEADER;

+

+#define EFI_IMAGE_SIZEOF_SECTION_HEADER       40

+

+#define EFI_IMAGE_SCN_TYPE_NO_PAD             0x00000008  // Reserved.

+#define EFI_IMAGE_SCN_CNT_CODE                0x00000020

+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA    0x00000040

+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA  0x00000080

+

+#define EFI_IMAGE_SCN_LNK_OTHER               0x00000100  // Reserved.

+#define EFI_IMAGE_SCN_LNK_INFO                0x00000200  // Section contains comments or some other type of information.

+#define EFI_IMAGE_SCN_LNK_REMOVE              0x00000800  // Section contents will not become part of image.

+#define EFI_IMAGE_SCN_LNK_COMDAT              0x00001000

+

+#define EFI_IMAGE_SCN_ALIGN_1BYTES            0x00100000

+#define EFI_IMAGE_SCN_ALIGN_2BYTES            0x00200000

+#define EFI_IMAGE_SCN_ALIGN_4BYTES            0x00300000

+#define EFI_IMAGE_SCN_ALIGN_8BYTES            0x00400000

+#define EFI_IMAGE_SCN_ALIGN_16BYTES           0x00500000

+#define EFI_IMAGE_SCN_ALIGN_32BYTES           0x00600000

+#define EFI_IMAGE_SCN_ALIGN_64BYTES           0x00700000

+

+#define EFI_IMAGE_SCN_MEM_DISCARDABLE         0x02000000

+#define EFI_IMAGE_SCN_MEM_NOT_CACHED          0x04000000

+#define EFI_IMAGE_SCN_MEM_NOT_PAGED           0x08000000

+#define EFI_IMAGE_SCN_MEM_SHARED              0x10000000

+#define EFI_IMAGE_SCN_MEM_EXECUTE             0x20000000

+#define EFI_IMAGE_SCN_MEM_READ                0x40000000

+#define EFI_IMAGE_SCN_MEM_WRITE               0x80000000

+

+///

+/// Symbol format.

+///

+#define EFI_IMAGE_SIZEOF_SYMBOL 18

+

+//

+// Section values.

+//

+// Symbols have a section number of the section in which they are

+// defined. Otherwise, section numbers have the following meanings:

+//

+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0  // Symbol is undefined or is common.

+#define EFI_IMAGE_SYM_ABSOLUTE  (UINT16) -1 // Symbol is an absolute value.

+#define EFI_IMAGE_SYM_DEBUG     (UINT16) -2 // Symbol is a special debug item.

+//

+// Type (fundamental) values.

+//

+#define EFI_IMAGE_SYM_TYPE_NULL   0   // no type.

+#define EFI_IMAGE_SYM_TYPE_VOID   1   //

+#define EFI_IMAGE_SYM_TYPE_CHAR   2   // type character.

+#define EFI_IMAGE_SYM_TYPE_SHORT  3   // type short integer.

+#define EFI_IMAGE_SYM_TYPE_INT    4

+#define EFI_IMAGE_SYM_TYPE_LONG   5

+#define EFI_IMAGE_SYM_TYPE_FLOAT  6

+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7

+#define EFI_IMAGE_SYM_TYPE_STRUCT 8

+#define EFI_IMAGE_SYM_TYPE_UNION  9

+#define EFI_IMAGE_SYM_TYPE_ENUM   10  // enumeration.

+#define EFI_IMAGE_SYM_TYPE_MOE    11  // member of enumeration.

+#define EFI_IMAGE_SYM_TYPE_BYTE   12

+#define EFI_IMAGE_SYM_TYPE_WORD   13

+#define EFI_IMAGE_SYM_TYPE_UINT   14

+#define EFI_IMAGE_SYM_TYPE_DWORD  15

+

+//

+// Type (derived) values.

+//

+#define EFI_IMAGE_SYM_DTYPE_NULL      0 // no derived type.

+#define EFI_IMAGE_SYM_DTYPE_POINTER   1

+#define EFI_IMAGE_SYM_DTYPE_FUNCTION  2

+#define EFI_IMAGE_SYM_DTYPE_ARRAY     3

+

+//

+// Storage classes.

+//

+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION   (UINT8) -1

+#define EFI_IMAGE_SYM_CLASS_NULL              0

+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC         1

+#define EFI_IMAGE_SYM_CLASS_EXTERNAL          2

+#define EFI_IMAGE_SYM_CLASS_STATIC            3

+#define EFI_IMAGE_SYM_CLASS_REGISTER          4

+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF      5

+#define EFI_IMAGE_SYM_CLASS_LABEL             6

+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL   7

+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT  8

+#define EFI_IMAGE_SYM_CLASS_ARGUMENT          9

+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG        10

+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION   11

+#define EFI_IMAGE_SYM_CLASS_UNION_TAG         12

+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION   13

+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC  14

+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG          15

+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM    16

+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM    17

+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD         18

+#define EFI_IMAGE_SYM_CLASS_BLOCK             100

+#define EFI_IMAGE_SYM_CLASS_FUNCTION          101

+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT     102

+#define EFI_IMAGE_SYM_CLASS_FILE              103

+#define EFI_IMAGE_SYM_CLASS_SECTION           104

+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL     105

+

+//

+// type packing constants

+//

+#define EFI_IMAGE_N_BTMASK  017

+#define EFI_IMAGE_N_TMASK   060

+#define EFI_IMAGE_N_TMASK1  0300

+#define EFI_IMAGE_N_TMASK2  0360

+#define EFI_IMAGE_N_BTSHFT  4

+#define EFI_IMAGE_N_TSHIFT  2

+

+//

+// Communal selection types.

+//

+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES    1

+#define EFI_IMAGE_COMDAT_SELECT_ANY             2

+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE       3

+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH     4

+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE     5

+

+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY  1

+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY    2

+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS      3

+

+///

+/// Relocation format.

+///

+typedef struct {

+  UINT32  VirtualAddress;

+  UINT32  SymbolTableIndex;

+  UINT16  Type;

+} EFI_IMAGE_RELOCATION;

+

+#define EFI_IMAGE_SIZEOF_RELOCATION 10

+

+//

+// I386 relocation types.

+//

+#define EFI_IMAGE_REL_I386_ABSOLUTE 0   // Reference is absolute, no relocation is necessary

+#define EFI_IMAGE_REL_I386_DIR16    01  // Direct 16-bit reference to the symbols virtual address

+#define EFI_IMAGE_REL_I386_REL16    02  // PC-relative 16-bit reference to the symbols virtual address

+#define EFI_IMAGE_REL_I386_DIR32    06  // Direct 32-bit reference to the symbols virtual address

+#define EFI_IMAGE_REL_I386_DIR32NB  07  // Direct 32-bit reference to the symbols virtual address, base not included

+#define EFI_IMAGE_REL_I386_SEG12    011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address

+#define EFI_IMAGE_REL_I386_SECTION  012

+#define EFI_IMAGE_REL_I386_SECREL   013

+#define EFI_IMAGE_REL_I386_REL32    024 // PC-relative 32-bit reference to the symbols virtual address

+

+///

+/// Based relocation format.

+///

+typedef struct {

+  UINT32  VirtualAddress;

+  UINT32  SizeOfBlock;

+} EFI_IMAGE_BASE_RELOCATION;

+

+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION  8

+

+//

+// Based relocation types.

+//

+#define EFI_IMAGE_REL_BASED_ABSOLUTE      0

+#define EFI_IMAGE_REL_BASED_HIGH          1

+#define EFI_IMAGE_REL_BASED_LOW           2

+#define EFI_IMAGE_REL_BASED_HIGHLOW       3

+#define EFI_IMAGE_REL_BASED_HIGHADJ       4

+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR  5

+#define EFI_IMAGE_REL_BASED_IA64_IMM64    9

+#define EFI_IMAGE_REL_BASED_DIR64         10

+

+///

+/// Line number format.

+///

+typedef struct {

+  union {

+    UINT32  SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.

+    UINT32  VirtualAddress;   // Virtual address of line number.

+  } Type;

+  UINT16  Linenumber;         // Line number.

+} EFI_IMAGE_LINENUMBER;

+

+#define EFI_IMAGE_SIZEOF_LINENUMBER 6

+

+//

+// Archive format.

+//

+#define EFI_IMAGE_ARCHIVE_START_SIZE        8

+#define EFI_IMAGE_ARCHIVE_START             "!<arch>\n"

+#define EFI_IMAGE_ARCHIVE_END               "`\n"

+#define EFI_IMAGE_ARCHIVE_PAD               "\n"

+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER     "/               "

+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER  "//              "

+

+typedef struct {

+  UINT8 Name[16];     // File member name - `/' terminated.

+  UINT8 Date[12];     // File member date - decimal.

+  UINT8 UserID[6];    // File member user id - decimal.

+  UINT8 GroupID[6];   // File member group id - decimal.

+  UINT8 Mode[8];      // File member mode - octal.

+  UINT8 Size[10];     // File member size - decimal.

+  UINT8 EndHeader[2]; // String to end header.

+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;

+

+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60

+

+//

+// DLL support.

+//

+

+///

+/// DLL Export Format

+///

+typedef struct {

+  UINT32  Characteristics;

+  UINT32  TimeDateStamp;

+  UINT16  MajorVersion;

+  UINT16  MinorVersion;

+  UINT32  Name;

+  UINT32  Base;

+  UINT32  NumberOfFunctions;

+  UINT32  NumberOfNames;

+  UINT32  AddressOfFunctions;

+  UINT32  AddressOfNames;

+  UINT32  AddressOfNameOrdinals;

+} EFI_IMAGE_EXPORT_DIRECTORY;

+

+///

+/// DLL support.

+/// Import Format

+///

+typedef struct {

+  UINT16  Hint;

+  UINT8   Name[1];

+} EFI_IMAGE_IMPORT_BY_NAME;

+

+typedef struct {

+  union {

+    UINT32                    Function;

+    UINT32                    Ordinal;

+    EFI_IMAGE_IMPORT_BY_NAME  *AddressOfData;

+  } u1;

+} EFI_IMAGE_THUNK_DATA;

+

+#define EFI_IMAGE_ORDINAL_FLAG              0x80000000

+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal)  ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)

+#define EFI_IMAGE_ORDINAL(Ordinal)          (Ordinal & 0xffff)

+

+typedef struct {

+  UINT32                Characteristics;

+  UINT32                TimeDateStamp;

+  UINT32                ForwarderChain;

+  UINT32                Name;

+  EFI_IMAGE_THUNK_DATA  *FirstThunk;

+} EFI_IMAGE_IMPORT_DESCRIPTOR;

+

+///

+/// Debug Format

+///

+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2

+

+typedef struct {

+  UINT32  Characteristics;

+  UINT32  TimeDateStamp;

+  UINT16  MajorVersion;

+  UINT16  MinorVersion;

+  UINT32  Type;

+  UINT32  SizeOfData;

+  UINT32  RVA;

+  UINT32  FileOffset;

+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;

+

+#define CODEVIEW_SIGNATURE_NB10 0x3031424E  // "NB10"

+typedef struct {

+  UINT32  Signature;                        // "NB10"

+  UINT32  Unknown;

+  UINT32  Unknown2;

+  UINT32  Unknown3;

+  //

+  // Filename of .PDB goes here

+  //

+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;

+

+#define CODEVIEW_SIGNATURE_RSDS 0x53445352  // "RSDS"

+typedef struct {

+  UINT32  Signature;                        // "RSDS"

+  UINT32  Unknown;

+  UINT32  Unknown2;

+  UINT32  Unknown3;

+  UINT32  Unknown4;

+  UINT32  Unknown5;

+  //

+  // Filename of .PDB goes here

+  //

+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;

+

+///

+/// Header format for TE images

+///

+typedef struct {

+  UINT16                    Signature;            // signature for TE format = "VZ"

+  UINT16                    Machine;              // from the original file header

+  UINT8                     NumberOfSections;     // from the original file header

+  UINT8                     Subsystem;            // from original optional header

+  UINT16                    StrippedSize;         // how many bytes we removed from the header

+  UINT32                    AddressOfEntryPoint;  // offset to entry point -- from original optional header

+  UINT32                    BaseOfCode;           // from original image -- required for ITP debug

+  UINT64                    ImageBase;            // from original file header

+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[2];     // only base relocation and debug directory

+} EFI_TE_IMAGE_HEADER;

+

+#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56      // "VZ"

+

+//

+// Data directory indexes in our TE image header

+//

+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC  0

+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG      1

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/FirmwareFileSystem.h b/edk2/MdePkg/Include/Common/FirmwareFileSystem.h
new file mode 100644
index 0000000..5678a95
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/FirmwareFileSystem.h
@@ -0,0 +1,98 @@
+/** @file

+  This file defines the data structures that comprise the FFS file system.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FirmwareFileSystem.h

+

+  @par Revision Reference:

+  These definitions are from Firmware File System Spec 0.9.

+

+**/

+

+#ifndef __EFI_FFS_FILE_SYSTEM_H__

+#define __EFI_FFS_FILE_SYSTEM_H__

+

+///

+/// FFS specific file types

+///

+#define EFI_FV_FILETYPE_FFS_PAD 0xF0

+

+//

+// FFS File Attributes

+//

+#define FFS_ATTRIB_TAIL_PRESENT     0x01

+#define FFS_ATTRIB_RECOVERY         0x02

+#define FFS_ATTRIB_HEADER_EXTENSION 0x04

+#define FFS_ATTRIB_DATA_ALIGNMENT   0x38

+#define FFS_ATTRIB_CHECKSUM         0x40

+

+///

+/// FFS_FIXED_CHECKSUM is the default checksum value used when the

+/// FFS_ATTRIB_CHECKSUM attribute bit is clear

+/// note this is NOT an architecturally defined value, but is in this file for

+/// implementation convenience

+///

+#define FFS_FIXED_CHECKSUM  0x5A

+

+//

+// File state definitions

+//

+#define EFI_FILE_HEADER_CONSTRUCTION  0x01

+#define EFI_FILE_HEADER_VALID         0x02

+#define EFI_FILE_DATA_VALID           0x04

+#define EFI_FILE_MARKED_FOR_UPDATE    0x08

+#define EFI_FILE_DELETED              0x10

+#define EFI_FILE_HEADER_INVALID       0x20

+

+#define EFI_FILE_ALL_STATE_BITS       (EFI_FILE_HEADER_CONSTRUCTION | \

+                                 EFI_FILE_HEADER_VALID | \

+                                 EFI_FILE_DATA_VALID | \

+                                 EFI_FILE_MARKED_FOR_UPDATE | \

+                                 EFI_FILE_DELETED | \

+                                 EFI_FILE_HEADER_INVALID \

+          )

+

+#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \

+    ( \

+      (BOOLEAN) ( \

+          (FvbAttributes & EFI_FVB_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \

+        ) \

+    )

+

+typedef UINT16  EFI_FFS_FILE_TAIL;

+

+///

+/// FFS file integrity check structure

+///

+typedef union {

+  struct {

+    UINT8 Header;

+    UINT8 File;

+  } Checksum;

+  UINT16  TailReference;

+} EFI_FFS_INTEGRITY_CHECK;

+

+//

+// FFS file header definition

+//

+typedef UINT8 EFI_FFS_FILE_ATTRIBUTES;

+typedef UINT8 EFI_FFS_FILE_STATE;

+

+typedef struct {

+  EFI_GUID                Name;

+  EFI_FFS_INTEGRITY_CHECK IntegrityCheck;

+  EFI_FV_FILETYPE         Type;

+  EFI_FFS_FILE_ATTRIBUTES Attributes;

+  UINT8                   Size[3];

+  EFI_FFS_FILE_STATE      State;

+} EFI_FFS_FILE_HEADER;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/FirmwareVolumeHeader.h b/edk2/MdePkg/Include/Common/FirmwareVolumeHeader.h
new file mode 100644
index 0000000..038dce6
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/FirmwareVolumeHeader.h
@@ -0,0 +1,109 @@
+/** @file

+  Defines data structure that is the volume header found at the beginning of

+  all firmware volumes that are either memory mapped, or have an

+  associated FirmwareVolumeBlock protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FirmwareVolumeHeader.h

+

+  @par Revision Reference:

+  These definitions are from Firmware Volume Block Spec 0.9.

+

+**/

+

+#ifndef __EFI_FIRMWARE_VOLUME_HEADER_H__

+#define __EFI_FIRMWARE_VOLUME_HEADER_H__

+

+//

+// Firmware Volume Block Attributes definition

+//

+typedef UINT32  EFI_FVB_ATTRIBUTES;

+

+//

+// Firmware Volume Block Attributes bit definitions

+//

+#define EFI_FVB_READ_DISABLED_CAP   0x00000001

+#define EFI_FVB_READ_ENABLED_CAP    0x00000002

+#define EFI_FVB_READ_STATUS         0x00000004

+

+#define EFI_FVB_WRITE_DISABLED_CAP  0x00000008

+#define EFI_FVB_WRITE_ENABLED_CAP   0x00000010

+#define EFI_FVB_WRITE_STATUS        0x00000020

+

+#define EFI_FVB_LOCK_CAP            0x00000040

+#define EFI_FVB_LOCK_STATUS         0x00000080

+

+#define EFI_FVB_STICKY_WRITE        0x00000200

+#define EFI_FVB_MEMORY_MAPPED       0x00000400

+#define EFI_FVB_ERASE_POLARITY      0x00000800

+

+#define EFI_FVB_ALIGNMENT_CAP       0x00008000

+#define EFI_FVB_ALIGNMENT_2         0x00010000

+#define EFI_FVB_ALIGNMENT_4         0x00020000

+#define EFI_FVB_ALIGNMENT_8         0x00040000

+#define EFI_FVB_ALIGNMENT_16        0x00080000

+#define EFI_FVB_ALIGNMENT_32        0x00100000

+#define EFI_FVB_ALIGNMENT_64        0x00200000

+#define EFI_FVB_ALIGNMENT_128       0x00400000

+#define EFI_FVB_ALIGNMENT_256       0x00800000

+#define EFI_FVB_ALIGNMENT_512       0x01000000

+#define EFI_FVB_ALIGNMENT_1K        0x02000000

+#define EFI_FVB_ALIGNMENT_2K        0x04000000

+#define EFI_FVB_ALIGNMENT_4K        0x08000000

+#define EFI_FVB_ALIGNMENT_8K        0x10000000

+#define EFI_FVB_ALIGNMENT_16K       0x20000000

+#define EFI_FVB_ALIGNMENT_32K       0x40000000

+#define EFI_FVB_ALIGNMENT_64K       0x80000000

+

+#define EFI_FVB_CAPABILITIES  (EFI_FVB_READ_DISABLED_CAP | \

+                              EFI_FVB_READ_ENABLED_CAP | \

+                              EFI_FVB_WRITE_DISABLED_CAP | \

+                              EFI_FVB_WRITE_ENABLED_CAP | \

+                              EFI_FVB_LOCK_CAP \

+                              )

+

+#define EFI_FVB_STATUS    (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS)

+

+///

+/// Firmware Volume Header Revision definition

+///

+#define EFI_FVH_REVISION  0x01

+

+///

+/// Firmware Volume Header Signature definition

+///

+#define EFI_FVH_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', 'H')

+

+///

+/// Firmware Volume Header Block Map Entry definition

+///

+typedef struct {

+  UINT32  NumBlocks;

+  UINT32  BlockLength;

+} EFI_FV_BLOCK_MAP_ENTRY;

+

+///

+/// Firmware Volume Header definition

+///

+typedef struct {

+  UINT8                   ZeroVector[16];

+  EFI_GUID                FileSystemGuid;

+  UINT64                  FvLength;

+  UINT32                  Signature;

+  EFI_FVB_ATTRIBUTES      Attributes;

+  UINT16                  HeaderLength;

+  UINT16                  Checksum;

+  UINT8                   Reserved[3];

+  UINT8                   Revision;

+  EFI_FV_BLOCK_MAP_ENTRY  FvBlockMap[1];

+} EFI_FIRMWARE_VOLUME_HEADER;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/FirmwareVolumeImageFormat.h b/edk2/MdePkg/Include/Common/FirmwareVolumeImageFormat.h
new file mode 100644
index 0000000..14fa41b
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/FirmwareVolumeImageFormat.h
@@ -0,0 +1,277 @@
+/** @file

+  This file defines the data structures that are architecturally defined for file

+  images loaded via the FirmwareVolume protocol.  The Firmware Volume specification

+  is the basis for these definitions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FimrwareVolumeImageFormat.h

+

+  @par Revision Reference:

+  These definitions are from Firmware Volume Spec 0.9.

+

+**/

+

+#ifndef __FIRMWARE_VOLUME_IMAGE_FORMAT_H__

+#define __FIRMWARE_VOLUME_IMAGE_FORMAT_H__

+

+//

+// pack all data structures since this is actually a binary format and we cannot

+// allow internal padding in the data structures because of some compilerism..

+//

+#pragma pack(1)

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Architectural file types

+//

+typedef UINT8 EFI_FV_FILETYPE;

+

+#define EFI_FV_FILETYPE_ALL                   0x00

+#define EFI_FV_FILETYPE_RAW                   0x01

+#define EFI_FV_FILETYPE_FREEFORM              0x02

+#define EFI_FV_FILETYPE_SECURITY_CORE         0x03

+#define EFI_FV_FILETYPE_PEI_CORE              0x04

+#define EFI_FV_FILETYPE_DXE_CORE              0x05

+#define EFI_FV_FILETYPE_PEIM                  0x06

+#define EFI_FV_FILETYPE_DRIVER                0x07

+#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER  0x08

+#define EFI_FV_FILETYPE_APPLICATION           0x09

+//

+// File type 0x0A is reserved and should not be used

+//

+#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Section types

+//

+typedef UINT8 EFI_SECTION_TYPE;

+

+//

+// ************************************************************

+// The section type EFI_SECTION_ALL is a psuedo type.  It is

+// used as a wildcard when retrieving sections.  The section

+// type EFI_SECTION_ALL matches all section types.

+// ************************************************************

+//

+#define EFI_SECTION_ALL 0x00

+

+//

+// ************************************************************

+// Encapsulation section Type values

+// ************************************************************

+//

+#define EFI_SECTION_COMPRESSION   0x01

+#define EFI_SECTION_GUID_DEFINED  0x02

+

+//

+// ************************************************************

+// Leaf section Type values

+// ************************************************************

+//

+#define EFI_SECTION_FIRST_LEAF_SECTION_TYPE 0x10

+

+#define EFI_SECTION_PE32                    0x10

+#define EFI_SECTION_PIC                     0x11

+#define EFI_SECTION_TE                      0x12

+#define EFI_SECTION_DXE_DEPEX               0x13

+#define EFI_SECTION_VERSION                 0x14

+#define EFI_SECTION_USER_INTERFACE          0x15

+#define EFI_SECTION_COMPATIBILITY16         0x16

+#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE   0x17

+#define EFI_SECTION_FREEFORM_SUBTYPE_GUID   0x18

+#define EFI_SECTION_RAW                     0x19

+#define EFI_SECTION_PEI_DEPEX               0x1B

+

+#define EFI_SECTION_LAST_LEAF_SECTION_TYPE  0x1B

+#define EFI_SECTION_LAST_SECTION_TYPE       0x1B

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Common section header

+//

+typedef struct {

+  UINT8 Size[3];

+  UINT8 Type;

+} EFI_COMMON_SECTION_HEADER;

+

+#define SECTION_SIZE(SectionHeaderPtr) \

+    ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) SectionHeaderPtr)->Size) & 0x00ffffff))

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Compression section

+//

+//

+// CompressionType values

+//

+#define EFI_NOT_COMPRESSED          0x00

+#define EFI_STANDARD_COMPRESSION    0x01

+#define EFI_CUSTOMIZED_COMPRESSION  0x02

+

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+  UINT32                    UncompressedLength;

+  UINT8                     CompressionType;

+} EFI_COMPRESSION_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// GUID defined section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+  EFI_GUID                  SectionDefinitionGuid;

+  UINT16                    DataOffset;

+  UINT16                    Attributes;

+} EFI_GUID_DEFINED_SECTION;

+

+//

+// Bit values for Attributes

+//

+#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED  0x01

+#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID    0x02

+

+//

+// Bit values for AuthenticationStatus

+//

+#define EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE 0x000001

+#define EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED      0x000002

+#define EFI_AGGREGATE_AUTH_STATUS_NOT_TESTED        0x000004

+#define EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED       0x000008

+#define EFI_AGGREGATE_AUTH_STATUS_ALL               0x00000f

+

+#define EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE     0x010000

+#define EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED          0x020000

+#define EFI_LOCAL_AUTH_STATUS_NOT_TESTED            0x040000

+#define EFI_LOCAL_AUTH_STATUS_TEST_FAILED           0x080000

+#define EFI_LOCAL_AUTH_STATUS_ALL                   0x0f0000

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// PE32+ section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_PE32_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// PIC section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_PIC_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// PEIM header section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_PEIM_HEADER_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// DEPEX section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_DEPEX_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Version section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+  UINT16                    BuildNumber;

+  INT16                     VersionString[1];

+} EFI_VERSION_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// User interface section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+  INT16                     FileNameString[1];

+} EFI_USER_INTERFACE_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Code16 section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_CODE16_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Firmware Volume Image section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_FIRMWARE_VOLUME_IMAGE_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Freeform subtype GUID section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+  EFI_GUID                  SubTypeGuid;

+} EFI_FREEFORM_SUBTYPE_GUID_SECTION;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+// Raw section

+//

+typedef struct {

+  EFI_COMMON_SECTION_HEADER CommonHeader;

+} EFI_RAW_SECTION;

+

+//

+// undo the pragma from the beginning...

+//

+#pragma pack()

+

+typedef union {

+  EFI_COMMON_SECTION_HEADER         *CommonHeader;

+  EFI_COMPRESSION_SECTION           *CompressionSection;

+  EFI_GUID_DEFINED_SECTION          *GuidDefinedSection;

+  EFI_PE32_SECTION                  *Pe32Section;

+  EFI_PIC_SECTION                   *PicSection;

+  EFI_PEIM_HEADER_SECTION           *PeimHeaderSection;

+  EFI_DEPEX_SECTION                 *DependencySection;

+  EFI_VERSION_SECTION               *VersionSection;

+  EFI_USER_INTERFACE_SECTION        *UISection;

+  EFI_CODE16_SECTION                *Code16Section;

+  EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FVImageSection;

+  EFI_FREEFORM_SUBTYPE_GUID_SECTION *FreeformSubtypeSection;

+  EFI_RAW_SECTION                   *RawSection;

+} EFI_FILE_SECTION_POINTER;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/Hob.h b/edk2/MdePkg/Include/Common/Hob.h
new file mode 100644
index 0000000..b6ae6de
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/Hob.h
@@ -0,0 +1,235 @@
+/** @file

+  Hand Off Block (HOB) definition.

+

+  The HOB is a memory data structure used to hand-off system information from

+  PEI to DXE (the next phase).

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Hob.h

+

+  @par Revision Reference:

+  These definitions are from Hand Off Block (HOB) Spec Version 0.9.

+

+**/

+

+#ifndef __HOB_H__

+#define __HOB_H__

+

+

+//

+// Every Hob must start with this data structure.

+//

+typedef struct {

+  UINT16  HobType;

+  UINT16  HobLength;

+  UINT32  Reserved;

+} EFI_HOB_GENERIC_HEADER;

+

+//

+// End of HOB List HOB

+//

+#define EFI_HOB_TYPE_END_OF_HOB_LIST  0xffff

+

+//

+// Handoff Information Table HOB

+//

+#define EFI_HOB_TYPE_HANDOFF          0x0001

+

+#define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009

+

+typedef UINT32  EFI_BOOT_MODE;

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+  UINT32                  Version;

+  EFI_BOOT_MODE           BootMode;

+  EFI_PHYSICAL_ADDRESS    EfiMemoryTop;

+  EFI_PHYSICAL_ADDRESS    EfiMemoryBottom;

+  EFI_PHYSICAL_ADDRESS    EfiFreeMemoryTop;

+  EFI_PHYSICAL_ADDRESS    EfiFreeMemoryBottom;

+  EFI_PHYSICAL_ADDRESS    EfiEndOfHobList;

+} EFI_HOB_HANDOFF_INFO_TABLE;

+

+//

+// Memory Descriptor HOB

+//

+#define EFI_HOB_TYPE_MEMORY_ALLOCATION  0x0002

+

+typedef struct {

+  EFI_GUID              Name;

+  EFI_PHYSICAL_ADDRESS  MemoryBaseAddress;

+  UINT64                MemoryLength;

+  EFI_MEMORY_TYPE       MemoryType;

+  UINT8                 Reserved[4];

+} EFI_HOB_MEMORY_ALLOCATION_HEADER;

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER            Header;

+  EFI_HOB_MEMORY_ALLOCATION_HEADER  AllocDescriptor;

+  //

+  // Additional data pertaining to the "Name" Guid memory

+  // may go here.

+  //

+} EFI_HOB_MEMORY_ALLOCATION;

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER            Header;

+  EFI_HOB_MEMORY_ALLOCATION_HEADER  AllocDescriptor;

+} EFI_HOB_MEMORY_ALLOCATION_BSP_STORE;

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER            Header;

+  EFI_HOB_MEMORY_ALLOCATION_HEADER  AllocDescriptor;

+} EFI_HOB_MEMORY_ALLOCATION_STACK;

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER            Header;

+  EFI_HOB_MEMORY_ALLOCATION_HEADER  MemoryAllocationHeader;

+  EFI_GUID                          ModuleName;

+  EFI_PHYSICAL_ADDRESS              EntryPoint;

+} EFI_HOB_MEMORY_ALLOCATION_MODULE;

+

+#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR  0x0003

+

+typedef UINT32  EFI_RESOURCE_TYPE;

+

+#define EFI_RESOURCE_SYSTEM_MEMORY          0

+#define EFI_RESOURCE_MEMORY_MAPPED_IO       1

+#define EFI_RESOURCE_IO                     2

+#define EFI_RESOURCE_FIRMWARE_DEVICE        3

+#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT  4

+#define EFI_RESOURCE_MEMORY_RESERVED        5

+#define EFI_RESOURCE_IO_RESERVED            6

+#define EFI_RESOURCE_MAX_MEMORY_TYPE        7

+

+typedef UINT32  EFI_RESOURCE_ATTRIBUTE_TYPE;

+

+#define EFI_RESOURCE_ATTRIBUTE_PRESENT                  0x00000001

+#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED              0x00000002

+#define EFI_RESOURCE_ATTRIBUTE_TESTED                   0x00000004

+#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC           0x00000008

+#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC         0x00000010

+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1           0x00000020

+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2           0x00000040

+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED           0x00000080

+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED          0x00000100

+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED      0x00000200

+#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE              0x00000400

+#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE        0x00000800

+#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE  0x00001000

+#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE     0x00002000

+#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO                0x00004000

+#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO                0x00008000

+#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO                0x00010000

+#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED        0x00020000

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER      Header;

+  EFI_GUID                    Owner;

+  EFI_RESOURCE_TYPE           ResourceType;

+  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;

+  EFI_PHYSICAL_ADDRESS        PhysicalStart;

+  UINT64                      ResourceLength;

+} EFI_HOB_RESOURCE_DESCRIPTOR;

+

+//

+// GUID Extension HOB

+// The HobLength is variable as it includes the GUID specific data.

+//

+#define EFI_HOB_TYPE_GUID_EXTENSION 0x0004

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+  EFI_GUID                Name;

+

+  //

+  // Guid specific data goes here

+  //

+} EFI_HOB_GUID_TYPE;

+

+//

+// Firmware Volume HOB

+//

+#define EFI_HOB_TYPE_FV 0x0005

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+  EFI_PHYSICAL_ADDRESS    BaseAddress;

+  UINT64                  Length;

+} EFI_HOB_FIRMWARE_VOLUME;

+

+//

+// CPU HOB

+//

+#define EFI_HOB_TYPE_CPU  0x0006

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+  UINT8                   SizeOfMemorySpace;

+  UINT8                   SizeOfIoSpace;

+  UINT8                   Reserved[6];

+} EFI_HOB_CPU;

+

+//

+// PEI Core Memory Pool HOB

+// The HobLength is variable as the HOB contains pool allocations by

+// the PeiServices AllocatePool function

+//

+#define EFI_HOB_TYPE_PEI_MEMORY_POOL  0x0007

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+} EFI_HOB_MEMORY_POOL;

+

+//

+// Capsule volume HOB -- identical to a firmware volume

+//

+#define EFI_HOB_TYPE_CV 0x0008

+

+typedef struct {

+  EFI_HOB_GENERIC_HEADER  Header;

+  EFI_PHYSICAL_ADDRESS    BaseAddress;

+  UINT64                  Length;

+} EFI_HOB_CAPSULE_VOLUME;

+

+#define EFI_HOB_TYPE_UNUSED 0xFFFE

+

+//

+// Union of all the possible HOB Types

+//

+typedef union {

+  EFI_HOB_GENERIC_HEADER              *Header;

+  EFI_HOB_HANDOFF_INFO_TABLE          *HandoffInformationTable;

+  EFI_HOB_MEMORY_ALLOCATION           *MemoryAllocation;

+  EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore;

+  EFI_HOB_MEMORY_ALLOCATION_STACK     *MemoryAllocationStack;

+  EFI_HOB_MEMORY_ALLOCATION_MODULE    *MemoryAllocationModule;

+  EFI_HOB_RESOURCE_DESCRIPTOR         *ResourceDescriptor;

+  EFI_HOB_GUID_TYPE                   *Guid;

+  EFI_HOB_FIRMWARE_VOLUME             *FirmwareVolume;

+  EFI_HOB_CPU                         *Cpu;

+  EFI_HOB_MEMORY_POOL                 *Pool;

+  EFI_HOB_CAPSULE_VOLUME              *CapsuleVolume;

+  UINT8                               *Raw;

+} EFI_PEI_HOB_POINTERS;

+

+#define GET_HOB_TYPE(Hob)     ((Hob).Header->HobType)

+#define GET_HOB_LENGTH(Hob)   ((Hob).Header->HobLength)

+#define GET_NEXT_HOB(Hob)     ((Hob).Raw + GET_HOB_LENGTH (Hob))

+#define END_OF_HOB_LIST(Hob)  (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST)

+

+//

+// Get the data and data size field of GUID 

+//

+#define GET_GUID_HOB_DATA(GuidHob)      ((VOID *) (((UINT8 *) &((GuidHob)->Name)) + sizeof (EFI_GUID)))

+#define GET_GUID_HOB_DATA_SIZE(GuidHob) (((GuidHob)->Header).HobLength - sizeof (EFI_HOB_GUID_TYPE))

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/InternalFormRepresentation.h b/edk2/MdePkg/Include/Common/InternalFormRepresentation.h
new file mode 100644
index 0000000..bf3d824
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/InternalFormRepresentation.h
@@ -0,0 +1,422 @@
+/** @file

+  This file defines the encoding for the VFR (Visual Form Representation) language.

+  IFR is primarily consumed by the EFI presentation engine, and produced by EFI

+  internal application and drivers as well as all add-in card option-ROM drivers

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  InternalFormRepresentation.h

+

+  @par Revision Reference:

+  These definitions are from Human Interface Infrastructure Spec Version 0.92.

+

+**/

+

+#ifndef __EFI_INTERNAL_FORM_REPRESENTATION_H__

+#define __EFI_INTERNAL_FORM_REPRESENTATION_H__

+

+//

+// The following types are currently defined:

+//

+typedef UINT32  RELOFST;

+typedef CHAR16  *EFI_STRING;

+

+//

+// IFR Op codes

+//

+#define EFI_IFR_FORM_OP                 0x01

+#define EFI_IFR_SUBTITLE_OP             0x02

+#define EFI_IFR_TEXT_OP                 0x03

+#define EFI_IFR_GRAPHIC_OP              0x04

+#define EFI_IFR_ONE_OF_OP               0x05

+#define EFI_IFR_CHECKBOX_OP             0x06

+#define EFI_IFR_NUMERIC_OP              0x07

+#define EFI_IFR_PASSWORD_OP             0x08

+#define EFI_IFR_ONE_OF_OPTION_OP        0x09  // ONEOF OPTION field

+#define EFI_IFR_SUPPRESS_IF_OP          0x0A

+#define EFI_IFR_END_FORM_OP             0x0B

+#define EFI_IFR_HIDDEN_OP               0x0C

+#define EFI_IFR_END_FORM_SET_OP         0x0D

+#define EFI_IFR_FORM_SET_OP             0x0E

+#define EFI_IFR_REF_OP                  0x0F

+#define EFI_IFR_END_ONE_OF_OP           0x10

+#define EFI_IFR_END_OP                  EFI_IFR_END_ONE_OF_OP

+#define EFI_IFR_INCONSISTENT_IF_OP      0x11

+#define EFI_IFR_EQ_ID_VAL_OP            0x12

+#define EFI_IFR_EQ_ID_ID_OP             0x13

+#define EFI_IFR_EQ_ID_LIST_OP           0x14

+#define EFI_IFR_AND_OP                  0x15

+#define EFI_IFR_OR_OP                   0x16

+#define EFI_IFR_NOT_OP                  0x17

+#define EFI_IFR_END_IF_OP               0x18  // for endif of inconsistentif, suppressif, grayoutif

+#define EFI_IFR_GRAYOUT_IF_OP           0x19

+#define EFI_IFR_DATE_OP                 0x1A

+#define EFI_IFR_TIME_OP                 0x1B

+#define EFI_IFR_STRING_OP               0x1C

+#define EFI_IFR_LABEL_OP                0x1D

+#define EFI_IFR_SAVE_DEFAULTS_OP        0x1E

+#define EFI_IFR_RESTORE_DEFAULTS_OP     0x1F

+#define EFI_IFR_BANNER_OP               0x20

+#define EFI_IFR_INVENTORY_OP            0x21

+#define EFI_IFR_EQ_VAR_VAL_OP           0x22

+#define EFI_IFR_ORDERED_LIST_OP         0x23

+#define EFI_IFR_VARSTORE_OP             0x24

+#define EFI_IFR_VARSTORE_SELECT_OP      0x25

+#define EFI_IFR_VARSTORE_SELECT_PAIR_OP 0x26

+#define EFI_IFR_TRUE_OP                 0x27

+#define EFI_IFR_FALSE_OP                0x28

+#define EFI_IFR_GT_OP                   0x29

+#define EFI_IFR_GE_OP                   0x2A

+#define EFI_IFR_OEM_DEFINED_OP          0x2B

+#define EFI_IFR_LAST_OPCODE             EFI_IFR_OEM_DEFINED_OP

+#define EFI_IFR_OEM_OP                  0xFE

+#define EFI_IFR_NV_ACCESS_COMMAND       0xFF

+

+//

+// Define values for the flags fields in some VFR opcodes. These are

+// bitmasks.

+//

+#define EFI_IFR_FLAG_DEFAULT              0x01

+#define EFI_IFR_FLAG_MANUFACTURING        0x02

+#define EFI_IFR_FLAG_INTERACTIVE          0x04

+#define EFI_IFR_FLAG_NV_ACCESS            0x08

+#define EFI_IFR_FLAG_RESET_REQUIRED       0x10

+#define EFI_IFR_FLAG_LATE_CHECK           0x20

+

+#define EFI_NON_DEVICE_CLASS              0x00  // Useful when you do not want something in the Device Manager

+#define EFI_DISK_DEVICE_CLASS             0x01

+#define EFI_VIDEO_DEVICE_CLASS            0x02

+#define EFI_NETWORK_DEVICE_CLASS          0x04

+#define EFI_INPUT_DEVICE_CLASS            0x08

+#define EFI_ON_BOARD_DEVICE_CLASS         0x10

+#define EFI_OTHER_DEVICE_CLASS            0x20

+

+#define EFI_SETUP_APPLICATION_SUBCLASS    0x00

+#define EFI_GENERAL_APPLICATION_SUBCLASS  0x01

+#define EFI_FRONT_PAGE_SUBCLASS           0x02

+#define EFI_SINGLE_USE_SUBCLASS           0x03  // Used to display a single entity and then exit

+

+//

+// Used to flag dynamically created op-codes. This is meaningful to the IFR Library set

+// and the browser since we need to distinguish between compiled NV map data and created data.

+// We do not allow new entries to be created in the NV map dynamically however we still need

+// to display this information correctly.  To dynamically create op-codes and assume that their

+// data will be saved, ensure that the NV starting location they refer to is pre-defined in the

+// NV map.

+//

+#define EFI_IFR_FLAG_CREATED  128

+

+#pragma pack(1)

+//

+// IFR Structure definitions

+//

+typedef struct {

+  UINT8 OpCode;

+  UINT8 Length;

+} EFI_IFR_OP_HEADER;

+

+typedef struct {

+  EFI_IFR_OP_HEADER     Header;

+  EFI_GUID              Guid;

+  STRING_REF            FormSetTitle;

+  STRING_REF            Help;

+  EFI_PHYSICAL_ADDRESS  CallbackHandle;

+  UINT16                Class;

+  UINT16                SubClass;

+  UINT16                NvDataSize; // set once, size of the NV data as defined in the script

+} EFI_IFR_FORM_SET;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            FormId;

+  STRING_REF        FormTitle;

+} EFI_IFR_FORM;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            LabelId;

+} EFI_IFR_LABEL;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  STRING_REF        SubTitle;

+} EFI_IFR_SUBTITLE;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  STRING_REF        Help;

+  STRING_REF        Text;

+  STRING_REF        TextTwo;

+  UINT8             Flags;          // This is included solely for purposes of interactive/dynamic support.

+  UINT16            Key;            // Value to be passed to caller to identify this particular op-code

+} EFI_IFR_TEXT;

+

+//

+// goto

+//

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            FormId;

+  STRING_REF        Prompt;

+  STRING_REF        Help;   // The string Token for the context-help

+  UINT8             Flags;  // This is included solely for purposes of interactive/dynamic support.

+  UINT16            Key;    // Value to be passed to caller to identify this particular op-code

+} EFI_IFR_REF;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_END_FORM;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_END_FORM_SET;

+

+//

+// Also notice that the IFR_ONE_OF and IFR_CHECK_BOX are identical in structure......code assumes this to be true, if this ever

+// changes we need to revisit the InitializeTagStructures code

+//

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name

+  UINT8             Width;      // The Size of the Data being saved

+  STRING_REF        Prompt;     // The String Token for the Prompt

+  STRING_REF        Help;       // The string Token for the context-help

+} EFI_IFR_ONE_OF;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId; // The offset in NV for storage of the data

+  UINT8             MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)

+  STRING_REF        Prompt;     // The string token for the prompt

+  STRING_REF        Help;       // The string token for the context-help

+} EFI_IFR_ORDERED_LIST;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name

+  UINT8             Width;      // The Size of the Data being saved

+  STRING_REF        Prompt;     // The String Token for the Prompt

+  STRING_REF        Help;       // The string Token for the context-help

+  UINT8             Flags;      // For now, if non-zero, means that it is the default option, - further definition likely

+  UINT16            Key;        // Value to be passed to caller to identify this particular op-code

+} EFI_IFR_CHECKBOX, EFI_IFR_CHECK_BOX;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  STRING_REF        Option;     // The string token describing the option

+  UINT16            Value;      // The value associated with this option that is stored in the NVRAM if chosen

+  UINT8             Flags;      // For now, if non-zero, means that it is the default option, - further definition likely above

+  UINT16            Key;        // Value to be passed to caller to identify this particular op-code

+} EFI_IFR_ONE_OF_OPTION;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name

+  UINT8             Width;      // The Size of the Data being saved

+  STRING_REF        Prompt;     // The String Token for the Prompt

+  STRING_REF        Help;       // The string Token for the context-help

+  UINT8             Flags;      // This is included solely for purposes of interactive/dynamic support.

+  UINT16            Key;        // Value to be passed to caller to identify this particular op-code

+  UINT16            Minimum;

+  UINT16            Maximum;

+  UINT16            Step;       // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for

+  UINT16            Default;

+} EFI_IFR_NUMERIC;

+

+//

+// There is an interesting twist with regards to Time and Date.  This is one of the few items which can accept input from

+// a user, however may or may not need to use storage in the NVRAM space.  The decided method for determining if NVRAM space

+// will be used (only for a TimeOp or DateOp) is:  If .QuestionId == 0 && .Width == 0 (normally an impossibility) then use system

+// resources to store the data away and not NV resources.  In other words, the setup engine will call gRT->SetTime, and gRT->SetDate

+// for the saving of data, and the values displayed will be from the gRT->GetXXXX series of calls.

+//

+typedef struct {

+  EFI_IFR_NUMERIC Hour;

+  EFI_IFR_NUMERIC Minute;

+  EFI_IFR_NUMERIC Second;

+} EFI_IFR_TIME;

+

+typedef struct {

+  EFI_IFR_NUMERIC Year;

+  EFI_IFR_NUMERIC Month;

+  EFI_IFR_NUMERIC Day;

+} EFI_IFR_DATE;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId;   // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name

+  UINT8             Width;        // The Size of the Data being saved -- BUGBUG -- remove someday

+  STRING_REF        Prompt;       // The String Token for the Prompt

+  STRING_REF        Help;         // The string Token for the context-help

+  UINT8             Flags;        // This is included solely for purposes of interactive/dynamic support.

+  UINT16            Key;          // Value to be passed to caller to identify this particular op-code

+  UINT8             MinSize;      // Minimum allowable sized password

+  UINT8             MaxSize;      // Maximum allowable sized password

+  UINT16            Encoding;

+} EFI_IFR_PASSWORD;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId;   // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name

+  UINT8             Width;        // The Size of the Data being saved -- BUGBUG -- remove someday

+  STRING_REF        Prompt;       // The String Token for the Prompt

+  STRING_REF        Help;         // The string Token for the context-help

+  UINT8             Flags;        // This is included solely for purposes of interactive/dynamic support.

+  UINT16            Key;          // Value to be passed to caller to identify this particular op-code

+  UINT8             MinSize;      // Minimum allowable sized password

+  UINT8             MaxSize;      // Maximum allowable sized password

+} EFI_IFR_STRING;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_END_ONE_OF;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            Value;

+  UINT16            Key;

+} EFI_IFR_HIDDEN;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT8             Flags;

+} EFI_IFR_SUPPRESS;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT8             Flags;

+} EFI_IFR_GRAY_OUT;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  STRING_REF        Popup;

+  UINT8             Flags;

+} EFI_IFR_INCONSISTENT;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId;   // offset into variable storage

+  UINT8             Width;        // size of variable storage

+  UINT16            Value;        // value to compare against

+} EFI_IFR_EQ_ID_VAL;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId;   // offset into variable storage

+  UINT8             Width;        // size of variable storage

+  UINT16            ListLength;

+  UINT16            ValueList[1];

+} EFI_IFR_EQ_ID_LIST;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId1;  // offset into variable storage for first value to compare

+  UINT8             Width;        // size of variable storage (must be same for both)

+  UINT16            QuestionId2;  // offset into variable storage for second value to compare

+} EFI_IFR_EQ_ID_ID;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            VariableId;   // offset into variable storage

+  UINT16            Value;        // value to compare against

+} EFI_IFR_EQ_VAR_VAL;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_AND;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_OR;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_NOT;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_END_EXPR, EFI_IFR_END_IF;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            FormId;

+  STRING_REF        Prompt;

+  STRING_REF        Help;

+  UINT8             Flags;

+  UINT16            Key;

+} EFI_IFR_SAVE_DEFAULTS;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  STRING_REF        Help;

+  STRING_REF        Text;

+  STRING_REF        TextTwo;      // optional text

+} EFI_IFR_INVENTORY;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  EFI_GUID          Guid;         // GUID for the variable

+  UINT16            VarId;        // variable store ID, as referenced elsewhere in the form

+  UINT16            Size;         // size of the variable storage

+} EFI_IFR_VARSTORE;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            VarId;        // variable store ID, as referenced elsewhere in the form

+} EFI_IFR_VARSTORE_SELECT;

+

+//

+// Used for the ideqid VFR statement where two variable stores may be referenced in the

+// same VFR statement.

+// A browser should treat this as an EFI_IFR_VARSTORE_SELECT statement and assume that all following

+// IFR opcodes use the VarId as defined here.

+//

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            VarId;          // variable store ID, as referenced elsewhere in the form

+  UINT16            SecondaryVarId; // variable store ID, as referenced elsewhere in the form

+} EFI_IFR_VARSTORE_SELECT_PAIR;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_TRUE;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_FALSE;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_GT;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+} EFI_IFR_GE;

+

+//

+// Save defaults and restore defaults have same structure

+//

+#define EFI_IFR_RESTORE_DEFAULTS  EFI_IFR_SAVE_DEFAULTS

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  STRING_REF        Title;        // The string token for the banner title

+  UINT16            LineNumber;   // 1-based line number

+  UINT8             Alignment;    // left, center, or right-aligned

+} EFI_IFR_BANNER;

+

+#define EFI_IFR_BANNER_ALIGN_LEFT   0

+#define EFI_IFR_BANNER_ALIGN_CENTER 1

+#define EFI_IFR_BANNER_ALIGN_RIGHT  2

+#define EFI_IFR_BANNER_TIMEOUT      0xFF

+

+#pragma pack()

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/Legacy16.h b/edk2/MdePkg/Include/Common/Legacy16.h
new file mode 100644
index 0000000..1f8b9bf
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/Legacy16.h
@@ -0,0 +1,310 @@
+/** @file

+  API between 16-bit Legacy BIOS and EFI

+

+  We need to figure out what the 16-bit code is going to use to

+  represent these data structures. Is a pointer SEG:OFF or 32-bit...

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.    

+

+  Module Name:  Legacy16.h

+

+  @par Revision Reference:

+  These definitions are from Compatibility Support Module Spec Version 0.96.

+

+**/

+

+#ifndef LEGACY_16_H_

+#define LEGACY_16_H_

+

+#define EFI_TO_LEGACY_MAJOR_VERSION 0x02

+#define EFI_TO_LEGACY_MINOR_VERSION 0x00

+

+#pragma pack(1)

+//

+// EFI Legacy to Legacy16 data

+// EFI_COMPATIBILITY16_TABLE has been moved to LegacyBios protocol defn file.

+//

+typedef struct {

+  //

+  // Memory map used to start up Legacy16 code

+  //

+  UINT32  BiosLessThan1MB;

+  UINT32  HiPmmMemory;

+  UINT32  PmmMemorySizeInBytes;

+

+  UINT16  ReverseThunkCallSegment;

+  UINT16  ReverseThunkCallOffset;

+  UINT32  NumberE820Entries;

+  UINT32  OsMemoryAbove1Mb;

+  UINT32  ThunkStart;

+  UINT32  ThunkSizeInBytes;

+  UINT32  LowPmmMemory;

+  UINT32  LowPmmMemorySizeInBytes;

+} EFI_TO_COMPATIBILITY16_INIT_TABLE;

+

+#pragma pack()

+//

+// Legacy16 Call types

+//

+typedef enum {

+  Legacy16InitializeYourself    = 0x0000,

+  Legacy16UpdateBbs             = 0x0001,

+  Legacy16PrepareToBoot         = 0x0002,

+  Legacy16Boot                  = 0x0003,

+  Legacy16RetrieveLastBootDevice= 0x0004,

+  Legacy16DispatchOprom         = 0x0005,

+  Legacy16GetTableAddress       = 0x0006,

+  Legacy16SetKeyboardLeds       = 0x0007,

+  Legacy16InstallPciHandler     = 0x0008,

+} EFI_COMPATIBILITY_FUNCTIONS;

+

+#define F0000Region 0x01

+#define E0000Region 0x02

+//

+// Legacy16 call prototypes

+//  Input:  AX = EFI_COMPATIBILITY16_FUNCTIONS for all functions.

+//  Output: AX = Return status for all functions. It follows EFI error

+//               codes.

+//

+//  Legacy16InitializeYourself

+//    Description: This is the first call to 16-bit code. It allows the

+//                 16-bit to perform any internal initialization.

+//    Input:  ES:BX pointer to EFI_TO_LEGACY16_INIT_TABLE

+//    Output:

+//  Legacy16UpdateBbs

+//    Description: The 16-bit code updates the BBS table for non-compliant

+//                 devices.

+//    Input:  ES:BX pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE

+//    Output:

+//  Legacy16PrepareToBoot

+//    Description: This is the last call to 16-bit code where 0xE0000 -0xFFFFF

+//                 is read/write. 16-bit code does any final clean up.

+//    Input:  ES:BX pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE

+//    Output:

+//  Legacy16Boot

+//    Description: Do INT19.

+//    Input:

+//    Output:

+//  Legacy16RetrieveLastBootDevice

+//    Description: Return the priority number of the device that booted.

+//    Input:

+//    Output: BX = priority number of the last attempted boot device.

+//  Legacy16DispatchOprom

+//    Description: Pass control to the specified OPROM. Allows the 16-bit

+//                 code to rehook INT 13,18 and/or 19 from non-BBS

+//                 compliant devices.

+//    Input:  ES:DI = Segment:Offset of PnPInstallationCheck

+//            SI = OPROM segment. Offset assumed to be 3.

+//            BH = PCI bus number.

+//            BL = PCI device * 8 | PCI function.

+//    Output: BX = Number of BBS non-compliant drives detected. Return

+//                 zero for BBS compliant devices.

+//  Legacy16GetTableAddress

+//    Description: Allocate an area in the 0xE0000-0xFFFFF region.

+//    Input:  BX = Allocation region.

+//                 0x0 = Any region

+//                 Bit 0 = 0xF0000 region

+//                 Bit 1 = 0xE0000 region

+//                 Multiple bits can be set.

+//            CX = Length in bytes requested

+//            DX = Required address alignment

+//                 Bit mapped. First non-zero bit from right to left is

+//                 alignment.

+//    Output: DS:BX is assigned region.

+//            AX = EFI_OUT_OF_RESOURCES if request cannot be granted.

+//  Legacy16SetKeyboardLeds

+//    Description: Perform any special action when keyboard LEDS change.

+//                 Other code performs the LED change and updates standard

+//                 BDA locations. This is for non-standard operations.

+//    Input:  CL = LED status. 1 = set.

+//                 Bit 0 = Scroll lock

+//                 Bit 1 = Num lock

+//                 Bit 2 = Caps lock

+//    Output:

+//  Legacy16InstallPciHandler

+//    Description: Provides 16-bit code a hook to establish an interrupt

+//                 handler for any PCI device requiring a PCI interrupt

+//                 but having no OPROM. This is called before interrupt

+//                 is assigned. 8259 will be disabled(even if sharded)

+//                 and PCI Interrupt Line unprogrammed. Other code will

+//                 program 8259 and PCI Interrupt Line.

+//    Input:  ES:BX Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER strcture

+//    Output:

+//

+typedef UINT8 SERIAL_MODE;

+typedef UINT8 PARALLEL_MODE;

+

+#pragma pack(1)

+

+#define DEVICE_SERIAL_MODE_NORMAL               0x00

+#define DEVICE_SERIAL_MODE_IRDA                 0x01

+#define DEVICE_SERIAL_MODE_ASK_IR               0x02

+#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00

+#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10

+

+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00

+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01

+#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02

+#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03

+

+typedef struct {

+  UINT16      Address;

+  UINT8       Irq;

+  SERIAL_MODE Mode;

+} DEVICE_PRODUCER_SERIAL;

+

+typedef struct {

+  UINT16        Address;

+  UINT8         Irq;

+  UINT8         Dma;

+  PARALLEL_MODE Mode;

+} DEVICE_PRODUCER_PARALLEL;

+

+typedef struct {

+  UINT16  Address;

+  UINT8   Irq;

+  UINT8   Dma;

+  UINT8   NumberOfFloppy;

+} DEVICE_PRODUCER_FLOPPY;

+

+typedef struct {

+  UINT32  A20Kybd : 1;

+  UINT32  A20Port90 : 1;

+  UINT32  Reserved : 30;

+} LEGACY_DEVICE_FLAGS;

+

+typedef struct {

+  DEVICE_PRODUCER_SERIAL    Serial[4];

+  DEVICE_PRODUCER_PARALLEL  Parallel[3];

+  DEVICE_PRODUCER_FLOPPY    Floppy;

+  UINT8                     MousePresent;

+  LEGACY_DEVICE_FLAGS       Flags;

+} DEVICE_PRODUCER_DATA_HEADER;

+//

+// SMM Table definitions

+// SMM table has a header that provides the number of entries. Following

+// the header is a variable length amount of data.

+//

+

+#define STANDARD_IO      0x00

+#define STANDARD_MEMORY  0x01

+

+#define PORT_SIZE_8   0x00

+#define PORT_SIZE_16  0x01

+#define PORT_SIZE_32  0x02

+#define PORT_SIZE_64  0x03

+

+#define DATA_SIZE_8   0x00

+#define DATA_SIZE_16  0x01

+#define DATA_SIZE_32  0x02

+#define DATA_SIZE_64  0x03

+

+typedef struct {

+  UINT16  Type : 3;

+  UINT16  PortGranularity : 3;

+  UINT16  DataGranularity : 3;

+  UINT16  Reserved : 7;

+} SMM_ATTRIBUTES;

+

+#define INT15_D042        0x0000

+#define GET_USB_BOOT_INFO 0x0001

+#define DMI_PNP_50_57     0x0002

+

+#define STANDARD_OWNER    0x0

+#define OEM_OWNER         0x1

+

+typedef struct {

+  UINT16  Function : 15;

+  UINT16  Owner : 1;

+} SMM_FUNCTION;

+

+typedef struct {

+  SMM_ATTRIBUTES  SmmAttributes;

+  SMM_FUNCTION    SmmFunction;

+  //

+  // Data size depends upon SmmAttributes and ranges from 2 bytes to

+  // 16 bytes

+  //

+  // bugbug how to do variable length Data

+  //

+  UINT8           SmmPort;

+  UINT8           SmmData;

+} SMM_ENTRY;

+

+typedef struct {

+  UINT16    NumSmmEntries;

+  SMM_ENTRY SmmEntry;

+} SMM_TABLE;

+

+//

+// If MAX_IDE_CONTROLLER changes value 16-bit legacy code needs to change

+//

+#define MAX_IDE_CONTROLLER  8

+

+typedef struct {

+  UINT16                      MajorVersion;

+  UINT16                      MinorVersion;

+

+  UINT32                      AcpiTable;   // 4 GB range

+  UINT32                      SmbiosTable; // 4 GB range

+  UINT32                      SmbiosTableLength;

+

+  //

+  // Legacy SIO state

+  //

+  DEVICE_PRODUCER_DATA_HEADER SioData;

+

+  UINT16                      DevicePathType;

+  UINT16                      PciIrqMask;

+  UINT32                      NumberE820Entries;

+  //

+  // Controller & Drive Identify[2] per controller information

+  //

+  HDD_INFO                    HddInfo[MAX_IDE_CONTROLLER];

+  UINT32                      NumberBbsEntries;

+  UINT32                      BbsTable;

+  UINT32                      SmmTable;

+  UINT32                      OsMemoryAbove1Mb;

+  UINT32                      UnconventionalDeviceTable;

+} EFI_TO_COMPATIBILITY16_BOOT_TABLE;

+

+typedef struct {

+  UINT8   PciBus;

+  UINT8   PciDeviceFun;

+  UINT8   PciSegment;

+  UINT8   PciClass;

+  UINT8   PciSubclass;

+  UINT8   PciInterface;

+  UINT8   PrimaryIrq;

+  UINT8   PrimaryReserved;

+  UINT16  PrimaryControl;

+  UINT16  PrimaryBase;

+  UINT16  PrimaryBusMaster;

+  UINT8   SecondaryIrq;

+  UINT8   SecondaryReserved;

+  UINT16  SecondaryControl;

+  UINT16  SecondaryBase;

+  UINT16  SecondaryBusMaster;

+} EFI_LEGACY_INSTALL_PCI_HANDLER;

+

+typedef struct {

+  UINT16  PnPInstallationCheckSegment;

+  UINT16  PnPInstallationCheckOffset;

+  UINT16  OpromSegment;

+  UINT8   PciBus;

+  UINT8   PciDeviceFunction;

+  UINT8   NumberBbsEntries;

+  VOID    *BbsTablePointer;

+

+} EFI_DISPATCH_OPROM_TABLE;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/MultiPhase.h b/edk2/MdePkg/Include/Common/MultiPhase.h
new file mode 100644
index 0000000..93867a5
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/MultiPhase.h
@@ -0,0 +1,84 @@
+/** @file

+  This includes some definitions that will be used in both PEI and DXE phases.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  MultiPhase.h

+

+**/

+

+#ifndef __MULTI_PHASE_H__

+#define __MULTI_PHASE_H__

+

+//

+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+//

+// Needed EFI defines for PEI

+//

+typedef UINT64  EFI_PHYSICAL_ADDRESS;

+

+typedef enum {

+  EfiReservedMemoryType,

+  EfiLoaderCode,

+  EfiLoaderData,

+  EfiBootServicesCode,

+  EfiBootServicesData,

+  EfiRuntimeServicesCode,

+  EfiRuntimeServicesData,

+  EfiConventionalMemory,

+  EfiUnusableMemory,

+  EfiACPIReclaimMemory,

+  EfiACPIMemoryNVS,

+  EfiMemoryMappedIO,

+  EfiMemoryMappedIOPortSpace,

+  EfiPalCode,

+  EfiMaxMemoryType

+} EFI_MEMORY_TYPE;

+

+typedef UINT32  EFI_STATUS_CODE_TYPE;

+typedef UINT32  EFI_STATUS_CODE_VALUE;

+

+typedef struct {

+  UINT16    HeaderSize;

+  UINT16    Size;

+  EFI_GUID  Type;

+} EFI_STATUS_CODE_DATA;

+

+typedef struct {

+  UINT64  Signature;

+  UINT32  Revision;

+  UINT32  HeaderSize;

+  UINT32  CRC32;

+  UINT32  Reserved;

+} EFI_TABLE_HEADER;

+

+#define EFI_PAGE_SIZE         4096

+

+

+typedef VOID    *EFI_HANDLE;

+typedef UINT16  EFI_HII_HANDLE;

+typedef UINT16  STRING_REF;

+typedef struct {

+  INT16     Value;

+  INT16     Exponent;

+} EFI_EXP_BASE10_DATA;

+

+//

+// Define macros to build data structure signatures from characters.

+//

+#define EFI_SIGNATURE_16(A, B)        ((A) | (B << 8))

+#define EFI_SIGNATURE_32(A, B, C, D)  (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))

+#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \

+    (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32))

+

+

+#include <Protocol/DevicePath.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/Pcd.h b/edk2/MdePkg/Include/Common/Pcd.h
new file mode 100644
index 0000000..6f34c74
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/Pcd.h
@@ -0,0 +1,25 @@
+/** @file

+  This file defines the common macro and data structure shared between PCD PEIM and

+  PCD DXE driver.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  Pcd.h

+

+**/

+#ifndef _COMMON_PCD_H

+#define _COMMON_PCD_H

+

+typedef UINT32  PCD_TOKEN_NUMBER;

+typedef UINT8   SKU_ID;

+

+#define PCD_INVALID_TOKEN_NUMBER     ((PCD_TOKEN_NUMBER)(-1))

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/PcdTemp.h b/edk2/MdePkg/Include/Common/PcdTemp.h
new file mode 100644
index 0000000..3428b4f
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/PcdTemp.h
@@ -0,0 +1,91 @@
+/** @file

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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 __PCD_TEMP_H__

+#define __PCD_TEMP_H__

+

+#define PCD_INVALID_TOKEN     ((UINTN)(-1))

+

+/*

+ * The following structure will be removed soon after the real 

+ * PCD service PEIM and DXE driver are implmented.

+ */

+

+///

+/// I have rearranged the data so that the variable length items are at the end of the structure

+/// and we have a reasonable change of interpreting the other stuff properly.

+///

+typedef struct {

+  UINTN                 Token;

+

+  //

+  // HII Knowledge - non optimized for now

+  //

+  UINT8                 HiiData;          // If TRUE, use Variable Data

+  UINT8                 SKUEnabled;       // If TRUE, there might be various SKU data entries for this Token

+  UINT8                 MaxSKUCount;      // Up to 256 entries - limits the search space

+  UINT8                 SKUId;            // ID of the SKU

+

+  GUID                  VariableGuid;     // Variable GUID

+  UINT32                DatumSize;

+  UINT64                Datum;

+  CHAR16                *VariableName;    // Null-terminated Variable Name (remember to calculate size)

+                                          // We still need Offset information for the variable

+                                          // So naturally we can use DatumSize as the Length Field

+                                          // And we can overload the use of Datum for the Offset information

+  VOID                  *ExtendedData;    // VOID* data of size DatumSize

+} EMULATED_PCD_ENTRY;

+

+typedef

+VOID

+(EFIAPI *PCD_TEMP_CALLBACK) (

+  IN  CONST EFI_GUID   *CallBackGuid, OPTIONAL

+  IN  UINTN            CallBackToken,

+  IN  VOID             *TokenData,

+  IN  UINTN            TokenDataSize

+  );

+

+///

+/// Used by the PCD Database - never contained in an FFS file

+///

+typedef struct {

+  UINTN                 Token;

+

+  //

+  // HII Knowledge - non optimized for now

+  //

+  UINT8                 HiiData;          // If TRUE, use Variable Data

+  UINT8                 SKUEnabled;       // If TRUE, there might be various SKU data entries for this Token

+  UINT8                 MaxSKUCount;      // Up to 256 entries - limits the search space

+  UINT8                 SKUId;            // ID of the SKU

+

+  GUID                  VariableGuid;     // Variable GUID

+  UINT32                DatumSize;

+  UINT64                Datum;

+  CHAR16                *VariableName;    // Null-terminated Variable Name (remember to calculate size)

+                                          // We still need Offset information for the variable

+                                          // So naturally we can use DatumSize as the Length Field

+                                          // And we can overload the use of Datum for the Offset information

+  VOID                  *ExtendedData;    // VOID* data of size DatumSize

+

+  PCD_TEMP_CALLBACK     *CallBackList;

+  UINT32                CallBackEntries;

+  UINT32                CallBackListSize;

+} EMULATED_PCD_ENTRY_EX;                  // This exists to facilitate PCD Database implementation only

+

+typedef struct {

+  UINTN                   Count;

+  EMULATED_PCD_ENTRY_EX   Entry[1];                  // This exists to facilitate PCD Database implementation only

+} EMULATED_PCD_DATABASE_EX;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/StatusCode.h b/edk2/MdePkg/Include/Common/StatusCode.h
new file mode 100644
index 0000000..474ed10
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/StatusCode.h
@@ -0,0 +1,912 @@
+/** @file

+  Status Code Definitions, according to Intel Platform Innovation Framework 

+  for EFI Status Codes Specification

+

+  The file is divided into sections for ease of use.

+

+<pre>

+  Section:    Contents:

+  1           General Status Code Definitions

+  2           Class definitions

+  3           Computing Unit Subclasses, Progress and Error Codes

+  4           Peripheral Subclasses, Progress and Error Codes.

+  5           IO Bus Subclasses, Progress and Error Codes.

+  6           Software Subclasses, Progress and Error Codes.

+  7           Debug Codes

+</pre>

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  StatusCode.h

+

+  @par Revision Reference:

+  Version 0.92.

+

+**/

+

+#ifndef _EFI_STATUS_CODE_H_

+#define _EFI_STATUS_CODE_H_

+

+

+//

+// /////////////////////////////////////////////////////////////////////////////

+// Section 1

+///////////////////////////////////////////////////////////////////////////////

+

+//

+// A Status Code Type is made up of the code type and severity

+// All values masked by EFI_STATUS_CODE_RESERVED_MASK are

+// reserved for use by this specification.

+//

+#define EFI_STATUS_CODE_TYPE_MASK     0x000000FF

+#define EFI_STATUS_CODE_SEVERITY_MASK 0xFF000000

+#define EFI_STATUS_CODE_RESERVED_MASK 0x00FFFF00

+

+//

+// Definition of code types, all other values masked by

+// EFI_STATUS_CODE_TYPE_MASK are reserved for use by

+// this specification.

+//

+#define EFI_PROGRESS_CODE 0x00000001

+#define EFI_ERROR_CODE    0x00000002

+#define EFI_DEBUG_CODE    0x00000003

+

+//

+// Definitions of severities, all other values masked by

+// EFI_STATUS_CODE_SEVERITY_MASK are reserved for use by

+// this specification.

+//

+#define EFI_ERROR_MINOR       0x40000000

+#define EFI_ERROR_MAJOR       0x80000000

+#define EFI_ERROR_UNRECOVERED 0x90000000

+#define EFI_ERROR_UNCONTAINED 0xA0000000

+

+//

+// A Status Code Value is made up of the class, subclass, and

+// an operation.  Classes, subclasses, and operations are defined

+// in the following sections.

+//

+#define EFI_STATUS_CODE_CLASS_MASK      0xFF000000

+#define EFI_STATUS_CODE_SUBCLASS_MASK   0x00FF0000

+#define EFI_STATUS_CODE_OPERATION_MASK  0x0000FFFF

+

+//

+// Data Hub Status Code class record definition

+//

+typedef struct {

+  EFI_STATUS_CODE_TYPE  CodeType;

+  EFI_STATUS_CODE_VALUE Value;

+  UINT32                Instance;

+  EFI_GUID              CallerId;

+  EFI_STATUS_CODE_DATA  Data;

+} DATA_HUB_STATUS_CODE_DATA_RECORD;

+

+//

+// /////////////////////////////////////////////////////////////////////////////

+// Section 2

+///////////////////////////////////////////////////////////////////////////////

+//

+// Class definitions

+// Values of 4-127 are reserved for future use by this

+// specification.

+// Values in the range 127-255 are reserved for OEM use.

+//

+#define EFI_COMPUTING_UNIT  0x00000000

+#define EFI_PERIPHERAL      0x01000000

+#define EFI_IO_BUS          0x02000000

+#define EFI_SOFTWARE        0x03000000

+

+//

+// General partitioning scheme for Progress and Error Codes are

+// 0x0000-0x0FFF  - Shared by all sub-classes in a given class

+// 0x1000-0x7FFF  - Subclass Specific

+// 0x8000-0xFFFF  - OEM specific

+//

+#define EFI_SUBCLASS_SPECIFIC 0x1000

+#define EFI_OEM_SPECIFIC      0x8000

+

+//

+// /////////////////////////////////////////////////////////////////////////////

+// Section 3

+///////////////////////////////////////////////////////////////////////////////

+//

+// Computing Unit Subclass definitions.

+// Values of 8-127 are reserved for future use by this

+// specification.

+// Values of 128-255 are reserved for OEM use.

+//

+#define EFI_COMPUTING_UNIT_UNSPECIFIED        (EFI_COMPUTING_UNIT | 0x00000000)

+#define EFI_COMPUTING_UNIT_HOST_PROCESSOR     (EFI_COMPUTING_UNIT | 0x00010000)

+#define EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR (EFI_COMPUTING_UNIT | 0x00020000)

+#define EFI_COMPUTING_UNIT_IO_PROCESSOR       (EFI_COMPUTING_UNIT | 0x00030000)

+#define EFI_COMPUTING_UNIT_CACHE              (EFI_COMPUTING_UNIT | 0x00040000)

+#define EFI_COMPUTING_UNIT_MEMORY             (EFI_COMPUTING_UNIT | 0x00050000)

+#define EFI_COMPUTING_UNIT_CHIPSET            (EFI_COMPUTING_UNIT | 0x00060000)

+

+//

+// Computing Unit Class Progress Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_CU_PC_INIT_BEGIN  0x00000000

+#define EFI_CU_PC_INIT_END    0x00000001

+

+//

+// Computing Unit Unspecified Subclass Progress Code definitions.

+//

+//

+// Computing Unit Host Processor Subclass Progress Code definitions.

+//

+#define EFI_CU_HP_PC_POWER_ON_INIT          (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_HP_PC_CACHE_INIT             (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_CU_HP_PC_RAM_INIT               (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_CU_HP_PC_MEMORY_CONTROLLER_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_CU_HP_PC_IO_INIT                (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_CU_HP_PC_BSP_SELECT             (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_CU_HP_PC_BSP_RESELECT           (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_CU_HP_PC_AP_INIT                (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_CU_HP_PC_SMM_INIT               (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+

+//

+// Computing Unit Firmware Processor Subclass Progress Code definitions.

+//

+//

+// Computing Unit IO Processor Subclass Progress Code definitions.

+//

+//

+// Computing Unit Cache Subclass Progress Code definitions.

+//

+#define EFI_CU_CACHE_PC_PRESENCE_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_CACHE_PC_CONFIGURATION   (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// Computing Unit Memory Subclass Progress Code definitions.

+//

+#define EFI_CU_MEMORY_PC_SPD_READ         (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_MEMORY_PC_PRESENCE_DETECT  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_CU_MEMORY_PC_TIMING           (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_CU_MEMORY_PC_CONFIGURING      (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_CU_MEMORY_PC_OPTIMIZING       (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_CU_MEMORY_PC_INIT             (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_CU_MEMORY_PC_TEST             (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+

+//

+// Computing Unit Chipset Subclass Progress Code definitions.

+//

+//

+// Computing Unit Class Error Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_CU_EC_NON_SPECIFIC    0x00000000

+#define EFI_CU_EC_DISABLED        0x00000001

+#define EFI_CU_EC_NOT_SUPPORTED   0x00000002

+#define EFI_CU_EC_NOT_DETECTED    0x00000003

+#define EFI_CU_EC_NOT_CONFIGURED  0x00000004

+

+//

+// Computing Unit Unspecified Subclass Error Code definitions.

+//

+//

+// Computing Unit Host Processor Subclass Error Code definitions.

+//

+#define EFI_CU_HP_EC_INVALID_TYPE         (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_HP_EC_INVALID_SPEED        (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_CU_HP_EC_MISMATCH             (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_CU_HP_EC_TIMER_EXPIRED        (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_CU_HP_EC_SELF_TEST            (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_CU_HP_EC_INTERNAL             (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_CU_HP_EC_THERMAL              (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_CU_HP_EC_LOW_VOLTAGE          (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_CU_HP_EC_HIGH_VOLTAGE         (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+#define EFI_CU_HP_EC_CACHE                (EFI_SUBCLASS_SPECIFIC | 0x00000009)

+#define EFI_CU_HP_EC_MICROCODE_UPDATE     (EFI_SUBCLASS_SPECIFIC | 0x0000000A)

+#define EFI_CU_HP_EC_CORRECTABLE          (EFI_SUBCLASS_SPECIFIC | 0x0000000B)

+#define EFI_CU_HP_EC_UNCORRECTABLE        (EFI_SUBCLASS_SPECIFIC | 0x0000000C)

+#define EFI_CU_HP_EC_NO_MICROCODE_UPDATE  (EFI_SUBCLASS_SPECIFIC | 0x0000000D)

+

+//

+// Computing Unit Firmware Processor Subclass Error Code definitions.

+//

+#define EFI_CU_FP_EC_HARD_FAIL  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_FP_EC_SOFT_FAIL  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_CU_FP_EC_COMM_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+

+//

+// Computing Unit IO Processor Subclass Error Code definitions.

+//

+//

+// Computing Unit Cache Subclass Error Code definitions.

+//

+#define EFI_CU_CACHE_EC_INVALID_TYPE  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_CACHE_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_CU_CACHE_EC_INVALID_SIZE  (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_CU_CACHE_EC_MISMATCH      (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+

+//

+// Computing Unit Memory Subclass Error Code definitions.

+//

+#define EFI_CU_MEMORY_EC_INVALID_TYPE   (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_CU_MEMORY_EC_INVALID_SPEED  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_CU_MEMORY_EC_CORRECTABLE    (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_CU_MEMORY_EC_UNCORRECTABLE  (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_CU_MEMORY_EC_SPD_FAIL       (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_CU_MEMORY_EC_INVALID_SIZE   (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_CU_MEMORY_EC_MISMATCH       (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_CU_MEMORY_EC_S3_RESUME_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_CU_MEMORY_EC_UPDATE_FAIL    (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+#define EFI_CU_MEMORY_EC_NONE_DETECTED  (EFI_SUBCLASS_SPECIFIC | 0x00000009)

+#define EFI_CU_MEMORY_EC_NONE_USEFUL    (EFI_SUBCLASS_SPECIFIC | 0x0000000A)

+

+//

+// Computing Unit Chipset Subclass Error Code definitions.

+//

+

+///////////////////////////////////////////////////////////////////////////////

+// Section 4

+///////////////////////////////////////////////////////////////////////////////

+//

+// Peripheral Subclass definitions.

+// Values of 12-127 are reserved for future use by this

+// specification.

+// Values of 128-255 are reserved for OEM use.

+//

+#define EFI_PERIPHERAL_UNSPECIFIED      (EFI_PERIPHERAL | 0x00000000)

+#define EFI_PERIPHERAL_KEYBOARD         (EFI_PERIPHERAL | 0x00010000)

+#define EFI_PERIPHERAL_MOUSE            (EFI_PERIPHERAL | 0x00020000)

+#define EFI_PERIPHERAL_LOCAL_CONSOLE    (EFI_PERIPHERAL | 0x00030000)

+#define EFI_PERIPHERAL_REMOTE_CONSOLE   (EFI_PERIPHERAL | 0x00040000)

+#define EFI_PERIPHERAL_SERIAL_PORT      (EFI_PERIPHERAL | 0x00050000)

+#define EFI_PERIPHERAL_PARALLEL_PORT    (EFI_PERIPHERAL | 0x00060000)

+#define EFI_PERIPHERAL_FIXED_MEDIA      (EFI_PERIPHERAL | 0x00070000)

+#define EFI_PERIPHERAL_REMOVABLE_MEDIA  (EFI_PERIPHERAL | 0x00080000)

+#define EFI_PERIPHERAL_AUDIO_INPUT      (EFI_PERIPHERAL | 0x00090000)

+#define EFI_PERIPHERAL_AUDIO_OUTPUT     (EFI_PERIPHERAL | 0x000A0000)

+#define EFI_PERIPHERAL_LCD_DEVICE       (EFI_PERIPHERAL | 0x000B0000)

+#define EFI_PERIPHERAL_NETWORK          (EFI_PERIPHERAL | 0x000C0000)

+

+//

+// Peripheral Class Progress Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_P_PC_INIT             0x00000000

+#define EFI_P_PC_RESET            0x00000001

+#define EFI_P_PC_DISABLE          0x00000002

+#define EFI_P_PC_PRESENCE_DETECT  0x00000003

+#define EFI_P_PC_ENABLE           0x00000004

+#define EFI_P_PC_RECONFIG         0x00000005

+#define EFI_P_PC_DETECTED         0x00000006

+

+//

+// Peripheral Class Unspecified Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Keyboard Subclass Progress Code definitions.

+//

+#define EFI_P_KEYBOARD_PC_CLEAR_BUFFER  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_P_KEYBOARD_PC_SELF_TEST     (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// Peripheral Class Mouse Subclass Progress Code definitions.

+//

+#define EFI_P_MOUSE_PC_SELF_TEST  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+

+//

+// Peripheral Class Local Console Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Remote Console Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Serial Port Subclass Progress Code definitions.

+//

+#define EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+

+//

+// Peripheral Class Parallel Port Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Fixed Media Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Removable Media Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Audio Input Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Audio Output Subclass Progress Code definitions.

+//

+//

+// Peripheral Class LCD Device Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Network Subclass Progress Code definitions.

+//

+//

+// Peripheral Class Error Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_P_EC_NON_SPECIFIC       0x00000000

+#define EFI_P_EC_DISABLED           0x00000001

+#define EFI_P_EC_NOT_SUPPORTED      0x00000002

+#define EFI_P_EC_NOT_DETECTED       0x00000003

+#define EFI_P_EC_NOT_CONFIGURED     0x00000004

+#define EFI_P_EC_INTERFACE_ERROR    0x00000005

+#define EFI_P_EC_CONTROLLER_ERROR   0x00000006

+#define EFI_P_EC_INPUT_ERROR        0x00000007

+#define EFI_P_EC_OUTPUT_ERROR       0x00000008

+#define EFI_P_EC_RESOURCE_CONFLICT  0x00000009

+

+//

+// Peripheral Class Unspecified Subclass Error Code definitions.

+//

+//

+// Peripheral Class Keyboard Subclass Error Code definitions.

+//

+#define EFI_P_KEYBOARD_EC_LOCKED    (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_P_KEYBOARD_EC_STUCK_KEY (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// Peripheral Class Mouse Subclass Error Code definitions.

+//

+#define EFI_P_MOUSE_EC_LOCKED (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+

+//

+// Peripheral Class Local Console Subclass Error Code definitions.

+//

+//

+// Peripheral Class Remote Console Subclass Error Code definitions.

+//

+//

+// Peripheral Class Serial Port Subclass Error Code definitions.

+//

+//

+// Peripheral Class Parallel Port Subclass Error Code definitions.

+//

+//

+// Peripheral Class Fixed Media Subclass Error Code definitions.

+//

+//

+// Peripheral Class Removable Media Subclass Error Code definitions.

+//

+//

+// Peripheral Class Audio Input Subclass Error Code definitions.

+//

+//

+// Peripheral Class Audio Output Subclass Error Code definitions.

+//

+//

+// Peripheral Class LCD Device Subclass Error Code definitions.

+//

+//

+// Peripheral Class Network Subclass Error Code definitions.

+//

+

+///////////////////////////////////////////////////////////////////////////////

+// Section 5

+///////////////////////////////////////////////////////////////////////////////

+//

+// IO Bus Subclass definitions.

+// Values of 14-127 are reserved for future use by this

+// specification.

+// Values of 128-255 are reserved for OEM use.

+//

+#define EFI_IO_BUS_UNSPECIFIED  (EFI_IO_BUS | 0x00000000)

+#define EFI_IO_BUS_PCI          (EFI_IO_BUS | 0x00010000)

+#define EFI_IO_BUS_USB          (EFI_IO_BUS | 0x00020000)

+#define EFI_IO_BUS_IBA          (EFI_IO_BUS | 0x00030000)

+#define EFI_IO_BUS_AGP          (EFI_IO_BUS | 0x00040000)

+#define EFI_IO_BUS_PC_CARD      (EFI_IO_BUS | 0x00050000)

+#define EFI_IO_BUS_LPC          (EFI_IO_BUS | 0x00060000)

+#define EFI_IO_BUS_SCSI         (EFI_IO_BUS | 0x00070000)

+#define EFI_IO_BUS_ATA_ATAPI    (EFI_IO_BUS | 0x00080000)

+#define EFI_IO_BUS_FC           (EFI_IO_BUS | 0x00090000)

+#define EFI_IO_BUS_IP_NETWORK   (EFI_IO_BUS | 0x000A0000)

+#define EFI_IO_BUS_SMBUS        (EFI_IO_BUS | 0x000B0000)

+#define EFI_IO_BUS_I2C          (EFI_IO_BUS | 0x000C0000)

+

+//

+// IO Bus Class Progress Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_IOB_PC_INIT     0x00000000

+#define EFI_IOB_PC_RESET    0x00000001

+#define EFI_IOB_PC_DISABLE  0x00000002

+#define EFI_IOB_PC_DETECT   0x00000003

+#define EFI_IOB_PC_ENABLE   0x00000004

+#define EFI_IOB_PC_RECONFIG 0x00000005

+#define EFI_IOB_PC_HOTPLUG  0x00000006

+

+//

+// IO Bus Class Unspecified Subclass Progress Code definitions.

+//

+//

+// IO Bus Class PCI Subclass Progress Code definitions.

+//

+#define EFI_IOB_PCI_PC_BUS_ENUM   (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_IOB_PCI_PC_RES_ALLOC  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_IOB_PCI_PC_HPC_INIT   (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+

+//

+// IO Bus Class USB Subclass Progress Code definitions.

+//

+//

+// IO Bus Class IBA Subclass Progress Code definitions.

+//

+//

+// IO Bus Class AGP Subclass Progress Code definitions.

+//

+//

+// IO Bus Class PC Card Subclass Progress Code definitions.

+//

+//

+// IO Bus Class LPC Subclass Progress Code definitions.

+//

+//

+// IO Bus Class SCSI Subclass Progress Code definitions.

+//

+//

+// IO Bus Class ATA/ATAPI Subclass Progress Code definitions.

+//

+#define EFI_IOB_ATA_BUS_SMART_ENABLE          (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_IOB_ATA_BUS_SMART_DISABLE         (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD   (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD  (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+

+//

+// IO Bus Class FC Subclass Progress Code definitions.

+//

+//

+// IO Bus Class IP Network Subclass Progress Code definitions.

+//

+//

+// IO Bus Class SMBUS Subclass Progress Code definitions.

+//

+//

+// IO Bus Class I2C Subclass Progress Code definitions.

+//

+//

+// IO Bus Class Error Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_IOB_EC_NON_SPECIFIC       0x00000000

+#define EFI_IOB_EC_DISABLED           0x00000001

+#define EFI_IOB_EC_NOT_SUPPORTED      0x00000002

+#define EFI_IOB_EC_NOT_DETECTED       0x00000003

+#define EFI_IOB_EC_NOT_CONFIGURED     0x00000004

+#define EFI_IOB_EC_INTERFACE_ERROR    0x00000005

+#define EFI_IOB_EC_CONTROLLER_ERROR   0x00000006

+#define EFI_IOB_EC_READ_ERROR         0x00000007

+#define EFI_IOB_EC_WRITE_ERROR        0x00000008

+#define EFI_IOB_EC_RESOURCE_CONFLICT  0x00000009

+

+//

+// IO Bus Class Unspecified Subclass Error Code definitions.

+//

+//

+// IO Bus Class PCI Subclass Error Code definitions.

+//

+#define EFI_IOB_PCI_EC_PERR (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_IOB_PCI_EC_SERR (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// IO Bus Class USB Subclass Error Code definitions.

+//

+//

+// IO Bus Class IBA Subclass Error Code definitions.

+//

+//

+// IO Bus Class AGP Subclass Error Code definitions.

+//

+//

+// IO Bus Class PC Card Subclass Error Code definitions.

+//

+//

+// IO Bus Class LPC Subclass Error Code definitions.

+//

+//

+// IO Bus Class SCSI Subclass Error Code definitions.

+//

+//

+// IO Bus Class ATA/ATAPI Subclass Error Code definitions.

+//

+#define EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_IOB_ATA_BUS_SMART_DISABLED      (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// IO Bus Class FC Subclass Error Code definitions.

+//

+//

+// IO Bus Class IP Network Subclass Error Code definitions.

+//

+//

+// IO Bus Class SMBUS Subclass Error Code definitions.

+//

+//

+// IO Bus Class I2C Subclass Error Code definitions.

+//

+

+///////////////////////////////////////////////////////////////////////////////

+// Section 6

+///////////////////////////////////////////////////////////////////////////////

+//

+// Software Subclass definitions.

+// Values of 14-127 are reserved for future use by this

+// specification.

+// Values of 128-255 are reserved for OEM use.

+//

+#define EFI_SOFTWARE_UNSPECIFIED          (EFI_SOFTWARE | 0x00000000)

+#define EFI_SOFTWARE_SEC                  (EFI_SOFTWARE | 0x00010000)

+#define EFI_SOFTWARE_PEI_CORE             (EFI_SOFTWARE | 0x00020000)

+#define EFI_SOFTWARE_PEI_MODULE           (EFI_SOFTWARE | 0x00030000)

+#define EFI_SOFTWARE_DXE_CORE             (EFI_SOFTWARE | 0x00040000)

+#define EFI_SOFTWARE_DXE_BS_DRIVER        (EFI_SOFTWARE | 0x00050000)

+#define EFI_SOFTWARE_DXE_RT_DRIVER        (EFI_SOFTWARE | 0x00060000)

+#define EFI_SOFTWARE_SMM_DRIVER           (EFI_SOFTWARE | 0x00070000)

+#define EFI_SOFTWARE_EFI_APPLICATION      (EFI_SOFTWARE | 0x00080000)

+#define EFI_SOFTWARE_EFI_OS_LOADER        (EFI_SOFTWARE | 0x00090000)

+#define EFI_SOFTWARE_RT                   (EFI_SOFTWARE | 0x000A0000)

+#define EFI_SOFTWARE_AL                   (EFI_SOFTWARE | 0x000B0000)

+#define EFI_SOFTWARE_EBC_EXCEPTION        (EFI_SOFTWARE | 0x000C0000)

+#define EFI_SOFTWARE_IA32_EXCEPTION       (EFI_SOFTWARE | 0x000D0000)

+#define EFI_SOFTWARE_IPF_EXCEPTION        (EFI_SOFTWARE | 0x000E0000)

+#define EFI_SOFTWARE_PEI_SERVICE          (EFI_SOFTWARE | 0x000F0000)

+#define EFI_SOFTWARE_EFI_BOOT_SERVICE     (EFI_SOFTWARE | 0x00100000)

+#define EFI_SOFTWARE_EFI_RUNTIME_SERVICE  (EFI_SOFTWARE | 0x00110000)

+#define EFI_SOFTWARE_EFI_DXE_SERVICE      (EFI_SOFTWARE | 0x00120000)

+

+//

+// Software Class Progress Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_SW_PC_INIT                0x00000000

+#define EFI_SW_PC_LOAD                0x00000001

+#define EFI_SW_PC_INIT_BEGIN          0x00000002

+#define EFI_SW_PC_INIT_END            0x00000003

+#define EFI_SW_PC_AUTHENTICATE_BEGIN  0x00000004

+#define EFI_SW_PC_AUTHENTICATE_END    0x00000005

+#define EFI_SW_PC_INPUT_WAIT          0x00000006

+#define EFI_SW_PC_USER_SETUP          0x00000007

+

+//

+// Software Class Unspecified Subclass Progress Code definitions.

+//

+//

+// Software Class SEC Subclass Progress Code definitions.

+//

+#define EFI_SW_SEC_PC_ENTRY_POINT     (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_SEC_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// Software Class PEI Core Subclass Progress Code definitions.

+//

+#define EFI_SW_PEI_CORE_PC_ENTRY_POINT      (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_PEI_CORE_PC_RETURN_TO_LAST   (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+

+//

+// Software Class PEI Module Subclass Progress Code definitions.

+//

+#define EFI_SW_PEIM_PC_RECOVERY_BEGIN (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_PEIM_PC_CAPSULE_LOAD   (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_PEIM_PC_CAPSULE_START  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_PEIM_PC_RECOVERY_USER  (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_PEIM_PC_RECOVERY_AUTO  (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+

+//

+// Software Class DXE Core Subclass Progress Code definitions.

+//

+#define EFI_SW_DXE_CORE_PC_ENTRY_POINT      (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_DXE_CORE_PC_RETURN_TO_LAST   (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_DXE_CORE_PC_START_DRIVER     (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+

+//

+// Software Class DXE BS Driver Subclass Progress Code definitions.

+//

+#define EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT            (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT          (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT            (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT     (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS     (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD           (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+

+//

+// Software Class DXE RT Driver Subclass Progress Code definitions.

+//

+#define EFI_SW_DXE_RT_PC_S0 (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_DXE_RT_PC_S1 (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_DXE_RT_PC_S2 (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_DXE_RT_PC_S3 (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_DXE_RT_PC_S4 (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_SW_DXE_RT_PC_S5 (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+

+//

+// Software Class SMM Driver Subclass Progress Code definitions.

+//

+//

+// Software Class EFI Application Subclass Progress Code definitions.

+//

+//

+// Software Class EFI OS Loader Subclass Progress Code definitions.

+//

+//

+// Software Class EFI RT Subclass Progress Code definitions.

+//

+#define EFI_SW_RT_PC_ENTRY_POINT      (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_RT_PC_HANDOFF_TO_NEXT  (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_RT_PC_RETURN_TO_LAST   (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+

+//

+// Software Class EFI AL Subclass Progress Code definitions.

+//

+#define EFI_SW_AL_PC_ENTRY_POINT    (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_AL_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// Software Class EBC Exception Subclass Progress Code definitions.

+//

+//

+// Software Class IA32 Exception Subclass Progress Code definitions.

+//

+//

+// Software Class IPF Exception Subclass Progress Code definitions.

+//

+//

+// Software Class PEI Services Subclass Progress Code definitions.

+//

+#define EFI_SW_PS_PC_INSTALL_PPI            (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_PS_PC_REINSTALL_PPI          (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_PS_PC_LOCATE_PPI             (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_PS_PC_NOTIFY_PPI             (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_PS_PC_GET_BOOT_MODE          (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_SW_PS_PC_SET_BOOT_MODE          (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_SW_PS_PC_GET_HOB_LIST           (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_SW_PS_PC_CREATE_HOB             (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_SW_PS_PC_FFS_FIND_NEXT_VOLUME   (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+#define EFI_SW_PS_PC_FFS_FIND_NEXT_FILE     (EFI_SUBCLASS_SPECIFIC | 0x00000009)

+#define EFI_SW_PS_PC_FFS_FIND_SECTION_DATA  (EFI_SUBCLASS_SPECIFIC | 0x0000000A)

+#define EFI_SW_PS_PC_INSTALL_PEI_MEMORY     (EFI_SUBCLASS_SPECIFIC | 0x0000000B)

+#define EFI_SW_PS_PC_ALLOCATE_PAGES         (EFI_SUBCLASS_SPECIFIC | 0x0000000C)

+#define EFI_SW_PS_PC_ALLOCATE_POOL          (EFI_SUBCLASS_SPECIFIC | 0x0000000D)

+#define EFI_SW_PS_PC_COPY_MEM               (EFI_SUBCLASS_SPECIFIC | 0x0000000E)

+#define EFI_SW_PS_PC_SET_MEM                (EFI_SUBCLASS_SPECIFIC | 0x0000000F)

+

+//

+// Software Class EFI Boot Services Subclass Progress Code definitions.

+//

+#define EFI_SW_BS_PC_RAISE_TPL                      (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_BS_PC_RESTORE_TPL                    (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_BS_PC_ALLOCATE_PAGES                 (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_BS_PC_FREE_PAGES                     (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_BS_PC_GET_MEMORY_MAP                 (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_SW_BS_PC_ALLOCATE_POOL                  (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_SW_BS_PC_FREE_POOL                      (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_SW_BS_PC_CREATE_EVENT                   (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_SW_BS_PC_SET_TIMER                      (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+#define EFI_SW_BS_PC_WAIT_FOR_EVENT                 (EFI_SUBCLASS_SPECIFIC | 0x00000009)

+#define EFI_SW_BS_PC_SIGNAL_EVENT                   (EFI_SUBCLASS_SPECIFIC | 0x0000000A)

+#define EFI_SW_BS_PC_CLOSE_EVENT                    (EFI_SUBCLASS_SPECIFIC | 0x0000000B)

+#define EFI_SW_BS_PC_CHECK_EVENT                    (EFI_SUBCLASS_SPECIFIC | 0x0000000C)

+#define EFI_SW_BS_PC_INSTALL_PROTOCOL_INTERFACE     (EFI_SUBCLASS_SPECIFIC | 0x0000000D)

+#define EFI_SW_BS_PC_REINSTALL_PROTOCOL_INTERFACE   (EFI_SUBCLASS_SPECIFIC | 0x0000000E)

+#define EFI_SW_BS_PC_UNINSTALL_PROTOCOL_INTERFACE   (EFI_SUBCLASS_SPECIFIC | 0x0000000F)

+#define EFI_SW_BS_PC_HANDLE_PROTOCOL                (EFI_SUBCLASS_SPECIFIC | 0x00000010)

+#define EFI_SW_BS_PC_PC_HANDLE_PROTOCOL             (EFI_SUBCLASS_SPECIFIC | 0x00000011)

+#define EFI_SW_BS_PC_REGISTER_PROTOCOL_NOTIFY       (EFI_SUBCLASS_SPECIFIC | 0x00000012)

+#define EFI_SW_BS_PC_LOCATE_HANDLE                  (EFI_SUBCLASS_SPECIFIC | 0x00000013)

+#define EFI_SW_BS_PC_INSTALL_CONFIGURATION_TABLE    (EFI_SUBCLASS_SPECIFIC | 0x00000014)

+#define EFI_SW_BS_PC_LOAD_IMAGE                     (EFI_SUBCLASS_SPECIFIC | 0x00000015)

+#define EFI_SW_BS_PC_START_IMAGE                    (EFI_SUBCLASS_SPECIFIC | 0x00000016)

+#define EFI_SW_BS_PC_EXIT                           (EFI_SUBCLASS_SPECIFIC | 0x00000017)

+#define EFI_SW_BS_PC_UNLOAD_IMAGE                   (EFI_SUBCLASS_SPECIFIC | 0x00000018)

+#define EFI_SW_BS_PC_EXIT_BOOT_SERVICES             (EFI_SUBCLASS_SPECIFIC | 0x00000019)

+#define EFI_SW_BS_PC_GET_NEXT_MONOTONIC_COUNT       (EFI_SUBCLASS_SPECIFIC | 0x0000001A)

+#define EFI_SW_BS_PC_STALL                          (EFI_SUBCLASS_SPECIFIC | 0x0000001B)

+#define EFI_SW_BS_PC_SET_WATCHDOG_TIMER             (EFI_SUBCLASS_SPECIFIC | 0x0000001C)

+#define EFI_SW_BS_PC_CONNECT_CONTROLLER             (EFI_SUBCLASS_SPECIFIC | 0x0000001D)

+#define EFI_SW_BS_PC_DISCONNECT_CONTROLLER          (EFI_SUBCLASS_SPECIFIC | 0x0000001E)

+#define EFI_SW_BS_PC_OPEN_PROTOCOL                  (EFI_SUBCLASS_SPECIFIC | 0x0000001F)

+#define EFI_SW_BS_PC_CLOSE_PROTOCOL                 (EFI_SUBCLASS_SPECIFIC | 0x00000020)

+#define EFI_SW_BS_PC_OPEN_PROTOCOL_INFORMATION      (EFI_SUBCLASS_SPECIFIC | 0x00000021)

+#define EFI_SW_BS_PC_PROTOCOLS_PER_HANDLE           (EFI_SUBCLASS_SPECIFIC | 0x00000022)

+#define EFI_SW_BS_PC_LOCATE_HANDLE_BUFFER           (EFI_SUBCLASS_SPECIFIC | 0x00000023)

+#define EFI_SW_BS_PC_LOCATE_PROTOCOL                (EFI_SUBCLASS_SPECIFIC | 0x00000024)

+#define EFI_SW_BS_PC_INSTALL_MULTIPLE_INTERFACES    (EFI_SUBCLASS_SPECIFIC | 0x00000025)

+#define EFI_SW_BS_PC_UNINSTALL_MULTIPLE_INTERFACES  (EFI_SUBCLASS_SPECIFIC | 0x00000026)

+#define EFI_SW_BS_PC_CALCULATE_CRC_32               (EFI_SUBCLASS_SPECIFIC | 0x00000027)

+#define EFI_SW_BS_PC_COPY_MEM                       (EFI_SUBCLASS_SPECIFIC | 0x00000028)

+#define EFI_SW_BS_PC_SET_MEM                        (EFI_SUBCLASS_SPECIFIC | 0x00000029)

+

+//

+// Software Class EFI Runtime Services Subclass Progress Code definitions.

+//

+#define EFI_SW_RS_PC_GET_TIME                       (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_RS_PC_SET_TIME                       (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_RS_PC_GET_WAKEUP_TIME                (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_RS_PC_SET_WAKEUP_TIME                (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP        (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_SW_RS_PC_CONVERT_POINTER                (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_SW_RS_PC_GET_VARIABLE                   (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_SW_RS_PC_GET_NEXT_VARIABLE_NAME         (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_SW_RS_PC_SET_VARIABLE                   (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+#define EFI_SW_RS_PC_GET_NEXT_HIGH_MONOTONIC_COUNT  (EFI_SUBCLASS_SPECIFIC | 0x00000009)

+#define EFI_SW_RS_PC_RESET_SYSTEM                   (EFI_SUBCLASS_SPECIFIC | 0x0000000A)

+

+//

+// Software Class EFI DXE Services Subclass Progress Code definitions

+//

+#define EFI_SW_DS_PC_ADD_MEMORY_SPACE             (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_DS_PC_ALLOCATE_MEMORY_SPACE        (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+#define EFI_SW_DS_PC_FREE_MEMORY_SPACE            (EFI_SUBCLASS_SPECIFIC | 0x00000002)

+#define EFI_SW_DS_PC_REMOVE_MEMORY_SPACE          (EFI_SUBCLASS_SPECIFIC | 0x00000003)

+#define EFI_SW_DS_PC_GET_MEMORY_SPACE_DESCRIPTOR  (EFI_SUBCLASS_SPECIFIC | 0x00000004)

+#define EFI_SW_DS_PC_SET_MEMORY_SPACE_ATTRIBUTES  (EFI_SUBCLASS_SPECIFIC | 0x00000005)

+#define EFI_SW_DS_PC_GET_MEMORY_SPACE_MAP         (EFI_SUBCLASS_SPECIFIC | 0x00000006)

+#define EFI_SW_DS_PC_ADD_IO_SPACE                 (EFI_SUBCLASS_SPECIFIC | 0x00000007)

+#define EFI_SW_DS_PC_ALLOCATE_IO_SPACE            (EFI_SUBCLASS_SPECIFIC | 0x00000008)

+#define EFI_SW_DS_PC_FREE_IO_SPACE                (EFI_SUBCLASS_SPECIFIC | 0x00000009)

+#define EFI_SW_DS_PC_REMOVE_IO_SPACE              (EFI_SUBCLASS_SPECIFIC | 0x0000000A)

+#define EFI_SW_DS_PC_GET_IO_SPACE_DESCRIPTOR      (EFI_SUBCLASS_SPECIFIC | 0x0000000B)

+#define EFI_SW_DS_PC_GET_IO_SPACE_MAP             (EFI_SUBCLASS_SPECIFIC | 0x0000000C)

+#define EFI_SW_DS_PC_DISPATCH                     (EFI_SUBCLASS_SPECIFIC | 0x0000000D)

+#define EFI_SW_DS_PC_SCHEDULE                     (EFI_SUBCLASS_SPECIFIC | 0x0000000E)

+#define EFI_SW_DS_PC_TRUST                        (EFI_SUBCLASS_SPECIFIC | 0x0000000F)

+#define EFI_SW_DS_PC_PROCESS_FIRMWARE_VOLUME      (EFI_SUBCLASS_SPECIFIC | 0x00000010)

+

+//

+// Software Class Error Code definitions.

+// These are shared by all subclasses.

+//

+#define EFI_SW_EC_NON_SPECIFIC            0x00000000

+#define EFI_SW_EC_LOAD_ERROR              0x00000001

+#define EFI_SW_EC_INVALID_PARAMETER       0x00000002

+#define EFI_SW_EC_UNSUPPORTED             0x00000003

+#define EFI_SW_EC_INVALID_BUFFER          0x00000004

+#define EFI_SW_EC_OUT_OF_RESOURCES        0x00000005

+#define EFI_SW_EC_ABORTED                 0x00000006

+#define EFI_SW_EC_ILLEGAL_SOFTWARE_STATE  0x00000007

+#define EFI_SW_EC_ILLEGAL_HARDWARE_STATE  0x00000008

+#define EFI_SW_EC_START_ERROR             0x00000009

+#define EFI_SW_EC_BAD_DATE_TIME           0x0000000A

+#define EFI_SW_EC_CFG_INVALID             0x0000000B

+#define EFI_SW_EC_CFG_CLR_REQUEST         0x0000000C

+#define EFI_SW_EC_CFG_DEFAULT             0x0000000D

+#define EFI_SW_EC_PWD_INVALID             0x0000000E

+#define EFI_SW_EC_PWD_CLR_REQUEST         0x0000000F

+#define EFI_SW_EC_PWD_CLEARED             0x00000010

+#define EFI_SW_EC_EVENT_LOG_FULL          0x00000011

+

+//

+// Software Class Unspecified Subclass Error Code definitions.

+//

+//

+// Software Class SEC Subclass Error Code definitions.

+//

+//

+// Software Class PEI Core Subclass Error Code definitions.

+//

+#define EFI_SW_PEI_CORE_EC_DXE_CORRUPT  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+

+//

+// Software Class PEI Module Subclass Error Code definitions.

+//

+#define EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE        (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+#define EFI_SW_PEIM_EC_INVALID_CAPSULE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x00000001)

+

+//

+// Software Class DXE Core Subclass Error Code definitions.

+//

+#define EFI_SW_CSM_LEGACY_ROM_INIT  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+//

+// Software Class DXE Boot Service Driver Subclass Error Code definitions.

+//

+#define EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE  (EFI_SUBCLASS_SPECIFIC | 0x00000000)

+

+//

+// Software Class DXE Runtime Service Driver Subclass Error Code definitions.

+//

+//

+// Software Class SMM Driver Subclass Error Code definitions.

+//

+//

+// Software Class EFI Application Subclass Error Code definitions.

+//

+//

+// Software Class EFI OS Loader Subclass Error Code definitions.

+//

+//

+// Software Class EFI RT Subclass Error Code definitions.

+//

+//

+// Software Class EFI AL Subclass Error Code definitions.

+//

+//

+// Software Class EBC Exception Subclass Error Code definitions.

+// These exceptions are derived from the debug protocol definitions in the EFI

+// specification.

+//

+#define EFI_SW_EC_EBC_UNDEFINED             0x00000000

+#define EFI_SW_EC_EBC_DIVIDE_ERROR          EXCEPT_EBC_DIVIDE_ERROR

+#define EFI_SW_EC_EBC_DEBUG                 EXCEPT_EBC_DEBUG

+#define EFI_SW_EC_EBC_BREAKPOINT            EXCEPT_EBC_BREAKPOINT

+#define EFI_SW_EC_EBC_OVERFLOW              EXCEPT_EBC_OVERFLOW

+#define EFI_SW_EC_EBC_INVALID_OPCODE        EXCEPT_EBC_INVALID_OPCODE

+#define EFI_SW_EC_EBC_STACK_FAULT           EXCEPT_EBC_STACK_FAULT

+#define EFI_SW_EC_EBC_ALIGNMENT_CHECK       EXCEPT_EBC_ALIGNMENT_CHECK

+#define EFI_SW_EC_EBC_INSTRUCTION_ENCODING  EXCEPT_EBC_INSTRUCTION_ENCODING

+#define EFI_SW_EC_EBC_BAD_BREAK             EXCEPT_EBC_BAD_BREAK

+#define EFI_SW_EC_EBC_STEP                  EXCEPT_EBC_STEP

+

+//

+// Software Class IA32 Exception Subclass Error Code definitions.

+// These exceptions are derived from the debug protocol definitions in the EFI

+// specification.

+//

+#define EFI_SW_EC_IA32_DIVIDE_ERROR     EXCEPT_IA32_DIVIDE_ERROR

+#define EFI_SW_EC_IA32_DEBUG            EXCEPT_IA32_DEBUG

+#define EFI_SW_EC_IA32_NMI              EXCEPT_IA32_NMI

+#define EFI_SW_EC_IA32_BREAKPOINT       EXCEPT_IA32_BREAKPOINT

+#define EFI_SW_EC_IA32_OVERFLOW         EXCEPT_IA32_OVERFLOW

+#define EFI_SW_EC_IA32_BOUND            EXCEPT_IA32_BOUND

+#define EFI_SW_EC_IA32_INVALID_OPCODE   EXCEPT_IA32_INVALID_OPCODE

+#define EFI_SW_EC_IA32_DOUBLE_FAULT     EXCEPT_IA32_DOUBLE_FAULT

+#define EFI_SW_EC_IA32_INVALID_TSS      EXCEPT_IA32_INVALID_TSS

+#define EFI_SW_EC_IA32_SEG_NOT_PRESENT  EXCEPT_IA32_SEG_NOT_PRESENT

+#define EFI_SW_EC_IA32_STACK_FAULT      EXCEPT_IA32_STACK_FAULT

+#define EFI_SW_EC_IA32_GP_FAULT         EXCEPT_IA32_GP_FAULT

+#define EFI_SW_EC_IA32_PAGE_FAULT       EXCEPT_IA32_PAGE_FAULT

+#define EFI_SW_EC_IA32_FP_ERROR         EXCEPT_IA32_FP_ERROR

+#define EFI_SW_EC_IA32_ALIGNMENT_CHECK  EXCEPT_IA32_ALIGNMENT_CHECK

+#define EFI_SW_EC_IA32_MACHINE_CHECK    EXCEPT_IA32_MACHINE_CHECK

+#define EFI_SW_EC_IA32_SIMD             EXCEPT_IA32_SIMD

+

+//

+// Software Class IPF Exception Subclass Error Code definitions.

+// These exceptions are derived from the debug protocol definitions in the EFI

+// specification.

+//

+#define EFI_SW_EC_IPF_ALT_DTLB            EXCEPT_IPF_ALT_DTLB

+#define EFI_SW_EC_IPF_DNESTED_TLB         EXCEPT_IPF_DNESTED_TLB

+#define EFI_SW_EC_IPF_BREAKPOINT          EXCEPT_IPF_BREAKPOINT

+#define EFI_SW_EC_IPF_EXTERNAL_INTERRUPT  EXCEPT_IPF_EXTERNAL_INTERRUPT

+#define EFI_SW_EC_IPF_GEN_EXCEPT          EXCEPT_IPF_GEN_EXCEPT

+#define EFI_SW_EC_IPF_NAT_CONSUMPTION     EXCEPT_IPF_NAT_CONSUMPTION

+#define EFI_SW_EC_IPF_DEBUG_EXCEPT        EXCEPT_IPF_DEBUG_EXCEPT

+#define EFI_SW_EC_IPF_UNALIGNED_ACCESS    EXCEPT_IPF_UNALIGNED_ACCESS

+#define EFI_SW_EC_IPF_FP_FAULT            EXCEPT_IPF_FP_FAULT

+#define EFI_SW_EC_IPF_FP_TRAP             EXCEPT_IPF_FP_TRAP

+#define EFI_SW_EC_IPF_TAKEN_BRANCH        EXCEPT_IPF_TAKEN_BRANCH

+#define EFI_SW_EC_IPF_SINGLE_STEP         EXCEPT_IPF_SINGLE_STEP

+

+//

+// Software Class PEI Service Subclass Error Code definitions.

+//

+//

+// Software Class EFI Boot Service Subclass Error Code definitions.

+//

+//

+// Software Class EFI Runtime Service Subclass Error Code definitions.

+//

+//

+// Software Class EFI DXE Service Subclass Error Code definitions.

+//

+

+///////////////////////////////////////////////////////////////////////////////

+// Section 7

+///////////////////////////////////////////////////////////////////////////////

+//

+// Debug Code definitions for all classes and subclass

+// Only one debug code is defined at this point and should

+// be used for anything that gets sent to debug stream.

+//

+#define EFI_DC_UNSPECIFIED  0x0

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/StatusCodeDataTypeId.h b/edk2/MdePkg/Include/Common/StatusCodeDataTypeId.h
new file mode 100644
index 0000000..49bea61
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/StatusCodeDataTypeId.h
@@ -0,0 +1,336 @@
+/** @file

+  This file defines the data structures to support Status Code Data.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  StatusCodeDataTypeId.h

+

+  @par Revision Reference:

+  These definitions are from Framework of EFI Status Code Spec

+  Version 0.92.

+

+**/

+

+#ifndef __STATUS_CODE_DATA_TYPE_ID_H__

+#define __STATUS_CODE_DATA_TYPE_ID_H__

+

+

+///

+/// The size of string

+///

+#define EFI_STATUS_CODE_DATA_MAX_STRING_SIZE  150

+

+///

+/// This is the max data size including all the headers which can be passed

+/// as Status Code data. This data should be multiple of 8 byte

+/// to avoid any kind of boundary issue. Also, sum of this data size (inclusive

+/// of size of EFI_STATUS_CODE_DATA should not exceed the max record size of

+/// data hub

+///

+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200

+

+#pragma pack(1)

+typedef enum {

+  EfiStringAscii,

+  EfiStringUnicode,

+  EfiStringToken

+} EFI_STRING_TYPE;

+

+typedef struct {

+  EFI_HII_HANDLE  Handle;

+  STRING_REF      Token;

+} EFI_STATUS_CODE_STRING_TOKEN;

+

+typedef union {

+  CHAR8                         *Ascii;

+  CHAR16                        *Unicode;

+  EFI_STATUS_CODE_STRING_TOKEN  Hii;

+} EFI_STATUS_CODE_STRING;

+

+typedef struct {

+  EFI_STATUS_CODE_DATA                          DataHeader;

+  EFI_STRING_TYPE                               StringType;

+  EFI_STATUS_CODE_STRING                        String;

+} EFI_STATUS_CODE_STRING_DATA;

+

+#pragma pack()

+

+#pragma pack(1)

+

+typedef struct {

+  UINT32  ErrorLevel;

+  //

+  // 12 * sizeof (UINT64) Var Arg stack

+  //

+  // ascii DEBUG () Format string

+  //

+} EFI_DEBUG_INFO;

+

+#pragma pack()

+

+//

+// declaration for EFI_EXP_DATA. This may change

+//

+// typedef UINTN   EFI_EXP_DATA;

+

+///

+/// Voltage Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  EFI_EXP_BASE10_DATA   Voltage;

+  EFI_EXP_BASE10_DATA   Threshold;

+} EFI_COMPUTING_UNIT_VOLTAGE_ERROR_DATA;

+

+///

+/// Microcode Update Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  UINT32                Version;

+} EFI_COMPUTING_UNIT_MICROCODE_UPDATE_ERROR_DATA;

+

+///

+/// Asynchronous Timer Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  EFI_EXP_BASE10_DATA   TimerLimit;

+} EFI_COMPUTING_UNIT_TIMER_EXPIRED_ERROR_DATA;

+

+///

+/// Host Processor Mismatch Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  UINT32                Instance;

+  UINT16                Attributes;

+} EFI_HOST_PROCESSOR_MISMATCH_ERROR_DATA;

+

+//

+// EFI_COMPUTING_UNIT_MISMATCH_ATTRIBUTES

+// All other attributes are reserved for future use and

+// must be initialized to 0.

+//

+#define EFI_COMPUTING_UNIT_MISMATCH_SPEED       0x0001

+#define EFI_COMPUTING_UNIT_MISMATCH_FSB_SPEED   0x0002

+#define EFI_COMPUTING_UNIT_MISMATCH_FAMILY      0x0004

+#define EFI_COMPUTING_UNIT_MISMATCH_MODEL       0x0008

+#define EFI_COMPUTING_UNIT_MISMATCH_STEPPING    0x0010

+#define EFI_COMPUTING_UNIT_MISMATCH_CACHE_SIZE  0x0020

+#define EFI_COMPUTING_UNIT_MISMATCH_OEM1        0x1000

+#define EFI_COMPUTING_UNIT_MISMATCH_OEM2        0x2000

+#define EFI_COMPUTING_UNIT_MISMATCH_OEM3        0x4000

+#define EFI_COMPUTING_UNIT_MISMATCH_OEM4        0x8000

+

+///

+/// Thermal Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  EFI_EXP_BASE10_DATA   Temperature;

+  EFI_EXP_BASE10_DATA   Threshold;

+} EFI_COMPUTING_UNIT_THERMAL_ERROR_DATA;

+

+///

+/// Processor Disabled Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  UINT32                Cause;

+  BOOLEAN               SoftwareDisabled;

+} EFI_COMPUTING_UNIT_CPU_DISABLED_ERROR_DATA;

+

+typedef enum {

+  EfiInitCacheDataOnly,

+  EfiInitCacheInstrOnly,

+  EfiInitCacheBoth,

+  EfiInitCacheUnspecified

+} EFI_INIT_CACHE_TYPE;

+

+///

+/// Embedded cache init extended data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  UINT32                Level;

+  EFI_INIT_CACHE_TYPE   Type;

+} EFI_CACHE_INIT_DATA;

+

+//

+// Memory Extended Error Data

+//

+

+///

+/// Memory Error Granularity Definition

+///

+typedef UINT8 EFI_MEMORY_ERROR_GRANULARITY;

+

+///

+/// Memory Error Operation Definition

+///

+typedef UINT8 EFI_MEMORY_ERROR_OPERATION;

+

+typedef struct {

+  EFI_STATUS_CODE_DATA          DataHeader;

+  EFI_MEMORY_ERROR_GRANULARITY  Granularity;

+  EFI_MEMORY_ERROR_OPERATION    Operation;

+  UINTN                         Syndrome;

+  EFI_PHYSICAL_ADDRESS          Address;

+  UINTN                         Resolution;

+} EFI_MEMORY_EXTENDED_ERROR_DATA;

+

+//

+// Memory Error Granularities

+//

+#define EFI_MEMORY_ERROR_OTHER      0x01

+#define EFI_MEMORY_ERROR_UNKNOWN    0x02

+#define EFI_MEMORY_ERROR_DEVICE     0x03

+#define EFI_MEMORY_ERROR_PARTITION  0x04

+

+//

+// Memory Error Operations

+//

+#define EFI_MEMORY_OPERATION_OTHER          0x01

+#define EFI_MEMORY_OPERATION_UNKNOWN        0x02

+#define EFI_MEMORY_OPERATION_READ           0x03

+#define EFI_MEMORY_OPERATION_WRITE          0x04

+#define EFI_MEMORY_OPERATION_PARTIAL_WRITE  0x05

+

+//

+// Define shorthands to describe Group Operations

+// Many memory init operations are essentially group

+// operations.

+

+/// A shorthand to describe that the operation is performed

+/// on multiple devices within the array

+///

+#define EFI_MULTIPLE_MEMORY_DEVICE_OPERATION  0xfffe

+///

+/// A shorthand to describe that the operation is performed on all devices within the array

+///

+#define EFI_ALL_MEMORY_DEVICE_OPERATION 0xffff

+///

+/// A shorthand to describe that the operation is performed on multiple arrays

+///

+#define EFI_MULTIPLE_MEMORY_ARRAY_OPERATION 0xfffe

+///

+/// A shorthand to describe that the operation is performed on all the arrays

+///

+#define EFI_ALL_MEMORY_ARRAY_OPERATION  0xffff

+

+//

+// DIMM number

+//

+#pragma pack(1)

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  UINT16                Array;

+  UINT16                Device;

+} EFI_STATUS_CODE_DIMM_NUMBER;

+#pragma pack()

+

+///

+/// Memory Module Mismatch Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA        DataHeader;

+  EFI_STATUS_CODE_DIMM_NUMBER Instance;

+} EFI_MEMORY_MODULE_MISMATCH_ERROR_DATA;

+

+///

+/// Memory Range Extended Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  EFI_PHYSICAL_ADDRESS  Start;

+  EFI_PHYSICAL_ADDRESS  Length;

+} EFI_MEMORY_RANGE_EXTENDED_DATA;

+

+///

+/// Device handle Extended Data. Used for many

+/// errors and progress codes to point to the device.

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  EFI_HANDLE            Handle;

+} EFI_DEVICE_HANDLE_EXTENDED_DATA;

+

+typedef struct {

+  EFI_STATUS_CODE_DATA                 DataHeader;

+  UINT8                                *DevicePath;

+} EFI_DEVICE_PATH_EXTENDED_DATA;

+

+typedef struct {

+  EFI_STATUS_CODE_DATA           DataHeader;  

+  EFI_HANDLE                     ControllerHandle;

+  EFI_HANDLE                     DriverBindingHandle;

+  UINT16                         DevicePathSize;

+  UINT8                          *RemainingDevicePath;

+} EFI_STATUS_CODE_START_EXTENDED_DATA;

+

+///

+/// Resource Allocation Failure Extended Error Data

+///

+

+/*

+typedef struct {

+  EFI_STATUS_CODE_DATA      DataHeader;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  UINT32                    Bar;

+  VOID                      *ReqRes;

+  VOID                      *AllocRes;

+} EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA;

+*/

+typedef struct {

+  EFI_STATUS_CODE_DATA               DataHeader;

+  UINT32                             Bar;

+  UINT16                             DevicePathSize;

+  UINT16                             ReqResSize;

+  UINT16                             AllocResSize;

+  UINT8                              *DevicePath;

+  UINT8                              *ReqRes;

+  UINT8                              *AllocRes;

+} EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA;

+

+///

+/// Extended Error Data for Assert

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA        DataHeader;

+  UINT32                      LineNumber;

+  UINT32                      FileNameSize;

+  EFI_STATUS_CODE_STRING_DATA *FileName;

+} EFI_DEBUG_ASSERT_DATA;

+

+///

+/// System Context Data EBC/IA32/IPF

+///

+typedef union {

+  EFI_SYSTEM_CONTEXT_EBC  SystemContextEbc;

+  EFI_SYSTEM_CONTEXT_IA32 SystemContextIa32;

+  EFI_SYSTEM_CONTEXT_IPF  SystemContextIpf;

+} EFI_STATUS_CODE_EXCEP_SYSTEM_CONTEXT;

+

+typedef struct {

+  EFI_STATUS_CODE_DATA                  DataHeader;

+  EFI_STATUS_CODE_EXCEP_SYSTEM_CONTEXT  Context;

+} EFI_STATUS_CODE_EXCEP_EXTENDED_DATA;

+

+///

+/// Legacy Oprom extended data

+///

+typedef struct {

+  EFI_STATUS_CODE_DATA  DataHeader;

+  EFI_HANDLE            DeviceHandle;

+  EFI_PHYSICAL_ADDRESS  RomImageBase;

+} EFI_LEGACY_OPROM_EXTENDED_DATA;

+

+#endif

diff --git a/edk2/MdePkg/Include/Common/UefiBaseTypes.h b/edk2/MdePkg/Include/Common/UefiBaseTypes.h
new file mode 100644
index 0000000..4954c10
--- /dev/null
+++ b/edk2/MdePkg/Include/Common/UefiBaseTypes.h
@@ -0,0 +1,85 @@
+/** @file

+  This file makes the BaseTypes.h backward compatible with the ones used in the 

+  past for EFI and Tiano development. It's mostly just prepending an EFI_ on the 

+  definitions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  UefiBaseTypes.h

+

+**/

+

+#ifndef __UEFI_BASE_TYPES_H__

+#define __UEFI_BASE_TYPES_H__

+

+#include <Common/BaseTypes.h>

+

+typedef UINT64    EFI_LBA;

+

+#define EFIERR(_a)                    ENCODE_ERROR(_a)

+

+#define EFI_MAX_BIT                   MAX_BIT

+#define EFI_MAX_ADDRESS               MAX_ADDRESS

+#define EFI_BREAKPOINT()              CpuBreakpoint ()

+#define EFI_DEADLOOP()                CpuDeadLoop ()

+#define EFI_ERROR(A)                  RETURN_ERROR(A)

+

+typedef GUID          EFI_GUID;

+typedef RETURN_STATUS EFI_STATUS;

+

+#define EFI_SUCCESS               RETURN_SUCCESS              

+#define EFI_LOAD_ERROR            RETURN_LOAD_ERROR           

+#define EFI_INVALID_PARAMETER     RETURN_INVALID_PARAMETER    

+#define EFI_UNSUPPORTED           RETURN_UNSUPPORTED          

+#define EFI_BAD_BUFFER_SIZE       RETURN_BAD_BUFFER_SIZE      

+#define EFI_BUFFER_TOO_SMALL      RETURN_BUFFER_TOO_SMALL     

+#define EFI_NOT_READY             RETURN_NOT_READY            

+#define EFI_DEVICE_ERROR          RETURN_DEVICE_ERROR         

+#define EFI_WRITE_PROTECTED       RETURN_WRITE_PROTECTED      

+#define EFI_OUT_OF_RESOURCES      RETURN_OUT_OF_RESOURCES     

+#define EFI_VOLUME_CORRUPTED      RETURN_VOLUME_CORRUPTED     

+#define EFI_VOLUME_FULL           RETURN_VOLUME_FULL          

+#define EFI_NO_MEDIA              RETURN_NO_MEDIA             

+#define EFI_MEDIA_CHANGED         RETURN_MEDIA_CHANGED        

+#define EFI_NOT_FOUND             RETURN_NOT_FOUND            

+#define EFI_ACCESS_DENIED         RETURN_ACCESS_DENIED        

+#define EFI_NO_RESPONSE           RETURN_NO_RESPONSE          

+#define EFI_NO_MAPPING            RETURN_NO_MAPPING           

+#define EFI_TIMEOUT               RETURN_TIMEOUT              

+#define EFI_NOT_STARTED           RETURN_NOT_STARTED          

+#define EFI_ALREADY_STARTED       RETURN_ALREADY_STARTED      

+#define EFI_ABORTED               RETURN_ABORTED              

+#define EFI_ICMP_ERROR            RETURN_ICMP_ERROR           

+#define EFI_TFTP_ERROR            RETURN_TFTP_ERROR           

+#define EFI_PROTOCOL_ERROR        RETURN_PROTOCOL_ERROR       

+#define EFI_INCOMPATIBLE_VERSION  RETURN_INCOMPATIBLE_VERSION 

+#define EFI_SECURITY_VIOLATION    RETURN_SECURITY_VIOLATION   

+#define EFI_CRC_ERROR             RETURN_CRC_ERROR   

+#define EFI_END_OF_MEDIA          RETURN_END_OF_MEDIA

+#define EFI_END_OF_FILE           RETURN_END_OF_FILE

+

+#define EFI_WARN_UNKNOWN_GLYPH    RETURN_WARN_UNKNOWN_GLYPH   

+#define EFI_WARN_DELETE_FAILURE   RETURN_WARN_DELETE_FAILURE  

+#define EFI_WARN_WRITE_FAILURE    RETURN_WARN_WRITE_FAILURE   

+#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL

+

+//

+// The EFI memory allocation functions work in units of EFI_PAGEs that are

+// 4K. This should in no way be confused with the page size of the processor.

+// An EFI_PAGE is just the quanta of memory in EFI.

+//

+#define EFI_PAGE_MASK         0xFFF

+#define EFI_PAGE_SHIFT        12

+

+#define EFI_SIZE_TO_PAGES(a)  (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0))

+

+#define EFI_PAGES_TO_SIZE(a)   ( (a) << EFI_PAGE_SHIFT)

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe.h b/edk2/MdePkg/Include/Dxe.h
new file mode 100644
index 0000000..d97209d
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe.h
@@ -0,0 +1,50 @@
+/** @file

+

+  Root include file for Mde Package DXE modules

+

+  DXE modules follow the public Framework specifications and the UEFI 

+  specifiations. The build infrastructure must set 

+  EFI_SPECIFICATION_VERSION  before including  this file. To support 

+  R9/UEFI2.0 set EFI_SPECIFIATION_VERSION to 0x00020000. To support 

+  R8.5/EFI 1.10 set EFI_SPECIFIATION_VERSION to 0x00010010. 

+  EDK_RELEASE_VERSION must be set to a non zero value.

+  EFI_SPECIFIATION_VERSION and EDK_RELEASE_VERSION are set automatically

+  by the build infrastructure for every module.

+

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __DXE_H__

+#define __DXE_H__

+

+//

+// Check to make sure EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION are defined.

+//

+#if !defined(EFI_SPECIFICATION_VERSION)

+  #error EFI_SPECIFICATION_VERSION not defined

+#elif !defined(EDK_RELEASE_VERSION)

+  #error EDK_RELEASE_VERSION not defined

+#elif (EDK_RELEASE_VERSION == 0)

+  #error EDK_RELEASE_VERSION can not be zero

+#endif

+

+

+#include <Common/UefiBaseTypes.h>

+#include <Dxe/DxeCis.h>

+#include <Dxe/SmmCis.h>

+

+#include <Common/DataHubRecords.h>

+#include <Guid/DataHubRecords.h>

+

+#include <Protocol/Pcd.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Bds.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Bds.h
new file mode 100644
index 0000000..f6b72d2
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Bds.h
@@ -0,0 +1,87 @@
+/** @file

+  Boot Device Selection Architectural Protocol as defined in DXE CIS

+

+  When the DXE core is done it calls the BDS via this protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Bds.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_BDS_H__

+#define __ARCH_PROTOCOL_BDS_H__

+

+//

+// Global ID for the BDS Architectural Protocol

+//

+#define EFI_BDS_ARCH_PROTOCOL_GUID \

+  { 0x665E3FF6, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

+

+//

+// Declare forward reference for the BDS Architectural Protocol

+//

+typedef struct _EFI_BDS_ARCH_PROTOCOL   EFI_BDS_ARCH_PROTOCOL;

+

+/**

+  This function uses policy data from the platform to determine what operating 

+  system or system utility should be loaded and invoked.  This function call 

+  also optionally make the use of user input to determine the operating system 

+  or system utility to be loaded and invoked.  When the DXE Core has dispatched 

+  all the drivers on the dispatch queue, this function is called.  This 

+  function will attempt to connect the boot devices required to load and invoke 

+  the selected operating system or system utility.  During this process, 

+  additional firmware volumes may be discovered that may contain addition DXE 

+  drivers that can be dispatched by the DXE Core.   If a boot device cannot be 

+  fully connected, this function calls the DXE Service Dispatch() to allow the 

+  DXE drivers from any newly discovered firmware volumes to be dispatched.  

+  Then the boot device connection can be attempted again.  If the same boot 

+  device connection operation fails twice in a row, then that boot device has 

+  failed, and should be skipped.  This function should never return.

+

+  @param  This The EFI_BDS_ARCH_PROTOCOL instance.

+

+  @return None.

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_BDS_ENTRY) (

+  IN EFI_BDS_ARCH_PROTOCOL  *This

+  );

+

+/**

+  Interface stucture for the BDS Architectural Protocol.

+

+  @par Protocol Description:

+  The EFI_BDS_ARCH_PROTOCOL transfers control from DXE to an operating 

+  system or a system utility.  If there are not enough drivers initialized 

+  when this protocol is used to access the required boot device(s), then 

+  this protocol should add drivers to the dispatch queue and return control 

+  back to the dispatcher.  Once the required boot devices are available, then 

+  the boot device can be used to load and invoke an OS or a system utility.

+

+  @par Protocol Parameters:

+  Entry - The entry point to BDS.  This call does not take any parameters, 

+  and the return value can be ignored.  If it returns, then the 

+  dispatcher must be invoked again, if it never returns, then an 

+  operating system or a system utility have been invoked.

+

+**/

+struct _EFI_BDS_ARCH_PROTOCOL {

+  EFI_BDS_ENTRY Entry;

+};

+

+extern EFI_GUID gEfiBdsArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Cpu.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Cpu.h
new file mode 100644
index 0000000..975a816
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Cpu.h
@@ -0,0 +1,326 @@
+/** @file

+  CPU Architectural Protocol as defined in DXE CIS

+

+  This code abstracts the DXE core from processor implementation details.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Cpu.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_CPU_H__

+#define __ARCH_PROTOCOL_CPU_H__

+

+

+#define EFI_CPU_ARCH_PROTOCOL_GUID \

+  { 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+typedef struct _EFI_CPU_ARCH_PROTOCOL   EFI_CPU_ARCH_PROTOCOL;

+

+typedef enum {

+  EfiCpuFlushTypeWriteBackInvalidate,

+  EfiCpuFlushTypeWriteBack,

+  EfiCpuFlushTypeInvalidate,

+  EfiCpuMaxFlushType

+} EFI_CPU_FLUSH_TYPE;

+

+typedef enum {

+  EfiCpuInit,

+  EfiCpuMaxInitType

+} EFI_CPU_INIT_TYPE;

+

+/**

+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.

+

+  @param  InterruptType Defines the type of interrupt or exception that 

+  occurred on the processor.This parameter is processor architecture specific.

+  

+  @param  SystemContext A pointer to the processor context when 

+  the interrupt occurred on the processor.

+

+  @return None

+

+**/

+typedef

+VOID

+(*EFI_CPU_INTERRUPT_HANDLER) (

+  IN EFI_EXCEPTION_TYPE                 InterruptType,

+  IN EFI_SYSTEM_CONTEXT                 SystemContext

+  );

+

+/**

+  This function flushes the range of addresses from Start to Start+Length 

+  from the processor's data cache. If Start is not aligned to a cache line 

+  boundary, then the bytes before Start to the preceding cache line boundary 

+  are also flushed. If Start+Length is not aligned to a cache line boundary, 

+  then the bytes past Start+Length to the end of the next cache line boundary 

+  are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be 

+  supported. If the data cache is fully coherent with all DMA operations, then 

+  this function can just return EFI_SUCCESS. If the processor does not support 

+  flushing a range of the data cache, then the entire data cache can be flushed.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  Start The beginning physical address to flush from the processor's data

+  cache.

+  @param  Length The number of bytes to flush from the processor's data cache. This

+  function may flush more bytes than Length specifies depending upon

+  the granularity of the flush operation that the processor supports.

+  @param  FlushType Specifies the type of flush operation to perform.

+

+  @retval  EFI_SUCCESS The address range from Start to Start+Length was flushed from

+  the processor's data cache.

+  @retval  EFI_UNSUPPORTEDT The processor does not support the cache flush type specified

+  by FlushType.

+  @retval  EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed

+  from the processor's data cache.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_FLUSH_DATA_CACHE) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This,

+  IN EFI_PHYSICAL_ADDRESS               Start,

+  IN UINT64                             Length,

+  IN EFI_CPU_FLUSH_TYPE                 FlushType

+  );

+

+

+/**

+  This function enables interrupt processing by the processor. 

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS Interrupts are enabled on the processor.

+  @retval  EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_ENABLE_INTERRUPT) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This

+  );

+

+

+/**

+  This function disables interrupt processing by the processor.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS Interrupts are disabled on the processor.

+  @retval  EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_DISABLE_INTERRUPT) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This

+  );

+

+

+/**

+  This function retrieves the processor's current interrupt state a returns it in 

+  State. If interrupts are currently enabled, then TRUE is returned. If interrupts 

+  are currently disabled, then FALSE is returned.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  State A pointer to the processor's current interrupt state. Set to TRUE if

+  interrupts are enabled and FALSE if interrupts are disabled.

+

+  @retval  EFI_SUCCESS The processor's current interrupt state was returned in State.

+  @retval  EFI_INVALID_PARAMETER State is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_GET_INTERRUPT_STATE) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This,

+  OUT BOOLEAN                           *State

+  );

+

+

+/**

+  This function generates an INIT on the processor. If this function succeeds, then the

+  processor will be reset, and control will not be returned to the caller. If InitType is 

+  not supported by this processor, or the processor cannot programmatically generate an 

+  INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error 

+  occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  InitType The type of processor INIT to perform.

+

+  @retval  EFI_SUCCESS The processor INIT was performed. This return code should never be seen.

+  @retval  EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported

+  by this processor.

+  @retval  EFI_DEVICE_ERROR The processor INIT failed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_INIT) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This,

+  IN EFI_CPU_INIT_TYPE                  InitType

+  );

+

+

+/**

+  This function registers and enables the handler specified by InterruptHandler for a processor 

+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the 

+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. 

+  The installed handler is called once for each processor interrupt or exception.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts

+  are enabled and FALSE if interrupts are disabled.

+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called

+  when a processor interrupt occurs. If this parameter is NULL, then the handler

+  will be uninstalled.

+

+  @retval  EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.

+  @retval  EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was

+  previously installed.

+  @retval  EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not

+  previously installed.

+  @retval  EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_REGISTER_INTERRUPT_HANDLER) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This,

+  IN EFI_EXCEPTION_TYPE                 InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER          InterruptHandler

+  );

+

+

+/**

+  This function reads the processor timer specified by TimerIndex and returns it in TimerValue.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter

+  must be between 0 and NumberOfTimers-1.

+  @param  TimerValue Pointer to the returned timer value.

+  @param  TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment

+  of TimerValue.

+

+  @retval  EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.

+  @retval  EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.

+  @retval  EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.

+  @retval  EFI_UNSUPPORTED The processor does not have any readable timers.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_GET_TIMER_VALUE) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This,

+  IN UINT32                             TimerIndex,

+  OUT UINT64                            *TimerValue,

+  OUT UINT64                            *TimerPeriod OPTIONAL

+  );

+

+

+/**

+  This function modifies the attributes for the memory region specified by BaseAddress and

+  Length from their current attributes to the attributes specified by Attributes.

+

+  @param  This The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  BaseAddress The physical address that is the start address of a memory region.

+  @param  Length The size in bytes of the memory region.

+  @param  Attributes The bit mask of attributes to set for the memory region.

+

+  @retval  EFI_SUCCESS The attributes were set for the memory region.

+  @retval  EFI_ACCESS_DENIED The attributes for the memory resource range specified by

+  BaseAddress and Length cannot be modified.

+  @retval  EFI_INVALID_PARAMETER Length is zero.

+  @retval  EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of

+  the memory resource range.

+  @retval  EFI_UNSUPPORTED The processor does not support one or more bytes of the memory

+  resource range specified by BaseAddress and Length.

+  The bit mask of attributes is not support for the memory resource

+  range specified by BaseAddress and Length.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_SET_MEMORY_ATTRIBUTES) (

+  IN EFI_CPU_ARCH_PROTOCOL              *This,

+  IN  EFI_PHYSICAL_ADDRESS              BaseAddress,

+  IN  UINT64                            Length,

+  IN  UINT64                            Attributes

+  );

+

+

+/**

+  @par Protocol Description:

+  The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE

+  Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt

+  vectors and exception vectors, reading internal processor timers, resetting the processor, and

+  determining the processor frequency.

+

+  @param FlushDataCache

+  Flushes a range of the processor's data cache. If the processor does 

+  not contain a data cache, or the data cache is fully coherent, then this 

+  function can just return EFI_SUCCESS. If the processor does not support 

+  flushing a range of addresses from the data cache, then the entire data 

+  cache must be flushed. 

+

+  @param EnableInterrupt    Enables interrupt processing by the processor. 

+

+  @param DisableInterrupt    Disables interrupt processing by the processor.

+

+  @param GetInterruptState  Retrieves the processor's current interrupt state.

+

+  @param Init

+  Generates an INIT on the processor. If a processor cannot programmatically 

+  generate an INIT without help from external hardware, then this function 

+  returns EFI_UNSUPPORTED.

+

+  @param RegisterInterruptHandler

+  Associates an interrupt service routine with one of the processor's interrupt 

+  vectors. This function is typically used by the EFI_TIMER_ARCH_PROTOCOL to 

+  hook the timer interrupt in a system. It can also be used by the debugger to 

+  hook exception vectors.

+

+  @param GetTimerValue    Returns the value of one of the processor's internal timers.

+

+  @param SetMemoryAttributes  Attempts to set the attributes of a memory region.

+

+  @param NumberOfTimers

+  The number of timers that are available in a processor. The value in this 

+  field is a constant that must not be modified after the CPU Architectural 

+  Protocol is installed. All consumers must treat this as a read-only field.

+

+  @param DmaBufferAlignment

+  The size, in bytes, of the alignment required for DMA buffer allocations. 

+  This is typically the size of the largest data cache line in the platform. 

+  The value in this field is a constant that must not be modified after the 

+  CPU Architectural Protocol is installed. All consumers must treat this as 

+  a read-only field.

+

+**/

+struct _EFI_CPU_ARCH_PROTOCOL {

+  EFI_CPU_FLUSH_DATA_CACHE            FlushDataCache;

+  EFI_CPU_ENABLE_INTERRUPT            EnableInterrupt;

+  EFI_CPU_DISABLE_INTERRUPT           DisableInterrupt;

+  EFI_CPU_GET_INTERRUPT_STATE         GetInterruptState;

+  EFI_CPU_INIT                        Init;

+  EFI_CPU_REGISTER_INTERRUPT_HANDLER  RegisterInterruptHandler;

+  EFI_CPU_GET_TIMER_VALUE             GetTimerValue;

+  EFI_CPU_SET_MEMORY_ATTRIBUTES       SetMemoryAttributes;

+  UINT32                              NumberOfTimers;

+  UINT32                              DmaBufferAlignment;

+};

+

+extern EFI_GUID gEfiCpuArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Metronome.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Metronome.h
new file mode 100644
index 0000000..a07003e
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Metronome.h
@@ -0,0 +1,100 @@
+/** @file

+  Metronome Architectural Protocol as defined in DXE CIS

+

+  This code abstracts the DXE core to provide delay services.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Metronome.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_METRONOME_H__

+#define __ARCH_PROTOCOL_METRONOME_H__

+

+//

+// Global ID for the Metronome Architectural Protocol

+//

+#define EFI_METRONOME_ARCH_PROTOCOL_GUID \

+  { 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+//

+// Declare forward reference for the Metronome Architectural Protocol

+//

+typedef struct _EFI_METRONOME_ARCH_PROTOCOL   EFI_METRONOME_ARCH_PROTOCOL;

+

+/**

+  The WaitForTick() function waits for the number of ticks specified by 

+  TickNumber from a known time source in the platform.  If TickNumber of 

+  ticks are detected, then EFI_SUCCESS is returned.  The actual time passed 

+  between entry of this function and the first tick is between 0 and 

+  TickPeriod 100 nS units.  If you want to guarantee that at least TickPeriod 

+  time has elapsed, wait for two ticks.  This function waits for a hardware 

+  event to determine when a tick occurs.  It is possible for interrupt 

+  processing, or exception processing to interrupt the execution of the 

+  WaitForTick() function.  Depending on the hardware source for the ticks, it 

+  is possible for a tick to be missed.  This function cannot guarantee that 

+  ticks will not be missed.  If a timeout occurs waiting for the specified 

+  number of ticks, then EFI_TIMEOUT is returned.

+

+  @param  This The EFI_METRONOME_ARCH_PROTOCOL instance.

+  

+  @param  TickNumber Number of ticks to wait.

+

+  @retval  EFI_SUCCESS The wait for the number of ticks specified by TickNumber

+  succeeded.

+  

+  @retval  EFI_TIMEOUT A timeout occurred waiting for the specified number of ticks.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_METRONOME_WAIT_FOR_TICK) (

+   IN EFI_METRONOME_ARCH_PROTOCOL   *This,

+   IN UINT32                        TickNumber

+  );

+

+//

+//

+

+/**

+  Interface stucture for the Metronome Architectural Protocol.

+

+  @par Protocol Description:

+  This protocol provides access to a known time source in the platform to the

+  core.  The core uses this known time source to produce core services that 

+  require calibrated delays.  

+

+  @param WaitForTick

+  Waits for a specified number of ticks from a known time source 

+  in the platform.  The actual time passed between entry of this 

+  function and the first tick is between 0 and TickPeriod 100 nS 

+  units.  If you want to guarantee that at least TickPeriod time 

+  has elapsed, wait for two ticks.

+

+  @param TickPeriod

+  The period of platform's known time source in 100 nS units.  

+  This value on any platform must be at least 10 uS, and must not 

+  exceed 200 uS.  The value in this field is a constant that must 

+  not be modified after the Metronome architectural protocol is 

+  installed.  All consumers must treat this as a read-only field.

+

+**/

+struct _EFI_METRONOME_ARCH_PROTOCOL {

+  EFI_METRONOME_WAIT_FOR_TICK  WaitForTick;

+  UINT32                       TickPeriod;

+};

+

+extern EFI_GUID gEfiMetronomeArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/MonotonicCounter.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/MonotonicCounter.h
new file mode 100644
index 0000000..d253740
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/MonotonicCounter.h
@@ -0,0 +1,33 @@
+/** @file

+  Monotonic Counter Architectural Protocol as defined in DXE CIS

+

+  This code provides the services required to access the systems monotonic counter

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  MonotonicCounter.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_MONTONIC_COUNTER_H__

+#define __ARCH_PROTOCOL_MONTONIC_COUNTER_H__

+

+///

+/// Global ID for the Monotonic Counter Architectural Protocol

+///

+#define EFI_MONTONIC_COUNTER_ARCH_PROTOCOL_GUID \

+  {0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} }

+  

+extern EFI_GUID gEfiMonotonicCounterArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/RealTimeClock.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/RealTimeClock.h
new file mode 100644
index 0000000..dc968e1
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/RealTimeClock.h
@@ -0,0 +1,41 @@
+/** @file

+  Real Time clock Architectural Protocol as defined in DXE CIS

+

+  This code abstracts time and data functions. Used to provide

+  Time and date related EFI runtime services.

+

+  The GetTime (), SetTime (), GetWakeupTime (), and SetWakeupTime () EFI 1.0

+  services are added to the EFI system table and the 

+  EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID protocol is registered with a NULL 

+  pointer.

+

+  No CRC of the EFI system table is required, as it is done in the DXE core.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  RealTimeClock.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_REAL_TIME_CLOCK_H__

+#define __ARCH_PROTOCOL_REAL_TIME_CLOCK_H__

+

+//

+// Global ID for the Real Time Clock Architectural Protocol

+//

+#define EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID \

+  { 0x27CFAC87, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

+

+extern EFI_GUID gEfiRealTimeClockArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Reset.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Reset.h
new file mode 100644
index 0000000..80befae
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Reset.h
@@ -0,0 +1,38 @@
+/** @file

+  Reset Architectural Protocol as defined in the DXE CIS

+

+  Used to provide ResetSystem runtime services

+

+  The ResetSystem () EFI 1.0 service is added to the EFI system table and the 

+  EFI_RESET_ARCH_PROTOCOL_GUID protocol is registered with a NULL pointer.

+

+  No CRC of the EFI system table is required, as it is done in the DXE core.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Reset.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_RESET_H__

+#define __ARCH_PROTOCOL_RESET_H__

+

+//

+// Global ID for the Reset Architectural Protocol

+//

+#define EFI_RESET_ARCH_PROTOCOL_GUID  \

+  { 0x27CFAC88, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

+

+extern EFI_GUID gEfiResetArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Runtime.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Runtime.h
new file mode 100644
index 0000000..bbd4c1a
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Runtime.h
@@ -0,0 +1,162 @@
+/** @file

+  Runtime Architectural Protocol as defined in DXE CIS

+

+  This code is used to produce the EFI 1.0 runtime virtual switch over

+

+  This driver must add SetVirtualAddressMap () and ConvertPointer () to

+  the EFI system table. This driver is not responcible for CRCing the 

+  EFI system table.

+

+  This driver will add EFI_RUNTIME_ARCH_PROTOCOL_GUID protocol with a 

+  pointer to the Runtime Arch Protocol instance structure. The protocol

+  member functions are used by the DXE core to export information need

+  by this driver to produce the runtime transition to virtual mode

+  calling.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Runtime.h

+

+  @par Revision Reference:

+  Version 0.90.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_RUNTIME_H__

+#define __ARCH_PROTOCOL_RUNTIME_H__

+

+//

+// Global ID for the Runtime Architectural Protocol

+//

+#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \

+  { 0x96d08253, 0x8483, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+typedef struct _EFI_RUNTIME_ARCH_PROTOCOL   EFI_RUNTIME_ARCH_PROTOCOL;

+

+/**

+  When a SetVirtualAddressMap() is performed all the runtime images loaded by 

+  DXE must be fixed up with the new virtual address map. To facilitate this the 

+  Runtime Architectural Protocol needs to be informed of every runtime driver 

+  that is registered.  All the runtime images loaded by DXE should be registered 

+  with this service by the DXE Core when ExitBootServices() is called.  The 

+  images that are registered with this service must have successfully been 

+  loaded into memory with the Boot Service LoadImage().  As a result, no 

+  parameter checking needs to be performed.

+

+  @param  This The EFI_RUNTIME_ARCH_PROTOCOL instance.

+  

+  @param  ImageBase Start of image that has been loaded in memory. It is either

+  a pointer to the DOS or PE header of the image.

+  

+  @param  ImageSize Size of the image in bytes.

+  

+  @param  RelocationData Information about the fixups that were performed on ImageBase

+  when it was loaded into memory. This information is needed

+  when the virtual mode fix-ups are reapplied so that data that

+  has been programmatically updated will not be fixed up. If

+  code updates a global variable the code is responsible for

+  fixing up the variable for virtual mode.

+

+  @retval  EFI_SUCCESS The ImageBase has been registered.

+  

+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources to register ImageBase.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_RUNTIME_REGISTER_IMAGE) (

+  IN EFI_RUNTIME_ARCH_PROTOCOL  *This,

+  IN  EFI_PHYSICAL_ADDRESS              ImageBase,   

+  IN  UINTN                             ImageSize,     

+  IN  VOID                              *RelocationData    

+  );

+

+

+/**

+  This function is used to support the required runtime events. Currently only 

+  runtime events of type EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE needs to be 

+  registered with this service.  All the runtime events that exist in the DXE 

+  Core should be registered with this service when ExitBootServices() is called.  

+  All the events that are registered with this service must have been created 

+  with the Boot Service CreateEvent().  As a result, no parameter checking needs 

+  to be performed.

+

+  @param  This The EFI_RUNTIME_ARCH_PROTOCOL instance.

+  

+  @param  Type The same as Type passed into CreateEvent().

+  

+  @param  NotifyTpl The same as NotifyTpl passed into CreateEvent().

+  

+  @param  NotifyFunction The same as NotifyFunction passed into CreateEvent().

+  

+  @param  NotifyContext The same as NotifyContext passed into CreateEvent().

+  

+  @param  Event The EFI_EVENT returned by CreateEvent().  Event must be in

+  runtime memory.

+

+  @retval  EFI_SUCCESS The Event has been registered.

+  

+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources to register Event.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_RUNTIME_REGISTER_EVENT) (

+  IN EFI_RUNTIME_ARCH_PROTOCOL  *This,

+  IN UINT32                             Type,

+  IN EFI_TPL                            NotifyTpl,

+  IN EFI_EVENT_NOTIFY                   NotifyFunction,

+  IN VOID                               *NotifyContext,

+  IN EFI_EVENT                          *Event

+  );

+

+//

+// Interface stucture for the Runtime Architectural Protocol

+//

+/**

+  @par Protocol Description:

+  The DXE driver that produces this protocol must be a runtime driver.  This 

+  driver is responsible for initializing the SetVirtualAddressMap() and 

+  ConvertPointer() fields of the EFI Runtime Services Table and the 

+  CalculateCrc32() field of the EFI Boot Services Table.  See the Runtime 

+  Services chapter and the Boot Services chapter for details on these services.

+  After the two fields of the EFI Runtime Services Table and the one field of 

+  the EFI Boot Services Table have been initialized, the driver must install 

+  the EFI_RUNTIME_ARCH_PROTOCOL_GUID on a new handle with an EFI_RUNTIME_ARCH_ 

+  PROTOCOL interface pointer.  The installation of this protocol informs the 

+  DXE core that the virtual memory services and the 32-bit CRC services are 

+  now available, and the DXE core must update the 32-bit CRC of the EFI Runtime 

+  Services Table and the 32-bit CRC of the EFI Boot Services Table.

+

+  All runtime core services are provided by the EFI_RUNTIME_ARCH_PROTOCOL.  

+  This includes the support for registering runtime images that must be 

+  re-fixed up when a transition is made from physical mode to virtual mode. 

+  This protocol also supports all events that are defined to fire at runtime. 

+  This protocol also contains a CRC-32 function that will be used by the DXE 

+  core as a boot service. The EFI_RUNTIME_ARCH_PROTOCOL needs the CRC-32 

+  function when a transition is made from physical mode to virtual mode and 

+  the EFI System Table and EFI Runtime Table are fixed up with virtual pointers.

+

+  @param RegisterRuntimeImage

+  Register a runtime image so it can be converted to virtual mode if the EFI Runtime Services 

+  SetVirtualAddressMap() is called.

+

+  @param RegisterRuntimeEvent

+  Register an event than needs to be notified at runtime. 

+

+**/

+struct _EFI_RUNTIME_ARCH_PROTOCOL {

+  EFI_RUNTIME_REGISTER_IMAGE  RegisterImage;

+  EFI_RUNTIME_REGISTER_EVENT  RegisterEvent;

+};

+

+extern EFI_GUID gEfiRuntimeArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Security.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Security.h
new file mode 100644
index 0000000..3598199
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Security.h
@@ -0,0 +1,136 @@
+/** @file

+  Security Architectural Protocol as defined in the DXE CIS

+

+  Used to provide Security services.  Specifically, dependening upon the 

+  authentication state of a discovered driver in a Firmware Volume, the 

+  portable DXE Core Dispatcher will call into the Security Architectural 

+  Protocol (SAP) with the authentication state of the driver.

+

+  This call-out allows for OEM-specific policy decisions to be made, such

+  as event logging for attested boots, locking flash in response to discovering

+  an unsigned driver or failed signature check, or other exception response.

+

+  The SAP can also change system behavior by having the DXE core put a driver

+  in the Schedule-On-Request (SOR) state.  This will allow for later disposition 

+  of the driver by platform agent, such as Platform BDS.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Security.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_SECURITY_H__

+#define __ARCH_PROTOCOL_SECURITY_H__

+

+//

+// Global ID for the Security Code Architectural Protocol

+//

+#define EFI_SECURITY_ARCH_PROTOCOL_GUID  \

+  { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } }

+

+typedef struct _EFI_SECURITY_ARCH_PROTOCOL    EFI_SECURITY_ARCH_PROTOCOL;

+

+/**

+  The EFI_SECURITY_ARCH_PROTOCOL (SAP) is used to abstract platform-specific 

+  policy from the DXE core response to an attempt to use a file that returns a 

+  given status for the authentication check from the section extraction protocol.  

+

+  The possible responses in a given SAP implementation may include locking 

+  flash upon failure to authenticate, attestation logging for all signed drivers, 

+  and other exception operations.  The File parameter allows for possible logging 

+  within the SAP of the driver.

+

+  If File is NULL, then EFI_INVALID_PARAMETER is returned.

+

+  If the file specified by File with an authentication status specified by 

+  AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.

+

+  If the file specified by File with an authentication status specified by 

+  AuthenticationStatus is not safe for the DXE Core to use under any circumstances, 

+  then EFI_ACCESS_DENIED is returned.

+

+  If the file specified by File with an authentication status specified by 

+  AuthenticationStatus is not safe for the DXE Core to use right now, but it 

+  might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is 

+  returned.

+

+  @param  This The EFI_SECURITY_ARCH_PROTOCOL instance.

+  

+  @param  AuthenticationStatus This is the authentication type returned from the Section

+  Extraction protocol.  See the Section Extraction Protocol

+  Specification for details on this type.

+  

+  @param  File This is a pointer to the device path of the file that is

+  being dispatched.  This will optionally be used for logging.

+

+  @retval  EFI_SUCCESS The file specified by File did authenticate, and the

+  platform policy dictates that the DXE Core may use File.

+  

+  @retval  EFI_INVALID_PARAMETER Driver is NULL.

+  

+  @retval  EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and

+  the platform policy dictates that File should be placed

+  in the untrusted state.   A file may be promoted from

+  the untrusted to the trusted state at a future time

+  with a call to the Trust() DXE Service.

+  

+  @retval  EFI_ACCESS_DENIED The file specified by File did not authenticate, and

+  the platform policy dictates that File should not be

+  used for any purpose.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (

+  IN EFI_SECURITY_ARCH_PROTOCOL     *This,

+  IN  UINT32                        AuthenticationStatus,

+  IN  EFI_DEVICE_PATH_PROTOCOL      *File

+  )

+;

+

+//

+// Interface stucture for the Timer Architectural Protocol

+//

+/**

+  @par Protocol Description:

+

+  The EFI_SECURITY_ARCH_PROTOCOL is used to abstract platform-specific policy

+  from the DXE core.  This includes locking flash upon failure to authenticate, 

+  attestation logging, and other exception operations.

+

+  The driver that produces the EFI_SECURITY_ARCH_PROTOCOL may also optionally 

+  install the EFI_SECURITY_POLICY_PROTOCOL_GUID onto a new handle with a NULL 

+  interface.  The existence of this GUID in the protocol database means that 

+  the GUIDed Section Extraction Protocol should authenticate the contents of 

+  an Authentication Section.  The expectation is that the GUIDed Section 

+  Extraction protocol will look for the existence of the EFI_SECURITY_POLICY_ 

+  PROTOCOL_GUID in the protocol database.  If it exists, then the publication 

+  thereof is taken as an injunction to attempt an authentication of any section 

+  wrapped in an Authentication Section.  See the Firmware File System 

+  Specification for details on the GUIDed Section Extraction Protocol and 

+  Authentication Sections.

+

+  @par Protocol Parameters:

+

+  FileAuthenticationState - This service is called upon fault with respect to 

+  the authentication of a section of a file.

+

+**/

+struct _EFI_SECURITY_ARCH_PROTOCOL {

+  EFI_SECURITY_FILE_AUTHENTICATION_STATE  FileAuthenticationState;

+};

+

+extern EFI_GUID gEfiSecurityArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/SecurityPolicy.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/SecurityPolicy.h
new file mode 100644
index 0000000..b46267e
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/SecurityPolicy.h
@@ -0,0 +1,31 @@
+/** @file

+  Security Policy protocol as defined in the DXE CIS

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SecurityPolicy.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef _SECURITY_POLICY_H_

+#define _SECURITY_POLICY_H_

+

+//

+// Security policy protocol GUID definition

+//

+#define EFI_SECURITY_POLICY_PROTOCOL_GUID  \

+  {0x78E4D245, 0xCD4D, 0x4a05, {0xA2, 0xBA, 0x47, 0x43, 0xE8, 0x6C, 0xFC, 0xAB} }

+

+extern EFI_GUID gEfiSecurityPolicyProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/StatusCode.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/StatusCode.h
new file mode 100644
index 0000000..6440dc3
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/StatusCode.h
@@ -0,0 +1,82 @@
+/** @file

+  Status code Runtime Protocol as defined in the DXE CIS

+

+  The StatusCode () Tiano service is added to the EFI system table and the 

+  EFI_STATUS_CODE_ARCH_PROTOCOL_GUID protocol is registered with a NULL 

+  pointer.

+

+  No CRC of the EFI system table is required, as it is done in the DXE core.

+

+  This code abstracts Status Code reporting.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  StatusCode.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __STATUS_CODE_RUNTIME_PROTOCOL_H__

+#define __STATUS_CODE_RUNTIME_PROTOCOL_H__

+

+#define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID  \

+{ 0xd2b2b828, 0x826, 0x48a7,  { 0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0 } }

+

+/**

+  Provides an interface that a software module can call to report a status code.

+

+  @param  Type Indicates the type of status code being reported.

+  

+  @param  Value Describes the current status of a hardware or software entity.

+  This included information about the class and subclass that is used to 

+  classify the entity as well as an operation.

+  

+  @param  Instance The enumeration of a hardware or software entity within 

+  the system. Valid instance numbers start with 1.

+  

+  @param  CallerId This optional parameter may be used to identify the caller.

+  This parameter allows the status code driver to apply different rules to 

+  different callers.

+  

+  @param  Data This optional parameter may be used to pass additional data.

+

+  @retval EFI_SUCCESS The function completed successfully

+  

+  @retval EFI_DEVICE_ERROR The function should not be completed due to a device error.

+

+**/

+typedef

+EFI_STATUS 

+(EFIAPI *EFI_REPORT_STATUS_CODE) (

+  IN EFI_STATUS_CODE_TYPE     Type,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId  OPTIONAL,

+  IN EFI_STATUS_CODE_DATA     *Data      OPTIONAL

+  );

+

+/**

+  @par Protocol Description:

+  Provides the service required to report a status code to the platform firmware.

+  This protocol must be produced by a runtime DXE driver and may be consumed 

+  only by the DXE Foundation.

+

+  @param ReportStatusCode Emit a status code.

+

+**/

+typedef struct _EFI_STATUS_CODE_PROTOCOL {

+  EFI_REPORT_STATUS_CODE         ReportStatusCode;

+} EFI_STATUS_CODE_PROTOCOL;

+

+extern EFI_GUID gEfiStatusCodeRuntimeProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Timer.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Timer.h
new file mode 100644
index 0000000..330f4cf
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Timer.h
@@ -0,0 +1,222 @@
+/** @file

+  Timer Architectural Protocol as defined in the DXE CIS

+

+  This code is used to provide the timer tick for the DXE core.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Timer.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_TIMER_H__

+#define __ARCH_PROTOCOL_TIMER_H__

+

+//

+// Global ID for the Timer Architectural Protocol

+//

+#define EFI_TIMER_ARCH_PROTOCOL_GUID \

+  { 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+//

+// Declare forward reference for the Timer Architectural Protocol

+//

+typedef struct _EFI_TIMER_ARCH_PROTOCOL   EFI_TIMER_ARCH_PROTOCOL;

+

+/**

+  This function of this type is called when a timer interrupt fires.  This 

+  function executes at TPL_HIGH_LEVEL.  The DXE Core will register a funtion

+  of tyis type to be called for the timer interrupt, so it can know how much 

+  time has passed.  This information is used to signal timer based events.  

+

+  @param  Time Time since the last timer interrupt in 100 ns units.  This will

+  typically be TimerPeriod, but if a timer interrupt is missed, and the

+  EFI_TIMER_ARCH_PROTOCOL driver can detect missed interrupts, then Time

+  will contain the actual amount of time since the last interrupt.

+

+  None.

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_TIMER_NOTIFY) (

+  IN UINT64  Time

+  );

+

+/**

+  This function registers the handler NotifyFunction so it is called every time 

+  the timer interrupt fires.  It also passes the amount of time since the last 

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the 

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is 

+  returned.  If the CPU does not support registering a timer interrupt handler, 

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler 

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.  

+  If an attempt is made to unregister a handler when a handler is not registered, 

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to 

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR 

+  is returned.

+

+  @param  This The EFI_TIMER_ARCH_PROTOCOL instance.

+  

+  @param  NotifyFunction The function to call when a timer interrupt fires.  This

+  function executes at TPL_HIGH_LEVEL.  The DXE Core will

+  register a handler for the timer interrupt, so it can know

+  how much time has passed.  This information is used to

+  signal timer based events.  NULL will unregister the handler.

+

+  @retval  EFI_SUCCESS The timer handler was registered.

+  

+  @retval  EFI_UNSUPPORTED The platform does not support timer interrupts.

+  

+  @retval  EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already

+  registered.

+  

+  @retval  EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not

+  previously registered.

+  

+  @retval  EFI_DEVICE_ERROR The timer handler could not be registered.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TIMER_REGISTER_HANDLER) (

+  IN EFI_TIMER_ARCH_PROTOCOL    *This,

+  IN EFI_TIMER_NOTIFY           NotifyFunction

+);

+

+/**

+  This function adjusts the period of timer interrupts to the value specified 

+  by TimerPeriod.  If the timer period is updated, then the selected timer 

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If 

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.  

+  If an error occurs while attempting to update the timer period, then the 

+  timer hardware will be put back in its state prior to this call, and 

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt 

+  is disabled.  This is not the same as disabling the CPU's interrupts.  

+  Instead, it must either turn off the timer hardware, or it must adjust the 

+  interrupt controller so that a CPU interrupt is not generated when the timer 

+  interrupt fires. 

+

+  @param  This The EFI_TIMER_ARCH_PROTOCOL instance.

+  

+  @param  TimerPeriod The rate to program the timer interrupt in 100 nS units.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is

+  returned.  If the timer is programmable, then the timer period

+  will be rounded up to the nearest timer period that is supported

+  by the timer hardware.  If TimerPeriod is set to 0, then the

+  timer interrupts will be disabled.

+

+  @retval  EFI_SUCCESS The timer period was changed.

+  

+  @retval  EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.

+  

+  @retval  EFI_DEVICE_ERROR The timer period could not be changed due to a device error.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TIMER_SET_TIMER_PERIOD) (

+  IN EFI_TIMER_ARCH_PROTOCOL    *This,

+  IN UINT64                     TimerPeriod

+  );

+

+/**

+  This function retrieves the period of timer interrupts in 100 ns units, 

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod 

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is 

+  returned, then the timer is currently disabled.

+

+  @param  This The EFI_TIMER_ARCH_PROTOCOL instance.

+  

+  @param  TimerPeriod A pointer to the timer period to retrieve in 100 ns units.  If

+  0 is returned, then the timer is currently disabled.

+

+  @retval  EFI_SUCCESS The timer period was returned in TimerPeriod.

+  

+  @retval  EFI_INVALID_PARAMETER TimerPeriod is NULL.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TIMER_GET_TIMER_PERIOD) (

+  IN EFI_TIMER_ARCH_PROTOCOL      *This,

+  OUT UINT64                      *TimerPeriod

+  );

+

+/**

+  This function generates a soft timer interrupt. If the platform does not support soft 

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. 

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() 

+  service, then a soft timer interrupt will be generated. If the timer interrupt is 

+  enabled when this service is called, then the registered handler will be invoked. The 

+  registered handler should not be able to distinguish a hardware-generated timer 

+  interrupt from a software-generated timer interrupt.

+

+  @param  This The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS The soft timer interrupt was generated.

+  

+  @retval  EFI_UNSUPPORTEDT The platform does not support the generation of soft timer interrupts.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TIMER_GENERATE_SOFT_INTERRUPT) (

+  IN EFI_TIMER_ARCH_PROTOCOL    *This

+  );

+

+

+/**

+  Interface stucture for the Timer Architectural Protocol.

+

+  @par Protocol Description:

+  This protocol provides the services to initialize a periodic timer 

+  interrupt, and to register a handler that is called each time the timer

+  interrupt fires.  It may also provide a service to adjust the rate of the

+  periodic timer interrupt.  When a timer interrupt occurs, the handler is 

+  passed the amount of time that has passed since the previous timer 

+  interrupt.

+

+  @param RegisterHandler

+  Registers a handler that will be called each time the 

+  timer interrupt fires.  TimerPeriod defines the minimum 

+  time between timer interrupts, so TimerPeriod will also 

+  be the minimum time between calls to the registered 

+  handler.

+

+  @param SetTimerPeriod

+  Sets the period of the timer interrupt in 100 nS units.  

+  This function is optional, and may return EFI_UNSUPPORTED.  

+  If this function is supported, then the timer period will 

+  be rounded up to the nearest supported timer period.

+

+  @param GetTimerPeriod

+  Retrieves the period of the timer interrupt in 100 nS units.

+

+  @param GenerateSoftInterrupt

+  Generates a soft timer interrupt that simulates the firing of 

+  the timer interrupt. This service can be used to invoke the 

+  registered handler if the timer interrupt has been masked for 

+  a period of time.

+

+**/

+struct _EFI_TIMER_ARCH_PROTOCOL {

+  EFI_TIMER_REGISTER_HANDLER          RegisterHandler;

+  EFI_TIMER_SET_TIMER_PERIOD          SetTimerPeriod;

+  EFI_TIMER_GET_TIMER_PERIOD          GetTimerPeriod;

+  EFI_TIMER_GENERATE_SOFT_INTERRUPT   GenerateSoftInterrupt;

+};

+

+extern EFI_GUID gEfiTimerArchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/Variable.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/Variable.h
new file mode 100644
index 0000000..13eb113
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/Variable.h
@@ -0,0 +1,39 @@
+/** @file

+  Variable Architectural Protocol as defined in the DXE CIS

+

+  This code is used to produce the EFI 1.0 runtime variable services

+

+  The GetVariable (), GetNextVariableName (), and SetVariable () EFI 1.0 

+  services are added to the EFI system table and the 

+  EFI_VARIABLE_ARCH_PROTOCOL_GUID protocol is registered with a NULL pointer.

+

+  No CRC of the EFI system table is required, as it is done in the DXE core.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Variable.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_VARIABLE_ARCH_H__

+#define __ARCH_PROTOCOL_VARIABLE_ARCH_H__

+

+//

+// Global ID for the Variable Architectural Protocol

+//

+#define EFI_VARIABLE_ARCH_PROTOCOL_GUID \

+  { 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }

+

+extern EFI_GUID gEfiVariableArchProtocolGuid;

+

+#endif 

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/VariableWrite.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/VariableWrite.h
new file mode 100644
index 0000000..8c21df5
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/VariableWrite.h
@@ -0,0 +1,38 @@
+/** @file

+  Variable Write Architectural Protocol as defined in the DXE CIS

+

+  This code is used to produce the EFI 1.0 runtime variable services

+

+  The SetVariable () EFI 1.0 services may be updated to the EFI system table and the 

+  EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID protocol is registered with a NULL pointer.

+

+  No CRC of the EFI system table is required, as it is done in the DXE core.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  VariableWrite.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_VARIABLE_WRITE_ARCH_H__

+#define __ARCH_PROTOCOL_VARIABLE_WRITE_ARCH_H__

+

+//

+// Global ID for the Variable Write Architectural Protocol

+//

+#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \

+  { 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53 } }

+

+extern EFI_GUID gEfiVariableWriteArchProtocolGuid;

+

+#endif 

diff --git a/edk2/MdePkg/Include/Dxe/ArchProtocol/WatchdogTimer.h b/edk2/MdePkg/Include/Dxe/ArchProtocol/WatchdogTimer.h
new file mode 100644
index 0000000..a8d84b1
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/ArchProtocol/WatchdogTimer.h
@@ -0,0 +1,172 @@
+/** @file

+  Watchdog Timer Architectural Protocol as defined in the DXE CIS

+

+  Used to provide system watchdog timer services

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  WatchdogTimer.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __ARCH_PROTOCOL_WATCHDOG_TIMER_H__

+#define __ARCH_PROTOCOL_WATCHDOG_TIMER_H__

+

+//

+// Global ID for the Watchdog Timer Architectural Protocol

+//

+#define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \

+  { 0x665E3FF5, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }

+

+//

+// Declare forward reference for the Timer Architectural Protocol

+//

+typedef struct _EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL;

+

+/**

+  A function of this type is called when the watchdog timer fires if a 

+  handler has been registered.

+

+  @param  Time The time in 100 ns units that has passed since the watchdog

+  timer was armed.  For the notify function to be called, this

+  must be greater than TimerPeriod.

+

+  @return None.

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_WATCHDOG_TIMER_NOTIFY) (

+  IN UINT64  Time

+  );

+

+/**

+  This function registers a handler that is to be invoked when the watchdog 

+  timer fires.  By default, the EFI_WATCHDOG_TIMER protocol will call the 

+  Runtime Service ResetSystem() when the watchdog timer fires.  If a 

+  NotifyFunction is registered, then the NotifyFunction will be called before 

+  the Runtime Service ResetSystem() is called.  If NotifyFunction is NULL, then 

+  the watchdog handler is unregistered.  If a watchdog handler is registered, 

+  then EFI_SUCCESS is returned.  If an attempt is made to register a handler 

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.  

+  If an attempt is made to uninstall a handler when a handler is not installed, 

+  then return EFI_INVALID_PARAMETER.

+

+  @param  This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+  

+  @param  NotifyFunction The function to call when the watchdog timer fires.  If this

+  is NULL, then the handler will be unregistered.

+

+  @retval  EFI_SUCCESS The watchdog timer handler was registered or

+  unregistered.

+  

+  @retval  EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already

+  registered.

+  

+  @retval  EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not

+  previously registered.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_WATCHDOG_TIMER_REGISTER_HANDLER) (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_WATCHDOG_TIMER_NOTIFY         NotifyFunction

+  );

+

+/**

+  This function sets the amount of time to wait before firing the watchdog 

+  timer to TimerPeriod 100 nS units.  If TimerPeriod is 0, then the watchdog 

+  timer is disabled.

+

+  @param  This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+  

+  @param  TimerPeriod The amount of time in 100 nS units to wait before the watchdog

+  timer is fired.  If TimerPeriod is zero, then the watchdog

+  timer is disabled.

+

+  @retval  EFI_SUCCESS The watchdog timer has been programmed to fire in Time

+  100 nS units.

+  

+  @retval  EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device

+  error.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) (

+  IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                            TimerPeriod

+  );

+

+/**

+  This function retrieves the amount of time the system will wait before firing 

+  the watchdog timer.  This period is returned in TimerPeriod, and EFI_SUCCESS 

+  is returned.  If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned.

+

+  @param  This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+  

+  @param  TimerPeriod A pointer to the amount of time in 100 nS units that the system

+  will wait before the watchdog timer is fired.  If TimerPeriod of

+  zero is returned, then the watchdog timer is disabled.

+

+  @retval  EFI_SUCCESS The amount of time that the system will wait before

+  firing the watchdog timer was returned in TimerPeriod.

+  

+  @retval  EFI_INVALID_PARAMETER TimerPeriod is NULL.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) (

+  IN  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *This,

+  OUT UINT64                            *TimerPeriod

+  );

+

+

+/**

+  Interface stucture for the Watchdog Timer Architectural Protocol.

+

+  @par Protocol Description:

+  This protocol provides the services required to implement the Boot Service 

+  SetWatchdogTimer().  It provides a service to set the amount of time to wait 

+  before firing the watchdog timer, and it also provides a service to register 

+  a handler that is invoked when the watchdog timer fires.  This protocol can 

+  implement the watchdog timer by using the event and timer Boot Services, or 

+  it can make use of custom hardware.  When the watchdog timer fires, control 

+  will be passed to a handler if one has been registered.  If no handler has 

+  been registered, or the registered handler returns, then the system will be 

+  reset by calling the Runtime Service ResetSystem().

+

+  @param RegisterHandler - Registers a handler that is invoked when the watchdog 

+  timer fires.

+

+  @param SetTimerPeriod  - Sets the amount of time in 100 ns units to wait before the 

+  watchdog timer is fired.  If this function is supported, 

+  then the watchdog timer period will be rounded up to the 

+  nearest supported watchdog timer period.

+

+  @param GetTimerPeriod  - Retrieves the amount of time in 100 ns units that the 

+  system will wait before the watchdog timer is fired.

+

+**/

+struct _EFI_WATCHDOG_TIMER_ARCH_PROTOCOL {

+  EFI_WATCHDOG_TIMER_REGISTER_HANDLER  RegisterHandler;

+  EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD  SetTimerPeriod;

+  EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD  GetTimerPeriod;

+};

+

+extern EFI_GUID gEfiWatchdogTimerArchProtocolGuid;

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Dxe/DxeCis.h b/edk2/MdePkg/Include/Dxe/DxeCis.h
new file mode 100644
index 0000000..a36481c
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/DxeCis.h
@@ -0,0 +1,589 @@
+/** @file

+  Include file matches things in the DXE CIS.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DxeCis.h

+

+  @par Revision Reference:

+  Version 0.91B.

+

+**/

+

+#ifndef __DXE_CIS__

+#define __DXE_CIS__

+

+#include <Uefi/UefiSpec.h>

+

+

+#define TIANO_ERROR(a)              (MAX_2_BITS | (a))

+

+#if (EFI_SPECIFICATION_VERSION < 0x00020000)

+//

+// Tiano added a couple of return types. These are owned by UEFI specification

+//  and Tiano can not use them. Thus for UEFI 2.0/R9 support we moved the values

+//  to a UEFI OEM extension range to conform to UEFI specification.

+//

+#define EFI_NOT_AVAILABLE_YET   EFIERR (28)

+#define EFI_UNLOAD_IMAGE        EFIERR (29)

+#else

+#define EFI_NOT_AVAILABLE_YET   TIANO_ERROR (0)

+#define EFI_UNLOAD_IMAGE        TIANO_ERROR (1)

+#endif

+

+//

+// BugBug: Implementation contamination of UEFI 2.0

+// Pointer to internal runtime pointer

+//

+#define EFI_IPF_GP_POINTER  0x00000008

+

+

+//

+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+//

+

+//

+// attributes for reserved memory before it is promoted to system memory

+//

+#define EFI_MEMORY_PRESENT      0x0100000000000000ULL

+#define EFI_MEMORY_INITIALIZED  0x0200000000000000ULL

+#define EFI_MEMORY_TESTED       0x0400000000000000ULL

+

+//

+// range for memory mapped port I/O on IPF

+//

+#define EFI_MEMORY_PORT_IO  0x4000000000000000ULL

+

+//

+// Modifier for EFI DXE Services

+//

+#define EFI_DXESERVICE

+

+

+//

+// Global Coherencey Domain types

+//

+typedef enum {

+  EfiGcdMemoryTypeNonExistent,

+  EfiGcdMemoryTypeReserved,

+  EfiGcdMemoryTypeSystemMemory,

+  EfiGcdMemoryTypeMemoryMappedIo,

+  EfiGcdMemoryTypeMaximum

+} EFI_GCD_MEMORY_TYPE;

+

+typedef enum {

+  EfiGcdIoTypeNonExistent,

+  EfiGcdIoTypeReserved,

+  EfiGcdIoTypeIo,

+  EfiGcdIoTypeMaximum

+} EFI_GCD_IO_TYPE;

+

+typedef enum {

+  EfiGcdAllocateAnySearchBottomUp,

+  EfiGcdAllocateMaxAddressSearchBottomUp,

+  EfiGcdAllocateAddress,

+  EfiGcdAllocateAnySearchTopDown,

+  EfiGcdAllocateMaxAddressSearchTopDown,

+  EfiGcdMaxAllocateType

+} EFI_GCD_ALLOCATE_TYPE;

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  BaseAddress;

+  UINT64                Length;

+  UINT64                Capabilities;

+  UINT64                Attributes;

+  EFI_GCD_MEMORY_TYPE   GcdMemoryType;

+  EFI_HANDLE            ImageHandle;

+  EFI_HANDLE            DeviceHandle;

+} EFI_GCD_MEMORY_SPACE_DESCRIPTOR;

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  BaseAddress;

+  UINT64                Length;

+  EFI_GCD_IO_TYPE       GcdIoType;

+  EFI_HANDLE            ImageHandle;

+  EFI_HANDLE            DeviceHandle;

+} EFI_GCD_IO_SPACE_DESCRIPTOR;

+

+/**

+  Adds reserved memory, system memory, or memory-mapped I/O resources to the

+  global coherency domain of the processor.

+

+  @param  GcdMemoryType Memory type of the memory space.

+  

+  @param  BaseAddress Base address of the memory space.

+  

+  @param  Length Length of the memory space.

+  

+  @param  Capabilities alterable attributes of the memory space.

+

+  @retval  EFI_SUCCESS Merged this memory space into GCD map.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ADD_MEMORY_SPACE) (

+  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length,

+  IN UINT64                Capabilities

+  )

+;

+

+/**

+  Allocates nonexistent memory, reserved memory, system memory, or memorymapped

+  I/O resources from the global coherency domain of the processor.

+

+  @param  GcdAllocateType The type of allocate operation

+  

+  @param  GcdMemoryType The desired memory type

+  

+  @param  Alignment Align with 2^Alignment

+  

+  @param  Length Length to allocate

+  

+  @param  BaseAddress Base address to allocate

+  

+  @param  Imagehandle The image handle consume the allocated space.

+  

+  @param  DeviceHandle The device handle consume the allocated space.

+

+  @retval  EFI_INVALID_PARAMETER Invalid parameter.

+  

+  @retval  EFI_NOT_FOUND No descriptor contains the desired space.

+  

+  @retval  EFI_SUCCESS Memory space successfully allocated.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ALLOCATE_MEMORY_SPACE) (

+  IN     EFI_GCD_ALLOCATE_TYPE               GcdAllocateType,

+  IN     EFI_GCD_MEMORY_TYPE                 GcdMemoryType,

+  IN     UINTN                               Alignment,

+  IN     UINT64                              Length,

+  IN OUT EFI_PHYSICAL_ADDRESS                *BaseAddress,

+  IN     EFI_HANDLE                          ImageHandle,

+  IN     EFI_HANDLE                          DeviceHandle OPTIONAL

+  )

+;

+

+/**

+  Frees nonexistent memory, reserved memory, system memory, or memory-mapped

+  I/O resources from the global coherency domain of the processor.

+

+  @param  BaseAddress Base address of the segment.

+  

+  @param  Length Length of the segment.

+

+  @retval  EFI_SUCCESS Space successfully freed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FREE_MEMORY_SPACE) (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+;

+

+/**

+  Removes reserved memory, system memory, or memory-mapped I/O resources from

+  the global coherency domain of the processor.

+

+  @param  BaseAddress Base address of the memory space.

+  

+  @param  Length Length of the memory space.

+

+  @retval  EFI_SUCCESS Successfully remove a segment of memory space.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_REMOVE_MEMORY_SPACE) (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+;

+

+/**

+  Retrieves the descriptor for a memory region containing a specified address.

+

+  @param  BaseAddress Specified start address

+  

+  @param  Descriptor Specified length

+

+  @retval  EFI_INVALID_PARAMETER Invalid parameter

+  

+  @retval  EFI_SUCCESS Successfully get memory space descriptor.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_MEMORY_SPACE_DESCRIPTOR) (

+  IN  EFI_PHYSICAL_ADDRESS             BaseAddress,

+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor

+  )

+;

+

+/**

+  Modifies the attributes for a memory region in the global coherency domain of the

+  processor.

+

+  @param  BaseAddress Specified start address

+  

+  @param  Length Specified length

+  

+  @param  Attributes Specified attributes

+

+  @retval  EFI_SUCCESS Successfully set attribute of a segment of memory space.

+

+**/

+typedef

+

+EFI_STATUS

+(EFIAPI *EFI_SET_MEMORY_SPACE_ATTRIBUTES) (

+  IN EFI_PHYSICAL_ADDRESS         BaseAddress,

+  IN UINT64                       Length,

+  IN UINT64                       Attributes

+  )

+;

+

+/**

+  Returns a map of the memory resources in the global coherency domain of the

+  processor.

+

+  @param  NumberOfDescriptors Number of descriptors.

+  

+  @param  MemorySpaceMap Descriptor array

+

+  @retval  EFI_INVALID_PARAMETER Invalid parameter

+  

+  @retval  EFI_OUT_OF_RESOURCES No enough buffer to allocate

+  

+  @retval  EFI_SUCCESS Successfully get memory space map.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_MEMORY_SPACE_MAP) (

+  OUT UINTN                            *NumberOfDescriptors,

+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  **MemorySpaceMap

+  )

+;

+

+/**

+  Adds reserved I/O or I/O resources to the global coherency domain of the processor.

+

+  @param  GcdIoType IO type of the segment.

+  

+  @param  BaseAddress Base address of the segment.

+  

+  @param  Length Length of the segment.

+

+  @retval  EFI_SUCCESS Merged this segment into GCD map.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ADD_IO_SPACE) (

+  IN EFI_GCD_IO_TYPE       GcdIoType,

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+;

+

+/**

+  Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency

+  domain of the processor.

+

+  @param  GcdAllocateType The type of allocate operation

+  

+  @param  GcdIoType The desired IO type

+  

+  @param  Alignment Align with 2^Alignment

+  

+  @param  Length Length to allocate

+  

+  @param  BaseAddress Base address to allocate

+  

+  @param  Imagehandle The image handle consume the allocated space.

+  

+  @param  DeviceHandle The device handle consume the allocated space.

+

+  @retval  EFI_INVALID_PARAMETER Invalid parameter.

+  

+  @retval  EFI_NOT_FOUND No descriptor contains the desired space.

+  

+  @retval  EFI_SUCCESS IO space successfully allocated.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ALLOCATE_IO_SPACE) (

+  IN     EFI_GCD_ALLOCATE_TYPE               GcdAllocateType,

+  IN     EFI_GCD_IO_TYPE                     GcdIoType,

+  IN     UINTN                               Alignment,

+  IN     UINT64                              Length,

+  IN OUT EFI_PHYSICAL_ADDRESS                *BaseAddress,

+  IN     EFI_HANDLE                          ImageHandle,

+  IN     EFI_HANDLE                          DeviceHandle OPTIONAL

+  )

+;

+

+/**

+  Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency

+  domain of the processor.

+

+  @param  BaseAddress Base address of the segment.

+  

+  @param  Length Length of the segment.

+

+  @retval  EFI_SUCCESS Space successfully freed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FREE_IO_SPACE) (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+;

+

+/**

+  Removes reserved I/O or I/O resources from the global coherency domain of the

+  processor.

+

+  @param  BaseAddress Base address of the segment.

+  

+  @param  Length Length of the segment.

+

+  @retval  EFI_SUCCESS Successfully removed a segment of IO space.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_REMOVE_IO_SPACE) (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,

+  IN UINT64                Length

+  )

+;

+

+/**

+  Retrieves the descriptor for an I/O region containing a specified address.

+

+  @param  BaseAddress Specified start address

+  

+  @param  Descriptor Specified length

+

+  @retval  EFI_INVALID_PARAMETER Descriptor is NULL.

+  

+  @retval  EFI_SUCCESS Successfully get the IO space descriptor.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_IO_SPACE_DESCRIPTOR) (

+  IN  EFI_PHYSICAL_ADDRESS         BaseAddress,

+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor

+  )

+;

+

+/**

+  Returns a map of the I/O resources in the global coherency domain of the processor.

+

+  @param  NumberOfDescriptors Number of descriptors.

+  

+  @param  MemorySpaceMap Descriptor array

+

+  @retval  EFI_INVALID_PARAMETER Invalid parameter

+  

+  @retval  EFI_OUT_OF_RESOURCES No enough buffer to allocate

+  

+  @retval  EFI_SUCCESS Successfully get IO space map.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_IO_SPACE_MAP) (

+  OUT UINTN                        *NumberOfDescriptors,

+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  **IoSpaceMap

+  )

+;

+

+/**

+  Loads and executed DXE drivers from firmware volumes.

+

+  @return Status code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISPATCH) (VOID)

+;

+

+/**

+  Clears the Schedule on Request (SOR) flag for a component that is stored in a firmware volume.

+

+  @param  FirmwareVolumeHandle The handle of the firmware volume that contains the file specified by FileName.

+  

+  @param  DriverName A pointer to the name of the file in a firmware volume.

+

+  @return Status code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCHEDULE) (

+  IN EFI_HANDLE  FirmwareVolumeHandle,

+  IN EFI_GUID    *DriverName

+  )

+;

+

+/**

+  Promotes a file stored in a firmware volume from the untrusted to the trusted state.

+

+  @param  FirmwareVolumeHandle The handle of the firmware volume that contains the file specified by FileName.

+  

+  @param  DriverName A pointer to the name of the file in a firmware volume.

+

+  @return Status code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TRUST) (

+  IN EFI_HANDLE  FirmwareVolumeHandle,

+  IN EFI_GUID    *DriverName

+  )

+;

+

+/**

+  Creates a firmware volume handle for a firmware volume that is present in system memory.

+

+  @param  FirmwareVolumeHeader A pointer to the header of the firmware volume.

+  @param  Size The size, in bytes, of the firmware volume.

+  @param  FirmwareVolumeHandle On output, a pointer to the created handle.

+

+  @return Status code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PROCESS_FIRMWARE_VOLUME) (

+  IN VOID                             *FvHeader,

+  IN UINTN                            Size,

+  OUT EFI_HANDLE                      *FirmwareVolumeHandle

+  )

+;

+

+//

+// DXE Services Table

+//

+#define EFI_DXE_SERVICES_SIGNATURE  0x565245535f455844ULL

+#define EFI_DXE_SERVICES_REVISION   ((0 << 16) | (25))

+

+typedef struct {

+  EFI_TABLE_HEADER                Hdr;

+

+  //

+  // Global Coherency Domain Services

+  //

+  EFI_ADD_MEMORY_SPACE            AddMemorySpace;

+  EFI_ALLOCATE_MEMORY_SPACE       AllocateMemorySpace;

+  EFI_FREE_MEMORY_SPACE           FreeMemorySpace;

+  EFI_REMOVE_MEMORY_SPACE         RemoveMemorySpace;

+  EFI_GET_MEMORY_SPACE_DESCRIPTOR GetMemorySpaceDescriptor;

+  EFI_SET_MEMORY_SPACE_ATTRIBUTES SetMemorySpaceAttributes;

+  EFI_GET_MEMORY_SPACE_MAP        GetMemorySpaceMap;

+  EFI_ADD_IO_SPACE                AddIoSpace;

+  EFI_ALLOCATE_IO_SPACE           AllocateIoSpace;

+  EFI_FREE_IO_SPACE               FreeIoSpace;

+  EFI_REMOVE_IO_SPACE             RemoveIoSpace;

+  EFI_GET_IO_SPACE_DESCRIPTOR     GetIoSpaceDescriptor;

+  EFI_GET_IO_SPACE_MAP            GetIoSpaceMap;

+

+  //

+  // Dispatcher Services

+  //

+  EFI_DISPATCH                    Dispatch;

+  EFI_SCHEDULE                    Schedule;

+  EFI_TRUST                       Trust;

+  //

+  // Service to process a single firmware volume found in a capsule

+  //

+  EFI_PROCESS_FIRMWARE_VOLUME     ProcessFirmwareVolume;

+} EFI_DXE_SERVICES;

+

+

+#include <Common/BootMode.h>

+#include <Common/BootScript.h>

+#include <Common/Capsule.h>

+#include <Common/Dependency.h>

+#include <Common/FirmwareVolumeImageFormat.h>

+#include <Common/FirmwareVolumeHeader.h>

+#include <Common/FirmwareFileSystem.h>

+#include <Common/Hob.h>

+#include <Common/InternalFormRepresentation.h>

+#include <Common/StatusCode.h>

+#include <Common/StatusCodeDataTypeId.h>

+

+#include <Guid/AcpiTableStorage.h>

+#include <Guid/Apriori.h>

+#include <Guid/Capsule.h>

+#include <Guid/DxeServices.h>

+#include <Guid/EventLegacyBios.h>

+#include <Guid/FirmwareFileSystem.h>

+#include <Guid/FrameworkDevicePath.h>

+#include <Guid/HobList.h>

+#include <Guid/MemoryAllocationHob.h>

+#include <Guid/SmramMemoryReserve.h>

+#include <Guid/StatusCodeDataTypeId.h>

+

+#include <Dxe/ArchProtocol/Bds.h>

+#include <Dxe/ArchProtocol/Cpu.h>

+#include <Dxe/ArchProtocol/Metronome.h>

+#include <Dxe/ArchProtocol/MonotonicCounter.h>

+#include <Dxe/ArchProtocol/RealTimeClock.h>

+#include <Dxe/ArchProtocol/Reset.h>

+#include <Dxe/ArchProtocol/Runtime.h>

+#include <Dxe/ArchProtocol/Security.h>

+#include <Dxe/ArchProtocol/SecurityPolicy.h>

+#include <Dxe/ArchProtocol/StatusCode.h>

+#include <Dxe/ArchProtocol/Timer.h>

+#include <Dxe/ArchProtocol/Variable.h>

+#include <Dxe/ArchProtocol/VariableWrite.h>

+#include <Dxe/ArchProtocol/WatchdogTimer.h>

+

+#include <Protocol/AcpiSupport.h>

+#include <Protocol/BootScriptSave.h>

+#include <Protocol/CpuIo.h>

+#include <Protocol/DataHub.h>

+#include <Protocol/FirmwareVolume.h>

+#include <Protocol/FirmwareVolumeBlock.h>

+#include <Protocol/FirmwareVolumeDispatch.h>

+#include <Protocol/Hii.h>

+#include <Protocol/FormBrowser.h>

+#include <Protocol/FormCallback.h>

+#include <Protocol/GuidedSectionExtraction.h>

+#include <Protocol/IdeControllerInit.h>

+#include <Protocol/IncompatiblePciDeviceSupport.h>

+#include <Protocol/PciHostBridgeResourceAllocation.h>

+#include <Protocol/PciHotPlugInit.h>

+#include <Protocol/PciPlatform.h>

+#include <Protocol/SectionExtraction.h>

+#include <Protocol/Smbus.h>

+#include <Protocol/LegacyBios.h>

+#include <Protocol/Legacy8259.h>

+#include <Protocol/LegacyRegion.h>

+#include <Protocol/LegacyBiosPlatform.h>

+#include <Protocol/LegacyInterrupt.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Dxe/SmmCis.h b/edk2/MdePkg/Include/Dxe/SmmCis.h
new file mode 100644
index 0000000..35a1a64
--- /dev/null
+++ b/edk2/MdePkg/Include/Dxe/SmmCis.h
@@ -0,0 +1,526 @@
+/** @file

+  Include file matches things in the Smm CIS spec.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmCis.h

+

+  @par Revision Reference:

+  Version 0.9.

+

+**/

+

+#ifndef __SMM_CIS__

+#define __SMM_CIS__

+

+#define EFI_SMM_CPU_IO_GUID \

+  { \

+    0x5f439a0b, 0x45d8, 0x4682, {0xa4, 0xf4, 0xf0, 0x57, 0x6b, 0x51, 0x34, 0x41 } \

+  }

+

+typedef struct _EFI_SMM_SYSTEM_TABLE              EFI_SMM_SYSTEM_TABLE;

+typedef struct _EFI_SMM_CPU_IO_INTERFACE          EFI_SMM_CPU_IO_INTERFACE;

+

+

+//

+// SMM Base specification constant and types

+//

+#define SMM_SMST_SIGNATURE            EFI_SIGNATURE_32 ('S', 'M', 'S', 'T')

+#define EFI_SMM_SYSTEM_TABLE_REVISION (0 << 16) | (0x09)

+

+//

+// *******************************************************

+// EFI_SMM_IO_WIDTH

+// *******************************************************

+//

+typedef enum {

+  SMM_IO_UINT8  = 0,

+  SMM_IO_UINT16 = 1,

+  SMM_IO_UINT32 = 2,

+  SMM_IO_UINT64 = 3

+} EFI_SMM_IO_WIDTH;

+

+/**

+  Provides the basic memory and I/O interfaces that are used to 

+  abstract accesses to devices.

+

+  @param  This The EFI_SMM_CPU_IO_INTERFACE instance.  

+  

+  @param  Width Signifies the width of the I/O operations. 

+  

+  @param  Address The base address of the I/O operations.

+  

+  @param  Count The number of I/O operations to perform. 

+  

+  @param  Buffer For read operations, the destination buffer to store the results.

+  For write operations, the source buffer from which to write data.

+

+  @retval EFI_SUCCESS The data was read from or written to the device.

+  

+  @retval EFI_UNSUPPORTED The Address is not valid for this system.

+  

+  @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.

+  

+  @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_CPU_IO) (

+  IN EFI_SMM_CPU_IO_INTERFACE         *This,

+  IN EFI_SMM_IO_WIDTH                 Width,

+  IN UINT64                           Address,

+  IN UINTN                            Count,

+  IN OUT VOID                         *Buffer

+  );

+

+typedef struct {

+  EFI_SMM_CPU_IO  Read;

+  EFI_SMM_CPU_IO  Write;

+} EFI_SMM_IO_ACCESS;

+

+struct _EFI_SMM_CPU_IO_INTERFACE {

+  EFI_SMM_IO_ACCESS Mem;

+  EFI_SMM_IO_ACCESS Io;

+};

+

+/**

+  Allocates pool memory from SMRAM for IA-32 or runtime memory for 

+  the Itanium processor family.

+

+  @param  PoolType The type of pool to allocate.The only supported type is EfiRuntimeServicesData

+  

+  @param  Size The number of bytes to allocate from the pool.

+  

+  @param  Buffer A pointer to a pointer to the allocated buffer if the call 

+  succeeds; undefined otherwise.

+

+  @retval EFI_SUCCESS  The requested number of bytes was allocated.

+  

+  @retval EFI_OUT_OF_RESOURCES  The pool requested could not be allocated.

+  

+  @retval EFI_UNSUPPORTED  In runtime.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMMCORE_ALLOCATE_POOL) (

+  IN EFI_MEMORY_TYPE                PoolType,

+  IN UINTN                          Size,

+  OUT VOID                          **Buffer

+  );

+

+/**

+  Returns pool memory to the system.

+

+  @param  Buffer Pointer to the buffer to free.

+

+  @retval EFI_SUCCESS  The memory was returned to the system.

+  

+  @retval EFI_INVALID_PARAMETER  Buffer was invalid.  

+  

+  @retval EFI_UNSUPPORTED  In runtime.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMMCORE_FREE_POOL) (

+  IN VOID                   *Buffer

+  );

+

+/**

+  Allocates memory pages from the system.

+

+  @param  Type The type of allocation to perform. 

+  

+  @param  MemoryType The only supported type is EfiRuntimeServicesData

+  

+  @param  NumberofPages The number of contiguous 4 KB pages to allocate

+  

+  @param  Memory Pointer to a physical address. On input, the way in which 

+  the address is used depends on the value of Type. On output, the address 

+  is set to the base of the page range that was allocated.

+

+  @retval EFI_SUCCESS  The requested pages were allocated.

+  

+  @retval EFI_OUT_OF_RESOURCES  The pages requested could not be allocated.

+  

+  @retval EFI_NOT_FOUND   The requested pages could not be found.

+  

+  @retval EFI_INVALID_PARAMETER  Type is not AllocateAnyPages or AllocateMaxAddress 

+  or AllocateAddress. Or MemoryType is in the range EfiMaxMemoryType..0x7FFFFFFF.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMMCORE_ALLOCATE_PAGES) (

+  IN EFI_ALLOCATE_TYPE      Type,

+  IN EFI_MEMORY_TYPE        MemoryType,

+  IN UINTN                  NumberOfPages,

+  OUT EFI_PHYSICAL_ADDRESS  *Memory

+  );

+

+/**

+  Frees memory pages for the system.

+

+  @param  Memory The base physical address of the pages to be freed

+  

+  @param  NumberOfPages The number of contiguous 4 KB pages to free.

+

+  @retval EFI_SUCCESS  The requested memory pages were freed.

+  

+  @retval EFI_INVALID_PARAMETER   Memory is not a page-aligned address or NumberOfPages is invalid.

+  

+  @retval EFI_NOT_FOUND   The requested memory pages were not allocated with SmmAllocatePages().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMMCORE_FREE_PAGES) (

+  IN EFI_PHYSICAL_ADDRESS   Memory,

+  IN UINTN                  NumberOfPages

+  );

+

+typedef

+VOID

+(EFIAPI *EFI_AP_PROCEDURE) (

+  IN  VOID                              *Buffer

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_STARTUP_THIS_AP) (

+  IN  EFI_AP_PROCEDURE                    Procedure,

+  IN  UINTN                               CpuNumber,

+  IN  OUT VOID                            *ProcArguments OPTIONAL

+  );

+

+typedef struct {

+  UINT8                 Reserved1[248];

+  UINT32                SMBASE;

+  UINT32                SMMRevId;

+  UINT16                IORestart;

+  UINT16                AutoHALTRestart;

+  UINT8                 Reserved2[164];

+  UINT32                ES;

+  UINT32                CS;

+  UINT32                SS;

+  UINT32                DS;

+  UINT32                FS;

+  UINT32                GS;

+  UINT32                LDTBase;

+  UINT32                TR;

+  UINT32                DR7;

+  UINT32                DR6;

+  UINT32                EAX;

+  UINT32                ECX;

+  UINT32                EDX;

+  UINT32                EBX;

+  UINT32                ESP;

+  UINT32                EBP;

+  UINT32                ESI;

+  UINT32                EDI;

+  UINT32                EIP;

+  UINT32                EFLAGS;

+  UINT32                CR3;

+  UINT32                CR0;

+} EFI_SMI_CPU_SAVE_STATE;

+

+typedef struct {

+  UINT64   reserved;         

+  UINT64   r1;

+  UINT64   r2;

+  UINT64   r3;

+  UINT64   r4;

+  UINT64   r5;

+  UINT64   r6;

+  UINT64   r7;

+  UINT64   r8;

+  UINT64   r9;

+  UINT64   r10;

+  UINT64   r11;

+  UINT64   r12;

+  UINT64   r13;

+  UINT64   r14;

+  UINT64   r15;

+  UINT64   r16;

+  UINT64   r17;

+  UINT64   r18;

+  UINT64   r19;

+  UINT64   r20;

+  UINT64   r21;

+  UINT64   r22;

+  UINT64   r23;

+  UINT64   r24;

+  UINT64   r25;

+  UINT64   r26;

+  UINT64   r27;

+  UINT64   r28;

+  UINT64   r29;

+  UINT64   r30;

+  UINT64   r31;

+

+  UINT64   pr;

+

+  UINT64   b0;

+  UINT64   b1;

+  UINT64   b2;

+  UINT64   b3;

+  UINT64   b4;

+  UINT64   b5;

+  UINT64   b6;

+  UINT64   b7;

+

+  // application registers

+  UINT64   ar_rsc;

+  UINT64   ar_bsp;

+  UINT64   ar_bspstore;

+  UINT64   ar_rnat;

+

+  UINT64   ar_fcr;

+

+  UINT64   ar_eflag;

+  UINT64   ar_csd;

+  UINT64   ar_ssd;

+  UINT64   ar_cflg;

+  UINT64   ar_fsr;

+  UINT64   ar_fir;

+  UINT64   ar_fdr;

+

+  UINT64   ar_ccv;

+

+  UINT64   ar_unat;

+

+  UINT64   ar_fpsr;

+

+  UINT64   ar_pfs;

+  UINT64   ar_lc;

+  UINT64   ar_ec;

+

+  // control registers

+  UINT64   cr_dcr;

+  UINT64   cr_itm;

+  UINT64   cr_iva;

+  UINT64   cr_pta;

+  UINT64   cr_ipsr;

+  UINT64   cr_isr;

+  UINT64   cr_iip;

+  UINT64   cr_ifa;

+  UINT64   cr_itir;

+  UINT64   cr_iipa;

+  UINT64   cr_ifs;

+  UINT64   cr_iim;

+  UINT64   cr_iha;

+

+  // debug registers

+  UINT64   dbr0;

+  UINT64   dbr1;

+  UINT64   dbr2;

+  UINT64   dbr3;

+  UINT64   dbr4;

+  UINT64   dbr5;

+  UINT64   dbr6;

+  UINT64   dbr7;

+

+  UINT64   ibr0;

+  UINT64   ibr1;

+  UINT64   ibr2;

+  UINT64   ibr3;

+  UINT64   ibr4;

+  UINT64   ibr5;

+  UINT64   ibr6;

+  UINT64   ibr7;

+

+  // virtual registers

+  UINT64   int_nat;         // nat bits for R1-R31

+

+} EFI_PMI_SYSTEM_CONTEXT;

+

+typedef union {

+  EFI_SMI_CPU_SAVE_STATE     Ia32SaveState;

+  EFI_PMI_SYSTEM_CONTEXT     ItaniumSaveState;

+} EFI_SMM_CPU_SAVE_STATE;

+

+typedef struct {

+  UINT16                Fcw;

+  UINT16                Fsw;

+  UINT16                Ftw;

+  UINT16                Opcode;

+  UINT32                Eip;

+  UINT16                Cs;

+  UINT16                Rsvd1;

+  UINT32                DataOffset;

+  UINT16                Ds;

+  UINT8                 Rsvd2[10];

+  UINT8                 St0Mm0[10], Rsvd3[6];

+  UINT8                 St0Mm1[10], Rsvd4[6];

+  UINT8                 St0Mm2[10], Rsvd5[6];

+  UINT8                 St0Mm3[10], Rsvd6[6];

+  UINT8                 St0Mm4[10], Rsvd7[6];

+  UINT8                 St0Mm5[10], Rsvd8[6];

+  UINT8                 St0Mm6[10], Rsvd9[6];

+  UINT8                 St0Mm7[10], Rsvd10[6];

+  UINT8                 Rsvd11[22*16];

+} EFI_SMI_OPTIONAL_FPSAVE_STATE;

+

+typedef struct {

+  UINT64   f2[2];

+  UINT64   f3[2];

+  UINT64   f4[2];

+  UINT64   f5[2];

+  UINT64   f6[2];

+  UINT64   f7[2];

+  UINT64   f8[2];

+  UINT64   f9[2];

+  UINT64   f10[2];

+  UINT64   f11[2];

+  UINT64   f12[2];

+  UINT64   f13[2];

+  UINT64   f14[2];

+  UINT64   f15[2];

+  UINT64   f16[2];

+  UINT64   f17[2];

+  UINT64   f18[2];

+  UINT64   f19[2];

+  UINT64   f20[2];

+  UINT64   f21[2];

+  UINT64   f22[2];

+  UINT64   f23[2];

+  UINT64   f24[2];

+  UINT64   f25[2];

+  UINT64   f26[2];

+  UINT64   f27[2];

+  UINT64   f28[2];

+  UINT64   f29[2];

+  UINT64   f30[2];

+  UINT64   f31[2];

+} EFI_PMI_OPTIONAL_FLOATING_POINT_CONTEXT;

+

+typedef union {

+  EFI_SMI_OPTIONAL_FPSAVE_STATE             Ia32FpSave;

+  EFI_PMI_OPTIONAL_FLOATING_POINT_CONTEXT   ItaniumFpSave;

+} EFI_SMM_FLOATING_POINT_SAVE_STATE;

+

+/**

+  This function is the main entry point for an SMM handler dispatch 

+  or communicate-based callback. 

+

+  @param  SmmImageHandle A unique value returned by the SMM infrastructure 

+  in response to registration for a communicate-based callback or dispatch. 

+  

+  @param  CommunicationBuffer An optional buffer that will be populated 

+  by the SMM infrastructure in response to a non-SMM agent (preboot or runtime) 

+  invoking the EFI_SMM_BASE_PROTOCOL.Communicate() service.

+  

+  @param  SourceSize If CommunicationBuffer is non-NULL, this field 

+  indicates the size of the data payload in this buffer.

+

+  @return Status Code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_HANDLER_ENTRY_POINT) (

+  IN EFI_HANDLE             SmmImageHandle,

+  IN OUT VOID               *CommunicationBuffer OPTIONAL,

+  IN OUT UINTN              *SourceSize OPTIONAL

+  );

+

+/**

+  The SmmInstallConfigurationTable() function is used to maintain the list 

+  of configuration tables that are stored in the System Management System 

+  Table.  The list is stored as an array of (GUID, Pointer) pairs.  The list 

+  must be allocated from pool memory with PoolType set to EfiRuntimeServicesData.

+

+  @param  SystemTable A pointer to the SMM System Table.

+  @param  Guid A pointer to the GUID for the entry to add, update, or remove.

+  @param  Table A pointer to the buffer of the table to add.

+  @param  TableSize The size of the table to install.

+

+  @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed.

+  @retval EFI_INVALID_PARAMETER Guid is not valid.

+  @retval EFI_NOT_FOUND An attempt was made to delete a non-existent entry.

+  @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_INSTALL_CONFIGURATION_TABLE) (

+  IN EFI_SMM_SYSTEM_TABLE         *SystemTable,

+  IN EFI_GUID                     *Guid,

+  IN VOID                         *Table,

+  IN UINTN                        TableSize

+  )

+;

+

+//

+// System Management System Table (SMST)

+//

+struct _EFI_SMM_SYSTEM_TABLE {

+  EFI_TABLE_HEADER                    Hdr;

+

+  CHAR16                              *SmmFirmwareVendor;

+  UINT32                              SmmFirmwareRevision;

+

+  EFI_SMM_INSTALL_CONFIGURATION_TABLE SmmInstallConfigurationTable;

+

+  //

+  // I/O Services

+  //

+  EFI_GUID                            EfiSmmCpuIoGuid;

+  EFI_SMM_CPU_IO_INTERFACE            SmmIo;

+

+  //

+  // Runtime memory service

+  //

+  EFI_SMMCORE_ALLOCATE_POOL           SmmAllocatePool;

+  EFI_SMMCORE_FREE_POOL               SmmFreePool;

+  EFI_SMMCORE_ALLOCATE_PAGES          SmmAllocatePages;

+  EFI_SMMCORE_FREE_PAGES              SmmFreePages;

+

+  //

+  // MP service

+  //

+  EFI_SMM_STARTUP_THIS_AP             SmmStartupThisAp;

+

+  //

+  // CPU information records

+  //

+  UINTN                               CurrentlyExecutingCpu;

+  UINTN                               NumberOfCpus;

+  EFI_SMM_CPU_SAVE_STATE              *CpuSaveState;

+  EFI_SMM_FLOATING_POINT_SAVE_STATE   *CpuOptionalFloatingPointState;

+

+  //

+  // Extensibility table

+  //

+  UINTN                               NumberOfTableEntries;

+  EFI_CONFIGURATION_TABLE             *SmmConfigurationTable;

+

+};

+

+#include <Guid/SmmCommunicate.h>

+#include <Guid/SmramMemoryReserve.h>

+#include <Protocol/SmmBase.h>

+#include <Protocol/SmmAccess.h>

+#include <Protocol/SmmControl.h>

+#include <Protocol/SmmGpiDispatch.h>

+#include <Protocol/SmmIchnDispatch.h>

+#include <Protocol/SmmPeriodicTimerDispatch.h>

+#include <Protocol/SmmPowerButtonDispatch.h>

+#include <Protocol/SmmStandbyButtonDispatch.h>

+#include <Protocol/SmmStatusCode.h>

+#include <Protocol/SmmSwDispatch.h>

+#include <Protocol/SmmSxDispatch.h>

+#include <Protocol/SmmUsbDispatch.h>

+

+extern EFI_GUID gEfiSmmCpuIoGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/DxeCore.h b/edk2/MdePkg/Include/DxeCore.h
new file mode 100644
index 0000000..9554fb8
--- /dev/null
+++ b/edk2/MdePkg/Include/DxeCore.h
@@ -0,0 +1,50 @@
+/** @file

+

+  Root include file for DXE Core

+

+  The DXE Core has its own module type since its entry point definition is 

+  unique. This module type should only be used by the DXE core. The build 

+  infrastructure must set EFI_SPECIFICATION_VERSION  before including  this 

+  file. To support R9/UEFI2.0 set EFI_SPECIFIATION_VERSION to 0x00020000. To 

+  support R8.5/EFI 1.10 set EFI_SPECIFIATION_VERSION to 0x00010010. 

+  EDK_RELEASE_VERSION must be set to a non zero value.   

+  EFI_SPECIFIATION_VERSION and EDK_RELEASE_VERSION are set automatically

+  by the build infrastructure for every module.

+

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __DXE_CORE_H__

+#define __DXE_CORE_H__

+

+

+//

+// Check to make sure EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION are defined.

+//  also check for legal combinations

+//

+#if !defined(EFI_SPECIFICATION_VERSION)

+  #error EFI_SPECIFICATION_VERSION not defined

+#elif !defined(EDK_RELEASE_VERSION)

+  #error EDK_RELEASE_VERSION not defined

+#elif (EDK_RELEASE_VERSION == 0)

+  #error EDK_RELEASE_VERSION can not be zero

+#endif

+

+

+

+#include <Common/UefiBaseTypes.h>

+#include <Dxe/DxeCis.h>

+

+#include <Protocol/Pcd.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/DxeDepex.h b/edk2/MdePkg/Include/DxeDepex.h
new file mode 100644
index 0000000..e91f350
--- /dev/null
+++ b/edk2/MdePkg/Include/DxeDepex.h
@@ -0,0 +1,58 @@
+/** @file

+  Include file for DXE Dependency Expression *.DXS file. 

+

+  This include file is only for Dependency Expression *.DXS files and 

+  should not be include directly in modules. 

+

+  DEPEX (DEPendency EXpresion) BNF Grammer for DXE:

+  The BNF grammar is thus:

+<pre>

+     <depex>   ::= before GUID       

+                 | after GUID                  

+                 | SOR <bool>

+                 | <bool>                 

+     <bool>    ::= <bool> and <term> 

+                 | <bool> or <term>  

+                 | <term>            

+     <term>    ::= not <factor>      

+                 | <factor>          

+     <factor>  ::= <bool>            

+                 | <boolval>         

+                 | <depinst>         

+                 | <termval>         

+     <boolval> ::= true              

+                 | false             

+     <depinst> ::= push GUID         

+     <termval> ::= end               

+</pre>

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __DXE_DEPEX_H__

+#define __DXE_DEPEX_H__

+

+//

+// The Depex grammer needs the following strings so we must undo

+// any pre-processor redefinitions

+//

+#undef DEPENDENCY_START   

+#undef BEFORE             

+#undef AFTER              

+#undef SOR                               

+#undef AND                

+#undef OR                 

+#undef NOT                

+#undef TRUE               

+#undef FALSE              

+#undef DEPENDENCY_END     

+

+#endif

diff --git a/edk2/MdePkg/Include/Ebc/ProcessorBind.h b/edk2/MdePkg/Include/Ebc/ProcessorBind.h
new file mode 100644
index 0000000..cef7692
--- /dev/null
+++ b/edk2/MdePkg/Include/Ebc/ProcessorBind.h
@@ -0,0 +1,81 @@
+/** @file

+  Processor or compiler specific defines and types for EBC.

+

+  We currently only have one EBC complier so there may be some Intel compiler

+  specific functions in this file.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ProcessorBind.h

+

+**/

+

+#ifndef __PROCESSOR_BIND_H__

+#define __PROCESSOR_BIND_H__

+

+//

+// Define the processor type so other code can make processor based choices

+//

+#define MDE_CPU_EBC

+

+//

+// Native integer types

+//

+typedef char                  INT8;

+typedef unsigned char         BOOLEAN;

+typedef unsigned char         UINT8;

+typedef unsigned char         CHAR8;

+

+typedef short                 INT16;

+typedef unsigned short        UINT16;

+typedef unsigned short        CHAR16;

+

+typedef int                   INT32;

+typedef unsigned int          UINT32;

+

+typedef __int64               INT64;

+typedef unsigned __int64      UINT64;

+

+//

+// "long" type scales to the processor native size with EBC compiler

+//

+typedef long                  INTN;

+typedef unsigned long         UINTN;

+

+#define UINT8_MAX 0xff

+

+//

+// Scalable macro to set the most significant bit in a natural number

+//

+#define MAX_BIT     0x8000000000000000ULL 

+#define MAX_2_BITS  0xC000000000000000ULL

+

+

+//

+// Maximum legal EBC address

+//

+#define MAX_ADDRESS   0xFFFFFFFFFFFFFFFFULL

+

+//

+// Modifier to ensure that all protocol member functions and EFI intrinsics

+// use the correct C calling convention. All protocol member functions and

+// EFI intrinsics are required to modify thier member functions with EFIAPI.

+//

+#define EFIAPI    

+

+//

+// The Microsoft* C compiler can removed references to unreferenced data items

+//  if the /OPT:REF linker option is used. We defined a macro as this is a 

+//  a non standard extension. Currently not supported by the EBC compiler

+//

+#define GLOBAL_REMOVE_IF_UNREFERENCED

+

+#endif 

+

diff --git a/edk2/MdePkg/Include/Guid/Acpi.h b/edk2/MdePkg/Include/Guid/Acpi.h
new file mode 100644
index 0000000..a64f1b7
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/Acpi.h
@@ -0,0 +1,48 @@
+/** @file

+  GUIDs used for ACPI entries in the EFI 1.0 system table

+

+  These GUIDs point the ACPI tables as defined in the ACPI specifications.

+  ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the 

+  ACPI 2.0 Table GUID and ACPI Table GUID.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Acpi.h

+

+  @par Revision Reference:

+  GUIDs defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __ACPI_GUID_H__

+#define __ACPI_GUID_H__

+

+#define EFI_ACPI_10_TABLE_GUID \

+  { \

+    0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+#define EFI_ACPI_TABLE_GUID \

+  { \

+    0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define ACPI_10_TABLE_GUID     EFI_ACPI_10_TABLE_GUID

+//

+// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID.

+//

+#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID

+#define EFI_ACPI_30_TABLE_GUID EFI_ACPI_TABLE_GUID

+

+extern EFI_GUID gEfiAcpi10TableGuid;

+extern EFI_GUID gEfiAcpi20TableGuid;

+extern EFI_GUID gEfiAcpi30TableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/AcpiTableStorage.h b/edk2/MdePkg/Include/Guid/AcpiTableStorage.h
new file mode 100644
index 0000000..80b1154
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/AcpiTableStorage.h
@@ -0,0 +1,30 @@
+/** @file

+  The ACPI table storage file is fully FFS compliant. 

+  The file is a number of sections of type EFI_SECTION_RAW.

+  This GUID is used to identify the file as an ACPI table storage file.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  AcpiTableStorage.h

+

+  @par Revision Reference:

+  GUID defined in ACPI Table Storage Spec Version 0.9.

+

+**/

+

+#ifndef _ACPI_TABLE_STORAGE_H_

+#define _ACPI_TABLE_STORAGE_H_

+

+#define EFI_ACPI_TABLE_STORAGE_GUID \

+  { 0x7e374e25, 0x8e01, 0x4fee, {0x87, 0xf2, 0x39, 0xc, 0x23, 0xc6, 0x6, 0xcd } }

+

+extern EFI_GUID gEfiAcpiTableStorageGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/Apriori.h b/edk2/MdePkg/Include/Guid/Apriori.h
new file mode 100644
index 0000000..ba92560
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/Apriori.h
@@ -0,0 +1,32 @@
+/** @file

+  GUID used as an FV filename for A Priori file. The A Priori file contains a

+  list of FV filenames that the DXE dispatcher will schedule reguardless of

+  the dependency grammer.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Apriori.h

+

+  @par Revision Reference:

+  GUID defined in DXE CIS spec version 0.91B

+

+**/

+

+#ifndef __APRIORI_GUID_H__

+#define __APRIORI_GUID_H__

+

+#define EFI_APRIORI_GUID \

+  { \

+    0xfc510ee7, 0xffdc, 0x11d4, {0xbd, 0x41, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+extern EFI_GUID gAprioriGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/Capsule.h b/edk2/MdePkg/Include/Guid/Capsule.h
new file mode 100644
index 0000000..7864b92
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/Capsule.h
@@ -0,0 +1,43 @@
+/** @file

+  GUIDs used for EFI Capsule

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Capsule.h

+

+  @par Revision Reference:

+  GUIDs defined in Capsule Spec Version 0.9

+

+**/

+

+#ifndef __CAPSULE_GUID_H__

+#define __CAPSULE_GUID_H__

+

+//

+// This is the GUID of the capsule header of the image on disk.

+//

+#define EFI_CAPSULE_GUID \

+  { \

+    0x3B6686BD, 0x0D76, 0x4030, {0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0 } \

+  }

+

+//

+// This is the GUID of the configuration results file created by the capsule

+// application.

+//

+#define EFI_CONFIG_FILE_NAME_GUID \

+  { \

+    0x98B8D59B, 0xE8BA, 0x48EE, {0x98, 0xDD, 0xC2, 0x95, 0x39, 0x2F, 0x1E, 0xDB } \

+  }

+

+extern EFI_GUID gEfiCapsuleGuid;

+extern EFI_GUID gEfiConfigFileNameGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/DataHubRecords.h b/edk2/MdePkg/Include/Guid/DataHubRecords.h
new file mode 100644
index 0000000..f29a5a4
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/DataHubRecords.h
@@ -0,0 +1,66 @@
+/** @file

+  DataHubRecord.h include all data hub sub class GUID defitions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DataHubRecords.h

+

+  @par Revision Reference:

+  These GUID are from Cache subclass spec 0.9, DataHub SubClass spec 0.9, Memory SubClass Spec 0.9, 

+  Processor Subclass spec 0.9, Misc SubClass spec 0.9.

+

+**/

+#ifndef _DATAHUB_RECORDS_GUID_H_

+#define _DATAHUB_RECORDS_GUID_H_

+

+#define EFI_PROCESSOR_PRODUCER_GUID \

+  { 0x1bf06aea, 0x5bec, 0x4a8d, {0x95, 0x76, 0x74, 0x9b, 0x09, 0x56, 0x2d, 0x30 } }

+

+extern  EFI_GUID gEfiProcessorProducerGuid;

+

+

+#define EFI_PROCESSOR_SUBCLASS_GUID \

+  { 0x26fdeb7e, 0xb8af, 0x4ccf, {0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7 } }

+

+extern  EFI_GUID gEfiProcessorSubClassGuid;

+

+

+#define EFI_CACHE_SUBCLASS_GUID \

+  { 0x7f0013a7, 0xdc79, 0x4b22, {0x80, 0x99, 0x11, 0xf7, 0x5f, 0xdc, 0x82, 0x9d } }

+

+extern  EFI_GUID gEfiCacheSubClassGuid;

+

+

+#define EFI_MEMORY_PRODUCER_GUID \

+  { 0x1d7add6e, 0xb2da, 0x4b0b, {0xb2, 0x9f, 0x49, 0xcb, 0x42, 0xf4, 0x63, 0x56 } }

+

+extern  EFI_GUID gEfiMemoryProducerGuid;

+

+

+#define EFI_MEMORY_SUBCLASS_GUID \

+  {0x4E8F4EBB, 0x64B9, 0x4e05, {0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97} }

+

+extern  EFI_GUID  gEfiMemorySubClassGuid;

+

+

+#define EFI_MISC_PRODUCER_GUID \

+  { 0x62512c92, 0x63c4, 0x4d80, {0x82, 0xb1, 0xc1, 0xa4, 0xdc, 0x44, 0x80, 0xe5 } } 

+

+extern  EFI_GUID gEfiMiscProducerGuid;

+

+

+#define EFI_MISC_SUBCLASS_GUID \

+  { 0x772484B2, 0x7482, 0x4b91, {0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81 } }

+

+extern  EFI_GUID  gEfiMiscSubClassGuid;

+

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Guid/DebugImageInfoTable.h b/edk2/MdePkg/Include/Guid/DebugImageInfoTable.h
new file mode 100644
index 0000000..f050a2e
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/DebugImageInfoTable.h
@@ -0,0 +1,58 @@
+/** @file

+  GUID and related data structures used with the Debug Image Info Table.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DebugImageInfoTable.h

+

+  @par Revision Reference:

+  GUID defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __DEBUG_IMAGE_INFO_GUID_H__

+#define __DEBUG_IMAGE_INFO_GUID_H__

+

+#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \

+  { \

+    0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \

+  }

+

+extern EFI_GUID gEfiDebugImageInfoTableGuid;

+

+#define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01

+#define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED     0x02

+#define EFI_DEBUG_IMAGE_INFO_INITIAL_SIZE       (EFI_PAGE_SIZE / sizeof (UINTN))

+#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL        0x01

+

+typedef struct {

+  UINT64                Signature;

+  EFI_PHYSICAL_ADDRESS  EfiSystemTableBase;

+  UINT32                Crc32;

+} EFI_SYSTEM_TABLE_POINTER;

+

+typedef struct {

+  UINT32                     ImageInfoType;

+  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImageProtocolInstance;

+  EFI_HANDLE                 ImageHandle;

+} EFI_DEBUG_IMAGE_INFO_NORMAL;

+

+typedef union {

+  UINTN                       *ImageInfoType;

+  EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;

+} EFI_DEBUG_IMAGE_INFO;

+

+typedef struct {

+  volatile UINT32       UpdateStatus;

+  UINT32                TableSize;

+  EFI_DEBUG_IMAGE_INFO  *EfiDebugImageInfoTable;

+} EFI_DEBUG_IMAGE_INFO_TABLE_HEADER;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/DxeServices.h b/edk2/MdePkg/Include/Guid/DxeServices.h
new file mode 100644
index 0000000..70e4304
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/DxeServices.h
@@ -0,0 +1,30 @@
+/** @file

+  GUID used to identify the DXE Services Table

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DxeServices.h

+

+  @par Revision Reference:

+  GUID defined in DXE CIS spec version 0.91B

+

+**/

+

+#ifndef __DXE_SERVICES_GUID_H__

+#define __DXE_SERVICES_GUID_H__

+

+#define EFI_DXE_SERVICES_TABLE_GUID \

+  { \

+    0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \

+  }

+

+extern EFI_GUID gEfiDxeServicesTableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/EventGroup.h b/edk2/MdePkg/Include/Guid/EventGroup.h
new file mode 100644
index 0000000..f86abd4
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/EventGroup.h
@@ -0,0 +1,45 @@
+/** @file

+  GUIDs for gBS->CreateEventEx Event Groups. Defined in EFI 2.0.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EventGroup.h

+

+**/

+

+#ifndef __EVENT_GROUP_GUID__

+#define __EVENT_GROUP_GUID__

+

+                                             

+#define EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \

+  { 0x27abf055, 0xb1b8, 0x4c26, { 0x80, 0x48, 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf } }

+

+extern EFI_GUID gEfiEventExitBootServicesGuid;

+

+

+#define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \

+  { 0x13fa7698, 0xc831, 0x49c7, { 0x87, 0xea, 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96 } }

+

+extern EFI_GUID gEfiEventVirtualAddressChangeGuid;

+

+

+#define EFI_EVENT_GROUP_MEMORY_MAP_CHANGE \

+  { 0x78bee926, 0x692f, 0x48fd, { 0x9e, 0xdb, 0x1, 0x42, 0x2e, 0xf0, 0xd7, 0xab } }

+

+extern EFI_GUID gEfiEventMemoryMapChangeGuid;

+

+

+#define EFI_EVENT_GROUP_READY_TO_BOOT \

+  { 0x7ce88fb3, 0x4bd7, 0x4679, { 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b } }

+

+extern EFI_GUID gEfiEventReadyToBootGuid;

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/EventLegacyBios.h b/edk2/MdePkg/Include/Guid/EventLegacyBios.h
new file mode 100644
index 0000000..6700a2d
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/EventLegacyBios.h
@@ -0,0 +1,28 @@
+/** @file

+  GUID is the name of events used with CreateEventEx in order to be notified when the EFI boot manager is about to boot a legacy boot option.  Events of this type are notificated just before Int19h is invoked. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EventLegacyBios.h

+

+  @par Revision Reference:

+  GUIDs defined in DXE CIS 0.91b.

+

+**/

+

+#ifndef __EVENT_LEGACY_BIOS_GUID_H__

+#define __EVENT_LEGACY_BIOS_GUID_H__

+

+#define EFI_EVENT_LEGACY_BOOT_GUID \

+   { 0x2a571201, 0x4966, 0x47f6, {0x8b, 0x86, 0xf3, 0x1e, 0x41, 0xf3, 0x2f, 0x10 } }

+

+extern EFI_GUID gEfiEventLegacyBootGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/FirmwareFileSystem.h b/edk2/MdePkg/Include/Guid/FirmwareFileSystem.h
new file mode 100644
index 0000000..06bfa7d
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/FirmwareFileSystem.h
@@ -0,0 +1,40 @@
+/** @file

+  Guid used to define the Firmware File System.  See the Framework Firmware 

+  File System Specification for more details.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FirmwareFileSystem.h

+

+  @par Revision Reference:

+  Guids defined in Firmware File System Spec 0.9

+

+**/

+

+#ifndef __FIRMWARE_FILE_SYSTEM_GUID_H__

+#define __FIRMWARE_FILE_SYSTEM_GUID_H__

+

+//

+// GUIDs defined by the FFS specification.

+//

+#define EFI_FIRMWARE_FILE_SYSTEM_GUID \

+  { \

+    0x7A9354D9, 0x0468, 0x444a, {0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF } \

+  }

+

+#define EFI_FFS_VOLUME_TOP_FILE_GUID \

+  { \

+    0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x9 } \

+  }

+

+extern EFI_GUID gEfiFirmwareFileSystemGuid;

+extern EFI_GUID gEfiFirmwareVolumeTopFileGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/FrameworkDevicePath.h b/edk2/MdePkg/Include/Guid/FrameworkDevicePath.h
new file mode 100644
index 0000000..74c17ea
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/FrameworkDevicePath.h
@@ -0,0 +1,29 @@
+/** @file

+  This GUID is used to define a vendor specific device path being owned by the 

+  Framework specificaitons. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FrameworkDevicePath.h

+

+  @par Revision Reference:

+  Spec Version 0.9

+

+**/

+

+#ifndef __FRAMEWORK_DEVICE_PATH_GUID_H__

+#define __FRAMEWORK_DEVICE_PATH_GUID_H__

+

+#define EFI_FRAMEWORK_DEVICE_PATH_GUID  \

+  { 0xb7084e63, 0x46b7, 0x4d1a, { 0x86, 0x77, 0xe3, 0x0b, 0x53, 0xdb, 0xf0, 0x50 } }

+

+extern EFI_GUID gEfiFrameworkDevicePathGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/GlobalVariable.h b/edk2/MdePkg/Include/Guid/GlobalVariable.h
new file mode 100644
index 0000000..4a774a5
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/GlobalVariable.h
@@ -0,0 +1,31 @@
+/** @file

+  GUID for EFI (NVRAM) Variables.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  GlobalVariable.h

+

+  @par Revision Reference:

+  GUID defined in UEFI 2.0

+**/

+

+#ifndef __GLOBAL_VARIABLE_GUID_H__

+#define __GLOBAL_VARIABLE_GUID_H__

+

+#define EFI_GLOBAL_VARIABLE_GUID \

+  { \

+    0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \

+  }

+

+#define EFI_GLOBAL_VARIABLE EFI_GLOBAL_VARIABLE_GUID

+

+extern EFI_GUID gEfiGlobalVariableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/Gpt.h b/edk2/MdePkg/Include/Guid/Gpt.h
new file mode 100644
index 0000000..7124511
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/Gpt.h
@@ -0,0 +1,45 @@
+/** @file

+  Guids used for the GPT (GUID Partition Table)

+

+  GPT defines a new disk partitioning scheme and also describes 

+  usage of the legacy Master Boot Record (MBR) partitioning scheme. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Gpt.h

+

+  @par Revision Reference:

+  GUIDs defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __GPT_GUID_H__

+#define __GPT_GUID_H__

+

+#define EFI_PART_TYPE_UNUSED_GUID \

+  { \

+    0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } \

+  }

+

+#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \

+  { \

+    0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } \

+  }

+

+#define EFI_PART_TYPE_LEGACY_MBR_GUID \

+  { \

+    0x024dee41, 0x33e7, 0x11d3, {0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f } \

+  }

+

+extern EFI_GUID gEfiPartTypeUnusedGuid;

+extern EFI_GUID gEfiPartTypeSystemPartGuid;

+extern EFI_GUID gEfiPartTypeLegacyMbrGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/HobList.h b/edk2/MdePkg/Include/Guid/HobList.h
new file mode 100644
index 0000000..2493292
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/HobList.h
@@ -0,0 +1,32 @@
+/** @file

+  GUIDs used for HOB List entries

+

+  These GUIDs point the HOB List passed from PEI to DXE.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  HobList.h

+

+  @par Revision Reference:

+  GUID defined in DXE CIS spec version 0.91

+

+**/

+

+#ifndef __HOB_LIST_GUID_H__

+#define __HOB_LIST_GUID_H__

+

+#define EFI_HOB_LIST_GUID \

+  { \

+    0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+extern EFI_GUID gEfiHobListGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/MemoryAllocationHob.h b/edk2/MdePkg/Include/Guid/MemoryAllocationHob.h
new file mode 100644
index 0000000..140d8b8
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/MemoryAllocationHob.h
@@ -0,0 +1,36 @@
+/** @file

+  GUIDs for HOBs used in memory allcation

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  MemoryAllocationHob.h

+

+  @par Revision Reference:

+  GUID defined in Hob Spec Version 0.9

+

+**/

+

+#ifndef __MEMORY_ALLOCATION_GUID_H__

+#define __MEMORY_ALLOCATION_GUID_H__

+

+#define EFI_HOB_MEMORY_ALLOC_BSP_STORE_GUID  \

+  {0x564b33cd, 0xc92a, 0x4593, {0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22} };

+

+#define EFI_HOB_MEMORY_ALLOC_STACK_GUID  \

+  {0x4ed4bf27, 0x4092, 0x42e9, {0x80, 0x7d, 0x52, 0x7b, 0x1d, 0x0, 0xc9, 0xbd} }

+

+#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID  \

+  {0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} }

+

+extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid;

+extern EFI_GUID gEfiHobMemoryAllocStackGuid;

+extern EFI_GUID gEfiHobMemoryAllocModuleGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/Mps.h b/edk2/MdePkg/Include/Guid/Mps.h
new file mode 100644
index 0000000..4596a3f
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/Mps.h
@@ -0,0 +1,37 @@
+/** @file

+  GUIDs used for MPS entries in the EFI 1.0 system table

+  ACPI is the primary means of exporting MP information to the OS. MPS obly was

+  included to support Itanium-based platform power on. So don't use it if you don't have too.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Mps.h

+

+  @par Revision Reference:

+  GUIDs defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __MPS_GUID_H__

+#define __MPS_GUID_H__

+

+#define EFI_MPS_TABLE_GUID \

+  { \

+    0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+//

+// GUID name defined in spec.

+//

+#define MPS_TABLE_GUID EFI_MPS_TABLE_GUID

+

+extern EFI_GUID gEfiMpsTableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/PcAnsi.h b/edk2/MdePkg/Include/Guid/PcAnsi.h
new file mode 100644
index 0000000..c9b74ab
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/PcAnsi.h
@@ -0,0 +1,48 @@
+/** @file

+  Terminal Device Path Vendor Guid.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PcAnsi.h

+

+  @par Revision Reference:

+  GUIDs defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __PC_ANSI_H__

+#define __PC_ANSI_H__

+

+#define EFI_PC_ANSI_GUID \

+  { \

+    0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+#define EFI_VT_100_GUID \

+  { \

+    0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+#define EFI_VT_100_PLUS_GUID \

+  { \

+    0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 } \

+  }

+

+#define EFI_VT_UTF8_GUID \

+  { \

+    0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \

+  }

+

+extern EFI_GUID gEfiPcAnsiGuid;

+extern EFI_GUID gEfiVT100Guid;

+extern EFI_GUID gEfiVT100PlusGuid;

+extern EFI_GUID gEfiVTUTF8Guid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/SalSystemTable.h b/edk2/MdePkg/Include/Guid/SalSystemTable.h
new file mode 100644
index 0000000..30c830f
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/SalSystemTable.h
@@ -0,0 +1,38 @@
+/** @file

+  GUIDs used for SAL system table entries in the EFI system table.

+

+  SAL System Table contains Itanium-based processor centric information about

+  the system.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SalSystemTable.h

+

+  @par Revision Reference:

+  GUIDs defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __SAL_SYSTEM_TABLE_GUID_H__

+#define __SAL_SYSTEM_TABLE_GUID_H__

+

+#define EFI_SAL_SYSTEM_TABLE_GUID \

+  { \

+    0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+//

+// GUID name defined in spec.

+//

+#define SAL_SYSTEM_TABLE_GUID EFI_SAL_SYSTEM_TABLE_GUID

+

+extern EFI_GUID gEfiSalSystemTableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/SmBios.h b/edk2/MdePkg/Include/Guid/SmBios.h
new file mode 100644
index 0000000..f02f9fe
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/SmBios.h
@@ -0,0 +1,68 @@
+/** @file

+  GUIDs used to locate the SMBIOS tables in the EFI 1.0 system table.

+

+  This GUID in the system table is the only legal way to search for and 

+  locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS

+  tables.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmBios.h

+

+  @par Revision Reference:

+  GUIDs defined in UEFI 2.0 spec.

+

+**/

+

+#ifndef __SMBIOS_GUID_H__

+#define __SMBIOS_GUID_H__

+

+#define EFI_SMBIOS_TABLE_GUID \

+  { \

+    0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+#define SMBIOS_TABLE_GUID EFI_SMBIOS_TABLE_GUID

+

+//

+// Smbios Table Entry Point Structure

+//

+#pragma pack(1)

+typedef struct {

+  UINT8   AnchorString[4];

+  UINT8   EntryPointStructureChecksum;

+  UINT8   EntryPointLength;

+  UINT8   MajorVersion;

+  UINT8   MinorVersion;

+  UINT16  MaxStructureSize;

+  UINT8   EntryPointRevision;

+  UINT8   FormattedArea[5];

+  UINT8   IntermediateAnchorString[5];

+  UINT8   IntermediateChecksum;

+  UINT16  TableLength;

+  UINT32  TableAddress;

+  UINT16  NumberOfSmbiosStructures;

+  UINT8   SmbiosBcdRevision;

+} SMBIOS_TABLE_ENTRY_POINT;

+

+//

+// The Smbios structure header

+//

+typedef struct {

+  UINT8   Type;

+  UINT8   Length;

+  UINT16  Handle;

+} SMBIOS_STRUCTURE;

+

+#pragma pack()

+

+extern EFI_GUID       gEfiSmbiosTableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/SmmCommunicate.h b/edk2/MdePkg/Include/Guid/SmmCommunicate.h
new file mode 100644
index 0000000..2ec200b
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/SmmCommunicate.h
@@ -0,0 +1,39 @@
+/** @file

+  Definitions EFI_SMM_COMMUNICATE_HEADER used by EFI_SMM_BASE_PROTOCOL.Communicate() functions

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmCommunicate.h

+

+  @par Revision Reference:

+  GUIDs defined in SmmCis spec version 0.9

+

+**/

+

+#ifndef __SMM_COMMUNICATE_GUID_H__

+#define __SMM_COMMUNICATE_GUID_H__

+

+//******************************************************

+// EFI_SMM_COMMUNICATE_HEADER

+//******************************************************

+#define SMM_COMMUNICATE_HEADER_GUID \

+  { \

+    0xf328e36c, 0x23b6, 0x4a95, {0x85, 0x4b, 0x32, 0xe1, 0x95, 0x34, 0xcd, 0x75 } \

+  }

+

+typedef struct {

+  EFI_GUID                         HeaderGuid;

+  UINTN                            MessageLength;

+  UINT8                            Data[1];

+} EFI_SMM_COMMUNICATE_HEADER;

+

+extern EFI_GUID gSmmCommunicateHeaderGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/SmramMemoryReserve.h b/edk2/MdePkg/Include/Guid/SmramMemoryReserve.h
new file mode 100644
index 0000000..fc49092
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/SmramMemoryReserve.h
@@ -0,0 +1,67 @@
+/** @file

+  GUID for use in reserving SMRAM regions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.    

+

+  Module Name:  SmramMemoryReserve.h

+

+  @par Revision Reference:

+  GUIDs defined in SmmCis spec version 0.9

+

+**/

+

+#ifndef _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_

+#define _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_

+

+#define EFI_SMM_PEI_SMRAM_MEMORY_RESERVE \

+  { \

+    0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d } \

+  }

+

+//

+// *******************************************************

+//  EFI_SMRAM_DESCRIPTOR

+// *******************************************************

+//

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  PhysicalStart;  // Phsyical location in DRAM

+  EFI_PHYSICAL_ADDRESS  CpuStart;       // Address CPU uses to access the SMI handler

+  // May or may not match PhysicalStart

+  //

+  UINT64                PhysicalSize;

+  UINT64                RegionState;

+} EFI_SMRAM_DESCRIPTOR;

+

+//

+// *******************************************************

+//  EFI_SMRAM_STATE

+// *******************************************************

+//

+#define EFI_SMRAM_OPEN                0x00000001

+#define EFI_SMRAM_CLOSED              0x00000002

+#define EFI_SMRAM_LOCKED              0x00000004

+#define EFI_CACHEABLE                 0x00000008

+#define EFI_ALLOCATED                 0x00000010

+#define EFI_NEEDS_TESTING             0x00000020

+#define EFI_NEEDS_ECC_INITIALIZATION  0x00000040

+

+//

+// *******************************************************

+//  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK

+// *******************************************************

+//

+typedef struct {

+  UINTN                 NumberOfSmmReservedRegions;

+  EFI_SMRAM_DESCRIPTOR  Descriptor[1];

+} EFI_SMRAM_HOB_DESCRIPTOR_BLOCK;

+

+extern EFI_GUID gEfiSmmPeiSmramMemoryReserve;

+

+#endif

diff --git a/edk2/MdePkg/Include/Guid/StatusCodeDataTypeId.h b/edk2/MdePkg/Include/Guid/StatusCodeDataTypeId.h
new file mode 100644
index 0000000..f747af0
--- /dev/null
+++ b/edk2/MdePkg/Include/Guid/StatusCodeDataTypeId.h
@@ -0,0 +1,82 @@
+/** @file

+  GUID used to identify id for the caller who is initiating the Status Code.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  StatusCodeDataTypeId.h

+

+  @par Revision Reference:

+  GUIDs defined in Status Codes Specification 0.92

+

+**/

+

+#ifndef __STATUS_CODE_DATA_TYPE_ID_GUID_H__

+#define __STATUS_CODE_DATA_TYPE_ID_GUID_H__

+

+//

+// String Data Type defintion. This is part of Status Code Specification

+//

+#define EFI_STATUS_CODE_DATA_TYPE_STRING_GUID \

+  { 0x92D11080, 0x496F, 0x4D95, { 0xBE, 0x7E, 0x03, 0x74, 0x88, 0x38, 0x2B, 0x0A } }

+

+extern EFI_GUID gEfiStatusCodeDataTypeStringGuid;

+

+//

+// This GUID indicates that the format of the accompanying data depends

+// upon the Status Code Value, but follows this Specification

+//

+#define EFI_STATUS_CODE_SPECIFIC_DATA_GUID \

+  { 0x335984bd, 0xe805, 0x409a, { 0xb8, 0xf8, 0xd2, 0x7e, 0xce, 0x5f, 0xf7, 0xa6 } }

+

+extern EFI_GUID gEfiStatusCodeSpecificDataGuid;

+

+//

+// Debug Assert Data. This is part of Status Code Specification

+//

+#define EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID \

+ { 0xDA571595, 0x4D99, 0x487C, { 0x82, 0x7C, 0x26, 0x22, 0x67, 0x7D, 0x33, 0x07 } }

+

+

+extern EFI_GUID gEfiStatusCodeDataTypeAssertGuid;

+

+//

+// Exception Data type (CPU REGS)

+//

+#define EFI_STATUS_CODE_DATA_TYPE_EXCEPTION_HANDLER_GUID \

+  { 0x3BC2BD12, 0xAD2E, 0x11D5, { 0x87, 0xDD, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9 } }

+

+extern EFI_GUID gEfiStatusCodeDataTypeExceptionHandlerGuid;

+

+//

+// Debug DataType defintions. User Defined Data Types.

+//

+#define EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID \

+  { 0x9A4E9246, 0xD553, 0x11D5, { 0x87, 0xE2, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xb9 } }

+

+extern EFI_GUID gEfiStatusCodeDataTypeDebugGuid;

+

+//

+// Progress Code. User Defined Data Type Guid.

+//

+#define EFI_STATUS_CODE_DATA_TYPE_ERROR_GUID \

+  0xAB359CE3, 0x99B3, 0xAE18, { 0xC8, 0x9D, 0x95, 0xD3, 0xB0, 0x72, 0xE1, 0x9B } }

+

+extern EFI_GUID gEfiStatusCodeDataTypeErrorGuid;

+

+

+//

+// Progress Code. User Defined Data Type Guid.

+//

+#define EFI_STATUS_CODE_DATA_TYPE_PROGRESS_CODE_GUID \

+  { 0xA356AB39, 0x35C4, 0x35DA, { 0xB3, 0x7A, 0xF8, 0xEA, 0x9E, 0x8B, 0x36, 0xA3 } }

+

+extern EFI_GUID gEfiStatusCodeDataTypeProgressCodeGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ia32/ProcessorBind.h b/edk2/MdePkg/Include/Ia32/ProcessorBind.h
new file mode 100644
index 0000000..587d8a6
--- /dev/null
+++ b/edk2/MdePkg/Include/Ia32/ProcessorBind.h
@@ -0,0 +1,167 @@
+/** @file

+  Processor or Compiler specific defines and types for x64.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ProcessorBind.h

+

+**/

+

+#ifndef __PROCESSOR_BIND_H__

+#define __PROCESSOR_BIND_H__

+

+//

+// Define the processor type so other code can make processor based choices

+//

+#define MDE_CPU_IA32

+

+//

+// Make sure we are useing the correct packing rules per EFI specification

+//

+#ifndef __GNUC__

+#pragma pack()

+#endif

+

+#if _MSC_EXTENSIONS

+

+//

+// Disable warning that make it impossible to compile at /W4

+// This only works for Microsoft* tools

+//

+

+//

+// Disabling bitfield type checking warnings.

+//

+#pragma warning ( disable : 4214 )

+

+//

+// Disabling the unreferenced formal parameter warnings.

+//

+#pragma warning ( disable : 4100 )

+

+//

+// Disable slightly different base types warning as CHAR8 * can not be set

+// to a constant string.

+//

+#pragma warning ( disable : 4057 )

+

+//

+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning

+//

+#pragma warning ( disable : 4127 )

+

+

+#endif

+

+

+#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)

+  //

+  // No ANSI C 2000 stdint.h integer width declarations, so define equivalents

+  //

+ 

+  #if _MSC_EXTENSIONS 

+    

+    //

+    // use Microsoft* C complier dependent interger width types 

+    //

+    typedef unsigned __int64    UINT64;

+    typedef __int64             INT64;

+    typedef unsigned __int32    UINT32;

+    typedef __int32             INT32;

+    typedef unsigned short      UINT16;

+    typedef unsigned short      CHAR16;

+    typedef short               INT16;

+    typedef unsigned char       BOOLEAN;

+    typedef unsigned char       UINT8;

+    typedef char                CHAR8;

+    typedef char                INT8;

+  #else

+

+    //

+    // Assume standard IA-32 alignment. 

+    // BugBug: Need to check portability of long long

+    //

+    typedef unsigned long long  UINT64;

+    typedef long long           INT64;

+    typedef unsigned int        UINT32;

+    typedef int                 INT32;

+    typedef unsigned short      UINT16;

+    typedef unsigned short      CHAR16;

+    typedef short               INT16;

+    typedef unsigned char       BOOLEAN;

+    typedef unsigned char       UINT8;

+    typedef char                CHAR8;

+    typedef char                INT8;

+  #endif

+

+  #define UINT8_MAX 0xff

+

+#else

+  //

+  // Use ANSI C 2000 stdint.h integer width declarations

+  //

+  #include "stdint.h"

+  typedef uint8_t   BOOLEAN;

+  typedef int8_t    INT8;

+  typedef uint8_t   UINT8;

+  typedef int16_t   INT16;

+  typedef uint16_t  UINT16;

+  typedef int32_t   INT32;

+  typedef uint32_t  UINT32;

+  typedef int64_t   INT64;

+  typedef uint64_t  UINT64;

+  typedef char      CHAR8;

+  typedef uint16_t  CHAR16;

+

+#endif

+

+typedef UINT32  UINTN;

+typedef INT32   INTN;

+

+

+//

+// Processor specific defines

+//

+#define MAX_BIT     0x80000000

+#define MAX_2_BITS  0xC0000000

+

+//

+// Maximum legal IA-32 address

+//

+#define MAX_ADDRESS   0xFFFFFFFF

+

+//

+// Modifier to ensure that all protocol member functions and EFI intrinsics

+// use the correct C calling convention. All protocol member functions and

+// EFI intrinsics are required to modify thier member functions with EFIAPI.

+//

+#if _MSC_EXTENSIONS

+  //

+  // Microsoft* compiler requires _EFIAPI useage, __cdecl is Microsoft* specific C.

+  // 

+  #define EFIAPI __cdecl  

+#endif

+

+#if __GNUC__

+  #define EFIAPI __attribute__((cdecl))    

+#endif

+

+//

+// The Microsoft* C compiler can removed references to unreferenced data items

+//  if the /OPT:REF linker option is used. We defined a macro as this is a 

+//  a non standard extension

+//

+#if _MSC_EXTENSIONS

+  #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)

+#else

+  #define GLOBAL_REMOVE_IF_UNREFERENCED

+#endif

+

+#endif

diff --git a/edk2/MdePkg/Include/IndustryStandard/Acpi.h b/edk2/MdePkg/Include/IndustryStandard/Acpi.h
new file mode 100644
index 0000000..d2fe345
--- /dev/null
+++ b/edk2/MdePkg/Include/IndustryStandard/Acpi.h
@@ -0,0 +1,91 @@
+/** @file

+  This file contains some basic ACPI definitions that are consumed by drivers

+  that do not care about ACPI versions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Acpi.h

+

+**/

+

+#ifndef _ACPI_H_

+#define _ACPI_H_

+

+//

+// Common table header, this prefaces all ACPI tables, including FACS, but

+// excluding the RSD PTR structure

+//

+typedef struct {

+  UINT32  Signature;

+  UINT32  Length;

+} EFI_ACPI_COMMON_HEADER;

+

+//

+// Common ACPI description table header.  This structure prefaces most ACPI tables.

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT32  Signature;

+  UINT32  Length;

+  UINT8   Revision;

+  UINT8   Checksum;

+  UINT8   OemId[6];

+  UINT64  OemTableId;

+  UINT32  OemRevision;

+  UINT32  CreatorId;

+  UINT32  CreatorRevision;

+} EFI_ACPI_DESCRIPTION_HEADER;

+

+#pragma pack()

+//

+// Define for Pci Host Bridge Resource Allocation

+//

+#define ACPI_ADDRESS_SPACE_DESCRIPTOR 0x8A

+#define ACPI_END_TAG_DESCRIPTOR       0x79

+

+#define ACPI_ADDRESS_SPACE_TYPE_MEM   0x00

+#define ACPI_ADDRESS_SPACE_TYPE_IO    0x01

+#define ACPI_ADDRESS_SPACE_TYPE_BUS   0x02

+

+//

+// Make sure structures match spec

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8   Desc;

+  UINT16  Len;

+  UINT8   ResType;

+  UINT8   GenFlag;

+  UINT8   SpecificFlag;

+  UINT64  AddrSpaceGranularity;

+  UINT64  AddrRangeMin;

+  UINT64  AddrRangeMax;

+  UINT64  AddrTranslationOffset;

+  UINT64  AddrLen;

+} EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;

+

+typedef struct {

+  UINT8 Desc;

+  UINT8 Checksum;

+} EFI_ACPI_END_TAG_DESCRIPTOR;

+

+//

+// General use definitions

+//

+#define EFI_ACPI_RESERVED_BYTE  0x00

+#define EFI_ACPI_RESERVED_WORD  0x0000

+#define EFI_ACPI_RESERVED_DWORD 0x00000000

+#define EFI_ACPI_RESERVED_QWORD 0x0000000000000000

+

+#pragma pack()

+

+#endif

diff --git a/edk2/MdePkg/Include/IndustryStandard/Usb.h b/edk2/MdePkg/Include/IndustryStandard/Usb.h
new file mode 100644
index 0000000..dca7351
--- /dev/null
+++ b/edk2/MdePkg/Include/IndustryStandard/Usb.h
@@ -0,0 +1,282 @@
+/** @file

+  Support for USB 1.1 standard.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Usb.h

+

+**/

+

+#ifndef __USB_H__

+#define __USB_H__

+

+//

+// USB Descriptor types

+//

+#define USB_DT_DEVICE     0x01

+#define USB_DT_CONFIG     0x02

+#define USB_DT_STRING     0x03

+#define USB_DT_INTERFACE  0x04

+#define USB_DT_ENDPOINT   0x05

+#define USB_DT_HUB        0x29

+#define USB_DT_HID        0x21

+

+//

+// USB request type

+//

+#define USB_TYPE_STANDARD (0x00 << 5)

+#define USB_TYPE_CLASS    (0x01 << 5)

+#define USB_TYPE_VENDOR   (0x02 << 5)

+#define USB_TYPE_RESERVED (0x03 << 5)

+

+//

+// USB request targer device

+//

+#define USB_RECIP_DEVICE    0x00

+#define USB_RECIP_INTERFACE 0x01

+#define USB_RECIP_ENDPOINT  0x02

+#define USB_RECIP_OTHER     0x03

+

+//

+// Request target types.

+//

+#define USB_RT_DEVICE     0x00

+#define USB_RT_INTERFACE  0x01

+#define USB_RT_ENDPOINT   0x02

+#define USB_RT_HUB        (USB_TYPE_CLASS | USB_RECIP_DEVICE)

+#define USB_RT_PORT       (USB_TYPE_CLASS | USB_RECIP_OTHER)

+

+//

+// USB Transfer Results

+//

+#define EFI_USB_NOERROR         0x00

+#define EFI_USB_ERR_NOTEXECUTE  0x01

+#define EFI_USB_ERR_STALL       0x02

+#define EFI_USB_ERR_BUFFER      0x04

+#define EFI_USB_ERR_BABBLE      0x08

+#define EFI_USB_ERR_NAK         0x10

+#define EFI_USB_ERR_CRC         0x20

+#define EFI_USB_ERR_TIMEOUT     0x40

+#define EFI_USB_ERR_BITSTUFF    0x80

+#define EFI_USB_ERR_SYSTEM      0x100

+

+//

+//Use 200 ms to increase the error handling response time

+//

+#define EFI_USB_INTERRUPT_DELAY 2000000

+

+//

+// USB transation direction

+//

+typedef enum {

+  EfiUsbDataOut,

+  EfiUsbDataIn,

+  EfiUsbNoData

+} EFI_USB_DATA_DIRECTION;

+

+//

+// Usb Data recipient type

+//

+typedef enum {

+  EfiUsbDevice,

+  EfiUsbInterface,

+  EfiUsbEndpoint

+} EFI_USB_RECIPIENT;

+

+typedef enum {

+  EfiUsbEndpointHalt,

+  EfiUsbDeviceRemoteWakeup

+} EFI_USB_STANDARD_FEATURE_SELECTOR;

+

+#pragma pack(1)

+//

+// Usb device request structure

+//

+typedef struct {

+  UINT8   RequestType;

+  UINT8   Request;

+  UINT16  Value;

+  UINT16  Index;

+  UINT16  Length;

+} EFI_USB_DEVICE_REQUEST;

+

+//

+// Standard USB request

+//

+#define USB_DEV_GET_STATUS                  0x00

+

+#define USB_DEV_CLEAR_FEATURE               0x01

+

+#define USB_DEV_SET_FEATURE                 0x03

+

+#define USB_DEV_SET_ADDRESS                 0x05

+#define USB_DEV_SET_ADDRESS_REQ_TYPE        0x00

+

+#define USB_DEV_GET_DESCRIPTOR              0x06

+#define USB_DEV_GET_DESCRIPTOR_REQ_TYPE     0x80

+

+#define USB_DEV_SET_DESCRIPTOR              0x07

+#define USB_DEV_SET_DESCRIPTOR_REQ_TYPE     0x00

+

+#define USB_DEV_GET_CONFIGURATION           0x08

+#define USB_DEV_GET_CONFIGURATION_REQ_TYPE  0x80

+

+#define USB_DEV_SET_CONFIGURATION           0x09

+#define USB_DEV_SET_CONFIGURATION_REQ_TYPE  0x00

+

+#define USB_DEV_GET_INTERFACE               0x0A

+#define USB_DEV_GET_INTERFACE_REQ_TYPE      0x81

+

+#define USB_DEV_SET_INTERFACE               0x0B

+#define USB_DEV_SET_INTERFACE_REQ_TYPE      0x01

+

+#define USB_DEV_SYNCH_FRAME                 0x0C

+#define USB_DEV_SYNCH_FRAME_REQ_TYPE        0x82

+

+//

+// Device descriptor. refer USB1.1

+//

+typedef struct usb_device_descriptor {

+  UINT8   Length;

+  UINT8   DescriptorType;

+  UINT16  BcdUSB;

+  UINT8   DeviceClass;

+  UINT8   DeviceSubClass;

+  UINT8   DeviceProtocol;

+  UINT8   MaxPacketSize0;

+  UINT16  IdVendor;

+  UINT16  IdProduct;

+  UINT16  BcdDevice;

+  UINT8   StrManufacturer;

+  UINT8   StrProduct;

+  UINT8   StrSerialNumber;

+  UINT8   NumConfigurations;

+} EFI_USB_DEVICE_DESCRIPTOR;

+

+//

+// Endpoint descriptor

+//

+typedef struct {

+  UINT8   Length;

+  UINT8   DescriptorType;

+  UINT8   EndpointAddress;

+  UINT8   Attributes;

+  UINT16  MaxPacketSize;

+  UINT8   Interval;

+} EFI_USB_ENDPOINT_DESCRIPTOR;

+

+//

+// Interface descriptor

+//

+typedef struct {

+  UINT8 Length;

+  UINT8 DescriptorType;

+  UINT8 InterfaceNumber;

+  UINT8 AlternateSetting;

+  UINT8 NumEndpoints;

+  UINT8 InterfaceClass;

+  UINT8 InterfaceSubClass;

+  UINT8 InterfaceProtocol;

+  UINT8 Interface;

+} EFI_USB_INTERFACE_DESCRIPTOR;

+

+//

+// USB alternate setting

+//

+typedef struct {

+  EFI_USB_INTERFACE_DESCRIPTOR  *Interface;

+} USB_ALT_SETTING;

+

+//

+// Configuration descriptor

+//

+typedef struct {

+  UINT8   Length;

+  UINT8   DescriptorType;

+  UINT16  TotalLength;

+  UINT8   NumInterfaces;

+  UINT8   ConfigurationValue;

+  UINT8   Configuration;

+  UINT8   Attributes;

+  UINT8   MaxPower;

+} EFI_USB_CONFIG_DESCRIPTOR;

+

+//

+// Supported String Languages

+//

+typedef struct {

+  UINT8   Length;

+  UINT8   DescriptorType;

+  UINT16  SupportedLanID[1];

+} EFI_USB_SUPPORTED_LANGUAGES;

+

+//

+// String descriptor

+//

+typedef struct {

+  UINT8   Length;

+  UINT8   DescriptorType;

+  CHAR16  String[1];

+} EFI_USB_STRING_DESCRIPTOR;

+

+//

+// Hub descriptor

+//

+#define MAXBYTES  8

+typedef struct {

+  UINT8 Length;

+  UINT8 DescriptorType;

+  UINT8 NbrPorts;

+  UINT8 HubCharacteristics[2];

+  UINT8 PwrOn2PwrGood;

+  UINT8 HubContrCurrent;

+  UINT8 Filler[MAXBYTES];

+} EFI_USB_HUB_DESCRIPTOR;

+

+typedef struct {

+  UINT16  PortStatus;

+  UINT16  PortChangeStatus;

+} EFI_USB_PORT_STATUS;

+

+//

+// Constant value for Port Status & Port Change Status

+//

+#define USB_PORT_STAT_CONNECTION    0x0001

+#define USB_PORT_STAT_ENABLE        0x0002

+#define USB_PORT_STAT_SUSPEND       0x0004

+#define USB_PORT_STAT_OVERCURRENT   0x0008

+#define USB_PORT_STAT_RESET         0x0010

+#define USB_PORT_STAT_POWER         0x0100

+#define USB_PORT_STAT_LOW_SPEED     0x0200

+

+#define USB_PORT_STAT_C_CONNECTION  0x0001

+#define USB_PORT_STAT_C_ENABLE      0x0002

+#define USB_PORT_STAT_C_SUSPEND     0x0004

+#define USB_PORT_STAT_C_OVERCURRENT 0x0008

+#define USB_PORT_STAT_C_RESET       0x0010

+

+//

+// Used for set/clear port feature request

+//

+typedef enum {

+  EfiUsbPortEnable            = 1,

+  EfiUsbPortSuspend           = 2,

+  EfiUsbPortReset             = 4,

+  EfiUsbPortPower             = 8,

+  EfiUsbPortConnectChange     = 16,

+  EfiUsbPortEnableChange      = 17,

+  EfiUsbPortSuspendChange     = 18,

+  EfiUsbPortOverCurrentChange = 19,

+  EfiUsbPortResetChange       = 20

+} EFI_USB_PORT_FEATURE;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/MdePkg/Include/IndustryStandard/pci22.h b/edk2/MdePkg/Include/IndustryStandard/pci22.h
new file mode 100644
index 0000000..7fee279
--- /dev/null
+++ b/edk2/MdePkg/Include/IndustryStandard/pci22.h
@@ -0,0 +1,481 @@
+/** @file

+  Support for PCI 2.2 standard.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  pci22.h

+

+**/

+

+#ifndef _PCI22_H

+#define _PCI22_H

+

+#define PCI_MAX_SEGMENT 0

+

+#define PCI_MAX_BUS     255

+

+#define PCI_MAX_DEVICE  31

+#define PCI_MAX_FUNC    7

+

+//

+// Command

+//

+#define PCI_VGA_PALETTE_SNOOP_DISABLED  0x20

+

+#pragma pack(push, 1)

+typedef struct {

+  UINT16  VendorId;

+  UINT16  DeviceId;

+  UINT16  Command;

+  UINT16  Status;

+  UINT8   RevisionID;

+  UINT8   ClassCode[3];

+  UINT8   CacheLineSize;

+  UINT8   LatencyTimer;

+  UINT8   HeaderType;

+  UINT8   BIST;

+} PCI_DEVICE_INDEPENDENT_REGION;

+

+typedef struct {

+  UINT32  Bar[6];

+  UINT32  CISPtr;

+  UINT16  SubsystemVendorID;

+  UINT16  SubsystemID;

+  UINT32  ExpansionRomBar;

+  UINT8   CapabilityPtr;

+  UINT8   Reserved1[3];

+  UINT32  Reserved2;

+  UINT8   InterruptLine;

+  UINT8   InterruptPin;

+  UINT8   MinGnt;

+  UINT8   MaxLat;

+} PCI_DEVICE_HEADER_TYPE_REGION;

+

+typedef struct {

+  PCI_DEVICE_INDEPENDENT_REGION Hdr;

+  PCI_DEVICE_HEADER_TYPE_REGION Device;

+} PCI_TYPE00;

+

+typedef struct {

+  UINT32  Bar[2];

+  UINT8   PrimaryBus;

+  UINT8   SecondaryBus;

+  UINT8   SubordinateBus;

+  UINT8   SecondaryLatencyTimer;

+  UINT8   IoBase;

+  UINT8   IoLimit;

+  UINT16  SecondaryStatus;

+  UINT16  MemoryBase;

+  UINT16  MemoryLimit;

+  UINT16  PrefetchableMemoryBase;

+  UINT16  PrefetchableMemoryLimit;

+  UINT32  PrefetchableBaseUpper32;

+  UINT32  PrefetchableLimitUpper32;

+  UINT16  IoBaseUpper16;

+  UINT16  IoLimitUpper16;

+  UINT8   CapabilityPtr;

+  UINT8   Reserved[3];

+  UINT32  ExpansionRomBAR;

+  UINT8   InterruptLine;

+  UINT8   InterruptPin;

+  UINT16  BridgeControl;

+} PCI_BRIDGE_CONTROL_REGISTER;

+

+typedef struct {

+  PCI_DEVICE_INDEPENDENT_REGION Hdr;

+  PCI_BRIDGE_CONTROL_REGISTER   Bridge;

+} PCI_TYPE01;

+

+typedef union {

+  PCI_TYPE00  Device;

+  PCI_TYPE01  Bridge;

+} PCI_TYPE_GENERIC;

+

+typedef struct {

+  UINT32  CardBusSocketReg; // Cardus Socket/ExCA Base

+  // Address Register

+  //

+  UINT16  Reserved;

+  UINT16  SecondaryStatus;      // Secondary Status

+  UINT8   PciBusNumber;         // PCI Bus Number

+  UINT8   CardBusBusNumber;     // CardBus Bus Number

+  UINT8   SubordinateBusNumber; // Subordinate Bus Number

+  UINT8   CardBusLatencyTimer;  // CardBus Latency Timer

+  UINT32  MemoryBase0;          // Memory Base Register 0

+  UINT32  MemoryLimit0;         // Memory Limit Register 0

+  UINT32  MemoryBase1;

+  UINT32  MemoryLimit1;

+  UINT32  IoBase0;

+  UINT32  IoLimit0;             // I/O Base Register 0

+  UINT32  IoBase1;              // I/O Limit Register 0

+  UINT32  IoLimit1;

+  UINT8   InterruptLine;        // Interrupt Line

+  UINT8   InterruptPin;         // Interrupt Pin

+  UINT16  BridgeControl;        // Bridge Control

+} PCI_CARDBUS_CONTROL_REGISTER;

+

+//

+// Definitions of PCI class bytes and manipulation macros.

+//

+#define PCI_CLASS_OLD                 0x00

+#define PCI_CLASS_OLD_OTHER           0x00

+#define PCI_CLASS_OLD_VGA             0x01

+

+#define PCI_CLASS_MASS_STORAGE        0x01

+#define PCI_CLASS_MASS_STORAGE_SCSI   0x00

+#define PCI_CLASS_MASS_STORAGE_IDE    0x01  // obsolete

+#define PCI_CLASS_IDE                 0x01

+#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02

+#define PCI_CLASS_MASS_STORAGE_IPI    0x03

+#define PCI_CLASS_MASS_STORAGE_RAID   0x04

+#define PCI_CLASS_MASS_STORAGE_OTHER  0x80

+

+#define PCI_CLASS_NETWORK             0x02

+#define PCI_CLASS_NETWORK_ETHERNET    0x00

+#define PCI_CLASS_ETHERNET            0x00  // obsolete

+#define PCI_CLASS_NETWORK_TOKENRING   0x01

+#define PCI_CLASS_NETWORK_FDDI        0x02

+#define PCI_CLASS_NETWORK_ATM         0x03

+#define PCI_CLASS_NETWORK_ISDN        0x04

+#define PCI_CLASS_NETWORK_OTHER       0x80

+

+#define PCI_CLASS_DISPLAY             0x03

+#define PCI_CLASS_DISPLAY_CTRL        0x03  // obsolete

+#define PCI_CLASS_DISPLAY_VGA         0x00

+#define PCI_CLASS_VGA                 0x00  // obsolete

+#define PCI_CLASS_DISPLAY_XGA         0x01

+#define PCI_CLASS_DISPLAY_3D          0x02

+#define PCI_CLASS_DISPLAY_OTHER       0x80

+#define PCI_CLASS_DISPLAY_GFX         0x80

+#define PCI_CLASS_GFX                 0x80  // obsolete

+#define PCI_CLASS_BRIDGE              0x06

+#define PCI_CLASS_BRIDGE_HOST         0x00

+#define PCI_CLASS_BRIDGE_ISA          0x01

+#define PCI_CLASS_ISA                 0x01  // obsolete

+#define PCI_CLASS_BRIDGE_EISA         0x02

+#define PCI_CLASS_BRIDGE_MCA          0x03

+#define PCI_CLASS_BRIDGE_P2P          0x04

+#define PCI_CLASS_BRIDGE_PCMCIA       0x05

+#define PCI_CLASS_BRIDGE_NUBUS        0x06

+#define PCI_CLASS_BRIDGE_CARDBUS      0x07

+#define PCI_CLASS_BRIDGE_RACEWAY      0x08

+#define PCI_CLASS_BRIDGE_ISA_PDECODE  0x80

+#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80  // obsolete

+#define PCI_CLASS_SERIAL              0x0C

+#define PCI_CLASS_SERIAL_FIREWIRE     0x00

+#define PCI_CLASS_SERIAL_ACCESS_BUS   0x01

+#define PCI_CLASS_SERIAL_SSA          0x02

+#define PCI_CLASS_SERIAL_USB          0x03

+#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04

+#define PCI_CLASS_SERIAL_SMB          0x05

+

+#define IS_CLASS1(_p, c)              ((_p)->Hdr.ClassCode[2] == (c))

+#define IS_CLASS2(_p, c, s)           (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s)))

+#define IS_CLASS3(_p, c, s, p)        (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p)))

+

+#define IS_PCI_DISPLAY(_p)            IS_CLASS1 (_p, PCI_CLASS_DISPLAY)

+#define IS_PCI_VGA(_p)                IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0)

+#define IS_PCI_8514(_p)               IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1)

+#define IS_PCI_GFX(_p)                IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0)

+#define IS_PCI_OLD(_p)                IS_CLASS1 (_p, PCI_CLASS_OLD)

+#define IS_PCI_OLD_VGA(_p)            IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA)

+#define IS_PCI_IDE(_p)                IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE)

+#define IS_PCI_SCSI(_p)               IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0)

+#define IS_PCI_RAID(_p)               IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0)

+#define IS_PCI_LPC(_p)                IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0)

+#define IS_PCI_P2P(_p)                IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0)

+#define IS_PCI_P2P_SUB(_p)            IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1)

+#define IS_PCI_USB(_p)                IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB)

+

+#define HEADER_TYPE_DEVICE            0x00

+#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01

+#define HEADER_TYPE_CARDBUS_BRIDGE    0x02

+

+#define HEADER_TYPE_MULTI_FUNCTION    0x80

+#define HEADER_LAYOUT_CODE            0x7f

+

+#define IS_PCI_BRIDGE(_p)             (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE))

+#define IS_CARDBUS_BRIDGE(_p)         (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE))

+#define IS_PCI_MULTI_FUNC(_p)         ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)

+

+#define PCI_DEVICE_ROMBAR             0x30

+#define PCI_BRIDGE_ROMBAR             0x38

+

+#define PCI_MAX_BAR                   6

+#define PCI_MAX_CONFIG_OFFSET         0x100

+//

+// bugbug: this is supported in PCI spec v2.3

+//

+#define PCI_EXP_MAX_CONFIG_OFFSET                   0x1000

+

+#define PCI_VENDOR_ID_OFFSET                        0x00

+#define PCI_DEVICE_ID_OFFSET                        0x02

+#define PCI_COMMAND_OFFSET                          0x04

+#define PCI_PRIMARY_STATUS_OFFSET                   0x06

+#define PCI_REVISION_ID_OFFSET                      0x08

+#define PCI_CLASSCODE_OFFSET                        0x09

+#define PCI_CACHELINE_SIZE_OFFSET                   0x0C

+#define PCI_LATENCY_TIMER_OFFSET                    0x0D

+#define PCI_HEADER_TYPE_OFFSET                      0x0E

+#define PCI_BIST_OFFSET                             0x0F

+

+#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET          0x3E

+#define PCI_BRIDGE_STATUS_REGISTER_OFFSET           0x1E

+

+#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET      0x18

+#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET    0x19

+#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET  0x1a

+

+typedef struct {

+  UINT8 Register;

+  UINT8 Function;

+  UINT8 Device;

+  UINT8 Bus;

+  UINT8 Reserved[4];

+} DEFIO_PCI_ADDR;

+

+typedef union {

+  struct {

+    UINT32  Reg : 8;

+    UINT32  Func : 3;

+    UINT32  Dev : 5;

+    UINT32  Bus : 8;

+    UINT32  Reserved : 7;

+    UINT32  Enable : 1;

+  } Bits;

+  UINT32  Uint32;

+} PCI_CONFIG_ACCESS_CF8;

+

+#pragma pack()

+

+#define EFI_ROOT_BRIDGE_LIST                            'eprb'

+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE              0xaa55

+#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE       0x0EF1

+#define PCI_DATA_STRUCTURE_SIGNATURE                    EFI_SIGNATURE_32 ('P', 'C', 'I', 'R')

+#define PCI_CODE_TYPE_PCAT_IMAGE                        0x00

+#define PCI_CODE_TYPE_EFI_IMAGE                         0x03

+#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED         0x0001

+

+#define EFI_PCI_COMMAND_IO_SPACE                        0x0001

+#define EFI_PCI_COMMAND_MEMORY_SPACE                    0x0002

+#define EFI_PCI_COMMAND_BUS_MASTER                      0x0004

+#define EFI_PCI_COMMAND_SPECIAL_CYCLE                   0x0008

+#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE     0x0010

+#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP               0x0020

+#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND            0x0040

+#define EFI_PCI_COMMAND_STEPPING_CONTROL                0x0080

+#define EFI_PCI_COMMAND_SERR                            0x0100

+#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK               0x0200

+

+#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE    0x0001

+#define EFI_PCI_BRIDGE_CONTROL_SERR                     0x0002

+#define EFI_PCI_BRIDGE_CONTROL_ISA                      0x0004

+#define EFI_PCI_BRIDGE_CONTROL_VGA                      0x0008

+#define EFI_PCI_BRIDGE_CONTROL_VGA_16                   0x0010

+#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT             0x0020

+#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS      0x0040

+#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK        0x0080

+#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER    0x0100

+#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER  0x0200

+#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS             0x0400

+#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR       0x0800

+

+//

+// Following are the PCI-CARDBUS bridge control bit

+//

+#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE       0x0080

+#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE   0x0100

+#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE   0x0200

+#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400

+

+//

+// Following are the PCI status control bit

+//

+#define EFI_PCI_STATUS_CAPABILITY             0x0010

+#define EFI_PCI_STATUS_66MZ_CAPABLE           0x0020

+#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE     0x0080

+#define EFI_PCI_MASTER_DATA_PARITY_ERROR      0x0100

+

+#define EFI_PCI_CAPABILITY_PTR                0x34

+#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14

+

+#pragma pack(1)

+typedef struct {

+  UINT16  Signature;    // 0xaa55

+  UINT8   Reserved[0x16];

+  UINT16  PcirOffset;

+} PCI_EXPANSION_ROM_HEADER;

+

+typedef struct {

+  UINT16  Signature;    // 0xaa55

+  UINT16  InitializationSize;

+  UINT32  EfiSignature; // 0x0EF1

+  UINT16  EfiSubsystem;

+  UINT16  EfiMachineType;

+  UINT16  CompressionType;

+  UINT8   Reserved[8];

+  UINT16  EfiImageHeaderOffset;

+  UINT16  PcirOffset;

+} EFI_PCI_EXPANSION_ROM_HEADER;

+

+typedef struct {

+  UINT16  Signature;    // 0xaa55

+  UINT8   Size512;

+  UINT8   Reserved[15];

+  UINT16  PcirOffset;

+} EFI_LEGACY_EXPANSION_ROM_HEADER;

+

+typedef union {

+  UINT8                           *Raw;

+  PCI_EXPANSION_ROM_HEADER        *Generic;

+  EFI_PCI_EXPANSION_ROM_HEADER    *Efi;

+  EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt;

+} EFI_PCI_ROM_HEADER;

+

+typedef struct {

+  UINT32  Signature;    // "PCIR"

+  UINT16  VendorId;

+  UINT16  DeviceId;

+  UINT16  Reserved0;

+  UINT16  Length;

+  UINT8   Revision;

+  UINT8   ClassCode[3];

+  UINT16  ImageLength;

+  UINT16  CodeRevision;

+  UINT8   CodeType;

+  UINT8   Indicator;

+  UINT16  Reserved1;

+} PCI_DATA_STRUCTURE;

+

+//

+// PCI Capability List IDs and records

+//

+#define EFI_PCI_CAPABILITY_ID_PMI     0x01

+#define EFI_PCI_CAPABILITY_ID_AGP     0x02

+#define EFI_PCI_CAPABILITY_ID_VPD     0x03

+#define EFI_PCI_CAPABILITY_ID_SLOTID  0x04

+#define EFI_PCI_CAPABILITY_ID_MSI     0x05

+#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06

+#define EFI_PCI_CAPABILITY_ID_PCIX    0x07

+//

+// bugbug: this ID is defined in PCI spec v2.3

+//

+#define EFI_PCI_CAPABILITY_ID_PCIEXP  0x10

+

+typedef struct {

+  UINT8 CapabilityID;

+  UINT8 NextItemPtr;

+} EFI_PCI_CAPABILITY_HDR;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_PMI

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT16                  PMC;

+  UINT16                  PMCSR;

+  UINT8                   BridgeExtention;

+  UINT8                   Data;

+} EFI_PCI_CAPABILITY_PMI;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_AGP

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT8                   Rev;

+  UINT8                   Reserved;

+  UINT32                  Status;

+  UINT32                  Command;

+} EFI_PCI_CAPABILITY_AGP;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_VPD

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT16                  AddrReg;

+  UINT32                  DataReg;

+} EFI_PCI_CAPABILITY_VPD;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_SLOTID

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT8                   ExpnsSlotReg;

+  UINT8                   ChassisNo;

+} EFI_PCI_CAPABILITY_SLOTID;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_MSI

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT16                  MsgCtrlReg;

+  UINT32                  MsgAddrReg;

+  UINT16                  MsgDataReg;

+} EFI_PCI_CAPABILITY_MSI32;

+

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT16                  MsgCtrlReg;

+  UINT32                  MsgAddrRegLsdw;

+  UINT32                  MsgAddrRegMsdw;

+  UINT16                  MsgDataReg;

+} EFI_PCI_CAPABILITY_MSI64;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  //

+  // not finished - fields need to go here

+  //

+} EFI_PCI_CAPABILITY_HOTPLUG;

+

+//

+// Capability EFI_PCI_CAPABILITY_ID_PCIX

+//

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT16                  CommandReg;

+  UINT32                  StatusReg;

+} EFI_PCI_CAPABILITY_PCIX;

+

+typedef struct {

+  EFI_PCI_CAPABILITY_HDR  Hdr;

+  UINT16                  SecStatusReg;

+  UINT32                  StatusReg;

+  UINT32                  SplitTransCtrlRegUp;

+  UINT32                  SplitTransCtrlRegDn;

+} EFI_PCI_CAPABILITY_PCIX_BRDG;

+

+#define DEVICE_ID_NOCARE    0xFFFF

+

+#define PCI_ACPI_UNUSED     0

+#define PCI_BAR_NOCHANGE    0

+#define PCI_BAR_OLD_ALIGN   0xFFFFFFFFFFFFFFFFULL

+#define PCI_BAR_EVEN_ALIGN  0xFFFFFFFFFFFFFFFEULL

+#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL

+#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL

+

+#define PCI_BAR_IDX0        0x00

+#define PCI_BAR_IDX1        0x01

+#define PCI_BAR_IDX2        0x02

+#define PCI_BAR_IDX3        0x03

+#define PCI_BAR_IDX4        0x04

+#define PCI_BAR_IDX5        0x05

+#define PCI_BAR_ALL         0xFF

+

+#pragma pack(pop)

+

+#endif

diff --git a/edk2/MdePkg/Include/IndustryStandard/scsi.h b/edk2/MdePkg/Include/IndustryStandard/scsi.h
new file mode 100644
index 0000000..4102309
--- /dev/null
+++ b/edk2/MdePkg/Include/IndustryStandard/scsi.h
@@ -0,0 +1,282 @@
+/** @file

+  support for SCSI standard

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  scsi.h

+

+**/

+

+#ifndef _SCSI_H

+#define _SCSI_H

+

+//

+// SCSI command OP Code

+//

+//

+// Commands for all device types

+//

+#define EFI_SCSI_OP_CHANGE_DEFINITION 0x40

+#define EFI_SCSI_OP_COMPARE           0x39

+#define EFI_SCSI_OP_COPY              0x18

+#define EFI_SCSI_OP_COPY_VERIFY       0x3a

+#define EFI_SCSI_OP_INQUIRY           0x12

+#define EFI_SCSI_OP_LOG_SELECT        0x4c

+#define EFI_SCSI_OP_LOG_SENSE         0x4d

+#define EFI_SCSI_OP_MODE_SEL6         0x15

+#define EFI_SCSI_OP_MODE_SEL10        0x55

+#define EFI_SCSI_OP_MODE_SEN6         0x1a

+#define EFI_SCSI_OP_MODE_SEN10        0x5a

+#define EFI_SCSI_OP_READ_BUFFER       0x3c

+#define EFI_SCSI_OP_REQUEST_SENSE     0x03

+#define EFI_SCSI_OP_SEND_DIAG         0x1d

+#define EFI_SCSI_OP_TEST_UNIT_READY   0x00

+#define EFI_SCSI_OP_WRITE_BUFF        0x3b

+

+//

+// Commands unique to Direct Access Devices

+//

+#define EFI_SCSI_OP_COMPARE         0x39

+#define EFI_SCSI_OP_FORMAT          0x04

+#define EFI_SCSI_OP_LOCK_UN_CACHE   0x36

+#define EFI_SCSI_OP_PREFETCH        0x34

+#define EFI_SCSI_OP_MEDIA_REMOVAL   0x1e

+#define EFI_SCSI_OP_READ6           0x08

+#define EFI_SCSI_OP_READ10          0x28

+#define EFI_SCSI_OP_READ_CAPACITY   0x25

+#define EFI_SCSI_OP_READ_DEFECT     0x37

+#define EFI_SCSI_OP_READ_LONG       0x3e

+#define EFI_SCSI_OP_REASSIGN_BLK    0x07

+#define EFI_SCSI_OP_RECEIVE_DIAG    0x1c

+#define EFI_SCSI_OP_RELEASE         0x17

+#define EFI_SCSI_OP_REZERO          0x01

+#define EFI_SCSI_OP_SEARCH_DATA_E   0x31

+#define EFI_SCSI_OP_SEARCH_DATA_H   0x30

+#define EFI_SCSI_OP_SEARCH_DATA_L   0x32

+#define EFI_SCSI_OP_SEEK6           0x0b

+#define EFI_SCSI_OP_SEEK10          0x2b

+#define EFI_SCSI_OP_SEND_DIAG       0x1d

+#define EFI_SCSI_OP_SET_LIMIT       0x33

+#define EFI_SCSI_OP_START_STOP_UNIT 0x1b

+#define EFI_SCSI_OP_SYNC_CACHE      0x35

+#define EFI_SCSI_OP_VERIFY          0x2f

+#define EFI_SCSI_OP_WRITE6          0x0a

+#define EFI_SCSI_OP_WRITE10         0x2a

+#define EFI_SCSI_OP_WRITE_VERIFY    0x2e

+#define EFI_SCSI_OP_WRITE_LONG      0x3f

+#define EFI_SCSI_OP_WRITE_SAME      0x41

+

+//

+// Commands unique to Sequential Access Devices

+//

+#define EFI_SCSI_OP_ERASE             0x19

+#define EFI_SCSI_OP_LOAD_UNLOAD       0x1b

+#define EFI_SCSI_OP_LOCATE            0x2b

+#define EFI_SCSI_OP_READ_BLOCK_LIMIT  0x05

+#define EFI_SCSI_OP_READ_POS          0x34

+#define EFI_SCSI_OP_READ_REVERSE      0x0f

+#define EFI_SCSI_OP_RECOVER_BUF_DATA  0x14

+#define EFI_SCSI_OP_RESERVE_UNIT      0x16

+#define EFI_SCSI_OP_REWIND            0x01

+#define EFI_SCSI_OP_SPACE             0x11

+#define EFI_SCSI_OP_VERIFY_TAPE       0x13

+#define EFI_SCSI_OP_WRITE_FILEMARK    0x10

+

+//

+// Commands unique to Printer Devices

+//

+#define EFI_SCSI_OP_PRINT       0x0a

+#define EFI_SCSI_OP_SLEW_PRINT  0x0b

+#define EFI_SCSI_OP_STOP_PRINT  0x1b

+#define EFI_SCSI_OP_SYNC_BUFF   0x10

+

+//

+// Commands unique to Processor Devices

+//

+#define EFI_SCSI_OP_RECEIVE 0x08

+#define EFI_SCSI_OP_SEND    0x0a

+

+//

+// Commands unique to Write-Once Devices

+//

+#define EFI_SCSI_OP_MEDIUM_SCAN     0x38

+#define EFI_SCSI_OP_SEARCH_DAT_E10  0x31

+#define EFI_SCSI_OP_SEARCH_DAT_E12  0xb1

+#define EFI_SCSI_OP_SEARCH_DAT_H10  0x30

+#define EFI_SCSI_OP_SEARCH_DAT_H12  0xb0

+#define EFI_SCSI_OP_SEARCH_DAT_L10  0x32

+#define EFI_SCSI_OP_SEARCH_DAT_L12  0xb2

+#define EFI_SCSI_OP_SET_LIMIT10     0x33

+#define EFI_SCSI_OP_SET_LIMIT12     0xb3

+#define EFI_SCSI_OP_VERIFY10        0x2f

+#define EFI_SCSI_OP_VERIFY12        0xaf

+#define EFI_SCSI_OP_WRITE12         0xaa

+#define EFI_SCSI_OP_WRITE_VERIFY10  0x2e

+#define EFI_SCSI_OP_WRITE_VERIFY12  0xae

+

+//

+// Commands unique to CD-ROM Devices

+//

+#define EFI_SCSI_OP_PLAY_AUD_10       0x45

+#define EFI_SCSI_OP_PLAY_AUD_12       0xa5

+#define EFI_SCSI_OP_PLAY_AUD_MSF      0x47

+#define EFI_SCSI_OP_PLAY_AUD_TKIN     0x48

+#define EFI_SCSI_OP_PLAY_TK_REL10     0x49

+#define EFI_SCSI_OP_PLAY_TK_REL12     0xa9

+#define EFI_SCSI_OP_READ_CD_CAPACITY  0x25

+#define EFI_SCSI_OP_READ_HEADER       0x44

+#define EFI_SCSI_OP_READ_SUB_CHANNEL  0x42

+#define EFI_SCSI_OP_READ_TOC          0x43

+

+//

+// Commands unique to Scanner Devices

+//

+#define EFI_SCSI_OP_GET_DATABUFF_STAT 0x34

+#define EFI_SCSI_OP_GET_WINDOW        0x25

+#define EFI_SCSI_OP_OBJECT_POS        0x31

+#define EFI_SCSI_OP_SCAN              0x1b

+#define EFI_SCSI_OP_SET_WINDOW        0x24

+

+//

+// Commands unique to Optical Memory Devices

+//

+#define EFI_SCSI_OP_UPDATE_BLOCK  0x3d

+

+//

+// Commands unique to Medium Changer Devices

+//

+#define EFI_SCSI_OP_EXCHANGE_MEDIUM   0xa6

+#define EFI_SCSI_OP_INIT_ELEMENT_STAT 0x07

+#define EFI_SCSI_OP_POS_TO_ELEMENT    0x2b

+#define EFI_SCSI_OP_REQUEST_VE_ADDR   0xb5

+#define EFI_SCSI_OP_SEND_VOL_TAG      0xb6

+

+//

+// Commands unique to Communition Devices

+//

+#define EFI_SCSI_OP_GET_MESSAGE6    0x08

+#define EFI_SCSI_OP_GET_MESSAGE10   0x28

+#define EFI_SCSI_OP_GET_MESSAGE12   0xa8

+#define EFI_SCSI_OP_SEND_MESSAGE6   0x0a

+#define EFI_SCSI_OP_SEND_MESSAGE10  0x2a

+#define EFI_SCSI_OP_SEND_MESSAGE12  0xaa

+

+//

+// SCSI Data Transfer Direction

+//

+#define EFI_SCSI_DATA_IN  0

+#define EFI_SCSI_DATA_OUT 1

+

+//

+// Peripheral Device Type Definitions

+//

+#define EFI_SCSI_TYPE_DISK          0x00  // Disk device

+#define EFI_SCSI_TYPE_TAPE          0x01  // Tape device

+#define EFI_SCSI_TYPE_PRINTER       0x02  // Printer

+#define EFI_SCSI_TYPE_PROCESSOR     0x03  // Processor

+#define EFI_SCSI_TYPE_WORM          0x04  // Write-once read-multiple

+#define EFI_SCSI_TYPE_CDROM         0x05  // CD-ROM device

+#define EFI_SCSI_TYPE_SCANNER       0x06  // Scanner device

+#define EFI_SCSI_TYPE_OPTICAL       0x07  // Optical memory device

+#define EFI_SCSI_TYPE_MEDIUMCHANGER 0x08  // Medium Changer device

+#define EFI_SCSI_TYPE_COMMUNICATION 0x09  // Communications device

+#define EFI_SCSI_TYPE_RESERVED_LOW  0x0A  // Reserved (low)

+#define EFI_SCSI_TYPE_RESERVED_HIGH 0x1E  // Reserved (high)

+#define EFI_SCSI_TYPE_UNKNOWN       0x1F  // Unknown or no device type

+#pragma pack(1)

+//

+// Data structures for scsi command use

+//

+typedef struct {

+  UINT8 Peripheral_Type : 5;

+  UINT8 Peripheral_Qualifier : 3;

+  UINT8 DeviceType_Modifier : 7;

+  UINT8 RMB : 1;

+  UINT8 Version;

+  UINT8 Response_Data_Format;

+  UINT8 Addnl_Length;

+  UINT8 Reserved_5_95[95 - 5 + 1];

+} EFI_SCSI_INQUIRY_DATA;

+

+typedef struct {

+  UINT8 Error_Code : 7;

+  UINT8 Valid : 1;

+  UINT8 Segment_Number;

+  UINT8 Sense_Key : 4;

+  UINT8 Reserved_21 : 1;

+  UINT8 ILI : 1;

+  UINT8 Reserved_22 : 2;

+  UINT8 Information_3_6[4];

+  UINT8 Addnl_Sense_Length;           // n - 7

+  UINT8 Vendor_Specific_8_11[4];

+  UINT8 Addnl_Sense_Code;             // mandatory

+  UINT8 Addnl_Sense_Code_Qualifier;   // mandatory

+  UINT8 Field_Replaceable_Unit_Code;  // optional

+  UINT8 Reserved_15_17[3];

+} EFI_SCSI_SENSE_DATA;

+

+typedef struct {

+  UINT8 LastLba3;

+  UINT8 LastLba2;

+  UINT8 LastLba1;

+  UINT8 LastLba0;

+  UINT8 BlockSize3;

+  UINT8 BlockSize2;

+  UINT8 BlockSize1;

+  UINT8 BlockSize0;

+} EFI_SCSI_DISK_CAPACITY_DATA;

+

+#pragma pack()

+//

+// Sense Key

+//

+#define EFI_SCSI_REQUEST_SENSE_ERROR  (0x70)

+#define EFI_SCSI_SK_NO_SENSE          (0x0)

+#define EFI_SCSI_SK_RECOVERY_ERROR    (0x1)

+#define EFI_SCSI_SK_NOT_READY         (0x2)

+#define EFI_SCSI_SK_MEDIUM_ERROR      (0x3)

+#define EFI_SCSI_SK_HARDWARE_ERROR    (0x4)

+#define EFI_SCSI_SK_ILLEGAL_REQUEST   (0x5)

+#define EFI_SCSI_SK_UNIT_ATTENTION    (0x6)

+#define EFI_SCSI_SK_DATA_PROTECT      (0x7)

+#define EFI_SCSI_SK_BLANK_CHECK       (0x8)

+#define EFI_SCSI_SK_VENDOR_SPECIFIC   (0x9)

+#define EFI_SCSI_SK_RESERVED_A        (0xA)

+#define EFI_SCSI_SK_ABORT             (0xB)

+#define EFI_SCSI_SK_RESERVED_C        (0xC)

+#define EFI_SCSI_SK_OVERFLOW          (0xD)

+#define EFI_SCSI_SK_MISCOMPARE        (0xE)

+#define EFI_SCSI_SK_RESERVED_F        (0xF)

+

+//

+// Additional Sense Codes

+//

+#define EFI_SCSI_ASC_NOT_READY                    (0x04)

+#define EFI_SCSI_ASC_MEDIA_ERR1                   (0x10)

+#define EFI_SCSI_ASC_MEDIA_ERR2                   (0x11)

+#define EFI_SCSI_ASC_MEDIA_ERR3                   (0x14)

+#define EFI_SCSI_ASC_MEDIA_ERR4                   (0x30)

+#define EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN            (0x06)

+#define EFI_SCSI_ASC_INVALID_CMD                  (0x20)

+#define EFI_SCSI_ASC_LBA_OUT_OF_RANGE             (0x21)

+#define EFI_SCSI_ASC_INVALID_FIELD                (0x24)

+#define EFI_SCSI_ASC_WRITE_PROTECTED              (0x27)

+#define EFI_SCSI_ASC_MEDIA_CHANGE                 (0x28)

+#define EFI_SCSI_ASC_RESET                        (0x29)  /* Power On Reset or Bus Reset occurred */

+#define EFI_SCSI_ASC_ILLEGAL_FIELD                (0x26)

+#define EFI_SCSI_ASC_NO_MEDIA                     (0x3A)

+#define EFI_SCSI_ASC_ILLEGAL_MODE_FOR_THIS_TRACK  (0x64)

+

+//

+// Additional Sense Code Qualifier

+//

+#define EFI_SCSI_ASCQ_IN_PROGRESS (0x01)

+

+#endif

diff --git a/edk2/MdePkg/Include/Ipf/IpfDefines.h b/edk2/MdePkg/Include/Ipf/IpfDefines.h
new file mode 100644
index 0000000..4b9c1ad
--- /dev/null
+++ b/edk2/MdePkg/Include/Ipf/IpfDefines.h
@@ -0,0 +1,553 @@
+///** @file

+//  IPF Processor Defines for assembly code

+//

+//  @note

+//  This file is included by assembly files as well. The assmber can NOT deal

+//  with /* */ commnets this is why this file is commented not following the

+//  coding standard

+//

+//Copyright (c) 2006, Intel Corporation

+//All rights reserved. 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.

+//

+//Module Name: IpfDefines.h

+//

+//**/

+

+#ifndef _IPFDEFINES_H

+#define _IPFDEFINES_H

+

+//

+//  IPI DElivery Methods

+//

+#define IPI_INT_DELIVERY    0x0

+#define IPI_PMI_DELIVERY    0x2

+#define IPI_NMI_DELIVERY    0x4

+#define IPI_INIT_DELIVERY   0x5

+#define IPI_ExtINT_DELIVERY 0x7

+

+//

+// Define Itanium-based system registers.

+//

+// Define Itanium-based system register bit field offsets.

+//

+// Processor Status Register (PSR) Bit positions

+//

+// User / System mask

+//

+#define PSR_RV0 0

+#define PSR_BE  1

+#define PSR_UP  2

+#define PSR_AC  3

+#define PSR_MFL 4

+#define PSR_MFH 5

+

+//

+// PSR bits 6-12 reserved (must be zero)

+//

+#define PSR_MBZ0    6

+#define PSR_MBZ0_V  0x1ffUL L

+

+//

+// System only mask

+//

+#define PSR_IC      13

+#define PSR_IC_MASK (1 << 13)

+#define PSR_I       14

+#define PSR_PK      15

+#define PSR_MBZ1    16

+#define PSR_MBZ1_V  0x1UL L

+#define PSR_DT      17

+#define PSR_DFL     18

+#define PSR_DFH     19

+#define PSR_SP      20

+#define PSR_PP      21

+#define PSR_DI      22

+#define PSR_SI      23

+#define PSR_DB      24

+#define PSR_LP      25

+#define PSR_TB      26

+#define PSR_RT      27

+

+//

+// PSR bits 28-31 reserved (must be zero)

+//

+#define PSR_MBZ2    28

+#define PSR_MBZ2_V  0xfUL L

+

+//

+// Neither mask

+//

+#define PSR_CPL     32

+#define PSR_CPL_LEN 2

+#define PSR_IS      34

+#define PSR_MC      35

+#define PSR_IT      36

+#define PSR_IT_MASK 0x1000000000

+#define PSR_ID      37

+#define PSR_DA      38

+#define PSR_DD      39

+#define PSR_SS      40

+#define PSR_RI      41

+#define PSR_RI_LEN  2

+#define PSR_ED      43

+#define PSR_BN      44

+

+//

+// PSR bits 45-63 reserved (must be zero)

+//

+#define PSR_MBZ3    45

+#define PSR_MBZ3_V  0xfffffUL L

+

+//

+// Floating Point Status Register (FPSR) Bit positions

+//

+//

+// Traps

+//

+#define FPSR_VD 0

+#define FPSR_DD 1

+#define FPSR_ZD 2

+#define FPSR_OD 3

+#define FPSR_UD 4

+#define FPSR_ID 5

+

+//

+// Status Field 0 - Controls

+//

+#define FPSR0_FTZ0  6

+#define FPSR0_WRE0  7

+#define FPSR0_PC0   8

+#define FPSR0_RC0   10

+#define FPSR0_TD0   12

+

+//

+// Status Field 0 - Flags

+//

+#define FPSR0_V0  13

+#define FPSR0_D0  14

+#define FPSR0_Z0  15

+#define FPSR0_O0  16

+#define FPSR0_U0  17

+#define FPSR0_I0  18

+

+//

+// Status Field 1 - Controls

+//

+#define FPSR1_FTZ0  19

+#define FPSR1_WRE0  20

+#define FPSR1_PC0   21

+#define FPSR1_RC0   23

+#define FPSR1_TD0   25

+

+//

+// Status Field 1 - Flags

+//

+#define FPSR1_V0  26

+#define FPSR1_D0  27

+#define FPSR1_Z0  28

+#define FPSR1_O0  29

+#define FPSR1_U0  30

+#define FPSR1_I0  31

+

+//

+// Status Field 2 - Controls

+//

+#define FPSR2_FTZ0  32

+#define FPSR2_WRE0  33

+#define FPSR2_PC0   34

+#define FPSR2_RC0   36

+#define FPSR2_TD0   38

+

+//

+// Status Field 2 - Flags

+//

+#define FPSR2_V0  39

+#define FPSR2_D0  40

+#define FPSR2_Z0  41

+#define FPSR2_O0  42

+#define FPSR2_U0  43

+#define FPSR2_I0  44

+

+//

+// Status Field 3 - Controls

+//

+#define FPSR3_FTZ0  45

+#define FPSR3_WRE0  46

+#define FPSR3_PC0   47

+#define FPSR3_RC0   49

+#define FPSR3_TD0   51

+

+//

+// Status Field 0 - Flags

+//

+#define FPSR3_V0  52

+#define FPSR3_D0  53

+#define FPSR3_Z0  54

+#define FPSR3_O0  55

+#define FPSR3_U0  56

+#define FPSR3_I0  57

+

+//

+// FPSR bits 58-63 Reserved -- Must be zero

+//

+#define FPSR_MBZ0   58

+#define FPSR_MBZ0_V 0x3fUL L

+

+//

+// For setting up FPSR on kernel entry

+// All traps are disabled.

+//

+#define FPSR_FOR_KERNEL     0x3f

+

+#define FP_REG_SIZE         16  // 16 byte spill size

+#define HIGHFP_REGS_LENGTH  (96 * 16)

+

+//

+// Define hardware Task Priority Register (TPR)

+//

+//

+// TPR bit positions

+//

+#define TPR_MIC     4   // Bits 0 - 3 ignored

+#define TPR_MIC_LEN 4

+#define TPR_MMI     16  // Mask Maskable Interrupt

+//

+// Define hardware Interrupt Status Register (ISR)

+//

+//

+// ISR bit positions

+//

+#define ISR_CODE          0

+#define ISR_CODE_LEN      16

+#define ISR_CODE_MASK     0xFFFF

+#define ISR_IA_VECTOR     16

+#define ISR_IA_VECTOR_LEN 8

+#define ISR_MBZ0          24

+#define ISR_MBZ0_V        0xff

+#define ISR_X             32

+#define ISR_W             33

+#define ISR_R             34

+#define ISR_NA            35

+#define ISR_SP            36

+#define ISR_RS            37

+#define ISR_IR            38

+#define ISR_NI            39

+#define ISR_MBZ1          40

+#define ISR_EI            41

+#define ISR_ED            43

+#define ISR_MBZ2          44

+#define ISR_MBZ2_V        0xfffff

+

+//

+// ISR codes

+//

+// For General exceptions: ISR{3:0}

+//

+#define ISR_ILLEGAL_OP  0 //  Illegal operation fault

+#define ISR_PRIV_OP     1 //  Privileged operation fault

+#define ISR_PRIV_REG    2 //  Privileged register fauls

+#define ISR_RESVD_REG   3 //  Reserved register/field flt

+#define ISR_ILLEGAL_ISA 4 // Disabled instruction set transition fault

+//

+// Define hardware Default Control Register (DCR)

+//

+//

+// DCR bit positions

+//

+#define DCR_PP        0

+#define DCR_BE        1

+#define DCR_LC        2

+#define DCR_MBZ0      4

+#define DCR_MBZ0_V    0xf

+#define DCR_DM        8

+#define DCR_DP        9

+#define DCR_DK        10

+#define DCR_DX        11

+#define DCR_DR        12

+#define DCR_DA        13

+#define DCR_DD        14

+#define DCR_DEFER_ALL 0x7f00

+#define DCR_MBZ1      2

+#define DCR_MBZ1_V    0xffffffffffffUL L

+

+//

+// Define hardware RSE Configuration Register

+//

+// RS Configuration (RSC) bit field positions

+//

+#define RSC_MODE        0

+#define RSC_PL          2

+#define RSC_BE          4

+#define RSC_MBZ0        5

+#define RSC_MBZ0_V      0x3ff

+#define RSC_LOADRS      16

+#define RSC_LOADRS_LEN  14

+#define RSC_MBZ1        30

+#define RSC_MBZ1_V      0x3ffffffffUL L

+

+//

+// RSC modes

+//

+#define RSC_MODE_LY (0x0) // Lazy

+#define RSC_MODE_SI (0x1) // Store intensive

+#define RSC_MODE_LI (0x2) // Load intensive

+#define RSC_MODE_EA (0x3) // Eager

+//

+// RSC Endian bit values

+//

+#define RSC_BE_LITTLE 0

+#define RSC_BE_BIG    1

+

+//

+// Define Interruption Function State (IFS) Register

+//

+// IFS bit field positions

+//

+#define IFS_IFM     0

+#define IFS_IFM_LEN 38

+#define IFS_MBZ0    38

+#define IFS_MBZ0_V  0x1ffffff

+#define IFS_V       63

+#define IFS_V_LEN   1

+

+//

+// IFS is valid when IFS_V = IFS_VALID

+//

+#define IFS_VALID 1

+

+//

+// Define Page Table Address (PTA)

+//

+#define PTA_VE        0

+#define PTA_VF        8

+#define PTA_SIZE      2

+#define PTA_SIZE_LEN  6

+#define PTA_BASE      15

+

+//

+// Define Region Register (RR)

+//

+//

+// RR bit field positions

+//

+#define RR_VE       0

+#define RR_MBZ0     1

+#define RR_PS       2

+#define RR_PS_LEN   6

+#define RR_RID      8

+#define RR_RID_LEN  24

+#define RR_MBZ1     32

+

+//

+// SAL uses region register 0 and RID of 1000

+//

+#define SAL_RID     0x1000

+#define SAL_RR_REG  0x0

+#define SAL_TR      0x0

+

+//

+// Total number of region registers

+//

+#define RR_SIZE 8

+

+//

+// Define Protection Key Register (PKR)

+//

+// PKR bit field positions

+//

+#define PKR_V       0

+#define PKR_WD      1

+#define PKR_RD      2

+#define PKR_XD      3

+#define PKR_MBZ0    4

+#define PKR_KEY     8

+#define PKR_KEY_LEN 24

+#define PKR_MBZ1    32

+

+#define PKR_VALID   (1 << PKR_V)

+

+//

+// Number of protection key registers

+//

+#define PKRNUM  8

+

+//

+// Define Interruption TLB Insertion register (ITIR)

+//

+//

+// Define Translation Insertion Format (TR)

+//

+// PTE0 bit field positions

+//

+#define PTE0_P    0

+#define PTE0_MBZ0 1

+#define PTE0_MA   2

+#define PTE0_A    5

+#define PTE0_D    6

+#define PTE0_PL   7

+#define PTE0_AR   9

+#define PTE0_PPN  12

+#define PTE0_MBZ1 48

+#define PTE0_ED   52

+#define PTE0_IGN0 53

+

+//

+// ITIR bit field positions

+//

+#define ITIR_MBZ0     0

+#define ITIR_PS       2

+#define ITIR_PS_LEN   6

+#define ITIR_KEY      8

+#define ITIR_KEY_LEN  24

+#define ITIR_MBZ1     32

+#define ITIR_MBZ1_LEN 16

+#define ITIR_PPN      48

+#define ITIR_PPN_LEN  15

+#define ITIR_MBZ2     63

+

+#define ATTR_IPAGE    0x661 // Access Rights = RWX (bits 11-9=011), PL 0(8-7=0)

+#define ATTR_DEF_BITS 0x661 // Access Rights = RWX (bits 11-9=010), PL 0(8-7=0)

+// Dirty (bit 6=1), Accessed (bit 5=1),

+// MA WB (bits 4-2=000), Present (bit 0=1)

+//

+// Memory access rights

+//

+#define AR_UR_KR      0x0 // user/kernel read

+#define AR_URX_KRX    0x1 // user/kernel read and execute

+#define AR_URW_KRW    0x2 // user/kernel read & write

+#define AR_URWX_KRWX  0x3 // user/kernel read,write&execute

+#define AR_UR_KRW     0x4 // user read/kernel read,write

+#define AR_URX_KRWX   0x5 // user read/execute, kernel all

+#define AR_URWX_KRW   0x6 // user all, kernel read & write

+#define AR_UX_KRX     0x7 // user execute only, kernel read and execute

+//

+// Memory attribute values

+//

+//

+// The next 4 are all cached, non-sequential & speculative, coherent

+//

+#define MA_WBU  0x0 // Write back, unordered

+//

+// The next 3 are all non-cached, sequential & non-speculative

+//

+#define MA_UC   0x4 // Non-coalescing, sequential & non-speculative

+#define MA_UCE  0x5 // Non-coalescing, sequential, non-speculative

+// & fetchadd exported

+//

+#define MA_WC   0x6 // Non-cached, Coalescing,  non-seq., spec.

+#define MA_NAT  0xf // NaT page

+//

+// Definition of the offset of TRAP/INTERRUPT/FAULT handlers from the

+// base of IVA (Interruption Vector Address)

+//

+#define IVT_SIZE          0x8000

+#define EXTRA_ALIGNMENT   0x1000

+

+#define OFF_VHPTFLT       0x0000  // VHPT Translation fault

+#define OFF_ITLBFLT       0x0400  // Instruction TLB fault

+#define OFF_DTLBFLT       0x0800  // Data TLB fault

+#define OFF_ALTITLBFLT    0x0C00  // Alternate ITLB fault

+#define OFF_ALTDTLBFLT    0x1000  // Alternate DTLB fault

+#define OFF_NESTEDTLBFLT  0x1400  // Nested TLB fault

+#define OFF_IKEYMISSFLT   0x1800  // Inst Key Miss fault

+#define OFF_DKEYMISSFLT   0x1C00  // Data Key Miss fault

+#define OFF_DIRTYBITFLT   0x2000  // Dirty-Bit fault

+#define OFF_IACCESSBITFLT 0x2400  // Inst Access-Bit fault

+#define OFF_DACCESSBITFLT 0x2800  // Data Access-Bit fault

+#define OFF_BREAKFLT      0x2C00  // Break Inst fault

+#define OFF_EXTINT        0x3000  // External Interrupt

+//

+//  Offset 0x3400 to 0x0x4C00 are reserved

+//

+#define OFF_PAGENOTPFLT   0x5000  // Page Not Present fault

+#define OFF_KEYPERMFLT    0x5100  // Key Permission fault

+#define OFF_IACCESSRTFLT  0x5200  // Inst Access-Rights flt

+#define OFF_DACCESSRTFLT  0x5300  // Data Access-Rights fault

+#define OFF_GPFLT         0x5400  // General Exception fault

+#define OFF_FPDISFLT      0x5500  // Disable-FP fault

+#define OFF_NATFLT        0x5600  // NAT Consumption fault

+#define OFF_SPECLNFLT     0x5700  // Speculation fault

+#define OFF_DBGFLT        0x5900  // Debug fault

+#define OFF_ALIGNFLT      0x5A00  // Unaligned Reference fault

+#define OFF_LOCKDREFFLT   0x5B00  // Locked Data Reference fault

+#define OFF_FPFLT         0x5C00  // Floating Point fault

+#define OFF_FPTRAP        0x5D00  // Floating Point Trap

+#define OFF_LOPRIVTRAP    0x5E00  // Lower-Privilege Transfer Trap

+#define OFF_TAKENBRTRAP   0x5F00  // Taken Branch Trap

+#define OFF_SSTEPTRAP     0x6000  // Single Step Trap

+//

+// Offset 0x6100 to 0x6800 are reserved

+//

+#define OFF_IA32EXCEPTN   0x6900  // iA32 Exception

+#define OFF_IA32INTERCEPT 0x6A00  // iA32 Intercept

+#define OFF_IA32INT       0x6B00  // iA32 Interrupt

+#define NUMBER_OF_VECTORS 0x100

+//

+// Privilege levels

+//

+#define PL_KERNEL 0

+#define PL_USER   3

+

+//

+// Instruction set (IS) bits

+//

+#define IS_IA64 0

+#define IS_IA   1

+

+//

+// RSC while in kernel: enabled, little endian, PL = 0, eager mode

+//

+#define RSC_KERNEL  ((RSC_MODE_EA << RSC_MODE) | (RSC_BE_LITTLE << RSC_BE))

+

+//

+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode

+//

+#define RSC_KERNEL_LAZ  ((RSC_MODE_LY << RSC_MODE) | (RSC_BE_LITTLE << RSC_BE))

+

+//

+// RSE disabled: disabled, PL = 0, little endian, eager mode

+//

+#define RSC_KERNEL_DISABLED   ((RSC_MODE_LY << RSC_MODE) | (RSC_BE_LITTLE << RSC_BE))

+

+#define NAT_BITS_PER_RNAT_REG 63

+

+//

+// Macros for generating PTE0 and PTE1 value

+//

+#define PTE0(ed, ppn12_47, ar, pl, d, a, ma, p) \

+                ( ( ed << PTE0_ED )               |  \

+                  ( ppn12_47 << PTE0_PPN )        |  \

+                  ( ar << PTE0_AR )               |  \

+                  ( pl << PTE0_PL )               |  \

+                  ( d << PTE0_D )                 |  \

+                  ( a << PTE0_A )                 |  \

+                  ( ma << PTE0_MA )               |  \

+                  ( p << PTE0_P )                    \

+                )

+

+#define ITIR(ppn48_63, key, ps)            \

+                ( ( ps << ITIR_PS )       |  \

+                  ( key << ITIR_KEY )     |  \

+                  ( ppn48_63 << ITIR_PPN )         \

+    )

+

+//

+// Macro to generate mask value from bit position. The result is a

+// 64-bit.

+//

+#define BITMASK(bp, value)      (value << bp)

+

+#define BUNDLE_SIZE             16

+#define SPURIOUS_INT            0xF

+

+#define FAST_DISABLE_INTERRUPTS rsm BITMASK (PSR_I, 1);;

+

+#define FAST_ENABLE_INTERRUPTS  ssm BITMASK (PSR_I, 1);;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ipf/IpfMacro.i b/edk2/MdePkg/Include/Ipf/IpfMacro.i
new file mode 100644
index 0000000..506b4b3
--- /dev/null
+++ b/edk2/MdePkg/Include/Ipf/IpfMacro.i
@@ -0,0 +1,64 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//  IpfMacro.i

+//

+// Abstract:

+//  Contains the macros needed for calling procedures in Itanium-based assembly code.

+//

+//

+// Revision History:

+//

+//--

+

+#ifndef  __IA64PROC_I__

+#define  __IA64PROC_I__

+

+

+#define PROCEDURE_ENTRY(name)   .##text;            \

+                                .##type name, @function;    \

+                                .##proc name;           \

+name::

+

+#define PROCEDURE_EXIT(name)    .##endp name

+

+// Note: use of NESTED_SETUP requires number of locals (l) >= 3

+

+#define NESTED_SETUP(i,l,o,r) \

+         alloc loc1=ar##.##pfs,i,l,o,r ;\

+         mov loc0=b0

+

+#define NESTED_RETURN \

+         mov b0=loc0 ;\

+         mov ar##.##pfs=loc1 ;;\

+         br##.##ret##.##dpnt  b0;;

+

+

+#define INTERRUPT_HANDLER_BEGIN(name) \

+PROCEDURE_ENTRY(name##HandlerBegin) \

+;; \

+PROCEDURE_EXIT(name##HandlerBegin)

+

+#define INTERRUPT_HANDLER_END(name) \

+PROCEDURE_ENTRY(name##HandlerEnd) \

+;; \

+PROCEDURE_EXIT(name##HandlerEnd) 

+

+

+#define INTERRUPT_HANDLER_BLOCK_BEGIN \

+INTERRUPT_HANDLER_BEGIN(First)

+

+#define INTERRUPT_HANDLER_BLOCK_END \

+INTERRUPT_HANDLER_END(Last)

+

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Ipf/ProcessorBind.h b/edk2/MdePkg/Include/Ipf/ProcessorBind.h
new file mode 100644
index 0000000..99da96c
--- /dev/null
+++ b/edk2/MdePkg/Include/Ipf/ProcessorBind.h
@@ -0,0 +1,202 @@
+/** @file

+  Processor or Compiler specific defines and types for Intel Itanium(TM).

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ProcessorBind.h

+

+**/

+

+#ifndef __PROCESSOR_BIND_H__

+#define __PROCESSOR_BIND_H__

+

+

+//

+// Define the processor type so other code can make processor based choices

+//

+#define MDE_CPU_IPF

+

+

+//

+// Make sure we are useing the correct packing rules per EFI specification

+//

+#pragma pack()

+

+

+#if _MSC_EXTENSIONS 

+    

+//

+// Disable warning that make it impossible to compile at /W4

+// This only works for Microsoft tools. Copied from the 

+// IA-32 version of efibind.h

+//

+

+//

+// Disabling bitfield type checking warnings.

+//

+#pragma warning ( disable : 4214 )

+

+

+// Disabling the unreferenced formal parameter warnings.

+//

+#pragma warning ( disable : 4100 )

+

+//

+// Disable slightly different base types warning as CHAR8 * can not be set

+// to a constant string.

+//

+#pragma warning ( disable : 4057 )

+

+//

+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning

+//

+#pragma warning ( disable : 4127 )

+

+//

+// Can not cast a function pointer to a data pointer. We need to do this on 

+// IPF to get access to the PLABEL.

+//

+#pragma warning ( disable : 4514 )

+

+

+#endif

+

+

+#if (__STDC_VERSION__ < 199901L)

+  //

+  // No ANSI C 2000 stdint.h integer width declarations, so define equivalents

+  //

+ 

+  #if _MSC_EXTENSIONS 

+    

+

+    //

+    // use Microsoft C complier dependent interger width types 

+    //

+    typedef unsigned __int64    UINT64;

+    typedef __int64             INT64;

+    typedef unsigned __int32    UINT32;

+    typedef __int32             INT32;

+    typedef unsigned short      UINT16;

+    typedef unsigned short      CHAR16;

+    typedef short               INT16;

+    typedef unsigned char       BOOLEAN;

+    typedef unsigned char       UINT8;

+    typedef char                CHAR8;

+    typedef char                INT8;

+  #else

+    #ifdef _EFI_P64 

+      //

+      // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints 

+      //  are 32-bits

+      //

+      typedef unsigned long long  UINT64;

+      typedef long long           INT64;

+      typedef unsigned int        UINT32;

+      typedef int                 INT32;

+      typedef unsigned short      CHAR16;

+      typedef unsigned short      UINT16;

+      typedef short               INT16;

+      typedef unsigned char       BOOLEAN;

+      typedef unsigned char       UINT8;

+      typedef char                CHAR8;

+      typedef char                INT8;

+    #else

+      //

+      // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit.

+      //

+      typedef unsigned long   UINT64;

+      typedef long            INT64;

+      typedef unsigned int    UINT32;

+      typedef int             INT32;

+      typedef unsigned short  UINT16;

+      typedef unsigned short  CHAR16;

+      typedef short           INT16;

+      typedef unsigned char   BOOLEAN;

+      typedef unsigned char   UINT8;

+      typedef char            CHAR8;

+      typedef char            INT8;

+    #endif

+  #endif

+

+  #define UINT8_MAX 0xff

+

+#else

+  //

+  // Use ANSI C 2000 stdint.h integer width declarations

+  //

+  #include <stdint.h>

+  typedef uint8_t   BOOLEAN;

+  typedef int8_t    INT8;

+  typedef uint8_t   UINT8;

+  typedef int16_t   INT16;

+  typedef uint16_t  UINT16;

+  typedef int32_t   INT32;

+  typedef uint32_t  UINT32;

+  typedef int64_t   INT64;

+  typedef uint64_t  UINT64;

+  typedef char      CHAR8;

+  typedef uint16_t  CHAR16;

+

+#endif

+

+typedef UINT64  UINTN;

+typedef INT64   INTN;

+

+

+//

+// Processor specific defines

+//

+#define MAX_BIT     0x8000000000000000ULL

+#define MAX_2_BITS  0xC000000000000000ULL

+

+//

+// Maximum legal Itanium-based address

+//

+#define MAX_ADDRESS   0xFFFFFFFFFFFFFFFFULL

+

+//

+// Modifier to ensure that all protocol member functions and EFI intrinsics

+// use the correct C calling convention. All protocol member functions and

+// EFI intrinsics are required to modify thier member functions with EFIAPI.

+//

+#if _MSC_EXTENSIONS 

+  //

+  // Microsoft* compiler requires _EFIAPI useage, __cdecl is Microsoft* specific C.

+  // 

+  #define EFIAPI __cdecl  

+#else

+  #define EFIAPI       

+#endif

+

+//

+// The Microsoft* C compiler can removed references to unreferenced data items

+//  if the /OPT:REF linker option is used. We defined a macro as this is a 

+//  a non standard extension

+//

+#define GLOBAL_REMOVE_IF_UNREFERENCED

+

+//

+// A pointer to a function in IPF points to a plabel.

+//

+typedef struct {

+  UINT64  EntryPoint;

+  UINT64  GP;

+} EFI_PLABEL;

+

+typedef struct {

+  UINTN BootPhase;      // entry r20 value

+  UINTN UniqueId;       // PAL arbitration ID

+  UINTN HealthStat;     // Health Status

+  UINTN PALRetAddress;  // return address to PAL

+} IPF_HANDOFF_STATUS;

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Ipf/SalApi.h b/edk2/MdePkg/Include/Ipf/SalApi.h
new file mode 100644
index 0000000..cbaf4ac
--- /dev/null
+++ b/edk2/MdePkg/Include/Ipf/SalApi.h
@@ -0,0 +1,691 @@
+/** @file

+  Main SAL API's defined in SAL 3.0 specification. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SalApi.h

+

+**/

+

+#ifndef __SAL_API_H__

+#define __SAL_API_H__

+

+typedef UINTN EFI_SAL_STATUS;

+

+//

+// EFI_SAL_STATUS defines

+//

+#define EFI_SAL_SUCCESS               ((EFI_SAL_STATUS) 0)

+#define EFI_SAL_MORE_RECORDS          ((EFI_SAL_STATUS) 3)

+#define EFI_SAL_NOT_IMPLEMENTED       ((EFI_SAL_STATUS) - 1)

+#define EFI_SAL_INVALID_ARGUMENT      ((EFI_SAL_STATUS) - 2)

+#define EFI_SAL_ERROR                 ((EFI_SAL_STATUS) - 3)

+#define EFI_SAL_VIRTUAL_ADDRESS_ERROR ((EFI_SAL_STATUS) - 4)

+#define EFI_SAL_NO_INFORMATION        ((EFI_SAL_STATUS) - 5)

+#define EFI_SAL_NOT_ENOUGH_SCRATCH    ((EFI_SAL_STATUS) - 9)

+

+//

+//  Return values from SAL

+//

+typedef struct {

+  EFI_SAL_STATUS  Status; // register r8

+  UINTN           r9;

+  UINTN           r10;

+  UINTN           r11;

+} SAL_RETURN_REGS;

+

+typedef SAL_RETURN_REGS (EFIAPI *SAL_PROC)

+  (

+    IN UINT64 FunctionId,

+    IN UINT64 Arg2,

+    IN UINT64 Arg3,

+    IN UINT64 Arg4,

+    IN UINT64 Arg5,

+    IN UINT64 Arg6,

+    IN UINT64 Arg7,

+    IN UINT64 Arg8

+  );

+

+//

+// SAL Procedure FunctionId definition

+//

+#define EFI_SAL_SET_VECTORS             0x01000000

+#define EFI_SAL_GET_STATE_INFO          0x01000001

+#define EFI_SAL_GET_STATE_INFO_SIZE     0x01000002

+#define EFI_SAL_CLEAR_STATE_INFO        0x01000003

+#define EFI_SAL_MC_RENDEZ               0x01000004

+#define EFI_SAL_MC_SET_PARAMS           0x01000005

+#define EFI_SAL_REGISTER_PHYSICAL_ADDR  0x01000006

+#define EFI_SAL_CACHE_FLUSH             0x01000008

+#define EFI_SAL_CACHE_INIT              0x01000009

+#define EFI_SAL_PCI_CONFIG_READ         0x01000010

+#define EFI_SAL_PCI_CONFIG_WRITE        0x01000011

+#define EFI_SAL_FREQ_BASE               0x01000012

+#define EFI_SAL_UPDATE_PAL              0x01000020

+

+#define EFI_SAL_FUNCTION_ID_MASK        0x0000ffff

+#define EFI_SAL_MAX_SAL_FUNCTION_ID     0x00000021

+

+//

+// SAL Procedure parameter definitions

+// Not much point in using typedefs or enums because all params

+// are UINT64 and the entry point is common

+//

+// EFI_SAL_SET_VECTORS

+//

+#define EFI_SAL_SET_MCA_VECTOR          0x0

+#define EFI_SAL_SET_INIT_VECTOR         0x1

+#define EFI_SAL_SET_BOOT_RENDEZ_VECTOR  0x2

+

+typedef struct {

+  UINT64  Length : 32;

+  UINT64  ChecksumValid : 1;

+  UINT64  Reserved1 : 7;

+  UINT64  ByteChecksum : 8;

+  UINT64  Reserved2 : 16;

+} SAL_SET_VECTORS_CS_N;

+

+//

+// EFI_SAL_GET_STATE_INFO, EFI_SAL_GET_STATE_INFO_SIZE,

+// EFI_SAL_CLEAR_STATE_INFO

+//

+#define EFI_SAL_MCA_STATE_INFO  0x0

+#define EFI_SAL_INIT_STATE_INFO 0x1

+#define EFI_SAL_CMC_STATE_INFO  0x2

+#define EFI_SAL_CP_STATE_INFO   0x3

+

+//

+// EFI_SAL_MC_SET_PARAMS

+//

+#define EFI_SAL_MC_SET_RENDEZ_PARAM 0x1

+#define EFI_SAL_MC_SET_WAKEUP_PARAM 0x2

+#define EFI_SAL_MC_SET_CPE_PARAM    0x3

+

+#define EFI_SAL_MC_SET_INTR_PARAM   0x1

+#define EFI_SAL_MC_SET_MEM_PARAM    0x2

+

+//

+// EFI_SAL_REGISTER_PAL_PHYSICAL_ADDR

+//

+#define EFI_SAL_REGISTER_PAL_ADDR 0x0

+

+//

+// EFI_SAL_CACHE_FLUSH

+//

+#define EFI_SAL_FLUSH_I_CACHE       0x01

+#define EFI_SAL_FLUSH_D_CACHE       0x02

+#define EFI_SAL_FLUSH_BOTH_CACHE    0x03

+#define EFI_SAL_FLUSH_MAKE_COHERENT 0x04

+

+//

+// EFI_SAL_PCI_CONFIG_READ, EFI_SAL_PCI_CONFIG_WRITE

+//

+#define EFI_SAL_PCI_CONFIG_ONE_BYTE   0x1

+#define EFI_SAL_PCI_CONFIG_TWO_BYTES  0x2

+#define EFI_SAL_PCI_CONFIG_FOUR_BYTES 0x4

+

+typedef struct {

+  UINT64  Register : 8;

+  UINT64  Function : 3;

+  UINT64  Device : 5;

+  UINT64  Bus : 8;

+  UINT64  Segment : 8;

+  UINT64  Reserved : 32;

+} SAL_PCI_ADDRESS;

+

+//

+// EFI_SAL_FREQ_BASE

+//

+#define EFI_SAL_CPU_INPUT_FREQ_BASE     0x0

+#define EFI_SAL_PLATFORM_IT_FREQ_BASE   0x1

+#define EFI_SAL_PLATFORM_RTC_FREQ_BASE  0x2

+

+//

+// EFI_SAL_UPDATE_PAL

+//

+#define EFI_SAL_UPDATE_BAD_PAL_VERSION  ((UINT64) -1)

+#define EFI_SAL_UPDATE_PAL_AUTH_FAIL    ((UINT64) -2)

+#define EFI_SAL_UPDATE_PAL_BAD_TYPE     ((UINT64) -3)

+#define EFI_SAL_UPDATE_PAL_READONLY     ((UINT64) -4)

+#define EFI_SAL_UPDATE_PAL_WRITE_FAIL   ((UINT64) -10)

+#define EFI_SAL_UPDATE_PAL_ERASE_FAIL   ((UINT64) -11)

+#define EFI_SAL_UPDATE_PAL_READ_FAIL    ((UINT64) -12)

+#define EFI_SAL_UPDATE_PAL_CANT_FIT     ((UINT64) -13)

+

+typedef struct {

+  UINT32  Size;

+  UINT32  MmddyyyyDate;

+  UINT16  Version;

+  UINT8   Type;

+  UINT8   Reserved[5];

+  UINT64  FwVendorId;

+} SAL_UPDATE_PAL_DATA_BLOCK;

+

+typedef struct _SAL_UPDATE_PAL_INFO_BLOCK {

+  struct _SAL_UPDATE_PAL_INFO_BLOCK *Next;

+  struct SAL_UPDATE_PAL_DATA_BLOCK  *DataBlock;

+  UINT8                             StoreChecksum;

+  UINT8                             Reserved[15];

+} SAL_UPDATE_PAL_INFO_BLOCK;

+

+//

+// SAL System Table Definitions

+//

+#pragma pack(1)

+typedef struct {

+  UINT32  Signature;

+  UINT32  Length;

+  UINT16  SalRevision;

+  UINT16  EntryCount;

+  UINT8   CheckSum;

+  UINT8   Reserved[7];

+  UINT16  SalAVersion;

+  UINT16  SalBVersion;

+  UINT8   OemId[32];

+  UINT8   ProductId[32];

+  UINT8   Reserved2[8];

+} SAL_SYSTEM_TABLE_HEADER;

+#pragma pack()

+

+#define EFI_SAL_ST_HEADER_SIGNATURE "SST_"

+#define EFI_SAL_REVISION            0x0300

+//

+// SAL System Types

+//

+#define EFI_SAL_ST_ENTRY_POINT        0

+#define EFI_SAL_ST_MEMORY_DESCRIPTOR  1

+#define EFI_SAL_ST_PLATFORM_FEATURES  2

+#define EFI_SAL_ST_TR_USAGE           3

+#define EFI_SAL_ST_PTC                4

+#define EFI_SAL_ST_AP_WAKEUP          5

+

+#pragma pack(1)

+typedef struct {

+  UINT8   Type; //  Type == 0

+  UINT8   Reserved[7];

+  UINT64  PalProcEntry;

+  UINT64  SalProcEntry;

+  UINT64  SalGlobalDataPointer;

+  UINT64  Reserved2[2];

+} SAL_ST_ENTRY_POINT_DESCRIPTOR;

+

+//

+// Not needed for Itanium-based OS boot

+//

+typedef struct {

+  UINT8   Type; //  Type == 1

+  UINT8   NeedVirtualRegistration;

+  UINT8   MemoryAttributes;

+  UINT8   PageAccessRights;

+  UINT8   SupportedAttributes;

+  UINT8   Reserved;

+  UINT8   MemoryType;

+  UINT8   MemoryUsage;

+  UINT64  PhysicalMemoryAddress;

+  UINT32  Length;

+  UINT32  Reserved1;

+  UINT64  OemReserved;

+} SAL_ST_MEMORY_DESCRIPTOR_ENTRY;

+

+#pragma pack()

+//

+// Memory Attributes

+//

+#define SAL_MDT_ATTRIB_WB 0x00

+//

+// #define SAL_MDT_ATTRIB_UC   0x02

+//

+#define SAL_MDT_ATTRIB_UC   0x04

+#define SAL_MDT_ATTRIB_UCE  0x05

+#define SAL_MDT_ATTRIB_WC   0x06

+

+//

+// Supported memory Attributes

+//

+#define SAL_MDT_SUPPORT_WB  0x1

+#define SAL_MDT_SUPPORT_UC  0x2

+#define SAL_MDT_SUPPORT_UCE 0x4

+#define SAL_MDT_SUPPORT_WC  0x8

+

+//

+// Virtual address registration

+//

+#define SAL_MDT_NO_VA   0x00

+#define SAL_MDT_NEED_VA 0x01

+//

+// MemoryType info

+//

+#define SAL_REGULAR_MEMORY  0x0000

+#define SAL_MMIO_MAPPING    0x0001

+#define SAL_SAPIC_IPI_BLOCK 0x0002

+#define SAL_IO_PORT_MAPPING 0x0003

+#define SAL_FIRMWARE_MEMORY 0x0004

+#define SAL_BLACK_HOLE      0x000A

+//

+// Memory Usage info

+//

+#define SAL_MDT_USAGE_UNSPECIFIED 0x00

+#define SAL_PAL_CODE              0x01

+#define SAL_BOOTSERVICE_CODE      0x02

+#define SAL_BOOTSERVICE_DATA      0x03

+#define SAL_RUNTIMESERVICE_CODE   0x04

+#define SAL_RUNTIMESERVICE_DATA   0x05

+#define SAL_IA32_OPTIONROM        0x06

+#define SAL_IA32_SYSTEMROM        0x07

+#define SAL_PMI_CODE              0x0a

+#define SAL_PMI_DATA              0x0b

+

+#pragma pack(1)

+typedef struct {

+  UINT8 Type;                     // Type == 2

+  UINT8 PlatformFeatures;

+  UINT8 Reserved[14];

+} SAL_ST_PLATFORM_FEATURES;

+#pragma pack()

+

+#define SAL_PLAT_FEAT_BUS_LOCK      0x01

+#define SAL_PLAT_FEAT_PLAT_IPI_HINT 0x02

+#define SAL_PLAT_FEAT_PROC_IPI_HINT 0x04

+

+#pragma pack(1)

+typedef struct {

+  UINT8   Type;                   // Type == 3

+  UINT8   TRType;

+  UINT8   TRNumber;

+  UINT8   Reserved[5];

+  UINT64  VirtualAddress;

+  UINT64  EncodedPageSize;

+  UINT64  Reserved1;

+} SAL_ST_TR_DECRIPTOR;

+#pragma pack()

+

+#define EFI_SAL_ST_TR_USAGE_INSTRUCTION 00

+#define EFI_SAL_ST_TR_USAGE_DATA        01

+

+#pragma pack(1)

+typedef struct {

+  UINT64  NumberOfProcessors;

+  UINT64  LocalIDRegister;

+} SAL_COHERENCE_DOMAIN_INFO;

+#pragma pack()

+

+#pragma pack(1)

+typedef struct {

+  UINT8                     Type; // Type == 4

+  UINT8                     Reserved[3];

+  UINT32                    NumberOfDomains;

+  SAL_COHERENCE_DOMAIN_INFO *DomainInformation;

+} SAL_ST_CACHE_COHERENCE_DECRIPTOR;

+#pragma pack()

+

+#pragma pack(1)

+typedef struct {

+  UINT8   Type;                   // Type == 5

+  UINT8   WakeUpType;

+  UINT8   Reserved[6];

+  UINT64  ExternalInterruptVector;

+} SAL_ST_AP_WAKEUP_DECRIPTOR;

+#pragma pack()

+//

+// FIT Entry

+//

+#define EFI_SAL_FIT_ENTRY_PTR   (0x100000000 - 32)  // 4GB - 24

+#define EFI_SAL_FIT_PALA_ENTRY  (0x100000000 - 48)  // 4GB - 32

+#define EFI_SAL_FIT_PALB_TYPE   01

+

+typedef struct {

+  UINT64  Address;

+  UINT8   Size[3];

+  UINT8   Reserved;

+  UINT16  Revision;

+  UINT8   Type : 7;

+  UINT8   CheckSumValid : 1;

+  UINT8   CheckSum;

+} EFI_SAL_FIT_ENTRY;

+

+//

+//  SAL Common Record Header

+//

+typedef struct {

+  UINT16  Length;

+  UINT8   Data[1024];

+} SAL_OEM_DATA;

+

+typedef struct {

+  UINT8 Seconds;

+  UINT8 Minutes;

+  UINT8 Hours;

+  UINT8 Reserved;

+  UINT8 Day;

+  UINT8 Month;

+  UINT8 Year;

+  UINT8 Century;

+} SAL_TIME_STAMP;

+

+typedef struct {

+  UINT64          RecordId;

+  UINT16          Revision;

+  UINT8           ErrorSeverity;

+  UINT8           ValidationBits;

+  UINT32          RecordLength;

+  SAL_TIME_STAMP  TimeStamp;

+  UINT8           OemPlatformId[16];

+} SAL_RECORD_HEADER;

+

+typedef struct {

+  EFI_GUID  Guid;

+  UINT16    Revision;

+  UINT8     ErrorRecoveryInfo;

+  UINT8     Reserved;

+  UINT32    SectionLength;

+} SAL_SEC_HEADER;

+

+//

+// SAL Processor Record

+//

+#define SAL_PROCESSOR_ERROR_RECORD_INFO \

+  { \

+    0xe429faf1, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define CHECK_INFO_VALID_BIT_MASK   0x1

+#define REQUESTOR_ID_VALID_BIT_MASK 0x2

+#define RESPONDER_ID_VALID_BIT_MASK 0x4

+#define TARGER_ID_VALID_BIT_MASK    0x8

+#define PRECISE_IP_VALID_BIT_MASK   0x10

+

+typedef struct {

+  UINT64  InfoValid : 1;

+  UINT64  ReqValid : 1;

+  UINT64  RespValid : 1;

+  UINT64  TargetValid : 1;

+  UINT64  IpValid : 1;

+  UINT64  Reserved : 59;

+  UINT64  Info;

+  UINT64  Req;

+  UINT64  Resp;

+  UINT64  Target;

+  UINT64  Ip;

+} MOD_ERROR_INFO;

+

+typedef struct {

+  UINT8 CpuidInfo[40];

+  UINT8 Reserved;

+} CPUID_INFO;

+

+typedef struct {

+  UINT64  FrLow;

+  UINT64  FrHigh;

+} FR_STRUCT;

+

+#define MIN_STATE_VALID_BIT_MASK  0x1

+#define BR_VALID_BIT_MASK         0x2

+#define CR_VALID_BIT_MASK         0x4

+#define AR_VALID_BIT_MASK         0x8

+#define RR_VALID_BIT_MASK         0x10

+#define FR_VALID_BIT_MASK         0x20

+

+typedef struct {

+  UINT64    ValidFieldBits;

+  UINT8     MinStateInfo[1024];

+  UINT64    Br[8];

+  UINT64    Cr[128];

+  UINT64    Ar[128];

+  UINT64    Rr[8];

+  FR_STRUCT Fr[128];

+} PSI_STATIC_STRUCT;

+

+#define PROC_ERROR_MAP_VALID_BIT_MASK       0x1

+#define PROC_STATE_PARAMETER_VALID_BIT_MASK 0x2

+#define PROC_CR_LID_VALID_BIT_MASK          0x4

+#define PROC_STATIC_STRUCT_VALID_BIT_MASK   0x8

+#define CPU_INFO_VALID_BIT_MASK             0x1000000

+

+typedef struct {

+  SAL_SEC_HEADER    SectionHeader;

+  UINT64            ValidationBits;

+  UINT64            ProcErrorMap;

+  UINT64            ProcStateParameter;

+  UINT64            ProcCrLid;

+  MOD_ERROR_INFO    CacheError[15];

+  MOD_ERROR_INFO    TlbError[15];

+  MOD_ERROR_INFO    BusError[15];

+  MOD_ERROR_INFO    RegFileCheck[15];

+  MOD_ERROR_INFO    MsCheck[15];

+  CPUID_INFO        CpuInfo;

+  PSI_STATIC_STRUCT PsiValidData;

+} SAL_PROCESSOR_ERROR_RECORD;

+

+//

+//  Sal Platform memory Error Record

+//

+#define SAL_MEMORY_ERROR_RECORD_INFO \

+  { \

+    0xe429faf2, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define MEMORY_ERROR_STATUS_VALID_BIT_MASK                0x1

+#define MEMORY_PHYSICAL_ADDRESS_VALID_BIT_MASK            0x2

+#define MEMORY_ADDR_BIT_MASK                              0x4

+#define MEMORY_NODE_VALID_BIT_MASK                        0x8

+#define MEMORY_CARD_VALID_BIT_MASK                        0x10

+#define MEMORY_MODULE_VALID_BIT_MASK                      0x20

+#define MEMORY_BANK_VALID_BIT_MASK                        0x40

+#define MEMORY_DEVICE_VALID_BIT_MASK                      0x80

+#define MEMORY_ROW_VALID_BIT_MASK                         0x100

+#define MEMORY_COLUMN_VALID_BIT_MASK                      0x200

+#define MEMORY_BIT_POSITION_VALID_BIT_MASK                0x400

+#define MEMORY_PLATFORM_REQUESTOR_ID_VALID_BIT_MASK       0x800

+#define MEMORY_PLATFORM_RESPONDER_ID_VALID_BIT_MASK       0x1000

+#define MEMORY_PLATFORM_TARGET_VALID_BIT_MASK             0x2000

+#define MEMORY_PLATFORM_BUS_SPECIFIC_DATA_VALID_BIT_MASK  0x4000

+#define MEMORY_PLATFORM_OEM_ID_VALID_BIT_MASK             0x8000

+#define MEMORY_PLATFORM_OEM_DATA_STRUCT_VALID_BIT_MASK    0x10000

+

+typedef struct {

+  SAL_SEC_HEADER  SectionHeader;

+  UINT64          ValidationBits;

+  UINT64          MemErrorStatus;

+  UINT64          MemPhysicalAddress;

+  UINT64          MemPhysicalAddressMask;

+  UINT16          MemNode;

+  UINT16          MemCard;

+  UINT16          MemModule;

+  UINT16          MemBank;

+  UINT16          MemDevice;

+  UINT16          MemRow;

+  UINT16          MemColumn;

+  UINT16          MemBitPosition;

+  UINT64          ModRequestorId;

+  UINT64          ModResponderId;

+  UINT64          ModTargetId;

+  UINT64          BusSpecificData;

+  UINT8           MemPlatformOemId[16];

+} SAL_MEMORY_ERROR_RECORD;

+

+//

+//  PCI BUS Errors

+//

+#define SAL_PCI_BUS_ERROR_RECORD_INFO \

+  { \

+    0xe429faf4, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define PCI_BUS_ERROR_STATUS_VALID_BIT_MASK     0x1

+#define PCI_BUS_ERROR_TYPE_VALID_BIT_MASK       0x2

+#define PCI_BUS_ID_VALID_BIT_MASK               0x4

+#define PCI_BUS_ADDRESS_VALID_BIT_MASK          0x8

+#define PCI_BUS_DATA_VALID_BIT_MASK             0x10

+#define PCI_BUS_CMD_VALID_BIT_MASK              0x20

+#define PCI_BUS_REQUESTOR_ID_VALID_BIT_MASK     0x40

+#define PCI_BUS_RESPONDER_ID_VALID_BIT_MASK     0x80

+#define PCI_BUS_TARGET_VALID_BIT_MASK           0x100

+#define PCI_BUS_OEM_ID_VALID_BIT_MASK           0x200

+#define PCI_BUS_OEM_DATA_STRUCT_VALID_BIT_MASK  0x400

+

+typedef struct {

+  UINT8 BusNumber;

+  UINT8 SegmentNumber;

+} PCI_BUS_ID;

+

+typedef struct {

+  SAL_SEC_HEADER  SectionHeader;

+  UINT64          ValidationBits;

+  UINT64          PciBusErrorStatus;

+  UINT16          PciBusErrorType;

+  PCI_BUS_ID      PciBusId;

+  UINT32          Reserved;

+  UINT64          PciBusAddress;

+  UINT64          PciBusData;

+  UINT64          PciBusCommand;

+  UINT64          PciBusRequestorId;

+  UINT64          PciBusResponderId;

+  UINT64          PciBusTargetId;

+  UINT8           PciBusOemId[16];

+} SAL_PCI_BUS_ERROR_RECORD;

+

+//

+//  PCI Component Errors

+//

+#define SAL_PCI_COMP_ERROR_RECORD_INFO \

+  { \

+    0xe429faf6, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define PCI_COMP_ERROR_STATUS_VALID_BIT_MASK    0x1

+#define PCI_COMP_INFO_VALID_BIT_MASK            0x2

+#define PCI_COMP_MEM_NUM_VALID_BIT_MASK         0x4

+#define PCI_COMP_IO_NUM_VALID_BIT_MASK          0x8

+#define PCI_COMP_REG_DATA_PAIR_VALID_BIT_MASK   0x10

+#define PCI_COMP_OEM_DATA_STRUCT_VALID_BIT_MASK 0x20

+

+typedef struct {

+  UINT16  VendorId;

+  UINT16  DeviceId;

+  UINT8   ClassCode[3];

+  UINT8   FunctionNumber;

+  UINT8   DeviceNumber;

+  UINT8   BusNumber;

+  UINT8   SegmentNumber;

+  UINT8   Reserved[5];

+} PCI_COMP_INFO;

+

+typedef struct {

+  SAL_SEC_HEADER  SectionHeader;

+  UINT64          ValidationBits;

+  UINT64          PciComponentErrorStatus;

+  PCI_COMP_INFO   PciComponentInfo;

+  UINT32          PciComponentMemNum;

+  UINT32          PciComponentIoNum;

+  UINT8           PciBusOemId[16];

+} SAL_PCI_COMPONENT_ERROR_RECORD;

+

+//

+//  Sal Device Errors Info.

+//

+#define SAL_DEVICE_ERROR_RECORD_INFO \

+  { \

+    0xe429faf3, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define SEL_RECORD_ID_VALID_BIT_MASK      0x1;

+#define SEL_RECORD_TYPE_VALID_BIT_MASK    0x2;

+#define SEL_GENERATOR_ID_VALID_BIT_MASK   0x4;

+#define SEL_EVM_REV_VALID_BIT_MASK        0x8;

+#define SEL_SENSOR_TYPE_VALID_BIT_MASK    0x10;

+#define SEL_SENSOR_NUM_VALID_BIT_MASK     0x20;

+#define SEL_EVENT_DIR_TYPE_VALID_BIT_MASK 0x40;

+#define SEL_EVENT_DATA1_VALID_BIT_MASK    0x80;

+#define SEL_EVENT_DATA2_VALID_BIT_MASK    0x100;

+#define SEL_EVENT_DATA3_VALID_BIT_MASK    0x200;

+

+typedef struct {

+  SAL_SEC_HEADER  SectionHeader;

+  UINT64          ValidationBits;

+  UINT16          SelRecordId;

+  UINT8           SelRecordType;

+  UINT32          TimeStamp;

+  UINT16          GeneratorId;

+  UINT8           EvmRevision;

+  UINT8           SensorType;

+  UINT8           SensorNum;

+  UINT8           EventDirType;

+  UINT8           Data1;

+  UINT8           Data2;

+  UINT8           Data3;

+} SAL_DEVICE_ERROR_RECORD;

+

+//

+//  Sal SMBIOS Device Errors Info.

+//

+#define SAL_SMBIOS_ERROR_RECORD_INFO \

+  { \

+    0xe429faf5, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define SMBIOS_EVENT_TYPE_VALID_BIT_MASK  0x1

+#define SMBIOS_LENGTH_VALID_BIT_MASK      0x2

+#define SMBIOS_TIME_STAMP_VALID_BIT_MASK  0x4

+#define SMBIOS_DATA_VALID_BIT_MASK        0x8

+

+typedef struct {

+  SAL_SEC_HEADER  SectionHeader;

+  UINT64          ValidationBits;

+  UINT8           SmbiosEventType;

+  UINT8           SmbiosLength;

+  UINT8           SmbiosBcdTimeStamp[6];

+} SAL_SMBIOS_DEVICE_ERROR_RECORD;

+

+//

+//  Sal Platform Specific Errors Info.

+//

+#define SAL_PLATFORM_ERROR_RECORD_INFO \

+  { \

+    0xe429faf7, 0x3cb7, 0x11d4, {0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+#define PLATFORM_ERROR_STATUS_VALID_BIT_MASK    0x1

+#define PLATFORM_REQUESTOR_ID_VALID_BIT_MASK    0x2

+#define PLATFORM_RESPONDER_ID_VALID_BIT_MASK    0x4

+#define PLATFORM_TARGET_VALID_BIT_MASK          0x8

+#define PLATFORM_SPECIFIC_DATA_VALID_BIT_MASK   0x10

+#define PLATFORM_OEM_ID_VALID_BIT_MASK          0x20

+#define PLATFORM_OEM_DATA_STRUCT_VALID_BIT_MASK 0x40

+#define PLATFORM_OEM_DEVICE_PATH_VALID_BIT_MASK 0x80

+

+typedef struct {

+  SAL_SEC_HEADER  SectionHeader;

+  UINT64          ValidationBits;

+  UINT64          PlatformErrorStatus;

+  UINT64          PlatformRequestorId;

+  UINT64          PlatformResponderId;

+  UINT64          PlatformTargetId;

+  UINT64          PlatformBusSpecificData;

+  UINT8           OemComponentId[16];

+} SAL_PLATFORM_SPECIFIC_ERROR_RECORD;

+

+//

+// Union of all the possible Sal Record Types

+//

+typedef union {

+  SAL_RECORD_HEADER                   *RecordHeader;

+  SAL_PROCESSOR_ERROR_RECORD          *SalProcessorRecord;

+  SAL_PCI_BUS_ERROR_RECORD            *SalPciBusRecord;

+  SAL_PCI_COMPONENT_ERROR_RECORD      *SalPciComponentRecord;

+  SAL_DEVICE_ERROR_RECORD             *ImpiRecord;

+  SAL_SMBIOS_DEVICE_ERROR_RECORD      *SmbiosRecord;

+  SAL_PLATFORM_SPECIFIC_ERROR_RECORD  *PlatformRecord;

+  SAL_MEMORY_ERROR_RECORD             *MemoryRecord;

+  UINT8                               *Raw;

+} SAL_ERROR_RECORDS_POINTERS;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/BaseLib.h b/edk2/MdePkg/Include/Library/BaseLib.h
new file mode 100644
index 0000000..7fb2e64
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/BaseLib.h
@@ -0,0 +1,4890 @@
+/** @file

+	Memory-only library functions with no library constructor/destructor

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	BaseLib.h

+

+**/

+

+#ifndef __BASE_LIB__

+#define __BASE_LIB__

+

+//

+// Definitions for architecture specific types

+// These include SPIN_LOCK and BASE_LIBRARY_JUMP_BUFFER

+//

+

+//

+// SPIN_LOCK

+//

+typedef UINTN                       SPIN_LOCK;

+

+#if   defined (MDE_CPU_IA32)

+//

+// IA32 context buffer used by SetJump() and LongJump()

+//

+typedef struct {

+  UINT32                            Ebx;

+  UINT32                            Esi;

+  UINT32                            Edi;

+  UINT32                            Ebp;

+  UINT32                            Esp;

+  UINT32                            Eip;

+} BASE_LIBRARY_JUMP_BUFFER;

+

+#elif defined (MDE_CPU_IPF)

+//

+// IPF context buffer used by SetJump() and LongJump()

+//

+typedef struct {

+  UINT64                            InitialUNAT;

+  UINT64                            AfterSpillUNAT;

+  UINT64                            PFS;

+  UINT64                            BSP;

+  UINT64                            RNAT;

+  UINT64                            Predicates;

+  UINT64                            LoopCount;

+  UINT64                            R4;

+  UINT64                            R5;

+  UINT64                            R6;

+  UINT64                            R7;

+  UINT64                            SP;

+  UINT64                            F2Low;

+  UINT64                            F2High;

+  UINT64                            F3Low;

+  UINT64                            F3High;

+  UINT64                            F4Low;

+  UINT64                            F4High;

+  UINT64                            F5Low;

+  UINT64                            F5High;

+  UINT64                            F16Low;

+  UINT64                            F16High;

+  UINT64                            F17Low;

+  UINT64                            F17High;

+  UINT64                            F18Low;

+  UINT64                            F18High;

+  UINT64                            F19Low;

+  UINT64                            F19High;

+  UINT64                            F20Low;

+  UINT64                            F20High;

+  UINT64                            F21Low;

+  UINT64                            F21High;

+  UINT64                            F22Low;

+  UINT64                            F22High;

+  UINT64                            F23Low;

+  UINT64                            F23High;

+  UINT64                            F24Low;

+  UINT64                            F24High;

+  UINT64                            F25Low;

+  UINT64                            F25High;

+  UINT64                            F26Low;

+  UINT64                            F26High;

+  UINT64                            F27Low;

+  UINT64                            F27High;

+  UINT64                            F28Low;

+  UINT64                            F28High;

+  UINT64                            F29Low;

+  UINT64                            F29High;

+  UINT64                            F30Low;

+  UINT64                            F30High;

+  UINT64                            F31Low;

+  UINT64                            F31High;

+  UINT64                            FPSR;

+  UINT64                            BR0;

+  UINT64                            BR1;

+  UINT64                            BR2;

+  UINT64                            BR3;

+  UINT64                            BR4;

+  UINT64                            BR5;

+} BASE_LIBRARY_JUMP_BUFFER;

+

+#elif defined (MDE_CPU_X64)

+//

+// X64 context buffer used by SetJump() and LongJump()

+//

+typedef struct {

+  UINT64                            Rbx;

+  UINT64                            Rsp;

+  UINT64                            Rbp;

+  UINT64                            Rdi;

+  UINT64                            Rsi;

+  UINT64                            R12;

+  UINT64                            R13;

+  UINT64                            R14;

+  UINT64                            R15;

+  UINT64                            Rip;

+} BASE_LIBRARY_JUMP_BUFFER;

+

+#elif defined (MDE_CPU_EBC)

+//

+// EBC context buffer used by SetJump() and LongJump()

+//

+typedef struct {

+  UINT64                            R0;

+  UINT64                            R1;

+  UINT64                            R2;

+  UINT64                            R3;

+  UINT64                            IP;

+} BASE_LIBRARY_JUMP_BUFFER;

+

+#else

+#error Unknown Processor Type

+#endif

+

+//

+// String Services

+//

+

+/**

+  Copies one Null-terminated Unicode string to another Null-terminated Unicode

+  string and returns the new Unicode string.

+

+  This function copies the contents of the Unicode string Source to the Unicode

+  string Destination, and returns Destination. If Source and Destination

+  overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+

+  @return Destiantion

+

+**/

+CHAR16 *

+EFIAPI

+StrCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  );

+

+/**

+  Copies one Null-terminated Unicode string with a maximum length to another

+  Null-terminated Unicode string with a maximum length and returns the new

+  Unicode string.

+

+  This function copies the contents of the Unicode string Source to the Unicode

+  string Destination, and returns Destination. At most, Length Unicode

+  characters are copied from Source to Destination. If Length is 0, then

+  Destination is returned unmodified. If Length is greater that the number of

+  Unicode characters in Source, then Destination is padded with Null Unicode

+  characters. If Source and Destination overlap, then the results are

+  undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+  @param  Length      Maximum number of Unicode characters to copy.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrnCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source,

+  IN      UINTN                     Length

+  );

+

+/**

+  Returns the length of a Null-terminated Unicode string.

+

+  This function returns the number of Unicode characters in the Null-terminated

+  Unicode string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated Unicode string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+StrLen (

+  IN      CONST CHAR16              *String

+  );

+

+/**

+  Returns the size of a Null-terminated Unicode string in bytes, including the

+  Null terminator.

+

+  This function returns the size, in bytes, of the Null-terminated Unicode

+  string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated Unicode string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+StrSize (

+  IN      CONST CHAR16              *String

+  );

+

+/**

+  Compares two Null-terminated Unicode strings, and returns the difference

+  between the first mismatched Unicode characters.

+

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. If FirstString is identical to

+  SecondString, then 0 is returned. Otherwise, the value returned is the first

+  mismatched Unicode character in SecondString subtracted from the first

+  mismatched Unicode character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated Unicode string.

+  @param  SecondString  Pointer to a Null-terminated Unicode string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+StrCmp (

+  IN      CONST CHAR16              *FirstString,

+  IN      CONST CHAR16              *SecondString

+  );

+

+/**

+  Compares two Null-terminated Unicode strings with maximum lengths, and

+  returns the difference between the first mismatched Unicode characters.

+

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. At most, Length Unicode

+  characters will be compared. If Length is 0, then 0 is returned. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched Unicode character in SecondString

+  subtracted from the first mismatched Unicode character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated Unicode string.

+  @param  SecondString  Pointer to a Null-terminated Unicode string.

+  @param  Length        Maximum number of Unicode characters to compare.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+StrnCmp (

+  IN      CONST CHAR16              *FirstString,

+  IN      CONST CHAR16              *SecondString,

+  IN      UINTN                     Length

+  );

+

+/**

+  Concatenates one Null-terminated Unicode string to another Null-terminated

+  Unicode string, and returns the concatenated Unicode string.

+

+  This function concatenates two Null-terminated Unicode strings. The contents

+  of Null-terminated Unicode string Source are concatenated to the end of

+  Null-terminated Unicode string Destination. The Null-terminated concatenated

+  Unicode String is returned. If Source and Destination overlap, then the

+  results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination

+  and Source results in a Unicode string with more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  );

+

+/**

+  Concatenates one Null-terminated Unicode string with a maximum length to the

+  end of another Null-terminated Unicode string, and returns the concatenated

+  Unicode string.

+

+  This function concatenates two Null-terminated Unicode strings. The contents

+  of Null-terminated Unicode string Source are concatenated to the end of

+  Null-terminated Unicode string Destination, and Destination is returned. At

+  most, Length Unicode characters are concatenated from Source to the end of

+  Destination, and Destination is always Null-terminated. If Length is 0, then

+  Destination is returned unmodified. If Source and Destination overlap, then

+  the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination

+  and Source results in a Unicode string with more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+  @param  Length      Maximum number of Unicode characters to concatenate from

+                      Source.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrnCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source,

+  IN      UINTN                     Length

+  );

+

+/**

+  Copies one Null-terminated ASCII string to another Null-terminated ASCII

+  string and returns the new ASCII string.

+

+  This function copies the contents of the ASCII string Source to the ASCII

+  string Destination, and returns Destination. If Source and Destination

+  overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source

+  );

+

+/**

+  Copies one Null-terminated ASCII string with a maximum length to another

+  Null-terminated ASCII string with a maximum length and returns the new ASCII

+  string.

+

+  This function copies the contents of the ASCII string Source to the ASCII

+  string Destination, and returns Destination. At most, Length ASCII characters

+  are copied from Source to Destination. If Length is 0, then Destination is

+  returned unmodified. If Length is greater that the number of ASCII characters

+  in Source, then Destination is padded with Null ASCII characters. If Source

+  and Destination overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+  @param  Length      Maximum number of ASCII characters to copy.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrnCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source,

+  IN      UINTN                     Length

+  );

+

+/**

+  Returns the length of a Null-terminated ASCII string.

+

+  This function returns the number of ASCII characters in the Null-terminated

+  ASCII string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and String contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated ASCII string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrLen (

+  IN      CONST CHAR8               *String

+  );

+

+/**

+  Returns the size of a Null-terminated ASCII string in bytes, including the

+  Null terminator.

+

+  This function returns the size, in bytes, of the Null-terminated ASCII string

+  specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and String contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated ASCII string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrSize (

+  IN      CONST CHAR8               *String

+  );

+

+/**

+  Compares two Null-terminated ASCII strings, and returns the difference

+  between the first mismatched ASCII characters.

+

+  This function compares the Null-terminated ASCII string FirstString to the

+  Null-terminated ASCII string SecondString. If FirstString is identical to

+  SecondString, then 0 is returned. Otherwise, the value returned is the first

+  mismatched ASCII character in SecondString subtracted from the first

+  mismatched ASCII character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+AsciiStrCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString

+  );

+

+/**

+  Performs a case insensitive comparison of two Null-terminated ASCII strings,

+  and returns the difference between the first mismatched ASCII characters.

+

+  This function performs a case insensitive comparison of the Null-terminated

+  ASCII string FirstString to the Null-terminated ASCII string SecondString. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched lower case ASCII character in

+  SecondString subtracted from the first mismatched lower case ASCII character

+  in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString using case insensitive

+              comparisons.

+  @retval !=0 FirstString is not identical to SecondString using case

+              insensitive comparisons.

+

+**/

+INTN

+EFIAPI

+AsciiStriCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString

+  );

+

+/**

+  Compares two Null-terminated ASCII strings with maximum lengths, and returns

+  the difference between the first mismatched ASCII characters.

+

+  This function compares the Null-terminated ASCII string FirstString to the

+  Null-terminated ASCII  string SecondString. At most, Length ASCII characters

+  will be compared. If Length is 0, then 0 is returned. If FirstString is

+  identical to SecondString, then 0 is returned. Otherwise, the value returned

+  is the first mismatched ASCII character in SecondString subtracted from the

+  first mismatched ASCII character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+AsciiStrnCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString,

+  IN      UINTN                     Length

+  );

+

+/**

+  Concatenates one Null-terminated ASCII string to another Null-terminated

+  ASCII string, and returns the concatenated ASCII string.

+

+  This function concatenates two Null-terminated ASCII strings. The contents of

+  Null-terminated ASCII string Source are concatenated to the end of Null-

+  terminated ASCII string Destination. The Null-terminated concatenated ASCII

+  String is returned.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Destination contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and concatenating Destination and

+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength

+  ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCat (

+  IN OUT  CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source

+  );

+

+/**

+  Concatenates one Null-terminated ASCII string with a maximum length to the

+  end of another Null-terminated ASCII string, and returns the concatenated

+  ASCII string.

+

+  This function concatenates two Null-terminated ASCII strings. The contents

+  of Null-terminated ASCII string Source are concatenated to the end of Null-

+  terminated ASCII string Destination, and Destination is returned. At most,

+  Length ASCII characters are concatenated from Source to the end of

+  Destination, and Destination is always Null-terminated. If Length is 0, then

+  Destination is returned unmodified. If Source and Destination overlap, then

+  the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Destination contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and

+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength

+  ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+  @param  Length      Maximum number of ASCII characters to concatenate from

+                      Source.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrnCat (

+  IN OUT  CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source,

+  IN      UINTN                     Length

+  );

+

+//

+// LIST_ENTRY definition

+//

+typedef struct _LIST_ENTRY LIST_ENTRY;

+

+struct _LIST_ENTRY {

+  LIST_ENTRY  *ForwardLink;

+  LIST_ENTRY  *BackLink;

+};

+

+//

+// Linked List Functions and Macros

+//

+

+/**

+  Initializes the head node of a doubly linked list that is declared as a

+  global variable in a module.

+

+  Initializes the forward and backward links of a new linked list. After

+  initializing a linked list with this macro, the other linked list functions

+  may be used to add and remove nodes from the linked list. This macro results

+  in smaller executables by initializing the linked list in the data section,

+  instead if calling the InitializeListHead() function to perform the

+  equivalent operation.

+

+  @param  ListHead  The head note of a list to initiailize.

+

+**/

+#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)  {&ListHead, &ListHead}

+

+/**

+  Initializes the head node of a doubly linked list, and returns the pointer to

+  the head node of the doubly linked list.

+

+  Initializes the forward and backward links of a new linked list. After

+  initializing a linked list with this function, the other linked list

+  functions may be used to add and remove nodes from the linked list. It is up

+  to the caller of this function to allocate the memory for ListHead.

+

+  If ListHead is NULL, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a new doubly linked list.

+

+  @return ListHead

+

+**/

+LIST_ENTRY *

+EFIAPI

+InitializeListHead (

+  IN      LIST_ENTRY                *ListHead

+  );

+

+/**

+  Adds a node to the beginning of a doubly linked list, and returns the pointer

+  to the head node of the doubly linked list.

+

+  Adds the node Entry at the beginning of the doubly linked list denoted by

+  ListHead, and returns ListHead.

+

+  If ListHead is NULL, then ASSERT().

+  If Entry is NULL, then ASSERT().

+  If ListHead was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and ListHead contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a doubly linked list.

+  @param  Entry     A pointer to a node that is to be inserted at the beginning

+                    of a doubly linked list.

+

+  @return ListHead

+

+**/

+LIST_ENTRY *

+EFIAPI

+InsertHeadList (

+  IN      LIST_ENTRY                *ListHead,

+  IN      LIST_ENTRY                *Entry

+  );

+

+/**

+  Adds a node to the end of a doubly linked list, and returns the pointer to

+  the head node of the doubly linked list.

+

+  Adds the node Entry to the end of the doubly linked list denoted by ListHead,

+  and returns ListHead.

+

+  If ListHead is NULL, then ASSERT().

+  If Entry is NULL, then ASSERT().

+  If ListHead was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and ListHead contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a doubly linked list.

+  @param  Entry     A pointer to a node that is to be added at the end of the

+                    doubly linked list.

+

+  @return ListHead

+

+**/

+LIST_ENTRY *

+EFIAPI

+InsertTailList (

+  IN      LIST_ENTRY                *ListHead,

+  IN      LIST_ENTRY                *Entry

+  );

+

+/**

+  Retrieves the first node of a doubly linked list.

+

+  Returns the first node of a doubly linked list. List must have been

+  initialized with InitializeListHead(). If List is empty, then NULL is

+  returned.

+

+  If List is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+

+  @return The first node of a doubly linked list.

+  @retval NULL  The list is empty.

+

+**/

+LIST_ENTRY *

+EFIAPI

+GetFirstNode (

+  IN      CONST LIST_ENTRY          *List

+  );

+

+/**

+  Retrieves the next node of a doubly linked list.

+

+  Returns the node of a doubly linked list that follows Node. List must have

+  been initialized with InitializeListHead(). If List is empty, then List is

+  returned.

+

+  If List is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+  If Node is not a node in List, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+  @param  Node  A pointer to a node in the doubly linked list.

+

+  @return Pointer to the next node if one exists. Otherwise a null value which

+          is actually List is returned.

+

+**/

+LIST_ENTRY *

+EFIAPI

+GetNextNode (

+  IN      CONST LIST_ENTRY          *List,

+  IN      CONST LIST_ENTRY          *Node

+  );

+

+/**

+  Checks to see if a doubly linked list is empty or not.

+

+  Checks to see if the doubly linked list is empty. If the linked list contains

+  zero nodes, this function returns TRUE. Otherwise, it returns FALSE.

+

+  If ListHead is NULL, then ASSERT().

+  If ListHead was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a doubly linked list.

+

+  @retval TRUE  The linked list is empty.

+  @retval FALSE The linked list is not empty.

+

+**/

+BOOLEAN

+EFIAPI

+IsListEmpty (

+  IN      CONST LIST_ENTRY          *ListHead

+  );

+

+/**

+  Determines if a node in a doubly linked list is null.

+

+  Returns FALSE if Node is one of the nodes in the doubly linked list specified

+  by List. Otherwise, TRUE is returned. List must have been initialized with

+  InitializeListHead().

+

+  If List is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+  If Node is not a node in List and Node is not equal to List, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+  @param  Node	A pointer to a node in the doubly linked list.

+

+  @retval TRUE  Node is one of the nodes in the doubly linked list.

+  @retval FALSE Node is not one of the nodes in the doubly linked list.

+

+**/

+BOOLEAN

+EFIAPI

+IsNull (

+  IN      CONST LIST_ENTRY          *List,

+  IN      CONST LIST_ENTRY          *Node

+  );

+

+/**

+  Determines if a node the last node in a doubly linked list.

+

+  Returns TRUE if Node is the last node in the doubly linked list specified by

+  List. Otherwise, FALSE is returned. List must have been initialized with

+  InitializeListHead().

+

+  If List is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+  If Node is not a node in List, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+  @param  Node	A pointer to a node in the doubly linked list.

+

+  @retval TRUE  Node is the last node in the linked list.

+  @retval FALSE Node is not the last node in the linked list.

+

+**/

+BOOLEAN

+EFIAPI

+IsNodeAtEnd (

+  IN      CONST LIST_ENTRY          *List,

+  IN      CONST LIST_ENTRY          *Node

+  );

+

+/**

+  Swaps the location of two nodes in a doubly linked list, and returns the

+  first node after the swap.

+

+  If FirstEntry is identical to SecondEntry, then SecondEntry is returned.

+  Otherwise, the location of the FirstEntry node is swapped with the location

+  of the SecondEntry node in a doubly linked list. SecondEntry must be in the

+  same double linked list as FirstEntry and that double linked list must have

+  been initialized with InitializeListHead(). SecondEntry is returned after the

+  nodes are swapped.

+

+  If FirstEntry is NULL, then ASSERT().

+  If SecondEntry is NULL, then ASSERT().

+  If SecondEntry and FirstEntry are not in the same linked list, then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and the linked list containing

+  FirstEntry and SecondEntry contains more than PcdMaximumLinkedListLenth

+  nodes, then ASSERT().

+

+  @param  FirstEntry  A pointer to a node in a linked list.

+  @param  SecondEntry A pointer to another node in the same linked list.

+

+**/

+LIST_ENTRY *

+EFIAPI

+SwapListEntries (

+  IN      LIST_ENTRY                *FirstEntry,

+  IN      LIST_ENTRY                *SecondEntry

+  );

+

+/**

+  Removes a node from a doubly linked list, and returns the node that follows

+  the removed node.

+

+  Removes the node Entry from a doubly linked list. It is up to the caller of

+  this function to release the memory used by this node if that is required. On

+  exit, the node following Entry in the doubly linked list is returned. If

+  Entry is the only node in the linked list, then the head node of the linked

+  list is returned.

+

+  If Entry is NULL, then ASSERT().

+  If Entry is the head node of an empty list, then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and the linked list containing

+  Entry contains more than PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  Entry A pointer to a node in a linked list

+

+  @return Entry

+

+**/

+LIST_ENTRY *

+EFIAPI

+RemoveEntryList (

+  IN      CONST LIST_ENTRY          *Entry

+  );

+

+//

+// Math Services

+//

+

+/**

+  Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled

+  with zeros. The shifted value is returned.

+

+  This function shifts the 64-bit value Operand to the left by Count bits. The

+  low Count bits are set to zero. The shifted value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to shift left.

+  @param  Count   The number of bits to shift left.

+

+  @return Operand << Count

+

+**/

+UINT64

+EFIAPI

+LShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Shifts a 64-bit integer right between 0 and 63 bits. This high bits are

+  filled with zeros. The shifted value is returned.

+

+  This function shifts the 64-bit value Operand to the right by Count bits. The

+  high Count bits are set to zero. The shifted value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand >> Count

+

+**/

+UINT64

+EFIAPI

+RShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Shifts a 64-bit integer right between 0 and 63 bits. The high bits are filled

+  with original integer's bit 63. The shifted value is returned.

+

+  This function shifts the 64-bit value Operand to the right by Count bits. The

+  high Count bits are set to bit 63 of Operand.  The shifted value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand >> Count

+

+**/

+UINT64

+EFIAPI

+ARShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Rotates a 32-bit integer left between 0 and 31 bits, filling the low bits

+  with the high bits that were rotated.

+

+  This function rotates the 32-bit value Operand to the left by Count bits. The

+  low Count bits are fill with the high Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 31, then ASSERT().

+

+  @param  Operand The 32-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count

+

+**/

+UINT32

+EFIAPI

+LRotU32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Rotates a 32-bit integer right between 0 and 31 bits, filling the high bits

+  with the low bits that were rotated.

+

+  This function rotates the 32-bit value Operand to the right by Count bits.

+  The high Count bits are fill with the low Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 31, then ASSERT().

+

+  @param  Operand The 32-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count

+

+**/

+UINT32

+EFIAPI

+RRotU32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Rotates a 64-bit integer left between 0 and 63 bits, filling the low bits

+  with the high bits that were rotated.

+

+  This function rotates the 64-bit value Operand to the left by Count bits. The

+  low Count bits are fill with the high Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count

+

+**/

+UINT64

+EFIAPI

+LRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Rotates a 64-bit integer right between 0 and 63 bits, filling the high bits

+  with the high low bits that were rotated.

+

+  This function rotates the 64-bit value Operand to the right by Count bits.

+  The high Count bits are fill with the low Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count

+

+**/

+UINT64

+EFIAPI

+RRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Returns the bit position of the lowest bit set in a 32-bit value.

+

+  This function computes the bit position of the lowest bit set in the 32-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 31 is returned.

+

+  @param  Operand The 32-bit operand to evaluate.

+

+  @return Position of the lowest bit set in Operand if found.

+  @retval -1 Operand is zero.

+

+**/

+INTN

+EFIAPI

+LowBitSet32 (

+  IN      UINT32                    Operand

+  );

+

+/**

+  Returns the bit position of the lowest bit set in a 64-bit value.

+

+  This function computes the bit position of the lowest bit set in the 64-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 63 is returned.

+

+  @param  Operand The 64-bit operand to evaluate.

+

+  @return Position of the lowest bit set in Operand if found.

+  @retval -1  Operand is zero.

+

+**/

+INTN

+EFIAPI

+LowBitSet64 (

+  IN      UINT64                    Operand

+  );

+

+/**

+  Returns the bit position of the highest bit set in a 32-bit value. Equivalent

+  to log2(x).

+

+  This function computes the bit position of the highest bit set in the 32-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 31 is returned.

+

+  @param  Operand The 32-bit operand to evaluate.

+

+  @return Position of the highest bit set in Operand if found.

+  @retval -1  Operand is zero.

+

+**/

+INTN

+EFIAPI

+HighBitSet32 (

+  IN      UINT32                    Operand

+  );

+

+/**

+  Returns the bit position of the highest bit set in a 64-bit value. Equivalent

+  to log2(x).

+

+  This function computes the bit position of the highest bit set in the 64-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 63 is returned.

+

+  @param  Operand The 64-bit operand to evaluate.

+

+  @return Position of the highest bit set in Operand if found.

+  @retval -1  Operand is zero.

+

+**/

+INTN

+EFIAPI

+HighBitSet64 (

+  IN      UINT64                    Operand

+  );

+

+/**

+  Returns the value of the highest bit set in a 32-bit value. Equivalent to

+  1 << HighBitSet32(x).

+

+  This function computes the value of the highest bit set in the 32-bit value

+  specified by Operand. If Operand is zero, then zero is returned.

+

+  @param  Operand The 32-bit operand to evaluate.

+

+  @return 1 << HighBitSet32(Operand)

+  @retval 0 Operand is zero.

+

+**/

+UINT32

+EFIAPI

+GetPowerOfTwo32 (

+  IN      UINT32                    Operand

+  );

+

+/**

+  Returns the value of the highest bit set in a 64-bit value. Equivalent to

+  1 << HighBitSet64(x).

+

+  This function computes the value of the highest bit set in the 64-bit value

+  specified by Operand. If Operand is zero, then zero is returned.

+

+  @param  Operand The 64-bit operand to evaluate.

+

+  @return 1 << HighBitSet64(Operand)

+  @retval 0 Operand is zero.

+

+**/

+UINT64

+EFIAPI

+GetPowerOfTwo64 (

+  IN      UINT64                    Operand

+  );

+

+/**

+  Switches the endianess of a 16-bit integer.

+

+  This function swaps the bytes in a 16-bit unsigned value to switch the value

+  from little endian to big endian or vice versa. The byte swapped value is

+  returned.

+

+  @param  Operand A 16-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT16

+EFIAPI

+SwapBytes16 (

+  IN      UINT16                    Value

+  );

+

+/**

+  Switches the endianess of a 32-bit integer.

+

+  This function swaps the bytes in a 32-bit unsigned value to switch the value

+  from little endian to big endian or vice versa. The byte swapped value is

+  returned.

+

+  @param  Operand A 32-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT32

+EFIAPI

+SwapBytes32 (

+  IN      UINT32                    Value

+  );

+

+/**

+  Switches the endianess of a 64-bit integer.

+

+  This function swaps the bytes in a 64-bit unsigned value to switch the value

+  from little endian to big endian or vice versa. The byte swapped value is

+  returned.

+

+  @param  Operand A 64-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT64

+EFIAPI

+SwapBytes64 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Multiples a 64-bit unsigned integer by a 32-bit unsigned integer and

+  generates a 64-bit unsigned result.

+

+  This function multiples the 64-bit unsigned value Multiplicand by the 32-bit

+  unsigned value Multiplier and generates a 64-bit unsigned result. This 64-

+  bit unsigned result is returned.

+

+  If the result overflows, then ASSERT().

+

+  @param  Multiplicand  A 64-bit unsigned value.

+  @param  Multiplier    A 32-bit unsigned value.

+

+  @return Multiplicand * Multiplier

+

+**/

+UINT64

+EFIAPI

+MultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  );

+

+/**

+  Multiples a 64-bit unsigned integer by a 64-bit unsigned integer and

+  generates a 64-bit unsigned result.

+

+  This function multiples the 64-bit unsigned value Multiplicand by the 64-bit

+  unsigned value Multiplier and generates a 64-bit unsigned result. This 64-

+  bit unsigned result is returned.

+

+  If the result overflows, then ASSERT().

+

+  @param  Multiplicand  A 64-bit unsigned value.

+  @param  Multiplier    A 64-bit unsigned value.

+

+  @return Multiplicand * Multiplier

+

+**/

+UINT64

+EFIAPI

+MultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    Multiplier

+  );

+

+/**

+  Multiples a 64-bit signed integer by a 64-bit signed integer and generates a

+  64-bit signed result.

+

+  This function multiples the 64-bit signed value Multiplicand by the 64-bit

+  signed value Multiplier and generates a 64-bit signed result. This 64-bit

+  signed result is returned.

+

+  If the result overflows, then ASSERT().

+

+  @param  Multiplicand  A 64-bit signed value.

+  @param  Multiplier    A 64-bit signed value.

+

+  @return Multiplicand * Multiplier

+

+**/

+INT64

+EFIAPI

+MultS64x64 (

+  IN      INT64                     Multiplicand,

+  IN      INT64                     Multiplier

+  );

+

+/**

+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates

+  a 64-bit unsigned result.

+

+  This function divides the 64-bit unsigned value Dividend by the 32-bit

+  unsigned value Divisor and generates a 64-bit unsigned quotient. This

+  function returns the 64-bit unsigned quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+DivU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  );

+

+/**

+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates

+  a 32-bit unsigned remainder.

+

+  This function divides the 64-bit unsigned value Dividend by the 32-bit

+  unsigned value Divisor and generates a 32-bit remainder. This function

+  returns the 32-bit unsigned remainder.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend % Divisor

+

+**/

+UINT32

+EFIAPI

+ModU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  );

+

+/**

+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates

+  a 64-bit unsigned result and an optional 32-bit unsigned remainder.

+

+  This function divides the 64-bit unsigned value Dividend by the 32-bit

+  unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder

+  is not NULL, then the 32-bit unsigned remainder is returned in Remainder.

+  This function returns the 64-bit unsigned quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+  @param  Remainder A pointer to a 32-bit unsigned value. This parameter is

+                    optional and may be NULL.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+DivU64x32Remainder (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor,

+  OUT     UINT32                    *Remainder  OPTIONAL

+  );

+

+/**

+  Divides a 64-bit unsigned integer by a 64-bit unsigned integer and generates

+  a 64-bit unsigned result and an optional 64-bit unsigned remainder.

+

+  This function divides the 64-bit unsigned value Dividend by the 64-bit

+  unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder

+  is not NULL, then the 64-bit unsigned remainder is returned in Remainder.

+  This function returns the 64-bit unsigned quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 64-bit unsigned value.

+  @param  Remainder A pointer to a 64-bit unsigned value. This parameter is

+                    optional and may be NULL.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+DivU64x64Remainder (

+  IN      UINT64                    Dividend,

+  IN      UINT64                    Divisor,

+  OUT     UINT64                    *Remainder  OPTIONAL

+  );

+

+/**

+  Divides a 64-bit signed integer by a 64-bit signed integer and generates a

+  64-bit signed result and a optional 64-bit signed remainder.

+

+  This function divides the 64-bit signed value Dividend by the 64-bit signed

+  value Divisor and generates a 64-bit signed quotient. If Remainder is not

+  NULL, then the 64-bit signed remainder is returned in Remainder. This

+  function returns the 64-bit signed quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit signed value.

+  @param  Divisor   A 64-bit signed value.

+  @param  Remainder A pointer to a 64-bit signed value. This parameter is

+                    optional and may be NULL.

+

+  @return Dividend / Divisor

+

+**/

+INT64

+EFIAPI

+DivS64x64Remainder (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder  OPTIONAL

+  );

+

+/**

+  Reads a 16-bit value from memory that may be unaligned.

+

+  This function returns the 16-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 16-bit value that may be unaligned.

+

+  @return *Uint16

+

+**/

+UINT16

+EFIAPI

+ReadUnaligned16 (

+  IN      CONST UINT16              *Uint16

+  );

+

+/**

+  Writes a 16-bit value to memory that may be unaligned.

+

+  This function writes the 16-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 16-bit value that may be unaligned.

+  @param  Value   16-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT16

+EFIAPI

+WriteUnaligned16 (

+  OUT     UINT16                    *Uint16,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a 24-bit value from memory that may be unaligned.

+

+  This function returns the 24-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 24-bit value that may be unaligned.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+ReadUnaligned24 (

+  IN      CONST UINT32              *Buffer

+  );

+

+/**

+  Writes a 24-bit value to memory that may be unaligned.

+

+  This function writes the 24-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 24-bit value that may be unaligned.

+  @param  Value   24-bit value to write to Buffer.

+

+  @return The value written.

+

+**/

+UINT32

+EFIAPI

+WriteUnaligned24 (

+  OUT     UINT32                    *Buffer,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a 32-bit value from memory that may be unaligned.

+

+  This function returns the 32-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 32-bit value that may be unaligned.

+

+  @return *Uint32

+

+**/

+UINT32

+EFIAPI

+ReadUnaligned32 (

+  IN      CONST UINT32              *Uint32

+  );

+

+/**

+  Writes a 32-bit value to memory that may be unaligned.

+

+  This function writes the 32-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 32-bit value that may be unaligned.

+  @param  Value   32-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT32

+EFIAPI

+WriteUnaligned32 (

+  OUT     UINT32                    *Uint32,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a 64-bit value from memory that may be unaligned.

+

+  This function returns the 64-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 64-bit value that may be unaligned.

+

+  @return *Uint64

+

+**/

+UINT64

+EFIAPI

+ReadUnaligned64 (

+  IN      CONST UINT64              *Uint64

+  );

+

+/**

+  Writes a 64-bit value to memory that may be unaligned.

+

+  This function writes the 64-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 64-bit value that may be unaligned.

+  @param  Value   64-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT64

+EFIAPI

+WriteUnaligned64 (

+  OUT     UINT64                    *Uint64,

+  IN      UINT64                    Value

+  );

+

+//

+// Bit Field Functions

+//

+

+/**

+  Returns a bit field from an 8-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The bit field read.

+

+**/

+UINT8

+EFIAPI

+BitFieldRead8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an 8-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 8-bit value is

+  returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldWrite8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 8-bit value is returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldOr8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field from an 8-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 8-bit value is returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the value.

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldAnd8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads a bit field from an 8-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 8-bit value is returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldAndThenOr8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Returns a bit field from a 16-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The bit field read.

+

+**/

+UINT16

+EFIAPI

+BitFieldRead16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a 16-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 16-bit value is

+  returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldWrite16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 16-bit value is returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldOr16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field from a 16-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 16-bit value is returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the value

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldAnd16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a bit field from a 16-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 16-bit value is returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldAndThenOr16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Returns a bit field from a 32-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The bit field read.

+

+**/

+UINT32

+EFIAPI

+BitFieldRead32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a 32-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 32-bit value is

+  returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldWrite32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 32-bit value is returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldOr32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field from a 32-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 32-bit value is returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the value

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldAnd32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field from a 32-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 32-bit value is returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldAndThenOr32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Returns a bit field from a 64-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The bit field read.

+

+**/

+UINT64

+EFIAPI

+BitFieldRead64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a 64-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 64-bit value is

+  returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldWrite64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 64-bit value is returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldOr64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field from a 64-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 64-bit value is returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the value

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldAnd64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a bit field from a 64-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 64-bit value is returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldAndThenOr64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+//

+// Base Library Synchronization Functions

+//

+

+/**

+  Retrieves the architecture specific spin lock alignment requirements for

+  optimal spin lock performance.

+

+  This function retrieves the spin lock alignment requirements for optimal

+  performance on a given CPU architecture. The spin lock alignment must be a

+  power of two and is returned by this function. If there are no alignment

+  requirements, then 1 must be returned. The spin lock synchronization

+  functions must function correctly if the spin lock size and alignment values

+  returned by this function are not used at all. These values are hints to the

+  consumers of the spin lock synchronization functions to obtain optimal spin

+  lock performance.

+

+  @return The architecture specific spin lock alignment.

+

+**/

+UINTN

+EFIAPI

+GetSpinLockProperties (

+  VOID

+  );

+

+/**

+  Initializes a spin lock to the released state and returns the spin lock.

+

+  This function initializes the spin lock specified by SpinLock to the released

+  state, and returns SpinLock. Optimal performance can be achieved by calling

+  GetSpinLockProperties() to determine the size and alignment requirements for

+  SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to initialize to the released

+                    state.

+

+  @return SpinLock

+

+**/

+SPIN_LOCK *

+EFIAPI

+InitializeSpinLock (

+  IN      SPIN_LOCK                 *SpinLock

+  );

+

+/**

+  Waits until a spin lock can be placed in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns SpinLock. Otherwise, this function waits

+  indefinitely for the spin lock to be released, and then places it in the

+  acquired state and returns SpinLock. All state transitions of SpinLock must

+  be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+  If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in

+  PcdSpinLockTimeout microseconds, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @return SpinLock

+

+**/

+SPIN_LOCK *

+EFIAPI

+AcquireSpinLock (

+  IN      SPIN_LOCK                 *SpinLock

+  );

+

+/**

+  Attempts to place a spin lock in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns TRUE. Otherwise, FALSE is returned. All state

+  transitions of SpinLock must be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @retval TRUE  SpinLock was placed in the acquired state.

+  @retval FALSE SpinLock could not be acquired.

+

+**/

+BOOLEAN

+EFIAPI

+AcquireSpinLockOrFail (

+  IN      SPIN_LOCK                 *SpinLock

+  );

+

+/**

+  Releases a spin lock.

+

+  This function places the spin lock specified by SpinLock in the release state

+  and returns SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to release.

+

+  @return SpinLock

+

+**/

+SPIN_LOCK *

+EFIAPI

+ReleaseSpinLock (

+  IN      SPIN_LOCK                 *SpinLock

+  );

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedIncrement (

+  IN      UINT32                    *Value

+  );

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedDecrement (

+  IN      UINT32                    *Value

+  );

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InterlockedCompareExchange32 (

+  IN      UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  );

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InterlockedCompareExchange64 (

+  IN      UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  );

+

+/**

+  Performs an atomic compare exchange operation on a pointer value.

+

+  Performs an atomic compare exchange operation on the pointer value specified

+  by Value. If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned. If Value is not equal to

+  CompareValue, then Value is returned. The compare exchange operation must be

+  performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the pointer value for the compare exchange

+                        operation.

+  @param  CompareValue  Pointer value used in compare operation.

+  @param  ExchangeValue Pointer value used in exchange operation.

+

+**/

+VOID *

+EFIAPI

+InterlockedCompareExchangePointer (

+  IN      VOID                      **Value,

+  IN      VOID                      *CompareValue,

+  IN      VOID                      *ExchangeValue

+  );

+

+//

+// Base Library CPU Functions

+//

+typedef

+VOID

+(EFIAPI *SWITCH_STACK_ENTRY_POINT) (

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2   OPTIONAL

+  );

+

+/**

+  Used to serialize load and store operations.

+

+  All loads and stores that proceed calls to this function are guaranteed to be

+  globally visible when this function returns.

+

+**/

+VOID

+EFIAPI

+MemoryFence (

+  VOID

+  );

+

+/**

+  Saves the current CPU context that can be restored with a call to LongJump()

+  and returns 0.

+

+  Saves the current CPU context in the buffer specified by JumpBuffer and

+  returns 0. The initial call to SetJump() must always return 0. Subsequent

+  calls to LongJump() cause a non-zero value to be returned by SetJump().

+

+  If JumpBuffer is NULL, then ASSERT().

+

+  @param  JumpBuffer  A pointer to CPU context buffer.

+

+  @retval 0 Indicates a return from SetJump().

+

+**/

+UINTN

+EFIAPI

+SetJump (

+  OUT     BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+  );

+

+/**

+  Restores the CPU context that was saved with SetJump().

+

+  Restores the CPU context from the buffer specified by JumpBuffer. This

+  function never returns to the caller. Instead is resumes execution based on

+  the state of JumpBuffer.

+

+  If JumpBuffer is NULL, then ASSERT().

+  If Value is 0, then ASSERT().

+

+  @param  JumpBuffer  A pointer to CPU context buffer.

+  @param  Value       The value to return when the SetJump() context is

+                      restored and must be non-zero.

+

+**/

+VOID

+EFIAPI

+LongJump (

+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                     Value

+  );

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  );

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  );

+

+/**

+  Disables CPU interrupts and returns the interrupt state prior to the disable

+  operation.

+

+  Disables CPU interrupts and returns the interrupt state prior to the disable

+  operation.

+

+  @retval TRUE  CPU interrupts were enabled on entry to this call.

+  @retval FALSE CPU interrupts were disabled on entry to this call.

+

+**/

+BOOLEAN

+EFIAPI

+SaveAndDisableInterrupts (

+  VOID

+  );

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  );

+

+/**

+  Retrieves the current CPU interrupt state.

+

+  Retrieves the current CPU interrupt state. Returns TRUE is interrupts are

+  currently enabled. Otherwise returns FALSE.

+

+  @retval TRUE  CPU interrupts are enabled.

+  @retval FALSE CPU interrupts are disabled.

+

+**/

+BOOLEAN

+EFIAPI

+GetInterruptState (

+  VOID

+  );

+

+/**

+  Set the current CPU interrupt state.

+

+  Sets the current CPU interrupt state to the state specified by

+  InterruptState. If InterruptState is TRUE, then interrupts are enabled. If

+  InterruptState is FALSE, then interrupts are disabled. InterruptState is

+  returned.

+

+  @param  InterruptState  TRUE if interrupts should enabled. FALSE if

+                          interrupts should be disabled.

+

+  @return InterruptState

+

+**/

+BOOLEAN

+EFIAPI

+SetInterruptState (

+  IN      BOOLEAN                   InterruptState

+  );

+

+/**

+  Places the CPU in a sleep state until an interrupt is received.

+

+  Places the CPU in a sleep state until an interrupt is received. If interrupts

+  are disabled prior to calling this function, then the CPU will be placed in a

+  sleep state indefinitely.

+

+**/

+VOID

+EFIAPI

+CpuSleep (

+  VOID

+  );

+

+/**

+  Requests CPU to pause for a short period of time.

+

+  Requests CPU to pause for a short period of time. Typically used in MP

+  systems to prevent memory starvation while waiting for a spin lock.

+

+**/

+VOID

+EFIAPI

+CpuPause (

+  VOID

+  );

+

+/**

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+**/

+VOID

+EFIAPI

+CpuFlushTlb (

+  VOID

+  );

+

+/**

+  Transfers control to a function starting with a new stack.

+

+  Transfers control to the function specified by EntryPoint using the new stack

+  specified by NewStack and passing in the parameters specified by Context1 and

+  Context2. Context1 and Context2 are optional and may be NULL. The function

+  EntryPoint must never return.

+

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  @param  EntryPoint  A pointer to function to call with the new stack.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function.

+

+**/

+VOID

+EFIAPI

+SwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  );

+

+/**

+  Generates a breakpoint on the CPU.

+

+  Generates a breakpoint on the CPU. The breakpoint must be implemented such

+  that code can resume normal execution after the breakpoint.

+

+**/

+VOID

+EFIAPI

+CpuBreakpoint (

+  VOID

+  );

+

+/**

+  Executes an infinite loop.

+

+  Forces the CPU to execute an infinite loop. A debugger may be used to skip

+  past the loop and the code that follows the loop must execute properly. This

+  implies that the infinite loop must not cause the code that follow it to be

+  optimized away.

+

+**/

+VOID

+EFIAPI

+CpuDeadLoop (

+  VOID

+  );

+

+//

+// IA32 and X64 Specific Functions

+//

+//

+// Byte packed structure for 16-bit Real Mode EFLAGS

+//

+typedef union {

+  struct {

+    UINT32  CF:1;           // Carry Flag

+    UINT32  Reserved_0:1;   // Reserved

+    UINT32  PF:1;           // Parity Flag

+    UINT32  Reserved_1:1;   // Reserved

+    UINT32  AF:1;           // Auxiliary Carry Flag

+    UINT32  Reserved_2:1;   // Reserved

+    UINT32  ZF:1;           // Zero Flag

+    UINT32  SF:1;           // Sign Flag

+    UINT32  TF:1;           // Trap Flag

+    UINT32  IF:1;           // Interrupt Enable Flag

+    UINT32  DF:1;           // Direction Flag

+    UINT32  OF:1;           // Overflow Flag

+    UINT32  IOPL:2;         // I/O Privilege Level

+    UINT32  NT:1;           // Nested Task

+    UINT32  Reserved_3:1;   // Reserved

+  } Bits;

+  UINT16    Uint16;

+} IA32_FLAGS16;

+

+//

+// Byte packed structure for EFLAGS/RFLAGS

+// 32-bits on IA-32

+// 64-bits on X64.  The upper 32-bits on X64 are reserved

+//

+typedef union {

+  struct {

+    UINT32  CF:1;           // Carry Flag

+    UINT32  Reserved_0:1;   // Reserved

+    UINT32  PF:1;           // Parity Flag

+    UINT32  Reserved_1:1;   // Reserved

+    UINT32  AF:1;           // Auxiliary Carry Flag

+    UINT32  Reserved_2:1;   // Reserved

+    UINT32  ZF:1;           // Zero Flag

+    UINT32  SF:1;           // Sign Flag

+    UINT32  TF:1;           // Trap Flag

+    UINT32  IF:1;           // Interrupt Enable Flag

+    UINT32  DF:1;           // Direction Flag

+    UINT32  OF:1;           // Overflow Flag

+    UINT32  IOPL:2;         // I/O Privilege Level

+    UINT32  NT:1;           // Nested Task

+    UINT32  Reserved_3:1;   // Reserved

+    UINT32  RF:1;           // Resume Flag

+    UINT32  VM:1;           // Virtual 8086 Mode

+    UINT32  AC:1;           // Alignment Check

+    UINT32  VIF:1;          // Virtual Interrupt Flag

+    UINT32  VIP:1;          // Virtual Interrupt Pending

+    UINT32  ID:1;           // ID Flag

+    UINT32  Reserved_4:10;  // Reserved

+  } Bits;

+  UINTN     UintN;

+} IA32_EFLAGS32;

+

+//

+// Byte packed structure for Control Register 0 (CR0)

+// 32-bits on IA-32

+// 64-bits on X64.  The upper 32-bits on X64 are reserved

+//

+typedef union {

+  struct {

+    UINT32  PE:1;           // Protection Enable

+    UINT32  MP:1;           // Monitor Coprocessor

+    UINT32  EM:1;           // Emulation

+    UINT32  TS:1;           // Task Switched

+    UINT32  ET:1;           // Extension Type

+    UINT32  NE:1;           // Numeric Error

+    UINT32  Reserved_0:10;  // Reserved

+    UINT32  WP:1;           // Write Protect

+    UINT32  Reserved_1:1;   // Reserved

+    UINT32  AM:1;           // Alignment Mask

+    UINT32  Reserved_2:10;  // Reserved

+    UINT32  NW:1;           // Mot Write-through

+    UINT32  CD:1;           // Cache Disable

+    UINT32  PG:1;           // Paging

+  } Bits;

+  UINTN     UintN;

+} IA32_CR0;

+

+//

+// Byte packed structure for Control Register 4 (CR4)

+// 32-bits on IA-32

+// 64-bits on X64.  The upper 32-bits on X64 are reserved

+//

+typedef union {

+  struct {

+    UINT32  VME:1;          // Virtual-8086 Mode Extensions

+    UINT32  PVI:1;          // Protected-Mode Virtual Interrupts

+    UINT32  TSD:1;          // Time Stamp Disable

+    UINT32  DE:1;           // Debugging Extensions

+    UINT32  PSE:1;          // Page Size Extensions

+    UINT32  PAE:1;          // Physical Address Extension

+    UINT32  MCE:1;          // Machine Check Enable

+    UINT32  PGE:1;          // Page Global Enable

+    UINT32  PCE:1;          // Performance Monitoring Counter

+                            // Enable

+    UINT32  OSFXSR:1;       // Operating System Support for

+                            // FXSAVE and FXRSTOR instructions

+    UINT32  OSXMMEXCPT:1;   // Operating System Support for

+                            // Unmasked SIMD Floating Point

+                            // Exceptions

+    UINT32  Reserved_0:2;   // Reserved

+    UINT32  VMXE:1;         // VMX Enable

+    UINT32  Reserved_1:18;  // Reseved

+  } Bits;

+  UINTN     UintN;

+} IA32_CR4;

+

+//

+// Byte packed structure for an IDTR, GDTR, LDTR descriptor

+//

+typedef struct {

+  UINT16  Limit;

+  UINTN   Base;

+} IA32_DESCRIPTOR;

+

+#define IA32_IDT_GATE_TYPE_TASK          0x85

+#define IA32_IDT_GATE_TYPE_INTERRUPT_16  0x86

+#define IA32_IDT_GATE_TYPE_TRAP_16       0x87

+#define IA32_IDT_GATE_TYPE_INTERRUPT_32  0x8E

+#define IA32_IDT_GATE_TYPE_TRAP_32       0x8F

+

+//

+// Byte packed structure for an Interrupt Gate Descriptor

+//

+typedef union {

+  struct {

+    UINT32  OffsetLow:16;   // Offset bits 15..0

+    UINT32  Selector:16;    // Selector

+    UINT32  Reserved_0:8;   // Reserved

+    UINT32  GateType:8;     // Gate Type.  See #defines above

+    UINT32  OffsetHigh:16;  // Offset bits 31..16

+  } Bits;

+  UINT64  Uint64;

+} IA32_IDT_GATE_DESCRIPTOR;

+

+//

+// Byte packed structure for an FP/SSE/SSE2 context

+//

+typedef struct {

+  UINT8  Buffer[512];

+} IA32_FX_BUFFER;

+

+//

+// Structures for the 16-bit real mode thunks

+//

+typedef struct {

+  UINT32                            Reserved1;

+  UINT32                            Reserved2;

+  UINT32                            Reserved3;

+  UINT32                            Reserved4;

+  UINT8                             BL;

+  UINT8                             BH;

+  UINT16                            Reserved5;

+  UINT8                             DL;

+  UINT8                             DH;

+  UINT16                            Reserved6;

+  UINT8                             CL;

+  UINT8                             CH;

+  UINT16                            Reserved7;

+  UINT8                             AL;

+  UINT8                             AH;

+  UINT16                            Reserved8;

+} IA32_BYTE_REGS;

+

+typedef struct {

+  UINT16                            DI;

+  UINT16                            Reserved1;

+  UINT16                            SI;

+  UINT16                            Reserved2;

+  UINT16                            BP;

+  UINT16                            Reserved3;

+  UINT16                            SP;

+  UINT16                            Reserved4;

+  UINT16                            BX;

+  UINT16                            Reserved5;

+  UINT16                            DX;

+  UINT16                            Reserved6;

+  UINT16                            CX;

+  UINT16                            Reserved7;

+  UINT16                            AX;

+  UINT16                            Reserved8;

+} IA32_WORD_REGS;

+

+typedef struct {

+  UINT32                            EDI;

+  UINT32                            ESI;

+  UINT32                            EBP;

+  UINT32                            ESP;

+  UINT32                            EBX;

+  UINT32                            EDX;

+  UINT32                            ECX;

+  UINT32                            EAX;

+  UINT16                            DS;

+  UINT16                            ES;

+  UINT16                            FS;

+  UINT16                            GS;

+  IA32_EFLAGS32                     EFLAGS;

+  UINT32                            Eip;

+  UINT16                            CS;

+  UINT16                            SS;

+} IA32_DWORD_REGS;

+

+typedef union {

+  IA32_DWORD_REGS                   E;

+  IA32_WORD_REGS                    X;

+  IA32_BYTE_REGS                    H;

+} IA32_REGISTER_SET;

+

+//

+// Byte packed structure for an 16-bit real mode thunks

+//

+typedef struct {

+  IA32_REGISTER_SET                 *RealModeState;

+  VOID                              *RealModeBuffer;

+  UINT32                            RealModeBufferSize;

+  UINT32                            ThunkAttributes;

+} THUNK_CONTEXT;

+

+#define THUNK_ATTRIBUTE_BIG_REAL_MODE             0x00000001

+#define THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15   0x00000002

+#define THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL 0x00000004

+

+/**

+  Retrieves CPUID information.

+

+  Executes the CPUID instruction with EAX set to the value specified by Index.

+  This function always returns Index.

+  If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.

+  If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.

+  If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.

+  If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.

+  This function is only available on IA-32 and X64.

+

+  @param  Index The 32-bit value to load into EAX prior to invoking the CPUID

+                instruction.

+  @param  Eax   Pointer to the 32-bit EAX value returned by the CPUID

+                instruction. This is an optional parameter that may be NULL.

+  @param  Ebx   Pointer to the 32-bit EBX value returned by the CPUID

+                instruction. This is an optional parameter that may be NULL.

+  @param  Ecx   Pointer to the 32-bit ECX value returned by the CPUID

+                instruction. This is an optional parameter that may be NULL.

+  @param  Edx   Pointer to the 32-bit EDX value returned by the CPUID

+                instruction. This is an optional parameter that may be NULL.

+

+  @return Index

+

+**/

+UINT32

+EFIAPI

+AsmCpuid (

+  IN      UINT32                    Index,

+  OUT     UINT32                    *Eax,  OPTIONAL

+  OUT     UINT32                    *Ebx,  OPTIONAL

+  OUT     UINT32                    *Ecx,  OPTIONAL

+  OUT     UINT32                    *Edx   OPTIONAL

+  );

+

+/**

+  Returns the lower 32-bits of a Machine Specific Register(MSR).

+

+  Reads and returns the lower 32-bits of the MSR specified by Index.

+  No parameter checking is performed on Index, and some Index values may cause

+  CPU exceptions. The caller must either guarantee that Index is valid, or the

+  caller must set up exception handlers to catch the exceptions. This function

+  is only available on IA-32 and X64.

+

+  @param  Index The 32-bit MSR index to read.

+

+  @return The lower 32 bits of the MSR identified by Index.

+

+**/

+UINT32

+EFIAPI

+AsmReadMsr32 (

+  IN      UINT32                    Index

+  );

+

+/**

+  Zero-extend a 32-bit value and writes it to a Machine Specific Register(MSR).

+

+  Writes the 32-bit value specified by Value to the MSR specified by Index. The

+  upper 32-bits of the MSR write are set to zero. The 32-bit value written to

+  the MSR is returned. No parameter checking is performed on Index or Value,

+  and some of these may cause CPU exceptions. The caller must either guarantee

+  that Index and Value are valid, or the caller must establish proper exception

+  handlers. This function is only available on IA-32 and X64.

+

+  @param  Index The 32-bit MSR index to write.

+  @param  Value The 32-bit value to write to the MSR.

+

+  @return Value

+

+**/

+UINT32

+EFIAPI

+AsmWriteMsr32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a 64-bit MSR, performs a bitwise inclusive OR on the lower 32-bits, and

+  writes the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the lower 32-bits of the read result and the value specified by

+  OrData, and writes the result to the 64-bit MSR specified by Index. The lower

+  32-bits of the value written to the MSR is returned. No parameter checking is

+  performed on Index or OrData, and some of these may cause CPU exceptions. The

+  caller must either guarantee that Index and OrData are valid, or the caller

+  must establish proper exception handlers. This function is only available on

+  IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  OrData  The value to OR with the read value from the MSR.

+

+  @return The lower 32-bit value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrOr32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND on the lower 32-bits, and writes

+  the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  lower 32-bits of the read result and the value specified by AndData, and

+  writes the result to the 64-bit MSR specified by Index. The lower 32-bits of

+  the value written to the MSR is returned. No parameter checking is performed

+  on Index or AndData, and some of these may cause CPU exceptions. The caller

+  must either guarantee that Index and AndData are valid, or the caller must

+  establish proper exception handlers. This function is only available on IA-32

+  and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+

+  @return The lower 32-bit value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrAnd32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise inclusive OR

+  on the lower 32-bits, and writes the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  lower 32-bits of the read result and the value specified by AndData

+  preserving the upper 32-bits, performs a bitwise inclusive OR between the

+  result of the AND operation and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Address. The lower 32-bits of the value

+  written to the MSR is returned. No parameter checking is performed on Index,

+  AndData, or OrData, and some of these may cause CPU exceptions. The caller

+  must either guarantee that Index, AndData, and OrData are valid, or the

+  caller must establish proper exception handlers. This function is only

+  available on IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The lower 32-bit value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrAndThenOr32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field of an MSR.

+

+  Reads the bit field in the lower 32-bits of a 64-bit MSR. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned. The caller must either guarantee that Index is valid, or the caller

+  must set up exception handlers to catch the exceptions. This function is only

+  available on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The bit field read from the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldRead32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an MSR.

+

+  Writes Value to a bit field in the lower 32-bits of a  64-bit MSR. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination MSR are preserved. The lower 32-bits of the MSR written is

+  returned. Extra left bits in Value are stripped. The caller must either

+  guarantee that Index and the data written is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldWrite32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Index. The lower 32-bits of the value

+  written to the MSR are returned. Extra left bits in OrData are stripped. The

+  caller must either guarantee that Index and the data written is valid, or

+  the caller must set up exception handlers to catch the exceptions. This

+  function is only available on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the MSR.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldOr32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  read result and the value specified by AndData, and writes the result to the

+  64-bit MSR specified by Index. The lower 32-bits of the value written to the

+  MSR are returned. Extra left bits in AndData are stripped. The caller must

+  either guarantee that Index and the data written is valid, or the caller must

+  set up exception handlers to catch the exceptions. This function is only

+  available on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the MSR.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldAnd32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by a

+  bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit MSR specified by Index. The

+  lower 32-bits of the value written to the MSR are returned. Extra left bits

+  in both AndData and OrData are stripped. The caller must either guarantee

+  that Index and the data written is valid, or the caller must set up exception

+  handlers to catch the exceptions. This function is only available on IA-32

+  and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the MSR.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldAndThenOr32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Returns a 64-bit Machine Specific Register(MSR).

+

+  Reads and returns the 64-bit MSR specified by Index. No parameter checking is

+  performed on Index, and some Index values may cause CPU exceptions. The

+  caller must either guarantee that Index is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  @param  Index The 32-bit MSR index to read.

+

+  @return The value of the MSR identified by Index.

+

+**/

+UINT64

+EFIAPI

+AsmReadMsr64 (

+  IN      UINT32                    Index

+  );

+

+/**

+  Writes a 64-bit value to a Machine Specific Register(MSR), and returns the

+  value.

+

+  Writes the 64-bit value specified by Value to the MSR specified by Index. The

+  64-bit value written to the MSR is returned. No parameter checking is

+  performed on Index or Value, and some of these may cause CPU exceptions. The

+  caller must either guarantee that Index and Value are valid, or the caller

+  must establish proper exception handlers. This function is only available on

+  IA-32 and X64.

+

+  @param  Index The 32-bit MSR index to write.

+  @param  Value The 64-bit value to write to the MSR.

+

+  @return Value

+

+**/

+UINT64

+EFIAPI

+AsmWriteMsr64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a 64-bit MSR, performs a bitwise inclusive OR, and writes the result

+  back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Index. The value written to the MSR is

+  returned. No parameter checking is performed on Index or OrData, and some of

+  these may cause CPU exceptions. The caller must either guarantee that Index

+  and OrData are valid, or the caller must establish proper exception handlers.

+  This function is only available on IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  OrData  The value to OR with the read value from the MSR.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrOr64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND, and writes the result back to the

+  64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  read result and the value specified by OrData, and writes the result to the

+  64-bit MSR specified by Index. The value written to the MSR is returned. No

+  parameter checking is performed on Index or OrData, and some of these may

+  cause CPU exceptions. The caller must either guarantee that Index and OrData

+  are valid, or the caller must establish proper exception handlers. This

+  function is only available on IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrAnd64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise inclusive

+  OR, and writes the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between read

+  result and the value specified by AndData, performs a bitwise inclusive OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 64-bit MSR specified by Index. The value written

+  to the MSR is returned. No parameter checking is performed on Index, AndData,

+  or OrData, and some of these may cause CPU exceptions. The caller must either

+  guarantee that Index, AndData, and OrData are valid, or the caller must

+  establish proper exception handlers. This function is only available on IA-32

+  and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrAndThenOr64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field of an MSR.

+

+  Reads the bit field in the 64-bit MSR. The bit field is specified by the

+  StartBit and the EndBit. The value of the bit field is returned. The caller

+  must either guarantee that Index is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read from the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldRead64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an MSR.

+

+  Writes Value to a bit field in a 64-bit MSR. The bit field is specified by

+  the StartBit and the EndBit. All other bits in the destination MSR are

+  preserved. The MSR written is returned. Extra left bits in Value are

+  stripped. The caller must either guarantee that Index and the data written is

+  valid, or the caller must set up exception handlers to catch the exceptions.

+  This function is only available on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldWrite64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise inclusive OR, and

+  writes the result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Index. The value written to the MSR is

+  returned. Extra left bits in OrData are stripped. The caller must either

+  guarantee that Index and the data written is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the bit field.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldOr64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  read result and the value specified by AndData, and writes the result to the

+  64-bit MSR specified by Index. The value written to the MSR is returned.

+  Extra left bits in AndData are stripped. The caller must either guarantee

+  that Index and the data written is valid, or the caller must set up exception

+  handlers to catch the exceptions. This function is only available on IA-32

+  and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the bit field.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldAnd64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by

+  a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit MSR specified by Index. The

+  value written to the MSR is returned. Extra left bits in both AndData and

+  OrData are stripped. The caller must either guarantee that Index and the data

+  written is valid, or the caller must set up exception handlers to catch the

+  exceptions. This function is only available on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the bit field.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldAndThenOr64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads the current value of the EFLAGS register.

+

+  Reads and returns the current value of the EFLAGS register. This function is

+  only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a

+  64-bit value on X64.

+

+  @return EFLAGS on IA-32 or RFLAGS on X64.

+

+**/

+UINTN

+EFIAPI

+AsmReadEflags (

+  VOID

+  );

+

+/**

+  Reads the current value of the Control Register 0 (CR0).

+

+  Reads and returns the current value of CR0. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of the Control Register 0 (CR0).

+

+**/

+UINTN

+EFIAPI

+AsmReadCr0 (

+  VOID

+  );

+

+/**

+  Reads the current value of the Control Register 2 (CR2).

+

+  Reads and returns the current value of CR2. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of the Control Register 2 (CR2).

+

+**/

+UINTN

+EFIAPI

+AsmReadCr2 (

+  VOID

+  );

+

+/**

+  Reads the current value of the Control Register 3 (CR3).

+

+  Reads and returns the current value of CR3. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of the Control Register 3 (CR3).

+

+**/

+UINTN

+EFIAPI

+AsmReadCr3 (

+  VOID

+  );

+

+/**

+  Reads the current value of the Control Register 4 (CR4).

+

+  Reads and returns the current value of CR4. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of the Control Register 4 (CR4).

+

+**/

+UINTN

+EFIAPI

+AsmReadCr4 (

+  VOID

+  );

+

+/**

+  Writes a value to Control Register 0 (CR0).

+

+  Writes and returns a new value to CR0. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Cr0 The value to write to CR0.

+

+  @return The value written to CR0.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr0 (

+  UINTN  Cr0

+  );

+

+/**

+  Writes a value to Control Register 2 (CR2).

+

+  Writes and returns a new value to CR2. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Cr2 The value to write to CR2.

+

+  @return The value written to CR2.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr2 (

+  UINTN  Cr2

+  );

+

+/**

+  Writes a value to Control Register 3 (CR3).

+

+  Writes and returns a new value to CR3. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Cr3 The value to write to CR3.

+

+  @return The value written to CR3.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr3 (

+  UINTN  Cr3

+  );

+

+/**

+  Writes a value to Control Register 4 (CR4).

+

+  Writes and returns a new value to CR4. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Cr4 The value to write to CR4.

+

+  @return The value written to CR4.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr4 (

+  UINTN  Cr4

+  );

+

+/**

+  Reads the current value of Debug Register 0 (DR0).

+

+  Reads and returns the current value of DR0. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 0 (DR0).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr0 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 1 (DR1).

+

+  Reads and returns the current value of DR1. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 1 (DR1).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr1 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 2 (DR2).

+

+  Reads and returns the current value of DR2. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 2 (DR2).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr2 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 3 (DR3).

+

+  Reads and returns the current value of DR3. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 3 (DR3).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr3 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 4 (DR4).

+

+  Reads and returns the current value of DR4. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 4 (DR4).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr4 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 5 (DR5).

+

+  Reads and returns the current value of DR5. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 5 (DR5).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr5 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 6 (DR6).

+

+  Reads and returns the current value of DR6. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 6 (DR6).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr6 (

+  VOID

+  );

+

+/**

+  Reads the current value of Debug Register 7 (DR7).

+

+  Reads and returns the current value of DR7. This function is only available

+  on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on

+  X64.

+

+  @return The value of Debug Register 7 (DR7).

+

+**/

+UINTN

+EFIAPI

+AsmReadDr7 (

+  VOID

+  );

+

+/**

+  Writes a value to Debug Register 0 (DR0).

+

+  Writes and returns a new value to DR0. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr0 The value to write to Dr0.

+

+  @return The value written to Debug Register 0 (DR0).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr0 (

+  UINTN  Dr0

+  );

+

+/**

+  Writes a value to Debug Register 1 (DR1).

+

+  Writes and returns a new value to DR1. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr1 The value to write to Dr1.

+

+  @return The value written to Debug Register 1 (DR1).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr1 (

+  UINTN  Dr1

+  );

+

+/**

+  Writes a value to Debug Register 2 (DR2).

+

+  Writes and returns a new value to DR2. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr2 The value to write to Dr2.

+

+  @return The value written to Debug Register 2 (DR2).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr2 (

+  UINTN  Dr2

+  );

+

+/**

+  Writes a value to Debug Register 3 (DR3).

+

+  Writes and returns a new value to DR3. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr3 The value to write to Dr3.

+

+  @return The value written to Debug Register 3 (DR3).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr3 (

+  UINTN  Dr3

+  );

+

+/**

+  Writes a value to Debug Register 4 (DR4).

+

+  Writes and returns a new value to DR4. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr4 The value to write to Dr4.

+

+  @return The value written to Debug Register 4 (DR4).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr4 (

+  UINTN  Dr4

+  );

+

+/**

+  Writes a value to Debug Register 5 (DR5).

+

+  Writes and returns a new value to DR5. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr5 The value to write to Dr5.

+

+  @return The value written to Debug Register 5 (DR5).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr5 (

+  UINTN  Dr5

+  );

+

+/**

+  Writes a value to Debug Register 6 (DR6).

+

+  Writes and returns a new value to DR6. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr6 The value to write to Dr6.

+

+  @return The value written to Debug Register 6 (DR6).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr6 (

+  UINTN  Dr6

+  );

+

+/**

+  Writes a value to Debug Register 7 (DR7).

+

+  Writes and returns a new value to DR7. This function is only available on

+  IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.

+

+  @param  Dr7 The value to write to Dr7.

+

+  @return The value written to Debug Register 7 (DR7).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr7 (

+  UINTN  Dr7

+  );

+

+/**

+  Reads the current value of Code Segment Register (CS).

+

+  Reads and returns the current value of CS. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of CS.

+

+**/

+UINT16

+EFIAPI

+AsmReadCs (

+  VOID

+  );

+

+/**

+  Reads the current value of Data Segment Register (DS).

+

+  Reads and returns the current value of DS. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of DS.

+

+**/

+UINT16

+EFIAPI

+AsmReadDs (

+  VOID

+  );

+

+/**

+  Reads the current value of Extra Segment Register (ES).

+

+  Reads and returns the current value of ES. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of ES.

+

+**/

+UINT16

+EFIAPI

+AsmReadEs (

+  VOID

+  );

+

+/**

+  Reads the current value of FS Data Segment Register (FS).

+

+  Reads and returns the current value of FS. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of FS.

+

+**/

+UINT16

+EFIAPI

+AsmReadFs (

+  VOID

+  );

+

+/**

+  Reads the current value of GS Data Segment Register (GS).

+

+  Reads and returns the current value of GS. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of GS.

+

+**/

+UINT16

+EFIAPI

+AsmReadGs (

+  VOID

+  );

+

+/**

+  Reads the current value of Stack Segment Register (SS).

+

+  Reads and returns the current value of SS. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of SS.

+

+**/

+UINT16

+EFIAPI

+AsmReadSs (

+  VOID

+  );

+

+/**

+  Reads the current value of Task Register (TR).

+

+  Reads and returns the current value of TR. This function is only available on

+  IA-32 and X64.

+

+  @return The current value of TR.

+

+**/

+UINT16

+EFIAPI

+AsmReadTr (

+  VOID

+  );

+

+/**

+  Reads the current Global Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current GDTR descriptor and returns it in Gdtr. This

+  function is only available on IA-32 and X64.

+

+  If Gdtr is NULL, then ASSERT().

+

+  @param  Gdtr  Pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmReadGdtr (

+  OUT     IA32_DESCRIPTOR           *Gdtr

+  );

+

+/**

+  Writes the current Global Descriptor Table Register (GDTR) descriptor.

+

+  Writes and the current GDTR descriptor specified by Gdtr. This function is

+  only available on IA-32 and X64.

+

+  If Gdtr is NULL, then ASSERT().

+

+  @param  Gdtr  Pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmWriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  );

+

+/**

+  Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current IDTR descriptor and returns it in Idtr. This

+  function is only available on IA-32 and X64.

+

+  If Idtr is NULL, then ASSERT().

+

+  @param  Idtr  Pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  );

+

+/**

+  Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Writes the current IDTR descriptor and returns it in Idtr. This function is

+  only available on IA-32 and X64.

+

+  If Idtr is NULL, then ASSERT().

+

+  @param  Idtr  Pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmWriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  );

+

+/**

+  Reads the current Local Descriptor Table Register(LDTR) selector.

+

+  Reads and returns the current 16-bit LDTR descriptor value. This function is

+  only available on IA-32 and X64.

+

+  @return The current selector of LDT.

+

+**/

+UINT16

+EFIAPI

+AsmReadLdtr (

+  VOID

+  );

+

+/**

+  Writes the current Local Descriptor Table Register (GDTR) selector.

+

+  Writes and the current LDTR descriptor specified by Ldtr. This function is

+  only available on IA-32 and X64.

+

+  @param  Ldtr  16-bit LDTR selector value.

+

+**/

+VOID

+EFIAPI

+AsmWriteLdtr (

+  IN      UINT16                    Ldtr

+  );

+

+/**

+  Save the current floating point/SSE/SSE2 context to a buffer.

+

+  Saves the current floating point/SSE/SSE2 state to the buffer specified by

+  Buffer. Buffer must be aligned on a 16-byte boundary. This function is only

+  available on IA-32 and X64.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  Buffer  Pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+AsmFxSave (

+  OUT     IA32_FX_BUFFER            *Buffer

+  );

+

+/**

+  Restores the current floating point/SSE/SSE2 context from a buffer.

+

+  Restores the current floating point/SSE/SSE2 state from the buffer specified

+  by Buffer. Buffer must be aligned on a 16-byte boundary. This function is

+  only available on IA-32 and X64.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-byte boundary, then ASSERT().

+  If Buffer was not saved with AsmFxSave(), then ASSERT().

+

+  @param  Buffer  Pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+AsmFxRestore (

+  IN      CONST IA32_FX_BUFFER      *Buffer

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #0 (MM0).

+

+  Reads and returns the current value of MM0. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM0.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm0 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #1 (MM1).

+

+  Reads and returns the current value of MM1. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM1.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm1 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #2 (MM2).

+

+  Reads and returns the current value of MM2. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM2.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm2 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #3 (MM3).

+

+  Reads and returns the current value of MM3. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM3.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm3 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #4 (MM4).

+

+  Reads and returns the current value of MM4. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM4.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm4 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #5 (MM5).

+

+  Reads and returns the current value of MM5. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM5.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm5 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #6 (MM6).

+

+  Reads and returns the current value of MM6. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM6.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm6 (

+  VOID

+  );

+

+/**

+  Reads the current value of 64-bit MMX Register #7 (MM7).

+

+  Reads and returns the current value of MM7. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of MM7.

+

+**/

+UINT64

+EFIAPI

+AsmReadMm7 (

+  VOID

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #0 (MM0).

+

+  Writes the current value of MM0. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM0.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm0 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #1 (MM1).

+

+  Writes the current value of MM1. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM1.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm1 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #2 (MM2).

+

+  Writes the current value of MM2. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM2.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm2 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #3 (MM3).

+

+  Writes the current value of MM3. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM3.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm3 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #4 (MM4).

+

+  Writes the current value of MM4. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM4.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm4 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #5 (MM5).

+

+  Writes the current value of MM5. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM5.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm5 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #6 (MM6).

+

+  Writes the current value of MM6. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM6.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm6 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Writes the current value of 64-bit MMX Register #7 (MM7).

+

+  Writes the current value of MM7. This function is only available on IA32 and

+  X64.

+

+  @param  Value The 64-bit value to write to MM7.

+

+**/

+VOID

+EFIAPI

+AsmWriteMm7 (

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads the current value of Time Stamp Counter (TSC).

+

+  Reads and returns the current value of TSC. This function is only available

+  on IA-32 and X64.

+

+  @return The current value of TSC

+

+**/

+UINT64

+EFIAPI

+AsmReadTsc (

+  VOID

+  );

+

+/**

+  Reads the current value of a Performance Counter (PMC).

+

+  Reads and returns the current value of performance counter specified by

+  Index. This function is only available on IA-32 and X64.

+

+  @param  Index The 32-bit Performance Counter index to read.

+

+  @return The value of the PMC specified by Index.

+

+**/

+UINT64

+EFIAPI

+AsmReadPmc (

+  IN      UINT32                    Index

+  );

+

+/**

+  Sets up a monitor buffer that is used by AsmMwait().

+

+  Executes a MONITOR instruction with the register state specified by Eax, Ecx

+  and Edx. Returns Eax. This function is only available on IA-32 and X64.

+

+  @param  Eax The value to load into EAX or RAX before executing the MONITOR

+              instruction.

+  @param  Ecx The value to load into ECX or RCX before executing the MONITOR

+              instruction.

+  @param  Edx The value to load into EDX or RDX before executing the MONITOR

+              instruction.

+

+  @return Eax

+

+**/

+UINTN

+EFIAPI

+AsmMonitor (

+  IN      UINTN                     Eax,

+  IN      UINTN                     Ecx,

+  IN      UINTN                     Edx

+  );

+

+/**

+  Executes an MWAIT instruction.

+

+  Executes an MWAIT instruction with the register state specified by Eax and

+  Ecx. Returns Eax. This function is only available on IA-32 and X64.

+

+  @param  Eax The value to load into EAX or RAX before executing the MONITOR

+              instruction.

+  @param  Ecx The value to load into ECX or RCX before executing the MONITOR

+              instruction.

+

+  @return Eax

+

+**/

+UINTN

+EFIAPI

+AsmMwait (

+  IN      UINTN                     Eax,

+  IN      UINTN                     Ecx

+  );

+

+/**

+  Executes a WBINVD instruction.

+

+  Executes a WBINVD instruction. This function is only available on IA-32 and

+  X64.

+

+**/

+VOID

+EFIAPI

+AsmWbinvd (

+  VOID

+  );

+

+/**

+  Executes a INVD instruction.

+

+  Executes a INVD instruction. This function is only available on IA-32 and

+  X64.

+

+**/

+VOID

+EFIAPI

+AsmInvd (

+  VOID

+  );

+

+/**

+  Flushes a cache line from all the instruction and data caches within the

+  coherency domain of the CPU.

+

+  Flushed the cache line specified by LinearAddress, and returns LinearAddress.

+  This function is only available on IA-32 and X64.

+

+  @param  LinearAddress The address of the cache line to flush. If the CPU is

+                        in a physical addressing mode, then LinearAddress is a

+                        physical address. If the CPU is in a virtual

+                        addressing mode, then LinearAddress is a virtual

+                        address.

+

+  @return LinearAddress

+**/

+VOID *

+EFIAPI

+AsmFlushCacheLine (

+  IN      VOID                      *LinearAddress

+  );

+

+/**

+  Enables the 32-bit paging mode on the CPU.

+

+  Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables

+  must be properly initialized prior to calling this service. This function

+  assumes the current execution mode is 32-bit protected mode. This function is

+  only available on IA-32. After the 32-bit paging mode is enabled, control is

+  transferred to the function specified by EntryPoint using the new stack

+  specified by NewStack and passing in the parameters specified by Context1 and

+  Context2. Context1 and Context2 are optional and may be NULL. The function

+  EntryPoint must never return.

+

+  If the current execution mode is not 32-bit protected mode, then ASSERT().

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  There are a number of constraints that must be followed before calling this

+  function:

+  1)  Interrupts must be disabled.

+  2)  The caller must be in 32-bit protected mode with flat descriptors. This

+      means all descriptors must have a base of 0 and a limit of 4GB.

+  3)  CR0 and CR4 must be compatible with 32-bit protected mode with flat

+      descriptors.

+  4)  CR3 must point to valid page tables that will be used once the transition

+      is complete, and those page tables must guarantee that the pages for this

+      function and the stack are identity mapped.

+

+  @param  EntryPoint  A pointer to function to call with the new stack after

+                      paging is enabled.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function as the first parameter after paging is enabled.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function as the second parameter after paging is enabled.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function after paging is enabled.

+

+**/

+VOID

+EFIAPI

+AsmEnablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  );

+

+/**

+  Disables the 32-bit paging mode on the CPU.

+

+  Disables the 32-bit paging mode on the CPU and returns to 32-bit protected

+  mode. This function assumes the current execution mode is 32-paged protected

+  mode. This function is only available on IA-32. After the 32-bit paging mode

+  is disabled, control is transferred to the function specified by EntryPoint

+  using the new stack specified by NewStack and passing in the parameters

+  specified by Context1 and Context2. Context1 and Context2 are optional and

+  may be NULL. The function EntryPoint must never return.

+

+  If the current execution mode is not 32-bit paged mode, then ASSERT().

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  There are a number of constraints that must be followed before calling this

+  function:

+  1)  Interrupts must be disabled.

+  2)  The caller must be in 32-bit paged mode.

+  3)  CR0, CR3, and CR4 must be compatible with 32-bit paged mode.

+  4)  CR3 must point to valid page tables that guarantee that the pages for

+      this function and the stack are identity mapped.

+

+  @param  EntryPoint  A pointer to function to call with the new stack after

+                      paging is disabled.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function as the first parameter after paging is disabled.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function as the second parameter after paging is

+                      disabled.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function after paging is disabled.

+

+**/

+VOID

+EFIAPI

+AsmDisablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  );

+

+/**

+  Enables the 64-bit paging mode on the CPU.

+

+  Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables

+  must be properly initialized prior to calling this service. This function

+  assumes the current execution mode is 32-bit protected mode with flat

+  descriptors. This function is only available on IA-32. After the 64-bit

+  paging mode is enabled, control is transferred to the function specified by

+  EntryPoint using the new stack specified by NewStack and passing in the

+  parameters specified by Context1 and Context2. Context1 and Context2 are

+  optional and may be 0. The function EntryPoint must never return.

+

+  If the current execution mode is not 32-bit protected mode with flat

+  descriptors, then ASSERT().

+  If EntryPoint is 0, then ASSERT().

+  If NewStack is 0, then ASSERT().

+

+  @param  Cs          The 16-bit selector to load in the CS before EntryPoint

+                      is called. The descriptor in the GDT that this selector

+                      references must be setup for long mode.

+  @param  EntryPoint  The 64-bit virtual address of the function to call with

+                      the new stack after paging is enabled.

+  @param  Context1    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the first parameter after

+                      paging is enabled.

+  @param  Context2    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the second parameter after

+                      paging is enabled.

+  @param  NewStack    The 64-bit virtual address of the new stack to use for

+                      the EntryPoint function after paging is enabled.

+

+**/

+VOID

+EFIAPI

+AsmEnablePaging64 (

+  IN      UINT16                    CodeSelector,

+  IN      UINT64                    EntryPoint,

+  IN      UINT64                    Context1,  OPTIONAL

+  IN      UINT64                    Context2,  OPTIONAL

+  IN      UINT64                    NewStack

+  );

+

+/**

+  Disables the 64-bit paging mode on the CPU.

+

+  Disables the 64-bit paging mode on the CPU and returns to 32-bit protected

+  mode. This function assumes the current execution mode is 64-paging mode.

+  This function is only available on X64. After the 64-bit paging mode is

+  disabled, control is transferred to the function specified by EntryPoint

+  using the new stack specified by NewStack and passing in the parameters

+  specified by Context1 and Context2. Context1 and Context2 are optional and

+  may be 0. The function EntryPoint must never return.

+

+  If the current execution mode is not 64-bit paged mode, then ASSERT().

+  If EntryPoint is 0, then ASSERT().

+  If NewStack is 0, then ASSERT().

+

+  @param  Cs          The 16-bit selector to load in the CS before EntryPoint

+                      is called. The descriptor in the GDT that this selector

+                      references must be setup for 32-bit protected mode.

+  @param  EntryPoint  The 64-bit virtual address of the function to call with

+                      the new stack after paging is disabled.

+  @param  Context1    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the first parameter after

+                      paging is disabled.

+  @param  Context2    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the second parameter after

+                      paging is disabled.

+  @param  NewStack    The 64-bit virtual address of the new stack to use for

+                      the EntryPoint function after paging is disabled.

+

+**/

+VOID

+EFIAPI

+AsmDisablePaging64 (

+  IN      UINT16                    CodeSelector,

+  IN      UINT32                    EntryPoint,

+  IN      UINT32                    Context1,  OPTIONAL

+  IN      UINT32                    Context2,  OPTIONAL

+  IN      UINT32                    NewStack

+  );

+

+//

+// 16-bit thunking services

+//

+

+/**

+  Retrieves the properties for 16-bit thunk functions.

+

+  Computes the size of the buffer and stack below 1MB required to use the

+  AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This

+  buffer size is returned in RealModeBufferSize, and the stack size is returned

+  in ExtraStackSize. If parameters are passed to the 16-bit real mode code,

+  then the actual minimum stack size is ExtraStackSize plus the maximum number

+  of bytes that need to be passed to the 16-bit real mode code.

+

+  If RealModeBufferSize is NULL, then ASSERT().

+  If ExtraStackSize is NULL, then ASSERT().

+

+  @param  RealModeBufferSize  A pointer to the size of the buffer below 1MB

+                              required to use the 16-bit thunk functions.

+  @param  ExtraStackSize      A pointer to the extra size of stack below 1MB

+                              that the 16-bit thunk functions require for

+                              temporary storage in the transition to and from

+                              16-bit real mode.

+

+**/

+VOID

+EFIAPI

+AsmGetThunk16Properties (

+  OUT     UINT32                    *RealModeBufferSize,

+  OUT     UINT32                    *ExtraStackSize

+  );

+

+/**

+  Prepares all structures a code required to use AsmThunk16().

+

+  Prepares all structures and code required to use AsmThunk16().

+

+  If ThunkContext is NULL, then ASSERT().

+

+  @param  ThunkContext  A pointer to the context structure that describes the

+                        16-bit real mode code to call.

+

+**/

+VOID

+EFIAPI

+AsmPrepareThunk16 (

+  OUT     THUNK_CONTEXT             *ThunkContext

+  );

+

+/**

+  Transfers control to a 16-bit real mode entry point and returns the results.

+

+  Transfers control to a 16-bit real mode entry point and returns the results.

+  AsmPrepareThunk16() must be called with ThunkContext before this function is

+  used.

+

+  If ThunkContext is NULL, then ASSERT().

+  If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().

+

+  @param  ThunkContext  A pointer to the context structure that describes the

+                        16-bit real mode code to call.

+

+**/

+VOID

+EFIAPI

+AsmThunk16 (

+  IN OUT  THUNK_CONTEXT             *ThunkContext

+  );

+

+/**

+  Prepares all structures and code for a 16-bit real mode thunk, transfers

+  control to a 16-bit real mode entry point, and returns the results.

+

+  Prepares all structures and code for a 16-bit real mode thunk, transfers

+  control to a 16-bit real mode entry point, and returns the results. If the

+  caller only need to perform a single 16-bit real mode thunk, then this

+  service should be used. If the caller intends to make more than one 16-bit

+  real mode thunk, then it is more efficient if AsmPrepareThunk16() is called

+  once and AsmThunk16() can be called for each 16-bit real mode thunk.

+

+  If ThunkContext is NULL, then ASSERT().

+

+  @param  ThunkContext  A pointer to the context structure that describes the

+                        16-bit real mode code to call.

+

+**/

+VOID

+EFIAPI

+AsmPrepareAndThunk16 (

+  IN OUT  THUNK_CONTEXT             *ThunkContext

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/BaseMemoryLib.h b/edk2/MdePkg/Include/Library/BaseMemoryLib.h
new file mode 100644
index 0000000..5994530
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/BaseMemoryLib.h
@@ -0,0 +1,395 @@
+/** @file

+	Memory-only library functions with no library constructor/destructor

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	BaseMemoryLib.h

+

+**/

+

+#ifndef __BASE_MEMORY_LIB__

+#define __BASE_MEMORY_LIB__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  );

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  );

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/CacheMaintenanceLib.h b/edk2/MdePkg/Include/Library/CacheMaintenanceLib.h
new file mode 100644
index 0000000..205bc2a
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/CacheMaintenanceLib.h
@@ -0,0 +1,214 @@
+/** @file

+	Cache Maintenance Functions

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	CacheMaintenanceLib.h

+

+**/

+

+#ifndef __CACHE_MAINTENANCE_LIB__

+#define __CACHE_MAINTENANCE_LIB__

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  );

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, the no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache lines to

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+

+  @param  Length  The number of bytes to invalidate from the instruction cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  );

+

+/**

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  );

+

+/**

+  Writes Back and Invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes Back and Invalidate the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, the no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back and invalidate from the

+                  data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  );

+

+/**

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  );

+

+/**

+  Writes Back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes Back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, the no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing

+                  mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  );

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  );

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, the no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to invalidate. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing mode,

+                  then Address is a virtual address.

+  @param  Length  The number of bytes to invalidate from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/CpuLib.h b/edk2/MdePkg/Include/Library/CpuLib.h
new file mode 100644
index 0000000..d79c002
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/CpuLib.h
@@ -0,0 +1,20 @@
+/** @file

+	Library that provides processor specific library services

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	CpuLib.h

+

+**/

+

+#ifndef __CPU_LIB_H__

+#define __CPU_LIB_H__

+

+#endif
\ No newline at end of file
diff --git a/edk2/MdePkg/Include/Library/DebugLib.h b/edk2/MdePkg/Include/Library/DebugLib.h
new file mode 100644
index 0000000..5efb304
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/DebugLib.h
@@ -0,0 +1,439 @@
+/** @file

+  Public include file for the Debug Library

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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 __DEBUG_LIB_H__

+#define __DEBUG_LIB_H__

+

+//

+// Declare bits for PcdDebugPropertyMask

+//

+#define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED       0x01

+#define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED        0x02

+#define DEBUG_PROPERTY_DEBUG_CODE_ENABLED         0x04

+#define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED       0x08

+#define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED  0x10

+#define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED    0x20

+

+//

+// Declare bits for PcdDebugPrintErrorLevel and the ErrorLevel parameter of DebugPrint()

+//

+#define EFI_D_INIT      0x00000001  // Initialization style messages

+#define EFI_D_WARN      0x00000002  // Warnings

+#define EFI_D_LOAD      0x00000004  // Load events

+#define EFI_D_FS        0x00000008  // EFI File system

+#define EFI_D_POOL      0x00000010  // Alloc & Free's

+#define EFI_D_PAGE      0x00000020  // Alloc & Free's

+#define EFI_D_INFO      0x00000040  // Verbose

+#define EFI_D_VARIABLE  0x00000100  // Variable

+#define EFI_D_BM        0x00000400  // Boot Manager (BDS)

+#define EFI_D_BLKIO     0x00001000  // BlkIo Driver

+#define EFI_D_NET       0x00004000  // SNI Driver

+#define EFI_D_UNDI      0x00010000  // UNDI Driver

+#define EFI_D_LOADFILE  0x00020000  // UNDI Driver

+#define EFI_D_EVENT     0x00080000  // Event messages

+#define EFI_D_ERROR     0x80000000  // Error

+

+/**

+

+  Prints a debug message to the debug output device if the specified error level is enabled.

+

+  If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print 

+  the message specified by Format and the associated variable argument list to 

+  the debug output device.

+

+  If Format is NULL, then ASSERT().

+

+  @param  ErrorLevel  The error level of the debug message.

+  @param  Format      Format string for the debug message to print.

+

+**/

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN        ErrorLevel,

+  IN  CONST CHAR8  *Format,

+  ...

+  );

+

+

+/**

+

+  Prints an assert message containing a filename, line number, and description.  

+  This may be followed by a breakpoint or a dead loop.

+

+  Print a message of the form “ASSERT <FileName>(<LineNumber>): <Description>\n?

+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 

+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 

+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 

+  CpuDeadLoop() is called.  If neither of these bits are set, then this function 

+  returns immediately after the message is printed to the debug output device.

+  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while

+  processing another DebugAssert(), then DebugAssert() must return immediately.

+

+  If FileName is NULL, then a <FileName> string of ?NULL) Filename?is printed.

+

+  If Description is NULL, then a <Description> string of ?NULL) Description?is printed.

+

+  @param  FileName     Pointer to the name of the source file that generated the assert condition.

+  @param  LineNumber   The line number in the source file that generated the assert condition

+  @param  Description  Pointer to the description of the assert condition.

+

+**/

+VOID

+EFIAPI

+DebugAssert (

+  IN CONST CHAR8  *FileName,

+  IN INTN         LineNumber,

+  IN CONST CHAR8  *Description

+  );

+

+

+/**

+

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS ?Buffer + 1), then ASSERT(). 

+

+  @param   Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param   Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  );

+

+

+/**

+  

+  Returns TRUE if ASSERT() macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  );

+

+

+/**

+  

+  Returns TRUE if DEBUG()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  );

+

+

+/**

+  

+  Returns TRUE if DEBUG_CODE()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  );

+

+

+/**

+  

+  Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  );

+

+

+/**

+  

+  Internal worker macro that calls DebugAssert().

+

+  This macro calls DebugAssert() passing in the filename, line number, and 

+  expression that evailated to FALSE.

+

+  @param  Expression  Boolean expression that evailated to FALSE

+

+**/

+#define _ASSERT(Expression)  DebugAssert (__FILE__, __LINE__, #Expression)

+

+

+/**

+  

+  Internal worker macro that calls DebugPrint().

+

+  This macro calls DebugPrint() passing in the debug error level, a format 

+  string, and a variable argument list.

+

+  @param  Expression  Expression containing an error level, a format string, 

+                      and a variable argument list based on the format string.

+

+**/

+#define _DEBUG(Expression)   DebugPrint Expression

+

+

+/**

+  

+  Macro that calls DebugAssert() if a expression evaluates to FALSE.

+

+  If the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro evaluates the Boolean expression specified by Expression.  If 

+  Expression evaluates to FALSE, then DebugAssert() is called passing in the 

+  source filename, source line number, and Expression.

+

+  @param  Expression  Boolean expression

+

+**/

+#define ASSERT(Expression)        \

+  do {                            \

+    if (DebugAssertEnabled ()) {  \

+      if (!(Expression)) {        \

+        _ASSERT (Expression);     \

+      }                           \

+    }                             \

+  } while (FALSE)

+

+

+/**

+  

+  Macro that calls DebugPrint().

+

+  If the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro passes Expression to DebugPrint().

+

+  @param  Expression  Expression containing an error level, a format string, 

+                      and a variable argument list based on the format string.

+  

+

+**/

+#define DEBUG(Expression)        \

+  do {                           \

+    if (DebugPrintEnabled ()) {  \

+      _DEBUG (Expression);       \

+    }                            \

+  } while (FALSE)

+

+

+/**

+  

+  Macro that calls DebugAssert() if an EFI_STATUS evaluates to an error code.

+

+  If the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro evaluates the EFI_STATUS value specified by StatusParameter.  

+  If StatusParameter is an error code, then DebugAssert() is called passing in 

+  the source filename, source line number, and StatusParameter.

+

+  @param  StatusParameter  EFI_STATUS value to evaluate.

+

+**/

+#define ASSERT_EFI_ERROR(StatusParameter)                                              \

+  do {                                                                                 \

+    if (DebugAssertEnabled ()) {                                                       \

+      if (EFI_ERROR (StatusParameter)) {                                               \

+        DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", StatusParameter));  \

+        _ASSERT (!EFI_ERROR (StatusParameter));                                        \

+      }                                                                                \

+    }                                                                                  \

+  } while (FALSE)

+

+

+/**

+  

+  Macro that calls DebugAssert() if a protocol is already installed in the 

+  handle database.

+

+  If the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear, 

+  then return.

+

+  If Handle is NULL, then a check is made to see if the protocol specified by Guid 

+  is present on any handle in the handle database.  If Handle is not NULL, then 

+  a check is made to see if the protocol specified by Guid is present on the 

+  handle specified by Handle.  If the check finds the protocol, then DebugAssert() 

+  is called passing in the source filename, source line number, and Guid.

+

+  If Guid is NULL, then ASSERT().

+

+  @param  Handle  The handle to check for the protocol.  This is an optional 

+                  parameter that may be NULL.  If it is NULL, then the entire 

+                  handle database is searched.

+

+  @param  Guid    Pointer to a protocol GUID.

+

+**/

+#define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)                    \

+  do {                                                                     \

+    if (DebugAssertEnabled ()) {                                           \

+      VOID  *Instance;                                                     \

+      ASSERT (Guid != NULL);                                               \

+      if (Handle == NULL) {                                                \

+        if (!EFI_ERROR (gBS->LocateProtocol (Guid, NULL, &Instance))) {    \

+          _ASSERT (Guid already installed in database);                    \

+        }                                                                  \

+      } else {                                                             \

+        if (!EFI_ERROR (gBS->HandleProtocol (Handle, Guid, &Instance))) {  \

+          _ASSERT (Guid already installed on Handle);                      \

+        }                                                                  \

+      }                                                                    \

+    }                                                                      \

+  } while (FALSE)

+

+

+/**

+  Macro that marks the beginning of debug source code.

+

+  If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro marks the beginning of source code that is included in a module.

+  Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 

+  are not included in a module.

+

+**/

+#define DEBUG_CODE_BEGIN()  do { if (DebugCodeEnabled ()) { UINT8  __DebugCodeLocal

+

+

+/**

+  

+  Macro that marks the end of debug source code.

+

+  If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro marks the end of source code that is included in a module.  

+  Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 

+  are not included in a module.

+

+**/

+#define DEBUG_CODE_END()    __DebugCodeLocal = 0; } } while (FALSE)

+

+

+/**

+  

+  Macro that declares a section of debug source code.

+

+  If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 

+  then the source code specified by Expression is included in a module.  

+  Otherwise, the source specified by Expression is not included in a module.

+

+**/

+#define DEBUG_CODE(Expression)  \

+  DEBUG_CODE_BEGIN ();          \

+  Expression                    \

+  DEBUG_CODE_END ()

+

+

+/**

+  

+  Macro that calls DebugClearMemory() to clear a buffer to a default value.

+

+  If the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro calls DebugClearMemory() passing in Address and Length.

+

+  @param  Address  Pointer to a buffer.

+  @param  Length   The number of bytes in the buffer to set.

+

+**/

+#define DEBUG_CLEAR_MEMORY(Address, Length)  \

+  do {                                       \

+    if (DebugClearMemoryEnabled ()) {        \

+      DebugClearMemory (Address, Length);    \

+    }                                        \

+  } while (FALSE)

+

+

+/**

+

+  Macro that calls DebugAssert() if the containing record does not have a 

+  matching signature.  If the signatures matches, then a pointer to the data 

+  structure that contains a specified field of that data structure is returned.  

+  This is a light weight method hide information by placing a public data 

+  structure inside a larger private data structure and using a pointer to the 

+  public data structure to retrieve a pointer to the private data structure.

+

+  If the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear, 

+  then this macro computes the offset, in bytes, of field specified by Field 

+  from the beginning of the  data structure specified by TYPE.  This offset is 

+  subtracted from Record, and is used to return a pointer to a data structure 

+  of the type specified by TYPE.

+

+  If the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set,  

+  then this macro computes the offset, in bytes, of field specified by Field from 

+  the beginning of the data structure specified by TYPE.  This offset is 

+  subtracted from Record, and is used to compute a pointer to a data structure of 

+  the type specified by TYPE.  The Signature field of the data structure specified 

+  by TYPE is compared to TestSignature.  If the signatures match, then a pointer 

+  to the pointer to a data structure of the type specified by TYPE is returned.  

+  If the signatures do not match, then DebugAssert() is called with a description 

+  of “CR has a bad signature?and Record is returned.  

+

+  If the data type specified by TYPE does not contain the field specified by Field, 

+  then the module will not compile.

+

+  If TYPE does not contain a field called Signature, then the module will not 

+  compile.

+

+  @param  Record         Pointer to the field specified by Field within a data 

+                         structure of type TYPE.

+

+  @param  TYPE           The name of the data structure type to return  This 

+                         data structure must contain the field specified by Field. 

+

+  @param  Field          The name of the field in the data structure specified 

+                         by TYPE to which Record points.

+

+  @param  TestSignature  The 32-bit signature value to match.

+

+**/

+#define CR(Record, TYPE, Field, TestSignature)                                          \

+  (DebugAssertEnabled () && (_CR (Record, TYPE, Field)->Signature != TestSignature)) ?  \

+  (TYPE *) (_ASSERT (CR has Bad Signature), Record) :                                   \

+  _CR (Record, TYPE, Field)

+    

+#endif

diff --git a/edk2/MdePkg/Include/Library/DevicePathLib.h b/edk2/MdePkg/Include/Library/DevicePathLib.h
new file mode 100644
index 0000000..b42a8fe
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/DevicePathLib.h
@@ -0,0 +1,196 @@
+/** @file

+	Entry point to a DXE Boot Services Driver

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	DevicePathLib.h

+

+**/

+

+#ifndef __DEVICE_PATH_LIB_H__

+#define __DEVICE_PATH_LIB_H__

+

+/**

+	This function returns the size, in bytes, 

+	of the device path data structure specified by DevicePath.

+	If DevicePath is NULL, then 0 is returned.

+

+	@param	DevicePath A pointer to a device path data structure.

+

+	@return The size of a device path in bytes.

+

+**/

+UINTN

+EFIAPI

+GetDevicePathSize (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+;

+

+/**

+	This function allocates space for a new copy of the device path

+	specified by DevicePath.

+

+	@param	DevicePath A pointer to a device path data structure.

+

+	@return The duplicated device path.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+DuplicateDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath

+  )

+;

+

+/**

+	This function appends the device path SecondDevicePath

+	to every device path instance in FirstDevicePath. 

+

+	@param	FirstDevicePath A pointer to a device path data structure.

+	

+	@param	SecondDevicePath A pointer to a device path data structure.

+

+	@return

+	A pointer to the new device path is returned.

+	NULL is returned if space for the new device path could not be allocated from pool.

+	It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath

+	if they are no longer needed.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath

+  )

+;

+

+/**

+  This function appends the device path node SecondDevicePath

+  to every device path instance in FirstDevicePath.

+

+  @param  DevicePath A pointer to a device path data structure.

+  

+  @param  DevicePathNode A pointer to a single device path node.

+

+  @return A pointer to the new device path.

+  If there is not enough temporary pool memory available to complete this function,

+  then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePathNode (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode

+  )

+;

+

+/**

+	This function appends the device path instance Instance to the device path Source.

+	If Source is NULL, then a new device path with one instance is created.  

+

+	@param	Source A pointer to a device path data structure.

+	@param	Instance A pointer to a device path instance.

+

+	@return

+	A pointer to the new device path.

+	If there is not enough temporary pool memory available to complete this function,

+	then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Source,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Instance

+  )

+;

+

+/**

+	Function retrieves the next device path instance from a device path data structure.

+

+	@param	DevicePath A pointer to a device path data structure.

+	

+	@param	Size A pointer to the size of a device path instance in bytes.

+

+	@return

+	This function returns a pointer to the current device path instance.

+	In addition, it returns the size in bytes of the current device path instance in Size,

+	and a pointer to the next device path instance in DevicePath.

+	If there are no more device path instances in DevicePath, then DevicePath will be set to NULL.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+GetNextDevicePathInstance (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,

+     OUT UINTN                     *Size

+  )

+;

+

+/**

+	Return TRUE is this is a multi instance device path.

+

+	@param	DevicePath A pointer to a device path data structure.

+

+	@retval	TRUE If DevicePath is multi-instance.

+	@retval	FALSE If DevicePath is not multi-instance or DevicePath is NULL.

+

+**/

+BOOLEAN

+EFIAPI

+IsDevicePathMultiInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+;

+

+/**

+	This function retrieves the device path protocol from a handle.

+

+	@param	Handle The handle from which to retrieve the device path protocol.

+

+	@return

+	This function returns the device path protocol from the handle specified by Handle.

+	If Handle is NULL or Handle does not contain a device path protocol, then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+DevicePathFromHandle (

+  IN EFI_HANDLE  Handle

+  )

+;

+

+/**

+	This function allocates a device path for a file and appends it to an existing device path.

+

+	@param	Device A pointer to a device handle.  This parameter is optional and may be NULL.

+	@param	FileName A pointer to a Null-terminated Unicode string.

+

+	@return

+	If Device is a valid device handle that contains a device path protocol,

+	then a device path for the file specified by FileName is allocated

+	and appended to the device path associated with the handle Device. The allocated device path is returned.

+	If Device is NULL or Device is a handle that does not support the device path protocol,

+	then a device path containing a single device path node for the file specified by FileName

+	is allocated and returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+FileDevicePath (

+  IN EFI_HANDLE    Device,     OPTIONAL

+  IN CONST CHAR16  *FileName

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/DxeCoreEntryPoint.h b/edk2/MdePkg/Include/Library/DxeCoreEntryPoint.h
new file mode 100644
index 0000000..1de2798
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/DxeCoreEntryPoint.h
@@ -0,0 +1,77 @@
+/** @file

+  Entry point to the DXE Core

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 __MODULE_ENTRY_POINT_H__

+#define __MODULE_ENTRY_POINT_H__

+

+//

+// Declare the cache of copy of HobList. 

+// 

+extern VOID  *gHobList;

+

+

+/**

+  Enrty point to DXE core.

+

+  @param  HobStart Pointer of HobList.

+

+**/

+VOID

+EFIAPI

+_ModuleEntryPoint (

+  IN VOID  *HobStart

+  );

+

+

+/**

+  Wrapper of enrty point to DXE CORE.

+

+  @param  HobStart Pointer of HobList.

+

+**/

+VOID

+EFIAPI

+EfiMain (

+  IN VOID  *HobStart

+  );

+

+

+/**

+  Call constructs for all libraries. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryConstructorList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Call the list of driver entry points. Automatics Generated by tool.

+

+  @param  HobStart Pointer to HobList.

+ 

+**/

+VOID

+EFIAPI

+ProcessModuleEntryPointList (

+  IN VOID  *HobStart

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/DxeRuntimeDriverLib.h b/edk2/MdePkg/Include/Library/DxeRuntimeDriverLib.h
new file mode 100644
index 0000000..7f6f0eb
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/DxeRuntimeDriverLib.h
@@ -0,0 +1,332 @@
+/** @file

+	Library to abstract runtime services

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	DxeRuntimeDriverLib.h

+

+**/

+

+#ifndef __DXE_RUNTIME_DRIVER_LIB__

+#define __DXE_RUNTIME_DRIVER_LIB__

+

+

+extern const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[];

+

+extern const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[];

+

+/**

+  Check to see if the execute context is in Runtime phase or not.

+

+  @param  None.

+

+  @retval  TRUE  The driver is in SMM.

+  @retval  FALSE The driver is not in SMM.

+

+**/

+BOOLEAN

+EFIAPI

+EfiAtRuntime (

+  VOID 

+  );

+

+/**

+  Check to see if the SetVirtualAddressMsp() is invoked or not.

+

+  @retval  TRUE  SetVirtualAddressMsp() has been called.

+  @retval  FALSE SetVirtualAddressMsp() has not been called.

+

+**/

+BOOLEAN

+EFIAPI

+EfiGoneVirtual (

+  VOID 

+  );

+

+/**

+  Return current time and date information, and time-keeping 

+  capabilities of hardware platform.

+

+  @param  Time         A pointer to storage to receive a snapshot of the current time.

+  @param  Capabilities An optional pointer to a buffer to receive the real time clock device¡¯s

+                       capabilities.

+ 

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetTime (

+  OUT EFI_TIME                    *Time,

+  OUT EFI_TIME_CAPABILITIES       *Capabilities

+  );

+

+/**

+  Set current time and date information.

+

+  @param  Time         A pointer to cache of time setting.

+ 

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to execute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiSetTime (

+  IN EFI_TIME                   *Time

+  );

+

+/**

+  Return current wakeup alarm clock setting.

+

+  @param  Enabled Indicate if the alarm clock is enabled or disabled.

+  @param  Pending Indicate if the alarm signal is pending and requires acknowledgement.

+  @param  Time    Current alarm clock setting.

+ 

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetWakeupTime (

+  OUT BOOLEAN                     *Enabled,

+  OUT BOOLEAN                     *Pending,

+  OUT EFI_TIME                    *Time

+  );

+

+/**

+  Set current wakeup alarm clock.

+

+  @param  Enable Enable or disable current alarm clock..

+  @param  Time   Point to alarm clock setting.

+ 

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiSetWakeupTime (

+  IN BOOLEAN                      Enable,

+  IN EFI_TIME                     *Time

+  );

+

+/**

+  Return value of variable.

+

+  @param  VariableName the name of the vendor's variable, it's a 

+                       Null-Terminated Unicode String

+  @param  VendorGuid   Unify identifier for vendor.

+  @param  Attributes   Point to memory location to return the attributes of variable. If the point 

+                       is NULL, the parameter would be ignored.

+  @param  DataSize     As input, point to the maxinum size of return Data-Buffer.

+                       As output, point to the actual size of the returned Data-Buffer.

+  @param  Data         Point to return Data-Buffer.

+ 

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetVariable (

+  IN      CHAR16                   *VariableName,

+  IN      EFI_GUID                 *VendorGuid,

+  OUT     UINT32                   *Attributes,

+  IN OUT  UINTN                    *DataSize,

+  OUT     VOID                     *Data

+  )

+;

+

+/**

+  Enumerates variable's name.

+

+  @param  VariableNameSize As input, point to maxinum size of variable name.

+                           As output, point to actual size of varaible name.

+  @param  VariableName     As input, supplies the last VariableName that was returned by 

+                           GetNextVariableName().

+                           As output, returns the name of variable. The name 

+                           string is Null-Terminated Unicode string.

+  @param  VendorGuid       As input, supplies the last VendorGuid that was returned by 

+                           GetNextVriableName().

+                           As output, returns the VendorGuid of the current variable.

+ 

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetNextVariableName (

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  );

+

+/**

+  Sets value of variable.

+

+  @param  VariableName the name of the vendor's variable, it's a 

+                       Null-Terminated Unicode String

+  @param  VendorGuid   Unify identifier for vendor.

+  @param  Attributes   Point to memory location to return the attributes of variable. If the point 

+                       is NULL, the parameter would be ignored.

+  @param  DataSize     The size in bytes of Data-Buffer.

+  @param  Data         Point to the content of the variable.

+

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiSetVariable (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  IN UINT32                       Attributes,

+  IN UINTN                        DataSize,

+  IN VOID                         *Data

+  );

+

+/**

+  Returns the next high 32 bits of platform's monotonic counter.

+

+  @param  HighCount Pointer to returned value.

+

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetNextHighMonotonicCount (

+  OUT UINT32                      *HighCount

+  );

+

+/**

+  Resets the entire platform.

+

+  @param  ResetType   The type of reset to perform.

+  @param  ResetStatus The status code for reset.

+  @param  DataSize    The size in bytes of reset data.

+  @param  ResetData   Pointer to data buffer that includes 

+                      Null-Terminated Unicode string.

+

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+VOID

+EfiResetSystem (

+  IN EFI_RESET_TYPE               ResetType,

+  IN EFI_STATUS                   ResetStatus,

+  IN UINTN                        DataSize,

+  IN CHAR16                       *ResetData

+  );

+

+/**

+  Determines the new virtual address that is to be used on subsequent memory accesses.

+

+  @param  DebugDisposition   Supplies type information for the pointer being converted.

+  @param  Address            The pointer to a pointer that is to be fixed to be the 

+                             value needed for the new virtual address mapping being 

+                             applied.

+

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiConvertPointer (

+  IN UINTN                  DebugDisposition,

+  IN OUT VOID               *Address

+  );

+

+

+/**

+  Change the runtime addressing mode of EFI firmware from physical to virtual.

+

+  @param  MemoryMapSize         The size in bytes of VirtualMap.

+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.

+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.

+  @param  VirtualMap            An array of memory descriptors which contain new virtual

+                                address mapping information for all runtime ranges. Type

+                                EFI_MEMORY_DESCRIPTOR is defined in the

+                                GetMemoryMap() function description.

+

+  @retval EFI_SUCCESS           The virtual address map has been applied.

+  @retval EFI_UNSUPPORTED       EFI firmware is not at runtime, or the EFI firmware is already in

+                                virtual address mapped mode.

+  @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is

+                                invalid.

+  @retval EFI_NO_MAPPING        A virtual address was not supplied for a range in the memory

+                                map that requires a mapping.

+  @retval EFI_NOT_FOUND         A virtual address was supplied for an address that is not found

+                                in the memory map.

+**/

+EFI_STATUS

+EFIAPI

+EfiSetVirtualAddressMap (

+  IN UINTN                          MemoryMapSize,

+  IN UINTN                          DescriptorSize,

+  IN UINT32                         DescriptorVersion,

+  IN CONST EFI_MEMORY_DESCRIPTOR    *VirtualMap

+  );

+

+

+/**

+  Conver the standard Lib double linked list to a virtual mapping.

+

+  @param  DebugDisposition   Supplies type information for the pointer being converted.

+  @param  ListHead           Head of linked list to convert.

+

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiConvertList (

+  IN UINTN                DebugDisposition,

+  IN OUT LIST_ENTRY       *ListHead

+  );

+

+

+EFI_STATUS

+EFIAPI

+EfiUpdateCapsule (

+  IN UEFI_CAPSULE_HEADER      **CapsuleHeaderArray,

+  IN UINTN                    CapsuleCount,

+  IN EFI_PHYSICAL_ADDRESS     ScatterGatherList

+  );

+

+

+EFI_STATUS

+EFIAPI

+EfiQueryCapsuleCapabilities (

+  IN UEFI_CAPSULE_HEADER       **CapsuleHeaderArray,

+  IN UINTN                     CapsuleCount,

+  OUT UINT64                   *MaximumCapsuleSize,

+  OUT EFI_RESET_TYPE           *ResetType

+  );

+

+EFI_STATUS

+EFIAPI

+EfiQueryVariableInfo (

+  IN UINT32   Attrubutes,

+  OUT UINT64  *MaximumVariableStorageSize,

+  OUT UINT64  *RemainingVariableStorageSize,

+  OUT UINT64  *MaximumVariableSize

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/DxeServicesTableLib.h b/edk2/MdePkg/Include/Library/DxeServicesTableLib.h
new file mode 100644
index 0000000..f473a17
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/DxeServicesTableLib.h
@@ -0,0 +1,26 @@
+/** @file

+	Library that provides a global pointer to the DXE Services Table

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	DxeServicesTableLib.h

+

+**/

+

+#ifndef __DXE_SERVICES_TABLE_LIB_H__

+#define __DXE_SERVICES_TABLE_LIB_H__

+

+//

+//

+//

+extern EFI_DXE_SERVICES  *gDS;

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Library/DxeSmmDriverEntryPoint.h b/edk2/MdePkg/Include/Library/DxeSmmDriverEntryPoint.h
new file mode 100644
index 0000000..12d35d5
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/DxeSmmDriverEntryPoint.h
@@ -0,0 +1,140 @@
+/** @file

+  Entry point to a DXE SMM Driver

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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 __MODULE_ENTRY_POINT_H__

+#define __MODULE_ENTRY_POINT_H__

+

+//

+// Declare the EFI/UEFI Specification Revision to which this driver is implemented 

+//

+extern const UINT32                   _gUefiDriverRevision;

+

+//

+// Declare the number of entry points in the image. 

+//

+extern const UINT8                    _gDriverEntryPointCount;

+

+//

+// Declare the number of unload handler in the image. 

+//

+extern const UINT8                    _gDriverUnloadImageCount;

+

+/**

+  Enrty point to DXE SMM Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+/**

+  Enrty point wrapper of DXE SMM Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+/**

+  Computes the cummulative return status for the driver entry point and perform

+  a long jump back into DriverEntryPoint().

+

+  @param  Status Status returned by the driver that is exiting.

+

+**/

+VOID

+EFIAPI

+ExitDriver (

+  IN EFI_STATUS  Status

+  );

+

+/**

+  Call constructs for all libraries. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryConstructorList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+/**

+  Call destructors for all libraries. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryDestructorList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Call the list of driver entry points. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @return Status returned by entry points of drivers.  

+ 

+**/

+EFI_STATUS

+EFIAPI

+ProcessModuleEntryPointList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Call the unload handlers for all the modules. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+ 

+  @return Status returned by unload handlers of drivers.

+

+**/

+EFI_STATUS

+EFIAPI

+ProcessModuleUnloadList (

+  IN EFI_HANDLE  ImageHandle

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/HiiLib.h b/edk2/MdePkg/Include/Library/HiiLib.h
new file mode 100644
index 0000000..05824a6
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/HiiLib.h
@@ -0,0 +1,44 @@
+/** @file

+	Public include file for the HII Library

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	HiiLib.h

+

+**/

+

+#ifndef __HII_LIB_H__

+#define __HII_LIB_H__

+

+/**

+	This function allocates pool for an EFI_HII_PACKAGES structure

+	with enough space for the variable argument list of package pointers.

+	The allocated structure is initialized using NumberOfPackages, Guid, 

+	and the variable length argument list of package pointers.

+

+	@param	NumberOfPackages The number of HII packages to prepare.

+	@param	Guid Package GUID.

+

+	@return

+	The allocated and initialized packages.

+

+**/

+EFI_HII_PACKAGES *

+EFIAPI

+PreparePackages (

+  IN UINTN           NumberOfPackages,

+  IN CONST EFI_GUID  *Guid OPTIONAL,

+  ...

+  )

+;

+

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/HobLib.h b/edk2/MdePkg/Include/Library/HobLib.h
new file mode 100644
index 0000000..9789c69
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/HobLib.h
@@ -0,0 +1,353 @@
+/** @file

+	Public include file for the HOB Library

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	HobLib.h

+

+**/

+

+#ifndef __HOB_LIB_H__

+#define __HOB_LIB_H__

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+;

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+;

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+;

+

+/**

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+;

+

+/**

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+;

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the moduleÂ’s entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+;

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+;

+

+/**

+  Builds a GUID HOB with a certain data length.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+;

+

+/**

+  Copies a data buffer to a newly-built HOB.

+

+  This function builds a customized HOB tagged with a GUID for identification,

+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+;

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+;

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+;

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+;

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+;

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+;

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/IoLib.h b/edk2/MdePkg/Include/Library/IoLib.h
new file mode 100644
index 0000000..532c26b
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/IoLib.h
@@ -0,0 +1,2311 @@
+/** @file

+	I/O and MMIO Library Services

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	IoLib.h

+

+**/

+

+#ifndef __IO_LIB_H__

+#define __IO_LIB_H__

+

+#define IO_LIB_ADDRESS(Segment,Port) \

+  ( ((Port) & 0xffff) | (((Segment) & 0xffff) << 16) )

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  );

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  );

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  );

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  );

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 64-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 64-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  );

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  );

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  );

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 64-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/MemoryAllocationLib.h b/edk2/MdePkg/Include/Library/MemoryAllocationLib.h
new file mode 100644
index 0000000..4e76684
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/MemoryAllocationLib.h
@@ -0,0 +1,547 @@
+/** @file

+	Memory Allocation Library Services

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	MemoryAllocationLib.h

+

+**/

+

+#ifndef __MEMORY_ALLOCATION_LIB_H__

+#define __MEMORY_ALLOCATION_LIB_H__

+

+/**

+	Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData.

+

+	@param	Pages The number of 4 KB pages to allocate.

+

+	@return

+	A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+	If Pages is 0, then NULL is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocatePages (

+  IN UINTN  Pages

+  )

+;

+

+/**

+	Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData. 

+

+	@param	Pages The number of 4 KB pages to allocate.

+

+	@return

+	A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+	If Pages is 0, then NULL is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimePages (

+  IN UINTN  Pages

+  )

+;

+

+/**

+	Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType. 

+

+	@param	Pages The number of 4 KB pages to allocate.

+

+	@return

+	A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+	If Pages is 0, then NULL is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedPages (

+  IN UINTN  Pages

+  )

+;

+

+/**

+	Frees one or more 4KB pages that were previously allocated with 

+	one of the page allocation functions in the Memory Allocation Library.

+

+	@param	Buffer Pointer to the buffer of pages to free.

+	@param	Pages The number of 4 KB pages to free.

+

+	None.

+

+**/

+VOID

+EFIAPI

+FreePages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+;

+

+/**

+	Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an alignment specified by Alignment.   

+

+	@param	Pages The number of 4 KB pages to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+	If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an alignment specified by Alignment.   

+

+	@param	Pages The number of 4 KB pages to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+	If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimePages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.

+

+	@param	Pages The number of 4 KB pages to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+	If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Frees one or more 4KB pages that were previously allocated with 

+	one of the aligned page allocation functions in the Memory Allocation Library.

+

+	@param	Buffer Pointer to the buffer of pages to free.

+	@param	Pages The number of 4 KB pages to free.

+

+	None.

+

+**/

+VOID

+EFIAPI

+FreeAlignedPages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+;

+

+/**

+	Allocates a buffer of type EfiBootServicesData.

+

+	@param	AllocationSize The number of bytes to allocate.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocatePool (

+  IN UINTN  AllocationSize

+  )

+;

+

+/**

+	Allocates a buffer of type EfiRuntimeServicesData.

+

+	@param	AllocationSize The number of bytes to allocate.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimePool (

+  IN UINTN  AllocationSize

+  )

+;

+

+/**

+	Allocates a buffer of type EfiReservedMemoryType.

+

+	@param	AllocationSize The number of bytes to allocate.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedPool (

+  IN UINTN  AllocationSize

+  )

+;

+

+/**

+	Allocates and zeros a buffer of type EfiBootServicesData.

+

+	@param	AllocationSize The number of bytes to allocate and zero.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateZeroPool (

+  IN UINTN  AllocationSize

+  )

+;

+

+/**

+	Allocates and zeros a buffer of type EfiRuntimeServicesData.

+

+	@param	AllocationSize The number of bytes to allocate and zero.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimeZeroPool (

+  IN UINTN  AllocationSize

+  )

+;

+

+/**

+	Allocates and zeros a buffer of type EfiReservedMemoryType.

+

+	@param	AllocationSize The number of bytes to allocate and zero.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedZeroPool (

+  IN UINTN  AllocationSize

+  )

+;

+

+/**

+	Copies a buffer to an allocated buffer of type EfiBootServicesData. 

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Buffer The buffer to copy to the allocated buffer.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+;

+

+/**

+	Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. 

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Buffer The buffer to copy to the allocated buffer.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+;

+

+/**

+	Copies a buffer to an allocated buffer of type EfiReservedMemoryType. 

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Buffer The buffer to copy to the allocated buffer.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+;

+

+/**

+	Frees a buffer that was previously allocated with one of the pool allocation functions 

+	in the Memory Allocation Library.

+

+	@param	Buffer Pointer to the buffer to free.

+

+	None.

+

+**/

+VOID

+EFIAPI

+FreePool (

+  IN VOID   *Buffer

+  )

+;

+

+/**

+	Allocates a buffer of type EfiBootServicesData at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+		If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimePool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates a buffer of type EfiReservedMemoryType at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimeZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+;

+

+/**

+	Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Buffer The buffer to copy to the allocated buffer.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+;

+

+/**

+	Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Buffer The buffer to copy to the allocated buffer.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+;

+

+/**

+	Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.

+

+	@param	AllocationSize The number of bytes to allocate.

+	@param	Buffer The buffer to copy to the allocated buffer.

+	@param	Alignment The requested alignment of the allocation.  Must be a power of two.

+	If Alignment is zero, then byte alignment is used.

+

+	@return

+	A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+	If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+;

+

+/**

+	Frees a buffer that was previously allocated with one of the aligned pool allocation functions 

+	in the Memory Allocation Library.

+

+	@param	Buffer Pointer to the buffer to free.

+

+	None.

+

+**/

+VOID

+EFIAPI

+FreeAlignedPool (

+  IN VOID   *Buffer

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PcdLib.h b/edk2/MdePkg/Include/Library/PcdLib.h
new file mode 100644
index 0000000..6d54312
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PcdLib.h
@@ -0,0 +1,700 @@
+/** @file

+PCD Library Class Interface Declarations

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name: PcdLib.h

+

+**/

+

+#ifndef __PCD_LIB_H__

+#define __PCD_LIB_H__

+

+#include <Common/Pcd.h>

+

+

+#define PcdToken(TokenName)  _PCD_TOKEN_##TokenName

+

+

+//

+// Feature Flag is in the form of a global constant

+//

+#define FeaturePcdGet(TokenName)     _gPcd_FixedAtBuild_##TokenName

+

+

+//

+// Fixed is fixed at build time

+//

+#define FixedPcdGet8(TokenName)     _gPcd_FixedAtBuild_##TokenName

+#define FixedPcdGet16(TokenName)    _gPcd_FixedAtBuild_##TokenName

+#define FixedPcdGet32(TokenName)    _gPcd_FixedAtBuild_##TokenName

+#define FixedPcdGet64(TokenName)    _gPcd_FixedAtBuild_##TokenName

+#define FixedPcdGetBool(TokenName)  _gPcd_FixedAtBuild_##TokenName

+

+

+//

+// BugBug: This works for strings, but not constants.

+//

+#define FixedPcdGetPtr(TokenName)    ((VOID *)_gPcd_FixedAtBuild_##TokenName)

+

+

+//

+// (Binary) Patch is in the form of a global variable

+//

+#define PatchPcdGet8(TokenName)     _gPcd_BinaryPatch_##TokenName

+#define PatchPcdGet16(TokenName)    _gPcd_BinaryPatch_##TokenName

+#define PatchPcdGet32(TokenName)    _gPcd_BinaryPatch_##TokenName

+#define PatchPcdGet64(TokenName)    _gPcd_BinaryPatch_##TokenName

+#define PatchPcdGetBool(TokenName)  _gPcd_BinaryPatch_##TokenName

+#define PatchPcdGetPtr(TokenName)   ((VOID *)_gPcd_BinaryPatch_##TokenName)

+

+#define PatchPcdSet8(TokenName, Value)     (_gPcd_BinaryPatch_##TokenName = Value)

+#define PatchPcdSet16(TokenName, Value)    (_gPcd_BinaryPatch_##TokenName = Value)

+#define PatchPcdSet32(TokenName, Value)    (_gPcd_BinaryPatch_##TokenName = Value)

+#define PatchPcdSet64(TokenName, Value)    (_gPcd_BinaryPatch_##TokenName = Value)

+#define PatchPcdSetBool(TokenName, Value)  (_gPcd_BinaryPatch_##TokenName = Value)

+#define PatchPcdSetPtr(TokenName, Value, Size)   CopyMem (_gPcd_BinaryPatch_##TokenName, Value, Size)

+

+//

+// Dynamic is via the protocol with only the TokenNumber as argument

+//  It can also be Patch or Fixed type based on a build option

+//

+#define PcdGet8(TokenName)          _PCD_MODE_8_##TokenName

+#define PcdGet16(TokenName)         _PCD_MODE_16_##TokenName

+#define PcdGet32(TokenName)         _PCD_MODE_32_##TokenName

+#define PcdGet64(TokenName)         _PCD_MODE_64_##TokenName

+#define PcdGetPtr(TokenName)        _PCD_MODE_PTR_##TokenName

+#define PcdGetBool(TokenName)       _PCD_MODE_BOOL_##TokenName

+

+

+//

+// Dynamic Ex is to support binary distribution

+//

+#define PcdGetEx8(Guid, TokenName)     LibPcdGetEx8 (Guid, _PCD_TOKEN_##TokenName)

+#define PcdGetEx16(Guid, TokenName)    LibPcdGetEx16 (Guid, _PCD_TOKEN_##TokenName)

+#define PcdGetEx32(Guid, TokenName)    LibPcdGetEx32 (Guid, _PCD_TOKEN_##TokenName)

+#define PcdGetEx64(Guid, TokenName)    LibPcdGetEx64 (Guid, _PCD_TOKEN_##TokenName)

+#define PcdGetExPtr(Guid, TokenName)   LibPcdGetExPtr (Guid, _PCD_TOKEN_##TokenName)

+#define PcdGetExBool(Guid, TokenName)  LibPcdGetExBool (Guid, _PCD_TOKEN_##TokenName)

+

+

+//

+// Dynamic Set

+//

+#define PcdSet8(TokenName, Value)       LibPcdSet8   (_PCD_TOKEN_##TokenName, Value)

+#define PcdSet16(TokenName, Value)      LibPcdSet16  (_PCD_TOKEN_##TokenName, Value)

+#define PcdSet32(TokenName, Value)      LibPcdSet32  (_PCD_TOKEN_##TokenName, Value)

+#define PcdSet64(TokenName, Value)      LibPcdSet64  (_PCD_TOKEN_##TokenName, Value)

+#define PcdSetPtr(TokenName, Value)     LibPcdSetPtr (_PCD_TOKEN_##TokenName, Value)

+#define PcdSetBool(TokenName, Value)    LibPcdSetBool(_PCD_TOKEN_##TokenName, Value)

+

+

+//

+// Dynamic Set Ex

+//

+#define PcdSetEx8(Guid, TokenName, Value)      LibPcdSetEx8   (Guid, _PCD_TOKEN_##TokenName, Value)

+#define PcdSetEx16(Guid, TokenName, Value)     LibPcdSetEx16  (Guid, _PCD_TOKEN_##TokenName, Value)

+#define PcdSetEx32(Guid, TokenName, Value)     LibPcdSetEx32  (Guid, _PCD_TOKEN_##TokenName, Value)

+#define PcdSetEx64(Guid, TokenName, Value)     LibPcdSetEx64  (Guid, _PCD_TOKEN_##TokenName, Value)

+#define PcdSetExPtr(Guid, TokenName, Value)    LibPcdSetExPtr (Guid, _PCD_TOKEN_##TokenName, Value)

+#define PcdSetExBool(Guid, TokenName, Value)   LibPcdSetExBool(Guid, _PCD_TOKEN_##TokenName, Value)

+

+

+/**

+  Sets the current SKU in the PCD database to the value specified by SkuId.  SkuId is returned.

+

+  @param[in]  SkuId The SKU value that will be used when the PCD service will retrieve and 

+              set values associated with a PCD token.

+

+  @retval SKU_ID Return the SKU ID that just be set.

+

+**/

+SKU_ID

+EFIAPI

+LibPcdSetSku (

+  IN SKU_ID   SkuId

+  );

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Returns the 8-bit value for the token specified by TokenNumber. 

+

+**/

+UINT8

+EFIAPI

+LibPcdGet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Returns the 16-bit value for the token specified by TokenNumber. 

+

+**/

+UINT16

+EFIAPI

+LibPcdGet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Returns the 32-bit value for the token specified by TokenNumber.

+

+**/

+UINT32

+EFIAPI

+LibPcdGet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Returns the 64-bit value for the token specified by TokenNumber.

+

+**/

+UINT64

+EFIAPI

+LibPcdGet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the pointer to the buffer of the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Returns the pointer to the token specified by TokenNumber.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Returns the Boolean value of the token specified by TokenNumber. 

+

+**/

+BOOLEAN 

+EFIAPI

+LibPcdGetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the size of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Returns the size of the token specified by TokenNumber. 

+

+**/

+UINTN

+EFIAPI

+LibPcdGetSize (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Return the UINT8.

+

+**/

+UINT8

+EFIAPI

+LibPcdGetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Return the UINT16.

+

+**/

+UINT16

+EFIAPI

+LibPcdGetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Return the UINT32.

+

+**/

+UINT32

+EFIAPI

+LibPcdGetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Return the UINT64.

+

+**/

+UINT64

+EFIAPI

+LibPcdGetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the pointer to the buffer of token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Return the VOID* pointer.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Return the BOOLEAN.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdGetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Returns the size of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Return the size.

+

+**/

+UINTN

+EFIAPI

+LibPcdGetExSize (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  );

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT16 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  );

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  );

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  );

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber to 

+  the value specified by Value.     Value is returned.

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value A pointer to the buffer to set.

+

+  @retval VOID* Return the pointer for the buffer been set.

+

+**/

+VOID*

+EFIAPI

+LibPcdSetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Value

+  );

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The boolean value to set.

+

+  @retval BOOLEAN Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  );

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  );

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  );

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  );

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  );

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval VOID * Return the value been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Value

+  );

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The Boolean value to set.

+

+  @retval Boolean Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  );

+

+

+/**

+  When the token specified by TokenNumber and Guid is set, 

+  then notification function specified by NotificationFunction is called.  

+  If Guid is NULL, then the default token space is used. 

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  CallBackGuid The PCD token GUID being set.

+  @param[in]  CallBackToken The PCD token number being set.

+  @param[in]  TokenData A pointer to the token data being set.

+  @param[in]  TokenDataSize The size, in bytes, of the data being set.

+

+  @retval VOID

+

+**/

+typedef

+VOID

+(EFIAPI *PCD_CALLBACK) (

+  IN        CONST GUID        *CallBackGuid, OPTIONAL

+  IN        PCD_TOKEN_NUMBER  CallBackToken,

+  IN  OUT   VOID              *TokenData,

+  IN        UINTN             TokenDataSize

+  );

+

+

+/**

+  When the token specified by TokenNumber and Guid is set, 

+  then notification function specified by NotificationFunction is called.  

+  If Guid is NULL, then the default token space is used. 

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates which 

+              namespace to set a value from.  If NULL, then the default 

+              token space is used.

+  @param[in]  TokenNumber The PCD token number to monitor.

+  @param[in]  NotificationFunction The function to call when the token 

+              specified by Guid and TokenNumber is set.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCallbackOnSet (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  );

+

+

+/**

+  Disable a notification function that was established with LibPcdCallbackonSet().

+

+  @param[in]  Guid Specify the GUID token space.

+  @param[in]  TokenNumber Specify the token number.

+  @param[in]  NotificationFunction The callback function to be unregistered.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCancelCallback (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  );

+

+

+/**

+  Retrieves the next PCD token number from the token space specified by Guid.  

+  If Guid is NULL, then the default token space is used.  If TokenNumber is 0, 

+  then the first token number is returned.  Otherwise, the token number that 

+  follows TokenNumber in the token space is returned.  If TokenNumber is the last 

+  token number in the token space, then 0 is returned.  If TokenNumber is not 0 and 

+  is not in the token space specified by Guid, then ASSERT().

+

+  @param[in]  Pointer to a 128-bit unique value that designates which namespace 

+              to set a value from.  If NULL, then the default token space is used.

+  @param[in]  The previous PCD token number.  If 0, then retrieves the first PCD 

+              token number.

+

+  @retval PCD_TOKEN_NUMBER The next valid token number.

+

+**/

+PCD_TOKEN_NUMBER

+EFIAPI

+LibPcdGetNextToken (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PciCf8Lib.h b/edk2/MdePkg/Include/Library/PciCf8Lib.h
new file mode 100644
index 0000000..a102391
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PciCf8Lib.h
@@ -0,0 +1,1052 @@
+/** @file

+	PCI CF8 Library Services for PCI Segment #0

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	PciCf8Lib.h

+

+**/

+

+#ifndef __PCI_CF8_LIB_H__

+#define __PCI_CF8_LIB_H__

+

+#include <Library/PciLib.h>

+

+/**

+  Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an

+  address that can be passed to the PCI Library functions.

+

+  Computes an address that is compatible with the PCI Library functions. The

+  unused upper bits of Bus, Device, Function and Register are stripped prior to

+  the generation of the address.

+

+  @param  Bus       PCI Bus number. Range 0..255.

+  @param  Device    PCI Device number. Range 0..31.

+  @param  Function  PCI Function number. Range 0..7.

+  @param  Register  PCI Register number. Range 0..255.

+

+  @return The encode PCI address.

+

+**/

+#define PCI_CF8_LIB_ADDRESS(Bus,Device,Function,Offset) \

+  PCI_LIB_ADDRESS (Bus, Device, Function, Offset)

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Read8 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Write8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Or8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8And8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8AndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Read16 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Write16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Or16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8And16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8AndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Read32 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Write32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Or32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8And32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8AndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If the register specified by StartAddress >= 0x100, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciCf8ReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If the register specified by StartAddress >= 0x100, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciCf8WriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PciExpressLib.h b/edk2/MdePkg/Include/Library/PciExpressLib.h
new file mode 100644
index 0000000..b773e72
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PciExpressLib.h
@@ -0,0 +1,1020 @@
+/** @file

+	Pci Express Library Services for PCI Segment #0

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	PciExpressLib.h

+

+**/

+

+#ifndef __PCI_EXPRESS_LIB_H__

+#define __PCI_EXPRESS_LIB_H__

+

+#include <Library/PciLib.h>

+

+/**

+  Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an

+  address that can be passed to the PCI Library functions.

+

+  Computes an address that is compatible with the PCI Library functions. The

+  unused upper bits of Bus, Device, Function and Register are stripped prior to

+  the generation of the address.

+

+  @param  Bus       PCI Bus number. Range 0..255.

+  @param  Device    PCI Device number. Range 0..31.

+  @param  Function  PCI Function number. Range 0..7.

+  @param  Register  PCI Register number. Range 0..4095.

+

+  @return The encode PCI address.

+

+**/

+#define PCI_EXPRESS_LIB_ADDRESS(Bus,Device,Function,Offset) \

+  PCI_LIB_ADDRESS (Bus, Device, Function, Offset)

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressRead8 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressRead16 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressRead32 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciExpressReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciExpressWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PciLib.h b/edk2/MdePkg/Include/Library/PciLib.h
new file mode 100644
index 0000000..55edf40
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PciLib.h
@@ -0,0 +1,1015 @@
+/** @file

+	PCI Library Services for PCI Segment #0

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	PciLib.h

+

+**/

+

+#ifndef __PCI_LIB_H__

+#define __PCI_LIB_H__

+

+/**

+  Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an

+  address that can be passed to the PCI Library functions.

+

+  @param  Bus       PCI Bus number. Range 0..255.

+  @param  Device    PCI Device number. Range 0..31.

+  @param  Function  PCI Function number. Range 0..7.

+  @param  Register  PCI Register number. Range 0..255 for PCI. Range 0..4095

+                    for PCI Express.

+

+  @return The encoded PCI address.

+

+**/

+#define PCI_LIB_ADDRESS(Bus,Device,Function,Offset)   \

+  (((Offset) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  );

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  );

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  );

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  );

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  );

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  );

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  );

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Data

+  );

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  );

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  );

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  );

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PciSegmentLib.h b/edk2/MdePkg/Include/Library/PciSegmentLib.h
new file mode 100644
index 0000000..eaca938
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PciSegmentLib.h
@@ -0,0 +1,924 @@
+/** @file

+  Functions accessing PCI configuration registers on any supported PCI segment

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PciSegmentLib.h

+

+**/

+

+#ifndef __PCI_SEGMENT_LIB__

+#define __PCI_SEGMENT_LIB__

+

+

+/**

+  Macro that converts PCI Segment, PCI Bus, PCI Device, PCI Function,

+  and PCI Register to an address that can be passed to the PCI Segment Library functions.

+

+  Computes an address that is compatible with the PCI Segment Library functions.

+  The unused upper bits of Segment, Bus, Device, Function,

+  and Register are stripped prior to the generation of the address.

+

+  @param  Segment   PCI Segment number.  Range 0..65535.

+  @param  Bus       PCI Bus number.  Range 0..255.

+  @param  Device    PCI Device number.  Range 0..31.

+  @param  Function  PCI Function number.  Range 0..7.

+  @param  Register  PCI Register number.  Range 0..255 for PCI.  Range 0..4095 for PCI Express.

+

+  @return The address that is compatible with the PCI Segment Library functions.

+

+**/

+#define PCI_SEGMENT_LIB_ADDRESS(Segment,Bus,Device,Function,Register) \

+  ( ((Register) & 0xfff)              | \

+    (((Function) & 0x07) << 12)       | \

+    (((Device) & 0x1f) << 15)         | \

+    (((Bus) & 0xff) << 20)            | \

+    (LShiftU64((Segment) & 0xffff, 32)) \

+  )

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+  

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 8-bit PCI configuration register specified by Address.

+

+**/

+UINT8

+EFIAPI

+PciSegmentRead8 (

+  IN UINT64                    Address

+  )

+;

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+PciSegmentWrite8 (

+  IN UINT64                    Address,

+  IN UINT8                     Value

+  )

+;

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentOr8 (

+  IN UINT64                    Address,

+  IN UINT8                     OrData

+  )

+;

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Andata    The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAnd8 (

+  IN UINT64                    Address,

+  IN UINT8                     AndData

+  )

+;

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,

+  followed a  bitwise inclusive OR with another 8-bit value.

+  

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Andata    The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAndThenOr8 (

+  IN UINT64                    Address,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+;

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register.

+  The bit field is specified by the StartBit and the EndBit.

+  The value of the bit field is returned.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+

+  @return The value of the bit field.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldRead8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+;

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register.

+  The bit field is specified by the StartBit and the EndBit.

+  All other bits in the destination PCI configuration register are preserved.

+  The new value of the 8-bit register is returned.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  Value     New value of the bit field.

+

+  @return The new value of the 8-bit register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldWrite8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     Value

+  )

+;

+

+/**

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 8-bit PCI configuration register specified by Address. 

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  OrData    The value to OR with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldOr8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     OrData

+  )

+;

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR,

+  and writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in OrData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAnd8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData

+  )

+;

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise AND,

+  and writes the result back to the bit field in the 8-bit register.

+ 

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in AndData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+  @param  OrData    The value to OR with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAndThenOr8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+;

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+  

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 16-bit PCI configuration register specified by Address.

+

+**/

+UINT16

+EFIAPI

+PciSegmentRead16 (

+  IN UINT64                    Address

+  )

+;

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+PciSegmentWrite16 (

+  IN UINT64                    Address,

+  IN UINT16                    Value

+  )

+;

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentOr16 (

+  IN UINT64                    Address,

+  IN UINT16                    OrData

+  )

+;

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Andata    The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAnd16 (

+  IN UINT64                    Address,

+  IN UINT16                    AndData

+  )

+;

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,

+  followed a  bitwise inclusive OR with another 16-bit value.

+  

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Andata    The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAndThenOr16 (

+  IN UINT64                    Address,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+;

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register.

+  The bit field is specified by the StartBit and the EndBit.

+  The value of the bit field is returned.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+

+  @return The value of the bit field.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldRead16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+;

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register.

+  The bit field is specified by the StartBit and the EndBit.

+  All other bits in the destination PCI configuration register are preserved.

+  The new value of the 16-bit register is returned.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  Value     New value of the bit field.

+

+  @return The new value of the 16-bit register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldWrite16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    Value

+  )

+;

+

+/**

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address. 

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  OrData    The value to OR with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldOr16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    OrData

+  )

+;

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,

+  and writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in OrData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAnd16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData

+  )

+;

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise AND,

+  and writes the result back to the bit field in the 16-bit register.

+ 

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in AndData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+  @param  OrData    The value to OR with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAndThenOr16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+;

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+  

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 32-bit PCI configuration register specified by Address.

+

+**/

+UINT32

+EFIAPI

+PciSegmentRead32 (

+  IN UINT64                    Address

+  )

+;

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT32

+EFIAPI

+PciSegmentWrite32 (

+  IN UINT64                    Address,

+  IN UINT32                    Value

+  )

+;

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentOr32 (

+  IN UINT64                    Address,

+  IN UINT32                    OrData

+  )

+;

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Andata    The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAnd32 (

+  IN UINT64                    Address,

+  IN UINT32                    AndData

+  )

+;

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,

+  followed a  bitwise inclusive OR with another 32-bit value.

+  

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Andata    The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAndThenOr32 (

+  IN UINT64                    Address,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+;

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register.

+  The bit field is specified by the StartBit and the EndBit.

+  The value of the bit field is returned.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+

+  @return The value of the bit field.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldRead32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+;

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register.

+  The bit field is specified by the StartBit and the EndBit.

+  All other bits in the destination PCI configuration register are preserved.

+  The new value of the 32-bit register is returned.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  Value     New value of the bit field.

+

+  @return The new value of the 32-bit register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldWrite32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    Value

+  )

+;

+

+/**

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 32-bit PCI configuration register specified by Address. 

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  OrData    The value to OR with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldOr32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    OrData

+  )

+;

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR,

+  and writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise inclusive OR between the read result and the value specified by OrData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in OrData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAnd32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData

+  )

+;

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise AND,

+  and writes the result back to the bit field in the 32-bit register.

+ 

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in AndData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+  @param  OrData    The value to OR with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAndThenOr32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+;

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress

+  and Size into the buffer specified by Buffer.

+  This function only allows the PCI configuration registers from a single PCI function to be read.

+  Size is returned.

+  If any reserved bits in StartAddress are set, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return The paramter of Size.

+

+**/

+UINTN

+EFIAPI

+PciSegmentReadBuffer (

+  IN  UINT64                   StartAddress,

+  IN  UINTN                    Size,

+  OUT VOID                     *Buffer

+  )

+;

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress

+  and Size from the buffer specified by Buffer.

+  This function only allows the PCI configuration registers from a single PCI function to be written.

+  Size is returned.

+  If any reserved bits in StartAddress are set, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return The paramter of Size.

+

+**/

+UINTN

+EFIAPI

+PciSegmentWriteBuffer (

+  IN UINT64                    StartAddress,

+  IN UINTN                     Size,

+  IN VOID                      *Buffer

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PeCoffGetEntryPointLib.h b/edk2/MdePkg/Include/Library/PeCoffGetEntryPointLib.h
new file mode 100644
index 0000000..f20562e
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PeCoffGetEntryPointLib.h
@@ -0,0 +1,39 @@
+/** @file

+	Memory Only PE COFF loader

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	PeCoffGetEntryPointLib.h

+

+**/

+

+#ifndef __PE_COFF_GET_ENTRY_POINT_LIB_H__

+#define __PE_COFF_GET_ENTRY_POINT_LIB_H__

+

+/**

+	Loads a PE/COFF image into memory

+

+	@param	Pe32Data Pointer to a PE/COFF Image

+	

+	@param	EntryPoint Pointer to the entry point of the PE/COFF image

+

+	@retval EFI_SUCCESS            if the EntryPoint was returned

+	@retval EFI_INVALID_PARAMETER  if the EntryPoint could not be found from Pe32Data

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetEntryPoint (

+  IN     VOID  *Pe32Data,

+  IN OUT VOID  **EntryPoint

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PeCoffLib.h b/edk2/MdePkg/Include/Library/PeCoffLib.h
new file mode 100644
index 0000000..08e8195
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PeCoffLib.h
@@ -0,0 +1,131 @@
+/** @file

+	Memory Only PE COFF loader

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	PeCoffLib.h

+

+**/

+

+#ifndef __BASE_PE_COFF_LIB_H__

+#define __BASE_PE_COFF_LIB_H__

+

+//

+// Return status codes from the PE/COFF Loader services

+// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes

+//

+#define IMAGE_ERROR_SUCCESS                      0

+#define IMAGE_ERROR_IMAGE_READ                   1  

+#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE  2

+#define IMAGE_ERROR_INVALID_MACHINE_TYPE         3

+#define IMAGE_ERROR_INVALID_SUBSYSTEM            4

+#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS        5

+#define IMAGE_ERROR_INVALID_IMAGE_SIZE           6

+#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT    7

+#define IMAGE_ERROR_SECTION_NOT_LOADED           8

+#define IMAGE_ERROR_FAILED_RELOCATION            9

+#define IMAGE_ERROR_FAILED_ICACHE_FLUSH          10

+

+

+//

+// PE/COFF Loader Read Function passed in by caller

+//

+typedef

+RETURN_STATUS

+(EFIAPI *PE_COFF_LOADER_READ_FILE) (

+  IN     VOID   *FileHandle,

+  IN     UINTN  FileOffset,

+  IN OUT UINTN  *ReadSize,

+  OUT    VOID   *Buffer

+  );

+

+//

+// Context structure used while PE/COFF image is being loaded and relocated

+//

+typedef struct {

+  PHYSICAL_ADDRESS                  ImageAddress;

+  UINT64                            ImageSize;

+  PHYSICAL_ADDRESS                  DestinationAddress;

+  PHYSICAL_ADDRESS                  EntryPoint;

+  PE_COFF_LOADER_READ_FILE          ImageRead;

+  VOID                              *Handle;

+  VOID                              *FixupData;

+  UINT32                            SectionAlignment;

+  UINT32                            PeCoffHeaderOffset;

+  UINT32                            DebugDirectoryEntryRva;

+  VOID                              *CodeView;

+  CHAR8                             *PdbPointer;

+  UINTN                             SizeOfHeaders;

+  UINT32                            ImageCodeMemoryType;

+  UINT32                            ImageDataMemoryType;

+  UINT32                            ImageError;

+  UINTN                             FixupDataSize;

+  UINT16                            Machine;

+  UINT16                            ImageType;

+  BOOLEAN                           RelocationsStripped;

+  BOOLEAN                           IsTeImage;

+} PE_COFF_LOADER_IMAGE_CONTEXT;

+

+

+/**

+	Retrieves information on a PE/COFF image

+

+	@param	ImageContext The context of the image being loaded

+

+	@retval	EFI_SUCCESS The information on the PE/COFF image was collected.

+	@retval	EFI_INVALID_PARAMETER ImageContext is NULL.

+	@retval	EFI_UNSUPPORTED The PE/COFF image is not supported.

+	@retval	Otherwise The error status from reading the PE/COFF image using the

+	ImageContext->ImageRead() function

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetImageInfo (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+;

+

+/**

+	Relocates a PE/COFF image in memory

+

+	@param	ImageContext Contains information on the loaded image to relocate

+

+	@retval EFI_SUCCESS      if the PE/COFF image was relocated

+	@retval EFI_LOAD_ERROR   if the image is not a valid PE/COFF image

+	@retval EFI_UNSUPPORTED  not support

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderRelocateImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+;

+

+/**

+	Loads a PE/COFF image into memory

+

+	@param	ImageContext Contains information on image to load into memory

+

+	@retval EFI_SUCCESS            if the PE/COFF image was loaded

+	@retval EFI_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer

+	@retval EFI_LOAD_ERROR         if the image is a runtime driver with no relocations

+	@retval EFI_INVALID_PARAMETER  if the image address is invalid

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderLoadImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PeiCoreEntryPoint.h b/edk2/MdePkg/Include/Library/PeiCoreEntryPoint.h
new file mode 100644
index 0000000..4f88223
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PeiCoreEntryPoint.h
@@ -0,0 +1,50 @@
+/** @file

+  Entry point to the PEI Core

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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 __MODULE_ENTRY_POINT_H__

+#define __MODULE_ENTRY_POINT_H__

+

+

+/**

+  Call constructs for all libraries. Automatics Generated by tool.

+

+  @param  FfsHeader   Pointer to header of FFS.

+  @param  PeiServices Pointer to the PEI Services Table.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryConstructorList (

+  IN EFI_FFS_FILE_HEADER  *FfsHeader,

+  IN EFI_PEI_SERVICES     **PeiServices

+  );

+

+

+/**

+  Call the list of driver entry points. Automatics Generated by tool.

+

+  @param  PeiStartupDescriptor  Pointer to startup information .

+  @param  OldCoreData           Pointer to Original startup information.

+

+  @return Status returned by entry points of drivers.  

+ 

+**/

+EFI_STATUS

+EFIAPI

+ProcessModuleEntryPointList (

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,

+  IN VOID                        *OldCoreData

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PeiCoreLib.h b/edk2/MdePkg/Include/Library/PeiCoreLib.h
new file mode 100644
index 0000000..dfbe51c
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PeiCoreLib.h
@@ -0,0 +1,306 @@
+/** @file

+	PEI Core Library implementation

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	PeiCoreLib.h

+

+**/

+

+#ifndef __PEI_CORE_LIB_H__

+#define __PEI_CORE_LIB_H__

+

+/**

+	This service enables a given PEIM to register an interface into the PEI Foundation. 

+

+	@param	PpiList A pointer to the list of interfaces that the caller shall install.

+

+	@retval	EFI_SUCCESS The interface was successfully installed.

+	@retval	EFI_INVALID_PARAMETER The PpiList pointer is NULL.

+	@retval	EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have

+	the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field.

+	@retval	EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreInstallPpi (

+  IN EFI_PEI_PPI_DESCRIPTOR           *PpiList

+  )

+;

+

+/**

+	This service enables PEIMs to replace an entry in the PPI database with an alternate entry.

+

+	@param	OldPpi Pointer to the old PEI PPI Descriptors.

+	@param	NewPpi Pointer to the new PEI PPI Descriptors.

+

+	@retval	EFI_SUCCESS The interface was successfully installed.

+	@retval	EFI_INVALID_PARAMETER The OldPpi or NewPpi is NULL.

+	@retval	EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have

+	the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field.

+	@retval	EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.

+	@retval	EFI_NOT_FOUND The PPI for which the reinstallation was requested has not been installed.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreReinstallPpi (

+  IN EFI_PEI_PPI_DESCRIPTOR           *OldPpi,

+  IN EFI_PEI_PPI_DESCRIPTOR           *NewPpi

+  )

+;

+

+/**

+	This service enables PEIMs to discover a given instance of an interface.

+

+	@param	Guid A pointer to the GUID whose corresponding interface needs to be found.

+	@param	Instance The N-th instance of the interface that is required.

+	@param	PpiDescriptor A pointer to instance of the EFI_PEI_PPI_DESCRIPTOR.

+	@param	Ppi A pointer to the instance of the interface.

+

+	@retval	EFI_SUCCESS The interface was successfully returned.

+	@retval	EFI_NOT_FOUND The PPI descriptor is not found in the database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreLocatePpi (

+  IN EFI_GUID                         *Guid,

+  IN UINTN                            Instance,

+  IN OUT EFI_PEI_PPI_DESCRIPTOR       **PpiDescriptor,

+  IN OUT VOID                         **Ppi

+  )

+;

+

+/**

+	This service enables PEIMs to register a given service to be invoked

+	when another service is installed or reinstalled.

+

+	@param	NotifyList A pointer to the list of notification interfaces that the caller shall install.

+

+	@retval	EFI_SUCCESS The interface was successfully installed.

+	@retval	EFI_INVALID_PARAMETER The NotifyList pointer is NULL.

+	@retval	EFI_INVALID_PARAMETER Any of the PEI notify descriptors in the list do not have

+	the EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES bit set in the Flags field.

+	@retval	EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreNotifyPpi (

+  IN EFI_PEI_NOTIFY_DESCRIPTOR        *NotifyList

+  )

+;

+

+/**

+	This service enables PEIMs to ascertain the present value of the boot mode.  

+

+	@param	BootMode A pointer to contain the value of the boot mode.

+

+	@retval	EFI_SUCCESS The boot mode was returned successfully.

+	@retval	EFI_INVALID_PARAMETER BootMode is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreGetBootMode (

+  IN OUT EFI_BOOT_MODE                *BootMode

+  )

+;

+

+/**

+	This service enables PEIMs to update the boot mode variable.    

+

+	@param	BootMode The value of the boot mode to set.

+

+	@retval	EFI_SUCCESS The value was successfully updated

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreSetBootMode (

+  IN EFI_BOOT_MODE                    BootMode

+  )

+;

+

+/**

+	This service enables a PEIM to ascertain the address of the list of HOBs in memory.

+

+	@param	HobList A pointer to the list of HOBs that the PEI Foundation will initialize.

+

+	@retval	EFI_SUCCESS The list was successfully returned.

+	@retval	EFI_NOT_AVAILABLE_YET The HOB list is not yet published.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreGetHobList (

+  IN OUT VOID                         **HobList

+  )

+;

+

+/**

+	This service enables PEIMs to create various types of HOBs.

+

+	@param	Type The type of HOB to be installed.

+	@param	Length The length of the HOB to be added.

+	@param	Hob The address of a pointer that will contain the HOB header.

+

+	@retval	EFI_SUCCESS The HOB was successfully created.

+	@retval	EFI_OUT_OF_RESOURCES There is no additional space for HOB creation.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreCreateHob (

+  IN UINT16                           Type,

+  IN UINT16                           Length,

+  IN OUT VOID                         **Hob

+  )

+;

+

+/**

+	This service enables PEIMs to discover additional firmware volumes.

+

+	@param	Instance This instance of the firmware volume to find.

+	The value 0 is the Boot Firmware Volume (BFV).

+	@param	FwVolHeader Pointer to the firmware volume header of the volume to return.

+

+	@retval	EFI_SUCCESS The volume was found.

+	@retval	EFI_NOT_FOUND The volume was not found.

+	@retval	EFI_INVALID_PARAMETER FwVolHeader is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreFfsFindNextVolume (

+  IN UINTN                            Instance,

+  IN OUT EFI_FIRMWARE_VOLUME_HEADER   **FwVolHeader

+  )

+;

+

+/**

+	This service enables PEIMs to discover additional firmware files.

+

+	@param	SearchType A filter to find files only of this type.

+	@param	FwVolHeader Pointer to the firmware volume header of the volume to search.

+	This parameter must point to a valid FFS volume.

+	@param	FileHeader Pointer to the current file from which to begin searching.

+

+	@retval	EFI_SUCCESS The file was found.

+	@retval	EFI_NOT_FOUND The file was not found.

+	@retval	EFI_NOT_FOUND The header checksum was not zero.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreFfsFindNextFile (

+  IN EFI_FV_FILETYPE                  SearchType,

+  IN EFI_FIRMWARE_VOLUME_HEADER       *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER          **FileHeader

+  )

+;

+

+/**

+	This service enables PEIMs to discover sections of a given type within a valid FFS file.

+

+	@param	SearchType The value of the section type to find.

+	@param	FfsFileHeader A pointer to the file header that contains the set of sections to be searched.

+	@param	SectionData A pointer to the discovered section, if successful.

+

+	@retval	EFI_SUCCESS The section was found.

+	@retval	EFI_NOT_FOUND The section was not found.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreFfsFindSectionData (

+  IN EFI_SECTION_TYPE                 SectionType,

+  IN EFI_FFS_FILE_HEADER              *FfsFileHeader,

+  IN OUT VOID                         **SectionData

+  )

+;

+

+/**

+	This service enables PEIMs to register the permanent memory configuration

+	that has been initialized with the PEI Foundation.

+

+	@param	MemoryBegin The value of a region of installed memory.

+	@param	MemoryLength The corresponding length of a region of installed memory.

+

+	@retval	EFI_SUCCESS The region was successfully installed in a HOB.

+	@retval	EFI_INVALID_PARAMETER MemoryBegin and MemoryLength are illegal for this system.

+	@retval	EFI_OUT_OF_RESOURCES There is no additional space for HOB creation.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreInstallPeiMemory (

+  IN EFI_PHYSICAL_ADDRESS             MemoryBegin,

+  IN UINT64                           MemoryLength

+  )

+;

+

+/**

+	This service enables PEIMs to allocate memory after the permanent memory has been installed by a PEIM.

+

+	@param	MemoryType Type of memory to allocate.

+	@param	Pages Number of pages to allocate.

+	@param	Memory Pointer of memory allocated.

+

+	@retval	EFI_SUCCESS The memory range was successfully allocated.

+	@retval	EFI_INVALID_PARAMETER Type is not equal to AllocateAnyPages.

+	@retval	EFI_NOT_AVAILABLE_YET Called with permanent memory not available.

+	@retval	EFI_OUT_OF_RESOURCES The pages could not be allocated.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreAllocatePages (

+  IN EFI_MEMORY_TYPE                  MemoryType,

+  IN UINTN                            Pages,

+  IN OUT EFI_PHYSICAL_ADDRESS         *Memory

+  )

+;

+

+/**

+	This service allocates memory from the Hand-Off Block (HOB) heap.

+

+	@param	Size The number of bytes to allocate from the pool.

+	@param	Buffer If the call succeeds, a pointer to a pointer to the allocated buffer;

+	undefined otherwise.

+

+	@retval	EFI_SUCCESS The allocation was successful

+	@retval	EFI_OUT_OF_RESOURCES There is not enough heap to allocate the requested size.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreAllocatePool (

+  IN UINTN                            Size,

+  OUT VOID                            **Buffer

+  )

+;

+

+/**

+	This service resets the entire platform, including all processors and devices, and reboots the system. 

+

+	@retval	EFI_NOT_AVAILABLE_YET The service has not been installed yet.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreResetSystem (

+  VOID

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PeiServicesTablePointerLib.h b/edk2/MdePkg/Include/Library/PeiServicesTablePointerLib.h
new file mode 100644
index 0000000..815e722
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PeiServicesTablePointerLib.h
@@ -0,0 +1,26 @@
+/** @file

+	PEI Services Table Pointer Library services

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	PeiServicesTablePointerLib.h

+

+**/

+

+#ifndef __PEI_SERVICES_TABLE_POINTER_LIB_H__

+#define __PEI_SERVICES_TABLE_POINTER_LIB_H__

+

+EFI_PEI_SERVICES **

+GetPeiServicesTablePointer (

+  VOID

+  );

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Library/PeimEntryPoint.h b/edk2/MdePkg/Include/Library/PeimEntryPoint.h
new file mode 100644
index 0000000..e088459
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PeimEntryPoint.h
@@ -0,0 +1,103 @@
+/** @file

+  Entry point to a PEIM

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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 __MODULE_ENTRY_POINT_H__

+#define __MODULE_ENTRY_POINT_H__

+

+//

+// Declare the EFI/UEFI Specification Revision to which this driver is implemented 

+//

+extern const UINT32                   _gPeimRevision;

+

+/**

+  Image entry point of Peim.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+  @return  Status returned by entry points of Peims.

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  );

+

+

+/**

+  Wrapper of Peim image entry point.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+  @return  Status returned by entry points of Peims.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  );

+

+

+/**

+  Call constructs for all libraries. Automatics Generated by tool.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryConstructorList (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  );

+

+

+/**

+  Call destructors for all libraries. Automatics Generated by tool.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryDestructorList (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  );

+

+

+/**

+  Call the list of driver entry points. Automatics Generated by tool.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+  @return Status returned by entry points of drivers.  

+ 

+**/

+EFI_STATUS

+EFIAPI

+ProcessModuleEntryPointList (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PerformanceLib.h b/edk2/MdePkg/Include/Library/PerformanceLib.h
new file mode 100644
index 0000000..3656409
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PerformanceLib.h
@@ -0,0 +1,201 @@
+/** @file

+  Library that provides services to measure module execution performance

+

+  Copyright (c) 2004, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PerformanceLib.h

+

+**/

+

+#ifndef __PERFORMANCE_LIB_H__

+#define __PERFORMANCE_LIB_H__

+

+//

+// Performance library propery mask bits

+//

+#define PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED  0x00000001

+

+/**

+  Creates a record for the beginning of a performance measurement. 

+  

+  Creates a record that contains the Handle, Token, and Module.

+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.

+  If TimeStamp is zero, then this function reads the current time stamp

+  and adds that time stamp value to the record as the start time.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  );

+

+/**

+  Fills in the end time of a performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then TimeStamp is added to the record as the end time.

+  If the record is found and TimeStamp is zero, then this function reads

+  the current time stamp and adds that time stamp value to the record as the end time.

+  If this function is called multiple times for the same record, then the end time is overwritten.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.

+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  );

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found then the start of the measurement is returned in StartTimeStamp,

+  and the end of the measurement is returned in EndTimeStamp.

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  StartTimeStamp          The 64-bit time stamp that was recorded when the measurement was started.

+  @param  EndTimeStamp            The 64-bit time stamp that was recorded when the measurement was ended.

+

+  @return The key for the current performance log entry.

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurement (

+  UINTN           LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp

+  );

+

+/**

+  Returns TRUE if the performance measurement macros are enabled. 

+  

+  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is set.

+  @retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PerformanceMeasurementEnabled (

+  VOID

+  );

+

+/**

+  Macro that calls EndPerformanceMeasurement().

+

+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,

+  then EndPerformanceMeasurement() is called.

+

+**/

+#define PERF_END(Handle, Token, Module, TimeStamp)                    \

+  do {                                                                \

+    if (PerformanceMeasurementEnabled ()) {                           \

+      EndPerformanceMeasurement (Handle, Token, Module, TimeStamp);   \

+    }                                                                 \

+  } while (FALSE)

+

+/**

+  Macro that calls StartPerformanceMeasurement().

+

+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,

+  then StartPerformanceMeasurement() is called.

+

+**/

+#define PERF_START(Handle, Token, Module, TimeStamp)                  \

+  do {                                                                \

+    if (PerformanceMeasurementEnabled ()) {                           \

+      StartPerformanceMeasurement (Handle, Token, Module, TimeStamp); \

+    }                                                                 \

+  } while (FALSE)

+

+/**

+  Macro that marks the beginning of performance measurement source code.

+

+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,

+  then this macro marks the beginning of source code that is included in a module.

+  Otherwise, the source lines between PERF_CODE_BEGIN() and PERF_CODE_END() are not included in a module.

+

+**/

+#define PERF_CODE_BEGIN()  do { if (PerformanceMeasurementEnabled ()) { UINT8  __PerformanceCodeLocal

+

+/**

+  Macro that marks the end of performance measurement source code.

+

+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,

+  then this macro marks the end of source code that is included in a module.

+  Otherwise, the source lines between PERF_CODE_BEGIN() and PERF_CODE_END() are not included in a module.

+

+**/

+#define PERF_CODE_END()    __PerformanceCodeLocal = 0; } } while (FALSE)

+

+/**

+  Macro that declares a section of performance measurement source code.

+

+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,

+  then the source code specified by Expression is included in a module.

+  Otherwise, the source specified by Expression is not included in a module.

+

+  @param  Expression              Performance measurement source code to include in a module.

+

+**/

+#define PERF_CODE(Expression)  \

+  PERF_CODE_BEGIN ();          \

+  Expression                   \

+  PERF_CODE_END ()

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/PrintLib.h b/edk2/MdePkg/Include/Library/PrintLib.h
new file mode 100644
index 0000000..9c65459
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/PrintLib.h
@@ -0,0 +1,406 @@
+/** @file

+	Library that provides print services

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	PrintLib.h

+

+**/

+

+#ifndef __PRINT_LIB_H__

+#define __PRINT_LIB_H__

+

+//

+// Print primitives

+//

+#define LEFT_JUSTIFY      0x01

+#define COMMA_TYPE        0x08

+#define PREFIX_ZERO       0x20

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on 

+  a Null-terminated Unicode format string and a VA_LIST argument list

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.  

+  The Unicode string is produced by parsing the format string specified by FormatString.  

+  Arguments are pulled from the variable argument list specified by Marker based on the 

+  contents of the format string.  

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeVSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  );

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 

+  Unicode format string and variable argument list.

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The Unicode string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the format string.

+  The length of the produced output buffer is returned.  

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  ...

+  );

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_LIST argument list

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The Unicode string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list specified by Marker based on the 

+  contents of the format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeVSPrintAsciiFormat (

+  OUT CHAR16       *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  IN  VA_LIST      Marker

+  );

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 

+  ASCII format string and  variable argument list.

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The Unicode string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the 

+  format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeSPrintAsciiFormat (

+  OUT CHAR16       *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  );

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_LIST argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list specified by Marker based on 

+  the contents of the format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiVSPrint (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR8   *FormatString,

+  IN  VA_LIST       Marker

+  );

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and  variable argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the 

+  format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  );

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_LIST argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list specified by Marker based on 

+  the contents of the format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiVSPrintUnicodeFormat (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  );

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and  variable argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the 

+  format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiSPrintUnicodeFormat (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  ...

+  );

+

+/**

+  Converts a decimal value to a Null-terminated Unicode string.

+  

+  Converts the decimal number specified by Value to a Null-terminated Unicode 

+  string specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  If the conversion contains more than Width characters, then only the first

+  Width characters are returned, and the total number of characters 

+  required to perform the conversion is returned.

+  Additional conversion parameters are specified in Flags.  

+  The Flags bit LEFT_JUSTIFY is always ignored.

+  All conversions are left justified in Buffer.

+  If Width is 0, PREFIX_ZERO is ignored in Flags.

+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas

+  are inserted every 3rd digit starting from the right.

+  If Value is < 0, then the fist character in Buffer is a '-'.

+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 

+  then Buffer is padded with '0' characters so the combination of the optional '-' 

+  sign character, '0' characters, digit characters for Value, and the Null-terminator

+  add up to Width characters.

+

+  If Buffer is NULL, then ASSERT().

+  If unsupported bits are set in Flags, then ASSERT().

+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer  Pointer to the output buffer for the produced Null-terminated

+                  Unicode string.

+  @param  Flags   The bitmask of flags that specify left justification, zero pad, and commas.

+  @param  Value   The 64-bit signed value to convert to a string.

+  @param  Width	  The maximum number of Unicode characters to place in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+EFIAPI

+UnicodeValueToString (

+  IN OUT CHAR16  *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width

+  );

+

+/**

+  Converts a decimal value to a Null-terminated ASCII string.

+  

+  Converts the decimal number specified by Value to a Null-terminated ASCII string 

+  specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  If the conversion contains more than Width characters, then only the first Width

+  characters are returned, and the total number of characters required to perform

+  the conversion is returned.

+  Additional conversion parameters are specified in Flags.  

+  The Flags bit LEFT_JUSTIFY is always ignored.

+  All conversions are left justified in Buffer.

+  If Width is 0, PREFIX_ZERO is ignored in Flags.

+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas 

+  are inserted every 3rd digit starting from the right.

+  If Value is < 0, then the fist character in Buffer is a '-'.

+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer

+  is padded with '0' characters so the combination of the optional '-'

+  sign character, '0' characters, digit characters for Value, and the 

+  Null-terminator add up to Width characters.

+

+  If Buffer is NULL, then ASSERT().

+  If unsupported bits are set in Flags, then ASSERT().

+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer  Pointer to the output buffer for the produced Null-terminated

+                  ASCII string.

+  @param  Flags   The bitmask of flags that specify left justification, zero pad, and commas.

+  @param  Value   The 64-bit signed value to convert to a string.

+  @param  Width	  The maximum number of ASCII characters to place in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+EFIAPI

+AsciiValueToString (

+  IN OUT CHAR8  *Buffer,

+  IN UINTN      Flags,

+  IN INT64      Value,

+  IN UINTN      Width

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/ReportStatusCodeLib.h b/edk2/MdePkg/Include/Library/ReportStatusCodeLib.h
new file mode 100644
index 0000000..b05bcc6
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/ReportStatusCodeLib.h
@@ -0,0 +1,763 @@
+/** @file

+  Report Status Code Library public .h file

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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 __REPORT_STATUS_CODE_LIB_H__

+#define __REPORT_STATUS_CODE_LIB_H__

+

+//

+// Declare bits for PcdReportStatusCodePropertyMask

+//

+#define REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED          0x00000001

+#define REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED             0x00000002

+#define REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED             0x00000004

+#define REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED              0x00000008

+#define REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED  0x00000010

+

+//

+// Extended Data structure definitions with EFI_STATUS_CODE_DATA headers removed

+//

+

+///

+/// Voltage Extended Error Data

+///

+typedef struct {

+  EFI_EXP_BASE10_DATA   Voltage;

+  EFI_EXP_BASE10_DATA   Threshold;

+} REPORT_STATUS_CODE_LIBRARY_COMPUTING_UNIT_VOLTAGE_ERROR_DATA;

+

+///

+/// Microcode Update Extended Error Data

+///

+typedef struct {

+  UINT32                Version;

+} REPORT_STATUS_CODE_LIBRARY_COMPUTING_UNIT_MICROCODE_UPDATE_ERROR_DATA;

+

+///

+/// Asynchronous Timer Extended Error Data

+///

+typedef struct {

+  EFI_EXP_BASE10_DATA   TimerLimit;

+} REPORT_STATUS_CODE_LIBRARY_COMPUTING_UNIT_TIMER_EXPIRED_ERROR_DATA;

+

+///

+/// Host Processor Mismatch Extended Error Data

+///

+typedef struct {

+  UINT32                Instance;

+  UINT16                Attributes;

+} REPORT_STATUS_CODE_LIBRARY_HOST_PROCESSOR_MISMATCH_ERROR_DATA;

+

+///

+/// Thermal Extended Error Data

+///

+typedef struct {

+  EFI_EXP_BASE10_DATA   Temperature;

+  EFI_EXP_BASE10_DATA   Threshold;

+} REPORT_STATUS_CODE_LIBRARY_COMPUTING_UNIT_THERMAL_ERROR_DATA;

+

+///

+/// Processor Disabled Extended Error Data

+///

+typedef struct {

+  UINT32                Cause;

+  BOOLEAN               SoftwareDisabled;

+} REPORT_STATUS_CODE_LIBRARY_COMPUTING_UNIT_CPU_DISABLED_ERROR_DATA;

+

+///

+/// Embedded cache init extended data

+///

+typedef struct {

+  UINT32                Level;

+  EFI_INIT_CACHE_TYPE   Type;

+} REPORT_STATUS_CODE_LIBRARY_CACHE_INIT_DATA;

+

+///

+/// Memory Extended Error Data

+///

+typedef struct {

+  EFI_MEMORY_ERROR_GRANULARITY  Granularity;

+  EFI_MEMORY_ERROR_OPERATION    Operation;

+  UINTN                         Syndrome;

+  EFI_PHYSICAL_ADDRESS          Address;

+  UINTN                         Resolution;

+} REPORT_STATUS_CODE_LIBRARY_MEMORY_EXTENDED_ERROR_DATA;

+

+///

+/// DIMM number

+///

+typedef struct {

+  UINT16                Array;

+  UINT16                Device;

+} REPORT_STATUS_CODE_LIBRARY_STATUS_CODE_DIMM_NUMBER;

+

+///

+/// Memory Module Mismatch Extended Error Data

+///

+typedef struct {

+  EFI_STATUS_CODE_DIMM_NUMBER Instance;

+} REPORT_STATUS_CODE_LIBRARY_MEMORY_MODULE_MISMATCH_ERROR_DATA;

+

+///

+/// Memory Range Extended Data

+///

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  Start;

+  EFI_PHYSICAL_ADDRESS  Length;

+} REPORT_STATUS_CODE_LIBRARY_MEMORY_RANGE_EXTENDED_DATA;

+

+///

+/// Device handle Extended Data. Used for many

+/// errors and progress codes to point to the device.

+///

+typedef struct {

+  EFI_HANDLE            Handle;

+} REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA;

+

+typedef struct {

+  UINT8                                *DevicePath;

+} REPORT_STATUS_CODE_LIBRARY_DEVICE_PATH_EXTENDED_DATA;

+

+typedef struct {

+  EFI_HANDLE                     ControllerHandle;

+  EFI_HANDLE                     DriverBindingHandle;

+  UINT16                         DevicePathSize;

+  UINT8                          *RemainingDevicePath;

+} REPORT_STATUS_CODE_LIBRARY_STATUS_CODE_START_EXTENDED_DATA;

+

+///

+/// Resource Allocation Failure Extended Error Data

+///

+typedef struct {

+  UINT32                             Bar;

+  UINT16                             DevicePathSize;

+  UINT16                             ReqResSize;

+  UINT16                             AllocResSize;

+  UINT8                              *DevicePath;

+  UINT8                              *ReqRes;

+  UINT8                              *AllocRes;

+} REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA;

+

+///

+/// Extended Error Data for Assert

+///

+typedef struct {

+  UINT32                      LineNumber;

+  UINT32                      FileNameSize;

+  EFI_STATUS_CODE_STRING_DATA *FileName;

+} REPORT_STATUS_CODE_LIBRARY_DEBUG_ASSERT_DATA;

+

+///

+/// System Context Data EBC/IA32/IPF

+///

+typedef struct {

+  EFI_STATUS_CODE_EXCEP_SYSTEM_CONTEXT  Context;

+} REPORT_STATUS_CODE_LIBRARY_STATUS_CODE_EXCEP_EXTENDED_DATA;

+

+///

+/// Legacy Oprom extended data

+///

+typedef struct {

+  EFI_HANDLE            DeviceHandle;

+  EFI_PHYSICAL_ADDRESS  RomImageBase;

+} REPORT_STATUS_CODE_LIBRARY_LEGACY_OPROM_EXTENDED_DATA;

+

+//

+// Extern for the modules Caller ID GUID

+//

+extern EFI_GUID gEfiCallerIdGuid;

+

+/**

+  Converts a status code to an 8-bit POST code value.

+

+  Converts the status code specified by CodeType and Value to an 8-bit POST code 

+  and returns the 8-bit POST code in PostCode.  If CodeType is an 

+  EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode 

+  are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits 

+  24..26 of Value., and TRUE is returned.  Otherwise, FALSE is returned.  

+

+  If PostCode is NULL, then ASSERT().

+

+  @param  CodeType  The type of status code being converted.

+  @param  Value     The status code value being converted.

+  @param  PostCode  A pointer to the 8-bit POST code value to return. 

+

+  @retval  TRUE   The status code specified by CodeType and Value was converted 

+                  to an 8-bit POST code and returned in  PostCode.

+  @retval  FALSE  The status code specified by CodeType and Value could not be 

+                  converted to an 8-bit POST code value.

+

+**/

+BOOLEAN

+EFIAPI

+CodeTypeToPostCode (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,

+  OUT UINT8                  *PostCode

+  );

+

+

+/**

+  Extracts ASSERT() information from a status code structure.

+

+  Converts the status code specified by CodeType, Value, and Data to the ASSERT()

+  arguments specified by Filename, Description, and LineNumber.  If CodeType is 

+  an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and 

+  Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract 

+  Filename, Description, and LineNumber from the optional data area of the 

+  status code buffer specified by Data.  The optional data area of Data contains 

+  a Null-terminated ASCII string for the FileName, followed by a Null-terminated 

+  ASCII string for the Description, followed by a 32-bit LineNumber.  If the 

+  ASSERT() information could be extracted from Data, then return TRUE.  

+  Otherwise, FALSE is returned.  

+

+  If Data is NULL, then ASSERT().

+  If Filename is NULL, then ASSERT().

+  If Description is NULL, then ASSERT().

+  If LineNumber is NULL, then ASSERT().

+

+  @param  CodeType     The type of status code being converted.

+  @param  Value        The status code value being converted.

+  @param  Data         Pointer to status code data buffer. 

+  @param  Filename     Pointer to the source file name that generated the ASSERT().

+  @param  Description  Pointer to the description of the ASSERT().

+  @param  LineNumber   Pointer to source line number that generated the ASSERT().

+

+  @retval  TRUE   The status code specified by CodeType, Value, and Data was 

+                  converted ASSERT() arguments specified by Filename, Description, 

+                  and LineNumber.

+  @retval  FALSE  The status code specified by CodeType, Value, and Data could 

+                  not be converted to ASSERT() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractAssertInfo (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,  

+  IN  EFI_STATUS_CODE_DATA   *Data, 

+  OUT CHAR8                  **Filename,

+  OUT CHAR8                  **Description,

+  OUT UINT32                 *LineNumber

+  );

+

+

+/**

+  Extracts DEBUG() information from a status code structure.

+

+  Converts the status code specified by Data to the DEBUG() arguments specified 

+  by ErrorLevel, Marker, and Format.  If type GUID in Data is 

+  EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and 

+  Format from the optional data area of the status code buffer specified by Data.  

+  The optional data area of Data contains a 32-bit ErrorLevel followed by Marker 

+  which is 12 UINTN parameters, followed by a Null-terminated ASCII string for 

+  the Format.  If the DEBUG() information could be extracted from Data, then 

+  return TRUE.  Otherwise, FALSE is returned.

+

+  If Data is NULL, then ASSERT().

+  If ErrorLevel is NULL, then ASSERT().

+  If Marker is NULL, then ASSERT().

+  If Format is NULL, then ASSERT().

+

+  @param  Data        Pointer to status code data buffer. 

+  @param  ErrorLevel  Pointer to error level mask for a debug message.

+  @param  Marker      Pointer to the variable argument list associated with Format.

+  @param  Format      Pointer to a Null-terminated ASCII format string of a 

+                      debug message.

+

+  @retval  TRUE   The status code specified by Data was converted DEBUG() arguments 

+                  specified by ErrorLevel, Marker, and Format.

+  @retval  FALSE  The status code specified by Data could not be converted to 

+                  DEBUG() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractDebugInfo (

+  IN  EFI_STATUS_CODE_DATA  *Data,

+  OUT UINT32                *ErrorLevel,

+  OUT VA_LIST               *Marker,

+  OUT CHAR8                 **Format

+  );

+

+

+/**

+  Reports a status code.

+

+  Reports the status code specified by the parameters Type and Value.  Status 

+  code also require an instance, caller ID, and extended data.  This function 

+  passed in a zero instance, NULL extended data, and a caller ID of 

+  gEfiCallerIdGuid, which is the GUID for the module.  

+  

+  ReportStatusCode()must actively prevent recusrsion.  If ReportStatusCode() 

+  is called while processing another any other Report Status Code Library function,

+  then ReportStatusCode() must return immediately.

+

+  @param  Type   Status code type. 

+  @param  Value  Status code value.

+

+  @retval  EFI_SUCCESS       The status code was reported.

+  @retval  EFI_DEVICE_ERROR  There status code could not be reported due to a 

+                             device error.

+  @retval  EFI_UNSUPPORTED   Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value

+  );

+

+

+/**

+  Reports a status code with a Device Path Protocol as the extended data.

+

+  Allocates and fills in the extended data section of a status code with the 

+  Device Path Protocol specified by DevicePath.  This function is responsible 

+  for allocating a buffer large enough for the standard header and the device 

+  path.  The standard header is filled in with a GUID of 

+  gEfiStatusCodeSpecificDataGuid.  The status code is reported with a zero 

+  instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithDevicePath()must actively prevent recursion.  If 

+  ReportStatusCodeWithDevicePath() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithDevicePath() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If DevicePath is NULL, then ASSERT().

+

+  @param  Type        Status code type. 

+  @param  Value       Status code value.

+  @param  DevicePath  Pointer to the Device Path Protocol to be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by DevicePath.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithDevicePath (

+  IN EFI_STATUS_CODE_TYPE      Type,

+  IN EFI_STATUS_CODE_VALUE     Value,

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  );

+

+

+/**

+  Reports a status code with an extended data buffer.

+

+  Allocates and fills in the extended data section of a status code with the 

+  extended data specified by ExtendedData and ExtendedDataSize.  ExtendedData 

+  is assumed to be one of the data structures specified in Related Definitions.  

+  These data structure do not have the standard header, so this function is 

+  responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled 

+  in with a GUID of  gEfiStatusCodeSpecificDataGuid.  The status code is reported 

+  with a zero instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithExtendedData()must actively prevent recursion.  If 

+  ReportStatusCodeWithExtendedData() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithExtendedData() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL, then ASSERT().

+  If ExtendedDataSize is 0, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  ExtendedData      Pointer to the extended data buffer to be reported.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer to 

+                            be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by ExtendedData and ExtendedDataSize.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithExtendedData (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN VOID                   *ExtendedData,

+  IN UINTN                  ExtendedDataSize

+  );

+

+

+/**

+  Reports a status code with full parameters.

+

+  The function reports a status code.  If ExtendedData is NULL and ExtendedDataSize 

+  is 0, then an extended data buffer is not reported.  If ExtendedData is not 

+  NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.  

+  ExtendedData is assumed not have the standard status code header, so this function 

+  is responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled in 

+  with a GUID specified by ExtendedDataGuid.  If ExtendedDataGuid is NULL, then a 

+  GUID of gEfiStatusCodeSpecificDatauid is used.  The status code is reported with 

+  an instance specified by Instance and a caller ID specified by CallerId.  If 

+  CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.

+

+  ReportStatusCodeEx()must actively prevent recursion.  If ReportStatusCodeEx() 

+  is called while processing another any other Report Status Code Library function, 

+  then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().

+  If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  If this parameter is NULL, then a caller 

+                            ID of gEfiCallerIdGuid is used.

+  @param  ExtendedDataGuid  Pointer to the GUID for the extended data buffer.  

+                            If this parameter is NULL, then a the status code 

+                            standard header is filled in with 

+                            gEfiStatusCodeSpecificDataGuid.

+  @param  ExtendedData      Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate 

+                                 the extended data section if it was specified.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeEx (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN UINT32                 Instance,

+  IN EFI_GUID               *CallerId           OPTIONAL,

+  IN EFI_GUID               *ExtendedDataGuid   OPTIONAL,

+  IN VOID                   *ExtendedData       OPTIONAL,

+  IN UINTN                  ExtendedDataSize

+  );

+

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Report Status Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  );

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Report 

+  Status Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  Pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  );

+

+

+/**

+  Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportProgressCodeEnabled (

+  VOID

+  );

+

+

+/**

+  Returns TRUE if status codes of type EFI_ERROR_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportErrorCodeEnabled (

+  VOID

+  );

+

+

+/**

+  Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportDebugCodeEnabled (

+  VOID

+  );

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeEnabled (

+  VOID

+  );

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the 

+  REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED bit of 

+  PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeDescriptionEnabled (

+  VOID

+  );

+

+

+/**

+  Reports a status code with minimal parameters if the status code type is enabled.

+

+  If the status code type specified by Type is enabled in 

+  PcdReportStatusCodeProperyMask, then call ReportStatusCode() passing in Type 

+  and Value.

+

+  @param  Type   Status code type. 

+  @param  Value  Status code value.

+

+  @retval  EFI_SUCCESS       The status code was reported.

+  @retval  EFI_DEVICE_ERROR  There status code could not be reported due to a device error.

+  @retval  EFI_UNSUPPORTED   Report status code is not supported

+

+**/

+#define REPORT_STATUS_CODE(Type,Value)                                                          \

+  (ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ?  \

+  ReportStatusCode(Type,Value)                                                               :  \

+  (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)       ?  \

+  ReportStatusCode(Type,Value)                                                               :  \

+  (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)       ?  \

+  ReportStatusCode(Type,Value)                                                               :  \

+  EFI_UNSUPPORTED

+

+

+/**

+  Reports a status code with a Device Path Protocol as the extended data if the 

+  status code type is enabled.

+

+  If the status code type specified by Type is enabled in 

+  PcdReportStatusCodeProperyMask, then call ReportStatusCodeWithDevicePath() 

+  passing in Type, Value, and DevicePath.

+

+  @param  Type        Status code type. 

+  @param  Value       Status code value.

+  @param  DevicePath  Pointer to the Device Path Protocol to be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by DevicePath.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type,Value,DevicePathParameter)                     \

+  (ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ?  \

+  ReportStatusCodeWithDevicePath(Type,Value,DevicePathParameter)                             :  \

+  (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)       ?  \

+  ReportStatusCodeWithDevicePath(Type,Value,DevicePathParameter)                             :  \

+  (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)       ?  \

+  ReportStatusCodeWithDevicePath(Type,Value,DevicePathParameter)                             :  \

+  EFI_UNSUPPORTED

+

+

+/**

+  Reports a status code with an extended data buffer if the status code type 

+  is enabled.

+

+  If the status code type specified by Type is enabled in 

+  PcdReportStatusCodeProperyMask, then call ReportStatusCodeWithExtendedData() 

+  passing in Type, Value, ExtendedData, and ExtendedDataSize.

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  ExtendedData      Pointer to the extended data buffer to be reported.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer to

+                            be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by ExtendedData and ExtendedDataSize.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+#define REPORT_STATUS_CODE_WITH_EXTENDED_DATA(Type,Value,ExtendedData,ExtendedDataSize)         \

+  (ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ?  \

+  ReportStatusCodeWithExtendedData(Type,Value,ExtendedData,ExtendedDataSize)                 :  \

+  (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)       ?  \

+  ReportStatusCodeWithExtendedData(Type,Value,ExtendedData,ExtendedDataSize)                 :  \

+  (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)       ?  \

+  ReportStatusCodeWithExtendedData(Type,Value,ExtendedData,ExtendedDataSize)                 :  \

+  EFI_UNSUPPORTED

+

+/**

+  Reports a status code specifying all parameters if the status code type is enabled.

+

+  If the status code type specified by Type is enabled in 

+  PcdReportStatusCodeProperyMask, then call ReportStatusCodeEx() passing in Type, 

+  Value, Instance, CallerId, ExtendedDataGuid, ExtendedData, and ExtendedDataSize.

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  If this parameter is NULL, then a caller 

+                            ID of gEfiCallerIdGuid is used.

+  @param  ExtendedDataGuid  Pointer to the GUID for the extended data buffer.  

+                            If this parameter is NULL, then a the status code 

+                            standard header is filled in with 

+                            gEfiStatusCodeSpecificDataGuid.

+  @param  ExtendedData      Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section if it was specified.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+#define REPORT_STATUS_CODE_EX(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)  \

+  (ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE)             ?  \

+  ReportStatusCodeEx(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)        :  \

+  (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)                   ?  \

+  ReportStatusCodeEx(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)        :  \

+  (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)                   ?  \

+  ReportStatusCodeEx(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)        :  \

+  EFI_UNSUPPORTED

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  If POST codes are enabled in PcdReportStatusCodeProperyMask, then call PostCode() 

+  passing in Value.  Value is returned.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return  Value

+

+**/

+#define POST_CODE(Value)  ReportPostCodeEnabled() ? PostCode(Value) : Value

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  If POST codes and POST code descriptions are enabled in 

+  PcdReportStatusCodeProperyMask, then call PostCodeWithDescription() passing in 

+  Value and Description.  If only POST codes are enabled, then call PostCode() 

+  passing in Value.  Value is returned.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  Pointer to an ASCII string that is a description of the 

+                       POST code value.

+

+**/

+#define POST_CODE_WITH_DESCRIPTION(Value,Description)  \

+  ReportPostCodeEnabled()                        ?     \

+    (ReportPostCodeDescriptionEnabled()          ?     \

+      PostCodeWithDescription(Value,Description) :     \

+      PostCode(Value))                           :     \

+    Value

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/ResourcePublicationLib.h b/edk2/MdePkg/Include/Library/ResourcePublicationLib.h
new file mode 100644
index 0000000..2aa0040
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/ResourcePublicationLib.h
@@ -0,0 +1,44 @@
+/** @file

+	Declare presence of resources in the platform

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	ResourcePublicationLib.h

+

+**/

+

+#ifndef __RESOURCE_PUBLICATION_LIB__

+#define __RESOURCE_PUBLICATION_LIB__

+

+/**

+  

+  Declares the presence of permanent system memory in the platform.

+

+  Declares that the system memory buffer specified by MemoryBegin and MemoryLength

+  as permanent memory that may be used for general purpose use by software.

+  The amount of memory available to software may be less than MemoryLength

+  if published memory has alignment restrictions.  

+

+  @param  MemoryBegin               The start address of the memory being declared.

+  @param  MemoryLength              The number of bytes of memory being declared.

+

+  @retval  RETURN_SUCCESS           The memory buffer was published.

+  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to publish the memory buffer

+

+**/

+RETURN_STATUS

+EFIAPI

+PublishSystemMemory (

+  IN PHYSICAL_ADDRESS       MemoryBegin,

+  IN UINT64                 MemoryLength

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/SmbusLib.h b/edk2/MdePkg/Include/Library/SmbusLib.h
new file mode 100644
index 0000000..484ab90
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/SmbusLib.h
@@ -0,0 +1,387 @@
+/** @file

+	SMBUS Functions

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	SmbusLib.h

+

+**/

+

+#ifndef __SMBUS_LIB__

+#define __SMBUS_LIB__

+

+//

+// PEC BIT is bit 21 in SMBUS address

+//

+#define SMBUS_LIB_PEC_BIT   (1 << 21)

+

+/**

+  Macro that converts SMBUS slave address, SMBUS command, SMBUS data length,

+  and PEC to a value that can be passed to the SMBUS Library functions.

+

+  Computes an address that is compatible with the SMBUS Library functions.

+  The unused upper bits of SlaveAddress, Command, and Length are stripped

+  prior to the generation of the address.

+  

+  @param  SlaveAddress    SMBUS Slave Address.  Range 0..127.

+  @param  Command         SMBUS Command.  Range 0..255.

+  @param  Length          SMBUS Data Length.  Range 0..31.

+  @param  Pec             TRUE if Packet Error Checking is enabled.  Otherwise FALSE.

+

+**/

+#define SMBUS_LIB_ADDRESS(SlaveAddress,Command,Length,Pec)  \

+  ( ((Pec) ? SMBUS_LIB_PEC_BIT: 0)      | \

+    (((SlaveAddress) & 0x7f) << 1)      | \

+    (((Command)      & 0xff) << 8)      | \

+    (((Length)       & 0x1f) << 16)       \

+  )

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to send.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from OutBuffer.  Bytes are then read from the SMBUS into InBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure InBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If OutBuffer is NULL, then ASSERT().

+  If InBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.

+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *OutBuffer,

+  OUT VOID           *InBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/TimerLib.h b/edk2/MdePkg/Include/Library/TimerLib.h
new file mode 100644
index 0000000..3d0f03e
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/TimerLib.h
@@ -0,0 +1,100 @@
+/** @file

+	Timer Library Functions

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	TimerLib.h

+

+**/

+

+#ifndef __TIMER_LIB__

+#define __TIMER_LIB__

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return Return value depends on implementation.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  );

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return Return value depends on implementation.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  );

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  Retrieves the current value of a 64-bit free running performance counter. The

+  counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  );

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  IN      UINT64                    *StartValue,  OPTIONAL

+  IN      UINT64                    *EndValue     OPTIONAL

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/UefiBootServicesTableLib.h b/edk2/MdePkg/Include/Library/UefiBootServicesTableLib.h
new file mode 100644
index 0000000..52b5e23
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/UefiBootServicesTableLib.h
@@ -0,0 +1,27 @@
+/** @file

+	Library that provides a global pointer to the UEFI Boot Services Tables

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	UefiBootServicesTableLib.h

+

+**/

+

+#ifndef __UEFI_BOOT_SERVICES_TABLE_LIB_H__

+#define __UEFI_BOOT_SERVICES_TABLE_LIB_H__

+

+//

+//

+//

+extern EFI_HANDLE         gImageHandle;

+extern EFI_SYSTEM_TABLE   *gST;

+extern EFI_BOOT_SERVICES  *gBS;

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/UefiDecompressLib.h b/edk2/MdePkg/Include/Library/UefiDecompressLib.h
new file mode 100644
index 0000000..d2a3793
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/UefiDecompressLib.h
@@ -0,0 +1,37 @@
+/** @file

+	Return UEFI Decompress Protocol 

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	UefiDecompressLib.h

+

+**/

+

+#ifndef __UEFI_DECPOMPRESS_LIB_H__

+#define __UEFI_DECPOMPRESS_LIB_H__

+

+RETURN_STATUS

+EFIAPI

+UefiDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  );

+

+RETURN_STATUS

+EFIAPI

+UefiDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/UefiDriverEntryPoint.h b/edk2/MdePkg/Include/Library/UefiDriverEntryPoint.h
new file mode 100644
index 0000000..6269876
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/UefiDriverEntryPoint.h
@@ -0,0 +1,154 @@
+/** @file

+  Entry point to a DXE Boot Services Driver

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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 __MODULE_ENTRY_POINT_H__

+#define __MODULE_ENTRY_POINT_H__

+

+//

+// Declare the EFI/UEFI Specification Revision to which this driver is implemented 

+//

+extern const UINT32                   _gUefiDriverRevision;

+

+//

+// Declare the number of entry points in the image. 

+//

+extern const UINT8                    _gDriverEntryPointCount;

+

+//

+// Declare the number of unload handler in the image. 

+//

+extern const UINT8                    _gDriverUnloadImageCount;

+

+//

+// Declare the arrary of Boot Sevice Exit Event callbacks . 

+//

+extern const EFI_EVENT_NOTIFY         _gDriverExitBootServicesEvent[];

+

+//

+// Declare the arrary of Virtual Address Change Event callbacks . 

+//

+extern const EFI_EVENT_NOTIFY         _gDriverSetVirtualAddressMapEvent[];

+

+/**

+  Enrty point to DXE SMM Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Enrty point wrapper of DXE Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Computes the cummulative return status for the driver entry point and perform

+  a long jump back into DriverEntryPoint().

+

+  @param  Status Status returned by the driver that is exiting.

+

+**/

+VOID

+EFIAPI

+ExitDriver (

+  IN EFI_STATUS  Status

+  );

+

+

+/**

+  Call constructs for all libraries. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryConstructorList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Call destructors for all libraries. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+**/

+VOID

+EFIAPI

+ProcessLibraryDestructorList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+/**

+  Call the list of driver entry points. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @return Status returned by entry points of drivers.  

+ 

+**/

+

+EFI_STATUS

+EFIAPI

+ProcessModuleEntryPointList (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  );

+

+

+/**

+  Call the unload handlers for all the modules. Automatics Generated by tool.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+ 

+  @return Status returned by unload handlers of drivers.

+

+**/

+EFI_STATUS

+EFIAPI

+ProcessModuleUnloadList (

+  IN EFI_HANDLE  ImageHandle

+  );

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/UefiDriverModelLib.h b/edk2/MdePkg/Include/Library/UefiDriverModelLib.h
new file mode 100644
index 0000000..b6532f1
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/UefiDriverModelLib.h
@@ -0,0 +1,48 @@
+/** @file

+	UEFI Driver Model Library Services

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	UefiDriverModelLib.h

+

+**/

+

+#ifndef __UEFI_DRIVER_MODEL_LIB_H__

+#define __UEFI_DRIVER_MODEL_LIB_H__

+

+//

+// Declare bitmask values for the protocols that are enabled 

+//

+#define UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED        0x01

+#define UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED    0x02

+#define UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED  0x04

+

+//

+// 

+//

+extern const UINT8                           _gDriverModelProtocolBitmask;

+

+//

+//

+//

+typedef struct {

+  const EFI_DRIVER_BINDING_PROTOCOL        *DriverBinding;

+  const EFI_COMPONENT_NAME_PROTOCOL        *ComponentName;

+  const EFI_DRIVER_CONFIGURATION_PROTOCOL  *DriverConfiguration;

+  const EFI_DRIVER_DIAGNOSTICS_PROTOCOL    *DriverDiagnostics;

+} EFI_DRIVER_MODEL_PROTOCOL_LIST;

+

+//

+//

+//

+extern const UINTN                           _gDriverModelProtocolListEntries;

+extern const EFI_DRIVER_MODEL_PROTOCOL_LIST  _gDriverModelProtocolList[];

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/UefiLib.h b/edk2/MdePkg/Include/Library/UefiLib.h
new file mode 100644
index 0000000..428235c
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/UefiLib.h
@@ -0,0 +1,542 @@
+/** @file

+  MDE UEFI library functions and macros

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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 __UEFI_LIB_H__

+#define __UEFI_LIB_H__

+

+//

+// Unicode String Table

+//

+typedef struct {

+  CHAR8   *Language;

+  CHAR16  *UnicodeString;

+} EFI_UNICODE_STRING_TABLE;

+

+//

+// EFI Lock Status

+//

+typedef enum {

+  EfiLockUninitialized = 0,

+  EfiLockReleased      = 1,

+  EfiLockAcquired      = 2

+} EFI_LOCK_STATE;

+

+//

+// EFI Lock 

+//

+typedef struct {

+  EFI_TPL         Tpl;

+  EFI_TPL         OwnerTpl;

+  EFI_LOCK_STATE  Lock;

+} EFI_LOCK;

+

+

+/**

+  This function searches the list of configuration tables stored in the EFI System 

+  Table for a table with a GUID that matches TableGuid.  If a match is found, 

+  then a pointer to the configuration table is returned in Table, and EFI_SUCCESS 

+  is returned.  If a matching GUID is not found, then EFI_NOT_FOUND is returned.

+

+  @param  TableGuid       Pointer to table's GUID type..

+  @param  Table           Pointer to the table associated with TableGuid in the EFI System Table.

+

+  @retval EFI_SUCCESS     A configuration table matching TableGuid was found.

+  @retval EFI_NOT_FOUND   A configuration table matching TableGuid could not be found.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetSystemConfigurationTable (  

+  IN  EFI_GUID  *TableGuid,

+  OUT VOID      **Table

+  );

+

+/**

+  This function causes the notification function to be executed for every protocol 

+  of type ProtocolGuid instance that exists in the system when this function is 

+  invoked.  In addition, every time a protocol of type ProtocolGuid instance is 

+  installed or reinstalled, the notification function is also executed.

+

+  @param  ProtocolGuid    Supplies GUID of the protocol upon whose installation the event is fired.

+  @param  NotifyTpl       Supplies the task priority level of the event notifications.

+  @param  NotifyFunction  Supplies the function to notify when the event is signaled.

+  @param  NotifyContext   The context parameter to pass to NotifyFunction.

+  @param  Registration    A pointer to a memory location to receive the registration value.

+

+  @return The notification event that was created. 

+

+**/

+EFI_EVENT

+EFIAPI

+EfiCreateProtocolNotifyEvent(

+  IN  EFI_GUID          *ProtocolGuid,

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT VOID              *Registration

+  );

+

+/**

+  This function creates an event using NotifyTpl, NoifyFunction, and NotifyContext.

+  This event is signaled with EfiNamedEventSignal().  This provide the ability for 

+  one or more listeners on the same event named by the GUID specified by Name.

+

+  @param  Name                  Supplies GUID name of the event.

+  @param  NotifyTpl             Supplies the task priority level of the event notifications.

+  @param  NotifyFunction        Supplies the function to notify when the event is signaled.

+  @param  NotifyContext         The context parameter to pass to NotifyFunction. 

+  @param  Registration          A pointer to a memory location to receive the registration value.

+

+  @retval EFI_SUCCESS           A named event was created.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to create the named event.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiNamedEventListen (

+  IN CONST EFI_GUID    *Name,

+  IN EFI_TPL           NotifyTpl,

+  IN EFI_EVENT_NOTIFY  NotifyFunction,

+  IN CONST VOID        *NotifyContext,  OPTIONAL

+  OUT VOID             *Registration    OPTIONAL

+  );

+

+/**

+  This function signals the named event specified by Name.  The named event must 

+  have been created with EfiNamedEventListen().

+

+  @param  Name                  Supplies GUID name of the event.

+

+  @retval EFI_SUCCESS           A named event was signaled.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to signal the named event.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiNamedEventSignal (

+  IN CONST EFI_GUID  *Name

+  );

+

+/**

+  This function initializes a basic mutual exclusion lock to the released state 

+  and returns the lock.  Each lock provides mutual exclusion access at its task 

+  priority level.  Since there is no preemption or multiprocessor support in EFI,

+  acquiring the lock only consists of raising to the locks TPL.

+

+  @param  Lock       A pointer to the lock data structure to initialize.

+  @param  Priority   EFI TPL associated with the lock.

+

+  @return The lock.

+

+**/

+EFI_LOCK *

+EFIAPI

+EfiInitializeLock (

+  IN OUT EFI_LOCK  *Lock,

+  IN EFI_TPL        Priority

+  );

+

+/**

+  This macro initializes the contents of a basic mutual exclusion lock to the 

+  released state.  Each lock provides mutual exclusion access at its task 

+  priority level.  Since there is no preemption or multiprocessor support in EFI,

+  acquiring the lock only consists of raising to the locks TPL.

+

+  @param  Lock      A pointer to the lock data structure to initialize.

+  @param  Priority  The task priority level of the lock.

+

+  @return The lock.

+

+**/

+#define EFI_INITIALIZE_LOCK_VARIABLE(Priority) \

+  {Priority, EFI_TPL_APPLICATION, EfiLockReleased }

+

+

+/**

+  

+  Macro that calls DebugAssert() if an EFI_LOCK structure is not in the locked state.

+

+  If the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set, 

+  then this macro evaluates the EFI_LOCK structure specified by Lock.  If Lock 

+  is not in the locked state, then DebugAssert() is called passing in the source 

+  filename, source line number, and Lock.

+

+  If Lock is NULL, then ASSERT().

+

+  @param  LockParameter  A pointer to the lock to acquire.

+

+**/

+#define ASSERT_LOCKED(LockParameter)                  \

+  do {                                                \

+    if (DebugAssertEnabled ()) {                      \

+      ASSERT (LockParameter != NULL);                 \

+      if ((LockParameter)->Lock != EfiLockAcquired) { \

+        _ASSERT (LockParameter not locked);           \

+      }                                               \

+    }                                                 \

+  } while (FALSE)

+

+

+/**

+  This function raises the system¡¯s current task priority level to the task 

+  priority level of the mutual exclusion lock.  Then, it places the lock in the 

+  acquired state.

+

+  @param  Priority  The task priority level of the lock.

+

+**/

+VOID

+EFIAPI

+EfiAcquireLock (

+  IN EFI_LOCK  *Lock

+  );

+

+/**

+  This function raises the system¡¯s current task priority level to the task 

+  priority level of the mutual exclusion lock.  Then, it attempts to place the 

+  lock in the acquired state.

+

+  @param  Lock              A pointer to the lock to acquire.

+

+  @retval EFI_SUCCESS       The lock was acquired.

+  @retval EFI_ACCESS_DENIED The lock could not be acquired because it is already owned.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiAcquireLockOrFail (

+  IN EFI_LOCK  *Lock

+  );

+

+/**

+  This function transitions a mutual exclusion lock from the acquired state to 

+  the released state, and restores the system¡¯s task priority level to its 

+  previous level.

+

+  @param  Lock  A pointer to the lock to release.

+

+**/

+VOID

+EFIAPI

+EfiReleaseLock (

+  IN EFI_LOCK  *Lock

+  );

+

+/**

+  This function looks up a Unicode string in UnicodeStringTable.  If Language is 

+  a member of SupportedLanguages and a Unicode string is found in UnicodeStringTable

+  that matches the language code specified by Language, then it is returned in 

+  UnicodeString.

+

+  @param  Language                A pointer to the ISO 639-2 language code for the 

+                                  Unicode string to look up and return.

+  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes 

+                                  that the Unicode string table supports.  Language 

+                                  must be a member of this set.

+  @param  UnicodeStringTable      A pointer to the table of Unicode strings.

+  @param  UnicodeString           A pointer to the Unicode string from UnicodeStringTable

+                                  that matches the language specified by Language.

+

+  @retval EFI_SUCCESS             The Unicode string that matches the language 

+                                  specified by Language was found

+                                  in the table of Unicoide strings UnicodeStringTable, 

+                                  and it was returned in UnicodeString.

+  @retval EFI_INVALID_PARAMETER   Language is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is NULL.

+  @retval EFI_UNSUPPORTED         SupportedLanguages is NULL.

+  @retval EFI_UNSUPPORTED         UnicodeStringTable is NULL.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not a 

+                                  member of SupportedLanguages.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not 

+                                  supported by UnicodeStringTable.

+

+**/

+EFI_STATUS

+EFIAPI

+LookupUnicodeString (

+  IN CONST CHAR8                     *Language,

+  IN CONST CHAR8                     *SupportedLanguages,

+  IN CONST EFI_UNICODE_STRING_TABLE  *UnicodeStringTable,

+  OUT CHAR16                         **UnicodeString

+  );

+

+/**

+  This function adds a Unicode string to UnicodeStringTable.

+  If Language is a member of SupportedLanguages then UnicodeString is added to 

+  UnicodeStringTable.  New buffers are allocated for both Language and 

+  UnicodeString.  The contents of Language and UnicodeString are copied into 

+  these new buffers.  These buffers are automatically freed when 

+  FreeUnicodeStringTable() is called.

+

+  @param  Language                A pointer to the ISO 639-2 language code for the Unicode 

+                                  string to add.

+  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes

+                                  that the Unicode string table supports.

+                                  Language must be a member of this set.

+  @param  UnicodeStringTable      A pointer to the table of Unicode strings.

+  @param  UnicodeString           A pointer to the Unicode string to add.

+

+  @retval EFI_SUCCESS             The Unicode string that matches the language 

+                                  specified by Language was found in the table of 

+                                  Unicode strings UnicodeStringTable, and it was 

+                                  returned in UnicodeString.

+  @retval EFI_INVALID_PARAMETER   Language is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is an empty string.

+  @retval EFI_UNSUPPORTED         SupportedLanguages is NULL.

+  @retval EFI_ALREADY_STARTED     A Unicode string with language Language is 

+                                  already present in UnicodeStringTable.

+  @retval EFI_OUT_OF_RESOURCES    There is not enough memory to add another 

+                                  Unicode string to UnicodeStringTable.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not a 

+                                  member of SupportedLanguages.

+

+**/

+EFI_STATUS

+EFIAPI

+AddUnicodeString (

+  IN CONST CHAR8               *Language,

+  IN CONST CHAR8               *SupportedLanguages,

+  IN EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,

+  IN CONST CHAR16              *UnicodeString

+  );

+

+/**

+  This function frees the table of Unicode strings in UnicodeStringTable.

+  If UnicodeStringTable is NULL, then EFI_SUCCESS is returned.

+  Otherwise, each language code, and each Unicode string in the Unicode string 

+  table are freed, and EFI_SUCCESS is returned.

+

+  @param  UnicodeStringTable  A pointer to the table of Unicode strings.

+

+  @retval EFI_SUCCESS         The Unicode string table was freed.

+

+**/

+EFI_STATUS

+EFIAPI

+FreeUnicodeStringTable (

+  IN EFI_UNICODE_STRING_TABLE  *UnicodeStringTable

+  );

+

+/**

+  This function computes and returns the width of the Unicode character 

+  specified by UnicodeChar.

+

+  @param  UnicodeChar   A Unicode character.

+

+  @retval 0             The width if UnicodeChar could not be determined.

+  @retval 1             UnicodeChar is a narrow glyph.

+  @retval 2             UnicodeChar is a wide glyph.

+

+**/

+UINTN

+EFIAPI

+GetGlyphWidth (

+  IN CHAR16  UnicodeChar

+  );

+

+/**

+  This function computes and returns the display length of

+  the Null-terminated Unicode string specified by String.

+  If String is NULL, then 0 is returned.

+  If any of the widths of the Unicode characters in String

+  can not be determined, then 0 is returned.

+

+  @param  String      A pointer to a Null-terminated Unicode string.

+

+  @return The display length of the Null-terminated Unicode string specified by String.

+  

+**/

+UINTN

+EFIAPI

+UnicodeStringDisplayLength (

+  IN CONST CHAR16  *String

+  );

+

+//

+// Functions that abstract early Framework contamination of UEFI.

+//

+/**

+  Signal a Ready to Boot Event.  

+  

+  Create a Ready to Boot Event. Signal it and close it. This causes other 

+  events of the same event group to be signaled in other modules. 

+

+**/

+VOID

+EFIAPI

+EfiSignalEventReadyToBoot (

+  VOID

+  );

+

+/**

+  Signal a Legacy Boot Event.  

+  

+  Create a legacy Boot Event. Signal it and close it. This causes other 

+  events of the same event group to be signaled in other modules. 

+

+**/

+VOID

+EFIAPI

+EfiSignalEventLegacyBoot (

+  VOID

+  );

+

+/**

+  Create a Legacy Boot Event.  

+  

+  Tiano extended the CreateEvent Type enum to add a legacy boot event type. 

+  This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was

+  added and now it's possible to not voilate the UEFI specification by 

+  declaring a GUID for the legacy boot event class. This library supports

+  the R8.5/EFI 1.10 form and R9/UEFI 2.0 form and allows common code to 

+  work both ways.

+

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventLegacyBoot (

+  OUT EFI_EVENT  *LegacyBootEvent

+  );

+

+/**

+  Create an EFI event in the Legacy Boot Event Group and allows

+  the caller to specify a notification function.  

+  

+  This function abstracts the creation of the Legacy Boot Event.

+  The Framework moved from a proprietary to UEFI 2.0 based mechanism.

+  This library abstracts the caller from how this event is created to prevent

+  to code form having to change with the version of the specification supported.

+  If LegacyBootEvent is NULL, then ASSERT().

+

+  @param  NotifyTpl         The task priority level of the event.

+  @param  NotifyFunction    The notification function to call when the event is signaled.

+  @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventLegacyBootEx (

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT EFI_EVENT         *LegacyBootEvent

+  );

+

+/**

+  Create a Read to Boot Event.  

+  

+  Tiano extended the CreateEvent Type enum to add a ready to boot event type. 

+  This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was

+  added and now it's possible to not voilate the UEFI specification and use 

+  the ready to boot event class defined in UEFI 2.0. This library supports

+  the R8.5/EFI 1.10 form and R9/UEFI 2.0 form and allows common code to 

+  work both ways.

+

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventReadyToBoot (

+  OUT EFI_EVENT  *ReadyToBootEvent

+  );

+

+/**

+  Create an EFI event in the Ready To Boot Event Group and allows

+  the caller to specify a notification function.  

+  

+  This function abstracts the creation of the Ready to Boot Event.

+  The Framework moved from a proprietary to UEFI 2.0 based mechanism.

+  This library abstracts the caller from how this event is created to prevent

+  to code form having to change with the version of the specification supported.

+  If ReadyToBootEvent is NULL, then ASSERT().

+

+  @param  NotifyTpl         The task priority level of the event.

+  @param  NotifyFunction    The notification function to call when the event is signaled.

+  @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventReadyToBootEx (

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT EFI_EVENT         *ReadyToBootEvent

+  );

+

+/**

+  Initialize a Firmware Volume (FV) Media Device Path node.

+  

+  Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum

+  so as we move to UEFI 2.0 support we must use a mechanism that conforms with

+  the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed 

+  device path is defined for PIWG extensions of device path. If the code 

+  is compiled to conform with the UEFI 2.0 specification use the new device path

+  else use the old form for backwards compatability.

+

+  @param  FvDevicePathNode  Pointer to a FV device path node to initialize

+  @param  NameGuid          FV file name to use in FvDevicePathNode

+

+**/

+VOID

+EFIAPI

+EfiInitializeFwVolDevicepathNode (

+  IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,

+  IN CONST EFI_GUID                         *NameGuid

+  );

+

+/**

+  Check to see if the Firmware Volume (FV) Media Device Path is valid 

+  

+  Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum

+  so as we move to UEFI 2.0 support we must use a mechanism that conforms with

+  the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed 

+  device path is defined for PIWG extensions of device path. If the code 

+  is compiled to conform with the UEFI 2.0 specification use the new device path

+  else use the old form for backwards compatability. The return value to this

+  function points to a location in FvDevicePathNode and it does not allocate

+  new memory for the GUID pointer that is returned.

+

+  @param  FvDevicePathNode  Pointer to FV device path to check.

+

+  @retval NULL              FvDevicePathNode is not valid.

+  @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.

+

+**/

+EFI_GUID *

+EFIAPI

+EfiGetNameGuidFromFwVolDevicePathNode (

+  IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode

+  );

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Library/UefiRuntimeServicesTableLib.h b/edk2/MdePkg/Include/Library/UefiRuntimeServicesTableLib.h
new file mode 100644
index 0000000..c59851e
--- /dev/null
+++ b/edk2/MdePkg/Include/Library/UefiRuntimeServicesTableLib.h
@@ -0,0 +1,25 @@
+/** @file

+	Library that provides a global pointer to the UEFI Runtime Services Tables

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	UefiRuntimeServicesTableLib.h

+

+**/

+

+#ifndef __UEFI_RUNTIME_SERVICES_TABLE_LIB_H__

+#define __UEFI_RUNTIME_SERVICES_TABLE_LIB_H__

+

+//

+//

+//

+extern EFI_RUNTIME_SERVICES  *gRT;

+

+#endif

diff --git a/edk2/MdePkg/Include/PeiCore.h b/edk2/MdePkg/Include/PeiCore.h
new file mode 100644
index 0000000..f0879c7
--- /dev/null
+++ b/edk2/MdePkg/Include/PeiCore.h
@@ -0,0 +1,48 @@
+/** @file

+

+  Root include file for PEI Core.

+

+  The PEI Core has its own module type since its entry point definition is 

+  unique. This module type should only be used by the PEI core. The build 

+  infrastructure automatically sets EDK_RELEASE_VERSION before including 

+  this file. 

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __PEI_CORE_H__

+#define __PEI_CORE_H__

+

+

+//

+// Check to make sure EDK_RELEASE_VERSION is defined

+//

+#if !defined(EDK_RELEASE_VERSION)

+  #error EDK_RELEASE_VERSION not defined

+#elif (EDK_RELEASE_VERSION == 0)

+  #error EDK_RELEASE_VERSION can not be zero

+#endif

+

+

+

+#include <Common/UefiBaseTypes.h>

+#include <Peim/PeiCis.h>

+

+//

+//StatusCodeDataTypeId needs DebugSupport Protocol definition

+//

+#include <Protocol/DebugSupport.h>

+#include <Common/StatusCodeDataTypeId.h>

+#include <Guid/StatusCodeDataTypeId.h>

+

+#include <Ppi/Pcd.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Peim.h b/edk2/MdePkg/Include/Peim.h
new file mode 100644
index 0000000..97c934b
--- /dev/null
+++ b/edk2/MdePkg/Include/Peim.h
@@ -0,0 +1,53 @@
+/** @file

+

+  Root include file for PEI Modules using the Mde Package.

+

+  PEI Modules follow the public Framwork specifications. This include

+  file supports all the public Framework specificaitons and if you 

+  only want to support PIWG specifications you need to use PiwgPeim.h

+  The build infrastructure automatically sets EDK_RELEASE_VERSION 

+  before including this file. 

+

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __PEIM_H__

+#define __PEIM_H__

+

+

+//

+// Check to make sure EDK_RELEASE_VERSION is defined

+//

+#if !defined(EDK_RELEASE_VERSION)

+  #error EDK_RELEASE_VERSION not defined

+#elif (EDK_RELEASE_VERSION == 0)

+  #error EDK_RELEASE_VERSION can not be zero

+#endif

+

+

+#include <Common/UefiBaseTypes.h>

+#include <Peim/PeiCis.h>

+

+#include <Protocol/Decompress.h>

+

+//

+//StatusCodeDataTypeId needs DebugSupport Protocol definition

+//

+#include <Protocol/DebugSupport.h>

+#include <Common/StatusCodeDataTypeId.h>

+#include <Guid/StatusCodeDataTypeId.h>

+#include <Guid/GlobalVariable.h>

+

+#include <Ppi/Pcd.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Peim/PeiCis.h b/edk2/MdePkg/Include/Peim/PeiCis.h
new file mode 100644
index 0000000..91a77ef
--- /dev/null
+++ b/edk2/MdePkg/Include/Peim/PeiCis.h
@@ -0,0 +1,671 @@
+/** @file
+  Framework PEI master include file. This file should match the PEI CIS spec.
+
+  Copyright (c) 2006, Intel Corporation                                                         
+  All rights reserved. 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.             
+
+  Module Name:  PeiCis.h
+
+  @par Revision Reference:
+  Version 0.91.
+
+**/
+
+#ifndef __PEIM_CIS_H__
+#define __PEIM_CIS_H__
+
+#include <Common/MultiPhase.h>
+#include <Common/BootMode.h>
+#include <Common/Hob.h>
+#include <Common/FirmwareVolumeImageFormat.h>
+#include <Common/FirmwareVolumeHeader.h>
+#include <Common/FirmwareFileSystem.h>
+#include <Common/Dependency.h>
+
+#define TIANO_ERROR(a)              (MAX_2_BITS | (a))
+
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+//
+// Tiano added a couple of return types. These are owned by UEFI specification
+//  and Tiano can not use them. Thus for UEFI 2.0/R9 support we moved the values
+//  to a UEFI OEM extension range to conform to UEFI specification.
+//
+#define EFI_NOT_AVAILABLE_YET   EFIERR (28)
+#define EFI_UNLOAD_IMAGE        EFIERR (29)
+#else
+#define EFI_NOT_AVAILABLE_YET   TIANO_ERROR (0)
+#define EFI_UNLOAD_IMAGE        TIANO_ERROR (1)
+#endif
+
+//
+// Declare forward referenced data structures
+//
+typedef struct _EFI_PEI_SERVICES          EFI_PEI_SERVICES;
+typedef struct _EFI_PEI_NOTIFY_DESCRIPTOR EFI_PEI_NOTIFY_DESCRIPTOR;
+
+
+#include <Ppi/CpuIo.h>
+#include <Ppi/PciCfg.h>
+
+//
+// PEI Specification Revision information
+//
+#define PEI_SPECIFICATION_MAJOR_REVISION  0
+#define PEI_SPECIFICATION_MINOR_REVISION  91
+
+/**
+  The PEI Dispatcher will invoke each PEIM one time.  During this pass, the PEI 
+  Dispatcher will pass control to the PEIM at the AddressOfEntryPoint in the PE Header. 
+
+  @param  FfsHeader Pointer to the FFS file header. 
+  
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @return Status code
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEIM_ENTRY_POINT)(
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN EFI_PEI_SERVICES          **PeiServices
+  );
+
+/**
+  Entry point of the notification callback function itself within the PEIM.
+
+  @param  PeiServices Indirect reference to the PEI Services Table.
+  
+  @param  NotifyDescriptor Address of the notification descriptor data structure.
+  
+  @param  Ppi Address of the PPI that was installed.
+
+  @return Status code
+  
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEIM_NOTIFY_ENTRY_POINT) (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+//
+// PEI Ppi Services List Descriptors
+//
+#define EFI_PEI_PPI_DESCRIPTOR_PIC              0x00000001
+#define EFI_PEI_PPI_DESCRIPTOR_PPI              0x00000010
+#define EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK  0x00000020
+#define EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH  0x00000040
+#define EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES     0x00000060
+#define EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST   0x80000000
+
+typedef struct {
+  UINTN     Flags;
+  EFI_GUID  *Guid;
+  VOID      *Ppi;
+} EFI_PEI_PPI_DESCRIPTOR;
+
+struct _EFI_PEI_NOTIFY_DESCRIPTOR {
+  UINTN                       Flags;
+  EFI_GUID                    *Guid;
+  EFI_PEIM_NOTIFY_ENTRY_POINT Notify;
+};
+
+/**
+  This service is the first one provided by the PEI Foundation.  This function 
+  installs an interface in the PEI PPI database by GUID.  The purpose of the 
+  service is to publish an interface that other parties can use to call 
+  additional PEIMs.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table 
+  published by the PEI Foundation. 
+  
+  @param  PpiList A pointer to the list of interfaces that the caller shall install.
+
+  @retval EFI_SUCCESS The interface was successfully installed.
+  
+  @retval EFI_INVALID_PARAMETER The PpiList pointer is NULL or Any of the PEI PPI descriptors in the list do not have the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field. 
+  
+  @retval EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_INSTALL_PPI) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN EFI_PEI_PPI_DESCRIPTOR      *PpiList
+  );
+
+/**
+  This function reinstalls an interface in the PEI PPI database by GUID. 
+  The purpose of the service is to publish an interface that other parties 
+  can use to replace a same-named interface in the protocol database 
+  with a different interface. 
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table 
+  published by the PEI Foundation. 
+  
+  @param  OldPpi A pointer to the former PPI in the database. 
+  
+  @param  NewPpi A pointer to the new interfaces that the caller shall install.
+
+  @retval EFI_SUCCESS The interface was successfully installed.
+  
+  @retval EFI_INVALID_PARAMETER The PpiList pointer is NULL or Any of the PEI PPI descriptors in the list do not have the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field. 
+  
+  @retval EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.
+  
+  @retval EFI_NOT_FOUND The PPI for which the reinstallation was requested has not been installed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_REINSTALL_PPI) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN EFI_PEI_PPI_DESCRIPTOR          *OldPpi,
+  IN EFI_PEI_PPI_DESCRIPTOR          *NewPpi
+  );
+
+/**
+  This function locates an interface in the PEI PPI database by GUID. 
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES published by the PEI Foundation.
+  
+  @param  Guid A pointer to the GUID whose corresponding interface needs to be found.
+  
+  @param  Instance The N-th instance of the interface that is required.
+  
+  @param  PpiDescriptor A pointer to instance of the EFI_PEI_PPI_DESCRIPTOR.
+  
+  @param  Ppi A pointer to the instance of the interface.  
+
+  @retval EFI_SUCCESS The interface was successfully returned.
+  
+  @retval EFI_NOT_FOUND The PPI descriptor is not found in the database.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_LOCATE_PPI) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN EFI_GUID                    *Guid,
+  IN UINTN                       Instance,
+  IN OUT EFI_PEI_PPI_DESCRIPTOR  **PpiDescriptor,
+  IN OUT VOID                    **Ppi
+  );
+
+/**
+  This function installs a notification service to be called back when a 
+  given interface is installed or reinstalled.  The purpose of the service 
+  is to publish an interface that other parties can use to call additional PPIs 
+  that may materialize later.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  
+  @param  NotifyList A pointer to the list of notification interfaces that the caller shall install.
+
+  @retval EFI_SUCCESS The interface was successfully installed.
+  
+  @retval EFI_INVALID_PARAMETER The PpiList pointer is NULL or Any of the PEI PPI descriptors in the list do not have the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field. 
+  
+  @retval EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_NOTIFY_PPI) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR       *NotifyList
+  );
+
+/**
+  This function returns the present value of the boot mode.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. 
+  
+  @param  BootMode A pointer to contain the value of the boot mode.
+
+  @retval EFI_SUCCESS The boot mode was returned successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_GET_BOOT_MODE) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  OUT EFI_BOOT_MODE              *BootMode
+  );
+
+/**
+  This function sets the value of the boot mode.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  
+  @param  BootMode The value of the boot mode to set.
+
+  @retval EFI_SUCCESS The boot mode was returned successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_SET_BOOT_MODE) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN EFI_BOOT_MODE               BootMode
+  );
+
+/**
+  This function returns the pointer to the list of Hand-Off Blocks (HOBs) in memory. 
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  
+  @param  HobList A pointer to the list of HOBs that the PEI Foundation will initialize
+
+  @retval EFI_SUCCESS The list was successfully returned.
+  
+  @retval EFI_NOT_AVAILABLE_YET The HOB list is not yet published.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_GET_HOB_LIST) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN OUT VOID                    **HobList
+  );
+
+/**
+  This service published by the PEI Foundation abstracts the creation of a Hand-Off Block's (HOB¡¯s) headers.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  Type The type of HOB to be installed.
+  
+  @param  Length The length of the HOB to be added.
+  
+  @param  Hob The address of a pointer that will contain the HOB header.
+
+  @retval EFI_SUCCESS The HOB was successfully created.
+  
+  @retval EFI_OUT_OF_RESOURCES There is no additional space for HOB creation.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_CREATE_HOB) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN UINT16                      Type,
+  IN UINT16                      Length,
+  IN OUT VOID                    **Hob
+  );
+
+/**
+  The purpose of the service is to abstract the capability of the PEI 
+  Foundation to discover instances of firmware volumes in the system. 
+  Given the input file pointer, this service searches for the next 
+  matching file in the Firmware File System (FFS) volume.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  Instance This instance of the firmware volume to find.  The value 0 is the Boot Firmware Volume (BFV).
+  
+  @param  FwVolHeader Pointer to the firmware volume header of the volume to return.
+
+  @retval EFI_SUCCESS The volume was found.
+  
+  @retval EFI_NOT_FOUND The volume was not found.
+  
+  @retval EFI_INVALID_PARAMETER FwVolHeader is NULL
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FFS_FIND_NEXT_VOLUME) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN UINTN                           Instance,
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER  **FwVolHeader
+  );
+
+/**
+  The purpose of the service is to abstract the capability of the PEI 
+  Foundation to discover instances of firmware files in the system. 
+  Given the input file pointer, this service searches for the next matching 
+  file in the Firmware File System (FFS) volume.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  SearchType A filter to find files only of this type.
+  
+  @param  FwVolHeader Pointer to the firmware volume header of the volume to search.This parameter must point to a valid FFS volume.
+  
+  @param  FileHeader Pointer to the current file from which to begin searching.This pointer will be updated upon return to reflect the file found.
+
+  @retval EFI_SUCCESS The file was found.
+  
+  @retval EFI_NOT_FOUND The file was not found.
+  
+  @retval EFI_NOT_FOUND The header checksum was not zero.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FFS_FIND_NEXT_FILE) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN EFI_FV_FILETYPE             SearchType,
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,
+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader
+  );
+
+/**
+  Given the input file pointer, this service searches for the next 
+  matching file in the Firmware File System (FFS) volume. 
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  SectionType The value of the section type to find.
+  
+  @param  FfsFileHeader A pointer to the file header that contains the set of sections to be searched.
+  
+  @param  SectionData A pointer to the discovered section, if successful.
+
+  @retval EFI_SUCCESS The section was found.
+  
+  @retval EFI_NOT_FOUND The section was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FFS_FIND_SECTION_DATA) (
+  IN EFI_PEI_SERVICES            **PeiServices,
+  IN EFI_SECTION_TYPE            SectionType,
+  IN EFI_FFS_FILE_HEADER         *FfsFileHeader,
+  IN OUT VOID                    **SectionData
+  );
+
+/**
+  This function registers the found memory configuration with the PEI Foundation.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  MemoryBegin The value of a region of installed memory
+  
+  @param  MemoryLength The corresponding length of a region of installed memory.
+
+  @retval EFI_SUCCESS The region was successfully installed in a HOB.
+  
+  @retval EFI_INVALID_PARAMETER MemoryBegin and MemoryLength are illegal for this system.
+  
+  @retval EFI_OUT_OF_RESOURCES There is no additional space for HOB creation.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_INSTALL_PEI_MEMORY) (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS       MemoryBegin,
+  IN UINT64                     MemoryLength
+  );
+
+/**
+  The purpose of the service is to publish an interface that allows 
+  PEIMs to allocate memory ranges that are managed by the PEI Foundation.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  MemoryType The type of memory to allocate. 
+  
+  @param  Pages The number of contiguous 4 KB pages to allocate.
+  
+  @param  Memory Pointer to a physical address. On output, the address is set to the base of the page range that was allocated.
+
+  @retval EFI_SUCCESS The memory range was successfully allocated.
+  
+  @retval EFI_OUT_OF_RESOURCES  The pages could not be allocated.
+  
+  @retval EFI_INVALID_PARAMETER Type is not equal to AllocateAnyPages.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_ALLOCATE_PAGES) (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_MEMORY_TYPE            MemoryType,
+  IN UINTN                      Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS   *Memory
+  );
+
+/**
+  The purpose of this service is to publish an interface that 
+  allows PEIMs to allocate memory ranges that are managed by the PEI Foundation.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  Size The number of bytes to allocate from the pool.
+  
+  @param  Buffer If the call succeeds, a pointer to a pointer to the allocated buffer; undefined otherwise.
+
+  @retval EFI_SUCCESS The allocation was successful.
+  
+  @retval EFI_OUT_OF_RESOURCES There is not enough heap to allocate the requested size.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_ALLOCATE_POOL) (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN UINTN                      Size,
+  OUT VOID                      **Buffer
+  );
+
+/**
+  This service copies the contents of one buffer to another buffer.
+
+  @param  Destination Pointer to the destination buffer of the memory copy.
+  
+  @param  Source Pointer to the source buffer of the memory copy
+  
+  @param  Length Number of bytes to copy from Source to Destination.
+
+  @return None
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_PEI_COPY_MEM) (
+  IN VOID                       *Destination,
+  IN VOID                       *Source,
+  IN UINTN                      Length
+  );
+
+/**
+  The service fills a buffer with a specified value.
+
+  @param  Buffer Pointer to the buffer to fill.
+  
+  @param  Size Number of bytes in Buffer to fill.
+  
+  @param  Value Value to fill Buffer with
+
+  @return None
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_PEI_SET_MEM) (
+  IN VOID                       *Buffer,
+  IN UINTN                      Size,
+  IN UINT8                      Value
+  );
+
+/**
+  This service publishes an interface that allows PEIMs to report status codes.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  
+  @param  Type Indicates the type of status code being reported. 
+  
+  @param  Value Describes the current status of a hardware or 
+  software entity.  This includes information about the class and 
+  subclass that is used to classify the entity as well as an operation.
+  For progress codes, the operation is the current activity.
+  For error codes, it is the exception.For debug codes,it is not defined at this time. 
+  
+  @param  Instance The enumeration of a hardware or software entity within 
+  the system.  A system may contain multiple entities that match a class/subclass 
+  pairing.  The instance differentiates between them.  An instance of 0 indicates 
+  that instance information is unavailable, not meaningful, or not relevant.
+  Valid instance numbers start with 1.
+  
+  @param  CallerId This optional parameter may be used to identify the caller. 
+  This parameter allows the status code driver to apply different rules to 
+  different callers.
+  
+  @param  Data This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS The function completed successfully. 
+  
+  @retval EFI_NOT_AVAILABLE_YET No progress code provider has installed an interface in the system.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_REPORT_STATUS_CODE) (
+  IN EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE     Type,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId OPTIONAL,
+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  );
+
+/**
+  Resets the entire platform.
+
+  @param  PeiServices An indirect pointer to the EFI_PEI_SERVICES 
+  table published by the PEI Foundation.
+
+  @retval EFI_SUCCESS The function completed successfully. 
+  
+  @retval EFI_NOT_AVAILABLE_YET The service has not been installed yet.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_RESET_SYSTEM) (
+  IN EFI_PEI_SERVICES   **PeiServices
+  );
+
+//
+// EFI PEI Services Table
+//
+#define PEI_SERVICES_SIGNATURE  0x5652455320494550ULL
+#define PEI_SERVICES_REVISION   ((PEI_SPECIFICATION_MAJOR_REVISION << 16) | (PEI_SPECIFICATION_MINOR_REVISION))
+
+struct _EFI_PEI_SERVICES {
+  EFI_TABLE_HEADER              Hdr;
+
+  //
+  // PPI Functions
+  //
+  EFI_PEI_INSTALL_PPI           InstallPpi;
+  EFI_PEI_REINSTALL_PPI         ReInstallPpi;
+  EFI_PEI_LOCATE_PPI            LocatePpi;
+  EFI_PEI_NOTIFY_PPI            NotifyPpi;
+
+  //
+  // Boot Mode Functions
+  //
+  EFI_PEI_GET_BOOT_MODE         GetBootMode;
+  EFI_PEI_SET_BOOT_MODE         SetBootMode;
+
+  //
+  // HOB Functions
+  //
+  EFI_PEI_GET_HOB_LIST          GetHobList;
+  EFI_PEI_CREATE_HOB            CreateHob;
+
+  //
+  // Filesystem Functions
+  //
+  EFI_PEI_FFS_FIND_NEXT_VOLUME  FfsFindNextVolume;
+  EFI_PEI_FFS_FIND_NEXT_FILE    FfsFindNextFile;
+  EFI_PEI_FFS_FIND_SECTION_DATA FfsFindSectionData;
+
+  //
+  // Memory Functions
+  //
+  EFI_PEI_INSTALL_PEI_MEMORY    InstallPeiMemory;
+  EFI_PEI_ALLOCATE_PAGES        AllocatePages;
+  EFI_PEI_ALLOCATE_POOL         AllocatePool;
+  EFI_PEI_COPY_MEM              CopyMem;
+  EFI_PEI_SET_MEM               SetMem;
+
+  //
+  // Status Code
+  //
+  EFI_PEI_REPORT_STATUS_CODE    PeiReportStatusCode;
+
+  //
+  // Reset
+  //
+  EFI_PEI_RESET_SYSTEM          PeiResetSystem;
+
+  //
+  // Pointer to PPI interface
+  //
+  EFI_PEI_CPU_IO_PPI            *CpuIo;
+  EFI_PEI_PCI_CFG_PPI           *PciCfg;
+
+};
+
+typedef struct {
+  UINTN                   BootFirmwareVolume;
+  UINTN                   SizeOfCacheAsRam;
+  EFI_PEI_PPI_DESCRIPTOR  *DispatchTable;
+} EFI_PEI_STARTUP_DESCRIPTOR;
+
+#include <Common/EfiImage.h>
+#include <Common/StatusCode.h>
+#include <Common/BootScript.h>
+#include <Common/Capsule.h>
+
+#include <Guid/Apriori.h>
+#include <Guid/Capsule.h>
+#include <Guid/DxeServices.h>
+#include <Guid/HobList.h>
+#include <Guid/MemoryAllocationHob.h>
+#include <Guid/FirmwareFileSystem.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Guid/GlobalVariable.h>
+
+#include <Ppi/BlockIo.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/BootScriptExecuter.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Ppi/DxeIpl.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/FindFv.h>
+#include <Ppi/LoadFile.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/Pcd.h>
+#include <Ppi/ReadOnlyVariable.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/Reset.h>
+#include <Ppi/S3Resume.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SectionExtraction.h>
+#include <Ppi/Security.h>
+#include <Ppi/Smbus.h>
+#include <Ppi/Stall.h>
+#include <Ppi/StatusCode.h>
+
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/Pcd.h>
+
+#endif
diff --git a/edk2/MdePkg/Include/PeimDepex.h b/edk2/MdePkg/Include/PeimDepex.h
new file mode 100644
index 0000000..a392e50
--- /dev/null
+++ b/edk2/MdePkg/Include/PeimDepex.h
@@ -0,0 +1,54 @@
+/** @file

+

+  Include file for PEI Dependency Expresion *.DXS file. 

+

+  This include file is only for Dependency Expression *.DXS files and 

+  should not be include directly in modules. 

+

+  DEPEX (DEPendency EXpresion) BNF Grammer for PEI:

+  The BNF grammar is thus:

+<pre>

+     <depex>   ::= <bool>            

+     <bool>    ::= <bool> and <term> 

+                 | <bool> or <term>  

+                 | <term>            

+     <term>    ::= not <factor>      

+                 | <factor>          

+     <factor>  ::= <bool>            

+                 | <boolval>         

+                 | <depinst>         

+                 | <termval>         

+     <boolval> ::= true              

+                 | false             

+     <depinst> ::= push GUID         

+     <termval> ::= end               

+</pre>

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __PEIM_DEPEX_H__

+#define __PEIM_DEPEX_H__

+

+//

+// The Depex grammer needs the following strings so we must undo

+// any pre-processor redefinitions

+//

+#undef DEPENDENCY_START                          

+#undef AND                

+#undef OR                 

+#undef NOT                

+#undef TRUE               

+#undef FALSE                                        

+#undef DEPENDENCY_END     

+

+#endif

diff --git a/edk2/MdePkg/Include/PiwgDxe.h b/edk2/MdePkg/Include/PiwgDxe.h
new file mode 100644
index 0000000..a8310bc
--- /dev/null
+++ b/edk2/MdePkg/Include/PiwgDxe.h
@@ -0,0 +1,26 @@
+/** @file

+

+  Root include file for Mde Package PIWG DXE modules.

+

+  This file is currently not implement since the PIWG has not yet released

+  an official specificaiton. In the future it will allow the construction

+  of a DXE module that strictly follows PIWG specifications.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __PIWG_DXE_H__

+#define __PIWG_DXE_H__

+

+#error No Approved PIWG specification exists

+

+#endif

diff --git a/edk2/MdePkg/Include/PiwgPeim.h b/edk2/MdePkg/Include/PiwgPeim.h
new file mode 100644
index 0000000..aaa5f5a
--- /dev/null
+++ b/edk2/MdePkg/Include/PiwgPeim.h
@@ -0,0 +1,25 @@
+/** @file

+

+  Root include file for Mde Package PIWG PEIM modules.

+

+  This file is currently not implement since the PIWG has not yet released

+  an official specificaiton. In the future it will allow the construction

+  of a PEIM module that strictly follows PIWG specifications.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __PIWG_PEIM_H__

+#define __PIWG_PEIM_H__

+

+#error No approved PIWG Specification exists

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/BlockIo.h b/edk2/MdePkg/Include/Ppi/BlockIo.h
new file mode 100644
index 0000000..debcc0c
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/BlockIo.h
@@ -0,0 +1,161 @@
+/** @file

+  This file declares BlockIo PPI used to access block-oriented storage devices

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BlockIo.h

+

+  @par Revision Reference:

+  This PPI is defined in Framework of EFI Recovery Spec

+  Version 0.9

+

+**/

+

+#ifndef _PEI_BLOCK_IO_H_

+#define _PEI_BLOCK_IO_H_

+

+#define EFI_PEI_VIRTUAL_BLOCK_IO_PPI \

+  { \

+    0x695d8aa1, 0x42ee, 0x4c46, {0x80, 0x5c, 0x6e, 0xa6, 0xbc, 0xe7, 0x99, 0xe3 } \

+  }

+

+typedef struct _EFI_PEI_RECOVERY_BLOCK_IO_PPI EFI_PEI_RECOVERY_BLOCK_IO_PPI;

+

+typedef UINT64  EFI_PEI_LBA;

+

+typedef enum {

+  LegacyFloppy  = 0,

+  IdeCDROM      = 1,

+  IdeLS120      = 2,

+  UsbMassStorage= 3,

+  MaxDeviceType

+} EFI_PEI_BLOCK_DEVICE_TYPE;

+

+typedef struct {

+  EFI_PEI_BLOCK_DEVICE_TYPE  DeviceType;

+  BOOLEAN                    MediaPresent;

+  UINTN                      LastBlock;

+  UINTN                      BlockSize;

+} EFI_PEI_BLOCK_IO_MEDIA;

+

+/**

+  Gets the count of block I/O devices that one specific block driver detects.

+

+  @param  PeiServices General-purpose services that are available to every PEIM.

+  

+  @param  This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.

+  

+  @param  NumberBlockDevices The number of block I/O devices discovered.

+

+  @return Status code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_GET_NUMBER_BLOCK_DEVICES) (

+  IN  EFI_PEI_SERVICES                         **PeiServices,

+  IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI            *This,

+  OUT UINTN                                    *NumberBlockDevices

+  );

+

+/**

+  Gets a block device¡¯s media information.

+

+  @param  PeiServices General-purpose services that are available to every PEIM

+  

+  @param  This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. 

+  

+  @param  DeviceIndex Specifies the block device to which the function 

+  wants to talk. Because the driver that implements Block I/O PPIs 

+  will manage multiple block devices, the PPIs that want to talk to a single 

+  device must specify the device index that was assigned during the enumeration 

+  process. This index is a number from one to NumberBlockDevices.

+  

+  @param  MediaInfo The media information of the specified block media.

+

+  @retval EFI_SUCCESS Media information about the specified block device was obtained successfully.

+  

+  @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_GET_DEVICE_MEDIA_INFORMATION) (

+  IN  EFI_PEI_SERVICES                         **PeiServices,

+  IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI            *This,

+  IN  UINTN                                    DeviceIndex,

+  OUT EFI_PEI_BLOCK_IO_MEDIA                   *MediaInfo

+  );

+

+/**

+  Reads the requested number of blocks from the specified block device.

+

+  @param  PeiServices General-purpose services that are available to every PEIM.

+  

+  @param  This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.

+  

+  @param  DeviceIndex Specifies the block device to which the function wants to talk.

+  

+  @param  StartLBA The starting logical block address (LBA) to read from on the device

+  

+  @param  BufferSize The size of the Buffer in bytes. This number must 

+  be a multiple of the intrinsic block size of the device.

+  

+  @param  Buffer A pointer to the destination buffer for the data.

+  The caller is responsible for the ownership of the buffer.

+

+  @retval EFI_SUCCESS The data was read correctly from the device.

+  

+  @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the read operation.

+  

+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,

+  or the buffer is not properly aligned.

+  

+  @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of 

+  the intrinsic block size of the device.

+  

+  @retval EFI_NO_MEDIA There is no media in the device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_READ_BLOCKS) (

+  IN  EFI_PEI_SERVICES                         **PeiServices,

+  IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI            *This,

+  IN  UINTN                                    DeviceIndex,

+  IN  EFI_PEI_LBA                              StartLBA,

+  IN  UINTN                                    BufferSize,

+  OUT VOID                                     *Buffer

+  );

+

+/**

+  @par Ppi Description:

+  EFI_PEI_RECOVERY_BLOCK_IO_PPI provides the services that are required 

+  to access a block I/O device during PEI recovery boot mode. 

+

+  @param GetNumberOfBlockDevices

+  Gets the number of block I/O devices that the specific block driver manages.

+

+  @param GetBlockDeviceMediaInfo

+  Gets the specified media information.

+

+  @param ReadBlocks

+  Reads the requested number of blocks from the specified block device.

+

+**/

+struct _EFI_PEI_RECOVERY_BLOCK_IO_PPI {

+  EFI_PEI_GET_NUMBER_BLOCK_DEVICES      GetNumberOfBlockDevices;

+  EFI_PEI_GET_DEVICE_MEDIA_INFORMATION  GetBlockDeviceMediaInfo;

+  EFI_PEI_READ_BLOCKS                   ReadBlocks;

+};

+

+extern EFI_GUID gEfiPeiBlockIoPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/BootInRecoveryMode.h b/edk2/MdePkg/Include/Ppi/BootInRecoveryMode.h
new file mode 100644
index 0000000..f15d570
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/BootInRecoveryMode.h
@@ -0,0 +1,33 @@
+/** @file

+  This PPI is installed by the platform PEIM to designate that a recovery boot 

+  is in progress.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BootInRecoveryMode.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS spec

+  Version 0.91.

+

+**/

+

+#ifndef __BOOT_IN_RECOVERY_MODE_PPI_H__

+#define __BOOT_IN_RECOVERY_MODE_PPI_H__

+

+#define EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI \

+  { \

+    0x17ee496a, 0xd8e4, 0x4b9a, {0x94, 0xd1, 0xce, 0x82, 0x72, 0x30, 0x8, 0x50 } \

+  }

+

+

+extern EFI_GUID gEfiPeiBootInRecoveryModePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/BootScriptExecuter.h b/edk2/MdePkg/Include/Ppi/BootScriptExecuter.h
new file mode 100644
index 0000000..b73396d
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/BootScriptExecuter.h
@@ -0,0 +1,78 @@
+/** @file

+  This file declares Boot Script Executer PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BootScriptExecuter.h

+

+  @par Revision Reference:

+  This PPI is defined in Framework of EFI BootScript spec.

+  Version 0.91.

+

+**/

+

+#ifndef _PEI_BOOT_SCRIPT_EXECUTER_PPI_H

+#define _PEI_BOOT_SCRIPT_EXECUTER_PPI_H

+

+#define EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID \

+  { \

+    0xabd42895, 0x78cf, 0x4872, {0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xff } \

+  }

+

+typedef struct _EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI;

+

+/**

+  Executes the Framework boot script table.

+

+  @param  PeiServices A pointer to the system PEI Services Table.

+  

+  @param  This A pointer to the EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI instance.

+  

+  @param  Address The physical memory address where the table is stored. 

+  It must be zero if the table to be executed is stored in a firmware volume file.

+  

+  @param  FvFile The firmware volume file name that contains the table to 

+  be executed. It must be NULL if the table to be executed is stored in physical memory.

+

+  @retval EFI_SUCCESS The boot script table was executed successfully.

+  

+  @retval EFI_INVALID_PARAMETER Address is zero and FvFile is NULL.

+  

+  @retval EFI_NOT_FOUND The file name specified in FvFile cannot be found.

+  

+  @retval EFI_UNSUPPORTED The format of the boot script table is invalid.

+  Or An unsupported opcode occurred in the table.

+  Or There were opcode execution errors, such as an insufficient dependency.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_BOOT_SCRIPT_EXECUTE) (

+  IN     EFI_PEI_SERVICES                        **PeiServices,

+  IN     EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI        *This,

+  IN     EFI_PHYSICAL_ADDRESS                    Address,

+  IN     EFI_GUID                                *FvFile OPTIONAL

+  );

+

+/**

+  @par Ppi Description:

+  This PPI produces functions to interpret and execute the Framework boot script table.

+

+  @param Execute

+  Executes a boot script table.

+

+**/

+struct _EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI {

+  EFI_PEI_BOOT_SCRIPT_EXECUTE Execute;

+};

+

+extern EFI_GUID gEfiPeiBootScriptExecuterPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/CpuIo.h b/edk2/MdePkg/Include/Ppi/CpuIo.h
new file mode 100644
index 0000000..0387033
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/CpuIo.h
@@ -0,0 +1,520 @@
+/** @file

+  This file declares CPU IO PPI that abstracts CPU IO access

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  CpuIo.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __PEI_CPUIO_PPI_H__

+#define __PEI_CPUIO_PPI_H__

+

+#define EFI_PEI_CPU_IO_PPI_INSTALLED_GUID \

+  { \

+    0xe6af1f7b, 0xfc3f, 0x46da, {0xa8, 0x28, 0xa3, 0xb4, 0x57, 0xa4, 0x42, 0x82 } \

+  }

+

+typedef struct _EFI_PEI_CPU_IO_PPI  EFI_PEI_CPU_IO_PPI;

+

+//

+// *******************************************************

+// EFI_PEI_CPU_IO_PPI_WIDTH

+// *******************************************************

+//

+typedef enum {

+  EfiPeiCpuIoWidthUint8,

+  EfiPeiCpuIoWidthUint16,

+  EfiPeiCpuIoWidthUint32,

+  EfiPeiCpuIoWidthUint64,

+  EfiPeiCpuIoWidthFifoUint8,

+  EfiPeiCpuIoWidthFifoUint16,

+  EfiPeiCpuIoWidthFifoUint32,

+  EfiPeiCpuIoWidthFifoUint64,

+  EfiPeiCpuIoWidthFillUint8,

+  EfiPeiCpuIoWidthFillUint16,

+  EfiPeiCpuIoWidthFillUint32,

+  EfiPeiCpuIoWidthFillUint64,

+  EfiPeiCpuIoWidthMaximum

+} EFI_PEI_CPU_IO_PPI_WIDTH;

+

+/**

+  Memory-based access services and I/O-based access services.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Width The width of the access.  Enumerated in bytes.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Count The number of accesses to perform.

+  

+  @param  Buffer A pointer to the buffer of data.

+

+  @retval EFI_SUCCESS  The function completed successfully. 

+  

+  @retval EFI_NOT_YET_AVAILABLE  The service has not been installed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_MEM) (

+  IN  EFI_PEI_SERVICES                  **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI                *This,

+  IN  EFI_PEI_CPU_IO_PPI_WIDTH          Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *Buffer

+  );

+

+//

+// *******************************************************

+// EFI_PEI_CPU_IO_PPI_ACCESS

+// *******************************************************

+//

+typedef struct {

+  EFI_PEI_CPU_IO_PPI_IO_MEM Read;

+  EFI_PEI_CPU_IO_PPI_IO_MEM Write;

+} EFI_PEI_CPU_IO_PPI_ACCESS;

+

+/**

+  8-bit I/O read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT8

+

+**/

+typedef

+UINT8

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_READ8) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  16-bit I/O read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT16

+

+**/

+typedef

+UINT16

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_READ16) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  32-bit I/O read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT32

+

+**/

+typedef

+UINT32

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_READ32) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  64-bit I/O read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT64

+

+**/

+typedef

+UINT64

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_READ64) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  8-bit I/O write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_WRITE8) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT8                   Data

+  );

+

+/**

+  16-bit I/O write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_WRITE16) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT16                  Data

+  );

+

+/**

+  32-bit I/O write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_WRITE32) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT32                  Data

+  );

+

+/**

+  64-bit I/O write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_IO_WRITE64) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT64                  Data

+  );

+

+/**

+  8-bit Memory read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT8

+

+**/

+typedef

+UINT8

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_READ8) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  16-bit Memory read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT16

+

+**/

+typedef

+UINT16

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_READ16) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  32-bit Memory read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT32

+

+**/

+typedef

+UINT32

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_READ32) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  64-bit Memory read operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+

+  @return UINT64

+

+**/

+typedef

+UINT64

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_READ64) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address

+  );

+

+/**

+  8-bit Memory write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_WRITE8) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT8                   Data

+  );

+

+/**

+  16-bit Memory write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_WRITE16) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT16                  Data

+  );

+

+/**

+  32-bit Memory write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_WRITE32) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT32                  Data

+  );

+

+/**

+  64-bit Memory write operations.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Data The data to write.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_PEI_CPU_IO_PPI_MEM_WRITE64) (

+  IN  EFI_PEI_SERVICES        **PeiServices,

+  IN  EFI_PEI_CPU_IO_PPI      *This,

+  IN  UINT64                  Address,

+  IN  UINT64                  Data

+  );

+

+/**

+  @par Ppi Description:

+  EFI_PEI_CPU_IO_PPI provides a set of memory and I/O-based services.

+  The perspective of the services is that of the processor, not the bus or system.

+

+  @param Mem

+  Collection of memory-access services.

+

+  @param I/O

+  Collection of I/O-access services.

+

+  @param IoRead8

+  8-bit read service.

+

+  @param IoRead16

+  16-bit read service.

+

+  @param IoRead32

+  32-bit read service.

+

+  @param IoRead64

+  64-bit read service.

+

+  @param IoWrite8

+  8-bit write service.

+

+  @param IoWrite16

+  16-bit write service.

+

+  @param IoWrite32

+  32-bit write service.

+

+  @param IoWrite64

+  64-bit write service.

+

+  @param MemRead8

+  8-bit read service.

+

+  @param MemRead16

+  16-bit read service.

+

+  @param MemRead32

+  32-bit read service.

+

+  @param MemRead64

+  64-bit read service.

+

+  @param MemWrite8

+  8-bit write service.

+

+  @param MemWrite16

+  16-bit write service.

+

+  @param MemWrite32

+  32-bit write service.

+

+  @param MemWrite64

+  64-bit write service.

+

+**/

+struct _EFI_PEI_CPU_IO_PPI {

+  EFI_PEI_CPU_IO_PPI_ACCESS       Mem;

+  EFI_PEI_CPU_IO_PPI_ACCESS       Io;

+  EFI_PEI_CPU_IO_PPI_IO_READ8     IoRead8;

+  EFI_PEI_CPU_IO_PPI_IO_READ16    IoRead16;

+  EFI_PEI_CPU_IO_PPI_IO_READ32    IoRead32;

+  EFI_PEI_CPU_IO_PPI_IO_READ64    IoRead64;

+  EFI_PEI_CPU_IO_PPI_IO_WRITE8    IoWrite8;

+  EFI_PEI_CPU_IO_PPI_IO_WRITE16   IoWrite16;

+  EFI_PEI_CPU_IO_PPI_IO_WRITE32   IoWrite32;

+  EFI_PEI_CPU_IO_PPI_IO_WRITE64   IoWrite64;

+  EFI_PEI_CPU_IO_PPI_MEM_READ8    MemRead8;

+  EFI_PEI_CPU_IO_PPI_MEM_READ16   MemRead16;

+  EFI_PEI_CPU_IO_PPI_MEM_READ32   MemRead32;

+  EFI_PEI_CPU_IO_PPI_MEM_READ64   MemRead64;

+  EFI_PEI_CPU_IO_PPI_MEM_WRITE8   MemWrite8;

+  EFI_PEI_CPU_IO_PPI_MEM_WRITE16  MemWrite16;

+  EFI_PEI_CPU_IO_PPI_MEM_WRITE32  MemWrite32;

+  EFI_PEI_CPU_IO_PPI_MEM_WRITE64  MemWrite64;

+};

+

+extern EFI_GUID gEfiPeiCpuIoPpiInServiceTableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/DeviceRecoveryModule.h b/edk2/MdePkg/Include/Ppi/DeviceRecoveryModule.h
new file mode 100644
index 0000000..3847686
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/DeviceRecoveryModule.h
@@ -0,0 +1,143 @@
+/** @file

+  This file declares Device Recovery Module PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DeviceRecoveryModule.h

+

+  @par Revision Reference:

+  This PPI is defined in Framework of EFI Recovery spec.

+  Version 0.9

+

+**/

+

+#ifndef _PEI_DEVICE_RECOVERY_MODULE_PPI_H

+#define _PEI_DEVICE_RECOVERY_MODULE_PPI_H

+

+#define EFI_PEI_DEVICE_RECOVERY_MODULE_PPI_GUID \

+  { \

+    0x0DE2CE25, 0x446A, 0x45a7, {0xBF, 0xC9, 0x37, 0xDA, 0x26, 0x34, 0x4B, 0x37 } \

+  }

+

+typedef struct _EFI_PEI_DEVICE_RECOVERY_MODULE_PPI EFI_PEI_DEVICE_RECOVERY_MODULE_PPI;

+

+/**

+  This function, by whatever mechanism, searches for DXE capsules from the 

+  associated device and returns the number and maximum size in bytes of 

+  the capsules discovered. Entry 1 is assumed to be the highest load priority 

+  and entry N is assumed to be the lowest priority.

+

+  @param  PeiServices General-purpose services that are available to every PEIM

+  

+  @param  This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance.

+  

+  @param  NumberRecoveryCapsules Pointer to a caller-allocated UINTN. On output, 

+  *NumberRecoveryCapsules contains the number of recovery capsule images available 

+  for retrieval from this PEIM instance.

+

+  @retval EFI_SUCCESS One or more capsules were discovered.

+  

+  @retval EFI_DEVICE_ERROR A device error occurred.

+  

+  @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_DEVICE_GET_NUMBER_RECOVERY_CAPSULE) (

+  IN EFI_PEI_SERVICES                               **PeiServices,

+  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI             *This,

+  OUT UINTN                                         *NumberRecoveryCapsules

+  );

+

+/**

+  This function gets the size and type of the requested recovery capsule.

+

+  @param  PeiServices General-purpose services that are available to every PEIM

+  

+  @param  This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance.

+  

+  @param  CapsuleInstance Specifies for which capsule instance to retrieve the information.

+  

+  @param  Size A pointer to a caller-allocated UINTN in which the size of 

+  the requested recovery module is returned.

+  

+  @param  CapsuleType A pointer to a caller-allocated EFI_GUID in 

+  which the type of the requested recovery capsule is returned.

+

+  @retval EFI_SUCCESS One or more capsules were discovered.

+  

+  @retval EFI_DEVICE_ERROR A device error occurred.

+  

+  @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_DEVICE_GET_RECOVERY_CAPSULE_INFO) (

+  IN  EFI_PEI_SERVICES                              **PeiServices,

+  IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI            *This,

+  IN  UINTN                                         CapsuleInstance,

+  OUT UINTN                                         *Size,

+  OUT EFI_GUID                                      *CapsuleType

+  );

+

+/**

+  This function, by whatever mechanism, retrieves a DXE capsule from some device 

+  and loads it into memory. Note that the published interface is device neutral.

+

+  @param  PeiServices General-purpose services that are available to every PEIM

+  

+  @param  This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance.

+  

+  @param  CapsuleInstance Specifies which capsule instance to retrieve.

+  

+  @param  Buffer Specifies a caller-allocated buffer in which the requested recovery capsule will be returned. 

+

+  @retval EFI_SUCCESS One or more capsules were discovered.

+  

+  @retval EFI_DEVICE_ERROR A device error occurred.

+  

+  @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_DEVICE_LOAD_RECOVERY_CAPSULE) (

+  IN OUT EFI_PEI_SERVICES                         **PeiServices,

+  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI           *This,

+  IN UINTN                                        CapsuleInstance,

+  OUT VOID                                        *Buffer

+  );

+

+/**

+  @par Ppi Description:

+  Presents a standard interface to EFI_PEI_DEVICE_RECOVERY_MODULE_PPI, 

+  regardless of the underlying device(s).

+

+  @param GetNumberRecoveryCapsules

+  Returns the number of DXE capsules that were found.

+

+  @param GetRecoveryCapsuleInfo

+  Returns the capsule image type and the size of a given image. 

+

+  @param LoadRecoveryCapsule

+  Loads a DXE capsule into memory

+

+**/

+struct _EFI_PEI_DEVICE_RECOVERY_MODULE_PPI {

+  EFI_PEI_DEVICE_GET_NUMBER_RECOVERY_CAPSULE  GetNumberRecoveryCapsules;

+  EFI_PEI_DEVICE_GET_RECOVERY_CAPSULE_INFO    GetRecoveryCapsuleInfo;

+  EFI_PEI_DEVICE_LOAD_RECOVERY_CAPSULE        LoadRecoveryCapsule;

+};

+

+extern EFI_GUID gEfiPeiDeviceRecoveryModulePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/DxeIpl.h b/edk2/MdePkg/Include/Ppi/DxeIpl.h
new file mode 100644
index 0000000..bed5795
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/DxeIpl.h
@@ -0,0 +1,70 @@
+/** @file

+  This file declares DXE Initial Program Load PPI.

+  When the PEI core is done it calls the DXE IPL via this PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DxeIpl.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __DXE_IPL_H__

+#define __DXE_IPL_H__

+

+#define EFI_DXE_IPL_PPI_GUID \

+  { \

+    0xae8ce5d, 0xe448, 0x4437, {0xa8, 0xd7, 0xeb, 0xf5, 0xf1, 0x94, 0xf7, 0x31 } \

+  }

+

+typedef struct _EFI_DXE_IPL_PPI EFI_DXE_IPL_PPI;

+

+/**

+  The architectural PPI that the PEI Foundation invokes when 

+  there are no additional PEIMs to invoke.

+

+  @param  This Pointer to the DXE IPL PPI instance

+  

+  @param  PeiServices Pointer to the PEI Services Table.

+  

+  @param  HobList Pointer to the list of Hand-Off Block (HOB) entries.

+

+  @retval EFI_SUCCESS Upon this return code, the PEI Foundation should enter 

+  some exception handling.Under normal circumstances, the DXE IPL PPI should not return.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DXE_IPL_ENTRY) (

+  IN EFI_DXE_IPL_PPI              *This,

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN EFI_PEI_HOB_POINTERS         HobList

+  );

+

+/**

+  @par Ppi Description:

+  Final service to be invoked by the PEI Foundation.

+  The DXE IPL PPI is responsible for locating and loading the DXE Foundation.

+  The DXE IPL PPI may use PEI services to locate and load the DXE Foundation.

+

+  @param Entry

+  The entry point to the DXE IPL PPI.

+

+**/

+struct _EFI_DXE_IPL_PPI {

+  EFI_DXE_IPL_ENTRY Entry;

+};

+

+extern EFI_GUID gEfiDxeIplPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/EndOfPeiPhase.h b/edk2/MdePkg/Include/Ppi/EndOfPeiPhase.h
new file mode 100644
index 0000000..e58fa03
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/EndOfPeiPhase.h
@@ -0,0 +1,31 @@
+/** @file

+  PPI to be used to signal when the PEI ownership of the memory map

+  officially ends and DXE will take over

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EndOfPeiSignal.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS spec Version 0.91.

+

+**/

+

+#ifndef __END_OF_PEI_SIGNAL_PPI_H__

+#define __END_OF_PEI_SIGNAL_PPI_H__

+

+#define EFI_PEI_END_OF_PEI_PHASE_PPI_GUID \

+  { \

+    0x605EA650, 0xC65C, 0x42e1, {0xBA, 0x80, 0x91, 0xA5, 0x2A, 0xB6, 0x18, 0xC6 } \

+  }

+

+extern EFI_GUID gEfiEndOfPeiSignalPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/FindFv.h b/edk2/MdePkg/Include/Ppi/FindFv.h
new file mode 100644
index 0000000..9715125
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/FindFv.h
@@ -0,0 +1,76 @@
+/** @file

+  This file declares FindFv PPI used to locate FVs that contain PEIMs in PEI

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FindFv.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS

+  Version 0.91

+

+**/

+

+#ifndef __FIND_FV_H__

+#define __FIND_FV_H__

+

+#define EFI_PEI_FIND_FV_PPI_GUID \

+  { \

+    0x36164812, 0xa023, 0x44e5, {0xbd, 0x85, 0x5, 0xbf, 0x3c, 0x77, 0x0, 0xaa } \

+  }

+

+typedef struct _EFI_PEI_FIND_FV_PPI EFI_PEI_FIND_FV_PPI;

+

+/**

+  This interface returns the base address of the firmware volume whose index 

+  was passed in FvNumber.Once this function reports a firmware volume 

+  index/base address pair, that index/address pairing must continue throughout PEI.

+

+  @param  PeiServices Pointer to the PEI Services Table.

+  

+  @param  This Interface pointer that implements the Find FV service.

+  

+  @param  FvNumber The index of the firmware volume to locate.

+  

+  @param  FvAddress The address of the volume to discover.

+

+  @retval EFI_SUCCESS An additional firmware volume was found.

+  

+  @retval EFI_OUT_OF_RESOURCES There are no firmware volumes for the given FvNumber.

+  

+  @retval EFI_INVALID_PARAMETER *FvAddress is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_FIND_FV_FINDFV) (

+  IN EFI_PEI_FIND_FV_PPI      *This,

+  IN EFI_PEI_SERVICES         **PeiServices,

+  UINT8                       *FvNumber,

+  EFI_FIRMWARE_VOLUME_HEADER  **FVAddress

+  );

+

+/**

+  @par Ppi Description:

+  Hardware mechanisms for locating FVs in a platform vary widely.

+  EFI_PEI_FIND_FV_PPI serves to abstract this variation so that the 

+  PEI Foundation can remain standard across a wide variety of platforms.

+

+  @param FindFv

+  Service that abstracts the location of additional firmware volumes.

+

+**/

+struct _EFI_PEI_FIND_FV_PPI {

+  EFI_PEI_FIND_FV_FINDFV  FindFv;

+};

+

+extern EFI_GUID gEfiFindFvPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/LoadFile.h b/edk2/MdePkg/Include/Ppi/LoadFile.h
new file mode 100644
index 0000000..af02be7
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/LoadFile.h
@@ -0,0 +1,78 @@
+/** @file

+  Load image file from fv to memory. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  LoadFile.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS spec Version 0.91.

+

+**/

+

+#ifndef __FV_FILE_LOADER_PPI_H__

+#define __FV_FILE_LOADER_PPI_H__

+

+#define EFI_PEI_FV_FILE_LOADER_GUID \

+  { \

+    0x7e1f0d85, 0x4ff, 0x4bb2, {0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 } \

+  }

+

+typedef struct _EFI_PEI_FV_FILE_LOADER_PPI  EFI_PEI_FV_FILE_LOADER_PPI;

+

+/**

+  Loads a PEIM into memory for subsequent execution.

+

+  @param  This Interface pointer that implements the Load File PPI instance.

+  

+  @param  FfsHeader Pointer to the FFS header of the file to load.

+  

+  @param  ImageAddress Pointer to the address of the loaded Image

+  

+  @param  ImageSize Pointer to the size of the loaded image.

+  

+  @param  EntryPoint Pointer to the entry point of the image.

+

+  @retval EFI_SUCCESS The image was loaded successfully.

+  

+  @retval EFI_OUT_OF_RESOURCES There was not enough memory.

+  

+  @retval EFI_INVALID_PARAMETER The contents of the FFS file did not 

+  contain a valid PE/COFF image that could be loaded.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_FV_LOAD_FILE) (

+  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,

+  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,

+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,

+  OUT UINT64                                    *ImageSize,

+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint

+  );

+

+/**

+  @par Ppi Description:

+  This PPI is a pointer to the Load File service. This service will be 

+  published by a PEIM.The PEI Foundation will use this service to 

+  launch the known non-XIP PE/COFF PEIM images.  This service may 

+  depend upon the presence of the EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI.

+

+  @param FvLoadFile

+  Loads a PEIM into memory for subsequent execution

+

+**/

+struct _EFI_PEI_FV_FILE_LOADER_PPI {

+  EFI_PEI_FV_LOAD_FILE  FvLoadFile;

+};

+

+extern EFI_GUID gEfiPeiFvFileLoaderPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/MasterBootMode.h b/edk2/MdePkg/Include/Ppi/MasterBootMode.h
new file mode 100644
index 0000000..010055c
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/MasterBootMode.h
@@ -0,0 +1,34 @@
+/** @file

+  This file declares Boot Mode PPI

+  The Master Boot Mode PPI is installed by a PEIM to signal that a final 

+  boot has been determined and set. This signal is useful in that PEIMs 

+  with boot-mode-specific behavior can put this PPI in their dependency expression.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  MasterBootMode.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS

+  Version 0.91.

+

+**/

+

+#ifndef __MASTER_BOOT_MODE_PPI_H__

+#define __MASTER_BOOT_MODE_PPI_H__

+

+#define EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI \

+  { \

+    0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10 } \

+  }

+

+extern EFI_GUID gEfiPeiMasterBootModePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/MemoryDiscovered.h b/edk2/MdePkg/Include/Ppi/MemoryDiscovered.h
new file mode 100644
index 0000000..414926c
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/MemoryDiscovered.h
@@ -0,0 +1,34 @@
+/** @file

+  This file declares Memory Discovered PPI.

+  This PPI is installed by the PEI Foundation at the point of system 

+  evolution when the permanent memory size has been registered and 

+  waiting PEIMs can use the main memory store. 

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  MemoryDiscovered.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS

+  Version 0.91.

+

+**/

+

+#ifndef __PEI_MEMORY_DISCOVERED_PPI_H__

+#define __PEI_MEMORY_DISCOVERED_PPI_H__

+

+#define EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID \

+  { \

+    0xf894643d, 0xc449, 0x42d1, {0x8e, 0xa8, 0x85, 0xbd, 0xd8, 0xc6, 0x5b, 0xde } \

+  }

+

+extern EFI_GUID gEfiPeiMemoryDiscoveredPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/Pcd.h b/edk2/MdePkg/Include/Ppi/Pcd.h
new file mode 100644
index 0000000..1625b87
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/Pcd.h
@@ -0,0 +1,298 @@
+/** @file

+  Platform Configuration Database (PCD) Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Pcd.h

+

+**/

+

+#ifndef __PCD_H__

+#define __PCD_H__

+

+#include <Common/Pcd.h>

+

+extern EFI_GUID gPcdPpiGuid;

+

+#define PCD_PPI_GUID \

+  { 0x632df884, 0x8023, 0x4872, { 0xb6, 0x70, 0xb7, 0x4a, 0x30, 0x19, 0x16, 0xe9 } }

+

+typedef 

+VOID

+(EFIAPI *PCD_PPI_SET_SKU) (

+  IN  SKU_ID          SkuId

+  );

+

+typedef

+UINT8

+(EFIAPI *PCD_PPI_GET8) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT16

+(EFIAPI *PCD_PPI_GET16) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT32

+(EFIAPI *PCD_PPI_GET32) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT64

+(EFIAPI *PCD_PPI_GET64) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+VOID *

+(EFIAPI *PCD_PPI_GET_POINTER) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+BOOLEAN

+(EFIAPI *PCD_PPI_GET_BOOLEAN) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINTN

+(EFIAPI *PCD_PPI_GET_SIZE) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT8

+(EFIAPI *PCD_PPI_GET_EX_8) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT16

+(EFIAPI *PCD_PPI_GET_EX_16) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER   TokenNumber

+  );

+

+typedef

+UINT32

+(EFIAPI *PCD_PPI_GET_EX_32) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT64

+(EFIAPI *PCD_PPI_GET_EX_64) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+VOID *

+(EFIAPI *PCD_PPI_GET_EX_POINTER) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+BOOLEAN

+(EFIAPI *PCD_PPI_GET_EX_BOOLEAN) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINTN

+(EFIAPI *PCD_PPI_GET_EX_SIZE) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET8) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET16) (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT16             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET32) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET64) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_POINTER) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_BOOLEAN) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_EX_8) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_EX_16) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_EX_32) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_EX_64) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_EX_POINTER) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_SET_EX_BOOLEAN) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  );

+

+/**

+  Callback on SET function prototype definition.

+

+  @param[in]  CallBackGuid The PCD token GUID being set.

+  @param[in]  CallBackToken The PCD token number being set.

+  @param[in]  TokenData A pointer to the token data being set.

+  @param[in]  TokenDataSize The size, in bytes, of the data being set.

+

+  @retval VOID

+

+--*/

+typedef

+VOID

+(EFIAPI *PCD_PPI_CALLBACK) (

+  IN      CONST EFI_GUID   *CallBackGuid, OPTIONAL

+  IN      PCD_TOKEN_NUMBER CallBackToken,

+  IN  OUT VOID             *TokenData,

+  IN      UINTN            TokenDataSize

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_CALLBACK_ONSET) (

+  IN  PCD_TOKEN_NUMBER       TokenNumber,

+  IN  CONST EFI_GUID         *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK       CallBackFunction

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PPI_CANCEL_CALLBACK) (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PPI_CALLBACK        CallBackFunction

+  );

+

+typedef 

+EFI_STATUS

+(EFIAPI *PCD_PPI_GET_NEXT_TOKEN) (

+  IN CONST EFI_GUID           *Guid, OPTIONAL

+  IN OUT  PCD_TOKEN_NUMBER    *TokenNumber

+  );

+

+typedef struct {

+  PCD_PPI_SET_SKU              SetSku;

+

+  PCD_PPI_GET8                 Get8;

+  PCD_PPI_GET16                Get16;

+  PCD_PPI_GET32                Get32;

+  PCD_PPI_GET64                Get64;

+  PCD_PPI_GET_POINTER          GetPtr;

+  PCD_PPI_GET_BOOLEAN          GetBool;

+  PCD_PPI_GET_SIZE             GetSize;

+

+  PCD_PPI_GET_EX_8             Get8Ex;

+  PCD_PPI_GET_EX_16            Get16Ex;

+  PCD_PPI_GET_EX_32            Get32Ex;

+  PCD_PPI_GET_EX_64            Get64Ex;

+  PCD_PPI_GET_EX_POINTER       GetPtrEx;

+  PCD_PPI_GET_EX_BOOLEAN       GetBoolEx;

+  PCD_PPI_GET_EX_SIZE          GetSizeEx;

+

+  PCD_PPI_SET8                 Set8;

+  PCD_PPI_SET16                Set16;

+  PCD_PPI_SET32                Set32;

+  PCD_PPI_SET64                Set64;

+  PCD_PPI_SET_POINTER          SetPtr;

+  PCD_PPI_SET_BOOLEAN          SetBool;

+

+  PCD_PPI_SET_EX_8             Set8Ex;

+  PCD_PPI_SET_EX_16            Set16Ex;

+  PCD_PPI_SET_EX_32            Set32Ex;

+  PCD_PPI_SET_EX_64            Set64Ex;

+  PCD_PPI_SET_EX_POINTER       SetPtrEx;

+  PCD_PPI_SET_EX_BOOLEAN       SetBoolEx;

+

+  PCD_PPI_CALLBACK_ONSET       CallbackOnSet;

+  PCD_PPI_CANCEL_CALLBACK      CancelCallback;

+  PCD_PPI_GET_NEXT_TOKEN       GetNextToken;

+} PCD_PPI;

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/PciCfg.h b/edk2/MdePkg/Include/Ppi/PciCfg.h
new file mode 100644
index 0000000..b38a0db
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/PciCfg.h
@@ -0,0 +1,133 @@
+/** @file

+  This file declares PciCfg PPI used to access PCI configuration space in PEI

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PciCfg.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS

+  Version 0.91.

+

+**/

+

+#ifndef __PEI_PCI_CFG_H__

+#define __PEI_PCI_CFG_H__

+

+#define EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID \

+  { \

+    0xe1f2eba0, 0xf7b9, 0x4a26, {0x86, 0x20, 0x13, 0x12, 0x21, 0x64, 0x2a, 0x90 } \

+  }

+

+typedef struct _EFI_PEI_PCI_CFG_PPI   EFI_PEI_PCI_CFG_PPI;

+

+#define PEI_PCI_CFG_ADDRESS(bus, dev, func, reg)  ( \

+      (UINT64) ((((UINTN) bus) << 24) + (((UINTN) dev) << 16) + (((UINTN) func) << 8) + ((UINTN) reg)) \

+    ) & 0x00000000ffffffff

+

+typedef enum {

+  EfiPeiPciCfgWidthUint8   = 0,

+  EfiPeiPciCfgWidthUint16  = 1,

+  EfiPeiPciCfgWidthUint32  = 2,

+  EfiPeiPciCfgWidthUint64  = 3,

+  EfiPeiPciCfgWidthMaximum

+} EFI_PEI_PCI_CFG_PPI_WIDTH;

+

+typedef struct {

+  UINT8 Register;

+  UINT8 Function;

+  UINT8 Device;

+  UINT8 Bus;

+  UINT8 Reserved[4];

+} EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS;

+

+/**

+  PCI read and write operation.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table 

+  published by the PEI Foundation.

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Width The width of the access. Enumerated in bytes.

+  

+  @param  Address The physical address of the access.

+  

+  @param  Buffer A pointer to the buffer of data.

+

+  @retval EFI_SUCCESS The function completed successfully. 

+  

+  @retval EFI_NOT_YET_AVAILABLE The service has not been installed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_PCI_CFG_PPI_IO) (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN EFI_PEI_PCI_CFG_PPI          *This,

+  IN EFI_PEI_PCI_CFG_PPI_WIDTH    Width,

+  IN UINT64                       Address,

+  IN OUT VOID                     *Buffer

+  );

+

+/**

+  PCI read-modify-write operation.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table 

+  published by the PEI Foundation.

+  

+  @param  This Pointer to local data for the interface.

+  

+  @param  Width The width of the access. Enumerated in bytes.

+  

+  @param  Address The physical address of the access.

+  

+  @param  SetBits Value of the bits to set.

+  

+  @param  ClearBits Value of the bits to clear.

+

+  @retval EFI_SUCCESS  The function completed successfully.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_PCI_CFG_PPI_RW) (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN EFI_PEI_PCI_CFG_PPI          *This,

+  IN EFI_PEI_PCI_CFG_PPI_WIDTH    Width,

+  IN UINT64                       Address,

+  IN UINTN                        SetBits,

+  IN UINTN                        ClearBits

+  );

+

+/**

+  @par Ppi Description:

+  The EFI_PEI_PCI_CFG_PPI interfaces are used to abstract accesses to PCI 

+  controllers behind a PCI root bridge controller.

+

+  @param Read

+  PCI read services.  See the Read() function description.

+

+  @param Write

+  PCI write services.  See the Write() function description.

+

+  @param Modify

+PCI read-modify-write services.  See the Modify() function description.

+

+**/

+struct _EFI_PEI_PCI_CFG_PPI {

+  EFI_PEI_PCI_CFG_PPI_IO  Read;

+  EFI_PEI_PCI_CFG_PPI_IO  Write;

+  EFI_PEI_PCI_CFG_PPI_RW  Modify;

+};

+

+extern EFI_GUID gEfiPciCfgPpiInServiceTableGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/ReadOnlyVariable.h b/edk2/MdePkg/Include/Ppi/ReadOnlyVariable.h
new file mode 100644
index 0000000..3ea3c77
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/ReadOnlyVariable.h
@@ -0,0 +1,136 @@
+/** @file

+  This file declares Read-only Variable Service PPI

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ReadOnlyVariable.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS

+  Version 0.91.

+

+**/

+

+#ifndef __PEI_READ_ONLY_VARIABLE_PPI_H__

+#define __PEI_READ_ONLY_VARIABLE_PPI_H__

+

+#define EFI_PEI_READ_ONLY_VARIABLE_ACCESS_PPI_GUID \

+  { \

+    0x3cdc90c6, 0x13fb, 0x4a75, {0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa } \

+  }

+

+typedef struct _EFI_PEI_READ_ONLY_VARIABLE_PPI  EFI_PEI_READ_ONLY_VARIABLE_PPI;

+

+//

+// Variable attributes

+//

+#define EFI_VARIABLE_NON_VOLATILE       0x00000001

+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002

+#define EFI_VARIABLE_RUNTIME_ACCESS     0x00000004

+#define EFI_VARIABLE_READ_ONLY          0x00000008

+

+/**

+  Get Variable value by Name and GUID pair

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  VariableName A NULL-terminated Unicode string that is the name of the vendor¡¯s variable. 

+  

+  @param  VendorGuid A unique identifier for the vendor.

+  

+  @param  Attributes If not NULL, a pointer to the memory location to return 

+  the attributes bitmask for the variable.

+  

+  @param  DataSize On input, the size in bytes of the return Data buffer.

+  On output, the size of data returned in Data.

+  

+  @param  Data The buffer to return the contents of the variable.

+

+  @retval EFI_SUCCESS The function completed successfully. 

+  

+  @retval EFI_NOT_FOUND The variable was not found.

+  

+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result.

+  

+  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.

+  

+  @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_GET_VARIABLE) (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  OUT UINT32                      *Attributes OPTIONAL,

+  IN OUT UINTN                    *DataSize,

+  OUT VOID                        *Data

+  );

+

+/**

+  This function can be called multiple times to retrieve the VariableName 

+  and VendorGuid of all variables currently available in the system. On each call 

+  to GetNextVariableName() the previous results are passed into the interface, 

+  and on output the interface returns the next variable name data.  When the 

+  entire variable list has been returned, the error EFI_NOT_FOUND is returned.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. 

+  

+  @param  VariableNameSize The size of the VariableName buffer.

+  

+  @param  VariableName On input, supplies the last VariableName that was 

+  returned by GetNextVariableName().  On output, returns the Null-terminated 

+  Unicode string of the current variable.

+  

+  @param  VendorGuid On input, supplies the last VendorGuid that was 

+  returned by GetNextVariableName().  On output, returns the VendorGuid 

+  of the current variable.

+

+  @retval EFI_SUCCESS The function completed successfully. 

+  

+  @retval EFI_NOT_FOUND The next variable was not found.

+  

+  @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.

+  

+  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.

+  

+  @retval EFI_DEVICE_ERROR The variable name could not be retrieved due to a hardware error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_GET_NEXT_VARIABLE_NAME) (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  );

+

+/**

+  @par Ppi Description:

+  This PPI provides a lightweight, read-only variant of the full EFI 

+  variable services. 

+

+  @param GetVariable

+  A service to ascertain a given variable name.

+

+  @param GetNextVariableName

+  A service to ascertain a variable based upon a given, known variable

+

+**/

+struct _EFI_PEI_READ_ONLY_VARIABLE_PPI {

+  EFI_PEI_GET_VARIABLE            PeiGetVariable;

+  EFI_PEI_GET_NEXT_VARIABLE_NAME  PeiGetNextVariableName;

+};

+

+extern EFI_GUID gEfiPeiReadOnlyVariablePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/RecoveryModule.h b/edk2/MdePkg/Include/Ppi/RecoveryModule.h
new file mode 100644
index 0000000..044a68a
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/RecoveryModule.h
@@ -0,0 +1,67 @@
+/** @file

+  This file declares Recovery Module PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  RecoveryModule.h

+

+  @par Revision Reference:

+  This PPI is defined in Framework of EFI Recovery Spec.

+  Version 0.9

+

+**/

+

+#ifndef __PEI_RECOVERY_MODULE_PPI_H__

+#define __PEI_RECOVERY_MODULE_PPI_H__

+

+#define EFI_PEI_RECOVERY_MODULE_PPI_GUID \

+  { \

+    0xFB6D9542, 0x612D, 0x4f45, {0x87, 0x2F, 0x5C, 0xFF, 0x52, 0xE9, 0x3D, 0xCF } \

+  }

+

+typedef struct _EFI_PEI_RECOVERY_MODULE_PPI EFI_PEI_RECOVERY_MODULE_PPI;

+

+/**

+  Loads a DXE capsule from some media into memory and updates the HOB table 

+  with the DXE firmware volume information.

+

+  @param  PeiServices General-purpose services that are available to every PEIM.

+  

+  @param  This Indicates the EFI_PEI_RECOVERY_MODULE_PPI instance. 

+

+  @retval EFI_SUCCESS The capsule was loaded correctly.

+  

+  @retval EFI_DEVICE_ERROR A device error occurred.

+  

+  @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_LOAD_RECOVERY_CAPSULE) (

+  IN EFI_PEI_SERVICES                     **PeiServices,

+  IN EFI_PEI_RECOVERY_MODULE_PPI          *This

+  );

+

+/**

+  @par Ppi Description:

+  Finds and loads the recovery files.

+

+  @param LoadRecoveryCapsule

+  Loads a DXE binary capsule into memory.

+

+**/

+struct _EFI_PEI_RECOVERY_MODULE_PPI {

+  EFI_PEI_LOAD_RECOVERY_CAPSULE LoadRecoveryCapsule;

+};

+

+extern EFI_GUID gEfiPeiRecoveryModulePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/Reset.h b/edk2/MdePkg/Include/Ppi/Reset.h
new file mode 100644
index 0000000..be35e70
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/Reset.h
@@ -0,0 +1,35 @@
+/** @file

+  This file declares Reset PPI used to reset the platform

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Reset.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS

+  Version 0.91.

+

+**/

+

+#ifndef __RESET_PPI_H__

+#define __RESET_PPI_H__

+

+#define EFI_PEI_RESET_PPI_GUID \

+  { \

+    0xef398d58, 0x9dfd, 0x4103, {0xbf, 0x94, 0x78, 0xc6, 0xf4, 0xfe, 0x71, 0x2f } \

+  }

+

+typedef struct {

+  EFI_PEI_RESET_SYSTEM  ResetSystem;

+} EFI_PEI_RESET_PPI;

+

+extern EFI_GUID gEfiPeiResetPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/S3Resume.h b/edk2/MdePkg/Include/Ppi/S3Resume.h
new file mode 100644
index 0000000..c458430
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/S3Resume.h
@@ -0,0 +1,65 @@
+/** @file

+  This file declares S3 Resume PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  S3Resume.h

+

+  @par Revision Reference:

+  This PPI is defined in Framework of EFI S3 Resume Boot Path spec.

+  Version 0.9

+

+**/

+

+#ifndef __PEI_S3_RESUME_PPI_H__

+#define __PEI_S3_RESUME_PPI_H__

+

+#define EFI_PEI_S3_RESUME_PPI_GUID \

+  { \

+    0x4426CCB2, 0xE684, 0x4a8a, {0xAE, 0x40, 0x20, 0xD4, 0xB0, 0x25, 0xB7, 0x10 } \

+  }

+

+typedef struct _EFI_PEI_S3_RESUME_PPI   EFI_PEI_S3_RESUME_PPI;

+

+/**

+  Restores the platform to its preboot configuration for an S3 resume and 

+  jumps to the OS waking vector.

+

+  @param  PeiServices Pointer to the PEI Services Table

+

+  @retval EFI_ABORTED Execution of the S3 resume boot script table failed.

+  

+  @retval EFI_NOT_FOUND Some necessary information that is used for 

+  the S3 resume boot path could not be located.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_S3_RESUME_PPI_RESTORE_CONFIG) (

+  IN EFI_PEI_SERVICES   **PeiServices

+  );

+

+/**

+  @par Ppi Description:

+  EFI_PEI_S3_RESUME_PPI accomplishes the firmware S3 resume boot 

+  path and transfers control to OS.

+

+  @param S3RestoreConfig

+  Restores the platform to its preboot configuration for an S3 resume and 

+  jumps to the OS waking vector.

+

+**/

+struct _EFI_PEI_S3_RESUME_PPI {

+  EFI_PEI_S3_RESUME_PPI_RESTORE_CONFIG  S3RestoreConfig;

+};

+

+extern EFI_GUID gEfiPeiS3ResumePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/SecPlatformInformation.h b/edk2/MdePkg/Include/Ppi/SecPlatformInformation.h
new file mode 100644
index 0000000..1e96259
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/SecPlatformInformation.h
@@ -0,0 +1,86 @@
+/** @file

+  This file declares Sec Platform Information PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SecPlatformInformation.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __SEC_PLATFORM_INFORMATION_PPI_H__

+#define __SEC_PLATFORM_INFORMATION_PPI_H__

+

+#define EFI_SEC_PLATFORM_INFORMATION_GUID \

+  { \

+    0x6f8c2b35, 0xfef4, 0x448d, {0x82, 0x56, 0xe1, 0x1b, 0x19, 0xd6, 0x10, 0x77 } \

+  }

+

+typedef struct _EFI_SEC_PLATFORM_INFORMATION_PPI EFI_SEC_PLATFORM_INFORMATION_PPI;

+

+extern EFI_GUID gEfiSecPlatformInformationPpiGuid;

+

+///

+/// EFI_HEALTH_FLAGS

+///

+typedef union {

+  struct {

+    UINT32   Status                   : 2;

+    UINT32   Tested                   : 1;

+    UINT32   Reserved1                :13;

+    UINT32   VirtualMemoryUnavailable : 1;

+    UINT32   Ia32ExecutionUnavailable : 1;

+    UINT32   FloatingPointUnavailable : 1;

+    UINT32   MiscFeaturesUnavailable  : 1;

+    UINT32   Reserved2                :12;

+  }                     Bits;

+  UINT32                Uint32;

+} EFI_HEALTH_FLAGS;

+

+typedef struct {

+  EFI_HEALTH_FLAGS HealthFlags;

+} EFI_SEC_PLATFORM_INFORMATION_RECORD;

+

+/**

+  This interface conveys state information out of the Security (SEC) phase into PEI.

+

+  @param  PeiServices Pointer to the PEI Services Table.

+  

+  @param  StructureSize Pointer to the variable describing size of the input buffer.

+  

+  @param  PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. 

+

+  @retval EFI_SUCCESS The data was successfully returned.

+  

+  @retval EFI_BUFFER_TOO_SMALL The buffer was too small.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SEC_PLATFORM_INFORMATION) (

+  IN EFI_PEI_SERVICES                      **PeiServices,

+  IN OUT UINT64                            *StructureSize,

+  OUT EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord

+  );

+

+/**

+  @par Ppi Description:

+

+  @param Name

+

+**/

+struct _EFI_SEC_PLATFORM_INFORMATION_PPI {

+  EFI_SEC_PLATFORM_INFORMATION  PlatformInformation;

+};

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/SectionExtraction.h b/edk2/MdePkg/Include/Ppi/SectionExtraction.h
new file mode 100644
index 0000000..afa473d
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/SectionExtraction.h
@@ -0,0 +1,118 @@
+/** @file

+  This file declares Section Extraction PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SectionExtraction.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __SECTION_EXTRACTION_PPI_H__

+#define __SECTION_EXTRACTION_PPI_H__

+

+#define EFI_PEI_SECTION_EXTRACTION_PPI_GUID \

+  { \

+    0x4F89E208, 0xE144, 0x4804, {0x9E, 0xC8, 0x0F, 0x89, 0x4F, 0x7E, 0x36, 0xD7 } \

+  }

+

+typedef struct _EFI_PEI_SECTION_EXTRACTION_PPI EFI_PEI_SECTION_EXTRACTION_PPI;

+

+//

+// Bit values for AuthenticationStatus

+//

+#define EFI_PEI_AUTH_STATUS_PLATFORM_OVERRIDE 0x01

+#define EFI_PEI_AUTH_STATUS_IMAGE_SIGNED      0x02

+#define EFI_PEI_AUTH_STATUS_NOT_TESTED        0x04

+#define EFI_PEI_AUTH_STATUS_TEST_FAILED       0x08

+

+/**

+  The function is used to retrieve a section from within a section file.

+  It will retrieve both encapsulation sections and leaf sections in their entirety,

+  exclusive of the section header.

+

+  @param  PeiServices Pointer to the PEI Services Table.

+  

+  @param  This Indicates the calling context

+  

+  @param  SectionType Pointer to an EFI_SECTION_TYPE. If SectionType == NULL, 

+  the contents of the entire section are returned in Buffer. If SectionType 

+  is not NULL, only the requested section is returned.

+  

+  @param  SectionDefinitionGuid Pointer to an EFI_GUID.

+  If SectionType == EFI_SECTION_GUID_DEFINED, SectionDefinitionGuid 

+  indicates for which section GUID to search.

+  If SectionType != EFI_SECTION_GUID_DEFINED, SectionDefinitionGuid 

+  is unused and is ignored.

+  

+  @param  SectionInstance If SectionType is not NULL, indicates which 

+  instance of the requested section type to return.

+  

+  @param  Buffer Pointer to a pointer to a buffer in which the section 

+  contents are returned.

+  

+  @param  BufferSize A pointer to a caller-allocated UINT32.On input, *BufferSize 

+  indicates the size in bytes of the memory region pointed to by Buffer.On output,

+  *BufferSize contains the number of bytes required to read the section.

+  

+  @param  AuthenticationStatus A pointer to a caller-allocated UINT32 in 

+  which any metadata from encapsulating GUID-defined sections is returned.

+

+  @retval EFI_SUCCESS The section was successfully processed and the section 

+  contents were returned in Buffer.

+  

+  @retval EFI_PROTOCOL_ERROR A GUID-defined section was encountered in 

+  the file with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED bit set, but 

+  there was no corresponding GUIDed Section Extraction Protocol in the 

+  handle database.*Buffer is unmodified.

+  

+  @retval EFI_NOT_FOUND The requested section does not exist.*Buffer is unmodified.

+  

+  @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to process the request.

+  

+  @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist.

+  

+  @retval EFI_WARN_TOO_SMALL The size of the input buffer is insufficient to 

+  contain the requested section.  The input buffer is filled and contents are

+  section contents are truncated.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_GET_SECTION) (

+  IN EFI_PEI_SERVICES                         **PeiServices,

+  IN EFI_PEI_SECTION_EXTRACTION_PPI           *This,

+  IN EFI_SECTION_TYPE                         *SectionType,

+  IN EFI_GUID                                 *SectionDefinitionGuid, OPTIONAL

+  IN UINTN                                    SectionInstance,

+  IN VOID                                     **Buffer,

+  IN OUT UINT32                               *BufferSize,

+  OUT UINT32                                  *AuthenticationStatus

+  );

+

+/**

+  @par Ppi Description:

+  This PPI supports encapsulating sections, such as GUIDed sections used to 

+  authenticate the file encapsulation of other domain-specific wrapping.

+

+  @param GetSection

+  Retrieves a section from within a section file.

+

+**/

+struct _EFI_PEI_SECTION_EXTRACTION_PPI {

+  EFI_PEI_GET_SECTION PeiGetSection;

+};

+

+extern EFI_GUID gEfiPeiSectionExtractionPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/Security.h b/edk2/MdePkg/Include/Ppi/Security.h
new file mode 100644
index 0000000..cc59023
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/Security.h
@@ -0,0 +1,77 @@
+/** @file

+  This file declares Security Architectural PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Security.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __SECURITY_PPI_H__

+#define __SECURITY_PPI_H__

+

+#define EFI_PEI_SECURITY_PPI_GUID \

+  { \

+    0x1388066e, 0x3a57, 0x4efa, {0x98, 0xf3, 0xc1, 0x2f, 0x3a, 0x95, 0x8a, 0x29 } \

+  }

+

+typedef struct _EFI_PEI_SECURITY_PPI  EFI_PEI_SECURITY_PPI;

+

+/**

+  Allows the platform builder to implement a security policy in response 

+  to varying file authentication states.

+

+  @param  PeiServices Pointer to the PEI Services Table.

+  

+  @param  This Interface pointer that implements the particular EFI_PEI_SECURITY_PPI instance.

+  

+  @param  AuthenticationStatus Status returned by the verification service as part of section extraction.

+  

+  @param  FfsFileHeader Pointer to the file under review. 

+  

+  @param  DeferExecution Pointer to a variable that alerts the PEI Foundation to defer execution of a PEIM.

+

+  @retval EFI_SUCCESS The service performed its action successfully.

+  

+  @retval EFI_SECURITY_VIOLATION The object cannot be trusted

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_SECURITY_AUTHENTICATION_STATE) (

+  IN EFI_PEI_SERVICES             **PeiServices,

+  IN EFI_PEI_SECURITY_PPI         *This,

+  IN UINT32                       AuthenticationStatus,

+  IN EFI_FFS_FILE_HEADER          *FfsFileHeader,

+  IN OUT BOOLEAN                  *StartCrisisRecovery

+  );

+

+/**

+  @par Ppi Description:

+  This PPI is installed by some platform PEIM that abstracts the security 

+  policy to the PEI Foundation, namely the case of a PEIM¡¯s authentication 

+  state being returned during the PEI section extraction process. 

+

+  @param AuthenticationState

+  Allows the platform builder to implement a security policy in response 

+  to varying file authentication states.

+

+**/

+struct _EFI_PEI_SECURITY_PPI {

+  EFI_PEI_SECURITY_AUTHENTICATION_STATE  AuthenticationState;

+};

+

+extern EFI_GUID gEfiPeiSecurityPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/Smbus.h b/edk2/MdePkg/Include/Ppi/Smbus.h
new file mode 100644
index 0000000..7360e5b
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/Smbus.h
@@ -0,0 +1,258 @@
+/** @file

+  This file declares Smbus PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Smbus.h

+

+  @par Revision Reference:

+  This PPI is defined in Framework of EFI SmBus PPI spec.

+  Version 0.9

+

+**/

+

+#ifndef _PEI_SMBUS_PPI_H

+#define _PEI_SMBUS_PPI_H

+

+#define EFI_PEI_SMBUS_PPI_GUID \

+  { \

+    0xabd42895, 0x78cf, 0x4872, {0x84, 0x44, 0x1b, 0x5c, 0x18, 0xb, 0xfb, 0xda } \

+  }

+

+typedef struct _EFI_PEI_SMBUS_PPI EFI_PEI_SMBUS_PPI;

+

+/**

+  Executes an SMBus operation to an SMBus controller.

+

+  @param  PeiServices A pointer to the system PEI Services Table.

+  

+  @param  This A pointer to the EFI_PEI_SMBUS_PPI instance.

+  

+  @param  SlaveAddress The SMBUS hardware address to which the SMBUS 

+  device is preassigned or allocated. 

+  

+  @param  Command This command is transmitted by the SMBus host 

+  controller to the SMBus slave device and the interpretation is 

+  SMBus slave device specific.

+  

+  @param  Operation Signifies which particular SMBus hardware protocol 

+  instance that it will use to execute the SMBus transactions. 

+  

+  @param  PecCheck Defines if Packet Error Code (PEC) checking is required 

+  for this operation.

+  

+  @param  Length Signifies the number of bytes that this operation will do.

+  

+  @param  Buffer Contains the value of data to execute to the SMBus slave device.

+

+  @retval EFI_SUCCESS The last data that was returned from the access 

+  matched the poll exit criteria.

+  

+  @retval EFI_CRC_ERROR The checksum is not correct (PEC is incorrect)

+  

+  @retval EFI_TIMEOUT Timeout expired before the operation was completed. 

+  Timeout is determined by the SMBus host controller device.

+  

+  @retval EFI_OUT_OF_RESOURCES The request could not be completed 

+  due to a lack of resources.

+  

+  @retval EFI_DEVICE_ERROR The request was not completed because 

+  a failure reflected in the Host Status Register bit.

+  

+  @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.

+  Or Length/Buffer is NULL for operations except for EfiSmbusQuickRead and 

+  EfiSmbusQuickWrite. Length is outside the range of valid values.

+  

+  @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.

+  

+  @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_SMBUS_PPI_EXECUTE_OPERATION) (

+  IN      EFI_PEI_SERVICES          **PeiServices,

+  IN EFI_PEI_SMBUS_PPI              *This,

+  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,

+  IN      EFI_SMBUS_DEVICE_COMMAND  Command,

+  IN      EFI_SMBUS_OPERATION       Operation,

+  IN      BOOLEAN                   PecCheck,

+  IN OUT  UINTN                     *Length,

+  IN OUT  VOID                      *Buffer

+  );

+

+typedef struct {

+  UINT32  VendorSpecificId;

+  UINT16  SubsystemDeviceId;

+  UINT16  SubsystemVendorId;

+  UINT16  Interface;

+  UINT16  DeviceId;

+  UINT16  VendorId;

+  UINT8   VendorRevision;

+  UINT8   DeviceCapabilities;

+} EFI_SMBUS_UDID;

+

+/**

+  CallBack function can be registered in EFI_PEI_SMBUS_PPI_NOTIFY.

+

+  @param  PeiServices A pointer to the system PEI Services Table.

+  

+  @param  This A pointer to the EFI_PEI_SMBUS_PPI instance.

+  

+  @param  SlaveAddress The SMBUS hardware address to which the SMBUS 

+  device is preassigned or allocated.

+  

+  @param  Data Data of the SMBus host notify command that 

+  the caller wants to be called.

+

+  @return Status Code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_SMBUS_NOTIFY_FUNCTION) (

+  IN      EFI_PEI_SERVICES              **PeiServices,

+  IN EFI_PEI_SMBUS_PPI                  *SmbusPpi,

+  IN      EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress,

+  IN      UINTN                         Data

+  );

+

+/**

+  The ArpDevice() function enumerates the entire bus or enumerates a specific 

+  device that is identified by SmbusUdid. 

+

+  @param  PeiServices A pointer to the system PEI Services Table.

+  

+  @param  This A pointer to the EFI_PEI_SMBUS_PPI instance.

+  

+  @param  ArpAll A Boolean expression that indicates if the host drivers need 

+  to enumerate all the devices or enumerate only the device that is identified 

+  by SmbusUdid. If ArpAll is TRUE, SmbusUdid and SlaveAddress are optional. 

+  If ArpAll is FALSE, ArpDevice will enumerate SmbusUdid and the address 

+  will be at SlaveAddress.

+  

+  @param  SmbusUdid The targeted SMBus Unique Device Identifier (UDID). 

+  The UDID may not exist for SMBus devices with fixed addresses. 

+  

+  @param  SlaveAddress The new SMBus address for the slave device for 

+  which the operation is targeted. 

+

+  @retval EFI_SUCCESS The SMBus slave device address was set.

+  

+  @retval EFI_INVALID_PARAMETER SlaveAddress is NULL.

+  

+  @retval EFI_OUT_OF_RESOURCES The request could not be completed 

+  due to a lack of resources.

+  

+  @retval EFI_TIMEOUT The SMBus slave device did not respond.

+  

+  @retval EFI_DEVICE_ERROR The request was not completed because the transaction failed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_SMBUS_PPI_ARP_DEVICE) (

+  IN      EFI_PEI_SERVICES          **PeiServices,

+  IN EFI_PEI_SMBUS_PPI              *This,

+  IN      BOOLEAN                   ArpAll,

+  IN      EFI_SMBUS_UDID            *SmbusUdid, OPTIONAL

+  IN OUT  EFI_SMBUS_DEVICE_ADDRESS  *SlaveAddress OPTIONAL

+  );

+

+typedef struct {

+  EFI_SMBUS_DEVICE_ADDRESS  SmbusDeviceAddress;

+  EFI_SMBUS_UDID            SmbusDeviceUdid;

+} EFI_SMBUS_DEVICE_MAP;

+

+/**

+  The GetArpMap() function returns the mapping of all the SMBus devices 

+  that are enumerated by the SMBus host driver. 

+

+  @param  PeiServices A pointer to the system PEI Services Table.

+  

+  @param  This A pointer to the EFI_PEI_SMBUS_PPI instance.

+  

+  @param  Length Size of the buffer that contains the SMBus device map.

+  

+  @param  SmbusDeviceMap The pointer to the device map as enumerated 

+  by the SMBus controller driver.

+

+  @retval EFI_SUCCESS The device map was returned correctly in the buffer.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_SMBUS_PPI_GET_ARP_MAP) (

+  IN      EFI_PEI_SERVICES          **PeiServices,

+  IN EFI_PEI_SMBUS_PPI              *This,

+  IN OUT  UINTN                     *Length,

+  IN OUT  EFI_SMBUS_DEVICE_MAP      **SmbusDeviceMap

+  );

+

+/**

+  The Notify() function registers all the callback functions to allow the 

+  bus driver to call these functions when the SlaveAddress/Data pair happens.

+

+  @param  PeiServices A pointer to the system PEI Services Table.

+  

+  @param  This A pointer to the EFI_PEI_SMBUS_PPI instance.

+  

+  @param  SlaveAddress Address that the host controller detects as 

+  sending a message and calls all the registered functions.

+  

+  @param  Data Data that the host controller detects as sending a message 

+  and calls all the registered functions.

+  

+  @param  NotifyFunction The function to call when the bus driver 

+  detects the SlaveAddress and Data pair.

+

+  @retval EFI_SUCCESS NotifyFunction has been registered.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_SMBUS_PPI_NOTIFY) (

+  IN      EFI_PEI_SERVICES          **PeiServices,

+  IN EFI_PEI_SMBUS_PPI              *This,

+  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,

+  IN      UINTN                     Data,

+  IN  EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction

+  );

+

+/**

+  @par Ppi Description:

+  Provides the basic I/O interfaces that a PEIM uses to access 

+  its SMBus controller and the slave devices attached to it.

+

+  @param Execute

+  Executes the SMBus operation to an SMBus slave device.

+

+  @param ArpDevice

+  Allows an SMBus 2.0 device(s) to be Address Resolution Protocol (ARP)

+

+  @param GetArpMap

+  Allows a PEIM to retrieve the address that was allocated by the SMBus 

+  host controller during enumeration/ARP.

+

+  @param Notify

+  Allows a driver to register for a callback to the SMBus host 

+  controller driver when the bus issues a notification to the bus controller PEIM.

+

+**/

+struct _EFI_PEI_SMBUS_PPI {

+  EFI_PEI_SMBUS_PPI_EXECUTE_OPERATION Execute;

+  EFI_PEI_SMBUS_PPI_ARP_DEVICE        ArpDevice;

+  EFI_PEI_SMBUS_PPI_GET_ARP_MAP       GetArpMap;

+  EFI_PEI_SMBUS_PPI_NOTIFY            Notify;

+};

+

+extern EFI_GUID gEfiPeiSmbusPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/Stall.h b/edk2/MdePkg/Include/Ppi/Stall.h
new file mode 100644
index 0000000..363baa6
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/Stall.h
@@ -0,0 +1,73 @@
+/** @file

+  This file declares Stall PPI.

+

+  This code abstracts the PEI core to provide Stall services.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Stall.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __STALL_PPI_H__

+#define __STALL_PPI_H__

+

+#define EFI_PEI_STALL_PPI_GUID \

+  { \

+    0x1f4c6f90, 0xb06b, 0x48d8, {0xa2, 0x01, 0xba, 0xe5, 0xf1, 0xcd, 0x7d, 0x56 } \

+  }

+

+typedef struct _EFI_PEI_STALL_PPI EFI_PEI_STALL_PPI;

+

+/**

+  The Stall() function provides a blocking stall for at least the number 

+  of microseconds stipulated in the final argument of the API.

+

+  @param  PeiServices An indirect pointer to the PEI Services Table 

+  published by the PEI Foundation. 

+  

+  @param  This Pointer to the local data for the interface.

+  

+  @param  Microseconds Number of microseconds for which to stall.

+

+  @retval EFI_SUCCESS The service provided at least the required delay.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PEI_STALL) (

+  IN EFI_PEI_SERVICES           **PeiServices,

+  IN EFI_PEI_STALL_PPI          *This,

+  IN UINTN                      Microseconds

+  );

+

+/**

+  @par Ppi Description:

+  This service provides a simple, blocking stall with platform-specific resolution. 

+

+  @param Resolution

+  The resolution in microseconds of the stall services.

+

+  @param Stall

+  The actual stall procedure call. 

+

+**/

+struct _EFI_PEI_STALL_PPI {

+  UINTN          Resolution;

+  EFI_PEI_STALL  Stall;

+};

+

+extern EFI_GUID gEfiPeiStallPpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Ppi/StatusCode.h b/edk2/MdePkg/Include/Ppi/StatusCode.h
new file mode 100644
index 0000000..5470222
--- /dev/null
+++ b/edk2/MdePkg/Include/Ppi/StatusCode.h
@@ -0,0 +1,42 @@
+/** @file

+  This file declares Status Code PPI.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  StatusCode.h

+

+  @par Revision Reference:

+  This PPI is defined in PEI CIS.

+  Version 0.91.

+

+**/

+

+#ifndef __STATUS_CODE_PPI_H__

+#define __STATUS_CODE_PPI_H__

+

+#define EFI_PEI_REPORT_PROGRESS_CODE_PPI_GUID \

+  { 0x229832d3, 0x7a30, 0x4b36, {0xb8, 0x27, 0xf4, 0xc, 0xb7, 0xd4, 0x54, 0x36 } }

+

+/**

+  @par Ppi Description:

+  This ppi provides the sevice to report status code. There can be only one instance 

+  of this service in the system.

+

+  @param ReportStatusCode

+  Service that allows PEIMs to report status codes. This function is defined in Peicis.h

+

+**/

+typedef struct {

+  EFI_PEI_REPORT_STATUS_CODE  ReportStatusCode;

+} EFI_PEI_PROGRESS_CODE_PPI;

+

+extern EFI_GUID gEfiPeiStatusCodePpiGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/AcpiSupport.h b/edk2/MdePkg/Include/Protocol/AcpiSupport.h
new file mode 100644
index 0000000..790cdf2
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/AcpiSupport.h
@@ -0,0 +1,173 @@
+/** @file

+  Definition of the ACPI Support protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  AcpiSupport.h

+

+  @par Revision Reference:

+  This is defined in the ACPI Specification 0.9.

+  

+**/

+

+#ifndef _ACPI_SUPPORT_PROTOCOL_H_

+#define _ACPI_SUPPORT_PROTOCOL_H_

+

+typedef struct _EFI_ACPI_SUPPORT_PROTOCOL EFI_ACPI_SUPPORT_PROTOCOL;

+

+//

+// ACPI Support Protocol GUID

+//

+#define EFI_ACPI_SUPPORT_GUID \

+  { \

+    0xdbff9d55, 0x89b7, 0x46da, {0xbd, 0xdf, 0x67, 0x7d, 0x3d, 0xc0, 0x24, 0x1d } \

+  }

+

+//

+// Protocol Data Definitions

+//

+//

+// ACPI Version bitmap definition:

+//

+// EFI_ACPI_TABLE_VERSION_1_0B - ACPI Version 1.0b

+// EFI_ACPI_TABLE_VERSION_2_0 - ACPI Version 2.0

+// EFI_ACPI_TABLE_VERSION_3_0 - ACPI Version 3.0

+// EFI_ACPI_TABLE_VERSION_NONE - No ACPI Versions.  This might be used

+//  to create memory-based operation regions or other information

+//  that is not part of the ACPI "tree" but must still be found

+//  in ACPI memory space and/or managed by the core ACPI driver.

+//

+// Note that EFI provides discrete GUIDs for each version of ACPI

+// that is supported.  It is expected that each EFI GUIDed

+// version of ACPI will also have a corresponding bitmap

+// definition.  This allows maintenance of separate ACPI trees

+// for each distinctly different version of ACPI.

+//

+#define EFI_ACPI_TABLE_VERSION      UINT32

+

+#define EFI_ACPI_TABLE_VERSION_NONE (1 << 0)

+#define EFI_ACPI_TABLE_VERSION_1_0B (1 << 1)

+#define EFI_ACPI_TABLE_VERSION_2_0  (1 << 2)

+#define EFI_ACPI_TABLE_VERSION_3_0  (1 << 3)

+

+//

+// Protocol Member Functions

+//

+

+/**

+  Returns a requested ACPI table.

+

+  @param  This A pointer to the EFI_ACPI_SUPPORT_PROTOCOL instance.

+  

+  @param  Index The zero-based index of the table to retrieve.

+  

+  @param  Table Pointer for returning the table buffer.

+  

+  @param  Version Updated with the ACPI versions to which this table belongs.

+  

+  @param  Handle Pointer for identifying the table.

+

+  @retval EFI_SUCCESS The function completed successfully.

+  

+  @retval EFI_NOT_FOUND The requested index is too large and a table was not found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ACPI_GET_ACPI_TABLE) (

+  IN EFI_ACPI_SUPPORT_PROTOCOL            *This,

+  IN INTN                                 Index,

+  OUT VOID                                **Table,

+  OUT EFI_ACPI_TABLE_VERSION              *Version,

+  OUT UINTN                               *Handle

+  );

+

+/**

+  Used to add, remove, or update ACPI tables.

+

+  @param  This A pointer to the EFI_ACPI_SUPPORT_PROTOCOL instance.

+  

+  @param  Table Pointer to the new table to add or update.

+  

+  @param  Checksum If TRUE, indicates that the checksum should be 

+  calculated for this table.

+  

+  @param  Version Indicates to which version(s) of ACPI the table should be added.

+  

+  @param  Pointer to the handle of the table to remove or update.

+

+  @retval EFI_SUCCESS The function completed successfully.

+  

+  @retval EFI_INVALID_PARAMETER *Handle was zero and Table was NULL.

+  

+  @retval EFI_ABORTED Could not complete the desired action.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ACPI_SET_ACPI_TABLE) (

+  IN EFI_ACPI_SUPPORT_PROTOCOL            *This,

+  IN VOID                                 *Table OPTIONAL,

+  IN BOOLEAN                              Checksum,

+  IN EFI_ACPI_TABLE_VERSION               Version,

+  IN OUT UINTN                            *Handle

+  );

+

+/**

+  Causes one or more versions of the ACPI tables to be published in 

+  the EFI system configuration tables.

+

+  @param  This A pointer to the EFI_ACPI_SUPPORT_PROTOCOL instance.

+  

+  @param  Version Indicates to which version(s) of ACPI that the table should be published. 

+

+  @retval EFI_SUCCESS The function completed successfully.

+  

+  @retval EFI_ABORTED An error occurred and the function could not complete successfully.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ACPI_PUBLISH_TABLES) (

+  IN EFI_ACPI_SUPPORT_PROTOCOL            *This,

+  IN EFI_ACPI_TABLE_VERSION               Version

+  );

+

+//

+// ACPI Support Protocol

+//

+/**

+  @par Protocol Description:

+  This protocol provides some basic services to support publishing ACPI system 

+  tables. The services handle many of the more mundane tasks that are required 

+  to publish a set of tables. 

+

+  @param GetAcpiTable

+  Returns a table specified by an index if it exists.

+

+  @param SetAcpiTable

+  Adds, removes, or updates ACPI tables

+

+  @param PublishTables

+  Publishes the ACPI tables.

+

+**/

+struct _EFI_ACPI_SUPPORT_PROTOCOL {

+  EFI_ACPI_GET_ACPI_TABLE GetAcpiTable;

+  EFI_ACPI_SET_ACPI_TABLE SetAcpiTable;

+  EFI_ACPI_PUBLISH_TABLES PublishTables;

+};

+

+//

+// Extern the GUID for protocol users.

+//

+extern EFI_GUID gEfiAcpiSupportProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Arp.h b/edk2/MdePkg/Include/Protocol/Arp.h
new file mode 100644
index 0000000..7394f3f
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Arp.h
@@ -0,0 +1,259 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+  

+  Module Name:  Arp.h

+  

+**/

+

+#ifndef __EFI_ARP_PROTOCOL_H__

+#define __EFI_ARP_PROTOCOL_H__

+

+#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3 } \

+  }

+

+#define EFI_ARP_PROTOCOL_GUID \

+  { \

+    0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c } \

+  }

+

+typedef struct _EFI_ARP_PROTOCOL EFI_ARP_PROTOCOL;

+

+typedef struct {

+UINT32                      Size;

+BOOLEAN                     DenyFlag;

+BOOLEAN                     StaticFlag;

+UINT16                      HwAddressType;

+UINT16                      SwAddressType;

+UINT8                       HwAddressLength;

+UINT8                       SwAddressLength;

+} EFI_ARP_FIND_DATA;

+

+typedef struct {

+  UINT16                    SwAddressType;      // Host byte order

+  UINT8                     SwAddressLength;

+  VOID                      *StationAddress;    // Network byte order

+  UINT32                    EntryTimeOut;

+  UINT32                    RetryCount;

+  UINT32                    RetryTimeOut;

+} EFI_ARP_CONFIG_DATA;

+

+

+/**

+  Assigns a station address (protocol type and network address) to this instance of the ARP cache.

+

+  @param  This                   A pointer to the EFI_ARP_PROTOCOL instance.

+  @param  ConfigData             A pointer to the EFI_ARP_CONFIG_DATA structure.Buffer

+

+  @retval EFI_SUCCESS           The new station address was successfully registered.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+  @retval EFI_ACCESS_DENIED     The SwAddressType, SwAddressLength, or

+                                StationAddress is different from the one that is already

+                                registered.

+  @retval EFI_OUT_OF_RESOURCES  Storage for the new StationAddress could not be allocated.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_ARP_CONFIGURE) (

+  IN EFI_ARP_PROTOCOL       *This,

+  IN EFI_ARP_CONFIG_DATA    *ConfigData   OPTIONAL

+  )

+;  

+

+/**

+  Inserts an entry to the ARP cache.

+

+  @param  This            A pointer to the EFI_ARP_PROTOCOL instance.  

+  @param  DenyFlag        Set to TRUE if this entry is a ¡°deny¡± entry. Set to FALSE if this

+                          entry is a ¡°normal¡± entry.

+  @param  TargetSwAddress Pointer to a protocol address to add (or deny). May be set to

+                          NULL if DenyFlag is TRUE.

+  @param  TargetHwAddress Pointer to a hardware address to add (or deny). May be set to

+                          NULL if DenyFlag is TRUE.

+  @param  TimeoutValue    Time in 100-ns units that this entry will remain in the ARP

+                          cache. A value of zero means that the entry is permanent. A

+                          nonzero value will override the one given by Configure() if

+                          the entry to be added is dynamic entry.

+  @param  Overwrite       If TRUE, the matching cache entry will be overwritten with the

+                          supplied parameters. If FALSE, EFI_ACCESS_DENIED

+

+  @retval EFI_SUCCESS           The entry has been added or updated.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+  @retval EFI_OUT_OF_RESOURCES  The new ARP cache entry could not be allocated.

+  @retval EFI_ACCESS_DENIED     The ARP cache entry already exists and Overwrite is not true.

+  @retval EFI_NOT_STARTED       The ARP driver instance has not been configured.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ARP_ADD) (

+  IN EFI_ARP_PROTOCOL       *This,

+  IN BOOLEAN                DenyFlag,

+  IN VOID                   *TargetSwAddress  OPTIONAL,

+  IN VOID                   *TargetHwAddress  OPTIONAL,

+  IN UINT32                 TimeoutValue,

+  IN BOOLEAN                Overwrite

+  )

+;  

+

+/**

+  Locates one or more entries in the ARP cache.

+

+  @param  This            A pointer to the EFI_ARP_PROTOCOL instance.

+  @param  BySwAddress     Set to TRUE to look for matching software protocol addresses.

+                          Set to FALSE to look for matching hardware protocol addresses.

+  @param  AddressBuffer   Pointer to address buffer. Set to NULL to match all addresses.

+  @param  EntryLength     The size of an entry in the entries buffer. To keep the

+                          EFI_ARP_FIND_DATA structure properly aligned, this field

+                          may be longer than sizeof(EFI_ARP_FIND_DATA) plus

+                          the length of the software and hardware addresses.

+  @param  EntryCount      The number of ARP cache entries that are found by the specified criteria.

+  @param  Entries         Pointer to the buffer that will receive the ARP cache entries.

+  @param  Refresh         Set to TRUE to refresh the timeout value of the matching ARP

+                          cache entry.

+

+  @retval EFI_SUCCESS           The requested ARP cache entries were copied into the buffer.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+  @retval EFI_NOT_FOUND         No matching entries were found.

+  @retval EFI_NOT_STARTED       The ARP driver instance has not been configured.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_ARP_FIND) (

+  IN EFI_ARP_PROTOCOL       *This,

+  IN BOOLEAN                BySwAddress,

+  IN VOID                   *AddressBuffer    OPTIONAL,

+  OUT UINT32                *EntryLength      OPTIONAL,

+  OUT UINT32                *EntryCount       OPTIONAL,

+  OUT EFI_ARP_FIND_DATA     **Entries         OPTIONAL,

+  IN BOOLEAN                Refresh

+  )

+;  

+

+

+/**

+  Removes entries from the ARP cache.

+

+  @param  This          A pointer to the EFI_ARP_PROTOCOL instance.

+  @param  BySwAddress   Set to TRUE to delete matching protocol addresses.

+                        Set to FALSE to delete matching hardware addresses.

+  @param  AddressBuffer Pointer to the address buffer that is used as a key to look for the

+                        cache entry. Set to NULL to delete all entries.

+

+  @retval EFI_SUCCESS           The entry was removed from the ARP cache.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_NOT_FOUND         The specified deletion key was not found.

+  @retval EFI_NOT_STARTED       The ARP driver instance has not been configured.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ARP_DELETE) (

+  IN EFI_ARP_PROTOCOL       *This,

+  IN BOOLEAN                BySwAddress,

+  IN VOID                   *AddressBuffer   OPTIONAL

+  )

+;  

+

+/**

+  Removes all dynamic ARP cache entries that were added by this interface.

+

+  @param  This                   A pointer to the EFI_ARP_PROTOCOL instance.

+                                 

+  @retval EFI_SUCCESS           The cache has been flushed.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_NOT_FOUND         There are no matching dynamic cache entries.

+  @retval EFI_NOT_STARTED       The ARP driver instance has not been configured.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ARP_FLUSH) (

+  IN EFI_ARP_PROTOCOL       *This

+  )

+;  

+

+/**

+  Starts an ARP request session.

+

+  @param  This            A pointer to the EFI_ARP_PROTOCOL instance.

+  @param  TargetSwAddress Pointer to the protocol address to resolve.

+  @param  ResolvedEvent   Pointer to the event that will be signaled when the address is

+                          resolved or some error occurs.

+  @param  TargetHwAddress Pointer to the buffer for the resolved hardware address in

+                          network byte order. The buffer must be large enough to hold the

+                          resulting hardware address. TargetHwAddress must not be

+                          NULL.

+

+  @retval EFI_SUCCESS           The data was copied from the ARP cache into the

+                                TargetHwAddress buffer.

+  @retval EFI_INVALID_PARAMETER This or TargetHwAddress is NULL.

+  @retval EFI_ACCESS_DENIED     The requested address is not present in the normal ARP cache but

+                                is present in the deny address list. Outgoing traffic to that address is

+                                forbidden.

+  @retval EFI_NOT_STARTED       The ARP driver instance has not been configured.

+  @retval EFI_NOT_READY         The request has been started and is not finished.

+  @retval EFI_UNSUPPORTED       The requested conversion is not supported in this implementation or

+                                configuration.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ARP_REQUEST) (

+  IN EFI_ARP_PROTOCOL       *This, 

+  IN VOID                   *TargetSwAddress  OPTIONAL,

+  IN EFI_EVENT              ResolvedEvent     OPTIONAL,

+  OUT VOID                  *TargetHwAddress  

+  )

+;  

+

+/**

+  Cancels an ARP request session.

+

+  @param  This            A pointer to the EFI_ARP_PROTOCOL instance.

+  @param  TargetSwAddress Pointer to the protocol address in previous request session.

+  @param  ResolvedEvent   Pointer to the event that is used as the notification event in

+                          previous request session.

+

+  @retval EFI_SUCCESS           The pending request session(s) is/are aborted and corresponding

+                                event(s) is/are signaled.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+  @retval EFI_NOT_STARTED       The ARP driver instance has not been configured.

+  @retval EFI_NOT_FOUND         The request is not issued by

+                                EFI_ARP_PROTOCOL.Request().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ARP_CANCEL) (

+  IN EFI_ARP_PROTOCOL       *This, 

+  IN VOID                   *TargetSwAddress  OPTIONAL,

+  IN EFI_EVENT              ResolvedEvent     OPTIONAL

+  )

+;  

+

+struct _EFI_ARP_PROTOCOL {

+  EFI_ARP_CONFIGURE         Configure;

+  EFI_ARP_ADD               Add;

+  EFI_ARP_FIND              Find;

+  EFI_ARP_DELETE            Delete;

+  EFI_ARP_FLUSH             Flush;

+  EFI_ARP_REQUEST           Request;

+  EFI_ARP_CANCEL            Cancel;

+};

+

+

+extern EFI_GUID gEfiArpServiceBindingProtocolGuid;

+extern EFI_GUID gEfiArpProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/AuthenticationInfo.h b/edk2/MdePkg/Include/Protocol/AuthenticationInfo.h
new file mode 100644
index 0000000..f80dbf3
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/AuthenticationInfo.h
@@ -0,0 +1,125 @@
+/** @file

+  EFI_AUTHENTICATION_INFO_PROTOCOL as defined in UEFI 2.0.

+  This protocol is used on any device handle to obtain authentication information 

+  associated with the physical or logical device.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  AuthenticationInfo.h

+

+**/

+

+#ifndef __AUTHENTICATION_INFO_H__

+#define __AUTHENTICATION_INFO_H__

+

+#define EFI_AUTHENTICATION_INFO_PROTOCOL_GUID \

+  { \

+    0x7671d9d0, 0x53db, 0x4173, {0xaa, 0x69, 0x23, 0x27, 0xf2, 0x1f, 0x0b, 0xc7 } \

+  }

+  

+#define EFI_AUTHENTICATION_CHAP_RADIUS_GUID \

+  { \

+    0xd6062b50, 0x15ca, 0x11da, {0x92, 0x19, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \

+  }

+

+#define EFI_AUTHENTICATION_CHAP_LOCAL_GUID \

+  { \

+    0xc280c73e, 0x15ca, 0x11da, {0xb0, 0xca, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \

+  }

+

+typedef struct _EFI_AUTHENTICATION_INFO_PROTOCOL EFI_AUTHENTICATION_INFO_PROTOCOL;

+

+typedef struct {

+  EFI_GUID         Guid;

+  UINT16           Length;

+} AUTH_NODE_HEADER;

+

+typedef struct {

+  AUTH_NODE_HEADER Header;

+  EFI_IPv6_ADDRESS RadiusIpAddr;             // IPv4 or IPv6 address

+  UINT16           Reserved;

+  EFI_IPv6_ADDRESS NasIpAddr;                // IPv4 or IPv6 address

+  UINT16           NasSecretLength; 

+  UINT8            *NasSecret;      

+  UINT16           ChapSecretLength;

+  UINT8            *ChapSecret;

+  UINT16           ChapNameLength;

+  UINT8            *ChapName;

+} CHAP_RADIUS_AUTH_NODE;

+

+typedef struct {

+  AUTH_NODE_HEADER Header;

+  UINT16           Reserved;

+  UINT16           UserSecretLength;

+  UINT8            *UserSecret;     

+  UINT16           UserNameLength;

+  UINT8            *UserName;

+  UINT16           ChapSecretLength;

+  UINT8            *ChapSecret;

+  UINT16           ChapNameLength;

+  UINT8            *ChapName;

+} CHAP_LOCAL_AUTH_NODE;

+

+/**

+  Retrieves the Authentication information associated with a particular controller handle.

+

+  @param  This                   Pointer to the EFI_AUTHENTICATION_INFO_PROTOCOL

+  @param  ControllerHandle       Handle to the Controller

+  @param  Buffer                 Pointer to the authentication information.

+

+  @retval EFI_SUCCESS           Successfully retrieved Authentication information for the given ControllerHandle

+  @retval EFI_INVALID_PARAMETER No matching Authentication information found for the given ControllerHandle

+  @retval EFI_DEVICE_ERROR      The authentication information could not be retrieved due to a

+                                hardware error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_AUTHENTICATION_PROTOCOL_INFO_GET) (

+  IN  EFI_AUTHENTICATION_INFO_PROTOCOL *This,

+  IN  EFI_HANDLE                       *ControllerHandle,

+  OUT VOID                             *Buffer

+  )

+;  

+

+/**

+  Set the Authentication information for a given controller handle.

+

+  @param  This                  Pointer to the EFI_AUTHENTICATION_INFO_PROTOCOL

+  @param  ControllerHandle      Handle to the Controller

+  @param  Buffer                Pointer to the authentication information.

+                                

+  @retval EFI_SUCCESS          Successfully set Authentication information for the given ControllerHandle

+  @retval EFI_UNSUPPORTED      If the platform policies do not allow setting of the Authentication

+                               information.

+  @retval EFI_DEVICE_ERROR     The authentication information could not be configured due to a

+                               hardware error.

+  @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the data.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_AUTHENTICATION_PROTOCOL_INFO_SET) (

+  IN EFI_AUTHENTICATION_INFO_PROTOCOL  *This,

+  IN EFI_HANDLE                        *ControllerHandle,

+  IN VOID                              *Buffer

+  )

+;  

+

+struct _EFI_AUTHENTICATION_INFO_PROTOCOL {

+  EFI_AUTHENTICATION_PROTOCOL_INFO_GET Get;

+  EFI_AUTHENTICATION_PROTOCOL_INFO_SET Set;

+};

+

+extern EFI_GUID gEfiAuthenticationInfoProtocolGuid;

+extern EFI_GUID gEfiAuthenticationChapRadiusGuid;

+extern EFI_GUID gEfiAuthenticationChapLocalGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Bis.h b/edk2/MdePkg/Include/Protocol/Bis.h
new file mode 100644
index 0000000..ffc66f6
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Bis.h
@@ -0,0 +1,418 @@
+/** @file

+  This file defines the BIS protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Bis.h

+

+**/

+

+#ifndef __BIS_H__

+#define __BIS_H__

+

+#define EFI_BIS_PROTOCOL_GUID \

+  { \

+    0x0b64aab0, 0x5429, 0x11d4, {0x98, 0x16, 0x00, 0xa0, 0xc9, 0x1f, 0xad, 0xcf } \

+  }

+

+typedef struct _EFI_BIS_PROTOCOL  EFI_BIS_PROTOCOL;

+

+

+//

+// Basic types

+//

+typedef VOID    *BIS_APPLICATION_HANDLE;

+typedef UINT16  BIS_ALG_ID;

+typedef UINT32  BIS_CERT_ID;

+

+//

+// EFI_BIS_DATA type.

+//

+// EFI_BIS_DATA instances obtained from BIS must be freed by calling Free( ).

+//

+typedef struct {

+  UINT32  Length; // Length of Data in 8 bit bytes.

+  UINT8   *Data;  // 32 Bit Flat Address of data.

+} EFI_BIS_DATA;

+

+//

+// EFI_BIS_VERSION type.

+//

+typedef struct {

+  UINT32  Major;  // BIS Interface version number.

+  UINT32  Minor;  // Build number.

+} EFI_BIS_VERSION;

+

+//

+// ----------------------------------------------------//

+// Use these values to initialize EFI_BIS_VERSION.Major

+// and to interpret results of Initialize.

+// ----------------------------------------------------//

+//

+#define BIS_CURRENT_VERSION_MAJOR BIS_VERSION_1

+#define BIS_VERSION_1             1

+

+//

+// EFI_BIS_SIGNATURE_INFO type.

+//

+typedef struct {

+  BIS_CERT_ID CertificateID;  // Truncated hash of platform Boot Object

+  //  authorization certificate.

+  //

+  BIS_ALG_ID  AlgorithmID;  // A signature algorithm number.

+  UINT16      KeyLength;    // Length of alg. keys in bits.

+} EFI_BIS_SIGNATURE_INFO;

+

+//

+// Currently defined values for EFI_BIS_SIGNATURE_INFO.AlgorithmID.

+// The exact numeric values come from

+//    "Common Data Security Architecture (CDSA) Specification".

+//

+#define BIS_ALG_DSA     (41)  // CSSM_ALGID_DSA

+#define BIS_ALG_RSA_MD5 (42)  // CSSM_ALGID_MD5_WITH_RSA

+// Currently defined values for EFI_BIS_SIGNATURE_INFO.CertificateId.

+//

+#define BIS_CERT_ID_DSA     BIS_ALG_DSA     // CSSM_ALGID_DSA

+#define BIS_CERT_ID_RSA_MD5 BIS_ALG_RSA_MD5 // CSSM_ALGID_MD5_WITH_RSA

+// The  following  is a mask value that gets applied to the truncated hash of a

+// platform  Boot Object Authorization Certificate to create the certificateID.

+// A certificateID must not have any bits set to the value 1 other than bits in

+// this mask.

+//

+#define BIS_CERT_ID_MASK  (0xFF7F7FFF)

+

+//

+// Macros for dealing with the EFI_BIS_DATA object obtained

+// from BIS_GetSignatureInfo()

+// BIS_GET_SIGINFO_COUNT - tells how many EFI_BIS_SIGNATURE_INFO

+//  elements are contained in a EFI_BIS_DATA struct pointed to

+//  by the provided EFI_BIS_DATA*.

+//

+#define BIS_GET_SIGINFO_COUNT(BisDataPtr) ((BisDataPtr)->Length / sizeof (EFI_BIS_SIGNATURE_INFO))

+

+//

+// BIS_GET_SIGINFO_ARRAY - produces a EFI_BIS_SIGNATURE_INFO*

+//  from a given EFI_BIS_DATA*.

+//

+#define BIS_GET_SIGINFO_ARRAY(BisDataPtr) ((EFI_BIS_SIGNATURE_INFO *) (BisDataPtr)->Data)

+

+//

+// Binary Value of "X-Intel-BIS-ParameterSet" Attribute.

+// (Value is Base64 encoded in actual signed manifest).

+// {EDD35E31-07B9-11d2-83A3-00A0C91FADCF}

+//

+#define BOOT_OBJECT_AUTHORIZATION_PARMSET_GUID \

+  { \

+    0xedd35e31, 0x7b9, 0x11d2, \

+    { \

+      0x83, 0xa3, 0x0, 0xa0, 0xc9, 0x1f, 0xad, 0xcf \

+    } \

+  }

+

+//

+// Support old name for backward compatible

+//

+#define BOOT_OBJECT_AUTHORIZATION_PARMSET_GUIDVALUE \

+        BOOT_OBJECT_AUTHORIZATION_PARMSET_GUID

+

+/**                                                                 

+  Initializes the BIS service, checking that it is compatible with the version requested by the caller.

+  After this call, other BIS functions may be invoked.                                                 

+    

+  @param  This                     A pointer to the EFI_BIS_PROTOCOL object.

+  @param  AppHandle                The function writes the new BIS_APPLICATION_HANDLE if           

+                                   successful, otherwise it writes NULL. The caller must eventually

+                                   destroy this handle by calling Shutdown().                      

+  @param  InterfaceVersion         On input, the caller supplies the major version number of the

+                                   interface version desired.                                   

+                                   On output, both the major and minor                         

+                                   version numbers are updated with the major and minor version

+                                   numbers of the interface                                    

+  @param  TargetAddress            Indicates a network or device address of the BIS platform to connect to.                                                                 

+  

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_INCOMPATIBLE_VERSION The InterfaceVersion.Major requested by the                

+                                   caller was not compatible with the interface version of the

+  @retval EFI_UNSUPPORTED          This is a local-platform implementation and        

+                                   TargetAddress.Data was not NULL, or                

+                                   TargetAddress.Data was any other value that was not

+                                   supported by the implementation.                   

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                              

+  @retval EFI_DEVICE_ERROR         The function encountered an unexpected internal failure.

+  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.

+                                          

+**/                                       

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_INITIALIZE) (

+  IN     EFI_BIS_PROTOCOL        *This,              

+  OUT    BIS_APPLICATION_HANDLE  *AppHandle,         

+  IN OUT EFI_BIS_VERSION         *InterfaceVersion,  

+  IN     EFI_BIS_DATA            *TargetAddress      

+  );

+

+/**                                                                 

+  Frees memory structures allocated and returned by other functions in the EFI_BIS protocol.  

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                         

+  @param  ToFree                   An EFI_BIS_DATA* and associated memory block to be freed.

+  

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid

+                                   application instance handle associated with the EFI_BIS protocol.                                     

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                                

+  @retval EFI_INVALID_PARAMETER    The ToFree parameter is not or is no longer a memory resource

+                                   associated with this AppHandle.                              

+                                           

+**/     

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_FREE) (

+  IN BIS_APPLICATION_HANDLE  AppHandle,               

+  IN EFI_BIS_DATA            *ToFree                  

+  );

+

+/**                                                                 

+  Shuts down an application¡¯s instance of the BIS service, invalidating the application handle. After

+  this call, other BIS functions may no longer be invoked using the application handle value.         

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid

+                                   application instance handle associated with the EFI_BIS protocol.                                     

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                                

+  @retval EFI_DEVICE_ERROR         The function encountered an unexpected internal failure.  

+                                           

+**/   

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_SHUTDOWN) (

+  IN BIS_APPLICATION_HANDLE  AppHandle               

+  );

+

+/**                                                                 

+  Retrieves the certificate that has been configured as the identity of the organization designated as

+  the source of authorization for signatures of boot objects.

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  Certificate              The function writes an allocated EFI_BIS_DATA* containing the Boot

+                                   Object Authorization Certificate object.                            

+  

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid

+                                   application instance handle associated with the EFI_BIS protocol.                                     

+  @retval EFI_NOT_FOUND            There is no Boot Object Authorization Certificate currently installed.                        

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                                

+  @retval EFI_INVALID_PARAMETER    The Certificate parameter supplied by the caller is NULL or

+                                   an invalid memory reference.                                       

+                                   

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_GET_BOOT_OBJECT_AUTHORIZATION_CERTIFICATE) (

+  IN  BIS_APPLICATION_HANDLE  AppHandle,              

+  OUT EFI_BIS_DATA            **Certificate           

+  );

+

+/**                                                                 

+  Verifies the integrity and authorization of the indicated data object according to the

+  indicated credentials.                                                                

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  Credentials              A Signed Manifest containing verification information for the indicated

+                                   data object.                                                            

+  @param  DataObject               An in-memory copy of the raw data object to be verified.

+  @param  IsVerified               The function writes TRUE if the verification succeeded, otherwise

+                                   FALSE.                                                           

+                                   

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid

+                                   application instance handle associated with the EFI_BIS protocol.                                       

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                                

+  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.

+  @retval EFI_SECURITY_VIOLATION   The signed manifest supplied as the Credentials parameter

+                                   was invalid (could not be parsed) or Platform-specific authorization failed, etc.

+  @retval EFI_DEVICE_ERROR         An unexpected internal error occurred.                           

+                                   

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_VERIFY_BOOT_OBJECT) (

+  IN  BIS_APPLICATION_HANDLE AppHandle,               

+  IN  EFI_BIS_DATA           *Credentials,            

+  IN  EFI_BIS_DATA           *DataObject,             

+  OUT BOOLEAN                *IsVerified              

+  );

+

+/**                                                                 

+  Retrieves the current status of the Boot Authorization Check Flag.

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  CheckIsRequired          The function writes the value TRUE if a Boot Authorization Check is

+                                   currently required on this platform, otherwise the function writes 

+                                   FALSE.                                                             

+                                   

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid

+                                   application instance handle associated with the EFI_BIS protocol.                                       

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                                

+  @retval EFI_INVALID_PARAMETER    The CheckIsRequired parameter supplied by the caller is

+                                   NULL or an invalid memory reference.                   

+                                   

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_GET_BOOT_OBJECT_AUTHORIZATION_CHECKFLAG) (

+  IN  BIS_APPLICATION_HANDLE  AppHandle,             

+  OUT BOOLEAN                 *CheckIsRequired       

+  );

+

+/**                                                                 

+  Retrieves a unique token value to be included in the request credential for the next update of any

+  parameter in the Boot Object Authorization set                                                    

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  UpdateToken              The function writes an allocated EFI_BIS_DATA* containing the new

+                                   unique update token value.                                                                          

+                                   

+  @retval EFI_SUCCESS              The function completed successfully.

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid

+                                   application instance handle associated with the EFI_BIS protocol.                                       

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                                

+  @retval EFI_INVALID_PARAMETER    The UpdateToken parameter supplied by the caller is NULL or

+                                   an invalid memory reference.        

+  @retval EFI_DEVICE_ERROR         An unexpected internal error occurred.                                                            

+                                   

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_GET_BOOT_OBJECT_AUTHORIZATION_UPDATE_TOKEN) (

+  IN  BIS_APPLICATION_HANDLE  AppHandle,              

+  OUT EFI_BIS_DATA            **UpdateToken           

+  );

+

+/**                                                                 

+  Updates one of the configurable parameters of the Boot Object Authorization set.

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  RequestCredential        This is a Signed Manifest with embedded attributes that carry the details

+                                   of the requested update.                                                 

+  @param  NewUpdateToken           The function writes an allocated EFI_BIS_DATA* containing the new                        

+                                   unique update token value.                                       

+                                   

+  @retval EFI_SUCCESS              The function completed successfully.                                                

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid                              

+                                   application instance handle associated with the EFI_BIS protocol.                   

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                       

+  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.                                                 

+  @retval EFI_SECURITY_VIOLATION   The signed manifest supplied as the RequestCredential parameter                           

+                                   was invalid (could not be parsed) or Platform-specific authorization failed, etc.   

+  @retval EFI_DEVICE_ERROR         An unexpected internal error occurred.                                                                                                                                                                   

+                                   

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_UPDATE_BOOT_OBJECT_AUTHORIZATION) (

+  IN  BIS_APPLICATION_HANDLE AppHandle,               

+  IN  EFI_BIS_DATA           *RequestCredential,      

+  OUT EFI_BIS_DATA           **NewUpdateToken         

+  );

+

+/**                                                                 

+  Verifies the integrity and authorization of the indicated data object according to the indicated

+  credentials and authority certificate.                                                          

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  Credentials              A Signed Manifest containing verification information for the

+                                   indicated data object.                                       

+  @param  DataObject               An in-memory copy of the raw data object to be verified.

+  @param  SectionName              An ASCII (not Unicode) string giving the section name in the  

+                                   manifest holding the verification information (in other words,

+                                   hash value) that corresponds to DataObject.                             

+  @param  AuthorityCertificate     A digital certificate whose public key must match the signer¡¯s                              

+                                   public key which is found in the credentials.                  

+  @param  IsVerified               The function writes TRUE if the verification was successful.

+                                   Otherwise, the function writes FALSE.                       

+                                   

+  @retval EFI_SUCCESS              The function completed successfully.                                                

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid                              

+                                   application instance handle associated with the EFI_BIS protocol.                   

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                       

+  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.                                                 

+  @retval EFI_SECURITY_VIOLATION   The Credentials.Data supplied by the caller is NULL,

+                                   or the AuthorityCertificate supplied by the caller was 

+                                   invalid (could not be parsed),                      

+                                   or Platform-specific authorization failed, etc.   

+  @retval EFI_DEVICE_ERROR         An unexpected internal error occurred.                                                                                                                                                                   

+                                   

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_VERIFY_OBJECT_WITH_CREDENTIAL) (

+  IN  BIS_APPLICATION_HANDLE AppHandle,              

+  IN  EFI_BIS_DATA           *Credentials,           

+  IN  EFI_BIS_DATA           *DataObject,            

+  IN  EFI_BIS_DATA           *SectionName,           

+  IN  EFI_BIS_DATA           *AuthorityCertificate,  

+  OUT BOOLEAN                *IsVerified             

+  );

+

+/**                                                                 

+  Retrieves a list of digital certificate identifier, digital signature algorithm, hash algorithm, and keylength

+  combinations that the platform supports.                                                                      

+      

+  @param  AppHandle                An opaque handle that identifies the caller¡¯s instance of initialization

+                                   of the BIS service.                                                                                           

+  @param  SignatureInfo            The function writes an allocated EFI_BIS_DATA* containing the array

+                                   of EFI_BIS_SIGNATURE_INFO structures representing the supported    

+                                   digital certificate identifier, algorithm, and key length combinations.                                   

+                                   

+  @retval EFI_SUCCESS              The function completed successfully.                                                

+  @retval EFI_NO_MAPPING           The AppHandle parameter is not or is no longer a valid                              

+                                   application instance handle associated with the EFI_BIS protocol.                   

+  @retval EFI_OUT_OF_RESOURCES     The function failed due to lack of memory or other resources.                       

+  @retval EFI_INVALID_PARAMETER    The SignatureInfo parameter supplied by the caller is NULL

+                                   or an invalid memory reference.                           

+  @retval EFI_DEVICE_ERROR         An unexpected internal error occurred.                                                                                                                                                                   

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BIS_GET_SIGNATURE_INFO) (

+  IN  BIS_APPLICATION_HANDLE  AppHandle,           

+  OUT EFI_BIS_DATA            **SignatureInfo      

+  );

+

+struct _EFI_BIS_PROTOCOL {

+  EFI_BIS_INITIALIZE                                  Initialize;

+  EFI_BIS_SHUTDOWN                                    Shutdown;

+  EFI_BIS_FREE                                        Free;

+  EFI_BIS_GET_BOOT_OBJECT_AUTHORIZATION_CERTIFICATE   GetBootObjectAuthorizationCertificate;

+  EFI_BIS_GET_BOOT_OBJECT_AUTHORIZATION_CHECKFLAG     GetBootObjectAuthorizationCheckFlag;

+  EFI_BIS_GET_BOOT_OBJECT_AUTHORIZATION_UPDATE_TOKEN  GetBootObjectAuthorizationUpdateToken;

+  EFI_BIS_GET_SIGNATURE_INFO                          GetSignatureInfo;

+  EFI_BIS_UPDATE_BOOT_OBJECT_AUTHORIZATION            UpdateBootObjectAuthorization;

+  EFI_BIS_VERIFY_BOOT_OBJECT                          VerifyBootObject;

+  EFI_BIS_VERIFY_OBJECT_WITH_CREDENTIAL               VerifyObjectWithCredential;

+};

+

+extern EFI_GUID gEfiBisProtocolGuid;

+extern EFI_GUID gBootObjectAuthorizationParmsetGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/BlockIo.h b/edk2/MdePkg/Include/Protocol/BlockIo.h
new file mode 100644
index 0000000..4c7e8b4
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/BlockIo.h
@@ -0,0 +1,173 @@
+/** @file

+  Block IO protocol as defined in the EFI 1.0 specification.

+

+  The Block IO protocol is used to abstract block devices like hard drives,

+  DVD-ROMs and floppy drives.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BlockIo.h

+

+**/

+

+#ifndef __BLOCK_IO_H__

+#define __BLOCK_IO_H__

+

+#define EFI_BLOCK_IO_PROTOCOL_GUID \

+  { \

+    0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_BLOCK_IO_PROTOCOL  EFI_BLOCK_IO_PROTOCOL;

+

+/**

+  Reset the Block Device.

+

+  @param  This                 Protocol instance pointer.

+  @param  ExtendedVerification Driver may perform diagnostics on reset.

+

+  @retval EFI_SUCCESS          The device was reset.

+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could

+                               not be reset.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BLOCK_RESET) (

+  IN EFI_BLOCK_IO_PROTOCOL          *This,

+  IN BOOLEAN                        ExtendedVerification

+  )

+;

+

+/**

+  Read BufferSize bytes from Lba into Buffer.

+

+  @param  This       Protocol instance pointer.

+  @param  MediaId    Id of the media, changes every time the media is replaced.

+  @param  Lba        The starting Logical Block Address to read from

+  @param  BufferSize Size of Buffer, must be a multiple of device block size.

+  @param  Buffer     Buffer containing read data

+

+  @retval EFI_SUCCESS           The data was read correctly from the device.

+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.

+  @retval EFI_NO_MEDIA          There is no media in the device.

+  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.

+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.

+  @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not

+                                valid for the device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BLOCK_READ) (

+  IN EFI_BLOCK_IO_PROTOCOL          *This,

+  IN UINT32                         MediaId,

+  IN EFI_LBA                        Lba,

+  IN UINTN                          BufferSize,

+  OUT VOID                          *Buffer

+  )

+;

+

+/**

+  Write BufferSize bytes from Lba into Buffer.

+

+  @param  This       Protocol instance pointer.

+  @param  MediaId    Id of the media, changes every time the media is replaced.

+  @param  Lba        The starting Logical Block Address to read from

+  @param  BufferSize Size of Buffer, must be a multiple of device block size.

+  @param  Buffer     Buffer containing read data

+

+  @retval EFI_SUCCESS           The data was written correctly to the device.

+  @retval EFI_WRITE_PROTECTED   The device can not be written to.

+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.

+  @retval EFI_NO_MEDIA          There is no media in the device.

+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.

+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.

+  @retval EFI_INVALID_PARAMETER The write request contains a LBA that is not

+                                valid for the device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BLOCK_WRITE) (

+  IN EFI_BLOCK_IO_PROTOCOL          *This,

+  IN UINT32                         MediaId,

+  IN EFI_LBA                        Lba,

+  IN UINTN                          BufferSize,

+  IN VOID                           *Buffer

+  )

+;

+

+/**

+  Flush the Block Device.

+

+  @param  This              Protocol instance pointer.

+

+  @retval EFI_SUCCESS       All outstanding data was written to the device

+  @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data

+  @retval EFI_NO_MEDIA      There is no media in the device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BLOCK_FLUSH) (

+  IN EFI_BLOCK_IO_PROTOCOL  *This

+  )

+;

+

+/**

+  Block IO read only mode data and updated only via members of BlockIO

+

+**/

+typedef struct {

+  UINT32  MediaId;    ///< The curent media Id. If the media changes, this value is changed.

+  BOOLEAN RemovableMedia;  ///< TRUE if the media is removable; otherwise, FALSE.

+  BOOLEAN MediaPresent;    /**< TRUE if there is a media currently present in the device;

+             othersise, FALSE. THis field shows the media present status

+             as of the most recent ReadBlocks() or WriteBlocks() call.

+        **/

+  BOOLEAN LogicalPartition;  /**< TRUE if LBA 0 is the first block of a partition; otherwise

+             FALSE. For media with only one partition this would be TRUE.

+        **/

+  BOOLEAN ReadOnly;    /**< TRUE if the media is marked read-only otherwise, FALSE.

+             This field shows the read-only status as of the most recent WriteBlocks () call.

+        **/

+  BOOLEAN WriteCaching;    ///< TRUE if the WriteBlock () function caches write data.

+

+  UINT32  BlockSize;    /**< The intrinsic block size of the device. If the media changes, then

+             this field is updated.

+        **/

+  UINT32  IoAlign;    ///< Supplies the alignment requirement for any buffer to read or write block(s).

+

+  EFI_LBA LastBlock;    /**< The last logical block address on the device.

+             If the media changes, then this field is updated.

+        **/

+} EFI_BLOCK_IO_MEDIA;

+

+#define EFI_BLOCK_IO_PROTOCOL_REVISION  0x00010000

+

+struct _EFI_BLOCK_IO_PROTOCOL {

+  UINT64              Revision;

+

+  EFI_BLOCK_IO_MEDIA  *Media;

+

+  EFI_BLOCK_RESET     Reset;

+  EFI_BLOCK_READ      ReadBlocks;

+  EFI_BLOCK_WRITE     WriteBlocks;

+  EFI_BLOCK_FLUSH     FlushBlocks;

+

+};

+

+extern EFI_GUID gEfiBlockIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/BootScriptSave.h b/edk2/MdePkg/Include/Protocol/BootScriptSave.h
new file mode 100644
index 0000000..4dff3a9
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/BootScriptSave.h
@@ -0,0 +1,110 @@
+/** @file

+  Definition of the Boot Script Save protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BootScriptSave.h

+

+  @par Revision Reference:

+  This protocol defined in the Boot Script Specification, Version 0.91.

+

+**/

+

+#ifndef _BOOT_SCRIPT_SAVE_PROTOCOL_H

+#define _BOOT_SCRIPT_SAVE_PROTOCOL_H

+

+//

+// S3 Save Protocol GUID

+//

+#define EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID \

+  { \

+    0x470e1529, 0xb79e, 0x4e32, {0xa0, 0xfe, 0x6a, 0x15, 0x6d, 0x29, 0xf9, 0xb2 } \

+  }

+

+typedef struct _EFI_BOOT_SCRIPT_SAVE_PROTOCOL EFI_BOOT_SCRIPT_SAVE_PROTOCOL;

+

+//

+// Protocol Member_Function

+//

+/**

+  Adds a record into a specified Framework boot script table.

+

+  @param  This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.

+  

+  @param  TableName Name of the script table.Currently, the only meaningful 

+  value is EFI_ACPI_S3_RESUME_SCRIPT_TABLE.

+  

+  @param  OpCode The operation code (opcode) number.

+  

+  @param  ... Argument list that is specific to each opcode.

+

+  @retval EFI_SUCCESS The operation succeeded. A record was added into the specified script table.

+  

+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.

+  

+  @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BOOT_SCRIPT_WRITE) (

+  IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL            *This,

+  IN UINT16                                   TableName,

+  IN UINT16                                   OpCode,

+  ...

+  );

+

+/**

+  Closes the specified script table.

+

+  @param  This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.

+  

+  @param  TableName Name of the script table.

+  

+  @param  Address A pointer to the physical address where the table begins.

+

+  @retval EFI_SUCCESS The table was successfully returned.

+  

+  @retval EFI_NOT_FOUND The specified table was not created previously.

+  

+  @retval EFI_OUT_OF_RESOURCES Memory is insufficient to hold the reorganized boot script table.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BOOT_SCRIPT_CLOSE_TABLE) (

+  IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL            *This,

+  IN UINT16                                   TableName,

+  OUT EFI_PHYSICAL_ADDRESS                    *Address

+  );

+

+//

+// S3 Save Protocol data structure

+//

+/**

+  @par Protocol Description:

+  The EFI_BOOT_SCRIPT_SAVE_PROTOCOL publishes the Framework boot script abstractions

+  to store or record various boot scripts into boot script tables.

+

+  @param Write

+  Writes various boot scripts to a boot script table.

+

+  @param CloseTable

+  Retrieves and closes a script table.

+

+**/

+struct _EFI_BOOT_SCRIPT_SAVE_PROTOCOL {

+  EFI_BOOT_SCRIPT_WRITE       Write;

+  EFI_BOOT_SCRIPT_CLOSE_TABLE CloseTable;

+};

+

+extern EFI_GUID gEfiBootScriptSaveProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/BusSpecificDriverOverride.h b/edk2/MdePkg/Include/Protocol/BusSpecificDriverOverride.h
new file mode 100644
index 0000000..c446940
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/BusSpecificDriverOverride.h
@@ -0,0 +1,66 @@
+/** @file

+  Bus Specific Driver Override protocol as defined in the EFI 1.1 specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  BusSpecificDriverOverride.h

+

+**/

+

+#ifndef _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_H_

+#define _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_H_

+

+//

+// Global ID for the Bus Specific Driver Override Protocol

+//

+#define EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID \

+  { \

+    0x3bc1b285, 0x8a15, 0x4a82, {0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65 } \

+  }

+

+typedef struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL;

+

+//

+// Prototypes for the Bus Specific Driver Override Protocol

+//

+

+/**                                                                   

+  Uses a bus specific algorithm to retrieve a driver image handle for a controller.

+    

+  @param  This                  A pointer to the EFI_BUS_SPECIFIC_DRIVER_

+                                OVERRIDE_PROTOCOL instance.              

+  @param  DriverImageHandle     On input, a pointer to the previous driver image handle returned

+                                by GetDriver(). On output, a pointer to the next driver         

+                                image handle. Passing in a NULL, will return the first driver   

+                                image handle.                                                     

+                                

+  @retval EFI_SUCCESS           A bus specific override driver is returned in DriverImageHandle.

+  @retval EFI_NOT_FOUND         The end of the list of override drivers was reached.

+  @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a

+                                previous call to GetDriver().                           

+                                   

+**/   

+typedef

+EFI_STATUS

+(EFIAPI *EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER) (

+  IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL              *This,

+  IN OUT EFI_HANDLE                                         *DriverImageHandle

+  );

+

+//

+// Interface structure for the Bus Specific Driver Override Protocol

+//

+struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL {

+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER GetDriver;

+};

+

+extern EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/ComponentName.h b/edk2/MdePkg/Include/Protocol/ComponentName.h
new file mode 100644
index 0000000..68fd31b
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/ComponentName.h
@@ -0,0 +1,123 @@
+/** @file

+  EFI Component Name Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ComponentName.h

+

+**/

+

+#ifndef __EFI_COMPONENT_NAME_H__

+#define __EFI_COMPONENT_NAME_H__

+

+//

+// Global ID for the Component Name Protocol

+//

+#define EFI_COMPONENT_NAME_PROTOCOL_GUID \

+  { \

+    0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_COMPONENT_NAME_PROTOCOL  EFI_COMPONENT_NAME_PROTOCOL;

+

+

+/**

+  Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  @param  This       A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param  Language   A pointer to a three character ISO 639-2 language identifier.

+                     This is the language of the driver name that that the caller

+                     is requesting, and it must match one of the languages specified

+                     in SupportedLanguages.  The number of languages supported by a

+                     driver is up to the driver writer.

+  @param  DriverName A pointer to the Unicode string to return.  This Unicode string

+                     is the name of the driver specified by This in the language

+                     specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by This

+                                and the language specified by Language was returned

+                                in DriverName.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_COMPONENT_NAME_GET_DRIVER_NAME) (

+  IN EFI_COMPONENT_NAME_PROTOCOL           *This,

+  IN  CHAR8                                *Language,

+  OUT CHAR16                               **DriverName

+  );

+

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by an EFI Driver.

+

+  @param  This             A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param  ControllerHandle The handle of a controller that the driver specified by

+                           This is managing.  This handle specifies the controller

+                           whose name is to be returned.

+  @param  ChildHandle      The handle of the child controller to retrieve the name

+                           of.  This is an optional parameter that may be NULL.  It

+                           will be NULL for device drivers.  It will also be NULL

+                           for a bus drivers that wish to retrieve the name of the

+                           bus controller.  It will not be NULL for a bus driver

+                           that wishes to retrieve the name of a child controller.

+  @param  Language         A pointer to a three character ISO 639-2 language

+                           identifier.  This is the language of the controller name

+                           that that the caller is requesting, and it must match one

+                           of the languages specified in SupportedLanguages.  The

+                           number of languages supported by a driver is up to the

+                           driver writer.

+  @param  ControllerName   A pointer to the Unicode string to return.  This Unicode

+                           string is the name of the controller specified by

+                           ControllerHandle and ChildHandle in the language specified

+                           by Language from the point of view of the driver specified

+                           by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in the

+                                language specified by Language for the driver

+                                specified by This was returned in DriverName.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently managing

+                                the controller specified by ControllerHandle and

+                                ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) (

+  IN EFI_COMPONENT_NAME_PROTOCOL                              *This,

+  IN  EFI_HANDLE                                              ControllerHandle,

+  IN  EFI_HANDLE                                              ChildHandle        OPTIONAL,

+  IN  CHAR8                                                   *Language,

+  OUT CHAR16                                                  **ControllerName

+  );

+

+//

+// Interface structure for the Component Name Protocol

+//

+struct _EFI_COMPONENT_NAME_PROTOCOL {

+  EFI_COMPONENT_NAME_GET_DRIVER_NAME      GetDriverName;

+  EFI_COMPONENT_NAME_GET_CONTROLLER_NAME  GetControllerName;

+  CHAR8                                   *SupportedLanguages;

+};

+

+extern EFI_GUID gEfiComponentNameProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/CpuIo.h b/edk2/MdePkg/Include/Protocol/CpuIo.h
new file mode 100644
index 0000000..619878c
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/CpuIo.h
@@ -0,0 +1,131 @@
+/** @file

+  This code abstracts the CPU IO Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  CpuIO.h

+

+  @par Revision Reference:

+  CPU IO Protocol is defined in Framework of EFI CPU IO Protocol Spec

+  Version 0.9

+

+**/

+

+#ifndef _CPUIO_H_

+#define _CPUIO_H_

+

+#define EFI_CPU_IO_PROTOCOL_GUID \

+  { \

+    0xB0732526, 0x38C8, 0x4b40, {0x88, 0x77, 0x61, 0xC7, 0xB0, 0x6A, 0xAC, 0x45 } \

+  }

+

+typedef struct _EFI_CPU_IO_PROTOCOL EFI_CPU_IO_PROTOCOL;

+

+//

+// *******************************************************

+// EFI_CPU_IO_PROTOCOL_WIDTH

+// *******************************************************

+//

+typedef enum {

+  EfiCpuIoWidthUint8,

+  EfiCpuIoWidthUint16,

+  EfiCpuIoWidthUint32,

+  EfiCpuIoWidthUint64,

+  EfiCpuIoWidthFifoUint8,

+  EfiCpuIoWidthFifoUint16,

+  EfiCpuIoWidthFifoUint32,

+  EfiCpuIoWidthFifoUint64,

+  EfiCpuIoWidthFillUint8,

+  EfiCpuIoWidthFillUint16,

+  EfiCpuIoWidthFillUint32,

+  EfiCpuIoWidthFillUint64,

+  EfiCpuIoWidthMaximum

+} EFI_CPU_IO_PROTOCOL_WIDTH;

+

+//

+// *******************************************************

+// EFI_CPU_IO_PROTOCOL_IO_MEM

+// *******************************************************

+//

+/**

+  Enables a driver to access memory-mapped registers in the EFI system memory space.

+  Or, Enables a driver to access registers in the EFI CPU I/O space.

+

+  @param  This A pointer to the EFI_CPU_IO_PROTOCOL instance.

+  

+  @param  Width Signifies the width of the I/O or Memory operation. 

+  

+  @param  Address The base address of the I/O or Memoryoperation. 

+  

+  @param  Count The number of I/O or Memory operations to perform.

+  The number of bytes moved is Width size * Count, starting at Address.

+  

+  @param  Buffer For read operations, the destination buffer to store the results.

+  For write operations, the source buffer from which to write data.

+

+  @retval EFI_SUCCESS The data was read from or written to the EFI system.

+  

+  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.Or Buffer is NULL.

+  

+  @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. 

+  Or,The address range specified by Address, Width, and Count is not valid for this EFI system.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CPU_IO_PROTOCOL_IO_MEM) (

+  IN EFI_CPU_IO_PROTOCOL                *This,

+  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  OUT VOID                          *Buffer

+  );

+

+//

+// *******************************************************

+// EFI_CPU_IO_PROTOCOL_ACCESS

+// *******************************************************

+//

+typedef struct {

+  EFI_CPU_IO_PROTOCOL_IO_MEM  Read;

+  EFI_CPU_IO_PROTOCOL_IO_MEM  Write;

+} EFI_CPU_IO_PROTOCOL_ACCESS;

+

+//

+// *******************************************************

+// EFI_CPU_IO_PROTOCOL

+// *******************************************************

+//

+/**

+  @par Protocol Description:

+  Provides the basic memory and I/O interfaces that are used to abstract 

+  accesses to devices in a system.

+

+  @param Mem.Read

+  Allows reads from memory-mapped I/O space.

+

+  @param Mem.Write

+  Allows writes to memory-mapped I/O space.

+

+  @param Io.Read

+  Allows reads from I/O space.

+

+  @param Io.Write

+  Allows writes to I/O space.

+

+**/

+struct _EFI_CPU_IO_PROTOCOL {

+  EFI_CPU_IO_PROTOCOL_ACCESS  Mem;

+  EFI_CPU_IO_PROTOCOL_ACCESS  Io;

+};

+

+extern EFI_GUID gEfiCpuIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DataHub.h b/edk2/MdePkg/Include/Protocol/DataHub.h
new file mode 100644
index 0000000..15d3cc6
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DataHub.h
@@ -0,0 +1,233 @@
+/** @file

+  The data hub protocol is used both by agents wishing to log

+  data and those wishing to be made aware of all information that

+  has been logged.

+

+  For more information please look at Intel Platform Innovation 

+  Framework for EFI Data Hub Specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DataHub.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework for EFI Data Hub Specification.

+  Version 0.9.

+

+**/

+

+#ifndef __DATA_HUB_H__

+#define __DATA_HUB_H__

+

+#define EFI_DATA_HUB_PROTOCOL_GUID \

+  { \

+    0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \

+  }

+

+//

+// EFI generic Data Hub Header

+//

+// A Data Record is an EFI_DATA_RECORD_HEADER followed by RecordSize bytes of

+//  data. The format of the data is defined by the DataRecordGuid.

+//

+// If EFI_DATA_RECORD_HEADER is extended in the future the Version number must

+//  change and the HeaderSize will change if the definition of

+//  EFI_DATA_RECORD_HEADER is extended.

+//

+// The logger is responcible for initializing:

+//  Version, HeaderSize, RecordSize, DataRecordGuid, DataRecordClass

+//

+// The Data Hub driver is responcible for initializing:

+//   LogTime and LogMonotonicCount.

+//

+#define EFI_DATA_RECORD_HEADER_VERSION  0x0100

+typedef struct {

+  UINT16    Version;

+  UINT16    HeaderSize;

+  UINT32    RecordSize;

+  EFI_GUID  DataRecordGuid;

+  EFI_GUID  ProducerName;

+  UINT64    DataRecordClass;

+  EFI_TIME  LogTime;

+  UINT64    LogMonotonicCount;

+} EFI_DATA_RECORD_HEADER;

+

+//

+// Definition of DataRecordClass. These are used to filter out class types

+// at a very high level. The DataRecordGuid still defines the format of

+// the data. See DateHub.doc for rules on what can and can not be a

+// new DataRecordClass

+//

+#define EFI_DATA_RECORD_CLASS_DEBUG         0x0000000000000001

+#define EFI_DATA_RECORD_CLASS_ERROR         0x0000000000000002

+#define EFI_DATA_RECORD_CLASS_DATA          0x0000000000000004

+#define EFI_DATA_RECORD_CLASS_PROGRESS_CODE 0x0000000000000008

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_DATA_HUB_PROTOCOL EFI_DATA_HUB_PROTOCOL;

+

+/**

+  Logs a data record to the system event log.

+

+  @param  This The EFI_DATA_HUB_PROTOCOL instance.

+  

+  @param  description

+  

+  @param  DataRecordGuid A GUID that indicates the format of the data passed into RawData.

+  

+  @param  ProducerName A GUID that indicates the identity of the caller to this API.

+  

+  @param  DataRecordClass This class indicates the generic type of the data record. 

+  

+  @param  RawData The DataRecordGuid-defined data to be logged.

+  

+  @param  RawDataSize The size in bytes of RawData.

+

+  @retval EFI_SUCCESS  Data was logged.

+  

+  @retval EFI_OUT_OF_RESOURCES  Data was not logged due to lack of system resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DATA_HUB_LOG_DATA) (

+  IN  EFI_DATA_HUB_PROTOCOL   *This,

+  IN  EFI_GUID                *DataRecordGuid,

+  IN  EFI_GUID                *ProducerName,

+  IN  UINT64                  DataRecordClass,

+  IN  VOID                    *RawData,

+  IN  UINT32                  RawDataSize

+  );

+

+/**

+  Allows the system data log to be searched.

+

+  @param  This The EFI_DATA_HUB_PROTOCOL instance. 

+  

+  @param  MonotonicCount On input, it specifies the Record to return. 

+  An input of zero means to return the first record.

+  

+  @param  FilterDriver If FilterDriver is not passed in a MonotonicCount of zero, 

+  it means to return the first data record. If FilterDriver is passed in, 

+  then a MonotonicCount of zero means to return the first data not yet read 

+  by FilterDriver.

+  

+  @param  Record Returns a dynamically allocated memory buffer with a data 

+  record that matches MonotonicCount.

+

+  @retval EFI_SUCCESS  Data was returned in Record.

+  

+  @retval EFI_INVALID_PARAMETER  FilterDriver was passed in but does not exist.

+  

+  @retval EFI_NOT_FOUND  MonotonicCount does not match any data record 

+  in the system.  If a MonotonicCount of zero was passed in, then no 

+  data records exist in the system.

+  

+  @retval EFI_OUT_OF_RESOURCES  Record was not returned due to lack 

+  of system resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DATA_HUB_GET_NEXT_RECORD) (

+  IN EFI_DATA_HUB_PROTOCOL    *This,

+  IN OUT  UINT64              *MonotonicCount,

+  IN  EFI_EVENT               *FilterDriver OPTIONAL,

+  OUT EFI_DATA_RECORD_HEADER  **Record

+  );

+

+/**

+  Registers an event to be signaled every time a data record is logged in the system.

+

+  @param  This The EFI_DATA_HUB_PROTOCOL instance. 

+  

+  @param  FilterEvent The EFI_EVENT to signal whenever data that matches 

+  FilterClass is logged in the system. 

+  

+  @param  FilterTpl The maximum EFI_TPL at which FilterEvent can be signaled.

+  It is strongly recommended that you use the lowest EFI_TPL possible. 

+  

+  @param  FilterClass FilterEvent will be signaled whenever a bit 

+  in EFI_DATA_RECORD_HEADER.DataRecordClass is also set in FilterClass. 

+  If FilterClass is zero, no class-based filtering will be performed. 

+  

+  @param  FilterDataRecordGuid FilterEvent will be signaled whenever 

+  FilterDataRecordGuid matches EFI_DATA_RECORD_HEADER.DataRecordGuid. 

+  If FilterDataRecordGuid is NULL, then no GUID-based filtering will be performed. 

+

+  @retval EFI_SUCCESS  The filter driver event was registered

+  

+  @retval EFI_ALREADY_STARTED  FilterEvent was previously registered and cannot be registered again.

+  

+  @retval EFI_OUT_OF_RESOURCES  The filter driver event was not registered

+  due to lack of system resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DATA_HUB_REGISTER_FILTER_DRIVER) (

+  IN EFI_DATA_HUB_PROTOCOL    *This,

+  IN EFI_EVENT                FilterEvent,

+  IN EFI_TPL                  FilterTpl,

+  IN UINT64                   FilterClass,

+  IN EFI_GUID                 *FilterDataRecordGuid OPTIONAL

+  );

+

+/**

+  Stops a filter driver from being notified when data records are logged.

+

+  @param  This The EFI_DATA_HUB_PROTOCOL instance. 

+  

+  @param  FilterEvent The EFI_EVENT to remove from the list of events to be 

+  signaled every time errors are logged.

+

+  @retval EFI_SUCCESS  The filter driver represented by FilterEvent was shut off.

+  

+  @retval EFI_NOT_FOUND  FilterEvent did not exist.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DATA_HUB_UNREGISTER_FILTER_DRIVER) (

+  IN EFI_DATA_HUB_PROTOCOL    *This,

+  IN EFI_EVENT                FilterEvent

+  );

+

+/**

+  @par Protocol Description:

+  This protocol is used to log information and register filter drivers 

+  to receive data records.

+

+  @param LogData

+  Logs a data record. 

+

+  @param GetNextDataRecord

+  Gets a data record. Used both to view the memory-based log and to 

+  get information about which data records have been consumed by a filter driver.

+

+  @param RegisterFilterDriver

+  Allows the registration of an EFI event to act as a filter driver for all data records that are logged. 

+

+  @param UnregisterFilterDriver

+  Used to remove a filter driver that was added with RegisterFilterDriver(). 

+

+**/

+struct _EFI_DATA_HUB_PROTOCOL {

+  EFI_DATA_HUB_LOG_DATA                 LogData;

+  EFI_DATA_HUB_GET_NEXT_RECORD          GetNextRecord;

+  EFI_DATA_HUB_REGISTER_FILTER_DRIVER   RegisterFilterDriver;

+  EFI_DATA_HUB_UNREGISTER_FILTER_DRIVER UnregisterFilterDriver;

+};

+

+extern EFI_GUID gEfiDataHubProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DebugPort.h b/edk2/MdePkg/Include/Protocol/DebugPort.h
new file mode 100644
index 0000000..ceffaf6
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DebugPort.h
@@ -0,0 +1,141 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DebugPort.h

+

+**/

+

+#ifndef __DEBUG_PORT_H__

+#define __DEBUG_PORT_H__

+

+

+//

+// DebugPortIo protocol {EBA4E8D2-3858-41EC-A281-2647BA9660D0}

+//

+#define EFI_DEBUGPORT_PROTOCOL_GUID \

+  { \

+    0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \

+  }

+

+extern EFI_GUID gEfiDebugPortProtocolGuid;

+

+typedef struct _EFI_DEBUGPORT_PROTOCOL EFI_DEBUGPORT_PROTOCOL;

+

+//

+// DebugPort member functions

+//

+

+/**                                                                 

+  Resets the debugport.

+    

+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.

+                                

+  @retval EFI_SUCCESS           The debugport device was reset and is in usable state.

+  @retval EFI_DEVICE_ERROR      The debugport device could not be reset and is unusable.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEBUGPORT_RESET) (

+  IN EFI_DEBUGPORT_PROTOCOL               *This

+  );

+

+/**                                                                 

+  Writes data to the debugport.

+    

+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.

+  @param  Timeout               The number of microseconds to wait before timing out a write operation.

+  @param  BufferSize            On input, the requested number of bytes of data to write. On output, the

+                                number of bytes of data actually written.

+  @param  Buffer                A pointer to a buffer containing the data to write.                                

+                                  

+  @retval EFI_SUCCESS           The data was written.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_TIMEOUT           The data write was stopped due to a timeout.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEBUGPORT_WRITE) (

+  IN EFI_DEBUGPORT_PROTOCOL               *This,

+  IN UINT32                               Timeout,

+  IN OUT UINTN                            *BufferSize,

+  IN VOID                                 *Buffer

+  );

+

+/**                                                                 

+  Reads data from the debugport.

+    

+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.

+  @param  Timeout               The number of microseconds to wait before timing out a read operation.

+  @param  BufferSize            On input, the requested number of bytes of data to read. On output, the

+                                number of bytes of data actually number of bytes

+                                of data read and returned in Buffer.

+  @param  Buffer                A pointer to a buffer into which the data read will be saved.

+                                  

+  @retval EFI_SUCCESS           The data was read.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_TIMEOUT           The operation was stopped due to a timeout or overrun.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEBUGPORT_READ) (

+  IN EFI_DEBUGPORT_PROTOCOL               *This,

+  IN UINT32                               Timeout,

+  IN OUT UINTN                            *BufferSize,

+  OUT VOID                                *Buffer

+  );

+

+/**                                                                 

+  Checks to see if any data is available to be read from the debugport device.

+    

+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.

+                                  

+  @retval EFI_SUCCESS           At least one byte of data is available to be read.

+  @retval EFI_DEVICE_ERROR      The debugport device is not functioning correctly.

+  @retval EFI_NOT_READY         No data is available to be read.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEBUGPORT_POLL) (

+  IN EFI_DEBUGPORT_PROTOCOL               *This

+  );

+

+//

+// DebugPort protocol definition

+//

+struct _EFI_DEBUGPORT_PROTOCOL {

+  EFI_DEBUGPORT_RESET Reset;

+  EFI_DEBUGPORT_WRITE Write;

+  EFI_DEBUGPORT_READ  Read;

+  EFI_DEBUGPORT_POLL  Poll;

+};

+

+//

+// DEBUGPORT variable definitions...

+//

+#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT"

+#define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID

+#define gEfiDebugPortVariableGuid   gEfiDebugPortProtocolGuid

+

+//

+// DebugPort device path definitions...

+//

+#define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID

+#define gEfiDebugPortDevicePathGuid     gEfiDebugPortProtocolGuid

+

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL  Header;

+  EFI_GUID                  Guid;

+} DEBUGPORT_DEVICE_PATH;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DebugSupport.h b/edk2/MdePkg/Include/Protocol/DebugSupport.h
new file mode 100644
index 0000000..1b782cf
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DebugSupport.h
@@ -0,0 +1,517 @@
+/** @file

+  DebugSupport protocol and supporting definitions as defined in the EFI 1.1

+  specification.

+

+  The DebugSupport protocol is used by source level debuggers to abstract the

+  processor and handle context save and restore operations.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DebugSupport.h

+

+**/

+

+#ifndef __DEBUG_SUPPORT_H__

+#define __DEBUG_SUPPORT_H__

+

+typedef struct _EFI_DEBUG_SUPPORT_PROTOCOL EFI_DEBUG_SUPPORT_PROTOCOL;

+

+//

+// Debug Support protocol {2755590C-6F3C-42FA-9EA4-A3BA543CDA25}

+//

+#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \

+  { \

+    0x2755590C, 0x6F3C, 0x42FA, {0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \

+  }

+

+//

+// Debug Support definitions

+//

+typedef INTN  EFI_EXCEPTION_TYPE;

+

+//

+//  IA-32 processor exception types

+//

+#define EXCEPT_IA32_DIVIDE_ERROR    0

+#define EXCEPT_IA32_DEBUG           1

+#define EXCEPT_IA32_NMI             2

+#define EXCEPT_IA32_BREAKPOINT      3

+#define EXCEPT_IA32_OVERFLOW        4

+#define EXCEPT_IA32_BOUND           5

+#define EXCEPT_IA32_INVALID_OPCODE  6

+#define EXCEPT_IA32_DOUBLE_FAULT    8

+#define EXCEPT_IA32_INVALID_TSS     10

+#define EXCEPT_IA32_SEG_NOT_PRESENT 11

+#define EXCEPT_IA32_STACK_FAULT     12

+#define EXCEPT_IA32_GP_FAULT        13

+#define EXCEPT_IA32_PAGE_FAULT      14

+#define EXCEPT_IA32_FP_ERROR        16

+#define EXCEPT_IA32_ALIGNMENT_CHECK 17

+#define EXCEPT_IA32_MACHINE_CHECK   18

+#define EXCEPT_IA32_SIMD            19

+

+//

+//  IA-32 processor context definition

+//

+//

+// FXSAVE_STATE

+// FP / MMX / XMM registers (see fxrstor instruction definition)

+//

+typedef struct {

+  UINT16  Fcw;

+  UINT16  Fsw;

+  UINT16  Ftw;

+  UINT16  Opcode;

+  UINT32  Eip;

+  UINT16  Cs;

+  UINT16  Reserved1;

+  UINT32  DataOffset;

+  UINT16  Ds;

+  UINT8   Reserved2[10];

+  UINT8   St0Mm0[10], Reserved3[6];

+  UINT8   St0Mm1[10], Reserved4[6];

+  UINT8   St0Mm2[10], Reserved5[6];

+  UINT8   St0Mm3[10], Reserved6[6];

+  UINT8   St0Mm4[10], Reserved7[6];

+  UINT8   St0Mm5[10], Reserved8[6];

+  UINT8   St0Mm6[10], Reserved9[6];

+  UINT8   St0Mm7[10], Reserved10[6];

+  UINT8   Reserved11[22 * 16];

+} EFI_FX_SAVE_STATE_IA32;

+

+typedef struct {

+  UINT32                 ExceptionData;

+  EFI_FX_SAVE_STATE_IA32 FxSaveState;

+  UINT32                 Dr0;

+  UINT32                 Dr1;

+  UINT32                 Dr2;

+  UINT32                 Dr3;

+  UINT32                 Dr6;

+  UINT32                 Dr7;

+  UINT32                 Cr0;

+  UINT32                 Cr1;  

+  UINT32                 Cr2;

+  UINT32                 Cr3;

+  UINT32                 Cr4;

+  UINT32                 Eflags;

+  UINT32                 Ldtr;

+  UINT32                 Tr;

+  UINT32                 Gdtr[2];

+  UINT32                 Idtr[2];

+  UINT32                 Eip;

+  UINT32                 Gs;

+  UINT32                 Fs;

+  UINT32                 Es;

+  UINT32                 Ds;

+  UINT32                 Cs;

+  UINT32                 Ss;

+  UINT32                 Edi;

+  UINT32                 Esi;

+  UINT32                 Ebp;

+  UINT32                 Esp;

+  UINT32                 Ebx;

+  UINT32                 Edx;

+  UINT32                 Ecx;

+  UINT32                 Eax;

+} EFI_SYSTEM_CONTEXT_IA32;

+

+//

+//  IPF processor exception types

+//

+#define EXCEPT_IPF_VHTP_TRANSLATION       0

+#define EXCEPT_IPF_INSTRUCTION_TLB        1

+#define EXCEPT_IPF_DATA_TLB               2

+#define EXCEPT_IPF_ALT_INSTRUCTION_TLB    3

+#define EXCEPT_IPF_ALT_DATA_TLB           4

+#define EXCEPT_IPF_DATA_NESTED_TLB        5

+#define EXCEPT_IPF_INSTRUCTION_KEY_MISSED 6

+#define EXCEPT_IPF_DATA_KEY_MISSED        7

+#define EXCEPT_IPF_DIRTY_BIT              8

+#define EXCEPT_IPF_INSTRUCTION_ACCESS_BIT 9

+#define EXCEPT_IPF_DATA_ACCESS_BIT        10

+#define EXCEPT_IPF_BREAKPOINT             11

+#define EXCEPT_IPF_EXTERNAL_INTERRUPT     12

+//

+// 13 - 19 reserved

+//

+#define EXCEPT_IPF_PAGE_NOT_PRESENT           20

+#define EXCEPT_IPF_KEY_PERMISSION             21

+#define EXCEPT_IPF_INSTRUCTION_ACCESS_RIGHTS  22

+#define EXCEPT_IPF_DATA_ACCESS_RIGHTS         23

+#define EXCEPT_IPF_GENERAL_EXCEPTION          24

+#define EXCEPT_IPF_DISABLED_FP_REGISTER       25

+#define EXCEPT_IPF_NAT_CONSUMPTION            26

+#define EXCEPT_IPF_SPECULATION                27

+//

+// 28 reserved

+//

+#define EXCEPT_IPF_DEBUG                          29

+#define EXCEPT_IPF_UNALIGNED_REFERENCE            30

+#define EXCEPT_IPF_UNSUPPORTED_DATA_REFERENCE     31

+#define EXCEPT_IPF_FP_FAULT                       32

+#define EXCEPT_IPF_FP_TRAP                        33

+#define EXCEPT_IPF_LOWER_PRIVILEGE_TRANSFER_TRAP  34

+#define EXCEPT_IPF_TAKEN_BRANCH                   35

+#define EXCEPT_IPF_SINGLE_STEP                    36

+//

+// 37 - 44 reserved

+//

+#define EXCEPT_IPF_IA32_EXCEPTION 45

+#define EXCEPT_IPF_IA32_INTERCEPT 46

+#define EXCEPT_IPF_IA32_INTERRUPT 47

+

+//

+//  IPF processor context definition

+//

+typedef struct {

+  //

+  // The first reserved field is necessary to preserve alignment for the correct

+  // bits in UNAT and to insure F2 is 16 byte aligned..

+  //

+  UINT64  Reserved;

+  UINT64  R1;

+  UINT64  R2;

+  UINT64  R3;

+  UINT64  R4;

+  UINT64  R5;

+  UINT64  R6;

+  UINT64  R7;

+  UINT64  R8;

+  UINT64  R9;

+  UINT64  R10;

+  UINT64  R11;

+  UINT64  R12;

+  UINT64  R13;

+  UINT64  R14;

+  UINT64  R15;

+  UINT64  R16;

+  UINT64  R17;

+  UINT64  R18;

+  UINT64  R19;

+  UINT64  R20;

+  UINT64  R21;

+  UINT64  R22;

+  UINT64  R23;

+  UINT64  R24;

+  UINT64  R25;

+  UINT64  R26;

+  UINT64  R27;

+  UINT64  R28;

+  UINT64  R29;

+  UINT64  R30;

+  UINT64  R31;

+

+  UINT64  F2[2];

+  UINT64  F3[2];

+  UINT64  F4[2];

+  UINT64  F5[2];

+  UINT64  F6[2];

+  UINT64  F7[2];

+  UINT64  F8[2];

+  UINT64  F9[2];

+  UINT64  F10[2];

+  UINT64  F11[2];

+  UINT64  F12[2];

+  UINT64  F13[2];

+  UINT64  F14[2];

+  UINT64  F15[2];

+  UINT64  F16[2];

+  UINT64  F17[2];

+  UINT64  F18[2];

+  UINT64  F19[2];

+  UINT64  F20[2];

+  UINT64  F21[2];

+  UINT64  F22[2];

+  UINT64  F23[2];

+  UINT64  F24[2];

+  UINT64  F25[2];

+  UINT64  F26[2];

+  UINT64  F27[2];

+  UINT64  F28[2];

+  UINT64  F29[2];

+  UINT64  F30[2];

+  UINT64  F31[2];

+

+  UINT64  Pr;

+

+  UINT64  B0;

+  UINT64  B1;

+  UINT64  B2;

+  UINT64  B3;

+  UINT64  B4;

+  UINT64  B5;

+  UINT64  B6;

+  UINT64  B7;

+

+  //

+  // application registers

+  //

+  UINT64  ArRsc;

+  UINT64  ArBsp;

+  UINT64  ArBspstore;

+  UINT64  ArRnat;

+

+  UINT64  ArFcr;

+

+  UINT64  ArEflag;

+  UINT64  ArCsd;

+  UINT64  ArSsd;

+  UINT64  ArCflg;

+  UINT64  ArFsr;

+  UINT64  ArFir;

+  UINT64  ArFdr;

+

+  UINT64  ArCcv;

+

+  UINT64  ArUnat;

+

+  UINT64  ArFpsr;

+

+  UINT64  ArPfs;

+  UINT64  ArLc;

+  UINT64  ArEc;

+

+  //

+  // control registers

+  //

+  UINT64  CrDcr;

+  UINT64  CrItm;

+  UINT64  CrIva;

+  UINT64  CrPta;

+  UINT64  CrIpsr;

+  UINT64  CrIsr;

+  UINT64  CrIip;

+  UINT64  CrIfa;

+  UINT64  CrItir;

+  UINT64  CrIipa;

+  UINT64  CrIfs;

+  UINT64  CrIim;

+  UINT64  CrIha;

+

+  //

+  // debug registers

+  //

+  UINT64  Dbr0;

+  UINT64  Dbr1;

+  UINT64  Dbr2;

+  UINT64  Dbr3;

+  UINT64  Dbr4;

+  UINT64  Dbr5;

+  UINT64  Dbr6;

+  UINT64  Dbr7;

+

+  UINT64  Ibr0;

+  UINT64  Ibr1;

+  UINT64  Ibr2;

+  UINT64  Ibr3;

+  UINT64  Ibr4;

+  UINT64  Ibr5;

+  UINT64  Ibr6;

+  UINT64  Ibr7;

+

+  //

+  // virtual registers - nat bits for R1-R31

+  //

+  UINT64  IntNat;

+

+} EFI_SYSTEM_CONTEXT_IPF;

+

+//

+//  EBC processor exception types

+//

+#define EXCEPT_EBC_UNDEFINED            0

+#define EXCEPT_EBC_DIVIDE_ERROR         1

+#define EXCEPT_EBC_DEBUG                2

+#define EXCEPT_EBC_BREAKPOINT           3

+#define EXCEPT_EBC_OVERFLOW             4

+#define EXCEPT_EBC_INVALID_OPCODE       5   // opcode out of range

+#define EXCEPT_EBC_STACK_FAULT          6

+#define EXCEPT_EBC_ALIGNMENT_CHECK      7

+#define EXCEPT_EBC_INSTRUCTION_ENCODING 8   // malformed instruction

+#define EXCEPT_EBC_BAD_BREAK            9   // BREAK 0 or undefined BREAK

+#define EXCEPT_EBC_STEP                 10  // to support debug stepping

+//

+// For coding convenience, define the maximum valid EBC exception.

+//

+#define MAX_EBC_EXCEPTION EXCEPT_EBC_STEP

+

+//

+//  EBC processor context definition

+//

+typedef struct {

+  UINT64  R0;

+  UINT64  R1;

+  UINT64  R2;

+  UINT64  R3;

+  UINT64  R4;

+  UINT64  R5;

+  UINT64  R6;

+  UINT64  R7;

+  UINT64  Flags;

+  UINT64  ControlFlags;

+  UINT64  Ip;

+} EFI_SYSTEM_CONTEXT_EBC;

+

+//

+// Universal EFI_SYSTEM_CONTEXT definition

+//

+typedef union {

+  EFI_SYSTEM_CONTEXT_EBC  *SystemContextEbc;

+  EFI_SYSTEM_CONTEXT_IA32 *SystemContextIa32;

+  EFI_SYSTEM_CONTEXT_IPF  *SystemContextIpf;

+} EFI_SYSTEM_CONTEXT;

+

+//

+// DebugSupport callback function prototypes

+//

+

+/**                                                                 

+  Registers and enables an exception callback function for the specified exception.

+    

+  @param  ExceptionType         Exception types in EBC, IA-32, X64, or IPF

+  @param  SystemContext         Exception content.

+                                   

+**/

+typedef

+VOID

+(*EFI_EXCEPTION_CALLBACK) (

+  IN     EFI_EXCEPTION_TYPE               ExceptionType,

+  IN OUT EFI_SYSTEM_CONTEXT               SystemContext

+  );

+

+/**                                                                 

+  Registers and enables the on-target debug agent¡¯s periodic entry point.

+      

+  @param  SystemContext         Exception content.

+                                   

+**/

+typedef

+VOID

+(*EFI_PERIODIC_CALLBACK) (

+  IN OUT EFI_SYSTEM_CONTEXT               SystemContext

+  );

+

+//

+// Machine type definition

+//

+typedef enum {

+  IsaIa32 = IMAGE_FILE_MACHINE_I386, // 0x014C

+  IsaX64  = IMAGE_FILE_MACHINE_X64,   // 0x8664

+  IsaIpf  = IMAGE_FILE_MACHINE_IA64,  // 0x0200

+  IsaEbc  = IMAGE_FILE_MACHINE_EBC    // 0x0EBC

+} EFI_INSTRUCTION_SET_ARCHITECTURE;

+

+

+//

+// DebugSupport member function definitions

+//

+

+/**                                                                 

+  Returns the maximum value that may be used for the ProcessorIndex parameter in

+  RegisterPeriodicCallback() and RegisterExceptionCallback().                   

+    

+  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.

+  @param  MaxProcessorIndex     Pointer to a caller-allocated UINTN in which the maximum supported

+                                processor index is returned.                                      

+                                

+  @retval EFI_SUCCESS           The function completed successfully.  

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_MAXIMUM_PROCESSOR_INDEX) (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,

+  OUT UINTN                              *MaxProcessorIndex

+  );

+

+/**                                                                 

+  Registers a function to be called back periodically in interrupt context.

+    

+  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.

+  @param  ProcessorIndex        Specifies which processor the callback function applies to.

+  @param  PeriodicCallback      A pointer to a function of type PERIODIC_CALLBACK that is the main

+                                periodic entry point of the debug agent.

+                                

+  @retval EFI_SUCCESS           The function completed successfully.  

+  @retval EFI_ALREADY_STARTED   Non-NULL PeriodicCallback parameter when a callback

+                                function was previously registered.                

+  @retval EFI_OUT_OF_RESOURCES  System has insufficient memory resources to register new callback                               

+                                function.                                                           

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_REGISTER_PERIODIC_CALLBACK) (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,

+  IN UINTN                               ProcessorIndex,

+  IN EFI_PERIODIC_CALLBACK               PeriodicCallback

+  );

+

+/**                                                                 

+  Registers a function to be called when a given processor exception occurs.

+    

+  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.

+  @param  ProcessorIndex        Specifies which processor the callback function applies to.

+  @param  PeriodicCallback      A pointer to a function of type EXCEPTION_CALLBACK that is called

+                                when the processor exception specified by ExceptionType occurs.  

+  @param  ExceptionType         Specifies which processor exception to hook.                       

+                                

+  @retval EFI_SUCCESS           The function completed successfully.  

+  @retval EFI_ALREADY_STARTED   Non-NULL PeriodicCallback parameter when a callback

+                                function was previously registered.                

+  @retval EFI_OUT_OF_RESOURCES  System has insufficient memory resources to register new callback                               

+                                function.                                                           

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_REGISTER_EXCEPTION_CALLBACK) (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,

+  IN UINTN                               ProcessorIndex,

+  IN EFI_EXCEPTION_CALLBACK              ExceptionCallback,

+  IN EFI_EXCEPTION_TYPE                  ExceptionType

+  );

+

+/**                                                                 

+  Invalidates processor instruction cache for a memory range. Subsequent execution in this range

+  causes a fresh memory fetch to retrieve code to be executed.                                  

+    

+  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.

+  @param  ProcessorIndex        Specifies which processor¡¯s instruction cache is to be invalidated.

+  @param  Start                 Specifies the physical base of the memory range to be invalidated.                                

+  @param  Length                Specifies the minimum number of bytes in the processor¡¯s instruction

+                                cache to invalidate.                                                 

+                                

+  @retval EFI_SUCCESS           The function completed successfully.  

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INVALIDATE_INSTRUCTION_CACHE) (

+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,

+  IN UINTN                               ProcessorIndex,

+  IN VOID                                *Start,

+  IN UINT64                              Length

+  );

+

+//

+// DebugSupport protocol definition

+//

+struct _EFI_DEBUG_SUPPORT_PROTOCOL {

+  EFI_INSTRUCTION_SET_ARCHITECTURE  Isa;

+  EFI_GET_MAXIMUM_PROCESSOR_INDEX   GetMaximumProcessorIndex;

+  EFI_REGISTER_PERIODIC_CALLBACK    RegisterPeriodicCallback;

+  EFI_REGISTER_EXCEPTION_CALLBACK   RegisterExceptionCallback;

+  EFI_INVALIDATE_INSTRUCTION_CACHE  InvalidateInstructionCache;

+};

+

+extern EFI_GUID gEfiDebugSupportProtocolGuid;

+

+#endif 

diff --git a/edk2/MdePkg/Include/Protocol/Decompress.h b/edk2/MdePkg/Include/Protocol/Decompress.h
new file mode 100644
index 0000000..7c295f3
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Decompress.h
@@ -0,0 +1,121 @@
+/** @file

+  The Decompress Protocol Interface

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Decompress.h

+

+**/

+

+#ifndef __DECOMPRESS_H__

+#define __DECOMPRESS_H__

+

+#define EFI_DECOMPRESS_PROTOCOL_GUID \

+  { \

+    0xd8117cfe, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_DECOMPRESS_PROTOCOL  EFI_DECOMPRESS_PROTOCOL;

+

+/**

+  The GetInfo() function retrieves the size of the uncompressed buffer 

+  and the temporary scratch buffer required to decompress the buffer 

+  specified by Source and SourceSize.  If the size of the uncompressed

+  buffer or the size of the scratch buffer cannot be determined from 

+  the compressed data specified by Source and SourceData, then 

+  EFI_INVALID_PARAMETER is returned.  Otherwise, the size of the uncompressed

+  buffer is returned in DestinationSize, the size of the scratch buffer is 

+  returned in ScratchSize, and EFI_SUCCESS is returned.

+

+  The GetInfo() function does not have scratch buffer available to perform 

+  a thorough checking of the validity of the source data. It just retrieves

+  the 'Original Size' field from the beginning bytes of the source data and

+  output it as DestinationSize.  And ScratchSize is specific to the decompression

+  implementation.

+

+  @param  This            The protocol instance pointer

+  @param  Source          The source buffer containing the compressed data.

+  @param  SourceSize      The size, in bytes, of source buffer.

+  @param  DestinationSize A pointer to the size, in bytes, of the uncompressed buffer

+                          that will be generated when the compressed buffer specified

+                          by Source and SourceSize is decompressed.

+  @param  ScratchSize     A pointer to the size, in bytes, of the scratch buffer that

+                          is required to decompress the compressed buffer specified by

+                          Source and SourceSize.

+

+  @retval  EFI_SUCCESS           The size of the uncompressed data was returned in DestinationSize

+                                 and the size of the scratch buffer was returned in ScratchSize.

+  @retval  EFI_INVALID_PARAMETER The size of the uncompressed data or the size of the scratch

+                                 buffer cannot be determined from the compressed data specified by

+                                 Source and SourceData.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DECOMPRESS_GET_INFO) (

+  IN EFI_DECOMPRESS_PROTOCOL            *This,

+  IN   VOID                             *Source,

+  IN   UINT32                           SourceSize,

+  OUT  UINT32                           *DestinationSize,

+  OUT  UINT32                           *ScratchSize

+  );

+

+/**

+  The Decompress() function extracts decompressed data to its original form.

+

+  This protocol is designed so that the decompression algorithm can be 

+  implemented without using any memory services.  As a result, the 

+  Decompress() function is not allowed to call AllocatePool() or 

+  AllocatePages() in its implementation.  It is the caller's responsibility 

+  to allocate and free the Destination and Scratch buffers.

+

+  If the compressed source data specified by Source and SourceSize is 

+  sucessfully decompressed into Destination, then EFI_SUCCESS is returned.  

+  If the compressed source data specified by Source and SourceSize is not in 

+  a valid compressed data format, then EFI_INVALID_PARAMETER is returned.

+

+  @param  This            The protocol instance pointer

+  @param  Source          The source buffer containing the compressed data.

+  @param  SourceSize      The size of source data.

+  @param  Destination     On output, the destination buffer that contains

+                          the uncompressed data.

+  @param  DestinationSize The size of destination buffer. The size of destination

+                          buffer needed is obtained from GetInfo().

+  @param  Scratch         A temporary scratch buffer that is used to perform the

+                          decompression.          

+  @param  ScratchSize     The size of scratch buffer. The size of scratch buffer needed

+                          is obtained from GetInfo().

+

+  @retval  EFI_SUCCESS          Decompression completed successfully, and the uncompressed

+                                buffer is returned in Destination.

+  @retval EFI_INVALID_PARAMETER The source buffer specified by Source and SourceSize is

+                                corrupted (not in a valid compressed format).

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DECOMPRESS_DECOMPRESS) (

+  IN EFI_DECOMPRESS_PROTOCOL              *This,

+  IN     VOID                             *Source,

+  IN     UINT32                           SourceSize,

+  IN OUT VOID                             *Destination,

+  IN     UINT32                           DestinationSize,

+  IN OUT VOID                             *Scratch,

+  IN     UINT32                           ScratchSize

+  );

+

+struct _EFI_DECOMPRESS_PROTOCOL {

+  EFI_DECOMPRESS_GET_INFO   GetInfo;

+  EFI_DECOMPRESS_DECOMPRESS Decompress;

+};

+

+extern EFI_GUID gEfiDecompressProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DeviceIo.h b/edk2/MdePkg/Include/Protocol/DeviceIo.h
new file mode 100644
index 0000000..0d70632
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DeviceIo.h
@@ -0,0 +1,222 @@
+/** @file

+  Device IO protocol as defined in the EFI 1.0 specification.

+

+  Device IO is used to abstract hardware access to devices. It includes

+  memory mapped IO, IO, PCI Config space, and DMA.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DeviceIo.h

+

+**/

+

+#ifndef __DEVICE_IO_H__

+#define __DEVICE_IO_H__

+

+#define EFI_DEVICE_IO_PROTOCOL_GUID \

+  { \

+    0xaf6ac311, 0x84c3, 0x11d2, {0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+typedef struct _EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL;

+

+typedef enum {

+  IO_UINT8,

+  IO_UINT16,

+  IO_UINT32,

+  IO_UINT64,

+  MMIO_COPY_UINT8,

+  MMIO_COPY_UINT16,

+  MMIO_COPY_UINT32,

+  MMIO_COPY_UINT64

+} EFI_IO_WIDTH;

+

+/**                                                                 

+  Enables a driver to access device registers in the appropriate memory or I/O space.

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.

+  @param  Width                 Signifies the width of the I/O operations.                                                                   

+  @param  Address               The base address of the I/O operations. 

+  @param  Count                 The number of I/O operations to perform.

+  @param  Buffer                For read operations, the destination buffer to store the results. For write

+                                operations, the source buffer to write data from.                

+  

+  @retval EFI_SUCCESS           The data was read from or written to the device.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.      

+  @retval EFI_INVALID_PARAMETER Width is invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DEVICE_IO) (

+  IN EFI_DEVICE_IO_PROTOCOL         *This,

+  IN EFI_IO_WIDTH                   Width,

+  IN UINT64                         Address,

+  IN UINTN                          Count,

+  IN OUT VOID                       *Buffer

+  );

+

+typedef struct {

+  EFI_DEVICE_IO Read;

+  EFI_DEVICE_IO Write;

+} EFI_IO_ACCESS;

+

+/**                                                                 

+  Provides an EFI Device Path for a PCI device with the given PCI configuration space address.

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.

+  @param  PciAddress            The PCI configuration space address of the device whose Device Path

+                                is going to be returned.  

+  @param  PciDevicePath         A pointer to the pointer for the EFI Device Path for PciAddress.

+                                Memory for the Device Path is allocated from the pool.          

+  

+  @retval EFI_SUCCESS           The PciDevicePath returns a pointer to a valid EFI Device Path.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.      

+  @retval EFI_UNSUPPORTED       The PciAddress does not map to a valid EFI Device Path.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_DEVICE_PATH) (

+  IN EFI_DEVICE_IO_PROTOCOL           *This,

+  IN UINT64                           PciAddress,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **PciDevicePath

+  );

+

+typedef enum {

+  EfiBusMasterRead,

+  EfiBusMasterWrite,

+  EfiBusMasterCommonBuffer

+} EFI_IO_OPERATION_TYPE;

+

+/**                                                                 

+  Provides the device-specific addresses needed to access system memory.

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.

+  @param  Operation             Indicates if the bus master is going to read or write to system memory.

+  @param  HostAddress           The system memory address to map to the device.

+  @param  NumberOfBytes         On input the number of bytes to map.

+  @param  DeviceAddress         The resulting map address for the bus master device to use to access the

+                                hosts HostAddress.

+  @param  Mapping               A resulting value to pass to Unmap().

+  

+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.      

+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.

+  @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.

+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IO_MAP) (

+  IN EFI_DEVICE_IO_PROTOCOL           *This,

+  IN EFI_IO_OPERATION_TYPE            Operation,

+  IN EFI_PHYSICAL_ADDRESS             *HostAddress,

+  IN OUT UINTN                        *NumberOfBytes,

+  OUT EFI_PHYSICAL_ADDRESS            *DeviceAddress,

+  OUT VOID                            **Mapping

+  );

+

+/**                                                                 

+  Completes the Map() operation and releases any corresponding resources.

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.

+  @param  Mapping               A resulting value to pass to Unmap().

+  

+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.

+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IO_UNMAP) (

+  IN EFI_DEVICE_IO_PROTOCOL           *This,

+  IN VOID                             *Mapping

+  );

+

+/**                                                                 

+  Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.

+  @param  Type                  The type allocation to perform.

+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or

+                                EfiRuntimeServicesData.

+  @param  Pages                 The number of pages to allocate.

+  @param  HostAddress           A pointer to store the base address of the allocated range.                                

+  

+  @retval EFI_SUCCESS           The requested memory pages were allocated.

+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.

+  @retval EFI_INVALID_PARAMETER The requested memory type is invalid.

+  @retval EFI_UNSUPPORTED       The requested HostAddress is not supported on

+                                this platform.                               

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IO_ALLOCATE_BUFFER) (

+  IN EFI_DEVICE_IO_PROTOCOL           *This,

+  IN EFI_ALLOCATE_TYPE                Type,

+  IN EFI_MEMORY_TYPE                  MemoryType,

+  IN UINTN                            Pages,

+  IN OUT EFI_PHYSICAL_ADDRESS         *HostAddress

+  );

+

+/**                                                                 

+  Flushes any posted write data to the device.

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.

+  

+  @retval EFI_SUCCESS           The buffers were flushed.

+  @retval EFI_DEVICE_ERROR      The buffers were not flushed due to a hardware error.                                 

+  

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IO_FLUSH) (

+  IN EFI_DEVICE_IO_PROTOCOL  *This

+  );

+

+/**                                                                 

+  Frees pages that were allocated with AllocateBuffer().

+    

+  @param  This                  A pointer to the EFI_DEVICE_IO_INTERFACE instance.  

+  @param  Pages                 The number of pages to free.

+  @param  HostAddress           The base address of the range to free.

+  

+  @retval EFI_SUCCESS           The requested memory pages were allocated.

+  @retval EFI_NOT_FOUND         The requested memory pages were not allocated with

+                                AllocateBuffer().  

+  @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is invalid.

+  

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IO_FREE_BUFFER) (

+  IN EFI_DEVICE_IO_PROTOCOL           *This,

+  IN UINTN                            Pages,

+  IN EFI_PHYSICAL_ADDRESS             HostAddress

+  );

+

+struct _EFI_DEVICE_IO_PROTOCOL {

+  EFI_IO_ACCESS           Mem;

+  EFI_IO_ACCESS           Io;

+  EFI_IO_ACCESS           Pci;

+  EFI_IO_MAP              Map;

+  EFI_PCI_DEVICE_PATH     PciDevicePath;

+  EFI_IO_UNMAP            Unmap;

+  EFI_IO_ALLOCATE_BUFFER  AllocateBuffer;

+  EFI_IO_FLUSH            Flush;

+  EFI_IO_FREE_BUFFER      FreeBuffer;

+};

+

+extern EFI_GUID gEfiDeviceIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DevicePath.h b/edk2/MdePkg/Include/Protocol/DevicePath.h
new file mode 100644
index 0000000..d019999
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DevicePath.h
@@ -0,0 +1,94 @@
+/** @file

+  The device path protocol as defined in EFI 1.0.

+

+  The device path represents a programatic path to a device. It's the view

+  from a software point of view. It also must persist from boot to boot, so 

+  it can not contain things like PCI bus numbers that change from boot to boot.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DevicePath.h

+

+**/

+

+#ifndef __EFI_DEVICE_PATH_PROTOCOL_H__

+#define __EFI_DEVICE_PATH_PROTOCOL_H__

+

+//

+// Device Path protocol

+//

+#define EFI_DEVICE_PATH_PROTOCOL_GUID \

+  { \

+    0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+#pragma pack(1)

+

+typedef struct {

+  UINT8 Type;

+  UINT8 SubType;

+  UINT8 Length[2];

+} EFI_DEVICE_PATH_PROTOCOL;

+

+#pragma pack()

+                                             

+#define EFI_DP_TYPE_MASK                     0x7F

+#define EFI_DP_TYPE_UNPACKED                 0x80

+#define END_DEVICE_PATH_TYPE                 0x7f

+                                             

+#define EFI_END_ENTIRE_DEVICE_PATH           0xff

+#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE   0xff

+#define EFI_END_INSTANCE_DEVICE_PATH         0x01

+#define END_ENTIRE_DEVICE_PATH_SUBTYPE       EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE

+#define END_INSTANCE_DEVICE_PATH_SUBTYPE     EFI_END_INSTANCE_DEVICE_PATH

+                                             

+#define EFI_END_DEVICE_PATH_LENGTH           (sizeof (EFI_DEVICE_PATH_PROTOCOL))

+#define END_DEVICE_PATH_LENGTH               EFI_END_DEVICE_PATH_LENGTH

+                                             

+#define DP_IS_END_TYPE(a)                    

+#define DP_IS_END_SUBTYPE(a)                 (((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)

+#define DevicePathSubType(a)                 ((a)->SubType)

+#define IsDevicePathUnpacked(a)              ((a)->Type & EFI_DP_TYPE_UNPACKED)

+                                             

+#define EfiDevicePathNodeLength(a)           (((a)->Length[0]) | ((a)->Length[1] << 8))

+#define DevicePathNodeLength(a)              (EfiDevicePathNodeLength(a))

+#define EfiNextDevicePathNode(a)             ((EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) (a)) + EfiDevicePathNodeLength (a)))

+#define NextDevicePathNode(a)                (EfiNextDevicePathNode(a)) 

+                                             

+#define EfiDevicePathType(a)                 (((a)->Type) & EFI_DP_TYPE_MASK)

+#define DevicePathType(a)                    (EfiDevicePathType(a))

+#define EfiIsDevicePathEndType(a)            (EfiDevicePathType (a) == END_DEVICE_PATH_TYPE)

+#define IsDevicePathEndType(a)               (EfiIsDevicePathEndType(a)) 

+                                             

+                                             

+#define EfiIsDevicePathEndSubType(a)         ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)

+#define IsDevicePathEndSubType(a)            (EfiIsDevicePathEndSubType(a))

+#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == EFI_END_INSTANCE_DEVICE_PATH)

+                                             

+#define EfiIsDevicePathEnd(a)                (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))

+#define IsDevicePathEnd(a)                   (EfiIsDevicePathEnd(a))

+#define EfiIsDevicePathEndInstance(a)        (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndInstanceSubType (a))

+

+

+#define SetDevicePathNodeLength(a,l) {                           \

+          (a)->Length[0] = (UINT8) (l);                          \

+          (a)->Length[1] = (UINT8) ((l) >> 8);                   \

+          }

+

+#define SetDevicePathEndNode(a)  {                               \

+          (a)->Type = END_DEVICE_PATH_TYPE;                      \

+          (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;         \

+          (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);     \

+          (a)->Length[1] = 0;                                    \

+          }

+

+extern EFI_GUID gEfiDevicePathProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DevicePathFromText.h b/edk2/MdePkg/Include/Protocol/DevicePathFromText.h
new file mode 100644
index 0000000..a3a6c43
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DevicePathFromText.h
@@ -0,0 +1,73 @@
+/** @file

+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0.  

+  This protocol provides service to convert text to device paths and device nodes.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DevicePathFromText.h

+

+**/

+

+#ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__

+#define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__

+

+//

+// Device Path From Text protocol

+//

+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \

+  { \

+    0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e  } \

+  }

+

+/**

+  Convert text to the binary representation of a device node.

+

+  @param  TextDeviceNode TextDeviceNode points to the text representation of a device

+                         node. Conversion starts with the first character and continues

+                         until the first non-device node character.

+

+  @retval a_pointer      Pointer to the EFI device node.

+  @retval NULL           if TextDeviceNode is NULL or there was insufficient memory.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE) (

+  IN CONST CHAR16                 *TextDeviceNode

+  )

+;    

+  

+

+/**

+  Convert text to the binary representation of a device node.

+

+  @param  TextDeviceNode TextDevicePath points to the text representation of a device

+                         path. Conversion starts with the first character and continues

+                         until the first non-device path character.

+

+  @retval a_pointer      Pointer to the allocated device path.

+  @retval NULL           if TextDeviceNode is NULL or there was insufficient memory.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH) (

+  IN CONST CHAR16                 *TextDevicePath

+  )

+;  

+  

+typedef struct {

+  EFI_DEVICE_PATH_FROM_TEXT_NODE  ConvertDeviceNodeFromText;

+  EFI_DEVICE_PATH_FROM_TEXT_PATH  ConvertDevicePathFromText;

+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;

+

+extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DevicePathToText.h b/edk2/MdePkg/Include/Protocol/DevicePathToText.h
new file mode 100644
index 0000000..d888562
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DevicePathToText.h
@@ -0,0 +1,86 @@
+/** @file

+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL as defined in UEFI 2.0.  

+  This protocol provides service to convert device nodes and paths to text.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DevicePathToText.h

+

+**/

+

+#ifndef __DEVICE_PATH_TO_TEXT_PROTOCOL_H__

+#define __DEVICE_PATH_TO_TEXT_PROTOCOL_H__

+

+//

+// Device Path To Text protocol

+//

+#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \

+  { \

+    0x8b843e20, 0x8132, 0x4852, {0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \

+  }

+

+/**

+  Convert a device node to its text representation.

+

+  @param  DeviceNode     Points to the device node to be converted.

+  @param  DisplayOnly    If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.

+  @param  AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text

+                         representation for a device node can be used, where applicable.

+

+  @retval a_pointer      a pointer to the allocated text representation of the device node data

+  @retval NULL           if DeviceNode is NULL or there was insufficient memory.

+

+**/

+typedef

+CHAR16*

+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DeviceNode,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  )

+;      

+

+/**

+  Convert a device path to its text representation.

+

+  @param  DevicePath     Points to the device path to be converted.

+  @param  DisplayOnly    If DisplayOnly is TRUE, then the shorter text representation

+                         of the display node is used, where applicable. If DisplayOnly

+                         is FALSE, then the longer text representation of the display node

+                         is used.  

+  @param  AllowShortcuts The AllowShortcuts is FALSE, then the shortcut forms of

+                         text representation for a device node cannot be used.

+

+  @retval a_pointer      a pointer to the allocated text representation of the device node.

+  @retval NULL           if DevicePath is NULL or there was insufficient memory.

+

+**/

+typedef

+CHAR16*

+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,

+  IN BOOLEAN                          DisplayOnly,

+  IN BOOLEAN                          AllowShortcuts

+  )

+;    

+

+typedef struct {

+  EFI_DEVICE_PATH_TO_TEXT_NODE        ConvertDeviceNodeToText;

+  EFI_DEVICE_PATH_TO_TEXT_PATH        ConvertDevicePathToText;

+} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;

+

+extern EFI_GUID gEfiDevicePathToTextProtocolGuid;

+

+#endif

+

+

diff --git a/edk2/MdePkg/Include/Protocol/DevicePathUtilities.h b/edk2/MdePkg/Include/Protocol/DevicePathUtilities.h
new file mode 100644
index 0000000..e72f57c
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DevicePathUtilities.h
@@ -0,0 +1,194 @@
+/** @file

+  EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0.  

+  Use to create and manipulate device paths and device nodes.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DevicePathUtilities.h

+

+**/

+

+#ifndef __DEVICE_PATH_UTILITIES_PROTOCOL_H__

+#define __DEVICE_PATH_UTILITIES_PROTOCOL_H__

+

+//

+// Device Path Utilities protocol

+//

+#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \

+  { \

+    0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \

+  }

+

+/**

+  Returns the size of the device path, in bytes.

+

+  @param  DevicePath Points to the start of the EFI device path.

+

+  @revtal Size       Size of the specified device path, in bytes, including the end-of-path tag.

+

+**/

+typedef

+UINTN

+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath

+  )

+;    

+  

+

+/**

+  Create a duplicate of the specified path.

+

+  @param  DevicePath Points to the source EFI device path.

+

+  @retval Pointer    A pointer to the duplicate device path.

+  @retval NULL       insufficient memory

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath

+  )

+;      

+

+/**

+  Create a new path by appending the second device path to the first.

+

+  @param  Src1 Points to the first device path. If NULL, then it is ignored.

+  @param  Src2 Points to the second device path. If NULL, then it is ignored.

+

+  @retval Pointer  A pointer to the newly created device path.

+  @retval NULL     Memory could not be allocated

+                   or either DevicePath or DeviceNode is NULL.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_PATH) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2

+  )

+;     

+  

+/**

+  Creates a new path by appending the device node to the device path.

+

+  @param  DevicePath Points to the device path.

+  @param  DeviceNode Points to the device node.

+

+  @retval Pointer    A pointer to the allocated device node.

+  @retval NULL       Memory could not be allocated

+                     or either DevicePath or DeviceNode is NULL.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_NODE) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode

+  )

+;

+

+/**

+  Creates a new path by appending the specified device path instance to the specified device path.

+

+  @param  DevicePath         Points to the device path. If NULL, then ignored.

+  @param  DevicePathInstance Points to the device path instance.

+

+  @retval Pointer            A pointer to the newly created device path

+  @retval NULL               Memory could not be allocated or DevicePathInstance is NULL.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance

+  )

+;  

+

+/**

+  Creates a copy of the current device path instance and returns a pointer to the next device path

+  instance.

+

+  @param  DevicePathInstance     On input, this holds the pointer to the current device path

+                                 instance. On output, this holds the pointer to the next

+                                 device path instance or NULL if there are no more device

+                                 path instances in the device path.  

+  @param  DevicePathInstanceSize On output, this holds the size of the device path instance,

+                                 in bytes or zero, if DevicePathInstance is zero.

+

+  @retval Pointer                A pointer to the copy of the current device path instance.

+  @retval NULL                   DevicePathInstace was NULL on entry or there was insufficient memory.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE) (

+  IN  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathInstance,

+  OUT UINTN                         *DevicePathInstanceSize

+  )

+;  

+

+/**

+  Creates a device node

+

+  @param  NodeType    NodeType is the device node type (EFI_DEVICE_PATH.Type) for

+                      the new device node.

+  @param  NodeSubType NodeSubType is the device node sub-type

+                      EFI_DEVICE_PATH.SubType) for the new device node.

+  @param  NodeLength  NodeLength is the length of the device node

+                      (EFI_DEVICE_PATH.Length) for the new device node.

+

+  @retval Pointer     A pointer to the newly created device node.

+  @retval NULL        NodeLength is less than

+                      the size of the header or there was insufficient memory.

+

+**/

+typedef

+EFI_DEVICE_PATH_PROTOCOL*

+(EFIAPI *EFI_DEVICE_PATH_CREATE_NODE) (

+  IN UINT8                          NodeType,

+  IN UINT8                          NodeSubType,

+  IN UINT16                         NodeLength

+)

+;   

+

+/**

+  Returns whether a device path is multi-instance.

+

+  @param  DevicePath Points to the device path. If NULL, then ignored.

+

+  @retval TRUE       The device path has more than one instance

+  @retval FALSE      The device path is empty or contains only a single instance.

+

+**/

+typedef

+BOOLEAN

+(EFIAPI *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE) (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath

+  )

+;                                                                                                       

+  

+

+typedef struct {

+  EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;

+  EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH      DuplicateDevicePath;

+  EFI_DEVICE_PATH_UTILS_APPEND_PATH          AppendDevicePath;

+  EFI_DEVICE_PATH_UTILS_APPEND_NODE          AppendDeviceNode;

+  EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE      AppendDevicePathInstance;

+  EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE    GetNextDevicePathInstance;

+  EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE    IsDevicePathMultiInstance;

+  EFI_DEVICE_PATH_CREATE_NODE                CreateDeviceNode;

+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;

+

+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; 

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Dhcp4.h b/edk2/MdePkg/Include/Protocol/Dhcp4.h
new file mode 100644
index 0000000..3adce1a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Dhcp4.h
@@ -0,0 +1,442 @@
+/** @file

+  EFI_DHCP4_PROTOCOL as defined in UEFI 2.0.

+  EFI_DHCP4_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0.

+  These protocols are used to collect configuration information for the EFI IPv4 Protocol 

+  drivers and to provide DHCPv4 server and PXE boot server discovery services.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DHCP4.h

+

+**/

+

+#ifndef __EFI_DHCP4_PROTOCOL_H__

+#define __EFI_DHCP4_PROTOCOL_H__

+

+#define EFI_DHCP4_PROTOCOL_GUID \

+  { \

+    0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56 } \

+  }

+

+#define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80 } \

+  }

+  

+typedef struct _EFI_DHCP4_PROTOCOL EFI_DHCP4_PROTOCOL;

+

+

+#pragma pack(1)

+typedef struct {

+  UINT8               OpCode;

+  UINT8               Length;

+  UINT8               Data[1];

+} EFI_DHCP4_PACKET_OPTION;

+#pragma pack()

+

+

+#pragma pack(1)

+typedef struct {

+    UINT8             OpCode;

+    UINT8             HwType;

+    UINT8             HwAddrLen;

+    UINT8             Hops;

+    UINT32            Xid;

+    UINT16            Seconds;

+    UINT16            Reserved;

+    EFI_IPv4_ADDRESS  ClientAddr;       //Client IP address from client

+    EFI_IPv4_ADDRESS  YourAddr;         //Client IP address from server

+    EFI_IPv4_ADDRESS  ServerAddr;       //IP address of next server in bootstrap 

+    EFI_IPv4_ADDRESS  GatewayAddr;      //Relay agent IP address

+    UINT8             ClientHwAddr[16]; //Client hardware address

+    CHAR8             ServerName[64];   

+    CHAR8             BootFileName[128];

+}EFI_DHCP4_HEADER;

+#pragma pack()

+

+

+#pragma pack(1)

+typedef struct {

+  UINT32              Size;

+  UINT32              Length;

+

+  struct {

+    EFI_DHCP4_HEADER  Header;

+    UINT32            Magik;

+    UINT8             Option[1];

+  } Dhcp4;

+} EFI_DHCP4_PACKET;

+#pragma pack()

+

+

+typedef enum {

+  Dhcp4Stopped        = 0x0,

+  Dhcp4Init           = 0x1,

+  Dhcp4Selecting      = 0x2,

+  Dhcp4Requesting     = 0x3,

+  Dhcp4Bound          = 0x4,

+  Dhcp4Renewing       = 0x5,

+  Dhcp4Rebinding      = 0x6,

+  Dhcp4InitReboot     = 0x7,

+  Dhcp4Rebooting      = 0x8

+} EFI_DHCP4_STATE;

+

+

+typedef enum{

+  Dhcp4SendDiscover   = 0x01,

+  Dhcp4RcvdOffer      = 0x02,

+  Dhcp4SelectOffer    = 0x03,

+  Dhcp4SendRequest    = 0x04,

+  Dhcp4RcvdAck        = 0x05,

+  Dhcp4RcvdNak        = 0x06,

+  Dhcp4SendDecline    = 0x07,

+  Dhcp4BoundCompleted = 0x08,

+  Dhcp4EnterRenewing  = 0x09,

+  Dhcp4EnterRebinding = 0x0a,

+  Dhcp4AddressLost    = 0x0b,

+  Dhcp4Fail           = 0x0c

+} EFI_DHCP4_EVENT;

+

+/**                                                                 

+  Callback routine 

+    

+  @param  This                  Pointer to the EFI DHCPv4 Protocol instance that is used to

+                                configure this callback function.                          

+  @param  Context               Pointer to the context that is initialized by

+                                EFI_DHCP4_PROTOCOL.Configure().                                              

+  @param  CurrentState          The current operational state of the EFI DHCPv4 Protocol

+                                driver.                                                 

+  @param  Dhcp4Event            The event that occurs in the current state, which usually means a

+                                state transition.                                                

+  @param  Packet                The DHCP packet that is going to be sent or already received.                

+  @param  NewPacket             The packet that is used to replace the above Packet.

+                                

+  @retval EFI_SUCCESS           Tells the EFI DHCPv4 Protocol driver to continue the DHCP process.

+  @retval EFI_NOT_READY         Only used in the Dhcp4Selecting state. The EFI DHCPv4 Protocol         

+                                driver will continue to wait for more DHCPOFFER packets until the retry

+                                timeout expires.                                                       

+  @retval EFI_ABORTED           Tells the EFI DHCPv4 Protocol driver to abort the current process and

+                                return to the Dhcp4Init or Dhcp4InitReboot state.                    

+                                   

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_DHCP4_CALLBACK) (

+  IN  EFI_DHCP4_PROTOCOL         *This,

+  IN  VOID                       *Context,

+  IN  EFI_DHCP4_STATE            CurrentState,

+  IN  EFI_DHCP4_EVENT            Dhcp4Event,

+  IN  EFI_DHCP4_PACKET           *Packet     OPTIONAL, 

+  OUT EFI_DHCP4_PACKET           **NewPacket OPTIONAL

+  );

+

+

+typedef struct {

+  UINT32                      DiscoverTryCount;      

+  UINT32                      *DiscoverTimeout;

+  UINT32                      RequestTryCount;

+  UINT32                      *RequestTimeout;

+  EFI_IPv4_ADDRESS            ClientAddress;

+  EFI_DHCP4_CALLBACK          Dhcp4Callback;

+  void                        *CallbackContext;

+  UINT32                      OptionCount;

+  EFI_DHCP4_PACKET_OPTION     **OptionList;

+} EFI_DHCP4_CONFIG_DATA;

+

+

+typedef struct {

+  EFI_DHCP4_STATE             State;

+  EFI_DHCP4_CONFIG_DATA       ConfigData;

+  EFI_IPv4_ADDRESS            ClientAddress;

+  EFI_MAC_ADDRESS             ClientMacAddress;

+  EFI_IPv4_ADDRESS            ServerAddress;

+  EFI_IPv4_ADDRESS            RouterAddress;

+  EFI_IPv4_ADDRESS            SubnetMask;

+  UINT32                      LeaseTime;

+  EFI_DHCP4_PACKET            *ReplyPacket;

+} EFI_DHCP4_MODE_DATA;

+

+

+typedef struct {

+  EFI_IPv4_ADDRESS            ListenAddress;

+  EFI_IPv4_ADDRESS            SubnetMask;

+  UINT16                      ListenPort;

+} EFI_DHCP4_LISTEN_POINT;

+

+

+typedef struct {

+  OUT EFI_STATUS              Status;

+  IN  EFI_EVENT               CompletionEvent;

+  IN  EFI_IPv4_ADDRESS        RemoteAddress;

+  IN  UINT16                  RemotePort;

+  IN  EFI_IPv4_ADDRESS        GatewayAddress;

+  IN  UINT32                  ListenPointCount;

+  IN  EFI_DHCP4_LISTEN_POINT  *ListenPoints;

+  IN  UINT32                  TimeoutValue;

+  IN  EFI_DHCP4_PACKET        *Packet;

+  OUT UINT32                  ResponseCount;

+  OUT EFI_DHCP4_PACKET        *ResponseList;

+} EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN;

+

+

+/**

+  Returns the current operating mode and cached data packet for the EFI DHCPv4 Protocol driver.

+

+  @param  This          Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  Dhcp4ModeData Pointer to storage for the EFI_DHCP4_MODE_DATA structure.

+

+  @retval EFI_SUCCESS           The mode data was returned.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_DHCP4_GET_MODE_DATA)(

+  IN  EFI_DHCP4_PROTOCOL      *This,

+  OUT EFI_DHCP4_MODE_DATA     *Dhcp4ModeData

+  )

+;

+

+/**

+  Initializes, changes, or resets the operational settings for the EFI DHCPv4 Protocol driver.

+

+  @param  This                   Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  Dhcp4CfgData           Pointer to the EFI_DHCP4_CONFIG_DATA.

+

+  @retval EFI_SUCCESS           The EFI DHCPv4 Protocol driver is now in the Dhcp4Init or

+                                Dhcp4InitReboot state, if the original state of this driver

+                                was Dhcp4Stopped and the value of Dhcp4CfgData was

+                                not NULL. Otherwise, the state was left unchanged.

+  @retval EFI_ACCESS_DENIED     This instance of the EFI DHCPv4 Protocol driver was not in the

+                                Dhcp4Stopped, Dhcp4Init, Dhcp4InitReboot, or Dhcp4Bound state;

+                                Or onother instance of this EFI DHCPv4 Protocol driver is already

+                                in a valid configured state.

+  @retval EFI_INVALID_PARAMETER Some parameter is NULL.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_CONFIGURE) (

+  IN EFI_DHCP4_PROTOCOL       *This,

+  IN EFI_DHCP4_CONFIG_DATA    *Dhcp4CfgData  OPTIONAL

+  )

+;

+

+

+/**

+  Starts the DHCP configuration process.

+

+  @param  This            Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  CompletionEvent If not NULL, indicates the event that will be signaled when the

+                          EFI DHCPv4 Protocol driver is transferred into the

+                          Dhcp4Bound state or when the DHCP process is aborted.

+                          EFI_DHCP4_PROTOCOL.GetModeData() can be called to

+                          check the completion status. If NULL,

+                          EFI_DHCP4_PROTOCOL.Start() will wait until the driver

+                          is transferred into the Dhcp4Bound state or the process fails.

+

+  @retval EFI_SUCCESS           The DHCP configuration process has started, or it has completed

+                                when CompletionEvent is NULL.

+  @retval EFI_NOT_STARTED       The EFI DHCPv4 Protocol driver is in the Dhcp4Stopped

+                                state. EFI_DHCP4_PROTOCOL. Configure() needs to be called.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval EFI_TIMEOUT           The DHCP configuration process failed because no response was

+                                received from the server within the specified timeout value.

+  @retval EFI_ABORTED           The user aborted the DHCP process.

+  @retval EFI_ALREADY_STARTED   Some other EFI DHCPv4 Protocol instance already started the

+                                DHCP process.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_START) (

+  IN EFI_DHCP4_PROTOCOL       *This,

+  IN EFI_EVENT                CompletionEvent   OPTIONAL

+  )

+;

+

+/**

+  Extends the lease time by sending a request packet.

+

+  @param  This            Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  RebindRequest   If TRUE, this function broadcasts the request packets and enters

+                          the Dhcp4Rebinding state. Otherwise, it sends a unicast

+                          request packet and enters the Dhcp4Renewing state.

+  @param  CompletionEvent If not NULL, this event is signaled when the renew/rebind phase

+                          completes or some error occurs.

+                          EFI_DHCP4_PROTOCOL.GetModeData() can be called to

+                          check the completion status. If NULL,

+                          EFI_DHCP4_PROTOCOL.RenewRebind() will busy-wait

+                          until the DHCP process finishes.

+

+  @retval EFI_SUCCESS           The EFI DHCPv4 Protocol driver is now in the

+                                Dhcp4Renewing state or is back to the Dhcp4Bound state.

+  @retval EFI_NOT_STARTED       The EFI DHCPv4 Protocol driver is in the Dhcp4Stopped

+                                state. EFI_DHCP4_PROTOCOL.Configure() needs to

+                                be called.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_TIMEOUT           There was no response from the server when the try count was

+                                exceeded.

+  @retval EFI_ACCESS_DENIED     The driver is not in the Dhcp4Bound state.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_RENEW_REBIND) (

+  IN EFI_DHCP4_PROTOCOL       *This,

+  IN BOOLEAN                  RebindRequest,

+  IN EFI_EVENT                CompletionEvent  OPTIONAL

+  )

+;  

+

+/**

+  Releases the current address configuration.

+

+  @param  This                  Pointer to the EFI_DHCP4_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           The EFI DHCPv4 Protocol driver is now in the Dhcp4Init phase.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_ACCESS_DENIED     The EFI DHCPv4 Protocol driver is not Dhcp4InitReboot state.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_RELEASE) (

+  IN EFI_DHCP4_PROTOCOL       *This

+  )

+;  

+

+/**

+  Stops the current address configuration.

+

+  @param  This                  Pointer to the EFI_DHCP4_PROTOCOL instance.

+                                 

+  @retval EFI_SUCCESS           The EFI DHCPv4 Protocol driver is now in the Dhcp4Stopped phase.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_STOP) (

+  IN EFI_DHCP4_PROTOCOL       *This

+  )

+; 

+

+/**

+  Builds a DHCP packet, given the options to be appended or deleted or replaced.

+

+  @param  This        Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  SeedPacket  Initial packet to be used as a base for building new packet.

+  @param  DeleteCount Number of opcodes in the DeleteList.

+  @param  DeleteList  List of opcodes to be deleted from the seed packet.

+                      Ignored if DeleteCount is zero.

+  @param  AppendCount Number of entries in the OptionList.

+  @param  AppendList  Pointer to a DHCP option list to be appended to SeedPacket.

+                      If SeedPacket also contains options in this list, they are

+                      replaced by new options (except pad option). Ignored if

+                      AppendCount is zero. Type EFI_DHCP4_PACKET_OPTION

+  @param  NewPacket   Pointer to storage for the pointer to the new allocated packet.

+                      Use the EFI Boot Service FreePool() on the resulting pointer

+                      when done with the packet.

+

+  @retval EFI_SUCCESS           The new packet was built.

+  @retval EFI_OUT_OF_RESOURCES  Storage for the new packet could not be allocated.

+  @retval EFI_INVALID_PARAMETER Some parameter is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_BUILD) (

+  IN  EFI_DHCP4_PROTOCOL      *This,

+  IN  EFI_DHCP4_PACKET        *SeedPacket,

+  IN  UINT32                  DeleteCount,

+  IN  UINT8                   *DeleteList         OPTIONAL,

+  IN  UINT32                  AppendCount,

+  IN  EFI_DHCP4_PACKET_OPTION *AppendList[]       OPTIONAL,

+  OUT EFI_DHCP4_PACKET        **NewPacket

+  );

+;   

+

+/**

+  Transmits a DHCP formatted packet and optionally waits for responses.

+

+  @param  This    Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  Token   Pointer to the EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN structure.

+

+  @retval EFI_SUCCESS           The packet was successfully queued for transmission.

+  @retval EFI_INVALID_PARAMETER Some parameter is NULL.

+  @retval EFI_NOT_READY         The previous call to this function has not finished yet. Try to call

+                                this function after collection process completes.

+  @retval EFI_NO_MAPPING        The default station address is not available yet.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval Others                Some other unexpected error occurred.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_TRANSMIT_RECEIVE) (

+  IN EFI_DHCP4_PROTOCOL                *This,

+  IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN  *Token

+  )

+;

+

+

+/**

+  Parses the packed DHCP option data.

+

+  @param  This             Pointer to the EFI_DHCP4_PROTOCOL instance.

+  @param  Packet           Pointer to packet to be parsed.

+  @param  OptionCount      On input, the number of entries in the PacketOptionList.

+                           On output, the number of entries that were written into the

+                           PacketOptionList.

+  @param  PacketOptionList List of packet option entries to be filled in. End option or pad

+                           options are not included.

+

+  @retval EFI_SUCCESS           The packet was successfully parsed.

+  @retval EFI_INVALID_PARAMETER Some parameter is NULL.

+  @retval EFI_BUFFER_TOO_SMALL  One or more of the following conditions is TRUE:

+                                1) *OptionCount is smaller than the number of options that

+                                were found in the Packet.

+                                2) PacketOptionList is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DHCP4_PARSE) (

+  IN EFI_DHCP4_PROTOCOL        *This,

+  IN EFI_DHCP4_PACKET          *Packet,

+  IN OUT UINT32                *OptionCount,

+  OUT EFI_DHCP4_PACKET_OPTION  *PacketOptionList[]  OPTIONAL

+  )

+;

+

+

+struct _EFI_DHCP4_PROTOCOL {

+  EFI_DHCP4_GET_MODE_DATA      GetModeData;

+  EFI_DHCP4_CONFIGURE          Configure;

+  EFI_DHCP4_START              Start;

+  EFI_DHCP4_RENEW_REBIND       RenewRebind;

+  EFI_DHCP4_RELEASE            Release;

+  EFI_DHCP4_STOP               Stop;

+  EFI_DHCP4_BUILD              Build;

+  EFI_DHCP4_TRANSMIT_RECEIVE   TransmitReceive;

+  EFI_DHCP4_PARSE              Parse;

+};

+

+extern EFI_GUID gEfiDhcp4ProtocolGuid;

+extern EFI_GUID gEfiDhcp4ServiceBindingProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DiskIo.h b/edk2/MdePkg/Include/Protocol/DiskIo.h
new file mode 100644
index 0000000..e36792c
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DiskIo.h
@@ -0,0 +1,98 @@
+/** @file

+  Disk IO protocol as defined in the EFI 1.0 specification.

+

+  The Disk IO protocol is used to convert block oriented devices into byte

+  oriented devices. The Disk IO protocol is intended to layer on top of the

+  Block IO protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DiskIo.h

+

+**/

+

+#ifndef __DISK_IO_H__

+#define __DISK_IO_H__

+

+#define EFI_DISK_IO_PROTOCOL_GUID \

+  { \

+    0xce345171, 0xba0b, 0x11d2, {0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+typedef struct _EFI_DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL;

+

+/**

+  Read BufferSize bytes from Offset into Buffer.

+

+  @param  This                  Protocol instance pointer.

+  @param  MediaId               Id of the media, changes every time the media is replaced.

+  @param  Offset                The starting byte offset to read from

+  @param  BufferSize            Size of Buffer

+  @param  Buffer                Buffer containing read data

+

+  @retval EFI_SUCCESS           The data was read correctly from the device.

+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.

+  @retval EFI_NO_MEDIA          There is no media in the device.

+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.

+  @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not

+                                valid for the device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISK_READ) (

+  IN EFI_DISK_IO_PROTOCOL         *This,

+  IN UINT32                       MediaId,

+  IN UINT64                       Offset,

+  IN UINTN                        BufferSize,

+  OUT VOID                        *Buffer

+  )

+;

+

+/**

+  Read BufferSize bytes from Offset into Buffer.

+

+  @param  This       Protocol instance pointer.

+  @param  MediaId    Id of the media, changes every time the media is replaced.

+  @param  Offset     The starting byte offset to read from

+  @param  BufferSize Size of Buffer

+  @param  Buffer     Buffer containing read data

+

+  @retval EFI_SUCCESS           The data was written correctly to the device.

+  @retval EFI_WRITE_PROTECTED   The device can not be written to.

+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.

+  @retval EFI_NO_MEDIA          There is no media in the device.

+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.

+  @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not

+                                 valid for the device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISK_WRITE) (

+  IN EFI_DISK_IO_PROTOCOL         *This,

+  IN UINT32                       MediaId,

+  IN UINT64                       Offset,

+  IN UINTN                        BufferSize,

+  IN VOID                         *Buffer

+  )

+;

+

+#define EFI_DISK_IO_PROTOCOL_REVISION 0x00010000

+

+struct _EFI_DISK_IO_PROTOCOL {

+  UINT64          Revision;

+  EFI_DISK_READ   ReadDisk;

+  EFI_DISK_WRITE  WriteDisk;

+};

+

+extern EFI_GUID gEfiDiskIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DriverBinding.h b/edk2/MdePkg/Include/Protocol/DriverBinding.h
new file mode 100644
index 0000000..5f5d909
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DriverBinding.h
@@ -0,0 +1,111 @@
+/** @file

+  EFI ControllerHandle Driver Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DriverBinding.h

+

+**/

+

+#ifndef __EFI_DRIVER_BINDING_H__

+#define __EFI_DRIVER_BINDING_H__

+

+//

+// Global ID for the ControllerHandle Driver Protocol

+//

+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \

+  { \

+    0x18a031ab, 0xb443, 0x4d1a, {0xa5, 0xc0, 0xc, 0x9, 0x26, 0x1e, 0x9f, 0x71 } \

+  }

+

+typedef struct _EFI_DRIVER_BINDING_PROTOCOL  EFI_DRIVER_BINDING_PROTOCOL;

+

+/**

+  Test to see if this driver supports ControllerHandle. 

+

+  @param  This                Protocol instance pointer.

+  @param  ControllerHandle    Handle of device to test

+  @param  RemainingDevicePath Optional parameter use to pick a specific child

+                              device to start.

+

+  @retval EFI_SUCCESS         This driver supports this device

+  @retval EFI_ALREADY_STARTED This driver is already running on this device

+  @retval other               This driver does not support this device

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_BINDING_SUPPORTED) (

+  IN EFI_DRIVER_BINDING_PROTOCOL            *This,

+  IN EFI_HANDLE                             ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL               *RemainingDevicePath OPTIONAL

+  )

+;

+

+/**

+  Start this driver on ControllerHandle.

+

+  @param  This                 Protocol instance pointer.

+  @param  ControllerHandle     Handle of device to bind driver to

+  @param  RemainingDevicePath  Optional parameter use to pick a specific child

+                               device to start.

+

+  @retval EFI_SUCCESS          This driver is added to ControllerHandle

+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle

+  @retval other                This driver does not support this device

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_BINDING_START) (

+  IN EFI_DRIVER_BINDING_PROTOCOL            *This,

+  IN EFI_HANDLE                             ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL               *RemainingDevicePath OPTIONAL

+  )

+;

+

+/**

+  Stop this driver on ControllerHandle.

+

+  @param  This              Protocol instance pointer.

+  @param  ControllerHandle  Handle of device to stop driver on

+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of

+                            children is zero stop the entire bus driver.

+  @param  ChildHandleBuffer List of Child Handles to Stop.

+

+  @retval EFI_SUCCESS       This driver is removed ControllerHandle

+  @retval other             This driver was not removed from this device

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_BINDING_STOP) (

+  IN EFI_DRIVER_BINDING_PROTOCOL            *This,

+  IN  EFI_HANDLE                            ControllerHandle,

+  IN  UINTN                                 NumberOfChildren,

+  IN  EFI_HANDLE                            *ChildHandleBuffer OPTIONAL

+  )

+;

+

+//

+// Interface structure for the ControllerHandle Driver Protocol

+//

+struct _EFI_DRIVER_BINDING_PROTOCOL {

+  EFI_DRIVER_BINDING_SUPPORTED  Supported;

+  EFI_DRIVER_BINDING_START      Start;

+  EFI_DRIVER_BINDING_STOP       Stop;

+  UINT32                        Version;

+  EFI_HANDLE                    ImageHandle;

+  EFI_HANDLE                    DriverBindingHandle;

+};

+

+extern EFI_GUID gEfiDriverBindingProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DriverConfiguration.h b/edk2/MdePkg/Include/Protocol/DriverConfiguration.h
new file mode 100644
index 0000000..f4f0c7a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DriverConfiguration.h
@@ -0,0 +1,203 @@
+/** @file

+  EFI Driver Configuration Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DriverConfiguration.h

+

+**/

+

+#ifndef __EFI_DRIVER_CONFIGURATION_H__

+#define __EFI_DRIVER_CONFIGURATION_H__

+

+//

+// Global ID for the Driver Configuration Protocol defined in EFI 1.10

+//

+#define EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \

+  { \

+    0x107a772b, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+//

+// Global ID for the Driver Configuration Protocol defined in UEFI 2.0

+//

+#define UEFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \

+  { \

+    0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe } \

+  }

+  

+typedef struct _EFI_DRIVER_CONFIGURATION_PROTOCOL  EFI_DRIVER_CONFIGURATION_PROTOCOL;

+

+typedef enum {

+  EfiDriverConfigurationActionNone              = 0,

+  EfiDriverConfigurationActionStopController    = 1,

+  EfiDriverConfigurationActionRestartController = 2,

+  EfiDriverConfigurationActionRestartPlatform   = 3,

+  EfiDriverConfigurationActionMaximum

+} EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED;

+

+#define EFI_DRIVER_CONFIGURATION_SAFE_DEFAULTS          0x00000000

+#define EFI_DRIVER_CONFIGURATION_MANUFACTURING_DEFAULTS 0x00000001

+#define EFI_DRIVER_CONFIGURATION_CUSTOM_DEFAULTS        0x00000002

+#define EFI_DRIVER_CONFIGURATION_PERORMANCE_DEFAULTS    0x00000003

+

+/**

+  Allows the user to set controller specific options for a controller that a 

+  driver is currently managing.

+

+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.

+  @param  ControllerHandle The handle of the controller to set options on.

+  @param  ChildHandle      The handle of the child controller to set options on.  This

+                           is an optional parameter that may be NULL.  It will be NULL

+                           for device drivers, and for a bus drivers that wish to set

+                           options for the bus controller.  It will not be NULL for a

+                           bus driver that wishes to set options for one of its child

+                           controllers.

+  @param  Language         A pointer to a three character ISO 639-2 language identifier.

+                           This is the language of the user interface that should be

+                           presented to the user, and it must match one of the languages

+                           specified in SupportedLanguages.  The number of languages

+                           supported by a driver is up to the driver writer.

+  @param  ActionRequired   A pointer to the action that the calling agent is required

+                           to perform when this function returns.  See "Related

+                           Definitions" for a list of the actions that the calling

+                           agent is required to perform prior to accessing

+                           ControllerHandle again.

+

+  @retval EFI_SUCCESS           The driver specified by This successfully set the

+                                configuration options for the controller specified

+                                by ControllerHandle..

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ActionRequired is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support setting

+                                configuration options for the controller specified by

+                                ControllerHandle and ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempt to set the

+                                configuration options for the controller specified

+                                by ControllerHandle and ChildHandle.

+  @retval EFI_OUT_RESOURCES     There are not enough resources available to set the

+                                configuration options for the controller specified

+                                by ControllerHandle and ChildHandle.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_CONFIGURATION_SET_OPTIONS) (

+  IN EFI_DRIVER_CONFIGURATION_PROTOCOL                        *This,

+  IN  EFI_HANDLE                                              ControllerHandle,

+  IN  EFI_HANDLE                                              ChildHandle  OPTIONAL,

+  IN  CHAR8                                                   *Language,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED                *ActionRequired

+  );

+

+/**

+  Tests to see if a controller's current configuration options are valid.

+

+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.

+  @param  ControllerHandle The handle of the controller to test if it's current

+                           configuration options are valid.

+  @param  ChildHandle      The handle of the child controller to test if it's current

+                           configuration options are valid.  This is an optional

+                           parameter that may be NULL.  It will be NULL for device

+                           drivers.  It will also be NULL for a bus drivers that wish

+                           to test the configuration options for the bus controller.

+                           It will not be NULL for a bus driver that wishes to test

+                           configuration options for one of its child controllers.

+

+  @retval EFI_SUCCESS           The controller specified by ControllerHandle and

+                                ChildHandle that is being managed by the driver

+                                specified by This has a valid set of  configuration

+                                options.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by ControllerHandle

+                                and ChildHandle.

+  @retval EFI_DEVICE_ERROR      The controller specified by ControllerHandle and

+                                ChildHandle that is being managed by the driver

+                                specified by This has an invalid set of configuration

+                                options.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_CONFIGURATION_OPTIONS_VALID) (

+  IN EFI_DRIVER_CONFIGURATION_PROTOCOL                        *This,

+  IN  EFI_HANDLE                                              ControllerHandle,

+  IN  EFI_HANDLE                                              ChildHandle  OPTIONAL

+  );

+

+/**

+  Forces a driver to set the default configuration options for a controller.

+

+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.

+  @param  ControllerHandle The handle of the controller to force default configuration options on.

+  @param  ChildHandle      The handle of the child controller to force default configuration options on  This is an optional parameter that may be NULL.  It will be NULL for device drivers.  It will also be NULL for a bus drivers that wish to force default configuration options for the bus controller.  It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers.

+  @param  DefaultType      The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle.  See Table 9-1 for legal values.  A DefaultType of 0x00000000 must be supported by this protocol.

+  @param  ActionRequired   A pointer to the action that the calling agent is required to perform when this function returns.  See "Related Definitions" in Section 9.1for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again.

+

+  @retval EFI_SUCCESS           The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ActionRequired is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the configuration type specified by DefaultType.

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempt to force the default configuration options on the controller specified by  ControllerHandle and ChildHandle.

+  @retval EFI_OUT_RESOURCES     There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_CONFIGURATION_FORCE_DEFAULTS) (

+  IN EFI_DRIVER_CONFIGURATION_PROTOCOL                        *This,

+  IN  EFI_HANDLE                                              ControllerHandle,

+  IN  EFI_HANDLE                                              ChildHandle  OPTIONAL,

+  IN  UINT32                                                  DefaultType,

+  OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED                *ActionRequired

+  );

+

+

+//

+//

+struct _EFI_DRIVER_CONFIGURATION_PROTOCOL {

+  EFI_DRIVER_CONFIGURATION_SET_OPTIONS    SetOptions;

+  EFI_DRIVER_CONFIGURATION_OPTIONS_VALID  OptionsValid;

+  EFI_DRIVER_CONFIGURATION_FORCE_DEFAULTS ForceDefaults;

+  CHAR8                                   *SupportedLanguages;

+};

+

+/**

+  Interface structure for the Driver Configuration Protocol.

+

+  @par Protocol Description:  

+  Used to set configuration options for a controller that an EFI Driver is managing.

+

+  @param SetOptions          Allows the use to set drivers specific configuration 

+                             options for a controller that the driver is currently managing.

+                             

+  @param OptionsValid        Tests to see if a controller's current configuration 

+                             options are valid. 

+                             

+  @param ForceDefaults       Forces a driver to set the default configuration options 

+                             for a controller.

+

+  @param SupportedLanguages  A Null-terminated ASCII string that contains one or more 

+                             ISO 639-2 language codes.  This is the list of language 

+                             codes that this protocol supports.

+

+**/

+

+extern EFI_GUID gEfiDriverConfigurationProtocolGuid;

+extern EFI_GUID gUefiDriverConfigurationProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/DriverDiagnostics.h b/edk2/MdePkg/Include/Protocol/DriverDiagnostics.h
new file mode 100644
index 0000000..c0a0cbc
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/DriverDiagnostics.h
@@ -0,0 +1,134 @@
+/** @file

+  EFI Driver Diagnostics Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  DriverDiagnostics.h

+

+**/

+

+#ifndef __EFI_DRIVER_DIAGNOSTICS_H__

+#define __EFI_DRIVER_DIAGNOSTICS_H__

+

+//

+// Global ID for the Driver Diagnostics Protocol as defined in EFI 1.10.

+//

+#define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \

+  { \

+    0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+//

+// Global ID for the Driver Diagnostics Protocol as defined in UEFI 2.0.

+//

+#define UEFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \

+  { \

+    0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63 } \

+  }

+  

+typedef struct _EFI_DRIVER_DIAGNOSTICS_PROTOCOL  EFI_DRIVER_DIAGNOSTICS_PROTOCOL;

+

+typedef enum {

+  EfiDriverDiagnosticTypeStandard     = 0,

+  EfiDriverDiagnosticTypeExtended     = 1,

+  EfiDriverDiagnosticTypeManufacturing= 2,

+  EfiDriverDiagnosticTypeMaximum

+} EFI_DRIVER_DIAGNOSTIC_TYPE;

+

+/**

+  Runs diagnostics on a controller.

+

+  @param  This             A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance.

+  @param  ControllerHandle The handle of the controller to run diagnostics on.

+  @param  ChildHandle      The handle of the child controller to run diagnostics on

+                           This is an optional parameter that may be NULL.  It will

+                           be NULL for device drivers.  It will also be NULL for a

+                           bus drivers that wish to run diagnostics on the bus

+                           controller.  It will not be NULL for a bus driver that

+                           wishes to run diagnostics on one of its child controllers.

+  @param  DiagnosticType   Indicates type of diagnostics to perform on the controller

+                           specified by ControllerHandle and ChildHandle.   See

+                           "Related Definitions" for the list of supported types.

+  @param  Language         A pointer to a three character ISO 639-2 language

+                           identifier.  This is the language in which the optional

+                           error message should be returned in Buffer, and it must

+                           match one of the languages specified in SupportedLanguages.

+                           The number of languages supported by a driver is up to

+                           the driver writer.

+  @param  ErrorType        A GUID that defines the format of the data returned in Buffer.

+  @param  BufferSize       The size, in bytes, of the data returned in Buffer.

+  @param  Buffer           A buffer that contains a Null-terminated Unicode string

+                           plus some additional data whose format is defined by

+                           ErrorType.  Buffer is allocated by this function with

+                           AllocatePool(), and it is the caller's responsibility

+                           to free it with a call to FreePool().

+

+  @retval EFI_SUCCESS           The controller specified by ControllerHandle and

+                                ChildHandle passed the diagnostic.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER ErrorType is NULL.

+  @retval EFI_INVALID_PARAMETER BufferType is NULL.

+  @retval EFI_INVALID_PARAMETER Buffer is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                running diagnostics for the controller specified

+                                by ControllerHandle and ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                type of diagnostic specified by DiagnosticType.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to complete

+                                the diagnostics.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to return

+                                the status information in ErrorType, BufferSize,

+                                and Buffer.

+  @retval EFI_DEVICE_ERROR      The controller specified by ControllerHandle and

+                                ChildHandle did not pass the diagnostic.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DRIVER_DIAGNOSTICS_RUN_DIAGNOSTICS) (

+  IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL                        *This,

+  IN  EFI_HANDLE                                            ControllerHandle,

+  IN  EFI_HANDLE                                            ChildHandle  OPTIONAL,

+  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                            DiagnosticType,

+  IN  CHAR8                                                 *Language,

+  OUT EFI_GUID                                              **ErrorType,

+  OUT UINTN                                                 *BufferSize,

+  OUT CHAR16                                                **Buffer

+  );

+

+

+//

+//

+

+/**

+  Interface structure for the Driver Diagnostics Protocol.

+

+  @par Protocol Description:

+  Used to perform diagnostics on a controller that an EFI Driver is managing.

+

+  @param RunDiagnostics      Runs diagnostics on a controller.

+  @param SupportedLanguages  A Null-terminated ASCII string that contains one or more

+                             ISO 639-2 language codes.  This is the list of language 

+                             codes that this protocol supports.

+

+**/

+struct _EFI_DRIVER_DIAGNOSTICS_PROTOCOL {

+  EFI_DRIVER_DIAGNOSTICS_RUN_DIAGNOSTICS  RunDiagnostics;

+  CHAR8                                   *SupportedLanguages;

+};

+

+extern EFI_GUID gEfiDriverDiagnosticsProtocolGuid;

+extern EFI_GUID gUefiDriverDiagnosticsProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Ebc.h b/edk2/MdePkg/Include/Protocol/Ebc.h
new file mode 100644
index 0000000..c1abcba
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Ebc.h
@@ -0,0 +1,148 @@
+/** @file

+  Describes the protocol interface to the EBC interpreter.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Ebc.h

+

+**/

+

+#ifndef __EFI_EBC_PROTOCOL_H__

+#define __EFI_EBC_PROTOCOL_H__

+

+#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \

+  { \

+    0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7 } \

+  }

+

+//

+// Protocol Guid Name defined in spec.

+//

+#define EFI_EBC_PROTOCOL_GUID EFI_EBC_INTERPRETER_PROTOCOL_GUID

+

+//

+// Define for forward reference.

+//

+typedef struct _EFI_EBC_PROTOCOL EFI_EBC_PROTOCOL;

+

+/**

+  Create a thunk for an image entry point. In short, given the physical address

+  of the entry point for a loaded image, create a thunk that does some 

+  fixup of arguments (and perform any other necessary overhead) and then

+  calls the original entry point. The caller can then use the returned pointer

+  to the created thunk as the new entry point to image.

+

+  @param  This          protocol instance pointer

+  @param  ImageHandle   handle to the image. The EBC interpreter may use this to keep

+                        track of any resource allocations performed in loading and

+                        executing the image.

+  @param  EbcEntryPoint the entry point for the image (as defined in the file header)

+  @param  Thunk pointer to thunk pointer where the address of the created

+                        thunk is returned.

+

+  @return Standard EFI_STATUS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EBC_CREATE_THUNK) (

+  IN EFI_EBC_PROTOCOL           *This,

+  IN EFI_HANDLE                 ImageHandle,

+  IN VOID                       *EbcEntryPoint,

+  OUT VOID                      **Thunk

+  );

+

+/**

+  Perform any cleanup necessary when an image is unloaded. Basically it gives

+  the EBC interpreter the chance to free up any resources allocated during

+  load and execution of an EBC image.

+

+  @param  This        protocol instance pointer

+  @param  ImageHandle the handle of the image being unloaded.

+

+  @return Standard EFI_STATUS.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EBC_UNLOAD_IMAGE) (

+  IN EFI_EBC_PROTOCOL           *This,

+  IN EFI_HANDLE                 ImageHandle

+  );

+

+/**

+  The I-Cache-flush registration service takes a pointer to a function to

+  call to flush the I-Cache. Here's the prototype for that function pointer.

+

+  @param  Start  physical start address of CPU instruction cache to flush.

+  @param  Length how many bytes to flush of the instruction cache.

+

+  @return Standard EFI_STATUS.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EBC_ICACHE_FLUSH) (

+  IN EFI_PHYSICAL_ADDRESS     Start,

+  IN UINT64                   Length

+  );

+

+/**

+  This routine is called by the core firmware to provide the EBC driver with

+  a function to call to flush the CPU's instruction cache following creation

+  of a thunk. It is not required.

+

+  @param  This  protocol instance pointer

+  @param  Flush pointer to the function to call to flush the CPU instruction

+  cache.

+

+  @return Standard EFI_STATUS.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EBC_REGISTER_ICACHE_FLUSH) (

+  IN EFI_EBC_PROTOCOL           *This,

+  IN EBC_ICACHE_FLUSH           Flush

+  );

+

+/**

+  This routine can be called to get the VM revision. It returns the same

+  value as the EBC BREAK 1 instruction returns.

+

+  @param  This    protocol instance pointer

+  @param  Version pointer to where to return the VM version

+

+  @return Standard EFI_STATUS.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EBC_GET_VERSION) (

+  IN EFI_EBC_PROTOCOL           *This,

+  IN OUT UINT64                 *Version

+  );

+

+//

+// Prototype for the actual EBC protocol interface

+//

+struct _EFI_EBC_PROTOCOL {

+  EFI_EBC_CREATE_THUNK          CreateThunk;

+  EFI_EBC_UNLOAD_IMAGE          UnloadImage;

+  EFI_EBC_REGISTER_ICACHE_FLUSH RegisterICacheFlush;

+  EFI_EBC_GET_VERSION           GetVersion;

+};

+

+//

+// Extern the global EBC protocol GUID

+//

+extern EFI_GUID gEfiEbcProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/EdidActive.h b/edk2/MdePkg/Include/Protocol/EdidActive.h
new file mode 100644
index 0000000..0562cbe
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/EdidActive.h
@@ -0,0 +1,34 @@
+/** @file

+  EDID Active Protocol from the UEFI 2.0 specification.

+

+  Placed on the video output device child handle that are actively displaying output.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EdidActive.h

+

+**/

+

+#ifndef __EDID_ACTIVE_H__

+#define __EDID_ACTIVE_H__

+

+#define EFI_EDID_ACTIVE_PROTOCOL_GUID \

+  { \

+    0xbd8c1056, 0x9f36, 0x44ec, {0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 } \

+  }

+

+typedef struct {

+  UINT32   SizeOfEdid;

+  UINT8    *Edid;

+} EFI_EDID_ACTIVE_PROTOCOL;

+

+extern EFI_GUID gEfiEdidActiveProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/EdidDiscovered.h b/edk2/MdePkg/Include/Protocol/EdidDiscovered.h
new file mode 100644
index 0000000..6790666
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/EdidDiscovered.h
@@ -0,0 +1,35 @@
+/** @file

+  EDID Discovered Protocol from the UEFI 2.0 specification.

+

+  This protocol is placed on the video output device child handle and it represents

+  the EDID information being used for output device represented by the child handle.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EdidDiscovered.h

+

+**/

+

+#ifndef __EDID_DISCOVERED_H__

+#define __EDID_DISCOVERED_H__

+

+#define EFI_EDID_DISCOVERED_PROTOCOL_GUID \

+  { \

+    0x1c0c34f6, 0xd380, 0x41fa, {0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa } \

+  }

+

+typedef struct {

+  UINT32   SizeOfEdid;

+  UINT8    *Edid;

+} EFI_EDID_DISCOVERED_PROTOCOL;

+

+extern EFI_GUID gEfiEdidDiscoveredProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/EdidOverride.h b/edk2/MdePkg/Include/Protocol/EdidOverride.h
new file mode 100644
index 0000000..3f4c576
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/EdidOverride.h
@@ -0,0 +1,66 @@
+/** @file

+  EDID Override Protocol from the UEFI 2.0 specification.

+

+  Allow platform to provide EDID information to producer of the Graphics Output

+  protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  EdidOverride.h

+

+**/

+

+#ifndef __EDID_OVERRIDE_H__

+#define __EDID_OVERRIDE_H__

+

+#define EFI_EDID_OVERRIDE_PROTOCOL_GUID \

+  { \

+    0x48ecb431, 0xfb72, 0x45c0, {0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x4, 0xb, 0xd5 } \

+  }

+

+typedef struct _EFI_EDID_OVERRIDE_PROTOCOL EFI_EDID_OVERRIDE_PROTOCOL;

+

+#define EFI_EDID_OVERRIDE_DONT_OVERRIDE   0x01

+#define EFI_EDID_OVERRIDE_ENABLE_HOT_PLUG 0x02

+

+/**

+  Return the current video mode information.

+

+  @param  This              Protocol instance pointer.

+  @param  ChildHandle       A child handle produced by the Graphics Output EFI

+                            driver that represents a video output device.

+  @param  Attributes        The attributes associated with ChildHandle video output device.

+  @param  EdidSize          A pointer to the size, in bytes, of the Edid buffer.

+  @param  Edid              A pointer to callee allocated buffer that contains the EDID that

+                            should be used for ChildHandle. A value of NULL

+                            represents no EDID override for ChildHandle.

+

+  @retval EFI_SUCCESS       Valid overrides returned for ChildHandle.

+  @retval EFI_UNSUPPORTED   ChildHandle has no overrides.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID) (

+  IN  EFI_EDID_OVERRIDE_PROTOCOL          *This,

+  IN  EFI_HANDLE                          *ChildHandle,

+  OUT UINT32                              *Attributes,

+  IN OUT UINTN                            *EdidSize,

+  IN OUT UINT8                            **Edid

+  )

+;

+

+struct _EFI_EDID_OVERRIDE_PROTOCOL {

+  EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID   GetEdid;

+};

+                                             

+extern EFI_GUID gEfiEdidOverrideProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/EfiNetworkInterfaceIdentifier.h b/edk2/MdePkg/Include/Protocol/EfiNetworkInterfaceIdentifier.h
new file mode 100644
index 0000000..98f1c59
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/EfiNetworkInterfaceIdentifier.h
@@ -0,0 +1,92 @@
+/** @file

+  Revision history:

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module name:

+

+  EfiNetworkInterfaceIdentifier.h

+

+**/

+

+#ifndef __EFI_NETWORK_INTERFACE_IDENTIFER_H__

+#define __EFI_NETWORK_INTERFACE_IDENTIFER_H__

+

+

+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID \

+  { \

+    0xE18541CD, 0xF755, 0x4f73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29 } \

+  }

+

+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION    0x00010000

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL;

+

+typedef enum {

+  EfiNetworkInterfaceUndi = 1

+} EFI_NETWORK_PROTOCOL_TYPE;

+

+struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL {

+

+  UINT64  Revision;

+  //

+  // Revision of the network interface identifier protocol interface.

+  //

+  UINT64  ID;

+  //

+  // Address of the first byte of the identifying structure for this

+  // network interface.  This is set to zero if there is no structure.

+  //

+  // For PXE/UNDI this is the first byte of the !PXE structure.

+  //

+  UINT64  ImageAddr;

+  //

+  // Address of the UNrelocated driver/ROM image.  This is set

+  // to zero if there is no driver/ROM image.

+  //

+  // For 16-bit UNDI, this is the first byte of the option ROM in

+  // upper memory.

+  //

+  // For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM

+  // image.

+  //

+  // For H/W UNDI, this is set to zero.

+  //

+  UINT32  ImageSize;

+  //

+  // Size of the UNrelocated driver/ROM image of this network interface.

+  // This is set to zero if there is no driver/ROM image.

+  //

+  CHAR8   StringId[4];

+  //

+  // 4 char ASCII string to go in class identifier (option 60) in DHCP

+  // and Boot Server discover packets.

+  // For EfiNetworkInterfaceUndi this field is "UNDI".

+  // For EfiNetworkInterfaceSnp this field is "SNPN".

+  //

+  UINT8   Type;

+  UINT8   MajorVer;

+  UINT8   MinorVer;

+  //

+  // Information to be placed into the PXE DHCP and Discover packets.

+  // This is the network interface type and version number that will

+  // be placed into DHCP option 94 (client network interface identifier).

+  //

+  BOOLEAN Ipv6Supported;

+  UINT8   IfNum;  // interface number to be used with pxeid structure

+};

+

+extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid;

+extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid_31;

+

+#endif // _EFI_NII_H

diff --git a/edk2/MdePkg/Include/Protocol/FileInfo.h b/edk2/MdePkg/Include/Protocol/FileInfo.h
new file mode 100644
index 0000000..55cf6ae
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FileInfo.h
@@ -0,0 +1,53 @@
+/** @file

+  SimpleFileSystem protocol as defined in the EFI 1.0 specification.

+

+  The SimpleFileSystem protocol is the programatic access to the FAT (12,16,32) 

+  file system specified in EFI 1.0. It can also be used to abstract any 

+  file system other than FAT.

+

+  EFI 1.0 can boot from any valid EFI image contained in a SimpleFileSystem

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FileInfo.c

+

+**/

+

+#ifndef __FILE_INFO_H__

+#define __FILE_INFO_H__

+

+#define EFI_FILE_INFO_ID \

+  { \

+    0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+typedef struct {

+  UINT64    Size;

+  UINT64    FileSize;

+  UINT64    PhysicalSize;

+  EFI_TIME  CreateTime;

+  EFI_TIME  LastAccessTime;

+  EFI_TIME  ModificationTime;

+  UINT64    Attribute;

+  CHAR16    FileName[1];

+} EFI_FILE_INFO;

+

+//

+// The FileName field of the EFI_FILE_INFO data structure is variable length.

+// Whenever code needs to know the size of the EFI_FILE_INFO data structure, it needs to

+// be the size of the data structure without the FileName field.  The following macro

+// computes this size correctly no matter how big the FileName array is declared.

+// This is required to make the EFI_FILE_INFO data structure ANSI compilant.

+//

+#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET (EFI_FILE_INFO, FileName)

+

+extern EFI_GUID gEfiFileInfoGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FileSystemInfo.h b/edk2/MdePkg/Include/Protocol/FileSystemInfo.h
new file mode 100644
index 0000000..f6e7488
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FileSystemInfo.h
@@ -0,0 +1,45 @@
+/** @file

+  FileSystemInfo protocol as defined in the EFI 1.0 specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FileSystemInfo.h

+

+**/

+

+#ifndef __FILE_SYSTEM_INFO_H__

+#define __FILE_SYSTEM_INFO_H__

+

+#define EFI_FILE_SYSTEM_INFO_ID_GUID \

+  { \

+    0x9576e93, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+typedef struct {

+  UINT64  Size;

+  BOOLEAN ReadOnly;

+  UINT64  VolumeSize;

+  UINT64  FreeSpace;

+  UINT32  BlockSize;

+  CHAR16  VolumeLabel[1];

+} EFI_FILE_SYSTEM_INFO;

+

+//

+// The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length.

+// Whenever code needs to know the size of the EFI_FILE_SYSTEM_INFO data structure, it needs

+// to be the size of the data structure without the VolumeLable field.  The following macro

+// computes this size correctly no matter how big the VolumeLable array is declared.

+// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant.

+//

+#define SIZE_OF_EFI_FILE_SYSTEM_INFO  EFI_FIELD_OFFSET (EFI_FILE_SYSTEM_INFO, VolumeLabel)

+

+extern EFI_GUID gEfiFileSystemInfoGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FileSystemVolumeLabelInfo.h b/edk2/MdePkg/Include/Protocol/FileSystemVolumeLabelInfo.h
new file mode 100644
index 0000000..baba276
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FileSystemVolumeLabelInfo.h
@@ -0,0 +1,42 @@
+/** @file

+  FileSystemVolumeLabelInfo protocol as defined in the EFI 1.0 specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FileSystemVolumeLabelInfo.h

+

+**/

+

+#ifndef __FILE_SYSTEM_VOLUME_LABEL_INFO_H__

+#define __FILE_SYSTEM_VOLUME_LABEL_INFO_H__

+

+#define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID_GUID \

+  { \

+    0xDB47D7D3, 0xFE81, 0x11d3, {0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } \

+  }

+

+//

+// Protocol Name defined in spec.

+//

+#define EFI_FILE_SYSTEM_VOLUME_LABEL_ID \

+        EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID_GUID

+

+typedef struct {

+  CHAR16  VolumeLabel[1];

+} EFI_FILE_SYSTEM_VOLUME_LABEL_INFO;

+

+typedef EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FILE_SYSTEM_VOLUME_LABEL;

+

+#define SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO \

+        EFI_FIELD_OFFSET (EFI_FILE_SYSTEM_VOLUME_LABEL_INFO, VolumeLabel)

+

+extern EFI_GUID gEfiFileSystemVolumeLabelInfoIdGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FirmwareVolume.h b/edk2/MdePkg/Include/Protocol/FirmwareVolume.h
new file mode 100644
index 0000000..7f86dbb
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FirmwareVolume.h
@@ -0,0 +1,321 @@
+/** @file

+  This file declares Firmware Volume protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FirmwareVolume.h

+

+  @par Revision Reference:

+  This protocol is defined in Firmware Volume specification.

+  Version 0.9

+

+**/

+

+#ifndef __FIRMWARE_VOLUME_H__

+#define __FIRMWARE_VOLUME_H__

+

+

+//

+// Firmware Volume Protocol GUID definition

+//

+#define EFI_FIRMWARE_VOLUME_PROTOCOL_GUID \

+  { \

+    0x389F751F, 0x1838, 0x4388, {0x83, 0x90, 0xCD, 0x81, 0x54, 0xBD, 0x27, 0xF8 } \

+  }

+

+#define FV_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', '_')

+

+typedef struct _EFI_FIRMWARE_VOLUME_PROTOCOL  EFI_FIRMWARE_VOLUME_PROTOCOL;

+

+//

+// EFI_FV_ATTRIBUTES bit definitions

+//

+typedef UINT64  EFI_FV_ATTRIBUTES;

+

+//

+// ************************************************************

+// EFI_FV_ATTRIBUTES bit definitions

+// ************************************************************

+//

+#define EFI_FV_READ_DISABLE_CAP       0x0000000000000001ULL

+#define EFI_FV_READ_ENABLE_CAP        0x0000000000000002ULL

+#define EFI_FV_READ_STATUS            0x0000000000000004ULL

+

+#define EFI_FV_WRITE_DISABLE_CAP      0x0000000000000008ULL

+#define EFI_FV_WRITE_ENABLE_CAP       0x0000000000000010ULL

+#define EFI_FV_WRITE_STATUS           0x0000000000000020ULL

+

+#define EFI_FV_LOCK_CAP               0x0000000000000040ULL

+#define EFI_FV_LOCK_STATUS            0x0000000000000080ULL

+#define EFI_FV_WRITE_POLICY_RELIABLE  0x0000000000000100ULL

+

+#define EFI_FV_ALIGNMENT_CAP          0x0000000000008000ULL

+#define EFI_FV_ALIGNMENT_2            0x0000000000010000ULL

+#define EFI_FV_ALIGNMENT_4            0x0000000000020000ULL

+#define EFI_FV_ALIGNMENT_8            0x0000000000040000ULL

+#define EFI_FV_ALIGNMENT_16           0x0000000000080000ULL

+#define EFI_FV_ALIGNMENT_32           0x0000000000100000ULL

+#define EFI_FV_ALIGNMENT_64           0x0000000000200000ULL

+#define EFI_FV_ALIGNMENT_128          0x0000000000400000ULL

+#define EFI_FV_ALIGNMENT_256          0x0000000000800000ULL

+#define EFI_FV_ALIGNMENT_512          0x0000000001000000ULL

+#define EFI_FV_ALIGNMENT_1K           0x0000000002000000ULL

+#define EFI_FV_ALIGNMENT_2K           0x0000000004000000ULL

+#define EFI_FV_ALIGNMENT_4K           0x0000000008000000ULL

+#define EFI_FV_ALIGNMENT_8K           0x0000000010000000ULL

+#define EFI_FV_ALIGNMENT_16K          0x0000000020000000ULL

+#define EFI_FV_ALIGNMENT_32K          0x0000000040000000ULL

+#define EFI_FV_ALIGNMENT_64K          0x0000000080000000ULL

+

+//

+// Protocol API definitions

+//

+

+/**

+  Retrieves attributes, insures positive polarity of attribute bits, returns

+  resulting attributes in output parameter

+

+  @param  This Calling context

+  @param  Attributes output buffer which contains attributes

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FV_GET_ATTRIBUTES) (

+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL  *This,

+  OUT EFI_FV_ATTRIBUTES             *Attributes

+  );

+

+/**

+  Sets volume attributes

+

+  @param  This Calling context

+  @param  Attributes Buffer which contains attributes

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FV_SET_ATTRIBUTES) (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN OUT EFI_FV_ATTRIBUTES          *Attributes

+  );

+

+typedef UINT32  EFI_FV_FILE_ATTRIBUTES;

+

+#define EFI_FV_FILE_ATTRIB_ALIGNMENT  0x0000001F

+

+/**

+  Read the requested file (NameGuid) and returns data in Buffer.

+

+  @param  This Calling context

+  @param  NameGuid Filename identifying which file to read

+  @param  Buffer Pointer to pointer to buffer in which contents of file are returned.

+  <br>

+  If Buffer is NULL, only type, attributes, and size are returned as

+  there is no output buffer.

+  <br>

+  If Buffer != NULL and *Buffer == NULL, the output buffer is allocated

+  from BS pool by ReadFile

+  <br>

+  If Buffer != NULL and *Buffer != NULL, the output buffer has been

+  allocated by the caller and is being passed in.

+  

+  @param  BufferSize Indicates the buffer size passed in, and on output the size

+  required to complete the read

+  @param  FoundType Indicates the type of the file who's data is returned

+  @param  FileAttributes Indicates the attributes of the file who's data is resturned

+  @param  AuthenticationStatus Indicates the authentication status of the data

+

+  @retval EFI_SUCCESS

+  @retval EFI_WARN_BUFFER_TOO_SMALL

+  @retval EFI_NOT_FOUND

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_ACCESS_DENIED

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FV_READ_FILE) (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN EFI_GUID                       *NameGuid,

+  IN OUT VOID                       **Buffer,

+  IN OUT UINTN                      *BufferSize,

+  OUT EFI_FV_FILETYPE               *FoundType,

+  OUT EFI_FV_FILE_ATTRIBUTES        *FileAttributes,

+  OUT UINT32                        *AuthenticationStatus

+  );

+

+/**

+  Read the requested section from the specified file and returns data in Buffer.

+

+  @param  This Calling context

+  @param  NameGuid Filename identifying the file from which to read

+  @param  SectionType Indicates what section type to retrieve

+  @param  SectionInstance Indicates which instance of SectionType to retrieve

+  @param  Buffer Pointer to pointer to buffer in which contents of file are returned.

+  <br>

+  If Buffer is NULL, only type, attributes, and size are returned as

+  there is no output buffer.

+  <br>

+  If Buffer != NULL and *Buffer == NULL, the output buffer is allocated

+  from BS pool by ReadFile

+  <br>

+  If Buffer != NULL and *Buffer != NULL, the output buffer has been

+  allocated by the caller and is being passed in.

+  

+  @param  BufferSize Indicates the buffer size passed in, and on output the size

+  required to complete the read

+  @param  AuthenticationStatus Indicates the authentication status of the data

+

+  @retval EFI_SUCCESS

+  @retval EFI_WARN_BUFFER_TOO_SMALL

+  @retval EFI_OUT_OF_RESOURCES

+  @retval EFI_NOT_FOUND

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_ACCESS_DENIED

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FV_READ_SECTION) (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN EFI_GUID                       *NameGuid,

+  IN EFI_SECTION_TYPE               SectionType,

+  IN UINTN                          SectionInstance,

+  IN OUT VOID                       **Buffer,

+  IN OUT UINTN                      *BufferSize,

+  OUT UINT32                        *AuthenticationStatus

+  );

+

+typedef UINT32  EFI_FV_WRITE_POLICY;

+

+#define EFI_FV_UNRELIABLE_WRITE 0x00000000

+#define EFI_FV_RELIABLE_WRITE   0x00000001

+

+typedef struct {

+  EFI_GUID                *NameGuid;

+  EFI_FV_FILETYPE         Type;

+  EFI_FV_FILE_ATTRIBUTES  FileAttributes;

+  VOID                    *Buffer;

+  UINT32                  BufferSize;

+} EFI_FV_WRITE_FILE_DATA;

+

+/**

+  Write the supplied file (NameGuid) to the FV.

+

+  @param  This Calling context

+  @param  NumberOfFiles Indicates the number of file records pointed to by FileData

+  @param  WritePolicy Indicates the level of reliability of the write with respect to

+  things like power failure events.

+  @param  FileData A pointer to an array of EFI_FV_WRITE_FILE_DATA structures.  Each

+  element in the array indicates a file to write, and there are

+  NumberOfFiles elements in the input array.

+

+  @retval EFI_SUCCESS

+  @retval EFI_OUT_OF_RESOURCES

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_WRITE_PROTECTED

+  @retval EFI_NOT_FOUND

+  @retval EFI_INVALID_PARAMETER

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FV_WRITE_FILE) (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN UINT32                         NumberOfFiles,

+  IN EFI_FV_WRITE_POLICY            WritePolicy,

+  IN EFI_FV_WRITE_FILE_DATA         *FileData

+  );

+

+/**

+  Given the input key, search for the next matching file in the volume.

+

+  @param  This Calling context

+  @param  Key Pointer to a caller allocated buffer that contains an implementation

+  specific key that is used to track where to begin searching on

+  successive calls.

+  @param  FileType Indicates the file type to filter for

+  @param  NameGuid Guid filename of the file found

+  @param  Attributes Attributes of the file found

+  @param  Size Size in bytes of the file found

+

+  @retval EFI_SUCCESS

+  @retval EFI_NOT_FOUND

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_ACCESS_DENIED

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FV_GET_NEXT_FILE) (

+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,

+  IN OUT VOID                       *Key,

+  IN OUT EFI_FV_FILETYPE            *FileType,

+  OUT EFI_GUID                      *NameGuid,

+  OUT EFI_FV_FILE_ATTRIBUTES        *Attributes,

+  OUT UINTN                         *Size

+  );

+

+/**

+  @par Protocol Description:

+  The Firmware Volume Protocol provides file-level access to the firmware volume.

+  Each firmware volume driver must produce an instance of the Firmware Volume 

+  Protocol if the firmware volume is to be visible to the system. The Firmware 

+  Volume Protocol also provides mechanisms for determining and modifying some 

+  attributes of the firmware volume.  

+

+  @param GetVolumeAttributes

+  Retrieves volume capabilities and current settings. 

+

+  @param SetVolumeAttributes

+  Modifies the current settings of the firmware volume.

+

+  @param ReadFile

+  Reads an entire file from the firmware volume. 

+

+  @param ReadSection

+  Reads a single section from a file into a buffer.

+

+  @param WriteFile

+  Writes an entire file into the firmware volume.

+

+  @param GetNextFile

+  Provides service to allow searching the firmware volume.

+

+  @param KeySize

+  Data field that indicates the size in bytes of the Key input buffer for 

+  the GetNextFile() API. 

+

+  @param ParentHandle

+  Handle of the parent firmware volume.

+

+**/

+struct _EFI_FIRMWARE_VOLUME_PROTOCOL {

+  EFI_FV_GET_ATTRIBUTES GetVolumeAttributes;

+  EFI_FV_SET_ATTRIBUTES SetVolumeAttributes;

+  EFI_FV_READ_FILE      ReadFile;

+  EFI_FV_READ_SECTION   ReadSection;

+  EFI_FV_WRITE_FILE     WriteFile;

+  EFI_FV_GET_NEXT_FILE  GetNextFile;

+  UINT32                KeySize;

+  EFI_HANDLE            ParentHandle;

+};

+

+extern EFI_GUID gEfiFirmwareVolumeProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FirmwareVolumeBlock.h b/edk2/MdePkg/Include/Protocol/FirmwareVolumeBlock.h
new file mode 100644
index 0000000..ee849a1
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FirmwareVolumeBlock.h
@@ -0,0 +1,251 @@
+/** @file

+  This file declares Firmware Volume Block protocol.

+

+  Low level firmware device access routines to abstract firmware device

+  hardware.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FirmwareVolumeBlock.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework of EFI Firmware Volume Block specification.

+  Version 0.9

+

+**/

+

+#ifndef __FIRMWARE_VOLUME_BLOCK_H__

+#define __FIRMWARE_VOLUME_BLOCK_H__

+

+

+#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \

+  { \

+    0xDE28BC59, 0x6228, 0x41BD, {0xBD, 0xF6, 0xA3, 0xB9, 0xAD, 0xB5, 0x8D, 0xA1 } \

+  }

+

+typedef struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL;

+

+/**

+  Retrieves Volume attributes.  No polarity translations are done.

+

+  @param  This Calling context

+  @param  Attributes output buffer which contains attributes

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_GET_ATTRIBUTES) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_FVB_ATTRIBUTES                          *Attributes

+  )

+;

+

+/**

+  Sets Volume attributes.  No polarity translations are done.

+

+  @param  This Calling context

+  @param  Attributes On input: contains new attributes

+  On output: contains current attributes of FV

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_SET_ATTRIBUTES) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN OUT EFI_FVB_ATTRIBUTES                       *Attributes

+  )

+;

+

+/**

+  Retrieves the physical address of a memory mapped FV.

+

+  @param  This Calling context

+  @param  Attributes Address is a pointer to a caller allocated EFI_PHYSICAL_ADDRESS

+  that on successful return from GetPhysicalAddress() contains the

+  base address of the firmware volume.

+

+  @retval EFI_UNSUPPORTED

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_GET_PHYSICAL_ADDRESS) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  OUT EFI_PHYSICAL_ADDRESS                        *Address

+  )

+;

+

+/**

+  Retrieves the size in bytes of a specific block within an FV.

+

+  @param  This Calling context.

+  @param  Lba Indicates which block to return the size for.

+  @param  BlockSize BlockSize is a pointer to a caller allocated

+  UINTN in which the size of the block is returned.

+  @param  NumberOfBlocks NumberOfBlocks is a pointer to a caller allocated

+  UINTN in which the number of consecutive blocks

+  starting with Lba is returned. All blocks in this

+  range have a size of BlockSize.

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_GET_BLOCK_SIZE) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  OUT UINTN                                       *BlockSize,

+  OUT UINTN                                       *NumberOfBlocks

+  )

+;

+

+/**

+  Reads data beginning at Lba:Offset from FV and places the data in Buffer.

+  The read terminates either when *NumBytes of data have been read, or when

+  a block boundary is reached.  *NumBytes is updated to reflect the actual

+  number of bytes read.

+

+  @param  This Calling context

+  @param  Lba Block in which to begin read

+  @param  Offset Offset in the block at which to begin read

+  @param  NumBytes At input, indicates the requested read size.  At output, indicates

+  the actual number of bytes read.

+  @param  Buffer Data buffer in which to place data read.

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_NOT_FOUND

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_READ) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  OUT UINT8                                       *Buffer

+  )

+;

+

+/**

+  Writes data beginning at Lba:Offset from FV. The write terminates either

+  when *NumBytes of data have been written, or when a block boundary is

+  reached.  *NumBytes is updated to reflect the actual number of bytes

+  written.

+

+  @param  This Calling context

+  @param  Lba Block in which to begin write

+  @param  Offset Offset in the block at which to begin write

+  @param  NumBytes At input, indicates the requested write size.  At output, indicates

+  the actual number of bytes written.

+  @param  Buffer Buffer containing source data for the write.

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_NOT_FOUND

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_SUCCESS

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_WRITE) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  IN EFI_LBA                                      Lba,

+  IN UINTN                                        Offset,

+  IN OUT UINTN                                    *NumBytes,

+  IN UINT8                                        *Buffer

+  )

+;

+

+#define EFI_LBA_LIST_TERMINATOR 0xFFFFFFFFFFFFFFFFULL

+

+/**

+  The EraseBlock() function erases one or more blocks as denoted by the 

+  variable argument list. The entire parameter list of blocks must be verified

+  prior to erasing any blocks.  If a block is requested that does not exist 

+  within the associated firmware volume (it has a larger index than the last 

+  block of the firmware volume), the EraseBlock() function must return

+  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

+

+  @param  This Calling context

+  @param  ... Starting LBA followed by Number of Lba to erase. a -1 to terminate

+  the list.

+

+  @retval EFI_INVALID_PARAMETER

+  @retval EFI_DEVICE_ERROR

+  @retval EFI_SUCCESS

+  @retval EFI_ACCESS_DENIED

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FVB_ERASE_BLOCKS) (

+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,

+  ...

+  )

+;

+

+/**

+  @par Protocol Description:

+  This protocol provides control over block-oriented firmware devices.  

+  Typically, the FFS (or an alternate file system) driver consumes the 

+  Firmware Volume Block Protocol and produces the Firmware Volume Protocol. 

+

+  @param GetAttributes

+  Retrieves the current volume attributes.

+

+  @param SetAttributes

+  Sets the current volume attributes. 

+

+  @param GetPhysicalAddress

+  Retrieves the memory-mapped address of the firmware volume. 

+

+  @param GetBlockSize

+  Retrieves the size for a specific block.

+

+  @param Read

+  Reads n bytes into a buffer from the firmware volume hardware.

+

+  @param Write

+  Writes n bytes from a buffer into the firmware volume hardware. 

+

+  @param EraseBlocks

+  Erases specified block(s) and sets all values as indicated by 

+  the EFI_FVB_ERASE_POLARITY bit.

+

+  @param ParentHandle

+  Handle of the parent firmware volume.

+

+**/

+struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL {

+  EFI_FVB_GET_ATTRIBUTES        GetVolumeAttributes;

+  EFI_FVB_SET_ATTRIBUTES        SetVolumeAttributes;

+  EFI_FVB_GET_PHYSICAL_ADDRESS  GetPhysicalAddress;

+  EFI_FVB_GET_BLOCK_SIZE        GetBlockSize;

+  EFI_FVB_READ                  Read;

+  EFI_FVB_WRITE                 Write;

+  EFI_FVB_ERASE_BLOCKS          EraseBlocks;

+  EFI_HANDLE                    ParentHandle;

+};

+

+extern EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FirmwareVolumeDispatch.h b/edk2/MdePkg/Include/Protocol/FirmwareVolumeDispatch.h
new file mode 100644
index 0000000..249a476
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FirmwareVolumeDispatch.h
@@ -0,0 +1,33 @@
+/** @file

+  This file declares Firmware Volume Dispatch protocol.

+

+  Presence of this protocol tells the dispatch to dispatch from this Firmware 

+  Volume

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FirmwareVolumeDispatch.h

+

+  @par Revision Reference:

+  This protol will be defined in DXE CIS Spec.

+  Version 0.91C.

+

+**/

+

+#ifndef __FIRMWARE_VOLUME_DISPATCH_H__

+#define __FIRMWARE_VOLUME_DISPATCH_H__

+

+#define EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID \

+  { 0x7aa35a69, 0x506c, 0x444f, {0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8 } }

+

+

+extern EFI_GUID gEfiFirmwareVolumeDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FormBrowser.h b/edk2/MdePkg/Include/Protocol/FormBrowser.h
new file mode 100644
index 0000000..c0ee94a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FormBrowser.h
@@ -0,0 +1,180 @@
+/** @file

+  The EFI_FORM_BROWSER_PROTOCOL is the interface to the EFI 

+  Configuration Driver.  This will allow the caller to direct the 

+  configuration driver to use either the HII database or use the passed 

+  in packet of data.  This will also allow the caller to post messages 

+  into the configuration drivers internal mailbox.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FormBrowser.h

+

+  @par Revision Reference:

+  This protocol is defined in HII spec 0.92.

+

+**/

+

+#ifndef __FORM_BROWSER_H__

+#define __FORM_BROWSER_H__

+

+

+#define EFI_FORM_BROWSER_PROTOCOL_GUID \

+  { \

+    0xe5a1333e, 0xe1b4, 0x4d55, {0xce, 0xeb, 0x35, 0xc3, 0xef, 0x13, 0x34, 0x43 } \

+  }

+

+typedef struct _EFI_FORM_BROWSER_PROTOCOL EFI_FORM_BROWSER_PROTOCOL;

+

+typedef struct {

+  UINT32  Length;

+  UINT16  Type;

+  UINT8   Data[1];

+} EFI_HII_PACKET;

+

+typedef struct {

+  EFI_HII_IFR_PACK    *IfrData;

+  EFI_HII_STRING_PACK *StringData;

+} EFI_IFR_PACKET;

+

+typedef struct {

+  UINTN LeftColumn;

+  UINTN RightColumn;

+  UINTN TopRow;

+  UINTN BottomRow;

+} EFI_SCREEN_DESCRIPTOR;

+

+/**

+  Provides direction to the configuration driver whether to use the HII 

+  database or a passed-in set of data. This function also establishes a 

+  pointer to the calling driver¡¯s callback interface. 

+

+  @param  This A pointer to the EFI_FORM_BROWSER_PROTOCOL instance.

+  

+  @param  UseDatabase Determines whether the HII database is to be 

+  used to gather information. If the value is FALSE, the configuration 

+  driver will get the information provided in the passed-in Packet parameters.

+  

+  @param  Handle A pointer to an array of HII handles to display. This value 

+  should correspond to the value of the HII form package that is required to 

+  be displayed.

+  

+  @param  HandleCount The number of handles in the array specified by Handle.

+  

+  @param  Packet A pointer to a set of data containing pointers to IFR 

+  and/or string data. 

+  

+  @param  CallbackHandle The handle to the driver¡¯s callback interface. 

+  This parameter is used only when the UseDatabase parameter is FALSE 

+  and an application wants to register a callback with the browser

+  

+  @param  NvMapOverride This buffer is used only when there is no NV variable 

+  to define the current settings and the caller needs to provide to the browser 

+  the current settings for the "fake" NV variable.

+  

+  @param  ScreenDimensions Allows the browser to be called so that it occupies 

+  a portion of the physical screen instead of dynamically determining the 

+  screen dimensions. 

+  

+  @param  ResetRequired This BOOLEAN value will tell the caller if a reset 

+  is required based on the data that might have been changed. The ResetRequired 

+  parameter is primarily applicable for configuration applications, and is an 

+  optional parameter. 

+

+  @retval EFI_SUCCESS The function completed successfully

+  

+  @retval EFI_NOT_FOUND The variable was not found.

+  

+  @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. 

+  DataSize has been updated with the size needed to complete the request.

+  

+  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.

+  

+  @retval EFI_DEVICE_ERROR The variable could not be saved due to a hardware failure. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SEND_FORM) (

+  IN  EFI_FORM_BROWSER_PROTOCOL       *This,

+  IN  BOOLEAN                         UseDatabase,

+  IN  EFI_HII_HANDLE                  *Handle,

+  IN  UINTN                           HandleCount,

+  IN  EFI_IFR_PACKET                  *Packet, OPTIONAL

+  IN  EFI_HANDLE                      CallbackHandle, OPTIONAL

+  IN  UINT8                           *NvMapOverride, OPTIONAL

+  IN EFI_SCREEN_DESCRIPTOR            *ScreenDimensions, OPTIONAL

+  OUT BOOLEAN                         *ResetRequired OPTIONAL

+  );

+

+/**

+  Routine used to abstract a generic dialog interface and return the selected 

+  key or string.

+

+  @param  NumberOfLines The number of lines for the dialog box.

+  

+  @param  HotKey Defines whether a single character is parsed (TRUE) 

+  and returned in KeyValue or if a string is returned in StringBuffer. 

+  

+  @param  MaximumStringSize The maximum size in bytes of a typed-in string. 

+  Because each character is a CHAR16, the minimum string returned is two bytes.

+  

+  @param  StringBuffer The passed-in pointer to the buffer that will hold 

+  the typed in string if HotKey is FALSE.

+  

+  @param  KeyValue The EFI_INPUT_KEY value returned if HotKey is TRUE.

+  

+  @param  String The pointer to the first string in the list of strings 

+  that comprise the dialog box.

+  

+  @param  ... A series of NumberOfLines text strings that will be used 

+  to construct the dialog box. 

+

+  @retval EFI_SUCCESS The dialog was displayed and user interaction was received.

+  

+  @retval EFI_DEVICE_ERROR The user typed in an ESC character to exit the routine.

+  

+  @retval EFI_INVALID_PARAMETER One of the parameters was invalid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CREATE_POP_UP) (

+  IN  UINTN                           NumberOfLines,

+  IN  BOOLEAN                         HotKey,

+  IN  UINTN                           MaximumStringSize,

+  OUT CHAR16                          *StringBuffer,

+  OUT EFI_INPUT_KEY                   *KeyValue,

+  IN  CHAR16                          *String,

+  ...

+  );

+

+/**

+  @par Protocol Description:

+  The EFI_FORM_BROWSER_PROTOCOL is the interface to call for drivers to 

+  leverage the EFI configuration driver interface. 

+

+  @param SendForm

+  Provides direction to the configuration driver whether to use the HII 

+  database or to use a passed-in set of data. This functions also establishes 

+  a pointer to the calling driver¡¯s callback interface. 

+

+  @param CreatePopUp

+  Routine used to abstract a generic dialog interface and return the 

+  selected key or string.

+

+**/

+struct _EFI_FORM_BROWSER_PROTOCOL {

+  EFI_SEND_FORM     SendForm;

+  EFI_CREATE_POP_UP CreatePopUp;

+};

+

+extern EFI_GUID gEfiFormBrowserProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/FormCallback.h b/edk2/MdePkg/Include/Protocol/FormCallback.h
new file mode 100644
index 0000000..7a1c539
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/FormCallback.h
@@ -0,0 +1,227 @@
+/** @file

+  The EFI_FORM_CALLBACK_PROTOCOL is the defined interface for access to custom 

+  NV storage devices as well as communication of user selections in a more 

+  interactive environment.  This protocol should be published by hardware 

+  specific drivers which want to export access to custom hardware storage or 

+  publish IFR which has a requirement to call back the original driver.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  FormCallback.h

+

+  @par Revision Reference:

+  This protocol is defined in HII spec 0.92.

+

+**/

+

+#ifndef __FORM_CALLBACK_H__

+#define __FORM_CALLBACK_H__

+

+

+#define EFI_FORM_CALLBACK_PROTOCOL_GUID \

+  { \

+    0xf3e4543d, 0xcf35, 0x6cef, {0x35, 0xc4, 0x4f, 0xe6, 0x34, 0x4d, 0xfc, 0x54 } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_FORM_CALLBACK_PROTOCOL  EFI_FORM_CALLBACK_PROTOCOL;

+

+

+#define RESET_REQUIRED  1 // Flags setting to signify that the callback operation resulted in an eventual

+// reset to be done upon exit of the browser

+//

+#define EXIT_REQUIRED   2   // Flags setting to signify that after the processing of the callback results - exit the browser

+#define SAVE_REQUIRED   4   // Flags setting to signify that after the processing of the callback results - save the NV data

+#define NV_CHANGED      8   // Flags setting to signify that after the processing of the callback results - turn the NV flag on

+#define NV_NOT_CHANGED  16  // Flags setting to signify that after the processing of the callback results - turn the NV flag off

+#pragma pack(1)

+typedef struct {

+  UINT8   OpCode;           // Likely a string, numeric, or one-of

+  UINT8   Length;           // Length of the EFI_IFR_DATA_ENTRY packet

+  UINT16  Flags;            // Flags settings to determine what behavior is desired from the browser after the callback

+  VOID    *Data;            // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately

+  // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value

+  // If the OpCode is a String type - Data is a CHAR16[x] type

+  // If the OpCode is a Checkbox type - Data is a UINT8 value

+  // If the OpCode is a NV Access type - Data is a EFI_IFR_NV_DATA structure

+  //

+} EFI_IFR_DATA_ENTRY;

+

+typedef struct {

+  VOID                *NvRamMap;  // If the flag of the op-code specified retrieval of a copy of the NVRAM map,

+  // this is a pointer to a buffer copy

+  //

+  UINT32              EntryCount; // How many EFI_IFR_DATA_ENTRY entries

+  //

+  // EFI_IFR_DATA_ENTRY  Data[1];    // The in-line Data entries.

+  //

+} EFI_IFR_DATA_ARRAY;

+

+typedef union {

+  EFI_IFR_DATA_ARRAY  DataArray;  // Primarily used by those who call back to their drivers and use HII as a repository

+  EFI_IFR_PACKET      DataPacket; // Primarily used by those which do not use HII as a repository

+  CHAR16              *String;  // If returning an error - fill the string with null-terminated contents

+} EFI_HII_CALLBACK_PACKET;

+

+typedef struct {

+  EFI_IFR_OP_HEADER Header;

+  UINT16            QuestionId;   // Offset into the map

+  UINT8             StorageWidth; // Width of the value

+  //

+  // CHAR8             Data[1];      // The Data itself

+  //

+} EFI_IFR_NV_DATA;

+

+#pragma pack()

+//

+// The following types are currently defined:

+//

+/**

+  Returns the value of a variable. 

+

+  @param  This A pointer to the EFI_FORM_CALLBACK_PROTOCOL instance.

+  

+  @param  VariableName A NULL-terminated Unicode string that is the 

+  name of the vendor¡¯s variable. 

+  

+  @param  VendorGuid A unique identifier for the vendor.

+  

+  @param  Attributes If not NULL, a pointer to the memory location to 

+  return the attribute's bit-mask for the variable. 

+  

+  @param  DataSize The size in bytes of the Buffer. A size of zero causes 

+  the variable to be deleted.

+  

+  @param  Buffer The buffer to return the contents of the variable.

+

+  @retval EFI_SUCCESS  The function completed successfully.

+  

+  @retval EFI_NOT_FOUND  The variable was not found.

+  

+  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. 

+  DataSize has been updated with the size needed to complete the request.

+  

+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.

+  

+  @retval EFI_DEVICE_ERROR  The variable could not be saved due to a hardware failure. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_NV_READ) (

+  IN     EFI_FORM_CALLBACK_PROTOCOL    *This,

+  IN     CHAR16                        *VariableName,

+  IN     EFI_GUID                      *VendorGuid,

+  OUT    UINT32                        *Attributes OPTIONAL,

+  IN OUT UINTN                         *DataSize,

+  OUT    VOID                          *Buffer

+  );

+

+/**

+  Sets the value of a variable. 

+

+  @param  This A pointer to the EFI_FORM_CALLBACK_PROTOCOL instance.

+  

+  @param  VariableName A NULL-terminated Unicode string that is the 

+  name of the vendor's variable. Each VariableName is unique for each VendorGuid.

+  

+  @param  VendorGuid A unique identifier for the vendor.

+  

+  @param  Attributes Attributes bit-mask to set for the variable. 

+  

+  @param  DataSize The size in bytes of the Buffer. A size of zero causes 

+  the variable to be deleted.

+  

+  @param  Buffer The buffer containing the contents of the variable.

+  

+  @param  ResetRequired Returns a value from the driver that abstracts 

+  this information and will enable a system to know if a system reset 

+  is required to achieve the configuration changes being enabled through 

+  this function.

+

+  @retval EFI_SUCCESS  The firmware has successfully stored the variable and 

+  its data as defined by the Attributes.

+  

+  @retval EFI_OUT_OF_RESOURCES  Not enough storage is available to hold 

+  the variable and its data.

+  

+  @retval EFI_INVALID_PARAMETER  An invalid combination of Attributes bits 

+  was supplied, or the DataSize exceeds the maximum allowed.

+  

+  @retval EFI_DEVICE_ERROR  The variable could not be saved due to a hardware failure. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_NV_WRITE) (

+  IN     EFI_FORM_CALLBACK_PROTOCOL    *This,

+  IN     CHAR16                        *VariableName,

+  IN     EFI_GUID                      *VendorGuid,

+  IN     UINT32                        Attributes,

+  IN     UINTN                         DataSize,

+  IN     VOID                          *Buffer,

+  OUT    BOOLEAN                       *ResetRequired

+  );

+

+/**

+  This function is called to provide results data to the driver. 

+

+  @param  This A pointer to the EFI_FORM_CALLBACK_PROTOCOL instance.

+  

+  @param  KeyValue A unique value which is sent to the original exporting 

+  driver so that it can identify the type of data to expect. The format of 

+  the data tends to vary based on the opcode that generated the callback. 

+  

+  @param  Data A pointer to the data being sent to the original exporting driver. 

+  

+  @param  Packet A pointer to a packet of information which a driver passes 

+  back to the browser.

+

+  @return Status Code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FORM_CALLBACK) (

+  IN     EFI_FORM_CALLBACK_PROTOCOL    *This,

+  IN     UINT16                        KeyValue,

+  IN     EFI_IFR_DATA_ARRAY            *Data,

+  OUT    EFI_HII_CALLBACK_PACKET       **Packet

+  );

+

+/**

+  @par Protocol Description:

+  The EFI_FORM_CALLBACK_PROTOCOL is the defined interface for access to 

+  custom NVS devices as well as communication of user selections in a more 

+  interactive environment. This protocol should be published by hardware-specific 

+  drivers that want to export access to custom hardware storage or publish IFR 

+  that has a requirement to call back the original driver.

+

+  @param NvRead

+  The read operation to access the NV data serviced by a hardware-specific driver.

+

+  @param NvWrite

+  The write operation to access the NV data serviced by a hardware-specific driver.

+

+  @param Callback

+  The function that is called from the configuration browser to communicate key value pairs. 

+

+**/

+struct _EFI_FORM_CALLBACK_PROTOCOL {

+  EFI_NV_READ       NvRead;

+  EFI_NV_WRITE      NvWrite;

+  EFI_FORM_CALLBACK Callback;

+};

+

+extern EFI_GUID gEfiFormCallbackProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/GraphicsOutput.h b/edk2/MdePkg/Include/Protocol/GraphicsOutput.h
new file mode 100644
index 0000000..1b4e1fc
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/GraphicsOutput.h
@@ -0,0 +1,194 @@
+/** @file

+  Graphics Output Protocol from the UEFI 2.0 specification.

+

+  Abstraction of a very simple graphics device.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  GraphicsOutput.h

+

+**/

+

+#ifndef __GRAPHICS_OUTPUT_H__

+#define __GRAPHICS_OUTPUT_H__

+

+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \

+  { \

+    0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \

+  }

+

+typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;

+

+typedef struct {

+  UINT32            RedMask;

+  UINT32            GreenMask;

+  UINT32            BlueMask;

+  UINT32            ReservedMask;

+} EFI_PIXEL_BITMASK;

+

+typedef enum {

+  PixelRedGreenBlueReserved8BitPerColor,

+  PixelBlueGreenRedReserved8BitPerColor,

+  PixelBitMask,

+  PixelBltOnly,

+  PixelFormatMax

+} EFI_GRAPHICS_PIXEL_FORMAT;

+

+typedef struct {

+  UINT32                     Version;

+  UINT32                     HorizontalResolution;

+  UINT32                     VerticalResolution;

+  EFI_GRAPHICS_PIXEL_FORMAT  PixelFormat;

+  EFI_PIXEL_BITMASK          PixelInformation;

+  UINT32                     PixelsPerScanLine;

+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;

+

+/**

+  Return the current video mode information.

+

+  @param  This       Protocol instance pointer.

+  @param  ModeNumber The mode number to return information on.

+  @param  SizeOfInfo A pointer to the size, in bytes, of the Info buffer.

+  @param  Info       A pointer to callee allocated buffer that returns information about ModeNumber.

+

+  @retval EFI_SUCCESS           Mode information returned.

+  @retval EFI_BUFFER_TOO_SMALL  The Info buffer was too small.

+  @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.

+  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()

+  @retval EFI_INVALID_PARAMETER One of the input args was NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (

+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,

+  IN  UINT32                                ModeNumber,

+  OUT UINTN                                 *SizeOfInfo,

+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info

+  )

+;

+

+/**

+  Return the current video mode information.

+

+  @param  This              Protocol instance pointer.

+  @param  ModeNumber        The mode number to be set.

+

+  @retval EFI_SUCCESS       Graphics mode was changed.

+  @retval EFI_DEVICE_ERROR  The device had an error and could not complete the request.

+  @retval EFI_UNSUPPORTED   ModeNumber is not supported by this device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (

+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,

+  IN  UINT32                       ModeNumber

+  )

+;

+

+typedef struct {

+  UINT8 Blue;

+  UINT8 Green;

+  UINT8 Red;

+  UINT8 Reserved;

+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;

+

+typedef union {

+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel;

+  UINT32                        Raw;

+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION;

+

+typedef enum {

+  EfiBltVideoFill,

+  EfiBltVideoToBltBuffer,

+  EfiBltBufferToVideo, 

+  EfiBltVideoToVideo,

+  EfiGraphicsOutputBltOperationMax

+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;

+

+/**

+  The following table defines actions for BltOperations:

+

+  <B>EfiBltVideoFill</B> - Write data from the  BltBuffer pixel (SourceX, SourceY) 

+  directly to every pixel of the video display rectangle 

+  (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). 

+  Only one pixel will be used from the BltBuffer. Delta is NOT used.

+

+  <B>EfiBltVideoToBltBuffer</B> - Read data from the video display rectangle 

+  (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in 

+  the BltBuffer rectangle (DestinationX, DestinationY ) 

+  (DestinationX + Width, DestinationY + Height). If DestinationX or 

+  DestinationY is not zero then Delta must be set to the length in bytes 

+  of a row in the BltBuffer.

+

+  <B>EfiBltBufferToVideo</B> - Write data from the  BltBuffer rectangle 

+  (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the 

+  video display rectangle (DestinationX, DestinationY) 

+  (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is 

+  not zero then Delta must be set to the length in bytes of a row in the 

+  BltBuffer.

+

+  <B>EfiBltVideoToVideo</B> - Copy from the video display rectangle (SourceX, SourceY)

+  (SourceX + Width, SourceY + Height) .to the video display rectangle 

+  (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). 

+  The BltBuffer and Delta  are not used in this mode.

+

+  @param  This         Protocol instance pointer.

+  @param  BltBuffer    Buffer containing data to blit into video buffer. This

+                       buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)

+  @param  BltOperation Operation to perform on BlitBuffer and video memory

+  @param  SourceX      X coordinate of source for the BltBuffer.

+  @param  SourceY      Y coordinate of source for the BltBuffer.

+  @param  DestinationX X coordinate of destination for the BltBuffer.

+  @param  DestinationY Y coordinate of destination for the BltBuffer.

+  @param  Width        Width of rectangle in BltBuffer in pixels.

+  @param  Height       Hight of rectangle in BltBuffer in pixels.

+  @param  Delta        OPTIONAL

+

+  @retval EFI_SUCCESS           The Blt operation completed.

+  @retval EFI_INVALID_PARAMETER BltOperation is not valid.

+  @retval EFI_DEVICE_ERROR      A hardware error occured writting to the video buffer.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (

+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,

+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL           *BltBuffer,   OPTIONAL

+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION       BltOperation,

+  IN  UINTN                                   SourceX,

+  IN  UINTN                                   SourceY,

+  IN  UINTN                                   DestinationX,

+  IN  UINTN                                   DestinationY,

+  IN  UINTN                                   Width,

+  IN  UINTN                                   Height,

+  IN  UINTN                                   Delta         OPTIONAL

+  );

+

+typedef struct {

+  UINT32                                 MaxMode;

+  UINT32                                 Mode;

+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;

+  UINTN                                  SizeOfInfo;

+  EFI_PHYSICAL_ADDRESS                   FrameBufferBase;

+  UINTN                                  FrameBufferSize;

+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;

+

+struct _EFI_GRAPHICS_OUTPUT_PROTOCOL {

+  EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE  QueryMode;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE    SetMode;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT         Blt;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE        *Mode;

+};

+

+extern EFI_GUID gEfiGraphicsOutputProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/GuidedSectionExtraction.h b/edk2/MdePkg/Include/Protocol/GuidedSectionExtraction.h
new file mode 100644
index 0000000..d98c56a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/GuidedSectionExtraction.h
@@ -0,0 +1,102 @@
+/** @file

+  This file declares GUIDed section extraction protocol.

+

+  This interface provides a means of decoding a GUID defined encapsulation 

+  section. There may be multiple different GUIDs associated with the GUIDed

+  section extraction protocol. That is, all instances of the GUIDed section

+  extraction protocol must have the same interface structure.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  GuidedSectionExtraction.h

+

+  @par Revision Reference:

+  This protocol is defined in Firmware Volume Specification.

+  Version 0.9

+

+**/

+

+#ifndef __GUIDED_SECTION_EXTRACTION_PROTOCOL_H__

+#define __GUIDED_SECTION_EXTRACTION_PROTOCOL_H__

+

+

+//

+// Protocol GUID definition. Each GUIDed section extraction protocol has the

+// same interface but with different GUID. All the GUIDs is defined here.

+// May add multiple GUIDs here.

+//

+#define EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID \

+  { \

+    0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL;

+

+//

+// Protocol member functions

+//

+/**

+  Processes the input section and returns the data contained therein along 

+  with the authentication status.

+

+  @param  This                  Indicates the EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.  

+  @param  InputSection          Buffer containing the input GUIDed section to be processed.  

+  @param  OutputBuffer          *OutputBuffer is allocated from boot services pool memory 

+                                and contains the new section stream.  

+  @param  OutputSize            A pointer to a caller-allocated UINTN in which the size 

+                                of *OutputBuffer allocation is stored.   

+  @param  AuthenticationStatus  A pointer to a caller-allocated UINT32 that 

+                                indicates the authentication status of the output buffer.

+                                

+  @retval EFI_SUCCESS           The InputSection was successfully processed and the 

+                                section contents were returned.

+  @retval EFI_OUT_OF_RESOURCES  The system has insufficient resources to 

+                                process the request.

+  @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match 

+                                this instance of the GUIDed Section Extraction Protocol.

+

+**/

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXTRACT_GUIDED_SECTION) (

+  IN  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL          *This,

+  IN  VOID                                            *InputSection,

+  OUT VOID                                            **OutputBuffer,

+  OUT UINTN                                           *OutputSize,

+  OUT UINT32                                          *AuthenticationStatus

+  );

+

+//

+// Protocol definition

+//

+/**

+  @par Protocol Description:

+  If a GUID-defined section is encountered when doing section extraction, 

+  the section extraction driver calls the appropriate instance of the GUIDed 

+  Section Extraction Protocol to extract the section stream contained therein.

+

+  @param ExtractSection

+  Takes the GUIDed section as input and produces the section stream data. 

+

+**/

+struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL {

+  EFI_EXTRACT_GUIDED_SECTION  ExtractSection;

+};

+

+//

+// may add other GUID here

+//

+extern EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Hash.h b/edk2/MdePkg/Include/Protocol/Hash.h
new file mode 100644
index 0000000..7007c78
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Hash.h
@@ -0,0 +1,149 @@
+/** @file

+  EFI_HASH_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0.

+  EFI_HASH_PROTOCOL as defined in UEFI 2.0.

+  The EFI Hash Service Binding Protocol is used to locate hashing services support 

+  provided by a driver and create and destroy instances of the EFI Hash Protocol 

+  so that a multiple drivers can use the underlying hashing services.

+  The EFI Service Binding Protocol defines the generic Service Binding Protocol functions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Hash.h

+

+**/

+

+#ifndef __EFI_HASH_PROTOCOL_H__

+#define __EFI_HASH_PROTOCOL_H__

+

+#define EFI_HASH_SERVICE_BINDING_PROTOCOL \

+  { \

+    0x42881c98, 0xa4f3, 0x44b0, {0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd } \

+  }

+  

+#define EFI_HASH_PROTOCOL_GUID \

+  { \

+    0xc5184932, 0xdba5, 0x46db, {0xa5, 0xba, 0xcc, 0x0b, 0xda, 0x9c, 0x14, 0x35 } \

+  }

+

+#define EFI_HASH_ALGORITHM_SHA1_GUID \

+  { \

+    0x2ae9d80f, 0x3fb2, 0x4095, {0xb7, 0xb1, 0xe9, 0x31, 0x57, 0xb9, 0x46, 0xb6 } \

+  }

+

+#define EFI_HASH_ALGORITHM_SHA224_GUID \

+  { \

+    0x8df01a06, 0x9bd5, 0x4bf7, {0xb0, 0x21, 0xdb, 0x4f, 0xd9, 0xcc, 0xf4, 0x5b } \

+  } 

+

+#define EFI_HASH_ALGORITHM_SHA256_GUID \

+  { \

+    0x51aa59de, 0xfdf2, 0x4ea3, {0xbc, 0x63, 0x87, 0x5f, 0xb7, 0x84, 0x2e, 0xe9 } \

+  } 

+

+#define EFI_HASH_ALGORITHM_SHA384_GUID \

+  { \

+    0xefa96432, 0xde33, 0x4dd2, {0xae, 0xe6, 0x32, 0x8c, 0x33, 0xdf, 0x77, 0x7a } \

+  } 

+

+#define EFI_HASH_ALGORITHM_SHA512_GUID \

+  { \

+    0xcaa4381e, 0x750c, 0x4770, {0xb8, 0x70, 0x7a, 0x23, 0xb4, 0xe4, 0x21, 0x30 } \

+  }

+

+#define EFI_HASH_ALGORTIHM_MD5_GUID \

+  { \

+    0xaf7c79c, 0x65b5, 0x4319, {0xb0, 0xae, 0x44, 0xec, 0x48, 0x4e, 0x4a, 0xd7 } \

+  }

+

+typedef struct _EFI_HASH_PROTOCOL EFI_HASH_PROTOCOL;

+

+typedef UINT8  EFI_MD5_HASH[16];

+typedef UINT8  EFI_SHA1_HASH[20];

+typedef UINT8  EFI_SHA224_HASH[28];

+typedef UINT8  EFI_SHA256_HASH[32];

+typedef UINT8  EFI_SHA384_HASH[48];

+typedef UINT8  EFI_SHA512_HASH[64];

+

+typedef union {

+  EFI_MD5_HASH     *Md5Hash;

+  EFI_SHA1_HASH    *Sha1Hash;

+  EFI_SHA224_HASH  *Sha224Hash;

+  EFI_SHA256_HASH  *Sha256Hash;

+  EFI_SHA384_HASH  *Sha384Hash;

+  EFI_SHA512_HASH  *Sha512Hash;

+} EFI_HASH_OUTPUT;

+

+/**

+  Returns the size of the hash which results from a specific algorithm.

+

+  @param  This                  Points to this instance of EFI_HASH_PROTOCOL.

+  @param  HashAlgorithm         Points to the EFI_GUID which identifies the algorithm to use.

+  @param  HashSize              Holds the returned size of the algorithm¡¯s hash.

+

+  @retval EFI_SUCCESS           Hash size returned successfully.

+  @retval EFI_INVALID_PARAMETER HashSize is NULL

+  @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported 

+                                by this driver.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HASH_GET_HASH_SIZE) (

+  IN  CONST EFI_HASH_PROTOCOL     *This,

+  IN  CONST EFI_GUID              *HashAlgorithm,

+  OUT UINTN                       *HashSize

+  )

+;      

+

+/**

+  Returns the size of the hash which results from a specific algorithm.

+

+  @param  This          Points to this instance of EFI_HASH_PROTOCOL.

+  @param  HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.

+  @param  Extend        Specifies whether to create a new hash (FALSE) or extend the specified

+                        existing hash (TRUE).

+  @param  Message       Points to the start of the message.

+  @param  MessageSize   The size of Message, in bytes.

+  @param  Hash          On input, if Extend is TRUE, then this holds the hash to extend. On

+                        output, holds the resulting hash computed from the message.

+

+  @retval EFI_SUCCESS           Hash returned successfully.

+  @retval EFI_INVALID_PARAMETER Message or Hash is NULL

+  @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this

+                                 driver. Or extend is TRUE and the algorithm doesn¡¯t support extending the hash.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HASH_HASH) (

+  IN CONST EFI_HASH_PROTOCOL      *This,

+  IN CONST EFI_GUID               *HashAlgorithm,

+  IN BOOLEAN                      Extend,

+  IN CONST UINT8                  *Message,

+  IN UINT64                       MessageSize,

+  IN OUT EFI_HASH_OUTPUT          *Hash

+  )

+;    

+

+struct _EFI_HASH_PROTOCOL {

+  EFI_HASH_GET_HASH_SIZE          GetHashSize;

+  EFI_HASH_HASH                   Hash;

+};

+

+extern EFI_GUID gEfiHashServiceBindingProtocolGuid;

+extern EFI_GUID gEfiHashProtocolGuid;

+extern EFI_GUID gEfiHashAlgorithmSha1Guid;

+extern EFI_GUID gEfiHashAlgorithmSha224Guid;

+extern EFI_GUID gEfiHashAlgorithmSha256Guid;

+extern EFI_GUID gEfiHashAlgorithmSha384Guid;

+extern EFI_GUID gEfiHashAlgorithmSha512Guid;

+extern EFI_GUID gEfiHashAlgorithmMD5Guid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Hii.h b/edk2/MdePkg/Include/Protocol/Hii.h
new file mode 100644
index 0000000..ceeba1c
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Hii.h
@@ -0,0 +1,1024 @@
+/** @file

+  This file defines the Human Interface Infrastructure protocol which will 

+  be used by resources which want to publish IFR/Font/String data and have it 

+  collected by the Configuration engine.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Hii.h

+

+  @par Revision Reference:

+  This protocol is defined in HII spec 0.92.

+

+**/

+

+#ifndef __HII_H__

+#define __HII_H__

+

+

+#define EFI_HII_PROTOCOL_GUID \

+  { \

+    0xea816d2c, 0xcee5, 0x4f02, {0x99, 0xb5, 0xd3, 0x90, 0x5c, 0xbb, 0xd0, 0x77 } \

+  }

+

+// BugBug:

+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+// If UGA goes away we need to put this some place. I'm not sure where?

+//

+//typedef struct {

+//  UINT8 Blue;

+//  UINT8 Green;

+//  UINT8 Red;

+//  UINT8 Reserved;

+//} EFI_UGA_PIXEL;

+

+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+//

+

+typedef struct _EFI_HII_PROTOCOL  EFI_HII_PROTOCOL;

+

+//

+// Global definition

+//

+#define NARROW_CHAR         0xFFF0

+#define WIDE_CHAR           0xFFF1

+#define NON_BREAKING_CHAR   0xFFF2

+#define GLYPH_WIDTH         8

+#define GLYPH_HEIGHT        19

+

+#define EFI_HII_FONT        1

+#define EFI_HII_STRING      2

+#define EFI_HII_IFR         3

+#define EFI_HII_KEYBOARD    4

+#define EFI_HII_HANDLES     5

+#define EFI_HII_VARIABLE    6

+#define EFI_HII_DEVICE_PATH 7

+

+

+// References to string tokens must use this macro to enable scanning for

+// token usages.

+//

+#define STRING_TOKEN(t) t

+

+//

+// The following types are currently defined:

+//

+typedef UINT16  EFI_FORM_ID;

+typedef UINT16  EFI_FORM_LABEL;

+

+#pragma pack(1)

+

+typedef struct {

+  UINT32  Length;

+  UINT16  Type;

+} EFI_HII_PACK_HEADER;

+

+//

+// A form list consists of a large variety of structure

+// possibilities so to represent the binary blob of data

+// associated with a package of forms, we will assume a

+// pointer to a self-describing data buffer.

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+} EFI_HII_IFR_PACK;

+

+typedef struct {

+  EFI_HII_PACK_HEADER Header;           // Must be filled in

+  EFI_HANDLE          ImageHandle;      // Must be filled in

+  EFI_HANDLE          DeviceHandle;     // Optional

+  EFI_HANDLE          ControllerHandle; // Optional

+  EFI_HANDLE          CallbackHandle;   // Optional

+  EFI_HANDLE          COBExportHandle;  // Optional

+} EFI_HII_HANDLE_PACK;

+

+//

+// ********************************************************

+// EFI_VARIABLE_CONTENTS

+// ********************************************************

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+  EFI_GUID            VariableGuid;

+  UINT32              VariableNameLength;

+  UINT16              VariableId;

+  //

+  //  CHAR16                VariableName[]; //Null-terminated

+  //

+} EFI_HII_VARIABLE_PACK;

+

+//

+// ********************************************************

+// EFI_DEVICE_PATH_PACK

+// ********************************************************

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+  //

+  //  EFI_DEVICE_PATH       DevicePath[];

+  //

+} EFI_HII_DEVICE_PATH_PACK;

+

+//

+// ********************************************************

+// EFI_HII_DATA_TABLE

+// ********************************************************

+//

+typedef struct {

+  EFI_HII_HANDLE  HiiHandle;

+  EFI_GUID        PackageGuid;

+  UINT32          DataTableSize;

+  UINT32          IfrDataOffset;

+  UINT32          StringDataOffset;

+  UINT32          VariableDataOffset;

+  UINT32          DevicePathOffset;

+  UINT32          NumberOfVariableData;

+  UINT32          NumberOfLanguages;

+  //

+  // EFI_HII_DEVICE_PATH_PACK DevicePath[];

+  // EFI_HII_VARIABLE_PACK VariableData[];

+  // EFI_HII_IFR_PACK IfrData;

+  // EFI_HII_STRING_PACK StringData[];

+  //

+} EFI_HII_DATA_TABLE;

+

+//

+// ********************************************************

+// EFI_HII_EXPORT_TABLE

+// ********************************************************

+//

+typedef struct {

+  UINT32    NumberOfHiiDataTables;

+  EFI_GUID  Revision;

+  //

+  // EFI_HII_DATA_TABLE HiiDataTable[];

+  //

+} EFI_HII_EXPORT_TABLE;

+

+typedef struct {

+  BOOLEAN               FormSetUpdate;      // If TRUE, next variable is significant

+  EFI_PHYSICAL_ADDRESS  FormCallbackHandle; // If not 0, will update Formset with this info

+  BOOLEAN               FormUpdate;         // If TRUE, next variable is significant

+  UINT16                FormValue;          // specify which form is to be updated if FormUpdate value is TRUE.

+  STRING_REF            FormTitle;          // If not 0, will update Form with this info

+  UINT16                DataCount;          // The number of Data entries in this structure

+  UINT8                 *Data;              // An array of 1+ op-codes, specified by DataCount

+} EFI_HII_UPDATE_DATA;

+

+//

+// String attributes

+//

+#define LANG_RIGHT_TO_LEFT  0x00000001

+

+//

+// A string package is used to localize strings to a particular

+// language.  The package is associated with a particular driver

+// or set of drivers.  Tools are used to associate tokens with

+// string references in forms and in programs.  These tokens are

+// language agnostic.  When paired with a language pack (directly

+// or indirectly), the string token resolves into an actual

+// UNICODE string.  The NumStringPointers determines how many

+// StringPointers (offset values) there are as well as the total

+// number of Strings that are defined.

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+  RELOFST             LanguageNameString;

+  RELOFST             PrintableLanguageName;

+  UINT32              NumStringPointers;

+  UINT32              Attributes;

+  //

+  //  RELOFST               StringPointers[];

+  //  EFI_STRING            Strings[];

+  //

+} EFI_HII_STRING_PACK;

+

+//

+// Glyph Attributes

+//

+#define EFI_GLYPH_NON_SPACING   1

+#define EFI_GLYPH_WIDE          2

+

+typedef struct {

+  CHAR16  UnicodeWeight;

+  UINT8   Attributes;

+  UINT8   GlyphCol1[GLYPH_HEIGHT];

+} EFI_NARROW_GLYPH;

+

+typedef struct {

+  CHAR16  UnicodeWeight;

+  UINT8   Attributes;

+  UINT8   GlyphCol1[GLYPH_HEIGHT];

+  UINT8   GlyphCol2[GLYPH_HEIGHT];

+  UINT8   Pad[3];

+} EFI_WIDE_GLYPH;

+

+//

+// A font list consists of a font header followed by a series

+// of glyph structures.  Note that fonts are not language specific.

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+  UINT16              NumberOfNarrowGlyphs;

+  UINT16              NumberOfWideGlyphs;

+} EFI_HII_FONT_PACK;

+

+//

+// The IfrData in the EFI_HII_IFR_PACK structure definition

+// is variable length, and not really part of the header. To

+// simplify from code the size of the header, define an

+// identical structure that does not include the IfrData field.

+// Then use sizeof() this new structure to determine the

+// actual size of the header.

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+} EFI_HII_IFR_PACK_HEADER;

+

+//

+// pedef EFI_HII_PACK_HEADER EFI_HII_IFR_PACK_HEADER;

+//

+typedef enum {

+  EfiKeyLCtrl,

+  EfiKeyA0,

+  EfiKeyLAlt,

+  EfiKeySpaceBar,

+  EfiKeyA2,

+  EfiKeyA3,

+  EfiKeyA4,

+  EfiKeyRCtrl,

+  EfiKeyLeftArrow,

+  EfiKeyDownArrow,

+  EfiKeyRightArrow,

+  EfiKeyZero,

+  EfiKeyPeriod,

+  EfiKeyEnter,

+  EfiKeyLShift,

+  EfiKeyB0,

+  EfiKeyB1,

+  EfiKeyB2,

+  EfiKeyB3,

+  EfiKeyB4,

+  EfiKeyB5,

+  EfiKeyB6,

+  EfiKeyB7,

+  EfiKeyB8,

+  EfiKeyB9,

+  EfiKeyB10,

+  EfiKeyRshift,

+  EfiKeyUpArrow,

+  EfiKeyOne,

+  EfiKeyTwo,

+  EfiKeyThree,

+  EfiKeyCapsLock,

+  EfiKeyC1,

+  EfiKeyC2,

+  EfiKeyC3,

+  EfiKeyC4,

+  EfiKeyC5,

+  EfiKeyC6,

+  EfiKeyC7,

+  EfiKeyC8,

+  EfiKeyC9,

+  EfiKeyC10,

+  EfiKeyC11,

+  EfiKeyC12,

+  EfiKeyFour,

+  EfiKeyFive,

+  EfiKeySix,

+  EfiKeyPlus,

+  EfiKeyTab,

+  EfiKeyD1,

+  EfiKeyD2,

+  EfiKeyD3,

+  EfiKeyD4,

+  EfiKeyD5,

+  EfiKeyD6,

+  EfiKeyD7,

+  EfiKeyD8,

+  EfiKeyD9,

+  EfiKeyD10,

+  EfiKeyD11,

+  EfiKeyD12,

+  EfiKeyD13,

+  EfiKeyDel,

+  EfiKeyEnd,

+  EfiKeyPgDn,

+  EfiKeySeven,

+  EfiKeyEight,

+  EfiKeyNine,

+  EfiKeyE0,

+  EfiKeyE1,

+  EfiKeyE2,

+  EfiKeyE3,

+  EfiKeyE4,

+  EfiKeyE5,

+  EfiKeyE6,

+  EfiKeyE7,

+  EfiKeyE8,

+  EfiKeyE9,

+  EfiKeyE10,

+  EfiKeyE11,

+  EfiKeyE12,

+  EfiKeyBackSpace,

+  EfiKeyIns,

+  EfiKeyHome,

+  EfiKeyPgUp,

+  EfiKeyNLck,

+  EfiKeySlash,

+  EfiKeyAsterisk,

+  EfiKeyMinus,

+  EfiKeyEsc,

+  EfiKeyF1,

+  EfiKeyF2,

+  EfiKeyF3,

+  EfiKeyF4,

+  EfiKeyF5,

+  EfiKeyF6,

+  EfiKeyF7,

+  EfiKeyF8,

+  EfiKeyF9,

+  EfiKeyF10,

+  EfiKeyF11,

+  EfiKeyF12,

+  EfiKeyPrint,

+  EfiKeySLck,

+  EfiKeyPause

+} EFI_KEY;

+

+typedef struct {

+  EFI_KEY Key;

+  CHAR16  Unicode;

+  CHAR16  ShiftedUnicode;

+  CHAR16  AltGrUnicode;

+  CHAR16  ShiftedAltGrUnicode;

+  UINT16  Modifier;

+} EFI_KEY_DESCRIPTOR;

+

+//

+// This structure allows a sparse set of keys to be redefined

+// or a complete redefinition of the keyboard layout.  Most

+// keyboards have a lot of commonality in their layouts, therefore

+// only defining those keys that need to change from the default

+// minimizes the passed in information.

+//

+// Additionally, when an update occurs, the active keyboard layout

+// will be switched to the newly updated keyboard layout.  This

+// allows for situations that when a keyboard layout driver is

+// loaded as part of system initialization, the system will default

+// the keyboard behavior to the new layout.

+//

+// Each call to update the keyboard mapping should contain the

+// complete set of key descriptors to be updated, since every

+// call to the HII which contains an EFI_HII_KEYBOARD_PACK will

+// wipe the previous set of overrides.  A call to

+//

+typedef struct {

+  EFI_HII_PACK_HEADER Header;

+  EFI_KEY_DESCRIPTOR  *Descriptor;

+  UINT8               DescriptorCount;

+} EFI_HII_KEYBOARD_PACK;

+

+//

+// The EFI_HII_PACKAGES can contain different types of packages just

+// after the structure as inline data.

+//

+typedef struct {

+  UINTN     NumberOfPackages;

+  EFI_GUID  *GuidId;

+  //

+  // EFI_HII_HANDLE_PACK    *HandlePack;        // Only one pack.

+  // EFI_HII_IFR_PACK       *IfrPack;           // Only one pack.

+  // EFI_HII_FONT_PACK      *FontPack[];        // Multiple packs ok

+  // EFI_HII_STRING_PACK    *StringPack[];      // Multiple packs ok

+  // EFI_HII_KEYBOARD_PACK  *KeyboardPack[];    // Multiple packs ok

+  //

+} EFI_HII_PACKAGES;

+

+typedef struct _EFI_HII_VARIABLE_PACK_LIST {

+  struct _EFI_HII_VARIABLE_PACK_LIST   *NextVariablePack;

+  EFI_HII_VARIABLE_PACK                *VariablePack;

+} EFI_HII_VARIABLE_PACK_LIST;

+

+#pragma pack()

+

+/**

+  Registers the various packs that are passed in via the Packages parameter. 

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Packages A pointer to an EFI_HII_PACKAGES package instance.

+  

+  @param  Handle A pointer to the EFI_HII_HANDLE instance.

+

+  @retval EFI_SUCCESS Data was extracted from Packages, the database 

+  was updated with the data, and Handle returned successfully.

+  

+  @retval EFI_INVALID_PARAMETER The content of Packages  was invalid. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_NEW_PACK) (

+  IN  EFI_HII_PROTOCOL    *This,

+  IN  EFI_HII_PACKAGES    *Packages,

+  OUT EFI_HII_HANDLE      *Handle

+  );

+

+/**

+  Removes a package from the HII database. 

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The handle that was registered to the data that is requested 

+  for removal. 

+

+  @retval EFI_SUCCESS The data associated with the Handle was removed 

+  from the HII database.

+  

+  @retval EFI_INVALID_PARAMETER The Handle was not valid. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_REMOVE_PACK) (

+  IN EFI_HII_PROTOCOL    *This,

+  IN EFI_HII_HANDLE      Handle

+  );

+

+/**

+  Determines the handles that are currently active in the database.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  HandleBufferLength On input, a pointer to the length of the handle 

+  buffer. On output, the length of the handle buffer that is required 

+  for the handles found.

+  

+  @param  Handle An array of EFI_HII_HANDLE instances returned.

+

+  @retval EFI_SUCCESS Handle was updated successfully.

+  

+  @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates 

+  that Handle is too small to support the number of handles.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_FIND_HANDLES) (

+  IN     EFI_HII_PROTOCOL *This,

+  IN OUT UINT16           *HandleBufferLength,

+  OUT    EFI_HII_HANDLE   *Handle

+  );

+

+/**

+  Exports the contents of the database into a buffer.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle An EFI_HII_HANDLE that corresponds to the desired 

+  handle to export. If the value is 0, the entire database will be exported.

+  In either case, the data will be exported in a format described by the 

+  structure definition of EFI_HII_EXPORT_TABLE.

+  

+  @param  BufferSize

+  On input, a pointer to the length of the buffer. On output, the length 

+  of the buffer that is required for the export data.

+  

+  @param  Buffer A pointer to a buffer that will contain the results of the export function.

+

+  @retval EFI_SUCCESS The buffer was successfully filled with BufferSize amount of data.

+  

+  @retval EFI_BUFFER_TOO_SMALL The value in BufferSize was too small to contain the export data.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_EXPORT) (

+  IN     EFI_HII_PROTOCOL *This,

+  IN     EFI_HII_HANDLE   Handle,

+  IN OUT UINTN            *BufferSize,

+  OUT    VOID             *Buffer

+  );

+

+/**

+  Remove any new strings that were added after the initial string export 

+  for this handle.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The handle on which the string resides.

+

+  @retval EFI_SUCCESS Remove strings from the handle successfully.

+  

+  @retval EFI_INVALID_PARAMETER The Handle was unknown.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_RESET_STRINGS) (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     EFI_HII_HANDLE     Handle

+  );

+

+/**

+  Tests if all of the characters in a string have corresponding font characters.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  StringToTest A pointer to a Unicode string.

+  

+  @param  FirstMissing A pointer to an index into the string. On input, 

+  the index of the first character in the StringToTest to examine. On exit, 

+  the index of the first character encountered for which a glyph is unavailable.

+  If all glyphs in the string are available, the index is the index of the 

+  terminator of the string.

+  

+  @param  GlyphBufferSize A pointer to a value. On output, if the function 

+  returns EFI_SUCCESS, it contains the amount of memory that is required to 

+  store the string¡¯s glyph equivalent.

+

+  @retval EFI_SUCCESS All glyphs are available. Note that an empty string 

+  always returns this value.

+  

+  @retval EFI_NOT_FOUND A glyph was not found for a character.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_TEST_STRING) (

+  IN     EFI_HII_PROTOCOL  *This,

+  IN     CHAR16            *StringToTest,

+  IN OUT UINT32            *FirstMissing,

+  OUT    UINT32            *GlyphBufferSize

+  );

+

+/**

+  Translates a Unicode character into the corresponding font glyph.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Source A pointer to a Unicode string.

+  

+  @param  Index On input, the offset into the string from which to fetch 

+  the character.On successful completion, the index is updated to the first 

+  character past the character(s) making up the just extracted glyph. 

+  

+  @param  GlyphBuffer Pointer to an array where the glyphs corresponding 

+  to the characters in the source may be stored. GlyphBuffer is assumed 

+  to be wide enough to accept a wide glyph character.

+  

+  @param  BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by 

+  this value is filled with the length of the glyph in pixels. It is unchanged 

+  if the call was unsuccessful.

+  

+  @param  InternalStatus The cell pointed to by this parameter must be 

+  initialized to zero prior to invoking the call the first time for any string.

+

+  @retval EFI_SUCCESS It worked.

+  

+  @retval EFI_NOT_FOUND A glyph for a character was not found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_GLYPH) (

+  IN     EFI_HII_PROTOCOL  *This,

+  IN     CHAR16            *Source,

+  IN OUT UINT16            *Index,

+  OUT    UINT8             **GlyphBuffer,

+  OUT    UINT16            *BitWidth,

+  IN OUT UINT32            *InternalStatus

+  );

+

+/**

+  Translates a glyph into the format required for input to the Universal 

+  Graphics Adapter (UGA) Block Transfer (BLT) routines.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  GlyphBuffer A pointer to the buffer that contains glyph data.

+  

+  @param  Foreground The foreground setting requested to be used for the 

+  generated BltBuffer data. 

+  

+  @param  Background The background setting requested to be used for the 

+  generated BltBuffer data.

+  

+  @param  Count The entry in the BltBuffer upon which to act.

+  

+  @param  Width The width in bits of the glyph being converted.

+  

+  @param  Height The height in bits of the glyph being converted

+  

+  @param  BltBuffer A pointer to the buffer that contains the data that is 

+  ready to be used by the UGA BLT routines. 

+

+  @retval EFI_SUCCESS It worked.

+  

+  @retval EFI_NOT_FOUND A glyph for a character was not found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GLYPH_TO_BLT) (

+  IN     EFI_HII_PROTOCOL   *This,

+  IN     UINT8              *GlyphBuffer,

+  IN     EFI_UGA_PIXEL      Foreground,

+  IN     EFI_UGA_PIXEL      Background,

+  IN     UINTN              Count,

+  IN     UINTN              Width,

+  IN     UINTN              Height,

+  IN OUT EFI_UGA_PIXEL      *BltBuffer

+  );

+

+/**

+  Allows a new string to be added to an already existing string package.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Pointer to a NULL-terminated string containing a single ISO 639-2 

+  language identifier, indicating the language in which the string is translated. 

+  

+  @param  Handle The handle of the language pack to which the string is to be added.

+  

+  @param  Reference The identifier of the string to be added. If the reference 

+  value is zero, then the string will be assigned a new identifier on that 

+  handle for the language specified. Otherwise, the string will be updated 

+  with the NewString Value. 

+  

+  @param  NewString The string to be added.

+

+  @retval EFI_SUCCESS The string was effectively registered.

+  

+  @retval EFI_INVALID_PARAMETER The Handle was unknown.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_NEW_STRING) (

+  IN     EFI_HII_PROTOCOL      *This,

+  IN     CHAR16                *Language,

+  IN     EFI_HII_HANDLE        Handle,

+  IN OUT STRING_REF            *Reference,

+  IN     CHAR16                *NewString

+  );

+

+/**

+  Allows a program to determine the primary languages that are supported 

+  on a given handle.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The handle on which the strings reside.

+  

+  @param  LanguageString A string allocated by GetPrimaryLanguages() that 

+  contains a list of all primary languages registered on the handle. 

+

+  @retval EFI_SUCCESS LanguageString was correctly returned.

+  

+  @retval EFI_INVALID_PARAMETER The Handle was unknown.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_PRI_LANGUAGES) (

+  IN  EFI_HII_PROTOCOL    *This,

+  IN  EFI_HII_HANDLE      Handle,

+  OUT EFI_STRING          *LanguageString

+  );

+

+/**

+  Allows a program to determine which secondary languages are supported 

+  on a given handle for a given primary language.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The handle on which the strings reside.

+  

+  @param  PrimaryLanguage Pointer to a NULL-terminated string containing a single 

+  ISO 639-2 language identifier, indicating the primary language.

+  

+  @param  LanguageString A string allocated by GetSecondaryLanguages() 

+  containing a list of all secondary languages registered on the handle.

+

+  @retval EFI_SUCCESS LanguageString was correctly returned.

+  

+  @retval EFI_INVALID_PARAMETER The Handle was unknown.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_SEC_LANGUAGES) (

+  IN  EFI_HII_PROTOCOL    *This,

+  IN  EFI_HII_HANDLE      Handle,

+  IN  CHAR16              *PrimaryLanguage,

+  OUT EFI_STRING          *LanguageString

+  );

+

+/**

+  Extracts a string from a package already registered with the EFI HII database.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The handle on which the string resides.

+  

+  @param  Token The string token assigned to the string.

+  

+  @param  Raw If TRUE, the string is returned unedited in the internal 

+  storage format described above. If false, the string returned is edited 

+  by replacing <cr> with <space> and by removing special characters such 

+  as the <wide> prefix.

+  

+  @param  LanguageString Pointer to a NULL-terminated string containing a 

+  single ISO 639-2 language identifier, indicating the language to print. 

+  If the LanguageString is empty (starts with a NULL), the default system 

+  language will be used to determine the language.

+  

+  @param  BufferLength Length of the StringBuffer.

+  

+  @param  StringBuffer The buffer designed to receive the characters in the string.

+

+  @retval EFI_SUCCESS StringBuffer is filled with a NULL-terminated string.

+  

+  @retval EFI_INVALID_PARAMETER The handle or string token is unknown.

+  

+  @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to 

+  allow the entire string to be stored. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_STRING) (

+  IN     EFI_HII_PROTOCOL  *This,

+  IN     EFI_HII_HANDLE    Handle,

+  IN     STRING_REF        Token,

+  IN     BOOLEAN           Raw,

+  IN     CHAR16            *LanguageString,

+  IN OUT UINTN             *BufferLength,

+  OUT    EFI_STRING        StringBuffer

+  );

+

+/**

+  Allows a program to extract a part of a string of not more than a given width. 

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The handle on which the string resides.

+  

+  @param  Token The string token assigned to the string. 

+  

+  @param  Index On input, the offset into the string where the line is to start.

+  On output, the index is updated to point to beyond the last character returned 

+  in the call.

+  

+  @param  LineWidth The maximum width of the line in units of narrow glyphs.

+  

+  @param  LanguageString Pointer to a NULL-terminated string containing a 

+  single ISO 639-2 language identifier, indicating the language to print.

+  

+  @param  BufferLength Pointer to the length of the StringBuffer. 

+  

+  @param  StringBuffer The buffer designed to receive the characters in the string. 

+

+  @retval EFI_SUCCESS StringBuffer filled with characters that will fit on the line.

+  

+  @retval EFI_NOT_FOUND The font glyph for at least one of the characters in 

+  the string is not in the font database.

+  

+  @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough 

+  to allow the entire string to be stored.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_LINE) (

+  IN     EFI_HII_PROTOCOL  *This,

+  IN     EFI_HII_HANDLE    Handle,

+  IN     STRING_REF        Token,

+  IN OUT UINT16            *Index,

+  IN     UINT16            LineWidth,

+  IN     CHAR16            *LanguageString,

+  IN OUT UINT16            *BufferLength,

+  OUT    EFI_STRING        StringBuffer

+  );

+

+/**

+  Allows a program to extract a form or form package that has previously 

+  been registered with the HII database.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle Handle on which the form resides.

+  

+  @param  FormId The ID of the form to return. If the ID is zero, 

+  the entire form package is returned. 

+  

+  @param  BufferLength On input, the length of the Buffer. On output, 

+  the length of the returned buffer, 

+  

+  @param  Buffer The buffer designed to receive the form(s).

+

+  @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength 

+  was updated.

+  

+  @retval EFI_INVALID_PARAMETER The handle is unknown.

+  

+  @retval EFI_NOT_FOUND A form on the requested handle cannot be found with 

+  the requested FormId.

+  

+  @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough 

+  to allow the form to be stored. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_FORMS) (

+  IN     EFI_HII_PROTOCOL  *This,

+  IN     EFI_HII_HANDLE    Handle,

+  IN     EFI_FORM_ID       FormId,

+  IN OUT UINTN             *BufferLength,

+  OUT    UINT8             *Buffer

+  );

+

+/**

+  Extracts the defaults that are associated with a given handle in the HII database.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle The HII handle from which will have default data retrieved.

+  

+  @param  DefaultMask The mask used to specify some type of default override when extracting 

+  the default image data.

+  

+  @param  VariablePackList A indirect pointer to the first entry of a link list with 

+  type EFI_HII_VARIABLE_PACK_LIST. 

+

+  @retval EFI_SUCCESS The VariablePackList was populated with the appropriate 

+  default setting data.

+  

+  @retval EFI_NOT_FOUND The IFR does not have any explicit or default map(s).

+  

+  @retval EFI_INVALID_PARAMETER The HII database entry associated with Handle 

+  contain invalid data.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_DEFAULT_IMAGE) (

+  IN     EFI_HII_PROTOCOL           *This,

+  IN     EFI_HII_HANDLE             Handle,

+  IN     UINTN                      DefaultMask,

+  OUT    EFI_HII_VARIABLE_PACK_LIST **VariablePackList

+  );

+

+/**

+  Allows the caller to update a form or form package that has previously been 

+  registered with the EFI HII database.

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  Handle Handle of the package where the form to be updated resides.

+  

+  @param  Label The label inside the form package where the update is to take place.

+  

+  @param  AddData If TRUE, adding data at a given Label; otherwise, 

+  if FALSE, removing data at a given Label.

+  

+  @param  Data The buffer containing the new tags to insert after the Label

+

+  @retval EFI_SUCCESS The form was updated with the new tags.

+  

+  @retval EFI_INVALID_PARAMETER The buffer for the buffer length does not 

+  contain an integral number of tags.

+  

+  @retval EFI_NOT_FOUND The Handle, Label, or FormId was not found. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_UPDATE_FORM) (

+  IN EFI_HII_PROTOCOL     *This,

+  IN EFI_HII_HANDLE       Handle,

+  IN EFI_FORM_LABEL       Label,

+  IN BOOLEAN              AddData,

+  IN EFI_HII_UPDATE_DATA  *Data

+  );

+

+/**

+  Retrieves the current keyboard layout. 

+

+  @param  This A pointer to the EFI_HII_PROTOCOL instance.

+  

+  @param  DescriptorCount A pointer to the number of Descriptor entries being 

+  described in the keyboard layout being retrieved.

+  

+  @param  Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR 

+  entries. Each entry will reflect the definition of a specific physical key.

+

+  @retval EFI_SUCCESS The keyboard layout was retrieved successfully.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT) (

+  IN     EFI_HII_PROTOCOL    *This,

+  OUT    UINT16              *DescriptorCount,

+  OUT    EFI_KEY_DESCRIPTOR  *Descriptor

+  );

+

+/**

+  @par Protocol Description:

+  The HII Protocol manages the HII database, which is a repository for data 

+  having to do with fonts, strings, forms, keyboards, and other future human 

+  interface items.

+

+  @param NewPack

+  Extracts the various packs from a package list.

+

+  @param RemovePack

+  Removes a package from the HII database.

+

+  @param FindHandles

+  Determines the handles that are currently active in the database.

+

+  @param ExportDatabase

+  Export the entire contents of the database to a buffer.

+

+  @param TestString

+  Tests if all of the characters in a string have corresponding font characters.

+

+  @param GetGlyph

+  Translates a Unicode character into the corresponding font glyph. 

+

+  @param GlyphToBlt

+  Converts a glyph value into a format that is ready for a UGA BLT command. 

+

+  @param NewString

+  Allows a new string to be added to an already existing string package.

+

+  @param GetPrimaryLanguages

+  Allows a program to determine the primary languages that are supported 

+  on a given handle. 

+

+  @param GetSecondaryLanguages

+  Allows a program to determine which secondary languages are supported 

+  on a given handle for a given primary language.

+

+  @param GetString

+  Extracts a string from a package that is already registered with the 

+  EFI HII database. 

+

+  @param ResetString

+  Remove any new strings that were added after the initial string export 

+  for this handle.

+

+  @param GetLine

+  Allows a program to extract a part of a string of not more than a given width.

+

+  @param GetForms

+  Allows a program to extract a form or form package that has been previously registered.

+

+  @param GetDefaultImage

+  Allows a program to extract the nonvolatile image that represents the default storage image. 

+

+  @param UpdateForm

+  Allows a program to update a previously registered form. 

+

+  @param GetKeyboardLayout

+  Allows a program to extract the current keyboard layout.

+

+**/

+struct _EFI_HII_PROTOCOL {

+  EFI_HII_NEW_PACK            NewPack;

+  EFI_HII_REMOVE_PACK         RemovePack;

+  EFI_HII_FIND_HANDLES        FindHandles;

+  EFI_HII_EXPORT              ExportDatabase;

+

+  EFI_HII_TEST_STRING         TestString;

+  EFI_HII_GET_GLYPH           GetGlyph;

+  EFI_HII_GLYPH_TO_BLT        GlyphToBlt;

+

+  EFI_HII_NEW_STRING          NewString;

+  EFI_HII_GET_PRI_LANGUAGES   GetPrimaryLanguages;

+  EFI_HII_GET_SEC_LANGUAGES   GetSecondaryLanguages;

+  EFI_HII_GET_STRING          GetString;

+  EFI_HII_RESET_STRINGS       ResetStrings;

+  EFI_HII_GET_LINE            GetLine;

+  EFI_HII_GET_FORMS           GetForms;

+  EFI_HII_GET_DEFAULT_IMAGE   GetDefaultImage;

+  EFI_HII_UPDATE_FORM         UpdateForm;

+

+  EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout;

+};

+

+extern EFI_GUID gEfiHiiProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/IP4.h b/edk2/MdePkg/Include/Protocol/IP4.h
new file mode 100644
index 0000000..0decc17
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/IP4.h
@@ -0,0 +1,411 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  IP4.h

+

+**/

+

+#ifndef __EFI_IP4_PROTOCOL_H__

+#define __EFI_IP4_PROTOCOL_H__

+

+#define EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0xc51711e7, 0xb4bf, 0x404a, {0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4 } \

+  }

+

+#define EFI_IP4_PROTOCOL_GUID \

+  { \

+    0x41d94cd2, 0x35b6, 0x455a, {0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } \

+  }

+

+typedef struct _EFI_IP4_PROTOCOL EFI_IP4_PROTOCOL;

+  

+typedef struct {

+  EFI_IPv4_ADDRESS        Ip4Address;

+  EFI_IPv4_ADDRESS        SubnetMask;

+} EFI_IP4_ADDRESS_PAIR; 

+

+typedef struct {

+  EFI_HANDLE              DriverHandle;

+  UINT32                  AddressCount;

+  EFI_IP4_ADDRESS_PAIR    AddressPairs[1];

+} EFI_IP4_VARIABLE_DATA;

+

+typedef struct {

+  UINT8                   DefaultProtocol;

+  BOOLEAN                 AcceptAnyProtocol;

+  BOOLEAN                 AcceptIcmpErrors;

+  BOOLEAN                 AcceptBroadcast;

+  BOOLEAN                 AcceptPromiscuous;

+  BOOLEAN                 UseDefaultAddress;

+  EFI_IPv4_ADDRESS        StationAddress;

+  EFI_IPv4_ADDRESS        SubnetMask;

+  UINT8                   TypeOfService;

+  UINT8                   TimeToLive;

+  BOOLEAN                 DoNotFragment;

+  BOOLEAN                 RawData;

+  UINT32                  ReceiveTimeout;

+  UINT32                  TransmitTimeout;

+} EFI_IP4_CONFIG_DATA;

+

+

+typedef struct {

+  EFI_IPv4_ADDRESS        SubnetAddress;

+  EFI_IPv4_ADDRESS        SubnetMask;

+  EFI_IPv4_ADDRESS        GatewayAddress;

+} EFI_IP4_ROUTE_TABLE;

+

+typedef struct {

+  UINT8                   Type;

+  UINT8                   Code;

+} EFI_IP4_ICMP_TYPE;

+

+typedef struct {

+  BOOLEAN                 IsStarted;

+  EFI_IP4_CONFIG_DATA     ConfigData;

+  BOOLEAN                 IsConfigured;

+  UINT32                  GroupCount;

+  EFI_IPv4_ADDRESS        *GroupTable;

+  UINT32                  RouteCount;

+  EFI_IP4_ROUTE_TABLE     *RouteTable;

+  UINT32                  IcmpTypeCount;

+  EFI_IP4_ICMP_TYPE       *IcmpTypeList;

+} EFI_IP4_MODE_DATA;

+

+#pragma pack(1)

+

+typedef struct {

+#ifdef EFI_NET_LITTLE_ENDIAN

+  UINT8                   HeaderLength:4;

+  UINT8                   Version:4;

+#else 

+  UINT8                   Version:4;

+  UINT8                   HeaderLength:4;

+#endif

+  UINT8                   TypeOfService;

+  UINT16                  TotalLength;

+  UINT16                  Identification;

+  UINT16                  Fragmentation;

+  UINT8                   TimeToLive;

+  UINT8                   Protocol;

+  UINT16                  Checksum;

+  EFI_IPv4_ADDRESS        SourceAddress;

+  EFI_IPv4_ADDRESS        DestinationAddress;

+} EFI_IP4_HEADER;

+#pragma pack()

+

+

+typedef struct {

+  UINT32                  FragmentLength;

+  VOID                    *FragmentBuffer;

+} EFI_IP4_FRAGMENT_DATA;

+

+

+typedef struct {

+  EFI_TIME               TimeStamp;

+  EFI_EVENT              RecycleSignal;

+  UINT32                 HeaderLength;

+  EFI_IP4_HEADER         *Header;

+  UINT32                 OptionsLength;

+  VOID                   *Options;

+  UINT32                 DataLength;

+  UINT32                 FragmentCount;

+  EFI_IP4_FRAGMENT_DATA  FragmentTable[1];

+} EFI_IP4_RECEIVE_DATA;

+

+

+typedef struct {

+  EFI_IPv4_ADDRESS       SourceAddress;

+  EFI_IPv4_ADDRESS       GatewayAddress;

+  UINT8                  Protocol;

+  UINT8                  TypeOfService;

+  UINT8                  TimeToLive;

+  BOOLEAN                DoNotFragment;

+} EFI_IP4_OVERRIDE_DATA;

+

+typedef struct {

+  EFI_IPv4_ADDRESS       DestinationAddress;

+  EFI_IP4_OVERRIDE_DATA  *OverrideData;      //OPTIONAL

+  UINT32                 OptionsLength;      //OPTIONAL

+  VOID                   *OptionsBuffer;     //OPTIONAL

+  UINT32                 TotalDataLength;

+  UINT32                 FragmentCount;

+  EFI_IP4_FRAGMENT_DATA  FragmentTable[1];

+} EFI_IP4_TRANSMIT_DATA;

+

+typedef struct {

+  EFI_EVENT                Event;

+  EFI_STATUS               Status;

+  union {

+    EFI_IP4_RECEIVE_DATA   *RxData;

+    EFI_IP4_TRANSMIT_DATA  *TxData;

+  } Packet;

+} EFI_IP4_COMPLETION_TOKEN;

+

+/**

+  Gets the current operational settings for this instance of the EFI IPv4 Protocol driver.

+

+  @param  This          Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  Ip4ModeData   Pointer to the EFI IPv4 Protocol mode data structure.

+  @param  MnpConfigData Pointer to the managed network configuration data structure.

+  @param  SnpData       Pointer to the simple network mode data structure.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_OUT_OF_RESOURCES  The required mode data could not be allocated.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IP4_GET_MODE_DATA) (

+  IN  EFI_IP4_PROTOCOL                *This,

+  OUT EFI_IP4_MODE_DATA               *Ip4ModeData     OPTIONAL,

+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData   OPTIONAL,

+  OUT EFI_SIMPLE_NETWORK_MODE         *SnpModeData     OPTIONAL

+  )

+;  

+

+/**

+  Assigns an IPv4 address and subnet mask to this EFI IPv4 Protocol driver instance.

+

+  @param  This         Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  IpConfigData Pointer to the EFI IPv4 Protocol configuration data structure.

+

+  @retval EFI_SUCCESS           The driver instance was successfully opened.

+  @retval EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+  @retval EFI_UNSUPPORTED       One or more of the following conditions is TRUE:

+                                A configuration protocol (DHCP, BOOTP, RARP, etc.) could

+                                not be located when clients choose to use the default IPv4

+                                address. This EFI IPv4 Protocol implementation does not

+                                support this requested filter or timeout setting.

+  @retval EFI_OUT_OF_RESOURCES  The EFI IPv4 Protocol driver instance data could not be allocated.

+  @retval EFI_ALREADY_STARTED   The interface is already open and must be stopped before the

+                                IPv4 address or subnet mask can be changed. The interface must

+                                also be stopped when switching to/from raw packet mode.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred. The EFI IPv4

+                                 Protocol driver instance is not opened.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IP4_CONFIGURE) (

+  IN EFI_IP4_PROTOCOL    *This,

+  IN EFI_IP4_CONFIG_DATA *IpConfigData     OPTIONAL

+  )

+;  

+

+/**

+  Joins and leaves multicast groups.

+

+  @param  This                  Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  JoinFlag              Set to TRUE to join the multicast group session and FALSE to leave.

+  @param  GroupAddress          Pointer to the IPv4 multicast address.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER One or more of the following is TRUE:

+                                - This is NULL.

+                                - JoinFlag is TRUE and GroupAddress is NULL.

+                                - GroupAddress is not NULL and *GroupAddress is

+                                not a multicast IPv4 address.

+  @retval EFI_NOT_STARTED       This instance has not been started.

+  @retval EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_OUT_OF_RESOURCES  System resources could not be allocated.

+  @retval EFI_UNSUPPORTED       This EFI IPv4 Protocol implementation does not support multicast groups.

+  @retval EFI_ALREADY_STARTED   The group address is already in the group table (when

+                                JoinFlag is TRUE).

+  @retval EFI_NOT_FOUND         The group address is not in the group table (when JoinFlag is FALSE).

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IP4_GROUPS) (

+  IN EFI_IP4_PROTOCOL    *This,

+  IN BOOLEAN             JoinFlag,

+  IN EFI_IPv4_ADDRESS    *GroupAddress  OPTIONAL

+  )

+;    

+

+/**

+  Adds and deletes routing table entries.

+

+  @param  This                   Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  DeleteRoute            Set to TRUE to delete this route from the routing table. Set to

+                                 FALSE to add this route to the routing table. SubnetAddress

+                                 and SubnetMask are used as the key to each route entry.

+  @param  SubnetAddress          The address of the subnet that needs to be routed.

+  @param  SubnetMask             The subnet mask of SubnetAddress.

+  @param  GatewayAddress         The unicast gateway IPv4 address for this route.

+

+  @retval EFI_SUCCESS            The operation completed successfully.

+  @retval EFI_NOT_STARTED        The driver instance has not been started.

+  @retval EFI_NO_MAPPING         When using the default address, configuration (DHCP, BOOTP,

+                                 RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:

+                                 - This is NULL.

+                                 - SubnetAddress is NULL.

+                                 - SubnetMask is NULL.

+                                 - GatewayAddress is NULL.

+                                 - *SubnetAddress is not a valid subnet address.

+                                 - *SubnetMask is not a valid subnet mask.

+                                 - *GatewayAddress is not a valid unicast IPv4 address.

+  @retval EFI_OUT_OF_RESOURCES   Could not add the entry to the routing table.

+  @retval EFI_NOT_FOUND          This route is not in the routing table (when DeleteRoute is TRUE).

+  @retval EFI_ACCESS_DENIED      The route is already defined in the routing table (when

+                                  DeleteRoute is FALSE).

+                                 

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IP4_ROUTES) (

+  IN EFI_IP4_PROTOCOL    *This,

+  IN BOOLEAN             DeleteRoute,

+  IN EFI_IPv4_ADDRESS    *SubnetAddress,

+  IN EFI_IPv4_ADDRESS    *SubnetMask,

+  IN EFI_IPv4_ADDRESS    *GatewayAddress  

+  )

+;  

+

+/**

+  Places outgoing data packets into the transmit queue.

+

+  @param  This  Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  Token Pointer to the transmit token.

+

+  @retval  EFI_SUCCESS           The data has been queued for transmission.

+  @retval  EFI_NOT_STARTED       This instance has not been started.

+  @retval  EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP,

+                                 RARP, etc.) is not finished yet.

+  @retval  EFI_INVALID_PARAMETER One or more pameters are invalid.

+  @retval  EFI_ACCESS_DENIED     The transmit completion token with the same Token.Event

+                                 was already in the transmit queue.

+  @retval  EFI_NOT_READY         The completion token could not be queued because the transmit

+                                 queue is full. 

+  @retval  EFI_NOT_FOUND         Not route is found to destination address.

+  @retval  EFI_OUT_OF_RESOURCES  Could not queue the transmit data.

+  @retval  EFI_BUFFER_TOO_SMALL  Token.Packet.TxData.TotalDataLength is too

+                                 short to transmit.

+  @retval  EFI_BAD_BUFFER_SIZE   The length of the IPv4 header + option length + total data length is

+                                 greater than MTU (or greater than the maximum packet size if

+                                 Token.Packet.TxData.OverrideData.

+                                 DoNotFragment is TRUE.)

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IP4_TRANSMIT) (

+  IN EFI_IP4_PROTOCOL          *This,

+  IN EFI_IP4_COMPLETION_TOKEN  *Token

+  )

+;    

+

+/**

+  Places a receiving request into the receiving queue.

+

+  @param  This  Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  Token Pointer to a token that is associated with the receive data descriptor.

+

+  @retval EFI_SUCCESS           The receive completion token was cached.

+  @retval EFI_NOT_STARTED       This EFI IPv4 Protocol instance has not been started.

+  @retval EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP, RARP, etc.)

+                                is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - This is NULL.

+                                - Token is NULL.

+                                - Token.Event is NULL.

+  @retval EFI_OUT_OF_RESOURCES  The receive completion token could not be queued due to a lack of system

+                                resources (usually memory).

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+                                The EFI IPv4 Protocol instance has been reset to startup defaults.

+                                EFI_ACCESS_DENIED The receive completion token with the same Token.Event was already

+                                in the receive queue.

+  @retval EFI_NOT_READY         The receive request could not be queued because the receive queue is full.

+  @retval EFI_ICMP_ERROR        An ICMP error packet was received.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IP4_RECEIVE) (

+  IN EFI_IP4_PROTOCOL          *This,

+  IN EFI_IP4_COMPLETION_TOKEN  *Token

+  )

+;      

+

+/**

+  Abort an asynchronous transmit or receive request.

+

+  @param  This  Pointer to the EFI_IP4_PROTOCOL instance.

+  @param  Token Pointer to a token that has been issued by

+                EFI_IP4_PROTOCOL.Transmit() or

+                EFI_IP4_PROTOCOL.Receive(). If NULL, all pending

+                tokens are aborted. Type EFI_IP4_COMPLETION_TOKEN is

+                defined in EFI_IP4_PROTOCOL.Transmit().

+

+  @retval EFI_SUCCESS           The asynchronous I/O request was aborted and

+                                Token.->Event was signaled. When Token is NULL, all

+                                pending requests were aborted and their events were signaled.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_NOT_STARTED       This instance has not been started.

+  @retval EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_NOT_FOUND         When Token is not NULL, the asynchronous I/O request was

+                                not found in the transmit or receive queue. It has either completed

+                                or was not issued by Transmit() and Receive().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IP4_CANCEL) (

+  IN EFI_IP4_PROTOCOL          *This,

+  IN EFI_IP4_COMPLETION_TOKEN  *Token OPTIONAL

+  )

+;      

+  

+/**

+  Polls for incoming data packets and processes outgoing data packets.

+

+  @param  This Pointer to the EFI_IP4_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.

+  @retval  EFI_NOT_STARTED       This EFI IPv4 Protocol instance has not been started.

+  @retval  EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP,

+                                 RARP, etc.) is not finished yet.

+  @retval  EFI_INVALID_PARAMETER This is NULL.

+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval  EFI_NOT_READY         No incoming or outgoing data is processed.

+  @retval  EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.

+                                 Consider increasing the polling rate.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IP4_POLL) (

+  IN EFI_IP4_PROTOCOL          *This

+  )

+;  

+

+struct _EFI_IP4_PROTOCOL {

+  EFI_IP4_GET_MODE_DATA        GetModeData;

+  EFI_IP4_CONFIGURE            Configure;

+  EFI_IP4_GROUPS               Groups;

+  EFI_IP4_ROUTES               Routes;

+  EFI_IP4_TRANSMIT             Transmit;

+  EFI_IP4_RECEIVE              Receive;

+  EFI_IP4_CANCEL               Cancel;

+  EFI_IP4_POLL                 Poll;

+};

+

+extern EFI_GUID gEfiIp4ServiceBindingProtocolGuid;

+extern EFI_GUID gEfiIp4ProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/IP4Config.h b/edk2/MdePkg/Include/Protocol/IP4Config.h
new file mode 100644
index 0000000..0212f35
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/IP4Config.h
@@ -0,0 +1,121 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  IP4Config.h

+

+**/

+

+#ifndef __EFI_IP4CONFIG_PROTOCOL_H__

+#define __EFI_IP4CONFIG_PROTOCOL_H__

+

+#define EFI_IP4_CONFIG_PROTOCOL_GUID \

+  { \

+    0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e } \

+  }

+

+typedef struct _EFI_IP4_CONFIG_PROTOCOL EFI_IP4_CONFIG_PROTOCOL;

+

+#define IP4_CONFIG_VARIABLE_ATTRIBUTES \

+        (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | \

+         EFI_VARIABLE_RUNTIME_ACCESS )

+

+typedef struct {

+  EFI_IPv4_ADDRESS             StationAddress;

+  EFI_IPv4_ADDRESS             SubnetMask;

+  UINT32                       RouteTableSize;

+  EFI_IP4_ROUTE_TABLE          *RouteTable;    //OPTIONAL

+} EFI_IP4_IPCONFIG_DATA;

+

+

+/**

+  Starts running the configuration policy for the EFI IPv4 Protocol driver.

+

+  @param  This          Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.

+  @param  DoneEvent     Event that will be signaled when the EFI IPv4 Protocol driver

+                        configuration policy completes execution. This event must be of

+                        type EVT_NOTIFY_SIGNAL.

+  @param  ReconfigEvent Event that will be signaled when the EFI IPv4 Protocol driver

+                        configuration needs to be updated. This event must be of type

+                        EVT_NOTIFY_SIGNAL.

+

+  @retval EFI_SUCCESS           The configuration policy for the EFI IPv4 Protocol driver is now

+                                running.

+  @retval EFI_INVALID_PARAMETER This, DoneEvent, or ReconfigEvent is NULL.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval EFI_ALREADY_STARTED   The configuration policy for the EFI IPv4 Protocol driver was

+                                already started.

+  @retval EFI_DEVICE_ERROR      An unexpected system error or network error occurred.

+  @retval EFI_UNSUPPORTED       This interface does not support the EFI IPv4 Protocol driver

+                                 configuration.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IP4_CONFIG_START) (

+  IN EFI_IP4_CONFIG_PROTOCOL   *This,

+  IN EFI_EVENT                 DoneEvent,

+  IN EFI_EVENT                 ReconfigEvent 

+  )

+;    

+

+/**

+  Stops running the configuration policy for the EFI IPv4 Protocol driver.

+

+  @param  This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           The configuration policy for the EFI IPv4 Protocol driver has been stopped.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_NOT_STARTED       The configuration policy for the EFI IPv4 Protocol driver was not started.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IP4_CONFIG_STOP) (

+  IN EFI_IP4_CONFIG_PROTOCOL   *This 

+  )

+;   

+

+/**

+  Returns the default configuration data (if any) for the EFI IPv4 Protocol driver.

+

+  @param  This             Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.

+  @param  IpConfigDataSize On input, the size of the IpConfigData buffer.

+                           On output, the count of bytes that were written into the IpConfigData buffer.

+  @param  IpConfigData     Pointer to the EFI IPv4 Configuration Protocol driver

+                           configuration data structure.

+

+  @retval EFI_SUCCESS           The EFI IPv4 Protocol driver configuration has been returned.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_NOT_STARTED       The configuration policy for the EFI IPv4 Protocol driver is not

+                                running.

+  @retval EFI_NOT_READY         EFI IPv4 Protocol driver configuration is still running.

+  @retval EFI_ABORTED           EFI IPv4 Protocol driver configuration could not complete.

+  @retval EFI_BUFFER_TOO_SMALL  *IpConfigDataSize is smaller than the configuration data

+                                buffer or IpConfigData is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IP4_CONFIG_GET_DATA) (

+  IN EFI_IP4_CONFIG_PROTOCOL   *This,

+  IN OUT UINTN                 *IpConfigDataSize,

+  OUT EFI_IP4_IPCONFIG_DATA    *IpConfigData    OPTIONAL 

+  )

+;    

+

+struct _EFI_IP4_CONFIG_PROTOCOL {

+  EFI_IP4_CONFIG_START         Start;

+  EFI_IP4_CONFIG_STOP          Stop;

+  EFI_IP4_CONFIG_GET_DATA      GetData;

+};

+

+extern EFI_GUID gEfiIp4ConfigProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/IScsiInitatorName.h b/edk2/MdePkg/Include/Protocol/IScsiInitatorName.h
new file mode 100644
index 0000000..48131e8
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/IScsiInitatorName.h
@@ -0,0 +1,92 @@
+/** @file

+  EFI_ISCSI_INITIATOR_NAME_PROTOCOL as defined in UEFI 2.0.

+  It rovides the ability to get and set the iSCSI Initiator Name.                                                  

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  IScsiInitatorName.h

+

+**/

+

+#ifndef __ISCSI_INITIATOR_NAME_H__

+#define __ISCSI_INITIATOR_NAME_H__

+

+#define EFI_ISCSI_INITIATOR_NAME_PROTOCOL_GUID \

+{ \

+  0xa6a72875, 0x2962, 0x4c18, {0x9f, 0x46, 0x8d, 0xa6, 0x44, 0xcc, 0xfe } \

+}

+

+typedef struct _EFI_ISCSI_INITIATOR_NAME_PROTOCOL EFI_ISCSI_INITIATOR_NAME_PROTOCOL;

+

+/**

+  Retrieves the current set value of iSCSI Initiator Name.

+

+  @param  This       Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL instance.

+  @param  BufferSize Size of the buffer in bytes pointed to by Buffer / Actual size of the

+                     variable data buffer.

+  @param  Buffer     Pointer to the buffer for data to be read.

+

+  @retval EFI_SUCCESS           Data was successfully retrieved into the provided buffer and the

+                                BufferSize was sufficient to handle the iSCSI initiator name

+  @retval EFI_BUFFER_TOO_SMALL  BufferSize is too small for the result.

+  @retval EFI_INVALID_PARAMETER BufferSize or Buffer is NULL.

+  @retval EFI_DEVICE_ERROR      The iSCSI initiator name could not be retrieved due to a hardware error.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_ISCSI_INITIATOR_NAME_GET) (

+  IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,

+  IN OUT UINTN                         *BufferSize,

+  OUT VOID                             *Buffer

+  )

+;

+

+  

+

+/**

+  Sets the iSCSI Initiator Name.

+

+  @param  This       Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL instance.

+  @param  BufferSize Size of the buffer in bytes pointed to by Buffer.

+  @param  Buffer     Pointer to the buffer for data to be written.

+

+  @retval EFI_SUCCESS           Data was successfully stored by the protocol.

+  @retval EFI_UNSUPPORTED       Platform policies do not allow for data to be written.

+  @retval EFI_INVALID_PARAMETER BufferSize or Buffer is NULL, or BufferSize exceeds the maximum allowed limit.

+  @retval EFI_DEVICE_ERROR      The data could not be stored due to a hardware error.

+  @retval EFI_OUT_OF_RESOURCES  Not enough storage is available to hold the data.

+  @retval EFI_PROTOCOL_ERROR    Input iSCSI initiator name does not adhere to RFC 3720

+                                (and other related protocols)

+

+**/

+typedef EFI_STATUS

+(EFIAPI *EFI_ISCSI_INITIATOR_NAME_SET) (

+  IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,

+  IN OUT UINTN                         *BufferSize,

+  IN VOID                              *Buffer

+  )

+;  

+

+struct _EFI_ISCSI_INITIATOR_NAME_PROTOCOL {

+  EFI_ISCSI_INITIATOR_NAME_GET         Get;

+  EFI_ISCSI_INITIATOR_NAME_SET         Set;

+};

+

+extern EFI_GUID gEfiIScsiInitiatorNameProtocolGuid;

+

+#endif

+

+

+

+

+

+

+

diff --git a/edk2/MdePkg/Include/Protocol/IdeControllerInit.h b/edk2/MdePkg/Include/Protocol/IdeControllerInit.h
new file mode 100644
index 0000000..beaac30
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/IdeControllerInit.h
@@ -0,0 +1,485 @@
+/** @file

+  This file declares EFI IDE Controller Init Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  IdeControllerInit.h

+

+  @par Revision Reference:

+  This Protocol is defined in IDE Controller Initialization Protocol Specification

+  Version 0.9

+

+**/

+

+#ifndef _EFI_IDE_CONTROLLER_INIT_PROTOCOL_H

+#define _EFI_IDE_CONTROLLER_INIT_PROTOCOL_H

+

+//

+// Global ID for the EFI Platform IDE Protocol GUID

+//

+#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \

+  { 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9 } }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_IDE_CONTROLLER_INIT_PROTOCOL  EFI_IDE_CONTROLLER_INIT_PROTOCOL;

+

+//

+//////////////////////////////////////////////////////////////////////////////////////////

+// EFI_IDE_BUS_ENUMERATION_PHASE

+// EFI_IDE_CONTROLLER_ENUM_PHASE

+//

+typedef enum{

+  EfiIdeBeforeChannelEnumeration,

+  EfiIdeAfterChannelEnumeration,

+  EfiIdeBeforeChannelReset,

+  EfiIdeAfterChannelReset,

+  EfiIdeBusBeforeDevicePresenceDetection,

+  EfiIdeBusAfterDevicePresenceDetection,

+  EfiIdeResetMode,

+  EfiIdeBusPhaseMaximum

+} EFI_IDE_CONTROLLER_ENUM_PHASE;

+

+//

+//******************************************************

+// EFI_ATA_EXT_TRANSFER_PROTOCOL

+//******************************************************

+//

+// This extended mode describes the SATA physical protocol.

+// SATA physical layers can operate at different speeds. 

+// These speeds are defined below. Various PATA protocols 

+// and associated modes are not applicable to SATA devices.

+//

+

+typedef enum {

+  EfiAtaSataTransferProtocol  

+} EFI_ATA_EXT_TRANSFER_PROTOCOL;

+

+#define  EFI_SATA_AUTO_SPEED  0

+#define  EFI_SATA_GEN1_SPEED  1

+#define  EFI_SATA_GEN2_SPEED  2

+

+//

+//*******************************************************

+// EFI_IDE_CABLE_TYPE

+//*******************************************************

+//

+typedef enum {

+  EfiIdeCableTypeUnknown,

+  EfiIdeCableType40pin,

+  EfiIdeCableType80Pin,

+  EfiIdeCableTypeSerial,

+  EfiIdeCableTypeMaximum

+} EFI_IDE_CABLE_TYPE;

+

+//

+//******************************************************

+// EFI_ATA_MODE

+//******************************************************

+//

+typedef struct {

+  BOOLEAN      Valid;

+  UINT32       Mode; 

+} EFI_ATA_MODE;

+

+//

+//******************************************************

+// EFI_ATA_EXTENDED_MODE

+//******************************************************

+//

+typedef struct {

+  EFI_ATA_EXT_TRANSFER_PROTOCOL  TransferProtocol;

+  UINT32                         Mode;

+} EFI_ATA_EXTENDED_MODE;

+

+//

+//******************************************************

+// EFI_ATA_COLLECTIVE_MODE

+//******************************************************

+//

+typedef struct {

+  EFI_ATA_MODE           PioMode; 

+  EFI_ATA_MODE           SingleWordDmaMode;

+  EFI_ATA_MODE           MultiWordDmaMode;

+  EFI_ATA_MODE           UdmaMode;

+  UINT32                 ExtModeCount;

+  EFI_ATA_EXTENDED_MODE  ExtMode[1]; 

+} EFI_ATA_COLLECTIVE_MODE;

+

+//

+//*******************************************************

+// EFI_ATA_IDENTIFY_DATA

+//*******************************************************

+//

+

+#pragma pack(1)

+

+typedef struct {   

+  UINT16  config;             // General Configuration

+  UINT16  cylinders;          // Number of Cylinders

+  UINT16  reserved_2;

+  UINT16  heads;              //Number of logical heads

+  UINT16  vendor_data1;

+  UINT16  vendor_data2;

+  UINT16  sectors_per_track;

+  UINT16  vendor_specific_7_9[3];

+  CHAR8   SerialNo[20];       // ASCII 

+  UINT16  vendor_specific_20_21[2]; 

+  UINT16  ecc_bytes_available;   

+  CHAR8   FirmwareVer[8];     // ASCII 

+  CHAR8   ModelName[40];      // ASCII   

+  UINT16  multi_sector_cmd_max_sct_cnt;

+  UINT16  reserved_48;

+  UINT16  capabilities;

+  UINT16  reserved_50;    

+  UINT16  pio_cycle_timing;   

+  UINT16  reserved_52;            

+  UINT16  field_validity;    

+  UINT16  current_cylinders;

+  UINT16  current_heads;

+  UINT16  current_sectors;   

+  UINT16  CurrentCapacityLsb;

+  UINT16  CurrentCapacityMsb;    

+  UINT16  reserved_59;    

+  UINT16  user_addressable_sectors_lo;

+  UINT16  user_addressable_sectors_hi;

+  UINT16  reserved_62;    

+  UINT16  multi_word_dma_mode;   

+  UINT16  advanced_pio_modes;

+  UINT16  min_multi_word_dma_cycle_time;

+  UINT16  rec_multi_word_dma_cycle_time;

+  UINT16  min_pio_cycle_time_without_flow_control;

+  UINT16  min_pio_cycle_time_with_flow_control;

+  UINT16  reserved_69_79[11];    

+  UINT16  major_version_no;

+  UINT16  minor_version_no;

+  UINT16  command_set_supported_82; // word 82

+  UINT16  command_set_supported_83; // word 83

+  UINT16  command_set_feature_extn; // word 84

+  UINT16  command_set_feature_enb_85; // word 85

+  UINT16  command_set_feature_enb_86; // word 86

+  UINT16  command_set_feature_default; // word 87

+  UINT16  ultra_dma_mode; // word 88

+  UINT16  reserved_89_127[39];

+  UINT16  security_status;

+  UINT16  vendor_data_129_159[31];

+  UINT16  reserved_160_255[96];

+} EFI_ATA_IDENTIFY_DATA;

+

+#pragma pack()

+//

+//*******************************************************

+// EFI_ATAPI_IDENTIFY_DATA

+//*******************************************************

+//

+#pragma pack(1)

+typedef struct {

+    UINT16  config;             // General Configuration

+    UINT16  obsolete_1;

+    UINT16  specific_config;

+    UINT16  obsolete_3;   

+    UINT16  retired_4_5[2];

+    UINT16  obsolete_6;   

+    UINT16  cfa_reserved_7_8[2];

+    UINT16  retired_9;

+    CHAR8   SerialNo[20];       // ASCII 

+    UINT16  retired_20_21[2];

+    UINT16  obsolete_22;

+    CHAR8   FirmwareVer[8];     // ASCII 

+    CHAR8   ModelName[40];      // ASCII 

+    UINT16  multi_sector_cmd_max_sct_cnt;

+    UINT16  reserved_48;

+    UINT16  capabilities_49;

+    UINT16  capabilities_50;

+    UINT16  obsolete_51_52[2];   

+    UINT16  field_validity;

+    UINT16  obsolete_54_58[5];

+    UINT16  mutil_sector_setting;

+    UINT16  user_addressable_sectors_lo;

+    UINT16  user_addressable_sectors_hi;

+    UINT16  obsolete_62;

+    UINT16  multi_word_dma_mode;

+    UINT16  advanced_pio_modes;

+    UINT16  min_multi_word_dma_cycle_time;

+    UINT16  rec_multi_word_dma_cycle_time;

+    UINT16  min_pio_cycle_time_without_flow_control;

+    UINT16  min_pio_cycle_time_with_flow_control;

+    UINT16  reserved_69_74[6];

+    UINT16  queue_depth;

+    UINT16  reserved_76_79[4];

+    UINT16  major_version_no;

+    UINT16  minor_version_no;

+    UINT16  cmd_set_support_82;

+    UINT16  cmd_set_support_83;

+    UINT16  cmd_feature_support;

+    UINT16  cmd_feature_enable_85;

+    UINT16  cmd_feature_enable_86;

+    UINT16  cmd_feature_default;

+    UINT16  ultra_dma_select;

+    UINT16  time_required_for_sec_erase;

+    UINT16  time_required_for_enhanced_sec_erase;

+    UINT16  current_advanced_power_mgmt_value;

+    UINT16  master_pwd_revison_code;

+    UINT16  hardware_reset_result;

+    UINT16  current_auto_acoustic_mgmt_value;

+    UINT16  reserved_95_99[5];

+    UINT16  max_user_lba_for_48bit_addr[4];

+    UINT16  reserved_104_126[23];

+    UINT16  removable_media_status_notification_support;

+    UINT16  security_status;

+    UINT16  vendor_data_129_159[31];

+    UINT16  cfa_power_mode;

+    UINT16  cfa_reserved_161_175[15];

+    UINT16  current_media_serial_no[30];

+    UINT16  reserved_206_254[49];

+    UINT16  integrity_word;

+} EFI_ATAPI_IDENTIFY_DATA;

+

+#pragma pack()

+//

+//*******************************************************

+// EFI_IDENTIFY_DATA

+//*******************************************************

+//

+typedef union {

+  EFI_ATA_IDENTIFY_DATA       AtaData;

+  EFI_ATAPI_IDENTIFY_DATA     AtapiData;

+} EFI_IDENTIFY_DATA; 

+

+#define   EFI_ATAPI_DEVICE_IDENTIFY_DATA  0x8000

+

+//

+/////////////////////////////////////////////////////////////////////////////////////////

+// Function prototype declaration, for ANSI compatability

+//

+/**

+  Returns the information about the specified IDE channel. 

+

+  @param  This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. 

+  

+  @param  Channel Zero-based channel number.

+  

+  @param  Enabled TRUE if this channel is enabled. Disabled channels are not scanned 

+  to see if any devices are present.

+  

+  @param  MaxDevices The maximum number of IDE devices that the bus driver 

+  can expect on this channel. 

+

+  @retval EFI_SUCCESS Information was returned without any errors.

+  

+  @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IDE_CONTROLLER_GET_CHANNEL_INFO) (

+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN  UINT8                           Channel, 

+  OUT BOOLEAN                         *Enabled,

+  OUT UINT8                           *MaxDevices

+);

+

+/**

+  The notifications from the IDE bus driver that it is about to enter a certain 

+  phase of the IDE channel enumeration process. 

+

+  @param  This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. 

+  

+  @param  Phase The phase during enumeration. 

+  

+  @param  Channel Zero-based channel number.

+

+  @retval EFI_SUCCESS The notification was accepted without any errors.

+  

+  @retval EFI_NOT_SUPPORTED Phase is not supported.

+  

+  @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).

+  

+  @retval EFI_NOT_READY This phase cannot be entered at this time.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IDE_CONTROLLER_NOTIFY_PHASE) (

+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL  *This,

+  IN EFI_IDE_CONTROLLER_ENUM_PHASE     Phase,

+  IN UINT8                             Channel

+);

+

+/**

+  Submits the device information to the IDE controller driver. 

+

+  @param  This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. 

+  

+  @param  Channel Zero-based channel number.

+  

+  @param  Device Zero-based device number on the Channel.

+  

+  @param  IdentifyData The device¡¯s response to the ATA IDENTIFY_DEVICE command.

+

+  @retval EFI_SUCCESS The information was accepted without any errors.

+  

+  @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).

+  Or Device is invalid.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_IDE_CONTROLLER_SUBMIT_DATA) (

+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN  UINT8                           Channel,

+  IN  UINT8                           Device,

+  IN  EFI_IDENTIFY_DATA               *IdentifyData

+);

+

+/**

+  Disqualifies specific modes for an IDE device. 

+

+  @param  This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. 

+  

+  @param  Channel Zero-based channel number.

+  

+  @param  Device Zero-based device number on the Channel.

+  

+  @param  BadModes The modes that the device does not support and that 

+  should be disqualified.

+

+  @retval EFI_SUCCESS The modes were accepted without any errors.

+  

+  @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).

+  Or Device is invalid.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IDE_CONTROLLER_DISQUALIFY_MODE) (

+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN  UINT8                           Channel,

+  IN  UINT8                           Device,

+  IN  EFI_ATA_COLLECTIVE_MODE         *BadModes

+);

+

+/**

+  Returns the information about the optimum modes for the specified IDE device.

+

+  @param  This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. 

+  

+  @param  Channel Zero-based channel number.

+  

+  @param  Device Zero-based device number on the Channel.

+  

+  @param  SupportedModes The optimum modes for the device. 

+

+  @retval EFI_SUCCESS SupportedModes was returned.

+  

+  @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).

+  Or Device is invalid. Or SupportedModes is NULL.

+  

+  @retval EFI_NOT_READY Modes cannot be calculated due to a lack of data. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IDE_CONTROLLER_CALCULATE_MODE) (

+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN  UINT8                           Channel,

+  IN  UINT8                           Device,

+  OUT EFI_ATA_COLLECTIVE_MODE         **SupportedModes

+);

+

+/**

+  Commands the IDE controller driver to program the IDE controller hardware 

+  so that the specified device can operate at the specified mode. 

+

+  @param  This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. 

+  

+  @param  Channel Zero-based channel number.

+  

+  @param  Device Zero-based device number on the Channel.

+  

+  @param  Modes The modes to set. 

+

+  @retval EFI_SUCCESS The command was accepted without any errors.

+  

+  @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount).

+  Or Device is invalid.

+  

+  @retval EFI_NOT_READY Modes cannot be set at this time due to lack of data.

+  

+  @retval EFI_DEVICE_ERROR Modes cannot be set due to hardware failure. 

+  The IDE bus driver should not use this device.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IDE_CONTROLLER_SET_TIMING) (

+  IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN  UINT8                           Channel,

+  IN  UINT8                           Device,

+  IN  EFI_ATA_COLLECTIVE_MODE         *Modes

+);

+

+//

+////////////////////////////////////////////////////////////////////////////////////////////////////

+// Interface structure 

+// EFI_IDE_CONTROLLER_INIT_PROTOCOL protocol provides the chipset specific information to the IDE bus driver.

+// An IDE Bus driver wants to manage an IDE bus and possible IDE devices will have to retrieve the 

+// EFI_IDE_CONTROLLER_INIT_PROTOCOL instances.

+//

+/**

+  @par Protocol Description:

+  Provides the basic interfaces to abstract an IDE controller.

+

+  @param GetChannelInfo

+  Returns the information about a specific channel. 

+

+  @param NotifyPhase

+  The notification that the IDE bus driver is about to enter the 

+  specified phase during the enumeration process. 

+

+  @param SubmitData 

+  Submits the Drive Identify data that was returned by the device. 

+

+  @param DisqualifyMode 

+  Submits information about modes that should be disqualified. 

+

+  @param CalculateMode 

+  Calculates and returns the optimum mode for a particular IDE device.

+

+  @param SetTiming 

+  Programs the IDE controller hardware to the default timing or per the modes 

+  that were returned by the last call to CalculateMode().

+

+  @param EnumAll 

+  Set to TRUE if the enumeration group includes all the channels that are 

+  produced by this controller. FALSE if an enumeration group consists of 

+  only one channel. 

+

+  @param ChannelCount

+  The number of channels that are produced by this controller.

+

+**/

+struct _EFI_IDE_CONTROLLER_INIT_PROTOCOL {

+  EFI_IDE_CONTROLLER_GET_CHANNEL_INFO    GetChannelInfo;

+  EFI_IDE_CONTROLLER_NOTIFY_PHASE        NotifyPhase;

+  EFI_IDE_CONTROLLER_SUBMIT_DATA         SubmitData;

+  EFI_IDE_CONTROLLER_DISQUALIFY_MODE     DisqualifyMode;

+  EFI_IDE_CONTROLLER_CALCULATE_MODE      CalculateMode;

+  EFI_IDE_CONTROLLER_SET_TIMING          SetTiming;

+  BOOLEAN                                EnumAll;

+  UINT8                                  ChannelCount; 

+};

+

+extern EFI_GUID gEfiIdeControllerInitProtocolGuid;

+

+#endif

+

+

diff --git a/edk2/MdePkg/Include/Protocol/IncompatiblePciDeviceSupport.h b/edk2/MdePkg/Include/Protocol/IncompatiblePciDeviceSupport.h
new file mode 100644
index 0000000..03a5b2e
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/IncompatiblePciDeviceSupport.h
@@ -0,0 +1,84 @@
+/** @file

+  This file declares EFI Incompatible PCI Device Support Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  IncompatiblePciDeviceSupport.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework of EFI PCI Platform Support Specification.

+  Version0.9

+

+**/

+

+#ifndef _INCOMPATIBLE_PCI_DEVICE_SUPPORT_H_

+#define _INCOMPATIBLE_PCI_DEVICE_SUPPORT_H_

+

+#define EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL_GUID \

+        {0xeb23f55a, 0x7863, 0x4ac2, {0x8d, 0x3d, 0x95, 0x65, 0x35, 0xde, 0x03, 0x75} }

+

+typedef struct _EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL;

+

+/**

+  Returns a list of ACPI resource descriptors that detail the special 

+  resource configuration requirements for an incompatible PCI device.

+

+  @param  This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance. 

+  

+  @param  VendorID A unique ID to identify the manufacturer of the PCI device.

+  

+  @param  DeviceID A unique ID to identify the particular PCI device.

+  

+  @param  RevisionID A PCI device-specific revision identifier.

+  

+  @param  SubsystemVendorId Specifies the subsystem vendor ID. 

+  

+  @param  SubsystemDeviceId Specifies the subsystem device ID.

+  

+  @param  Configuration A list of ACPI resource descriptors that detail 

+  the configuration requirement. 

+

+  @retval EFI_SUCCESS The function always returns EFI_SUCCESS.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_CHECK_DEVICE) (

+  IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL   *This,

+  IN  UINTN                                         VendorId,

+  IN  UINTN                                         DeviceId,

+  IN  UINTN                                         Revision,

+  IN  UINTN                                         SubVendorId,OPTIONAL

+  IN  UINTN                                         SubDeviceId,OPTIONAL

+  OUT VOID                                          **Configuration

+); 

+

+

+//

+// Interface structure for the Incompatible PCI Device Support Protocol

+//

+/**

+  @par Protocol Description:

+  This protocol can find some incompatible PCI devices and report their 

+  special resource requirements to the PCI bus driver.

+

+  @param CheckDevice

+  Returns a list of ACPI resource descriptors that detail any special 

+  resource configuration requirements if the specified device is a recognized 

+  incompatible PCI device. 

+

+**/

+struct _EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL {

+  EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_CHECK_DEVICE      CheckDevice;  

+};

+

+extern EFI_GUID gEfiIncompatiblePciDeviceSupportProtocolGuid;

+  

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Legacy8259.h b/edk2/MdePkg/Include/Protocol/Legacy8259.h
new file mode 100644
index 0000000..c30a5e5
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Legacy8259.h
@@ -0,0 +1,307 @@
+/** @file

+  This protocol abstracts the 8259 interrupt controller. This includes

+  PCI IRQ routing need to program the PCI Interrupt Line register.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.    

+

+  Module Name:  Legacy8259.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework for EFI Compatibility Support Module spec

+  Version 0.96

+

+**/

+

+#ifndef _EFI_LEGACY_8259_H

+#define _EFI_LEGACY_8259_H

+

+#define EFI_LEGACY_8259_PROTOCOL_GUID \

+  { \

+    0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1 } \

+  }

+

+typedef struct _EFI_LEGACY_8259_PROTOCOL EFI_LEGACY_8259_PROTOCOL;

+

+typedef enum {

+  Efi8259Irq0,

+  Efi8259Irq1,

+  Efi8259Irq2,

+  Efi8259Irq3,

+  Efi8259Irq4,

+  Efi8259Irq5,

+  Efi8259Irq6,

+  Efi8259Irq7,

+  Efi8259Irq8,

+  Efi8259Irq9,

+  Efi8259Irq10,

+  Efi8259Irq11,

+  Efi8259Irq12,

+  Efi8259Irq13,

+  Efi8259Irq14,

+  Efi8259Irq15,

+  Efi8259IrqMax

+} EFI_8259_IRQ;

+

+typedef enum {

+  Efi8259LegacyMode,

+  Efi8259ProtectedMode,

+  Efi8259MaxMode

+} EFI_8259_MODE;

+

+/**

+  Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for

+  the legacy mode mask and the protected mode mask. The base address for the 8259

+  is different for legacy and protected mode, so two masks are required.

+

+  @param  This Protocol instance pointer.

+  @param  MasterBase The base vector for the Master PIC in the 8259 controller

+  @param  Slavebase The base vector for the Master PIC in the 8259 controller

+

+  @retval  EFI_SUCCESS The new bases were programmed

+  @retval  EFI_DEVICE_ERROR A device erro occured programming the vector bases

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  UINT8                             MasterBase,

+  IN  UINT8                             SlaveBase

+  )

+;

+

+/**

+  Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for

+  the legacy mode mask and the protected mode mask. The base address for the 8259

+  is different for legacy and protected mode, so two masks are required.

+

+  @param  This Protocol instance pointer.

+  @param  LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15

+  @param  LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15

+  @param  ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15

+  @param  ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15

+

+  @retval  EFI_SUCCESS 8259 status returned

+  @retval  EFI_DEVICE_ERROR Error reading 8259

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_GET_MASK) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  OUT UINT16                            *LegacyMask, OPTIONAL

+  OUT UINT16                            *LegacyEdgeLevel, OPTIONAL

+  OUT UINT16                            *ProtectedMask, OPTIONAL

+  OUT UINT16                            *ProtectedEdgeLevel OPTIONAL

+  )

+;

+

+/**

+  Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for

+  the legacy mode mask and the protected mode mask. The base address for the 8259

+  is different for legacy and protected mode, so two masks are required.

+  Also set the edge/level masks.

+

+  @param  This Protocol instance pointer.

+  @param  LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15

+  @param  LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15

+  @param  ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15

+  @param  ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15

+

+  @retval  EFI_SUCCESS 8259 status returned

+  @retval  EFI_DEVICE_ERROR Error reading 8259

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_SET_MASK) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  UINT16                            *LegacyMask, OPTIONAL

+  IN  UINT16                            *LegacyEdgeLevel, OPTIONAL

+  IN  UINT16                            *ProtectedMask, OPTIONAL

+  IN  UINT16                            *ProtectedEdgeLevel OPTIONAL

+  )

+;

+

+/**

+  Set the 8259 mode of operation. The base address for the 8259 is different for

+  legacy and protected mode. The legacy mode requires the master 8259 to have a

+  master base of 0x08 and the slave base of 0x70. The protected mode base locations

+  are not defined. Interrupts must be masked by the caller before this function

+  is called. The interrupt mask from the current mode is saved. The interrupt 

+  mask for the new mode is Mask, or if Mask does not exist the previously saved

+  mask is used.

+

+  @param  This Protocol instance pointer.

+  @param  Mode Mode of operation. i.e. real mode or protected mode

+  @param  Mask Optional interupt mask for the new mode.

+  @param  EdgeLevel Optional trigger mask for the new mode.

+

+  @retval  EFI_SUCCESS 8259 programmed

+  @retval  EFI_DEVICE_ERROR Error writting to 8259

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_SET_MODE) (

+  IN EFI_LEGACY_8259_PROTOCOL         *This,

+  IN  EFI_8259_MODE                   Mode,

+  IN  UINT16                          *Mask, OPTIONAL

+  IN  UINT16                          *EdgeLevel OPTIONAL

+  )

+;

+

+/**

+  Convert from IRQ to processor interrupt vector number.

+

+  @param  This Protocol instance pointer.

+  @param  Irq 8259 IRQ0 - IRQ15

+  @param  Vector Processor vector number that matches Irq

+

+  @retval  EFI_SUCCESS The Vector matching Irq is returned

+  @retval  EFI_INVALID_PARAMETER Irq not valid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_GET_VECTOR) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  EFI_8259_IRQ                      Irq,

+  OUT UINT8                             *Vector

+  )

+;

+

+/**

+  Enable Irq by unmasking interrupt in 8259

+

+  @param  This Protocol instance pointer.

+  @param  Irq 8259 IRQ0 - IRQ15

+  @param  LevelTriggered TRUE if level triggered.  FALSE if edge triggered.

+

+  @retval  EFI_SUCCESS Irq enabled on 8259

+  @retval  EFI_INVALID_PARAMETER Irq not valid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  EFI_8259_IRQ                      Irq,

+  IN  BOOLEAN                           LevelTriggered

+  )

+;

+

+/**

+  Disable Irq by masking interrupt in 8259

+

+  @param  This Protocol instance pointer.

+  @param  Irq 8259 IRQ0 - IRQ15

+

+  @retval  EFI_SUCCESS Irq disabled on 8259

+  @retval  EFI_INVALID_PARAMETER Irq not valid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  EFI_8259_IRQ                      Irq

+  )

+;

+

+/**

+  PciHandle represents a PCI config space of a PCI function. Vector 

+  represents Interrupt Pin (from PCI config space) and it is the data

+  that is programmed into the Interrupt Line (from the PCI config space)

+  register.

+

+  @param  This Protocol instance pointer.

+  @param  PciHandle PCI function to return vector for

+  @param  Vector Vector for fucntion that matches

+

+  @retval  EFI_SUCCESS A valid Vector is returned

+  @retval  EFI_INVALID_PARAMETER PciHandle not valid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  EFI_HANDLE                        PciHandle,

+  OUT UINT8                             *Vector

+  )

+;

+

+/**

+  Send an EOI to 8259

+

+  @param  This Protocol instance pointer.

+  @param  Irq 8259 IRQ0 - IRQ15

+

+  @retval  EFI_SUCCESS EOI successfully sent to 8259

+  @retval  EFI_INVALID_PARAMETER Irq not valid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT) (

+  IN EFI_LEGACY_8259_PROTOCOL           *This,

+  IN  EFI_8259_IRQ                      Irq

+  )

+;

+

+/**

+  @par Protocol Description:

+  Abstracts the 8259 and APIC hardware control between EFI usage and 

+  Compatibility16 usage.

+

+  @param SetVectorBase

+  Sets the vector bases for master and slave PICs. 

+

+  @param GetMask

+  Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected mode. 

+

+  @param SetMask

+  Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected mode.

+

+  @param SetMode

+  Sets PIC mode to 16-bit real mode or 32-bit protected mode.

+

+  @param GetVector

+  Gets the base vector assigned to an IRQ.

+

+  @param EnableIrq

+  Enables an IRQ. 

+

+  @param DisableIrq

+  Disables an IRQ.

+

+  @param GetInterruptLine

+  Gets an IRQ that is assigned to a PCI device. 

+

+  @param EndOfInterrupt

+  Issues the end of interrupt command. 

+

+**/

+struct _EFI_LEGACY_8259_PROTOCOL {

+  EFI_LEGACY_8259_SET_VECTOR_BASE     SetVectorBase;

+  EFI_LEGACY_8259_GET_MASK            GetMask;

+  EFI_LEGACY_8259_SET_MASK            SetMask;

+  EFI_LEGACY_8259_SET_MODE            SetMode;

+  EFI_LEGACY_8259_GET_VECTOR          GetVector;

+  EFI_LEGACY_8259_ENABLE_IRQ          EnableIrq;

+  EFI_LEGACY_8259_DISABLE_IRQ         DisableIrq;

+  EFI_LEGACY_8259_GET_INTERRUPT_LINE  GetInterruptLine;

+  EFI_LEGACY_8259_END_OF_INTERRUPT    EndOfInterrupt;

+};

+

+extern EFI_GUID gEfiLegacy8259ProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/LegacyBios.h b/edk2/MdePkg/Include/Protocol/LegacyBios.h
new file mode 100644
index 0000000..aa94cfb
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/LegacyBios.h
@@ -0,0 +1,701 @@
+/** @file

+  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage

+  under EFI and Legacy OS boot.

+

+  Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow 

+  well known naming conventions.

+

+  Thunk - A thunk is a transition from one processor mode to another. A Thunk

+  is a transition from native EFI mode to 16-bit mode. A reverse thunk

+  would be a transition from 16-bit mode to native EFI mode.

+

+  You most likely should not use this protocol! Find the EFI way to solve the

+  problem to make your code portable

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  LegacyBios.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework for EFI Compatibility Support Module spec

+  Version 0.96

+

+**/

+

+#ifndef _EFI_LEGACY_BIOS_H

+#define _EFI_LEGACY_BIOS_H

+

+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \

+  { \

+    0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \

+  }

+

+typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL;

+

+//

+// Convert from 32-bit address (_Adr) to Segment:Offset 16-bit form

+//

+#define EFI_SEGMENT(_Adr)     (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)

+#define EFI_OFFSET(_Adr)      (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)

+#define BYTE_GRANULARITY      0x01

+#define WORD_GRANULARITY      0x02

+#define DWORD_GRANULARITY     0x04

+#define QWORD_GRANULARITY     0x08

+#define PARAGRAPH_GRANULARITY 0x10

+

+#define CARRY_FLAG            0x01

+

+//*********************************************************

+// EFI_EFLAGS_REG

+//*********************************************************

+typedef struct {

+  UINT32 CF:1;

+  UINT32 Reserved1:1;

+  UINT32 PF:1;

+  UINT32 Reserved2:1;

+  UINT32 AF:1;

+  UINT32 Reserved3:1;

+  UINT32 ZF:1;

+  UINT32 SF:1;

+  UINT32 TF:1;

+  UINT32 IF:1;

+  UINT32 DF:1;

+  UINT32 OF:1;

+  UINT32 IOPL:2;

+  UINT32 NT:1;

+  UINT32 Reserved4:2;

+  UINT32 VM:1;

+  UINT32 Reserved5:14;

+} EFI_EFLAGS_REG;

+

+//*********************************************************

+// EFI_DWORD_REGS

+//*********************************************************

+

+typedef struct {

+    UINT32           EAX;

+    UINT32           EBX;

+    UINT32           ECX;

+    UINT32           EDX;

+    UINT32           ESI;

+    UINT32           EDI;

+    EFI_EFLAGS_REG   EFlags;

+    UINT16           ES;

+    UINT16           CS;

+    UINT16           SS;

+    UINT16           DS;

+    UINT16           FS;

+    UINT16           GS;

+    UINT32           EBP;

+    UINT32           ESP;

+} EFI_DWORD_REGS;

+

+//*******************************************

+// EFI_FLAGS_REG

+//*******************************************

+typedef struct {

+  UINT16     CF:1;

+  UINT16     Reserved1:1;

+  UINT16     PF:1;

+  UINT16     Reserved2:1;

+  UINT16     AF:1;

+  UINT16     Reserved3:1;

+  UINT16     ZF:1;

+  UINT16     SF:1;

+  UINT16     TF:1;

+  UINT16     IF:1;

+  UINT16     DF:1;

+  UINT16     OF:1;

+  UINT16     IOPL:2;

+  UINT16     NT:1;

+  UINT16     Reserved4:1;

+} EFI_FLAGS_REG;

+

+

+//*********************************************************

+// EFI_WORD_REGS

+//*********************************************************

+

+typedef struct {

+    UINT16           AX;

+    UINT16           ReservedAX;

+    UINT16           BX;

+    UINT16           ReservedBX;    

+    UINT16           CX;

+    UINT16           ReservedCX;

+    UINT16           DX;

+    UINT16           ReservedDX;

+    UINT16           SI;

+    UINT16           ReservedSI;

+    UINT16           DI;

+    UINT16           ReservedDI;

+    EFI_FLAGS_REG    Flags;

+    UINT16           ReservedFlags;

+    UINT16           ES;

+    UINT16           CS;

+    UINT16           SS;

+    UINT16           DS;

+    UINT16           FS;

+     UINT16           GS; 

+    UINT16           BP;

+    UINT16           ReservedBP; 

+    UINT16           SP;

+    UINT16           ReservedSP; 

+} EFI_WORD_REGS;

+

+//*********************************************************

+// EFI_BYTE_REGS

+//*********************************************************

+

+typedef struct {

+    UINT8   AL, AH;

+    UINT16  ReservedAX;

+    UINT8   BL, BH;

+    UINT16  ReservedBX;

+    UINT8   CL, CH;

+    UINT16  ReservedCX;

+    UINT8   DL, DH;

+    UINT16  ReservedDX;

+} EFI_BYTE_REGS;

+

+typedef union {

+  EFI_DWORD_REGS  E;

+  EFI_WORD_REGS   X;

+  EFI_BYTE_REGS   H;

+} EFI_IA32_REGISTER_SET;

+

+#pragma pack(1)

+//

+// $EFI table created by Legacy16 code and consumed by EFI Legacy driver

+//

+typedef struct {

+  UINT32  Signature;      // "$EFI"

+  UINT8   TableChecksum;

+  UINT8   TableLength;

+  UINT8   EfiMajorRevision;

+  UINT8   EfiMinorRevision;

+  UINT8   TableMajorRevision;

+  UINT8   TableMinorRevision;

+  UINT8   Reserved[2];

+  UINT16  Legacy16CallSegment;

+  UINT16  Legacy16CallOffset;

+

+  UINT16  PnPInstallationCheckSegment;

+  UINT16  PnPInstallationCheckOffset;

+

+  UINT32  EfiSystemTable;

+  UINT32  OemStringPointer;

+  UINT32  AcpiRsdPtrPointer;

+  UINT16  OemRevision;

+  UINT32  E820Pointer;

+  UINT32  E820Length;

+  UINT32  IrqRoutingTablePointer;

+  UINT32  IrqRoutingTableLength;

+  UINT32  MpTablePtr;

+  UINT32  MpTableLength;

+  UINT16  OemIntSegment;

+  UINT16  OemIntOffset;

+  UINT16  Oem32Segment;

+  UINT16  Oem32Offset;

+  UINT16  Oem16Segment;

+  UINT16  Oem16Offset;

+  UINT16  TpmSegment;

+  UINT16  TpmOffset;

+  UINT32  IbvPointer;

+  UINT32  PciExpressBase;

+  UINT8   LastPciBus;

+} EFI_COMPATIBILITY16_TABLE;

+//

+// define maximum number of HDD system supports

+//

+#define MAX_HDD_ENTRIES 0x30

+

+typedef struct {

+  UINT16  Raw[256];

+} ATAPI_IDENTIFY;

+

+//

+// HDD_INFO status

+//

+#define HDD_PRIMARY               0x01

+#define HDD_SECONDARY             0x02

+#define HDD_MASTER_ATAPI_CDROM    0x04

+#define HDD_SLAVE_ATAPI_CDROM     0x08

+#define HDD_MASTER_IDE            0x20

+#define HDD_SLAVE_IDE             0x40

+#define HDD_MASTER_ATAPI_ZIPDISK  0x10

+#define HDD_SLAVE_ATAPI_ZIPDISK   0x80

+

+typedef struct {

+  UINT16          Status;

+  UINT32          Bus;

+  UINT32          Device;

+  UINT32          Function;

+  UINT16          CommandBaseAddress;

+  UINT16          ControlBaseAddress;

+  UINT16          BusMasterAddress;

+  UINT8           HddIrq;

+  ATAPI_IDENTIFY  IdentifyDrive[2];

+} HDD_INFO;

+

+//

+// Parties data structures

+//

+typedef struct {

+  UINT8 DirectoryServiceValidity : 1;

+  UINT8 RabcaUsedFlag : 1;

+  UINT8 ExecuteHddDiagnosticsFlag : 1;

+  UINT8 Reserved : 5;

+} UDC_ATTRIBUTES;

+

+typedef struct {

+  UDC_ATTRIBUTES  Attributes;

+  UINT8           DeviceNumber;

+  UINT8           BbsTableEntryNumberForParentDevice;

+  UINT8           BbsTableEntryNumberForBoot;

+  UINT8           BbsTableEntryNumberForHddDiag;

+  UINT8           BeerData[128];

+  UINT8           ServiceAreaData[64];

+} UD_TABLE;

+

+//

+// define BBS Device Types

+//

+#define BBS_FLOPPY        0x01

+#define BBS_HARDDISK      0x02

+#define BBS_CDROM         0x03

+#define BBS_PCMCIA        0x04

+#define BBS_USB           0x05

+#define BBS_EMBED_NETWORK 0x06

+#define BBS_BEV_DEVICE    0x80

+#define BBS_UNKNOWN       0xff

+

+typedef struct {

+  UINT16  OldPosition : 4;

+  UINT16  Reserved1 : 4;

+  UINT16  Enabled : 1;

+  UINT16  Failed : 1;

+  UINT16  MediaPresent : 2;

+  UINT16  Reserved2 : 4;

+} BBS_STATUS_FLAGS;

+

+#define MAX_BBS_ENTRIES 0x100

+//

+// BBS_IGNORE_ENTRY is placed in the BootPriority field if the entry is to

+// be skipped.

+// BBS_UNPRIORITIZED_ENTRY is placed in the BootPriority field before

+// priority has been assigned but indicates valid entry.

+// BBS_LOWEST_PRIORITY is normally used for removable media with no media

+//   inserted. This allows the 16-bit CSM to allocate a drive letter to

+//   the device.

+// BBS_DO_NOT_BOOT_FROM is used for devices that the 16-bit CSM is to assign

+//   a drive letter to but never boot from.

+//

+// AdditionalIrq??Handler usage is IBV specific. The fields have been added

+// for:

+//   1. Saving non-BBS card info about IRQs taken by card.

+//   2. For BBS compliant cards that hook IRQs in order to have their SETUP

+//      executed.

+//

+#define BBS_DO_NOT_BOOT_FROM    0xFFFC

+#define BBS_LOWEST_PRIORITY     0xFFFD

+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE

+#define BBS_IGNORE_ENTRY        0xFFFF

+

+typedef struct {

+  UINT16            BootPriority;

+  UINT32            Bus;

+  UINT32            Device;

+  UINT32            Function;

+  UINT8             Class;

+  UINT8             SubClass;

+  UINT16            MfgStringOffset;

+  UINT16            MfgStringSegment;

+  UINT16            DeviceType;

+  BBS_STATUS_FLAGS  StatusFlags;

+  UINT16            BootHandlerOffset;

+  UINT16            BootHandlerSegment;

+  UINT16            DescStringOffset;

+  UINT16            DescStringSegment;

+  UINT32            InitPerReserved;

+  UINT32            AdditionalIrq13Handler;

+  UINT32            AdditionalIrq18Handler;

+  UINT32            AdditionalIrq19Handler;

+  UINT32            AdditionalIrq40Handler;

+  UINT8             AssignedDriveNumber;

+  UINT32            AdditionalIrq41Handler;

+  UINT32            AdditionalIrq46Handler;

+  UINT32            IBV1;

+  UINT32            IBV2;

+} BBS_TABLE;

+

+#pragma pack()

+

+/**

+  Thunk to 16-bit real mode and execute a software interrupt with a vector 

+  of BiosInt. Regs will contain the 16-bit register context on entry and 

+  exit.

+

+  @param  This Protocol instance pointer.

+  @param  BiosInt Processor interrupt vector to invoke

+  @param  Reg Register contexted passed into (and returned) from thunk to

+  16-bit mode

+

+  @retval  FALSE Thunk completed, and there were no BIOS errors in the target code.

+  See Regs for status.

+  @retval  TRUE There was a BIOS erro in the target code.

+

+**/

+typedef

+BOOLEAN

+(EFIAPI *EFI_LEGACY_BIOS_INT86) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN  UINT8                           BiosInt,

+  IN OUT  EFI_IA32_REGISTER_SET       *Regs

+  )

+;

+

+/**

+  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the 

+  16-bit register context on entry and exit. Arguments can be passed on 

+  the Stack argument

+

+  @param  This Protocol instance pointer.

+  @param  Segment Segemnt of 16-bit mode call

+  @param  Offset Offset of 16-bit mdoe call

+  @param  Reg Register contexted passed into (and returned) from thunk to

+  16-bit mode

+  @param  Stack Caller allocated stack used to pass arguments

+  @param  StackSize Size of Stack in bytes

+

+  @retval  FALSE Thunk completed, and there were no BIOS errors in the target code.

+  See Regs for status.

+  @retval  TRUE There was a BIOS erro in the target code.

+

+**/

+typedef

+BOOLEAN

+(EFIAPI *EFI_LEGACY_BIOS_FARCALL86) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN  UINT16                          Segment,

+  IN  UINT16                          Offset,

+  IN  EFI_IA32_REGISTER_SET           *Regs,

+  IN  VOID                            *Stack,

+  IN  UINTN                           StackSize

+  )

+;

+

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN  EFI_HANDLE                      PciHandle,

+  OUT VOID                            **RomImage, OPTIONAL

+  OUT UINTN                           *RomSize, OPTIONAL

+  OUT UINTN                           *Flags

+

+/**

+  Test to see if a legacy PCI ROM exists for this device. Optionally return

+  the Legacy ROM instance for this PCI device.

+

+  @param  This Protocol instance pointer.

+  @param  PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded

+  @param  RomImage Return the legacy PCI ROM for this device

+  @param  RomSize Size of ROM Image

+  @param  Flags Indicates if ROM found and if PC-AT.

+

+  @retval  EFI_SUCCESS Legacy Option ROM availible for this device

+  @retval  EFI_UNSUPPORTED Legacy Option ROM not supported.

+

+**/

+  )

+;

+

+/**

+  Load a legacy PC-AT OPROM on the PciHandle device. Return information

+  about how many disks were added by the OPROM and the shadow address and

+  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:

+

+  @param  This Protocol instance pointer.

+  @param  PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded.

+  This value is NULL if RomImage is non-NULL. This is the normal

+  case.

+  @param  RomImage A PCI PC-AT ROM image. This argument is non-NULL if there is

+  no hardware associated with the ROM and thus no PciHandle,

+  otherwise is must be NULL.

+  Example is PXE base code.

+  @param  Flags Return Status if ROM was found and if was Legacy OPROM.

+  @param  DiskStart Disk number of first device hooked by the ROM. If DiskStart

+  is the same as DiskEnd no disked were hooked.

+  @param  DiskEnd Disk number of the last device hooked by the ROM.

+  @param  RomShadowAddress Shadow address of PC-AT ROM

+  @param  RomShadowSize Size of RomShadowAddress in bytes

+

+  @retval  EFI_SUCCESS Thunk completed, see Regs for status.

+  @retval  EFI_INVALID_PARAMETER PciHandle not found

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN  EFI_HANDLE                      PciHandle,

+  IN  VOID                            **RomImage,

+  OUT UINTN                           *Flags,

+  OUT UINT8                           *DiskStart, OPTIONAL

+  OUT UINT8                           *DiskEnd, OPTIONAL

+  OUT VOID                            **RomShadowAddress, OPTIONAL

+  OUT UINT32                          *ShadowedRomSize OPTIONAL

+  )

+;

+

+/**

+  Attempt to legacy boot the BootOption. If the EFI contexted has been 

+  compromised this function will not return.

+

+  @param  This Protocol instance pointer.

+  @param  BootOption EFI Device Path from BootXXXX variable.

+  @param  LoadOptionSize Size of LoadOption in size.

+  @param  LoadOption LoadOption from BootXXXX variable

+

+  @retval  EFI_SUCCESS Removable media not present

+

+**/

+/**

+  Update BDA with current Scroll, Num & Cap lock LEDS

+

+  @param  This Protocol instance pointer.

+  @param  Leds Status of current Scroll, Num & Cap lock LEDS

+  Bit 0 is Scroll Lock  0 = Not locked

+  Bit 1 is Num Lock

+  Bit 2 is Caps Lock

+

+  @retval  EFI_SUCCESS Removable media not present

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_BOOT) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN  BBS_BBS_DEVICE_PATH             *BootOption,

+  IN  UINT32                          LoadOptionsSize,

+  IN  VOID                            *LoadOptions

+  )

+;

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN  UINT8                           Leds

+  )

+;

+

+/**

+  Retrieve legacy BBS info and assign boot priority.

+

+  @param  This Protocol instance pointer.

+  @param  HddCount Number of HDD_INFO structures

+  @param  HddInfo Onboard IDE controller information

+  @param  BbsCount Number of BBS_TABLE structures

+  @param  BbsTable List BBS entries

+

+  @retval  EFI_SUCCESS Tables returned

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  OUT UINT16                          *HddCount,

+  OUT HDD_INFO                        **HddInfo,

+  OUT UINT16                          *BbsCount,

+  OUT IN BBS_TABLE                    **BbsTable

+  )

+;

+

+/**

+  Assign drive number to legacy HDD drives prior to booting an EFI

+  aware OS so the OS can access drives without an EFI driver.

+

+  @param  This Protocol instance pointer.

+  @param  BbsCount Number of BBS_TABLE structures

+  @param  BbsTable List BBS entries

+

+  @retval  EFI_SUCCESS Drive numbers assigned

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  OUT UINT16                          *BbsCount,

+  OUT IN BBS_TABLE                    **BbsTable

+  )

+;

+

+/**

+  To boot from an unconventional device like parties and/or execute

+  HDD diagnostics.

+

+  @param  This Protocol instance pointer.

+  @param  Attributes How to interpret the other input parameters

+  @param  BbsEntry The 0-based index into the BbsTable for the parent

+  device.

+  @param  BeerData Pointer to the 128 bytes of ram BEER data.

+  @param  ServiceAreaData Pointer to the 64 bytes of raw Service Area data. The

+  caller must provide a pointer to the specific Service

+  Area and not the start all Service Areas.

+

+  EFI_INVALID_PARAMETER if error. Does NOT return if no error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE) (

+  IN EFI_LEGACY_BIOS_PROTOCOL         *This,

+  IN UDC_ATTRIBUTES                   Attributes,

+  IN UINTN                            BbsEntry,

+  IN VOID                             *BeerData,

+  IN VOID                             *ServiceAreaData

+  )

+;

+

+/**

+  Shadow all legacy16 OPROMs that haven't been shadowed.

+  Warning: Use this with caution. This routine disconnects all EFI

+  drivers. If used externally then caller must re-connect EFI

+  drivers.

+

+  @retval  EFI_SUCCESS OPROMs shadowed

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS) (

+  IN EFI_LEGACY_BIOS_PROTOCOL *This

+  )

+;

+

+/**

+  Get a region from the LegacyBios for S3 usage.

+

+  @param  This Protocol instance pointer.

+  @param  LegacyMemorySize Size of required region

+  @param  Region Region to use.

+  00 = Either 0xE0000 or 0xF0000 block

+  Bit0 = 1 0xF0000 block

+  Bit1 = 1 0xE0000 block

+  @param  Alignment Address alignment. Bit mapped. First non-zero

+  bit from right is alignment.

+  @param  LegacyMemoryAddress Region Assigned

+

+  @retval  EFI_SUCCESS Region assigned

+  

+  @retval  Other Region not assigned

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION) (

+  IN EFI_LEGACY_BIOS_PROTOCOL *This,

+  IN    UINTN                 LegacyMemorySize,

+  IN    UINTN                 Region,

+  IN    UINTN                 Alignment,

+  OUT   VOID                  **LegacyMemoryAddress

+  )

+;

+

+/**

+  Get a region from the LegacyBios for Tiano usage. Can only be invoked once.

+

+  @param  This Protocol instance pointer.

+  @param  LegacyMemorySize Size of data to copy

+  @param  LegacyMemoryAddress Legacy Region destination address

+  Note: must be in region assigned by

+  LegacyBiosGetLegacyRegion

+  @param  LegacyMemorySourceAddress Source of data

+

+  @retval  EFI_SUCCESS Region assigned

+  @retval  EFI_ACCESS_DENIED Destination outside assigned region

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION) (

+  IN EFI_LEGACY_BIOS_PROTOCOL *This,

+  IN    UINTN                 LegacyMemorySize,

+  IN    VOID                  *LegacyMemoryAddress,

+  IN    VOID                  *LegacyMemorySourceAddress

+  )

+;

+

+/**

+  @par Protocol Description:

+  Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot() 

+  member function allows the BDS to support booting a traditional OS. 

+  EFI thunks drivers that make EFI bindings for BIOS INT services use 

+  all the other member functions.

+

+  @param Int86

+  Performs traditional software INT. See the Int86() function description.

+

+  @param FarCall86

+  Performs a far call into Compatibility16 or traditional OpROM code. 

+

+  @param CheckPciRom

+  Checks if a traditional OpROM exists for this device.

+

+  @param InstallPciRom

+  Loads a traditional OpROM in traditional OpROM address space.

+

+  @param LegacyBoot

+  Boots a traditional OS.

+

+  @param UpdateKeyboardLedStatus

+  Updates BDA to reflect the current EFI keyboard LED status.

+

+  @param GetBbsInfo

+  Allows an external agent, such as BIOS Setup, to get the BBS data. 

+

+  @param ShadowAllLegacyOproms

+  Causes all legacy OpROMs to be shadowed.

+

+  @param PrepareToBootEfi

+  Performs all actions prior to boot. Used when booting an EFI-aware OS 

+  rather than a legacy OS. 

+

+  @param GetLegacyRegion

+  Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block.

+

+  @param CopyLegacyRegion

+  Allows EFI to copy data to the area specified by GetLegacyRegion. 

+

+  @param BootUnconventionalDevice

+  Allows the user to boot off an unconventional device such as a PARTIES partition.

+

+**/

+struct _EFI_LEGACY_BIOS_PROTOCOL {

+  EFI_LEGACY_BIOS_INT86                       Int86;

+  EFI_LEGACY_BIOS_FARCALL86                   FarCall86;

+  EFI_LEGACY_BIOS_CHECK_ROM                   CheckPciRom;

+  EFI_LEGACY_BIOS_INSTALL_ROM                 InstallPciRom;

+  EFI_LEGACY_BIOS_BOOT                        LegacyBoot;

+  EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS  UpdateKeyboardLedStatus;

+  EFI_LEGACY_BIOS_GET_BBS_INFO                GetBbsInfo;

+  EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI         PrepareToBootEfi;

+  EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS    ShadowAllLegacyOproms;

+  EFI_LEGACY_BIOS_GET_LEGACY_REGION           GetLegacyRegion;

+  EFI_LEGACY_BIOS_COPY_LEGACY_REGION          CopyLegacyRegion;

+  EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE  BootUnconventionalDevice;

+};

+

+extern EFI_GUID gEfiLegacyBiosProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/LegacyBiosPlatform.h b/edk2/MdePkg/Include/Protocol/LegacyBiosPlatform.h
new file mode 100644
index 0000000..56d6724
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/LegacyBiosPlatform.h
@@ -0,0 +1,307 @@
+/** @file

+  The EFI Legacy BIOS Patform Protocol is used to mate a Legacy16 

+  implementation with this EFI code. The EFI driver that produces 

+  the Legacy BIOS protocol is generic and consumes this protocol.

+  A driver that matches the Legacy16 produces this protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.    

+

+  Module Name:  LegacyBiosPlatform.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework for EFI Compatibility Support Module spec

+  Version 0.96

+**/

+

+#ifndef _EFI_LEGACY_BIOS_PLATFORM_H

+#define _EFI_LEGACY_BIOS_PLATFORM_H

+

+#define EFI_LEGACY_BIOS_PLATFORM_PROTOCOL_GUID \

+  { \

+    0x783658a3, 0x4172, 0x4421, {0xa2, 0x99, 0xe0, 0x9, 0x7, 0x9c, 0xc, 0xb4 } \

+  }

+

+typedef struct _EFI_LEGACY_BIOS_PLATFORM_PROTOCOL EFI_LEGACY_BIOS_PLATFORM_PROTOCOL;

+

+#pragma pack(1)

+//

+// Define structures for GetOemIntData

+//  Note:

+//    OemIntDataElenent is an array of structures from 0 to Count-1.

+//    RawData is an array of bytes from 0 to RamDataLength-1.

+//

+typedef struct {

+  UINT16  Int;

+  UINT16  Ax;

+  UINT32  RawDataLength;

+  UINT8   RawData[1];

+} EFI_OEM_INT_DATA_ELEMENT;

+

+typedef struct {

+  UINT16                    Count;

+  EFI_OEM_INT_DATA_ELEMENT  OemIntDataElement[1];

+} EFI_OEM_INT_DATA;

+#pragma pack()

+

+typedef enum {

+  EfiGetPlatformBinaryMpTable      = 0,

+  EfiGetPlatformBinaryOemIntData   = 1,

+  EfiGetPlatformBinaryOem16Data    = 2,

+  EfiGetPlatformBinaryOem32Data    = 3,

+  EfiGetPlatformBinaryTpmBinary    = 4,

+  EfiGetPlatformBinarySystemRom    = 5,

+  EfiGetPlatformPciExpressBase     = 6,

+  EfiGetPlatformPmmSize            = 7,

+  EfiGetPlatformEndOpromShadowAddr = 8,

+

+} EFI_GET_PLATFORM_INFO_MODE;

+

+typedef enum {

+  EfiGetPlatformVgaHandle       = 0,

+  EfiGetPlatformIdeHandle       = 1,

+  EfiGetPlatformIsaBusHandle    = 2,

+  EfiGetPlatformUsbHandle       = 3

+} EFI_GET_PLATFORM_HANDLE_MODE;

+

+typedef enum {

+  EfiPlatformHookPrepareToScanRom = 0,

+  EfiPlatformHookShadowServiceRoms= 1,

+  EfiPlatformHookAfterRomInit     = 2

+} EFI_GET_PLATFORM_HOOK_MODE;

+

+/**

+  Finds the binary data or other platform information.

+

+  @param  This Protocol instance pointer.

+  @param  Mode Specifies what data to return

+  @param  Table Pointer to MP table.

+  @param  TableSize Size in bytes of table.

+  @param  Location Legacy region requested

+  0x00 = Any location

+  Bit 0 = 0xF0000 region

+  Bit 1 = 0xE0000 region

+  Multiple bits can be set

+  @param  Alignment Address alignment for allocation.

+  Bit mapped. First non-zero bit from right

+  is alignment.

+  @param  LegacySegment Segment in LegacyBios where Table is stored

+  @param  LegacyOffset Offset in LegacyBios where Table is stored

+

+  @retval  EFI_SUCCESS Data was returned successfully.

+  @retval  EFI_UNSUPPORTED Mode is not supported on the platform.

+  @retval  EFI_NOT_FOUND Binary image or table not found.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_GET_PLATFORM_INFO) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  IN EFI_GET_PLATFORM_INFO_MODE          Mode,

+  OUT VOID                               **Table,

+  OUT UINTN                              *TableSize,

+  OUT UINTN                              *Location,

+  OUT UINTN                              *Alignment,

+  IN  UINT16                             LegacySegment,

+  IN  UINT16                             LegacyOffset

+  )

+;

+

+/**

+  Returns a buffer of handles for the requested sub-function.

+

+  @param  This Protocol instance pointer.

+  @param  Mode Specifies what handle to return.

+  @param  Type Type from Device Path for Handle to represent.

+  @param  HandleBuffer Handles of the device/controller in priority order

+  with HandleBuffer[0] highest priority.

+  @param  HandleCount Number of handles in the buffer.

+  @param  AdditionalData Mode specific.

+

+  @retval  EFI_SUCCESS Handle is valid

+  @retval  EFI_UNSUPPORTED Mode is not supported on the platform.

+  @retval  EFI_NOT_FOUND Handle is not known

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_GET_PLATFORM_HANDLE) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  IN EFI_GET_PLATFORM_HANDLE_MODE        Mode,

+  IN UINT16                              Type,

+  OUT EFI_HANDLE                         **HandleBuffer,

+  OUT UINTN                              *HandleCount,

+  IN  VOID                               **AdditionalData OPTIONAL

+  )

+;

+

+/**

+  Load and initialize the Legacy BIOS SMM handler.

+

+  @param  This Protocol instance pointer.

+  @param  EfiToLegacy16BootTable Pointer to Legacy16 boot table.

+

+  @retval  EFI_SUCCESS SMM code loaded.

+  @retval  EFI_DEVICE_ERROR SMM code failed to load

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_SMM_INIT) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  IN  VOID                               *EfiToLegacy16BootTable

+  )

+;

+

+/**

+  Allows platform to perform any required action after a LegacyBios operation.

+

+  @param  This Protocol instance pointer.

+  @param  Mode Specifies what handle to return.

+  @param  Type Mode specific.

+  @param  DeviceHandle List of PCI devices in the system.

+  @param  ShadowAddress First free OpROM area, after other OpROMs have been dispatched.

+  @param  Compatibility16Table Pointer to Compatibility16Table.

+  @param  AdditionalData Mode specific Pointer to additional data returned ¨C mode specific.

+

+  @retval  EFI_SUCCESS RomImage is valid

+  @retval  EFI_UNSUPPORTED Mode is not supported on the platform.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_HOOKS) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  IN EFI_GET_PLATFORM_HOOK_MODE          Mode,

+  IN UINT16                              Type,

+  IN  EFI_HANDLE                         DeviceHandle,

+  IN  OUT UINTN                          *ShadowAddress,

+  IN  EFI_COMPATIBILITY16_TABLE          *Compatibility16Table,

+  IN  VOID                               **AdditionalData OPTIONAL

+  )

+;

+

+/**

+  Returns information associated with PCI IRQ routing.

+

+  @param  This Protocol instance pointer.

+  @param  RoutingTable Pointer to PCI IRQ Routing table.

+  @param  RoutingTableEntries Number of entries in table.

+  @param  LocalPirqTable $PIR table

+  @param  PirqTableSize $PIR table size

+  @param  LocalIrqPriorityTable List of interrupts in priority order to assign

+  @param  IrqPriorityTableEntries- Number of entries in priority table

+

+  @retval  EFI_SUCCESS Data was successfully returned.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_GET_ROUTING_TABLE) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  OUT VOID                               **RoutingTable,

+  OUT UINTN                              *RoutingTableEntries,

+  OUT VOID                               **LocalPirqTable, OPTIONAL

+  OUT UINTN                              *PirqTableSize, OPTIONAL

+  OUT VOID                               **LocalIrqPriorityTable, OPTIONAL

+  OUT UINTN                              *IrqPriorityTableEntries OPTIONAL

+  )

+;

+

+/**

+  Translates the given PIRQ accounting for bridge

+

+  @param  This Protocol instance pointer.

+  @param  PciBus PCI bus number for this device.

+  @param  PciDevice PCI device number for this device.

+  @param  PciFunction PCI function number for this device.

+  @param  Pirq Input is PIRQ reported by device, output is true PIRQ.

+  @param  PciIrq The IRQ already assigned to the PIRQ or the IRQ to be

+  assigned to the PIRQ.

+

+  @retval  EFI_SUCCESS The PIRQ was translated.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_TRANSLATE_PIRQ) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  IN  UINTN                              PciBus,

+  IN  UINTN                              PciDevice,

+  IN  UINTN                              PciFunction,

+  IN  OUT UINT8                          *Pirq,

+  OUT UINT8                              *PciIrq

+  )

+;

+

+/**

+  Attempt to legacy boot the BootOption. If the EFI contexted has been 

+  compromised this function will not return.

+

+  @param  This Protocol instance pointer.

+  @param  BbsDevicePath EFI Device Path from BootXXXX variable.

+  @param  BbsTable Internal BBS table.

+  @param  LoadOptionSize Size of LoadOption in size.

+  @param  LoadOption LoadOption from BootXXXX variable

+  @param  EfiToLegacy16BootTable Pointer to BootTable structure

+

+  @retval  EFI_SUCCESS Ready to boot.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_BIOS_PLATFORM_PREPARE_TO_BOOT) (

+  IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL   *This,

+  IN  BBS_BBS_DEVICE_PATH                *BbsDevicePath,

+  IN  VOID                               *BbsTable,

+  IN  UINT32                             LoadOptionsSize,

+  IN  VOID                               *LoadOptions,

+  IN  VOID                               *EfiToLegacy16BootTable

+  )

+;

+

+/**

+  @par Protocol Description:

+  Abstracts the platform portion of the traditional BIOS. 

+

+  @param GetPlatformInfo

+  Gets binary data or other platform information.

+

+  @param GetPlatformHandle

+  Returns a buffer of all handles matching the requested subfunction. 

+

+  @param SmmInit

+  Loads and initializes the traditional BIOS SMM handler.

+

+  @param PlatformHooks

+  Allows platform to perform any required actions after a LegacyBios operation.

+

+  @param GetRoutingTable

+  Gets $PIR table. 

+

+  @param TranslatePirq 

+  Translates the given PIRQ to the final value after traversing any PCI bridges. 

+

+  @param PrepareToBoot

+  Final platform function before the system attempts to boot to a traditional OS. 

+

+**/

+struct _EFI_LEGACY_BIOS_PLATFORM_PROTOCOL {

+  EFI_LEGACY_BIOS_PLATFORM_GET_PLATFORM_INFO    GetPlatformInfo;

+  EFI_LEGACY_BIOS_PLATFORM_GET_PLATFORM_HANDLE  GetPlatformHandle;

+  EFI_LEGACY_BIOS_PLATFORM_SMM_INIT             SmmInit;

+  EFI_LEGACY_BIOS_PLATFORM_HOOKS                PlatformHooks;

+  EFI_LEGACY_BIOS_PLATFORM_GET_ROUTING_TABLE    GetRoutingTable;

+  EFI_LEGACY_BIOS_PLATFORM_TRANSLATE_PIRQ       TranslatePirq;

+  EFI_LEGACY_BIOS_PLATFORM_PREPARE_TO_BOOT      PrepareToBoot;

+};

+

+extern EFI_GUID gEfiLegacyBiosPlatformProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/LegacyInterrupt.h b/edk2/MdePkg/Include/Protocol/LegacyInterrupt.h
new file mode 100644
index 0000000..54dc9aa
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/LegacyInterrupt.h
@@ -0,0 +1,131 @@
+/** @file

+  This protocol manages the legacy memory regions between 0xc0000 - 0xfffff

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.    

+

+  Module Name:  LegacyInterrupt.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework for EFI Compatibility Support Module spec

+  Version 0.96

+

+**/

+

+#ifndef _EFI_LEGACY_INTERRUPT_H_

+#define _EFI_LEGACY_INTERRUPT_H_

+

+#define EFI_LEGACY_INTERRUPT_PROTOCOL_GUID \

+  { \

+    0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe } \

+  }

+

+typedef struct _EFI_LEGACY_INTERRUPT_PROTOCOL EFI_LEGACY_INTERRUPT_PROTOCOL;

+

+/**

+  Get the number of PIRQs this hardware supports.

+

+  @param  This Protocol instance pointer.

+  @param  NumberPirsq Number of PIRQs.

+

+  @retval  EFI_SUCCESS Number of PIRQs returned.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS) (

+  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,

+  OUT UINT8                                   *NumberPirqs

+  );

+

+/**

+  Gets the PCI location associated with this protocol.

+

+  @param  This Protocol instance pointer.

+  @param  Bus PCI Bus

+  @param  Device PCI Device

+  @param  Function PCI Function

+

+  @retval  EFI_SUCCESS Bus/Device/Function returned

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_INTERRUPT_GET_LOCATION) (

+  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,

+  OUT UINT8                                   *Bus,

+  OUT UINT8                                   *Device,

+  OUT UINT8                                   *Function

+  );

+

+/**

+  Read the PIRQ register and return the data

+

+  @param  This Protocol instance pointer.

+  @param  PirqNumber PIRQ register to read

+  @param  PirqData Data read

+

+  @retval  EFI_SUCCESS Data was read

+  @retval  EFI_INVALID_PARAMETER Invalid PIRQ number

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_INTERRUPT_READ_PIRQ) (

+  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,

+  IN  UINT8                                  PirqNumber,

+  OUT UINT8                                  *PirqData

+  );

+

+/**

+  Write the specified PIRQ register with the given data.

+

+  @param  This Protocol instance pointer.

+  @param  PirqNumber PIRQ register to read.

+  @param  PirqData Data written.

+

+  @retval  EFI_SUCCESS Table pointer returned

+  @retval  EFI_INVALID_PARAMETER Invalid PIRQ number

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_INTERRUPT_WRITE_PIRQ) (

+  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,

+  IN  UINT8                                  PirqNumber,

+  IN UINT8                                   PirqData

+  );

+

+/**

+  @par Protocol Description:

+  Abstracts the PIRQ programming from the generic EFI Compatibility Support Modules

+

+  @param GetNumberPirqs

+  Gets the number of PIRQs supported.

+

+  @param GetLocation

+  Gets the PCI bus, device, and function that associated with this protocol. 

+

+  @param ReadPirq

+  Reads the indicated PIRQ register.

+

+  @param WritePirq

+  Writes to the indicated PIRQ register. 

+

+**/

+struct _EFI_LEGACY_INTERRUPT_PROTOCOL {

+  EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS GetNumberPirqs;

+  EFI_LEGACY_INTERRUPT_GET_LOCATION     GetLocation;

+  EFI_LEGACY_INTERRUPT_READ_PIRQ        ReadPirq;

+  EFI_LEGACY_INTERRUPT_WRITE_PIRQ       WritePirq;

+};

+

+extern EFI_GUID gEfiLegacyInterruptProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/LegacyRegion.h b/edk2/MdePkg/Include/Protocol/LegacyRegion.h
new file mode 100644
index 0000000..db7d346
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/LegacyRegion.h
@@ -0,0 +1,152 @@
+/** @file

+  This protocol manages the legacy memory regions between 0xc0000 - 0xfffff

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.    

+

+  Module Name:  LegacyRegion.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework for EFI Compatibility Support Module spec

+  Version 0.96

+

+**/

+

+#ifndef _EFI_LEGACY_REGION_H_

+#define _EFI_LEGACY_REGION_H_

+

+#define EFI_LEGACY_REGION_PROTOCOL_GUID \

+  { \

+    0xfc9013a, 0x568, 0x4ba9, {0x9b, 0x7e, 0xc9, 0xc3, 0x90, 0xa6, 0x60, 0x9b } \

+  }

+

+typedef struct _EFI_LEGACY_REGION_PROTOCOL EFI_LEGACY_REGION_PROTOCOL;

+

+/**

+  Sets hardware to decode or not decode a region.

+

+  @param  This Indicates the EFI_LEGACY_REGION_PROTOCOL instance

+  

+  @param  Start Start of region to decode.

+  

+  @param  Length Size in bytes of the region.

+  

+  @param  On Decode/nondecode flag.

+

+  @retval EFI_SUCCESS Decode range successfully changed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_REGION_DECODE) (

+  IN EFI_LEGACY_REGION_PROTOCOL           *This,

+  IN  UINT32                              Start,

+  IN  UINT32                              Length,

+  IN  BOOLEAN                             *On

+  );

+

+/**

+  Sets a region to read only.

+

+  @param  This Indicates the EFI_LEGACY_REGION_PROTOCOL instance

+  

+  @param  Start Start of region to lock.

+  

+  @param  Length Size in bytes of the region.

+  

+  @param  Granularity Lock attribute affects this granularity in bytes.

+

+  @retval EFI_SUCCESS The region was made read only.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_REGION_LOCK) (

+  IN EFI_LEGACY_REGION_PROTOCOL           *This,

+  IN  UINT32                              Start,

+  IN  UINT32                              Length,

+  OUT UINT32                              *Granularity OPTIONAL

+  );

+

+/**

+  Sets a region to read only and ensures that flash is locked from being 

+  inadvertently modified.

+

+  @param  This Indicates the EFI_LEGACY_REGION_PROTOCOL instance

+  

+  @param  Start Start of region to lock.

+  

+  @param  Length Size in bytes of the region.

+  

+  @param  Granularity Lock attribute affects this granularity in bytes.

+

+  @retval EFI_SUCCESS The region was made read only and flash is locked.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_REGION_BOOT_LOCK) (

+  IN EFI_LEGACY_REGION_PROTOCOL           *This,

+  IN  UINT32                              Start,

+  IN  UINT32                              Length,

+  OUT UINT32                              *Granularity OPTIONAL

+  );

+

+/**

+  Sets a region to read-write.

+

+  @param  This Indicates the EFI_LEGACY_REGION_PROTOCOL instance

+  

+  @param  Start Start of region to lock.

+  

+  @param  Length Size in bytes of the region.

+  

+  @param  Granularity Lock attribute affects this granularity in bytes.

+

+  @retval EFI_SUCCESS The region was successfully made read-write.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LEGACY_REGION_UNLOCK) (

+  IN EFI_LEGACY_REGION_PROTOCOL           *This,

+  IN  UINT32                              Start,

+  IN  UINT32                              Length,

+  OUT UINT32                              *Granularity OPTIONAL

+  );

+

+/**

+  @par Protocol Description:

+  Abstracts the hardware control of the physical address region 0xC0000¨C0xFFFFF 

+  for the traditional BIOS.

+

+  @param Decode

+  Specifies a region for the chipset to decode

+

+  @param Lock

+  Makes the specified OpROM region read only or locked.

+

+  @param BootLock

+  Sets a region to read only and ensures tat flash is locked from 

+  inadvertent modification.

+

+  @param Unlock

+  Makes the specified OpROM region read-write or unlocked. 

+

+**/

+struct _EFI_LEGACY_REGION_PROTOCOL {

+  EFI_LEGACY_REGION_DECODE    Decode;

+  EFI_LEGACY_REGION_LOCK      Lock;

+  EFI_LEGACY_REGION_BOOT_LOCK BootLock;

+  EFI_LEGACY_REGION_UNLOCK    UnLock;

+};

+

+extern EFI_GUID gEfiLegacyRegionProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/LoadFile.h b/edk2/MdePkg/Include/Protocol/LoadFile.h
new file mode 100644
index 0000000..346039f
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/LoadFile.h
@@ -0,0 +1,83 @@
+/** @file

+  Load File protocol as defined in the EFI 1.0 specification.

+

+  Load file protocol exists to supports the addition of new boot devices, 

+  and to support booting from devices that do not map well to file system. 

+  Network boot is done via a LoadFile protocol.

+

+  EFI 1.0 can boot from any device that produces a LoadFile protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  LoadFile.h

+

+**/

+

+#ifndef __EFI_LOAD_FILE_PROTOCOL_H__

+#define __EFI_LOAD_FILE_PROTOCOL_H__

+

+#define LOAD_FILE_PROTOCOL_GUID \

+  { \

+    0x56EC3091, 0x954C, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \

+  }

+

+//

+// Protocol Guid Name defined by UEFI 2.0 spec.

+//

+#define EFI_LOAD_FILE_PROTOCOL_GUID LOAD_FILE_PROTOCOL_GUID

+

+typedef struct _EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL;

+

+/**

+  Causes the driver to load a specified file.

+

+  @param  This       Protocol instance pointer.

+  @param  FilePath   The device specific path of the file to load.

+  @param  BootPolicy If TRUE, indicates that the request originates from the

+                     boot manager is attempting to load FilePath as a boot

+                     selection. If FALSE, then FilePath must match as exact file

+                     to be loaded.

+  @param  BufferSize On input the size of Buffer in bytes. On output with a return

+                     code of EFI_SUCCESS, the amount of data transferred to

+                     Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,

+                     the size of Buffer required to retrieve the requested file.

+  @param  Buffer     The memory buffer to transfer the file to. IF Buffer is NULL,

+                     then no the size of the requested file is returned in

+                     BufferSize.

+

+  @retval EFI_SUCCESS           The file was loaded.

+  @retval EFI_UNSUPPORTED       The device does not support the provided BootPolicy

+  @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or

+                                BufferSize is NULL.

+  @retval EFI_NO_MEDIA          No medium was present to load the file.

+  @retval EFI_DEVICE_ERROR      The file was not loaded due to a device error.

+  @retval EFI_NO_RESPONSE       The remote system did not respond.

+  @retval EFI_NOT_FOUND         The file was not found

+  @retval EFI_ABORTED           The file load process was manually cancelled.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LOAD_FILE) (

+  IN EFI_LOAD_FILE_PROTOCOL           *This,

+  IN EFI_DEVICE_PATH_PROTOCOL         *FilePath,

+  IN BOOLEAN                          BootPolicy,

+  IN OUT UINTN                        *BufferSize,

+  IN VOID                             *Buffer OPTIONAL

+  )

+;

+

+struct _EFI_LOAD_FILE_PROTOCOL {

+  EFI_LOAD_FILE LoadFile;

+};

+

+extern EFI_GUID gEfiLoadFileProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/LoadedImage.h b/edk2/MdePkg/Include/Protocol/LoadedImage.h
new file mode 100644
index 0000000..aee063c
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/LoadedImage.h
@@ -0,0 +1,69 @@
+/** @file

+  EFI 1.0 Loaded image protocol definition.

+

+  Every EFI driver and application is passed an image handle when it is loaded.

+  This image handle will contain a Loaded Image Protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  LoadedImage.h

+

+**/

+

+#ifndef __LOADED_IMAGE_PROTOCOL_H__

+#define __LOADED_IMAGE_PROTOCOL_H__

+

+#define EFI_LOADED_IMAGE_PROTOCOL_GUID \

+  { \

+    0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \

+  }

+

+//

+// EFI_SYSTEM_TABLE & EFI_IMAGE_UNLOAD are defined in EfiApi.h

+//

+#define EFI_LOADED_IMAGE_INFORMATION_REVISION 0x1000

+#define EFI_LOADED_IMAGE_PROTOCOL_REVISION    EFI_LOADED_IMAGE_INFORMATION_REVISION

+

+typedef struct {

+  UINT32                    Revision;

+  EFI_HANDLE                ParentHandle;

+  EFI_SYSTEM_TABLE          *SystemTable;

+

+  //

+  // Source location of image

+  //

+  EFI_HANDLE                DeviceHandle;

+  EFI_DEVICE_PATH_PROTOCOL  *FilePath;

+  VOID                      *Reserved;

+

+  //

+  // Images load options

+  //

+  UINT32                    LoadOptionsSize;

+  VOID                      *LoadOptions;

+

+  //

+  // Location of where image was loaded

+  //

+  VOID                      *ImageBase;

+  UINT64                    ImageSize;

+  EFI_MEMORY_TYPE           ImageCodeType;

+  EFI_MEMORY_TYPE           ImageDataType;

+

+  //

+  // If the driver image supports a dynamic unload request

+  //

+  EFI_IMAGE_UNLOAD          Unload;

+

+} EFI_LOADED_IMAGE_PROTOCOL;

+

+extern EFI_GUID gEfiLoadedImageProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/ManagedNetwork.h b/edk2/MdePkg/Include/Protocol/ManagedNetwork.h
new file mode 100644
index 0000000..1bf9a13
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/ManagedNetwork.h
@@ -0,0 +1,314 @@
+/** @file

+  EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0.

+  EFI_MANAGED_NETWORK_PROTOCOL as defined in UEFI 2.0.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ManagedNetwork.h

+

+**/

+

+#ifndef _EFI_MANAGED_NETWORK_PROTOCOL_H

+#define _EFI_MANAGED_NETWORK_PROTOCOL_H

+

+#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c } \

+  }

+

+#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \

+  { \

+    0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x7, 0x8, 0x92, 0xe0, 0x5e } \

+  }

+

+typedef struct _EFI_MANAGED_NETWORK_PROTOCOL EFI_MANAGED_NETWORK_PROTOCOL;

+

+typedef struct {

+  UINT32     ReceivedQueueTimeoutValue;

+  UINT32     TransmitQueueTimeoutValue;

+  UINT16     ProtocolTypeFilter;

+  BOOLEAN    EnableUnicastReceive;

+  BOOLEAN    EnableMulticastReceive;

+  BOOLEAN    EnableBroadcastReceive;

+  BOOLEAN    EnablePromiscuousReceive;

+  BOOLEAN    FlushQueuesOnReset;

+  BOOLEAN    EnableReceiveTimestamps;

+  BOOLEAN    DisableBackgroundPolling;

+} EFI_MANAGED_NETWORK_CONFIG_DATA;

+

+typedef struct {

+  EFI_TIME      Timestamp;

+  EFI_EVENT     RecycleEvent;

+  UINT32        PacketLength;

+  UINT32        HeaderLength;

+  UINT32        AddressLength;

+  UINT32        DataLength;

+  BOOLEAN       BroadcastFlag;

+  BOOLEAN       MulticastFlag;

+  BOOLEAN       PromiscuousFlag;

+  UINT16        ProtocolType;

+  VOID          *DestinationAddress;

+  VOID          *SourceAddress;

+  VOID          *MediaHeader;

+  VOID          *PacketData;

+} EFI_MANAGED_NETWORK_RECEIVE_DATA;

+

+typedef struct {

+  UINT32        FragmentLength;

+  VOID          *FragmentBuffer;

+} EFI_MANAGED_NETWORK_FRAGMENT_DATA;

+

+typedef struct {

+  EFI_MAC_ADDRESS                   *DestinationAddress; //OPTIONAL

+  EFI_MAC_ADDRESS                   *SourceAddress;      //OPTIONAL

+  UINT16                            ProtocolType;        //OPTIONAL

+  UINT32                            DataLength;

+  UINT16                            HeaderLength;        //OPTIONAL

+  UINT16                            FragmentCount;

+  EFI_MANAGED_NETWORK_FRAGMENT_DATA FragmentTable[1];

+} EFI_MANAGED_NETWORK_TRANSMIT_DATA;

+

+

+typedef struct {

+  EFI_EVENT                             Event;

+  EFI_STATUS                            Status;

+  union {

+    EFI_MANAGED_NETWORK_RECEIVE_DATA    *RxData;

+    EFI_MANAGED_NETWORK_TRANSMIT_DATA   *TxData;

+  } Packet;

+} EFI_MANAGED_NETWORK_COMPLETION_TOKEN;

+

+/**

+  Returns the operational parameters for the current MNP child driver.

+

+  @param  This          Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  MnpConfigData Pointer to storage for MNP operational parameters.

+  @param  SnpModeData   Pointer to storage for SNP operational parameters.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this MNP implementation.

+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been configured. The default

+                                values are returned in MnpConfigData if it is not NULL.

+  @retval Other                 The mode data could not be read.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_GET_MODE_DATA) (

+  IN  EFI_MANAGED_NETWORK_PROTOCOL     *This,

+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData  OPTIONAL,

+  OUT EFI_SIMPLE_NETWORK_MODE          *SnpModeData    OPTIONAL 

+  )

+;  

+

+/**

+  Sets or clears the operational parameters for the MNP child driver.

+

+  @param  This          Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  MnpConfigData Pointer to configuration data that will be assigned to the MNP

+                        child driver instance. If NULL, the MNP child driver instance is

+                        reset to startup defaults and all pending transmit and receive

+                        requests are flushed.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources (usually memory) could not be

+                                allocated.

+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this [MNP]

+                                implementation.

+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.

+  @retval Other                 The MNP child driver instance has been reset to startup defaults.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_CONFIGURE) (

+  IN EFI_MANAGED_NETWORK_PROTOCOL     *This,

+  IN EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData  OPTIONAL 

+  )

+;    

+    

+/**

+  Translates an IP multicast address to a hardware (MAC) multicast address.

+

+  @param  This       Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  Ipv6Flag   Set to TRUE to if IpAddress is an IPv6 multicast address.

+                     Set to FALSE if IpAddress is an IPv4 multicast address.

+  @param  IpAddress  Pointer to the multicast IP address (in network byte order) to convert.

+  @param  MacAddress Pointer to the resulting multicast MAC address.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER One of the following conditions is TRUE:

+                                - This is NULL.

+                                - IpAddress is NULL.

+                                - *IpAddress is not a valid multicast IP address.

+                                - MacAddress is NULL.

+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been configured.

+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this MNP implementation.

+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.

+  @retval Other                 The address could not be converted.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_MCAST_IP_TO_MAC) (

+  IN  EFI_MANAGED_NETWORK_PROTOCOL  *This,

+  IN  BOOLEAN                       Ipv6Flag,

+  IN  EFI_IP_ADDRESS                *IpAddress,

+  OUT EFI_MAC_ADDRESS               *MacAddress 

+  )

+;      

+

+/**

+  Enables and disables receive filters for multicast address.

+

+  @param  This       Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  JoinFlag   Set to TRUE to join this multicast group.

+                     Set to FALSE to leave this multicast group.

+  @param  MacAddress Pointer to the multicast MAC group (address) to join or leave.

+

+  @retval EFI_SUCCESS           The requested operation completed successfully.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - This is NULL.

+                                - JoinFlag is TRUE and MacAddress is NULL.

+                                - *MacAddress is not a valid multicast MAC address.

+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been configured.

+  @retval EFI_ALREADY_STARTED   The supplied multicast group is already joined.

+  @retval EFI_NOT_FOUND         The supplied multicast group is not joined.

+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.  

+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this MNP implementation.

+  @retval Other                 The requested operation could not be completed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_GROUPS) (

+  IN EFI_MANAGED_NETWORK_PROTOCOL  *This,

+  IN BOOLEAN                       JoinFlag,

+  IN EFI_MAC_ADDRESS               *MacAddress  OPTIONAL 

+  )

+;      

+  

+/**

+  Places asynchronous outgoing data packets into the transmit queue.

+

+  @param  This  Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  Token Pointer to a token associated with the transmit data descriptor.

+

+  @retval EFI_SUCCESS           The transmit completion token was cached.

+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been configured.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_ACCESS_DENIED     The transmit completion token is already in the transmit queue.

+  @retval EFI_OUT_OF_RESOURCES  The transmit data could not be queued due to a lack of system resources

+                                (usually memory).

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval EFI_NOT_READY         The transmit request could not be queued because the transmit queue is full.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_TRANSMIT) (

+  IN EFI_MANAGED_NETWORK_PROTOCOL          *This,

+  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token 

+  )

+;      

+    

+/**

+  Places an asynchronous receiving request into the receiving queue.

+

+  @param  This  Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  Token Pointer to a token associated with the receive data descriptor.

+

+  @retval EFI_SUCCESS           The receive completion token was cached.

+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been configured.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - This is NULL.

+                                - Token is NULL.

+                                - Token.Event is NULL

+  @retval EFI_OUT_OF_RESOURCES  The transmit data could not be queued due to a lack of system resources

+                                (usually memory).

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval EFI_ACCESS_DENIED     The receive completion token was already in the receive queue.

+  @retval EFI_NOT_READY         The receive request could not be queued because the receive queue is full.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_RECEIVE) (

+  IN EFI_MANAGED_NETWORK_PROTOCOL          *This,

+  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token 

+  )

+;      

+   

+

+/**

+  Aborts an asynchronous transmit or receive request.

+

+  @param  This  Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+  @param  Token Pointer to a token that has been issued by

+                EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or

+                EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If

+                NULL, all pending tokens are aborted.

+

+  @retval  EFI_SUCCESS           The asynchronous I/O request was aborted and Token.Event

+                                 was signaled. When Token is NULL, all pending requests were

+                                 aborted and their events were signaled.

+  @retval  EFI_NOT_STARTED       This MNP child driver instance has not been configured.

+  @retval  EFI_INVALID_PARAMETER This is NULL.

+  @retval  EFI_NOT_FOUND         When Token is not NULL, the asynchronous I/O request was

+                                 not found in the transmit or receive queue. It has either completed

+                                 or was not issued by Transmit() and Receive().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_CANCEL) (

+  IN EFI_MANAGED_NETWORK_PROTOCOL          *This,

+  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token  OPTIONAL 

+  )

+;   

+

+/**

+  Polls for incoming data packets and processes outgoing data packets.

+

+  @param  This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

+

+  @retval EFI_SUCCESS      Incoming or outgoing data was processed.

+  @retval EFI_NOT_STARTED  This MNP child driver instance has not been configured.

+  @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.

+  @retval EFI_NOT_READY    No incoming or outgoing data was processed. Consider increasing

+                           the polling rate.

+  @retval EFI_TIMEOUT      Data was dropped out of the transmit and/or receive queue.

+                            Consider increasing the polling rate.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MANAGED_NETWORK_POLL) (

+  IN EFI_MANAGED_NETWORK_PROTOCOL    *This 

+  )

+;     

+

+struct _EFI_MANAGED_NETWORK_PROTOCOL {

+  EFI_MANAGED_NETWORK_GET_MODE_DATA       GetModeData;

+  EFI_MANAGED_NETWORK_CONFIGURE           Configure;

+  EFI_MANAGED_NETWORK_MCAST_IP_TO_MAC     McastIpToMac;

+  EFI_MANAGED_NETWORK_GROUPS              Groups;

+  EFI_MANAGED_NETWORK_TRANSMIT            Transmit;

+  EFI_MANAGED_NETWORK_RECEIVE             Receive;

+  EFI_MANAGED_NETWORK_CANCEL              Cancel;

+  EFI_MANAGED_NETWORK_POLL                Poll;

+};

+

+extern EFI_GUID gEfiManagedNetworkServiceBindingProtocolGuid;

+extern EFI_GUID gEfiManagedNetworkProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Mtftp4.h b/edk2/MdePkg/Include/Protocol/Mtftp4.h
new file mode 100644
index 0000000..840e04b
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Mtftp4.h
@@ -0,0 +1,508 @@
+/** @file

+  EFI Multicast Trivial File Tranfer Protocol Definition

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Mtftp4.h

+

+**/

+

+#ifndef __EFI_MTFTP4_PROTOCOL_H__

+#define __EFI_MTFTP4_PROTOCOL_H__

+

+#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F } \

+  }

+

+#define EFI_MTFTP4_PROTOCOL_GUID \

+  { \

+    0x3ad9df29, 0x4501, 0x478d, {0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3 } \

+  }

+

+typedef struct _EFI_MTFTP4_PROTOCOL EFI_MTFTP4_PROTOCOL;

+typedef struct _EFI_MTFTP4_TOKEN EFI_MTFTP4_TOKEN;

+

+//

+//MTFTP4 packet opcode definition

+//

+#define EFI_MTFTP4_OPCODE_RRQ                     1

+#define EFI_MTFTP4_OPCODE_WRQ                     2

+#define EFI_MTFTP4_OPCODE_DATA                    3

+#define EFI_MTFTP4_OPCODE_ACK                     4

+#define EFI_MTFTP4_OPCODE_ERROR                   5

+#define EFI_MTFTP4_OPCODE_OACK                    6

+#define EFI_MTFTP4_OPCODE_DIR                     7

+#define EFI_MTFTP4_OPCODE_DATA8                   8

+#define EFI_MTFTP4_OPCODE_ACK8                    9

+

+//

+// MTFTP4 error code definition

+//

+#define EFI_MTFTP4_ERRORCODE_NOT_DEFINED          0

+#define EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND       1

+#define EFI_MTFTP4_ERRORCODE_ACCESS_VIOLATION     2

+#define EFI_MTFTP4_ERRORCODE_DISK_FULL            3

+#define EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION    4

+#define EFI_MTFTP4_ERRORCODE_UNKNOWN_TRANSFER_ID  5

+#define EFI_MTFTP4_ERRORCODE_FILE_ALREADY_EXISTS  6

+#define EFI_MTFTP4_ERRORCODE_NO_SUCH_USER         7

+#define EFI_MTFTP4_ERRORCODE_REQUEST_DENIED       8

+

+//

+// MTFTP4 pacekt definitions

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT8                   Filename[1];

+} EFI_MTFTP4_REQ_HEADER;

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT8                   Data[1];

+} EFI_MTFTP4_OACK_HEADER;

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT16                  Block;

+  UINT8                   Data[1];

+} EFI_MTFTP4_DATA_HEADER;

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT16                  Block[1];

+} EFI_MTFTP4_ACK_HEADER;

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT64                  Block;

+  UINT8                   Data[1];

+} EFI_MTFTP4_DATA8_HEADER;

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT64                  Block[1];

+} EFI_MTFTP4_ACK8_HEADER;

+

+typedef struct {

+  UINT16                  OpCode;

+  UINT16                  ErrorCode;

+  UINT8                   ErrorMessage[1];

+} EFI_MTFTP4_ERROR_HEADER;

+

+typedef union {

+  UINT16                  OpCode;

+  EFI_MTFTP4_REQ_HEADER   Rrq;

+  EFI_MTFTP4_REQ_HEADER   Wrq;

+  EFI_MTFTP4_OACK_HEADER  Oack;

+  EFI_MTFTP4_DATA_HEADER  Data;

+  EFI_MTFTP4_ACK_HEADER   Ack;

+  EFI_MTFTP4_DATA8_HEADER Data8;

+  EFI_MTFTP4_ACK8_HEADER  Ack8;

+  EFI_MTFTP4_ERROR_HEADER Error;

+} EFI_MTFTP4_PACKET;

+

+#pragma pack()

+

+//

+// MTFTP4 option definition

+//

+typedef struct {

+  UINT8                   *OptionStr;

+  UINT8                   *ValueStr;

+} EFI_MTFTP4_OPTION;

+

+

+typedef struct {

+  BOOLEAN                 UseDefaultSetting;

+  EFI_IPv4_ADDRESS        StationIp;

+  EFI_IPv4_ADDRESS        SubnetMask;

+  UINT16                  LocalPort;

+  EFI_IPv4_ADDRESS        GatewayIp;

+  EFI_IPv4_ADDRESS        ServerIp;

+  UINT16                  InitialServerPort;

+  UINT16                  TryCount;

+  UINT16                  TimeoutValue;

+} EFI_MTFTP4_CONFIG_DATA;

+

+

+typedef struct {

+  EFI_MTFTP4_CONFIG_DATA  ConfigData;

+  UINT8                   SupportedOptionCount;  

+  UINT8                   **SupportedOptoins;

+  UINT8                   UnsupportedOptionCount;  

+  UINT8                   **UnsupportedOptoins;

+} EFI_MTFTP4_MODE_DATA;

+

+

+typedef struct {

+  EFI_IPv4_ADDRESS        GatewayIp;

+  EFI_IPv4_ADDRESS        ServerIp;

+  UINT16                  ServerPort;

+  UINT16                  TryCount;

+  UINT16                  TimeoutValue;

+} EFI_MTFTP4_OVERRIDE_DATA;

+

+//

+// Protocol interfaces definition

+//

+

+/**

+  a callback function that is provided by the caller to intercept               

+  the EFI_MTFTP4_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the

+  EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept       

+  EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to    

+  EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().                   

+

+  @param  This        Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  Token       The token that the caller provided in the

+                      EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile()

+                      or ReadDirectory() function.

+  @param  PacketLen   Indicates the length of the packet.

+  @param  Packet      Pointer to an MTFTPv4 packet.

+

+  @retval EFI_SUCCESS Operation sucess

+  @retval Others      Abort transfer process

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_CHECK_PACKET)( 

+  IN EFI_MTFTP4_PROTOCOL  *This,

+  IN EFI_MTFTP4_TOKEN     *Token,

+  IN UINT16               PacketLen,

+  IN EFI_MTFTP4_PACKET    *Paket

+  )

+;

+

+/**

+  Timeout callback funtion.            

+

+  @param  This           Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  Token          The token that is provided in the

+                         EFI_MTFTP4_PROTOCOL.ReadFile() or

+                         EFI_MTFTP4_PROTOCOL.WriteFile() or

+                         EFI_MTFTP4_PROTOCOL.ReadDirectory() functions

+                         by the caller.

+                         

+  @retval EFI_SUCCESS   Operation sucess

+  @retval Others        Aborts download process.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_TIMEOUT_CALLBACK)( 

+  IN EFI_MTFTP4_PROTOCOL  *This,

+  IN EFI_MTFTP4_TOKEN     *Token

+  )

+;

+

+/**

+  a callback function that the caller provides to feed data to the

+  EFI_MTFTP4_PROTOCOL.WriteFile() function.

+

+  @param  This   Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  Token  The token provided in the

+                 EFI_MTFTP4_PROTOCOL.WriteFile() by the caller.

+  @param  Length Indicates the length of the raw data wanted on input, and the

+                 length the data available on output.

+  @param  Buffer Pointer to the buffer where the data is stored.

+

+  @retval EFI_SUCCESS Operation sucess

+  @retval Others      Aborts session.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_PACKET_NEEDED)( 

+  IN  EFI_MTFTP4_PROTOCOL *This,

+  IN  EFI_MTFTP4_TOKEN    *Token,

+  IN  OUT UINT16          *Length,

+  OUT VOID                **Buffer

+  )

+;

+

+

+/**

+  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.

+

+  @param  This     Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  ModeData Pointer to storage for the EFI MTFTPv4 Protocol driver mode data.

+

+  @retval EFI_SUCCESS           The configuration data was successfully returned.

+  @retval EFI_OUT_OF_RESOURCES  The required mode data could not be allocated.

+  @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_GET_MODE_DATA)(

+  IN  EFI_MTFTP4_PROTOCOL     *This,

+  OUT EFI_MTFTP4_MODE_DATA    *ModeData

+  )

+;

+

+

+/**

+  Initializes, changes, or resets the default operational setting for this 

+  EFI MTFTPv4 Protocol driver instance.

+

+  @param  This            Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  MtftpConfigData Pointer to the configuration data structure.

+

+  @retval EFI_SUCCESS           The EFI MTFTPv4 Protocol driver was configured successfully.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_ACCESS_DENIED     The EFI configuration could not be changed at this time because

+                                there is one MTFTP background operation in progress.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) has not finished yet.

+  @retval EFI_UNSUPPORTED       A configuration protocol (DHCP, BOOTP, RARP, etc.) could not

+                                be located when clients choose to use the default address

+                                settings.

+  @retval EFI_OUT_OF_RESOURCES  The EFI MTFTPv4 Protocol driver instance data could not be

+                                allocated.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred. The EFI

+                                 MTFTPv4 Protocol driver instance is not configured.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_CONFIGURE)(

+  IN EFI_MTFTP4_PROTOCOL       *This,

+  IN EFI_MTFTP4_CONFIG_DATA    *MtftpConfigData OPTIONAL

+  )

+;   

+    

+    

+/**

+  Gets information about a file from an MTFTPv4 server.

+

+  @param  This         Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  OverrideData Data that is used to override the existing parameters. If NULL,

+                       the default parameters that were set in the

+                       EFI_MTFTP4_PROTOCOL.Configure() function are used.

+  @param  Filename     Pointer to ASCIIZ file name string.

+  @param  ModeStr      Pointer to ASCIIZ mode string. If NULL, ¡°octet¡± will be used.

+  @param  OptionCount  Number of option/value string pairs in OptionList.

+  @param  OptionList   Pointer to array of option/value string pairs. Ignored if

+                       OptionCount is zero.

+  @param  PacketLength The number of bytes in the returned packet.

+  @param  Packet       The pointer to the received packet. This buffer must be freed by

+                       the caller.

+

+  @retval EFI_SUCCESS           An MTFTPv4 OACK packet was received and is in the Buffer.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_UNSUPPORTED       One or more options in the OptionList are in the

+                                unsupported list of structure EFI_MTFTP4_MODE_DATA.

+  

+  @retval EFI_NOT_STARTED       The EFI MTFTPv4 Protocol driver has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) has not finished yet.

+  @retval EFI_ACCESS_DENIED     The previous operation has not completed yet.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval EFI_TFTP_ERROR        An MTFTPv4 ERROR packet was received and is in the buffer.

+  @retval EFI_ICMP_ERROR        An ICMP ERROR packet was received and is in the Buffer.

+  @retval EFI_PROTOCOL_ERROR    An unexpected MTFTPv4 packet was received and is in the buffer.

+  @retval EFI_TIMEOUT           No responses were received from the MTFTPv4 server.

+  @retval EFI_DEVICE_ERROR      An unexpected network error or system error occurred.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_GET_INFO)(

+  IN  EFI_MTFTP4_PROTOCOL      *This,

+  IN  EFI_MTFTP4_OVERRIDE_DATA *OverrideData   OPTIONAL,

+  IN  UINT8                    *Filename,

+  IN  UINT8                    *ModeStr        OPTIONAL,

+  IN  UINT8                    OptionCount,

+  IN  EFI_MTFTP4_OPTION        *OptionList,

+  OUT UINT32                   *PacketLength,

+  OUT EFI_MTFTP4_PACKET        **Packet        OPTIONAL

+  )

+;

+

+/**

+  Parses the options in an MTFTPv4 OACK packet.

+

+  @param  This         Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  PacketLen    Length of the OACK packet to be parsed.

+  @param  Packet       Pointer to the OACK packet to be parsed.

+  @param  OptionCount  Pointer to the number of options in following OptionList.

+  @param  OptionList   Pointer to EFI_MTFTP4_OPTION storage. Call the EFI Boot

+                       Service FreePool() to release each option if they are not

+                       needed any more.

+

+  @retval EFI_SUCCESS           The OACK packet was valid and the OptionCount and

+                                OptionList parameters have been updated.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - PacketLen is 0.

+                                - Packet is NULL or Packet is not a valid MTFTPv4 packet.

+                                - OptionCount is NULL.

+  @retval EFI_NOT_FOUND         No options were found in the OACK packet.

+  @retval EFI_OUT_OF_RESOURCES  Storage for the OptionList array cannot be allocated.

+  @retval EFI_PROTOCOL_ERROR    One or more of the option fields is invalid.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_PARSE_OPTIONS)(

+  IN  EFI_MTFTP4_PROTOCOL      *This,

+  IN  UINT32                   PacketLen,

+  IN  EFI_MTFTP4_PACKET        *Packet,

+  OUT UINT32                   *OptionCount,

+  OUT EFI_MTFTP4_OPTION        **OptionList OPTIONAL

+  )

+;  

+

+

+/**

+  Downloads a file from an MTFTPv4 server.

+

+  @param  This  Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  Token Pointer to the token structure to provide the parameters that are

+                used in this operation.

+

+  @retval EFI_SUCCESS          The data file has been transferred successfully.

+  @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.

+  @retval EFI_BUFFER_TOO_SMALL BufferSize is not large enough to hold the downloaded data

+                               in downloading process.

+  @retval EFI_ABORTED          Current operation is aborted by user.

+  @retval EFI_ICMP_ERROR       An ICMP ERROR packet was received.

+  @retval EFI_TIMEOUT          No responses were received from the MTFTPv4 server.

+  @retval EFI_TFTP_ERROR       An MTFTPv4 ERROR packet was received.

+  @retval EFI_DEVICE_ERROR     An unexpected network error or system error occurred.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_READ_FILE)(

+  IN EFI_MTFTP4_PROTOCOL       *This,

+  IN EFI_MTFTP4_TOKEN          *Token

+  )

+;  

+  

+

+

+/**

+  Sends a file to an MTFTPv4 server.

+

+  @param  This Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  Token Pointer to the token structure to provide the parameters that are

+  used in this operation.

+

+  @retval EFI_SUCCESS           The upload session has started.

+  @retval EFI_UNSUPPORTED       The operation is not supported by this implementation.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_UNSUPPORTED       One or more options in the Token.OptionList are in

+                                the unsupported list of structure EFI_MTFTP4_MODE_DATA.

+  @retval EFI_NOT_STARTED       The EFI MTFTPv4 Protocol driver has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_ALREADY_STARTED   This Token is already being used in another MTFTPv4 session.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval EFI_ACCESS_DENIED     The previous operation has not completed yet.

+  @retval EFI_DEVICE_ERROR      An unexpected network error or system error occurred.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_WRITE_FILE)(

+  IN EFI_MTFTP4_PROTOCOL       *This,

+  IN EFI_MTFTP4_TOKEN          *Token

+  )

+;  

+  

+

+/**

+  Downloads a data file ¡°directory¡± from an MTFTPv4 server. May be unsupported in some EFI

+  implementations.                                                                                                                                                                                 

+

+  @param  This  Pointer to the EFI_MTFTP4_PROTOCOL instance.

+  @param  Token Pointer to the token structure to provide the parameters that are

+                used in this operation.

+

+  @retval EFI_SUCCESS           The MTFTPv4 related file "directory" has been downloaded.

+  @retval EFI_UNSUPPORTED       The operation is not supported by this implementation.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_UNSUPPORTED       One or more options in the Token.OptionList are in

+                                the unsupported list of structure EFI_MTFTP4_MODE_DATA.

+  @retval EFI_NOT_STARTED       The EFI MTFTPv4 Protocol driver has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_ALREADY_STARTED   This Token is already being used in another MTFTPv4 session.

+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

+  @retval EFI_ACCESS_DENIED     The previous operation has not completed yet.

+  @retval EFI_DEVICE_ERROR      An unexpected network error or system error occurred.

+

+**/

+typedef 

+EFI_STATUS 

+(EFIAPI *EFI_MTFTP4_READ_DIRECTORY)(

+  IN EFI_MTFTP4_PROTOCOL       *This,

+  IN EFI_MTFTP4_TOKEN          *Token

+  )

+;    

+

+/**

+  Polls for incoming data packets and processes outgoing data packets.

+

+  @param  This Pointer to the EFI_MTFTP4_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.

+  @retval  EFI_NOT_STARTED       This EFI MTFTPv4 Protocol instance has not been started.

+  @retval  EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                 RARP, etc.) is not finished yet.

+  @retval  EFI_INVALID_PARAMETER This is NULL.

+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval  EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.

+                                 Consider increasing the polling rate.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_MTFTP4_POLL) (

+  IN EFI_MTFTP4_PROTOCOL       *This

+  )

+;                                                                                                                 

+                                                                                                                  

+  

+struct _EFI_MTFTP4_PROTOCOL {

+  EFI_MTFTP4_GET_MODE_DATA     GetModeData;

+  EFI_MTFTP4_CONFIGURE         Configure;

+  EFI_MTFTP4_GET_INFO          GetInfo;

+  EFI_MTFTP4_PARSE_OPTIONS     ParseOptions;

+  EFI_MTFTP4_READ_FILE         ReadFile;

+  EFI_MTFTP4_WRITE_FILE        WriteFile;

+  EFI_MTFTP4_READ_DIRECTORY    ReadDirectory;

+  EFI_MTFTP4_POLL              Poll;

+};

+

+struct _EFI_MTFTP4_TOKEN {

+  OUT EFI_STATUS                  Status;

+  IN  EFI_EVENT                   Event;

+  IN  EFI_MTFTP4_OVERRIDE_DATA    *OverrideData;

+  IN  UINT8                       *Filename;

+  IN  UINT8                       *ModeStr;

+  IN  UINT32                      OptionCount;

+  IN  EFI_MTFTP4_OPTION           *OptionList;

+  IN  OUT UINT64                  BufferSize;

+  IN  OUT VOID                    *Buffer;

+  IN  EFI_MTFTP4_CHECK_PACKET     CheckPacket;

+  IN  EFI_MTFTP4_TIMEOUT_CALLBACK TimeoutCallback;

+  IN  EFI_MTFTP4_PACKET_NEEDED    PacketNeeded;

+};

+

+extern EFI_GUID gEfiMtftp4ServiceBindingProtocolGuid;

+extern EFI_GUID gEfiMtftp4ProtocolGuid;  

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Protocol/Pcd.h b/edk2/MdePkg/Include/Protocol/Pcd.h
new file mode 100644
index 0000000..3adac6d
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Pcd.h
@@ -0,0 +1,297 @@
+/** @file

+  Platform Configuration Database (PCD) Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Pcd.h

+

+**/

+

+#ifndef __PCD_H__

+#define __PCD_H__

+

+#include <Common/Pcd.h>

+

+extern EFI_GUID gPcdProtocolGuid;

+

+#define PCD_PROTOCOL_GUID \

+  { 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7 } }

+

+typedef 

+VOID

+(EFIAPI *PCD_PROTOCOL_SET_SKU) (

+  IN  SKU_ID                  SkuId

+  );

+

+typedef

+UINT8

+(EFIAPI *PCD_PROTOCOL_GET8) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT16

+(EFIAPI *PCD_PROTOCOL_GET16) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT32

+(EFIAPI *PCD_PROTOCOL_GET32) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT64

+(EFIAPI *PCD_PROTOCOL_GET64) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+VOID *

+(EFIAPI *PCD_PROTOCOL_GET_POINTER) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+BOOLEAN

+(EFIAPI *PCD_PROTOCOL_GET_BOOLEAN) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINTN

+(EFIAPI *PCD_PROTOCOL_GET_SIZE) (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT8

+(EFIAPI *PCD_PROTOCOL_GET_EX_8) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT16

+(EFIAPI *PCD_PROTOCOL_GET_EX_16) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT32

+(EFIAPI *PCD_PROTOCOL_GET_EX_32) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINT64

+(EFIAPI *PCD_PROTOCOL_GET_EX_64) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+VOID *

+(EFIAPI *PCD_PROTOCOL_GET_EX_POINTER) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+BOOLEAN

+(EFIAPI *PCD_PROTOCOL_GET_EX_BOOLEAN) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+UINTN

+(EFIAPI *PCD_PROTOCOL_GET_EX_SIZE) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET8) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET16) (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT16             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET32) (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT32             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET64) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_POINTER) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_BOOLEAN) (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_EX_8) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_EX_16) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_EX_32) (

+  IN CONST EFI_GUID     *Guid,

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT32             Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_EX_64) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_EX_POINTER) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_SET_EX_BOOLEAN) (

+  IN CONST EFI_GUID    *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  );

+  

+/**

+  Callback on SET function prototype definition.

+

+  @param[in]  CallBackGuid The PCD token GUID being set.

+  @param[in]  CallBackToken The PCD token number being set.

+  @param[in]  TokenData A pointer to the token data being set.

+  @param[in]  TokenDataSize The size, in bytes, of the data being set.

+

+  @retval VOID

+

+--*/

+typedef

+VOID

+(EFIAPI *PCD_PROTOCOL_CALLBACK) (

+  IN      CONST EFI_GUID   *CallBackGuid, OPTIONAL

+  IN      PCD_TOKEN_NUMBER            CallBackToken,

+  IN  OUT VOID             *TokenData,

+  IN      UINTN            TokenDataSize

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_CALLBACK_ONSET) (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_CANCEL_CALLBACK) (

+  IN  PCD_TOKEN_NUMBER        TokenNumber,

+  IN  CONST EFI_GUID          *Guid, OPTIONAL

+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction

+  );

+

+typedef 

+EFI_STATUS

+(EFIAPI *PCD_PROTOCOL_GET_NEXT_TOKEN) (

+  IN      CONST EFI_GUID      *Guid, OPTIONAL

+  IN OUT  PCD_TOKEN_NUMBER    *TokenNumber

+  );

+

+typedef struct {

+  PCD_PROTOCOL_SET_SKU              SetSku;

+

+  PCD_PROTOCOL_GET8                 Get8;

+  PCD_PROTOCOL_GET16                Get16;

+  PCD_PROTOCOL_GET32                Get32;

+  PCD_PROTOCOL_GET64                Get64;

+  PCD_PROTOCOL_GET_POINTER          GetPtr;

+  PCD_PROTOCOL_GET_BOOLEAN          GetBool;

+  PCD_PROTOCOL_GET_SIZE             GetSize;

+

+  PCD_PROTOCOL_GET_EX_8             Get8Ex;

+  PCD_PROTOCOL_GET_EX_16            Get16Ex;

+  PCD_PROTOCOL_GET_EX_32            Get32Ex;

+  PCD_PROTOCOL_GET_EX_64            Get64Ex;

+  PCD_PROTOCOL_GET_EX_POINTER       GetPtrEx;

+  PCD_PROTOCOL_GET_EX_BOOLEAN       GetBoolEx;

+  PCD_PROTOCOL_GET_EX_SIZE          GetSizeEx;

+

+  PCD_PROTOCOL_SET8                 Set8;

+  PCD_PROTOCOL_SET16                Set16;

+  PCD_PROTOCOL_SET32                Set32;

+  PCD_PROTOCOL_SET64                Set64;

+  PCD_PROTOCOL_SET_POINTER          SetPtr;

+  PCD_PROTOCOL_SET_BOOLEAN          SetBool;

+

+  PCD_PROTOCOL_SET_EX_8             Set8Ex;

+  PCD_PROTOCOL_SET_EX_16            Set16Ex;

+  PCD_PROTOCOL_SET_EX_32            Set32Ex;

+  PCD_PROTOCOL_SET_EX_64            Set64Ex;

+  PCD_PROTOCOL_SET_EX_POINTER       SetPtrEx;

+  PCD_PROTOCOL_SET_EX_BOOLEAN       SetBoolEx;

+

+  PCD_PROTOCOL_CALLBACK_ONSET       CallbackOnSet;

+  PCD_PROTOCOL_CANCEL_CALLBACK      CancelCallback;

+  PCD_PROTOCOL_GET_NEXT_TOKEN       GetNextToken;

+} PCD_PROTOCOL;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h b/edk2/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h
new file mode 100644
index 0000000..9d83c5a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h
@@ -0,0 +1,363 @@
+/** @file

+  This file declares Pci Host Bridge Resource Allocation Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PciHostBridgeResourceAllocation.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework of EFI Pci Host Bridge Resource Allocation Protocol Spec

+  Version 0.9

+

+**/

+

+#ifndef _PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_H_

+#define _PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_H_

+

+#define EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GUID \

+  { 0xCF8034BE, 0x6768, 0x4d8b, {0xB7,0x39,0x7C,0xCE,0x68,0x3A,0x9F,0xBE }}

+

+

+typedef struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL;

+

+

+//

+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES

+//

+

+// If this bit is set, then the PCI Root Bridge does not 

+// support separate windows for Non-prefetchable and Prefetchable 

+// memory. A PCI bus driver needs to include requests for Prefetchable 

+// memory in the Non-prefetchable memory pool.

+//

+#define EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM  1

+

+//

+// If this bit is set, then the PCI Root Bridge supports 

+// 64 bit memory windows.  If this bit is not set, 

+// the PCI bus driver needs to include requests for 64 bit 

+// memory address in the corresponding 32 bit memory pool. 

+//

+#define EFI_PCI_HOST_BRIDGE_MEM64_DECODE   2

+

+

+//

+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE

+//

+typedef enum {

+  EfiPciHostBridgeBeginEnumeration,

+  EfiPciHostBridgeBeginBusAllocation,

+  EfiPciHostBridgeEndBusAllocation,

+  EfiPciHostBridgeBeginResourceAllocation,

+  EfiPciHostBridgeAllocateResources,

+  EfiPciHostBridgeSetResources,

+  EfiPciHostBridgeFreeResources,

+  EfiPciHostBridgeEndResourceAllocation

+} EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE;

+

+//

+// EfiPciHostBridgeBeginEnumeration

+// Reset the host bridge PCI apertures and internal data structures. 

+// PCI enumerator should issue this notification before starting fresh 

+// enumeration process. Enumeration cannot be restarted after sending 

+// any other notification such as EfiPciHostBridgeBeginBusAllocation. 

+//

+// EfiPciHostBridgeBeginBusAllocation  

+// The bus allocation phase is about to begin. No specific action 

+// is required here. This notification can be used to perform any 

+// chipset specific programming. 

+//

+// EfiPciHostBridgeEndBusAllocation

+// The bus allocation and bus programming phase is complete. No specific

+// action is required here. This notification can be used to perform any 

+// chipset specific programming. 

+//

+// EfiPciHostBridgeBeginResourceAllocation

+// The resource allocation phase is about to begin.No specific action is 

+// required here. This notification can be used to perform any chipset specific programming. 

+//

+// EfiPciHostBridgeAllocateResources

+// Allocate resources per previously submitted requests for all the PCI Root 

+// Bridges. These resource settings are returned on the next call to 

+// GetProposedResources(). 

+//

+// EfiPciHostBridgeSetResources

+// Program the Host Bridge hardware to decode previously allocated resources

+// (proposed resources) for all the PCI Root Bridges. 

+//

+// EfiPciHostBridgeFreeResources

+// De-allocate previously allocated resources previously for all the PCI 

+// Root Bridges and reset the I/O and memory apertures to initial state. 

+//

+// EfiPciHostBridgeEndResourceAllocation

+// The resource allocation phase is completed.  No specific action is required 

+// here. This notification can be used to perform any chipset specific programming. 

+

+

+

+//

+// EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE

+//

+typedef enum {

+  EfiPciBeforeChildBusEnumeration,        

+  EfiPciBeforeResourceCollection

+} EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE;

+

+//

+// EfiPciBeforeChildBusEnumeration

+// This notification is only applicable to PCI-PCI bridges and 

+// indicates that the PCI enumerator is about to begin enumerating 

+// the bus behind the PCI-PCI Bridge. This notification is sent after 

+// the primary bus number, the secondary bus number and the subordinate 

+// bus number registers in the PCI-PCI Bridge are programmed to valid 

+// (not necessary final) values

+//

+// EfiPciBeforeResourceCollection

+// This notification is sent before the PCI enumerator probes BAR registers 

+// for every valid PCI function.

+//

+

+

+/**

+  Enter a certain phase of the PCI enumeration process

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance

+  @param  Phase The phase during enumeration

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_OUT_OF_RESOURCES If SubmitResources ( ) could not allocate resources

+  @retval  EFI_NOT_READY This phase cannot be entered at this time

+  @retval  EFI_DEVICE_ERROR SetResources failed due to HW error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_NOTIFY_PHASE) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL         *This,

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE            Phase

+  );

+

+  

+/**

+  Return the device handle of the next PCI root bridge that is associated with 

+  this Host Bridge

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle Returns the device handle of the next PCI Root Bridge.

+  On input, it holds the RootBridgeHandle returned by the most

+  recent call to GetNextRootBridge().The handle for the first

+  PCI Root Bridge is returned if RootBridgeHandle is NULL on input

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_NEXT_ROOT_BRIDGE) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL     *This,

+  IN OUT EFI_HANDLE                                       *RootBridgeHandle

+  );

+

+

+/**

+  Returns the attributes of a PCI Root Bridge.

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle The device handle of the PCI Root Bridge

+  that the caller is interested in

+  @param  Attribute The pointer to attributes of the PCI Root Bridge

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+  @retval  EFI_INVALID_PARAMETER Attributes is NULL

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_ATTRIBUTES) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL           *This,

+  IN  EFI_HANDLE                                                RootBridgeHandle,

+  OUT UINT64                                                    *Attributes

+  );

+

+

+/**

+  This is the request from the PCI enumerator to set up 

+  the specified PCI Root Bridge for bus enumeration process. 

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle The PCI Root Bridge to be set up

+  @param  Configuration Pointer to the pointer to the PCI bus resource descriptor

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+  @retval  EFI_DEVICE_ERROR Request failed due to hardware error

+  @retval  EFI_OUT_OF_RESOURCES Request failed due to lack of resources

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_START_BUS_ENUMERATION) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL           *This,

+  IN  EFI_HANDLE                                                RootBridgeHandle,

+  OUT VOID                                                      **Configuration

+  );

+

+  

+/**

+  This function programs the PCI Root Bridge hardware so that 

+  it decodes the specified PCI bus range

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle The PCI Root Bridge whose bus range is to be programmed

+  @param  Configuration The pointer to the PCI bus resource descriptor

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+  @retval  EFI_INVALID_PARAMETER Configuration is NULL

+  @retval  EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI resource descriptor

+  @retval  EFI_INVALID_PARAMETER Configuration contains one or more memory or IO ACPI resource descriptor

+  @retval  EFI_INVALID_PARAMETER Address Range Minimum or Address Range Length fields in Configuration

+  are invalid for this Root Bridge.

+  @retval  EFI_INVALID_PARAMETER Configuration contains one or more invalid ACPI resource descriptor

+  @retval  EFI_DEVICE_ERROR Request failed due to hardware error

+  @retval  EFI_OUT_OF_RESOURCES Request failed due to lack of resources

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SET_BUS_NUMBERS) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,

+  IN EFI_HANDLE                                                RootBridgeHandle,

+  IN VOID                                                      *Configuration

+  );

+

+

+/**

+  Submits the I/O and memory resource requirements for the specified PCI Root Bridge

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle The PCI Root Bridge whose I/O and memory resource requirements

+  are being submitted

+  @param  Configuration The pointer to the PCI I/O and PCI memory resource descriptor

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+  @retval  EFI_INVALID_PARAMETER Configuration is NULL

+  @retval  EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI resource descriptor

+  @retval  EFI_INVALID_PARAMETER Configuration includes a resource descriptor of unsupported type

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SUBMIT_RESOURCES) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,

+  IN EFI_HANDLE                                                RootBridgeHandle,

+  IN VOID                                                      *Configuration

+  );

+

+

+/**

+  This function returns the proposed resource settings for the specified 

+  PCI Root Bridge

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle The PCI Root Bridge handle

+  @param  Configuration The pointer to the pointer to the PCI I/O

+  and memory resource descriptor

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+  @retval  EFI_DEVICE_ERROR Request failed due to hardware error

+  @retval  EFI_OUT_OF_RESOURCES Request failed due to lack of resources

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_PROPOSED_RESOURCES) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL           *This,

+  IN  EFI_HANDLE                                                RootBridgeHandle,

+  OUT VOID                                                      **Configuration

+  );

+

+

+

+/**

+  This function is called for all the PCI controllers that the PCI 

+  bus driver finds. Can be used to Preprogram the controller.

+

+  @param  This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+  @param  RootBridgeHandle The PCI Root Bridge handle

+  @param  PciBusAddress Address of the controller on the PCI bus

+  @param Phase The Phase during resource allocation

+

+  @retval  EFI_SUCCESS Success

+  @retval  EFI_INVALID_PARAMETER RootBridgeHandle is invalid

+  @retval  EFI_DEVICE_ERROR Device pre-initialization failed due to hardware error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER) (

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL            *This,

+  IN  EFI_HANDLE                                                 RootBridgeHandle,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS                PciAddress,

+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE               Phase

+  );

+

+/**

+  @par Protocol Description:

+  Provides the basic interfaces to abstract a PCI host bridge resource allocation. 

+

+  @param NotifyPhase

+  The notification from the PCI bus enumerator that it is about to enter 

+  a certain phase during the enumeration process.

+

+  @param GetNextRootBridge  

+  Retrieves the device handle for the next PCI root bridge that is produced by the 

+  host bridge to which this instance of the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is attached. 

+

+  @param GetAllocAttributes 

+  Retrieves the allocation-related attributes of a PCI root bridge.

+

+  @param StartBusEnumeration 

+  Sets up a PCI root bridge for bus enumeration. 

+

+  @param SetBusNumbers 

+  Sets up the PCI root bridge so that it decodes a specific range of bus numbers.

+

+  @param SubmitResources

+  Submits the resource requirements for the specified PCI root bridge. 

+

+  @param GetProposedResources 

+  Returns the proposed resource assignment for the specified PCI root bridges.

+

+  @param PreprocessController

+  Provides hooks from the PCI bus driver to every PCI controller 

+  (device/function) at various stages of the PCI enumeration process that 

+  allow the host bridge driver to preinitialize individual PCI controllers 

+  before enumeration.

+

+**/

+struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL {

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_NOTIFY_PHASE           NotifyPhase;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_NEXT_ROOT_BRIDGE   GetNextRootBridge;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_ATTRIBUTES         GetAllocAttributes;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_START_BUS_ENUMERATION  StartBusEnumeration;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SET_BUS_NUMBERS        SetBusNumbers;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SUBMIT_RESOURCES       SubmitResources;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_PROPOSED_RESOURCES GetProposedResources;

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER  PreprocessController;

+};

+

+extern EFI_GUID gEfiPciHostBridgeResourceAllocationProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PciHotPlugInit.h b/edk2/MdePkg/Include/Protocol/PciHotPlugInit.h
new file mode 100644
index 0000000..b4b5a3d
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PciHotPlugInit.h
@@ -0,0 +1,185 @@
+/** @file

+  This file declares EFI PCI Hot Plug Init Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PciHotPlugInit.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework of EFI Hot Plug Pci Initialization Protocol Spec

+  Version 0.9

+

+**/

+

+#ifndef _EFI_PCI_HOT_PLUG_INIT_H

+#define _EFI_PCI_HOT_PLUG_INIT_H

+

+//

+// Global ID for the PCI Hot Plug Protocol

+//

+#define EFI_PCI_HOT_PLUG_INIT_PROTOCOL_GUID \

+  { 0xaa0e8bc1, 0xdabc, 0x46b0, {0xa8, 0x44, 0x37, 0xb8, 0x16, 0x9b, 0x2b, 0xea } }

+

+  

+typedef struct _EFI_PCI_HOT_PLUG_INIT_PROTOCOL EFI_PCI_HOT_PLUG_INIT_PROTOCOL;

+

+#define  EFI_HPC_STATE_INITIALIZED    0x01

+#define  EFI_HPC_STATE_ENABLED        0x02

+

+typedef UINT16 EFI_HPC_STATE;

+

+

+typedef struct{

+  EFI_DEVICE_PATH_PROTOCOL  *HpcDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *HpbDevicePath;

+} EFI_HPC_LOCATION;

+

+

+typedef enum{

+  EfiPaddingPciBus,

+  EfiPaddingPciRootBridge

+} EFI_HPC_PADDING_ATTRIBUTES;

+

+/**

+  Returns a list of root Hot Plug Controllers (HPCs) that require initialization 

+  during the boot process.

+

+  @param  This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance.

+  

+  @param  HpcCount The number of root HPCs that were returned.

+  

+  @param  HpcList The list of root HPCs. HpcCount defines the number of 

+  elements in this list.

+

+  @retval EFI_SUCCESS HpcList was returned.

+  

+  @retval EFI_OUT_OF_RESOURCES HpcList was not returned due to insufficient resources.

+  

+  @retval EFI_INVALID_PARAMETER HpcCount is NULL or HpcList is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_ROOT_HPC_LIST) (

+  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL   *This,

+  OUT UINTN                           *HpcCount,

+  OUT EFI_HPC_LOCATION                **HpcList

+);

+

+/**

+  Initializes one root Hot Plug Controller (HPC). This process may causes 

+  initialization of its subordinate buses. 

+

+  @param  This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance.

+  

+  @param  HpcDevicePath The device path to the HPC that is being initialized.

+  

+  @param  HpcPciAddress The address of the HPC function on the PCI bus.

+  

+  @param  Event The event that should be signaled when the HPC initialization 

+  is complete.

+  

+  @param  HpcState The state of the HPC hardware. 

+

+  @retval EFI_SUCCESS If Event is NULL, the specific HPC was successfully 

+  initialized. If Event is not NULL,  Event will be signaled at a later time 

+  when initialization is complete.

+  

+  @retval EFI_UNSUPPORTED This instance of EFI_PCI_HOT_PLUG_INIT_PROTOCOL 

+  does not support the specified HPC.

+  

+  @retval EFI_OUT_OF_RESOURCES Initialization failed due to insufficient 

+  resources.

+  

+  @retval EFI_INVALID_PARAMETER HpcState is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INITIALIZE_ROOT_HPC) (

+  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL     *This,

+  IN  EFI_DEVICE_PATH_PROTOCOL          *HpcDevicePath,

+  IN  UINT64                            HpcPciAddress,

+  IN  EFI_EVENT                         Event, OPTIONAL

+  OUT EFI_HPC_STATE                     *HpcState

+);

+

+/**

+  Returns the resource padding that is required by the PCI bus that is controlled 

+  by the specified Hot Plug Controller (HPC).

+

+  @param  This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance.

+  

+  @param  HpcDevicePath The device path to the HPC.

+  

+  @param  HpcPciAddress The address of the HPC function on the PCI bus. 

+  

+  @param  HpcState The state of the HPC hardware. 

+  

+  @param  Padding The amount of resource padding that is required by the 

+  PCI bus under the control of the specified HPC. 

+  

+  @param  Attributes Describes how padding is accounted for. The padding 

+  is returned in the form of ACPI 2.0 resource descriptors. 

+

+  @retval EFI_SUCCESS The resource padding was successfully returned.

+  

+  @retval EFI_UNSUPPORTED This instance of the EFI_PCI_HOT_PLUG_INIT_PROTOCOL 

+  does not support the specified HPC.

+  

+  @retval EFI_NOT_READY This function was called before HPC initialization is complete.

+  

+  @retval EFI_INVALID_PARAMETER  HpcState or Padding or Attributes is NULL.

+  

+  @retval EFI_OUT_OF_RESOURCES ACPI 2.0 resource descriptors for Padding 

+  cannot be allocated due to insufficient resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_PCI_HOT_PLUG_PADDING) (

+  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL     *This,

+  IN  EFI_DEVICE_PATH_PROTOCOL          *HpcDevicePath,

+  IN  UINT64                            HpcPciAddress,

+  OUT EFI_HPC_STATE                     *HpcState,

+  OUT VOID                              **Padding,

+  OUT EFI_HPC_PADDING_ATTRIBUTES        *Attributes

+); 

+

+

+//

+// Prototypes for the PCI Hot Plug Init Protocol

+//

+

+/**

+  @par Protocol Description:

+  This protocol provides the necessary functionality to initialize the 

+  Hot Plug Controllers (HPCs) and the buses that they control. This protocol 

+  also provides information regarding resource padding. 

+

+  @param GetRootHpcList

+  Returns a list of root HPCs and the buses that they control.

+

+  @param InitializeRootHpc

+  Initializes the specified root HPC.

+

+  @param GetResourcePadding

+  Returns the resource padding that is required by the HPC.

+

+**/

+struct _EFI_PCI_HOT_PLUG_INIT_PROTOCOL {

+  EFI_GET_ROOT_HPC_LIST                                  GetRootHpcList;

+  EFI_INITIALIZE_ROOT_HPC                                InitializeRootHpc;

+  EFI_GET_PCI_HOT_PLUG_PADDING                           GetResourcePadding;

+};

+

+extern EFI_GUID gEfiPciHotPlugInitProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PciIo.h b/edk2/MdePkg/Include/Protocol/PciIo.h
new file mode 100644
index 0000000..18494b3
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PciIo.h
@@ -0,0 +1,503 @@
+/** @file

+  EFI PCI I/O Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PciIo.h

+

+**/

+

+#ifndef __PCI_IO_H__

+#define __PCI_IO_H__

+

+//

+// Global ID for the PCI I/O Protocol

+//

+#define EFI_PCI_IO_PROTOCOL_GUID \

+  { \

+    0x4cf5b200, 0x68b8, 0x4ca5, {0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a } \

+  }

+

+typedef struct _EFI_PCI_IO_PROTOCOL  EFI_PCI_IO_PROTOCOL;

+

+//

+// Prototypes for the PCI I/O Protocol

+//

+typedef enum {

+  EfiPciIoWidthUint8      = 0,

+  EfiPciIoWidthUint16,

+  EfiPciIoWidthUint32,

+  EfiPciIoWidthUint64,

+  EfiPciIoWidthFifoUint8,

+  EfiPciIoWidthFifoUint16,

+  EfiPciIoWidthFifoUint32,

+  EfiPciIoWidthFifoUint64,

+  EfiPciIoWidthFillUint8,

+  EfiPciIoWidthFillUint16,

+  EfiPciIoWidthFillUint32,

+  EfiPciIoWidthFillUint64,

+  EfiPciIoWidthMaximum

+} EFI_PCI_IO_PROTOCOL_WIDTH;

+

+//

+// Complete PCI address generater

+//

+#define EFI_PCI_IO_PASS_THROUGH_BAR               0xff    // Special BAR that passes a memory or I/O cycle through unchanged

+#define EFI_PCI_IO_ATTRIBUTE_MASK                 0x077f  // All the following I/O and Memory cycles

+#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO   0x0001  // I/O cycles 0x0000-0x00FF (10 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO               0x0002  // I/O cycles 0x0100-0x03FF or greater (10 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO       0x0004  // I/O cycles 0x3C6, 0x3C8, 0x3C9 (10 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY           0x0008  // MEM cycles 0xA0000-0xBFFFF (24 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO               0x0010  // I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO       0x0020  // I/O cycles 0x1F0-0x1F7, 0x3F6, 0x3F7 (10 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO     0x0040  // I/O cycles 0x170-0x177, 0x376, 0x377 (10 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080  // Map a memory range so write are combined

+#define EFI_PCI_IO_ATTRIBUTE_IO                   0x0100  // Enable the I/O decode bit in the PCI Config Header

+#define EFI_PCI_IO_ATTRIBUTE_MEMORY               0x0200  // Enable the Memory decode bit in the PCI Config Header

+#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER           0x0400  // Enable the DMA bit in the PCI Config Header

+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED        0x0800  // Map a memory range so all r/w accesses are cached

+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE       0x1000  // Disable a memory range

+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE      0x2000  // Clear for an add-in PCI Device

+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         0x4000  // Clear for a physical PCI Option ROM accessed through ROM BAR

+#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE   0x8000  // Clear for PCI controllers that can not genrate a DAC

+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16            0x10000 // I/O cycles 0x0100-0x03FF or greater (16 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16    0x20000 // I/O cycles 0x3C6, 0x3C8, 0x3C9 (16 bit decode)

+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16            0x30000 // I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode)

+

+#define EFI_PCI_DEVICE_ENABLE                     (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER)

+#define EFI_VGA_DEVICE_ENABLE                     (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_IO)

+

+//

+// *******************************************************

+// EFI_PCI_IO_PROTOCOL_OPERATION

+// *******************************************************

+//

+typedef enum {

+  EfiPciIoOperationBusMasterRead,

+  EfiPciIoOperationBusMasterWrite,

+  EfiPciIoOperationBusMasterCommonBuffer,

+  EfiPciIoOperationMaximum

+} EFI_PCI_IO_PROTOCOL_OPERATION;

+

+//

+// *******************************************************

+// EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION

+// *******************************************************

+//

+typedef enum {

+  EfiPciIoAttributeOperationGet,

+  EfiPciIoAttributeOperationSet,

+  EfiPciIoAttributeOperationEnable,

+  EfiPciIoAttributeOperationDisable,

+  EfiPciIoAttributeOperationSupported,

+  EfiPciIoAttributeOperationMaximum

+} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;

+

+/**                                                                 

+  Reads from the memory space of a PCI controller. Returns when either the polling exit criteria is

+  satisfied or after a defined duration.                                                           

+          

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.

+  @param  Width                 Signifies the width of the memory or I/O operations.

+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the

+                                base address for the memory operation to perform.                   

+  @param  Offset                The offset within the selected BAR to start the memory operation.

+  @param  Mask                  Mask used for the polling criteria.

+  @param  Value                 The comparison value used for the polling exit criteria.

+  @param  Delay                 The number of 100 ns units to poll.

+  @param  Result                Pointer to the last value read from the memory location.

+                                

+  @retval EFI_SUCCESS           The last data returned from the access matched the poll exit criteria.

+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.

+  @retval EFI_UNSUPPORTED       Offset is not valid for the BarIndex of this PCI controller.

+  @retval EFI_TIMEOUT           Delay expired before a match occurred.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_POLL_IO_MEM) (

+  IN EFI_PCI_IO_PROTOCOL           *This,

+  IN  EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN  UINT8                        BarIndex,

+  IN  UINT64                       Offset,

+  IN  UINT64                       Mask,

+  IN  UINT64                       Value,

+  IN  UINT64                       Delay,

+  OUT UINT64                       *Result

+  );

+

+/**                                                                 

+  Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space.

+          

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.

+  @param  Width                 Signifies the width of the memory or I/O operations.

+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the

+                                base address for the memory or I/O operation to perform.                    

+  @param  Offset                The offset within the selected BAR to start the memory or I/O operation.                                

+  @param  Count                 The number of memory or I/O operations to perform.

+  @param  Buffer                For read operations, the destination buffer to store the results. For write

+                                operations, the source buffer to write data from.                          

+  

+  @retval EFI_SUCCESS           The data was read from or written to the PCI controller.

+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.

+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not

+                                valid for the PCI BAR specified by BarIndex.                  

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_IO_MEM) (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT8                        BarIndex,

+  IN     UINT64                       Offset,

+  IN     UINTN                        Count,

+  IN OUT VOID                         *Buffer

+  );

+

+typedef struct {

+  EFI_PCI_IO_PROTOCOL_IO_MEM  Read;

+  EFI_PCI_IO_PROTOCOL_IO_MEM  Write;

+} EFI_PCI_IO_PROTOCOL_ACCESS;

+

+/**                                                                 

+  Enable a PCI driver to access PCI controller registers in PCI configuration space.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+  @param  Width                 Signifies the width of the memory operations.

+  @param  Offset                The offset within the PCI configuration space for the PCI controller.

+  @param  Count                 The number of PCI configuration operations to perform.

+  @param  Buffer                For read operations, the destination buffer to store the results. For write

+                                operations, the source buffer to write data from.

+  

+                                  

+  @retval EFI_SUCCESS           The data was read from or written to the PCI controller.

+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not

+                                valid for the PCI configuration header of the PCI controller.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.                                 

+  @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid.                                

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_CONFIG) (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT32                       Offset,

+  IN     UINTN                        Count,

+  IN OUT VOID                         *Buffer

+  );

+

+typedef struct {

+  EFI_PCI_IO_PROTOCOL_CONFIG  Read;

+  EFI_PCI_IO_PROTOCOL_CONFIG  Write;

+} EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS;

+

+/**                                                                 

+  Enables a PCI driver to copy one region of PCI memory space to another region of PCI

+  memory space.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.

+  @param  Width                 Signifies the width of the memory operations.

+  @param  DestBarIndex          The BAR index in the standard PCI Configuration header to use as the

+                                base address for the memory operation to perform.                   

+  @param  DestOffset            The destination offset within the BAR specified by DestBarIndex to

+                                start the memory writes for the copy operation.                   

+  @param  SrcBarIndex           The BAR index in the standard PCI Configuration header to use as the

+                                base address for the memory operation to perform.                   

+  @param  SrcOffset             The source offset within the BAR specified by SrcBarIndex to start

+                                the memory reads for the copy operation.                          

+  @param  Count                 The number of memory operations to perform. Bytes moved is Width

+                                size * Count, starting at DestOffset and SrcOffset.             

+                                

+  @retval EFI_SUCCESS           The data was copied from one memory region to another memory region.

+  @retval EFI_UNSUPPORTED       DestBarIndex not valid for this PCI controller.

+  @retval EFI_UNSUPPORTED       SrcBarIndex not valid for this PCI controller.

+  @retval EFI_UNSUPPORTED       The address range specified by DestOffset, Width, and Count

+                                is not valid for the PCI BAR specified by DestBarIndex.    

+  @retval EFI_UNSUPPORTED       The address range specified by SrcOffset, Width, and Count is

+                                not valid for the PCI BAR specified by SrcBarIndex.          

+  @retval EFI_INVALID_PARAMETER Width is invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_COPY_MEM) (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT8                        DestBarIndex,

+  IN     UINT64                       DestOffset,

+  IN     UINT8                        SrcBarIndex,

+  IN     UINT64                       SrcOffset,

+  IN     UINTN                        Count

+  );

+

+/**                                                                 

+  Provides the PCI controller¨Cspecific addresses needed to access system memory.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.

+  @param  Operation             Indicates if the bus master is going to read or write to system memory.

+  @param  HostAddress           The system memory address to map to the PCI controller.

+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes

+                                that were mapped.                                                 

+  @param  DeviceAddress         The resulting map address for the bus master PCI controller to use to

+                                access the hosts HostAddress.                                        

+  @param  Mapping               A resulting value to pass to Unmap().

+                                  

+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.

+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.                                

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_MAP) (

+  IN EFI_PCI_IO_PROTOCOL                *This,

+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                           *HostAddress,

+  IN OUT UINTN                          *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,

+  OUT    VOID                           **Mapping

+  );

+

+/**                                                                 

+  Completes the Map() operation and releases any corresponding resources.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.                                      

+  @param  Mapping               The mapping value returned from Map().

+                                  

+  @retval EFI_SUCCESS           The range was unmapped.

+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_UNMAP) (

+  IN EFI_PCI_IO_PROTOCOL           *This,

+  IN  VOID                         *Mapping

+  );

+

+/**                                                                 

+  Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer

+  mapping.                                                                       

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.

+  @param  Type                  This parameter is not used and must be ignored.

+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or

+                                EfiRuntimeServicesData.                               

+  @param  Pages                 The number of pages to allocate.                                

+  @param  HostAddress           A pointer to store the base system memory address of the

+                                allocated range.                                        

+  @param  Attributes            The requested bit mask of attributes for the allocated range.

+                                  

+  @retval EFI_SUCCESS           The requested memory pages were allocated.

+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are

+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.                     

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.  

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER) (

+  IN EFI_PCI_IO_PROTOCOL           *This,

+  IN  EFI_ALLOCATE_TYPE            Type,

+  IN  EFI_MEMORY_TYPE              MemoryType,

+  IN  UINTN                        Pages,

+  OUT VOID                         **HostAddress,

+  IN  UINT64                       Attributes

+  );

+

+/**                                                                 

+  Frees memory that was allocated with AllocateBuffer().

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+  @param  Pages                 The number of pages to free.                                

+  @param  HostAddress           The base system memory address of the allocated range.                                    

+                                  

+  @retval EFI_SUCCESS           The requested memory pages were freed.

+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages

+                                was not allocated with AllocateBuffer().

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_FREE_BUFFER) (

+  IN EFI_PCI_IO_PROTOCOL           *This,

+  IN  UINTN                        Pages,

+  IN  VOID                         *HostAddress

+  );

+

+/**                                                                 

+  Flushes all PCI posted write transactions from a PCI host bridge to system memory.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+                                  

+  @retval EFI_SUCCESS           The PCI posted write transactions were flushed from the PCI host

+                                bridge to system memory.                                        

+  @retval EFI_DEVICE_ERROR      The PCI posted write transactions were not flushed from the PCI

+                                host bridge due to a hardware error.                           

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_FLUSH) (

+  IN EFI_PCI_IO_PROTOCOL  *This

+  );

+

+/**                                                                 

+  Retrieves this PCI controller¡¯s current PCI bus number, device number, and function number.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+  @param  SegmentNumber         The PCI controller¡¯s current PCI segment number.

+  @param  BusNumber             The PCI controller¡¯s current PCI bus number.

+  @param  DeviceNumber          The PCI controller¡¯s current PCI device number.

+  @param  FunctionNumber        The PCI controller¡¯s current PCI function number.

+                                  

+  @retval EFI_SUCCESS           The PCI controller location was returned.                                                       

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                              

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION) (

+  IN EFI_PCI_IO_PROTOCOL          *This,

+  OUT UINTN                       *SegmentNumber,

+  OUT UINTN                       *BusNumber,

+  OUT UINTN                       *DeviceNumber,

+  OUT UINTN                       *FunctionNumber

+  );

+

+/**                                                                 

+  Performs an operation on the attributes that this PCI controller supports. The operations include

+  getting the set of supported attributes, retrieving the current attributes, setting the current  

+  attributes, enabling attributes, and disabling attributes.                                       

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+  @param  Operation             The operation to perform on the attributes for this PCI controller.

+  @param  Attributes            The mask of attributes that are used for Set, Enable, and Disable

+                                operations.                                                      

+  @param  Result                A pointer to the result mask of attributes that are returned for the Get

+                                and Supported operations.                                               

+                                  

+  @retval EFI_SUCCESS           The operation on the PCI controller's attributes was completed.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                              

+  @retval EFI_UNSUPPORTED       one or more of the bits set in                               

+                                Attributes are not supported by this PCI controller or one of

+                                its parent bridges when Operation is Set, Enable or Disable.

+                                       

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_ATTRIBUTES) (

+  IN EFI_PCI_IO_PROTOCOL                       *This,

+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,

+  IN  UINT64                                   Attributes,

+  OUT UINT64                                   *Result OPTIONAL

+  );

+

+/**                                                                 

+  Gets the attributes that this PCI controller supports setting on a BAR using

+  SetBarAttributes(), and retrieves the list of resource descriptors for a BAR.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the

+                                base address for resource range. The legal range for this field is 0..5.

+  @param  Supports              A pointer to the mask of attributes that this PCI controller supports

+                                setting for this BAR with SetBarAttributes().                        

+  @param  Resources             A pointer to the ACPI 2.0 resource descriptors that describe the current

+                                configuration of this BAR of the PCI controller.                        

+                                  

+  @retval EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI       

+                                controller supports are returned in Supports. If Resources      

+                                is not NULL, then the ACPI 2.0 resource descriptors that the PCI

+                                controller is currently using are returned in Resources.          

+  @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.

+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to allocate

+                                Resources.                                                 

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES) (

+  IN EFI_PCI_IO_PROTOCOL             *This,

+  IN  UINT8                          BarIndex,

+  OUT UINT64                         *Supports, OPTIONAL

+  OUT VOID                           **Resources OPTIONAL

+  );

+

+/**                                                                 

+  Sets the attributes for a range of a BAR on a PCI controller.

+            

+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.  

+  @param  Attributes            The mask of attributes to set for the resource range specified by

+                                BarIndex, Offset, and Length.                                    

+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the

+                                base address for resource range. The legal range for this field is 0..5.

+  @param  Offset                A pointer to the BAR relative base address of the resource range to be

+                                modified by the attributes specified by Attributes.                   

+  @param  Length                A pointer to the length of the resource range to be modified by the

+                                attributes specified by Attributes.                                

+                                  

+  @retval EFI_SUCCESS           The set of attributes specified by Attributes for the resource      

+                                range specified by BarIndex, Offset, and Length were                

+                                set on the PCI controller, and the actual resource range is returned

+                                in Offset and Length.                                               

+  @retval EFI_INVALID_PARAMETER Offset or Length is NULL.

+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to set the attributes on the

+                                resource range specified by BarIndex, Offset, and          

+                                Length.                                                    

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES) (

+  IN EFI_PCI_IO_PROTOCOL              *This,

+  IN     UINT64                       Attributes,

+  IN     UINT8                        BarIndex,

+  IN OUT UINT64                       *Offset,

+  IN OUT UINT64                       *Length

+  );

+

+//

+// Interface structure for the PCI I/O Protocol

+//

+struct _EFI_PCI_IO_PROTOCOL {

+  EFI_PCI_IO_PROTOCOL_POLL_IO_MEM         PollMem;

+  EFI_PCI_IO_PROTOCOL_POLL_IO_MEM         PollIo;

+  EFI_PCI_IO_PROTOCOL_ACCESS              Mem;

+  EFI_PCI_IO_PROTOCOL_ACCESS              Io;

+  EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS       Pci;

+  EFI_PCI_IO_PROTOCOL_COPY_MEM            CopyMem;

+  EFI_PCI_IO_PROTOCOL_MAP                 Map;

+  EFI_PCI_IO_PROTOCOL_UNMAP               Unmap;

+  EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER     AllocateBuffer;

+  EFI_PCI_IO_PROTOCOL_FREE_BUFFER         FreeBuffer;

+  EFI_PCI_IO_PROTOCOL_FLUSH               Flush;

+  EFI_PCI_IO_PROTOCOL_GET_LOCATION        GetLocation;

+  EFI_PCI_IO_PROTOCOL_ATTRIBUTES          Attributes;

+  EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES  GetBarAttributes;

+  EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES  SetBarAttributes;

+  UINT64                                  RomSize;

+  VOID                                    *RomImage;

+};

+

+extern EFI_GUID gEfiPciIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PciPlatform.h b/edk2/MdePkg/Include/Protocol/PciPlatform.h
new file mode 100644
index 0000000..5b0add1
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PciPlatform.h
@@ -0,0 +1,207 @@
+/** @file

+  This file declares PlatfromOpRom protocols.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PciPlatform.h

+

+  @par Revision Reference:

+  This protocol is defined in PCI Platform Support Specification

+  Version 0.9

+

+**/

+

+#ifndef _PCI_PLATFORM_H_

+#define _PCI_PLATFORM_H_

+

+//

+// Protocol for GUID.

+//

+

+#define EFI_PCI_PLATFORM_PROTOCOL_GUID \

+{ 0x7d75280, 0x27d4, 0x4d69, {0x90, 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41} }

+

+typedef struct _EFI_PCI_PLATFORM_PROTOCOL EFI_PCI_PLATFORM_PROTOCOL;

+

+typedef    UINT32   EFI_PCI_PLATFORM_POLICY;

+

+

+#define     EFI_RESERVE_NONE_IO_ALIAS        0x0000

+#define     EFI_RESERVE_ISA_IO_ALIAS         0x0001

+#define     EFI_RESERVE_ISA_IO_NO_ALIAS      0x0002

+#define     EFI_RESERVE_VGA_IO_ALIAS         0x0004

+#define     EFI_RESERVE_VGA_IO_NO_ALIAS      0x0008

+

+

+typedef enum {

+  ChipsetEntry,

+  ChipsetExit,

+  MaximumChipsetPhase

+} EFI_PCI_CHIPSET_EXECUTION_PHASE;

+

+

+/**

+  The PlatformNotify() function can be used to notify the platform driver so that 

+  it can perform platform-specific actions. No specific actions are required. 

+  Eight notification points are defined at this time. More synchronization points 

+  may be added as required in the future. The PCI bus driver calls the platform driver 

+  twice for every Phase-once before the PCI Host Bridge Resource Allocation Protocol 

+  driver is notified, and once after the PCI Host Bridge Resource Allocation Protocol 

+  driver has been notified. 

+  This member function may not perform any error checking on the input parameters. It 

+  also does not return any error codes. If this member function detects any error condition, 

+  it needs to handle those errors on its own because there is no way to surface any 

+  errors to the caller.

+

+  @param  This Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.

+  @param  HostBridge The handle of the host bridge controller.

+  @param  Phase The phase of the PCI bus enumeration.

+  @param  ChipsetPhase Defines the execution phase of the PCI chipset driver.

+

+  @retval  EFI_SUCCESS The function completed successfully.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_PLATFORM_PHASE_NOTIFY) (

+  IN EFI_PCI_PLATFORM_PROTOCOL                       *This,

+  IN  EFI_HANDLE                                     HostBridge,

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE  Phase,

+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase  

+)

+;

+

+

+/**

+  The PlatformPrepController() function can be used to notify the platform driver so that 

+  it can perform platform-specific actions. No specific actions are required. 

+  Several notification points are defined at this time. More synchronization points may be 

+  added as required in the future. The PCI bus driver calls the platform driver twice for 

+  every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver 

+  is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has 

+  been notified. 

+  This member function may not perform any error checking on the input parameters. It also 

+  does not return any error codes. If this member function detects any error condition, it 

+  needs to handle those errors on its own because there is no way to surface any errors to 

+  the caller.  

+

+  @param  This Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.

+  @param  HostBridge The associated PCI host bridge handle.

+  @param  RootBridge The associated PCI root bridge handle.

+  @param  PciAddress The address of the PCI device on the PCI bus.

+  @param  Phase The phase of the PCI controller enumeration.

+  @param  ChipsetPhase Defines the execution phase of the PCI chipset driver.

+

+  @retval  EFI_SUCCESS The function completed successfully.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_PLATFORM_PREPROCESS_CONTROLLER) (

+  IN  EFI_PCI_PLATFORM_PROTOCOL                      *This,

+  IN  EFI_HANDLE                                     HostBridge,

+  IN  EFI_HANDLE                                     RootBridge,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,

+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,

+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase

+)

+;

+

+

+/**

+  The GetPlatformPolicy() function retrieves the platform policy regarding PCI 

+  enumeration. The PCI bus driver and the PCI Host Bridge Resource Allocation Protocol 

+  driver can call this member function to retrieve the policy.

+

+  @param  This Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.

+  @param  PciPolicy The platform policy with respect to VGA and ISA aliasing.

+

+  @retval  EFI_SUCCESS The function completed successfully.

+  @retval  EFI_INVALID_PARAMETER PciPolicy is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_PLATFORM_GET_PLATFORM_POLICY) (

+  IN  EFI_PCI_PLATFORM_PROTOCOL           *This,

+  OUT EFI_PCI_PLATFORM_POLICY             *PciPolicy

+)

+;

+

+

+/**

+  The GetPciRom() function gets the PCI device's option ROM from a platform-specific location. 

+  The option ROM will be loaded into memory. This member function is used to return an image 

+  that is packaged as a PCI 2.2 option ROM. The image may contain both legacy and EFI option 

+  ROMs. See the EFI 1.10 Specification for details. This member function can be used to return 

+  option ROM images for embedded controllers. Option ROMs for embedded controllers are typically 

+  stored in platform-specific storage, and this member function can retrieve it from that storage 

+  and return it to the PCI bus driver. The PCI bus driver will call this member function before 

+  scanning the ROM that is attached to any controller, which allows a platform to specify a ROM 

+  image that is different from the ROM image on a PCI card.

+

+  @param  This Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.

+  @param  PciHandle The handle of the PCI device.

+  @param  RomImage If the call succeeds, the pointer to the pointer to the option ROM image.

+  Otherwise, this field is undefined. The memory for RomImage is allocated

+  by EFI_PCI_PLATFORM_PROTOCOL.GetPciRom() using the EFI Boot Service AllocatePool().

+  It is the caller's responsibility to free the memory using the EFI Boot Service

+  FreePool(), when the caller is done with the option ROM.

+  @param  RomSize If the call succeeds, a pointer to the size of the option ROM size. Otherwise,

+  this field is undefined.

+

+  @retval  EFI_SUCCESS The option ROM was available for this device and loaded into memory.

+  @retval  EFI_NOT_FOUND No option ROM was available for this device.

+  @retval  EFI_OUT_OF_RESOURCES No memory was available to load the option ROM.

+  @retval  EFI_DEVICE_ERROR An error occurred in getting the option ROM.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_PLATFORM_GET_PCI_ROM) (        

+  IN   EFI_PCI_PLATFORM_PROTOCOL    *This,

+  IN   EFI_HANDLE                   PciHandle,

+  OUT  VOID                         **RomImage,

+  OUT  UINTN                        *RomSize              

+)

+;

+

+/**

+  @par Protocol Description:

+  This protocol provides the interface between the PCI bus driver/PCI Host 

+  Bridge Resource Allocation driver and a platform-specific driver to describe 

+  the unique features of a platform.

+

+  @param PlatformNotify

+  The notification from the PCI bus enumerator to the platform that it is 

+  about to enter a certain phase during the enumeration process.

+

+  @param PlatformPrepController

+  The notification from the PCI bus enumerator to the platform for each PCI 

+  controller at several predefined points during PCI controller initialization.

+

+  @param GetPlatformPolicy

+  Retrieves the platform policy regarding enumeration.

+

+  @param GetPciRom

+  Gets the PCI device¡¯s option ROM from a platform-specific location.

+

+**/

+struct _EFI_PCI_PLATFORM_PROTOCOL {

+  EFI_PCI_PLATFORM_PHASE_NOTIFY          PhaseNotify;

+  EFI_PCI_PLATFORM_PREPROCESS_CONTROLLER PlatformPrepController;

+  EFI_PCI_PLATFORM_GET_PLATFORM_POLICY   GetPlatformPolicy;

+  EFI_PCI_PLATFORM_GET_PCI_ROM           GetPciRom;

+};

+

+extern EFI_GUID   gEfiPciPlatformProtocolGuid;

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PciRootBridgeIo.h b/edk2/MdePkg/Include/Protocol/PciRootBridgeIo.h
new file mode 100644
index 0000000..06912da
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PciRootBridgeIo.h
@@ -0,0 +1,384 @@
+/** @file

+  PCI Root Bridge I/O protocol as defined in the EFI 1.1 specification.

+

+  PCI Root Bridge I/O protocol is used by PCI Bus Driver to perform PCI Memory, PCI I/O, 

+  and PCI Configuration cycles on a PCI Root Bridge. It also provides services to perform 

+  defferent types of bus mastering DMA

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PciRootBridgeIo.h

+

+**/

+

+#ifndef __PCI_ROOT_BRIDGE_IO_H__

+#define __PCI_ROOT_BRIDGE_IO_H__

+

+#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \

+  { \

+    0x2f707ebb, 0x4a1a, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;

+

+typedef enum {

+  EfiPciWidthUint8,

+  EfiPciWidthUint16,

+  EfiPciWidthUint32,

+  EfiPciWidthUint64,

+  EfiPciWidthFifoUint8,

+  EfiPciWidthFifoUint16,

+  EfiPciWidthFifoUint32,

+  EfiPciWidthFifoUint64,

+  EfiPciWidthFillUint8,

+  EfiPciWidthFillUint16,

+  EfiPciWidthFillUint32,

+  EfiPciWidthFillUint64,

+  EfiPciWidthMaximum

+} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH;

+

+typedef enum {

+  EfiPciOperationBusMasterRead,

+  EfiPciOperationBusMasterWrite,

+  EfiPciOperationBusMasterCommonBuffer,

+  EfiPciOperationBusMasterRead64,

+  EfiPciOperationBusMasterWrite64,

+  EfiPciOperationBusMasterCommonBuffer64,

+  EfiPciOperationMaximum

+} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION;

+

+#define EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO          0x0001

+#define EFI_PCI_ATTRIBUTE_ISA_IO                      0x0002

+#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO              0x0004

+#define EFI_PCI_ATTRIBUTE_VGA_MEMORY                  0x0008

+#define EFI_PCI_ATTRIBUTE_VGA_IO                      0x0010

+#define EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO              0x0020

+#define EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO            0x0040

+#define EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE        0x0080

+#define EFI_PCI_ATTRIBUTE_MEMORY_CACHED               0x0800

+#define EFI_PCI_ATTRIBUTE_MEMORY_DISABLE              0x1000

+#define EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE          0x8000

+

+#define EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER   (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE)

+

+#define EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER (~EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER)

+

+#define EFI_PCI_ADDRESS(bus, dev, func, reg) \

+    ((UINT64) ((((UINTN) bus) << 24) + (((UINTN) dev) << 16) + (((UINTN) func) << 8) + ((UINTN) reg)))

+

+typedef struct {

+  UINT8   Register;

+  UINT8   Function;

+  UINT8   Device;

+  UINT8   Bus;

+  UINT32  ExtendedRegister;

+} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS;

+

+/**                                                                 

+  Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is

+  satisfied or after a defined duration.

+          

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Width                 Signifies the width of the memory or I/O operations.

+  @param  Address               The base address of the memory or I/O operations.  

+  @param  Mask                  Mask used for the polling criteria.

+  @param  Value                 The comparison value used for the polling exit criteria.

+  @param  Delay                 The number of 100 ns units to poll.

+  @param  Result                Pointer to the last value read from the memory location.

+                                

+  @retval EFI_SUCCESS           The last data returned from the access matched the poll exit criteria.

+  @retval EFI_TIMEOUT           Delay expired before a match occurred.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,

+  IN  UINT64                                   Address,

+  IN  UINT64                                   Mask,

+  IN  UINT64                                   Value,

+  IN  UINT64                                   Delay,

+  OUT UINT64                                   *Result

+  );

+

+/**                                                                 

+  Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.

+          

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Width                 Signifies the width of the memory operations.

+  @param  Address               The base address of the memory operations.                                  

+  @param  Count                 The number of memory operations to perform.

+  @param  Buffer                For read operations, the destination buffer to store the results. For write

+                                operations, the source buffer to write data from.                          

+  

+  @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.  

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT64                                   Address,

+  IN     UINTN                                    Count,

+  IN OUT VOID                                     *Buffer

+  );

+

+typedef struct {

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM  Read;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM  Write;

+} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS;

+

+/**                                                                 

+  Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI

+  root bridge memory space.                                                                       

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.

+  @param  Width                 Signifies the width of the memory operations.

+  @param  DestAddress           The destination address of the memory operation.                                

+  @param  SrcAddress            The source address of the memory operation.                                

+  @param  Count                 The number of memory operations to perform.    

+                                

+  @retval EFI_SUCCESS           The data was copied from one memory region to another memory region.  

+  @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,

+  IN     UINT64                                   DestAddress,

+  IN     UINT64                                   SrcAddress,

+  IN     UINTN                                    Count

+  );

+

+/**                                                                 

+  Provides the PCI controller¨Cspecific addresses required to access system memory from a

+  DMA bus master.                                                                        

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Operation             Indicates if the bus master is going to read or write to system memory.

+  @param  HostAddress           The system memory address to map to the PCI controller.

+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes

+                                that were mapped.                                                 

+  @param  DeviceAddress         The resulting map address for the bus master PCI controller to use to

+                                access the hosts HostAddress.                                        

+  @param  Mapping               A resulting value to pass to Unmap().

+                                  

+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.

+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.                                

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL                *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                                       *HostAddress,

+  IN OUT UINTN                                      *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,

+  OUT    VOID                                       **Mapping

+  );

+

+/**                                                                 

+  Completes the Map() operation and releases any corresponding resources.

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Mapping               The mapping value returned from Map().

+                                  

+  @retval EFI_SUCCESS           The range was unmapped.

+  @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().

+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,

+  IN  VOID                                     *Mapping

+  );

+

+/**                                                                 

+  Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or

+  EfiPciOperationBusMasterCommonBuffer64 mapping.                                 

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Type                  This parameter is not used and must be ignored.

+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or

+                                EfiRuntimeServicesData.                               

+  @param  Pages                 The number of pages to allocate.                                

+  @param  HostAddress           A pointer to store the base system memory address of the

+                                allocated range.                                        

+  @param  Attributes            The requested bit mask of attributes for the allocated range.

+                                  

+  @retval EFI_SUCCESS           The requested memory pages were allocated.

+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are

+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.                     

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.  

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,

+  IN     EFI_ALLOCATE_TYPE                        Type,

+  IN     EFI_MEMORY_TYPE                          MemoryType,

+  IN     UINTN                                    Pages,

+  IN OUT VOID                                     **HostAddress,

+  IN     UINT64                                   Attributes

+  );

+

+/**                                                                 

+  Frees memory that was allocated with AllocateBuffer().

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Pages                 The number of pages to free.                                

+  @param  HostAddress           The base system memory address of the allocated range.                                    

+                                  

+  @retval EFI_SUCCESS           The requested memory pages were freed.

+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages

+                                was not allocated with AllocateBuffer().

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,

+  IN  UINTN                                    Pages,

+  IN  VOID                                     *HostAddress

+  );

+

+/**                                                                 

+  Flushes all PCI posted write transactions from a PCI host bridge to system memory.

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+                                  

+  @retval EFI_SUCCESS           The PCI posted write transactions were flushed from the PCI host

+                                bridge to system memory.                                        

+  @retval EFI_DEVICE_ERROR      The PCI posted write transactions were not flushed from the PCI

+                                host bridge due to a hardware error.                           

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This

+  );

+

+/**                                                                 

+  Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the

+  attributes that a PCI root bridge is currently using.                                    

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Supports              A pointer to the mask of attributes that this PCI root bridge supports

+                                setting with SetAttributes().                                         

+  @param  Attributes            A pointer to the mask of attributes that this PCI root bridge is currently

+                                using.                                                                      

+                                

+  @retval EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root     

+                                bridge supports is returned in Supports. If Attributes is          

+                                not NULL, then the attributes that the PCI root bridge is currently

+                                using is returned in Attributes.                                   

+  @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.

+                                

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,

+  OUT UINT64                                   *Supports,

+  OUT UINT64                                   *Attributes

+  );

+

+/**                                                                 

+  Sets attributes for a resource range on a PCI root bridge.

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Attributes            The mask of attributes to set.

+  @param  ResourceBase          A pointer to the base address of the resource range to be modified by the

+                                attributes specified by Attributes.

+  @param  ResourceLength        A pointer to the length of the resource range to be modified by the

+                                attributes specified by Attributes.                                                                                                              

+                                

+  @retval EFI_SUCCESS           The set of attributes specified by Attributes for the resource   

+                                range specified by ResourceBase and ResourceLength               

+                                were set on the PCI root bridge, and the actual resource range is

+                                returned in ResuourceBase and ResourceLength.                    

+  @retval EFI_UNSUPPORTED       A bit is set in Attributes that is not supported by the PCI Root

+                                Bridge.                                                         

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to set the attributes on the                              

+                                resource range specified by BaseAddress and Length.        

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                               

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,

+  IN     UINT64                                   Attributes,

+  IN OUT UINT64                                   *ResourceBase,

+  IN OUT UINT64                                   *ResourceLength

+  );

+

+/**                                                                 

+  Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0

+  resource descriptors.                                                                           

+            

+  @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param  Resources             A pointer to the ACPI 2.0 resource descriptors that describe the current

+                                configuration of this PCI root bridge.                                  

+                                

+  @retval EFI_SUCCESS           The current configuration of this PCI root bridge was returned in

+                                Resources.                                                                                                                       

+  @retval EFI_UNSUPPORTED       The current configuration of this PCI root bridge could not be

+                                retrieved.                                                                          

+                                       

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION) (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,

+  IN  VOID                                     **Resources

+  );

+

+struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL {

+  EFI_HANDLE                                      ParentHandle;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM     PollMem;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM     PollIo;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS          Mem;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS          Io;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS          Pci;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM        CopyMem;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP             Map;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP           Unmap;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER     FreeBuffer;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH           Flush;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES  GetAttributes;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES  SetAttributes;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION   Configuration;

+  UINT32                                          SegmentNumber;

+};

+

+extern EFI_GUID gEfiPciRootBridgeIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PlatformDriverOverride.h b/edk2/MdePkg/Include/Protocol/PlatformDriverOverride.h
new file mode 100644
index 0000000..1015c50
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PlatformDriverOverride.h
@@ -0,0 +1,135 @@
+/** @file

+  Platform Driver Override protocol as defined in the EFI 1.1 specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PlatformDriverOverride.h

+

+**/

+

+#ifndef __EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_H__

+#define __EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_H__

+

+//

+// Global ID for the Platform Driver Override Protocol

+//

+#define EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID \

+  { \

+    0x6b30c738, 0xa391, 0x11d4, {0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL;

+

+//

+// Prototypes for the Platform Driver Override Protocol

+//

+

+/**                                                                 

+  Retrieves the image handle of the platform override driver for a controller in the system.

+    

+  @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_

+                                PROTOCOL instance.                            

+  @param  ControllerHandle      The device handle of the controller to check if a driver override

+                                exists.                                                          

+  @param  DriverImageHandle     On input, a pointer to the previous driver image handle returned

+                                by GetDriver(). On output, a pointer to the next driver         

+                                image handle.                                                   

+                                

+  @retval EFI_SUCCESS           The driver override for ControllerHandle was returned in

+                                DriverImageHandle.                                      

+  @retval EFI_NOT_FOUND         A driver override for ControllerHandle was not found.

+  @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not a valid handle.

+  @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a

+                                previous call to GetDriver().                           

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER) (

+  IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              *This,

+  IN     EFI_HANDLE                                     ControllerHandle,

+  IN OUT EFI_HANDLE                                     *DriverImageHandle

+  );

+

+/**                                                                 

+  Retrieves the device path of the platform override driver for a controller in the system.

+    

+  @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_

+                                PROTOCOL instance.                            

+  @param  ControllerHandle      The device handle of the controller to check if a driver override

+                                exists.                                                          

+  @param  DriverImageHandle     On input, a pointer to the previous driver image handle returned

+                                by GetDriverPath(). On output, a pointer to the next driver         

+                                device path.

+                                

+  @retval EFI_SUCCESS           The driver override for ControllerHandle was returned in

+                                DriverImageHandle.                                      

+  @retval EFI_UNSUPPORTED       The operation is not supported.                                

+  @retval EFI_NOT_FOUND         A driver override for ControllerHandle was not found.

+  @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not a valid handle.

+  @retval EFI_INVALID_PARAMETER DriverImagePath is not a device path that was returned on a

+                                previous call to GetDriverPath().                          

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH) (

+  IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              *This,

+  IN     EFI_HANDLE                                     ControllerHandle,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL                       **DriverImagePath

+  );

+

+/**                                                                 

+  Used to associate a driver image handle with a device path that was returned on a prior call to the

+  GetDriverPath() service. This driver image handle will then be available through the               

+  GetDriver() service.                                                                               

+    

+  @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_

+                                PROTOCOL instance.                            

+  @param  ControllerHandle      The device handle of the controller.                                                             

+  @param  DriverImagePath       A pointer to the driver device path that was returned in a prior

+                                call to GetDriverPath().                                                                        

+  @param  DriverImageHandle     The driver image handle that was returned by LoadImage()

+                                when the driver specified by DriverImagePath was loaded 

+                                into memory.                                            

+                                

+  @retval EFI_SUCCESS           The association between DriverImagePath and                   

+                                DriverImageHandle was established for the controller specified

+                                by ControllerHandle.                                                                            

+  @retval EFI_UNSUPPORTED       The operation is not supported.                                

+  @retval EFI_NOT_FOUND         DriverImagePath is not a device path that was returned on a prior

+                                call to GetDriverPath() for the controller specified by          

+                                ControllerHandle.                                                

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid device handle.

+  @retval EFI_INVALID_PARAMETER DriverImagePath is not a valid device path.

+  @retval EFI_INVALID_PARAMETER DriverImageHandle is not a valid image handle.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED) (

+  IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL          *This,

+  IN EFI_HANDLE                                     ControllerHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL                       *DriverImagePath,

+  IN EFI_HANDLE                                     DriverImageHandle

+  );

+

+//

+// Interface structure for the Platform Driver Override Protocol

+//

+struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL {

+  EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER       GetDriver;

+  EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH  GetDriverPath;

+  EFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED    DriverLoaded;

+};

+

+extern EFI_GUID gEfiPlatformDriverOverrideProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/PxeBaseCode.h b/edk2/MdePkg/Include/Protocol/PxeBaseCode.h
new file mode 100644
index 0000000..14a6848
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PxeBaseCode.h
@@ -0,0 +1,622 @@
+/** @file

+  EFI PXE Base Code Protocol definitions.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PxeBaseCode.h

+

+**/

+#ifndef __PXE_BASE_CODE_PROTOCOL_H__

+#define __PXE_BASE_CODE_PROTOCOL_H__

+

+//

+// PXE Base Code protocol

+//

+#define EFI_PXE_BASE_CODE_PROTOCOL_GUID \

+  { \

+    0x03c4e603, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE_PROTOCOL;

+

+//

+// Default IP TTL and ToS.

+//

+#define DEFAULT_TTL 16

+#define DEFAULT_ToS 0

+

+//

+// ICMP error format

+//

+typedef struct {

+  UINT8   Type;

+  UINT8   Code;

+  UINT16  Checksum;

+  union {

+    UINT32  reserved;

+    UINT32  Mtu;

+    UINT32  Pointer;

+    struct {

+      UINT16  Identifier;

+      UINT16  Sequence;

+    } Echo;

+  } u;

+  UINT8 Data[494];

+} EFI_PXE_BASE_CODE_ICMP_ERROR;

+

+//

+// TFTP error format

+//

+typedef struct {

+  UINT8 ErrorCode;

+  CHAR8 ErrorString[127];

+} EFI_PXE_BASE_CODE_TFTP_ERROR;

+

+//

+// IP Receive Filter definitions

+//

+#define EFI_PXE_BASE_CODE_MAX_IPCNT 8

+

+typedef struct {

+  UINT8           Filters;

+  UINT8           IpCnt;

+  UINT16          reserved;

+  EFI_IP_ADDRESS  IpList[EFI_PXE_BASE_CODE_MAX_IPCNT];

+} EFI_PXE_BASE_CODE_IP_FILTER;

+

+#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP            0x0001

+#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST             0x0002

+#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS           0x0004

+#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008

+

+//

+// ARP Cache definitions

+//

+typedef struct {

+  EFI_IP_ADDRESS  IpAddr;

+  EFI_MAC_ADDRESS MacAddr;

+} EFI_PXE_BASE_CODE_ARP_ENTRY;

+

+typedef struct {

+  EFI_IP_ADDRESS  IpAddr;

+  EFI_IP_ADDRESS  SubnetMask;

+  EFI_IP_ADDRESS  GwAddr;

+} EFI_PXE_BASE_CODE_ROUTE_ENTRY;

+

+//

+// UDP definitions

+//

+typedef UINT16  EFI_PXE_BASE_CODE_UDP_PORT;

+

+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP    0x0001

+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT  0x0002

+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP   0x0004

+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008

+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER    0x0010

+#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT  0x0020

+

+//

+// Discover() definitions

+//

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP         0

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS      1

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM         2

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI           3

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO        4

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD          5

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM          6

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG  7

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW       8

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9         9

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10        10

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11        11

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12       12

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL    13

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT       14

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO             15

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT           16

+//

+// 17 through 32767 are reserved

+// 32768 through 65279 are for vendor use

+// 65280 through 65534 are reserved

+//

+#define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST   65535

+

+#define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK     0x7FFF

+#define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL  0x0000

+

+//

+// Discover() server list structure.

+//

+typedef struct {

+  UINT16          Type;

+  BOOLEAN         AcceptAnyResponse;

+  UINT8           Reserved;

+  EFI_IP_ADDRESS  IpAddr;

+} EFI_PXE_BASE_CODE_SRVLIST;

+

+//

+// Discover() information override structure.

+//

+typedef struct {

+  BOOLEAN                   UseMCast;

+  BOOLEAN                   UseBCast;

+  BOOLEAN                   UseUCast;

+  BOOLEAN                   MustUseList;

+  EFI_IP_ADDRESS            ServerMCastIp;

+  UINT16                    IpCnt;

+  EFI_PXE_BASE_CODE_SRVLIST SrvList[1];

+} EFI_PXE_BASE_CODE_DISCOVER_INFO;

+

+//

+// Mtftp() definitions

+//

+typedef enum {

+  EFI_PXE_BASE_CODE_TFTP_FIRST,

+  EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,

+  EFI_PXE_BASE_CODE_TFTP_READ_FILE,

+  EFI_PXE_BASE_CODE_TFTP_WRITE_FILE,

+  EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY,

+  EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE,

+  EFI_PXE_BASE_CODE_MTFTP_READ_FILE,

+  EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY,

+  EFI_PXE_BASE_CODE_MTFTP_LAST

+} EFI_PXE_BASE_CODE_TFTP_OPCODE;

+

+typedef struct {

+  EFI_IP_ADDRESS              MCastIp;

+  EFI_PXE_BASE_CODE_UDP_PORT  CPort;

+  EFI_PXE_BASE_CODE_UDP_PORT  SPort;

+  UINT16                      ListenTimeout;

+  UINT16                      TransmitTimeout;

+} EFI_PXE_BASE_CODE_MTFTP_INFO;

+

+//

+// PXE Base Code Mode structure

+//

+#define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES   8

+#define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8

+

+typedef struct {

+  BOOLEAN                       Started;

+  BOOLEAN                       Ipv6Available;

+  BOOLEAN                       Ipv6Supported;

+  BOOLEAN                       UsingIpv6;

+  BOOLEAN                       BisSupported;

+  BOOLEAN                       BisDetected;

+  BOOLEAN                       AutoArp;

+  BOOLEAN                       SendGUID;

+  BOOLEAN                       DhcpDiscoverValid;

+  BOOLEAN                       DhcpAckReceived;

+  BOOLEAN                       ProxyOfferReceived;

+  BOOLEAN                       PxeDiscoverValid;

+  BOOLEAN                       PxeReplyReceived;

+  BOOLEAN                       PxeBisReplyReceived;

+  BOOLEAN                       IcmpErrorReceived;

+  BOOLEAN                       TftpErrorReceived;

+  BOOLEAN                       MakeCallbacks;

+  UINT8                         TTL;

+  UINT8                         ToS;

+  EFI_IP_ADDRESS                StationIp;

+  EFI_IP_ADDRESS                SubnetMask;

+  EFI_PXE_BASE_CODE_PACKET      DhcpDiscover;

+  EFI_PXE_BASE_CODE_PACKET      DhcpAck;

+  EFI_PXE_BASE_CODE_PACKET      ProxyOffer;

+  EFI_PXE_BASE_CODE_PACKET      PxeDiscover;

+  EFI_PXE_BASE_CODE_PACKET      PxeReply;

+  EFI_PXE_BASE_CODE_PACKET      PxeBisReply;

+  EFI_PXE_BASE_CODE_IP_FILTER   IpFilter;

+  UINT32                        ArpCacheEntries;

+  EFI_PXE_BASE_CODE_ARP_ENTRY   ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES];

+  UINT32                        RouteTableEntries;

+  EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES];

+  EFI_PXE_BASE_CODE_ICMP_ERROR  IcmpError;

+  EFI_PXE_BASE_CODE_TFTP_ERROR  TftpError;

+} EFI_PXE_BASE_CODE_MODE;

+

+//

+// PXE Base Code Interface Function definitions

+//

+

+/**                                                                 

+  Enables the use of the PXE Base Code Protocol functions.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  UseIpv6               Specifies the type of IP addresses that are to be used during the session

+                                that is being started. Set to TRUE for IPv6 addresses, and FALSE for     

+                                IPv4 addresses.                                                                                                   

+                                

+  @retval EFI_SUCCESS           The PXE Base Code Protocol was started.

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this oper  

+  @retval EFI_UNSUPPORTED       UseIpv6 is TRUE, but the Ipv6Supported field of the

+                                EFI_PXE_BASE_CODE_MODE structure is FALSE.  

+  @retval EFI_ALREADY_STARTED   The PXE Base Code Protocol is already in the started state.                                   

+  @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid

+                                EFI_PXE_BASE_CODE_PROTOCOL structure.      

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough memory or other resources to start the                                          

+                                PXE Base Code Protocol.                                         

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_START) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  IN BOOLEAN                               UseIpv6

+  );

+

+/**                                                                 

+  Disables the use of the PXE Base Code Protocol functions.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+ 

+  @retval EFI_SUCCESS           The PXE Base Code Protocol was stopped.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is already in the stopped state.  

+  @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid

+                                EFI_PXE_BASE_CODE_PROTOCOL structure.                  

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.                                

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_STOP) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL    *This

+  );

+

+/**                                                                 

+  Attempts to complete a DHCPv4 D.O.R.A. (discover / offer / request / acknowledge) or DHCPv6

+  S.A.R.R (solicit / advertise / request / reply) sequence.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  SortOffers            TRUE if the offers received should be sorted. Set to FALSE to try the

+                                offers in the order that they are received.                          

+ 

+  @retval EFI_SUCCESS           Valid DHCP has completed.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid

+                                EFI_PXE_BASE_CODE_PROTOCOL structure.                  

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.                                

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough memory to complete the DHCP Protocol.

+  @retval EFI_ABORTED           The callback function aborted the DHCP Protocol.

+  @retval EFI_TIMEOUT           The DHCP Protocol timed out.

+  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the DHCP session.

+  @retval EFI_NO_RESPONSE       Valid PXE offer was not received.

+                                     

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_DHCP) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  IN BOOLEAN                               SortOffers

+  );

+

+/**                                                                 

+  Attempts to complete the PXE Boot Server and/or boot image discovery sequence.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  Type                  The type of bootstrap to perform.

+  @param  Layer                 Pointer to the boot server layer number to discover, which must be

+                                PXE_BOOT_LAYER_INITIAL when a new server type is being            

+                                discovered.                                                       

+  @param  UseBis                TRUE if Boot Integrity Services are to be used. FALSE otherwise.                                

+  @param  Info                  Pointer to a data structure that contains additional information on the

+                                type of discovery operation that is to be performed.                   

+                                  

+  @retval EFI_SUCCESS           The Discovery sequence has been completed.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.                                

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough memory to complete Discovery.

+  @retval EFI_ABORTED           The callback function aborted the Discovery sequence.

+  @retval EFI_TIMEOUT           The Discovery sequence timed out.

+  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the PXE discovery

+                                session.                                                  

+                                       

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_DISCOVER) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL           *This,

+  IN UINT16                               Type,

+  IN UINT16                               *Layer,

+  IN BOOLEAN                              UseBis,

+  IN EFI_PXE_BASE_CODE_DISCOVER_INFO      *Info   OPTIONAL

+  );

+

+/**                                                                 

+  Used to perform TFTP and MTFTP services.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  Operation             The type of operation to perform.

+  @param  BufferPtr             A pointer to the data buffer.                                                                     

+  @param  Overwrite             Only used on write file operations. TRUE if a file on a remote server can

+                                be overwritten.                                                          

+  @param  BufferSize            For get-file-size operations, *BufferSize returns the size of the

+                                requested file.                                                  

+  @param  BlockSize             The requested block size to be used during a TFTP transfer.

+  @param  ServerIp              The TFTP / MTFTP server IP address.

+  @param  Filename              A Null-terminated ASCII string that specifies a directory name or a file

+                                name.                                                                   

+  @param  Info                  Pointer to the MTFTP information.

+  @param  DontUseBuffer         Set to FALSE for normal TFTP and MTFTP read file operation.                       

+                                  

+  @retval EFI_SUCCESS           The TFTP/MTFTP operation was completed.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.                                

+  @retval EFI_BUFFER_TOO_SMALL  The buffer is not large enough to complete the read operation.   

+  @retval EFI_ABORTED           The callback function aborted the TFTP/MTFTP operation.

+  @retval EFI_TIMEOUT           The TFTP/MTFTP operation timed out.

+  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the MTFTP session.

+  @retval EFI_TFTP_ERROR        A TFTP error packet was received during the MTFTP session.

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_MTFTP) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL                *This,

+  IN EFI_PXE_BASE_CODE_TFTP_OPCODE             Operation,

+  IN OUT VOID                                  *BufferPtr OPTIONAL,

+  IN BOOLEAN                                   Overwrite,

+  IN OUT UINT64                                *BufferSize,

+  IN UINTN                                     *BlockSize OPTIONAL,

+  IN EFI_IP_ADDRESS                            *ServerIp,

+  IN UINT8                                     *Filename  OPTIONAL,

+  IN EFI_PXE_BASE_CODE_MTFTP_INFO              *Info      OPTIONAL,

+  IN BOOLEAN                                   DontUseBuffer

+  );

+

+/**                                                                 

+  Writes a UDP packet to the network interface.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  OpFlags               The UDP operation flags. 

+  @param  DestIp                The destination IP address.

+  @param  DestPort              The destination UDP port number.                                                                         

+  @param  GatewayIp             The gateway IP address.                                                 

+  @param  SrcIp                 The source IP address.

+  @param  SrcPort               The source UDP port number.

+  @param  HeaderSize            An optional field which may be set to the length of a header at

+                                HeaderPtr to be prefixed to the data at BufferPtr.             

+  @param  HeaderPtr             If HeaderSize is not NULL, a pointer to a header to be prefixed to the

+                                data at BufferPtr.                                                    

+  @param  BufferSize            A pointer to the size of the data at BufferPtr.

+  @param  BufferPtr             A pointer to the data to be written.

+                                  

+  @retval EFI_SUCCESS           The UDP Write operation was completed.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+  @retval EFI_BAD_BUFFER_SIZE   The buffer is too long to be transmitted.  

+  @retval EFI_ABORTED           The callback function aborted the UDP Write operation.

+  @retval EFI_TIMEOUT           The UDP Write operation timed out.

+  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the UDP write session.  

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL                *This,

+  IN UINT16                                    OpFlags,

+  IN EFI_IP_ADDRESS                            *DestIp,

+  IN EFI_PXE_BASE_CODE_UDP_PORT                *DestPort,

+  IN EFI_IP_ADDRESS                            *GatewayIp,  OPTIONAL

+  IN EFI_IP_ADDRESS                            *SrcIp,      OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT            *SrcPort,    OPTIONAL

+  IN UINTN                                     *HeaderSize, OPTIONAL

+  IN VOID                                      *HeaderPtr,  OPTIONAL

+  IN UINTN                                     *BufferSize,

+  IN VOID                                      *BufferPtr

+  );

+

+/**                                                                 

+  Reads a UDP packet from the network interface.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  OpFlags               The UDP operation flags. 

+  @param  DestIp                The destination IP address.

+  @param  DestPort              The destination UDP port number.                                                                         

+  @param  GatewayIp             The gateway IP address.                                                 

+  @param  SrcIp                 The source IP address.

+  @param  SrcPort               The source UDP port number.

+  @param  HeaderSize            An optional field which may be set to the length of a header at

+                                HeaderPtr to be prefixed to the data at BufferPtr.             

+  @param  HeaderPtr             If HeaderSize is not NULL, a pointer to a header to be prefixed to the

+                                data at BufferPtr.                                                    

+  @param  BufferSize            A pointer to the size of the data at BufferPtr.

+  @param  BufferPtr             A pointer to the data to be read.

+                                  

+  @retval EFI_SUCCESS           The UDP Write operation was completed.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.

+  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than Buffer can hold.

+  @retval EFI_ABORTED           The callback function aborted the UDP Read operation.

+  @retval EFI_TIMEOUT           The UDP Read operation timed out.  

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_UDP_READ) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL                *This,

+  IN UINT16                                    OpFlags,

+  IN OUT EFI_IP_ADDRESS                        *DestIp,     OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT            *DestPort,   OPTIONAL

+  IN OUT EFI_IP_ADDRESS                        *SrcIp,      OPTIONAL

+  IN OUT EFI_PXE_BASE_CODE_UDP_PORT            *SrcPort,    OPTIONAL

+  IN UINTN                                     *HeaderSize, OPTIONAL

+  IN VOID                                      *HeaderPtr,  OPTIONAL

+  IN OUT UINTN                                 *BufferSize,

+  IN VOID                                      *BufferPtr

+  );

+

+/**                                                                 

+  Updates the IP receive filters of a network device and enables software filtering.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  NewFilter             Pointer to the new set of IP receive filters.

+  

+  @retval EFI_SUCCESS           The IP receive filter settings were updated.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                  

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  IN EFI_PXE_BASE_CODE_IP_FILTER           *NewFilter

+  );

+

+/**                                                                 

+  Uses the ARP protocol to resolve a MAC address.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  IpAddr                Pointer to the IP address that is used to resolve a MAC address.

+  @param  MacAddr               If not NULL, a pointer to the MAC address that was resolved with the

+                                ARP protocol.                                                       

+                                  

+  @retval EFI_SUCCESS           The IP or MAC address was resolved.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.  

+  @retval EFI_ABORTED           The callback function aborted the ARP Protocol.

+  @retval EFI_TIMEOUT           The ARP Protocol encountered a timeout condition.

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_ARP) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  IN EFI_IP_ADDRESS                        *IpAddr,

+  IN EFI_MAC_ADDRESS                       *MacAddr OPTIONAL

+  );

+

+/**                                                                 

+  Updates the parameters that affect the operation of the PXE Base Code Protocol.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  NewAutoArp            If not NULL, a pointer to a value that specifies whether to replace the

+                                current value of AutoARP.                                              

+  @param  NewSendGUID           If not NULL, a pointer to a value that specifies whether to replace the

+                                current value of SendGUID.                                             

+  @param  NewTTL                If not NULL, a pointer to be used in place of the current value of TTL,

+                                the ¡°time to live¡± field of the IP header.                           

+  @param  NewToS                If not NULL, a pointer to be used in place of the current value of ToS,

+                                the ¡°type of service¡± field of the IP header.                        

+  @param  NewMakeCallback       If not NULL, a pointer to a value that specifies whether to replace the

+                                current value of the MakeCallback field of the Mode structure.                                                                

+                                  

+  @retval EFI_SUCCESS           The new parameters values were updated.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                  

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  IN BOOLEAN                               *NewAutoArp,     OPTIONAL

+  IN BOOLEAN                               *NewSendGUID,    OPTIONAL

+  IN UINT8                                 *NewTTL,         OPTIONAL

+  IN UINT8                                 *NewToS,         OPTIONAL

+  IN BOOLEAN                               *NewMakeCallback OPTIONAL

+  );

+

+/**                                                                 

+  Updates the station IP address and/or subnet mask values of a network device.

+    

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  NewStationIp          Pointer to the new IP address to be used by the network device.  

+  @param  NewSubnetMask         Pointer to the new subnet mask to be used by the network device.                                 

+                                  

+  @retval EFI_SUCCESS           The new station IP address and/or subnet mask were updated.

+  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                  

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  IN EFI_IP_ADDRESS                        *NewStationIp,   OPTIONAL

+  IN EFI_IP_ADDRESS                        *NewSubnetMask   OPTIONAL

+  );

+

+/**                                                                 

+  Updates the contents of the cached DHCP and Discover packets.

+    

+  @param  This                   Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

+  @param  NewDhcpDiscoverValid   Pointer to a value that will replace the current

+                                 DhcpDiscoverValid field.                        

+  @param  NewDhcpAckReceived     Pointer to a value that will replace the current

+                                 DhcpAckReceived field.                          

+  @param  NewProxyOfferReceived  Pointer to a value that will replace the current

+                                 ProxyOfferReceived field.                       

+  @param  NewPxeDiscoverValid    Pointer to a value that will replace the current     

+                                 ProxyOfferReceived field.                       

+  @param  NewPxeReplyReceived    Pointer to a value that will replace the current

+                                 PxeReplyReceived field.                         

+  @param  NewPxeBisReplyReceived Pointer to a value that will replace the current

+                                 PxeBisReplyReceived field.                      

+  @param  NewDhcpDiscover        Pointer to the new cached DHCP Discover packet contents.   

+  @param  NewDhcpAck             Pointer to the new cached DHCP Ack packet contents.

+  @param  NewProxyOffer          Pointer to the new cached Proxy Offer packet contents.

+  @param  NewPxeDiscover         Pointer to the new cached PXE Discover packet contents.

+  @param  NewPxeReply            Pointer to the new cached PXE Reply packet contents.

+  @param  NewPxeBisReply         Pointer to the new cached PXE BIS Reply packet contents.

+                                   

+  @retval EFI_SUCCESS            The cached packet contents were updated.

+  @retval EFI_NOT_STARTED        The PXE Base Code Protocol is in the stopped state.

+  @retval EFI_INVALID_PARAMETER  This is NULL or not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure.

+                                                                      

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS) (

+  IN EFI_PXE_BASE_CODE_PROTOCOL            *This,

+  BOOLEAN                                  *NewDhcpDiscoverValid,   OPTIONAL

+  BOOLEAN                                  *NewDhcpAckReceived,     OPTIONAL

+  BOOLEAN                                  *NewProxyOfferReceived,  OPTIONAL

+  BOOLEAN                                  *NewPxeDiscoverValid,    OPTIONAL

+  BOOLEAN                                  *NewPxeReplyReceived,    OPTIONAL

+  BOOLEAN                                  *NewPxeBisReplyReceived, OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET              *NewDhcpDiscover,        OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET              *NewDhcpAck,             OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET              *NewProxyOffer,          OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET              *NewPxeDiscover,         OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET              *NewPxeReply,            OPTIONAL

+  IN EFI_PXE_BASE_CODE_PACKET              *NewPxeBisReply          OPTIONAL

+  );

+

+//

+// PXE Base Code Protocol structure

+//

+#define EFI_PXE_BASE_CODE_INTERFACE_REVISION  0x00010000

+#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION   EFI_PXE_BASE_CODE_INTERFACE_REVISION

+

+struct _EFI_PXE_BASE_CODE_PROTOCOL {

+  UINT64                            Revision;

+  EFI_PXE_BASE_CODE_START           Start;

+  EFI_PXE_BASE_CODE_STOP            Stop;

+  EFI_PXE_BASE_CODE_DHCP            Dhcp;

+  EFI_PXE_BASE_CODE_DISCOVER        Discover;

+  EFI_PXE_BASE_CODE_MTFTP           Mtftp;

+  EFI_PXE_BASE_CODE_UDP_WRITE       UdpWrite;

+  EFI_PXE_BASE_CODE_UDP_READ        UdpRead;

+  EFI_PXE_BASE_CODE_SET_IP_FILTER   SetIpFilter;

+  EFI_PXE_BASE_CODE_ARP             Arp;

+  EFI_PXE_BASE_CODE_SET_PARAMETERS  SetParameters;

+  EFI_PXE_BASE_CODE_SET_STATION_IP  SetStationIp;

+  EFI_PXE_BASE_CODE_SET_PACKETS     SetPackets;

+  EFI_PXE_BASE_CODE_MODE            *Mode;

+};

+

+extern EFI_GUID gEfiPxeBaseCodeProtocolGuid;

+

+#endif 

diff --git a/edk2/MdePkg/Include/Protocol/PxeBaseCodeCallBack.h b/edk2/MdePkg/Include/Protocol/PxeBaseCodeCallBack.h
new file mode 100644
index 0000000..7f16701
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/PxeBaseCodeCallBack.h
@@ -0,0 +1,94 @@
+/** @file

+  EFI PXE Base Code CallBack Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  PxeBaseCodeCallBack.h

+

+**/

+

+#ifndef _PXE_BASE_CODE_CALLBACK_H_

+#define _PXE_BASE_CODE_CALLBACK_H_

+

+//

+// Call Back Definitions

+//

+#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID \

+  { \

+    0x245dca21, 0xfb7b, 0x11d3, {0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+//

+// Revision Number

+//

+#define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION 0x00010000

+#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION  \

+        EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION

+

+//

+// Protocol definition

+//

+typedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL;

+

+typedef enum {

+  EFI_PXE_BASE_CODE_FUNCTION_FIRST,

+  EFI_PXE_BASE_CODE_FUNCTION_DHCP,

+  EFI_PXE_BASE_CODE_FUNCTION_DISCOVER,

+  EFI_PXE_BASE_CODE_FUNCTION_MTFTP,

+  EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE,

+  EFI_PXE_BASE_CODE_FUNCTION_UDP_READ,

+  EFI_PXE_BASE_CODE_FUNCTION_ARP,

+  EFI_PXE_BASE_CODE_FUNCTION_IGMP,

+  EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST

+} EFI_PXE_BASE_CODE_FUNCTION;

+

+typedef enum {

+  EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST,

+  EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,

+  EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT,

+  EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST

+} EFI_PXE_BASE_CODE_CALLBACK_STATUS;

+

+/**                                                                 

+  Callback function that is invoked when the PXE Base Code Protocol is about to transmit, has

+  received, or is waiting to receive a packet.                                                 

+  

+  @param  This                  Pointer to the EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL instance.

+  @param  Function              The PXE Base Code Protocol function that is waiting for an event.                                                              

+  @param  Received              TRUE if the callback is being invoked due to a receive event. FALSE if

+                                the callback is being invoked due to a transmit event.                

+  @param  PacketLen             The length, in bytes, of Packet. This field will have a value of zero if

+                                this is a wait for receive event.                                       

+  @param  Packet                If Received is TRUE, a pointer to the packet that was just received;

+                                otherwise a pointer to the packet that is about to be transmitted.  

+                                  

+  @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE if Function specifies a continue operation    

+  @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT    if Function specifies an abort operation

+                                   

+**/

+typedef 

+EFI_PXE_BASE_CODE_CALLBACK_STATUS 

+(EFIAPI *EFI_PXE_CALLBACK)(

+  IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *This,

+  IN EFI_PXE_BASE_CODE_FUNCTION           Function,

+  IN BOOLEAN                              Received,

+  IN UINT32                               PacketLen,

+  IN EFI_PXE_BASE_CODE_PACKET             *Packet     OPTIONAL

+  );

+

+struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL {

+  UINT64            Revision;

+  EFI_PXE_CALLBACK  Callback;

+};

+

+extern EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid;

+

+#endif 

+

diff --git a/edk2/MdePkg/Include/Protocol/ScsiIo.h b/edk2/MdePkg/Include/Protocol/ScsiIo.h
new file mode 100644
index 0000000..e1019ba
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/ScsiIo.h
@@ -0,0 +1,233 @@
+/** @file

+  EFI_SCSI_IO_PROTOCOL as defined in UEFI 2.0.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ScsiIo.h

+

+**/

+

+#ifndef __EFI_SCSI_IO_PROTOCOL_H__

+#define __EFI_SCSI_IO_PROTOCOL_H__

+

+#define EFI_SCSI_IO_PROTOCOL_GUID \

+  { \

+    0x932f4736, 0x2362, 0x4002, {0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_SCSI_IO_PROTOCOL EFI_SCSI_IO_PROTOCOL;

+

+//

+// SCSI Data Direction definition

+//

+#define EFI_SCSI_IO_DATA_DIRECTION_READ                        0

+#define EFI_SCSI_IO_DATA_DIRECTION_WRITE                       1

+#define EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL               2

+

+//

+// SCSI Host Adapter Status definition

+//

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK                     0x00

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND        0x09    // timeout when processing the command

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT                0x0b    // timeout when waiting for the command processing

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT         0x0d    // a message reject was received when processing command

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET              0x0e    // a bus reset was detected

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR           0x0f

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED   0x10    // the adapter failed in issuing request sense command

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT      0x11    // selection timeout

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN  0x12    // data overrun or data underrun

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE               0x13    // Unexepected bus free

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR            0x14    // Target bus phase sequence failure

+#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OTHER                  0x7f

+

+

+//

+// SCSI Target Status definition

+//

+#define EFI_SCSI_IO_STATUS_TARGET_GOOD                         0x00

+#define EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION              0x02    // check condition

+#define EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET                0x04    // condition met

+#define EFI_SCSI_IO_STATUS_TARGET_BUSY                         0x08    // busy

+#define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE                 0x10    // intermediate

+#define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET   0x14    // intermediate-condition met

+#define EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT         0x18    // reservation conflict

+#define EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED           0x22    // command terminated

+#define EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL                   0x28    // queue full

+

+typedef struct {

+  UINT64                              Timeout;

+  VOID                                *InDataBuffer;

+  VOID                                *OutDataBuffer;

+  VOID                                *SenseData;

+  VOID                                *Cdb;

+  UINT32                              InTransferLength;

+  UINT32                              OutTransferLength;

+  UINT8                               CdbLength;

+  UINT8                               DataDirection;

+  UINT8                               HostAdapterStatus;

+  UINT8                               TargetStatus;

+  UINT8                               SenseDataLength;

+} EFI_SCSI_IO_SCSI_REQUEST_PACKET;

+

+/**

+  Retrieves the device type information of the SCSI Controller.

+

+  @param  This       Protocol instance pointer.

+  @param  DeviceType A pointer to the device type information

+                     retrieved from the SCSI Controller.

+

+  @retval EFI_SUCCESS           Retrieves the device type information successfully.

+  @retval EFI_INVALID_PARAMETER The DeviceType is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE) (

+  IN  EFI_SCSI_IO_PROTOCOL            *This,

+  OUT UINT8                           *DeviceType

+  )

+;

+

+/**

+  Retrieves the device location in the SCSI channel.

+

+  @param  This   Protocol instance pointer.

+  @param  Target A pointer to the Target ID of a SCSI device

+                 on the SCSI channel.

+  @param  Lun    A pointer to the LUN of the SCSI device on

+                 the SCSI channel.

+

+  @retval EFI_SUCCESS           Retrieves the device location successfully.

+  @retval EFI_INVALID_PARAMETER The Target or Lun is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION) (

+  IN EFI_SCSI_IO_PROTOCOL           *This,

+  IN OUT UINT8                      **Target,

+  OUT UINT64                        *Lun

+  )

+;

+

+/**

+  Resets the SCSI Bus that the SCSI Controller is attached to.

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS      The SCSI bus is reset successfully.

+  @retval EFI_DEVICE_ERROR Errors encountered when resetting the SCSI bus.

+  @retval EFI_UNSUPPORTED  The bus reset operation is not supported by the

+                           SCSI Host Controller.

+  @retval EFI_TIMEOUT      A timeout occurred while attempting to reset

+                            the SCSI bus.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_BUS) (

+  IN EFI_SCSI_IO_PROTOCOL     *This

+  )

+;

+

+/**

+  Resets the SCSI Controller that the device handle specifies.

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS      Reset the SCSI controller successfully.

+  @retval EFI_DEVICE_ERROR Errors are encountered when resetting the

+                           SCSI Controller.

+  @retval EFI_UNSUPPORTED  The SCSI bus does not support a device

+                           reset operation.

+  @retval EFI_TIMEOUT      A timeout occurred while attempting to

+                           reset the SCSI Controller.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_DEVICE) (

+  IN EFI_SCSI_IO_PROTOCOL     *This

+  )

+;

+

+

+/**

+  Sends a SCSI Request Packet to the SCSI Controller for execution.

+

+  @param  This    Protocol instance pointer.

+  @param  Packet  The SCSI request packet to send to the SCSI

+                  Controller specified by the device handle.

+  @param  Event   If the SCSI bus where the SCSI device is attached

+                  does not support non-blocking I/O, then Event is

+                  ignored, and blocking I/O is performed.

+                  If Event is NULL, then blocking I/O is performed.

+                  If Event is not NULL and non-blocking I/O is

+                  supported, then non-blocking I/O is performed,

+                  and Event will be signaled when the SCSI Request

+                  Packet completes.

+

+  @retval EFI_SUCCESS               The SCSI Request Packet was sent by the host

+                                    successfully, and TransferLength bytes were

+                                    transferred to/from DataBuffer.See

+                                    HostAdapterStatus, TargetStatus,

+                                    SenseDataLength, and SenseData in that order

+                                    for additional status information.

+  @retval EFI_WARN_BUFFER_TOO_SMALL The SCSI Request Packet was executed,

+                                    but the entire DataBuffer could not be transferred.

+                                    The actual number of bytes transferred is returned

+                                    in TransferLength. See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in

+                                    that order for additional status information.

+  @retval EFI_NOT_READY             The SCSI Request Packet could not be sent because

+                                    there are too many SCSI Command Packets already

+                                    queued.The caller may retry again later.

+  @retval EFI_DEVICE_ERROR          A device error occurred while attempting to send

+                                    the SCSI Request Packet. See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in

+                                    that order for additional status information.

+  @retval EFI_INVALID_PARAMETER     The contents of CommandPacket are invalid.

+                                    The SCSI Request Packet was not sent, so no

+                                    additional status information is available.

+  @retval EFI_UNSUPPORTED           The command described by the SCSI Request Packet

+                                    is not supported by the SCSI initiator(i.e., SCSI

+                                    Host Controller). The SCSI Request Packet was not

+                                    sent, so no additional status information is

+                                    available.

+  @retval EFI_TIMEOUT               A timeout occurred while waiting for the SCSI

+                                    Request Packet to execute. See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in

+                                    that order for additional status information.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND) (

+  IN EFI_SCSI_IO_PROTOCOL                   *This,

+  IN OUT  EFI_SCSI_IO_SCSI_REQUEST_PACKET   *Packet,

+  IN EFI_EVENT                              Event  OPTIONAL

+  )

+;

+

+struct _EFI_SCSI_IO_PROTOCOL {

+  EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE      GetDeviceType;

+  EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION  GetDeviceLocation;

+  EFI_SCSI_IO_PROTOCOL_RESET_BUS            ResetBus;

+  EFI_SCSI_IO_PROTOCOL_RESET_DEVICE         ResetDevice;

+  EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND    ExecuteSCSICommand;    

+  UINT32                                    IoAlign;

+};

+

+extern EFI_GUID gEfiScsiIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/ScsiPassThru.h b/edk2/MdePkg/Include/Protocol/ScsiPassThru.h
new file mode 100644
index 0000000..a5aa6c4
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/ScsiPassThru.h
@@ -0,0 +1,312 @@
+/** @file

+  SCSI Pass Through protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ScsiPassThru.h

+

+**/

+

+#ifndef __SCSI_PASS_THROUGH_H__

+#define __SCSI_PASS_THROUGH_H__

+

+#define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \

+  { \

+    0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77 } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_SCSI_PASS_THRU_PROTOCOL  EFI_SCSI_PASS_THRU_PROTOCOL;

+

+#define EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL    0x0001

+#define EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL     0x0002

+#define EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO  0x0004

+

+//

+// SCSI Host Adapter Status definition

+//

+#define EFI_SCSI_STATUS_HOST_ADAPTER_OK                     0x00

+#define EFI_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND        0x09  // timeout when processing the command

+#define EFI_SCSI_STATUS_HOST_ADAPTER_TIMEOUT                0x0b  // timeout when waiting for the command processing

+#define EFI_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT         0x0d  // a message reject was received when processing command

+#define EFI_SCSI_STATUS_HOST_ADAPTER_BUS_RESET              0x0e  // a bus reset was detected

+#define EFI_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR           0x0f

+#define EFI_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED   0x10  // the adapter failed in issuing request sense command

+#define EFI_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT      0x11  // selection timeout

+#define EFI_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN  0x12  // data overrun or data underrun

+#define EFI_SCSI_STATUS_HOST_ADAPTER_BUS_FREE               0x13  // Unexepected bus free

+#define EFI_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR            0x14  // Target bus phase sequence failure

+#define EFI_SCSI_STATUS_HOST_ADAPTER_OTHER                  0x7f

+

+//

+// SCSI Target Status definition

+//

+#define EFI_SCSI_STATUS_TARGET_GOOD                       0x00

+#define EFI_SCSI_STATUS_TARGET_CHECK_CONDITION            0x02  // check condition

+#define EFI_SCSI_STATUS_TARGET_CONDITION_MET              0x04  // condition met

+#define EFI_SCSI_STATUS_TARGET_BUSY                       0x08  // busy

+#define EFI_SCSI_STATUS_TARGET_INTERMEDIATE               0x10  // intermediate

+#define EFI_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14  // intermediate-condition met

+#define EFI_SCSI_STATUS_TARGET_RESERVATION_CONFLICT       0x18  // reservation conflict

+#define EFI_SCSI_STATUS_TARGET_COMMOND_TERMINATED         0x22  // command terminated

+#define EFI_SCSI_STATUS_TARGET_QUEUE_FULL                 0x28  // queue full

+

+typedef struct {

+  UINT64  Timeout;

+  VOID    *DataBuffer;

+  VOID    *SenseData;

+  VOID    *Cdb;

+  UINT32  TransferLength;

+  UINT8   CdbLength;

+  UINT8   DataDirection;

+  UINT8   HostAdapterStatus;

+  UINT8   TargetStatus;

+  UINT8   SenseDataLength;

+} EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET;

+

+typedef struct {

+  CHAR16  *ControllerName;

+  CHAR16  *ChannelName;

+  UINT32  AdapterId;

+  UINT32  Attributes;

+  UINT32  IoAlign;

+} EFI_SCSI_PASS_THRU_MODE;

+

+/**

+  Sends a SCSI Request Packet to a SCSI device that is attached to 

+  the SCSI channel. This function supports both blocking I/O and 

+  non-blocking I/O.  The blocking I/O functionality is required, 

+  and the non-blocking I/O functionality is optional.

+

+  @param  This   Protocol instance pointer.

+  @param  Target The Target ID of the SCSI device to

+                 send the SCSI Request Packet.

+  @param  Lun    The LUN of the SCSI device to send the

+                 SCSI Request Packet.

+  @param  Packet A pointer to the SCSI Request Packet to send

+                 to the SCSI device specified by Target and Lun.

+  @param  Event  If non-blocking I/O is not supported then Event

+                 is ignored, and blocking I/O is performed.

+                 If Event is NULL, then blocking I/O is performed.

+                 If Event is not NULL and non blocking I/O is

+                 supported, then non-blocking I/O is performed,

+                 and Event will be signaled when the SCSI Request

+                 Packet completes

+

+  @retval EFI_SUCCESS               The SCSI Request Packet was sent by the host, and

+                                    TransferLength bytes were transferred to/from

+                                    DataBuffer.See HostAdapterStatus, TargetStatus,

+                                    SenseDataLength,and SenseData in that order

+                                    for additional status information.

+  @retval EFI_WARN_BUFFER_TOO_SMALL The SCSI Request Packet was executed, but the

+                                    entire DataBuffer could not be transferred.

+                                    The actual number of bytes transferred is returned

+                                    in TransferLength. See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in

+                                    that order for additional status information.

+  @retval EFI_NOT_READY             The SCSI Request Packet could not be sent because

+                                    there are too many SCSI Request Packets already

+                                    queued.  The caller may retry again later.

+  @retval EFI_DEVICE_ERROR          A device error occurred while attempting to send

+                                    the SCSI Request Packet. See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in

+                                    that order for additional status information.

+  @retval EFI_INVALID_PARAMETER     Target, Lun, or the contents of ScsiRequestPacket

+                                    are invalid. The SCSI Request Packet was not sent,

+                                    so no additional status information is available.

+  @retval EFI_UNSUPPORTED           The command described by the SCSI Request Packet

+                                    is not supported by the host adapter. The SCSI

+                                    Request Packet was not sent, so no additional

+                                    status information is available.

+  @retval EFI_TIMEOUT               A timeout occurred while waiting for the SCSI

+                                    Request Packet to execute. See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in

+                                    that order for additional status information.

+                                    

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_PASS_THRU_PASSTHRU) (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL                          *This,

+  IN UINT32                                               Target,

+  IN UINT64                                               Lun,

+  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET           *Packet,

+  IN EFI_EVENT                                            Event   OPTIONAL

+  )

+;

+

+/**

+  Used to retrieve the list of legal Target IDs for SCSI devices 

+  on a SCSI channel.

+

+  @param  This   Protocol instance pointer.

+  @param  Target On input, a pointer to the Target ID of a

+                 SCSI device present on the SCSI channel.

+                 On output, a pointer to the Target ID of

+                 the next SCSI device present on a SCSI channel.

+                 An input value of 0xFFFFFFFF retrieves the

+                 Target ID of the first SCSI device present on

+                 a SCSI channel.

+  @param  Lun    On input, a pointer to the LUN of a SCSI device

+                 present on the SCSI channel.On output, a pointer

+                 to the LUN of the next SCSI device present on a

+                 SCSI channel.

+

+  @retval EFI_SUCCESS           The Target ID of the next SCSI device on the SCSI

+                                channel was returned in Target and Lun.

+  @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.

+  @retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF, and Target and Lun were

+                                 not returned on a previous call to GetNextDevice().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_PASS_THRU_GET_NEXT_DEVICE) (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL            *This,

+  IN OUT UINT32                             *Target,

+  IN OUT UINT64                             *Lun

+  )

+;

+

+/**

+  Used to allocate and build a device path node for a SCSI device 

+  on a SCSI channel.

+

+  @param  This       Protocol instance pointer.

+  @param  Target     The Target ID of the SCSI device for which

+                     a device path node is to be allocated and built.

+  @param  Lun        The LUN of the SCSI device for which a device

+                     path node is to be allocated and built.

+  @param  DevicePath A pointer to a single device path node that

+                     describes the SCSI device specified by

+                     Target and Lun. This function is responsible

+                     for allocating the buffer DevicePath with the boot

+                     service AllocatePool().  It is the caller's

+                     responsibility to free DevicePath when the caller

+                     is finished with DevicePath.

+

+  @retval EFI_SUCCESS           The device path node that describes the SCSI device

+                                specified by Target and Lun was allocated and

+                                returned in DevicePath.

+  @retval EFI_NOT_FOUND         The SCSI devices specified by Target and Lun does

+                                not exist on the SCSI channel.

+  @retval EFI_INVALID_PARAMETER DevicePath is NULL.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to allocate

+                                DevicePath.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_PASS_THRU_BUILD_DEVICE_PATH) (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL            *This,

+  IN     UINT32                             Target,

+  IN     UINT64                             Lun,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath

+  )

+;

+

+/**

+  Used to translate a device path node to a Target ID and LUN.

+

+  @param  This       Protocol instance pointer.

+  @param  DevicePath A pointer to the device path node that

+                     describes a SCSI device on the SCSI channel.

+  @param  Target     A pointer to the Target ID of a SCSI device

+                     on the SCSI channel.

+  @param  Lun        A pointer to the LUN of a SCSI device on

+                     the SCSI channel.

+

+  @retval EFI_SUCCESS           DevicePath was successfully translated to a

+                                Target ID and LUN, and they were returned

+                                in Target and Lun.

+  @retval EFI_INVALID_PARAMETER DevicePath is NULL.

+  @retval EFI_INVALID_PARAMETER Target is NULL.

+  @retval EFI_INVALID_PARAMETER Lun is NULL.

+  @retval EFI_UNSUPPORTED       This driver does not support the device path

+                                node type in DevicePath.

+  @retval EFI_NOT_FOUND         A valid translation from DevicePath to a

+                                Target ID and LUN does not exist.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_PASS_THRU_GET_TARGET_LUN) (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL            *This,

+  IN  EFI_DEVICE_PATH_PROTOCOL              *DevicePath,

+  OUT UINT32                                *Target,

+  OUT UINT64                                *Lun

+  )

+;

+

+/**

+  Resets a SCSI channel.This operation resets all the 

+  SCSI devices connected to the SCSI channel.

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS      The SCSI channel was reset.

+  @retval EFI_UNSUPPORTED  The SCSI channel does not support

+                           a channel reset operation.

+  @retval EFI_DEVICE_ERROR A device error occurred while

+                           attempting to reset the SCSI channel.

+  @retval EFI_TIMEOUT      A timeout occurred while attempting

+                           to reset the SCSI channel.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_PASS_THRU_RESET_CHANNEL) (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL             *This

+  )

+;

+

+/**

+  Resets a SCSI device that is connected to a SCSI channel.

+

+  @param  This   Protocol instance pointer.

+  @param  Target The Target ID of the SCSI device to reset.

+  @param  Lun    The LUN of the SCSI device to reset.

+

+  @retval EFI_SUCCESS           The SCSI device specified by Target and

+                                Lun was reset.

+  @retval EFI_UNSUPPORTED       The SCSI channel does not support a target

+                                reset operation.

+  @retval EFI_INVALID_PARAMETER Target or Lun are invalid.

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting

+                                to reset the SCSI device specified by Target

+                                and Lun.

+  @retval EFI_TIMEOUT           A timeout occurred while attempting to reset

+                                the SCSI device specified by Target and Lun.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SCSI_PASS_THRU_RESET_TARGET) (

+  IN EFI_SCSI_PASS_THRU_PROTOCOL             *This,

+  IN UINT32                                  Target,

+  IN UINT64                                  Lun

+  )

+;

+

+struct _EFI_SCSI_PASS_THRU_PROTOCOL {

+  EFI_SCSI_PASS_THRU_MODE               *Mode;

+  EFI_SCSI_PASS_THRU_PASSTHRU           PassThru;

+  EFI_SCSI_PASS_THRU_GET_NEXT_DEVICE    GetNextDevice;

+  EFI_SCSI_PASS_THRU_BUILD_DEVICE_PATH  BuildDevicePath;

+  EFI_SCSI_PASS_THRU_GET_TARGET_LUN     GetTargetLun;

+  EFI_SCSI_PASS_THRU_RESET_CHANNEL      ResetChannel;

+  EFI_SCSI_PASS_THRU_RESET_TARGET       ResetTarget;

+};

+

+extern EFI_GUID gEfiScsiPassThruProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/ScsiPassThruExt.h b/edk2/MdePkg/Include/Protocol/ScsiPassThruExt.h
new file mode 100644
index 0000000..b522792
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/ScsiPassThruExt.h
@@ -0,0 +1,332 @@
+/** @file

+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL as defined in UEFI 2.0.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ScsiPassThruExt.h

+

+**/

+

+#ifndef __EXT_SCSI_PASS_THROUGH_PROTOCOL_H__

+#define __EXT_SCSI_PASS_THROUGH_PROTOCOL_H__

+

+#define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \

+  { \

+    0x1d3de7f0, 0x0807, 0x424f, {0xaa, 0x69, 0x11, 0xa5, 0x4e, 0x19, 0xa4, 0x6f } \

+  }

+

+typedef struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL EFI_EXT_SCSI_PASS_THRU_PROTOCOL;

+

+#define TARGET_MAX_BYTES                             0x10

+

+#define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL   0x0001

+#define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL    0x0002

+#define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004

+

+//

+// DataDirection

+//

+#define EFI_EXT_SCSI_DATA_DIRECTION_READ             0

+#define EFI_EXT_SCSI_DATA_DIRECTION_WRITE            1

+#define EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL    2

+//

+// HostAdapterStatus

+//

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK                    0x00

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND       0x09

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT               0x0b

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT        0x0d

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET             0x0e

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR          0x0f

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED  0x10

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT     0x11

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE              0x13

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR           0x14

+#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER                 0x7f

+//

+// TargetStatus

+//

+#define EFI_EXT_SCSI_STATUS_TARGET_GOOD                        0x00

+#define EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION             0x02

+#define EFI_EXT_SCSI_STATUS_TARGET_CONDITION_MET               0x04

+#define EFI_EXT_SCSI_STATUS_TARGET_BUSY                        0x08

+#define EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE                0x10

+#define EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET  0x14

+#define EFI_EXT_SCSI_STATUS_TARGET_RESERVATION_CONFLICT        0x18

+#define EFI_EXT_SCSI_STATUS_TARGET_TASK_SET_FULL               0x28

+#define EFI_EXT_SCSI_STATUS_TARGET_ACA_ACTIVE                  0x30

+#define EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED                0x40

+

+typedef struct {

+  UINT32 AdapterId;

+  UINT32 Attributes;

+  UINT32 IoAlign;

+} EFI_EXT_SCSI_PASS_THRU_MODE;

+

+typedef struct {

+  UINT64 Timeout;

+  VOID   *InDataBuffer;

+  VOID   *OutDataBuffer;

+  VOID   *SenseData;

+  VOID   *Cdb;

+  UINT32 InTransferLength;

+  UINT32 OutTransferLength;

+  UINT8  CdbLength;

+  UINT8  DataDirection;

+  UINT8  HostAdapterStatus;

+  UINT8  TargetStatus;

+  UINT8  SenseDataLength;

+} EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET;

+

+/**

+  Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function   

+  supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the

+  nonblocking I/O functionality is optional.                                                             

+

+  @param  This    A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+  @param  Target  The Target is an array of size TARGET_MAX_BYTES and it represents

+                  the id of the SCSI device to send the SCSI Request Packet. Each

+                  transport driver may chose to utilize a subset of this size to suit the needs

+                  of transport target representation. For example, a Fibre Channel driver

+                  may use only 8 bytes (WWN) to represent an FC target.

+  @param  Lun     The LUN of the SCSI device to send the SCSI Request Packet.

+  @param  Packet  A pointer to the SCSI Request Packet to send to the SCSI device

+                  specified by Target and Lun.

+  @param  Event   If nonblocking I/O is not supported then Event is ignored, and blocking

+                  I/O is performed. If Event is NULL, then blocking I/O is performed. If

+                  Event is not NULL and non blocking I/O is supported, then

+                  nonblocking I/O is performed, and Event will be signaled when the

+                  SCSI Request Packet completes.

+

+  @retval EFI_SUCCESS           The SCSI Request Packet was sent by the host. For bi-directional

+                                commands, InTransferLength bytes were transferred from

+                                InDataBuffer. For write and bi-directional commands,

+                                OutTransferLength bytes were transferred by

+                                OutDataBuffer.

+  @retval EFI_BAD_BUFFER_SIZE   The SCSI Request Packet was not executed. The number of bytes that

+                                could be transferred is returned in InTransferLength. For write

+                                and bi-directional commands, OutTransferLength bytes were

+                                transferred by OutDataBuffer.

+  @retval EFI_NOT_READY         The SCSI Request Packet could not be sent because there are too many

+                                SCSI Request Packets already queued. The caller may retry again later.

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to send the SCSI Request

+                                Packet.

+  @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket are invalid.

+  @retval EFI_UNSUPPORTED       The command described by the SCSI Request Packet is not supported

+                                by the host adapter. This includes the case of Bi-directional SCSI

+                                commands not supported by the implementation. The SCSI Request

+                                Packet was not sent, so no additional status information is available.

+  @retval EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_PASSTHRU) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                *This,

+  IN UINT8                                          *Target,

+  IN UINT64                                         Lun,

+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,

+  IN EFI_EVENT                                      Event     OPTIONAL

+  )

+;      

+

+/**

+  Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on a SCSI channel. These       

+  can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal

+  Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the       

+  Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI    

+  channel.                                                                                               

+

+  @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+  @param  Target On input, a pointer to the Target ID (an array of size

+                 TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel.

+                 On output, a pointer to the Target ID (an array of

+                 TARGET_MAX_BYTES) of the next SCSI device present on a SCSI

+                 channel. An input value of 0xF(all bytes in the array are 0xF) in the

+                 Target array retrieves the Target ID of the first SCSI device present on a

+                 SCSI channel.

+  @param  Lun    On input, a pointer to the LUN of a SCSI device present on the SCSI

+                 channel. On output, a pointer to the LUN of the next SCSI device present

+                 on a SCSI channel.

+

+  @retval EFI_SUCCESS           The Target ID and LUN of the next SCSI device on the SCSI

+                                channel was returned in Target and Lun.

+  @retval EFI_INVALID_PARAMETER Target array is not all 0xF, and Target and Lun were

+                                not returned on a previous call to GetNextTargetLun().

+  @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                *This,

+  IN OUT UINT8                                      **Target,

+  IN OUT UINT64                                     *Lun

+  )

+;   

+

+/**

+  Used to allocate and build a device path node for a SCSI device on a SCSI channel.

+

+  @param  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+  @param  Target     The Target is an array of size TARGET_MAX_BYTES and it specifies the

+                     Target ID of the SCSI device for which a device path node is to be

+                     allocated and built. Transport drivers may chose to utilize a subset of

+                     this size to suit the representation of targets. For example, a Fibre

+                     Channel driver may use only 8 bytes (WWN) in the array to represent a

+                     FC target.

+  @param  Lun        The LUN of the SCSI device for which a device path node is to be

+                     allocated and built.

+  

+  @param  DevicePath A pointer to a single device path node that describes the SCSI device

+                     specified by Target and Lun. This function is responsible for

+                     allocating the buffer DevicePath with the boot service

+                     AllocatePool(). It is the caller's responsibility to free

+                     DevicePath when the caller is finished with DevicePath.

+

+  @retval EFI_SUCCESS           The device path node that describes the SCSI device specified by

+                                Target and Lun was allocated and returned in

+                                DevicePath.

+  @retval EFI_INVALID_PARAMETER DevicePath is NULL.

+  @retval EFI_NOT_FOUND         The SCSI devices specified by Target and Lun does not exist

+                                on the SCSI channel.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to allocate DevicePath.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL               *This,

+  IN UINT8                                         *Target,

+  IN UINT64                                        Lun,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL                  **DevicePath

+  )

+;     

+

+/**

+  Used to translate a device path node to a Target ID and LUN.

+

+  @param  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+  @param  DevicePath A pointer to a single device path node that describes the SCSI device

+                     on the SCSI channel.

+  @param  Target     A pointer to the Target Array which represents the ID of a SCSI device

+                     on the SCSI channel.

+  @param  Lun        A pointer to the LUN of a SCSI device on the SCSI channel.

+

+  @retval EFI_SUCCESS           DevicePath was successfully translated to a Target ID and

+                                LUN, and they were returned in Target and Lun.

+  @retval EFI_INVALID_PARAMETER DevicePath or Target or Lun is NULL.

+  @retval EFI_NOT_FOUND         A valid translation from DevicePath to a Target ID and LUN

+                                does not exist.

+  @retval EFI_UNSUPPORTED       This driver does not support the device path node type in

+                                 DevicePath.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL               *This,

+  IN EFI_DEVICE_PATH_PROTOCOL                      *DevicePath,

+  OUT UINT8                                        **Target,

+  OUT UINT64                                       *Lun

+  )

+;       

+

+/**

+  Resets a SCSI channel. This operation resets all the SCSI devices connected to the SCSI channel.

+

+  @param  This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+

+  @retval EFI_SUCCESS      The SCSI channel was reset.

+  @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI channel.

+  @retval EFI_TIMEOUT      A timeout occurred while attempting to reset the SCSI channel.

+  @retval EFI_UNSUPPORTED  The SCSI channel does not support a channel reset operation.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL               *This

+  )

+;    

+  

+/**

+  Resets a SCSI logical unit that is connected to a SCSI channel.

+

+  @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+  @param  Target The Target is an array of size TARGET_MAX_BYTE and it represents the

+                 target port ID of the SCSI device containing the SCSI logical unit to

+                 reset. Transport drivers may chose to utilize a subset of this array to suit

+                 the representation of their targets.

+  @param  Lun    The LUN of the SCSI device to reset.

+

+  @retval EFI_SUCCESS           The SCSI device specified by Target and Lun was reset.

+  @retval EFI_INVALID_PARAMETER Target or Lun is NULL.

+  @retval EFI_TIMEOUT           A timeout occurred while attempting to reset the SCSI device

+                                specified by Target and Lun.

+  @retval EFI_UNSUPPORTED       The SCSI channel does not support a target reset operation.

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to reset the SCSI device

+                                 specified by Target and Lun.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL               *This,

+  IN UINT8                                         *Target,

+  IN UINT64                                        Lun

+  )

+;         

+

+/**

+  Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either     

+  be the list SCSI devices that are actually present on the SCSI channel, or the list of legal Target IDs

+  for the SCSI channel. Regardless, the caller of this function must probe the Target ID returned to     

+  see if a SCSI device is actually present at that location on the SCSI channel.                         

+

+  @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

+  @param  Target (TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel.

+                 On output, a pointer to the Target ID (an array of

+                 TARGET_MAX_BYTES) of the next SCSI device present on a SCSI

+                 channel. An input value of 0xF(all bytes in the array are 0xF) in the

+                 Target array retrieves the Target ID of the first SCSI device present on a

+                 SCSI channel.

+

+  @retval EFI_SUCCESS           The Target ID of the next SCSI device on the SCSI

+                                channel was returned in Target.

+  @retval EFI_INVALID_PARAMETER Target or Lun is NULL.

+  @retval EFI_TIMEOUT           Target array is not all 0xF, and Target were not

+                                returned on a previous call to GetNextTarget().

+  @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET) (

+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL               *This,

+  IN OUT UINT8                                     **Target

+  )

+;          

+  

+struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL {

+  EFI_EXT_SCSI_PASS_THRU_MODE                *Mode;

+  EFI_EXT_SCSI_PASS_THRU_PASSTHRU            PassThru;

+  EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN GetNextTargetLun;

+  EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH   BuildDevicePath;

+  EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN      GetTargetLun;

+  EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL       ResetChannel;

+  EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN    ResetTargetLun;

+  EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET     GetNextTarget;

+};

+

+extern EFI_GUID gEfiExtScsiPassThruProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SectionExtraction.h b/edk2/MdePkg/Include/Protocol/SectionExtraction.h
new file mode 100644
index 0000000..9200f8a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SectionExtraction.h
@@ -0,0 +1,162 @@
+/** @file

+  This file declares Section Extraction protocols.

+

+  This interface provides a means of decoding a set of sections into a linked list of

+  leaf sections.  This provides for an extensible and flexible file format.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. This program and the 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.             

+

+  Module Name:  SectionExtraction.h

+

+  @par Revision Reference:

+  This protocol is defined in Firmware Volume Specification.

+  Version 0.9

+

+**/

+

+#ifndef __SECTION_EXTRACTION_PROTOCOL_H__

+#define __SECTION_EXTRACTION_PROTOCOL_H__

+

+

+//

+// Protocol GUID definition

+//

+#define EFI_SECTION_EXTRACTION_PROTOCOL_GUID \

+  { \

+    0x448F5DA4, 0x6DD7, 0x4FE1, {0x93, 0x07, 0x69, 0x22, 0x41, 0x92, 0x21, 0x5D } \

+  }

+

+typedef struct _EFI_SECTION_EXTRACTION_PROTOCOL EFI_SECTION_EXTRACTION_PROTOCOL;

+

+//

+// Protocol member functions

+//

+/**

+  Creates and returns a new section stream handle to represent the new section stream.

+

+  @param  This                  Indicates the EFI_SECTION_EXTRACTION_PROTOCOL instance.  

+  @param  SectionStreamLength   Size in bytes of the section stream.  

+  @param  SectionStream         Buffer containing the new section stream.  

+  @param  SectionStreamHandle   A pointer to a caller-allocated UINTN that, 

+                                on output, contains the new section stream handle.

+

+  @retval EFI_SUCCESS           The SectionStream  was successfully processed and 

+                                the section stream handle was returned.  

+  @retval EFI_OUT_OF_RESOURCES  The system has insufficient resources to 

+                                process the request.  

+  @retval EFI_INVALID_PARAMETER The section stream may be corrupt or the value 

+                                of SectionStreamLength may be incorrect.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_OPEN_SECTION_STREAM) (

+  IN  EFI_SECTION_EXTRACTION_PROTOCOL                   *This,

+  IN  UINTN                                             SectionStreamLength,

+  IN  VOID                                              *SectionStream,

+  OUT UINTN                                             *SectionStreamHandle

+  );

+

+/**

+  Reads and returns a single section from a section stream.

+

+  @param  This                  Indicates the EFI_SECTION_EXTRACTION_PROTOCOL instance.                                

+  @param  SectionStreamHandle   Indicates from which section stream to read.                                

+  @param  SectionType           Pointer to an EFI_SECTION_TYPE.  

+  @param  SectionDefinitionGuid Pointer to an EFI_GUID.If SectionType == 

+                                EFI_SECTION_GUID_DEFINED, SectionDefinitionGuid indicates what section GUID 

+                                to search for.If SectionType !=EFI_SECTION_GUID_DEFINED, then 

+                                SectionDefinitionGuid is unused and is ignored.  

+  @param  SectionInstance       Indicates which instance of the requested section 

+                                type to return when SectionType is not NULL.  

+  @param  SectionStreamHandle   A pointer to a caller-allocated UINTN that, on output,

+                                contains the new section stream handle.  

+  @param  Buffer                Pointer to a pointer to a buffer in which the section 

+                                contents are returned.   

+  @param  BufferSize            Pointer to a caller-allocated UINTN.  

+  @param  AuthenticationStatus  Pointer to a caller-allocated UINT32 in 

+                                which any meta-data from encapsulation GUID-defined sections is returned.

+

+  @retval EFI_SUCCESS           The SectionStream was successfully processed and 

+                                the section contents were returned in Buffer.  

+  @retval EFI_PROTOCOL_ERROR    A GUID-defined section was encountered in 

+                                the section stream with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED bit set, 

+                                but there was no corresponding GUIDed Section Extraction Protocol in 

+                                the handle database.  

+  @retval EFI_NOT_FOUND         An error was encountered when parsing the SectionStream, 

+                                which indicates that the SectionStream is not correctly formatted.

+                                Or The requested section does not exist.  

+  @retval EFI_OUT_OF_RESOURCES  The system has insufficient resources to process 

+                                the request.  

+  @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist.  

+  @retval EFI_BUFFER_TOO_SMALL  The size of the input buffer is insufficient to 

+                                contain the requested section.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_SECTION) (

+  IN EFI_SECTION_EXTRACTION_PROTOCOL                    *This,

+  IN UINTN                                              SectionStreamHandle,

+  IN EFI_SECTION_TYPE                                   *SectionType,

+  IN EFI_GUID                                           *SectionDefinitionGuid,

+  IN UINTN                                              SectionInstance,

+  IN VOID                                               **Buffer,

+  IN OUT UINTN                                          *BufferSize,

+  OUT UINT32                                            *AuthenticationStatus

+  );

+

+/**

+  Deletes a section stream handle and returns all associated resources to the system.

+

+  @param  This                  Indicates the EFI_SECTION_EXTRACTION_PROTOCOL instance.  

+  @param  SectionStreamHandle   Indicates the section stream to close.

+  

+  @retval EFI_SUCCESS           The SectionStream was successfully processed and 

+                                the section stream handle was returned.

+  

+  @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CLOSE_SECTION_STREAM) (

+  IN EFI_SECTION_EXTRACTION_PROTOCOL                    *This,

+  IN UINTN                                              SectionStreamHandle

+  );

+

+//

+// Protocol definition

+//

+/**

+  @par Protocol Description:

+  The Section Extraction Protocol provides a simple method of extracting 

+  sections from arbitrarily complex files.

+

+  @param OpenSectionStream

+  Takes a bounded stream of sections and returns a section stream handle. 

+

+  @param GetSection

+  Given a section stream handle, retrieves the requested section and 

+  meta-data from the section stream. 

+

+  @param CloseSectionStream

+  Given a section stream handle, closes the section stream.

+

+**/

+struct _EFI_SECTION_EXTRACTION_PROTOCOL {

+  EFI_OPEN_SECTION_STREAM   OpenSectionStream;

+  EFI_GET_SECTION           GetSection;

+  EFI_CLOSE_SECTION_STREAM  CloseSectionStream;

+};

+

+extern EFI_GUID gEfiSectionExtractionProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SerialIo.h b/edk2/MdePkg/Include/Protocol/SerialIo.h
new file mode 100644
index 0000000..89a7340
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SerialIo.h
@@ -0,0 +1,266 @@
+/** @file

+  Serial IO protocol as defined in the EFI 1.0 specification.

+

+  Abstraction of a basic serial device. Targeted at 16550 UART, but

+  could be much more generic.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SerialIo.h

+

+**/

+

+#ifndef __SERIAL_IO_PROTOCOL_H__

+#define __SERIAL_IO_PROTOCOL_H__

+

+#define EFI_SERIAL_IO_PROTOCOL_GUID \

+  { \

+    0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD } \

+  }

+

+typedef struct _EFI_SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL;

+

+//

+// Serial IO Data structures

+//

+typedef enum {

+  DefaultParity,

+  NoParity,

+  EvenParity,

+  OddParity,

+  MarkParity,

+  SpaceParity

+} EFI_PARITY_TYPE;

+

+typedef enum {

+  DefaultStopBits,

+  OneStopBit,

+  OneFiveStopBits,

+  TwoStopBits

+} EFI_STOP_BITS_TYPE;

+

+//

+// define for Control bits, grouped by read only, write only, and read write

+//

+//

+// Read Only

+//

+#define EFI_SERIAL_CLEAR_TO_SEND        0x00000010

+#define EFI_SERIAL_DATA_SET_READY       0x00000020

+#define EFI_SERIAL_RING_INDICATE        0x00000040

+#define EFI_SERIAL_CARRIER_DETECT       0x00000080

+#define EFI_SERIAL_INPUT_BUFFER_EMPTY   0x00000100

+#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY  0x00000200

+

+//

+// Write Only

+//

+#define EFI_SERIAL_REQUEST_TO_SEND      0x00000002

+#define EFI_SERIAL_DATA_TERMINAL_READY  0x00000001

+

+//

+// Read Write

+//

+#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE     0x00001000

+#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE     0x00002000

+#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000

+

+//

+// Serial IO Member Functions

+//

+/**

+  Reset the serial device.

+

+  @param  This              Protocol instance pointer.

+                            

+  @retval EFI_SUCCESS       The device was reset.

+  @retval EFI_DEVICE_ERROR  The serial device could not be reset.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERIAL_RESET) (

+  IN EFI_SERIAL_IO_PROTOCOL *This

+  )

+;

+

+/**

+  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, 

+  data buts, and stop bits on a serial device.

+

+  @param  This             Protocol instance pointer.

+  @param  BaudRate         The requested baud rate. A BaudRate value of 0 will use the the

+                           device's default interface speed.

+  @param  ReveiveFifoDepth The requested depth of the FIFO on the receive side of the

+                           serial interface. A ReceiveFifoDepth value of 0 will use

+                           the device's dfault FIFO depth.

+  @param  Timeout          The requested time out for a single character in microseconds.

+                           This timeout applies to both the transmit and receive side of the

+                           interface. A Timeout value of 0 will use the device's default time

+                           out value.

+  @param  Parity           The type of parity to use on this serial device. A Parity value of

+                           DefaultParity will use the device's default parity value.

+  @param  DataBits         The number of data bits to use on the serial device. A DataBits

+                           vaule of 0 will use the device's default data bit setting.

+  @param  StopBits         The number of stop bits to use on this serial device. A StopBits

+                           value of DefaultStopBits will use the device's default number of

+                           stop bits.

+

+  @retval EFI_SUCCESS      The device was reset.

+  @retval EFI_DEVICE_ERROR The serial device could not be reset.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES) (

+  IN EFI_SERIAL_IO_PROTOCOL         *This,

+  IN UINT64                         BaudRate,

+  IN UINT32                         ReceiveFifoDepth,

+  IN UINT32                         Timeout,

+  IN EFI_PARITY_TYPE                Parity,

+  IN UINT8                          DataBits,

+  IN EFI_STOP_BITS_TYPE             StopBits

+  )

+;

+

+/**

+  Set the control bits on a serial device

+

+  @param  This             Protocol instance pointer.

+  @param  Control          Set the bits of Control that are settable.

+

+  @retval EFI_SUCCESS      The new control bits were set on the serial device.

+  @retval EFI_UNSUPPORTED  The serial device does not support this operation.

+  @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS) (

+  IN EFI_SERIAL_IO_PROTOCOL         *This,

+  IN UINT32                         Control

+  )

+;

+

+/**

+  Retrieves the status of thecontrol bits on a serial device

+

+  @param  This              Protocol instance pointer.

+  @param  Control           A pointer to return the current Control signals from the serial device.

+                            

+  @retval EFI_SUCCESS       The control bits were read from the serial device.

+  @retval EFI_DEVICE_ERROR  The serial device is not functioning correctly.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS) (

+  IN EFI_SERIAL_IO_PROTOCOL         *This,

+  OUT UINT32                        *Control

+  )

+;

+

+/**

+  Writes data to a serial device.

+

+  @param  This              Protocol instance pointer.

+  @param  BufferSize        On input, the size of the Buffer. On output, the amount of

+                            data actually written.

+  @param  Buffer            The buffer of data to write

+

+  @retval EFI_SUCCESS       The data was written.

+  @retval EFI_DEVICE_ERROR  The device reported an error.

+  @retval EFI_TIMEOUT       The data write was stopped due to a timeout.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERIAL_WRITE) (

+  IN EFI_SERIAL_IO_PROTOCOL         *This,

+  IN OUT UINTN                      *BufferSize,

+  IN VOID                           *Buffer

+  )

+;

+

+/**

+  Writes data to a serial device.

+

+  @param  This              Protocol instance pointer.

+  @param  BufferSize        On input, the size of the Buffer. On output, the amount of

+                            data returned in Buffer.

+  @param  Buffer            The buffer to return the data into.

+

+  @retval EFI_SUCCESS       The data was read.

+  @retval EFI_DEVICE_ERROR  The device reported an error.

+  @retval EFI_TIMEOUT       The data write was stopped due to a timeout.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERIAL_READ) (

+  IN EFI_SERIAL_IO_PROTOCOL         *This,

+  IN OUT UINTN                      *BufferSize,

+  OUT VOID                          *Buffer

+  )

+;

+

+/**

+  The data values in SERIAL_IO_MODE are read-only and are updated by the code 

+  that produces the SERIAL_IO_PROTOCOL member functions.

+

+  ControlMask - A mask fo the Control bits that the device supports. The device

+  must always support the Input Buffer Empty control bit.

+  TimeOut  - If applicable, the number of microseconds to wait before timing out

+  a Read or Write operation.

+  BaudRate - If applicable, the current baud rate setting of the device; otherwise,

+  baud rate has the value of zero to indicate that device runs at the

+  device's designed speed.

+  ReceiveFifoDepth - The number of characters the device will buffer on input

+  DataBits - The number of characters the device will buffer on input

+  Parity   - If applicable, this is the EFI_PARITY_TYPE that is computed or 

+  checked as each character is transmitted or reveived. If the device

+  does not support parity the value is the default parity value.

+  StopBits - If applicable, the EFI_STOP_BITS_TYPE number of stop bits per

+  character. If the device does not support stop bits the value is

+  the default stop bit values.

+

+**/

+typedef struct {

+  UINT32  ControlMask;

+

+  //

+  // current Attributes

+  //

+  UINT32  Timeout;

+  UINT64  BaudRate;

+  UINT32  ReceiveFifoDepth;

+  UINT32  DataBits;

+  UINT32  Parity;

+  UINT32  StopBits;

+} EFI_SERIAL_IO_MODE;

+

+#define SERIAL_IO_INTERFACE_REVISION    0x00010000

+#define EFI_SERIAL_IO_PROTOCOL_REVISION SERIAL_IO_INTERFACE_REVISION

+

+struct _EFI_SERIAL_IO_PROTOCOL {

+  UINT32                      Revision;

+  EFI_SERIAL_RESET            Reset;

+  EFI_SERIAL_SET_ATTRIBUTES   SetAttributes;

+  EFI_SERIAL_SET_CONTROL_BITS SetControl;

+  EFI_SERIAL_GET_CONTROL_BITS GetControl;

+  EFI_SERIAL_WRITE            Write;

+  EFI_SERIAL_READ             Read;

+

+  EFI_SERIAL_IO_MODE          *Mode;

+};

+

+extern EFI_GUID gEfiSerialIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/ServiceBinding.h b/edk2/MdePkg/Include/Protocol/ServiceBinding.h
new file mode 100644
index 0000000..57ce92f
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/ServiceBinding.h
@@ -0,0 +1,74 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ServiceBinding.h

+

+**/

+

+#ifndef __EFI_SERVICE_BINDING_H__

+#define __EFI_SERVICE_BINDING_H__

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_SERVICE_BINDING_PROTOCOL EFI_SERVICE_BINDING_PROTOCOL;

+

+/**

+  Creates a child handle with a set of I/O services.

+

+  @param  This        Protocol instance pointer.

+  @param  ChildHandle Pointer to the handle of the child to create.  If it is NULL,

+                      then a new handle is created.  If it is not NULL, then the

+                      I/O services are added to the existing child handle.

+

+  @retval EFI_SUCCES            The child handle was created with the I/O services

+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create

+                                the child

+  @retval other                 The child handle was not created

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERVICE_BINDING_CREATE_CHILD) (

+  IN     EFI_SERVICE_BINDING_PROTOCOL  *This,

+  IN OUT EFI_HANDLE                    *ChildHandle

+  )

+;

+

+/**

+  Destroys a child handle with a set of I/O services.

+

+  @param  This        Protocol instance pointer.

+  @param  ChildHandle Handle of the child to destroy

+

+  @retval EFI_SUCCES            The I/O services were removed from the child handle

+  @retval EFI_UNSUPPORTED       The child handle does not support the I/O services

+                                that are being removed.

+  @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.

+  @retval EFI_ACCESS_DENIED     The child handle could not be destroyed because its

+                                I/O services are being used.

+  @retval other                 The child handle was not destroyed

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SERVICE_BINDING_DESTROY_CHILD) (

+  IN EFI_SERVICE_BINDING_PROTOCOL          *This,

+  IN EFI_HANDLE                            ChildHandle

+  )

+;

+

+struct _EFI_SERVICE_BINDING_PROTOCOL {

+  EFI_SERVICE_BINDING_CREATE_CHILD         CreateChild;

+  EFI_SERVICE_BINDING_DESTROY_CHILD        DestroyChild;

+};

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SimpleFileSystem.h b/edk2/MdePkg/Include/Protocol/SimpleFileSystem.h
new file mode 100644
index 0000000..add8ad6
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SimpleFileSystem.h
@@ -0,0 +1,328 @@
+/** @file

+  SimpleFileSystem protocol as defined in the EFI 1.0 specification.

+

+  The SimpleFileSystem protocol is the programatic access to the FAT (12,16,32) 

+  file system specified in EFI 1.0. It can also be used to abstract a file  

+  system other than FAT.

+

+  EFI 1.0 can boot from any valid EFI image contained in a SimpleFileSystem

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SimpleFileSystem.h

+

+**/

+

+#ifndef __SIMPLE_FILE_SYSTEM_H__

+#define __SIMPLE_FILE_SYSTEM_H__

+

+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \

+  { \

+    0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;

+typedef struct _EFI_FILE  EFI_FILE;

+typedef struct _EFI_FILE  *EFI_FILE_HANDLE;

+typedef struct _EFI_FILE  EFI_FILE_PROTOCOL;

+

+/**

+  Open the root directory on a volume.

+

+  @param  This Protocol instance pointer.

+  @param  Root Returns an Open file handle for the root directory

+

+  @retval EFI_SUCCESS          The device was opened.

+  @retval EFI_UNSUPPORTED      This volume does not suppor the file system.

+  @retval EFI_NO_MEDIA         The device has no media.

+  @retval EFI_DEVICE_ERROR     The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_ACCESS_DENIED    The service denied access to the file

+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME) (

+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    *This,

+  OUT EFI_FILE                          **Root

+  )

+;

+

+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION  0x00010000

+

+struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {

+  UINT64                                      Revision;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume;

+};

+

+/**

+  Open the root directory on a volume.

+

+  @param  This       Protocol instance pointer.

+  @param  NewHandle  Returns File Handle for FileName

+  @param  FileName   Null terminated string. "\", ".", and ".." are supported

+  @param  OpenMode   Open mode for file.

+  @param  Attributes Only used for EFI_FILE_MODE_CREATE

+

+  @retval EFI_SUCCESS          The device was opened.

+  @retval EFI_NOT_FOUND        The specified file could not be found on the device

+  @retval EFI_NO_MEDIA         The device has no media.

+  @retval EFI_MEDIA_CHANGED    The media has changed

+  @retval EFI_DEVICE_ERROR     The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_ACCESS_DENIED    The service denied access to the file

+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources

+  @retval EFI_VOLUME_FULL      The volume is full.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_OPEN) (

+  IN EFI_FILE                 *This,

+  OUT EFI_FILE                **NewHandle,

+  IN CHAR16                   *FileName,

+  IN UINT64                   OpenMode,

+  IN UINT64                   Attributes

+  )

+;

+

+//

+// Open modes

+//

+#define EFI_FILE_MODE_READ    0x0000000000000001ULL

+#define EFI_FILE_MODE_WRITE   0x0000000000000002ULL

+#define EFI_FILE_MODE_CREATE  0x8000000000000000ULL

+

+//

+// File attributes

+//

+#define EFI_FILE_READ_ONLY  0x0000000000000001ULL

+#define EFI_FILE_HIDDEN     0x0000000000000002ULL

+#define EFI_FILE_SYSTEM     0x0000000000000004ULL

+#define EFI_FILE_RESERVED   0x0000000000000008ULL

+#define EFI_FILE_DIRECTORY  0x0000000000000010ULL

+#define EFI_FILE_ARCHIVE    0x0000000000000020ULL

+#define EFI_FILE_VALID_ATTR 0x0000000000000037ULL

+

+/**

+  Close the file handle

+

+  @param  This          Protocol instance pointer.

+

+  @retval EFI_SUCCESS   The device was opened.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_CLOSE) (

+  IN EFI_FILE  *This

+  )

+;

+

+/**

+  Close and delete the file handle

+

+  @param  This                     Protocol instance pointer.

+                                   

+  @retval EFI_SUCCESS              The device was opened.

+  @retval EFI_WARN_DELETE_FAILURE  The handle was closed but the file was not deleted

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_DELETE) (

+  IN EFI_FILE  *This

+  )

+;

+

+/**

+  Read data from the file.

+

+  @param  This       Protocol instance pointer.

+  @param  BufferSize On input size of buffer, on output amount of data in buffer.

+  @param  Buffer     The buffer in which data is read.

+

+  @retval EFI_SUCCESS          Data was read.

+  @retval EFI_NO_MEDIA         The device has no media

+  @retval EFI_DEVICE_ERROR     The device reported an error

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_BUFFER_TO_SMALL  BufferSize is too small. BufferSize contains required size

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_READ) (

+  IN EFI_FILE                 *This,

+  IN OUT UINTN                *BufferSize,

+  OUT VOID                    *Buffer

+  )

+;

+

+/**

+  Write data from to the file.

+

+  @param  This       Protocol instance pointer.

+  @param  BufferSize On input size of buffer, on output amount of data in buffer.

+  @param  Buffer     The buffer in which data to write.

+

+  @retval EFI_SUCCESS          Data was written.

+  @retval EFI_UNSUPPORT        Writes to Open directory are not supported

+  @retval EFI_NO_MEDIA         The device has no media

+  @retval EFI_DEVICE_ERROR     The device reported an error

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_WRITE_PROTECTED  The device is write protected

+  @retval EFI_ACCESS_DENIED    The file was open for read only

+  @retval EFI_VOLUME_FULL      The volume is full

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_WRITE) (

+  IN EFI_FILE                 *This,

+  IN OUT UINTN                *BufferSize,

+  IN VOID                     *Buffer

+  )

+;

+

+/**

+  Set a files current position

+

+  @param  This            Protocol instance pointer.

+  @param  Position        Byte possition from the start of the file

+                          

+  @retval EFI_SUCCESS     Data was written.

+  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_SET_POSITION) (

+  IN EFI_FILE                 *This,

+  IN UINT64                   Position

+  )

+;

+

+/**

+  Get a files current position

+

+  @param  This            Protocol instance pointer.

+  @param  Position        Byte possition from the start of the file

+                          

+  @retval EFI_SUCCESS     Data was written.

+  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_GET_POSITION) (

+  IN EFI_FILE                 *This,

+  OUT UINT64                  *Position

+  )

+;

+

+/**

+  Get information about a file

+

+  @param  This            Protocol instance pointer.

+  @param  InformationType Type of info to return in Buffer

+  @param  BufferSize      On input size of buffer, on output amount of data in buffer.

+  @param  Buffer          The buffer to return data.

+

+  @retval EFI_SUCCESS          Data was returned.

+  @retval EFI_UNSUPPORT        InformationType is not supported

+  @retval EFI_NO_MEDIA         The device has no media

+  @retval EFI_DEVICE_ERROR     The device reported an error

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_WRITE_PROTECTED  The device is write protected

+  @retval EFI_ACCESS_DENIED    The file was open for read only

+  @retval EFI_BUFFER_TOO_SMALL Buffer was too small, required size returned in BufferSize

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_GET_INFO) (

+  IN EFI_FILE                 *This,

+  IN EFI_GUID                 *InformationType,

+  IN OUT UINTN                *BufferSize,

+  OUT VOID                    *Buffer

+  )

+;

+

+/**

+  Set information about a file

+

+  @param  File            Protocol instance pointer.

+  @param  InformationType Type of info in Buffer

+  @param  BufferSize      Size of buffer.

+  @param  Buffer          The data to write.

+

+  @retval EFI_SUCCESS          Data was returned.

+  @retval EFI_UNSUPPORT        InformationType is not supported

+  @retval EFI_NO_MEDIA         The device has no media

+  @retval EFI_DEVICE_ERROR     The device reported an error

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_WRITE_PROTECTED  The device is write protected

+  @retval EFI_ACCESS_DENIED    The file was open for read only

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_SET_INFO) (

+  IN EFI_FILE                 *This,

+  IN EFI_GUID                 *InformationType,

+  IN UINTN                    BufferSize,

+  IN VOID                     *Buffer

+  )

+;

+

+/**

+  Flush data back for the file handle

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS          Data was written.

+  @retval EFI_UNSUPPORT        Writes to Open directory are not supported

+  @retval EFI_NO_MEDIA         The device has no media

+  @retval EFI_DEVICE_ERROR     The device reported an error

+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted

+  @retval EFI_WRITE_PROTECTED  The device is write protected

+  @retval EFI_ACCESS_DENIED    The file was open for read only

+  @retval EFI_VOLUME_FULL      The volume is full

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FILE_FLUSH) (

+  IN EFI_FILE  *This

+  )

+;

+

+#define EFI_FILE_HANDLE_REVISION   0x00010000

+#define EFI_FILE_PROTOCOL_REVISION EFI_FILE_HANDLE_REVISION

+

+struct _EFI_FILE {

+  UINT64                Revision;

+  EFI_FILE_OPEN         Open;

+  EFI_FILE_CLOSE        Close;

+  EFI_FILE_DELETE       Delete;

+  EFI_FILE_READ         Read;

+  EFI_FILE_WRITE        Write;

+  EFI_FILE_GET_POSITION GetPosition;

+  EFI_FILE_SET_POSITION SetPosition;

+  EFI_FILE_GET_INFO     GetInfo;

+  EFI_FILE_SET_INFO     SetInfo;

+  EFI_FILE_FLUSH        Flush;

+};

+

+

+extern EFI_GUID gEfiSimpleFileSystemProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SimpleNetwork.h b/edk2/MdePkg/Include/Protocol/SimpleNetwork.h
new file mode 100644
index 0000000..0da64bb
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SimpleNetwork.h
@@ -0,0 +1,580 @@
+/** @file

+  Simple Network protocol as defined in the EFI 1.0 specification.

+

+  Basic network device abstraction.

+

+  Rx    - Received

+  Tx    - Transmit

+  MCast - MultiCast

+  ...

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SimpleNetwork.h

+

+**/

+

+#ifndef __SIMPLE_NETWORK_H__

+#define __SIMPLE_NETWORK_H__

+

+#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \

+  { \

+    0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } \

+  }

+

+typedef struct _EFI_SIMPLE_NETWORK_PROTOCOL  EFI_SIMPLE_NETWORK_PROTOCOL;

+

+//

+// Simple Network Protocol data structures

+//

+typedef struct {

+  //

+  // Total number of frames received.  Includes frames with errors and

+  // dropped frames.

+  //

+  UINT64  RxTotalFrames;

+

+  //

+  // Number of valid frames received and copied into receive buffers.

+  //

+  UINT64  RxGoodFrames;

+

+  //

+  // Number of frames below the minimum length for the media.

+  // This would be <64 for ethernet.

+  //

+  UINT64  RxUndersizeFrames;

+

+  //

+  // Number of frames longer than the maxminum length for the

+  // media.  This would be >1500 for ethernet.

+  //

+  UINT64  RxOversizeFrames;

+

+  //

+  // Valid frames that were dropped because receive buffers were full.

+  //

+  UINT64  RxDroppedFrames;

+

+  //

+  // Number of valid unicast frames received and not dropped.

+  //

+  UINT64  RxUnicastFrames;

+

+  //

+  // Number of valid broadcast frames received and not dropped.

+  //

+  UINT64  RxBroadcastFrames;

+

+  //

+  // Number of valid mutlicast frames received and not dropped.

+  //

+  UINT64  RxMulticastFrames;

+

+  //

+  // Number of frames w/ CRC or alignment errors.

+  //

+  UINT64  RxCrcErrorFrames;

+

+  //

+  // Total number of bytes received.  Includes frames with errors

+  // and dropped frames.

+  //

+  UINT64  RxTotalBytes;

+

+  //

+  // Transmit statistics.

+  //

+  UINT64  TxTotalFrames;

+  UINT64  TxGoodFrames;

+  UINT64  TxUndersizeFrames;

+  UINT64  TxOversizeFrames;

+  UINT64  TxDroppedFrames;

+  UINT64  TxUnicastFrames;

+  UINT64  TxBroadcastFrames;

+  UINT64  TxMulticastFrames;

+  UINT64  TxCrcErrorFrames;

+  UINT64  TxTotalBytes;

+

+  //

+  // Number of collisions detection on this subnet.

+  //

+  UINT64  Collisions;

+

+  //

+  // Number of frames destined for unsupported protocol.

+  //

+  UINT64  UnsupportedProtocol;

+

+} EFI_NETWORK_STATISTICS;

+

+typedef enum {

+  EfiSimpleNetworkStopped,

+  EfiSimpleNetworkStarted,

+  EfiSimpleNetworkInitialized,

+  EfiSimpleNetworkMaxState

+} EFI_SIMPLE_NETWORK_STATE;

+

+#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST                0x01

+#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST              0x02

+#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST              0x04

+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS            0x08

+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST  0x10

+

+#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT              0x01

+#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT             0x02

+#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT              0x04

+#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT             0x08

+

+#define MAX_MCAST_FILTER_CNT                              16

+typedef struct {

+  UINT32          State;

+  UINT32          HwAddressSize;

+  UINT32          MediaHeaderSize;

+  UINT32          MaxPacketSize;

+  UINT32          NvRamSize;

+  UINT32          NvRamAccessSize;

+  UINT32          ReceiveFilterMask;

+  UINT32          ReceiveFilterSetting;

+  UINT32          MaxMCastFilterCount;

+  UINT32          MCastFilterCount;

+  EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT];

+  EFI_MAC_ADDRESS CurrentAddress;

+  EFI_MAC_ADDRESS BroadcastAddress;

+  EFI_MAC_ADDRESS PermanentAddress;

+  UINT8           IfType;

+  BOOLEAN         MacAddressChangeable;

+  BOOLEAN         MultipleTxSupported;

+  BOOLEAN         MediaPresentSupported;

+  BOOLEAN         MediaPresent;

+} EFI_SIMPLE_NETWORK_MODE;

+

+//

+// Protocol Member Functions

+//

+/**

+  Changes the state of a network interface from "stopped" to "started".

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS           The network interface was started.

+  @retval EFI_ALREADY_STARTED   The network interface is already in the started state.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_START) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This

+  )

+;

+

+/**

+  Changes the state of a network interface from "started" to "stopped".

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS           The network interface was stopped.

+  @retval EFI_ALREADY_STARTED   The network interface is already in the stopped state.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_STOP) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This

+  )

+;

+

+/**

+  Resets a network adapter and allocates the transmit and receive buffers 

+  required by the network interface; optionally, also requests allocation 

+  of additional transmit and receive buffers.

+

+  @param  This              Protocol instance pointer.

+  @param  ExtraRxBufferSize The size, in bytes, of the extra receive buffer space

+                            that the driver should allocate for the network interface.

+                            Some network interfaces will not be able to use the extra

+                            buffer, and the caller will not know if it is actually

+                            being used.

+  @param  ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space

+                            that the driver should allocate for the network interface.

+                            Some network interfaces will not be able to use the extra

+                            buffer, and the caller will not know if it is actually

+                            being used.

+

+  @retval EFI_SUCCESS           The network interface was initialized.

+  @retval EFI_NOT_STARTED       The network interface has not been started

+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and

+                                receive buffers.   .

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL                    *This,

+  IN UINTN                                          ExtraRxBufferSize  OPTIONAL,

+  IN UINTN                                          ExtraTxBufferSize  OPTIONAL

+  )

+;

+

+/**

+  Resets a network adapter and re-initializes it with the parameters that were 

+  provided in the previous call to Initialize().  

+

+  @param  This                 Protocol instance pointer.

+  @param  ExtendedVerification Indicates that the driver may perform a more

+                               exhaustive verification operation of the device

+                               during reset.

+

+  @retval EFI_SUCCESS           The network interface was reset.

+  @retval EFI_NOT_STARTED       The network interface has not been started

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_RESET) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL   *This,

+  IN BOOLEAN                       ExtendedVerification

+  )

+;

+

+/**

+  Resets a network adapter and leaves it in a state that is safe for 

+  another driver to initialize.

+

+  @param  This Protocol instance pointer.

+

+  @retval EFI_SUCCESS           The network interface was shutdown.

+  @retval EFI_NOT_STARTED       The network interface has not been started

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This

+  )

+;

+

+/**

+  Manages the multicast receive filters of a network interface.

+

+  @param  This             Protocol instance pointer.

+  @param  Enable           A bit mask of receive filters to enable on the network interface.

+  @param  Disable          A bit mask of receive filters to disable on the network interface.

+  @param  ResetMCastFilter Set to TRUE to reset the contents of the multicast receive

+                           filters on the network interface to their default values.

+  @param  McastFilterCnt   Number of multicast HW MAC addresses in the new

+                           MCastFilter list. This value must be less than or equal to

+                           the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This

+                           field is optional if ResetMCastFilter is TRUE.

+  @param  MCastFilter      A pointer to a list of new multicast receive filter HW MAC

+                           addresses. This list will replace any existing multicast

+                           HW MAC address list. This field is optional if

+                           ResetMCastFilter is TRUE.

+

+  @retval EFI_SUCCESS           The multicast receive filter list was updated.

+  @retval EFI_NOT_STARTED       The network interface has not been started

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL                             *This,

+  IN UINT32                                                  Enable,

+  IN UINT32                                                  Disable,

+  IN BOOLEAN                                                 ResetMCastFilter,

+  IN UINTN                                                   MCastFilterCnt     OPTIONAL,

+  IN EFI_MAC_ADDRESS                                         *MCastFilter OPTIONAL

+  )

+;

+

+/**

+  Modifies or resets the current station address, if supported.

+

+  @param  This  Protocol instance pointer.

+  @param  Reset Flag used to reset the station address to the network interfaces

+                permanent address.

+  @param  New   New station address to be used for the network interface.

+

+  @retval EFI_SUCCESS           The network interfaces station address was updated.

+  @retval EFI_NOT_STARTED       The network interface has not been started

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL            *This,

+  IN BOOLEAN                                Reset,

+  IN EFI_MAC_ADDRESS                        *New OPTIONAL

+  )

+;

+

+/**

+  Resets or collects the statistics on a network interface.

+

+  @param  This            Protocol instance pointer.

+  @param  Reset           Set to TRUE to reset the statistics for the network interface.

+  @param  StatisticsSize  On input the size, in bytes, of StatisticsTable. On

+                          output the size, in bytes, of the resulting table of

+                          statistics.

+  @param  StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that

+                          contains the statistics.

+

+  @retval EFI_SUCCESS           The statistics were collected from the network interface.

+  @retval EFI_NOT_STARTED       The network interface has not been started.

+  @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer

+                                size needed to hold the statistics is returned in

+                                StatisticsSize.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,

+  IN BOOLEAN                              Reset,

+  IN OUT UINTN                            *StatisticsSize   OPTIONAL,

+  OUT EFI_NETWORK_STATISTICS              *StatisticsTable  OPTIONAL

+  )

+;

+

+/**

+  Converts a multicast IP address to a multicast HW MAC address.

+

+  @param  This Protocol instance pointer.

+  @param  IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set

+               to FALSE if the multicast IP address is IPv4 [RFC 791].

+  @param  IP   The multicast IP address that is to be converted to a multicast

+               HW MAC address.

+  @param  MAC  The multicast HW MAC address that is to be generated from IP.

+

+  @retval EFI_SUCCESS           The multicast IP address was mapped to the multicast

+                                HW MAC address.

+  @retval EFI_NOT_STARTED       The network interface has not been started.

+  @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer

+                                size needed to hold the statistics is returned in

+                                StatisticsSize.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,

+  IN BOOLEAN                              IPv6,

+  IN EFI_IP_ADDRESS                       *IP,

+  OUT EFI_MAC_ADDRESS                     *MAC

+  )

+;

+

+/**

+  Performs read and write operations on the NVRAM device attached to a 

+  network interface.

+

+  @param  This       Protocol instance pointer.

+  @param  ReadWrite  TRUE for read operations, FALSE for write operations.

+  @param  Offset     Byte offset in the NVRAM device at which to start the read or

+                     write operation. This must be a multiple of NvRamAccessSize and

+                     less than NvRamSize.

+  @param  BufferSize The number of bytes to read or write from the NVRAM device.

+                     This must also be a multiple of NvramAccessSize.

+  @param  Buffer     A pointer to the data buffer.

+

+  @retval EFI_SUCCESS           The NVRAM access was performed.

+  @retval EFI_NOT_STARTED       The network interface has not been started.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,

+  IN BOOLEAN                              ReadWrite,

+  IN UINTN                                Offset,

+  IN UINTN                                BufferSize,

+  IN OUT VOID                             *Buffer

+  )

+;

+

+/**

+  Reads the current interrupt status and recycled transmit buffer status from 

+  a network interface.

+

+  @param  This            Protocol instance pointer.

+  @param  InterruptStatus A pointer to the bit mask of the currently active interrupts

+                          If this is NULL, the interrupt status will not be read from

+                          the device. If this is not NULL, the interrupt status will

+                          be read from the device. When the  interrupt status is read,

+                          it will also be cleared. Clearing the transmit  interrupt

+                          does not empty the recycled transmit buffer array.

+  @param  TxBuf           Recycled transmit buffer address. The network interface will

+                          not transmit if its internal recycled transmit buffer array

+                          is full. Reading the transmit buffer does not clear the

+                          transmit interrupt. If this is NULL, then the transmit buffer

+                          status will not be read. If there are no transmit buffers to

+                          recycle and TxBuf is not NULL, * TxBuf will be set to NULL.

+

+  @retval EFI_SUCCESS           The status of the network interface was retrieved.

+  @retval EFI_NOT_STARTED       The network interface has not been started.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,

+  OUT UINT32                              *InterruptStatus OPTIONAL,

+  OUT VOID                                **TxBuf OPTIONAL

+  )

+;

+

+/**

+  Places a packet in the transmit queue of a network interface.

+

+  @param  This       Protocol instance pointer.

+  @param  HeaderSize The size, in bytes, of the media header to be filled in by

+                     the Transmit() function. If HeaderSize is non-zero, then it

+                     must be equal to This->Mode->MediaHeaderSize and the DestAddr

+                     and Protocol parameters must not be NULL.

+  @param  BufferSize The size, in bytes, of the entire packet (media header and

+                     data) to be transmitted through the network interface.

+  @param  Buffer     A pointer to the packet (media header followed by data) to be

+                     transmitted. This parameter cannot be NULL. If HeaderSize is zero,

+                     then the media header in Buffer must already be filled in by the

+                     caller. If HeaderSize is non-zero, then the media header will be

+                     filled in by the Transmit() function.

+  @param  SrcAddr    The source HW MAC address. If HeaderSize is zero, then this parameter

+                     is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then

+                     This->Mode->CurrentAddress is used for the source HW MAC address.

+  @param  DsetAddr   The destination HW MAC address. If HeaderSize is zero, then this

+                     parameter is ignored.

+  @param  Protocol   The type of header to build. If HeaderSize is zero, then this

+                     parameter is ignored. See RFC 1700, section "Ether Types", for

+                     examples.

+

+  @retval EFI_SUCCESS           The packet was placed on the transmit queue.

+  @retval EFI_NOT_STARTED       The network interface has not been started.

+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.                      

+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.

+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,

+  IN UINTN                                HeaderSize,

+  IN UINTN                                BufferSize,

+  IN VOID                                 *Buffer,

+  IN EFI_MAC_ADDRESS                      *SrcAddr  OPTIONAL,

+  IN EFI_MAC_ADDRESS                      *DestAddr OPTIONAL,

+  IN UINT16                               *Protocol OPTIONAL

+  )

+;

+

+/**

+  Receives a packet from a network interface.

+

+  @param  This       Protocol instance pointer.

+  @param  HeaderSize The size, in bytes, of the media header received on the network

+                     interface. If this parameter is NULL, then the media header size

+                     will not be returned.

+  @param  BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in

+                     bytes, of the packet that was received on the network interface.

+  @param  Buffer     A pointer to the data buffer to receive both the media header and

+                     the data.

+  @param  SrcAddr    The source HW MAC address. If this parameter is NULL, the

+                     HW MAC source address will not be extracted from the media

+                     header.

+  @param  DsetAddr   The destination HW MAC address. If this parameter is NULL,

+                     the HW MAC destination address will not be extracted from the

+                     media header.

+  @param  Protocol   The media header type. If this parameter is NULL, then the

+                     protocol will not be extracted from the media header. See

+                     RFC 1700 section "Ether Types" for examples.

+

+  @retval  EFI_SUCCESS           The received data was stored in Buffer, and BufferSize has

+                                 been updated to the number of bytes received.

+  @retval  EFI_NOT_STARTED       The network interface has not been started.

+  @retval  EFI_NOT_READY         The network interface is too busy to accept this transmit

+                                 request.

+  @retval  EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.

+  @retval  EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.

+  @retval  EFI_DEVICE_ERROR      The command could not be sent to the network interface.

+  @retval  EFI_UNSUPPORTED       This function is not supported by the network interface.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE) (

+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,

+  OUT UINTN                               *HeaderSize OPTIONAL,

+  IN OUT UINTN                            *BufferSize,

+  OUT VOID                                *Buffer,

+  OUT EFI_MAC_ADDRESS                     *SrcAddr    OPTIONAL,

+  OUT EFI_MAC_ADDRESS                     *DestAddr   OPTIONAL,

+  OUT UINT16                              *Protocol   OPTIONAL

+  )

+;

+

+#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION  0x00010000

+

+struct _EFI_SIMPLE_NETWORK_PROTOCOL {

+  UINT64                              Revision;

+  EFI_SIMPLE_NETWORK_START            Start;

+  EFI_SIMPLE_NETWORK_STOP             Stop;

+  EFI_SIMPLE_NETWORK_INITIALIZE       Initialize;

+  EFI_SIMPLE_NETWORK_RESET            Reset;

+  EFI_SIMPLE_NETWORK_SHUTDOWN         Shutdown;

+  EFI_SIMPLE_NETWORK_RECEIVE_FILTERS  ReceiveFilters;

+  EFI_SIMPLE_NETWORK_STATION_ADDRESS  StationAddress;

+  EFI_SIMPLE_NETWORK_STATISTICS       Statistics;

+  EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC  MCastIpToMac;

+  EFI_SIMPLE_NETWORK_NVDATA           NvData;

+  EFI_SIMPLE_NETWORK_GET_STATUS       GetStatus;

+  EFI_SIMPLE_NETWORK_TRANSMIT         Transmit;

+  EFI_SIMPLE_NETWORK_RECEIVE          Receive;

+  EFI_EVENT                           WaitForPacket;

+  EFI_SIMPLE_NETWORK_MODE             *Mode;

+};

+

+extern EFI_GUID gEfiSimpleNetworkProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SimplePointer.h b/edk2/MdePkg/Include/Protocol/SimplePointer.h
new file mode 100644
index 0000000..a0e0804
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SimplePointer.h
@@ -0,0 +1,97 @@
+/** @file

+  Simple Pointer protocol from the EFI 1.1 specification.

+

+  Abstraction of a very simple pointer device like a mice or tracekballs.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SimplePointer.h

+

+**/

+

+#ifndef __SIMPLE_POINTER_H__

+#define __SIMPLE_POINTER_H__

+

+#define EFI_SIMPLE_POINTER_PROTOCOL_GUID \

+  { \

+    0x31878c87, 0xb75, 0x11d5, {0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_SIMPLE_POINTER_PROTOCOL  EFI_SIMPLE_POINTER_PROTOCOL;

+

+//

+// Data structures

+//

+typedef struct {

+  INT32   RelativeMovementX;

+  INT32   RelativeMovementY;

+  INT32   RelativeMovementZ;

+  BOOLEAN LeftButton;

+  BOOLEAN RightButton;

+} EFI_SIMPLE_POINTER_STATE;

+

+typedef struct {

+  UINT64  ResolutionX;

+  UINT64  ResolutionY;

+  UINT64  ResolutionZ;

+  BOOLEAN LeftButton;

+  BOOLEAN RightButton;

+} EFI_SIMPLE_POINTER_MODE;

+

+/**                                                                 

+  Resets the pointer device hardware.

+    

+  @param  This                  A pointer to the EFI_SIMPLE_POINTER_PROTOCOL

+                                instance.                                   

+  @param  ExtendedVerification  Indicates that the driver may perform a more exhaustive

+                                verification operation of the device during reset.                                       

+                                

+  @retval EFI_SUCCESS           The device was reset.

+  @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could not be reset.  

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_POINTER_RESET) (

+  IN EFI_SIMPLE_POINTER_PROTOCOL            *This,

+  IN BOOLEAN                                ExtendedVerification

+  );

+

+/**                                                                 

+  Retrieves the current state of a pointer device.

+    

+  @param  This                  A pointer to the EFI_SIMPLE_POINTER_PROTOCOL

+                                instance.                                   

+  @param  State                 A pointer to the state information on the pointer device.

+                                

+  @retval EFI_SUCCESS           The state of the pointer device was returned in State.

+  @retval EFI_NOT_READY         The state of the pointer device has not changed since the last call to

+                                GetState().                                                           

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to retrieve the pointer device's

+                                current state.                                                           

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIMPLE_POINTER_GET_STATE) (

+  IN EFI_SIMPLE_POINTER_PROTOCOL          *This,

+  IN OUT EFI_SIMPLE_POINTER_STATE         *State

+  );

+

+struct _EFI_SIMPLE_POINTER_PROTOCOL {

+  EFI_SIMPLE_POINTER_RESET      Reset;

+  EFI_SIMPLE_POINTER_GET_STATE  GetState;

+  EFI_EVENT                     WaitForInput;

+  EFI_SIMPLE_POINTER_MODE       *Mode;

+};

+

+extern EFI_GUID gEfiSimplePointerProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SimpleTextIn.h b/edk2/MdePkg/Include/Protocol/SimpleTextIn.h
new file mode 100644
index 0000000..053ed58
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SimpleTextIn.h
@@ -0,0 +1,126 @@
+/** @file

+  Simple Text In protocol from the EFI 1.0 specification.

+

+  Abstraction of a very simple input device like a keyboard or serial

+  terminal.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SimpleTextIn.h

+

+**/

+

+#ifndef __SIMPLE_TEXT_IN_PROTOCOL_H__

+#define __SIMPLE_TEXT_IN_PROTOCOL_H__

+

+#define EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID \

+  { \

+    0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+#define EFI_SIMPLE_INPUT_PROTOCOL_GUID      EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID

+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID

+

+typedef struct _EFI_SIMPLE_TEXT_IN_PROTOCOL EFI_SIMPLE_TEXT_IN_PROTOCOL;

+typedef struct _EFI_SIMPLE_TEXT_IN_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL;

+

+//

+// Data structures

+//

+typedef struct {

+  UINT16  ScanCode;

+  CHAR16  UnicodeChar;

+} EFI_INPUT_KEY;

+

+//

+// Required unicode control chars

+//

+#define CHAR_NULL             0x0000

+#define CHAR_BACKSPACE        0x0008

+#define CHAR_TAB              0x0009

+#define CHAR_LINEFEED         0x000A

+#define CHAR_CARRIAGE_RETURN  0x000D

+

+//

+// EFI Scan codes

+//

+#define SCAN_NULL       0x0000

+#define SCAN_UP         0x0001

+#define SCAN_DOWN       0x0002

+#define SCAN_RIGHT      0x0003

+#define SCAN_LEFT       0x0004

+#define SCAN_HOME       0x0005

+#define SCAN_END        0x0006

+#define SCAN_INSERT     0x0007

+#define SCAN_DELETE     0x0008

+#define SCAN_PAGE_UP    0x0009

+#define SCAN_PAGE_DOWN  0x000A

+#define SCAN_F1         0x000B

+#define SCAN_F2         0x000C

+#define SCAN_F3         0x000D

+#define SCAN_F4         0x000E

+#define SCAN_F5         0x000F

+#define SCAN_F6         0x0010

+#define SCAN_F7         0x0011

+#define SCAN_F8         0x0012

+#define SCAN_F9         0x0013

+#define SCAN_F10        0x0014

+#define SCAN_F11        0x0015

+#define SCAN_F12        0x0016

+#define SCAN_ESC        0x0017

+

+/**

+  Reset the input device and optionaly run diagnostics

+

+  @param  This                 Protocol instance pointer.

+  @param  ExtendedVerification Driver may perform diagnostics on reset.

+

+  @retval EFI_SUCCESS          The device was reset.

+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could not be reset.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INPUT_RESET) (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  IN BOOLEAN                              ExtendedVerification

+  )

+;

+

+/**

+  Reads the next keystroke from the input device. The WaitForKey Event can 

+  be used to test for existance of a keystroke via WaitForEvent () call.

+

+  @param  This Protocol instance pointer.

+  @param  Key  Driver may perform diagnostics on reset.

+

+  @retval EFI_SUCCESS      The keystroke information was returned.

+  @retval EFI_NOT_READY    There was no keystroke data availiable.

+  @retval EFI_DEVICE_ERROR The keydtroke information was not returned due to

+                           hardware errors.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INPUT_READ_KEY) (

+  IN EFI_SIMPLE_TEXT_IN_PROTOCOL          *This,

+  OUT EFI_INPUT_KEY                       *Key

+  )

+;

+

+struct _EFI_SIMPLE_TEXT_IN_PROTOCOL {

+  EFI_INPUT_RESET     Reset;

+  EFI_INPUT_READ_KEY  ReadKeyStroke;

+  EFI_EVENT           WaitForKey;

+} EFI_SIMPLE_INPUT_PROTOCOL;

+

+extern EFI_GUID gEfiSimpleTextInProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SimpleTextOut.h b/edk2/MdePkg/Include/Protocol/SimpleTextOut.h
new file mode 100644
index 0000000..b568865
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SimpleTextOut.h
@@ -0,0 +1,390 @@
+/** @file

+  Simple Text Out protocol from the EFI 1.0 specification.

+

+  Abstraction of a very simple text based output device like VGA text mode or

+  a serial terminal. The Simple Text Out protocol instance can represent

+  a single hardware device or a virtual device that is an agregation

+  of multiple physical devices.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SimpleTextOut.h

+

+**/

+

+#ifndef __SIMPLE_TEXT_OUT_H__

+#define __SIMPLE_TEXT_OUT_H__

+

+#define EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID \

+  { \

+    0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \

+  }

+

+#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID  EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID

+

+typedef struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL EFI_SIMPLE_TEXT_OUT_PROTOCOL;

+typedef struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;

+

+//

+// Define's for required EFI Unicode Box Draw characters

+//

+#define BOXDRAW_HORIZONTAL                  0x2500

+#define BOXDRAW_VERTICAL                    0x2502

+#define BOXDRAW_DOWN_RIGHT                  0x250c

+#define BOXDRAW_DOWN_LEFT                   0x2510

+#define BOXDRAW_UP_RIGHT                    0x2514

+#define BOXDRAW_UP_LEFT                     0x2518

+#define BOXDRAW_VERTICAL_RIGHT              0x251c

+#define BOXDRAW_VERTICAL_LEFT               0x2524

+#define BOXDRAW_DOWN_HORIZONTAL             0x252c

+#define BOXDRAW_UP_HORIZONTAL               0x2534

+#define BOXDRAW_VERTICAL_HORIZONTAL         0x253c

+#define BOXDRAW_DOUBLE_HORIZONTAL           0x2550

+#define BOXDRAW_DOUBLE_VERTICAL             0x2551

+#define BOXDRAW_DOWN_RIGHT_DOUBLE           0x2552

+#define BOXDRAW_DOWN_DOUBLE_RIGHT           0x2553

+#define BOXDRAW_DOUBLE_DOWN_RIGHT           0x2554

+#define BOXDRAW_DOWN_LEFT_DOUBLE            0x2555

+#define BOXDRAW_DOWN_DOUBLE_LEFT            0x2556

+#define BOXDRAW_DOUBLE_DOWN_LEFT            0x2557

+#define BOXDRAW_UP_RIGHT_DOUBLE             0x2558

+#define BOXDRAW_UP_DOUBLE_RIGHT             0x2559

+#define BOXDRAW_DOUBLE_UP_RIGHT             0x255a

+#define BOXDRAW_UP_LEFT_DOUBLE              0x255b

+#define BOXDRAW_UP_DOUBLE_LEFT              0x255c

+#define BOXDRAW_DOUBLE_UP_LEFT              0x255d

+#define BOXDRAW_VERTICAL_RIGHT_DOUBLE       0x255e

+#define BOXDRAW_VERTICAL_DOUBLE_RIGHT       0x255f

+#define BOXDRAW_DOUBLE_VERTICAL_RIGHT       0x2560

+#define BOXDRAW_VERTICAL_LEFT_DOUBLE        0x2561

+#define BOXDRAW_VERTICAL_DOUBLE_LEFT        0x2562

+#define BOXDRAW_DOUBLE_VERTICAL_LEFT        0x2563

+#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE      0x2564

+#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL      0x2565

+#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL      0x2566

+#define BOXDRAW_UP_HORIZONTAL_DOUBLE        0x2567

+#define BOXDRAW_UP_DOUBLE_HORIZONTAL        0x2568

+#define BOXDRAW_DOUBLE_UP_HORIZONTAL        0x2569

+#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE  0x256a

+#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL  0x256b

+#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL  0x256c

+

+//

+// EFI Required Block Elements Code Chart

+//

+#define BLOCKELEMENT_FULL_BLOCK   0x2588

+#define BLOCKELEMENT_LIGHT_SHADE  0x2591

+

+//

+// EFI Required Geometric Shapes Code Chart

+//

+#define GEOMETRICSHAPE_UP_TRIANGLE    0x25b2

+#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba

+#define GEOMETRICSHAPE_DOWN_TRIANGLE  0x25bc

+#define GEOMETRICSHAPE_LEFT_TRIANGLE  0x25c4

+

+//

+// EFI Required Arrow shapes

+//

+#define ARROW_LEFT  0x2190

+#define ARROW_UP    0x2191

+#define ARROW_RIGHT 0x2192

+#define ARROW_DOWN  0x2193

+

+//

+// EFI Console Colours

+//

+#define EFI_BLACK                 0x00

+#define EFI_BLUE                  0x01

+#define EFI_GREEN                 0x02

+#define EFI_CYAN                  (EFI_BLUE | EFI_GREEN)

+#define EFI_RED                   0x04

+#define EFI_MAGENTA               (EFI_BLUE | EFI_RED)

+#define EFI_BROWN                 (EFI_GREEN | EFI_RED)

+#define EFI_LIGHTGRAY             (EFI_BLUE | EFI_GREEN | EFI_RED)

+#define EFI_BRIGHT                0x08

+#define EFI_DARKGRAY              (EFI_BRIGHT)

+#define EFI_LIGHTBLUE             (EFI_BLUE | EFI_BRIGHT)

+#define EFI_LIGHTGREEN            (EFI_GREEN | EFI_BRIGHT)

+#define EFI_LIGHTCYAN             (EFI_CYAN | EFI_BRIGHT)

+#define EFI_LIGHTRED              (EFI_RED | EFI_BRIGHT)

+#define EFI_LIGHTMAGENTA          (EFI_MAGENTA | EFI_BRIGHT)

+#define EFI_YELLOW                (EFI_BROWN | EFI_BRIGHT)

+#define EFI_WHITE                 (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)

+

+#define EFI_TEXT_ATTR(f, b)       ((f) | ((b) << 4))

+

+#define EFI_BACKGROUND_BLACK      0x00

+#define EFI_BACKGROUND_BLUE       0x10

+#define EFI_BACKGROUND_GREEN      0x20

+#define EFI_BACKGROUND_CYAN       (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN)

+#define EFI_BACKGROUND_RED        0x40

+#define EFI_BACKGROUND_MAGENTA    (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED)

+#define EFI_BACKGROUND_BROWN      (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)

+#define EFI_BACKGROUND_LIGHTGRAY  (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)

+

+//

+// We currently define attributes from 0 - 7F for color manipulations

+// To internally handle the local display characteristics for a particular character, we are defining

+// Bit 7 to signify the local glyph representation for a character.  If turned on, glyphs will be

+// pulled from the wide glyph database and will display locally as a wide character (16 X 19 versus 8 X 19)

+// If bit 7 is off, the narrow glyph database will be used.  This does NOT affect information that is sent to

+// non-local displays (e.g. serial or LAN consoles).

+//

+#define EFI_WIDE_ATTRIBUTE  0x80

+

+/**

+  Reset the text output device hardware and optionaly run diagnostics

+

+  @param  This                 Protocol instance pointer.

+  @param  ExtendedVerification Driver may perform more exhaustive verfication

+                               operation of the device during reset.

+

+  @retval EFI_SUCCESS          The text output device was reset.

+  @retval EFI_DEVICE_ERROR     The text output device is not functioning correctly and

+                               could not be reset.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_RESET) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN BOOLEAN                                ExtendedVerification

+  )

+;

+

+/**

+  Write a Unicode string to the output device.

+

+  @param  This   Protocol instance pointer.

+  @param  String The NULL-terminated Unicode string to be displayed on the output

+                 device(s). All output devices must also support the Unicode

+                 drawing defined in this file.

+

+  @retval EFI_SUCCESS             The string was output to the device.

+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output

+                                  the text.

+  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a

+                                  defined text mode.

+  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the

+                                  characters in the Unicode string could not be

+                                  rendered and were skipped.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_STRING) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN CHAR16                                 *String

+  )

+;

+

+/**

+  Verifies that all characters in a Unicode string can be output to the 

+  target device.

+

+  @param  This   Protocol instance pointer.

+  @param  String The NULL-terminated Unicode string to be examined for the output

+                 device(s).

+

+  @retval EFI_SUCCESS      The device(s) are capable of rendering the output string.

+  @retval EFI_UNSUPPORTED  Some of the characters in the Unicode string cannot be

+                           rendered by one or more of the output devices mapped

+                           by the EFI handle.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_TEST_STRING) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN CHAR16                                 *String

+  )

+;

+

+/**

+  Returns information for an available text mode that the output device(s)

+  supports.

+

+  @param  This       Protocol instance pointer.

+  @param  ModeNumber The mode number to return information on.

+  @param  Columns    Returns the geometry of the text output device for the

+                     requested ModeNumber.

+  @param  Rows       Returns the geometry of the text output device for the

+                     requested ModeNumber.

+                                          

+  @retval EFI_SUCCESS      The requested mode information was returned.

+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.

+  @retval EFI_UNSUPPORTED  The mode number was not valid.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_QUERY_MODE) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  ModeNumber,

+  OUT UINTN                                 *Columns,

+  OUT UINTN                                 *Rows

+  )

+;

+

+/**

+  Sets the output device(s) to a specified mode.

+

+  @param  This       Protocol instance pointer.

+  @param  ModeNumber The mode number to set.

+

+  @retval EFI_SUCCESS      The requested text mode was set.

+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.

+  @retval EFI_UNSUPPORTED  The mode number was not valid.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_SET_MODE) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  ModeNumber

+  )

+;

+

+/**

+  Sets the background and foreground colors for the OutputString () and

+  ClearScreen () functions.

+

+  @param  This      Protocol instance pointer.

+  @param  Attribute The attribute to set. Bits 0..3 are the foreground color, and

+                    bits 4..6 are the background color. All other bits are undefined

+                    and must be zero. The valid Attributes are defined in this file.

+

+  @retval EFI_SUCCESS     The attribute was set.

+  @retval EFI_DEVICE_     ERROR The device had an error and could not complete the request.

+  @retval EFI_UNSUPPORTED The attribute requested is not defined.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  Attribute

+  )

+;

+

+/**

+  Clears the output device(s) display to the currently selected background 

+  color.

+

+  @param  This              Protocol instance pointer.

+                           

+  @retval  EFI_SUCCESS      The operation completed successfully.

+  @retval  EFI_DEVICE_ERROR The device had an error and could not complete the request.

+  @retval  EFI_UNSUPPORTED  The output device is not in a valid text mode.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_CLEAR_SCREEN) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL   *This

+  )

+;

+

+/**

+  Sets the current coordinates of the cursor position

+

+  @param  This        Protocol instance pointer.

+  @param  Column      The position to set the cursor to. Must be greater than or

+                      equal to zero and less than the number of columns and rows

+                      by QueryMode ().

+  @param  Row         The position to set the cursor to. Must be greater than or

+                      equal to zero and less than the number of columns and rows

+                      by QueryMode ().

+

+  @retval EFI_SUCCESS      The operation completed successfully.

+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.

+  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode, or the

+                           cursor position is invalid for the current mode.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN UINTN                                  Column,

+  IN UINTN                                  Row

+  )

+;

+

+/**

+  Makes the cursor visible or invisible

+

+  @param  This    Protocol instance pointer.

+  @param  Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is

+                  set to be invisible.

+

+  @retval EFI_SUCCESS      The operation completed successfully.

+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the

+                           request, or the device does not support changing

+                           the cursor mode.

+  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TEXT_ENABLE_CURSOR) (

+  IN EFI_SIMPLE_TEXT_OUT_PROTOCOL           *This,

+  IN BOOLEAN                                Visible

+  )

+;

+

+/**

+  Mode Structure pointed to by Simple Text Out protocol.

+

+  MaxMode   - The number of modes supported by QueryMode () and SetMode ().

+  Mode      - The text mode of the output device(s).

+  Attribute - The current character output attribute

+  CursorColumn  - The cursor's column.

+  CursorRow     - The cursor's row.

+  CursorVisible - The cursor is currently visbile or not.

+

+**/

+typedef struct {

+  INT32   MaxMode;

+

+  //

+  // current settings

+  //

+  INT32   Mode;

+  INT32   Attribute;

+  INT32   CursorColumn;

+  INT32   CursorRow;

+  BOOLEAN CursorVisible;

+} EFI_SIMPLE_TEXT_OUTPUT_MODE;

+

+struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL {

+  EFI_TEXT_RESET                Reset;

+

+  EFI_TEXT_STRING               OutputString;

+  EFI_TEXT_TEST_STRING          TestString;

+

+  EFI_TEXT_QUERY_MODE           QueryMode;

+  EFI_TEXT_SET_MODE             SetMode;

+  EFI_TEXT_SET_ATTRIBUTE        SetAttribute;

+

+  EFI_TEXT_CLEAR_SCREEN         ClearScreen;

+  EFI_TEXT_SET_CURSOR_POSITION  SetCursorPosition;

+  EFI_TEXT_ENABLE_CURSOR        EnableCursor;

+

+  //

+  // Current mode

+  //

+  EFI_SIMPLE_TEXT_OUTPUT_MODE   *Mode;

+};

+

+extern EFI_GUID gEfiSimpleTextOutProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Smbus.h b/edk2/MdePkg/Include/Protocol/Smbus.h
new file mode 100644
index 0000000..8fe37b1
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Smbus.h
@@ -0,0 +1,237 @@
+/** @file

+  This file declares the EFI SMBus Host Controller protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Smbus.h

+

+  @par Revision Reference:

+  This protocol is defined in Framework of EFI SMBus Host Controller Specification

+  Version 0.9

+

+**/

+

+#ifndef _EFI_SMBUS_H

+#define _EFI_SMBUS_H

+

+#define EFI_SMBUS_HC_PROTOCOL_GUID \

+  { \

+    0xe49d33ed, 0x513d, 0x4634, {0xb6, 0x98, 0x6f, 0x55, 0xaa, 0x75, 0x1c, 0x1b } \

+  }

+

+typedef struct _EFI_SMBUS_HC_PROTOCOL EFI_SMBUS_HC_PROTOCOL;

+

+/**

+  Executes an SMBus operation to an SMBus controller.

+

+  @param  This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.

+  

+  @param  SlaveAddress The SMBus slave address of the device with which to communicate.

+  

+  @param  Command This command is transmitted by the SMBus host 

+  controller to the SMBus slave device and the interpretation is 

+  SMBus slave device specific.

+  

+  @param  Operation Signifies which particular SMBus hardware protocol 

+  instance that it will use to execute the SMBus transactions. 

+  

+  @param  PecCheck Defines if Packet Error Code (PEC) checking is required 

+  for this operation.

+  

+  @param  Length Signifies the number of bytes that this operation will do.

+  

+  @param  Buffer Contains the value of data to execute to the SMBus slave device.

+

+  @retval EFI_SUCCESS The last data that was returned from the access 

+  matched the poll exit criteria.

+  

+  @retval EFI_CRC_ERROR The checksum is not correct (PEC is incorrect)

+  

+  @retval EFI_TIMEOUT Timeout expired before the operation was completed. 

+  Timeout is determined by the SMBus host controller device.

+  

+  @retval EFI_OUT_OF_RESOURCES The request could not be completed 

+  due to a lack of resources.

+  

+  @retval EFI_DEVICE_ERROR The request was not completed because 

+  a failure reflected in the Host Status Register bit.

+  

+  @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.

+  Or Length/Buffer is NULL for operations except for EfiSmbusQuickRead and 

+  EfiSmbusQuickWrite. Length is outside the range of valid values.

+  

+  @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.

+  

+  @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMBUS_HC_EXECUTE_OPERATION) (

+  IN EFI_SMBUS_HC_PROTOCOL              *This,

+  IN      EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress,

+  IN      EFI_SMBUS_DEVICE_COMMAND      Command,

+  IN      EFI_SMBUS_OPERATION           Operation,

+  IN      BOOLEAN                       PecCheck,

+  IN OUT  UINTN                         *Length,

+  IN OUT  VOID                          *Buffer

+  );

+

+typedef struct {

+  UINT32  VendorSpecificId;

+  UINT16  SubsystemDeviceId;

+  UINT16  SubsystemVendorId;

+  UINT16  Interface;

+  UINT16  DeviceId;

+  UINT16  VendorId;

+  UINT8   VendorRevision;

+  UINT8   DeviceCapabilities;

+} EFI_SMBUS_UDID;

+

+/**

+  CallBack function can be registered in EFI_SMBUS_HC_PROTOCOL_NOTIFY.

+

+  @param  SlaveAddress The SMBUS hardware address to which the SMBUS 

+  device is preassigned or allocated.

+  

+  @param  Data Data of the SMBus host notify command that 

+  the caller wants to be called.

+

+  @return Status Code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMBUS_NOTIFY_FUNCTION) (

+  IN      EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress,

+  IN      UINTN                         Data

+  );

+

+/**

+  Sets the SMBus slave device addresses for the device with a given unique ID 

+  or enumerates the entire bus.

+

+  @param  This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.

+  

+  @param  ArpAll A Boolean expression that indicates if the host drivers need 

+  to enumerate all the devices or enumerate only the device that is identified 

+  by SmbusUdid. If ArpAll is TRUE, SmbusUdid and SlaveAddress are optional. 

+  If ArpAll is FALSE, ArpDevice will enumerate SmbusUdid and the address 

+  will be at SlaveAddress.

+  

+  @param  SmbusUdid The Unique Device Identifier (UDID) that is associated 

+  with this device.

+  

+  @param  SlaveAddress The SMBus slave address that is associated with an SMBus UDID. 

+

+  @retval EFI_SUCCESS The SMBus slave device address was set.

+  

+  @retval EFI_INVALID_PARAMETER SlaveAddress is NULL.

+  

+  @retval EFI_OUT_OF_RESOURCES The request could not be completed 

+  due to a lack of resources.

+  

+  @retval EFI_TIMEOUT The SMBus slave device did not respond.

+  

+  @retval EFI_DEVICE_ERROR The request was not completed because the transaction failed.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMBUS_HC_PROTOCOL_ARP_DEVICE) (

+  IN EFI_SMBUS_HC_PROTOCOL              *This,

+  IN      BOOLEAN                       ArpAll,

+  IN      EFI_SMBUS_UDID                *SmbusUdid, OPTIONAL

+  IN OUT  EFI_SMBUS_DEVICE_ADDRESS      *SlaveAddress OPTIONAL

+  );

+

+typedef struct {

+  EFI_SMBUS_DEVICE_ADDRESS  SmbusDeviceAddress;

+  EFI_SMBUS_UDID            SmbusDeviceUdid;

+} EFI_SMBUS_DEVICE_MAP;

+

+/**

+  The GetArpMap() function returns the mapping of all the SMBus devices 

+  that are enumerated by the SMBus host driver. 

+

+  @param  This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.

+  

+  @param  Length Size of the buffer that contains the SMBus device map.

+  

+  @param  SmbusDeviceMap The pointer to the device map as enumerated 

+  by the SMBus controller driver.

+

+  @retval EFI_SUCCESS The device map was returned correctly in the buffer.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMBUS_HC_PROTOCOL_GET_ARP_MAP) (

+  IN EFI_SMBUS_HC_PROTOCOL              *This,

+  IN OUT  UINTN                         *Length,

+  IN OUT  EFI_SMBUS_DEVICE_MAP          **SmbusDeviceMap

+  );

+

+/**

+  The Notify() function registers all the callback functions to allow the 

+  bus driver to call these functions when the SlaveAddress/Data pair happens.

+

+  @param  This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.

+  

+  @param  SlaveAddress Address that the host controller detects as 

+  sending a message and calls all the registered functions.

+  

+  @param  Data Data that the host controller detects as sending a message 

+  and calls all the registered functions.

+  

+  @param  NotifyFunction The function to call when the bus driver 

+  detects the SlaveAddress and Data pair.

+

+  @retval EFI_SUCCESS NotifyFunction was registered.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMBUS_HC_PROTOCOL_NOTIFY) (

+  IN EFI_SMBUS_HC_PROTOCOL              *This,

+  IN      EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress,

+  IN      UINTN                         Data,

+  IN      EFI_SMBUS_NOTIFY_FUNCTION     NotifyFunction

+  );

+

+/**

+  @par Protocol Description:

+  Provides basic SMBus host controller management and basic data 

+  transactions over the SMBus.

+

+  @param Execute

+  Executes the SMBus operation to an SMBus slave device.

+

+  @param ArpDevice

+  Allows an SMBus 2.0 device(s) to be Address Resolution Protocol (ARP)

+

+  @param GetArpMap

+  Allows a driver to retrieve the address that was allocated by the SMBus 

+  host controller during enumeration/ARP.

+

+  @param Notify

+  Allows a driver to register for a callback to the SMBus host 

+  controller driver when the bus issues a notification to the bus controller driver.

+

+**/

+struct _EFI_SMBUS_HC_PROTOCOL {

+  EFI_SMBUS_HC_EXECUTE_OPERATION    Execute;

+  EFI_SMBUS_HC_PROTOCOL_ARP_DEVICE  ArpDevice;

+  EFI_SMBUS_HC_PROTOCOL_GET_ARP_MAP GetArpMap;

+  EFI_SMBUS_HC_PROTOCOL_NOTIFY      Notify;

+};

+

+extern EFI_GUID gEfiSmbusProtocolGuid;

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmAccess.h b/edk2/MdePkg/Include/Protocol/SmmAccess.h
new file mode 100644
index 0000000..f405c8f
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmAccess.h
@@ -0,0 +1,172 @@
+/** @file

+  This file declares SMM SMRAM Access abstraction protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmAccess.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+**/

+

+#ifndef _SMM_ACCESS_H_

+#define _SMM_ACCESS_H_

+

+typedef struct _EFI_SMM_ACCESS_PROTOCOL  EFI_SMM_ACCESS_PROTOCOL;

+

+#define EFI_SMM_ACCESS_PROTOCOL_GUID \

+  { \

+    0x3792095a, 0xe309, 0x4c1e, {0xaa, 0x01, 0x85, 0xf5, 0x65, 0x5a, 0x17, 0xf1 } \

+  }

+

+//

+// SMM Access specification constant and types

+//

+// *******************************************************

+//  EFI_SMRAM_STATE

+// *******************************************************

+//

+#define EFI_SMRAM_OPEN    0x00000001

+#define EFI_SMRAM_CLOSED  0x00000002

+#define EFI_SMRAM_LOCKED  0x00000004

+#define EFI_CACHEABLE     0x00000008

+#define EFI_ALLOCATED     0x00000010

+

+//

+// SMM Access specification Member Function

+//

+/**

+  Opens the SMRAM area to be accessible by a boot-service driver.

+

+  @param  This The EFI_SMM_ACCESS_PROTOCOL instance. 

+  

+  @param  DescriptorIndex Indicates that the driver wishes to open 

+  the memory tagged by this index. 

+

+  @retval EFI_SUCCESS The operation was successful.

+  

+  @retval EFI_INVALID_PARAMETER The given DescriptorIndex is not supported.

+  

+  @retval EFI_NOT_STARTED The SMM base service has not been initialized.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_OPEN) (

+  IN EFI_SMM_ACCESS_PROTOCOL         *This,

+  UINTN                              DescriptorIndex

+  );

+

+/**

+  Inhibits access to the SMRAM.

+

+  @param  This The EFI_SMM_ACCESS_PROTOCOL instance. 

+  

+  @param  DescriptorIndex Indicates that the driver wishes to open 

+  the memory tagged by this index. 

+

+  @retval EFI_SUCCESS The operation was successful.

+  

+  @retval EFI_DEVICE_ERROR The given DescriptorIndex is not open.

+  

+  @retval EFI_INVALID_PARAMETER The given DescriptorIndex is not supported.

+  

+  @retval EFI_NOT_STARTED The SMM base service has not been initialized.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_CLOSE) (

+  IN EFI_SMM_ACCESS_PROTOCOL          *This,

+  UINTN                               DescriptorIndex

+  );

+

+/**

+  Inhibits access to the SMRAM.

+  

+  @param  This The EFI_SMM_ACCESS_PROTOCOL instance. 

+  

+  @param  DescriptorIndex Indicates that the driver wishes to open 

+  the memory tagged by this index. 

+

+  @retval EFI_SUCCESS The operation was successful.

+  

+  @retval EFI_DEVICE_ERROR The given DescriptorIndex is not open.

+  

+  @retval EFI_INVALID_PARAMETER The given DescriptorIndex is not supported.

+  

+  @retval EFI_NOT_STARTED The SMM base service has not been initialized.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_LOCK) (

+  IN EFI_SMM_ACCESS_PROTOCOL         *This,

+  UINTN                              DescriptorIndex

+  );

+

+/**

+  Queries the memory controller for the possible regions that will support SMRAM.

+

+  @param  This The EFI_SMM_ACCESS_PROTOCOL instance. 

+  

+  @param  SmramMapSize A pointer to the size, in bytes, of the SmramMemoryMap buffer.

+  

+  @param  SmramMap A pointer to the buffer in which firmware places the current memory map.

+

+  @retval EFI_SUCCESS The chipset supported the given resource.

+  

+  @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_CAPABILITIES) (

+  IN EFI_SMM_ACCESS_PROTOCOL             *This,

+  IN OUT UINTN                           *SmramMapSize,

+  IN OUT EFI_SMRAM_DESCRIPTOR            *SmramMap

+  );

+

+/**

+  @par Protocol Description:

+  This protocol is used to control the visibility of the SMRAM on the platform.

+

+  @param Open

+  Opens the SMRAM. 

+

+  @param Close

+  Closes the SMRAM.

+

+  @param Lock

+  Locks the SMRAM. 

+

+  @param GetCapabilities

+  Gets information on possible SMRAM regions.

+

+  @param LockState

+Indicates the current state of the SMRAM. Set to TRUE if any region is locked. 

+

+  @param OpenState

+Indicates the current state of the SMRAM. Set to TRUE if any region is open. 

+

+**/

+struct _EFI_SMM_ACCESS_PROTOCOL {

+  EFI_SMM_OPEN          Open;

+  EFI_SMM_CLOSE         Close;

+  EFI_SMM_LOCK          Lock;

+  EFI_SMM_CAPABILITIES  GetCapabilities;

+  BOOLEAN               LockState;

+  BOOLEAN               OpenState;

+};

+

+extern EFI_GUID gEfiSmmAccessProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmBase.h b/edk2/MdePkg/Include/Protocol/SmmBase.h
new file mode 100644
index 0000000..6dd3a5d
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmBase.h
@@ -0,0 +1,310 @@
+/** @file

+  This file declares SMM Base abstraction protocol.

+  This is the base level of compatiblity for SMM drivers.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmBase.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _SMM_BASE_H_

+#define _SMM_BASE_H_

+

+#define EFI_SMM_BASE_PROTOCOL_GUID \

+  { \

+    0x1390954D, 0xda95, 0x4227, {0x93, 0x28, 0x72, 0x82, 0xc2, 0x17, 0xda, 0xa8 } \

+  }

+

+typedef struct _EFI_SMM_BASE_PROTOCOL             EFI_SMM_BASE_PROTOCOL;

+

+//

+// SMM Handler Definition

+//

+#define EFI_HANDLER_SUCCESS         0x0000

+#define EFI_HANDLER_CRITICAL_EXIT   0x0001

+#define EFI_HANDLER_SOURCE_QUIESCED 0x0002

+#define EFI_HANDLER_SOURCE_PENDING  0x0003

+

+/**

+  Entry Point to Callback service

+

+  @param  SmmImageHandle A handle allocated by the SMM infrastructure code 

+  to uniquely designate a specific DXE SMM driver. 

+  

+  @param  CommunicationBuffer A pointer to a collection of data in memory 

+  that will be conveyed from a non-SMM environment into an SMM environment.

+  The buffer must be contiguous, physically mapped, and be a physical address.

+  

+  @param  SourceSize The size of the CommunicationBuffer.

+

+  @return Status code

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_CALLBACK_ENTRY_POINT) (

+  IN EFI_HANDLE             SmmImageHandle,

+  IN OUT VOID               *CommunicationBuffer OPTIONAL,

+  IN OUT UINTN              *SourceSize OPTIONAL

+  );

+

+//

+// SMM Base Protocol Definition

+//

+/**

+  Register a given driver into SMRAM.This is the equivalent of performing

+  the LoadImage/StartImage into System Management Mode.

+

+  @param  This Protocol instance pointer.

+  @param  FilePath Location of the image to be installed as the handler.

+  @param  SourceBuffer Optional source buffer in case of the image file

+  being in memory.

+  @param  SourceSize Size of the source image file, if in memory.

+  @param  ImageHandle Pointer to the handle that reflects the driver

+  loaded into SMM.

+  @param  LegacyIA32Binary The binary image to load is legacy 16 bit code.

+

+  @retval  EFI_SUCCESS The operation was successful.

+  @retval  EFI_OUT_OF_RESOURCES There were no additional SMRAM resources to load the handler

+  @retval  EFI_UNSUPPORTED This platform does not support 16-bit handlers.

+  @retval  EFI_UNSUPPORTED In runtime.

+  @retval  EFI_INVALID_PARAMETER The handlers was not the correct image type

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_REGISTER_HANDLER) (

+  IN EFI_SMM_BASE_PROTOCOL                           *This,

+  IN  EFI_DEVICE_PATH_PROTOCOL                       *FilePath,

+  IN  VOID                                           *SourceBuffer OPTIONAL,

+  IN  UINTN                                          SourceSize,

+  OUT EFI_HANDLE                                     *ImageHandle,

+  IN  BOOLEAN                                        LegacyIA32Binary OPTIONAL

+  )

+;

+

+/**

+  Remove a given driver SMRAM.  This is the equivalent of performing

+  the UnloadImage System Management Mode.

+

+  @param  This Protocol instance pointer.

+  @param  ImageHandle Pointer to the handle that reflects the driver

+  loaded into SMM.

+

+  @retval  EFI_SUCCESS The operation was successful

+  @retval  EFI_INVALID_PARAMETER The handler did not exist

+  @retval  EFI_UNSUPPORTED In runtime.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_UNREGISTER_HANDLER) (

+  IN EFI_SMM_BASE_PROTOCOL          *This,

+  IN EFI_HANDLE                     ImageHandle

+  )

+;

+

+/**

+  The SMM Inter-module Communicate Service Communicate() function 

+  provides a services to send/received messages from a registered 

+  EFI service.  The BASE protocol driver is responsible for doing 

+  any of the copies such that the data lives in boot-service accessible RAM.

+

+  @param  This Protocol instance pointer.

+  @param  ImageHandle Pointer to the handle that reflects the driver

+  loaded into SMM.

+  @param  CommunicationBuffer Pointer to the buffer to convey into SMRAM.

+  @param  SourceSize Size of the contents of buffer..

+

+  @retval  EFI_SUCCESS The message was successfully posted

+  @retval  EFI_INVALID_PARAMETER The buffer was NULL

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_COMMUNICATE) (

+  IN EFI_SMM_BASE_PROTOCOL          *This,

+  IN EFI_HANDLE                     ImageHandle,

+  IN OUT VOID                       *CommunicationBuffer,

+  IN OUT UINTN                      *SourceSize

+  )

+;

+

+/**

+  Register a callback to execute within SMM.   

+  This allows receipt of messages created with the Boot Service COMMUNICATE.

+

+  @param  This Protocol instance pointer.

+  @param  CallbackAddress Address of the callback service

+  @param  MakeFirst If present, will stipulate that the handler is posted

+  to be the first module executed in the dispatch table.

+  @param  MakeLast If present, will stipulate that the handler is posted

+  to be last executed in the dispatch table.

+  @param  FloatingPointSave This is an optional parameter which informs the

+  EFI_SMM_ACCESS_PROTOCOL Driver core if it needs to save

+  the floating point register state.  If any of the handlers

+  require this, then the state will be saved for all of the handlers.

+

+  @retval  EFI_SUCCESS The operation was successful

+  @retval  EFI_OUT_OF_RESOURCES Not enough space in the dispatch queue

+  @retval  EFI_UNSUPPORTED In runtime.

+  @retval  EFI_UNSUPPORTED Not in SMM.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_CALLBACK_SERVICE) (

+  IN EFI_SMM_BASE_PROTOCOL                            *This,

+  IN EFI_HANDLE                                       SmmImageHandle,

+  IN EFI_SMM_CALLBACK_ENTRY_POINT                     CallbackAddress,

+  IN BOOLEAN                                          MakeLast OPTIONAL,

+  IN BOOLEAN                                          FloatingPointSave OPTIONAL

+  )

+;

+

+/**

+  The SmmAllocatePool() function allocates a memory region of Size bytes from memory of 

+  type PoolType and returns the address of the allocated memory in the location referenced 

+  by Buffer.  This function allocates pages from EFI SMRAM Memory as needed to grow the 

+  requested pool type.  All allocations are eight-byte aligned.

+

+  @param  This Protocol instance pointer.

+  @param  PoolType The type of pool to allocate.

+  The only supported type is EfiRuntimeServicesData;

+  the interface will internally map this runtime request to SMRAM.

+  @param  Size The number of bytes to allocate from the pool.

+  @param  Buffer A pointer to a pointer to the allocated buffer if the call

+  succeeds; undefined otherwise.

+

+  @retval  EFI_SUCCESS The requested number of bytes was allocated.

+  @retval  EFI_OUT_OF_RESOURCES The pool requested could not be allocated.

+  @retval  EFI_INVALID_PARAMETER PoolType was invalid.

+  @retval  EFI_UNSUPPORTED In runtime.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_ALLOCATE_POOL) (

+  IN EFI_SMM_BASE_PROTOCOL          *This,

+  IN EFI_MEMORY_TYPE                PoolType,

+  IN UINTN                          Size,

+  OUT VOID                          **Buffer

+  )

+;

+

+/**

+  The SmmFreePool() function returns the memory specified by Buffer to the system.  

+  On return, the memory's type is EFI SMRAM Memory.  The Buffer that is freed must 

+  have been allocated by SmmAllocatePool().

+

+  @param  This Protocol instance pointer.

+  @param  Buffer Pointer to the buffer allocation.

+

+  @retval  EFI_SUCCESS The memory was returned to the system.

+  @retval  EFI_INVALID_PARAMETER Buffer was invalid.

+  @retval  EFI_UNSUPPORTED In runtime.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_FREE_POOL) (

+  IN EFI_SMM_BASE_PROTOCOL          *This,

+  IN VOID                           *Buffer

+  )

+;

+

+/**

+  This routine tells caller if execution context is SMM or not.

+

+  @param  This Protocol instance pointer.

+  @param  InSmm Whether the caller is inside SMM for IA-32 or servicing a PMI for the Itanium processor family.

+

+  @retval  EFI_SUCCESS The operation was successful

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_INSIDE_OUT) (

+  IN EFI_SMM_BASE_PROTOCOL          *This,

+  OUT BOOLEAN                       *InSmm

+  )

+;

+

+/**

+  The GetSmstLocation() function returns the locatin of the System Management 

+  Service Table.  The use of the API is such that a driver can discover the 

+  location of the SMST in its entry point and then cache it in some driver 

+  global variable so that the SMST can be invoked in subsequent callbacks.

+

+  @param  This Protocol instance pointer.

+  @param  Smst Pointer to the SMST.

+

+  @retval  EFI_SUCCESS The operation was successful

+  @retval  EFI_INVALID_PARAMETER Smst was invalid.

+  @retval  EFI_UNSUPPORTED Not in SMM.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_GET_SMST_LOCATION) (

+  IN EFI_SMM_BASE_PROTOCOL          *This,

+  IN OUT EFI_SMM_SYSTEM_TABLE       **Smst

+  )

+;

+

+/**

+  @par Protocol Description:

+  This protocol is used to install SMM handlers for support of subsequent SMI/PMI 

+  activations. This protocol is available on both IA-32 and Itanium-based systems.

+

+  @param Register

+  Registers a handler to run in System Management RAM (SMRAM).

+

+  @param UnRegister

+  Removes a handler from execution in SMRAM.

+

+  @param Communicate

+  Sends/receives a message for a registered handler.

+

+  @param RegisterCallback

+  Registers a callback from the constructor.

+

+  @param InSmm

+  Detects whether the caller is inside or outside of SMM. SName

+

+  @param SmmAllocatePool

+  Allocates SMRAM.

+

+  @param SmmFreePool

+  Deallocates SMRAM.

+

+  @param GetSmstLocation

+  Retrieves the location of the System Management System Table (SMST).

+

+**/

+struct _EFI_SMM_BASE_PROTOCOL {

+  EFI_SMM_REGISTER_HANDLER    Register;

+  EFI_SMM_UNREGISTER_HANDLER  UnRegister;

+  EFI_SMM_COMMUNICATE         Communicate;

+  EFI_SMM_CALLBACK_SERVICE    RegisterCallback;

+  EFI_SMM_INSIDE_OUT          InSmm;

+  EFI_SMM_ALLOCATE_POOL       SmmAllocatePool;

+  EFI_SMM_FREE_POOL           SmmFreePool;

+  EFI_SMM_GET_SMST_LOCATION   GetSmstLocation;

+};

+

+extern EFI_GUID gEfiSmmBaseProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmControl.h b/edk2/MdePkg/Include/Protocol/SmmControl.h
new file mode 100644
index 0000000..3bcd0f7
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmControl.h
@@ -0,0 +1,139 @@
+/** @file

+  This file declares SMM Control abstraction protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmControl.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _SMM_CONTROL_H_

+#define _SMM_CONTROL_H_

+

+typedef struct _EFI_SMM_CONTROL_PROTOCOL              EFI_SMM_CONTROL_PROTOCOL;

+

+#define EFI_SMM_CONTROL_PROTOCOL_GUID \

+  { \

+    0x8d12e231, 0xc667, 0x4fd1, {0x98, 0xf2, 0x24, 0x49, 0xa7, 0xe7, 0xb2, 0xe5 } \

+  }

+

+// SMM Access specification Data Structures

+//

+typedef struct {

+  UINT8 SmiTriggerRegister;

+  UINT8 SmiDataRegister;

+} EFI_SMM_CONTROL_REGISTER;

+

+//

+// SMM Control specification member function

+//

+/**

+  Invokes SMI activation from either the preboot or runtime environment.

+

+  @param  This The EFI_SMM_CONTROL_PROTOCOL instance. 

+  

+  @param  ArgumentBuffer Optional sized data to pass into the protocol activation. 

+  

+  @param  ArgumentBufferSize Optional size of the data.

+  

+  @param  Periodic Optional mechanism to engender a periodic stream.

+  

+  @param  ActivationInterval Optional parameter to repeat at this period one 

+  time or, if the Periodic Boolean is set, periodically.

+

+  @retval EFI_SUCCESS  The SMI/PMI has been engendered.

+  

+  @retval EFI_DEVICE_ERROR  The timing is unsupported.

+  

+  @retval EFI_INVALID_PARAMETER  The activation period is unsupported.

+  

+  @retval EFI_NOT_STARTED  The SMM base service has not been initialized.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_ACTIVATE) (

+  IN EFI_SMM_CONTROL_PROTOCOL                             *This,

+  IN OUT INT8                                             *ArgumentBuffer OPTIONAL,

+  IN OUT UINTN                                            *ArgumentBufferSize OPTIONAL,

+  IN BOOLEAN                                              Periodic OPTIONAL,

+  IN UINTN                                                ActivationInterval OPTIONAL

+  );

+

+/**

+  Clears any system state that was created in response to the Active call.

+

+  @param  This The EFI_SMM_CONTROL_PROTOCOL instance. 

+  

+  @param  Periodic Optional parameter to repeat at this period one time

+

+  @retval EFI_SUCCESS  The SMI/PMI has been engendered.

+  

+  @retval EFI_DEVICE_ERROR  The source could not be cleared.

+  

+  @retval EFI_INVALID_PARAMETER  The service did not support the Periodic input argument.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_DEACTIVATE) (

+  IN EFI_SMM_CONTROL_PROTOCOL                   *This,

+  IN BOOLEAN                                    Periodic OPTIONAL

+  );

+

+/**

+  Provides information on the source register used to generate the SMI.

+

+  @param  This The EFI_SMM_CONTROL_PROTOCOL instance. 

+  

+  @param  SmiRegister Pointer to the SMI register description structure

+

+  @retval EFI_SUCCESS  The register structure has been returned.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_GET_REGISTER_INFO) (

+  IN EFI_SMM_CONTROL_PROTOCOL           *This,

+  IN OUT EFI_SMM_CONTROL_REGISTER       *SmiRegister

+  );

+

+/**

+  @par Protocol Description:

+  This protocol is used initiate SMI/PMI activations. 

+

+  @param Trigger

+  Initiates the SMI/PMI activation.

+

+  @param Clear

+  Quiesces the SMI/PMI activation. 

+

+  @param GetRegisterInfo

+  Provides data on the register used as the source of the SMI.

+

+  @param MinimumTriggerPeriod

+  Minimum interval at which the platform can set the period. 

+

+**/

+

+struct _EFI_SMM_CONTROL_PROTOCOL {

+  EFI_SMM_ACTIVATE          Trigger;

+  EFI_SMM_DEACTIVATE        Clear;

+  EFI_SMM_GET_REGISTER_INFO GetRegisterInfo;

+  UINTN                     MinimumTriggerPeriod;

+};

+

+extern EFI_GUID gEfiSmmControlProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmGpiDispatch.h b/edk2/MdePkg/Include/Protocol/SmmGpiDispatch.h
new file mode 100644
index 0000000..b472e92
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmGpiDispatch.h
@@ -0,0 +1,150 @@
+/** @file

+  This file declares Smm Gpi Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmGpiDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_GPI_DISPATCH_H_

+#define _EFI_SMM_GPI_DISPATCH_H_

+

+//

+// Global ID for the GPI SMI Protocol

+//

+#define EFI_SMM_GPI_DISPATCH_PROTOCOL_GUID \

+  { \

+    0xe0744b81, 0x9513, 0x49cd, {0x8c, 0xea, 0xe9, 0x24, 0x5e, 0x70, 0x39, 0xda } \

+  }

+

+typedef struct _EFI_SMM_GPI_DISPATCH_PROTOCOL  EFI_SMM_GPI_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+//

+// GpiMask is a bit mask of 32 possible general purpose inputs that can generate a

+// a SMI.  Bit 0 corresponds to logical GPI[0], 1 corresponds to logical GPI[1], etc.

+//

+// The logical GPI index to physical pin on device is described by the GPI device name

+// found on the same handle as the GpiSmi child dispatch protocol.  The GPI device name

+// is defined as protocol with a GUID name and NULL protocol pointer.

+//

+typedef struct {

+  UINTN GpiNum;

+} EFI_SMM_GPI_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a GPI SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The DispatchContext fields are filled in by the dispatching driver prior to

+  invoking this dispatch function.

+

+  @return None

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_GPI_DISPATCH) (

+  IN  EFI_HANDLE                    DispatchHandle,

+  IN  EFI_SMM_GPI_DISPATCH_CONTEXT  *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function the GPI(s) for which the dispatch function

+  should be invoked.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The GPI input value

+  is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_GPI_REGISTER) (

+  IN EFI_SMM_GPI_DISPATCH_PROTOCOL            *This,

+  IN  EFI_SMM_GPI_DISPATCH                    DispatchFunction,

+  IN  EFI_SMM_GPI_DISPATCH_CONTEXT            *DispatchContext,

+  OUT EFI_HANDLE                              *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+  @retval  other TBD

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_GPI_UNREGISTER) (

+  IN EFI_SMM_GPI_DISPATCH_PROTOCOL            *This,

+  IN  EFI_HANDLE                              DispatchHandle

+  );

+

+//

+// Interface structure for the SMM GPI SMI Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for the General Purpose Input 

+  (GPI) SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+  @param NumSupportedGpis

+  Denotes the maximum value of inputs that can have handlers attached.

+

+**/

+struct _EFI_SMM_GPI_DISPATCH_PROTOCOL {

+  EFI_SMM_GPI_REGISTER    Register;

+  EFI_SMM_GPI_UNREGISTER  UnRegister;

+  UINTN                   NumSupportedGpis;

+};

+

+extern EFI_GUID gEfiSmmGpiDispatchProtocolGuid;

+

+#endif

+

diff --git a/edk2/MdePkg/Include/Protocol/SmmIchnDispatch.h b/edk2/MdePkg/Include/Protocol/SmmIchnDispatch.h
new file mode 100644
index 0000000..8829f85
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmIchnDispatch.h
@@ -0,0 +1,193 @@
+/** @file

+  This file declares EFI Smm ICH [N] Specific Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmIchnDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_ICHN_DISPATCH_H_

+#define _EFI_SMM_ICHN_DISPATCH_H_

+

+//

+// Global ID for the ICH SMI Protocol

+//

+#define EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID \

+  { \

+    0xc50b323e, 0x9075, 0x4f2a, {0xac, 0x8e, 0xd2, 0x59, 0x6a, 0x10, 0x85, 0xcc } \

+  }

+

+typedef struct _EFI_SMM_ICHN_DISPATCH_PROTOCOL  EFI_SMM_ICHN_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+//

+// ICHN Specific SMIs.  These are miscellaneous SMI sources that are supported by the

+// ICHN specific SMI implementation.  These may change over time.  TrapNumber is only

+// valid if the Type is Trap.

+//

+typedef enum {

+  //

+  // NOTE: NEVER delete items from this list/enumeration!  Doing so will prevent other versions

+  // of the code from compiling.  If the ICH version your driver is written for doesn't support

+  // some of these SMIs, then simply return EFI_UNSUPPORTED when a child/client tries to register

+  // for them.

+  //

+  IchnMch,

+  IchnPme,

+  IchnRtcAlarm,

+  IchnRingIndicate,

+  IchnAc97Wake,

+  IchnSerialIrq,

+  IchnY2KRollover,

+  IchnTcoTimeout,

+  IchnOsTco,

+  IchnNmi,

+  IchnIntruderDetect,

+  IchnBiosWp,

+  IchnMcSmi,

+  IchnPmeB0,

+  IchnThrmSts,

+  IchnSmBus,

+  IchnIntelUsb2,

+  IchnMonSmi7,

+  IchnMonSmi6,

+  IchnMonSmi5,

+  IchnMonSmi4,

+  IchnDevTrap13,

+  IchnDevTrap12,

+  IchnDevTrap11,

+  IchnDevTrap10,

+  IchnDevTrap9,

+  IchnDevTrap8,

+  IchnDevTrap7,

+  IchnDevTrap6,

+  IchnDevTrap5,

+  IchnDevTrap3,

+  IchnDevTrap2,

+  IchnDevTrap1,

+  IchnDevTrap0,

+  IchnIoTrap3,

+  IchnIoTrap2,

+  IchnIoTrap1,

+  IchnIoTrap0,

+  //

+  // INSERT NEW ITEMS JUST BEFORE THIS LINE

+  //

+  NUM_ICHN_TYPES  // the number of items in this enumeration

+} EFI_SMM_ICHN_SMI_TYPE;

+

+typedef struct {

+  EFI_SMM_ICHN_SMI_TYPE Type;

+} EFI_SMM_ICHN_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a ICH n specific SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The DispatchContext fields are filled in

+  by the dispatching driver prior to

+  invoking this dispatch function.

+

+  Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_ICHN_DISPATCH) (

+  IN  EFI_HANDLE                      DispatchHandle,

+  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT   *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function the ICHN SMI source for which the dispatch

+  function should be invoked.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The ICHN input value

+  is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_ICHN_REGISTER) (

+  IN EFI_SMM_ICHN_DISPATCH_PROTOCOL             *This,

+  IN  EFI_SMM_ICHN_DISPATCH                     DispatchFunction,

+  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT             *DispatchContext,

+  OUT EFI_HANDLE                                *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+  @retval  other TBD

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_ICHN_UNREGISTER) (

+  IN EFI_SMM_ICHN_DISPATCH_PROTOCOL             *This,

+  IN  EFI_HANDLE                                DispatchHandle

+  );

+

+//

+// Interface structure for the SMM Ich n specific SMI Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for a given SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+**/

+struct _EFI_SMM_ICHN_DISPATCH_PROTOCOL {

+  EFI_SMM_ICHN_REGISTER   Register;

+  EFI_SMM_ICHN_UNREGISTER UnRegister;

+};

+

+extern EFI_GUID gEfiSmmIchnDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmPeriodicTimerDispatch.h b/edk2/MdePkg/Include/Protocol/SmmPeriodicTimerDispatch.h
new file mode 100644
index 0000000..c94843f
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmPeriodicTimerDispatch.h
@@ -0,0 +1,194 @@
+/** @file

+  This file declares EFI Smm Periodic Timer Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmPeriodicTimerDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_PERIODIC_TIMER_DISPATCH_H_

+#define _EFI_SMM_PERIODIC_TIMER_DISPATCH_H_

+

+//

+// Global ID for the Periodic Timer SMI Protocol

+//

+#define EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL_GUID \

+  { \

+    0x9cca03fc, 0x4c9e, 0x4a19, {0x9b, 0x6, 0xed, 0x7b, 0x47, 0x9b, 0xde, 0x55 } \

+  }

+

+typedef struct _EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL  EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+//

+// Period is the minimum period of time in 100 nanosecond units that child gets called.

+// The child will be called back after a time greater than the time Period.

+//

+// SmiTickInterval is the period of time interval between SMIs.  Children of this interface

+// should use this field when registering for periodic timer intervals when a finer

+// granularity periodic SMI is desired.  Valid values for this field are those returned

+// by GetNextInterval.  A value of 0 indicates the parent is allowed to use any SMI

+// interval period to satisfy the requested period.

+//    Example: A chipset supports periodic SMIs on every 64ms or 2 seconds.

+//      A child wishes schedule a period SMI to fire on a period of 3 seconds, there

+//      are several ways to approach the problem:

+//      1. The child may accept a 4 second periodic rate, in which case it registers with

+//           Period = 40000

+//           SmiTickInterval = 20000

+//         The resulting SMI will occur every 2 seconds with the child called back on

+//         every 2nd SMI.

+//         NOTE: the same result would occur if the child set SmiTickInterval = 0.

+//      2. The child may choose the finer granularity SMI (64ms):

+//           Period = 30000

+//           SmiTickInterval = 640

+//         The resulting SMI will occur every 64ms with the child called back on

+//         every 47th SMI.

+//         NOTE: the child driver should be aware that this will result in more

+//           SMIs occuring during system runtime which can negatively impact system

+//           performance.

+//

+// ElapsedTime is the actual time in 100 nanosecond units elapsed since last called, a

+// value of 0 indicates an unknown amount of time.

+//

+typedef struct {

+  UINT64  Period;

+  UINT64  SmiTickInterval;

+  UINT64  ElapsedTime;

+} EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a Periodic Timer SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The DispatchContext fields are filled in

+  by the dispatching driver prior to

+  invoking this dispatch function.

+

+  Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_PERIODIC_TIMER_DISPATCH) (

+  IN  EFI_HANDLE                                DispatchHandle,

+  IN  EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT   *DispatchContext

+  );

+

+/**

+  Returns the next SMI tick period supported by the chipset.  The order

+  returned is from longest to shortest interval period.

+

+  @param  This Protocol instance pointer.

+  @param  SmiTickInterval Pointer to pointer of next shorter SMI interval

+  period supported by the child.  This parameter works as a get-first, 

+  get-next field.The first time this function is called, *SmiTickInterval 

+  should be set to NULL to get the longest SMI interval.The returned 

+  *SmiTickInterval should be passed in on subsequent calls to get the 

+  next shorter interval period until *SmiTickInterval = NULL.

+

+  @retval EFI_SUCCESS The service returned successfully.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_PERIODIC_TIMER_INTERVAL) (

+  IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL           *This,

+  IN OUT UINT64                                         **SmiTickInterval

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function the period at which the dispatch function

+  should be invoked.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The period input value

+  is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_PERIODIC_TIMER_REGISTER) (

+  IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL           *This,

+  IN  EFI_SMM_PERIODIC_TIMER_DISPATCH                   DispatchFunction,

+  IN  EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT           *DispatchContext,

+  OUT EFI_HANDLE                                        *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_PERIODIC_TIMER_UNREGISTER) (

+  IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL           *This,

+  IN  EFI_HANDLE                                        DispatchHandle

+  );

+

+//

+// Interface structure for the SMM Periodic Timer Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for the periodical timer SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+  @param GetNextShorterInterval

+  Returns the next SMI tick period that is supported by the chipset. 

+

+**/

+struct _EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL {

+  EFI_SMM_PERIODIC_TIMER_REGISTER   Register;

+  EFI_SMM_PERIODIC_TIMER_UNREGISTER UnRegister;

+  EFI_SMM_PERIODIC_TIMER_INTERVAL   GetNextShorterInterval;

+};

+

+extern EFI_GUID gEfiSmmPeriodicTimerDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmPowerButtonDispatch.h b/edk2/MdePkg/Include/Protocol/SmmPowerButtonDispatch.h
new file mode 100644
index 0000000..065d85f
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmPowerButtonDispatch.h
@@ -0,0 +1,147 @@
+/** @file

+  This file declares EFI Smm Power Button Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmPowerButtonDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_POWER_BUTTON_DISPATCH_H_

+#define _EFI_SMM_POWER_BUTTON_DISPATCH_H_

+

+//

+// Global ID for the Power Button SMI Protocol

+//

+#define EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL_GUID \

+  { \

+    0xb709efa0, 0x47a6, 0x4b41, {0xb9, 0x31, 0x12, 0xec, 0xe7, 0xa8, 0xee, 0x56 } \

+  }

+

+typedef struct _EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL  EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+//

+// Power Button. Example, Use for changing LEDs before ACPI OS is on.

+//    - DXE/BDS Phase

+//    - OS Install Phase

+//

+typedef enum {

+  PowerButtonEntry,

+  PowerButtonExit

+} EFI_POWER_BUTTON_PHASE;

+

+typedef struct {

+  EFI_POWER_BUTTON_PHASE  Phase;

+} EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a Power Button SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The DispatchContext fields are filled in

+  by the dispatching driver prior to

+  invoking this dispatch function.

+

+  Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_POWER_BUTTON_DISPATCH) (

+  IN  EFI_HANDLE                             DispatchHandle,

+  IN  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT  *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function the Power Button SMI phase for which the dispatch

+  function should be invoked.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The Power Button  SMI

+  phase is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_POWER_BUTTON_REGISTER) (

+  IN EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL            *This,

+  IN  EFI_SMM_POWER_BUTTON_DISPATCH                    DispatchFunction,

+  IN  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT            *DispatchContext,

+  OUT EFI_HANDLE                                       *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+  @retval  other TBD

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_POWER_BUTTON_UNREGISTER) (

+  IN EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL             *This,

+  IN  EFI_HANDLE                                        DispatchHandle

+  );

+

+//

+// Interface structure for the SMM Power Button SMI Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for the SMM power button SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+**/

+struct _EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL {

+  EFI_SMM_POWER_BUTTON_REGISTER   Register;

+  EFI_SMM_POWER_BUTTON_UNREGISTER UnRegister;

+};

+

+extern EFI_GUID gEfiSmmPowerButtonDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmStandbyButtonDispatch.h b/edk2/MdePkg/Include/Protocol/SmmStandbyButtonDispatch.h
new file mode 100644
index 0000000..7c52eb1
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmStandbyButtonDispatch.h
@@ -0,0 +1,147 @@
+/** @file

+  This file declares EFI Smm Standby Button Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmStandbyButtonDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_STANDBY_BUTTON_DISPATCH_H_

+#define _EFI_SMM_STANDBY_BUTTON_DISPATCH_H_

+

+//

+// Global ID for the Standby Button SMI Protocol

+//

+#define EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL_GUID \

+  { \

+    0x78965b98, 0xb0bf, 0x449e, {0x8b, 0x22, 0xd2, 0x91, 0x4e, 0x49, 0x8a, 0x98 } \

+  }

+

+typedef struct _EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL  EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+//

+// Standby Button. Example, Use for changing LEDs before ACPI OS is on.

+//    - DXE/BDS Phase

+//    - OS Install Phase

+//

+typedef enum {

+  Entry,

+  Exit

+} EFI_STANDBY_BUTTON_PHASE;

+

+typedef struct {

+  EFI_STANDBY_BUTTON_PHASE  Phase;

+} EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a Standby Button SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The DispatchContext fields are filled in

+  by the dispatching driver prior to

+  invoking this dispatch function.

+

+  @return Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_STANDBY_BUTTON_DISPATCH) (

+  IN  EFI_HANDLE                                DispatchHandle,

+  IN  EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT   *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function the Standby Button SMI phase for which the dispatch

+  function should be invoked.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The Standby Button  SMI

+  phase is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_STANDBY_BUTTON_REGISTER) (

+  IN EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL           *This,

+  IN  EFI_SMM_STANDBY_BUTTON_DISPATCH                   DispatchFunction,

+  IN  EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT           *DispatchContext,

+  OUT EFI_HANDLE                                        *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+  @retval  other TBD

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_STANDBY_BUTTON_UNREGISTER) (

+  IN EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL           *This,

+  IN  EFI_HANDLE                                        DispatchHandle

+  );

+

+//

+// Interface structure for the SMM Standby Button SMI Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for the standby button SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+**/

+struct _EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL {

+  EFI_SMM_STANDBY_BUTTON_REGISTER   Register;

+  EFI_SMM_STANDBY_BUTTON_UNREGISTER UnRegister;

+};

+

+extern EFI_GUID gEfiSmmStandbyButtonDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmStatusCode.h b/edk2/MdePkg/Include/Protocol/SmmStatusCode.h
new file mode 100644
index 0000000..6608715
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmStatusCode.h
@@ -0,0 +1,86 @@
+/** @file

+  This file declares SMM Status code Protocol.

+

+  This code abstracts SMM Status Code reporting.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmStatusCode.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _PROTOCOL_SMM_STATUS_CODE_H__

+#define _PROTOCOL_SMM_STATUS_CODE_H__

+

+//

+// Global ID for the Smm Status Code Protocol

+//

+#define EFI_SMM_STATUS_CODE_PROTOCOL_GUID \

+  { \

+    0x6afd2b77, 0x98c1, 0x4acd, {0xa6, 0xf9, 0x8a, 0x94, 0x39, 0xde, 0xf, 0xb1 } \

+  }

+

+typedef struct _EFI_SMM_STATUS_CODE_PROTOCOL  EFI_SMM_STATUS_CODE_PROTOCOL;

+

+/**

+  Service to emit the status code in SMM.

+

+  @param  This Pointer to EFI_SMM_STATUS_CODE_PROTOCOL instance.

+  

+  @param  CodeType Indicates the type of status code being reported.

+  

+  @param  Value Describes the current status of a hardware or software entity.

+  This included information about the class and subclass that is used to 

+  classify the entity as well as an operation.

+  

+  @param  Instance The enumeration of a hardware or software entity within 

+  the system. Valid instance numbers start with 1.

+  

+  @param  CallerId This optional parameter may be used to identify the caller.

+  This parameter allows the status code driver to apply different rules to 

+  different callers.

+  

+  @param  Data This optional parameter may be used to pass additional data.

+

+  @retval EFI_SUCCESS The function completed successfully

+  

+  @retval EFI_DEVICE_ERROR The function should not be completed due to a device error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_REPORT_STATUS_CODE) (

+  IN EFI_SMM_STATUS_CODE_PROTOCOL *This,

+  IN EFI_STATUS_CODE_TYPE         CodeType,

+  IN EFI_STATUS_CODE_VALUE        Value,

+  IN UINT32                       Instance,

+  IN EFI_GUID                     *CallerId,

+  IN EFI_STATUS_CODE_DATA         *Data OPTIONAL

+  );

+

+/**

+  @par Protocol Description:

+  Provides status code services from SMM.

+

+  @param ReportStatusCode

+  Allows for the SMM agent to produce a status code output.

+

+**/

+struct _EFI_SMM_STATUS_CODE_PROTOCOL {

+  EFI_SMM_REPORT_STATUS_CODE  ReportStatusCode;

+};

+

+extern EFI_GUID gEfiSmmStatusCodeProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmSwDispatch.h b/edk2/MdePkg/Include/Protocol/SmmSwDispatch.h
new file mode 100644
index 0000000..bc456cb
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmSwDispatch.h
@@ -0,0 +1,149 @@
+/** @file

+  This file declares EFI Smm Software Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmSwDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_SW_DISPATCH_H_

+#define _EFI_SMM_SW_DISPATCH_H_

+

+//

+// Global ID for the SW SMI Protocol

+//

+#define EFI_SMM_SW_DISPATCH_PROTOCOL_GUID \

+  { \

+    0xe541b773, 0xdd11, 0x420c, {0xb0, 0x26, 0xdf, 0x99, 0x36, 0x53, 0xf8, 0xbf } \

+  }

+

+typedef struct _EFI_SMM_SW_DISPATCH_PROTOCOL  EFI_SMM_SW_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+//

+// A particular chipset may not support all possible software SMI input values.

+// For example, the ICH supports only values 00h to 0FFh.  The parent only allows a single

+// child registration for each SwSmiInputValue.

+//

+typedef struct {

+  UINTN SwSmiInputValue;

+} EFI_SMM_SW_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a Software SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The SwSmiInputValue field is filled in

+  by the software dispatch driver prior to

+  invoking this dispatch function.

+  The dispatch function will only be called

+  for input values for which it is registered.

+

+  Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_SW_DISPATCH) (

+  IN  EFI_HANDLE                    DispatchHandle,

+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function which Software SMI input value the

+  dispatch function should be invoked for.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The SW driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The SW SMI input value

+  is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_SW_REGISTER) (

+  IN EFI_SMM_SW_DISPATCH_PROTOCOL           *This,

+  IN  EFI_SMM_SW_DISPATCH                   DispatchFunction,

+  IN  EFI_SMM_SW_DISPATCH_CONTEXT           *DispatchContext,

+  OUT EFI_HANDLE                            *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+  @retval  other TBD

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_SW_UNREGISTER) (

+  IN EFI_SMM_SW_DISPATCH_PROTOCOL           *This,

+  IN  EFI_HANDLE                            DispatchHandle

+  );

+

+//

+// Interface structure for the SMM Software SMI Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for a given SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+  @param MaximumSwiValue

+  A read-only field that describes the maximum value that can be used 

+  in the EFI_SMM_SW_DISPATCH_PROTOCOL.Register() service.

+

+**/

+struct _EFI_SMM_SW_DISPATCH_PROTOCOL {

+  EFI_SMM_SW_REGISTER   Register;

+  EFI_SMM_SW_UNREGISTER UnRegister;

+  UINTN                 MaximumSwiValue;

+};

+

+extern EFI_GUID gEfiSmmSwDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmSxDispatch.h b/edk2/MdePkg/Include/Protocol/SmmSxDispatch.h
new file mode 100644
index 0000000..dcbc6a9
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmSxDispatch.h
@@ -0,0 +1,160 @@
+/** @file

+  This file declares EFI Smm Sx Smi Child Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmSxDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+

+**/

+

+#ifndef _EFI_SMM_SX_DISPATCH_H_

+#define _EFI_SMM_SX_DISPATCH_H_

+

+//

+// Global ID for the Sx SMI Protocol

+//

+#define EFI_SMM_SX_DISPATCH_PROTOCOL_GUID \

+  { \

+    0x14fc52be, 0x1dc, 0x426c, {0x91, 0xae, 0xa2, 0x3c, 0x3e, 0x22, 0xa, 0xe8 } \

+  }

+

+typedef struct _EFI_SMM_SX_DISPATCH_PROTOCOL  EFI_SMM_SX_DISPATCH_PROTOCOL;

+//

+// Related Definitions

+//

+typedef enum {

+  SxS0,

+  SxS1,

+  SxS2,

+  SxS3,

+  SxS4,

+  SxS5,

+  EfiMaximumSleepType

+} EFI_SLEEP_TYPE;

+

+typedef enum {

+  SxEntry,

+  SxExit,

+  EfiMaximumPhase

+} EFI_SLEEP_PHASE;

+

+typedef struct {

+  EFI_SLEEP_TYPE  Type;

+  EFI_SLEEP_PHASE Phase;

+} EFI_SMM_SX_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a Sx state SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function¡¯s context. 

+  The Type and Phase fields are filled in by the Sx dispatch driver 

+  prior to invoking this dispatch function. For this interface, 

+  the Sx driver will call the dispatch function for all Sx type 

+  and phases, so the Sx state handler(s) must check the  Type and 

+  Phase field of EFI_SMM_SX_DISPATCH_CONTEXT and act accordingly.

+

+  Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_SX_DISPATCH) (

+  IN  EFI_HANDLE                    DispatchHandle,

+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function which Sx state type and phase the caller

+  wishes to be called back on.  For this intertace,

+  the Sx driver will call the registered handlers for

+  all Sx type and phases, so the Sx state handler(s)

+  must check the Type and Phase field of the Dispatch

+  context and act accordingly.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_UNSUPPORTED The Sx driver or hardware does not support that

+  Sx Type/Phase.

+  @retval  EFI_DEVICE_ERROR The Sx driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. Type & Phase are not

+  within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_SX_REGISTER) (

+  IN EFI_SMM_SX_DISPATCH_PROTOCOL           *This,

+  IN  EFI_SMM_SX_DISPATCH                   DispatchFunction,

+  IN  EFI_SMM_SX_DISPATCH_CONTEXT           *DispatchContext,

+  OUT EFI_HANDLE                            *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully unregistered and the

+  SMI source has been disabled if there are no other registered child

+  dispatch functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+  @retval  other TBD

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_SX_UNREGISTER) (

+  IN EFI_SMM_SX_DISPATCH_PROTOCOL           *This,

+  IN  EFI_HANDLE                            DispatchHandle

+  );

+

+//

+// Interface structure for the SMM Child Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for a given Sx-state source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+**/

+struct _EFI_SMM_SX_DISPATCH_PROTOCOL {

+  EFI_SMM_SX_REGISTER   Register;

+  EFI_SMM_SX_UNREGISTER UnRegister;

+};

+

+extern EFI_GUID gEfiSmmSxDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/SmmUsbDispatch.h b/edk2/MdePkg/Include/Protocol/SmmUsbDispatch.h
new file mode 100644
index 0000000..f036171
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/SmmUsbDispatch.h
@@ -0,0 +1,141 @@
+/** @file

+  This file declares EFI Smm USB Smi Child Protocol.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  SmmUsbDispatch.h

+

+  @par Revision Reference:

+  This Protocol is defined in Framework of EFI SMM Core Interface Spec

+  Version 0.9.

+**/

+

+#ifndef _EFI_SMM_USB_DISPATCH_H_

+#define _EFI_SMM_USB_DISPATCH_H_

+

+//

+// Global ID for the USB Protocol

+//

+#define EFI_SMM_USB_DISPATCH_PROTOCOL_GUID \

+  { \

+    0xa05b6ffd, 0x87af, 0x4e42, {0x95, 0xc9, 0x62, 0x28, 0xb6, 0x3c, 0xf3, 0xf3 } \

+  }

+

+typedef struct _EFI_SMM_USB_DISPATCH_PROTOCOL  EFI_SMM_USB_DISPATCH_PROTOCOL;

+

+//

+// Related Definitions

+//

+typedef enum {

+  UsbLegacy,

+  UsbWake

+} EFI_USB_SMI_TYPE;

+

+typedef struct {

+  EFI_USB_SMI_TYPE          Type;

+  EFI_DEVICE_PATH_PROTOCOL  *Device;

+} EFI_SMM_USB_DISPATCH_CONTEXT;

+

+//

+// Member functions

+//

+/**

+  Dispatch function for a USB SMI handler.

+

+  @param  DispatchHandle Handle of this dispatch function.

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The DispatchContext fields are filled in

+  by the dispatching driver prior to

+  invoking this dispatch function.

+

+  Nothing

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_SMM_USB_DISPATCH) (

+  IN  EFI_HANDLE                    DispatchHandle,

+  IN  EFI_SMM_USB_DISPATCH_CONTEXT  *DispatchContext

+  );

+

+/**

+  Register a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchFunction Pointer to dispatch function to be invoked for

+  this SMI source

+  @param  DispatchContext Pointer to the dispatch function's context.

+  The caller fills this context in before calling

+  the register function to indicate to the register

+  function the USB SMI types for which the dispatch

+  function should be invoked.

+  @param  DispatchHandle Handle of dispatch function, for when interfacing

+  with the parent Sx state SMM driver.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  registered and the SMI source has been enabled.

+  @retval  EFI_DEVICE_ERROR The driver was unable to enable the SMI source.

+  @retval  EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this

+  child.

+  @retval  EFI_INVALID_PARAMETER DispatchContext is invalid. The USB SMI type

+  is not within valid range.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_USB_REGISTER) (

+  IN EFI_SMM_USB_DISPATCH_PROTOCOL            *This,

+  IN  EFI_SMM_USB_DISPATCH                    DispatchFunction,

+  IN  EFI_SMM_USB_DISPATCH_CONTEXT            *DispatchContext,

+  OUT EFI_HANDLE                              *DispatchHandle

+  );

+

+/**

+  Unregister a child SMI source dispatch function with a parent SMM driver

+

+  @param  This Protocol instance pointer.

+  @param  DispatchHandle Handle of dispatch function to deregister.

+

+  @retval  EFI_SUCCESS The dispatch function has been successfully

+  unregistered and the SMI source has been disabled

+  if there are no other registered child dispatch

+  functions for this SMI source.

+  @retval  EFI_INVALID_PARAMETER Handle is invalid.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SMM_USB_UNREGISTER) (

+  IN EFI_SMM_USB_DISPATCH_PROTOCOL            *This,

+  IN  EFI_HANDLE                              DispatchHandle

+  );

+

+//

+// Interface structure for the SMM USB SMI Dispatch Protocol

+//

+/**

+  @par Protocol Description:

+  Provides the parent dispatch service for the USB SMI source generator.

+

+  @param Register

+  Installs a child service to be dispatched by this protocol.

+

+  @param UnRegister

+  Removes a child service dispatched by this protocol.

+

+**/

+struct _EFI_SMM_USB_DISPATCH_PROTOCOL {

+  EFI_SMM_USB_REGISTER    Register;

+  EFI_SMM_USB_UNREGISTER  UnRegister;

+};

+

+extern EFI_GUID gEfiSmmUsbDispatchProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/TapeIo.h b/edk2/MdePkg/Include/Protocol/TapeIo.h
new file mode 100644
index 0000000..8f15b3a
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/TapeIo.h
@@ -0,0 +1,236 @@
+/** @file

+  EFI_TAPE_IO_PROTOCOL as defined in the UEFI 2.0.

+  Provide services to control and access a tape device.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  TapeIo.h

+

+**/

+

+#ifndef __EFI_TAPE_IO_PROTOCOL_H__

+#define __EFI_TAPE_IO_PROTOCOL_H__

+

+#define EFI_TAPE_IO_PROTOCOL_GUID \

+  { \

+    0x1e93e633, 0xd65a, 0x459e, {0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \

+  }

+

+typedef struct _EFI_TAPE_IO_PROTOCOL EFI_TAPE_IO_PROTOCOL;

+

+typedef struct {

+  UINT64     Signature;

+  UINT32     Revision;

+  UINT32     BootDescSize;

+  UINT32     BootDescCRC;

+  EFI_GUID   TapeGUID;

+  EFI_GUID   TapeType;

+  EFI_GUID   TapeUnique;

+  UINT32     BLLocation;

+  UINT32     BLBlocksize;

+  UINT32     BLFilesize;

+  CHAR8      OSVersion[40];

+  CHAR8      AppVersion[40];

+  CHAR8      CreationDate[10];

+  CHAR8      CreationTime[10];

+  CHAR8      SystemName[256];  // UTF-8

+  CHAR8      TapeTitle[120];   // UTF-8

+  CHAR8      pad[468];         // pad to 1024

+} TAPE_HEADER;

+

+/**

+  Reads from the tape.

+

+  @param  This       A pointer to the EFI_TAPE_IO_PROTOCOL instance.

+  @param  BufferSize Size of the buffer in bytes pointed to by Buffer.

+  @param  Buffer     Pointer to the buffer for data to be read into.

+

+  @retval EFI_SUCCESS           Data was successfully transferred from the media.

+  @retval EFI_END_OF_FILE       A filemark was encountered which limited the data

+                                transferred by the read operation or the head is positioned

+                                just after a filemark.

+  @retval EFI_NO_MEDIA          No media is loaded in the device.

+  @retval EFI_NOT_READY         The transfer failed since the device was not ready (e.g. not

+                                online). The transfer may be retried at a later time.

+  @retval EFI_UNSUPPORTED       The device does not support this type of transfer.

+  @retval EFI_TIMEOUT           The transfer failed to complete within the timeout specified.

+  @retval EFI_MEDIA_CHANGED     The media in the device was changed since the last access.

+                                The transfer was aborted since the current position of the

+                                media may be incorrect.

+  @retval EFI_INVALID_PARAMETER A NULL Buffer was specified with a non-zero

+                                BufferSize or the device is operating in fixed block

+                                size mode and the BufferSize was not a multiple of

+                                device¡¯s fixed block size

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to transfer data

+                                from the media.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TAPE_READ) (

+  IN EFI_TAPE_IO_PROTOCOL *This,

+  IN OUT UINTN            *BufferSize,

+  OUT VOID                *Buffer

+  )

+;    

+

+/**

+  Writes to the tape.

+

+  @param  This       A pointer to the EFI_TAPE_IO_PROTOCOL instance.

+  @param  BufferSize Size of the buffer in bytes pointed to by Buffer.

+  @param  Buffer     Pointer to the buffer for data to be written from.

+

+  @retval EFI_SUCCESS           Data was successfully transferred to the media.

+  @retval EFI_END_OF_MEDIA      The logical end of media has been reached. Data may have

+                                been successfully transferred to the media.

+  @retval EFI_NO_MEDIA          No media is loaded in the device.

+  @retval EFI_NOT_READY         The transfer failed since the device was not ready (e.g. not

+                                online). The transfer may be retried at a later time.

+  @retval EFI_UNSUPPORTED       The device does not support this type of transfer.

+  @retval EFI_TIMEOUT           The transfer failed to complete within the timeout specified.

+  @retval EFI_MEDIA_CHANGED     The media in the device was changed since the last access.

+                                The transfer was aborted since the current position of the

+                                media may be incorrect.

+  @retval EFI_WRITE_PROTECTED   The media in the device is write-protected. The transfer

+                                was aborted since a write cannot be completed.

+  @retval EFI_INVALID_PARAMETER A NULL Buffer was specified with a non-zero

+                                BufferSize or the device is operating in fixed block

+                                size mode and the BufferSize was not a multiple of

+                                device¡¯s fixed block size

+  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to transfer data

+                                from the media.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TAPE_WRITE) (

+  IN EFI_TAPE_IO_PROTOCOL *This,

+  IN UINTN                *BufferSize,

+  IN VOID                 *Buffer

+  )

+; 

+  

+

+/**

+  Rewinds the tape.

+

+  @param  This A pointer to the EFI_TAPE_IO_PROTOCOL instance.

+

+  @retval EFI_SUCCESS      The media was successfully repositioned.

+  @retval EFI_NO_MEDIA     No media is loaded in the device.

+  @retval EFI_NOT_READY    Repositioning the media failed since the device was not

+                           ready (e.g. not online). The transfer may be retried at a later time.

+  @retval EFI_UNSUPPORTED  The device does not support this type of media repositioning.

+  @retval EFI_TIMEOUT      Repositioning of the media did not complete within the timeout specified.

+  @retval EFI_DEVICE_ERROR A device error occurred while attempting to reposition the media.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TAPE_REWIND) (

+  IN EFI_TAPE_IO_PROTOCOL *This

+  )

+;   

+

+

+/**

+  Positions the tape.

+

+  @param  This      A pointer to the EFI_TAPE_IO_PROTOCOL instance.

+  @param  Direction Direction and number of data blocks or filemarks to space over on media.

+  @param  Type      Type of mark to space over on media.

+

+  @retval EFI_SUCCESS       The media was successfully repositioned.

+  @retval EFI_END_OF_MEDIA  Beginning or end of media was reached before the

+                            indicated number of data blocks or filemarks were found.

+  @retval EFI_NO_MEDIA      No media is loaded in the device.

+  @retval EFI_NOT_READY     The reposition failed since the device was not ready (e.g. not

+                            online). The reposition may be retried at a later time.

+  @retval EFI_UNSUPPORTED   The device does not support this type of repositioning.

+  @retval EFI_TIMEOUT       The repositioning failed to complete within the timeout specified.

+  @retval EFI_MEDIA_CHANGED The media in the device was changed since the last access.

+                            Repositioning the media was aborted since the current

+                            position of the media may be incorrect.

+  @retval EFI_DEVICE_ERROR  A device error occurred while attempting to reposition the media.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TAPE_SPACE) (

+  IN EFI_TAPE_IO_PROTOCOL *This,

+  INTN                    Direction,

+  UINTN                   Type

+  )

+;   

+

+

+/**

+  Writes filemarks to the media.

+

+  @param  This  A pointer to the EFI_TAPE_IO_PROTOCOL instance.

+  @param  Count Number of filemarks to write to the media.

+

+  @retval EFI_SUCCESS       Data was successfully transferred from the media.

+  @retval EFI_NO_MEDIA      No media is loaded in the device.

+  @retval EFI_NOT_READY     The transfer failed since the device was not ready (e.g. not

+                            online). The transfer may be retried at a later time.

+  @retval EFI_UNSUPPORTED   The device does not support this type of repositioning.

+  @retval EFI_TIMEOUT       The transfer failed to complete within the timeout specified.

+  @retval EFI_MEDIA_CHANGED The media in the device was changed since the last access.

+                            The transfer was aborted since the current position of the

+                            media may be incorrect.

+  @retval EFI_DEVICE_ERROR  A device error occurred while attempting to transfer data from the media.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TAPE_WRITEFM) (

+  IN EFI_TAPE_IO_PROTOCOL *This,

+  IN UINTN                Count

+  )

+;   

+

+

+/**

+  Resets the tape device.

+

+  @param  This                 A pointer to the EFI_TAPE_IO_PROTOCOL instance.

+  @param  ExtendedVerification Indicates whether the parent bus should also be reset.

+

+  @retval  EFI_SUCCESS      The bus and/or device were successfully reset.

+  @retval  EFI_NO_MEDIA     No media is loaded in the device.

+  @retval  EFI_NOT_READY    The reset failed since the device and/or bus was not ready.

+                            The reset may be retried at a later time.

+  @retval  EFI_UNSUPPORTED  The device does not support this type of reset.

+  @retval  EFI_TIMEOUT      The reset did not complete within the timeout allowed.

+  @retval  EFI_DEVICE_ERROR A device error occurred while attempting to reset the bus and/or device.

+

+**/

+typedef 

+EFI_STATUS

+(EFIAPI *EFI_TAPE_RESET) (

+  IN EFI_TAPE_IO_PROTOCOL *This,

+  IN BOOLEAN              ExtendedVerification

+  )

+;    

+

+struct _EFI_TAPE_IO_PROTOCOL {

+  EFI_TAPE_READ           TapeRead;

+  EFI_TAPE_WRITE          TapeWrite;

+  EFI_TAPE_REWIND         TapeRewind;

+  EFI_TAPE_SPACE          TapeSpace;

+  EFI_TAPE_WRITEFM        TapeWriteFM;

+  EFI_TAPE_RESET          TapeReset;

+};

+

+extern EFI_GUID gEfiTapeIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Tcp4.h b/edk2/MdePkg/Include/Protocol/Tcp4.h
new file mode 100644
index 0000000..87dea25
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Tcp4.h
@@ -0,0 +1,507 @@
+/** @file

+  EFI TCPv4 Protocol Definition

+  The EFI TCPv4 Service Binding Protocol is used to locate EFI TCPv4 Protocol drivers to create

+  and destroy child of the driver to communicate with other host using TCP protocol.      

+  The EFI TCPv4 Protocol provides services to send and receive data stream.     

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Tcp4.h

+

+**/

+

+#ifndef __EFI_TCP4_PROTOCOL_H__

+#define __EFI_TCP4_PROTOCOL_H__

+

+#define EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0x00720665, 0x67EB, 0x4a99, {0xBA, 0xF7, 0xD3, 0xC3, 0x3A, 0x1C, 0x7C, 0xC9 } \

+  }

+

+#define EFI_TCP4_PROTOCOL_GUID \

+  { \

+    0x65530BC7, 0xA359, 0x410f, {0xB0, 0x10, 0x5A, 0xAD, 0xC7, 0xEC, 0x2B, 0x62 } \

+  }

+

+typedef struct _EFI_TCP4_PROTOCOL EFI_TCP4_PROTOCOL;

+

+typedef struct {

+  EFI_IPv4_ADDRESS        LocalAddress;

+  UINT16                  LocalPort;

+  EFI_IPv4_ADDRESS        RemoteAddress;

+  UINT16                  RemotePort;

+} EFI_TCP4_SERVICE_POINT;

+

+typedef struct {

+  EFI_HANDLE              DriverHandle;

+  UINTN                   ServiceCount;

+  EFI_TCP4_SERVICE_POINT  Services[1];

+} EFI_TCP4_VARIABLE_DATA;

+

+typedef struct {

+  BOOLEAN                 UseDefaultAddress;

+  EFI_IPv4_ADDRESS        StationAddress;

+  EFI_IPv4_ADDRESS        SubnetMask;

+  UINT16                  StationPort;

+  EFI_IPv4_ADDRESS        RemoteAddress;

+  UINT16                  RemotePort;

+  BOOLEAN                 ActiveFlag;

+} EFI_TCP4_ACCESS_POINT;

+

+typedef struct {

+  UINTN                   ReceiveBufferSize;

+  UINTN                   SendBufferSize;

+  UINTN                   MaxSynBackLog;

+  UINTN                   ConnectionTimeout;

+  UINTN                   DataRetries;

+  UINTN                   FinTimeout;

+  UINTN                   TimeWaitTimeout;

+  UINTN                   KeepAliveProbes;

+  UINTN                   KeepAliveTime;

+  UINTN                   KeepAliveInterval;

+  BOOLEAN                 EnableNagle;

+  BOOLEAN                 EnableTimeStamp;

+  BOOLEAN                 EnableWindowScaling;

+  BOOLEAN                 EnableSelectiveAck;

+  BOOLEAN                 EnablePathMtuDiscovery;

+} EFI_TCP4_OPTION;

+

+typedef struct {

+  //

+  // I/O parameters

+  //

+  UINT8                   TypeOfService;

+  UINT8                   TimeToLive;

+

+  //

+  // Access Point

+  //

+  EFI_TCP4_ACCESS_POINT   AccessPoint;

+                          

+  //                      

+  // TCP Control Options  

+  //                      

+  EFI_TCP4_OPTION         *ControlOption;

+} EFI_TCP4_CONFIG_DATA;

+

+typedef enum {

+  Tcp4StateClosed         = 0,

+  Tcp4StateListen         = 1,

+  Tcp4StateSynSent        = 2,

+  Tcp4StateSynReceived    = 3,

+  Tcp4StateEstablished    = 4,

+  Tcp4StateFinWait1       = 5,

+  Tcp4StateFinWait2       = 6,

+  Tcp4StateClosing        = 7,

+  Tcp4StateTimeWait       = 8,

+  Tcp4StateCloseWait      = 9,

+  Tcp4StateLastAck        = 10

+} EFI_TCP4_CONNECTION_STATE;

+

+typedef struct {

+  EFI_EVENT   Event;

+  EFI_STATUS  Status;

+} EFI_TCP4_COMPLETION_TOKEN;

+

+typedef struct {

+  EFI_TCP4_COMPLETION_TOKEN CompletionToken;

+} EFI_TCP4_CONNECTION_TOKEN;

+

+typedef struct {

+  EFI_TCP4_COMPLETION_TOKEN CompletionToken;

+  EFI_HANDLE                NewChildHandle;

+} EFI_TCP4_LISTEN_TOKEN;

+

+typedef struct {

+  UINTN FragmentLength;

+  VOID  *FragmentBuffer;

+} EFI_TCP4_FRAGMENT_DATA;

+

+typedef struct {

+  BOOLEAN                   UrgentFlag;

+  IN OUT UINTN              DataLength;

+  UINTN                     FragmentCount;

+  EFI_TCP4_FRAGMENT_DATA    FragmentTable[1];

+} EFI_TCP4_RECEIVE_DATA;    

+

+typedef struct {            

+  BOOLEAN                   Push;

+  BOOLEAN                   Urgent;

+  UINTN                     DataLength;

+  UINTN                     FragmentCount;

+  EFI_TCP4_FRAGMENT_DATA    FragmentTable[1];

+} EFI_TCP4_TRANSMIT_DATA;

+

+typedef struct {

+  EFI_TCP4_COMPLETION_TOKEN CompletionToken;

+  union {

+    EFI_TCP4_RECEIVE_DATA   *RxData;

+    EFI_TCP4_TRANSMIT_DATA  *TxData;

+  } Packet;

+} EFI_TCP4_IO_TOKEN;

+

+typedef struct {

+  EFI_TCP4_COMPLETION_TOKEN CompletionToken;

+  BOOLEAN                   AbortOnClose;

+} EFI_TCP4_CLOSE_TOKEN;

+

+//

+// Interface definition for TCP4 protocol

+//

+

+/**

+  Get the current operational status.

+

+  @param  This           Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  Tcp4State      Pointer to the buffer to receive the current TCP state.

+  @param  Tcp4ConfigData Pointer to the buffer to receive the current TCP configuration.

+  @param  Ip4ModeData    Pointer to the buffer to receive the current IPv4 configuration

+                         data used by the TCPv4 instance.

+  @param  MnpConfigData  Pointer to the buffer to receive the current MNP configuration

+                         data used indirectly by the TCPv4 instance.

+  @param  SnpModeData    Pointer to the buffer to receive the current SNP configuration

+                         data used indirectly by the TCPv4 instance.

+

+  @retval EFI_SUCCESS           The mode data was read.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_NOT_STARTED       No configuration data is available because this instance hasn¡¯t

+                                 been started.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_GET_MODE_DATA) (

+  IN  EFI_TCP4_PROTOCOL                  *This,

+  OUT EFI_TCP4_CONNECTION_STATE          *Tcp4State      OPTIONAL,

+  OUT EFI_TCP4_CONFIG_DATA               *Tcp4ConfigData OPTIONAL,

+  OUT EFI_IP4_MODE_DATA                  *Ip4ModeData    OPTIONAL,

+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA    *MnpConfigData  OPTIONAL,

+  OUT EFI_SIMPLE_NETWORK_MODE            *SnpModeData    OPTIONAL

+  )

+;

+  

+/**

+  Initialize or brutally reset the operational parameters for this EFI TCPv4 instance.

+

+  @param  This           Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  Tcp4ConfigData Pointer to the configure data to configure the instance.

+

+  @retval EFI_SUCCESS           The operational settings are set, changed, or reset

+                                successfully.

+  @retval EFI_INVALID_PARAMETER Some parameter is invalid.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (through

+                                DHCP, BOOTP, RARP, etc.) is not finished yet.

+  @retval EFI_ACCESS_DENIED     Configuring TCP instance when it is configured without

+                                calling Configure() with NULL to reset it.

+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.

+  @retval EFI_UNSUPPORTED       One or more of the control options are not supported in

+                                the implementation.

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough system resources when

+                                executing Configure().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_CONFIGURE) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_CONFIG_DATA                *TcpConfigData OPTIONAL

+  )

+;

+    

+

+/**

+  Add or delete a route entry to the route table

+

+  @param  This           Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  DeleteRoute    Set it to TRUE to delete this route from the routing table. Set it to

+                         FALSE to add this route to the routing table.

+                         DestinationAddress and SubnetMask are used as the

+                         keywords to search route entry.

+  @param  SubnetAddress  The destination network.

+  @param  SubnetMask     The subnet mask of the destination network.

+  @param  GatewayAddress The gateway address for this route. It must be on the same

+                         subnet with the station address unless a direct route is specified.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_NOT_STARTED       The EFI TCPv4 Protocol instance has not been configured.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - This is NULL.

+                                - SubnetAddress is NULL.

+                                - SubnetMask is NULL.

+                                - GatewayAddress is NULL.

+                                - *SubnetAddress is not NULL a valid subnet address.

+                                - *SubnetMask is not a valid subnet mask.

+                                - *GatewayAddress is not a valid unicast IP address or it

+                                is not in the same subnet.

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough resources to add the entry to the

+                                routing table.

+  @retval EFI_NOT_FOUND         This route is not in the routing table.

+  @retval EFI_ACCESS_DENIED     The route is already defined in the routing table.

+  @retval EFI_UNSUPPORTED       The TCP driver does not support this operation.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_ROUTES) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN BOOLEAN                             DeleteRoute,

+  IN EFI_IPv4_ADDRESS                    *SubnetAddress,

+  IN EFI_IPv4_ADDRESS                    *SubnetMask,

+  IN EFI_IPv4_ADDRESS                    *GatewayAddress

+  )

+;  

+

+/**

+  Initiate a nonblocking TCP connection request for an active TCP instance.

+

+  @param  This                  Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  ConnectionToken       Pointer to the connection token to return when the TCP three

+                                way handshake finishes.

+                                 

+  @retval EFI_SUCCESS           The connection request is successfully initiated and the state

+                                - of this TCPv4 instance has been changed to

+                                - Tcp4StateSynSent.

+  @retval EFI_NOT_STARTED       This EFI TCPv4 Protocol instance has not been configured.

+  @retval EFI_ACCESS_DENIED     One or more of the following conditions are TRUE:

+                                - This instance is not configured as an active one.

+                                - This instance is not in Tcp4StateClosed state.

+  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:

+                                - This is NULL.

+                                - ConnectionToken is NULL.

+                                - ConnectionToken->CompletionToken.Event is NULL.

+  @retval EFI_OUT_OF_RESOURCES  The driver can¡¯t allocate enough resource to initiate the activeopen.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_CONNECT) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_CONNECTION_TOKEN           *ConnectionToken

+  )

+;  

+  

+

+/**

+  Listen on the passive instance to accept an incoming connection request. This is a nonblocking operation.

+

+  @param  This        Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  ListenToken Pointer to the listen token to return when operation finishes.

+

+  @retval EFI_SUCCESS           The listen token has been queued successfully.

+  @retval EFI_NOT_STARTED       This EFI TCPv4 Protocol instance has not been configured.

+  @retval EFI_ACCESS_DENIED     One or more of the following are TRUE:

+                                - This instance is not a passive instance.

+                                - This instance is not in Tcp4StateListen state.

+                                - The same listen token has already existed in the listen

+                                token queue of this TCP instance.

+  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:

+                                - This is NULL.

+                                - ListenToken is NULL.

+                                - ListentToken->CompletionToken.Event is NULL.

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough resource to finish the operation.

+  @retval EFI_DEVICE_ERROR      Any unexpected and not belonged to above category error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_ACCEPT) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_LISTEN_TOKEN               *ListenToken

+  )

+;    

+

+/**

+  Queues outgoing data into the transmit queue.

+

+  @param  This  Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  Token Pointer to the completion token to queue to the transmit queue.

+

+  @retval EFI_SUCCESS             The data has been queued for transmission.

+  @retval EFI_NOT_STARTED         This EFI TCPv4 Protocol instance has not been configured.

+  @retval EFI_NO_MAPPING          When using a default address, configuration (DHCP, BOOTP,

+                                  RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:

+                                  - This is NULL.

+                                  - Token is NULL.

+                                  - Token->CompletionToken.Event is NULL.

+                                  - Token->Packet.TxData is NULL L.

+                                  - Token->Packet.FragmentCount is zero.

+                                  - Token->Packet.DataLength is not equal to the sum of fragment lengths.

+  @retval EFI_ACCESS_DENIED       One or more of the following conditions is TRUE:

+                                  - A transmit completion token with the same Token->CompletionToken.Event

+                                  was already in the transmission queue.

+                                  - The current instance is in Tcp4StateClosed state.

+                                  - The current instance is a passive one and it is in

+                                  Tcp4StateListen state.

+                                  - User has called Close() to disconnect this connection.

+  @retval EFI_NOT_READY           The completion token could not be queued because the

+                                  transmit queue is full.

+  @retval EFI_OUT_OF_RESOURCES    Could not queue the transmit data because of resource

+                                  shortage.

+  @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_TRANSMIT) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_IO_TOKEN                   *Token

+  )

+;      

+

+

+/**

+  Places an asynchronous receive request into the receiving queue.

+

+  @param  This  Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  Token Pointer to a token that is associated with the receive data

+                descriptor.

+

+  @retval EFI_SUCCESS           The receive completion token was cached.

+  @retval EFI_NOT_STARTED       This EFI TCPv4 Protocol instance has not been configured.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP, RARP,

+                                etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - This is NULL.

+                                - Token is NULL.

+                                - Token->CompletionToken.Event is NULL.

+                                - Token->Packet.RxData is NULL.

+                                - Token->Packet.RxData->DataLength is 0.

+                                - The Token->Packet.RxData->DataLength is not

+                                the sum of all FragmentBuffer length in FragmentTable.

+  @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of

+                               system resources (usually memory).

+  @retval EFI_DEVICE_ERROR     An unexpected system or network error occurred.

+  @retval EFI_ACCESS_DENIED    One or more of the following conditions is TRUE:

+                               - A receive completion token with the same Token-

+                               >CompletionToken.Event was already in the receive

+                               queue.

+                               - The current instance is in Tcp4StateClosed state.

+                               - The current instance is a passive one and it is in

+                               Tcp4StateListen state.

+                               - User has called Close() to disconnect this connection.

+  @retval EFI_CONNECTION_FIN   The communication peer has closed the connection and there is

+                               no any buffered data in the receive buffer of this instance.

+  @retval EFI_NOT_READY        The receive request could not be queued because the receive queue is full.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_RECEIVE) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_IO_TOKEN                   *Token

+  )

+;       

+   

+/**

+  Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a

+  nonblocking operation.                                                                                                                                                                        

+

+  @param  This       Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  CloseToken Pointer to the close token to return when operation finishes.

+

+  @retval EFI_SUCCESS           The Close() is called successfully.

+  @retval EFI_NOT_STARTED       This EFI TCPv4 Protocol instance has not been configured.

+  @retval EFI_ACCESS_DENIED     One or more of the following are TRUE:

+                                - Configure() has been called with

+                                TcpConfigData set to NULL and this function has

+                                not returned.

+                                - Previous Close() call on this instance has not

+                                finished.

+  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:

+                                - This is NULL.

+                                - CloseToken is NULL.

+                                - CloseToken->CompletionToken.Event is NULL.

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough resource to finish the operation.

+  @retval EFI_DEVICE_ERROR      Any unexpected and not belonged to above category error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_CLOSE) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_CLOSE_TOKEN                *CloseToken

+  )

+;      

+

+/**

+  Abort an asynchronous connection, listen, transmission or receive request.

+

+  @param  This  Pointer to the EFI_TCP4_PROTOCOL instance.

+  @param  Token Pointer to a token that has been issued by

+                EFI_TCP4_PROTOCOL.Connect(),

+                EFI_TCP4_PROTOCOL.Accept(),

+                EFI_TCP4_PROTOCOL.Transmit() or

+                EFI_TCP4_PROTOCOL.Receive(). If NULL, all pending

+                tokens issued by above four functions will be aborted. Type

+                EFI_TCP4_COMPLETION_TOKEN is defined in

+                EFI_TCP4_PROTOCOL.Connect().

+

+  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.

+  @retval  EFI_INVALID_PARAMETER This is NULL.

+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval  EFI_NOT_READY         No incoming or outgoing data is processed.

+  @retval  EFI_TIMEOUT           Data was dropped out of the transmission or receive queue.

+                                 Consider increasing the polling rate.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_CANCEL) (

+  IN EFI_TCP4_PROTOCOL                   *This,

+  IN EFI_TCP4_COMPLETION_TOKEN           *Token OPTIONAL

+  )

+;      

+

+

+/**

+  Poll to receive incoming data and transmit outgoing segments.

+

+  @param  This Pointer to the EFI_TCP4_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.

+  @retval  EFI_INVALID_PARAMETER This is NULL.

+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval  EFI_NOT_READY         No incoming or outgoing data is processed.

+  @retval  EFI_TIMEOUT           Data was dropped out of the transmission or receive queue.

+                                 Consider increasing the polling rate.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_TCP4_POLL) (

+  IN EFI_TCP4_PROTOCOL                   *This

+  )

+;      

+

+struct _EFI_TCP4_PROTOCOL {

+  EFI_TCP4_GET_MODE_DATA                 GetModeData;

+  EFI_TCP4_CONFIGURE                     Configure;

+  EFI_TCP4_ROUTES                        Routes;

+  EFI_TCP4_CONNECT                       Connect;

+  EFI_TCP4_ACCEPT                        Accept;

+  EFI_TCP4_TRANSMIT                      Transmit;

+  EFI_TCP4_RECEIVE                       Receive;

+  EFI_TCP4_CLOSE                         Close;

+  EFI_TCP4_CANCEL                        Cancel;

+  EFI_TCP4_POLL                          Poll;

+};

+

+#define EFI_CONNECTION_FIN               EFIERR (104)

+#define EFI_CONNECTION_RESET             EFIERR (105)

+#define EFI_CONNECTION_REFUSED           EFIERR (106)

+

+extern EFI_GUID gEfiTcp4ServiceBindingProtocolGuid;

+extern EFI_GUID gEfiTcp4ProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Udp4.h b/edk2/MdePkg/Include/Protocol/Udp4.h
new file mode 100644
index 0000000..7ac3c80
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Udp4.h
@@ -0,0 +1,363 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Udp4.h

+

+**/

+

+#ifndef __EFI_UDP4_PROTOCOL_H__

+#define __EFI_UDP4_PROTOCOL_H__

+

+//

+//GUID definitions

+//

+#define EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID \

+  { \

+    0x83f01464, 0x99bd, 0x45e5, {0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6 } \

+  }

+

+#define EFI_UDP4_PROTOCOL_GUID \

+  { \

+    0x3ad9df29, 0x4501, 0x478d, {0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3 } \

+  }

+

+typedef struct _EFI_UDP4_PROTOCOL EFI_UDP4_PROTOCOL; 

+  

+typedef struct {

+  EFI_HANDLE              InstanceHandle;

+  EFI_IPv4_ADDRESS        LocalAddress;

+  UINT16                  LocalPort;

+  EFI_IPv4_ADDRESS        RemoteAddress;

+  UINT16                  RemotePort;

+} EFI_UDP4_SERVICE_POINT; 

+

+typedef struct {

+  EFI_HANDLE              DriverHandle;

+  UINT32                  ServiceCount;

+  EFI_UDP4_SERVICE_POINT  Services[1];

+} EFI_UDP4_VARIABLE_DATA;

+

+//

+//ICMP error definitions

+//

+#define EFI_NETWORK_UNREACHABLE      EFIERR(100)

+#define EFI_HOST_UNREACHABLE         EFIERR(101) 

+#define EFI_PROTOCOL_UNREACHABLE     EFIERR(102)

+#define EFI_PORT_UNREACHABLE         EFIERR(103)

+

+

+typedef struct {

+  UINT32             FragmentLength;

+  VOID               *FragmentBuffer;

+} EFI_UDP4_FRAGMENT_DATA;

+

+typedef struct {

+  EFI_IPv4_ADDRESS   SourceAddress;

+  UINT16             SourcePort;

+  EFI_IPv4_ADDRESS   DestinationAddress;

+  UINT16             DestinationPort;

+} EFI_UDP4_SESSION_DATA;

+typedef struct {

+  //

+  // Receiving Filters

+  //

+  BOOLEAN            AcceptBroadcast;

+  BOOLEAN            AcceptPromiscuous;

+  BOOLEAN            AcceptAnyPort;

+  BOOLEAN            AllowDuplicatePort;

+  //

+  // I/O parameters

+  //

+  UINT8              TypeOfService;

+  UINT8              TimeToLive;

+  BOOLEAN            DoNotFragment;

+  UINT32             ReceiveTimeout;

+  UINT32             TransmitTimeout;

+  //

+  // Access Point

+  //

+  BOOLEAN            UseDefaultAddress;

+  EFI_IPv4_ADDRESS   StationAddress;

+  EFI_IPv4_ADDRESS   SubnetMask;

+  UINT16             StationPort;

+  EFI_IPv4_ADDRESS   RemoteAddress;

+  UINT16             RemotePort;

+} EFI_UDP4_CONFIG_DATA;

+

+typedef struct {

+  EFI_UDP4_SESSION_DATA     *UdpSessionData;       //OPTIONAL

+  EFI_IPv4_ADDRESS          *GatewayAddress;       //OPTIONAL

+  UINT32                    DataLength;

+  UINT32                    FragmentCount; 

+  EFI_UDP4_FRAGMENT_DATA    FragmentTable[1];

+} EFI_UDP4_TRANSMIT_DATA;

+

+typedef struct {

+  EFI_TIME                  TimeStamp;

+  EFI_EVENT                 RecycleSignal;

+  EFI_UDP4_SESSION_DATA     UdpSession;

+  UINT32                    DataLength;

+  UINT32                    FragmentCount;

+  EFI_UDP4_FRAGMENT_DATA    FragmentTable[1];

+} EFI_UDP4_RECEIVE_DATA;

+

+

+typedef struct {

+  EFI_EVENT                 Event;

+  EFI_STATUS                Status;

+  union {

+    EFI_UDP4_RECEIVE_DATA   *RxData;

+    EFI_UDP4_TRANSMIT_DATA  *TxData;

+  } Packet;

+} EFI_UDP4_COMPLETION_TOKEN;

+

+/**

+  Reads the current operational settings.

+

+  @param  This           Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  Udp4ConfigData Pointer to the buffer to receive the current configuration data.

+  @param  Ip4ModeData    Pointer to the EFI IPv4 Protocol mode data structure.

+  @param  MnpConfigData  Pointer to the managed network configuration data structure.

+  @param  SnpModeData    Pointer to the simple network mode data structure.

+

+  @retval EFI_SUCCESS           The mode data was read.

+  @retval EFI_NOT_STARTED       When Udp4ConfigData is queried, no configuration data is

+                                available because this instance has not been started.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_GET_MODE_DATA) (

+  IN  EFI_UDP4_PROTOCOL                *This,

+  OUT EFI_UDP4_CONFIG_DATA             *Udp4ConfigData OPTIONAL,

+  OUT EFI_IP4_MODE_DATA                *Ip4ModeData    OPTIONAL,

+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData  OPTIONAL,

+  OUT EFI_SIMPLE_NETWORK_MODE          *SnpModeData    OPTIONAL

+  )

+;  

+  

+

+/**

+  Initializes, changes, or resets the operational parameters for this instance of the EFI UDPv4

+  Protocol.

+

+  @param  This           Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  Udp4ConfigData Pointer to the buffer to receive the current configuration data.

+

+  @retval EFI_SUCCESS           The configuration settings were set, changed, or reset successfully.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:

+  @retval EFI_ALREADY_STARTED   The EFI UDPv4 Protocol instance is already started/configured

+                                and must be stopped/reset before it can be reconfigured.

+  @retval EFI_ACCESS_DENIED     UdpConfigData. AllowDuplicatePort is FALSE

+                                and UdpConfigData.StationPort is already used by

+                                other instance.

+  @retval EFI_OUT_OF_RESOURCES  The EFI UDPv4 Protocol driver cannot allocate memory for this

+                                EFI UDPv4 Protocol instance.

+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred and this instance

+                                 was not opened. 

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_CONFIGURE) (

+  IN EFI_UDP4_PROTOCOL      *This,

+  IN EFI_UDP4_CONFIG_DATA   *UdpConfigData OPTIONAL

+  )

+;  

+

+/**

+  Joins and leaves multicast groups.

+

+  @param  This             Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  JoinFlag         Set to TRUE to join a multicast group. Set to FALSE to leave one

+                           or all multicast groups.

+  @param  MulticastAddress Pointer to multicast group address to join or leave.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_NOT_STARTED       The EFI UDPv4 Protocol instance has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_OUT_OF_RESOURCES  Could not allocate resources to join the group.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+                                - This is NULL.

+                                - JoinFlag is TRUE and MulticastAddress is NULL.

+                                - JoinFlag is TRUE and *MulticastAddress is not

+                                  a valid multicast address.

+  @retval EFI_ALREADY_STARTED   The group address is already in the group table (when

+                                JoinFlag is TRUE).

+  @retval EFI_NOT_FOUND         The group address is not in the group table (when JoinFlag is

+                                FALSE).

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_GROUPS) (

+  IN EFI_UDP4_PROTOCOL      *This,

+  IN BOOLEAN                JoinFlag,

+  IN EFI_IPv4_ADDRESS       *MulticastAddress    OPTIONAL

+  )

+;   

+

+/**

+  Adds and deletes routing table entries.

+

+  @param  This           Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  DeleteRoute    Set to TRUE to delete this route from the routing table.

+                         Set to FALSE to add this route to the routing table.

+  @param  SubnetAddress  The destination network address that needs to be routed.

+  @param  SubnetMask     The subnet mask of SubnetAddress.

+  @param  GatewayAddress The gateway IP address for this route.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_NOT_STARTED       The EFI UDPv4 Protocol instance has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                - RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  Could not add the entry to the routing table.

+  @retval EFI_NOT_FOUND         This route is not in the routing table.

+  @retval EFI_ACCESS_DENIED     The route is already defined in the routing table.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_ROUTES) (

+  IN EFI_UDP4_PROTOCOL      *This,

+  IN BOOLEAN                DeleteRoute,

+  IN EFI_IPv4_ADDRESS       *SubnetAddress,

+  IN EFI_IPv4_ADDRESS       *SubnetMask,

+  IN EFI_IPv4_ADDRESS       *GatewayAddress

+  )

+;     

+

+/**

+  Polls for incoming data packets and processes outgoing data packets.

+

+  @param  This Pointer to the EFI_UDP4_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           Incoming or outgoing data was processed.

+  @retval EFI_INVALID_PARAMETER This is NULL.

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_POLL) (

+  IN EFI_UDP4_PROTOCOL      *This

+  )

+;   

+

+/**

+  Places an asynchronous receive request into the receiving queue.

+

+  @param  This  Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  Token Pointer to a token that is associated with the receive data

+                descriptor.

+

+  @retval EFI_SUCCESS           The receive completion token was cached.

+  @retval EFI_NOT_STARTED       This EFI UDPv4 Protocol instance has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP, RARP, etc.)

+                                is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:

+  @retval EFI_OUT_OF_RESOURCES  The receive completion token could not be queued due to a lack of system

+                                resources (usually memory).

+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

+  @retval EFI_ACCESS_DENIED     A receive completion token with the same Token.Event was already in

+                                the receive queue.

+  @retval EFI_NOT_READY         The receive request could not be queued because the receive queue is full.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_RECEIVE) (

+  IN EFI_UDP4_PROTOCOL          *This,

+  IN EFI_UDP4_COMPLETION_TOKEN  *Token

+  )

+;   

+

+/**

+  Queues outgoing data packets into the transmit queue.

+

+  @param  This  Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  Token Pointer to the completion token that will be placed into the

+                transmit queue.

+

+  @retval EFI_SUCCESS           The data has been queued for transmission.

+  @retval EFI_NOT_STARTED       This EFI UDPv4 Protocol instance has not been started.

+  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,

+                                RARP, etc.) is not finished yet.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_ACCESS_DENIED     The transmit completion token with the same

+                                Token.Event was already in the transmit queue.

+  @retval EFI_NOT_READY         The completion token could not be queued because the

+                                transmit queue is full.

+  @retval EFI_OUT_OF_RESOURCES  Could not queue the transmit data.

+  @retval EFI_NOT_FOUND         There is no route to the destination network or address.

+  @retval EFI_BAD_BUFFER_SIZE   The data length is greater than the maximum UDP packet

+                                size. Or the length of the IP header + UDP header + data

+                                length is greater than MTU if DoNotFragment is TRUE.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_TRANSMIT) (

+  IN EFI_UDP4_PROTOCOL           *This,

+  IN EFI_UDP4_COMPLETION_TOKEN   *Token

+  )

+;     

+

+/**

+  Aborts an asynchronous transmit or receive request.

+

+  @param  This  Pointer to the EFI_UDP4_PROTOCOL instance.

+  @param  Token Pointer to a token that has been issued by

+                EFI_UDP4_PROTOCOL.Transmit() or

+                EFI_UDP4_PROTOCOL.Receive().If NULL, all pending

+                tokens are aborted.

+

+  @retval  EFI_SUCCESS           The asynchronous I/O request was aborted and Token.Event

+                                 was signaled. When Token is NULL, all pending requests are

+                                 aborted and their events are signaled.

+  @retval  EFI_INVALID_PARAMETER This is NULL.

+  @retval  EFI_NOT_STARTED       This instance has not been started.

+  @retval  EFI_NO_MAPPING        When using the default address, configuration (DHCP, BOOTP,

+                                 RARP, etc.) is not finished yet.

+  @retval  EFI_NOT_FOUND         When Token is not NULL, the asynchronous I/O request was

+                                 not found in the transmit or receive queue. It has either completed

+                                 or was not issued by Transmit() and Receive().

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UDP4_CANCEL)(

+  IN EFI_UDP4_PROTOCOL          *This,

+  IN EFI_UDP4_COMPLETION_TOKEN  *Token  OPTIONAL

+  )

+;       

+

+struct _EFI_UDP4_PROTOCOL {

+  EFI_UDP4_GET_MODE_DATA        GetModeData;

+  EFI_UDP4_CONFIGURE            Configure;

+  EFI_UDP4_GROUPS               Groups;

+  EFI_UDP4_ROUTES               Routes;

+  EFI_UDP4_TRANSMIT             Transmit;

+  EFI_UDP4_RECEIVE              Receive;

+  EFI_UDP4_CANCEL               Cancel;

+  EFI_UDP4_POLL                 Poll;

+};

+

+extern EFI_GUID gEfiUdp4ServiceBindingProtocolGuid;

+extern EFI_GUID gEfiUdp4ProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/UgaDraw.h b/edk2/MdePkg/Include/Protocol/UgaDraw.h
new file mode 100644
index 0000000..5586bdf
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/UgaDraw.h
@@ -0,0 +1,168 @@
+/** @file

+  UGA Draw protocol from the EFI 1.1 specification.

+

+  Abstraction of a very simple graphics device.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  UgaDraw.h

+

+**/

+

+#ifndef __UGA_DRAW_H__

+#define __UGA_DRAW_H__

+

+#define EFI_UGA_DRAW_PROTOCOL_GUID \

+  { \

+    0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \

+  }

+

+typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL;

+

+/**

+  Return the current video mode information.

+

+  @param  This                  Protocol instance pointer.

+  @param  HorizontalResolution  Current video horizontal resolution in pixels

+  @param  VerticalResolution    Current video vertical resolution in pixels

+  @param  ColorDepth            Current video color depth in bits per pixel

+  @param  RefreshRate           Current video refresh rate in Hz.

+

+  @retval EFI_SUCCESS           Mode information returned.

+  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()

+  @retval EFI_INVALID_PARAMETER One of the input args was NULL.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE) (

+  IN  EFI_UGA_DRAW_PROTOCOL *This,

+  OUT UINT32                *HorizontalResolution,

+  OUT UINT32                *VerticalResolution,

+  OUT UINT32                *ColorDepth,

+  OUT UINT32                *RefreshRate

+  )

+;

+

+/**

+  Return the current video mode information.

+

+  @param  This                 Protocol instance pointer.

+  @param  HorizontalResolution Current video horizontal resolution in pixels

+  @param  VerticalResolution   Current video vertical resolution in pixels

+  @param  ColorDepth           Current video color depth in bits per pixel

+  @param  RefreshRate          Current video refresh rate in Hz.

+

+  @retval EFI_SUCCESS          Mode information returned.

+  @retval EFI_NOT_STARTED      Video display is not initialized. Call SetMode ()

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE) (

+  IN  EFI_UGA_DRAW_PROTOCOL *This,

+  IN  UINT32                HorizontalResolution,

+  IN  UINT32                VerticalResolution,

+  IN  UINT32                ColorDepth,

+  IN  UINT32                RefreshRate

+  )

+;

+

+typedef struct {

+  UINT8 Blue;

+  UINT8 Green;

+  UINT8 Red;

+  UINT8 Reserved;

+} EFI_UGA_PIXEL;

+

+typedef union {

+  EFI_UGA_PIXEL Pixel;

+  UINT32        Raw;

+} EFI_UGA_PIXEL_UNION;

+

+typedef enum {

+  EfiUgaVideoFill,

+  EfiUgaVideoToBltBuffer,

+  EfiUgaBltBufferToVideo,

+  EfiUgaVideoToVideo,

+  EfiUgaBltMax

+} EFI_UGA_BLT_OPERATION;

+

+/**

+  Type specifying a pointer to a function to perform an UGA Blt operation.

+

+    The following table defines actions for BltOperations:

+

+    <B>EfiUgaVideoFill</B> - Write data from the  BltBuffer pixel (SourceX, SourceY) 

+      directly to every pixel of the video display rectangle 

+      (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). 

+      Only one pixel will be used from the BltBuffer. Delta is NOT used.

+

+    <B>EfiUgaVideoToBltBuffer</B> - Read data from the video display rectangle 

+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in 

+      the BltBuffer rectangle (DestinationX, DestinationY ) 

+      (DestinationX + Width, DestinationY + Height). If DestinationX or 

+      DestinationY is not zero then Delta must be set to the length in bytes 

+      of a row in the BltBuffer.

+

+    <B>EfiUgaBltBufferToVideo</B> - Write data from the  BltBuffer rectangle 

+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the 

+      video display rectangle (DestinationX, DestinationY) 

+      (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is 

+      not zero then Delta must be set to the length in bytes of a row in the 

+      BltBuffer.

+

+    <B>EfiUgaVideoToVideo</B> - Copy from the video display rectangle (SourceX, SourceY)

+     (SourceX + Width, SourceY + Height) .to the video display rectangle 

+     (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). 

+     The BltBuffer and Delta  are not used in this mode.

+

+

+    @param[in] This          - Protocol instance pointer.

+    @param[in] BltBuffer     - Buffer containing data to blit into video buffer. This 

+                               buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)

+    @param[in] BltOperation  - Operation to perform on BlitBuffer and video memory

+    @param[in] SourceX       - X coordinate of source for the BltBuffer.

+    @param[in] SourceY       - Y coordinate of source for the BltBuffer.

+    @param[in] DestinationX  - X coordinate of destination for the BltBuffer.

+    @param[in] DestinationY  - Y coordinate of destination for the BltBuffer.

+    @param[in] Width         - Width of rectangle in BltBuffer in pixels.

+    @param[in] Height        - Hight of rectangle in BltBuffer in pixels.

+    @param[in] Delta         - OPTIONAL

+  

+    @retval EFI_SUCCESS           - The Blt operation completed.

+    @retval EFI_INVALID_PARAMETER - BltOperation is not valid.

+    @retval EFI_DEVICE_ERROR      - A hardware error occured writting to the video buffer.

+

+--*/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT) (

+  IN  EFI_UGA_DRAW_PROTOCOL                   * This,

+  IN  EFI_UGA_PIXEL                           * BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION                   BltOperation,

+  IN  UINTN                                   SourceX,

+  IN  UINTN                                   SourceY,

+  IN  UINTN                                   DestinationX,

+  IN  UINTN                                   DestinationY,

+  IN  UINTN                                   Width,

+  IN  UINTN                                   Height,

+  IN  UINTN                                   Delta         OPTIONAL

+  );

+

+struct _EFI_UGA_DRAW_PROTOCOL {

+  EFI_UGA_DRAW_PROTOCOL_GET_MODE  GetMode;

+  EFI_UGA_DRAW_PROTOCOL_SET_MODE  SetMode;

+  EFI_UGA_DRAW_PROTOCOL_BLT       Blt;

+};

+

+extern EFI_GUID gEfiUgaDrawProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/UnicodeCollation.h b/edk2/MdePkg/Include/Protocol/UnicodeCollation.h
new file mode 100644
index 0000000..e027803
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/UnicodeCollation.h
@@ -0,0 +1,183 @@
+/** @file

+  Unicode Collation protocol that follows the EFI 1.0 specification.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  UnicodeCollation.h

+

+**/

+

+#ifndef __UNICODE_COLLATION_H__

+#define __UNICODE_COLLATION_H__

+

+#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \

+  { \

+    0x1d85cd7f, 0xf43d, 0x11d2, {0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

+  }

+

+typedef struct _EFI_UNICODE_COLLATION_PROTOCOL   EFI_UNICODE_COLLATION_PROTOCOL;

+

+//

+// Protocol data structures and defines

+//

+#define EFI_UNICODE_BYTE_ORDER_MARK (CHAR16) (0xfeff)

+

+//

+// Protocol member functions

+//

+/**

+  Performs a case-insensitive comparison of two Null-terminated Unicode 

+  strings.

+

+  @param  This Protocol instance pointer.

+  @param  Str1 A pointer to a Null-terminated Unicode string.

+  @param  Str2 A pointer to a Null-terminated Unicode string.

+

+  @retval 0   Str1 is equivalent to Str2

+  @retval >_0 Str1 is lexically greater than Str2

+  @retval <_0 Str1 is lexically less than Str2

+

+**/

+typedef

+INTN

+(EFIAPI *EFI_UNICODE_COLLATION_STRICOLL) (

+  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,

+  IN CHAR16                                 *Str1,

+  IN CHAR16                                 *Str2

+  )

+;

+

+/**

+  Performs a case-insensitive comparison of a Null-terminated Unicode 

+  pattern string and a Null-terminated Unicode string.

+

+  @param  This    Protocol instance pointer.

+  @param  String  A pointer to a Null-terminated Unicode string.

+  @param  Pattern A pointer to a Null-terminated Unicode pattern string.

+

+  @retval TRUE    Pattern was found in String.

+  @retval FALSE   Pattern was not found in String.

+

+**/

+typedef

+BOOLEAN

+(EFIAPI *EFI_UNICODE_COLLATION_METAIMATCH) (

+  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,

+  IN CHAR16                                 *String,

+  IN CHAR16                                 *Pattern

+  )

+;

+

+/**

+  Converts all the Unicode characters in a Null-terminated Unicode string to 

+  lower case Unicode characters.

+

+  @param  This   Protocol instance pointer.

+  @param  String A pointer to a Null-terminated Unicode string.

+

+  NONE

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_UNICODE_COLLATION_STRLWR) (

+  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,

+  IN OUT CHAR16                             *Str

+  )

+;

+

+/**

+  Converts all the Unicode characters in a Null-terminated Unicode string to upper

+  case Unicode characters.

+

+  @param  This   Protocol instance pointer.

+  @param  String A pointer to a Null-terminated Unicode string.

+

+  NONE

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_UNICODE_COLLATION_STRUPR) (

+  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,

+  IN OUT CHAR16                             *Str

+  )

+;

+

+/**

+  Converts an 8.3 FAT file name in an OEM character set to a Null-terminated 

+  Unicode string.

+

+  @param  This    Protocol instance pointer.

+  @param  FatSize The size of the string Fat in bytes.

+  @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file

+                  name using an OEM character set.

+  @param  String  A pointer to a Null-terminated Unicode string. The string must

+                  be preallocated to hold FatSize Unicode characters.

+

+  NONE

+

+**/

+typedef

+VOID

+(EFIAPI *EFI_UNICODE_COLLATION_FATTOSTR) (

+  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,

+  IN UINTN                                  FatSize,

+  IN CHAR8                                  *Fat,

+  OUT CHAR16                                *String

+  )

+;

+

+/**

+  Converts a Null-terminated Unicode string to legal characters in a FAT 

+  filename using an OEM character set. 

+

+  @param  This    Protocol instance pointer.

+  @param  String  A pointer to a Null-terminated Unicode string. The string must

+                  be preallocated to hold FatSize Unicode characters.

+  @param  FatSize The size of the string Fat in bytes.

+  @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file

+                  name using an OEM character set.

+

+  @retval TRUE    Fat is a Long File Name

+  @retval FALSE   Fat is an 8.3 file name

+

+**/

+typedef

+BOOLEAN

+(EFIAPI *EFI_UNICODE_COLLATION_STRTOFAT) (

+  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,

+  IN CHAR16                                 *String,

+  IN UINTN                                  FatSize,

+  OUT CHAR8                                 *Fat

+  )

+;

+

+struct _EFI_UNICODE_COLLATION_PROTOCOL {

+  //

+  // general

+  //

+  EFI_UNICODE_COLLATION_STRICOLL    StriColl;

+  EFI_UNICODE_COLLATION_METAIMATCH  MetaiMatch;

+  EFI_UNICODE_COLLATION_STRLWR      StrLwr;

+  EFI_UNICODE_COLLATION_STRUPR      StrUpr;

+

+  //

+  // for supporting fat volumes

+  //

+  EFI_UNICODE_COLLATION_FATTOSTR    FatToStr;

+  EFI_UNICODE_COLLATION_STRTOFAT    StrToFat;

+

+  CHAR8                             *SupportedLanguages;

+};

+

+extern EFI_GUID gEfiUnicodeCollationProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/Usb2HostController.h b/edk2/MdePkg/Include/Protocol/Usb2HostController.h
new file mode 100644
index 0000000..5326d5b
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/Usb2HostController.h
@@ -0,0 +1,497 @@
+/** @file

+  EFI_USB2_HC_PROTOCOL as defined in UEFI 2.0.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  Usb2HostController.h

+

+**/

+

+#ifndef _USB2_HOSTCONTROLLER_H_

+#define _USB2_HOSTCONTROLLER_H_

+

+#define EFI_USB2_HC_PROTOCOL_GUID \

+  { \

+    0x3e745226, 0x9818, 0x45b6, {0xa2, 0xac, 0xd7, 0xcd, 0xe, 0x8b, 0xa2, 0xbc } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_USB2_HC_PROTOCOL EFI_USB2_HC_PROTOCOL;

+

+#define EFI_USB_SPEED_FULL      0x0000  // 12 Mb/s, USB 1.1 OHCI and UHCI HC.

+#define EFI_USB_SPEED_LOW       0x0001  // 1 Mb/s, USB 1.1 OHCI and UHCI HC.

+#define EFI_USB_SPEED_HIGH      0x0002  // 480 Mb/s, USB 2.0 EHCI HC.

+

+typedef struct {

+  UINT8      TranslatorHubAddress;

+  UINT8      TranslatorPortNumber;

+} EFI_USB2_HC_TRANSACTION_TRANSLATOR;

+

+//

+// Protocol definitions

+//

+

+/**

+  Retrieves the Host Controller capabilities.

+

+  @param  This           A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  MaxSpeed       Host controller data transfer speed.

+  @param  PortNumber     Number of the root hub ports.

+  @param  Is64BitCapable TRUE if controller supports 64-bit memory addressing,

+                         FALSE otherwise.

+

+  @retval EFI_SUCCESS           The host controller capabilities were retrieved successfully.

+  @retval EFI_INVALID_PARAMETER One of the input args was NULL.

+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to

+                                retrieve the capabilities.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_CAPABILITY) (

+  IN  EFI_USB2_HC_PROTOCOL  *This,

+  OUT UINT8                 *MaxSpeed,

+  OUT UINT8                 *PortNumber,

+  OUT UINT8                 *Is64BitCapable

+  )

+;

+

+/**

+  Provides software reset for the USB host controller.

+

+  @param  This       A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  Attributes A bit mask of the reset operation to perform.

+

+  @retval EFI_SUCCESS           The reset operation succeeded.

+  @retval EFI_INVALID_PARAMETER Attributes is not valid.

+  @retval EFI_UNSUPPORTED       The type of reset specified by Attributes is not currently

+                                supported by the host controller hardware.

+  @retval EFI_ACCESS_DENIED     Reset operation is rejected due to the debug port being configured

+                                and active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or

+                                EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Attributes can be used to

+                                perform reset operation for this host controller.

+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to

+                                retrieve the capabilities.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_RESET) (

+  IN EFI_USB2_HC_PROTOCOL   *This,

+  IN UINT16                 Attributes

+  )

+;

+

+/**

+  Retrieves current state of the USB host controller.

+

+  @param  This  A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  State A pointer to the EFI_USB_HC_STATE data structure that

+                indicates current state of the USB host controller.

+

+  @retval EFI_SUCCESS           The state information of the host controller was returned in State.

+  @retval EFI_INVALID_PARAMETER State is NULL.

+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to retrieve the

+                                host controller¡¯s current state.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_STATE) (

+  IN  EFI_USB2_HC_PROTOCOL    *This,

+  OUT EFI_USB_HC_STATE        *State

+  )

+;  

+

+/**

+  Sets the USB host controller to a specific state.

+

+  @param  This  A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  State Indicates the state of the host controller that will be set.

+

+  @retval EFI_SUCCESS           The USB host controller was successfully placed in the state

+                                specified by State.

+  @retval EFI_INVALID_PARAMETER State is not valid.

+  @retval EFI_DEVICE_ERROR      Failed to set the state specified by State due to device error.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_SET_STATE) (

+  IN EFI_USB2_HC_PROTOCOL    *This,

+  IN EFI_USB_HC_STATE        State

+  )

+;

+

+/**

+  Submits control transfer to a target USB device.

+

+  @param  This                A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  DeviceAddress       Represents the address of the target device on the USB.

+  @param  DeviceSpeed         Indicates device speed.

+  @param  MaximumPacketLength Indicates the maximum packet size that the default control transfer

+                              endpoint is capable of sending or receiving.

+  @param  Request             A pointer to the USB device request that will be sent to the USB device.

+  @param  TransferDirection   Specifies the data direction for the transfer. There are three values

+                              available, EfiUsbDataIn, EfiUsbDataOut and EfiUsbNoData.

+  @param  Data                A pointer to the buffer of data that will be transmitted to USB device or

+                              received from USB device.

+  @param  DataLength          On input, indicates the size, in bytes, of the data buffer specified by Data.

+                              On output, indicates the amount of data actually transferred.

+  @param  Translator          A pointer to the transaction translator data.

+  @param  TimeOut             Indicates the maximum time, in milliseconds, which the transfer is

+                              allowed to complete.

+  @param  TransferResult      A pointer to the detailed result information generated by this control

+                              transfer.

+

+  @retval EFI_SUCCESS           The control transfer was completed successfully.

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The control transfer could not be completed due to a lack of resources.

+  @retval EFI_TIMEOUT           The control transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The control transfer failed due to host controller or device error.

+                                Caller should check TransferResult for detailed error information.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER) (

+  IN     EFI_USB2_HC_PROTOCOL               *This,

+  IN     UINT8                              DeviceAddress,

+  IN     UINT8                              DeviceSpeed,

+  IN     UINTN                              MaximumPacketLength,

+  IN     EFI_USB_DEVICE_REQUEST             *Request,

+  IN     EFI_USB_DATA_DIRECTION             TransferDirection,

+  IN OUT VOID                               *Data       OPTIONAL,

+  IN OUT UINTN                              *DataLength OPTIONAL,

+  IN     UINTN                              TimeOut,

+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,

+  OUT    UINT32                             *TransferResult

+  )

+;  

+

+#define EFI_USB_MAX_BULK_BUFFER_NUM 10

+

+/**

+  Submits bulk transfer to a bulk endpoint of a USB device.

+

+  @param  This                A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  DeviceAddress       Represents the address of the target device on the USB.

+  @param  EndPointAddress     The combination of an endpoint number and an endpoint direction of the

+                              target USB device.

+  @param  DeviceSpeed         Indicates device speed.

+  @param  MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of

+                              sending or receiving.

+  @param  DataBuffersNumber   Number of data buffers prepared for the transfer.

+  @param  Data                Array of pointers to the buffers of data that will be transmitted to USB

+                              device or received from USB device.

+  @param  DataLength          When input, indicates the size, in bytes, of the data buffers specified by

+                              Data. When output, indicates the actually transferred data size.

+  @param  DataToggle          A pointer to the data toggle value.

+  @param  Translator          A pointer to the transaction translator data.

+  @param  TimeOut             Indicates the maximum time, in milliseconds, which the transfer is

+                              allowed to complete.

+  @param  TransferResult      A pointer to the detailed result information of the bulk transfer.

+

+  @retval EFI_SUCCESS           The bulk transfer was completed successfully.

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The bulk transfer could not be submitted due to a lack of resources.

+  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.

+                                Caller should check TransferResult for detailed error information.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_BULK_TRANSFER) (

+  IN     EFI_USB2_HC_PROTOCOL               *This,

+  IN     UINT8                              DeviceAddress,

+  IN     UINT8                              EndPointAddress,

+  IN     UINT8                              DeviceSpeed,

+  IN     UINTN                              MaximumPacketLength,

+  IN     UINT8                              DataBuffersNumber,

+  IN OUT VOID                               *Data[EFI_USB_MAX_BULK_BUFFER_NUM],

+  IN OUT UINTN                              *DataLength,

+  IN OUT UINT8                              *DataToggle,

+  IN     UINTN                              TimeOut,

+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,

+  OUT    UINT32                             *TransferResult

+  )

+;

+

+/**

+  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.

+

+  @param  This                A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  DeviceAddress       Represents the address of the target device on the USB.

+  @param  EndPointAddress     The combination of an endpoint number and an endpoint direction of the

+                              target USB device.

+  @param  DeviceSpeed         Indicates device speed.

+  @param  MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of

+                              sending or receiving.

+  @param  IsNewTransfer       If TRUE, an asynchronous interrupt pipe is built between the host and the

+                              target interrupt endpoint. If FALSE, the specified asynchronous interrupt

+                              pipe is canceled. If TRUE, and an interrupt transfer exists for the target

+                              end point, then EFI_INVALID_PARAMETER is returned.

+  @param  DataToggle          A pointer to the data toggle value.

+  @param  PollingInterval     Indicates the interval, in milliseconds, that the asynchronous interrupt

+                              transfer is polled.

+  @param  DataLength          Indicates the length of data to be received at the rate specified by

+                              PollingInterval from the target asynchronous interrupt endpoint.

+  @param  CallBackFunction    The Callback function. This function is called at the rate specified by

+                              PollingInterval.

+  @param  Context             The context that is passed to the CallBackFunction. This is an

+                              optional parameter and may be NULL.

+

+  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully

+                                submitted or canceled.

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER) (

+  IN     EFI_USB2_HC_PROTOCOL                                *This,

+  IN     UINT8                                               DeviceAddress,

+  IN     UINT8                                               EndPointAddress,

+  IN     UINT8                                               DeviceSpeed,

+  IN     UINTN                                               MaxiumPacketLength,

+  IN     BOOLEAN                                             IsNewTransfer,

+  IN OUT UINT8                                               *DataToggle,

+  IN     UINTN                                               PollingInterval  OPTIONAL,

+  IN     UINTN                                               DataLength       OPTIONAL,

+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK                     CallBackFunction OPTIONAL,

+  IN     VOID                                                *Context         OPTIONAL

+  )

+;

+

+/**

+  Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.

+

+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB.

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint direction of the

+                                target USB device.

+  @param  DeviceSpeed           Indicates device speed.

+  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint is capable of

+                                sending or receiving.

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB device or

+                                received from USB device.

+  @param  DataLength            On input, the size, in bytes, of the data buffer specified by Data. On

+                                output, the number of bytes transferred.

+  @param  DataToggle            A pointer to the data toggle value.

+  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer is

+                                allowed to complete.

+  @param  TransferResult        A pointer to the detailed result information from the synchronous

+                                interrupt transfer.

+

+  @retval EFI_SUCCESS           The synchronous interrupt transfer was completed successfully.

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The synchronous interrupt transfer could not be submitted due to a lack of resources.

+  @retval EFI_TIMEOUT           The synchronous interrupt transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The synchronous interrupt transfer failed due to host controller or device error.

+                                Caller should check TransferResult for detailed error information.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER) (

+  IN     EFI_USB2_HC_PROTOCOL   *This,

+  IN     UINT8                  DeviceAddress,

+  IN     UINT8                  EndPointAddress,

+  IN     UINT8                  DeviceSpeed,

+  IN     UINTN                  MaximumPacketLength,

+  IN OUT VOID                   *Data,

+  IN OUT UINTN                  *DataLength,

+  IN OUT UINT8                  *DataToggle,

+  IN     UINTN                  TimeOut,

+  OUT    UINT32                 *TransferResult

+  )

+;

+

+#define EFI_USB_MAX_ISO_BUFFER_NUM  7

+#define EFI_USB_MAX_ISO_BUFFER_NUM1 2

+

+/**

+  Submits isochronous transfer to an isochronous endpoint of a USB device.

+

+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB.

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint direction of the

+                                target USB device.

+  @param  DeviceSpeed           Indicates device speed.

+  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint is capable of

+                                sending or receiving.

+  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.

+  @param  Data                  Array of pointers to the buffers of data that will be transmitted to USB

+                                device or received from USB device.

+  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received from

+                                the USB device.

+  @param  Translator            A pointer to the transaction translator data.

+  @param  TransferResult        A pointer to the detailed result information of the isochronous transfer.

+

+  @retval EFI_SUCCESS           The isochronous transfer was completed successfully.

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The isochronous transfer could not be submitted due to a lack of resources.

+  @retval EFI_TIMEOUT           The isochronous transfer cannot be completed within the one USB frame time.

+  @retval EFI_DEVICE_ERROR      The isochronous transfer failed due to host controller or device error.

+                                Caller should check TransferResult for detailed error information.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER) (

+  IN     EFI_USB2_HC_PROTOCOL               *This,

+  IN     UINT8                              DeviceAddress,

+  IN     UINT8                              EndPointAddress,

+  IN     UINT8                              DeviceSpeed,

+  IN     UINTN                              MaximumPacketLength,

+  IN     UINT8                              DataBuffersNumber,

+  IN OUT VOID                               *Data[EFI_USB_MAX_ISO_BUFFER_NUM],

+  IN     UINTN                              DataLength,

+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,

+  OUT    UINT32                             *TransferResult

+  )

+;

+

+/**

+  Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device.

+

+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB.

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint direction of the

+                                target USB device.

+  @param  DeviceSpeed           Indicates device speed.

+  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint is capable of

+                                sending or receiving.

+  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.

+  @param  Data                  Array of pointers to the buffers of data that will be transmitted to USB

+                                device or received from USB device.

+  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received from

+                                the USB device.

+  @param  Translator            A pointer to the transaction translator data.

+  @param  IsochronousCallback   The Callback function. This function is called if the requested

+                                isochronous transfer is completed.

+  @param  Context               Data passed to the IsochronousCallback function. This is an

+                                optional parameter and may be NULL.

+

+  @retval EFI_SUCCESS           The asynchronous isochronous transfer request has been successfully

+                                submitted or canceled.

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The asynchronous isochronous transfer could not be submitted due to

+                                a lack of resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER) (

+  IN     EFI_USB2_HC_PROTOCOL               *This,

+  IN     UINT8                              DeviceAddress,

+  IN     UINT8                              EndPointAddress,

+  IN     UINT8                              DeviceSpeed,

+  IN     UINTN                              MaximumPacketLength,

+  IN     UINT8                              DataBuffersNumber,

+  IN OUT VOID                               *Data[EFI_USB_MAX_ISO_BUFFER_NUM],

+  IN     UINTN                              DataLength,

+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,

+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    IsochronousCallBack,

+  IN     VOID                               *Context OPTIONAL

+  )

+;

+

+/**

+  Retrieves the current status of a USB root hub port.

+

+  @param  This       A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  PortNumber Specifies the root hub port from which the status is to be retrieved.

+                     This value is zero based.

+  @param  PortStatus A pointer to the current port status bits and port status change bits.

+

+  @retval EFI_SUCCESS           The status of the USB root hub port specified by PortNumber

+                                was returned in PortStatus.

+  @retval EFI_INVALID_PARAMETER PortNumber is invalid.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS) (

+  IN EFI_USB2_HC_PROTOCOL    *This,

+  IN  UINT8                  PortNumber,

+  OUT EFI_USB_PORT_STATUS    *PortStatus

+  )

+;  

+

+/**

+  Sets a feature for the specified root hub port.

+

+  @param  This        A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  PortNumber  Specifies the root hub port whose feature is requested to be set. This

+                      value is zero based.

+  @param  PortFeature Indicates the feature selector associated with the feature set request.

+

+  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the USB

+                                root hub port specified by PortNumber.

+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE) (

+  IN EFI_USB2_HC_PROTOCOL    *This,

+  IN UINT8                   PortNumber,

+  IN EFI_USB_PORT_FEATURE    PortFeature

+  )

+;  

+

+/**

+  Clears a feature for the specified root hub port.

+

+  @param  This        A pointer to the EFI_USB2_HC_PROTOCOL instance.

+  @param  PortNumber  Specifies the root hub port whose feature is requested to be cleared. This

+                      value is zero based.

+  @param  PortFeature Indicates the feature selector associated with the feature clear request.

+

+  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared for the USB

+                                root hub port specified by PortNumber.

+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE) (

+  IN EFI_USB2_HC_PROTOCOL    *This,

+  IN UINT8                   PortNumber,

+  IN EFI_USB_PORT_FEATURE    PortFeature

+  )

+;  

+

+struct _EFI_USB2_HC_PROTOCOL {

+  EFI_USB2_HC_PROTOCOL_GET_CAPABILITY              GetCapability;

+  EFI_USB2_HC_PROTOCOL_RESET                       Reset;

+  EFI_USB2_HC_PROTOCOL_GET_STATE                   GetState;

+  EFI_USB2_HC_PROTOCOL_SET_STATE                   SetState;

+  EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER            ControlTransfer;

+  EFI_USB2_HC_PROTOCOL_BULK_TRANSFER               BulkTransfer;

+  EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER    AsyncInterruptTransfer;

+  EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER     SyncInterruptTransfer;

+  EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER        IsochronousTransfer;

+  EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER  AsyncIsochronousTransfer;

+  EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS     GetRootHubPortStatus;

+  EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE    SetRootHubPortFeature;

+  EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE  ClearRootHubPortFeature;

+  UINT16                                           MajorRevision;

+  UINT16                                           MinorRevision;

+};

+

+extern EFI_GUID gEfiUsb2HcProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/UsbHostController.h b/edk2/MdePkg/Include/Protocol/UsbHostController.h
new file mode 100644
index 0000000..f816d73
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/UsbHostController.h
@@ -0,0 +1,446 @@
+/** @file

+  EFI_USB_HC_PROTOCOL as defined in EFI 1.10.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  UsbHostController.h

+

+**/

+

+#ifndef _USB_HOSTCONTROLLER_H_

+#define _USB_HOSTCONTROLLER_H_

+

+#define EFI_USB_HC_PROTOCOL_GUID \

+  { \

+    0xf5089266, 0x1aa0, 0x4953, {0x97, 0xd8, 0x56, 0x2f, 0x8a, 0x73, 0xb5, 0x19 } \

+  }

+

+//

+// Forward reference for pure ANSI compatability

+//

+typedef struct _EFI_USB_HC_PROTOCOL EFI_USB_HC_PROTOCOL;

+

+//

+// Protocol definitions

+//

+

+/**                                                                 

+  Provides software reset for the USB host controller.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  Attributes            A bit mask of the reset operation to perform.

+                                

+  @retval EFI_SUCCESS           The reset operation succeeded.

+  @retval EFI_UNSUPPORTED       The type of reset specified by Attributes is not currently supported

+                                by the host controller hardware.                                    

+  @retval EFI_INVALID_PARAMETER Attributes is not valid.

+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to perform the reset operation.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_RESET) (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN UINT16                  Attributes

+  );

+

+/**                                                                 

+  Retrieves current state of the USB host controller.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  State                 A pointer to the EFI_USB_HC_STATE data structure that

+                                indicates current state of the USB host controller.  

+                                

+  @retval EFI_SUCCESS           The state information of the host controller was returned in State.

+  @retval EFI_INVALID_PARAMETER State is NULL.

+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to retrieve the host controller¡¯s

+                                current state.                                                                 

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_GET_STATE) (

+  IN  EFI_USB_HC_PROTOCOL    *This,

+  OUT EFI_USB_HC_STATE       *State

+  );

+

+/**                                                                 

+  Sets the USB host controller to a specific state.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  State                 Indicates the state of the host controller that will be set.                                

+                                

+  @retval EFI_SUCCESS           The USB host controller was successfully placed in the state specified by

+                                State.                                                                   

+  @retval EFI_INVALID_PARAMETER State is NULL.

+  @retval EFI_DEVICE_ERROR      Failed to set the state specified by State due to device error.                                

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_SET_STATE) (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN EFI_USB_HC_STATE        State

+  );

+

+/**                                                                 

+  Submits control transfer to a target USB device.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB, which is

+                                assigned during USB enumeration.                                

+  @param  IsSlowDevice          Indicates whether the target device is slow device or full-speed

+                                device.                                                         

+  @param  MaximumPacketLength   Indicates the maximum packet size that the default control 

+                                transfer endpoint is capable of sending or receiving.     

+  @param  Request               A pointer to the USB device request that will be sent to the USB

+                                device.

+  @param  TransferDirection     Specifies the data direction for the transfer.  

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB  

+                                device or received from USB device.                            

+  @param  DataLength            On input, indicates the size, in bytes, of the data buffer specified

+                                by Data. On output, indicates the amount of data actually           

+                                transferred.                                                        

+  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer

+                                is allowed to complete.                                        

+  @param  TransferResult        A pointer to the detailed result information generated by this  

+                                control transfer.

+                                

+  @retval EFI_SUCCESS           The control transfer was completed successfully.

+  @retval EFI_OUT_OF_RESOURCES  The control transfer could not be completed due to a lack of resources.                                

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_TIMEOUT           The control transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The control transfer failed due to host controller or device error.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_CONTROL_TRANSFER) (

+  IN     EFI_USB_HC_PROTOCOL       *This,

+  IN     UINT8                     DeviceAddress,

+  IN     BOOLEAN                   IsSlowDevice,

+  IN     UINT8                     MaximumPacketLength,

+  IN     EFI_USB_DEVICE_REQUEST    *Request,

+  IN     EFI_USB_DATA_DIRECTION    TransferDirection,

+  IN OUT VOID                      *Data       OPTIONAL,

+  IN OUT UINTN                     *DataLength OPTIONAL,

+  IN     UINTN                     TimeOut,

+  OUT    UINT32                    *TransferResult

+  );

+

+/**                                                                 

+  Submits bulk transfer to a bulk endpoint of a USB device.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB, which is

+                                assigned during USB enumeration.                                

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint

+                                direction of the target USB device.                  

+  @param  MaximumPacketLength   Indicates the maximum packet size that the default control 

+                                transfer endpoint is capable of sending or receiving.     

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB  

+                                device or received from USB device.                            

+  @param  DataLength            On input, indicates the size, in bytes, of the data buffer specified

+                                by Data. On output, indicates the amount of data actually           

+                                transferred.             

+  @param  DataToggle            A pointer to the data toggle value.                                                                           

+  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer

+                                is allowed to complete.                                        

+  @param  TransferResult        A pointer to the detailed result information of the bulk transfer.

+                                

+  @retval EFI_SUCCESS           The bulk transfer was completed successfully.

+  @retval EFI_OUT_OF_RESOURCES  The bulk transfer could not be completed due to a lack of resources.                                

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_BULK_TRANSFER) (

+  IN     EFI_USB_HC_PROTOCOL    *This,

+  IN     UINT8                  DeviceAddress,

+  IN     UINT8                  EndPointAddress,

+  IN     UINT8                  MaximumPacketLength,

+  IN OUT VOID                   *Data,

+  IN OUT UINTN                  *DataLength,

+  IN OUT UINT8                  *DataToggle,

+  IN     UINTN                  TimeOut,

+  OUT    UINT32                 *TransferResult

+  );

+

+/**                                                                 

+  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB, which is

+                                assigned during USB enumeration.                                

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint

+                                direction of the target USB device.   

+  @param  IsSlowDevice          Indicates whether the target device is slow device or full-speed

+                                device.                                                                          

+  @param  MaximumPacketLength   Indicates the maximum packet size that the default control 

+                                transfer endpoint is capable of sending or receiving.     

+  @param  IsNewTransfer         If TRUE, an asynchronous interrupt pipe is built between the host                       

+                                and the target interrupt endpoint. If FALSE, the specified       

+  

+  @param  DataToggle            A pointer to the data toggle value.      

+  @param  PollingInterval       Indicates the interval, in milliseconds, that the asynchronous

+                                interrupt transfer is polled.                                                                                                      asynchronous interrupt pipe is canceled.                         

+  @param  DataLength            Indicates the length of data to be received at the rate specified by

+                                PollingInterval from the target asynchronous interrupt              

+                                endpoint.                                                             

+  @param  CallBackFunction      The Callback function.                                

+  @param  Context               The context that is passed to the CallBackFunction.

+                                

+  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully

+                                submitted or canceled.    

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.                                

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER) (

+  IN     EFI_USB_HC_PROTOCOL                                 *This,

+  IN     UINT8                                               DeviceAddress,

+  IN     UINT8                                               EndPointAddress,

+  IN     BOOLEAN                                             IsSlowDevice,

+  IN     UINT8                                               MaxiumPacketLength,

+  IN     BOOLEAN                                             IsNewTransfer,

+  IN OUT UINT8                                               *DataToggle,

+  IN     UINTN                                               PollingInterval  OPTIONAL,

+  IN     UINTN                                               DataLength       OPTIONAL,

+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK                     CallBackFunction OPTIONAL,

+  IN     VOID                                                *Context         OPTIONAL

+  );

+

+/**                                                                 

+  Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB, which is

+                                assigned during USB enumeration.                                

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint

+                                direction of the target USB device.   

+  @param  IsSlowDevice          Indicates whether the target device is slow device or full-speed

+                                device.                                                                          

+  @param  MaximumPacketLength   Indicates the maximum packet size that the default control 

+                                transfer endpoint is capable of sending or receiving.       

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                                                                                            asynchronous interrupt pipe is canceled.                         

+  @param  DataLength            On input, the size, in bytes, of the data buffer specified by Data.

+                                On output, the number of bytes transferred.                          

+  @param  DataToggle            A pointer to the data toggle value.                                

+  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer    

+                                is allowed to complete.                                            

+  @param  TransferResult        A pointer to the detailed result information from the synchronous

+                                interrupt transfer.

+                                

+  @retval EFI_SUCCESS           The synchronous interrupt transfer was completed successfully.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.                                  

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_TIMEOUT           The synchronous interrupt transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The synchronous interrupt transfer failed due to host controller or device error.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER) (

+  IN     EFI_USB_HC_PROTOCOL    *This,

+  IN     UINT8                  DeviceAddress,

+  IN     UINT8                  EndPointAddress,

+  IN     BOOLEAN                IsSlowDevice,

+  IN     UINT8                  MaximumPacketLength,

+  IN OUT VOID                   *Data,

+  IN OUT UINTN                  *DataLength,

+  IN OUT UINT8                  *DataToggle,

+  IN     UINTN                  TimeOut,

+  OUT    UINT32                 *TransferResult

+  );

+

+/**                                                                 

+  Submits isochronous transfer to an isochronous endpoint of a USB device.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB, which is

+                                assigned during USB enumeration.                                

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint

+                                direction of the target USB device.                  

+  @param  MaximumPacketLength   Indicates the maximum packet size that the default control 

+                                transfer endpoint is capable of sending or receiving.       

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                                                                                            asynchronous interrupt pipe is canceled.                         

+  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received

+                                from the USB device.                                                 

+  @param  TransferResult        A pointer to the detailed result information from the isochronous

+                                transfer.

+                                

+  @retval EFI_SUCCESS           The isochronous transfer was completed successfully.

+  @retval EFI_OUT_OF_RESOURCES  The isochronous could not be completed due to a lack of resources.                                  

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+  @retval EFI_TIMEOUT           The isochronous transfer failed due to timeout.

+  @retval EFI_DEVICE_ERROR      The isochronous transfer failed due to host controller or device error.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_ISOCHRONOUS_TRANSFER) (

+  IN     EFI_USB_HC_PROTOCOL    *This,

+  IN     UINT8                  DeviceAddress,

+  IN     UINT8                  EndPointAddress,

+  IN     UINT8                  MaximumPacketLength,

+  IN OUT VOID                   *Data,

+  IN     UINTN                  DataLength,

+  OUT    UINT32                 *TransferResult

+  );

+

+/**                                                                 

+  Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  DeviceAddress         Represents the address of the target device on the USB, which is

+                                assigned during USB enumeration.                                

+  @param  EndPointAddress       The combination of an endpoint number and an endpoint

+                                direction of the target USB device.                  

+  @param  MaximumPacketLength   Indicates the maximum packet size that the default control 

+                                transfer endpoint is capable of sending or receiving.       

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                                                                                            asynchronous interrupt pipe is canceled.                         

+  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received

+                                from the USB device.                                                 

+  @param  IsochronousCallback   The Callback function.

+  @param  Context               Data passed to the IsochronousCallback function. This is

+                                an optional parameter and may be NULL.

+                                

+  @retval EFI_SUCCESS           The asynchronous isochronous transfer was completed successfully.

+  @retval EFI_OUT_OF_RESOURCES  The asynchronous isochronous could not be completed due to a lack of resources.                                  

+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER) (

+  IN     EFI_USB_HC_PROTOCOL                *This,

+  IN     UINT8                              DeviceAddress,

+  IN     UINT8                              EndPointAddress,

+  IN     UINT8                              MaximumPacketLength,

+  IN OUT VOID                               *Data,

+  IN     UINTN                              DataLength,

+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    IsochronousCallBack,

+  IN     VOID                               *Context OPTIONAL

+  );

+

+/**                                                                 

+  Retrieves the number of root hub ports.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  PortNumber            A pointer to the number of the root hub ports.                                

+                                

+  @retval EFI_SUCCESS           The port number was retrieved successfully.

+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to retrieve the port number.

+  @retval EFI_INVALID_PARAMETER PortNumber is NULL.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_NUMBER) (

+  IN EFI_USB_HC_PROTOCOL    *This,

+  OUT UINT8                 *PortNumber

+  );

+

+/**                                                                 

+  Retrieves the current status of a USB root hub port.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  PortNumber            Specifies the root hub port from which the status is to be retrieved.

+                                This value is zero based.

+  @param  PortStatus            A pointer to the current port status bits and port status change bits.                                

+                                

+  @retval EFI_SUCCESS           The status of the USB root hub port specified by PortNumber

+                                was returned in PortStatus.                                

+  @retval EFI_INVALID_PARAMETER PortNumber is invalid.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS) (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN  UINT8                  PortNumber,

+  OUT EFI_USB_PORT_STATUS    *PortStatus

+  );

+

+/**                                                                 

+  Sets a feature for the specified root hub port.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  PortNumber            Specifies the root hub port from which the status is to be retrieved.

+                                This value is zero based.

+  @param  PortFeature           Indicates the feature selector associated with the feature set

+                                request.

+                                

+  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the USB

+                                root hub port specified by PortNumber.                  

+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE) (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN UINT8                   PortNumber,

+  IN EFI_USB_PORT_FEATURE    PortFeature

+  );

+

+/**                                                                 

+  Clears a feature for the specified root hub port.

+    

+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.

+  @param  PortNumber            Specifies the root hub port from which the status is to be cleared.

+                                This value is zero based.

+  @param  PortFeature           Indicates the feature selector associated with the feature clear

+                                request.

+                                

+  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared for the USB

+                                root hub port specified by PortNumber.                  

+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.

+                                

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE) (

+  IN EFI_USB_HC_PROTOCOL     *This,

+  IN UINT8                   PortNumber,

+  IN EFI_USB_PORT_FEATURE    PortFeature

+  );

+

+struct _EFI_USB_HC_PROTOCOL {

+  EFI_USB_HC_PROTOCOL_RESET                       Reset;

+  EFI_USB_HC_PROTOCOL_GET_STATE                   GetState;

+  EFI_USB_HC_PROTOCOL_SET_STATE                   SetState;

+  EFI_USB_HC_PROTOCOL_CONTROL_TRANSFER            ControlTransfer;

+  EFI_USB_HC_PROTOCOL_BULK_TRANSFER               BulkTransfer;

+  EFI_USB_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER    AsyncInterruptTransfer;

+  EFI_USB_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER     SyncInterruptTransfer;

+  EFI_USB_HC_PROTOCOL_ISOCHRONOUS_TRANSFER        IsochronousTransfer;

+  EFI_USB_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER  AsyncIsochronousTransfer;

+  EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_NUMBER     GetRootHubPortNumber;

+  EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS     GetRootHubPortStatus;

+  EFI_USB_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE    SetRootHubPortFeature;

+  EFI_USB_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE  ClearRootHubPortFeature;

+  UINT16                                          MajorRevision;

+  UINT16                                          MinorRevision;

+};

+

+extern EFI_GUID gEfiUsbHcProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/Protocol/UsbIo.h b/edk2/MdePkg/Include/Protocol/UsbIo.h
new file mode 100644
index 0000000..30309e3
--- /dev/null
+++ b/edk2/MdePkg/Include/Protocol/UsbIo.h
@@ -0,0 +1,418 @@
+/** @file

+  EFI Usb I/O Protocol

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  UsbIo.h

+

+**/

+

+#ifndef __USB_IO_H__

+#define __USB_IO_H__

+

+//

+// Global ID for the USB I/O Protocol

+//

+#define EFI_USB_IO_PROTOCOL_GUID \

+  { \

+    0x2B2F68D6, 0x0CD2, 0x44cf, {0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \

+  }

+

+typedef struct _EFI_USB_IO_PROTOCOL   EFI_USB_IO_PROTOCOL;

+

+/**                                                                 

+  Async USB transfer callback routine.

+    

+  @param  Data                  Data received or sent via the USB Asynchronous Transfer, if the

+                                transfer completed successfully.                               

+  @param  DataLength            The length of Data received or sent via the Asynchronous

+                                Transfer, if transfer successfully completes.                                           

+  @param  Context               Data passed from UsbAsyncInterruptTransfer() request.

+  @param  Status                Indicates the result of the asynchronous transfer.

+                                

+  @retval EFI_SUCCESS           The asynchronous USB transfer request has been successfully executed.  

+  @retval EFI_DEVICE_ERROR      The asynchronous USB transfer request failed.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ASYNC_USB_TRANSFER_CALLBACK) (

+  IN VOID         *Data,

+  IN UINTN        DataLength,

+  IN VOID         *Context,

+  IN UINT32       Status

+  );

+

+//

+// Prototype for EFI USB I/O protocol

+//

+

+

+/**                                                                 

+  This function is used to manage a USB device with a control transfer pipe. A control transfer is

+  typically used to perform device initialization and configuration.                              

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                

+  @param  Request               A pointer to the USB device request that will be sent to the USB

+                                device.                                                         

+  @param  Direction             Indicates the data direction.

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                            

+  @param  Timeout               Indicating the transfer should be completed within this time frame.

+                                The units are in milliseconds.                                       

+  @param  DataLength            The size, in bytes, of the data buffer specified by Data.

+  @param  Status                A pointer to the result of the USB transfer.

+                                

+  @retval EFI_SUCCESS           The control transfer has been successfully executed.

+  @retval EFI_DEVICE_ERROR      The transfer failed. The transfer status is returned in Status.

+  @retval EFI_INVALID_PARAMETE  One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_TIMEOUT           The control transfer fails due to timeout.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_CONTROL_TRANSFER) (

+  IN EFI_USB_IO_PROTOCOL                        *This,

+  IN EFI_USB_DEVICE_REQUEST                     *Request,

+  IN EFI_USB_DATA_DIRECTION                     Direction,

+  IN UINT32                                     Timeout,

+  IN OUT VOID                                   *Data OPTIONAL,

+  IN UINTN                                      DataLength  OPTIONAL,

+  OUT UINT32                                    *Status

+  );

+

+/**                                                                 

+  This function is used to manage a USB device with the bulk transfer pipe. Bulk Transfers are

+  typically used to transfer large amounts of data to/from USB devices.

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                

+  @param  DeviceEndpoint        A pointer to the USB device request that will be sent to the USB

+                                device.                                                         

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                            

+  @param  DataLength            The size, in bytes, of the data buffer specified by Data.

+  @param  Timeout               Indicating the transfer should be completed within this time frame.

+                                The units are in milliseconds.                                           

+  @param  Status                This parameter indicates the USB transfer status.

+                                

+  @retval EFI_SUCCESS           The bulk transfer has been successfully executed.

+  @retval EFI_DEVICE_ERROR      The transfer failed. The transfer status is returned in Status.

+  @retval EFI_INVALID_PARAMETE  One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.

+  @retval EFI_TIMEOUT           The control transfer fails due to timeout.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_BULK_TRANSFER) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  IN UINT8                          DeviceEndpoint,

+  IN OUT VOID                       *Data,

+  IN OUT UINTN                      *DataLength,

+  IN UINTN                          Timeout,

+  OUT UINT32                        *Status

+  );

+

+/**                                                                 

+  This function is used to manage a USB device with an interrupt transfer pipe. An Asynchronous   

+  Interrupt Transfer is typically used to query a device¡¯s status at a fixed rate. For example,  

+  keyboard, mouse, and hub devices use this type of transfer to query their interrupt endpoints at

+  a fixed rate.                                                                                   

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                

+  @param  DeviceEndpoint        A pointer to the USB device request that will be sent to the USB

+                                device.                                                         

+  @param  IsNewTransfer         If TRUE, a new transfer will be submitted to USB controller. If                             

+                                FALSE, the interrupt transfer is deleted from the device¡¯s interrupt

+                                transfer queue.                                                      

+  @param  PollingInterval       Indicates the periodic rate, in milliseconds, that the transfer is to be                        

+                                executed.                                                                 

+  @param  DataLength            Specifies the length, in bytes, of the data to be received from the

+                                USB device.                                                        

+  @param  Context               Data passed to the InterruptCallback function.

+  @param  InterruptCallback     The Callback function. This function is called if the asynchronous

+                                interrupt transfer is completed.

+                                

+  @retval EFI_SUCCESS           The asynchronous USB transfer request transfer has been successfully executed.

+  @retval EFI_DEVICE_ERROR      The asynchronous USB transfer request failed.   

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER) (

+  IN EFI_USB_IO_PROTOCOL                                 *This,

+  IN UINT8                                               DeviceEndpoint,

+  IN BOOLEAN                                             IsNewTransfer,

+  IN UINTN                                               PollingInterval    OPTIONAL,

+  IN UINTN                                               DataLength         OPTIONAL,

+  IN EFI_ASYNC_USB_TRANSFER_CALLBACK                     InterruptCallBack  OPTIONAL,

+  IN VOID                                                *Context OPTIONAL

+  );

+

+/**                                                                 

+  This function is used to manage a USB device with an interrupt transfer pipe.

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                

+  @param  DeviceEndpoint        A pointer to the USB device request that will be sent to the USB

+                                device.                                                         

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                            

+  @param  DataLength            On input, then size, in bytes, of the buffer Data. On output, the

+                                amount of data actually transferred.                             

+  @param  Timeout               The time out, in seconds, for this transfer.

+  @param  Status                This parameter indicates the USB transfer status.                                

+                                

+  @retval EFI_SUCCESS           The sync interrupt transfer has been successfully executed.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_DEVICE_ERROR      The sync interrupt transfer request failed.   

+  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.

+  @retval EFI_TIMEOUT           The transfer fails due to timeout.                                                       

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_SYNC_INTERRUPT_TRANSFER) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  IN     UINT8                      DeviceEndpoint,

+  IN OUT VOID                       *Data,

+  IN OUT UINTN                      *DataLength,

+  IN     UINTN                      Timeout,

+  OUT    UINT32                     *Status

+  );

+

+/**                                                                 

+  This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous

+  transfer is typically used to transfer streaming data.

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                

+  @param  DeviceEndpoint        A pointer to the USB device request that will be sent to the USB

+                                device.                                                         

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                            

+  @param  DataLength            The size, in bytes, of the data buffer specified by Data.                                         

+  @param  Status                This parameter indicates the USB transfer status.                                

+                                

+  @retval EFI_SUCCESS           The isochronous transfer has been successfully executed.

+  @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid.

+  @retval EFI_DEVICE_ERROR      The transfer failed due to the reason other than timeout, The error status

+                                is returned in Status.                                                    

+  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.

+  @retval EFI_TIMEOUT           The transfer fails due to timeout.                                                       

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_ISOCHRONOUS_TRANSFER) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  IN     UINT8                      DeviceEndpoint,

+  IN OUT VOID                       *Data,

+  IN     UINTN                      DataLength,

+  OUT    UINT32                     *Status

+  );

+

+/**                                                                 

+  This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous

+  transfer is typically used to transfer streaming data.                                      

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                

+  @param  DeviceEndpoint        A pointer to the USB device request that will be sent to the USB

+                                device.                                                         

+  @param  Data                  A pointer to the buffer of data that will be transmitted to USB

+                                device or received from USB device.                            

+  @param  DataLength            The size, in bytes, of the data buffer specified by Data.                                         

+  @param  Context               Data passed to the IsochronousCallback() function.

+  @param  IsochronousCallback   The IsochronousCallback() function.

+                                

+  @retval EFI_SUCCESS           The asynchronous isochronous transfer has been successfully submitted

+                                to the system.

+  @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER) (

+  IN EFI_USB_IO_PROTOCOL              *This,

+  IN UINT8                            DeviceEndpoint,

+  IN OUT VOID                         *Data,

+  IN     UINTN                        DataLength,

+  IN EFI_ASYNC_USB_TRANSFER_CALLBACK  IsochronousCallBack,

+  IN VOID                             *Context OPTIONAL

+  );

+

+/**                                                                 

+  Resets and reconfigures the USB controller. This function will work for all USB devices except

+  USB Hub Controllers.                                                                          

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+                                

+  @retval EFI_SUCCESS           The USB controller was reset.                                

+  @retval EFI_INVALID_PARAMETER If the controller specified by This is a USB hub.

+  @retval EFI_DEVICE_ERROR      An error occurred during the reconfiguration process.

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_PORT_RESET) (

+  IN EFI_USB_IO_PROTOCOL    *This

+  );

+

+/**                                                                 

+  Retrieves the USB Device Descriptor.

+    

+  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+  @param  DeviceDescriptor      A pointer to the caller allocated USB Device Descriptor.

+                                

+  @retval EFI_SUCCESS           The device descriptor was retrieved successfully.

+  @retval EFI_INVALID_PARAMETER DeviceDescriptor is NULL.

+  @retval EFI_NOT_FOUND         The device descriptor was not found. The device may not be configured.

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_GET_DEVICE_DESCRIPTOR) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  OUT EFI_USB_DEVICE_DESCRIPTOR     *DeviceDescriptor

+  );

+

+/**                                                                 

+  Retrieves the USB Device Descriptor.

+    

+  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+  @param  ConfigurationDescriptor A pointer to the caller allocated USB Active Configuration

+                                  Descriptor.                                               

+  @retval EFI_SUCCESS             The active configuration descriptor was retrieved successfully.

+  @retval EFI_INVALID_PARAMETER   ConfigurationDescriptor is NULL.

+  @retval EFI_NOT_FOUND           An active configuration descriptor cannot be found. The device may not

+                                  be configured.                                                        

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_GET_CONFIG_DESCRIPTOR) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  OUT EFI_USB_CONFIG_DESCRIPTOR     *ConfigurationDescriptor

+  );

+

+/**                                                                 

+  Retrieves the Interface Descriptor for a USB Device Controller. As stated earlier, an interface

+  within a USB device is equivalently to a USB Controller within the current configuration.      

+    

+  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+  @param  InterfaceDescriptor     A pointer to the caller allocated USB Interface Descriptor within

+                                  the configuration setting.                                       

+  @retval EFI_SUCCESS             The interface descriptor retrieved successfully.

+  @retval EFI_INVALID_PARAMETER   InterfaceDescriptor is NULL.

+  @retval EFI_NOT_FOUND           The interface descriptor cannot be found. The device may not be

+                                  correctly configured.                                          

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_GET_INTERFACE_DESCRIPTOR) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  OUT EFI_USB_INTERFACE_DESCRIPTOR  *InterfaceDescriptor

+  );

+

+/**                                                                 

+  Retrieves an Endpoint Descriptor within a USB Controller.

+    

+  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+  @param  EndpointIndex           Indicates which endpoint descriptor to retrieve.

+  @param  EndpointDescriptor      A pointer to the caller allocated USB Endpoint Descriptor of

+                                  a USB controller.                                           

+                                                    

+  @retval EFI_SUCCESS             The endpoint descriptor was retrieved successfully.

+  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.

+  @retval EFI_NOT_FOUND           The endpoint descriptor cannot be found. The device may not be

+                                  correctly configured.                                         

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  IN  UINT8                         EndpointIndex,

+  OUT EFI_USB_ENDPOINT_DESCRIPTOR   *EndpointDescriptor

+  );

+

+/**                                                                 

+  Retrieves a Unicode string stored in a USB Device.

+    

+  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+  @param  LangID                  The Language ID for the string being retrieved.

+  @param  StringID                The ID of the string being retrieved.                                                         

+  @param  String                  A pointer to a buffer allocated by this function with                

+                                  AllocatePool() to store the string.

+                                                    

+  @retval EFI_SUCCESS             The string was retrieved successfully.  

+  @retval EFI_NOT_FOUND           The string specified by LangID and StringID was not found.                                      

+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to allocate the return buffer String.

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_GET_STRING_DESCRIPTOR) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  IN  UINT16                        LangID,

+  IN  UINT8                         StringID,

+  OUT CHAR16                        **String

+  );

+

+/**                                                                 

+  Retrieves all the language ID codes that the USB device supports.

+    

+  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.                                  

+  @param  LangIDTable             Language ID for the string the caller wants to get.

+  @param  TableSize               The size, in bytes, of the table LangIDTable.

+                                                    

+  @retval EFI_SUCCESS             The support languages were retrieved successfully.  

+                                           

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_USB_IO_GET_SUPPORTED_LANGUAGE) (

+  IN EFI_USB_IO_PROTOCOL            *This,

+  OUT UINT16                        **LangIDTable,

+  OUT UINT16                        *TableSize

+  );

+

+//

+//  Protocol Interface Structure

+//

+struct _EFI_USB_IO_PROTOCOL {

+  //

+  // IO transfer

+  //

+  EFI_USB_IO_CONTROL_TRANSFER           UsbControlTransfer;

+  EFI_USB_IO_BULK_TRANSFER              UsbBulkTransfer;

+  EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER   UsbAsyncInterruptTransfer;

+  EFI_USB_IO_SYNC_INTERRUPT_TRANSFER    UsbSyncInterruptTransfer;

+  EFI_USB_IO_ISOCHRONOUS_TRANSFER       UsbIsochronousTransfer;

+  EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER UsbAsyncIsochronousTransfer;

+

+  //

+  // Common device request

+  //

+  EFI_USB_IO_GET_DEVICE_DESCRIPTOR      UsbGetDeviceDescriptor;

+  EFI_USB_IO_GET_CONFIG_DESCRIPTOR      UsbGetConfigDescriptor;

+  EFI_USB_IO_GET_INTERFACE_DESCRIPTOR   UsbGetInterfaceDescriptor;

+  EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR    UsbGetEndpointDescriptor;

+  EFI_USB_IO_GET_STRING_DESCRIPTOR      UsbGetStringDescriptor;

+  EFI_USB_IO_GET_SUPPORTED_LANGUAGE     UsbGetSupportedLanguages;

+

+  //

+  // Reset controller's parent port

+  //

+  EFI_USB_IO_PORT_RESET                 UsbPortReset;

+};

+

+extern EFI_GUID gEfiUsbIoProtocolGuid;

+

+#endif

diff --git a/edk2/MdePkg/Include/ToBeRemoved/Variable.h b/edk2/MdePkg/Include/ToBeRemoved/Variable.h
new file mode 100644
index 0000000..bc0d640
--- /dev/null
+++ b/edk2/MdePkg/Include/ToBeRemoved/Variable.h
@@ -0,0 +1,78 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiVariable.h

+  

+Abstract:

+  

+  Header file for EFI Variable Services

+

+--*/

+

+#ifndef _EFI_VARIABLE_H_

+#define _EFI_VARIABLE_H_

+

+#define VARIABLE_STORE_SIGNATURE  EFI_SIGNATURE_32 ('$', 'V', 'S', 'S')

+

+#define MAX_VARIABLE_SIZE         1024

+

+#define VARIABLE_DATA             0x55AA

+

+//

+// Variable Store Header flags

+//

+#define VARIABLE_STORE_FORMATTED  0x5a

+#define VARIABLE_STORE_HEALTHY    0xfe

+

+//

+// Variable Store Status

+//

+typedef enum {

+  EfiRaw,

+  EfiValid,

+  EfiInvalid,

+  EfiUnknown

+} VARIABLE_STORE_STATUS;

+

+//

+// Variable State flags

+//

+#define VAR_IN_DELETED_TRANSITION     0xfe  // Variable is in obsolete transistion

+#define VAR_DELETED                   0xfd  // Variable is obsolete

+#define VAR_ADDED                     0x7f  // Variable has been completely added

+#define IS_VARIABLE_STATE(_c, _Mask)  (BOOLEAN) (((~_c) & (~_Mask)) != 0)

+

+#pragma pack(1)

+

+typedef struct {

+  UINT32  Signature;

+  UINT32  Size;

+  UINT8   Format;

+  UINT8   State;

+  UINT16  Reserved;

+  UINT32  Reserved1;

+} VARIABLE_STORE_HEADER;

+

+typedef struct {

+  UINT16    StartId;

+  UINT8     State;

+  UINT8     Reserved;

+  UINT32    Attributes;

+  UINTN     NameSize;

+  UINTN     DataSize;

+  EFI_GUID  VendorGuid;

+} VARIABLE_HEADER;

+

+#pragma pack()

+

+#endif // _EFI_VARIABLE_H_

diff --git a/edk2/MdePkg/Include/ToBeRemoved/WorkingBlockHeader.h b/edk2/MdePkg/Include/ToBeRemoved/WorkingBlockHeader.h
new file mode 100644
index 0000000..235b740
--- /dev/null
+++ b/edk2/MdePkg/Include/ToBeRemoved/WorkingBlockHeader.h
@@ -0,0 +1,47 @@
+/*++

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiWorkingBlockHeader.h

+

+Abstract:

+

+  Defines data structure that is the headers found at the runtime 

+  updatable firmware volumes, such as the FileSystemGuid of the 

+  working block, the header structure of the variable block, FTW

+  working block, or event log block.

+

+--*/

+

+#ifndef _EFI_WORKING_BLOCK_HEADER_H_

+#define _EFI_WORKING_BLOCK_HEADER_H_

+

+//

+// EFI Fault tolerant working block header

+// The header is immediately followed by the write queue.

+//

+typedef struct {

+  EFI_GUID  Signature;

+  UINT32    Crc;

+  UINT32    WorkingBlockValid : 1;

+  UINT32    WorkingBlockInvalid : 1;

+#define WORKING_BLOCK_VALID   0x1

+#define WORKING_BLOCK_INVALID 0x2

+  UINT32    Reserved : 6;

+  UINT8     Reserved3[3];

+  UINTN     WriteQueueSize;

+  //

+  // UINT8                WriteQueue[WriteQueueSize];

+  //

+} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER;

+

+#endif

diff --git a/edk2/MdePkg/Include/Uefi.h b/edk2/MdePkg/Include/Uefi.h
new file mode 100644
index 0000000..fcaaeb2
--- /dev/null
+++ b/edk2/MdePkg/Include/Uefi.h
@@ -0,0 +1,66 @@
+/** @file

+

+  Root include file for Mde Package UEFI modules.

+

+  UEFI modules follow the public EFI 1.10 or UEFI 2.0 specifications and

+  also contains the infrastructure required to build modules. The build 

+  infrastructure must set EFI_SPECIFICATION_VERSION  before including  this 

+  file. To support R9/UEFI2.0 set EFI_SPECIFIATION_VERSION to 0x00020000. To 

+  support R8.5/EFI 1.10 set EFI_SPECIFIATION_VERSION to 0x00010010. 

+  Seting EDK_RELEASE_VERSION to zero implies no Tiano extensions and a

+  non zero value implies Tiano extensions are availible. 

+  EFI_SPECIFIATION_VERSION and EDK_RELEASE_VERSION are set automatically

+  by the build infrastructure for every module.

+  

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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 __UEFI_H__

+#define __UEFI_H__

+

+

+//

+// Check to make sure EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION are defined.

+//  also check for legal combinations

+//

+#if !defined(EFI_SPECIFICATION_VERSION)

+  #error EFI_SPECIFICATION_VERSION not defined

+#elif !defined(EDK_RELEASE_VERSION)

+  #error EDK_RELEASE_VERSION not defined

+#elif EDK_RELEASE_VERSION == 0x00000000

+//

+// UEFI mode with no Tiano extensions is legal

+//

+#elif (EDK_RELEASE_VERSION <= 0x00080005) && (EFI_SPECIFICATION_VERSION >= 0x00020000)

+  #error Illegal combination of EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION versions

+#endif

+

+

+

+#include <Common/UefiBaseTypes.h>

+#include <Uefi/UefiSpec.h>

+

+//

+// Need due to R8.5 Tiano contamination of UEFI enumes. 

+// There is a UEFI library that does things the new way and the old way

+// This is why these definitions are need in Uefi.h

+//

+#include <Guid/EventLegacyBios.h>

+#include <Guid/FrameworkDevicePath.h>

+

+

+//

+// All module types types have access to PCD for build support

+//

+#include <Protocol/Pcd.h>

+

+#endif

diff --git a/edk2/MdePkg/Include/Uefi/EfiPxe.h b/edk2/MdePkg/Include/Uefi/EfiPxe.h
new file mode 100644
index 0000000..eadac3c
--- /dev/null
+++ b/edk2/MdePkg/Include/Uefi/EfiPxe.h
@@ -0,0 +1,1780 @@
+/** @file

+  This header file contains all of the PXE type definitions,

+  structure prototypes, global variables and constants that

+  are needed for porting PXE to EFI.

+  

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+  

+  Module name: EfiPxe.h

+  

+  @par Revision Reference:

+  32/64-bit PXE specification:

+  alpha-4, 99-Dec-17

+  

+**/

+

+#ifndef __EFI_PXE_H__

+#define __EFI_PXE_H__

+

+#pragma pack(1)

+

+

+

+#define PXE_BUSTYPE(a, b, c, d) \

+    ( \

+      (((PXE_UINT32) (d) & 0xFF) << 24) | (((PXE_UINT32) (c) & 0xFF) << 16) | (((PXE_UINT32) (b) & 0xFF) << 8) | \

+        ((PXE_UINT32) (a) & 0xFF) \

+    )

+

+//

+// UNDI ROM ID and devive ID signature

+//

+#define PXE_BUSTYPE_PXE PXE_BUSTYPE ('!', 'P', 'X', 'E')

+

+//

+// BUS ROM ID signatures

+//

+#define PXE_BUSTYPE_PCI     PXE_BUSTYPE ('P', 'C', 'I', 'R')

+#define PXE_BUSTYPE_PC_CARD PXE_BUSTYPE ('P', 'C', 'C', 'R')

+#define PXE_BUSTYPE_USB     PXE_BUSTYPE ('U', 'S', 'B', 'R')

+#define PXE_BUSTYPE_1394    PXE_BUSTYPE ('1', '3', '9', '4')

+

+#define PXE_SWAP_UINT16(n)  ((((PXE_UINT16) (n) & 0x00FF) << 8) | (((PXE_UINT16) (n) & 0xFF00) >> 8))

+

+#define PXE_SWAP_UINT32(n) \

+  ((((PXE_UINT32)(n) & 0x000000FF) << 24) | \

+   (((PXE_UINT32)(n) & 0x0000FF00) << 8)  | \

+   (((PXE_UINT32)(n) & 0x00FF0000) >> 8)  | \

+   (((PXE_UINT32)(n) & 0xFF000000) >> 24))

+

+#define PXE_SWAP_UINT64(n) \

+  ((((PXE_UINT64)(n) & 0x00000000000000FFULL) << 56) | \

+   (((PXE_UINT64)(n) & 0x000000000000FF00ULL) << 40) | \

+   (((PXE_UINT64)(n) & 0x0000000000FF0000ULL) << 24) | \

+   (((PXE_UINT64)(n) & 0x00000000FF000000ULL) << 8)  | \

+   (((PXE_UINT64)(n) & 0x000000FF00000000ULL) >> 8)  | \

+   (((PXE_UINT64)(n) & 0x0000FF0000000000ULL) >> 24) | \

+   (((PXE_UINT64)(n) & 0x00FF000000000000ULL) >> 40) | \

+   (((PXE_UINT64)(n) & 0xFF00000000000000ULL) >> 56))

+

+

+#define PXE_CPBSIZE_NOT_USED  0               // zero

+#define PXE_DBSIZE_NOT_USED   0               // zero

+#define PXE_CPBADDR_NOT_USED  (PXE_UINT64) 0  // zero

+#define PXE_DBADDR_NOT_USED   (PXE_UINT64) 0  // zero

+#define PXE_CONST             const

+

+#define PXE_VOLATILE          volatile

+

+typedef VOID           PXE_VOID;

+typedef UINT8          PXE_UINT8;

+typedef UINT16         PXE_UINT16;

+typedef UINT32         PXE_UINT32;

+typedef UINTN          PXE_UINTN;

+ 

+//

+// typedef unsigned long PXE_UINT64;

+//

+typedef UINT64      PXE_UINT64;

+

+typedef PXE_UINT8 PXE_BOOL;

+#define PXE_FALSE 0 // zero

+#define PXE_TRUE  (!PXE_FALSE)

+

+typedef PXE_UINT16      PXE_OPCODE;

+

+//

+// Return UNDI operational state.

+//

+#define PXE_OPCODE_GET_STATE  0x0000

+

+//

+// Change UNDI operational state from Stopped to Started.

+//

+#define PXE_OPCODE_START  0x0001

+

+//

+// Change UNDI operational state from Started to Stopped.

+//

+#define PXE_OPCODE_STOP 0x0002

+

+//

+// Get UNDI initialization information.

+//

+#define PXE_OPCODE_GET_INIT_INFO  0x0003

+

+//

+// Get NIC configuration information.

+//

+#define PXE_OPCODE_GET_CONFIG_INFO  0x0004

+

+//

+// Changed UNDI operational state from Started to Initialized.

+//

+#define PXE_OPCODE_INITIALIZE 0x0005

+

+//

+// Re-initialize the NIC H/W.

+//

+#define PXE_OPCODE_RESET  0x0006

+

+//

+// Change the UNDI operational state from Initialized to Started.

+//

+#define PXE_OPCODE_SHUTDOWN 0x0007

+

+//

+// Read & change state of external interrupt enables.

+//

+#define PXE_OPCODE_INTERRUPT_ENABLES  0x0008

+

+//

+// Read & change state of packet receive filters.

+//

+#define PXE_OPCODE_RECEIVE_FILTERS  0x0009

+

+//

+// Read & change station MAC address.

+//

+#define PXE_OPCODE_STATION_ADDRESS  0x000A

+

+//

+// Read traffic statistics.

+//

+#define PXE_OPCODE_STATISTICS 0x000B

+

+//

+// Convert multicast IP address to multicast MAC address.

+//

+#define PXE_OPCODE_MCAST_IP_TO_MAC  0x000C

+

+//

+// Read or change non-volatile storage on the NIC.

+//

+#define PXE_OPCODE_NVDATA 0x000D

+

+//

+// Get & clear interrupt status.

+//

+#define PXE_OPCODE_GET_STATUS 0x000E

+

+//

+// Fill media header in packet for transmit.

+//

+#define PXE_OPCODE_FILL_HEADER  0x000F

+

+//

+// Transmit packet(s).

+//

+#define PXE_OPCODE_TRANSMIT 0x0010

+

+//

+// Receive packet.

+//

+#define PXE_OPCODE_RECEIVE  0x0011

+

+//

+// Last valid PXE UNDI OpCode number.

+//

+#define PXE_OPCODE_LAST_VALID 0x0011

+

+typedef PXE_UINT16  PXE_OPFLAGS;

+

+#define PXE_OPFLAGS_NOT_USED  0x0000

+

+//

+// //////////////////////////////////////

+// UNDI Get State

+//

+// No OpFlags

+

+////////////////////////////////////////

+// UNDI Start

+//

+// No OpFlags

+

+////////////////////////////////////////

+// UNDI Stop

+//

+// No OpFlags

+

+////////////////////////////////////////

+// UNDI Get Init Info

+//

+// No Opflags

+

+////////////////////////////////////////

+// UNDI Get Config Info

+//

+// No Opflags

+

+////////////////////////////////////////

+// UNDI Initialize

+//

+#define PXE_OPFLAGS_INITIALIZE_CABLE_DETECT_MASK    0x0001

+#define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE         0x0000

+#define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE  0x0001

+

+//

+// //////////////////////////////////////

+// UNDI Reset

+//

+#define PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS  0x0001

+#define PXE_OPFLAGS_RESET_DISABLE_FILTERS     0x0002

+

+//

+// //////////////////////////////////////

+// UNDI Shutdown

+//

+// No OpFlags

+

+////////////////////////////////////////

+// UNDI Interrupt Enables

+//

+//

+// Select whether to enable or disable external interrupt signals.

+// Setting both enable and disable will return PXE_STATCODE_INVALID_OPFLAGS.

+//

+#define PXE_OPFLAGS_INTERRUPT_OPMASK  0xC000

+#define PXE_OPFLAGS_INTERRUPT_ENABLE  0x8000

+#define PXE_OPFLAGS_INTERRUPT_DISABLE 0x4000

+#define PXE_OPFLAGS_INTERRUPT_READ    0x0000

+

+//

+// Enable receive interrupts.  An external interrupt will be generated

+// after a complete non-error packet has been received.

+//

+#define PXE_OPFLAGS_INTERRUPT_RECEIVE 0x0001

+

+//

+// Enable transmit interrupts.  An external interrupt will be generated

+// after a complete non-error packet has been transmitted.

+//

+#define PXE_OPFLAGS_INTERRUPT_TRANSMIT  0x0002

+

+//

+// Enable command interrupts.  An external interrupt will be generated

+// when command execution stops.

+//

+#define PXE_OPFLAGS_INTERRUPT_COMMAND 0x0004

+

+//

+// Generate software interrupt.  Setting this bit generates an external

+// interrupt, if it is supported by the hardware.

+//

+#define PXE_OPFLAGS_INTERRUPT_SOFTWARE  0x0008

+

+//

+// //////////////////////////////////////

+// UNDI Receive Filters

+//

+//

+// Select whether to enable or disable receive filters.

+// Setting both enable and disable will return PXE_STATCODE_INVALID_OPCODE.

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_OPMASK   0xC000

+#define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE   0x8000

+#define PXE_OPFLAGS_RECEIVE_FILTER_DISABLE  0x4000

+#define PXE_OPFLAGS_RECEIVE_FILTER_READ     0x0000

+

+//

+// To reset the contents of the multicast MAC address filter list,

+// set this OpFlag:

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST 0x2000

+

+//

+// Enable unicast packet receiving.  Packets sent to the current station

+// MAC address will be received.

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST  0x0001

+

+//

+// Enable broadcast packet receiving.  Packets sent to the broadcast

+// MAC address will be received.

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST  0x0002

+

+//

+// Enable filtered multicast packet receiving.  Packets sent to any

+// of the multicast MAC addresses in the multicast MAC address filter

+// list will be received.  If the filter list is empty, no multicast

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004

+

+//

+// Enable promiscuous packet receiving.  All packets will be received.

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008

+

+//

+// Enable promiscuous multicast packet receiving.  All multicast

+// packets will be received.

+//

+#define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010

+

+//

+// //////////////////////////////////////

+// UNDI Station Address

+//

+#define PXE_OPFLAGS_STATION_ADDRESS_READ   0x0000

+#define PXE_OPFLAGS_STATION_ADDRESS_WRITE  0x0000

+#define PXE_OPFLAGS_STATION_ADDRESS_RESET  0x0001

+

+//

+// //////////////////////////////////////

+// UNDI Statistics

+//

+#define PXE_OPFLAGS_STATISTICS_READ   0x0000

+#define PXE_OPFLAGS_STATISTICS_RESET  0x0001

+

+//

+// //////////////////////////////////////

+// UNDI MCast IP to MAC

+//

+//

+// Identify the type of IP address in the CPB.

+//

+#define PXE_OPFLAGS_MCAST_IP_TO_MAC_OPMASK  0x0003

+#define PXE_OPFLAGS_MCAST_IPV4_TO_MAC       0x0000

+#define PXE_OPFLAGS_MCAST_IPV6_TO_MAC       0x0001

+

+//

+// //////////////////////////////////////

+// UNDI NvData

+//

+//

+// Select the type of non-volatile data operation.

+//

+#define PXE_OPFLAGS_NVDATA_OPMASK 0x0001

+#define PXE_OPFLAGS_NVDATA_READ   0x0000

+#define PXE_OPFLAGS_NVDATA_WRITE  0x0001

+

+//

+// //////////////////////////////////////

+// UNDI Get Status

+//

+//

+// Return current interrupt status.  This will also clear any interrupts

+// that are currently set.  This can be used in a polling routine.  The

+// interrupt flags are still set and cleared even when the interrupts

+// are disabled.

+//

+#define PXE_OPFLAGS_GET_INTERRUPT_STATUS  0x0001

+

+//

+// Return list of transmitted buffers for recycling.  Transmit buffers

+// must not be changed or unallocated until they have recycled.  After

+// issuing a transmit command, wait for a transmit complete interrupt.

+// When a transmit complete interrupt is received, read the transmitted

+// buffers.  Do not plan on getting one buffer per interrupt.  Some

+// NICs and UNDIs may transmit multiple buffers per interrupt.

+//

+#define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS 0x0002

+

+//

+// //////////////////////////////////////

+// UNDI Fill Header

+//

+#define PXE_OPFLAGS_FILL_HEADER_OPMASK      0x0001

+#define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED  0x0001

+#define PXE_OPFLAGS_FILL_HEADER_WHOLE       0x0000

+

+//

+// //////////////////////////////////////

+// UNDI Transmit

+//

+//

+// S/W UNDI only.  Return after the packet has been transmitted.  A

+// transmit complete interrupt will still be generated and the transmit

+// buffer will have to be recycled.

+//

+#define PXE_OPFLAGS_SWUNDI_TRANSMIT_OPMASK  0x0001

+#define PXE_OPFLAGS_TRANSMIT_BLOCK          0x0001

+#define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK     0x0000

+

+//

+//

+//

+#define PXE_OPFLAGS_TRANSMIT_OPMASK     0x0002

+#define PXE_OPFLAGS_TRANSMIT_FRAGMENTED 0x0002

+#define PXE_OPFLAGS_TRANSMIT_WHOLE      0x0000

+

+//

+// //////////////////////////////////////

+// UNDI Receive

+//

+// No OpFlags

+//

+typedef PXE_UINT16  PXE_STATFLAGS;

+

+#define PXE_STATFLAGS_INITIALIZE  0x0000

+

+//

+// //////////////////////////////////////

+// Common StatFlags that can be returned by all commands.

+//

+//

+// The COMMAND_COMPLETE and COMMAND_FAILED status flags must be

+// implemented by all UNDIs.  COMMAND_QUEUED is only needed by UNDIs

+// that support command queuing.

+//

+#define PXE_STATFLAGS_STATUS_MASK       0xC000

+#define PXE_STATFLAGS_COMMAND_COMPLETE  0xC000

+#define PXE_STATFLAGS_COMMAND_FAILED    0x8000

+#define PXE_STATFLAGS_COMMAND_QUEUED    0x4000

+

+//

+// //////////////////////////////////////

+// UNDI Get State

+//

+#define PXE_STATFLAGS_GET_STATE_MASK        0x0003

+#define PXE_STATFLAGS_GET_STATE_INITIALIZED 0x0002

+#define PXE_STATFLAGS_GET_STATE_STARTED     0x0001

+#define PXE_STATFLAGS_GET_STATE_STOPPED     0x0000

+

+//

+// //////////////////////////////////////

+// UNDI Start

+//

+// No additional StatFlags

+

+////////////////////////////////////////

+// UNDI Get Init Info

+//

+#define PXE_STATFLAGS_CABLE_DETECT_MASK           0x0001

+#define PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED  0x0000

+#define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED      0x0001

+

+//

+// //////////////////////////////////////

+// UNDI Initialize

+//

+#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA  0x0001

+

+//

+// //////////////////////////////////////

+// UNDI Reset

+//

+#define PXE_STATFLAGS_RESET_NO_MEDIA  0x0001

+

+//

+// //////////////////////////////////////

+// UNDI Shutdown

+//

+// No additional StatFlags

+

+////////////////////////////////////////

+// UNDI Interrupt Enables

+//

+//

+// If set, receive interrupts are enabled.

+//

+#define PXE_STATFLAGS_INTERRUPT_RECEIVE 0x0001

+

+//

+// If set, transmit interrupts are enabled.

+//

+#define PXE_STATFLAGS_INTERRUPT_TRANSMIT  0x0002

+

+//

+// If set, command interrupts are enabled.

+//

+#define PXE_STATFLAGS_INTERRUPT_COMMAND 0x0004

+

+//

+// //////////////////////////////////////

+// UNDI Receive Filters

+//

+//

+// If set, unicast packets will be received.

+//

+#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST  0x0001

+

+//

+// If set, broadcast packets will be received.

+//

+#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST  0x0002

+

+//

+// If set, multicast packets that match up with the multicast address

+// filter list will be received.

+//

+#define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004

+

+//

+// If set, all packets will be received.

+//

+#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008

+

+//

+// If set, all multicast packets will be received.

+//

+#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010

+

+//

+// //////////////////////////////////////

+// UNDI Station Address

+//

+// No additional StatFlags

+

+////////////////////////////////////////

+// UNDI Statistics

+//

+// No additional StatFlags

+

+////////////////////////////////////////

+// UNDI MCast IP to MAC

+//

+// No additional StatFlags

+

+////////////////////////////////////////

+// UNDI NvData

+//

+// No additional StatFlags

+

+

+////////////////////////////////////////

+// UNDI Get Status

+//

+//

+// Use to determine if an interrupt has occurred.

+//

+#define PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK 0x000F

+#define PXE_STATFLAGS_GET_STATUS_NO_INTERRUPTS  0x0000

+

+//

+// If set, at least one receive interrupt occurred.

+//

+#define PXE_STATFLAGS_GET_STATUS_RECEIVE  0x0001

+

+//

+// If set, at least one transmit interrupt occurred.

+//

+#define PXE_STATFLAGS_GET_STATUS_TRANSMIT 0x0002

+

+//

+// If set, at least one command interrupt occurred.

+//

+#define PXE_STATFLAGS_GET_STATUS_COMMAND  0x0004

+

+//

+// If set, at least one software interrupt occurred.

+//

+#define PXE_STATFLAGS_GET_STATUS_SOFTWARE 0x0008

+

+//

+// This flag is set if the transmitted buffer queue is empty.  This flag

+// will be set if all transmitted buffer addresses get written into the DB.

+//

+#define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY  0x0010

+

+//

+// This flag is set if no transmitted buffer addresses were written

+// into the DB.  (This could be because DBsize was too small.)

+//

+#define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN  0x0020

+

+//

+// //////////////////////////////////////

+// UNDI Fill Header

+//

+// No additional StatFlags

+

+////////////////////////////////////////

+// UNDI Transmit

+//

+// No additional StatFlags.

+

+////////////////////////////////////////

+// UNDI Receive

+//

+// No additional StatFlags.

+//

+typedef PXE_UINT16  PXE_STATCODE;

+

+#define PXE_STATCODE_INITIALIZE 0x0000

+

+//

+// //////////////////////////////////////

+// Common StatCodes returned by all UNDI commands, UNDI protocol functions

+// and BC protocol functions.

+//

+#define PXE_STATCODE_SUCCESS              0x0000

+

+#define PXE_STATCODE_INVALID_CDB          0x0001

+#define PXE_STATCODE_INVALID_CPB          0x0002

+#define PXE_STATCODE_BUSY                 0x0003

+#define PXE_STATCODE_QUEUE_FULL           0x0004

+#define PXE_STATCODE_ALREADY_STARTED      0x0005

+#define PXE_STATCODE_NOT_STARTED          0x0006

+#define PXE_STATCODE_NOT_SHUTDOWN         0x0007

+#define PXE_STATCODE_ALREADY_INITIALIZED  0x0008

+#define PXE_STATCODE_NOT_INITIALIZED      0x0009

+#define PXE_STATCODE_DEVICE_FAILURE       0x000A

+#define PXE_STATCODE_NVDATA_FAILURE       0x000B

+#define PXE_STATCODE_UNSUPPORTED          0x000C

+#define PXE_STATCODE_BUFFER_FULL          0x000D

+#define PXE_STATCODE_INVALID_PARAMETER    0x000E

+#define PXE_STATCODE_INVALID_UNDI         0x000F

+#define PXE_STATCODE_IPV4_NOT_SUPPORTED   0x0010

+#define PXE_STATCODE_IPV6_NOT_SUPPORTED   0x0011

+#define PXE_STATCODE_NOT_ENOUGH_MEMORY    0x0012

+#define PXE_STATCODE_NO_DATA              0x0013

+

+typedef PXE_UINT16  PXE_IFNUM;

+

+//

+// This interface number must be passed to the S/W UNDI Start command.

+//

+#define PXE_IFNUM_START 0x0000

+

+//

+// This interface number is returned by the S/W UNDI Get State and

+// Start commands if information in the CDB, CPB or DB is invalid.

+//

+#define PXE_IFNUM_INVALID 0x0000

+

+typedef PXE_UINT16  PXE_CONTROL;

+

+//

+// Setting this flag directs the UNDI to queue this command for later

+// execution if the UNDI is busy and it supports command queuing.

+// If queuing is not supported, a PXE_STATCODE_INVALID_CONTROL error

+// is returned.  If the queue is full, a PXE_STATCODE_CDB_QUEUE_FULL

+// error is returned.

+//

+#define PXE_CONTROL_QUEUE_IF_BUSY 0x0002

+

+//

+// These two bit values are used to determine if there are more UNDI

+// CDB structures following this one.  If the link bit is set, there

+// must be a CDB structure following this one.  Execution will start

+// on the next CDB structure as soon as this one completes successfully.

+// If an error is generated by this command, execution will stop.

+//

+#define PXE_CONTROL_LINK              0x0001

+#define PXE_CONTROL_LAST_CDB_IN_LIST  0x0000

+

+typedef PXE_UINT8   PXE_FRAME_TYPE;

+

+#define PXE_FRAME_TYPE_NONE                     0x00

+#define PXE_FRAME_TYPE_UNICAST                  0x01

+#define PXE_FRAME_TYPE_BROADCAST                0x02

+#define PXE_FRAME_TYPE_FILTERED_MULTICAST       0x03

+#define PXE_FRAME_TYPE_PROMISCUOUS              0x04

+#define PXE_FRAME_TYPE_PROMISCUOUS_MULTICAST    0x05

+

+#define PXE_FRAME_TYPE_MULTICAST                PXE_FRAME_TYPE_FILTERED_MULTICAST       

+

+typedef PXE_UINT32  PXE_IPV4;

+

+typedef PXE_UINT32  PXE_IPV6[4];

+#define PXE_MAC_LENGTH  32

+

+typedef PXE_UINT8   PXE_MAC_ADDR[PXE_MAC_LENGTH];

+

+typedef PXE_UINT8   PXE_IFTYPE;

+typedef UINT16      PXE_MEDIA_PROTOCOL;

+

+//

+// This information is from the ARP section of RFC 1700.

+//

+//     1 Ethernet (10Mb)                                    [JBP]

+//     2 Experimental Ethernet (3Mb)                        [JBP]

+//     3 Amateur Radio AX.25                                [PXK]

+//     4 Proteon ProNET Token Ring                          [JBP]

+//     5 Chaos                                              [GXP]

+//     6 IEEE 802 Networks                                  [JBP]

+//     7 ARCNET                                             [JBP]

+//     8 Hyperchannel                                       [JBP]

+//     9 Lanstar                                             [TU]

+//    10 Autonet Short Address                             [MXB1]

+//    11 LocalTalk                                         [JKR1]

+//    12 LocalNet (IBM* PCNet or SYTEK* LocalNET)           [JXM]

+//    13 Ultra link                                        [RXD2]

+//    14 SMDS                                              [GXC1]

+//    15 Frame Relay                                        [AGM]

+//    16 Asynchronous Transmission Mode (ATM)              [JXB2]

+//    17 HDLC                                               [JBP]

+//    18 Fibre Channel                            [Yakov Rekhter]

+//    19 Asynchronous Transmission Mode (ATM)      [Mark Laubach]

+//    20 Serial Line                                        [JBP]

+//    21 Asynchronous Transmission Mode (ATM)              [MXB1]

+//

+// * Other names and brands may be claimed as the property of others.

+//

+#define PXE_IFTYPE_ETHERNET       0x01

+#define PXE_IFTYPE_TOKENRING      0x04

+#define PXE_IFTYPE_FIBRE_CHANNEL  0x12

+

+typedef struct s_pxe_hw_undi {

+  PXE_UINT32  Signature;      // PXE_ROMID_SIGNATURE

+  PXE_UINT8   Len;            // sizeof(PXE_HW_UNDI)

+  PXE_UINT8   Fudge;          // makes 8-bit cksum equal zero

+  PXE_UINT8   Rev;            // PXE_ROMID_REV

+  PXE_UINT8   IFcnt;          // physical connector count

+  PXE_UINT8   MajorVer;       // PXE_ROMID_MAJORVER

+  PXE_UINT8   MinorVer;       // PXE_ROMID_MINORVER

+  PXE_UINT16  reserved;       // zero, not used

+  PXE_UINT32  Implementation; // implementation flags

+  // reserved             // vendor use

+  // UINT32 Status;       // status port

+  // UINT32 Command;      // command port

+  // UINT64 CDBaddr;      // CDB address port

+  //

+} PXE_HW_UNDI;

+

+//

+// Status port bit definitions

+//

+//

+// UNDI operation state

+//

+#define PXE_HWSTAT_STATE_MASK   0xC0000000

+#define PXE_HWSTAT_BUSY         0xC0000000

+#define PXE_HWSTAT_INITIALIZED  0x80000000

+#define PXE_HWSTAT_STARTED      0x40000000

+#define PXE_HWSTAT_STOPPED      0x00000000

+

+//

+// If set, last command failed

+//

+#define PXE_HWSTAT_COMMAND_FAILED 0x20000000

+

+//

+// If set, identifies enabled receive filters

+//

+#define PXE_HWSTAT_PROMISCUOUS_MULTICAST_RX_ENABLED 0x00001000

+#define PXE_HWSTAT_PROMISCUOUS_RX_ENABLED           0x00000800

+#define PXE_HWSTAT_BROADCAST_RX_ENABLED             0x00000400

+#define PXE_HWSTAT_MULTICAST_RX_ENABLED             0x00000200

+#define PXE_HWSTAT_UNICAST_RX_ENABLED               0x00000100

+

+//

+// If set, identifies enabled external interrupts

+//

+#define PXE_HWSTAT_SOFTWARE_INT_ENABLED     0x00000080

+#define PXE_HWSTAT_TX_COMPLETE_INT_ENABLED  0x00000040

+#define PXE_HWSTAT_PACKET_RX_INT_ENABLED    0x00000020

+#define PXE_HWSTAT_CMD_COMPLETE_INT_ENABLED 0x00000010

+

+//

+// If set, identifies pending interrupts

+//

+#define PXE_HWSTAT_SOFTWARE_INT_PENDING     0x00000008

+#define PXE_HWSTAT_TX_COMPLETE_INT_PENDING  0x00000004

+#define PXE_HWSTAT_PACKET_RX_INT_PENDING    0x00000002

+#define PXE_HWSTAT_CMD_COMPLETE_INT_PENDING 0x00000001

+

+//

+// Command port definitions

+//

+//

+// If set, CDB identified in CDBaddr port is given to UNDI.

+// If not set, other bits in this word will be processed.

+//

+#define PXE_HWCMD_ISSUE_COMMAND   0x80000000

+#define PXE_HWCMD_INTS_AND_FILTS  0x00000000

+

+//

+// Use these to enable/disable receive filters.

+//

+#define PXE_HWCMD_PROMISCUOUS_MULTICAST_RX_ENABLE 0x00001000

+#define PXE_HWCMD_PROMISCUOUS_RX_ENABLE           0x00000800

+#define PXE_HWCMD_BROADCAST_RX_ENABLE             0x00000400

+#define PXE_HWCMD_MULTICAST_RX_ENABLE             0x00000200

+#define PXE_HWCMD_UNICAST_RX_ENABLE               0x00000100

+

+//

+// Use these to enable/disable external interrupts

+//

+#define PXE_HWCMD_SOFTWARE_INT_ENABLE     0x00000080

+#define PXE_HWCMD_TX_COMPLETE_INT_ENABLE  0x00000040

+#define PXE_HWCMD_PACKET_RX_INT_ENABLE    0x00000020

+#define PXE_HWCMD_CMD_COMPLETE_INT_ENABLE 0x00000010

+

+//

+// Use these to clear pending external interrupts

+//

+#define PXE_HWCMD_CLEAR_SOFTWARE_INT      0x00000008

+#define PXE_HWCMD_CLEAR_TX_COMPLETE_INT   0x00000004

+#define PXE_HWCMD_CLEAR_PACKET_RX_INT     0x00000002

+#define PXE_HWCMD_CLEAR_CMD_COMPLETE_INT  0x00000001

+

+typedef struct s_pxe_sw_undi {

+  PXE_UINT32  Signature;      // PXE_ROMID_SIGNATURE

+  PXE_UINT8   Len;            // sizeof(PXE_SW_UNDI)

+  PXE_UINT8   Fudge;          // makes 8-bit cksum zero

+  PXE_UINT8   Rev;            // PXE_ROMID_REV

+  PXE_UINT8   IFcnt;          // physical connector count

+  PXE_UINT8   MajorVer;       // PXE_ROMID_MAJORVER

+  PXE_UINT8   MinorVer;       // PXE_ROMID_MINORVER

+  PXE_UINT16  reserved1;      // zero, not used

+  PXE_UINT32  Implementation; // Implementation flags

+  PXE_UINT64  EntryPoint;     // API entry point

+  PXE_UINT8   reserved2[3];   // zero, not used

+  PXE_UINT8   BusCnt;         // number of bustypes supported

+  PXE_UINT32  BusType[1];     // list of supported bustypes

+} PXE_SW_UNDI;

+

+typedef union u_pxe_undi {

+  PXE_HW_UNDI hw;

+  PXE_SW_UNDI sw;

+} PXE_UNDI;

+

+//

+// Signature of !PXE structure

+//

+#define PXE_ROMID_SIGNATURE PXE_BUSTYPE ('!', 'P', 'X', 'E')

+

+//

+// !PXE structure format revision

+//

+#define PXE_ROMID_REV 0x02

+

+//

+// UNDI command interface revision.  These are the values that get sent

+// in option 94 (Client Network Interface Identifier) in the DHCP Discover

+// and PXE Boot Server Request packets.

+//

+#define PXE_ROMID_MAJORVER    0x03

+#define PXE_ROMID_MINORVER    0x01

+

+//

+// Implementation flags

+//

+#define PXE_ROMID_IMP_HW_UNDI                             0x80000000

+#define PXE_ROMID_IMP_SW_VIRT_ADDR                        0x40000000

+#define PXE_ROMID_IMP_64BIT_DEVICE                        0x00010000

+#define PXE_ROMID_IMP_FRAG_SUPPORTED                      0x00008000

+#define PXE_ROMID_IMP_CMD_LINK_SUPPORTED                  0x00004000

+#define PXE_ROMID_IMP_CMD_QUEUE_SUPPORTED                 0x00002000

+#define PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED               0x00001000

+#define PXE_ROMID_IMP_NVDATA_SUPPORT_MASK                 0x00000C00

+#define PXE_ROMID_IMP_NVDATA_BULK_WRITABLE                0x00000C00

+#define PXE_ROMID_IMP_NVDATA_SPARSE_WRITABLE              0x00000800

+#define PXE_ROMID_IMP_NVDATA_READ_ONLY                    0x00000400

+#define PXE_ROMID_IMP_NVDATA_NOT_AVAILABLE                0x00000000

+#define PXE_ROMID_IMP_STATISTICS_SUPPORTED                0x00000200

+#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE               0x00000100

+#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED  0x00000080

+#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED            0x00000040

+#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED              0x00000020

+#define PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED     0x00000010

+#define PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED              0x00000008

+#define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED           0x00000004

+#define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED             0x00000002

+#define PXE_ROMID_IMP_CMD_COMPLETE_INT_SUPPORTED          0x00000001

+

+typedef struct s_pxe_cdb {

+  PXE_OPCODE    OpCode;

+  PXE_OPFLAGS   OpFlags;

+  PXE_UINT16    CPBsize;

+  PXE_UINT16    DBsize;

+  PXE_UINT64    CPBaddr;

+  PXE_UINT64    DBaddr;

+  PXE_STATCODE  StatCode;

+  PXE_STATFLAGS StatFlags;

+  PXE_UINT16    IFnum;

+  PXE_CONTROL   Control;

+} PXE_CDB;

+

+typedef union u_pxe_ip_addr {

+  PXE_IPV6  IPv6;

+  PXE_IPV4  IPv4;

+} PXE_IP_ADDR;

+

+typedef union pxe_device {

+  //

+  // PCI and PC Card NICs are both identified using bus, device

+  // and function numbers.  For PC Card, this may require PC

+  // Card services to be loaded in the BIOS or preboot

+  // environment.

+  //

+  struct {

+    //

+    // See S/W UNDI ROMID structure definition for PCI and

+    // PCC BusType definitions.

+    //

+    PXE_UINT32  BusType;

+

+    //

+    // Bus, device & function numbers that locate this device.

+    //

+    PXE_UINT16  Bus;

+    PXE_UINT8   Device;

+    PXE_UINT8   Function;

+  }

+  PCI, PCC;

+

+  //

+  // %%TBD - More information is needed about enumerating

+  // USB and 1394 devices.

+  //

+  struct {

+    PXE_UINT32  BusType;

+    PXE_UINT32  tdb;

+  }

+  USB, _1394;

+} PXE_DEVICE;

+

+//

+// cpb and db definitions

+//

+#define MAX_PCI_CONFIG_LEN    64  // # of dwords

+#define MAX_EEPROM_LEN        128 // #of dwords

+#define MAX_XMIT_BUFFERS      32  // recycling Q length for xmit_done

+#define MAX_MCAST_ADDRESS_CNT 8

+

+typedef struct s_pxe_cpb_start_30 {

+  //

+  // PXE_VOID Delay(UINTN microseconds);

+  //

+  // UNDI will never request a delay smaller than 10 microseconds

+  // and will always request delays in increments of 10 microseconds.

+  // The Delay() CallBack routine must delay between n and n + 10

+  // microseconds before returning control to the UNDI.

+  //

+  // This field cannot be set to zero.

+  //

+  UINT64  Delay;

+

+  //

+  // PXE_VOID Block(UINT32 enable);

+  //

+  // UNDI may need to block multi-threaded/multi-processor access to

+  // critical code sections when programming or accessing the network

+  // device.  To this end, a blocking service is needed by the UNDI.

+  // When UNDI needs a block, it will call Block() passing a non-zero

+  // value.  When UNDI no longer needs a block, it will call Block()

+  // with a zero value.  When called, if the Block() is already enabled,

+  // do not return control to the UNDI until the previous Block() is

+  // disabled.

+  //

+  // This field cannot be set to zero.

+  //

+  UINT64  Block;

+

+  //

+  // PXE_VOID Virt2Phys(UINT64 virtual, UINT64 physical_ptr);

+  //

+  // UNDI will pass the virtual address of a buffer and the virtual

+  // address of a 64-bit physical buffer.  Convert the virtual address

+  // to a physical address and write the result to the physical address

+  // buffer.  If virtual and physical addresses are the same, just

+  // copy the virtual address to the physical address buffer.

+  //

+  // This field can be set to zero if virtual and physical addresses

+  // are equal.

+  //

+  UINT64  Virt2Phys;

+  //

+  // PXE_VOID Mem_IO(UINT8 read_write, UINT8 len, UINT64 port,

+  //              UINT64 buf_addr);

+  //

+  // UNDI will read or write the device io space using this call back

+  // function. It passes the number of bytes as the len parameter and it

+  // will be either 1,2,4 or 8.

+  //

+  // This field can not be set to zero.

+  //

+  UINT64  Mem_IO;

+} PXE_CPB_START_30;

+

+typedef struct s_pxe_cpb_start_31 {

+  //

+  // PXE_VOID Delay(UINT64 UnqId, UINTN microseconds);

+  //

+  // UNDI will never request a delay smaller than 10 microseconds

+  // and will always request delays in increments of 10 microseconds.

+  // The Delay() CallBack routine must delay between n and n + 10

+  // microseconds before returning control to the UNDI.

+  //

+  // This field cannot be set to zero.

+  //

+  UINT64  Delay;

+

+  //

+  // PXE_VOID Block(UINT64 unq_id, UINT32 enable);

+  //

+  // UNDI may need to block multi-threaded/multi-processor access to

+  // critical code sections when programming or accessing the network

+  // device.  To this end, a blocking service is needed by the UNDI.

+  // When UNDI needs a block, it will call Block() passing a non-zero

+  // value.  When UNDI no longer needs a block, it will call Block()

+  // with a zero value.  When called, if the Block() is already enabled,

+  // do not return control to the UNDI until the previous Block() is

+  // disabled.

+  //

+  // This field cannot be set to zero.

+  //

+  UINT64  Block;

+

+  //

+  // PXE_VOID Virt2Phys(UINT64 UnqId, UINT64 virtual, UINT64 physical_ptr);

+  //

+  // UNDI will pass the virtual address of a buffer and the virtual

+  // address of a 64-bit physical buffer.  Convert the virtual address

+  // to a physical address and write the result to the physical address

+  // buffer.  If virtual and physical addresses are the same, just

+  // copy the virtual address to the physical address buffer.

+  //

+  // This field can be set to zero if virtual and physical addresses

+  // are equal.

+  //

+  UINT64  Virt2Phys;

+  //

+  // PXE_VOID Mem_IO(UINT64 UnqId, UINT8 read_write, UINT8 len, UINT64 port,

+  //              UINT64 buf_addr);

+  //

+  // UNDI will read or write the device io space using this call back

+  // function. It passes the number of bytes as the len parameter and it

+  // will be either 1,2,4 or 8.

+  //

+  // This field can not be set to zero.

+  //

+  UINT64  Mem_IO;

+  //

+  // PXE_VOID Map_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,

+  //                 UINT32 Direction, UINT64 mapped_addr);

+  //

+  // UNDI will pass the virtual address of a buffer, direction of the data

+  // flow from/to the mapped buffer (the constants are defined below)

+  // and a place holder (pointer) for the mapped address.

+  // This call will Map the given address to a physical DMA address and write

+  // the result to the mapped_addr pointer.  If there is no need to

+  // map the given address to a lower address (i.e. the given address is

+  // associated with a physical address that is already compatible to be

+  // used with the DMA, it converts the given virtual address to it's

+  // physical address and write that in the mapped address pointer.

+  //

+  // This field can be set to zero if there is no mapping service available

+  //

+  UINT64  Map_Mem;

+

+  //

+  // PXE_VOID UnMap_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,

+  //            UINT32 Direction, UINT64 mapped_addr);

+  //

+  // UNDI will pass the virtual and mapped addresses of a buffer

+  // This call will un map the given address

+  //

+  // This field can be set to zero if there is no unmapping service available

+  //

+  UINT64  UnMap_Mem;

+

+  //

+  // PXE_VOID Sync_Mem(UINT64 unq_id, UINT64 virtual,

+  //            UINT32 size, UINT32 Direction, UINT64 mapped_addr);

+  //

+  // UNDI will pass the virtual and mapped addresses of a buffer

+  // This call will synchronize the contents of both the virtual and mapped

+  // buffers for the given Direction.

+  //

+  // This field can be set to zero if there is no service available

+  //

+  UINT64  Sync_Mem;

+

+  //

+  // protocol driver can provide anything for this Unique_ID, UNDI remembers

+  // that as just a 64bit value assocaited to the interface specified by

+  // the ifnum and gives it back as a parameter to all the call-back routines

+  // when calling for that interface!

+  //

+  UINT64  Unique_ID;

+  //

+} PXE_CPB_START_31;

+

+#define TO_AND_FROM_DEVICE    0

+#define FROM_DEVICE           1

+#define TO_DEVICE             2

+

+#define PXE_DELAY_MILLISECOND 1000

+#define PXE_DELAY_SECOND      1000000

+#define PXE_IO_READ           0

+#define PXE_IO_WRITE          1

+#define PXE_MEM_READ          2

+#define PXE_MEM_WRITE         4

+

+typedef struct s_pxe_db_get_init_info {

+  //

+  // Minimum length of locked memory buffer that must be given to

+  // the Initialize command. Giving UNDI more memory will generally

+  // give better performance.

+  //

+  // If MemoryRequired is zero, the UNDI does not need and will not

+  // use system memory to receive and transmit packets.

+  //

+  PXE_UINT32  MemoryRequired;

+

+  //

+  // Maximum frame data length for Tx/Rx excluding the media header.

+  //

+  PXE_UINT32  FrameDataLen;

+

+  //

+  // Supported link speeds are in units of mega bits.  Common ethernet

+  // values are 10, 100 and 1000.  Unused LinkSpeeds[] entries are zero

+  // filled.

+  //

+  PXE_UINT32  LinkSpeeds[4];

+

+  //

+  // Number of non-volatile storage items.

+  //

+  PXE_UINT32  NvCount;

+

+  //

+  // Width of non-volatile storage item in bytes.  0, 1, 2 or 4

+  //

+  PXE_UINT16  NvWidth;

+

+  //

+  // Media header length.  This is the typical media header length for

+  // this UNDI.  This information is needed when allocating receive

+  // and transmit buffers.

+  //

+  PXE_UINT16  MediaHeaderLen;

+

+  //

+  // Number of bytes in the NIC hardware (MAC) address.

+  //

+  PXE_UINT16  HWaddrLen;

+

+  //

+  // Maximum number of multicast MAC addresses in the multicast

+  // MAC address filter list.

+  //

+  PXE_UINT16  MCastFilterCnt;

+

+  //

+  // Default number and size of transmit and receive buffers that will

+  // be allocated by the UNDI.  If MemoryRequired is non-zero, this

+  // allocation will come out of the memory buffer given to the Initialize

+  // command.  If MemoryRequired is zero, this allocation will come out of

+  // memory on the NIC.

+  //

+  PXE_UINT16  TxBufCnt;

+  PXE_UINT16  TxBufSize;

+  PXE_UINT16  RxBufCnt;

+  PXE_UINT16  RxBufSize;

+

+  //

+  // Hardware interface types defined in the Assigned Numbers RFC

+  // and used in DHCP and ARP packets.

+  // See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros.

+  //

+  PXE_UINT8   IFtype;

+

+  //

+  // Supported duplex.  See PXE_DUPLEX_xxxxx #defines below.

+  //

+  PXE_UINT8   SupportedDuplexModes;

+

+  //

+  // Supported loopback options.  See PXE_LOOPBACK_xxxxx #defines below.

+  //

+  PXE_UINT8   SupportedLoopBackModes;

+} PXE_DB_GET_INIT_INFO;

+

+#define PXE_MAX_TXRX_UNIT_ETHER           1500

+

+#define PXE_HWADDR_LEN_ETHER              0x0006

+#define PXE_MAC_HEADER_LEN_ETHER          0x000E

+

+#define PXE_DUPLEX_ENABLE_FULL_SUPPORTED  1

+#define PXE_DUPLEX_FORCE_FULL_SUPPORTED   2

+

+#define PXE_LOOPBACK_INTERNAL_SUPPORTED   1

+#define PXE_LOOPBACK_EXTERNAL_SUPPORTED   2

+

+typedef struct s_pxe_pci_config_info {

+  //

+  // This is the flag field for the PXE_DB_GET_CONFIG_INFO union.

+  // For PCI bus devices, this field is set to PXE_BUSTYPE_PCI.

+  //

+  UINT32  BusType;

+

+  //

+  // This identifies the PCI network device that this UNDI interface

+  // is bound to.

+  //

+  UINT16  Bus;

+  UINT8   Device;

+  UINT8   Function;

+

+  //

+  // This is a copy of the PCI configuration space for this

+  // network device.

+  //

+  union {

+    UINT8   Byte[256];

+    UINT16  Word[128];

+    UINT32  Dword[64];

+  } Config;

+} PXE_PCI_CONFIG_INFO;

+

+typedef struct s_pxe_pcc_config_info {

+  //

+  // This is the flag field for the PXE_DB_GET_CONFIG_INFO union.

+  // For PCC bus devices, this field is set to PXE_BUSTYPE_PCC.

+  //

+  PXE_UINT32  BusType;

+

+  //

+  // This identifies the PCC network device that this UNDI interface

+  // is bound to.

+  //

+  PXE_UINT16  Bus;

+  PXE_UINT8   Device;

+  PXE_UINT8   Function;

+

+  //

+  // This is a copy of the PCC configuration space for this

+  // network device.

+  //

+  union {

+    PXE_UINT8   Byte[256];

+    PXE_UINT16  Word[128];

+    PXE_UINT32  Dword[64];

+  } Config;

+} PXE_PCC_CONFIG_INFO;

+

+typedef union u_pxe_db_get_config_info {

+  PXE_PCI_CONFIG_INFO   pci;

+  PXE_PCC_CONFIG_INFO   pcc;

+} PXE_DB_GET_CONFIG_INFO;

+

+typedef struct s_pxe_cpb_initialize {

+  //

+  // Address of first (lowest) byte of the memory buffer.  This buffer must

+  // be in contiguous physical memory and cannot be swapped out.  The UNDI

+  // will be using this for transmit and receive buffering.

+  //

+  PXE_UINT64  MemoryAddr;

+

+  //

+  // MemoryLength must be greater than or equal to MemoryRequired

+  // returned by the Get Init Info command.

+  //

+  PXE_UINT32  MemoryLength;

+

+  //

+  // Desired link speed in Mbit/sec.  Common ethernet values are 10, 100

+  // and 1000.  Setting a value of zero will auto-detect and/or use the

+  // default link speed (operation depends on UNDI/NIC functionality).

+  //

+  PXE_UINT32  LinkSpeed;

+

+  //

+  // Suggested number and size of receive and transmit buffers to

+  // allocate.  If MemoryAddr and MemoryLength are non-zero, this

+  // allocation comes out of the supplied memory buffer.  If MemoryAddr

+  // and MemoryLength are zero, this allocation comes out of memory

+  // on the NIC.

+  //

+  // If these fields are set to zero, the UNDI will allocate buffer

+  // counts and sizes as it sees fit.

+  //

+  PXE_UINT16  TxBufCnt;

+  PXE_UINT16  TxBufSize;

+  PXE_UINT16  RxBufCnt;

+  PXE_UINT16  RxBufSize;

+

+  //

+  // The following configuration parameters are optional and must be zero

+  // to use the default values.

+  //

+  PXE_UINT8   DuplexMode;

+

+  PXE_UINT8   LoopBackMode;

+} PXE_CPB_INITIALIZE;

+

+#define PXE_DUPLEX_DEFAULT      0x00

+#define PXE_FORCE_FULL_DUPLEX   0x01

+#define PXE_ENABLE_FULL_DUPLEX  0x02

+#define PXE_FORCE_HALF_DUPLEX   0x04

+#define PXE_DISABLE_FULL_DUPLEX 0x08

+

+#define LOOPBACK_NORMAL         0

+#define LOOPBACK_INTERNAL       1

+#define LOOPBACK_EXTERNAL       2

+

+typedef struct s_pxe_db_initialize {

+  //

+  // Actual amount of memory used from the supplied memory buffer.  This

+  // may be less that the amount of memory suppllied and may be zero if

+  // the UNDI and network device do not use external memory buffers.

+  //

+  // Memory used by the UNDI and network device is allocated from the

+  // lowest memory buffer address.

+  //

+  PXE_UINT32  MemoryUsed;

+

+  //

+  // Actual number and size of receive and transmit buffers that were

+  // allocated.

+  //

+  PXE_UINT16  TxBufCnt;

+  PXE_UINT16  TxBufSize;

+  PXE_UINT16  RxBufCnt;

+  PXE_UINT16  RxBufSize;

+} PXE_DB_INITIALIZE;

+

+typedef struct s_pxe_cpb_receive_filters {

+  //

+  // List of multicast MAC addresses.  This list, if present, will

+  // replace the existing multicast MAC address filter list.

+  //

+  PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];

+} PXE_CPB_RECEIVE_FILTERS;

+

+typedef struct s_pxe_db_receive_filters {

+  //

+  // Filtered multicast MAC address list.

+  //

+  PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];

+} PXE_DB_RECEIVE_FILTERS;

+

+typedef struct s_pxe_cpb_station_address {

+  //

+  // If supplied and supported, the current station MAC address

+  // will be changed.

+  //

+  PXE_MAC_ADDR  StationAddr;

+} PXE_CPB_STATION_ADDRESS;

+

+typedef struct s_pxe_dpb_station_address {

+  //

+  // Current station MAC address.

+  //

+  PXE_MAC_ADDR  StationAddr;

+

+  //

+  // Station broadcast MAC address.

+  //

+  PXE_MAC_ADDR  BroadcastAddr;

+

+  //

+  // Permanent station MAC address.

+  //

+  PXE_MAC_ADDR  PermanentAddr;

+} PXE_DB_STATION_ADDRESS;

+

+typedef struct s_pxe_db_statistics {

+  //

+  // Bit field identifying what statistic data is collected by the

+  // UNDI/NIC.

+  // If bit 0x00 is set, Data[0x00] is collected.

+  // If bit 0x01 is set, Data[0x01] is collected.

+  // If bit 0x20 is set, Data[0x20] is collected.

+  // If bit 0x21 is set, Data[0x21] is collected.

+  // Etc.

+  //

+  PXE_UINT64  Supported;

+

+  //

+  // Statistic data.

+  //

+  PXE_UINT64  Data[64];

+} PXE_DB_STATISTICS;

+

+//

+// Total number of frames received.  Includes frames with errors and

+// dropped frames.

+//

+#define PXE_STATISTICS_RX_TOTAL_FRAMES  0x00

+

+//

+// Number of valid frames received and copied into receive buffers.

+//

+#define PXE_STATISTICS_RX_GOOD_FRAMES 0x01

+

+//

+// Number of frames below the minimum length for the media.

+// This would be <64 for ethernet.

+//

+#define PXE_STATISTICS_RX_UNDERSIZE_FRAMES  0x02

+

+//

+// Number of frames longer than the maxminum length for the

+// media.  This would be >1500 for ethernet.

+//

+#define PXE_STATISTICS_RX_OVERSIZE_FRAMES 0x03

+

+//

+// Valid frames that were dropped because receive buffers were full.

+//

+#define PXE_STATISTICS_RX_DROPPED_FRAMES  0x04

+

+//

+// Number of valid unicast frames received and not dropped.

+//

+#define PXE_STATISTICS_RX_UNICAST_FRAMES  0x05

+

+//

+// Number of valid broadcast frames received and not dropped.

+//

+#define PXE_STATISTICS_RX_BROADCAST_FRAMES  0x06

+

+//

+// Number of valid mutlicast frames received and not dropped.

+//

+#define PXE_STATISTICS_RX_MULTICAST_FRAMES  0x07

+

+//

+// Number of frames w/ CRC or alignment errors.

+//

+#define PXE_STATISTICS_RX_CRC_ERROR_FRAMES  0x08

+

+//

+// Total number of bytes received.  Includes frames with errors

+// and dropped frames.

+//

+#define PXE_STATISTICS_RX_TOTAL_BYTES 0x09

+

+//

+// Transmit statistics.

+//

+#define PXE_STATISTICS_TX_TOTAL_FRAMES      0x0A

+#define PXE_STATISTICS_TX_GOOD_FRAMES       0x0B

+#define PXE_STATISTICS_TX_UNDERSIZE_FRAMES  0x0C

+#define PXE_STATISTICS_TX_OVERSIZE_FRAMES   0x0D

+#define PXE_STATISTICS_TX_DROPPED_FRAMES    0x0E

+#define PXE_STATISTICS_TX_UNICAST_FRAMES    0x0F

+#define PXE_STATISTICS_TX_BROADCAST_FRAMES  0x10

+#define PXE_STATISTICS_TX_MULTICAST_FRAMES  0x11

+#define PXE_STATISTICS_TX_CRC_ERROR_FRAMES  0x12

+#define PXE_STATISTICS_TX_TOTAL_BYTES       0x13

+

+//

+// Number of collisions detection on this subnet.

+//

+#define PXE_STATISTICS_COLLISIONS 0x14

+

+//

+// Number of frames destined for unsupported protocol.

+//

+#define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15

+

+typedef struct s_pxe_cpb_mcast_ip_to_mac {

+  //

+  // Multicast IP address to be converted to multicast MAC address.

+  //

+  PXE_IP_ADDR IP;

+} PXE_CPB_MCAST_IP_TO_MAC;

+

+typedef struct s_pxe_db_mcast_ip_to_mac {

+  //

+  // Multicast MAC address.

+  //

+  PXE_MAC_ADDR  MAC;

+} PXE_DB_MCAST_IP_TO_MAC;

+

+typedef struct s_pxe_cpb_nvdata_sparse {

+  //

+  // NvData item list.  Only items in this list will be updated.

+  //

+  struct {

+    //

+    //  Non-volatile storage address to be changed.

+    //

+    PXE_UINT32  Addr;

+

+    //

+    // Data item to write into above storage address.

+    //

+    union {

+      PXE_UINT8   Byte;

+      PXE_UINT16  Word;

+      PXE_UINT32  Dword;

+    } Data;

+  } Item[MAX_EEPROM_LEN];

+}

+PXE_CPB_NVDATA_SPARSE;

+

+//

+// When using bulk update, the size of the CPB structure must be

+// the same size as the non-volatile NIC storage.

+//

+typedef union u_pxe_cpb_nvdata_bulk {

+  //

+  // Array of byte-wide data items.

+  //

+  PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];

+

+  //

+  // Array of word-wide data items.

+  //

+  PXE_UINT16  Word[MAX_EEPROM_LEN << 1];

+

+  //

+  // Array of dword-wide data items.

+  //

+  PXE_UINT32  Dword[MAX_EEPROM_LEN];

+} PXE_CPB_NVDATA_BULK;

+

+typedef struct s_pxe_db_nvdata {

+  //

+  // Arrays of data items from non-volatile storage.

+  //

+  union {

+    //

+    // Array of byte-wide data items.

+    //

+    PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];

+

+    //

+    // Array of word-wide data items.

+    //

+    PXE_UINT16  Word[MAX_EEPROM_LEN << 1];

+

+    //

+    // Array of dword-wide data items.

+    //

+    PXE_UINT32  Dword[MAX_EEPROM_LEN];

+  } Data;

+} PXE_DB_NVDATA;

+

+typedef struct s_pxe_db_get_status {

+  //

+  // Length of next receive frame (header + data).  If this is zero,

+  // there is no next receive frame available.

+  //

+  PXE_UINT32  RxFrameLen;

+

+  //

+  // Reserved, set to zero.

+  //

+  PXE_UINT32  reserved;

+

+  //

+  //  Addresses of transmitted buffers that need to be recycled.

+  //

+  PXE_UINT64  TxBuffer[MAX_XMIT_BUFFERS];

+} PXE_DB_GET_STATUS;

+

+typedef struct s_pxe_cpb_fill_header {

+  //

+  // Source and destination MAC addresses.  These will be copied into

+  // the media header without doing byte swapping.

+  //

+  PXE_MAC_ADDR  SrcAddr;

+  PXE_MAC_ADDR  DestAddr;

+

+  //

+  // Address of first byte of media header.  The first byte of packet data

+  // follows the last byte of the media header.

+  //

+  PXE_UINT64        MediaHeader;

+

+  //

+  // Length of packet data in bytes (not including the media header).

+  //

+  PXE_UINT32        PacketLen;

+

+  //

+  // Protocol type.  This will be copied into the media header without

+  // doing byte swapping.  Protocol type numbers can be obtained from

+  // the Assigned Numbers RFC 1700.

+  //

+  PXE_UINT16        Protocol;

+

+  //

+  // Length of the media header in bytes.

+  //

+  PXE_UINT16        MediaHeaderLen;

+} PXE_CPB_FILL_HEADER;

+

+#define PXE_PROTOCOL_ETHERNET_IP  0x0800

+#define PXE_PROTOCOL_ETHERNET_ARP 0x0806

+#define MAX_XMIT_FRAGMENTS        16

+

+typedef struct s_pxe_cpb_fill_header_fragmented {

+  //

+  // Source and destination MAC addresses.  These will be copied into

+  // the media header without doing byte swapping.

+  //

+  PXE_MAC_ADDR        SrcAddr;

+  PXE_MAC_ADDR        DestAddr;

+

+  //

+  // Length of packet data in bytes (not including the media header).

+  //

+  PXE_UINT32          PacketLen;

+

+  //

+  // Protocol type.  This will be copied into the media header without

+  // doing byte swapping.  Protocol type numbers can be obtained from

+  // the Assigned Numbers RFC 1700.

+  //

+  PXE_MEDIA_PROTOCOL  Protocol;

+

+  //

+  // Length of the media header in bytes.

+  //

+  PXE_UINT16          MediaHeaderLen;

+

+  //

+  // Number of packet fragment descriptors.

+  //

+  PXE_UINT16          FragCnt;

+

+  //

+  // Reserved, must be set to zero.

+  //

+  PXE_UINT16          reserved;

+

+  //

+  // Array of packet fragment descriptors.  The first byte of the media

+  // header is the first byte of the first fragment.

+  //

+  struct {

+    //

+    // Address of this packet fragment.

+    //

+    PXE_UINT64  FragAddr;

+

+    //

+    // Length of this packet fragment.

+    //

+    PXE_UINT32  FragLen;

+

+    //

+    // Reserved, must be set to zero.

+    //

+    PXE_UINT32  reserved;

+  } FragDesc[MAX_XMIT_FRAGMENTS];

+}

+PXE_CPB_FILL_HEADER_FRAGMENTED;

+

+typedef struct s_pxe_cpb_transmit {

+  //

+  // Address of first byte of frame buffer.  This is also the first byte

+  // of the media header.

+  //

+  PXE_UINT64  FrameAddr;

+

+  //

+  // Length of the data portion of the frame buffer in bytes.  Do not

+  // include the length of the media header.

+  //

+  PXE_UINT32  DataLen;

+

+  //

+  // Length of the media header in bytes.

+  //

+  PXE_UINT16  MediaheaderLen;

+

+  //

+  // Reserved, must be zero.

+  //

+  PXE_UINT16  reserved;

+} PXE_CPB_TRANSMIT;

+

+typedef struct s_pxe_cpb_transmit_fragments {

+  //

+  // Length of packet data in bytes (not including the media header).

+  //

+  PXE_UINT32  FrameLen;

+

+  //

+  // Length of the media header in bytes.

+  //

+  PXE_UINT16  MediaheaderLen;

+

+  //

+  // Number of packet fragment descriptors.

+  //

+  PXE_UINT16  FragCnt;

+

+  //

+  // Array of frame fragment descriptors.  The first byte of the first

+  // fragment is also the first byte of the media header.

+  //

+  struct {

+    //

+    // Address of this frame fragment.

+    //

+    PXE_UINT64  FragAddr;

+

+    //

+    // Length of this frame fragment.

+    //

+    PXE_UINT32  FragLen;

+

+    //

+    // Reserved, must be set to zero.

+    //

+    PXE_UINT32  reserved;

+  } FragDesc[MAX_XMIT_FRAGMENTS];

+}

+PXE_CPB_TRANSMIT_FRAGMENTS;

+

+typedef struct s_pxe_cpb_receive {

+  //

+  // Address of first byte of receive buffer.  This is also the first byte

+  // of the frame header.

+  //

+  PXE_UINT64  BufferAddr;

+

+  //

+  // Length of receive buffer.  This must be large enough to hold the

+  // received frame (media header + data).  If the length of smaller than

+  // the received frame, data will be lost.

+  //

+  PXE_UINT32  BufferLen;

+

+  //

+  // Reserved, must be set to zero.

+  //

+  PXE_UINT32  reserved;

+} PXE_CPB_RECEIVE;

+

+typedef struct s_pxe_db_receive {

+  //

+  // Source and destination MAC addresses from media header.

+  //

+  PXE_MAC_ADDR        SrcAddr;

+  PXE_MAC_ADDR        DestAddr;

+

+  //

+  // Length of received frame.  May be larger than receive buffer size.

+  // The receive buffer will not be overwritten.  This is how to tell

+  // if data was lost because the receive buffer was too small.

+  //

+  PXE_UINT32          FrameLen;

+

+  //

+  // Protocol type from media header.

+  //

+  PXE_MEDIA_PROTOCOL  Protocol;

+

+  //

+  // Length of media header in received frame.

+  //

+  PXE_UINT16          MediaHeaderLen;

+

+  //

+  // Type of receive frame.

+  //

+  PXE_FRAME_TYPE      Type;

+

+  //

+  // Reserved, must be zero.

+  //

+  PXE_UINT8           reserved[7];

+

+} PXE_DB_RECEIVE;

+

+#pragma pack()

+

+#endif

diff --git a/edk2/MdePkg/Include/Uefi/Errors.h b/edk2/MdePkg/Include/Uefi/Errors.h
new file mode 100644
index 0000000..fd1dc02
--- /dev/null
+++ b/edk2/MdePkg/Include/Uefi/Errors.h
@@ -0,0 +1,24 @@
+/** @file

+  Include file that supportes UEFI Error Codes.

+  

+  This include file must only contain things defined in the UEFI 2.0 specification.

+  

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+  

+  Module Name: UefiErrors.h

+  

+**/

+

+#ifndef __UEFI_ERRORS_H__

+#define __UEFI_ERRORS_H__

+

+

+

+#endif

diff --git a/edk2/MdePkg/Include/Uefi/UefiSpec.h b/edk2/MdePkg/Include/Uefi/UefiSpec.h
new file mode 100644
index 0000000..d648b1b
--- /dev/null
+++ b/edk2/MdePkg/Include/Uefi/UefiSpec.h
@@ -0,0 +1,2460 @@
+/** @file

+  Include file that supportes UEFI.

+  

+  This include file must only contain things defined in the UEFI 2.0 specification.

+  If a code construct is defined in the UEFI 2.0 specification it must be included

+  by this include file.

+  

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+  

+  Module Name:    UefiSpec.h

+  

+**/

+

+#ifndef __UEFI_SPEC_H__

+#define __UEFI_SPEC_H__

+

+#include <Common/MultiPhase.h>

+

+//

+// EFI Data Types based on ANSI C integer types in EfiBind.h

+//

+

+

+//

+// EFI Data Types derived from other EFI data types.

+//

+

+#define NULL_HANDLE ((VOID *) 0)

+

+typedef VOID *EFI_EVENT;

+typedef UINTN EFI_TPL;

+

+//

+// EFI Time Abstraction:

+//  Year:       2000 - 20XX

+//  Month:      1 - 12

+//  Day:        1 - 31

+//  Hour:       0 - 23

+//  Minute:     0 - 59

+//  Second:     0 - 59

+//  Nanosecond: 0 - 999,999,999

+//  TimeZone:   -1440 to 1440 or 2047

+//

+typedef struct {

+  UINT16  Year;

+  UINT8   Month;

+  UINT8   Day;

+  UINT8   Hour;

+  UINT8   Minute;

+  UINT8   Second;

+  UINT8   Pad1;

+  UINT32  Nanosecond;

+  INT16   TimeZone;

+  UINT8   Daylight;

+  UINT8   Pad2;

+} EFI_TIME;

+

+//

+// Bit definitions for EFI_TIME.Daylight

+//

+#define EFI_TIME_ADJUST_DAYLIGHT  0x01

+#define EFI_TIME_IN_DAYLIGHT      0x02

+

+//

+// Value definition for EFI_TIME.TimeZone

+//

+#define EFI_UNSPECIFIED_TIMEZONE  0x07FF

+

+//

+// Networking

+//

+typedef struct {

+  UINT8 Addr[4];

+} EFI_IPv4_ADDRESS;

+

+typedef struct {

+  UINT8 Addr[16];

+} EFI_IPv6_ADDRESS;

+

+typedef struct {

+  UINT8 Addr[32];

+} EFI_MAC_ADDRESS;

+

+typedef union {

+  UINT32            Addr[4];

+  EFI_IPv4_ADDRESS  v4;

+  EFI_IPv6_ADDRESS  v6;

+} EFI_IP_ADDRESS;

+

+

+typedef enum {

+  AllocateAnyPages,

+  AllocateMaxAddress,

+  AllocateAddress,

+  MaxAllocateType

+} EFI_ALLOCATE_TYPE;

+

+

+//

+// possible caching types for the memory range

+//

+#define EFI_MEMORY_UC   0x0000000000000001ULL

+#define EFI_MEMORY_WC   0x0000000000000002ULL

+#define EFI_MEMORY_WT   0x0000000000000004ULL

+#define EFI_MEMORY_WB   0x0000000000000008ULL

+#define EFI_MEMORY_UCE  0x0000000000000010ULL

+

+//

+// physical memory protection on range

+//

+#define EFI_MEMORY_WP 0x0000000000001000ULL

+#define EFI_MEMORY_RP 0x0000000000002000ULL

+#define EFI_MEMORY_XP 0x0000000000004000ULL

+

+//

+// range requires a runtime mapping

+//

+#define EFI_MEMORY_RUNTIME  0x8000000000000000ULL

+

+typedef UINT64  EFI_VIRTUAL_ADDRESS;

+

+#define EFI_MEMORY_DESCRIPTOR_VERSION 1

+typedef struct {

+  UINT32                Type;

+  UINT32                Pad;

+  EFI_PHYSICAL_ADDRESS  PhysicalStart;

+  EFI_VIRTUAL_ADDRESS   VirtualStart;

+  UINT64                NumberOfPages;

+  UINT64                Attribute;

+} EFI_MEMORY_DESCRIPTOR;

+

+//

+//  EFI_FIELD_OFFSET - returns the byte offset to a field within a structure

+//

+#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))

+

+#include <Protocol/DevicePath.h>

+#include <Protocol/SimpleTextIn.h>

+#include <Protocol/SimpleTextOut.h>

+

+//

+// Declare forward referenced data structures

+//

+typedef struct  _EFI_SYSTEM_TABLE   EFI_SYSTEM_TABLE;

+

+/**

+  Allocates memory pages from the system.

+  

+  @param  Type        The type of allocation to perform.

+  @param  MemoryType  The type of memory to allocate.

+  @param  Pages       The number of contiguous 4 KB pages to allocate.

+  @param  Memory      Pointer to a physical address. On input, the way in which the address is

+                      used depends on the value of Type.          

+                     

+  @retval EFI_SUCCESS           The requested pages were allocated.

+  @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or

+                                AllocateMaxAddress or AllocateAddress.

+                                2) MemoryType is in the range

+                                EfiMaxMemoryType..0x7FFFFFFF.

+  @retval EFI_OUT_OF_RESOURCES  The pages could not be allocated.

+  @retval EFI_NOT_FOUND         The requested pages could not be found.

+                     

+**/                  

+typedef              

+EFI_STATUS           

+(EFIAPI *EFI_ALLOCATE_PAGES) (

+  IN EFI_ALLOCATE_TYPE            Type,

+  IN EFI_MEMORY_TYPE              MemoryType,

+  IN UINTN                        Pages,

+  IN OUT EFI_PHYSICAL_ADDRESS     *Memory

+  );

+

+/**

+  Frees memory pages.

+    

+  @param  Memory      The base physical address of the pages to be freed.

+  @param  Pages       The number of contiguous 4 KB pages to free.

+                               

+  @retval EFI_SUCCESS           The requested pages were freed.

+  @retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.    

+  @retval EFI_NOT_FOUND         The requested memory pages were not allocated with

+                                AllocatePages().

+                     

+**/          

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FREE_PAGES) (

+  IN EFI_PHYSICAL_ADDRESS         Memory,

+  IN UINTN                        Pages

+  );

+

+/**

+  Returns the current memory map.

+    

+  @param  MemoryMapSize         A pointer to the size, in bytes, of the MemoryMap buffer.

+  @param  MemoryMap             A pointer to the buffer in which firmware places the current memory

+                                map.

+  @param  MapKey                A pointer to the location in which firmware returns the key for the

+                                current memory map.                                                

+  @param  DescriptorSize        A pointer to the location in which firmware returns the size, in bytes, of

+                                an individual EFI_MEMORY_DESCRIPTOR.                                      

+  @param  DescriptorVersion     A pointer to the location in which firmware returns the version number

+                                associated with the EFI_MEMORY_DESCRIPTOR. 

+                                                                 

+  @retval EFI_SUCCESS           The memory map was returned in the MemoryMap buffer.

+  @retval EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small. The current buffer size

+                                needed to hold the memory map is returned in MemoryMapSize.

+  @retval EFI_INVALID_PARAMETER 1) MemoryMapSize is NULL.

+                                2) The MemoryMap buffer is not too small and MemoryMap is

+                                   NULL.                                                 

+                     

+**/          

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_MEMORY_MAP) (

+  IN OUT UINTN                    *MemoryMapSize,

+  IN OUT EFI_MEMORY_DESCRIPTOR    *MemoryMap,

+  OUT UINTN                       *MapKey,

+  OUT UINTN                       *DescriptorSize,

+  OUT UINT32                      *DescriptorVersion

+  );

+

+#define NextMemoryDescriptor(_Ptr, _Size)   ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) (_Ptr)) + (_Size)))

+#define NEXT_MEMORY_DESCRIPTOR(_Ptr, _Size) NextMemoryDescriptor (_Ptr, _Size)

+

+/**

+  Allocates pool memory.

+    

+  @param  PoolType              The type of pool to allocate.

+  @param  Size                  The number of bytes to allocate from the pool.                                

+  @param  Buffer                A pointer to a pointer to the allocated buffer if the call succeeds;

+                                undefined otherwise.                                

+                                                                 

+  @retval EFI_SUCCESS           The requested number of bytes was allocated.

+  @retval EFI_OUT_OF_RESOURCES  The pool requested could not be allocated.                                

+  @retval EFI_INVALID_PARAMETER PoolType was invalid.                                

+                     

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_ALLOCATE_POOL) (

+  IN EFI_MEMORY_TYPE              PoolType,

+  IN UINTN                        Size,

+  OUT VOID                        **Buffer

+  );

+

+/**

+  Returns pool memory to the system.

+    

+  @param  Buffer                Pointer to the buffer to free.                                                             

+                                                                 

+  @retval EFI_SUCCESS           The memory was returned to the system.  

+  @retval EFI_INVALID_PARAMETER Buffer was invalid.

+                     

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_FREE_POOL) (

+  IN VOID                         *Buffer

+  );

+

+/**

+  Changes the runtime addressing mode of EFI firmware from physical to virtual.

+    

+  @param  MemoryMapSize         The size in bytes of VirtualMap.

+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.

+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.

+  @param  VirtualMap            An array of memory descriptors which contain new virtual

+                                address mapping information for all runtime ranges.

+                                                                 

+  @retval EFI_SUCCESS           The virtual address map has been applied.

+  @retval EFI_UNSUPPORTED       EFI firmware is not at runtime, or the EFI firmware is already in

+                                virtual address mapped mode.                                     

+  @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid.                              

+  @retval EFI_NO_MAPPING        A virtual address was not supplied for a range in the memory

+                                map that requires a mapping.                                

+  @retval EFI_NOT_FOUND         A virtual address was supplied for an address that is not found

+                                in the memory map.                                             

+                                

+**/                             

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) (

+  IN UINTN                        MemoryMapSize,

+  IN UINTN                        DescriptorSize,

+  IN UINT32                       DescriptorVersion,

+  IN EFI_MEMORY_DESCRIPTOR        *VirtualMap

+  );

+

+/**

+  Connects one or more drivers to a controller.

+    

+  @param  ControllerHandle      The handle of the controller to which driver(s) are to be connected.

+  @param  DriverImageHandle     A pointer to an ordered list handles that support the

+                                EFI_DRIVER_BINDING_PROTOCOL.                         

+  @param  RemainingDevicePath   A pointer to the device path that specifies a child of the

+                                controller specified by ControllerHandle.                 

+  @param  Recursive             If TRUE, then ConnectController() is called recursively            

+                                until the entire tree of controllers below the controller specified

+                                by ControllerHandle have been created. If FALSE, then              

+                                the tree of controllers is only expanded one level.                                                                                                               

+                                

+  @retval EFI_SUCCESS           1) One or more drivers were connected to ControllerHandle.

+                                2) No drivers were connected to ControllerHandle, but      

+                                RemainingDevicePath is not NULL, and it is an End Device

+                                Path Node.                                                                                                                  

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.       

+  @retval EFI_NOT_FOUND         1) There are no EFI_DRIVER_BINDING_PROTOCOL instances

+                                present in the system.                            

+                                2) No drivers were connected to ControllerHandle.

+                                

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CONNECT_CONTROLLER) (

+  IN  EFI_HANDLE                    ControllerHandle,

+  IN  EFI_HANDLE                    *DriverImageHandle,   OPTIONAL

+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath, OPTIONAL

+  IN  BOOLEAN                       Recursive

+  );

+

+/**

+  Disconnects one or more drivers from a controller.

+    

+  @param  ControllerHandle      The handle of the controller from which driver(s) are to be disconnected.

+  @param  DriverImageHandle     The driver to disconnect from ControllerHandle.                       

+  @param  ChildHandle           The handle of the child to destroy.                                

+                                

+  @retval EFI_SUCCESS           1) One or more drivers were disconnected from the controller.

+                                2) On entry, no drivers are managing ControllerHandle.

+                                3) DriverImageHandle is not NULL, and on entry

+                                   DriverImageHandle is not managing ControllerHandle.

+                                   

+  @retval EFI_INVALID_PARAMETER One ore more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to disconnect any drivers from

+                                ControllerHandle.                                                      

+  @retval EFI_DEVICE_ERROR      The controller could not be disconnected because of a device error.  

+                                

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_DISCONNECT_CONTROLLER) (

+  IN EFI_HANDLE                     ControllerHandle,

+  IN EFI_HANDLE                     DriverImageHandle, OPTIONAL

+  IN EFI_HANDLE                     ChildHandle        OPTIONAL

+  );

+

+//

+// ConvertPointer DebugDisposition type.

+//

+#define EFI_OPTIONAL_PTR     0x00000001

+#define EFI_OPTIONAL_POINTER EFI_OPTIONAL_PTR

+

+/**

+  Determines the new virtual address that is to be used on subsequent memory accesses.

+    

+  @param  DebugDisposition      Supplies type information for the pointer being converted.

+  @param  Address               A pointer to a pointer that is to be fixed to be the value needed

+                                for the new virtual address mappings being applied.                              

+                                

+  @retval EFI_SUCCESS           The pointer pointed to by Address was modified.                                                                   

+  @retval EFI_INVALID_PARAMETER 1) Address is NULL.

+                                2) *Address is NULL and DebugDisposition does

+                                not have the EFI_OPTIONAL_PTR bit set.    

+  @retval EFI_NOT_FOUND         The pointer pointed to by Address was not found to be part

+                                of the current memory map. This is normally fatal.          

+                                

+**/ 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CONVERT_POINTER) (

+  IN UINTN                          DebugDisposition,

+  IN OUT VOID                       **Address

+  );

+

+//

+// EFI Event Types (name defined in spec)

+//

+#define EVENT_TIMER                             0x80000000

+#define EVENT_RUNTIME                           0x40000000

+#define EVENT_RUNTIME_CONTEXT                   0x20000000

+

+#define EVENT_NOTIFY_WAIT                       0x00000100

+#define EVENT_NOTIFY_SIGNAL                     0x00000200

+

+#define EVENT_SIGNAL_EXIT_BOOT_SERVICES         0x00000201

+#define EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE     0x60000202

+

+#if ((EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000))

+//

+// Prior to UEFI 2.0 Tiano extended these enums. This was replaced by

+// CreateEventEx() Event Groups in UEFI 2.0

+//

+#define EFI_EVENT_NOTIFY_SIGNAL_ALL     0x00000400

+

+#define EFI_EVENT_SIGNAL_READY_TO_BOOT  0x00000203

+#define EFI_EVENT_SIGNAL_LEGACY_BOOT    0x00000204

+

+#endif

+

+//

+// EFI Event Types (name following coding style)

+//

+#define EFI_EVENT_TIMER                         EVENT_TIMER

+#define EFI_EVENT_RUNTIME                       EVENT_RUNTIME

+#define EFI_EVENT_RUNTIME_CONTEXT               EVENT_RUNTIME_CONTEXT

+

+#define EFI_EVENT_NOTIFY_WAIT                   EVENT_NOTIFY_WAIT

+#define EFI_EVENT_NOTIFY_SIGNAL                 EVENT_NOTIFY_SIGNAL

+

+#define EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES     EVENT_SIGNAL_EXIT_BOOT_SERVICES

+#define EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE

+

+

+/**                                                                                                   

+  Invoke a notification event

+                                                                                                      

+  @param  Event                 Event whose notification function is being invoked.

+  @param  Context               Pointer to the notification function¡¯s context, 

+                                which is implementation-dependent.                                                  

+                                                                                                      

+**/                                                                                                   

+typedef

+VOID

+(EFIAPI *EFI_EVENT_NOTIFY) (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  );

+

+/**                                                                                                   

+  Creates an event.

+                                                                                                      

+  @param  Type                  The type of event to create and its mode and attributes.

+  @param  NotifyTpl             Pointer to the notification function¡¯s context.

+  @param  NotifyFunction        Pointer to the event¡¯s notification function, if any.  

+  @param  NotifyContext         Pointer to the notification function¡¯s context; corresponds to parameter

+                                Context in the notification function.                                                                                                          

+  @param  Event                 Pointer to the newly created event if the call succeeds; undefined  

+                                otherwise.                                                          

+

+  @retval EFI_SUCCESS           The event structure was created.                    

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The event could not be allocated.

+  

+**/                                                                                   

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CREATE_EVENT) (

+  IN UINT32                       Type,

+  IN EFI_TPL                      NotifyTpl,

+  IN EFI_EVENT_NOTIFY             NotifyFunction,

+  IN VOID                         *NotifyContext,

+  OUT EFI_EVENT                   *Event

+  );

+

+/**                                                                                                   

+  Creates an event in a group.

+                                                                                                      

+  @param  Type                  The type of event to create and its mode and attributes.

+  @param  NotifyTpl             Pointer to the notification function¡¯s context.

+  @param  NotifyFunction        Pointer to the event¡¯s notification function, if any.  

+  @param  NotifyContext         Pointer to the notification function¡¯s context; corresponds to parameter

+                                Context in the notification function.          

+  @param  EventGroup            Pointer to the unique identifier of the group to which this event belongs.                                                                                                                                

+  @param  Event                 Pointer to the newly created event if the call succeeds; undefined  

+                                otherwise.                                                          

+

+  @retval EFI_SUCCESS           The event structure was created.                    

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The event could not be allocated.

+  

+**/                 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CREATE_EVENT_EX) (

+  IN UINT32                 Type,

+  IN EFI_TPL                NotifyTpl      OPTIONAL,

+  IN EFI_EVENT_NOTIFY       NotifyFunction OPTIONAL,

+  IN CONST VOID             *NotifyContext OPTIONAL,

+  IN CONST EFI_GUID         *EventGroup    OPTIONAL,

+  OUT EFI_EVENT             *Event

+  );

+

+typedef enum {

+  TimerCancel,

+  TimerPeriodic,

+  TimerRelative

+} EFI_TIMER_DELAY;

+

+/**                                                 

+  Sets the type of timer and the trigger time for a timer event.

+                                                    

+  @param  Event                 The timer event that is to be signaled at the specified time.

+  @param  Type                  The type of time that is specified in TriggerTime.

+  @param  TriggerTime           The number of 100ns units until the timer expires.  

+

+  @retval EFI_SUCCESS           The event has been set to be signaled at the requested time.  

+  @retval EFI_INVALID_PARAMETER Event or Type is not valid.

+  

+**/         

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_TIMER) (

+  IN EFI_EVENT                Event,

+  IN EFI_TIMER_DELAY          Type,

+  IN UINT64                   TriggerTime

+  );

+

+/**                                                                                                   

+  Signals an event.

+                                                                                                       

+  @param  Event                 The event to signal.

+

+  @retval EFI_SUCCESS           The event has been signaled.  

+  

+**/                 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SIGNAL_EVENT) (

+  IN EFI_EVENT                Event

+  );

+

+/**                                                                                                   

+  Stops execution until an event is signaled.

+                                                                                                       

+  @param  NumberOfEvents        The number of events in the Event array.

+  @param  Event                 An array of EFI_EVENT.

+  @param  Index                 Pointer to the index of the event which satisfied the wait condition.

+

+  @retval EFI_SUCCESS           The event indicated by Index was signaled.

+  @retval EFI_INVALID_PARAMETER 1) NumberOfEvents is 0.

+                                2) The event indicated by Index is of type

+                                   EVT_NOTIFY_SIGNAL.                     

+  @retval EFI_UNSUPPORTED       The current TPL is not TPL_APPLICATION.                                   

+  

+**/          

+typedef

+EFI_STATUS

+(EFIAPI *EFI_WAIT_FOR_EVENT) (

+  IN UINTN                    NumberOfEvents,

+  IN EFI_EVENT                *Event,

+  OUT UINTN                   *Index

+  );

+

+/**                                                                                                   

+  Closes an event.

+                                                                                                       

+  @param  Event                 The event to close.

+

+  @retval EFI_SUCCESS           The event has been closed.  

+  

+**/                 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CLOSE_EVENT) (

+  IN EFI_EVENT                Event

+  );

+

+/**                                                 

+  Checks whether an event is in the signaled state.

+                                                    

+  @param  Event                 The event to check.

+

+  @retval EFI_SUCCESS           The event is in the signaled state.

+  @retval EFI_NOT_READY         The event is not in the signaled state.

+  @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL.

+  

+**/         

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CHECK_EVENT) (

+  IN EFI_EVENT                Event

+  );

+

+//

+// Task priority level (name defined in spec).

+//

+#define TPL_APPLICATION       4

+#define TPL_CALLBACK          8

+#define TPL_NOTIFY            16

+#define TPL_HIGH_LEVEL        31

+

+//

+// Task priority level (name following coding style).

+//

+#define EFI_TPL_APPLICATION   TPL_APPLICATION

+#define EFI_TPL_CALLBACK      TPL_CALLBACK

+#define EFI_TPL_NOTIFY        TPL_NOTIFY

+#define EFI_TPL_HIGH_LEVEL    TPL_HIGH_LEVEL

+

+/**                                                 

+  Raises a task¡¯s priority level and returns its previous level.

+                                                    

+  @param  NewTpl                The new task priority level.

+  

+  @retval                       Previous task priority level  

+  

+**/         

+typedef

+EFI_TPL

+(EFIAPI *EFI_RAISE_TPL) (

+  IN EFI_TPL      NewTpl

+  );

+

+/**                                                 

+  Restores a task¡¯s priority level to its previous value.

+                                                    

+  @param  OldTpl                The previous task priority level to restore    

+  

+**/       

+typedef

+VOID

+(EFIAPI *EFI_RESTORE_TPL) (

+  IN EFI_TPL      OldTpl

+  );

+

+//

+// Variable attributes

+//

+#define EFI_VARIABLE_NON_VOLATILE       0x00000001

+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002

+#define EFI_VARIABLE_RUNTIME_ACCESS     0x00000004

+

+/**                                                 

+  Returns the value of a variable.

+                                                    

+  @param  VariableName          A Null-terminated Unicode string that is the name of the

+                                vendor¡¯s variable.                                     

+  @param  VendorGuid            A unique identifier for the vendor.                    

+  @param  Attributes            If not NULL, a pointer to the memory location to return the

+                                attributes bitmask for the variable.                       

+  @param  DataSize              On input, the size in bytes of the return Data buffer.

+                                On output the size of data returned in Data.          

+  @param  Data                  The buffer to return the contents of the variable.                                

+  

+  @retval EFI_SUCCESS           The function completed successfully.

+  @retval EFI_NOT_FOUND         The variable was not found.

+  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_DEVICE_ERROR      The variable could not be retrieved due to a hardware error.

+  

+**/         

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_VARIABLE) (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  OUT UINT32                      *Attributes,    OPTIONAL

+  IN OUT UINTN                    *DataSize,

+  OUT VOID                        *Data

+  );

+

+/**                                                 

+  Enumerates the current variable names.

+                                                    

+  @param  VariableNameSize      The size of the VariableName buffer.

+  @param  VariableName          On input, supplies the last VariableName that was returned     

+                                by GetNextVariableName(). On output, returns the Nullterminated

+                                Unicode string of the current variable.                                             

+  @param  VendorGuid            On input, supplies the last VendorGuid that was returned by

+                                GetNextVariableName(). On output, returns the              

+                                VendorGuid of the current variable.                          

+  

+  @retval EFI_SUCCESS           The function completed successfully.

+  @retval EFI_NOT_FOUND         The next variable was not found.

+  @retval EFI_BUFFER_TOO_SMALL  The VariableNameSize is too small for the result.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_DEVICE_ERROR      The variable could not be retrieved due to a hardware error.

+  

+**/        

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) (

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  );

+

+/**                                                                                               

+  Sets the value of a variable.

+                                                                                                    

+  @param  VariableName          A Null-terminated Unicode string that is the name of the

+                                vendor¡¯s variable.                                     

+  @param  VendorGuid            A unique identifier for the vendor.                                

+  @param  Attributes            Attributes bitmask to set for the variable.                                

+  @param  DataSize              The size in bytes of the Data buffer.

+  @param  Data                  The contents for the variable.

+                                                                                                  

+  @retval EFI_SUCCESS           The firmware has successfully stored the variable and its data as

+                                defined by the Attributes.                                       

+  @retval EFI_WRITE_PROTECTED   The variable in question is read-only.

+  @retval EFI_OUT_OF_RESOURCES  Not enough storage is available to hold the variable and its data.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                               

+  @retval EFI_DEVICE_ERROR      The variable could not be retrieved due to a hardware error.      

+                                                                                                  

+**/                                                                                               

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_VARIABLE) (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  IN UINT32                       Attributes,

+  IN UINTN                        DataSize,

+  IN VOID                         *Data

+  );

+

+//

+// EFI Time

+//

+typedef struct {

+  UINT32  Resolution;

+  UINT32  Accuracy;

+  BOOLEAN SetsToZero;

+} EFI_TIME_CAPABILITIES;

+

+/**                                                                 

+  Returns the current time and date information, and the time-keeping capabilities 

+  of the hardware platform.

+                                                                    

+  @param  Time                  A pointer to storage to receive a snapshot of the current time.                                

+  @param  Capabilities          An optional pointer to a buffer to receive the real time clock 

+                                device¡¯s capabilities.                                  

+                                                                    

+  @retval EFI_SUCCESS           The operation completed successfully.     

+  @retval EFI_INVALID_PARAMETER Time is NULL.

+  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.

+                                                                    

+**/                                                                 

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_TIME) (

+  OUT EFI_TIME                    *Time,

+  OUT EFI_TIME_CAPABILITIES       *Capabilities OPTIONAL

+  );

+

+/**                                                                 

+  Sets the current local time and date information.

+                                                                    

+  @param  Time                  A pointer to the current time.

+                                                                    

+  @retval EFI_SUCCESS           The operation completed successfully.     

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.

+                                                                    

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_TIME) (

+  IN EFI_TIME                     *Time

+  );

+  

+/**                                                                 

+  Returns the current wakeup alarm clock setting.

+  

+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.

+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.                                                                      

+  @param  Time                  The current alarm setting.

+                                                                    

+  @retval EFI_SUCCESS           The alarm settings were returned.

+  @retval EFI_INVALID_PARAMETER Any parameter is NULL.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.

+                                                                    

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_WAKEUP_TIME) (

+  OUT BOOLEAN                     *Enabled,

+  OUT BOOLEAN                     *Pending,

+  OUT EFI_TIME                    *Time

+  );

+

+/**                                                                 

+  Sets the system wakeup alarm clock time.

+  

+  @param  Enabled               Enable or disable the wakeup alarm.  

+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.

+                                                                    

+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If

+                                Enable is FALSE, then the wakeup alarm was disabled.    

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+                                                                    

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_WAKEUP_TIME) (

+  IN BOOLEAN                      Enable,

+  IN EFI_TIME                     *Time   OPTIONAL

+  );

+

+/**                                                                 

+  This is the declaration of an EFI image entry point. This can be the entry point to an application

+  written to this specification, an EFI boot service driver, or an EFI runtime driver.                

+  

+  @param  ImageHandle           Handle that identifies the loaded image.

+  @param  SystemTable           System Table for this image.

+                                                                    

+  @retval EFI_SUCCESS           The operation completed successfully.                                     

+  

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IMAGE_ENTRY_POINT) (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_SYSTEM_TABLE             *SystemTable

+  );

+

+/**                                                                 

+  Loads an EFI image into memory.

+  

+  @param  BootPolicy            If TRUE, indicates that the request originates from the boot

+                                manager, and that the boot manager is attempting to load    

+                                FilePath as a boot selection. Ignored if SourceBuffer is    

+                                not NULL.                                                   

+  @param  ParentImageHandle     The caller¡¯s image handle.

+  @param  FilePath              The DeviceHandle specific file path from which the image is

+                                loaded.                                                     

+  @param  SourceBuffer          If not NULL, a pointer to the memory location containing a copy

+                                of the image to be loaded.                                     

+  @param  SourceSize            The size in bytes of SourceBuffer.  

+  @param  ImageHandle           Pointer to the returned image handle that is created when the

+                                image is successfully loaded.                                

+                                                                                 

+  @retval EFI_SUCCESS           Image was loaded into memory correctly.

+  @retval EFI_NOT_FOUND         Both SourceBuffer and FilePath are NULL.

+  @retval EFI_INVALID_PARAMETER One or more parametes are invalid.

+  @retval EFI_UNSUPPORTED       The image type is not supported.

+  @retval EFI_OUT_OF_RESOURCES  Image was not loaded due to insufficient resources.

+  @retval EFI_LOAD_ERROR        Image was not loaded because the image format was corrupt or not

+                                understood.                                                     

+  @retval EFI_DEVICE_ERROR      Image was not loaded because the device returned a read error.                          

+  

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IMAGE_LOAD) (

+  IN BOOLEAN                      BootPolicy,

+  IN EFI_HANDLE                   ParentImageHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL     *FilePath,

+  IN VOID                         *SourceBuffer OPTIONAL,

+  IN UINTN                        SourceSize,

+  OUT EFI_HANDLE                  *ImageHandle

+  );

+

+/**                                                                 

+  Transfers control to a loaded image¡¯s entry point.

+  

+  @param  ImageHandle           Handle of image to be started.  

+  @param  ExitDataSize          Pointer to the size, in bytes, of ExitData.

+  @param  ExitData              Pointer to a pointer to a data buffer that includes a Null-terminated

+                                Unicode string, optionally followed by additional binary data.       

+                                                                                  

+  @retval EFI_INVALID_PARAMETER ImageHandle is either an invalid image handle or the image

+                                has already been initialized with StartImage

+  @retval Exit code from image  Exit code from image

+  

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IMAGE_START) (

+  IN EFI_HANDLE                   ImageHandle,

+  OUT UINTN                       *ExitDataSize,

+  OUT CHAR16                      **ExitData    OPTIONAL

+  );

+

+/**                                                                 

+  Terminates a loaded EFI image and returns control to boot services.

+  

+  @param  ImageHandle           Handle that identifies the image.

+  @param  ExitStatus            The image¡¯s exit code.

+  @param  ExitDataSize          The size, in bytes, of ExitData.

+  @param  ExitData              Pointer to a data buffer that includes a Null-terminated Unicode string,                    

+                                optionally followed by additional binary data.                                                                            

+                                

+  @retval EFI_SUCCESS           The image specified by ImageHandle was unloaded.  

+  @retval EFI_INVALID_PARAMETER The image specified by ImageHandle has been loaded and

+                                started with LoadImage() and StartImage(), but the    

+                                image is not the currently executing image.               

+  

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXIT) (

+  IN EFI_HANDLE                   ImageHandle,

+  IN EFI_STATUS                   ExitStatus,

+  IN UINTN                        ExitDataSize,

+  IN CHAR16                       *ExitData     OPTIONAL

+  );

+

+/**                                                                 

+  Unloads an image.

+  

+  @param  ImageHandle           Handle that identifies the image to be unloaded.

+                                

+  @retval EFI_SUCCESS           The image has been unloaded.

+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.

+  @retval EFI_UNSUPPORTED       The image has been started, and does not support unload.

+  @retval                       Exit code from the image's unload handler                                

+  

+**/    

+typedef

+EFI_STATUS

+(EFIAPI *EFI_IMAGE_UNLOAD) (

+  IN EFI_HANDLE                   ImageHandle

+  );

+

+/**                                                                 

+  Terminates all boot services.

+  

+  @param  ImageHandle           Handle that identifies the exiting image.

+  @param  MapKey                Key to the latest memory map.

+                                

+  @retval EFI_SUCCESS           Boot services have been terminated.

+  @retval EFI_INVALID_PARAMETER MapKey is incorrect.  

+  

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_EXIT_BOOT_SERVICES) (

+  IN EFI_HANDLE                   ImageHandle,

+  IN UINTN                        MapKey

+  );

+

+/**                                                                 

+  Induces a fine-grained stall.

+  

+  @param  Microseconds          The number of microseconds to stall execution.  

+                                

+  @retval EFI_SUCCESS           Execution was stalled at least the requested number of

+                                Microseconds.  

+  

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_STALL) (

+  IN UINTN                    Microseconds

+  );

+

+/**                                                                 

+  Sets the system¡¯s watchdog timer.

+  

+  @param  Timeout               The number of seconds to set the watchdog timer to.

+  @param  WatchdogCode          The numeric code to log on a watchdog timer timeout event.

+  @param  DataSize              The size, in bytes, of WatchdogData.

+  @param  WatchdogData          A data buffer that includes a Null-terminated Unicode string, optionally

+                                followed by additional binary data.                                       

+                                

+  @retval EFI_SUCCESS           The timeout has been set.

+  @retval EFI_INVALID_PARAMETER The supplied WatchdogCode is invalid.                               

+  @retval EFI_UNSUPPORTED       The system does not have a watchdog timer.

+  @retval EFI_DEVICE_ERROR      The watch dog timer could not be programmed due to a hardware

+                                error.                                                       

+                                

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SET_WATCHDOG_TIMER) (

+  IN UINTN                    Timeout,

+  IN UINT64                   WatchdogCode,

+  IN UINTN                    DataSize,

+  IN CHAR16                   *WatchdogData OPTIONAL

+  );

+

+typedef enum {

+  EfiResetCold,

+  EfiResetWarm,

+  EfiResetShutdown,

+#if ((EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000))

+  //

+  // Tiano extension for capsules that was removed after UEFI 2.0 came out

+  //

+  EfiResetUpdate

+#endif

+} EFI_RESET_TYPE;

+

+/**                                                                 

+  Resets the entire platform.

+  

+  @param  ResetType             The type of reset to perform.

+  @param  ResetStatus           The status code for the reset.

+  @param  DataSize              The size, in bytes, of WatchdogData.

+  @param  ResetData             For a ResetType of EfiResetCold, EfiResetWarm, or             

+                                EfiResetShutdown the data buffer starts with a Null-terminated

+                                Unicode string, optionally followed by additional binary data.

+

+**/  

+typedef

+VOID

+(EFIAPI *EFI_RESET_SYSTEM) (

+  IN EFI_RESET_TYPE           ResetType,

+  IN EFI_STATUS               ResetStatus,

+  IN UINTN                    DataSize,

+  IN CHAR16                   *ResetData OPTIONAL

+  );

+

+/**                                                                 

+  Returns a monotonically increasing count for the platform.

+  

+  @param  Count                 Pointer to returned value.

+                                

+  @retval EFI_SUCCESS           The next monotonic count was returned.

+  @retval EFI_INVALID_PARAMETER Count is NULL.                         

+  @retval EFI_DEVICE_ERROR      The device is not functioning properly.                                                  

+                                

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) (

+  OUT UINT64                  *Count

+  );

+

+/**                                                                 

+  Returns the next high 32 bits of the platform¡¯s monotonic counter.

+  

+  @param  HighCount             Pointer to returned value.

+                                

+  @retval EFI_SUCCESS           The next high monotonic count was returned.

+  @retval EFI_INVALID_PARAMETER HighCount is NULL.                         

+  @retval EFI_DEVICE_ERROR      The device is not functioning properly.                                                  

+                                

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) (

+  OUT UINT32                  *HighCount

+  );

+

+/**                                                                 

+  Computes and returns a 32-bit CRC for a data buffer.

+  

+  @param  Data                  A pointer to the buffer on which the 32-bit CRC is to be computed.

+  @param  DataSize              The number of bytes in the buffer Data.

+  @param  Crc32                 The 32-bit CRC that was computed for the data buffer specified by Data

+                                and DataSize.

+                                

+  @retval EFI_SUCCESS           The 32-bit CRC was computed for the data buffer and returned in

+                                Crc32.                                                           

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.  

+                                

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CALCULATE_CRC32) (

+  IN  VOID                              *Data,

+  IN  UINTN                             DataSize,

+  OUT UINT32                            *Crc32

+  );

+

+/**                                                                 

+  Copies the contents of one buffer to another buffer.

+  

+  @param  Destination           Pointer to the destination buffer of the memory copy.

+  @param  Source                Pointer to the source buffer of the memory copy.

+  @param  Length                Number of bytes to copy from Source to Destination.                                

+                                

+**/  

+typedef

+VOID

+(EFIAPI *EFI_COPY_MEM) (

+  IN VOID     *Destination,

+  IN VOID     *Source,

+  IN UINTN    Length

+  );

+

+/**                                                                 

+  The SetMem() function fills a buffer with a specified value.

+  

+  @param  Buffer                Pointer to the buffer to fill.

+  @param  Size                  Number of bytes in Buffer to fill.

+  @param  Value                 Value to fill Buffer with.

+                                

+**/  

+typedef

+VOID

+(EFIAPI *EFI_SET_MEM) (

+  IN VOID     *Buffer,

+  IN UINTN    Size,

+  IN UINT8    Value

+  );

+

+//

+// Protocol handler functions

+//

+typedef enum {

+  EFI_NATIVE_INTERFACE

+} EFI_INTERFACE_TYPE;

+

+/**                                                                 

+  Installs a protocol interface on a device handle. If the handle does not exist, it is created and added

+  to the list of handles in the system. InstallMultipleProtocolInterfaces() performs                     

+  more error checking than InstallProtocolInterface(), so it is recommended that                         

+  InstallMultipleProtocolInterfaces() be used in place of                                                

+  InstallProtocolInterface()                                                                             

+  

+  @param  Handle                A pointer to the EFI_HANDLE on which the interface is to be installed.

+  @param  Protocol              The numeric ID of the protocol interface.

+  @param  InterfaceType         Indicates whether Interface is supplied in native form.                                

+  @param  Interface             A pointer to the protocol interface.

+                                

+  @retval EFI_SUCCESS           The protocol interface was installed.

+  @retval EFI_OUT_OF_RESOURCES  Space for a new handle could not be allocated.                            

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.  

+                                

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) (

+  IN OUT EFI_HANDLE           *Handle,

+  IN EFI_GUID                 *Protocol,

+  IN EFI_INTERFACE_TYPE       InterfaceType,

+  IN VOID                     *Interface

+  );

+

+/**                                                                 

+  Installs one or more protocol interfaces into the boot services environment.

+  

+  @param  Handle                The handle to install the new protocol interfaces on, or NULL if a new

+                                handle is to be allocated.                                                                            

+  @param  ...                   A variable argument list containing pairs of protocol GUIDs and protocol

+                                interfaces.                                                               

+

+  @retval EFI_SUCCESS           All the protocol interface was installed.

+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.

+  @retval EFI_ALREADY_STARTED   A Device Path Protocol instance was passed in that is already present in

+                                the handle database.

+    

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) (

+  IN OUT EFI_HANDLE           *Handle,

+  ...

+  );

+

+/**                                                                 

+  Reinstalls a protocol interface on a device handle.

+  

+  @param  Handle                Handle on which the interface is to be reinstalled.                                                                                   

+  @param  Protocol              The numeric ID of the interface.

+  @param  OldInterface          A pointer to the old interface. NULL can be used if a structure is not

+                                associated with Protocol.                                             

+  @param  NewInterface          A pointer to the new interface.                      

+  

+  @retval EFI_SUCCESS           The protocol interface was reinstalled.

+  @retval EFI_NOT_FOUND         The OldInterface on the handle was not found.

+  @retval EFI_ACCESS_DENIED     The protocol interface could not be reinstalled,

+                                because OldInterface is still being used by a   

+                                driver that will not release it.                

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+    

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) (

+  IN EFI_HANDLE               Handle,

+  IN EFI_GUID                 *Protocol,

+  IN VOID                     *OldInterface,

+  IN VOID                     *NewInterface

+  );

+

+/**                                                                 

+  Removes a protocol interface from a device handle. It is recommended that

+  UninstallMultipleProtocolInterfaces() be used in place of                

+  UninstallProtocolInterface().                                            

+  

+  @param  Handle                The handle on which the interface was installed.

+  @param  Protocol              The numeric ID of the interface.

+  @param  Interface             A pointer to the interface.                      

+  

+  @retval EFI_SUCCESS           The interface was removed.

+  @retval EFI_NOT_FOUND         The interface was not found.

+  @retval EFI_ACCESS_DENIED     The interface was not removed because the interface

+                                is still being used by a driver.                                                                                               

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.                                

+    

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) (

+  IN EFI_HANDLE               Handle,

+  IN EFI_GUID                 *Protocol,

+  IN VOID                     *Interface

+  );

+

+/**                                                                 

+  Removes one or more protocol interfaces into the boot services environment.                                      

+  

+  @param  Handle                The handle to remove the protocol interfaces from.  

+  @param  ...                   A variable argument list containing pairs of protocol GUIDs and

+                                protocol interfaces.

+  

+  @retval EFI_SUCCESS           All the protocol interfaces were removed.                                                                                        

+  @retval EFI_INVALID_PARAMETER One of the protocol interfaces was not previously installed on Handle.                          

+    

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) (

+  IN EFI_HANDLE           Handle,

+  ...

+  );

+

+/**                                                                 

+  Queries a handle to determine if it supports a specified protocol.

+  

+  @param  Handle                The handle being queried.

+  @param  Protocol              The published unique identifier of the protocol.

+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol

+                                Interface is returned.                                            

+  @retval EFI_SUCCESS           The interface information for the specified protocol was returned.

+  @retval EFI_UNSUPPORTED       The device does not support the specified protocol.

+  @retval EFI_INVALID_PARAMETER One of the protocol interfaces was not previously installed on Handle.                          

+    

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_HANDLE_PROTOCOL) (

+  IN EFI_HANDLE               Handle,

+  IN EFI_GUID                 *Protocol,

+  OUT VOID                    **Interface

+  );

+

+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL  0x00000001

+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL        0x00000002

+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL       0x00000004

+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008

+#define EFI_OPEN_PROTOCOL_BY_DRIVER           0x00000010

+#define EFI_OPEN_PROTOCOL_EXCLUSIVE           0x00000020

+

+/**                                                                 

+  Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the

+  handle, it opens the protocol on behalf of the calling agent.

+    

+  @param  Handle                The handle for the protocol interface that is being opened.

+  @param  Protocol              The published unique identifier of the protocol.

+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol

+                                Interface is returned.                                            

+  @param  AgentHandle           The handle of the agent that is opening the protocol interface

+                                specified by Protocol and Interface.                            

+  @param  ControllerHandle      If the agent that is opening a protocol is a driver that follows the                          

+                                UEFI Driver Model, then this parameter is the controller handle     

+                                that requires the protocol interface. If the agent does not follow  

+                                the UEFI Driver Model, then this parameter is optional and may      

+                                be NULL.                                                            

+  @param  Attributes            The open mode of the protocol interface specified by Handle                    

+                                and Protocol.             

+                                                                 

+  @retval EFI_SUCCESS           An item was added to the open list for the protocol interface, and the

+                                protocol interface was returned in Interface.                         

+  @retval EFI_UNSUPPORTED       Handle does not support Protocol.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_ACCESS_DENIED     Required attributes can't be supported in current environment.

+  @retval EFI_ALREADY_STARTED   Item on the open list already has requierd attributes whose agent

+                                handle is the same as AgentHandle.                                

+    

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_OPEN_PROTOCOL) (

+  IN EFI_HANDLE                 Handle,

+  IN EFI_GUID                   *Protocol,

+  OUT VOID                      **Interface,

+  IN  EFI_HANDLE                AgentHandle,

+  IN  EFI_HANDLE                ControllerHandle, OPTIONAL

+  IN  UINT32                    Attributes

+  );

+

+  

+/**                                                                 

+  Closes a protocol on a handle that was opened using OpenProtocol().

+    

+  @param  Handle                The handle for the protocol interface that was previously opened

+                                with OpenProtocol(), and is now being closed.                   

+  @param  Protocol              The published unique identifier of the protocol.

+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol

+                                Interface is returned.                                            

+  @param  AgentHandle           The handle of the agent that is closing the protocol interface.                                 

+  @param  ControllerHandle      If the agent that opened a protocol is a driver that follows the

+                                UEFI Driver Model, then this parameter is the controller handle 

+                                that required the protocol interface.                           

+                                                                 

+  @retval EFI_SUCCESS           The protocol instance was closed.                                  

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.  

+  @retval EFI_NOT_FOUND         1) Handle does not support the protocol specified by Protocol.

+                                2) The protocol interface specified by Handle and Protocol is not

+                                   currently open by AgentHandle and ControllerHandle.           

+                                   

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_CLOSE_PROTOCOL) (

+  IN EFI_HANDLE               Handle,

+  IN EFI_GUID                 *Protocol,

+  IN EFI_HANDLE               AgentHandle,

+  IN EFI_HANDLE               ControllerHandle

+  );

+

+typedef struct {

+  EFI_HANDLE  AgentHandle;

+  EFI_HANDLE  ControllerHandle;

+  UINT32      Attributes;

+  UINT32      OpenCount;

+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;

+

+/**                                                                 

+  Retrieves the list of agents that currently have a protocol interface opened.

+    

+  @param  Handle                The handle for the protocol interface that is being queried.                                    

+  @param  Protocol              The published unique identifier of the protocol.

+  @param  EntryBuffer           A pointer to a buffer of open protocol information in the form of

+                                EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.                  

+  @param  EntryCount            A pointer to the number of entries in EntryBuffer.

+                                                                 

+  @retval EFI_SUCCESS           The open protocol information was returned in EntryBuffer, and the

+                                number of entries was returned EntryCount.                        

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to allocate EntryBuffer.

+  @retval EFI_NOT_FOUND         Handle does not support the protocol specified by Protocol.

+                                   

+**/  

+typedef

+EFI_STATUS

+(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) (

+  IN  EFI_HANDLE                          Handle,

+  IN  EFI_GUID                            *Protocol,

+  IN  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,

+  OUT UINTN                               *EntryCount

+  );

+

+/**                                                                 

+  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated

+  from pool.                                                                                           

+  

+  @param  Handle                The handle from which to retrieve the list of protocol interface

+                                GUIDs.                                                            

+  @param  ProtocolBuffer        A pointer to the list of protocol interface GUID pointers that are

+                                installed on Handle.                                                    

+  @param  ProtocolBufferCount   A pointer to the number of GUID pointers present in 

+                                ProtocolBuffer.                                      

+                                

+  @retval EFI_SUCCESS           The list of protocol interface GUIDs installed on Handle was returned in

+                                ProtocolBuffer. The number of protocol interface GUIDs was              

+                                returned in ProtocolBufferCount.                                        

+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the results.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) (

+  IN EFI_HANDLE       Handle,

+  OUT EFI_GUID        ***ProtocolBuffer,

+  OUT UINTN           *ProtocolBufferCount

+  );

+

+/**                                                                 

+  Creates an event that is to be signaled whenever an interface is installed for a specified protocol.  

+  

+  @param  Protocol              The numeric ID of the protocol for which the event is to be registered.                                

+  @param  Event                 Event that is to be signaled whenever a protocol interface is registered

+                                for Protocol.                                                           

+  @param  Registration          A pointer to a memory location to receive the registration value.                                

+                                

+  @retval EFI_SUCCESS           The notification event has been registered.                                                                

+  @retval EFI_OUT_OF_RESOURCES  Space for the notification event could not be allocated.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) (

+  IN EFI_GUID                 *Protocol,

+  IN EFI_EVENT                Event,

+  OUT VOID                    **Registration

+  );

+

+typedef enum {

+  AllHandles,

+  ByRegisterNotify,

+  ByProtocol

+} EFI_LOCATE_SEARCH_TYPE;

+

+/**                                                                 

+  Returns an array of handles that support a specified protocol.

+  

+  @param  SearchType            Specifies which handle(s) are to be returned.

+  @param  Protocol              Specifies the protocol to search by.

+  @param  SearchKey             Specifies the search key.                

+  @param  BufferSize            On input, the size in bytes of Buffer. On output, the size in bytes of     

+                                the array returned in Buffer (if the buffer was large enough) or the       

+                                size, in bytes, of the buffer needed to obtain the array (if the buffer was

+                                not large enough).                                                             

+  @param  Buffer                The buffer in which the array is returned.

+                                

+  @retval EFI_SUCCESS           The array of handles was returned.

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small for the result.  

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LOCATE_HANDLE) (

+  IN EFI_LOCATE_SEARCH_TYPE   SearchType,

+  IN EFI_GUID                 *Protocol,    OPTIONAL

+  IN VOID                     *SearchKey,   OPTIONAL

+  IN OUT UINTN                *BufferSize,

+  OUT EFI_HANDLE              *Buffer

+  );

+

+/**                                                                 

+  Locates the handle to a device on the device path that supports the specified protocol.

+    

+  @param  Protocol              Specifies the protocol to search for.

+  @param  DevicePath            On input, a pointer to a pointer to the device path. On output, the device

+                                path pointer is modified to point to the remaining part of the device     

+                                path.                                                                        

+  @param  Device                A pointer to the returned device handle.  

+                                

+  @retval EFI_SUCCESS           The resulting handle was returned.

+  @retval EFI_NOT_FOUND         No handles match the search.  

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LOCATE_DEVICE_PATH) (

+  IN EFI_GUID                         *Protocol,

+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **DevicePath,

+  OUT EFI_HANDLE                      *Device

+  );

+

+/**                                                                 

+  Adds, updates, or removes a configuration table entry from the EFI System Table.

+    

+  @param  Guid                  A pointer to the GUID for the entry to add, update, or remove.

+  @param  Table                 A pointer to the configuration table for the entry to add, update, or

+                                remove. May be NULL.                                                   

+                                

+  @retval EFI_SUCCESS           The (Guid, Table) pair was added, updated, or removed.

+  @retval EFI_NOT_FOUND         An attempt was made to delete a nonexistent entry.

+  @retval EFI_INVALID_PARAMETER Guid is not valid.

+  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available to complete the operation.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) (

+  IN EFI_GUID                 *Guid,

+  IN VOID                     *Table

+  );

+

+/**                                                                 

+  Reserved service.

+                                    

+  @retval EFI_SUCCESS           The operation has been completed successfully.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_RESERVED_SERVICE) (

+  VOID

+  );

+

+/**                                                                 

+  Returns an array of handles that support the requested protocol in a buffer allocated from pool.

+  

+  @param  SearchType            Specifies which handle(s) are to be returned.

+  @param  Protocol              Specifies the protocol to search by.

+  @param  SearchKey             Supplies the search key depending on the SearchType.

+  @param  NoHandles             The number of handles returned in Buffer.

+  @param  Buffer                A pointer to the buffer to return the requested array of handles that

+                                support Protocol.                                                    

+                                

+  @retval EFI_SUCCESS           The array of handles was returned in Buffer, and the number of

+                                handles in Buffer was returned in NoHandles.                  

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the matching results.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) (

+  IN EFI_LOCATE_SEARCH_TYPE       SearchType,

+  IN EFI_GUID                     *Protocol,      OPTIONAL

+  IN VOID                         *SearchKey,     OPTIONAL

+  IN OUT UINTN                    *NoHandles,

+  OUT EFI_HANDLE                  **Buffer

+  );

+

+/**                                                                 

+  Returns the first protocol instance that matches the given protocol.

+    

+  @param  Protocol              Provides the protocol to search for.

+  @param  Registration          Optional registration key returned from

+                                RegisterProtocolNotify().              

+  @param  Interface             On return, a pointer to the first interface that matches Protocol and

+                                Registration.   

+                                                                                     

+  @retval EFI_SUCCESS           A protocol instance matching Protocol was found and returned in

+                                Interface.                                                     

+  @retval EFI_NOT_FOUND         No protocol instances were found that match Protocol and

+                                Registration.                                            

+  @retval EFI_INVALID_PARAMETER Interface is NULL.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_LOCATE_PROTOCOL) (

+  IN EFI_GUID  *Protocol,

+  IN VOID      *Registration, OPTIONAL

+  OUT VOID      **Interface

+  );

+

+

+typedef struct {

+  UINT64                            Length;

+  union {

+    EFI_PHYSICAL_ADDRESS  DataBlock;

+    EFI_PHYSICAL_ADDRESS  ContinuationPointer;

+  } Union;

+} UEFI_CAPSULE_BLOCK_DESCRIPTOR;

+

+typedef struct {

+  EFI_GUID    CapsuleGuid;

+  UINT32            HeaderSize;

+  UINT32            Flags;

+  UINT32            CapsuleImageSize;

+} UEFI_CAPSULE_HEADER;

+

+#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET        0x00010000

+#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE         0x00020000

+

+/**                                                                 

+  Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended

+  consumption, the firmware may process the capsule immediately. If the payload should persist     

+  across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must           

+  be passed into ResetSystem() and will cause the capsule to be processed by the firmware as       

+  part of the reset process.                                                                       

+    

+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules

+                                being passed into update capsule.                              

+  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER in

+                                CaspuleHeaderArray.                        

+  @param  ScatterGatherList     Physical pointer to a set of                   

+                                EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the

+                                location in physical memory of a set of capsules.

+                                                                                   

+  @retval EFI_SUCCESS           Valid capsule was passed. If                     

+                                CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the

+                                capsule has been successfully processed by the firmware.

+  @retval EFI_DEVICE_ERROR      The capsule update was started, but failed due to a device error.                                

+  @retval EFI_INVALID_PARAMETER CapsuleSize is NULL.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_UPDATE_CAPSULE) (

+  IN UEFI_CAPSULE_HEADER    **CapsuleHeaderArray,

+  IN UINTN                  CapsuleCount,

+  IN EFI_PHYSICAL_ADDRESS   ScatterGatherList   OPTIONAL

+  );

+

+/**                                                                 

+  Returns if the capsule can be supported via UpdateCapsule().

+    

+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules

+                                being passed into update capsule.                              

+  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER in

+                                CaspuleHeaderArray.                        

+  @param  MaxiumCapsuleSize     On output the maximum size that UpdateCapsule() can

+                                support as an argument to UpdateCapsule() via      

+                                CapsuleHeaderArray and ScatterGatherList.            

+  @param  ResetType             Returns the type of reset required for the capsule update.                                

+                                                                                   

+  @retval EFI_SUCCESS           Valid answer returned.                                                                

+  @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform, and

+                                MaximumCapsuleSize and ResetType are undefined.        

+  @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL.

+                                   

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES) (

+  IN UEFI_CAPSULE_HEADER    **CapsuleHeaderArray,

+  IN UINTN                  CapsuleCount,

+  OUT   UINT64              *MaximumCapsuleSize,

+  OUT EFI_RESET_TYPE        *ResetType

+  );

+

+/**                                                                                                    

+  Returns information about the EFI variables.

+                                                                                                       

+  @param  Attributes                   Attributes bitmask to specify the type of variables on

+                                       which to return information.                          

+  @param  MaximumVariableStorageSize   On output the maximum size of the storage space    

+                                       available for the EFI variables associated with the

+                                       attributes specified.                              

+  @param  RemainingVariableStorageSize Returns the remaining size of the storage space    

+                                       available for the EFI variables associated with the

+                                       attributes specified.                                

+  @param  MaximumVariableSize          Returns the maximum size of the individual EFI                        

+                                       variables associated with the attributes specified.                                                                

+                                       

+  @retval EFI_SUCCESS                  Valid answer returned.                                   

+  @retval EFI_INVALID_PARAMETER        An invalid combination of attribute bits was supplied                 

+  @retval EFI_UNSUPPORTED              The attribute is not supported on this platform, and the

+                                       MaximumVariableStorageSize,                             

+                                       RemainingVariableStorageSize, MaximumVariableSize       

+                                       are undefined.                                              

+                                                                                                       

+**/                                                                                                    

+typedef                         

+EFI_STATUS

+(EFIAPI *EFI_QUERY_VARIABLE_INFO) (

+  IN UINT32           Attributes,

+  OUT UINT64            *MaximumVariableStorageSize,

+  OUT    UINT64         *RemainingVariableStorageSize,

+  OUT UINT64            *MaximumVariableSize

+  );

+

+

+//

+// EFI Runtime Services Table

+//

+#define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | 02)

+#define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | 10)

+#define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | 0)

+

+#define EFI_RUNTIME_SERVICES_SIGNATURE  0x56524553544e5552ULL

+#define EFI_RUNTIME_SERVICES_REVISION   (EFI_2_00_SYSTEM_TABLE_REVISION)

+

+#if (EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000)

+//

+// Include the definition for TIANO_REPORT_STATUS_CODE if this is the version

+//  of Tiano that extended the EFI specification. If Tiano mode is diabled

+//  don't include it.

+//

+#include <Dxe/ArchProtocol/StatusCode.h>

+#endif

+

+

+typedef struct {

+  EFI_TABLE_HEADER              Hdr;

+

+  //

+  // Time services

+  //

+  EFI_GET_TIME                  GetTime;

+  EFI_SET_TIME                  SetTime;

+  EFI_GET_WAKEUP_TIME           GetWakeupTime;

+  EFI_SET_WAKEUP_TIME           SetWakeupTime;

+

+  //

+  // Virtual memory services

+  //

+  EFI_SET_VIRTUAL_ADDRESS_MAP   SetVirtualAddressMap;

+  EFI_CONVERT_POINTER           ConvertPointer;

+

+  //

+  // Variable services

+  //

+  EFI_GET_VARIABLE              GetVariable;

+  EFI_GET_NEXT_VARIABLE_NAME    GetNextVariableName;

+  EFI_SET_VARIABLE              SetVariable;

+

+  //

+  // Misc

+  //

+  EFI_GET_NEXT_HIGH_MONO_COUNT  GetNextHighMonotonicCount;

+  EFI_RESET_SYSTEM              ResetSystem;

+

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+  //

+  // New Boot Services added by UEFI 2.0

+  //

+  EFI_UPDATE_CAPSULE              UpdateCapsule;

+  EFI_QUERY_CAPSULE_CAPABILITIES  QueryCapsuleCapabilities;

+  EFI_QUERY_VARIABLE_INFO         QueryVariableInfo;

+#elif (EDK_RELEASE_VERSION != 0)

+  //

+  // Tiano extension to EFI 1.10 runtime table

+  //  It was moved to a protocol to not conflict with UEFI 2.0

+  //  If Tiano is disabled this item is not enabled for EFI 1.10

+  //

+  TIANO_REPORT_STATUS_CODE          ReportStatusCode;

+#endif

+} EFI_RUNTIME_SERVICES;

+

+//

+// EFI Boot Services Table

+//

+#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42ULL

+#define EFI_BOOT_SERVICES_REVISION  (EFI_2_00_SYSTEM_TABLE_REVISION)

+

+typedef struct {

+  EFI_TABLE_HEADER                            Hdr;

+

+  //

+  // Task priority functions

+  //

+  EFI_RAISE_TPL                               RaiseTPL;

+  EFI_RESTORE_TPL                             RestoreTPL;

+

+  //

+  // Memory functions

+  //

+  EFI_ALLOCATE_PAGES                          AllocatePages;

+  EFI_FREE_PAGES                              FreePages;

+  EFI_GET_MEMORY_MAP                          GetMemoryMap;

+  EFI_ALLOCATE_POOL                           AllocatePool;

+  EFI_FREE_POOL                               FreePool;

+

+  //

+  // Event & timer functions

+  //

+  EFI_CREATE_EVENT                            CreateEvent;

+  EFI_SET_TIMER                               SetTimer;

+  EFI_WAIT_FOR_EVENT                          WaitForEvent;

+  EFI_SIGNAL_EVENT                            SignalEvent;

+  EFI_CLOSE_EVENT                             CloseEvent;

+  EFI_CHECK_EVENT                             CheckEvent;

+

+  //

+  // Protocol handler functions

+  //

+  EFI_INSTALL_PROTOCOL_INTERFACE              InstallProtocolInterface;

+  EFI_REINSTALL_PROTOCOL_INTERFACE            ReinstallProtocolInterface;

+  EFI_UNINSTALL_PROTOCOL_INTERFACE            UninstallProtocolInterface;

+  EFI_HANDLE_PROTOCOL                         HandleProtocol;

+  VOID                                        *Reserved;

+  EFI_REGISTER_PROTOCOL_NOTIFY                RegisterProtocolNotify;

+  EFI_LOCATE_HANDLE                           LocateHandle;

+  EFI_LOCATE_DEVICE_PATH                      LocateDevicePath;

+  EFI_INSTALL_CONFIGURATION_TABLE             InstallConfigurationTable;

+

+  //

+  // Image functions

+  //

+  EFI_IMAGE_LOAD                              LoadImage;

+  EFI_IMAGE_START                             StartImage;

+  EFI_EXIT                                    Exit;

+  EFI_IMAGE_UNLOAD                            UnloadImage;

+  EFI_EXIT_BOOT_SERVICES                      ExitBootServices;

+

+  //

+  // Misc functions

+  //

+  EFI_GET_NEXT_MONOTONIC_COUNT                GetNextMonotonicCount;

+  EFI_STALL                                   Stall;

+  EFI_SET_WATCHDOG_TIMER                      SetWatchdogTimer;

+

+  //

+  // ////////////////////////////////////////////////////

+  // EFI 1.1 Services

+    //////////////////////////////////////////////////////

+  //

+  // DriverSupport Services

+  //

+  EFI_CONNECT_CONTROLLER                      ConnectController;

+  EFI_DISCONNECT_CONTROLLER                   DisconnectController;

+

+  //

+  // Added Open and Close protocol for the new driver model

+  //

+  EFI_OPEN_PROTOCOL                           OpenProtocol;

+  EFI_CLOSE_PROTOCOL                          CloseProtocol;

+  EFI_OPEN_PROTOCOL_INFORMATION               OpenProtocolInformation;

+

+  //

+  // Added new services to EFI 1.1 as Lib to reduce code size.

+  //

+  EFI_PROTOCOLS_PER_HANDLE                    ProtocolsPerHandle;

+  EFI_LOCATE_HANDLE_BUFFER                    LocateHandleBuffer;

+  EFI_LOCATE_PROTOCOL                         LocateProtocol;

+

+  EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES    InstallMultipleProtocolInterfaces;

+  EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES  UninstallMultipleProtocolInterfaces;

+

+  //

+  // CRC32 services

+  //

+  EFI_CALCULATE_CRC32                         CalculateCrc32;

+

+  //

+  // Memory Utility Services

+  //

+  EFI_COPY_MEM                                CopyMem;

+  EFI_SET_MEM                                 SetMem;

+

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+  //

+  // UEFI 2.0 Extension to the table

+  //

+  EFI_CREATE_EVENT_EX                         CreateEventEx;

+#endif

+} EFI_BOOT_SERVICES;

+

+//

+// EFI Configuration Table

+//

+typedef struct {

+  EFI_GUID  VendorGuid;

+  VOID      *VendorTable;

+} EFI_CONFIGURATION_TABLE;

+

+//

+// EFI System Table

+//

+#define EFI_SYSTEM_TABLE_SIGNATURE      0x5453595320494249ULL

+#define EFI_SYSTEM_TABLE_REVISION       (EFI_2_00_SYSTEM_TABLE_REVISION)

+

+struct _EFI_SYSTEM_TABLE {

+  EFI_TABLE_HEADER              Hdr;

+

+  CHAR16                        *FirmwareVendor;

+  UINT32                        FirmwareRevision;

+

+  EFI_HANDLE                    ConsoleInHandle;

+  EFI_SIMPLE_TEXT_IN_PROTOCOL   *ConIn;

+

+  EFI_HANDLE                    ConsoleOutHandle;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *ConOut;

+

+  EFI_HANDLE                    StandardErrorHandle;

+  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *StdErr;

+

+  EFI_RUNTIME_SERVICES          *RuntimeServices;

+  EFI_BOOT_SERVICES             *BootServices;

+

+  UINTN                         NumberOfTableEntries;

+  EFI_CONFIGURATION_TABLE       *ConfigurationTable;

+

+};

+

+//

+// Device Path information

+//

+

+#pragma pack(1)

+

+//

+// Hardware Device Paths

+//

+#define HARDWARE_DEVICE_PATH      0x01

+

+#define HW_PCI_DP                 0x01

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT8                           Function;

+  UINT8                           Device;

+} PCI_DEVICE_PATH;

+

+#define HW_PCCARD_DP              0x02

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT8                           FunctionNumber;

+} PCCARD_DEVICE_PATH;

+

+#define HW_MEMMAP_DP              0x03

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          MemoryType;

+  EFI_PHYSICAL_ADDRESS            StartingAddress;

+  EFI_PHYSICAL_ADDRESS            EndingAddress;

+} MEMMAP_DEVICE_PATH;

+

+#define HW_VENDOR_DP              0x04

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  EFI_GUID                        Guid;

+} VENDOR_DEVICE_PATH;

+

+#define HW_CONTROLLER_DP          0x05

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+#if EDK_RELEASE_VERSION >= 0x00020000

+  UINT32                          ControllerNumber;

+#else

+  UINT32                          Controller;

+#endif

+} CONTROLLER_DEVICE_PATH;

+

+//

+// ACPI Device Paths

+//

+#define ACPI_DEVICE_PATH          0x02

+

+#define ACPI_DP                   0x01

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          HID;

+  UINT32                          UID;

+} ACPI_HID_DEVICE_PATH;

+

+#define ACPI_EXTENDED_DP          0x02

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          HID;

+  UINT32                          UID;

+  UINT32                          CID;

+  //

+  // Optional variable length _HIDSTR

+  // Optional variable length _UIDSTR

+  //

+} ACPI_EXTENDED_HID_DEVICE_PATH;

+

+//

+//  EISA ID Macro

+//  EISA ID Definition 32-bits

+//   bits[15:0] - three character compressed ASCII EISA ID.

+//   bits[31:16] - binary number

+//    Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'

+//

+#define PNP_EISA_ID_CONST         0x41d0

+#define EISA_ID(_Name, _Num)      ((UINT32) ((_Name) | (_Num) << 16))

+#define EISA_PNP_ID(_PNPId)       (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))

+#define EFI_PNP_ID(_PNPId)        (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))

+

+#define PNP_EISA_ID_MASK          0xffff

+#define EISA_ID_TO_NUM(_Id)       ((_Id) >> 16)

+

+

+#define ACPI_ADR_DP               0x03

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          ADR;

+} ACPI_ADR_DEVICE_PATH;

+

+

+//

+// Messaging Device Paths

+//

+#define MESSAGING_DEVICE_PATH     0x03

+

+#define MSG_ATAPI_DP              0x01

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT8                           PrimarySecondary;

+  UINT8                           SlaveMaster;

+  UINT16                          Lun;

+} ATAPI_DEVICE_PATH;

+

+#define MSG_SCSI_DP               0x02

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT16                          Pun;

+  UINT16                          Lun;

+} SCSI_DEVICE_PATH;

+

+#define MSG_FIBRECHANNEL_DP       0x03

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          Reserved;

+  UINT64                          WWN;

+  UINT64                          Lun;

+} FIBRECHANNEL_DEVICE_PATH;

+

+#define MSG_1394_DP               0x04

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          Reserved;

+  UINT64                          Guid;

+} F1394_DEVICE_PATH;

+

+#define MSG_USB_DP                0x05

+typedef struct {

+    EFI_DEVICE_PATH_PROTOCOL      Header;

+    UINT8                         ParentPortNumber;

+    UINT8                         InterfaceNumber;

+} USB_DEVICE_PATH;

+

+#define MSG_USB_CLASS_DP          0x0f

+typedef struct {

+    EFI_DEVICE_PATH_PROTOCOL      Header;

+    UINT16                        VendorId;

+    UINT16                        ProductId;

+    UINT8                         DeviceClass;

+    UINT8                         DeviceSubClass;

+    UINT8                         DeviceProtocol;

+} USB_CLASS_DEVICE_PATH;

+

+#define MSG_USB_WWID_DP          0x10

+typedef struct {

+    EFI_DEVICE_PATH_PROTOCOL      Header;

+    UINT16                        InterfaceNumber;

+    UINT16                        VendorId;

+    UINT16                        ProductId;

+    // CHAR16                     SerialNumber[];

+} USB_WWID_DEVICE_PATH;

+

+#define MSG_DEVICE_LOGICAL_UNIT_DP  0x11

+typedef struct {

+    EFI_DEVICE_PATH_PROTOCOL      Header;

+    UINT8                         LUN;

+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;

+

+#define MSG_I2O_DP                0x06

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          Tid;

+} I2O_DEVICE_PATH;

+

+#define MSG_MAC_ADDR_DP           0x0b

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  EFI_MAC_ADDRESS                 MacAddress;

+  UINT8                           IfType;

+} MAC_ADDR_DEVICE_PATH;

+

+#define MSG_IPv4_DP               0x0c

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  EFI_IPv4_ADDRESS                LocalIpAddress;

+  EFI_IPv4_ADDRESS                RemoteIpAddress;

+  UINT16                          LocalPort;

+  UINT16                          RemotePort;

+  UINT16                          Protocol;

+  BOOLEAN                         StaticIpAddress;

+} IPv4_DEVICE_PATH;

+

+#define MSG_IPv6_DP               0x0d

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  EFI_IPv6_ADDRESS                LocalIpAddress;

+  EFI_IPv6_ADDRESS                RemoteIpAddress;

+  UINT16                          LocalPort;

+  UINT16                          RemotePort;

+  UINT16                          Protocol;

+  BOOLEAN                         StaticIpAddress;

+} IPv6_DEVICE_PATH;

+

+#define MSG_INFINIBAND_DP         0x09

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          ResourceFlags;

+  UINT8                           PortGid[16];

+  UINT64                          ServiceId;

+  UINT64                          TargetPortId;

+  UINT64                          DeviceId;

+} INFINIBAND_DEVICE_PATH;

+

+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE                0x01

+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT  0x02

+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL           0x04

+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL           0x08

+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL           0x10

+

+#define MSG_UART_DP               0x0e

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          Reserved;

+  UINT64                          BaudRate;

+  UINT8                           DataBits;

+  UINT8                           Parity;

+  UINT8                           StopBits;

+} UART_DEVICE_PATH;

+

+//

+// Use VENDOR_DEVICE_PATH struct

+//

+#define MSG_VENDOR_DP             0x0a

+

+#define DEVICE_PATH_MESSAGING_PC_ANSI     EFI_PC_ANSI_GUID

+#define DEVICE_PATH_MESSAGING_VT_100      EFI_VT_100_GUID

+#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID

+#define DEVICE_PATH_MESSAGING_VT_UTF8     EFI_VT_UTF8_GUID

+#define DEVICE_PATH_MESSAGING_SAS         EFI_SAS_DEVICE_PATH_GUID

+

+

+#define MSG_ISCSI_DP              0x13

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT16                          NetworkProtocol;

+  UINT16                          LoginOption;

+  UINT16                          Reserved;

+  UINT16                          TargetPortalGroupTag;

+  UINT64                          LUN;

+  // CHAR8                        iSCSI Target Name

+} ISCSI_DEVICE_PATH;

+

+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST             0x0000

+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C   0x0002

+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST               0x0000

+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C     0x0008

+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP              0x0000

+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON               0x1000

+#define ISCSI_LOGIN_OPTION_CHAP_BI                      0x0000

+#define ISCSI_LOGIN_OPTION_CHAP_UNI                     0x2000

+

+

+//

+// Media Device Path

+//

+#define MEDIA_DEVICE_PATH         0x04

+

+#define MEDIA_HARDDRIVE_DP        0x01

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          PartitionNumber;

+  UINT64                          PartitionStart;

+  UINT64                          PartitionSize;

+  UINT8                           Signature[16];

+  UINT8                           MBRType;

+  UINT8                           SignatureType;

+} HARDDRIVE_DEVICE_PATH;

+

+#define MBR_TYPE_PCAT             0x01

+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02

+

+#define SIGNATURE_TYPE_MBR        0x01

+#define SIGNATURE_TYPE_GUID       0x02

+

+#define MEDIA_CDROM_DP            0x02

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT32                          BootEntry;

+  UINT64                          PartitionStart;

+  UINT64                          PartitionSize;

+} CDROM_DEVICE_PATH;

+

+//

+// Use VENDOR_DEVICE_PATH struct

+//

+#define MEDIA_VENDOR_DP           0x03

+

+#define MEDIA_FILEPATH_DP         0x04

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  CHAR16                          PathName[1];

+} FILEPATH_DEVICE_PATH;

+

+#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName)

+

+#define MEDIA_PROTOCOL_DP         0x05

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  EFI_GUID                        Protocol;

+} MEDIA_PROTOCOL_DEVICE_PATH;

+

+#if ((EDK_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000))

+//

+// Prior to UEFI 2.0 Tiano extended this enum. UEFI owns device path values

+// and we moved to a new GUID'ed device path for Tiano

+//

+

+#define MEDIA_FV_FILEPATH_DP  0x06

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL  Header;

+  EFI_GUID                  NameGuid;

+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;

+

+#else

+

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL  Header;

+  EFI_GUID                  PiwgSpecificDevicePath;

+  UINT32                    Type;

+} PIWG_DEVICE_PATH;

+

+#define PIWG_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE         0x01

+typedef struct {

+  PIWG_DEVICE_PATH      Piwg;

+  EFI_GUID              NameGuid;

+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;

+

+//

+// Place holder for a future extension

+//

+#define PIWG_MEDIAFW_VOL_DEVICE_PATH_TYPE                   0x02

+typedef struct {

+  PIWG_DEVICE_PATH      Piwg;

+  EFI_GUID              VolumeGuid;

+} MEDIA_FW_VOL_DEVICE_PATH;

+

+#endif

+

+

+//

+// BBS Device Path

+//

+#define BBS_DEVICE_PATH           0x05

+#define BBS_BBS_DP                0x01

+typedef struct {

+  EFI_DEVICE_PATH_PROTOCOL        Header;

+  UINT16                          DeviceType;

+  UINT16                          StatusFlag;

+  CHAR8                           String[1];

+} BBS_BBS_DEVICE_PATH;

+

+//

+// DeviceType definitions - from BBS specification

+//

+#define BBS_TYPE_FLOPPY           0x01

+#define BBS_TYPE_HARDDRIVE        0x02

+#define BBS_TYPE_CDROM            0x03

+#define BBS_TYPE_PCMCIA           0x04

+#define BBS_TYPE_USB              0x05

+#define BBS_TYPE_EMBEDDED_NETWORK 0x06

+#define BBS_TYPE_BEV              0x80

+#define BBS_TYPE_UNKNOWN          0xFF

+

+

+//

+// Union of all possible Device Paths and pointers to Device Paths

+//

+

+typedef union {

+  EFI_DEVICE_PATH_PROTOCOL             DevPath;

+  PCI_DEVICE_PATH                      Pci;

+  PCCARD_DEVICE_PATH                   PcCard;

+  MEMMAP_DEVICE_PATH                   MemMap;

+  VENDOR_DEVICE_PATH                   Vendor;

+

+  CONTROLLER_DEVICE_PATH               Controller;

+  ACPI_HID_DEVICE_PATH                 Acpi;

+

+  ATAPI_DEVICE_PATH                    Atapi;

+  SCSI_DEVICE_PATH                     Scsi;

+  FIBRECHANNEL_DEVICE_PATH             FibreChannel;

+

+  F1394_DEVICE_PATH                    F1394;

+  USB_DEVICE_PATH                      Usb;

+  USB_CLASS_DEVICE_PATH                UsbClass;

+  I2O_DEVICE_PATH                      I2O;

+  MAC_ADDR_DEVICE_PATH                 MacAddr;

+  IPv4_DEVICE_PATH                     Ipv4;

+  IPv6_DEVICE_PATH                     Ipv6;

+  INFINIBAND_DEVICE_PATH               InfiniBand;

+  UART_DEVICE_PATH                     Uart;

+

+  HARDDRIVE_DEVICE_PATH                HardDrive;

+  CDROM_DEVICE_PATH                    CD;

+

+  FILEPATH_DEVICE_PATH                 FilePath;

+  MEDIA_PROTOCOL_DEVICE_PATH           MediaProtocol;

+

+  BBS_BBS_DEVICE_PATH                  Bbs;

+} EFI_DEV_PATH;

+

+

+

+typedef union {

+  EFI_DEVICE_PATH_PROTOCOL             *DevPath;

+  PCI_DEVICE_PATH                      *Pci;

+  PCCARD_DEVICE_PATH                   *PcCard;

+  MEMMAP_DEVICE_PATH                   *MemMap;

+  VENDOR_DEVICE_PATH                   *Vendor;

+

+  CONTROLLER_DEVICE_PATH               *Controller;

+  ACPI_HID_DEVICE_PATH                 *Acpi;

+  ACPI_EXTENDED_HID_DEVICE_PATH        *ExtendedAcpi;

+

+  ATAPI_DEVICE_PATH                    *Atapi;

+  SCSI_DEVICE_PATH                     *Scsi;

+  FIBRECHANNEL_DEVICE_PATH             *FibreChannel;

+

+  F1394_DEVICE_PATH                    *F1394;

+  USB_DEVICE_PATH                      *Usb;

+  USB_CLASS_DEVICE_PATH                *UsbClass;

+  I2O_DEVICE_PATH                      *I2O;

+  MAC_ADDR_DEVICE_PATH                 *MacAddr;

+  IPv4_DEVICE_PATH                     *Ipv4;

+  IPv6_DEVICE_PATH                     *Ipv6;

+  INFINIBAND_DEVICE_PATH               *InfiniBand;

+  UART_DEVICE_PATH                     *Uart;

+

+  HARDDRIVE_DEVICE_PATH                *HardDrive;

+  CDROM_DEVICE_PATH                    *CD;

+

+  FILEPATH_DEVICE_PATH                 *FilePath;

+  MEDIA_PROTOCOL_DEVICE_PATH           *MediaProtocol;

+

+  BBS_BBS_DEVICE_PATH                  *Bbs;

+  UINT8                                *Raw;

+} EFI_DEV_PATH_PTR;

+

+#pragma pack()

+

+

+//

+// PXE Informations

+//

+

+//

+// Packet definitions

+//

+typedef struct {

+  UINT8   BootpOpcode;

+  UINT8   BootpHwType;

+  UINT8   BootpHwAddrLen;

+  UINT8   BootpGateHops;

+  UINT32  BootpIdent;

+  UINT16  BootpSeconds;

+  UINT16  BootpFlags;

+  UINT8   BootpCiAddr[4];

+  UINT8   BootpYiAddr[4];

+  UINT8   BootpSiAddr[4];

+  UINT8   BootpGiAddr[4];

+  UINT8   BootpHwAddr[16];

+  UINT8   BootpSrvName[64];

+  UINT8   BootpBootFile[128];

+  UINT32  DhcpMagik;

+  UINT8   DhcpOptions[56];

+} EFI_PXE_BASE_CODE_DHCPV4_PACKET;

+

+typedef union {

+  UINT8                           Raw[1472];

+  EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4;

+

+  //

+  //  EFI_PXE_BASE_CODE_DHCPV6_PACKET     Dhcpv6;

+  //

+} EFI_PXE_BASE_CODE_PACKET;

+

+#include <Uefi/EfiPxe.h>

+

+//

+// EFI Revision information

+//

+#define EFI_FIRMWARE_REVISION       (EFI_2_00_SYSTEM_TABLE_REVISION)

+

+#include <Common/EfiImage.h>

+#include <IndustryStandard/Usb.h>

+

+

+#define EFI_USB_HC_RESET_GLOBAL            0x0001

+#define EFI_USB_HC_RESET_HOST_CONTROLLER   0x0002

+#define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004

+#define EFI_USB_HC_RESET_HOST_WITH_DEBUG   0x0008

+

+//

+// USB Host Controller state

+//

+typedef enum {

+  EfiUsbHcStateHalt,

+  EfiUsbHcStateOperational,

+  EfiUsbHcStateSuspend,

+  EfiUsbHcStateMaximum

+} EFI_USB_HC_STATE;

+

+

+//

+// EFI File location to boot from on removable media devices

+//

+#define EFI_REMOVABLE_MEDIA_FILE_NAME_IA32    L"\\EFI\\BOOT\\BOOTIA32.EFI"

+#define EFI_REMOVABLE_MEDIA_FILE_NAME_IA64    L"\\EFI\\BOOT\\BOOTIA64.EFI"

+#define EFI_REMOVABLE_MEDIA_FILE_NAME_X64     L"\\EFI\\BOOT\\BOOTX64.EFI"

+#define EFI_REMOVABLE_MEDIA_FILE_NAME_EBC     L"\\EFI\\BOOT\\BOOTEBC.EFI"

+

+#if   defined (MDE_CPU_IA32)

+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_IA32

+#elif defined (MDE_CPU_IPF)

+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_IA64

+#elif defined (MDE_CPU_X64)

+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_X64

+#elif defined (MDE_CPU_EBC)

+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_EBC

+#else

+  #error Unknown Processor Type

+#endif

+

+

+//

+// Protocols from EFI 1.10 that got thier names fixed in UEFI 2.0

+//

+#include <Protocol/LoadedImage.h>

+#include <Protocol/SimpleTextIn.h>

+#include <Protocol/SimpleTextOut.h>

+#include <Protocol/SerialIo.h>

+#include <Protocol/LoadFile.h>

+#include <Protocol/SimpleFileSystem.h>

+#include <Protocol/DiskIo.h>

+#include <Protocol/BlockIo.h>

+#include <Protocol/UnicodeCollation.h>

+#include <Protocol/SimpleNetwork.h>

+#include <Protocol/EfiNetworkInterfaceIdentifier.h>

+#include <Protocol/PxeBaseCode.h>

+#include <Protocol/PxeBaseCodeCallBack.h>

+

+//

+// EFI 1.10 Protocols

+//

+#include <Protocol/Bis.h>

+#include <Protocol/BusSpecificDriverOverride.h>

+#include <Protocol/ComponentName.h>

+#include <Protocol/DebugPort.h>

+#include <Protocol/DebugSupport.h>

+#include <Protocol/Decompress.h>

+#include <Protocol/DriverBinding.h>

+#include <Protocol/DriverConfiguration.h>

+#include <Protocol/DriverDiagnostics.h>

+#include <Protocol/Ebc.h>

+#include <Protocol/EfiNetworkInterfaceIdentifier.h>

+#include <Protocol/FileInfo.h>

+#include <Protocol/FileSystemInfo.h>

+#include <Protocol/FileSystemVolumeLabelInfo.h>

+#include <Protocol/PciIo.h>

+#include <Protocol/PciRootBridgeIo.h>

+#include <Protocol/PlatformDriverOverride.h>

+#include <Protocol/SimplePointer.h>

+#include <Protocol/ScsiPassThru.h>

+#include <Protocol/UsbIo.h>

+#include <Protocol/UsbHostController.h>

+#include <Protocol/UgaDraw.h>

+

+//

+// EFI 1.10 GUIDs

+//

+#include <Guid/Acpi.h>

+#include <Guid/DebugImageInfoTable.h>

+#include <Guid/GlobalVariable.h>

+#include <Guid/Gpt.h>

+#include <Guid/PcAnsi.h>

+#include <Guid/SmBios.h>

+#include <Guid/SalSystemTable.h>

+

+

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+//

+// Turn on UEFI 2.0 Protocols and GUIDs

+//

+#include <Protocol/AuthenticationInfo.h>

+#include <Protocol/DevicePathUtilities.h>

+#include <Protocol/DevicePathToText.h>

+#include <Protocol/DevicePathFromText.h>

+#include <Protocol/GraphicsOutput.h>

+#include <Protocol/EdidDiscovered.h>

+#include <Protocol/EdidActive.h>

+#include <Protocol/EdidOverride.h>

+#include <Protocol/ScsiIo.h>

+#include <Protocol/ScsiPassThruExt.h>

+#include <Protocol/IScsiInitatorName.h>

+#include <Protocol/Usb2HostController.h>

+#include <Protocol/TapeIo.h>

+#include <Protocol/ManagedNetwork.h>

+#include <Protocol/Arp.h>

+#include <Protocol/Dhcp4.h>

+#include <Protocol/IP4.h>

+#include <Protocol/IP4Config.h>

+#include <Protocol/Tcp4.h>

+#include <Protocol/Udp4.h>

+#include <Protocol/Mtftp4.h>

+#include <Protocol/ServiceBinding.h>

+#include <Protocol/Hash.h>

+

+#include <Guid/EventGroup.h>

+//#include <Guid/WinCertificateUefi.h>

+#endif

+

+

+#endif

diff --git a/edk2/MdePkg/Include/x64/ProcessorBind.h b/edk2/MdePkg/Include/x64/ProcessorBind.h
new file mode 100644
index 0000000..c61966e
--- /dev/null
+++ b/edk2/MdePkg/Include/x64/ProcessorBind.h
@@ -0,0 +1,193 @@
+/** @file

+  Processor or Compiler specific defines and types x64 (Intel(r) EM64T, AMD64).

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  ProcessorBind.h

+

+**/

+

+#ifndef __PROCESSOR_BIND_H__

+#define __PROCESSOR_BIND_H__

+

+//

+// Define the processor type so other code can make processor based choices

+//

+#define MDE_CPU_X64

+

+

+//

+// Make sure we are useing the correct packing rules per EFI specification

+//

+#pragma pack()

+

+

+#if _MSC_EXTENSIONS 

+    

+//

+// Disable warning that make it impossible to compile at /W4

+// This only works for Microsoft* tools

+//

+

+//

+// Disabling bitfield type checking warnings.

+//

+#pragma warning ( disable : 4214 )

+

+//

+// Disabling the unreferenced formal parameter warnings.

+//

+#pragma warning ( disable : 4100 )

+

+//

+// Disable slightly different base types warning as CHAR8 * can not be set

+// to a constant string.

+//

+#pragma warning ( disable : 4057 )

+

+//

+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning

+//

+#pragma warning ( disable : 4127 )

+

+

+#endif

+

+

+#if (__STDC_VERSION__ < 199901L)

+  //

+  // No ANSI C 2000 stdint.h integer width declarations, so define equivalents

+  //

+ 

+  #if _MSC_EXTENSIONS 

+    

+

+    //

+    // use Microsoft C complier dependent interger width types 

+    //

+    typedef unsigned __int64    UINT64;

+    typedef __int64             INT64;

+    typedef unsigned __int32    UINT32;

+    typedef __int32             INT32;

+    typedef unsigned short      UINT16;

+    typedef unsigned short      CHAR16;

+    typedef short               INT16;

+    typedef unsigned char       BOOLEAN;

+    typedef unsigned char       UINT8;

+    typedef char                CHAR8;

+    typedef char                INT8;

+  #else

+    #ifdef _EFI_P64 

+      //

+      // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints 

+      //  are 32-bits

+      //

+      typedef unsigned long long  UINT64;

+      typedef long long           INT64;

+      typedef unsigned int        UINT32;

+      typedef int                 INT32;

+      typedef unsigned short      CHAR16;

+      typedef unsigned short      UINT16;

+      typedef short               INT16;

+      typedef unsigned char       BOOLEAN;

+      typedef unsigned char       UINT8;

+      typedef char                CHAR8;

+      typedef char                INT8;

+    #else

+      //

+      // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit.

+      //

+      typedef unsigned long   UINT64;

+      typedef long            INT64;

+      typedef unsigned int    UINT32;

+      typedef int             INT32;

+      typedef unsigned short  UINT16;

+      typedef unsigned short  CHAR16;

+      typedef short           INT16;

+      typedef unsigned char   BOOLEAN;

+      typedef unsigned char   UINT8;

+      typedef char            CHAR8;

+      typedef char            INT8;

+    #endif

+  #endif

+

+  #define UINT8_MAX 0xff

+

+#else

+  //

+  // Use ANSI C 2000 stdint.h integer width declarations

+  //

+  #include <stdint.h>

+  typedef uint8_t   BOOLEAN;

+  typedef int8_t    INT8;

+  typedef uint8_t   UINT8;

+  typedef int16_t   INT16;

+  typedef uint16_t  UINT16;

+  typedef int32_t   INT32;

+  typedef uint32_t  UINT32;

+  typedef int64_t   INT64;

+  typedef uint64_t  UINT64;

+  typedef char      CHAR8;

+  typedef uint16_t  CHAR16;

+

+#endif

+

+typedef UINT64  UINTN;

+typedef INT64   INTN;

+

+

+//

+// Processor specific defines

+//

+#define MAX_BIT     0x8000000000000000

+#define MAX_2_BITS  0xC000000000000000

+

+//

+// Maximum legal Itanium-based address

+//

+#define MAX_ADDRESS   0xFFFFFFFFFFFFFFFF

+

+//

+// Modifier to ensure that all protocol member functions and EFI intrinsics

+// use the correct C calling convention. All protocol member functions and

+// EFI intrinsics are required to modify thier member functions with EFIAPI.

+//

+#if _MSC_EXTENSIONS 

+  ///

+  /// Define the standard calling convention reguardless of optimization level.

+  /// __cdecl is Microsoft* specific C extension.

+  /// 

+  #define EFIAPI __cdecl  

+#elif __GNUC__

+  ///

+  /// Define the standard calling convention reguardless of optimization level.

+  /// efidecl is an extension to GCC that supports the differnece between x64

+  /// GCC ABI and x64 Microsoft* ABI. EFI is closer to the Microsoft* ABI and

+  /// EFIAPI makes sure the right ABI is used for public interfaces. 

+  /// eficecl is a work in progress and we do not yet have the compiler

+  ///

+  #define EFIAPI __attribute__((efidecl))    

+#else

+  #define EFIAPI       

+#endif

+

+//

+// The Microsoft* C compiler can removed references to unreferenced data items

+//  if the /OPT:REF linker option is used. We defined a macro as this is a 

+//  a non standard extension

+//

+#if _MSC_EXTENSIONS

+  #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)

+#else

+  #define GLOBAL_REMOVE_IF_UNREFERENCED

+#endif

+

+#endif

+

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.mbd b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.mbd
new file mode 100644
index 0000000..a0be253
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseCacheMaintenanceLib</BaseName>

+    <Guid>123dd843-57c9-4158-8418-ce68b3944ce7</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.msa b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.msa
new file mode 100644
index 0000000..30c4f1f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.msa
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://nwlxweb02.jf.intel.com/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseCacheMaintenanceLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>123dd843-57c9-4158-8418-ce68b3944ce7</Guid>

+    <Version>0</Version>

+    <Abstract>Library Dependencies:BaseLib</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">CacheMaintenanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>x86Cache.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x86Cache.c</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>EbcCache.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>IpfCache.c</Filename>

+      <Filename>Ipf/Cpu.s</Filename>

+      <Filename>Ipf/CallPalProc.s</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/EbcCache.c b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/EbcCache.c
new file mode 100644
index 0000000..3a0f6f2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/EbcCache.c
@@ -0,0 +1,231 @@
+/** @file

+  Cache Maintenance Functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, the no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache lines to

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+

+  @param  Length  The number of bytes to invalidate from the instruction cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+}

+

+/**

+  Writes Back and Invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes Back and Invalidate the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, the no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back and invalidate from the

+                  data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+}

+

+/**

+  Writes Back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes Back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, the no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing

+                  mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, the no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to invalidate. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing mode,

+                  then Address is a virtual address.

+  @param  Length  The number of bytes to invalidate from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/Ipf/CallPalProc.s b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/Ipf/CallPalProc.s
new file mode 100644
index 0000000..18b0f58
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/Ipf/CallPalProc.s
@@ -0,0 +1,38 @@
+/// @file

+///   Contains an implementation of CallPalProcStatic on Itanium-based

+///   architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  CallPalProc.s

+///

+///

+

+.auto

+.text

+

+.proc   CallPalProcStatic

+.type   CallPalProcStatic, @function

+CallPalProcStatic::

+        mov                 r9  = ar.k5

+        mov                 r8  = ip

+        add                 r8  = (PalProcReturn - CallPalProcStatic), r8

+        mov                 r28 = r32

+        mov                 b7  = r9

+        mov                 r29 = r33

+        mov                 r30 = r34

+        mov                 r31 = r35

+        mov                 r32 = b0

+        mov                 b0  = r8

+        br.sptk             b7

+PalProcReturn:

+        mov                 b0 = r32

+        br.ret.sptk.many    b0

+.endp   CallPalProcStatic

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/Ipf/Cpu.s b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/Ipf/Cpu.s
new file mode 100644
index 0000000..4f144c6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/Ipf/Cpu.s
@@ -0,0 +1,106 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+//  Module Name:

+//

+//    Cpu.s 

+//

+//  Abstract:

+//

+//

+// Revision History:

+//

+//--

+

+  .file  "Cpu.s"

+  .radix  D

+  .section  .text,  "ax", "progbits"

+  .align 32

+  .section  .pdata,  "a", "progbits"

+  .align 4

+  .section  .xdata,  "a", "progbits"

+  .align 8

+  .section  .data,  "wa", "progbits"

+  .align 16

+  .section  .rdata,  "a", "progbits"

+  .align 16

+  .section  .bss,  "wa", "nobits"

+  .align 16

+  .section  .tls$,  "was", "progbits"

+  .align 16

+  .section  .sdata,  "was", "progbits"

+  .align 16

+  .section  .sbss,  "was", "nobits"

+  .align 16

+  .section  .srdata,  "as", "progbits"

+  .align 16

+  .section  .rdata,  "a", "progbits"

+  .align 16

+  .section  .rtcode,  "ax", "progbits"

+  .align 32

+  .type  InvalidateInstructionCacheRange#  ,@function 

+        .global InvalidateInstructionCacheRange#

+// Function compile flags: /Ogsy

+  .section  .rtcode

+

+// Begin code for function: InvalidateInstructionCacheRange:

+  .proc  InvalidateInstructionCacheRange#

+  .align 32

+InvalidateInstructionCacheRange:  

+// File e:\tmp\pioflush.c

+ {   .mii  //R-Addr: 0X00 

+  alloc  r3=2, 0, 0, 0              //11, 00000002H

+  cmp4.leu p0,p6=32, r33;;          //15, 00000020H

+  (p6)  mov  r33=32;;               //16, 00000020H

+ }

+ {   .mii  //R-Addr: 0X010 

+  nop.m   0

+  zxt4  r29=r33;;                   //21

+  dep.z  r30=r29, 0, 5;;            //21, 00000005H

+ }

+ {   .mii  //R-Addr: 0X020 

+  cmp4.eq  p0,p7=r0, r30            //21

+  shr.u  r28=r29, 5;;               //19, 00000005H

+  (p7)  adds  r28=1, r28;;          //22, 00000001H

+ }

+ {   .mii  //R-Addr: 0X030 

+  nop.m   0

+  shl  r27=r28, 5;;             //25, 00000005H

+  zxt4  r26=r27;;               //25

+ }

+ {   .mfb  //R-Addr: 0X040 

+  add  r31=r26, r32             //25

+  nop.f   0

+  nop.b   0

+ }

+$L143:

+ {   .mii  //R-Addr: 0X050 

+  fc   r32                        //27

+  adds  r32=32, r32;;             //28, 00000020H

+  cmp.ltu  p14,p15=r32, r31       //29

+ }

+ {   .mfb  //R-Addr: 0X060 

+  nop.m   0

+  nop.f   0

+  (p14)  br.cond.dptk.few $L143#;;  //29, 880000/120000

+ }

+ {   .mmi

+    sync.i;;

+    srlz.i

+    nop.i   0;;

+ }

+ {   .mfb  //R-Addr: 0X070 

+  nop.m   0

+  nop.f   0

+  br.ret.sptk.few b0;;            //31

+ }

+// End code for function:

+  .endp  InvalidateInstructionCacheRange#

+// END

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/IpfCache.c b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/IpfCache.c
new file mode 100644
index 0000000..b37ac9e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/IpfCache.c
@@ -0,0 +1,261 @@
+/** @file

+  Cache Maintenance Functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+typedef struct {

+  UINT64                            Status;

+  UINT64                            r9;

+  UINT64                            r10;

+  UINT64                            r11;

+} PAL_PROC_RETURN;

+

+PAL_PROC_RETURN

+CallPalProcStatic (

+  IN      UINT64                    Arg1,

+  IN      UINT64                    Arg2,

+  IN      UINT64                    Arg3,

+  IN      UINT64                    Arg4

+  );

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+  CallPalProcStatic (1, 1, 1, 0);

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, the no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache lines to

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+

+  @param  Length  The number of bytes to invalidate from the instruction cache.

+

+  @return Address

+

+**/

+VOID*

+EFIAPI

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+

+  if (Length > 0) {

+    InvalidateInstructionCache ();

+  }

+  return Address;

+}

+

+/**

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+  CallPalProcStatic (1, 2, 1, 0);

+}

+

+/**

+  Writes Back and Invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes Back and Invalidate the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, the no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back and invalidate from the

+                  data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+

+  if (Length > 0) {

+    WriteBackInvalidateDataCache ();

+  }

+  return Address;

+}

+

+/**

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+  CallPalProcStatic (1, 2, 0, 0);

+}

+

+/**

+  Writes Back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes Back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, the no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing

+                  mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+

+  if (Length > 0) {

+    WriteBackDataCache ();

+  }

+  return Address;

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+  WriteBackInvalidateDataCache ();

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, the no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to invalidate. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing mode,

+                  then Address is a virtual address.

+  @param  Length  The number of bytes to invalidate from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return WriteBackInvalidateDataCacheRange (Address, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/build.xml b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/build.xml
new file mode 100644
index 0000000..990fd68
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseCacheMaintenanceLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseCacheMaintenanceLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseCacheMaintenanceLib">

+      <GenBuild baseName="BaseCacheMaintenanceLib" mbdFilename="${MODULE_DIR}/BaseCacheMaintenanceLib.mbd" msaFilename="${MODULE_DIR}/BaseCacheMaintenanceLib.msa"/>

+   </target>

+   <target depends="BaseCacheMaintenanceLib_clean" name="clean"/>

+   <target depends="BaseCacheMaintenanceLib_cleanall" name="cleanall"/>

+   <target name="BaseCacheMaintenanceLib_clean">

+      <OutputDirSetup baseName="BaseCacheMaintenanceLib" mbdFilename="${MODULE_DIR}/BaseCacheMaintenanceLib.mbd" msaFilename="${MODULE_DIR}/BaseCacheMaintenanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseCacheMaintenanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseCacheMaintenanceLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseCacheMaintenanceLib_cleanall">

+      <OutputDirSetup baseName="BaseCacheMaintenanceLib" mbdFilename="${MODULE_DIR}/BaseCacheMaintenanceLib.mbd" msaFilename="${MODULE_DIR}/BaseCacheMaintenanceLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseCacheMaintenanceLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseCacheMaintenanceLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseCacheMaintenanceLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseCacheMaintenanceLib/x86Cache.c b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/x86Cache.c
new file mode 100644
index 0000000..3879cdf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseCacheMaintenanceLib/x86Cache.c
@@ -0,0 +1,246 @@
+/** @file

+  Cache Maintenance Functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  x86Cache.c

+

+**/

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, the no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache lines to

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+

+  @param  Length  The number of bytes to invalidate from the instruction cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+  AsmWbinvd ();

+}

+

+/**

+  Writes Back and Invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes Back and Invalidate the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, the no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  invalidate. If the CPU is in a physical addressing mode, then

+                  Address is a physical address. If the CPU is in a virtual

+                  addressing mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back and invalidate from the

+                  data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  UINT8                             (*Uint8Ptr)[32];

+

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+

+  Uint8Ptr = Address;

+  while (Length > sizeof (*Uint8Ptr)) {

+    AsmFlushCacheLine (Uint8Ptr++);

+    Length -= sizeof (*Uint8Ptr);

+  }

+  if (Length > 0) {

+    AsmFlushCacheLine (Uint8Ptr);

+    AsmFlushCacheLine (&(*Uint8Ptr)[Length - 1]);

+  }

+  return Address;

+}

+

+/**

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+  WriteBackInvalidateDataCache ();

+}

+

+/**

+  Writes Back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes Back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, the no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing

+                  mode, then Address is a virtual address.

+  @param  Length  The number of bytes to write back from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return WriteBackInvalidateDataCacheRange (Address, Length);

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+  AsmInvd ();

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, the no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to invalidate. If

+                  the CPU is in a physical addressing mode, then Address is a

+                  physical address. If the CPU is in a virtual addressing mode,

+                  then Address is a virtual address.

+  @param  Length  The number of bytes to invalidate from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return WriteBackInvalidateDataCacheRange (Address, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.mbd b/edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.mbd
new file mode 100644
index 0000000..6463e09
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseDebugLibNull</BaseName>

+    <Guid>9ba1d976-0624-41a3-8650-28165e8d9ae8</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.msa b/edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.msa
new file mode 100644
index 0000000..24e2a16
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.msa
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseDebugLibNull</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>9ba1d976-0624-41a3-8650-28165e8d9ae8</Guid>

+    <Version>0</Version>

+    <Abstract>NULL Debug Library for UEFI drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseDebugLibNull/DebugLib.c b/edk2/MdePkg/Library/BaseDebugLibNull/DebugLib.c
new file mode 100644
index 0000000..35aea32
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibNull/DebugLib.c
@@ -0,0 +1,225 @@
+/** @file

+  Base Debug Library that uses PrintLib to print messages to a memory buffer.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+**/

+

+//

+// Define the maximum debug and assert message length that this library supports 

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+/**

+

+  Prints a debug message to the debug output device if the specified error level is enabled.

+

+  If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print 

+  the message specified by Format and the associated variable argument list to 

+  the debug output device.

+

+  If Format is NULL, then ASSERT().

+

+  @param  ErrorLevel  The error level of the debug message.

+  @param  Format      Format string for the debug message to print.

+

+**/

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN        ErrorLevel,

+  IN  CONST CHAR8  *Format,

+  ...

+  )

+{

+  CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Print the assert message to a buffer

+  //

+  VA_START (Marker, Format);

+  AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);

+  VA_END (Marker);

+}

+

+

+/**

+

+  Prints an assert message containing a filename, line number, and description.  

+  This may be followed by a breakpoint or a dead loop.

+

+  Print a message of the form “ASSERT <FileName>(<LineNumber>): <Description>\n” 

+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 

+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 

+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 

+  CpuDeadLoop() is called.  If neither of these bits are set, then this function 

+  returns immediately after the message is printed to the debug output device.

+  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while

+  processing another DebugAssert(), then DebugAssert() must return immediately.

+

+  If FileName is NULL, then a <FileName> string of “(NULL) Filename” is printed.

+

+  If Description is NULL, then a <Description> string of “(NULL) Description” is printed.

+

+  @param  FileName     Pointer to the name of the source file that generated the assert condition.

+  @param  LineNumber   The line number in the source file that generated the assert condition

+  @param  Description  Pointer to the description of the assert condition.

+

+**/

+VOID

+EFIAPI

+DebugAssert (

+  IN CONST CHAR8  *FileName,

+  IN INTN         LineNumber,

+  IN CONST CHAR8  *Description

+  )

+{

+  CHAR8  Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Print the assert message to a buffer

+  //

+  AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT %s(%d): %s\n", FileName, LineNumber, Description);

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param   Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param   Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  

+  Returns TRUE if ASSERT() macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CODE()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/BaseDebugLibNull/build.xml b/edk2/MdePkg/Library/BaseDebugLibNull/build.xml
new file mode 100644
index 0000000..72c80ab
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibNull/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseDebugLibNull"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseDebugLibNull"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseDebugLibNull">

+      <GenBuild baseName="BaseDebugLibNull" mbdFilename="${MODULE_DIR}/BaseDebugLibNull.mbd" msaFilename="${MODULE_DIR}/BaseDebugLibNull.msa"/>

+   </target>

+   <target depends="BaseDebugLibNull_clean" name="clean"/>

+   <target depends="BaseDebugLibNull_cleanall" name="cleanall"/>

+   <target name="BaseDebugLibNull_clean">

+      <OutputDirSetup baseName="BaseDebugLibNull" mbdFilename="${MODULE_DIR}/BaseDebugLibNull.mbd" msaFilename="${MODULE_DIR}/BaseDebugLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseDebugLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseDebugLibNull_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseDebugLibNull_cleanall">

+      <OutputDirSetup baseName="BaseDebugLibNull" mbdFilename="${MODULE_DIR}/BaseDebugLibNull.mbd" msaFilename="${MODULE_DIR}/BaseDebugLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseDebugLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseDebugLibNull_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseDebugLibNull*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.mbd b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.mbd
new file mode 100644
index 0000000..0fc959a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseDebugLibReportStatusCode</BaseName>

+    <Guid>bda39d3a-451b-4350-8266-81ab10fa0523</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.msa b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.msa
new file mode 100644
index 0000000..b2ef0e3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.msa
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseDebugLibReportStatusCode</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>bda39d3a-451b-4350-8266-81ab10fa0523</Guid>

+    <Version>0</Version>

+    <Abstract>Debug Library for PEIMs that send debug messages to ReportStatusCode</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/DebugLib.c b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/DebugLib.c
new file mode 100644
index 0000000..d330c0f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/DebugLib.c
@@ -0,0 +1,283 @@
+/** @file

+  Debug Library that fowards all messages to ReportStatusCode()

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+

+/**

+

+  Prints a debug message to the debug output device if the specified error level is enabled.

+

+  If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print 

+  the message specified by Format and the associated variable argument list to 

+  the debug output device.

+

+  If Format is NULL, then ASSERT().

+

+  @param  ErrorLevel  The error level of the debug message.

+  @param  Format      Format string for the debug message to print.

+

+**/

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN        ErrorLevel,

+  IN  CONST CHAR8  *Format,

+  ...

+  )

+{

+  UINT64          Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)];

+  EFI_DEBUG_INFO  *DebugInfo;

+  UINTN           TotalSize;

+  UINTN           Index;

+  VA_LIST         Marker;

+  UINT64          *ArgumentPointer;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver Debug Level value and global debug level

+  //

+  if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+    return;

+  }

+

+  TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrLen (Format) + 1;

+  if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {

+    return;

+  }

+

+  //

+  // Then EFI_DEBUG_INFO

+  //

+  DebugInfo = (EFI_DEBUG_INFO *)Buffer;

+  DebugInfo->ErrorLevel = (UINT32)ErrorLevel;

+

+  //

+  // 256 byte mini Var Arg stack. That is followed by the format string.

+  //

+  VA_START (Marker, Format);

+  for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) {

+    *ArgumentPointer = VA_ARG (Marker, UINT64);

+  }

+  VA_END (Marker);

+  AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format);

+

+  //

+  //

+  //

+  REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+    EFI_DEBUG_CODE,

+    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),

+    DebugInfo,

+    TotalSize

+    );

+}

+

+

+/**

+

+  Prints an assert message containing a filename, line number, and description.  

+  This may be followed by a breakpoint or a dead loop.

+

+  Print a message of the form “ASSERT <FileName>(<LineNumber>): <Description>\n” 

+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 

+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 

+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 

+  CpuDeadLoop() is called.  If neither of these bits are set, then this function 

+  returns immediately after the message is printed to the debug output device.

+  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while

+  processing another DebugAssert(), then DebugAssert() must return immediately.

+

+  If FileName is NULL, then a <FileName> string of “(NULL) Filename” is printed.

+

+  If Description is NULL, then a <Description> string of “(NULL) Description” is printed.

+

+  @param  FileName     Pointer to the name of the source file that generated the assert condition.

+  @param  LineNumber   The line number in the source file that generated the assert condition

+  @param  Description  Pointer to the description of the assert condition.

+

+**/

+VOID

+EFIAPI

+DebugAssert (

+  IN CONST CHAR8  *FileName,

+  IN INTN         LineNumber,

+  IN CONST CHAR8  *Description

+  )

+{

+  UINT64                 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof(UINT64)];

+  EFI_DEBUG_ASSERT_DATA  *AssertData;

+  UINTN                  TotalSize;

+  CHAR8                  *Temp;

+

+  //

+  // Make sure it will all fit in the passed in buffer

+  //

+  TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA) + AsciiStrLen (FileName) + 1 + AsciiStrLen (Description) + 1;

+  if (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE) {

+    //

+    // Fill in EFI_DEBUG_ASSERT_DATA

+    //

+    AssertData = (EFI_DEBUG_ASSERT_DATA *)Buffer;

+    AssertData->LineNumber = (UINT32)LineNumber;

+

+    //

+    // Copy Ascii FileName including NULL.

+    //

+    Temp = AsciiStrCpy ((CHAR8 *)(AssertData + 1), FileName);

+

+    //

+    // Copy Ascii Description 

+    //

+    AsciiStrCpy (Temp + AsciiStrLen(FileName) + 1, Description);

+

+    REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+      (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),

+      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),

+      AssertData,

+      TotalSize

+      );

+  }

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param   Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param   Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  

+  Returns TRUE if ASSERT() macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CODE()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/build.xml b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/build.xml
new file mode 100644
index 0000000..cd85f35
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseDebugLibReportStatusCode/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseDebugLibReportStatusCode"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseDebugLibReportStatusCode"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseDebugLibReportStatusCode">

+      <GenBuild baseName="BaseDebugLibReportStatusCode" mbdFilename="${MODULE_DIR}/BaseDebugLibReportStatusCode.mbd" msaFilename="${MODULE_DIR}/BaseDebugLibReportStatusCode.msa"/>

+   </target>

+   <target depends="BaseDebugLibReportStatusCode_clean" name="clean"/>

+   <target depends="BaseDebugLibReportStatusCode_cleanall" name="cleanall"/>

+   <target name="BaseDebugLibReportStatusCode_clean">

+      <OutputDirSetup baseName="BaseDebugLibReportStatusCode" mbdFilename="${MODULE_DIR}/BaseDebugLibReportStatusCode.mbd" msaFilename="${MODULE_DIR}/BaseDebugLibReportStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseDebugLibReportStatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseDebugLibReportStatusCode_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseDebugLibReportStatusCode_cleanall">

+      <OutputDirSetup baseName="BaseDebugLibReportStatusCode" mbdFilename="${MODULE_DIR}/BaseDebugLibReportStatusCode.mbd" msaFilename="${MODULE_DIR}/BaseDebugLibReportStatusCode.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseDebugLibReportStatusCode_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseDebugLibReportStatusCode_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseDebugLibReportStatusCode*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.mbd b/edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.mbd
new file mode 100644
index 0000000..8f0c690
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.mbd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseIoLibIntrinsic</BaseName>

+    <Guid>926c9cd0-4bb8-479b-9ac4-8a2a23f85307</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+  <BuildOptions ToolChain="MSFT">

+    <Option>C_PROJ_FLAGS = ${C_PROJ_FLAGS}</Option>

+  </BuildOptions>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.msa b/edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.msa
new file mode 100644
index 0000000..8ceb32e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.msa
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseIoLibIntrinsic</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>926c9cd0-4bb8-479b-9ac4-8a2a23f85307</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>IoLib.c</Filename>

+      <Filename>IoLibMsc.c</Filename>

+      <Filename>IoLibGcc.c</Filename>

+      <Filename>IoHighLevel.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>IoLib.c</Filename>

+      <Filename>IoLibMsc.c</Filename>

+      <Filename>IoLibGcc.c</Filename>

+      <Filename>IoHighLevel.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
new file mode 100644
index 0000000..48a7477
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
@@ -0,0 +1,2272 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoHighLevel.c

+

+  The following IoLib instances share the same version of this file:

+

+    BaseIoLibIntrinsic

+    DxeIoLibCpuIo

+    PeiIoLibCpuIo

+

+**/

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, IoRead8 (Port) | OrData);

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, IoRead8 (Port) & AndData);

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (IoRead8 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, IoRead16 (Port) | OrData);

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, IoRead16 (Port) & AndData);

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (IoRead16 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 64-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, MmioRead8 (Address) | OrData);

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, MmioRead8 (Address) & AndData);

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (MmioRead8 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, MmioRead16 (Address) | OrData);

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, MmioRead16 (Address) & AndData);

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (MmioRead16 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 64-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 64-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
new file mode 100644
index 0000000..126457a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
@@ -0,0 +1,255 @@
+/** @file

+  Common I/O Library routines.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoLib.c

+

+**/

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return *(volatile UINT8*)Address;

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return *(volatile UINT8*)Address = Value;

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT ((Address & 1) == 0);

+  return *(volatile UINT16*)Address;

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Address & 1) == 0);

+  return *(volatile UINT16*)Address = Value;

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT ((Address & 3) == 0);

+  return *(volatile UINT32*)Address;

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Address & 3) == 0);

+  return *(volatile UINT32*)Address = Value;

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT ((Address & 7) == 0);

+  return *(volatile UINT64*)Address;

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT ((Address & 7) == 0);

+  return *(volatile UINT64*)Address = Value;

+}

diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
new file mode 100644
index 0000000..a065c14
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
@@ -0,0 +1,194 @@
+/** @file

+  I/O Library. This file has compiler specifics for GCC as there is no

+  ANSI C standard for doing IO.

+

+  GCC - uses EFIAPI assembler. __asm__ calls GAS. __volatile__ makes sure the

+  compiler puts the assembler in this exact location. The complex GNUC

+  operations are not optimzed. It would be possible to also write these

+  with EFIAPI assembler.

+

+  We don't advocate putting compiler specifics in libraries or drivers but there

+  is no other way to make this work.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoLibGcc.c

+

+**/

+

+#ifdef __GNUC__

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+__inline__

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  UINT8   Data;

+

+  __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));

+  return Data;

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+__inline__

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));

+  return Value;;

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+__inline__

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  UINT16   Data;

+

+  ASSERT ((Port & 1) == 0);

+  __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));

+  return Data;

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+__inline__

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Port & 1) == 0);

+  __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));

+  return Value;;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+__inline__

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  UINT32   Data;

+

+  ASSERT ((Port & 3) == 0);

+  __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));

+  return Data;

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+__inline__

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32  Value

+  )

+{

+  ASSERT ((Port & 3) == 0);

+  __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));

+  return Value;

+}

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
new file mode 100644
index 0000000..8bce7a5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
@@ -0,0 +1,193 @@
+/** @file

+  I/O Library. This file has compiler specifics for Microsft C as there is no

+  ANSI C standard for doing IO.

+

+  MSC - uses intrinsic functions and the optimize will remove the function call

+  overhead.

+

+  We don't advocate putting compiler specifics in libraries or drivers but there

+  is no other way to make this work.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoLibMsc.c

+

+**/

+

+

+#if _MSC_EXTENSIONS

+

+//

+// Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics

+//

+int            _inp  (unsigned short port);

+unsigned short _inpw (unsigned short port);

+unsigned long  _inpd (unsigned short port);

+int            _outp (unsigned short port, int databyte );

+unsigned short _outpw(unsigned short port, unsigned short dataword );

+unsigned long  _outpd(unsigned short port, unsigned long dataword );

+

+#pragma intrinsic(_inp)

+#pragma intrinsic(_inpw)

+#pragma intrinsic(_inpd)

+#pragma intrinsic(_outp)

+#pragma intrinsic(_outpw)

+#pragma intrinsic(_outpd)

+

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  return (UINT8)_inp ((UINT16)Port);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)_outp ((UINT16)Port, Value);

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT ((Port & 1) == 0);

+  return _inpw((UINT16)Port);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Port & 1) == 0);

+  return _outpw ((UINT16)Port, Value);

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT ((Port & 3) == 0);

+  return _inpd((UINT16)Port);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Port & 3) == 0);

+  return _outpd ((UINT16)Port, Value);

+}

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseIoLibIntrinsic/build.xml b/edk2/MdePkg/Library/BaseIoLibIntrinsic/build.xml
new file mode 100644
index 0000000..9e5a3b3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseIoLibIntrinsic/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseIoLibIntrinsic"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseIoLibIntrinsic"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseIoLibIntrinsic">

+      <GenBuild baseName="BaseIoLibIntrinsic" mbdFilename="${MODULE_DIR}/BaseIoLibIntrinsic.mbd" msaFilename="${MODULE_DIR}/BaseIoLibIntrinsic.msa"/>

+   </target>

+   <target depends="BaseIoLibIntrinsic_clean" name="clean"/>

+   <target depends="BaseIoLibIntrinsic_cleanall" name="cleanall"/>

+   <target name="BaseIoLibIntrinsic_clean">

+      <OutputDirSetup baseName="BaseIoLibIntrinsic" mbdFilename="${MODULE_DIR}/BaseIoLibIntrinsic.mbd" msaFilename="${MODULE_DIR}/BaseIoLibIntrinsic.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseIoLibIntrinsic_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseIoLibIntrinsic_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseIoLibIntrinsic_cleanall">

+      <OutputDirSetup baseName="BaseIoLibIntrinsic" mbdFilename="${MODULE_DIR}/BaseIoLibIntrinsic.mbd" msaFilename="${MODULE_DIR}/BaseIoLibIntrinsic.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseIoLibIntrinsic_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseIoLibIntrinsic_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseIoLibIntrinsic*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseLib/ARShiftU64.c b/edk2/MdePkg/Library/BaseLib/ARShiftU64.c
new file mode 100644
index 0000000..feb5430
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/ARShiftU64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Shifts a 64-bit integer right between 0 and 63 bits. The high bits are filled

+  with original integer's bit 63. The shifted value is returned.

+

+  This function shifts the 64-bit value Operand to the right by Count bits. The

+  high Count bits are set to bit 63 of Operand.  The shifted value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand arithmetically shifted right by Count

+

+**/

+UINT64

+EFIAPI

+ARShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return InternalMathARShiftU64 (Operand, Count);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/BaseLib-Gcc.msa b/edk2/MdePkg/Library/BaseLib/BaseLib-Gcc.msa
new file mode 100644
index 0000000..1957312
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/BaseLib-Gcc.msa
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>27d67720-ea68-48ae-93da-a3a074c90e30</Guid>

+    <Version>0</Version>

+    <Abstract>Memory-only library functions with no library constructordestructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-22 18:15</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TimerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>String.c</Filename>

+    <Filename>LinkedList.c</Filename>

+    <Filename>Synchronization.c</Filename>

+    <Filename>Cpu.c</Filename>

+    <Filename>CpuDeadLoop.c</Filename>

+    <Filename>BitField.c</Filename>

+    <Filename>ARShiftU64.c</Filename>

+    <Filename>DivS64x64Remainder.c</Filename>

+    <Filename>DivU64x32.c</Filename>

+    <Filename>DivU64x32Remainder.c</Filename>

+    <Filename>DivU64x64Remainder.c</Filename>

+    <Filename>GetPowerOfTwo32.c</Filename>

+    <Filename>GetPowerOfTwo64.c</Filename>

+    <Filename>HighBitSet32.c</Filename>

+    <Filename>HighBitSet64.c</Filename>

+    <Filename>LowBitSet32.c</Filename>

+    <Filename>LowBitSet64.c</Filename>

+    <Filename>LRotU32.c</Filename>

+    <Filename>LRotU64.c</Filename>

+    <Filename>LShiftU64.c</Filename>

+    <Filename>ModU64x32.c</Filename>

+    <Filename>MultS64x64.c</Filename>

+    <Filename>MultU64x32.c</Filename>

+    <Filename>MultU64x64.c</Filename>

+    <Filename>RRotU32.c</Filename>

+    <Filename>RRotU64.c</Filename>

+    <Filename>RShiftU64.c</Filename>

+    <Filename>SwapBytes16.c</Filename>

+    <Filename>SwapBytes32.c</Filename>

+    <Filename>SwapBytes64.c</Filename>

+    <Arch ArchType="IA32">

+      <Filename>x86LowLevel.c</Filename>

+      <Filename>x86Thunk.c</Filename>

+      <Filename>Unaligned.c</Filename>

+      <Filename>LongJump.c</Filename>

+      <Filename>SwitchStack.c</Filename>

+      <Filename>Ia32/Non-existing.c</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/LShiftU64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/RShiftU64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ARShiftU64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/LRotU64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/RRotU64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/MultU64x32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/MultU64x64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/DivU64x32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ModU64x32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/DivU64x32Remainder.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/DivU64x64Remainder.s</Filename>

+      <Filename>Ia32/DivS64x64Remainder.c</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SwapBytes64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetJump.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/LongJump.s</Filename>

+      <Filename>Ia32/InternalSwitchStack.c</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CpuId.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadEflags.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMsr64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMsr32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMsr64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadCr0.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadCr2.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadCr3.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadCr4.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteCr0.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteCr2.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteCr3.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteCr4.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr0.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr1.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr2.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr3.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr4.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr5.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr6.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDr7.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr0.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr1.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr2.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr3.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr4.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr5.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr6.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteDr7.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadCs.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadDs.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadEs.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadFs.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadGs.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadSs.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadTr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadGdtr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteGdtr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadIdtr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteIdtr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadLdtr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteLdtr.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/FxSave.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/FxRestore.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm0.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm1.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm2.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm3.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm4.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm5.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm6.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadMm7.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm0.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm1.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm2.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm3.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm4.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm5.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm6.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/WriteMm7.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadTsc.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ReadPmc.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/Monitor.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/Mwait.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/EnablePaging32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/DisablePaging32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/EnablePaging64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/Wbinvd.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/Invd.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/FlushCacheLine.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/InterlockedIncrement.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/InterlockedDecrement.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/InterlockedCompareExchange32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/InterlockedCompareExchange64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/EnableInterrupts.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/DisableInterrupts.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/EnableDisableInterrupts.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CpuSleep.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CpuPause.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CpuBreakpoint.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CpuFlushTlb.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/Thunk16.s</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x86LowLevel.c</Filename>

+      <Filename>x86Thunk.c</Filename>

+      <Filename>Unaligned.c</Filename>

+      <Filename>Math64.c</Filename>

+      <Filename>LongJump.c</Filename>

+      <Filename>SwitchStack.c</Filename>

+      <Filename>x64/Non-existing.c</Filename>

+      <Filename>x64/SwitchStack.asm</Filename>

+      <Filename>x64/SetJump.asm</Filename>

+      <Filename>x64/LongJump.asm</Filename>

+      <Filename>x64/CpuId.asm</Filename>

+      <Filename>x64/ReadEflags.asm</Filename>

+      <Filename>x64/ReadMsr32.asm</Filename>

+      <Filename>x64/ReadMsr64.asm</Filename>

+      <Filename>x64/WriteMsr32.asm</Filename>

+      <Filename>x64/WriteMsr64.asm</Filename>

+      <Filename>x64/ReadCr0.asm</Filename>

+      <Filename>x64/ReadCr2.asm</Filename>

+      <Filename>x64/ReadCr3.asm</Filename>

+      <Filename>x64/ReadCr4.asm</Filename>

+      <Filename>x64/WriteCr0.asm</Filename>

+      <Filename>x64/WriteCr2.asm</Filename>

+      <Filename>x64/WriteCr3.asm</Filename>

+      <Filename>x64/WriteCr4.asm</Filename>

+      <Filename>x64/ReadDr0.asm</Filename>

+      <Filename>x64/ReadDr1.asm</Filename>

+      <Filename>x64/ReadDr2.asm</Filename>

+      <Filename>x64/ReadDr3.asm</Filename>

+      <Filename>x64/ReadDr4.asm</Filename>

+      <Filename>x64/ReadDr5.asm</Filename>

+      <Filename>x64/ReadDr6.asm</Filename>

+      <Filename>x64/ReadDr7.asm</Filename>

+      <Filename>x64/WriteDr0.asm</Filename>

+      <Filename>x64/WriteDr1.asm</Filename>

+      <Filename>x64/WriteDr2.asm</Filename>

+      <Filename>x64/WriteDr3.asm</Filename>

+      <Filename>x64/WriteDr4.asm</Filename>

+      <Filename>x64/WriteDr5.asm</Filename>

+      <Filename>x64/WriteDr6.asm</Filename>

+      <Filename>x64/WriteDr7.asm</Filename>

+      <Filename>x64/ReadCs.asm</Filename>

+      <Filename>x64/ReadDs.asm</Filename>

+      <Filename>x64/ReadEs.asm</Filename>

+      <Filename>x64/ReadFs.asm</Filename>

+      <Filename>x64/ReadGs.asm</Filename>

+      <Filename>x64/ReadSs.asm</Filename>

+      <Filename>x64/ReadTr.asm</Filename>

+      <Filename>x64/ReadGdtr.asm</Filename>

+      <Filename>x64/WriteGdtr.asm</Filename>

+      <Filename>x64/ReadIdtr.asm</Filename>

+      <Filename>x64/WriteIdtr.asm</Filename>

+      <Filename>x64/ReadLdtr.asm</Filename>

+      <Filename>x64/WriteLdtr.asm</Filename>

+      <Filename>x64/FxSave.asm</Filename>

+      <Filename>x64/FxRestore.asm</Filename>

+      <Filename>x64/ReadMm0.asm</Filename>

+      <Filename>x64/ReadMm1.asm</Filename>

+      <Filename>x64/ReadMm2.asm</Filename>

+      <Filename>x64/ReadMm3.asm</Filename>

+      <Filename>x64/ReadMm4.asm</Filename>

+      <Filename>x64/ReadMm5.asm</Filename>

+      <Filename>x64/ReadMm6.asm</Filename>

+      <Filename>x64/ReadMm7.asm</Filename>

+      <Filename>x64/WriteMm0.asm</Filename>

+      <Filename>x64/WriteMm1.asm</Filename>

+      <Filename>x64/WriteMm2.asm</Filename>

+      <Filename>x64/WriteMm3.asm</Filename>

+      <Filename>x64/WriteMm4.asm</Filename>

+      <Filename>x64/WriteMm5.asm</Filename>

+      <Filename>x64/WriteMm6.asm</Filename>

+      <Filename>x64/WriteMm7.asm</Filename>

+      <Filename>x64/ReadTsc.asm</Filename>

+      <Filename>x64/ReadPmc.asm</Filename>

+      <Filename>x64/Monitor.asm</Filename>

+      <Filename>x64/Mwait.asm</Filename>

+      <Filename>x64/DisablePaging64.asm</Filename>

+      <Filename>x64/Wbinvd.asm</Filename>

+      <Filename>x64/Invd.asm</Filename>

+      <Filename>x64/FlushCacheLine.asm</Filename>

+      <Filename>x64/InterlockedIncrement.asm</Filename>

+      <Filename>x64/InterlockedDecrement.asm</Filename>

+      <Filename>x64/InterlockedCompareExchange32.asm</Filename>

+      <Filename>x64/InterlockedCompareExchange64.asm</Filename>

+      <Filename>x64/EnableInterrupts.asm</Filename>

+      <Filename>x64/DisableInterrupts.asm</Filename>

+      <Filename>x64/EnableDisableInterrupts.asm</Filename>

+      <Filename>x64/CpuSleep.asm</Filename>

+      <Filename>x64/CpuPause.asm</Filename>

+      <Filename>x64/CpuBreakpoint.asm</Filename>

+      <Filename>x64/CpuFlushTlb.asm</Filename>

+      <Filename>x64/Thunk16.asm</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Math64.c</Filename>

+      <Filename>LongJump.c</Filename>

+      <Filename>SwitchStack.c</Filename>

+      <Filename>Ipf/setjmp.s</Filename>

+      <Filename>Ipf/SwitchStack.s</Filename>

+      <Filename>Ipf/Unaligned.c</Filename>

+      <Filename>Ipf/CpuBreakpoint.c</Filename>

+      <Filename>Ipf/InterlockedCompareExchange32.s</Filename>

+      <Filename>Ipf/InterlockedCompareExchange64.s</Filename>

+      <Filename>Ipf/Synchronization.c</Filename>

+      <Filename>Ipf/CpuPause.s</Filename>

+      <Filename>Ipf/CpuFlushTlb.s</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>Math64.c</Filename>

+      <Filename>Unaligned.c</Filename>

+      <Filename>Ebc/SwitchStack.c</Filename>

+      <Filename>Ebc/SetJumpLongJump.c</Filename>

+      <Filename>Ebc/CpuBreakpoint.c</Filename>

+      <Filename>Ebc/Synchronization.c</Filename>

+    </Arch>

+  </SourceFiles>

+ <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumAsciiStringLength</C_Name>

+      <Token>0x00000002</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumLinkedListLength</C_Name>

+      <Token>0x00000003</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdSpinLockTimeout</C_Name>

+      <Token>0x00000004</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseLib/BaseLib.mbd b/edk2/MdePkg/Library/BaseLib/BaseLib.mbd
new file mode 100644
index 0000000..971777a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/BaseLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseLib</BaseName>

+    <Guid>27d67720-ea68-48ae-93da-a3a074c90e30</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-22 18:15</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseLib/BaseLib.msa b/edk2/MdePkg/Library/BaseLib/BaseLib.msa
new file mode 100644
index 0000000..4f50169
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/BaseLib.msa
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>27d67720-ea68-48ae-93da-a3a074c90e30</Guid>

+    <Version>0</Version>

+    <Abstract>Memory-only library functions with no library constructordestructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-22 18:15</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">TimerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>String.c</Filename>

+    <Filename>LinkedList.c</Filename>

+    <Filename>Synchronization.c</Filename>

+    <Filename>Cpu.c</Filename>

+    <Filename>CpuDeadLoop.c</Filename>

+    <Filename>BitField.c</Filename>

+    <Filename>ARShiftU64.c</Filename>

+    <Filename>DivS64x64Remainder.c</Filename>

+    <Filename>DivU64x32.c</Filename>

+    <Filename>DivU64x32Remainder.c</Filename>

+    <Filename>DivU64x64Remainder.c</Filename>

+    <Filename>GetPowerOfTwo32.c</Filename>

+    <Filename>GetPowerOfTwo64.c</Filename>

+    <Filename>HighBitSet32.c</Filename>

+    <Filename>HighBitSet64.c</Filename>

+    <Filename>LowBitSet32.c</Filename>

+    <Filename>LowBitSet64.c</Filename>

+    <Filename>LRotU32.c</Filename>

+    <Filename>LRotU64.c</Filename>

+    <Filename>LShiftU64.c</Filename>

+    <Filename>ModU64x32.c</Filename>

+    <Filename>MultS64x64.c</Filename>

+    <Filename>MultU64x32.c</Filename>

+    <Filename>MultU64x64.c</Filename>

+    <Filename>RRotU32.c</Filename>

+    <Filename>RRotU64.c</Filename>

+    <Filename>RShiftU64.c</Filename>

+    <Filename>SwapBytes16.c</Filename>

+    <Filename>SwapBytes32.c</Filename>

+    <Filename>SwapBytes64.c</Filename>

+    <Arch ArchType="IA32">

+      <Filename>x86LowLevel.c</Filename>

+      <Filename>x86Thunk.c</Filename>

+      <Filename>Unaligned.c</Filename>

+      <Filename>LongJump.c</Filename>

+      <Filename>SwitchStack.c</Filename>

+      <Filename>Ia32/Non-existing.c</Filename>

+      <Filename>Ia32/InternalSwitchStack.c</Filename>

+      <Filename>Ia32/LShiftU64.asm</Filename>

+      <Filename>Ia32/RShiftU64.asm</Filename>

+      <Filename>Ia32/ARShiftU64.asm</Filename>

+      <Filename>Ia32/LRotU64.asm</Filename>

+      <Filename>Ia32/RRotU64.asm</Filename>

+      <Filename>Ia32/MultU64x32.asm</Filename>

+      <Filename>Ia32/MultU64x64.asm</Filename>

+      <Filename>Ia32/DivU64x32.asm</Filename>

+      <Filename>Ia32/ModU64x32.asm</Filename>

+      <Filename>Ia32/DivU64x32Remainder.asm</Filename>

+      <Filename>Ia32/DivU64x64Remainder.asm</Filename>

+      <Filename>Ia32/DivS64x64Remainder.c</Filename>

+      <Filename>Ia32/SwapBytes64.asm</Filename>

+      <Filename>Ia32/SetJump.asm</Filename>

+      <Filename>Ia32/LongJump.asm</Filename>

+      <Filename>Ia32/CpuId.asm</Filename>

+      <Filename>Ia32/ReadEflags.asm</Filename>

+      <Filename>Ia32/ReadMsr64.asm</Filename>

+      <Filename>Ia32/WriteMsr32.asm</Filename>

+      <Filename>Ia32/WriteMsr64.asm</Filename>

+      <Filename>Ia32/ReadCr0.asm</Filename>

+      <Filename>Ia32/ReadCr2.asm</Filename>

+      <Filename>Ia32/ReadCr3.asm</Filename>

+      <Filename>Ia32/ReadCr4.asm</Filename>

+      <Filename>Ia32/WriteCr0.asm</Filename>

+      <Filename>Ia32/WriteCr2.asm</Filename>

+      <Filename>Ia32/WriteCr3.asm</Filename>

+      <Filename>Ia32/WriteCr4.asm</Filename>

+      <Filename>Ia32/ReadDr0.asm</Filename>

+      <Filename>Ia32/ReadDr1.asm</Filename>

+      <Filename>Ia32/ReadDr2.asm</Filename>

+      <Filename>Ia32/ReadDr3.asm</Filename>

+      <Filename>Ia32/ReadDr4.asm</Filename>

+      <Filename>Ia32/ReadDr5.asm</Filename>

+      <Filename>Ia32/ReadDr6.asm</Filename>

+      <Filename>Ia32/ReadDr7.asm</Filename>

+      <Filename>Ia32/WriteDr0.asm</Filename>

+      <Filename>Ia32/WriteDr1.asm</Filename>

+      <Filename>Ia32/WriteDr2.asm</Filename>

+      <Filename>Ia32/WriteDr3.asm</Filename>

+      <Filename>Ia32/WriteDr4.asm</Filename>

+      <Filename>Ia32/WriteDr5.asm</Filename>

+      <Filename>Ia32/WriteDr6.asm</Filename>

+      <Filename>Ia32/WriteDr7.asm</Filename>

+      <Filename>Ia32/ReadCs.asm</Filename>

+      <Filename>Ia32/ReadDs.asm</Filename>

+      <Filename>Ia32/ReadEs.asm</Filename>

+      <Filename>Ia32/ReadFs.asm</Filename>

+      <Filename>Ia32/ReadGs.asm</Filename>

+      <Filename>Ia32/ReadSs.asm</Filename>

+      <Filename>Ia32/ReadTr.asm</Filename>

+      <Filename>Ia32/ReadGdtr.asm</Filename>

+      <Filename>Ia32/WriteGdtr.asm</Filename>

+      <Filename>Ia32/ReadIdtr.asm</Filename>

+      <Filename>Ia32/WriteIdtr.asm</Filename>

+      <Filename>Ia32/ReadLdtr.asm</Filename>

+      <Filename>Ia32/WriteLdtr.asm</Filename>

+      <Filename>Ia32/FxSave.asm</Filename>

+      <Filename>Ia32/FxRestore.asm</Filename>

+      <Filename>Ia32/ReadMm0.asm</Filename>

+      <Filename>Ia32/ReadMm1.asm</Filename>

+      <Filename>Ia32/ReadMm2.asm</Filename>

+      <Filename>Ia32/ReadMm3.asm</Filename>

+      <Filename>Ia32/ReadMm4.asm</Filename>

+      <Filename>Ia32/ReadMm5.asm</Filename>

+      <Filename>Ia32/ReadMm6.asm</Filename>

+      <Filename>Ia32/ReadMm7.asm</Filename>

+      <Filename>Ia32/WriteMm0.asm</Filename>

+      <Filename>Ia32/WriteMm1.asm</Filename>

+      <Filename>Ia32/WriteMm2.asm</Filename>

+      <Filename>Ia32/WriteMm3.asm</Filename>

+      <Filename>Ia32/WriteMm4.asm</Filename>

+      <Filename>Ia32/WriteMm5.asm</Filename>

+      <Filename>Ia32/WriteMm6.asm</Filename>

+      <Filename>Ia32/WriteMm7.asm</Filename>

+      <Filename>Ia32/ReadTsc.asm</Filename>

+      <Filename>Ia32/ReadPmc.asm</Filename>

+      <Filename>Ia32/Monitor.asm</Filename>

+      <Filename>Ia32/Mwait.asm</Filename>

+      <Filename>Ia32/EnablePaging32.asm</Filename>

+      <Filename>Ia32/DisablePaging32.asm</Filename>

+      <Filename>Ia32/EnablePaging64.asm</Filename>

+      <Filename>Ia32/Wbinvd.asm</Filename>

+      <Filename>Ia32/Invd.asm</Filename>

+      <Filename>Ia32/FlushCacheLine.asm</Filename>

+      <Filename>Ia32/InterlockedIncrement.asm</Filename>

+      <Filename>Ia32/InterlockedDecrement.asm</Filename>

+      <Filename>Ia32/InterlockedCompareExchange32.asm</Filename>

+      <Filename>Ia32/InterlockedCompareExchange64.asm</Filename>

+      <Filename>Ia32/EnableInterrupts.asm</Filename>

+      <Filename>Ia32/DisableInterrupts.asm</Filename>

+      <Filename>Ia32/EnableDisableInterrupts.asm</Filename>

+      <Filename>Ia32/CpuSleep.asm</Filename>

+      <Filename>Ia32/CpuPause.asm</Filename>

+      <Filename>Ia32/CpuBreakpoint.asm</Filename>

+      <Filename>Ia32/CpuFlushTlb.asm</Filename>

+      <Filename>Ia32/Thunk16.asm</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x86LowLevel.c</Filename>

+      <Filename>x86Thunk.c</Filename>

+      <Filename>Unaligned.c</Filename>

+      <Filename>Math64.c</Filename>

+      <Filename>LongJump.c</Filename>

+      <Filename>SwitchStack.c</Filename>

+      <Filename>x64/Non-existing.c</Filename>

+      <Filename>x64/SwitchStack.asm</Filename>

+      <Filename>x64/SetJump.asm</Filename>

+      <Filename>x64/LongJump.asm</Filename>

+      <Filename>x64/CpuId.asm</Filename>

+      <Filename>x64/ReadEflags.asm</Filename>

+      <Filename>x64/ReadMsr32.asm</Filename>

+      <Filename>x64/ReadMsr64.asm</Filename>

+      <Filename>x64/WriteMsr32.asm</Filename>

+      <Filename>x64/WriteMsr64.asm</Filename>

+      <Filename>x64/ReadCr0.asm</Filename>

+      <Filename>x64/ReadCr2.asm</Filename>

+      <Filename>x64/ReadCr3.asm</Filename>

+      <Filename>x64/ReadCr4.asm</Filename>

+      <Filename>x64/WriteCr0.asm</Filename>

+      <Filename>x64/WriteCr2.asm</Filename>

+      <Filename>x64/WriteCr3.asm</Filename>

+      <Filename>x64/WriteCr4.asm</Filename>

+      <Filename>x64/ReadDr0.asm</Filename>

+      <Filename>x64/ReadDr1.asm</Filename>

+      <Filename>x64/ReadDr2.asm</Filename>

+      <Filename>x64/ReadDr3.asm</Filename>

+      <Filename>x64/ReadDr4.asm</Filename>

+      <Filename>x64/ReadDr5.asm</Filename>

+      <Filename>x64/ReadDr6.asm</Filename>

+      <Filename>x64/ReadDr7.asm</Filename>

+      <Filename>x64/WriteDr0.asm</Filename>

+      <Filename>x64/WriteDr1.asm</Filename>

+      <Filename>x64/WriteDr2.asm</Filename>

+      <Filename>x64/WriteDr3.asm</Filename>

+      <Filename>x64/WriteDr4.asm</Filename>

+      <Filename>x64/WriteDr5.asm</Filename>

+      <Filename>x64/WriteDr6.asm</Filename>

+      <Filename>x64/WriteDr7.asm</Filename>

+      <Filename>x64/ReadCs.asm</Filename>

+      <Filename>x64/ReadDs.asm</Filename>

+      <Filename>x64/ReadEs.asm</Filename>

+      <Filename>x64/ReadFs.asm</Filename>

+      <Filename>x64/ReadGs.asm</Filename>

+      <Filename>x64/ReadSs.asm</Filename>

+      <Filename>x64/ReadTr.asm</Filename>

+      <Filename>x64/ReadGdtr.asm</Filename>

+      <Filename>x64/WriteGdtr.asm</Filename>

+      <Filename>x64/ReadIdtr.asm</Filename>

+      <Filename>x64/WriteIdtr.asm</Filename>

+      <Filename>x64/ReadLdtr.asm</Filename>

+      <Filename>x64/WriteLdtr.asm</Filename>

+      <Filename>x64/FxSave.asm</Filename>

+      <Filename>x64/FxRestore.asm</Filename>

+      <Filename>x64/ReadMm0.asm</Filename>

+      <Filename>x64/ReadMm1.asm</Filename>

+      <Filename>x64/ReadMm2.asm</Filename>

+      <Filename>x64/ReadMm3.asm</Filename>

+      <Filename>x64/ReadMm4.asm</Filename>

+      <Filename>x64/ReadMm5.asm</Filename>

+      <Filename>x64/ReadMm6.asm</Filename>

+      <Filename>x64/ReadMm7.asm</Filename>

+      <Filename>x64/WriteMm0.asm</Filename>

+      <Filename>x64/WriteMm1.asm</Filename>

+      <Filename>x64/WriteMm2.asm</Filename>

+      <Filename>x64/WriteMm3.asm</Filename>

+      <Filename>x64/WriteMm4.asm</Filename>

+      <Filename>x64/WriteMm5.asm</Filename>

+      <Filename>x64/WriteMm6.asm</Filename>

+      <Filename>x64/WriteMm7.asm</Filename>

+      <Filename>x64/ReadTsc.asm</Filename>

+      <Filename>x64/ReadPmc.asm</Filename>

+      <Filename>x64/Monitor.asm</Filename>

+      <Filename>x64/Mwait.asm</Filename>

+      <Filename>x64/DisablePaging64.asm</Filename>

+      <Filename>x64/Wbinvd.asm</Filename>

+      <Filename>x64/Invd.asm</Filename>

+      <Filename>x64/FlushCacheLine.asm</Filename>

+      <Filename>x64/InterlockedIncrement.asm</Filename>

+      <Filename>x64/InterlockedDecrement.asm</Filename>

+      <Filename>x64/InterlockedCompareExchange32.asm</Filename>

+      <Filename>x64/InterlockedCompareExchange64.asm</Filename>

+      <Filename>x64/EnableInterrupts.asm</Filename>

+      <Filename>x64/DisableInterrupts.asm</Filename>

+      <Filename>x64/EnableDisableInterrupts.asm</Filename>

+      <Filename>x64/CpuSleep.asm</Filename>

+      <Filename>x64/CpuPause.asm</Filename>

+      <Filename>x64/CpuBreakpoint.asm</Filename>

+      <Filename>x64/CpuFlushTlb.asm</Filename>

+      <Filename>x64/Thunk16.asm</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Math64.c</Filename>

+      <Filename>LongJump.c</Filename>

+      <Filename>SwitchStack.c</Filename>

+      <Filename>Ipf/PalCallStatic.s</Filename>

+      <Filename>Ipf/setjmp.s</Filename>

+      <Filename>Ipf/SwitchStack.s</Filename>

+      <Filename>Ipf/Unaligned.c</Filename>

+      <Filename>Ipf/CpuBreakpoint.c</Filename>

+      <Filename>Ipf/InterlockedCompareExchange32.s</Filename>

+      <Filename>Ipf/InterlockedCompareExchange64.s</Filename>

+      <Filename>Ipf/Synchronization.c</Filename>

+      <Filename>Ipf/CpuPause.s</Filename>

+      <Filename>Ipf/CpuFlushTlb.s</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>Math64.c</Filename>

+      <Filename>Unaligned.c</Filename>

+      <Filename>Ebc/SwitchStack.c</Filename>

+      <Filename>Ebc/SetJumpLongJump.c</Filename>

+      <Filename>Ebc/CpuBreakpoint.c</Filename>

+      <Filename>Ebc/Synchronization.c</Filename>

+    </Arch>

+  </SourceFiles>

+ <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumAsciiStringLength</C_Name>

+      <Token>0x00000002</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumLinkedListLength</C_Name>

+      <Token>0x00000003</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdSpinLockTimeout</C_Name>

+      <Token>0x00000004</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseLib/BaseLibInternals.h b/edk2/MdePkg/Library/BaseLib/BaseLibInternals.h
new file mode 100644
index 0000000..0c32e1b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -0,0 +1,204 @@
+/** @file

+  Declaration of internal functions in BaseLib.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  BaseLibInternals.h

+

+**/

+

+#ifndef __BASE_LIB_INTERNALS__

+#define __BASE_LIB_INTERNALS__

+

+//

+// Math functions

+//

+

+UINT64

+EFIAPI

+InternalMathLShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+UINT64

+EFIAPI

+InternalMathRShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+UINT64

+EFIAPI

+InternalMathARShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+UINT64

+EFIAPI

+InternalMathLRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+UINT64

+EFIAPI

+InternalMathRRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+UINT64

+EFIAPI

+InternalMathSwapBytes64 (

+  IN      UINT64                    Operand

+  );

+

+UINT64

+EFIAPI

+InternalMathMultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  );

+

+UINT64

+EFIAPI

+InternalMathMultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    Multiplier

+  );

+

+UINT64

+EFIAPI

+InternalMathDivU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  );

+

+UINT32

+EFIAPI

+InternalMathModU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  );

+

+UINT64

+EFIAPI

+InternalMathDivRemU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor,

+  OUT     UINT32                    *Remainder

+  );

+

+UINT64

+EFIAPI

+InternalMathDivRemU64x64 (

+  IN      UINT64                    Dividend,

+  IN      UINT64                    Divisor,

+  OUT     UINT64                    *Remainder

+  );

+

+INT64

+EFIAPI

+InternalMathDivRemS64x64 (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder

+  );

+

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,

+  IN      VOID                      *Context2,

+  IN      VOID                      *NewStack

+  );

+

+//

+// Ia32 and x64 specific functions

+//

+

+VOID

+EFIAPI

+InternalX86ReadGdtr (

+  OUT     IA32_DESCRIPTOR           *Gdtr

+  );

+

+VOID

+EFIAPI

+InternalX86WriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  );

+

+VOID

+EFIAPI

+InternalX86ReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  );

+

+VOID

+EFIAPI

+InternalX86WriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  );

+

+VOID

+EFIAPI

+InternalX86FxSave (

+  OUT     IA32_FX_BUFFER            *Buffer

+  );

+

+VOID

+EFIAPI

+InternalX86FxRestore (

+  IN      CONST IA32_FX_BUFFER      *Buffer

+  );

+

+VOID

+EFIAPI

+InternalX86EnablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  );

+

+VOID

+EFIAPI

+InternalX86DisablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  );

+

+VOID

+EFIAPI

+InternalX86EnablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT64                    EntryPoint,

+  IN      UINT64                    Context1,  OPTIONAL

+  IN      UINT64                    Context2,  OPTIONAL

+  IN      UINT64                    NewStack

+  );

+

+VOID

+EFIAPI

+InternalX86DisablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT32                    EntryPoint,

+  IN      UINT32                    Context1,  OPTIONAL

+  IN      UINT32                    Context2,  OPTIONAL

+  IN      UINT32                    NewStack

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseLib/BitField.c b/edk2/MdePkg/Library/BaseLib/BitField.c
new file mode 100644
index 0000000..ad95339
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/BitField.c
@@ -0,0 +1,812 @@
+/** @file

+  Bit field functions of BaseLib.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  BitField.c

+

+**/

+

+unsigned int

+EFIAPI

+BitFieldReadUint (

+  IN      unsigned int              Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  //

+  // ~((unsigned int)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]

+  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.

+  //

+  return (Operand & ~((unsigned int)-2 << EndBit)) >> StartBit;

+}

+

+unsigned int

+EFIAPI

+BitFieldOrUint (

+  IN      unsigned int              Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      unsigned int              OrData

+  )

+{

+  //

+  // ~((unsigned int)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]

+  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.

+  //

+  return Operand | ((OrData << StartBit) & ~((unsigned int)-2 << EndBit));

+}

+

+unsigned int

+EFIAPI

+BitFieldAndUint (

+  IN      unsigned int              Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      unsigned int              AndData

+  )

+{

+  //

+  // ~((unsigned int)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]

+  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.

+  //

+  return Operand & ~((~AndData << StartBit) & ~((unsigned int)-2 << EndBit));

+}

+

+/**

+  Returns a bit field from an 8-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The bit field read.

+

+**/

+UINT8

+EFIAPI

+BitFieldRead8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT8)BitFieldReadUint (Operand, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an 8-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 8-bit value is

+  returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldWrite8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value);

+}

+

+/**

+  Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 8-bit value is returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldOr8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT8)BitFieldOrUint (Operand, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field from an 8-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 8-bit value is returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the value.

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldAnd8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT8)BitFieldAndUint (Operand, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field from an 8-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 8-bit value is returned.

+

+  If 8-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 8-bit value.

+

+**/

+UINT8

+EFIAPI

+BitFieldAndThenOr8 (

+  IN      UINT8                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr8 (

+           BitFieldAnd8 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Returns a bit field from a 16-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The bit field read.

+

+**/

+UINT16

+EFIAPI

+BitFieldRead16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT16)BitFieldReadUint (Operand, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a 16-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 16-bit value is

+  returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldWrite16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value);

+}

+

+/**

+  Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 16-bit value is returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldOr16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT16)BitFieldOrUint (Operand, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field from a 16-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 16-bit value is returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the value

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldAnd16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT16)BitFieldAndUint (Operand, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field from a 16-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 16-bit value is returned.

+

+  If 16-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 16-bit value.

+

+**/

+UINT16

+EFIAPI

+BitFieldAndThenOr16 (

+  IN      UINT16                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr16 (

+           BitFieldAnd16 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Returns a bit field from a 32-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The bit field read.

+

+**/

+UINT32

+EFIAPI

+BitFieldRead32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)BitFieldReadUint (Operand, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a 32-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 32-bit value is

+  returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldWrite32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value);

+}

+

+/**

+  Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 32-bit value is returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldOr32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)BitFieldOrUint (Operand, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field from a 32-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 32-bit value is returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the value

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldAnd32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)BitFieldAndUint (Operand, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field from a 32-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 32-bit value is returned.

+

+  If 32-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 32-bit value.

+

+**/

+UINT32

+EFIAPI

+BitFieldAndThenOr32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr32 (

+           BitFieldAnd32 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Returns a bit field from a 64-bit value.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The bit field read.

+

+**/

+UINT64

+EFIAPI

+BitFieldRead64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);

+}

+

+/**

+  Writes a bit field to a 64-bit value, and returns the result.

+

+  Writes Value to the bit field specified by the StartBit and the EndBit in

+  Operand. All other bits in Operand are preserved. The new 64-bit value is

+  returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldWrite64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value);

+}

+

+/**

+  Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the

+  result.

+

+  Performs a bitwise inclusive OR between the bit field specified by StartBit

+  and EndBit in Operand and the value specified by OrData. All other bits in

+  Operand are preserved. The new 64-bit value is returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldOr64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return Operand |

+         (LShiftU64 (OrData, StartBit) & ~LShiftU64 ((UINT64)-2, EndBit));

+}

+

+/**

+  Reads a bit field from a 64-bit value, performs a bitwise AND, and returns

+  the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData. All other bits in Operand are

+  preserved. The new 64-bit value is returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the value

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldAnd64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return Operand &

+         ~(LShiftU64 (~AndData, StartBit) & ~LShiftU64 ((UINT64)-2, EndBit));

+}

+

+/**

+  Reads a bit field from a 64-bit value, performs a bitwise AND followed by a

+  bitwise OR, and returns the result.

+

+  Performs a bitwise AND between the bit field specified by StartBit and EndBit

+  in Operand and the value specified by AndData, followed by a bitwise

+  inclusive OR with value specified by OrData. All other bits in Operand are

+  preserved. The new 64-bit value is returned.

+

+  If 64-bit operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the value.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The new 64-bit value.

+

+**/

+UINT64

+EFIAPI

+BitFieldAndThenOr64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (Operand) * 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr64 (

+           BitFieldAnd64 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Cpu.c b/edk2/MdePkg/Library/BaseLib/Cpu.c
new file mode 100644
index 0000000..cc7a608
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Cpu.c
@@ -0,0 +1,67 @@
+/** @file

+  Base Library CPU Functions for all architectures.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  Cpu.c

+

+**/

+

+/**

+  Disables CPU interrupts and returns the interrupt state prior to the disable

+  operation.

+

+  Disables CPU interrupts and returns the interrupt state prior to the disable

+  operation.

+

+  @retval TRUE  CPU interrupts were enabled on entry to this call.

+  @retval FALSE CPU interrupts were disabled on entry to this call.

+

+**/

+BOOLEAN

+EFIAPI

+SaveAndDisableInterrupts (

+  VOID

+  )

+{

+  BOOLEAN                           InterruptState;

+

+  InterruptState = GetInterruptState ();

+  DisableInterrupts ();

+  return InterruptState;

+}

+

+/**

+  Set the current CPU interrupt state.

+

+  Sets the current CPU interrupt state to the state specified by

+  InterruptState. If InterruptState is TRUE, then interrupts are enabled. If

+  InterruptState is FALSE, then interrupts are disabled. InterruptState is

+  returned.

+

+  @param  InterruptState  TRUE if interrupts should enabled. FALSE if

+                          interrupts should be disabled.

+

+  @return InterruptState

+

+**/

+BOOLEAN

+EFIAPI

+SetInterruptState (

+  IN      BOOLEAN                   InterruptState

+  )

+{

+  if (InterruptState) {

+    EnableInterrupts ();

+  } else {

+    DisableInterrupts ();

+  }

+  return InterruptState;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/CpuDeadLoop.c b/edk2/MdePkg/Library/BaseLib/CpuDeadLoop.c
new file mode 100644
index 0000000..f8f5302
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/CpuDeadLoop.c
@@ -0,0 +1,33 @@
+/** @file

+  Base Library CPU Functions for all architectures.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+/**

+  Executes an infinite loop.

+

+  Forces the CPU to execute an infinite loop. A debugger may be used to skip

+  past the loop and the code that follows the loop must execute properly. This

+  implies that the infinite loop must not cause the code that follow it to be

+  optimized away.

+

+**/

+VOID

+EFIAPI

+CpuDeadLoop (

+  VOID

+  )

+{

+  volatile UINTN  Index;

+

+  for (Index = 0; Index == 0;);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/DivS64x64Remainder.c b/edk2/MdePkg/Library/BaseLib/DivS64x64Remainder.c
new file mode 100644
index 0000000..aa28fc8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/DivS64x64Remainder.c
@@ -0,0 +1,46 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Divides a 64-bit signed integer by a 64-bit signed integer and generates a

+  64-bit signed result and a optional 64-bit signed remainder.

+

+  This function divides the 64-bit signed value Dividend by the 64-bit signed

+  value Divisor and generates a 64-bit signed quotient. If Remainder is not

+  NULL, then the 64-bit signed remainder is returned in Remainder. This

+  function returns the 64-bit signed quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit signed value.

+  @param  Divisor   A 64-bit signed value.

+  @param  Remainder A pointer to a 64-bit signed value. This parameter is

+                    optional and may be NULL.

+

+  @return Dividend / Divisor

+

+**/

+INT64

+EFIAPI

+DivS64x64Remainder (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivRemS64x64 (Dividend, Divisor, Remainder);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/DivU64x32.c b/edk2/MdePkg/Library/BaseLib/DivU64x32.c
new file mode 100644
index 0000000..b223c6c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/DivU64x32.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates

+  a 64-bit unsigned result.

+

+  This function divides the 64-bit unsigned value Dividend by the 32-bit

+  unsigned value Divisor and generates a 64-bit unsigned quotient. This

+  function returns the 64-bit unsigned quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+DivU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivU64x32 (Dividend, Divisor);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/DivU64x32Remainder.c b/edk2/MdePkg/Library/BaseLib/DivU64x32Remainder.c
new file mode 100644
index 0000000..aa34b31
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/DivU64x32Remainder.c
@@ -0,0 +1,46 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates

+  a 64-bit unsigned result and an optional 32-bit unsigned remainder.

+

+  This function divides the 64-bit unsigned value Dividend by the 32-bit

+  unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder

+  is not NULL, then the 32-bit unsigned remainder is returned in Remainder.

+  This function returns the 64-bit unsigned quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+  @param  Remainder A pointer to a 32-bit unsigned value. This parameter is

+                    optional and may be NULL.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+DivU64x32Remainder (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor,

+  OUT     UINT32                    *Remainder

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivRemU64x32 (Dividend, Divisor, Remainder);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/DivU64x64Remainder.c b/edk2/MdePkg/Library/BaseLib/DivU64x64Remainder.c
new file mode 100644
index 0000000..0caa529
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/DivU64x64Remainder.c
@@ -0,0 +1,46 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Divides a 64-bit unsigned integer by a 64-bit unsigned integer and generates

+  a 64-bit unsigned result and an optional 64-bit unsigned remainder.

+

+  This function divides the 64-bit unsigned value Dividend by the 64-bit

+  unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder

+  is not NULL, then the 64-bit unsigned remainder is returned in Remainder.

+  This function returns the 64-bit unsigned quotient.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 64-bit unsigned value.

+  @param  Remainder A pointer to a 64-bit unsigned value. This parameter is

+                    optional and may be NULL.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+DivU64x64Remainder (

+  IN      UINT64                    Dividend,

+  IN      UINT64                    Divisor,

+  OUT     UINT64                    *Remainder

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivRemU64x64 (Dividend, Divisor, Remainder);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ebc/CpuBreakpoint.c b/edk2/MdePkg/Library/BaseLib/Ebc/CpuBreakpoint.c
new file mode 100644
index 0000000..352e1c7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ebc/CpuBreakpoint.c
@@ -0,0 +1,164 @@
+/** @file

+  Base Library CPU Functions for EBC

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+extern

+UINT64

+_break (

+  CHAR8 BreakCode

+  );

+

+/**

+  Generates a breakpoint on the CPU.

+

+  Generates a breakpoint on the CPU. The breakpoint must be implemented such

+  that code can resume normal execution after the breakpoint.

+

+**/

+VOID

+EFIAPI

+CpuBreakpoint (

+  VOID

+  )

+{

+  _break (3);

+}

+

+/**

+  Used to serialize load and store operations.

+

+  All loads and stores that proceed calls to this function are guaranteed to be

+  globally visible when this function returns.

+

+**/

+VOID

+EFIAPI

+MemoryFence (

+  VOID

+  )

+{

+}

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Retrieves the current CPU interrupt state.

+

+  Retrieves the current CPU interrupt state. Returns TRUE is interrupts are

+  currently enabled. Otherwise returns FALSE.

+

+  @retval TRUE  CPU interrupts are enabled.

+  @retval FALSE CPU interrupts are disabled.

+

+**/

+BOOLEAN

+EFIAPI

+GetInterruptState (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+  return FALSE;

+}

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  )

+{

+  EnableInterrupts ();

+  DisableInterrupts ();

+}

+

+/**

+  Requests CPU to pause for a short period of time.

+

+  Requests CPU to pause for a short period of time. Typically used in MP

+  systems to prevent memory starvation while waiting for a spin lock.

+

+**/

+VOID

+EFIAPI

+CpuPause (

+  VOID

+  )

+{

+}

+

+/**

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+**/

+VOID

+EFIAPI

+CpuFlushTlb (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Places the CPU in a sleep state until an interrupt is received.

+

+  Places the CPU in a sleep state until an interrupt is received. If interrupts

+  are disabled prior to calling this function, then the CPU will be placed in a

+  sleep state indefinitely.

+

+**/

+VOID

+EFIAPI

+CpuSleep (

+  VOID

+  )

+{

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c b/edk2/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c
new file mode 100644
index 0000000..a238125
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c
@@ -0,0 +1,40 @@
+/** @file

+  Switch Stack functions. 

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  SetJumpLongJump.c

+

+**/

+

+

+

+UINTN

+EFIAPI

+SetJump (

+  IN BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+  )

+{

+  ASSERT (JumpBuffer != NULL);

+  ASSERT (FALSE);

+  return 0;

+}

+

+VOID

+EFIAPI

+LongJump (

+  IN BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                Value

+  )

+{

+  ASSERT (JumpBuffer != NULL);

+  ASSERT (Value != 0);

+  ASSERT (FALSE);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ebc/SwitchStack.c b/edk2/MdePkg/Library/BaseLib/Ebc/SwitchStack.c
new file mode 100644
index 0000000..73b8edb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ebc/SwitchStack.c
@@ -0,0 +1,52 @@
+/** @file

+  Switch Stack functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SwitchStack.c

+

+**/

+

+/**

+  Transfers control to a function starting with a new stack.

+

+  Transfers control to the function specified by EntryPoint using the new stack

+  specified by NewStack and passing in the parameters specified by Context1 and

+  Context2. Context1 and Context2 are optional and may be NULL. The function

+  EntryPoint must never return.

+

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  @param  EntryPoint  A pointer to function to call with the new stack.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function.

+

+**/

+VOID

+EFIAPI

+SwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  //

+  // This version of this function does not actually change the stack pointer

+  // This is to support compilation of CPU types that do not support assemblers

+  // such as EBC

+  //

+  EntryPoint (Context1, Context2);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ebc/Synchronization.c b/edk2/MdePkg/Library/BaseLib/Ebc/Synchronization.c
new file mode 100644
index 0000000..df591b2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ebc/Synchronization.c
@@ -0,0 +1,57 @@
+/** @file

+  Implementation of synchronization functions on EBC.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  Synchronization.c

+

+**/

+

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return ++*Value;

+}

+

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return --*Value;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/GetPowerOfTwo32.c b/edk2/MdePkg/Library/BaseLib/GetPowerOfTwo32.c
new file mode 100644
index 0000000..6dfe805
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/GetPowerOfTwo32.c
@@ -0,0 +1,39 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Returns the value of the highest bit set in a 32-bit value. Equivalent to

+  1 << HighBitSet32(x).

+

+  This function computes the value of the highest bit set in the 32-bit value

+  specified by Operand. If Operand is zero, then zero is returned.

+

+  @param  Operand The 32-bit operand to evaluate.

+

+  @return 1 << HighBitSet32(Operand)

+  @retval 0 Operand is zero.

+

+**/

+UINT32

+EFIAPI

+GetPowerOfTwo32 (

+  IN      UINT32                    Operand

+  )

+{

+  INTN                              BitPos;

+

+  return (BitPos = HighBitSet32 (Operand)) > 0 ? 1ul << BitPos : 0;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/GetPowerOfTwo64.c b/edk2/MdePkg/Library/BaseLib/GetPowerOfTwo64.c
new file mode 100644
index 0000000..9994fb8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/GetPowerOfTwo64.c
@@ -0,0 +1,39 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Returns the value of the highest bit set in a 64-bit value. Equivalent to

+  1 << HighBitSet64(x).

+

+  This function computes the value of the highest bit set in the 64-bit value

+  specified by Operand. If Operand is zero, then zero is returned.

+

+  @param  Operand The 64-bit operand to evaluate.

+

+  @return 1 << HighBitSet64(Operand)

+  @retval 0 Operand is zero.

+

+**/

+UINT64

+EFIAPI

+GetPowerOfTwo64 (

+  IN      UINT64                    Operand

+  )

+{

+  INTN                              BitPos;

+

+  return (BitPos = HighBitSet64 (Operand)) > 0 ? LShiftU64 (1, BitPos) : 0;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/HighBitSet32.c b/edk2/MdePkg/Library/BaseLib/HighBitSet32.c
new file mode 100644
index 0000000..65f067a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/HighBitSet32.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Returns the bit position of the highest bit set in a 32-bit value. Equivalent

+  to log2(x).

+

+  This function computes the bit position of the highest bit set in the 32-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 31 is returned.

+

+  @param  Operand The 32-bit operand to evaluate.

+

+  @return Position of the highest bit set in Operand if found.

+  @retval -1  Operand is zero.

+

+**/

+INTN

+EFIAPI

+HighBitSet32 (

+  IN      UINT32                    Operand

+  )

+{

+  INTN                              BitIndex;

+

+  for (BitIndex = -1; Operand != 0; BitIndex++, Operand >>= 1);

+  return BitIndex;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/HighBitSet64.c b/edk2/MdePkg/Library/BaseLib/HighBitSet64.c
new file mode 100644
index 0000000..5088977
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/HighBitSet64.c
@@ -0,0 +1,43 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Returns the bit position of the highest bit set in a 64-bit value. Equivalent

+  to log2(x).

+

+  This function computes the bit position of the highest bit set in the 64-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 63 is returned.

+

+  @param  Operand The 64-bit operand to evaluate.

+

+  @return Position of the highest bit set in Operand if found.

+  @retval -1  Operand is zero.

+

+**/

+INTN

+EFIAPI

+HighBitSet64 (

+  IN      UINT64                    Operand

+  )

+{

+  INTN                              BitIndex;

+

+  for (BitIndex = -1;

+       Operand != 0;

+       BitIndex++, Operand = RShiftU64 (Operand, 1));

+  return BitIndex;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.asm
new file mode 100644
index 0000000..6b9cfa1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ARShiftU64.asm

+;

+; Abstract:

+;

+;   64-bit arithmetic right shift function for IA-32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMathARShiftU64  PROC

+    mov     cl, [esp + 12]

+    mov     eax, [esp + 8]

+    cdq

+    test    cl, 32

+    cmovz   edx, eax

+    cmovz   eax, [esp + 4]

+    shrd    eax, edx, cl

+    sar     edx, cl

+    ret

+InternalMathARShiftU64  ENDP

+

+    END
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.s b/edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.s
new file mode 100644
index 0000000..d6af974
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ARShiftU64.asm

+#

+# Abstract:

+#

+#   64-bit arithmetic right shift function for IA-32

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _ARShiftU64

+_ARShiftU64: 

+    movb    12(%esp),%cl

+    movl    8(%esp),%eax

+    cltd

+    testb   $32,%cl

+# MISMATCH: "    cmovz   edx, eax"

+    cmovz   %eax, %edx

+# MISMATCH: "    cmovz   eax, [esp + 4]"

+    cmovz   4(%esp), %eax

+    shrdl   %cl,%edx,%eax

+    sar     %cl,%edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.asm b/edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.asm
new file mode 100644
index 0000000..a4d3978
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuBreakpoint.Asm

+;

+; Abstract:

+;

+;   CpuBreakpoint function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuBreakpoint (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_CpuBreakpoint   PROC

+    int  3

+    ret

+_CpuBreakpoint   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.s b/edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.s
new file mode 100644
index 0000000..859369e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------ ;

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   CpuBreakpoint.s

+#

+# Abstract:

+#

+#   CpuBreakpoint function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# CpuBreakpoint (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _CpuBreakpoint

+_CpuBreakpoint: 

+    int  $3

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.asm b/edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.asm
new file mode 100644
index 0000000..de87ad7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuFlushTlb.Asm

+;

+; Abstract:

+;

+;   CpuFlushTlb function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuFlushTlb (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_CpuFlushTlb    PROC

+    mov     eax, cr3

+    mov     cr3, eax

+    ret

+_CpuFlushTlb    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.s b/edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.s
new file mode 100644
index 0000000..1d85fa7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------ ;

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   CpuFlushTlb.Asm

+#

+# Abstract:

+#

+#   CpuFlushTlb function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# CpuFlushTlb (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _CpuFlushTlb

+_CpuFlushTlb: 

+    movl    %cr3, %eax

+    movl    %eax, %cr3

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuId.asm b/edk2/MdePkg/Library/BaseLib/Ia32/CpuId.asm
new file mode 100644
index 0000000..2c94e3a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuId.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuId.Asm

+;

+; Abstract:

+;

+;   AsmCpuid function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  AsmCpuid (

+;    IN   UINT32  RegisterInEax,

+;    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+;    )

+;------------------------------------------------------------------------------

+AsmCpuid    PROC    USES    ebx

+    push    ebp

+    mov     ebp, esp

+    mov     eax, [ebp + 12]

+    cpuid

+    push    ecx

+    mov     ecx, [ebp + 16]

+    jecxz   @F

+    mov     [ecx], eax

+@@:

+    mov     ecx, [ebp + 20]

+    jecxz   @F

+    mov     [ecx], ebx

+@@:

+    mov     ecx, [ebp + 24]

+    jecxz   @F

+    pop     [ecx]

+@@:

+    mov     ecx, [ebp + 28]

+    jecxz   @F

+    mov     [ecx], edx

+@@:

+    mov     eax, [ebp + 12]

+    leave

+    ret

+AsmCpuid    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuId.s b/edk2/MdePkg/Library/BaseLib/Ia32/CpuId.s
new file mode 100644
index 0000000..989daba
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuId.s
@@ -0,0 +1,63 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   CpuId.Asm

+#

+# Abstract:

+#

+#   AsmCpuid function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  AsmCpuid (

+#    IN   UINT32  RegisterInEax,

+#    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+#    )

+#------------------------------------------------------------------------------

+.globl _AsmCpuid

+_AsmCpuid:

+    push   %ebx

+    push   %edi

+    movl    12(%esp),%eax

+    cpuid

+    movl    %ecx,%edi

+    movl    16(%esp),%ecx

+    jecxz   L1

+    movl    %eax,(%ecx)

+L1:

+    movl    20(%esp),%ecx

+    jecxz   L2

+    movl    %ebx,(%ecx)

+L2:

+    movl    24(%esp),%ecx

+    jecxz   L3

+    movl    %edi,(%ecx)

+L3:

+    movl    28(%esp),%ecx

+    jecxz   L4

+    movl    %edx,(%ecx)

+L4:

+    pop    %edi

+    pop    %ebx

+    ret

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.asm b/edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.asm
new file mode 100644
index 0000000..79a4f2f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuPause.Asm

+;

+; Abstract:

+;

+;   CpuPause function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuPause (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_CpuPause   PROC

+    pause

+    ret

+_CpuPause   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.s b/edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.s
new file mode 100644
index 0000000..ace2c67
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------ ;

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   CpuPause.Asm

+#

+# Abstract:

+#

+#   CpuPause function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# CpuPause (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _CpuPause

+_CpuPause: 

+    pause

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuSleep.asm b/edk2/MdePkg/Library/BaseLib/Ia32/CpuSleep.asm
new file mode 100644
index 0000000..66fb90e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuSleep.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuSleep.Asm

+;

+; Abstract:

+;

+;   CpuSleep function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuSleep (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_CpuSleep   PROC

+    hlt

+    ret

+_CpuSleep   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/CpuSleep.s b/edk2/MdePkg/Library/BaseLib/Ia32/CpuSleep.s
new file mode 100644
index 0000000..9b77131
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/CpuSleep.s
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------ ;

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   CpuSleep.Asm

+#

+# Abstract:

+#

+#   CpuSleep function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# CpuSleep (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _CpuSleep

+_CpuSleep: 

+    hlt

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.asm b/edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.asm
new file mode 100644
index 0000000..74bdd0b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DisableInterrupts.Asm

+;

+; Abstract:

+;

+;   DisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; DisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_DisableInterrupts  PROC

+    cli

+    ret

+_DisableInterrupts  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.s b/edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.s
new file mode 100644
index 0000000..cc9c95c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   DisableInterrupts.Asm

+#

+# Abstract:

+#

+#   DisableInterrupts function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# DisableInterrupts (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _DisableInterrupts

+_DisableInterrupts: 

+    cli

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.asm
new file mode 100644
index 0000000..04ae8cf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DisablePaging32.Asm

+;

+; Abstract:

+;

+;   AsmDisablePaging32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86DisablePaging32 (

+;   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+;   IN      VOID                      *Context1,    OPTIONAL

+;   IN      VOID                      *Context2,    OPTIONAL

+;   IN      VOID                      *NewStack

+;   );

+;------------------------------------------------------------------------------

+InternalX86DisablePaging32    PROC

+    mov     ebx, [esp + 4]

+    mov     ecx, [esp + 8]

+    mov     edx, [esp + 12]

+    pushfd

+    pop     edi

+    cli

+    mov     eax, cr0

+    btr     eax, 31

+    mov     esp, [esp + 16]

+    mov     cr0, eax

+    push    edi

+    popfd

+    push    edx

+    push    ecx

+    call    ebx

+    jmp     $

+InternalX86DisablePaging32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.s b/edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.s
new file mode 100644
index 0000000..21e8a82
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.s
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   DisablePaging32.Asm

+#

+# Abstract:

+#

+#   AsmDisablePaging32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmDisablePaging32 (

+#   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+#   IN      VOID                      *Context1,    OPTIONAL

+#   IN      VOID                      *Context2,    OPTIONAL

+#   IN      VOID                      *NewStack

+#   );

+#------------------------------------------------------------------------------

+.global _AsmDisablePaging32

+_AsmDisablePaging32: 

+    movl    4(%esp),%ebx

+    movl    8(%esp),%ecx

+    movl    12(%esp),%edx

+    pushfl

+    popl    %edi

+    cli

+    movl    %cr0, %eax

+    btrl    $31,%eax

+    movl    16(%esp),%esp

+    movl    %eax, %cr0

+    pushl   %edi

+    popfl

+    pushl   %edx

+    pushl   %ecx

+    call    *%ebx

+    jmp     .

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivS64x64Remainder.c b/edk2/MdePkg/Library/BaseLib/Ia32/DivS64x64Remainder.c
new file mode 100644
index 0000000..219f48f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivS64x64Remainder.c
@@ -0,0 +1,38 @@
+/** @file

+  Integer division worker functions for Ia32.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  DivS64x64Remainder.c

+

+**/

+

+#include "../BaseLibInternals.h"

+

+INT64

+EFIAPI

+InternalMathDivRemS64x64 (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder

+  )

+{

+  INT64                             Quot;

+

+  Quot = InternalMathDivRemU64x64 (

+           Dividend >= 0 ? Dividend : -Dividend,

+           Divisor >= 0 ? Divisor : -Divisor,

+           (UINT64 *) Remainder

+           );

+  if (Remainder != NULL && Dividend < 0) {

+    *Remainder = -*Remainder;

+  }

+  return (Dividend ^ Divisor) >= 0 ? Quot : -Quot;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.asm
new file mode 100644
index 0000000..1ad5474
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DivU64x32.asm

+;

+; Abstract:

+;

+;   Calculate the quotient of a 64-bit integer by a 32-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMathDivU64x32   PROC

+    mov     eax, [esp + 8]

+    mov     ecx, [esp + 12]

+    xor     edx, edx

+    div     ecx

+    push    eax

+    mov     eax, [esp + 8]

+    div     ecx

+    pop     edx

+    ret

+InternalMathDivU64x32   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.s b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.s
new file mode 100644
index 0000000..89d7546
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.s
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   DivU64x32.asm
+#
+# Abstract:
+#
+#   Calculate the quotient of a 64-bit integer by a 32-bit integer
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global _InternalMathDivU64x32
+_InternalMathDivU64x32:
+    movl    8(%esp),%eax
+    movl    12(%esp),%ecx
+    xorl    %edx,%edx
+    divl    %ecx
+    pushl   %eax
+    movl    8(%esp),%eax
+    divl    %ecx
+    popl    %edx
+    ret
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm
new file mode 100644
index 0000000..f1c6c1f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DivError.asm

+;

+; Abstract:

+;

+;   Set error flag for all division functions

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMathDivRemU64x32    PROC

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 8]

+    xor     edx, edx

+    div     ecx

+    push    eax

+    mov     eax, [esp + 8]

+    div     ecx

+    mov     ecx, [esp + 20]

+    jecxz   @F

+    mov     [ecx], edx

+@@:

+    pop     edx

+    ret

+InternalMathDivRemU64x32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.s b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.s
new file mode 100644
index 0000000..1f34f18
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   DivError.asm

+#

+# Abstract:

+#

+#   Set error flag for all division functions

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _InternalMathDivRemU64x32

+_InternalMathDivRemU64x32: 

+    movl    12(%esp),%ecx

+    movl    8(%esp),%eax

+    xorl    %edx,%edx

+    divl    %ecx

+    pushl   %eax

+    movl    8(%esp),%eax

+    divl    %ecx

+    movl    20(%esp),%ecx

+    jecxz   L1

+    movl    %edx,(%ecx)

+L1: 

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm
new file mode 100644
index 0000000..261211b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm
@@ -0,0 +1,83 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DivU64x64Remainder.asm

+;

+; Abstract:

+;

+;   Calculate the quotient of a 64-bit integer by a 64-bit integer and returns

+;   both the quotient and the remainder

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+EXTERN  InternalMathDivRemU64x32:PROC

+

+InternalMathDivRemU64x64    PROC

+    mov     ecx, [esp + 16]

+    test    ecx, ecx

+    jnz     _@DivRemU64x64

+    mov     ecx, [esp + 20]

+    jecxz   @F

+    and     dword ptr [ecx + 4], 0

+    mov     [esp + 16], ecx

+@@:

+    jmp     InternalMathDivRemU64x32

+InternalMathDivRemU64x64    ENDP

+

+_@DivRemU64x64  PROC    USES    ebx esi edi

+    mov     edx, dword ptr [esp + 20]

+    mov     eax, dword ptr [esp + 16]

+    mov     edi, edx

+    mov     esi, eax

+    mov     ebx, dword ptr [esp + 24]

+@@:

+    shr     edx, 1

+    rcr     eax, 1

+    shrd    ebx, ecx, 1

+    shr     ecx, 1

+    jnz     @B

+    div     ebx

+    mov     ebx, eax

+    mov     ecx, [esp + 28]

+    mul     dword ptr [esp + 24]

+    imul    ecx, ebx

+    add     edx, ecx

+    mov     ecx, dword ptr [esp + 32]

+    jc      @TooLarge

+    cmp     edi, edx

+    ja      @Correct

+    jb      @TooLarge

+    cmp     esi, eax

+    jae     @Correct

+@TooLarge:

+    dec     ebx

+    jecxz   @Return

+    sub     eax, dword ptr [esp + 24]

+    sbb     edx, dword ptr [esp + 28]

+@Correct:

+    jecxz   @Return

+    sub     esi, eax

+    sbb     edi, edx

+    mov     [ecx], esi

+    mov     [ecx + 4], edi

+@Return:

+    mov     eax, ebx

+    xor     edx, edx

+    ret

+_@DivRemU64x64  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.s b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.s
new file mode 100644
index 0000000..f604f7c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.s
@@ -0,0 +1,89 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   DivU64x64Remainder.asm

+#

+# Abstract:

+#

+#   Calculate the quotient of a 64-bit integer by a 64-bit integer and returns

+#   both the quotient and the remainder

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.extern _InternalMathDivRemU64x32

+

+.global _InternalMathDivRemU64x64

+_InternalMathDivRemU64x64: 

+    movl    16(%esp),%ecx

+    testl   %ecx,%ecx

+    jnz     _DivRemU64x64

+    movl    20(%esp),%ecx

+    jecxz   L1

+    and     $0,4(%ecx)

+    movl    %ecx,16(%esp)

+L1: 

+    jmp     _InternalMathDivRemU64x32

+

+

+.global DivRemU64x64

+DivRemU64x64:

+# MISMATCH: "DivRemU64x64:    USES    ebx esi edi"

+    push   %ebx                                                                             

+    push   %esi                                                                             

+    push   %edi                                        

+    mov     20(%esp), %edx

+    mov     16(%esp), %eax

+    movl    %edx,%edi

+    movl    %eax,%esi

+    mov     24(%esp), %ebx

+L2: 

+    shrl    %edx

+    rcrl    $1,%eax

+    shrdl   $1,%ecx,%ebx

+    shrl    %ecx

+    jnz     L2

+    divl    %ebx

+    movl    %eax,%ebx

+    movl    28(%esp),%ecx

+    mull    24(%esp)

+    imull   %ebx,%ecx

+    addl    %ecx,%edx

+    mov     32(%esp), %ecx

+    jc      TooLarge

+    cmpl    %edx,%edi

+    ja      Correct

+    jb      TooLarge

+    cmpl    %eax,%esi

+    jae     Correct

+TooLarge: 

+    decl    %ebx

+    jecxz   Return

+    sub     24(%esp), %eax

+    sbb     28(%esp), %edx

+Correct: 

+    jecxz   Return

+    subl    %eax,%esi

+    sbbl    %edx,%edi

+    movl    %esi,(%ecx)

+    movl    %edi,4(%ecx)

+Return: 

+    movl    %ebx,%eax

+    xorl    %edx,%edx

+    push   %edi                                        

+    push   %esi                                                                             

+    push   %ebx                                                                             

+    ret

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.asm b/edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.asm
new file mode 100644
index 0000000..fe2016d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   EnableDisableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableDisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableDisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_EnableDisableInterrupts    PROC

+    sti

+    cli

+    ret

+_EnableDisableInterrupts    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.s b/edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.s
new file mode 100644
index 0000000..80362a9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   EnableDisableInterrupts.Asm

+#

+# Abstract:

+#

+#   EnableDisableInterrupts function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# EnableDisableInterrupts (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _EnableDisableInterrupts

+_EnableDisableInterrupts: 

+    sti

+    cli

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.asm b/edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.asm
new file mode 100644
index 0000000..194dd8f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   EnableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_EnableInterrupts   PROC

+    sti

+    ret

+_EnableInterrupts   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.s b/edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.s
new file mode 100644
index 0000000..74413d8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   EnableInterrupts.Asm

+#

+# Abstract:

+#

+#   EnableInterrupts function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# EnableInterrupts (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _EnableInterrupts

+_EnableInterrupts: 

+    sti

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm
new file mode 100644
index 0000000..cf6f2fe
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   EnablePaging32.Asm

+;

+; Abstract:

+;

+;   AsmEnablePaging32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86EnablePaging32 (

+;   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+;   IN      VOID                      *Context1,    OPTIONAL

+;   IN      VOID                      *Context2,    OPTIONAL

+;   IN      VOID                      *NewStack

+;   );

+;------------------------------------------------------------------------------

+InternalX86EnablePaging32 PROC

+    mov     ebx, [esp + 4]

+    mov     ecx, [esp + 8]

+    mov     edx, [esp + 12]

+    pushfd

+    pop     edi

+    cli

+    mov     eax, cr0

+    bts     eax, 31

+    mov     esp, [esp + 16]

+    mov     cr0, eax

+    push    edi

+    popfd

+    push    edx

+    push    ecx

+    call    ebx

+    jmp     $

+InternalX86EnablePaging32 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.s b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.s
new file mode 100644
index 0000000..6f9befc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.s
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   EnablePaging32.Asm

+#

+# Abstract:

+#

+#   AsmEnablePaging32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmEnablePaging32 (

+#   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+#   IN      VOID                      *Context1,    OPTIONAL

+#   IN      VOID                      *Context2,    OPTIONAL

+#   IN      VOID                      *NewStack

+#   );

+#------------------------------------------------------------------------------

+.global _AsmEnablePaging32

+_AsmEnablePaging32: 

+    movl    4(%esp),%ebx

+    movl    8(%esp),%ecx

+    movl    12(%esp),%edx

+    pushfl

+    popl    %edi

+    cli

+    movl    %cr0, %eax

+    btsl    $31,%eax

+    movl    16(%esp),%esp

+    movl    %eax, %cr0

+    pushl   %edi

+    popfl

+    pushl   %edx

+    pushl   %ecx

+    call    *%ebx

+    jmp     .

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm
new file mode 100644
index 0000000..6c9b0ea
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   EnablePaging64.Asm

+;

+; Abstract:

+;

+;   AsmEnablePaging64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686p

+    .model  flat,C

+    .code

+

+InternalX86EnablePaging64 PROC

+    cli

+    mov     [esp], @F                   ; offset for far retf

+    mov     eax, cr4

+    or      al, (1 SHL 5)

+    mov     cr4, eax                    ; enable PAE

+    mov     ecx, 0c0000080h

+    rdmsr

+    or      ah, 1                       ; set LME

+    wrmsr

+    mov     eax, cr0

+    bts     eax, 31

+    mov     cr0, eax                    ; enable paging

+    retf

+@@:                                     ; long mode starts here

+    DB      67h, 48h

+    mov     ebx, [esp]                  ; mov rbx, [esp]

+    DB      67h, 48h

+    mov     ecx, [esp + 8]              ; mov rcx, [esp + 8]

+    DB      67h, 48h

+    mov     edx, [esp + 10h]            ; mov rdx, [esp + 10h]

+    DB      67h, 48h

+    mov     esp, [esp + 18h]            ; mov rsp, [esp + 18h]

+    DB      48h

+    add     esp, -20h                   ; add rsp, -20h

+    call    ebx                         ; call rbx

+    jmp     $

+InternalX86EnablePaging64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.s b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.s
new file mode 100644
index 0000000..b365ea7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.s
@@ -0,0 +1,66 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   EnablePaging64.Asm

+#

+# Abstract:

+#

+#   AsmEnablePaging64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+     

+    #.MODEL flat

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmEnablePaging64 (

+#   IN      UINT16                    CodeSelector,

+#   IN      UINT64                    EntryPoint,

+#   IN      UINT64                    Context1,    OPTIONAL

+#   IN      UINT64                    Context2,    OPTIONAL

+#   IN      UINT64                    NewStack

+#   );

+#------------------------------------------------------------------------------

+.global _AsmEnablePaging64

+_AsmEnablePaging64:

+    cli

+    movl    $$LongStart, (%esp)

+    movl    %cr4, %eax

+    orb     $0x20, %al

+    movl    %eax, %cr4                  # enable PAE

+    movl    $0xc0000080, %ecx

+    rdmsr

+    orb     $1, %ah                     # set LME

+    wrmsr

+    movl    %cr0, %eax

+    btsl    $31, %eax

+    movl    %eax, %cr0                  # enable paging

+    lret

+LongStart:                              # long mode starts here

+    .byte   0x67,0x48

+    movl    (%esp), %ebx                # mov rbx, [esp]

+    .byte   0x67,0x48

+    movl    8(%esp), %ecx               # mov rcx, [esp + 8]

+    .byte   0x67,0x48

+    movl    0x10(%esp), %edx            # mov rdx, [esp + 10h]

+    .byte   0x67,0x48

+    movl    0x18(%esp), %esp            # mov rsp, [esp + 18h]

+    .byte   0x48

+    addl    $0x-20, %esp                # add rsp, -20h

+    call    *%ebx                       # call rbx

+    jmp     .

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.asm b/edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.asm
new file mode 100644
index 0000000..d79f217
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   FlushCacheLine.Asm

+;

+; Abstract:

+;

+;   AsmFlushCacheLine function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmFlushCacheLine (

+;   IN      VOID                      *LinearAddress

+;   );

+;------------------------------------------------------------------------------

+_AsmFlushCacheLine  PROC

+    mov     eax, [esp + 4]

+    clflush [eax]

+    ret

+_AsmFlushCacheLine  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.s b/edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.s
new file mode 100644
index 0000000..c14bd11
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   FlushCacheLine.Asm

+#

+# Abstract:

+#

+#   AsmFlushCacheLine function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmFlushCacheLine (

+#   IN      VOID                      *LinearAddress

+#   );

+#------------------------------------------------------------------------------

+.global _AsmFlushCacheLine

+_AsmFlushCacheLine: 

+    movl    4(%esp),%eax

+    clflush (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm b/edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm
new file mode 100644
index 0000000..e9e37d1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   FxRestore.Asm

+;

+; Abstract:

+;

+;   AsmFxRestore function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86FxRestore (

+;   IN CONST IA32_FX_BUFFER *Buffer

+;   );

+;------------------------------------------------------------------------------

+InternalX86FxRestore  PROC

+    mov     eax, [esp + 4]

+    fxrstor [eax]

+    ret

+InternalX86FxRestore  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.s b/edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.s
new file mode 100644
index 0000000..631a3ef
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   FxRestore.Asm

+#

+# Abstract:

+#

+#   AsmFxRestore function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmFxRestore (

+#   IN CONST IA32_FX_BUFFER *Buffer

+#   );

+#------------------------------------------------------------------------------

+.global _AsmFxRestore

+_AsmFxRestore: 

+    movl    4(%esp),%eax

+    fxrstor (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm b/edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm
new file mode 100644
index 0000000..22496c5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   FxSave.Asm

+;

+; Abstract:

+;

+;   AsmFxSave function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86FxSave (

+;   OUT IA32_FX_BUFFER *Buffer

+;   );

+;------------------------------------------------------------------------------

+InternalX86FxSave PROC

+    mov     eax, [esp + 4]

+    fxsave  [eax]

+    ret

+InternalX86FxSave ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/FxSave.s b/edk2/MdePkg/Library/BaseLib/Ia32/FxSave.s
new file mode 100644
index 0000000..44a5512
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/FxSave.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   FxSave.Asm

+#

+# Abstract:

+#

+#   AsmFxSave function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmFxSave (

+#   OUT IA32_FX_BUFFER *Buffer

+#   );

+#------------------------------------------------------------------------------

+.global _AsmFxSave

+_AsmFxSave: 

+    movl    4(%esp),%eax

+    fxsave  (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange32.asm
new file mode 100644
index 0000000..c8c20fb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange32.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedCompareExchange32 (

+;   IN      UINT32                    *Value,

+;   IN      UINT32                    CompareValue,

+;   IN      UINT32                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange32   PROC

+    mov     ecx, [esp + 4]

+    mov     eax, [esp + 8]

+    mov     edx, [esp + 12]

+    lock    cmpxchg [ecx], edx

+    ret

+InternalSyncCompareExchange32   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange32.s b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange32.s
new file mode 100644
index 0000000..43bb925
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange32.s
@@ -0,0 +1,64 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   InterlockedCompareExchange32.Asm

+#

+# Abstract:

+#

+#   InterlockedCompareExchange32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID *

+# EFIAPI

+# InterlockedCompareExchangePointer (

+#   IN      VOID                      **Value,

+#   IN      VOID                      *CompareValue,

+#   IN      VOID                      *ExchangeValue

+#   );

+#------------------------------------------------------------------------------

+.global _InterlockedCompareExchangePointer

+_InterlockedCompareExchangePointer: 

+    #

+    # InterlockedCompareExchangePointer() shares the same code as

+    # InterlockedCompareExchange32() on IA32 and thus no code inside this

+    # function

+    #

+

+

+#------------------------------------------------------------------------------

+# UINT32

+# EFIAPI

+# InterlockedCompareExchange32 (

+#   IN      UINT32                    *Value,

+#   IN      UINT32                    CompareValue,

+#   IN      UINT32                    ExchangeValue

+#   );

+#------------------------------------------------------------------------------

+.global _InterlockedCompareExchange32

+_InterlockedCompareExchange32: 

+    movl    4(%esp),%ecx

+    movl    8(%esp),%eax

+    movl    12(%esp),%edx

+    lock    cmpxchgl %edx,(%ecx)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange64.asm
new file mode 100644
index 0000000..cded920
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange64.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange64.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InterlockedCompareExchange64 (

+;   IN      UINT64                    *Value,

+;   IN      UINT64                    CompareValue,

+;   IN      UINT64                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange64   PROC    USES    esi ebx

+    mov     esi, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     ebx, [esp + 24]

+    mov     ecx, [esp + 28]

+    lock    cmpxchg8b   qword ptr [esi]

+    ret

+InternalSyncCompareExchange64   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange64.s b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange64.s
new file mode 100644
index 0000000..abc51e9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedCompareExchange64.s
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   InterlockedCompareExchange64.Asm

+#

+# Abstract:

+#

+#   InterlockedCompareExchange64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InterlockedCompareExchange64 (

+#   IN      UINT64                    *Value,

+#   IN      UINT64                    CompareValue,

+#   IN      UINT64                    ExchangeValue

+#   );

+#------------------------------------------------------------------------------

+.global _InterlockedCompareExchange64

+    push    %esi

+    push    %ebx

+    movl    12(%esp),%esi

+    movl    16(%esp),%eax

+    movl    20(%esp),%edx

+    movl    24(%esp),%ebx

+    movl    28(%esp),%ecx

+    lock    

+    cmpxchg8b   (%esi)

+    pop     %ebx

+    pop     %esi

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedDecrement.asm b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedDecrement.asm
new file mode 100644
index 0000000..d849540
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedDecrement.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedDecrement.Asm

+;

+; Abstract:

+;

+;   InterlockedDecrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedDecrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncDecrement   PROC

+    mov     eax, [esp + 4]

+    lock    dec     dword ptr [eax]

+    mov     eax, [eax]

+    ret

+InternalSyncDecrement   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedDecrement.s b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedDecrement.s
new file mode 100644
index 0000000..a7b653a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedDecrement.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   InterlockedDecrement.Asm

+#

+# Abstract:

+#

+#   InterlockedDecrement function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT32

+# EFIAPI

+# InterlockedDecrement (

+#   IN      UINT32                    *Value

+#   );

+#------------------------------------------------------------------------------

+.global _InterlockedDecrement

+_InterlockedDecrement: 

+    movl    4(%esp),%eax

+    lock    

+    decl     (%eax)

+    movl    (%eax),%eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedIncrement.asm b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedIncrement.asm
new file mode 100644
index 0000000..a7bfb6f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedIncrement.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedIncrement.Asm

+;

+; Abstract:

+;

+;   InterlockedIncrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedIncrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncIncrement   PROC

+    mov     eax, [esp + 4]

+    lock    inc     dword ptr [eax]

+    mov     eax, [eax]

+    ret

+InternalSyncIncrement   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedIncrement.s b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedIncrement.s
new file mode 100644
index 0000000..3f9beec
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InterlockedIncrement.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   InterlockedIncrement.Asm

+#

+# Abstract:

+#

+#   InterlockedIncrement function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT32

+# EFIAPI

+# InterlockedIncrement (

+#   IN      UINT32                    *Value

+#   );

+#------------------------------------------------------------------------------

+.global _InterlockedIncrement

+_InterlockedIncrement: 

+    movl    4(%esp),%eax

+    lock    

+    incl     (%eax)

+    movl    (%eax),%eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.c b/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.c
new file mode 100644
index 0000000..ab8116b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.c
@@ -0,0 +1,52 @@
+/** @file

+  SwitchStack() function for IA-32.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  InternalSwitchStack.c

+

+**/

+

+/**

+  Transfers control to a function starting with a new stack.

+

+  Transfers control to the function specified by EntryPoint using the new stack

+  specified by NewStack and passing in the parameters specified by Context1 and

+  Context2. Context1 and Context2 are optional and may be NULL. The function

+  EntryPoint must never return.

+

+  @param  EntryPoint  A pointer to function to call with the new stack.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function.

+

+**/

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,

+  IN      VOID                      *Context2,

+  IN      VOID                      *NewStack

+  )

+{

+  BASE_LIBRARY_JUMP_BUFFER  JumpBuffer;

+

+  JumpBuffer.Eip = (UINTN)EntryPoint;

+  JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*);

+  JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2);

+  ((VOID**)JumpBuffer.Esp)[1] = Context1;

+  ((VOID**)JumpBuffer.Esp)[2] = Context2;

+

+  LongJump (&JumpBuffer, (UINTN)-1);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Invd.asm b/edk2/MdePkg/Library/BaseLib/Ia32/Invd.asm
new file mode 100644
index 0000000..5767f54
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Invd.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Invd.Asm

+;

+; Abstract:

+;

+;   AsmInvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmInvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmInvd    PROC

+    invd

+    ret

+_AsmInvd    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Invd.s b/edk2/MdePkg/Library/BaseLib/Ia32/Invd.s
new file mode 100644
index 0000000..6d6c8d4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Invd.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   Invd.Asm

+#

+# Abstract:

+#

+#   AsmInvd function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmInvd (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmInvd

+_AsmInvd: 

+    invd

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.asm
new file mode 100644
index 0000000..1d5562a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   LRotU64.asm

+;

+; Abstract:

+;

+;   64-bit left rotation for Ia32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMathLRotU64 PROC    USES    ebx

+    mov     cl, [esp + 16]

+    mov     edx, [esp + 12]

+    mov     eax, [esp + 8]

+    shld    ebx, edx, cl

+    shld    edx, eax, cl

+    ror     ebx, cl

+    shld    eax, ebx, cl

+    test    cl, 32

+    cmovnz  ecx, eax

+    cmovnz  eax, edx

+    cmovnz  edx, ecx

+    ret

+InternalMathLRotU64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.s b/edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.s
new file mode 100644
index 0000000..9c961ce
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   LRotU64.asm

+#

+# Abstract:

+#

+#   64-bit left rotation for Ia32

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _LRotU64

+    push    %ebx

+    movb    16(%esp),%cl

+    movl    12(%esp),%edx

+    movl    8(%esp),%eax

+    shldl   %cl,%edx,%ebx

+    shldl   %cl,%eax,%edx

+    rorl    %cl,%ebx

+    shldl   %cl,%ebx,%eax

+    testb   $32,%cl

+    cmovnz  %eax, %ecx

+    cmovnz  %edx, %eax 

+    cmovnz  %ecx, %edx

+    pop     %ebx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.asm
new file mode 100644
index 0000000..9ce946d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   LShiftU64.asm

+;

+; Abstract:

+;

+;   64-bit left shift function for IA-32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMathLShiftU64   PROC

+    mov     cl, [esp + 12]

+    xor     eax, eax

+    mov     edx, [esp + 4]

+    test    cl, 32

+    cmovz   eax, edx

+    cmovz   edx, [esp + 8]

+    shld    edx, eax, cl

+    shl     eax, cl

+    ret

+InternalMathLShiftU64   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.s b/edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.s
new file mode 100644
index 0000000..4aa17c6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.s
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   LShiftU64.asm
+#
+# Abstract:
+#
+#   64-bit left shift function for IA-32
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMathLShiftU64
+_InternalMathLShiftU64:
+    movb    12(%esp), %cl
+    xorl    %eax, %eax
+    movl    4(%esp), %edx
+    testb   $32, %cl
+    cmovz   %edx, %eax
+    cmovz   0x8(%esp), %edx
+    shld    %cl,%eax,%edx
+    shl     %cl, %eax
+    ret
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm b/edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm
new file mode 100644
index 0000000..5b7e21a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   LongJump.Asm

+;

+; Abstract:

+;

+;   Implementation of _LongJump() on IA-32.

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+__LongJump   PROC

+    pop     eax

+    pop     edx

+    pop     eax

+    mov     ebx, [edx]

+    mov     esi, [edx + 4]

+    mov     edi, [edx + 8]

+    mov     ebp, [edx + 12]

+    mov     esp, [edx + 16]

+    jmp     dword ptr [edx + 20]

+__LongJump   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/LongJump.s b/edk2/MdePkg/Library/BaseLib/Ia32/LongJump.s
new file mode 100644
index 0000000..4a36afc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/LongJump.s
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   LongJump.Asm

+#

+# Abstract:

+#

+#   Implementation of _LongJump() on IA-32.

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global __LongJump

+__LongJump: 

+    popl    %eax

+    popl    %edx

+    popl    %eax

+    movl    (%edx),%ebx

+    movl    4(%edx),%esi

+    movl    8(%edx),%edi

+    movl    12(%edx),%ebp

+    movl    16(%edx),%esp

+    jmpl    *20(%edx)

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.asm
new file mode 100644
index 0000000..62481ce
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DivU64x32.asm

+;

+; Abstract:

+;

+;   Calculate the remainder of a 64-bit integer by a 32-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMathModU64x32   PROC

+    mov     eax, [esp + 8]

+    mov     ecx, [esp + 12]

+    xor     edx, edx

+    div     ecx

+    mov     eax, [esp + 4]

+    div     ecx

+    mov     eax, edx

+    ret

+InternalMathModU64x32   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.s b/edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.s
new file mode 100644
index 0000000..ed9c2fe
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.s
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   DivU64x32.asm

+#

+# Abstract:

+#

+#   Calculate the remainder of a 64-bit integer by a 32-bit integer

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _ModU64x32

+_ModU64x32: 

+    movl    8(%esp),%eax

+    movl    12(%esp),%ecx

+    xorl    %edx,%edx

+    divl    %ecx

+    movl    4(%esp),%eax

+    divl    %ecx

+    movl    %edx,%eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Monitor.asm b/edk2/MdePkg/Library/BaseLib/Ia32/Monitor.asm
new file mode 100644
index 0000000..5d92d26
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Monitor.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Monitor.Asm

+;

+; Abstract:

+;

+;   AsmMonitor function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmMonitor (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx,

+;   IN      UINTN                     Edx

+;   );

+;------------------------------------------------------------------------------

+_AsmMonitor PROC

+    mov     eax, [esp + 4]

+    mov     ecx, [esp + 8]

+    mov     edx, [esp + 12]

+    DB      0fh, 1, 0c8h

+    ret

+_AsmMonitor ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Monitor.s b/edk2/MdePkg/Library/BaseLib/Ia32/Monitor.s
new file mode 100644
index 0000000..8da0e34
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Monitor.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   Monitor.Asm

+#

+# Abstract:

+#

+#   AsmMonitor function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmMonitor (

+#   IN      UINTN                     Eax,

+#   IN      UINTN                     Ecx,

+#   IN      UINTN                     Edx

+#   );

+#------------------------------------------------------------------------------

+.global _AsmMonitor

+_AsmMonitor: 

+    movl    4(%esp),%eax

+    movl    8(%esp),%ecx

+    movl    12(%esp),%edx

+    monitor %eax,%ecx,%edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.asm
new file mode 100644
index 0000000..e2806e3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.asm
@@ -0,0 +1,35 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   MultU64x32.asm

+;

+; Abstract:

+;

+;   Calculate the product of a 64-bit integer and a 32-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMathMultU64x32  PROC

+    mov     ecx, [esp + 12]

+    mov     eax, ecx

+    imul    ecx, [esp + 8]

+    mul     dword ptr [esp + 4]

+    add     edx, ecx

+    ret

+InternalMathMultU64x32  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.s b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.s
new file mode 100644
index 0000000..572a312
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.s
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   MultU64x32.asm
+#
+# Abstract:
+#
+#   Calculate the product of a 64-bit integer and a 32-bit integer
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global _InternalMathMultU64x32
+_InternalMathMultU64x32:
+    movl    12(%esp),%ecx
+    movl    %ecx,%eax
+    imull   8(%esp),%ecx
+    mull   0x4(%esp)
+    addl    %ecx,%edx
+    ret
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm
new file mode 100644
index 0000000..24c6a7d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   MultU64x64.asm

+;

+; Abstract:

+;

+;   Calculate the product of a 64-bit integer and another 64-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMathMultU64x64  PROC    USES    ebx

+    mov     ebx, [esp + 8]

+    mov     edx, [esp + 16]

+    mov     ecx, ebx

+    mov     eax, edx

+    imul    ebx, [esp + 20]

+    imul    edx, [esp + 12]

+    add     ebx, edx

+    mul     ecx

+    add     edx, ebx

+    ret

+InternalMathMultU64x64  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.s b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.s
new file mode 100644
index 0000000..8841fc4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.s
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   MultU64x64.asm

+#

+# Abstract:

+#

+#   Calculate the product of a 64-bit integer and another 64-bit integer

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _MultS64x64

+_MultS64x64: 

+    #

+    # MultS64x32 shares the same implementation with _MultU64x32, and thus no

+    # code inside this function.

+    #

+

+

+.global _MultU64x64

+    push    %ebx

+    movl    8(%esp),%ebx

+    movl    16(%esp),%edx

+    movl    %ebx,%ecx

+    movl    %edx,%eax

+    imull   20(%esp),%ebx

+    imull   12(%esp),%edx

+    addl    %edx,%ebx

+    mull    %ecx

+    addl    %ebx,%edx

+    pop     %ebx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Mwait.asm b/edk2/MdePkg/Library/BaseLib/Ia32/Mwait.asm
new file mode 100644
index 0000000..91d505b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Mwait.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Mwait.Asm

+;

+; Abstract:

+;

+;   AsmMwait function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmMwait (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx

+;   );

+;------------------------------------------------------------------------------

+_AsmMwait   PROC

+    mov     eax, [esp + 4]

+    mov     ecx, [esp + 8]

+    DB      0fh, 1, 0c9h

+    ret

+_AsmMwait   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Mwait.s b/edk2/MdePkg/Library/BaseLib/Ia32/Mwait.s
new file mode 100644
index 0000000..7e04453
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Mwait.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   Mwait.Asm

+#

+# Abstract:

+#

+#   AsmMwait function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmMwait (

+#   IN      UINTN                     Eax,

+#   IN      UINTN                     Ecx

+#   );

+#------------------------------------------------------------------------------

+.global _AsmMwait

+_AsmMwait: 

+    movl    4(%esp),%eax

+    movl    8(%esp),%ecx

+    mwait   %eax,%ecx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Non-existing.c b/edk2/MdePkg/Library/BaseLib/Ia32/Non-existing.c
new file mode 100644
index 0000000..4132d30
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Non-existing.c
@@ -0,0 +1,30 @@
+/** @file

+	Non-existing BaseLib functions on Ia32

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	Non-existing.c

+

+**/

+

+#include "../BaseLibInternals.h"

+

+VOID

+EFIAPI

+InternalX86DisablePaging64 (

+  IN      UINT16                    CodeSelector,

+  IN      UINT32                    EntryPoint,

+  IN      UINT32                    Context1,  OPTIONAL

+  IN      UINT32                    Context2,  OPTIONAL

+  IN      UINT32                    NewStack

+  )

+{

+  ASSERT (FALSE);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm
new file mode 100644
index 0000000..062e201
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   RRotU64.asm

+;

+; Abstract:

+;

+;   64-bit right rotation for Ia32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMathRRotU64 PROC    USES    ebx

+    mov     cl, [esp + 16]

+    mov     eax, [esp + 8]

+    mov     edx, [esp + 12]

+    shrd    ebx, eax, cl

+    shrd    eax, edx, cl

+    rol     ebx, cl

+    shrd    edx, ebx, cl

+    test    cl, 32

+    cmovnz  ecx, eax

+    cmovnz  eax, edx

+    cmovnz  edx, ecx

+    ret

+InternalMathRRotU64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.s b/edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.s
new file mode 100644
index 0000000..541e420
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   RRotU64.asm

+#

+# Abstract:

+#

+#   64-bit right rotation for Ia32

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _RRotU64

+    push    %ebx

+    movb    16(%esp),%cl

+    movl    8(%esp),%eax

+    movl    12(%esp),%edx

+    shrdl   %cl,%eax,%ebx

+    shrdl   %cl,%edx,%eax

+    roll    %cl,%ebx

+    shrdl   %cl,%ebx,%edx

+    testb   $32,%cl

+    cmovnz  %eax, %ecx

+    cmovnz  %edx, %eax

+    cmovnz  %ecx, %edx

+    pop     %ebx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm
new file mode 100644
index 0000000..effbc55
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   RShiftU64.asm

+;

+; Abstract:

+;

+;   64-bit logical right shift function for IA-32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMathRShiftU64   PROC

+    mov     cl, [esp + 12]

+    xor     edx, edx

+    mov     eax, [esp + 8]

+    test    cl, 32

+    cmovz   edx, eax

+    cmovz   eax, [esp + 4]

+    shrd    eax, edx, cl

+    shr     edx, cl

+    ret

+InternalMathRShiftU64   ENDP

+

+    END
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.s b/edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.s
new file mode 100644
index 0000000..f6c28de
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.s
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   RShiftU64.asm
+#
+# Abstract:
+#
+#   64-bit logical right shift function for IA-32
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    .code: 
+
+.global _InternalMathRShiftU64
+_InternalMathRShiftU64:
+    movb    12(%esp),%cl
+    xorl    %edx,%edx
+    movl    8(%esp),%eax
+    testb   $32,%cl
+    cmovz   %eax, %edx
+    cmovz   0x4(%esp), %eax
+    shrdl   %cl,%edx,%eax
+    shr     %cl,%edx
+    ret
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.asm
new file mode 100644
index 0000000..579cee2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr0.Asm

+;

+; Abstract:

+;

+;   AsmReadCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadCr0 PROC

+    mov     eax, cr0

+    ret

+_AsmReadCr0 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.s
new file mode 100644
index 0000000..3108b71
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadCr0.Asm

+#

+# Abstract:

+#

+#   AsmReadCr0 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadCr0 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadCr0

+_AsmReadCr0: 

+    movl    %cr0, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.asm
new file mode 100644
index 0000000..3e4a926
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr2.Asm

+;

+; Abstract:

+;

+;   AsmReadCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadCr2 PROC

+    mov     eax, cr2

+    ret

+_AsmReadCr2 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.s
new file mode 100644
index 0000000..3ce287a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadCr2.Asm

+#

+# Abstract:

+#

+#   AsmReadCr2 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadCr2 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadCr2

+_AsmReadCr2: 

+    movl    %cr2, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.asm
new file mode 100644
index 0000000..c24ded8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr3.Asm

+;

+; Abstract:

+;

+;   AsmReadCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadCr3 PROC

+    mov     eax, cr3

+    ret

+_AsmReadCr3 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.s
new file mode 100644
index 0000000..2bd63c7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadCr3.Asm

+#

+# Abstract:

+#

+#   AsmReadCr3 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadCr3 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadCr3

+_AsmReadCr3: 

+    movl    %cr3, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.asm
new file mode 100644
index 0000000..258f37a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr4.Asm

+;

+; Abstract:

+;

+;   AsmReadCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadCr4 PROC

+    mov     eax, cr4

+    ret

+_AsmReadCr4 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.s
new file mode 100644
index 0000000..4d746d8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadCr4.Asm

+#

+# Abstract:

+#

+#   AsmReadCr4 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadCr4 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadCr4

+_AsmReadCr4: 

+    movl    %cr4, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.asm
new file mode 100644
index 0000000..5972d66
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCs.Asm

+;

+; Abstract:

+;

+;   AsmReadCs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadCs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadCs  PROC

+    mov     ax, cs

+    ret

+_AsmReadCs  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.s
new file mode 100644
index 0000000..66bf4b9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadCs.Asm

+#

+# Abstract:

+#

+#   AsmReadCs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadCs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadCs

+_AsmReadCs: 

+    movw    %cs,%ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.asm
new file mode 100644
index 0000000..4da1dd8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr0.Asm

+;

+; Abstract:

+;

+;   AsmReadDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr0 PROC

+    mov     eax, dr0

+    ret

+_AsmReadDr0 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.s
new file mode 100644
index 0000000..00c521b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.s
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr0.Asm

+#

+# Abstract:

+#

+#   AsmReadDr0 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr0 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr0

+_AsmReadDr0: 

+    movl    %dr0, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.asm
new file mode 100644
index 0000000..8724dd2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr1.Asm

+;

+; Abstract:

+;

+;   AsmReadDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr1 PROC

+    mov     eax, dr1

+    ret

+_AsmReadDr1 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.s
new file mode 100644
index 0000000..81d0e54
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr1.Asm

+#

+# Abstract:

+#

+#   AsmReadDr1 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr1 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr1

+_AsmReadDr1: 

+    movl    %dr1, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.asm
new file mode 100644
index 0000000..9122d42
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr2.Asm

+;

+; Abstract:

+;

+;   AsmReadDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr2 PROC

+    mov     eax, dr2

+    ret

+_AsmReadDr2 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.s
new file mode 100644
index 0000000..296fff6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr2.Asm

+#

+# Abstract:

+#

+#   AsmReadDr2 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr2 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr2

+_AsmReadDr2: 

+    movl    %dr2, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.asm
new file mode 100644
index 0000000..7c1ee98
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr3.Asm

+;

+; Abstract:

+;

+;   AsmReadDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr3 PROC

+    mov     eax, dr3

+    ret

+_AsmReadDr3 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.s
new file mode 100644
index 0000000..e99391d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr3.Asm

+#

+# Abstract:

+#

+#   AsmReadDr3 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr3 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr3

+_AsmReadDr3: 

+    movl    %dr3, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm
new file mode 100644
index 0000000..0172455
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr4.Asm

+;

+; Abstract:

+;

+;   AsmReadDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr4 PROC

+    DB      0fh, 21h, 0e0h

+    ret

+_AsmReadDr4 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.s
new file mode 100644
index 0000000..7bff676
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr4.Asm

+#

+# Abstract:

+#

+#   AsmReadDr4 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr4 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr4

+_AsmReadDr4: 

+    movl    %dr4, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm
new file mode 100644
index 0000000..a95527e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr5.Asm

+;

+; Abstract:

+;

+;   AsmReadDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr5 PROC

+    DB      0fh, 21h, 0e8h

+    ret

+_AsmReadDr5 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.s
new file mode 100644
index 0000000..df409e3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr5.Asm

+#

+# Abstract:

+#

+#   AsmReadDr5 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr5 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr5

+_AsmReadDr5: 

+    movl    %dr5, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.asm
new file mode 100644
index 0000000..b2d9a3d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr6.Asm

+;

+; Abstract:

+;

+;   AsmReadDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr6 PROC

+    mov     eax, dr6

+    ret

+_AsmReadDr6 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.s
new file mode 100644
index 0000000..bdadd80
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr6.Asm

+#

+# Abstract:

+#

+#   AsmReadDr6 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr6 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr6

+_AsmReadDr6: 

+    movl    %dr6, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.asm
new file mode 100644
index 0000000..23924b1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr7.Asm

+;

+; Abstract:

+;

+;   AsmReadDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDr7 PROC

+    mov     eax, dr7

+    ret

+_AsmReadDr7 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.s
new file mode 100644
index 0000000..cf213ca
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDr7.Asm

+#

+# Abstract:

+#

+#   AsmReadDr7 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadDr7 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDr7

+_AsmReadDr7: 

+    movl    %dr7, %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.asm
new file mode 100644
index 0000000..6992766
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDs.Asm

+;

+; Abstract:

+;

+;   AsmReadDs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadDs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadDs  PROC

+    mov     ax, ds

+    ret

+_AsmReadDs  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.s
new file mode 100644
index 0000000..ca1e379
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadDs.Asm

+#

+# Abstract:

+#

+#   AsmReadDs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadDs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadDs

+_AsmReadDs: 

+    movw    %ds,%ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.asm
new file mode 100644
index 0000000..365b1de
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadEflags.Asm

+;

+; Abstract:

+;

+;   AsmReadEflags function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadEflags (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadEflags  PROC

+    pushfd

+    pop     eax

+    ret

+_AsmReadEflags  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.s
new file mode 100644
index 0000000..a70a209
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadEflags.Asm

+#

+# Abstract:

+#

+#   AsmReadEflags function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadEflags (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadEflags

+_AsmReadEflags: 

+    pushfl

+    popl    %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.asm
new file mode 100644
index 0000000..0ced46a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadEs.Asm

+;

+; Abstract:

+;

+;   AsmReadEs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadEs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadEs  PROC

+    mov     ax, es

+    ret

+_AsmReadEs  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.s
new file mode 100644
index 0000000..69727b5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadEs.Asm

+#

+# Abstract:

+#

+#   AsmReadEs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadEs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadEs

+_AsmReadEs: 

+    movw    %es,%ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.asm
new file mode 100644
index 0000000..f1790c6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadFs.Asm

+;

+; Abstract:

+;

+;   AsmReadFs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadFs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadFs  PROC

+    mov     ax, fs

+    ret

+_AsmReadFs  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.s
new file mode 100644
index 0000000..7f4fdfa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadFs.Asm

+#

+# Abstract:

+#

+#   AsmReadFs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadFs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadFs

+_AsmReadFs: 

+    movw    %fs,%ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.asm
new file mode 100644
index 0000000..beacb62
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadGdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86ReadGdtr (

+;   OUT IA32_DESCRIPTOR  *Gdtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86ReadGdtr   PROC

+    mov     eax, [esp + 4]

+    sgdt    fword ptr [eax]

+    ret

+InternalX86ReadGdtr   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.s
new file mode 100644
index 0000000..f03a056
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadGdtr.Asm

+#

+# Abstract:

+#

+#   AsmReadGdtr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmReadGdtr (

+#   OUT IA32_DESCRIPTOR  *Gdtr

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadGdtr

+_AsmReadGdtr: 

+    movl    4(%esp),%eax

+    sgdt    (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.asm
new file mode 100644
index 0000000..1de0ebf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadGs.Asm

+;

+; Abstract:

+;

+;   AsmReadGs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadGs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadGs  PROC

+    mov     ax, gs

+    ret

+_AsmReadGs  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.s
new file mode 100644
index 0000000..0d88a60
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadGs.Asm

+#

+# Abstract:

+#

+#   AsmReadGs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadGs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadGs

+_AsmReadGs: 

+    movw    %gs,%ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.asm
new file mode 100644
index 0000000..95158be
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.asm
@@ -0,0 +1,34 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadIdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalX86ReadIdtr   PROC

+    mov     eax, [esp + 4]

+    sidt    fword ptr [eax]

+    ret

+InternalX86ReadIdtr   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.s
new file mode 100644
index 0000000..fa72d3b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadIdtr.Asm

+#

+# Abstract:

+#

+#   AsmReadIdtr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmReadIdtr (

+#   OUT IA32_DESCRIPTOR  *Idtr

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadIdtr

+_AsmReadIdtr: 

+    movl    4(%esp),%eax

+    sidt    (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.asm
new file mode 100644
index 0000000..a859a0e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadLdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadLdtr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadLdtr    PROC

+    sldt    ax

+    ret

+_AsmReadLdtr    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.s
new file mode 100644
index 0000000..aea1d92
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadLdtr.Asm

+#

+# Abstract:

+#

+#   AsmReadLdtr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadLdtr (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadLdtr

+_AsmReadLdtr: 

+    sldt   %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.asm
new file mode 100644
index 0000000..c45895b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm0.Asm

+;

+; Abstract:

+;

+;   AsmReadMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm0 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm0

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm0 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.s
new file mode 100644
index 0000000..dd6b846
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm0.Asm

+#

+# Abstract:

+#

+#   AsmReadMm0 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm0 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm0

+_AsmReadMm0: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm0,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.asm
new file mode 100644
index 0000000..ea748cb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm1.Asm

+;

+; Abstract:

+;

+;   AsmReadMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm1 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm1

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm1 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.s
new file mode 100644
index 0000000..cbaafff
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm1.Asm

+#

+# Abstract:

+#

+#   AsmReadMm1 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm1 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm1

+_AsmReadMm1: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm1,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.asm
new file mode 100644
index 0000000..ab16c51
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm2.Asm

+;

+; Abstract:

+;

+;   AsmReadMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm2 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm2

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm2 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.s
new file mode 100644
index 0000000..22a5d71
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm2.Asm

+#

+# Abstract:

+#

+#   AsmReadMm2 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm2 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm2

+_AsmReadMm2: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm2,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.asm
new file mode 100644
index 0000000..3c4bf34
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm3.Asm

+;

+; Abstract:

+;

+;   AsmReadMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm3 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm3

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm3 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.s
new file mode 100644
index 0000000..dae267a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm3.Asm

+#

+# Abstract:

+#

+#   AsmReadMm3 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm3 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm3

+_AsmReadMm3: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm3,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.asm
new file mode 100644
index 0000000..4c2beb8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm4.Asm

+;

+; Abstract:

+;

+;   AsmReadMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm4 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm4

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm4 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.s
new file mode 100644
index 0000000..0ae1afc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm4.Asm

+#

+# Abstract:

+#

+#   AsmReadMm4 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm4 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm4

+_AsmReadMm4: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm4,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.asm
new file mode 100644
index 0000000..66e3826
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm5.Asm

+;

+; Abstract:

+;

+;   AsmReadMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm5 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm5

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm5 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.s
new file mode 100644
index 0000000..2fad14a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm5.Asm

+#

+# Abstract:

+#

+#   AsmReadMm5 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm5 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm5

+_AsmReadMm5: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm5,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.asm
new file mode 100644
index 0000000..69d9e13
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm6.Asm

+;

+; Abstract:

+;

+;   AsmReadMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm6 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm6

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm6 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.s
new file mode 100644
index 0000000..22cddfa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm6.Asm

+#

+# Abstract:

+#

+#   AsmReadMm6 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm6 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm6

+_AsmReadMm6: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm6,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.asm
new file mode 100644
index 0000000..a8788cb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm7.Asm

+;

+; Abstract:

+;

+;   AsmReadMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMm7 PROC

+    push    eax

+    push    eax

+    movq    [esp], mm7

+    pop     eax

+    pop     edx

+    ret

+_AsmReadMm7 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.s
new file mode 100644
index 0000000..fb485a0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMm7.Asm

+#

+# Abstract:

+#

+#   AsmReadMm7 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmReadMm7 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMm7

+_AsmReadMm7: 

+    pushl   %eax

+    pushl   %eax

+    movq    %mm7,(%esp)

+    popl    %eax

+    popl    %edx

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.asm
new file mode 100644
index 0000000..6c9fe00
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMsr64.Asm

+;

+; Abstract:

+;

+;   AsmReadMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; AsmReadMsr32 (

+;   IN UINT32  Index

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMsr32   PROC

+    ;

+    ; AsmReadMsr32 shares the same implementation with AsmReadMsr64 and thus no

+    ; code inside this function

+    ;

+_AsmReadMsr32   ENDP

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMsr64 (

+;   IN UINT64  Index

+;   );

+;------------------------------------------------------------------------------

+_AsmReadMsr64   PROC

+    mov     ecx, [esp + 4]

+    rdmsr

+    ret

+_AsmReadMsr64   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.s
new file mode 100644
index 0000000..6a2c9c6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.s
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadMsr64.Asm

+#

+# Abstract:

+#

+#   AsmReadMsr64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT32

+# EFIAPI

+# AsmReadMsr32 (

+#   IN UINT32  Index

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMsr32

+_AsmReadMsr32: 

+    #

+    # AsmReadMsr32 shares the same implementation with AsmReadMsr64 and thus no

+    # code inside this function

+    #

+

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmReadMsr64 (

+#   IN UINT64  Index

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadMsr64

+_AsmReadMsr64: 

+    movl    4(%esp),%ecx

+    rdmsr

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.asm
new file mode 100644
index 0000000..1fe5981
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadPmc.Asm

+;

+; Abstract:

+;

+;   AsmReadPmc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadPmc (

+;   IN UINT32   PmcIndex

+;   );

+;------------------------------------------------------------------------------

+_AsmReadPmc PROC

+    mov     ecx, [esp + 4]

+    rdpmc

+    ret

+_AsmReadPmc ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.s
new file mode 100644
index 0000000..868e85c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadPmc.Asm

+#

+# Abstract:

+#

+#   AsmReadPmc function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmReadPmc (

+#   IN UINT32   PmcIndex

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadPmc

+_AsmReadPmc: 

+    movl    4(%esp),%ecx

+    rdpmc

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.asm
new file mode 100644
index 0000000..6d0cd9f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadSs.Asm

+;

+; Abstract:

+;

+;   AsmReadSs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadSs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadSs  PROC

+    mov     ax, ss

+    ret

+_AsmReadSs  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.s
new file mode 100644
index 0000000..7db65c1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadSs.Asm

+#

+# Abstract:

+#

+#   AsmReadSs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadSs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadSs

+_AsmReadSs: 

+    movw    %ss,%ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.asm
new file mode 100644
index 0000000..d77ee89
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadTr.Asm

+;

+; Abstract:

+;

+;   AsmReadTr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadTr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadTr  PROC

+    str     ax

+    ret

+_AsmReadTr  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.s
new file mode 100644
index 0000000..8c31e9d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadTr.Asm

+#

+# Abstract:

+#

+#   AsmReadTr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadTr (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadTr

+_AsmReadTr: 

+    str     %eax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.asm b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.asm
new file mode 100644
index 0000000..ea3c164
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadTsc.Asm

+;

+; Abstract:

+;

+;   AsmReadTsc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadTsc (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmReadTsc PROC

+    rdtsc

+    ret

+_AsmReadTsc ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.s b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.s
new file mode 100644
index 0000000..e7981c0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   ReadTsc.Asm

+#

+# Abstract:

+#

+#   AsmReadTsc function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmReadTsc (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmReadTsc

+_AsmReadTsc: 

+    rdtsc

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm b/edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm
new file mode 100644
index 0000000..41277cd
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetJump.Asm

+;

+; Abstract:

+;

+;   Implementation of SetJump() on IA-32.

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat

+    .code

+

+_SetJump    PROC

+    pop     ecx

+    mov     edx, [esp]

+    mov     [edx], ebx

+    mov     [edx + 4], esi

+    mov     [edx + 8], edi

+    mov     [edx + 12], ebp

+    mov     [edx + 16], esp

+    mov     [edx + 20], ecx

+    xor     eax, eax

+    jmp     ecx

+_SetJump    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/SetJump.s b/edk2/MdePkg/Library/BaseLib/Ia32/SetJump.s
new file mode 100644
index 0000000..b1b6a84
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/SetJump.s
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   SetJump.Asm

+#

+# Abstract:

+#

+#   Implementation of SetJump() on IA-32.

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+.global _SetJump

+_SetJump: 

+    popl    %ecx

+    movl    (%esp),%edx

+    movl    %ebx,(%edx)

+    movl    %esi,4(%edx)

+    movl    %edi,8(%edx)

+    movl    %ebp,12(%edx)

+    movl    %esp,16(%edx)

+    movl    %ecx,20(%edx)

+    xorl    %eax,%eax

+    jmp     *%ecx

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm
new file mode 100644
index 0000000..72e366b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm
@@ -0,0 +1,36 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuId.Asm

+;

+; Abstract:

+;

+;   AsmCpuid function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .code

+

+InternalMathSwapBytes64 PROC

+    mov     eax, [esp + 8]

+    mov     edx, [esp + 4]

+    bswap   eax

+    bswap   edx

+    ret

+InternalMathSwapBytes64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.s b/edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.s
new file mode 100644
index 0000000..01af949
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.s
@@ -0,0 +1,34 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CpuId.Asm
+#
+# Abstract:
+#
+#   AsmCpuid function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+
+.global _InternalMathSwapBytes64
+_InternalMathSwapBytes64:
+
+    movl    8(%esp), %eax
+    movl    4(%esp), %edx
+    bswapl  %eax
+    bswapl  %edx
+    ret
+
+
diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm b/edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm
new file mode 100644
index 0000000..454b890
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm
@@ -0,0 +1,225 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Thunk.asm

+;

+; Abstract:

+;

+;   Real mode thunk

+;

+;------------------------------------------------------------------------------

+

+    .686p

+    .model  flat,C

+

+EXTERNDEF   C   m16Start:BYTE

+EXTERNDEF   C   m16Size:WORD

+EXTERNDEF   C   mThunk16Attr:WORD

+EXTERNDEF   C   m16Gdt:WORD

+EXTERNDEF   C   m16GdtrBase:WORD

+EXTERNDEF   C   mTransition:WORD

+

+THUNK_ATTRIBUTE_BIG_REAL_MODE               EQU 1

+THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15     EQU 2

+THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL   EQU 4

+

+IA32_REGS   STRUC   4t

+_EDI        DD      ?

+_ESI        DD      ?

+_EBP        DD      ?

+_ESP        DD      ?

+_EBX        DD      ?

+_EDX        DD      ?

+_ECX        DD      ?

+_EAX        DD      ?

+_DS         DW      ?

+_ES         DW      ?

+_FS         DW      ?

+_GS         DW      ?

+_EFLAGS     DD      ?

+_EIP        DD      ?

+_CS         DW      ?

+_SS         DW      ?

+IA32_REGS   ENDS

+

+    .const

+

+m16Size         DW      offset InternalAsmThunk16 - offset m16Start

+mThunk16Attr    DW      offset _ThunkAttr - offset m16Start

+m16Gdt          DW      offset _NullSegDesc - offset m16Start

+m16GdtrBase     DW      offset _16GdtrBase - offset m16Start

+mTransition     DW      offset _EntryPoint - offset m16Start

+

+    .code

+

+m16Start    LABEL   BYTE

+

+SavedGdt        LABEL   FWORD

+                DW      ?

+                DD      ?

+

+_BackFromUserCode   PROC

+    push    ss

+    push    cs

+    DB      66h

+    call    @Base                       ; push eip

+@Base:

+    pushf                               ; pushfd actually

+    cli                                 ; disable interrupts

+    push    gs

+    push    fs

+    push    es

+    push    ds

+    pushaw                              ; pushad actually

+    DB      66h, 0bah                   ; mov edx, imm32

+_ThunkAttr  DD      ?

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15

+    jz      @1

+    mov     eax, 15cd2401h              ; mov ax, 2401h & int 15h

+    cli                                 ; disable interrupts

+    jnc     @2

+@1:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL

+    jz      @2

+    in      al, 92h

+    or      al, 2

+    out     92h, al                     ; deactivate A20M#

+@2:

+    mov     eax, ss

+    DB      67h

+    lea     bp, [esp + sizeof (IA32_REGS)]

+    mov     word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp

+    mov     ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP

+    shl     ax, 4                       ; shl eax, 4

+    add     bp, ax                      ; add ebp, eax

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr4    DD      ?

+    mov     cr4, eax

+    DB      66h

+    lgdt    fword ptr cs:[edi + (offset SavedGdt - offset @Base)]

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr0    DD      ?

+    mov     cr0, eax

+    DB      0b8h                        ; mov ax, imm16

+SavedSs     DW      ?

+    mov     ss, eax

+    DB      66h, 0bch                   ; mov esp, imm32

+SavedEsp    DD      ?

+    DB      66h

+    retf                                ; return to protected mode

+_BackFromUserCode   ENDP

+

+_EntryPoint     DD      offset _ToUserCode - offset m16Start

+                DW      8h

+_16Idtr         FWORD   (1 SHL 10) - 1

+_16Gdtr         LABEL   FWORD

+                DW      offset GdtEnd - offset _NullSegDesc - 1

+_16GdtrBase     DD      offset _NullSegDesc

+

+_ToUserCode PROC

+    mov     edx, ss

+    mov     ss, ecx                     ; set new segment selectors

+    mov     ds, ecx

+    mov     es, ecx

+    mov     fs, ecx

+    mov     gs, ecx

+    mov     cr0, eax

+    mov     cr4, ebp                    ; real mode starts at next instruction

+    mov     ss, esi                     ; set up 16-bit stack segment

+    xchg    sp, bx                      ; set up 16-bit stack pointer

+    DB      66h

+    call    @Base                       ; push eip

+@Base:

+    pop     bp                          ; ebp <- offset @Base

+    DB      67h                         ; address size override

+    push    [esp + sizeof (IA32_REGS) + 2]

+    lea     eax, [esi + (offset @RealMode - offset @Base)]

+    push    eax

+    retf

+@RealMode:

+    mov     cs:[esi + (offset SavedSs - offset @Base)], edx

+    mov     cs:[esi + (offset SavedEsp - offset @Base)], bx

+    DB      66h

+    lidt    fword ptr cs:[esi + (offset _16Idtr - offset @Base)]

+    popaw                               ; popad actually

+    pop     ds

+    pop     es

+    pop     fs

+    pop     gs

+    popf                                ; popfd

+    DB      66h

+    retf                                ; transfer control to user code

+_ToUserCode ENDP

+

+_NullSegDesc    DQ      0

+_16CsDesc       LABEL   QWORD

+                DW      -1

+                DW      0

+                DB      0

+                DB      9bh

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+_16DsDesc       LABEL   QWORD

+                DW      -1

+                DW      0

+                DB      0

+                DB      93h

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+GdtEnd          LABEL   QWORD

+

+;

+;   @param  RegSet  Pointer to a IA32_DWORD_REGS structure

+;   @param  Transition  Pointer to the transition code

+;   @return The address of the 16-bit stack after returning from user code

+;

+InternalAsmThunk16  PROC    USES    ebp ebx esi edi ds  es  fs  gs

+    mov     esi, [esp + 36]             ; esi <- RegSet

+    movzx   edx, (IA32_REGS ptr [esi])._SS

+    mov     edi, (IA32_REGS ptr [esi])._ESP

+    add     edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space

+    mov     ebx, edi                    ; ebx <- stack offset

+    imul    eax, edx, 16                ; eax <- edx * 16

+    push    sizeof (IA32_REGS) / 4

+    add     edi, eax                    ; edi <- linear address of 16-bit stack

+    pop     ecx

+    rep     movsd                       ; copy RegSet

+    mov     eax, [esp + 40]             ; eax <- address of transition code

+    mov     esi, edx                    ; esi <- 16-bit stack segment

+    lea     edx, [eax + (offset SavedCr0 - offset m16Start)]

+    mov     ecx, eax

+    and     ecx, 0fh

+    shl     eax, 12

+    lea     ecx, [ecx + (offset _BackFromUserCode - offset m16Start)]

+    mov     ax, cx

+    stosd                               ; [edi] <- return address of user code

+    sgdt    fword ptr [edx + (offset SavedGdt - offset SavedCr0)]

+    sidt    fword ptr [esp + 36]        ; save IDT stack in argument space

+    mov     eax, cr0

+    mov     [edx], eax                  ; save CR0 in SavedCr0

+    and     eax, 7ffffffeh              ; clear PE, PG bits

+    mov     ebp, cr4

+    mov     [edx + (offset SavedCr4 - offset SavedCr0)], ebp

+    and     ebp, 300h                   ; clear all but PCE and OSFXSR bits

+    push    10h

+    pop     ecx                         ; ecx <- selector for data segments

+    lgdt    fword ptr [edx + (offset _16Gdtr - offset SavedCr0)]

+    pushfd

+    call    fword ptr [edx + (offset _EntryPoint - offset SavedCr0)]

+    popfd

+    lidt    fword ptr [esp + 36]        ; restore protected mode IDTR

+    lea     eax, [ebp - sizeof (IA32_REGS)]

+    ret

+InternalAsmThunk16  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.s b/edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.s
new file mode 100644
index 0000000..fa7be91
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.s
@@ -0,0 +1,27 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   Thunk.asm

+#

+# Abstract:

+#

+#   Real mode thunk

+#

+#------------------------------------------------------------------------------

+

+

+

+

+                        ##########

+                        # FIXME! #

+                        ##########

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.asm b/edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.asm
new file mode 100644
index 0000000..07258fb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Wbinvd.Asm

+;

+; Abstract:

+;

+;   AsmWbinvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWbinvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmWbinvd  PROC

+    wbinvd

+    ret

+_AsmWbinvd  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.s b/edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.s
new file mode 100644
index 0000000..e9f6c0c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.s
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   Wbinvd.Asm

+#

+# Abstract:

+#

+#   AsmWbinvd function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWbinvd (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWbinvd

+_AsmWbinvd: 

+    wbinvd

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.asm
new file mode 100644
index 0000000..d64d621
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteCr0    PROC

+    mov     eax, [esp + 4]

+    mov     cr0, eax

+    ret

+_AsmWriteCr0    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.s
new file mode 100644
index 0000000..6e3ad50
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteCr0.Asm

+#

+# Abstract:

+#

+#   AsmWriteCr0 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmWriteCr0 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteCr0

+_AsmWriteCr0: 

+    movl    4(%esp),%eax

+    movl    %eax, %cr0

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.asm
new file mode 100644
index 0000000..7ab5b0f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteCr2    PROC

+    mov     eax, [esp + 4]

+    mov     cr2, eax

+    ret

+_AsmWriteCr2    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.s
new file mode 100644
index 0000000..cf45e01
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteCr2.Asm

+#

+# Abstract:

+#

+#   AsmWriteCr2 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmWriteCr2 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteCr2

+_AsmWriteCr2: 

+    movl    4(%esp),%eax

+    movl    %eax, %cr2

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.asm
new file mode 100644
index 0000000..9753de1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteCr3    PROC

+    mov     eax, [esp + 4]

+    mov     cr3, eax

+    ret

+_AsmWriteCr3    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.s
new file mode 100644
index 0000000..1c55581
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteCr3.Asm

+#

+# Abstract:

+#

+#   AsmWriteCr3 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmWriteCr3 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteCr3

+_AsmWriteCr3: 

+    movl    4(%esp),%eax

+    movl    %eax, %cr3

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.asm
new file mode 100644
index 0000000..60bfe78
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteCr4    PROC

+    mov     eax, [esp + 4]

+    mov     cr4, eax

+    ret

+_AsmWriteCr4    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.s
new file mode 100644
index 0000000..fbe48c1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteCr4.Asm

+#

+# Abstract:

+#

+#   AsmWriteCr4 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# AsmWriteCr4 (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteCr4

+_AsmWriteCr4: 

+    movl    4(%esp),%eax

+    movl    %eax, %cr4

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.asm
new file mode 100644
index 0000000..3dab544
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr0 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr0    PROC

+    mov     eax, [esp + 4]

+    mov     dr0, eax

+    ret

+_AsmWriteDr0    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.s
new file mode 100644
index 0000000..a5a84de
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr0.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr0 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr0 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr0

+_AsmWriteDr0: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr0

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.asm
new file mode 100644
index 0000000..5898206
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr1.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr1 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr1    PROC

+    mov     eax, [esp + 4]

+    mov     dr1, eax

+    ret

+_AsmWriteDr1    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.s
new file mode 100644
index 0000000..66fc2c7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr1.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr1 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr1 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr1

+_AsmWriteDr1: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr1

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.asm
new file mode 100644
index 0000000..3ed25fc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr2 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr2    PROC

+    mov     eax, [esp + 4]

+    mov     dr2, eax

+    ret

+_AsmWriteDr2    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.s
new file mode 100644
index 0000000..7b3f780
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr2.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr2 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr2 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr2

+_AsmWriteDr2: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr2

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.asm
new file mode 100644
index 0000000..c1dbc82
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr3 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr3    PROC

+    mov     eax, [esp + 4]

+    mov     dr3, eax

+    ret

+_AsmWriteDr3    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.s
new file mode 100644
index 0000000..34d3e4f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr3.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr3 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr3 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr3

+_AsmWriteDr3: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr3

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm
new file mode 100644
index 0000000..2c82512
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr4 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr4    PROC

+    mov     eax, [esp + 4]

+    DB      0fh, 23h, 0e0h

+    ret

+_AsmWriteDr4    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.s
new file mode 100644
index 0000000..20ddbd2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr4.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr4 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr4 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr4

+_AsmWriteDr4: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr4

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm
new file mode 100644
index 0000000..dc07424
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr5.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr5 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr5    PROC

+    mov     eax, [esp + 4]

+    DB      0fh, 23h, 0e8h

+    ret

+_AsmWriteDr5    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.s
new file mode 100644
index 0000000..057928a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr5.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr5 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr5 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr5

+_AsmWriteDr5: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr5

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.asm
new file mode 100644
index 0000000..e307e82
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr6.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr6 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr6    PROC

+    mov     eax, [esp + 4]

+    mov     dr6, eax

+    ret

+_AsmWriteDr6    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.s
new file mode 100644
index 0000000..7d7726b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr6.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr6 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr6 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr6

+_AsmWriteDr6: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr6

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.asm
new file mode 100644
index 0000000..55dbdc9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr7.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteDr7 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteDr7    PROC

+    mov     eax, [esp + 4]

+    mov     dr7, eax

+    ret

+_AsmWriteDr7    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.s
new file mode 100644
index 0000000..a96f445
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteDr7.Asm

+#

+# Abstract:

+#

+#   AsmWriteDr7 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteDr7 (

+#   IN UINTN Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteDr7

+_AsmWriteDr7: 

+    movl    4(%esp),%eax

+    movl    %eax, %dr7

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.asm
new file mode 100644
index 0000000..a317e75
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.asm
@@ -0,0 +1,34 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteGdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686P

+    .model  flat,C

+    .code

+

+InternalX86WriteGdtr  PROC

+    mov     eax, [esp + 4]

+    lgdt    fword ptr [eax]

+    ret

+InternalX86WriteGdtr  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.s
new file mode 100644
index 0000000..c3eb63d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteGdtr.Asm

+#

+# Abstract:

+#

+#   AsmWriteGdtr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteGdtr (

+#   OUT IA32_DESCRIPTOR  *Gdtr

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteGdtr

+_AsmWriteGdtr: 

+    movl    4(%esp),%eax

+    lgdt    (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.asm
new file mode 100644
index 0000000..d4b3b51
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.asm
@@ -0,0 +1,34 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteIdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686P

+    .model  flat,C

+    .code

+

+InternalX86WriteIdtr  PROC

+    mov     eax, [esp + 4]

+    lidt    fword ptr [eax]

+    ret

+InternalX86WriteIdtr  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.s
new file mode 100644
index 0000000..f71b696
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteIdtr.Asm

+#

+# Abstract:

+#

+#   AsmWriteIdtr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteIdtr (

+#   OUT IA32_DESCRIPTOR  *Idtr

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteIdtr

+_AsmWriteIdtr: 

+    movl    4(%esp),%eax

+    lidt    (%eax)

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.asm
new file mode 100644
index 0000000..39f8b2e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteLdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteLdtr (

+;   IN UINT16 Ldtr

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteLdtr   PROC

+    mov     eax, [esp + 4]

+    lldt    ax

+    ret

+_AsmWriteLdtr   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.s
new file mode 100644
index 0000000..3797bd5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteLdtr.Asm

+#

+# Abstract:

+#

+#   AsmWriteLdtr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWriteLdtr (

+#   IN UINT16 Ldtr

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteLdtr

+_AsmWriteLdtr: 

+    movl    4(%esp),%eax

+    lldtw   %ax

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.asm
new file mode 100644
index 0000000..e924dbd
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm0.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm0 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm0    PROC

+    movq    mm0, [esp + 4]

+    ret

+_AsmWriteMm0    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.s
new file mode 100644
index 0000000..c444421
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm0.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm0 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm0 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm0

+_AsmWriteMm0: 

+    movq    4(%esp),%mm0

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.asm
new file mode 100644
index 0000000..1f1d8ce
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm1.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm1 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm1    PROC

+    movq    mm1, [esp + 4]

+    ret

+_AsmWriteMm1    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.s
new file mode 100644
index 0000000..e3a492f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm1.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm1 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm1 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm1

+_AsmWriteMm1: 

+    movq    4(%esp),%mm1

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.asm
new file mode 100644
index 0000000..a18417a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm2.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm2 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm2    PROC

+    movq    mm2, [esp + 4]

+    ret

+_AsmWriteMm2    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.s
new file mode 100644
index 0000000..eaebb37
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm2.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm2 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm2 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm2

+_AsmWriteMm2: 

+    movq    4(%esp),%mm2

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.asm
new file mode 100644
index 0000000..7aad49f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm3.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm3 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm3    PROC

+    movq    mm3, [esp + 4]

+    ret

+_AsmWriteMm3    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.s
new file mode 100644
index 0000000..a514091
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm3.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm3 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm3 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm3

+_AsmWriteMm3: 

+    movq    4(%esp),%mm3

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.asm
new file mode 100644
index 0000000..8be9c4b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm4.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm4 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm4    PROC

+    movq    mm4, [esp + 4]

+    ret

+_AsmWriteMm4    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.s
new file mode 100644
index 0000000..6d4a6cd
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm4.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm4 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm4 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm4

+_AsmWriteMm4: 

+    movq    4(%esp),%mm4

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.asm
new file mode 100644
index 0000000..bc501b3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm5.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm5 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm5    PROC

+    movq    mm5, [esp + 4]

+    ret

+_AsmWriteMm5    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.s
new file mode 100644
index 0000000..15d4332
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm5.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm5 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm5 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm5

+_AsmWriteMm5: 

+    movq    4(%esp),%mm5

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.asm
new file mode 100644
index 0000000..4a6445c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm6.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm6 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm6    PROC

+    movq    mm6, [esp + 4]

+    ret

+_AsmWriteMm6    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.s
new file mode 100644
index 0000000..6b1361e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm6.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm6 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm6 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm6

+_AsmWriteMm6: 

+    movq    4(%esp),%mm6

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.asm
new file mode 100644
index 0000000..3bc73fe
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm7.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMm7 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMm7    PROC

+    movq    mm7, [esp + 4]

+    ret

+_AsmWriteMm7    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.s
new file mode 100644
index 0000000..d702fbb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMm7.Asm

+#

+# Abstract:

+#

+#   AsmWriteMm7 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMm7 (

+#   IN UINT64   Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMm7

+_AsmWriteMm7: 

+    movq    4(%esp),%mm7

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr32.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr32.asm
new file mode 100644
index 0000000..ba14514
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr32.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMsr32.Asm

+;

+; Abstract:

+;

+;   AsmWriteMsr32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; AsmWriteMsr32 (

+;   IN UINT32  Index,

+;   IN UINT32  Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMsr32  PROC

+    mov     eax, [esp + 8]

+    xor     edx, edx

+    mov     ecx, [esp + 4]

+    wrmsr

+    ret

+_AsmWriteMsr32  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr32.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr32.s
new file mode 100644
index 0000000..450b3b7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr32.s
@@ -0,0 +1,45 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMsr32.Asm

+#

+# Abstract:

+#

+#   AsmWriteMsr32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT32

+# EFIAPI

+# AsmWriteMsr32 (

+#   IN UINT32  Index,

+#   IN UINT32  Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMsr32

+_AsmWriteMsr32: 

+    movl    8(%esp),%eax

+    xorl    %edx,%edx

+    movl    4(%esp),%ecx

+    wrmsr

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.asm b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.asm
new file mode 100644
index 0000000..5afc074
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMsr64.Asm

+;

+; Abstract:

+;

+;   AsmWriteMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMsr64 (

+;   IN UINT32  Index,

+;   IN UINT64  Value

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteMsr64  PROC

+    mov     edx, [esp + 12]

+    mov     eax, [esp + 8]

+    mov     ecx, [esp + 4]

+    wrmsr

+    ret

+_AsmWriteMsr64  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.s b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.s
new file mode 100644
index 0000000..802aad7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.s
@@ -0,0 +1,45 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, Intel Corporation

+# All rights reserved. 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.

+#

+# Module Name:

+#

+#   WriteMsr64.Asm

+#

+# Abstract:

+#

+#   AsmWriteMsr64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+

+     

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMsr64 (

+#   IN UINT32  Index,

+#   IN UINT64  Value

+#   );

+#------------------------------------------------------------------------------

+.global _AsmWriteMsr64

+_AsmWriteMsr64: 

+    movl    12(%esp),%edx

+    movl    8(%esp),%eax

+    movl    4(%esp),%ecx

+    wrmsr

+    ret

+

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c b/edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c
new file mode 100644
index 0000000..7923e92
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c
@@ -0,0 +1,119 @@
+/** @file

+  Base Library CPU functions for Itanium

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+//void __mfa (void);

+

+#pragma intrinsic (_enable)

+#pragma intrinsic (_disable)

+#pragma intrinsic (__break)

+#pragma intrinsic (__mfa)

+

+/**

+  Generates a breakpoint on the CPU.

+

+  Generates a breakpoint on the CPU. The breakpoint must be implemented such

+  that code can resume normal execution after the breakpoint.

+

+**/

+VOID

+EFIAPI

+CpuBreakpoint (

+  VOID

+  )

+{

+  __break (0);

+}

+

+/**

+  Used to serialize load and store operations.

+

+  All loads and stores that proceed calls to this function are guaranteed to be

+  globally visible when this function returns.

+

+**/

+VOID

+EFIAPI

+MemoryFence (

+  VOID

+  )

+{

+  __mfa ();

+}

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{

+  _disable ();

+}

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  _enable ();

+}

+

+/**

+  Retrieves the current CPU interrupt state.

+

+  Retrieves the current CPU interrupt state. Returns TRUE is interrupts are

+  currently enabled. Otherwise returns FALSE.

+

+  @retval TRUE  CPU interrupts are enabled.

+  @retval FALSE CPU interrupts are disabled.

+

+**/

+BOOLEAN

+EFIAPI

+GetInterruptState (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  )

+{

+  EnableInterrupts ();

+  DisableInterrupts ();

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s b/edk2/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s
new file mode 100644
index 0000000..6088304
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/CpuFlushTlb.s
@@ -0,0 +1,57 @@
+/// @file

+///   CpuFlushTlb() function for Itanium-based architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  CpuFlushTlb.s

+///

+///

+

+.auto

+.text

+

+.global PalCallStatic

+.type   PalCallStatic, @function

+

+.proc   CpuFlushTlb

+.type   CpuFlushTlb, @function

+CpuFlushTlb::

+        alloc               loc0 = ar.pfs, 0, 2, 5, 0

+        mov                 out0 = 0

+        mov                 out1 = 6

+        mov                 out2 = 0

+        mov                 out3 = 0

+        mov                 out4 = 0

+        mov                 loc1 = b0

+        br.call.sptk        b0  = PalCallStatic

+        rsm                 1 << 14                 // Disable interrupts

+        mov                 ar.pfs = loc0

+        extr.u              r14 = r10, 32, 32       // r14 <- count1

+        extr.u              r15 = r11, 32, 32       // r15 <- stride1

+        extr.u              r10 = r10, 0, 32        // r10 <- count2

+        mov                 loc0 = psr

+        extr.u              r11 = r11, 0, 32        // r11 <- stride2

+        br.cond.sptk        LoopPredicate

+LoopOuter:

+        mov                 ar.lc = r10             // LC <- count2

+        mov                 ar.ec = r0              // EC <- 0

+Loop:

+        ptc.e               r9

+        add                 r9 = r11, r9            // r9 += stride2

+        br.ctop.sptk        Loop

+        add                 r9 = r15, r9            // r9 += stride1

+LoopPredicate:

+        cmp.ne              p6, p7 = r0, r14        // count1 == 0?

+        add                 r14 = -1, r14

+(p6)    br.cond.sptk        LoopOuter

+        mov                 psr.l = loc0

+        mov                 b0  = loc1

+        br.ret.sptk.many    b0

+.endp

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/CpuPause.s b/edk2/MdePkg/Library/BaseLib/Ipf/CpuPause.s
new file mode 100644
index 0000000..f52692f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/CpuPause.s
@@ -0,0 +1,25 @@
+/// @file

+///   CpuPause() function for Itanium-based architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  CpuPause.s

+///

+///

+

+.auto

+.text

+

+.proc   CpuPause

+.type   CpuPause, @function

+CpuPause::

+        hint                @pause

+        br.ret.sptk.many    b0

+.endp

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/InterlockedCompareExchange32.s b/edk2/MdePkg/Library/BaseLib/Ipf/InterlockedCompareExchange32.s
new file mode 100644
index 0000000..3a278d7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/InterlockedCompareExchange32.s
@@ -0,0 +1,29 @@
+/// @file

+///   Contains an implementation of InterlockedCompareExchange32 on Itanium-

+///   based architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  InterlockedCompareExchange32.s

+///

+///

+

+.auto

+.text

+

+.proc   InternalSyncCompareExchange32

+.type   InternalSyncCompareExchange32, @function

+InternalSyncCompareExchange32::

+        zxt4                r33 = r33

+        mov                 ar.ccv = r33

+        cmpxchg4.rel        r8  = [r32], r34

+        mf

+        br.ret.sptk.many    b0

+.endp   InternalSyncCompareExchange32
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/InterlockedCompareExchange64.s b/edk2/MdePkg/Library/BaseLib/Ipf/InterlockedCompareExchange64.s
new file mode 100644
index 0000000..200e30e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/InterlockedCompareExchange64.s
@@ -0,0 +1,28 @@
+/// @file

+///   Contains an implementation of InterlockedCompareExchange64 on Itanium-

+///   based architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  InterlockedCompareExchange64.s

+///

+///

+

+.auto

+.text

+

+.proc   InternalSyncCompareExchange64

+.type   InternalSyncCompareExchange64, @function

+InternalSyncCompareExchange64::

+        mov                 ar.ccv = r33

+        cmpxchg8.rel        r8  = [r64], r34

+        mf

+        br.ret.sptk.many    b0

+.endp   InternalSyncCompareExchange64
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s b/edk2/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s
new file mode 100644
index 0000000..7fa68e1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/PalCallStatic.s
@@ -0,0 +1,47 @@
+/// @file

+///   Contains an implementation of CallPalProcStatic on Itanium-based

+///   architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  PalCallStatic.s

+///

+///

+

+.auto

+.text

+

+.proc   PalCallStatic

+.type   PalCallStatic, @function

+.regstk 5, 0, 0, 0

+PalCallStatic::

+        cmp.ne              p6, p7 = r0, in0

+        mov                 r31 = in4

+        mov                 r8  = ip

+(p6)    mov                 in0 = ar.k5

+        add                 r8  = (PalProcReturn - PalCallStatic), r8

+        mov                 in4 = b0

+        mov                 r30 = in3

+        mov                 r29 = in2

+        mov                 b7  = in0

+        mov                 in3 = psr

+        rsm                 1 << 14                 // Disable interrupts

+        mov                 r28 = in1

+        mov                 in0 = 256

+        mov                 b0  = r8

+        br.cond.sptk        b7

+PalProcReturn:

+        mov                 psr.l = in3

+        cmp.eq              p6, p7 = in0, in1       // in1 == PAL_COPY_PAL?

+(p6)    cmp.eq              p6, p7 = r0, r8         // Status == Success?

+(p6)    mov                 ar.k5 = in2

+        mov                 b0  = in4

+        br.ret.sptk.many    b0

+.endp   PalCallStatic

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/SwitchStack.s b/edk2/MdePkg/Library/BaseLib/Ipf/SwitchStack.s
new file mode 100644
index 0000000..58fe43d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/SwitchStack.s
@@ -0,0 +1,122 @@
+//++

+// Copyright (c) 2006, Intel Corporation                                                         

+// All rights reserved. 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.             

+// 

+// Module Name:

+//

+//  SwitchStack.s

+//

+// Abstract:

+//

+//  Contains an implementation of a stack switch for the Itanium-based architecture.

+//

+//

+//

+// Revision History:

+//

+//--

+

+  .file  "SwitchStack.s"

+

+#include  "asm.h"

+#include  "ia_64gen.h"

+

+// Define hardware RSE Configuration Register

+//

+// RS Configuration (RSC) bit field positions

+

+#define RSC_MODE       0

+#define RSC_PL         2

+#define RSC_BE         4

+// RSC bits 5-15 reserved

+#define RSC_MBZ0       5

+#define RSC_MBZ0_V     0x3ff

+#define RSC_LOADRS     16

+#define RSC_LOADRS_LEN 14

+// RSC bits 30-63 reserved

+#define RSC_MBZ1       30

+#define RSC_MBZ1_V     0x3ffffffffULL

+

+// RSC modes

+// Lazy

+#define RSC_MODE_LY (0x0)

+// Store intensive

+#define RSC_MODE_SI (0x1)

+// Load intensive

+#define RSC_MODE_LI (0x2)

+// Eager

+#define RSC_MODE_EA (0x3)

+

+// RSC Endian bit values

+#define RSC_BE_LITTLE 0

+#define RSC_BE_BIG    1

+

+// RSC while in kernel: enabled, little endian, pl = 0, eager mode

+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))

+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode

+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))

+// RSE disabled: disabled, pl = 0, little endian, eager mode

+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))

+

+

+//VOID

+//InternalSwitchStack (

+//    VOID    *ContinuationFunction,

+//    UINTN   Parameter,

+//    UINTN   NewTopOfStack,

+//    UINTN   NewBSPStore OPTIONAL

+//)

+///*++

+//

+//Input Arguments

+//

+//  ContinuationFunction - This is a pointer to the PLABEL of the function that should  be called once the

+//        new stack has been created.  

+//  Parameter - The parameter to pass to the continuation function

+//  NewTopOfStack - This is the new top of the memory stack for ensuing code.  This is mandatory and

+//      should be non-zero

+//  NewBSPStore - This is the new BSP store for the ensuing code.  It is optional on IA-32 and mandatory on Itanium-based platform.

+//

+//--*/

+

+PROCEDURE_ENTRY(InternalSwitchStack)

+

+        mov        r16 = -0x10;;

+        and        r16 = r34, r16;;             // get new stack value in R16, 0 the last nibble.

+        mov        r15 = r35;;                  // Get new BspStore into R15

+        mov        r13 = r32;;                  // this is a pointer to the PLABEL of the continuation function.  

+        mov        r17 = r33;;                  // this is the parameter to pass to the continuation function

+

+        alloc       r11=0,0,0,0                 // Set 0-size frame

+        ;;

+        flushrs;;

+

+        mov         r21 = RSC_KERNEL_DISABLED   // for rse disable             

+        ;;

+        mov         ar.rsc = r21                // turn off RSE                

+

+        add         sp = r0, r16;;              // transfer to the EFI stack

+        mov         ar.bspstore = r15           // switch to EFI BSP        

+        invala                                  // change of ar.bspstore needs invala.     

+      

+        mov         r18 = RSC_KERNEL_LAZ        // RSC enabled, Lazy mode

+        ;;

+        mov         ar.rsc = r18                // turn rse on, in kernel mode     

+        ;;        

+        alloc       r11=0,0,1,0;;               // alloc 0 outs going to ensuing DXE IPL service

+        mov         out0 = r17

+        ld8         r16 = [r13],8;;             // r16 = address of continuation function from the PLABEL

+        ld8         gp = [r13]                  // gp  = gp of continuation function from the PLABEL

+        mov         b6 = r16

+        ;;

+        br.call.sptk.few b0=b6;;                // Call the continuation function

+        ;;

+PROCEDURE_EXIT(InternalSwitchStack)

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/Synchronization.c b/edk2/MdePkg/Library/BaseLib/Ipf/Synchronization.c
new file mode 100644
index 0000000..9eb8799
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/Synchronization.c
@@ -0,0 +1,59 @@
+/** @file

+  Implementation of synchronization functions on Itanium.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  Synchronization.c

+

+**/

+

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  );

+

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  UINT32                            OriginalValue;

+

+  do {

+    OriginalValue = *Value;

+  } while (OriginalValue == InternalSyncCompareExchange32 (

+                              Value,

+                              OriginalValue,

+                              OriginalValue + 1

+                              ));

+  return OriginalValue + 1;

+}

+

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  UINT32                            OriginalValue;

+

+  do {

+    OriginalValue = *Value;

+  } while (OriginalValue == InternalSyncCompareExchange32 (

+                              Value,

+                              OriginalValue,

+                              OriginalValue - 1

+                              ));

+  return OriginalValue - 1;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/Unaligned.c b/edk2/MdePkg/Library/BaseLib/Ipf/Unaligned.c
new file mode 100644
index 0000000..30e5b15
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/Unaligned.c
@@ -0,0 +1,237 @@
+/** @file

+  Unaligned access functions of BaseLib for IPF.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  Unaligned.c

+

+**/

+

+/**

+  Reads a 16-bit value from memory that may be unaligned.

+

+  This function returns the 16-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 16-bit value that may be unaligned.

+

+  @return *Uint16

+

+**/

+UINT16

+EFIAPI

+ReadUnaligned16 (

+  IN      CONST UINT16              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT16)(((UINT8*)Buffer)[0] | (((UINT8*)Buffer)[1] << 8));

+}

+

+/**

+  Writes a 16-bit value to memory that may be unaligned.

+

+  This function writes the 16-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 16-bit value that may be unaligned.

+  @param  Value   16-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT16

+EFIAPI

+WriteUnaligned16 (

+  OUT     UINT16                    *Buffer,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  ((UINT8*)Buffer)[0] = (UINT8)Value;

+  ((UINT8*)Buffer)[1] = (UINT8)(Value >> 8);

+

+  return Value;

+}

+

+/**

+  Reads a 24-bit value from memory that may be unaligned.

+

+  This function returns the 24-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 24-bit value that may be unaligned.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+ReadUnaligned24 (

+  IN      CONST UINT32              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT32)(

+            ReadUnaligned16 ((UINT16*)Buffer) |

+            (((UINT8*)Buffer)[2] << 16)

+            );

+}

+

+/**

+  Writes a 24-bit value to memory that may be unaligned.

+

+  This function writes the 24-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 24-bit value that may be unaligned.

+  @param  Value   24-bit value to write to Buffer.

+

+  @return The value written.

+

+**/

+UINT32

+EFIAPI

+WriteUnaligned24 (

+  OUT     UINT32                    *Buffer,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);

+  *(UINT8*)((UINT16*)Buffer + 1) = (UINT8)(Value >> 16);

+  return Value;

+}

+

+/**

+  Reads a 32-bit value from memory that may be unaligned.

+

+  This function returns the 32-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 32-bit value that may be unaligned.

+

+  @return *Uint32

+

+**/

+UINT32

+EFIAPI

+ReadUnaligned32 (

+  IN      CONST UINT32              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT32)(

+           ReadUnaligned16 ((UINT16*)Buffer) |

+           (ReadUnaligned16 ((UINT16*)Buffer + 1) << 16)

+           );

+}

+

+/**

+  Writes a 32-bit value to memory that may be unaligned.

+

+  This function writes the 32-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 32-bit value that may be unaligned.

+  @param  Value   32-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT32

+EFIAPI

+WriteUnaligned32 (

+  OUT     UINT32                    *Buffer,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);

+  WriteUnaligned16 ((UINT16*)Buffer + 1, (UINT16)(Value >> 16));

+  return Value;

+}

+

+/**

+  Reads a 64-bit value from memory that may be unaligned.

+

+  This function returns the 64-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 64-bit value that may be unaligned.

+

+  @return *Uint64

+

+**/

+UINT64

+EFIAPI

+ReadUnaligned64 (

+  IN      CONST UINT64              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT64)(

+           ReadUnaligned32 ((UINT32*)Buffer) |

+           LShiftU64 (ReadUnaligned32 ((UINT32*)Buffer + 1), 32)

+           );

+}

+

+/**

+  Writes a 64-bit value to memory that may be unaligned.

+

+  This function writes the 64-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 64-bit value that may be unaligned.

+  @param  Value   64-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT64

+EFIAPI

+WriteUnaligned64 (

+  OUT     UINT64                    *Buffer,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned32 ((UINT32*)Buffer, (UINT32)Value);

+  WriteUnaligned32 ((UINT32*)Buffer + 1, (UINT32)RShiftU64 (Value, 32));

+  return Value;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/asm.h b/edk2/MdePkg/Library/BaseLib/Ipf/asm.h
new file mode 100644
index 0000000..8ef0b30
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/asm.h
@@ -0,0 +1,27 @@
+/// @file

+///   This module contains generic macros for an assembly writer.

+///

+/// Copyright (c) 2006, Intel Corporation<BR>

+/// All rights reserved. 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.

+///

+/// Module Name: asm.h

+///

+#ifndef _ASM_H

+#define _ASM_H

+

+#define TRUE  1

+#define FALSE 0

+#define PROCEDURE_ENTRY(name)   .##text;            \

+  .##type name, @function; \

+  .##proc name; \

+  name::

+

+#define PROCEDURE_EXIT(name)  .##endp name

+

+#endif // _ASM_H

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/ia_64gen.h b/edk2/MdePkg/Library/BaseLib/Ipf/ia_64gen.h
new file mode 100644
index 0000000..081cc4a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/ia_64gen.h
@@ -0,0 +1,205 @@
+/// @file

+/// 

+/// 

+/// Copyright (c) 2006, Intel Corporation<BR>

+/// All rights reserved. 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.             

+/// 

+/// Module Name: ia_64gen.h

+///

+#ifndef _IA64GEN_H

+#define _IA64GEN_H

+

+#define TT_UNAT           0

+#define C_PSR             0

+#define J_UNAT            0

+#define T_TYPE            0

+#define T_IPSR            0x8

+#define T_ISR             0x10

+#define T_IIP             0x18

+#define T_IFA             0x20

+#define T_IIPA            0x28

+#define T_IFS             0x30

+#define T_IIM             0x38

+#define T_RSC             0x40

+#define T_BSP             0x48

+#define T_BSPSTORE        0x50

+#define T_RNAT            0x58

+#define T_PFS             0x60

+#define T_KBSPSTORE       0x68

+#define T_UNAT            0x70

+#define T_CCV             0x78

+#define T_DCR             0x80

+#define T_PREDS           0x88

+#define T_NATS            0x90

+#define T_R1              0x98

+#define T_GP              0x98

+#define T_R2              0xa0

+#define T_R3              0xa8

+#define T_R4              0xb0

+#define T_R5              0xb8

+#define T_R6              0xc0

+#define T_R7              0xc8

+#define T_R8              0xd0

+#define T_R9              0xd8

+#define T_R10             0xe0

+#define T_R11             0xe8

+#define T_R12             0xf0

+#define T_SP              0xf0

+#define T_R13             0xf8

+#define T_R14             0x100

+#define T_R15             0x108

+#define T_R16             0x110

+#define T_R17             0x118

+#define T_R18             0x120

+#define T_R19             0x128

+#define T_R20             0x130

+#define T_R21             0x138

+#define T_R22             0x140

+#define T_R23             0x148

+#define T_R24             0x150

+#define T_R25             0x158

+#define T_R26             0x160

+#define T_R27             0x168

+#define T_R28             0x170

+#define T_R29             0x178

+#define T_R30             0x180

+#define T_R31             0x188

+#define T_F2              0x1f0

+#define T_F3              0x200

+#define T_F4              0x210

+#define T_F5              0x220

+#define T_F6              0x230

+#define T_F7              0x240

+#define T_F8              0x250

+#define T_F9              0x260

+#define T_F10             0x270

+#define T_F11             0x280

+#define T_F12             0x290

+#define T_F13             0x2a0

+#define T_F14             0x2b0

+#define T_F15             0x2c0

+#define T_F16             0x2d0

+#define T_F17             0x2e0

+#define T_F18             0x2f0

+#define T_F19             0x300

+#define T_F20             0x310

+#define T_F21             0x320

+#define T_F22             0x330

+#define T_F23             0x340

+#define T_F24             0x350

+#define T_F25             0x360

+#define T_F26             0x370

+#define T_F27             0x380

+#define T_F28             0x390

+#define T_F29             0x3a0

+#define T_F30             0x3b0

+#define T_F31             0x3c0

+#define T_FPSR            0x1e0

+#define T_B0              0x190

+#define T_B1              0x198

+#define T_B2              0x1a0

+#define T_B3              0x1a8

+#define T_B4              0x1b0

+#define T_B5              0x1b8

+#define T_B6              0x1c0

+#define T_B7              0x1c8

+#define T_EC              0x1d0

+#define T_LC              0x1d8

+#define J_NATS            0x8

+#define J_PFS             0x10

+#define J_BSP             0x18

+#define J_RNAT            0x20

+#define J_PREDS           0x28

+#define J_LC              0x30

+#define J_R4              0x38

+#define J_R5              0x40

+#define J_R6              0x48

+#define J_R7              0x50

+#define J_SP              0x58

+#define J_F2              0x60

+#define J_F3              0x70

+#define J_F4              0x80

+#define J_F5              0x90

+#define J_F16             0xa0

+#define J_F17             0xb0

+#define J_F18             0xc0

+#define J_F19             0xd0

+#define J_F20             0xe0

+#define J_F21             0xf0

+#define J_F22             0x100

+#define J_F23             0x110

+#define J_F24             0x120

+#define J_F25             0x130

+#define J_F26             0x140

+#define J_F27             0x150

+#define J_F28             0x160

+#define J_F29             0x170

+#define J_F30             0x180

+#define J_F31             0x190

+#define J_FPSR            0x1a0

+#define J_B0              0x1a8

+#define J_B1              0x1b0

+#define J_B2              0x1b8

+#define J_B3              0x1c0

+#define J_B4              0x1c8

+#define J_B5              0x1d0

+#define TRAP_FRAME_LENGTH 0x3d0

+#define C_UNAT            0x28

+#define C_NATS            0x30

+#define C_PFS             0x8

+#define C_BSPSTORE        0x10

+#define C_RNAT            0x18

+#define C_RSC             0x20

+#define C_PREDS           0x38

+#define C_LC              0x40

+#define C_DCR             0x48

+#define C_R1              0x50

+#define C_GP              0x50

+#define C_R4              0x58

+#define C_R5              0x60

+#define C_R6              0x68

+#define C_R7              0x70

+#define C_SP              0x78

+#define C_R13             0x80

+#define C_F2              0x90

+#define C_F3              0xa0

+#define C_F4              0xb0

+#define C_F5              0xc0

+#define C_F16             0xd0

+#define C_F17             0xe0

+#define C_F18             0xf0

+#define C_F19             0x100

+#define C_F20             0x110

+#define C_F21             0x120

+#define C_F22             0x130

+#define C_F23             0x140

+#define C_F24             0x150

+#define C_F25             0x160

+#define C_F26             0x170

+#define C_F27             0x180

+#define C_F28             0x190

+#define C_F29             0x1a0

+#define C_F30             0x1b0

+#define C_F31             0x1c0

+#define C_FPSR            0x1d0

+#define C_B0              0x1d8

+#define C_B1              0x1e0

+#define C_B2              0x1e8

+#define C_B3              0x1f0

+#define C_B4              0x1f8

+#define C_B5              0x200

+#define TT_R2             0x8

+#define TT_R3             0x10

+#define TT_R8             0x18

+#define TT_R9             0x20

+#define TT_R10            0x28

+#define TT_R11            0x30

+#define TT_R14            0x38

+

+#endif _IA64GEN_H

diff --git a/edk2/MdePkg/Library/BaseLib/Ipf/setjmp.s b/edk2/MdePkg/Library/BaseLib/Ipf/setjmp.s
new file mode 100644
index 0000000..1098be8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Ipf/setjmp.s
@@ -0,0 +1,317 @@
+/// @file

+///  Contains an implementation of setjmp and longjmp for the

+///  Itanium-based architecture.

+///

+/// Copyright (c) 2006, Intel Corporation                                                         

+/// All rights reserved. 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.             

+/// 

+/// Module Name: setjmp.s

+///

+///

+

+  .file  "setjmp.s"

+

+#include  "asm.h"

+#include  "ia_64gen.h"

+

+/// int SetJump(struct jmp_buffer save)

+///

+///  Setup a non-local goto.

+///

+/// Description:

+///

+///  SetJump stores the current register set in the area pointed to

+///  by "save".  It returns zero.  Subsequent calls to "LongJump" will

+///  restore the registers and return non-zero to the same location.

+///

+/// On entry, r32 contains the pointer to the jmp_buffer

+///

+

+PROCEDURE_ENTRY(SetJump)

+  //

+  //  Make sure buffer is aligned at 16byte boundary

+  //

+  mov    r32 = r33        

+

+    add     r10 = -0x10,r0  ;;  // mask the lower 4 bits

+    and     r32 = r32, r10;; 

+    add     r32 = 0x10, r32;;   // move to next 16 byte boundary

+

+    add    r10 = J_PREDS, r32  // skip Unats & pfs save area

+  add    r11 = J_BSP, r32

+  //

+  //  save immediate context

+  //

+  mov    r2 = ar.bsp     // save backing store pointer

+  mov    r3 = pr         // save predicates

+  ;;

+  //

+  // save user Unat register

+  //

+  mov    r16 = ar.lc        // save loop count register

+  mov    r14 = ar.unat     // save user Unat register

+

+  st8    [r10] = r3, J_LC-J_PREDS

+  st8    [r11] = r2, J_R4-J_BSP

+  ;;

+  st8    [r10] = r16, J_R5-J_LC

+  st8    [r32] = r14, J_NATS  // Note: Unat at the 

+                    // beginning of the save area

+  mov    r15 = ar.pfs

+  ;;

+  //

+  //  save preserved general registers & NaT's

+  //

+  st8.spill  [r11] = r4, J_R6-J_R4

+  ;;

+  st8.spill  [r10] = r5, J_R7-J_R5 

+    ;;

+  st8.spill  [r11] = r6, J_SP-J_R6

+  ;;

+  st8.spill  [r10] = r7, J_F3-J_R7 

+    ;;

+  st8.spill  [r11] = sp, J_F2-J_SP

+  ;;

+  //

+  // save spilled Unat and pfs registers

+  //

+  mov    r2 = ar.unat       // save Unat register after spill

+  ;;

+  st8    [r32] = r2, J_PFS-J_NATS  // save unat for spilled regs

+  ;;

+  st8    [r32] = r15          // save pfs

+  //

+  //  save floating registers 

+  //

+  stf.spill  [r11] = f2, J_F4-J_F2

+  stf.spill  [r10] = f3, J_F5-J_F3 

+  ;;

+  stf.spill  [r11] = f4, J_F16-J_F4

+  stf.spill  [r10] = f5, J_F17-J_F5 

+  ;;

+  stf.spill  [r11] = f16, J_F18-J_F16

+  stf.spill  [r10] = f17, J_F19-J_F17 

+  ;;

+  stf.spill  [r11] = f18, J_F20-J_F18

+  stf.spill  [r10] = f19, J_F21-J_F19 

+  ;;

+  stf.spill  [r11] = f20, J_F22-J_F20

+  stf.spill  [r10] = f21, J_F23-J_F21 

+  ;;

+  stf.spill  [r11] = f22, J_F24-J_F22

+  stf.spill  [r10] = f23, J_F25-J_F23 

+  ;;

+  stf.spill  [r11] = f24, J_F26-J_F24

+  stf.spill  [r10] = f25, J_F27-J_F25 

+  ;;

+  stf.spill  [r11] = f26, J_F28-J_F26

+  stf.spill  [r10] = f27, J_F29-J_F27 

+  ;;

+  stf.spill  [r11] = f28, J_F30-J_F28

+  stf.spill  [r10] = f29, J_F31-J_F29 

+  ;;

+  stf.spill  [r11] = f30, J_FPSR-J_F30

+  stf.spill  [r10] = f31, J_B0-J_F31    // size of f31 + fpsr

+  //

+  // save FPSR register & branch registers

+  //

+  mov    r2 = ar.fpsr  // save fpsr register

+  mov    r3 = b0 

+  ;;

+  st8    [r11] = r2, J_B1-J_FPSR

+  st8    [r10] = r3, J_B2-J_B0

+  mov    r2 = b1

+  mov    r3 = b2 

+  ;;

+  st8    [r11] = r2, J_B3-J_B1

+  st8    [r10] = r3, J_B4-J_B2

+  mov    r2 = b3

+  mov    r3 = b4 

+  ;;

+  st8    [r11] = r2, J_B5-J_B3

+  st8    [r10] = r3

+  mov    r2 = b5 

+  ;;

+  st8    [r11] = r2

+  ;;

+  //

+  // return

+  //

+  mov    r8 = r0        // return 0 from setjmp

+  mov    ar.unat = r14  // restore unat

+  br.ret.sptk  b0

+

+PROCEDURE_EXIT(SetJump)

+

+

+//

+// void _LongJump(struct jmp_buffer *)

+//

+//  Perform a non-local goto.

+//

+// Description:

+//

+//  LongJump initializes the register set to the values saved by a

+//  previous 'SetJump' and jumps to the return location saved by that

+//  'SetJump'.  This has the effect of unwinding the stack and returning

+//  for a second time to the 'SetJump'.

+//

+

+PROCEDURE_ENTRY(_LongJump)

+  //

+  //  Make sure buffer is aligned at 16byte boundary

+  //

+  mov    r32 = r33        

+

+    add     r10 = -0x10,r0  ;;  // mask the lower 4 bits

+    and     r32 = r32, r10;; 

+    add     r32 = 0x10, r32;;   // move to next 16 byte boundary

+

+  //

+  // caching the return value as we do invala in the end

+  //

+///  mov    r8 = r33          // return value

+  mov    r8 = 1              // For now return hard coded 1

+

+  //

+  //  get immediate context

+  //

+  mov    r14 = ar.rsc    // get user RSC conf 

+  add    r10 = J_PFS, r32  // get address of pfs

+  add    r11 = J_NATS, r32

+  ;;

+  ld8    r15 = [r10], J_BSP-J_PFS  // get pfs

+  ld8    r2 = [r11], J_LC-J_NATS      // get unat for spilled regs

+  ;;

+  mov    ar.unat = r2

+  ;;

+  ld8    r16 = [r10], J_PREDS-J_BSP  // get backing store pointer

+  mov    ar.rsc = r0        // put RSE in enforced lazy 

+  mov    ar.pfs = r15

+  ;;

+  

+  //

+  // while returning from longjmp the BSPSTORE and BSP needs to be

+  // same and discard all the registers allocated after we did

+  // setjmp. Also, we need to generate the RNAT register since we

+  // did not flushed the RSE on setjmp.

+  //

+  mov    r17 = ar.bspstore  // get current BSPSTORE

+  ;;

+    cmp.ltu  p6,p7 = r17, r16  // is it less than BSP of 

+(p6)  br.spnt.few  .flush_rse

+  mov    r19 = ar.rnat    // get current RNAT

+  ;;

+  loadrs              // invalidate dirty regs

+  br.sptk.many  .restore_rnat    // restore RNAT

+

+.flush_rse:

+  flushrs

+  ;;

+  mov    r19 = ar.rnat    // get current RNAT

+  mov    r17 = r16      // current BSPSTORE

+  ;;

+.restore_rnat:

+  //

+  // check if RNAT is saved between saved BSP and curr BSPSTORE

+  //

+  dep    r18 = 1,r16,3,6   // get RNAT address

+  ;;

+  cmp.ltu  p8,p9 = r18, r17  // RNAT saved on RSE

+  ;;

+(p8)  ld8    r19 = [r18]    // get RNAT from RSE

+  ;;

+  mov    ar.bspstore = r16  // set new BSPSTORE  

+  ;;

+  mov    ar.rnat = r19    // restore RNAT

+  mov    ar.rsc = r14    // restore RSC conf

+

+

+  ld8    r3 = [r11], J_R4-J_LC    // get lc register

+  ld8    r2 = [r10], J_R5-J_PREDS   // get predicates

+  ;;

+  mov    pr = r2, -1

+  mov    ar.lc = r3

+  //

+  //  restore preserved general registers & NaT's

+  //

+  ld8.fill  r4 = [r11], J_R6-J_R4

+  ;;

+  ld8.fill  r5 = [r10], J_R7-J_R5 

+  ld8.fill  r6 = [r11], J_SP-J_R6

+  ;;

+  ld8.fill  r7 = [r10], J_F2-J_R7

+  ld8.fill  sp = [r11], J_F3-J_SP

+  ;;

+  //

+  //  restore floating registers 

+  //

+  ldf.fill  f2 = [r10], J_F4-J_F2

+  ldf.fill  f3 = [r11], J_F5-J_F3 

+  ;;

+  ldf.fill  f4 = [r10], J_F16-J_F4

+  ldf.fill  f5 = [r11], J_F17-J_F5 

+  ;;

+  ldf.fill  f16 = [r10], J_F18-J_F16

+  ldf.fill  f17 = [r11], J_F19-J_F17

+  ;;

+  ldf.fill  f18 = [r10], J_F20-J_F18

+  ldf.fill  f19 = [r11], J_F21-J_F19

+  ;;

+  ldf.fill  f20 = [r10], J_F22-J_F20

+  ldf.fill  f21 = [r11], J_F23-J_F21

+  ;;

+  ldf.fill  f22 = [r10], J_F24-J_F22

+  ldf.fill  f23 = [r11], J_F25-J_F23 

+  ;;

+  ldf.fill  f24 = [r10], J_F26-J_F24

+  ldf.fill  f25 = [r11], J_F27-J_F25

+  ;;

+  ldf.fill  f26 = [r10], J_F28-J_F26

+  ldf.fill  f27 = [r11], J_F29-J_F27

+  ;;

+  ldf.fill  f28 = [r10], J_F30-J_F28

+  ldf.fill  f29 = [r11], J_F31-J_F29 

+  ;;

+  ldf.fill  f30 = [r10], J_FPSR-J_F30

+  ldf.fill  f31 = [r11], J_B0-J_F31 ;;

+

+    //

+  // restore branch registers and fpsr

+  //

+  ld8    r16 = [r10], J_B1-J_FPSR  // get fpsr

+  ld8    r17 = [r11], J_B2-J_B0    // get return pointer

+  ;;

+  mov    ar.fpsr = r16

+  mov    b0 = r17

+  ld8    r2 = [r10], J_B3-J_B1

+  ld8    r3 = [r11], J_B4-J_B2

+  ;;

+  mov    b1 = r2

+  mov    b2 = r3

+  ld8    r2 = [r10], J_B5-J_B3

+  ld8    r3 = [r11]

+  ;;

+  mov    b3 = r2

+  mov    b4 = r3 

+  ld8    r2 = [r10]

+  ld8    r21 = [r32]      // get user unat

+  ;;

+  mov    b5 = r2

+  mov    ar.unat = r21

+

+  //

+  // invalidate ALAT

+  //

+  invala ;;

+

+  br.ret.sptk  b0

+PROCEDURE_EXIT(_LongJump)

+

+

diff --git a/edk2/MdePkg/Library/BaseLib/LRotU32.c b/edk2/MdePkg/Library/BaseLib/LRotU32.c
new file mode 100644
index 0000000..ea78246
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LRotU32.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Rotates a 32-bit integer left between 0 and 31 bits, filling the low bits

+  with the high bits that were rotated.

+

+  This function rotates the 32-bit value Operand to the left by Count bits. The

+  low Count bits are fill with the high Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 31, then ASSERT().

+

+  @param  Operand The 32-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count

+

+**/

+UINT32

+EFIAPI

+LRotU32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return (Operand << Count) | (Operand >> (32 - Count));

+}

diff --git a/edk2/MdePkg/Library/BaseLib/LRotU64.c b/edk2/MdePkg/Library/BaseLib/LRotU64.c
new file mode 100644
index 0000000..cf751f9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LRotU64.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Rotates a 64-bit integer left between 0 and 63 bits, filling the low bits

+  with the high bits that were rotated.

+

+  This function rotates the 64-bit value Operand to the left by Count bits. The

+  low Count bits are fill with the high Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count

+

+**/

+UINT64

+EFIAPI

+LRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return InternalMathLRotU64 (Operand, Count);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/LShiftU64.c b/edk2/MdePkg/Library/BaseLib/LShiftU64.c
new file mode 100644
index 0000000..50449eb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LShiftU64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled

+  with zeros. The shifted value is returned.

+

+  This function shifts the 64-bit value Operand to the left by Count bits. The

+  low Count bits are set to zero. The shifted value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to shift left.

+  @param  Count   The number of bits to shift left.

+

+  @return Operand << Count

+

+**/

+UINT64

+EFIAPI

+LShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return InternalMathLShiftU64 (Operand, Count);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/LinkedList.c b/edk2/MdePkg/Library/BaseLib/LinkedList.c
new file mode 100644
index 0000000..9ad1b08
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LinkedList.c
@@ -0,0 +1,438 @@
+/** @file

+  Linked List Library Functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  LinkedList.c

+

+**/

+

+BOOLEAN

+EFIAPI

+IsNodeInList (

+  IN      CONST LIST_ENTRY      *List,

+  IN      CONST LIST_ENTRY      *Node

+  )

+{

+  UINTN                         Count;

+  CONST LIST_ENTRY              *Ptr;

+  BOOLEAN                       Found;

+

+  //

+  // Test the validity of List and Node

+  //

+  ASSERT (List != NULL);

+  ASSERT (List->ForwardLink != NULL);

+  ASSERT (List->BackLink != NULL);

+  ASSERT (Node != NULL);

+

+  Count = FixedPcdGet32 (PcdMaximumLinkedListLength);

+  if (Count != 0) {

+    Count++;

+  }

+

+  Ptr = List;

+  do {

+    Ptr = Ptr->ForwardLink;

+    Count--;

+  } while ((Ptr != List) && (Ptr != Node) && (Count > 0));

+  Found = (BOOLEAN)(Ptr == Node);

+

+  if (FixedPcdGet32 (PcdMaximumLinkedListLength) > 0) {

+    while ((Count > 0) && (Ptr != List)) {

+      Ptr = Ptr->ForwardLink;

+      Count--;

+    }

+    ASSERT (Count > 0);

+  }

+

+  return Found;

+}

+

+/**

+  Initializes the head node of a doubly linked list, and returns the pointer to

+  the head node of the doubly linked list.

+

+  Initializes the forward and backward links of a new linked list. After

+  initializing a linked list with this function, the other linked list

+  functions may be used to add and remove nodes from the linked list. It is up

+  to the caller of this function to allocate the memory for ListHead.

+

+  If ListHead is NULL, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a new doubly linked list.

+

+  @return ListHead

+

+**/

+LIST_ENTRY *

+EFIAPI

+InitializeListHead (

+  IN OUT  LIST_ENTRY            *List

+  )

+

+{

+  ASSERT (List != NULL);

+

+  List->ForwardLink = List;

+  List->BackLink = List;

+  return List;

+}

+

+/**

+  Adds a node to the beginning of a doubly linked list, and returns the pointer

+  to the head node of the doubly linked list.

+

+  Adds the node Entry at the beginning of the doubly linked list denoted by

+  ListHead, and returns ListHead.

+

+  If ListHead is NULL, then ASSERT().

+  If Entry is NULL, then ASSERT().

+  If ListHead was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and ListHead contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a doubly linked list.

+  @param  Entry     A pointer to a node that is to be inserted at the beginning

+                    of a doubly linked list.

+

+  @return ListHead

+

+**/

+LIST_ENTRY *

+EFIAPI

+InsertHeadList (

+  IN OUT  LIST_ENTRY            *List,

+  IN OUT  LIST_ENTRY            *Entry

+  )

+{

+  //

+  // ASSERT List not too long and Entry is not one of the nodes of List

+  //

+  ASSERT (!IsNodeInList (List, Entry));

+

+  Entry->ForwardLink = List->ForwardLink;

+  Entry->BackLink = List;

+  Entry->ForwardLink->BackLink = Entry;

+  List->ForwardLink = Entry;

+  return List;

+}

+

+/**

+  Adds a node to the end of a doubly linked list, and returns the pointer to

+  the head node of the doubly linked list.

+

+  Adds the node Entry to the end of the doubly linked list denoted by ListHead,

+  and returns ListHead.

+

+  If ListHead is NULL, then ASSERT().

+  If Entry is NULL, then ASSERT().

+  If ListHead was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and ListHead contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a doubly linked list.

+  @param  Entry     A pointer to a node that is to be added at the end of the

+                    doubly linked list.

+

+  @return ListHead

+

+**/

+LIST_ENTRY *

+EFIAPI

+InsertTailList (

+  IN OUT  LIST_ENTRY            *List,

+  IN OUT  LIST_ENTRY            *Entry

+  )

+{

+  //

+  // ASSERT List not too long and Entry is not one of the nodes of List

+  //

+  ASSERT (!IsNodeInList (List, Entry));

+

+  Entry->ForwardLink = List;

+  Entry->BackLink = List->BackLink;

+  Entry->BackLink->ForwardLink = Entry;

+  List->BackLink = Entry;

+  return List;

+}

+

+/**

+  Retrieves the first node of a doubly linked list.

+

+  Returns the first node of a doubly linked list. List must have been

+  initialized with InitializeListHead(). If List is empty, then NULL is

+  returned.

+

+  If List is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+

+  @return The first node of a doubly linked list.

+  @retval NULL  The list is empty.

+

+**/

+LIST_ENTRY *

+EFIAPI

+GetFirstNode (

+  IN CONST LIST_ENTRY  *List

+  )

+{

+  //

+  // ASSERT List not too long

+  //

+  ASSERT (IsNodeInList (List, List));

+

+  return List->ForwardLink;

+}

+

+/**

+  Retrieves the next node of a doubly linked list.

+

+  Returns the node of a doubly linked list that follows Node. List must have

+  been initialized with InitializeListHead(). If List is empty, then List is

+  returned.

+

+  If List is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+  If Node is not a node in List, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+  @param  Node  A pointer to a node in the doubly linked list.

+

+  @return Pointer to the next node if one exists. Otherwise a null value which

+          is actually List is returned.

+

+**/

+LIST_ENTRY *

+EFIAPI

+GetNextNode (

+  IN CONST LIST_ENTRY  *List,

+  IN CONST LIST_ENTRY  *Node

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (IsNodeInList (List, Node));

+

+  return Node->ForwardLink;

+}

+

+/**

+  Checks to see if a doubly linked list is empty or not.

+

+  Checks to see if the doubly linked list is empty. If the linked list contains

+  zero nodes, this function returns TRUE. Otherwise, it returns FALSE.

+

+  If ListHead is NULL, then ASSERT().

+  If ListHead was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  ListHead  A pointer to the head node of a doubly linked list.

+

+  @retval TRUE  The linked list is empty.

+  @retval FALSE The linked list is not empty.

+

+**/

+BOOLEAN

+EFIAPI

+IsListEmpty (

+  IN      CONST LIST_ENTRY      *List

+  )

+{

+  //

+  // ASSERT List not too long

+  //

+  ASSERT (IsNodeInList (List, List));

+

+  return (BOOLEAN)(List->ForwardLink == List);

+}

+

+/**

+  Determines if a node in a doubly linked list is null.

+

+  Returns FALSE if Node is one of the nodes in the doubly linked list specified

+  by List. Otherwise, TRUE is returned. List must have been initialized with

+  InitializeListHead().

+

+  If List is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+  If Node is not a node in List and Node is not equal to List, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+  @param  Node	A pointer to a node in the doubly linked list.

+

+  @retval TRUE  Node is one of the nodes in the doubly linked list.

+  @retval FALSE Node is not one of the nodes in the doubly linked list.

+

+**/

+BOOLEAN

+EFIAPI

+IsNull (

+  IN      CONST LIST_ENTRY      *List,

+  IN      CONST LIST_ENTRY      *Node

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (IsNodeInList (List, Node));

+

+  return (BOOLEAN)(Node == List);

+}

+

+/**

+  Determines if a node the last node in a doubly linked list.

+

+  Returns TRUE if Node is the last node in the doubly linked list specified by

+  List. Otherwise, FALSE is returned. List must have been initialized with

+  InitializeListHead().

+

+  If List is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If List was not initialized with InitializeListHead(), then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and List contains more than

+  PcdMaximumLinkedListLenth nodes, then ASSERT().

+  If Node is not a node in List, then ASSERT().

+

+  @param  List  A pointer to the head node of a doubly linked list.

+  @param  Node	A pointer to a node in the doubly linked list.

+

+  @retval TRUE  Node is the last node in the linked list.

+  @retval FALSE Node is not the last node in the linked list.

+

+**/

+BOOLEAN

+EFIAPI

+IsNodeAtEnd (

+  IN      CONST LIST_ENTRY      *List,

+  IN      CONST LIST_ENTRY      *Node

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (IsNodeInList (List, Node));

+

+  return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == Node);

+}

+

+/**

+  Swaps the location of two nodes in a doubly linked list, and returns the

+  first node after the swap.

+

+  If FirstEntry is identical to SecondEntry, then SecondEntry is returned.

+  Otherwise, the location of the FirstEntry node is swapped with the location

+  of the SecondEntry node in a doubly linked list. SecondEntry must be in the

+  same double linked list as FirstEntry and that double linked list must have

+  been initialized with InitializeListHead(). SecondEntry is returned after the

+  nodes are swapped.

+

+  If FirstEntry is NULL, then ASSERT().

+  If SecondEntry is NULL, then ASSERT().

+  If SecondEntry and FirstEntry are not in the same linked list, then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and the linked list containing

+  FirstEntry and SecondEntry contains more than PcdMaximumLinkedListLenth

+  nodes, then ASSERT().

+

+  @param  FirstEntry  A pointer to a node in a linked list.

+  @param  SecondEntry A pointer to another node in the same linked list.

+

+**/

+LIST_ENTRY *

+EFIAPI

+SwapListEntries (

+  IN OUT  LIST_ENTRY            *FirstEntry,

+  IN OUT  LIST_ENTRY            *SecondEntry

+  )

+{

+  LIST_ENTRY                    *Ptr;

+

+  if (FirstEntry == SecondEntry) {

+    return SecondEntry;

+  }

+

+  //

+  // ASSERT Entry1 and Entry2 are in the same linked list

+  //

+  ASSERT (IsNodeInList (FirstEntry, SecondEntry));

+

+  //

+  // Ptr is the node pointed to by FirstEntry->ForwardLink

+  //

+  Ptr = RemoveEntryList (FirstEntry);

+

+  //

+  // If FirstEntry immediately follows SecondEntry, FirstEntry willl be placed

+  // immediately in front of SecondEntry

+  //

+  if (Ptr->BackLink == SecondEntry) {

+    return InsertTailList (SecondEntry, FirstEntry);

+  }

+

+  //

+  // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry,

+  // then there are no further steps necessary

+  //

+  if (Ptr == InsertHeadList (SecondEntry, FirstEntry)) {

+    return Ptr;

+  }

+

+  //

+  // Move SecondEntry to the front of Ptr

+  //

+  RemoveEntryList (SecondEntry);

+  InsertTailList (Ptr, SecondEntry);

+  return SecondEntry;

+}

+

+/**

+  Removes a node from a doubly linked list, and returns the node that follows

+  the removed node.

+

+  Removes the node Entry from a doubly linked list. It is up to the caller of

+  this function to release the memory used by this node if that is required. On

+  exit, the node following Entry in the doubly linked list is returned. If

+  Entry is the only node in the linked list, then the head node of the linked

+  list is returned.

+

+  If Entry is NULL, then ASSERT().

+  If Entry is the head node of an empty list, then ASSERT().

+  If PcdMaximumLinkedListLenth is not zero, and the linked list containing

+  Entry contains more than PcdMaximumLinkedListLenth nodes, then ASSERT().

+

+  @param  Entry A pointer to a node in a linked list

+

+  @return Entry

+

+**/

+LIST_ENTRY *

+EFIAPI

+RemoveEntryList (

+  IN      CONST LIST_ENTRY      *Entry

+  )

+{

+  ASSERT (!IsListEmpty (Entry));

+

+  Entry->ForwardLink->BackLink = Entry->BackLink;

+  Entry->BackLink->ForwardLink = Entry->ForwardLink;

+  return Entry->ForwardLink;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/LongJump.c b/edk2/MdePkg/Library/BaseLib/LongJump.c
new file mode 100644
index 0000000..07b8115
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LongJump.c
@@ -0,0 +1,49 @@
+/** @file

+  Long Jump functions. 

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  LongJump.c

+

+**/

+

+VOID

+EFIAPI

+_LongJump (

+  IN BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                Value

+  );

+

+/**

+  Restores the CPU context that was saved with SetJump().

+

+  Restores the CPU context from the buffer specified by JumpBuffer.

+  This function never returns to the caller.

+  Instead is resumes execution based on the state of JumpBuffer.

+

+  If JumpBuffer is NULL, then ASSERT().

+  If Value is 0, then ASSERT().

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+  @param  Value         The value to return when the SetJump() context is restored.

+

+**/

+VOID

+EFIAPI

+LongJump (

+  IN BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                Value

+  )

+{

+  ASSERT (JumpBuffer != NULL);

+  ASSERT (Value != 0);

+  

+  _LongJump (JumpBuffer, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/LowBitSet32.c b/edk2/MdePkg/Library/BaseLib/LowBitSet32.c
new file mode 100644
index 0000000..5a21245
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LowBitSet32.c
@@ -0,0 +1,44 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Returns the bit position of the lowest bit set in a 32-bit value.

+

+  This function computes the bit position of the lowest bit set in the 32-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 31 is returned.

+

+  @param  Operand The 32-bit operand to evaluate.

+

+  @return Position of the lowest bit set in Operand if found.

+  @retval -1 Operand is zero.

+

+**/

+INTN

+EFIAPI

+LowBitSet32 (

+  IN      UINT32                    Operand

+  )

+{

+  INTN                              BitIndex;

+

+  if (Operand == 0) {

+    return -1;

+  }

+

+  for (BitIndex = 0; (Operand & 1) == 0; BitIndex++, Operand >>= 1);

+  return BitIndex;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/LowBitSet64.c b/edk2/MdePkg/Library/BaseLib/LowBitSet64.c
new file mode 100644
index 0000000..a3e5ba0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/LowBitSet64.c
@@ -0,0 +1,46 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Returns the bit position of the lowest bit set in a 64-bit value.

+

+  This function computes the bit position of the lowest bit set in the 64-bit

+  value specified by Operand. If Operand is zero, then -1 is returned.

+  Otherwise, a value between 0 and 63 is returned.

+

+  @param  Operand The 64-bit operand to evaluate.

+

+  @return Position of the lowest bit set in Operand if found.

+  @retval -1  Operand is zero.

+

+**/

+INTN

+EFIAPI

+LowBitSet64 (

+  IN      UINT64                    Operand

+  )

+{

+  INTN                              BitIndex;

+

+  if (Operand == 0) {

+    return -1;

+  }

+

+  for (BitIndex = 0;

+       (Operand & 1) == 0;

+       BitIndex++, Operand = RShiftU64 (Operand, 1));

+  return BitIndex;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Math64.c b/edk2/MdePkg/Library/BaseLib/Math64.c
new file mode 100644
index 0000000..57dcca3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Math64.c
@@ -0,0 +1,174 @@
+/** @file

+  Leaf math worker functions that require 64-bit arithmetic support from the

+  compiler.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  Math64.c

+

+**/

+

+UINT64

+EFIAPI

+InternalMathLShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return Operand << Count;

+}

+

+UINT64

+EFIAPI

+InternalMathRShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return Operand >> Count;

+}

+

+UINT64

+EFIAPI

+InternalMathARShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  //

+  // Test if this compiler supports arithmetic shift

+  //

+  if ((((-1) << (sizeof (-1) * 8 - 1)) >> (sizeof (-1) * 8 - 1)) == -1) {

+    //

+    // Arithmetic shift is supported

+    //

+    return (UINT64)((INT64)Operand >> Count);

+  }

+

+  //

+  // Arithmetic is not supported

+  //

+  return (Operand >> Count) |

+         ((INTN)Operand < 0 ? ~((UINTN)-1 >> Count) : 0);

+}

+

+UINT64

+EFIAPI

+InternalMathLRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return (Operand << Count) | (Operand >> (64 - Count));

+}

+

+UINT64

+EFIAPI

+InternalMathRRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return (Operand >> Count) | (Operand << (64 - Count));

+}

+

+UINT64

+EFIAPI

+InternalMathSwapBytes64 (

+  IN      UINT64                    Operand

+  )

+{

+  return (UINT64)(

+           ((UINT64)SwapBytes32 ((UINT32)Operand) << 32) |

+           ((UINT64)SwapBytes32 ((UINT32)(Operand >> 32)))

+           );

+}

+

+UINT64

+EFIAPI

+InternalMathMultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  )

+{

+  return Multiplicand * Multiplier;

+}

+

+UINT64

+EFIAPI

+InternalMathMultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    Multiplier

+  )

+{

+  return Multiplicand * Multiplier;

+}

+

+UINT64

+EFIAPI

+InternalMathDivU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  return Dividend / Divisor;

+}

+

+UINT32

+EFIAPI

+InternalMathModU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  return (UINT32)(Dividend % Divisor);

+}

+

+UINT64

+EFIAPI

+InternalMathDivRemU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor,

+  OUT     UINT32                    *Remainder

+  )

+{

+  if (Remainder != NULL) {

+    *Remainder = (UINT32)(Dividend % Divisor);

+  }

+  return Dividend / Divisor;

+}

+

+UINT64

+EFIAPI

+InternalMathDivRemU64x64 (

+  IN      UINT64                    Dividend,

+  IN      UINT64                    Divisor,

+  OUT     UINT64                    *Remainder

+  )

+{

+  if (Remainder != NULL) {

+    *Remainder = Dividend % Divisor;

+  }

+  return Dividend / Divisor;

+}

+

+INT64

+EFIAPI

+InternalMathDivRemS64x64 (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder

+  )

+{

+  if (Remainder != NULL) {

+    *Remainder = Dividend % Divisor;

+  }

+  return Dividend / Divisor;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/ModU64x32.c b/edk2/MdePkg/Library/BaseLib/ModU64x32.c
new file mode 100644
index 0000000..a8737f4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/ModU64x32.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates

+  a 32-bit unsigned remainder.

+

+  This function divides the 64-bit unsigned value Dividend by the 32-bit

+  unsigned value Divisor and generates a 32-bit remainder. This function

+  returns the 32-bit unsigned remainder.

+

+  If Divisor is 0, then ASSERT().

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend % Divisor

+

+**/

+UINT32

+EFIAPI

+ModU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathModU64x32 (Dividend, Divisor);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/MultS64x64.c b/edk2/MdePkg/Library/BaseLib/MultS64x64.c
new file mode 100644
index 0000000..7e8d318
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/MultS64x64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Multiples a 64-bit signed integer by a 64-bit signed integer and generates a

+  64-bit signed result.

+

+  This function multiples the 64-bit signed value Multiplicand by the 64-bit

+  signed value Multiplier and generates a 64-bit signed result. This 64-bit

+  signed result is returned.

+

+  If the result overflows, then ASSERT().

+

+  @param  Multiplicand  A 64-bit signed value.

+  @param  Multiplier    A 64-bit signed value.

+

+  @return Multiplicand * Multiplier

+

+**/

+INT64

+EFIAPI

+MultS64x64 (

+  IN      INT64                     Multiplicand,

+  IN      INT64                     Multiplier

+  )

+{

+  return (INT64)MultU64x64 (Multiplicand, Multiplier);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/MultU64x32.c b/edk2/MdePkg/Library/BaseLib/MultU64x32.c
new file mode 100644
index 0000000..4c30472
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/MultU64x32.c
@@ -0,0 +1,45 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Multiples a 64-bit unsigned integer by a 32-bit unsigned integer and

+  generates a 64-bit unsigned result.

+

+  This function multiples the 64-bit unsigned value Multiplicand by the 32-bit

+  unsigned value Multiplier and generates a 64-bit unsigned result. This 64-

+  bit unsigned result is returned.

+

+  If the result overflows, then ASSERT().

+

+  @param  Multiplicand  A 64-bit unsigned value.

+  @param  Multiplier    A 32-bit unsigned value.

+

+  @return Multiplicand * Multiplier

+

+**/

+UINT64

+EFIAPI

+MultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  )

+{

+  UINT64                            Result;

+

+  Result = InternalMathMultU64x32 (Multiplicand, Multiplier);

+  // TODO: ASSERT (Result not overflow);

+  return Result;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/MultU64x64.c b/edk2/MdePkg/Library/BaseLib/MultU64x64.c
new file mode 100644
index 0000000..6324c3e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/MultU64x64.c
@@ -0,0 +1,45 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Multiples a 64-bit unsigned integer by a 64-bit unsigned integer and

+  generates a 64-bit unsigned result.

+

+  This function multiples the 64-bit unsigned value Multiplicand by the 64-bit

+  unsigned value Multiplier and generates a 64-bit unsigned result. This 64-

+  bit unsigned result is returned.

+

+  If the result overflows, then ASSERT().

+

+  @param  Multiplicand  A 64-bit unsigned value.

+  @param  Multiplier    A 64-bit unsigned value.

+

+  @return Multiplicand * Multiplier

+

+**/

+UINT64

+EFIAPI

+MultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    Multiplier

+  )

+{

+  UINT64                            Result;

+

+  Result = InternalMathMultU64x64 (Multiplicand, Multiplier);

+  // TODO: ASSERT (Result not overflow);

+  return Result;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/RRotU32.c b/edk2/MdePkg/Library/BaseLib/RRotU32.c
new file mode 100644
index 0000000..93dda94
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/RRotU32.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Rotates a 32-bit integer right between 0 and 31 bits, filling the high bits

+  with the low bits that were rotated.

+

+  This function rotates the 32-bit value Operand to the right by Count bits.

+  The high Count bits are fill with the low Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 31, then ASSERT().

+

+  @param  Operand The 32-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count

+

+**/

+UINT32

+EFIAPI

+RRotU32 (

+  IN      UINT32                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return (Operand >> Count) | (Operand << (32 - Count));

+}

diff --git a/edk2/MdePkg/Library/BaseLib/RRotU64.c b/edk2/MdePkg/Library/BaseLib/RRotU64.c
new file mode 100644
index 0000000..d55bbfc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/RRotU64.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Rotates a 64-bit integer right between 0 and 63 bits, filling the high bits

+  with the high low bits that were rotated.

+

+  This function rotates the 64-bit value Operand to the right by Count bits.

+  The high Count bits are fill with the low Count bits of Operand. The rotated

+  value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count

+

+**/

+UINT64

+EFIAPI

+RRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return InternalMathRRotU64 (Operand, Count);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/RShiftU64.c b/edk2/MdePkg/Library/BaseLib/RShiftU64.c
new file mode 100644
index 0000000..f9ae4f6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/RShiftU64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Shifts a 64-bit integer right between 0 and 63 bits. This high bits are

+  filled with zeros. The shifted value is returned.

+

+  This function shifts the 64-bit value Operand to the right by Count bits. The

+  high Count bits are set to zero. The shifted value is returned.

+

+  If Count is greater than 63, then ASSERT().

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand >> Count

+

+**/

+UINT64

+EFIAPI

+RShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  ASSERT (Count < sizeof (Operand) * 8);

+  return InternalMathRShiftU64 (Operand, Count);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/String.c b/edk2/MdePkg/Library/BaseLib/String.c
new file mode 100644
index 0000000..6ef2c3b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/String.c
@@ -0,0 +1,798 @@
+/** @file

+  Unicode string primatives.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  String.c

+

+**/

+

+/**

+  Copies one Null-terminated Unicode string to another Null-terminated Unicode

+  string and returns the new Unicode string.

+

+  This function copies the contents of the Unicode string Source to the Unicode

+  string Destination, and returns Destination. If Source and Destination

+  overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+

+  @return Destiantion

+

+**/

+CHAR16 *

+EFIAPI

+StrCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) > StrLen (Source));

+

+  ReturnValue = Destination;

+  while (*Source) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+  return ReturnValue;

+}

+

+/**

+  Copies one Null-terminated Unicode string with a maximum length to another

+  Null-terminated Unicode string with a maximum length and returns the new

+  Unicode string.

+

+  This function copies the contents of the Unicode string Source to the Unicode

+  string Destination, and returns Destination. At most, Length Unicode

+  characters are copied from Source to Destination. If Length is 0, then

+  Destination is returned unmodified. If Length is greater that the number of

+  Unicode characters in Source, then Destination is padded with Null Unicode

+  characters. If Source and Destination overlap, then the results are

+  undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+  @param  Length      Maximum number of Unicode characters to copy.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrnCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source,

+  IN      UINTN                     Length

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  if (Length == 0) {

+    return Destination;

+  }

+

+  //

+  // Destination cannot be NULL if Length is not zero

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  // Q: Does Source have to be NULL-terminated?

+  //

+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) >= Length);

+

+  ReturnValue = Destination;

+

+  while ((*Source != L'\0') && (Length > 0)) {

+    *(Destination++) = *(Source++);

+    Length--;

+  }

+

+  ZeroMem (Destination, Length * sizeof (*Destination));

+  return ReturnValue;

+}

+

+/**

+  Returns the length of a Null-terminated Unicode string.

+

+  This function returns the number of Unicode characters in the Null-terminated

+  Unicode string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated Unicode string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+StrLen (

+  IN      CONST CHAR16              *String

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (String != NULL);

+

+  for (Length = 0; *String != L'\0'; String++, Length++) {

+    //

+    // If PcdMaximumUnicodeStringLength is not zero,

+    // length should not more than PcdMaximumUnicodeStringLength

+    //

+    if (FixedPcdGet32 (PcdMaximumUnicodeStringLength) != 0) {

+      ASSERT (Length < FixedPcdGet32 (PcdMaximumUnicodeStringLength));

+    }

+  }

+  return Length;

+}

+

+/**

+  Returns the size of a Null-terminated Unicode string in bytes, including the

+  Null terminator.

+

+  This function returns the size, in bytes, of the Null-terminated Unicode

+  string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated Unicode string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+StrSize (

+  IN      CONST CHAR16              *String

+  )

+{

+  return (StrLen (String) + 1) * sizeof (*String);

+}

+

+/**

+  Compares two Null-terminated Unicode strings, and returns the difference

+  between the first mismatched Unicode characters.

+

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. If FirstString is identical to

+  SecondString, then 0 is returned. Otherwise, the value returned is the first

+  mismatched Unicode character in SecondString subtracted from the first

+  mismatched Unicode character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated Unicode string.

+  @param  SecondString  Pointer to a Null-terminated Unicode string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+StrCmp (

+  IN      CONST CHAR16              *FirstString,

+  IN      CONST CHAR16              *SecondString

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength

+  //

+  ASSERT (StrSize (FirstString) != 0);

+  ASSERT (StrSize (SecondString) != 0);

+

+  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {

+    FirstString++;

+    SecondString++;

+  }

+  return *FirstString - *SecondString;

+}

+

+/**

+  Compares two Null-terminated Unicode strings with maximum lengths, and

+  returns the difference between the first mismatched Unicode characters.

+

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. At most, Length Unicode

+  characters will be compared. If Length is 0, then 0 is returned. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched Unicode character in SecondString

+  subtracted from the first mismatched Unicode character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated Unicode string.

+  @param  SecondString  Pointer to a Null-terminated Unicode string.

+  @param  Length        Maximum number of Unicode characters to compare.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+StrnCmp (

+  IN      CONST CHAR16              *FirstString,

+  IN      CONST CHAR16              *SecondString,

+  IN      UINTN                     Length

+  )

+{

+  if (Length == 0) {

+    return 0;

+  }

+

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (FirstString) != 0);

+  ASSERT (StrSize (SecondString) != 0);

+

+  while ((*FirstString != L'\0') &&

+         (*FirstString == *SecondString) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+

+  return *FirstString - *SecondString;

+}

+

+/**

+  Concatenates one Null-terminated Unicode string to another Null-terminated

+  Unicode string, and returns the concatenated Unicode string.

+

+  This function concatenates two Null-terminated Unicode strings. The contents

+  of Null-terminated Unicode string Source are concatenated to the end of

+  Null-terminated Unicode string Destination. The Null-terminated concatenated

+  Unicode String is returned. If Source and Destination overlap, then the

+  results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination

+  and Source results in a Unicode string with more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  )

+{

+  StrCpy (Destination + StrLen (Destination), Source);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (StrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  Concatenates one Null-terminated Unicode string with a maximum length to the

+  end of another Null-terminated Unicode string, and returns the concatenated

+  Unicode string.

+

+  This function concatenates two Null-terminated Unicode strings. The contents

+  of Null-terminated Unicode string Source are concatenated to the end of

+  Null-terminated Unicode string Destination, and Destination is returned. At

+  most, Length Unicode characters are concatenated from Source to the end of

+  Destination, and Destination is always Null-terminated. If Length is 0, then

+  Destination is returned unmodified. If Source and Destination overlap, then

+  the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination

+  and Source results in a Unicode string with more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+  @param  Length      Maximum number of Unicode characters to concatenate from

+                      Source.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrnCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source,

+  IN      UINTN                     Length

+  )

+{

+  StrnCpy (Destination + StrLen (Destination), Source, Length);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (StrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  Copies one Null-terminated ASCII string to another Null-terminated ASCII

+  string and returns the new ASCII string.

+

+  This function copies the contents of the ASCII string Source to the ASCII

+  string Destination, and returns Destination. If Source and Destination

+  overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source

+  )

+{

+  CHAR8                             *ReturnValue;

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));

+

+  ReturnValue = Destination;

+  while (*Source) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+  return ReturnValue;

+}

+

+/**

+  Copies one Null-terminated ASCII string with a maximum length to another

+  Null-terminated ASCII string with a maximum length and returns the new ASCII

+  string.

+

+  This function copies the contents of the ASCII string Source to the ASCII

+  string Destination, and returns Destination. At most, Length ASCII characters

+  are copied from Source to Destination. If Length is 0, then Destination is

+  returned unmodified. If Length is greater that the number of ASCII characters

+  in Source, then Destination is padded with Null ASCII characters. If Source

+  and Destination overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+  @param  Length      Maximum number of ASCII characters to copy.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrnCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source,

+  IN      UINTN                     Length

+  )

+{

+  CHAR8                             *ReturnValue;

+

+  if (Length == 0) {

+    return Destination;

+  }

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) >= Length);

+

+  ReturnValue = Destination;

+

+  while (*Source && Length > 0) {

+    *(Destination++) = *(Source++);

+    Length--;

+  }

+

+  ZeroMem (Destination, Length * sizeof (*Destination));

+  return ReturnValue;

+}

+

+/**

+  Returns the length of a Null-terminated ASCII string.

+

+  This function returns the number of ASCII characters in the Null-terminated

+  ASCII string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and String contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated ASCII string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrLen (

+  IN      CONST CHAR8               *String

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (String != NULL);

+

+  for (Length = 0; *String != '\0'; String++, Length++) {

+    //

+    // If PcdMaximumUnicodeStringLength is not zero,

+    // length should not more than PcdMaximumUnicodeStringLength

+    //

+    if (FixedPcdGet32 (PcdMaximumAsciiStringLength) != 0) {

+      ASSERT (Length < FixedPcdGet32 (PcdMaximumAsciiStringLength));

+    }

+  }

+  return Length;

+}

+

+/**

+  Returns the size of a Null-terminated ASCII string in bytes, including the

+  Null terminator.

+

+  This function returns the size, in bytes, of the Null-terminated ASCII string

+  specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and String contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated ASCII string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrSize (

+  IN      CONST CHAR8               *String

+  )

+{

+  return (AsciiStrLen (String) + 1) * sizeof (*String);

+}

+

+/**

+  Compares two Null-terminated ASCII strings, and returns the difference

+  between the first mismatched ASCII characters.

+

+  This function compares the Null-terminated ASCII string FirstString to the

+  Null-terminated ASCII string SecondString. If FirstString is identical to

+  SecondString, then 0 is returned. Otherwise, the value returned is the first

+  mismatched ASCII character in SecondString subtracted from the first

+  mismatched ASCII character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+AsciiStrCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') && (*FirstString == *SecondString)) {

+    FirstString++;

+    SecondString++;

+  }

+

+  return *FirstString - *SecondString;

+}

+

+STATIC

+CHAR8

+EFIAPI

+AsciiToUpper (

+  IN      CHAR8                     Chr

+  )

+{

+  return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr;

+}

+

+/**

+  Performs a case insensitive comparison of two Null-terminated ASCII strings,

+  and returns the difference between the first mismatched ASCII characters.

+

+  This function performs a case insensitive comparison of the Null-terminated

+  ASCII string FirstString to the Null-terminated ASCII string SecondString. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched lower case ASCII character in

+  SecondString subtracted from the first mismatched lower case ASCII character

+  in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString using case insensitive

+              comparisons.

+  @retval !=0 FirstString is not identical to SecondString using case

+              insensitive comparisons.

+

+**/

+INTN

+EFIAPI

+AsciiStriCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') &&

+         (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) {

+    FirstString++;

+    SecondString++;

+  }

+

+  return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);

+}

+

+/**

+  Compares two Null-terminated ASCII strings with maximum lengths, and returns

+  the difference between the first mismatched ASCII characters.

+

+  This function compares the Null-terminated ASCII string FirstString to the

+  Null-terminated ASCII  string SecondString. At most, Length ASCII characters

+  will be compared. If Length is 0, then 0 is returned. If FirstString is

+  identical to SecondString, then 0 is returned. Otherwise, the value returned

+  is the first mismatched ASCII character in SecondString subtracted from the

+  first mismatched ASCII character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+AsciiStrnCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') &&

+         (*FirstString == *SecondString) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+  return *FirstString - *SecondString;

+}

+

+/**

+  Concatenates one Null-terminated ASCII string to another Null-terminated

+  ASCII string, and returns the concatenated ASCII string.

+

+  This function concatenates two Null-terminated ASCII strings. The contents of

+  Null-terminated ASCII string Source are concatenated to the end of Null-

+  terminated ASCII string Destination. The Null-terminated concatenated ASCII

+  String is returned.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Destination contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and concatenating Destination and

+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength

+  ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCat (

+  IN OUT CHAR8    *Destination,

+  IN CONST CHAR8  *Source

+  )

+{

+  AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (AsciiStrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  Concatenates one Null-terminated ASCII string with a maximum length to the

+  end of another Null-terminated ASCII string, and returns the concatenated

+  ASCII string.

+

+  This function concatenates two Null-terminated ASCII strings. The contents

+  of Null-terminated ASCII string Source are concatenated to the end of Null-

+  terminated ASCII string Destination, and Destination is returned. At most,

+  Length ASCII characters are concatenated from Source to the end of

+  Destination, and Destination is always Null-terminated. If Length is 0, then

+  Destination is returned unmodified. If Source and Destination overlap, then

+  the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Destination contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and

+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength

+  ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+  @param  Length      Maximum number of ASCII characters to concatenate from

+                      Source.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrnCat (

+  IN OUT  CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source,

+  IN      UINTN                     Length

+  )

+{

+  AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (AsciiStrSize (Destination) != 0);

+  return Destination;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/SwapBytes16.c b/edk2/MdePkg/Library/BaseLib/SwapBytes16.c
new file mode 100644
index 0000000..c8460a2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/SwapBytes16.c
@@ -0,0 +1,36 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Switches the endianess of a 16-bit integer.

+

+  This function swaps the bytes in a 16-bit unsigned value to switch the value

+  from little endian to big endian or vice versa. The byte swapped value is

+  returned.

+

+  @param  Operand A 16-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT16

+EFIAPI

+SwapBytes16 (

+  IN      UINT16                    Operand

+  )

+{

+  return (Operand << 8) | (Operand >> 8);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/SwapBytes32.c b/edk2/MdePkg/Library/BaseLib/SwapBytes32.c
new file mode 100644
index 0000000..4e683b0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/SwapBytes32.c
@@ -0,0 +1,39 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Switches the endianess of a 32-bit integer.

+

+  This function swaps the bytes in a 32-bit unsigned value to switch the value

+  from little endian to big endian or vice versa. The byte swapped value is

+  returned.

+

+  @param  Operand A 32-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT32

+EFIAPI

+SwapBytes32 (

+  IN      UINT32                    Operand

+  )

+{

+  return (UINT32)(

+           ((UINT32)SwapBytes16 ((UINT16)Operand) << 16) |

+           ((UINT32)SwapBytes16 ((UINT16)(Operand >> 16)))

+           );

+}

diff --git a/edk2/MdePkg/Library/BaseLib/SwapBytes64.c b/edk2/MdePkg/Library/BaseLib/SwapBytes64.c
new file mode 100644
index 0000000..1b0882f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/SwapBytes64.c
@@ -0,0 +1,36 @@
+/** @file

+  Math worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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 "BaseLibInternals.h"

+

+/**

+  Switches the endianess of a 64-bit integer.

+

+  This function swaps the bytes in a 64-bit unsigned value to switch the value

+  from little endian to big endian or vice versa. The byte swapped value is

+  returned.

+

+  @param  Operand A 64-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT64

+EFIAPI

+SwapBytes64 (

+  IN      UINT64                    Operand

+  )

+{

+  return InternalMathSwapBytes64 (Operand);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/SwitchStack.c b/edk2/MdePkg/Library/BaseLib/SwitchStack.c
new file mode 100644
index 0000000..fec3cfa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/SwitchStack.c
@@ -0,0 +1,51 @@
+/** @file

+  Switch Stack functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SwitchStack.c

+

+**/

+

+#include <BaseLibInternals.h>

+

+/**

+  Transfers control to a function starting with a new stack.

+

+  Transfers control to the function specified by EntryPoint using the new stack

+  specified by NewStack and passing in the parameters specified by Context1 and

+  Context2. Context1 and Context2 are optional and may be NULL. The function

+  EntryPoint must never return.

+

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  @param  EntryPoint  A pointer to function to call with the new stack.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function.

+

+**/

+VOID

+EFIAPI

+SwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,

+  IN      VOID                      *Context2,

+  IN      VOID                      *NewStack

+  )

+{

+  ASSERT (EntryPoint != NULL && NewStack != NULL);

+

+  InternalSwitchStack (EntryPoint, Context1, Context2, NewStack);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Synchronization.c b/edk2/MdePkg/Library/BaseLib/Synchronization.c
new file mode 100644
index 0000000..c04edfc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Synchronization.c
@@ -0,0 +1,355 @@
+/** @file

+  Implementation of synchronization functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  Synchronization.c

+

+**/

+

+#define SPIN_LOCK_RELEASED          ((SPIN_LOCK)1)

+#define SPIN_LOCK_ACQUIRED          ((SPIN_LOCK)2)

+

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  );

+

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  );

+

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  );

+

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  );

+

+/**

+  Retrieves the architecture specific spin lock alignment requirements for

+  optimal spin lock performance.

+

+  This function retrieves the spin lock alignment requirements for optimal

+  performance on a given CPU architecture. The spin lock alignment must be a

+  power of two and is returned by this function. If there are no alignment

+  requirements, then 1 must be returned. The spin lock synchronization

+  functions must function correctly if the spin lock size and alignment values

+  returned by this function are not used at all. These values are hints to the

+  consumers of the spin lock synchronization functions to obtain optimal spin

+  lock performance.

+

+  @return The architecture specific spin lock alignment.

+

+**/

+UINTN

+EFIAPI

+GetSpinLockProperties (

+  VOID

+  )

+{

+  // @bug May use a PCD entry to determine this alignment.

+  return 32;

+}

+

+/**

+  Initializes a spin lock to the released state and returns the spin lock.

+

+  This function initializes the spin lock specified by SpinLock to the released

+  state, and returns SpinLock. Optimal performance can be achieved by calling

+  GetSpinLockProperties() to determine the size and alignment requirements for

+  SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to initialize to the released

+                    state.

+

+  @return SpinLock

+

+**/

+SPIN_LOCK *

+EFIAPI

+InitializeSpinLock (

+  OUT     SPIN_LOCK                 *SpinLock

+  )

+{

+  ASSERT (SpinLock != NULL);

+  *SpinLock = SPIN_LOCK_RELEASED;

+  return SpinLock;

+}

+

+/**

+  Waits until a spin lock can be placed in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns SpinLock. Otherwise, this function waits

+  indefinitely for the spin lock to be released, and then places it in the

+  acquired state and returns SpinLock. All state transitions of SpinLock must

+  be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+  If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in

+  PcdSpinLockTimeout microseconds, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @return SpinLock

+

+**/

+SPIN_LOCK *

+EFIAPI

+AcquireSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  UINT64                            Tick;

+  UINT64                            Start, End;

+  UINT64                            Timeout;

+

+  Tick = 0;

+  Start = 0;

+  End = 0;

+  if (FixedPcdGet32 (PcdSpinLockTimeout) > 0) {

+    Tick = GetPerformanceCounter ();

+    Timeout = DivU64x32 (

+                MultU64x32 (

+                  GetPerformanceCounterProperties (&Start, &End),

+                  FixedPcdGet32 (PcdSpinLockTimeout)

+                  ),

+                1000000

+                );

+    if (Start < End) {

+      Tick += Timeout;

+    } else {

+      Tick -= Timeout;

+    }

+  }

+

+  while (!AcquireSpinLockOrFail (SpinLock)) {

+    CpuPause ();

+    ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));

+  }

+  return SpinLock;

+}

+

+/**

+  Attempts to place a spin lock in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns TRUE. Otherwise, FALSE is returned. All state

+  transitions of SpinLock must be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @retval TRUE  SpinLock was placed in the acquired state.

+  @retval FALSE SpinLock could not be acquired.

+

+**/

+BOOLEAN

+EFIAPI

+AcquireSpinLockOrFail (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  ASSERT (SpinLock != NULL);

+  ASSERT (*SpinLock == SPIN_LOCK_ACQUIRED || *SpinLock == SPIN_LOCK_RELEASED);

+  return (BOOLEAN)(

+           InterlockedCompareExchangePointer (

+             (VOID**)SpinLock,

+             (VOID*)SPIN_LOCK_RELEASED,

+             (VOID*)SPIN_LOCK_ACQUIRED

+             ) == (VOID*)SPIN_LOCK_RELEASED

+           );

+}

+

+/**

+  Releases a spin lock.

+

+  This function places the spin lock specified by SpinLock in the release state

+  and returns SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to release.

+

+  @return SpinLock

+

+**/

+SPIN_LOCK *

+EFIAPI

+ReleaseSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  ASSERT (SpinLock != NULL);

+  ASSERT (*SpinLock == SPIN_LOCK_ACQUIRED || *SpinLock == SPIN_LOCK_RELEASED);

+  *SpinLock = SPIN_LOCK_RELEASED;

+  return SpinLock;

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedIncrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncIncrement (Value);

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedDecrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncDecrement (Value);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InterlockedCompareExchange32 (

+  IN      UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InterlockedCompareExchange64 (

+  IN      UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a pointer value.

+

+  Performs an atomic compare exchange operation on the pointer value specified

+  by Value. If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned. If Value is not equal to

+  CompareValue, then Value is returned. The compare exchange operation must be

+  performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the pointer value for the compare exchange

+                        operation.

+  @param  CompareValue  Pointer value used in compare operation.

+  @param  ExchangeValue Pointer value used in exchange operation.

+

+**/

+VOID *

+EFIAPI

+InterlockedCompareExchangePointer (

+  IN      VOID                      **Value,

+  IN      VOID                      *CompareValue,

+  IN      VOID                      *ExchangeValue

+  )

+{

+  switch (sizeof (*Value)) {

+    case sizeof (UINT32):

+      return (VOID*)(UINTN)InterlockedCompareExchange32 (

+                             (UINT32*)Value,

+                             (UINT32)(UINTN)CompareValue,

+                             (UINT32)(UINTN)ExchangeValue

+                             );

+    case sizeof (UINT64):

+      return (VOID*)(UINTN)InterlockedCompareExchange64 (

+                             (UINT64*)Value,

+                             (UINT64)(UINTN)CompareValue,

+                             (UINT64)(UINTN)ExchangeValue

+                             );

+    default:

+      ASSERT (FALSE);

+      return NULL;

+  }

+}

diff --git a/edk2/MdePkg/Library/BaseLib/Unaligned.c b/edk2/MdePkg/Library/BaseLib/Unaligned.c
new file mode 100644
index 0000000..2ce8fc6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/Unaligned.c
@@ -0,0 +1,220 @@
+/** @file

+  Unaligned access functions of BaseLib.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  Unaligned.c

+

+**/

+

+/**

+  Reads a 16-bit value from memory that may be unaligned.

+

+  This function returns the 16-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 16-bit value that may be unaligned.

+

+  @return *Uint16

+

+**/

+UINT16

+EFIAPI

+ReadUnaligned16 (

+  IN      CONST UINT16              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer;

+}

+

+/**

+  Writes a 16-bit value to memory that may be unaligned.

+

+  This function writes the 16-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 16-bit value that may be unaligned.

+  @param  Value   16-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT16

+EFIAPI

+WriteUnaligned16 (

+  OUT     UINT16                    *Buffer,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer = Value;

+}

+

+/**

+  Reads a 24-bit value from memory that may be unaligned.

+

+  This function returns the 24-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 24-bit value that may be unaligned.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+ReadUnaligned24 (

+  IN      CONST UINT32              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer & 0xffffff;

+}

+

+/**

+  Writes a 24-bit value to memory that may be unaligned.

+

+  This function writes the 24-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 24-bit value that may be unaligned.

+  @param  Value   24-bit value to write to Buffer.

+

+  @return The value written.

+

+**/

+UINT32

+EFIAPI

+WriteUnaligned24 (

+  OUT     UINT32                    *Buffer,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  BitFieldWrite32 (*Buffer, 0, 23, Value);

+  return Value;

+}

+

+/**

+  Reads a 32-bit value from memory that may be unaligned.

+

+  This function returns the 32-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 32-bit value that may be unaligned.

+

+  @return *Uint32

+

+**/

+UINT32

+EFIAPI

+ReadUnaligned32 (

+  IN      CONST UINT32              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer;

+}

+

+/**

+  Writes a 32-bit value to memory that may be unaligned.

+

+  This function writes the 32-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 32-bit value that may be unaligned.

+  @param  Value   32-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT32

+EFIAPI

+WriteUnaligned32 (

+  OUT     UINT32                    *Buffer,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer = Value;

+}

+

+/**

+  Reads a 64-bit value from memory that may be unaligned.

+

+  This function returns the 64-bit value pointed to by Buffer. The function

+  guarantees that the read operation does not produce an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 64-bit value that may be unaligned.

+

+  @return *Uint64

+

+**/

+UINT64

+EFIAPI

+ReadUnaligned64 (

+  IN      CONST UINT64              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer;

+}

+

+/**

+  Writes a 64-bit value to memory that may be unaligned.

+

+  This function writes the 64-bit value specified by Value to Buffer. Value is

+  returned. The function guarantees that the write operation does not produce

+  an alignment fault.

+

+  If the Buffer is NULL, then ASSERT().

+

+  @param  Buffer  Pointer to a 64-bit value that may be unaligned.

+  @param  Value   64-bit value to write to Buffer.

+

+  @return Value

+

+**/

+UINT64

+EFIAPI

+WriteUnaligned64 (

+  OUT     UINT64                    *Buffer,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer = Value;

+}

diff --git a/edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.asm b/edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.asm
new file mode 100644
index 0000000..f1ebe47
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuBreakpoint.Asm

+;

+; Abstract:

+;

+;   CpuBreakpoint function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuBreakpoint (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuBreakpoint   PROC

+    int  3

+    ret

+CpuBreakpoint   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/CpuFlushTlb.asm b/edk2/MdePkg/Library/BaseLib/X64/CpuFlushTlb.asm
new file mode 100644
index 0000000..c2c4490
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/CpuFlushTlb.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuFlushTlb.Asm

+;

+; Abstract:

+;

+;   CpuFlushTlb function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuFlushTlb (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuFlushTlb PROC

+    mov     rax, cr3

+    mov     cr3, rax

+    ret

+CpuFlushTlb ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/CpuId.asm b/edk2/MdePkg/Library/BaseLib/X64/CpuId.asm
new file mode 100644
index 0000000..5e7ee19
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/CpuId.asm
@@ -0,0 +1,62 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation
+; All rights reserved. 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.
+;
+; Module Name:
+;
+;   CpuId.Asm
+;
+; Abstract:
+;
+;   AsmCpuid function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+    .code
+
+;------------------------------------------------------------------------------
+;  VOID
+;  EFIAPI
+;  AsmCpuid (
+;    IN   UINT32  RegisterInEax,
+;    OUT  UINT32  *RegisterOutEax  OPTIONAL,
+;    OUT  UINT32  *RegisterOutEbx  OPTIONAL,
+;    OUT  UINT32  *RegisterOutEcx  OPTIONAL,
+;    OUT  UINT32  *RegisterOutEdx  OPTIONAL
+;    )
+;------------------------------------------------------------------------------
+AsmCpuid    PROC    USES    rbx
+    mov     eax, ecx
+    push    rax                         ; save Index on stack
+    push    rdx
+    cpuid
+    test    r9, r9
+    jz      @F
+    mov     [r9], ecx
+@@:
+    pop     rcx
+    jrcxz   @F
+    mov     [rcx], eax
+@@:
+    mov     rcx, r8
+    jrcxz   @F
+    mov     [rcx], ebx
+@@:
+    mov     rcx, [rsp + 38h]
+    jrcxz   @F
+    mov     [rcx], edx
+@@:
+    pop     rax                         ; restore Index to rax as return value
+    ret
+AsmCpuid    ENDP
+
+    END
diff --git a/edk2/MdePkg/Library/BaseLib/X64/CpuPause.asm b/edk2/MdePkg/Library/BaseLib/X64/CpuPause.asm
new file mode 100644
index 0000000..d16da37
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/CpuPause.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuPause.Asm

+;

+; Abstract:

+;

+;   CpuPause function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuPause (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuPause    PROC

+    pause

+    ret

+CpuPause    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/CpuSleep.asm b/edk2/MdePkg/Library/BaseLib/X64/CpuSleep.asm
new file mode 100644
index 0000000..b2c4907
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/CpuSleep.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CpuSleep.Asm

+;

+; Abstract:

+;

+;   CpuSleep function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuSleep (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuSleep    PROC

+    hlt

+    ret

+CpuSleep    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/DisableInterrupts.asm b/edk2/MdePkg/Library/BaseLib/X64/DisableInterrupts.asm
new file mode 100644
index 0000000..586832c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/DisableInterrupts.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DisableInterrupts.Asm

+;

+; Abstract:

+;

+;   DisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; DisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+DisableInterrupts   PROC

+    cli

+    ret

+DisableInterrupts   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm b/edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm
new file mode 100644
index 0000000..3134e42
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   DisablePaging64.Asm

+;

+; Abstract:

+;

+;   AsmDisablePaging64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86DisablePaging64    PROC

+    cli

+    shl     rcx, 32

+    lea     ecx, @F

+    push    rcx

+    mov     ebx, edx

+    mov     esi, r8d

+    mov     edi, r9d

+    mov     eax, [rsp + 28h]

+    retf

+@@:

+    mov     esp, eax                    ; set up new stack

+    mov     rax, cr0

+    btr     eax, 31

+    mov     cr0, rax                    ; disable paging

+    mov     ecx, 0c0000080h

+    rdmsr

+    and     ah, NOT 1                   ; clear LME

+    wrmsr

+    mov     rax, cr4

+    and     al, NOT (1 SHL 5)           ; clear PAE

+    mov     cr4, rax

+    push    rdi

+    push    rsi

+    call    rbx

+    jmp     $

+InternalX86DisablePaging64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.asm b/edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.asm
new file mode 100644
index 0000000..0d0400f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   EnableDisableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableDisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableDisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+EnableDisableInterrupts PROC

+    sti

+    cli

+    ret

+EnableDisableInterrupts ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/EnableInterrupts.asm b/edk2/MdePkg/Library/BaseLib/X64/EnableInterrupts.asm
new file mode 100644
index 0000000..8fb4adf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/EnableInterrupts.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   EnableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+EnableInterrupts    PROC

+    sti

+    ret

+EnableInterrupts    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/FlushCacheLine.asm b/edk2/MdePkg/Library/BaseLib/X64/FlushCacheLine.asm
new file mode 100644
index 0000000..1d470e8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/FlushCacheLine.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   FlushCacheLine.Asm

+;

+; Abstract:

+;

+;   AsmFlushCacheLine function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmFlushCacheLine (

+;   IN      VOID                      *LinearAddress

+;   );

+;------------------------------------------------------------------------------

+AsmFlushCacheLine   PROC

+    clflush [rcx]

+    ret

+AsmFlushCacheLine   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/FxRestore.asm b/edk2/MdePkg/Library/BaseLib/X64/FxRestore.asm
new file mode 100644
index 0000000..8acfc2f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/FxRestore.asm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   FxRestore.Asm

+;

+; Abstract:

+;

+;   AsmFxRestore function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86FxRestore  PROC

+    fxrstor [rcx]

+    ret

+InternalX86FxRestore  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/FxSave.asm b/edk2/MdePkg/Library/BaseLib/X64/FxSave.asm
new file mode 100644
index 0000000..cacb1f5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/FxSave.asm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   FxSave.Asm

+;

+; Abstract:

+;

+;   AsmFxSave function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86FxSave PROC

+    fxsave  [rcx]

+    ret

+InternalX86FxSave ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/InterlockedCompareExchange32.asm b/edk2/MdePkg/Library/BaseLib/X64/InterlockedCompareExchange32.asm
new file mode 100644
index 0000000..55b0554
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/InterlockedCompareExchange32.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange32.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedCompareExchange32 (

+;   IN      UINT32                    *Value,

+;   IN      UINT32                    CompareValue,

+;   IN      UINT32                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange32   PROC

+    mov     eax, edx

+    lock    cmpxchg [rcx], r8d

+    ret

+InternalSyncCompareExchange32   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/InterlockedCompareExchange64.asm b/edk2/MdePkg/Library/BaseLib/X64/InterlockedCompareExchange64.asm
new file mode 100644
index 0000000..88c25a5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/InterlockedCompareExchange64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange64.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InterlockedCompareExchange64 (

+;   IN      UINT64                    *Value,

+;   IN      UINT64                    CompareValue,

+;   IN      UINT64                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange64   PROC

+    mov     rax, rdx

+    lock    cmpxchg [rcx], r8

+    ret

+InternalSyncCompareExchange64   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/InterlockedDecrement.asm b/edk2/MdePkg/Library/BaseLib/X64/InterlockedDecrement.asm
new file mode 100644
index 0000000..f907fed
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/InterlockedDecrement.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedDecrement.Asm

+;

+; Abstract:

+;

+;   InterlockedDecrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedDecrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncDecrement   PROC

+    lock    dec     dword ptr [rcx]

+    mov     eax, [rcx]

+    ret

+InternalSyncDecrement   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/InterlockedIncrement.asm b/edk2/MdePkg/Library/BaseLib/X64/InterlockedIncrement.asm
new file mode 100644
index 0000000..f5a4130
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/InterlockedIncrement.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   InterlockedIncrement.Asm

+;

+; Abstract:

+;

+;   InterlockedIncrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedIncrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncIncrement   PROC

+    lock    inc     dword ptr [rcx]

+    mov     eax, [rcx]

+    ret

+InternalSyncIncrement   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/Invd.asm b/edk2/MdePkg/Library/BaseLib/X64/Invd.asm
new file mode 100644
index 0000000..4465879
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/Invd.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Invd.Asm

+;

+; Abstract:

+;

+;   AsmInvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmInvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmInvd PROC

+    invd

+    ret

+AsmInvd ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/LongJump.asm b/edk2/MdePkg/Library/BaseLib/X64/LongJump.asm
new file mode 100644
index 0000000..f913b6a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/LongJump.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   LongJump.Asm

+;

+; Abstract:

+;

+;   Implementation of _LongJump() on x64.

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+_LongJump    PROC

+    mov     rbx, [rcx]

+    mov     rsp, [rcx + 8]

+    mov     rbp, [rcx + 10h]

+    mov     rdi, [rcx + 18h]

+    mov     rsi, [rcx + 20h]

+    mov     r12, [rcx + 28h]

+    mov     r13, [rcx + 30h]

+    mov     r14, [rcx + 38h]

+    mov     r15, [rcx + 40h]

+    mov     rax, rdx

+    jmp     qword ptr [rcx + 48h]

+_LongJump    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/Monitor.asm b/edk2/MdePkg/Library/BaseLib/X64/Monitor.asm
new file mode 100644
index 0000000..0140494
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/Monitor.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Monitor.Asm

+;

+; Abstract:

+;

+;   AsmMonitor function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmMonitor (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx,

+;   IN      UINTN                     Edx

+;   );

+;------------------------------------------------------------------------------

+AsmMonitor  PROC

+    mov     eax, ecx

+    mov     ecx, edx

+    mov     edx, r8d

+    DB      0fh, 1, 0c8h

+    ret

+AsmMonitor  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/Mwait.asm b/edk2/MdePkg/Library/BaseLib/X64/Mwait.asm
new file mode 100644
index 0000000..8f76d94
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/Mwait.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Mwait.Asm

+;

+; Abstract:

+;

+;   AsmMwait function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmMwait (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx

+;   );

+;------------------------------------------------------------------------------

+AsmMwait    PROC

+    mov     eax, ecx

+    mov     ecx, edx

+    DB      0fh, 1, 0c9h

+    ret

+AsmMwait    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/Non-existing.c b/edk2/MdePkg/Library/BaseLib/X64/Non-existing.c
new file mode 100644
index 0000000..b2c7378
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/Non-existing.c
@@ -0,0 +1,54 @@
+/** @file

+	Non-existing BaseLib functions on x64

+

+	Copyright (c) 2006, Intel Corporation

+	All rights reserved. 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.

+

+	Module Name:	Non-existing.c

+

+**/

+

+#include "../BaseLibInternals.h"

+

+VOID

+EFIAPI

+InternalX86EnablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  ASSERT (FALSE);

+}

+

+VOID

+EFIAPI

+InternalX86DisablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  ASSERT (FALSE);

+}

+

+VOID

+EFIAPI

+InternalX86EnablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT64                    EntryPoint,

+  IN      UINT64                    Context1,  OPTIONAL

+  IN      UINT64                    Context2,  OPTIONAL

+  IN      UINT64                    NewStack

+  )

+{

+  ASSERT (FALSE);

+}

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadCr0.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadCr0.asm
new file mode 100644
index 0000000..3e369c3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadCr0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr0.Asm

+;

+; Abstract:

+;

+;   AsmReadCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr0  PROC

+    mov     rax, cr0

+    ret

+AsmReadCr0  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadCr2.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadCr2.asm
new file mode 100644
index 0000000..8476f5a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadCr2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr2.Asm

+;

+; Abstract:

+;

+;   AsmReadCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr2  PROC

+    mov     rax, cr2

+    ret

+AsmReadCr2  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadCr3.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadCr3.asm
new file mode 100644
index 0000000..af54d46
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadCr3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr3.Asm

+;

+; Abstract:

+;

+;   AsmReadCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr3  PROC

+    mov     rax, cr3

+    ret

+AsmReadCr3  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadCr4.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadCr4.asm
new file mode 100644
index 0000000..c8a881d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadCr4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCr4.Asm

+;

+; Abstract:

+;

+;   AsmReadCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr4  PROC

+    mov     rax, cr4

+    ret

+AsmReadCr4  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadCs.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadCs.asm
new file mode 100644
index 0000000..126149a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadCs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadCs.Asm

+;

+; Abstract:

+;

+;   AsmReadCs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadCs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCs   PROC

+    mov     ax, cs

+    ret

+AsmReadCs   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr0.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr0.asm
new file mode 100644
index 0000000..7e0d6b7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr0.Asm

+;

+; Abstract:

+;

+;   AsmReadDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr0  PROC

+    mov     rax, dr0

+    ret

+AsmReadDr0  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr1.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr1.asm
new file mode 100644
index 0000000..22f11c4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr1.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr1.Asm

+;

+; Abstract:

+;

+;   AsmReadDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr1  PROC

+    mov     rax, dr1

+    ret

+AsmReadDr1  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr2.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr2.asm
new file mode 100644
index 0000000..3b81605
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr2.Asm

+;

+; Abstract:

+;

+;   AsmReadDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr2  PROC

+    mov     rax, dr2

+    ret

+AsmReadDr2  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr3.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr3.asm
new file mode 100644
index 0000000..1968fd0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr3.Asm

+;

+; Abstract:

+;

+;   AsmReadDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr3  PROC

+    mov     rax, dr3

+    ret

+AsmReadDr3  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm
new file mode 100644
index 0000000..9774001
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr4.Asm

+;

+; Abstract:

+;

+;   AsmReadDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr4  PROC

+    DB      0fh, 21h, 0e0h

+    ret

+AsmReadDr4  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm
new file mode 100644
index 0000000..0582502
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr5.Asm

+;

+; Abstract:

+;

+;   AsmReadDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr5  PROC

+    DB      0fh, 21h, 0e8h

+    ret

+AsmReadDr5  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr6.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr6.asm
new file mode 100644
index 0000000..a3dafb9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr6.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr6.Asm

+;

+; Abstract:

+;

+;   AsmReadDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr6  PROC

+    mov     rax, dr6

+    ret

+AsmReadDr6  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDr7.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDr7.asm
new file mode 100644
index 0000000..0cff14b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDr7.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDr7.Asm

+;

+; Abstract:

+;

+;   AsmReadDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr7  PROC

+    mov     rax, dr7

+    ret

+AsmReadDr7  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadDs.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadDs.asm
new file mode 100644
index 0000000..bdcddb6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadDs.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadDs.Asm

+;

+; Abstract:

+;

+;   AsmReadDs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadDs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDs   PROC

+    mov     ax, ds

+    ret

+AsmReadDs   ENDP

+

+    END

+

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadEflags.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadEflags.asm
new file mode 100644
index 0000000..174ae95
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadEflags.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadEflags.Asm

+;

+; Abstract:

+;

+;   AsmReadEflags function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadEflags (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadEflags   PROC

+    pushfq

+    pop     rax

+    ret

+AsmReadEflags   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadEs.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadEs.asm
new file mode 100644
index 0000000..40384bc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadEs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadEs.Asm

+;

+; Abstract:

+;

+;   AsmReadEs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadEs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadEs   PROC

+    mov     ax, es

+    ret

+AsmReadEs   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadFs.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadFs.asm
new file mode 100644
index 0000000..b63e474
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadFs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadFs.Asm

+;

+; Abstract:

+;

+;   AsmReadFs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadFs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadFs   PROC

+    mov     ax, fs

+    ret

+AsmReadFs   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadGdtr.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadGdtr.asm
new file mode 100644
index 0000000..2d40599
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadGdtr.asm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadGdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86ReadGdtr   PROC

+    sgdt    fword ptr [rcx]

+    ret

+InternalX86ReadGdtr   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadGs.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadGs.asm
new file mode 100644
index 0000000..02d140e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadGs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadGs.Asm

+;

+; Abstract:

+;

+;   AsmReadGs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadGs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadGs   PROC

+    mov     ax, gs

+    ret

+AsmReadGs   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadIdtr.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadIdtr.asm
new file mode 100644
index 0000000..260f697
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadIdtr.asm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadIdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86ReadIdtr   PROC

+    sidt    fword ptr [rcx]

+    ret

+InternalX86ReadIdtr   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadLdtr.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadLdtr.asm
new file mode 100644
index 0000000..3d6a2f8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadLdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadLdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadLdtr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadLdtr PROC

+    sldt    eax

+    ret

+AsmReadLdtr ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm
new file mode 100644
index 0000000..1239bca
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm0.Asm

+;

+; Abstract:

+;

+;   AsmReadMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm0  PROC

+    DB      48h, 0fh, 7eh, 0c0h

+    ret

+AsmReadMm0  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm
new file mode 100644
index 0000000..b42bd7f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm1.Asm

+;

+; Abstract:

+;

+;   AsmReadMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm1  PROC

+    DB      48h, 0fh, 7eh, 0c8h

+    ret

+AsmReadMm1  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm
new file mode 100644
index 0000000..b10782e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm2.Asm

+;

+; Abstract:

+;

+;   AsmReadMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm2  PROC

+    DB      48h, 0fh, 7eh, 0d0h

+    ret

+AsmReadMm2  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm
new file mode 100644
index 0000000..15a9647
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm3.Asm

+;

+; Abstract:

+;

+;   AsmReadMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm3  PROC

+    DB      48h, 0fh, 7eh, 0d8h

+    ret

+AsmReadMm3  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm
new file mode 100644
index 0000000..73f5283
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm4.Asm

+;

+; Abstract:

+;

+;   AsmReadMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm4  PROC

+    DB      48h, 0fh, 7eh, 0e0h

+    ret

+AsmReadMm4  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm
new file mode 100644
index 0000000..a487889
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm5.Asm

+;

+; Abstract:

+;

+;   AsmReadMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm5  PROC

+    DB      48h, 0fh, 7eh, 0e8h

+    ret

+AsmReadMm5  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm
new file mode 100644
index 0000000..56f81bf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm6.Asm

+;

+; Abstract:

+;

+;   AsmReadMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm6  PROC

+    DB      48h, 0fh, 7eh, 0f0h

+    ret

+AsmReadMm6  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm
new file mode 100644
index 0000000..e3ad6bb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMm7.Asm

+;

+; Abstract:

+;

+;   AsmReadMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadMm7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm7  PROC

+    DB      48h, 0fh, 7eh, 0f8h

+    ret

+AsmReadMm7  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMsr32.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMsr32.asm
new file mode 100644
index 0000000..271eabb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMsr32.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMsr32.Asm

+;

+; Abstract:

+;

+;   AsmReadMsr32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; AsmReadMsr32 (

+;   IN UINT32  Index

+;   );

+;------------------------------------------------------------------------------

+AsmReadMsr32    PROC

+    rdmsr

+    ret

+AsmReadMsr32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.asm
new file mode 100644
index 0000000..4444c18
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadMsr64.Asm

+;

+; Abstract:

+;

+;   AsmReadMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMsr64 (

+;   IN UINT32  Index

+;   );

+;------------------------------------------------------------------------------

+AsmReadMsr64    PROC

+    rdmsr

+    shl     rax, 20h

+    shrd    rax, rdx, 20h

+    ret

+AsmReadMsr64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadPmc.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadPmc.asm
new file mode 100644
index 0000000..b5004d6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadPmc.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadPmc.Asm

+;

+; Abstract:

+;

+;   AsmReadPmc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadPmc (

+;   IN UINT32   PmcIndex

+;   );

+;------------------------------------------------------------------------------

+AsmReadPmc  PROC

+    rdpmc

+    shl     ecx, 1

+    jnc     @F

+    shl     rax, 20h

+    shrd    rax, rdx, 20h

+@@:

+    ret

+AsmReadPmc  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadSs.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadSs.asm
new file mode 100644
index 0000000..4aa480d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadSs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadSs.Asm

+;

+; Abstract:

+;

+;   AsmReadSs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadSs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadSs   PROC

+    mov     ax, ss

+    ret

+AsmReadSs   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadTr.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadTr.asm
new file mode 100644
index 0000000..7cf8cdf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadTr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadTr.Asm

+;

+; Abstract:

+;

+;   AsmReadTr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadTr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadTr   PROC

+    str     eax

+    ret

+AsmReadTr   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/ReadTsc.asm b/edk2/MdePkg/Library/BaseLib/X64/ReadTsc.asm
new file mode 100644
index 0000000..25fa2cc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/ReadTsc.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ReadTsc.Asm

+;

+; Abstract:

+;

+;   AsmReadTsc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadTsc (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadTsc  PROC

+    rdtsc

+    shl     rax, 20h

+    shrd    rax, rdx, 20h

+    ret

+AsmReadTsc  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/SetJump.asm b/edk2/MdePkg/Library/BaseLib/X64/SetJump.asm
new file mode 100644
index 0000000..305e721
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/SetJump.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetJump.Asm

+;

+; Abstract:

+;

+;   Implementation of SetJump() on x64.

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+SetJump     PROC

+    pop     rdx

+    mov     [rcx], rbx

+    mov     [rcx + 8], rsp

+    mov     [rcx + 10h], rbp

+    mov     [rcx + 18h], rdi

+    mov     [rcx + 20h], rsi

+    mov     [rcx + 28h], r12

+    mov     [rcx + 30h], r13

+    mov     [rcx + 38h], r14

+    mov     [rcx + 40h], r15

+    mov     [rcx + 48h], rdx

+    xor     rax, rax

+    jmp     rdx

+SetJump     ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.asm b/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.asm
new file mode 100644
index 0000000..53d1417
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SwitchStack.Asm

+;

+; Abstract:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; Routine Description:

+;

+;   Routine for switching stacks with 1 parameter

+;

+; Arguments:

+;

+;   (rcx) EntryPoint    - Entry point with new stack.

+;   (rdx) Context       - Parameter for entry point.

+;   (r8)  Context2      - Parameter2 for entry point.

+;   (r9)  NewStack      - Pointer to new stack.

+;

+; Returns:

+;

+;   None

+;

+;------------------------------------------------------------------------------

+InternalSwitchStack PROC

+    mov     rax, rcx

+    mov     rcx, rdx

+    mov     rdx, r8

+    lea     rsp, [r9 - 20h]

+    call    rax

+InternalSwitchStack ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm b/edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm
new file mode 100644
index 0000000..3121867
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm
@@ -0,0 +1,242 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Thunk.asm

+;

+; Abstract:

+;

+;   Real mode thunk

+;

+;------------------------------------------------------------------------------

+

+EXTERNDEF   m16Start:BYTE

+EXTERNDEF   m16Size:WORD

+EXTERNDEF   mThunk16Attr:WORD

+EXTERNDEF   m16Gdt:WORD

+EXTERNDEF   m16GdtrBase:WORD

+EXTERNDEF   mTransition:WORD

+

+THUNK_ATTRIBUTE_BIG_REAL_MODE               EQU 1

+THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15     EQU 2

+THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL   EQU 4

+

+IA32_REGS   STRUC   4t

+_EDI        DD      ?

+_ESI        DD      ?

+_EBP        DD      ?

+_ESP        DD      ?

+_EBX        DD      ?

+_EDX        DD      ?

+_ECX        DD      ?

+_EAX        DD      ?

+_DS         DW      ?

+_ES         DW      ?

+_FS         DW      ?

+_GS         DW      ?

+_EFLAGS     DQ      ?

+_EIP        DD      ?

+_CS         DW      ?

+_SS         DW      ?

+IA32_REGS   ENDS

+

+    .const

+

+m16Size         DW      offset InternalAsmThunk16 - offset m16Start

+mThunk16Attr    DW      offset _ThunkAttr - offset m16Start

+m16Gdt          DW      offset _NullSegDesc - offset m16Start

+m16GdtrBase     DW      offset _16GdtrBase - offset m16Start

+mTransition     DW      offset _EntryPoint - offset m16Start

+

+    .code

+

+m16Start    LABEL   BYTE

+

+SavedGdt        LABEL   FWORD

+                DW      ?

+                DQ      ?

+

+_BackFromUserCode   PROC

+    DB      16h                         ; push ss

+    DB      0eh                         ; push cs

+    DB      66h

+    call    @Base                       ; push eip

+@Base:

+    DB      66h

+    push    0                           ; reserved high order 32 bits of EFlags

+    pushf                               ; pushfd actually

+    cli                                 ; disable interrupts

+    push    gs

+    push    fs

+    DB      6                           ; push es

+    DB      1eh                         ; push ds

+    DB      66h, 60h                    ; pushad

+    DB      66h, 0bah                   ; mov edx, imm32

+_ThunkAttr  DD      ?

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15

+    jz      @1

+    mov     eax, 15cd2401h              ; mov ax, 2401h & int 15h

+    cli                                 ; disable interrupts

+    jnc     @2

+@1:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL

+    jz      @2

+    in      al, 92h

+    or      al, 2

+    out     92h, al                     ; deactivate A20M#

+@2:

+    mov     eax, ss

+    lea     bp, [esp + sizeof (IA32_REGS)]

+    mov     word ptr (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._ESP, bp

+    mov     ebx, (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._EIP

+    shl     ax, 4                       ; shl eax, 4

+    add     bp, ax                      ; add ebp, eax

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr4    DD      ?

+    mov     cr4, rax

+    DB      66h, 2eh

+    lgdt    fword ptr [rdi + (offset SavedGdt - offset @Base)]

+    DB      66h

+    mov     ecx, 0c0000080h

+    rdmsr

+    or      ah, 1

+    wrmsr

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr0    DD      ?

+    mov     cr0, rax

+    DB      0b8h                        ; mov ax, imm16

+SavedSs     DW      ?

+    mov     ss, eax

+    DB      66h, 0bch                   ; mov esp, imm32

+SavedEsp    DD      ?

+    DB      66h

+    retf                                ; return to protected mode

+_BackFromUserCode   ENDP

+

+_EntryPoint     DD      offset _ToUserCode - offset m16Start

+                DW      8h

+_16Gdtr         LABEL   FWORD

+                DW      offset GdtEnd - offset _NullSegDesc - 1

+_16GdtrBase     DQ      offset _NullSegDesc

+_16Idtr         FWORD   (1 SHL 10) - 1

+

+_ToUserCode PROC

+    mov     edi, ss

+    mov     ss, edx                     ; set new segment selectors

+    mov     ds, edx

+    mov     es, edx

+    mov     fs, edx

+    mov     gs, edx

+    DB      66h

+    mov     ecx, 0c0000080h

+    mov     cr0, rax                    ; real mode starts at next instruction

+    rdmsr

+    and     ah, NOT 1

+    wrmsr

+    mov     cr4, rbp

+    mov     ss, esi                     ; set up 16-bit stack segment

+    xchg    sp, bx                      ; set up 16-bit stack pointer

+    DB      66h

+    call    @Base                       ; push eip

+@Base:

+    pop     bp                          ; ebp <- offset @Base

+    push    [esp + sizeof (IA32_REGS) + 2]

+    lea     eax, [rsi + (offset @RealMode - offset @Base)]

+    push    rax

+    retf

+@RealMode:

+    DB      2eh                         ; cs:

+    mov     [rsi + (offset SavedSs - offset @Base)], edi

+    DB      2eh                         ; cs:

+    mov     [rsi + (offset SavedEsp - offset @Base)], bx

+    DB      66h, 2eh                    ; CS and operand size override

+    lidt    fword ptr [rsi + (offset _16Idtr - offset @Base)]

+    DB      66h, 61h                    ; popad

+    DB      1fh                         ; pop ds

+    DB      07h                         ; pop es

+    pop     fs

+    pop     gs

+    popf                                ; popfd

+    lea     sp, [esp + 4]               ; skip high order 32 bits of EFlags

+    DB      66h

+    retf                                ; transfer control to user code

+_ToUserCode ENDP

+

+_NullSegDesc    DQ      0

+_16CsDesc       LABEL   QWORD

+                DW      -1

+                DW      0

+                DB      0

+                DB      9bh

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+_16DsDesc       LABEL   QWORD

+                DW      -1

+                DW      0

+                DB      0

+                DB      93h

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+GdtEnd          LABEL   QWORD

+

+;

+;   @param  RegSet  Pointer to a IA32_DWORD_REGS structure

+;   @param  Transition  Pointer to the transition code

+;   @return The address of the 16-bit stack after returning from user code

+;

+InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi

+    mov     r10d, ds

+    mov     r11d, es

+    push    fs

+    push    gs

+    mov     rsi, rcx

+    movzx   r8d, (IA32_REGS ptr [rsi])._SS

+    mov     edi, (IA32_REGS ptr [rsi])._ESP

+    lea     rdi, [edi - (sizeof (IA32_REGS) + 4)]

+    imul    eax, r8d, 16                ; eax <- r8d(stack segment) * 16

+    mov     ebx, edi                    ; ebx <- stack offset for 16-bit code

+    push    sizeof (IA32_REGS) / 4

+    add     edi, eax                    ; edi <- linear address of 16-bit stack

+    pop     rcx

+    rep     movsd                       ; copy RegSet

+    lea     ecx, [rdx + (offset SavedCr4 - offset m16Start)]

+    mov     eax, edx                    ; eax <- transition code address

+    and     edx, 0fh

+    shl     eax, 12

+    lea     edx, [rdx + (offset _BackFromUserCode - offset m16Start)]

+    mov     ax, dx

+    stosd                               ; [edi] <- return address of user code

+    sgdt    fword ptr [rcx + (offset SavedGdt - offset SavedCr4)]

+    sidt    fword ptr [rsp + 38h]       ; save IDT stack in argument space

+    mov     rax, cr0

+    mov     [rcx + (offset SavedCr0 - offset SavedCr4)], eax

+    and     eax, 7ffffffeh              ; clear PE, PG bits

+    mov     rbp, cr4

+    mov     [rcx], ebp                  ; save CR4 in SavedCr4

+    and     ebp, 300h                   ; clear all but PCE and OSFXSR bits

+    mov     esi, r8d                    ; esi <- 16-bit stack segment

+    push    10h

+    pop     rdx                         ; rdx <- selector for data segments

+    lgdt    fword ptr [rcx + (offset _16Gdtr - offset SavedCr4)]

+    pushfq

+    call    fword ptr [rcx + (offset _EntryPoint - offset SavedCr4)]

+    popfq

+    lidt    fword ptr [rsp + 38h]       ; restore protected mode IDTR

+    lea     eax, [rbp - sizeof (IA32_REGS)]

+    pop     gs

+    pop     fs

+    mov     es, r11d

+    mov     ds, r10d

+    ret

+InternalAsmThunk16  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/Wbinvd.asm b/edk2/MdePkg/Library/BaseLib/X64/Wbinvd.asm
new file mode 100644
index 0000000..ca0cb25
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/Wbinvd.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   Wbinvd.Asm

+;

+; Abstract:

+;

+;   AsmWbinvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWbinvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWbinvd   PROC

+    wbinvd

+    ret

+AsmWbinvd   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteCr0.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteCr0.asm
new file mode 100644
index 0000000..defc7e7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteCr0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr0 PROC

+    mov     cr0, rcx

+    ret

+AsmWriteCr0 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteCr2.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteCr2.asm
new file mode 100644
index 0000000..ebe6f89
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteCr2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr2 PROC

+    mov     cr2, rcx

+    ret

+AsmWriteCr2 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteCr3.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteCr3.asm
new file mode 100644
index 0000000..5715dea
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteCr3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr3 PROC

+    mov     cr3, rcx

+    ret

+AsmWriteCr3 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteCr4.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteCr4.asm
new file mode 100644
index 0000000..210744e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteCr4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteCr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr4 PROC

+    mov     cr4, rcx

+    ret

+AsmWriteCr4 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr0.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr0.asm
new file mode 100644
index 0000000..2515a20
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr0 PROC

+    mov     dr0, rcx

+    ret

+AsmWriteDr0 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr1.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr1.asm
new file mode 100644
index 0000000..89f36ac
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr1.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr1.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr1 PROC

+    mov     dr1, rcx

+    ret

+AsmWriteDr1 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr2.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr2.asm
new file mode 100644
index 0000000..820977c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr2 PROC

+    mov     dr2, rcx

+    ret

+AsmWriteDr2 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr3.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr3.asm
new file mode 100644
index 0000000..51c1407
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr3 PROC

+    mov     dr3, rcx

+    ret

+AsmWriteDr3 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm
new file mode 100644
index 0000000..12b6438
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr4 PROC

+    DB      0fh, 23h, 0e1h

+    ret

+AsmWriteDr4 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm
new file mode 100644
index 0000000..6d454d5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr5.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr5 PROC

+    DB      0fh, 23h, 0e9h

+    ret

+AsmWriteDr5 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr6.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr6.asm
new file mode 100644
index 0000000..b7b9f25
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr6.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr6.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr6 PROC

+    mov     dr6, rcx

+    ret

+AsmWriteDr6 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteDr7.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteDr7.asm
new file mode 100644
index 0000000..de2237b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteDr7.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteDr7.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr7 PROC

+    mov     dr7, rcx

+    ret

+AsmWriteDr7 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteGdtr.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteGdtr.asm
new file mode 100644
index 0000000..1757e3d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteGdtr.asm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteGdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86WriteGdtr  PROC

+    lgdt    fword ptr [rcx]

+    ret

+InternalX86WriteGdtr  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteIdtr.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteIdtr.asm
new file mode 100644
index 0000000..09fcb9e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteIdtr.asm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteIdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalX86WriteIdtr  PROC

+    lidt    fword ptr [rcx]

+    ret

+InternalX86WriteIdtr  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteLdtr.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteLdtr.asm
new file mode 100644
index 0000000..d85ae38
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteLdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteLdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteLdtr (

+;   IN UINT16 Ldtr

+;   );

+;------------------------------------------------------------------------------

+AsmWriteLdtr    PROC

+    lldt    cx

+    ret

+AsmWriteLdtr    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm
new file mode 100644
index 0000000..bb9a576
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm0.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm0 PROC

+    DB      48h, 0fh, 6eh, 0c1h

+    ret

+AsmWriteMm0 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm
new file mode 100644
index 0000000..1bab3bc
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm1.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm1 PROC

+    DB      48h, 0fh, 6eh, 0c9h

+    ret

+AsmWriteMm1 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm
new file mode 100644
index 0000000..97e8a6a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm2.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm2 PROC

+    DB      48h, 0fh, 6eh, 0d1h

+    ret

+AsmWriteMm2 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm
new file mode 100644
index 0000000..d55e19a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm3.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm3 PROC

+    DB      48h, 0fh, 6eh, 0d9h

+    ret

+AsmWriteMm3 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm
new file mode 100644
index 0000000..2a69b93
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm4.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm4 PROC

+    DB      48h, 0fh, 6eh, 0e1h

+    ret

+AsmWriteMm4 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm
new file mode 100644
index 0000000..c4d798b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm5.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm5 PROC

+    DB      48h, 0fh, 6eh, 0e9h

+    ret

+AsmWriteMm5 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm
new file mode 100644
index 0000000..c0164f6
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm6.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm6 PROC

+    DB      48h, 0fh, 6eh, 0f1h

+    ret

+AsmWriteMm6 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm
new file mode 100644
index 0000000..20768e2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMm7.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteMm7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm7 PROC

+    DB      48h, 0fh, 6eh, 0f9h

+    ret

+AsmWriteMm7 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMsr32.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMsr32.asm
new file mode 100644
index 0000000..0a74403
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMsr32.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMsr32.Asm

+;

+; Abstract:

+;

+;   AsmWriteMsr32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; AsmWriteMsr32 (

+;   IN UINT32  Index,

+;   IN UINT32  Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMsr32   PROC

+    mov     eax, edx

+    xor     edx, edx

+    wrmsr

+    ret

+AsmWriteMsr32   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm b/edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm
new file mode 100644
index 0000000..3337f45
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   WriteMsr64.Asm

+;

+; Abstract:

+;

+;   AsmWriteMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMsr64 (

+;   IN UINT32  Index,

+;   IN UINT64  Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMsr64   PROC

+    push    rdx

+    mov     eax, edx

+    shr     rdx, 20h

+    wrmsr

+    pop     rax

+    ret

+AsmWriteMsr64   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseLib/build.xml b/edk2/MdePkg/Library/BaseLib/build.xml
new file mode 100644
index 0000000..224e8a9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseLib">

+      <GenBuild baseName="BaseLib" mbdFilename="${MODULE_DIR}/BaseLib.mbd" msaFilename="${MODULE_DIR}/BaseLib.msa"/>

+   </target>

+   <target depends="BaseLib_clean" name="clean"/>

+   <target depends="BaseLib_cleanall" name="cleanall"/>

+   <target name="BaseLib_clean">

+      <OutputDirSetup baseName="BaseLib" mbdFilename="${MODULE_DIR}/BaseLib.mbd" msaFilename="${MODULE_DIR}/BaseLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseLib_cleanall">

+      <OutputDirSetup baseName="BaseLib" mbdFilename="${MODULE_DIR}/BaseLib.mbd" msaFilename="${MODULE_DIR}/BaseLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseLib/x86LowLevel.c b/edk2/MdePkg/Library/BaseLib/x86LowLevel.c
new file mode 100644
index 0000000..c222c6c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/x86LowLevel.c
@@ -0,0 +1,979 @@
+/** @file

+  IA-32/x64 specific functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  x86LowLevel.c

+

+**/

+

+#include "BaseLibInternals.h"

+

+//

+// Bit-wise MSR operations

+//

+

+/**

+  Reads a 64-bit MSR, performs a bitwise inclusive OR on the lower 32-bits, and

+  writes the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the lower 32-bits of the read result and the value specified by

+  OrData, and writes the result to the 64-bit MSR specified by Index. The lower

+  32-bits of the value written to the MSR is returned. No parameter checking is

+  performed on Index or OrData, and some of these may cause CPU exceptions. The

+  caller must either guarantee that Index and OrData are valid, or the caller

+  must establish proper exception handlers. This function is only available on

+  IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  OrData  The value to OR with the read value from the MSR.

+

+  @return The lower 32-bit value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrOr32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    OrData

+  )

+{

+  return (UINT32)AsmMsrOr64 (Index, OrData);

+}

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND on the lower 32-bits, and writes

+  the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  lower 32-bits of the read result and the value specified by AndData, and

+  writes the result to the 64-bit MSR specified by Index. The lower 32-bits of

+  the value written to the MSR is returned. No parameter checking is performed

+  on Index or AndData, and some of these may cause CPU exceptions. The caller

+  must either guarantee that Index and AndData are valid, or the caller must

+  establish proper exception handlers. This function is only available on IA-32

+  and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+

+  @return The lower 32-bit value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrAnd32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    AndData

+  )

+{

+  return (UINT32)AsmMsrAnd64 (Index, AndData);

+}

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise inclusive OR

+  on the lower 32-bits, and writes the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  lower 32-bits of the read result and the value specified by AndData

+  preserving the upper 32-bits, performs a bitwise inclusive OR between the

+  result of the AND operation and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Address. The lower 32-bits of the value

+  written to the MSR is returned. No parameter checking is performed on Index,

+  AndData, or OrData, and some of these may cause CPU exceptions. The caller

+  must either guarantee that Index, AndData, and OrData are valid, or the

+  caller must establish proper exception handlers. This function is only

+  available on IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The lower 32-bit value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrAndThenOr32 (

+  IN      UINT32                    Index,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return (UINT32)AsmMsrAndThenOr64 (Index, AndData, OrData);

+}

+

+/**

+  Reads a bit field of an MSR.

+

+  Reads the bit field in the lower 32-bits of a 64-bit MSR. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned. The caller must either guarantee that Index is valid, or the caller

+  must set up exception handlers to catch the exceptions. This function is only

+  available on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The bit field read from the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldRead32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (AsmReadMsr32 (Index), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an MSR.

+

+  Writes Value to a bit field in the lower 32-bits of a  64-bit MSR. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination MSR are preserved. The lower 32-bits of the MSR written is

+  returned. Extra left bits in Value are stripped. The caller must either

+  guarantee that Index and the data written is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldWrite32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (EndBit < sizeof (Value) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldWrite64 (Index, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Index. The lower 32-bits of the value

+  written to the MSR are returned. Extra left bits in OrData are stripped. The

+  caller must either guarantee that Index and the data written is valid, or

+  the caller must set up exception handlers to catch the exceptions. This

+  function is only available on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the MSR.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldOr32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (OrData) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldOr64 (Index, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  read result and the value specified by AndData, and writes the result to the

+  64-bit MSR specified by Index. The lower 32-bits of the value written to the

+  MSR are returned. Extra left bits in AndData are stripped. The caller must

+  either guarantee that Index and the data written is valid, or the caller must

+  set up exception handlers to catch the exceptions. This function is only

+  available on IA-32 and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the MSR.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldAnd32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT (EndBit < sizeof (AndData) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldAnd64 (Index, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by a

+  bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit MSR specified by Index. The

+  lower 32-bits of the value written to the MSR are returned. Extra left bits

+  in both AndData and OrData are stripped. The caller must either guarantee

+  that Index and the data written is valid, or the caller must set up exception

+  handlers to catch the exceptions. This function is only available on IA-32

+  and X64.

+

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the MSR.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The lower 32-bit of the value written to the MSR.

+

+**/

+UINT32

+EFIAPI

+AsmMsrBitFieldAndThenOr32 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT (EndBit < sizeof (AndData) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldAndThenOr64 (

+                   Index,

+                   StartBit,

+                   EndBit,

+                   AndData,

+                   OrData

+                   );

+}

+

+/**

+  Reads a 64-bit MSR, performs a bitwise inclusive OR, and writes the result

+  back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Index. The value written to the MSR is

+  returned. No parameter checking is performed on Index or OrData, and some of

+  these may cause CPU exceptions. The caller must either guarantee that Index

+  and OrData are valid, or the caller must establish proper exception handlers.

+  This function is only available on IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  OrData  The value to OR with the read value from the MSR.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrOr64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    OrData

+  )

+{

+  return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) | OrData);

+}

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND, and writes the result back to the

+  64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  read result and the value specified by OrData, and writes the result to the

+  64-bit MSR specified by Index. The value written to the MSR is returned. No

+  parameter checking is performed on Index or OrData, and some of these may

+  cause CPU exceptions. The caller must either guarantee that Index and OrData

+  are valid, or the caller must establish proper exception handlers. This

+  function is only available on IA-32 and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrAnd64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    AndData

+  )

+{

+  return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) & AndData);

+}

+

+/**

+  Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise inclusive

+  OR, and writes the result back to the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between read

+  result and the value specified by AndData, performs a bitwise inclusive OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 64-bit MSR specified by Index. The value written

+  to the MSR is returned. No parameter checking is performed on Index, AndData,

+  or OrData, and some of these may cause CPU exceptions. The caller must either

+  guarantee that Index, AndData, and OrData are valid, or the caller must

+  establish proper exception handlers. This function is only available on IA-32

+  and X64.

+

+  @param  Index   The 32-bit MSR index to write.

+  @param  AndData The value to AND with the read value from the MSR.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrAndThenOr64 (

+  IN      UINT32                    Index,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return AsmWriteMsr64 (Index, (AsmReadMsr64 (Index) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an MSR.

+

+  Reads the bit field in the 64-bit MSR. The bit field is specified by the

+  StartBit and the EndBit. The value of the bit field is returned. The caller

+  must either guarantee that Index is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldRead64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (AsmReadMsr64 (Index), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an MSR.

+

+  Writes Value to a bit field in a 64-bit MSR. The bit field is specified by

+  the StartBit and the EndBit. All other bits in the destination MSR are

+  preserved. The MSR written is returned. Extra left bits in Value are

+  stripped. The caller must either guarantee that Index and the data written is

+  valid, or the caller must set up exception handlers to catch the exceptions.

+  This function is only available on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldWrite64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldWrite64 (AsmReadMsr64 (Index), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise inclusive OR, and

+  writes the result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit MSR specified by Index. The value written to the MSR is

+  returned. Extra left bits in OrData are stripped. The caller must either

+  guarantee that Index and the data written is valid, or the caller must set up

+  exception handlers to catch the exceptions. This function is only available

+  on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the bit field.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldOr64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldOr64 (AsmReadMsr64 (Index), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the

+  read result and the value specified by AndData, and writes the result to the

+  64-bit MSR specified by Index. The value written to the MSR is returned.

+  Extra left bits in AndData are stripped. The caller must either guarantee

+  that Index and the data written is valid, or the caller must set up exception

+  handlers to catch the exceptions. This function is only available on IA-32

+  and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the bit field.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldAnd64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldAnd64 (AsmReadMsr64 (Index), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MSR.

+

+  Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by

+  a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit MSR specified by Index. The

+  value written to the MSR is returned. Extra left bits in both AndData and

+  OrData are stripped. The caller must either guarantee that Index and the data

+  written is valid, or the caller must set up exception handlers to catch the

+  exceptions. This function is only available on IA-32 and X64.

+

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Index     The 32-bit MSR index to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the bit field.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MSR.

+

+**/

+UINT64

+EFIAPI

+AsmMsrBitFieldAndThenOr64 (

+  IN      UINT32                    Index,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldAndThenOr64 (

+             AsmReadMsr64 (Index),

+             StartBit,

+             EndBit,

+             AndData,

+             OrData

+             )

+           );

+}

+

+//

+// Base Library CPU Functions

+//

+

+/**

+  Retrieves the current CPU interrupt state.

+

+  Retrieves the current CPU interrupt state. Returns TRUE is interrupts are

+  currently enabled. Otherwise returns FALSE.

+

+  @retval TRUE  CPU interrupts are enabled.

+  @retval FALSE CPU interrupts are disabled.

+

+**/

+BOOLEAN

+EFIAPI

+GetInterruptState (

+  VOID

+  )

+{

+  IA32_EFLAGS32                     EFlags;

+

+  EFlags.UintN = AsmReadEflags ();

+  return (BOOLEAN)(EFlags.Bits.IF == 1);

+}

+

+//

+// Ia32 and x64 specific functions

+//

+

+/**

+  Reads the current Global Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current GDTR descriptor and returns it in Gdtr. This

+  function is only available on IA-32 and X64.

+

+  If Gdtr is NULL, then ASSERT().

+

+  @param  Gdtr  Pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmReadGdtr (

+  OUT     IA32_DESCRIPTOR           *Gdtr

+  )

+{

+  ASSERT (Gdtr != NULL);

+  InternalX86ReadGdtr (Gdtr);

+}

+

+/**

+  Writes the current Global Descriptor Table Register (GDTR) descriptor.

+

+  Writes and the current GDTR descriptor specified by Gdtr. This function is

+  only available on IA-32 and X64.

+

+  If Gdtr is NULL, then ASSERT().

+

+  @param  Gdtr  Pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmWriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  )

+{

+  ASSERT (Gdtr != NULL);

+  InternalX86WriteGdtr (Gdtr);

+}

+

+/**

+  Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current IDTR descriptor and returns it in Idtr. This

+  function is only available on IA-32 and X64.

+

+  If Idtr is NULL, then ASSERT().

+

+  @param  Idtr  Pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  )

+{

+  ASSERT (Idtr != NULL);

+  InternalX86ReadIdtr (Idtr);

+}

+

+/**

+  Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Writes the current IDTR descriptor and returns it in Idtr. This function is

+  only available on IA-32 and X64.

+

+  If Idtr is NULL, then ASSERT().

+

+  @param  Idtr  Pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+AsmWriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  )

+{

+  ASSERT (Idtr != NULL);

+  InternalX86WriteIdtr (Idtr);

+}

+

+/**

+  Save the current floating point/SSE/SSE2 context to a buffer.

+

+  Saves the current floating point/SSE/SSE2 state to the buffer specified by

+  Buffer. Buffer must be aligned on a 16-byte boundary. This function is only

+  available on IA-32 and X64.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  Buffer  Pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+AsmFxSave (

+  OUT     IA32_FX_BUFFER            *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & 0xf) == 0);

+  InternalX86FxSave (Buffer);

+}

+

+/**

+  Restores the current floating point/SSE/SSE2 context from a buffer.

+

+  Restores the current floating point/SSE/SSE2 state from the buffer specified

+  by Buffer. Buffer must be aligned on a 16-byte boundary. This function is

+  only available on IA-32 and X64.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-byte boundary, then ASSERT().

+  If Buffer was not saved with AsmFxSave(), then ASSERT().

+

+  @param  Buffer  Pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+AsmFxRestore (

+  IN CONST IA32_FX_BUFFER  *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & 0xf) == 0);

+  InternalX86FxRestore (Buffer);

+}

+

+/**

+  Enables the 32-bit paging mode on the CPU.

+

+  Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables

+  must be properly initialized prior to calling this service. This function

+  assumes the current execution mode is 32-bit protected mode. This function is

+  only available on IA-32. After the 32-bit paging mode is enabled, control is

+  transferred to the function specified by EntryPoint using the new stack

+  specified by NewStack and passing in the parameters specified by Context1 and

+  Context2. Context1 and Context2 are optional and may be NULL. The function

+  EntryPoint must never return.

+

+  If the current execution mode is not 32-bit protected mode, then ASSERT().

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  There are a number of constraints that must be followed before calling this

+  function:

+  1)  Interrupts must be disabled.

+  2)  The caller must be in 32-bit protected mode with flat descriptors. This

+      means all descriptors must have a base of 0 and a limit of 4GB.

+  3)  CR0 and CR4 must be compatible with 32-bit protected mode with flat

+      descriptors.

+  4)  CR3 must point to valid page tables that will be used once the transition

+      is complete, and those page tables must guarantee that the pages for this

+      function and the stack are identity mapped.

+

+  @param  EntryPoint  A pointer to function to call with the new stack after

+                      paging is enabled.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function as the first parameter after paging is enabled.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function as the second parameter after paging is enabled.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function after paging is enabled.

+

+**/

+VOID

+EFIAPI

+AsmEnablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  ASSERT (EntryPoint != NULL);

+  ASSERT (NewStack != NULL);

+  InternalX86EnablePaging32 (EntryPoint, Context1, Context2, NewStack);

+}

+

+/**

+  Disables the 32-bit paging mode on the CPU.

+

+  Disables the 32-bit paging mode on the CPU and returns to 32-bit protected

+  mode. This function assumes the current execution mode is 32-paged protected

+  mode. This function is only available on IA-32. After the 32-bit paging mode

+  is disabled, control is transferred to the function specified by EntryPoint

+  using the new stack specified by NewStack and passing in the parameters

+  specified by Context1 and Context2. Context1 and Context2 are optional and

+  may be NULL. The function EntryPoint must never return.

+

+  If the current execution mode is not 32-bit paged mode, then ASSERT().

+  If EntryPoint is NULL, then ASSERT().

+  If NewStack is NULL, then ASSERT().

+

+  There are a number of constraints that must be followed before calling this

+  function:

+  1)  Interrupts must be disabled.

+  2)  The caller must be in 32-bit paged mode.

+  3)  CR0, CR3, and CR4 must be compatible with 32-bit paged mode.

+  4)  CR3 must point to valid page tables that guarantee that the pages for

+      this function and the stack are identity mapped.

+

+  @param  EntryPoint  A pointer to function to call with the new stack after

+                      paging is disabled.

+  @param  Context1    A pointer to the context to pass into the EntryPoint

+                      function as the first parameter after paging is disabled.

+  @param  Context2    A pointer to the context to pass into the EntryPoint

+                      function as the second parameter after paging is

+                      disabled.

+  @param  NewStack    A pointer to the new stack to use for the EntryPoint

+                      function after paging is disabled.

+

+**/

+VOID

+EFIAPI

+AsmDisablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  ASSERT (EntryPoint != NULL);

+  ASSERT (NewStack != NULL);

+  InternalX86DisablePaging32 (EntryPoint, Context1, Context2, NewStack);

+}

+

+/**

+  Enables the 64-bit paging mode on the CPU.

+

+  Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables

+  must be properly initialized prior to calling this service. This function

+  assumes the current execution mode is 32-bit protected mode with flat

+  descriptors. This function is only available on IA-32. After the 64-bit

+  paging mode is enabled, control is transferred to the function specified by

+  EntryPoint using the new stack specified by NewStack and passing in the

+  parameters specified by Context1 and Context2. Context1 and Context2 are

+  optional and may be 0. The function EntryPoint must never return.

+

+  If the current execution mode is not 32-bit protected mode with flat

+  descriptors, then ASSERT().

+  If EntryPoint is 0, then ASSERT().

+  If NewStack is 0, then ASSERT().

+

+  @param  Cs          The 16-bit selector to load in the CS before EntryPoint

+                      is called. The descriptor in the GDT that this selector

+                      references must be setup for long mode.

+  @param  EntryPoint  The 64-bit virtual address of the function to call with

+                      the new stack after paging is enabled.

+  @param  Context1    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the first parameter after

+                      paging is enabled.

+  @param  Context2    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the second parameter after

+                      paging is enabled.

+  @param  NewStack    The 64-bit virtual address of the new stack to use for

+                      the EntryPoint function after paging is enabled.

+

+**/

+VOID

+EFIAPI

+AsmEnablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT64                    EntryPoint,

+  IN      UINT64                    Context1,  OPTIONAL

+  IN      UINT64                    Context2,  OPTIONAL

+  IN      UINT64                    NewStack

+  )

+{

+  ASSERT (EntryPoint != 0);

+  ASSERT (NewStack != 0);

+  InternalX86EnablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);

+}

+

+/**

+  Disables the 64-bit paging mode on the CPU.

+

+  Disables the 64-bit paging mode on the CPU and returns to 32-bit protected

+  mode. This function assumes the current execution mode is 64-paging mode.

+  This function is only available on X64. After the 64-bit paging mode is

+  disabled, control is transferred to the function specified by EntryPoint

+  using the new stack specified by NewStack and passing in the parameters

+  specified by Context1 and Context2. Context1 and Context2 are optional and

+  may be 0. The function EntryPoint must never return.

+

+  If the current execution mode is not 64-bit paged mode, then ASSERT().

+  If EntryPoint is 0, then ASSERT().

+  If NewStack is 0, then ASSERT().

+

+  @param  Cs          The 16-bit selector to load in the CS before EntryPoint

+                      is called. The descriptor in the GDT that this selector

+                      references must be setup for 32-bit protected mode.

+  @param  EntryPoint  The 64-bit virtual address of the function to call with

+                      the new stack after paging is disabled.

+  @param  Context1    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the first parameter after

+                      paging is disabled.

+  @param  Context2    The 64-bit virtual address of the context to pass into

+                      the EntryPoint function as the second parameter after

+                      paging is disabled.

+  @param  NewStack    The 64-bit virtual address of the new stack to use for

+                      the EntryPoint function after paging is disabled.

+

+**/

+VOID

+EFIAPI

+AsmDisablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT32                    EntryPoint,

+  IN      UINT32                    Context1,  OPTIONAL

+  IN      UINT32                    Context2,  OPTIONAL

+  IN      UINT32                    NewStack

+  )

+{

+  ASSERT (EntryPoint != 0);

+  ASSERT (NewStack != 0);

+  InternalX86DisablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);

+}

+

+//

+// x86 version of MemoryFence()

+//

+

+/**

+  Used to serialize load and store operations.

+

+  All loads and stores that proceed calls to this function are guaranteed to be

+  globally visible when this function returns.

+

+**/

+VOID

+EFIAPI

+MemoryFence (

+  VOID

+  )

+{

+}

diff --git a/edk2/MdePkg/Library/BaseLib/x86Thunk.c b/edk2/MdePkg/Library/BaseLib/x86Thunk.c
new file mode 100644
index 0000000..9e69255
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseLib/x86Thunk.c
@@ -0,0 +1,242 @@
+/** @file

+  Real Mode Thunk Functions for IA32 and X64.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  x86Thunk.c

+

+**/

+

+//

+// Byte packed structure for a segment descriptor in a GDT/LDT

+//

+typedef union {

+  struct {

+    UINT32  LimitLow:16;

+    UINT32  BaseLow:16;

+    UINT32  BaseMid:8;

+    UINT32  Type:4;

+    UINT32  S:1;

+    UINT32  DPL:2;

+    UINT32  P:1;

+    UINT32  LimitHigh:4;

+    UINT32  AVL:1;

+    UINT32  L:1;

+    UINT32  DB:1;

+    UINT32  G:1;

+    UINT32  BaseHigh:8;

+  } Bits;

+  UINT64  Uint64;

+} IA32_SEGMENT_DESCRIPTOR;

+

+extern CONST UINT8                  m16Start;

+extern CONST UINT16                 m16Size;

+extern CONST UINT16                 mThunk16Attr;

+extern CONST UINT16                 m16Gdt;

+extern CONST UINT16                 m16GdtrBase;

+extern CONST UINT16                 mTransition;

+

+/**

+  Invokes 16-bit code in big real mode and returns the updated register set.

+

+  This function transfers control to the 16-bit code specified by CS:EIP using

+  the stack specified by SS:ESP in RegisterSet. The updated registers are saved

+  on the real mode stack and the starting address of the save area is returned.

+

+  @param  RegisterSet Values of registers before invocation of 16-bit code.

+  @param  Transition  Pointer to the transition code under 1MB.

+

+  @return The pointer to a IA32_REGISTER_SET structure containing the updated

+          register values.

+

+**/

+IA32_REGISTER_SET *

+InternalAsmThunk16 (

+  IN      IA32_REGISTER_SET         *RegisterSet,

+  IN OUT  VOID                      *Transition

+  );

+

+/**

+  Retrieves the properties for 16-bit thunk functions.

+

+  Computes the size of the buffer and stack below 1MB required to use the

+  AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This

+  buffer size is returned in RealModeBufferSize, and the stack size is returned

+  in ExtraStackSize. If parameters are passed to the 16-bit real mode code,

+  then the actual minimum stack size is ExtraStackSize plus the maximum number

+  of bytes that need to be passed to the 16-bit real mode code.

+

+  If RealModeBufferSize is NULL, then ASSERT().

+  If ExtraStackSize is NULL, then ASSERT().

+

+  @param  RealModeBufferSize  A pointer to the size of the buffer below 1MB

+                              required to use the 16-bit thunk functions.

+  @param  ExtraStackSize      A pointer to the extra size of stack below 1MB

+                              that the 16-bit thunk functions require for

+                              temporary storage in the transition to and from

+                              16-bit real mode.

+

+**/

+VOID

+EFIAPI

+AsmGetThunk16Properties (

+  OUT     UINT32                    *RealModeBufferSize,

+  OUT     UINT32                    *ExtraStackSize

+  )

+{

+  ASSERT (RealModeBufferSize != NULL);

+  ASSERT (ExtraStackSize != NULL);

+

+  *RealModeBufferSize = m16Size;

+

+  //

+  // Extra 4 bytes for return address, and another 4 bytes for mode transition

+  //

+  *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8;

+}

+

+/**

+  Prepares all structures a code required to use AsmThunk16().

+

+  Prepares all structures and code required to use AsmThunk16().

+

+  If ThunkContext is NULL, then ASSERT().

+

+  @param  ThunkContext  A pointer to the context structure that describes the

+                        16-bit real mode code to call.

+

+**/

+VOID

+EFIAPI

+AsmPrepareThunk16 (

+  OUT     THUNK_CONTEXT             *ThunkContext

+  )

+{

+  IA32_SEGMENT_DESCRIPTOR           *RealModeGdt;

+

+  ASSERT (ThunkContext != NULL);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);

+  ASSERT (ThunkContext->RealModeBufferSize >= m16Size);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);

+

+  CopyMem (ThunkContext->RealModeBuffer, &m16Start, m16Size);

+

+  //

+  // Point RealModeGdt to the GDT to be used in transition

+  //

+  // RealModeGdt[0]: Reserved as NULL descriptor

+  // RealModeGdt[1]: Code Segment

+  // RealModeGdt[2]: Data Segment

+  // RealModeGdt[3]: Call Gate

+  //

+  RealModeGdt = (IA32_SEGMENT_DESCRIPTOR*)(

+                  (UINTN)ThunkContext->RealModeBuffer + m16Gdt);

+

+  //

+  // Update Code & Data Segment Descriptor

+  //

+  RealModeGdt[1].Bits.BaseLow =

+    (UINT32)(UINTN)ThunkContext->RealModeBuffer & ~0xf;

+  RealModeGdt[1].Bits.BaseMid =

+    (UINT32)(UINTN)ThunkContext->RealModeBuffer >> 16;

+

+  //

+  // Update transition code entry point offset

+  //

+  *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mTransition) +=

+    (UINT32)(UINTN)ThunkContext->RealModeBuffer & 0xf;

+

+  //

+  // Update Segment Limits for both Code and Data Segment Descriptors

+  //

+  if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) {

+    //

+    // Set segment limits to 64KB

+    //

+    RealModeGdt[1].Bits.LimitHigh = 0;

+    RealModeGdt[1].Bits.G = 0;

+    RealModeGdt[2].Bits.LimitHigh = 0;

+    RealModeGdt[2].Bits.G = 0;

+  }

+

+  //

+  // Update GDTBASE for this thunk context

+  //

+  *(VOID**)((UINTN)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt;

+

+  //

+  // Update Thunk Attributes

+  //

+  *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mThunk16Attr) =

+    ThunkContext->ThunkAttributes;

+}

+

+/**

+  Transfers control to a 16-bit real mode entry point and returns the results.

+

+  Transfers control to a 16-bit real mode entry point and returns the results.

+  AsmPrepareThunk16() must be called with ThunkContext before this function is

+  used. This function must be called with interrupts disabled.

+

+  If ThunkContext is NULL, then ASSERT().

+  If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().

+

+  @param  ThunkContext  A pointer to the context structure that describes the

+                        16-bit real mode code to call.

+

+**/

+VOID

+EFIAPI

+AsmThunk16 (

+  IN OUT  THUNK_CONTEXT             *ThunkContext

+  )

+{

+  IA32_REGISTER_SET                 *UpdatedRegs;

+

+  ASSERT (ThunkContext != NULL);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);

+  ASSERT (ThunkContext->RealModeBufferSize >= m16Size);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);

+

+  UpdatedRegs = InternalAsmThunk16 (

+                  ThunkContext->RealModeState,

+                  ThunkContext->RealModeBuffer

+                  );

+

+  CopyMem (ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs));

+}

+

+/**

+  Prepares all structures and code for a 16-bit real mode thunk, transfers

+  control to a 16-bit real mode entry point, and returns the results.

+

+  Prepares all structures and code for a 16-bit real mode thunk, transfers

+  control to a 16-bit real mode entry point, and returns the results. If the

+  caller only need to perform a single 16-bit real mode thunk, then this

+  service should be used. If the caller intends to make more than one 16-bit

+  real mode thunk, then it is more efficient if AsmPrepareThunk16() is called

+  once and AsmThunk16() can be called for each 16-bit real mode thunk. This

+  function must be called with interrupts disabled.

+

+  If ThunkContext is NULL, then ASSERT().

+

+  @param  ThunkContext  A pointer to the context structure that describes the

+                        16-bit real mode code to call.

+

+**/

+VOID

+EFIAPI

+AsmPrepareAndThunk16 (

+  IN OUT  THUNK_CONTEXT             *ThunkContext

+  )

+{

+  AsmPrepareThunk16 (ThunkContext);

+  AsmThunk16 (ThunkContext);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.mbd b/edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.mbd
new file mode 100644
index 0000000..767de2f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseMemoryLib</BaseName>

+    <Guid>fd44e603-002a-4b29-9f5f-529e815b6165</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:55</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.msa b/edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.msa
new file mode 100644
index 0000000..eae00d7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.msa
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>fd44e603-002a-4b29-9f5f-529e815b6165</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:55</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>CopyMem.c</Filename>

+    <Filename>MemLibGuid.c</Filename>

+    <Filename>MemLibGeneric.c</Filename>

+    <Filename>CopyMemWrapper.c</Filename>

+    <Filename>SetMemWrapper.c</Filename>

+    <Filename>SetMem16Wrapper.c</Filename>

+    <Filename>SetMem32Wrapper.c</Filename>

+    <Filename>SetMem64Wrapper.c</Filename>

+    <Filename>CompareMemWrapper.c</Filename>

+    <Filename>ZeroMemWrapper.c</Filename>

+    <Filename>ScanMem8Wrapper.c</Filename>

+    <Filename>ScanMem16Wrapper.c</Filename>

+    <Filename>ScanMem32Wrapper.c</Filename>

+    <Filename>ScanMem64Wrapper.c</Filename>

+    <Filename>SetMem.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.c
new file mode 100644
index 0000000..c8199d8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  CompareMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CompareMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)DestinationBuffer + 1);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)SourceBuffer + 1);

+  if (Length == 0) {

+    return 0;

+  }

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/CopyMem.c b/edk2/MdePkg/Library/BaseMemoryLib/CopyMem.c
new file mode 100644
index 0000000..f2106ac
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/CopyMem.c
@@ -0,0 +1,60 @@
+/** @file

+  Implementation of the EfiCopyMem routine. This function is broken

+  out into its own source file so that it can be excluded from a

+  build for a particular platform easily if an optimized version

+  is desired.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  EfiCopyMem.c

+

+**/

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memcpy()

+  //

+  volatile UINT8                    *Destination8;

+  CONST UINT8                       *Source8;

+

+  if (Source > Destination) {

+    Destination8 = (UINT8*)Destination;

+    Source8 = (CONST UINT8*)Source;

+    while (Length-- != 0) {

+      *(Destination8++) = *(Source8++);

+    }

+  } else if (Source < Destination) {

+    Destination8 = (UINT8*)Destination + Length;

+    Source8 = (CONST UINT8*)Source + Length;

+    while (Length-- != 0) {

+      *(--Destination8) = *(--Source8);

+    }

+  }

+  return Destination;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.c
new file mode 100644
index 0000000..5ca62f5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CopyMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CopyMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (

+    Destination == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Destination + 1

+    );

+  ASSERT (

+    Source == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Source + 1

+    );

+  if (Destination == Source || Length == 0) {

+    return Destination;

+  }

+  return InternalMemCopyMem (Destination, Source, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/MemLibGeneric.c b/edk2/MdePkg/Library/BaseMemoryLib/MemLibGeneric.c
new file mode 100644
index 0000000..bda1f49
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/MemLibGeneric.c
@@ -0,0 +1,266 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGeneric.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length > 0);

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/MemLibGuid.c b/edk2/MdePkg/Library/BaseMemoryLib/MemLibGuid.c
new file mode 100644
index 0000000..c54983c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/MemLibGuid.c
@@ -0,0 +1,139 @@
+/** @file

+  Implementation of GUID functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGuid.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  )

+{

+  return (BOOLEAN)(

+           ReadUnaligned64 ((CONST UINT64*)Guid1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&

+           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)

+           );

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (Buffer != NULL);

+  //

+  // Make sure Buffer is aligned on a 64-bit boundary.

+  //

+  ASSERT (((UINTN) Buffer & 7) == 0);

+

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/MemLibInternals.h b/edk2/MdePkg/Library/BaseMemoryLib/MemLibInternals.h
new file mode 100644
index 0000000..ca7311a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/MemLibInternals.h
@@ -0,0 +1,230 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibInternals.h

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.c
new file mode 100644
index 0000000..a17705d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.c
new file mode 100644
index 0000000..67eb84d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.c
new file mode 100644
index 0000000..c5f0762
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.c
new file mode 100644
index 0000000..9b817b1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  ScanMem8() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem8Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/SetMem.c b/edk2/MdePkg/Library/BaseMemoryLib/SetMem.c
new file mode 100644
index 0000000..bd7fee0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/SetMem.c
@@ -0,0 +1,51 @@
+/** @file

+  Implementation of the EfiSetMem routine. This function is broken

+  out into its own source file so that it can be excluded from a

+  build for a particular platform easily if an optimized version

+  is desired.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  EfiSetMem.c

+

+**/

+

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memset()

+  //

+  volatile UINT8                    *Pointer;

+

+  Pointer = (UINT8*)Buffer;

+  while (Size-- != 0) {

+    *(Pointer++) = Value;

+  }

+  return Buffer;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.c
new file mode 100644
index 0000000..3acbdac
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.c
new file mode 100644
index 0000000..620b69a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.c
new file mode 100644
index 0000000..73c28af
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
new file mode 100644
index 0000000..294a27a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  SetMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Size <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  return InternalMemSetMem (Buffer, Size, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.c
new file mode 100644
index 0000000..4a3d615
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ZeroMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemSetMem (Buffer, Length, 0);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLib/build.xml b/edk2/MdePkg/Library/BaseMemoryLib/build.xml
new file mode 100644
index 0000000..040f139
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseMemoryLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseMemoryLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseMemoryLib">

+      <GenBuild baseName="BaseMemoryLib" mbdFilename="${MODULE_DIR}/BaseMemoryLib.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLib.msa"/>

+   </target>

+   <target depends="BaseMemoryLib_clean" name="clean"/>

+   <target depends="BaseMemoryLib_cleanall" name="cleanall"/>

+   <target name="BaseMemoryLib_clean">

+      <OutputDirSetup baseName="BaseMemoryLib" mbdFilename="${MODULE_DIR}/BaseMemoryLib.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseMemoryLib_cleanall">

+      <OutputDirSetup baseName="BaseMemoryLib" mbdFilename="${MODULE_DIR}/BaseMemoryLib.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseMemoryLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx-Gcc.msa b/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx-Gcc.msa
new file mode 100644
index 0000000..83db200
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx-Gcc.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLibMmx</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>d458a654-f64c-49db-b8d1-3821306bf1f6</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 19:53</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CopyMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ZeroMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem16.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CompareMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem8.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem16.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem64.s</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.mbd b/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.mbd
new file mode 100644
index 0000000..adea3a0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseMemoryLibMmx</BaseName>

+    <Guid>d458a654-f64c-49db-b8d1-3821306bf1f6</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 19:53</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa b/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa
new file mode 100644
index 0000000..d212557
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLibMmx</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>d458a654-f64c-49db-b8d1-3821306bf1f6</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 19:53</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>Ia32/CopyMem.asm</Filename>

+      <Filename>Ia32/SetMem.asm</Filename>

+      <Filename>Ia32/ZeroMem.asm</Filename>

+      <Filename>Ia32/SetMem16.asm</Filename>

+      <Filename>Ia32/SetMem32.asm</Filename>

+      <Filename>Ia32/SetMem64.asm</Filename>

+      <Filename>Ia32/CompareMem.asm</Filename>

+      <Filename>Ia32/ScanMem8.asm</Filename>

+      <Filename>Ia32/ScanMem16.asm</Filename>

+      <Filename>Ia32/ScanMem32.asm</Filename>

+      <Filename>Ia32/ScanMem64.asm</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/CompareMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/CompareMemWrapper.c
new file mode 100644
index 0000000..c8199d8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/CompareMemWrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  CompareMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CompareMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)DestinationBuffer + 1);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)SourceBuffer + 1);

+  if (Length == 0) {

+    return 0;

+  }

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/CopyMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/CopyMemWrapper.c
new file mode 100644
index 0000000..5ca62f5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/CopyMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CopyMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CopyMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (

+    Destination == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Destination + 1

+    );

+  ASSERT (

+    Source == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Source + 1

+    );

+  if (Destination == Source || Length == 0) {

+    return Destination;

+  }

+  return InternalMemCopyMem (Destination, Source, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.asm
new file mode 100644
index 0000000..3cf6fe7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.s
new file mode 100644
index 0000000..6bce0e1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.s
@@ -0,0 +1,50 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CompareMem.Asm
+#
+# Abstract:
+#
+#   CompareMem function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemCompareMem
+_InternalMemCompareMem:
+    push    %esi
+    push    %edi
+    movl    12(%esp), %esi
+    movl    16(%esp), %edi
+    movl    20(%esp), %ecx
+    repe    cmpsb
+    movzbl  -1(%esi), %eax
+    movzbl  -1(%edi), %edx
+    subl    %edx, %eax
+    subl    %edx, %eax
+    pop     %edi
+    pop     %esi
+    ret
+
+
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.asm
new file mode 100644
index 0000000..b709a80
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.asm
@@ -0,0 +1,86 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_CopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [edi + edx - 1]        ; eax <- End of Destination

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, esi                    ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     ecx, ecx

+    sub     ecx, esi

+    and     ecx, 7                      ; ecx + esi aligns on 8-byte boundary

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx                    ; edx <- remaining bytes to copy

+    rep     movsb

+@@:

+    mov     ecx, edx

+    and     edx, 7

+    shr     ecx, 3                      ; ecx <- # of Qwords to copy

+    jz      @CopyBytes

+    push    eax

+    push    eax

+    movq    [esp], mm0                  ; save mm0

+@@:

+    movq    mm0, [esi]

+    movntq  [edi], mm0

+    add     esi, 8

+    add     edi, 8

+    loop    @B

+    mfence

+    movq    mm0, [esp]                  ; restore mm0

+    pop     ecx                         ; stack cleanup

+    pop     ecx                         ; stack cleanup

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     edi, eax                    ; edi <- Last byte in Destination

+    lea     esi, [esi + edx - 1]        ; esi <- Last byte in Source

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb

+    cld

+    mov     eax, [esp + 12]

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.s
new file mode 100644
index 0000000..56788cb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.s
@@ -0,0 +1,90 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CopyMem.asm
+#
+# Abstract:
+#
+#   CopyMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_CopyMem (
+#    IN VOID   *Destination,
+#    IN VOID   *Source,
+#    IN UINTN  Count
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemCopyMem
+_InternalMemCopyMem:
+    push    %esi
+    push    %edi
+    movl    16(%esp), %esi              # esi <- Source
+    movl    12(%esp), %edi              # edi <- Destination
+    movl    20(%esp), %edx              # edx <- Count
+    leal    -1(%edi,%edx,), %eax        # eax <- End of Destination
+    cmpl    %edi, %esi
+    jae     L0
+    cmpl    %esi, %eax                  # Overlapped?
+    jae     @CopyBackward               # Copy backward if overlapped
+L0: 
+    xorl    %ecx, %ecx
+    subl    %esi, %ecx
+    andl    $7, %ecx                    # ecx + esi aligns on 8-byte boundary
+    jz      L1
+    cmpl    %edx, %ecx
+    cmova   %edx, %ecx
+    subl    %ecx, %edx                  # edx <- remaining bytes to copy
+    rep
+    movsb
+L1: 
+    movl    %edx, %ecx
+    andl    $7, %edx
+    shrl    $3, %ecx                    # ecx <- # of Qwords to copy
+    jz      @CopyBytes
+    pushl   %eax
+    pushl   %eax
+    movq    %mm0, (%esp)                # save mm0
+L2: 
+    movq    (%esi), %mm0
+    movntq  %mm0, (%edi)
+    addl    $8, %esi
+    addl    $8, %edi
+    loop    L2
+    mfence
+    movq    (%esp), %mm0                # restore mm0
+    popl    %ecx                        # stack cleanup
+    popl    %ecx                        # stack cleanup
+    jmp     @CopyBytes
+@CopyBackward: 
+    movl    %eax, %edi                  # edi <- Last byte in Destination
+    leal    -1(%esi,%edx,), %esi        # esi <- Last byte in Source
+    std
+@CopyBytes: 
+    movl    %edx, %ecx
+    rep
+    movsb
+    cld
+    movl    12(%esp), %eax
+    push    %esi
+    push    %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..7071942
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.s
new file mode 100644
index 0000000..e23799e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem16.Asm
+#
+# Abstract:
+#
+#   ScanMem16 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem16
+_InternalMemScanMem16:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movl    16(%esp), %eax
+    repne   scasw
+    leal    -2(%edi), %eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
+
+
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..e6aaf02
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.s
new file mode 100644
index 0000000..6b4a919
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem32.Asm
+#
+# Abstract:
+#
+#   ScanMem32 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem32
+_InternalMemScanMem32:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movl    16(%esp), %eax
+    repne   scasl
+    leal    -4(%edi), %eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..f9725a4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.s
new file mode 100644
index 0000000..00f6d74
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.s
@@ -0,0 +1,53 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem64.Asm
+#
+# Abstract:
+#
+#   ScanMem64 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem64
+_InternalMemScanMem64:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    16(%esp), %eax
+    movl    20(%esp), %edx
+    movl    8(%esp), %edi
+L0: 
+    cmpl    (%edi), %eax
+    leal    8(%edi), %edi
+    loopne  L0
+    jne     L1
+    cmpl    -4(%edi), %edx
+    jecxz   L1
+    jne     L0
+L1: 
+    leal    -8(%edi), %eax
+    cmovne  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..6ae1900
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.s
new file mode 100644
index 0000000..5764037
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem8.Asm
+#
+# Abstract:
+#
+#   ScanMem8 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem8
+_InternalMemScanMem8:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movb    16(%esp), %al
+    repne   scasb
+    leal    -1(%edi), %eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.asm
new file mode 100644
index 0000000..f2c55f1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov     ecx, [esp + 12]             ; ecx <- Count

+    mov     edi, [esp + 8]              ; edi <- Buffer

+    mov     edx, ecx

+    shr     ecx, 3                      ; # of Qwords to set

+    mov     al, [esp + 16]              ; al <- Value

+    jz      @SetBytes

+    mov     ah, al                      ; ax <- Value | (Value << 8)

+    push    ecx

+    push    ecx

+    movq    [esp], mm0                  ; save mm0

+    movd    mm0, eax

+    pshufw  mm0, mm0, 0                 ; fill mm0 with 8 Value's

+@@:

+    movntq  [edi], mm0

+    add     edi, 8

+    loop    @B

+    mfence

+    movq    mm0, [esp]                  ; restore mm0

+    pop     ecx                         ; stack cleanup

+    pop     ecx

+@SetBytes:

+    and     edx, 7

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]              ; eax <- Buffer as return value

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.s
new file mode 100644
index 0000000..8a893f8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.s
@@ -0,0 +1,67 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem.asm
+#
+# Abstract:
+#
+#   SetMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT8  Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem
+_InternalMemSetMem:
+    push    %edi
+    movl    12(%esp), %ecx              # ecx <- Count
+    movl    8(%esp), %edi               # edi <- Buffer
+    movl    %ecx, %edx
+    shrl    $3, %ecx                    # # of Qwords to set
+    movb    16(%esp), %al               # al <- Value
+    jz      @SetBytes
+    movb    %al, %ah                    # ax <- Value | (Value << 8)
+    pushl   %ecx
+    pushl   %ecx
+    movq    %mm0, (%esp)                # save mm0
+    movd    %eax, %mm0
+    pshufw  $0x0,%mm0,%mm0
+L0: 
+    movntq  %mm0, (%edi)
+    addl    $8, %edi
+    loop    L0
+    mfence
+    movq    (%esp), %mm0                # restore mm0
+    popl    %ecx                        # stack cleanup
+    popl    %ecx
+@SetBytes: 
+    andl    $7, %edx
+    movl    %edx, %ecx
+    rep
+    stosb
+    movl    8(%esp), %eax               # eax <- Buffer as return value
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.asm
new file mode 100644
index 0000000..f9dc533
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.asm
@@ -0,0 +1,59 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     ecx, edx

+    and     edx, 3

+    shr     ecx, 2

+    mov     eax, [esp + 16]

+    jz      @SetWords

+    movd    mm0, eax

+    pshufw  mm0, mm0, 0

+@@:

+    movntq  [edi], mm0

+    add     edi, 8

+    loop    @B

+    mfence

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.s
new file mode 100644
index 0000000..bcbd49e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.s
@@ -0,0 +1,60 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem16.asm
+#
+# Abstract:
+#
+#   SetMem16 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem16 (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT16 Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem16
+_InternalMemSetMem16:
+    push    %edi
+    movl    12(%esp), %edx
+    movl    8(%esp), %edi
+    movl    %edx, %ecx
+    andl    $3, %edx
+    shrl    $2, %ecx
+    movl    16(%esp), %eax
+    jz      @SetWords
+    movd    %eax, %mm0
+    pshufw  $0, %mm0, %mm0
+L0: 
+    movntq  %mm0, (%edi)
+    addl    $8, %edi
+    loop    L0
+    mfence
+@SetWords: 
+    movl    %edx, %ecx
+    rep
+    stosw
+    movl    8(%esp), %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.asm
new file mode 100644
index 0000000..7f24fcd
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.asm
@@ -0,0 +1,59 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    edi

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     ecx, edx

+    shr     ecx, 1

+    movd    mm0, [esp + 16]

+    mov     eax, edi

+    jz      @SetDwords

+    pshufw  mm0, mm0, 44h

+@@:

+    movntq  [edi], mm0

+    add     edi, 8

+    loop    @B

+    mfence

+@SetDwords:

+    test    dl, 1

+    jz      @F

+    movd    [edi], mm0

+@@:

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.s
new file mode 100644
index 0000000..a1a0eaf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.s
@@ -0,0 +1,59 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem32.asm
+#
+# Abstract:
+#
+#   SetMem32 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem32 (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT32 Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem32
+_InternalMemSetMem32:
+    push    %edi
+    movl    12(%esp), %edx
+    movl    8(%esp), %edi
+    movl    %edx, %ecx
+    shrl    %ecx
+    movd    16(%esp), %mm0
+    movl    %edi, %eax
+    jz      @SetDwords
+    pshufw  $0x44, %mm0, %mm0
+L0: 
+    movntq  %mm0, (%edi)
+    addl    $8, %edi
+    loopl   L0
+    mfence
+@SetDwords: 
+    testb   $1, %dl
+    jz      @F
+    movd    %mm0, (%edi)
+L1: 
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.asm
new file mode 100644
index 0000000..b607608
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.asm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    edi

+    movq    mm0, [esp + 16]

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, edi

+@@:

+    movntq  [edi], mm0

+    add     edi, 8

+    loop    @B

+    mfence

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.s
new file mode 100644
index 0000000..9699581
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.s
@@ -0,0 +1,50 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem64.asm
+#
+# Abstract:
+#
+#   SetMem64 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem64 (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT64 Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem64
+_InternalMemSetMem64:
+    push    %edi
+    movq    16(%esp), %mm0
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movl    %edi, %eax
+L0: 
+    movntq  %mm0, (%edi)
+    addl    $8, %edi
+    loopl   L0
+    mfence
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.asm b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..31ef120
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_ZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edx, ecx

+    shr     ecx, 3

+    jz      @ZeroBytes

+    pxor    mm0, mm0

+@@:

+    movntq  [edi], mm0

+    add     edi, 8

+    loop    @B

+    mfence

+@ZeroBytes:

+    and     edx, 7

+    xor     eax, eax

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.s b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.s
new file mode 100644
index 0000000..0bb19c7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.s
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ZeroMem.asm
+#
+# Abstract:
+#
+#   ZeroMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_ZeroMem (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemZeroMem
+_InternalMemZeroMem:
+    push    %edi
+    movl    8(%esp), %edi
+    movl    12(%esp), %ecx
+    movl    %ecx, %edx
+    shrl    $3, %ecx
+    jz      @ZeroBytes
+    pxor    %mm0, %mm0
+L0: 
+    movntq  %mm0, (%edi)
+    addl    $8, %edi
+    loop    L0
+    mfence
+@ZeroBytes: 
+    andl    $7, %edx
+    xorl    %eax, %eax
+    movl    %edx, %ecx
+    rep
+    stosb
+    movl    8(%esp), %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibGuid.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibGuid.c
new file mode 100644
index 0000000..c54983c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibGuid.c
@@ -0,0 +1,139 @@
+/** @file

+  Implementation of GUID functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGuid.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  )

+{

+  return (BOOLEAN)(

+           ReadUnaligned64 ((CONST UINT64*)Guid1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&

+           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)

+           );

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (Buffer != NULL);

+  //

+  // Make sure Buffer is aligned on a 64-bit boundary.

+  //

+  ASSERT (((UINTN) Buffer & 7) == 0);

+

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibInternals.h b/edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibInternals.h
new file mode 100644
index 0000000..ca7311a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibInternals.h
@@ -0,0 +1,230 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibInternals.h

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem16Wrapper.c
new file mode 100644
index 0000000..a17705d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem16Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem32Wrapper.c
new file mode 100644
index 0000000..67eb84d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem64Wrapper.c
new file mode 100644
index 0000000..c5f0762
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem64Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem8Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem8Wrapper.c
new file mode 100644
index 0000000..9b817b1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem8Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  ScanMem8() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem8Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem16Wrapper.c
new file mode 100644
index 0000000..3acbdac
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem32Wrapper.c
new file mode 100644
index 0000000..620b69a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem64Wrapper.c
new file mode 100644
index 0000000..73c28af
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
new file mode 100644
index 0000000..294a27a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  SetMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Size <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  return InternalMemSetMem (Buffer, Size, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/ZeroMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibMmx/ZeroMemWrapper.c
new file mode 100644
index 0000000..4a3d615
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ZeroMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemSetMem (Buffer, Length, 0);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibMmx/build.xml b/edk2/MdePkg/Library/BaseMemoryLibMmx/build.xml
new file mode 100644
index 0000000..8b72825
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibMmx/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseMemoryLibMmx"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseMemoryLibMmx"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseMemoryLibMmx">

+      <GenBuild baseName="BaseMemoryLibMmx" mbdFilename="${MODULE_DIR}/BaseMemoryLibMmx.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibMmx.msa"/>

+   </target>

+   <target depends="BaseMemoryLibMmx_clean" name="clean"/>

+   <target depends="BaseMemoryLibMmx_cleanall" name="cleanall"/>

+   <target name="BaseMemoryLibMmx_clean">

+      <OutputDirSetup baseName="BaseMemoryLibMmx" mbdFilename="${MODULE_DIR}/BaseMemoryLibMmx.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibMmx.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLibMmx_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLibMmx_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseMemoryLibMmx_cleanall">

+      <OutputDirSetup baseName="BaseMemoryLibMmx" mbdFilename="${MODULE_DIR}/BaseMemoryLibMmx.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibMmx.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLibMmx_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLibMmx_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseMemoryLibMmx*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr-Gcc.msa b/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr-Gcc.msa
new file mode 100644
index 0000000..c7b7b77
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr-Gcc.msa
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLibRepStr</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e7884bf4-51a1-485b-982a-ff89129983bc</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CopyMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem16.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ZeroMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CompareMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem8.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem16.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem64.s</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>x64/CopyMem.asm</Filename>

+      <Filename>x64/SetMem.asm</Filename>

+      <Filename>x64/SetMem16.asm</Filename>

+      <Filename>x64/SetMem32.asm</Filename>

+      <Filename>x64/SetMem64.asm</Filename>

+      <Filename>x64/ZeroMem.asm</Filename>

+      <Filename>x64/CompareMem.asm</Filename>

+      <Filename>x64/ScanMem8.asm</Filename>

+      <Filename>x64/ScanMem16.asm</Filename>

+      <Filename>x64/ScanMem32.asm</Filename>

+      <Filename>x64/ScanMem64.asm</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.mbd b/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.mbd
new file mode 100644
index 0000000..400ca94
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseMemoryLibRepStr</BaseName>

+    <Guid>e7884bf4-51a1-485b-982a-ff89129983bc</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.msa b/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.msa
new file mode 100644
index 0000000..aa06791
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.msa
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLibRepStr</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e7884bf4-51a1-485b-982a-ff89129983bc</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>Ia32/CopyMem.asm</Filename>

+      <Filename>Ia32/SetMem.asm</Filename>

+      <Filename>Ia32/SetMem16.asm</Filename>

+      <Filename>Ia32/SetMem32.asm</Filename>

+      <Filename>Ia32/SetMem64.asm</Filename>

+      <Filename>Ia32/ZeroMem.asm</Filename>

+      <Filename>Ia32/CompareMem.asm</Filename>

+      <Filename>Ia32/ScanMem8.asm</Filename>

+      <Filename>Ia32/ScanMem16.asm</Filename>

+      <Filename>Ia32/ScanMem32.asm</Filename>

+      <Filename>Ia32/ScanMem64.asm</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>x64/CopyMem.asm</Filename>

+      <Filename>x64/SetMem.asm</Filename>

+      <Filename>x64/SetMem16.asm</Filename>

+      <Filename>x64/SetMem32.asm</Filename>

+      <Filename>x64/SetMem64.asm</Filename>

+      <Filename>x64/ZeroMem.asm</Filename>

+      <Filename>x64/CompareMem.asm</Filename>

+      <Filename>x64/ScanMem8.asm</Filename>

+      <Filename>x64/ScanMem16.asm</Filename>

+      <Filename>x64/ScanMem32.asm</Filename>

+      <Filename>x64/ScanMem64.asm</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/CompareMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/CompareMemWrapper.c
new file mode 100644
index 0000000..c8199d8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/CompareMemWrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  CompareMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CompareMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)DestinationBuffer + 1);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)SourceBuffer + 1);

+  if (Length == 0) {

+    return 0;

+  }

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/CopyMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/CopyMemWrapper.c
new file mode 100644
index 0000000..5ca62f5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/CopyMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CopyMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CopyMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (

+    Destination == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Destination + 1

+    );

+  ASSERT (

+    Source == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Source + 1

+    );

+  if (Destination == Source || Length == 0) {

+    return Destination;

+  }

+  return InternalMemCopyMem (Destination, Source, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.asm
new file mode 100644
index 0000000..3cf6fe7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.s
new file mode 100644
index 0000000..1ba0eda
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.s
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CompareMem.Asm
+#
+# Abstract:
+#
+#   CompareMem function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    .code: 
+
+.global InternalMemCompareMem
+InternalMemCompareMem:
+    push    %esi
+    push    %edi
+    movl    12(%esp),%esi
+    movl    16(%esp),%edi
+    movl    20(%esp),%ecx
+    repe    cmpsb
+    movzbl  -1(%esi), %eax
+    movzbl  -1(%edi), %edx
+    subl    %edx,%eax
+    pop     %edi
+    pop     %esi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.asm
new file mode 100644
index 0000000..7b3e5ea
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CopyMem.Asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [edi + edx - 1]        ; eax <- End of Destination

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, esi

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     ecx, edx

+    and     edx, 3

+    shr     ecx, 2

+    rep     movsd                       ; Copy as many Dwords as possible

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     edi, eax                    ; edi <- End of Destination

+    lea     esi, [esi + edx - 1]        ; esi <- End of Source

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb                       ; Copy bytes backward

+    cld

+    mov     eax, [esp + 12]             ; eax <- Destination as return value

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.s
new file mode 100644
index 0000000..f4df08b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.s
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CopyMem.Asm
+#
+# Abstract:
+#
+#   CopyMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global InternalMemCopyMem
+InternalMemCopyMem:
+    push    %esi
+    push    %edi
+    movl    16(%esp),%esi               # esi <- Source
+    movl    12(%esp),%edi               # edi <- Destination
+    movl    20(%esp),%edx               # edx <- Count
+    leal    -1(%edi,%edx),%eax          # eax <- End of Destination
+    cmpl    %edi,%esi
+    jae     L0
+    cmpl    %esi,%eax
+    jae     @CopyBackward               # Copy backward if overlapped
+L0: 
+    movl    %edx,%ecx
+    andl    $3,%edx
+    shrl    $2,%ecx
+    rep
+    movsl                               # Copy as many Dwords as possible
+    jmp     @CopyBytes
+@CopyBackward: 
+    movl    %eax,%edi                   # edi <- End of Destination
+    leal    -1(%esi,%edx),%esi          # esi <- End of Source
+    std
+@CopyBytes: 
+    movl    %edx,%ecx
+    rep
+    movsb                               # Copy bytes backward
+    cld
+    movl    12(%esp),%eax               # eax <- Destination as return value
+    push    %edi
+    push    %esi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..7071942
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.s
new file mode 100644
index 0000000..33101c1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem16.Asm
+#
+# Abstract:
+#
+#   ScanMem16 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    .code: 
+
+.global InternalMemScanMem16
+InternalMemScanMem16:
+    push    %edi
+    movl    12(%esp),%ecx
+    movl    8(%esp),%edi
+    movl    16(%esp),%eax
+    repne   scasw
+    leal    -2(%edi),%eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..e6aaf02
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.s
new file mode 100644
index 0000000..bd007fa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.s
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem32.Asm
+#
+# Abstract:
+#
+#   ScanMem32 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    .code: 
+
+.global InternalMemScanMem32
+InternalMemScanMem32:
+    push    %edi
+    movl    12(%esp),%ecx
+    movl    8(%esp),%edi
+    movl    16(%esp),%eax
+    repne   scasl
+    leal    -4(%edi),%eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..f9725a4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.s
new file mode 100644
index 0000000..bfb4189
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.s
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem64.Asm
+#
+# Abstract:
+#
+#   ScanMem64 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    .code: 
+
+InternalMemScanMem64:
+    push    %edi
+    movl    12(%esp),%ecx
+    movl    16(%esp),%eax
+    movl    20(%esp),%edx
+    movl    8(%esp),%edi
+L0:
+    cmpl    (%edi),%eax
+    leal    8(%edi),%edi
+    loopne  L0
+    jne     L1
+    cmpl    -4(%edi),%edx
+    jecxz   L1
+    jne     L0
+L1:
+    leal    -8(%edi),%eax
+    cmovne  %ecx, %eax
+    pop     %edi
+    ret
+
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..6ae1900
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.s
new file mode 100644
index 0000000..a9c8d93
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.s
@@ -0,0 +1,42 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem8.Asm
+#
+# Abstract:
+#
+#   ScanMem8 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    .code: 
+
+.global InternalMemScanMem8
+InternalMemScanMem8:
+    push    %edi
+    movl    12(%esp),%ecx
+    movl    8(%esp),%edi
+    movb    16(%esp),%al
+    repne   scasb
+    leal    -1(%edi),%eax
+    cmovnz  %ecx, %eax
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.asm
new file mode 100644
index 0000000..495dd3f
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMemSetMem   PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosb

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.s
new file mode 100644
index 0000000..fcbc1ab
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.s
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem.Asm
+#
+# Abstract:
+#
+#   SetMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global InternalMemSetMem
+InternalMemSetMem:
+    push    %edi
+    movl    16(%esp),%eax
+    movl    8(%esp),%edi
+    movl    12(%esp),%ecx
+    rep
+    stosb
+    movl    8(%esp),%eax
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.asm
new file mode 100644
index 0000000..483e26e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMemSetMem16 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.s
new file mode 100644
index 0000000..c45ff67
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.s
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem16.Asm
+#
+# Abstract:
+#
+#   SetMem16 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global InternalMemSetMem16
+InternalMemSetMem16:
+    push    %edi
+    movl    16(%esp),%eax
+    movl    8(%esp),%edi
+    movl    12(%esp),%ecx
+    rep
+    stosw
+    movl    8(%esp),%eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.asm
new file mode 100644
index 0000000..18b77ce
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMemSetMem32 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosd

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.s
new file mode 100644
index 0000000..9f31def
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.s
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem32.Asm
+#
+# Abstract:
+#
+#   SetMem32 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global InternalMemSetMem32
+InternalMemSetMem32:
+    push    %edi
+    movl    16(%esp),%eax
+    movl    8(%esp),%edi
+    movl    12(%esp),%ecx
+    rep
+    stosl
+    movl    8(%esp),%eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.asm
new file mode 100644
index 0000000..3f6f3ec
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMemSetMem64 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    mov     [edi + ecx*4 - 8], eax

+    mov     [edi + ecx*4 - 4], edx

+    loop    @B

+    mov     eax, edi

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.s
new file mode 100644
index 0000000..81f7068
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.s
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem64.Asm
+#
+# Abstract:
+#
+#   SetMem64 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global InternalMemSetMem64
+InternalMemSetMem64:
+    push    %edi
+    movl    12(%esp),%ecx
+    movl    16(%esp),%eax
+    movl    20(%esp),%edx
+    movl    8(%esp),%edi
+L0: 
+    mov     %eax,-8(%edi,%ecx,4)
+    mov     %edx,-4(%edi,%ecx,4)
+    loop    L0
+    movl    %edi,%eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..f892250
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalMemZeroMem  PROC    USES    edi

+    xor     eax, eax

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edx, ecx

+    shr     ecx, 2

+    and     edx, 3

+    push    edi

+    rep     stosd

+    mov     ecx, edx

+    rep     stosb

+    pop     eax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.s b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.s
new file mode 100644
index 0000000..d61cdff
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ZeroMem.Asm
+#
+# Abstract:
+#
+#   ZeroMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .386: 
+    .code: 
+
+.global InternalMemZeroMem
+InternalMemZeroMem:
+    push    %edi
+    xorl    %eax,%eax
+    movl    8(%esp),%edi
+    movl    12(%esp),%ecx
+    movl    %ecx,%edx
+    shrl    $2,%ecx
+    andl    $3,%edx
+    pushl   %edi
+    rep
+    stosl
+    movl    %edx,%ecx
+    rep
+    stosb
+    popl    %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibGuid.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibGuid.c
new file mode 100644
index 0000000..c54983c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibGuid.c
@@ -0,0 +1,139 @@
+/** @file

+  Implementation of GUID functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGuid.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  )

+{

+  return (BOOLEAN)(

+           ReadUnaligned64 ((CONST UINT64*)Guid1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&

+           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)

+           );

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (Buffer != NULL);

+  //

+  // Make sure Buffer is aligned on a 64-bit boundary.

+  //

+  ASSERT (((UINTN) Buffer & 7) == 0);

+

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibInternals.h b/edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibInternals.h
new file mode 100644
index 0000000..ca7311a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibInternals.h
@@ -0,0 +1,230 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibInternals.h

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem16Wrapper.c
new file mode 100644
index 0000000..a17705d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem16Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem32Wrapper.c
new file mode 100644
index 0000000..67eb84d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem64Wrapper.c
new file mode 100644
index 0000000..c5f0762
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem64Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem8Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem8Wrapper.c
new file mode 100644
index 0000000..9b817b1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem8Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  ScanMem8() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem8Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem16Wrapper.c
new file mode 100644
index 0000000..3acbdac
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem32Wrapper.c
new file mode 100644
index 0000000..620b69a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem64Wrapper.c
new file mode 100644
index 0000000..73c28af
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
new file mode 100644
index 0000000..294a27a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  SetMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Size <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  return InternalMemSetMem (Buffer, Size, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/ZeroMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ZeroMemWrapper.c
new file mode 100644
index 0000000..4a3d615
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ZeroMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemSetMem (Buffer, Length, 0);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/build.xml b/edk2/MdePkg/Library/BaseMemoryLibRepStr/build.xml
new file mode 100644
index 0000000..66b1335
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseMemoryLibRepStr"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseMemoryLibRepStr"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseMemoryLibRepStr">

+      <GenBuild baseName="BaseMemoryLibRepStr" mbdFilename="${MODULE_DIR}/BaseMemoryLibRepStr.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibRepStr.msa"/>

+   </target>

+   <target depends="BaseMemoryLibRepStr_clean" name="clean"/>

+   <target depends="BaseMemoryLibRepStr_cleanall" name="cleanall"/>

+   <target name="BaseMemoryLibRepStr_clean">

+      <OutputDirSetup baseName="BaseMemoryLibRepStr" mbdFilename="${MODULE_DIR}/BaseMemoryLibRepStr.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibRepStr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLibRepStr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLibRepStr_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseMemoryLibRepStr_cleanall">

+      <OutputDirSetup baseName="BaseMemoryLibRepStr" mbdFilename="${MODULE_DIR}/BaseMemoryLibRepStr.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibRepStr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLibRepStr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLibRepStr_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseMemoryLibRepStr*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/CompareMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/CompareMem.asm
new file mode 100644
index 0000000..b8e289b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/CompareMem.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/CopyMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/CopyMem.asm
new file mode 100644
index 0000000..4363071
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/CopyMem.asm
@@ -0,0 +1,52 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CopyMem.Asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rdi + r8 - 1]          ; r9 <- End of Destination

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F

+    cmp     r9, rsi

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     rcx, r8

+    and     r8, 7

+    shr     rcx, 3

+    rep     movsq                       ; Copy as many Qwords as possible

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     rdi, r9                     ; rdi <- End of Destination

+    lea     rsi, [rsi + r8 - 1]         ; esi <- End of Source

+    std                                 ; set direction flag

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb                       ; Copy bytes backward

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem16.asm
new file mode 100644
index 0000000..6af88fa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem16.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem32.asm
new file mode 100644
index 0000000..f9c9feb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem32.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem64.asm
new file mode 100644
index 0000000..2f286c9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem64.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem8.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem8.asm
new file mode 100644
index 0000000..4027ece
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ScanMem8.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem.asm
new file mode 100644
index 0000000..b9108c7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem.asm
@@ -0,0 +1,35 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemSetMem   PROC    USES    rdi

+    mov     rax, r8

+    mov     rdi, rcx

+    xchg    rcx, rdx

+    rep     stosb

+    mov     rax, rdx

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem16.asm
new file mode 100644
index 0000000..3a9fd47
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem16.asm
@@ -0,0 +1,35 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemSetMem16 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosw

+    mov     rax, rdx

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem32.asm
new file mode 100644
index 0000000..2020d19
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem32.asm
@@ -0,0 +1,35 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemSetMem32 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosd

+    mov     rax, rdx

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem64.asm
new file mode 100644
index 0000000..70ca4fb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/SetMem64.asm
@@ -0,0 +1,35 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemSetMem64 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosq

+    mov     rax, rdx

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ZeroMem.asm b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ZeroMem.asm
new file mode 100644
index 0000000..c18a2e2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibRepStr/x64/ZeroMem.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemZeroMem  PROC    USES    rdi

+    push    rcx

+    xor     rax, rax

+    mov     rdi, rcx

+    mov     rcx, rdx

+    shr     rcx, 3

+    and     rdx, 7

+    rep     stosq

+    mov     ecx, edx

+    rep     stosb

+    pop     rax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2-Gcc.msa b/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2-Gcc.msa
new file mode 100644
index 0000000..5fd0d4d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2-Gcc.msa
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLibSse2</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>65a18235-5096-4032-8c63-214f0249ce8d</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:46</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CopyMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem16.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/SetMem64.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ZeroMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/CompareMem.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem8.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem16.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem32.s</Filename>

+      <Filename FileType="GCC_Assembly_Code">Ia32/ScanMem64.s</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>x64/CopyMem.asm</Filename>

+      <Filename>x64/SetMem.asm</Filename>

+      <Filename>x64/SetMem16.asm</Filename>

+      <Filename>x64/SetMem32.asm</Filename>

+      <Filename>x64/SetMem64.asm</Filename>

+      <Filename>x64/ZeroMem.asm</Filename>

+      <Filename>x64/CompareMem.asm</Filename>

+      <Filename>x64/ScanMem8.asm</Filename>

+      <Filename>x64/ScanMem16.asm</Filename>

+      <Filename>x64/ScanMem32.asm</Filename>

+      <Filename>x64/ScanMem64.asm</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.mbd b/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.mbd
new file mode 100644
index 0000000..3469685
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseMemoryLibSse2</BaseName>

+    <Guid>65a18235-5096-4032-8c63-214f0249ce8d</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:46</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.msa b/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.msa
new file mode 100644
index 0000000..22febd1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.msa
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseMemoryLibSse2</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>65a18235-5096-4032-8c63-214f0249ce8d</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:46</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>Ia32/CopyMem.asm</Filename>

+      <Filename>Ia32/SetMem.asm</Filename>

+      <Filename>Ia32/SetMem16.asm</Filename>

+      <Filename>Ia32/SetMem32.asm</Filename>

+      <Filename>Ia32/SetMem64.asm</Filename>

+      <Filename>Ia32/ZeroMem.asm</Filename>

+      <Filename>Ia32/CompareMem.asm</Filename>

+      <Filename>Ia32/ScanMem8.asm</Filename>

+      <Filename>Ia32/ScanMem16.asm</Filename>

+      <Filename>Ia32/ScanMem32.asm</Filename>

+      <Filename>Ia32/ScanMem64.asm</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>MemLibGuid.c</Filename>

+      <Filename>CopyMemWrapper.c</Filename>

+      <Filename>SetMemWrapper.c</Filename>

+      <Filename>SetMem16Wrapper.c</Filename>

+      <Filename>SetMem32Wrapper.c</Filename>

+      <Filename>SetMem64Wrapper.c</Filename>

+      <Filename>CompareMemWrapper.c</Filename>

+      <Filename>ZeroMemWrapper.c</Filename>

+      <Filename>ScanMem8Wrapper.c</Filename>

+      <Filename>ScanMem16Wrapper.c</Filename>

+      <Filename>ScanMem32Wrapper.c</Filename>

+      <Filename>ScanMem64Wrapper.c</Filename>

+      <Filename>x64/CopyMem.asm</Filename>

+      <Filename>x64/SetMem.asm</Filename>

+      <Filename>x64/SetMem16.asm</Filename>

+      <Filename>x64/SetMem32.asm</Filename>

+      <Filename>x64/SetMem64.asm</Filename>

+      <Filename>x64/ZeroMem.asm</Filename>

+      <Filename>x64/CompareMem.asm</Filename>

+      <Filename>x64/ScanMem8.asm</Filename>

+      <Filename>x64/ScanMem16.asm</Filename>

+      <Filename>x64/ScanMem32.asm</Filename>

+      <Filename>x64/ScanMem64.asm</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/CompareMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/CompareMemWrapper.c
new file mode 100644
index 0000000..c8199d8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/CompareMemWrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  CompareMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CompareMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)DestinationBuffer + 1);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)SourceBuffer + 1);

+  if (Length == 0) {

+    return 0;

+  }

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/CopyMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/CopyMemWrapper.c
new file mode 100644
index 0000000..5ca62f5
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/CopyMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CopyMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CopyMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (

+    Destination == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Destination + 1

+    );

+  ASSERT (

+    Source == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Source + 1

+    );

+  if (Destination == Source || Length == 0) {

+    return Destination;

+  }

+  return InternalMemCopyMem (Destination, Source, Length);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.asm
new file mode 100644
index 0000000..3cf6fe7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.s
new file mode 100644
index 0000000..c01b0c1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.s
@@ -0,0 +1,48 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CompareMem.Asm
+#
+# Abstract:
+#
+#   CompareMem function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemCompareMem
+_InternalMemCompareMem:
+    push    %esi
+    push    %edi
+    movl    12(%esp), %esi
+    movl    16(%esp), %edi
+    movl    20(%esp), %ecx
+    repe    cmpsb
+    movzbl  -1(%esi), %eax
+    movzbl  -1(%edi), %edx
+    subl    %edx, %eax
+    subl    %edx, %eax
+    pop     %edi
+    pop     %esi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.asm
new file mode 100644
index 0000000..6127cc2
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.asm
@@ -0,0 +1,84 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_CopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [edi + edx - 1]        ; eax <- End of Destination

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, esi                    ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx                    ; edx <- remaining bytes to copy

+    rep     movsb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4                      ; ecx <- # of DQwords to copy

+    jz      @CopyBytes

+    add     esp, -16

+    movdqu  [esp], xmm0                 ; save xmm0

+@@:

+    movdqu  xmm0, [esi]                 ; esi may not be 16-bytes aligned

+    movntdq [edi], xmm0                 ; edi should be 16-bytes aligned

+    add     esi, 16

+    add     edi, 16

+    loop    @B

+    mfence

+    movdqu  xmm0, [esp]                 ; restore xmm0

+    add     esp, 16                     ; stack cleanup

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     edi, eax                    ; edi <- Last byte in Destination

+    lea     esi, [esi + edx - 1]        ; esi <- Last byte in Source

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb

+    cld

+    mov     eax, [esp + 12]             ; eax <- Destination as return value

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.s
new file mode 100644
index 0000000..deb9860
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.s
@@ -0,0 +1,88 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   CopyMem.asm
+#
+# Abstract:
+#
+#   CopyMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_CopyMem (
+#    IN VOID   *Destination,
+#    IN VOID   *Source,
+#    IN UINTN  Count
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemCopyMem
+_InternalMemCopyMem:
+    push    %esi
+    push    %edi
+    movl    16(%esp), %esi              # esi <- Source
+    movl    12(%esp), %edi              # edi <- Destination
+    movl    20(%esp), %edx              # edx <- Count
+    leal    -1(%edi,%edx,), %eax        # eax <- End of Destination
+    cmpl    %edi, %esi
+    jae     L0
+    cmpl    %esi, %eax                  # Overlapped?
+    jae     @CopyBackward               # Copy backward if overlapped
+L0: 
+    xorl    %ecx, %ecx
+    subl    %edi, %ecx
+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary
+    jz      L1
+    cmpl    %edx, %ecx
+    cmova   %edx, %ecx
+    subl    %ecx, %edx                  # edx <- remaining bytes to copy
+    rep
+    movsb
+L1: 
+    movl    %edx, %ecx
+    andl    $15, %edx
+    shrl    $4, %ecx                    # ecx <- # of DQwords to copy
+    jz      @CopyBytes
+    addl    $-16, %esp
+    movdqu  %xmm0, (%esp)
+L2: 
+    movdqu  (%esi), %xmm0
+    movntdq %xmm0, (%edi) 
+    addl    $16, %esi
+    addl    $16, %edi
+    loop    L2
+    mfence
+    movdqu  (%esp),%xmm0
+    addl    $16, %esp                   # stack cleanup
+    jmp     @CopyBytes
+@CopyBackward: 
+    movl    %eax, %edi                  # edi <- Last byte in Destination
+    leal    -1(%esi,%edx,), %esi        # esi <- Last byte in Source
+    std
+@CopyBytes: 
+    movl    %edx, %ecx
+    rep
+    movsb
+    cld
+    movl    12(%esp), %eax              # eax <- Destination as return value
+    pop     %edi
+    pop     %esi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..7071942
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.s
new file mode 100644
index 0000000..c433a28
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem16.Asm
+#
+# Abstract:
+#
+#   ScanMem16 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem16
+_InternalMemScanMem16:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movl    16(%esp), %eax
+    repne   scasw
+    leal    -2(%edi), %eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..e6aaf02
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.s
new file mode 100644
index 0000000..1de283c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem32.Asm
+#
+# Abstract:
+#
+#   ScanMem32 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem32
+_InternalMemScanMem32:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movl    16(%esp), %eax
+    repnz   scasl
+    leal    -4(%edi), %eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..f9725a4
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.s
new file mode 100644
index 0000000..00f6d74
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.s
@@ -0,0 +1,53 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem64.Asm
+#
+# Abstract:
+#
+#   ScanMem64 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem64
+_InternalMemScanMem64:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    16(%esp), %eax
+    movl    20(%esp), %edx
+    movl    8(%esp), %edi
+L0: 
+    cmpl    (%edi), %eax
+    leal    8(%edi), %edi
+    loopne  L0
+    jne     L1
+    cmpl    -4(%edi), %edx
+    jecxz   L1
+    jne     L0
+L1: 
+    leal    -8(%edi), %eax
+    cmovne  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..6ae1900
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.s
new file mode 100644
index 0000000..5764037
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.s
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ScanMem8.Asm
+#
+# Abstract:
+#
+#   ScanMem8 function
+#
+# Notes:
+#
+#   The following BaseMemoryLib instances share the same version of this file:
+#
+#       BaseMemoryLibRepStr
+#       BaseMemoryLibMmx
+#       BaseMemoryLibSse2
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.global _InternalMemScanMem8
+_InternalMemScanMem8:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    movb    16(%esp), %al
+    repne   scasb
+    leal    -1(%edi), %eax
+    cmovnz  %ecx, %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.asm
new file mode 100644
index 0000000..62b10cf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.asm
@@ -0,0 +1,74 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov     edx, [esp + 12]             ; edx <- Count

+    mov     edi, [esp + 8]              ; edi <- Buffer

+    mov     al, [esp + 16]              ; al <- Value

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4                      ; ecx <- # of DQwords to set

+    jz      @SetBytes

+    mov     ah, al                      ; ax <- Value | (Value << 8)

+    add     esp, -16

+    movdqu  [esp], xmm0                 ; save xmm0

+    movd    xmm0, eax

+    pshuflw xmm0, xmm0, 0               ; xmm0[0..63] <- Value repeats 8 times

+    movlhps xmm0, xmm0                  ; xmm0 <- Value repeats 16 times

+@@:

+    movntdq [edi], xmm0                 ; edi should be 16-byte aligned

+    add     edi, 16

+    loop    @B

+    mfence

+    movdqu  xmm0, [esp]                 ; restore xmm0

+    add     esp, 16                     ; stack cleanup

+@SetBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]              ; eax <- Buffer as return value

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.s
new file mode 100644
index 0000000..e778cd8
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.s
@@ -0,0 +1,76 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem.asm
+#
+# Abstract:
+#
+#   SetMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT8  Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem
+_InternalMemSetMem:
+    push    %edi
+    movl    12(%esp), %edx              # edx <- Count
+    movl    8(%esp), %edi               # edi <- Buffer
+    movb    16(%esp), %al               # al <- Value
+    xorl    %ecx, %ecx
+    subl    %edi, %ecx
+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary
+    jz      L0
+    cmpl    %edx, %ecx
+    cmova   %edx, %ecx
+    subl    %ecx, %edx
+    rep
+    stosb
+L0: 
+    movl    %edx, %ecx
+    andl    $15, %edx
+    shrl    $4, %ecx                    # ecx <- # of DQwords to set
+    jz      @SetBytes
+    movb    %al, %ah                    # ax <- Value | (Value << 8)
+    addl    $-16, %esp
+    movdqu  %xmm0, (%esp)
+    movd    %eax, %xmm0
+    pshuflw $0, %xmm0, %xmm0
+    movlhps %xmm0, %xmm0
+L1: 
+    movntdq %xmm0, (%edi)
+    addl    $16, %edi
+    loop   L1
+    mfence
+    movdqu  (%esp), %xmm0
+    addl    $16, %esp                   # stack cleanup
+@SetBytes: 
+    movl    %edx, %ecx
+    rep
+    stosb
+    movl    8(%esp), %eax               # eax <- Buffer as return value
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.asm
new file mode 100644
index 0000000..3fabb00
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.asm
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    mov     eax, [esp + 16]

+    jz      @F

+    shr     ecx, 1

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosw

+@@:

+    mov     ecx, edx

+    and     edx, 7

+    shr     ecx, 3

+    jz      @SetWords

+    movd    xmm0, eax

+    pshuflw xmm0, xmm0, 0

+    movlhps xmm0, xmm0

+@@:

+    movntdq [edi], xmm0                 ; edi should be 16-byte aligned

+    add     edi, 16

+    loop    @B

+    mfence

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.s
new file mode 100644
index 0000000..27110b3
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.s
@@ -0,0 +1,72 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem16.asm
+#
+# Abstract:
+#
+#   SetMem16 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem16 (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT16 Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem16
+_InternalMemSetMem16:
+    push    %edi
+    movl    12(%esp), %edx
+    movl    8(%esp), %edi
+    xorl    %ecx, %ecx
+    subl    %edi, %ecx
+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary
+    movl    16(%esp), %eax
+    jz      L0
+    shrl    %ecx
+    cmpl    %edx, %ecx
+    cmova   %edx, %ecx
+    subl    %ecx, %edx
+    rep
+    stosw
+L0: 
+    movl    %edx, %ecx
+    andl    $7, %edx
+    shrl    $3, %ecx
+    jz      @SetWords
+    movd    %eax, %xmm0
+    pshuflw $0, %xmm0, %xmm0
+    movlhps %xmm0, %xmm0
+L1:
+    movntdq %xmm0, (%edi)
+    addl    $16, %edi
+    loop    L1
+    mfence
+@SetWords: 
+    movl    %edx, %ecx
+    rep
+    stosw
+    movl    8(%esp), %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.asm
new file mode 100644
index 0000000..a7f1f0e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.asm
@@ -0,0 +1,69 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    edi

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    mov     eax, [esp + 16]

+    jz      @F

+    shr     ecx, 2

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosd

+@@:

+    mov     ecx, edx

+    and     edx, 3

+    shr     ecx, 2

+    jz      @SetDwords

+    movd    xmm0, eax

+    pshufd  xmm0, xmm0, 0

+@@:

+    movntdq [edi], xmm0

+    add     edi, 16

+    loop    @B

+    mfence

+@SetDwords:

+    mov     ecx, edx

+    rep     stosd

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.s
new file mode 100644
index 0000000..a1a6317
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.s
@@ -0,0 +1,71 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem32.asm
+#
+# Abstract:
+#
+#   SetMem32 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem32 (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT32 Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem32
+_InternalMemSetMem32:
+    push    %edi
+    movl    12(%esp), %edx
+    movl    8(%esp), %edi
+    xorl    %ecx, %ecx
+    subl    %edi, %ecx
+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary
+    movl    16(%esp), %eax
+    jz      L0
+    shrl    $2, %ecx
+    cmpl    %edx, %ecx
+    cmova   %edx, %ecx
+    subl    %ecx, %edx
+    rep
+    stosl
+L0: 
+    movl    %edx, %ecx
+    andl    $3, %edx
+    shrl    $2, %ecx
+    jz      @SetDwords
+    movd    %eax, %xmm0
+    pshufd  $0, %xmm0, %xmm0
+L1: 
+    movntdq %xmm0, (%edi)
+    addl    $16, %edi
+    loop    L1
+    mfence
+@SetDwords: 
+    movl    %edx, %ecx
+    rep
+    stosl
+    movl    8(%esp), %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.asm
new file mode 100644
index 0000000..1ddc7ea
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.asm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    test    edi, 8

+    DB      0f2h, 0fh, 12h, 44h, 24h, 16    ; movddup xmm0, [esp + 16]

+    jz      @F

+    movq    [edi], xmm0

+    add     edi, 8

+    dec     ecx

+@@:

+    mov     edx, ecx

+    shr     ecx, 1

+    jz      @SetQwords

+@@:

+    movntdq [edi], xmm0

+    add     edi, 16

+    loop    @B

+    mfence

+@SetQwords:

+    test    dl, 1

+    jz      @F

+    movq    [edi], xmm0

+@@:

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.s
new file mode 100644
index 0000000..2535a61
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.s
@@ -0,0 +1,63 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   SetMem64.asm
+#
+# Abstract:
+#
+#   SetMem64 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_SetMem64 (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count,
+#    IN UINT64 Value
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemSetMem64
+_InternalMemSetMem64:
+    push    %edi
+    movl    12(%esp), %ecx
+    movl    8(%esp), %edi
+    testl   $8, %edi
+    movddup 16(%esp), %xmm0
+    jz      L0
+    movq    %xmm0, (%edi)
+    addl    $8, %edi
+    decl    %ecx
+L0: 
+    movl    %ecx, %edx
+    shrl    %ecx
+    jz      @SetQwords
+L1: 
+    movntdq %xmm0, (%edi)
+    addl    $16, %edi
+    loop    L1
+    mfence
+@SetQwords: 
+    testb   $1, %dl
+    jz      L2
+    movq    %xmm0, (%edi)
+L2: 
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..b532382
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_ZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    mov     edi, [esp + 8]

+    mov     edx, [esp + 12]

+    xor     ecx, ecx

+    sub     ecx, edi

+    xor     eax, eax

+    and     ecx, 15

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4

+    jz      @ZeroBytes

+    pxor    xmm0, xmm0

+@@:

+    movntdq [edi], xmm0

+    add     edi, 16

+    loop    @B

+    mfence

+@ZeroBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.s b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.s
new file mode 100644
index 0000000..f927f91
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.s
@@ -0,0 +1,68 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+#
+# Module Name:
+#
+#   ZeroMem.asm
+#
+# Abstract:
+#
+#   ZeroMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+    .686: 
+    #.MODEL flat,C
+    .xmm: 
+    .code: 
+
+#------------------------------------------------------------------------------
+#  VOID *
+#  _mem_ZeroMem (
+#    IN VOID   *Buffer,
+#    IN UINTN  Count
+#    )
+#------------------------------------------------------------------------------
+.global _InternalMemZeroMem
+_InternalMemZeroMem:
+    push    %edi
+    movl    8(%esp), %edi
+    movl    12(%esp), %edx
+    xorl    %ecx, %ecx
+    subl    %edi, %ecx
+    xorl    %eax, %eax
+    andl    $15, %ecx
+    jz      L0
+    cmpl    %edx, %ecx
+    cmova   %edx, %ecx
+    subl    %ecx, %edx
+    rep
+    stosb
+L0: 
+    movl    %edx, %ecx
+    andl    $15, %edx
+    shrl    $4, %ecx
+    jz      @ZeroBytes
+    pxor    %xmm0, %xmm0
+L1: 
+    movntdq %xmm0, (%edi)
+    addl    $16, %edi
+    loop    L1
+    mfence
+@ZeroBytes: 
+    movl    %edx, %ecx
+    rep
+    stosb
+    movl    8(%esp), %eax
+    pop     %edi
+    ret
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibGuid.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibGuid.c
new file mode 100644
index 0000000..c54983c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibGuid.c
@@ -0,0 +1,139 @@
+/** @file

+  Implementation of GUID functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGuid.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  )

+{

+  return (BOOLEAN)(

+           ReadUnaligned64 ((CONST UINT64*)Guid1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&

+           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)

+           );

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (Buffer != NULL);

+  //

+  // Make sure Buffer is aligned on a 64-bit boundary.

+  //

+  ASSERT (((UINTN) Buffer & 7) == 0);

+

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibInternals.h b/edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibInternals.h
new file mode 100644
index 0000000..ca7311a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibInternals.h
@@ -0,0 +1,230 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibInternals.h

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem16Wrapper.c
new file mode 100644
index 0000000..a17705d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem16Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem32Wrapper.c
new file mode 100644
index 0000000..67eb84d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem64Wrapper.c
new file mode 100644
index 0000000..c5f0762
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem64Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem8Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem8Wrapper.c
new file mode 100644
index 0000000..9b817b1
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem8Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  ScanMem8() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem8Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem16Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem16Wrapper.c
new file mode 100644
index 0000000..3acbdac
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem32Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem32Wrapper.c
new file mode 100644
index 0000000..620b69a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem64Wrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem64Wrapper.c
new file mode 100644
index 0000000..73c28af
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
new file mode 100644
index 0000000..294a27a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  SetMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Size <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  return InternalMemSetMem (Buffer, Size, Value);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/ZeroMemWrapper.c b/edk2/MdePkg/Library/BaseMemoryLibSse2/ZeroMemWrapper.c
new file mode 100644
index 0000000..4a3d615
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ZeroMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemSetMem (Buffer, Length, 0);

+}

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/build.xml b/edk2/MdePkg/Library/BaseMemoryLibSse2/build.xml
new file mode 100644
index 0000000..1a5866a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseMemoryLibSse2"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseMemoryLibSse2"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseMemoryLibSse2">

+      <GenBuild baseName="BaseMemoryLibSse2" mbdFilename="${MODULE_DIR}/BaseMemoryLibSse2.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibSse2.msa"/>

+   </target>

+   <target depends="BaseMemoryLibSse2_clean" name="clean"/>

+   <target depends="BaseMemoryLibSse2_cleanall" name="cleanall"/>

+   <target name="BaseMemoryLibSse2_clean">

+      <OutputDirSetup baseName="BaseMemoryLibSse2" mbdFilename="${MODULE_DIR}/BaseMemoryLibSse2.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibSse2.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLibSse2_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLibSse2_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseMemoryLibSse2_cleanall">

+      <OutputDirSetup baseName="BaseMemoryLibSse2" mbdFilename="${MODULE_DIR}/BaseMemoryLibSse2.mbd" msaFilename="${MODULE_DIR}/BaseMemoryLibSse2.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseMemoryLibSse2_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseMemoryLibSse2_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseMemoryLibSse2*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/CompareMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/CompareMem.asm
new file mode 100644
index 0000000..b8e289b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/CompareMem.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/CopyMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/CopyMem.asm
new file mode 100644
index 0000000..955cd25
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/CopyMem.asm
@@ -0,0 +1,78 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_CopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rdi + r8 - 1]          ; r9 <- Last byte of Destination

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F                          ; Copy forward if Source > Destination

+    cmp     r9, rsi                     ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     rcx, rcx

+    sub     rcx, rdi                    ; rcx <- -rdi

+    and     rcx, 15                     ; rcx + rsi should be 16 bytes aligned

+    jz      @F                          ; skip if rcx == 0

+    cmp     rcx, r8

+    cmova   rcx, r8

+    sub     r8, rcx

+    rep     movsb

+@@:

+    mov     rcx, r8

+    and     r8, 15

+    shr     rcx, 4                      ; rcx <- # of DQwords to copy

+    jz      @CopyBytes

+    movdqa  [rsp + 18h], xmm0           ; save xmm0 on stack

+@@:

+    movdqu  xmm0, [rsi]                 ; rsi may not be 16-byte aligned

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rsi, 16

+    add     rdi, 16

+    loop    @B

+    mfence

+    movdqa  xmm0, [rsp + 18h]           ; restore xmm0

+    jmp     @CopyBytes                  ; copy remaining bytes

+@CopyBackward:

+    mov     rdi, r9                     ; rdi <- Last byte of Destination

+    lea     rsi, [rsi + r8 - 1]         ; rsi <- Last byte of Source

+    std

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem16.asm
new file mode 100644
index 0000000..6af88fa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem16.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem32.asm
new file mode 100644
index 0000000..f9c9feb
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem32.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem64.asm
new file mode 100644
index 0000000..2f286c9
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem64.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem8.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem8.asm
new file mode 100644
index 0000000..4027ece
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ScanMem8.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances share the same version of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem.asm
new file mode 100644
index 0000000..2aba207
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem.asm
@@ -0,0 +1,69 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    rdi

+    mov     rdi, rcx                    ; rdi <- Buffer

+    mov     al, r8b                     ; al <- Value

+    mov     r9, rdi                     ; r9 <- Buffer as return value

+    xor     rcx, rcx

+    sub     rcx, rdi

+    and     rcx, 15                     ; rcx + rdi aligns on 16-byte boundary

+    jz      @F

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosb

+@@:

+    mov     rcx, rdx

+    and     rdx, 15

+    shr     rcx, 4

+    jz      @SetBytes

+    mov     ah, al                      ; ax <- Value repeats twice

+    movdqa  [rsp + 10h], xmm0           ; save xmm0

+    movd    xmm0, eax                   ; xmm0[0..16] <- Value repeats twice

+    pshuflw xmm0, xmm0, 0               ; xmm0[0..63] <- Value repeats 8 times

+    movlhps xmm0, xmm0                  ; xmm0 <- Value repeats 16 times

+@@:

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rdi, 16

+    loop    @B

+    mfence

+    movdqa  xmm0, [rsp + 10h]           ; restore xmm0

+@SetBytes:

+    mov     ecx, edx                    ; high 32 bits of rcx are always zero

+    rep     stosb

+    mov     rax, r9                     ; rax <- Return value

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem16.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem16.asm
new file mode 100644
index 0000000..a2f4d0e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem16.asm
@@ -0,0 +1,67 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     r9, rdi

+    xor     rcx, rcx

+    sub     rcx, rdi

+    and     rcx, 15

+    mov     rax, r8

+    jz      @F

+    shr     rcx, 1

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosw

+@@:

+    mov     rcx, rdx

+    and     edx, 7

+    shr     rcx, 3

+    jz      @SetWords

+    movd    xmm0, eax

+    pshuflw xmm0, xmm0, 0

+    movlhps xmm0, xmm0

+@@:

+    movntdq [rdi], xmm0

+    add     rdi, 16

+    loop    @B

+    mfence

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     rax, r9

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem32.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem32.asm
new file mode 100644
index 0000000..24207ec
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem32.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     r9, rdi

+    xor     rcx, rcx

+    sub     rcx, rdi

+    and     rcx, 15

+    mov     rax, r8

+    jz      @F

+    shr     rcx, 2

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosd

+@@:

+    mov     rcx, rdx

+    and     edx, 3

+    shr     rcx, 2

+    jz      @SetDwords

+    movd    xmm0, eax

+    pshufd  xmm0, xmm0, 0

+@@:

+    movntdq [rdi], xmm0

+    add     rdi, 16

+    loop    @B

+    mfence

+@SetDwords:

+    mov     ecx, edx

+    rep     stosd

+    mov     rax, r9

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem64.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem64.asm
new file mode 100644
index 0000000..8b33386
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/SetMem64.asm
@@ -0,0 +1,61 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_SetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     r9, rcx

+    test    cl, 8

+    jz      @F

+    mov     [rdi], r8

+    add     rdi, 8

+    dec     rdx

+@@:

+    mov     rcx, rdx

+    shr     rcx, 1

+    jz      @SetQwords

+    movd    xmm0, r8

+    movlhps xmm0, xmm0

+@@:

+    movntdq [rdi], xmm0

+    add     rdi, 16

+    loop    @B

+    mfence

+@SetQwords:

+    test    dl, 1

+    jz      @F

+    mov     [rdi], r8

+@@:

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ZeroMem.asm b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ZeroMem.asm
new file mode 100644
index 0000000..6d0f99b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseMemoryLibSse2/x64/ZeroMem.asm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, Intel Corporation

+; All rights reserved. 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  _mem_ZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    rdi

+    mov     rdi, rcx

+    xor     rcx, rcx

+    xor     eax, eax

+    sub     rcx, rdi

+    and     rcx, 15

+    mov     r8, rdi

+    jz      @F

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosb

+@@:

+    mov     rcx, rdx

+    and     edx, 15

+    shr     rcx, 4

+    jz      @ZeroBytes

+    pxor    xmm0, xmm0

+@@:

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rdi, 16

+    loop    @B

+    mfence

+@ZeroBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     rax, r8

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.mbd b/edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.mbd
new file mode 100644
index 0000000..695b32e
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePcdLibNull</BaseName>

+    <Guid>40096a3a-5c2a-4fbc-aef7-5475dd7ab334</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-31 10:50</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.msa b/edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.msa
new file mode 100644
index 0000000..d42f10e
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.msa
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePcdLibNull</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>40096a3a-5c2a-4fbc-aef7-5475dd7ab334</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>NULL PCD Library</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-31 10:50</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PcdLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePcdLibNull/PcdLib.c b/edk2/MdePkg/Library/BasePcdLibNull/PcdLib.c
new file mode 100644
index 0000000..a4e0183
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePcdLibNull/PcdLib.c
@@ -0,0 +1,731 @@
+/** @file

+  A emptry template implementation of PCD Library.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PcdLib.c

+

+**/

+

+

+

+/**

+  Sets the current SKU in the PCD database to the value specified by SkuId.  SkuId is returned.

+

+  @param[in]  SkuId The SKU value that will be used when the PCD service will retrieve and 

+              set values associated with a PCD token.

+

+  @retval SKU_ID Return the SKU ID that just be set.

+

+**/

+SKU_ID

+EFIAPI

+LibPcdSetSku (

+  IN SKU_ID  SkuId

+  )

+{

+  return SkuId;

+}

+

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Returns the 8-bit value for the token specified by TokenNumber. 

+

+**/

+UINT8

+EFIAPI

+LibPcdGet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Returns the 16-bit value for the token specified by TokenNumber. 

+

+**/

+UINT16

+EFIAPI

+LibPcdGet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Returns the 32-bit value for the token specified by TokenNumber.

+

+**/

+UINT32

+EFIAPI

+LibPcdGet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Returns the 64-bit value for the token specified by TokenNumber.

+

+**/

+UINT64

+EFIAPI

+LibPcdGet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the pointer to the buffer of the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Returns the pointer to the token specified by TokenNumber.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Returns the Boolean value of the token specified by TokenNumber. 

+

+**/

+BOOLEAN 

+EFIAPI

+LibPcdGetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the size of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Returns the size of the token specified by TokenNumber. 

+

+**/

+UINTN

+EFIAPI

+LibPcdGetSize (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return 0;

+}

+

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Return the UINT8.

+

+**/

+UINT8

+EFIAPI

+LibPcdGetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Return the UINT16.

+

+**/

+UINT16

+EFIAPI

+LibPcdGetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Return the UINT32.

+

+**/

+UINT32

+EFIAPI

+LibPcdGetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Return the UINT64.

+

+**/

+UINT64

+EFIAPI

+LibPcdGetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the pointer to the buffer of the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Return the VOID* pointer.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Return the BOOLEAN.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdGetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the size of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Return the size.

+

+**/

+UINTN

+EFIAPI

+LibPcdGetExSize (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return 0;

+}

+

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+{

+  return Value;

+}

+

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT16 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+{

+  return Value;

+}

+

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSet32 (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT32             Value

+  )

+{

+  return Value;

+}

+

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSet64 (

+  IN PCD_TOKEN_NUMBER   TokenNumber,

+  IN UINT64             Value

+  )

+{

+  return Value;

+}

+

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber to 

+  the value specified by Value. Value is returned.

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value A pointer to the buffer to set.

+

+  @retval VOID* Return the pointer for the buffer been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return Buffer;

+}

+

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The boolean value to set.

+

+  @retval BOOLEAN Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  return Value;

+}

+

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32            Value

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return Value;

+}

+

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval VOID * Return the value been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+{

+  ASSERT (Guid != NULL);

+  ASSERT (Buffer != NULL);

+

+  return Buffer;

+}

+

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The Boolean value to set.

+

+  @retval Boolean Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return Value;

+}

+

+

+

+/**

+  When the token specified by TokenNumber and Guid is set, 

+  then notification function specified by NotificationFunction is called.  

+  If Guid is NULL, then the default token space is used. 

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates which 

+              namespace to set a value from.  If NULL, then the default 

+              token space is used.

+  @param[in]  TokenNumber The PCD token number to monitor.

+  @param[in]  NotificationFunction The function to call when the token 

+              specified by Guid and TokenNumber is set.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCallbackOnSet (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  )

+{

+  ASSERT (NotificationFunction != NULL);

+}

+

+

+

+/**

+  Disable a notification function that was established with LibPcdCallbackonSet().

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Specify the GUID token space.

+  @param[in]  TokenNumber Specify the token number.

+  @param[in]  NotificationFunction The callback function to be unregistered.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCancelCallback (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  )

+{

+  ASSERT (NotificationFunction != NULL);

+}

+

+

+

+/**

+  Retrieves the next PCD token number from the token space specified by Guid.  

+  If Guid is NULL, then the default token space is used.  If TokenNumber is 0, 

+  then the first token number is returned.  Otherwise, the token number that 

+  follows TokenNumber in the token space is returned.  If TokenNumber is the last 

+  token number in the token space, then 0 is returned.  If TokenNumber is not 0 and 

+  is not in the token space specified by Guid, then ASSERT().

+

+  @param[in]  Pointer to a 128-bit unique value that designates which namespace 

+              to set a value from.  If NULL, then the default token space is used.

+  @param[in]  The previous PCD token number.  If 0, then retrieves the first PCD 

+              token number.

+

+  @retval PCD_TOKEN_NUMBER The next valid token number.

+

+**/

+PCD_TOKEN_NUMBER

+EFIAPI

+LibPcdGetNextToken (

+  IN CONST GUID               *Guid, OPTIONAL

+  IN       PCD_TOKEN_NUMBER   TokenNumber

+  )

+{

+  return 0;

+}

diff --git a/edk2/MdePkg/Library/BasePcdLibNull/build.xml b/edk2/MdePkg/Library/BasePcdLibNull/build.xml
new file mode 100644
index 0000000..1b436c3
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePcdLibNull/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePcdLibNull"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePcdLibNull"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePcdLibNull">

+      <GenBuild baseName="BasePcdLibNull" mbdFilename="${MODULE_DIR}/BasePcdLibNull.mbd" msaFilename="${MODULE_DIR}/BasePcdLibNull.msa"/>

+   </target>

+   <target depends="BasePcdLibNull_clean" name="clean"/>

+   <target depends="BasePcdLibNull_cleanall" name="cleanall"/>

+   <target name="BasePcdLibNull_clean">

+      <OutputDirSetup baseName="BasePcdLibNull" mbdFilename="${MODULE_DIR}/BasePcdLibNull.mbd" msaFilename="${MODULE_DIR}/BasePcdLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePcdLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePcdLibNull_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePcdLibNull_cleanall">

+      <OutputDirSetup baseName="BasePcdLibNull" mbdFilename="${MODULE_DIR}/BasePcdLibNull.mbd" msaFilename="${MODULE_DIR}/BasePcdLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePcdLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePcdLibNull_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePcdLibNull*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.mbd b/edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.mbd
new file mode 100644
index 0000000..f05ef61
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePciCf8Lib</BaseName>

+    <Guid>472ab06d-9810-4c00-bb7f-dad1828fc1ab</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.msa b/edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.msa
new file mode 100644
index 0000000..24915ba
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePciCf8Lib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>472ab06d-9810-4c00-bb7f-dad1828fc1ab</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PciCf8Lib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePciCf8Lib/PciLib.c b/edk2/MdePkg/Library/BasePciCf8Lib/PciLib.c
new file mode 100644
index 0000000..108c952
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciCf8Lib/PciLib.c
@@ -0,0 +1,1441 @@
+/** @file

+  PCI Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PciLib.c

+

+**/

+

+//

+// Declare I/O Ports used to perform PCI Confguration Cycles

+//

+#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8

+#define PCI_CONFIGURATION_DATA_PORT     0xCFC

+

+//

+// Declare macro to convert PCI Library formatted address to CF8 formatted address

+//

+// PCI Library formatted address    CF8 Formatted Address

+// =============================    ======================

+//    Bits 00..11  Register           Bits 00..07  Register

+//    Bits 12..14  Function           Bits 08..10  Function

+//    Bits 15..19  Device             Bits 11..15  Device

+//    Bits 20..27  Bus                Bits 16..23  Bus

+//    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)

+//                                    Bits 31..31  Must be 1

+//

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \

+  ASSERT (((A) & (~0xffff0ff | (M))) == 0)

+

+/**

+  Convert a PCI Express address to PCI CF8 address.

+

+  @param  A The address to convert.

+

+  @retval The coverted address.

+

+**/

+#define PCI_TO_CF8_ADDRESS(A) \

+  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Read8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Write8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoWrite8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           Value

+           );

+}

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Or8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoOr8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           OrData

+           );

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8And8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoAnd8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           AndData

+           );

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8AndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoAndThenOr8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldRead8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldWrite8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldOr8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldAnd8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldAndThenOr8(

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldAndThenOr8 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Read16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Write16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoWrite16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           Value

+           );

+}

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Or16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoOr16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           OrData

+           );

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8And16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoAnd16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           AndData

+           );

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8AndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoAndThenOr16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldRead16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldWrite16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldOr16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldAnd16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldAndThenOr16(

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldAndThenOr16 (

+           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Read32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoRead32 (PCI_CONFIGURATION_DATA_PORT);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Write32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoWrite32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           Value

+           );

+}

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Or32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoOr32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           OrData

+           );

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8And32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoAnd32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           AndData

+           );

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8AndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoAndThenOr32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldRead32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldWrite32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldOr32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldAnd32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldAndThenOr32(

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  return IoBitFieldAndThenOr32 (

+           PCI_CONFIGURATION_DATA_PORT,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If the register specified by StartAddress >= 0x100, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciCf8ReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             EndAddress;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+  ASSERT ((StartAddress + Size - 1) <= 0x0FFFFFFF);

+  ASSERT (Buffer != NULL);

+

+  EndAddress = StartAddress + Size;

+

+  if (StartAddress < EndAddress && (StartAddress & 1)) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(UINT8*)Buffer = PciCf8Read8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (StartAddress < EndAddress && (StartAddress & 2)) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    *(UINT16*)Buffer = PciCf8Read16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (EndAddress - StartAddress >= 4) {

+    //

+    // Read as many double words as possible

+    //

+    *(UINT32*)Buffer = PciCf8Read32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if ((EndAddress & 2) != 0) {

+    //

+    // Read the last remaining word if exist

+    //

+    *(UINT16*)Buffer = PciCf8Read16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (EndAddress & 1) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(UINT8*)Buffer = PciCf8Read8 (StartAddress);

+  }

+

+  return Size;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If the register specified by StartAddress >= 0x100, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciCf8WriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             EndAddress;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+  ASSERT ((StartAddress + Size - 1) <= 0x0FFFFFFF);

+  ASSERT (Buffer != NULL);

+

+  EndAddress = StartAddress + Size;

+

+  if ((StartAddress < EndAddress) && ((StartAddress & 1)!= 0)) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciCf8Write8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (StartAddress < EndAddress && (StartAddress & 2)) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciCf8Write16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (EndAddress - StartAddress >= 4) {

+    //

+    // Write as many double words as possible

+    //

+    PciCf8Write32 (StartAddress, *(UINT32*)Buffer);

+    StartAddress += sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (EndAddress & 2) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciCf8Write16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (EndAddress & 1) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciCf8Write8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return Size;

+}

diff --git a/edk2/MdePkg/Library/BasePciCf8Lib/build.xml b/edk2/MdePkg/Library/BasePciCf8Lib/build.xml
new file mode 100644
index 0000000..5bdefd2
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciCf8Lib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePciCf8Lib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePciCf8Lib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePciCf8Lib">

+      <GenBuild baseName="BasePciCf8Lib" mbdFilename="${MODULE_DIR}/BasePciCf8Lib.mbd" msaFilename="${MODULE_DIR}/BasePciCf8Lib.msa"/>

+   </target>

+   <target depends="BasePciCf8Lib_clean" name="clean"/>

+   <target depends="BasePciCf8Lib_cleanall" name="cleanall"/>

+   <target name="BasePciCf8Lib_clean">

+      <OutputDirSetup baseName="BasePciCf8Lib" mbdFilename="${MODULE_DIR}/BasePciCf8Lib.mbd" msaFilename="${MODULE_DIR}/BasePciCf8Lib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciCf8Lib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciCf8Lib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePciCf8Lib_cleanall">

+      <OutputDirSetup baseName="BasePciCf8Lib" mbdFilename="${MODULE_DIR}/BasePciCf8Lib.mbd" msaFilename="${MODULE_DIR}/BasePciCf8Lib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciCf8Lib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciCf8Lib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePciCf8Lib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.mbd b/edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.mbd
new file mode 100644
index 0000000..a7051c2
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePciExpressLib</BaseName>

+    <Guid>287e50f4-a188-4699-b907-3e4080ca5688</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.msa b/edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.msa
new file mode 100644
index 0000000..c51521d
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.msa
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePciExpressLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>287e50f4-a188-4699-b907-3e4080ca5688</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PciExpressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPciExpressBaseAddress</C_Name>

+      <Token>0x0000000A</Token>

+      <DatumType>UINT64</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePciExpressLib/PciLib.c b/edk2/MdePkg/Library/BasePciExpressLib/PciLib.c
new file mode 100644
index 0000000..de33bf3
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciExpressLib/PciLib.c
@@ -0,0 +1,1337 @@
+/** @file

+  PCI Library.

+

+  Functions in this library instance make use of MMIO functions in IoLib to

+  access memory mapped PCI configuration space.

+

+  All assertions for I/O operations are handled in MMIO functions in the IoLib

+  Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PciLib.c

+

+**/

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A) \

+  ASSERT (((A) & ~0xfffffff) == 0)

+

+

+UINTN

+EFIAPI

+GetPciExpressBaseAddress (

+  VOID

+  )

+{

+  return (UINTN)PcdGet64 (PcdPciExpressBaseAddress);

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressRead8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioRead8 (GetPciExpressBaseAddress () + Address);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioWrite8 (GetPciExpressBaseAddress () + Address, Value);

+}

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioOr8 (GetPciExpressBaseAddress () + Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAnd8 (GetPciExpressBaseAddress () + Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAndThenOr8 (

+           GetPciExpressBaseAddress () + Address,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldRead8 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldWrite8 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldOr8 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAnd8 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAndThenOr8 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioRead16 (GetPciExpressBaseAddress () + Address);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioWrite16 (GetPciExpressBaseAddress () + Address, Value);

+}

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioOr16 (GetPciExpressBaseAddress () + Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAnd16 (GetPciExpressBaseAddress () + Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAndThenOr16 (

+           GetPciExpressBaseAddress () + Address,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldRead16 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldWrite16 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldOr16 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAnd16 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAndThenOr16 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioRead32 (GetPciExpressBaseAddress () + Address);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioWrite32 (GetPciExpressBaseAddress () + Address, Value);

+}

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioOr32 (GetPciExpressBaseAddress () + Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAnd32 (GetPciExpressBaseAddress () + Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAndThenOr32 (

+           GetPciExpressBaseAddress () + Address,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldRead32 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldWrite32 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldOr32 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAnd32 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAndThenOr32 (

+           GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciExpressReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             EndAddress;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+  ASSERT ((StartAddress + Size - 1) <= 0x0FFFFFFF);

+  ASSERT (Buffer != NULL);

+

+  EndAddress = StartAddress + Size;

+

+  if (StartAddress < EndAddress && (StartAddress & 1)) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(UINT8*)Buffer = PciExpressRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (StartAddress < EndAddress && (StartAddress & 2)) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    *(UINT16*)Buffer = PciExpressRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (EndAddress - StartAddress >= 4) {

+    //

+    // Read as many double words as possible

+    //

+    *(UINT32*)Buffer = PciExpressRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if ((EndAddress & 2) != 0) {

+    //

+    // Read the last remaining word if exist

+    //

+    *(UINT16*)Buffer = PciExpressRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (EndAddress & 1) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(UINT8*)Buffer = PciExpressRead8 (StartAddress);

+  }

+

+  return Size;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciExpressWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             EndAddress;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+  ASSERT ((StartAddress + Size - 1) <= 0x0FFFFFFF);

+  ASSERT (Buffer != NULL);

+

+  EndAddress = StartAddress + Size;

+

+  if ((StartAddress < EndAddress) && ((StartAddress & 1)!= 0)) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (StartAddress < EndAddress && (StartAddress & 2)) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciExpressWrite16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (EndAddress - StartAddress >= 4) {

+    //

+    // Write as many double words as possible

+    //

+    PciExpressWrite32 (StartAddress, *(UINT32*)Buffer);

+    StartAddress += sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (EndAddress & 2) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciExpressWrite16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (EndAddress & 1) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return Size;

+}

diff --git a/edk2/MdePkg/Library/BasePciExpressLib/build.xml b/edk2/MdePkg/Library/BasePciExpressLib/build.xml
new file mode 100644
index 0000000..d021c9e
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciExpressLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePciExpressLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePciExpressLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePciExpressLib">

+      <GenBuild baseName="BasePciExpressLib" mbdFilename="${MODULE_DIR}/BasePciExpressLib.mbd" msaFilename="${MODULE_DIR}/BasePciExpressLib.msa"/>

+   </target>

+   <target depends="BasePciExpressLib_clean" name="clean"/>

+   <target depends="BasePciExpressLib_cleanall" name="cleanall"/>

+   <target name="BasePciExpressLib_clean">

+      <OutputDirSetup baseName="BasePciExpressLib" mbdFilename="${MODULE_DIR}/BasePciExpressLib.mbd" msaFilename="${MODULE_DIR}/BasePciExpressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciExpressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciExpressLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePciExpressLib_cleanall">

+      <OutputDirSetup baseName="BasePciExpressLib" mbdFilename="${MODULE_DIR}/BasePciExpressLib.mbd" msaFilename="${MODULE_DIR}/BasePciExpressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciExpressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciExpressLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePciExpressLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.mbd b/edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.mbd
new file mode 100644
index 0000000..b908388
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePciLibCf8</BaseName>

+    <Guid>28bde99c-e8a7-4e3e-9a8a-e66cd64f31c6</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.msa b/edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.msa
new file mode 100644
index 0000000..d57f5b4
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePciLibCf8</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>28bde99c-e8a7-4e3e-9a8a-e66cd64f31c6</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PciLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PciCf8Lib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePciLibCf8/PciLib.c b/edk2/MdePkg/Library/BasePciLibCf8/PciLib.c
new file mode 100644
index 0000000..3a41809
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -0,0 +1,1070 @@
+/** @file

+  PCI Library using Port CF8/CFC access.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PciLib.c

+

+**/

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return PciCf8Read8 (Address);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Data

+  )

+{

+  return PciCf8Write8 (Address, Data);

+}

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8Or8 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciCf8And8 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8AndThenOr8 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciCf8BitFieldRead8 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  return PciCf8Read16 (Address);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Data

+  )

+{

+  return PciCf8Write16 (Address, Data);

+}

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8Or16 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciCf8And16 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8AndThenOr16 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciCf8BitFieldRead16 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  return PciCf8Read32 (Address);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Data

+  )

+{

+  return PciCf8Write32 (Address, Data);

+}

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8Or32 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciCf8And32 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8AndThenOr32 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciCf8BitFieldRead32 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  return PciCf8ReadBuffer (StartAddress, Size, Buffer);

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  return PciCf8WriteBuffer (StartAddress, Size, Buffer);

+}

diff --git a/edk2/MdePkg/Library/BasePciLibCf8/build.xml b/edk2/MdePkg/Library/BasePciLibCf8/build.xml
new file mode 100644
index 0000000..4e31f36
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibCf8/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePciLibCf8"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePciLibCf8"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePciLibCf8">

+      <GenBuild baseName="BasePciLibCf8" mbdFilename="${MODULE_DIR}/BasePciLibCf8.mbd" msaFilename="${MODULE_DIR}/BasePciLibCf8.msa"/>

+   </target>

+   <target depends="BasePciLibCf8_clean" name="clean"/>

+   <target depends="BasePciLibCf8_cleanall" name="cleanall"/>

+   <target name="BasePciLibCf8_clean">

+      <OutputDirSetup baseName="BasePciLibCf8" mbdFilename="${MODULE_DIR}/BasePciLibCf8.mbd" msaFilename="${MODULE_DIR}/BasePciLibCf8.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciLibCf8_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciLibCf8_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePciLibCf8_cleanall">

+      <OutputDirSetup baseName="BasePciLibCf8" mbdFilename="${MODULE_DIR}/BasePciLibCf8.mbd" msaFilename="${MODULE_DIR}/BasePciLibCf8.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciLibCf8_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciLibCf8_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePciLibCf8*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.mbd b/edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.mbd
new file mode 100644
index 0000000..c2caa74
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePciLibPciExpress</BaseName>

+    <Guid>8987081e-daeb-44a9-8bef-a195b22d9417</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.msa b/edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.msa
new file mode 100644
index 0000000..2e58851
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePciLibPciExpress</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>8987081e-daeb-44a9-8bef-a195b22d9417</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PciLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PciExpressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PciLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePciLibPciExpress/PciLib.c b/edk2/MdePkg/Library/BasePciLibPciExpress/PciLib.c
new file mode 100644
index 0000000..59bcd2d
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibPciExpress/PciLib.c
@@ -0,0 +1,1070 @@
+/** @file

+  PCI Library using PC Express access.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PciLib.c

+

+**/

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return PciExpressRead8 (Address);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Data

+  )

+{

+  return PciExpressWrite8 (Address, Data);

+}

+

+/**

+  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressOr8 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciExpressAnd8 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise inclusive OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressAndThenOr8 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciExpressBitFieldRead8 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  return PciExpressRead16 (Address);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Data

+  )

+{

+  return PciExpressWrite16 (Address, Data);

+}

+

+/**

+  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressOr16 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciExpressAnd16 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise inclusive OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressAndThenOr16 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciExpressBitFieldRead16 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  return PciExpressRead32 (Address);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Data

+  )

+{

+  return PciExpressWrite32 (Address, Data);

+}

+

+/**

+  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressOr32 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciExpressAnd32 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise inclusive OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData,

+  performs a bitwise inclusive OR between the result of the AND operation and

+  the value specified by OrData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressAndThenOr32 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciExpressBitFieldRead32 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise inclusive OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND followed by a bitwise inclusive OR between the read result and

+  the value specified by AndData, and writes the result to the 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   PCI configuration register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  return PciExpressReadBuffer (StartAddress, Size, Buffer);

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  return PciExpressWriteBuffer (StartAddress, Size, Buffer);

+}

diff --git a/edk2/MdePkg/Library/BasePciLibPciExpress/build.xml b/edk2/MdePkg/Library/BasePciLibPciExpress/build.xml
new file mode 100644
index 0000000..ab53057
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePciLibPciExpress/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePciLibPciExpress"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePciLibPciExpress"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePciLibPciExpress">

+      <GenBuild baseName="BasePciLibPciExpress" mbdFilename="${MODULE_DIR}/BasePciLibPciExpress.mbd" msaFilename="${MODULE_DIR}/BasePciLibPciExpress.msa"/>

+   </target>

+   <target depends="BasePciLibPciExpress_clean" name="clean"/>

+   <target depends="BasePciLibPciExpress_cleanall" name="cleanall"/>

+   <target name="BasePciLibPciExpress_clean">

+      <OutputDirSetup baseName="BasePciLibPciExpress" mbdFilename="${MODULE_DIR}/BasePciLibPciExpress.mbd" msaFilename="${MODULE_DIR}/BasePciLibPciExpress.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciLibPciExpress_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciLibPciExpress_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePciLibPciExpress_cleanall">

+      <OutputDirSetup baseName="BasePciLibPciExpress" mbdFilename="${MODULE_DIR}/BasePciLibPciExpress.mbd" msaFilename="${MODULE_DIR}/BasePciLibPciExpress.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePciLibPciExpress_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePciLibPciExpress_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePciLibPciExpress*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.mbd b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.mbd
new file mode 100644
index 0000000..8bb2641
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePeCoffGetEntryPointLib</BaseName>

+    <Guid>be490364-73d2-420d-950e-f6450ca75dfb</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.msa b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.msa
new file mode 100644
index 0000000..1f92c24
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.msa
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePeCoffGetEntryPointLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>be490364-73d2-420d-950e-f6450ca75dfb</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeCoffGetEntryPointLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeCoffGetEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
new file mode 100644
index 0000000..d5ff7db
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
@@ -0,0 +1,54 @@
+/** @file

+  Tiano PE/COFF loader.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PeCoffGetEntryPoint.c

+

+**/

+

+

+

+/**

+  Loads a PE/COFF image into memory.

+

+  @param  Pe32Data Pointer to a PE/COFF Image

+  

+  @param  EntryPoint Pointer to the entry point of the PE/COFF image

+

+  @retval EFI_SUCCESS            if the EntryPoint was returned

+  @retval EFI_INVALID_PARAMETER  if the EntryPoint could not be found from Pe32Data

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetEntryPoint (

+  IN     VOID  *Pe32Data,

+  IN OUT VOID  **EntryPoint

+  )

+{

+  EFI_IMAGE_DOS_HEADER  *DosHeader;

+  EFI_IMAGE_NT_HEADERS  *PeHeader;

+

+  DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;

+  if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header

+    //

+    PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));

+  } else {

+    //

+    // DOS image header is not present, so PE header is at the image base

+    //

+    PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;

+  }

+  *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHeader->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));

+  return RETURN_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/build.xml b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/build.xml
new file mode 100644
index 0000000..36286fc
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePeCoffGetEntryPointLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePeCoffGetEntryPointLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePeCoffGetEntryPointLib">

+      <GenBuild baseName="BasePeCoffGetEntryPointLib" mbdFilename="${MODULE_DIR}/BasePeCoffGetEntryPointLib.mbd" msaFilename="${MODULE_DIR}/BasePeCoffGetEntryPointLib.msa"/>

+   </target>

+   <target depends="BasePeCoffGetEntryPointLib_clean" name="clean"/>

+   <target depends="BasePeCoffGetEntryPointLib_cleanall" name="cleanall"/>

+   <target name="BasePeCoffGetEntryPointLib_clean">

+      <OutputDirSetup baseName="BasePeCoffGetEntryPointLib" mbdFilename="${MODULE_DIR}/BasePeCoffGetEntryPointLib.mbd" msaFilename="${MODULE_DIR}/BasePeCoffGetEntryPointLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePeCoffGetEntryPointLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePeCoffGetEntryPointLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePeCoffGetEntryPointLib_cleanall">

+      <OutputDirSetup baseName="BasePeCoffGetEntryPointLib" mbdFilename="${MODULE_DIR}/BasePeCoffGetEntryPointLib.mbd" msaFilename="${MODULE_DIR}/BasePeCoffGetEntryPointLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePeCoffGetEntryPointLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePeCoffGetEntryPointLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePeCoffGetEntryPointLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
new file mode 100644
index 0000000..c7f3354
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -0,0 +1,1019 @@
+/** @file

+  Tiano PE/COFF loader.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PeCoffLoader.c

+

+**/

+

+

+

+

+STATIC

+RETURN_STATUS

+PeCoffLoaderGetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  OUT    EFI_IMAGE_NT_HEADERS          *PeHdr,

+  OUT    EFI_TE_IMAGE_HEADER           *TeHdr

+  );

+

+STATIC

+RETURN_STATUS

+PeCoffLoaderCheckImageType (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  IN     EFI_IMAGE_NT_HEADERS          *PeHdr,

+  IN     EFI_TE_IMAGE_HEADER           *TeHdr

+  );

+

+STATIC

+VOID                            *

+PeCoffLoaderImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  IN     UINTN                         Address

+  );

+

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  );

+

+

+

+/**

+  Retrieves the PE or TE Header from a PE/COFF or TE image.

+

+  @param  ImageContext The context of the image being loaded.

+  

+  @param  PeHdr The buffer in which to return the PE header.

+  

+  @param  TeHdr The buffer in which to return the TE header.

+

+  @return

+  RETURN_SUCCESS if the PE or TE Header is read,

+  Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.

+

+**/

+STATIC

+RETURN_STATUS

+PeCoffLoaderGetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  OUT    EFI_IMAGE_NT_HEADERS          *PeHdr,

+  OUT    EFI_TE_IMAGE_HEADER           *TeHdr

+  )

+{

+  RETURN_STATUS            Status;

+  EFI_IMAGE_DOS_HEADER  DosHdr;

+  UINTN                 Size;

+

+  ImageContext->IsTeImage = FALSE;

+  //

+  // Read the DOS image headers

+  //

+  Size = sizeof (EFI_IMAGE_DOS_HEADER);

+  Status = ImageContext->ImageRead (

+                          ImageContext->Handle,

+                          0,

+                          &Size,

+                          &DosHdr

+                          );

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return Status;

+  }

+

+  ImageContext->PeCoffHeaderOffset = 0;

+  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header

+    //

+    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;

+  }

+  //

+  // Read the PE/COFF Header

+  //

+  Size = sizeof (EFI_IMAGE_NT_HEADERS);

+  Status = ImageContext->ImageRead (

+                          ImageContext->Handle,

+                          ImageContext->PeCoffHeaderOffset,

+                          &Size,

+                          PeHdr

+                          );

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return Status;

+  }

+  //

+  // Check the PE/COFF Header Signature. If not, then try to read a TE header

+  //

+  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {

+    Size = sizeof (EFI_TE_IMAGE_HEADER);

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &Size,

+                            TeHdr

+                            );

+    if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {

+      return RETURN_UNSUPPORTED;

+    }

+

+    ImageContext->IsTeImage = TRUE;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Checks the PE or TE header of a PE/COFF or TE image to determine if it supported.

+

+  @param  ImageContext The context of the image being loaded.

+  

+  @param  PeHdr The buffer in which to return the PE header.

+  

+  @param  TeHdr The buffer in which to return the TE header.

+

+  @retval RETURN_SUCCESS if the PE/COFF or TE image is supported

+  @retval RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported.

+

+**/

+STATIC

+RETURN_STATUS

+PeCoffLoaderCheckImageType (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN     EFI_IMAGE_NT_HEADERS                  *PeHdr,

+  IN     EFI_TE_IMAGE_HEADER                   *TeHdr

+  )

+{

+  //

+  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)

+  // and the machine type for the Virtual Machine.

+  //

+  if (ImageContext->IsTeImage == FALSE) {

+    ImageContext->Machine = PeHdr->FileHeader.Machine;

+  } else {

+    ImageContext->Machine = TeHdr->Machine;

+  }

+

+  if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;

+    return RETURN_UNSUPPORTED;

+  }

+

+  //

+  // See if the image type is supported.  We support EFI Applications,

+  // EFI Boot Service Drivers, and EFI Runtime Drivers.

+  //

+  if (ImageContext->IsTeImage == FALSE) {

+    ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;

+  } else {

+    ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);

+  }

+

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieves information on a PE/COFF image.

+

+  @param  This Calling context

+  @param  ImageContext The context of the image being loaded

+

+  @retval  RETURN_SUCCESS The information on the PE/COFF image was collected.

+  @retval  RETURN_INVALID_PARAMETER ImageContext is NULL.

+  @retval  RETURN_UNSUPPORTED The PE/COFF image is not supported.

+  @retval  Otherwise The error status from reading the PE/COFF image using the

+  ImageContext->ImageRead() function

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetImageInfo (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT           *ImageContext

+  )

+{

+  RETURN_STATUS                      Status;

+  EFI_IMAGE_NT_HEADERS            PeHdr;

+  EFI_TE_IMAGE_HEADER             TeHdr;

+  EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;

+  UINTN                           Size;

+  UINTN                           Index;

+  UINTN                           DebugDirectoryEntryRva;

+  UINTN                           DebugDirectoryEntryFileOffset;

+  UINTN                           SectionHeaderOffset;

+  EFI_IMAGE_SECTION_HEADER        SectionHeader;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;

+

+  if (NULL == ImageContext) {

+    return RETURN_INVALID_PARAMETER;

+  }

+  //

+  // Assume success

+  //

+  ImageContext->ImageError  = IMAGE_ERROR_SUCCESS;

+

+  Status                    = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Verify machine type

+  //

+  Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Retrieve the base address of the image

+  //

+  if (!(ImageContext->IsTeImage)) {

+    ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;

+  } else {

+    ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase);

+  }

+  //

+  // Initialize the alternate destination address to 0 indicating that it

+  // should not be used.

+  //

+  ImageContext->DestinationAddress = 0;

+

+  //

+  // Initialize the codeview pointer.

+  //

+  ImageContext->CodeView    = NULL;

+  ImageContext->PdbPointer  = NULL;

+

+  //

+  // Three cases with regards to relocations:

+  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but

+  //   has no base relocs to apply

+  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.

+  //

+  // Look at the file header to determine if relocations have been stripped, and

+  // save this info in the image context for later use.

+  //

+  if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {

+    ImageContext->RelocationsStripped = TRUE;

+  } else {

+    ImageContext->RelocationsStripped = FALSE;

+  }

+

+  if (!(ImageContext->IsTeImage)) {

+    ImageContext->ImageSize         = (UINT64) PeHdr.OptionalHeader.SizeOfImage;

+    ImageContext->SectionAlignment  = PeHdr.OptionalHeader.SectionAlignment;

+    ImageContext->SizeOfHeaders     = PeHdr.OptionalHeader.SizeOfHeaders;

+

+    //

+    // Modify ImageSize to contain .PDB file name if required and initialize

+    // PdbRVA field...

+    //

+    if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+      DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+

+      DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;

+

+      //

+      // Determine the file offset of the debug directory...  This means we walk

+      // the sections to find which section contains the RVA of the debug

+      // directory

+      //

+      DebugDirectoryEntryFileOffset = 0;

+

+      SectionHeaderOffset = (UINTN)(

+                               ImageContext->PeCoffHeaderOffset +

+                               sizeof (UINT32) + 

+                               sizeof (EFI_IMAGE_FILE_HEADER) + 

+                               PeHdr.FileHeader.SizeOfOptionalHeader

+                               );

+

+      for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) {

+        //

+        // Read section header from file

+        //

+        Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle,

+                                 SectionHeaderOffset,

+                                 &Size,

+                                 &SectionHeader

+                                 );

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return Status;

+        }

+

+        if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+            DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+            DebugDirectoryEntryFileOffset =

+            DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;

+          break;

+        }

+

+        SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+      }

+

+      if (DebugDirectoryEntryFileOffset != 0) {

+        for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {

+          //

+          // Read next debug directory entry

+          //

+          Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+          Status = ImageContext->ImageRead (

+                                   ImageContext->Handle,

+                                   DebugDirectoryEntryFileOffset,

+                                   &Size,

+                                   &DebugEntry

+                                   );

+          if (RETURN_ERROR (Status)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            return Status;

+          }

+

+          if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+            ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));

+            if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {

+              ImageContext->ImageSize += DebugEntry.SizeOfData;

+            }

+

+            return RETURN_SUCCESS;

+          }

+        }

+      }

+    }

+  } else {

+    ImageContext->ImageSize         = 0;

+    ImageContext->SectionAlignment  = 4096;

+    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize;

+

+    DebugDirectoryEntry             = &TeHdr.DataDirectory[1];

+    DebugDirectoryEntryRva          = DebugDirectoryEntry->VirtualAddress;

+    SectionHeaderOffset             = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));

+

+    DebugDirectoryEntryFileOffset   = 0;

+

+    for (Index = 0; Index < TeHdr.NumberOfSections;) {

+      //

+      // Read section header from file

+      //

+      Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle,

+                               SectionHeaderOffset,

+                               &Size,

+                               &SectionHeader

+                               );

+      if (RETURN_ERROR (Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+

+      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -

+          SectionHeader.VirtualAddress +

+          SectionHeader.PointerToRawData +

+          sizeof (EFI_TE_IMAGE_HEADER) -

+          TeHdr.StrippedSize;

+

+        //

+        // File offset of the debug directory was found, if this is not the last

+        // section, then skip to the last section for calculating the image size.

+        //

+        if (Index < (UINTN) TeHdr.NumberOfSections - 1) {

+          SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);

+          Index = TeHdr.NumberOfSections - 1;

+          continue;

+        }

+      }

+

+      //

+      // In Te image header there is not a field to describe the ImageSize.

+      // Actually, the ImageSize equals the RVA plus the VirtualSize of 

+      // the last section mapped into memory (Must be rounded up to 

+      // a mulitple of Section Alignment). Per the PE/COFF specification, the

+      // section headers in the Section Table must appear in order of the RVA

+      // values for the corresponding sections. So the ImageSize can be determined

+      // by the RVA and the VirtualSize of the last section header in the

+      // Section Table.

+      //

+      if ((++Index) == (UINTN) TeHdr.NumberOfSections) {

+        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +

+                                   ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);

+      }

+

+      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+    }

+

+    if (DebugDirectoryEntryFileOffset != 0) {

+      for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {

+        //

+        // Read next debug directory entry

+        //

+        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle,

+                                 DebugDirectoryEntryFileOffset,

+                                 &Size,

+                                 &DebugEntry

+                                 );

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return Status;

+        }

+

+        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));

+          return RETURN_SUCCESS;

+        }

+      }

+    }

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Converts an image address to the loaded address.

+

+  @param  ImageContext The context of the image being loaded.

+  

+  @param  Address The address to be converted to the loaded address.

+

+  @return NULL if the address can not be converted, otherwise, the converted address

+

+**/

+STATIC

+VOID *

+PeCoffLoaderImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN     UINTN                                 Address

+  )

+{

+  if (Address >= ImageContext->ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+    return NULL;

+  }

+

+  return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address);

+}

+

+/**

+  Relocates a PE/COFF image in memory.

+

+  @param  This Calling context.

+  

+  @param  ImageContext Contains information on the loaded image to relocate.

+

+  @retval RETURN_SUCCESS      if the PE/COFF image was relocated.

+  @retval RETURN_LOAD_ERROR   if the image is not a valid PE/COFF image.

+  @retval RETURN_UNSUPPORTED  not support.

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderRelocateImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  RETURN_STATUS             Status;

+  EFI_IMAGE_NT_HEADERS      *PeHdr;

+  EFI_TE_IMAGE_HEADER       *TeHdr;

+  EFI_IMAGE_DATA_DIRECTORY  *RelocDir;

+  UINT64                    Adjust;

+  EFI_IMAGE_BASE_RELOCATION *RelocBase;

+  EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;

+  UINT16                    *Reloc;

+  UINT16                    *RelocEnd;

+  CHAR8                     *Fixup;

+  CHAR8                     *FixupBase;

+  UINT16                    *F16;

+  UINT32                    *F32;

+  CHAR8                     *FixupData;

+  PHYSICAL_ADDRESS          BaseAddress;

+

+  PeHdr = NULL;

+  TeHdr = NULL;

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // If there are no relocation entries, then we are done

+  //

+  if (ImageContext->RelocationsStripped) {

+    return RETURN_SUCCESS;

+  }

+

+  //

+  // If the destination address is not 0, use that rather than the

+  // image address as the relocation target.

+  //

+  if (ImageContext->DestinationAddress) {

+    BaseAddress = ImageContext->DestinationAddress;

+  } else {

+    BaseAddress = ImageContext->ImageAddress;

+  }

+

+  if (!(ImageContext->IsTeImage)) {

+    PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + 

+                                            ImageContext->PeCoffHeaderOffset);

+    Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;

+    PeHdr->OptionalHeader.ImageBase = (UINTN)BaseAddress;

+

+    //

+    // Find the relocation block

+    //

+    // Per the PE/COFF spec, you can't assume that a given data directory

+    // is present in the image. You have to check the NumberOfRvaAndSizes in

+    // the optional header to verify a desired directory entry is there.

+    //

+    if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      RelocDir  = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+      RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);

+      RelocBaseEnd = PeCoffLoaderImageAddress (

+                      ImageContext,

+                      RelocDir->VirtualAddress + RelocDir->Size - 1

+                      );

+    } else {

+      //

+      // Set base and end to bypass processing below.

+      //

+      RelocBase = RelocBaseEnd = 0;

+    }

+  } else {

+    TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);

+    Adjust            = (UINT64) (BaseAddress - TeHdr->ImageBase);

+    TeHdr->ImageBase  = (UINT64) (BaseAddress);

+

+    //

+    // Find the relocation block

+    //

+    RelocDir = &TeHdr->DataDirectory[0];

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(

+		                                ImageContext->ImageAddress + 

+		                                RelocDir->VirtualAddress +

+		                                sizeof(EFI_TE_IMAGE_HEADER) - 

+		                                TeHdr->StrippedSize

+		                                );

+    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);

+  }

+  

+  //

+  // Run the relocation information and apply the fixups

+  //

+  FixupData = ImageContext->FixupData;

+  while (RelocBase < RelocBaseEnd) {

+

+    Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));

+    RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);

+    if (!(ImageContext->IsTeImage)) {

+      FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);

+    } else {

+      FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +

+	  	              RelocBase->VirtualAddress +

+	  	              sizeof(EFI_TE_IMAGE_HEADER) - 

+	  	              TeHdr->StrippedSize

+	  	              );

+    }

+

+    if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||

+        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + 

+          (UINTN)ImageContext->ImageSize)) {

+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+      return RETURN_LOAD_ERROR;

+    }

+

+    //

+    // Run this relocation record

+    //

+    while (Reloc < RelocEnd) {

+

+      Fixup = FixupBase + (*Reloc & 0xFFF);

+      switch ((*Reloc) >> 12) {

+      case EFI_IMAGE_REL_BASED_ABSOLUTE:

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGH:

+        F16   = (UINT16 *) Fixup;

+        *F16  = (UINT16) ((*F16 << 16) + (UINT16) Adjust);

+        if (FixupData != NULL) {

+          *(UINT16 *) FixupData = *F16;

+          FixupData             = FixupData + sizeof (UINT16);

+        }

+        break;

+

+      case EFI_IMAGE_REL_BASED_LOW:

+        F16   = (UINT16 *) Fixup;

+        *F16  = (UINT16) (*F16 + (UINT16) Adjust);

+        if (FixupData != NULL) {

+          *(UINT16 *) FixupData = *F16;

+          FixupData             = FixupData + sizeof (UINT16);

+        }

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHLOW:

+        F32   = (UINT32 *) Fixup;

+        *F32  = *F32 + (UINT32) Adjust;

+        if (FixupData != NULL) {

+          FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT32));

+          *(UINT32 *) FixupData = *F32;

+          FixupData             = FixupData + sizeof (UINT32);

+        }

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHADJ:

+        //

+        // Return the same EFI_UNSUPPORTED return code as

+        // PeCoffLoaderRelocateImageEx() returns if it does not recognize

+        // the relocation type.

+        //

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_UNSUPPORTED;

+

+      default:

+        Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+          return Status;

+        }

+      }

+

+      //

+      // Next relocation record

+      //

+      Reloc += 1;

+    }

+

+    //

+    // Next reloc block

+    //

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Loads a PE/COFF image into memory.

+

+  @param  This Calling context.

+  

+  @param  ImageContext Contains information on image to load into memory.

+

+  @retval RETURN_SUCCESS            if the PE/COFF image was loaded.

+  @retval RETURN_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer.

+  @retval RETURN_LOAD_ERROR         if the image is a runtime driver with no relocations.

+  @retval RETURN_INVALID_PARAMETER  if the image address is invalid.

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderLoadImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  RETURN_STATUS                            Status;

+  EFI_IMAGE_NT_HEADERS                  *PeHdr;

+  EFI_TE_IMAGE_HEADER                   *TeHdr;

+  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;

+  EFI_IMAGE_SECTION_HEADER              *FirstSection;

+  EFI_IMAGE_SECTION_HEADER              *Section;

+  UINTN                                 NumberOfSections;

+  UINTN                                 Index;

+  CHAR8                                 *Base;

+  CHAR8                                 *End;

+  CHAR8                                 *MaxEnd;

+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;

+  UINTN                                 Size;

+  UINT32                                TempDebugEntryRva;

+

+  PeHdr = NULL;

+  TeHdr = NULL;

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // Copy the provided context info into our local version, get what we

+  // can from the original image, and then use that to make sure everything

+  // is legit.

+  //

+  CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));

+

+  Status = PeCoffLoaderGetImageInfo (&CheckContext);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure there is enough allocated space for the image being loaded

+  //

+  if (ImageContext->ImageSize < CheckContext.ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;

+    return RETURN_BUFFER_TOO_SMALL;

+  }

+

+  //

+  // If there's no relocations, then make sure it's not a runtime driver,

+  // and that it's being loaded at the linked address.

+  //

+  if (CheckContext.RelocationsStripped) {

+    //

+    // If the image does not contain relocations and it is a runtime driver

+    // then return an error.

+    //

+    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+      return RETURN_LOAD_ERROR;

+    }

+    //

+    // If the image does not contain relocations, and the requested load address

+    // is not the linked address, then return an error.

+    //

+    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+      return RETURN_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Make sure the allocated space has the proper section alignment

+  //

+  if (!(ImageContext->IsTeImage)) {

+    if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;

+      return RETURN_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Read the entire PE/COFF or TE header into memory

+  //

+  if (!(ImageContext->IsTeImage)) {

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &ImageContext->SizeOfHeaders,

+                            (VOID *) (UINTN) ImageContext->ImageAddress

+                            );

+

+    PeHdr = (EFI_IMAGE_NT_HEADERS *)

+      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);

+

+    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+                      (UINTN)ImageContext->ImageAddress +

+                      ImageContext->PeCoffHeaderOffset +

+                      sizeof(UINT32) + 

+                      sizeof(EFI_IMAGE_FILE_HEADER) + 

+                      PeHdr->FileHeader.SizeOfOptionalHeader

+      );

+    NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections);

+  } else {

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &ImageContext->SizeOfHeaders,

+                            (void *) (UINTN) ImageContext->ImageAddress

+                            );

+

+    TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);

+

+    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+		      (UINTN)ImageContext->ImageAddress +

+		      sizeof(EFI_TE_IMAGE_HEADER)

+		      );

+    NumberOfSections  = (UINTN) (TeHdr->NumberOfSections);

+

+  }

+

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return RETURN_LOAD_ERROR;

+  }

+

+  //

+  // Load each section of the image

+  //

+  Section = FirstSection;

+  for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {

+

+    //

+    // Compute sections address

+    //

+    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);

+    End = PeCoffLoaderImageAddress (

+            ImageContext,

+            Section->VirtualAddress + Section->Misc.VirtualSize - 1

+            );

+    if (ImageContext->IsTeImage) {

+      Base  = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);

+      End   = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);

+    }

+

+    if (End > MaxEnd) {

+      MaxEnd = End;

+    }

+    //

+    // If the base start or end address resolved to 0, then fail.

+    //

+    if ((Base == NULL) || (End == NULL)) {

+      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;

+      return RETURN_LOAD_ERROR;

+    }

+

+    //

+    // Read the section

+    //

+    Size = (UINTN) Section->Misc.VirtualSize;

+    if ((Size == 0) || (Size > Section->SizeOfRawData)) {

+      Size = (UINTN) Section->SizeOfRawData;

+    }

+

+    if (Section->SizeOfRawData) {

+      if (!(ImageContext->IsTeImage)) {

+        Status = ImageContext->ImageRead (

+                                ImageContext->Handle,

+                                Section->PointerToRawData,

+                                &Size,

+                                Base

+                                );

+      } else {

+        Status = ImageContext->ImageRead (

+                                ImageContext->Handle,

+                                Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,

+                                &Size,

+                                Base

+                                );

+      }

+

+      if (RETURN_ERROR (Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+    }

+

+    //

+    // If raw size is less then virt size, zero fill the remaining

+    //

+

+    if (Size < Section->Misc.VirtualSize) {

+      ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);

+    }

+

+    //

+    // Next Section

+    //

+    Section += 1;

+  }

+

+  //

+  // Get image's entry point

+  //

+  if (!(ImageContext->IsTeImage)) {

+    ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (

+                                                                ImageContext,

+                                                                PeHdr->OptionalHeader.AddressOfEntryPoint

+                                                                );

+  } else {

+    ImageContext->EntryPoint =  (PHYSICAL_ADDRESS) (

+		                   (UINTN)ImageContext->ImageAddress +

+		                   (UINTN)TeHdr->AddressOfEntryPoint +

+		                   (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -

+          (UINTN) TeHdr->StrippedSize

+      );

+  }

+

+  //

+  // Determine the size of the fixup data

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory

+  // is present in the image. You have to check the NumberOfRvaAndSizes in

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (!(ImageContext->IsTeImage)) {

+    if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)

+        &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);

+    } else {

+      ImageContext->FixupDataSize = 0;

+    }

+  } else {

+    DirectoryEntry              = &TeHdr->DataDirectory[0];

+    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);

+  }

+  //

+  // Consumer must allocate a buffer for the relocation fixup log.

+  // Only used for runtime drivers.

+  //

+  ImageContext->FixupData = NULL;

+

+  //

+  // Load the Codeview info if present

+  //

+  if (ImageContext->DebugDirectoryEntryRva != 0) {

+    if (!(ImageContext->IsTeImage)) {

+      DebugEntry = PeCoffLoaderImageAddress (

+                    ImageContext,

+                    ImageContext->DebugDirectoryEntryRva

+                    );

+    } else {

+      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(

+	  	                                         ImageContext->ImageAddress +

+	  	                                         ImageContext->DebugDirectoryEntryRva +

+	  	                                         sizeof(EFI_TE_IMAGE_HEADER) -

+	  	                                         TeHdr->StrippedSize

+	  	                                         );

+    }

+

+    if (DebugEntry != NULL) {

+      TempDebugEntryRva = DebugEntry->RVA;

+      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {

+        Section--;

+        if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {

+          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;

+        } else {

+          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;

+        }

+      }

+

+      if (TempDebugEntryRva != 0) {

+        if (!(ImageContext->IsTeImage)) {

+          ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);

+        } else {

+          ImageContext->CodeView = (VOID *)(

+		  	              (UINTN)ImageContext->ImageAddress +

+		  	              (UINTN)TempDebugEntryRva +

+		  	              (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -

+                (UINTN) TeHdr->StrippedSize

+            );

+        }

+

+        if (ImageContext->CodeView == NULL) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return RETURN_LOAD_ERROR;

+        }

+

+        if (DebugEntry->RVA == 0) {

+          Size = DebugEntry->SizeOfData;

+          if (!(ImageContext->IsTeImage)) {

+            Status = ImageContext->ImageRead (

+                                    ImageContext->Handle,

+                                    DebugEntry->FileOffset,

+                                    &Size,

+                                    ImageContext->CodeView

+                                    );

+          } else {

+            Status = ImageContext->ImageRead (

+                                    ImageContext->Handle,

+                                    DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,

+                                    &Size,

+                                    ImageContext->CodeView

+                                    );

+            //

+            // Should we apply fix up to this field according to the size difference between PE and TE?

+            // Because now we maintain TE header fields unfixed, this field will also remain as they are

+            // in original PE image.

+            //

+          }

+

+          if (RETURN_ERROR (Status)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            return RETURN_LOAD_ERROR;

+          }

+

+          DebugEntry->RVA = TempDebugEntryRva;

+        }

+

+        switch (*(UINT32 *) ImageContext->CodeView) {

+        case CODEVIEW_SIGNATURE_NB10:

+          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);

+          break;

+

+        case CODEVIEW_SIGNATURE_RSDS:

+          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);

+          break;

+

+        default:

+          break;

+        }

+      }

+    }

+  }

+

+  return Status;

+}

diff --git a/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.mbd b/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.mbd
new file mode 100644
index 0000000..7e8def9
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePeCoffLib</BaseName>

+    <Guid>556f5d10-7309-4af4-b80a-8196bd60946f</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.msa b/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.msa
new file mode 100644
index 0000000..6efb353
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.msa
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePeCoffLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>556f5d10-7309-4af4-b80a-8196bd60946f</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the PEI library.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004 - 2005, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeCoffLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BasePeCoff.c</Filename>

+    <Arch ArchType="IA32">

+      <Filename>Ia32/PeCoffLoaderEx.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x64/PeCoffLoaderEx.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>ipf/PeCoffLoaderEx.c</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>ebc/PeCoffLoaderEx.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePeCoffLib/Ebc/PeCoffLoaderEx.c b/edk2/MdePkg/Library/BasePeCoffLib/Ebc/PeCoffLoaderEx.c
new file mode 100644
index 0000000..6cfc566
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/Ebc/PeCoffLoaderEx.c
@@ -0,0 +1,43 @@
+/** @file

+  EBC Specific relocation fixups.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PeCoffLoaderEx.c

+

+**/

+

+

+

+

+/**

+  Performs an IA-32 specific relocation fixup.

+

+  @param  Reloc Pointer to the relocation record.

+

+  @param  Fixup Pointer to the address to fix up.

+

+  @param  FixupData Pointer to a buffer to log the fixups.

+

+  @param  Adjust The offset to adjust the fixup.

+

+  @retval  EFI_UNSUPPORTED Unsupported now.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  return RETURN_UNSUPPORTED;

+}

diff --git a/edk2/MdePkg/Library/BasePeCoffLib/Ia32/PeCoffLoaderEx.c b/edk2/MdePkg/Library/BasePeCoffLib/Ia32/PeCoffLoaderEx.c
new file mode 100644
index 0000000..4ee64c2
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/Ia32/PeCoffLoaderEx.c
@@ -0,0 +1,44 @@
+/** @file

+  IA-32 Specific relocation fixups.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PeCoffLoaderEx.c

+

+**/

+

+

+

+

+

+/**

+  Performs an IA-32 specific relocation fixup.

+

+  @param  Reloc Pointer to the relocation record.

+

+  @param  Fixup Pointer to the address to fix up.

+

+  @param  FixupData Pointer to a buffer to log the fixups.

+

+  @param  Adjust The offset to adjust the fixup.

+

+  @retval  EFI_UNSUPPORTED Unsupported now.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  return RETURN_UNSUPPORTED;

+}

diff --git a/edk2/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c b/edk2/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
new file mode 100644
index 0000000..d35231e
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
@@ -0,0 +1,230 @@
+/** @file

+  Fixes Intel Itanium(TM) specific relocation types.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PeCoffLoaderEx.c

+

+**/

+

+

+

+

+

+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos)  \

+    Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)

+

+#define INS_IMM64(Value, Address, Size, InstPos, ValPos)  \

+    *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \

+          ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)

+

+#define IMM64_IMM7B_INST_WORD_X         3  

+#define IMM64_IMM7B_SIZE_X              7  

+#define IMM64_IMM7B_INST_WORD_POS_X     4  

+#define IMM64_IMM7B_VAL_POS_X           0  

+

+#define IMM64_IMM9D_INST_WORD_X         3  

+#define IMM64_IMM9D_SIZE_X              9  

+#define IMM64_IMM9D_INST_WORD_POS_X     18  

+#define IMM64_IMM9D_VAL_POS_X           7  

+

+#define IMM64_IMM5C_INST_WORD_X         3  

+#define IMM64_IMM5C_SIZE_X              5  

+#define IMM64_IMM5C_INST_WORD_POS_X     13  

+#define IMM64_IMM5C_VAL_POS_X           16  

+

+#define IMM64_IC_INST_WORD_X            3  

+#define IMM64_IC_SIZE_X                 1  

+#define IMM64_IC_INST_WORD_POS_X        12  

+#define IMM64_IC_VAL_POS_X              21  

+

+#define IMM64_IMM41a_INST_WORD_X        1  

+#define IMM64_IMM41a_SIZE_X             10  

+#define IMM64_IMM41a_INST_WORD_POS_X    14  

+#define IMM64_IMM41a_VAL_POS_X          22  

+

+#define IMM64_IMM41b_INST_WORD_X        1  

+#define IMM64_IMM41b_SIZE_X             8  

+#define IMM64_IMM41b_INST_WORD_POS_X    24  

+#define IMM64_IMM41b_VAL_POS_X          32  

+

+#define IMM64_IMM41c_INST_WORD_X        2  

+#define IMM64_IMM41c_SIZE_X             23  

+#define IMM64_IMM41c_INST_WORD_POS_X    0  

+#define IMM64_IMM41c_VAL_POS_X          40  

+

+#define IMM64_SIGN_INST_WORD_X          3  

+#define IMM64_SIGN_SIZE_X               1  

+#define IMM64_SIGN_INST_WORD_POS_X      27  

+#define IMM64_SIGN_VAL_POS_X            63  

+

+/**

+  Performs an Itanium-based specific relocation fixup.

+

+  @param  Reloc Pointer to the relocation record.

+  

+  @param  Fixup Pointer to the address to fix up.

+  

+  @param  FixupData Pointer to a buffer to log the fixups.

+  

+  @param  Adjust The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup, 

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT64      *F64;

+  UINT64      FixupVal;

+

+  switch ((*Reloc) >> 12) {

+

+    case EFI_IMAGE_REL_BASED_DIR64:

+      F64 = (UINT64 *) Fixup;

+      *F64 = *F64 + (UINT64) Adjust;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    case EFI_IMAGE_REL_BASED_IA64_IMM64:

+

+      //

+      // Align it to bundle address before fixing up the

+      // 64-bit immediate value of the movl instruction.

+      //

+

+      Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));

+      FixupVal = (UINT64)0;

+                       

+      // 

+      // Extract the lower 32 bits of IMM64 from bundle

+      //

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,

+                IMM64_IMM7B_SIZE_X,

+                IMM64_IMM7B_INST_WORD_POS_X,

+                IMM64_IMM7B_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,

+                IMM64_IMM9D_SIZE_X,

+                IMM64_IMM9D_INST_WORD_POS_X,

+                IMM64_IMM9D_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,

+                IMM64_IMM5C_SIZE_X,

+                IMM64_IMM5C_INST_WORD_POS_X,

+                IMM64_IMM5C_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,

+                IMM64_IC_SIZE_X,

+                IMM64_IC_INST_WORD_POS_X,

+                IMM64_IC_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,

+                IMM64_IMM41a_SIZE_X,

+                IMM64_IMM41a_INST_WORD_POS_X,

+                IMM64_IMM41a_VAL_POS_X

+                );

+                       

+      // 

+      // Update 64-bit address

+      //

+      FixupVal += Adjust;

+

+      // 

+      // Insert IMM64 into bundle

+      //

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),

+                IMM64_IMM7B_SIZE_X,

+                IMM64_IMM7B_INST_WORD_POS_X,

+                IMM64_IMM7B_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),

+                IMM64_IMM9D_SIZE_X,

+                IMM64_IMM9D_INST_WORD_POS_X,

+                IMM64_IMM9D_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),

+                IMM64_IMM5C_SIZE_X,

+                IMM64_IMM5C_INST_WORD_POS_X,

+                IMM64_IMM5C_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),

+                IMM64_IC_SIZE_X,

+                IMM64_IC_INST_WORD_POS_X,

+                IMM64_IC_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),

+                IMM64_IMM41a_SIZE_X,

+                IMM64_IMM41a_INST_WORD_POS_X,

+                IMM64_IMM41a_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),

+                IMM64_IMM41b_SIZE_X,

+                IMM64_IMM41b_INST_WORD_POS_X,

+                IMM64_IMM41b_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),

+                IMM64_IMM41c_SIZE_X,

+                IMM64_IMM41c_INST_WORD_POS_X,

+                IMM64_IMM41c_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),

+                IMM64_SIGN_SIZE_X,

+                IMM64_SIGN_INST_WORD_POS_X,

+                IMM64_SIGN_VAL_POS_X

+                );

+

+      F64 = (UINT64 *) Fixup;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/BasePeCoffLib/build.xml b/edk2/MdePkg/Library/BasePeCoffLib/build.xml
new file mode 100644
index 0000000..cd2e0fd
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePeCoffLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePeCoffLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePeCoffLib">

+      <GenBuild baseName="BasePeCoffLib" mbdFilename="${MODULE_DIR}/BasePeCoffLib.mbd" msaFilename="${MODULE_DIR}/BasePeCoffLib.msa"/>

+   </target>

+   <target depends="BasePeCoffLib_clean" name="clean"/>

+   <target depends="BasePeCoffLib_cleanall" name="cleanall"/>

+   <target name="BasePeCoffLib_clean">

+      <OutputDirSetup baseName="BasePeCoffLib" mbdFilename="${MODULE_DIR}/BasePeCoffLib.mbd" msaFilename="${MODULE_DIR}/BasePeCoffLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePeCoffLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePeCoffLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePeCoffLib_cleanall">

+      <OutputDirSetup baseName="BasePeCoffLib" mbdFilename="${MODULE_DIR}/BasePeCoffLib.mbd" msaFilename="${MODULE_DIR}/BasePeCoffLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePeCoffLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePeCoffLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePeCoffLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePeCoffLib/x64/PeCoffLoaderEx.c b/edk2/MdePkg/Library/BasePeCoffLib/x64/PeCoffLoaderEx.c
new file mode 100644
index 0000000..7648447
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePeCoffLib/x64/PeCoffLoaderEx.c
@@ -0,0 +1,56 @@
+/** @file

+  x64 Specific relocation fixups.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PeCoffLoaderEx.c

+

+**/

+

+

+

+

+/**

+  Performs an x64 specific relocation fixup.

+

+  @param  Reloc Pointer to the relocation record

+  @param  Fixup Pointer to the address to fix up

+  @param  FixupData Pointer to a buffer to log the fixups

+  @param  Adjust The offset to adjust the fixup

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup, 

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT64      *F64;

+

+  switch ((*Reloc) >> 12) {

+

+    case EFI_IMAGE_REL_BASED_DIR64:

+      F64 = (UINT64 *) Fixup;

+      *F64 = *F64 + (UINT64) Adjust;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.mbd b/edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.mbd
new file mode 100644
index 0000000..ac9c3ac
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePerformanceLibNull</BaseName>

+    <Guid>FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:05</Created>

+    <Modified>2006-04-04 11:05</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.msa b/edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.msa
new file mode 100644
index 0000000..f288f36
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.msa
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePerformanceLibNull</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-04 11:05</Created>

+    <Updated>2006-04-04 11:05</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PerformanceLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PerformanceLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c b/edk2/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
new file mode 100644
index 0000000..01226cb
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
@@ -0,0 +1,148 @@
+/** @file

+  Base Performance Library which provides no service.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PerformanceLib.c

+

+**/

+

+/**

+  Creates a record for the beginning of a performance measurement. 

+  

+  Creates a record that contains the Handle, Token, and Module.

+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.

+  If TimeStamp is zero, then this function reads the current time stamp

+  and adds that time stamp value to the record as the start time.

+

+	@param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+	@param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+	@param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+	@param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+	@retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,

+  IN CONST CHAR8  *Module,

+  IN UINT64       TimeStamp

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Fills in the end time of a performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then TimeStamp is added to the record as the end time.

+  If the record is found and TimeStamp is zero, then this function reads

+  the current time stamp and adds that time stamp value to the record as the end time.

+  If this function is called multiple times for the same record, then the end time is overwritten.

+

+	@param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+	@param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+	@param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+	@param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.

+	@retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,

+  IN CONST CHAR8  *Module,

+  IN UINT64       TimeStamp

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieves a previously logged performance measurement. 

+  

+  Retrieves the performance log entry from the performance log

+  that immediately follows the log entry specified by LogEntryKey.

+  If LogEntryKey is zero, then the first entry from the performance log is returned.

+  If the log entry specified by LogEntryKey is the last entry in the performance log,

+  then 0 is returned.  Otherwise, the performance log entry is returned in Handle,

+  Token, Module, StartTimeStamp, and EndTimeStamp.

+  The key for the current performance log entry is returned. 

+

+  @param  LogEntryKey             The key for the previous performance measurement log entry.

+                                  If 0, then the first performance measurement log entry is retrieved.

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  StartTimeStamp          The 64-bit time stamp that was recorded when the measurement was started.

+  @param  EndTimeStamp            The 64-bit time stamp that was recorded when the measurement was ended.

+

+  @return The key for the current performance log entry.

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurement (

+  UINTN           LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp

+  )

+{

+  ASSERT (Handle != NULL);

+  ASSERT (Token != NULL);

+  ASSERT (Module != NULL);

+  ASSERT (StartTimeStamp != NULL);

+  ASSERT (EndTimeStamp != NULL);

+

+  return 0;

+}

+

+/**

+  Returns TRUE if the performance measurement macros are enabled. 

+  

+  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is set.

+	@retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PerformanceMeasurementEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/BasePerformanceLibNull/build.xml b/edk2/MdePkg/Library/BasePerformanceLibNull/build.xml
new file mode 100644
index 0000000..ffb6803
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePerformanceLibNull/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePerformanceLibNull"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePerformanceLibNull"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePerformanceLibNull">

+      <GenBuild baseName="BasePerformanceLibNull" mbdFilename="${MODULE_DIR}/BasePerformanceLibNull.mbd" msaFilename="${MODULE_DIR}/BasePerformanceLibNull.msa"/>

+   </target>

+   <target depends="BasePerformanceLibNull_clean" name="clean"/>

+   <target depends="BasePerformanceLibNull_cleanall" name="cleanall"/>

+   <target name="BasePerformanceLibNull_clean">

+      <OutputDirSetup baseName="BasePerformanceLibNull" mbdFilename="${MODULE_DIR}/BasePerformanceLibNull.mbd" msaFilename="${MODULE_DIR}/BasePerformanceLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePerformanceLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePerformanceLibNull_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePerformanceLibNull_cleanall">

+      <OutputDirSetup baseName="BasePerformanceLibNull" mbdFilename="${MODULE_DIR}/BasePerformanceLibNull.mbd" msaFilename="${MODULE_DIR}/BasePerformanceLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePerformanceLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePerformanceLibNull_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePerformanceLibNull*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BasePrintLib/BasePrintLib.mbd b/edk2/MdePkg/Library/BasePrintLib/BasePrintLib.mbd
new file mode 100644
index 0000000..8ac041b
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePrintLib/BasePrintLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BasePrintLib</BaseName>

+    <Guid>a86fbfca-0183-4eeb-aa8a-762e3b7da1f3</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BasePrintLib/BasePrintLib.msa b/edk2/MdePkg/Library/BasePrintLib/BasePrintLib.msa
new file mode 100644
index 0000000..ef0159a
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePrintLib/BasePrintLib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BasePrintLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>a86fbfca-0183-4eeb-aa8a-762e3b7da1f3</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PrintLib.c</Filename>

+    <Filename>PrintLibInternal.c</Filename>

+    <Filename>PrintLibInternal.h</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BasePrintLib/PrintLib.c b/edk2/MdePkg/Library/BasePrintLib/PrintLib.c
new file mode 100644
index 0000000..84dceb6
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePrintLib/PrintLib.c
@@ -0,0 +1,976 @@
+/** @file

+  Print Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PrintLib.c

+

+**/

+

+#include "PrintLibInternal.h"

+

+typedef struct {

+  RETURN_STATUS  Status;

+  CHAR8          *String;

+} STATUS_LOOKUP_TABLE_ENTRY;

+

+static CONST STATUS_LOOKUP_TABLE_ENTRY  StatusString[] = {

+  { RETURN_SUCCESS,               "Success" },

+  { RETURN_LOAD_ERROR,            "Load Error" },

+  { RETURN_INVALID_PARAMETER,     "Invalid Parameter" },

+  { RETURN_UNSUPPORTED,           "Unsupported" },

+  { RETURN_BAD_BUFFER_SIZE,       "Bad Buffer Size" },

+  { RETURN_BUFFER_TOO_SMALL,      "Buffer Too Small" },

+  { RETURN_NOT_READY,             "Not Ready" },

+  { RETURN_DEVICE_ERROR,          "Device Error" },

+  { RETURN_WRITE_PROTECTED,       "Write Protected" },

+  { RETURN_OUT_OF_RESOURCES,      "Out of Resources" },

+  { RETURN_VOLUME_CORRUPTED,      "Volume Corrupt" },

+  { RETURN_VOLUME_FULL,           "Volume Full" },

+  { RETURN_NO_MEDIA,              "No Media" },

+  { RETURN_MEDIA_CHANGED,         "Media changed" },

+  { RETURN_NOT_FOUND,             "Not Found" },

+  { RETURN_ACCESS_DENIED,         "Access Denied" },

+  { RETURN_NO_RESPONSE,           "No Response" },

+  { RETURN_NO_MAPPING,            "No mapping" },

+  { RETURN_TIMEOUT,               "Time out" },

+  { RETURN_NOT_STARTED,           "Not started" },

+  { RETURN_ALREADY_STARTED,       "Already started" },

+  { RETURN_ABORTED,               "Aborted" },

+  { RETURN_ICMP_ERROR,            "ICMP Error" },

+  { RETURN_TFTP_ERROR,            "TFTP Error" },

+  { RETURN_PROTOCOL_ERROR,        "Protocol Error" },

+  { RETURN_WARN_UNKNOWN_GLYPH,    "Warning Unknown Glyph" },

+  { RETURN_WARN_DELETE_FAILURE,   "Warning Delete Failure" },

+  { RETURN_WARN_WRITE_FAILURE,    "Warning Write Failure" },

+  { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" },

+  { 0,                              NULL                     }

+};

+

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and a VA_LIST argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+  @param  Buffer      Character buffer to print the results of the parsing

+                      of Format into.

+  @param  BufferSize  Maximum number of characters to put into buffer.

+                      Zero means no limit.

+  @param  Flags       Intial flags value.

+                      Can only have FORMAT_UNICODE and OUTPUT_UNICODE set

+  @param  Format      Null-terminated format string.

+  @param  Marker      Vararg list consumed by processing Format.

+

+  @return Number of characters printed.

+

+**/

+UINTN

+BasePrintLibVSPrint (

+  OUT CHAR8        *Buffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *Format,

+  IN  VA_LIST      Marker

+  )

+{

+  CHAR8           *OriginalBuffer;

+  CHAR8           ValueBuffer[MAXIMUM_VALUE_CHARACTERS];

+  UINTN           BytesPerOutputCharacter;

+  UINTN           BytesPerFormatCharacter;

+  UINTN           FormatMask;

+  UINTN           FormatCharacter;

+  UINTN           Width;

+  UINTN           Precision;

+  INT64           Value;

+  CHAR8           *ArgumentString;

+  UINTN           Character;

+  GUID            *TmpGuid;

+  TIME            *TmpTime;

+  UINTN           Count;

+  UINTN           ArgumentMask;

+  INTN            BytesPerArgumentCharacter;

+  UINTN           ArgumentCharacter;

+  BOOLEAN         Done;

+  UINTN           Index;

+  CHAR8           Prefix;

+  BOOLEAN         ZeroPad;

+  BOOLEAN         Comma;

+  UINTN           Digits;

+  UINTN           Radix;

+  RETURN_STATUS   Status;

+

+  OriginalBuffer = Buffer;

+

+  if ((Flags & OUTPUT_UNICODE) != 0) {

+    BytesPerOutputCharacter = 2;

+  } else {

+    BytesPerOutputCharacter = 1;

+  }

+  if ((Flags & FORMAT_UNICODE) != 0) {

+    BytesPerFormatCharacter = 2;

+    FormatMask = 0xffff;

+  } else {

+    BytesPerFormatCharacter = 1;

+    FormatMask = 0xff;

+  }

+

+  //

+  // Reserve space for the Null terminator.

+  // If BufferSize is 0, this will set BufferSize to the max unsigned value

+  //

+  BufferSize--;

+

+  //

+  // Get the first character from the format string

+  //

+  FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+

+  //

+  // Loop until the end of the format string is reached or the output buffer is full

+  //

+  while (FormatCharacter != 0 && BufferSize > 0) {

+    //

+    // Clear all the flag bits except those that may have been passed in

+    //

+    Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE);

+

+    //

+    // Set the default width to zero, and the default precision to 1

+    //

+    Width     = 0;

+    Precision = 1;

+    Prefix    = 0;

+    Comma     = FALSE;

+    ZeroPad   = FALSE;

+    Count     = 0;

+    Digits    = 0;

+

+    switch (FormatCharacter) {

+    case '%':

+      //

+      // Parse Flags and Width

+      //

+      for (Done = FALSE; !Done; ) {

+        Format += BytesPerFormatCharacter;

+        FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+        switch (FormatCharacter) {

+        case '.': 

+          Flags |= PRECISION; 

+          break;

+        case '-': 

+          Flags |= LEFT_JUSTIFY; 

+          break;

+        case '+': 

+          Flags |= PREFIX_SIGN;  

+          break;

+        case ' ': 

+          Flags |= PREFIX_BLANK; 

+          break;

+        case ',': 

+          Flags |= COMMA_TYPE; 

+          break;

+        case 'L':

+        case 'l': 

+          Flags |= LONG_TYPE;    

+          break;

+        case '*':

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PAD_TO_WIDTH;

+            Width = VA_ARG (Marker, UINTN);

+          } else {

+            Precision = VA_ARG (Marker, UINTN);

+          }

+          break;

+        case '0':

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PREFIX_ZERO;

+          }

+        case '1':

+        case '2':

+        case '3':

+        case '4':

+        case '5':

+        case '6':

+        case '7':

+        case '8':

+        case '9':

+          for (Count = 0; ((FormatCharacter >= '0') &&  (FormatCharacter <= '9')); ){

+            Count = (Count * 10) + FormatCharacter - '0';

+            Format += BytesPerFormatCharacter;

+            FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+          }

+          Format -= BytesPerFormatCharacter;

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PAD_TO_WIDTH;

+            Width = Count;

+          } else {

+            Precision = Count;

+          }

+          break;

+        default:

+          Done = TRUE;

+          break;

+        }

+      } 

+

+      //

+      // Limit the maximum field width to the remaining characters in the output buffer

+      //

+      if (Width > BufferSize) {

+        Width = BufferSize;

+      }

+

+      //

+      // Handle each argument type

+      //

+      switch (FormatCharacter) {

+      case 'p':

+        if (sizeof (VOID *) > 4) {

+          Flags |= LONG_TYPE;

+        }

+      case 'X':

+        Flags |= PREFIX_ZERO;

+        //

+        // break skiped on purpose

+        //

+      case 'x':

+        Flags |= RADIX_HEX;

+        //

+        // break skiped on purpose

+        //

+      case 'd':

+        if ((Flags & LONG_TYPE) == 0) {

+          Value = (VA_ARG (Marker, int));

+        } else {

+          Value = VA_ARG (Marker, INT64);

+        }

+        if ((Flags & PREFIX_BLANK) != 0) {

+          Prefix = ' ';

+        }

+        if ((Flags & PREFIX_SIGN) != 0) {

+          Prefix = '+';

+        }

+        if ((Flags & COMMA_TYPE) != 0) {

+          Comma = TRUE;

+        }

+        if ((Flags & RADIX_HEX) == 0) {

+          Radix = 10;

+          if (Comma) {

+            Flags &= (~PREFIX_ZERO);

+            Precision = 1;

+          }

+          if (Value < 0) {

+            Flags |= PREFIX_SIGN;

+            Prefix = '-';

+            Value = -Value;

+          }

+        } else {

+          Radix = 16;

+          Comma = FALSE;

+          if ((Flags & LONG_TYPE) == 0 && Value < 0) {

+            Value = (unsigned int)Value;

+          }

+        }

+        //

+        // Convert Value to a reversed string

+        //

+        Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);

+        if (Value == 0 && Precision == 0) {

+          Count = 0;

+        }

+        ArgumentString = (CHAR8 *)ValueBuffer + Count;

+        Digits = 3 - (Count % 3);

+        if (Comma && Count != 0) {

+          Count += ((Count - 1) / 3);

+        }

+        if (Prefix != 0) {

+          Count++;

+        }

+        Flags |= ARGUMENT_REVERSED;

+        ZeroPad = TRUE;

+        if ((Flags & PREFIX_ZERO) != 0) {

+          if ((Flags & PAD_TO_WIDTH) != 0) {

+            if ((Flags & PRECISION) == 0) {

+              Precision = Width;

+            }

+          }

+        }

+        break;

+

+      case 's':

+      case 'S':

+        Flags |= ARGUMENT_UNICODE;

+        //

+        // break skipped on purpose

+        //

+      case 'a':

+        ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);

+        if (ArgumentString == NULL) {

+          Flags &= (~ARGUMENT_UNICODE);

+          ArgumentString = "<null string>";

+        }

+        break;

+

+      case 'c':

+        Character = VA_ARG (Marker, UINTN) & 0xffff;

+        ArgumentString = (CHAR8 *)&Character;

+        Flags |= ARGUMENT_UNICODE;

+        break;

+

+      case 'g':

+        TmpGuid = VA_ARG (Marker, GUID *);

+        if (TmpGuid == NULL) {

+          ArgumentString = "<null guid>";

+        } else {

+          BasePrintLibSPrint (

+            ValueBuffer,

+            0, 

+            0,

+            "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",

+            TmpGuid->Data1,

+            TmpGuid->Data2,

+            TmpGuid->Data3,

+            TmpGuid->Data4[0],

+            TmpGuid->Data4[1],

+            TmpGuid->Data4[2],

+            TmpGuid->Data4[3],

+            TmpGuid->Data4[4],

+            TmpGuid->Data4[5],

+            TmpGuid->Data4[6],

+            TmpGuid->Data4[7]

+            );

+          ArgumentString = ValueBuffer;

+        }

+        break;

+

+      case 't':

+        TmpTime = VA_ARG (Marker, TIME *); 

+        if (TmpTime == NULL) {

+          ArgumentString = "<null time>";

+        } else {

+          BasePrintLibSPrint (

+            ValueBuffer,

+            0,

+            0,

+            "%02d/%02d/%04d  %02d:%02d",

+            TmpTime->Month,

+            TmpTime->Day,

+            TmpTime->Year,

+            TmpTime->Hour,

+            TmpTime->Minute

+            );

+          ArgumentString = ValueBuffer;

+        }

+        break;

+

+      case 'r':

+        Status = VA_ARG (Marker, RETURN_STATUS);

+        ArgumentString = ValueBuffer;

+        for (Index = 0; StatusString[Index].String != NULL; Index++) {

+          if (Status == StatusString[Index].Status) {

+            ArgumentString = StatusString[Index].String;

+          }

+        }

+        if (ArgumentString == ValueBuffer) {

+          BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status);

+        }

+        break;

+

+      case '%':

+      default:

+        //

+        // if the type is '%' or unknown, then print it to the screen

+        //

+        ArgumentString = (CHAR8 *)&FormatCharacter;

+        Flags |= ARGUMENT_UNICODE;

+        break;

+      }

+      break;

+    case '\n':

+      ArgumentString = "\r\n";

+      break;

+    default:

+      ArgumentString = (CHAR8 *)&FormatCharacter;

+      Flags |= ARGUMENT_UNICODE;

+      break;

+    }

+

+    //

+    // Retrieve the ArgumentString attriubutes

+    //

+    if ((Flags & ARGUMENT_UNICODE) != 0) {

+      ArgumentMask = 0xffff;

+      BytesPerArgumentCharacter = 2;

+    } else {

+      ArgumentMask = 0xff;

+      BytesPerArgumentCharacter = 1;

+    }

+    if ((Flags & ARGUMENT_REVERSED) != 0) {

+      BytesPerArgumentCharacter = -BytesPerArgumentCharacter;

+    } else {

+      //

+      // Compute the number of characters in ArgumentString and store it in Count

+      // ArgumentString is either null-terminated, or it contains Precision characters

+      //

+      for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {

+        ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;

+        if (ArgumentCharacter == 0) {

+          break;

+        }

+      }

+    }

+

+    //

+    // Limit the length of the string to append to the remaining characters in the output buffer

+    //

+    if (Count > BufferSize) {

+      Count = BufferSize;

+    }

+    if (Precision < Count) {

+      Precision = Count;

+    }

+

+    //

+    // Pad before the string

+    //

+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {

+      Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);

+    }

+

+    if (ZeroPad) {

+      if (Prefix != 0) {

+        Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);

+      }

+      Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter);

+    } else {

+      Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter);

+      if (Prefix != 0) {

+        Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);

+      }

+    }

+

+    //

+    // Output the Prefix character if it is present

+    //

+    Index = 0;

+    if (Prefix) {

+      Index++;

+    }

+

+    //

+    // Copy the string into the output buffer performing the required type conversions

+    //

+    while (Index < Count) {

+      ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;

+

+      Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter);

+      ArgumentString    += BytesPerArgumentCharacter;

+      Index++;

+      if (Comma) {

+        Digits++;

+        if (Digits == 3) {

+          Digits = 0;

+          Index++;

+          if (Index < Count) {

+            Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter);

+          }

+        }

+      }

+    }

+

+    //

+    // Pad after the string

+    //

+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {

+      Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);

+    }

+

+    //

+    // Reduce the number of characters

+    //

+    BufferSize -= Count;

+

+    //

+    // Get the next character from the format string

+    //

+    Format += BytesPerFormatCharacter;

+

+    //

+    // Get the next character from the format string

+    //

+    FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+  }

+

+  //

+  // Null terminate the Unicode or ASCII string

+  //

+  Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter);

+   

+  return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);

+}

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and variable argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+  @param  Buffer        Character buffer to print the results of the parsing

+                        of Format into.

+  @param  BufferSize    Maximum number of characters to put into buffer.

+                        Zero means no limit.

+  @param  Flags         Intial flags value.

+                        Can only have FORMAT_UNICODE and OUTPUT_UNICODE set

+  @param  FormatString  Null-terminated format string.

+

+  @return Number of characters printed.

+

+**/

+UINTN

+BasePrintLibSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST  Marker;

+

+  VA_START (Marker, FormatString);

+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on 

+  a Null-terminated Unicode format string and a VA_LIST argument list

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.  

+  The Unicode string is produced by parsing the format string specified by FormatString.  

+  Arguments are pulled from the variable argument list specified by Marker based on the 

+  contents of the format string.  

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeVSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 

+  Unicode format string and variable argument list.

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The Unicode string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the format string.

+  The length of the produced output buffer is returned.  

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_LIST argument list

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The Unicode string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list specified by Marker based on the 

+  contents of the format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeVSPrintAsciiFormat (

+  OUT CHAR16       *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  IN  VA_LIST      Marker

+  )

+{

+  return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 

+  ASCII format string and  variable argument list.

+  

+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The Unicode string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the 

+  format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          Unicode string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+UnicodeSPrintAsciiFormat (

+  OUT CHAR16       *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_LIST argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list specified by Marker based on 

+  the contents of the format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiVSPrint (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR8   *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and  variable argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the 

+  format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_LIST argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list specified by Marker based on 

+  the contents of the format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  @param  Marker          VA_LIST marker for the variable argument list.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiVSPrintUnicodeFormat (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and  variable argument list.

+  

+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer

+  and BufferSize.

+  The ASCII string is produced by parsing the format string specified by FormatString.

+  Arguments are pulled from the variable argument list based on the contents of the 

+  format string.

+  The length of the produced output buffer is returned.

+  If BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize is not 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().

+

+  @param  StartOfBuffer   APointer to the output buffer for the produced Null-terminated 

+                          ASCII string.

+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.

+  @param  FormatString    Null-terminated Unicode format string.

+  

+  @return Length of the produced output buffer.

+

+**/

+UINTN

+EFIAPI

+AsciiSPrintUnicodeFormat (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+/**

+  Converts a decimal value to a Null-terminated Unicode string.

+  

+  Converts the decimal number specified by Value to a Null-terminated Unicode 

+  string specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  If the conversion contains more than Width characters, then only the first

+  Width characters are returned, and the total number of characters 

+  required to perform the conversion is returned.

+  Additional conversion parameters are specified in Flags.  

+  The Flags bit LEFT_JUSTIFY is always ignored.

+  All conversions are left justified in Buffer.

+  If Width is 0, PREFIX_ZERO is ignored in Flags.

+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas

+  are inserted every 3rd digit starting from the right.

+  If Value is < 0, then the fist character in Buffer is a '-'.

+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 

+  then Buffer is padded with '0' characters so the combination of the optional '-' 

+  sign character, '0' characters, digit characters for Value, and the Null-terminator

+  add up to Width characters.

+

+  If Buffer is NULL, then ASSERT().

+  If unsupported bits are set in Flags, then ASSERT().

+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer  Pointer to the output buffer for the produced Null-terminated

+                  Unicode string.

+  @param  Flags   The bitmask of flags that specify left justification, zero pad, and commas.

+  @param  Value   The 64-bit signed value to convert to a string.

+  @param  Width	  The maximum number of Unicode characters to place in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+EFIAPI

+UnicodeValueToString (

+  IN OUT CHAR16  *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width

+  )

+{

+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2);

+}

+

+/**

+  Converts a decimal value to a Null-terminated ASCII string.

+  

+  Converts the decimal number specified by Value to a Null-terminated ASCII string 

+  specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  If the conversion contains more than Width characters, then only the first Width

+  characters are returned, and the total number of characters required to perform

+  the conversion is returned.

+  Additional conversion parameters are specified in Flags.  

+  The Flags bit LEFT_JUSTIFY is always ignored.

+  All conversions are left justified in Buffer.

+  If Width is 0, PREFIX_ZERO is ignored in Flags.

+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas 

+  are inserted every 3rd digit starting from the right.

+  If Value is < 0, then the fist character in Buffer is a '-'.

+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer

+  is padded with '0' characters so the combination of the optional '-'

+  sign character, '0' characters, digit characters for Value, and the 

+  Null-terminator add up to Width characters.

+

+  If Buffer is NULL, then ASSERT().

+  If unsupported bits are set in Flags, then ASSERT().

+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer  Pointer to the output buffer for the produced Null-terminated

+                  ASCII string.

+  @param  Flags   The bitmask of flags that specify left justification, zero pad, and commas.

+  @param  Value   The 64-bit signed value to convert to a string.

+  @param  Width	  The maximum number of ASCII characters to place in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+EFIAPI

+AsciiValueToString (

+  IN OUT CHAR8  *Buffer,

+  IN UINTN      Flags,

+  IN INT64      Value,

+  IN UINTN      Width

+  )

+{

+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 1);

+}

diff --git a/edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.c b/edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.c
new file mode 100644
index 0000000..89d18b0
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.c
@@ -0,0 +1,179 @@
+/** @file

+  Print Library worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PrintLibInternal.c

+

+**/

+

+#include "PrintLibInternal.h"

+

+static CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

+

+

+/**

+  Internal function that places the character into the Buffer.

+

+  Internal function that places ASCII or Unicode character into the Buffer.

+

+  @param  Buffer      Buffer to place the Unicode or ASCII string.

+  @param  Length      Count of character to be placed into Buffer.

+  @param  Character   Character to be placed into Buffer.

+  @param  Increment   Character increment in Buffer.

+

+  @return Number of characters printed.

+

+**/

+CHAR8 *

+BasePrintLibFillBuffer (

+  CHAR8   *Buffer,

+  INTN    Length,

+  UINTN   Character,

+  INTN    Increment

+  )

+{

+  INTN  Index;

+

+  for (Index = 0; Index < Length; Index++) {

+    *Buffer       =  (CHAR8) Character;

+    *(Buffer + 1) =  (CHAR8) (Character >> 8);

+    Buffer        += Increment;

+  }

+  return Buffer;

+}

+

+/**

+  Internal function that convert a decimal number to a string in Buffer.

+

+  Print worker function that convert a decimal number to a string in Buffer.

+

+  @param  Buffer    Location to place the Unicode or ASCII string of Value.

+  @param  Value     Value to convert to a Decimal or Hexidecimal string in Buffer.

+  @param  Radix     Radix of the value

+

+  @return Number of characters printed.

+

+**/

+UINTN

+EFIAPI

+BasePrintLibValueToString (

+  IN OUT CHAR8  *Buffer,

+  IN INT64      Value,

+  IN UINTN      Radix

+  )

+{

+  UINTN   Digits;

+  UINT32  Remainder;

+

+  //

+  // Loop to convert one digit at a time in reverse order

+  //

+  *(Buffer++) = 0;

+  Digits = 0;

+  do {

+    Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);

+    *(Buffer++) = mHexStr[Remainder];

+    Digits++;

+  } while (Value != 0);

+  return Digits;

+}

+

+/**

+  Internal function that converts a decimal value to a Null-terminated string.

+  

+  Converts the decimal number specified by Value to a Null-terminated  

+  string specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  If the conversion contains more than Width characters, then only the first

+  Width characters are returned, and the total number of characters 

+  required to perform the conversion is returned.

+  Additional conversion parameters are specified in Flags.  

+  The Flags bit LEFT_JUSTIFY is always ignored.

+  All conversions are left justified in Buffer.

+  If Width is 0, PREFIX_ZERO is ignored in Flags.

+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas

+  are inserted every 3rd digit starting from the right.

+  If Value is < 0, then the fist character in Buffer is a '-'.

+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 

+  then Buffer is padded with '0' characters so the combination of the optional '-' 

+  sign character, '0' characters, digit characters for Value, and the Null-terminator

+  add up to Width characters.

+

+  If Buffer is NULL, then ASSERT().

+  If unsupported bits are set in Flags, then ASSERT().

+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer    Pointer to the output buffer for the produced Null-terminated

+                    string.

+  @param  Flags     The bitmask of flags that specify left justification, zero pad,

+                    and commas.

+  @param  Value     The 64-bit signed value to convert to a string.

+  @param  Width	    The maximum number of characters to place in Buffer.

+  @param  Increment Character increment in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+BasePrintLibConvertValueToString (

+  IN OUT CHAR8   *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width,

+  IN UINTN       Increment

+  )

+{

+  CHAR8  *OriginalBuffer;

+  CHAR8  ValueBuffer[MAXIMUM_VALUE_CHARACTERS];

+  UINTN  Count;

+  UINTN  Digits;

+  UINTN  Index;

+

+  OriginalBuffer = Buffer;

+

+  if (Width == 0 || (Flags & COMMA_TYPE) != 0) {

+    Flags &= (~PREFIX_ZERO);

+  }

+

+  if (Width == 0 || Width > (MAXIMUM_VALUE_CHARACTERS - 1)) {

+    Width = MAXIMUM_VALUE_CHARACTERS - 1;

+  }

+

+  if (Value < 0) {

+    Value = -Value;

+    Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment);

+  }

+

+  Count = BasePrintLibValueToString (ValueBuffer, Value, 10);

+

+  if ((Flags & PREFIX_ZERO) != 0) {

+    Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment);

+  }

+

+  Digits = 3 - (Count % 3);

+  for (Index = 0; Index < Count; Index++) {

+    Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment);

+    if ((Flags & COMMA_TYPE) != 0) {

+      Digits++;

+      if (Digits == 3) {

+        Digits = 0;

+        if ((Index + 1) < Count) {

+          Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', Increment);

+        }

+      }

+    }

+  }

+

+  Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, Increment);

+

+  return ((Buffer - OriginalBuffer) / Increment);

+}

diff --git a/edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.h b/edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.h
new file mode 100644
index 0000000..0f7bebf
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.h
@@ -0,0 +1,174 @@
+/** @file

+  Print Library.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PrintLibInternal.h

+

+**/

+

+//

+// Print primitives

+//

+//#define LEFT_JUSTIFY      0x01

+#define PREFIX_SIGN       0x02

+#define PREFIX_BLANK      0x04

+//#define COMMA_TYPE        0x08

+#define LONG_TYPE         0x10

+//#define PREFIX_ZERO       0x20

+#define OUTPUT_UNICODE    0x40

+#define RADIX_HEX         0x80

+#define FORMAT_UNICODE    0x100

+#define PAD_TO_WIDTH      0x200

+#define ARGUMENT_UNICODE  0x400

+#define PRECISION         0x800

+#define ARGUMENT_REVERSED 0x1000

+

+///

+/// Define the maximum number of characters that are required to encode

+/// a decimal, hexidecimal, GUID, or TIME value with a Nll terminator.

+///   Maximum Length Decimal String     = 28    "-9,223,372,036,854,775,808"

+///   Maximum Length Hexidecimal String = 17    "FFFFFFFFFFFFFFFF"

+///   Maximum Length GUID               = 37    "00000000-0000-0000-0000-000000000000"

+///   Maximum Length TIME               = 18    "12/12/2006  12:12"

+///

+#define MAXIMUM_VALUE_CHARACTERS  38

+

+//

+// Record date and time information

+//

+typedef struct {

+  UINT16  Year;

+  UINT8   Month;

+  UINT8   Day;

+  UINT8   Hour;

+  UINT8   Minute;

+  UINT8   Second;

+  UINT8   Pad1;

+  UINT32  Nanosecond;

+  INT16   TimeZone;

+  UINT8   Daylight;

+  UINT8   Pad2;

+} TIME;

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and variable argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+  @param  Buffer        Character buffer to print the results of the parsing

+                        of Format into.

+  @param  BufferSize    Maximum number of characters to put into buffer.

+                        Zero means no limit.

+  @param  Flags         Intial flags value.

+                        Can only have FORMAT_UNICODE and OUTPUT_UNICODE set

+  @param  FormatString  Null-terminated format string.

+

+  @return Number of characters printed.

+

+**/

+UINTN

+BasePrintLibSPrint (

+  OUT CHAR8        *Buffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  );

+

+/**

+  Internal function that places the character into the Buffer.

+

+  Internal function that places ASCII or Unicode character into the Buffer.

+

+  @param  Buffer      Buffer to place the Unicode or ASCII string.

+  @param  Length      Count of character to be placed into Buffer.

+  @param  Character   Character to be placed into Buffer.

+  @param  Increment   Character increment in Buffer.

+

+  @return Number of characters printed.

+

+**/

+CHAR8 *

+BasePrintLibFillBuffer (

+  CHAR8   *Buffer,

+  INTN    Length,

+  UINTN   Character,

+  INTN    Increment

+  );

+

+/**

+  Internal function that convert a decimal number to a string in Buffer.

+

+  Print worker function that convert a decimal number to a string in Buffer.

+

+  @param  Buffer    Location to place the Unicode or ASCII string of Value.

+  @param  Value     Value to convert to a Decimal or Hexidecimal string in Buffer.

+  @param  Radix     Radix of the value

+

+  @return Number of characters printed.

+

+**/

+UINTN

+EFIAPI

+BasePrintLibValueToString (

+  IN OUT CHAR8  *Buffer, 

+  IN INT64      Value, 

+  IN UINTN      Radix

+  );

+

+/**

+  Internal function that converts a decimal value to a Null-terminated string.

+  

+  Converts the decimal number specified by Value to a Null-terminated  

+  string specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  If the conversion contains more than Width characters, then only the first

+  Width characters are returned, and the total number of characters 

+  required to perform the conversion is returned.

+  Additional conversion parameters are specified in Flags.  

+  The Flags bit LEFT_JUSTIFY is always ignored.

+  All conversions are left justified in Buffer.

+  If Width is 0, PREFIX_ZERO is ignored in Flags.

+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas

+  are inserted every 3rd digit starting from the right.

+  If Value is < 0, then the fist character in Buffer is a '-'.

+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 

+  then Buffer is padded with '0' characters so the combination of the optional '-' 

+  sign character, '0' characters, digit characters for Value, and the Null-terminator

+  add up to Width characters.

+

+  If Buffer is NULL, then ASSERT().

+  If unsupported bits are set in Flags, then ASSERT().

+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer    Pointer to the output buffer for the produced Null-terminated

+                    string.

+  @param  Flags     The bitmask of flags that specify left justification, zero pad,

+                    and commas.

+  @param  Value     The 64-bit signed value to convert to a string.

+  @param  Width	    The maximum number of characters to place in Buffer.

+  @param  Increment Character increment in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+BasePrintLibConvertValueToString (

+  IN OUT CHAR8   *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width,

+  IN UINTN       Increment

+  );

diff --git a/edk2/MdePkg/Library/BasePrintLib/build.xml b/edk2/MdePkg/Library/BasePrintLib/build.xml
new file mode 100644
index 0000000..76cac3f
--- /dev/null
+++ b/edk2/MdePkg/Library/BasePrintLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BasePrintLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BasePrintLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BasePrintLib">

+      <GenBuild baseName="BasePrintLib" mbdFilename="${MODULE_DIR}/BasePrintLib.mbd" msaFilename="${MODULE_DIR}/BasePrintLib.msa"/>

+   </target>

+   <target depends="BasePrintLib_clean" name="clean"/>

+   <target depends="BasePrintLib_cleanall" name="cleanall"/>

+   <target name="BasePrintLib_clean">

+      <OutputDirSetup baseName="BasePrintLib" mbdFilename="${MODULE_DIR}/BasePrintLib.mbd" msaFilename="${MODULE_DIR}/BasePrintLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePrintLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePrintLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BasePrintLib_cleanall">

+      <OutputDirSetup baseName="BasePrintLib" mbdFilename="${MODULE_DIR}/BasePrintLib.mbd" msaFilename="${MODULE_DIR}/BasePrintLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BasePrintLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BasePrintLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BasePrintLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.mbd b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.mbd
new file mode 100644
index 0000000..abc965c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseReportStatusCodeLibNull</BaseName>

+    <Guid>55c61087-7367-4546-bc32-4937c5e6aff3</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.msa b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.msa
new file mode 100644
index 0000000..663d416
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseReportStatusCodeLibNull</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>55c61087-7367-4546-bc32-4937c5e6aff3</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ReportStatusCodeLib.c</Filename>

+    <Filename>PostCode.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeDataTypeDebug</C_Name>

+    </GuidEntry>

+  </Guids>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+      <Token>0x00000007</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/PostCode.c b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/PostCode.c
new file mode 100644
index 0000000..3d0ce7c
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/PostCode.c
@@ -0,0 +1,125 @@
+/** @file

+  Report Status Code Library Post Code functions for DXE Phase.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Report Status Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x\n", Value));

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Report 

+  Status Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  Pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x - %s\n", Value, Description));

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the 

+  REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED bit of 

+  PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeDescriptionEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/ReportStatusCodeLib.c b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/ReportStatusCodeLib.c
new file mode 100644
index 0000000..752dc72
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/ReportStatusCodeLib.c
@@ -0,0 +1,439 @@
+/** @file

+  Report Status Code Library template for Base modules.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+**/

+

+/**

+  Converts a status code to an 8-bit POST code value.

+

+  Converts the status code specified by CodeType and Value to an 8-bit POST code 

+  and returns the 8-bit POST code in PostCode.  If CodeType is an 

+  EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode 

+  are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits 

+  24..26 of Value., and TRUE is returned.  Otherwise, FALSE is returned.  

+

+  If PostCode is NULL, then ASSERT().

+

+  @param  CodeType  The type of status code being converted.

+  @param  Value     The status code value being converted.

+  @param  PostCode  A pointer to the 8-bit POST code value to return. 

+

+  @retval  TRUE   The status code specified by CodeType and Value was converted 

+                  to an 8-bit POST code and returned in  PostCode.

+  @retval  FALSE  The status code specified by CodeType and Value could not be 

+                  converted to an 8-bit POST code value.

+

+**/

+BOOLEAN

+EFIAPI

+CodeTypeToPostCode (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,

+  OUT UINT8                  *PostCode

+  )

+{

+  //

+  // If PostCode is NULL, then ASSERT()

+  //

+  ASSERT (PostCode != NULL);

+

+  //

+  // Convert Value to an 8 bit post code

+  //

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||

+      ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)       ) {

+    *PostCode  = (UINT8) (((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5);

+    *PostCode |= (UINT8) (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f);

+    return TRUE;

+  }

+  return FALSE;

+}

+

+

+/**

+  Extracts ASSERT() information from a status code structure.

+

+  Converts the status code specified by CodeType, Value, and Data to the ASSERT()

+  arguments specified by Filename, Description, and LineNumber.  If CodeType is 

+  an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and 

+  Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract 

+  Filename, Description, and LineNumber from the optional data area of the 

+  status code buffer specified by Data.  The optional data area of Data contains 

+  a Null-terminated ASCII string for the FileName, followed by a Null-terminated 

+  ASCII string for the Description, followed by a 32-bit LineNumber.  If the 

+  ASSERT() information could be extracted from Data, then return TRUE.  

+  Otherwise, FALSE is returned.  

+

+  If Data is NULL, then ASSERT().

+  If Filename is NULL, then ASSERT().

+  If Description is NULL, then ASSERT().

+  If LineNumber is NULL, then ASSERT().

+

+  @param  CodeType     The type of status code being converted.

+  @param  Value        The status code value being converted.

+  @param  Data         Pointer to status code data buffer. 

+  @param  Filename     Pointer to the source file name that generated the ASSERT().

+  @param  Description  Pointer to the description of the ASSERT().

+  @param  LineNumber   Pointer to source line number that generated the ASSERT().

+

+  @retval  TRUE   The status code specified by CodeType, Value, and Data was 

+                  converted ASSERT() arguments specified by Filename, Description, 

+                  and LineNumber.

+  @retval  FALSE  The status code specified by CodeType, Value, and Data could 

+                  not be converted to ASSERT() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractAssertInfo (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,  

+  IN  EFI_STATUS_CODE_DATA   *Data, 

+  OUT CHAR8                  **Filename,

+  OUT CHAR8                  **Description,

+  OUT UINT32                 *LineNumber

+  )

+{

+  EFI_DEBUG_ASSERT_DATA  *AssertData;

+

+  ASSERT (Data        != NULL);

+  ASSERT (Filename    != NULL);

+  ASSERT (Description != NULL);

+  ASSERT (LineNumber  != NULL);

+

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK)      == EFI_ERROR_CODE) && 

+      ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK)  == EFI_ERROR_UNRECOVERED) &&

+      ((Value    & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {

+    AssertData   = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);

+    *Filename    = (CHAR8 *)(AssertData + 1);

+    *Description = *Filename + AsciiStrLen (*Filename) + 1;

+    *LineNumber  = AssertData->LineNumber;

+    return TRUE;

+  }

+  return FALSE;

+}

+

+

+/**

+  Extracts DEBUG() information from a status code structure.

+

+  Converts the status code specified by Data to the DEBUG() arguments specified 

+  by ErrorLevel, Marker, and Format.  If type GUID in Data is 

+  EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and 

+  Format from the optional data area of the status code buffer specified by Data.  

+  The optional data area of Data contains a 32-bit ErrorLevel followed by Marker 

+  which is 12 UINTN parameters, followed by a Null-terminated ASCII string for 

+  the Format.  If the DEBUG() information could be extracted from Data, then 

+  return TRUE.  Otherwise, FALSE is returned.

+

+  If Data is NULL, then ASSERT().

+  If ErrorLevel is NULL, then ASSERT().

+  If Marker is NULL, then ASSERT().

+  If Format is NULL, then ASSERT().

+

+  @param  Data        Pointer to status code data buffer. 

+  @param  ErrorLevel  Pointer to error level mask for a debug message.

+  @param  Marker      Pointer to the variable argument list associated with Format.

+  @param  Format      Pointer to a Null-terminated ASCII format string of a 

+                      debug message.

+

+  @retval  TRUE   The status code specified by Data was converted DEBUG() arguments 

+                  specified by ErrorLevel, Marker, and Format.

+  @retval  FALSE  The status code specified by Data could not be converted to 

+                  DEBUG() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractDebugInfo (

+  IN  EFI_STATUS_CODE_DATA  *Data,

+  OUT UINT32                *ErrorLevel,

+  OUT VA_LIST               *Marker,

+  OUT CHAR8                 **Format

+  )

+{

+  EFI_DEBUG_INFO  *DebugInfo;

+

+  ASSERT (Data       != NULL);

+  ASSERT (ErrorLevel != NULL);

+  ASSERT (Marker     != NULL);

+  ASSERT (Format     != NULL);

+

+  //

+  // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE

+  //

+  if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {

+    return FALSE;

+  }

+

+  //

+  // Retrieve the debug information from the status code record

+  //

+  DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);

+

+  *ErrorLevel = DebugInfo->ErrorLevel;

+

+  //

+  // The first 12 * UINTN bytes of the string are really an 

+  // argument stack to support varargs on the Format string.

+  //

+  *Marker = (VA_LIST) (DebugInfo + 1);

+  *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);

+

+  return TRUE;

+}

+

+

+/**

+  Reports a status code.

+

+  Reports the status code specified by the parameters Type and Value.  Status 

+  code also require an instance, caller ID, and extended data.  This function 

+  passed in a zero instance, NULL extended data, and a caller ID of 

+  gEfiCallerIdGuid, which is the GUID for the module.  

+  

+  ReportStatusCode()must actively prevent recusrsion.  If ReportStatusCode() 

+  is called while processing another any other Report Status Code Library function,

+  then ReportStatusCode() must return immediately.

+

+  @param  Type   Status code type. 

+  @param  Value  Status code value.

+

+  @retval  EFI_SUCCESS       The status code was reported.

+  @retval  EFI_DEVICE_ERROR  There status code could not be reported due to a 

+                             device error.

+  @retval  EFI_UNSUPPORTED   Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  Reports a status code with a Device Path Protocol as the extended data.

+

+  Allocates and fills in the extended data section of a status code with the 

+  Device Path Protocol specified by DevicePath.  This function is responsible 

+  for allocating a buffer large enough for the standard header and the device 

+  path.  The standard header is filled in with a GUID of 

+  gEfiStatusCodeSpecificDataGuid.  The status code is reported with a zero 

+  instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithDevicePath()must actively prevent recursion.  If 

+  ReportStatusCodeWithDevicePath() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithDevicePath() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If DevicePath is NULL, then ASSERT().

+

+  @param  Type        Status code type. 

+  @param  Value       Status code value.

+  @param  DevicePath  Pointer to the Device Path Protocol to be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by DevicePath.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithDevicePath (

+  IN EFI_STATUS_CODE_TYPE      Type,

+  IN EFI_STATUS_CODE_VALUE     Value,

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  ASSERT (DevicePath != NULL);

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  Reports a status code with an extended data buffer.

+

+  Allocates and fills in the extended data section of a status code with the 

+  extended data specified by ExtendedData and ExtendedDataSize.  ExtendedData 

+  is assumed to be one of the data structures specified in Related Definitions.  

+  These data structure do not have the standard header, so this function is 

+  responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled 

+  in with a GUID of  gEfiStatusCodeSpecificDataGuid.  The status code is reported 

+  with a zero instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithExtendedData()must actively prevent recursion.  If 

+  ReportStatusCodeWithExtendedData() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithExtendedData() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL, then ASSERT().

+  If ExtendedDataSize is 0, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  ExtendedData      Pointer to the extended data buffer to be reported.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer to 

+                            be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by ExtendedData and ExtendedDataSize.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithExtendedData (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN VOID                   *ExtendedData,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  ASSERT (ExtendedData     != NULL);

+  ASSERT (ExtendedDataSize != 0);

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  Reports a status code with full parameters.

+

+  The function reports a status code.  If ExtendedData is NULL and ExtendedDataSize 

+  is 0, then an extended data buffer is not reported.  If ExtendedData is not 

+  NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.  

+  ExtendedData is assumed not have the standard status code header, so this function 

+  is responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled in 

+  with a GUID specified by ExtendedDataGuid.  If ExtendedDataGuid is NULL, then a 

+  GUID of gEfiStatusCodeSpecificDatauid is used.  The status code is reported with 

+  an instance specified by Instance and a caller ID specified by CallerId.  If 

+  CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.

+

+  ReportStatusCodeEx()must actively prevent recursion.  If ReportStatusCodeEx() 

+  is called while processing another any other Report Status Code Library function, 

+  then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().

+  If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  If this parameter is NULL, then a caller 

+                            ID of gEfiCallerIdGuid is used.

+  @param  ExtendedDataGuid  Pointer to the GUID for the extended data buffer.  

+                            If this parameter is NULL, then a the status code 

+                            standard header is filled in with 

+                            gEfiStatusCodeSpecificDataGuid.

+  @param  ExtendedData      Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate 

+                                 the extended data section if it was specified.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeEx (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN UINT32                 Instance,

+  IN EFI_GUID               *CallerId           OPTIONAL,

+  IN EFI_GUID               *ExtendedDataGuid   OPTIONAL,

+  IN VOID                   *ExtendedData       OPTIONAL,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));

+  ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportProgressCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_ERROR_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportErrorCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportDebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/build.xml b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/build.xml
new file mode 100644
index 0000000..4c6822d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseReportStatusCodeLibNull/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseReportStatusCodeLibNull"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseReportStatusCodeLibNull"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseReportStatusCodeLibNull">

+      <GenBuild baseName="BaseReportStatusCodeLibNull" mbdFilename="${MODULE_DIR}/BaseReportStatusCodeLibNull.mbd" msaFilename="${MODULE_DIR}/BaseReportStatusCodeLibNull.msa"/>

+   </target>

+   <target depends="BaseReportStatusCodeLibNull_clean" name="clean"/>

+   <target depends="BaseReportStatusCodeLibNull_cleanall" name="cleanall"/>

+   <target name="BaseReportStatusCodeLibNull_clean">

+      <OutputDirSetup baseName="BaseReportStatusCodeLibNull" mbdFilename="${MODULE_DIR}/BaseReportStatusCodeLibNull.mbd" msaFilename="${MODULE_DIR}/BaseReportStatusCodeLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseReportStatusCodeLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseReportStatusCodeLibNull_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseReportStatusCodeLibNull_cleanall">

+      <OutputDirSetup baseName="BaseReportStatusCodeLibNull" mbdFilename="${MODULE_DIR}/BaseReportStatusCodeLibNull.mbd" msaFilename="${MODULE_DIR}/BaseReportStatusCodeLibNull.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseReportStatusCodeLibNull_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseReportStatusCodeLibNull_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseReportStatusCodeLibNull*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseSmbusLib/BaseSmbusLib.mbd b/edk2/MdePkg/Library/BaseSmbusLib/BaseSmbusLib.mbd
new file mode 100644
index 0000000..e548f14
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseSmbusLib/BaseSmbusLib.mbd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseSmbusLib</BaseName>

+    <Guid>4c38a173-b317-4f29-a7bf-1cc7e10ccb10</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 09:00</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+  <BuildOptions ToolChain="MSFT">

+    <Option>C_PROJ_FLAGS = ${C_PROJ_FLAGS}</Option>

+  </BuildOptions>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseSmbusLib/BaseSmbusLib.msa b/edk2/MdePkg/Library/BaseSmbusLib/BaseSmbusLib.msa
new file mode 100644
index 0000000..fa23452
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseSmbusLib/BaseSmbusLib.msa
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseSmbusLib</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>4c38a173-b317-4f29-a7bf-1cc7e10ccb10</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 09:00</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">SmbusLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PciLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>SmbusLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseSmbusLib/SmbusLib.c b/edk2/MdePkg/Library/BaseSmbusLib/SmbusLib.c
new file mode 100644
index 0000000..29c09e7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseSmbusLib/SmbusLib.c
@@ -0,0 +1,861 @@
+/** @file

+  Base SMBUS library implementation built upon I/O library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SmbusLib.c

+

+**/

+

+#include "SmbusLibRegisters.h"

+

+#define SMBUS_LIB_SLAVE_ADDRESS(SmBusAddress)      (((SmBusAddress) >> 1)  & 0x7f)

+#define SMBUS_LIB_COMMAND(SmBusAddress)            (((SmBusAddress) >> 8)  & 0xff)

+#define SMBUS_LIB_LENGTH(SmBusAddress)             (((SmBusAddress) >> 16) & 0x1f)

+#define SMBUS_LIB_PEC(SmBusAddress)     ((BOOLEAN) (((SmBusAddress) & SMBUS_LIB_PEC_BIT) != 0))

+#define SMBUS_LIB_RESEARVED(SmBusAddress)          ((SmBusAddress) & ~(((1 << 21) - 2) | SMBUS_LIB_PEC_BIT))

+

+//

+// Replaced by PCD

+//

+#define ICH_SMBUS_BASE_ADDRESS               0xEFA0

+

+/**

+  Reads an 8-bit SMBUS register on ICH.

+

+  This internal function reads an SMBUS register specified by Offset.

+

+  @param  Offset  The offset of SMBUS register.

+

+  @return The value read.

+

+**/

+UINT8

+InternalSmBusIoRead8 (

+  IN UINTN      Offset

+  )

+{

+  return IoRead8 (ICH_SMBUS_BASE_ADDRESS + Offset);

+}

+

+/**

+  Writes an 8-bit SMBUS register on ICH.

+

+  This internal function writes an SMBUS register specified by Offset.

+

+  @param  Offset  The offset of SMBUS register.

+  @param  Value   The value to write to SMBUS register.

+

+  @return The value written the SMBUS register.

+

+**/

+UINT8

+InternalSmBusIoWrite8 (

+  IN UINTN      Offset,

+  IN UINT8      Value

+  )

+{

+  return IoWrite8 (ICH_SMBUS_BASE_ADDRESS + Offset, Value);

+}

+

+/**

+  Acquires the ownership of SMBUS.

+

+  This internal function reads the host state register.

+  If the SMBUS is not available, RETURN_TIMEOUT is returned;

+  Otherwise, it performs some basic initializations and returns

+  RETURN_SUCCESS. 

+

+  @retval RETURN_SUCCESS    The SMBUS command was executed successfully.

+  @retval RETURN_TIMEOUT    A timeout occurred while executing the SMBUS command.

+

+**/

+RETURN_STATUS

+InternalSmBusAcquire (

+  VOID 

+  )

+{

+  UINT8   HostStatus;

+

+  HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);

+  if ((HostStatus & SMBUS_B_INUSE_STS) != 0) {

+    return RETURN_TIMEOUT;

+  } else if ((HostStatus & SMBUS_B_HOST_BUSY) != 0) {

+    //

+    // Clear Status Register and exit

+    //

+    InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);

+    return RETURN_TIMEOUT;

+  }

+  //

+  // Clear byte pointer of 32-byte buffer.

+  //

+  InternalSmBusIoRead8 (SMBUS_R_HST_CTL);

+  //

+  // Clear BYTE_DONE status

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_BYTE_DONE_STS);

+  

+  return RETURN_SUCCESS;

+}

+

+/**

+  Waits until the completion of SMBUS transaction.

+

+  This internal function waits until the transaction of SMBUS is over

+  by polling the INTR bit of Host status register.

+  If the SMBUS is not available, RETURN_TIMEOUT is returned;

+  Otherwise, it performs some basic initializations and returns

+  RETURN_SUCCESS. 

+

+  @retval RETURN_SUCCESS      The SMBUS command was executed successfully.

+  @retval RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).

+  @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected

+                              in the Host Status Register bit.  Device errors are

+                              a result of a transaction collision, illegal command field,

+                              unclaimed cycle (host initiated), or bus errors (collisions).

+

+**/

+RETURN_STATUS

+InternalSmBusWait (

+  VOID 

+  )

+{

+  UINT8   HostStatus;

+  UINT8   AuxiliaryStatus;

+  BOOLEAN First;

+  First = TRUE;

+

+  do {

+    //

+    // Poll INTR bit of host status register.

+    //

+    HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);

+  } while ((HostStatus & (SMBUS_B_INTR | SMBUS_B_ERROR | SMBUS_B_BYTE_DONE_STS)) == 0);

+  

+  if ((HostStatus & SMBUS_B_ERROR) == 0) {

+    return RETURN_SUCCESS;

+  }

+  //

+  // Clear error bits of host status register

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_ERROR);

+  //

+  // Read auxiliary status register to judge CRC error.

+  //

+  AuxiliaryStatus = InternalSmBusIoRead8 (SMBUS_R_AUX_STS);

+  if ((AuxiliaryStatus & SMBUS_B_CRCE) != 0) {

+    return RETURN_CRC_ERROR;

+  }

+

+  return RETURN_DEVICE_ERROR;

+}

+

+/**

+  Executes an SMBUS quick read/write command.

+

+  This internal function executes an SMBUS quick read/write command

+  on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+InternalSmBusQuick (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  RETURN_STATUS   ReturnStatus;

+

+  ReturnStatus = InternalSmBusAcquire ();

+  if (RETURN_ERROR (ReturnStatus)) {

+    goto Done;

+  }

+ 

+  //

+  // Set Command register

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, 0);

+  //

+  // Set Auxiliary Control register

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, 0);

+  //

+  // Set SMBus slave address for the device to send/receive from

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);

+  //

+  // Set Control Register (Initiate Operation, Interrupt disabled)

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, SMBUS_V_SMB_CMD_QUICK + SMBUS_B_START);

+

+  //

+  // Wait for the end

+  //

+  ReturnStatus = InternalSmBusWait ();

+

+  //

+  // Clear status register and exit

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;

+

+Done:

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+}

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusQuick (SmBusAddress | SMBUS_B_READ, Status);

+}

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusQuick (SmBusAddress | SMBUS_B_WRITE, Status);

+}

+

+/**

+  Executes an SMBUS byte or word command.

+

+  This internal function executes an .

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+

+  @param  HostControl     The value of Host Control Register to set.  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The byte/word write to the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte/word read from the SMBUS.

+

+**/

+UINT16

+InternalSmBusByteWord (

+  IN  UINT8                     HostControl,

+  IN  UINTN                     SmBusAddress,

+  IN  UINT16                    Value,

+  OUT RETURN_STATUS             *Status

+  )

+{

+  RETURN_STATUS                 ReturnStatus;

+  UINT8                         AuxiliaryControl;

+

+  ReturnStatus = InternalSmBusAcquire ();

+  if (RETURN_ERROR (ReturnStatus)) {

+    goto Done;

+  }

+

+  AuxiliaryControl = 0;

+  if (SMBUS_LIB_PEC (SmBusAddress)) {

+    AuxiliaryControl |= SMBUS_B_AAC;

+    HostControl      |= SMBUS_B_PEC_EN;

+  }

+ 

+  //

+  // Set commond register

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));

+

+  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) Value);

+  InternalSmBusIoWrite8 (SMBUS_R_HST_D1, (UINT8) (Value >> 8));

+

+  //

+  // Set Auxiliary Control Regiester.

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);

+  //

+  // Set SMBus slave address for the device to send/receive from.

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);

+  //

+  // Set Control Register (Initiate Operation, Interrupt disabled)

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);

+

+  //

+  // Wait for the end

+  //

+  ReturnStatus = InternalSmBusWait ();

+ 

+  Value  = InternalSmBusIoRead8 (SMBUS_R_HST_D1) << 8;

+  Value |= InternalSmBusIoRead8 (SMBUS_R_HST_D0);

+

+  //

+  // Clear status register and exit

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;

+

+Done:

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return (UINT8) InternalSmBusByteWord (

+                   SMBUS_V_SMB_CMD_BYTE,

+                   SmBusAddress | SMBUS_B_READ,

+                   0,

+                   Status

+                   );

+}

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to send.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return (UINT8) InternalSmBusByteWord (

+                   SMBUS_V_SMB_CMD_BYTE,

+                   SmBusAddress | SMBUS_B_WRITE,

+                   Value,

+                   Status

+                   );

+}

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return (UINT8) InternalSmBusByteWord (

+                   SMBUS_V_SMB_CMD_BYTE_DATA,

+                   SmBusAddress | SMBUS_B_READ,

+                   0,

+                   Status

+                   );

+}

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return (UINT8) InternalSmBusByteWord (

+                   SMBUS_V_SMB_CMD_BYTE_DATA,

+                   SmBusAddress | SMBUS_B_WRITE,

+                   Value,

+                   Status

+                   );

+}

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusByteWord (

+           SMBUS_V_SMB_CMD_WORD_DATA,

+           SmBusAddress | SMBUS_B_READ,

+           0,

+           Status

+           );

+}

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusByteWord (

+           SMBUS_V_SMB_CMD_WORD_DATA,

+           SmBusAddress | SMBUS_B_WRITE,

+           Value,

+           Status

+           );

+}

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusByteWord (

+           SMBUS_V_SMB_CMD_PROCESS_CALL,

+           SmBusAddress | SMBUS_B_WRITE,

+           Value,

+           Status

+           );

+}

+

+/**

+  Executes an SMBUS block command.

+

+  Executes an SMBUS block read, block write and block write-block read command

+  on the SMBUS device specified by SmBusAddress.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+

+  @param  HostControl     The value of Host Control Register to set.  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.

+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes read from the SMBUS.

+

+**/

+UINTN

+InternalSmBusBlock (

+  IN  UINT8                     HostControl,

+  IN  UINTN                     SmBusAddress,

+  IN  UINT8                     *OutBuffer,

+  OUT UINT8                     *InBuffer,

+  OUT RETURN_STATUS             *Status

+  )

+{

+  RETURN_STATUS                 ReturnStatus;

+  UINTN                         Index;

+  UINTN                         BytesCount;

+  UINT8                         AuxiliaryControl;

+

+  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress) + 1;

+

+  ReturnStatus = InternalSmBusAcquire ();

+  if (RETURN_ERROR (ReturnStatus)) {

+    goto Done;

+  }

+  

+  AuxiliaryControl = SMBUS_B_E32B;

+  if (SMBUS_LIB_PEC (SmBusAddress)) {

+    AuxiliaryControl |= SMBUS_B_AAC;

+    HostControl      |= SMBUS_B_PEC_EN;

+  }

+

+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));

+

+  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) BytesCount);

+

+  if (OutBuffer != NULL) {

+    for (Index = 0; Index < BytesCount; Index++) {

+      InternalSmBusIoWrite8 (SMBUS_R_HOST_BLOCK_DB, OutBuffer[Index]);

+    }

+  }

+  //

+  // Set Auxiliary Control Regiester.

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);

+  //

+  // Set SMBus slave address for the device to send/receive from

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);

+  //

+  // Set Control Register (Initiate Operation, Interrupt disabled)

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);

+

+  //

+  // Wait for the end

+  //

+  ReturnStatus = InternalSmBusWait ();

+  if (RETURN_ERROR (ReturnStatus)) {

+    goto Done;

+  }

+

+  BytesCount = InternalSmBusIoRead8 (SMBUS_R_HST_D0);

+  if (InBuffer != NULL) {

+    for (Index = 0; Index < BytesCount; Index++) {

+      InBuffer[Index] = InternalSmBusIoRead8 (SMBUS_R_HOST_BLOCK_DB);

+    }

+  }

+

+  //

+  // Clear status register and exit

+  //

+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);

+

+Done:

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+

+  return BytesCount;

+}

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusBlock (

+           SMBUS_V_SMB_CMD_BLOCK,

+           SmBusAddress | SMBUS_B_READ,

+           NULL,

+           Buffer,

+           Status

+           );

+}

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusBlock (

+           SMBUS_V_SMB_CMD_BLOCK,

+           SmBusAddress | SMBUS_B_WRITE,

+           Buffer,

+           NULL,

+           Status

+           );

+}

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from OutBuffer.  Bytes are then read from the SMBUS into InBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure InBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If OutBuffer is NULL, then ASSERT().

+  If InBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.

+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *OutBuffer,

+  OUT VOID           *InBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (InBuffer  != NULL);

+  ASSERT (OutBuffer != NULL);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusBlock (

+           SMBUS_V_SMB_CMD_BLOCK_PROCESS,

+           SmBusAddress | SMBUS_B_WRITE,

+           OutBuffer,

+           InBuffer,

+           Status

+           );

+}

diff --git a/edk2/MdePkg/Library/BaseSmbusLib/SmbusLibRegisters.h b/edk2/MdePkg/Library/BaseSmbusLib/SmbusLibRegisters.h
new file mode 100644
index 0000000..6eb14fa
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseSmbusLib/SmbusLibRegisters.h
@@ -0,0 +1,120 @@
+/** @file

+  Base SMBUS library implementation built upon I/O library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SmbusLib.h

+

+**/

+

+#ifndef __SMBUS_LIB_REGISTER_H

+#define __SMBUS_LIB_REGISTER_H

+

+#define SMBUS_R_HST_STS               0x00  // Host Status Register

+#define SMBUS_B_HOST_BUSY             0x01  // RO

+#define SMBUS_B_INTR                  0x02  // R/WC

+#define SMBUS_B_DEV_ERR               0x04  // R/WC

+#define SMBUS_B_BUS_ERR               0x08  // R/WC

+#define SMBUS_B_FAILED                0x10  // R/WC

+#define SMBUS_B_SMBALERT_STS          0x20  // R/WC

+#define SMBUS_B_INUSE_STS             0x40  // R/WC

+#define SMBUS_B_BYTE_DONE_STS         0x80  // R/WC

+#define SMBUS_B_ERROR                 (SMBUS_B_DEV_ERR | SMBUS_B_BUS_ERR | SMBUS_B_FAILED)

+#define SMBUS_B_HSTS_ALL              0xFF  // R/WC

+

+

+#define SMBUS_R_HST_CTL               0x02  // Host Control Register R/W

+#define SMBUS_B_INTREN                0x01  // RW

+#define SMBUS_B_KILL                  0x02  // RW

+#define SMBUS_B_CMD                   (7 << 2) // RW

+#define SMBUS_V_SMB_CMD_QUICK         (0 << 2)

+#define SMBUS_V_SMB_CMD_BYTE          (1 << 2)

+#define SMBUS_V_SMB_CMD_BYTE_DATA     (2 << 2)

+#define SMBUS_V_SMB_CMD_WORD_DATA     (3 << 2)

+#define SMBUS_V_SMB_CMD_PROCESS_CALL  (4 << 2)

+#define SMBUS_V_SMB_CMD_BLOCK         (5 << 2)

+#define SMBUS_V_SMB_CMD_IIC_READ      (6 << 2)

+#define SMBUS_V_SMB_CMD_BLOCK_PROCESS (7 << 2)

+#define SMBUS_B_LAST_BYTE             0x20  // WO

+#define SMBUS_B_START                 0x40  // WO

+#define SMBUS_B_PEC_EN                0x80  // RW

+

+

+#define SMBUS_R_HST_CMD               0x03  // Host Command Register R/W

+

+

+#define SMBUS_R_XMIT_SLVA             0x04  // Transmit Slave Address Register R/W

+#define SMBUS_B_RW                    0x01  // RW

+#define SMBUS_B_READ                  0x01  // RW

+#define SMBUS_B_WRITE                 0x00  // RW

+#define SMBUS_B_ADDRESS               0xFE  // RW

+

+

+#define SMBUS_R_HST_D0                0x05  // Data 0 Register R/W

+

+

+#define SMBUS_R_HST_D1                0x06  // Data 1 Register R/W

+

+

+#define SMBUS_R_HOST_BLOCK_DB         0x07  // Host Block Data Register R/W

+

+

+#define SMBUS_R_PEC                   0x08  // Packet Error Check Data Register R/W

+

+

+#define SMBUS_R_RCV_SLVA              0x09  // Receive Slave Address Register R/W

+#define SMBUS_B_SLAVE_ADDR            0x7F  // RW

+

+

+#define SMBUS_R_SLV_DATA              0x0A  // Receive Slave Data Register R/W

+

+

+#define SMBUS_R_AUX_STS               0x0C  // Auxiliary Status Register R/WC

+#define SMBUS_B_CRCE                  0x01  // R/WC

+

+

+#define SMBUS_R_AUX_CTL               0x0D  // Auxiliary Control Register R/W

+#define SMBUS_B_AAC                   0x01  // R/W

+#define SMBUS_B_E32B                  0x02  // R/W

+

+

+#define SMBUS_R_SMLINK_PIN_CTL        0x0E  // SMLINK Pin Control Register R/W

+#define SMBUS_B_SMLINK0_CUR_STS       0x01  // RO

+#define SMBUS_B_SMLINK1_CUR_STS       0x02  // RO

+#define SMBUS_B_SMLINK_CLK_CTL        0x04  // RW

+

+

+#define SMBUS_R_SMBUS_PIN_CTL         0x0F  // SMBus Pin Control Register R/W

+#define SMBUS_B_SMBCLK_CUR_STS        0x01  // RO

+#define SMBUS_B_SMBDATA_CUR_STS       0x02  // RO

+#define SMBUS_B_SMBCLK_CTL            0x04  // RW

+

+

+#define SMBUS_R_SLV_STS               0x10  // Slave Status Register R/WC

+#define SMBUS_B_HOST_NOTIFY_STS       0x01  // R/WC

+

+

+#define SMBUS_R_SLV_CMD               0x11  // Slave Command Register R/W

+#define SMBUS_B_HOST_NOTIFY_INTREN    0x01  // R/W

+#define SMBUS_B_HOST_NOTIFY_WKEN      0x02  // R/W

+#define SMBUS_B_SMBALERT_DIS          0x04  // R/W

+

+

+#define SMBUS_R_NOTIFY_DADDR          0x14  // Notify Device Address Register RO

+#define SMBUS_B_DEVICE_ADDRESS        0xFE  // RO

+

+

+#define SMBUS_R_NOTIFY_DLOW           0x16  // Notify Data Low Byte Register RO

+

+

+#define SMBUS_R_NOTIFY_DHIGH          0x17  // Notify Data High Byte Register RO   

+

+

+#endif

diff --git a/edk2/MdePkg/Library/BaseSmbusLib/build.xml b/edk2/MdePkg/Library/BaseSmbusLib/build.xml
new file mode 100644
index 0000000..803f646
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseSmbusLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseSmbusLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseSmbusLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseSmbusLib">

+      <GenBuild baseName="BaseSmbusLib" mbdFilename="${MODULE_DIR}/BaseSmbusLib.mbd" msaFilename="${MODULE_DIR}/BaseSmbusLib.msa"/>

+   </target>

+   <target depends="BaseSmbusLib_clean" name="clean"/>

+   <target depends="BaseSmbusLib_cleanall" name="cleanall"/>

+   <target name="BaseSmbusLib_clean">

+      <OutputDirSetup baseName="BaseSmbusLib" mbdFilename="${MODULE_DIR}/BaseSmbusLib.mbd" msaFilename="${MODULE_DIR}/BaseSmbusLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseSmbusLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseSmbusLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseSmbusLib_cleanall">

+      <OutputDirSetup baseName="BaseSmbusLib" mbdFilename="${MODULE_DIR}/BaseSmbusLib.mbd" msaFilename="${MODULE_DIR}/BaseSmbusLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseSmbusLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseSmbusLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseSmbusLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.mbd b/edk2/MdePkg/Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.mbd
new file mode 100644
index 0000000..d597fe0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseTimerLibLocalApic</BaseName>

+    <Guid>b5a05743-9b71-489b-a0ed-a0eb3950d23b</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 16:57</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.msa b/edk2/MdePkg/Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.msa
new file mode 100644
index 0000000..b056c8d
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.msa
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseTimerLibLocalApic</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>b5a05743-9b71-489b-a0ed-a0eb3950d23b</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 16:57</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">TimerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Arch ArchType="IA32">

+      <Filename>x86TimerLib.c</Filename>

+    </Arch>

+    <Arch ArchType="X64">

+      <Filename>x86TimerLib.c</Filename>

+    </Arch>

+    <Arch ArchType="IPF">

+      <Filename>Ipf/CallPalProc.s</Filename>

+      <Filename>Ipf/ReadItc.s</Filename>

+      <Filename>Ipf/IpfTimerLib.c</Filename>

+    </Arch>

+    <Arch ArchType="EBC">

+      <Filename>Ebc/EbcTimerLib.c</Filename>

+    </Arch>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ebc/EbcTimerLib.c b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ebc/EbcTimerLib.c
new file mode 100644
index 0000000..7de360a
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ebc/EbcTimerLib.c
@@ -0,0 +1,123 @@
+/** @file

+  Timer Library functions for EBC.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  EbcTimerLib.c

+

+**/

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return Return value depends on implementation.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  //

+  // EBC architecture does not support local APIC timer.

+  //

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return Return value depends on implementation.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  //

+  // EBC architecture does not support local APIC timer.

+  //

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  Retrieves the current value of a 64-bit free running performance counter. The

+  counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  //

+  // EBC architecture does not support local APIC timer.

+  //

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  IN      UINT64                    *StartValue,

+  IN      UINT64                    *EndValue

+  )

+{

+  //

+  // EBC architecture does not support local APIC timer.

+  //

+  ASSERT (FALSE);

+  return 0;  

+}

diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/CallPalProc.s b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/CallPalProc.s
new file mode 100644
index 0000000..18b0f58
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/CallPalProc.s
@@ -0,0 +1,38 @@
+/// @file

+///   Contains an implementation of CallPalProcStatic on Itanium-based

+///   architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  CallPalProc.s

+///

+///

+

+.auto

+.text

+

+.proc   CallPalProcStatic

+.type   CallPalProcStatic, @function

+CallPalProcStatic::

+        mov                 r9  = ar.k5

+        mov                 r8  = ip

+        add                 r8  = (PalProcReturn - CallPalProcStatic), r8

+        mov                 r28 = r32

+        mov                 b7  = r9

+        mov                 r29 = r33

+        mov                 r30 = r34

+        mov                 r31 = r35

+        mov                 r32 = b0

+        mov                 b0  = r8

+        br.sptk             b7

+PalProcReturn:

+        mov                 b0 = r32

+        br.ret.sptk.many    b0

+.endp   CallPalProcStatic

diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c
new file mode 100644
index 0000000..4214b62
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c
@@ -0,0 +1,155 @@
+/** @file

+  Timer Library functions built upon local APIC on IA32/x64.

+

+  @bug Should use PCD to retrieve all the constants including index of

+  the IA32_APIC_BASE MSR, the offsets of InitialCount, CorrentCount

+  and DivideConfiguration.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IpfTimerLib.c

+

+**/

+

+UINT64

+ReadItc (

+  VOID

+  );

+

+typedef struct {

+  UINT64                            Status;

+  UINT64                            r9;

+  UINT64                            r10;

+  UINT64                            r11;

+} PAL_PROC_RETURN;

+

+PAL_PROC_RETURN

+CallPalProcStatic (

+  IN      UINT64                    Arg1,

+  IN      UINT64                    Arg2,

+  IN      UINT64                    Arg3,

+  IN      UINT64                    Arg4

+  );

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return The ticks delayed actually.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  UINT64                            Ticks;

+  UINT64                            Delay;

+

+  Ticks = GetPerformanceCounter ();

+  Delay = GetPerformanceCounterProperties (NULL, NULL) * MicroSeconds / 1000000;

+  while (Ticks + Delay >= GetPerformanceCounter ());

+  return (UINTN)Delay;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return The ticks delayed actually.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  UINT64                            Ticks;

+  UINT64                            Delay;

+

+  Ticks = GetPerformanceCounter ();

+  Delay = GetPerformanceCounterProperties (NULL, NULL) * NanoSeconds / 1000000000;

+  while (Ticks + Delay >= GetPerformanceCounter ());

+  return (UINTN)Delay;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  Retrieves the current value of a 64-bit free running performance counter. The

+  counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  return ReadItc ();

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  IN      UINT64                    *StartValue,

+  IN      UINT64                    *EndValue

+  )

+{

+  PAL_PROC_RETURN                   PalRet;

+  UINT64                            BaseFrequence;

+

+  PalRet = CallPalProcStatic (13, 0, 0, 0);

+  ASSERT (PalRet.Status == 0);

+  BaseFrequence = PalRet.r9;

+

+  PalRet = CallPalProcStatic (14, 0, 0, 0);

+  ASSERT (PalRet.Status == 0);

+

+  *StartValue = 0;

+  *EndValue = (UINT64)(-1);

+  return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11;

+}

diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/ReadItc.s b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/ReadItc.s
new file mode 100644
index 0000000..383bb24
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/Ipf/ReadItc.s
@@ -0,0 +1,25 @@
+/// @file

+///   Contains an implementation of ReadItc on Itanium-based architecture.

+///

+/// Copyright (c) 2006, Intel Corporation

+/// All rights reserved. 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.

+///

+/// Module Name:  ReadItc.s

+///

+///

+

+.auto

+.text

+

+.proc   ReadItc

+.type   ReadItc, @function

+ReadItc::

+        mov                 r8  = ar.itc

+        br.ret.sptk.many    b0

+.endp   ReadItc
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/build.xml b/edk2/MdePkg/Library/BaseTimerLibLocalApic/build.xml
new file mode 100644
index 0000000..1d6cc6b
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseTimerLibLocalApic"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseTimerLibLocalApic"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseTimerLibLocalApic">

+      <GenBuild baseName="BaseTimerLibLocalApic" mbdFilename="${MODULE_DIR}/BaseTimerLibLocalApic.mbd" msaFilename="${MODULE_DIR}/BaseTimerLibLocalApic.msa"/>

+   </target>

+   <target depends="BaseTimerLibLocalApic_clean" name="clean"/>

+   <target depends="BaseTimerLibLocalApic_cleanall" name="cleanall"/>

+   <target name="BaseTimerLibLocalApic_clean">

+      <OutputDirSetup baseName="BaseTimerLibLocalApic" mbdFilename="${MODULE_DIR}/BaseTimerLibLocalApic.mbd" msaFilename="${MODULE_DIR}/BaseTimerLibLocalApic.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseTimerLibLocalApic_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseTimerLibLocalApic_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseTimerLibLocalApic_cleanall">

+      <OutputDirSetup baseName="BaseTimerLibLocalApic" mbdFilename="${MODULE_DIR}/BaseTimerLibLocalApic.mbd" msaFilename="${MODULE_DIR}/BaseTimerLibLocalApic.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseTimerLibLocalApic_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseTimerLibLocalApic_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseTimerLibLocalApic*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/BaseTimerLibLocalApic/x86TimerLib.c b/edk2/MdePkg/Library/BaseTimerLibLocalApic/x86TimerLib.c
new file mode 100644
index 0000000..9c69cdf
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseTimerLibLocalApic/x86TimerLib.c
@@ -0,0 +1,168 @@
+/** @file

+  Timer Library functions built upon local APIC on IA32/x64.

+

+  @bug Should use PCD to retrieve all the constants including index of

+  the IA32_APIC_BASE MSR, the offsets of InitialCount, CorrentCount

+  and DivideConfiguration.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  x86TimerLib.c

+

+**/

+

+static

+UINTN

+EFIAPI

+DelayWorker (

+  IN      UINT64                    NDelay

+  )

+{

+  UINT64                            Ticks;

+

+  Ticks = GetPerformanceCounter ();

+  Ticks -= DivU64x32 (

+             MultU64x64 (

+               GetPerformanceCounterProperties (NULL, NULL),

+               NDelay

+               ),

+             1000000000u

+             );

+  while (Ticks <= GetPerformanceCounter ());

+  return (UINTN)Ticks;

+}

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return Return value depends on implementation.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  return DelayWorker (MicroSeconds * 1000ull);

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return Return value depends on implementation.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  return DelayWorker (NanoSeconds);

+}

+

+static

+UINTN

+EFIAPI

+GetApicBase (

+  VOID

+  )

+{

+  return (UINTN)AsmMsrBitFieldRead64 (27, 12, 35) << 12;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  Retrieves the current value of a 64-bit free running performance counter. The

+  counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  return MmioRead32 (GetApicBase () + 0x390);

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  IN      UINT64                    *StartValue,

+  IN      UINT64                    *EndValue

+  )

+{

+  static const UINT32               mFrequencies[] = {

+    100000000,

+    133000000,

+    200000000,

+    166000000

+  };

+  static const UINT8                mDivisor[] = {

+    0x02, 0x04, 0x08, 0x10,

+    0x02, 0x04, 0x08, 0x10,

+    0x20, 0x40, 0x80, 0x01,

+    0x20, 0x40, 0x80, 0x01

+  };

+

+  UINTN                             ApicBase;

+

+  ApicBase = GetApicBase ();

+

+  if (StartValue != NULL) {

+    *StartValue = MmioRead32 (ApicBase + 0x380);

+  }

+

+  if (EndValue != NULL) {

+    *EndValue = 0;

+  }

+

+  return mFrequencies[AsmMsrBitFieldRead32 (44, 16, 18)] /

+         mDivisor[MmioBitFieldRead32 (ApicBase + 0x3e0, 0, 3)];

+}

diff --git a/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c b/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
new file mode 100644
index 0000000..ee832f0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
@@ -0,0 +1,712 @@
+/** @file

+  UEFI Decompress Library.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  UefiDecompressLib.c

+

+**/

+

+//

+// Decompression algorithm begins here

+//

+#define BITBUFSIZ 32

+#define MAXMATCH  256

+#define THRESHOLD 3

+#define CODE_BIT  16

+#define BAD_TABLE - 1

+

+//

+// C: Char&Len Set; P: Position Set; T: exTra Set

+//

+#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)

+#define CBIT    9

+#define MAXPBIT 5

+#define TBIT    5

+#define MAXNP   ((1U << MAXPBIT) - 1)

+#define NT      (CODE_BIT + 3)

+#if NT > MAXNP

+#define NPT NT

+#else

+#define NPT MAXNP

+#endif

+

+typedef struct {

+  UINT8   *mSrcBase;  ///< Starting address of compressed data

+  UINT8   *mDstBase;  ///< Starting address of decompressed data

+  UINT32  mOutBuf;

+  UINT32  mInBuf;

+

+  UINT16  mBitCount;

+  UINT32  mBitBuf;

+  UINT32  mSubBitBuf;

+  UINT16  mBlockSize;

+  UINT32  mCompSize;

+  UINT32  mOrigSize;

+

+  UINT16  mBadTableFlag;

+

+  UINT16  mLeft[2 * NC - 1];

+  UINT16  mRight[2 * NC - 1];

+  UINT8   mCLen[NC];

+  UINT8   mPTLen[NPT];

+  UINT16  mCTable[4096];

+  UINT16  mPTTable[256];

+

+  ///

+  /// The length of the field 'Position Set Code Length Array Size' in Block Header.

+  /// For EFI 1.1 de/compression algorithm, mPBit = 4

+  /// For Tiano de/compression algorithm, mPBit = 5

+  ///

+  UINT8   mPBit;

+} SCRATCH_DATA;

+

+/**

+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.

+

+  @param  Sd The global scratch data

+  @param  NumOfBits The number of bits to shift and read.

+

+**/

+VOID

+FillBuf (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+{

+  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);

+

+  while (NumOfBits > Sd->mBitCount) {

+

+    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));

+

+    if (Sd->mCompSize > 0) {

+      //

+      // Get 1 byte into SubBitBuf

+      //

+      Sd->mCompSize--;

+      Sd->mSubBitBuf  = 0;

+      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];

+      Sd->mBitCount   = 8;

+

+    } else {

+      //

+      // No more bits from the source, just pad zero bit.

+      //

+      Sd->mSubBitBuf  = 0;

+      Sd->mBitCount   = 8;

+

+    }

+  }

+

+  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);

+  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;

+}

+

+/**

+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent 

+  NumOfBits of bits from source. Returns NumOfBits of bits that are 

+  popped out.

+

+  @param  Sd The global scratch data.

+  @param  NumOfBits The number of bits to pop and read.

+

+  @return The bits that are popped out.

+

+**/

+UINT32

+GetBits (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+{

+  UINT32  OutBits;

+

+  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));

+

+  FillBuf (Sd, NumOfBits);

+

+  return OutBits;

+}

+

+/**

+  Creates Huffman Code mapping table according to code length array.

+

+  @param  Sd The global scratch data

+  @param  NumOfChar Number of symbols in the symbol set

+  @param  BitLen Code length array

+  @param  TableBits The width of the mapping table

+  @param  Table The table

+

+  @retval  0 OK.

+  @retval  BAD_TABLE The table is corrupted.

+

+**/

+UINT16

+MakeTable (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfChar,

+  IN  UINT8         *BitLen,

+  IN  UINT16        TableBits,

+  OUT UINT16        *Table

+  )

+{

+  UINT16  Count[17];

+  UINT16  Weight[17];

+  UINT16  Start[18];

+  UINT16  *Pointer;

+  UINT16  Index3;

+  volatile UINT16  Index;

+  UINT16  Len;

+  UINT16  Char;

+  UINT16  JuBits;

+  UINT16  Avail;

+  UINT16  NextCode;

+  UINT16  Mask;

+

+  for (Index = 1; Index <= 16; Index++) {

+    Count[Index] = 0;

+  }

+

+  for (Index = 0; Index < NumOfChar; Index++) {

+    Count[BitLen[Index]]++;

+  }

+

+  Start[1] = 0;

+

+  for (Index = 1; Index <= 16; Index++) {

+    Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));

+  }

+

+  if (Start[17] != 0) {

+    /*(1U << 16)*/

+    return (UINT16) BAD_TABLE;

+  }

+

+  JuBits = (UINT16) (16 - TableBits);

+

+  for (Index = 1; Index <= TableBits; Index++) {

+    Start[Index] >>= JuBits;

+    Weight[Index] = (UINT16) (1U << (TableBits - Index));

+  }

+

+  while (Index <= 16) {

+    Weight[Index] = (UINT16) (1U << (16 - Index));

+    Index++;    

+  }

+

+  Index = (UINT16) (Start[TableBits + 1] >> JuBits);

+

+  if (Index != 0) {

+    Index3 = (UINT16) (1U << TableBits);

+    while (Index != Index3) {

+      Table[Index++] = 0;

+    }

+  }

+

+  Avail = NumOfChar;

+  Mask  = (UINT16) (1U << (15 - TableBits));

+

+  for (Char = 0; Char < NumOfChar; Char++) {

+

+    Len = BitLen[Char];

+    if (Len == 0) {

+      continue;

+    }

+

+    NextCode = (UINT16) (Start[Len] + Weight[Len]);

+

+    if (Len <= TableBits) {

+

+      for (Index = Start[Len]; Index < NextCode; Index++) {

+        Table[Index] = Char;

+      }

+

+    } else {

+

+      Index3  = Start[Len];

+      Pointer = &Table[Index3 >> JuBits];

+      Index   = (UINT16) (Len - TableBits);

+

+      while (Index != 0) {

+        if (*Pointer == 0) {

+          Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;

+          *Pointer = Avail++;

+        }

+

+        if (Index3 & Mask) {

+          Pointer = &Sd->mRight[*Pointer];

+        } else {

+          Pointer = &Sd->mLeft[*Pointer];

+        }

+

+        Index3 <<= 1;

+        Index--;

+      }

+

+      *Pointer = Char;

+

+    }

+

+    Start[Len] = NextCode;

+  }

+  //

+  // Succeeds

+  //

+  return 0;

+}

+

+/**

+  Decodes a position value.

+

+  @param  Sd the global scratch data

+

+  @return The position value decoded.

+

+**/

+UINT32

+DecodeP (

+  IN  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  Val;

+  UINT32  Mask;

+  UINT32  Pos;

+

+  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+

+  if (Val >= MAXNP) {

+    Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+    do {

+

+      if (Sd->mBitBuf & Mask) {

+        Val = Sd->mRight[Val];

+      } else {

+        Val = Sd->mLeft[Val];

+      }

+

+      Mask >>= 1;

+    } while (Val >= MAXNP);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mPTLen[Val]);

+

+  Pos = Val;

+  if (Val > 1) {

+    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));

+  }

+

+  return Pos;

+}

+

+/**

+  Reads code lengths for the Extra Set or the Position Set.

+

+  @param  Sd The global scratch data.

+  @param  nn Number of symbols.

+  @param  nbit Number of bits needed to represent nn.

+  @param  Special The special symbol that needs to be taken care of.

+

+  @retval  0 OK.

+  @retval  BAD_TABLE Table is corrupted.

+

+**/

+UINT16

+ReadPTLen (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        nn,

+  IN  UINT16        nbit,

+  IN  UINT16        Special

+  )

+{

+  UINT16  Number;

+  UINT16  CharC;

+  volatile UINT16  Index;

+  UINT32  Mask;

+

+  Number = (UINT16) GetBits (Sd, nbit);

+

+  if (Number == 0) {

+    CharC = (UINT16) GetBits (Sd, nbit);

+

+    for (Index = 0; Index < 256; Index++) {

+      Sd->mPTTable[Index] = CharC;

+    }

+

+    for (Index = 0; Index < nn; Index++) {

+      Sd->mPTLen[Index] = 0;

+    }

+

+    return 0;

+  }

+

+  Index = 0;

+

+  while (Index < Number) {

+

+    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));

+

+    if (CharC == 7) {

+      Mask = 1U << (BITBUFSIZ - 1 - 3);

+      while (Mask & Sd->mBitBuf) {

+        Mask >>= 1;

+        CharC += 1;

+      }

+    }

+

+    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));

+

+    Sd->mPTLen[Index++] = (UINT8) CharC;

+

+    if (Index == Special) {

+      CharC = (UINT16) GetBits (Sd, 2);

+      while ((INT16) (--CharC) >= 0) {

+        Sd->mPTLen[Index++] = 0;

+      }

+    }

+  }

+

+  while (Index < nn) {

+    Sd->mPTLen[Index++] = 0;

+  }

+

+  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);

+}

+

+/**

+  Reads code lengths for Char&Len Set.

+

+  @param  Sd the global scratch data

+

+**/

+VOID

+ReadCLen (

+  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  Number;

+  UINT16  CharC;

+  volatile UINT16  Index;

+  UINT32  Mask;

+

+  Number = (UINT16) GetBits (Sd, CBIT);

+

+  if (Number == 0) {

+    CharC = (UINT16) GetBits (Sd, CBIT);

+

+    for (Index = 0; Index < NC; Index++) {

+      Sd->mCLen[Index] = 0;

+    }

+

+    for (Index = 0; Index < 4096; Index++) {

+      Sd->mCTable[Index] = CharC;

+    }

+

+    return ;

+  }

+

+  Index = 0;

+  while (Index < Number) {

+

+    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+    if (CharC >= NT) {

+      Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+      do {

+

+        if (Mask & Sd->mBitBuf) {

+          CharC = Sd->mRight[CharC];

+        } else {

+          CharC = Sd->mLeft[CharC];

+        }

+

+        Mask >>= 1;

+

+      } while (CharC >= NT);

+    }

+    //

+    // Advance what we have read

+    //

+    FillBuf (Sd, Sd->mPTLen[CharC]);

+

+    if (CharC <= 2) {

+

+      if (CharC == 0) {

+        CharC = 1;

+      } else if (CharC == 1) {

+        CharC = (UINT16) (GetBits (Sd, 4) + 3);

+      } else if (CharC == 2) {

+        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);

+      }

+

+      while ((INT16) (--CharC) >= 0) {

+        Sd->mCLen[Index++] = 0;

+      }

+

+    } else {

+

+      Sd->mCLen[Index++] = (UINT8) (CharC - 2);

+

+    }

+  }

+

+  while (Index < NC) {

+    Sd->mCLen[Index++] = 0;

+  }

+

+  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);

+

+  return ;

+}

+

+/**

+  Decode a character/length value.

+

+  @param  Sd The global scratch data.

+

+  @return The value decoded.

+

+**/

+UINT16

+DecodeC (

+  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  Index2;

+  UINT32  Mask;

+

+  if (Sd->mBlockSize == 0) {

+    //

+    // Starting a new block

+    //

+    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);

+    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+

+    ReadCLen (Sd);

+

+    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+  }

+

+  Sd->mBlockSize--;

+  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];

+

+  if (Index2 >= NC) {

+    Mask = 1U << (BITBUFSIZ - 1 - 12);

+

+    do {

+      if (Sd->mBitBuf & Mask) {

+        Index2 = Sd->mRight[Index2];

+      } else {

+        Index2 = Sd->mLeft[Index2];

+      }

+

+      Mask >>= 1;

+    } while (Index2 >= NC);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mCLen[Index2]);

+

+  return Index2;

+}

+

+/**

+  Decode the source data and put the resulting data into the destination buffer.

+

+  @param  Sd The global scratch data

+

+**/

+VOID

+Decode (

+  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  BytesRemain;

+  UINT32  DataIdx;

+  UINT16  CharC;

+

+  BytesRemain = (UINT16) (-1);

+

+  DataIdx     = 0;

+

+  for (;;) {

+    CharC = DecodeC (Sd);

+    if (Sd->mBadTableFlag != 0) {

+      return ;

+    }

+

+    if (CharC < 256) {

+      //

+      // Process an Original character

+      //

+      if (Sd->mOutBuf >= Sd->mOrigSize) {

+        return ;

+      } else {

+        Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;

+      }

+

+    } else {

+      //

+      // Process a Pointer

+      //

+      CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));

+

+      BytesRemain = CharC;

+

+      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;

+

+      BytesRemain--;

+      while ((INT16) (BytesRemain) >= 0) {

+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];

+        if (Sd->mOutBuf >= Sd->mOrigSize) {

+          return ;

+        }

+

+        BytesRemain--;

+      }

+    }

+  }

+

+  return ;

+}

+

+/**

+  The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().

+

+  @param  Source The source buffer containing the compressed data.

+  @param  SourceSize The size of source buffer

+  @param  DestinationSize The size of destination buffer.

+  @param  ScratchSize The size of scratch buffer.

+

+  @retval  RETURN_SUCCESS The size of destination buffer and the size of scratch buffer are successull retrieved.

+  @retval  RETURN_INVALID_PARAMETER The source data is corrupted

+

+**/

+RETURN_STATUS

+EFIAPI

+UefiDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+{

+  UINT32  CompressedSize;

+

+  ASSERT (Source != NULL);

+  ASSERT (DestinationSize != NULL);

+  ASSERT (ScratchSize != NULL);

+

+  *ScratchSize  = sizeof (SCRATCH_DATA);

+

+  if (SourceSize < 8) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  CopyMem (&CompressedSize, Source, sizeof (UINT32));

+  CopyMem (DestinationSize, (VOID *)((UINT8 *)Source + 4), sizeof (UINT32));

+

+  if (SourceSize < (CompressedSize + 8)) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().

+

+  @param  Source The source buffer containing the compressed data.

+  @param  Destination The destination buffer to store the decompressed data

+  @param  Scratch The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+

+  @retval  RETURN_SUCCESS Decompression is successfull

+  @retval  RETURN_INVALID_PARAMETER The source data is corrupted

+

+**/

+RETURN_STATUS

+EFIAPI

+UefiDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch

+  )

+{

+  volatile UINT32  Index;

+  UINT32           CompSize;

+  UINT32           OrigSize;

+  SCRATCH_DATA     *Sd;

+  CONST UINT8      *Src;

+  UINT8            *Dst;

+

+  ASSERT (Source != NULL);

+  ASSERT (Destination != NULL);

+  ASSERT (Scratch != NULL);

+

+  Src     = Source;

+  Dst     = Destination;

+

+  Sd = (SCRATCH_DATA *) Scratch;

+

+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);

+  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);

+

+  //

+  // If compressed file size is 0, return

+  //

+  if (OrigSize == 0) {

+    return RETURN_SUCCESS;

+  }

+

+  Src = Src + 8;

+

+  for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {

+    ((UINT8 *) Sd)[Index] = 0;

+  }

+  //

+  // The length of the field 'Position Set Code Length Array Size' in Block Header.

+  // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4

+  // For Tiano de/compression algorithm(Version 2), mPBit = 5

+  //

+  Sd->mPBit     = 4;

+  Sd->mSrcBase  = (UINT8 *)Src;

+  Sd->mDstBase  = Dst;

+  Sd->mCompSize = CompSize;

+  Sd->mOrigSize = OrigSize;

+

+  //

+  // Fill the first BITBUFSIZ bits

+  //

+  FillBuf (Sd, BITBUFSIZ);

+

+  //

+  // Decompress it

+  //

+  Decode (Sd);

+

+  if (Sd->mBadTableFlag != 0) {

+    //

+    // Something wrong with the source

+    //

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.mbd b/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.mbd
new file mode 100644
index 0000000..7ed513e
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>BaseUefiDecompressLib</BaseName>

+    <Guid>9ae5147d-b240-467f-a484-b024fdc42ee0</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.msa b/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.msa
new file mode 100644
index 0000000..cbd4ee7
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>BaseUefiDecompressLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>9ae5147d-b240-467f-a484-b024fdc42ee0</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiDecompressLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>BaseUefiDecompressLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/BaseUefiDecompressLib/build.xml b/edk2/MdePkg/Library/BaseUefiDecompressLib/build.xml
new file mode 100644
index 0000000..fffaca0
--- /dev/null
+++ b/edk2/MdePkg/Library/BaseUefiDecompressLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="BaseUefiDecompressLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/BaseUefiDecompressLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="BaseUefiDecompressLib">

+      <GenBuild baseName="BaseUefiDecompressLib" mbdFilename="${MODULE_DIR}/BaseUefiDecompressLib.mbd" msaFilename="${MODULE_DIR}/BaseUefiDecompressLib.msa"/>

+   </target>

+   <target depends="BaseUefiDecompressLib_clean" name="clean"/>

+   <target depends="BaseUefiDecompressLib_cleanall" name="cleanall"/>

+   <target name="BaseUefiDecompressLib_clean">

+      <OutputDirSetup baseName="BaseUefiDecompressLib" mbdFilename="${MODULE_DIR}/BaseUefiDecompressLib.mbd" msaFilename="${MODULE_DIR}/BaseUefiDecompressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseUefiDecompressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseUefiDecompressLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="BaseUefiDecompressLib_cleanall">

+      <OutputDirSetup baseName="BaseUefiDecompressLib" mbdFilename="${MODULE_DIR}/BaseUefiDecompressLib.mbd" msaFilename="${MODULE_DIR}/BaseUefiDecompressLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/BaseUefiDecompressLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/BaseUefiDecompressLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**BaseUefiDecompressLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c b/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c
new file mode 100644
index 0000000..a6f04df
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c
@@ -0,0 +1,63 @@
+/** @file

+  Entry point to the DXE Core.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.

+

+**/

+

+//

+// Cache copy of HobList pointer. 

+// 

+VOID *gHobList = NULL;

+

+/**

+  Enrty point to DXE core.

+

+  @param  HobStart Pointer of HobList.

+

+**/

+VOID

+EFIAPI

+_ModuleEntryPoint (

+  IN VOID  *HobStart

+  )

+{

+  //

+  // Cache a pointer to the HobList

+  //

+  gHobList = HobStart;

+

+  //

+  // Call the DXE Core entry point

+  //

+  ProcessModuleEntryPointList (HobStart);

+

+  //

+  // Should never return

+  //

+  ASSERT(FALSE);

+  CpuDeadLoop ();

+}

+

+

+/**

+  Wrapper of enrty point to DXE CORE.

+

+  @param  HobStart Pointer of HobList.

+

+**/

+VOID

+EFIAPI

+EfiMain (

+  IN VOID  *HobStart

+  )

+{

+  _ModuleEntryPoint (HobStart);

+}

diff --git a/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.mbd b/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.mbd
new file mode 100644
index 0000000..57a7d25
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeCoreEntryPoint</BaseName>

+    <Guid>d258d6af-2fc0-4019-9c1f-1101c3dd19b5</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.msa b/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.msa
new file mode 100644
index 0000000..02d9b73
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeCoreEntryPoint</BaseName>

+    <ModuleType>DXE_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>d258d6af-2fc0-4019-9c1f-1101c3dd19b5</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to the DXE Core</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DxeCoreEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeCoreEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeCoreEntryPoint/build.xml b/edk2/MdePkg/Library/DxeCoreEntryPoint/build.xml
new file mode 100644
index 0000000..2d58241
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreEntryPoint/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeCoreEntryPoint"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeCoreEntryPoint"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeCoreEntryPoint">

+      <GenBuild baseName="DxeCoreEntryPoint" mbdFilename="${MODULE_DIR}/DxeCoreEntryPoint.mbd" msaFilename="${MODULE_DIR}/DxeCoreEntryPoint.msa"/>

+   </target>

+   <target depends="DxeCoreEntryPoint_clean" name="clean"/>

+   <target depends="DxeCoreEntryPoint_cleanall" name="cleanall"/>

+   <target name="DxeCoreEntryPoint_clean">

+      <OutputDirSetup baseName="DxeCoreEntryPoint" mbdFilename="${MODULE_DIR}/DxeCoreEntryPoint.mbd" msaFilename="${MODULE_DIR}/DxeCoreEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreEntryPoint_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeCoreEntryPoint_cleanall">

+      <OutputDirSetup baseName="DxeCoreEntryPoint" mbdFilename="${MODULE_DIR}/DxeCoreEntryPoint.mbd" msaFilename="${MODULE_DIR}/DxeCoreEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreEntryPoint_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeCoreEntryPoint*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.mbd b/edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.mbd
new file mode 100644
index 0000000..6173b1c
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeCoreHobLib</BaseName>

+    <Guid>882ee1a3-35b2-412c-b8a2-7a8d34a7c390</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.msa b/edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.msa
new file mode 100644
index 0000000..fc493a8
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeCoreHobLib</BaseName>

+    <ModuleType>DXE_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>882ee1a3-35b2-412c-b8a2-7a8d34a7c390</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DxeCoreEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>HobLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeCoreHobLib/HobLib.c b/edk2/MdePkg/Library/DxeCoreHobLib/HobLib.c
new file mode 100644
index 0000000..45336c5
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreHobLib/HobLib.c
@@ -0,0 +1,444 @@
+/** @file

+  HOB Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  HobLib.c

+

+**/

+

+

+

+extern VOID *gHobList;

+

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+{

+  return gHobList;

+}

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  ASSERT (HobStart != NULL);

+   

+  Hob.Raw = (UINT8 *) HobStart;

+  //

+  // Parse the HOB list until end of list or matching type is found.

+  //

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == Type) {

+      return Hob.Raw;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return NULL;

+}

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextHob (Type, HobList);

+}

+

+/**

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  GuidHob;

+

+  GuidHob.Raw = (UINT8 *) HobStart;

+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {

+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+  return GuidHob.Raw;

+}

+

+/**

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextGuidHob (Guid, HobList);

+}

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the moduleÂ’s entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a GUID HOB with a certain data length.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Copies a data buffer to a newly-built HOB.

+

+  This function builds a customized HOB tagged with a GUID for identification,

+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

diff --git a/edk2/MdePkg/Library/DxeCoreHobLib/build.xml b/edk2/MdePkg/Library/DxeCoreHobLib/build.xml
new file mode 100644
index 0000000..acd833b
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeCoreHobLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeCoreHobLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeCoreHobLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeCoreHobLib">

+      <GenBuild baseName="DxeCoreHobLib" mbdFilename="${MODULE_DIR}/DxeCoreHobLib.mbd" msaFilename="${MODULE_DIR}/DxeCoreHobLib.msa"/>

+   </target>

+   <target depends="DxeCoreHobLib_clean" name="clean"/>

+   <target depends="DxeCoreHobLib_cleanall" name="cleanall"/>

+   <target name="DxeCoreHobLib_clean">

+      <OutputDirSetup baseName="DxeCoreHobLib" mbdFilename="${MODULE_DIR}/DxeCoreHobLib.mbd" msaFilename="${MODULE_DIR}/DxeCoreHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreHobLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeCoreHobLib_cleanall">

+      <OutputDirSetup baseName="DxeCoreHobLib" mbdFilename="${MODULE_DIR}/DxeCoreHobLib.mbd" msaFilename="${MODULE_DIR}/DxeCoreHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeCoreHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeCoreHobLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeCoreHobLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeHobLib/DxeHobLib.mbd b/edk2/MdePkg/Library/DxeHobLib/DxeHobLib.mbd
new file mode 100644
index 0000000..9a314af
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeHobLib/DxeHobLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeHobLib</BaseName>

+    <Guid>f12b59c9-76d0-4661-ad7c-f04d1bef0558</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeHobLib/DxeHobLib.msa b/edk2/MdePkg/Library/DxeHobLib/DxeHobLib.msa
new file mode 100644
index 0000000..c8deefe
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeHobLib/DxeHobLib.msa
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeHobLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>f12b59c9-76d0-4661-ad7c-f04d1bef0558</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>HobLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>HobList</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <Constructor>HobLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeHobLib/HobLib.c b/edk2/MdePkg/Library/DxeHobLib/HobLib.c
new file mode 100644
index 0000000..41baba2
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeHobLib/HobLib.c
@@ -0,0 +1,470 @@
+/** @file

+  HOB Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  HobLib.c

+

+**/

+

+

+

+STATIC VOID  *mHobList = NULL;

+

+/**

+  The constructor function caches the pointer to HOB list.

+  

+  The constructor function gets the start address of HOB list from system configuration table.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+HobLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &mHobList);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mHobList != NULL);

+  return Status;

+}

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+{

+  return mHobList;

+}

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  ASSERT (HobStart != NULL);

+   

+  Hob.Raw = (UINT8 *) HobStart;

+  //

+  // Parse the HOB list until end of list or matching type is found.

+  //

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == Type) {

+      return Hob.Raw;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return NULL;

+}

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextHob (Type, HobList);

+}

+

+/**

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  GuidHob;

+

+  GuidHob.Raw = (UINT8 *) HobStart;

+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {

+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+  return GuidHob.Raw;

+}

+

+/**

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextGuidHob (Guid, HobList);

+}

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the moduleÂ’s entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a GUID HOB with a certain data length.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Copies a data buffer to a newly-built HOB.

+

+  This function builds a customized HOB tagged with a GUID for identification,

+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

diff --git a/edk2/MdePkg/Library/DxeHobLib/build.xml b/edk2/MdePkg/Library/DxeHobLib/build.xml
new file mode 100644
index 0000000..06e4e80
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeHobLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeHobLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeHobLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeHobLib">

+      <GenBuild baseName="DxeHobLib" mbdFilename="${MODULE_DIR}/DxeHobLib.mbd" msaFilename="${MODULE_DIR}/DxeHobLib.msa"/>

+   </target>

+   <target depends="DxeHobLib_clean" name="clean"/>

+   <target depends="DxeHobLib_cleanall" name="cleanall"/>

+   <target name="DxeHobLib_clean">

+      <OutputDirSetup baseName="DxeHobLib" mbdFilename="${MODULE_DIR}/DxeHobLib.mbd" msaFilename="${MODULE_DIR}/DxeHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeHobLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeHobLib_cleanall">

+      <OutputDirSetup baseName="DxeHobLib" mbdFilename="${MODULE_DIR}/DxeHobLib.mbd" msaFilename="${MODULE_DIR}/DxeHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeHobLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeHobLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.mbd b/edk2/MdePkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.mbd
new file mode 100644
index 0000000..1db8290
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeIoLibCpuIo</BaseName>

+    <Guid>e94cd42a-3aad-4ea0-9b09-945891c60ccd</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-14 12:44</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.msa b/edk2/MdePkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.msa
new file mode 100644
index 0000000..9ae50fe
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.msa
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeIoLibCpuIo</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e94cd42a-3aad-4ea0-9b09-945891c60ccd</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>I/O Library implemented with Framework CPU I/O Protocol</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-14 12:44</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>IoLib.c</Filename>

+    <Filename>IoHighLevel.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">CpuIo</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>IoLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeIoLibCpuIo/IoHighLevel.c b/edk2/MdePkg/Library/DxeIoLibCpuIo/IoHighLevel.c
new file mode 100644
index 0000000..48a7477
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeIoLibCpuIo/IoHighLevel.c
@@ -0,0 +1,2272 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoHighLevel.c

+

+  The following IoLib instances share the same version of this file:

+

+    BaseIoLibIntrinsic

+    DxeIoLibCpuIo

+    PeiIoLibCpuIo

+

+**/

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, IoRead8 (Port) | OrData);

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, IoRead8 (Port) & AndData);

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (IoRead8 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, IoRead16 (Port) | OrData);

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, IoRead16 (Port) & AndData);

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (IoRead16 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 64-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, MmioRead8 (Address) | OrData);

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, MmioRead8 (Address) & AndData);

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (MmioRead8 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, MmioRead16 (Address) | OrData);

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, MmioRead16 (Address) & AndData);

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (MmioRead16 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 64-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 64-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/edk2/MdePkg/Library/DxeIoLibCpuIo/IoLib.c b/edk2/MdePkg/Library/DxeIoLibCpuIo/IoLib.c
new file mode 100644
index 0000000..fa3421b
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeIoLibCpuIo/IoLib.c
@@ -0,0 +1,591 @@
+/** @file

+  I/O Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoLib.c

+

+**/

+

+//

+// Globle varible to cache pointer to CpuIo protocol.

+//

+STATIC EFI_CPU_IO_PROTOCOL          *mCpuIo = NULL;

+

+/**

+  The constructor function caches the pointer to CpuIo protocol.

+  

+  The constructor function locates CpuIo protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+IoLibConstructor (

+  IN      EFI_HANDLE                ImageHandle,

+  IN      EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID**) &mCpuIo);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  Reads registers in the EFI CPU I/O space.

+

+  Reads the I/O port specified by Port with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required. 

+  @param  Width         The width of the I/O operation.

+  

+  @return Data read from registers in the EFI CPU I/O space.

+

+**/

+UINT64

+EFIAPI

+IoReadWorker (

+  IN      UINTN                     Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width

+  )

+{

+  EFI_STATUS                        Status;

+  UINT64                            Data;

+

+  Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Writes registers in the EFI CPU I/O space.

+

+  Writes the I/O port specified by Port with registers width and value specified by Width

+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required. 

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+  

+  @return The paramter of Data.

+

+**/

+UINT64

+EFIAPI

+IoWriteWorker (

+  IN      UINTN                     Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,

+  IN      UINT64                    Data

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Reads memory-mapped registers in the EFI system memory space. 

+

+  Reads the MMIO registers specified by Address with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required. 

+  @param  Width         The width of the I/O operation.

+  

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioReadWorker (

+  IN      UINTN                     Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width

+  )

+{

+  EFI_STATUS                        Status;

+  UINT64                            Data;

+

+  Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Writes memory-mapped registers in the EFI system memory space. 

+

+  Writes the MMIO registers specified by Address with registers width and value specified by Width

+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required. 

+  @param  Width         The width of the I/O operation.

+  

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioWriteWorker (

+  IN      UINTN                     Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,

+  IN      UINT64                    Data

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoReadWorker (Port, EfiCpuIoWidthUint64);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);

+}

diff --git a/edk2/MdePkg/Library/DxeIoLibCpuIo/build.xml b/edk2/MdePkg/Library/DxeIoLibCpuIo/build.xml
new file mode 100644
index 0000000..4c7243c
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeIoLibCpuIo/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeIoLibCpuIo"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeIoLibCpuIo"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeIoLibCpuIo">

+      <GenBuild baseName="DxeIoLibCpuIo" mbdFilename="${MODULE_DIR}/DxeIoLibCpuIo.mbd" msaFilename="${MODULE_DIR}/DxeIoLibCpuIo.msa"/>

+   </target>

+   <target depends="DxeIoLibCpuIo_clean" name="clean"/>

+   <target depends="DxeIoLibCpuIo_cleanall" name="cleanall"/>

+   <target name="DxeIoLibCpuIo_clean">

+      <OutputDirSetup baseName="DxeIoLibCpuIo" mbdFilename="${MODULE_DIR}/DxeIoLibCpuIo.mbd" msaFilename="${MODULE_DIR}/DxeIoLibCpuIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeIoLibCpuIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeIoLibCpuIo_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeIoLibCpuIo_cleanall">

+      <OutputDirSetup baseName="DxeIoLibCpuIo" mbdFilename="${MODULE_DIR}/DxeIoLibCpuIo.mbd" msaFilename="${MODULE_DIR}/DxeIoLibCpuIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeIoLibCpuIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeIoLibCpuIo_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeIoLibCpuIo*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.mbd b/edk2/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.mbd
new file mode 100644
index 0000000..d1f11c9
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeMemoryAllocationLib</BaseName>

+    <Guid>4674739d-3195-4fb2-8094-ac1d22d00194</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.msa b/edk2/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.msa
new file mode 100644
index 0000000..d33f59e
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeMemoryAllocationLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>4674739d-3195-4fb2-8094-ac1d22d00194</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MemoryAllocationLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c b/edk2/MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
new file mode 100644
index 0000000..15a419b
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
@@ -0,0 +1,903 @@
+/** @file

+  Support routines for memory allocation routines for use with drivers.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  MemoryAllocationLib.c

+

+**/

+

+

+

+/**

+  Allocates the number of 4KB pages specified by Pages of a certain memory type.

+

+  @param  MemoryType The type of memory to allocate.

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.<BR>

+  If Pages is 0, then NULL is returned.<BR>

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory; 

+

+  if (Pages == 0) {

+    return NULL;

+  }

+

+  Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+  if (EFI_ERROR (Status)) {

+    Memory = 0;

+  }

+  return (VOID *) (UINTN) Memory;

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData.

+

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.<BR>

+  If Pages is 0, then NULL is returned.<BR>

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocatePages (

+  IN UINTN  Pages

+  )

+{

+  return InternalAllocatePages (EfiBootServicesData, Pages);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData. 

+

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.<BR>

+  If Pages is 0, then NULL is returned.<BR>

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimePages (

+  IN UINTN  Pages

+  )

+{

+  return InternalAllocatePages (EfiRuntimeServicesData, Pages);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType. 

+

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.<BR>

+  If Pages is 0, then NULL is returned.<BR>

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedPages (

+  IN UINTN  Pages

+  )

+{

+  return InternalAllocatePages (EfiReservedMemoryType, Pages);

+}

+

+/**

+  Frees one or more 4KB pages that were previously allocated with 

+  one of the page allocation functions in the Memory Allocation Library.

+

+  @param  Buffer Pointer to the buffer of pages to free.

+  @param  Pages The number of 4 KB pages to free.

+

+**/

+VOID

+EFIAPI

+FreePages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (Pages != 0);

+  Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of a certian memory type 

+  with an alignment specified by Alignment. 

+

+  @param  MemoryType The type of memory to allocate.

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.<BR>

+  If Pages is 0, then NULL is returned.<BR>

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory;

+  UINTN                 AlignedMemory;

+  UINTN                 AlignmentMask;

+  UINTN                 UnalignedPages;

+  UINTN                 RealPages;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+ 

+  if (Pages == 0) {

+    return NULL;

+  }

+  if (Alignment > EFI_PAGE_SIZE) {

+    //

+    // Caculate the total number of pages since alignment is larger than page size.

+    //

+    AlignmentMask  = Alignment - 1;

+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);

+    //

+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.

+    //

+    ASSERT (RealPages > Pages);

+ 

+    Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;

+    UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);

+    if (UnalignedPages > 0) {

+      //

+      // Free first unaligned page(s).

+      //

+      Status = gBS->FreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));

+    UnalignedPages = RealPages - Pages - UnalignedPages;

+    if (UnalignedPages > 0) {

+      //

+      // Free last unaligned page(s).

+      //

+      Status = gBS->FreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+  } else {

+    //

+    // Do not over-allocate pages in this case.

+    //

+    Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = (UINTN) Memory;

+  }

+  return (VOID *) AlignedMemory;

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData

+  with an alignment specified by Alignment.   

+

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.<BR>

+  If Pages is 0, then NULL is returned.<BR>

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData

+  with an alignment specified by Alignment.   

+

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimePages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);

+}

+

+/**

+  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.

+

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);

+}

+

+/**

+  Frees one or more 4KB pages that were previously allocated with 

+  one of the aligned page allocation functions in the Memory Allocation Library.

+

+  @param  Buffer Pointer to the buffer of pages to free.

+  @param  Pages The number of 4 KB pages to free.

+

+**/

+VOID

+EFIAPI

+FreeAlignedPages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (Pages != 0);

+  Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates a buffer of a certain memory type.

+

+  @param  MemoryType The type of memory to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            AllocationSize

+  )

+{

+  EFI_STATUS  Status;

+  VOID        *Memory;

+

+  Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);

+  if (EFI_ERROR (Status)) {

+    Memory = NULL;

+  }

+  return Memory;

+}

+

+/**

+  Allocates a buffer of type EfiBootServicesData.

+

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocatePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocatePool (EfiBootServicesData, AllocationSize);

+}

+

+/**

+  Allocates a buffer of type EfiRuntimeServicesData.

+

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);

+}

+

+/**

+  Allocates a buffer of type EfiReservedMemoryType.

+

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of a certian pool type.

+

+  @param  PoolType The type of memory to allocate.

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize

+  ) 

+{

+  VOID  *Memory;

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData.

+

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiRuntimeServicesData.

+

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimeZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiReservedMemoryType.

+

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Copies a buffer to an allocated buffer of a certian memory type. 

+

+  @param  MemoryType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate and zero.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  ) 

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+} 

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData. 

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. 

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType. 

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  Buffer Pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreePool (

+  IN VOID   *Buffer

+  )

+{

+  EFI_STATUS    Status;

+

+  Status = gBS->FreePool (Buffer);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates a buffer of a certain pool type at a specified alignment.

+

+  @param  PoolType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.                            If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID        *RawAddress;

+  UINTN       AlignedAddress;

+  UINTN       AlignmentMask;

+  UINTN       OverAllocationSize;

+  UINTN       RealAllocationSize;

+  VOID        **FreePointer;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+  

+  if (Alignment == 0) {

+    AlignmentMask = Alignment;

+  } else {

+    AlignmentMask = Alignment - 1;

+  }

+  //

+  // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address. 

+  //

+  OverAllocationSize  = sizeof (RawAddress) + AlignmentMask;

+  RealAllocationSize  = AllocationSize + OverAllocationSize;

+  //

+  // Make sure that AllocationSize plus OverAllocationSize does not overflow. 

+  //

+  ASSERT (RealAllocationSize > AllocationSize); 

+

+  RawAddress = InternalAllocatePool (PoolType, RealAllocationSize);

+  if (RawAddress == NULL) {

+    return NULL;

+  }

+  AlignedAddress      = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;

+  //

+  // Save the original memory address just before the aligned address.

+  //

+  FreePointer         = (VOID **)(AlignedAddress - sizeof (RawAddress));

+  *FreePointer        = RawAddress;

+

+  return (VOID *) AlignedAddress;

+}

+

+/**

+  Allocates a buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.                            If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);

+}

+

+/**

+  Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimePool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+/**

+  Allocates a buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  PoolType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID    *Memory;

+  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimeZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  PoolType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer,

+  IN UINTN            Alignment

+  )

+{

+  VOID  *Memory;

+  

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);

+}

+

+/**

+  Frees a buffer that was previously allocated with one of the aligned pool allocation functions 

+  in the Memory Allocation Library.

+

+  @param  Buffer Pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreeAlignedPool (

+  IN VOID   *Buffer

+  )

+{

+  VOID        *RawAddress;

+  VOID        **FreePointer;

+  EFI_STATUS  Status;

+

+  //

+  // Get the pre-saved original address in the over-allocate pool.

+  //

+  FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));

+  RawAddress  = *FreePointer;

+

+  Status = gBS->FreePool (RawAddress);

+  ASSERT_EFI_ERROR (Status);

+}

diff --git a/edk2/MdePkg/Library/DxeMemoryAllocationLib/build.xml b/edk2/MdePkg/Library/DxeMemoryAllocationLib/build.xml
new file mode 100644
index 0000000..0cbff38
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeMemoryAllocationLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeMemoryAllocationLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeMemoryAllocationLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeMemoryAllocationLib">

+      <GenBuild baseName="DxeMemoryAllocationLib" mbdFilename="${MODULE_DIR}/DxeMemoryAllocationLib.mbd" msaFilename="${MODULE_DIR}/DxeMemoryAllocationLib.msa"/>

+   </target>

+   <target depends="DxeMemoryAllocationLib_clean" name="clean"/>

+   <target depends="DxeMemoryAllocationLib_cleanall" name="cleanall"/>

+   <target name="DxeMemoryAllocationLib_clean">

+      <OutputDirSetup baseName="DxeMemoryAllocationLib" mbdFilename="${MODULE_DIR}/DxeMemoryAllocationLib.mbd" msaFilename="${MODULE_DIR}/DxeMemoryAllocationLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeMemoryAllocationLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeMemoryAllocationLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeMemoryAllocationLib_cleanall">

+      <OutputDirSetup baseName="DxeMemoryAllocationLib" mbdFilename="${MODULE_DIR}/DxeMemoryAllocationLib.mbd" msaFilename="${MODULE_DIR}/DxeMemoryAllocationLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeMemoryAllocationLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeMemoryAllocationLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeMemoryAllocationLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.c b/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.c
new file mode 100644
index 0000000..f3818a6
--- /dev/null
+++ b/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.c
@@ -0,0 +1,851 @@
+/** @file

+Implementation of PcdLib class library for DXE phase.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: DxePcdLib.c

+

+**/

+

+static PCD_PROTOCOL  *mPcd;

+

+/**

+  The constructor function caches the PCD_PROTOCOL pointer.

+

+  @param[in] ImageHandle The firmware allocated handle for the EFI image.	

+  @param[in] SystemTable A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS The constructor always return EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PcdLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **)&mPcd);

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Sets the current SKU in the PCD database to the value specified by SkuId.  SkuId is returned.

+

+  @param[in]  SkuId The SKU value that will be used when the PCD service will retrieve and 

+              set values associated with a PCD token.

+

+  @retval SKU_ID Return the SKU ID that just be set.

+

+**/

+SKU_ID

+EFIAPI

+LibPcdSetSku (

+  IN SKU_ID  SkuId

+  )

+{

+  mPcd->SetSku (SkuId);

+

+  return SkuId;

+}

+

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Returns the 8-bit value for the token specified by TokenNumber. 

+

+**/

+UINT8

+EFIAPI

+LibPcdGet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->Get8 (TokenNumber);

+}

+

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Returns the 16-bit value for the token specified by TokenNumber. 

+

+**/

+UINT16

+EFIAPI

+LibPcdGet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->Get16 (TokenNumber);

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Returns the 32-bit value for the token specified by TokenNumber.

+

+**/

+UINT32

+EFIAPI

+LibPcdGet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->Get32 (TokenNumber);

+}

+

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Returns the 64-bit value for the token specified by TokenNumber.

+

+**/

+UINT64

+EFIAPI

+LibPcdGet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->Get64 (TokenNumber);

+}

+

+

+

+/**

+  Returns the pointer to the buffer of the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Returns the pointer to the token specified by TokenNumber.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->GetPtr (TokenNumber);

+}

+

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Returns the Boolean value of the token specified by TokenNumber. 

+

+**/

+BOOLEAN 

+EFIAPI

+LibPcdGetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->GetBool (TokenNumber);

+}

+

+

+

+/**

+  Returns the size of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Returns the size of the token specified by TokenNumber. 

+

+**/

+UINTN

+EFIAPI

+LibPcdGetSize (

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  return mPcd->GetSize (TokenNumber);

+}

+

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Return the UINT8.

+

+**/

+UINT8

+EFIAPI

+LibPcdGetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+  

+  return mPcd->Get8Ex (Guid, TokenNumber);

+}

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Return the UINT16.

+

+**/

+UINT16

+EFIAPI

+LibPcdGetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return mPcd->Get16Ex (Guid, TokenNumber);

+}

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Return the UINT32.

+

+**/

+UINT32

+EFIAPI

+LibPcdGetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return mPcd->Get32Ex (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Return the UINT64.

+

+**/

+UINT64

+EFIAPI

+LibPcdGetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+  

+  return mPcd->Get64Ex (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the pointer to the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Return the VOID* pointer.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return mPcd->GetPtrEx (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Return the BOOLEAN.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdGetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return mPcd->GetBoolEx (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the size of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Return the size.

+

+**/

+UINTN

+EFIAPI

+LibPcdGetExSize (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return mPcd->GetSizeEx (Guid, TokenNumber);

+}

+

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+{

+  EFI_STATUS Status;

+

+  Status = mPcd->Set8 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return Value;

+}

+

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT16 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+{

+  EFI_STATUS Status;

+

+  Status = mPcd->Set16 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return Value;

+}

+

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32             Value

+  )

+{

+  EFI_STATUS Status;

+  Status = mPcd->Set32 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64             Value

+  )

+{

+  EFI_STATUS Status;

+

+  Status = mPcd->Set64 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber to 

+  the value specified by Value. Value is returned.

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value A pointer to the buffer to set.

+

+  @retval VOID* Return the pointer for the buffer been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+{

+  EFI_STATUS Status;

+  

+  ASSERT (Buffer != NULL);

+

+  Status = mPcd->SetPtr (TokenNumber, SizeOfBuffer, Buffer);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Buffer;

+}

+

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The boolean value to set.

+

+  @retval BOOLEAN Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  EFI_STATUS Status;

+

+  Status = mPcd->SetBool (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = mPcd->Set8Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = mPcd->Set16Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32             Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = mPcd->Set32Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64             Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = mPcd->Set64Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval VOID * Return the value been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+  ASSERT (Buffer != NULL);

+

+  Status = mPcd->SetPtrEx (Guid, TokenNumber, SizeOfBuffer, Buffer);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Buffer;

+}

+

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The Boolean value to set.

+

+  @retval Boolean Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = mPcd->SetBoolEx (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  When the token specified by TokenNumber and Guid is set, 

+  then notification function specified by NotificationFunction is called.  

+  If Guid is NULL, then the default token space is used. 

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates which 

+              namespace to set a value from.  If NULL, then the default 

+              token space is used.

+  @param[in]  TokenNumber The PCD token number to monitor.

+  @param[in]  NotificationFunction The function to call when the token 

+              specified by Guid and TokenNumber is set.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCallbackOnSet (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (NotificationFunction != NULL);

+

+  Status = mPcd->CallbackOnSet (TokenNumber, Guid, NotificationFunction);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  Disable a notification function that was established with LibPcdCallbackonSet().

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Specify the GUID token space.

+  @param[in]  TokenNumber Specify the token number.

+  @param[in]  NotificationFunction The callback function to be unregistered.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCancelCallback (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (NotificationFunction != NULL);

+    

+  Status = mPcd->CancelCallback (TokenNumber, Guid, NotificationFunction);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  Retrieves the next PCD token number from the token space specified by Guid.  

+  If Guid is NULL, then the default token space is used.  If TokenNumber is 0, 

+  then the first token number is returned.  Otherwise, the token number that 

+  follows TokenNumber in the token space is returned.  If TokenNumber is the last 

+  token number in the token space, then 0 is returned.  If TokenNumber is not 0 and 

+  is not in the token space specified by Guid, then ASSERT().

+

+  @param[in]  Pointer to a 128-bit unique value that designates which namespace 

+              to set a value from.  If NULL, then the default token space is used.

+  @param[in]  The previous PCD token number.  If 0, then retrieves the first PCD 

+              token number.

+

+  @retval PCD_TOKEN_NUMBER The next valid token number.

+

+**/

+PCD_TOKEN_NUMBER           

+EFIAPI

+LibPcdGetNextToken (

+  IN CONST GUID             *Guid, OPTIONAL

+  IN       PCD_TOKEN_NUMBER TokenNumber

+  )

+{

+  EFI_STATUS Status;

+

+  Status = mPcd->GetNextToken (Guid, &TokenNumber);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return TokenNumber;

+}

+

diff --git a/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.mbd b/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.mbd
new file mode 100644
index 0000000..52fc7e3
--- /dev/null
+++ b/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxePcdLib</BaseName>

+    <Guid>af97eb89-4cc6-45f8-a514-ca025b346480</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.msa b/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.msa
new file mode 100644
index 0000000..163b751
--- /dev/null
+++ b/edk2/MdePkg/Library/DxePcdLib/DxePcdLib.msa
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxePcdLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>af97eb89-4cc6-45f8-a514-ca025b346480</Guid>

+    <Version>0</Version>

+    <Abstract>IO Library implemented with Framework CPU IO Protocol</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxePcdLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Pcd</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>PcdLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxePcdLib/build.xml b/edk2/MdePkg/Library/DxePcdLib/build.xml
new file mode 100644
index 0000000..3f50282
--- /dev/null
+++ b/edk2/MdePkg/Library/DxePcdLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxePcdLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxePcdLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxePcdLib">

+      <GenBuild baseName="DxePcdLib" mbdFilename="${MODULE_DIR}/DxePcdLib.mbd" msaFilename="${MODULE_DIR}/DxePcdLib.msa"/>

+   </target>

+   <target depends="DxePcdLib_clean" name="clean"/>

+   <target depends="DxePcdLib_cleanall" name="cleanall"/>

+   <target name="DxePcdLib_clean">

+      <OutputDirSetup baseName="DxePcdLib" mbdFilename="${MODULE_DIR}/DxePcdLib.mbd" msaFilename="${MODULE_DIR}/DxePcdLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxePcdLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxePcdLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxePcdLib_cleanall">

+      <OutputDirSetup baseName="DxePcdLib" mbdFilename="${MODULE_DIR}/DxePcdLib.mbd" msaFilename="${MODULE_DIR}/DxePcdLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxePcdLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxePcdLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxePcdLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.mbd b/edk2/MdePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.mbd
new file mode 100644
index 0000000..5569ae9
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeReportStatusCodeLib</BaseName>

+    <Guid>3ddc3b12-99ea-4364-b315-6310a2050be5</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.msa b/edk2/MdePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.msa
new file mode 100644
index 0000000..214fdf3
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.msa
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeReportStatusCodeLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>3ddc3b12-99ea-4364-b315-6310a2050be5</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:16</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ReportStatusCodeLib.c</Filename>

+    <Filename>PostCode.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">StatusCode</Protocol>

+  </Protocols>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeDataTypeAssert</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeDataTypeDebug</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeSpecificData</C_Name>

+    </GuidEntry>

+  </Guids>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+      <Token>0x00000007</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeReportStatusCodeLib/PostCode.c b/edk2/MdePkg/Library/DxeReportStatusCodeLib/PostCode.c
new file mode 100644
index 0000000..3d0ce7c
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeReportStatusCodeLib/PostCode.c
@@ -0,0 +1,125 @@
+/** @file

+  Report Status Code Library Post Code functions for DXE Phase.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Report Status Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x\n", Value));

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Report 

+  Status Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  Pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x - %s\n", Value, Description));

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the 

+  REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED bit of 

+  PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeDescriptionEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/DxeReportStatusCodeLib/ReportStatusCodeLib.c b/edk2/MdePkg/Library/DxeReportStatusCodeLib/ReportStatusCodeLib.c
new file mode 100644
index 0000000..9edb753
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeReportStatusCodeLib/ReportStatusCodeLib.c
@@ -0,0 +1,585 @@
+/** @file

+  Report Status Code Library for DXE Phase.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+//

+// Global pointer to the Status Code Protocol

+//

+static EFI_STATUS_CODE_PROTOCOL  *gStatusCode = NULL;

+

+/**

+  Internal worker function that reports a status code through the Status Code Protocol

+

+  This function checks to see if a Status Code Protocol is present in the handle 

+  database.  If a Status Code Protocol is not present, then EFI_UNSUPPORTED is 

+  returned.  If a Status Code Protocol is present, then it is cached in gStatusCode,

+  and the ReportStatusCode() service of the Status Code Protocol is called passing in

+  Type, Value, Instance, CallerId, and Data.  The result of this call is returned.

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  This is an optional parameter that may be 

+                            NULL.

+  @param  Data              Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to report the status code.

+  @retval  EFI_UNSUPPORTED       Status Code Protocol is not available.

+

+**/

+EFI_STATUS

+InternalReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     Type,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId OPTIONAL,

+  IN EFI_STATUS_CODE_DATA     *Data     OPTIONAL  

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // If gStatusCode is NULL, then see if a Status Code Protocol instance is present 

+  // in the handle database.

+  //

+  if (gStatusCode == NULL) {

+    Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&gStatusCode);

+    if (EFI_ERROR (Status) || gStatusCode == NULL) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  //

+  // A Status Code Protocol is present in the handle database, so pass in all the  

+  // parameters to the ReportStatusCode() service of the Status Code Protocol

+  //

+  return gStatusCode->ReportStatusCode (Type, Value, Instance, CallerId, Data);

+}

+

+

+/**

+  Computes and returns the size, in bytes, of a device path.

+

+  @param  DevicePath  A pointer to a device path.

+

+  @return  The size, in bytes, of DevicePath.

+

+**/

+UINTN

+InternalReportStatusCodeDevicePathSize (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *Start;

+

+  if (DevicePath == NULL) {

+    return 0;

+  }

+

+  //

+  // Search for the end of the device path structure

+  //

+  Start = DevicePath;

+  while (!EfiIsDevicePathEnd (DevicePath)) {

+    DevicePath = EfiNextDevicePathNode (DevicePath);

+  }

+

+  //

+  // Subtract the start node from the end node and add in the size of the end node

+  //

+  return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);

+}

+

+

+/**

+  Converts a status code to an 8-bit POST code value.

+

+  Converts the status code specified by CodeType and Value to an 8-bit POST code 

+  and returns the 8-bit POST code in PostCode.  If CodeType is an 

+  EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode 

+  are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits 

+  24..26 of Value., and TRUE is returned.  Otherwise, FALSE is returned.  

+

+  If PostCode is NULL, then ASSERT().

+

+  @param  CodeType  The type of status code being converted.

+  @param  Value     The status code value being converted.

+  @param  PostCode  A pointer to the 8-bit POST code value to return. 

+

+  @retval  TRUE   The status code specified by CodeType and Value was converted 

+                  to an 8-bit POST code and returned in  PostCode.

+  @retval  FALSE  The status code specified by CodeType and Value could not be 

+                  converted to an 8-bit POST code value.

+

+**/

+BOOLEAN

+EFIAPI

+CodeTypeToPostCode (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,

+  OUT UINT8                  *PostCode

+  )

+{

+  //

+  // If PostCode is NULL, then ASSERT()

+  //

+  ASSERT (PostCode != NULL);

+

+  //

+  // Convert Value to an 8 bit post code

+  //

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||

+      ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)       ) {

+    *PostCode  = (UINT8) (((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5);

+    *PostCode |= (UINT8) (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f);

+    return TRUE;

+  }

+  return FALSE;

+}

+

+

+/**

+  Extracts ASSERT() information from a status code structure.

+

+  Converts the status code specified by CodeType, Value, and Data to the ASSERT()

+  arguments specified by Filename, Description, and LineNumber.  If CodeType is 

+  an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and 

+  Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract 

+  Filename, Description, and LineNumber from the optional data area of the 

+  status code buffer specified by Data.  The optional data area of Data contains 

+  a Null-terminated ASCII string for the FileName, followed by a Null-terminated 

+  ASCII string for the Description, followed by a 32-bit LineNumber.  If the 

+  ASSERT() information could be extracted from Data, then return TRUE.  

+  Otherwise, FALSE is returned.  

+

+  If Data is NULL, then ASSERT().

+  If Filename is NULL, then ASSERT().

+  If Description is NULL, then ASSERT().

+  If LineNumber is NULL, then ASSERT().

+

+  @param  CodeType     The type of status code being converted.

+  @param  Value        The status code value being converted.

+  @param  Data         Pointer to status code data buffer. 

+  @param  Filename     Pointer to the source file name that generated the ASSERT().

+  @param  Description  Pointer to the description of the ASSERT().

+  @param  LineNumber   Pointer to source line number that generated the ASSERT().

+

+  @retval  TRUE   The status code specified by CodeType, Value, and Data was 

+                  converted ASSERT() arguments specified by Filename, Description, 

+                  and LineNumber.

+  @retval  FALSE  The status code specified by CodeType, Value, and Data could 

+                  not be converted to ASSERT() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractAssertInfo (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,  

+  IN  EFI_STATUS_CODE_DATA   *Data, 

+  OUT CHAR8                  **Filename,

+  OUT CHAR8                  **Description,

+  OUT UINT32                 *LineNumber

+  )

+{

+  EFI_DEBUG_ASSERT_DATA  *AssertData;

+

+  ASSERT (Data        != NULL);

+  ASSERT (Filename    != NULL);

+  ASSERT (Description != NULL);

+  ASSERT (LineNumber  != NULL);

+

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK)      == EFI_ERROR_CODE) && 

+      ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK)  == EFI_ERROR_UNRECOVERED) &&

+      ((Value    & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {

+    AssertData   = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);

+    *Filename    = (CHAR8 *)(AssertData + 1);

+    *Description = *Filename + AsciiStrLen (*Filename) + 1;

+    *LineNumber  = AssertData->LineNumber;

+    return TRUE;

+  }

+  return FALSE;

+}

+

+

+/**

+  Extracts DEBUG() information from a status code structure.

+

+  Converts the status code specified by Data to the DEBUG() arguments specified 

+  by ErrorLevel, Marker, and Format.  If type GUID in Data is 

+  EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and 

+  Format from the optional data area of the status code buffer specified by Data.  

+  The optional data area of Data contains a 32-bit ErrorLevel followed by Marker 

+  which is 12 UINTN parameters, followed by a Null-terminated ASCII string for 

+  the Format.  If the DEBUG() information could be extracted from Data, then 

+  return TRUE.  Otherwise, FALSE is returned.

+

+  If Data is NULL, then ASSERT().

+  If ErrorLevel is NULL, then ASSERT().

+  If Marker is NULL, then ASSERT().

+  If Format is NULL, then ASSERT().

+

+  @param  Data        Pointer to status code data buffer. 

+  @param  ErrorLevel  Pointer to error level mask for a debug message.

+  @param  Marker      Pointer to the variable argument list associated with Format.

+  @param  Format      Pointer to a Null-terminated ASCII format string of a 

+                      debug message.

+

+  @retval  TRUE   The status code specified by Data was converted DEBUG() arguments 

+                  specified by ErrorLevel, Marker, and Format.

+  @retval  FALSE  The status code specified by Data could not be converted to 

+                  DEBUG() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractDebugInfo (

+  IN  EFI_STATUS_CODE_DATA  *Data,

+  OUT UINT32                *ErrorLevel,

+  OUT VA_LIST               *Marker,

+  OUT CHAR8                 **Format

+  )

+{

+  EFI_DEBUG_INFO  *DebugInfo;

+

+  ASSERT (Data       != NULL);

+  ASSERT (ErrorLevel != NULL);

+  ASSERT (Marker     != NULL);

+  ASSERT (Format     != NULL);

+

+  //

+  // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE

+  //

+  if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {

+    return FALSE;

+  }

+

+  //

+  // Retrieve the debug information from the status code record

+  //

+  DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);

+

+  *ErrorLevel = DebugInfo->ErrorLevel;

+

+  //

+  // The first 12 * UINTN bytes of the string are really an 

+  // argument stack to support varargs on the Format string.

+  //

+  *Marker = (VA_LIST) (DebugInfo + 1);

+  *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);

+

+  return TRUE;

+}

+

+

+/**

+  Reports a status code.

+

+  Reports the status code specified by the parameters Type and Value.  Status 

+  code also require an instance, caller ID, and extended data.  This function 

+  passed in a zero instance, NULL extended data, and a caller ID of 

+  gEfiCallerIdGuid, which is the GUID for the module.  

+  

+  ReportStatusCode()must actively prevent recusrsion.  If ReportStatusCode() 

+  is called while processing another any other Report Status Code Library function,

+  then ReportStatusCode() must return immediately.

+

+  @param  Type   Status code type. 

+  @param  Value  Status code value.

+

+  @retval  EFI_SUCCESS       The status code was reported.

+  @retval  EFI_DEVICE_ERROR  There status code could not be reported due to a 

+                             device error.

+  @retval  EFI_UNSUPPORTED   Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value

+  )

+{

+  return InternalReportStatusCode (Type, Value, 0, &gEfiCallerIdGuid, NULL);

+}

+

+

+/**

+  Reports a status code with a Device Path Protocol as the extended data.

+

+  Allocates and fills in the extended data section of a status code with the 

+  Device Path Protocol specified by DevicePath.  This function is responsible 

+  for allocating a buffer large enough for the standard header and the device 

+  path.  The standard header is filled in with a GUID of 

+  gEfiStatusCodeSpecificDataGuid.  The status code is reported with a zero 

+  instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithDevicePath()must actively prevent recursion.  If 

+  ReportStatusCodeWithDevicePath() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithDevicePath() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If DevicePath is NULL, then ASSERT().

+

+  @param  Type        Status code type. 

+  @param  Value       Status code value.

+  @param  DevicePath  Pointer to the Device Path Protocol to be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by DevicePath.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithDevicePath (

+  IN EFI_STATUS_CODE_TYPE      Type,

+  IN EFI_STATUS_CODE_VALUE     Value,

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  ASSERT (DevicePath != NULL);

+  return ReportStatusCodeWithExtendedData (

+           Type, 

+           Value, 

+           (VOID *)DevicePath, 

+           InternalReportStatusCodeDevicePathSize (DevicePath)

+           );

+}

+

+

+/**

+  Reports a status code with an extended data buffer.

+

+  Allocates and fills in the extended data section of a status code with the 

+  extended data specified by ExtendedData and ExtendedDataSize.  ExtendedData 

+  is assumed to be one of the data structures specified in Related Definitions.  

+  These data structure do not have the standard header, so this function is 

+  responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled 

+  in with a GUID of  gEfiStatusCodeSpecificDataGuid.  The status code is reported 

+  with a zero instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithExtendedData()must actively prevent recursion.  If 

+  ReportStatusCodeWithExtendedData() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithExtendedData() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL, then ASSERT().

+  If ExtendedDataSize is 0, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  ExtendedData      Pointer to the extended data buffer to be reported.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer to 

+                            be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by ExtendedData and ExtendedDataSize.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithExtendedData (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN VOID                   *ExtendedData,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  ASSERT (ExtendedData     != NULL);

+  ASSERT (ExtendedDataSize != 0);

+  return ReportStatusCodeEx (

+           Type,

+           Value,

+           0,

+           NULL,

+           NULL,

+           ExtendedData,

+           ExtendedDataSize

+           );

+}

+

+

+/**

+  Reports a status code with full parameters.

+

+  The function reports a status code.  If ExtendedData is NULL and ExtendedDataSize 

+  is 0, then an extended data buffer is not reported.  If ExtendedData is not 

+  NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.  

+  ExtendedData is assumed not have the standard status code header, so this function 

+  is responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled in 

+  with a GUID specified by ExtendedDataGuid.  If ExtendedDataGuid is NULL, then a 

+  GUID of gEfiStatusCodeSpecificDatauid is used.  The status code is reported with 

+  an instance specified by Instance and a caller ID specified by CallerId.  If 

+  CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.

+

+  ReportStatusCodeEx()must actively prevent recursion.  If ReportStatusCodeEx() 

+  is called while processing another any other Report Status Code Library function, 

+  then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().

+  If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  If this parameter is NULL, then a caller 

+                            ID of gEfiCallerIdGuid is used.

+  @param  ExtendedDataGuid  Pointer to the GUID for the extended data buffer.  

+                            If this parameter is NULL, then a the status code 

+                            standard header is filled in with 

+                            gEfiStatusCodeSpecificDataGuid.

+  @param  ExtendedData      Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate 

+                                 the extended data section if it was specified.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeEx (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN UINT32                 Instance,

+  IN EFI_GUID               *CallerId           OPTIONAL,

+  IN EFI_GUID               *ExtendedDataGuid   OPTIONAL,

+  IN VOID                   *ExtendedData       OPTIONAL,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  EFI_STATUS            Status;

+  EFI_STATUS_CODE_DATA  *StatusCodeData;

+

+  ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));

+  ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));

+

+  //

+  // Allocate space for the Status Code Header and its buffer

+  //

+  StatusCodeData = NULL;

+  gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_STATUS_CODE_DATA) + ExtendedDataSize, (VOID **)&StatusCodeData);

+  if (StatusCodeData == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Fill in the extended data header

+  //

+  StatusCodeData->HeaderSize = sizeof (EFI_STATUS_CODE_DATA);

+  StatusCodeData->Size = (UINT16)ExtendedDataSize;

+  if (ExtendedDataGuid == NULL) {

+    ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;

+  }

+  CopyGuid (&StatusCodeData->Type, ExtendedDataGuid);

+

+  //

+  // Fill in the extended data buffer

+  //

+  CopyMem (StatusCodeData + 1, ExtendedData, ExtendedDataSize);

+

+  //

+  // Report the status code

+  //

+  if (CallerId == NULL) {

+    CallerId = &gEfiCallerIdGuid;

+  }

+  Status = InternalReportStatusCode (Type, Value, Instance, CallerId, StatusCodeData);

+

+  //

+  // Free the allocated buffer

+  //

+  gBS->FreePool (StatusCodeData);

+

+  return Status;

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportProgressCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_ERROR_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportErrorCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportDebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/DxeReportStatusCodeLib/build.xml b/edk2/MdePkg/Library/DxeReportStatusCodeLib/build.xml
new file mode 100644
index 0000000..fc74f9d
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeReportStatusCodeLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeReportStatusCodeLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeReportStatusCodeLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeReportStatusCodeLib">

+      <GenBuild baseName="DxeReportStatusCodeLib" mbdFilename="${MODULE_DIR}/DxeReportStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/DxeReportStatusCodeLib.msa"/>

+   </target>

+   <target depends="DxeReportStatusCodeLib_clean" name="clean"/>

+   <target depends="DxeReportStatusCodeLib_cleanall" name="cleanall"/>

+   <target name="DxeReportStatusCodeLib_clean">

+      <OutputDirSetup baseName="DxeReportStatusCodeLib" mbdFilename="${MODULE_DIR}/DxeReportStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/DxeReportStatusCodeLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeReportStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeReportStatusCodeLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeReportStatusCodeLib_cleanall">

+      <OutputDirSetup baseName="DxeReportStatusCodeLib" mbdFilename="${MODULE_DIR}/DxeReportStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/DxeReportStatusCodeLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeReportStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeReportStatusCodeLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeReportStatusCodeLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.c b/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.c
new file mode 100644
index 0000000..f130b20
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.c
@@ -0,0 +1,36 @@
+/** @file

+  DXE Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  DxeServicesTableLib.c

+

+**/

+

+

+

+EFI_DXE_SERVICES  *gDS      = NULL;

+

+/**

+**/

+EFI_STATUS

+DxeServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (gDS != NULL);

+

+  return Status;

+}

diff --git a/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.mbd b/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.mbd
new file mode 100644
index 0000000..6f818e0
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeServicesTableLib</BaseName>

+    <Guid>baa1baa3-0a8d-402c-8042-985115fae953</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-31 13:35</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.msa b/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.msa
new file mode 100644
index 0000000..fe99c31
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeServicesTableLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>baa1baa3-0a8d-402c-8042-985115fae953</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-31 13:35</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DxeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeServicesTableLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>DxeServicesTable</C_Name>

+    </GuidEntry>

+  </Guids>

+  <Externs>

+    <Extern>

+      <Constructor>DxeServicesTableLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeServicesTableLib/build.xml b/edk2/MdePkg/Library/DxeServicesTableLib/build.xml
new file mode 100644
index 0000000..d81cd22
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeServicesTableLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeServicesTableLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeServicesTableLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeServicesTableLib">

+      <GenBuild baseName="DxeServicesTableLib" mbdFilename="${MODULE_DIR}/DxeServicesTableLib.mbd" msaFilename="${MODULE_DIR}/DxeServicesTableLib.msa"/>

+   </target>

+   <target depends="DxeServicesTableLib_clean" name="clean"/>

+   <target depends="DxeServicesTableLib_cleanall" name="cleanall"/>

+   <target name="DxeServicesTableLib_clean">

+      <OutputDirSetup baseName="DxeServicesTableLib" mbdFilename="${MODULE_DIR}/DxeServicesTableLib.mbd" msaFilename="${MODULE_DIR}/DxeServicesTableLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeServicesTableLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeServicesTableLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeServicesTableLib_cleanall">

+      <OutputDirSetup baseName="DxeServicesTableLib" mbdFilename="${MODULE_DIR}/DxeServicesTableLib.mbd" msaFilename="${MODULE_DIR}/DxeServicesTableLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeServicesTableLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeServicesTableLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeServicesTableLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.c b/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.c
new file mode 100644
index 0000000..2991350
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.c
@@ -0,0 +1,102 @@
+/** @file

+Implementation of SmBusLib class library for PEI phase.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: DxeSmbusLib.c

+

+**/

+

+#include "InternalSmbusLib.h"

+

+//

+// Globle varible to cache pointer to Smbus protocol.

+//

+STATIC EFI_SMBUS_HC_PROTOCOL      *mSmbus = NULL; 

+

+/**

+  The constructor function caches the pointer to Smbus protocol.

+  

+  The constructor function locates Smbus protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmbusLibConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  

+  Status = gBS->LocateProtocol (&gEfiSmbusProtocolGuid, NULL, (VOID**) &mSmbus);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mSmbus != NULL);

+

+  return Status;

+}

+

+/**

+  Executes an SMBus operation to an SMBus controller. 

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance that it will use to

+                          execute the SMBus transactions.

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will do. The maximum number of

+                          bytes can be revision specific and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave device. Not all operations

+                          require this argument. The length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation..

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  )

+{

+  RETURN_STATUS             ReturnStatus;

+  EFI_SMBUS_DEVICE_ADDRESS  SmbusDeviceAddress;

+

+  SmbusDeviceAddress.SmbusDeviceAddress = SMBUS_LIB_SLAVE_ADDRESS (SmBusAddress);

+

+  ReturnStatus = mSmbus->Execute (

+                           mSmbus,

+                           SmbusDeviceAddress,

+                           SMBUS_LIB_COMMAND (SmBusAddress),

+                           SmbusOperation,

+                           SMBUS_LIB_PEC (SmBusAddress),  

+                           &Length,

+                           Buffer

+                           );

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+

+  return Length;

+}

diff --git a/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.mbd b/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.mbd
new file mode 100644
index 0000000..6522eac
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeSmbusLib</BaseName>

+    <Guid>91B68627-0B5D-4d32-8F1C-16CD242A8C2A</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-17 22:31</Created>

+    <Modified>2006-04-17 23:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.msa b/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.msa
new file mode 100644
index 0000000..0fbf88c
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.msa
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeSmbusLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>07720769-A7D0-4a8d-BE41-71CC18EB3338</Guid>

+    <Version>0</Version>

+    <Abstract>SmBus Library Instance implemented with SmBus Protocol.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-17 22:31</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">SmbusLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DxeSmbusLib.c</Filename>

+    <Filename>SmbusLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">Smbus</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>SmbusLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeSmbusLib/InternalSmbusLib.h b/edk2/MdePkg/Library/DxeSmbusLib/InternalSmbusLib.h
new file mode 100644
index 0000000..bd6d57f
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmbusLib/InternalSmbusLib.h
@@ -0,0 +1,60 @@
+/** @file

+Internal header file for Smbus library.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: SmbusLib.c

+

+**/

+

+#ifndef __INTERNAL_SMBUS_LIB_H

+#define __INTERNAL_SMBUS_LIB_H

+

+#define SMBUS_LIB_SLAVE_ADDRESS(SmBusAddress)      (((SmBusAddress) >> 1)  & 0x7f)

+#define SMBUS_LIB_COMMAND(SmBusAddress)            (((SmBusAddress) >> 8)  & 0xff)

+#define SMBUS_LIB_LENGTH(SmBusAddress)             (((SmBusAddress) >> 16) & 0x1f)

+#define SMBUS_LIB_PEC(SmBusAddress)     ((BOOLEAN) (((SmBusAddress) & SMBUS_LIB_PEC_BIT) != 0))

+#define SMBUS_LIB_RESEARVED(SmBusAddress)          ((SmBusAddress) & ~(((1 << 21) - 2) | SMBUS_LIB_PEC_BIT))

+

+//

+// Declaration for internal functions

+//

+/**

+  Executes an SMBus operation to an SMBus controller. 

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance that it will use to

+                          execute the SMBus transactions.

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will do. The maximum number of

+                          bytes can be revision specific and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave device. Not all operations

+                          require this argument. The length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation.

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/DxeSmbusLib/SmbusLib.c b/edk2/MdePkg/Library/DxeSmbusLib/SmbusLib.c
new file mode 100644
index 0000000..e71f11b
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmbusLib/SmbusLib.c
@@ -0,0 +1,466 @@
+/** @file

+Implementation of SmBusLib class library for PEI phase.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: SmbusLib.c

+

+**/

+

+#include "InternalSmbusLib.h"

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickRead, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickWrite, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)  == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte, Status);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to send.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Byte   = Value;

+  InternalSmBusExec (EfiSmbusSendByte, SmBusAddress, 1, &Byte, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, 1, &Byte, Status);

+  

+  return Byte;

+}

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Byte = Value;

+  InternalSmBusExec (EfiSmbusWriteByte, SmBusAddress, 1, &Byte, Status);

+  

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);

+  

+  return Word;

+}

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Word = Value;

+  InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);

+  

+  return Value;

+}

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN  Length;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Length = SMBUS_LIB_LENGTH (SmBusAddress) + 1;

+  return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from OutBuffer.  Bytes are then read from the SMBUS into InBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure InBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If OutBuffer is NULL, then ASSERT().

+  If InBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.

+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *OutBuffer,

+  OUT VOID           *InBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN   Length;

+

+  ASSERT (InBuffer  != NULL);

+  ASSERT (OutBuffer != NULL);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Length   = SMBUS_LIB_LENGTH (SmBusAddress) + 1;

+  //

+  // Assuming that InBuffer is large enough to save another memory copy.

+  //

+  InBuffer = CopyMem (InBuffer, OutBuffer, Length);

+  return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, InBuffer, Status);

+}

diff --git a/edk2/MdePkg/Library/DxeSmbusLib/build.xml b/edk2/MdePkg/Library/DxeSmbusLib/build.xml
new file mode 100644
index 0000000..7cf1273
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmbusLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeSmbusLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeSmbusLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeSmbusLib">

+      <GenBuild baseName="DxeSmbusLib" mbdFilename="${MODULE_DIR}/DxeSmbusLib.mbd" msaFilename="${MODULE_DIR}/DxeSmbusLib.msa"/>

+   </target>

+   <target depends="DxeSmbusLib_clean" name="clean"/>

+   <target depends="DxeSmbusLib_cleanall" name="cleanall"/>

+   <target name="DxeSmbusLib_clean">

+      <OutputDirSetup baseName="DxeSmbusLib" mbdFilename="${MODULE_DIR}/DxeSmbusLib.mbd" msaFilename="${MODULE_DIR}/DxeSmbusLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeSmbusLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeSmbusLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeSmbusLib_cleanall">

+      <OutputDirSetup baseName="DxeSmbusLib" mbdFilename="${MODULE_DIR}/DxeSmbusLib.mbd" msaFilename="${MODULE_DIR}/DxeSmbusLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeSmbusLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeSmbusLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeSmbusLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c
new file mode 100644
index 0000000..3439d6d
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c
@@ -0,0 +1,274 @@
+/** @file

+  Entry point to a EFI/DXE driver.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.

+

+**/

+

+EFI_BOOT_SERVICES  *mBS;

+

+/**

+  This function returns the size, in bytes, 

+  of the device path data structure specified by DevicePath.

+  If DevicePath is NULL, then 0 is returned.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @return The size of a device path in bytes.

+

+**/

+STATIC

+UINTN

+EFIAPI

+SmmGetDevicePathSize (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;

+

+  if (DevicePath == NULL) {

+    return 0;

+  }

+

+  //

+  // Search for the end of the device path structure

+  //

+  Start = DevicePath;

+  while (!EfiIsDevicePathEnd (DevicePath)) {

+    DevicePath = EfiNextDevicePathNode (DevicePath);

+  }

+

+  //

+  // Compute the size and add back in the size of the end device path structure

+  //

+  return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);

+}

+

+/**

+  This function appends the device path SecondDevicePath

+  to every device path instance in FirstDevicePath. 

+

+  @param  FirstDevicePath A pointer to a device path data structure.

+  

+  @param  SecondDevicePath A pointer to a device path data structure.

+

+  @return A pointer to the new device path is returned.

+          NULL is returned if space for the new device path could not be allocated from pool.

+          It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath

+          if they are no longer needed.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+SmmAppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath

+  )

+{

+  EFI_STATUS                Status;

+  UINTN                     Size;

+  UINTN                     Size1;

+  UINTN                     Size2;

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath2;

+

+  ASSERT (FirstDevicePath != NULL && SecondDevicePath != NULL);

+

+  //

+  // Allocate space for the combined device path. It only has one end node of

+  // length EFI_DEVICE_PATH_PROTOCOL

+  //

+  Size1         = SmmGetDevicePathSize (FirstDevicePath);

+  Size2         = SmmGetDevicePathSize (SecondDevicePath);

+  Size          = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);

+

+  Status = mBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &NewDevicePath);

+

+  if (EFI_SUCCESS == Status) {

+    mBS->CopyMem ((VOID *) NewDevicePath, (VOID *) FirstDevicePath, Size1);

+    //

+    // Over write Src1 EndNode and do the copy

+    //

+    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));

+    mBS->CopyMem ((VOID *) DevicePath2, (VOID *) SecondDevicePath, Size2);

+  }

+

+  return NewDevicePath;

+}

+

+/**

+  Unload function that is registered in the LoadImage protocol.  It un-installs

+  protocols produced and deallocates pool used by the driver.  Called by the core

+  when unloading the driver.

+

+  @param  ImageHandle   ImageHandle of the unloaded driver

+

+  @return Status of the ProcessModuleUnloadList.

+

+**/

+EFI_STATUS

+EFIAPI

+_DriverUnloadHandler (

+  EFI_HANDLE ImageHandle

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Call the unload handlers for all the modules

+  //

+  Status = ProcessModuleUnloadList (ImageHandle);

+

+  //

+  // If the driver specific unload handler does not return an error, then call all of the

+  // library destructors.  If the unload handler returned an error, then the driver can not be

+  // unloaded, and the library destructors should not be called

+  //

+  if (!EFI_ERROR (Status)) {

+    ProcessLibraryDestructorList (ImageHandle, gST);

+  }

+

+  //

+  // Return the status from the driver specific unload handler

+  //

+  return Status;

+}

+

+/**

+  Enrty point to DXE SMM Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                 Status;

+  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;

+  EFI_SMM_BASE_PROTOCOL      *SmmBase;

+  BOOLEAN                    InSmm;

+  EFI_DEVICE_PATH_PROTOCOL   *CompleteFilePath;

+  EFI_DEVICE_PATH_PROTOCOL   *ImageDevicePath;

+  EFI_HANDLE                 Handle;

+

+  //

+  // Cache a pointer to the Boot Services Table 

+  //

+  mBS = SystemTable->BootServices;

+

+  //

+  // Retrieve the Loaded Image Protocol

+  //

+  Status = mBS->HandleProtocol (

+                  ImageHandle, 

+                  &gEfiLoadedImageProtocolGuid,

+                  (VOID*)&LoadedImage

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Retrieve SMM Base Protocol

+  //

+  Status = mBS->LocateProtocol (

+                  &gEfiSmmBaseProtocolGuid, 

+                  NULL, 

+                  (VOID **) &SmmBase

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Check to see if we are already in SMM

+  //

+  SmmBase->InSmm (SmmBase, &InSmm);

+

+  //

+  //

+  //

+  if (!InSmm) {

+    //

+    // Retrieve the Device Path Protocol from the DeviceHandle tha this driver was loaded from

+    //

+    Status = mBS->HandleProtocol (

+                    LoadedImage->DeviceHandle, 

+                    &gEfiDevicePathProtocolGuid,

+                    (VOID*)&ImageDevicePath

+                    );

+    ASSERT_EFI_ERROR (Status);

+

+    //

+    // Build the full device path to the currently execuing image

+    //

+    CompleteFilePath = SmmAppendDevicePath (ImageDevicePath, LoadedImage->FilePath);

+

+    //

+    // Load the image in memory to SMRAM; it will automatically generate the

+    // SMI.

+    //

+    Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE);

+    ASSERT_EFI_ERROR (Status);

+    return Status;

+  }

+

+  //

+  // Call constructor for all libraries

+  //

+  ProcessLibraryConstructorList (ImageHandle, SystemTable);

+

+  //

+  // Optionally install the unload handler

+  //

+  if (_gDriverUnloadImageCount > 0) {

+    Status = mBS->HandleProtocol (

+                    ImageHandle,

+                    &gEfiLoadedImageProtocolGuid,

+                    (VOID **)&LoadedImage

+                    );

+    ASSERT_EFI_ERROR (Status);

+    LoadedImage->Unload = _DriverUnloadHandler;

+  }

+

+  //

+  // Call the list of driver entry points

+  //

+  Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);

+  if (EFI_ERROR (Status)) {

+    ProcessLibraryDestructorList (ImageHandle, SystemTable);

+  }

+

+  return Status;

+}

+

+/**

+  Enrty point wrapper of DXE SMM Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return _ModuleEntryPoint (ImageHandle, SystemTable);

+}

diff --git a/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.mbd b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.mbd
new file mode 100644
index 0000000..b9d9ed2
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>DxeSmmDriverEntryPoint</BaseName>

+    <Guid>79C5C7B7-1083-42a6-AD15-2A4E7C4274D7</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-27 17:32</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.msa b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.msa
new file mode 100644
index 0000000..da25eb3
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.msa
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>DxeSmmDriverEntryPoint</BaseName>

+    <ModuleType>DXE_SMM_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>79C5C7B7-1083-42a6-AD15-2A4E7C4274D7</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Component description file for the entry point to a EFI/DXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-27 17:32</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DxeSmmDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DriverEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">SmmBase</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+  </Protocols>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/build.xml b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/build.xml
new file mode 100644
index 0000000..39a7ca4
--- /dev/null
+++ b/edk2/MdePkg/Library/DxeSmmDriverEntryPoint/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="DxeSmmDriverEntryPoint"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/DxeSmmDriverEntryPoint"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="DxeSmmDriverEntryPoint">

+      <GenBuild baseName="DxeSmmDriverEntryPoint" mbdFilename="${MODULE_DIR}/DxeSmmDriverEntryPoint.mbd" msaFilename="${MODULE_DIR}/DxeSmmDriverEntryPoint.msa"/>

+   </target>

+   <target depends="DxeSmmDriverEntryPoint_clean" name="clean"/>

+   <target depends="DxeSmmDriverEntryPoint_cleanall" name="cleanall"/>

+   <target name="DxeSmmDriverEntryPoint_clean">

+      <OutputDirSetup baseName="DxeSmmDriverEntryPoint" mbdFilename="${MODULE_DIR}/DxeSmmDriverEntryPoint.mbd" msaFilename="${MODULE_DIR}/DxeSmmDriverEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeSmmDriverEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeSmmDriverEntryPoint_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="DxeSmmDriverEntryPoint_cleanall">

+      <OutputDirSetup baseName="DxeSmmDriverEntryPoint" mbdFilename="${MODULE_DIR}/DxeSmmDriverEntryPoint.mbd" msaFilename="${MODULE_DIR}/DxeSmmDriverEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/DxeSmmDriverEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/DxeSmmDriverEntryPoint_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**DxeSmmDriverEntryPoint*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/HiiLib/HiiLib.c b/edk2/MdePkg/Library/HiiLib/HiiLib.c
new file mode 100644
index 0000000..d7fad9f
--- /dev/null
+++ b/edk2/MdePkg/Library/HiiLib/HiiLib.c
@@ -0,0 +1,62 @@
+/** @file

+  HII Library implementation that uses DXE protocols and services.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  HiiLib.c

+

+**/

+

+/**

+  This function allocates pool for an EFI_HII_PACKAGES structure

+  with enough space for the variable argument list of package pointers.

+  The allocated structure is initialized using NumberOfPackages, Guid, 

+  and the variable length argument list of package pointers.

+

+  @param  NumberOfPackages The number of HII packages to prepare.

+  @param  Guid Package GUID.

+

+  @return The allocated and initialized packages.

+

+**/

+EFI_HII_PACKAGES *

+EFIAPI

+PreparePackages (

+  IN UINTN           NumberOfPackages,

+  IN CONST EFI_GUID  *Guid OPTIONAL,

+  ...

+  )

+{

+  VA_LIST           Args;

+  EFI_HII_PACKAGES  *HiiPackages;

+  VOID              **Package;

+  UINTN             Index;

+

+  ASSERT (NumberOfPackages > 0);

+

+  HiiPackages                   = AllocateZeroPool (sizeof (EFI_HII_PACKAGES) + NumberOfPackages * sizeof (VOID *));

+  ASSERT (HiiPackages != NULL);

+

+  HiiPackages->GuidId           = (EFI_GUID *) Guid;

+  HiiPackages->NumberOfPackages = NumberOfPackages;

+  Package                       = (VOID **) (((UINT8 *) HiiPackages) + sizeof (EFI_HII_PACKAGES));

+

+  VA_START (Args, Guid);

+

+  for (Index = 0; Index < NumberOfPackages; Index++) {

+    *Package = VA_ARG (Args, VOID *);

+    Package++;

+  }

+

+  VA_END (Args);

+

+  return HiiPackages;

+

+}

diff --git a/edk2/MdePkg/Library/HiiLib/HiiLib.mbd b/edk2/MdePkg/Library/HiiLib/HiiLib.mbd
new file mode 100644
index 0000000..4a681fb
--- /dev/null
+++ b/edk2/MdePkg/Library/HiiLib/HiiLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>HiiLib</BaseName>

+    <Guid>1e2c4c2e-67e6-4e57-b3ae-cf5a5af72c2c</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 09:00</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/HiiLib/HiiLib.msa b/edk2/MdePkg/Library/HiiLib/HiiLib.msa
new file mode 100644
index 0000000..4b188b6
--- /dev/null
+++ b/edk2/MdePkg/Library/HiiLib/HiiLib.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>HiiLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>1e2c4c2e-67e6-4e57-b3ae-cf5a5af72c2c</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 09:00</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">HiiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>HiiLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/HiiLib/build.xml b/edk2/MdePkg/Library/HiiLib/build.xml
new file mode 100644
index 0000000..2299e53
--- /dev/null
+++ b/edk2/MdePkg/Library/HiiLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="HiiLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/HiiLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="HiiLib">

+      <GenBuild baseName="HiiLib" mbdFilename="${MODULE_DIR}/HiiLib.mbd" msaFilename="${MODULE_DIR}/HiiLib.msa"/>

+   </target>

+   <target depends="HiiLib_clean" name="clean"/>

+   <target depends="HiiLib_cleanall" name="cleanall"/>

+   <target name="HiiLib_clean">

+      <OutputDirSetup baseName="HiiLib" mbdFilename="${MODULE_DIR}/HiiLib.mbd" msaFilename="${MODULE_DIR}/HiiLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/HiiLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/HiiLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="HiiLib_cleanall">

+      <OutputDirSetup baseName="HiiLib" mbdFilename="${MODULE_DIR}/HiiLib.mbd" msaFilename="${MODULE_DIR}/HiiLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/HiiLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/HiiLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**HiiLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c b/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c
new file mode 100644
index 0000000..d44725a
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c
@@ -0,0 +1,51 @@
+/** @file

+  Entry point to a the PEI Core.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.

+

+**/

+

+/**

+  Enrty point to PEI core.

+

+  @param  PeiStartupDescriptor Pointer of start up information.

+ 

+  @return Status returned by entry points of core and drivers. 

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor

+  )

+{

+  //

+  // Call the PEI Core entry point

+  //

+  return ProcessModuleEntryPointList (PeiStartupDescriptor, NULL);

+}

+

+

+/**

+  Wrapper of enrty point to PEI core.

+

+  @param  PeiStartupDescriptor Pointer of start up information.

+ 

+  @return Status returned by entry points of core and drivers. 

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor

+  )

+{

+  return _ModuleEntryPoint (PeiStartupDescriptor);

+}

diff --git a/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.mbd b/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.mbd
new file mode 100644
index 0000000..8739972
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiCoreEntryPoint</BaseName>

+    <Guid>b3b0654a-969d-4096-86cb-27e262a02083</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.msa b/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.msa
new file mode 100644
index 0000000..a76c2ec
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.msa
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiCoreEntryPoint</BaseName>

+    <ModuleType>PEI_CORE</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>b3b0654a-969d-4096-86cb-27e262a02083</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to the PEI Core</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeiCoreEntryPoint</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiCoreEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiCoreEntryPoint/build.xml b/edk2/MdePkg/Library/PeiCoreEntryPoint/build.xml
new file mode 100644
index 0000000..738c43b
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreEntryPoint/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiCoreEntryPoint"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiCoreEntryPoint"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiCoreEntryPoint">

+      <GenBuild baseName="PeiCoreEntryPoint" mbdFilename="${MODULE_DIR}/PeiCoreEntryPoint.mbd" msaFilename="${MODULE_DIR}/PeiCoreEntryPoint.msa"/>

+   </target>

+   <target depends="PeiCoreEntryPoint_clean" name="clean"/>

+   <target depends="PeiCoreEntryPoint_cleanall" name="cleanall"/>

+   <target name="PeiCoreEntryPoint_clean">

+      <OutputDirSetup baseName="PeiCoreEntryPoint" mbdFilename="${MODULE_DIR}/PeiCoreEntryPoint.mbd" msaFilename="${MODULE_DIR}/PeiCoreEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiCoreEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiCoreEntryPoint_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiCoreEntryPoint_cleanall">

+      <OutputDirSetup baseName="PeiCoreEntryPoint" mbdFilename="${MODULE_DIR}/PeiCoreEntryPoint.mbd" msaFilename="${MODULE_DIR}/PeiCoreEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiCoreEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiCoreEntryPoint_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiCoreEntryPoint*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.c b/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.c
new file mode 100644
index 0000000..70c4d64
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.c
@@ -0,0 +1,376 @@
+/** @file

+  PEI Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  PeiCoreLib.c

+

+**/

+

+/**

+  This service enables a given PEIM to register an interface into the PEI Foundation. 

+

+  @param  PpiList A pointer to the list of interfaces that the caller shall install.

+

+  @retval  EFI_SUCCESS The interface was successfully installed.

+  @retval  EFI_INVALID_PARAMETER The PpiList pointer is NULL.

+  @retval  EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have

+  the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field.

+  @retval  EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreInstallPpi (

+  IN EFI_PEI_PPI_DESCRIPTOR           *PpiList

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->InstallPpi (PeiServices, PpiList);

+}

+

+/**

+  This service enables PEIMs to replace an entry in the PPI database with an alternate entry.

+

+  @param  OldPpi Pointer to the old PEI PPI Descriptors.

+  @param  NewPpi Pointer to the new PEI PPI Descriptors.

+

+  @retval  EFI_SUCCESS The interface was successfully installed.

+  @retval  EFI_INVALID_PARAMETER The OldPpi or NewPpi is NULL.

+  @retval  EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have

+  the EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field.

+  @retval  EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.

+  @retval  EFI_NOT_FOUND The PPI for which the reinstallation was requested has not been installed.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreReinstallPpi (

+  IN EFI_PEI_PPI_DESCRIPTOR           *OldPpi,

+  IN EFI_PEI_PPI_DESCRIPTOR           *NewPpi

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->ReInstallPpi (PeiServices, OldPpi, NewPpi);

+}

+

+/**

+  This service enables PEIMs to discover a given instance of an interface.

+

+  @param  Guid A pointer to the GUID whose corresponding interface needs to be found.

+  @param  Instance The N-th instance of the interface that is required.

+  @param  PpiDescriptor A pointer to instance of the EFI_PEI_PPI_DESCRIPTOR.

+  @param  Ppi A pointer to the instance of the interface.

+

+  @retval  EFI_SUCCESS The interface was successfully returned.

+  @retval  EFI_NOT_FOUND The PPI descriptor is not found in the database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreLocatePpi (

+  IN EFI_GUID                         *Guid,

+  IN UINTN                            Instance,

+  IN OUT EFI_PEI_PPI_DESCRIPTOR       **PpiDescriptor,

+  IN OUT VOID                         **Ppi

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->LocatePpi (PeiServices, Guid, Instance, PpiDescriptor, Ppi);

+}

+

+/**

+  This service enables PEIMs to register a given service to be invoked

+  when another service is installed or reinstalled.

+

+  @param  NotifyList A pointer to the list of notification interfaces that the caller shall install.

+

+  @retval  EFI_SUCCESS The interface was successfully installed.

+  @retval  EFI_INVALID_PARAMETER The NotifyList pointer is NULL.

+  @retval  EFI_INVALID_PARAMETER Any of the PEI notify descriptors in the list do not have

+  the EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES bit set in the Flags field.

+  @retval  EFI_OUT_OF_RESOURCES There is no additional space in the PPI database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreNotifyPpi (

+  IN EFI_PEI_NOTIFY_DESCRIPTOR        *NotifyList

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->NotifyPpi (PeiServices, NotifyList);

+}

+

+/**

+  This service enables PEIMs to ascertain the present value of the boot mode.  

+

+  @param  BootMode A pointer to contain the value of the boot mode.

+

+  @retval  EFI_SUCCESS The boot mode was returned successfully.

+  @retval  EFI_INVALID_PARAMETER BootMode is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreGetBootMode (

+  IN OUT EFI_BOOT_MODE                *BootMode

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->GetBootMode (PeiServices, BootMode);

+}

+

+/**

+  This service enables PEIMs to update the boot mode variable.    

+

+  @param  BootMode The value of the boot mode to set.

+

+  @retval  EFI_SUCCESS The value was successfully updated

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreSetBootMode (

+  IN EFI_BOOT_MODE                    BootMode

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->SetBootMode (PeiServices, BootMode);

+}

+

+/**

+  This service enables a PEIM to ascertain the address of the list of HOBs in memory.

+

+  @param  HobList A pointer to the list of HOBs that the PEI Foundation will initialize.

+

+  @retval  EFI_SUCCESS The list was successfully returned.

+  @retval  EFI_NOT_AVAILABLE_YET The HOB list is not yet published.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreGetHobList (

+  IN OUT VOID                         **HobList

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->GetHobList (PeiServices, HobList);

+}

+

+/**

+  This service enables PEIMs to create various types of HOBs.

+

+  @param  Type The type of HOB to be installed.

+  @param  Length The length of the HOB to be added.

+  @param  Hob The address of a pointer that will contain the HOB header.

+

+  @retval  EFI_SUCCESS The HOB was successfully created.

+  @retval  EFI_OUT_OF_RESOURCES There is no additional space for HOB creation.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreCreateHob (

+  IN UINT16                           Type,

+  IN UINT16                           Length,

+  IN OUT VOID                         **Hob

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->CreateHob (PeiServices, Type, Length, Hob);

+}

+

+/**

+  This service enables PEIMs to discover additional firmware volumes.

+

+  @param  Instance This instance of the firmware volume to find.

+  The value 0 is the Boot Firmware Volume (BFV).

+  @param  FwVolHeader Pointer to the firmware volume header of the volume to return.

+

+  @retval  EFI_SUCCESS The volume was found.

+  @retval  EFI_NOT_FOUND The volume was not found.

+  @retval  EFI_INVALID_PARAMETER FwVolHeader is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreFfsFindNextVolume (

+  IN UINTN                            Instance,

+  IN OUT EFI_FIRMWARE_VOLUME_HEADER   **FwVolHeader

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FfsFindNextVolume (PeiServices, Instance, FwVolHeader);

+}

+

+/**

+  This service enables PEIMs to discover additional firmware files.

+

+  @param  SearchType A filter to find files only of this type.

+  @param  FwVolHeader Pointer to the firmware volume header of the volume to search.

+  This parameter must point to a valid FFS volume.

+  @param  FileHeader Pointer to the current file from which to begin searching.

+

+  @retval  EFI_SUCCESS The file was found.

+  @retval  EFI_NOT_FOUND The file was not found.

+  @retval  EFI_NOT_FOUND The header checksum was not zero.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreFfsFindNextFile (

+  IN EFI_FV_FILETYPE                  SearchType,

+  IN EFI_FIRMWARE_VOLUME_HEADER       *FwVolHeader,

+  IN OUT EFI_FFS_FILE_HEADER          **FileHeader

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FfsFindNextFile (PeiServices, SearchType, FwVolHeader, FileHeader);

+}

+

+/**

+  This service enables PEIMs to discover sections of a given type within a valid FFS file.

+

+  @param  SearchType The value of the section type to find.

+  @param  FfsFileHeader A pointer to the file header that contains the set of sections to be searched.

+  @param  SectionData A pointer to the discovered section, if successful.

+

+  @retval  EFI_SUCCESS The section was found.

+  @retval  EFI_NOT_FOUND The section was not found.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreFfsFindSectionData (

+  IN EFI_SECTION_TYPE                 SectionType,

+  IN EFI_FFS_FILE_HEADER              *FfsFileHeader,

+  IN OUT VOID                         **SectionData

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FfsFindSectionData (PeiServices, SectionType, FfsFileHeader, SectionData);

+}

+

+/**

+  This service enables PEIMs to register the permanent memory configuration

+  that has been initialized with the PEI Foundation.

+

+  @param  MemoryBegin The value of a region of installed memory.

+  @param  MemoryLength The corresponding length of a region of installed memory.

+

+  @retval  EFI_SUCCESS The region was successfully installed in a HOB.

+  @retval  EFI_INVALID_PARAMETER MemoryBegin and MemoryLength are illegal for this system.

+  @retval  EFI_OUT_OF_RESOURCES There is no additional space for HOB creation.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreInstallPeiMemory (

+  IN EFI_PHYSICAL_ADDRESS             MemoryBegin,

+  IN UINT64                           MemoryLength

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->InstallPeiMemory (PeiServices, MemoryBegin, MemoryLength);

+}

+

+/**

+  This service enables PEIMs to allocate memory after the permanent memory has been installed by a PEIM.

+

+  @param  MemoryType Type of memory to allocate.

+  @param  Pages Number of pages to allocate.

+  @param  Memory Pointer of memory allocated.

+

+  @retval  EFI_SUCCESS The memory range was successfully allocated.

+  @retval  EFI_INVALID_PARAMETER Type is not equal to AllocateAnyPages.

+  @retval  EFI_NOT_AVAILABLE_YET Called with permanent memory not available.

+  @retval  EFI_OUT_OF_RESOURCES The pages could not be allocated.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreAllocatePages (

+  IN EFI_MEMORY_TYPE                  MemoryType,

+  IN UINTN                            Pages,

+  IN OUT EFI_PHYSICAL_ADDRESS         *Memory

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->AllocatePages (PeiServices, MemoryType, Pages, Memory);

+}

+

+/**

+  This service allocates memory from the Hand-Off Block (HOB) heap.

+

+  @param  Size The number of bytes to allocate from the pool.

+  @param  Buffer If the call succeeds, a pointer to a pointer to the allocated buffer;

+  undefined otherwise.

+

+  @retval  EFI_SUCCESS The allocation was successful

+  @retval  EFI_OUT_OF_RESOURCES There is not enough heap to allocate the requested size.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreAllocatePool (

+  IN UINTN                            Size,

+  OUT VOID                            **Buffer

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->AllocatePool (PeiServices, Size, Buffer);

+}

+

+/**

+  This service resets the entire platform, including all processors and devices, and reboots the system. 

+

+  @retval  EFI_NOT_AVAILABLE_YET The service has not been installed yet.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiCoreResetSystem (

+  VOID

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->PeiResetSystem (PeiServices);

+}

diff --git a/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.mbd b/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.mbd
new file mode 100644
index 0000000..441a418
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiCoreLib</BaseName>

+    <Guid>a804239b-4155-446f-acc8-f0825d74908c</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.msa b/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.msa
new file mode 100644
index 0000000..19cb7d1
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreLib/PeiCoreLib.msa
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiCoreLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>a804239b-4155-446f-acc8-f0825d74908c</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiCoreLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiCoreLib/build.xml b/edk2/MdePkg/Library/PeiCoreLib/build.xml
new file mode 100644
index 0000000..063f689
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiCoreLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiCoreLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiCoreLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiCoreLib">

+      <GenBuild baseName="PeiCoreLib" mbdFilename="${MODULE_DIR}/PeiCoreLib.mbd" msaFilename="${MODULE_DIR}/PeiCoreLib.msa"/>

+   </target>

+   <target depends="PeiCoreLib_clean" name="clean"/>

+   <target depends="PeiCoreLib_cleanall" name="cleanall"/>

+   <target name="PeiCoreLib_clean">

+      <OutputDirSetup baseName="PeiCoreLib" mbdFilename="${MODULE_DIR}/PeiCoreLib.mbd" msaFilename="${MODULE_DIR}/PeiCoreLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiCoreLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiCoreLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiCoreLib_cleanall">

+      <OutputDirSetup baseName="PeiCoreLib" mbdFilename="${MODULE_DIR}/PeiCoreLib.mbd" msaFilename="${MODULE_DIR}/PeiCoreLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiCoreLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiCoreLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiCoreLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiHobLib/HobLib.c b/edk2/MdePkg/Library/PeiHobLib/HobLib.c
new file mode 100644
index 0000000..380a735
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiHobLib/HobLib.c
@@ -0,0 +1,510 @@
+/** @file

+  HOB Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  HobLib.c

+

+**/

+

+

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+{

+  EFI_STATUS            Status;

+  VOID                  *HobList;

+

+  Status = PeiCoreGetHobList (&HobList);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (HobList != NULL);

+

+  return HobList;

+}

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  ASSERT (HobStart != NULL);

+   

+  Hob.Raw = (UINT8 *) HobStart;

+  //

+  // Parse the HOB list until end of list or matching type is found.

+  //

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == Type) {

+      return Hob.Raw;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return NULL;

+}

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextHob (Type, HobList);

+}

+

+/**

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  GuidHob;

+

+  GuidHob.Raw = (UINT8 *) HobStart;

+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {

+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+  return GuidHob.Raw;

+}

+

+/**

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size info respectively.

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextGuidHob (Guid, HobList);

+}

+

+/**

+  Adds a new HOB to the HOB List.

+

+  This internal function enables PEIMs to create various types of HOBs.

+

+  @param  Type          Type of the new HOB.

+  @param  Length        Length of the new HOB to allocate.

+

+  @return The address of new HOB.

+

+**/

+VOID *

+InternalPeiCreateHob (

+  IN UINT16                      Type,

+  IN UINT16                      Length

+  )

+{

+  EFI_STATUS        Status;

+  VOID              *Hob;

+

+  Status = PeiCoreCreateHob (Type, Length, &Hob);

+  //

+  // Assume the process of HOB building is always successful.

+  //

+  ASSERT_EFI_ERROR (Status);

+  return Hob;

+}

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the moduleÂ’s entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));

+

+  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);

+  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;

+  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;

+  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;

+

+  CopyGuid (&Hob->ModuleName, ModuleName);

+  Hob->EntryPoint = EntryPoint;

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+{

+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));

+

+  Hob->ResourceType      = ResourceType;

+  Hob->ResourceAttribute = ResourceAttribute;

+  Hob->PhysicalStart     = PhysicalStart;

+  Hob->ResourceLength    = NumberOfBytes;

+}

+

+/**

+  Builds a GUID HOB with a certain data length.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+{

+  EFI_HOB_GUID_TYPE *Hob;

+

+  //

+  // Make sure that data length is not too long.

+  //

+  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));

+  CopyGuid (&Hob->Name, Guid);

+  return Hob + 1;

+}

+

+/**

+  Copies a data buffer to a newly-built HOB.

+

+  This function builds a customized HOB tagged with a GUID for identification,

+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @return The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+{

+  VOID  *HobData;

+

+  HobData = BuildGuidHob (Guid, DataLength);

+

+  return CopyMem (HobData, Data, DataLength);

+}

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  EFI_HOB_FIRMWARE_VOLUME  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));

+

+  Hob->BaseAddress = BaseAddress;

+  Hob->Length      = Length;

+}

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  EFI_HOB_CAPSULE_VOLUME  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CV, sizeof (EFI_HOB_CAPSULE_VOLUME));

+

+  Hob->BaseAddress  = BaseAddress;

+  Hob->Length       = Length;

+}

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+{

+  EFI_HOB_CPU  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));

+

+  Hob->SizeOfMemorySpace = SizeOfMemorySpace;

+  Hob->SizeOfIoSpace     = SizeOfIoSpace;

+}

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));

+

+  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);

+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;

+  Hob->AllocDescriptor.MemoryLength      = Length;

+  Hob->AllocDescriptor.MemoryType        = EfiConventionalMemory;

+}

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION_BSP_STORE  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_BSP_STORE));

+

+  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocBspStoreGuid);

+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;

+  Hob->AllocDescriptor.MemoryLength      = Length;

+  Hob->AllocDescriptor.MemoryType        = MemoryType;

+}

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));

+

+  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));

+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;

+  Hob->AllocDescriptor.MemoryLength      = Length;

+  Hob->AllocDescriptor.MemoryType        = MemoryType;

+}

diff --git a/edk2/MdePkg/Library/PeiHobLib/PeiHobLib.mbd b/edk2/MdePkg/Library/PeiHobLib/PeiHobLib.mbd
new file mode 100644
index 0000000..2d2f34a
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiHobLib/PeiHobLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiHobLib</BaseName>

+    <Guid>9643128f-ac24-4b3e-b6be-d8849a306153</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiHobLib/PeiHobLib.msa b/edk2/MdePkg/Library/PeiHobLib/PeiHobLib.msa
new file mode 100644
index 0000000..1d8fb79
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiHobLib/PeiHobLib.msa
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiHobLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>9643128f-ac24-4b3e-b6be-d8849a306153</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">HobLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>HobLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>HobMemoryAllocModule</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>HobMemoryAllocBspStore</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>HobMemoryAllocStack</C_Name>

+    </GuidEntry>

+  </Guids>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiHobLib/build.xml b/edk2/MdePkg/Library/PeiHobLib/build.xml
new file mode 100644
index 0000000..7374180
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiHobLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiHobLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiHobLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiHobLib">

+      <GenBuild baseName="PeiHobLib" mbdFilename="${MODULE_DIR}/PeiHobLib.mbd" msaFilename="${MODULE_DIR}/PeiHobLib.msa"/>

+   </target>

+   <target depends="PeiHobLib_clean" name="clean"/>

+   <target depends="PeiHobLib_cleanall" name="cleanall"/>

+   <target name="PeiHobLib_clean">

+      <OutputDirSetup baseName="PeiHobLib" mbdFilename="${MODULE_DIR}/PeiHobLib.mbd" msaFilename="${MODULE_DIR}/PeiHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiHobLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiHobLib_cleanall">

+      <OutputDirSetup baseName="PeiHobLib" mbdFilename="${MODULE_DIR}/PeiHobLib.mbd" msaFilename="${MODULE_DIR}/PeiHobLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiHobLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiHobLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiHobLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c b/edk2/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
new file mode 100644
index 0000000..48a7477
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
@@ -0,0 +1,2272 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoHighLevel.c

+

+  The following IoLib instances share the same version of this file:

+

+    BaseIoLibIntrinsic

+    DxeIoLibCpuIo

+    PeiIoLibCpuIo

+

+**/

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, IoRead8 (Port) | OrData);

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, IoRead8 (Port) & AndData);

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (IoRead8 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, IoRead16 (Port) | OrData);

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, IoRead16 (Port) & AndData);

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (IoRead16 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, performs a bitwise OR

+  between the result of the AND operation and the value specified by OrData,

+  and writes the result to the 64-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise inclusive OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND followed

+  by a bitwise inclusive OR between the read result and the value specified by

+  AndData, and writes the result to the 64-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Port      The I/O port to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with the read value from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, MmioRead8 (Address) | OrData);

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, MmioRead8 (Address) & AndData);

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (MmioRead8 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 7, then ASSERT().

+  If EndBit is greater than 7, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..7.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..7.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, MmioRead16 (Address) | OrData);

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, MmioRead16 (Address) & AndData);

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (MmioRead16 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 15, then ASSERT().

+  If EndBit is greater than 15, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..15.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..15.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 31, then ASSERT().

+  If EndBit is greater than 31, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..31.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..31.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise inclusive OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, performs a

+  bitwise OR between the result of the AND operation and the value specified by

+  OrData, and writes the result to the 64-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to read.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  Value     New value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  OrData    The value to OR with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise inclusive OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  followed by a bitwise inclusive OR between the read result and the value

+  specified by AndData, and writes the result to the 64-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If StartBit is greater than 63, then ASSERT().

+  If EndBit is greater than 63, then ASSERT().

+  If EndBit is less than or equal to StartBit, then ASSERT().

+

+  @param  Address   MMIO register to write.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    Range 0..63.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    Range 0..63.

+  @param  AndData   The value to AND with read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/edk2/MdePkg/Library/PeiIoLibCpuIo/IoLib.c b/edk2/MdePkg/Library/PeiIoLibCpuIo/IoLib.c
new file mode 100644
index 0000000..1da0203
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiIoLibCpuIo/IoLib.c
@@ -0,0 +1,550 @@
+/** @file

+  I/O Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  IoLib.c

+

+**/

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  return CpuIo->IoRead8 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  CpuIo->IoWrite8 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return CpuIo->IoRead16 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  CpuIo->IoWrite16 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return CpuIo->IoRead32 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  CpuIo->IoWrite32 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return CpuIo->IoRead64 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  CpuIo->IoWrite64 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;;

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  return CpuIo->MemRead8 (PeiServices, CpuIo, (UINT64) Address);

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  CpuIo->MemWrite8 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return CpuIo->MemRead16 (PeiServices, CpuIo, (UINT64) Address);

+

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  CpuIo->MemWrite16 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return CpuIo->MemRead32 (PeiServices, CpuIo, (UINT64) Address);

+

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  CpuIo->MemWrite32 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return CpuIo->MemRead64 (PeiServices, CpuIo, (UINT64) Address);

+

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  EFI_PEI_SERVICES                  **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  CpuIo->MemWrite64 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

diff --git a/edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.mbd b/edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.mbd
new file mode 100644
index 0000000..a615d24
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiIoLibCpuIo</BaseName>

+    <Guid>b2585b69-fb63-4220-844a-8fbea8bf01af</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-14 12:42</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.msa b/edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.msa
new file mode 100644
index 0000000..e3253dc
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiIoLibCpuIo</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>b2585b69-fb63-4220-844a-8fbea8bf01af</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>I/O Library implemented with Framework CPU I/O Protocol</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-14 12:42</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">IoLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>IoLib.c</Filename>

+    <Filename>IoHighLevel.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiIoLibCpuIo/build.xml b/edk2/MdePkg/Library/PeiIoLibCpuIo/build.xml
new file mode 100644
index 0000000..e8f6056
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiIoLibCpuIo/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiIoLibCpuIo"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiIoLibCpuIo"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiIoLibCpuIo">

+      <GenBuild baseName="PeiIoLibCpuIo" mbdFilename="${MODULE_DIR}/PeiIoLibCpuIo.mbd" msaFilename="${MODULE_DIR}/PeiIoLibCpuIo.msa"/>

+   </target>

+   <target depends="PeiIoLibCpuIo_clean" name="clean"/>

+   <target depends="PeiIoLibCpuIo_cleanall" name="cleanall"/>

+   <target name="PeiIoLibCpuIo_clean">

+      <OutputDirSetup baseName="PeiIoLibCpuIo" mbdFilename="${MODULE_DIR}/PeiIoLibCpuIo.mbd" msaFilename="${MODULE_DIR}/PeiIoLibCpuIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiIoLibCpuIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiIoLibCpuIo_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiIoLibCpuIo_cleanall">

+      <OutputDirSetup baseName="PeiIoLibCpuIo" mbdFilename="${MODULE_DIR}/PeiIoLibCpuIo.mbd" msaFilename="${MODULE_DIR}/PeiIoLibCpuIo.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiIoLibCpuIo_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiIoLibCpuIo_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiIoLibCpuIo*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c b/edk2/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
new file mode 100644
index 0000000..59e9a26
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
@@ -0,0 +1,904 @@
+/** @file

+  Support routines for memory allocation routines for use with drivers.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  MemoryAllocationLib.c

+

+**/

+

+

+

+/**

+  Allocates the number of 4KB pages specified by Pages of a certain memory type.

+

+  @param  MemoryType The type of memory to allocate.

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+  If Pages is 0, then NULL is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory; 

+  EFI_PEI_SERVICES      **PeiServices;

+

+  if (Pages == 0) {

+    return NULL;

+  }

+

+  PeiServices = GetPeiServicesTablePointer ();

+  Status = (*PeiServices)->AllocatePages (PeiServices, MemoryType, Pages, &Memory);

+  if (EFI_ERROR (Status)) {

+    Memory = 0;

+  }

+  return (VOID *) (UINTN) Memory;

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData.

+

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+  If Pages is 0, then NULL is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocatePages (

+  IN UINTN  Pages

+  )

+{

+  return InternalAllocatePages (EfiBootServicesData, Pages);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData. 

+

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+  If Pages is 0, then NULL is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimePages (

+  IN UINTN  Pages

+  )

+{

+  return InternalAllocatePages (EfiRuntimeServicesData, Pages);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType. 

+

+  @param  Pages The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer.  The buffer returned is aligned on a 4KB boundary.

+  If Pages is 0, then NULL is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedPages (

+  IN UINTN  Pages

+  )

+{

+  return InternalAllocatePages (EfiReservedMemoryType, Pages);

+}

+

+/**

+  Frees one or more 4KB pages that were previously allocated with 

+  one of the page allocation functions in the Memory Allocation Library.

+

+  @param  Buffer Pointer to the buffer of pages to free.

+  @param  Pages The number of 4 KB pages to free.

+

+**/

+VOID

+EFIAPI

+FreePages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  //

+  // PEI phase does not support to free pages, so leave it as NOP.

+  //

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of a certian memory type 

+  with an alignment specified by Alignment. 

+

+  @param  MemoryType The type of memory to allocate.

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  VOID    *Memory;

+  UINTN   AlignmentMask;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  if (Pages == 0) {

+    return NULL;

+  }

+  //

+  // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.

+  //

+  ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));

+  //

+  // We would rather waste some memory to save PEI code size.

+  //

+  Memory = InternalAllocatePages (MemoryType, Pages + EFI_SIZE_TO_PAGES (Alignment));

+  if (Alignment == 0) {

+    AlignmentMask = Alignment;

+  } else {

+    AlignmentMask = Alignment - 1;  

+  }

+  return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) & ~AlignmentMask);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData

+  with an alignment specified by Alignment.   

+

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);

+}

+

+/**

+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData

+  with an alignment specified by Alignment.   

+

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimePages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);

+}

+

+/**

+  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.

+

+  @param  Pages The number of 4 KB pages to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return The allocated buffer is returned.  If Pages is 0, then NULL is returned.

+  If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);

+}

+

+/**

+  Frees one or more 4KB pages that were previously allocated with 

+  one of the aligned page allocation functions in the Memory Allocation Library.

+

+  @param  Buffer Pointer to the buffer of pages to free.

+  @param  Pages The number of 4 KB pages to free.

+

+**/

+VOID

+EFIAPI

+FreeAlignedPages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  //

+  // PEI phase does not support to free pages, so leave it as NOP.

+  //

+}

+

+/**

+  Allocates a buffer of a certain memory type.

+

+  @param  MemoryType The type of memory to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            AllocationSize

+  )

+{

+  //

+  // If we need lots of small runtime/reserved memory type from PEI in the future, 

+  // we can consider providing a more complex algorithm that allocates runtime pages and 

+  // provide pool allocations from those pages. 

+  //

+  return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));

+}

+

+/**

+  Allocates a buffer of type EfiBootServicesData.

+

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocatePool (

+  IN UINTN  AllocationSize

+  )

+{

+  EFI_STATUS        Status;

+  EFI_PEI_SERVICES  **PeiServices;

+  VOID              *Buffer;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+

+  Status = (*PeiServices)->AllocatePool (PeiServices, AllocationSize, &Buffer);

+  if (EFI_ERROR (Status)) {

+    Buffer = NULL;

+  }

+  return Buffer;

+}

+

+/**

+  Allocates a buffer of type EfiRuntimeServicesData.

+

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);

+}

+

+/**

+  Allocates a buffer of type EfiReservedMemoryType.

+

+  @param  AllocationSize The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of a certian pool type.

+

+  @param  PoolType The type of memory to allocate.

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize

+  ) 

+{

+  VOID  *Memory;

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData.

+

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  VOID  *Memory;

+

+  Memory = AllocatePool (AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Allocates and zeros a buffer of type EfiRuntimeServicesData.

+

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimeZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiReservedMemoryType.

+

+  @param  AllocationSize The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Copies a buffer to an allocated buffer of a certian memory type. 

+

+  @param  MemoryType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate and zero.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  ) 

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+} 

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData. 

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = AllocatePool (AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. 

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType. 

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  Buffer Pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreePool (

+  IN VOID   *Buffer

+  )

+{

+  //

+  // PEI phase does not support to free pool, so leave it as NOP.

+  //

+}

+

+/**

+  Allocates a buffer of a certain pool type at a specified alignment.

+

+  @param  PoolType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.                            If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID    *RawAddress;

+  UINTN   AlignedAddress;

+  UINTN   AlignmentMask;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+  

+  if (Alignment == 0) {

+    AlignmentMask = Alignment;

+  } else {

+    AlignmentMask = Alignment - 1;

+  }

+  //

+  // Make sure that AllocationSize plus AlignmentMask does not overflow.

+  //

+  ASSERT (AllocationSize <= (MAX_ADDRESS - AlignmentMask));

+

+  RawAddress      = InternalAllocatePool (PoolType, AllocationSize + AlignmentMask);

+  

+  AlignedAddress  = ((UINTN) RawAddress + AlignmentMask) & ~AlignmentMask;

+    

+  return (VOID *) AlignedAddress;

+}

+

+/**

+  Allocates a buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.                            If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  VOID    *RawAddress;

+  UINTN   AlignedAddress;

+  UINTN   AlignmentMask;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  if (Alignment == 0) {

+    AlignmentMask = Alignment;

+  } else {

+    AlignmentMask = Alignment - 1;

+  }

+

+  //

+  // Make sure that AllocationSize plus AlignmentMask does not overflow.

+  //

+  ASSERT (AllocationSize <= (MAX_ADDRESS - AlignmentMask));

+

+  RawAddress      = AllocatePool (AllocationSize + AlignmentMask);

+  

+  AlignedAddress  = ((UINTN) RawAddress + AlignmentMask) & ~AlignmentMask;

+    

+  return (VOID *) AlignedAddress;

+}

+

+/**

+  Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimePool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+/**

+  Allocates a buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  PoolType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID    *Memory;

+

+  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  VOID    *Memory;

+

+  Memory = AllocateAlignedPool (AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimeZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+/**

+  Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  PoolType The type of pool to allocate.

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+InternalAllocateAlignedCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer,

+  IN UINTN            Alignment

+  )

+{

+  VOID  *Memory;

+  

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  VOID  *Memory;

+  

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = AllocateAlignedPool (AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);

+}

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.

+

+  @param  AllocationSize The number of bytes to allocate.

+  @param  Buffer The buffer to copy to the allocated buffer.

+  @param  Alignment The requested alignment of the allocation.  Must be a power of two.

+  If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.

+  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+**/

+VOID *

+EFIAPI

+AllocateAlignedReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);

+}

+

+/**

+  Frees a buffer that was previously allocated with one of the aligned pool allocation functions 

+  in the Memory Allocation Library.

+

+  @param  Buffer Pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreeAlignedPool (

+  IN VOID   *Buffer

+  )

+{

+  //

+  // PEI phase does not support to free pool, so leave it as NOP.

+  //

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.mbd b/edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.mbd
new file mode 100644
index 0000000..9499160
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiMemoryAllocationLib</BaseName>

+    <Guid>b694e0dc-cd4e-4b30-885b-9c164ed3e74a</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.msa b/edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.msa
new file mode 100644
index 0000000..2750565
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiMemoryAllocationLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>b694e0dc-cd4e-4b30-885b-9c164ed3e74a</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MemoryAllocationLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiMemoryAllocationLib/build.xml b/edk2/MdePkg/Library/PeiMemoryAllocationLib/build.xml
new file mode 100644
index 0000000..11a28fb
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryAllocationLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiMemoryAllocationLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiMemoryAllocationLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiMemoryAllocationLib">

+      <GenBuild baseName="PeiMemoryAllocationLib" mbdFilename="${MODULE_DIR}/PeiMemoryAllocationLib.mbd" msaFilename="${MODULE_DIR}/PeiMemoryAllocationLib.msa"/>

+   </target>

+   <target depends="PeiMemoryAllocationLib_clean" name="clean"/>

+   <target depends="PeiMemoryAllocationLib_cleanall" name="cleanall"/>

+   <target name="PeiMemoryAllocationLib_clean">

+      <OutputDirSetup baseName="PeiMemoryAllocationLib" mbdFilename="${MODULE_DIR}/PeiMemoryAllocationLib.mbd" msaFilename="${MODULE_DIR}/PeiMemoryAllocationLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiMemoryAllocationLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiMemoryAllocationLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiMemoryAllocationLib_cleanall">

+      <OutputDirSetup baseName="PeiMemoryAllocationLib" mbdFilename="${MODULE_DIR}/PeiMemoryAllocationLib.mbd" msaFilename="${MODULE_DIR}/PeiMemoryAllocationLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiMemoryAllocationLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiMemoryAllocationLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiMemoryAllocationLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiMemoryLib/CompareMemWrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/CompareMemWrapper.c
new file mode 100644
index 0000000..c8199d8
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/CompareMemWrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  CompareMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CompareMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)DestinationBuffer + 1);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)SourceBuffer + 1);

+  if (Length == 0) {

+    return 0;

+  }

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/CopyMemWrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/CopyMemWrapper.c
new file mode 100644
index 0000000..5ca62f5
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/CopyMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CopyMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CopyMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (

+    Destination == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Destination + 1

+    );

+  ASSERT (

+    Source == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Source + 1

+    );

+  if (Destination == Source || Length == 0) {

+    return Destination;

+  }

+  return InternalMemCopyMem (Destination, Source, Length);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/MemLib.c b/edk2/MdePkg/Library/PeiMemoryLib/MemLib.c
new file mode 100644
index 0000000..3a27ab2
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/MemLib.c
@@ -0,0 +1,47 @@
+/** @file

+  Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLib.c

+

+**/

+

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  (*GetPeiServicesTablePointer ())->CopyMem (

+                                      Destination,

+                                      (VOID*)Source,

+                                      Length

+                                      );

+  return Destination;

+}

+

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  (*GetPeiServicesTablePointer ())->SetMem (

+                                      Buffer,

+                                      Size,

+                                      Value

+                                      );

+  return Buffer;

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/MemLibGeneric.c b/edk2/MdePkg/Library/PeiMemoryLib/MemLibGeneric.c
new file mode 100644
index 0000000..bda1f49
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/MemLibGeneric.c
@@ -0,0 +1,266 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGeneric.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length > 0);

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/MemLibGuid.c b/edk2/MdePkg/Library/PeiMemoryLib/MemLibGuid.c
new file mode 100644
index 0000000..c54983c
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/MemLibGuid.c
@@ -0,0 +1,139 @@
+/** @file

+  Implementation of GUID functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGuid.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  )

+{

+  return (BOOLEAN)(

+           ReadUnaligned64 ((CONST UINT64*)Guid1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&

+           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)

+           );

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (Buffer != NULL);

+  //

+  // Make sure Buffer is aligned on a 64-bit boundary.

+  //

+  ASSERT (((UINTN) Buffer & 7) == 0);

+

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/MemLibInternals.h b/edk2/MdePkg/Library/PeiMemoryLib/MemLibInternals.h
new file mode 100644
index 0000000..ca7311a
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/MemLibInternals.h
@@ -0,0 +1,230 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibInternals.h

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.mbd b/edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.mbd
new file mode 100644
index 0000000..d78b59c
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiMemoryLib</BaseName>

+    <Guid>3a9759d2-53bc-4eb2-abcd-c93099419063</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.msa b/edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.msa
new file mode 100644
index 0000000..9a233ed
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.msa
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiMemoryLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>3a9759d2-53bc-4eb2-abcd-c93099419063</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MemLib.c</Filename>

+    <Filename>MemLibGuid.c</Filename>

+    <Filename>MemLibGeneric.c</Filename>

+    <Filename>CopyMemWrapper.c</Filename>

+    <Filename>SetMemWrapper.c</Filename>

+    <Filename>SetMem16Wrapper.c</Filename>

+    <Filename>SetMem32Wrapper.c</Filename>

+    <Filename>SetMem64Wrapper.c</Filename>

+    <Filename>CompareMemWrapper.c</Filename>

+    <Filename>ZeroMemWrapper.c</Filename>

+    <Filename>ScanMem8Wrapper.c</Filename>

+    <Filename>ScanMem16Wrapper.c</Filename>

+    <Filename>ScanMem32Wrapper.c</Filename>

+    <Filename>ScanMem64Wrapper.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/ScanMem16Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem16Wrapper.c
new file mode 100644
index 0000000..a17705d
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem16Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/ScanMem32Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem32Wrapper.c
new file mode 100644
index 0000000..67eb84d
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/ScanMem64Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem64Wrapper.c
new file mode 100644
index 0000000..c5f0762
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem64Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/ScanMem8Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem8Wrapper.c
new file mode 100644
index 0000000..9b817b1
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/ScanMem8Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  ScanMem8() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem8Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/SetMem16Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/SetMem16Wrapper.c
new file mode 100644
index 0000000..3acbdac
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/SetMem32Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/SetMem32Wrapper.c
new file mode 100644
index 0000000..620b69a
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/SetMem64Wrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/SetMem64Wrapper.c
new file mode 100644
index 0000000..73c28af
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/SetMemWrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/SetMemWrapper.c
new file mode 100644
index 0000000..294a27a
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/SetMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  SetMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Size <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  return InternalMemSetMem (Buffer, Size, Value);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/ZeroMemWrapper.c b/edk2/MdePkg/Library/PeiMemoryLib/ZeroMemWrapper.c
new file mode 100644
index 0000000..4a3d615
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ZeroMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemSetMem (Buffer, Length, 0);

+}

diff --git a/edk2/MdePkg/Library/PeiMemoryLib/build.xml b/edk2/MdePkg/Library/PeiMemoryLib/build.xml
new file mode 100644
index 0000000..8642382
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiMemoryLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiMemoryLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiMemoryLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiMemoryLib">

+      <GenBuild baseName="PeiMemoryLib" mbdFilename="${MODULE_DIR}/PeiMemoryLib.mbd" msaFilename="${MODULE_DIR}/PeiMemoryLib.msa"/>

+   </target>

+   <target depends="PeiMemoryLib_clean" name="clean"/>

+   <target depends="PeiMemoryLib_cleanall" name="cleanall"/>

+   <target name="PeiMemoryLib_clean">

+      <OutputDirSetup baseName="PeiMemoryLib" mbdFilename="${MODULE_DIR}/PeiMemoryLib.mbd" msaFilename="${MODULE_DIR}/PeiMemoryLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiMemoryLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiMemoryLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiMemoryLib_cleanall">

+      <OutputDirSetup baseName="PeiMemoryLib" mbdFilename="${MODULE_DIR}/PeiMemoryLib.mbd" msaFilename="${MODULE_DIR}/PeiMemoryLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiMemoryLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiMemoryLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiMemoryLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.c b/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
new file mode 100644
index 0000000..8ef5205
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
@@ -0,0 +1,946 @@
+/** @file

+Implementation of PcdLib class library for PEI phase.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: PeiPcdLib.c

+

+**/

+

+

+

+/**

+  The constructor function retrieve the PCD_PPI pointer.

+

+  @param[in] VOID

+  

+  @retval PCD_PPI * The pointer to the PCD_PPI.

+

+**/

+PCD_PPI  *

+GetPcdPpiPtr (

+  VOID

+  ) 

+{

+  EFI_STATUS        Status;

+  PCD_PPI           *PcdPpi;

+  EFI_PEI_SERVICES  **PeiServices;

+

+

+  PeiServices = GetPeiServicesTablePointer ();

+

+  Status = (**PeiServices).LocatePpi (

+                             PeiServices,

+                             &gPcdPpiGuid,

+                             0,

+                             NULL,

+                             (VOID **)&PcdPpi

+                             );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return PcdPpi;

+}

+

+

+

+/**

+  Sets the current SKU in the PCD database to the value specified by SkuId.  SkuId is returned.

+

+  @param[in]  SkuId The SKU value that will be used when the PCD service will retrieve and 

+              set values associated with a PCD token.

+

+  @retval SKU_ID Return the SKU ID that just be set.

+

+**/

+SKU_ID

+EFIAPI

+LibPcdSetSku (

+  IN SKU_ID  SkuId

+  )

+{

+

+  GetPcdPpiPtr()->SetSku (SkuId);;

+

+  return SkuId;

+}

+

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Returns the 8-bit value for the token specified by TokenNumber. 

+

+**/

+UINT8

+EFIAPI

+LibPcdGet8 (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get8 (TokenNumber);

+}

+

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber. 

+

+  @param[in]  The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Returns the 16-bit value for the token specified by TokenNumber. 

+

+**/

+UINT16

+EFIAPI

+LibPcdGet16 (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI  *PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get16 (TokenNumber);

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Returns the 32-bit value for the token specified by TokenNumber.

+

+**/

+UINT32

+EFIAPI

+LibPcdGet32 (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get32 (TokenNumber);

+}

+

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Returns the 64-bit value for the token specified by TokenNumber.

+

+**/

+UINT64

+EFIAPI

+LibPcdGet64 (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get64 (TokenNumber);

+}

+

+

+

+/**

+  Returns the pointer to the buffer of the token specified by TokenNumber.

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Returns the pointer to the token specified by TokenNumber.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetPtr (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->GetPtr (TokenNumber);

+}

+

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Returns the Boolean value of the token specified by TokenNumber. 

+

+**/

+BOOLEAN 

+EFIAPI

+LibPcdGetBool (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->GetBool (TokenNumber);

+}

+

+

+

+/**

+  Returns the size of the token specified by TokenNumber. 

+

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Returns the size of the token specified by TokenNumber. 

+

+**/

+UINTN

+EFIAPI

+LibPcdGetSize (

+  IN PCD_TOKEN_NUMBER             TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->GetSize (TokenNumber);

+}

+

+

+

+/**

+  Returns the 8-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT8 Return the UINT8.

+

+**/

+UINT8

+EFIAPI

+LibPcdGetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get8Ex (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the 16-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT16 Return the UINT16.

+

+**/

+UINT16

+EFIAPI

+LibPcdGetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get16Ex (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT32 Return the UINT32.

+

+**/

+UINT32

+EFIAPI

+LibPcdGetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get32Ex (Guid, TokenNumber);

+}

+

+

+

+

+/**

+  Returns the 64-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINT64 Return the UINT64.

+

+**/

+UINT64

+EFIAPI

+LibPcdGetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->Get64Ex (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the pointer to the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval VOID* Return the VOID* pointer.

+

+**/

+VOID *

+EFIAPI

+LibPcdGetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->GetPtrEx (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the Boolean value of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval BOOLEAN Return the BOOLEAN.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdGetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->GetBoolEx (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the size of the token specified by TokenNumber and Guid. 

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates 

+              which namespace to retrieve a value from.

+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.

+

+  @retval UINTN Return the size.

+

+**/

+UINTN

+EFIAPI

+LibPcdGetExSize (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber

+  )

+{

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  return PcdPpi->GetSizeEx (Guid, TokenNumber);

+}

+

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSet8 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set8 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return Value;

+}

+

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT16 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSet16 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set16 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return Value;

+}

+

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSet32 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32             Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  Status = PcdPpi->Set32 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSet64 (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64             Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set64 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber to 

+  the value specified by Value. Value is returned.

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value A pointer to the buffer to set.

+

+  @retval VOID* Return the pointer for the buffer been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetPtr (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->SetPtr (TokenNumber, SizeOfBuffer, Buffer);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Buffer;

+}

+

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber 

+  to the value specified by Value.  Value is returned.

+  

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The boolean value to set.

+

+  @retval BOOLEAN Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetBool (

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->SetBool (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 8-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT8             Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set8Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 16-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 16-bit value to set.

+

+  @retval UINT8 Return the value been set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT16            Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set16Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 32-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 32-bit value to set.

+

+  @retval UINT32 Return the value been set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT32             Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set32Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets the 64-bit value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 64-bit value to set.

+

+  @retval UINT64 Return the value been set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINT64            Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->Set64Ex (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  Sets a buffer for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  If Value is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The 8-bit value to set.

+

+  @retval VOID * Return the value been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN UINTN             SizeOfBuffer,

+  IN VOID              *Buffer

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+  Status = PcdPpi->SetPtrEx (Guid, TokenNumber, SizeOfBuffer, Buffer);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Buffer;

+}

+

+

+

+/**

+  Sets the Boolean value for the token specified by TokenNumber and 

+  Guid to the value specified by Value. Value is returned.

+  If Guid is NULL, then ASSERT().

+  

+  @param[in]  Guid Pointer to a 128-bit unique value that 

+              designates which namespace to set a value from.

+  @param[in]  TokenNumber The PCD token number to set a current value for.

+  @param[in]  Value The Boolean value to set.

+

+  @retval Boolean Return the value been set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN PCD_TOKEN_NUMBER  TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->SetBoolEx (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  When the token specified by TokenNumber and Guid is set, 

+  then notification function specified by NotificationFunction is called.  

+  If Guid is NULL, then the default token space is used. 

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Pointer to a 128-bit unique value that designates which 

+              namespace to set a value from.  If NULL, then the default 

+              token space is used.

+  @param[in]  TokenNumber The PCD token number to monitor.

+  @param[in]  NotificationFunction The function to call when the token 

+              specified by Guid and TokenNumber is set.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCallbackOnSet (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->CallbackOnSet (TokenNumber, Guid, NotificationFunction);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  Disable a notification function that was established with LibPcdCallbackonSet().

+  If NotificationFunction is NULL, then ASSERT().

+

+  @param[in]  Guid Specify the GUID token space.

+  @param[in]  TokenNumber Specify the token number.

+  @param[in]  NotificationFunction The callback function to be unregistered.

+

+  @retval VOID

+

+**/

+VOID

+EFIAPI

+LibPcdCancelCallback (

+  IN CONST GUID               *Guid,       OPTIONAL

+  IN PCD_TOKEN_NUMBER         TokenNumber,

+  IN PCD_CALLBACK             NotificationFunction

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->CancelCallback (TokenNumber, Guid, NotificationFunction);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  Retrieves the next PCD token number from the token space specified by Guid.  

+  If Guid is NULL, then the default token space is used.  If TokenNumber is 0, 

+  then the first token number is returned.  Otherwise, the token number that 

+  follows TokenNumber in the token space is returned.  If TokenNumber is the last 

+  token number in the token space, then 0 is returned.  If TokenNumber is not 0 and 

+  is not in the token space specified by Guid, then ASSERT().

+

+  @param[in]  Pointer to a 128-bit unique value that designates which namespace 

+              to set a value from.  If NULL, then the default token space is used.

+  @param[in]  The previous PCD token number.  If 0, then retrieves the first PCD 

+              token number.

+

+  @retval PCD_TOKEN_NUMBER The next valid token number.

+

+**/

+PCD_TOKEN_NUMBER           

+EFIAPI

+LibPcdGetNextToken (

+  IN CONST GUID             *Guid, OPTIONAL

+  IN       PCD_TOKEN_NUMBER TokenNumber

+  )

+{

+  EFI_STATUS Status;

+  PCD_PPI * PcdPpi;

+

+  PcdPpi = GetPcdPpiPtr ();

+

+

+  Status = PcdPpi->GetNextToken (Guid, &TokenNumber);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return TokenNumber;

+}

diff --git a/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.mbd b/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.mbd
new file mode 100644
index 0000000..bb90381
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiPcdLib</BaseName>

+    <Guid>9dbf6f25-0da2-4a1d-8e12-e78de6ab4d0e</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.msa b/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.msa
new file mode 100644
index 0000000..89d5fe3
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.msa
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiPcdLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>9dbf6f25-0da2-4a1d-8e12-e78de6ab4d0e</Guid>

+    <Version>0</Version>

+    <Abstract>PCD Library Instance implemented with PCD PPI.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiPcdLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiPcdLib/build.xml b/edk2/MdePkg/Library/PeiPcdLib/build.xml
new file mode 100644
index 0000000..d2a3404
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiPcdLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiPcdLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiPcdLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiPcdLib">

+      <GenBuild baseName="PeiPcdLib" mbdFilename="${MODULE_DIR}/PeiPcdLib.mbd" msaFilename="${MODULE_DIR}/PeiPcdLib.msa"/>

+   </target>

+   <target depends="PeiPcdLib_clean" name="clean"/>

+   <target depends="PeiPcdLib_cleanall" name="cleanall"/>

+   <target name="PeiPcdLib_clean">

+      <OutputDirSetup baseName="PeiPcdLib" mbdFilename="${MODULE_DIR}/PeiPcdLib.mbd" msaFilename="${MODULE_DIR}/PeiPcdLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiPcdLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiPcdLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiPcdLib_cleanall">

+      <OutputDirSetup baseName="PeiPcdLib" mbdFilename="${MODULE_DIR}/PeiPcdLib.mbd" msaFilename="${MODULE_DIR}/PeiPcdLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiPcdLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiPcdLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiPcdLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.mbd b/edk2/MdePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.mbd
new file mode 100644
index 0000000..54cb661
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiReportStatusCodeLib</BaseName>

+    <Guid>8c690838-7a22-45c4-aa58-a33e3e515cd4</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.msa b/edk2/MdePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.msa
new file mode 100644
index 0000000..c37e423
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiReportStatusCodeLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>8c690838-7a22-45c4-aa58-a33e3e515cd4</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">ReportStatusCodeLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>ReportStatusCodeLib.c</Filename>

+    <Filename>PostCode.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeDataTypeDebug</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeDataTypeAssert</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>StatusCodeSpecificData</C_Name>

+    </GuidEntry>

+  </Guids>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+      <Token>0x00000007</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiReportStatusCodeLib/PostCode.c b/edk2/MdePkg/Library/PeiReportStatusCodeLib/PostCode.c
new file mode 100644
index 0000000..c5d32e7
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiReportStatusCodeLib/PostCode.c
@@ -0,0 +1,125 @@
+/** @file

+  Report Status Code Library Post Code functions for PEI Phase.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Report Status Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x\n", Value));

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Report 

+  Status Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  Pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return  Value

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x - %s\n", Value, Description));

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_POST_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the 

+  REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED bit of 

+  PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTIONS_ENABLED 

+                  bit of PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportPostCodeDescriptionEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c b/edk2/MdePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c
new file mode 100644
index 0000000..5c022d6
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiReportStatusCodeLib/ReportStatusCodeLib.c
@@ -0,0 +1,548 @@
+/** @file

+  Report Status Code Library for DXE Phase.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+//

+// Define the maximum extended data size that is supported in the PEI phase

+//

+#define MAX_EXTENDED_DATA_SIZE  0x200

+

+/**

+  Internal worker function that reports a status code through the Status Code Protocol

+

+  This function checks to see if a Status Code Protocol is present in the handle 

+  database.  If a Status Code Protocol is not present, then EFI_UNSUPPORTED is 

+  returned.  If a Status Code Protocol is present, then it is cached in gStatusCode,

+  and the ReportStatusCode() service of the Status Code Protocol is called passing in

+  Type, Value, Instance, CallerId, and Data.  The result of this call is returned.

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  This is an optional parameter that may be 

+                            NULL.

+  @param  Data              Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to report the status code.

+  @retval  EFI_UNSUPPORTED       Status Code Protocol is not available.

+

+**/

+EFI_STATUS

+InternalReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE     Type,

+  IN EFI_STATUS_CODE_VALUE    Value,

+  IN UINT32                   Instance,

+  IN EFI_GUID                 *CallerId OPTIONAL,

+  IN EFI_STATUS_CODE_DATA     *Data     OPTIONAL  

+  )

+{

+  EFI_PEI_SERVICES  **PeiServices;

+  

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->PeiReportStatusCode (PeiServices, Type, Value, Instance, CallerId, Data);

+}

+

+

+/**

+  Computes and returns the size, in bytes, of a device path.

+

+  @param  DevicePath  A pointer to a device path.

+

+  @return  The size, in bytes, of DevicePath.

+

+**/

+UINTN

+InternalReportStatusCodeDevicePathSize (

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *Start;

+

+  if (DevicePath == NULL) {

+    return 0;

+  }

+

+  //

+  // Search for the end of the device path structure

+  //

+  Start = DevicePath;

+  while (!EfiIsDevicePathEnd (DevicePath)) {

+    DevicePath = EfiNextDevicePathNode (DevicePath);

+  }

+

+  //

+  // Subtract the start node from the end node and add in the size of the end node

+  //

+  return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);

+}

+

+

+/**

+  Converts a status code to an 8-bit POST code value.

+

+  Converts the status code specified by CodeType and Value to an 8-bit POST code 

+  and returns the 8-bit POST code in PostCode.  If CodeType is an 

+  EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode 

+  are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits 

+  24..26 of Value., and TRUE is returned.  Otherwise, FALSE is returned.  

+

+  If PostCode is NULL, then ASSERT().

+

+  @param  CodeType  The type of status code being converted.

+  @param  Value     The status code value being converted.

+  @param  PostCode  A pointer to the 8-bit POST code value to return. 

+

+  @retval  TRUE   The status code specified by CodeType and Value was converted 

+                  to an 8-bit POST code and returned in  PostCode.

+  @retval  FALSE  The status code specified by CodeType and Value could not be 

+                  converted to an 8-bit POST code value.

+

+**/

+BOOLEAN

+EFIAPI

+CodeTypeToPostCode (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,

+  OUT UINT8                  *PostCode

+  )

+{

+  //

+  // If PostCode is NULL, then ASSERT()

+  //

+  ASSERT (PostCode != NULL);

+

+  //

+  // Convert Value to an 8 bit post code

+  //

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||

+      ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)       ) {

+    *PostCode  = (UINT8) (((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5);

+    *PostCode |= (UINT8) (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f);

+    return TRUE;

+  }

+  return FALSE;

+}

+

+

+/**

+  Extracts ASSERT() information from a status code structure.

+

+  Converts the status code specified by CodeType, Value, and Data to the ASSERT()

+  arguments specified by Filename, Description, and LineNumber.  If CodeType is 

+  an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and 

+  Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract 

+  Filename, Description, and LineNumber from the optional data area of the 

+  status code buffer specified by Data.  The optional data area of Data contains 

+  a Null-terminated ASCII string for the FileName, followed by a Null-terminated 

+  ASCII string for the Description, followed by a 32-bit LineNumber.  If the 

+  ASSERT() information could be extracted from Data, then return TRUE.  

+  Otherwise, FALSE is returned.  

+

+  If Data is NULL, then ASSERT().

+  If Filename is NULL, then ASSERT().

+  If Description is NULL, then ASSERT().

+  If LineNumber is NULL, then ASSERT().

+

+  @param  CodeType     The type of status code being converted.

+  @param  Value        The status code value being converted.

+  @param  Data         Pointer to status code data buffer. 

+  @param  Filename     Pointer to the source file name that generated the ASSERT().

+  @param  Description  Pointer to the description of the ASSERT().

+  @param  LineNumber   Pointer to source line number that generated the ASSERT().

+

+  @retval  TRUE   The status code specified by CodeType, Value, and Data was 

+                  converted ASSERT() arguments specified by Filename, Description, 

+                  and LineNumber.

+  @retval  FALSE  The status code specified by CodeType, Value, and Data could 

+                  not be converted to ASSERT() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractAssertInfo (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,  

+  IN  EFI_STATUS_CODE_DATA   *Data, 

+  OUT CHAR8                  **Filename,

+  OUT CHAR8                  **Description,

+  OUT UINT32                 *LineNumber

+  )

+{

+  EFI_DEBUG_ASSERT_DATA  *AssertData;

+

+  ASSERT (Data        != NULL);

+  ASSERT (Filename    != NULL);

+  ASSERT (Description != NULL);

+  ASSERT (LineNumber  != NULL);

+

+  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK)      == EFI_ERROR_CODE) && 

+      ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK)  == EFI_ERROR_UNRECOVERED) &&

+      ((Value    & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {

+    AssertData   = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);

+    *Filename    = (CHAR8 *)(AssertData + 1);

+    *Description = *Filename + AsciiStrLen (*Filename) + 1;

+    *LineNumber  = AssertData->LineNumber;

+    return TRUE;

+  }

+  return FALSE;

+}

+

+

+/**

+  Extracts DEBUG() information from a status code structure.

+

+  Converts the status code specified by Data to the DEBUG() arguments specified 

+  by ErrorLevel, Marker, and Format.  If type GUID in Data is 

+  EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and 

+  Format from the optional data area of the status code buffer specified by Data.  

+  The optional data area of Data contains a 32-bit ErrorLevel followed by Marker 

+  which is 12 UINTN parameters, followed by a Null-terminated ASCII string for 

+  the Format.  If the DEBUG() information could be extracted from Data, then 

+  return TRUE.  Otherwise, FALSE is returned.

+

+  If Data is NULL, then ASSERT().

+  If ErrorLevel is NULL, then ASSERT().

+  If Marker is NULL, then ASSERT().

+  If Format is NULL, then ASSERT().

+

+  @param  Data        Pointer to status code data buffer. 

+  @param  ErrorLevel  Pointer to error level mask for a debug message.

+  @param  Marker      Pointer to the variable argument list associated with Format.

+  @param  Format      Pointer to a Null-terminated ASCII format string of a 

+                      debug message.

+

+  @retval  TRUE   The status code specified by Data was converted DEBUG() arguments 

+                  specified by ErrorLevel, Marker, and Format.

+  @retval  FALSE  The status code specified by Data could not be converted to 

+                  DEBUG() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractDebugInfo (

+  IN  EFI_STATUS_CODE_DATA  *Data,

+  OUT UINT32                *ErrorLevel,

+  OUT VA_LIST               *Marker,

+  OUT CHAR8                 **Format

+  )

+{

+  EFI_DEBUG_INFO  *DebugInfo;

+

+  ASSERT (Data       != NULL);

+  ASSERT (ErrorLevel != NULL);

+  ASSERT (Marker     != NULL);

+  ASSERT (Format     != NULL);

+

+  //

+  // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE

+  //

+  if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {

+    return FALSE;

+  }

+

+  //

+  // Retrieve the debug information from the status code record

+  //

+  DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);

+

+  *ErrorLevel = DebugInfo->ErrorLevel;

+

+  //

+  // The first 12 * UINTN bytes of the string are really an 

+  // argument stack to support varargs on the Format string.

+  //

+  *Marker = (VA_LIST) (DebugInfo + 1);

+  *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);

+

+  return TRUE;

+}

+

+

+/**

+  Reports a status code.

+

+  Reports the status code specified by the parameters Type and Value.  Status 

+  code also require an instance, caller ID, and extended data.  This function 

+  passed in a zero instance, NULL extended data, and a caller ID of 

+  gEfiCallerIdGuid, which is the GUID for the module.  

+  

+  ReportStatusCode()must actively prevent recusrsion.  If ReportStatusCode() 

+  is called while processing another any other Report Status Code Library function,

+  then ReportStatusCode() must return immediately.

+

+  @param  Type   Status code type. 

+  @param  Value  Status code value.

+

+  @retval  EFI_SUCCESS       The status code was reported.

+  @retval  EFI_DEVICE_ERROR  There status code could not be reported due to a 

+                             device error.

+  @retval  EFI_UNSUPPORTED   Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value

+  )

+{

+  return InternalReportStatusCode (Type, Value, 0, &gEfiCallerIdGuid, NULL);

+}

+

+

+/**

+  Reports a status code with a Device Path Protocol as the extended data.

+

+  Allocates and fills in the extended data section of a status code with the 

+  Device Path Protocol specified by DevicePath.  This function is responsible 

+  for allocating a buffer large enough for the standard header and the device 

+  path.  The standard header is filled in with a GUID of 

+  gEfiStatusCodeSpecificDataGuid.  The status code is reported with a zero 

+  instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithDevicePath()must actively prevent recursion.  If 

+  ReportStatusCodeWithDevicePath() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithDevicePath() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If DevicePath is NULL, then ASSERT().

+

+  @param  Type        Status code type. 

+  @param  Value       Status code value.

+  @param  DevicePath  Pointer to the Device Path Protocol to be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by DevicePath.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithDevicePath (

+  IN EFI_STATUS_CODE_TYPE      Type,

+  IN EFI_STATUS_CODE_VALUE     Value,

+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  ASSERT (DevicePath != NULL);

+  return ReportStatusCodeWithExtendedData (

+           Type, 

+           Value, 

+           (VOID *)DevicePath, 

+           InternalReportStatusCodeDevicePathSize (DevicePath)

+           );

+}

+

+

+/**

+  Reports a status code with an extended data buffer.

+

+  Allocates and fills in the extended data section of a status code with the 

+  extended data specified by ExtendedData and ExtendedDataSize.  ExtendedData 

+  is assumed to be one of the data structures specified in Related Definitions.  

+  These data structure do not have the standard header, so this function is 

+  responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled 

+  in with a GUID of  gEfiStatusCodeSpecificDataGuid.  The status code is reported 

+  with a zero instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithExtendedData()must actively prevent recursion.  If 

+  ReportStatusCodeWithExtendedData() is called while processing another any other 

+  Report Status Code Library function, then ReportStatusCodeWithExtendedData() 

+  must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL, then ASSERT().

+  If ExtendedDataSize is 0, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  ExtendedData      Pointer to the extended data buffer to be reported.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer to 

+                            be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended 

+                                 data specified by ExtendedData and ExtendedDataSize.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the 

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithExtendedData (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN VOID                   *ExtendedData,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  ASSERT (ExtendedData     != NULL);

+  ASSERT (ExtendedDataSize != 0);

+  return ReportStatusCodeEx (

+           Type,

+           Value,

+           0,

+           NULL,

+           NULL,

+           ExtendedData,

+           ExtendedDataSize

+           );

+}

+

+

+/**

+  Reports a status code with full parameters.

+

+  The function reports a status code.  If ExtendedData is NULL and ExtendedDataSize 

+  is 0, then an extended data buffer is not reported.  If ExtendedData is not 

+  NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.  

+  ExtendedData is assumed not have the standard status code header, so this function 

+  is responsible for allocating a buffer large enough for the standard header and 

+  the extended data passed into this function.  The standard header is filled in 

+  with a GUID specified by ExtendedDataGuid.  If ExtendedDataGuid is NULL, then a 

+  GUID of gEfiStatusCodeSpecificDatauid is used.  The status code is reported with 

+  an instance specified by Instance and a caller ID specified by CallerId.  If 

+  CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.

+

+  ReportStatusCodeEx()must actively prevent recursion.  If ReportStatusCodeEx() 

+  is called while processing another any other Report Status Code Library function, 

+  then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().

+  If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().

+

+  @param  Type              Status code type. 

+  @param  Value             Status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          Pointer to a GUID that identifies the caller of this 

+                            function.  If this parameter is NULL, then a caller 

+                            ID of gEfiCallerIdGuid is used.

+  @param  ExtendedDataGuid  Pointer to the GUID for the extended data buffer.  

+                            If this parameter is NULL, then a the status code 

+                            standard header is filled in with 

+                            gEfiStatusCodeSpecificDataGuid.

+  @param  ExtendedData      Pointer to the extended data buffer.  This is an 

+                            optional parameter that may be NULL.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate 

+                                 the extended data section if it was specified.

+  @retval  EFI_UNSUPPORTED       Report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeEx (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN UINT32                 Instance,

+  IN EFI_GUID               *CallerId           OPTIONAL,

+  IN EFI_GUID               *ExtendedDataGuid   OPTIONAL,

+  IN VOID                   *ExtendedData       OPTIONAL,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  EFI_STATUS_CODE_DATA  *StatusCodeData;

+  UINT64                Buffer[MAX_EXTENDED_DATA_SIZE / sizeof (UINT64)];

+

+  ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));

+  ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));

+

+  if (ExtendedDataSize > (MAX_EXTENDED_DATA_SIZE - sizeof (EFI_STATUS_CODE_DATA))) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  StatusCodeData = (EFI_STATUS_CODE_DATA  *)Buffer;

+  StatusCodeData->HeaderSize = sizeof (EFI_STATUS_CODE_DATA);

+  StatusCodeData->Size = (UINT16)ExtendedDataSize;

+  if (ExtendedDataGuid == NULL) {

+    ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;

+  }

+  CopyGuid (&StatusCodeData->Type, ExtendedDataGuid);

+  CopyMem (StatusCodeData + 1, ExtendedData, ExtendedDataSize);

+  if (CallerId == NULL) {

+    CallerId = &gEfiCallerIdGuid;

+  }

+  return InternalReportStatusCode (Type, Value, Instance, CallerId, StatusCodeData);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportProgressCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_ERROR_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportErrorCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED 

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of 

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportDebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/PeiReportStatusCodeLib/build.xml b/edk2/MdePkg/Library/PeiReportStatusCodeLib/build.xml
new file mode 100644
index 0000000..1715983
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiReportStatusCodeLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiReportStatusCodeLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiReportStatusCodeLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiReportStatusCodeLib">

+      <GenBuild baseName="PeiReportStatusCodeLib" mbdFilename="${MODULE_DIR}/PeiReportStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/PeiReportStatusCodeLib.msa"/>

+   </target>

+   <target depends="PeiReportStatusCodeLib_clean" name="clean"/>

+   <target depends="PeiReportStatusCodeLib_cleanall" name="cleanall"/>

+   <target name="PeiReportStatusCodeLib_clean">

+      <OutputDirSetup baseName="PeiReportStatusCodeLib" mbdFilename="${MODULE_DIR}/PeiReportStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/PeiReportStatusCodeLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiReportStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiReportStatusCodeLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiReportStatusCodeLib_cleanall">

+      <OutputDirSetup baseName="PeiReportStatusCodeLib" mbdFilename="${MODULE_DIR}/PeiReportStatusCodeLib.mbd" msaFilename="${MODULE_DIR}/PeiReportStatusCodeLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiReportStatusCodeLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiReportStatusCodeLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiReportStatusCodeLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.c b/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.c
new file mode 100644
index 0000000..2726c53
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.c
@@ -0,0 +1,50 @@
+/** @file

+  Resource Publication Library that uses PEI Core Services to publish system memory.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  PeiResourcePublicationLib.c

+

+**/

+

+

+/**

+  

+  Declares the presence of permanent system memory in the platform.

+

+  Declares that the system memory buffer specified by MemoryBegin and MemoryLength

+  as permanent memory that may be used for general purpose use by software.

+  The amount of memory available to software may be less than MemoryLength

+  if published memory has alignment restrictions.  

+

+  @param  MemoryBegin               The start address of the memory being declared.

+  @param  MemoryLength              The number of bytes of memory being declared.

+

+  @retval  RETURN_SUCCESS           The memory buffer was published.

+  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to publish the memory buffer

+

+**/

+RETURN_STATUS

+EFIAPI

+PublishSystemMemory (

+  IN PHYSICAL_ADDRESS       MemoryBegin,

+  IN UINT64                 MemoryLength

+  )

+{

+  EFI_STATUS        Status;

+

+  ASSERT (MemoryLength > 0);

+  ASSERT (MemoryLength <= (MAX_ADDRESS - MemoryBegin + 1));

+

+  Status      = PeiCoreInstallPeiMemory (MemoryBegin, MemoryLength);

+     

+  return (RETURN_STATUS) Status;

+}

+

diff --git a/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.mbd b/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.mbd
new file mode 100644
index 0000000..4271c55
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiResourcePublicationLib</BaseName>

+    <Guid>e8d6390d-e190-4957-9ab6-d47d51b01336</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 09:00</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.msa b/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.msa
new file mode 100644
index 0000000..2e85949
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.msa
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiResourcePublicationLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e8d6390d-e190-4957-9ab6-d47d51b01336</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 09:00</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">ResourcePublicationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiResourcePublicationLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiResourcePublicationLib/build.xml b/edk2/MdePkg/Library/PeiResourcePublicationLib/build.xml
new file mode 100644
index 0000000..f7394ab
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiResourcePublicationLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiResourcePublicationLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiResourcePublicationLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiResourcePublicationLib">

+      <GenBuild baseName="PeiResourcePublicationLib" mbdFilename="${MODULE_DIR}/PeiResourcePublicationLib.mbd" msaFilename="${MODULE_DIR}/PeiResourcePublicationLib.msa"/>

+   </target>

+   <target depends="PeiResourcePublicationLib_clean" name="clean"/>

+   <target depends="PeiResourcePublicationLib_cleanall" name="cleanall"/>

+   <target name="PeiResourcePublicationLib_clean">

+      <OutputDirSetup baseName="PeiResourcePublicationLib" mbdFilename="${MODULE_DIR}/PeiResourcePublicationLib.mbd" msaFilename="${MODULE_DIR}/PeiResourcePublicationLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiResourcePublicationLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiResourcePublicationLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiResourcePublicationLib_cleanall">

+      <OutputDirSetup baseName="PeiResourcePublicationLib" mbdFilename="${MODULE_DIR}/PeiResourcePublicationLib.mbd" msaFilename="${MODULE_DIR}/PeiResourcePublicationLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiResourcePublicationLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiResourcePublicationLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiResourcePublicationLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
new file mode 100644
index 0000000..0240c38
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
@@ -0,0 +1,39 @@
+/** @file

+  PEI Services Table Pointer Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  PeiServicesTablePointer.c

+

+**/

+

+

+

+static EFI_PEI_SERVICES  **gPeiServices;

+

+EFI_PEI_SERVICES **

+GetPeiServicesTablePointer (

+  VOID

+  )

+{

+  return gPeiServices;

+}

+

+/**

+**/

+EFI_STATUS

+PeiServicesTablePointerLibConstructor (

+  IN EFI_FFS_FILE_HEADER  *FfsHeader,

+  IN EFI_PEI_SERVICES     **PeiServices

+  )

+{

+  gPeiServices = PeiServices;

+  return EFI_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.mbd b/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.mbd
new file mode 100644
index 0000000..c45d77e
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiServicesTablePointerLib</BaseName>

+    <Guid>1c747f6b-0a58-49ae-8ea3-0327a4fa10e3</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.msa b/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.msa
new file mode 100644
index 0000000..4578872
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.msa
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiServicesTablePointerLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>1c747f6b-0a58-49ae-8ea3-0327a4fa10e3</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeiServicesTablePointerLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiServicesTablePointer.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <Constructor>PeiServicesTablePointerLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLib/build.xml b/edk2/MdePkg/Library/PeiServicesTablePointerLib/build.xml
new file mode 100644
index 0000000..f723919
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiServicesTablePointerLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiServicesTablePointerLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiServicesTablePointerLib">

+      <GenBuild baseName="PeiServicesTablePointerLib" mbdFilename="${MODULE_DIR}/PeiServicesTablePointerLib.mbd" msaFilename="${MODULE_DIR}/PeiServicesTablePointerLib.msa"/>

+   </target>

+   <target depends="PeiServicesTablePointerLib_clean" name="clean"/>

+   <target depends="PeiServicesTablePointerLib_cleanall" name="cleanall"/>

+   <target name="PeiServicesTablePointerLib_clean">

+      <OutputDirSetup baseName="PeiServicesTablePointerLib" mbdFilename="${MODULE_DIR}/PeiServicesTablePointerLib.mbd" msaFilename="${MODULE_DIR}/PeiServicesTablePointerLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiServicesTablePointerLib_cleanall">

+      <OutputDirSetup baseName="PeiServicesTablePointerLib" mbdFilename="${MODULE_DIR}/PeiServicesTablePointerLib.mbd" msaFilename="${MODULE_DIR}/PeiServicesTablePointerLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiServicesTablePointerLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c
new file mode 100644
index 0000000..285a5a0
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c
@@ -0,0 +1,37 @@
+/** @file

+  PEI Services Table Pointer Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  PeiServicesTablePointer.c

+

+**/

+

+

+

+EFI_PEI_SERVICES **

+GetPeiServicesTablePointer (

+  VOID

+  )

+{

+  return (EFI_PEI_SERVICES **)(UINTN)AsmReadMm7 ();

+}

+

+/**

+**/

+EFI_STATUS

+PeiServicesTablePointerLibConstructor (

+  IN EFI_FFS_FILE_HEADER  *FfsHeader,

+  IN EFI_PEI_SERVICES     **PeiServices

+  )

+{

+  AsmWriteMm7 ((UINT64)(UINTN)PeiServices);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.mbd b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.mbd
new file mode 100644
index 0000000..5023d92
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiServicesTablePointerLibMm7</BaseName>

+    <Guid>e6e9c1f8-2c8a-4f4b-a27c-c382e4bb8e67</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.msa b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.msa
new file mode 100644
index 0000000..7a6d8ba
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.msa
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiServicesTablePointerLibMm7</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>e6e9c1f8-2c8a-4f4b-a27c-c382e4bb8e67</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiServicesTablePointer.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <Constructor>PeiServicesTablePointerLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/build.xml b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/build.xml
new file mode 100644
index 0000000..b663224
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiServicesTablePointerLibMm7/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiServicesTablePointerLibMm7"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiServicesTablePointerLibMm7"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiServicesTablePointerLibMm7">

+      <GenBuild baseName="PeiServicesTablePointerLibMm7" mbdFilename="${MODULE_DIR}/PeiServicesTablePointerLibMm7.mbd" msaFilename="${MODULE_DIR}/PeiServicesTablePointerLibMm7.msa"/>

+   </target>

+   <target depends="PeiServicesTablePointerLibMm7_clean" name="clean"/>

+   <target depends="PeiServicesTablePointerLibMm7_cleanall" name="cleanall"/>

+   <target name="PeiServicesTablePointerLibMm7_clean">

+      <OutputDirSetup baseName="PeiServicesTablePointerLibMm7" mbdFilename="${MODULE_DIR}/PeiServicesTablePointerLibMm7.mbd" msaFilename="${MODULE_DIR}/PeiServicesTablePointerLibMm7.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLibMm7_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLibMm7_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiServicesTablePointerLibMm7_cleanall">

+      <OutputDirSetup baseName="PeiServicesTablePointerLibMm7" mbdFilename="${MODULE_DIR}/PeiServicesTablePointerLibMm7.mbd" msaFilename="${MODULE_DIR}/PeiServicesTablePointerLibMm7.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLibMm7_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiServicesTablePointerLibMm7_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiServicesTablePointerLibMm7*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeiSmbusLib/InternalSmbusLib.h b/edk2/MdePkg/Library/PeiSmbusLib/InternalSmbusLib.h
new file mode 100644
index 0000000..bd6d57f
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiSmbusLib/InternalSmbusLib.h
@@ -0,0 +1,60 @@
+/** @file

+Internal header file for Smbus library.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: SmbusLib.c

+

+**/

+

+#ifndef __INTERNAL_SMBUS_LIB_H

+#define __INTERNAL_SMBUS_LIB_H

+

+#define SMBUS_LIB_SLAVE_ADDRESS(SmBusAddress)      (((SmBusAddress) >> 1)  & 0x7f)

+#define SMBUS_LIB_COMMAND(SmBusAddress)            (((SmBusAddress) >> 8)  & 0xff)

+#define SMBUS_LIB_LENGTH(SmBusAddress)             (((SmBusAddress) >> 16) & 0x1f)

+#define SMBUS_LIB_PEC(SmBusAddress)     ((BOOLEAN) (((SmBusAddress) & SMBUS_LIB_PEC_BIT) != 0))

+#define SMBUS_LIB_RESEARVED(SmBusAddress)          ((SmBusAddress) & ~(((1 << 21) - 2) | SMBUS_LIB_PEC_BIT))

+

+//

+// Declaration for internal functions

+//

+/**

+  Executes an SMBus operation to an SMBus controller. 

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance that it will use to

+                          execute the SMBus transactions.

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will do. The maximum number of

+                          bytes can be revision specific and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave device. Not all operations

+                          require this argument. The length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation.

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.c b/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.c
new file mode 100644
index 0000000..db28021
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.c
@@ -0,0 +1,99 @@
+/** @file

+Implementation of SmBusLib class library for PEI phase.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: PeiSmbusLib.c

+

+**/

+

+#include "InternalSmbusLib.h"

+

+/**

+  Gets Smbus PPIs.

+

+  This internal function retrieves Smbus PPI from PPI database.

+

+  @param  PeiServices   An indirect pointer to the EFI_PEI_SERVICES published by the PEI Foundation.

+

+  @return The pointer to Smbus PPI.

+

+**/

+EFI_PEI_SMBUS_PPI *

+InternalGetSmbusPpi (

+  EFI_PEI_SERVICES      **PeiServices

+  ) 

+{

+  EFI_STATUS            Status;

+  EFI_PEI_SMBUS_PPI     *SmbusPpi;

+

+  Status = (*PeiServices)->LocatePpi (PeiServices, &gEfiPeiSmbusPpiGuid, 0, NULL, (VOID **) &SmbusPpi);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (SmbusPpi != NULL);

+

+  return SmbusPpi;

+}

+

+/**

+  Executes an SMBus operation to an SMBus controller. 

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance that it will use to

+                          execute the SMBus transactions.

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will do. The maximum number of

+                          bytes can be revision specific and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave device. Not all operations

+                          require this argument. The length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation..

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  )

+{

+  EFI_PEI_SMBUS_PPI         *SmbusPpi;

+  EFI_PEI_SERVICES          **PeiServices;

+  RETURN_STATUS             ReturnStatus;

+  EFI_SMBUS_DEVICE_ADDRESS  SmbusDeviceAddress;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  SmbusPpi    = InternalGetSmbusPpi (PeiServices);

+  SmbusDeviceAddress.SmbusDeviceAddress = SMBUS_LIB_SLAVE_ADDRESS (SmBusAddress);

+

+  ReturnStatus = SmbusPpi->Execute (

+                             PeiServices,

+                             SmbusPpi,

+                             SmbusDeviceAddress,

+                             SMBUS_LIB_COMMAND (SmBusAddress),

+                             SmbusOperation,

+                             SMBUS_LIB_PEC (SmBusAddress),  

+                             &Length,

+                             Buffer

+                             );

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+

+  return Length;

+}

diff --git a/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.mbd b/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.mbd
new file mode 100644
index 0000000..5b5bfdf
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeiSmbusLib</BaseName>

+    <Guid>56E800D9-7603-4e01-9581-1FFB9E98F5BE</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-17 22:30</Created>

+    <Modified>2006-04-17 22:30</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.msa b/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.msa
new file mode 100644
index 0000000..5db00bc
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiSmbusLib/PeiSmbusLib.msa
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeiSmbusLib</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>51C4C059-67F0-4e3c-9A55-FF42A8291C8C</Guid>

+    <Version>0</Version>

+    <Abstract>SmBus Library Instance implemented with SmBus PPI.</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-17 22:30</Created>

+    <Updated>2006-04-17 22:30</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">SmbusLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PeiServicesTablePointerLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeiSmbusLib.c</Filename>

+    <Filename>SmbusLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PPIs>

+    <Ppi Usage="ALWAYS_CONSUMED">Smbus</Ppi>

+  </PPIs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeiSmbusLib/SmbusLib.c b/edk2/MdePkg/Library/PeiSmbusLib/SmbusLib.c
new file mode 100644
index 0000000..e71f11b
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiSmbusLib/SmbusLib.c
@@ -0,0 +1,466 @@
+/** @file

+Implementation of SmBusLib class library for PEI phase.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.             

+

+

+Module Name: SmbusLib.c

+

+**/

+

+#include "InternalSmbusLib.h"

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickRead, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickWrite, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)  == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte, Status);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to send.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Byte   = Value;

+  InternalSmBusExec (EfiSmbusSendByte, SmBusAddress, 1, &Byte, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, 1, &Byte, Status);

+  

+  return Byte;

+}

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Byte = Value;

+  InternalSmBusExec (EfiSmbusWriteByte, SmBusAddress, 1, &Byte, Status);

+  

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);

+  

+  return Word;

+}

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Word = Value;

+  InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);

+  

+  return Value;

+}

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN  Length;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Length = SMBUS_LIB_LENGTH (SmBusAddress) + 1;

+  return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from OutBuffer.  Bytes are then read from the SMBUS into InBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller¡¯s responsibility to make sure InBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If OutBuffer is NULL, then ASSERT().

+  If InBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.

+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *OutBuffer,

+  OUT VOID           *InBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN   Length;

+

+  ASSERT (InBuffer  != NULL);

+  ASSERT (OutBuffer != NULL);

+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);

+

+  Length   = SMBUS_LIB_LENGTH (SmBusAddress) + 1;

+  //

+  // Assuming that InBuffer is large enough to save another memory copy.

+  //

+  InBuffer = CopyMem (InBuffer, OutBuffer, Length);

+  return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, InBuffer, Status);

+}

diff --git a/edk2/MdePkg/Library/PeiSmbusLib/build.xml b/edk2/MdePkg/Library/PeiSmbusLib/build.xml
new file mode 100644
index 0000000..1ab32b7
--- /dev/null
+++ b/edk2/MdePkg/Library/PeiSmbusLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeiSmbusLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeiSmbusLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeiSmbusLib">

+      <GenBuild baseName="PeiSmbusLib" mbdFilename="${MODULE_DIR}/PeiSmbusLib.mbd" msaFilename="${MODULE_DIR}/PeiSmbusLib.msa"/>

+   </target>

+   <target depends="PeiSmbusLib_clean" name="clean"/>

+   <target depends="PeiSmbusLib_cleanall" name="cleanall"/>

+   <target name="PeiSmbusLib_clean">

+      <OutputDirSetup baseName="PeiSmbusLib" mbdFilename="${MODULE_DIR}/PeiSmbusLib.mbd" msaFilename="${MODULE_DIR}/PeiSmbusLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiSmbusLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiSmbusLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeiSmbusLib_cleanall">

+      <OutputDirSetup baseName="PeiSmbusLib" mbdFilename="${MODULE_DIR}/PeiSmbusLib.mbd" msaFilename="${MODULE_DIR}/PeiSmbusLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeiSmbusLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeiSmbusLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeiSmbusLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c b/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c
new file mode 100644
index 0000000..b661646
--- /dev/null
+++ b/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c
@@ -0,0 +1,68 @@
+

+/** @file

+  Entry point to a PEIM.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.

+

+**/

+

+/**

+  Image entry point of Peim.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+  @return  Status returned by entry points of Peims.

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_FFS_FILE_HEADER       *FfsHeader,

+  IN EFI_PEI_SERVICES          **PeiServices

+  )

+{

+  if (_gPeimRevision != 0) {

+    //

+    // Make sure that the PEI spec revision of the platform is >= PEI spec revision of the driver

+    //

+    ASSERT ((*PeiServices)->Hdr.Revision >= _gPeimRevision);

+  }

+

+  //

+  // Call constructor for all libraries

+  //

+  ProcessLibraryConstructorList (FfsHeader, PeiServices);

+

+  //

+  // Call the driver entry point

+  //

+  return ProcessModuleEntryPointList (FfsHeader, PeiServices);

+}

+

+

+/**

+  Wrapper of Peim image entry point.

+

+  @param  FfsHeader   Pointer to FFS header the loaded driver.

+  @param  PeiServices Pointer to the PEI services.

+

+  @return  Status returned by entry points of Peims.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_FFS_FILE_HEADER  *FfsHeader,

+  IN EFI_PEI_SERVICES     **PeiServices

+  )

+{

+  return _ModuleEntryPoint (FfsHeader, PeiServices);

+}

diff --git a/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.mbd b/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.mbd
new file mode 100644
index 0000000..1a41f73
--- /dev/null
+++ b/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>PeimEntryPoint</BaseName>

+    <Guid>fa177ff7-1fc7-458d-a358-d9d62ae61cec</Guid>

+    <Version>0</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.msa b/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.msa
new file mode 100644
index 0000000..8539598
--- /dev/null
+++ b/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.msa
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>PeimEntryPoint</BaseName>

+    <ModuleType>PEIM</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>fa177ff7-1fc7-458d-a358-d9d62ae61cec</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to the PEI Core</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">PeimEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>PeimEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/PeimEntryPoint/build.xml b/edk2/MdePkg/Library/PeimEntryPoint/build.xml
new file mode 100644
index 0000000..ae43cb5
--- /dev/null
+++ b/edk2/MdePkg/Library/PeimEntryPoint/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="PeimEntryPoint"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/PeimEntryPoint"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="PeimEntryPoint">

+      <GenBuild baseName="PeimEntryPoint" mbdFilename="${MODULE_DIR}/PeimEntryPoint.mbd" msaFilename="${MODULE_DIR}/PeimEntryPoint.msa"/>

+   </target>

+   <target depends="PeimEntryPoint_clean" name="clean"/>

+   <target depends="PeimEntryPoint_cleanall" name="cleanall"/>

+   <target name="PeimEntryPoint_clean">

+      <OutputDirSetup baseName="PeimEntryPoint" mbdFilename="${MODULE_DIR}/PeimEntryPoint.mbd" msaFilename="${MODULE_DIR}/PeimEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeimEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeimEntryPoint_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="PeimEntryPoint_cleanall">

+      <OutputDirSetup baseName="PeimEntryPoint" mbdFilename="${MODULE_DIR}/PeimEntryPoint.mbd" msaFilename="${MODULE_DIR}/PeimEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/PeimEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/PeimEntryPoint_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**PeimEntryPoint*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c b/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c
new file mode 100644
index 0000000..aa990f7
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c
@@ -0,0 +1,47 @@
+/** @file

+  UEFI Boot Services Table Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  UefiBootServicesTableLib.c

+

+**/

+

+EFI_HANDLE         gImageHandle;

+EFI_SYSTEM_TABLE   *gST;

+EFI_BOOT_SERVICES  *gBS;

+

+/**

+**/

+EFI_STATUS

+UefiBootServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  //

+  // Cache the Image Handle

+  //

+  gImageHandle = ImageHandle;

+

+  //

+  // Cache pointer to the EFI System Table

+  //

+  gST = SystemTable;

+  ASSERT (gST != NULL);

+

+  //

+  // Cache pointer to the EFI Boot Services Table

+  //

+  gBS = SystemTable->BootServices;

+  ASSERT (gBS != NULL);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.mbd b/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.mbd
new file mode 100644
index 0000000..dc6fda9
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiBootServicesTableLib</BaseName>

+    <Guid>baa1baa3-0a8d-402c-8042-985115fae953</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 15:49</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.msa b/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.msa
new file mode 100644
index 0000000..7856e2b
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.msa
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiBootServicesTableLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>baa1baa3-0a8d-402c-8042-985115fae953</Guid>

+    <Version>0</Version>

+    <Abstract>UEFI Boot Services Table Library</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 15:49</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UefiBootServicesTableLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <Constructor>UefiBootServicesTableLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiBootServicesTableLib/build.xml b/edk2/MdePkg/Library/UefiBootServicesTableLib/build.xml
new file mode 100644
index 0000000..51f52ec
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiBootServicesTableLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiBootServicesTableLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiBootServicesTableLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiBootServicesTableLib">

+      <GenBuild baseName="UefiBootServicesTableLib" mbdFilename="${MODULE_DIR}/UefiBootServicesTableLib.mbd" msaFilename="${MODULE_DIR}/UefiBootServicesTableLib.msa"/>

+   </target>

+   <target depends="UefiBootServicesTableLib_clean" name="clean"/>

+   <target depends="UefiBootServicesTableLib_cleanall" name="cleanall"/>

+   <target name="UefiBootServicesTableLib_clean">

+      <OutputDirSetup baseName="UefiBootServicesTableLib" mbdFilename="${MODULE_DIR}/UefiBootServicesTableLib.mbd" msaFilename="${MODULE_DIR}/UefiBootServicesTableLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiBootServicesTableLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiBootServicesTableLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiBootServicesTableLib_cleanall">

+      <OutputDirSetup baseName="UefiBootServicesTableLib" mbdFilename="${MODULE_DIR}/UefiBootServicesTableLib.mbd" msaFilename="${MODULE_DIR}/UefiBootServicesTableLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiBootServicesTableLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiBootServicesTableLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiBootServicesTableLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiDebugLibConOut/DebugLib.c b/edk2/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
new file mode 100644
index 0000000..27d82b3
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
@@ -0,0 +1,247 @@
+/** @file

+  UEFI Debug Library that uses PrintLib to send messages to CONOUT.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+//

+// Define the maximum debug and assert message length that this library supports 

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+

+/**

+

+  Prints a debug message to the debug output device if the specified error level is enabled.

+

+  If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print 

+  the message specified by Format and the associated variable argument list to 

+  the debug output device.

+

+  If Format is NULL, then ASSERT().

+

+  @param  ErrorLevel  The error level of the debug message.

+  @param  Format      Format string for the debug message to print.

+

+**/

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN        ErrorLevel,

+  IN  CONST CHAR8  *Format,

+  ...

+  )

+{

+  CHAR16   Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver debug mask value and global mask

+  //

+  if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+    return;

+  }

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrintAsciiFormat (Buffer, sizeof (Buffer), Format, Marker);

+  VA_END (Marker);

+

+  //

+  // Send the print string to the Console Output device

+  //

+  if (gST->ConOut != NULL) {

+    gST->ConOut->OutputString (gST->ConOut, Buffer);

+  }

+}

+

+

+/**

+

+  Prints an assert message containing a filename, line number, and description.  

+  This may be followed by a breakpoint or a dead loop.

+

+  Print a message of the form “ASSERT <FileName>(<LineNumber>): <Description>\n” 

+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 

+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 

+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 

+  CpuDeadLoop() is called.  If neither of these bits are set, then this function 

+  returns immediately after the message is printed to the debug output device.

+  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while

+  processing another DebugAssert(), then DebugAssert() must return immediately.

+

+  If FileName is NULL, then a <FileName> string of “(NULL) Filename” is printed.

+

+  If Description is NULL, then a <Description> string of “(NULL) Description” is printed.

+

+  @param  FileName     Pointer to the name of the source file that generated the assert condition.

+  @param  LineNumber   The line number in the source file that generated the assert condition

+  @param  Description  Pointer to the description of the assert condition.

+

+**/

+VOID

+EFIAPI

+DebugAssert (

+  IN CONST CHAR8  *FileName,

+  IN INTN         LineNumber,

+  IN CONST CHAR8  *Description

+  )

+{

+  CHAR16  Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  UnicodeSPrintAsciiFormat (Buffer, sizeof (Buffer), "ASSERT %s(%d): %s\n", FileName, LineNumber, Description);

+

+  //

+  // Send the print string to the Console Output device

+  //

+  if (gST->ConOut != NULL) {

+    gST->ConOut->OutputString (gST->ConOut, Buffer);

+  }

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param   Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param   Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  

+  Returns TRUE if ASSERT() macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CODE()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.mbd b/edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.mbd
new file mode 100644
index 0000000..12032d4
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiDebugLibConOut</BaseName>

+    <Guid>5cddfaf3-e9a7-4d16-bdce-1e002df475bb</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.msa b/edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.msa
new file mode 100644
index 0000000..1f396a4
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.msa
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiDebugLibConOut</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>5cddfaf3-e9a7-4d16-bdce-1e002df475bb</Guid>

+    <Version>0</Version>

+    <Abstract>Debug Library for UEFI drivers</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiDebugLibConOut/build.xml b/edk2/MdePkg/Library/UefiDebugLibConOut/build.xml
new file mode 100644
index 0000000..e70683c
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibConOut/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiDebugLibConOut"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiDebugLibConOut"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiDebugLibConOut">

+      <GenBuild baseName="UefiDebugLibConOut" mbdFilename="${MODULE_DIR}/UefiDebugLibConOut.mbd" msaFilename="${MODULE_DIR}/UefiDebugLibConOut.msa"/>

+   </target>

+   <target depends="UefiDebugLibConOut_clean" name="clean"/>

+   <target depends="UefiDebugLibConOut_cleanall" name="cleanall"/>

+   <target name="UefiDebugLibConOut_clean">

+      <OutputDirSetup baseName="UefiDebugLibConOut" mbdFilename="${MODULE_DIR}/UefiDebugLibConOut.mbd" msaFilename="${MODULE_DIR}/UefiDebugLibConOut.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDebugLibConOut_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDebugLibConOut_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiDebugLibConOut_cleanall">

+      <OutputDirSetup baseName="UefiDebugLibConOut" mbdFilename="${MODULE_DIR}/UefiDebugLibConOut.mbd" msaFilename="${MODULE_DIR}/UefiDebugLibConOut.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDebugLibConOut_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDebugLibConOut_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiDebugLibConOut*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c b/edk2/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
new file mode 100644
index 0000000..18f651c
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
@@ -0,0 +1,247 @@
+/** @file

+  UEFI Debug Library that uses PrintLib to send messages to STDERR.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+**/

+

+//

+// Define the maximum debug and assert message length that this library supports 

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+

+/**

+

+  Prints a debug message to the debug output device if the specified error level is enabled.

+

+  If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print 

+  the message specified by Format and the associated variable argument list to 

+  the debug output device.

+

+  If Format is NULL, then ASSERT().

+

+  @param  ErrorLevel  The error level of the debug message.

+  @param  Format      Format string for the debug message to print.

+

+**/

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN        ErrorLevel,

+  IN  CONST CHAR8  *Format,

+  ...

+  )

+{

+  CHAR16   Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver debug mask value and global mask

+  //

+  if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+    return;

+  }

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrintAsciiFormat (Buffer, sizeof (Buffer), Format, Marker);

+  VA_END (Marker);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  if (gST->StdErr != NULL) {

+    gST->StdErr->OutputString (gST->StdErr, Buffer);

+  }

+}

+

+

+/**

+

+  Prints an assert message containing a filename, line number, and description.  

+  This may be followed by a breakpoint or a dead loop.

+

+  Print a message of the form “ASSERT <FileName>(<LineNumber>): <Description>\n” 

+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 

+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 

+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 

+  CpuDeadLoop() is called.  If neither of these bits are set, then this function 

+  returns immediately after the message is printed to the debug output device.

+  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while

+  processing another DebugAssert(), then DebugAssert() must return immediately.

+

+  If FileName is NULL, then a <FileName> string of “(NULL) Filename” is printed.

+

+  If Description is NULL, then a <Description> string of “(NULL) Description” is printed.

+

+  @param  FileName     Pointer to the name of the source file that generated the assert condition.

+  @param  LineNumber   The line number in the source file that generated the assert condition

+  @param  Description  Pointer to the description of the assert condition.

+

+**/

+VOID

+EFIAPI

+DebugAssert (

+  IN CONST CHAR8  *FileName,

+  IN INTN         LineNumber,

+  IN CONST CHAR8  *Description

+  )

+{

+  CHAR16  Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  UnicodeSPrintAsciiFormat (Buffer, sizeof (Buffer), "ASSERT %s(%d): %s\n", FileName, LineNumber, Description);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  if (gST->StdErr != NULL) {

+    gST->StdErr->OutputString (gST->StdErr, Buffer);

+  }

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by 

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS – Buffer + 1), then ASSERT(). 

+

+  @param   Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param   Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  

+  Returns TRUE if ASSERT() macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CODE()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**

+  

+  Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of 

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.mbd b/edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.mbd
new file mode 100644
index 0000000..ecec5af
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiDebugLibStdErr</BaseName>

+    <Guid>b57a1df6-ffdb-4247-a3df-3a562176751a</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.msa b/edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.msa
new file mode 100644
index 0000000..e894c58
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.msa
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiDebugLibStdErr</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>b57a1df6-ffdb-4247-a3df-3a562176751a</Guid>

+    <Version>0</Version>

+    <Abstract>Debug Library for UEFI drivers</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">PcdLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DebugLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <PCDs>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+    </PcdData>

+    <PcdData ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+    </PcdData>

+  </PCDs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiDebugLibStdErr/build.xml b/edk2/MdePkg/Library/UefiDebugLibStdErr/build.xml
new file mode 100644
index 0000000..f3c02f0
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDebugLibStdErr/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiDebugLibStdErr"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiDebugLibStdErr"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiDebugLibStdErr">

+      <GenBuild baseName="UefiDebugLibStdErr" mbdFilename="${MODULE_DIR}/UefiDebugLibStdErr.mbd" msaFilename="${MODULE_DIR}/UefiDebugLibStdErr.msa"/>

+   </target>

+   <target depends="UefiDebugLibStdErr_clean" name="clean"/>

+   <target depends="UefiDebugLibStdErr_cleanall" name="cleanall"/>

+   <target name="UefiDebugLibStdErr_clean">

+      <OutputDirSetup baseName="UefiDebugLibStdErr" mbdFilename="${MODULE_DIR}/UefiDebugLibStdErr.mbd" msaFilename="${MODULE_DIR}/UefiDebugLibStdErr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDebugLibStdErr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDebugLibStdErr_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiDebugLibStdErr_cleanall">

+      <OutputDirSetup baseName="UefiDebugLibStdErr" mbdFilename="${MODULE_DIR}/UefiDebugLibStdErr.mbd" msaFilename="${MODULE_DIR}/UefiDebugLibStdErr.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDebugLibStdErr_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDebugLibStdErr_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiDebugLibStdErr*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c b/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
new file mode 100644
index 0000000..1b1376e
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
@@ -0,0 +1,431 @@
+/** @file

+  Device Path services. The thing to remember is device paths are built out of

+  nodes. The device path is terminated by an end node that is length

+  sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)

+  all over this file.

+

+  The only place where multi-instance device paths are supported is in

+  environment varibles. Multi-instance device paths should never be placed

+  on a Handle.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. 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.             

+

+  Module Name:  UefiDevicePathLib.c

+

+**/

+

+/**

+  This function returns the size, in bytes, 

+  of the device path data structure specified by DevicePath.

+  If DevicePath is NULL, then 0 is returned.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @return The size of a device path in bytes.

+

+**/

+UINTN

+EFIAPI

+GetDevicePathSize (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;

+

+  if (DevicePath == NULL) {

+    return 0;

+  }

+

+  //

+  // Search for the end of the device path structure

+  //

+  Start = DevicePath;

+  while (!EfiIsDevicePathEnd (DevicePath)) {

+    DevicePath = EfiNextDevicePathNode (DevicePath);

+  }

+

+  //

+  // Compute the size and add back in the size of the end device path structure

+  //

+  return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);

+}

+

+/**

+  This function allocates space for a new copy of the device path

+  specified by DevicePath.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @return The duplicated device path.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+DuplicateDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  UINTN                     Size;

+

+  //

+  // Compute the size

+  //

+  Size = GetDevicePathSize (DevicePath);

+  if (Size == 0) {

+    return NULL;

+  }

+

+  //

+  // Allocate space for duplicate device path

+  //

+  NewDevicePath = AllocateCopyPool (Size, DevicePath);

+

+  return NewDevicePath;

+}

+

+/**

+  This function appends the device path SecondDevicePath

+  to every device path instance in FirstDevicePath. 

+

+  @param  FirstDevicePath A pointer to a device path data structure.

+  

+  @param  SecondDevicePath A pointer to a device path data structure.

+

+  @return A pointer to the new device path is returned.

+  NULL is returned if space for the new device path could not be allocated from pool.

+  It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath

+  if they are no longer needed.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath

+  )

+{

+  UINTN                     Size;

+  UINTN                     Size1;

+  UINTN                     Size2;

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath2;

+

+  //

+  // If there's only 1 path, just duplicate it

+  //

+  if (FirstDevicePath == NULL) {

+    return DuplicateDevicePath (SecondDevicePath);

+  }

+

+  if (SecondDevicePath == NULL) {

+    return DuplicateDevicePath (FirstDevicePath);

+  }

+

+  //

+  // Allocate space for the combined device path. It only has one end node of

+  // length EFI_DEVICE_PATH_PROTOCOL

+  //

+  Size1         = GetDevicePathSize (FirstDevicePath);

+  Size2         = GetDevicePathSize (SecondDevicePath);

+  Size          = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);

+

+  NewDevicePath = AllocatePool (Size);

+

+  if (NewDevicePath != NULL) {

+    NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1);

+    //

+    // Over write Src1 EndNode and do the copy

+    //

+    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));

+    CopyMem (DevicePath2, SecondDevicePath, Size2);

+  }

+

+  return NewDevicePath;

+}

+

+/**

+  This function appends the device path node SecondDevicePath

+  to every device path instance in FirstDevicePath.

+

+  @param  DevicePath A pointer to a device path data structure.

+  

+  @param  DevicePathNode A pointer to a single device path node.

+

+  @return A pointer to the new device path.

+  If there is not enough temporary pool memory available to complete this function,

+  then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePathNode (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *NextNode;

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  UINTN                     NodeLength;

+

+  //

+  // Build a Node that has a terminator on it

+  //

+  NodeLength = DevicePathNodeLength (DevicePathNode);

+

+  TempDevicePath = AllocatePool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL));

+  if (TempDevicePath == NULL) {

+    return NULL;

+  }

+  TempDevicePath = CopyMem (TempDevicePath, DevicePathNode, NodeLength);

+  //

+  // Add and end device path node to convert Node to device path

+  //

+  NextNode = NextDevicePathNode (TempDevicePath);

+  SetDevicePathEndNode (NextNode);

+  //

+  // Append device paths

+  //

+  NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);

+

+  FreePool (TempDevicePath);

+

+  return NewDevicePath;

+}

+

+/**

+  This function appends the device path instance Instance to the device path Source.

+  If Source is NULL, then a new device path with one instance is created.  

+

+  @param  Source A pointer to a device path data structure.

+  @param  Instance A pointer to a device path instance.

+

+  @return A pointer to the new device path.

+  If there is not enough temporary pool memory available to complete this function,

+  then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Source,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Instance

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  UINTN                     SrcSize;

+  UINTN                     InstanceSize;

+

+  if (Source == NULL) {

+    return DuplicateDevicePath (Instance);

+  }

+

+  SrcSize       = GetDevicePathSize (Source);

+  InstanceSize  = GetDevicePathSize (Instance);

+

+  NewDevicePath = AllocatePool (SrcSize + InstanceSize);

+  if (NewDevicePath != NULL) {

+    

+    DevicePath = CopyMem (NewDevicePath, Source, SrcSize);;

+ 

+    while (!IsDevicePathEnd (DevicePath)) {

+      DevicePath = NextDevicePathNode (DevicePath);

+    }

+    

+    DevicePath->SubType  = END_INSTANCE_DEVICE_PATH_SUBTYPE;

+

+    DevicePath           = NextDevicePathNode (DevicePath);

+    CopyMem (DevicePath, Instance, InstanceSize);

+  }

+

+  return NewDevicePath;

+}

+

+/**

+  Function retrieves the next device path instance from a device path data structure.

+

+  @param  DevicePath A pointer to a device path data structure.

+  

+  @param  Size A pointer to the size of a device path instance in bytes.

+

+  @return This function returns a pointer to the current device path instance.

+  In addition, it returns the size in bytes of the current device path instance in Size,

+  and a pointer to the next device path instance in DevicePath.

+  If there are no more device path instances in DevicePath, then DevicePath will be set to NULL.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+GetNextDevicePathInstance (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,

+     OUT UINTN                     *Size

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;

+  EFI_DEVICE_PATH_PROTOCOL  *ReturnValue;

+  UINT8                     Temp;

+

+  ASSERT (DevicePath != NULL);

+  ASSERT (Size != NULL);

+  if (*DevicePath == NULL) {

+    *Size = 0;

+    return NULL;

+  }

+

+  //

+  // Find the end of the device path instance

+  //

+  DevPath = *DevicePath;

+  while (!IsDevicePathEndType (DevPath)) {

+    DevPath = NextDevicePathNode (DevPath);

+  }

+

+  //

+  // Compute the size of the device path instance

+  //

+  *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);

+ 

+  //

+  // Make a copy and return the device path instance

+  //

+  Temp              = DevPath->SubType;

+  DevPath->SubType  = END_ENTIRE_DEVICE_PATH_SUBTYPE;

+  ReturnValue       = DuplicateDevicePath (*DevicePath);

+  DevPath->SubType  = Temp;

+

+  //

+  // If DevPath is the end of an entire device path, then another instance

+  // does not follow, so *DevicePath is set to NULL.

+  //

+  if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {

+    *DevicePath = NULL;

+  } else {

+    *DevicePath = NextDevicePathNode (DevPath);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Return TRUE is this is a multi instance device path.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @retval  TRUE If DevicePath is multi-instance.

+  @retval  FALSE If DevicePath is not multi-instance or DevicePath is NULL.

+

+**/

+BOOLEAN

+EFIAPI

+IsDevicePathMultiInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  CONST EFI_DEVICE_PATH_PROTOCOL  *Node;

+

+  if (DevicePath == NULL) {

+    return FALSE;

+  }

+

+  Node = DevicePath;

+  while (!EfiIsDevicePathEnd (Node)) {

+    if (EfiIsDevicePathEndInstance (Node)) {

+      return TRUE;

+    }

+

+    Node = EfiNextDevicePathNode (Node);

+  }

+

+  return FALSE;

+}

+

+/**

+  This function retrieves the device path protocol from a handle.

+

+  @param  Handle The handle from which to retrieve the device path protocol.

+

+  @return This function returns the device path protocol from the handle specified by Handle.

+  If Handle is NULL or Handle does not contain a device path protocol, then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+DevicePathFromHandle (

+  IN EFI_HANDLE  Handle

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_STATUS                Status;

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID *) &DevicePath

+                  );

+  if (EFI_ERROR (Status)) {

+    DevicePath = NULL;

+  }

+  return DevicePath;

+}

+

+/**

+  This function allocates a device path for a file and appends it to an existing device path.

+

+  @param  Device A pointer to a device handle.  This parameter is optional and may be NULL.

+  @param  FileName A pointer to a Null-terminated Unicode string.

+

+  @return If Device is a valid device handle that contains a device path protocol,

+  then a device path for the file specified by FileName is allocated

+  and appended to the device path associated with the handle Device. The allocated device path is returned.

+  If Device is NULL or Device is a handle that does not support the device path protocol,

+  then a device path containing a single device path node for the file specified by FileName

+  is allocated and returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+FileDevicePath (

+  IN EFI_HANDLE    Device,     OPTIONAL

+  IN CONST CHAR16  *FileName

+  )

+{

+  UINTN                     FileNameSize;

+  UINTN                     FilePathNodeSize;

+  FILEPATH_DEVICE_PATH      *FilePathNode;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+

+  DevicePath        = NULL;

+

+  FileNameSize      = StrSize (FileName);

+  FilePathNodeSize  = FileNameSize + SIZE_OF_FILEPATH_DEVICE_PATH;

+  FilePathNode      = AllocatePool (FilePathNodeSize);

+  if (FilePathNode != NULL) {

+    //

+    // Build a file path node

+    //

+    FilePathNode->Header.Type     = MEDIA_DEVICE_PATH;

+    FilePathNode->Header.SubType  = MEDIA_FILEPATH_DP;

+    SetDevicePathNodeLength (&FilePathNode->Header, FilePathNodeSize);

+    CopyMem (FilePathNode->PathName, FileName, FileNameSize);

+ 

+    //

+    // Append file path node to device's device path

+    //

+    if (Device != NULL) {

+      DevicePath = DevicePathFromHandle (Device);

+    }

+    DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) FilePathNode);

+    FreePool (FilePathNode);

+  }

+  return DevicePath;

+}

+

diff --git a/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.mbd b/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.mbd
new file mode 100644
index 0000000..dc69382
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiDevicePathLib</BaseName>

+    <Guid>91c1677a-e57f-4191-8b8e-eb7711a716e0</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 16:52</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.msa b/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.msa
new file mode 100644
index 0000000..d925592
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.msa
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiDevicePathLib</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>91c1677a-e57f-4191-8b8e-eb7711a716e0</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification </Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-13 16:52</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DevicePathLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UefiDevicePathLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePath</Protocol>

+  </Protocols>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiDevicePathLib/build.xml b/edk2/MdePkg/Library/UefiDevicePathLib/build.xml
new file mode 100644
index 0000000..acfbb9a
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiDevicePathLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiDevicePathLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiDevicePathLib">

+      <GenBuild baseName="UefiDevicePathLib" mbdFilename="${MODULE_DIR}/UefiDevicePathLib.mbd" msaFilename="${MODULE_DIR}/UefiDevicePathLib.msa"/>

+   </target>

+   <target depends="UefiDevicePathLib_clean" name="clean"/>

+   <target depends="UefiDevicePathLib_cleanall" name="cleanall"/>

+   <target name="UefiDevicePathLib_clean">

+      <OutputDirSetup baseName="UefiDevicePathLib" mbdFilename="${MODULE_DIR}/UefiDevicePathLib.mbd" msaFilename="${MODULE_DIR}/UefiDevicePathLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDevicePathLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDevicePathLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiDevicePathLib_cleanall">

+      <OutputDirSetup baseName="UefiDevicePathLib" mbdFilename="${MODULE_DIR}/UefiDevicePathLib.mbd" msaFilename="${MODULE_DIR}/UefiDevicePathLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDevicePathLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDevicePathLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiDevicePathLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
new file mode 100644
index 0000000..aea75aa
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
@@ -0,0 +1,274 @@
+/** @file

+  UEFI Device Path Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  UefiDevicePathLib.c

+

+**/

+

+STATIC EFI_DEVICE_PATH_UTILITIES_PROTOCOL          *mDevicePathUtilities = NULL;

+

+/**

+  The constructor function caches the pointer to DevicePathUtilites protocol.

+  

+  The constructor function locates DevicePathUtilities protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+DevicePathLibConstructor (

+  IN      EFI_HANDLE                ImageHandle,

+  IN      EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiDevicePathUtilitiesProtocolGuid,

+                  NULL,

+                  (VOID**) &mDevicePathUtilities

+                  );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mDevicePathUtilities != NULL);

+

+  return Status;

+}

+

+/**

+  This function returns the size, in bytes, 

+  of the device path data structure specified by DevicePath.

+  If DevicePath is NULL, then 0 is returned.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @return The size of a device path in bytes.

+

+**/

+UINTN

+EFIAPI

+GetDevicePathSize (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  return mDevicePathUtilities->GetDevicePathSize (DevicePath);

+}

+

+/**

+  This function allocates space for a new copy of the device path

+  specified by DevicePath.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @return The duplicated device path.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+DuplicateDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath

+  )

+{

+  return mDevicePathUtilities->DuplicateDevicePath (DevicePath);

+}

+

+/**

+  This function appends the device path SecondDevicePath

+  to every device path instance in FirstDevicePath. 

+

+  @param  FirstDevicePath A pointer to a device path data structure.

+  

+  @param  SecondDevicePath A pointer to a device path data structure.

+

+  @return A pointer to the new device path is returned.

+  NULL is returned if space for the new device path could not be allocated from pool.

+  It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath

+  if they are no longer needed.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePath (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath

+  )

+{

+  return mDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);

+}

+

+/**

+  This function appends the device path node SecondDevicePath

+  to every device path instance in FirstDevicePath.

+

+  @param  FirstDevicePath A pointer to a device path data structure.

+  

+  @param  SecondDevicePath A pointer to a single device path node.

+

+  @return A pointer to the new device path.

+  If there is not enough temporary pool memory available to complete this function,

+  then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePathNode (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath

+  )

+{

+  return mDevicePathUtilities->AppendDeviceNode (FirstDevicePath, SecondDevicePath);

+}

+

+/**

+  This function appends the device path instance Instance to the device path Source.

+  If Source is NULL, then a new device path with one instance is created.  

+

+  @param  Source A pointer to a device path data structure.

+  @param  Instance A pointer to a device path instance.

+

+  @return A pointer to the new device path.

+  If there is not enough temporary pool memory available to complete this function,

+  then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Source,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *Instance

+  )

+{

+  return mDevicePathUtilities->AppendDevicePathInstance (Source, Instance);

+}

+

+/**

+  Function retrieves the next device path instance from a device path data structure.

+

+  @param  DevicePath A pointer to a device path data structure.

+  

+  @param  Size A pointer to the size of a device path instance in bytes.

+

+  @return This function returns a pointer to the current device path instance.

+  In addition, it returns the size in bytes of the current device path instance in Size,

+  and a pointer to the next device path instance in DevicePath.

+  If there are no more device path instances in DevicePath, then DevicePath will be set to NULL.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+GetNextDevicePathInstance (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,

+     OUT UINTN                     *Size

+  )

+{

+  ASSERT (DevicePath != NULL);

+  ASSERT (Size != NULL);

+  return mDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);

+}

+

+/**

+  Return TRUE is this is a multi instance device path.

+

+  @param  DevicePath A pointer to a device path data structure.

+

+  @retval  TRUE If DevicePath is multi-instance.

+  @retval  FALSE If DevicePath is not multi-instance or DevicePath is NULL.

+

+**/

+BOOLEAN

+EFIAPI

+IsDevicePathMultiInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  return mDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);

+}

+

+/**

+  This function retrieves the device path protocol from a handle.

+

+  @param  Handle The handle from which to retrieve the device path protocol.

+

+  @return This function returns the device path protocol from the handle specified by Handle.

+  If Handle is NULL or Handle does not contain a device path protocol, then NULL is returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+DevicePathFromHandle (

+  IN EFI_HANDLE  Handle

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_STATUS                Status;

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID *) &DevicePath

+                  );

+  if (EFI_ERROR (Status)) {

+    DevicePath = NULL;

+  }

+  return DevicePath;

+}

+

+/**

+  This function allocates a device path for a file and appends it to an existing device path.

+

+  @param  Device A pointer to a device handle.  This parameter is optional and may be NULL.

+  @param  FileName A pointer to a Null-terminated Unicode string.

+

+  @return If Device is a valid device handle that contains a device path protocol,

+  then a device path for the file specified by FileName is allocated

+  and appended to the device path associated with the handle Device. The allocated device path is returned.

+  If Device is NULL or Device is a handle that does not support the device path protocol,

+  then a device path containing a single device path node for the file specified by FileName

+  is allocated and returned.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+FileDevicePath (

+  IN EFI_HANDLE    Device,     OPTIONAL

+  IN CONST CHAR16  *FileName

+  )

+{

+  UINTN                     Size;

+  FILEPATH_DEVICE_PATH      *FilePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *FileDevicePathNode;

+

+  DevicePath = NULL;

+

+  Size = StrSize (FileName);

+  FileDevicePathNode = mDevicePathUtilities->CreateDeviceNode (

+                                               MEDIA_DEVICE_PATH,

+                                               MEDIA_FILEPATH_DP,

+                                               (UINT16) (Size + SIZE_OF_FILEPATH_DEVICE_PATH)

+                                               );

+  if (FileDevicePathNode != NULL) {

+    FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePathNode;

+    CopyMem (&FilePath->PathName, FileName, Size);

+    if (Device != NULL) {

+      DevicePath = DevicePathFromHandle (Device);

+    }

+    DevicePath = AppendDevicePathNode (DevicePath, FileDevicePathNode);

+    FreePool (FileDevicePathNode);

+  }

+  return DevicePath;

+}

+

diff --git a/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.mbd b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.mbd
new file mode 100644
index 0000000..f975a6c
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiDevicePathLibDevicePathProtocol</BaseName>

+    <Guid>050EB8C6-C12E-4b86-892B-40985E8B3137</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-30 10:05</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.msa b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.msa
new file mode 100644
index 0000000..2c69aa0
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.msa
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiDevicePathLibDevicePathProtocol</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>050EB8C6-C12E-4b86-892B-40985E8B3137</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00020000</Version>

+    <Abstract>Device Path Library</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-30 10:05</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">DevicePathLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UefiDevicePathLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DevicePathUtilities</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>DevicePathLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/build.xml b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/build.xml
new file mode 100644
index 0000000..a6b1dbb
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiDevicePathLibDevicePathProtocol"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiDevicePathLibDevicePathProtocol"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiDevicePathLibDevicePathProtocol">

+      <GenBuild baseName="UefiDevicePathLibDevicePathProtocol" mbdFilename="${MODULE_DIR}/UefiDevicePathLibDevicePathProtocol.mbd" msaFilename="${MODULE_DIR}/UefiDevicePathLibDevicePathProtocol.msa"/>

+   </target>

+   <target depends="UefiDevicePathLibDevicePathProtocol_clean" name="clean"/>

+   <target depends="UefiDevicePathLibDevicePathProtocol_cleanall" name="cleanall"/>

+   <target name="UefiDevicePathLibDevicePathProtocol_clean">

+      <OutputDirSetup baseName="UefiDevicePathLibDevicePathProtocol" mbdFilename="${MODULE_DIR}/UefiDevicePathLibDevicePathProtocol.mbd" msaFilename="${MODULE_DIR}/UefiDevicePathLibDevicePathProtocol.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDevicePathLibDevicePathProtocol_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDevicePathLibDevicePathProtocol_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiDevicePathLibDevicePathProtocol_cleanall">

+      <OutputDirSetup baseName="UefiDevicePathLibDevicePathProtocol" mbdFilename="${MODULE_DIR}/UefiDevicePathLibDevicePathProtocol.mbd" msaFilename="${MODULE_DIR}/UefiDevicePathLibDevicePathProtocol.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDevicePathLibDevicePathProtocol_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDevicePathLibDevicePathProtocol_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiDevicePathLibDevicePathProtocol*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c b/edk2/MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c
new file mode 100644
index 0000000..60177bc
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c
@@ -0,0 +1,137 @@
+/** @file

+  Entry point to a EFI/DXE driver.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.

+

+**/

+

+/**

+  Unload function that is registered in the LoadImage protocol.  It un-installs

+  protocols produced and deallocates pool used by the driver.  Called by the core

+  when unloading the driver.

+

+  @param  ImageHandle

+

+  @retval EFI_SUCCESS

+

+**/

+EFI_STATUS

+EFIAPI

+_DriverUnloadHandler (

+  EFI_HANDLE ImageHandle

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // If an UnloadImage() handler is specified, then call it

+  //

+  Status = ProcessModuleUnloadList (ImageHandle);

+

+  //

+  // If the driver specific unload handler does not return an error, then call all of the

+  // library destructors.  If the unload handler returned an error, then the driver can not be

+  // unloaded, and the library destructors should not be called

+  //

+  if (!EFI_ERROR (Status)) {

+    ProcessLibraryDestructorList (ImageHandle, gST);

+  }

+

+  //

+  // Return the status from the driver specific unload handler

+  //

+  return Status;

+}

+

+/**

+  Enrty point to DXE Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                 Status;

+  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;

+

+  if (_gUefiDriverRevision != 0) {

+    //

+    // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver

+    //

+    if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {

+      return EFI_INCOMPATIBLE_VERSION;

+    }

+  }

+

+  //

+  // Call constructor for all libraries

+  //

+  ProcessLibraryConstructorList (ImageHandle, SystemTable);

+

+  //

+  //  Install unload handler...

+  //

+  if (_gDriverUnloadImageCount != 0) {

+    Status = gBS->HandleProtocol (

+                    ImageHandle,

+                    &gEfiLoadedImageProtocolGuid,

+                    (VOID **)&LoadedImage

+                    );

+    ASSERT_EFI_ERROR (Status);

+    LoadedImage->Unload = _DriverUnloadHandler;

+  }

+

+  //

+  // Call the driver entry point

+  //

+  Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);

+

+  //

+  // If all of the drivers returned errors, then invoke all of the library destructors

+  //

+  if (EFI_ERROR (Status)) {

+    ProcessLibraryDestructorList (ImageHandle, SystemTable);

+  }

+

+  //

+  // Return the cummalative return status code from all of the driver entry points

+  //

+  return Status;

+}

+

+

+/**

+  Enrty point wrapper of DXE Driver.

+

+  @param  ImageHandle ImageHandle of the loaded driver.

+  @param  SystemTable Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.

+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return _ModuleEntryPoint (ImageHandle, SystemTable);

+}

diff --git a/edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.mbd b/edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.mbd
new file mode 100644
index 0000000..d41abe2
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiDriverEntryPoint</BaseName>

+    <Guid>331deb15-454b-48d8-9b74-70d01f3f3556</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.msa b/edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.msa
new file mode 100644
index 0000000..43e37c5
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.msa
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiDriverEntryPoint</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>331deb15-454b-48d8-9b74-70d01f3f3556</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiDriverEntryPoint</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>DriverEntryPoint.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>

+  </Protocols>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiDriverEntryPoint/build.xml b/edk2/MdePkg/Library/UefiDriverEntryPoint/build.xml
new file mode 100644
index 0000000..ac6a598
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverEntryPoint/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiDriverEntryPoint"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiDriverEntryPoint"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiDriverEntryPoint">

+      <GenBuild baseName="UefiDriverEntryPoint" mbdFilename="${MODULE_DIR}/UefiDriverEntryPoint.mbd" msaFilename="${MODULE_DIR}/UefiDriverEntryPoint.msa"/>

+   </target>

+   <target depends="UefiDriverEntryPoint_clean" name="clean"/>

+   <target depends="UefiDriverEntryPoint_cleanall" name="cleanall"/>

+   <target name="UefiDriverEntryPoint_clean">

+      <OutputDirSetup baseName="UefiDriverEntryPoint" mbdFilename="${MODULE_DIR}/UefiDriverEntryPoint.mbd" msaFilename="${MODULE_DIR}/UefiDriverEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDriverEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDriverEntryPoint_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiDriverEntryPoint_cleanall">

+      <OutputDirSetup baseName="UefiDriverEntryPoint" mbdFilename="${MODULE_DIR}/UefiDriverEntryPoint.mbd" msaFilename="${MODULE_DIR}/UefiDriverEntryPoint.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDriverEntryPoint_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDriverEntryPoint_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiDriverEntryPoint*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.c b/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.c
new file mode 100644
index 0000000..9b96f28
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.c
@@ -0,0 +1,405 @@
+/** @file

+  EFI Driver Model Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  EfiDriverModelLib.c

+

+**/

+

+

+

+/**

+**/

+EFI_STATUS

+UefiDriverModelLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                   Status;

+  UINTN                        Index;

+  EFI_HANDLE                   DriverBindingHandle;

+  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;

+

+  //

+  // If no Driver Binding Protocols are advertised by the driver then simply return

+  //

+  if (_gDriverModelProtocolListEntries == 0) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Install the first Driver Bindng Protocol onto ImageHandle

+  //

+  DriverBindingHandle = ImageHandle;

+

+  //

+  // See if onle one Driver Binding Protocol is advertised by the driver

+  //

+  if (_gDriverModelProtocolListEntries == 1) {

+    //

+    // The Driver Binding Protocol must never be NULL

+    //

+    ASSERT(_gDriverModelProtocolList[0].DriverBinding != NULL);

+

+    //

+    // Check for all 8 possible combinations of the ComponentName, DriverConfiguration, and DriverDiagnostics Protocol

+    // These are all checks against const pointers, so the optimizing compiler will only select one of the 

+    // calls to InstallMultipleProtocolInterfaces()

+    //

+    if (_gDriverModelProtocolList[0].DriverDiagnostics == NULL) {

+      if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          NULL

+                          );

+        } else {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          NULL

+                          );

+        }

+      } else {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          NULL

+                          );

+        } else {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid,       (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          NULL

+                          );

+        }

+      }

+    } else {

+      if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,     (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        } else {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,     (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid,     (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        }

+      } else {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          &gEfiDriverDiagnosticsProtocolGuid,   (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        } else {

+          Status = gBS->InstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid,       (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          &gEfiDriverDiagnosticsProtocolGuid,   (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        }

+      }

+    }

+

+    //

+    // ASSERT if the call to InstallMultipleProtocolInterfaces() failed

+    //

+    ASSERT_EFI_ERROR (Status);

+

+    //

+    // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol

+    //

+    DriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding;

+    DriverBinding->ImageHandle         = ImageHandle;

+    DriverBinding->DriverBindingHandle = DriverBindingHandle;

+

+  } else {

+    for (Index = 0; Index < _gDriverModelProtocolListEntries; Index++) {

+      //

+      // The Driver Binding Protocol must never be NULL

+      //

+      ASSERT(_gDriverModelProtocolList[Index].DriverBinding != NULL);

+

+      //

+      // Install the Driver Binding Protocol and ASSERT() if the installation fails

+      //

+      Status = gBS->InstallProtocolInterface (

+                      &DriverBindingHandle,

+                      &gEfiDriverBindingProtocolGuid,

+                      EFI_NATIVE_INTERFACE,

+                      (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding

+                      );

+      ASSERT_EFI_ERROR (Status);

+

+      //

+      // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol

+      //

+      DriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding;

+      DriverBinding->ImageHandle         = ImageHandle;

+      DriverBinding->DriverBindingHandle = DriverBindingHandle;

+

+      //

+      // If Component Name Protocol is specified then install it and ASSERT() if the installation fails

+      //

+      if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED) != 0) {

+        if (_gDriverModelProtocolList[Index].ComponentName != NULL) {

+          Status = gBS->InstallProtocolInterface (

+                          &DriverBindingHandle,

+                          &gEfiComponentNameProtocolGuid,

+                          EFI_NATIVE_INTERFACE,

+                          (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[Index].ComponentName

+                          );

+          ASSERT_EFI_ERROR (Status);

+        }

+      }

+

+      //

+      // If Driver Configuration Protocol is specified then install it and ASSERT() if the installation fails

+      //

+      if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED) != 0) {

+        if (_gDriverModelProtocolList[Index].DriverConfiguration != NULL) {

+          Status = gBS->InstallProtocolInterface (

+                          &DriverBindingHandle,

+                          &gEfiDriverConfigurationProtocolGuid,

+                          EFI_NATIVE_INTERFACE,

+                          (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[Index].DriverConfiguration

+                          );

+          ASSERT_EFI_ERROR (Status);

+        }

+      }

+

+      //

+      // If Driver Diagnostics Protocol is specified then install it and ASSERT() if the installation fails

+      //

+      if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED) != 0) {

+        if (_gDriverModelProtocolList[Index].DriverDiagnostics != NULL) {

+          Status = gBS->InstallProtocolInterface (

+                          &DriverBindingHandle,

+                          &gEfiDriverDiagnosticsProtocolGuid,

+                          EFI_NATIVE_INTERFACE,

+                          (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[Index].DriverDiagnostics

+                          );

+          ASSERT_EFI_ERROR (Status);

+        }

+      }

+

+      //

+      // Install subsequent Driver Bindng Protocols onto new handles

+      //

+      DriverBindingHandle = NULL;

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+**/

+EFI_STATUS

+UefiDriverModelLibDestructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+  EFI_HANDLE  DriverBindingHandle;

+

+  //

+  // If no Driver Binding Protocols are advertised by the driver then simply return

+  //

+  if (_gDriverModelProtocolListEntries == 0) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // See if onle one Driver Binding Protocol is advertised by the driver

+  //

+  if (_gDriverModelProtocolListEntries == 1) {

+    //

+    // The Driver Binding Protocol must never be NULL

+    //

+    ASSERT(_gDriverModelProtocolList[0].DriverBinding != NULL);

+

+    //

+    // Retrieve the DriverBindingHandle from the Driver Binding Protocol

+    //

+    DriverBindingHandle = _gDriverModelProtocolList[0].DriverBinding->DriverBindingHandle;

+

+    //

+    // Check for all 8 possible combinations of the ComponentName, DriverConfiguration, and DriverDiagnostics Protocol

+    // These are all checks against const pointers, so the optimizing compiler will only select one of the 

+    // calls to InstallMultipleProtocolInterfaces()

+    //

+    if (_gDriverModelProtocolList[0].DriverDiagnostics == NULL) {

+      if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          NULL

+                          );

+        } else {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          NULL

+                          );

+        }

+      } else {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          NULL

+                          );

+        } else {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid,       (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          NULL

+                          );

+        }

+      }

+    } else {

+      if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,     (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        } else {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,     (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid,     (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        }

+      } else {

+        if (_gDriverModelProtocolList[0].ComponentName == NULL) {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          &gEfiDriverDiagnosticsProtocolGuid,   (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        } else {

+          Status = gBS->UninstallMultipleProtocolInterfaces (

+                          &DriverBindingHandle,

+                          &gEfiDriverBindingProtocolGuid,       (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,

+                          &gEfiComponentNameProtocolGuid,       (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,

+                          &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,

+                          &gEfiDriverDiagnosticsProtocolGuid,   (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,

+                          NULL

+                          );

+        }

+      }

+    }

+

+    //

+    // ASSERT if the call to UninstallMultipleProtocolInterfaces() failed

+    //

+    ASSERT_EFI_ERROR (Status);

+  } else {

+    for (Index = 0; Index < _gDriverModelProtocolListEntries; Index++) {

+      //

+      // The Driver Binding Protocol must never be NULL

+      //

+      ASSERT(_gDriverModelProtocolList[Index].DriverBinding != NULL);

+

+      //

+      // Retrieve the DriverBindingHandle from the Driver Binding Protocol

+      //

+      DriverBindingHandle = _gDriverModelProtocolList[0].DriverBinding->DriverBindingHandle;

+

+      //

+      // Uninstall the Driver Binding Protocol and ASSERT() if the installation fails

+      //

+      Status = gBS->UninstallProtocolInterface (

+                      DriverBindingHandle,

+                      &gEfiDriverBindingProtocolGuid,

+                      (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding

+                      );

+      ASSERT_EFI_ERROR (Status);

+

+      //

+      // If Component Name Protocol is specified then uninstall it and ASSERT() if the uninstallation fails

+      //

+      if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED) != 0) {

+        if (_gDriverModelProtocolList[Index].ComponentName != NULL) {

+          Status = gBS->UninstallProtocolInterface (

+                          DriverBindingHandle,

+                          &gEfiComponentNameProtocolGuid,

+                          (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[Index].ComponentName

+                          );

+          ASSERT_EFI_ERROR (Status);

+        }

+      }

+

+      //

+      // If Driver Configuration Protocol is specified then uninstall it and ASSERT() if the uninstallation fails

+      //

+      if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED) != 0) {

+        if (_gDriverModelProtocolList[Index].DriverConfiguration != NULL) {

+          Status = gBS->UninstallProtocolInterface (

+                          DriverBindingHandle,

+                          &gEfiDriverConfigurationProtocolGuid,

+                          (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[Index].DriverConfiguration

+                          );

+          ASSERT_EFI_ERROR (Status);

+        }

+      }

+

+      //

+      // If Driver Diagnostics Protocol is specified then uninstall it and ASSERT() if the uninstallation fails

+      //

+      if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED) != 0) {

+        if (_gDriverModelProtocolList[Index].DriverDiagnostics != NULL) {

+          Status = gBS->UninstallProtocolInterface (

+                          DriverBindingHandle,

+                          &gEfiDriverDiagnosticsProtocolGuid,

+                          (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[Index].DriverDiagnostics

+                          );

+          ASSERT_EFI_ERROR (Status);

+        }

+      }

+    }

+  }

+  return EFI_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.mbd b/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.mbd
new file mode 100644
index 0000000..6de82c1
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiDriverModelLib</BaseName>

+    <Guid>52af22ae-9901-4484-8cdc-622dd5838b09</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.msa b/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.msa
new file mode 100644
index 0000000..2bc1f9e
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverModelLib/UefiDriverModelLib.msa
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiDriverModelLib</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>52af22ae-9901-4484-8cdc-622dd5838b09</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiDriverModelLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UefiDriverModelLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Protocols>

+    <Protocol Usage="ALWAYS_CONSUMED">DriverBinding</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">ComponentName</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">DriverConfiguration</Protocol>

+    <Protocol Usage="ALWAYS_CONSUMED">DriverDiagnostics</Protocol>

+  </Protocols>

+  <Externs>

+    <Extern>

+      <Constructor>UefiDriverModelLibConstructor</Constructor>

+      <Destructor>UefiDriverModelLibDestructor</Destructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiDriverModelLib/build.xml b/edk2/MdePkg/Library/UefiDriverModelLib/build.xml
new file mode 100644
index 0000000..3210d27
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiDriverModelLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiDriverModelLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiDriverModelLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiDriverModelLib">

+      <GenBuild baseName="UefiDriverModelLib" mbdFilename="${MODULE_DIR}/UefiDriverModelLib.mbd" msaFilename="${MODULE_DIR}/UefiDriverModelLib.msa"/>

+   </target>

+   <target depends="UefiDriverModelLib_clean" name="clean"/>

+   <target depends="UefiDriverModelLib_cleanall" name="cleanall"/>

+   <target name="UefiDriverModelLib_clean">

+      <OutputDirSetup baseName="UefiDriverModelLib" mbdFilename="${MODULE_DIR}/UefiDriverModelLib.mbd" msaFilename="${MODULE_DIR}/UefiDriverModelLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDriverModelLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDriverModelLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiDriverModelLib_cleanall">

+      <OutputDirSetup baseName="UefiDriverModelLib" mbdFilename="${MODULE_DIR}/UefiDriverModelLib.mbd" msaFilename="${MODULE_DIR}/UefiDriverModelLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiDriverModelLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiDriverModelLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiDriverModelLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiLib/Console.c b/edk2/MdePkg/Library/UefiLib/Console.c
new file mode 100644
index 0000000..4fbdef7
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiLib/Console.c
@@ -0,0 +1,282 @@
+/** @file

+  Mde UEFI library functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  Console.c

+

+**/

+

+

+

+typedef struct {

+  CHAR16  WChar;

+  UINT32  Width;

+} UNICODE_WIDTH_ENTRY;

+

+UNICODE_WIDTH_ENTRY mUnicodeWidthTable[] = {

+  //

+  // General script area

+  //

+  {(CHAR16)0x1FFF,  1},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all narrow glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x007F,  1},       // C0 controls and basic Latin. 0x0000-0x007F

+  {(CHAR16)0x00FF,  1},       // C1 controls and Latin-1 support. 0x0080-0x00FF

+  {(CHAR16)0x017F,  1},       // Latin extended-A. 0x0100-0x017F

+  {(CHAR16)0x024F,  1},       // Latin extended-B. 0x0180-0x024F

+  {(CHAR16)0x02AF,  1},       // IPA extensions. 0x0250-0x02AF

+  {(CHAR16)0x02FF,  1},       // Spacing modifier letters. 0x02B0-0x02FF

+  {(CHAR16)0x036F,  1},       // Combining diacritical marks. 0x0300-0x036F

+  {(CHAR16)0x03FF,  1},       // Greek. 0x0370-0x03FF

+  {(CHAR16)0x04FF,  1},       // Cyrillic. 0x0400-0x04FF

+  {(CHAR16)0x052F,  0},       // Unassigned. As Armenian in ver3.0. 0x0500-0x052F

+  {(CHAR16)0x058F,  1},       // Armenian. 0x0530-0x058F

+  {(CHAR16)0x05FF,  1},       // Hebrew. 0x0590-0x05FF

+  {(CHAR16)0x06FF,  1},       // Arabic. 0x0600-0x06FF

+  {(CHAR16)0x08FF,  0},       // Unassigned. 0x0700-0x08FF

+  {(CHAR16)0x097F,  1},       // Devanagari. 0x0900-0x097F

+  {(CHAR16)0x09FF,  1},       // Bengali. 0x0980-0x09FF

+  {(CHAR16)0x0A7F,  1},       // Gurmukhi. 0x0A00-0x0A7F

+  {(CHAR16)0x0AFF,  1},       // Gujarati. 0x0A80-0x0AFF

+  {(CHAR16)0x0B7F,  1},       // Oriya. 0x0B00-0x0B7F

+  {(CHAR16)0x0BFF,  1},       // Tamil. (See page 7-92). 0x0B80-0x0BFF

+  {(CHAR16)0x0C7F,  1},       // Telugu. 0x0C00-0x0C7F

+  {(CHAR16)0x0CFF,  1},       // Kannada. (See page 7-100). 0x0C80-0x0CFF

+  {(CHAR16)0x0D7F,  1},       // Malayalam (See page 7-104). 0x0D00-0x0D7F

+  {(CHAR16)0x0DFF,  0},       // Unassigned. 0x0D80-0x0DFF

+  {(CHAR16)0x0E7F,  1},       // Thai. 0x0E00-0x0E7F

+  {(CHAR16)0x0EFF,  1},       // Lao. 0x0E80-0x0EFF

+  {(CHAR16)0x0FBF,  1},       // Tibetan. 0x0F00-0x0FBF

+  {(CHAR16)0x109F,  0},       // Unassigned. 0x0FC0-0x109F

+  {(CHAR16)0x10FF,  1},       // Georgian. 0x10A0-0x10FF

+  {(CHAR16)0x11FF,  1},       // Hangul Jamo. 0x1100-0x11FF

+  {(CHAR16)0x1DFF,  0},       // Unassigned. 0x1200-0x1DFF

+  {(CHAR16)0x1EFF,  1},       // Latin extended additional. 0x1E00-0x1EFF

+  {(CHAR16)0x1FFF,  1},       // Greek extended. 0x1F00-0x1FFF

+  *

+  */

+

+  //

+  // Symbol area

+  //

+  {(CHAR16)0x2FFF,  1},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all narrow glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x206F,  1},       // General punctuation. (See page7-154). 0x200-0x206F

+  {(CHAR16)0x209F,  1},       // Superscripts and subscripts. 0x2070-0x209F

+  {(CHAR16)0x20CF,  1},       // Currency symbols. 0x20A0-0x20CF

+  {(CHAR16)0x20FF,  1},       // Combining diacritical marks for symbols. 0x20D0-0x20FF

+  {(CHAR16)0x214F,  1},       // Letterlike sympbols. 0x2100-0x214F

+  {(CHAR16)0x218F,  1},       // Number forms. 0x2150-0x218F

+  {(CHAR16)0x21FF,  1},       // Arrows. 0x2190-0x21FF

+  {(CHAR16)0x22FF,  1},       // Mathematical operators. 0x2200-0x22FF

+  {(CHAR16)0x23FF,  1},       // Miscellaneous technical. 0x2300-0x23FF

+  {(CHAR16)0x243F,  1},       // Control pictures. 0x2400-0x243F

+  {(CHAR16)0x245F,  1},       // Optical character recognition. 0x2440-0x245F

+  {(CHAR16)0x24FF,  1},       // Enclosed alphanumerics. 0x2460-0x24FF

+  {(CHAR16)0x257F,  1},       // Box drawing. 0x2500-0x257F

+  {(CHAR16)0x259F,  1},       // Block elements. 0x2580-0x259F

+  {(CHAR16)0x25FF,  1},       // Geometric shapes. 0x25A0-0x25FF

+  {(CHAR16)0x26FF,  1},       // Miscellaneous symbols. 0x2600-0x26FF

+  {(CHAR16)0x27BF,  1},       // Dingbats. 0x2700-0x27BF

+  {(CHAR16)0x2FFF,  0},       // Reserved. 0x27C0-0x2FFF

+  *

+  */

+

+  //

+  // CJK phonetics and symbol area

+  //

+  {(CHAR16)0x33FF,  2},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all wide glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x303F,  2},       // CJK symbols and punctuation. 0x3000-0x303F

+  {(CHAR16)0x309F,  2},       // Hiragana. 0x3040-0x309F

+  {(CHAR16)0x30FF,  2},       // Katakana. 0x30A0-0x30FF

+  {(CHAR16)0x312F,  2},       // Bopomofo. 0x3100-0x312F

+  {(CHAR16)0x318F,  2},       // Hangul compatibility jamo. 0x3130-0x318F

+  {(CHAR16)0x319F,  2},       // Kanbun. 0x3190-0x319F

+  {(CHAR16)0x31FF,  0},       // Reserved. As Bopomofo extended in ver3.0. 0x31A0-0x31FF

+  {(CHAR16)0x32FF,  2},       // Enclosed CJK letters and months. 0x3200-0x32FF

+  {(CHAR16)0x33FF,  2},       // CJK compatibility. 0x3300-0x33FF

+  *

+  */

+

+  //

+  // CJK ideograph area

+  //

+  {(CHAR16)0x9FFF,  2},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all wide glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x4DFF,  0},       // Reserved. 0x3400-0x4DBF as CJK unified ideographs 

+                      // extension A in ver3.0. 0x3400-0x4DFF

+  {(CHAR16)0x9FFF,  2},       // CJK unified ideographs. 0x4E00-0x9FFF

+  *

+  */

+

+  //

+  // Reserved

+  //

+  {(CHAR16)0xABFF,  0},       // Reserved. 0xA000-0xA490 as Yi syllables. 0xA490-0xA4D0

+  // as Yi radicals in ver3.0. 0xA000-0xABFF

+  //

+  // Hangul syllables

+  //

+  {(CHAR16)0xD7FF,  2},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all wide glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0xD7A3,  2},       // Hangul syllables. 0xAC00-0xD7A3

+  {(CHAR16)0xD7FF,  0},       // Reserved. 0xD7A3-0xD7FF

+  *

+  */

+

+  //

+  // Surrogates area

+  //

+  {(CHAR16)0xDFFF,  0},       // Surrogates, not used now. 0xD800-0xDFFF

+

+  //

+  // Private use area

+  //

+  {(CHAR16)0xF8FF,  0},       // Private use area. 0xE000-0xF8FF

+

+  //

+  // Compatibility area and specials

+  //

+  {(CHAR16)0xFAFF,  2},       // CJK compatibility ideographs. 0xF900-0xFAFF

+  {(CHAR16)0xFB4F,  1},       // Alphabetic presentation forms. 0xFB00-0xFB4F

+  {(CHAR16)0xFDFF,  1},       // Arabic presentation forms-A. 0xFB50-0xFDFF

+  {(CHAR16)0xFE1F,  0},       // Reserved. As variation selectors in ver3.0. 0xFE00-0xFE1F

+  {(CHAR16)0xFE2F,  1},       // Combining half marks. 0xFE20-0xFE2F

+  {(CHAR16)0xFE4F,  2},       // CJK compatibility forms. 0xFE30-0xFE4F

+  {(CHAR16)0xFE6F,  1},       // Small Form Variants. 0xFE50-0xFE6F

+  {(CHAR16)0xFEFF,  1},       // Arabic presentation forms-B. 0xFE70-0xFEFF

+  {(CHAR16)0xFFEF,  1},       // Half width and full width forms. 0xFF00-0xFFEF

+  {(CHAR16)0xFFFF,  0},       // Speicials. 0xFFF0-0xFFFF

+};

+

+/**

+  This function computes and returns the width of the Unicode character 

+  specified by UnicodeChar.

+

+  @param  UnicodeChar   A Unicode character.

+

+  @retval 0             The width if UnicodeChar could not be determined.

+  @retval 1             UnicodeChar is a narrow glyph.

+  @retval 2             UnicodeChar is a wide glyph.

+

+**/

+UINTN

+EFIAPI

+GetGlyphWidth (

+  IN CHAR16  UnicodeChar

+  )

+{

+  UINTN               Index;

+  UINTN               Low;

+  UINTN               High;

+  UNICODE_WIDTH_ENTRY *Item;

+

+  Item  = NULL;

+  Low   = 0;

+  High  = (sizeof (mUnicodeWidthTable)) / (sizeof (UNICODE_WIDTH_ENTRY)) - 1;

+  while (Low <= High) {

+    Index = (Low + High) >> 1;

+    Item  = &(mUnicodeWidthTable[Index]);

+    if (Index == 0) {

+      if (UnicodeChar <= Item->WChar) {

+        break;

+      }

+

+      return 0;

+    }

+

+    if (UnicodeChar > Item->WChar) {

+      Low = Index + 1;

+    } else if (UnicodeChar <= mUnicodeWidthTable[Index - 1].WChar) {

+      High = Index - 1;

+    } else {

+      //

+      // Index - 1 < UnicodeChar <= Index. Found

+      //

+      break;

+    }

+  }

+

+  if (Low <= High) {

+    return Item->Width;

+  }

+

+  return 0;

+}

+

+/**

+  This function computes and returns the display length of

+  the Null-terminated Unicode string specified by String.

+  If String is NULL, then 0 is returned.

+  If any of the widths of the Unicode characters in String

+  can not be determined, then 0 is returned.

+

+  @param  String      A pointer to a Null-terminated Unicode string.

+

+  @return The display length of the Null-terminated Unicode string specified by String.

+  

+**/

+UINTN

+EFIAPI

+UnicodeStringDisplayLength (

+  IN CONST CHAR16  *String

+  )

+{

+  UINTN      Length;

+  UINTN      Width;

+

+  if (String == NULL) {

+    return 0;

+  }

+

+  Length = 0;

+  while (*String != 0) {

+    Width = GetGlyphWidth (*String);

+    if (Width == 0) {

+      return 0;

+    }

+

+    Length += Width;

+    String++;

+  }

+

+  return Length;

+}

diff --git a/edk2/MdePkg/Library/UefiLib/UefiLib.c b/edk2/MdePkg/Library/UefiLib/UefiLib.c
new file mode 100644
index 0000000..5280d65
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiLib/UefiLib.c
@@ -0,0 +1,650 @@
+/** @file

+  Mde UEFI library functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  UefiLib.c

+

+**/

+

+/**

+  Compare whether two names of languages are identical.

+

+  @param  Language1 Name of language 1.

+  @param  Language2 Name of language 2.

+

+  @retval TRUE      Language 1 and language 2 are the same.

+  @retval FALSE     Language 1 and language 2 are not the same.

+

+**/

+BOOLEAN

+CompareIso639LanguageCode (

+  IN CONST CHAR8  *Language1,

+  IN CONST CHAR8  *Language2

+  )

+{

+  return (BOOLEAN) (ReadUnaligned24 ((CONST UINT32 *) Language1) == ReadUnaligned24 ((CONST UINT32 *) Language2));

+}

+

+/**

+  This function searches the list of configuration tables stored in the EFI System 

+  Table for a table with a GUID that matches TableGuid.  If a match is found, 

+  then a pointer to the configuration table is returned in Table, and EFI_SUCCESS 

+  is returned.  If a matching GUID is not found, then EFI_NOT_FOUND is returned.

+

+  @param  TableGuid       Pointer to table's GUID type..

+  @param  Table           Pointer to the table associated with TableGuid in the EFI System Table.

+

+  @retval EFI_SUCCESS     A configuration table matching TableGuid was found.

+  @retval EFI_NOT_FOUND   A configuration table matching TableGuid could not be found.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetSystemConfigurationTable (  

+  IN  EFI_GUID  *TableGuid,

+  OUT VOID      **Table

+  )

+{

+  EFI_SYSTEM_TABLE  *SystemTable;

+  UINTN             Index;

+

+  ASSERT (TableGuid != NULL);

+  ASSERT (Table != NULL);

+

+  SystemTable = gST;

+  *Table = NULL;

+  for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {

+    if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {

+      *Table = SystemTable->ConfigurationTable[Index].VendorTable;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+/**

+  This function causes the notification function to be executed for every protocol 

+  of type ProtocolGuid instance that exists in the system when this function is 

+  invoked.  In addition, every time a protocol of type ProtocolGuid instance is 

+  installed or reinstalled, the notification function is also executed.

+

+  @param  ProtocolGuid    Supplies GUID of the protocol upon whose installation the event is fired.

+  @param  NotifyTpl       Supplies the task priority level of the event notifications.

+  @param  NotifyFunction  Supplies the function to notify when the event is signaled.

+  @param  NotifyContext   The context parameter to pass to NotifyFunction.

+  @param  Registration    A pointer to a memory location to receive the registration value.

+

+  @return The notification event that was created. 

+

+**/

+EFI_EVENT

+EFIAPI

+EfiCreateProtocolNotifyEvent(

+  IN  EFI_GUID          *ProtocolGuid,

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT VOID              *Registration

+  )

+{

+  EFI_STATUS  Status;

+  EFI_EVENT   Event;

+

+  //

+  // Create the event

+  //

+

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  NotifyContext,

+                  &Event

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Register for protocol notifactions on this event

+  //

+

+  Status = gBS->RegisterProtocolNotify (

+                  ProtocolGuid,

+                  Event,

+                  Registration

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Kick the event so we will perform an initial pass of

+  // current installed drivers

+  //

+

+  gBS->SignalEvent (Event);

+  return Event;

+}

+

+/**

+  This function creates an event using NotifyTpl, NoifyFunction, and NotifyContext.

+  This event is signaled with EfiNamedEventSignal().  This provide the ability for 

+  one or more listeners on the same event named by the GUID specified by Name.

+

+  @param  Name                  Supplies GUID name of the event.

+  @param  NotifyTpl             Supplies the task priority level of the event notifications.

+  @param  NotifyFunction        Supplies the function to notify when the event is signaled.

+  @param  NotifyContext         The context parameter to pass to NotifyFunction. 

+  @param  Registration          A pointer to a memory location to receive the registration value.

+

+  @retval EFI_SUCCESS           A named event was created.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to create the named event.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiNamedEventListen (

+  IN CONST EFI_GUID    *Name,

+  IN EFI_TPL           NotifyTpl,

+  IN EFI_EVENT_NOTIFY  NotifyFunction,

+  IN CONST VOID        *NotifyContext,  OPTIONAL

+  OUT VOID             *Registration    OPTIONAL

+  )

+{

+  EFI_STATUS  Status;

+  EFI_EVENT   Event;

+  VOID        *RegistrationLocal;

+

+  //

+  // Create event

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_NOTIFY_SIGNAL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  (VOID *) NotifyContext,

+                  &Event

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // The Registration is not optional to RegisterProtocolNotify().

+  // To make it optional to EfiNamedEventListen(), may need to substitute with a local.

+  //

+  if (Registration != NULL) {

+    RegistrationLocal = Registration;

+  } else {

+    RegistrationLocal = &RegistrationLocal;

+  }

+

+  //

+  // Register for an installation of protocol interface

+  //

+

+  Status = gBS->RegisterProtocolNotify (

+                  (EFI_GUID *) Name,

+                  Event,

+                  RegistrationLocal

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function signals the named event specified by Name.  The named event must 

+  have been created with EfiNamedEventListen().

+

+  @param  Name                  Supplies GUID name of the event.

+

+  @retval EFI_SUCCESS           A named event was signaled.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to signal the named event.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiNamedEventSignal (

+  IN CONST EFI_GUID  *Name

+  )

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE  Handle;

+

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  (EFI_GUID *) Name,

+                  EFI_NATIVE_INTERFACE,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gBS->UninstallProtocolInterface (

+                  Handle,

+                  (EFI_GUID *) Name,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  This function initializes a basic mutual exclusion lock to the released state 

+  and returns the lock.  Each lock provides mutual exclusion access at its task 

+  priority level.  Since there is no preemption or multiprocessor support in EFI,

+  acquiring the lock only consists of raising to the locks TPL.

+

+  @param  Lock       A pointer to the lock data structure to initialize.

+  @param  Priority   EFI TPL associated with the lock.

+

+  @return The lock.

+

+**/

+EFI_LOCK *

+EFIAPI

+EfiInitializeLock (

+  IN OUT EFI_LOCK  *Lock,

+  IN EFI_TPL        Priority

+  )

+{

+  ASSERT (Lock != NULL);

+  ASSERT (Priority <= EFI_TPL_HIGH_LEVEL);

+

+  Lock->Tpl       = Priority;

+  Lock->OwnerTpl  = EFI_TPL_APPLICATION;

+  Lock->Lock      = EfiLockReleased ;

+  return Lock;

+}

+

+/**

+  This function raises the system¡¯s current task priority level to the task 

+  priority level of the mutual exclusion lock.  Then, it places the lock in the 

+  acquired state.

+

+  @param  Priority  The task priority level of the lock.

+

+**/

+VOID

+EFIAPI

+EfiAcquireLock (

+  IN EFI_LOCK  *Lock

+  )

+{

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock == EfiLockReleased);

+

+  Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);

+  Lock->Lock     = EfiLockAcquired;

+}

+

+/**

+  This function raises the system¡¯s current task priority level to the task 

+  priority level of the mutual exclusion lock.  Then, it attempts to place the 

+  lock in the acquired state.

+

+  @param  Lock              A pointer to the lock to acquire.

+

+  @retval EFI_SUCCESS       The lock was acquired.

+  @retval EFI_ACCESS_DENIED The lock could not be acquired because it is already owned.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiAcquireLockOrFail (

+  IN EFI_LOCK  *Lock

+  )

+{

+

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock != EfiLockUninitialized);

+

+  if (Lock->Lock == EfiLockAcquired) {

+    //

+    // Lock is already owned, so bail out

+    //

+    return EFI_ACCESS_DENIED;

+  }

+

+  Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);

+

+  Lock->Lock = EfiLockAcquired;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function transitions a mutual exclusion lock from the acquired state to 

+  the released state, and restores the system¡¯s task priority level to its 

+  previous level.

+

+  @param  Lock  A pointer to the lock to release.

+

+**/

+VOID

+EFIAPI

+EfiReleaseLock (

+  IN EFI_LOCK  *Lock

+  )

+{

+  EFI_TPL Tpl;

+

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock == EfiLockAcquired);

+

+  Tpl = Lock->OwnerTpl;

+  

+  Lock->Lock = EfiLockReleased;

+

+  gBS->RestoreTPL (Tpl);

+}

+

+/**

+  This function looks up a Unicode string in UnicodeStringTable.  If Language is 

+  a member of SupportedLanguages and a Unicode string is found in UnicodeStringTable

+  that matches the language code specified by Language, then it is returned in 

+  UnicodeString.

+

+  @param  Language                A pointer to the ISO 639-2 language code for the 

+                                  Unicode string to look up and return.

+  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes 

+                                  that the Unicode string table supports.  Language 

+                                  must be a member of this set.

+  @param  UnicodeStringTable      A pointer to the table of Unicode strings.

+  @param  UnicodeString           A pointer to the Unicode string from UnicodeStringTable

+                                  that matches the language specified by Language.

+

+  @retval  EFI_SUCCESS            The Unicode string that matches the language 

+                                  specified by Language was found

+                                  in the table of Unicoide strings UnicodeStringTable, 

+                                  and it was returned in UnicodeString.

+  @retval  EFI_INVALID_PARAMETER  Language is NULL.

+  @retval  EFI_INVALID_PARAMETER  UnicodeString is NULL.

+  @retval  EFI_UNSUPPORTED        SupportedLanguages is NULL.

+  @retval  EFI_UNSUPPORTED        UnicodeStringTable is NULL.

+  @retval  EFI_UNSUPPORTED        The language specified by Language is not a 

+                                  member of SupportedLanguages.

+  @retval  EFI_UNSUPPORTED        The language specified by Language is not 

+                                  supported by UnicodeStringTable.

+

+**/

+EFI_STATUS

+EFIAPI

+LookupUnicodeString (

+  IN CONST CHAR8                     *Language,

+  IN CONST CHAR8                     *SupportedLanguages,

+  IN CONST EFI_UNICODE_STRING_TABLE  *UnicodeStringTable,

+  OUT CHAR16                         **UnicodeString

+  )

+{

+  //

+  // Make sure the parameters are valid

+  //

+  if (Language == NULL || UnicodeString == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If there are no supported languages, or the Unicode String Table is empty, then the

+  // Unicode String specified by Language is not supported by this Unicode String Table

+  //

+  if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Make sure Language is in the set of Supported Languages

+  //

+  while (*SupportedLanguages != 0) {

+    if (CompareIso639LanguageCode (Language, SupportedLanguages)) {

+

+      //

+      // Search the Unicode String Table for the matching Language specifier

+      //

+      while (UnicodeStringTable->Language != NULL) {

+        if (CompareIso639LanguageCode (Language, UnicodeStringTable->Language)) {

+

+          //

+          // A matching string was found, so return it

+          //

+          *UnicodeString = UnicodeStringTable->UnicodeString;

+          return EFI_SUCCESS;

+        }

+

+        UnicodeStringTable++;

+      }

+

+      return EFI_UNSUPPORTED;

+    }

+

+    SupportedLanguages += 3;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  This function adds a Unicode string to UnicodeStringTable.

+  If Language is a member of SupportedLanguages then UnicodeString is added to 

+  UnicodeStringTable.  New buffers are allocated for both Language and 

+  UnicodeString.  The contents of Language and UnicodeString are copied into 

+  these new buffers.  These buffers are automatically freed when 

+  FreeUnicodeStringTable() is called.

+

+  @param  Language                A pointer to the ISO 639-2 language code for the Unicode 

+                                  string to add.

+  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes

+                                  that the Unicode string table supports.

+                                  Language must be a member of this set.

+  @param  UnicodeStringTable      A pointer to the table of Unicode strings.

+  @param  UnicodeString           A pointer to the Unicode string to add.

+

+  @retval EFI_SUCCESS             The Unicode string that matches the language 

+                                  specified by Language was found in the table of 

+                                  Unicode strings UnicodeStringTable, and it was 

+                                  returned in UnicodeString.

+  @retval EFI_INVALID_PARAMETER   Language is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is an empty string.

+  @retval EFI_UNSUPPORTED         SupportedLanguages is NULL.

+  @retval EFI_ALREADY_STARTED     A Unicode string with language Language is 

+                                  already present in UnicodeStringTable.

+  @retval EFI_OUT_OF_RESOURCES    There is not enough memory to add another 

+                                  Unicode string to UnicodeStringTable.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not a 

+                                  member of SupportedLanguages.

+

+**/

+EFI_STATUS

+EFIAPI

+AddUnicodeString (

+  IN CONST CHAR8               *Language,

+  IN CONST CHAR8               *SupportedLanguages,

+  IN EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,

+  IN CONST CHAR16              *UnicodeString

+  )

+{

+  UINTN                     NumberOfEntries;

+  EFI_UNICODE_STRING_TABLE  *OldUnicodeStringTable;

+  EFI_UNICODE_STRING_TABLE  *NewUnicodeStringTable;

+  UINTN                     UnicodeStringLength;

+

+  //

+  // Make sure the parameter are valid

+  //

+  if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If there are no supported languages, then a Unicode String can not be added

+  //

+  if (SupportedLanguages == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // If the Unicode String is empty, then a Unicode String can not be added

+  //

+  if (UnicodeString[0] == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Make sure Language is a member of SupportedLanguages

+  //

+  while (*SupportedLanguages != 0) {

+    if (CompareIso639LanguageCode (Language, SupportedLanguages)) {

+

+      //

+      // Determine the size of the Unicode String Table by looking for a NULL Language entry

+      //

+      NumberOfEntries = 0;

+      if (*UnicodeStringTable != NULL) {

+        OldUnicodeStringTable = *UnicodeStringTable;

+        while (OldUnicodeStringTable->Language != NULL) {

+          if (CompareIso639LanguageCode (Language, OldUnicodeStringTable->Language)) {

+            return EFI_ALREADY_STARTED;

+          }

+

+          OldUnicodeStringTable++;

+          NumberOfEntries++;

+        }

+      }

+

+      //

+      // Allocate space for a new Unicode String Table.  It must hold the current number of

+      // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table

+      // marker

+      //

+      NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));

+      if (NewUnicodeStringTable == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // If the current Unicode String Table contains any entries, then copy them to the

+      // newly allocated Unicode String Table.

+      //

+      if (*UnicodeStringTable != NULL) {

+        CopyMem (

+           NewUnicodeStringTable,

+           *UnicodeStringTable,

+           NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)

+           );

+      }

+

+      //

+      // Allocate space for a copy of the Language specifier

+      //

+      NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (3, Language);

+      if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {

+        gBS->FreePool (NewUnicodeStringTable);

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // Compute the length of the Unicode String

+      //

+      for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)

+        ;

+

+      //

+      // Allocate space for a copy of the Unicode String

+      //

+      NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (

+                                                              (UnicodeStringLength + 1) * sizeof (CHAR16),

+                                                              UnicodeString

+                                                              );

+      if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {

+        gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);

+        gBS->FreePool (NewUnicodeStringTable);

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // Mark the end of the Unicode String Table

+      //

+      NewUnicodeStringTable[NumberOfEntries + 1].Language       = NULL;

+      NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString  = NULL;

+

+      //

+      // Free the old Unicode String Table

+      //

+      if (*UnicodeStringTable != NULL) {

+        gBS->FreePool (*UnicodeStringTable);

+      }

+

+      //

+      // Point UnicodeStringTable at the newly allocated Unicode String Table

+      //

+      *UnicodeStringTable = NewUnicodeStringTable;

+

+      return EFI_SUCCESS;

+    }

+

+    SupportedLanguages += 3;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  This function frees the table of Unicode strings in UnicodeStringTable.

+  If UnicodeStringTable is NULL, then EFI_SUCCESS is returned.

+  Otherwise, each language code, and each Unicode string in the Unicode string 

+  table are freed, and EFI_SUCCESS is returned.

+

+  @param  UnicodeStringTable  A pointer to the table of Unicode strings.

+

+  @retval EFI_SUCCESS         The Unicode string table was freed.

+

+**/

+EFI_STATUS

+EFIAPI

+FreeUnicodeStringTable (

+  IN EFI_UNICODE_STRING_TABLE  *UnicodeStringTable

+  )

+{

+  UINTN Index;

+

+  //

+  // If the Unicode String Table is NULL, then it is already freed

+  //

+  if (UnicodeStringTable == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Loop through the Unicode String Table until we reach the end of table marker

+  //

+  for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {

+

+    //

+    // Free the Language string from the Unicode String Table

+    //

+    gBS->FreePool (UnicodeStringTable[Index].Language);

+

+    //

+    // Free the Unicode String from the Unicode String Table

+    //

+    if (UnicodeStringTable[Index].UnicodeString != NULL) {

+      gBS->FreePool (UnicodeStringTable[Index].UnicodeString);

+    }

+  }

+

+  //

+  // Free the Unicode String Table itself

+  //

+  gBS->FreePool (UnicodeStringTable);

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/UefiLib/UefiLib.mbd b/edk2/MdePkg/Library/UefiLib/UefiLib.mbd
new file mode 100644
index 0000000..252e3b1
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiLib/UefiLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiLib</BaseName>

+    <Guid>3a004ba5-efe0-4a61-9f1a-267a46ae5ba9</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiLib/UefiLib.msa b/edk2/MdePkg/Library/UefiLib/UefiLib.msa
new file mode 100644
index 0000000..a37d655
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiLib/UefiLib.msa
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiLib</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>3a004ba5-efe0-4a61-9f1a-267a46ae5ba9</Guid>

+    <Version>0</Version>

+    <Abstract>Component description file for the entry point to a EFIDXE Drivers</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-09 23:12</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UefiLib.c</Filename>

+    <Filename>Console.c</Filename>

+    <Filename>UefiNotTiano.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Guids>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>EventLegacyBoot</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>EventReadyToBoot</C_Name>

+    </GuidEntry>

+    <GuidEntry Usage="ALWAYS_CONSUMED">

+      <C_Name>FrameworkDevicePath</C_Name>

+    </GuidEntry>

+  </Guids>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiLib/UefiNotTiano.c b/edk2/MdePkg/Library/UefiLib/UefiNotTiano.c
new file mode 100644
index 0000000..770d76d
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiLib/UefiNotTiano.c
@@ -0,0 +1,370 @@
+/** @file

+  Library functions that abstract areas of conflict between Tiano an UEFI 2.0.

+

+  Help Port Framework/Tinao code that has conflicts with UEFI 2.0 by hiding the

+  oldconflicts with library functions and supporting implementations of the old 

+  (R8.5/EFI 1.10) and new (R9/UEFI 2.0) way.

+

+Copyright (c) 2006, Intel Corporation<BR>

+All rights reserved. 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.

+

+**/

+

+/**

+  An empty function to pass error checking of CreateEventEx (). 

+  

+  This empty function enusres that EFI_EVENT_NOTIFY_SIGNAL_ALL is error
+  checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
+  

+**/

+VOID
+InternalEmptyFuntion (
+  IN EFI_EVENT                Event,
+  IN VOID                     *Context
+  )
+{
+  return;
+}

+

+/**

+  Create a Legacy Boot Event.  

+  

+  Tiano extended the CreateEvent Type enum to add a legacy boot event type. 

+  This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was

+  added and now it's possible to not voilate the UEFI specification by 

+  declaring a GUID for the legacy boot event class. This library supports

+  the R8.5/EFI 1.10 form and R9/UEFI 2.0 form and allows common code to 

+  work both ways.

+

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventLegacyBoot (

+  OUT EFI_EVENT  *LegacyBootEvent

+  )

+{

+  return EfiCreateEventLegacyBootEx (

+           EFI_TPL_CALLBACK,

+           InternalEmptyFuntion,

+           NULL,

+           LegacyBootEvent

+           );

+}

+

+/**

+  Create an EFI event in the Legacy Boot Event Group and allows

+  the caller to specify a notification function.  

+  

+  This function abstracts the creation of the Legacy Boot Event.

+  The Framework moved from a proprietary to UEFI 2.0 based mechanism.

+  This library abstracts the caller from how this event is created to prevent

+  to code form having to change with the version of the specification supported.

+  If LegacyBootEvent is NULL, then ASSERT().

+

+  @param  NotifyTpl         The task priority level of the event.

+  @param  NotifyFunction    The notification function to call when the event is signaled.

+  @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventLegacyBootEx (

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT EFI_EVENT         *LegacyBootEvent

+  )

+{

+  EFI_STATUS    Status;

+

+  ASSERT (LegacyBootEvent != NULL);

+

+#if (EFI_SPECIFICATION_VERSION < 0x00020000) 

+  //

+  // prior to UEFI 2.0 use Tiano extension to EFI

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_LEGACY_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  NotifyContext,

+                  LegacyBootEvent

+                  );

+#else

+  //

+  // For UEFI 2.0 and the future use an Event Group

+  //

+  Status = gBS->CreateEventEx (

+                  EVENT_NOTIFY_SIGNAL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  NotifyContext,

+                  &gEfiEventLegacyBootGuid,

+                  LegacyBootEvent

+                  );

+#endif

+

+  return Status;

+}

+

+/**

+  Create a Read to Boot Event.  

+  

+  Tiano extended the CreateEvent Type enum to add a ready to boot event type. 

+  This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was

+  added and now it's possible to not voilate the UEFI specification and use 

+  the ready to boot event class defined in UEFI 2.0. This library supports

+  the R8.5/EFI 1.10 form and R9/UEFI 2.0 form and allows common code to 

+  work both ways.

+

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventReadyToBoot (

+  OUT EFI_EVENT  *ReadyToBootEvent

+  )

+{

+  return EfiCreateEventReadyToBootEx (

+           EFI_TPL_CALLBACK,

+           InternalEmptyFuntion,

+           NULL,

+           ReadyToBootEvent

+           );

+}

+

+/**

+  Create an EFI event in the Ready To Boot Event Group and allows

+  the caller to specify a notification function.  

+  

+  This function abstracts the creation of the Ready to Boot Event.

+  The Framework moved from a proprietary to UEFI 2.0 based mechanism.

+  This library abstracts the caller from how this event is created to prevent

+  to code form having to change with the version of the specification supported.

+  If ReadyToBootEvent is NULL, then ASSERT().

+

+  @param  NotifyTpl         The task priority level of the event.

+  @param  NotifyFunction    The notification function to call when the event is signaled.

+  @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventReadyToBootEx (

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT EFI_EVENT         *ReadyToBootEvent

+  )

+{

+  EFI_STATUS    Status;

+

+  ASSERT (ReadyToBootEvent != NULL);

+

+#if (EFI_SPECIFICATION_VERSION < 0x00020000) 

+  //

+  // prior to UEFI 2.0 use Tiano extension to EFI

+  //

+  Status = gBS->CreateEvent (

+                  EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  NotifyContext,

+                  ReadyToBootEvent

+                  );

+#else

+  //

+  // For UEFI 2.0 and the future use an Event Group

+  //

+  Status = gBS->CreateEventEx (

+                  EVENT_NOTIFY_SIGNAL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  NotifyContext,

+                  &gEfiEventReadyToBootGuid,

+                  ReadyToBootEvent

+                  );

+#endif

+

+  return Status;

+}

+

+

+/**

+  Signal a Ready to Boot Event.  

+  

+  Create a Ready to Boot Event. Signal it and close it. This causes other 

+  events of the same event group to be signaled in other modules. 

+

+**/

+VOID

+EFIAPI

+EfiSignalEventReadyToBoot (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+  EFI_EVENT     ReadyToBootEvent;

+

+  Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);

+  if (!EFI_ERROR (Status)) {

+    gBS->SignalEvent (ReadyToBootEvent);

+    gBS->CloseEvent (ReadyToBootEvent);

+  }

+}

+

+/**

+  Signal a Legacy Boot Event.  

+  

+  Create a legacy Boot Event. Signal it and close it. This causes other 

+  events of the same event group to be signaled in other modules. 

+

+**/

+VOID

+EFIAPI

+EfiSignalEventLegacyBoot (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+  EFI_EVENT     LegacyBootEvent;

+

+  Status = EfiCreateEventLegacyBoot (&LegacyBootEvent);

+  if (!EFI_ERROR (Status)) {

+    gBS->SignalEvent (LegacyBootEvent);

+    gBS->CloseEvent (LegacyBootEvent);

+  }

+}

+

+

+/**

+  Check to see if the Firmware Volume (FV) Media Device Path is valid 

+  

+  Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum

+  so as we move to UEFI 2.0 support we must use a mechanism that conforms with

+  the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed 

+  device path is defined for PIWG extensions of device path. If the code 

+  is compiled to conform with the UEFI 2.0 specification use the new device path

+  else use the old form for backwards compatability. The return value to this

+  function points to a location in FvDevicePathNode and it does not allocate

+  new memory for the GUID pointer that is returned.

+

+  @param  FvDevicePathNode  Pointer to FV device path to check.

+

+  @retval NULL              FvDevicePathNode is not valid.

+  @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.

+

+**/

+EFI_GUID *

+EFIAPI

+EfiGetNameGuidFromFwVolDevicePathNode (

+  IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode

+  )

+{

+  ASSERT (FvDevicePathNode != NULL);

+

+#if (EFI_SPECIFICATION_VERSION < 0x00020000) 

+  //

+  // Use old Device Path that conflicts with UEFI

+  //

+  if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH ||

+      DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_FV_FILEPATH_DP) {

+    return (EFI_GUID *) &FvDevicePathNode->NameGuid;

+  }

+

+#else

+  //

+  // Use the new Device path that does not conflict with the UEFI

+  //

+  if (FvDevicePathNode->Piwg.Header.Type == MEDIA_DEVICE_PATH ||

+      FvDevicePathNode->Piwg.Header.SubType == MEDIA_VENDOR_DP) {

+    if (CompareGuid (&gEfiFrameworkDevicePathGuid, &FvDevicePathNode->Piwg.PiwgSpecificDevicePath)) {

+      if (FvDevicePathNode->Piwg.Type == PIWG_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE) {

+        return (EFI_GUID *) &FvDevicePathNode->NameGuid;

+      }

+    }

+  }

+#endif  

+  return NULL;

+}

+

+

+/**

+  Initialize a Firmware Volume (FV) Media Device Path node.

+  

+  Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum

+  so as we move to UEFI 2.0 support we must use a mechanism that conforms with

+  the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed 

+  device path is defined for PIWG extensions of device path. If the code 

+  is compiled to conform with the UEFI 2.0 specification use the new device path

+  else use the old form for backwards compatability.

+

+  @param  FvDevicePathNode  Pointer to a FV device path node to initialize

+  @param  NameGuid          FV file name to use in FvDevicePathNode

+

+**/

+VOID

+EFIAPI

+EfiInitializeFwVolDevicepathNode (

+  IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,

+  IN CONST EFI_GUID                         *NameGuid

+  )

+{

+  ASSERT (FvDevicePathNode  != NULL);

+  ASSERT (NameGuid          != NULL);

+

+#if (EFI_SPECIFICATION_VERSION < 0x00020000) 

+  //

+  // Use old Device Path that conflicts with UEFI

+  //

+  FvDevicePathNode->Header.Type     = MEDIA_DEVICE_PATH;

+  FvDevicePathNode->Header.SubType  = MEDIA_FV_FILEPATH_DP;

+  SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));

+  

+#else

+  //

+  // Use the new Device path that does not conflict with the UEFI

+  //

+  FvDevicePathNode->Piwg.Header.Type     = MEDIA_DEVICE_PATH;

+  FvDevicePathNode->Piwg.Header.SubType  = MEDIA_VENDOR_DP;

+  SetDevicePathNodeLength (&FvDevicePathNode->Piwg.Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));

+

+  //

+  // Add the GUID for generic PIWG device paths

+  //

+  CopyGuid (&FvDevicePathNode->Piwg.PiwgSpecificDevicePath, &gEfiFrameworkDevicePathGuid);

+

+  //

+  // Add in the FW Vol File Path PIWG defined inforation

+  //

+  FvDevicePathNode->Piwg.Type = PIWG_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE;

+

+#endif

+

+  CopyGuid (&FvDevicePathNode->NameGuid, NameGuid);

+

+}

+

diff --git a/edk2/MdePkg/Library/UefiLib/build.xml b/edk2/MdePkg/Library/UefiLib/build.xml
new file mode 100644
index 0000000..3db4bf4
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiLib">

+      <GenBuild baseName="UefiLib" mbdFilename="${MODULE_DIR}/UefiLib.mbd" msaFilename="${MODULE_DIR}/UefiLib.msa"/>

+   </target>

+   <target depends="UefiLib_clean" name="clean"/>

+   <target depends="UefiLib_cleanall" name="cleanall"/>

+   <target name="UefiLib_clean">

+      <OutputDirSetup baseName="UefiLib" mbdFilename="${MODULE_DIR}/UefiLib.mbd" msaFilename="${MODULE_DIR}/UefiLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiLib_cleanall">

+      <OutputDirSetup baseName="UefiLib" mbdFilename="${MODULE_DIR}/UefiLib.mbd" msaFilename="${MODULE_DIR}/UefiLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiMemoryLib/CompareMemWrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/CompareMemWrapper.c
new file mode 100644
index 0000000..c8199d8
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/CompareMemWrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  CompareMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CompareMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Compares two memory buffers of a given length.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of

+  DestinationBuffer. If all Length bytes of the two buffers are identical, then

+  0 is returned. Otherwise, the value returned is the first mismatched byte in

+  SourceBuffer subtracted from the first mismatched byte in DestinationBuffer.

+

+  If DestinationBuffer is NULL and Length > 0, then ASSERT().

+  If SourceBuffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare

+

+  @retval 0         if DestinationBuffer == SourceBuffer

+  @retval Non-zero  if DestinationBuffer != SourceBuffer

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)DestinationBuffer + 1);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)SourceBuffer + 1);

+  if (Length == 0) {

+    return 0;

+  }

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/CopyMemWrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/CopyMemWrapper.c
new file mode 100644
index 0000000..5ca62f5
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/CopyMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CopyMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  CopyMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and

+  returns DestinationBuffer. The implementation must be reentrant, and it must

+  handle the case where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then

+  ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (

+    Destination == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Destination + 1

+    );

+  ASSERT (

+    Source == NULL ||

+    Length <= MAX_ADDRESS - (UINTN)Source + 1

+    );

+  if (Destination == Source || Length == 0) {

+    return Destination;

+  }

+  return InternalMemCopyMem (Destination, Source, Length);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/MemLib.c b/edk2/MdePkg/Library/UefiMemoryLib/MemLib.c
new file mode 100644
index 0000000..f8f8e30
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/MemLib.c
@@ -0,0 +1,39 @@
+/** @file

+  Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLib.c

+

+**/

+

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  gBS->CopyMem (Destination, (VOID*)Source, Length);

+  return Destination;

+}

+

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  gBS->SetMem (Buffer, Size, Value);

+  return Buffer;

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/MemLibGeneric.c b/edk2/MdePkg/Library/UefiMemoryLib/MemLibGeneric.c
new file mode 100644
index 0000000..bda1f49
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/MemLibGeneric.c
@@ -0,0 +1,266 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGeneric.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length > 0);

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  ASSERT (Length > 0);

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/MemLibGuid.c b/edk2/MdePkg/Library/UefiMemoryLib/MemLibGuid.c
new file mode 100644
index 0000000..c54983c
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/MemLibGuid.c
@@ -0,0 +1,139 @@
+/** @file

+  Implementation of GUID functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibGuid.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+/**

+  This function copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid

+  to DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid Pointer to the destination GUID.

+  @param  SourceGuid Pointer to the source GUID.

+

+  @return DestinationGuid

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT     GUID                      *DestinationGuid,

+  IN      CONST GUID                *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs

+

+  This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE

+  is returned. If there are any bit differences in the two GUIDs, then FALSE is

+  returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1 guid to compare

+  @param  Guid2 guid to compare

+

+  @retval TRUE  if Guid1 == Guid2

+  @retval FALSE if Guid1 != Guid2

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN      CONST GUID                *Guid1,

+  IN      CONST GUID                *Guid2

+  )

+{

+  return (BOOLEAN)(

+           ReadUnaligned64 ((CONST UINT64*)Guid1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&

+           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)

+             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)

+           );

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the

+  128-bit GUID value that matches Guid. If a match is found, then a pointer to

+  the matching GUID in the target buffer is returned. If no match is found,

+  then NULL is returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Guid was not found.

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      CONST GUID                *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (Buffer != NULL);

+  //

+  // Make sure Buffer is aligned on a 64-bit boundary.

+  //

+  ASSERT (((UINTN) Buffer & 7) == 0);

+

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/MemLibInternals.h b/edk2/MdePkg/Library/UefiMemoryLib/MemLibInternals.h
new file mode 100644
index 0000000..ca7311a
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/MemLibInternals.h
@@ -0,0 +1,230 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  MemLibInternals.h

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  Destination Target of copy

+  @param  Source Place to copy from

+  @param  Length Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @retval 0     if MemOne == MemTwo

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/ScanMem16Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem16Wrapper.c
new file mode 100644
index 0000000..a17705d
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem16Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 16-bit increments for a 16-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/ScanMem32Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem32Wrapper.c
new file mode 100644
index 0000000..67eb84d
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 32-bit increments for a 32-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/ScanMem64Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem64Wrapper.c
new file mode 100644
index 0000000..c5f0762
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem64Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address at 64-bit increments for a 64-bit

+  value that matches Value. If a match is found, then a pointer to the matching

+  value in the target buffer is returned. If no match is found, then NULL is

+  returned. If Length is 0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/ScanMem8Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem8Wrapper.c
new file mode 100644
index 0000000..9b817b1
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/ScanMem8Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  ScanMem8() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ScanMem8Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  This function searches target the buffer specified by Buffer and Length from

+  the lowest address to the highest address for an 8-bit value that matches

+  Value. If a match is found, then a pointer to the matching byte in the target

+  buffer is returned. If no match is found, then NULL is returned. If Length is

+  0, then NULL is returned.

+

+  If Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+  @retval NULL  if Length == 0 or Value was not found.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS + (UINTN)Buffer + 1);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return NULL;

+  }

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/SetMem16Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/SetMem16Wrapper.c
new file mode 100644
index 0000000..3acbdac
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem16Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem16 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/SetMem32Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/SetMem32Wrapper.c
new file mode 100644
index 0000000..620b69a
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem32Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem32 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/SetMem64Wrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/SetMem64Wrapper.c
new file mode 100644
index 0000000..73c28af
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMem64Wrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) != 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) != 0);

+

+  if ((Length /= sizeof (Value)) == 0) {

+    return Buffer;

+  }

+  return InternalMemSetMem64 (Buffer, Length, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
new file mode 100644
index 0000000..294a27a
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  SetMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  SetMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+  @param  Value Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (Size <= MAX_ADDRESS - (UINTN)Buffer + 1);

+  return InternalMemSetMem (Buffer, Size, Value);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.mbd b/edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.mbd
new file mode 100644
index 0000000..70fd110
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.mbd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiMemoryLib</BaseName>

+    <Guid>f1bbe03d-2f28-4dee-bec7-d98d7a30c36a</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.msa b/edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.msa
new file mode 100644
index 0000000..e752b81
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.msa
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiMemoryLib</BaseName>

+    <ModuleType>UEFI_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>f1bbe03d-2f28-4dee-bec7-d98d7a30c36a</Guid>

+    <Version>EDK_RELEASE_VERSION        0x00090000</Version>

+    <Abstract>Memory-only library functions with no library constructor/destructor</Abstract>

+    <Description>FIX ME!</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-04-12 13:39</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">BaseMemoryLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>MemLib.c</Filename>

+    <Filename>MemLibGuid.c</Filename>

+    <Filename>MemLibGeneric.c</Filename>

+    <Filename>CopyMemWrapper.c</Filename>

+    <Filename>SetMemWrapper.c</Filename>

+    <Filename>SetMem16Wrapper.c</Filename>

+    <Filename>SetMem32Wrapper.c</Filename>

+    <Filename>SetMem64Wrapper.c</Filename>

+    <Filename>CompareMemWrapper.c</Filename>

+    <Filename>ZeroMemWrapper.c</Filename>

+    <Filename>ScanMem8Wrapper.c</Filename>

+    <Filename>ScanMem16Wrapper.c</Filename>

+    <Filename>ScanMem32Wrapper.c</Filename>

+    <Filename>ScanMem64Wrapper.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/ZeroMemWrapper.c b/edk2/MdePkg/Library/UefiMemoryLib/ZeroMemWrapper.c
new file mode 100644
index 0000000..4a3d615
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  ZeroMemWrapper.c

+

+  The following BaseMemoryLib instances share the same version of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    PeiMemoryLib

+    UefiMemoryLib

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Buffer is NULL and Length > 0, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer Memory to set.

+  @param  Size Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  IN      VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemSetMem (Buffer, Length, 0);

+}

diff --git a/edk2/MdePkg/Library/UefiMemoryLib/build.xml b/edk2/MdePkg/Library/UefiMemoryLib/build.xml
new file mode 100644
index 0000000..3c5ba25
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiMemoryLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiMemoryLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiMemoryLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiMemoryLib">

+      <GenBuild baseName="UefiMemoryLib" mbdFilename="${MODULE_DIR}/UefiMemoryLib.mbd" msaFilename="${MODULE_DIR}/UefiMemoryLib.msa"/>

+   </target>

+   <target depends="UefiMemoryLib_clean" name="clean"/>

+   <target depends="UefiMemoryLib_cleanall" name="cleanall"/>

+   <target name="UefiMemoryLib_clean">

+      <OutputDirSetup baseName="UefiMemoryLib" mbdFilename="${MODULE_DIR}/UefiMemoryLib.mbd" msaFilename="${MODULE_DIR}/UefiMemoryLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiMemoryLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiMemoryLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiMemoryLib_cleanall">

+      <OutputDirSetup baseName="UefiMemoryLib" mbdFilename="${MODULE_DIR}/UefiMemoryLib.mbd" msaFilename="${MODULE_DIR}/UefiMemoryLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiMemoryLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiMemoryLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiMemoryLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c
new file mode 100644
index 0000000..ac4b3eb
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c
@@ -0,0 +1,36 @@
+/** @file

+  UEFI Runtime Services Table Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.             

+

+  Module Name:  UefiRuntimeServicesTableLib.c

+

+**/

+

+//

+// Cached copy of the EFI Runtime Services Table

+//

+EFI_RUNTIME_SERVICES  *gRT = NULL;

+

+/**

+**/

+EFI_STATUS

+UefiRuntimeServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  //

+  // Cache pointer to the EFI Runtime Services Table

+  //

+  gRT = SystemTable->RuntimeServices;

+  ASSERT (gRT != NULL);

+  return EFI_SUCCESS;

+}

diff --git a/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.mbd b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.mbd
new file mode 100644
index 0000000..df9238a
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.mbd
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MbdLibHeader>

+    <BaseName>UefiRuntimeServicesTableLib</BaseName>

+    <Guid>baa1baa3-0a8d-402c-8042-985115fae953</Guid>

+    <Version>0</Version>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 15:49</Created>

+    <Modified>2006-03-19 15:17</Modified>

+  </MbdLibHeader>

+</LibraryModuleBuildDescription>

diff --git a/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.msa b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.msa
new file mode 100644
index 0000000..c0e6dcb
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.msa
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<LibraryModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaLibHeader>

+    <BaseName>UefiRuntimeServicesTableLib</BaseName>

+    <ModuleType>DXE_DRIVER</ModuleType>

+    <ComponentType>LIBRARY</ComponentType>

+    <Guid>baa1baa3-0a8d-402c-8042-985115fae953</Guid>

+    <Version>0</Version>

+    <Abstract>UEFI Runtime Services Table Library</Abstract>

+    <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>

+    <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <Created>2006-03-17 15:49</Created>

+    <Updated>2006-03-19 15:17</Updated>

+    <Specification>0</Specification>

+  </MsaLibHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_PRODUCED">UefiRuntimeServicesTableLib</LibraryClass>

+    <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename>UefiRuntimeServicesTableLib.c</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <Constructor>UefiRuntimeServicesTableLibConstructor</Constructor>

+    </Extern>

+  </Externs>

+</LibraryModuleSurfaceArea>

diff --git a/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/build.xml b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/build.xml
new file mode 100644
index 0000000..c6dbade
--- /dev/null
+++ b/edk2/MdePkg/Library/UefiRuntimeServicesTableLib/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation 

+All rights reserved. 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.-->

+<project basedir="." default="UefiRuntimeServicesTableLib"><!--Apply external ANT tasks-->

+   <taskdef resource="GenBuild.tasks"/>

+   <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+   <property environment="env"/>

+   <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>

+   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->

+   <property name="MODULE_RELATIVE_PATH" value="Library/UefiRuntimeServicesTableLib"/>

+   <property name="MODULE_DIR" value="${PACKAGE_DIR}/${MODULE_RELATIVE_PATH}"/>

+   <property name="COMMON_FILE" value="${WORKSPACE_DIR}/Tools/Conf/Common.xml"/>

+   <target name="UefiRuntimeServicesTableLib">

+      <GenBuild baseName="UefiRuntimeServicesTableLib" mbdFilename="${MODULE_DIR}/UefiRuntimeServicesTableLib.mbd" msaFilename="${MODULE_DIR}/UefiRuntimeServicesTableLib.msa"/>

+   </target>

+   <target depends="UefiRuntimeServicesTableLib_clean" name="clean"/>

+   <target depends="UefiRuntimeServicesTableLib_cleanall" name="cleanall"/>

+   <target name="UefiRuntimeServicesTableLib_clean">

+      <OutputDirSetup baseName="UefiRuntimeServicesTableLib" mbdFilename="${MODULE_DIR}/UefiRuntimeServicesTableLib.mbd" msaFilename="${MODULE_DIR}/UefiRuntimeServicesTableLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiRuntimeServicesTableLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiRuntimeServicesTableLib_build.xml" target="clean"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>

+   </target>

+   <target name="UefiRuntimeServicesTableLib_cleanall">

+      <OutputDirSetup baseName="UefiRuntimeServicesTableLib" mbdFilename="${MODULE_DIR}/UefiRuntimeServicesTableLib.mbd" msaFilename="${MODULE_DIR}/UefiRuntimeServicesTableLib.msa"/>

+      <if>

+         <available file="${DEST_DIR_OUTPUT}/UefiRuntimeServicesTableLib_build.xml"/>

+         <then>

+            <ant antfile="${DEST_DIR_OUTPUT}/UefiRuntimeServicesTableLib_build.xml" target="cleanall"/>

+         </then>

+      </if>

+      <delete dir="${DEST_DIR_OUTPUT}"/>

+      <delete dir="${DEST_DIR_DEBUG}"/>

+      <delete>

+         <fileset dir="${BIN_DIR}" includes="**UefiRuntimeServicesTableLib*"/>

+      </delete>

+   </target>

+</project>
\ No newline at end of file
diff --git a/edk2/MdePkg/MdePkg-All-Archs.fpd b/edk2/MdePkg/MdePkg-All-Archs.fpd
new file mode 100644
index 0000000..392c239
--- /dev/null
+++ b/edk2/MdePkg/MdePkg-All-Archs.fpd
@@ -0,0 +1,2799 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<FrameworkPlatformDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <PlatformHeader>

+    <PlatformName>MdePkgAll</PlatformName>

+    <GuidValue>0fe7dd3e-0969-48c3-8cd2-de9a190088e2</GuidValue>

+    <Version>0.3</Version>

+    <Abstract>EFI/Tiano MdePkg Package</Abstract>

+    <Description>This FPD file is used for Package Level build.</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-04-03 13:40</CreatedDate>

+    <ModifiedDate>2006-05-14 09:49</ModifiedDate>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>

+  </PlatformHeader>

+  <Flash>

+    <FlashDefinitionFile>dummy.fdf</FlashDefinitionFile>

+  </Flash>

+  <TianoImage>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </DXE_DRIVERS>

+    

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePrintLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePerformanceLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePcdLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibPciExpress" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibCf8" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciCf8Lib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciExpressLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseSmbusLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiSmbusLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmbusLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeimEntryPoint" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeHobLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiHobLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreHobLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeServicesTableLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+  

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" />

+  

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverModelLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiMemoryLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibConOut" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxePcdLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiPcdLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" />

+      

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePeCoffLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePrintLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseDebugLibNull" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePerformanceLibNull" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePcdLibNull" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciLibPciExpress" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciLibCf8" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciCf8Lib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciExpressLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseSmbusLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiSmbusLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeSmbusLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiCoreLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiMemoryLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeimEntryPoint" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeHobLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiHobLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeCoreHobLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeServicesTableLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" />

+  

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" />

+  

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDriverModelLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiMemoryLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDebugLibConOut" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxePcdLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiPcdLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" />

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDevicePathLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="HiiLib" />

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePeCoffLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePrintLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseDebugLibNull" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePerformanceLibNull" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePcdLibNull" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciLibPciExpress" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciLibCf8" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciCf8Lib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciExpressLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseSmbusLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiSmbusLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeSmbusLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiCoreLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiMemoryLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeimEntryPoint" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeHobLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiHobLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeCoreHobLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeServicesTableLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" />

+  

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+  

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" />

+  

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDriverModelLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiMemoryLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDebugLibConOut" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxePcdLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiPcdLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" />

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDevicePathLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="HiiLib" />

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePeCoffLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePrintLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseDebugLibNull" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePerformanceLibNull" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePcdLibNull" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciLibPciExpress" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciLibCf8" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciCf8Lib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciExpressLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseSmbusLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiSmbusLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeSmbusLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiCoreLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiMemoryLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeimEntryPoint" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeHobLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiHobLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeCoreHobLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeServicesTableLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" />

+  

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" />

+  

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDriverModelLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiMemoryLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDebugLibConOut" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxePcdLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiPcdLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" />

+      

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDevicePathLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="HiiLib" />

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" />

+    </OTHER_COMPONENTS>

+  </TianoImage>

+  <FrameworkModules>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </DXE_DRIVERS>

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePrintLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePerformanceLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePcdLibNull" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibPciExpress" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibCf8" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciCf8Lib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciExpressLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeimEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+        <PcdBuildDeclarations>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverModelLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiMemoryLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>   

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibConOut" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxePcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiPcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" >

+      </ModuleSA>        

+      

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePeCoffLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePrintLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseDebugLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePerformanceLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePcdLibNull" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciLibPciExpress" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciLibCf8" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciCf8Lib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BasePciExpressLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiCoreLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeimEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeCoreHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+        <PcdBuildDeclarations>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDriverModelLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiMemoryLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>   

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDebugLibConOut" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxePcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiPcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDevicePathLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="HiiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IPF" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" >

+      </ModuleSA>        

+      

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePeCoffLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePrintLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseDebugLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePerformanceLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePcdLibNull" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciLibPciExpress" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciLibCf8" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciCf8Lib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BasePciExpressLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiCoreLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeimEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeCoreHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+        <PcdBuildDeclarations>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDriverModelLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiMemoryLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>   

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDebugLibConOut" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxePcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiPcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDevicePathLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="HiiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="X64" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePeCoffLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePrintLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseDebugLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePerformanceLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePcdLibNull" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciLibPciExpress" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciLibCf8" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciCf8Lib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BasePciExpressLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiCoreLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeimEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeCoreHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+        <PcdBuildDeclarations>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDriverModelLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiMemoryLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>   

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDebugLibConOut" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxePcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiPcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDevicePathLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="HiiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="EBC" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" >

+      </ModuleSA>        

+      

+    </OTHER_COMPONENTS>  

+  </FrameworkModules>

+  <BuildOptions>

+    <OutputDirectory IntermediateDirectories="UNIFIED"/>

+  </BuildOptions>

+</FrameworkPlatformDescription>

diff --git a/edk2/MdePkg/MdePkg.fpd b/edk2/MdePkg/MdePkg.fpd
new file mode 100644
index 0000000..e514d44
--- /dev/null
+++ b/edk2/MdePkg/MdePkg.fpd
@@ -0,0 +1,1011 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<FrameworkPlatformDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <PlatformHeader>

+    <PlatformName>MdePkg</PlatformName>

+    <GuidValue>1123e1a9-4d9b-499f-843c-b2297ff61a11</GuidValue>

+    <Version>0.3</Version>

+    <Abstract>EFI/Tiano MdePkg Package</Abstract>

+    <Description>This FPD file is used for Package Level build.</Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-02-24 14:49</CreatedDate>

+    <ModifiedDate>2006-05-14 09:49</ModifiedDate>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>

+  </PlatformHeader>

+  <Flash>

+    <FlashDefinitionFile>dummy.fdf</FlashDefinitionFile>

+  </Flash>

+  <TianoImage>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+    </DXE_DRIVERS>

+

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePrintLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePerformanceLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePcdLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibPciExpress" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibCf8" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciCf8Lib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciExpressLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseSmbusLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiSmbusLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmbusLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" />

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeimEntryPoint" />

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeHobLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiHobLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreHobLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeServicesTableLib" />

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" />

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverModelLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiMemoryLib" />

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibConOut" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxePcdLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiPcdLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" />

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiLib" />

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" />

+    </OTHER_COMPONENTS>

+  </TianoImage>

+  <FrameworkModules>

+    <SEC>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </SEC>

+    <PEI_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </PEI_CORE>

+    <PEIM>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </PEIM>

+    <DXE_CORE>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </DXE_CORE>

+    <DXE_DRIVERS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+    </DXE_DRIVERS>

+    <OTHER_COMPONENTS>

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+            <Token>0x00000001</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumAsciiStringLength</C_Name>

+            <Token>0x00000002</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdSpinLockTimeout</C_Name>

+            <Token>0x00000004</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>10000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdMaximumLinkedListLength</C_Name>

+            <Token>0x00000003</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>1000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibRepStr" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibMmx" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseMemoryLibSse2" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseCacheMaintenanceLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseIoLibIntrinsic" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseTimerLibLocalApic" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePeCoffGetEntryPointLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePrintLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePerformanceLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+            <Token>0x00000009</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>      

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePcdLibNull" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibPciExpress" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciLibCf8" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciCf8Lib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BasePciExpressLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdPciExpressBaseAddress</C_Name>

+            <Token>0x0000000A</Token>

+            <DatumType>UINT64</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <GuidOffset>0</GuidOffset>

+            <DefaultValue>0xE0000000</DefaultValue>

+          </PcdBuildData>        

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmbusLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiServicesTablePointerLibMm7" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseDebugLibReportStatusCode" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeimEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreEntryPoint" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeCoreHobLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiIoLibCpuIo" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeReportStatusCodeLib" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseReportStatusCodeLibNull" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+            <Token>0x00000007</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x07</DefaultValue>

+          </PcdBuildData>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeSmmDriverEntryPoint" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiBootServicesTableLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiRuntimeServicesTableLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverEntryPoint" >

+        <PcdBuildDeclarations>

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDriverModelLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiMemoryLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibStdErr" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>   

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDebugLibConOut" >

+        <PcdBuildDeclarations>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugPropertyMask</C_Name>

+            <Token>0x00000005</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x0f</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="PATCHABLE_IN_MODULE">

+            <C_Name>PcdDebugPrintErrorLevel</C_Name>

+            <Token>0x00000006</Token>

+            <DatumType>UINT32</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0x00</MaxSku>

+            <SkuId>0x00</SkuId>

+            <DatumSize>4</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0x80000000</DefaultValue>

+          </PcdBuildData>

+          <PcdBuildData ItemType="FIXED_AT_BUILD">

+            <C_Name>PcdDebugClearMemoryValue</C_Name>

+            <Token>0x00000008</Token>

+            <DatumType>UINT8</DatumType>

+            <HiiEnable>false</HiiEnable>

+            <VpdEnable>false</VpdEnable>

+            <AlternateNameSpaceEnable>false</AlternateNameSpaceEnable>

+            <SkuEnable>false</SkuEnable>

+            <SkuDataArrayEnable>false</SkuDataArrayEnable>

+            <MaxSku>0</MaxSku>

+            <SkuId>0</SkuId>

+            <DatumSize>1</DatumSize>

+            <VariableGuid>0</VariableGuid>

+            <VariableName>L""</VariableName>

+            <DataOffset>0</DataOffset>

+            <DefaultValue>0xAF</DefaultValue>

+          </PcdBuildData>           

+        </PcdBuildDeclarations>

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxePcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiPcdLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="DxeMemoryAllocationLib" >

+      </ModuleSA>        

+

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiMemoryAllocationLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="BaseUefiDecompressLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="UefiDevicePathLibDevicePathProtocol" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="HiiLib" >

+      </ModuleSA>        

+      <ModuleSA Arch="IA32" FvBinding="NULL" ModuleName="PeiResourcePublicationLib" >

+      </ModuleSA>        

+    </OTHER_COMPONENTS>  

+  </FrameworkModules>

+  <BuildOptions>

+    <OutputDirectory IntermediateDirectories="UNIFIED"/>

+  </BuildOptions>

+</FrameworkPlatformDescription>

diff --git a/edk2/MdePkg/MdePkg.spd b/edk2/MdePkg/MdePkg.spd
new file mode 100644
index 0000000..9fbb8a6
--- /dev/null
+++ b/edk2/MdePkg/MdePkg.spd
@@ -0,0 +1,1231 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <SpdHeader>

+    <PackageName>MdePkg</PackageName>

+    <Guid>5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec</Guid>

+    <Version>0.3</Version>

+    <Abstract>Framework Module Development Environment Industry Standards</Abstract>

+    <Description>This Package provides headers and libraries that conform to EFI/Framework Industry standards.</Description>

+    <Copyright>Copyright (c) 2006,  Intel Corporation.</Copyright>

+    <License>

+      All rights reserved.

+      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.

+     </License>

+    <Created>2006-03-18 19:02</Created>

+    <Updated>2006-03-19 15:18</Updated>

+    <URL>http://www.TianoCore.org</URL>

+    <PackageType>SOURCE</PackageType>

+    <ReadOnly>true</ReadOnly>

+    <RePackage>false</RePackage>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </SpdHeader>

+  <LibraryClassDeclarations>

+    <LibraryClassDeclaration>

+      <LibraryClass>BaseLib</LibraryClass>

+      <IncludeHeader>Include/Library/BaseLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>BaseMemoryLib</LibraryClass>

+      <IncludeHeader>Include/Library/BaseMemoryLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>CacheMaintenanceLib</LibraryClass>

+      <IncludeHeader>Include/Library/CacheMaintenanceLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>CpuLib</LibraryClass>

+      <IncludeHeader>Include/Library/CpuLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>DebugLib</LibraryClass>

+      <IncludeHeader>Include/Library/DebugLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>DevicePathLib</LibraryClass>

+      <IncludeHeader>Include/Library/DevicePathLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>DxeCoreEntryPoint</LibraryClass>

+      <IncludeHeader>Include/Library/DxeCoreEntryPoint.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>DxeRuntimeDriverLib</LibraryClass>

+      <IncludeHeader>Include/Library/DxeRuntimeDriverLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>DxeServicesTableLib</LibraryClass>

+      <IncludeHeader>Include/Library/DxeServicesTableLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>DxeSmmDriverEntryPoint</LibraryClass>

+      <IncludeHeader>Include/Library/DxeSmmDriverEntryPoint.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>HiiLib</LibraryClass>

+      <IncludeHeader>Include/Library/HiiLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>HobLib</LibraryClass>

+      <IncludeHeader>Include/Library/HobLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>IoLib</LibraryClass>

+      <IncludeHeader>Include/Library/IoLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>MemoryAllocationLib</LibraryClass>

+      <IncludeHeader>Include/Library/MemoryAllocationLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PcdLib</LibraryClass>

+      <IncludeHeader>Include/Library/PcdLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PciCf8Lib</LibraryClass>

+      <IncludeHeader>Include/Library/PciCf8Lib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PciExpressLib</LibraryClass>

+      <IncludeHeader>Include/Library/PciExpressLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PciLib</LibraryClass>

+      <IncludeHeader>Include/Library/PciLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PciSegmentLib</LibraryClass>

+      <IncludeHeader>Include/Library/PciSegmentLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PeCoffGetEntryPointLib</LibraryClass>

+      <IncludeHeader>Include/Library/PeCoffGetEntryPointLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PeCoffLib</LibraryClass>

+      <IncludeHeader>Include/Library/PeCoffLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PeiCoreEntryPoint</LibraryClass>

+      <IncludeHeader>Include/Library/PeiCoreEntryPoint.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PeiCoreLib</LibraryClass>

+      <IncludeHeader>Include/Library/PeiCoreLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PeimEntryPoint</LibraryClass>

+      <IncludeHeader>Include/Library/PeimEntryPoint.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PeiServicesTablePointerLib</LibraryClass>

+      <IncludeHeader>Include/Library/PeiServicesTablePointerLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PerformanceLib</LibraryClass>

+      <IncludeHeader>Include/Library/PerformanceLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>PrintLib</LibraryClass>

+      <IncludeHeader>Include/Library/PrintLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>ReportStatusCodeLib</LibraryClass>

+      <IncludeHeader>Include/Library/ReportStatusCodeLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>ResourcePublicationLib</LibraryClass>

+      <IncludeHeader>Include/Library/ResourcePublicationLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>SmbusLib</LibraryClass>

+      <IncludeHeader>Include/Library/SmbusLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>TimerLib</LibraryClass>

+      <IncludeHeader>Include/Library/TimerLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>Uefi2PortLib</LibraryClass>

+      <IncludeHeader>Include/Library/Uefi2PortLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>UefiBootServicesTableLib</LibraryClass>

+      <IncludeHeader>Include/Library/UefiBootServicesTableLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>UefiDecompressLib</LibraryClass>

+      <IncludeHeader>Include/Library/UefiDecompressLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>UefiDriverEntryPoint</LibraryClass>

+      <IncludeHeader>Include/Library/UefiDriverEntryPoint.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>UefiDriverModelLib</LibraryClass>

+      <IncludeHeader>Include/Library/UefiDriverModelLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>UefiLib</LibraryClass>

+      <IncludeHeader>Include/Library/UefiLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+    <LibraryClassDeclaration>

+      <LibraryClass>UefiRuntimeServicesTableLib</LibraryClass>

+      <IncludeHeader>Include/Library/UefiRuntimeServicesTableLib.h</IncludeHeader>

+    </LibraryClassDeclaration>

+  </LibraryClassDeclarations>

+  <MsaFiles>

+    <MsaFile>

+      <Filename>Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseDebugLibNull/BaseDebugLibNull.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseDebugLibReportStatusCode/BaseDebugLibReportStatusCode.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePerformanceLibNull/BasePerformanceLibNull.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePcdLibNull/BasePcdLibNull.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseLib/BaseLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseMemoryLib/BaseMemoryLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseMemoryLibMmx/BaseMemoryLibMmx.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseMemoryLibSse2/BaseMemoryLibSse2.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePeCoffLib/BasePeCoffLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePrintLib/BasePrintLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseSmbusLib/BaseSmbusLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiSmbusLib/PeiSmbusLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeSmbusLib/DxeSmbusLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseUefiDecompressLib/BaseUefiDecompressLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePciCf8Lib/BasePciCf8Lib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePciExpressLib/BasePciExpressLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePciLibCf8/BasePciLibCf8.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BasePciLibPciExpress/BasePciLibPciExpress.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/BaseTimerLibLocalApic/BaseTimerLibLocalApic.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeCoreEntryPoint/DxeCoreEntryPoint.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeCoreHobLib/DxeCoreHobLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeHobLib/DxeHobLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeIoLibCpuIo/DxeIoLibCpuIo.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiIoLibCpuIo/PeiIoLibCpuIo.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxePcdLib/DxePcdLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeServicesTableLib/DxeServicesTableLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/HiiLib/HiiLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiCoreEntryPoint/PeiCoreEntryPoint.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiCoreLib/PeiCoreLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiHobLib/PeiHobLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiMemoryLib/PeiMemoryLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeimEntryPoint/PeimEntryPoint.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiPcdLib/PeiPcdLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiResourcePublicationLib/PeiResourcePublicationLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiBootServicesTableLib/UefiBootServicesTableLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiDebugLibConOut/UefiDebugLibConOut.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiDebugLibStdErr/UefiDebugLibStdErr.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiDevicePathLib/UefiDevicePathLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiDriverEntryPoint/UefiDriverEntryPoint.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiDriverModelLib/UefiDriverModelLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiLib/UefiLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiMemoryLib/UefiMemoryLib.msa</Filename>

+    </MsaFile>

+    <MsaFile>

+      <Filename>Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.msa</Filename>

+    </MsaFile>

+  </MsaFiles>

+  <PackageHeaders>

+    <IncludeHeader ModuleType="BASE">Include/Base.h</IncludeHeader>

+    <IncludeHeader ModuleType="SEC">Include/Peim.h</IncludeHeader>

+    <IncludeHeader ModuleType="PEI_CORE">Include/PeiCore.h</IncludeHeader>

+    <IncludeHeader ModuleType="PEIM">Include/Peim.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_CORE">Include/DxeCore.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_DRIVER">Include/Dxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_RUNTIME_DRIVER">Include/Dxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_SMM_DRIVER">Include/Dxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="DXE_SAL_DRIVER">Include/Dxe.h</IncludeHeader>

+    <IncludeHeader ModuleType="UEFI_DRIVER">Include/Uefi.h</IncludeHeader>

+    <IncludeHeader ModuleType="UEFI_APPLICATION">Include/Uefi.h</IncludeHeader>

+  </PackageHeaders>

+  <GuidDeclarations>

+    <Entry Name="Acpi10Table">

+      <C_Name>gEfiAcpi10TableGuid</C_Name>

+      <Guid>0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="Acpi20Table">

+      <C_Name>gEfiAcpi20TableGuid</C_Name>

+      <Guid>0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="Acpi30Table">

+      <C_Name>gEfiAcpi30TableGuid</C_Name>

+      <Guid>0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="DebugImageInfoTable">

+      <C_Name>gEfiDebugImageInfoTableGuid</C_Name>

+      <Guid>0x49152e77, 0x1ada, 0x4764, 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b</Guid>

+    </Entry>

+    <Entry Name="GlobalVariable">

+      <C_Name>gEfiGlobalVariableGuid</C_Name>

+      <Guid>0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C</Guid>

+    </Entry>

+    <Entry Name="PartTypeUnused">

+      <C_Name>gEfiPartTypeUnusedGuid</C_Name>

+      <Guid>0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00</Guid>

+    </Entry>

+    <Entry Name="PartTypeSystemPart">

+      <C_Name>gEfiPartTypeSystemPartGuid</C_Name>

+      <Guid>0xc12a7328, 0xf81f, 0x11d2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b</Guid>

+    </Entry>

+    <Entry Name="PartTypeLegacyMbr">

+      <C_Name>gEfiPartTypeLegacyMbrGuid</C_Name>

+      <Guid>0x024dee41, 0x33e7, 0x11d3, 0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f</Guid>

+    </Entry>

+    <Entry Name="MpsTable">

+      <C_Name>gEfiMpsTableGuid</C_Name>

+      <Guid>0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="PcAnsi">

+      <C_Name>gEfiPcAnsiGuid</C_Name>

+      <Guid>0xe0c14753, 0xf9be, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="VT100">

+      <C_Name>gEfiVT100Guid</C_Name>

+      <Guid>0xdfa66065, 0xb419, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="VT100Plus">

+      <C_Name>gEfiVT100PlusGuid</C_Name>

+      <Guid>0x7baec70b, 0x57e0, 0x4c76, 0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43</Guid>

+    </Entry>

+    <Entry Name="VTUTF8">

+      <C_Name>gEfiVTUTF8Guid</C_Name>

+      <Guid>0xad15a0d6, 0x8bec, 0x4acf, 0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88</Guid>

+    </Entry>

+    <Entry Name="SalSystemTable">

+      <C_Name>gEfiSalSystemTableGuid</C_Name>

+      <Guid>0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="SmbiosTable">

+      <C_Name>gEfiSmbiosTableGuid</C_Name>

+      <Guid>0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="Apriori">

+      <C_Name>gAprioriGuid</C_Name>

+      <Guid>0xfc510ee7, 0xffdc, 0x11d4, 0xbd, 0x41, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="DxeServicesTable">

+      <C_Name>gEfiDxeServicesTableGuid</C_Name>

+      <Guid>0x5ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9</Guid>

+    </Entry>

+    <Entry Name="FirmwareFileSystem">

+      <C_Name>gEfiFirmwareFileSystemGuid</C_Name>

+      <Guid>0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF</Guid>

+    </Entry>

+    <Entry Name="FirmwareVolumeTopFile">

+      <C_Name>gEfiFirmwareVolumeTopFileGuid</C_Name>

+      <Guid>0x1BA0062E, 0xC779, 0x4582, 0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x09</Guid>

+    </Entry>

+    <Entry Name="HobList">

+      <C_Name>gEfiHobListGuid</C_Name>

+      <Guid>0x7739f24c, 0x93d7, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="HobMemoryAllocBspStore">

+      <C_Name>gEfiHobMemoryAllocBspStoreGuid</C_Name>

+      <Guid>0x564b33cd, 0xc92a, 0x4593, 0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22</Guid>

+    </Entry>

+    <Entry Name="HobMemoryAllocStack">

+      <C_Name>gEfiHobMemoryAllocStackGuid</C_Name>

+      <Guid>0x4ed4bf27, 0x4092, 0x42e9, 0x80, 0x7d, 0x52, 0x7b, 0x1d, 0x00, 0xc9, 0xbd</Guid>

+    </Entry>

+    <Entry Name="HobMemoryAllocModule">

+      <C_Name>gEfiHobMemoryAllocModuleGuid</C_Name>

+      <Guid>0xf8e21975, 0x0899, 0x4f58, 0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a</Guid>

+    </Entry>

+    <Entry Name="FileInfo">

+      <C_Name>gEfiFileInfoGuid</C_Name>

+      <Guid>0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="FileSystemInfo">

+      <C_Name>gEfiFileSystemInfoGuid</C_Name>

+      <Guid>0x9576e93, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="FileSystemVolumeLabelInfoId">

+      <C_Name>gEfiFileSystemVolumeLabelInfoIdGuid</C_Name>

+      <Guid>0xDB47D7D3, 0xFE81, 0x11d3, 0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>

+    </Entry>

+    <Entry Name="ProcessorProducer">

+      <C_Name>gEfiProcessorProducerGuid</C_Name>

+      <Guid>0x1bf06aea, 0x5bec, 0x4a8d, 0x95, 0x76, 0x74, 0x9b, 0x09, 0x56, 0x2d, 0x30</Guid>

+    </Entry>

+    <Entry Name="ProcessorSubClass">

+      <C_Name>gEfiProcessorSubClassGuid</C_Name>

+      <Guid>0x26fdeb7e, 0xb8af, 0x4ccf, 0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7</Guid>

+    </Entry>

+    <Entry Name="CacheSubClass">

+      <C_Name>gEfiCacheSubClassGuid</C_Name>

+      <Guid>0x7f0013a7, 0xdc79, 0x4b22, 0x80, 0x99, 0x11, 0xf7, 0x5f, 0xdc, 0x82, 0x9d</Guid>

+    </Entry>

+    <Entry Name="MemoryProducer">

+      <C_Name>gEfiMemoryProducerGuid</C_Name>

+      <Guid>0x772484B2, 0x7482, 0x4b91, 0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81</Guid>

+    </Entry>

+    <Entry Name="MemorySubClass">

+      <C_Name>gEfiMemorySubClassGuid</C_Name>

+      <Guid>0x4E8F4EBB, 0x64B9, 0x4e05, 0x9B, 0x18, 0x4C, 0xFE, 0x49, 0x23, 0x50, 0x97</Guid>

+    </Entry>

+    <Entry Name="MiscProducer">

+      <C_Name>gEfiMiscProducerGuid</C_Name>

+      <Guid>0x62512c92, 0x63c4, 0x4d80, 0x82, 0xb1, 0xc1, 0xa4, 0xdc, 0x44, 0x80, 0xe5</Guid>

+    </Entry>

+    <Entry Name="MiscSubClass">

+      <C_Name>gEfiMiscSubClassGuid</C_Name>

+      <Guid>0x772484B2, 0x7482, 0x4b91, 0x9F, 0x9A, 0xAD, 0x43, 0xF8, 0x1C, 0x58, 0x81</Guid>

+    </Entry>

+    <Entry Name="StatusCodeDataTypeString">

+      <C_Name>gEfiStatusCodeDataTypeStringGuid</C_Name>

+      <Guid>0x92D11080, 0x496F, 0x4D95, 0xBE, 0x7E, 0x03, 0x74, 0x88, 0x38, 0x2B, 0x0A</Guid>

+    </Entry>

+    <Entry Name="StatusCodeSpecificData">

+      <C_Name>gEfiStatusCodeSpecificDataGuid</C_Name>

+      <Guid>0x335984bd, 0xe805, 0x409a, 0xb8, 0xf8, 0xd2, 0x7e, 0xce, 0x5f, 0xf7, 0xa6</Guid>

+    </Entry>

+    <Entry Name="StatusCodeDataTypeAssert">

+      <C_Name>gEfiStatusCodeDataTypeAssertGuid</C_Name>

+      <Guid>0xDA571595, 0x4D99, 0x487C, 0x82, 0x7C, 0x26, 0x22, 0x67, 0x7D, 0x33, 0x07</Guid>

+    </Entry>

+    <Entry Name="StatusCodeDataTypeExceptionHandler">

+      <C_Name>gEfiStatusCodeDataTypeExceptionHandlerGuid</C_Name>

+      <Guid>0x3BC2BD12, 0xAD2E, 0x11D5, 0x87, 0xDD, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9</Guid>

+    </Entry>

+    <Entry Name="StatusCodeDataTypeDebug">

+      <C_Name>gEfiStatusCodeDataTypeDebugGuid</C_Name>

+      <Guid>0x9A4E9246, 0xD553, 0x11D5, 0x87, 0xE2, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xb9</Guid>

+    </Entry>

+    <Entry Name="StatusCodeDataTypeError">

+      <C_Name>gEfiStatusCodeDataTypeErrorGuid</C_Name>

+      <Guid>0xAB359CE3, 0x99B3, 0xAE18, 0xC8, 0x9D, 0x95, 0xD3, 0xB0, 0x72, 0xE1, 0x9B</Guid>

+    </Entry>

+    <Entry Name="StatusCodeDataTypeProgressCode">

+      <C_Name>gEfiStatusCodeDataTypeProgressCodeGuid</C_Name>

+      <Guid>0xA356AB39, 0x35C4, 0x35DA, 0xB3, 0x7A, 0xF8, 0xEA, 0x9E, 0x8B, 0x36, 0xA3</Guid>

+    </Entry>

+    <Entry Name="AuthenticationChapRadius">

+      <C_Name>gEfiAuthenticationChapRadiusGuid</C_Name>

+      <Guid>0xd6062b50, 0x15ca, 0x11da, 0x92, 0x19, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d</Guid>

+    </Entry>

+    <Entry Name="AuthenticationChapLocal">

+      <C_Name>gEfiAuthenticationChapLocalGuid</C_Name>

+      <Guid>0xc280c73e, 0x15ca, 0x11da, 0xb0, 0xca, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d</Guid>

+    </Entry>

+    <Entry Name="HashAlgorithmSha1">

+      <C_Name>gEfiHashAlgorithmSha1Guid</C_Name>

+      <Guid>0x2ae9d80f, 0x3fb2, 0x4095, 0xb7, 0xb1, 0xe9, 0x31, 0x57, 0xb9, 0x46, 0xb6</Guid>

+    </Entry>

+    <Entry Name="HashAlgorithmSha224">

+      <C_Name>gEfiHashAlgorithmSha224Guid</C_Name>

+      <Guid>0x8df01a06, 0x9bd5, 0x4bf7, 0xb0, 0x21, 0xdb, 0x4f, 0xd9, 0xcc, 0xf4, 0x5b</Guid>

+    </Entry>

+    <Entry Name="HashAlgorithmSha256">

+      <C_Name>gEfiHashAlgorithmSha256Guid</C_Name>

+      <Guid>0x51aa59de, 0xfdf2, 0x4ea3, 0xbc, 0x63, 0x87, 0x5f, 0xb7, 0x84, 0x2e, 0xe9</Guid>

+    </Entry>

+    <Entry Name="HashAlgorithmSha384">

+      <C_Name>gEfiHashAlgorithmSha384Guid</C_Name>

+      <Guid>0xefa96432, 0xde33, 0x4dd2, 0xae, 0xe6, 0x32, 0x8c, 0x33, 0xdf, 0x77, 0x7a</Guid>

+    </Entry>

+    <Entry Name="HashAlgorithmSha512">

+      <C_Name>gEfiHashAlgorithmSha512Guid</C_Name>

+      <Guid>0xcaa4381e, 0x750c, 0x4770, 0xb8, 0x70, 0x7a, 0x23, 0xb4, 0xe4, 0x21, 0x30</Guid>

+    </Entry>

+    <Entry Name="HashAlgorithmMD5">

+      <C_Name>gEfiHashAlgorithmMD5Guid</C_Name>

+      <Guid>0xaf7c79c, 0x65b5, 0x4319, 0xb0, 0xae, 0x44, 0xec, 0x48, 0x4e, 0x4a, 0xd7</Guid>

+    </Entry>

+    <Entry Name="BootObjectAuthorizationParmset">

+      <C_Name>gBootObjectAuthorizationParmsetGuid</C_Name>

+      <Guid>0xedd35e31, 0x7b9, 0x11d2, 0x83, 0xa3, 0x00, 0xa0, 0xc9, 0x1f, 0xad, 0xcf</Guid>

+    </Entry>

+    <Entry Name="AcpiTableStorage">

+      <C_Name>gEfiAcpiTableStorageGuid</C_Name>

+      <Guid>0x7e374e25, 0x8e01, 0x4fee, 0x87, 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd</Guid>

+    </Entry>

+    <Entry Name="SmmPeiSmramMemoryReserve">

+      <C_Name>gEfiSmmPeiSmramMemoryReserve</C_Name>

+      <Guid>0x6dadf1d1, 0xd4cc, 0x4910, 0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d</Guid>

+    </Entry>

+    <Entry Name="SmmCpuIo">

+      <C_Name>gEfiSmmCpuIoGuid</C_Name>

+      <Guid>0x5f439a0b, 0x45d8, 0x4682, 0xa4, 0xf4, 0xf0, 0x57, 0x6b, 0x51, 0x34, 0x41</Guid>

+    </Entry>

+    <Entry Name="SmmCommunicateHeader">

+      <C_Name>gSmmCommunicateHeaderGuid</C_Name>

+      <Guid>0xf328e36c, 0x23b6, 0x4a95, 0x85, 0x4b, 0x32, 0xe1, 0x95, 0x34, 0xcd, 0x75</Guid>

+    </Entry>

+    <Entry Name="Capsule">

+      <C_Name>gEfiCapsuleGuid</C_Name>

+      <Guid>0x3B6686BD, 0x0D76, 0x4030, 0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0</Guid>

+    </Entry>

+    <Entry Name="ConfigFileName">

+      <C_Name>gEfiConfigFileNameGuid</C_Name>

+      <Guid>0x98B8D59B, 0xE8BA, 0x48EE, 0x98, 0xDD, 0xC2, 0x95, 0x39, 0x2F, 0x1E, 0xDB</Guid>

+    </Entry>

+    <Entry Name="EventLegacyBoot">

+      <C_Name>gEfiEventLegacyBootGuid</C_Name>

+      <Guid>0x2a571201, 0x4966, 0x47f6, 0x8b, 0x86, 0xf3, 0x1e, 0x41, 0xf3, 0x2f, 0x10</Guid>

+    </Entry>

+    <Entry Name="EventExitBootServices">

+      <C_Name>gEfiEventExitBootServicesGuid</C_Name>

+      <Guid>0x27abf055, 0xb1b8, 0x4c26, 0x80, 0x48, 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf</Guid>

+    </Entry>

+    <Entry Name="EventVirtualAddressChange">

+      <C_Name>gEfiEventVirtualAddressChangeGuid</C_Name>

+      <Guid>0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96</Guid>

+    </Entry>

+    <Entry Name="EventMemoryMapChange">

+      <C_Name>gEfiEventMemoryMapChangeGuid</C_Name>

+      <Guid>0x78bee926, 0x692f, 0x48fd, 0x9e, 0xdb, 0x01, 0x42, 0x2e, 0xf0, 0xd7, 0xab</Guid>

+    </Entry>

+    <Entry Name="EventReadyToBoot">

+      <C_Name>gEfiEventReadyToBootGuid</C_Name>

+      <Guid>0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b</Guid>

+    </Entry>

+    <Entry Name="FrameworkDevicePath">

+      <C_Name>gEfiFrameworkDevicePathGuid</C_Name>

+      <Guid>0xb7084e63, 0x46b7, 0x4d1a, 0x86, 0x77, 0xe3, 0x0b, 0x53, 0xdb, 0xf0, 0x50</Guid>

+    </Entry>

+  </GuidDeclarations>

+  <ProtocolDeclarations>

+    <Entry Name="Bds">

+      <C_Name>gEfiBdsArchProtocolGuid</C_Name>

+      <Guid>0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>

+    </Entry>

+    <Entry Name="Cpu">

+      <C_Name>gEfiCpuArchProtocolGuid</C_Name>

+      <Guid>0x26baccb1, 0x6f42, 0x11d4, 0xbc, 0xe7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="Metronome">

+      <C_Name>gEfiMetronomeArchProtocolGuid</C_Name>

+      <Guid>0x26baccb2, 0x6f42, 0x11d4, 0xbc, 0xe7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="MonotonicCounter">

+      <C_Name>gEfiMonotonicCounterArchProtocolGuid</C_Name>

+      <Guid>0x1da97072, 0xbddc, 0x4b30, 0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a</Guid>

+    </Entry>

+    <Entry Name="RealTimeClock">

+      <C_Name>gEfiRealTimeClockArchProtocolGuid</C_Name>

+      <Guid>0x27CFAC87, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>

+    </Entry>

+    <Entry Name="Reset">

+      <C_Name>gEfiResetArchProtocolGuid</C_Name>

+      <Guid>0x27CFAC88, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>

+    </Entry>

+    <Entry Name="Runtime">

+      <C_Name>gEfiRuntimeArchProtocolGuid</C_Name>

+      <Guid>0x96d08253, 0x8483, 0x11d4, 0xbc, 0xf1, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="Security">

+      <C_Name>gEfiSecurityArchProtocolGuid</C_Name>

+      <Guid>0xA46423E3, 0x4617, 0x49f1, 0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39</Guid>

+    </Entry>

+    <Entry Name="StatusCode">

+      <C_Name>gEfiStatusCodeRuntimeProtocolGuid</C_Name>

+      <Guid>0xd2b2b828, 0x826, 0x48a7, 0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0</Guid>

+    </Entry>

+    <Entry Name="Timer">

+      <C_Name>gEfiTimerArchProtocolGuid</C_Name>

+      <Guid>0x26baccb3, 0x6f42, 0x11d4, 0xbc, 0xe7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="Variable">

+      <C_Name>gEfiVariableArchProtocolGuid</C_Name>

+      <Guid>0x1e5668e2, 0x8481, 0x11d4, 0xbc, 0xf1, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="VariableWrite">

+      <C_Name>gEfiVariableWriteArchProtocolGuid</C_Name>

+      <Guid>0x6441f818, 0x6362, 0x4e44, 0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53</Guid>

+    </Entry>

+    <Entry Name="WatchdogTimer">

+      <C_Name>gEfiWatchdogTimerArchProtocolGuid</C_Name>

+      <Guid>0x665E3FF5, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>

+    </Entry>

+    <Entry Name="CpuIo">

+      <C_Name>gEfiCpuIoProtocolGuid</C_Name>

+      <Guid>0xB0732526, 0x38C8, 0x4b40, 0x88, 0x77, 0x61, 0xC7, 0xB0, 0x6A, 0xAC, 0x45</Guid>

+    </Entry>

+    <Entry Name="DataHub">

+      <C_Name>gEfiDataHubProtocolGuid</C_Name>

+      <Guid>0xae80d021, 0x618e, 0x11d4, 0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81</Guid>

+    </Entry>

+    <Entry Name="FirmwareVolume">

+      <C_Name>gEfiFirmwareVolumeProtocolGuid</C_Name>

+      <Guid>0x389F751F, 0x1838, 0x4388, 0x83, 0x90, 0xCD, 0x81, 0x54, 0xBD, 0x27, 0xF8</Guid>

+    </Entry>

+    <Entry Name="FirmwareVolumeBlock">

+      <C_Name>gEfiFirmwareVolumeBlockProtocolGuid</C_Name>

+      <Guid>0xDE28BC59, 0x6228, 0x41BD, 0xBD, 0xF6, 0xA3, 0xB9, 0xAD, 0xB5, 0x8D, 0xA1</Guid>

+    </Entry>

+    <Entry Name="FirmwareVolumeDispatch">

+      <C_Name>gEfiFirmwareVolumeDispatchProtocolGuid</C_Name>

+      <Guid>0x7aa35a69, 0x506c, 0x444f, 0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8</Guid>

+    </Entry>

+    <Entry Name="FormBrowser">

+      <C_Name>gEfiFormBrowserProtocolGuid</C_Name>

+      <Guid>0xe5a1333e, 0xe1b4, 0x4d55, 0xce, 0xeb, 0x35, 0xc3, 0xef, 0x13, 0x34, 0x43</Guid>

+    </Entry>

+    <Entry Name="FormCallback">

+      <C_Name>gEfiFormCallbackProtocolGuid</C_Name>

+      <Guid>0xf3e4543d, 0xcf35, 0x6cef, 0x35, 0xc4, 0x4f, 0xe6, 0x34, 0x4d, 0xfc, 0x54</Guid>

+    </Entry>

+    <Entry Name="Crc32GuidedSectionExtraction">

+      <C_Name>gEfiCrc32GuidedSectionExtractionProtocolGuid</C_Name>

+      <Guid>0xFC1BCDB0, 0x7D31, 0x49aa, 0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83</Guid>

+    </Entry>

+    <Entry Name="Hii">

+      <C_Name>gEfiHiiProtocolGuid</C_Name>

+      <Guid>0xea816d2c, 0xcee5, 0x4f02, 0x99, 0xb5, 0xd3, 0x90, 0x5c, 0xbb, 0xd0, 0x77</Guid>

+    </Entry>

+    <Entry Name="Pcd">

+      <C_Name>gPcdProtocolGuid</C_Name>

+      <Guid>0x11b34006, 0xd85b, 0x4d0a, 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0x0e, 0xf7</Guid>

+    </Entry>

+    <Entry Name="SectionExtraction">

+      <C_Name>gEfiSectionExtractionProtocolGuid</C_Name>

+      <Guid>0x448F5DA4, 0x6DD7, 0x4FE1, 0x93, 0x07, 0x69, 0x22, 0x41, 0x92, 0x21, 0x5D</Guid>

+    </Entry>

+    <Entry Name="Bis">

+      <C_Name>gEfiBisProtocolGuid</C_Name>

+      <Guid>0x0b64aab0, 0x5429, 0x11d4, 0x98, 0x16, 0x00, 0xa0, 0xc9, 0x1f, 0xad, 0xcf</Guid>

+    </Entry>

+    <Entry Name="BlockIo">

+      <C_Name>gEfiBlockIoProtocolGuid</C_Name>

+      <Guid>0x964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="BusSpecificDriverOverride">

+      <C_Name>gEfiBusSpecificDriverOverrideProtocolGuid</C_Name>

+      <Guid>0x3bc1b285, 0x8a15, 0x4a82, 0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65</Guid>

+    </Entry>

+    <Entry Name="ComponentName">

+      <C_Name>gEfiComponentNameProtocolGuid</C_Name>

+      <Guid>0x107a772c, 0xd5e1, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="DebugPort">

+      <C_Name>gEfiDebugPortProtocolGuid</C_Name>

+      <Guid>0xEBA4E8D2, 0x3858, 0x41EC, 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0</Guid>

+    </Entry>

+    <Entry Name="DebugSupport">

+      <C_Name>gEfiDebugSupportProtocolGuid</C_Name>

+      <Guid>0x2755590C, 0x6F3C, 0x42FA, 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25</Guid>

+    </Entry>

+    <Entry Name="Decompress">

+      <C_Name>gEfiDecompressProtocolGuid</C_Name>

+      <Guid>0xd8117cfe, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="DevicePath">

+      <C_Name>gEfiDevicePathProtocolGuid</C_Name>

+      <Guid>0x9576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="DiskIo">

+      <C_Name>gEfiDiskIoProtocolGuid</C_Name>

+      <Guid>0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="DriverBinding">

+      <C_Name>gEfiDriverBindingProtocolGuid</C_Name>

+      <Guid>0x18a031ab, 0xb443, 0x4d1a, 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71</Guid>

+    </Entry>

+    <Entry Name="DriverConfiguration">

+      <C_Name>gEfiDriverConfigurationProtocolGuid</C_Name>

+      <Guid>0x107a772b, 0xd5e1, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="UefiDriverConfiguration">

+      <C_Name>gUefiDriverConfigurationProtocolGuid</C_Name>

+      <Guid>0xbfd7dc1d, 0x24f1, 0x40d9, 0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe</Guid>

+    </Entry>

+    <Entry Name="DriverDiagnostics">

+      <C_Name>gEfiDriverDiagnosticsProtocolGuid</C_Name>

+      <Guid>0x0784924f, 0xe296, 0x11d4, 0x9a, 0x49, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="UefiDriverDiagnostics">

+      <C_Name>gUefiDriverDiagnosticsProtocolGuid</C_Name>

+      <Guid>0x4d330321, 0x025f, 0x4aac, 0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63</Guid>

+    </Entry>

+    <Entry Name="Ebc">

+      <C_Name>gEfiEbcProtocolGuid</C_Name>

+      <Guid>0x13AC6DD1, 0x73D0, 0x11D4, 0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7</Guid>

+    </Entry>

+    <Entry Name="NetworkInterfaceIdentifier">

+      <C_Name>gEfiNetworkInterfaceIdentifierProtocolGuid</C_Name>

+      <Guid>0xE18541CD, 0xF755, 0x4f73, 0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29</Guid>

+    </Entry>

+    <Entry Name="NetworkInterfaceIdentifier31">

+      <C_Name>gEfiNetworkInterfaceIdentifierProtocolGuid_31</C_Name>

+      <Guid>0x1ACED566, 0x76ED, 0x4218, 0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89</Guid>

+    </Entry>

+    <Entry Name="NetworkInterfaceIdentifier2">

+      <C_Name>gEfiNetworkInterfaceIdentifierProtocolGuid_31</C_Name>

+      <Guid>0x1ACED566, 0x76ED, 0x4218, 0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89</Guid>

+    </Entry>

+    <Entry Name="LoadedImage">

+      <C_Name>gEfiLoadedImageProtocolGuid</C_Name>

+      <Guid>0x5B1B31A1, 0x9562, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B</Guid>

+    </Entry>

+    <Entry Name="LoadFile">

+      <C_Name>gEfiLoadFileProtocolGuid</C_Name>

+      <Guid>0x56EC3091, 0x954C, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B</Guid>

+    </Entry>

+    <Entry Name="PciIo">

+      <C_Name>gEfiPciIoProtocolGuid</C_Name>

+      <Guid>0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a</Guid>

+    </Entry>

+    <Entry Name="PciRootBridgeIo">

+      <C_Name>gEfiPciRootBridgeIoProtocolGuid</C_Name>

+      <Guid>0x2f707ebb, 0x4a1a, 0x11d4, 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="PlatformDriverOverride">

+      <C_Name>gEfiPlatformDriverOverrideProtocolGuid</C_Name>

+      <Guid>0x6b30c738, 0xa391, 0x11d4, 0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="PxeBaseCode">

+      <C_Name>gEfiPxeBaseCodeProtocolGuid</C_Name>

+      <Guid>0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="PxeBaseCodeCallBack">

+      <C_Name>gEfiPxeBaseCodeCallbackProtocolGuid</C_Name>

+      <Guid>0x245dca21, 0xfb7b, 0x11d3, 0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="ScsiPassThru">

+      <C_Name>gEfiScsiPassThruProtocolGuid</C_Name>

+      <Guid>0xa59e8fcf, 0xbda0, 0x43bb, 0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77</Guid>

+    </Entry>

+    <Entry Name="SerialIo">

+      <C_Name>gEfiSerialIoProtocolGuid</C_Name>

+      <Guid>0xBB25CF6F, 0xF1D4, 0x11D2, 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD</Guid>

+    </Entry>

+    <Entry Name="SimpleFileSystem">

+      <C_Name>gEfiSimpleFileSystemProtocolGuid</C_Name>

+      <Guid>0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="SimpleNetwork">

+      <C_Name>gEfiSimpleNetworkProtocolGuid</C_Name>

+      <Guid>0xA19832B9, 0xAC25, 0x11D3, 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D</Guid>

+    </Entry>

+    <Entry Name="SimplePointer">

+      <C_Name>gEfiSimplePointerProtocolGuid</C_Name>

+      <Guid>0x31878c87, 0x0b75, 0x11d5, 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="SimpleTextIn">

+      <C_Name>gEfiSimpleTextInProtocolGuid</C_Name>

+      <Guid>0x387477c1, 0x69c7, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="SimpleTextOut">

+      <C_Name>gEfiSimpleTextOutProtocolGuid</C_Name>

+      <Guid>0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+    <Entry Name="UgaDraw">

+      <C_Name>gEfiUgaDrawProtocolGuid</C_Name>

+      <Guid>0x982c298b, 0xf4fa, 0x41cb, 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39</Guid>

+    </Entry>

+    <Entry Name="UnicodeCollation">

+      <C_Name>gEfiUnicodeCollationProtocolGuid</C_Name>

+      <Guid>0x1d85cd7f, 0xf43d, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d</Guid>

+    </Entry>

+    <Entry Name="UsbHc">

+      <C_Name>gEfiUsbHcProtocolGuid</C_Name>

+      <Guid>0xf5089266, 0x1aa0, 0x4953, 0x97, 0xd8, 0x56, 0x2f, 0x8a, 0x73, 0xb5, 0x19</Guid>

+    </Entry>

+    <Entry Name="PciPlatform">

+      <C_Name>gEfiPciPlatformProtocolGuid</C_Name>

+      <Guid>0x7d75280, 0x27d4, 0x4d69, 0x90, 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41</Guid>

+    </Entry>

+    <Entry Name="IncompatiblePciDeviceSupport">

+      <C_Name>gEfiIncompatiblePciDeviceSupportProtocolGuid</C_Name>

+      <Guid>0xeb23f55a, 0x7863, 0x4ac2, 0x8d, 0x3d, 0x95, 0x65, 0x35, 0xde, 0x03, 0x75</Guid>

+    </Entry>

+    <Entry Name="PciHotPlugInit">

+      <C_Name>gEfiPciHotPlugInitProtocolGuid</C_Name>

+      <Guid>0xaa0e8bc1, 0xdabc, 0x46b0, 0xa8, 0x44, 0x37, 0xb8, 0x16, 0x9b, 0x2b, 0xea</Guid>

+    </Entry>

+    <Entry Name="PciHostBridgeResourceAllocation">

+      <C_Name>gEfiPciHostBridgeResourceAllocationProtocolGuid</C_Name>

+      <Guid>0xCF8034BE, 0x6768, 0x4d8b, 0xb7, 0x39, 0x7c, 0xce, 0x68, 0x3a, 0x9f, 0xbe</Guid>

+    </Entry>

+    <Entry Name="IdeControllerInit">

+      <C_Name>gEfiIdeControllerInitProtocolGuid</C_Name>

+      <Guid>0xa1e37052, 0x80d9, 0x4e65, 0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9</Guid>

+    </Entry>

+    <Entry Name="UsbIo">

+      <C_Name>gEfiUsbIoProtocolGuid</C_Name>

+      <Guid>0x2B2F68D6, 0x0CD2, 0x44cf, 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75</Guid>

+    </Entry>

+    <Entry Name="Arp">

+      <C_Name>gEfiArpProtocolGuid</C_Name>

+      <Guid>0xf4b427bb, 0xba21, 0x4f16, 0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c</Guid>

+    </Entry>

+    <Entry Name="ArpServiceBinding">

+      <C_Name>gEfiArpServiceBindingProtocolGuid</C_Name>

+      <Guid>0xf44c00ee, 0x1f2c, 0x4a00, 0xaa, 0x09, 0x1c, 0x9f, 0x3e, 0x08, 0x00, 0xa3</Guid>

+    </Entry>

+    <Entry Name="Dhcp4">

+      <C_Name>gEfiDhcp4ProtocolGuid</C_Name>

+      <Guid>0x8a219718, 0x4ef5, 0x4761, 0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56</Guid>

+    </Entry>

+    <Entry Name="Dhcp4ServiceBinding">

+      <C_Name>gEfiDhcp4ServiceBindingProtocolGuid</C_Name>

+      <Guid>0x9d9a39d8, 0xbd42, 0x4a73, 0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80</Guid>

+    </Entry>

+    <Entry Name="Ip4">

+      <C_Name>gEfiIp4ProtocolGuid</C_Name>

+      <Guid>0x41d94cd2, 0x35b6, 0x455a, 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd</Guid>

+    </Entry>

+    <Entry Name="Ip4ServiceBinding">

+      <C_Name>gEfiIp4ServiceBindingProtocolGuid</C_Name>

+      <Guid>0xc51711e7, 0xb4bf, 0x404a, 0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4</Guid>

+    </Entry>

+    <Entry Name="Ip4Config">

+      <C_Name>gEfiIp4ConfigProtocolGuid</C_Name>

+      <Guid>0x3b95aa31, 0x3793, 0x434b, 0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e</Guid>

+    </Entry>

+    <Entry Name="ManagedNetwork">

+      <C_Name>gEfiManagedNetworkProtocolGuid</C_Name>

+      <Guid>0x3b95aa31, 0x3793, 0x434b, 0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e</Guid>

+    </Entry>

+    <Entry Name="ManagedNetworkServiceBinding">

+      <C_Name>gEfiManagedNetworkServiceBindingProtocolGuid</C_Name>

+      <Guid>0xf36ff770, 0xa7e1, 0x42cf, 0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c</Guid>

+    </Entry>

+    <Entry Name="Mtftp4">

+      <C_Name>gEfiMtftp4ProtocolGuid</C_Name>

+      <Guid>0x3ad9df29, 0x4501, 0x478d, 0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3</Guid>

+    </Entry>

+    <Entry Name="Mtftp4ServiceBinding">

+      <C_Name>gEfiMtftp4ServiceBindingProtocolGuid</C_Name>

+      <Guid>0x2FE800BE, 0x8F01, 0x4aa6, 0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F</Guid>

+    </Entry>

+    <Entry Name="Tcp4">

+      <C_Name>gEfiTcp4ProtocolGuid</C_Name>

+      <Guid>0x65530BC7, 0xA359, 0x410f, 0xB0, 0x10, 0x5A, 0xAD, 0xC7, 0xEC, 0x2B, 0x62</Guid>

+    </Entry>

+    <Entry Name="Tcp4ServiceBinding">

+      <C_Name>gEfiTcp4ServiceBindingProtocolGuid</C_Name>

+      <Guid>0x00720665, 0x67EB, 0x4a99, 0xBA, 0xF7, 0xD3, 0xC3, 0x3A, 0x1C, 0x7C, 0xC9</Guid>

+    </Entry>

+    <Entry Name="Udp4">

+      <C_Name>gEfiUdp4ProtocolGuid</C_Name>

+      <Guid>0x3ad9df29, 0x4501, 0x478d, 0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3</Guid>

+    </Entry>

+    <Entry Name="Udp4ServiceBinding">

+      <C_Name>gEfiUdp4ServiceBindingProtocolGuid</C_Name>

+      <Guid>0x83f01464, 0x99bd, 0x45e5, 0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6</Guid>

+    </Entry>

+    <Entry Name="AuthenticationInfo">

+      <C_Name>gEfiAuthenticationInfoProtocolGuid</C_Name>

+      <Guid>0x7671d9d0, 0x53db, 0x4173, 0xaa, 0x69, 0x23, 0x27, 0xf2, 0x1f, 0x0b, 0xc7</Guid>

+    </Entry>

+    <Entry Name="DevicePathFromText">

+      <C_Name>gEfiDevicePathFromTextProtocolGuid</C_Name>

+      <Guid>0x5c99a21, 0xc70f, 0x4ad2, 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e</Guid>

+    </Entry>

+    <Entry Name="DevicePathToText">

+      <C_Name>gEfiDevicePathToTextProtocolGuid</C_Name>

+      <Guid>0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c</Guid>

+    </Entry>

+    <Entry Name="DevicePathUtilities">

+      <C_Name>gEfiDevicePathUtilitiesProtocolGuid</C_Name>

+      <Guid>0x379be4e, 0xd706, 0x437d, 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4</Guid>

+    </Entry>

+    <Entry Name="EdidActive">

+      <C_Name>gEfiEdidActiveProtocolGuid</C_Name>

+      <Guid>0xbd8c1056, 0x9f36, 0x44ec, 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86</Guid>

+    </Entry>

+    <Entry Name="EdidDiscovered">

+      <C_Name>gEfiEdidDiscoveredProtocolGuid</C_Name>

+      <Guid>0x1c0c34f6, 0xd380, 0x41fa, 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa</Guid>

+    </Entry>

+    <Entry Name="EdidOverride">

+      <C_Name>gEfiEdidOverrideProtocolGuid</C_Name>

+      <Guid>0x48ecb431, 0xfb72, 0x45c0, 0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x04, 0x0b, 0xd5</Guid>

+    </Entry>

+    <Entry Name="GraphicsOutput">

+      <C_Name>gEfiGraphicsOutputProtocolGuid</C_Name>

+      <Guid>0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a</Guid>

+    </Entry>

+    <Entry Name="Hash">

+      <C_Name>gEfiHashProtocolGuid</C_Name>

+      <Guid>0xc5184932, 0xdba5, 0x46db, 0xa5, 0xba, 0xcc, 0x0b, 0xda, 0x9c, 0x14, 0x35</Guid>

+    </Entry>

+    <Entry Name="HashServiceBinding">

+      <C_Name>gEfiHashServiceBindingProtocolGuid</C_Name>

+      <Guid>0x42881c98, 0xa4f3, 0x44b0, 0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd</Guid>

+    </Entry>

+    <Entry Name="IScsiInitiatorName">

+      <C_Name>gEfiIScsiInitiatorNameProtocolGuid</C_Name>

+      <Guid>0xa6a72875, 0x2962, 0x4c18, 0x9f, 0x46, 0x8d, 0xa6, 0x44, 0xcc, 0xfe, 0x00</Guid>

+    </Entry>

+    <Entry Name="ScsiIo">

+      <C_Name>gEfiScsiIoProtocolGuid</C_Name>

+      <Guid>0x932f4736, 0x2362, 0x4002, 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85</Guid>

+    </Entry>

+    <Entry Name="ExtScsiPassThru">

+      <C_Name>gEfiExtScsiPassThruProtocolGuid</C_Name>

+      <Guid>0x1d3de7f0, 0x0807, 0x424f, 0xaa, 0x69, 0x11, 0xa5, 0x4e, 0x19, 0xa4, 0x6f</Guid>

+    </Entry>

+    <Entry Name="TapeIo">

+      <C_Name>gEfiTapeIoProtocolGuid</C_Name>

+      <Guid>0x1e93e633, 0xd65a, 0x459e, 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18</Guid>

+    </Entry>

+    <Entry Name="Usb2Hc">

+      <C_Name>gEfiUsb2HcProtocolGuid</C_Name>

+      <Guid>0x3e745226, 0x9818, 0x45b6, 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc</Guid>

+    </Entry>

+    <Entry Name="SecurityPolicy">

+      <C_Name>gEfiSecurityPolicyProtocolGuid</C_Name>

+      <Guid>0x78E4D245, 0xCD4D, 0x4a05, 0xA2, 0xBA, 0x47, 0x43, 0xE8, 0x6C, 0xFC, 0xAB</Guid>

+    </Entry>

+    <Entry Name="AcpiSupport">

+      <C_Name>gEfiAcpiSupportProtocolGuid</C_Name>

+      <Guid>0xdbff9d55, 0x89b7, 0x46da, 0xbd, 0xdf, 0x67, 0x7d, 0x3d, 0xc0, 0x24, 0x1d</Guid>

+    </Entry>

+    <Entry Name="BootScriptSave">

+      <C_Name>gEfiBootScriptSaveProtocolGuid</C_Name>

+      <Guid>0x470e1529, 0xb79e, 0x4e32, 0xa0, 0xfe, 0x6a, 0x15, 0x6d, 0x29, 0xf9, 0xb2</Guid>

+    </Entry>

+    <Entry Name="Smbus">

+      <C_Name>gEfiSmbusProtocolGuid</C_Name>

+      <Guid>0xe49d33ed, 0x513d, 0x4634, 0xb6, 0x98, 0x6f, 0x55, 0xaa, 0x75, 0x1c, 0x1b</Guid>

+    </Entry>

+    <Entry Name="LegacyBios">

+      <C_Name>gEfiLegacyBiosProtocolGuid</C_Name>

+      <Guid>0xdb9a1e3d, 0x45cb, 0x4abb, 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d</Guid>

+    </Entry>

+    <Entry Name="Legacy8259">

+      <C_Name>gEfiLegacy8259ProtocolGuid</C_Name>

+      <Guid>0x38321dba, 0x4fe0, 0x4e17, 0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1</Guid>

+    </Entry>

+    <Entry Name="LegacyBiosPlatform">

+      <C_Name>gEfiLegacyBiosPlatformProtocolGuid</C_Name>

+      <Guid>0x783658a3, 0x4172, 0x4421, 0xa2, 0x99, 0xe0, 0x09, 0x07, 0x9c, 0x0c, 0xb4</Guid>

+    </Entry>

+    <Entry Name="LegacyInterrupt">

+      <C_Name>gEfiLegacyInterruptProtocolGuid</C_Name>

+      <Guid>0x31ce593d, 0x108a, 0x485d, 0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe</Guid>

+    </Entry>

+    <Entry Name="LegacyRegion">

+      <C_Name>gEfiLegacyRegionProtocolGuid</C_Name>

+      <Guid>0xfc9013a, 0x0568, 0x4ba9, 0x9b, 0x7e, 0xc9, 0xc3, 0x90, 0xa6, 0x60, 0x9b</Guid>

+    </Entry>

+    <Entry Name="SmmAccess">

+      <C_Name>gEfiSmmAccessProtocolGuid</C_Name>

+      <Guid>0x3792095a, 0xe309, 0x4c1e, 0xaa, 0x01, 0x85, 0xf5, 0x65, 0x5a, 0x17, 0xf1</Guid>

+    </Entry>

+    <Entry Name="SmmBase">

+      <C_Name>gEfiSmmBaseProtocolGuid</C_Name>

+      <Guid>0x1390954D, 0xda95, 0x4227, 0x93, 0x28, 0x72, 0x82, 0xc2, 0x17, 0xda, 0xa8</Guid>

+    </Entry>

+    <Entry Name="SmmControl">

+      <C_Name>gEfiSmmControlProtocolGuid</C_Name>

+      <Guid>0x8d12e231, 0xc667, 0x4fd1, 0x98, 0xf2, 0x24, 0x49, 0xa7, 0xe7, 0xb2, 0xe5</Guid>

+    </Entry>

+    <Entry Name="SmmGpiDispatch">

+      <C_Name>gEfiSmmGpiDispatchProtocolGuid</C_Name>

+      <Guid>0xe0744b81, 0x9513, 0x49cd, 0x8c, 0xea, 0xe9, 0x24, 0x5e, 0x70, 0x39, 0xda</Guid>

+    </Entry>

+    <Entry Name="SmmIchnDispatch">

+      <C_Name>gEfiSmmIchnDispatchProtocolGuid</C_Name>

+      <Guid>0xc50b323e, 0x9075, 0x4f2a, 0xac, 0x8e, 0xd2, 0x59, 0x6a, 0x10, 0x85, 0xcc</Guid>

+    </Entry>

+    <Entry Name="SmmPeriodicTimerDispatch">

+      <C_Name>gEfiSmmPeriodicTimerDispatchProtocolGuid</C_Name>

+      <Guid>0x9cca03fc, 0x4c9e, 0x4a19, 0x9b, 0x06, 0xed, 0x7b, 0x47, 0x9b, 0xde, 0x55</Guid>

+    </Entry>

+    <Entry Name="SmmPowerButtonDispatch">

+      <C_Name>gEfiSmmPowerButtonDispatchProtocolGuid</C_Name>

+      <Guid>0xb709efa0, 0x47a6, 0x4b41, 0xb9, 0x31, 0x12, 0xec, 0xe7, 0xa8, 0xee, 0x56</Guid>

+    </Entry>

+    <Entry Name="SmmStandbyButtonDispatch">

+      <C_Name>gEfiSmmStandbyButtonDispatchProtocolGuid</C_Name>

+      <Guid>0x78965b98, 0xb0bf, 0x449e, 0x8b, 0x22, 0xd2, 0x91, 0x4e, 0x49, 0x8a, 0x98</Guid>

+    </Entry>

+    <Entry Name="SmmStatusCode">

+      <C_Name>gEfiSmmStatusCodeProtocolGuid</C_Name>

+      <Guid>0x6afd2b77, 0x98c1, 0x4acd, 0xa6, 0xf9, 0x8a, 0x94, 0x39, 0xde, 0x0f, 0xb1</Guid>

+    </Entry>

+    <Entry Name="SmmSwDispatch">

+      <C_Name>gEfiSmmSwDispatchProtocolGuid</C_Name>

+      <Guid>0xe541b773, 0xdd11, 0x420c, 0xb0, 0x26, 0xdf, 0x99, 0x36, 0x53, 0xf8, 0xbf</Guid>

+    </Entry>

+    <Entry Name="SmmSxDispatch">

+      <C_Name>gEfiSmmSxDispatchProtocolGuid</C_Name>

+      <Guid>0x14fc52be, 0x01dc, 0x426c, 0x91, 0xae, 0xa2, 0x3c, 0x3e, 0x22, 0x0a, 0xe8</Guid>

+    </Entry>

+    <Entry Name="SmmUsbDispatch">

+      <C_Name>gEfiSmmUsbDispatchProtocolGuid</C_Name>

+      <Guid>0xa05b6ffd, 0x87af, 0x4e42, 0x95, 0xc9, 0x62, 0x28, 0xb6, 0x3c, 0xf3, 0xf3</Guid>

+    </Entry>

+    <Entry Name="DeviceIo">

+      <C_Name>gEfiDeviceIoProtocolGuid</C_Name>

+      <Guid>0xaf6ac311, 0x84c3, 0x11d2, 0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b</Guid>

+    </Entry>

+  </ProtocolDeclarations>

+  <PpiDeclarations>

+    <Entry Name="BootInRecoveryMode">

+      <C_Name>gEfiPeiBootInRecoveryModePpiGuid</C_Name>

+      <Guid>0x17ee496a, 0xd8e4, 0x4b9a, 0x94, 0xd1, 0xce, 0x82, 0x72, 0x30, 0x08, 0x50</Guid>

+    </Entry>

+    <Entry Name="CpuIo">

+      <C_Name>gEfiPeiCpuIoPpiInServiceTableGuid</C_Name>

+      <Guid>0xe6af1f7b, 0xfc3f, 0x46da, 0xa8, 0x28, 0xa3, 0xb4, 0x57, 0xa4, 0x42, 0x82</Guid>

+    </Entry>

+    <Entry Name="DxeIpl">

+      <C_Name>gEfiDxeIplPpiGuid</C_Name>

+      <Guid>0xae8ce5d, 0xe448, 0x4437, 0xa8, 0xd7, 0xeb, 0xf5, 0xf1, 0x94, 0xf7, 0x31</Guid>

+    </Entry>

+    <Entry Name="EndOfPeiSignal">

+      <C_Name>gEfiEndOfPeiSignalPpiGuid</C_Name>

+      <Guid>0x605EA650, 0xC65C, 0x42e1, 0xBA, 0x80, 0x91, 0xA5, 0x2A, 0xB6, 0x18, 0xC6</Guid>

+    </Entry>

+    <Entry Name="FindFv">

+      <C_Name>gEfiFindFvPpiGuid</C_Name>

+      <Guid>0x36164812, 0xa023, 0x44e5, 0xbd, 0x85, 0x05, 0xbf, 0x3c, 0x77, 0x00, 0xaa</Guid>

+    </Entry>

+    <Entry Name="FvFileLoader">

+      <C_Name>gEfiPeiFvFileLoaderPpiGuid</C_Name>

+      <Guid>0x7e1f0d85, 0x04ff, 0x4bb2, 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8</Guid>

+    </Entry>

+    <Entry Name="MasterBootMode">

+      <C_Name>gEfiPeiMasterBootModePpiGuid</C_Name>

+      <Guid>0x7408d748, 0xfc8c, 0x4ee6, 0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10</Guid>

+    </Entry>

+    <Entry Name="MemoryDiscovered">

+      <C_Name>gEfiPeiMemoryDiscoveredPpiGuid</C_Name>

+      <Guid>0xf894643d, 0xc449, 0x42d1, 0x8e, 0xa8, 0x85, 0xbd, 0xd8, 0xc6, 0x5b, 0xde</Guid>

+    </Entry>

+    <Entry Name="PciCfg">

+      <C_Name>gEfiPciCfgPpiInServiceTableGuid</C_Name>

+      <Guid>0xe1f2eba0, 0xf7b9, 0x4a26, 0x86, 0x20, 0x13, 0x12, 0x21, 0x64, 0x2a, 0x90</Guid>

+    </Entry>

+    <Entry Name="ReadOnlyVariable">

+      <C_Name>gEfiPeiReadOnlyVariablePpiGuid</C_Name>

+      <Guid>0x3cdc90c6, 0x13fb, 0x4a75, 0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa</Guid>

+    </Entry>

+    <Entry Name="RecoveryModule">

+      <C_Name>gEfiPeiRecoveryModulePpiGuid</C_Name>

+      <Guid>0xFB6D9542, 0x612D, 0x4f45, 0x87, 0x2F, 0x5C, 0xFF, 0x52, 0xE9, 0x3D, 0xCF</Guid>

+    </Entry>

+    <Entry Name="Reset">

+      <C_Name>gEfiPeiResetPpiGuid</C_Name>

+      <Guid>0xef398d58, 0x9dfd, 0x4103, 0xbf, 0x94, 0x78, 0xc6, 0xf4, 0xfe, 0x71, 0x2f</Guid>

+    </Entry>

+    <Entry Name="S3Resume">

+      <C_Name>gEfiPeiS3ResumePpiGuid</C_Name>

+      <Guid>0x4426CCB2, 0xE684, 0x4a8a, 0xAE, 0x40, 0x20, 0xD4, 0xB0, 0x25, 0xB7, 0x10</Guid>

+    </Entry>

+    <Entry Name="SecPlatformInformation">

+      <C_Name>gEfiSecPlatformInformationPpiGuid</C_Name>

+      <Guid>0x6f8c2b35, 0xfef4, 0x448d, 0x82, 0x56, 0xe1, 0x1b, 0x19, 0xd6, 0x10, 0x77</Guid>

+    </Entry>

+    <Entry Name="SectionExtraction">

+      <C_Name>gEfiPeiSectionExtractionPpiGuid</C_Name>

+      <Guid>0x4F89E208, 0xE144, 0x4804, 0x9E, 0xC8, 0x0F, 0x89, 0x4F, 0x7E, 0x36, 0xD7</Guid>

+    </Entry>

+    <Entry Name="Security">

+      <C_Name>gEfiPeiSecurityPpiGuid</C_Name>

+      <Guid>0x1388066e, 0x3a57, 0x4efa, 0x98, 0xf3, 0xc1, 0x2f, 0x3a, 0x95, 0x8a, 0x29</Guid>

+    </Entry>

+    <Entry Name="StatusCode">

+      <C_Name>gEfiPeiStatusCodePpiGuid</C_Name>

+      <Guid>0x229832d3, 0x7a30, 0x4b36, 0xb8, 0x27, 0xf4, 0x0c, 0xb7, 0xd4, 0x54, 0x36</Guid>

+    </Entry>

+    <Entry Name="Pcd">

+      <C_Name>gPcdPpiGuid</C_Name>

+      <Guid>0x5d5c0e21, 0x749c, 0x4063, 0x81, 0xaf, 0xbc, 0x74, 0xfc, 0x79, 0xab, 0x5c</Guid>

+    </Entry>

+    <Entry Name="BootScriptExecuter">

+      <C_Name>gEfiPeiBootScriptExecuterPpiGuid</C_Name>

+      <Guid>0xabd42895, 0x78cf, 0x4872, 0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xff</Guid>

+    </Entry>

+    <Entry Name="Smbus">

+      <C_Name>gEfiPeiSmbusPpiGuid</C_Name>

+      <Guid>0xabd42895, 0x78cf, 0x4872, 0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xda</Guid>

+    </Entry>

+    <Entry Name="BlockIo">

+      <C_Name>gEfiPeiBlockIoPpiGuid</C_Name>

+      <Guid>0x695d8aa1, 0x42ee, 0x4c46, 0x80, 0x5c, 0x6e, 0xa6, 0xbc, 0xe7, 0x99, 0xe3</Guid>

+    </Entry>

+    <Entry Name="DeviceRecoveryModule">

+      <C_Name>gEfiPeiDeviceRecoveryModulePpiGuid</C_Name>

+      <Guid>0x0DE2CE25, 0x446A, 0x45a7, 0xBF, 0xC9, 0x37, 0xDA, 0x26, 0x34, 0x4B, 0x37</Guid>

+    </Entry>

+    <Entry Name="Stall">

+      <C_Name>gEfiPeiStallPpiGuid</C_Name>

+      <Guid>0x1f4c6f90, 0xb06b, 0x48d8, 0xa2, 0x01, 0xba, 0xe5, 0xf1, 0xcd, 0x7d, 0x56</Guid>

+    </Entry>

+  </PpiDeclarations>

+  <PcdDefinitions>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+      <Token>0x00000001</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumAsciiStringLength</C_Name>

+      <Token>0x00000002</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdMaximumLinkedListLength</C_Name>

+      <Token>0x00000003</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>1000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdSpinLockTimeout</C_Name>

+      <Token>0x00000004</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>10000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugPropertyMask</C_Name>

+      <Token>0x00000005</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="PATCHABLE_IN_MODULE">

+      <C_Name>PcdDebugPrintErrorLevel</C_Name>

+      <Token>0x00000006</Token>

+      <DatumType>UINT32</DatumType>

+      <DefaultValue>0x80000000</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdReportStatusCodePropertyMask</C_Name>

+      <Token>0x00000007</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdDebugClearMemoryValue</C_Name>

+      <Token>0x00000008</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0xAF</DefaultValue>

+    </PcdEntry>

+    <PcdEntry ItemType="FIXED_AT_BUILD">

+      <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>

+      <Token>0x00000009</Token>

+      <DatumType>UINT8</DatumType>

+      <DefaultValue>0x0</DefaultValue>

+    </PcdEntry>

+  </PcdDefinitions>

+</PackageSurfaceArea>

diff --git a/edk2/MdePkg/build.xml b/edk2/MdePkg/build.xml
new file mode 100644
index 0000000..fa56d05
--- /dev/null
+++ b/edk2/MdePkg/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+ 

+<project default="buildfpd" basedir=".">

+  <!-- Apply external ANT tasks -->

+  <taskdef resource="net/sf/antcontrib/antlib.xml" />

+  <taskdef resource="GenBuild.tasks" />

+  

+  <property environment="env" />  

+  <property name="WORKSPACE_DIR" value="${env.WORKSPACE}" />

+  <property name="PACKAGE" value="MdePkg" />

+  <property name="PACKAGE_DIR" value="${WORKSPACE_DIR}/MdePkg" />

+  <property name="BUILD_MODE" value="PACKAGE" />

+  

+  <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml" />

+  

+  <target name="buildfpd" depends="init, fpdparser, builds" />

+  

+  <target name="init">

+    <if>

+      <not>

+        <isset property="env.WORKSPACE" />

+      </not>

+      <then>

+        <fail message="WORKSPACE environmental variable not set." />

+      </then>

+    </if>

+    <ToolChainSetup confPath="${WORKSPACE_DIR}/Tools/Conf" />

+  </target>

+

+  <target name="tools">

+    <ant antfile="${WORKSPACE_DIR}/Tools/Source/TianoTools/build.xml" />

+  </target>

+  

+  <target name="fpdparser" unless="FPD_File">

+    <FPDParser fpdfilename="MdePkg.fpd" />

+  </target>

+  

+  <target name="builds" depends="fpdparser">

+    <ant antfile="${PACKAGE_DIR}/build.out.xml" />

+  </target>

+  

+  <!-- clean. -->

+  <target name="clean" depends="init">

+    <if>

+      <available file="${PACKAGE_DIR}/build.out.xml" />

+      <then>

+        <ant antfile="${PACKAGE_DIR}/build.out.xml" target="clean" />

+      </then>

+    </if>

+  </target>

+  

+  <!-- clean All. -->

+  <target name="cleanall" depends="init">

+    <if>

+      <available file="${PACKAGE_DIR}/build.out.xml" />

+      <then>

+        <ant antfile="${PACKAGE_DIR}/build.out.xml" target="cleanall" />

+        <delete file="${PACKAGE_DIR}/build.out.xml" />

+      </then>

+    </if>

+    <delete dir="${PACKAGE_DIR}/Build/FV" />

+  </target>

+  

+</project>

diff --git a/edk2/MdePkg/genbuildfile.xml b/edk2/MdePkg/genbuildfile.xml
new file mode 100644
index 0000000..77702ef
--- /dev/null
+++ b/edk2/MdePkg/genbuildfile.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+ 

+<project default="workspace" basedir=".">

+  <taskdef resource="GenBuild.tasks" />

+  

+  <target name="workspace">

+    <bf recursive="true" />

+  </target>

+</project>

diff --git a/edk2/ReleaseNotes.txt b/edk2/ReleaseNotes.txt
new file mode 100644
index 0000000..80ecbf1
--- /dev/null
+++ b/edk2/ReleaseNotes.txt
@@ -0,0 +1,430 @@
+Intel(R) Platform Innovation Framework for EFI

+EFI Development Kit 2.0 (EDK 2.0) 

+Alpha Release

+2006-04-26

+

+Copyright (c) 2006, Intel Corporation

+

+This document provides updates to documentation, along with a description on 

+how to install and build the Edk 2.0.

+

+Package Contents

+----------------

+  ReleaseNote.txt- These release notes for the package.

+  MdePkg         - A package containing Industry Standard headers and libraries

+  Tools          - A package containing Build Specific tools which are designed

+                   to help the developer create and modify drivers and

+                   libraries

+  EdkModulePkg   - A package containing reference drivers

+  EdkFatBinPkg   - A package containing binary DXE drivers for the Fat 32 file

+                   system

+  EdkShellBinPkg - A package containing binary Shell applications and commands

+  EdkNt32Pkg     - A package containing the NT32 Emulation platform reference

+

+Note: MDE and MDK that appear in other documentation refer to the MdePkg and

+Tools packages.  These two packages are the minimum requirement for developing

+EDK 2.0 Packages.  It is also recommended that the top level files included

+with the EDK be downloaded in conjunction with these two packages.

+

+Note: Documents have the following filenames:

+  EDK 2.0 Module Development Environment Library Specification v0.50 

+      (MDE_Library_Spec_0_50.rtf)

+  EDK 2.0 Build and Packaging Architecture Specification v0.50

+      (Build_Packaging_Spec_0_50.rtf)

+  EDK 2.0 Platform Configuration Database Infrastructure Description v0.51

+      (PCD_Infrastructure_0_51.rtf)

+  EDK 2.0 Module Surface Area v0.50

+      (Module_Surface_Area_0_50.rtf)

+  EDK 2.0 Module Development Environment (MDE) Package Specification v0.50

+      (MDE_Package_Spec_0_50.rtf)

+  EDK 2.0 C Coding Standards Specification v0.50

+      (C_Coding_Standards_Specification_ 0_50.rtf)

+

+Pre-Requisites

+--------------

+The following list of tools must be installed on the development workstation

+prior to using the Edk 2.0.

+

+Compiler Tool Chain

+      Microsoft* Visual Studio .NET 2003*  (http://www.microsoft.com)

+    or

+      GCC version 4.x or later (http://gcc.gnu.org)

+

+Assembler Tool Chain

+      Microsoft Macro Assembler, version 6.15 or later

+    or

+      GNU binutils 2.16.1 or later

+

+Java Development Kit ( Java 5.0 or later)

+      Sun* jdk-1.5.0_04 or later (http://java.sun.com)

+    or

+      Bea Systems* jrockit-25.2.0-jdk1.5.0_03 or later (http://www.bea.com)

+

+Java Tools

+    Apache-ANT, version 1.6.5 or later (http://ant.apache.org)

+    Ant-contrib, version 1.0b2 or later

+      (http://sourceforge.net/project/showfiles.php?group_id=36177)

+    Saxon8, version 8.1.1

+      (http://prdownloads.sourceforge.net/saxon/saxonb8-1-1.zip?download)

+    XMLBeans, version 2.1.0 or later (http://xmlbeans.apache.org) 

+

+Other Tools

+    TortoiseSVN version 1.3.3. (http://tortoisesvn.tigris.org/)

+

+Optional Tools

+--------------

+Compiler Tool Chains:

+    Intel C++ Compiler for Windows, ver. 9.0 or later (http://www.intel.com)

+    Intel C Compiler for EFI Byte Code, ver. 1.2 or later 

+      (http://www.intel.com/cd/software/products/asmo-na/eng/compilers/efibc/index.htm)

+    Microsoft Driver Development Kit, version 3790.1830 or later

+      (http://www.microsoft.com/whdc/devtools/ddk/orderddkcd.mspx)

+    Microsoft ACPI Source Language Assembler, Version 1.0.13NT or later

+    Intel ACPI Component Architecture, version 20060113

+

+-----------------------

+Notes On Required Tools (Source Control System)

+-----------------------

+The EDK 2.0 is being managed by the Subversion Source Control on Tianocore.org.

+This software package provides speed, security, and additional features. The

+recommended client is TortoiseSVN version 1.3.3. 

+ (Available at http://tortoisesvn.tigris.org/)

+

+There are instructions for the use of Subversion Source Control on the

+Tianocore.org website, as part of the checkout procedures.

+

+The URL of the EDK 2.0 repository is:

+  https://edk2.tianocore.org/svn/edk2/trunk/edk2

+

+-----------------------

+Notes On Documentation

+-----------------------

+The documents are being managed by the Subversion Source Control on

+Tianocore.org.  The document repository is "docs" and must be checked out

+separately from the EDK 2.0 source tree. Refer to the checkout procedures on

+the Tianocore.org website for EDK 2.0.

+

+The URL of the document repository is:

+  https://edk2.tianocore.org/svn/edk2/trunk/docs

+

+

+-----------------------

+Notes On Required Tools (MS Windows environment example)

+-----------------------

+Software Installation Order:

+  After installing the compiler tools and your Subversion client, the following

+  required tools should be installed in order: 

+    Java JDK, Apache-Ant, ant-contrib, xmlbeans, saxon8

+

+Java Development Kit:

+ 

+   The Java Environment Variable must be set before attempting to build.

+       i.e. For Sun JDK (see note below*):

+              set JAVA_HOME=c:\ Java\jdk1.5.0_06  

+       i.e. For Bea Systems:

+              set JAVA_HOME=c:\Program Files\Java\jrockit-R26.0.0-jdk1.5.0_04

+ 

+  *When using the Sun JDK5.0

+    During installation, you should specify the install directory as C:\Java

+    instead of C:\Program Files\(or some other drive letter.)  While installing

+    to this non-standard location is not required. In use, it seems to work 

+    more reliably. 

+    For the JDK, the install path would be C:\Java\jdk1.5.0_06

+    For the JRE, the install path would be C:\Java\jre1.5.0_06

+    Alternatively, you can specify C:\sunjavajdk and C:\sunjavajre.

+

+    NOTE: You cannot combine the location for the JDK and the JRE, as the JRE

+    install removes most of the binaries and libraries installed by the JDK

+    install.

+

+Java Tools:

+    The Apache-ANT requires the ANT_HOME environment variable to be set before

+    attempting to build:

+         i.e.  set ANT_HOME=c:\<full path to where ant was installed>

+

+    The ant-contrib.jar file should be installed in the %ANT_HOME%\lib 

+    directory.

+

+    The XMLBeans, requires the XMLBEANS_HOME environment variable to be set

+    before attempting to build:

+         i.e. set XMLBEANS_HOME=C:\<full path to where xmlbeans  was installed>

+

+    The saxon8.jar file should be copied to the %XMLBEANS_HOME%\lib directory.

+

+   The Ant and XMLBean tools are required to be in the path.

+     MS system example:

+        set PATH=%PATH%;%ANT_HOME%\bin;%XMLBEANS_HOME%\bin

+     Linux/OS X bash shell example:

+        export PATH=$PATH:${ANT_HOME}/bin:${XMLBEANS_HOME}/bin

+ 

+-------------------------------------------------------------------------------

+Quick Start

+-----------

+Edit the text file, msft_tools_def.txt, located in the Tools/Conf directory.

+This file contains the names of the compiler tool chains and the location of

+the compiler binaries.  It has been pre-populated with the standard location

+for the Microsoft tool chains and includes the standard location of the Intel C

+Compiler for EFI Byte Code (EBC)

+  

+Follow the instructions at https://edk2.tianocore.org/servlets/ProjectSource to

+checkout the entire EDK 2.0 source tree.

+

+In a command window, change to the top level directory of the Edk 2.0 sources.

+  Set the WORKSPACE environment variable, e.g.:

+

+    c:\> set WORKSPACE=C:\MyWork\Edk2.0

+

+To test your tool chain setup and to build the Supplied Tools, execute:

+    c:\MyWork\Edk2.0\> edksetup

+

+(This command will be referred to as the setup command throughout the rest of

+this document.)

+      NOTE: You should run the setup command at the start of every session.

+            This configures the environment to include the TianoTools and the

+            Java applications and libraries.

+

+Once this is completed, you are ready to test the Build, by executing:

+    c:\MyWork\Edk2.0\> ant

+

+This command builds all of the packages, including the NT32 reference platform.

+

+-------------------------

+Individual Package Builds

+-------------------------

+After running the setup command, you can build individual packages.

+  In the command window, cd to the package that you want to build, and just

+  type:

+    c:\MyWork\Edk2.0\EdkNt32Pkg\> ant

+

+The EdkNt32Pkg has a special target; "run" that will execute the Nt32 emulation

+platform under Microsoft Windows.

+

+To exit the Nt32 emulation platform, you may type reset at the EFI Shell>

+command prompt.  Alternately, you may use the Graphical interface, Boot

+Maintenance Manager screen's Reset System command.

+

+------------------------

+Individual Module Builds

+------------------------

+After running the setup command, you can build individual modules.

+  In the command window, cd to the module that you want to build, and just

+  type:

+    c:\MyWork\Edk2.0\MdePkg\Library\BaseLib\> ant

+

+-------------------------------------------------------------------------------

+A Word on Apache-ANT

+--------------------

+The Apache-ANT program is a build tool that uses XML-based project files.

+Similar to Makefiles, these project files may contain multiple targets.  Most

+build.xml files in Edk2.0 are auto-generated; any edits performed on the

+build.xml files will be overwritten the next time ant is executed.

+

+Pre-defined targets in the build.xml files include:

+    all      - This target builds binaries for defined architectures

+    clean    - This target removes object files generated by commands

+    cleanall - This target removes all generated files and directories.

+

+A Word on GCC tool chain

+------------------------

+You will find a script in the tree that will download, configure, compile, and

+install a gcc 4.0.2 tool chain for development. It has support for the ia32

+architecture.  It can be built and run on Cygwin, Linux, and many other POSIX

+compliant host environments. There are a few tools that you will need on your

+host computer in order to compile the tool chain. Among them are bash, gcc,

+gmake, curl (or wget).

+

+-------------------------------------------------------------------------------

+

+General Information:

+===============================================================    

+Mechanisms:

+----------

+A brief overview:

+

+A) Surface Area Package Description (SPD) file contains information about the

+modules that the package contains, including the location of all MSA files, and

+public library names and headers that might be provided by a module in the

+package.  Packages are defined by SPD files.  (Found in the root of the Package

+subdirectory (i.e. EdkNt32Pkg)) The SPD is further explained in the "Build 

+Packaging Specification" document.

+ 

+B) Module Surface Area Definition (MSA) files.  A description of a module's 

+surface area, with all module specific default flags and features specified.

+Refer to the "Module Surface Area Architecture Specification" for additional

+details. The MSA is further explained in the "Build Packaging Specification"

+document.

+ 

+C) Module Build Description (MDB). The "as-built" definition file that contains

+only the changes to the default flags defined in the MSA. The MSA and MDB are

+further explained in the "Build Packaging Specification" document.

+

+D) Platform Configuration Database (PCD).  A platform database which contains a

+variety of current platform settings or directives by which a driver or

+application can interact with.  The PCD is defined by the PCD_Protocol (This is

+further explained in the "Platform Configuration Database Infrastructure 

+Description" document.

+

+E) Library Class.  A library class is a logical grouping of similar functions.

+When developing components, the module surface area declares the class of

+libraries that can be used by the component. The MBD file specifies the

+instance(s) of the library that will be used during compilation/linking. All

+library type modules must include header files in their distribution package,

+as well as their surface area and module build description files. Components,

+on the other hand, need only provide the binary and build description files

+when distributing BINARY packages.  The Library Classes are further explained

+in the "Build Packaging Specification" document.

+

+=========================================================================

+The common operations by developers of new modules are:

+-------------------------------------------------------

+

+1) How to manually create a new module in a package:

+  - The module source code must first be created in an appropriate directory

+    (under the package the module is to be a part of.)  

+  - An MSA file must be created, spelling out all aspects of the module.

+  - The MSA must be added to the SPD for the package to include the module.

+

+-----------------------------------------

+2) Add/Remove module(s) to/from a package:

+

+  - Setup environment as Build

+  - Add a module to a package

+     * Generate the module SurfaceArea description file and build description

+       file

+     * Run GenBuildFile.bat under <PackageDir> to generate an entrance

+       build.xml for the module

+     * Add a new <MsaFile> element under <MsaFiles> into

+       <PackageDir>\<PackageName>.spd, using relative path to package

+     * Add a new <ModuleSA> entry under each <TianoImage> into

+       <PackageDir>\<PackageName>.fpd file

+

+   - Remove a module from a package

+     * Comment out or remove corresponding <MsaFile> element under <MsaFiles>

+       from <PackageDir>\<PackageName>.spd

+     * Comment out or remove corresponding <ModuleSA> entry under each

+       <TianoImage> from <PackageDir>\<PackageName>.fpd

+

+-----------------------------------

+3) How to manually create a package:

+  - Identify the modules that are to be members of the project.

+  - Identify the Variables and Guids required in and of the Package (including

+    consumption/production information).

+  - Create an SPD file defining these modules and calling out their MSA files.

+

+--------------------------------------

+4) Declare a new Protocol in a package: 

+  - This release requires manual editing of the SPD file, adding the protocol

+    to the ProtocolDeclarations section of the file. 

+  - Add the Protocol .h file to the Include\Protocol directory.

+  - Add an <Entry> to the <ProtocolDeclarations> element in the 

+    <PackageName>.spd file

+     * Each line contains Protocol base name then the global variable name and

+       then the hex value of the Protocol GUID.

+

+Example Protocol Entries (NOTE: The Guid entry is a single line in the SPD file):

+<ProtocolDeclarations>

+  <Entry Name="UnicodeCollation">

+  <C_Name>gEfiUnicodeCollationProtocolGuid</C_Name>

+  <Guid>{ 0x1d85cd7f, 0xf43d, 0x11d2, 0x9a, 0xc, 0x0, 0x90, 0x27,

+    0x3f, 0xc1, 0x4d }</Guid>

+  <Entry Name="UsbHc">

+  <C_Name>gEfiUsbHcProtocolGuid</C_Name>

+  <Guid>{ 0xf5089266, 0x1aa0, 0x4953, 0x97, 0xd8, 0x56, 0x2f, 0x8a,

+    0x73, 0xb5, 0x19 }</Guid>

+

+---------------------------------

+5) Declare a new PPI in a package:

+ - This release requires manual editing of the SPD file

+  - Add the PPI .h file to the Include\Ppi directory.

+  - Add an <Entry> to the package <PpiDeclarations> element in the 

+    <PackageName>.spd file

+     * Each line contains PPI base name then the global variable name and then

+       the hex value of the PPI GUID.

+

+Example Ppi Entries (NOTE: The Guid entry is a single line in the SPD file):

+<PpiDeclarations>

+  <Entry Name="NtPeiLoadFile">

+    <C_Name>gNtPeiLoadFilePpiGuid</C_Name>

+    <Guid>{ 0xfd0c65eb, 0x405, 0x4cd2, 0x8a, 0xee, 0xf4, 0x0, 0xef, 0x13,

+      0xba, 0xc2 }</Guid>

+  </Entry>

+  <Entry Name="NtThunk">

+    <C_Name>gPeiNtThunkPpiGuid</C_Name>

+    <Guid>{ 0x98c281e5, 0xf906, 0x43dd, 0xa9, 0x2b, 0xb0, 0x3, 0xbf,

+      0x27, 0x65, 0xda }</Guid>

+  </Entry>

+</PpiDeclarations>

+

+

+----------------------------------

+6) Declare a new GUID in a package:

+  - This release requires manual editing of the SPD file to include the new

+    Guid.  This is identical to adding a ProtocolDeclaration or PpiDeclaration

+    element as described above.

+

+--------------------------------------- 

+7) Define a new PCD entry in a package:

+  - This release requires manual editing of the SPD file to include the new

+    PCD.  New Pcd entries are added to the PcdDefinitions section of the

+    <PackageName>.spd file using the following example for the format:

+    NOTE: The hex <Token> value must be unique.

+

+<PcdDefinitions>

+  <PcdEntry ItemType="FIXED_AT_BUILD">

+    <C_Name>PcdMaximumUnicodeStringLength</C_Name>

+    <Token>0x00000001</Token>

+    <DatumType>UINT32</DatumType>

+    <DefaultValue>1000000</DefaultValue>

+  </PcdEntry>

+</PcdDefinition>

+  

+------------------------------

+8) Declare a new Library Class:

+  - This release requires manual editing of the SPD file to include the new

+    Library Class.  New Library Class entries are added to the 

+    LibraryClassDeclarations seection of the <PackageName>.spd file using

+    the following example for the format:

+

+<LibraryClassDeclarations>

+  <LibraryClassDeclaration>

+    <LibraryClass>BaseLib</LibraryClass>

+    <IncludeHeader>Include/Library/BaseLib.h</IncludeHeader>

+  </LibraryClassDeclaration>

+</LibraryClassDeclarations>

+

+--------------------------------------

+9) Add a library instance to a package:

+  - This requires manual MSA and MBD file.

+

+-----------------------------

+10) Add a module to a package:

+  - This requires manual MSA and MBD editing

+

+

+=======================================================

+Notes:

+------

+The EDK 2.0 represents significant changes in the structure of the EDK.

+Therefore it is very difficult to isolate all of the changes of this version of

+the EDK with the previous (EDK 1.0) version.

+

+Of particular note:

+

+1) EDK 2.0 contains new hardware feature support for the ICH SMBUS Libraries.

+   These libraries are provided to make Memory Reference Code (MRC) development

+   easier.

+2) The MDE Libraries - The MDE libraries represent significant changes in source

+   (with only limited changes in functionality.)  These new libraries conform

+   to the "MDE Library Specification". 

+3) The Fat Binary and the EDK Shell Binary Packages are functionally identical

+   to the EDK 1.0 version.

+4) The EDK tools directory has been expanded to include more tools and more

+   tool functionality.

+5) The EDK NT32 section has been ported to the new build process, but

+   functionally remains the same as the EDK 1.0 version.

+6) The Application "HelloWorld" has been ported to EDK 2.0 as well.

+

+=======================================================

+Virus scanned by McAfee VirusScan Enterprise 8.0.0, Virus Definitions 4718, no

+virus detected.

+

diff --git a/edk2/Tools/Conf/BuildMacro.xml b/edk2/Tools/Conf/BuildMacro.xml
new file mode 100644
index 0000000..6f55b5d
--- /dev/null
+++ b/edk2/Tools/Conf/BuildMacro.xml
@@ -0,0 +1,1166 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="common">

+  <!--

+    macro definitions for building files with different types

+    -->

+  <!--

+    C Code

+    -->

+  <macrodef name="Build_C_Code">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="c"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        <then>

+          <makedeps DepsFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep">

+            <input file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            <input file="${DEST_DIR_DEBUG}/AutoGen.h"/>

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+          </makedeps>

+        </then>

+      </if>

+

+      <OnDependency>

+        <sourcefiles>

+          <file ListFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep"/>

+        </sourcefiles>

+        <targetfiles>

+          <file Name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        </targetfiles>

+

+        <sequential>

+          <cc userdefine="on">

+            <command type="CC" workdir="${DEST_DIR_OUTPUT}">

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <EXTRA.INC/>

+

+              <argument value="${CC_FLAGS}"/>

+              <EXTRA.ARG/>

+              <!-- <argument value="/FI${DEST_DIR_DEBUG}/AutoGen.h" /> -->

+              <includeFile value="${DEST_DIR_DEBUG}/AutoGen.h"/>

+              <!-- <argument value="/Fo${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> -->

+              <outputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+

+              <fileset casesensitive="off" file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+

+      <!--

+        for library generation later

+        -->

+      <bl NAME="OBJECTS" VALUE="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> 

+    </sequential>

+  </macrodef>

+

+

+  <macrodef name="Build_AUTOGEN">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="c"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        <then>

+          <makedeps DepsFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep">

+            <input file="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            <input file="${DEST_DIR_DEBUG}/AutoGen.h"/>

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+          </makedeps>

+        </then>

+      </if>

+

+      <OnDependency>

+        <sourcefiles>

+          <file ListFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep"/>

+        </sourcefiles>

+        <targetfiles>

+          <file Name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        </targetfiles>

+

+        <sequential>

+          <cc userdefine="on">

+            <command type="CC" workdir="${DEST_DIR_OUTPUT}">

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <EXTRA.INC/>

+    

+              <argument value="${CC_FLAGS}"/>

+              <EXTRA.ARG/>

+              <!-- <argument value="/FI${DEST_DIR_DEBUG}/AutoGen.h" />  -->

+              <includeFile value="${DEST_DIR_DEBUG}/AutoGen.h"/>

+              <!-- <argument value="/Fo${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> -->

+              <outputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+    

+              <fileset casesensitive="off" file="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+      <!--

+        for library generation later

+        -->

+      <bl NAME="OBJECTS" VALUE="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> 

+    </sequential>

+  </macrodef>

+

+  <macrodef name="Build_Dependency_File">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="dxs"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <OnDependency>

+        <sourcefiles>

+          <file name="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/${BASE_NAME}.@{FILEEXT}.depex"/>

+        </targetfiles>

+

+        <sequential>

+          <copy file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+                tofile="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.c"/>

+

+          <cc userdefine="on">

+            <command type="CC" workdir=".">

+              <includepath path="${DEST_DIR_DEBUG}" /> 

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <EXTRA.INC/>

+              <argument value="${PP_FLAGS}"/>

+              <fileset casesensitive="off" file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.c"/>

+              <outputFile value="@{FILENAME}.@{FILEEXT}.i"/>

+            </command>

+          </cc>

+    

+          <gendepex inputFile="@{FILENAME}.@{FILEEXT}.i" outputFile="${DEST_DIR_OUTPUT}/${BASE_NAME}.@{FILEEXT}.depex"/>

+          <delete file="@{FILENAME}.@{FILEEXT}.i" />

+          <delete file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.c" /> 

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+  

+<!-- Usage Example

+   <Build_C_Code

+     FILEPATH="."

+     FILENAME="${SOURCE_NAME}"

+     FILEEXT="c">

+     <EXTRA.INC>

+       <includepath path="${PACKAGE_DIR}/Include"/>

+       <includepath path="${PACKAGE_DIR}/Include/${ARCH}"/>

+     </EXTRA.INC>

+

+     <EXTRA.ARG>

+       <argument value="/D EFI_DEBUG /D EFI_WHATEVER_FLAG"/>

+     </EXTRA.ARG>

+   </Build_C_Code>

+  -->

+

+  <!--

+    IA32/x64 Assembly

+    -->

+  <macrodef name="Build_Assembly">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="asm"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <OnDependency>

+        <sourcefiles>

+          <file Name="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file Name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        </targetfiles>

+

+        <sequential>

+          <cc userdefine="on">

+            <command type="ASM">

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <EXTRA.INC/>

+      

+              <argument value="${ASM_FLAGS}"/>

+              <EXTRA.ARG/>

+              <argument value="/Fl${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.lst"/>

+              <OutputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+      

+              <fileset casesensitive="off" file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+      <!--

+        for library generation later

+        -->

+      <bl NAME="OBJECTS" VALUE="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    Library    private HashMap map = new HashMap();

+    -->

+  <macrodef name="Build_Library">

+    <attribute name="FILENAME" />

+    <attribute name="FILEEXT" default="obj"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${BIN_DIR}"/>

+

+      <OnDependency>

+        <sourcefiles>

+          <file list="${OBJECTS}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${BIN_DIR}/@{FILENAME}.lib"/>

+        </targetfiles>

+

+        <sequential>

+          <!--  <echo>re-generate library</echo> -->

+          <cc userdefine="on">

+            <command type="LIB">

+              <argument value="${LIB_FLAGS}"/>

+              <!--<argument value="${OBJECTS}"/>-->

+              <FileList dir="" files="${OBJECTS}"/>

+              <!-- <argument value="/out:${BIN_DIR}/@{FILENAME}.lib"/> -->

+              <OutputFile value="${BIN_DIR}/@{FILENAME}.lib"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+

+  <!--

+    GCC Assembly

+    -->

+  <macrodef name="Build_GCC_Assembly_Code">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="s"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        <then>

+          <makedeps DepsFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep">

+            <input file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+          </makedeps>

+        </then>

+      </if>

+

+      <OnDependency>

+        <sourcefiles>

+          <file listfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        </targetfiles>

+

+        <sequential>

+      

+          <cc userdefine="on">

+            <command type="ASM" includepathDelimiter="-I">

+              <EXTRA.INC/>

+      

+              <argument value="${ASM_FLAGS}"/>

+              <EXTRA.ARG/>

+              <!-- <argument value="-o ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> -->

+              <OutputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+      

+              <fileset casesensitive="off" file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+      <!--

+        for library generation later

+        -->

+      <bl NAME="OBJECTS" VALUE="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    IPF Assembly

+    -->

+  <macrodef name="Build_IPF_Assembly_Code">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="s"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        <then>

+          <makedeps DepsFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep">

+            <input file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+          </makedeps>

+        </then>

+      </if>

+

+      <OnDependency>

+        <sourcefiles>

+          <file listfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        </targetfiles>

+

+        <sequential>

+          <copy file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+                tofile="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.c"/>

+          <cc userdefine="on">

+            <command type="CC" workdir="."> 

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <EXTRA.INC/>

+              <argument value="${PP_FLAGS}"/>

+              <fileset casesensitive="off" file="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.c"/>

+            </command>

+          </cc>

+          <move file="@{FILENAME}.@{FILEEXT}.i" 

+                tofile="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.pro"/>

+      

+          <cc userdefine="on">

+            <command type="ASM" includepathDelimiter="-I">

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <EXTRA.INC/>

+      

+              <argument value="${ASM_FLAGS}"/>

+              <EXTRA.ARG/>

+              <!-- <argument value="-o ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> -->

+              <OutputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+      

+              <fileset casesensitive="off" file="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.pro"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+      <!--

+        for library generation later

+        -->

+      <bl NAME="OBJECTS" VALUE="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+    </sequential>

+  </macrodef>

+

+

+  <macrodef name="Build_IPF_PP_Code">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="i"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+  

+      <cc userdefine="on">

+        <command type="ASM" includepathDelimiter="-I">

+          <includepath path="${WORKSPACE_DIR}"/>

+          <includepath path="${MODULE_DIR}"/>

+          <includepath path="${MODULE_DIR}/${ARCH}"/>

+          <EXTRA.INC/>

+  

+          <argument value="${ASM_FLAGS}"/>

+          <EXTRA.ARG/>

+          <!-- <argument value="-o ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/> -->

+          <OutputFile File="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+  

+          <fileset casesensitive="off" file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+        </command>

+      </cc>

+  

+      <!--

+        for library generation later

+        -->

+      <bl NAME="OBJECTS" VALUE="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+    </sequential>

+  </macrodef>

+  

+  <!--

+    [Build.Ia32.Makefile,Build.Ipf.Makefile,Build.Ebc.Makefile]

+    [Build.Ia32.Custom_Makefile,Build.Ipf.Custom_Makefile,Build.Ebc.Custom_Makefile]

+    -->

+  <macrodef name="Build_Custom_Build">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="c"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+

+    </sequential>

+  </macrodef>

+

+  <!--

+    Unicode -> .sdb

+    -->

+  <macrodef name="Build_Unicode">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="uni"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_OUTPUT}/@{FILEPATH}"/>

+

+      <OnDependency>

+        <sourcefiles>

+          <file name="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb"/>

+        </targetfiles>

+

+        <sequential>

+          <strgather commandtype="parse" newdatabase="true">

+            <database name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb"/>

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+            <EXTRA.ARG/>

+            <inputfile name="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+          </strgather>

+        </sequential>

+      </OnDependency>

+

+      <bl name="SDB_FILES" value="${SDB_FILES}, ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb"/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    .sdb(s) -> .c, .h -> .obj

+    -->

+  <macrodef name="Build_Unicode_Database">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="sdb"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <OnDependency>

+        <sourcefiles>

+          <file list="${SDB_FILES}"/>

+          <file list="${SOURCE_FILES}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb"/>

+        </targetfiles>

+        

+        <sequential>

+          <strgather commandtype="scan" outputdatabase="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb" verbose="read">

+            <skipext name=".uni"/>

+            <skipext name=".h"/>

+            <database list="${SDB_FILES}"/>

+            <inputfile name="${SOURCE_FILES}"/>

+          </strgather>

+        </sequential>

+      </OnDependency>

+

+      <OnDependency>

+        <sourcefiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}StrDefs.h"/>

+          <file name="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}Strings.hpk"/>

+          <file name="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}Strings.c"/>

+        </targetfiles>

+        

+        <sequential>

+          <strgather basename="@{FILENAME}Strings" commandtype="dump"

+                     outputdefines="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}StrDefs.h"

+                     outputhpk="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}Strings.hpk"

+                     outputstring="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}Strings.c">

+            <database name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.sdb"/>

+          </strgather>

+        </sequential>

+      </OnDependency>

+

+      <OnDependency>

+        <sourcefiles>

+          <file name="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}Strings.c"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}Strings.obj"/>

+        </targetfiles>

+        

+        <sequential>

+          <cc userdefine="on">

+            <command type="CC" workdir="${DEST_DIR_OUTPUT}" includepathDelimiter="-I">

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+

+              <argument value="${CC_FLAGS}"/>

+              <OutputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}Strings.obj"/>

+

+              <fileset casesensitive="off" file="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}Strings.c"/>

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+

+      <bl name="OBJECTS" value="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}Strings.obj"/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    Vfr

+    -->

+  <macrodef name="Build_Vfr">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="vfr"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${DEST_DIR_DEBUG}/@{FILEPATH}"/>

+

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        <then>

+          <makedeps DepsFile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep">

+            <input file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+            <!-- <input file="${DEST_DIR_DEBUG}/AutoGen.h"/> -->

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+          </makedeps>

+        </then>

+      </if>

+

+      <OnDependency>

+        <sourcefiles>

+          <file listfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}.dep"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+        </targetfiles>

+

+        <sequential>

+          <vfrcompile createIfrBinFile="on" createListFile="on" outPutDir="${DEST_DIR_DEBUG}/@{FILEPATH}" vfrFile="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}">

+            <includepath path="${WORKSPACE_DIR}"/>

+            <includepath path="${MODULE_DIR}"/>

+            <includepath path="${MODULE_DIR}/${ARCH}"/>

+            <EXTRA.INC/>

+          </vfrcompile>

+    

+          <cc userdefine="on">

+            <command type="CC" workdir="${DEST_DIR_OUTPUT}" includepathDelimiter="-I">

+              <includepath path="${WORKSPACE_DIR}"/>

+              <includepath path="${MODULE_DIR}"/>

+              <includepath path="${MODULE_DIR}/${ARCH}"/>

+              <argument value="${CC_FLAGS}"/>

+              <OutputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+              <EXTRA.ARG/>

+    

+              <fileset casesensitive="off" file="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.c"/>

+            </command>

+          </cc>

+    

+          <delete file="@{FILENAME}.i"/>

+        </sequential>

+      </OnDependency>

+      <bl name="OBJECTS" value="${OBJECTS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.obj"/>

+    </sequential>

+  </macrodef>

+

+<!--############################################################################

+  Build Sections

+#############################################################################-->

+  <!--

+    DLL

+    -->

+  <macrodef name="GenDll">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT"/>

+

+    <element name="LIB.ARG" optional="yes"/>

+    <element name="LINK.ARG" optional="yes"/>

+

+    <sequential>

+      <OnDependency>

+        <sourcefiles>

+          <file list="${OBJECTS}"/>

+          <file list="${LIBS}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.dll"/>

+        </targetfiles>

+

+        <sequential>

+          <cc userdefine="on">

+            <command type="LIB">

+              <argument value="${LIB_FLAGS}"/>

+              <FileList dir="" files="${OBJECTS}"/>

+              <LIB.ARG/>

+              <OutputFile value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}Local.lib"/>

+            </command>

+          </cc>

+          <cc userdefine="on">

+            <command type="LINK">

+              <argument value="${LINK_FLAGS}"/>

+              <libset libs="${LIBS} ${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}Local.lib"/>

+              <LINK.ARG/>

+              <EntryPoint value="_ModuleEntryPoint"/>

+              <map value="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.map"/>

+              <pdb value="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.pdb"/>

+              <OutputFile value="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.dll"/>

+              <!-- <FileList dir="" files="${OBJECTS}"/> -->

+            </command>

+          </cc>

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI

+    -->

+  <macrodef name="GenEfi">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="dll"/>

+

+    <sequential>

+      <OnDependency>

+        <sourcefiles>

+          <file name="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.efi"/>

+        </targetfiles>

+

+        <sequential>

+          <fwimage componenttype="${COMPONENT_TYPE}" outImage="${DEST_DIR_OUTPUT}/@{FILENAME}.efi" 

+                   peImage="${DEST_DIR_DEBUG}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" time="0"/>

+          <copy file="${DEST_DIR_OUTPUT}/@{FILENAME}.efi" tofile="${DEST_DIR_DEBUG}/@{FILENAME}.efi" />

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+

+<!--

+  EFI_SECTION_FREEFORM_SUBTYPE_GUID

+  EFI_SECTION_VERSION

+  EFI_SECTION_USER_INTERFACE

+  EFI_SECTION_DXE_DEPEX

+  EFI_SECTION_PEI_DEPEX

+  EFI_SECTION_PE32

+  EFI_SECTION_PIC

+  EFI_SECTION_TE

+  EFI_SECTION_RAW

+  EFI_SECTION_COMPRESSION

+  EFI_SECTION_GUID_DEFINED

+  EFI_SECTION_COMPATIBILITY16

+  EFI_SECTION_FIRMWARE_VOLUME_IMAGE

+  -->

+  <!--

+    EFI_SECTION_PE32

+    -->

+  <macrodef name="EFI_SECTION_PE32">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="" />

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+

+    <sequential>

+      <PRE.PROCESS/>

+

+      <if>

+        <not>

+          <equals arg1="${OBJECTS}" arg2=""/>

+        </not>

+

+        <then>

+          <GenDll FILEPATH="." FILENAME="@{FILENAME}" FILEEXT="">

+            <LIB.ARG></LIB.ARG>

+            <LINK.ARG></LINK.ARG>

+          </GenDll>

+    

+          <GenEfi FILEPATH="." FILENAME="@{FILENAME}" FILEEXT="dll"/>

+        </then>

+      </if>

+

+      <OnDependency>

+        <sourcefiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.efi"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.pe32"/>

+        </targetfiles>

+

+        <sequential>

+          <copy file="${DEST_DIR_OUTPUT}/@{FILENAME}.efi" tofile="${BIN_DIR}/@{FILENAME}.efi" />

+          <gensection inputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.efi" 

+                      outputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.pe32" 

+                      sectiontype="EFI_SECTION_PE32"/>

+    

+          <POST.PROCESS/>

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI_SECTION_VERSION

+    -->

+  <macrodef name="EFI_SECTION_VERSION">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="" />

+    <attribute name="VERSION" default="0000"/>

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+

+    <sequential>

+      <if>

+        <not>

+          <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.ver"/>

+        </not>

+

+        <then>

+          <PRE.PROCESS/>

+          <gensection outputfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.ver" 

+                      versionnum="@{VERSION}"

+                      sectiontype="EFI_SECTION_VERSION"/>

+          <POST.PROCESS/>

+        </then>

+      </if>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI_SECTION_USER_INTERFACE

+    -->

+  <macrodef name="EFI_SECTION_USER_INTERFACE">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="" />

+    <attribute name="UI" default="${BASE_NAME}"/>

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+

+    <sequential>

+      <if>

+        <not>

+          <available type="file" file="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.ui"/>

+        </not>

+

+        <then>

+          <PRE.PROCESS/>

+          <gensection interfacestring="@{UI}"

+                      outputfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.ui" 

+                      sectiontype="EFI_SECTION_USER_INTERFACE"/>

+          <POST.PROCESS/>

+        </then>

+      </if>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI_SECTION_FREEFORM_SUBTYPE_GUID

+    <macrodef name="EFI_SECTION_FREEFORM_SUBTYPE_GUID">

+      <attribute name="FILEPATH"/>

+      <attribute name="FILENAME"/>

+      <attribute name="FILEEXT" default=""/>

+  

+      <element name="EXTRA.INC" optional="yes"/>

+      <element name="EXTRA.ARG" optional="yes"/>

+  

+      <sequential>

+        <gensection inputfile="" 

+                    outputfile="" 

+                    sectiontype="EFI_SECTION_FREEFORM_SUBTYPE_GUID"/>

+      </sequential>

+    </macrodef>

+    -->

+

+  <!--

+    EFI_SECTION_DXE_DEPEX

+    -->

+  <macrodef name="EFI_SECTION_DXE_DEPEX">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="dxs"/>

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+

+    <sequential>

+      <PRE.PROCESS/>

+

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}.depex"/>

+        <then>

+          <OnDependency>

+            <sourcefiles>

+              <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}.depex"/>

+            </sourcefiles>

+            <targetfiles>

+              <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx"/>

+            </targetfiles>

+            <sequential>

+              <gensection inputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}.depex" 

+                          outputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx" 

+                          sectiontype="EFI_SECTION_DXE_DEPEX"/>

+            </sequential>

+          </OnDependency>

+        </then>

+        <else>

+          <if>

+            <not>

+              <available type="file" file="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx"/>

+            </not>

+            <then>

+              <touch file="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx"/>

+            </then>

+          </if>

+        </else>

+      </if>

+

+      <POST.PROCESS/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI_SECTION_PEI_DEPEX

+    -->

+  <macrodef name="EFI_SECTION_PEI_DEPEX">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="dxs"/>

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+    <sequential>

+      <PRE.PROCESS/>

+      <if>

+        <available type="file" file="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}.depex"/>

+        <then>

+          <OnDependency>

+            <sourcefiles>

+              <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}.depex"/>

+            </sourcefiles>

+            <targetfiles>

+              <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx"/>

+            </targetfiles>

+

+            <sequential>

+              <gensection inputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}.depex" 

+                          outputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx" 

+                          sectiontype="EFI_SECTION_PEI_DEPEX"/>

+            </sequential>

+          </OnDependency>

+          

+        </then>

+        <else>

+          <if>

+            <not>

+              <available type="file" file="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx"/>

+            </not>

+            <then>

+              <touch file="${DEST_DIR_OUTPUT}/@{FILENAME}.dpx"/>

+            </then>

+          </if>

+        </else>

+      </if>

+      <POST.PROCESS/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI_SECTION_PIC

+    <macrodef name="EFI_SECTION_PIC">

+      <attribute name="FILEPATH"/>

+      <attribute name="FILENAME"/>

+      <attribute name="FILEEXT" default=""/>

+  

+      <element name="EXTRA.INC" optional="yes"/>

+      <element name="EXTRA.ARG" optional="yes"/>

+  

+      <sequential>

+        <gensection inputfile="${BIN_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+                    outputfile="${BIN_DIR}/@{FILENAME}.pe32" 

+                    sectiontype="EFI_SECTION_PIC"/>

+      </sequential>

+    </macrodef>

+    -->

+

+  <!--

+    EFI_SECTION_TE

+    <macrodef name="EFI_SECTION_TE">

+      <attribute name="FILEPATH"/>

+      <attribute name="FILENAME"/>

+      <attribute name="FILEEXT" default=""/>

+  

+      <element name="EXTRA.INC" optional="yes"/>

+      <element name="EXTRA.ARG" optional="yes"/>

+  

+      <sequential>

+        <gensection inputfile="${BIN_DIR}/@{FILENAME}.@{FILEEXT}" 

+                    outputfile="${BIN_DIR}/@{FILENAME}.pe32" 

+                    sectiontype="EFI_SECTION_PE32"/>

+      </sequential>

+    </macrodef>

+    -->

+

+  <!--

+    EFI_SECTION_RAW

+    -->

+  <macrodef name="EFI_SECTION_RAW">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="bin"/>

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+

+    <sequential>

+      <OnDependency>

+        <sourcefiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILENAME}.sec"/>

+        </targetfiles>

+

+        <sequential>

+          <PRE.PROCESS/>

+          <gensection inputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.@{FILEEXT}" 

+                      outputfile="${DEST_DIR_OUTPUT}/@{FILENAME}.sec" 

+                      sectiontype="EFI_SECTION_RAW"/>

+          <POST.PROCESS/>

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+

+  <!--

+    EFI_SECTION_COMPRESSION

+    <macrodef name="EFI_SECTION_COMPRESSION">

+      <attribute name="FILEPATH"/>

+      <attribute name="FILENAME"/>

+      <attribute name="FILEEXT" default=""/>

+  

+      <element name="EXTRA.INC" optional="yes"/>

+      <element name="EXTRA.ARG" optional="yes"/>

+  

+      <sequential>

+        <gensection inputfile="${BIN_DIR}/@{FILENAME}.@{FILEEXT}" 

+                    outputfile="${BIN_DIR}/@{FILENAME}.pe32" 

+                    sectiontype="EFI_SECTION_PE32"/>

+      </sequential>

+    </macrodef>

+    -->

+

+  <!--

+    EFI_SECTION_GUID_DEFINED

+    <macrodef name="EFI_SECTION_GUID_DEFINED">

+      <attribute name="FILEPATH"/>

+      <attribute name="FILENAME"/>

+      <attribute name="FILEEXT" default=""/>

+  

+      <element name="EXTRA.INC" optional="yes"/>

+      <element name="EXTRA.ARG" optional="yes"/>

+  

+      <sequential>

+        <gensection inputfile="${BIN_DIR}/@{FILENAME}.@{FILEEXT}" 

+                    outputfile="${BIN_DIR}/@{FILENAME}.pe32" 

+                    sectiontype="EFI_SECTION_PE32"/>

+      </sequential>

+    </macrodef>

+    -->

+

+  <!--

+    EFI_SECTION_COMPATIBILITY16

+    <macrodef name="EFI_SECTION_COMPATIBILITY16">

+      <attribute name="FILEPATH"/>

+      <attribute name="FILENAME"/>

+      <attribute name="FILEEXT" default=""/>

+  

+      <element name="EXTRA.INC" optional="yes"/>

+      <element name="EXTRA.ARG" optional="yes"/>

+  

+      <sequential>

+        <gensection inputfile="${BIN_DIR}/@{FILENAME}.@{FILEEXT}" 

+                    outputfile="${BIN_DIR}/@{FILENAME}.pe32" 

+                    sectiontype="EFI_SECTION_PE32"/>

+      </sequential>

+    </macrodef>

+  

+    -->

+  <!--

+    EFI_SECTION_FIRMWARE_VOLUME_IMAGE

+    -->

+  <macrodef name="EFI_SECTION_FIRMWARE_VOLUME_IMAGE">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="fv"/>

+

+    <element name="PRE.PROCESS" optional="yes"/>

+    <element name="POST.PROCESS" optional="yes"/>

+

+    <sequential>

+      <OnDependency>

+        <sourcefiles>

+          <file name="${FV_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}"/>

+        </sourcefiles>

+        <targetfiles>

+          <file name="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}fv.sec"/>

+        </targetfiles>

+

+        <sequential>

+          <PRE.PROCESS/>

+    

+          <copy file="${FV_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+                tofile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+                overwrite="true"/>

+          <gensection inputfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+                      outputfile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}fv.sec" 

+                      sectiontype="EFI_SECTION_FIRMWARE_VOLUME_IMAGE"/>

+    

+          <POST.PROCESS/>

+        </sequential>

+      </OnDependency>

+    </sequential>

+  </macrodef>

+

+  <!--

+    Binary

+    -->

+  <macrodef name="Build_Binary">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="bin"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <copy file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+            tofile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.bin"/>

+    </sequential>

+  </macrodef>

+

+  <!--

+    Graphics (bmp, ...)

+    -->

+  <macrodef name="Build_Graphics">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="bmp"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${MODULE_DIR}/@{FILEPATH}" /> 

+      <copy file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+            tofile="${DEST_DIR_OUTPUT}/@{FILEPATH}/@{FILENAME}.bin"/>

+    </sequential>

+  </macrodef>

+  <macrodef name="Build_EFI">

+    <attribute name="FILEPATH"/>

+    <attribute name="FILENAME"/>

+    <attribute name="FILEEXT" default="efi"/>

+

+    <element name="EXTRA.INC" optional="yes"/>

+    <element name="EXTRA.ARG" optional="yes"/>

+

+    <sequential>

+      <mkdir dir="${MODULE_DIR}/@{FILEPATH}" /> 

+      <copy file="${MODULE_DIR}/@{FILEPATH}/@{FILENAME}.@{FILEEXT}" 

+        tofile="${DEST_DIR_OUTPUT}/${BASE_NAME}.efi"/>

+    </sequential>

+  </macrodef>

+</project>

diff --git a/edk2/Tools/Conf/Common.xml b/edk2/Tools/Conf/Common.xml
new file mode 100644
index 0000000..9bf62ca
--- /dev/null
+++ b/edk2/Tools/Conf/Common.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<root>

+  <Ffs type="APPLICATION">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_PE32" /> 

+        <Section SectionType="EFI_SECTION_USER_INTERFACE" />

+        <Section SectionType="EFI_SECTION_VERSION" /> 

+      </Sections>

+    </Sections>

+  </Ffs>

+

+  <Ffs type="BINARY">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections  EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_RAW" /> 

+      </Sections>

+    </Sections>

+  </Ffs>

+  

+  <Ffs type="FILE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections>

+      <Section SectionType="EFI_SECTION_RAW"/> 

+    </Sections>

+  </Ffs>

+  

+  <Ffs type="PE32_PEIM.CompressPEIM">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM" /> 

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" /> 

+

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX" />

+      <Sections EncapsulationType="Compress">

+        <Section SectionType="EFI_SECTION_PE32" /> 

+        <Section SectionType="EFI_SECTION_USER_INTERFACE" />

+        <Section SectionType="EFI_SECTION_VERSION" /> 

+      </Sections>

+    </Sections>

+  </Ffs>

+

+  <Ffs type="PEI_CORE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEI_CORE" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections>

+      <Section SectionType="EFI_SECTION_PE32"/>

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/>

+    </Sections>

+  </Ffs>

+

+  <Ffs type="PE32_PEIM.Relocatable">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/> 

+      <Section SectionType="EFI_SECTION_PE32"/> 

+    </Sections>

+  </Ffs>

+

+  <Ffs type="DXE_CORE">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_DXE_CORE" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections EncapsulationType="Compress">

+      <Section SectionType="EFI_SECTION_PE32" /> 

+      <Section SectionType="EFI_SECTION_USER_INTERFACE" />

+      <Section SectionType="EFI_SECTION_VERSION" /> 

+    </Sections>

+  </Ffs>

+

+

+  <Ffs type="BS_DRIVER, RT_DRIVER, SAL_RT_DRIVER">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_DRIVER" /> 

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" /> 

+

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_PEI_DEPEX" />

+        <Section SectionType="EFI_SECTION_PE32" />

+        <Section SectionType="EFI_SECTION_USER_INTERFACE" />

+        <Section SectionType="EFI_SECTION_VERSION" />

+      </Sections>

+    </Sections>

+  </Ffs>

+

+  <Ffs type="COMBINED_PEIM_DRIVER">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/> 

+      <Section SectionType="EFI_SECTION_PE32"/> 

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/> 

+    </Sections>

+  </Ffs>

+

+  <Ffs type="PE32_PEIM">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_PEIM" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections>

+      <Section SectionType="EFI_SECTION_PEI_DEPEX"/> 

+      <Section SectionType="EFI_SECTION_PE32"/> 

+      <Section SectionType="EFI_SECTION_USER_INTERFACE"/>

+      <Section SectionType="EFI_SECTION_VERSION"/> 

+    </Sections>

+  </Ffs>

+

+  <Ffs type="Logo, Logo.Logo">

+    <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_FREEFORM" />

+    <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />

+    <Sections EncapsulationType="Compress">

+      <Sections EncapsulationType="Guid-Defined">

+        <Section SectionType="EFI_SECTION_RAW" /> 

+      </Sections>

+    </Sections>

+  </Ffs>

+ 

+</root>

diff --git a/edk2/Tools/Conf/FrameworkDatabase.db b/edk2/Tools/Conf/FrameworkDatabase.db
new file mode 100644
index 0000000..881ffeb
--- /dev/null
+++ b/edk2/Tools/Conf/FrameworkDatabase.db
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<FrameworkDatabase xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <FdbHeader>

+    <DatabaseName>FrameworkDatabase</DatabaseName>

+    <Guid>5ce32c23-6448-43ab-b509-a9deae3aae65</Guid>

+    <Version>0.3</Version>

+    <Created>2006-03-04 22:14</Created>

+    <Updated>2006-03-06 16:56</Updated>

+    <Abstract>The Framework Module Development Packaging System Database</Abstract>

+    <Description>This Database tracks the Basename, Version, Guid and Path for all packages installed in this workspace.</Description>

+    <Copyright>Copyright (c) 2006,  Intel Corporation.</Copyright>

+    <License>

+      All rights reserved.

+      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.

+    </License>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </FdbHeader>

+  <PackageList>

+    <Package>

+      <PackageName>EdkFatBinPkg</PackageName>

+      <Guid>0fd7197b-9bde-44fe-a7e4-d2177a9922e5</Guid>

+      <Version>0.3</Version>

+      <Path>EdkFatBinPkg/</Path>

+      <InstalledDate>2006-03-05 09:49</InstalledDate>

+    </Package>

+    <Package>

+      <PackageName>EdkModulePkg</PackageName>

+      <Guid>0xb6ec423c, 0x21d2, 0x490d, 0x85, 0xc6, 0xdd, 0x58, 0x64, 0xea, 0xa6, 0x74</Guid>

+      <Version>0.3</Version>

+      <Path>EdkModulePkg/</Path>

+      <InstalledDate>2006-02-21 17:43</InstalledDate>

+    </Package>

+    <Package>

+      <PackageName>EdkNt32Pkg</PackageName>

+      <Guid>0fb2aa2d-10d5-40a5-a9dc-060c12a4a3f3</Guid>

+      <Version>0.3</Version>

+      <Path>EdkNt32Pkg/</Path>

+      <InstalledDate>2006-02-22 13:25</InstalledDate>

+    </Package>

+    <Package>

+      <PackageName>EdkShellBinPkg</PackageName>

+      <Guid>d4266a1b-1d38-4116-93ae-60dc3e2012a6</Guid>

+      <Version>0.3</Version>

+      <Path>EdkShellBinPkg/</Path>

+      <InstalledDate>2006-03-05 10:13</InstalledDate>

+    </Package>

+    <Package>

+      <PackageName>MdePkg</PackageName>

+      <Guid>5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec</Guid>

+      <Version>0.3</Version>

+      <Path>MdePkg/</Path>

+      <InstalledDate>2006-03-18 19:02</InstalledDate>

+    </Package>

+    <Package>

+      <PackageName>Tools</PackageName>

+      <Guid>53f84ca0-53fe-4412-b4e7-dcec602e1d49</Guid>

+      <Version>0.3</Version>

+      <Path>Tools/</Path>

+      <InstalledDate>2006-02-24 14:49</InstalledDate>

+    </Package>

+    <!--

+    <Package>

+      <PackageName>EdkFatPkg</PackageName>

+      <Guid>0x8EA68A2C, 0x99CB, 0x4332, 0x85, 0xc6, 0xdd, 0x58, 0x64, 0xea, 0xa6, 0x74</Guid>

+      <Version>1.0</Version>

+      <Path>EdkFatPkg/</Path>

+      <InstalledDate>2006-03-05 09:49</InstalledDate>

+    </Package>

+    -->

+  </PackageList>

+  <PlatformList>

+    <Platform PlatformName="NT32" PlatformGuid="eb216561-961f-47ee-9ef9-ca426ef547c2" PlatformVersion="0.3">

+      <Filename>EdkNt32Pkg/Nt32.fpd</Filename>

+      <InstalledDate>2006-02-23 18:21</InstalledDate>

+      <ModifiedDate>2006-06-03 20:20</ModifiedDate>

+    </Platform>

+    <Platform PlatformName="NT32Test" PlatformGuid="b23bda70-806b-4c2c-85f3-1d7139cb9f12" PlatformVersion="0.3">

+      <Filename>EdkNt32Pkg/Nt32Test.fpd</Filename>

+      <InstalledDate>2006-02-24 14:49</InstalledDate>

+      <ModifiedDate>2006-05-14 09:49</ModifiedDate>

+    </Platform>

+    <Platform PlatformName="MdePkgAll" PlatformGuid="0fe7dd3e-0969-48c3-8cd2-de9a190088e2" PlatformVersion="0.3">

+      <Filename>MdePkg/MdePkg-All-Archs.fpd</Filename>

+      <InstalledDate>2006-02-24 14:49</InstalledDate>

+      <ModifiedDate>2006-05-14 09:49</ModifiedDate>

+    </Platform>

+    <Platform PlatformName="MdePkg" PlatformGuid="1123e1a9-4d9b-499f-843c-b2297ff61a11" PlatformVersion="0.3">

+      <Filename>MdePkg/MdePkg.fpd</Filename>

+      <InstalledDate>2006-02-24 14:49</InstalledDate>

+      <ModifiedDate>2006-05-14 09:49</ModifiedDate>

+    </Platform>

+    <Platform PlatformName="EdkModuleAll" PlatformGuid="dc967761-e6e9-4d1a-b02c-818102db4cc6" PlatformVersion="0.3">

+      <Filename>EdkModulePkg/EdkModulePkg-All-Archs.fpd</Filename>

+      <InstalledDate>2006-02-24 14:49</InstalledDate>

+      <ModifiedDate>2006-06-03 22:14</ModifiedDate>

+    </Platform>

+    <Platform PlatformName="EdkModule" PlatformGuid="dbb0551f-a04b-4038-9303-e60998023c8d" PlatformVersion="0.3">

+      <Filename>EdkModulePkg/EdkModulePkg.fpd</Filename>

+      <InstalledDate>2006-02-24 14:49</InstalledDate>

+      <ModifiedDate>2006-06-01 17:59</ModifiedDate>

+    </Platform>

+  </PlatformList>

+</FrameworkDatabase>

diff --git a/edk2/Tools/Conf/Pcd/PcdDatabaseCommonDefinitions.sample b/edk2/Tools/Conf/Pcd/PcdDatabaseCommonDefinitions.sample
new file mode 100644
index 0000000..9b7d7d3
--- /dev/null
+++ b/edk2/Tools/Conf/Pcd/PcdDatabaseCommonDefinitions.sample
@@ -0,0 +1,53 @@
+//

+// The following definition will be generated by build tool 

+//

+

+//

+// Common definitions

+//

+#define PCD_TYPE_SHIFT        24

+

+

+#define PCD_TYPE_DATA         (0x00 << PCD_TYPE_SHIFT)

+#define PCD_TYPE_HII    	    (0x80 << PCD_TYPE_SHIFT)

+#define PCD_TYPE_VPD    	    (0x40 << PCD_TYPE_SHIFT)

+#define PCD_TYPE_SKU_ENABLED 	(0x20 << PCD_TYPE_SHIFT)

+#define PCD_TYPE_STRING       (0x10 << PCD_TYPE_SHIFT)

+

+

+#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING))

+

+typedef struct  {

+  UINT32                ExTokenNumber;

+  UINT32                LocalTokenNumber;   // PCD Number of this particular platform build

+  UINT16                ExGuidIndex;        // Index of GuidTable

+} DYNAMICEX_MAPPING;

+

+

+typedef struct {

+  UINT32  SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler

+  UINT32  SkuIdTableOffset;   //Offset from the PCD_DB

+} SKU_HEAD;

+

+

+typedef struct {

+  UINT16  GuidTableIndex;   // Offset in Guid Table in units of GUID.

+  UINT16  StringIndex;           // Offset in String Table in units of UINT16.

+  UINT16  Offset;           // Offset in Variable

+} VARIABLE_HEAD  ;

+

+

+typedef  struct {

+  UINT32  Offset;

+} VPD_HEAD;

+

+typedef struct {

+  UINT32 LocalTokenNumber;

+  UINT16 TokenNumber;

+  UINT16 Size;

+} SIZEINFO;

+

+#define offsetof(s,m)                 (UINT32)&(((s *)0)->m)

+

+

+

diff --git a/edk2/Tools/Conf/Pcd/PcdDatabaseDxeDefinitions.sample b/edk2/Tools/Conf/Pcd/PcdDatabaseDxeDefinitions.sample
new file mode 100644
index 0000000..be2bc0e
--- /dev/null
+++ b/edk2/Tools/Conf/Pcd/PcdDatabaseDxeDefinitions.sample
@@ -0,0 +1,16 @@
+

+typedef struct {

+  DXE_PCD_DATABASE_INIT Init;

+  DXE_PCD_DATABASE_UNINIT Uninit;

+} DXE_PCD_DATABASE;

+

+

+typedef struct {

+  PEI_PCD_DATABASE PeiDb;

+  DXE_PCD_DATABASE DxeDb;

+} PCD_DATABASE;

+

+#define DXE_NEX_TOKEN_NUMBER (DXE_LOCAL_TOKEN_NUMBER - DXE_EX_TOKEN_NUMBER)

+

+#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)

+

diff --git a/edk2/Tools/Conf/Pcd/PcdDatabasePeiDefinitions.sample b/edk2/Tools/Conf/Pcd/PcdDatabasePeiDefinitions.sample
new file mode 100644
index 0000000..86ae4fc
--- /dev/null
+++ b/edk2/Tools/Conf/Pcd/PcdDatabasePeiDefinitions.sample
@@ -0,0 +1,8 @@
+

+typedef struct {

+  PEI_PCD_DATABASE_INIT Init;

+  PEI_PCD_DATABASE_UNINIT Uninit;

+} PEI_PCD_DATABASE;

+

+#define PEI_NEX_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER - PEI_EX_TOKEN_NUMBER)

+

diff --git a/edk2/Tools/Conf/debug_efi_flags.txt b/edk2/Tools/Conf/debug_efi_flags.txt
new file mode 100644
index 0000000..0a5e637
--- /dev/null
+++ b/edk2/Tools/Conf/debug_efi_flags.txt
@@ -0,0 +1,4 @@
+WORKSPACE_TARGET = DEBUG

+EFI_LOCK_STATUS  = FALSE

+EFI_S3_RESUME    = YES

+EFI_LOG_LEVEL    = 3

diff --git a/edk2/Tools/Conf/efi_flags_table.txt b/edk2/Tools/Conf/efi_flags_table.txt
new file mode 100644
index 0000000..6dfc4fa
--- /dev/null
+++ b/edk2/Tools/Conf/efi_flags_table.txt
@@ -0,0 +1,26 @@
+#

+# TABLE COLUMES: FLAGS_NAME, FLAGS_SETTING, VENDOR_ARCH_COMMANDTYPE ADD and SUB

+# Here, Vendor is defined in tools_def.txt, for example: MSFT, WINDDK, INTEL, GCC, CYGWIN

+# ARCH is IA32, IPF, x64, EBC and so on

+# COMMANDTYPE is one of CC, LIB, LINK, ASM, ASMLINK, PP, ASL

+#

+

+# EFI_DEBUG

+EFI_DEBUG YES MSFT_IA32_ASM    ADD.["/Zi", "/DEBUG"]

+EFI_DEBUG YES MSFT_IA32_CC     ADD.["/Zi", "/Gm", "/D EFI_DEBUG"] SUB.["/nologo", "/WX"]

+EFI_DEBUG YES MSFT_IA32_LINK   ADD.["/DEBUG"]

+EFI_DEBUG YES MSFT_NT32_CC     ADD.["/DEBUG"]

+

+EFI_DEBUG YES INTEL_EBC_CC     ADD.["/Zd", "/Zi"]

+EFI_DEBUG YES INTEL_EBC_LINK   ADD.["/DEBUG"]

+

+EFI_DEBUG YES WINDDK_X64_ASM   ADD.["/Zi", "/DDEBUG"]

+EFI_DEBUG YES WINDDK_X64_CC    ADD.["/Zi", "/Gm", "/D EFI_DEBUG"]

+EFI_DEBUG YES WINDDK_X64_LINK  ADD.["/DEBUG"]

+

+EFI_DEBUG YES WINDDK_IPF_ASM   ADD.["-d debug"]

+EFI_DEBUG YES WINDDK_IPF_CC    ADD.["/Zi", "/Gm"]

+EFI_DEBUG YES WINDDK_IPF_LINK  ADD.["/DEBUG"]

+

+

+# EFI_DEBUG_CLEAR_MEMORY

diff --git a/edk2/Tools/Conf/gcc_tools.txt b/edk2/Tools/Conf/gcc_tools.txt
new file mode 100644
index 0000000..cdce142
--- /dev/null
+++ b/edk2/Tools/Conf/gcc_tools.txt
@@ -0,0 +1,7 @@
+IA32_CC = "-Os", "-fshort-wchar", "-fno-strict-aliasing", "-Wall", "-Werror", "-c"

+IA32_LIB = 

+IA32_LINK = "-nostdlib", "-O2", "--gc-sections", "--dll", "--export-all-symbols"

+IA32_ASM = "/nologo", "/W3", "/WX", "/c", "/coff", "/DEFI32"

+IA32_ASMLINK = 

+IA32_PP = "-E"

+

diff --git a/edk2/Tools/Conf/gcc_tools_def.txt b/edk2/Tools/Conf/gcc_tools_def.txt
new file mode 100644
index 0000000..c873965
--- /dev/null
+++ b/edk2/Tools/Conf/gcc_tools_def.txt
@@ -0,0 +1,57 @@
+#Host definitions

+HOST_VENDOR = INTEL

+PATH_TO_HOST_CC = c:\cygwin\bin

+

+#Default values

+CC_NAME = gcc

+LIB_NAME = ar

+LINK_NAME = ld

+ASM_NAME = ml.exe

+ASMLINK_NAME = link.exe

+ASL_NAME = iasl.exe

+PP_NAME=gcc

+

+#define for IA32

+IA32_VENDOR = GCC

+IA32_CC_VENDOR = GCC

+IA32_ASL_VENDOR = GCC

+IA32_ASM_VENDOR = MSFT

+# IA32_PATH = /usr/bin

+IA32_PATH = C:\cygwin\opt\tiano\i386-tiano-pe\i386-tiano-pe\bin

+# IA32_ASM_PATH = /usr/bin

+IA32_ASM_PATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin

+#IA32_ASMLINK_PATH = C:\MASM611\BINR

+IA32_ASL_PATH = C:\TianoTools\Bin

+

+#define for x64

+x64_VENDOR = WINDDK

+x64_CC_VENDOR = WINDDK

+x64_ASM_VENDOR = WINDDK

+x64_CC_NAME = cl.exe

+x64_LIB_NAME = lib.exe

+x64_LINK_NAME = link.exe

+x64_PP_NAME = cl.exe

+x64_ASL_VENDOR = INTEL

+x64_PATH = c:\WINDDK\3790.1830\bin\win64\x86\amd64

+x64_ASL_PATH = C:\TianoTools\Bin

+X64_ASM_NAME = ml64.exe

+

+#define for IPF

+IPF_CC_NAME = cl.exe

+IPF_LIB_NAME = lib.exe

+IPF_LINK_NAME = link.exe

+IPF_PP_NAME = cl.exe

+IPF_VENDOR = WINDDK

+IPF_ASL_VENDOR = INTEL

+IPF_PATH = c:\WINDDK\3790.1830\bin\win64\x86

+IPF_ASL_PATH = C:\TianoTools\Bin

+IPF_ASM_NAME = ias.exe

+

+#define for EBC

+EBC_VENDOR = INTEL

+EBC_ASL_VENDOR = INTEL

+EBC_PATH = C:\Program Files\Intel\EBC\Bin

+EBC_ASL_PATH = C:\TianoTools\Bin

+EBC_CC_NAME = iec.exe

+EBC_LIB_NAME = link.exe

+EBC_LINK_NAME = link.exe

diff --git a/edk2/Tools/Conf/global_efi_flags.txt b/edk2/Tools/Conf/global_efi_flags.txt
new file mode 100644
index 0000000..1c1df04
--- /dev/null
+++ b/edk2/Tools/Conf/global_efi_flags.txt
@@ -0,0 +1,35 @@
+EFI_GENERATE_SYM_FILE   = NO

+EFI_DEBUG               = NO

+EFI_DEBUG_CLEAR_MEMORY  = NO

+EFI_PEI_PERFORMANCE     = YES

+EFI_DXE_PERFORMANCE     = YES

+EFI_SYMBOLIC_DEBUG      = NO

+EFI_USE_NEW_SHELL_BIN   = NO

+EFI_GENERATE_INTERMEDIATE_FILE = NO

+

+EFI_READ_DISABLED_CAP   = TRUE

+EFI_READ_ENABLED_CAP    = TRUE

+EFI_READ_STATUS         = TRUE

+EFI_WRITE_DISABLED_CAP  = TRUE

+EFI_WRITE_ENABLED_CAP   = TRUE

+EFI_WRITE_STATUS        = TRUE

+EFI_LOCK_CAP            = TRUE

+EFI_STICKY_WRITE        = TRUE

+EFI_MEMORY_MAPPED       = TRUE

+EFI_ALIGNMENT_CAP       = TRUE

+EFI_ALIGNMENT_2         = TRUE

+EFI_ALIGNMENT_4         = TRUE

+EFI_ALIGNMENT_8         = TRUE

+EFI_ALIGNMENT_16        = TRUE

+EFI_ALIGNMENT_32        = TRUE

+EFI_ALIGNMENT_64        = TRUE

+EFI_ALIGNMENT_128       = TRUE

+EFI_ALIGNMENT_256       = TRUE

+EFI_ALIGNMENT_512       = TRUE

+EFI_ALIGNMENT_1K        = TRUE

+EFI_ALIGNMENT_2K        = TRUE

+EFI_ALIGNMENT_4K        = TRUE

+EFI_ALIGNMENT_8K        = TRUE

+EFI_ALIGNMENT_16K       = TRUE

+EFI_ALIGNMENT_32K       = TRUE

+EFI_ALIGNMENT_64K       = TRUE
\ No newline at end of file
diff --git a/edk2/Tools/Conf/intel_tools.txt b/edk2/Tools/Conf/intel_tools.txt
new file mode 100644
index 0000000..d448246
--- /dev/null
+++ b/edk2/Tools/Conf/intel_tools.txt
@@ -0,0 +1,19 @@
+ASL = -vo

+

+IA32_CC = 

+IA32_LIB =

+IA32_LINK =

+

+X64_CC = 

+X64_LIB =

+X64_LINK =

+

+IPF_CC = 

+IPF_LIB =

+IPF_LINK =

+IPF_ASM = "-N us", "-X explicit", "-M ilp64", "-N so", "-W4"

+

+EBC_CC = "-nologo", "-FAcs", "-c", "-W3", "-WX"

+EBC_LIB = "/lib", "/NOLOGO", "/MACHINE:EBC" 

+EBC_LINK = "/NOLOGO", "/MACHINE:EBC", "/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER", "/OPT:REF", "/NODEFAULTLIB"

+EBC_PP = "/P"
\ No newline at end of file
diff --git a/edk2/Tools/Conf/msft_tools.txt b/edk2/Tools/Conf/msft_tools.txt
new file mode 100644
index 0000000..cc0cf08
--- /dev/null
+++ b/edk2/Tools/Conf/msft_tools.txt
@@ -0,0 +1,8 @@
+ASL = "/nologo"

+

+IA32_CC = "/nologo", "/W3", "/WX", "/GX", "/Gy", "/Gs-", "/c", "/D EFI32", "/D UNICODE"

+IA32_LIB = "/NOLOGO"

+IA32_LINK = "/NOLOGO", "/SUBSYSTEM:CONSOLE", "/NODEFAULTLIB", "/IGNORE:4086", "/MAP", "/OPT:REF", "/MACHINE:I386", "/ALIGN:32", "/DLL", "/LTCG"

+IA32_ASM = "/nologo", "/W3", "/WX", "/c", "/coff", "/DEFI32"

+IA32_ASMLINK = 

+IA32_PP = "/P"

diff --git a/edk2/Tools/Conf/msft_tools_def.txt b/edk2/Tools/Conf/msft_tools_def.txt
new file mode 100644
index 0000000..844c3bb
--- /dev/null
+++ b/edk2/Tools/Conf/msft_tools_def.txt
@@ -0,0 +1,42 @@
+#Host definitions

+HOST_VENDOR = INTEL

+PATH_TO_HOST_CC = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin

+

+#Default values

+CC_NAME = cl.exe

+LIB_NAME = lib.exe

+LINK_NAME = link.exe

+ASM_NAME = ml.exe

+ASMLINK_NAME = link.exe

+ASL_NAME = iasl.exe

+PP_NAME=cl.exe

+

+#define for IA32

+IA32_VENDOR = MSFT

+IA32_ASL_VENDOR = INTEL

+IA32_PATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin

+#IA32_ASM_PATH = C:\MASM611\BIN

+IA32_ASMLINK_PATH = C:\MASM611\BINR

+IA32_ASL_PATH = C:\TianoTools\Bin

+

+#define for x64

+x64_VENDOR = WINDDK

+x64_ASL_VENDOR = INTEL

+x64_PATH = c:\WINDDK\3790.1830\bin\win64\x86\amd64

+x64_ASL_PATH = C:\TianoTools\Bin

+X64_ASM_NAME = ml64.exe

+

+#define for IPF

+IPF_VENDOR = WINDDK

+IPF_ASL_VENDOR = INTEL

+IPF_PATH = c:\WINDDK\3790.1830\bin\win64\x86

+IPF_ASL_PATH = C:\TianoTools\Bin

+IPF_ASM_NAME = ias.exe

+

+#define for EBC

+EBC_VENDOR = INTEL

+EBC_ASL_VENDOR = INTEL

+EBC_PATH = C:\Program Files\Intel\EBC\Bin

+EBC_ASL_PATH = C:\TianoTools\Bin

+EBC_CC_NAME = iec.exe

+EBC_LIB_NAME = link.exe

diff --git a/edk2/Tools/Conf/my_efi_flags.txt b/edk2/Tools/Conf/my_efi_flags.txt
new file mode 100644
index 0000000..f033429
--- /dev/null
+++ b/edk2/Tools/Conf/my_efi_flags.txt
@@ -0,0 +1,2 @@
+EFI_DEBUG              = NO

+EFI_DEBUG_CLEAR_MEMORY = NO
\ No newline at end of file
diff --git a/edk2/Tools/Conf/release_efi_flags.txt b/edk2/Tools/Conf/release_efi_flags.txt
new file mode 100644
index 0000000..0a5e637
--- /dev/null
+++ b/edk2/Tools/Conf/release_efi_flags.txt
@@ -0,0 +1,4 @@
+WORKSPACE_TARGET = DEBUG

+EFI_LOCK_STATUS  = FALSE

+EFI_S3_RESUME    = YES

+EFI_LOG_LEVEL    = 3

diff --git a/edk2/Tools/Conf/target.txt b/edk2/Tools/Conf/target.txt
new file mode 100644
index 0000000..571d517
--- /dev/null
+++ b/edk2/Tools/Conf/target.txt
@@ -0,0 +1,2 @@
+WORKSPACE_TARGET    =   DEBUG

+TARGET_ARCH         =   IA32, x64, IPF, EBC

diff --git a/edk2/Tools/Conf/tools_def.template b/edk2/Tools/Conf/tools_def.template
new file mode 100644
index 0000000..aeec82a
--- /dev/null
+++ b/edk2/Tools/Conf/tools_def.template
@@ -0,0 +1,43 @@
+#Host definitions

+HOST_VENDOR = INTEL

+PATH_TO_HOST_CC = C:\Program Files\Intel\Compiler\c++\9.0\IA32\Bin

+

+#Default values

+CC_NAME = cl.exe

+LIB_NAME = lib.exe

+LINK_NAME = link.exe

+ASM_NAME = ml.exe

+ASMLINK_NAME = link.exe

+ASL_NAME = iasl.exe

+PP_NAME=cl.exe

+

+#define for IA32

+IA32_VENDOR = MSFT

+IA32_ASL_VENDOR = INTEL

+#IA32_PATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin

+#IA32_ASM_PATH = C:\MASM611\BIN

+IA32_ASMLINK_PATH = C:\MASM611\BINR

+IA32_ASL_PATH = C:\TianoTools\Bin

+

+#define for x64

+x64_VENDOR = WINDDK

+x64_ASL_VENDOR = INTEL

+x64_PATH = C:\WINDDK\3790.1830\bin\win64\x86\amd64

+x64_ASL_PATH = C:\TianoTools\Bin

+X64_ASM_NAME = ml64.exe

+

+#define for IPF

+IPF_VENDOR = WINDDK

+IPF_ASL_VENDOR = INTEL

+IPF_PATH = C:\WINDDK\3790.1830\bin\win64\x86

+IPF_ASL_PATH = C:\TianoTools\Bin

+IPF_ASM_NAME = ias.exe

+

+#define for EBC

+EBC_VENDOR = INTEL

+EBC_ASL_VENDOR = INTEL

+EBC_PATH = C:\Program Files\Intel\Ebc\Bin

+EBC_ASL_PATH = C:\TianoTools\Bin

+EBC_CC_NAME = iec.exe

+#EBC_LIB_PATH = 

+EBC_LIB_NAME = link.exe

diff --git a/edk2/Tools/Conf/winddk_tools.txt b/edk2/Tools/Conf/winddk_tools.txt
new file mode 100644
index 0000000..062d974
--- /dev/null
+++ b/edk2/Tools/Conf/winddk_tools.txt
@@ -0,0 +1,19 @@
+IA32_CC = "/nologo", "/X", "/W4", "/WX", "/GX", "/Gy", "/GS-", "/c", "/D EFI32"

+IA32_LIB = "/NOLOGO"

+IA32_LINK = "/NOLOGO", "/SUBSYSTEM:CONSOLE", "/NODEFAULTLIB", "/IGNORE:4086", "/MAP", "/OPT:REF", "/MACHINE:I386", "/ALIGN:32", "/DLL"

+IA32_ASM = "/nologo", "/W3", "/WX", "/c", "/coff", "/DEFI32"

+IA32_PP = "/P"

+

+x64_CC = "/nologo", "/X", "/W4", "/WX", "/Gy", "/c", "/Gs8192", "/GS-", "/D EFIx64"

+x64_LIB = "/NOLOGO"

+x64_LINK = "/NOLOGO", "/Machine:AMD64", "/ALIGN:32", "/DLL", "/NODEFAULTLIB", "/OPT:REF"

+x64_ASM = "/nologo", "/W3", "/WX", "/c", "/DEFI32"

+x64_ASMLINK = 

+x64_PP = "/P"

+

+IPF_CC = "/nologo", "/W4", "/WX", "/EHsc", "/Gy", "/c", "/GS-", "/D EFI64"

+IPF_PP = "/nologo", "/W4", "/WX", "/EHsc", "/Gy", "/c", "/GS-", "-P", "-C", "/D EFI_MONOSHELL", "/D EFI64"

+IPF_LIB = "/NOLOGO"

+IPF_LINK = "/NOLOGO", "/SUBSYSTEM:CONSOLE", "/NODEFAULTLIB", "/IGNORE:4086", "/MAP", "/OPT:REF", "/MACHINE:IA64"

+IPF_ASM = "-N us", "-X explicit", "-M ilp64", "-N so", "-W4" 

+IPF_PP = "/P"

diff --git a/edk2/Tools/FrameworkWizardMinReq.doc b/edk2/Tools/FrameworkWizardMinReq.doc
new file mode 100644
index 0000000..8ce27eb
--- /dev/null
+++ b/edk2/Tools/FrameworkWizardMinReq.doc
Binary files differ
diff --git a/edk2/Tools/JavaResources.msa b/edk2/Tools/JavaResources.msa
new file mode 100644
index 0000000..6eeb7b4
--- /dev/null
+++ b/edk2/Tools/JavaResources.msa
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>JavaResources</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>CUSTOM_BUILD</ComponentType>

+    <Guid>faf22a0f-10fc-428e-b311-fe506a9c0b2d</Guid>

+    <Version>2.0</Version>

+    <Abstract>This is the EFI/Tiano Tool Resources Module</Abstract>

+    <Description>

+      This Module provides the EFI/Tiano Tools and resources that are used to create EFI/Tiano

+      Modules and Platform Binary Files (PBF)

+      These resources and tools do not require compilation.  (The three JAR files are provided,

+      Pre-compiled, and do not require additional compilation, the sources are provided, but

+      will not be built under normal procedures.

+    </Description>

+    <Copyright>Copyright 2005-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-03-23 12:00</CreatedDate>

+    <ModifiedDate>2006-06-01 17:25</ModifiedDate>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">SurfaceArea</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename Path="Conf" FileType="db">FrameworkDatabase.db</Filename>

+    <Filename Path="Conf" FileType="txt">cygwin_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">gcc_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">intel_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">msft_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">tools_def.template</Filename>

+    <Filename Path="Conf" FileType="txt">winddk_tools.txt</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>Base</PackageName>

+  </Includes>

+  <BuildOptions>

+    <Option>DO_NOT_COMPILE</Option>

+  </BuildOptions>

+</ModuleSurfaceArea>

diff --git a/edk2/Tools/Source/Cpptasks/build.xml b/edk2/Tools/Source/Cpptasks/build.xml
new file mode 100644
index 0000000..cfed13b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/build.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="CppTasks" default="all" basedir=".">

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env"/>

+  <property name="workspace" value="${env.WORKSPACE}"/>

+  <property name="buildDir" value="build"/>

+  <property name="installLocation" value="${workspace}/Tools/Jars"/>

+  <target name="all" depends="install"/>

+  <target name="init">

+    <uptodate property="jar.newer" targetfile="${installLocation}/cpptasks.jar">

+      <srcfiles dir="net" includes="**"/>

+    </uptodate>

+  </target>

+  <target name="source" depends="init" unless="jar.newer">

+    <mkdir dir="${buildDir}"/>

+    <javac srcdir="net" destdir="${buildDir}">

+      <classpath>

+        <fileset dir="${workspace}/Tools/Jars">

+          <include name="*.jar"/>

+        </fileset>

+      </classpath>

+    </javac>

+  </target>

+  <target name="clean">

+    <delete dir="${buildDir}"/>

+  </target>

+  <target name="cleanall">

+    <delete dir="${buildDir}"/>

+    <if>

+      <available file="${installLocation}/cpptasks.jar"/>

+      <then>

+        <echo message="You must manually remove the file: ${installLocation}/cpptasks.jar"/>

+        <echo message="Java has already loaded the file, and cannot remove it within ANT!"/>

+      </then>

+    </if>

+  </target>

+  <target name="install" depends="source" unless="jar.newer">

+    <copy file="cpptasks.tasks" toDir="${buildDir}"/>

+    <copy file="cpptasks.types" toDir="${buildDir}"/>

+    <jar destfile="${installLocation}/cpptasks.jar"

+      basedir="${buildDir}"

+      includes="**"

+    />

+  </target>

+</project>

diff --git a/edk2/Tools/Source/Cpptasks/cpptasks.mf b/edk2/Tools/Source/Cpptasks/cpptasks.mf
new file mode 100644
index 0000000..a2bf638
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/cpptasks.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 2.0

+Main-Class: net.sf.antcontrib.cpptasks.AboutCCTask

+

+Name: CCTask

+Implementation-Vendor: Ant-Contrib project

+Implementation-Version: 1.0

+Implementation-Title: Compile and link tasks for Apache Ant

diff --git a/edk2/Tools/Source/Cpptasks/cpptasks.tasks b/edk2/Tools/Source/Cpptasks/cpptasks.tasks
new file mode 100644
index 0000000..f344583
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/cpptasks.tasks
@@ -0,0 +1 @@
+cc=net.sf.antcontrib.cpptasks.CCTask

diff --git a/edk2/Tools/Source/Cpptasks/cpptasks.types b/edk2/Tools/Source/Cpptasks/cpptasks.types
new file mode 100644
index 0000000..65af6e6
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/cpptasks.types
@@ -0,0 +1,9 @@
+defineset=net.sf.antcontrib.cpptasks.types.DefineSet

+compiler=net.sf.antcontrib.cpptasks.CompilerDef

+linker=net.sf.antcontrib.cpptasks.LinkerDef

+assembler=net.sf.antcontrib.cpptasks.AssemblerDef

+aslcompiler=net.sf.antcontrib.cpptasks.AslcompilerDef

+targetplatform=net.sf.antcontrib.cpptasks.TargetDef

+versioninfo=net.sf.antcontrib.cpptasks.VersionInfo

+distributer=net.sf.antcontrib.cpptasks.DistributerDef

+command=net.sf.antcontrib.cpptasks.userdefine.UserDefineDef
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/javadoc.xml b/edk2/Tools/Source/Cpptasks/javadoc.xml
new file mode 100644
index 0000000..f0ca964
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/javadoc.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="javadoc">

+<target name="javadoc">

+

+    <javadoc packagenames="net.sf.antcontrib.*"

+             useexternalfile="yes"

+             sourcepath="."

+             destdir="doc"

+             author="true"

+             version="true"

+             source="1.3"

+             locale="en_US"

+             windowtitle="cpptasks API"

+             doctitle="cpptasks">

+      <group title="CCTasks" packages="net.sf.antcontrib.cpptasks" />

+

+      <bottom>Copyright @2001-2005 Ant-Contrib project. All Rights Reserved.</bottom>

+</javadoc>

+</target>

+</project>

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AboutCCTask.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AboutCCTask.java
new file mode 100644
index 0000000..67757bb
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AboutCCTask.java
@@ -0,0 +1,49 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+/**

+ * The equivalent of a Help About

+ *    run "java -jar cpptasks.jar" to read

+ *

+ *  @author Curt Arnold

+ */

+public class AboutCCTask {

+    /**

+     * display identification message and exit

+     *

+     * @param args ignored

+     */

+    public static void main(String args[]) {

+      System.out.println("CCTask: Compile and link task for Apache Ant 1.5 or later\n");

+      System.out.println("Copyright (c) 2002-2004, The Ant-Contrib project.\n");

+      System.out.println("http://sf.net/projects/ant-contrib\n");

+      System.out.println("Licensed under the Apache Software License 2.0");

+      System.out.println("available at http://www.apache.org/licenses/LICENSE-2.0\n");

+      System.out.println("This software is not a product of the");

+      System.out.println("of the Apache Software Foundation and no");

+      System.out.println("endorsement or promotion is implied.\n");

+      System.out.println("THIS SOFTWARE IS PROVIDED 'AS-IS', See");

+      System.out.println("http://www.apache.org/LICENSE for additional");

+      System.out.println("disclaimers.\n");

+      System.out.println("To use:");

+      System.out.println("\tPlace cpptasks.jar into lib directory of Ant 1.5 or later.");

+      System.out.println("\tAdd <taskdef resource=\"cpptasks.tasks\"/> and");

+      System.out.println("\t\t<typedef resource=\"cpptasks.types\"/> to build.xml");

+      System.out.println("Add <cc/>, <compiler/>, <linker/>, <assembler/> and <aslcompiler> elements.");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ArchEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ArchEnum.java
new file mode 100644
index 0000000..e219ad6
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ArchEnum.java
@@ -0,0 +1,72 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Enumeration of cpu architecture types.

+ *

+ * @author Curt Arnold

+ *

+ */

+public final class ArchEnum

+    extends EnumeratedAttribute {

+  /**

+   * Constructor.

+   *

+   * Set by default to "pentium3"

+   *

+   * @see java.lang.Object#Object()

+   */

+  public ArchEnum() {

+    setValue("pentium3");

+  }

+

+  /**

+   * Gets list of acceptable values.

+   *

+   * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+   */

+  public String[] getValues() {

+    /**

+     * Class initializer.

+     */

+     return new String[] {

+          "i386",

+          "i486",

+          "i586",

+          "i686",

+          "pentium",

+          "pentium-mmx",

+          "pentiumpro",

+          "pentium2",

+          "pentium3",

+          "pentium4",

+          "k6",

+          "k6-2",

+          "k6-3",

+          "athlon",

+          "athlon-tbird",

+          "athlon-4",

+          "athlon-xp",

+          "athlon-mp",

+          "winchip-c6",

+          "winchip2",

+          "c3"};

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AslcompilerDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AslcompilerDef.java
new file mode 100644
index 0000000..f69d3fd
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AslcompilerDef.java
@@ -0,0 +1,118 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import net.sf.antcontrib.cpptasks.compiler.Aslcompiler;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.intel.IntelWin32Aslcompiler;

+import net.sf.antcontrib.cpptasks.types.AslcompilerArgument;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+ * A asl compiler definition. asl compiler elements may be placed either as

+ * children of a cc element or the project element. A asl compiler element with

+ * an id attribute may be referenced from asl compiler elements with refid or

+ * extends attributes.

+ * 

+ */

+public final class AslcompilerDef extends ProcessorDef {

+

+    private Boolean defaultflag = new Boolean(true);

+

+    public AslcompilerDef () {

+    }

+

+    /**

+     * Adds a asl compiler command-line arg.

+     */

+    public void addConfiguredAslcompilerArg(AslcompilerArgument arg) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        addConfiguredProcessorArg(arg);

+    }

+

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                        "Not an actual task, but looks like one for documentation purposes");

+    }

+

+    public final Boolean getDefaultflag(AslcompilerDef[] defaultProviders,

+                    int index) {

+        if (isReference()) {

+            return ((AslcompilerDef) getCheckedRef(AslcompilerDef.class,

+                            "AslcompilerDef")).getDefaultflag(defaultProviders,

+                            index);

+        }

+        return defaultflag;

+    }

+

+    public Processor getProcessor() {

+        Processor processor = super.getProcessor();

+        if (processor == null) {

+            processor = IntelWin32Aslcompiler.getInstance();

+        }

+        return processor;

+    }

+

+    /**

+     * Sets r type.

+     * 

+     * <table width="100%" border="1"> <thead>Supported ASL Compilers</thead>

+     * <tr>

+     * <td>iasl (default)</td>

+     * <td>Intel ACPI Source Language</td>

+     * </tr>

+     * <tr>

+     * <td>asl</td>

+     * <td>Microsoft ACPI Source Language</td>

+     * </tr>

+     * </table>

+     * 

+     */

+    public void setName(AslcompilerEnum name) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        Aslcompiler aslcompiler = name.getAslcompiler();

+        setProcessor(aslcompiler);

+    }

+

+    protected void setProcessor(Processor proc) throws BuildException {

+        try {

+            super.setProcessor((Aslcompiler) proc);

+        } catch (ClassCastException ex) {

+            throw new BuildException(ex);

+        }

+    }

+

+    /**

+     * Enables or disables default flags.

+     * 

+     * @param defaultflag

+     *            if true, default flags will add to command line.

+     * 

+     */

+    public void setDefaultflag(boolean defaultflag) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.defaultflag = booleanValueOf(defaultflag);

+    }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AslcompilerEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AslcompilerEnum.java
new file mode 100644
index 0000000..fa98069
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AslcompilerEnum.java
@@ -0,0 +1,54 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import net.sf.antcontrib.cpptasks.compiler.Aslcompiler;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioAslcompiler;

+import net.sf.antcontrib.cpptasks.intel.IntelWin32Aslcompiler;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Enumeration of supported ASL Compilers

+ * 

+ * <table width="100%" border="1"> <thead>Supported ASL Compilers </thead>

+ * <tr>

+ * <td>iasl (default)</td>

+ * <td>Intel ACPI Source Language</td>

+ * </tr>

+ * <tr>

+ * <td>asl</td>

+ * <td>Microsoft ACPI Source Language</td>

+ * </tr>

+ * </table>

+ * 

+ */

+public class AslcompilerEnum extends EnumeratedAttribute {

+    private final static ProcessorEnumValue[] aslcompiler = new ProcessorEnumValue[] {

+                    new ProcessorEnumValue("iasl", IntelWin32Aslcompiler

+                                    .getInstance()),

+                    new ProcessorEnumValue("asl", DevStudioAslcompiler

+                                    .getInstance()), };

+

+    public Aslcompiler getAslcompiler() {

+        return (Aslcompiler) aslcompiler[getIndex()].getProcessor();

+    }

+

+    public String[] getValues() {

+        return ProcessorEnumValue.getValues(aslcompiler);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AssemblerDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AssemblerDef.java
new file mode 100644
index 0000000..aeae215
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AssemblerDef.java
@@ -0,0 +1,237 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.Assembler;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.gcc.GccAssembler;

+import net.sf.antcontrib.cpptasks.types.AssemblerArgument;

+import net.sf.antcontrib.cpptasks.types.ConditionalPath;

+import net.sf.antcontrib.cpptasks.types.IncludePath;

+import net.sf.antcontrib.cpptasks.types.SystemIncludePath;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+

+/**

+ * A assembler definition. Assembler elements may be placed either as children

+ * of a cc element or the project element. A assembler element with an id

+ * attribute may be referenced from assembler elements with refid or extends

+ * attributes.

+ * 

+ */

+public final class AssemblerDef extends ProcessorDef {

+

+    private final Vector includePaths = new Vector();

+

+    private final Vector sysIncludePaths = new Vector();

+

+    private Boolean defaultflag = new Boolean(true);

+

+    public AssemblerDef () {

+    }

+

+    /**

+     * Adds a assembler command-line arg.

+     */

+    public void addConfiguredAssemblerArg(AssemblerArgument arg) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        addConfiguredProcessorArg(arg);

+    }

+

+    /**

+     * Creates an include path.

+     */

+    public IncludePath createIncludePath() {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        IncludePath path = new IncludePath(p);

+        includePaths.addElement(path);

+        return path;

+    }

+

+    /**

+     * Creates an include path.

+     */

+    public SystemIncludePath createSysIncludePath() {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        SystemIncludePath path = new SystemIncludePath(p);

+        sysIncludePaths.addElement(path);

+        return path;

+    }

+

+    /**

+     * Add a <includepath>or <sysincludepath> if specify the file attribute

+     * 

+     * @throws BuildException

+     *             if the specify file not exist

+     */

+    protected void loadFile(Vector activePath, File file) throws BuildException {

+        FileReader fileReader;

+        BufferedReader in;

+        String str;

+        if (!file.exists()) {

+            throw new BuildException("The file " + file + " is not existed");

+        }

+        try {

+            fileReader = new FileReader(file);

+            in = new BufferedReader(fileReader);

+            while ((str = in.readLine()) != null) {

+                if (str.trim() == "") {

+                    continue;

+                }

+                str = getProject().replaceProperties(str);

+                activePath.addElement(str.trim());

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                        "Not an actual task, but looks like one for documentation purposes");

+    }

+

+    /**

+     * Returns the assembler-specific include path.

+     */

+    public String[] getActiveIncludePaths() {

+        if (isReference()) {

+            return ((AssemblerDef) getCheckedRef(AssemblerDef.class,

+                            "AssemblerDef")).getActiveIncludePaths();

+        }

+        return getActivePaths(includePaths);

+    }

+

+    /**

+     * Returns the assembler-specific sysinclude path.

+     */

+    public String[] getActiveSysIncludePaths() {

+        if (isReference()) {

+            return ((AssemblerDef) getCheckedRef(AssemblerDef.class,

+                            "AssemblerDef")).getActiveSysIncludePaths();

+        }

+        return getActivePaths(sysIncludePaths);

+    }

+

+    private String[] getActivePaths(Vector paths) {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project not set");

+        }

+        Vector activePaths = new Vector(paths.size());

+        for (int i = 0; i < paths.size(); i++) {

+            ConditionalPath path = (ConditionalPath) paths.elementAt(i);

+            if (path.isActive(p)) {

+                if (path.getFile() == null) {

+                    String[] pathEntries = path.list();

+                    for (int j = 0; j < pathEntries.length; j++) {

+                        activePaths.addElement(pathEntries[j]);

+                    }

+                } else {

+                    loadFile(activePaths, path.getFile());

+                }

+            }

+        }

+        String[] pathNames = new String[activePaths.size()];

+        activePaths.copyInto(pathNames);

+        return pathNames;

+    }

+

+    public final Boolean getDefaultflag(AssemblerDef[] defaultProviders,

+                    int index) {

+        if (isReference()) {

+            return ((AssemblerDef) getCheckedRef(AssemblerDef.class,

+                            "AssemblerDef")).getDefaultflag(defaultProviders,

+                            index);

+        }

+        return defaultflag;

+    }

+

+    public Processor getProcessor() {

+        Processor processor = super.getProcessor();

+        if (processor == null) {

+            processor = GccAssembler.getInstance();

+        }

+        return processor;

+    }

+

+    /**

+     * Sets r type.

+     * 

+     * <table width="100%" border="1"> <thead>Supported assemblers</thead>

+     * <tr>

+     * <td>gcc (default)</td>

+     * <td>GAS assembler</td>

+     * </tr>

+     * <tr>

+     * <td>masm</td>

+     * <td>MASM assembler</td>

+     * </tr>

+     * </table>

+     * 

+     */

+    public void setName(AssemblerEnum name) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        Assembler assembler = name.getAssembler();

+        setProcessor(assembler);

+    }

+

+    protected void setProcessor(Processor proc) throws BuildException {

+        try {

+            super.setProcessor((Assembler) proc);

+        } catch (ClassCastException ex) {

+            throw new BuildException(ex);

+        }

+    }

+

+    /**

+     * Enables or disables default flags.

+     * 

+     * @param defaultflag

+     *            if true, default flags will add to command line.

+     * 

+     */

+    public void setDefaultflag(boolean defaultflag) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.defaultflag = booleanValueOf(defaultflag);

+    }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AssemblerEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AssemblerEnum.java
new file mode 100644
index 0000000..9abf9f4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/AssemblerEnum.java
@@ -0,0 +1,53 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import net.sf.antcontrib.cpptasks.compiler.Assembler;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioAssembler;

+import net.sf.antcontrib.cpptasks.gcc.GccAssembler;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Enumeration of supported assemblers

+ * 

+ * <table width="100%" border="1"> <thead>Supported assemblers </thead>

+ * <tr>

+ * <td>gas (default)</td>

+ * <td>GAS assembler</td>

+ * </tr>

+ * <tr>

+ * <td>masm</td>

+ * <td>MASM assembler</td>

+ * </tr>

+ * </table>

+ * 

+ */

+public class AssemblerEnum extends EnumeratedAttribute {

+    private final static ProcessorEnumValue[] assemblers = new ProcessorEnumValue[] {

+                    new ProcessorEnumValue("gas", GccAssembler.getInstance()),

+                    new ProcessorEnumValue("masm", DevStudioAssembler

+                                    .getInstance()), };

+

+    public Assembler getAssembler() {

+        return (Assembler) assemblers[getIndex()].getProcessor();

+    }

+

+    public String[] getValues() {

+        return ProcessorEnumValue.getValues(assemblers);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CCTask.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CCTask.java
new file mode 100644
index 0000000..d044df1
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CCTask.java
@@ -0,0 +1,1749 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import java.io.File;

+import java.io.IOException;

+import java.util.Enumeration;

+import java.util.Hashtable;

+import java.util.Iterator;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.AslcompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.AssemblerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.LinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+import net.sf.antcontrib.cpptasks.types.AslcompilerArgument;

+import net.sf.antcontrib.cpptasks.types.AssemblerArgument;

+import net.sf.antcontrib.cpptasks.types.CompilerArgument;

+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;

+import net.sf.antcontrib.cpptasks.types.DefineSet;

+import net.sf.antcontrib.cpptasks.types.IncludePath;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.types.LinkerArgument;

+import net.sf.antcontrib.cpptasks.types.SystemIncludePath;

+import net.sf.antcontrib.cpptasks.types.SystemLibrarySet;

+import net.sf.antcontrib.cpptasks.userdefine.UserDefineCompiler;

+import net.sf.antcontrib.cpptasks.userdefine.UserDefineDef;

+import net.sf.antcontrib.cpptasks.VersionInfo;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.types.Environment;

+

+/**

+ * Compile, link, assembler and asl compile task.

+ * 

+ * <p>

+ * This task can compile various source languages and produce executables,

+ * shared libraries (aka DLL's) and static libraries. Compiler adaptors are

+ * currently available for several C/C++ compilers, FORTRAN, MIDL and Windows

+ * Resource files. Assembler adaptors are currently available for MASM and GAS.

+ * And aslcompiler support to ASL and IASL command.

+ * </p>

+ * 

+ * 

+ * <p>

+ * Copyright (c) 2001-2005, The Ant-Contrib project.

+ * </p>

+ * 

+ * <p>

+ * Licensed under the Apache Software License 2.0,

+ * http://www.apache.org/licenses/LICENSE-2.0.

+ * </p>

+ * 

+ * <p>

+ * For use with Apache Ant 1.5 or later. This software is not a product of the

+ * of the Apache Software Foundation and no endorsement is implied.

+ * </p>

+ * 

+ * <p>

+ * THIS SOFTWARE IS PROVIDED 'AS-IS', See

+ * http://www.apache.org/licenses/LICENSE-2.0 for additional disclaimers.

+ * </p>

+ * 

+ * To use:

+ * <ol>

+ * <li>Place cpptasks.jar into the lib directory of Ant 1.5 or later.</li>

+ * <li>Add &lt;taskdef resource="cpptasks.tasks"/&gt; and &lt;typedef

+ * resource="cpptasks.types"/&gt; to build.xml.</li>

+ * <li>Add &lt;cc/&gt;, &lt;compiler/&gt; &lt;linker/&gt; &lt;assembler/&gt;

+ * and &lt;aslcompiler/&gt elements to project.</li>

+ * <li>Set path and environment variables to be able to run compiler from

+ * command line.</li>

+ * <li>Build project.</li>

+ * </ol>

+ * 

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public class CCTask extends Task {

+    private class SystemLibraryCollector implements FileVisitor {

+        private Hashtable libraries;

+

+        private Linker linker;

+

+        public SystemLibraryCollector (Linker linker, Hashtable libraries) {

+            this.linker = linker;

+            this.libraries = libraries;

+        }

+

+        public void visit(File basedir, String filename) {

+            if (linker.bid(filename) > 0) {

+                File libfile = new File(basedir, filename);

+                String key = linker.getLibraryKey(libfile);

+                libraries.put(key, libfile);

+            }

+        }

+    }

+

+    private static final ProcessorConfiguration[] EMPTY_CONFIG_ARRAY = new ProcessorConfiguration[0];

+

+    /**

+     * Builds a Hashtable to targets needing to be rebuilt keyed by compiler

+     * configuration

+     */

+    public static Hashtable getTargetsToBuildByConfiguration(Hashtable targets) {

+        Hashtable targetsByConfig = new Hashtable();

+        Enumeration targetEnum = targets.elements();

+        while (targetEnum.hasMoreElements()) {

+            TargetInfo target = (TargetInfo) targetEnum.nextElement();

+            if (target.getRebuild()) {

+                Vector targetsForSameConfig = (Vector) targetsByConfig

+                                .get(target.getConfiguration());

+                if (targetsForSameConfig != null) {

+                    targetsForSameConfig.addElement(target);

+                } else {

+                    targetsForSameConfig = new Vector();

+                    targetsForSameConfig.addElement(target);

+                    targetsByConfig.put(target.getConfiguration(),

+                                    targetsForSameConfig);

+                }

+            }

+        }

+        return targetsByConfig;

+    }

+

+    /** The userdefine definitions. */

+    private Vector _userdefines = new Vector();

+    

+    /** The compiler definitions. */

+    private Vector _compilers = new Vector();

+

+    /** The output file type. */

+    // private LinkType _linkType = LinkType.EXECUTABLE;

+    /** The library sets. */

+    private Vector _libsets = new Vector();

+

+    /** The aslcompiler definitions. */

+    private Vector _aslcompiler = new Vector();

+

+    /** The assembler definitions. */

+    private Vector _assemblers = new Vector();

+

+    /** The linker definitions. */

+    private Vector _linkers = new Vector();

+

+    /** The object directory. */

+    private File _objDir;

+

+    /** The output file. */

+    private File _outfile;

+    

+    private boolean userdefine = false;

+    private String arch;

+    private String os;

+    private String vendor;

+    

+    /** the flag for assembler */

+    private boolean assembler = true;

+

+    /** the flag for aslcompiler */

+    private boolean aslcompiler = true;

+

+    /** The linker definitions. */

+    private final Vector targetPlatforms = new Vector();

+

+    /** The distributer definitions. */

+    private Vector distributers = new Vector();

+

+    /**

+     * If true, stop build on compile failure.

+     */

+    protected boolean failOnError = true;

+

+    /**

+     * Content that appears in <cc>and also in <compiler>are maintained by a

+     * captive CompilerDef instance

+     */

+    private final CompilerDef compilerDef = new CompilerDef();

+

+    /**

+     * Content that appears in <cc>and also in <aslcompiler>are maintained by a

+     * captive AslcompilerDef instance

+     */

+    private final AslcompilerDef aslcompilerDef = new AslcompilerDef();

+

+    /** The OS390 dataset to build to object to */

+    private String dataset;

+

+    /**

+     * 

+     * Depth of dependency checking

+     * 

+     * Values < 0 indicate full dependency checking Values >= 0 indicate partial

+     * dependency checking and for superficial compilation checks. Will throw

+     * BuildException before attempting link

+     */

+    private int dependencyDepth = -1;

+

+    /**

+     * Content that appears in <cc>and also in <assembler>are maintained by a

+     * captive AssemblerDef instance

+     */

+    private final AssemblerDef assemblerDef = new AssemblerDef();

+

+    /**

+     * Content that appears in <cc>and also in <linker>are maintained by a

+     * captive CompilerDef instance

+     */

+    private final LinkerDef linkerDef = new LinkerDef();

+

+    /**

+     * contains the subsystem, output type and

+     * 

+     */

+    private final LinkType linkType = new LinkType();

+

+    /**

+     * The property name which will be set with the physical filename of the

+     * file that is generated by the linker

+     */

+    private String outputFileProperty;

+

+    /**

+     * if relentless = true, compilations should attempt to compile as many

+     * files as possible before throwing a BuildException

+     */

+    private boolean relentless;

+

+    public CCTask () {

+    }

+

+    

+    public void addConfiguredCommand(UserDefineDef userdefineDef) {

+        if (userdefineDef == null) {

+            throw new NullPointerException("UserDefineDef");

+        }

+        userdefineDef.setProject(getProject());

+        _userdefines.addElement(userdefineDef);

+    }

+    /**

+     * Adds a asl compiler definition or reference.

+     * 

+     * @param Aslcompiler

+     *            aslcompiler

+     * @throws NullPointerException

+     *             if aslcompiler is null

+     */

+    public void addConfiguredAslcompiler(AslcompilerDef aslcompier) {

+        if (aslcompier == null) {

+            throw new NullPointerException("aslcompier");

+        }

+        aslcompier.setProject(getProject());

+        _aslcompiler.addElement(aslcompier);

+    }

+

+    /**

+     * Adds a asl command-line arg. Argument will be inherited by all nested

+     * aslcompiler elements that do not have inherit="false".

+     * 

+     */

+    public void addConfiguredAslcompilerArg(AslcompilerArgument arg) {

+        aslcompilerDef.addConfiguredAslcompilerArg(arg);

+    }

+

+    /**

+     * Adds a assembler definition or reference.

+     * 

+     * @param assembler

+     *            assemblera

+     * @throws NullPointerException

+     *             if assembler is null

+     */

+    public void addConfiguredAssembler(AssemblerDef assembler) {

+        if (assembler == null) {

+            throw new NullPointerException("assembler");

+        }

+        assembler.setProject(getProject());

+        _assemblers.addElement(assembler);

+    }

+

+    /**

+     * Adds a assembler command-line arg. Argument will be inherited by all

+     * nested assembler elements that do not have inherit="false".

+     * 

+     */

+    public void addConfiguredAssemblerArg(AssemblerArgument arg) {

+        assemblerDef.addConfiguredAssemblerArg(arg);

+    }

+

+    /**

+     * Adds a compiler definition or reference.

+     * 

+     * @param compiler

+     *            compiler

+     * @throws NullPointerException

+     *             if compiler is null

+     */

+    public void addConfiguredCompiler(CompilerDef compiler) {

+        if (compiler == null) {

+            throw new NullPointerException("compiler");

+        }

+        compiler.setProject(getProject());

+        _compilers.addElement(compiler);

+    }

+

+    /**

+     * Adds a compiler command-line arg. Argument will be inherited by all

+     * nested compiler elements that do not have inherit="false".

+     * 

+     */

+    public void addConfiguredCompilerArg(CompilerArgument arg) {

+        compilerDef.addConfiguredCompilerArg(arg);

+    }

+

+    /**

+     * Adds a defineset. Will be inherited by all compiler elements that do not

+     * have inherit="false".

+     * 

+     * @param defs

+     *            Define set

+     */

+    public void addConfiguredDefineset(DefineSet defs) {

+        compilerDef.addConfiguredDefineset(defs);

+    }

+

+    /**

+     * Adds a linker definition. The first linker that is not disqualified by

+     * its "if" and "unless" attributes will perform the link. If no child

+     * linker element is active, the linker implied by the cc elements name or

+     * classname attribute will be used.

+     * 

+     * @param linker

+     *            linker

+     * @throws NullPointerException

+     *             if linker is null

+     */

+    public void addConfiguredLinker(LinkerDef linker) {

+        if (linker == null) {

+            throw new NullPointerException("linker");

+        }

+        linker.setProject(getProject());

+        _linkers.addElement(linker);

+    }

+

+    /**

+     * Adds a linker command-line arg. Argument will be inherited by all nested

+     * linker elements that do not have inherit="false".

+     */

+    public void addConfiguredLinkerArg(LinkerArgument arg) {

+        linkerDef.addConfiguredLinkerArg(arg);

+    }

+

+    /**

+     * Add an environment variable to the launched process.

+     */

+    public void addEnv(Environment.Variable var) {

+        compilerDef.addEnv(var);

+        linkerDef.addEnv(var);

+        assemblerDef.addEnv(var);

+        aslcompilerDef.addEnv(var);

+    }

+

+    /**

+     * Adds a source file set.

+     * 

+     * Files in these filesets will be auctioned to the available compiler

+     * configurations, with the default compiler implied by the cc element

+     * bidding last. If no compiler is interested in the file, it will be passed

+     * to the linker.

+     * 

+     * To have a file be processed by a particular compiler configuration, add a

+     * fileset to the corresponding compiler element.

+     */

+    public void addFileset(ConditionalFileSet srcSet) {

+        compilerDef.addFileset(srcSet);

+    }

+

+    /**

+     * Adds a library set.

+     * 

+     * Library sets will be inherited by all linker elements that do not have

+     * inherit="false".

+     * 

+     * @param libset

+     *            library set

+     * @throws NullPointerException

+     *             if libset is null.

+     */

+    public void addLibset(LibrarySet libset) {

+        if (libset == null) {

+            throw new NullPointerException("libset");

+        }

+        linkerDef.addLibset(libset);

+    }

+

+    /**

+     * Adds a system library set. Timestamps and locations of system library

+     * sets are not used in dependency analysis.

+     * 

+     * Essential libraries (such as C Runtime libraries) should not be specified

+     * since the task will attempt to identify the correct libraries based on

+     * the multithread, debug and runtime attributes.

+     * 

+     * System library sets will be inherited by all linker elements that do not

+     * have inherit="false".

+     * 

+     * @param libset

+     *            library set

+     * @throws NullPointerException

+     *             if libset is null.

+     */

+    public void addSyslibset(SystemLibrarySet libset) {

+        if (libset == null) {

+            throw new NullPointerException("libset");

+        }

+        linkerDef.addSyslibset(libset);

+    }

+

+    /**

+     * Checks all targets that are not forced to be rebuilt or are missing

+     * object files to be checked for modified include files

+     * 

+     * @returns total number of targets to be rebuilt

+     * 

+     */

+    protected int checkForChangedIncludeFiles(Hashtable targets) {

+        int potentialTargets = 0;

+        int definiteTargets = 0;

+        Enumeration targetEnum = targets.elements();

+        while (targetEnum.hasMoreElements()) {

+            TargetInfo target = (TargetInfo) targetEnum.nextElement();

+            if (!target.getRebuild()) {

+                potentialTargets++;

+            } else {

+                definiteTargets++;

+            }

+        }

+        //

+        // If there were remaining targets that

+        // might be out of date

+        //

+        if (potentialTargets > 0) {

+            log("Starting dependency analysis for "

+                            + Integer.toString(potentialTargets) + " files.");

+            DependencyTable dependencyTable = new DependencyTable(_objDir);

+            try {

+                dependencyTable.load();

+            } catch (Exception ex) {

+                log("Problem reading dependencies.xml: " + ex.toString());

+            }

+            targetEnum = targets.elements();

+            while (targetEnum.hasMoreElements()) {

+                TargetInfo target = (TargetInfo) targetEnum.nextElement();

+                if (!target.getRebuild()) {

+                    if (dependencyTable.needsRebuild(this, target,

+                                    dependencyDepth)) {

+                        target.mustRebuild();

+                    }

+                }

+            }

+            dependencyTable.commit(this);

+        }

+        //

+        // count files being rebuilt now

+        //

+        int currentTargets = 0;

+        targetEnum = targets.elements();

+        while (targetEnum.hasMoreElements()) {

+            TargetInfo target = (TargetInfo) targetEnum.nextElement();

+            if (target.getRebuild()) {

+                currentTargets++;

+            }

+        }

+        if (potentialTargets > 0) {

+            log(Integer.toString(potentialTargets - currentTargets

+                            + definiteTargets)

+                            + " files are up to date.");

+            log(Integer.toString(currentTargets - definiteTargets)

+                            + " files to be recompiled from dependency analysis.");

+        }

+        log(Integer.toString(currentTargets) + " total files to be compiled.");

+        return currentTargets;

+    }

+

+    protected LinkerConfiguration collectExplicitObjectFiles(

+                    Vector objectFiles, Vector sysObjectFiles) {

+        //

+        // find the first eligible linker

+        //

+        //

+        ProcessorConfiguration linkerConfig = null;

+        LinkerDef selectedLinkerDef = null;

+        Linker selectedLinker = null;

+        Hashtable sysLibraries = new Hashtable();

+        TargetDef targetPlatform = getTargetPlatform();

+        FileVisitor objCollector = null;

+        FileVisitor sysLibraryCollector = null;

+        for (int i = 0; i < _linkers.size(); i++) {

+            LinkerDef currentLinkerDef = (LinkerDef) _linkers.elementAt(i);

+            if (currentLinkerDef.isActive()) {

+                selectedLinkerDef = currentLinkerDef;

+                selectedLinker = currentLinkerDef.getProcessor().getLinker(

+                                linkType);

+                //

+                // skip the linker if it doesn't know how to

+                // produce the specified link type

+                if (selectedLinker != null) {

+                    linkerConfig = currentLinkerDef.createConfiguration(this,

+                                    linkType, linkerDef, targetPlatform);

+                    if (linkerConfig != null) {

+                        //

+                        // create collectors for object files

+                        // and system libraries

+                        objCollector = new ObjectFileCollector(selectedLinker,

+                                        objectFiles);

+                        sysLibraryCollector = new SystemLibraryCollector(

+                                        selectedLinker, sysLibraries);

+                        //

+                        // if the <linker> has embedded <fileset>'s

+                        // (such as linker specific libraries)

+                        // add them as object files.

+                        //

+                        if (currentLinkerDef.hasFileSets()) {

+                            currentLinkerDef.visitFiles(objCollector);

+                        }

+                        //

+                        // user libraries are just a specialized form

+                        // of an object fileset

+                        selectedLinkerDef.visitUserLibraries(selectedLinker,

+                                        objCollector);

+                    }

+                    break;

+                }

+            }

+        }

+        if (linkerConfig == null) {

+            linkerConfig = linkerDef.createConfiguration(this, linkType, null,

+                            targetPlatform);

+            selectedLinker = (Linker) linkerDef.getProcessor().getLinker(

+                            linkType);

+            objCollector = new ObjectFileCollector(selectedLinker, objectFiles);

+            sysLibraryCollector = new SystemLibraryCollector(selectedLinker,

+                            sysLibraries);

+        }

+        //

+        // unless there was a <linker> element that

+        // explicitly did not inherit files from

+        // containing <cc> element

+        if (selectedLinkerDef == null || selectedLinkerDef.getInherit()) {

+            linkerDef.visitUserLibraries(selectedLinker, objCollector);

+            linkerDef.visitSystemLibraries(selectedLinker, sysLibraryCollector);

+        }

+        //

+        // if there was a <syslibset> in a nested <linker>

+        // evaluate it last so it takes priority over

+        // identically named libs from <cc> element

+        //

+        if (selectedLinkerDef != null) {

+            //

+            // add any system libraries to the hashtable

+            // done in reverse order so the earliest

+            // on the classpath takes priority

+            selectedLinkerDef.visitSystemLibraries(selectedLinker,

+                            sysLibraryCollector);

+        }

+        //

+        // copy over any system libraries to the

+        // object files vector

+        //

+        Enumeration sysLibEnum = sysLibraries.elements();

+        while (sysLibEnum.hasMoreElements()) {

+            sysObjectFiles.addElement(sysLibEnum.nextElement());

+        }

+        return (LinkerConfiguration) linkerConfig;

+    }

+

+    /**

+     * Adds an include path.

+     * 

+     * Include paths will be inherited by nested compiler elements that do not

+     * have inherit="false".

+     */

+    public IncludePath createIncludePath() {

+        return compilerDef.createIncludePath();

+    }

+

+    /**

+     * Specifies precompilation prototype file and exclusions. Inherited by all

+     * compilers that do not have inherit="false".

+     * 

+     */

+    public PrecompileDef createPrecompile() throws BuildException {

+        return compilerDef.createPrecompile();

+    }

+

+    /**

+     * Adds a system include path. Locations and timestamps of files located

+     * using the system include paths are not used in dependency analysis.

+     * 

+     * 

+     * Standard include locations should not be specified. The compiler adapters

+     * should recognized the settings from the appropriate environment variables

+     * or configuration files.

+     * 

+     * System include paths will be inherited by nested compiler elements that

+     * do not have inherit="false".

+     */

+    public SystemIncludePath createSysIncludePath() {

+        return compilerDef.createSysIncludePath();

+    }

+

+    /**

+     * Executes the task. Compiles the given files.

+     * 

+     * @throws BuildException

+     *             if someting goes wrong with the build

+     */

+    public void execute() throws BuildException {

+        //

+        // if link type allowed objdir to be defaulted

+        // provide it from outfile

+        if (_objDir == null) {

+            if (_outfile != null) {

+                _objDir = new File(_outfile.getParent());

+            } else {

+                _objDir = new File(".");

+            }

+        }

+

+        //

+        // if the object directory does not exist

+        //

+        if (!_objDir.exists()) {

+            throw new BuildException("Object directory does not exist");

+        }

+        

+        //

+        // if userdefine is true, then run all user defined command

+        //

+        if (userdefine) {

+            Iterator iter = _userdefines.iterator();

+            while( iter.hasNext()) {

+                UserDefineDef userdefineDef = (UserDefineDef)iter.next();

+                UserDefineCompiler userdefineCompiler = new UserDefineCompiler(this, userdefineDef);

+                userdefineCompiler.command(this, userdefineDef);

+            }

+            return ;

+        }

+        

+        TargetHistoryTable objHistory = new TargetHistoryTable(this, _objDir);

+        //

+        // determine the eventual linker configuration

+        // (may be null) and collect any explicit

+        // object files or libraries

+        Vector objectFiles = new Vector();

+        Vector sysObjectFiles = new Vector();

+        LinkerConfiguration linkerConfig = collectExplicitObjectFiles(

+                        objectFiles, sysObjectFiles);

+        //

+        // Assembler hashtable of all files

+        // that we know how to compile (keyed by output file name)

+        //

+        Hashtable targets = getTargets(linkerConfig, objectFiles);

+        Hashtable acpiTarget = new Hashtable();

+        if (aslcompiler) {

+            acpiTarget = getAcpiTargets(linkerConfig, new Vector());

+        }

+        Hashtable assemblerTarget = new Hashtable();

+        if (assembler) {

+            assemblerTarget = getAssemblerTargets(linkerConfig, objectFiles);

+        }

+        TargetInfo linkTarget = null;

+        //

+        // if output file is not specified,

+        // then skip link step

+        //

+        if (_outfile != null) {

+            linkTarget = getLinkTarget(linkerConfig, objectFiles,

+                            sysObjectFiles, targets, assemblerTarget);

+        }

+        //

+        // If specify the aslcompiler, then call asl compiler

+        //

+        if (aslcompiler) {

+            BuildException acpiException = null;

+            Hashtable targetsByConfig = getTargetsToBuildByConfiguration(acpiTarget);

+            Enumeration acpiTargetEnum = targetsByConfig.elements();

+            Vector[] targetVectors = new Vector[targetsByConfig.size()];

+            int index = 0;

+            while (acpiTargetEnum.hasMoreElements()) {

+                Vector targetsForConfig = (Vector) acpiTargetEnum.nextElement();

+                targetVectors[index++] = targetsForConfig;

+            }

+            for (int i = 0; i < targetVectors.length; i++) {

+                //

+                // get the targets for this configuration

+                //

+                Vector targetsForConfig = targetVectors[i];

+                //

+                // get the configuration from the first entry

+                //

+                AslcompilerConfiguration config = (AslcompilerConfiguration) ((TargetInfo) targetsForConfig

+                                .elementAt(0)).getConfiguration();

+                //

+                // prepare the list of source files

+                //

+                String[] sourceFiles = new String[targetsForConfig.size()];

+                Enumeration targetsEnum = targetsForConfig.elements();

+                index = 0;

+                while (targetsEnum.hasMoreElements()) {

+                    TargetInfo targetInfo = ((TargetInfo) targetsEnum

+                                    .nextElement());

+                    sourceFiles[index++] = targetInfo.getSources()[0]

+                                    .toString();

+                }

+                try {

+                    config.aslcompiler(this, _objDir, sourceFiles);

+                    log(sourceFiles.length

+                                    + " total ACPI source files to be compiled.");

+                } catch (BuildException ex) {

+                    if (acpiException == null) {

+                        acpiException = ex;

+                    }

+                    if (!relentless)

+                        break;

+                }

+            }

+        }

+        //

+        // If specify the assembler, then call assembler

+        //

+        if (assembler) {

+            BuildException assemblerException = null;

+            Hashtable targetsByConfig = getTargetsToBuildByConfiguration(assemblerTarget);

+            Enumeration assembleTargetEnum = targetsByConfig.elements();

+            Vector[] targetVectors = new Vector[targetsByConfig.size()];

+            int index = 0;

+            while (assembleTargetEnum.hasMoreElements()) {

+                Vector targetsForConfig = (Vector) assembleTargetEnum

+                                .nextElement();

+                targetVectors[index++] = targetsForConfig;

+            }

+            for (int i = 0; i < targetVectors.length; i++) {

+                //

+                // get the targets for this configuration

+                //

+                Vector targetsForConfig = targetVectors[i];

+                //

+                // get the configuration from the first entry

+                //

+                AssemblerConfiguration config = (AssemblerConfiguration) ((TargetInfo) targetsForConfig

+                                .elementAt(0)).getConfiguration();

+                //

+                // prepare the list of source files

+                //

+                String[] sourceFiles = new String[targetsForConfig.size()];

+                Enumeration targetsEnum = targetsForConfig.elements();

+                index = 0;

+                while (targetsEnum.hasMoreElements()) {

+                    TargetInfo targetInfo = ((TargetInfo) targetsEnum

+                                    .nextElement());

+                    sourceFiles[index++] = targetInfo.getSources()[0]

+                                    .toString();

+                }

+                try {

+                    config.assembler(this, _objDir, sourceFiles);

+                    log(sourceFiles.length + " total files to be assembled.");

+                } catch (BuildException ex) {

+                    if (assemblerException == null) {

+                        assemblerException = ex;

+                    }

+                    if (!relentless)

+                        break;

+                }

+            }

+            //

+            // if we threw a assembler exception and

+            // didn't throw it at the time because

+            // we were relentless then

+            // save the history and

+            // throw the exception

+            //

+            if (assemblerException != null) {

+                if (failOnError) {

+                    throw assemblerException;

+                } else {

+                    log(assemblerException.getMessage(), Project.MSG_ERR);

+                    return;

+                }

+            }

+        }

+

+        //

+        // mark targets that don't have a history record or

+        // whose source last modification time is not

+        // the same as the history to be rebuilt

+        //

+        objHistory.markForRebuild(targets);

+        CCTaskProgressMonitor monitor = new CCTaskProgressMonitor(objHistory);

+        //

+        // check for changed include files

+        //

+        int rebuildCount = checkForChangedIncludeFiles(targets);

+        if (rebuildCount > 0) {

+            BuildException compileException = null;

+            //

+            // compile all targets with getRebuild() == true

+            //

+            Hashtable targetsByConfig = getTargetsToBuildByConfiguration(targets);

+            //

+            // build array containing Vectors with precompiled generation

+            // steps going first

+            //

+            Vector[] targetVectors = new Vector[targetsByConfig.size()];

+            int index = 0;

+            Enumeration targetVectorEnum = targetsByConfig.elements();

+            while (targetVectorEnum.hasMoreElements()) {

+                Vector targetsForConfig = (Vector) targetVectorEnum

+                                .nextElement();

+                //

+                // get the configuration from the first entry

+                //

+                CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig

+                                .elementAt(0)).getConfiguration();

+                if (config.isPrecompileGeneration()) {

+                    targetVectors[index++] = targetsForConfig;

+                }

+            }

+            targetVectorEnum = targetsByConfig.elements();

+            while (targetVectorEnum.hasMoreElements()) {

+                Vector targetsForConfig = (Vector) targetVectorEnum

+                                .nextElement();

+                for (int i = 0; i < targetVectors.length; i++) {

+                    if (targetVectors[i] == targetsForConfig) {

+                        break;

+                    }

+                    if (targetVectors[i] == null) {

+                        targetVectors[i] = targetsForConfig;

+                        break;

+                    }

+                }

+            }

+            for (int i = 0; i < targetVectors.length; i++) {

+                //

+                // get the targets for this configuration

+                //

+                Vector targetsForConfig = targetVectors[i];

+                //

+                // get the configuration from the first entry

+                //

+                CompilerConfiguration config = (CompilerConfiguration) ((TargetInfo) targetsForConfig

+                                .elementAt(0)).getConfiguration();

+                //

+                // prepare the list of source files

+                //

+                String[] sourceFiles = new String[targetsForConfig.size()];

+                Enumeration targetsEnum = targetsForConfig.elements();

+                index = 0;

+                while (targetsEnum.hasMoreElements()) {

+                    TargetInfo targetInfo = ((TargetInfo) targetsEnum

+                                    .nextElement());

+                    sourceFiles[index++] = targetInfo.getSources()[0]

+                                    .toString();

+                }

+                try {

+                    config.compile(this, _objDir, sourceFiles, relentless,

+                                    monitor);

+                } catch (BuildException ex) {

+                    if (compileException == null) {

+                        compileException = ex;

+                    }

+                    if (!relentless)

+                        break;

+                }

+            }

+            //

+            // save the details of the object file compilation

+            // settings to disk for dependency analysis

+            //

+            try {

+                objHistory.commit();

+            } catch (IOException ex) {

+                this.log("Error writing history.xml: " + ex.toString());

+            }

+            //

+            // if we threw a compile exception and

+            // didn't throw it at the time because

+            // we were relentless then

+            // save the history and

+            // throw the exception

+            //

+            if (compileException != null) {

+                if (failOnError) {

+                    throw compileException;

+                } else {

+                    log(compileException.getMessage(), Project.MSG_ERR);

+                    return;

+                }

+            }

+        }

+        //

+        // if the dependency tree was not fully

+        // evaluated, then throw an exception

+        // since we really didn't do what we

+        // should have done

+        //

+        //

+        if (dependencyDepth >= 0) {

+            throw new BuildException(

+                            "All files at depth "

+                                            + Integer.toString(dependencyDepth)

+                                            + " from changes successfully compiled.\n"

+                                            + "Remove or change dependencyDepth to -1 to perform full compilation.");

+        }

+        //

+        // if no link target then

+        // commit the history for the object files

+        // and leave the task

+        if (linkTarget != null) {

+            //

+            // get the history for the link target (may be the same

+            // as the object history)

+            TargetHistoryTable linkHistory = getLinkHistory(objHistory);

+            //

+            // see if it needs to be rebuilt

+            //

+            linkHistory.markForRebuild(linkTarget);

+            //

+            // if it needs to be rebuilt, rebuild it

+            //

+            File output = linkTarget.getOutput();

+            if (linkTarget.getRebuild()) {

+                log("Starting link");

+                LinkerConfiguration linkConfig = (LinkerConfiguration) linkTarget

+                                .getConfiguration();

+                if (failOnError) {

+                    linkConfig.link(this, linkTarget);

+                } else {

+                    try {

+                        linkConfig.link(this, linkTarget);

+                    } catch (BuildException ex) {

+                        log(ex.getMessage(), Project.MSG_ERR);

+                        return;

+                    }

+                }

+                if (outputFileProperty != null)

+                    getProject().setProperty(outputFileProperty,

+                                    output.getAbsolutePath());

+                linkHistory.update(linkTarget);

+                try {

+                    linkHistory.commit();

+                } catch (IOException ex) {

+                    log("Error writing link history.xml: " + ex.toString());

+                }

+            } else {

+                if (outputFileProperty != null)

+                    getProject().setProperty(outputFileProperty,

+                                    output.getAbsolutePath());

+            }

+        }

+    }

+

+    /**

+     * Gets the dataset.

+     * 

+     * @return Returns a String

+     */

+    public String getDataset() {

+        return dataset;

+    }

+

+    protected TargetHistoryTable getLinkHistory(TargetHistoryTable objHistory) {

+        File outputFileDir = new File(_outfile.getParent());

+        //

+        // if the output file is being produced in the link

+        // directory, then we can use the same history file

+        //

+        if (_objDir.equals(outputFileDir)) {

+            return objHistory;

+        }

+        return new TargetHistoryTable(this, outputFileDir);

+    }

+

+    protected TargetInfo getLinkTarget(LinkerConfiguration linkerConfig,

+                    Vector objectFiles, Vector sysObjectFiles,

+                    Hashtable compileTargets, Hashtable assemblerTargets) {

+        //

+        // walk the compile phase targets and

+        // add those sources that have already been

+        // assigned to the linker or

+        // our output files the linker knows how to consume

+        // files the linker knows how to consume

+        //

+        Enumeration compileTargetsEnum = compileTargets.elements();

+        while (compileTargetsEnum.hasMoreElements()) {

+            TargetInfo compileTarget = (TargetInfo) compileTargetsEnum

+                            .nextElement();

+            //

+            // output of compile tasks

+            //

+            int bid = linkerConfig.bid(compileTarget.getOutput().toString());

+            if (bid > 0) {

+                objectFiles.addElement(compileTarget.getOutput());

+            }

+        }

+        //

+        // walk the assembler phase targets and

+        // add those sources that have already been

+        // assigned to the linker or

+        // our output files the linker knows how to consume

+        // files the linker knows how to consume

+        //

+        Enumeration assembleTargetsEnum = assemblerTargets.elements();

+        while (assembleTargetsEnum.hasMoreElements()) {

+            TargetInfo assemblerTarget = (TargetInfo) assembleTargetsEnum

+                            .nextElement();

+            //

+            // output of assemble tasks

+            //

+            int bid = linkerConfig.bid(assemblerTarget.getOutput().toString());

+            if (bid > 0) {

+                objectFiles.addElement(assemblerTarget.getOutput());

+            }

+        }

+        File[] objectFileArray = new File[objectFiles.size()];

+        objectFiles.copyInto(objectFileArray);

+        File[] sysObjectFileArray = new File[sysObjectFiles.size()];

+        sysObjectFiles.copyInto(sysObjectFileArray);

+        String baseName = _outfile.getName();

+        String fullName = linkerConfig.getOutputFileName(baseName);

+        File outputFile = new File(_outfile.getParent(), fullName);

+        return new TargetInfo(linkerConfig, objectFileArray,

+                        sysObjectFileArray, outputFile, linkerConfig

+                                        .getRebuild());

+    }

+

+    public File getObjdir() {

+        return _objDir;

+    }

+

+    public File getOutfile() {

+        return _outfile;

+    }

+

+    public TargetDef getTargetPlatform() {

+        return null;

+    }

+

+    /**

+     * This method collects a Hashtable, keyed by output file name, of

+     * TargetInfo's for every source file that is specified in the filesets of

+     * the <aslcompiler> elements. The TargetInfo's contain the appropriate ACPI

+     * configurations for their possible acpi

+     * 

+     */

+    private Hashtable getAcpiTargets(LinkerConfiguration linkerConfig,

+                    Vector objectFiles) {

+        Hashtable targets = new Hashtable(1000);

+        TargetDef targetPlatform = getTargetPlatform();

+        Vector biddingProcessors = new Vector(_aslcompiler.size());

+        for (int i = 0; i < _aslcompiler.size(); i++) {

+            AslcompilerDef currentAslDef = (AslcompilerDef) _aslcompiler

+                            .elementAt(i);

+            if (currentAslDef.isActive()) {

+                ProcessorConfiguration config = currentAslDef

+                                .createConfiguration(this, linkType,

+                                                aslcompilerDef, targetPlatform);

+                //

+                // if the aslcompiler has a fileset

+                // then allow it to add its files to

+                // the set of potential targets

+                //

+                ProcessorConfiguration[] localConfigs = new ProcessorConfiguration[] { config };

+                if (currentAslDef.hasFileSets()) {

+                    TargetMatcher matcher = new TargetMatcher(this, _objDir,

+                                    localConfigs, linkerConfig, objectFiles,

+                                    targets);

+                    currentAslDef.visitFiles(matcher);

+                }

+                biddingProcessors.addElement(config);

+            }

+        }

+        //

+        // add fallback compiler at the end

+        //

+        ProcessorConfiguration config = aslcompilerDef.createConfiguration(

+                        this, linkType, null, targetPlatform);

+        biddingProcessors.addElement(config);

+        ProcessorConfiguration[] bidders = new ProcessorConfiguration[biddingProcessors

+                        .size()];

+        biddingProcessors.copyInto(bidders);

+        TargetMatcher matcher = new TargetMatcher(this, _objDir, bidders,

+                        linkerConfig, objectFiles, targets);

+        aslcompilerDef.visitFiles(matcher);

+        return targets;

+    }

+

+    /**

+     * This method collects a Hashtable, keyed by output file name, of

+     * TargetInfo's for every source file that is specified in the filesets of

+     * the <assembler> elements. The TargetInfo's contain the appropriate

+     * assembler configurations for their possible assembly

+     * 

+     */

+    private Hashtable getAssemblerTargets(LinkerConfiguration linkerConfig,

+                    Vector objectFiles) {

+        Hashtable targets = new Hashtable(1000);

+        TargetDef targetPlatform = getTargetPlatform();

+        Vector biddingProcessors = new Vector(_assemblers.size());

+        for (int i = 0; i < _assemblers.size(); i++) {

+            AssemblerDef currentAssemblerDef = (AssemblerDef) _assemblers

+                            .elementAt(i);

+            if (currentAssemblerDef.isActive()) {

+                ProcessorConfiguration config = currentAssemblerDef

+                                .createConfiguration(this, linkType,

+                                                assemblerDef, targetPlatform);

+                //

+                // if the assembler has a fileset

+                // then allow it to add its files to

+                // the set of potential targets

+                //

+                ProcessorConfiguration[] localConfigs = new ProcessorConfiguration[] { config };

+                if (currentAssemblerDef.hasFileSets()) {

+                    TargetMatcher matcher = new TargetMatcher(this, _objDir,

+                                    localConfigs, linkerConfig, objectFiles,

+                                    targets);

+                    currentAssemblerDef.visitFiles(matcher);

+                }

+                biddingProcessors.addElement(config);

+            }

+        }

+        //

+        // add fallback assembler at the end

+        //

+        ProcessorConfiguration config = assemblerDef.createConfiguration(this,

+                        linkType, null, targetPlatform);

+        biddingProcessors.addElement(config);

+        ProcessorConfiguration[] bidders = new ProcessorConfiguration[biddingProcessors

+                        .size()];

+        biddingProcessors.copyInto(bidders);

+        TargetMatcher matcher = new TargetMatcher(this, _objDir, bidders,

+                        linkerConfig, objectFiles, targets);

+        assemblerDef.visitFiles(matcher);

+        return targets;

+    }

+

+    /**

+     * This method collects a Hashtable, keyed by output file name, of

+     * TargetInfo's for every source file that is specified in the filesets of

+     * the <cc>and nested <compiler>elements. The TargetInfo's contain the

+     * appropriate compiler configurations for their possible compilation

+     * 

+     */

+    private Hashtable getTargets(LinkerConfiguration linkerConfig,

+                    Vector objectFiles) {

+        Hashtable targets = new Hashtable(1000);

+        TargetDef targetPlatform = getTargetPlatform();

+        //

+        // find active (specialized) compilers

+        //

+        Vector biddingProcessors = new Vector(_compilers.size());

+        for (int i = 0; i < _compilers.size(); i++) {

+            CompilerDef currentCompilerDef = (CompilerDef) _compilers

+                            .elementAt(i);

+            if (currentCompilerDef.isActive()) {

+                ProcessorConfiguration config = currentCompilerDef

+                                .createConfiguration(this, linkType,

+                                                compilerDef, targetPlatform);

+                //

+                // see if this processor had a precompile child element

+                //

+                PrecompileDef precompileDef = currentCompilerDef

+                                .getActivePrecompile(compilerDef);

+                ProcessorConfiguration[] localConfigs = new ProcessorConfiguration[] { config };

+                //

+                // if it does then

+                //

+                if (precompileDef != null) {

+                    File prototype = precompileDef.getPrototype();

+                    //

+                    // will throw exceptions if prototype doesn't exist, etc

+                    //

+                    if (!prototype.exists()) {

+                        throw new BuildException("prototype ("

+                                        + prototype.toString()

+                                        + ") does not exist.");

+                    }

+                    if (prototype.isDirectory()) {

+                        throw new BuildException("prototype ("

+                                        + prototype.toString()

+                                        + ") is a directory.");

+                    }

+                    String[] exceptFiles = precompileDef.getExceptFiles();

+                    //

+                    // create a precompile building and precompile using

+                    // variants of the configuration

+                    // or return null if compiler doesn't support

+                    // precompilation

+                    CompilerConfiguration[] configs = ((CompilerConfiguration) config)

+                                    .createPrecompileConfigurations(prototype,

+                                                    exceptFiles);

+                    if (configs != null && configs.length == 2) {

+                        //

+                        // visit the precompiled file to add it into the

+                        // targets list (just like any other file if

+                        // compiler doesn't support precompilation)

+                        TargetMatcher matcher = new TargetMatcher(

+                                        this,

+                                        _objDir,

+                                        new ProcessorConfiguration[] { configs[0] },

+                                        linkerConfig, objectFiles, targets);

+                        matcher.visit(new File(prototype.getParent()),

+                                        prototype.getName());

+                        //

+                        // only the configuration that uses the

+                        // precompiled header gets added to the bidding list

+                        biddingProcessors.addElement(configs[1]);

+                        localConfigs = new ProcessorConfiguration[2];

+                        localConfigs[0] = configs[1];

+                        localConfigs[1] = config;

+                    }

+                }

+                //

+                // if the compiler has a fileset

+                // then allow it to add its files

+                // to the set of potential targets

+                if (currentCompilerDef.hasFileSets()) {

+                    TargetMatcher matcher = new TargetMatcher(this, _objDir,

+                                    localConfigs, linkerConfig, objectFiles,

+                                    targets);

+                    currentCompilerDef.visitFiles(matcher);

+                }

+                biddingProcessors.addElement(config);

+            }

+        }

+        //

+        // add fallback compiler at the end

+        //

+        ProcessorConfiguration config = compilerDef.createConfiguration(this,

+                        linkType, null, targetPlatform);

+        biddingProcessors.addElement(config);

+        ProcessorConfiguration[] bidders = new ProcessorConfiguration[biddingProcessors

+                        .size()];

+        biddingProcessors.copyInto(bidders);

+        //

+        // bid out the <fileset>'s in the cctask

+        //

+        TargetMatcher matcher = new TargetMatcher(this, _objDir, bidders,

+                        linkerConfig, objectFiles, targets);

+        compilerDef.visitFiles(matcher);

+        return targets;

+    }

+

+    /**

+     * Sets the default compiler adapter. Use the "name" attribute when the

+     * compiler is a supported compiler.

+     * 

+     * @param classname

+     *            fully qualified classname which implements CompilerAdapter

+     */

+    public void setClassname(String classname) {

+        compilerDef.setClassname(classname);

+        linkerDef.setClassname(classname);

+        assemblerDef.setClassname(classname);

+        aslcompilerDef.setClassname(classname);

+    }

+

+    /**

+     * Sets the dataset for OS/390 builds.

+     * 

+     * @param dataset

+     *            The dataset to set

+     */

+    public void setDataset(String dataset) {

+        this.dataset = dataset;

+    }

+

+    /**

+     * Enables or disables generation of debug info.

+     */

+    public void setDebug(boolean debug) {

+        compilerDef.setDebug(debug);

+        linkerDef.setDebug(debug);

+        assemblerDef.setDebug(debug);

+        aslcompilerDef.setDebug(debug);

+    }

+

+    /**

+     * Deprecated.

+     * 

+     * Controls the depth of the dependency evaluation. Used to do a quick check

+     * of changes before a full build.

+     * 

+     * Any negative value which will perform full dependency checking. Positive

+     * values will truncate dependency checking. A value of 0 will cause only

+     * those files that changed to be recompiled, a value of 1 which cause files

+     * that changed or that explicitly include a file that changed to be

+     * recompiled.

+     * 

+     * Any non-negative value will cause a BuildException to be thrown before

+     * attempting a link or completing the task.

+     * 

+     */

+    public void setDependencyDepth(int depth) {

+        dependencyDepth = depth;

+    }

+

+    /**

+     * Enables generation of exception handling code

+     */

+    public void setExceptions(boolean exceptions) {

+        compilerDef.setExceptions(exceptions);

+    }

+

+    /**

+     * Enables run-time type information.

+     */

+    public void setRtti(boolean rtti) {

+        compilerDef.setRtti(rtti);

+    }

+

+    // public LinkType getLinkType() {

+    // return linkType;

+    // }

+    /**

+     * Enables or disables incremental linking.

+     * 

+     * @param incremental

+     *            new state

+     */

+    public void setIncremental(boolean incremental) {

+        linkerDef.setIncremental(incremental);

+    }

+

+    /**

+     * Set use of libtool.

+     * 

+     * If set to true, the "libtool " will be prepended to the command line for

+     * compatible processors

+     * 

+     * @param libtool

+     *            If true, use libtool.

+     */

+    public void setLibtool(boolean libtool) {

+        compilerDef.setLibtool(libtool);

+        linkerDef.setLibtool(libtool);

+        assemblerDef.setLibtool(libtool);

+        aslcompilerDef.setLibtool(libtool);

+    }

+

+    /**

+     * Sets the output file type. Supported values "executable", "shared", and

+     * "static". Deprecated, specify outtype instead.

+     * 

+     * @deprecated

+     */

+    public void setLink(OutputTypeEnum outputType) {

+        linkType.setOutputType(outputType);

+    }

+

+    /**

+     * Enables or disables generation of multithreaded code

+     * 

+     * @param multi

+     *            If true, generated code may be multithreaded.

+     */

+    public void setMultithreaded(boolean multi) {

+        compilerDef.setMultithreaded(multi);

+    }

+

+    //

+    // keep near duplicate comment at CompilerDef.setName in sync

+    //

+    /**

+     * Sets type of the default compiler and linker.

+     * 

+     * <table width="100%" border="1"> <thead>Supported compilers </thead>

+     * <tr>

+     * <td>gcc (default)</td>

+     * <td>GCC C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>g++</td>

+     * <td>GCC C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>c++</td>

+     * <td>GCC C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>g77</td>

+     * <td>GNU FORTRAN compiler</td>

+     * </tr>

+     * <tr>

+     * <td>msvc</td>

+     * <td>Microsoft Visual C++</td>

+     * </tr>

+     * <tr>

+     * <td>bcc</td>

+     * <td>Borland C++ Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>msrc</td>

+     * <td>Microsoft Resource Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>brc</td>

+     * <td>Borland Resource Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>df</td>

+     * <td>Compaq Visual Fortran Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>midl</td>

+     * <td>Microsoft MIDL Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>icl</td>

+     * <td>Intel C++ compiler for Windows (IA-32)</td>

+     * </tr>

+     * <tr>

+     * <td>ecl</td>

+     * <td>Intel C++ compiler for Windows (IA-64)</td>

+     * </tr>

+     * <tr>

+     * <td>icc</td>

+     * <td>Intel C++ compiler for Linux (IA-32)</td>

+     * </tr>

+     * <tr>

+     * <td>ecc</td>

+     * <td>Intel C++ compiler for Linux (IA-64)</td>

+     * </tr>

+     * <tr>

+     * <td>CC</td>

+     * <td>Sun ONE C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>aCC</td>

+     * <td>HP aC++ C++ Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>os390</td>

+     * <td>OS390 C Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>os400</td>

+     * <td>Icc Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>sunc89</td>

+     * <td>Sun C89 C Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>xlC</td>

+     * <td>VisualAge C Compiler</td>

+     * </tr>

+     * </table>

+     * 

+     */

+    public void setName(CompilerEnum name) {

+        compilerDef.setName(name);

+        Processor compiler = compilerDef.getProcessor();

+        Linker linker = compiler.getLinker(linkType);

+        linkerDef.setProcessor(linker);

+    }

+

+    /**

+     * Do not propagate old environment when new environment variables are

+     * specified.

+     */

+    public void setNewenvironment(boolean newenv) {

+        compilerDef.setNewenvironment(newenv);

+        linkerDef.setNewenvironment(newenv);

+        assemblerDef.setNewenvironment(newenv);

+        aslcompilerDef.setNewenvironment(newenv);

+    }

+

+    /**

+     * Sets the destination directory for object files.

+     * 

+     * Generally this should be a property expression that evaluates to distinct

+     * debug and release object file directories.

+     * 

+     * @param dir

+     *            object directory

+     */

+    public void setObjdir(File dir) {

+        if (dir == null) {

+            throw new NullPointerException("dir");

+        }

+        _objDir = dir;

+    }

+

+    /**

+     * Sets the output file name. If not specified, the task will only compile

+     * files and not attempt to link. If an extension is not specified, the task

+     * may use a system appropriate extension and prefix, for example,

+     * outfile="example" may result in "libexample.so" being created.

+     * 

+     * @param outfile

+     *            output file name

+     */

+    public void setOutfile(File outfile) {

+        //

+        // if file name was empty, skip link step

+        //

+        if (outfile == null || outfile.toString().length() > 0) {

+            _outfile = outfile;

+        }

+    }

+

+    /**

+     * Specifies the name of a property to set with the physical filename that

+     * is produced by the linker

+     */

+    public void setOutputFileProperty(String outputFileProperty) {

+        this.outputFileProperty = outputFileProperty;

+    }

+

+    /**

+     * Sets the output file type. Supported values "executable", "shared", and

+     * "static".

+     */

+    public void setOuttype(OutputTypeEnum outputType) {

+        linkType.setOutputType(outputType);

+    }

+

+    /**

+     * Sets the project.

+     */

+    public void setProject(Project project) {

+        super.setProject(project);

+        compilerDef.setProject(project);

+        linkerDef.setProject(project);

+        assemblerDef.setProject(project);

+        aslcompilerDef.setProject(project);

+    }

+

+    /**

+     * If set to true, all files will be rebuilt.

+     * 

+     * @paran rebuildAll If true, all files will be rebuilt. If false, up to

+     *        date files will not be rebuilt.

+     */

+    public void setRebuild(boolean rebuildAll) {

+        compilerDef.setRebuild(rebuildAll);

+        linkerDef.setRebuild(rebuildAll);

+        assemblerDef.setRebuild(rebuildAll);

+        aslcompilerDef.setRebuild(rebuildAll);

+    }

+

+    /**

+     * If set to true, compilation errors will not stop the task until all files

+     * have been attempted.

+     * 

+     * @param relentless

+     *            If true, don't stop on the first compilation error

+     * 

+     */

+    public void setRelentless(boolean relentless) {

+        this.relentless = relentless;

+    }

+

+    /**

+     * Sets the type of runtime library, possible values "dynamic", "static".

+     */

+    public void setRuntime(RuntimeType rtlType) {

+        linkType.setStaticRuntime((rtlType.getIndex() == 1));

+    }

+

+    /**

+     * Sets the nature of the subsystem under which that the program will

+     * execute.

+     * 

+     * <table width="100%" border="1"> <thead>Supported subsystems </thead>

+     * <tr>

+     * <td>gui</td>

+     * <td>Graphical User Interface</td>

+     * </tr>

+     * <tr>

+     * <td>console</td>

+     * <td>Command Line Console</td>

+     * </tr>

+     * <tr>

+     * <td>other</td>

+     * <td>Other</td>

+     * </tr>

+     * </table>

+     * 

+     * @param subsystem

+     *            subsystem

+     * @throws NullPointerException

+     *             if subsystem is null

+     */

+    public void setSubsystem(SubsystemEnum subsystem) {

+        if (subsystem == null) {

+            throw new NullPointerException("subsystem");

+        }

+        linkType.setSubsystem(subsystem);

+    }

+

+    /**

+     * Enumerated attribute with the values "none", "severe", "default",

+     * "production", "diagnostic", and "failtask".

+     */

+    public void setWarnings(CompilerDef.WarningLevel level) {

+        compilerDef.setWarnings(level);

+    }

+

+    /**

+     * Indicates whether the build will continue even if there are compilation

+     * errors; defaults to true.

+     * 

+     * @param fail

+     *            if true halt the build on failure

+     */

+    public void setFailonerror(boolean fail) {

+        failOnError = fail;

+    }

+

+    /**

+     * Gets the failonerror flag.

+     * 

+     * @return the failonerror flag

+     */

+    public boolean getFailonerror() {

+        return failOnError;

+    }

+

+    /**

+     * Adds descriptive version information to be included in the generated

+     * file. The first active version info block will be used. (Non-functional

+     * prototype)

+     */

+    public void addConfiguredVersioninfo(VersionInfo info) {

+        linkerDef.addConfiguredVersioninfo(info);

+    }

+

+    /**

+     * Adds a target definition or reference (Non-functional prototype).

+     * 

+     * @param target

+     *            target

+     * @throws NullPointerException

+     *             if compiler is null

+     */

+    public void addConfiguredTarget(TargetDef target) {

+        if (target == null) {

+            throw new NullPointerException("target");

+        }

+        target.setProject(getProject());

+        targetPlatforms.addElement(target);

+    }

+

+    /**

+     * Adds a distributer definition or reference (Non-functional prototype).

+     * 

+     * @param distributer

+     *            distributer

+     * @throws NullPointerException

+     *             if compiler is null

+     */

+    public void addConfiguredDistributer(DistributerDef distributer) {

+        if (distributer == null) {

+            throw new NullPointerException("distributer");

+        }

+        distributer.setProject(getProject());

+        distributers.addElement(distributer);

+    }

+

+    /**

+     * Sets optimization.

+     * @param optimization

+     */

+    public void setOptimize(OptimizationEnum optimization) {

+        compilerDef.setOptimize(optimization);

+    }

+

+    public boolean isAssembler() {

+        return assembler;

+    }

+

+    public void setAssembler(boolean assembler) {

+        this.assembler = assembler;

+    }

+

+    public boolean isAslcompiler() {

+        return aslcompiler;

+    }

+

+    public void setAslcompiler(boolean aslcompiler) {

+        this.aslcompiler = aslcompiler;

+    }

+

+    public boolean isUserdefine() {

+        return userdefine;

+    }

+

+    public void setUserdefine(boolean userdefine) {

+        this.userdefine = userdefine;

+    }

+

+    public String getArch() {

+        return arch;

+    }

+

+    public void setArch(String arch) {

+        this.arch = arch;

+    }

+

+    public String getOs() {

+        return os;

+    }

+

+    public void setOs(String os) {

+        this.os = os;

+    }

+

+    public String getVendor() {

+        return vendor;

+    }

+

+    public void setVendor(String vendor) {

+        this.vendor = vendor;

+    }

+    

+    

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java
new file mode 100644
index 0000000..78192a5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CCTaskProgressMonitor.java
@@ -0,0 +1,56 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.IOException;

+

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;

+public class CCTaskProgressMonitor implements ProgressMonitor {

+    private ProcessorConfiguration config;

+    private TargetHistoryTable history;

+    private long lastCommit = -1;

+    public CCTaskProgressMonitor(TargetHistoryTable history) {

+        this.history = history;

+    }

+    public void finish(ProcessorConfiguration config, boolean normal) {

+        long current = System.currentTimeMillis();

+        if ((current - lastCommit) > 120000) {

+            try {

+                history.commit();

+                lastCommit = System.currentTimeMillis();

+            } catch (IOException ex) {

+            }

+        }

+    }

+    public void progress(String[] sources) {

+        history.update(config, sources);

+        long current = System.currentTimeMillis();

+        if ((current - lastCommit) > 120000) {

+            try {

+                history.commit();

+                lastCommit = current;

+            } catch (IOException ex) {

+            }

+        }

+    }

+    public void start(ProcessorConfiguration config) {

+        if (lastCommit < 0) {

+            lastCommit = System.currentTimeMillis();

+        }

+        this.config = config;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CPUEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CPUEnum.java
new file mode 100644
index 0000000..ba73902
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CPUEnum.java
@@ -0,0 +1,71 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Enumeration of cpu types.

+ *

+ * @author Curt Arnold

+ *

+ */

+public final class CPUEnum

+    extends EnumeratedAttribute {

+

+  /**

+   * Constructor.

+   *

+   * Set by default to "pentium3"

+   *

+   * @see java.lang.Object#Object()

+   */

+  public CPUEnum() {

+    setValue("pentium3");

+  }

+

+  /**

+   * Gets list of acceptable values.

+   *

+   * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+   */

+  public String[] getValues() {

+    return new String[] {

+        "i386",

+        "i486",

+        "i586",

+        "i686",

+        "pentium",

+        "pentium-mmx",

+        "pentiumpro",

+        "pentium2",

+        "pentium3",

+        "pentium4",

+        "k6",

+        "k6-2",

+        "k6-3",

+        "athlon",

+        "athlon-tbird",

+        "athlon-4",

+        "athlon-xp",

+        "athlon-mp",

+        "winchip-c6",

+        "winchip2",

+        "c3" };

+  }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CUtil.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CUtil.java
new file mode 100644
index 0000000..074e8b4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CUtil.java
@@ -0,0 +1,461 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+import java.io.IOException;

+import java.util.Enumeration;

+import java.util.Hashtable;

+import java.util.StringTokenizer;

+import java.util.Vector;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+import org.apache.tools.ant.types.Environment;

+/**

+ * Some utilities used by the CC and Link tasks.

+ * 

+ * @author Adam Murdoch

+ */

+public class CUtil {

+    /**

+     * A class that splits a white-space, comma-separated list into a String

+     * array. Used for task attributes.

+     */

+    public static final class StringArrayBuilder {

+        private String[] _value;

+        public StringArrayBuilder(String value) {

+            // Split the defines up

+            StringTokenizer tokens = new StringTokenizer(value, ", ");

+            Vector vallist = new Vector();

+            while (tokens.hasMoreTokens()) {

+                String val = tokens.nextToken().trim();

+                if (val.length() == 0) {

+                    continue;

+                }

+                vallist.addElement(val);

+            }

+            _value = new String[vallist.size()];

+            vallist.copyInto(_value);

+        }

+        public String[] getValue() {

+            return _value;

+        }

+    }

+    /**

+     * Adds the elements of the array to the given vector

+     */

+    public static void addAll(Vector dest, Object[] src) {

+        if (src == null) {

+            return;

+        }

+        for (int i = 0; i < src.length; i++) {

+            dest.addElement(src[i]);

+        }

+    }

+    /**

+     * Checks a array of names for non existent or non directory entries and

+     * nulls them out.

+     * 

+     * @return Count of non-null elements

+     */

+    public static int checkDirectoryArray(String[] names) {

+        int count = 0;

+        for (int i = 0; i < names.length; i++) {

+            if (names[i] != null) {

+                File dir = new File(names[i]);

+                if (dir.exists() && dir.isDirectory()) {

+                    count++;

+                } else {

+                    names[i] = null;

+                }

+            }

+        }

+        return count;

+    }

+    /**

+     * Extracts the basename of a file, removing the extension, if present

+     */

+    public static String getBasename(File file) {

+        String path = file.getPath();

+        // Remove the extension

+        String basename = file.getName();

+        int pos = basename.lastIndexOf('.');

+        if (pos != -1) {

+            basename = basename.substring(0, pos);

+        }

+        return basename;

+    }

+    /**

+     * Gets the parent directory for the executable file name using the current

+     * directory and system executable path

+     * 

+     * @param exeName

+     *            Name of executable such as "cl.exe"

+     * @return parent directory or null if not located

+     */

+    public static File getExecutableLocation(String exeName) {

+        //

+        //   must add current working directory to the

+        //      from of the path from the "path" environment variable

+        File currentDir = new File(System.getProperty("user.dir"));

+        if (new File(currentDir, exeName).exists()) {

+            return currentDir;

+        }

+        File[] envPath = CUtil.getPathFromEnvironment("PATH",

+                File.pathSeparator);

+        for (int i = 0; i < envPath.length; i++) {

+            if (new File(envPath[i], exeName).exists()) {

+                return envPath[i];

+            }

+        }

+        return null;

+    }

+    /**

+     * Extracts the parent of a file

+     */

+    public static String getParentPath(String path) {

+        int pos = path.lastIndexOf(File.separator);

+        if (pos <= 0) {

+            return null;

+        }

+        return path.substring(0, pos);

+    }

+    /**

+     * Returns an array of File for each existing directory in the specified

+     * environment variable

+     * 

+     * @param envVariable

+     *            environment variable name such as "LIB" or "INCLUDE"

+     * @param delim

+     *            delimitor used to separate parts of the path, typically ";"

+     *            or ":"

+     * @return array of File's for each part that is an existing directory

+     */

+    public static File[] getPathFromEnvironment(String envVariable, String delim) {

+        // OS/4000 does not support the env command.

+        if (System.getProperty("os.name").equals("OS/400"))

+            return new File[]{};

+        Vector osEnv = Execute.getProcEnvironment();

+        String match = envVariable.concat("=");

+        for (Enumeration e = osEnv.elements(); e.hasMoreElements();) {

+            String entry = ((String) e.nextElement()).trim();

+            if (entry.length() > match.length()) {

+                String entryFrag = entry.substring(0, match.length());

+                if (entryFrag.equalsIgnoreCase(match)) {

+                    String path = entry.substring(match.length());

+                    return parsePath(path, delim);

+                }

+            }

+        }

+        File[] noPath = new File[0];

+        return noPath;

+    }

+    /**

+     * Returns a relative path for the targetFile relative to the base

+     * directory.

+     * 

+     * @param canonicalBase

+     *            base directory as returned by File.getCanonicalPath()

+     * @param targetFile

+     *            target file

+     * @return relative path of target file. Returns targetFile if there were

+     *         no commonalities between the base and the target

+     * 

+     * @author Curt Arnold

+     */

+    public static String getRelativePath(String base, File targetFile) {

+        try {

+            //

+            //   remove trailing file separator

+            //

+            String canonicalBase = base;

+            if (base.charAt(base.length() - 1) == File.separatorChar) {

+                canonicalBase = base.substring(0, base.length() - 1);

+            }

+            //

+            //   get canonical name of target and remove trailing separator

+            //

+            String canonicalTarget;

+            if (System.getProperty("os.name").equals("OS/400"))

+                canonicalTarget = targetFile.getPath();

+            else

+                canonicalTarget = targetFile.getCanonicalPath();

+            if (canonicalTarget.charAt(canonicalTarget.length() - 1) == File.separatorChar) {

+                canonicalTarget = canonicalTarget.substring(0, canonicalTarget

+                        .length() - 1);

+            }

+            if (canonicalTarget.equals(canonicalBase)) {

+                return ".";

+            }

+            //

+            //  see if the prefixes are the same

+            //

+            if (canonicalBase.substring(0, 2).equals("\\\\")) {

+                //

+                //  UNC file name, if target file doesn't also start with same

+                //      server name, don't go there

+                int endPrefix = canonicalBase.indexOf('\\', 2);

+                String prefix1 = canonicalBase.substring(0, endPrefix);

+                String prefix2 = canonicalTarget.substring(0, endPrefix);

+                if (!prefix1.equals(prefix2)) {

+                    return canonicalTarget;

+                }

+            } else {

+                if (canonicalBase.substring(1, 3).equals(":\\")) {

+                    int endPrefix = 2;

+                    String prefix1 = canonicalBase.substring(0, endPrefix);

+                    String prefix2 = canonicalTarget.substring(0, endPrefix);

+                    if (!prefix1.equals(prefix2)) {

+                        return canonicalTarget;

+                    }

+                } else {

+                    if (canonicalBase.charAt(0) == '/') {

+                        if (canonicalTarget.charAt(0) != '/') {

+                            return canonicalTarget;

+                        }

+                    }

+                }

+            }

+            char separator = File.separatorChar;

+            int lastSeparator = -1;

+            int minLength = canonicalBase.length();

+            if (canonicalTarget.length() < minLength) {

+                minLength = canonicalTarget.length();

+            }

+            int firstDifference = minLength + 1;

+            //

+            //  walk to the shorter of the two paths

+            //      finding the last separator they have in common

+            for (int i = 0; i < minLength; i++) {

+                if (canonicalTarget.charAt(i) == canonicalBase.charAt(i)) {

+                    if (canonicalTarget.charAt(i) == separator) {

+                        lastSeparator = i;

+                    }

+                } else {

+                    firstDifference = lastSeparator + 1;

+                    break;

+                }

+            }

+            StringBuffer relativePath = new StringBuffer(50);

+            //

+            //   walk from the first difference to the end of the base

+            //      adding "../" for each separator encountered

+            //

+            if (canonicalBase.length() > firstDifference) {

+                relativePath.append("..");

+                for (int i = firstDifference; i < canonicalBase.length(); i++) {

+                    if (canonicalBase.charAt(i) == separator) {

+                        relativePath.append(separator);

+                        relativePath.append("..");

+                    }

+                }

+            }

+            if (canonicalTarget.length() > firstDifference) {

+                //

+                //    append the rest of the target

+                //

+                //

+                if (relativePath.length() > 0) {

+                    relativePath.append(separator);

+                }

+                relativePath.append(canonicalTarget.substring(firstDifference));

+            }

+            return relativePath.toString();

+        } catch (IOException ex) {

+        }

+        return targetFile.toString();

+    }

+    public static boolean isActive(Project p, String ifCond, String unlessCond)

+            throws BuildException {

+        if (ifCond != null) {

+            String ifValue = p.getProperty(ifCond);

+            if (ifValue == null) {

+                return false;

+            } else {

+                if (ifValue.equals("false") || ifValue.equals("no")) {

+                    throw new BuildException("if condition \"" + ifCond

+                            + "\" has suspicious value \"" + ifValue);

+                }

+            }

+        }

+        if (unlessCond != null) {

+            String unlessValue = p.getProperty(unlessCond);

+            if (unlessValue != null) {

+                if (unlessValue.equals("false") || unlessValue.equals("no")) {

+                    throw new BuildException("unless condition \"" + unlessCond

+                            + "\" has suspicious value \"" + unlessValue);

+                }

+                return false;

+            }

+        }

+        return true;

+    }

+    /**

+     * Parse a string containing directories into an File[]

+     * 

+     * @param path

+     *            path string, for example ".;c:\something\include"

+     * @param delim

+     *            delimiter, typically ; or :

+     */

+    public static File[] parsePath(String path, String delim) {

+        Vector libpaths = new Vector();

+        int delimPos = 0;

+        for (int startPos = 0; startPos < path.length(); startPos = delimPos

+                + delim.length()) {

+            delimPos = path.indexOf(delim, startPos);

+            if (delimPos < 0) {

+                delimPos = path.length();

+            }

+            //

+            //   don't add an entry for zero-length paths

+            //

+            if (delimPos > startPos) {

+                String dirName = path.substring(startPos, delimPos);

+                File dir = new File(dirName);

+                if (dir.exists() && dir.isDirectory()) {

+                    libpaths.addElement(dir);

+                }

+            }

+        }

+        File[] paths = new File[libpaths.size()];

+        libpaths.copyInto(paths);

+        return paths;

+    }

+    /**

+     * This method is exposed so test classes can overload and test the

+     * arguments without actually spawning the compiler

+     */

+    public static int runCommand(CCTask task, File workingDir,

+            String[] cmdline, boolean newEnvironment, Environment env)

+            throws BuildException {

+        try {

+            task.log(Commandline.toString(cmdline), Project.MSG_VERBOSE);

+            Execute exe = new Execute(new LogStreamHandler(task,

+                    Project.MSG_INFO, Project.MSG_ERR));

+            if (System.getProperty("os.name").equals("OS/390"))

+                exe.setVMLauncher(false);

+            exe.setAntRun(task.getProject());

+            exe.setCommandline(cmdline);

+            exe.setWorkingDirectory(workingDir);

+            if (env != null) {

+                String[] environment = env.getVariables();

+                if (environment != null) {

+                    for (int i = 0; i < environment.length; i++) {

+                        task.log("Setting environment variable: "

+                                + environment[i], Project.MSG_VERBOSE);

+                    }

+                }

+                exe.setEnvironment(environment);

+            }

+            exe.setNewenvironment(newEnvironment);

+            return exe.execute();

+        } catch (java.io.IOException exc) {

+            throw new BuildException("Could not launch " + cmdline[0] + ": "

+                    + exc, task.getLocation());

+        }

+    }

+    /**

+     * Compares the contents of 2 arrays for equaliy.

+     */

+    public static boolean sameList(Object[] a, Object[] b) {

+        if (a == null || b == null || a.length != b.length) {

+            return false;

+        }

+        for (int i = 0; i < a.length; i++) {

+            if (!a[i].equals(b[i])) {

+                return false;

+            }

+        }

+        return true;

+    }

+    /**

+     * Compares the contents of an array and a Vector for equality.

+     */

+    public static boolean sameList(Vector v, Object[] a) {

+        if (v == null || a == null || v.size() != a.length) {

+            return false;

+        }

+        for (int i = 0; i < a.length; i++) {

+            Object o = a[i];

+            if (!o.equals(v.elementAt(i))) {

+                return false;

+            }

+        }

+        return true;

+    }

+    /**

+     * Compares the contents of an array and a Vector for set equality. Assumes

+     * input array and vector are sets (i.e. no duplicate entries)

+     */

+    public static boolean sameSet(Object[] a, Vector b) {

+        if (a == null || b == null || a.length != b.size()) {

+            return false;

+        }

+        if (a.length == 0) {

+            return true;

+        }

+        // Convert the array into a set

+        Hashtable t = new Hashtable();

+        for (int i = 0; i < a.length; i++) {

+            t.put(a[i], a[i]);

+        }

+        for (int i = 0; i < b.size(); i++) {

+            Object o = b.elementAt(i);

+            if (t.remove(o) == null) {

+                return false;

+            }

+        }

+        return (t.size() == 0);

+    }

+    /**

+     * Converts a vector to a string array.

+     */

+    public static String[] toArray(Vector src) {

+        String[] retval = new String[src.size()];

+        src.copyInto(retval);

+        return retval;

+    }

+    /**

+     * Replaces any embedded quotes in the string so that the value can be

+     * placed in an attribute in an XML file

+     * 

+     * @param attrValue

+     *            value to be expressed

+     * @return equivalent attribute literal

+     *  

+     */

+    public static String xmlAttribEncode(String attrValue) {

+        int quotePos = attrValue.indexOf('\"');

+        if (quotePos < 0) {

+            return attrValue;

+        }

+        int startPos = 0;

+        StringBuffer buf = new StringBuffer(attrValue.length() + 20);

+        while (quotePos >= 0) {

+            buf.append(attrValue.substring(startPos, quotePos));

+            buf.append("&quot;");

+            startPos = quotePos + 1;

+            quotePos = attrValue.indexOf('\"', startPos);

+        }

+        buf.append(attrValue.substring(startPos));

+        return buf.toString();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerDef.java
new file mode 100644
index 0000000..0a92a51
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerDef.java
@@ -0,0 +1,556 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;

+import net.sf.antcontrib.cpptasks.compiler.Compiler;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;

+import net.sf.antcontrib.cpptasks.types.CompilerArgument;

+import net.sf.antcontrib.cpptasks.types.ConditionalPath;

+import net.sf.antcontrib.cpptasks.types.DefineSet;

+import net.sf.antcontrib.cpptasks.types.IncludePath;

+import net.sf.antcontrib.cpptasks.types.SystemIncludePath;

+import net.sf.antcontrib.cpptasks.types.UndefineArgument;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.EnumeratedAttribute;

+import org.apache.tools.ant.*;

+/**

+ * A compiler definition. compiler elements may be placed either as children of

+ * a cc element or the project element. A compiler element with an id attribute

+ * may be referenced from compiler elements with refid or extends attributes.

+ * 

+ * @author Adam Murdoch

+ */

+public final class CompilerDef extends ProcessorDef {

+    /**

+     * Enumerated attribute with the values "none", "severe", "default",

+     * "production", "diagnostic", and "failtask".

+     */

+    public static class WarningLevel extends EnumeratedAttribute {

+        public String[] getValues() {

+            return new String[]{"none", "severe", "default", "production",

+                    "diagnostic", "aserror"};

+        }

+    }

+    /** The source file sets. */

+    private final Vector defineSets = new Vector();

+    private Boolean exceptions;

+    private Boolean rtti;

+    private final Vector includePaths = new Vector();

+    private Boolean multithreaded;

+    private final Vector precompileDefs = new Vector();

+    private final Vector sysIncludePaths = new Vector();

+    private OptimizationEnum optimization;

+    private int warnings = -1;

+    private Boolean defaultflag = new Boolean(true);

+    public CompilerDef() {

+    }

+    /**

+     * Adds a compiler command-line arg.

+     */

+    public void addConfiguredCompilerArg(CompilerArgument arg) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        addConfiguredProcessorArg(arg);

+    }

+    /**

+     * Adds a compiler command-line arg.

+     */

+    public void addConfiguredCompilerParam(CompilerParam param) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        addConfiguredProcessorParam(param);

+    }

+    /**

+     * Adds a defineset.

+     */

+    public void addConfiguredDefineset(DefineSet defs) {

+        if (defs == null) {

+            throw new NullPointerException("defs");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        defineSets.addElement(defs);

+    }

+    /**

+     * Creates an include path.

+     */

+    public IncludePath createIncludePath() {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        IncludePath path = new IncludePath(p);

+        includePaths.addElement(path);

+        return path;

+    }

+    /**

+     * Add a <includepath>or <sysincludepath> if specify the file 

+     * attribute

+     * 

+     * @throws BuildException

+     *             if the specify file not exist

+     */

+    protected void loadFile(Vector activePath,File file) throws BuildException {

+        FileReader fileReader;

+        BufferedReader in;

+        String str;

+        if (! file.exists()){

+            throw new BuildException("The file " + file + " is not existed");

+        }

+        try {

+            fileReader = new FileReader(file);

+            in = new BufferedReader(fileReader);

+            while ( (str = in.readLine()) != null ){                

+                if(str.trim() == ""){

+                    continue ;

+                }

+                str = getProject().replaceProperties(str);

+                activePath.addElement(str.trim());

+            }

+        }

+        catch(Exception e){

+            throw new BuildException(e.getMessage());

+        }

+    }

+    

+    /**

+     * Specifies precompilation prototype file and exclusions.

+     *  

+     */

+    public PrecompileDef createPrecompile() throws BuildException {

+    	Project p = getProject();

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        PrecompileDef precomp = new PrecompileDef();

+        precomp.setProject(p);

+        precompileDefs.addElement(precomp);

+        return precomp;

+    }

+    /**

+     * Creates a system include path. Locations and timestamps of files located

+     * using the system include paths are not used in dependency analysis.

+     * 

+     * 

+     * Standard include locations should not be specified. The compiler

+     * adapters should recognized the settings from the appropriate environment

+     * variables or configuration files.

+     */

+    public SystemIncludePath createSysIncludePath() {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        SystemIncludePath path = new SystemIncludePath(p);

+        sysIncludePaths.addElement(path);

+        return path;

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    public UndefineArgument[] getActiveDefines() {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException(

+                    "project must be set before this call");

+        }

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getActiveDefines();

+        }

+        Vector actives = new Vector();

+        for (int i = 0; i < defineSets.size(); i++) {

+            DefineSet currentSet = (DefineSet) defineSets.elementAt(i);

+            UndefineArgument[] defines = currentSet.getDefines();

+            for (int j = 0; j < defines.length; j++) {

+                if (defines[j].isActive(p)) {

+                    actives.addElement(defines[j]);

+                }

+            }

+        }

+        UndefineArgument[] retval = new UndefineArgument[actives.size()];

+        actives.copyInto(retval);

+        return retval;

+    }

+    /**

+     * Returns the compiler-specific include path.

+     */

+    public String[] getActiveIncludePaths() {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getActiveIncludePaths();

+        }

+        return getActivePaths(includePaths);

+    }

+    private String[] getActivePaths(Vector paths) {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project not set");

+        }

+        Vector activePaths = new Vector(paths.size());

+        for (int i = 0; i < paths.size(); i++) {

+            ConditionalPath path = (ConditionalPath) paths.elementAt(i);

+            if (path.isActive(p)) {

+                if (path.getFile() == null) {

+                    String[] pathEntries = path.list();

+                    for (int j = 0; j < pathEntries.length; j++) {

+                        activePaths.addElement(pathEntries[j]);

+                    }

+                }

+                else {

+                    loadFile(activePaths, path.getFile());

+                }

+            }

+        }

+        String[] pathNames = new String[activePaths.size()];

+        activePaths.copyInto(pathNames);

+        return pathNames;

+    }

+    public PrecompileDef getActivePrecompile(CompilerDef ccElement) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getActivePrecompile(ccElement);

+        }

+        PrecompileDef current = null;

+        Enumeration enumPrecompilerDef = precompileDefs.elements();

+        while (enumPrecompilerDef.hasMoreElements()) {

+            current = (PrecompileDef) enumPrecompilerDef.nextElement();

+            if (current.isActive()) {

+                return current;

+            }

+        }

+        CompilerDef extendedDef = (CompilerDef) getExtends();

+        if (extendedDef != null) {

+            current = extendedDef.getActivePrecompile(null);

+            if (current != null) {

+                return current;

+            }

+        }

+        if (ccElement != null && getInherit()) {

+            return ccElement.getActivePrecompile(null);

+        }

+        return null;

+    }

+    public String[] getActiveSysIncludePaths() {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getActiveSysIncludePaths();

+        }

+        return getActivePaths(sysIncludePaths);

+    }

+    public final boolean getExceptions(CompilerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getExceptions(defaultProviders, index);

+        }

+        if (exceptions != null) {

+            return exceptions.booleanValue();

+        } else {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getExceptions(defaultProviders,

+                        index + 1);

+            }

+        }

+        return false;

+    }

+    public final Boolean getRtti(CompilerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getRtti(defaultProviders, index);

+        }

+        if (rtti != null) {

+            return rtti;

+        } else {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getRtti(defaultProviders,

+                        index + 1);

+            }

+        }

+        return null;

+    }

+    public final Boolean getDefaultflag(CompilerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                  "CompilerDef")).getDefaultflag(defaultProviders, index);

+        }

+        return defaultflag;

+    }

+    public final OptimizationEnum getOptimization(CompilerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getOptimization(defaultProviders, index);

+        }

+        if (optimization != null) {

+            return optimization;

+        } else {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getOptimization(defaultProviders,

+                        index + 1);

+            }

+        }

+        return null;

+    }

+    

+    public boolean getMultithreaded(CompilerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getMultithreaded(defaultProviders, index);

+        }

+        if (multithreaded != null) {

+            return multithreaded.booleanValue();

+        } else {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getMultithreaded(

+                        defaultProviders, index + 1);

+            }

+        }

+        return true;

+    }

+    public Processor getProcessor() {

+        Processor processor = super.getProcessor();

+        if (processor == null) {

+            processor = GccCCompiler.getInstance();

+        }

+        if (getLibtool() && processor instanceof CommandLineCompiler) {

+            CommandLineCompiler compiler = (CommandLineCompiler) processor;

+            processor = compiler.getLibtoolCompiler();

+        }

+        return processor;

+    }

+    public int getWarnings(CompilerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((CompilerDef) getCheckedRef(CompilerDef.class,

+                    "CompilerDef")).getWarnings(defaultProviders, index);

+        }

+        if (warnings == -1) {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getWarnings(defaultProviders,

+                        index + 1);

+            }

+        }

+        return warnings;

+    }

+    /**

+     * Sets the default compiler adapter. Use the "name" attribute when the

+     * compiler is a supported compiler.

+     * 

+     * @param classname

+     *            fully qualified classname which implements CompilerAdapter

+     */

+    public void setClassname(String classname) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        super.setClassname(classname);

+        Processor proc = getProcessor();

+        if (!(proc instanceof Compiler)) {

+            throw new BuildException(classname + " does not implement Compiler");

+        }

+    }

+    /**

+     * Enables or disables exception support.

+     * 

+     * @param exceptions

+     *            if true, exceptions are supported.

+     *  

+     */

+    public void setExceptions(boolean exceptions) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.exceptions = booleanValueOf(exceptions);

+    }

+

+    /**

+     * Enables or disables run-time type information.

+     * 

+     * @param rtti

+     *            if true, run-time type information is supported.

+     *  

+     */

+    public void setRtti(boolean rtti) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.rtti = booleanValueOf(rtti);

+    }

+    

+    /**

+     * Enables or disables generation of multithreaded code. Unless specified,

+     * multithreaded code generation is enabled.

+     * 

+     * @param multi

+     *            If true, generated code may be multithreaded.

+     */

+    public void setMultithreaded(boolean multithreaded) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.multithreaded = booleanValueOf(multithreaded);

+    }

+    /**

+     * Sets compiler type.

+     * 

+     * 

+     * <table width="100%" border="1"> <thead>Supported compilers </thead>

+     * <tr>

+     * <td>gcc (default)</td>

+     * <td>GCC C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>g++</td>

+     * <td>GCC C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>c++</td>

+     * <td>GCC C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>g77</td>

+     * <td>GNU Fortran compiler</td>

+     * </tr>

+     * <tr>

+     * <td>msvc</td>

+     * <td>Microsoft Visual C++</td>

+     * </tr>

+     * <tr>

+     * <td>bcc</td>

+     * <td>Borland C++ Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>msrc</td>

+     * <td>Microsoft Resource Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>brc</td>

+     * <td>Borland Resource Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>df</td>

+     * <td>Compaq Visual Fortran Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>midl</td>

+     * <td>Microsoft MIDL Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>icl</td>

+     * <td>Intel C++ compiler for Windows (IA-32)</td>

+     * </tr>

+     * <tr>

+     * <td>ecl</td>

+     * <td>Intel C++ compiler for Windows (IA-64)</td>

+     * </tr>

+     * <tr>

+     * <td>icc</td>

+     * <td>Intel C++ compiler for Linux (IA-32)</td>

+     * </tr>

+     * <tr>

+     * <td>ecc</td>

+     * <td>Intel C++ compiler for Linux (IA-64)</td>

+     * </tr>

+     * <tr>

+     * <td>CC</td>

+     * <td>Sun ONE C++ compiler</td>

+     * </tr>

+     * <tr>

+     * <td>aCC</td>

+     * <td>HP aC++ C++ Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>os390</td>

+     * <td>OS390 C Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>os400</td>

+     * <td>Icc Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>sunc89</td>

+     * <td>Sun C89 C Compiler</td>

+     * </tr>

+     * <tr>

+     * <td>xlC</td>

+     * <td>VisualAge C Compiler</td>

+     * </tr>

+     * </table>

+     *  

+     */

+    public void setName(CompilerEnum name) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        Compiler compiler = name.getCompiler();

+        setProcessor(compiler);

+    }

+    protected void setProcessor(Processor proc) throws BuildException {

+        try {

+            super.setProcessor((Compiler) proc);

+        } catch (ClassCastException ex) {

+            throw new BuildException(ex);

+        }

+    }

+    /**

+     * Enumerated attribute with the values "none", "severe", "default",

+     * "production", "diagnostic", and "failtask".

+     */

+    public void setWarnings(CompilerDef.WarningLevel level) {

+        warnings = level.getIndex();

+    }

+    /**

+     * Sets optimization level.

+     * 

+     * @param value optimization level

+     */

+    public void setOptimize(OptimizationEnum value) {

+    	if (isReference()) {

+    		throw tooManyAttributes();

+    	}

+    	this.optimization = value;

+    }

+    /**

+     * Enables or disables default flags.

+     * 

+     * @param defaultflag

+     *            if true, default flags will add to command line.

+     *  

+     */

+    public void setDefaultflag(boolean defaultflag) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.defaultflag = booleanValueOf(defaultflag);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerEnum.java
new file mode 100644
index 0000000..a017243
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerEnum.java
@@ -0,0 +1,221 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import net.sf.antcontrib.cpptasks.arm.ADSCCompiler;

+import net.sf.antcontrib.cpptasks.borland.BorlandCCompiler;

+import net.sf.antcontrib.cpptasks.borland.BorlandResourceCompiler;

+import net.sf.antcontrib.cpptasks.compaq.CompaqVisualFortranCompiler;

+import net.sf.antcontrib.cpptasks.compiler.Compiler;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCCompiler;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioMIDLCompiler;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioResourceCompiler;

+import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;

+import net.sf.antcontrib.cpptasks.hp.aCCCompiler;

+import net.sf.antcontrib.cpptasks.ibm.VisualAgeCCompiler;

+import net.sf.antcontrib.cpptasks.intel.IntelLinux32CCompiler;

+import net.sf.antcontrib.cpptasks.intel.IntelLinux64CCompiler;

+import net.sf.antcontrib.cpptasks.intel.IntelWin32CCompiler;

+import net.sf.antcontrib.cpptasks.intel.IntelWin64CCompiler;

+import net.sf.antcontrib.cpptasks.os390.OS390CCompiler;

+import net.sf.antcontrib.cpptasks.os400.IccCompiler;

+import net.sf.antcontrib.cpptasks.sun.C89CCompiler;

+import net.sf.antcontrib.cpptasks.sun.ForteCCCompiler;

+import net.sf.antcontrib.cpptasks.ti.ClxxCCompiler;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+/**

+ * Enumeration of supported compilers

+ * 

+ * <table width="100%" border="1"> <thead>Supported compilers </thead>

+ * <tr>

+ * <td>gcc (default)</td>

+ * <td>GCC C++ compiler</td>

+ * </tr>

+ * <tr>

+ * <td>g++</td>

+ * <td>GCC C++ compiler</td>

+ * </tr>

+ * <tr>

+ * <td>c++</td>

+ * <td>GCC C++ compiler</td>

+ * </tr>

+ * <tr>

+ * <td>g77</td>

+ * <td>GNU FORTRAN compiler</td>

+ * </tr>

+ * <tr>

+ * <td>msvc</td>

+ * <td>Microsoft Visual C++</td>

+ * </tr>

+ * <tr>

+ * <td>bcc</td>

+ * <td>Borland C++ Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>msrc</td>

+ * <td>Microsoft Resource Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>brc</td>

+ * <td>Borland Resource Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>df</td>

+ * <td>Compaq Visual Fortran Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>midl</td>

+ * <td>Microsoft MIDL Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>icl</td>

+ * <td>Intel C++ compiler for Windows (IA-32)</td>

+ * </tr>

+ * <tr>

+ * <td>ecl</td>

+ * <td>Intel C++ compiler for Windows (IA-64)</td>

+ * </tr>

+ * <tr>

+ * <td>icc</td>

+ * <td>Intel C++ compiler for Linux (IA-32)</td>

+ * </tr>

+ * <tr>

+ * <td>ecc</td>

+ * <td>Intel C++ compiler for Linux (IA-64)</td>

+ * </tr>

+ * <tr>

+ * <td>CC</td>

+ * <td>Sun ONE C++ compiler</td>

+ * </tr>

+ * <tr>

+ * <td>aCC</td>

+ * <td>HP aC++ C++ Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>os390</td>

+ * <td>OS390 C Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>os400</td>

+ * <td>Icc Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>sunc89</td>

+ * <td>Sun C89 C Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>xlC</td>

+ * <td>VisualAge C Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>cl6x</td>

+ * <td>TI TMS320C6000 Optimizing Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>cl55</td>

+ * <td>TI TMS320C55x Optimizing C/C++ Compiler</td>

+ * </tr>

+ * <tr>

+ * <td>armcpp</td>

+ * <td>ARM 32-bit C++ compiler</td>

+ * </tr>

+ * <tr>

+ * <td>armcc</td>

+ * <td>ARM 32-bit C compiler</td>

+ * </tr>

+ * <tr>

+ * <td>tcpp</td>

+ * <td>ARM 16-bit C++ compiler</td>

+ * </tr>

+ * <tr>

+ * <td>tcc</td>

+ * <td>ARM 16-bit C compiler</td>

+ * </tr>

+ * </table>

+ * 

+ * @author Curt Arnold

+ *  

+ */

+public class CompilerEnum extends EnumeratedAttribute {

+    private final static ProcessorEnumValue[] compilers = new ProcessorEnumValue[]{

+            new ProcessorEnumValue("gcc", GccCCompiler.getInstance()),

+            new ProcessorEnumValue("g++", GccCCompiler.getGppInstance()),

+            new ProcessorEnumValue("c++", GccCCompiler.getCppInstance()),

+            new ProcessorEnumValue("g77", GccCCompiler.getG77Instance()),

+            new ProcessorEnumValue("msvc", DevStudioCCompiler.getInstance()),

+            new ProcessorEnumValue("bcc", BorlandCCompiler.getInstance()),

+            new ProcessorEnumValue("msrc", DevStudioResourceCompiler

+                    .getInstance()),

+            new ProcessorEnumValue("brc", BorlandResourceCompiler.getInstance()),

+            new ProcessorEnumValue("df", CompaqVisualFortranCompiler

+                    .getInstance()),

+            new ProcessorEnumValue("midl", DevStudioMIDLCompiler.getInstance()),

+            new ProcessorEnumValue("icl", IntelWin32CCompiler.getInstance()),

+            new ProcessorEnumValue("ecl", IntelWin64CCompiler.getInstance()),

+            new ProcessorEnumValue("icc", IntelLinux32CCompiler.getInstance()),

+            new ProcessorEnumValue("ecc", IntelLinux64CCompiler.getInstance()),

+            new ProcessorEnumValue("CC", ForteCCCompiler.getInstance()),

+            new ProcessorEnumValue("aCC", aCCCompiler.getInstance()),

+            new ProcessorEnumValue("os390", OS390CCompiler.getInstance()),

+            new ProcessorEnumValue("os400", IccCompiler.getInstance()),

+            new ProcessorEnumValue("sunc89", C89CCompiler.getInstance()),

+            new ProcessorEnumValue("xlC", VisualAgeCCompiler.getInstance()),

+            new ProcessorEnumValue("cl6x", ClxxCCompiler.getCl6xInstance()),

+            new ProcessorEnumValue("cl55", ClxxCCompiler.getCl55Instance()),

+            new ProcessorEnumValue("armcc", ADSCCompiler.getArmCC()),

+            new ProcessorEnumValue("armcpp", ADSCCompiler.getArmCpp()),

+            new ProcessorEnumValue("tcc", ADSCCompiler.getThumbCC()),

+            new ProcessorEnumValue("tcpp", ADSCCompiler.getThumbCpp()),

+            // userdefined

+            //new ProcessorEnumValue("userdefine", UserdefineCompiler.getInstance()),

+            // GCC Cross Compilers

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-gcc",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler

+                            .getInstance()),

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-g++",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler

+                            .getGppInstance()),

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-c++",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler

+                            .getCppInstance()),

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-g77",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccCCompiler

+                            .getG77Instance()),

+            // GCC Cross Compilers

+            new ProcessorEnumValue("gcc-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler

+                            .getInstance()),

+            new ProcessorEnumValue("g++-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler

+                            .getGppInstance()),

+            new ProcessorEnumValue("c++-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler

+                            .getCppInstance()),

+            new ProcessorEnumValue("g77-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GccCCompiler

+                            .getG77Instance()),};

+    public Compiler getCompiler() {

+        return (Compiler) compilers[getIndex()].getProcessor();

+    }

+    public String[] getValues() {

+        return ProcessorEnumValue.getValues(compilers);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerParam.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerParam.java
new file mode 100644
index 0000000..82eb6ee
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CompilerParam.java
@@ -0,0 +1,33 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+/*******************************************************************************

+ * Place class description here.

+ * 

+ * @author inger

+ * @author <additional author>

+ * 

+ * @since  

+ ******************************************************************************/

+public class CompilerParam extends ProcessorParam {

+    public CompilerParam() {

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DependencyInfo.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DependencyInfo.java
new file mode 100644
index 0000000..429d2b0
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DependencyInfo.java
@@ -0,0 +1,86 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.util.Vector;

+/**

+ * @author Curt Arnold

+ */

+public final class DependencyInfo {

+    /**

+     * Last modified time of this file or anything that it depends on.

+     * 

+     * Not persisted since almost any change could invalidate it. Initialized

+     * to long.MIN_VALUE on construction.

+     */

+    private long compositeLastModified;

+    private/* final */String includePathIdentifier;

+    private/* final */String[] includes;

+    private/* final */String source;

+    private/* final */long sourceLastModified;

+    private/* final */String[] sysIncludes;

+    public DependencyInfo(String includePathIdentifier, String source,

+            long sourceLastModified, Vector includes, Vector sysIncludes) {

+        if (source == null) {

+            throw new NullPointerException("source");

+        }

+        if (includePathIdentifier == null) {

+            throw new NullPointerException("includePathIdentifier");

+        }

+        this.source = source;

+        this.sourceLastModified = sourceLastModified;

+        this.includePathIdentifier = includePathIdentifier;

+        this.includes = new String[includes.size()];

+        if (includes.size() == 0) {

+            compositeLastModified = sourceLastModified;

+        } else {

+            includes.copyInto(this.includes);

+            compositeLastModified = Long.MIN_VALUE;

+        }

+        this.sysIncludes = new String[sysIncludes.size()];

+        sysIncludes.copyInto(this.sysIncludes);

+    }

+    /**

+     * Returns the latest modification date of the source or anything that it

+     * depends on.

+     * 

+     * @returns the composite lastModified time, returns Long.MIN_VALUE if not

+     * set

+     */

+    public long getCompositeLastModified() {

+        return compositeLastModified;

+    }

+    public String getIncludePathIdentifier() {

+        return includePathIdentifier;

+    }

+    public String[] getIncludes() {

+        String[] includesClone = (String[]) includes.clone();

+        return includesClone;

+    }

+    public String getSource() {

+        return source;

+    }

+    public long getSourceLastModified() {

+        return sourceLastModified;

+    }

+    public String[] getSysIncludes() {

+        String[] sysIncludesClone = (String[]) sysIncludes.clone();

+        return sysIncludesClone;

+    }

+    public void setCompositeLastModified(long lastMod) {

+        compositeLastModified = lastMod;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DependencyTable.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DependencyTable.java
new file mode 100644
index 0000000..3cbee7a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DependencyTable.java
@@ -0,0 +1,609 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.BufferedWriter;

+import java.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.OutputStreamWriter;

+import java.io.UnsupportedEncodingException;

+import java.util.Enumeration;

+import java.util.Hashtable;

+import java.util.Vector;

+import javax.xml.parsers.ParserConfigurationException;

+import javax.xml.parsers.SAXParser;

+import javax.xml.parsers.SAXParserFactory;

+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.xml.sax.Attributes;

+import org.xml.sax.SAXException;

+import org.xml.sax.helpers.DefaultHandler;

+/**

+ * @author Curt Arnold

+ */

+public final class DependencyTable {

+    /**

+     * This class handles populates the TargetHistory hashtable in response to

+     * SAX parse events

+     */

+    private class DependencyTableHandler extends DefaultHandler {

+        private File baseDir;

+        private final DependencyTable dependencyTable;

+        private String includePath;

+        private Vector includes;

+        private String source;

+        private long sourceLastModified;

+        private Vector sysIncludes;

+        /**

+         * Constructor

+         * 

+         * @param history

+         *            hashtable of TargetHistory keyed by output name

+         * @param outputFiles

+         *            existing files in output directory

+         */

+        private DependencyTableHandler(DependencyTable dependencyTable,

+                File baseDir) {

+            this.dependencyTable = dependencyTable;

+            this.baseDir = baseDir;

+            includes = new Vector();

+            sysIncludes = new Vector();

+            source = null;

+        }

+        public void endElement(String namespaceURI, String localName,

+                String qName) throws SAXException {

+            //

+            //   if </source> then

+            //       create Dependency object and add to hashtable

+            //           if corresponding source file exists and

+            //           has the same timestamp

+            //

+            if (qName.equals("source")) {

+                if (source != null && includePath != null) {

+                    File existingFile = new File(baseDir, source);

+                    //

+                    //   if the file exists and the time stamp is right

+                    //       preserve the dependency info

+                    if (existingFile.exists()) {

+                        //

+                        //   would have expected exact matches

+                        //       but was seeing some unexpected difference by

+                        //       a few tens of milliseconds, as long

+                        //       as the times are within a second

+                        long existingLastModified = existingFile.lastModified();

+                        long diff = existingLastModified - sourceLastModified;

+                        if (diff >= -500 && diff <= 500) {

+                            DependencyInfo dependInfo = new DependencyInfo(

+                                    includePath, source, sourceLastModified,

+                                    includes, sysIncludes);

+                            dependencyTable.putDependencyInfo(source,

+                                    dependInfo);

+                        }

+                    }

+                    source = null;

+                    includes.setSize(0);

+                }

+            } else {

+                //

+                //    this causes any <source> elements outside the

+                //       scope of an <includePath> to be discarded

+                //

+                if (qName.equals("includePath")) {

+                    includePath = null;

+                }

+            }

+        }

+        /**

+         * startElement handler

+         */

+        public void startElement(String namespaceURI, String localName,

+                String qName, Attributes atts) throws SAXException {

+            //

+            //   if includes, then add relative file name to vector

+            //

+            if (qName.equals("include")) {

+                includes.addElement(atts.getValue("file"));

+            } else {

+                if (qName.equals("sysinclude")) {

+                    sysIncludes.addElement(atts.getValue("file"));

+                } else {

+                    //

+                    //    if source then

+                    //        capture source file name,

+                    //        modification time and reset includes vector

+                    //

+                    if (qName.equals("source")) {

+                        source = atts.getValue("file");

+                        sourceLastModified = Long.parseLong(atts

+                                .getValue("lastModified"), 16);

+                        includes.setSize(0);

+                        sysIncludes.setSize(0);

+                    } else {

+                        if (qName.equals("includePath")) {

+                            includePath = atts.getValue("signature");

+                        }

+                    }

+                }

+            }

+        }

+    }

+    public abstract class DependencyVisitor {

+        /**

+         * Previews all the children of this source file.

+         * 

+         * May be called multiple times as DependencyInfo's for children are

+         * filled in.

+         * 

+         * @return true to continue towards recursion into included files

+         */

+        public abstract boolean preview(DependencyInfo parent,

+                DependencyInfo[] children);

+        /**

+         * Called if the dependency depth exhausted the stack.

+         */

+        public abstract void stackExhausted();

+        /**

+         * Visits the dependency info.

+         * 

+         * @returns true to continue towards recursion into included files

+         */

+        public abstract boolean visit(DependencyInfo dependInfo);

+    }

+    public class TimestampChecker extends DependencyVisitor {

+        private boolean noNeedToRebuild;

+        private long outputLastModified;

+        private boolean rebuildOnStackExhaustion;

+        public TimestampChecker(final long outputLastModified,

+                boolean rebuildOnStackExhaustion) {

+            this.outputLastModified = outputLastModified;

+            noNeedToRebuild = true;

+            this.rebuildOnStackExhaustion = rebuildOnStackExhaustion;

+        }

+        public boolean getMustRebuild() {

+            return !noNeedToRebuild;

+        }

+        public boolean preview(DependencyInfo parent, DependencyInfo[] children) {

+            int withCompositeTimes = 0;

+            long parentCompositeLastModified = parent.getSourceLastModified();

+            for (int i = 0; i < children.length; i++) {

+                if (children[i] != null) {

+                    //

+                    //  expedient way to determine if a child forces us to

+                    // rebuild

+                    //

+                    visit(children[i]);

+                    long childCompositeLastModified = children[i]

+                            .getCompositeLastModified();

+                    if (childCompositeLastModified != Long.MIN_VALUE) {

+                        withCompositeTimes++;

+                        if (childCompositeLastModified > parentCompositeLastModified) {

+                            parentCompositeLastModified = childCompositeLastModified;

+                        }

+                    }

+                }

+            }

+            if (withCompositeTimes == children.length) {

+                parent.setCompositeLastModified(parentCompositeLastModified);

+            }

+            //

+            //  may have been changed by an earlier call to visit()

+            //

+            return noNeedToRebuild;

+        }

+        public void stackExhausted() {

+            if (rebuildOnStackExhaustion) {

+                noNeedToRebuild = false;

+            }

+        }

+        public boolean visit(DependencyInfo dependInfo) {

+            if (noNeedToRebuild) {

+                if (dependInfo.getSourceLastModified() > outputLastModified

+                        || dependInfo.getCompositeLastModified() > outputLastModified) {

+                    noNeedToRebuild = false;

+                }

+            }

+            //

+            //   only need to process the children if

+            //      it has not yet been determined whether

+            //      we need to rebuild and the composite modified time

+            //         has not been determined for this file

+            return noNeedToRebuild

+                    && dependInfo.getCompositeLastModified() == Long.MIN_VALUE;

+        }

+    }

+    private/* final */File baseDir;

+    private String baseDirPath;

+    /**

+     * a hashtable of DependencyInfo[] keyed by output file name

+     */

+    private final Hashtable dependencies = new Hashtable();

+    /** The file the cache was loaded from. */

+    private/* final */File dependenciesFile;

+    /** Flag indicating whether the cache should be written back to file. */

+    private boolean dirty;

+    /**

+     * Creates a target history table from dependencies.xml in the prject

+     * directory, if it exists. Otherwise, initializes the dependencies empty.

+     * 

+     * @param task

+     *            task used for logging history load errors

+     * @param baseDir

+     *            output directory for task

+     */

+    public DependencyTable(File baseDir) {

+        if (baseDir == null) {

+            throw new NullPointerException("baseDir");

+        }

+        this.baseDir = baseDir;

+        try {

+            baseDirPath = baseDir.getCanonicalPath();

+        } catch (IOException ex) {

+            baseDirPath = baseDir.toString();

+        }

+        dirty = false;

+        //

+        //   load any existing dependencies from file

+        dependenciesFile = new File(baseDir, "dependencies.xml");

+    }

+    public void commit(CCTask task) {

+        //

+        //   if not dirty, no need to update file

+        //

+        if (dirty) {

+            //

+            //   walk through dependencies to get vector of include paths

+            // identifiers

+            //

+            Vector includePaths = getIncludePaths();

+            //

+            //

+            //   write dependency file

+            //

+            try {

+                FileOutputStream outStream = new FileOutputStream(

+                        dependenciesFile);

+                OutputStreamWriter streamWriter;

+                //

+                //    Early VM's may not have UTF-8 support

+                //       fallback to default code page which

+                //           "should" be okay unless there are

+                //            non ASCII file names

+                String encodingName = "UTF-8";

+                try {

+                    streamWriter = new OutputStreamWriter(outStream, "UTF-8");

+                } catch (UnsupportedEncodingException ex) {

+                    streamWriter = new OutputStreamWriter(outStream);

+                    encodingName = streamWriter.getEncoding();

+                }

+                BufferedWriter writer = new BufferedWriter(streamWriter);

+                writer.write("<?xml version='1.0' encoding='");

+                writer.write(encodingName);

+                writer.write("'?>\n");

+                writer.write("<dependencies>\n");

+                StringBuffer buf = new StringBuffer();

+                Enumeration includePathEnum = includePaths.elements();

+                while (includePathEnum.hasMoreElements()) {

+                    writeIncludePathDependencies((String) includePathEnum

+                            .nextElement(), writer, buf);

+                }

+                writer.write("</dependencies>\n");

+                writer.close();

+                dirty = false;

+            } catch (IOException ex) {

+                task.log("Error writing " + dependenciesFile.toString() + ":"

+                        + ex.toString());

+            }

+        }

+    }

+    /**

+     * Returns an enumerator of DependencyInfo's

+     */

+    public Enumeration elements() {

+        return dependencies.elements();

+    }

+    /**

+     * This method returns a DependencyInfo for the specific source file and

+     * include path identifier

+     *  

+     */

+    public DependencyInfo getDependencyInfo(String sourceRelativeName,

+            String includePathIdentifier) {

+        DependencyInfo dependInfo = null;

+        DependencyInfo[] dependInfos = (DependencyInfo[]) dependencies

+                .get(sourceRelativeName);

+        if (dependInfos != null) {

+            for (int i = 0; i < dependInfos.length; i++) {

+                dependInfo = dependInfos[i];

+                if (dependInfo.getIncludePathIdentifier().equals(

+                        includePathIdentifier)) {

+                    return dependInfo;

+                }

+            }

+        }

+        return null;

+    }

+    private Vector getIncludePaths() {

+        Vector includePaths = new Vector();

+        DependencyInfo[] dependInfos;

+        Enumeration dependenciesEnum = dependencies.elements();

+        while (dependenciesEnum.hasMoreElements()) {

+            dependInfos = (DependencyInfo[]) dependenciesEnum.nextElement();

+            for (int i = 0; i < dependInfos.length; i++) {

+                DependencyInfo dependInfo = dependInfos[i];

+                boolean matchesExisting = false;

+                final String dependIncludePath = dependInfo

+                        .getIncludePathIdentifier();

+                Enumeration includePathEnum = includePaths.elements();

+                while (includePathEnum.hasMoreElements()) {

+                    if (dependIncludePath.equals(includePathEnum.nextElement())) {

+                        matchesExisting = true;

+                        break;

+                    }

+                }

+                if (!matchesExisting) {

+                    includePaths.addElement(dependIncludePath);

+                }

+            }

+        }

+        return includePaths;

+    }

+    public void load() throws IOException, ParserConfigurationException,

+            SAXException {

+        dependencies.clear();

+        if (dependenciesFile.exists()) {

+            SAXParserFactory factory = SAXParserFactory.newInstance();

+            factory.setValidating(false);

+            SAXParser parser = factory.newSAXParser();

+            parser.parse(dependenciesFile, new DependencyTableHandler(this,

+                    baseDir));

+            dirty = false;

+        }

+    }

+    /**

+     * Determines if the specified target needs to be rebuilt.

+     * 

+     * This task may result in substantial IO as files are parsed to determine

+     * their dependencies

+     */

+    public boolean needsRebuild(CCTask task, TargetInfo target,

+            int dependencyDepth) {

+        //    look at any files where the compositeLastModified

+        //    is not known, but the includes are known

+        //

+        boolean mustRebuild = false;

+        CompilerConfiguration compiler = (CompilerConfiguration) target

+                .getConfiguration();

+        String includePathIdentifier = compiler.getIncludePathIdentifier();

+        File[] sources = target.getSources();

+        DependencyInfo[] dependInfos = new DependencyInfo[sources.length];

+        long outputLastModified = target.getOutput().lastModified();

+        //

+        //   try to solve problem using existing dependency info

+        //      (not parsing any new files)

+        //

+        DependencyInfo[] stack = new DependencyInfo[50];

+        boolean rebuildOnStackExhaustion = true;

+        if (dependencyDepth >= 0) {

+            if (dependencyDepth < 50) {

+                stack = new DependencyInfo[dependencyDepth];

+            }

+            rebuildOnStackExhaustion = false;

+        }

+        TimestampChecker checker = new TimestampChecker(outputLastModified,

+                rebuildOnStackExhaustion);

+        for (int i = 0; i < sources.length && !mustRebuild; i++) {

+            File source = sources[i];

+            String relative = CUtil.getRelativePath(baseDirPath, source);

+            DependencyInfo dependInfo = getDependencyInfo(relative,

+                    includePathIdentifier);

+            if (dependInfo == null) {

+                task.log("Parsing " + relative, Project.MSG_VERBOSE);

+                dependInfo = parseIncludes(task, compiler, source);

+            }

+            walkDependencies(task, dependInfo, compiler, stack, checker);

+            mustRebuild = checker.getMustRebuild();

+        }

+        return mustRebuild;

+    }

+    public DependencyInfo parseIncludes(CCTask task,

+            CompilerConfiguration compiler, File source) {

+        DependencyInfo dependInfo = compiler.parseIncludes(task, baseDir,

+                source);

+        String relativeSource = CUtil.getRelativePath(baseDirPath, source);

+        putDependencyInfo(relativeSource, dependInfo);

+        return dependInfo;

+    }

+    private void putDependencyInfo(String key, DependencyInfo dependInfo) {

+        //

+        //   optimistic, add new value

+        //

+        DependencyInfo[] old = (DependencyInfo[]) dependencies.put(key,

+                new DependencyInfo[]{dependInfo});

+        dirty = true;

+        //

+        //   something was already there

+        //

+        if (old != null) {

+            //

+            //   see if the include path matches a previous entry

+            //       if so replace it

+            String includePathIdentifier = dependInfo

+                    .getIncludePathIdentifier();

+            for (int i = 0; i < old.length; i++) {

+                DependencyInfo oldDepend = old[i];

+                if (oldDepend.getIncludePathIdentifier().equals(

+                        includePathIdentifier)) {

+                    old[i] = dependInfo;

+                    dependencies.put(key, old);

+                    return;

+                }

+            }

+            //

+            //   no match prepend the new entry to the array

+            //      of dependencies for the file

+            DependencyInfo[] combined = new DependencyInfo[old.length + 1];

+            combined[0] = dependInfo;

+            for (int i = 0; i < old.length; i++) {

+                combined[i + 1] = old[i];

+            }

+            dependencies.put(key, combined);

+        }

+        return;

+    }

+    public void walkDependencies(CCTask task, DependencyInfo dependInfo,

+            CompilerConfiguration compiler, DependencyInfo[] stack,

+            DependencyVisitor visitor) throws BuildException {

+        //

+        //   visit this node

+        //       if visit returns true then

+        //          visit the referenced include and sysInclude dependencies

+        //

+        if (visitor.visit(dependInfo)) {

+            //

+            //   find first null entry on stack

+            //

+            int stackPosition = -1;

+            for (int i = 0; i < stack.length; i++) {

+                if (stack[i] == null) {

+                    stackPosition = i;

+                    stack[i] = dependInfo;

+                    break;

+                } else {

+                    //

+                    //   if we have appeared early in the calling history

+                    //      then we didn't exceed the criteria

+                    if (stack[i] == dependInfo) {

+                        return;

+                    }

+                }

+            }

+            if (stackPosition == -1) {

+                visitor.stackExhausted();

+                return;

+            }

+            //

+            //   locate dependency infos

+            //

+            String[] includes = dependInfo.getIncludes();

+            String includePathIdentifier = compiler.getIncludePathIdentifier();

+            DependencyInfo[] includeInfos = new DependencyInfo[includes.length];

+            for (int i = 0; i < includes.length; i++) {

+                DependencyInfo includeInfo = getDependencyInfo(includes[i],

+                        includePathIdentifier);

+                includeInfos[i] = includeInfo;

+            }

+            //

+            //   preview with only the already available dependency infos

+            //

+            if (visitor.preview(dependInfo, includeInfos)) {

+                //

+                //   now need to fill in the missing DependencyInfos

+                //

+                int missingCount = 0;

+                for (int i = 0; i < includes.length; i++) {

+                    if (includeInfos[i] == null) {

+                        missingCount++;

+                        task.log("Parsing " + includes[i], Project.MSG_VERBOSE);

+                        // If the include is part of a UNC don't go building a

+                        // relative file name.

+                        File src = includes[i].startsWith("\\\\") ? new File(

+                                includes[i]) : new File(baseDir, includes[i]);

+                        DependencyInfo includeInfo = parseIncludes(task,

+                                compiler, src);

+                        includeInfos[i] = includeInfo;

+                    }

+                }

+                //

+                //   if it passes a review the second time

+                //      then recurse into all the children

+                if (missingCount == 0

+                        || visitor.preview(dependInfo, includeInfos)) {

+                    //

+                    //   recurse into

+                    //

+                    for (int i = 0; i < includeInfos.length; i++) {

+                        DependencyInfo includeInfo = includeInfos[i];

+                        walkDependencies(task, includeInfo, compiler, stack,

+                                visitor);

+                    }

+                }

+            }

+            stack[stackPosition] = null;

+        }

+    }

+    private void writeDependencyInfo(BufferedWriter writer, StringBuffer buf,

+            DependencyInfo dependInfo) throws IOException {

+        String[] includes = dependInfo.getIncludes();

+        String[] sysIncludes = dependInfo.getSysIncludes();

+        //

+        //   if the includes have not been evaluted then

+        //       it is not worth our time saving it

+        //       and trying to distiguish between files with

+        //       no dependencies and those with undetermined dependencies

+        buf.setLength(0);

+        buf.append("      <source file=\"");

+        buf.append(CUtil.xmlAttribEncode(dependInfo.getSource()));

+        buf.append("\" lastModified=\"");

+        buf.append(Long.toHexString(dependInfo.getSourceLastModified()));

+        buf.append("\">\n");

+        writer.write(buf.toString());

+        for (int i = 0; i < includes.length; i++) {

+            buf.setLength(0);

+            buf.append("         <include file=\"");

+            buf.append(CUtil.xmlAttribEncode(includes[i]));

+            buf.append("\"/>\n");

+            writer.write(buf.toString());

+        }

+        for (int i = 0; i < sysIncludes.length; i++) {

+            buf.setLength(0);

+            buf.append("         <sysinclude file=\"");

+            buf.append(CUtil.xmlAttribEncode(sysIncludes[i]));

+            buf.append("\"/>\n");

+            writer.write(buf.toString());

+        }

+        writer.write("      </source>\n");

+        return;

+    }

+    private void writeIncludePathDependencies(String includePathIdentifier,

+            BufferedWriter writer, StringBuffer buf) throws IOException {

+        //

+        //  include path element

+        //

+        buf.setLength(0);

+        buf.append("   <includePath signature=\"");

+        buf.append(CUtil.xmlAttribEncode(includePathIdentifier));

+        buf.append("\">\n");

+        writer.write(buf.toString());

+        Enumeration dependenciesEnum = dependencies.elements();

+        while (dependenciesEnum.hasMoreElements()) {

+            DependencyInfo[] dependInfos = (DependencyInfo[]) dependenciesEnum

+                    .nextElement();

+            for (int i = 0; i < dependInfos.length; i++) {

+                DependencyInfo dependInfo = dependInfos[i];

+                //

+                //   if this is for the same include path

+                //      then output the info

+                if (dependInfo.getIncludePathIdentifier().equals(

+                        includePathIdentifier)) {

+                    writeDependencyInfo(writer, buf, dependInfo);

+                }

+            }

+        }

+        writer.write("   </includePath>\n");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerDef.java
new file mode 100644
index 0000000..ee4f656
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerDef.java
@@ -0,0 +1,243 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+

+import org.apache.tools.ant.types.DataType;

+import org.apache.tools.ant.types.Reference;

+import java.util.Vector;

+

+/**

+ * Distributed build information (Non-functional prototype).

+ *

+ */

+public final class DistributerDef

+    extends DataType {

+  /**

+   * if property.

+   */

+  private String ifCond;

+

+  /**

+   * unless property.

+   */

+  private String unlessCond;

+

+  /**

+   * hosts.

+   *

+   */

+  private String hosts;

+

+  /**

+   * Protocol.

+   *

+   */

+  private DistributerProtocolEnum protocol;

+

+  /**

+   * Not sure what this is.

+   */

+  private int tcpCork;

+

+  /**

+   * user name.

+   */

+  private String user;

+

+  /**

+   *  local to remote file name maps.

+   */

+  private final Vector maps = new Vector();

+

+  /**

+   * Constructor.

+   *

+   */

+  public DistributerDef() {

+  }

+

+  /**

+   * Required by documentation generator.

+   */

+  public void execute() {

+    throw new org.apache.tools.ant.BuildException(

+        "Not an actual task, but looks like one for documentation purposes");

+  }

+

+  /**

+   * Returns true if the if and unless conditions (if any) are

+   * satisfied.

+   * @return true if definition is active.

+   */

+  public boolean isActive() {

+    return CUtil.isActive(getProject(), ifCond, unlessCond);

+  }

+

+  /**

+   * Sets an id that can be used to reference this element.

+   *

+   * @param id

+   *            id

+   */

+  public void setId(final String id) {

+    //

+    //  this is actually accomplished by a different

+    //     mechanism, but we can document it

+    //

+  }

+

+  /**

+   * Sets the property name for the 'if' condition.

+   *

+   * The define will be ignored unless the property is defined.

+   *

+   * The value of the property is insignificant, but values that would imply

+   * misinterpretation ("false", "no") will throw an exception when

+   * evaluated.

+   *

+   * @param propName

+   *            property name

+   */

+  public void setIf(final String propName) {

+    ifCond = propName;

+  }

+

+  /**

+   * Specifies that this element should behave as if the content of the

+   * element with the matching id attribute was inserted at this location. If

+   * specified, no other attributes should be specified.

+   * @param r reference name

+   */

+  public void setRefid(final Reference r)  {

+    super.setRefid(r);

+  }

+

+  /**

+   * Set the property name for the 'unless' condition.

+   *

+   * If named property is set, the define will be ignored.

+   *

+   * The value of the property is insignificant, but values that would imply

+   * misinterpretation ("false", "no") of the behavior will throw an

+   * exception when evaluated.

+   *

+   * @param propName

+   *            name of property

+   */

+  public void setUnless(final String propName) {

+    unlessCond = propName;

+  }

+

+  /**

+   * Gets hosts.

+   * @return hosts, may be null.

+   *

+   */

+  public String getHosts() {

+    if (isReference()) {

+      DistributerDef refDistributer = (DistributerDef)

+          getCheckedRef(DistributerDef.class,

+                        "DistributerDef");

+      return refDistributer.getHosts();

+    }

+    return hosts;

+  }

+

+  /**

+   * Gets tcp cork.

+   * @return TCP_CORK value.

+   *

+   */

+  public int getTcpcork() {

+    if (isReference()) {

+      DistributerDef refDistributer = (DistributerDef)

+          getCheckedRef(DistributerDef.class,

+                        "DistributerDef");

+      return refDistributer.getTcpcork();

+    }

+    return tcpCork;

+  }

+

+  /**

+   * Gets protocol.

+   * @return protocol, may be null.

+   *

+   */

+  public DistributerProtocolEnum getProtocol() {

+    if (isReference()) {

+      DistributerDef refDistributer = (DistributerDef)

+          getCheckedRef(DistributerDef.class,

+                        "DistributerDef");

+      return refDistributer.getProtocol();

+    }

+    return protocol;

+  }

+

+  /**

+   * Sets hosts.

+   * @param value new value

+   */

+  public void setHosts(final String value) {

+    if (isReference()) {

+      throw tooManyAttributes();

+    }

+    hosts = value;

+  }

+

+  /**

+   * Sets TCP_CORK value.

+   * @param value new value

+   */

+  public void setTcpcork(final int value) {

+    if (isReference()) {

+      throw tooManyAttributes();

+    }

+    tcpCork = value;

+  }

+

+  /**

+   * Sets protocol.

+   * @param value new value

+   */

+  public void setProtocol(final DistributerProtocolEnum value) {

+    if (isReference()) {

+      throw tooManyAttributes();

+    }

+    protocol = value;

+  }

+

+  /**

+   *  Local to remote filename maps.

+   * @return new map

+   */

+  public DistributerMap createMap() {

+    DistributerMap map = new DistributerMap();

+    map.setProject(getProject());

+    maps.addElement(map);

+    return map;

+  }

+

+  /**

+   *  Sets remote user name.

+   * @param value user name

+   */

+  public void setUser(final String value) {

+    user = value;

+  }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerMap.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerMap.java
new file mode 100644
index 0000000..aeacf55
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerMap.java
@@ -0,0 +1,218 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import java.io.File;

+import java.io.IOException;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.DataType;

+

+/**

+ * Local to remote filename mapping (Experimental).

+ *

+ */

+public final class DistributerMap

+    extends DataType {

+  /**

+   * if property.

+   */

+  private String ifCond;

+

+  /**

+   * unless property.

+   */

+  private String unlessCond;

+

+  /**

+   * local directory name.

+   *

+   */

+  private File localName;

+

+  /**

+   * Canonical local file name.

+   */

+  private String canonicalPath;

+

+  /**

+   * remote name.

+   *

+   */

+  private String remoteName;

+

+  /**

+   * Separator (/ or \) character on remote system.

+   */

+  private char remoteSeparator = File.separatorChar;

+

+  /**

+   * hosts that for which this map is valid.

+   *

+   */

+  private String hosts;

+

+  /**

+   * Constructor.

+   *

+   */

+  public DistributerMap() {

+  }

+

+  /**

+   * Required by documentation generator.

+   */

+  public void execute()  {

+    throw new org.apache.tools.ant.BuildException(

+        "Not an actual task, but looks like one for documentation purposes");

+  }

+

+  /**

+   * Returns true if the if and unless conditions (if any) are

+   * satisfied.

+   *

+   * @return true if this object is active.

+   */

+  public boolean isActive()  {

+    return CUtil.isActive(getProject(), ifCond, unlessCond);

+  }

+

+  /**

+   * Sets the property name for the 'if' condition.

+   *

+   * This object will be ignored unless the property is defined.

+   *

+   * The value of the property is insignificant, but values that would imply

+   * misinterpretation ("false", "no") will throw an exception when

+   * evaluated.

+   *

+   * @param propName

+   *            property name

+   */

+  public void setIf(final String propName) {

+    ifCond = propName;

+  }

+

+  /**

+   * Set the property name for the 'unless' condition.

+   *

+   * If named property is set, the define will be ignored.

+   *

+   * The value of the property is insignificant, but values that would imply

+   * misinterpretation ("false", "no") of the behavior will throw an

+   * exception when evaluated.

+   *

+   * @param propName

+   *            name of property

+   */

+  public void setUnless(final String propName) {

+    unlessCond = propName;

+  }

+

+  /**

+   * Gets local directory.

+   * @return local directory, may be null.

+   *

+   */

+  public File getLocal() {

+    return localName;

+  }

+

+  /**

+   * Gets remote name for directory.

+   * @return remote name, may be null.

+   *

+   */

+  public String getRemote() {

+    return remoteName;

+  }

+

+  /**

+   * Converts the local file name to the remote name for the same file.

+   *

+   * @param host host

+   * @param localFile local file

+   * @return remote name for local file, null if unknown.

+   */

+  public String toRemote(final String host, final File localFile) {

+    if (remoteName != null

+        && (hosts == null || hosts.indexOf(host) >= 0)) {

+      try {

+        String canonical = localFile.getCanonicalPath();

+        if (canonical.startsWith(canonicalPath)) {

+          if (isActive()) {

+            return remoteName

+                + canonical.substring(canonicalPath.length()).replace(File.

+                separatorChar, remoteSeparator);

+          }

+        }

+      } catch (IOException ex) {

+        return null;

+      }

+    }

+    return null;

+  }

+

+  /**

+   * Sets local directory for base of mapping.

+   *

+   * @param value value

+   */

+  public void setLocal(final File value)  {

+    if (value == null) {

+      throw new NullPointerException("value");

+    }

+    if (value.exists() && !value.isDirectory()) {

+      throw new BuildException("local should be a directory");

+    }

+    localName = value;

+    try {

+      canonicalPath = localName.getCanonicalPath();

+    } catch (IOException ex) {

+      throw new BuildException(ex);

+    }

+  }

+

+  /**

+   * Sets remote name for directory.

+   * @param value remote name for directory

+   */

+  public void setRemote(final String value) {

+    remoteName = value;

+  }

+

+  /**

+   * Sets the separator character (/ or \) for the remote system.

+   * @param value separator character

+   */

+  public void setRemoteSeparator(final String value)  {

+    if (value != null && value.length() != 1) {

+      throw new BuildException("remote separator must be a single character");

+    }

+    remoteSeparator = value.charAt(0);

+  }

+

+  /**

+   * Sets hosts for which this mapping is valid.

+   *

+   * @param value hosts

+   */

+  public void setHosts(final String value) {

+    hosts = value;

+  }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java
new file mode 100644
index 0000000..5606d47
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/DistributerProtocolEnum.java
@@ -0,0 +1,50 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Distributer prococol names (experimental).

+ *

+ * @author Curt Arnold

+ *

+ */

+public final class DistributerProtocolEnum

+    extends EnumeratedAttribute {

+  /**

+   * Constructor.

+   *

+   * Set by default to "distcc"

+   *

+   * @see java.lang.Object#Object()

+   */

+  public DistributerProtocolEnum() {

+    setValue("distcc");

+  }

+

+  /**

+   * Gets list of acceptable values.

+   *

+   * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+   */

+  public String[] getValues() {

+    return new String[] {

+        "distcc",

+        "ssh"};

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/FileVisitor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/FileVisitor.java
new file mode 100644
index 0000000..24aef25
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/FileVisitor.java
@@ -0,0 +1,27 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * An abstract class implemented to walk over the fileset members of a

+ * ProcessorDef

+ */

+public interface FileVisitor {

+    abstract void visit(File parentDir, String filename) throws BuildException;

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerDef.java
new file mode 100644
index 0000000..d997b2f
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerDef.java
@@ -0,0 +1,549 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+import net.sf.antcontrib.cpptasks.gcc.GccLinker;

+import net.sf.antcontrib.cpptasks.types.FlexLong;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.types.LinkerArgument;

+import net.sf.antcontrib.cpptasks.types.SystemLibrarySet;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.types.FlexInteger;

+/**

+ * A linker definition. linker elements may be placed either as children of a

+ * cc element or the project element. A linker element with an id attribute may

+ * be referenced by linker elements with refid or extends attributes.

+ * 

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public class LinkerDef extends ProcessorDef {

+    private long base;

+    private String entry;

+    private Boolean fixed;

+    private Boolean incremental;

+    private final Vector librarySets = new Vector();

+    private Boolean map;

+    private int stack;

+    private final Vector sysLibrarySets = new Vector();

+    private final Vector versionInfos = new Vector();

+    private Boolean defaultflag = new Boolean(true);

+    /**

+     * Default constructor

+     * 

+     * @see java.lang.Object#Object()

+     */

+    public LinkerDef() {

+        base = -1;

+        stack = -1;

+    }

+    private void addActiveLibrarySet(Project project, Vector libsets,

+            Vector srcSets) {

+        Enumeration srcenum = srcSets.elements();

+        while (srcenum.hasMoreElements()) {

+            LibrarySet set = (LibrarySet) srcenum.nextElement();

+            if (set.isActive(project)) {

+                libsets.addElement(set);

+            }

+        }

+    }

+    private void addActiveSystemLibrarySets(Project project, Vector libsets) {

+        addActiveLibrarySet(project, libsets, sysLibrarySets);

+    }

+    private void addActiveUserLibrarySets(Project project, Vector libsets) {

+        addActiveLibrarySet(project, libsets, librarySets);

+    }

+    /**

+     * Adds a linker command-line arg.

+     */

+    public void addConfiguredLinkerArg(LinkerArgument arg) {

+        addConfiguredProcessorArg(arg);

+    }

+    /**

+     * Adds a compiler command-line arg.

+     */

+    public void addConfiguredLinkerParam(LinkerParam param) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        addConfiguredProcessorParam(param);

+    }

+    /**

+     * Adds a system library set.

+     */

+    public void addLibset(LibrarySet libset) {

+        if (isReference()) {

+            throw super.noChildrenAllowed();

+        }

+        if (libset == null) {

+            throw new NullPointerException("libset");

+        }

+        librarySets.addElement(libset);

+    }

+    /**

+     * Adds a system library set.

+     */

+    public void addSyslibset(SystemLibrarySet libset) {

+        if (isReference()) {

+            throw super.noChildrenAllowed();

+        }

+        if (libset == null) {

+            throw new NullPointerException("libset");

+        }

+        sysLibrarySets.addElement(libset);

+    }

+    

+    /**

+     * Adds desriptive version information to be included in the

+     * generated file.  The first active version info block will

+     * be used.

+     */

+    public void addConfiguredVersioninfo(VersionInfo newVersionInfo) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        newVersionInfo.setProject(this.getProject());

+        versionInfos.addElement(newVersionInfo);

+    }

+    

+    public ProcessorConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef baseDef, TargetDef targetPlatform) {

+        //

+        //    must combine some local context (the linkType)

+        //       with the referenced element

+        //

+        //    get a pointer to the definition (either local or referenced)

+        ProcessorDef thisDef = this;

+        if (isReference()) {

+            thisDef = ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef"));

+        }

+        //

+        //    find the appropriate processor (combines local linkType

+        //       with possibly remote linker name)

+        Processor proc = getProcessor();

+        proc = proc.getLinker(linkType);

+        ProcessorDef[] defaultProviders = getDefaultProviders(baseDef);

+        return proc.createConfiguration(task, linkType, defaultProviders,

+                thisDef, targetPlatform);

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /**

+     * Returns an array of active library sets for this linker definition.

+     */

+    public LibrarySet[] getActiveLibrarySets(LinkerDef[] defaultProviders,

+            int index) {    	

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getActiveUserLibrarySets(defaultProviders, index);

+        }

+        Project p = getProject();

+        Vector libsets = new Vector();

+        for (int i = index; i < defaultProviders.length; i++) {

+            defaultProviders[i].addActiveUserLibrarySets(p, libsets);

+            defaultProviders[i].addActiveSystemLibrarySets(p, libsets);

+        }

+        addActiveUserLibrarySets(p, libsets);

+        addActiveSystemLibrarySets(p, libsets);

+        LibrarySet[] sets = new LibrarySet[libsets.size()];

+        libsets.copyInto(sets);

+        return sets;

+    }

+    /**

+     * Returns an array of active library sets for this linker definition.

+     */

+    public LibrarySet[] getActiveSystemLibrarySets(

+            LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getActiveUserLibrarySets(defaultProviders, index);

+        }

+        Project p = getProject();

+        Vector libsets = new Vector();

+        for (int i = index; i < defaultProviders.length; i++) {

+            defaultProviders[i].addActiveSystemLibrarySets(p, libsets);

+        }

+        addActiveSystemLibrarySets(p, libsets);

+        LibrarySet[] sets = new LibrarySet[libsets.size()];

+        libsets.copyInto(sets);

+        return sets;

+    }

+    /**

+     * Returns an array of active library sets for this linker definition.

+     */

+    public LibrarySet[] getActiveUserLibrarySets(LinkerDef[] defaultProviders,

+            int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getActiveUserLibrarySets(defaultProviders, index);

+        }

+        Project p = getProject();

+        Vector libsets = new Vector();

+        for (int i = index; i < defaultProviders.length; i++) {

+            defaultProviders[i].addActiveUserLibrarySets(p, libsets);

+        }

+        addActiveUserLibrarySets(p, libsets);

+        LibrarySet[] sets = new LibrarySet[libsets.size()];

+        libsets.copyInto(sets);

+        return sets;

+    }

+    public long getBase(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getBase(defaultProviders, index);

+        }

+        if (base <= 0) {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getBase(defaultProviders,

+                        index + 1);

+            }

+        }

+        return base;

+    }

+    public Boolean getFixed(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getFixed(defaultProviders, index);

+        }

+        if (fixed == null) {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getFixed(defaultProviders,

+                        index + 1);

+            }

+        }

+        return fixed;

+    }

+    public boolean getIncremental(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getIncremental(defaultProviders, index);

+        }

+        if (incremental != null) {

+            return incremental.booleanValue();

+        }

+        if (defaultProviders != null && index < defaultProviders.length) {

+            return defaultProviders[index].getIncremental(defaultProviders, index + 1);

+        }

+        return false;

+    }

+    public boolean getMap(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getMap(defaultProviders, index);

+        }

+        if (map != null) {

+            return map.booleanValue();

+        }

+        if (defaultProviders != null && index < defaultProviders.length) {

+            return defaultProviders[index].getMap(defaultProviders, index + 1);

+        }

+        return false;

+    }

+    public final Boolean getDefaultflag(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class,

+                  "LinkerDef")).getDefaultflag(defaultProviders, index);

+        }

+        return defaultflag;

+    }

+    public String getEntry(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getEntry(defaultProviders, index);

+        }

+        if (entry != null) {

+            return entry;

+        }

+        if (defaultProviders != null && index < defaultProviders.length) {

+            return defaultProviders[index].getEntry(defaultProviders, index + 1);

+        }

+        return null;

+    }

+

+    public Processor getProcessor() {

+        Linker linker = (Linker) super.getProcessor();

+        if (linker == null) {

+            linker = GccLinker.getInstance();

+        }

+        if (getLibtool() && linker instanceof CommandLineLinker) {

+            CommandLineLinker cmdLineLinker = (CommandLineLinker) linker;

+            linker = cmdLineLinker.getLibtoolLinker();

+        }

+        return linker;

+    }

+    public int getStack(LinkerDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))

+                    .getStack(defaultProviders, index);

+        }

+        if (stack < 0) {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getStack(defaultProviders,

+                        index + 1);

+            }

+        }

+        return stack;

+    }

+    /**

+     * Sets the base address. May be specified in either decimal or hex.

+     * 

+     * @param base

+     *            base address

+     *  

+     */

+    public void setBase(FlexLong base) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.base = base.longValue();

+    }

+    /**

+     * Sets the starting address.

+     * 

+     * @param name

+     *            function name

+     */

+    public void setEntry(String entry) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.entry = entry;

+    }

+    /**

+     * If true, marks the file to be loaded only at its preferred address.

+     */

+    public void setFixed(boolean fixed) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.fixed = booleanValueOf(fixed);

+    }

+    /**

+     * If true, allows incremental linking.

+     *  

+     */

+    public void setIncremental(boolean incremental) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.incremental = booleanValueOf(incremental);

+    }

+    /**

+     * If set to true, a map file will be produced.

+     */

+    public void setMap(boolean map) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.map = booleanValueOf(map);

+    }

+    /**

+     * Sets linker type.

+     * 

+     * 

+     * <table width="100%" border="1"> <thead>Supported linkers </thead>

+     * <tr>

+     * <td>gcc</td>

+     * <td>Gcc Linker</td>

+     * </tr>

+     * <tr>

+     * <td>g++</td>

+     * <td>G++ Linker</td>

+     * </tr>

+     * <tr>

+     * <td>ld</td>

+     * <td>Ld Linker</td>

+     * </tr>

+     * <tr>

+     * <td>ar</td>

+     * <td>Gcc Librarian</td>

+     * </tr>

+     * <tr>

+     * <td>msvc</td>

+     * <td>Microsoft Linker</td>

+     * </tr>

+     * <tr>

+     * <td>bcc</td>

+     * <td>Borland Linker</td>

+     * </tr>

+     * <tr>

+     * <td>df</td>

+     * <td>Compaq Visual Fortran Linker</td>

+     * </tr>

+     * <tr>

+     * <td>icl</td>

+     * <td>Intel Linker for Windows (IA-32)</td>

+     * </tr>

+     * <tr>

+     * <td>ecl</td>

+     * <td>Intel Linker for Windows (IA-64)</td>

+     * </tr>

+     * <tr>

+     * <td>icc</td>

+     * <td>Intel Linker for Linux (IA-32)</td>

+     * </tr>

+     * <tr>

+     * <td>ecc</td>

+     * <td>Intel Linker for Linux (IA-64)</td>

+     * </tr>

+     * <tr>

+     * <td>CC</td>

+     * <td>Sun ONE Linker</td>

+     * </tr>

+     * <tr>

+     * <td>aCC</td>

+     * <td>HP aC++ Linker</td>

+     * </tr>

+     * <tr>

+     * <td>os390</td>

+     * <td>OS390 Linker</td>

+     * </tr>

+     * <tr>

+     * <td>os390batch</td>

+     * <td>OS390 Linker</td>

+     * </tr>

+     * <tr>

+     * <td>os400</td>

+     * <td>IccLinker</td>

+     * </tr>

+     * <tr>

+     * <td>sunc89</td>

+     * <td>C89 Linker</td>

+     * </tr>

+     * <tr>

+     * <td>xlC</td>

+     * <td>VisualAge Linker</td>

+     * </tr>

+     * </table>

+     *  

+     */

+    public void setName(LinkerEnum name) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        Linker linker = name.getLinker();

+        super.setProcessor(linker);

+    }

+    protected void setProcessor(Processor proc) throws BuildException {

+        Linker linker = null;

+        if (proc instanceof Linker) {

+            linker = (Linker) proc;

+        } else {

+            LinkType linkType = new LinkType();

+            linker = proc.getLinker(linkType);

+        }

+        super.setProcessor(linker);

+    }

+    /**

+     * Sets stack size in bytes.

+     */

+    public void setStack(FlexInteger stack) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.stack = stack.intValue();

+    }

+    public void visitSystemLibraries(Linker linker, FileVisitor libraryVisitor) {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class,

+                    "Linker"));

+            master.visitSystemLibraries(linker, libraryVisitor);

+        } else {

+            //

+            //   if this linker extends another,

+            //      visit its libraries first

+            //

+            LinkerDef extendsDef = (LinkerDef) getExtends();

+            if (extendsDef != null) {

+                extendsDef.visitSystemLibraries(linker, libraryVisitor);

+            }

+            if (sysLibrarySets.size() > 0) {

+                File[] libpath = linker.getLibraryPath();

+                for (int i = 0; i < sysLibrarySets.size(); i++) {

+                    LibrarySet set = (LibrarySet) sysLibrarySets.elementAt(i);

+                    if (set.isActive(p)) {

+                        set.visitLibraries(p, linker, libpath,

+                                libraryVisitor);

+                    }

+                }

+            }

+        }

+    }

+    public void visitUserLibraries(Linker linker, FileVisitor libraryVisitor) {

+    	Project p = getProject();

+    	if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class,

+                    "Linker"));

+            master.visitUserLibraries(linker, libraryVisitor);

+        } else {

+            //

+            //   if this linker extends another,

+            //      visit its libraries first

+            //

+            LinkerDef extendsDef = (LinkerDef) getExtends();

+            if (extendsDef != null) {

+                extendsDef.visitUserLibraries(linker, libraryVisitor);

+            }

+            //

+            //   visit the user libraries

+            //

+            if (librarySets.size() > 0) {

+                File[] libpath = linker.getLibraryPath();

+                for (int i = 0; i < librarySets.size(); i++) {

+                    LibrarySet set = (LibrarySet) librarySets.elementAt(i);

+                    if (set.isActive(p)) {

+                        set.visitLibraries(p, linker, libpath,

+                                libraryVisitor);

+                    }

+                }

+            }

+        }

+    }

+    /**

+     * Enables or disables default flags.

+     * 

+     * @param defaultflag

+     *            if true, default flags will add to command line.

+     *  

+     */

+    public void setDefaultflag(boolean defaultflag) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.defaultflag = booleanValueOf(defaultflag);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerEnum.java
new file mode 100644
index 0000000..cfe8984
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerEnum.java
@@ -0,0 +1,106 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import net.sf.antcontrib.cpptasks.arm.ADSLinker;

+import net.sf.antcontrib.cpptasks.borland.BorlandLinker;

+import net.sf.antcontrib.cpptasks.compaq.CompaqVisualFortranLinker;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker;

+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;

+import net.sf.antcontrib.cpptasks.gcc.GccLinker;

+import net.sf.antcontrib.cpptasks.gcc.GppLinker;

+import net.sf.antcontrib.cpptasks.gcc.LdLinker;

+import net.sf.antcontrib.cpptasks.hp.aCCLinker;

+import net.sf.antcontrib.cpptasks.ibm.VisualAgeLinker;

+import net.sf.antcontrib.cpptasks.intel.IntelLinux32Linker;

+import net.sf.antcontrib.cpptasks.intel.IntelLinux64Linker;

+import net.sf.antcontrib.cpptasks.intel.IntelWin32Linker;

+import net.sf.antcontrib.cpptasks.os390.OS390Linker;

+import net.sf.antcontrib.cpptasks.os400.IccLinker;

+import net.sf.antcontrib.cpptasks.sun.C89Linker;

+import net.sf.antcontrib.cpptasks.sun.ForteCCLinker;

+import net.sf.antcontrib.cpptasks.ti.ClxxLinker;

+import org.apache.tools.ant.types.EnumeratedAttribute;

+/**

+ * Enumeration of supported linkers

+ * 

+ * @author Curt Arnold

+ *  

+ */

+public class LinkerEnum extends EnumeratedAttribute {

+    private final static ProcessorEnumValue[] linkers = new ProcessorEnumValue[]{

+            new ProcessorEnumValue("gcc", GccLinker.getInstance()),

+            new ProcessorEnumValue("g++", GppLinker.getInstance()),

+            new ProcessorEnumValue("ld", LdLinker.getInstance()),

+            new ProcessorEnumValue("ar", GccLibrarian.getInstance()),

+            new ProcessorEnumValue("msvc", DevStudioLinker.getInstance()),

+            new ProcessorEnumValue("bcc", BorlandLinker.getInstance()),

+            new ProcessorEnumValue("df", CompaqVisualFortranLinker

+                    .getInstance()),

+            new ProcessorEnumValue("icl", IntelWin32Linker.getInstance()),

+            new ProcessorEnumValue("ecl", IntelWin32Linker.getInstance()),

+            new ProcessorEnumValue("icc", IntelLinux32Linker.getInstance()),

+            new ProcessorEnumValue("ecc", IntelLinux64Linker.getInstance()),

+            new ProcessorEnumValue("CC", ForteCCLinker.getInstance()),

+            new ProcessorEnumValue("aCC", aCCLinker.getInstance()),

+            new ProcessorEnumValue("os390", OS390Linker.getInstance()),

+            new ProcessorEnumValue("os390batch", OS390Linker

+                    .getDataSetInstance()),

+            new ProcessorEnumValue("os400", IccLinker.getInstance()),

+            new ProcessorEnumValue("sunc89", C89Linker.getInstance()),

+            new ProcessorEnumValue("xlC", VisualAgeLinker.getInstance()),

+            new ProcessorEnumValue("cl6x", ClxxLinker.getCl6xInstance()),

+            new ProcessorEnumValue("cl55", ClxxLinker.getCl55Instance()),

+            new ProcessorEnumValue("armcc", ADSLinker.getInstance()),

+            new ProcessorEnumValue("armcpp", ADSLinker.getInstance()),

+            new ProcessorEnumValue("tcc", ADSLinker.getInstance()),

+            new ProcessorEnumValue("tcpp", ADSLinker.getInstance()),

+            // gcc cross compilers

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-gcc",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccLinker

+                            .getInstance()),

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-g++",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GppLinker

+                            .getInstance()),

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-ld",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.LdLinker

+                            .getInstance()),

+            new ProcessorEnumValue(

+                    "sparc-sun-solaris2-ar",

+                    net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2.GccLibrarian

+                            .getInstance()),

+            new ProcessorEnumValue("gcc-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GccLinker

+                            .getInstance()),

+            new ProcessorEnumValue("g++-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GppLinker

+                            .getInstance()),

+            new ProcessorEnumValue("ld-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.LdLinker.getInstance()),

+            new ProcessorEnumValue("ar-cross",

+                    net.sf.antcontrib.cpptasks.gcc.cross.GccLibrarian

+                            .getInstance()),};

+    public Linker getLinker() {

+        return (Linker) linkers[getIndex()].getProcessor();

+    }

+    public String[] getValues() {

+        return ProcessorEnumValue.getValues(linkers);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerParam.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerParam.java
new file mode 100644
index 0000000..383bae5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/LinkerParam.java
@@ -0,0 +1,33 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+/*******************************************************************************

+ * Place class description here.

+ * 

+ * @author inger

+ * @author <additional author>

+ * 

+ * @since  

+ ******************************************************************************/

+public class LinkerParam extends ProcessorParam {

+    public LinkerParam() {

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OSFamilyEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OSFamilyEnum.java
new file mode 100644
index 0000000..536d992
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OSFamilyEnum.java
@@ -0,0 +1,59 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Enumeration of cpu types.

+ *

+ * @author Curt Arnold

+ *

+ */

+public final class OSFamilyEnum

+    extends EnumeratedAttribute {

+  /**

+   * Constructor.

+   *

+   * Set by default to "pentium3"

+   *

+   * @see java.lang.Object#Object()

+   */

+  public OSFamilyEnum() {

+    setValue("windows");

+  }

+

+  /**

+   * Gets list of acceptable values.

+   *

+   * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+   */

+  public String[] getValues() {

+    return new String[] {

+        "windows",

+        "dos",

+        "mac",

+        "unix",

+        "netware",

+        "os/2",

+        "tandem",

+        "win9x",

+        "z/os",

+        "os/400",

+        "openvms"};

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ObjectFileCollector.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ObjectFileCollector.java
new file mode 100644
index 0000000..3e97fa4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ObjectFileCollector.java
@@ -0,0 +1,42 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Collects object files for the link step.

+ * 

+ *  

+ */

+public final class ObjectFileCollector implements FileVisitor {

+    private final Vector files;

+    private final Linker linker;

+    public ObjectFileCollector(Linker linker, Vector files) {

+        this.linker = linker;

+        this.files = files;

+    }

+    public void visit(File parentDir, String filename) throws BuildException {

+        int bid = linker.bid(filename);

+        if (bid >= 1) {

+            files.addElement(new File(parentDir, filename));

+        }

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OptimizationEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OptimizationEnum.java
new file mode 100644
index 0000000..4a0d179
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OptimizationEnum.java
@@ -0,0 +1,82 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+

+/**

+ * Enumeration of optimization levels (experimental).

+ *

+ * @author Curt Arnold

+ *

+ */

+public final class OptimizationEnum

+    extends EnumeratedAttribute {

+  /**

+   * Constructor.

+   *

+   * Set by default to "speed"

+   *

+   * @see java.lang.Object#Object()

+   */

+  public OptimizationEnum() {

+    setValue("speed");

+  }

+

+  /**

+   * Gets list of acceptable values.

+   *

+   * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+   */

+  public String[] getValues() {

+    return new String[] {

+        "none",

+        "size",

+        "minimal",

+        "speed",

+        "full",

+        "aggressive",

+        "extreme",

+        "unsafe"

+    };

+  }

+

+  /**

+   * Is size optimized.

+   * @return boolean true if size is optimized.

+   */

+  public boolean isSize() {

+    return "speed".equals(getValue());

+  }

+

+  /**

+   * Is speed optimized.

+   * @return boolean true if speed is optimized.

+   */

+  public boolean isSpeed() {

+    return !isSize() && !isNoOptimization();

+  }

+

+  /**

+   * Is no optimization performed.

+   * @return boolean true if no optimization is performed.

+   */

+  public boolean isNoOptimization() {

+    return "none".equals(getValue());

+  }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OutputTypeEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OutputTypeEnum.java
new file mode 100644
index 0000000..fb37843
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/OutputTypeEnum.java
@@ -0,0 +1,48 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import org.apache.tools.ant.types.EnumeratedAttribute;

+/**

+ * Enumeration of supported subsystems

+ * 

+ * @author Curt Arnold

+ *  

+ */

+public class OutputTypeEnum extends EnumeratedAttribute {

+    /**

+     * Constructor

+     * 

+     * Set by default to "executable"

+     * 

+     * @see java.lang.Object#Object()

+     */

+    public OutputTypeEnum() {

+        setValue("executable");

+    }

+    /**

+     * Gets list of acceptable values

+     * 

+     * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+     */

+    public String[] getValues() {

+        return new String[]{"executable", // executable program

+                "plugin", // plugin module

+                "shared", // dynamically linkable module

+                "static" // convenience library

+        };

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/PrecompileDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/PrecompileDef.java
new file mode 100644
index 0000000..828e2c2
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/PrecompileDef.java
@@ -0,0 +1,215 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;

+

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.DirectoryScanner;

+import org.apache.tools.ant.types.DataType;

+/**

+ * An element that specifies a prototype file and rules for source files that

+ * should not use precompiled headers

+ * 

+ * @author Curt Arnold

+ */

+public final class PrecompileDef extends DataType {

+    private final Vector exceptSets = new Vector();

+    private String ifCond;

+    /**

+     * Directory of prototype file

+     */

+    private File prototype = new File("stdafx.cpp");

+    private String unlessCond;

+    /**

+     * Constructor

+     *  

+     */

+    public PrecompileDef() {

+    }

+    /**

+     * Method used by PrecompileExceptDef to add exception set to

+     * PrecompileDef.

+     */

+    public void appendExceptFileSet(ConditionalFileSet exceptSet) {

+        exceptSet.setProject(getProject());

+        exceptSets.addElement(exceptSet);

+    }

+    /**

+     * Adds filesets that specify files that should not be processed with

+     * precompiled headers enabled.

+     * 

+     * @param exceptSet

+     *            FileSet specify files that should not be processed with

+     *            precompiled headers enabled.

+     */

+    public PrecompileExceptDef createExcept() {

+        return new PrecompileExceptDef(this);

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    public String[] getExceptFiles() {

+        PrecompileDef ref = getRef();

+        if (ref != null) {

+            return ref.getExceptFiles();

+        }

+        if (exceptSets.size() == 0) {

+            return new String[0];

+        }

+        Project p = getProject();

+        String[] exceptFiles = null;

+        Enumeration setEnum = exceptSets.elements();

+        while (setEnum.hasMoreElements()) {

+            ConditionalFileSet exceptSet = (ConditionalFileSet) setEnum

+                    .nextElement();

+            if (exceptSet.isActive()) {

+                DirectoryScanner scanner = exceptSet

+                        .getDirectoryScanner(p);

+                String[] scannerFiles = scanner.getIncludedFiles();

+                if (exceptFiles == null) {

+                    exceptFiles = scannerFiles;

+                } else {

+                    if (scannerFiles.length > 0) {

+                        String[] newFiles = new String[exceptFiles.length

+                                + scannerFiles.length];

+                        for (int i = 0; i < exceptFiles.length; i++) {

+                            newFiles[i] = exceptFiles[i];

+                        }

+                        int index = exceptFiles.length;

+                        for (int i = 0; i < scannerFiles.length; i++) {

+                            newFiles[index++] = scannerFiles[i];

+                        }

+                        exceptFiles = newFiles;

+                    }

+                }

+            }

+        }

+        if (exceptFiles == null) {

+            exceptFiles = new String[0];

+        }

+        return exceptFiles;

+    }

+    /**

+     * Gets prototype source file

+     *  

+     */

+    public File getPrototype() {

+        PrecompileDef ref = getRef();

+        if (ref != null) {

+            return ref.getPrototype();

+        }

+        return prototype;

+    }

+    private PrecompileDef getRef() {

+        if (isReference()) {

+            return ((PrecompileDef) getCheckedRef(PrecompileDef.class,

+                    "PrecompileDef"));

+        }

+        return null;

+    }

+    public boolean isActive() {    	

+        boolean isActive = CUtil.isActive(getProject(), ifCond, unlessCond);

+        if (!isActive) {

+            PrecompileDef ref = getRef();

+            if (ref != null) {

+                return ref.isActive();

+            }

+        }

+        return isActive;

+    }

+    /**

+     * Sets a description of the current data type.

+     */

+    public void setDescription(String desc) {

+        super.setDescription(desc);

+    }

+    /**

+     * Sets an id that can be used to reference this element.

+     * 

+     * @param id

+     *            id

+     */

+    public void setId(String id) {

+        //

+        //  this is actually accomplished by a different

+        //     mechanism, but we can document it

+        //

+    }

+    /**

+     * Set the 'if' condition.

+     * 

+     * The processor will be ignored unless the property is defined.

+     * 

+     * The value of property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * isActive() is evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Sets file to precompile.

+     * 

+     * Should be a source file that includes only one unguarded header file.

+     * Default value is "stdafx.cpp".

+     * 

+     * @param prototype

+     *            file path for prototype source file

+     */

+    public void setPrototype(File prototype) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        if (prototype == null) {

+            throw new NullPointerException("prototype");

+        }

+        this.prototype = prototype;

+    }

+    /**

+     * Specifies that this element should behave as if the content of the

+     * element with the matching id attribute was inserted at this location.

+     * 

+     * @param ref

+     *            Reference to other element

+     *  

+     */

+    public void setRefid(org.apache.tools.ant.types.Reference ref) {

+        super.setRefid(ref);

+    }

+    /**

+     * Set the 'unless' condition. If named property exists at execution time,

+     * the processor will be ignored.

+     * 

+     * Value of property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when isActive is called.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessCond = propName;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java
new file mode 100644
index 0000000..d6cdd60
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/PrecompileExceptDef.java
@@ -0,0 +1,80 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Specifies files that should not be compiled using precompiled headers.

+ * 

+ * @author Curt Arnold

+ */

+public final class PrecompileExceptDef {

+    private ConditionalFileSet localSet = null;

+    /**

+     * Collection of <fileset>contained by definition

+     */

+    private PrecompileDef owner;

+    /**

+     * Constructor

+     *  

+     */

+    public PrecompileExceptDef(PrecompileDef owner) {

+        this.owner = owner;

+    }

+    /**

+     * Adds filesets that specify files that should not be processed using

+     * precompiled headers.

+     * 

+     * @param exceptSet

+     *            FileSet specify files that should not be processed with

+     *            precompiled headers enabled.

+     */

+    public void addFileset(ConditionalFileSet exceptSet) {

+        owner.appendExceptFileSet(exceptSet);

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /**

+     * Sets the base-directory

+     */

+    public void setDir(File dir) throws BuildException {

+        if (localSet == null) {

+            localSet = new ConditionalFileSet();

+            owner.appendExceptFileSet(localSet);

+        }

+        localSet.setDir(dir);

+    }

+    /**

+     * Comma or space separated list of file patterns that should not be

+     * compiled using precompiled headers.

+     * 

+     * @param includes

+     *            the string containing the include patterns

+     */

+    public void setIncludes(String includes) {

+        if (localSet == null) {

+            localSet = new ConditionalFileSet();

+            owner.appendExceptFileSet(localSet);

+        }

+        localSet.setIncludes(includes);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorDef.java
new file mode 100644
index 0000000..38faf42
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorDef.java
@@ -0,0 +1,714 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.lang.reflect.Method;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.DirectoryScanner;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.types.DataType;

+import org.apache.tools.ant.types.Environment;

+import org.apache.tools.ant.types.Reference;

+/**

+ * An abstract compiler/linker definition.

+ * 

+ * @author Curt Arnold

+ */

+public abstract class ProcessorDef extends DataType {

+    /**

+     * Returns the equivalent Boolean object for the specified value

+     * 

+     * Equivalent to Boolean.valueOf in JDK 1.4

+     * 

+     * @param val

+     *            boolean value

+     * @return Boolean.TRUE or Boolean.FALSE

+     */

+    protected static Boolean booleanValueOf(boolean val) {

+        if (val) {

+            return Boolean.TRUE;

+        }

+        return Boolean.FALSE;

+    }

+    /**

+     * if true, targets will be built for debugging

+     */

+    private Boolean debug;

+    private Environment env = null;

+    /**

+     * Reference for "extends" processor definition

+     */

+    private Reference extendsRef = null;

+    /**

+     * Name of property that must be present or definition will be ignored. May

+     * be null.

+     */

+    private String ifProp;

+    /**

+     * if true, processor definition inherits values from containing <cc>

+     * element

+     */

+    private boolean inherit;

+    private Boolean libtool = null;

+    protected boolean newEnvironment = false;

+    /**

+     * Processor.

+     */

+    private Processor processor;

+    /**

+     * Collection of <compilerarg>or <linkerarg>contained by definition

+     */

+    private final Vector processorArgs = new Vector();

+    /**

+     * Collection of <compilerparam>or <linkerparam>contained by definition

+     */

+    private final Vector processorParams = new Vector();

+    /**

+     * if true, all targets will be unconditionally rebuilt

+     */

+    private Boolean rebuild;

+    /**

+     * Collection of <fileset>contained by definition

+     */

+    private final Vector srcSets = new Vector();

+    /**

+     * Name of property that if present will cause definition to be ignored.

+     * May be null.

+     */

+    private String unlessProp;

+    /**

+     * Constructor

+     *  

+     */

+    protected ProcessorDef() throws NullPointerException {

+        inherit = true;

+    }

+    /**

+     * Adds a <compilerarg>or <linkerarg>

+     * 

+     * @param arg

+     *            command line argument, must not be null

+     * @throws NullPointerException

+     *             if arg is null

+     * @throws BuildException

+     *             if this definition is a reference

+     */

+    protected void addConfiguredProcessorArg(CommandLineArgument arg)

+            throws NullPointerException, BuildException {

+        if (arg == null) {

+            throw new NullPointerException("arg");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        if(arg.getFile() == null ) {

+            processorArgs.addElement(arg);

+        }

+        else {

+            loadFile(arg.getFile());

+        }

+    }

+    /**

+     * Add a <compilerarg>or <linkerarg> if specify the file attribute

+     * 

+     * @param arg

+     *            command line argument, must not be null

+     * @throws BuildException

+     *             if the specify file not exist

+     */

+    protected void loadFile(File file)

+        throws BuildException {

+        FileReader fileReader;

+        BufferedReader in;

+        String str;

+        if (! file.exists()){

+            throw new BuildException("The file " + file + " is not existed");

+        }

+        try {

+            fileReader = new FileReader(file);

+            in = new BufferedReader(fileReader);

+            while ( (str = in.readLine()) != null ){                

+                if(str.trim() == ""){

+                    continue ;

+                }

+                str = getProject().replaceProperties(str);

+                CommandLineArgument newarg = new CommandLineArgument();

+                newarg.setValue(str.trim());

+                processorArgs.addElement(newarg);

+            }

+        }

+        catch(Exception e){

+            throw new BuildException(e.getMessage());

+        }

+    }

+    /**

+     * Adds a <compilerarg>or <linkerarg>

+     * 

+     * @param arg

+     *            command line argument, must not be null

+     * @throws NullPointerException

+     *             if arg is null

+     * @throws BuildException

+     *             if this definition is a reference

+     */

+    protected void addConfiguredProcessorParam(ProcessorParam param)

+            throws NullPointerException, BuildException {

+        if (param == null) {

+            throw new NullPointerException("param");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        processorParams.addElement(param);

+    }

+    /**

+     * Add an environment variable to the launched process.

+     */

+    public void addEnv(Environment.Variable var) {

+        if (env == null) {

+            env = new Environment();

+        }

+        env.addVariable(var);

+    }

+    /**

+     * Adds a source file set.

+     * 

+     * Files in these set will be processed by this configuration and will not

+     * participate in the auction.

+     * 

+     * @param srcSet

+     *            Fileset identifying files that should be processed by this

+     *            processor

+     * @throws BuildException

+     *             if processor definition is a reference

+     */

+    public void addFileset(ConditionalFileSet srcSet) throws BuildException {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        srcSet.setProject(getProject());

+        srcSets.addElement(srcSet);

+    }

+    /**

+     * Creates a configuration

+     * 

+     * @param baseDef

+     *            reference to def from containing <cc>element, may be null

+     * @return configuration

+     *  

+     */

+    public ProcessorConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef baseDef, TargetDef targetPlatform) {

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).createConfiguration(task, linkType,

+                    baseDef, targetPlatform);

+        }

+        ProcessorDef[] defaultProviders = getDefaultProviders(baseDef);

+        Processor proc = getProcessor();

+        return proc.createConfiguration(task, linkType, defaultProviders, this, targetPlatform);

+    }

+    /**

+     * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that

+     * are active for the current project settings.

+     * 

+     * @return active compiler arguments

+     */

+    public CommandLineArgument[] getActiveProcessorArgs() {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getActiveProcessorArgs();

+        }

+        Vector activeArgs = new Vector(processorArgs.size());

+        for (int i = 0; i < processorArgs.size(); i++) {

+            CommandLineArgument arg = (CommandLineArgument) processorArgs

+                    .elementAt(i);

+            if (arg.isActive(p)) {

+                activeArgs.addElement(arg);

+            }

+        }

+        CommandLineArgument[] array = new CommandLineArgument[activeArgs.size()];

+        activeArgs.copyInto(array);

+        return array;

+    }

+    /**

+     * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that

+     * are active for the current project settings.

+     * 

+     * @return active compiler arguments

+     */

+    public ProcessorParam[] getActiveProcessorParams() {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getActiveProcessorParams();

+        }

+        Vector activeParams = new Vector(processorParams.size());

+        for (int i = 0; i < processorParams.size(); i++) {

+            ProcessorParam param = (ProcessorParam) processorParams

+                    .elementAt(i);

+            if (param.isActive(p)) {

+                activeParams.addElement(param);

+            }

+        }

+        ProcessorParam[] array = new ProcessorParam[activeParams.size()];

+        activeParams.copyInto(array);

+        return array;

+    }

+    /**

+     * Gets boolean indicating debug build

+     * 

+     * @param defaultProviders

+     *            array of ProcessorDef's in descending priority

+     * @param index

+     *            index to first element in array that should be considered

+     * @return if true, built targets for debugging

+     */

+    public boolean getDebug(ProcessorDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getDebug(defaultProviders, index);

+        }

+        if (debug != null) {

+            return debug.booleanValue();

+        } else {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getDebug(defaultProviders,

+                        index + 1);

+            }

+        }

+        return false;

+    }

+    /**

+     * Creates an chain of objects which provide default values in descending

+     * order of significance.

+     * 

+     * @param baseDef

+     *            corresponding ProcessorDef from CCTask, will be last element

+     *            in array unless inherit = false

+     * @return default provider array

+     *  

+     */

+    protected final ProcessorDef[] getDefaultProviders(ProcessorDef baseDef) {

+        ProcessorDef extendsDef = getExtends();

+        Vector chain = new Vector();

+        while (extendsDef != null && !chain.contains(extendsDef)) {

+            chain.addElement(extendsDef);

+            extendsDef = extendsDef.getExtends();

+        }

+        if (baseDef != null && getInherit()) {

+            chain.addElement(baseDef);

+        }

+        ProcessorDef[] defaultProviders = new ProcessorDef[chain.size()];

+        chain.copyInto(defaultProviders);

+        return defaultProviders;

+    }

+    /**

+     * Gets the ProcessorDef specified by the extends attribute

+     * 

+     * @return Base ProcessorDef, null if extends is not specified

+     * @throws BuildException

+     *             if reference is not same type object

+     */

+    public ProcessorDef getExtends() throws BuildException {

+        if (extendsRef != null) {

+            Object obj = extendsRef.getReferencedObject(getProject());

+            if (!getClass().isInstance(obj)) {

+                throw new BuildException("Referenced object "

+                        + extendsRef.getRefId() + " not correct type, is "

+                        + obj.getClass().getName() + " should be "

+                        + getClass().getName());

+            }

+            return (ProcessorDef) obj;

+        }

+        return null;

+    }

+    /**

+     * Gets the inherit attribute. If the inherit value is true, this processor

+     * definition will inherit default values from the containing <cc>element.

+     * 

+     * @return if true then properties from the containing <cc>element are

+     *         used.

+     */

+    public final boolean getInherit() {

+        return inherit;

+    }

+    public boolean getLibtool() {

+        if (libtool != null) {

+            return libtool.booleanValue();

+        }

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getLibtool();

+        }

+        ProcessorDef extendsDef = getExtends();

+        if (extendsDef != null) {

+            return extendsDef.getLibtool();

+        }

+        return false;

+    }

+    /**

+     * Obtains the appropriate processor (compiler, linker)

+     * 

+     * @return processor

+     */

+    protected Processor getProcessor() {

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getProcessor();

+        }

+        //

+        //   if a processor has not been explicitly set

+        //      then may be set by an extended definition

+        if (processor == null) {

+            ProcessorDef extendsDef = getExtends();

+            if (extendsDef != null) {

+                return extendsDef.getProcessor();

+            }

+        }

+        return processor;

+    }

+    /**

+     * Gets a boolean value indicating whether all targets must be rebuilt

+     * regardless of dependency analysis.

+     * 

+     * @param defaultProviders

+     *            array of ProcessorDef's in descending priority

+     * @param index

+     *            index to first element in array that should be considered

+     * @return true if all targets should be rebuilt.

+     */

+    public boolean getRebuild(ProcessorDef[] defaultProviders, int index) {

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getRebuild(defaultProviders, index);

+        }

+        if (rebuild != null) {

+            return rebuild.booleanValue();

+        } else {

+            if (defaultProviders != null && index < defaultProviders.length) {

+                return defaultProviders[index].getRebuild(defaultProviders,

+                        index + 1);

+            }

+        }

+        return false;

+    }

+    /**

+     * Returns true if the processor definition contains embedded file set

+     * definitions

+     * 

+     * @return true if processor definition contains embedded filesets

+     */

+    public boolean hasFileSets() {

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).hasFileSets();

+        }

+        return srcSets.size() > 0;

+    }

+    /**

+     * Determine if this def should be used.

+     * 

+     * Definition will be active if the "if" variable (if specified) is set and

+     * the "unless" variable (if specified) is not set and that all reference

+     * or extended definitions are active

+     * 

+     * @return true if processor is active

+     * @throws IllegalStateException

+     *             if not properly initialized

+     * @throws BuildException

+     *             if "if" or "unless" variable contains suspicious values

+     *             "false" or "no" which indicates possible confusion

+     */

+    public boolean isActive() throws BuildException, IllegalStateException {

+        Project project = getProject();

+        if (!CUtil.isActive(project, ifProp, unlessProp)) {

+            return false;

+        }

+        if (isReference()) {

+            if (!((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).isActive()) {

+                return false;

+            }

+        }

+        //

+        //  walk through any extended definitions

+        //

+        ProcessorDef[] defaultProviders = getDefaultProviders(null);

+        for (int i = 0; i < defaultProviders.length; i++) {

+            if (!defaultProviders[i].isActive()) {

+                return false;

+            }

+        }

+        return true;

+    }

+    /**

+     * Sets the class name for the adapter. Use the "name" attribute when the

+     * tool is supported.

+     * 

+     * @param className

+     *            full class name

+     *  

+     */

+    public void setClassname(String className) throws BuildException {

+        Object proc = null;

+        try {

+            Class implClass = ProcessorDef.class.getClassLoader().loadClass(

+                    className);

+            try {

+                Method getInstance = implClass.getMethod("getInstance",

+                        new Class[0]);

+                proc = getInstance.invoke(null, new Object[0]);

+            } catch (Exception ex) {

+                proc = implClass.newInstance();

+            }

+        } catch (Exception ex) {

+            throw new BuildException(ex);

+        }

+        setProcessor((Processor) proc);

+    }

+    /**

+     * If set true, all targets will be built for debugging.

+     * 

+     * @param debug

+     *            true if targets should be built for debugging

+     * @throws BuildException

+     *             if processor definition is a reference

+     */

+    public void setDebug(boolean debug) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.debug = booleanValueOf(debug);

+    }

+    /**

+     * Sets a description of the current data type.

+     */

+    public void setDescription(String desc) {

+        super.setDescription(desc);

+    }

+    /**

+     * Specifies that this element extends the element with id attribute with a

+     * matching value. The configuration will be constructed from the settings

+     * of this element, element referenced by extends, and the containing cc

+     * element.

+     * 

+     * @param extendsRef

+     *            Reference to the extended processor definition.

+     * @throws BuildException

+     *             if this processor definition is a reference

+     */

+    public void setExtends(Reference extendsRef) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.extendsRef = extendsRef;

+    }

+    /**

+     * Sets an id that can be used to reference this element.

+     * 

+     * @param id

+     *            id

+     */

+    public void setId(String id) {

+        //

+        //  this is actually accomplished by a different

+        //     mechanism, but we can document it

+        //

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The configuration will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setIf(String propName) {

+        ifProp = propName;

+    }

+    /**

+     * If inherit has the default value of true, defines, includes and other

+     * settings from the containing <cc>element will be inherited.

+     * 

+     * @param inherit

+     *            new value

+     * @throws BuildException

+     *             if processor definition is a reference

+     */

+    public void setInherit(boolean inherit) throws BuildException {

+        if (isReference()) {

+            throw super.tooManyAttributes();

+        }

+        this.inherit = inherit;

+    }

+    /**

+     * Set use of libtool.

+     * 

+     * If set to true, the "libtool " will be prepended to the command line

+     * 

+     * @param libtool

+     *            If true, use libtool.

+     */

+    public void setLibtool(boolean libtool) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.libtool = booleanValueOf(libtool);

+    }

+    /**

+     * Do not propagate old environment when new environment variables are

+     * specified.

+     */

+    public void setNewenvironment(boolean newenv) {

+        newEnvironment = newenv;

+    }

+    /**

+     * Sets the processor

+     * 

+     * @param processor

+     *            processor, may not be null.

+     * @throws BuildException

+     *             if ProcessorDef is a reference

+     * @throws NullPointerException

+     *             if processor is null

+     */

+    protected void setProcessor(Processor processor) throws BuildException,

+            NullPointerException {

+        if (processor == null) {

+            throw new NullPointerException("processor");

+        }

+        if (isReference()) {

+            throw super.tooManyAttributes();

+        }

+        if (env == null && !newEnvironment) {

+            this.processor = processor;

+        } else {

+            this.processor = processor.changeEnvironment(newEnvironment, env);

+        }

+    }

+    /**

+     * If set true, all targets will be unconditionally rebuilt.

+     * 

+     * @param rebuild

+     *            if true, rebuild all targets.

+     * @throws BuildException

+     *             if processor definition is a reference

+     */

+    public void setRebuild(boolean rebuild) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.rebuild = booleanValueOf(rebuild);

+    }

+    /**

+     * Specifies that this element should behave as if the content of the

+     * element with the matching id attribute was inserted at this location. If

+     * specified, no other attributes or child content should be specified,

+     * other than "if", "unless" and "description".

+     * 

+     * @param ref

+     *            Reference to other element

+     *  

+     */

+    public void setRefid(org.apache.tools.ant.types.Reference ref) {

+        super.setRefid(ref);

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the configuration will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessProp = propName;

+    }

+    /**

+     * This method calls the FileVistor's visit function for every file in the

+     * processors definition

+     * 

+     * @param visitor

+     *            object whose visit method is called for every file

+     */

+    public void visitFiles(FileVisitor visitor) {

+    	Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException(

+                    "project must be set before this call");

+        }

+        if (isReference()) {

+            ((ProcessorDef) getCheckedRef(ProcessorDef.class, "ProcessorDef"))

+                    .visitFiles(visitor);

+        }

+        //

+        //   if this processor extends another,

+        //      visit its files first

+        //

+        ProcessorDef extendsDef = getExtends();

+        if (extendsDef != null) {

+            extendsDef.visitFiles(visitor);

+        }

+        for (int i = 0; i < srcSets.size(); i++) {

+            ConditionalFileSet srcSet = (ConditionalFileSet) srcSets

+                    .elementAt(i);

+            if (srcSet.isActive()) {

+                // Find matching source files

+                DirectoryScanner scanner = srcSet.getDirectoryScanner(p);

+                // Check each source file - see if it needs compilation

+                String[] fileNames = scanner.getIncludedFiles();

+                File parentDir = scanner.getBasedir();

+                for (int j = 0; j < fileNames.length; j++) {

+                    String currentFile = fileNames[j];

+                    visitor.visit(parentDir, currentFile);

+                }

+            }

+        }

+    }

+    public Vector getSrcSets() {

+        if (isReference()) {

+            return ((ProcessorDef) getCheckedRef(ProcessorDef.class,

+                    "ProcessorDef")).getSrcSets();

+        }

+        return srcSets;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java
new file mode 100644
index 0000000..d028052
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorEnumValue.java
@@ -0,0 +1,47 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+/**

+ * One entry in the arrays used by the CompilerEnum and LinkerEnum classes.

+ * 

+ * @author Curt Arnold

+ * @see CompilerEnum

+ * @see LinkerEnum

+ *  

+ */

+public class ProcessorEnumValue {

+    public static String[] getValues(ProcessorEnumValue[] processors) {

+        String[] values = new String[processors.length];

+        for (int i = 0; i < processors.length; i++) {

+            values[i] = processors[i].getName();

+        }

+        return values;

+    }

+    private String name;

+    private Processor processor;

+    public ProcessorEnumValue(String name, Processor processor) {

+        this.name = name;

+        this.processor = processor;

+    }

+    public String getName() {

+        return name;

+    }

+    public Processor getProcessor() {

+        return processor;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorParam.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorParam.java
new file mode 100644
index 0000000..b2d4796
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorParam.java
@@ -0,0 +1,100 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+/*******************************************************************************

+ * Place class description here.

+ * 

+ * @author inger

+ * @author <additional author>

+ * 

+ * @since  

+ ******************************************************************************/

+public class ProcessorParam {

+    private String ifCond;

+    private String name;

+    private String unlessCond;

+    private String value;

+    public ProcessorParam() {

+    }

+    public String getName() {

+        return name;

+    }

+    public String getValue() {

+        return value;

+    }

+    /**

+     * Returns true if the define's if and unless conditions (if any) are

+     * satisfied.

+     */

+    public boolean isActive(org.apache.tools.ant.Project p) {

+        if (value == null) {

+            return false;

+        }

+        if (ifCond != null && p.getProperty(ifCond) == null) {

+            return false;

+        } else if (unlessCond != null && p.getProperty(unlessCond) != null) {

+            return false;

+        }

+        return true;

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The argument will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     */

+    public void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Specifies relative location of argument on command line. "start" will

+     * place argument at start of command line, "mid" will place argument after

+     * all "start" arguments but before filenames, "end" will place argument

+     * after filenames.

+     *  

+     */

+    public void setName(String name) {

+        this.name = name;

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the argument will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessCond = propName;

+    }

+    /**

+     * Specifies the string that should appear on the command line. The

+     * argument will be quoted if it contains embedded blanks. Use multiple

+     * arguments to avoid quoting.

+     *  

+     */

+    public void setValue(String value) {

+        this.value = value;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/RuntimeType.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/RuntimeType.java
new file mode 100644
index 0000000..02da661
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/RuntimeType.java
@@ -0,0 +1,26 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import org.apache.tools.ant.types.EnumeratedAttribute;

+/**

+ * Enumerated attribute with the values "dynamic" and "static",

+ */

+public class RuntimeType extends EnumeratedAttribute {

+    public String[] getValues() {

+        return new String[]{"dynamic", "static"};

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/SourceHistory.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/SourceHistory.java
new file mode 100644
index 0000000..0c608b4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/SourceHistory.java
@@ -0,0 +1,51 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+import java.io.IOException;

+/**

+ * The history of a source file used to build a target

+ * 

+ * @author Curt Arnold

+ */

+public final class SourceHistory {

+    private/* final */long lastModified;

+    private/* final */String relativePath;

+    /**

+     * Constructor

+     */

+    public SourceHistory(String relativePath, long lastModified) {

+        if (relativePath == null) {

+            throw new NullPointerException("relativePath");

+        }

+        this.relativePath = relativePath;

+        this.lastModified = lastModified;

+    }

+    public String getAbsolutePath(File baseDir) {

+        try {

+            return new File(baseDir, relativePath).getCanonicalPath();

+        } catch (IOException ex) {

+        }

+        return relativePath;

+    }

+    public long getLastModified() {

+        return lastModified;

+    }

+    public String getRelativePath() {

+        return relativePath;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/SubsystemEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/SubsystemEnum.java
new file mode 100644
index 0000000..3dc342a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/SubsystemEnum.java
@@ -0,0 +1,34 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import org.apache.tools.ant.types.EnumeratedAttribute;

+/**

+ * Enumeration of supported subsystems

+ * 

+ * @author Curt Arnold

+ *  

+ */

+public final class SubsystemEnum extends EnumeratedAttribute {

+    private final static String[] values = new String[]{"gui", "console",

+            "other"};

+    public SubsystemEnum() {

+        setValue("gui");

+    }

+    public String[] getValues() {

+        return (String[]) values.clone();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetDef.java
new file mode 100644
index 0000000..8e46cb7
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetDef.java
@@ -0,0 +1,228 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import org.apache.tools.ant.types.DataType;

+import org.apache.tools.ant.types.Reference;

+

+/**

+ * Information on the execution platforms for the generated code.

+ * (Non-functional prototype)

+ *

+ */

+public final class TargetDef

+    extends DataType {

+  /**

+   * if property.

+   */

+  private String ifCond;

+

+  /**

+   * unless property.

+   */

+  private String unlessCond;

+

+  /**

+   * cpu.

+   *

+   */

+  private CPUEnum cpu;

+

+  /**

+   * architecture.

+   *

+   */

+  private ArchEnum arch;

+

+  /**

+   * OS Family.

+   *

+   */

+  private OSFamilyEnum osFamily;

+

+  /**

+   * Constructor.

+   *

+   */

+  public TargetDef() {

+  }

+

+  /**

+   * Bogus method required for documentation generation.

+   */

+  public void execute() {

+    throw new org.apache.tools.ant.BuildException(

+        "Not an actual task, but looks like one for documentation purposes");

+  }

+

+  /**

+   * Returns true if the define's if and unless conditions (if any) are

+   * satisfied.

+   * @return true if active

+   */

+  public boolean isActive() {

+    return CUtil.isActive(getProject(), ifCond, unlessCond);

+  }

+

+  /**

+   * Sets a description of the current data type.

+   * @param desc description

+   */

+  public void setDescription(final String desc) {

+    super.setDescription(desc);

+  }

+

+  /**

+   * Sets an id that can be used to reference this element.

+   *

+   * @param id

+   *            id

+   */

+  public void setId(final String id) {

+    //

+    //  this is actually accomplished by a different

+    //     mechanism, but we can document it

+    //

+  }

+

+  /**

+   * Sets the property name for the 'if' condition.

+   *

+   * The define will be ignored unless the property is defined.

+   *

+   * The value of the property is insignificant, but values that would imply

+   * misinterpretation ("false", "no") will throw an exception when

+   * evaluated.

+   *

+   * @param propName

+   *            property name

+   */

+  public void setIf(final String propName) {

+    ifCond = propName;

+  }

+

+  /**

+   * Specifies that this element should behave as if the content of the

+   * element with the matching id attribute was inserted at this location. If

+   * specified, no other attributes should be specified.

+   * @param r id of referenced target

+   */

+  public void setRefid(final Reference r) {

+    super.setRefid(r);

+  }

+

+  /**

+   * Set the property name for the 'unless' condition.

+   *

+   * If named property is set, the define will be ignored.

+   *

+   * The value of the property is insignificant, but values that would imply

+   * misinterpretation ("false", "no") of the behavior will throw an

+   * exception when evaluated.

+   *

+   * @param propName

+   *            name of property

+   */

+  public void setUnless(final String propName) {

+    unlessCond = propName;

+  }

+

+  /**

+   * Gets cpu.

+   * @return cpu, may be null.

+   *

+   */

+  public CPUEnum getCpu() {

+    if (isReference()) {

+      TargetDef refPlatform = (TargetDef)

+          getCheckedRef(TargetDef.class,

+                        "TargetDef");

+      return refPlatform.getCpu();

+    }

+    return cpu;

+  }

+

+  /**

+   * Gets arch.

+   * @return arch, may be null.

+   *

+   */

+  public ArchEnum getArch() {

+    if (isReference()) {

+      TargetDef refPlatform = (TargetDef)

+          getCheckedRef(TargetDef.class,

+                        "TargetDef");

+      return refPlatform.getArch();

+    }

+    return arch;

+  }

+

+  /**

+   * Gets operating system family.

+   * @return os family, may be null.

+   *

+   */

+  public OSFamilyEnum getOsfamily() {

+    if (isReference()) {

+      TargetDef refPlatform = (TargetDef)

+          getCheckedRef(TargetDef.class,

+                        "TargetDef");

+      return refPlatform.getOsfamily();

+    }

+    return osFamily;

+  }

+

+  /**

+   * Sets preferred cpu, but does not use cpu specific instructions.

+   * @param value new value

+   */

+  public void setCpu(final CPUEnum value) {

+    if (isReference()) {

+      throw tooManyAttributes();

+    }

+    cpu = value;

+  }

+

+  /**

+   * Sets cpu architecture, compiler may use cpu specific instructions.

+   * @param value new value

+   */

+  public void setArch(final ArchEnum value) {

+    if (isReference()) {

+      throw tooManyAttributes();

+    }

+    if (cpu != null) {

+      throw tooManyAttributes();

+    }

+    arch = value;

+  }

+

+  /**

+   * Sets operating system family.

+   * @param value new value

+   */

+  public void setOsfamily(final OSFamilyEnum value) {

+    if (isReference()) {

+      throw tooManyAttributes();

+    }

+    if (cpu != null) {

+      throw tooManyAttributes();

+    }

+    osFamily = value;

+  }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetHistory.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetHistory.java
new file mode 100644
index 0000000..0094c8e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetHistory.java
@@ -0,0 +1,58 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+/**

+ * A description of a file built or to be built

+ */

+public final class TargetHistory {

+    private/* final */String config;

+    private/* final */String output;

+    private/* final */long outputLastModified;

+    private/* final */SourceHistory[] sources;

+    /**

+     * Constructor from build step

+     */

+    public TargetHistory(String config, String output, long outputLastModified,

+            SourceHistory[] sources) {

+        if (config == null) {

+            throw new NullPointerException("config");

+        }

+        if (sources == null) {

+            throw new NullPointerException("source");

+        }

+        if (output == null) {

+            throw new NullPointerException("output");

+        }

+        this.config = config;

+        this.output = output;

+        this.outputLastModified = outputLastModified;

+        this.sources = (SourceHistory[]) sources.clone();

+    }

+    public String getOutput() {

+        return output;

+    }

+    public long getOutputLastModified() {

+        return outputLastModified;

+    }

+    public String getProcessorConfiguration() {

+        return config;

+    }

+    public SourceHistory[] getSources() {

+        SourceHistory[] clone = (SourceHistory[]) sources.clone();

+        return clone;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetHistoryTable.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetHistoryTable.java
new file mode 100644
index 0000000..9fb0a7b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetHistoryTable.java
@@ -0,0 +1,426 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.BufferedWriter;

+import java.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.OutputStreamWriter;

+import java.io.UnsupportedEncodingException;

+import java.util.Enumeration;

+import java.util.Hashtable;

+import java.util.Vector;

+

+import javax.xml.parsers.SAXParser;

+import javax.xml.parsers.SAXParserFactory;

+

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+

+import org.apache.tools.ant.BuildException;

+import org.xml.sax.Attributes;

+import org.xml.sax.SAXException;

+import org.xml.sax.helpers.DefaultHandler;

+/**

+ * A history of the compiler and linker settings used to build the files in the

+ * same directory as the history.

+ * 

+ * @author Curt Arnold

+ */

+public final class TargetHistoryTable {

+    /**

+     * This class handles populates the TargetHistory hashtable in response to

+     * SAX parse events

+     */

+    private class TargetHistoryTableHandler extends DefaultHandler {

+        private final File baseDir;

+        private String config;

+        private final Hashtable history;

+        private String output;

+        private long outputLastModified;

+        private final Vector sources = new Vector();

+        /**

+         * Constructor

+         * 

+         * @param history

+         *            hashtable of TargetHistory keyed by output name

+         * @param outputFiles

+         *            existing files in output directory

+         */

+        private TargetHistoryTableHandler(Hashtable history, File baseDir) {

+            this.history = history;

+            config = null;

+            output = null;

+            this.baseDir = baseDir;

+        }

+        public void endElement(String namespaceURI, String localName,

+                String qName) throws SAXException {

+            //

+            //   if </target> then

+            //       create TargetHistory object and add to hashtable

+            //           if corresponding output file exists and

+            //           has the same timestamp

+            //

+            if (qName.equals("target")) {

+                if (config != null && output != null) {

+                    File existingFile = new File(baseDir, output);

+                    //

+                    //   if the corresponding files doesn't exist or has a

+                    // different

+                    //      modification time, then discard this record

+                    if (existingFile.exists()) {

+                        long existingLastModified = existingFile.lastModified();

+                        //

+                        //   would have expected exact time stamps

+                        //      but have observed slight differences

+                        //      in return value for multiple evaluations of

+                        //      lastModified(). Check if times are within

+                        //      a second

+                        long diff = outputLastModified - existingLastModified;

+                        if (diff >= -500 && diff <= 500) {

+                            SourceHistory[] sourcesArray = new SourceHistory[sources

+                                    .size()];

+                            sources.copyInto(sourcesArray);

+                            TargetHistory targetHistory = new TargetHistory(

+                                    config, output, outputLastModified,

+                                    sourcesArray);

+                            history.put(output, targetHistory);

+                        }

+                    }

+                }

+                output = null;

+                sources.setSize(0);

+            } else {

+                //

+                //   reset config so targets not within a processor element

+                //      don't pick up a previous processors signature

+                //

+                if (qName.equals("processor")) {

+                    config = null;

+                }

+            }

+        }

+        /**

+         * startElement handler

+         */

+        public void startElement(String namespaceURI, String localName,

+                String qName, Attributes atts) throws SAXException {

+            //

+            //   if sourceElement

+            //

+            if (qName.equals("source")) {

+                String sourceFile = atts.getValue("file");

+                long sourceLastModified = Long.parseLong(atts

+                        .getValue("lastModified"), 16);

+                sources.addElement(new SourceHistory(sourceFile,

+                        sourceLastModified));

+            } else {

+                //

+                //   if <target> element,

+                //      grab file name and lastModified values

+                //      TargetHistory object will be created in endElement

+                //

+                if (qName.equals("target")) {

+                    sources.setSize(0);

+                    output = atts.getValue("file");

+                    outputLastModified = Long.parseLong(atts

+                            .getValue("lastModified"), 16);

+                } else {

+                    //

+                    //   if <processor> element,

+                    //       grab signature attribute

+                    //

+                    if (qName.equals("processor")) {

+                        config = atts.getValue("signature");

+                    }

+                }

+            }

+        }

+    }

+    /** Flag indicating whether the cache should be written back to file. */

+    private boolean dirty;

+    /**

+     * a hashtable of TargetHistory's keyed by output file name

+     */

+    private final Hashtable history = new Hashtable();

+    /** The file the cache was loaded from. */

+    private/* final */File historyFile;

+    private/* final */File outputDir;

+    private String outputDirPath;

+    /**

+     * Creates a target history table from history.xml in the output directory,

+     * if it exists. Otherwise, initializes the history table empty.

+     * 

+     * @param task

+     *            task used for logging history load errors

+     * @param outputDir

+     *            output directory for task

+     */

+    public TargetHistoryTable(CCTask task, File outputDir)

+            throws BuildException {

+        if (outputDir == null) {

+            throw new NullPointerException("outputDir");

+        }

+        if (!outputDir.isDirectory()) {

+            throw new BuildException("Output directory is not a directory");

+        }

+        if (!outputDir.exists()) {

+            throw new BuildException("Output directory does not exist");

+        }

+        this.outputDir = outputDir;

+        try {

+            outputDirPath = outputDir.getCanonicalPath();

+        } catch (IOException ex) {

+            outputDirPath = outputDir.toString();

+        }

+        //

+        //   load any existing history from file

+        //       suppressing any records whose corresponding

+        //       file does not exist, is zero-length or

+        //          last modified dates differ

+        historyFile = new File(outputDir, "history.xml");

+        if (historyFile.exists()) {

+            SAXParserFactory factory = SAXParserFactory.newInstance();

+            factory.setValidating(false);

+            try {

+                SAXParser parser = factory.newSAXParser();

+                parser.parse(historyFile, new TargetHistoryTableHandler(

+                        history, outputDir));

+            } catch (Exception ex) {

+                //

+                //   a failure on loading this history is not critical

+                //       but should be logged

+                task.log("Error reading history.xml: " + ex.toString());

+            }

+        } else {

+            //

+            // create empty history file for identifying new files by last

+            // modified

+            //   timestamp comperation (to compare with

+            //   System.currentTimeMillis() don't work on Unix, because it

+            //   maesure timestamps only in seconds).

+            //

+            try {

+                FileOutputStream outputStream = new FileOutputStream(

+                        historyFile);

+                byte[] historyElement = new byte[]{0x3C, 0x68, 0x69, 0x73,

+                        0x74, 0x6F, 0x72, 0x79, 0x2F, 0x3E};

+                outputStream.write(historyElement);

+                outputStream.close();

+            } catch (IOException ex) {

+                throw new BuildException("Can't create history file", ex);

+            }

+        }

+    }

+    public void commit() throws IOException {

+        //

+        //   if not dirty, no need to update file

+        //

+        if (dirty) {

+            //

+            //   build (small) hashtable of config id's in history

+            //

+            Hashtable configs = new Hashtable(20);

+            Enumeration elements = history.elements();

+            while (elements.hasMoreElements()) {

+                TargetHistory targetHistory = (TargetHistory) elements

+                        .nextElement();

+                String configId = targetHistory.getProcessorConfiguration();

+                if (configs.get(configId) == null) {

+                    configs.put(configId, configId);

+                }

+            }

+            FileOutputStream outStream = new FileOutputStream(historyFile);

+            OutputStreamWriter outWriter;

+            //

+            //   early VM's don't support UTF-8 encoding

+            //       try and fallback to the default encoding

+            //           otherwise

+            String encodingName = "UTF-8";

+            try {

+                outWriter = new OutputStreamWriter(outStream, "UTF-8");

+            } catch (UnsupportedEncodingException ex) {

+                outWriter = new OutputStreamWriter(outStream);

+                encodingName = outWriter.getEncoding();

+            }

+            BufferedWriter writer = new BufferedWriter(outWriter);

+            writer.write("<?xml version='1.0' encoding='");

+            writer.write(encodingName);

+            writer.write("'?>\n");

+            writer.write("<history>\n");

+            StringBuffer buf = new StringBuffer(200);

+            Enumeration configEnum = configs.elements();

+            while (configEnum.hasMoreElements()) {

+                String configId = (String) configEnum.nextElement();

+                buf.setLength(0);

+                buf.append("   <processor signature=\"");

+                buf.append(CUtil.xmlAttribEncode(configId));

+                buf.append("\">\n");

+                writer.write(buf.toString());

+                elements = history.elements();

+                while (elements.hasMoreElements()) {

+                    TargetHistory targetHistory = (TargetHistory) elements

+                            .nextElement();

+                    if (targetHistory.getProcessorConfiguration().equals(

+                            configId)) {

+                        buf.setLength(0);

+                        buf.append("      <target file=\"");

+                        buf.append(CUtil.xmlAttribEncode(targetHistory

+                                .getOutput()));

+                        buf.append("\" lastModified=\"");

+                        buf.append(Long.toHexString(targetHistory

+                                .getOutputLastModified()));

+                        buf.append("\">\n");

+                        writer.write(buf.toString());

+                        SourceHistory[] sourceHistories = targetHistory

+                                .getSources();

+                        for (int i = 0; i < sourceHistories.length; i++) {

+                            buf.setLength(0);

+                            buf.append("         <source file=\"");

+                            buf.append(CUtil.xmlAttribEncode(sourceHistories[i]

+                                    .getRelativePath()));

+                            buf.append("\" lastModified=\"");

+                            buf.append(Long.toHexString(sourceHistories[i]

+                                    .getLastModified()));

+                            buf.append("\"/>\n");

+                            writer.write(buf.toString());

+                        }

+                        writer.write("      </target>\n");

+                    }

+                }

+                writer.write("   </processor>\n");

+            }

+            writer.write("</history>\n");

+            writer.close();

+            dirty = false;

+        }

+    }

+    public TargetHistory get(String configId, String outputName) {

+        TargetHistory targetHistory = (TargetHistory) history.get(outputName);

+        if (targetHistory != null) {

+            if (!targetHistory.getProcessorConfiguration().equals(configId)) {

+                targetHistory = null;

+            }

+        }

+        return targetHistory;

+    }

+    public void markForRebuild(Hashtable targetInfos) {

+        Enumeration targetInfoEnum = targetInfos.elements();

+        while (targetInfoEnum.hasMoreElements()) {

+            markForRebuild((TargetInfo) targetInfoEnum.nextElement());

+        }

+    }

+    public void markForRebuild(TargetInfo targetInfo) {

+        //

+        //     if it must already be rebuilt, no need to check further

+        //

+        if (!targetInfo.getRebuild()) {

+            TargetHistory history = get(targetInfo.getConfiguration()

+                    .toString(), targetInfo.getOutput().getName());

+            if (history == null) {

+                targetInfo.mustRebuild();

+            } else {

+                SourceHistory[] sourceHistories = history.getSources();

+                File[] sources = targetInfo.getSources();

+                if (sourceHistories.length != sources.length) {

+                    targetInfo.mustRebuild();

+                } else {

+                    for (int i = 0; i < sourceHistories.length

+                            && !targetInfo.getRebuild(); i++) {

+                        //

+                        //   relative file name, must absolutize it on output

+                        // directory

+                        //

+                        boolean foundMatch = false;

+                        String historySourcePath = sourceHistories[i]

+                                .getAbsolutePath(outputDir);

+                        for (int j = 0; j < sources.length; j++) {

+                            File targetSource = sources[j];

+                            String targetSourcePath = targetSource

+                                    .getAbsolutePath();

+                            if (targetSourcePath.equals(historySourcePath)) {

+                                foundMatch = true;

+                                if (targetSource.lastModified() != sourceHistories[i]

+                                        .getLastModified()) {

+                                    targetInfo.mustRebuild();

+                                    break;

+                                }

+                            }

+                        }

+                        if (!foundMatch) {

+                            targetInfo.mustRebuild();

+                        }

+                    }

+                }

+            }

+        }

+    }

+    public void update(ProcessorConfiguration config, String[] sources) {

+        String configId = config.getIdentifier();

+        String[] onesource = new String[1];

+        String outputName;

+        for (int i = 0; i < sources.length; i++) {

+            onesource[0] = sources[i];

+            outputName = config.getOutputFileName(sources[i]);

+            update(configId, outputName, onesource);

+        }

+    }

+    private void update(String configId, String outputName, String[] sources) {

+        File outputFile = new File(outputDir, outputName);

+        //

+        //   if output file doesn't exist or predates the start of the

+        //        compile step (most likely a compilation error) then

+        //        do not write add a history entry

+        //

+        if (outputFile.exists()

+                && outputFile.lastModified() >= historyFile.lastModified()) {

+            dirty = true;

+            history.remove(outputName);

+            SourceHistory[] sourceHistories = new SourceHistory[sources.length];

+            for (int i = 0; i < sources.length; i++) {

+                File sourceFile = new File(sources[i]);

+                long lastModified = sourceFile.lastModified();

+                String relativePath = CUtil.getRelativePath(outputDirPath,

+                        sourceFile);

+                sourceHistories[i] = new SourceHistory(relativePath,

+                        lastModified);

+            }

+            TargetHistory newHistory = new TargetHistory(configId, outputName,

+                    outputFile.lastModified(), sourceHistories);

+            history.put(outputName, newHistory);

+        }

+    }

+    public void update(TargetInfo linkTarget) {

+        File outputFile = linkTarget.getOutput();

+        String outputName = outputFile.getName();

+        //

+        //   if output file doesn't exist or predates the start of the

+        //        compile or link step (most likely a compilation error) then

+        //        do not write add a history entry

+        //

+        if (outputFile.exists()

+                && outputFile.lastModified() >= historyFile.lastModified()) {

+            dirty = true;

+            history.remove(outputName);

+            SourceHistory[] sourceHistories = linkTarget

+                    .getSourceHistories(outputDirPath);

+            TargetHistory newHistory = new TargetHistory(linkTarget

+                    .getConfiguration().getIdentifier(), outputName, outputFile

+                    .lastModified(), sourceHistories);

+            history.put(outputName, newHistory);

+        }

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetInfo.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetInfo.java
new file mode 100644
index 0000000..3a9dd14
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetInfo.java
@@ -0,0 +1,127 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+/**

+ * A description of a file built or to be built

+ */

+public final class TargetInfo {

+    private static final File[] emptyFileArray = new File[0];

+    private/* final */ProcessorConfiguration config;

+    private/* final */File output;

+    private boolean rebuild;

+    private/* final */File[] sources;

+    private File[] sysSources;

+    public TargetInfo(ProcessorConfiguration config, File[] sources,

+            File[] sysSources, File output, boolean rebuild) {

+        if (config == null) {

+            throw new NullPointerException("config");

+        }

+        if (sources == null) {

+            throw new NullPointerException("sources");

+        }

+        if (output == null) {

+            throw new NullPointerException("output");

+        }

+        this.config = config;

+        this.sources = (File[]) sources.clone();

+        if (sysSources == null) {

+            this.sysSources = emptyFileArray;

+        } else {

+            this.sysSources = (File[]) sysSources.clone();

+        }

+        this.output = output;

+        this.rebuild = rebuild;

+        //

+        //   if the output doesn't exist, must rebuild it

+        //

+        if (!output.exists()) {

+            rebuild = true;

+        }

+    }

+    public String[] getAllSourcePaths() {

+        String[] paths = new String[sysSources.length + sources.length];

+        for (int i = 0; i < sysSources.length; i++) {

+            paths[i] = sysSources[i].toString();

+        }

+        int offset = sysSources.length;

+        for (int i = 0; i < sources.length; i++) {

+            paths[offset + i] = sources[i].toString();

+        }

+        return paths;

+    }

+    public File[] getAllSources() {

+        File[] allSources = new File[sources.length + sysSources.length];

+        for (int i = 0; i < sysSources.length; i++) {

+            allSources[i] = sysSources[i];

+        }

+        int offset = sysSources.length;

+        for (int i = 0; i < sources.length; i++) {

+            allSources[i + offset] = sources[i];

+        }

+        return allSources;

+    }

+    public ProcessorConfiguration getConfiguration() {

+        return config;

+    }

+    public File getOutput() {

+        return output;

+    }

+    public boolean getRebuild() {

+        return rebuild;

+    }

+    /**

+     * Returns an array of SourceHistory objects (contains relative path and

+     * last modified time) for the source[s] of this target

+     */

+    public SourceHistory[] getSourceHistories(String basePath) {

+        SourceHistory[] histories = new SourceHistory[sources.length];

+        for (int i = 0; i < sources.length; i++) {

+            String relativeName = CUtil.getRelativePath(basePath, sources[i]);

+            long lastModified = sources[i].lastModified();

+            histories[i] = new SourceHistory(relativeName, lastModified);

+        }

+        return histories;

+    }

+    public String[] getSourcePaths() {

+        String[] paths = new String[sources.length];

+        for (int i = 0; i < sources.length; i++) {

+            paths[i] = sources[i].toString();

+        }

+        return paths;

+    }

+    public File[] getSources() {

+        File[] clone = (File[]) sources.clone();

+        return clone;

+    }

+    public String[] getSysSourcePaths() {

+        String[] paths = new String[sysSources.length];

+        for (int i = 0; i < sysSources.length; i++) {

+            paths[i] = sysSources[i].toString();

+        }

+        return paths;

+    }

+    public File[] getSysSources() {

+        File[] clone = (File[]) sysSources.clone();

+        return clone;

+    }

+    public void mustRebuild() {

+        this.rebuild = true;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetMatcher.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetMatcher.java
new file mode 100644
index 0000000..2574e15
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/TargetMatcher.java
@@ -0,0 +1,117 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+import java.io.File;

+import java.util.Hashtable;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.LinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * This class matches each visited file with an appropriate compiler

+ * 

+ * @author Curt Arnold

+ */

+public final class TargetMatcher implements FileVisitor {

+    private LinkerConfiguration linker;

+    private Vector objectFiles;

+    private File outputDir;

+    private ProcessorConfiguration[] processors;

+    private final File sourceFiles[] = new File[1];

+    private Hashtable targets;

+    private CCTask task;

+    public TargetMatcher(CCTask task, File outputDir,

+            ProcessorConfiguration[] processors, LinkerConfiguration linker,

+            Vector objectFiles, Hashtable targets) {

+        this.task = task;

+        this.outputDir = outputDir;

+        this.processors = processors;

+        this.targets = targets;

+        this.linker = linker;

+        this.objectFiles = objectFiles;

+    }

+    public void visit(File parentDir, String filename) throws BuildException {

+        //

+        //   see if any processor wants to bid

+        //       on this one

+        ProcessorConfiguration selectedCompiler = null;

+        int bid = 0;

+        if (processors != null) {

+            for (int k = 0; k < processors.length; k++) {

+                int newBid = processors[k].bid(filename);

+                if (newBid > bid) {

+                    bid = newBid;

+                    selectedCompiler = processors[k];

+                }

+            }

+        }

+        //

+        //   no processor interested in file

+        //      log diagnostic message

+        if (bid <= 0) {

+            if (linker != null) {

+                int linkerbid = linker.bid(filename);

+                if (linkerbid > 0) {

+                    File objFile = new File(parentDir, filename);

+                    objectFiles.addElement(objFile);

+                    if (linkerbid == 1) {

+                        task.log("Unrecognized file type " + objFile.toString()

+                                + " will be passed to linker");

+                    }

+                }

+            }

+        } else {

+            //

+            //  get output file name

+            //

+            String outputFileName = selectedCompiler

+                    .getOutputFileName(filename);

+            //

+            //   if there is some output for this task

+            //      (that is a source file and not an header file)

+            //

+            if (outputFileName != null) {

+                sourceFiles[0] = new File(parentDir, filename);

+                //

+                //   see if the same output file has already been registered

+                //

+                TargetInfo previousTarget = (TargetInfo) targets

+                        .get(outputFileName);

+                if (previousTarget == null) {

+                    targets.put(outputFileName, new TargetInfo(

+                            selectedCompiler, sourceFiles, null, new File(

+                                    outputDir, outputFileName),

+                            selectedCompiler.getRebuild()));

+                } else {

+                    if (!previousTarget.getSources()[0].equals(sourceFiles[0])) {

+                        StringBuffer builder = new StringBuffer(

+                                "Output filename conflict: ");

+                        builder.append(outputFileName);

+                        builder.append(" would be produced from ");

+                        builder.append(previousTarget.getSources()[0]

+                                .toString());

+                        builder.append(" and ");

+                        builder.append(filename);

+                        throw new BuildException(builder.toString());

+                    }

+                }

+            }

+        }

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/VersionInfo.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/VersionInfo.java
new file mode 100644
index 0000000..f55b976
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/VersionInfo.java
@@ -0,0 +1,550 @@
+/*

+ * 

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks;

+

+import java.io.IOException;

+import java.io.Writer;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.types.DataType;

+import org.apache.tools.ant.types.Reference;

+

+/**

+ * Version Information. (Non-functional prototype)

+ * 

+ */

+public class VersionInfo extends DataType {

+	/**

+	 * if property.

+	 */

+    private String ifCond;

+    /**

+     * unless property.

+     */

+    private String unlessCond;

+

+    /**

+     * extends property.

+     */

+    private String extendsId;

+    

+    /**

+     * file version.

+     *

+     */

+    private String fileVersion;

+    /**

+     * Product version.

+     *

+     */

+    private String productVersion;

+    /**

+     * file language.

+     *

+     */

+    private String language;

+    

+    /**

+     * comments.

+     *

+     */

+    private String fileComments;

+    /**

+     * Company name.

+     *

+     */

+    private String companyName;

+    /**

+     * Description.

+     *

+     */

+    private String description;

+    /**

+     * internal name.

+     */

+    private String internalName;

+    /**

+     * legal copyright.

+     *

+     */

+    private String legalCopyright;

+    /**

+     * legal trademark.

+     *

+     */

+    private String legalTrademark;

+    /**

+     * original filename.

+     *

+     */

+    private String originalFilename;

+    /**

+     * private build.

+     *

+     */

+    private String privateBuild;

+    /**

+     * product name.

+     *

+     */

+    private String productName;

+    /**

+     * Special build

+     */

+    private String specialBuild;

+    /**

+     * compatibility version

+     *

+     */

+    private String compatibilityVersion;

+	

+

+    /**

+     * Constructor.

+     *

+     */

+    public VersionInfo() {

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /**

+     * Returns true if the define's if and unless conditions (if any) are

+     * satisfied.

+     * 

+     * @exception BuildException

+     *                throws build exception if name is not set

+     */

+    public final boolean isActive() throws BuildException {

+        return CUtil.isActive(getProject(), ifCond, unlessCond);

+    }

+    /**

+     * Sets an id that can be used to reference this element.

+     * 

+     * @param id

+     *            id

+     */

+    public void setId(String id) {

+        //

+        //  this is actually accomplished by a different

+        //     mechanism, but we can document it

+        //

+    }

+    /**

+     * Sets the name of a version info that this info extends.

+     * 

+     * @param id

+     *            id

+     */

+    public void setExtends(String id) {

+    	extendsId = id;

+    }

+

+    

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The define will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     * 

+     * @param propName

+     *            property name

+     */

+    public final void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Specifies that this element should behave as if the content of the

+     * element with the matching id attribute was inserted at this location. If

+     * specified, no other attributes should be specified.

+     *  

+     */

+    public void setRefid(Reference r) throws BuildException {

+        super.setRefid(r);

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the define will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public final void setUnless(String propName) {

+        unlessCond = propName;

+    }

+    /**

+     * Gets file version.

+     * @return file version, may be null.

+     *

+     */

+    public String getFileversion() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getFileversion();

+        }

+    	return fileVersion;

+    }

+    /**

+     * Gets Product version.

+     * @return product version, may be null

+     */

+    public String getProductversion() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getProductversion();

+        }

+    	return productVersion;

+    }

+    /**

+     * Gets compatibility version.

+     * @return compatibility version, may be null

+     */

+    public String getCompatibilityversion() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getCompatibilityversion();

+        }

+    	return compatibilityVersion;

+    }

+    /**

+     * Gets file language, should be an IETF RFC 3066 identifier, for example, en-US.

+     * @return language, may be null.

+     */

+    public String getLanguage() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getLanguage();

+        }

+    	return language;

+    }

+    

+    /**

+     * Gets comments.

+     * @return comments, may be null.

+     */

+    public String getFilecomments() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getFilecomments();

+        }

+    	return fileComments;

+    }

+    /**

+     * Gets Company name.

+     * @return company name, may be null.

+     */

+    public String getCompanyname() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getCompanyname();

+        }

+    	return companyName;

+    }

+    /**

+     * Gets Description.

+     * @return description, may be null.

+     */

+    public String getDescription() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getDescription();

+        }

+    	return description;

+    }

+    /**

+     * Gets internal name.

+     * @return internal name, may be null.

+     */

+    public String getInternalname() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getInternalname();

+        }

+    	return internalName;

+    }

+    /**

+     * Gets legal copyright.

+     * @return legal copyright, may be null.

+     */

+    public String getLegalcopyright() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getLegalcopyright();

+        }

+    	return legalCopyright;

+    }

+    /**

+     * Gets legal trademark.

+     * @return legal trademark, may be null;

+     */

+    public String getLegaltrademark() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getLegaltrademark();

+        }

+    	return legalTrademark;

+    }

+    /**

+     * Gets original filename.

+     * @return original filename, may be null.

+     */

+    public String getOriginalfilename() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getOriginalfilename();

+        }

+    	return originalFilename;

+    }

+    /**

+     * Gets private build.

+     * @return private build, may be null.

+     */

+    public String getPrivatebuild() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getPrivatebuild();

+        }

+    	return privateBuild;

+    }

+    /**

+     * Gets product name.

+     * @return product name, may be null.

+     */

+    public String getProductname() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getProductname();

+        }

+    	return productName;

+    }

+    /**

+     * Special build

+     * @return special build, may be null.

+     */

+    public String getSpecialbuild() {

+        if (isReference()) {

+            VersionInfo refVersion = (VersionInfo) 

+				getCheckedRef(VersionInfo.class,

+                    "VersionInfo");

+            return refVersion.getSpecialbuild();

+        }

+    	return specialBuild;

+    }

+

+    /**

+     * Sets file version.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setFileversion(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	fileVersion = value;

+    }

+    /**

+     * Sets product version.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setProductversion(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	productVersion = value;

+    }

+    /**

+     * Sets compatibility version.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setCompatibilityversion(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	compatibilityVersion = value;

+    }

+    /**

+     * Sets language.

+     * @param value new value, should be an IETF RFC 3066 language identifier.

+     * @throws BuildException if specified with refid

+     */

+    public void setLanguage(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        language = value;

+    }

+    /**

+     * Sets comments.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setFilecomments(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	fileComments = value;

+    }

+

+    /**

+     * Sets company name.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setCompanyname(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	companyName = value;

+    }

+

+

+    /**

+     * Sets internal name.  Internal name will automatically be

+     * specified from build step, only set this value if

+     * intentionally overriding that value.

+     * 

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setInternalname(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	internalName = value;

+    }

+    

+    /**

+     * Sets legal copyright.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setLegalcopyright(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	legalCopyright = value;

+    }

+    /**

+     * Sets legal trademark.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setLegaltrademark(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	legalTrademark = value;

+    }

+    /**

+     * Sets original name.  Only set this value if

+     * intentionally overriding the value from the build set.

+     * 

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setOriginalfilename(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	originalFilename = value;

+    }

+    /**

+     * Sets private build.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setPrivatebuild(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	privateBuild = value;

+    }

+    /**

+     * Sets product name.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setProductname(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	productName= value;

+    }

+    /**

+     * Sets private build.

+     * @param value new value

+     * @throws BuildException if specified with refid

+     */

+    public void setSpecialbuild(String value) throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+    	specialBuild = value;

+    }

+    

+    /**

+     * Writes windows resource 

+     * @param writer writer, may not be null.

+     * @param project project, may not be null

+     * @param executableName name of executable

+     */

+    public void writeResource(final Writer writer, 

+    		final Project p, 

+			final String executableName) throws IOException {

+    	// TODO:

+    	

+    }

+    

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java
new file mode 100644
index 0000000..78489b8
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSCCompiler.java
@@ -0,0 +1,215 @@
+/*

+ * 

+ * Copyright 2003-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.arm;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the ARM C Compilers

+ * 

+ * See Doc No: ARM DUI 0151A, Issued: Nov 2001 at

+ * http://www.arm.com/arm/User_Guides?OpenDocument

+ * 

+ * @author Curt Arnold

+ *  

+ */

+public class ADSCCompiler extends CommandLineCCompiler {

+    /**

+     * Header file extensions

+     */

+    private static final String[] headerExtensions = new String[]{".h", ".hpp",

+            ".inl"};

+    /**

+     * Source file extensions

+     */

+    private static final String[] sourceExtensions = new String[]{".c", ".cc",

+            ".cpp", ".cxx", ".c++"};

+    /**

+     * Singleton for ARM 32-bit C compiler

+     */

+    private static final ADSCCompiler armcc = new ADSCCompiler("armcc", false,

+            null);

+    /**

+     * Singleton for ARM 32-bit C++ compiler

+     */

+    private static final ADSCCompiler armcpp = new ADSCCompiler("armcpp",

+            false, null);

+    /**

+     * Singleton for ARM 16-bit C compiler

+     */

+    private static final ADSCCompiler tcc = new ADSCCompiler("tcc", false, null);

+    /**

+     * Singleton for ARM 16-bit C++ compiler

+     */

+    private static final ADSCCompiler tcpp = new ADSCCompiler("tcpp", false,

+            null);

+    /**

+     * Singleton for ARM 32-bit C compiler

+     */

+    public static ADSCCompiler getArmCC() {

+        return armcc;

+    }

+    /**

+     * Singleton for ARM 32-bit C++ compiler

+     */

+    public static ADSCCompiler getArmCpp() {

+        return armcpp;

+    }

+    /**

+     * Singleton for ARM 16-bit C compiler

+     */

+    public static ADSCCompiler getThumbCC() {

+        return tcpp;

+    }

+    /**

+     * Singleton for ARM 16-bit C++ compiler

+     */

+    public static ADSCCompiler getThumbCpp() {

+        return tcpp;

+    }

+    private static void quoteFile(StringBuffer buf, String outPath) {

+        if (outPath.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(outPath);

+            buf.append('\"');

+        } else {

+            buf.append(outPath);

+        }

+    }

+    /**

+     * Private constructor

+     * 

+     * @param command

+     *            executable name

+     * @param newEnvironment

+     *            Change environment

+     * @param env

+     *            New environment

+     */

+    private ADSCCompiler(String command, boolean newEnvironment, Environment env) {

+        super(command, "-vsn", sourceExtensions, headerExtensions, ".o", false,

+                null, newEnvironment, env);

+    }

+    /**

+     * Adds command switches for generic configuration options

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addImpliedArgs(java.util.Vector,

+     *      boolean, boolean, boolean,

+     *      net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    protected void addImpliedArgs(Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        if (debug) {

+            args.addElement("-g");

+        }

+        //

+        //   didn't see anything about producing

+        //     anything other than executables in the docs

+        if (linkType.isExecutable()) {

+        } else if (linkType.isSharedLibrary()) {

+        }

+    }

+    /**

+     * Adds flags that customize the warnings reported

+     * 

+     * Compiler does not appear to have warning levels but ability to turn off

+     * specific errors by explicit switches, could fabricate levels by

+     * prioritizing errors.

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addWarningSwitch(java.util.Vector,

+     *      int)

+     */

+    protected void addWarningSwitch(Vector args, int warnings) {

+    }

+    /**

+     * Add command line options for preprocessor macro

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getDefineSwitch(java.lang.StringBuffer,

+     *      java.lang.String, java.lang.String)

+     */

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        buffer.append("-D");

+        buffer.append(define);

+        if (value != null) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    /**

+     * ARMINC environment variable contains the default include path

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getEnvironmentIncludePath()

+     */

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("ARMINC", ";");

+    }

+    /**

+     * Returns command line option to specify include directory

+     *  

+     */

+    protected String getIncludeDirSwitch(String source) {

+        StringBuffer buf = new StringBuffer("-I");

+        quoteFile(buf, source);

+        return buf.toString();

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return ADSLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return ADSLinker.getDllInstance();

+        }

+        return ADSLinker.getInstance();

+    }

+    /**

+     * Maximum command line length

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getMaximumCommandLength()

+     */

+    public int getMaximumCommandLength() {

+        return 1000;

+    }

+    /*

+     * Adds command to undefine preprocessor macro

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getUndefineSwitch(java.lang.StringBuffer,

+     *      java.lang.String)

+     */

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        buffer.append("-U");

+        buffer.append(define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java
new file mode 100644
index 0000000..0ff53d3
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSLibrarian.java
@@ -0,0 +1,160 @@
+/*

+ * 

+ * Copyright 2003-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.arm;

+

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for ARM Librarian

+ *

+ * @author Curt Arnold

+ */

+public class ADSLibrarian extends CommandLineLinker {

+

+    private static final ADSLibrarian instance = new ADSLibrarian();

+

+    public static ADSLibrarian getInstance() {

+      return instance;

+    }

+

+    private ADSLibrarian()

+    {

+        super("armar",null,

+          new String[] { ".o" }, new String[0], ".lib", false, null);

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long, java.util.Vector)

+     */

+    protected void addBase(long base, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean, java.util.Vector)

+     */

+    protected void addFixed(Boolean fixed, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean, net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)

+     */

+    protected void addImpliedArgs(

+        boolean debug,

+        LinkType linkType,

+        Vector args,

+        Boolean defaultflag) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean, java.util.Vector)

+     */

+    protected void addIncremental(boolean incremental, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean, java.util.Vector)

+     */

+    protected void addMap(boolean map, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int, java.util.Vector)

+     */

+    protected void addStack(int stack, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)

+     */

+    protected String getCommandFileSwitch(String commandFile) {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()

+     */

+    public File[] getLibraryPath() {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])

+     */

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return new String[0];

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    public Linker getLinker(LinkType linkType) {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()

+     */

+    protected int getMaximumCommandLength() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)

+     */

+    protected String[] getOutputFileSwitch(String outputFile) {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()

+     */

+    public boolean isCaseSensitive() {

+        // TODO Auto-generated method stub

+        return false;

+    }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSLinker.java
new file mode 100644
index 0000000..042eb21
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/arm/ADSLinker.java
@@ -0,0 +1,166 @@
+/*

+ * 

+ * Copyright 2003-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.arm;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for the ARM Linker

+ * 

+ * @author CurtA

+ */

+public class ADSLinker extends CommandLineLinker {

+    private static final ADSLinker dllInstance = new ADSLinker(".o");

+    private static final ADSLinker instance = new ADSLinker(".axf");

+    public static ADSLinker getDllInstance() {

+        return dllInstance;

+    }

+    public static ADSLinker getInstance() {

+        return instance;

+    }

+    private ADSLinker(String outputSuffix) {

+        super("armlink", "-vsn", new String[]{".o", ".lib", ".res"},

+                new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null);

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long,

+     *      java.util.Vector)

+     */

+    protected void addBase(long base, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean,

+     *      java.util.Vector)

+     */

+    protected void addFixed(Boolean fixed, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean,

+     *      net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)

+     */

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if (debug) {

+            args.addElement("-debug");

+        }

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean,

+     *      java.util.Vector)

+     */

+    protected void addIncremental(boolean incremental, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean,

+     *      java.util.Vector)

+     */

+    protected void addMap(boolean map, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int,

+     *      java.util.Vector)

+     */

+    protected void addStack(int stack, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+        // TODO Auto-generated method stub

+

+    }

+    

+    /**

+     * May have to make this String array return

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)

+     */

+    protected String getCommandFileSwitch(String commandFile) {

+        return "-via" + commandFile;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()

+     */

+    public File[] getLibraryPath() {

+        return CUtil.getPathFromEnvironment("ARMLIB", ";");

+    }

+    /*

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])

+     */

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+    	//

+    	//  TODO: looks like bad extension

+    	//

+        return new String[]{".o"};

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    public Linker getLinker(LinkType linkType) {

+        return this;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()

+     */

+    protected int getMaximumCommandLength() {

+        return 1024;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)

+     */

+    protected String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"-output", outputFile};

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()

+     */

+    public boolean isCaseSensitive() {

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java
new file mode 100644
index 0000000..3304c9a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandCCompiler.java
@@ -0,0 +1,135 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.PrecompilingCommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Borland(r) C/C++ compiler.

+ * 

+ * @author Curt Arnold

+ */

+public class BorlandCCompiler extends PrecompilingCommandLineCCompiler {

+    private static final String[] headerExtensions = new String[]{".h", ".hpp",

+            ".inl"};

+    private static final String[] sourceExtensions = new String[]{".c", ".cc",

+            ".cpp", ".cxx", ".c++"};

+    private static final BorlandCCompiler instance = new BorlandCCompiler(

+            false, null);

+    public static BorlandCCompiler getInstance() {

+        return instance;

+    }

+    private BorlandCCompiler(boolean newEnvironment, Environment env) {

+        super("bcc32", "--version", sourceExtensions, headerExtensions, ".obj", false,

+                null, newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        args.addElement("-c");

+        //

+        //  turn off compiler autodependency since

+        //     we do it ourselves

+        args.addElement("-X");

+        if (exceptions) {

+            args.addElement("-x");

+        } else {

+            args.addElement("-x-");

+        }

+        if (multithreaded) {

+            args.addElement("-tWM");

+        }

+        if (debug) {

+            args.addElement("-Od");

+            args.addElement("-v");

+        } else {

+        	if (optimization != null) {

+        		if (optimization.isSpeed()) {

+        			args.addElement("-O1");

+        		} else {

+        			if (optimization.isSpeed()) {

+        				args.addElement("-O2");

+        			} else {

+        				if (optimization.isNoOptimization()) {

+        					args.addElement("-Od");

+        				}

+        			}

+        		}

+        	}

+        }

+        if (rtti != null && !rtti.booleanValue()) {

+        	args.addElement("-RT-");

+        }

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+        BorlandProcessor.addWarningSwitch(args, level);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new BorlandCCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    protected CompilerConfiguration createPrecompileGeneratingConfig(

+            CommandLineCompilerConfiguration baseConfig, File prototype,

+            String lastInclude) {

+        String[] additionalArgs = new String[]{"-H=" + lastInclude, "-Hc"};

+        return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,

+                null, true);

+    }

+    protected CompilerConfiguration createPrecompileUsingConfig(

+            CommandLineCompilerConfiguration baseConfig, File prototype,

+            String lastInclude, String[] exceptFiles) {

+        String[] additionalArgs = new String[]{"-Hu"};

+        return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,

+                exceptFiles, false);

+    }

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        BorlandProcessor.getDefineSwitch(buffer, define, value);

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return BorlandProcessor.getEnvironmentPath("bcc32", 'I',

+                new String[]{"..\\include"});

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return BorlandProcessor.getIncludeDirSwitch("-I", includeDir);

+    }

+    public Linker getLinker(LinkType type) {

+        return BorlandLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        BorlandProcessor.getUndefineSwitch(buffer, define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java
new file mode 100644
index 0000000..19daedd
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandCfgParser.java
@@ -0,0 +1,70 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import java.io.IOException;

+import java.io.Reader;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.parser.AbstractParser;

+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;

+import net.sf.antcontrib.cpptasks.parser.LetterState;

+import net.sf.antcontrib.cpptasks.parser.WhitespaceOrLetterState;

+/**

+ * A parser that paths from a borland cfg file

+ * 

+ * @author Curt Arnold

+ */

+public final class BorlandCfgParser extends AbstractParser {

+    private AbstractParserState newLineState;

+    private final Vector path = new Vector();

+    /**

+     * 

+     *  

+     */

+    public BorlandCfgParser(char switchChar) {

+        //

+        //   a quoted path (-I"some path")

+        //      doesn't end till a close quote and will be abandoned

+        //      if a new line is encountered first

+        //

+        AbstractParserState quote = new CfgFilenameState(this, new char[]{'"'});

+        //

+        //    an unquoted path (-Ic:\borland\include)

+        //      ends at the first space or new line

+        AbstractParserState unquote = new CfgFilenameState(this, new char[]{

+                ' ', '\n', '\r'});

+        AbstractParserState quoteBranch = new QuoteBranchState(this, quote,

+                unquote);

+        AbstractParserState toNextSwitch = new ConsumeToSpaceOrNewLine(this);

+        AbstractParserState switchState = new LetterState(this, switchChar,

+                quoteBranch, toNextSwitch);

+        newLineState = new WhitespaceOrLetterState(this, '-', switchState);

+    }

+    public void addFilename(String include) {

+        path.addElement(include);

+    }

+    public AbstractParserState getNewLineState() {

+        return newLineState;

+    }

+    public String[] parsePath(Reader reader) throws IOException {

+        path.setSize(0);

+        super.parse(reader);

+        String[] retval = new String[path.size()];

+        path.copyInto(retval);

+        return retval;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java
new file mode 100644
index 0000000..5fb3eb0
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandLibrarian.java
@@ -0,0 +1,200 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import java.io.File;

+import java.io.IOException;

+import java.util.Vector;

+import org.apache.tools.ant.BuildException;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for the Borland(r) tlib Librarian

+ * 

+ * @author Curt Arnold

+ */

+public class BorlandLibrarian extends CommandLineLinker {

+    private static final BorlandLibrarian instance = new BorlandLibrarian();

+    public static BorlandLibrarian getInstance() {

+        return instance;

+    }

+    private BorlandLibrarian() {

+        super("tlib", "--version", new String[]{".obj"}, new String[0], ".lib", false,

+                null);

+    }

+    protected void addBase(long base, Vector args) {

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    protected void addMap(boolean map, Vector args) {

+    }

+    protected void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    protected String getCommandFileSwitch(String cmdFile) {

+        return BorlandProcessor.getCommandFileSwitch(cmdFile);

+    }

+    public File[] getLibraryPath() {

+        return CUtil.getPathFromEnvironment("LIB", ";");

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return BorlandProcessor.getLibraryPatterns(libnames, libType);

+    }

+    public Linker getLinker(LinkType type) {

+        return BorlandLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    public String[] getOutputFileSwitch(String outFile) {

+        return BorlandProcessor.getOutputFileSwitch(outFile);

+    }

+    public boolean isCaseSensitive() {

+        return BorlandProcessor.isCaseSensitive();

+    }

+    /**

+     * Gets identifier for the linker.

+     * 

+     * TLIB will lockup when attempting to get version

+     * information.  Since the Librarian version isn't critical

+     * just return a stock response.

+     */

+    public String getIdentifier() {

+    	return "TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation";

+    }

+    

+    /**

+     * Prepares argument list for exec command.

+     * 

+     * @param outputFile

+     *            linker output file

+     * @param sourceFiles

+     *            linker input files (.obj, .o, .res)

+     * @param args

+     *            linker arguments

+     * @return arguments for runTask

+     */

+    protected String[] prepareArguments(

+    		CCTask task,

+    		String outputDir, 

+			String outputName,

+            String[] sourceFiles, 

+			CommandLineLinkerConfiguration config) {

+    	String[] preargs = config.getPreArguments();

+        String[] endargs = config.getEndArguments();

+        StringBuffer buf = new StringBuffer();

+        Vector execArgs = new Vector(preargs.length + endargs.length + 10

+                + sourceFiles.length);

+        

+        execArgs.addElement(this.getCommand());

+        String outputFileName = new File(outputDir, outputName).toString();

+        execArgs.addElement(quoteFilename(buf, outputFileName));

+

+        for (int i = 0; i < preargs.length; i++) {

+            execArgs.addElement(preargs[i]);

+        }

+

+        //

+        //   add a place-holder for page size

+        //

+        int pageSizeIndex = execArgs.size();

+        execArgs.addElement(null);

+        

+        int objBytes = 0;

+        

+        for (int i = 0; i < sourceFiles.length; i++) {

+            String last4 = sourceFiles[i]

+                    .substring(sourceFiles[i].length() - 4).toLowerCase();

+            if (last4.equals(".def")) {

+            } else {

+                if (last4.equals(".res")) {

+                } else {

+                    if (last4.equals(".lib")) {

+                    } else {

+                        execArgs.addElement("+" + quoteFilename(buf, sourceFiles[i]));

+                        objBytes += new File(sourceFiles[i]).length();

+                    }

+                }

+            }

+        }

+        

+        for (int i = 0; i < endargs.length; i++) {

+            execArgs.addElement(endargs[i]);

+        }

+        

+        String[] execArguments = new String[execArgs.size()];

+        execArgs.copyInto(execArguments);

+

+    	int minPageSize = objBytes >> 16;

+    	int pageSize = 0;

+    	for(int i = 4; i <= 15; i++) {

+    		pageSize = 1 << i;

+    		if (pageSize > minPageSize) break;

+    	}

+        execArguments[pageSizeIndex] = "/P" + Integer.toString(pageSize);

+        

+        return execArguments;

+    }

+    

+    /**

+     * Prepares argument list to execute the linker using a response file.

+     * 

+     * @param outputFile

+     *            linker output file

+     * @param args

+     *            output of prepareArguments

+     * @return arguments for runTask

+     */

+    protected String[] prepareResponseFile(File outputFile, String[] args)

+            throws IOException {

+    	return BorlandProcessor.prepareResponseFile(outputFile, args, " & \n");

+    }

+    

+    /**

+     * Builds a library

+     *

+     */

+    public void link(CCTask task,

+                     File outputFile,

+                     String[] sourceFiles,

+                     CommandLineLinkerConfiguration config)

+                     throws BuildException

+    {

+    	//

+    	//  delete any existing library

+    	outputFile.delete();

+    	//

+    	//  build a new library

+    	super.link(task, outputFile, sourceFiles, config);

+    }

+    

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
new file mode 100644
index 0000000..f425c52
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
@@ -0,0 +1,264 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import java.io.File;

+import java.io.IOException;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for the Borland(r) ilink32 linker

+ * 

+ * @author Curt Arnold

+ */

+public final class BorlandLinker extends CommandLineLinker {

+    private static final BorlandLinker dllLinker = new BorlandLinker(".dll");

+    private static final BorlandLinker instance = new BorlandLinker(".exe");

+    public static BorlandLinker getInstance() {

+        return instance;

+    }

+    private BorlandLinker(String outputSuffix) {

+        super("ilink32", "-r", new String[]{".obj", ".lib", ".res"},

+                new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null);

+    }

+    protected void addBase(long base, Vector args) {

+        if (base >= 0) {

+            String baseAddr = Long.toHexString(base);

+            args.addElement("-b:" + baseAddr);

+        }

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if (linkType.isExecutable()) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("/ap");

+            } else {

+                if (linkType.isSubsystemGUI()) {

+                    args.addElement("/Tpe");

+                }

+            }

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("/Tpd");

+            args.addElement("/Gi");

+        }

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    protected void addMap(boolean map, Vector args) {

+        if (!map) {

+            args.addElement("-x");

+        }

+    }

+    protected void addStack(int stack, Vector args) {

+        if (stack >= 0) {

+            String stackStr = Integer.toHexString(stack);

+            args.addElement("-S:" + stackStr);

+        }

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    public String getIdentifier() {

+        return "Borland Linker";

+    }

+    public File[] getLibraryPath() {

+        return BorlandProcessor.getEnvironmentPath("ilink32", 'L',

+                new String[]{"..\\lib"});

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return BorlandProcessor.getLibraryPatterns(libnames, libType);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return BorlandLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    public String[] getOutputFileSwitch(String outFile) {

+        return BorlandProcessor.getOutputFileSwitch(outFile);

+    }

+    protected String getStartupObject(LinkType linkType) {

+        if (linkType.isSharedLibrary()) {

+            return "c0d32.obj";

+        }

+        if (linkType.isSubsystemGUI()) {

+            return "c0w32.obj";

+        }

+        if (linkType.isSubsystemConsole()) {

+            return "c0x32.obj";

+        }

+        return null;

+    }

+    public boolean isCaseSensitive() {

+        return BorlandProcessor.isCaseSensitive();

+    }

+    /**

+     * Prepares argument list for exec command.

+     * 

+     * @param outputFile

+     *            linker output file

+     * @param sourceFiles

+     *            linker input files (.obj, .o, .res)

+     * @param args

+     *            linker arguments

+     * @return arguments for runTask

+     */

+    protected String[] prepareArguments(

+    		CCTask task,

+    		String outputDir, 

+			String outputName,

+            String[] sourceFiles, 

+			CommandLineLinkerConfiguration config) {

+        String[] preargs = config.getPreArguments();

+        String[] endargs = config.getEndArguments();

+        Vector execArgs = new Vector(preargs.length + endargs.length + 10

+                + sourceFiles.length);

+        execArgs.addElement(this.getCommand());

+        for (int i = 0; i < preargs.length; i++) {

+            execArgs.addElement(preargs[i]);

+        }

+        for (int i = 0; i < endargs.length; i++) {

+            execArgs.addElement(endargs[i]);

+        }

+        //

+        //  see if the input files have any known startup obj files

+        //

+        String startup = null;

+        for (int i = 0; i < sourceFiles.length; i++) {

+            String filename = new File(sourceFiles[i]).getName().toLowerCase();

+            if (startup != null && filename.substring(0, 2).equals("c0")

+                    && filename.substring(3, 5).equals("32")

+                    && filename.substring(filename.length() - 4).equals(".obj")) {

+                startup = sourceFiles[i];

+            }

+        }

+        //

+        //  c0w32.obj, c0x32.obj or c0d32.obj depending on

+        //        link type

+        if (startup == null) {

+            startup = config.getStartupObject();

+        }

+        execArgs.addElement(startup);

+        Vector resFiles = new Vector();

+        Vector libFiles = new Vector();

+        String defFile = null;

+        StringBuffer buf = new StringBuffer();

+        for (int i = 0; i < sourceFiles.length; i++) {

+            String last4 = sourceFiles[i]

+                    .substring(sourceFiles[i].length() - 4).toLowerCase();

+            if (last4.equals(".def")) {

+                defFile = quoteFilename(buf, sourceFiles[i]);

+            } else {

+                if (last4.equals(".res")) {

+                    resFiles.addElement(quoteFilename(buf, sourceFiles[i]));

+                } else {

+                    if (last4.equals(".lib")) {

+                        libFiles.addElement(quoteFilename(buf, sourceFiles[i]));

+                    } else {

+                        execArgs.addElement(quoteFilename(buf, sourceFiles[i]));

+                    }

+                }

+            }

+        }

+        //

+        //   output file name

+        //

+        String outputFileName = new File(outputDir, outputName).toString();

+        execArgs.addElement("," + quoteFilename(buf, outputFileName));

+        if (config.getMap()) {

+            int lastPeriod = outputFileName.lastIndexOf('.');

+            String mapName;

+            if (lastPeriod < outputFileName.length() - 4) {

+                mapName = outputFileName + ".map";

+            } else {

+                mapName = outputFileName.substring(0, lastPeriod) + ".map";

+            }

+            execArgs.addElement("," + quoteFilename(buf, mapName) + ",");

+        } else {

+            execArgs.addElement(",,");

+        }

+        //

+        //   add all the libraries

+        //

+        Enumeration libEnum = libFiles.elements();

+        boolean hasImport32 = false;

+        boolean hasCw32 = false;

+        while (libEnum.hasMoreElements()) {

+            String libName = (String) libEnum.nextElement();

+            if (libName.equalsIgnoreCase("import32.lib")) {

+            	hasImport32 = true;

+            }

+            if (libName.equalsIgnoreCase("cw32.lib")) {

+            	hasImport32 = true;

+            }

+            execArgs.addElement(quoteFilename(buf, libName));

+        }

+        if (!hasCw32) {

+        	execArgs.addElement(quoteFilename(buf, "cw32.lib"));

+        }

+        if (!hasImport32) {

+        	execArgs.addElement(quoteFilename(buf, "import32.lib"));

+        }

+        if (defFile == null) {

+            execArgs.addElement(",,");

+        } else {

+            execArgs.addElement("," + quoteFilename(buf, defFile) + ",");

+        }

+        Enumeration resEnum = resFiles.elements();

+        while (resEnum.hasMoreElements()) {

+            String resName = (String) resEnum.nextElement();

+            execArgs.addElement(quoteFilename(buf, resName));

+        }

+        String[] execArguments = new String[execArgs.size()];

+        execArgs.copyInto(execArguments);

+        return execArguments;

+    }

+    /**

+     * Prepares argument list to execute the linker using a response file.

+     * 

+     * @param outputFile

+     *            linker output file

+     * @param args

+     *            output of prepareArguments

+     * @return arguments for runTask

+     */

+    protected String[] prepareResponseFile(File outputFile, String[] args)

+            throws IOException {

+    	return BorlandProcessor.prepareResponseFile(outputFile, args, " + \n");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java
new file mode 100644
index 0000000..d53f00c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandProcessor.java
@@ -0,0 +1,219 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.Reader;

+import java.util.Vector;

+import java.io.FileWriter;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+/**

+ * A add-in class for Borland(r) processor adapters

+ * 

+ *  

+ */

+public final class BorlandProcessor {

+    public static void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("-w-");

+                break;

+            case 5 :

+                args.addElement("-w!");

+                break;

+            default :

+                args.addElement("-w");

+                break;

+        }

+    }

+    public static String getCommandFileSwitch(String cmdFile) {

+        StringBuffer buf = new StringBuffer("@");

+        quoteFile(buf, cmdFile);

+        return buf.toString();

+    }

+    public static void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        buffer.append("-D");

+        buffer.append(define);

+        if (value != null && value.length() > 0) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    /**

+     * This method extracts path information from the appropriate .cfg file in

+     * the install directory.

+     * 

+     * @param toolName

+     *            Tool name, for example, "bcc32", "brc32", "ilink32"

+     * @param switchChar

+     *            Command line switch character, for example "L" for libraries

+     * @param defaultRelativePaths

+     *            default paths relative to executable directory

+     * @return path

+     */

+    public static File[] getEnvironmentPath(String toolName, char switchChar,

+            String[] defaultRelativePath) {

+        if (toolName == null) {

+            throw new NullPointerException("toolName");

+        }

+        if (defaultRelativePath == null) {

+            throw new NullPointerException("defaultRelativePath");

+        }

+        String[] path = defaultRelativePath;

+        File exeDir = CUtil.getExecutableLocation(toolName + ".exe");

+        if (exeDir != null) {

+            File cfgFile = new File(exeDir, toolName + ".cfg");

+            if (cfgFile.exists()) {

+                try {

+                    Reader reader = new BufferedReader(new FileReader(cfgFile));

+                    BorlandCfgParser cfgParser = new BorlandCfgParser(

+                            switchChar);

+                    path = cfgParser.parsePath(reader);

+                    reader.close();

+                } catch (IOException ex) {

+                    //

+                    //  could be logged

+                    //

+                }

+            }

+        } else {

+            //

+            //  if can't find the executable,

+            //     assume current directory to resolve relative paths

+            //

+            exeDir = new File(System.getProperty("user.dir"));

+        }

+        int nonExistant = 0;

+        File[] resourcePath = new File[path.length];

+        for (int i = 0; i < path.length; i++) {

+            resourcePath[i] = new File(path[i]);

+            if (!resourcePath[i].isAbsolute()) {

+                resourcePath[i] = new File(exeDir, path[i]);

+            }

+            //

+            //  if any of the entries do not exist or are

+            //     not directories, null them out

+            if (!(resourcePath[i].exists() && resourcePath[i].isDirectory())) {

+                resourcePath[i] = null;

+                nonExistant++;

+            }

+        }

+        //

+        //  if there were some non-existant or non-directory

+        //    entries in the configuration file then

+        //    create a shorter array

+        if (nonExistant > 0) {

+            File[] culled = new File[resourcePath.length - nonExistant];

+            int index = 0;

+            for (int i = 0; i < resourcePath.length; i++) {

+                if (resourcePath[i] != null) {

+                    culled[index++] = resourcePath[i];

+                }

+            }

+            resourcePath = culled;

+        }

+        return resourcePath;

+    }

+    public static String getIncludeDirSwitch(String includeOption,

+            String includeDir) {

+        StringBuffer buf = new StringBuffer(includeOption);

+        quoteFile(buf, includeDir);

+        return buf.toString();

+    }

+    public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        String[] patterns = new String[libnames.length];

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(libnames[i]);

+            buf.append(".lib");

+            patterns[i] = buf.toString();

+        }

+        return patterns;

+    }

+    public static String[] getOutputFileSwitch(String outFile) {

+        return new String[0];

+    }

+    public static void getUndefineSwitch(StringBuffer buffer, String define) {

+        buffer.append("-U");

+        buffer.append(define);

+    }

+    public static boolean isCaseSensitive() {

+        return false;

+    }

+    private static void quoteFile(StringBuffer buf, String outPath) {

+        if (outPath.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(outPath);

+            buf.append('\"');

+        } else {

+            buf.append(outPath);

+        }

+    }

+    

+    /**

+     * Prepares argument list to execute the linker using a response file.

+     * 

+     * @param outputFile

+     *            linker output file

+     * @param args

+     *            output of prepareArguments

+     * @return arguments for runTask

+     */

+    public static String[] prepareResponseFile(File outputFile, 

+    		String[] args,

+			String continuation)

+            throws IOException {

+        String baseName = outputFile.getName();

+        File commandFile = new File(outputFile.getParent(), baseName + ".lnk");

+        FileWriter writer = new FileWriter(commandFile);

+        for (int i = 1; i < args.length - 1; i++) {

+            writer.write(args[i]);

+            //

+            //  if either the current argument ends with

+            //     or next argument starts with a comma then

+            //      don't split the line

+            if (args[i].endsWith(",") || args[i + 1].startsWith(",")) {

+                writer.write(' ');

+            } else {

+                //

+                //  split the line to make it more readable

+                //

+                writer.write(continuation);

+            }

+        }

+        //

+        //  write the last argument

+        //

+        if (args.length > 1) {

+            writer.write(args[args.length - 1]);

+        }

+        writer.close();

+        String[] execArgs = new String[2];

+        execArgs[0] = args[0];

+        execArgs[1] = getCommandFileSwitch(commandFile.toString());

+        return execArgs;

+    }

+    

+    private BorlandProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java
new file mode 100644
index 0000000..5e86097
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/BorlandResourceCompiler.java
@@ -0,0 +1,130 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import java.io.File;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Borland(r) brc32 Resource compiler.

+ * 

+ * @author Curt Arnold

+ */

+public class BorlandResourceCompiler extends CommandLineCompiler {

+    private static final BorlandResourceCompiler instance = new BorlandResourceCompiler(

+            false, null);

+    public static BorlandResourceCompiler getInstance() {

+        return instance;

+    }

+    private BorlandResourceCompiler(boolean newEnvironment, Environment env) {

+        super("brc32", "c:\\__bogus\\__bogus.rc", new String[]{".rc"},

+                new String[]{".h", ".hpp", ".inl"}, ".res", false, null,

+                newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        //

+        //  compile only

+        //

+        args.addElement("-r");

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new BorlandResourceCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    public void compile(CCTask task, File outputDir, String[] sourceFiles,

+            String[] args, String[] endArgs, boolean relentless,

+            CommandLineCompilerConfiguration config, ProgressMonitor monitor)

+            throws BuildException {

+        super.compile(task, outputDir, sourceFiles, args, endArgs, relentless,

+                config, monitor);

+    }

+    /**

+     * The include parser for C will work just fine, but we didn't want to

+     * inherit from CommandLineCCompiler

+     */

+    protected Parser createParser(File source) {

+        return new CParser();

+    }

+    protected int getArgumentCountPerInputFile() {

+        return 2;

+    }

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        buffer.append("-d");

+        buffer.append(define);

+        if (value != null && value.length() > 0) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return BorlandProcessor.getEnvironmentPath("brc32", 'i',

+                new String[]{"..\\include"});

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return BorlandProcessor.getIncludeDirSwitch("-i", includeDir);

+    }

+    protected String getInputFileArgument(File outputDir, String filename,

+            int index) {

+        if (index == 0) {

+            String outputFileName = getOutputFileName(filename);

+            String fullOutputName = new File(outputDir, outputFileName)

+                    .toString();

+            return "-fo" + fullOutputName;

+        }

+        return filename;

+    }

+    public Linker getLinker(LinkType type) {

+        return BorlandLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    protected int getMaximumInputFilesPerCommand() {

+        return 1;

+    }

+    protected int getTotalArgumentLengthForInputFile(File outputDir,

+            String inputFile) {

+        String arg1 = getInputFileArgument(outputDir, inputFile, 0);

+        String arg2 = getInputFileArgument(outputDir, inputFile, 1);

+        return arg1.length() + arg2.length() + 2;

+    }

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java
new file mode 100644
index 0000000..a3651d3
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/CfgFilenameState.java
@@ -0,0 +1,46 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import net.sf.antcontrib.cpptasks.parser.AbstractParser;

+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;

+import net.sf.antcontrib.cpptasks.parser.FilenameState;

+public class CfgFilenameState extends FilenameState {

+    private char terminator;

+    public CfgFilenameState(AbstractParser parser, char[] terminators) {

+        super(parser, terminators);

+        terminator = terminators[0];

+    }

+    public AbstractParserState consume(char ch) {

+        //

+        //   if a ';' is encountered then

+        //      close the previous filename by sending a

+        //         recognized terminator to our super class

+        //      and stay in this state for more filenamese

+        if (ch == ';') {

+            super.consume(terminator);

+            return this;

+        }

+        AbstractParserState newState = super.consume(ch);

+        //

+        //   change null (consume to end of line)

+        //      to look for next switch character

+        if (newState == null) {

+            newState = getParser().getNewLineState();

+        }

+        return newState;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java
new file mode 100644
index 0000000..d1dd072
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/ConsumeToSpaceOrNewLine.java
@@ -0,0 +1,30 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import net.sf.antcontrib.cpptasks.parser.AbstractParser;

+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;

+public class ConsumeToSpaceOrNewLine extends AbstractParserState {

+    public ConsumeToSpaceOrNewLine(AbstractParser parser) {

+        super(parser);

+    }

+    public AbstractParserState consume(char ch) {

+        if (ch == ' ' || ch == '\t' || ch == '\n') {

+            return getParser().getNewLineState();

+        }

+        return this;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java
new file mode 100644
index 0000000..89724b2
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/borland/QuoteBranchState.java
@@ -0,0 +1,35 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.borland;

+import net.sf.antcontrib.cpptasks.parser.AbstractParser;

+import net.sf.antcontrib.cpptasks.parser.AbstractParserState;

+public class QuoteBranchState extends AbstractParserState {

+    private AbstractParserState quote;

+    private AbstractParserState unquote;

+    public QuoteBranchState(AbstractParser parser, AbstractParserState quote,

+            AbstractParserState unquote) {

+        super(parser);

+        this.quote = quote;

+        this.unquote = unquote;

+    }

+    public AbstractParserState consume(char ch) {

+        if (ch == '"') {

+            return quote;

+        }

+        return unquote.consume(ch);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java
new file mode 100644
index 0000000..e1d3deb
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranCompiler.java
@@ -0,0 +1,138 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compaq;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineFortranCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Compaq(r) Visual Fortran compiler.

+ * 

+ * @author Curt Arnold

+ */

+public class CompaqVisualFortranCompiler extends CommandLineFortranCompiler {

+    private static final CompaqVisualFortranCompiler[] instance = new CompaqVisualFortranCompiler[]{new CompaqVisualFortranCompiler(

+            false, null)};

+    public static CompaqVisualFortranCompiler getInstance() {

+        return instance[0];

+    }

+    private CompaqVisualFortranCompiler(boolean newEnvironment, Environment env) {

+        super("DF", null, new String[]{".f90", ".for", ".f"}, new String[]{

+                ".i", ".i90", ".fpp", ".inc", ".bak", ".exe"}, ".obj", false,

+                null, newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        args.addElement("/nologo");

+        args.addElement("/compile_only");

+        if (debug) {

+            args.addElement("/debug:full");

+            args.addElement("/define:_DEBUG");

+        } else {

+            args.addElement("/debug:none");

+            args.addElement("/define:NDEBUG");

+        }

+        if (multithreaded) {

+            args.addElement("/threads");

+            args.addElement("/define:_MT");

+        } else {

+            args.addElement("/nothreads");

+        }

+        boolean staticRuntime = linkType.isStaticRuntime();

+        if (staticRuntime) {

+            args.addElement("/libs:static");

+        } else {

+            args.addElement("/libs:dll");

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("/dll");

+            args.addElement("/define:_DLL");

+        }

+    }

+    public void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("/nowarn");

+                break;

+            case 1 :

+                break;

+            case 2 :

+                break;

+            case 3 :

+                args.addElement("/warn:usage");

+                break;

+            case 4 :

+                args.addElement("/warn:all");

+                break;

+            case 5 :

+                args.addElement("/warn:errors");

+                break;

+        }

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new CompaqVisualFortranCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    protected void getDefineSwitch(StringBuffer buf, String define, String value) {

+        buf.append("/define:");

+        buf.append(define);

+        if (value != null && value.length() > 0) {

+            buf.append('=');

+            buf.append(value);

+        }

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ";");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        StringBuffer buf = new StringBuffer("/include:");

+        if (includeDir.indexOf(' ') >= 0) {

+            buf.append('"');

+            buf.append(includeDir);

+            buf.append('"');

+        } else {

+            buf.append(includeDir);

+        }

+        return buf.toString();

+    }

+    public Linker getLinker(LinkType type) {

+        return CompaqVisualFortranLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    protected void getUndefineSwitch(StringBuffer buf, String define) {

+        buf.append("/undefine:");

+        buf.append(define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java
new file mode 100644
index 0000000..eb4a407
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLibrarian.java
@@ -0,0 +1,82 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compaq;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioLibrarian;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioProcessor;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for the Compaq(r) Visual Fortran Librarian

+ * 

+ * @author Curt Arnold

+ */

+public class CompaqVisualFortranLibrarian extends CommandLineLinker {

+    private static final CompaqVisualFortranLibrarian instance = new CompaqVisualFortranLibrarian();

+    public static CompaqVisualFortranLibrarian getInstance() {

+        return instance;

+    }

+    private CompaqVisualFortranLibrarian() {

+        super("lib", "/bogus", new String[]{".obj"}, new String[0], ".lib",

+                false, null);

+    }

+    protected void addBase(long base, Vector args) {

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        args.addElement("/nologo");

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    protected void addMap(boolean map, Vector args) {

+    }

+    protected void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    protected String getCommandFileSwitch(String commandFile) {

+        return DevStudioProcessor.getCommandFileSwitch(commandFile);

+    }

+    public File[] getLibraryPath() {

+        return new File[0];

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return new String[0];

+    }

+    public Linker getLinker(LinkType type) {

+        return CompaqVisualFortranLinker.getInstance().getLinker(type);

+    }

+    protected int getMaximumCommandLength() {

+        return DevStudioLibrarian.getInstance().getMaximumCommandLength();

+    }

+    protected String[] getOutputFileSwitch(String outputFile) {

+        return DevStudioLibrarian.getInstance().getOutputFileSwitch(outputFile);

+    }

+    public boolean isCaseSensitive() {

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java
new file mode 100644
index 0000000..d83e3b2
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compaq/CompaqVisualFortranLinker.java
@@ -0,0 +1,77 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compaq;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLinker;

+/**

+ * Adapter for the Compaq(r) Visual Fortran linker.

+ * 

+ * @author Curt Arnold

+ */

+public final class CompaqVisualFortranLinker extends DevStudioCompatibleLinker {

+    private static final CompaqVisualFortranLinker dllLinker = new CompaqVisualFortranLinker(

+            ".dll");

+    private static final CompaqVisualFortranLinker instance = new CompaqVisualFortranLinker(

+            ".exe");

+    public static CompaqVisualFortranLinker getInstance() {

+        return instance;

+    }

+    private CompaqVisualFortranLinker(String outputSuffix) {

+        super("DF", "__bogus__.xxx", outputSuffix);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {

+        args.addElement("/NOLOGO");

+        boolean staticRuntime = linkType.isStaticRuntime();

+        if (staticRuntime) {

+            args.addElement("/libs:static");

+        } else {

+            args.addElement("/libs:dll");

+        }

+        if (debug) {

+            args.addElement("/debug");

+        } else {

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("/dll");

+        } else {

+            args.addElement("/exe");

+        }

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return CompaqVisualFortranLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        StringBuffer buf = new StringBuffer("/OUT:");

+        if (outputFile.indexOf(' ') >= 0) {

+            buf.append('"');

+            buf.append(outputFile);

+            buf.append('"');

+        } else {

+            buf.append(outputFile);

+        }

+        return new String[]{buf.toString()};

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractAslcompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractAslcompiler.java
new file mode 100644
index 0000000..90c539c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractAslcompiler.java
@@ -0,0 +1,75 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.AslcompilerDef;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.TargetDef;

+

+/**

+ * An abstract asl compiler implementation.

+ * 

+ */

+public abstract class AbstractAslcompiler extends AbstractProcessor

+implements Aslcompiler {

+    private String outputSuffix;

+    protected AbstractAslcompiler(String[] sourceExtensions,

+            String[] headerExtensions, String outputSuffix) {

+        super(sourceExtensions, headerExtensions);

+        this.outputSuffix = outputSuffix;

+    }    

+    abstract protected AslcompilerConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            AslcompilerDef specificConfig, TargetDef targetPlatform);

+    

+    public ProcessorConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            ProcessorDef specificConfig, TargetDef targetPlatform) {

+        if (specificConfig == null) {

+            throw new NullPointerException("specificConfig");

+        }

+        return createConfiguration(task, linkType, baseConfigs,

+                (AslcompilerDef) specificConfig, targetPlatform);

+    }

+    

+    public String getOutputFileName(String inputFile) {

+        if (bid(inputFile) > 1) {

+            String baseName = getBaseOutputName(inputFile);

+            return baseName + outputSuffix;

+        }

+        return null;

+    }

+    protected String getBaseOutputName(String inputFile) {

+        int lastSlash = inputFile.lastIndexOf('/');

+        int lastReverse = inputFile.lastIndexOf('\\');

+        int lastSep = inputFile.lastIndexOf(File.separatorChar);

+        if (lastReverse > lastSlash) {

+            lastSlash = lastReverse;

+        }

+        if (lastSep > lastSlash) {

+            lastSlash = lastSep;

+        }

+        int lastPeriod = inputFile.lastIndexOf('.');

+        if (lastPeriod < 0) {

+            lastPeriod = inputFile.length();

+        }

+        return inputFile.substring(lastSlash + 1, lastPeriod);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractAssembler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractAssembler.java
new file mode 100644
index 0000000..1d49232
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractAssembler.java
@@ -0,0 +1,72 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.AssemblerDef;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.TargetDef;

+/**

+ * An abstract assembler implementation.

+ * 

+ */

+public abstract class AbstractAssembler extends AbstractProcessor

+implements Assembler {

+    private String outputSuffix;

+    protected AbstractAssembler(String[] sourceExtensions,

+            String[] headerExtensions, String outputSuffix) {

+        super(sourceExtensions, headerExtensions);

+        this.outputSuffix = outputSuffix;

+    }    

+    abstract protected AssemblerConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            AssemblerDef specificConfig, TargetDef targetPlatform);

+    public ProcessorConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            ProcessorDef specificConfig, TargetDef targetPlatform) {

+        if (specificConfig == null) {

+            throw new NullPointerException("specificConfig");

+        }

+        return createConfiguration(task, linkType, baseConfigs,

+                (AssemblerDef) specificConfig, targetPlatform);

+    }

+    public String getOutputFileName(String inputFile) {

+        if (bid(inputFile) > 1) {

+            String baseName = getBaseOutputName(inputFile);

+            return baseName + outputSuffix;

+        }

+        return null;

+    }

+    protected String getBaseOutputName(String inputFile) {

+        int lastSlash = inputFile.lastIndexOf('/');

+        int lastReverse = inputFile.lastIndexOf('\\');

+        int lastSep = inputFile.lastIndexOf(File.separatorChar);

+        if (lastReverse > lastSlash) {

+            lastSlash = lastReverse;

+        }

+        if (lastSep > lastSlash) {

+            lastSlash = lastSep;

+        }

+        int lastPeriod = inputFile.lastIndexOf('.');

+        if (lastPeriod < 0) {

+            lastPeriod = inputFile.length();

+        }

+        return inputFile.substring(lastSlash + 1, lastPeriod);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java
new file mode 100644
index 0000000..f16ec6c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractCompiler.java
@@ -0,0 +1,205 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.Reader;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.CompilerDef;

+import net.sf.antcontrib.cpptasks.DependencyInfo;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+import net.sf.antcontrib.cpptasks.TargetDef;

+

+/**

+ * An abstract compiler implementation.

+ * 

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public abstract class AbstractCompiler extends AbstractProcessor

+        implements

+            Compiler {

+    private static final String[] emptyIncludeArray = new String[0];

+    private String outputSuffix;

+    protected AbstractCompiler(String[] sourceExtensions,

+            String[] headerExtensions, String outputSuffix) {

+        super(sourceExtensions, headerExtensions);

+        this.outputSuffix = outputSuffix;

+    }

+    /**

+     * Checks file name to see if parse should be attempted

+     * 

+     * Default implementation returns false for files with extensions '.dll',

+     * 'tlb', '.res'

+     *  

+     */

+    protected boolean canParse(File sourceFile) {

+        String sourceName = sourceFile.toString();

+        int lastPeriod = sourceName.lastIndexOf('.');

+        if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) {

+            String ext = sourceName.substring(lastPeriod).toUpperCase();

+            if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) {

+                return false;

+            }

+        }

+        return true;

+    }

+    abstract protected CompilerConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            CompilerDef specificConfig, TargetDef targetPlatform);

+    public ProcessorConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            ProcessorDef specificConfig, TargetDef targetPlatform) {

+        if (specificConfig == null) {

+            throw new NullPointerException("specificConfig");

+        }

+        return createConfiguration(task, linkType, baseConfigs,

+                (CompilerDef) specificConfig, targetPlatform);

+    }

+    abstract protected Parser createParser(File sourceFile);

+    protected String getBaseOutputName(String inputFile) {

+        int lastSlash = inputFile.lastIndexOf('/');

+        int lastReverse = inputFile.lastIndexOf('\\');

+        int lastSep = inputFile.lastIndexOf(File.separatorChar);

+        if (lastReverse > lastSlash) {

+            lastSlash = lastReverse;

+        }

+        if (lastSep > lastSlash) {

+            lastSlash = lastSep;

+        }

+        int lastPeriod = inputFile.lastIndexOf('.');

+        if (lastPeriod < 0) {

+            lastPeriod = inputFile.length();

+        }

+        return inputFile.substring(lastSlash + 1, lastPeriod);

+    }

+    public String getOutputFileName(String inputFile) {

+        //

+        //  if a recognized input file

+        //

+        if (bid(inputFile) > 1) {

+            String baseName = getBaseOutputName(inputFile);

+            return baseName + outputSuffix;

+        }

+        return null;

+    }

+    /**

+     * Returns dependency info for the specified source file

+     * 

+     * @param task

+     *            task for any diagnostic output

+     * @param source

+     *            file to be parsed

+     * @param includePath

+     *            include path to be used to resolve included files

+     * 

+     * @param sysIncludePath

+     *            sysinclude path from build file, files resolved using

+     *            sysInclude path will not participate in dependency analysis

+     * 

+     * @param envIncludePath

+     *            include path from environment variable, files resolved with

+     *            envIncludePath will not participate in dependency analysis

+     * 

+     * @param baseDir

+     *            used to produce relative paths in DependencyInfo

+     * @param includePathIdentifier

+     *            used to distinguish DependencyInfo's from different include

+     *            path settings

+     * 

+     * @author Curt Arnold

+     */

+    public final DependencyInfo parseIncludes(CCTask task, File source,

+            File[] includePath, File[] sysIncludePath, File[] envIncludePath,

+            File baseDir, String includePathIdentifier) {

+        //

+        //  if any of the include files can not be identified

+        //      change the sourceLastModified to Long.MAX_VALUE to

+        //      force recompilation of anything that depends on it

+        long sourceLastModified = source.lastModified();

+        File[] sourcePath = new File[1];

+        sourcePath[0] = new File(source.getParent());

+        Vector onIncludePath = new Vector();

+        Vector onSysIncludePath = new Vector();

+        String baseDirPath;

+        try {

+            baseDirPath = baseDir.getCanonicalPath();

+        } catch (IOException ex) {

+            baseDirPath = baseDir.toString();

+        }

+        String relativeSource = CUtil.getRelativePath(baseDirPath, source);

+        String[] includes = emptyIncludeArray;

+        if (canParse(source)) {

+            Parser parser = createParser(source);

+            try {

+                Reader reader = new BufferedReader(new FileReader(source));

+                parser.parse(reader);

+                includes = parser.getIncludes();

+            } catch (IOException ex) {

+                task.log("Error parsing " + source.toString() + ":"

+                        + ex.toString());

+                includes = new String[0];

+            }

+        }

+        for (int i = 0; i < includes.length; i++) {

+            String includeName = includes[i];

+            if (!resolveInclude(includeName, sourcePath, onIncludePath)) {

+                if (!resolveInclude(includeName, includePath, onIncludePath)) {

+                    if (!resolveInclude(includeName, sysIncludePath,

+                            onSysIncludePath)) {

+                        if (!resolveInclude(includeName, envIncludePath,

+                                onSysIncludePath)) {

+                            //

+                            //  this should be enough to require us to reparse

+                            //     the file with the missing include for dependency

+                            //     information without forcing a rebuild

+                            sourceLastModified++;

+                        }

+                    }

+                }

+            }

+        }

+        for (int i = 0; i < onIncludePath.size(); i++) {

+            String relativeInclude = CUtil.getRelativePath(baseDirPath,

+                    (File) onIncludePath.elementAt(i));

+            onIncludePath.setElementAt(relativeInclude, i);

+        }

+        for (int i = 0; i < onSysIncludePath.size(); i++) {

+            String relativeInclude = CUtil.getRelativePath(baseDirPath,

+                    (File) onSysIncludePath.elementAt(i));

+            onSysIncludePath.setElementAt(relativeInclude, i);

+        }

+        return new DependencyInfo(includePathIdentifier, relativeSource,

+                sourceLastModified, onIncludePath, onSysIncludePath);

+    }

+    protected boolean resolveInclude(String includeName, File[] includePath,

+            Vector onThisPath) {

+        for (int i = 0; i < includePath.length; i++) {

+            File includeFile = new File(includePath[i], includeName);

+            if (includeFile.exists()) {

+                onThisPath.addElement(includeFile);

+                return true;

+            }

+        }

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java
new file mode 100644
index 0000000..20580e5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractLinker.java
@@ -0,0 +1,85 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.LinkerDef;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.TargetDef;

+

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * An abstract Linker implementation.

+ * 

+ * @author Adam Murdoch

+ */

+public abstract class AbstractLinker extends AbstractProcessor

+        implements

+            Linker {

+    public AbstractLinker(String[] objExtensions, String[] ignoredExtensions) {

+        super(objExtensions, ignoredExtensions);

+    }

+    /**

+     * Returns the bid of the processor for the file.

+     * 

+     * A linker will bid 1 on any unrecognized file type.

+     * 

+     * @param inputFile

+     *            filename of input file

+     * @return bid for the file, 0 indicates no interest, 1 indicates that the

+     *         processor recognizes the file but doesn't process it (header

+     *         files, for example), 100 indicates strong interest

+     */

+    public int bid(String inputFile) {

+        int bid = super.bid(inputFile);

+        switch (bid) {

+            //

+            //  unrecognized extension, take the file

+            //

+            case 0 :

+                return 1;

+            //

+            //   discard the ignored extensions

+            //

+            case 1 :

+                return 0;

+        }

+        return bid;

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        return this;

+    }

+    abstract protected LinkerConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            LinkerDef specificConfig, TargetDef targetPlatform);

+    public ProcessorConfiguration createConfiguration(CCTask task,

+            LinkType linkType, ProcessorDef[] baseConfigs,

+            ProcessorDef specificConfig,

+			TargetDef targetPlatform) {

+        if (specificConfig == null) {

+            throw new NullPointerException("specificConfig");

+        }

+        return createConfiguration(task, linkType, baseConfigs,

+                (LinkerDef) specificConfig, targetPlatform);

+    }

+    public String getLibraryKey(File libfile) {

+        return libfile.getName();

+    }

+    public abstract String getOutputFileName(String fileName);

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java
new file mode 100644
index 0000000..b6456d5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AbstractProcessor.java
@@ -0,0 +1,129 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import org.apache.tools.ant.types.Environment;

+/**

+ * An abstract processor (compiler/linker) implementation.

+ * 

+ * @author Curt Arnold

+ */

+public abstract class AbstractProcessor implements Processor, Cloneable {

+    /**

+     * default bid for a file name that the processor recognizes but does not

+     * process and does not want to fall through to the linker

+     */

+    public final static int DEFAULT_DISCARD_BID = 1;

+    /**

+     * default bid for a file name that the processor desires to process

+     */

+    public final static int DEFAULT_PROCESS_BID = 100;

+    /**

+     * Determines the identification of a command line processor by capture the

+     * first line of its output for a specific command.

+     * 

+     * @param command

+     *            array of command line arguments starting with executable

+     *            name. For example, { "cl" }

+     * @param fallback

+     *            start of identifier if there is an error in executing the

+     *            command

+     * @return identifier for the processor

+     */

+    protected static String getIdentifier(String[] command, String fallback) {

+        String identifier = fallback;

+        try {

+            String[] cmdout = CaptureStreamHandler.run(command);

+            if (cmdout.length > 0) {

+                identifier = cmdout[0];

+            }

+        } catch (Throwable ex) {

+            identifier = fallback + ":" + ex.toString();

+        }

+        return identifier;

+    }

+    private final String[] headerExtensions;

+    private final String[] sourceExtensions;

+    protected AbstractProcessor(String[] sourceExtensions,

+            String[] headerExtensions) {

+        this.sourceExtensions = (String[]) sourceExtensions.clone();

+        this.headerExtensions = (String[]) headerExtensions.clone();

+    }

+    /**

+     * Returns the bid of the processor for the file.

+     * 

+     * @param inputFile

+     *            filename of input file

+     * @return bid for the file, 0 indicates no interest, 1 indicates that the

+     *         processor recognizes the file but doesn't process it (header

+     *         files, for example), 100 indicates strong interest

+     */

+    public int bid(String inputFile) {

+        String lower = inputFile.toLowerCase();

+        for (int i = 0; i < sourceExtensions.length; i++) {

+            if (lower.endsWith(sourceExtensions[i])) {

+                return DEFAULT_PROCESS_BID;

+            }

+        }

+        for (int i = 0; i < headerExtensions.length; i++) {

+            if (lower.endsWith(headerExtensions[i])) {

+                return DEFAULT_DISCARD_BID;

+            }

+        }

+        return 0;

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        return this;

+    }

+    protected Object clone() throws CloneNotSupportedException {

+        return super.clone();

+    }

+    public String[] getHeaderExtensions() {

+        return (String[]) this.headerExtensions.clone();

+    }

+    abstract public String getIdentifier();

+    /**

+     * Gets the target operating system architecture

+     * 

+     * @return String target operating system architecture

+     */

+    protected String getOSArch() {

+        return System.getProperty("os.arch");

+    }

+    /**

+     * Gets the target operating system name

+     * 

+     * @return String target operating system name

+     */

+    protected String getOSName() {

+        return System.getProperty("os.name");

+    }

+    public String[] getSourceExtensions() {

+        return (String[]) this.sourceExtensions.clone();

+    }

+    /**

+     * Returns true if the target operating system is Mac OS X or Darwin.

+     * 

+     * @return boolean

+     */

+    protected boolean isDarwin() {

+        String osName = getOSName();

+        return "Mac OS X".equals(osName);

+    }

+    public final String toString() {

+        return getIdentifier();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Aslcompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Aslcompiler.java
new file mode 100644
index 0000000..a210e1c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Aslcompiler.java
@@ -0,0 +1,23 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+/**

+ * A asl compiler.

+ * 

+ */

+public interface Aslcompiler extends Processor {

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AslcompilerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AslcompilerConfiguration.java
new file mode 100644
index 0000000..62ac276
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AslcompilerConfiguration.java
@@ -0,0 +1,29 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import org.apache.tools.ant.BuildException;

+/**

+ * A configuration for an ASL compiler

+ *

+ */

+public interface AslcompilerConfiguration extends ProcessorConfiguration {

+    void aslcompiler(CCTask task, File outputDir, String[] sourceFiles) throws BuildException;

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Assembler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Assembler.java
new file mode 100644
index 0000000..1b6d7b5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Assembler.java
@@ -0,0 +1,23 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+/**

+ * A assembler.

+ * 

+ */

+public interface Assembler extends Processor {

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AssemblerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AssemblerConfiguration.java
new file mode 100644
index 0000000..9411551
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/AssemblerConfiguration.java
@@ -0,0 +1,29 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import org.apache.tools.ant.BuildException;

+/**

+ * A configuration for an assembler

+ *

+ */

+public interface AssemblerConfiguration extends ProcessorConfiguration {

+    void assembler(CCTask task, File outputDir, String[] sourceFiles) throws BuildException;

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java
new file mode 100644
index 0000000..1b89a70
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CaptureStreamHandler.java
@@ -0,0 +1,122 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.BufferedReader;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.InputStreamReader;

+import java.io.OutputStream;

+import java.util.Vector;

+

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;

+/**

+ * Implements ExecuteStreamHandler to capture the output of a Execute to an

+ * array of strings

+ * 

+ * @author Curt Arnold

+ */

+public class CaptureStreamHandler implements ExecuteStreamHandler {

+    /**

+     * Runs an executable and captures the output in a String array

+     * 

+     * @param cmdline

+     *            command line arguments

+     * @return output of process

+     */

+    public static String[] run(String[] cmdline) {

+        CaptureStreamHandler handler = new CaptureStreamHandler();

+        Execute exec = new Execute(handler);

+        exec.setCommandline(cmdline);

+        try {

+            int status = exec.execute();

+        } catch (IOException ex) {

+        }

+        return handler.getOutput();

+    }

+    private InputStream errorStream;

+    private InputStream fromProcess;

+    public CaptureStreamHandler() {

+    }

+    public String[] getOutput() {

+        String[] output;

+        if (fromProcess != null) {

+            Vector lines = new Vector(10);

+            try {

+                BufferedReader reader = new BufferedReader(

+                        new InputStreamReader(errorStream));

+                for (int i = 0; i < 2; i++) {

+                    for (int j = 0; j < 100; j++) {

+                        String line = reader.readLine();

+                        if (line == null) {

+                            reader = new BufferedReader(new InputStreamReader(

+                                    fromProcess));

+                            break;

+                        }

+                        lines.addElement(line);

+                    }

+                }

+            } catch (IOException ex) {

+            }

+            output = new String[lines.size()];

+            lines.copyInto(output);

+            return output;

+        }

+        output = new String[0];

+        return output;

+    }

+    /**

+     * Install a handler for the error stream of the subprocess.

+     * 

+     * @param is

+     *            input stream to read from the error stream from the

+     *            subprocess

+     */

+    public void setProcessErrorStream(InputStream is) throws IOException {

+        errorStream = is;

+    }

+    /**

+     * Install a handler for the input stream of the subprocess.

+     * 

+     * @param os

+     *            output stream to write to the standard input stream of the

+     *            subprocess

+     */

+    public void setProcessInputStream(OutputStream os) throws IOException {

+        os.close();

+    }

+    /**

+     * Install a handler for the output stream of the subprocess.

+     * 

+     * @param is

+     *            input stream to read from the error stream from the

+     *            subprocess

+     */

+    public void setProcessOutputStream(InputStream is) throws IOException {

+        fromProcess = is;

+    }

+    /**

+     * Start handling of the streams.

+     */

+    public void start() throws IOException {

+    }

+    /**

+     * Stop handling of the streams - will not be restarted.

+     */

+    public void stop() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAslcompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAslcompiler.java
new file mode 100644
index 0000000..88dda57
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAslcompiler.java
@@ -0,0 +1,226 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.AslcompilerDef;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.TargetDef;

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * An abstract ASL Compiler implementation which uses an external program to

+ * perform the ASL compile.

+ * 

+ */

+public abstract class CommandLineAslcompiler extends AbstractAslcompiler{

+

+    private String command;

+    private String identifier;

+    private String identifierArg;

+    

+    protected CommandLineAslcompiler(String command, String identifierArg,

+            String[] sourceExtensions, String[] headerExtensions,

+            String outputSuffix) {

+        super(sourceExtensions, headerExtensions, outputSuffix);

+        this.command = command;

+        this.identifierArg = identifierArg;

+    }

+    

+    abstract protected void addImpliedArgs(Vector args, boolean debug,

+        Boolean defaultflag);

+   

+    /**

+     * Compile a ACPI source file

+     * 

+     */

+    public void aslcompiler(CCTask task, File outputDir, String[] sourceFiles,

+        String[] args, String[] endArgs) throws BuildException{

+        String command = getCommand();

+        int baseLength = command.length() + args.length + endArgs.length; 

+        for (int i = 0; i < args.length; i++) {

+          baseLength += args[i].length();

+        }

+        for (int i = 0; i < endArgs.length; i++) {

+            baseLength += endArgs[i].length();

+        }

+        if (baseLength > getMaximumCommandLength()) {

+            throw new BuildException(

+                "Command line is over maximum length without sepcifying source file");

+        }

+        int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();

+        int argumentCountPerInputFile = getArgumentCountPerInputFIle();

+        for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {

+            int cmdLength = baseLength;

+            int firstFileNextExec;

+            for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length

+                && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {

+                cmdLength += getTotalArgumentLengthForInputFile(outputDir, 

+                    sourceFiles[firstFileNextExec]);  

+                if (cmdLength >= getMaximumCommandLength()) 

+                    break;

+            }

+            if (firstFileNextExec == sourceIndex) {

+                throw new BuildException(

+                    "Extremely long file name, can't fit on command line");

+            }

+            int argCount = args.length + 1 + endArgs.length

+                    + (firstFileNextExec - sourceIndex)

+                    * argumentCountPerInputFile;

+            String[] commandline = new String[argCount];

+            int index = 0;

+            commandline[index++] = command;

+            for (int j = 0; j < args.length; j++) {

+                commandline[index++] = args[j];

+            }

+            for (int j = sourceIndex; j < firstFileNextExec; j++) {

+                for (int k = 0; k < argumentCountPerInputFile; k++) {

+                    commandline[index++] = getInputFileArgument(outputDir, 

+                            sourceFiles[j], k);                    

+                }

+            }

+            for (int j = 0; j < endArgs.length; j++) {

+                commandline[index++] = endArgs[j];

+            }

+            int retval = runCommand(task, outputDir, commandline);

+            // if with monitor, add more code

+            if (retval != 0) {

+               throw new BuildException(this.getCommand()

+                       + " failed with return code " + retval,

+                       task.getLocation());

+            }

+            sourceIndex = firstFileNextExec;

+        }

+    }

+    

+    protected AslcompilerConfiguration createConfiguration(final CCTask task,

+          final LinkType linkType, 

+          final ProcessorDef[] baseDefs, 

+          final AslcompilerDef specificDef,

+          final TargetDef targetPlatform) {

+        Vector args = new Vector();

+        AslcompilerDef[] defaultProviders = new AslcompilerDef[baseDefs.length +1];

+        for (int i = 0; i < baseDefs.length; i++) {

+            defaultProviders[i + 1] = (AslcompilerDef) baseDefs[i];

+        }

+        defaultProviders[0] = specificDef;

+        Vector cmdArgs = new Vector();

+        //

+        //  add command line arguments inherited from <cc> element

+        //    any "extends" and finally and specific AslcompilerDef

+        //

+        CommandLineArgument[] commandArgs;

+        for (int i = defaultProviders.length - 1; i >=0; i--){

+            commandArgs = defaultProviders[i].getActiveProcessorArgs();

+            for (int j = 0; j < commandArgs.length; j++) {

+                if (commandArgs[j].getLocation() == 0) {

+                    args.addElement(commandArgs[j].getValue());

+                }

+                else {

+                    cmdArgs.addElement(commandArgs[j]);

+                }

+            }

+        }

+        // omit param

+        boolean debug = specificDef.getDebug(baseDefs, 0);

+        Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);

+        this.addImpliedArgs(args, debug, defaultflag);

+        Enumeration argEnum = cmdArgs.elements();

+        int endCount = 0;

+        while( argEnum.hasMoreElements()) {

+            CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement();

+            switch (arg.getLocation()) {

+                case 1 :

+                    args.addElement(arg.getValue());

+                    break;

+                case 2 :

+                    endCount++;

+                    break;

+            }

+        }

+        String[] endArgs = new String[endCount];

+        argEnum = cmdArgs.elements();

+        int index = 0;

+        while (argEnum.hasMoreElements()) {

+            CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement();

+            if (arg.getLocation() == 2) {

+                endArgs[index++] = arg.getValue();

+            }

+        }

+        String[] argArray = new String[args.size()];

+        args.copyInto(argArray);

+        return new CommandLineAslcompilerConfiguration(this, argArray, true, endArgs);

+    }

+    

+    protected int getArgumentCountPerInputFile() {

+        return 1;

+    }

+    

+    public String getIdentifier() {

+        if (identifier == null) {

+            if (identifierArg == null) {

+               identifier = getIdentifier(new String[]{command}, command);

+            }

+            else {

+                identifier = getIdentifier(

+                    new String[]{command, identifierArg}, command);

+            }

+        }

+        return identifier;

+    }

+    

+    public final String getCommand() {

+      return command;

+    }

+    abstract public int getMaximumCommandLength();

+    public void setCommand(String command) {

+      this.command = command;

+    }

+    protected int getTotalArgumentLengthForInputFile(File outputDir,

+        String inputFile) {

+        return inputFile.length() + 1;

+    }

+    protected int runCommand(CCTask task, File workingDir, String[] cmdline) 

+            throws BuildException {

+        return CUtil.runCommand(task, workingDir, cmdline, false, null);

+      

+    }

+    protected int getMaximumInputFilesPerCommand(){

+        return 1;

+    }

+    protected int getArgumentCountPerInputFIle(){

+        return 1;

+    }

+    protected String getInputFileArgument(File outputDir, String filename, int index) {

+        //

+        //   if there is an embedded space,

+        //      must enclose in quotes

+        if (filename.indexOf(' ') >= 0) {

+            StringBuffer buf = new StringBuffer("\"");

+            buf.append(filename);

+            buf.append("\"");

+            return buf.toString();

+        }

+        return filename;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAslcompilerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAslcompilerConfiguration.java
new file mode 100644
index 0000000..9a3457d
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAslcompilerConfiguration.java
@@ -0,0 +1,93 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+

+import org.apache.tools.ant.BuildException;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+

+/**

+ * A configuration for an ASL compiler

+ * 

+ */

+public final class CommandLineAslcompilerConfiguration implements

+                AslcompilerConfiguration {

+

+    private String[] args;

+

+    private CommandLineAslcompiler acpi;

+

+    private String[] endArgs;

+

+    private boolean rebuild;

+

+    public CommandLineAslcompilerConfiguration (CommandLineAslcompiler acpi,

+                    String[] args, boolean rebuild, String[] endArgs) {

+        if (acpi == null) {

+            throw new NullPointerException("acpi");

+        }

+        if (args == null) {

+            this.args = new String[0];

+        } else {

+            this.args = (String[]) args.clone();

+        }

+        this.acpi = acpi;

+        this.rebuild = rebuild;

+        this.endArgs = (String[]) endArgs.clone();

+    }

+

+    public int bid (String inputFile) {

+        int acpiBid = acpi.bid(inputFile);

+        return acpiBid;

+    }

+

+    public void aslcompiler (CCTask task, File outputDir, String[] sourceFiles)

+                    throws BuildException {

+        try {

+            acpi.aslcompiler(task, outputDir, sourceFiles, args, endArgs);

+        } catch (BuildException ex) {

+            throw ex;

+        }

+    }

+

+    public String getIdentifier () {

+        return acpi.getCommand();

+    }

+

+    public ProcessorParam[] getParams () {

+        return new ProcessorParam[0];

+    }

+

+    public boolean getRebuild () {

+        return rebuild;

+    }

+

+    public String[] getPreArguments () {

+        return (String[]) args.clone();

+    }

+

+    public String[] getEndArguments () {

+        return (String[]) endArgs.clone();

+    }

+

+    public String getOutputFileName (String inputFile) {

+        return acpi.getOutputFileName(inputFile);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAssembler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAssembler.java
new file mode 100644
index 0000000..f01fc5e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAssembler.java
@@ -0,0 +1,326 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+import java.io.IOException;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.AssemblerDef;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.TargetDef;

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+ * An abstract Assembler implementation which uses an external program to

+ * perform the assemble.

+ * 

+ */

+public abstract class CommandLineAssembler extends AbstractAssembler {

+

+    private String command;

+

+    private String identifier;

+

+    private String identifierArg;

+

+    protected CommandLineAssembler (String command, String identifierArg,

+                    String[] sourceExtensions, String[] headerExtensions,

+                    String outputSuffix) {

+        super(sourceExtensions, headerExtensions, outputSuffix);

+        this.command = command;

+        this.identifierArg = identifierArg;

+    }

+

+    abstract protected void addImpliedArgs(Vector args, boolean debug,

+                    Boolean defaultflag);

+

+    /**

+     * Adds command-line arguments for include directories.

+     * 

+     * If relativeArgs is not null will add corresponding relative paths include

+     * switches to that vector (for use in building a configuration identifier

+     * that is consistent between machines).

+     * 

+     * @param baseDirPaths

+     *            A vector containing the parts of the working directory,

+     *            produced by CUtil.DecomposeFile.

+     * @param includeDirs

+     *            Array of include directory paths

+     * @param args

+     *            Vector of command line arguments used to execute the task

+     * @param relativeArgs

+     *            Vector of command line arguments used to build the

+     *            configuration identifier

+     */

+    protected void addIncludes(String baseDirPath, File[] includeDirs,

+                    Vector args, Vector relativeArgs, StringBuffer includePathId) {

+        for (int i = 0; i < includeDirs.length; i++) {

+            args.addElement(getIncludeDirSwitch(includeDirs[i]

+                            .getAbsolutePath()));

+            if (relativeArgs != null) {

+                String relative = CUtil.getRelativePath(baseDirPath,

+                                includeDirs[i]);

+                relativeArgs.addElement(getIncludeDirSwitch(relative));

+                if (includePathId != null) {

+                    if (includePathId.length() == 0) {

+                        includePathId.append("/I");

+                    } else {

+                        includePathId.append(" /I");

+                    }

+                    includePathId.append(relative);

+                }

+            }

+        }

+    }

+

+    abstract protected String getIncludeDirSwitch(String source);

+

+    /**

+     * Assembles a source file

+     * 

+     */

+    public void assembler(CCTask task, File outputDir, String[] sourceFiles,

+                    String[] args, String[] endArgs) throws BuildException {

+        String command = getCommand();

+        int baseLength = command.length() + args.length + endArgs.length;

+        for (int i = 0; i < args.length; i++) {

+            baseLength += args[i].length();

+        }

+        for (int i = 0; i < endArgs.length; i++) {

+            baseLength += endArgs[i].length();

+        }

+        if (baseLength > getMaximumCommandLength()) {

+            throw new BuildException(

+                            "Command line is over maximum length without sepcifying source file");

+        }

+        int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();

+        int argumentCountPerInputFile = getArgumentCountPerInputFIle();

+        for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {

+            int cmdLength = baseLength;

+            int firstFileNextExec;

+            for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length

+                            && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {

+                cmdLength += getTotalArgumentLengthForInputFile(outputDir,

+                                sourceFiles[firstFileNextExec]);

+                if (cmdLength >= getMaximumCommandLength())

+                    break;

+            }

+            if (firstFileNextExec == sourceIndex) {

+                throw new BuildException(

+                                "Extremely long file name, can't fit on command line");

+            }

+            int argCount = args.length + 1 + endArgs.length

+                            + (firstFileNextExec - sourceIndex)

+                            * argumentCountPerInputFile;

+            String[] commandline = new String[argCount];

+            int index = 0;

+            commandline[index++] = command;

+            for (int j = 0; j < args.length; j++) {

+                commandline[index++] = args[j];

+            }

+            for (int j = sourceIndex; j < firstFileNextExec; j++) {

+                for (int k = 0; k < argumentCountPerInputFile; k++) {

+                    commandline[index++] = getInputFileArgument(outputDir,

+                                    sourceFiles[j], k);

+                }

+            }

+            for (int j = 0; j < endArgs.length; j++) {

+                commandline[index++] = endArgs[j];

+            }

+            int retval = runCommand(task, outputDir, commandline);

+            // if with monitor, add more code

+            if (retval != 0) {

+                throw new BuildException(this.getCommand()

+                                + " failed with return code " + retval, task

+                                .getLocation());

+            }

+            sourceIndex = firstFileNextExec;

+        }

+    }

+

+    protected AssemblerConfiguration createConfiguration(final CCTask task,

+                    final LinkType linkType, final ProcessorDef[] baseDefs,

+                    final AssemblerDef specificDef,

+                    final TargetDef targetPlatform) {

+        Vector args = new Vector();

+        AssemblerDef[] defaultProviders = new AssemblerDef[baseDefs.length + 1];

+        for (int i = 0; i < baseDefs.length; i++) {

+            defaultProviders[i + 1] = (AssemblerDef) baseDefs[i];

+        }

+        defaultProviders[0] = specificDef;

+        Vector cmdArgs = new Vector();

+        //

+        // add command line arguments inherited from <cc> element

+        // any "extends" and finally and specific AssemblerDef

+        //

+        CommandLineArgument[] commandArgs;

+        for (int i = defaultProviders.length - 1; i >= 0; i--) {

+            commandArgs = defaultProviders[i].getActiveProcessorArgs();

+            for (int j = 0; j < commandArgs.length; j++) {

+                if (commandArgs[j].getLocation() == 0) {

+                    args.addElement(commandArgs[j].getValue());

+                } else {

+                    cmdArgs.addElement(commandArgs[j]);

+                }

+            }

+        }

+        // omit param

+        boolean debug = specificDef.getDebug(baseDefs, 0);

+        Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);

+        this.addImpliedArgs(args, debug, defaultflag);

+        //

+        // Want to have distinct set of arguments with relative

+        // path names for includes that are used to build

+        // the configuration identifier

+        //

+        Vector relativeArgs = (Vector) args.clone();

+        //

+        // add all active include an

+        //

+        StringBuffer includePathIdentifier = new StringBuffer();

+        File baseDir = specificDef.getProject().getBaseDir();

+        String baseDirPath;

+        try {

+            baseDirPath = baseDir.getCanonicalPath();

+        } catch (IOException ex) {

+            baseDirPath = baseDir.toString();

+        }

+        Vector includePath = new Vector();

+        Vector sysIncludePath = new Vector();

+        for (int i = defaultProviders.length - 1; i >= 0; i--) {

+            String[] incPath = defaultProviders[i].getActiveIncludePaths();

+            for (int j = 0; j < incPath.length; j++) {

+                includePath.addElement(incPath[j]);

+            }

+            incPath = defaultProviders[i].getActiveSysIncludePaths();

+            for (int j = 0; j < incPath.length; j++) {

+                sysIncludePath.addElement(incPath[j]);

+            }

+        }

+        File[] incPath = new File[includePath.size()];

+        for (int i = 0; i < includePath.size(); i++) {

+            incPath[i] = new File((String) includePath.elementAt(i));

+        }

+        File[] sysIncPath = new File[sysIncludePath.size()];

+        for (int i = 0; i < sysIncludePath.size(); i++) {

+            sysIncPath[i] = new File((String) sysIncludePath.elementAt(i));

+        }

+        addIncludes(baseDirPath, incPath, args, relativeArgs,

+                        includePathIdentifier);

+        addIncludes(baseDirPath, sysIncPath, args, null, null);

+        StringBuffer buf = new StringBuffer(getIdentifier());

+        for (int i = 0; i < relativeArgs.size(); i++) {

+            buf.append(relativeArgs.elementAt(i));

+            buf.append(' ');

+        }

+        buf.setLength(buf.length() - 1);

+        Enumeration argEnum = cmdArgs.elements();

+        int endCount = 0;

+        while (argEnum.hasMoreElements()) {

+            CommandLineArgument arg = (CommandLineArgument) argEnum

+                            .nextElement();

+            switch (arg.getLocation()) {

+            case 1:

+                args.addElement(arg.getValue());

+                break;

+            case 2:

+                endCount++;

+                break;

+            }

+        }

+        String[] endArgs = new String[endCount];

+        argEnum = cmdArgs.elements();

+        int index = 0;

+        while (argEnum.hasMoreElements()) {

+            CommandLineArgument arg = (CommandLineArgument) argEnum

+                            .nextElement();

+            if (arg.getLocation() == 2) {

+                endArgs[index++] = arg.getValue();

+            }

+        }

+        String[] argArray = new String[args.size()];

+        args.copyInto(argArray);

+        return new CommandLineAssemblerConfiguration(this, incPath, sysIncPath,

+                        new File[0], argArray, true, endArgs, new String[0]);

+    }

+

+    protected int getArgumentCountPerInputFile() {

+        return 1;

+    }

+

+    protected abstract File[] getEnvironmentIncludePath();

+

+    public String getIdentifier() {

+        if (identifier == null) {

+            if (identifierArg == null) {

+                identifier = getIdentifier(new String[] { command }, command);

+            } else {

+                identifier = getIdentifier(new String[] { command,

+                                identifierArg }, command);

+            }

+        }

+        return identifier;

+    }

+

+    public final String getCommand() {

+        return command;

+    }

+

+    abstract public int getMaximumCommandLength();

+

+    public void setCommand(String command) {

+        this.command = command;

+    }

+

+    protected int getTotalArgumentLengthForInputFile(File outputDir,

+                    String inputFile) {

+        return inputFile.length() + 1;

+    }

+

+    protected int runCommand(CCTask task, File workingDir, String[] cmdline)

+                    throws BuildException {

+        return CUtil.runCommand(task, workingDir, cmdline, false, null);

+    }

+

+    protected int getMaximumInputFilesPerCommand() {

+        return Integer.MAX_VALUE;

+    }

+

+    protected int getArgumentCountPerInputFIle() {

+        return 1;

+    }

+

+    protected String getInputFileArgument(File outputDir, String filename,

+                    int index) {

+        //

+        // if there is an embedded space,

+        // must enclose in quotes

+        if (filename.indexOf(' ') >= 0) {

+            StringBuffer buf = new StringBuffer("\"");

+            buf.append(filename);

+            buf.append("\"");

+            return buf.toString();

+        }

+        return filename;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAssemblerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAssemblerConfiguration.java
new file mode 100644
index 0000000..542d441
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineAssemblerConfiguration.java
@@ -0,0 +1,123 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+

+import org.apache.tools.ant.BuildException;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+

+/**

+ * A configuration for an assember

+ * 

+ */

+public final class CommandLineAssemblerConfiguration implements

+                AssemblerConfiguration {

+

+    private String[] args;

+

+    private CommandLineAssembler assembler;

+

+    private String[] endArgs;

+

+    //

+    // include path from environment variable

+    // not explicitly stated in Ant script

+    //

+    private File[] envIncludePath;

+

+    private String[] exceptFiles;

+

+    private File[] includePath;

+

+    private boolean rebuild;

+

+    private File[] sysIncludePath;

+

+    public CommandLineAssemblerConfiguration (CommandLineAssembler assembler,

+                    File[] includePath, File[] sysIncludePath,

+                    File[] envIncludePath, String[] args, boolean rebuild,

+                    String[] endArgs, String[] exceptFiles) {

+        if (assembler == null) {

+            throw new NullPointerException("assembler");

+        }

+        if (args == null) {

+            this.args = new String[0];

+        } else {

+            this.args = (String[]) args.clone();

+        }

+        if (includePath == null) {

+            this.includePath = new File[0];

+        } else {

+            this.includePath = (File[]) includePath.clone();

+        }

+        if (sysIncludePath == null) {

+            this.sysIncludePath = new File[0];

+        } else {

+            this.sysIncludePath = (File[]) sysIncludePath.clone();

+        }

+        if (envIncludePath == null) {

+            this.envIncludePath = new File[0];

+        } else {

+            this.envIncludePath = (File[]) envIncludePath.clone();

+        }

+        this.assembler = assembler;

+        this.rebuild = rebuild;

+        this.endArgs = (String[]) endArgs.clone();

+        this.exceptFiles = (String[]) exceptFiles.clone();

+    }

+

+    public int bid(String inputFile) {

+        int assembleBid = assembler.bid(inputFile);

+        return assembleBid;

+    }

+

+    public void assembler(CCTask task, File outputDir, String[] sourceFiles)

+                    throws BuildException {

+        try {

+            assembler.assembler(task, outputDir, sourceFiles, args, endArgs);

+        } catch (BuildException ex) {

+            throw ex;

+        }

+    }

+

+    public String getOutputFileName(String inputFile) {

+        return assembler.getOutputFileName(inputFile);

+    }

+

+    public String getIdentifier() {

+        return assembler.getCommand();

+    }

+

+    public ProcessorParam[] getParams() {

+        return new ProcessorParam[0];

+    }

+

+    public boolean getRebuild() {

+        return rebuild;

+    }

+

+    public String[] getPreArguments() {

+        return (String[]) args.clone();

+    }

+

+    public String[] getEndArguments() {

+        return (String[]) endArgs.clone();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java
new file mode 100644
index 0000000..442d6b8
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCCompiler.java
@@ -0,0 +1,42 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * An abstract Compiler implementation which uses an external program to

+ * perform the compile.

+ * 

+ * @author Adam Murdoch

+ */

+public abstract class CommandLineCCompiler extends CommandLineCompiler {

+    protected CommandLineCCompiler(String command, String identifierArg,

+            String[] sourceExtensions, String[] headerExtensions,

+            String outputSuffix, boolean libtool,

+            CommandLineCCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super(command, identifierArg, sourceExtensions, headerExtensions,

+                outputSuffix, libtool, libtoolCompiler, newEnvironment, env);

+    }

+    protected Parser createParser(File source) {

+        return new CParser();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java
new file mode 100644
index 0000000..3f45ce5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCompiler.java
@@ -0,0 +1,435 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+import java.io.IOException;

+import java.util.Enumeration;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.CompilerDef;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+import net.sf.antcontrib.cpptasks.types.UndefineArgument;

+import net.sf.antcontrib.cpptasks.TargetDef;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;;

+/**

+ * An abstract Compiler implementation which uses an external program to

+ * perform the compile.

+ * 

+ * @author Adam Murdoch

+ */

+public abstract class CommandLineCompiler extends AbstractCompiler {

+    private String command;

+    private final Environment env;

+    private String identifier;

+    private String identifierArg;

+    private boolean libtool;

+    private CommandLineCompiler libtoolCompiler;

+    private final boolean newEnvironment;

+    protected CommandLineCompiler(String command, String identifierArg,

+            String[] sourceExtensions, String[] headerExtensions,

+            String outputSuffix, boolean libtool,

+            CommandLineCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super(sourceExtensions, headerExtensions, outputSuffix);

+        this.command = command;

+        if (libtool && libtoolCompiler != null) {

+            throw new java.lang.IllegalArgumentException(

+                    "libtoolCompiler should be null when libtool is true");

+        }

+        this.libtool = libtool;

+        this.libtoolCompiler = libtoolCompiler;

+        this.identifierArg = identifierArg;

+        this.newEnvironment = newEnvironment;

+        this.env = env;

+    }

+    abstract protected void addImpliedArgs(Vector args, boolean debug,

+            boolean multithreaded, boolean exceptions, LinkType linkType,

+			Boolean rtti, OptimizationEnum optimization, Boolean defaultflag);

+    /**

+     * Adds command-line arguments for include directories.

+     * 

+     * If relativeArgs is not null will add corresponding relative paths

+     * include switches to that vector (for use in building a configuration

+     * identifier that is consistent between machines).

+     * 

+     * @param baseDirPaths

+     *            A vector containing the parts of the working directory,

+     *            produced by CUtil.DecomposeFile.

+     * @param includeDirs

+     *            Array of include directory paths

+     * @param args

+     *            Vector of command line arguments used to execute the task

+     * @param relativeArgs

+     *            Vector of command line arguments used to build the

+     *            configuration identifier

+     */

+    protected void addIncludes(String baseDirPath, File[] includeDirs,

+            Vector args, Vector relativeArgs, StringBuffer includePathId) {

+        for (int i = 0; i < includeDirs.length; i++) {

+            args.addElement(getIncludeDirSwitch(includeDirs[i]

+                    .getAbsolutePath()));

+            if (relativeArgs != null) {

+                String relative = CUtil.getRelativePath(baseDirPath,

+                        includeDirs[i]);

+                relativeArgs.addElement(getIncludeDirSwitch(relative));

+                if (includePathId != null) {

+                    if (includePathId.length() == 0) {

+                        includePathId.append("/I");

+                    } else {

+                        includePathId.append(" /I");

+                    }

+                    includePathId.append(relative);

+                }

+            }

+        }

+    }

+    abstract protected void addWarningSwitch(Vector args, int warnings);

+    protected void buildDefineArguments(CompilerDef[] defs, Vector args) {

+        //

+        //   assume that we aren't inheriting defines from containing <cc>

+        //

+        UndefineArgument[] merged = defs[0].getActiveDefines();

+        for (int i = 1; i < defs.length; i++) {

+            //

+            //  if we are inheriting, merge the specific defines with the

+            //      containing defines

+            merged = UndefineArgument.merge(defs[i].getActiveDefines(), merged);

+        }

+        StringBuffer buf = new StringBuffer(30);

+        for (int i = 0; i < merged.length; i++) {

+            buf.setLength(0);

+            UndefineArgument current = merged[i];

+            if (current.isDefine()) {

+                getDefineSwitch(buf, current.getName(), current.getValue());

+            } else {

+                getUndefineSwitch(buf, current.getName());

+            }

+            args.addElement(buf.toString());

+        }

+    }

+    /**

+     * Compiles a source file.

+     * 

+     * @author Curt Arnold

+     */

+    public void compile(CCTask task, File outputDir, String[] sourceFiles,

+            String[] args, String[] endArgs, boolean relentless,

+            CommandLineCompilerConfiguration config, ProgressMonitor monitor)

+            throws BuildException {

+        BuildException exc = null;

+        //

+        //   determine length of executable name and args

+        //

+        String command = getCommand();

+        int baseLength = command.length() + args.length + endArgs.length;

+        if (libtool) {

+            baseLength += 8;

+        }

+        for (int i = 0; i < args.length; i++) {

+            baseLength += args[i].length();

+        }

+        for (int i = 0; i < endArgs.length; i++) {

+            baseLength += endArgs[i].length();

+        }

+        if (baseLength > getMaximumCommandLength()) {

+            throw new BuildException(

+                    "Command line is over maximum length without specifying source file");

+        }

+        //

+        //  typically either 1 or Integer.MAX_VALUE

+        //

+        int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();

+        int argumentCountPerInputFile = getArgumentCountPerInputFile();

+        for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {

+            int cmdLength = baseLength;

+            int firstFileNextExec;

+            for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length

+                    && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {

+                cmdLength += getTotalArgumentLengthForInputFile(outputDir,

+                        sourceFiles[firstFileNextExec]);

+                if (cmdLength >= getMaximumCommandLength())

+                    break;

+            }

+            if (firstFileNextExec == sourceIndex) {

+                throw new BuildException(

+                        "Extremely long file name, can't fit on command line");

+            }

+            int argCount = args.length + 1 + endArgs.length

+                    + (firstFileNextExec - sourceIndex)

+                    * argumentCountPerInputFile;

+            if (libtool) {

+                argCount++;

+            }

+            String[] commandline = new String[argCount];

+            int index = 0;

+            if (libtool) {

+                commandline[index++] = "libtool";

+            }

+            commandline[index++] = command;

+            for (int j = 0; j < args.length; j++) {

+                commandline[index++] = args[j];

+            }

+            for (int j = sourceIndex; j < firstFileNextExec; j++) {

+                for (int k = 0; k < argumentCountPerInputFile; k++) {

+                    commandline[index++] = getInputFileArgument(outputDir,

+                            sourceFiles[j], k);

+                }

+            }

+            for (int j = 0; j < endArgs.length; j++) {

+                commandline[index++] = endArgs[j];

+            }

+            int retval = runCommand(task, outputDir, commandline);

+            if (monitor != null) {

+                String[] fileNames = new String[firstFileNextExec - sourceIndex];

+                for (int j = 0; j < fileNames.length; j++) {

+                    fileNames[j] = sourceFiles[sourceIndex + j];

+                }

+                monitor.progress(fileNames);

+            }

+            //

+            //   if the process returned a failure code and

+            //      we aren't holding an exception from an earlier

+            //      interation

+            if (retval != 0 && exc == null) {

+                //

+                //   construct the exception

+                //

+                exc = new BuildException(this.getCommand()

+                        + " failed with return code " + retval, task

+                        .getLocation());

+                //

+                //   and throw it now unless we are relentless

+                //

+                if (!relentless) {

+                    throw exc;

+                }

+            }

+            sourceIndex = firstFileNextExec;

+        }

+        //

+        //   if the compiler returned a failure value earlier

+        //      then throw an exception

+        if (exc != null) {

+            throw exc;

+        }

+    }

+    protected CompilerConfiguration createConfiguration(final CCTask task,

+            final LinkType linkType, 

+			final ProcessorDef[] baseDefs, 

+			final CompilerDef specificDef,

+			final TargetDef targetPlatform) {

+        Vector args = new Vector();

+        CompilerDef[] defaultProviders = new CompilerDef[baseDefs.length + 1];

+        for (int i = 0; i < baseDefs.length; i++) {

+            defaultProviders[i + 1] = (CompilerDef) baseDefs[i];

+        }

+        defaultProviders[0] = specificDef;

+        Vector cmdArgs = new Vector();

+        //

+        //   add command line arguments inherited from <cc> element

+        //     any "extends" and finally the specific CompilerDef

+        CommandLineArgument[] commandArgs;

+        for (int i = defaultProviders.length - 1; i >= 0; i--) {

+            commandArgs = defaultProviders[i].getActiveProcessorArgs();

+            for (int j = 0; j < commandArgs.length; j++) {

+                if (commandArgs[j].getLocation() == 0) {

+                    args.addElement(commandArgs[j].getValue());

+                } else {

+                    cmdArgs.addElement(commandArgs[j]);

+                }

+            }

+        }

+        Vector params = new Vector();

+        //

+        //   add command line arguments inherited from <cc> element

+        //     any "extends" and finally the specific CompilerDef

+        ProcessorParam[] paramArray;

+        for (int i = defaultProviders.length - 1; i >= 0; i--) {

+            paramArray = defaultProviders[i].getActiveProcessorParams();

+            for (int j = 0; j < paramArray.length; j++) {

+                params.add(paramArray[j]);

+            }

+        }

+        paramArray = (ProcessorParam[]) (params

+                .toArray(new ProcessorParam[params.size()]));

+        boolean multithreaded = specificDef.getMultithreaded(defaultProviders,

+                1);

+        boolean debug = specificDef.getDebug(baseDefs, 0);

+        boolean exceptions = specificDef.getExceptions(defaultProviders, 1);

+        Boolean rtti = specificDef.getRtti(defaultProviders, 1);

+        Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);

+        OptimizationEnum optimization = specificDef.getOptimization(defaultProviders, 1);

+        this.addImpliedArgs(args, debug, multithreaded, exceptions, linkType, rtti, optimization, defaultflag);

+        //

+        //    add all appropriate defines and undefines

+        //

+        buildDefineArguments(defaultProviders, args);

+        //

+        //   Want to have distinct set of arguments with relative

+        //      path names for includes that are used to build

+        //      the configuration identifier

+        //

+        Vector relativeArgs = (Vector) args.clone();

+        //

+        //    add all active include and sysincludes

+        //

+        StringBuffer includePathIdentifier = new StringBuffer();

+        File baseDir = specificDef.getProject().getBaseDir();

+        String baseDirPath;

+        try {

+            baseDirPath = baseDir.getCanonicalPath();

+        } catch (IOException ex) {

+            baseDirPath = baseDir.toString();

+        }

+        Vector includePath = new Vector();

+        Vector sysIncludePath = new Vector();

+        for (int i = defaultProviders.length - 1; i >= 0; i--) {

+            String[] incPath = defaultProviders[i].getActiveIncludePaths();

+            for (int j = 0; j < incPath.length; j++) {

+                includePath.addElement(incPath[j]);

+            }

+            incPath = defaultProviders[i].getActiveSysIncludePaths();

+            for (int j = 0; j < incPath.length; j++) {

+                sysIncludePath.addElement(incPath[j]);

+            }

+        }

+        File[] incPath = new File[includePath.size()];

+        for (int i = 0; i < includePath.size(); i++) {

+            incPath[i] = new File((String) includePath.elementAt(i));

+        }

+        File[] sysIncPath = new File[sysIncludePath.size()];

+        for (int i = 0; i < sysIncludePath.size(); i++) {

+            sysIncPath[i] = new File((String) sysIncludePath.elementAt(i));

+        }

+        addIncludes(baseDirPath, incPath, args, relativeArgs,

+                includePathIdentifier);

+        addIncludes(baseDirPath, sysIncPath, args, null, null);

+        StringBuffer buf = new StringBuffer(getIdentifier());

+        for (int i = 0; i < relativeArgs.size(); i++) {

+            buf.append(relativeArgs.elementAt(i));

+            buf.append(' ');

+        }

+        buf.setLength(buf.length() - 1);

+        String configId = buf.toString();

+        int warnings = specificDef.getWarnings(defaultProviders, 0);

+        addWarningSwitch(args, warnings);

+        Enumeration argEnum = cmdArgs.elements();

+        int endCount = 0;

+        while (argEnum.hasMoreElements()) {

+            CommandLineArgument arg = (CommandLineArgument) argEnum

+                    .nextElement();

+            switch (arg.getLocation()) {

+                case 1 :

+                    args.addElement(arg.getValue());

+                    break;

+                case 2 :

+                    endCount++;

+                    break;

+            }

+        }

+        String[] endArgs = new String[endCount];

+        argEnum = cmdArgs.elements();

+        int index = 0;

+        while (argEnum.hasMoreElements()) {

+            CommandLineArgument arg = (CommandLineArgument) argEnum

+                    .nextElement();

+            if (arg.getLocation() == 2) {

+                endArgs[index++] = arg.getValue();

+            }

+        }

+        String[] argArray = new String[args.size()];

+        args.copyInto(argArray);

+        boolean rebuild = specificDef.getRebuild(baseDefs, 0);

+        File[] envIncludePath = getEnvironmentIncludePath();

+        return new CommandLineCompilerConfiguration(this, configId, incPath,

+                sysIncPath, envIncludePath, includePathIdentifier.toString(),

+                argArray, paramArray, rebuild, endArgs);

+    }

+    protected int getArgumentCountPerInputFile() {

+        return 1;

+    }

+    protected final String getCommand() {

+        return command;

+    }

+    abstract protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value);

+    protected abstract File[] getEnvironmentIncludePath();

+    public String getIdentifier() {

+        if (identifier == null) {

+            if (identifierArg == null) {

+                identifier = getIdentifier(new String[]{command}, command);

+            } else {

+                identifier = getIdentifier(

+                        new String[]{command, identifierArg}, command);

+            }

+        }

+        return identifier;

+    }

+    abstract protected String getIncludeDirSwitch(String source);

+    protected String getInputFileArgument(File outputDir, String filename,

+            int index) {

+        //

+        //   if there is an embedded space,

+        //      must enclose in quotes

+        if (filename.indexOf(' ') >= 0) {

+            StringBuffer buf = new StringBuffer("\"");

+            buf.append(filename);

+            buf.append("\"");

+            return buf.toString();

+        }

+        return filename;

+    }

+    protected final boolean getLibtool() {

+        return libtool;

+    }

+    /**

+     * Obtains the same compiler, but with libtool set

+     * 

+     * Default behavior is to ignore libtool

+     */

+    public final CommandLineCompiler getLibtoolCompiler() {

+        if (libtoolCompiler != null) {

+            return libtoolCompiler;

+        }

+        return this;

+    }

+    abstract public int getMaximumCommandLength();

+    protected int getMaximumInputFilesPerCommand() {

+        return Integer.MAX_VALUE;

+    }

+    protected int getTotalArgumentLengthForInputFile(File outputDir,

+            String inputFile) {

+        return inputFile.length() + 1;

+    }

+    abstract protected void getUndefineSwitch(StringBuffer buffer, String define);

+    /**

+     * This method is exposed so test classes can overload and test the

+     * arguments without actually spawning the compiler

+     */

+    protected int runCommand(CCTask task, File workingDir, String[] cmdline)

+            throws BuildException {

+        return CUtil.runCommand(task, workingDir, cmdline, newEnvironment, env);

+    }

+    protected final void setCommand(String command) {

+        this.command = command;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java
new file mode 100644
index 0000000..4c53df1
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineCompilerConfiguration.java
@@ -0,0 +1,216 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CompilerParam;

+import net.sf.antcontrib.cpptasks.DependencyInfo;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * A configuration for a C++ compiler

+ * 

+ * @author Curt Arnold

+ */

+public final class CommandLineCompilerConfiguration

+        implements

+            CompilerConfiguration {

+    private/* final */String[] args;

+    private/* final */CommandLineCompiler compiler;

+    private String[] endArgs;

+    //

+    //    include path from environment variable not

+    //       explicitly stated in Ant script

+    private/* final */File[] envIncludePath;

+    private String[] exceptFiles;

+    private/* final */String identifier;

+    private/* final */File[] includePath;

+    private/* final */String includePathIdentifier;

+    private boolean isPrecompiledHeaderGeneration;

+    private/* final */ProcessorParam[] params;

+    private/* final */boolean rebuild;

+    private/* final */File[] sysIncludePath;

+    public CommandLineCompilerConfiguration(CommandLineCompiler compiler,

+            String identifier, File[] includePath, File[] sysIncludePath,

+            File[] envIncludePath, String includePathIdentifier, String[] args,

+            ProcessorParam[] params, boolean rebuild, String[] endArgs) {

+        if (compiler == null) {

+            throw new NullPointerException("compiler");

+        }

+        if (identifier == null) {

+            throw new NullPointerException("identifier");

+        }

+        if (includePathIdentifier == null) {

+            throw new NullPointerException("includePathIdentifier");

+        }

+        if (args == null) {

+            this.args = new String[0];

+        } else {

+            this.args = (String[]) args.clone();

+        }

+        if (includePath == null) {

+            this.includePath = new File[0];

+        } else {

+            this.includePath = (File[]) includePath.clone();

+        }

+        if (sysIncludePath == null) {

+            this.sysIncludePath = new File[0];

+        } else {

+            this.sysIncludePath = (File[]) sysIncludePath.clone();

+        }

+        if (envIncludePath == null) {

+            this.envIncludePath = new File[0];

+        } else {

+            this.envIncludePath = (File[]) envIncludePath.clone();

+        }

+        this.compiler = compiler;

+        this.params = (ProcessorParam[]) params.clone();

+        this.rebuild = rebuild;

+        this.identifier = identifier;

+        this.includePathIdentifier = includePathIdentifier;

+        this.endArgs = (String[]) endArgs.clone();

+        exceptFiles = null;

+        isPrecompiledHeaderGeneration = false;

+    }

+    public CommandLineCompilerConfiguration(

+            CommandLineCompilerConfiguration base, String[] additionalArgs,

+            String[] exceptFiles, boolean isPrecompileHeaderGeneration) {

+        compiler = base.compiler;

+        identifier = base.identifier;

+        rebuild = base.rebuild;

+        includePath = (File[]) base.includePath.clone();

+        sysIncludePath = (File[]) base.sysIncludePath.clone();

+        endArgs = (String[]) base.endArgs.clone();

+        envIncludePath = (File[]) base.envIncludePath.clone();

+        includePathIdentifier = base.includePathIdentifier;

+        if (exceptFiles != null) {

+            this.exceptFiles = (String[]) exceptFiles.clone();

+        }

+        this.isPrecompiledHeaderGeneration = isPrecompileHeaderGeneration;

+        args = new String[base.args.length + additionalArgs.length];

+        for (int i = 0; i < base.args.length; i++) {

+            args[i] = base.args[i];

+        }

+        int index = base.args.length;

+        for (int i = 0; i < additionalArgs.length; i++) {

+            args[index++] = additionalArgs[i];

+        }

+    }

+    public int bid(String inputFile) {

+        int compilerBid = compiler.bid(inputFile);

+        if (compilerBid > 0 && exceptFiles != null) {

+            for (int i = 0; i < exceptFiles.length; i++) {

+                if (inputFile.equals(exceptFiles[i])) {

+                    return 0;

+                }

+            }

+        }

+        return compilerBid;

+    }

+    public void compile(CCTask task, File outputDir, String[] sourceFiles,

+            boolean relentless, ProgressMonitor monitor) throws BuildException {

+        if (monitor != null) {

+            monitor.start(this);

+        }

+        try {

+            compiler.compile(task, outputDir, sourceFiles, args, endArgs,

+                    relentless, this, monitor);

+            if (monitor != null) {

+                monitor.finish(this, true);

+            }

+        } catch (BuildException ex) {

+            if (monitor != null) {

+                monitor.finish(this, false);

+            }

+            throw ex;

+        }

+    }

+    /**

+     * 

+     * This method may be used to get two distinct compiler configurations, one

+     * for compiling the specified file and producing a precompiled header

+     * file, and a second for compiling other files using the precompiled

+     * header file.

+     * 

+     * The last (preferrably only) include directive in the prototype file will

+     * be used to mark the boundary between pre-compiled and normally compiled

+     * headers.

+     * 

+     * @param prototype

+     *            A source file (for example, stdafx.cpp) that is used to build

+     *            the precompiled header file. @returns null if precompiled

+     *            headers are not supported or a two element array containing

+     *            the precompiled header generation configuration and the

+     *            consuming configuration

+     *  

+     */

+    public CompilerConfiguration[] createPrecompileConfigurations(

+            File prototype, String[] nonPrecompiledFiles) {

+        if (compiler instanceof PrecompilingCompiler) {

+            return ((PrecompilingCompiler) compiler)

+                    .createPrecompileConfigurations(this, prototype,

+                            nonPrecompiledFiles);

+        }

+        return null;

+    }

+    /**

+     * Returns a string representation of this configuration. Should be

+     * canonical so that equivalent configurations will have equivalent string

+     * representations

+     */

+    public String getIdentifier() {

+        return identifier;

+    }

+    public String getIncludePathIdentifier() {

+        return includePathIdentifier;

+    }

+    public String getOutputFileName(String inputFile) {

+        return compiler.getOutputFileName(inputFile);

+    }

+    public CompilerParam getParam(String name) {

+        for (int i = 0; i < params.length; i++) {

+            if (name.equals(params[i].getName()))

+                return (CompilerParam) params[i];

+        }

+        return null;

+    }

+    public ProcessorParam[] getParams() {

+        return params;

+    }

+    public boolean getRebuild() {

+        return rebuild;

+    }

+    public boolean isPrecompileGeneration() {

+        return isPrecompiledHeaderGeneration;

+    }

+    public DependencyInfo parseIncludes(CCTask task, File baseDir, File source) {

+        return compiler.parseIncludes(task, source, includePath,

+                sysIncludePath, envIncludePath, baseDir,

+                getIncludePathIdentifier());

+    }

+    public String toString() {

+        return identifier;

+    }

+    public String[] getPreArguments() {

+    	return (String[]) args.clone();

+    }

+    public String[] getEndArguments() {

+    	return (String[]) endArgs.clone();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java
new file mode 100644
index 0000000..d01cb9e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineFortranCompiler.java
@@ -0,0 +1,42 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.parser.FortranParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * An abstract Compiler implementation which uses an external program to

+ * perform the compile.

+ * 

+ * @author Curt Arnold

+ */

+public abstract class CommandLineFortranCompiler extends CommandLineCompiler {

+    protected CommandLineFortranCompiler(String command, String identifierArg,

+            String[] sourceExtensions, String[] headerExtensions,

+            String outputSuffix, boolean libtool,

+            CommandLineFortranCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super(command, identifierArg, sourceExtensions, headerExtensions,

+                outputSuffix, libtool, libtoolCompiler, newEnvironment, env);

+    }

+    protected Parser createParser(File source) {

+        return new FortranParser();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
new file mode 100644
index 0000000..4161469
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
@@ -0,0 +1,404 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+

+import java.io.File;

+import java.io.FileWriter;

+import java.io.IOException;

+import java.util.Enumeration;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.LinkerDef;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.TargetDef;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+

+

+/**

+ * An abstract Linker implementation that performs the link via an external

+ * command.

+ *

+ * @author Adam Murdoch

+ */

+public abstract class CommandLineLinker extends AbstractLinker

+{

+    private String command;

+    private Environment env = null;

+    private String identifier;

+    private String identifierArg;

+    private boolean isLibtool;

+    private String[] librarySets;

+    private CommandLineLinker libtoolLinker;

+    private boolean newEnvironment = false;

+    private String outputSuffix;

+

+

+    /** Creates a comand line linker invocation */

+    public CommandLineLinker(String command,

+        String identifierArg,

+        String[] extensions,

+        String[] ignoredExtensions, String outputSuffix,

+        boolean isLibtool, CommandLineLinker libtoolLinker)

+    {

+        super(extensions, ignoredExtensions);

+        this.command = command;

+        this.identifierArg = identifierArg;

+        this.outputSuffix = outputSuffix;

+        this.isLibtool = isLibtool;

+        this.libtoolLinker = libtoolLinker;

+    }

+    protected abstract void addBase(long base, Vector args);

+

+    protected abstract void addFixed(Boolean fixed, Vector args);

+

+    abstract protected void addImpliedArgs(boolean debug,

+      LinkType linkType, Vector args, Boolean defaultflag);

+    protected abstract void addIncremental(boolean incremental, Vector args);

+

+      //

+      //  Windows processors handle these through file list

+      //

+    protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, Vector preargs,

+        Vector midargs, Vector endargs) {

+        return null;

+    }

+    protected abstract void addMap(boolean map, Vector args);

+    protected abstract void addStack(int stack, Vector args);

+    protected abstract void addEntry(String entry, Vector args);

+    

+    protected LinkerConfiguration createConfiguration(

+      CCTask task,

+      LinkType linkType,

+      ProcessorDef[] baseDefs, LinkerDef specificDef, TargetDef targetPlatform) {

+

+      Vector preargs = new Vector();

+      Vector midargs = new Vector();

+      Vector endargs = new Vector();

+      Vector[] args = new Vector[] { preargs, midargs, endargs };

+

+      LinkerDef[] defaultProviders = new LinkerDef[baseDefs.length+1];

+      defaultProviders[0] = specificDef;

+      for(int i = 0; i < baseDefs.length; i++) {

+        defaultProviders[i+1] = (LinkerDef) baseDefs[i];

+      }

+      //

+      //   add command line arguments inherited from <cc> element

+      //     any "extends" and finally the specific CompilerDef

+      CommandLineArgument[] commandArgs;

+      for(int i = defaultProviders.length-1; i >= 0; i--) {

+        commandArgs = defaultProviders[i].getActiveProcessorArgs();

+        for(int j = 0; j < commandArgs.length; j++) {

+          args[commandArgs[j].getLocation()].

+                addElement(commandArgs[j].getValue());

+        }

+      }

+

+        Vector params = new Vector();

+        //

+        //   add command line arguments inherited from <cc> element

+        //     any "extends" and finally the specific CompilerDef

+        ProcessorParam[] paramArray;

+        for (int i = defaultProviders.length - 1; i >= 0; i--) {

+            paramArray = defaultProviders[i].getActiveProcessorParams();

+            for (int j = 0; j < paramArray.length; j++) {

+                params.add(paramArray[j]);

+            }

+        }

+

+        paramArray = (ProcessorParam[])(params.toArray(new ProcessorParam[params.size()]));

+

+        boolean debug = specificDef.getDebug(baseDefs,0);

+

+      

+      String startupObject = getStartupObject(linkType);

+      Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);

+      addImpliedArgs(debug, linkType, preargs, defaultflag);

+      addIncremental(specificDef.getIncremental(defaultProviders,1), preargs);

+      addFixed(specificDef.getFixed(defaultProviders,1), preargs);

+      addMap(specificDef.getMap(defaultProviders,1), preargs);

+      addBase(specificDef.getBase(defaultProviders,1), preargs);

+      addStack(specificDef.getStack(defaultProviders,1), preargs);

+      addEntry(specificDef.getEntry(defaultProviders, 1), preargs);

+

+      String[] libnames = null;

+      LibrarySet[] libsets = specificDef.getActiveLibrarySets(defaultProviders,1);

+      if (libsets.length > 0) {

+        libnames = addLibrarySets(task, libsets, preargs, midargs, endargs);

+      }

+

+      StringBuffer buf = new StringBuffer(getIdentifier());

+      for (int i = 0; i < 3; i++) {

+        Enumeration argenum = args[i].elements();

+        while (argenum.hasMoreElements()) {

+           buf.append(' ');

+           buf.append(argenum.nextElement().toString());

+        }

+      }

+      String configId = buf.toString();

+

+      String[][] options = new String[][] {

+        new String[args[0].size() + args[1].size()],

+        new String[args[2].size()] };

+      args[0].copyInto(options[0]);

+      int offset = args[0].size();

+      for (int i = 0; i < args[1].size(); i++) {

+        options[0][i+offset] = (String) args[1].elementAt(i);

+      }

+      args[2].copyInto(options[1]);

+

+

+      boolean rebuild = specificDef.getRebuild(baseDefs,0);

+      boolean map = specificDef.getMap(defaultProviders,1);

+

+      //task.log("libnames:"+libnames.length, Project.MSG_VERBOSE);

+      return new CommandLineLinkerConfiguration(this,configId,options,

+              paramArray,

+              rebuild,map,libnames, startupObject);

+    }

+

+    /**

+     * Allows drived linker to decorate linker option.

+     * Override by GccLinker to prepend a "-Wl," to

+     * pass option to through gcc to linker.

+     *

+     * @param buf buffer that may be used and abused in the decoration process,

+     * must not be null.

+     * @param arg linker argument

+     */

+    protected String decorateLinkerOption(StringBuffer buf, String arg) {

+      return arg;

+    }

+

+    protected final String getCommand() {

+      return command;

+    }

+    protected abstract String getCommandFileSwitch(String commandFile);

+

+

+     public String getIdentifier() {

+      if(identifier == null) {

+        if (identifierArg == null) {

+          identifier = getIdentifier(new String[] { command }, command);

+        } else {

+          identifier = getIdentifier(new String[] { command, identifierArg },

+            command);

+        }

+      }

+      return identifier;

+    }

+    public final CommandLineLinker getLibtoolLinker() {

+      if (libtoolLinker != null) {

+        return libtoolLinker;

+      }

+      return this;

+    }

+    protected abstract int getMaximumCommandLength();

+

+    public String getOutputFileName(String baseName) {

+        return baseName + outputSuffix;

+    }

+

+    protected String[] getOutputFileSwitch(CCTask task, String outputFile) {

+        return getOutputFileSwitch(outputFile);

+    }

+    protected abstract String[] getOutputFileSwitch(String outputFile);

+    protected String getStartupObject(LinkType linkType) {

+      return null;

+    }

+

+    /**

+     * Performs a link using a command line linker

+     *

+     */

+    public void link(CCTask task,

+                     File outputFile,

+                     String[] sourceFiles,

+                     CommandLineLinkerConfiguration config)

+                     throws BuildException

+    {

+        File parentDir = new File(outputFile.getParent());

+        String parentPath;

+        try {

+          parentPath = parentDir.getCanonicalPath();

+        } catch(IOException ex) {

+          parentPath = parentDir.getAbsolutePath();

+        }

+        String[] execArgs = prepareArguments(task, parentPath,outputFile.getName(),

+            sourceFiles, config);

+        int commandLength = 0;

+        for(int i = 0; i < execArgs.length; i++) {

+          commandLength += execArgs[i].length() + 1;

+        }

+

+        //

+        //   if command length exceeds maximum

+        //       (1024 for Windows) then create a temporary

+        //       file containing everything but the command name

+        if(commandLength >= this.getMaximumCommandLength()) {

+          try {

+            execArgs = prepareResponseFile(outputFile,execArgs);

+          }

+          catch(IOException ex) {

+            throw new BuildException(ex);

+          }

+        }

+        

+        int retval = runCommand(task,parentDir,execArgs);        

+        //

+        //   if the process returned a failure code then

+        //       throw an BuildException

+        //

+        if(retval != 0) {

+          //

+          //   construct the exception

+          //

+          throw new BuildException(this.getCommand() + " failed with return code " + retval, task.getLocation());

+        }

+        

+    }

+

+

+    /**

+     * Prepares argument list for exec command.  Will return null

+     * if command line would exceed allowable command line buffer.

+     *

+     * @param outputFile linker output file

+     * @param sourceFiles linker input files (.obj, .o, .res)

+     * @param args linker arguments

+     * @return arguments for runTask

+     */

+    protected String[] prepareArguments(

+        CCTask task,

+        String outputDir,

+        String outputFile,

+        String[] sourceFiles,

+        CommandLineLinkerConfiguration config) {

+                        

+        String[] preargs = config.getPreArguments();

+        String[] endargs = config.getEndArguments();

+        String outputSwitch[] =  getOutputFileSwitch(task, outputFile);

+        int allArgsCount = preargs.length + 1 + outputSwitch.length +

+                sourceFiles.length + endargs.length;

+        if (isLibtool) {

+          allArgsCount++;

+        }

+        String[] allArgs = new String[allArgsCount];

+        int index = 0;

+        if (isLibtool) {

+          allArgs[index++] = "libtool";

+        }

+        allArgs[index++] = this.getCommand();

+        StringBuffer buf = new StringBuffer();

+        for (int i = 0; i < preargs.length; i++) {

+          allArgs[index++] = decorateLinkerOption(buf, preargs[i]);

+        }

+        for (int i = 0; i < outputSwitch.length; i++) {

+          allArgs[index++] = outputSwitch[i];

+        }

+        for (int i = 0; i < sourceFiles.length; i++) {

+          allArgs[index++] = prepareFilename(buf,outputDir,sourceFiles[i]);

+        }

+        for (int i = 0; i < endargs.length; i++) {

+          allArgs[index++] = decorateLinkerOption(buf, endargs[i]);

+        }

+        return allArgs;

+    }

+

+    /**

+     * Processes filename into argument form

+     *

+     */

+    protected String prepareFilename(StringBuffer buf,

+      String outputDir, String sourceFile) {

+      String relativePath = CUtil.getRelativePath(outputDir,

+        new File(sourceFile));

+      return quoteFilename(buf,relativePath);

+    }

+

+    /**

+     * Prepares argument list to execute the linker using a

+     * response file.

+     *

+     * @param outputFile linker output file

+     * @param args output of prepareArguments

+     * @return arguments for runTask

+     */

+    protected String[] prepareResponseFile(File outputFile,String[] args) throws IOException

+    {

+        String baseName = outputFile.getName();

+        File commandFile = new File(outputFile.getParent(),baseName + ".rsp");

+        FileWriter writer = new FileWriter(commandFile);

+        int execArgCount = 1;

+        if (isLibtool) {

+          execArgCount++;

+        }

+        String[] execArgs = new String[execArgCount+1];

+        for (int i = 0; i < execArgCount; i++) {

+          execArgs[i] = args[i];

+        }

+        execArgs[execArgCount] = getCommandFileSwitch(commandFile.toString());

+        for(int i = execArgCount; i < args.length; i++) {

+        	//

+        	//   if embedded space and not quoted then

+        	//       quote argument

+          if (args[i].indexOf(" ") >= 0 && args[i].charAt(0) != '\"') {

+          	writer.write('\"');

+          	writer.write(args[i]);

+          	writer.write("\"\n");

+          } else {

+          	writer.write(args[i]);

+            writer.write('\n');

+          }

+        }

+        writer.close();

+        return execArgs;

+    }

+

+

+    protected String quoteFilename(StringBuffer buf,String filename) {

+      if(filename.indexOf(' ') >= 0) {

+        buf.setLength(0);

+        buf.append('\"');

+        buf.append(filename);

+        buf.append('\"');

+        return buf.toString();

+      }

+      return filename;

+    }

+

+    /**

+     * This method is exposed so test classes can overload

+     * and test the arguments without actually spawning the

+     * compiler

+     */

+    protected int runCommand(CCTask task, File workingDir,String[] cmdline)

+      throws BuildException {

+      return CUtil.runCommand(task,workingDir,cmdline, newEnvironment, env);

+    }

+

+    protected final void setCommand(String command) {

+        this.command = command;

+    }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java
new file mode 100644
index 0000000..b3a7290
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CommandLineLinkerConfiguration.java
@@ -0,0 +1,119 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.LinkerParam;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+import net.sf.antcontrib.cpptasks.TargetInfo;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * A configuration for a command line linker

+ * 

+ * @author Curt Arnold

+ */

+public final class CommandLineLinkerConfiguration

+        implements

+            LinkerConfiguration {

+    private/* final */String[][] args;

+    private/* final */String identifier;

+    private String[] libraryNames;

+    private/* final */CommandLineLinker linker;

+    private/* final */boolean map;

+    private/* final */ProcessorParam[] params;

+    private/* final */boolean rebuild;

+    private String startupObject;

+    public CommandLineLinkerConfiguration(CommandLineLinker linker,

+            String identifier, String[][] args, ProcessorParam[] params,

+            boolean rebuild, boolean map, String[] libraryNames,

+            String startupObject) {

+        if (linker == null) {

+            throw new NullPointerException("linker");

+        }

+        if (args == null) {

+            throw new NullPointerException("args");

+        } else {

+            this.args = (String[][]) args.clone();

+        }

+        this.linker = linker;

+        this.params = (ProcessorParam[]) params.clone();

+        this.rebuild = rebuild;

+        this.identifier = identifier;

+        this.map = map;

+        if (libraryNames == null) {

+            this.libraryNames = new String[0];

+        } else {

+            this.libraryNames = (String[]) libraryNames.clone();

+        }

+        this.startupObject = startupObject;

+    }

+    public int bid(String filename) {

+        return linker.bid(filename);

+    }

+    public String[] getEndArguments() {

+        String[] clone = (String[]) args[1].clone();

+        return clone;

+    }

+    /**

+     * Returns a string representation of this configuration. Should be

+     * canonical so that equivalent configurations will have equivalent string

+     * representations

+     */

+    public String getIdentifier() {

+        return identifier;

+    }

+    public String[] getLibraryNames() {

+        String[] clone = (String[]) libraryNames.clone();

+        return clone;

+    }

+    public boolean getMap() {

+        return map;

+    }

+    public String getOutputFileName(String inputFile) {

+        return linker.getOutputFileName(inputFile);

+    }

+    public LinkerParam getParam(String name) {

+        for (int i = 0; i < params.length; i++) {

+            if (name.equals(params[i].getName()))

+                return (LinkerParam) params[i];

+        }

+        return null;

+    }

+    public ProcessorParam[] getParams() {

+        return params;

+    }

+    public String[] getPreArguments() {

+        String[] clone = (String[]) args[0].clone();

+        return clone;

+    }

+    public boolean getRebuild() {

+        return rebuild;

+    }

+    public String getStartupObject() {

+        return startupObject;

+    }

+    public void link(CCTask task, TargetInfo linkTarget) throws BuildException {

+        //

+        //  AllSourcePath's include any syslibsets

+        //

+        String[] sourcePaths = linkTarget.getAllSourcePaths();

+        linker.link(task, linkTarget.getOutput(), sourcePaths, this);

+    }

+    public String toString() {

+        return identifier;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Compiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Compiler.java
new file mode 100644
index 0000000..bbb6c99
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Compiler.java
@@ -0,0 +1,24 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+/**

+ * A compiler.

+ * 

+ * @author Adam Murdoch

+ */

+public interface Compiler extends Processor {

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java
new file mode 100644
index 0000000..72abb8b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/CompilerConfiguration.java
@@ -0,0 +1,64 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CompilerParam;

+import net.sf.antcontrib.cpptasks.DependencyInfo;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * A configuration for a compiler

+ * 

+ * @author Curt Arnold

+ */

+public interface CompilerConfiguration extends ProcessorConfiguration {

+    void compile(CCTask task, File outputDir, String[] sourceFiles,

+            boolean relentless, ProgressMonitor monitor) throws BuildException;

+    /**

+     * 

+     * This method may be used to get two distinct compiler configurations, one

+     * for compiling the specified file and producing a precompiled header

+     * file, and a second for compiling other files using the precompiled

+     * header file.

+     * 

+     * The last (preferrably only) include directive in the prototype file will

+     * be used to mark the boundary between pre-compiled and normally compiled

+     * headers.

+     * 

+     * @param prototype

+     *            A source file (for example, stdafx.cpp) that is used to build

+     *            the precompiled header file. @returns null if precompiled

+     *            headers are not supported or a two element array containing

+     *            the precompiled header generation configuration and the

+     *            consuming configuration

+     *  

+     */

+    CompilerConfiguration[] createPrecompileConfigurations(File prototype,

+            String[] nonPrecompiledFiles);

+    /**

+     * Returns an digest for the include path for the configuration.

+     * 

+     * This is used to determine if cached dependency information is invalid

+     * because the include paths have changed

+     */

+    String getIncludePathIdentifier();

+    public CompilerParam getParam(String name);

+    boolean isPrecompileGeneration();

+    DependencyInfo parseIncludes(CCTask task, File baseDir, File source);

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/LinkType.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/LinkType.java
new file mode 100644
index 0000000..7d6041f
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/LinkType.java
@@ -0,0 +1,134 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import net.sf.antcontrib.cpptasks.OutputTypeEnum;

+import net.sf.antcontrib.cpptasks.SubsystemEnum;

+/**

+ * This class represents the target platform for the compile and link step. The

+ * name is an anachronism and should be changed.

+ * 

+ * @author Curt Arnold

+ */

+public class LinkType {

+    private OutputTypeEnum outputType = new OutputTypeEnum();

+    private boolean staticRuntime = false;

+    private SubsystemEnum subsystem = new SubsystemEnum();

+    /**

+     * Constructor

+     * 

+     * By default, an gui executable with a dynamically linked runtime

+     *  

+     */

+    public LinkType() {

+    }

+    /**

+     * Gets whether the link should produce an executable

+     * 

+     * @return boolean

+     */

+    public boolean isExecutable() {

+        String value = outputType.getValue();

+        return value.equals("executable");

+    }

+    /**

+     * Gets whether the link should produce a plugin module.

+     * 

+     * @return boolean

+     */

+    public boolean isPluginModule() {

+        String value = outputType.getValue();

+        return value.equals("plugin");

+    }

+    /**

+     * Gets whether the link should produce a shared library.

+     * 

+     * @return boolean

+     */

+    public boolean isSharedLibrary() {

+        String value = outputType.getValue();

+        return value.equals("shared") || value.equals("plugin");

+    }

+    /**

+     * Gets whether the link should produce a static library.

+     * 

+     * @return boolean

+     */

+    public boolean isStaticLibrary() {

+        String value = outputType.getValue();

+        return value.equals("static");

+    }

+    /**

+     * Gets whether the module should use a statically linked runtime library.

+     * 

+     * @return boolean

+     */

+    public boolean isStaticRuntime() {

+        return staticRuntime;

+    }

+    /**

+     * Gets whether the link should produce a module for a console subsystem.

+     * 

+     * @return boolean

+     */

+    public boolean isSubsystemConsole() {

+        String value = subsystem.getValue();

+        return value.equals("console");

+    }

+    /**

+     * Gets whether the link should produce a module for a graphical user

+     * interface subsystem.

+     * 

+     * @return boolean

+     */

+    public boolean isSubsystemGUI() {

+        String value = subsystem.getValue();

+        return value.equals("gui");

+    }

+    /**

+     * Sets the output type (execuable, shared, etc).

+     * 

+     * @param outputType,

+     *            may not be null

+     */

+    public void setOutputType(OutputTypeEnum outputType) {

+        if (outputType == null) {

+            throw new IllegalArgumentException("outputType");

+        }

+        this.outputType = outputType;

+    }

+    /**

+     * Requests use of a static runtime library.

+     * 

+     * @param staticRuntime

+     *            if true, use static runtime library if possible.

+     */

+    public void setStaticRuntime(boolean staticRuntime) {

+        this.staticRuntime = staticRuntime;

+    }

+    /**

+     * Sets the subsystem (gui, console, etc).

+     * 

+     * @param subsystem

+     *            subsystem, may not be null

+     */

+    public void setSubsystem(SubsystemEnum subsystem) {

+        if (subsystem == null) {

+            throw new IllegalArgumentException("subsystem");

+        }

+        this.subsystem = subsystem;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Linker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Linker.java
new file mode 100644
index 0000000..776a808
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Linker.java
@@ -0,0 +1,57 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+/**

+ * A linker for executables, and static and dynamic libraries.

+ * 

+ * @author Adam Murdoch

+ */

+public interface Linker extends Processor {

+    /**

+     * Extracts the significant part of a library name to ensure there aren't

+     * collisions

+     */

+    String getLibraryKey(File libname);

+    /**

+     * returns the library path for the linker

+     */

+    File[] getLibraryPath();

+    /**

+     * Returns a set of filename patterns corresponding to library names.

+     * 

+     * For example, "advapi32" would be expanded to "advapi32.dll" by

+     * DevStudioLinker and to "libadvapi32.a" and "libadvapi32.so" by

+     * GccLinker.

+     * 

+     * @param libnames

+     *            array of library names

+     */

+    String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libraryType);

+    /**

+     * Gets the linker for the specified link type.

+     * 

+     * @return appropriate linker or null, will return this if this linker can

+     *         handle the specified link type

+     */

+    Linker getLinker(LinkType linkType);

+    /**

+     * Returns true if the linker is case-sensitive

+     */

+    boolean isCaseSensitive();

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java
new file mode 100644
index 0000000..c2d62c4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/LinkerConfiguration.java
@@ -0,0 +1,31 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.LinkerParam;

+import net.sf.antcontrib.cpptasks.TargetInfo;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * A configuration for a linker

+ * 

+ * @author Curt Arnold

+ */

+public interface LinkerConfiguration extends ProcessorConfiguration {

+    public LinkerParam getParam(String name);

+    void link(CCTask task, TargetInfo linkTarget) throws BuildException;

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java
new file mode 100644
index 0000000..eb64119
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCCompiler.java
@@ -0,0 +1,43 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * A command line C compiler that can utilize precompilation of header files

+ * 

+ * @author Curt Arnold

+ */

+public abstract class PrecompilingCommandLineCCompiler

+        extends

+            PrecompilingCommandLineCompiler {

+    protected PrecompilingCommandLineCCompiler(String command,

+            String identifierArg, String[] sourceExtensions,

+            String[] headerExtensions, String outputSuffix, boolean libtool,

+            PrecompilingCommandLineCCompiler libtoolCompiler,

+            boolean newEnvironment, Environment env) {

+        super(command, identifierArg, sourceExtensions, headerExtensions,

+                outputSuffix, libtool, libtoolCompiler, newEnvironment, env);

+    }

+    protected Parser createParser(File source) {

+        return new CParser();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java
new file mode 100644
index 0000000..6e3c145
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCommandLineCompiler.java
@@ -0,0 +1,104 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.Reader;

+

+import net.sf.antcontrib.cpptasks.parser.Parser;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+/**

+ * A command line C compiler that can utilize precompilation of header files

+ * 

+ * @author Curt Arnold

+ */

+public abstract class PrecompilingCommandLineCompiler

+        extends

+            CommandLineCompiler implements PrecompilingCompiler {

+    protected PrecompilingCommandLineCompiler(String command,

+            String identifierArg, String[] sourceExtensions,

+            String[] headerExtensions, String outputSuffix, boolean libtool,

+            PrecompilingCommandLineCompiler libtoolCompiler,

+            boolean newEnvironment, Environment env) {

+        super(command, identifierArg, sourceExtensions, headerExtensions,

+                outputSuffix, libtool, libtoolCompiler, newEnvironment, env);

+    }

+    /**

+     * 

+     * This method may be used to get two distinct compiler configurations, one

+     * for compiling the specified file and producing a precompiled header

+     * file, and a second for compiling other files using the precompiled

+     * header file.

+     * 

+     * The last (preferrably only) include directive in the prototype file will

+     * be used to mark the boundary between pre-compiled and normally compiled

+     * headers.

+     * 

+     * @param config

+     *            base configuration

+     * @param prototype

+     *            A source file (for example, stdafx.cpp) that is used to build

+     *            the precompiled header file. @returns null if precompiled

+     *            headers are not supported or a two element array containing

+     *            the precompiled header generation configuration and the

+     *            consuming configuration

+     *  

+     */

+    public CompilerConfiguration[] createPrecompileConfigurations(

+            CompilerConfiguration config, File prototype, String[] exceptFiles) {

+        //

+        //   cast should success or someone is passing us a configuration

+        //      that was prepared by another processor

+        //

+        CommandLineCompilerConfiguration cmdLineConfig = (CommandLineCompilerConfiguration) config;

+        //

+        //   parse prototype file to determine last header

+        //

+        Parser parser = createParser(prototype);

+        String[] includes;

+        try {

+            Reader reader = new BufferedReader(new FileReader(prototype));

+            parser.parse(reader);

+            includes = parser.getIncludes();

+        } catch (IOException ex) {

+            throw new BuildException(

+                    "Error parsing precompiled header protoype: "

+                            + prototype.toString() + ":" + ex.toString());

+        }

+        if (includes.length == 0) {

+            throw new BuildException("Precompiled header prototype: "

+                    + prototype.toString()

+                    + " does not contain any include directives.");

+        }

+        CompilerConfiguration[] configs = new CompilerConfiguration[2];

+        configs[0] = createPrecompileGeneratingConfig(cmdLineConfig, prototype,

+                includes[0]);

+        configs[1] = createPrecompileUsingConfig(cmdLineConfig, prototype,

+                includes[0], exceptFiles);

+        return configs;

+    }

+    abstract protected CompilerConfiguration createPrecompileGeneratingConfig(

+            CommandLineCompilerConfiguration baseConfig, File prototype,

+            String lastInclude);

+    abstract protected CompilerConfiguration createPrecompileUsingConfig(

+            CommandLineCompilerConfiguration baseConfig, File prototype,

+            String lastInclude, String[] exceptFiles);

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java
new file mode 100644
index 0000000..e60b1da
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/PrecompilingCompiler.java
@@ -0,0 +1,49 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import java.io.File;

+/**

+ * A compiler that can utilize precompilation of header files

+ * 

+ * @author Curt Arnold

+ */

+public interface PrecompilingCompiler {

+    /**

+     * 

+     * This method may be used to get two distinct compiler configurations, one

+     * for compiling the specified file and producing a precompiled header

+     * file, and a second for compiling other files using the precompiled

+     * header file.

+     * 

+     * The last (preferrably only) include directive in the prototype file will

+     * be used to mark the boundary between pre-compiled and normally compiled

+     * headers.

+     * 

+     * @param config

+     *            base configuration

+     * @param prototype

+     *            A source file (for example, stdafx.cpp) that is used to build

+     *            the precompiled header file. @returns null if precompiled

+     *            headers are not supported or a two element array containing

+     *            the precompiled header generation configuration and the

+     *            consuming configuration

+     *  

+     */

+    CompilerConfiguration[] createPrecompileConfigurations(

+            CompilerConfiguration config, File prototype,

+            String[] nonPrecompiledFiles);

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Processor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Processor.java
new file mode 100644
index 0000000..6fb74e9
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/Processor.java
@@ -0,0 +1,73 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.TargetDef;

+import org.apache.tools.ant.types.Environment;

+/**

+ * A processor. Base interface for Compiler and Linker

+ * 

+ * @author Curt Arnold

+ */

+public interface Processor {

+    /**

+     * Returns a bid indicating the desire of this compiler to process the

+     * file.

+     * 

+     * @param inputFile

+     *            input file

+     * @return 0 = no interest, 100 = high interest

+     */

+    int bid(String inputFile);

+    Processor changeEnvironment(boolean newEnvironment, Environment env);

+    /**

+     * Returns the compiler configuration for <cc>or <compiler>element.

+     * 

+     * @param defaultProviders

+     *            When specificConfig corresponds to a <compiler>or linker

+     *            element, defaultProvider will be a zero to two element array.

+     *            If there is an extends attribute, the first element will be

+     *            the referenced ProcessorDef, unless inherit = false, the last

+     *            element will be the containing <cc>element

+     * @param specificConfig

+     *            A <cc>or <compiler>element.

+     * @return resulting configuration

+     */

+    ProcessorConfiguration createConfiguration(CCTask task, LinkType linkType,

+            ProcessorDef[] defaultProviders, ProcessorDef specificConfig,

+			TargetDef targetPlatform);

+    /**

+     * Retrieve an identifier that identifies the specific version of the

+     * compiler. Compilers with the same identifier should produce the same

+     * output files for the same input files and command line switches.

+     */

+    String getIdentifier();

+    /**

+     * Gets the linker that is associated with this processors

+     */

+    Linker getLinker(LinkType type);

+    /**

+     * Output file name (no path components) corresponding to source file

+     * 

+     * @param inputFile

+     *            input file

+     * @return output file name or null if no output file or name not

+     *         determined by input file

+     */

+    String getOutputFileName(String inputFile);

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java
new file mode 100644
index 0000000..dd75483
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/ProcessorConfiguration.java
@@ -0,0 +1,52 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+import net.sf.antcontrib.cpptasks.ProcessorParam;

+/**

+ * A configuration for a C++ compiler, linker or other processor

+ * 

+ * @author Curt Arnold

+ */

+public interface ProcessorConfiguration {

+    /**

+     * An indication of how much this compiler would like to process this file

+     * 

+     * @return 0 is no interest to process, 100 is strong interest to process

+     */

+    int bid(String filename);

+    /**

+     * Returns a string representation of this configuration. Should be

+     * canonical so that equivalent configurations will have equivalent string

+     * representations

+     */

+    String getIdentifier();

+    /**

+     * Output file name (no path components) corresponding to source file

+     * 

+     * @param inputFile

+     *            input file

+     * @return output file name or null if no output file or name not

+     *         determined by input file

+     */

+    String getOutputFileName(String inputFile);

+    ProcessorParam[] getParams();

+    /**

+     * If true, all files using this configuration should be rebuilt and any

+     * existing output files should be ignored

+     */

+    boolean getRebuild();

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java
new file mode 100644
index 0000000..2206ed8
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/compiler/ProgressMonitor.java
@@ -0,0 +1,31 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.compiler;

+/**

+ * Interface to receive notification of compile progress

+ * 

+ * @author Curt Arnold

+ */

+public interface ProgressMonitor {

+    public void finish(ProcessorConfiguration config, boolean normal);

+    /**

+     * Called to notify monitor of progress

+     *  

+     */

+    void progress(String[] sources);

+    public void start(ProcessorConfiguration config);

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioAslcompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioAslcompiler.java
new file mode 100644
index 0000000..f0be594
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioAslcompiler.java
@@ -0,0 +1,70 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineAslcompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+

+/**

+ * Adaptor for Microsoft ASL compiler.

+ * 

+ */

+public final class DevStudioAslcompiler extends CommandLineAslcompiler {

+    private final static String[] sourceExtensions = new String[] { ".asl" };

+

+    private final static String[] headerExtensions = new String[] {};

+

+    private final static String[] defaultflags = new String[] {};

+

+    private static final DevStudioAslcompiler instance = new DevStudioAslcompiler(

+                    "asl", sourceExtensions, headerExtensions, false);

+

+    /**

+     * Gets asl adapter

+     */

+    public static DevStudioAslcompiler getInstance() {

+        return instance;

+    }

+

+    /**

+     * Private constructor. Use DevStudioAslcompiler.getInstance() to get

+     * singleton instance of this class.

+     */

+    private DevStudioAslcompiler (String command, String[] sourceExtensions,

+                    String[] headerExtensions, boolean isLibtool) {

+        super(command, null, sourceExtensions, headerExtensions, ".aml");

+    }

+

+    public void addImpliedArgs(Vector args, boolean debug, Boolean defaultflag) {

+        if (defaultflag != null && defaultflag.booleanValue()) {

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+    }

+

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+

+    public Linker getLinker(LinkType linkType) {

+        return DevStudioLinker.getInstance().getLinker(linkType);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioAssembler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioAssembler.java
new file mode 100644
index 0000000..23d319e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioAssembler.java
@@ -0,0 +1,84 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineAssembler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+

+/**

+ * Adaptor for Microsoft MASM

+ * 

+ */

+public final class DevStudioAssembler extends CommandLineAssembler {

+    private final static String[] sourceExtensions = new String[] { ".asm" };

+

+    private final static String[] headerExtensions = new String[] { ".h",

+                    ".inc" };

+

+    private final static String[] defaultflags = new String[] { "/nologo", "/c" };

+

+    private static final DevStudioAssembler instance = new DevStudioAssembler(

+                    "ml", sourceExtensions, headerExtensions, false);

+

+    /**

+     * Gets masm adapter

+     */

+    public static DevStudioAssembler getInstance() {

+        return instance;

+    }

+

+    /**

+     * Private constructor. Use DevStudioAssembler.getInstance() to get

+     * singleton instance of this class.

+     */

+    private DevStudioAssembler (String command, String[] sourceExtensions,

+                    String[] headerExtensions, boolean isLibtool) {

+        super(command, null, sourceExtensions, headerExtensions, ".obj");

+    }

+

+    public void addImpliedArgs(Vector args, boolean debug, Boolean defaultflag) {

+        if (defaultflag != null && defaultflag.booleanValue()) {

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+        if (debug) {

+            args.addElement("Zi");

+        }

+    }

+

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+

+    public Linker getLinker(LinkType linkType) {

+        return DevStudioLinker.getInstance().getLinker(linkType);

+    }

+

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ";");

+    }

+

+    protected String getIncludeDirSwitch(String includeDir) {

+        return "/I" + includeDir.replace('/', '\\');

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java
new file mode 100644
index 0000000..3bb5181
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCCompiler.java
@@ -0,0 +1,50 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Microsoft(r) C/C++ Optimizing Compiler

+ * 

+ * @author Adam Murdoch

+ */

+public final class DevStudioCCompiler extends DevStudioCompatibleCCompiler {

+    private static final DevStudioCCompiler instance = new DevStudioCCompiler(

+            "cl", false, null);

+    public static DevStudioCCompiler getInstance() {

+        return instance;

+    }

+    private DevStudioCCompiler(String command, boolean newEnvironment,

+            Environment env) {

+        super(command, "/bogus", newEnvironment, env);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new DevStudioCCompiler(getCommand(), newEnvironment, env);

+        }

+        return this;

+    }

+    public Linker getLinker(LinkType type) {

+        return DevStudioLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 4096;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java
new file mode 100644
index 0000000..5e29a32
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleCCompiler.java
@@ -0,0 +1,136 @@
+/*

+ *

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import java.io.File;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.PrecompilingCommandLineCCompiler;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+/**

+ * An abstract base class for compilers that are basically command line

+ * compatible with Microsoft(r) C/C++ Optimizing Compiler

+ *

+ * @author Curt Arnold

+ */

+public abstract class DevStudioCompatibleCCompiler

+        extends

+            PrecompilingCommandLineCCompiler {

+    private static String[] mflags = new String[]{

+    //

+            //   first four are single-threaded

+            //      (runtime=static,debug=false), (..,debug=true),

+            //      (runtime=dynamic,debug=true), (..,debug=false), (not supported)

+            //    next four are multi-threaded, same sequence

+            "/ML", "/MLd", null, null, "/MT", "/MTd", "/MD", "/MDd"};

+    private static String[] defaultflags = new String[]{"/nologo", "/c"};

+    protected DevStudioCompatibleCCompiler(String command,

+            String identifierArg, boolean newEnvironment, Environment env) {

+        super(command, identifierArg, new String[]{".c", ".cc", ".cpp", ".cxx",

+                ".c++"}, new String[]{".h", ".hpp", ".inl"}, ".obj", false,

+                null, newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args,

+                    final boolean debug,

+            final boolean multithreaded,

+                        final boolean exceptions,

+                        final LinkType linkType,

+                        final Boolean rtti,

+                        final OptimizationEnum optimization,

+                        final Boolean defaultflag) {

+        if (defaultflag != null && defaultflag.booleanValue()) {

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+        if (exceptions) {

+            args.addElement("/GX");

+        }

+        int mindex = 0;

+        if (multithreaded) {

+            mindex += 4;

+        }

+        boolean staticRuntime = linkType.isStaticRuntime();

+        if (!staticRuntime) {

+            mindex += 2;

+        }

+        if (debug) {

+            mindex += 1;

+            args.addElement("/Zi");

+            args.addElement("/Od");

+            args.addElement("/GZ");

+            args.addElement("/D_DEBUG");

+        } else {

+                if (optimization != null) {

+                   if (optimization.isSize()) {

+                     args.addElement("/O1");

+                   }

+                   if (optimization.isSpeed()) {

+                     args.addElement("/O2");

+                   }

+                }

+            args.addElement("/DNDEBUG");

+        }

+        String mflag = mflags[mindex];

+        if (mflag == null) {

+            throw new BuildException(

+                    "multithread='false' and runtime='dynamic' not supported");

+        }

+        args.addElement(mflag);

+        if (rtti != null && rtti.booleanValue()) {

+                args.addElement("/GR");

+        }

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+        DevStudioProcessor.addWarningSwitch(args, level);

+    }

+    protected CompilerConfiguration createPrecompileGeneratingConfig(

+            CommandLineCompilerConfiguration baseConfig, File prototype,

+            String lastInclude) {

+        String[] additionalArgs = new String[]{

+                "/Fp" + CUtil.getBasename(prototype) + ".pch", "/Yc"};

+        return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,

+                null, true);

+    }

+    protected CompilerConfiguration createPrecompileUsingConfig(

+            CommandLineCompilerConfiguration baseConfig, File prototype,

+            String lastInclude, String[] exceptFiles) {

+        String[] additionalArgs = new String[]{

+                "/Fp" + CUtil.getBasename(prototype) + ".pch",

+                "/Yu" + lastInclude};

+        return new CommandLineCompilerConfiguration(baseConfig, additionalArgs,

+                exceptFiles, false);

+    }

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        DevStudioProcessor.getDefineSwitch(buffer, define, value);

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ";");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return DevStudioProcessor.getIncludeDirSwitch(includeDir);

+    }

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        DevStudioProcessor.getUndefineSwitch(buffer, define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java
new file mode 100644
index 0000000..40bef6e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLibrarian.java
@@ -0,0 +1,86 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+/**

+ * Abstract base adapter for librarians with command line options compatible

+ * with the Microsoft(r) Library Manager

+ * 

+ * @author Curt Arnold

+ */

+public abstract class DevStudioCompatibleLibrarian extends CommandLineLinker {

+    private static String[] defaultflags = new String[]{"/nologo"};

+    public DevStudioCompatibleLibrarian(String command, String identifierArg) {

+        super(command, identifierArg, new String[]{".obj"}, new String[0],

+                ".lib", false, null);

+    }

+    protected void addBase(long base, Vector args) {

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, 

+        Vector args, Boolean defaultflag) {

+        if(defaultflag != null && defaultflag.booleanValue()){

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    protected void addMap(boolean map, Vector args) {

+    }

+    protected void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    protected String getCommandFileSwitch(String cmdFile) {

+        return "@" + cmdFile;

+    }

+    public File[] getLibraryPath() {

+        return new File[0];

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return new String[0];

+    }

+    public int getMaximumCommandLength() {

+        return 4096;

+    }

+    public String[] getOutputFileSwitch(String outFile) {

+        StringBuffer buf = new StringBuffer("/OUT:");

+        if (outFile.indexOf(' ') >= 0) {

+            buf.append('"');

+            buf.append(outFile);

+            buf.append('"');

+        } else {

+            buf.append(outFile);

+        }

+        return new String[]{buf.toString()};

+    }

+    public boolean isCaseSensitive() {

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java
new file mode 100644
index 0000000..9e156b0
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioCompatibleLinker.java
@@ -0,0 +1,127 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+/**

+ * Abstract base class for linkers that try to mimic the command line arguments

+ * for the Microsoft (r) Incremental Linker

+ * 

+ * @author Curt Arnold

+ */

+public abstract class DevStudioCompatibleLinker extends CommandLineLinker {

+    private static String[] defaultflags = new String[]{"/NOLOGO"};

+    public DevStudioCompatibleLinker(String command, String identifierArg,

+            String outputSuffix) {

+        super(command, identifierArg, new String[]{".obj", ".lib", ".res"},

+                new String[]{".map", ".pdb", ".lnk", ".dll"}, outputSuffix,

+                false, null);

+    }

+    protected void addBase(long base, Vector args) {

+        if (base >= 0) {

+            String baseAddr = Long.toHexString(base);

+            args.addElement("/BASE:0x" + baseAddr);

+        }

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+        if (fixed != null) {

+            if (fixed.booleanValue()) {

+                args.addElement("/FIXED");

+            } else {

+                args.addElement("/FIXED:NO");

+            }

+        }

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType,

+        Vector args, Boolean defaultflag) {

+        if(defaultflag != null && defaultflag.booleanValue()){

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+        if (debug) {

+            args.addElement("/DEBUG");

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("/DLL");

+        }

+        /*

+         * if(linkType.isSubsystemGUI()) {

+         * args.addElement("/SUBSYSTEM:WINDOWS"); } else {

+         * if(linkType.isSubsystemConsole()) {

+         * args.addElement("/SUBSYSTEM:CONSOLE"); } }

+         */

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+        if (incremental) {

+            args.addElement("/INCREMENTAL:YES");

+        } else {

+            args.addElement("/INCREMENTAL:NO");

+        }

+    }

+    protected void addMap(boolean map, Vector args) {

+        if (map) {

+            args.addElement("/MAP");

+        }

+    }

+    protected void addStack(int stack, Vector args) {

+        if (stack >= 0) {

+            String stackStr = Integer.toHexString(stack);

+            args.addElement("/STACK:0x" + stackStr);

+        }

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    	if (entry != null) {

+    		args.addElement("/ENTRY:" + entry);

+    	}

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    public File[] getLibraryPath() {

+        return CUtil.getPathFromEnvironment("LIB", ";");

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        String[] patterns = new String[libnames.length];

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(libnames[i]);

+            buf.append(".lib");

+            patterns[i] = buf.toString();

+        }

+        return patterns;

+    }

+    public int getMaximumCommandLength() {

+        return 4096;

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"/OUT:" + outputFile};

+    }

+    public boolean isCaseSensitive() {

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java
new file mode 100644
index 0000000..06eac71
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioLibrarian.java
@@ -0,0 +1,36 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+/**

+ * Adapter for the Microsoft (r) Library Manager

+ * 

+ * @author Curt Arnold

+ */

+public final class DevStudioLibrarian extends DevStudioCompatibleLibrarian {

+    private static final DevStudioLibrarian instance = new DevStudioLibrarian();

+    public static DevStudioLibrarian getInstance() {

+        return instance;

+    }

+    private DevStudioLibrarian() {

+        super("lib", "/bogus");

+    }

+    public Linker getLinker(LinkType type) {

+        return DevStudioLinker.getInstance().getLinker(type);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java
new file mode 100644
index 0000000..7ae0178
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioLinker.java
@@ -0,0 +1,44 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+/**

+ * Adapter for the Microsoft (r) Incremental Linker

+ * 

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public final class DevStudioLinker extends DevStudioCompatibleLinker {

+    private static final DevStudioLinker dllLinker = new DevStudioLinker(".dll");

+    private static final DevStudioLinker instance = new DevStudioLinker(".exe");

+    public static DevStudioLinker getInstance() {

+        return instance;

+    }

+    private DevStudioLinker(String outputSuffix) {

+        super("link", "/DLL", outputSuffix);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        if (type.isStaticLibrary()) {

+            return DevStudioLibrarian.getInstance();

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java
new file mode 100644
index 0000000..7df898b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioMIDLCompiler.java
@@ -0,0 +1,113 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import java.io.File;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+/**

+ * Adapter for the Microsoft (r) MIDL Compiler

+ * 

+ * @author Curt Arnold

+ */

+public final class DevStudioMIDLCompiler extends CommandLineCompiler {

+    private static final DevStudioMIDLCompiler instance = new DevStudioMIDLCompiler(

+            false, null);

+    public static DevStudioMIDLCompiler getInstance() {

+        return instance;

+    }

+    private DevStudioMIDLCompiler(boolean newEnvironment, Environment env) {

+        super("midl", null, new String[]{".idl", ".odl"}, new String[]{},

+                ".tlb", false, null, newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+        DevStudioProcessor.addWarningSwitch(args, level);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new DevStudioMIDLCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    /**

+     * The include parser for C will work just fine, but we didn't want to

+     * inherit from CommandLineCCompiler

+     */

+    protected Parser createParser(File source) {

+        return new CParser();

+    }

+    protected int getArgumentCountPerInputFile() {

+        return 3;

+    }

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        DevStudioProcessor.getDefineSwitch(buffer, define, value);

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ";");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return DevStudioProcessor.getIncludeDirSwitch(includeDir);

+    }

+    protected String getInputFileArgument(File outputDir, String filename,

+            int index) {

+        switch (index) {

+            case 0 :

+                return "/tlb";

+            case 1 :

+                return new File(outputDir, getOutputFileName(filename))

+                        .getAbsolutePath();

+        }

+        return filename;

+    }

+    public Linker getLinker(LinkType type) {

+        return DevStudioLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    protected int getMaximumInputFilesPerCommand() {

+        return 1;

+    }

+    protected int getTotalArgumentLengthForInputFile(File outputDir,

+            String inputFile) {

+        String arg1 = getInputFileArgument(outputDir, inputFile, 0);

+        String arg2 = getInputFileArgument(outputDir, inputFile, 1);

+        String arg3 = getInputFileArgument(outputDir, inputFile, 2);

+        return arg1.length() + arg2.length() + arg3.length() + 3;

+    }

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        DevStudioProcessor.getUndefineSwitch(buffer, define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java
new file mode 100644
index 0000000..6b2af7e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioProcessor.java
@@ -0,0 +1,90 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import java.util.Vector;

+/**

+ * A add-in class for Microsoft Developer Studio processors

+ * 

+ *  

+ */

+public class DevStudioProcessor {

+    public static void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("/W0");

+                break;

+            case 1 :

+                args.addElement("/W1");

+                break;

+            case 2 :

+                break;

+            case 3 :

+                args.addElement("/W3");

+                break;

+            case 4 :

+                args.addElement("/W4");

+                break;

+            case 5 :

+                args.addElement("/WX");

+                break;

+        }

+    }

+    public static String getCommandFileSwitch(String cmdFile) {

+        StringBuffer buf = new StringBuffer("@");

+        if (cmdFile.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(cmdFile.replace('/', '\\'));

+            buf.append('\"');

+        } else {

+            buf.append(cmdFile);

+        }

+        return buf.toString();

+    }

+    public static void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        buffer.append("/D");

+        buffer.append(define);

+        if (value != null && value.length() > 0) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    public static String getIncludeDirSwitch(String includeDir) {

+        return "/I" + includeDir.replace('/', '\\');

+    }

+    public static String[] getOutputFileSwitch(String outPath) {

+        StringBuffer buf = new StringBuffer("/Fo");

+        if (outPath.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(outPath);

+            buf.append('\"');

+        } else {

+            buf.append(outPath);

+        }

+        String[] retval = new String[]{buf.toString()};

+        return retval;

+    }

+    public static void getUndefineSwitch(StringBuffer buffer, String define) {

+        buffer.append("/U");

+        buffer.append(define);

+    }

+    public static boolean isCaseSensitive() {

+        return false;

+    }

+    private DevStudioProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java
new file mode 100644
index 0000000..d6e2fd4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/devstudio/DevStudioResourceCompiler.java
@@ -0,0 +1,117 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.devstudio;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Microsoft (r) Windows 32 Resource Compiler

+ * 

+ * @author Curt Arnold

+ */

+public final class DevStudioResourceCompiler extends CommandLineCompiler {

+    private static final DevStudioResourceCompiler instance = new DevStudioResourceCompiler(

+            false, null);

+    public static DevStudioResourceCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private DevStudioResourceCompiler(boolean newEnvironment, Environment env) {

+        super("rc", null, new String[]{".rc"}, new String[]{".h", ".hpp",

+                ".inl"}, ".res", false, null, newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        if (debug) {

+            args.addElement("/D_DEBUG");

+        } else {

+            args.addElement("/DNDEBUG");

+        }

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new DevStudioResourceCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    /**

+     * The include parser for C will work just fine, but we didn't want to

+     * inherit from CommandLineCCompiler

+     */

+    protected Parser createParser(File source) {

+        return new CParser();

+    }

+    protected int getArgumentCountPerInputFile() {

+        return 2;

+    }

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        DevStudioProcessor.getDefineSwitch(buffer, define, value);

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ";");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return DevStudioProcessor.getIncludeDirSwitch(includeDir);

+    }

+    protected String getInputFileArgument(File outputDir, String filename,

+            int index) {

+        if (index == 0) {

+            String outputFileName = getOutputFileName(filename);

+            String fullOutputName = new File(outputDir, outputFileName)

+                    .toString();

+            return "/fo" + fullOutputName;

+        }

+        return filename;

+    }

+    public Linker getLinker(LinkType type) {

+        return DevStudioLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    protected int getMaximumInputFilesPerCommand() {

+        return 1;

+    }

+    protected int getTotalArgumentLengthForInputFile(File outputDir,

+            String inputFile) {

+        String arg1 = getInputFileArgument(outputDir, inputFile, 0);

+        String arg2 = getInputFileArgument(outputDir, inputFile, 1);

+        return arg1.length() + arg2.length() + 2;

+    }

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        DevStudioProcessor.getUndefineSwitch(buffer, define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java
new file mode 100644
index 0000000..f7bb2ea
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/AbstractArLibrarian.java
@@ -0,0 +1,106 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the "ar" tool

+ * 

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public abstract class AbstractArLibrarian extends CommandLineLinker {

+    private/* final */

+    String outputPrefix;

+    private static String[] defaultflags = new String[]{};

+    protected AbstractArLibrarian(String command, String identificationArg,

+            String[] inputExtensions, String[] ignoredExtensions,

+            String outputPrefix, String outputExtension, boolean isLibtool,

+            AbstractArLibrarian libtoolLibrarian) {

+        super(command, identificationArg, inputExtensions, ignoredExtensions,

+                outputExtension, isLibtool, libtoolLibrarian);

+        this.outputPrefix = outputPrefix;

+    }

+    public void addBase(long base, Vector args) {

+    }

+    public void addFixed(Boolean fixed, Vector args) {

+    }

+    public void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if(defaultflag != null && defaultflag.booleanValue()){

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+    }

+    public void addIncremental(boolean incremental, Vector args) {

+    }

+    public void addMap(boolean map, Vector args) {

+    }

+    public void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        return null;

+    }

+    public File[] getLibraryPath() {

+        return new File[0];

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+    	return new String[0];

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    public String getOutputFileName(String baseName) {

+        return outputPrefix + super.getOutputFileName(baseName);

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        return GccProcessor.getOutputFileSwitch("rvs", outputFile);

+    }

+    public boolean isCaseSensitive() {

+        return true;

+    }

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        //

+        //   if there is an existing library then

+        //      we must delete it before executing "ar"

+        if (outputFile.exists()) {

+            if (!outputFile.delete()) {

+                throw new BuildException("Unable to delete "

+                        + outputFile.getAbsolutePath());

+            }

+        }

+        //

+        //   delegate to CommandLineLinker

+        //

+        super.link(task, outputFile, sourceFiles, config);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java
new file mode 100644
index 0000000..f6e3766
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java
@@ -0,0 +1,323 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Abstract adapter for ld-like linkers

+ * 

+ * @author Curt Arnold

+ */

+public abstract class AbstractLdLinker extends CommandLineLinker {

+    private String outputPrefix;

+    private static String[] defaultflags = new String[]{};

+    protected AbstractLdLinker(String command, String identifierArg,

+            String[] extensions, String[] ignoredExtensions,

+            String outputPrefix, String outputSuffix, boolean isLibtool,

+            AbstractLdLinker libtoolLinker) {

+        super(command, identifierArg, extensions, ignoredExtensions,

+                outputSuffix, isLibtool, libtoolLinker);

+        this.outputPrefix = outputPrefix;

+    }

+    public void addBase(long base, Vector args) {

+    	if (base >= 0) {

+    		args.addElement("--image-base");

+    		args.addElement(Long.toHexString(base));

+    	}

+    }

+    public void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if(defaultflag != null && defaultflag.booleanValue()){

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+        if (debug) {

+            args.addElement("-g");

+        }

+        if (isDarwin()) {

+            if (linkType.isPluginModule()) {

+                args.addElement("-bundle");

+            } else {

+                if (linkType.isSharedLibrary()) {

+                    args.addElement("-prebind");

+                    args.addElement("-dynamiclib");

+                }

+            }

+        } else {

+            if (linkType.isStaticRuntime()) {

+                args.addElement("-static");

+            }

+            if (linkType.isPluginModule()) {

+                args.addElement("-shared");

+            } else {

+                if (linkType.isSharedLibrary()) {

+                    args.addElement("-shared");

+                }

+            }

+        }

+    }

+    public void addIncremental(boolean incremental, Vector args) {

+    	if (incremental) {

+    		args.addElement("-i");

+    	}

+    }

+    protected int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        Vector libnames = new Vector();

+        super.addLibrarySets(task, libsets, preargs, midargs, endargs);

+        LibraryTypeEnum previousLibraryType = null;

+        for (int i = 0; i < libsets.length; i++) {

+            LibrarySet set = libsets[i];

+            File libdir = set.getDir(null);

+            String[] libs = set.getLibs();

+            if (libdir != null) {

+            	if (set.getType() != null && 

+            			"framework".equals(set.getType().getValue()) &&

+						isDarwin()) {

+            		endargs.addElement("-F" + libdir.getAbsolutePath());            		

+            	} else {

+            		endargs.addElement("-L" + libdir.getAbsolutePath());

+            	}

+            }

+            //

+            //  if there has been a change of library type

+            //

+            if (set.getType() != previousLibraryType) {

+            	if (set.getType() != null && "static".equals(set.getType().getValue())) {

+            		endargs.addElement("-Bstatic");

+            		previousLibraryType = set.getType();

+            	} else {

+            		if (set.getType() == null || 

+            				!"framework".equals(set.getType().getValue()) ||

+							!isDarwin()) {

+            			endargs.addElement("-Bdynamic");

+            			previousLibraryType = set.getType();

+            		}

+            	}

+            }

+            StringBuffer buf = new StringBuffer("-l");

+            if (set.getType() != null && 

+            		"framework".equals(set.getType().getValue()) && 

+					isDarwin()) {

+            	buf.setLength(0);

+            	buf.append("-framework ");

+            }

+            int initialLength = buf.length();

+            for (int j = 0; j < libs.length; j++) {

+                //

+                //  reset the buffer to just "-l"

+                //

+                buf.setLength(initialLength);

+                //

+                //  add the library name

+                buf.append(libs[j]);

+                libnames.addElement(libs[j]);

+                //

+                //  add the argument to the list

+                endargs.addElement(buf.toString());

+            }

+        }

+        String rc[] = new String[libnames.size()];

+        for (int i = 0; i < libnames.size(); i++) {

+            rc[i] = (String) libnames.elementAt(i);

+        }

+        return rc;

+    }

+    public void addMap(boolean map, Vector args) {

+    	if (map) {

+    		args.addElement("-M");

+    	}

+    }

+    public void addStack(int stack, Vector args) {

+    	if (stack > 0) {

+    		args.addElement("--stack");

+    		args.addElement(Integer.toString(stack));

+    	}

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    	if (entry != null) {

+    		args.addElement("-e");

+    		args.addElement(entry);

+    	}

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        throw new IllegalStateException("ld does not support command files");

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("LIB", ":");

+    }

+    public String getLibraryKey(File libfile) {

+        String libname = libfile.getName();

+        int lastDot = libname.lastIndexOf('.');

+        if (lastDot >= 0) {

+            return libname.substring(0, lastDot);

+        }

+        return libname;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        return new File[0];

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        int patternCount = libnames.length;

+        if (libType == null) {

+        	patternCount *= 2;

+        }

+        String[] patterns = new String[patternCount];

+        int offset = 0;

+        if (libType == null || "static".equals(libType.getValue())) {

+        	offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);

+        }

+        if (libType != null && "framework".equals(libType.getValue()) && isDarwin()) {

+        	for(int i = 0; i < libnames.length; i++) {

+        		buf.setLength(0);

+        		buf.append(libnames[i]);

+        		buf.append(".framework/");

+        		buf.append(libnames[i]);

+        		patterns[offset++] = buf.toString();

+        	}

+        } else {

+        	if (libType == null || !"static".equals(libType.getValue())) {

+        		if (isHPUX()) {

+        			offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,

+        					offset);

+        		} else {

+        			offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,

+        					offset);

+        		}

+        	}

+        }

+        return patterns;

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    public String getOutputFileName(String baseName) {

+        return outputPrefix + super.getOutputFileName(baseName);

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        return GccProcessor.getOutputFileSwitch("-o", outputFile);

+    }

+    public boolean isCaseSensitive() {

+        return true;

+    }

+    protected boolean isHPUX() {

+        String osname = System.getProperty("os.name").toLowerCase();

+        if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {

+            return true;

+        }

+        return false;

+    }

+    /**

+     * Prepares argument list for exec command. Will return null if command

+     * line would exceed allowable command line buffer.

+     * 

+     * @param outputFile

+     *            linker output file

+     * @param sourceFiles

+     *            linker input files (.obj, .o, .res)

+     * @param args

+     *            linker arguments

+     * @return arguments for runTask

+     */

+    public String[] prepareArguments(CCTask task, String outputDir,

+            String outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) {

+        //

+        //   need to suppress sources that correspond to

+        //        library set entries since they are already

+        //        in the argument list

+        String[] libnames = config.getLibraryNames();

+        if (libnames == null || libnames.length == 0) {

+            return super.prepareArguments(task, outputDir, outputFile,

+                    sourceFiles, config);

+        }

+        //

+        //

+        //   null out any sources that correspond to library names

+        //

+        String[] localSources = (String[]) sourceFiles.clone();

+        int extra = 0;

+        for (int i = 0; i < libnames.length; i++) {

+            String libname = libnames[i];

+            for (int j = 0; j < localSources.length; j++) {

+                if (localSources[j] != null

+                        && localSources[j].indexOf(libname) > 0

+                        && localSources[j].indexOf("lib") > 0) {

+                    String filename = new File(localSources[j]).getName();

+                    if (filename.startsWith("lib")

+                            && filename.substring(3).startsWith(libname)) {

+                        String extension = filename

+                                .substring(libname.length() + 3);

+                        if (extension.equals(".a") || extension.equals(".so")

+                                || extension.equals(".sl")) {

+                            localSources[j] = null;

+                            extra++;

+                        }

+                    }

+                }

+            }

+        }

+        if (extra == 0) {

+            return super.prepareArguments(task, outputDir, outputFile,

+                    sourceFiles, config);

+        }

+        String[] finalSources = new String[localSources.length - extra];

+        int index = 0;

+        for (int i = 0; i < localSources.length; i++) {

+            if (localSources[i] != null) {

+                finalSources[index++] = localSources[i];

+            }

+        }

+        return super.prepareArguments(task, outputDir, outputFile,

+                finalSources, config);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccAssembler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccAssembler.java
new file mode 100644
index 0000000..412bffa
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccAssembler.java
@@ -0,0 +1,76 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineAssembler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+

+/**

+ * Adapter for gcc assemble

+ * 

+ */

+public final class GccAssembler extends CommandLineAssembler {

+    private final static String[] sourceExtensions = new String[] { ".asm" };

+

+    private final static String[] headerExtensions = new String[] { ".h",

+                    ".inc" };

+

+    private static final GccAssembler instance = new GccAssembler("gas",

+                    sourceExtensions, headerExtensions, false);

+

+    /**

+     * Gets gcc adapter

+     */

+    public static GccAssembler getInstance() {

+        return instance;

+    }

+

+    /**

+     * Private constructor. Use GccAssembler.getInstance() to get singleton

+     * instance of this class.

+     */

+    private GccAssembler (String command, String[] sourceExtensions,

+                    String[] headerExtensions, boolean isLibtool) {

+        super(command, null, sourceExtensions, headerExtensions,

+                        isLibtool ? ".fo" : ".o");

+    }

+

+    public void addImpliedArgs(Vector args, boolean debug, Boolean defaultflag) {

+

+    }

+

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+

+    public Linker getLinker(LinkType linkType) {

+        return GccLinker.getInstance().getLinker(linkType);

+    }

+

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ":");

+    }

+

+    protected String getIncludeDirSwitch(String includeDir) {

+        return "-I" + includeDir;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java
new file mode 100644
index 0000000..af3b26b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccCCompiler.java
@@ -0,0 +1,243 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.FortranParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+/**

+ * Adapter for the GCC C/C++ compiler

+ * 

+ * @author Adam Murdoch

+ */

+public final class GccCCompiler extends GccCompatibleCCompiler {

+    private final static String[] sourceExtensions = new String[]{".c", /* C */

+            ".cc", /* C++ */

+            ".cpp", /* C++ */

+            ".cxx", /* C++ */

+            ".c++", /* C++ */

+            ".i", /* preprocessed C */

+            ".ii", /* preprocessed C++ */

+            ".f", /* FORTRAN */

+            ".for", /* FORTRAN */

+            ".m", /* Objective-C */

+            ".mm", /* Objected-C++ */

+            ".s" /* Assembly */

+            };

+    private final static String[] headerExtensions = new String[]{".h", ".hpp",

+    ".inl"};

+    private static final GccCCompiler cppInstance = new GccCCompiler("c++",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("c++", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    private static final GccCCompiler g77Instance = new GccCCompiler("g77",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("g77", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    private static final GccCCompiler gppInstance = new GccCCompiler("g++",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("g++", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    private static final GccCCompiler instance = new GccCCompiler("gcc",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("gcc", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    /**

+     * Gets c++ adapter

+     */

+    public static GccCCompiler getCppInstance() {

+        return cppInstance;

+    }

+    /**

+     * Gets g77 adapter

+     */

+    public static GccCCompiler getG77Instance() {

+        return g77Instance;

+    }

+    /**

+     * Gets gpp adapter

+     */

+    public static GccCCompiler getGppInstance() {

+        return gppInstance;

+    }

+    /**

+     * Gets gcc adapter

+     */

+    public static GccCCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private File[] includePath;

+    private boolean isPICMeaningful = true;

+    /**

+     * Private constructor. Use GccCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    private GccCCompiler(String command, String[] sourceExtensions,

+            String[] headerExtensions, boolean isLibtool,

+            GccCCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super(command, null, sourceExtensions, headerExtensions, isLibtool,

+                libtoolCompiler, newEnvironment, env);

+        isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;

+    }

+    public void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        super.addImpliedArgs(args, debug, multithreaded, 

+        		exceptions, linkType, rtti, optimization, defaultflag);

+        if (isPICMeaningful && linkType.isSharedLibrary()) {

+            args.addElement("-fPIC");

+        }

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new GccCCompiler(getCommand(), this.getSourceExtensions(),

+                    this.getHeaderExtensions(), this.getLibtool(),

+                    (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,

+                    env);

+        }

+        return this;

+    }

+    /**

+     * Create parser to determine dependencies.

+     * 

+     * Will create appropriate parser (C++, FORTRAN) based on file extension.

+     *  

+     */

+    protected Parser createParser(File source) {

+        if (source != null) {

+            String sourceName = source.getName();

+            int lastDot = sourceName.lastIndexOf('.');

+            if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {

+                char afterDot = sourceName.charAt(lastDot + 1);

+                if (afterDot == 'f' || afterDot == 'F') {

+                    return new FortranParser();

+                }

+            }

+        }

+        return new CParser();

+    }

+    public File[] getEnvironmentIncludePath() {

+        if (includePath == null) {

+            //

+            //   construct default include path from machine id and version id

+            //

+            String[] defaultInclude = new String[1];

+            StringBuffer buf = new StringBuffer("/lib/");

+            buf.append(GccProcessor.getMachine());

+            buf.append('/');

+            buf.append(GccProcessor.getVersion());

+            buf.append("/include");

+            defaultInclude[0] = buf.toString();

+            //

+            //   read specs file and look for -istart and -idirafter

+            //

+            String[] specs = GccProcessor.getSpecs();

+            String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",

+                    new String[]{"-isystem ", "-idirafter "});

+            //

+            //   if no entries were found, then use a default path

+            //

+            if (optionValues[0].length == 0 && optionValues[1].length == 0) {

+                optionValues[0] = new String[]{"/usr/local/include",

+                        "/usr/include", "/usr/include/win32api"};

+            }

+            //

+            //  remove mingw entries.

+            //    For MinGW compiles this will mean the

+            //      location of the sys includes will be

+            //      wrong in dependencies.xml

+            //      but that should have no significant effect

+            for (int i = 0; i < optionValues.length; i++) {

+                for (int j = 0; j < optionValues[i].length; j++) {

+                    if (optionValues[i][j].indexOf("mingw") > 0) {

+                        optionValues[i][j] = null;

+                    }

+                }

+            }

+            //

+            //   if cygwin then

+            //     we have to prepend location of gcc32

+            //       and .. to start of absolute filenames to

+            //       have something that will exist in the

+            //       windows filesystem

+            if (GccProcessor.isCygwin()) {

+                GccProcessor.convertCygwinFilenames(optionValues[0]);

+                GccProcessor.convertCygwinFilenames(optionValues[1]);

+                GccProcessor.convertCygwinFilenames(defaultInclude);

+            }

+            int count = CUtil.checkDirectoryArray(optionValues[0]);

+            count += CUtil.checkDirectoryArray(optionValues[1]);

+            count += CUtil.checkDirectoryArray(defaultInclude);

+            includePath = new File[count];

+            int index = 0;

+            for (int i = 0; i < optionValues.length; i++) {

+                for (int j = 0; j < optionValues[i].length; j++) {

+                    if (optionValues[i][j] != null) {

+                        includePath[index++] = new File(optionValues[i][j]);

+                    }

+                }

+            }

+            for (int i = 0; i < defaultInclude.length; i++) {

+                if (defaultInclude[i] != null) {

+                    includePath[index++] = new File(defaultInclude[i]);

+                }

+            }

+        }

+        return (File[]) includePath.clone();

+    }

+    public String getIdentifier() throws BuildException {

+        if (identifier == null) {

+            StringBuffer buf;

+            if (getLibtool()) {

+                buf = new StringBuffer("libtool ");

+            } else {

+                buf = new StringBuffer(' ');

+            }

+            buf.append(getCommand());

+            buf.append(' ');

+            buf.append(GccProcessor.getVersion());

+            buf.append(' ');

+            buf.append(GccProcessor.getMachine());

+            identifier = buf.toString();

+        }

+        return identifier;

+    }

+    public Linker getLinker(LinkType linkType) {

+        return GccLinker.getInstance().getLinker(linkType);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java
new file mode 100644
index 0000000..98f086e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccCompatibleCCompiler.java
@@ -0,0 +1,152 @@
+/*

+ *

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+/**

+ * Abstract base class for compilers that attempt to be command line compatible

+ * with GCC

+ *

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public abstract class GccCompatibleCCompiler extends CommandLineCCompiler {

+    private final static String[] headerExtensions = new String[]{".h", ".hpp",

+            ".inl"};

+    private final static String[] sourceExtensions = new String[]{".c", ".cc",

+            ".cpp", ".cxx", ".c++", ".i", ".f", ".for"};

+    private final static String[] defaultflags = new String[]{"-c"};

+    /**

+     * Private constructor. Use GccCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    protected GccCompatibleCCompiler(String command, String identifierArg,

+            boolean libtool, GccCompatibleCCompiler libtoolCompiler,

+            boolean newEnvironment, Environment env) {

+        super(command, identifierArg, sourceExtensions, headerExtensions,

+                libtool ? ".fo" : ".o", libtool, libtoolCompiler,

+                newEnvironment, env);

+    }

+    /**

+     * Private constructor. Use GccCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    protected GccCompatibleCCompiler(String command, String identifierArg,

+            String[] sourceExtensions, String[] headerExtensions,

+            boolean libtool, GccCompatibleCCompiler libtoolCompiler,

+            boolean newEnvironment, Environment env) {

+        super(command, identifierArg, sourceExtensions, headerExtensions,

+                libtool ? ".fo" : ".o", libtool, libtoolCompiler,

+                newEnvironment, env);

+    }

+    public void addImpliedArgs(final Vector args,

+                    final boolean debug,

+            final boolean multithreaded,

+                        final boolean exceptions,

+                        final LinkType linkType,

+                        final Boolean rtti,

+                        final OptimizationEnum optimization,

+                        final Boolean defaultflag) {

+        //

+        //  -fPIC is too much trouble

+        //      users have to manually add it for

+        //      operating systems that make sense

+        //

+        if (defaultflag != null && defaultflag.booleanValue()) {

+            for (int i = 0; i < defaultflags.length; i++) {

+                args.addElement(defaultflags[i]);

+            }

+        }

+        if (debug) {

+            args.addElement("-g");

+        } else {

+          if (optimization != null) {

+            if (optimization.isSize()) {

+              args.addElement("-Os");

+            } else if (optimization.isSpeed()) {

+              if ("full".equals(optimization.getValue())) {

+                args.addElement("-O2");

+              } else {

+                if ("speed".equals(optimization.getValue())) {

+                  args.addElement("-O1");

+                } else {

+                  args.addElement("-O3");

+                }

+              }

+            }

+          }

+        }

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+        if (rtti != null && !rtti.booleanValue()) {

+          args.addElement("-fno-rtti");

+        }

+

+    }

+    /**

+     * Adds an include path to the command.

+     */

+    public void addIncludePath(String path, Vector cmd) {

+        cmd.addElement("-I" + path);

+    }

+    public void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("-w");

+                break;

+            case 5 :

+                args.addElement("-Werror");

+            /* nobreak */

+            case 4 :

+                args.addElement("-W");

+            /* nobreak */

+            case 3 :

+                args.addElement("-Wall");

+                break;

+        }

+    }

+    public void getDefineSwitch(StringBuffer buffer, String define, String value) {

+        buffer.append("-D");

+        buffer.append(define);

+        if (value != null && value.length() > 0) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ":");

+    }

+    public String getIncludeDirSwitch(String includeDir) {

+        return "-I" + includeDir;

+    }

+    public void getUndefineSwitch(StringBuffer buffer, String define) {

+        buffer.append("-U");

+        buffer.append(define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java
new file mode 100644
index 0000000..6250002
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLibrarian.java
@@ -0,0 +1,41 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+/**

+ * Adapter for the 'ar' archiver

+ * 

+ * @author Adam Murdoch

+ */

+public final class GccLibrarian extends AbstractArLibrarian {

+    private static String[] objFileExtensions = new String[]{".o"};

+    private static GccLibrarian instance = new GccLibrarian("ar",

+            objFileExtensions, false, new GccLibrarian("ar", objFileExtensions,

+                    true, null));

+    public static GccLibrarian getInstance() {

+        return instance;

+    }

+    private GccLibrarian(String command, String[] inputExtensions,

+            boolean isLibtool, GccLibrarian libtoolLibrarian) {

+        super(command, "V", inputExtensions, new String[0], "lib", ".a",

+                isLibtool, libtoolLibrarian);

+    }

+    public Linker getLinker(LinkType type) {

+        return GccLinker.getInstance().getLinker(type);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLinker.java
new file mode 100644
index 0000000..f37f550
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLinker.java
@@ -0,0 +1,210 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+/**

+ * Adapter for the GCC linker

+ * 

+ * @author Adam Murdoch

+ */

+public class GccLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static String[] linkerOptions = new String[]{"-bundle",

+            "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",

+            "-static", "-shared", "-symbolic", "-Xlinker",

+            "--export-all-symbols", "-static-libgcc",};

+    private static final GccLinker dllLinker = new GccLinker("gcc", objFiles,

+            discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles,

+                    discardFiles, "lib", ".so", true, null));

+    private static final GccLinker instance = new GccLinker("gcc", objFiles,

+            discardFiles, "", "", false, null);

+    private static final GccLinker machBundleLinker = new GccLinker("gcc",

+            objFiles, discardFiles, "lib", ".bundle", false, null);

+    private static final GccLinker machDllLinker = new GccLinker("gcc",

+            objFiles, discardFiles, "lib", ".dylib", false, null);

+    public static GccLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    protected GccLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {

+        super(command, "-dumpversion", extensions, ignoredExtensions,

+                outputPrefix, outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        super.addImpliedArgs(debug, linkType, args, defaultflag);

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+    }

+    /**

+     * Allows drived linker to decorate linker option. Override by GccLinker to

+     * prepend a "-Wl," to pass option to through gcc to linker.

+     * 

+     * @param buf

+     *            buffer that may be used and abused in the decoration process,

+     *            must not be null.

+     * @param arg

+     *            linker argument

+     */

+    public String decorateLinkerOption(StringBuffer buf, String arg) {

+        String decoratedArg = arg;

+        if (arg.length() > 1 && arg.charAt(0) == '-') {

+            switch (arg.charAt(1)) {

+                //

+                //   passed automatically by GCC

+                //

+                case 'g' :

+                case 'f' :

+                case 'F' :

+                /* Darwin */

+                case 'm' :

+                case 'O' :

+                case 'W' :

+                case 'l' :

+                case 'L' :

+                case 'u' :

+                case 'v' :

+                    break;

+                default :

+                    boolean known = false;

+                    for (int i = 0; i < linkerOptions.length; i++) {

+                        if (linkerOptions[i].equals(arg)) {

+                            known = true;

+                            break;

+                        }

+                    }

+                    if (!known) {

+                        buf.setLength(0);

+                        buf.append("-Wl,");

+                        buf.append(arg);

+                        decoratedArg = buf.toString();

+                    }

+                    break;

+            }

+        }

+        return decoratedArg;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            //

+            //   construct gcc lib path from machine and version

+            //

+            StringBuffer buf = new StringBuffer("/lib/gcc-lib/");

+            buf.append(GccProcessor.getMachine());

+            buf.append('/');

+            buf.append(GccProcessor.getVersion());

+            //

+            //   build default path from gcc and system /lib and /lib/w32api

+            //

+            String[] impliedLibPath = new String[]{buf.toString(),

+                    "/lib/w32api", "/lib"};

+            //

+            //     read gcc specs file for other library paths

+            //

+            String[] specs = GccProcessor.getSpecs();

+            String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",

+                    new String[]{"%q"});

+            String[] libpath;

+            if (libpaths[0].length > 0) {

+                libpath = new String[libpaths[0].length + 3];

+                int i = 0;

+                for (; i < libpaths[0].length; i++) {

+                    libpath[i] = libpaths[0][i];

+                }

+                libpath[i++] = buf.toString();

+                libpath[i++] = "/lib/w32api";

+                libpath[i++] = "/lib";

+            } else {

+                //

+                //   if a failure to find any matches then

+                //      use some default values for lib path entries

+                libpath = new String[]{"/usr/local/lib/mingw",

+                        "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",

+                        "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};

+            }

+            for (int i = 0; i < libpath.length; i++) {

+                if (libpath[i].indexOf("mingw") >= 0) {

+                    libpath[i] = null;

+                }

+            }

+            //

+            //   if cygwin then

+            //     we have to prepend location of gcc32

+            //       and .. to start of absolute filenames to

+            //       have something that will exist in the

+            //       windows filesystem

+            if (GccProcessor.isCygwin()) {

+                GccProcessor.convertCygwinFilenames(libpath);

+            }

+            //

+            //  check that remaining entries are actual directories

+            //

+            int count = CUtil.checkDirectoryArray(libpath);

+            //

+            //   populate return array with remaining entries

+            //

+            libDirs = new File[count];

+            int index = 0;

+            for (int i = 0; i < libpath.length; i++) {

+                if (libpath[i] != null) {

+                    libDirs[index++] = new File(libpath[i]);

+                }

+            }

+        }

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isPluginModule()) {

+            if (isDarwin()) {

+                return machBundleLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        if (type.isSharedLibrary()) {

+            if (isDarwin()) {

+                return machDllLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
new file mode 100644
index 0000000..236969f
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
@@ -0,0 +1,299 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;

+/**

+ * A add-in class for Gcc processors

+ * 

+ *  

+ */

+public class GccProcessor {

+    //   the results from gcc -dumpmachine

+    private static String machine;

+    private static String[] specs;

+    //   the results from gcc -dumpversion

+    private static String version;

+    private static int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    /**

+     * Converts absolute Cygwin file or directory names to the corresponding

+     * Win32 name.

+     * 

+     * @param names

+     *            array of names, some elements may be null, will be changed in

+     *            place.

+     */

+    public static void convertCygwinFilenames(String[] names) {

+        if (names == null) {

+            throw new NullPointerException("names");

+        }

+        File gccDir = CUtil.getExecutableLocation("gcc.exe");

+        if (gccDir != null) {

+            String prefix = gccDir.getAbsolutePath() + "/..";

+            StringBuffer buf = new StringBuffer();

+            for (int i = 0; i < names.length; i++) {

+                String name = names[i];

+                if (name != null && name.length() > 1 && name.charAt(0) == '/') {

+                    buf.setLength(0);

+                    buf.append(prefix);

+                    buf.append(name);

+                    names[i] = buf.toString();

+                }

+            }

+        }

+    }

+    public static String[] getLibraryPatterns(String[] libnames) {

+        StringBuffer buf = new StringBuffer();

+        String[] patterns = new String[libnames.length * 2];

+        int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);

+        if (isHPUX()) {

+            offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,

+                    offset);

+        } else {

+            offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,

+                    offset);

+        }

+        return patterns;

+    }

+    public static String getMachine() {

+        if (machine == null) {

+            String[] args = new String[]{"gcc", "-dumpmachine"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            if (cmdout.length == 0) {

+                machine = "nomachine";

+            } else {

+                machine = cmdout[0];

+            }

+        }

+        return machine;

+    }

+    public static String[] getOutputFileSwitch(String letter, String outputFile) {

+        StringBuffer buf = new StringBuffer();

+        if (outputFile.indexOf(' ') >= 0) {

+            buf.append('"');

+            buf.append(outputFile.replace('\\', '/'));

+            buf.append('"');

+        } else {

+            buf.append(outputFile.replace('\\', '/'));

+        }

+        String[] retval = new String[]{letter, buf.toString()};

+        return retval;

+    }

+    /**

+     * Returns the contents of the gcc specs file.

+     * 

+     * The implementation locates gcc.exe in the executable path and then

+     * builds a relative path name from the results of -dumpmachine and

+     * -dumpversion. Attempts to use gcc -dumpspecs to provide this information

+     * resulted in stalling on the Execute.run

+     * 

+     * @returns contents of the specs file

+     */

+    public static String[] getSpecs() {

+        if (specs == null) {

+            File gccParent = CUtil.getExecutableLocation("gcc.exe");

+            if (gccParent != null) {

+                //

+                //  build a relative path like

+                //    ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs

+                //

+                StringBuffer buf = new StringBuffer("../lib/gcc-lib/");

+                buf.append(getMachine());

+                buf.append('/');

+                buf.append(getVersion());

+                buf.append("/specs");

+                //

+                //  resolve it relative to the location of gcc.exe

+                //

+                String relativePath = buf.toString();

+                File specsFile = new File(gccParent, relativePath);

+                //

+                //  found the specs file

+                //

+                try {

+                    //

+                    //  read the lines in the file

+                    //

+                    BufferedReader reader = new BufferedReader(new FileReader(

+                            specsFile));

+                    Vector lines = new Vector(100);

+                    String line = reader.readLine();

+                    while (line != null) {

+                        lines.addElement(line);

+                        line = reader.readLine();

+                    }

+                    specs = new String[lines.size()];

+                    lines.copyInto(specs);

+                } catch (IOException ex) {

+                }

+            }

+        }

+        if (specs == null) {

+            specs = new String[0];

+        }

+        return specs;

+    }

+    public static String getVersion() {

+        if (version == null) {

+            String[] args = new String[]{"gcc", "-dumpversion"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            if (cmdout.length == 0) {

+                version = "noversion";

+            } else {

+                version = cmdout[0];

+            }

+        }

+        return version;

+    }

+    public static boolean isCaseSensitive() {

+        return true;

+    }

+    /**

+     * Determines if task is running with cygwin

+     * 

+     * @return true if cygwin was detected

+     */

+    public static boolean isCygwin() {

+        return getMachine().indexOf("cygwin") > 0;

+    }

+    private static boolean isHPUX() {

+        String osname = System.getProperty("os.name").toLowerCase();

+        if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {

+            return true;

+        }

+        return false;

+    }

+    /**

+     * 

+     * Parses the results of the specs file for a specific processor and

+     * options

+     * 

+     * @param specsContent

+     *            Contents of specs file as returned from getSpecs

+     * @param specSectionStart

+     *            start of spec section, for example "*cpp:"

+     * @param options

+     *            command line switches such as "-istart"

+     */

+    public static String[][] parseSpecs(String[] specsContent,

+            String specSectionStart, String[] options) {

+        if (specsContent == null) {

+            throw new NullPointerException("specsContent");

+        }

+        if (specSectionStart == null) {

+            throw new NullPointerException("specSectionStart");

+        }

+        if (options == null) {

+            throw new NullPointerException("option");

+        }

+        String[][] optionValues = new String[options.length][];

+        StringBuffer optionValue = new StringBuffer(40);

+        for (int i = 0; i < specsContent.length; i++) {

+            String specLine = specsContent[i];

+            //

+            //   if start of section then start paying attention

+            //

+            if (specLine.startsWith(specSectionStart)) {

+                Vector[] optionVectors = new Vector[options.length];

+                for (int j = 0; j < options.length; j++) {

+                    optionVectors[j] = new Vector(10);

+                }

+                //

+                //  go to next line and examine contents

+                //     and repeat until end of file

+                //

+                for (i++; i < specsContent.length; i++) {

+                    specLine = specsContent[i];

+                    for (int j = 0; j < options.length; j++) {

+                        int optionStart = specLine.indexOf(options[j]);

+                        while (optionStart >= 0) {

+                            optionValue.setLength(0);

+                            //

+                            //   walk rest of line looking for first non

+                            // whitespace

+                            //       and then next space

+                            boolean hasNonBlank = false;

+                            int k = optionStart + options[j].length();

+                            for (; k < specLine.length(); k++) {

+                                //

+                                //  either a blank or a "}" (close of

+                                // conditional)

+                                //    section will end the path

+                                //

+                                if (specLine.charAt(k) == ' '

+                                        || specLine.charAt(k) == '}') {

+                                    if (hasNonBlank) {

+                                        break;

+                                    }

+                                } else {

+                                    hasNonBlank = true;

+                                    optionValue.append(specLine.charAt(k));

+                                }

+                            }

+                            //

+                            //  transition back to whitespace

+                            //     value is over, add it to vector

+                            if (hasNonBlank) {

+                                optionVectors[j].addElement(optionValue

+                                        .toString());

+                            }

+                            //

+                            //  find next occurance on line

+                            //

+                            optionStart = specLine.indexOf(options[j], k);

+                        }

+                    }

+                }

+                //

+                //   copy vectors over to option arrays

+                //

+                for (int j = 0; j < options.length; j++) {

+                    optionValues[j] = new String[optionVectors[j].size()];

+                    optionVectors[j].copyInto(optionValues[j]);

+                }

+            }

+        }

+        //

+        //   fill in any missing option values with

+        //      a zero-length string array

+        for (int i = 0; i < optionValues.length; i++) {

+            String[] zeroLenArray = new String[0];

+            if (optionValues[i] == null) {

+                optionValues[i] = zeroLenArray;

+            }

+        }

+        return optionValues;

+    }

+    private GccProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GppLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GppLinker.java
new file mode 100644
index 0000000..e7036ab
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GppLinker.java
@@ -0,0 +1,203 @@
+/*

+ * 

+ * Copyright 2003-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+/**

+ * Adapter for the g++ variant of the GCC linker

+ * 

+ * @author Stephen M. Webb <stephen.webb@bregmasoft.com>

+ */

+public class GppLinker extends AbstractLdLinker {

+    protected static final String[] discardFiles = new String[0];

+    protected static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final GppLinker dllLinker = new GppLinker("gcc", objFiles,

+            discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles,

+                    discardFiles, "lib", ".so", true, null));

+    private final static String libPrefix = "libraries: =";

+    protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static String[] linkerOptions = new String[]{"-bundle", "-dylib",

+            "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",

+            "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};

+    private static final GppLinker instance = new GppLinker("gcc", objFiles,

+            discardFiles, "", "", false, null);

+    private static final GppLinker machDllLinker = new GppLinker("gcc",

+            objFiles, discardFiles, "lib", ".dylib", false, null);

+    private static final GppLinker machPluginLinker = new GppLinker("gcc",

+            objFiles, discardFiles, "lib", ".bundle", false, null);

+    public static GppLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private String runtimeLibrary;

+    protected GppLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {

+        super(command, "-dumpversion", extensions, ignoredExtensions,

+                outputPrefix, outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        super.addImpliedArgs(debug, linkType, args, defaultflag);

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+        if (linkType.isStaticRuntime()) {

+            String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"};

+            String[] cmdout = CaptureStreamHandler.run(cmdin);

+            if (cmdout.length > 0) {

+                runtimeLibrary = cmdout[0];

+            } else {

+                runtimeLibrary = null;

+            }

+        } else {

+            runtimeLibrary = "-lstdc++";

+        }

+    }

+    public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,

+                endargs);

+        if (runtimeLibrary != null) {

+            endargs.addElement(runtimeLibrary);

+        }

+        return rs;

+    }

+    /**

+     * Allows drived linker to decorate linker option. Override by GppLinker to

+     * prepend a "-Wl," to pass option to through gcc to linker.

+     * 

+     * @param buf

+     *            buffer that may be used and abused in the decoration process,

+     *            must not be null.

+     * @param arg

+     *            linker argument

+     */

+    public String decorateLinkerOption(StringBuffer buf, String arg) {

+        String decoratedArg = arg;

+        if (arg.length() > 1 && arg.charAt(0) == '-') {

+            switch (arg.charAt(1)) {

+                //

+                //   passed automatically by GCC

+                //

+                case 'g' :

+                case 'f' :

+                case 'F' :

+                /* Darwin */

+                case 'm' :

+                case 'O' :

+                case 'W' :

+                case 'l' :

+                case 'L' :

+                case 'u' :

+                    break;

+                default :

+                    boolean known = false;

+                    for (int i = 0; i < linkerOptions.length; i++) {

+                        if (linkerOptions[i].equals(arg)) {

+                            known = true;

+                            break;

+                        }

+                    }

+                    if (!known) {

+                        buf.setLength(0);

+                        buf.append("-Wl,");

+                        buf.append(arg);

+                        decoratedArg = buf.toString();

+                    }

+                    break;

+            }

+        }

+        return decoratedArg;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            Vector dirs = new Vector();

+            // Ask GCC where it will look for its libraries.

+            String[] args = new String[]{"g++", "-print-search-dirs"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            for (int i = 0; i < cmdout.length; ++i) {

+                int prefixIndex = cmdout[i].indexOf(libPrefix);

+                if (prefixIndex >= 0) {

+                    // Special case DOS-type GCCs like MinGW or Cygwin

+                    int s = prefixIndex + libPrefix.length();

+                    int t = cmdout[i].indexOf(';', s);

+                    while (t > 0) {

+                        dirs.addElement(cmdout[i].substring(s, t));

+                        s = t + 1;

+                        t = cmdout[i].indexOf(';', s);

+                    }

+                    dirs.addElement(cmdout[i].substring(s));

+                    ++i;

+                    for (; i < cmdout.length; ++i) {

+                        dirs.addElement(cmdout[i]);

+                    }

+                }

+            }

+            // Eliminate all but actual directories.

+            String[] libpath = new String[dirs.size()];

+            dirs.copyInto(libpath);

+            int count = CUtil.checkDirectoryArray(libpath);

+            // Build return array.

+            libDirs = new File[count];

+            int index = 0;

+            for (int i = 0; i < libpath.length; ++i) {

+                if (libpath[i] != null) {

+                    libDirs[index++] = new File(libpath[i]);

+                }

+            }

+        }

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isPluginModule()) {

+            if (GccProcessor.getMachine().indexOf("darwin") >= 0) {

+                return machPluginLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        if (type.isSharedLibrary()) {

+            if (GccProcessor.getMachine().indexOf("darwin") >= 0) {

+                return machDllLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/LdLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/LdLinker.java
new file mode 100644
index 0000000..e05fa5b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/LdLinker.java
@@ -0,0 +1,57 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+/**

+ * Adapter for the 'ld' linker

+ * 

+ * @author Curt Arnold

+ */

+public final class LdLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final LdLinker dllLinker = new LdLinker("ld", objFiles,

+            discardFiles, "lib", ".so", false, new LdLinker("ld", objFiles,

+                    discardFiles, "lib", ".so", true, null));

+    private static final LdLinker instance = new LdLinker("ld", objFiles,

+            discardFiles, "", "", false, null);

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    public static LdLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private LdLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) {

+        super(command, "-version", extensions, ignoredExtensions, outputPrefix,

+                outputSuffix, isLibtool, libtoolLinker);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java
new file mode 100644
index 0000000..6a5697e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccCCompiler.java
@@ -0,0 +1,273 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross;

+import java.io.File;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.CompilerParam;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.FortranParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+/**

+ * Adapter for the GCC C/C++ compiler

+ * 

+ * @author Adam Murdoch

+ */

+public final class GccCCompiler extends GccCompatibleCCompiler {

+    private final static String[] headerExtensions = new String[]{".h", ".hpp",

+    ".inl"};

+    private final static String[] sourceExtensions = new String[]{".c", /* C */

+            ".cc", /* C++ */

+            ".cpp", /* C++ */

+            ".cxx", /* C++ */

+            ".c++", /* C++ */

+            ".i", /* preprocessed C */

+            ".ii", /* preprocessed C++ */

+            ".f", /* FORTRAN */

+            ".for", /* FORTRAN */

+            ".m", /* Objective-C */

+            ".mm", /* Objected-C++ */

+            ".s" /* Assembly */

+    };

+    private static final GccCCompiler cppInstance = new GccCCompiler("c++",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("c++", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    private static final GccCCompiler g77Instance = new GccCCompiler("g77",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("g77", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    private static final GccCCompiler gppInstance = new GccCCompiler("g++",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("g++", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    private static final GccCCompiler instance = new GccCCompiler("gcc",

+            sourceExtensions, headerExtensions, false,

+            new GccCCompiler("gcc", sourceExtensions, headerExtensions, true,

+                    null, false, null), false, null);

+    /**

+     * Gets c++ adapter

+     */

+    public static GccCCompiler getCppInstance() {

+        return cppInstance;

+    }

+    /**

+     * Gets g77 adapter

+     */

+    public static GccCCompiler getG77Instance() {

+        return g77Instance;

+    }

+    /**

+     * Gets gpp adapter

+     */

+    public static GccCCompiler getGppInstance() {

+        return gppInstance;

+    }

+    /**

+     * Gets gcc adapter

+     */

+    public static GccCCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private File[] includePath;

+    private boolean isPICMeaningful = true;

+    /**

+     * Private constructor. Use GccCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    private GccCCompiler(String command, String[] sourceExtensions,

+            String[] headerExtensions, boolean isLibtool,

+            GccCCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super(command, null, sourceExtensions, headerExtensions, isLibtool,

+                libtoolCompiler, newEnvironment, env);

+        isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;

+    }

+    public void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        super.addImpliedArgs(args, debug, multithreaded, 

+        		exceptions, linkType, rtti, optimization, defaultflag);

+        if (isPICMeaningful && linkType.isSharedLibrary()) {

+            args.addElement("-fPIC");

+        }

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new GccCCompiler(getCommand(), this.getSourceExtensions(),

+                    this.getHeaderExtensions(), this.getLibtool(),

+                    (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,

+                    env);

+        }

+        return this;

+    }

+    protected Object clone() throws CloneNotSupportedException {

+        GccCCompiler clone = (GccCCompiler) super.clone();

+        return clone;

+    }

+    public void compile(CCTask task, File outputDir, String[] sourceFiles,

+            String[] args, String[] endArgs, boolean relentless,

+            CommandLineCompilerConfiguration config, ProgressMonitor monitor)

+            throws BuildException {

+        try {

+            GccCCompiler clone = (GccCCompiler) this.clone();

+            CompilerParam param = config.getParam("target");

+            if (param != null)

+                clone.setCommand(param.getValue() + "-" + this.getCommand());

+            clone.supercompile(task, outputDir, sourceFiles, args, endArgs,

+                    relentless, config, monitor);

+        } catch (CloneNotSupportedException e) {

+            supercompile(task, outputDir, sourceFiles, args, endArgs,

+                    relentless, config, monitor);

+        }

+    }

+    /**

+     * Create parser to determine dependencies.

+     * 

+     * Will create appropriate parser (C++, FORTRAN) based on file extension.

+     *  

+     */

+    protected Parser createParser(File source) {

+        if (source != null) {

+            String sourceName = source.getName();

+            int lastDot = sourceName.lastIndexOf('.');

+            if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {

+                char afterDot = sourceName.charAt(lastDot + 1);

+                if (afterDot == 'f' || afterDot == 'F') {

+                    return new FortranParser();

+                }

+            }

+        }

+        return new CParser();

+    }

+    public File[] getEnvironmentIncludePath() {

+        if (includePath == null) {

+            //

+            //   construct default include path from machine id and version id

+            //

+            String[] defaultInclude = new String[1];

+            StringBuffer buf = new StringBuffer("/lib/");

+            buf.append(GccProcessor.getMachine());

+            buf.append('/');

+            buf.append(GccProcessor.getVersion());

+            buf.append("/include");

+            defaultInclude[0] = buf.toString();

+            //

+            //   read specs file and look for -istart and -idirafter

+            //

+            String[] specs = GccProcessor.getSpecs();

+            String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",

+                    new String[]{"-isystem ", "-idirafter "});

+            //

+            //   if no entries were found, then use a default path

+            //

+            if (optionValues[0].length == 0 && optionValues[1].length == 0) {

+                optionValues[0] = new String[]{"/usr/local/include",

+                        "/usr/include", "/usr/include/win32api"};

+            }

+            //

+            //  remove mingw entries.

+            //    For MinGW compiles this will mean the

+            //      location of the sys includes will be

+            //      wrong in dependencies.xml

+            //      but that should have no significant effect

+            for (int i = 0; i < optionValues.length; i++) {

+                for (int j = 0; j < optionValues[i].length; j++) {

+                    if (optionValues[i][j].indexOf("mingw") > 0) {

+                        optionValues[i][j] = null;

+                    }

+                }

+            }

+            //

+            //   if cygwin then

+            //     we have to prepend location of gcc32

+            //       and .. to start of absolute filenames to

+            //       have something that will exist in the

+            //       windows filesystem

+            if (GccProcessor.isCygwin()) {

+                GccProcessor.convertCygwinFilenames(optionValues[0]);

+                GccProcessor.convertCygwinFilenames(optionValues[1]);

+                GccProcessor.convertCygwinFilenames(defaultInclude);

+            }

+            int count = CUtil.checkDirectoryArray(optionValues[0]);

+            count += CUtil.checkDirectoryArray(optionValues[1]);

+            count += CUtil.checkDirectoryArray(defaultInclude);

+            includePath = new File[count];

+            int index = 0;

+            for (int i = 0; i < optionValues.length; i++) {

+                for (int j = 0; j < optionValues[i].length; j++) {

+                    if (optionValues[i][j] != null) {

+                        includePath[index++] = new File(optionValues[i][j]);

+                    }

+                }

+            }

+            for (int i = 0; i < defaultInclude.length; i++) {

+                if (defaultInclude[i] != null) {

+                    includePath[index++] = new File(defaultInclude[i]);

+                }

+            }

+        }

+        return (File[]) includePath.clone();

+    }

+    public String getIdentifier() throws BuildException {

+        if (identifier == null) {

+            StringBuffer buf;

+            if (getLibtool()) {

+                buf = new StringBuffer("libtool ");

+            } else {

+                buf = new StringBuffer(' ');

+            }

+            buf.append(getCommand());

+            buf.append(' ');

+            buf.append(GccProcessor.getVersion());

+            buf.append(' ');

+            buf.append(GccProcessor.getMachine());

+            identifier = buf.toString();

+        }

+        return identifier;

+    }

+    public Linker getLinker(LinkType linkType) {

+        return GccLinker.getInstance().getLinker(linkType);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    private void supercompile(CCTask task, File outputDir,

+            String[] sourceFiles, String[] args, String[] endArgs,

+            boolean relentless, CommandLineCompilerConfiguration config,

+            ProgressMonitor monitor) throws BuildException {

+        super.compile(task, outputDir, sourceFiles, args, endArgs, relentless,

+                config, monitor);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java
new file mode 100644
index 0000000..ea2278a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccLibrarian.java
@@ -0,0 +1,69 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.LinkerParam;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractArLibrarian;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the 'ar' archiver

+ * 

+ * @author Adam Murdoch

+ */

+public final class GccLibrarian extends AbstractArLibrarian {

+    private static String[] objFileExtensions = new String[]{".o"};

+    private static GccLibrarian instance = new GccLibrarian("ar",

+            objFileExtensions, false, new GccLibrarian("ar", objFileExtensions,

+                    true, null));

+    public static GccLibrarian getInstance() {

+        return instance;

+    }

+    private GccLibrarian(String command, String[] inputExtensions,

+            boolean isLibtool, GccLibrarian libtoolLibrarian) {

+        super(command, "V", inputExtensions, new String[0], "lib", ".a",

+                isLibtool, libtoolLibrarian);

+    }

+    protected Object clone() throws CloneNotSupportedException {

+        GccLibrarian clone = (GccLibrarian) super.clone();

+        return clone;

+    }

+    public Linker getLinker(LinkType type) {

+        return GccLinker.getInstance().getLinker(type);

+    }

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        try {

+            GccLibrarian clone = (GccLibrarian) this.clone();

+            LinkerParam param = config.getParam("target");

+            if (param != null)

+                clone.setCommand(param.getValue() + "-" + this.getCommand());

+            clone.superlink(task, outputFile, sourceFiles, config);

+        } catch (CloneNotSupportedException e) {

+            superlink(task, outputFile, sourceFiles, config);

+        }

+    }

+    private void superlink(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        super.link(task, outputFile, sourceFiles, config);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java
new file mode 100644
index 0000000..3293829
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccLinker.java
@@ -0,0 +1,234 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross;

+import java.io.File;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.LinkerParam;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the GCC linker

+ * 

+ * @author Adam Murdoch

+ */

+public class GccLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final GccLinker dllLinker = new GccLinker("gcc", objFiles,

+            discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles,

+                    discardFiles, "lib", ".so", true, null));

+    private static final GccLinker instance = new GccLinker("gcc", objFiles,

+            discardFiles, "", "", false, null);

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static String[] linkerOptions = new String[]{"-bundle",

+            "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",

+            "-static", "-shared", "-symbolic", "-Xlinker",

+            "--export-all-symbols", "-static-libgcc",};

+    private static final GccLinker machBundleLinker = new GccLinker("gcc",

+            objFiles, discardFiles, "lib", ".bundle", false, null);

+    private static final GccLinker machDllLinker = new GccLinker("gcc",

+            objFiles, discardFiles, "lib", ".dylib", false, null);

+    public static GccLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    protected GccLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {

+        super(command, "-dumpversion", extensions, ignoredExtensions,

+                outputPrefix, outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        super.addImpliedArgs(debug, linkType, args, defaultflag);

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+    }

+    protected Object clone() throws CloneNotSupportedException {

+        GccLinker clone = (GccLinker) super.clone();

+        return clone;

+    }

+    /**

+     * Allows drived linker to decorate linker option. Override by GccLinker to

+     * prepend a "-Wl," to pass option to through gcc to linker.

+     * 

+     * @param buf

+     *            buffer that may be used and abused in the decoration process,

+     *            must not be null.

+     * @param arg

+     *            linker argument

+     */

+    public String decorateLinkerOption(StringBuffer buf, String arg) {

+        String decoratedArg = arg;

+        if (arg.length() > 1 && arg.charAt(0) == '-') {

+            switch (arg.charAt(1)) {

+                //

+                //   passed automatically by GCC

+                //

+                case 'g' :

+                case 'f' :

+                case 'F' :

+                /* Darwin */

+                case 'm' :

+                case 'O' :

+                case 'W' :

+                case 'l' :

+                case 'L' :

+                case 'u' :

+                case 'v' :

+                    break;

+                default :

+                    boolean known = false;

+                    for (int i = 0; i < linkerOptions.length; i++) {

+                        if (linkerOptions[i].equals(arg)) {

+                            known = true;

+                            break;

+                        }

+                    }

+                    if (!known) {

+                        buf.setLength(0);

+                        buf.append("-Wl,");

+                        buf.append(arg);

+                        decoratedArg = buf.toString();

+                    }

+                    break;

+            }

+        }

+        return decoratedArg;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            //

+            //   construct gcc lib path from machine and version

+            //

+            StringBuffer buf = new StringBuffer("/lib/gcc-lib/");

+            buf.append(GccProcessor.getMachine());

+            buf.append('/');

+            buf.append(GccProcessor.getVersion());

+            //

+            //   build default path from gcc and system /lib and /lib/w32api

+            //

+            String[] impliedLibPath = new String[]{buf.toString(),

+                    "/lib/w32api", "/lib"};

+            //

+            //     read gcc specs file for other library paths

+            //

+            String[] specs = GccProcessor.getSpecs();

+            String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",

+                    new String[]{"%q"});

+            String[] libpath;

+            if (libpaths[0].length > 0) {

+                libpath = new String[libpaths[0].length + 3];

+                int i = 0;

+                for (; i < libpaths[0].length; i++) {

+                    libpath[i] = libpaths[0][i];

+                }

+                libpath[i++] = buf.toString();

+                libpath[i++] = "/lib/w32api";

+                libpath[i++] = "/lib";

+            } else {

+                //

+                //   if a failure to find any matches then

+                //      use some default values for lib path entries

+                libpath = new String[]{"/usr/local/lib/mingw",

+                        "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",

+                        "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};

+            }

+            for (int i = 0; i < libpath.length; i++) {

+                if (libpath[i].indexOf("mingw") >= 0) {

+                    libpath[i] = null;

+                }

+            }

+            //

+            //   if cygwin then

+            //     we have to prepend location of gcc32

+            //       and .. to start of absolute filenames to

+            //       have something that will exist in the

+            //       windows filesystem

+            if (GccProcessor.isCygwin()) {

+                GccProcessor.convertCygwinFilenames(libpath);

+            }

+            //

+            //  check that remaining entries are actual directories

+            //

+            int count = CUtil.checkDirectoryArray(libpath);

+            //

+            //   populate return array with remaining entries

+            //

+            libDirs = new File[count];

+            int index = 0;

+            for (int i = 0; i < libpath.length; i++) {

+                if (libpath[i] != null) {

+                    libDirs[index++] = new File(libpath[i]);

+                }

+            }

+        }

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isPluginModule()) {

+            if (isDarwin()) {

+                return machBundleLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        if (type.isSharedLibrary()) {

+            if (isDarwin()) {

+                return machDllLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        return instance;

+    }

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        try {

+            GccLinker clone = (GccLinker) this.clone();

+            LinkerParam param = config.getParam("target");

+            if (param != null)

+                clone.setCommand(param.getValue() + "-" + this.getCommand());

+            clone.superlink(task, outputFile, sourceFiles, config);

+        } catch (CloneNotSupportedException e) {

+            superlink(task, outputFile, sourceFiles, config);

+        }

+    }

+    private void superlink(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        super.link(task, outputFile, sourceFiles, config);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java
new file mode 100644
index 0000000..283df63
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GccProcessor.java
@@ -0,0 +1,288 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;

+

+/**

+ * A add-in class for Gcc processors

+ * 

+ *  

+ */

+public class GccProcessor {

+    //   the results from gcc -dumpmachine

+    private static String machine;

+    private static String[] specs;

+    //   the results from gcc -dumpversion

+    private static String version;

+    private static int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    /**

+     * Converts absolute Cygwin file or directory names to the corresponding

+     * Win32 name.

+     * 

+     * @param names

+     *            array of names, some elements may be null, will be changed in

+     *            place.

+     */

+    public static void convertCygwinFilenames(String[] names) {

+        if (names == null) {

+            throw new NullPointerException("names");

+        }

+        File gccDir = CUtil.getExecutableLocation("gcc.exe");

+        if (gccDir != null) {

+            String prefix = gccDir.getAbsolutePath() + "/..";

+            StringBuffer buf = new StringBuffer();

+            for (int i = 0; i < names.length; i++) {

+                String name = names[i];

+                if (name != null && name.length() > 1 && name.charAt(0) == '/') {

+                    buf.setLength(0);

+                    buf.append(prefix);

+                    buf.append(name);

+                    names[i] = buf.toString();

+                }

+            }

+        }

+    }

+    

+    public static String getMachine() {

+        if (machine == null) {

+            String[] args = new String[]{"gcc", "-dumpmachine"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            if (cmdout.length == 0) {

+                machine = "nomachine";

+            } else {

+                machine = cmdout[0];

+            }

+        }

+        return machine;

+    }

+    public static String[] getOutputFileSwitch(String letter, String outputFile) {

+        StringBuffer buf = new StringBuffer();

+        if (outputFile.indexOf(' ') >= 0) {

+            buf.append('"');

+            buf.append(outputFile.replace('\\', '/'));

+            buf.append('"');

+        } else {

+            buf.append(outputFile.replace('\\', '/'));

+        }

+        String[] retval = new String[]{letter, buf.toString()};

+        return retval;

+    }

+    /**

+     * Returns the contents of the gcc specs file.

+     * 

+     * The implementation locates gcc.exe in the executable path and then

+     * builds a relative path name from the results of -dumpmachine and

+     * -dumpversion. Attempts to use gcc -dumpspecs to provide this information

+     * resulted in stalling on the Execute.run

+     * 

+     * @returns contents of the specs file

+     */

+    public static String[] getSpecs() {

+        if (specs == null) {

+            File gccParent = CUtil.getExecutableLocation("gcc.exe");

+            if (gccParent != null) {

+                //

+                //  build a relative path like

+                //    ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs

+                //

+                StringBuffer buf = new StringBuffer("../lib/gcc-lib/");

+                buf.append(getMachine());

+                buf.append('/');

+                buf.append(getVersion());

+                buf.append("/specs");

+                //

+                //  resolve it relative to the location of gcc.exe

+                //

+                String relativePath = buf.toString();

+                File specsFile = new File(gccParent, relativePath);

+                //

+                //  found the specs file

+                //

+                try {

+                    //

+                    //  read the lines in the file

+                    //

+                    BufferedReader reader = new BufferedReader(new FileReader(

+                            specsFile));

+                    Vector lines = new Vector(100);

+                    String line = reader.readLine();

+                    while (line != null) {

+                        lines.addElement(line);

+                        line = reader.readLine();

+                    }

+                    specs = new String[lines.size()];

+                    lines.copyInto(specs);

+                } catch (IOException ex) {

+                }

+            }

+        }

+        if (specs == null) {

+            specs = new String[0];

+        }

+        return specs;

+    }

+    public static String getVersion() {

+        if (version == null) {

+            String[] args = new String[]{"gcc", "-dumpversion"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            if (cmdout.length == 0) {

+                version = "noversion";

+            } else {

+                version = cmdout[0];

+            }

+        }

+        return version;

+    }

+    public static boolean isCaseSensitive() {

+        return true;

+    }

+    /**

+     * Determines if task is running with cygwin

+     * 

+     * @return true if cygwin was detected

+     */

+    public static boolean isCygwin() {

+        return getMachine().indexOf("cygwin") > 0;

+    }

+    private static boolean isHPUX() {

+        String osname = System.getProperty("os.name").toLowerCase();

+        if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {

+            return true;

+        }

+        return false;

+    }

+    /**

+     * 

+     * Parses the results of the specs file for a specific processor and

+     * options

+     * 

+     * @param specsContent

+     *            Contents of specs file as returned from getSpecs

+     * @param specSectionStart

+     *            start of spec section, for example "*cpp:"

+     * @param options

+     *            command line switches such as "-istart"

+     */

+    public static String[][] parseSpecs(String[] specsContent,

+            String specSectionStart, String[] options) {

+        if (specsContent == null) {

+            throw new NullPointerException("specsContent");

+        }

+        if (specSectionStart == null) {

+            throw new NullPointerException("specSectionStart");

+        }

+        if (options == null) {

+            throw new NullPointerException("option");

+        }

+        String[][] optionValues = new String[options.length][];

+        StringBuffer optionValue = new StringBuffer(40);

+        for (int i = 0; i < specsContent.length; i++) {

+            String specLine = specsContent[i];

+            //

+            //   if start of section then start paying attention

+            //

+            if (specLine.startsWith(specSectionStart)) {

+                Vector[] optionVectors = new Vector[options.length];

+                for (int j = 0; j < options.length; j++) {

+                    optionVectors[j] = new Vector(10);

+                }

+                //

+                //  go to next line and examine contents

+                //     and repeat until end of file

+                //

+                for (i++; i < specsContent.length; i++) {

+                    specLine = specsContent[i];

+                    for (int j = 0; j < options.length; j++) {

+                        int optionStart = specLine.indexOf(options[j]);

+                        while (optionStart >= 0) {

+                            optionValue.setLength(0);

+                            //

+                            //   walk rest of line looking for first non

+                            // whitespace

+                            //       and then next space

+                            boolean hasNonBlank = false;

+                            int k = optionStart + options[j].length();

+                            for (; k < specLine.length(); k++) {

+                                //

+                                //  either a blank or a "}" (close of

+                                // conditional)

+                                //    section will end the path

+                                //

+                                if (specLine.charAt(k) == ' '

+                                        || specLine.charAt(k) == '}') {

+                                    if (hasNonBlank) {

+                                        break;

+                                    }

+                                } else {

+                                    hasNonBlank = true;

+                                    optionValue.append(specLine.charAt(k));

+                                }

+                            }

+                            //

+                            //  transition back to whitespace

+                            //     value is over, add it to vector

+                            if (hasNonBlank) {

+                                optionVectors[j].addElement(optionValue

+                                        .toString());

+                            }

+                            //

+                            //  find next occurance on line

+                            //

+                            optionStart = specLine.indexOf(options[j], k);

+                        }

+                    }

+                }

+                //

+                //   copy vectors over to option arrays

+                //

+                for (int j = 0; j < options.length; j++) {

+                    optionValues[j] = new String[optionVectors[j].size()];

+                    optionVectors[j].copyInto(optionValues[j]);

+                }

+            }

+        }

+        //

+        //   fill in any missing option values with

+        //      a zero-length string array

+        for (int i = 0; i < optionValues.length; i++) {

+            String[] zeroLenArray = new String[0];

+            if (optionValues[i] == null) {

+                optionValues[i] = zeroLenArray;

+            }

+        }

+        return optionValues;

+    }

+    private GccProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java
new file mode 100644
index 0000000..3ba8f06
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java
@@ -0,0 +1,228 @@
+/*

+ * 

+ * Copyright 2003-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.LinkerParam;

+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the g++ variant of the GCC linker

+ * 

+ * @author Stephen M. Webb <stephen.webb@bregmasoft.com>

+ */

+public class GppLinker extends AbstractLdLinker {

+    protected static final String[] discardFiles = new String[0];

+    protected static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final GppLinker dllLinker = new GppLinker("gcc", objFiles,

+            discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles,

+                    discardFiles, "lib", ".so", true, null));

+    private final static String libPrefix = "libraries: =";

+    protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static String[] linkerOptions = new String[]{"-bundle", "-dylib",

+            "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",

+            "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};

+    private static final GppLinker instance = new GppLinker("gcc", objFiles,

+            discardFiles, "", "", false, null);

+    private static final GppLinker machDllLinker = new GppLinker("gcc",

+            objFiles, discardFiles, "lib", ".dylib", false, null);

+    private static final GppLinker machPluginLinker = new GppLinker("gcc",

+            objFiles, discardFiles, "lib", ".bundle", false, null);

+    public static GppLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private String runtimeLibrary;

+    protected GppLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {

+        super(command, "-dumpversion", extensions, ignoredExtensions,

+                outputPrefix, outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        super.addImpliedArgs(debug, linkType, args, defaultflag);

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+        if (linkType.isStaticRuntime()) {

+            String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"};

+            String[] cmdout = CaptureStreamHandler.run(cmdin);

+            if (cmdout.length > 0) {

+                runtimeLibrary = cmdout[0];

+            } else {

+                runtimeLibrary = null;

+            }

+        } else {

+            runtimeLibrary = "-lstdc++";

+        }

+    }

+    public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,

+                endargs);

+        if (runtimeLibrary != null) {

+            endargs.addElement(runtimeLibrary);

+        }

+        return rs;

+    }

+    protected Object clone() throws CloneNotSupportedException {

+        GppLinker clone = (GppLinker) super.clone();

+        return clone;

+    }

+    /**

+     * Allows drived linker to decorate linker option. Override by GppLinker to

+     * prepend a "-Wl," to pass option to through gcc to linker.

+     * 

+     * @param buf

+     *            buffer that may be used and abused in the decoration process,

+     *            must not be null.

+     * @param arg

+     *            linker argument

+     */

+    public String decorateLinkerOption(StringBuffer buf, String arg) {

+        String decoratedArg = arg;

+        if (arg.length() > 1 && arg.charAt(0) == '-') {

+            switch (arg.charAt(1)) {

+                //

+                //   passed automatically by GCC

+                //

+                case 'g' :

+                case 'f' :

+                case 'F' :

+                /* Darwin */

+                case 'm' :

+                case 'O' :

+                case 'W' :

+                case 'l' :

+                case 'L' :

+                case 'u' :

+                    break;

+                default :

+                    boolean known = false;

+                    for (int i = 0; i < linkerOptions.length; i++) {

+                        if (linkerOptions[i].equals(arg)) {

+                            known = true;

+                            break;

+                        }

+                    }

+                    if (!known) {

+                        buf.setLength(0);

+                        buf.append("-Wl,");

+                        buf.append(arg);

+                        decoratedArg = buf.toString();

+                    }

+                    break;

+            }

+        }

+        return decoratedArg;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            Vector dirs = new Vector();

+            // Ask GCC where it will look for its libraries.

+            String[] args = new String[]{"g++", "-print-search-dirs"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            for (int i = 0; i < cmdout.length; ++i) {

+                int prefixIndex = cmdout[i].indexOf(libPrefix);

+                if (prefixIndex >= 0) {

+                    // Special case DOS-type GCCs like MinGW or Cygwin

+                    int s = prefixIndex + libPrefix.length();

+                    int t = cmdout[i].indexOf(';', s);

+                    while (t > 0) {

+                        dirs.addElement(cmdout[i].substring(s, t));

+                        s = t + 1;

+                        t = cmdout[i].indexOf(';', s);

+                    }

+                    dirs.addElement(cmdout[i].substring(s));

+                    ++i;

+                    for (; i < cmdout.length; ++i) {

+                        dirs.addElement(cmdout[i]);

+                    }

+                }

+            }

+            // Eliminate all but actual directories.

+            String[] libpath = new String[dirs.size()];

+            dirs.copyInto(libpath);

+            int count = CUtil.checkDirectoryArray(libpath);

+            // Build return array.

+            libDirs = new File[count];

+            int index = 0;

+            for (int i = 0; i < libpath.length; ++i) {

+                if (libpath[i] != null) {

+                    libDirs[index++] = new File(libpath[i]);

+                }

+            }

+        }

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isPluginModule()) {

+            if (GccProcessor.getMachine().indexOf("darwin") >= 0) {

+                return machPluginLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        if (type.isSharedLibrary()) {

+            if (GccProcessor.getMachine().indexOf("darwin") >= 0) {

+                return machDllLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        return instance;

+    }

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        try {

+            GppLinker clone = (GppLinker) this.clone();

+            LinkerParam param = config.getParam("target");

+            if (param != null)

+                clone.setCommand(param.getValue() + "-" + this.getCommand());

+            clone.superlink(task, outputFile, sourceFiles, config);

+        } catch (CloneNotSupportedException e) {

+            superlink(task, outputFile, sourceFiles, config);

+        }

+    }

+    private void superlink(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        super.link(task, outputFile, sourceFiles, config);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java
new file mode 100644
index 0000000..8ac0cf8
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/LdLinker.java
@@ -0,0 +1,83 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.LinkerParam;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the 'ld' linker

+ * 

+ * @author Curt Arnold

+ */

+public final class LdLinker extends AbstractLdLinker {

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final String[] discardFiles = new String[0];

+    private static final LdLinker dllLinker = new LdLinker("ld", objFiles,

+            discardFiles, "lib", ".so", false, new LdLinker("ld", objFiles,

+                    discardFiles, "lib", ".so", true, null));

+    private static final LdLinker instance = new LdLinker("ld", objFiles,

+            discardFiles, "", "", false, null);

+    public static LdLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private LdLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) {

+        super(command, "-version", extensions, ignoredExtensions, outputPrefix,

+                outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected Object clone() throws CloneNotSupportedException {

+        LdLinker clone = (LdLinker) super.clone();

+        return clone;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        try {

+            LdLinker clone = (LdLinker) this.clone();

+            LinkerParam param = config.getParam("target");

+            if (param != null)

+                clone.setCommand(param.getValue() + "-" + this.getCommand());

+            clone.superlink(task, outputFile, sourceFiles, config);

+        } catch (CloneNotSupportedException e) {

+            superlink(task, outputFile, sourceFiles, config);

+        }

+    }

+    private void superlink(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        super.link(task, outputFile, sourceFiles, config);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java
new file mode 100644
index 0000000..62d65b9
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccCCompiler.java
@@ -0,0 +1,245 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+import net.sf.antcontrib.cpptasks.parser.CParser;

+import net.sf.antcontrib.cpptasks.parser.FortranParser;

+import net.sf.antcontrib.cpptasks.parser.Parser;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Environment;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+/**

+ * Adapter for the GCC C/C++ compiler

+ * 

+ * @author Adam Murdoch

+ */

+public final class GccCCompiler extends GccCompatibleCCompiler {

+    private final static String[] sourceExtensions = new String[]{".c", /* C */

+            ".cc", /* C++ */

+            ".cpp", /* C++ */

+            ".cxx", /* C++ */

+            ".c++", /* C++ */

+            ".i", /* preprocessed C */

+            ".ii", /* preprocessed C++ */

+            ".f", /* FORTRAN */

+            ".for", /* FORTRAN */

+            ".m", /* Objective-C */

+            ".mm", /* Objected-C++ */

+            ".s" /* Assembly */

+            };

+    private final static String[] headerExtensions = new String[]{".h", ".hpp",

+    ".inl"};

+    public static final String CMD_PREFIX = "sparc-sun-solaris2-";

+    private static final GccCCompiler cppInstance = new GccCCompiler(CMD_PREFIX

+            + "c++", sourceExtensions, headerExtensions, false,

+            new GccCCompiler(CMD_PREFIX + "c++", sourceExtensions,

+                    headerExtensions, true, null, false, null), false, null);

+    private static final GccCCompiler g77Instance = new GccCCompiler(CMD_PREFIX

+            + "g77", sourceExtensions, headerExtensions, false,

+            new GccCCompiler(CMD_PREFIX + "g77", sourceExtensions,

+                    headerExtensions, true, null, false, null), false, null);

+    private static final GccCCompiler gppInstance = new GccCCompiler(CMD_PREFIX

+            + "g++", sourceExtensions, headerExtensions, false,

+            new GccCCompiler(CMD_PREFIX + "g++", sourceExtensions,

+                    headerExtensions, true, null, false, null), false, null);

+    private static final GccCCompiler instance = new GccCCompiler(CMD_PREFIX

+            + "gcc", sourceExtensions, headerExtensions, false,

+            new GccCCompiler(CMD_PREFIX + "gcc", sourceExtensions,

+                    headerExtensions, true, null, false, null), false, null);

+    /**

+     * Gets c++ adapter

+     */

+    public static GccCCompiler getCppInstance() {

+        return cppInstance;

+    }

+    /**

+     * Gets g77 adapter

+     */

+    public static GccCCompiler getG77Instance() {

+        return g77Instance;

+    }

+    /**

+     * Gets gpp adapter

+     */

+    public static GccCCompiler getGppInstance() {

+        return gppInstance;

+    }

+    /**

+     * Gets gcc adapter

+     */

+    public static GccCCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private File[] includePath;

+    private boolean isPICMeaningful = true;

+    /**

+     * Private constructor. Use GccCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    private GccCCompiler(String command, String[] sourceExtensions,

+            String[] headerExtensions, boolean isLibtool,

+            GccCCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super(command, null, sourceExtensions, headerExtensions, isLibtool,

+                libtoolCompiler, newEnvironment, env);

+        isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;

+    }

+    public void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        super.addImpliedArgs(args, debug, multithreaded, 

+        		exceptions, linkType, rtti, optimization, defaultflag);

+        if (isPICMeaningful && linkType.isSharedLibrary()) {

+            args.addElement("-fPIC");

+        }

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new GccCCompiler(getCommand(), this.getSourceExtensions(),

+                    this.getHeaderExtensions(), this.getLibtool(),

+                    (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,

+                    env);

+        }

+        return this;

+    }

+    /**

+     * Create parser to determine dependencies.

+     * 

+     * Will create appropriate parser (C++, FORTRAN) based on file extension.

+     *  

+     */

+    protected Parser createParser(File source) {

+        if (source != null) {

+            String sourceName = source.getName();

+            int lastDot = sourceName.lastIndexOf('.');

+            if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {

+                char afterDot = sourceName.charAt(lastDot + 1);

+                if (afterDot == 'f' || afterDot == 'F') {

+                    return new FortranParser();

+                }

+            }

+        }

+        return new CParser();

+    }

+    public File[] getEnvironmentIncludePath() {

+        if (includePath == null) {

+            //

+            //   construct default include path from machine id and version id

+            //

+            String[] defaultInclude = new String[1];

+            StringBuffer buf = new StringBuffer("/lib/");

+            buf.append(GccProcessor.getMachine());

+            buf.append('/');

+            buf.append(GccProcessor.getVersion());

+            buf.append("/include");

+            defaultInclude[0] = buf.toString();

+            //

+            //   read specs file and look for -istart and -idirafter

+            //

+            String[] specs = GccProcessor.getSpecs();

+            String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",

+                    new String[]{"-isystem ", "-idirafter "});

+            //

+            //   if no entries were found, then use a default path

+            //

+            if (optionValues[0].length == 0 && optionValues[1].length == 0) {

+                optionValues[0] = new String[]{"/usr/local/include",

+                        "/usr/include", "/usr/include/win32api"};

+            }

+            //

+            //  remove mingw entries.

+            //    For MinGW compiles this will mean the

+            //      location of the sys includes will be

+            //      wrong in dependencies.xml

+            //      but that should have no significant effect

+            for (int i = 0; i < optionValues.length; i++) {

+                for (int j = 0; j < optionValues[i].length; j++) {

+                    if (optionValues[i][j].indexOf("mingw") > 0) {

+                        optionValues[i][j] = null;

+                    }

+                }

+            }

+            //

+            //   if cygwin then

+            //     we have to prepend location of gcc32

+            //       and .. to start of absolute filenames to

+            //       have something that will exist in the

+            //       windows filesystem

+            if (GccProcessor.isCygwin()) {

+                GccProcessor.convertCygwinFilenames(optionValues[0]);

+                GccProcessor.convertCygwinFilenames(optionValues[1]);

+                GccProcessor.convertCygwinFilenames(defaultInclude);

+            }

+            int count = CUtil.checkDirectoryArray(optionValues[0]);

+            count += CUtil.checkDirectoryArray(optionValues[1]);

+            count += CUtil.checkDirectoryArray(defaultInclude);

+            includePath = new File[count];

+            int index = 0;

+            for (int i = 0; i < optionValues.length; i++) {

+                for (int j = 0; j < optionValues[i].length; j++) {

+                    if (optionValues[i][j] != null) {

+                        includePath[index++] = new File(optionValues[i][j]);

+                    }

+                }

+            }

+            for (int i = 0; i < defaultInclude.length; i++) {

+                if (defaultInclude[i] != null) {

+                    includePath[index++] = new File(defaultInclude[i]);

+                }

+            }

+        }

+        return (File[]) includePath.clone();

+    }

+    public String getIdentifier() throws BuildException {

+        if (identifier == null) {

+            StringBuffer buf;

+            if (getLibtool()) {

+                buf = new StringBuffer("libtool ");

+            } else {

+                buf = new StringBuffer(' ');

+            }

+            buf.append(getCommand());

+            buf.append(' ');

+            buf.append(GccProcessor.getVersion());

+            buf.append(' ');

+            buf.append(GccProcessor.getMachine());

+            identifier = buf.toString();

+        }

+        return identifier;

+    }

+    public Linker getLinker(LinkType linkType) {

+        return GccLinker.getInstance().getLinker(linkType);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java
new file mode 100644
index 0000000..bb24387
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLibrarian.java
@@ -0,0 +1,43 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractArLibrarian;

+/**

+ * Adapter for the 'ar' archiver

+ * 

+ * @author Adam Murdoch

+ */

+public final class GccLibrarian extends AbstractArLibrarian {

+    private static String[] objFileExtensions = new String[]{".o"};

+    private static GccLibrarian instance = new GccLibrarian(

+            GccCCompiler.CMD_PREFIX + "ar", objFileExtensions, false,

+            new GccLibrarian(GccCCompiler.CMD_PREFIX + "ar", objFileExtensions,

+                    true, null));

+    public static GccLibrarian getInstance() {

+        return instance;

+    }

+    private GccLibrarian(String command, String[] inputExtensions,

+            boolean isLibtool, GccLibrarian libtoolLibrarian) {

+        super(command, "V", inputExtensions, new String[0], "lib", ".a",

+                isLibtool, libtoolLibrarian);

+    }

+    public Linker getLinker(LinkType type) {

+        return GccLinker.getInstance().getLinker(type);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java
new file mode 100644
index 0000000..914da34
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccLinker.java
@@ -0,0 +1,215 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+/**

+ * Adapter for the GCC linker

+ * 

+ * @author Adam Murdoch

+ */

+public class GccLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static String[] linkerOptions = new String[]{"-bundle",

+            "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",

+            "-static", "-shared", "-symbolic", "-Xlinker",

+            "--export-all-symbols", "-static-libgcc",};

+    private static final GccLinker dllLinker = new GccLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",

+            ".so", false, new GccLinker(GccCCompiler.CMD_PREFIX + "gcc",

+                    objFiles, discardFiles, "lib", ".so", true, null));

+    private static final GccLinker instance = new GccLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "",

+            false, null);

+    private static final GccLinker machBundleLinker = new GccLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",

+            ".bundle", false, null);

+    private static final GccLinker machDllLinker = new GccLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",

+            ".dylib", false, null);

+    public static GccLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    protected GccLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {

+        super(command, "-dumpversion", extensions, ignoredExtensions,

+                outputPrefix, outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        super.addImpliedArgs(debug, linkType, args, defaultflag);

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+    }

+    /**

+     * Allows drived linker to decorate linker option. Override by GccLinker to

+     * prepend a "-Wl," to pass option to through gcc to linker.

+     * 

+     * @param buf

+     *            buffer that may be used and abused in the decoration process,

+     *            must not be null.

+     * @param arg

+     *            linker argument

+     */

+    public String decorateLinkerOption(StringBuffer buf, String arg) {

+        String decoratedArg = arg;

+        if (arg.length() > 1 && arg.charAt(0) == '-') {

+            switch (arg.charAt(1)) {

+                //

+                //   passed automatically by GCC

+                //

+                case 'g' :

+                case 'f' :

+                case 'F' :

+                /* Darwin */

+                case 'm' :

+                case 'O' :

+                case 'W' :

+                case 'l' :

+                case 'L' :

+                case 'u' :

+                case 'v' :

+                    break;

+                default :

+                    boolean known = false;

+                    for (int i = 0; i < linkerOptions.length; i++) {

+                        if (linkerOptions[i].equals(arg)) {

+                            known = true;

+                            break;

+                        }

+                    }

+                    if (!known) {

+                        buf.setLength(0);

+                        buf.append("-Wl,");

+                        buf.append(arg);

+                        decoratedArg = buf.toString();

+                    }

+                    break;

+            }

+        }

+        return decoratedArg;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            //

+            //   construct gcc lib path from machine and version

+            //

+            StringBuffer buf = new StringBuffer("/lib/gcc-lib/");

+            buf.append(GccProcessor.getMachine());

+            buf.append('/');

+            buf.append(GccProcessor.getVersion());

+            //

+            //   build default path from gcc and system /lib and /lib/w32api

+            //

+            String[] impliedLibPath = new String[]{buf.toString(),

+                    "/lib/w32api", "/lib"};

+            //

+            //     read gcc specs file for other library paths

+            //

+            String[] specs = GccProcessor.getSpecs();

+            String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",

+                    new String[]{"%q"});

+            String[] libpath;

+            if (libpaths[0].length > 0) {

+                libpath = new String[libpaths[0].length + 3];

+                int i = 0;

+                for (; i < libpaths[0].length; i++) {

+                    libpath[i] = libpaths[0][i];

+                }

+                libpath[i++] = buf.toString();

+                libpath[i++] = "/lib/w32api";

+                libpath[i++] = "/lib";

+            } else {

+                //

+                //   if a failure to find any matches then

+                //      use some default values for lib path entries

+                libpath = new String[]{"/usr/local/lib/mingw",

+                        "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",

+                        "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};

+            }

+            for (int i = 0; i < libpath.length; i++) {

+                if (libpath[i].indexOf("mingw") >= 0) {

+                    libpath[i] = null;

+                }

+            }

+            //

+            //   if cygwin then

+            //     we have to prepend location of gcc32

+            //       and .. to start of absolute filenames to

+            //       have something that will exist in the

+            //       windows filesystem

+            if (GccProcessor.isCygwin()) {

+                GccProcessor.convertCygwinFilenames(libpath);

+            }

+            //

+            //  check that remaining entries are actual directories

+            //

+            int count = CUtil.checkDirectoryArray(libpath);

+            //

+            //   populate return array with remaining entries

+            //

+            libDirs = new File[count];

+            int index = 0;

+            for (int i = 0; i < libpath.length; i++) {

+                if (libpath[i] != null) {

+                    libDirs[index++] = new File(libpath[i]);

+                }

+            }

+        }

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isPluginModule()) {

+            if (isDarwin()) {

+                return machBundleLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        if (type.isSharedLibrary()) {

+            if (isDarwin()) {

+                return machDllLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java
new file mode 100644
index 0000000..599d6a8
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GccProcessor.java
@@ -0,0 +1,305 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2;

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * A add-in class for Gcc processors

+ * 

+ *  

+ */

+public class GccProcessor {

+    //   the results from gcc -dumpmachine

+    private static String machine;

+    private static String[] specs;

+    //   the results from gcc -dumpversion

+    private static String version;

+    private static int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    /**

+     * Converts absolute Cygwin file or directory names to the corresponding

+     * Win32 name.

+     * 

+     * @param names

+     *            array of names, some elements may be null, will be changed in

+     *            place.

+     */

+    public static void convertCygwinFilenames(String[] names) {

+        if (names == null) {

+            throw new NullPointerException("names");

+        }

+        File gccDir = CUtil.getExecutableLocation(GccCCompiler.CMD_PREFIX

+                + "gcc.exe");

+        if (gccDir != null) {

+            String prefix = gccDir.getAbsolutePath() + "/..";

+            StringBuffer buf = new StringBuffer();

+            for (int i = 0; i < names.length; i++) {

+                String name = names[i];

+                if (name != null && name.length() > 1 && name.charAt(0) == '/') {

+                    buf.setLength(0);

+                    buf.append(prefix);

+                    buf.append(name);

+                    names[i] = buf.toString();

+                }

+            }

+        }

+    }

+    public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        String[] patterns = new String[libnames.length * 2];

+        int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);

+        if (isHPUX()) {

+            offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,

+                    offset);

+        } else {

+            offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,

+                    offset);

+        }

+        return patterns;

+    }

+    public static String getMachine() {

+        if (machine == null) {

+            String[] args = new String[]{GccCCompiler.CMD_PREFIX + "gcc",

+                    "-dumpmachine"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            if (cmdout.length == 0) {

+                machine = "nomachine";

+            } else {

+                machine = cmdout[0];

+            }

+        }

+        return machine;

+    }

+    public static String[] getOutputFileSwitch(String letter, String outputFile) {

+        StringBuffer buf = new StringBuffer();

+        if (outputFile.indexOf(' ') >= 0) {

+            buf.append('"');

+            buf.append(outputFile.replace('\\', '/'));

+            buf.append('"');

+        } else {

+            buf.append(outputFile.replace('\\', '/'));

+        }

+        String[] retval = new String[]{letter, buf.toString()};

+        return retval;

+    }

+    /**

+     * Returns the contents of the gcc specs file.

+     * 

+     * The implementation locates gcc.exe in the executable path and then

+     * builds a relative path name from the results of -dumpmachine and

+     * -dumpversion. Attempts to use gcc -dumpspecs to provide this information

+     * resulted in stalling on the Execute.run

+     * 

+     * @returns contents of the specs file

+     */

+    public static String[] getSpecs() {

+        if (specs == null) {

+            File gccParent = CUtil

+                    .getExecutableLocation(GccCCompiler.CMD_PREFIX + "gcc.exe");

+            if (gccParent != null) {

+                //

+                //  build a relative path like

+                //    ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs

+                //

+                StringBuffer buf = new StringBuffer("../lib/gcc-lib/");

+                buf.append(getMachine());

+                buf.append('/');

+                buf.append(getVersion());

+                buf.append("/specs");

+                //

+                //  resolve it relative to the location of gcc.exe

+                //

+                String relativePath = buf.toString();

+                File specsFile = new File(gccParent, relativePath);

+                //

+                //  found the specs file

+                //

+                try {

+                    //

+                    //  read the lines in the file

+                    //

+                    BufferedReader reader = new BufferedReader(new FileReader(

+                            specsFile));

+                    Vector lines = new Vector(100);

+                    String line = reader.readLine();

+                    while (line != null) {

+                        lines.addElement(line);

+                        line = reader.readLine();

+                    }

+                    specs = new String[lines.size()];

+                    lines.copyInto(specs);

+                } catch (IOException ex) {

+                }

+            }

+        }

+        if (specs == null) {

+            specs = new String[0];

+        }

+        return specs;

+    }

+    public static String getVersion() {

+        if (version == null) {

+            String[] args = new String[]{GccCCompiler.CMD_PREFIX + "gcc",

+                    "-dumpversion"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            if (cmdout.length == 0) {

+                version = "noversion";

+            } else {

+                version = cmdout[0];

+            }

+        }

+        return version;

+    }

+    public static boolean isCaseSensitive() {

+        return true;

+    }

+    /**

+     * Determines if task is running with cygwin

+     * 

+     * @return true if cygwin was detected

+     */

+    public static boolean isCygwin() {

+        return getMachine().indexOf("cygwin") > 0;

+    }

+    private static boolean isHPUX() {

+        String osname = System.getProperty("os.name").toLowerCase();

+        if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {

+            return true;

+        }

+        return false;

+    }

+    /**

+     * 

+     * Parses the results of the specs file for a specific processor and

+     * options

+     * 

+     * @param specsContent

+     *            Contents of specs file as returned from getSpecs

+     * @param specSectionStart

+     *            start of spec section, for example "*cpp:"

+     * @param options

+     *            command line switches such as "-istart"

+     */

+    public static String[][] parseSpecs(String[] specsContent,

+            String specSectionStart, String[] options) {

+        if (specsContent == null) {

+            throw new NullPointerException("specsContent");

+        }

+        if (specSectionStart == null) {

+            throw new NullPointerException("specSectionStart");

+        }

+        if (options == null) {

+            throw new NullPointerException("option");

+        }

+        String[][] optionValues = new String[options.length][];

+        StringBuffer optionValue = new StringBuffer(40);

+        for (int i = 0; i < specsContent.length; i++) {

+            String specLine = specsContent[i];

+            //

+            //   if start of section then start paying attention

+            //

+            if (specLine.startsWith(specSectionStart)) {

+                Vector[] optionVectors = new Vector[options.length];

+                for (int j = 0; j < options.length; j++) {

+                    optionVectors[j] = new Vector(10);

+                }

+                //

+                //  go to next line and examine contents

+                //     and repeat until end of file

+                //

+                for (i++; i < specsContent.length; i++) {

+                    specLine = specsContent[i];

+                    for (int j = 0; j < options.length; j++) {

+                        int optionStart = specLine.indexOf(options[j]);

+                        while (optionStart >= 0) {

+                            optionValue.setLength(0);

+                            //

+                            //   walk rest of line looking for first non

+                            // whitespace

+                            //       and then next space

+                            boolean hasNonBlank = false;

+                            int k = optionStart + options[j].length();

+                            for (; k < specLine.length(); k++) {

+                                //

+                                //  either a blank or a "}" (close of

+                                // conditional)

+                                //    section will end the path

+                                //

+                                if (specLine.charAt(k) == ' '

+                                        || specLine.charAt(k) == '}') {

+                                    if (hasNonBlank) {

+                                        break;

+                                    }

+                                } else {

+                                    hasNonBlank = true;

+                                    optionValue.append(specLine.charAt(k));

+                                }

+                            }

+                            //

+                            //  transition back to whitespace

+                            //     value is over, add it to vector

+                            if (hasNonBlank) {

+                                optionVectors[j].addElement(optionValue

+                                        .toString());

+                            }

+                            //

+                            //  find next occurance on line

+                            //

+                            optionStart = specLine.indexOf(options[j], k);

+                        }

+                    }

+                }

+                //

+                //   copy vectors over to option arrays

+                //

+                for (int j = 0; j < options.length; j++) {

+                    optionValues[j] = new String[optionVectors[j].size()];

+                    optionVectors[j].copyInto(optionValues[j]);

+                }

+            }

+        }

+        //

+        //   fill in any missing option values with

+        //      a zero-length string array

+        for (int i = 0; i < optionValues.length; i++) {

+            String[] zeroLenArray = new String[0];

+            if (optionValues[i] == null) {

+                optionValues[i] = zeroLenArray;

+            }

+        }

+        return optionValues;

+    }

+    private GccProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java
new file mode 100644
index 0000000..6a4c0ab
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/GppLinker.java
@@ -0,0 +1,210 @@
+/*

+ * 

+ * Copyright 2003-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+/**

+ * Adapter for the g++ variant of the GCC linker

+ * 

+ * @author Stephen M. Webb <stephen.webb@bregmasoft.com>

+ */

+public class GppLinker extends AbstractLdLinker {

+    protected static final String[] discardFiles = new String[0];

+    protected static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private final static String libPrefix = "libraries: =";

+    protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static String[] linkerOptions = new String[]{"-bundle", "-dylib",

+            "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",

+            "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};

+    private static final GppLinker dllLinker = new GppLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",

+            ".so", false, new GppLinker(GccCCompiler.CMD_PREFIX + "gcc",

+                    objFiles, discardFiles, "lib", ".so", true, null));

+    private static final GppLinker instance = new GppLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "",

+            false, null);

+    private static final GppLinker machDllLinker = new GppLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",

+            ".dylib", false, null);

+    private static final GppLinker machPluginLinker = new GppLinker(

+            GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",

+            ".bundle", false, null);

+    public static GppLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private String runtimeLibrary;

+    protected GppLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {

+        super(command, "-dumpversion", extensions, ignoredExtensions,

+                outputPrefix, outputSuffix, isLibtool, libtoolLinker);

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        super.addImpliedArgs(debug, linkType, args, defaultflag);

+        if (getIdentifier().indexOf("mingw") >= 0) {

+            if (linkType.isSubsystemConsole()) {

+                args.addElement("-mconsole");

+            }

+            if (linkType.isSubsystemGUI()) {

+                args.addElement("-mwindows");

+            }

+        }

+        if (linkType.isStaticRuntime()) {

+            String[] cmdin = new String[]{GccCCompiler.CMD_PREFIX + "g++",

+                    "-print-file-name=libstdc++.a"};

+            String[] cmdout = CaptureStreamHandler.run(cmdin);

+            if (cmdout.length > 0) {

+                runtimeLibrary = cmdout[0];

+            } else {

+                runtimeLibrary = null;

+            }

+        } else {

+            runtimeLibrary = "-lstdc++";

+        }

+    }

+    public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,

+                endargs);

+        if (runtimeLibrary != null) {

+            endargs.addElement(runtimeLibrary);

+        }

+        return rs;

+    }

+    /**

+     * Allows drived linker to decorate linker option. Override by GppLinker to

+     * prepend a "-Wl," to pass option to through gcc to linker.

+     * 

+     * @param buf

+     *            buffer that may be used and abused in the decoration process,

+     *            must not be null.

+     * @param arg

+     *            linker argument

+     */

+    public String decorateLinkerOption(StringBuffer buf, String arg) {

+        String decoratedArg = arg;

+        if (arg.length() > 1 && arg.charAt(0) == '-') {

+            switch (arg.charAt(1)) {

+                //

+                //   passed automatically by GCC

+                //

+                case 'g' :

+                case 'f' :

+                case 'F' :

+                /* Darwin */

+                case 'm' :

+                case 'O' :

+                case 'W' :

+                case 'l' :

+                case 'L' :

+                case 'u' :

+                    break;

+                default :

+                    boolean known = false;

+                    for (int i = 0; i < linkerOptions.length; i++) {

+                        if (linkerOptions[i].equals(arg)) {

+                            known = true;

+                            break;

+                        }

+                    }

+                    if (!known) {

+                        buf.setLength(0);

+                        buf.append("-Wl,");

+                        buf.append(arg);

+                        decoratedArg = buf.toString();

+                    }

+                    break;

+            }

+        }

+        return decoratedArg;

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            Vector dirs = new Vector();

+            // Ask GCC where it will look for its libraries.

+            String[] args = new String[]{GccCCompiler.CMD_PREFIX + "g++",

+                    "-print-search-dirs"};

+            String[] cmdout = CaptureStreamHandler.run(args);

+            for (int i = 0; i < cmdout.length; ++i) {

+                int prefixIndex = cmdout[i].indexOf(libPrefix);

+                if (prefixIndex >= 0) {

+                    // Special case DOS-type GCCs like MinGW or Cygwin

+                    int s = prefixIndex + libPrefix.length();

+                    int t = cmdout[i].indexOf(';', s);

+                    while (t > 0) {

+                        dirs.addElement(cmdout[i].substring(s, t));

+                        s = t + 1;

+                        t = cmdout[i].indexOf(';', s);

+                    }

+                    dirs.addElement(cmdout[i].substring(s));

+                    ++i;

+                    for (; i < cmdout.length; ++i) {

+                        dirs.addElement(cmdout[i]);

+                    }

+                }

+            }

+            // Eliminate all but actual directories.

+            String[] libpath = new String[dirs.size()];

+            dirs.copyInto(libpath);

+            int count = CUtil.checkDirectoryArray(libpath);

+            // Build return array.

+            libDirs = new File[count];

+            int index = 0;

+            for (int i = 0; i < libpath.length; ++i) {

+                if (libpath[i] != null) {

+                    libDirs[index++] = new File(libpath[i]);

+                }

+            }

+        }

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isPluginModule()) {

+            if (GccProcessor.getMachine().indexOf("darwin") >= 0) {

+                return machPluginLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        if (type.isSharedLibrary()) {

+            if (GccProcessor.getMachine().indexOf("darwin") >= 0) {

+                return machDllLinker;

+            } else {

+                return dllLinker;

+            }

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java
new file mode 100644
index 0000000..fc7761e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/sparc_sun_solaris2/LdLinker.java
@@ -0,0 +1,60 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.gcc.cross.sparc_sun_solaris2;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+/**

+ * Adapter for the 'ld' linker

+ * 

+ * @author Curt Arnold

+ */

+public final class LdLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final LdLinker dllLinker = new LdLinker(

+            GccCCompiler.CMD_PREFIX + "ld", objFiles, discardFiles, "lib",

+            ".so", false, new LdLinker(GccCCompiler.CMD_PREFIX + "ld",

+                    objFiles, discardFiles, "lib", ".so", true, null));

+    private static final LdLinker instance = new LdLinker(

+            GccCCompiler.CMD_PREFIX + "ld", objFiles, discardFiles, "", "",

+            false, null);

+    public static LdLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private LdLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix,

+            String outputSuffix, boolean isLibtool, LdLinker libtoolLinker) {

+        super(command, "-version", extensions, ignoredExtensions, outputPrefix,

+                outputSuffix, isLibtool, libtoolLinker);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java
new file mode 100644
index 0000000..951bfc1
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/hp/aCCCompiler.java
@@ -0,0 +1,104 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.hp;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the HP aC++ C++ compiler

+ * 

+ * @author Curt Arnold

+ */

+public final class aCCCompiler extends GccCompatibleCCompiler {

+    private static final aCCCompiler instance = new aCCCompiler("aCC", false,

+            null);

+    /**

+     * Gets singleton instance of this class

+     */

+    public static aCCCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private File[] includePath;

+    /**

+     * Private constructor. Use GccCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    private aCCCompiler(String command, boolean newEnvironment, Environment env) {

+        super(command, "-help", false, null, newEnvironment, env);

+    }

+    public void addImpliedArgs(Vector args, boolean debug,

+            boolean multithreaded, boolean exceptions, LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization) {

+        args.addElement("-c");

+        if (debug) {

+            args.addElement("-g");

+        }

+        /*

+         * if (multithreaded) { args.addElement("-mt"); }

+         */

+        if (linkType.isSharedLibrary()) {

+            args.addElement("+z");

+        }

+    }

+    public void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("-w");

+                break;

+            case 1 :

+            case 2 :

+                args.addElement("+w");

+                break;

+        /*

+         * case 3: case 4: case 5: args.addElement("+w2"); break;

+         */

+        }

+    }

+    public File[] getEnvironmentIncludePath() {

+        if (includePath == null) {

+            File ccLoc = CUtil.getExecutableLocation("aCC");

+            if (ccLoc != null) {

+                File compilerIncludeDir = new File(

+                        new File(ccLoc, "../include").getAbsolutePath());

+                if (compilerIncludeDir.exists()) {

+                    includePath = new File[2];

+                    includePath[0] = compilerIncludeDir;

+                }

+            }

+            if (includePath == null) {

+                includePath = new File[1];

+            }

+            includePath[includePath.length - 1] = new File("/usr/include");

+        }

+        return includePath;

+    }

+    public Linker getLinker(LinkType linkType) {

+        return aCCLinker.getInstance().getLinker(linkType);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/hp/aCCLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/hp/aCCLinker.java
new file mode 100644
index 0000000..86b22e0
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/hp/aCCLinker.java
@@ -0,0 +1,100 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.hp;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+/**

+ * Adapter for Sun (r) Forte(tm) C++ Linker

+ * 

+ * @author Curt Arnold

+ */

+public final class aCCLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final aCCLinker arLinker = new aCCLinker("aCC", objFiles,

+            discardFiles, "", ".a");

+    private static final aCCLinker dllLinker = new aCCLinker("aCC", objFiles,

+            discardFiles, "lib", ".sl");

+    private static final aCCLinker instance = new aCCLinker("aCC", objFiles,

+            discardFiles, "", "");

+    public static aCCLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private aCCLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix, String outputSuffix) {

+        super(command, "-help", extensions, ignoredExtensions, outputPrefix,

+                outputSuffix, false, null);

+    }

+    public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {

+        if (debug) {

+            args.addElement("-g");

+        }

+        /*

+         * if(linkType.isStaticRuntime()) { args.addElement("-static"); }

+         */

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-b");

+        }

+        /*

+         * if (linkType.isStaticLibrary()) { args.addElement("-Wl,-noshared"); }

+         */

+    }

+    public void addIncremental(boolean incremental, Vector args) {

+        /*

+         * if (incremental) { args.addElement("-xidlon"); } else {

+         * args.addElement("-xidloff"); }

+         */

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            File CCloc = CUtil.getExecutableLocation("aCC");

+            if (CCloc != null) {

+                File compilerLib = new File(new File(CCloc, "../lib")

+                        .getAbsolutePath());

+                if (compilerLib.exists()) {

+                    libDirs = new File[2];

+                    libDirs[0] = compilerLib;

+                }

+            }

+            if (libDirs == null) {

+                libDirs = new File[1];

+            }

+        }

+        libDirs[libDirs.length - 1] = new File("/usr/lib");

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return arLinker;

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java
new file mode 100644
index 0000000..f181c0e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ibm/VisualAgeCCompiler.java
@@ -0,0 +1,111 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.ibm;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the IBM(r) Visual Age(tm) C++ compiler for AIX(tm)

+ * 

+ * @author Curt Arnold

+ */

+public final class VisualAgeCCompiler extends GccCompatibleCCompiler {

+    private static final VisualAgeCCompiler instance = new VisualAgeCCompiler(

+            "xlC", false, null);

+    /**

+     * Gets singleton instance of this class

+     */

+    public static VisualAgeCCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private File[] includePath;

+    /**

+     * Private constructor. Use getInstance() to get singleton instance of this

+     * class.

+     */

+    private VisualAgeCCompiler(String command, boolean newEnvironment,

+            Environment env) {

+        super(command, "-help", false, null, newEnvironment, env);

+    }

+    public void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization) {

+        args.addElement("-c");

+        if (debug) {

+            args.addElement("-g");

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-fpic");

+        }

+        if (rtti != null) {

+        	if (rtti.booleanValue()) {

+        		args.addElement("-qrtti=all");

+        	} else {

+        		args.addElement("-qnortti");

+        	}

+        }

+    }

+    public void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("-w");

+                break;

+            case 1 :

+                args.addElement("-qflag=s:s");

+                break;

+            case 2 :

+                args.addElement("-qflag=e:e");

+                break;

+            case 3 :

+                args.addElement("-qflag=w:w");

+                break;

+            case 4 :

+                args.addElement("-qflag=i:i");

+                break;

+            case 5 :

+                args.addElement("-qhalt=w:w");

+                break;

+        }

+    }

+    public Linker getLinker(LinkType linkType) {

+        return VisualAgeLinker.getInstance().getLinker(linkType);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    /**

+     * Gets identifier for the compiler.

+     * 

+     * Initial attempt at extracting version information

+     * would lock up.  Using a stock response.

+     */

+    public String getIdentifier() {

+    	return "VisualAge compiler - unidentified version";

+    }

+    

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java
new file mode 100644
index 0000000..f0a811b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ibm/VisualAgeLinker.java
@@ -0,0 +1,75 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.ibm;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;

+/**

+ * Adapter for IBM(r) Visual Age(tm) Linker for AIX(tm)

+ * 

+ * @author Curt Arnold

+ */

+public final class VisualAgeLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[]{};

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final VisualAgeLinker dllLinker = new VisualAgeLinker(

+            "makeC++SharedLib", objFiles, discardFiles, "lib", ".so");

+    private static final VisualAgeLinker instance = new VisualAgeLinker("xlC",

+            objFiles, discardFiles, "", "");

+    public static VisualAgeLinker getInstance() {

+        return instance;

+    }

+    private VisualAgeLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix, String outputSuffix) {

+        //

+        //  just guessing that -? might display something useful

+        //

+        super(command, "-?", extensions, ignoredExtensions, outputPrefix,

+                outputSuffix, false, null);

+    }

+    public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {

+        if (debug) {

+            //args.addElement("-g");

+        }

+        if (linkType.isSharedLibrary()) {

+            //args.addElement("-G");

+        }

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+    /**

+     * Gets identifier for the compiler.

+     * 

+     * Initial attempt at extracting version information

+     * would lock up.  Using a stock response.

+     */

+    public String getIdentifier() {

+    	return "VisualAge linker - unidentified version";

+    }

+    

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java
new file mode 100644
index 0000000..65402f4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux32CCompiler.java
@@ -0,0 +1,58 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Intel (r) C/C++ compiler for IA-32 Linux (r)

+ * 

+ * The Intel (r) C/C++ compiler for IA32 Linux mimics the command options for

+ * gcc compiler.

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelLinux32CCompiler extends GccCompatibleCCompiler {

+    private static final IntelLinux32CCompiler instance = new IntelLinux32CCompiler(

+            false, new IntelLinux32CCompiler(true, null, false, null), false,

+            null);

+    public static IntelLinux32CCompiler getInstance() {

+        return instance;

+    }

+    private IntelLinux32CCompiler(boolean isLibtool,

+            IntelLinux32CCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super("icc", "-V", isLibtool, libtoolCompiler, newEnvironment, env);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new IntelLinux32CCompiler(getLibtool(),

+                    (IntelLinux32CCompiler) getLibtoolCompiler(),

+                    newEnvironment, env);

+        }

+        return this;

+    }

+    public Linker getLinker(LinkType type) {

+        return IntelLinux32Linker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java
new file mode 100644
index 0000000..268f490
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux32Linker.java
@@ -0,0 +1,55 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;

+/**

+ * Adapter for the Intel (r) Linker for Linux (r) for IA-32

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelLinux32Linker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final IntelLinux32Linker dllLinker = new IntelLinux32Linker(

+            "lib", ".so", false, new IntelLinux32Linker("lib", ".so", true,

+                    null));

+    private static final IntelLinux32Linker instance = new IntelLinux32Linker(

+            "", "", false, null);

+    public static IntelLinux32Linker getInstance() {

+        return instance;

+    }

+    private IntelLinux32Linker(String outputPrefix, String outputSuffix,

+            boolean isLibtool, IntelLinux32Linker libtoolLinker) {

+        super("icc", "-V", objFiles, discardFiles, outputPrefix, outputSuffix,

+                isLibtool, libtoolLinker);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java
new file mode 100644
index 0000000..5a506e0
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux64CCompiler.java
@@ -0,0 +1,58 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Intel (r) C/C++ compiler for IA-64 Linux (r)

+ * 

+ * The Intel C/C++ compiler for IA-64 Linux mimics the command options for gcc

+ * compiler.

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelLinux64CCompiler extends GccCompatibleCCompiler {

+    private static final IntelLinux64CCompiler instance = new IntelLinux64CCompiler(

+            false, new IntelLinux64CCompiler(true, null, false, null), false,

+            null);

+    public static IntelLinux64CCompiler getInstance() {

+        return instance;

+    }

+    private IntelLinux64CCompiler(boolean isLibtool,

+            IntelLinux64CCompiler libtoolCompiler, boolean newEnvironment,

+            Environment env) {

+        super("ecc", "-V", isLibtool, libtoolCompiler, newEnvironment, env);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new IntelLinux64CCompiler(getLibtool(),

+                    (IntelLinux64CCompiler) this.getLibtoolCompiler(),

+                    newEnvironment, env);

+        }

+        return this;

+    }

+    public Linker getLinker(LinkType type) {

+        return IntelLinux64Linker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java
new file mode 100644
index 0000000..f381403
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelLinux64Linker.java
@@ -0,0 +1,55 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+import net.sf.antcontrib.cpptasks.gcc.GccLibrarian;

+/**

+ * Adapter for the Intel (r) linker for Linux for IA-64

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelLinux64Linker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[0];

+    private static final String[] libtoolObjFiles = new String[]{".fo", ".a",

+            ".lib", ".dll", ".so", ".sl"};

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib",

+            ".dll", ".so", ".sl"};

+    private static final IntelLinux64Linker dllLinker = new IntelLinux64Linker(

+            "lib", ".so", false, new IntelLinux64Linker("lib", ".so", true,

+                    null));

+    private static final IntelLinux64Linker instance = new IntelLinux64Linker(

+            "", "", false, null);

+    public static IntelLinux64Linker getInstance() {

+        return instance;

+    }

+    private IntelLinux64Linker(String outputPrefix, String outputSuffix,

+            boolean isLibtool, IntelLinux64Linker libtoolLinker) {

+        super("ecc", "-V", objFiles, discardFiles, outputPrefix, outputSuffix,

+                isLibtool, libtoolLinker);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return GccLibrarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java
new file mode 100644
index 0000000..d1b4eaf
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelProcessor.java
@@ -0,0 +1,51 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioProcessor;

+/**

+ * A add-in class for Intel (r) compilers and linkers

+ * 

+ *  

+ */

+public class IntelProcessor {

+    public static void addWarningSwitch(Vector args, int level) {

+        DevStudioProcessor.addWarningSwitch(args, level);

+    }

+    public static String getCommandFileSwitch(String cmdFile) {

+        return DevStudioProcessor.getCommandFileSwitch(cmdFile);

+    }

+    public static void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        DevStudioProcessor.getDefineSwitch(buffer, define, value);

+    }

+    public static String getIncludeDirSwitch(String includeDir) {

+        return DevStudioProcessor.getIncludeDirSwitch(includeDir);

+    }

+    public static String[] getOutputFileSwitch(String outPath) {

+        return DevStudioProcessor.getOutputFileSwitch(outPath);

+    }

+    public static void getUndefineSwitch(StringBuffer buffer, String define) {

+        DevStudioProcessor.getUndefineSwitch(buffer, define);

+    }

+    public static boolean isCaseSensitive() {

+        return false;

+    }

+    private IntelProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Aslcompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Aslcompiler.java
new file mode 100644
index 0000000..5255cb9
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Aslcompiler.java
@@ -0,0 +1,66 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineAslcompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioLinker;

+/**

+ * Adapter for Intel ASL compiler

+ *

+ */

+public final class IntelWin32Aslcompiler extends CommandLineAslcompiler{

+   private final static String[] sourceExtensions = new String[]{".asl"};

+   private final static String[] headerExtensions = new String[]{};

+   private final static String[] defaultflags = new String[]{};

+   private static final IntelWin32Aslcompiler instance = new IntelWin32Aslcompiler("iasl", 

+       sourceExtensions, headerExtensions, false);

+   

+   /**

+    * Gets gcc adapter

+    */

+   public static IntelWin32Aslcompiler getInstance() {

+       return instance;

+   }

+   

+   /**

+    * Private constructor. Use GccAssembler.getInstance() to get singleton

+    * instance of this class. 

+    */

+   private IntelWin32Aslcompiler(String command, String[] sourceExtensions,

+       String[] headerExtensions, boolean isLibtool){

+       super(command, null, sourceExtensions, headerExtensions, 

+               ".aml");

+   }

+   public void addImpliedArgs(Vector args, boolean debug,

+       Boolean defaultflag){

+       if (defaultflag != null && defaultflag.booleanValue()) {

+           for (int i = 0; i < defaultflags.length; i++) {

+               args.addElement(defaultflags[i]);

+           }

+       }

+   }

+   public int getMaximumCommandLength() {

+       return Integer.MAX_VALUE;

+   }

+   public Linker getLinker(LinkType linkType) {

+     return DevStudioLinker.getInstance().getLinker(linkType);

+   }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java
new file mode 100644
index 0000000..7aef799
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32CCompiler.java
@@ -0,0 +1,53 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleCCompiler;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Intel (r) C++ compiler for 32-bit applications

+ * 

+ * The Intel (r) C++ compiler for IA32 Windows mimics the command options for

+ * the Microsoft (r) C++ compiler.

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelWin32CCompiler extends DevStudioCompatibleCCompiler {

+    private static final IntelWin32CCompiler instance = new IntelWin32CCompiler(

+            false, null);

+    public static IntelWin32CCompiler getInstance() {

+        return instance;

+    }

+    private IntelWin32CCompiler(boolean newEnvironment, Environment env) {

+        super("icl", null, newEnvironment, env);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new IntelWin32CCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    public Linker getLinker(LinkType type) {

+        return IntelWin32Linker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java
new file mode 100644
index 0000000..e83da1c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Librarian.java
@@ -0,0 +1,38 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLibrarian;

+/**

+ * Adapter for the xilib from the Intel(r) C++ Compiler for IA-32 or IA-64

+ * systems running Microsoft (r) operating systems

+ * 

+ * @author Curt Arnold

+ */

+public class IntelWin32Librarian extends DevStudioCompatibleLibrarian {

+    private static final IntelWin32Librarian instance = new IntelWin32Librarian();

+    public static IntelWin32Librarian getInstance() {

+        return instance;

+    }

+    protected IntelWin32Librarian() {

+        super("xilib", "/bogus");

+    }

+    public Linker getLinker(LinkType type) {

+        return IntelWin32Linker.getInstance().getLinker(type);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java
new file mode 100644
index 0000000..51258e2
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin32Linker.java
@@ -0,0 +1,46 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleLinker;

+/**

+ * Adapter for the Intel (r) linker for 32-bit applications

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelWin32Linker extends DevStudioCompatibleLinker {

+    private static final IntelWin32Linker dllLinker = new IntelWin32Linker(

+            ".dll");

+    private static final IntelWin32Linker instance = new IntelWin32Linker(

+            ".exe");

+    public static IntelWin32Linker getInstance() {

+        return instance;

+    }

+    private IntelWin32Linker(String outputSuffix) {

+        super("xilink", "/bogus", outputSuffix);

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return IntelWin32Librarian.getInstance();

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java
new file mode 100644
index 0000000..9b8d2c9
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/intel/IntelWin64CCompiler.java
@@ -0,0 +1,53 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.intel;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.devstudio.DevStudioCompatibleCCompiler;

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Intel C++ compiler for Itanium(TM) Applications

+ * 

+ * @author Curt Arnold

+ */

+public final class IntelWin64CCompiler extends DevStudioCompatibleCCompiler {

+    private static final IntelWin64CCompiler instance = new IntelWin64CCompiler(

+            false, null);

+    public static IntelWin64CCompiler getInstance() {

+        return instance;

+    }

+    private IntelWin64CCompiler(boolean newEnvironment, Environment env) {

+        super("ecl", null, newEnvironment, env);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new IntelWin64CCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    public Linker getLinker(LinkType type) {

+        //

+        //   currently the Intel Win32 and Win64 linkers

+        //      are command line equivalent

+        return IntelWin32Linker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java
new file mode 100644
index 0000000..633b55e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390CCompiler.java
@@ -0,0 +1,157 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.os390;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.CompilerDef;

+import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.types.DefineArgument;

+import net.sf.antcontrib.cpptasks.types.UndefineArgument;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the IBM (R) OS/390 (tm) C++ Compiler

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public class OS390CCompiler extends CommandLineCCompiler {

+    private static final AbstractCompiler instance = new OS390CCompiler(false,

+            null);

+    public static AbstractCompiler getInstance() {

+        return instance;

+    }

+    private OS390CCompiler(boolean newEnvironment, Environment env) {

+        super("cxx", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++",

+                ".s"}, new String[]{".h", ".hpp"}, ".o", false, null,

+                newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        // Specifies that only compilations and assemblies be done.

+        //  Link-edit is not done

+        args.addElement("-c");

+        args.addElement("-W");

+        args.addElement("c,NOEXPMAC,NOSHOWINC");

+        /*

+         * if (exceptions) { args.addElement("/GX"); }

+         */

+        if (debug) {

+            args.addElement("-g");

+            args.addElement("-D");

+            args.addElement("_DEBUG");

+            /*

+             * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {

+             * args.addElement("/MTd"); } else { args.addElement("/MDd");

+             * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); }

+             */

+        } else {

+            args.addElement("-D");

+            args.addElement("NEBUG");

+            /*

+             * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {

+             * args.addElement("/MT"); } else { args.addElement("/MD");

+             * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); }

+             */

+        }

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+        OS390Processor.addWarningSwitch(args, level);

+    }

+    /**

+     * The buildDefineArguments implementation CommandLineCCompiler is not good

+     * for us because os390 defines are give by -D definex instead of

+     * /Ddefinex, 2 args not 1! since we implement this ourslefs, we do not

+     * have to implement the getDefineSwitch() and the getUndefineSwitch().

+     */

+    protected void buildDefineArguments(CompilerDef[] defs, Vector args) {

+        //

+        //   assume that we aren't inheriting defines from containing <cc>

+        //

+        UndefineArgument[] merged = defs[0].getActiveDefines();

+        for (int i = 1; i < defs.length; i++) {

+            //

+            //  if we are inheriting, merge the specific defines with the

+            //      containing defines

+            merged = DefineArgument.merge(defs[i].getActiveDefines(), merged);

+        }

+        StringBuffer buf = new StringBuffer(30);

+        for (int i = 0; i < merged.length; i++) {

+            buf.setLength(0);

+            UndefineArgument current = merged[i];

+            if (current.isDefine()) {

+                args.addElement("-D");

+                buf.append(current.getName());

+                if (current.getValue() != null

+                        && current.getValue().length() > 0) {

+                    buf.append('=');

+                    buf.append(current.getValue());

+                }

+                args.addElement(buf.toString());

+            } else {

+                args.addElement("-U");

+                args.addElement(current.getName());

+            }

+        }

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new OS390CCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    /*

+     * @see CommandLineCompiler#getDefineSwitch(StringBuffer, String, String)

+     */

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ":");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return OS390Processor.getIncludeDirSwitch(includeDir);

+    }

+    public Linker getLinker(LinkType type) {

+        return OS390Linker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    /* Only compile one file at time for now */

+    protected int getMaximumInputFilesPerCommand() {

+        return Integer.MAX_VALUE;

+    }

+    /*

+     * @see CommandLineCompiler#getUndefineSwitch(StringBuffer, String)

+     */

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390Linker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390Linker.java
new file mode 100644
index 0000000..f6653b7
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390Linker.java
@@ -0,0 +1,201 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.os390;

+import java.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the IBM (R) OS/390 (tm) Linker

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public final class OS390Linker extends CommandLineLinker {

+    private static final OS390Linker datasetLinker = new OS390Linker();

+    private static final OS390Linker dllLinker = new OS390Linker("", ".dll");

+    private static final OS390Linker instance = new OS390Linker("", "");

+    public static OS390Linker getDataSetInstance() {

+        return datasetLinker;

+    }

+    public static OS390Linker getInstance() {

+        return instance;

+    }

+    private boolean isADatasetLinker;

+    File outputFile;

+    private String outputPrefix;

+    CCTask task;

+    private OS390Linker() {

+        super("cxx", "/bogus", new String[]{".o", ".a", ".lib", ".xds"},

+                new String[]{".dll", ".x"}, ".xds", false, null);

+        this.outputPrefix = "";

+        this.isADatasetLinker = true;

+    }

+    private OS390Linker(String outputPrefix, String outputSuffix) {

+        super("cxx", "/bogus", new String[]{".o", ".a", ".lib", ".x"},

+                new String[]{".dll"}, outputSuffix, false, null);

+        this.outputPrefix = outputPrefix;

+        this.isADatasetLinker = false;

+    }

+    protected void addBase(long base, Vector args) {

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-W");

+            args.addElement("l,DLL");

+        }

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    /*

+     * @see CommandLineLinker#addLibrarySets(LibrarySet[], Vector, Vector,

+     *      Vector)

+     */

+    protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        // If yo want to link against a library sitting in a dataset and

+        // not in the HFS, you can just use the //'dataset' notation

+        // to specify it. e.g:

+        // <libset dir="." libs="//'MQM.V5R2M0.SCSQLOAD'"/>

+        //

+        // We have to have special handling here because the file is not

+        // on the normal filesystem so the task will not noramly include it

+        // as part of the link command.

+        if (libsets != null) {

+            for (int i = 0; i < libsets.length; i++) {

+                String libs[] = libsets[i].getLibs();

+                for (int j = 0; j < libs.length; j++) {

+                    if (libs[j].startsWith("//")) {

+                        endargs.addElement("-l");

+                        endargs.addElement(libs[j]);

+                    } else if (libsets[i].getDataset() != null) {

+                        String ds = libsets[i].getDataset();

+                        endargs.addElement("//'" + ds + "(" + libs[j] + ")'");

+                    }

+                }

+            }

+        }

+        return super.addLibrarySets(task, libsets, preargs, midargs, endargs);

+    }

+    protected void addMap(boolean map, Vector args) {

+    }

+    protected void addStack(int stack, Vector args) {

+    }

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    public File[] getLibraryPath() {

+        return CUtil.getPathFromEnvironment("LIB", ";");

+    }

+    

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        String[] patterns = new String[libnames.length * 3];

+        int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);

+        offset = addLibraryPatterns(libnames, buf, "", ".x", patterns, offset);

+        offset = addLibraryPatterns(libnames, buf, "", ".o", patterns, offset);

+        return patterns;

+    }

+    

+    private static int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    

+    public Linker getLinker(LinkType linkType) {

+        if (this == datasetLinker)

+            return datasetLinker;

+        if (linkType.isSharedLibrary())

+            return dllLinker;

+        return instance;

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    public String getOutputFileName(String baseName) {

+        return outputPrefix + super.getOutputFileName(baseName);

+    }

+    protected String[] getOutputFileSwitch(CCTask task, String outputFile) {

+        if (isADatasetLinker && task.getDataset() != null) {

+            String ds = task.getDataset();

+            outputFile = "//'" + ds + "(" + outputFile + ")'";

+        }

+        return getOutputFileSwitch(outputFile);

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"-o", outputFile};

+    }

+    public boolean isCaseSensitive() {

+        return OS390Processor.isCaseSensitive();

+    }

+    /*

+     * @see CommandLineLinker#link(Task, File, String[],

+     *      CommandLineLinkerConfiguration)

+     */

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        this.task = task;

+        this.outputFile = outputFile;

+        if (isADatasetLinker) {

+            int p = outputFile.getName().indexOf(".");

+            if (p >= 0) {

+                String newname = outputFile.getName().substring(0, p);

+                outputFile = new File(outputFile.getParent(), newname);

+            }

+        }

+        super.link(task, outputFile, sourceFiles, config);

+    }

+    /*

+     * @see CommandLineLinker#runCommand(Task, File, String[])

+     */

+    protected int runCommand(CCTask task, File workingDir, String[] cmdline)

+            throws BuildException {

+        int rc = super.runCommand(task, workingDir, cmdline);

+        // create the .xds file if everything was ok.

+        if (rc == 0) {

+            try {

+                outputFile.delete();

+                new FileOutputStream(outputFile).close();

+            } catch (IOException e) {

+                throw new BuildException(e.getMessage());

+            }

+        }

+        return rc;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390Processor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390Processor.java
new file mode 100644
index 0000000..2c209dd
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os390/OS390Processor.java
@@ -0,0 +1,71 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.os390;

+import java.util.Vector;

+/**

+ * A add-in class for IBM (r) OS/390 compilers and linkers

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public class OS390Processor {

+    public static void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+        /*

+         * case 0: args.addElement("/W0"); break;

+         * 

+         * case 1: args.addElement("/W1"); break;

+         * 

+         * case 2: break;

+         * 

+         * case 3: args.addElement("/W3"); break;

+         * 

+         * case 4: args.addElement("/W4"); break;

+         */

+        }

+    }

+    public static String getCommandFileSwitch(String cmdFile) {

+        StringBuffer buf = new StringBuffer("@");

+        if (cmdFile.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(cmdFile);

+            buf.append('\"');

+        } else {

+            buf.append(cmdFile);

+        }

+        return buf.toString();

+    }

+    public static String getIncludeDirSwitch(String includeDir) {

+        return "-I" + includeDir;

+    }

+    public static String[] getOutputFileSwitch(String outPath) {

+        StringBuffer buf = new StringBuffer("-o ");

+        if (outPath.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(outPath);

+            buf.append('\"');

+        } else {

+            buf.append(outPath);

+        }

+        String[] retval = new String[]{buf.toString()};

+        return retval;

+    }

+    public static boolean isCaseSensitive() {

+        return true;

+    }

+    private OS390Processor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccCompiler.java
new file mode 100644
index 0000000..f40858f
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccCompiler.java
@@ -0,0 +1,124 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.os400;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the IBM (R) OS/390 (tm) C++ Compiler

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public class IccCompiler extends CommandLineCCompiler {

+    private static final AbstractCompiler instance = new IccCompiler(false,

+            null);

+    public static AbstractCompiler getInstance() {

+        return instance;

+    }

+    private IccCompiler(boolean newEnvironment, Environment env) {

+        super("icc", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++",

+                ".s"}, new String[]{".h", ".hpp"}, ".o", false, null,

+                newEnvironment, env);

+    }

+    protected void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        // Specifies that only compilations and assemblies be done.

+        //  Link-edit is not done

+        args.addElement("-c");

+        /*

+         * if (exceptions) { args.addElement("/GX"); }

+         */

+        if (debug) {

+            args.addElement("-g");

+            /*

+             * args.addElement("-D"); args.addElement("_DEBUG"); if

+             * (multithreaded) { args.addElement("/D_MT"); if (staticLink) {

+             * args.addElement("/MTd"); } else { args.addElement("/MDd");

+             * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); }

+             */

+        } else {

+            /*

+             * args.addElement("-D"); args.addElement("NEBUG"); if

+             * (multithreaded) { args.addElement("/D_MT"); if (staticLink) {

+             * args.addElement("/MT"); } else { args.addElement("/MD");

+             * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); }

+             */

+        }

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+        IccProcessor.addWarningSwitch(args, level);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new IccCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    /*

+     * @see CommandLineCompiler#getDefineSwitch(StringBuffer, String, String)

+     */

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        buffer.append("-q");

+        buffer.append(define);

+        if (value != null && value.length() > 0) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ":");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return IccProcessor.getIncludeDirSwitch(includeDir);

+    }

+    public Linker getLinker(LinkType type) {

+        return IccLinker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    /* Only compile one file at time for now */

+    protected int getMaximumInputFilesPerCommand() {

+        return 1;

+        //return Integer.MAX_VALUE;

+    }

+    /*

+     * @see CommandLineCompiler#getUndefineSwitch(StringBuffer, String)

+     */

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        /*

+         * buffer.addElement("-q"); buf.append(define);

+         */

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccLinker.java
new file mode 100644
index 0000000..5e4e2f2
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccLinker.java
@@ -0,0 +1,202 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.os400;

+import java.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+import org.apache.tools.ant.BuildException;

+/**

+ * Adapter for the IBM (R) OS/390 (tm) Linker

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public final class IccLinker extends CommandLineLinker {

+    private static final IccLinker datasetLinker = new IccLinker();

+    private static final IccLinker dllLinker = new IccLinker("", ".dll");

+    private static final IccLinker instance = new IccLinker("", "");

+    public static IccLinker getDataSetInstance() {

+        return datasetLinker;

+    }

+    public static IccLinker getInstance() {

+        return instance;

+    }

+    private boolean isADatasetLinker;

+    File outputFile;

+    private String outputPrefix;

+    CCTask task;

+    private IccLinker() {

+        super("icc", "/bogus", new String[]{".o", ".a", ".lib", ".xds"},

+                new String[]{".dll", ".x"}, ".xds", false, null);

+        this.outputPrefix = "";

+        this.isADatasetLinker = true;

+    }

+    private IccLinker(String outputPrefix, String outputSuffix) {

+        super("icc", "/bogus", new String[]{".o", ".a", ".lib", ".x"},

+                new String[]{".dll"}, outputSuffix, false, null);

+        this.outputPrefix = outputPrefix;

+        this.isADatasetLinker = false;

+    }

+    protected void addBase(long base, Vector args) {

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-W");

+            args.addElement("l,DLL");

+        }

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    /*

+     * @see CommandLineLinker#addLibrarySets(LibrarySet[], Vector, Vector,

+     *      Vector)

+     */

+    protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        // If yo want to link against a library sitting in a dataset and

+        // not in the HFS, you can just use the //'dataset' notation

+        // to specify it. e.g:

+        // <libset dir="." libs="//'MQM.V5R2M0.SCSQLOAD'"/>

+        //

+        // We have to have special handling here because the file is not

+        // on the normal filesystem so the task will not noramly include it

+        // as part of the link command.

+        if (libsets != null) {

+            for (int i = 0; i < libsets.length; i++) {

+                String libs[] = libsets[i].getLibs();

+                for (int j = 0; j < libs.length; j++) {

+                    if (libs[j].startsWith("//")) {

+                        endargs.addElement("-l");

+                        endargs.addElement(libs[j]);

+                    } else if (libsets[i].getDataset() != null) {

+                        String ds = libsets[i].getDataset();

+                        endargs.addElement("//'" + ds + "(" + libs[j] + ")'");

+                    }

+                }

+            }

+        }

+        return super.addLibrarySets(task, libsets, preargs, midargs, endargs);

+    }

+    protected void addMap(boolean map, Vector args) {

+    }

+    protected void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    public File[] getLibraryPath() {

+        return CUtil.getPathFromEnvironment("LIB", ";");

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        String[] patterns = new String[libnames.length * 3];

+        int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);

+        offset = addLibraryPatterns(libnames, buf, "", ".x", patterns, offset);

+        offset = addLibraryPatterns(libnames, buf, "", ".o", patterns, offset);

+        return patterns;

+    }

+    

+    private static int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    

+    

+    public Linker getLinker(LinkType linkType) {

+        if (this == datasetLinker)

+            return datasetLinker;

+        if (linkType.isSharedLibrary())

+            return dllLinker;

+        return instance;

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    protected String[] getOutputFileSwitch(CCTask task, String outputFile) {

+        if (isADatasetLinker && task.getDataset() != null) {

+            String ds = task.getDataset();

+            outputFile = "//'" + ds + "(" + outputFile + ")'";

+        }

+        return getOutputFileSwitch(outputFile);

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"-o", outputFile};

+    }

+    public boolean isCaseSensitive() {

+        return IccProcessor.isCaseSensitive();

+    }

+    /*

+     * @see CommandLineLinker#link(Task, File, String[],

+     *      CommandLineLinkerConfiguration)

+     */

+    public void link(CCTask task, File outputFile, String[] sourceFiles,

+            CommandLineLinkerConfiguration config) throws BuildException {

+        this.task = task;

+        this.outputFile = outputFile;

+        if (isADatasetLinker) {

+            int p = outputFile.getName().indexOf(".");

+            if (p >= 0) {

+                String newname = outputFile.getName().substring(0, p);

+                outputFile = new File(outputFile.getParent(), newname);

+            }

+        }

+        super.link(task, outputFile, sourceFiles, config);

+    }

+    /*

+     * @see CommandLineLinker#runCommand(Task, File, String[])

+     */

+    protected int runCommand(CCTask task, File workingDir, String[] cmdline)

+            throws BuildException {

+        int rc = super.runCommand(task, workingDir, cmdline);

+        // create the .xds file if everything was ok.

+        if (rc == 0) {

+            try {

+                outputFile.delete();

+                new FileOutputStream(outputFile).close();

+            } catch (IOException e) {

+                throw new BuildException(e.getMessage());

+            }

+        }

+        return rc;

+    }

+    public String xgetOutputFileName(String baseName) {

+        return outputPrefix + super.getOutputFileName(baseName);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccProcessor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccProcessor.java
new file mode 100644
index 0000000..4cc7b36
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/os400/IccProcessor.java
@@ -0,0 +1,71 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.os400;

+import java.util.Vector;

+/**

+ * A add-in class for IBM (r) OS/390 compilers and linkers

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public class IccProcessor {

+    public static void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+        /*

+         * case 0: args.addElement("/W0"); break;

+         * 

+         * case 1: args.addElement("/W1"); break;

+         * 

+         * case 2: break;

+         * 

+         * case 3: args.addElement("/W3"); break;

+         * 

+         * case 4: args.addElement("/W4"); break;

+         */

+        }

+    }

+    public static String getCommandFileSwitch(String cmdFile) {

+        StringBuffer buf = new StringBuffer("@");

+        if (cmdFile.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(cmdFile);

+            buf.append('\"');

+        } else {

+            buf.append(cmdFile);

+        }

+        return buf.toString();

+    }

+    public static String getIncludeDirSwitch(String includeDir) {

+        return "-I" + includeDir;

+    }

+    public static String[] getOutputFileSwitch(String outPath) {

+        StringBuffer buf = new StringBuffer("-o ");

+        if (outPath.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(outPath);

+            buf.append('\"');

+        } else {

+            buf.append(outPath);

+        }

+        String[] retval = new String[]{buf.toString()};

+        return retval;

+    }

+    public static boolean isCaseSensitive() {

+        return true;

+    }

+    private IccProcessor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/AbstractParser.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/AbstractParser.java
new file mode 100644
index 0000000..6f0b79c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/AbstractParser.java
@@ -0,0 +1,67 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+import java.io.IOException;

+import java.io.Reader;

+/**

+ * An abstract base class for simple parsers

+ * 

+ * @author Curt Arnold

+ */

+public abstract class AbstractParser {

+    /**

+     * 

+     *  

+     */

+    protected AbstractParser() {

+    }

+    protected abstract void addFilename(String filename);

+    public abstract AbstractParserState getNewLineState();

+    protected void parse(Reader reader) throws IOException {

+        char[] buf = new char[4096];

+        AbstractParserState newLineState = getNewLineState();

+        AbstractParserState state = newLineState;

+        int charsRead = -1;

+        do {

+            charsRead = reader.read(buf, 0, buf.length);

+            if (state == null) {

+                for (int i = 0; i < charsRead; i++) {

+                    if (buf[i] == '\n') {

+                        state = newLineState;

+                        break;

+                    }

+                }

+            }

+            if (state != null) {

+                for (int i = 0; i < charsRead; i++) {

+                    state = state.consume(buf[i]);

+                    //

+                    //  didn't match a production, skip to a new line

+                    //

+                    if (state == null) {

+                        for (; i < charsRead; i++) {

+                            if (buf[i] == '\n') {

+                                state = newLineState;

+                                break;

+                            }

+                        }

+                    }

+                }

+            }

+        } while (charsRead >= 0);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java
new file mode 100644
index 0000000..fe66dbb
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/AbstractParserState.java
@@ -0,0 +1,41 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+/**

+ * An base class for objects that represent the state of an AbstractParser.

+ * 

+ * @author CurtArnold

+ * @see AbstractParser

+ */

+public abstract class AbstractParserState {

+    private AbstractParser parser;

+    protected AbstractParserState(AbstractParser parser) {

+        if (parser == null) {

+            throw new NullPointerException("parser");

+        }

+        this.parser = parser;

+    }

+    /**

+     * Consume a character

+     * 

+     * @return new state, may be null to ignore the rest of the line

+     */

+    public abstract AbstractParserState consume(char ch);

+    protected AbstractParser getParser() {

+        return parser;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/BranchState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/BranchState.java
new file mode 100644
index 0000000..370c7d5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/BranchState.java
@@ -0,0 +1,46 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+public class BranchState extends AbstractParserState {

+    private char[] branchChars;

+    private AbstractParserState[] branchStates;

+    private AbstractParserState noMatchState;

+    public BranchState(AbstractParser parser, char[] branchChars,

+            AbstractParserState[] branchStates, AbstractParserState noMatchState) {

+        super(parser);

+        this.branchChars = (char[]) branchChars.clone();

+        this.branchStates = (AbstractParserState[]) branchStates.clone();

+        this.noMatchState = noMatchState;

+    }

+    public AbstractParserState consume(char ch) {

+        AbstractParserState state;

+        for (int i = 0; i < branchChars.length; i++) {

+            if (ch == branchChars[i]) {

+                state = branchStates[i];

+                return state.consume(ch);

+            }

+        }

+        state = getNoMatchState();

+        if (state != null) {

+            return state.consume(ch);

+        }

+        return state;

+    }

+    protected AbstractParserState getNoMatchState() {

+        return noMatchState;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/CParser.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/CParser.java
new file mode 100644
index 0000000..07f8eba
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/CParser.java
@@ -0,0 +1,78 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+import java.io.IOException;

+import java.io.Reader;

+import java.util.Vector;

+/**

+ * A parser that extracts #include statements from a Reader.

+ * 

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public final class CParser extends AbstractParser implements Parser {

+    private final Vector includes = new Vector();

+    private AbstractParserState newLineState;

+    /**

+     * 

+     *  

+     */

+    public CParser() {

+        AbstractParserState quote = new FilenameState(this, new char[]{'"'});

+        AbstractParserState bracket = new FilenameState(this, new char[]{'>'});

+        AbstractParserState postE = new PostE(this, bracket, quote);

+        //

+        //    nclude

+        //

+        AbstractParserState e = new LetterState(this, 'e', postE, null);

+        AbstractParserState d = new LetterState(this, 'd', e, null);

+        AbstractParserState u = new LetterState(this, 'u', d, null);

+        AbstractParserState l = new LetterState(this, 'l', u, null);

+        AbstractParserState c = new LetterState(this, 'c', l, null);

+        AbstractParserState n = new LetterState(this, 'n', c, null);

+        //

+        //   mport is equivalent to nclude

+        //

+        AbstractParserState t = new LetterState(this, 't', postE, null);

+        AbstractParserState r = new LetterState(this, 'r', t, null);

+        AbstractParserState o = new LetterState(this, 'o', r, null);

+        AbstractParserState p = new LetterState(this, 'p', o, null);

+        AbstractParserState m = new LetterState(this, 'm', p, null);

+        //

+        //   switch between

+        //

+        AbstractParserState n_m = new BranchState(this, new char[]{'n', 'm'},

+                new AbstractParserState[]{n, m}, null);

+        AbstractParserState i = new WhitespaceOrLetterState(this, 'i', n_m);

+        newLineState = new LetterState(this, '#', i, null);

+    }

+    public void addFilename(String include) {

+        includes.addElement(include);

+    }

+    public String[] getIncludes() {

+        String[] retval = new String[includes.size()];

+        includes.copyInto(retval);

+        return retval;

+    }

+    public AbstractParserState getNewLineState() {

+        return newLineState;

+    }

+    public void parse(Reader reader) throws IOException {

+        includes.setSize(0);

+        super.parse(reader);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java
new file mode 100644
index 0000000..a86700f
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/CaseInsensitiveLetterState.java
@@ -0,0 +1,87 @@
+/*

+ *

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+

+/**

+ * This parser state checks consumed characters against a specific character

+ * (case insensitive).

+ *

+ * @author Curt Arnold

+ */

+public final class CaseInsensitiveLetterState

+    extends AbstractParserState {

+  /**

+   * Next state if a match is found.

+   */

+  private final AbstractParserState nextState;

+

+  /**

+   * Next state if not match is found.

+   */

+  private final AbstractParserState noMatchState;

+

+  /**

+   * Lower case version of character to match.

+   */

+  private final char lowerLetter;

+

+  /**

+   * Lower case version of character to match.

+   */

+  private final char upperLetter;

+

+  /**

+   * Constructor.

+   *

+   * @param parser

+   *            parser

+   * @param matchLetter

+   *            letter to match

+   * @param nextStateArg

+   *            next state if a match on the letter

+   * @param noMatchStateArg

+   *            state if no match on letter

+   */

+  public CaseInsensitiveLetterState(final AbstractParser parser,

+                                    final char matchLetter,

+                                    final AbstractParserState nextStateArg,

+                                    final AbstractParserState noMatchStateArg) {

+    super(parser);

+    this.lowerLetter = Character.toLowerCase(matchLetter);

+    this.upperLetter = Character.toUpperCase(matchLetter);

+    this.nextState = nextStateArg;

+    this.noMatchState = noMatchStateArg;

+  }

+

+  /**

+   * Consumes a character and returns the next state for the parser.

+   *

+   * @param ch

+   *            next character

+   * @return the configured nextState if ch is the expected character or the

+   *         configure noMatchState otherwise.

+   */

+  public AbstractParserState consume(final char ch) {

+    if (ch == lowerLetter || ch == upperLetter) {

+      return nextState;

+    }

+    if (ch == '\n') {

+      getParser().getNewLineState();

+    }

+    return noMatchState;

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/FilenameState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/FilenameState.java
new file mode 100644
index 0000000..f33940b
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/FilenameState.java
@@ -0,0 +1,41 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+public class FilenameState extends AbstractParserState {

+    private final StringBuffer buf = new StringBuffer();

+    private final char[] terminators;

+    public FilenameState(AbstractParser parser, char[] terminators) {

+        super(parser);

+        this.terminators = (char[]) terminators.clone();

+    }

+    public AbstractParserState consume(char ch) {

+        for (int i = 0; i < terminators.length; i++) {

+            if (ch == terminators[i]) {

+                getParser().addFilename(buf.toString());

+                buf.setLength(0);

+                return null;

+            }

+        }

+        if (ch == '\n') {

+            buf.setLength(0);

+            return getParser().getNewLineState();

+        } else {

+            buf.append(ch);

+        }

+        return this;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/FortranParser.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/FortranParser.java
new file mode 100644
index 0000000..261e95a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/FortranParser.java
@@ -0,0 +1,106 @@
+/*

+ *

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+

+import java.io.IOException;

+import java.io.Reader;

+import java.util.Vector;

+

+/**

+ * A parser that extracts INCLUDE statements from a Reader.

+ *

+ * @author Curt Arnold

+ */

+public final class FortranParser

+    extends AbstractParser

+    implements Parser {

+  /**

+   * List of included filenames.

+   */

+  private final Vector includes = new Vector();

+

+  /**

+   * State that starts consuming content at the beginning of a line.

+   */

+  private final AbstractParserState newLineState;

+

+  /**

+   * Default constructor.

+   *

+   */

+  public FortranParser() {

+    AbstractParserState filename = new FilenameState(this, new char[] {'\'',

+        '/'});

+    AbstractParserState apos = new WhitespaceOrLetterState(this, '\'',

+        filename);

+    AbstractParserState blank = new LetterState(this, ' ', apos, null);

+    AbstractParserState e = new CaseInsensitiveLetterState(this, 'E',

+        blank, null);

+    AbstractParserState d = new CaseInsensitiveLetterState(this, 'D', e,

+        null);

+    AbstractParserState u = new CaseInsensitiveLetterState(this, 'U', d,

+        null);

+    AbstractParserState l = new CaseInsensitiveLetterState(this, 'L', u,

+        null);

+    AbstractParserState c = new CaseInsensitiveLetterState(this, 'C', l,

+        null);

+    AbstractParserState n = new CaseInsensitiveLetterState(this, 'N', c,

+        null);

+    newLineState = new WhitespaceOrCaseInsensitiveLetterState(this, 'I', n);

+  }

+

+  /**

+   * Called by FilenameState at completion of file name production.

+   *

+   * @param include

+   *            include file name

+   */

+  public void addFilename(final String include) {

+    includes.addElement(include);

+  }

+

+  /**

+   * Gets collection of include file names encountered in parse.

+   * @return include file names

+   */

+  public String[] getIncludes() {

+    String[] retval = new String[includes.size()];

+    includes.copyInto(retval);

+    return retval;

+  }

+

+  /**

+   * Get the state for the beginning of a new line.

+   * @return start of line state

+   */

+  public AbstractParserState getNewLineState() {

+    return newLineState;

+  }

+

+  /**

+   * Collects all included files from the content of the reader.

+   *

+   * @param reader

+   *            character reader containing a FORTRAN source module

+   * @throws IOException

+   *             throw if I/O error during parse

+   */

+  public void parse(final Reader reader) throws IOException {

+    includes.setSize(0);

+    super.parse(reader);

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/LetterState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/LetterState.java
new file mode 100644
index 0000000..945ae91
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/LetterState.java
@@ -0,0 +1,80 @@
+/*

+ *

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+

+/**

+ * This parser state checks consumed characters against a specific character.

+ *

+ * @author Curt Arnold

+ */

+public final class LetterState

+    extends AbstractParserState {

+  /**

+   * Next state if a match is found.

+   */

+  private final AbstractParserState nextState;

+

+  /**

+   * Next state if not match is found.

+   */

+  private final AbstractParserState noMatchState;

+

+  /**

+   * Character to match.

+   */

+  private final char thisLetter;

+

+  /**

+   * Constructor.

+   *

+   * @param parser

+   *            parser

+   * @param matchLetter

+   *            letter to match

+   * @param nextStateArg

+   *            next state if a match on the letter

+   * @param noMatchStateArg

+   *            state if no match on letter

+   */

+  public LetterState(final AbstractParser parser,

+                     final char matchLetter,

+                     final AbstractParserState nextStateArg,

+                     final AbstractParserState noMatchStateArg) {

+    super(parser);

+    this.thisLetter = matchLetter;

+    this.nextState = nextStateArg;

+    this.noMatchState = noMatchStateArg;

+  }

+

+  /**

+   * Consumes a character and returns the next state for the parser.

+   *

+   * @param ch

+   *            next character

+   * @return the configured nextState if ch is the expected character or the

+   *         configure noMatchState otherwise.

+   */

+  public AbstractParserState consume(final char ch) {

+    if (ch == thisLetter) {

+      return nextState;

+    }

+    if (ch == '\n') {

+      getParser().getNewLineState();

+    }

+    return noMatchState;

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/Parser.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/Parser.java
new file mode 100644
index 0000000..cf759fc
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/Parser.java
@@ -0,0 +1,28 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+import java.io.IOException;

+import java.io.Reader;

+/**

+ * A parser that extracts #include statements from a Reader.

+ * 

+ * @author Curt Arnold

+ */

+public interface Parser {

+    String[] getIncludes();

+    void parse(Reader reader) throws IOException;

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/PostE.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/PostE.java
new file mode 100644
index 0000000..fe225fb
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/PostE.java
@@ -0,0 +1,41 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+public class PostE extends AbstractParserState {

+    private AbstractParserState bracket;

+    private AbstractParserState quote;

+    public PostE(CParser parser, AbstractParserState bracket,

+            AbstractParserState quote) {

+        super(parser);

+        this.bracket = bracket;

+        this.quote = quote;

+    }

+    public AbstractParserState consume(char ch) {

+        switch (ch) {

+            case ' ' :

+            case '\t' :

+                return this;

+            case '<' :

+                return bracket;

+            case '"' :

+                return quote;

+            case '\n' :

+                return getParser().getNewLineState();

+        }

+        return null;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java
new file mode 100644
index 0000000..9d42fee
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/WhitespaceOrCaseInsensitiveLetterState.java
@@ -0,0 +1,83 @@
+/*

+ *

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+

+/**

+ * This parser state checks consumed characters against a specific character

+ * (case insensitive) or whitespace.

+ *

+ * @author Curt Arnold

+ */

+public final class WhitespaceOrCaseInsensitiveLetterState

+    extends

+    AbstractParserState {

+  /**

+   * Next state if the character is found.

+   */

+  private final AbstractParserState nextState;

+

+  /**

+   * Character to match (lower case).

+   */

+  private final char lowerLetter;

+

+  /**

+   * Character to match (upper case).

+   */

+  private final char upperLetter;

+

+  /**

+   * Constructor.

+   *

+   * @param parser

+   *            parser

+   * @param matchLetter

+   *            letter to match

+   * @param nextStateArg

+   *            next state if a match on the letter

+   */

+  public WhitespaceOrCaseInsensitiveLetterState(final AbstractParser parser,

+                                                final char matchLetter,

+                                                final AbstractParserState

+                                                nextStateArg) {

+    super(parser);

+    this.lowerLetter = Character.toLowerCase(matchLetter);

+    this.upperLetter = Character.toUpperCase(matchLetter);

+    this.nextState = nextStateArg;

+  }

+

+  /**

+   * Consumes a character and returns the next state for the parser.

+   *

+   * @param ch

+   *            next character

+   * @return the configured nextState if ch is the expected character or the

+   *         configure noMatchState otherwise.

+   */

+  public AbstractParserState consume(final char ch) {

+    if (ch == lowerLetter || ch == upperLetter) {

+      return nextState;

+    }

+    if (ch == ' ' || ch == '\t') {

+      return this;

+    }

+    if (ch == '\n') {

+      getParser().getNewLineState();

+    }

+    return null;

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java
new file mode 100644
index 0000000..824abe6
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/parser/WhitespaceOrLetterState.java
@@ -0,0 +1,75 @@
+/*

+ *

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.parser;

+

+/**

+ * This parser state checks consumed characters against a specific character or

+ * whitespace.

+ *

+ * @author Curt Arnold

+ */

+public final class WhitespaceOrLetterState

+    extends AbstractParserState {

+  /**

+   * Next state if the character is found.

+   */

+  private final AbstractParserState nextState;

+

+  /**

+   * Character to match.

+   */

+  private final char thisLetter;

+

+  /**

+   * Constructor.

+   *

+   * @param parser

+   *            parser

+   * @param matchLetter

+   *            letter to match

+   * @param nextStateArg

+   *            next state if a match on the letter

+   */

+  public WhitespaceOrLetterState(final AbstractParser parser,

+                                 final char matchLetter,

+                                 final AbstractParserState nextStateArg) {

+    super(parser);

+    this.thisLetter = matchLetter;

+    this.nextState = nextStateArg;

+  }

+

+  /**

+   * Consumes a character and returns the next state for the parser.

+   *

+   * @param ch

+   *            next character @returns the configured nextState if ch is the

+   *            expected character or the configure noMatchState otherwise.

+   * @return next state

+   */

+  public AbstractParserState consume(final char ch) {

+    if (ch == thisLetter) {

+      return nextState;

+    }

+    if (ch == ' ' || ch == '\t') {

+      return this;

+    }

+    if (ch == '\n') {

+      getParser().getNewLineState();

+    }

+    return null;

+  }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java
new file mode 100644
index 0000000..6679c23
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89CCompiler.java
@@ -0,0 +1,109 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.sun;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.AbstractCompiler;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.compiler.Processor;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for the Sun C89 C++ Compiler

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public class C89CCompiler extends CommandLineCCompiler {

+    private static final AbstractCompiler instance = new C89CCompiler(false,

+            null);

+    public static AbstractCompiler getInstance() {

+        return instance;

+    }

+    private C89CCompiler(boolean newEnvironment, Environment env) {

+        super("c89", null, new String[]{".c", ".cc", ".cpp", ".cxx", ".c++"},

+                new String[]{".h", ".hpp"}, ".o", false, null, newEnvironment,

+                env);

+    }

+    protected void addImpliedArgs(

+    		final Vector args, 

+			final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        // Specifies that only compilations and assemblies be done.

+        args.addElement("-c");

+        /*

+         * if (exceptions) { args.addElement("/GX"); }

+         */

+        if (debug) {

+            args.addElement("-g");

+            args.addElement("-D_DEBUG");

+            /*

+             * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {

+             * args.addElement("/MTd"); } else { args.addElement("/MDd");

+             * args.addElement("/D_DLL"); } } else { args.addElement("/MLd"); }

+             */

+        } else {

+            args.addElement("-DNDEBUG");

+            /*

+             * if (multithreaded) { args.addElement("/D_MT"); if (staticLink) {

+             * args.addElement("/MT"); } else { args.addElement("/MD");

+             * args.addElement("/D_DLL"); } } else { args.addElement("/ML"); }

+             */

+        }

+    }

+    protected void addWarningSwitch(Vector args, int level) {

+        C89Processor.addWarningSwitch(args, level);

+    }

+    public Processor changeEnvironment(boolean newEnvironment, Environment env) {

+        if (newEnvironment || env != null) {

+            return new C89CCompiler(newEnvironment, env);

+        }

+        return this;

+    }

+    protected void getDefineSwitch(StringBuffer buf, String define, String value) {

+        C89Processor.getDefineSwitch(buf, define, value);

+    }

+    protected File[] getEnvironmentIncludePath() {

+        return CUtil.getPathFromEnvironment("INCLUDE", ":");

+    }

+    protected String getIncludeDirSwitch(String includeDir) {

+        return C89Processor.getIncludeDirSwitch(includeDir);

+    }

+    public Linker getLinker(LinkType type) {

+        return C89Linker.getInstance().getLinker(type);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    /* Only compile one file at time for now */

+    protected int getMaximumInputFilesPerCommand() {

+        return 1;

+    }

+    protected void getUndefineSwitch(StringBuffer buf, String define) {

+        C89Processor.getUndefineSwitch(buf, define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89Linker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89Linker.java
new file mode 100644
index 0000000..37b3950
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89Linker.java
@@ -0,0 +1,125 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.sun;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for the Sun C89 Linker

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public final class C89Linker extends CommandLineLinker {

+    private static final C89Linker dllLinker = new C89Linker("lib", ".so");

+    private static final C89Linker instance = new C89Linker("", "");

+    public static C89Linker getInstance() {

+        return instance;

+    }

+    private String outputPrefix;

+    private C89Linker(String outputPrefix, String outputSuffix) {

+        super("ld", "/bogus", new String[]{".o", ".a", ".lib", ".x"},

+                new String[]{}, outputSuffix, false, null);

+        this.outputPrefix = outputPrefix;

+    }

+    protected void addBase(long base, Vector args) {

+    }

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-G");

+        }

+    }

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,

+            Vector preargs, Vector midargs, Vector endargs) {

+        super.addLibrarySets(task, libsets, preargs, midargs, endargs);

+        StringBuffer buf = new StringBuffer("-l");

+        for (int i = 0; i < libsets.length; i++) {

+            LibrarySet set = libsets[i];

+            File libdir = set.getDir(null);

+            String[] libs = set.getLibs();

+            if (libdir != null) {

+                endargs.addElement("-L");

+                endargs.addElement(libdir.getAbsolutePath());

+            }

+            for (int j = 0; j < libs.length; j++) {

+                //

+                //  reset the buffer to just "-l"

+                //

+                buf.setLength(2);

+                //

+                //  add the library name

+                buf.append(libs[j]);

+                //

+                //  add the argument to the list

+                endargs.addElement(buf.toString());

+            }

+        }

+        return null;

+    }

+    protected void addMap(boolean map, Vector args) {

+    }

+    protected void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    public String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    public File[] getLibraryPath() {

+        return CUtil.getPathFromEnvironment("LIB", ";");

+    }

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return C89Processor.getLibraryPatterns(libnames, libType);

+    }

+    public Linker getLinker(LinkType linkType) {

+        if (linkType.isSharedLibrary()) {

+            return dllLinker;

+        }

+        /*

+         * if(linkType.isStaticLibrary()) { return

+         * OS390Librarian.getInstance(); }

+         */

+        return instance;

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+    public String getOutputFileName(String baseName) {

+        return outputPrefix + super.getOutputFileName(baseName);

+    }

+    public String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"-o", outputFile};

+    }

+    public boolean isCaseSensitive() {

+        return C89Processor.isCaseSensitive();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89Processor.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89Processor.java
new file mode 100644
index 0000000..c54c866
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/C89Processor.java
@@ -0,0 +1,116 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.sun;

+import java.util.Vector;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * A add-in class for Sun C89 compilers and linkers

+ * 

+ * @author Hiram Chirino (cojonudo14@hotmail.com)

+ */

+public class C89Processor {

+    private static int addLibraryPatterns(String[] libnames, StringBuffer buf,

+            String prefix, String extension, String[] patterns, int offset) {

+        for (int i = 0; i < libnames.length; i++) {

+            buf.setLength(0);

+            buf.append(prefix);

+            buf.append(libnames[i]);

+            buf.append(extension);

+            patterns[offset + i] = buf.toString();

+        }

+        return offset + libnames.length;

+    }

+    public static void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+        /*

+         * case 0: args.addElement("/W0"); break;

+         * 

+         * case 1: args.addElement("/W1"); break;

+         * 

+         * case 2: break;

+         * 

+         * case 3: args.addElement("/W3"); break;

+         * 

+         * case 4: args.addElement("/W4"); break;

+         */

+        }

+    }

+    public static String getCommandFileSwitch(String cmdFile) {

+        StringBuffer buf = new StringBuffer("@");

+        if (cmdFile.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(cmdFile);

+            buf.append('\"');

+        } else {

+            buf.append(cmdFile);

+        }

+        return buf.toString();

+    }

+    public static void getDefineSwitch(StringBuffer buf, String define,

+            String value) {

+        buf.setLength(0);

+        buf.append("-D");

+        buf.append(define);

+        if (value != null && value.length() > 0) {

+            buf.append('=');

+            buf.append(value);

+        }

+    }

+    public static String getIncludeDirSwitch(String includeDir) {

+        return "-I" + includeDir;

+    }

+    public static String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        StringBuffer buf = new StringBuffer();

+        int patternCount = libnames.length*2;

+        if (libType != null) {

+        	patternCount = libnames.length;

+        }

+        String[] patterns = new String[patternCount];

+        int offset = 0;

+        if (libType == null || "static".equals(libType.getValue())) {

+        	offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);

+        }

+        if (libType == null || !"static".equals(libType.getValue())) {

+        	offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,

+                offset);

+        }

+        return patterns;

+    }

+    public static String[] getOutputFileSwitch(String outPath) {

+        StringBuffer buf = new StringBuffer("-o ");

+        if (outPath.indexOf(' ') >= 0) {

+            buf.append('\"');

+            buf.append(outPath);

+            buf.append('\"');

+        } else {

+            buf.append(outPath);

+        }

+        String[] retval = new String[]{buf.toString()};

+        return retval;

+    }

+    public static void getUndefineSwitch(StringBuffer buf, String define) {

+        buf.setLength(0);

+        buf.append("-U");

+        buf.append(define);

+    }

+    public static boolean isCaseSensitive() {

+        return true;

+    }

+    private C89Processor() {

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java
new file mode 100644
index 0000000..a35d01a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/ForteCCCompiler.java
@@ -0,0 +1,119 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.sun;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+/**

+ * Adapter for the Sun (r) Forte (tm) C++ compiler

+ * 

+ * @author Curt Arnold

+ */

+public final class ForteCCCompiler extends GccCompatibleCCompiler {

+    private static final ForteCCCompiler instance = new ForteCCCompiler("CC");

+    /**

+     * Gets singleton instance of this class

+     */

+    public static ForteCCCompiler getInstance() {

+        return instance;

+    }

+    private String identifier;

+    private File[] includePath;

+    /**

+     * Private constructor. Use ForteCCCompiler.getInstance() to get singleton

+     * instance of this class.

+     */

+    private ForteCCCompiler(String command) {

+        super(command, "-V", false, null, false, null);

+    }

+    public void addImpliedArgs(final Vector args, 

+    		final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization) {

+        args.addElement("-c");

+        if (debug) {

+            args.addElement("-g");

+        }

+    	if (optimization != null) {

+    		if (optimization.isSpeed()) {

+    			args.addElement("-xO2");

+    		}

+    	}

+    	if (rtti != null) {

+    		if (rtti.booleanValue()) {

+    			args.addElement("-features=rtti");

+    		} else {

+    			args.addElement("-features=no%rtti");

+    		}

+    	}

+        if (multithreaded) {

+            args.addElement("-mt");

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-KPIC");

+        }

+        

+    }

+    public void addWarningSwitch(Vector args, int level) {

+        switch (level) {

+            case 0 :

+                args.addElement("-w");

+                break;

+            case 1 :

+            case 2 :

+                args.addElement("+w");

+                break;

+            case 3 :

+            case 4 :

+            case 5 :

+                args.addElement("+w2");

+                break;

+        }

+    }

+    public File[] getEnvironmentIncludePath() {

+        if (includePath == null) {

+            File ccLoc = CUtil.getExecutableLocation("CC");

+            if (ccLoc != null) {

+                File compilerIncludeDir = new File(

+                        new File(ccLoc, "../include").getAbsolutePath());

+                if (compilerIncludeDir.exists()) {

+                    includePath = new File[2];

+                    includePath[0] = compilerIncludeDir;

+                }

+            }

+            if (includePath == null) {

+                includePath = new File[1];

+            }

+            includePath[includePath.length - 1] = new File("/usr/include");

+        }

+        return includePath;

+    }

+    public Linker getLinker(LinkType linkType) {

+        return ForteCCLinker.getInstance().getLinker(linkType);

+    }

+    public int getMaximumCommandLength() {

+        return Integer.MAX_VALUE;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java
new file mode 100644
index 0000000..c39071a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/sun/ForteCCLinker.java
@@ -0,0 +1,100 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.sun;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;

+/**

+ * Adapter for Sun (r) Forte(tm) C++ Linker

+ * 

+ * @author Curt Arnold

+ */

+public final class ForteCCLinker extends AbstractLdLinker {

+    private static final String[] discardFiles = new String[]{".dll", ".so",

+    ".sl"};

+    private static final String[] objFiles = new String[]{".o", ".a", ".lib"};

+    private static final ForteCCLinker arLinker = new ForteCCLinker("CC",

+            objFiles, discardFiles, "lib", ".a");

+    private static final ForteCCLinker dllLinker = new ForteCCLinker("CC",

+            objFiles, discardFiles, "lib", ".so");

+    private static final ForteCCLinker instance = new ForteCCLinker("CC",

+            objFiles, discardFiles, "", "");

+    public static ForteCCLinker getInstance() {

+        return instance;

+    }

+    private File[] libDirs;

+    private ForteCCLinker(String command, String[] extensions,

+            String[] ignoredExtensions, String outputPrefix, String outputSuffix) {

+        super(command, "-V", extensions, ignoredExtensions, outputPrefix,

+                outputSuffix, false, null);

+    }

+    public void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {

+        if (debug) {

+            args.addElement("-g");

+        }

+        if (linkType.isStaticRuntime()) {

+            args.addElement("-static");

+        }

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-G");

+        }

+        if (linkType.isStaticLibrary()) {

+            args.addElement("-xar");

+        }

+    }

+    public void addIncremental(boolean incremental, Vector args) {

+        /*

+         * if (incremental) { args.addElement("-xidlon"); } else {

+         * args.addElement("-xidloff"); }

+         */

+    }

+    /**

+     * Returns library path.

+     *  

+     */

+    public File[] getLibraryPath() {

+        if (libDirs == null) {

+            File CCloc = CUtil.getExecutableLocation("CC");

+            if (CCloc != null) {

+                File compilerLib = new File(new File(CCloc, "../lib")

+                        .getAbsolutePath());

+                if (compilerLib.exists()) {

+                    libDirs = new File[2];

+                    libDirs[0] = compilerLib;

+                }

+            }

+            if (libDirs == null) {

+                libDirs = new File[1];

+            }

+        }

+        libDirs[libDirs.length - 1] = new File("/usr/lib");

+        return libDirs;

+    }

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            return arLinker;

+        }

+        if (type.isSharedLibrary()) {

+            return dllLinker;

+        }

+        return instance;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java
new file mode 100644
index 0000000..d08b9fb
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxCCompiler.java
@@ -0,0 +1,192 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.ti;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.compiler.CommandLineCCompiler;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.OptimizationEnum;

+

+

+import org.apache.tools.ant.types.Environment;

+/**

+ * Adapter for TI DSP compilers with cl** commands

+ * 

+ * @author CurtA

+ */

+public class ClxxCCompiler extends CommandLineCCompiler {

+    /**

+     * Header file extensions

+     */

+    private static final String[] headerExtensions = new String[]{".h", ".hpp",

+            ".inl"};

+    /**

+     * Source file extensions

+     */

+    private static final String[] sourceExtensions = new String[]{".c", ".cc",

+            ".cpp", ".cxx", ".c++"};

+    /**

+     * Singleton for TMS320C55x

+     */

+    private static final ClxxCCompiler cl55 = new ClxxCCompiler("cl55", false,

+            null);

+    /**

+     * Singleton for TMS320C6000

+     */

+    private static final ClxxCCompiler cl6x = new ClxxCCompiler("cl6x", false,

+            null);

+    public static ClxxCCompiler getCl55Instance() {

+        return cl55;

+    }

+    public static ClxxCCompiler getCl6xInstance() {

+        return cl6x;

+    }

+    /**

+     * Private constructor

+     * 

+     * @param command

+     *            executable name

+     * @param newEnvironment

+     *            Change environment

+     * @param env

+     *            New environment

+     */

+    private ClxxCCompiler(String command, boolean newEnvironment,

+            Environment env) {

+        super(command, "-h", sourceExtensions, headerExtensions, ".o", false,

+                null, newEnvironment, env);

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addImpliedArgs(java.util.Vector,

+     *      boolean, boolean, boolean,

+     *      net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    protected void addImpliedArgs(

+    		final Vector args, 

+			final boolean debug,

+            final boolean multithreaded, 

+			final boolean exceptions, 

+			final LinkType linkType,

+			final Boolean rtti,

+			final OptimizationEnum optimization,

+   final Boolean defaultflag) {

+        if (debug) {

+            args.addElement("-gw");

+        }

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#addWarningSwitch(java.util.Vector,

+     *      int)

+     */

+    protected void addWarningSwitch(Vector args, int warnings) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getDefineSwitch(java.lang.StringBuffer,

+     *      java.lang.String, java.lang.String)

+     */

+    protected void getDefineSwitch(StringBuffer buffer, String define,

+            String value) {

+        buffer.append("-d");

+        buffer.append(define);

+        if (value != null) {

+            buffer.append('=');

+            buffer.append(value);

+        }

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getEnvironmentIncludePath()

+     */

+    protected File[] getEnvironmentIncludePath() {

+        File[] c_dir = CUtil.getPathFromEnvironment("C_DIR", ";");

+        File[] cx_dir = CUtil.getPathFromEnvironment("C6X_C_DIR", ";");

+        if (c_dir.length == 0) {

+            return cx_dir;

+        }

+        if (cx_dir.length == 0) {

+            return c_dir;

+        }

+        File[] combo = new File[c_dir.length + cx_dir.length];

+        for (int i = 0; i < cx_dir.length; i++) {

+            combo[i] = cx_dir[i];

+        }

+        for (int i = 0; i < c_dir.length; i++) {

+            combo[i + cx_dir.length] = c_dir[i];

+        }

+        return combo;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getIncludeDirSwitch(java.lang.String)

+     */

+    protected String getIncludeDirSwitch(String source) {

+        return "-I" + source;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    public Linker getLinker(LinkType type) {

+        if (type.isStaticLibrary()) {

+            if (this == cl6x) {

+                return ClxxLibrarian.getCl6xInstance();

+            }

+            return ClxxLibrarian.getCl55Instance();

+        }

+        if (type.isSharedLibrary()) {

+            if (this == cl6x) {

+                return ClxxLinker.getCl6xDllInstance();

+            }

+            return ClxxLinker.getCl55DllInstance();

+        }

+        if (this == cl6x) {

+            return ClxxLinker.getCl6xInstance();

+        }

+        return ClxxLinker.getCl55Instance();

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getMaximumCommandLength()

+     */

+    public int getMaximumCommandLength() {

+        return 1024;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineCompiler#getUndefineSwitch(java.lang.StringBuffer,

+     *      java.lang.String)

+     */

+    protected void getUndefineSwitch(StringBuffer buffer, String define) {

+        buffer.append("-u");

+        buffer.append(define);

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java
new file mode 100644
index 0000000..082d1a4
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxLibrarian.java
@@ -0,0 +1,162 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.ti;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * 

+ * Adapter for TI DSP librarian

+ *  *

+ * @author CurtA

+ */

+public class ClxxLibrarian extends CommandLineLinker {

+    private static final ClxxLibrarian cl55Instance = new ClxxLibrarian("ar55");

+    private static final ClxxLibrarian cl6xInstance = new ClxxLibrarian("ar6x");

+    public static final ClxxLibrarian getCl55Instance() {

+        return cl55Instance;

+    }

+    public static final ClxxLibrarian getCl6xInstance() {

+        return cl6xInstance;

+    }

+    private ClxxLibrarian(String command) {

+        super(command, null, new String[]{".o"}, new String[0], ".lib", false,

+                null);

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long,

+     *      java.util.Vector)

+     */

+    protected void addBase(long base, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean,

+     *      java.util.Vector)

+     */

+    protected void addFixed(Boolean fixed, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean,

+     *      net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)

+     */

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean,

+     *      java.util.Vector)

+     */

+    protected void addIncremental(boolean incremental, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean,

+     *      java.util.Vector)

+     */

+    protected void addMap(boolean map, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int,

+     *      java.util.Vector)

+     */

+    protected void addStack(int stack, Vector args) {

+        // TODO Auto-generated method stub

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)

+     */

+    protected String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()

+     */

+    public File[] getLibraryPath() {

+        return new File[0];

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])

+     */

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+        return new String[0];

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    public Linker getLinker(LinkType linkType) {

+        return null;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()

+     */

+    protected int getMaximumCommandLength() {

+        return 1024;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)

+     */

+    protected String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"-o", outputFile};

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()

+     */

+    public boolean isCaseSensitive() {

+        // TODO Auto-generated method stub

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java
new file mode 100644
index 0000000..43ee7c0
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ti/ClxxLinker.java
@@ -0,0 +1,181 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.ti;

+import java.io.File;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;

+import net.sf.antcontrib.cpptasks.compiler.LinkType;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;

+

+/**

+ * Adapter for TI DSP linkers

+ *  *

+ * @author CurtA

+ *  

+ */

+public class ClxxLinker extends CommandLineLinker {

+    private static final ClxxLinker cl55DllInstance = new ClxxLinker("lnk55",

+            ".dll");

+    private static final ClxxLinker cl55Instance = new ClxxLinker("lnk55",

+            ".exe");

+    private static final ClxxLinker cl6xDllInstance = new ClxxLinker("lnk6x",

+            ".dll");

+    private static final ClxxLinker cl6xInstance = new ClxxLinker("lnk6x",

+            ".exe");

+    public static ClxxLinker getCl55DllInstance() {

+        return cl55DllInstance;

+    }

+    public static ClxxLinker getCl55Instance() {

+        return cl55Instance;

+    }

+    public static ClxxLinker getCl6xDllInstance() {

+        return cl6xDllInstance;

+    }

+    public static ClxxLinker getCl6xInstance() {

+        return cl6xInstance;

+    }

+    private ClxxLinker(String command, String outputSuffix) {

+        super(command, "-h", new String[]{".o", ".lib", ".res"}, new String[]{

+                ".map", ".pdb", ".lnk"}, outputSuffix, false, null);

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addBase(long,

+     *      java.util.Vector)

+     */

+    protected void addBase(long base, Vector args) {

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addFixed(java.lang.Boolean,

+     *      java.util.Vector)

+     */

+    protected void addFixed(Boolean fixed, Vector args) {

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addImpliedArgs(boolean,

+     *      net.sf.antcontrib.cpptasks.compiler.LinkType, java.util.Vector)

+     */

+    protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {

+        if (linkType.isSharedLibrary()) {

+            args.addElement("-abs");

+        }

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addIncremental(boolean,

+     *      java.util.Vector)

+     */

+    protected void addIncremental(boolean incremental, Vector args) {

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addMap(boolean,

+     *      java.util.Vector)

+     */

+    protected void addMap(boolean map, Vector args) {

+        if (map) {

+            args.addElement("-m");

+        }

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addStack(int,

+     *      java.util.Vector)

+     */

+    protected void addStack(int stack, Vector args) {

+    }

+    /* (non-Javadoc)

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)

+     */

+    protected void addEntry(String entry, Vector args) {

+    }

+    

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getCommandFileSwitch(java.lang.String)

+     */

+    protected String getCommandFileSwitch(String commandFile) {

+        return "@" + commandFile;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPath()

+     */

+    public File[] getLibraryPath() {

+        return new File[0];

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#getLibraryPatterns(java.lang.String[])

+     */

+    public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {

+    	//

+    	//  TODO: Looks bogus, should be .a or .so's not .o's

+    	//

+    	String[] libpats = new String[libnames.length];

+        for (int i = 0; i < libnames.length; i++) {

+            libpats[i] = libnames[i] + ".o";

+        }

+        return libpats;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Processor#getLinker(net.sf.antcontrib.cpptasks.compiler.LinkType)

+     */

+    public Linker getLinker(LinkType linkType) {

+        return this;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getMaximumCommandLength()

+     */

+    protected int getMaximumCommandLength() {

+        return 1024;

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#getOutputFileSwitch(java.lang.String)

+     */

+    protected String[] getOutputFileSwitch(String outputFile) {

+        return new String[]{"-o", outputFile};

+    }

+    /*

+     * (non-Javadoc)

+     * 

+     * @see net.sf.antcontrib.cpptasks.compiler.Linker#isCaseSensitive()

+     */

+    public boolean isCaseSensitive() {

+        // TODO Auto-generated method stub

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/AslcompilerArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/AslcompilerArgument.java
new file mode 100644
index 0000000..87babcf
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/AslcompilerArgument.java
@@ -0,0 +1,30 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+

+/**

+ * A aslcompiler command line argument.

+ */

+public class AslcompilerArgument extends CommandLineArgument {

+    public AslcompilerArgument () {

+    }

+

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                        "Not an actual task, but looks like one for documentation purposes");

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/AssemblerArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/AssemblerArgument.java
new file mode 100644
index 0000000..1b5f54d
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/AssemblerArgument.java
@@ -0,0 +1,30 @@
+/*

+ * 

+ * Copyright 2001-2005 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+

+/**

+ * A assembler command line argument.

+ */

+public class AssemblerArgument extends CommandLineArgument {

+    public AssemblerArgument () {

+    }

+

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                        "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java
new file mode 100644
index 0000000..91ab2f6
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/CommandLineArgument.java
@@ -0,0 +1,122 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+

+import org.apache.tools.ant.types.EnumeratedAttribute;

+import java.io.File;

+/**

+ * An compiler/linker command line flag.

+ */

+public class CommandLineArgument {

+    /**

+     * Enumerated attribute with the values "start", "mid" and "end",

+     */

+    public static class LocationEnum extends EnumeratedAttribute {

+        public String[] getValues() {

+            return new String[]{"start", "mid", "end"};

+        }

+    }

+    private String ifCond;

+    private int location;

+    private String unlessCond;

+    private String value;

+    private File file;

+    public CommandLineArgument() {

+    }

+    public int getLocation() {

+        return location;

+    }

+    public String getValue() {

+        return value;

+    }

+    public File getFile() {

+      return file;

+    }

+    /**

+     * Returns true if the define's if and unless conditions (if any) are

+     * satisfied.

+     */

+    public boolean isActive(org.apache.tools.ant.Project p) {

+        if (value == null) {

+            return false;

+        }

+        if (ifCond != null && p.getProperty(ifCond) == null) {

+            return false;

+        } else if (unlessCond != null && p.getProperty(unlessCond) != null) {

+            return false;

+        }

+        return true;

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The argument will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     */

+    public void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Specifies relative location of argument on command line. "start" will

+     * place argument at start of command line, "mid" will place argument after

+     * all "start" arguments but before filenames, "end" will place argument

+     * after filenames.

+     *  

+     */

+    public void setLocation(LocationEnum location) {

+        this.location = location.getIndex();

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the argument will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessCond = propName;

+    }

+    /**

+     * Specifies the string that should appear on the command line. The

+     * argument will be quoted if it contains embedded blanks. Use multiple

+     * arguments to avoid quoting.

+     *  

+     */

+    public void setValue(String value) {

+        this.value = value;

+    }

+    /**

+     * Specifies the file which lists many strings that should appear on 

+     * the command line. Each line is one argument. The argument will be 

+     * quated if it contains embedded blanks. Use multiple arguments in 

+     * file to avoid quating. 

+     * 

+     * @param file

+     *          name of the file

+     */

+    public void setFile(File file) {

+        this.file = file;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/CompilerArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/CompilerArgument.java
new file mode 100644
index 0000000..ca9e90e
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/CompilerArgument.java
@@ -0,0 +1,28 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+/**

+ * A compiler command line argument.

+ */

+public class CompilerArgument extends CommandLineArgument {

+    public CompilerArgument() {

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java
new file mode 100644
index 0000000..af2d141
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/ConditionalFileSet.java
@@ -0,0 +1,84 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import net.sf.antcontrib.cpptasks.CUtil;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.types.AbstractFileSet;

+import org.apache.tools.ant.types.FileSet;

+/**

+ * An Ant FileSet object augmented with if and unless conditions.

+ * 

+ * @author Curt Arnold

+ */

+public class ConditionalFileSet extends FileSet {

+    private String ifCond;

+    private String unlessCond;

+    public ConditionalFileSet() {

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /**

+     * overrides FileSet's implementation which would throw an exception since

+     * the referenced object isn't this type.

+     */

+    protected AbstractFileSet getRef(Project p) {

+        return (AbstractFileSet) getRefid().getReferencedObject(p);

+    }

+    /**

+     * Returns true if the Path's if and unless conditions (if any) are

+     * satisfied.

+     */

+    public boolean isActive() throws BuildException {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException(

+                    "setProject() should have been called");

+        }

+        return CUtil.isActive(p, ifCond, unlessCond);

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The fileset will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     */

+    public void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the fileset will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessCond = propName;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/ConditionalPath.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/ConditionalPath.java
new file mode 100644
index 0000000..dc21189
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/ConditionalPath.java
@@ -0,0 +1,92 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.types.Path;

+/**

+ * An Ant Path object augmented with if and unless conditionals

+ * 

+ * @author Curt Arnold

+ */

+public class ConditionalPath extends Path {

+    private String ifCond;

+    private String unlessCond;

+    private File file;

+    public ConditionalPath(Project project) {

+        super(project);

+    }

+    public ConditionalPath(Project p, String path) {

+        super(p, path);

+    }

+    public File getFile() {

+      return file;

+    }

+    /**

+     * Returns true if the Path's if and unless conditions (if any) are

+     * satisfied.

+     */

+    public boolean isActive(org.apache.tools.ant.Project p)

+            throws BuildException {

+        return CUtil.isActive(p, ifCond, unlessCond);

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The path will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     * 

+     * @param propName

+     *            property name

+     */

+    public void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the path will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessCond = propName;

+    }

+    /**

+     * Specifies the file which lists many include paths that should appear on 

+     * the command line. Each line is an include path. The includepath will be 

+     * quated if it contains embedded blanks. 

+     * 

+     * @param file

+     *          name of the file

+     */

+    public void setFile(File file) {

+        this.file = file;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/DefineArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/DefineArgument.java
new file mode 100644
index 0000000..824e939
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/DefineArgument.java
@@ -0,0 +1,38 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+/**

+ * Preprocessor macro definition.

+ * 

+ * @author Mark A Russell <a

+ *         href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com

+ *         </a>

+ */

+public class DefineArgument extends UndefineArgument {

+    private String value;

+    public DefineArgument() {

+        super(true);

+    }

+    /** Returns the value of the define */

+    public final String getValue() {

+        return value;

+    }

+    /** Set the value attribute */

+    public final void setValue(String value) {

+        this.value = value;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/DefineSet.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/DefineSet.java
new file mode 100644
index 0000000..9d229fb
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/DefineSet.java
@@ -0,0 +1,199 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.DataType;

+import org.apache.tools.ant.types.Reference;

+/**

+ * Set of preprocessor macro defines and undefines.

+ * 

+ * @author Mark A Russell <a

+ *         href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com

+ *         </a>

+ * @author Adam Murdoch

+ */

+public class DefineSet extends DataType {

+    private Vector defineList = new Vector();

+    private String ifCond = null;

+    private String unlessCond = null;

+    /**

+     * 

+     * Adds a define element.

+     * 

+     * @throws BuildException

+     *             if reference

+     */

+    public void addDefine(DefineArgument arg) throws BuildException {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        defineList.addElement(arg);

+    }

+    /** Adds defines/undefines. */

+    private void addDefines(String[] defs, boolean isDefine) {

+        for (int i = 0; i < defs.length; i++) {

+            UndefineArgument def;

+            if (isDefine) {

+                def = new DefineArgument();

+            } else {

+                def = new UndefineArgument();

+            }

+            def.setName(defs[i]);

+            defineList.addElement(def);

+        }

+    }

+    /**

+     * 

+     * Adds an undefine element.

+     * 

+     * @throws BuildException

+     *             if reference

+     */

+    public void addUndefine(UndefineArgument arg) throws BuildException {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        defineList.addElement(arg);

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /** Returns the defines and undefines in this set. */

+    public UndefineArgument[] getDefines() throws BuildException {

+        if (isReference()) {

+            DefineSet defset = (DefineSet) getCheckedRef(DefineSet.class,

+                    "DefineSet");

+            return defset.getDefines();

+        } else {

+            if (isActive()) {

+                UndefineArgument[] defs = new UndefineArgument[defineList

+                        .size()];

+                defineList.copyInto(defs);

+                return defs;

+            } else {

+                return new UndefineArgument[0];

+            }

+        }

+    }

+    /**

+     * Returns true if the define's if and unless conditions (if any) are

+     * satisfied.

+     * 

+     * @exception BuildException

+     *                throws build exception if name is not set

+     */

+    public final boolean isActive() throws BuildException {

+        return CUtil.isActive(getProject(), ifCond, unlessCond);

+    }

+    /**

+     * A comma-separated list of preprocessor macros to define. Use nested

+     * define elements to define macro values.

+     * 

+     * @param defList

+     *            comma-separated list of preprocessor macros

+     * @throws BuildException

+     *             throw if defineset is a reference

+     */

+    public void setDefine(CUtil.StringArrayBuilder defList)

+            throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        addDefines(defList.getValue(), true);

+    }

+    /**

+     * Sets a description of the current data type.

+     */

+    public void setDescription(String desc) {

+        super.setDescription(desc);

+    }

+    /**

+     * Sets an id that can be used to reference this element.

+     * 

+     * @param id

+     *            id

+     */

+    public void setId(String id) {

+        //

+        //  this is actually accomplished by a different

+        //     mechanism, but we can document it

+        //

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The define will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     * 

+     * @param propName

+     *            property name

+     */

+    public final void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Specifies that this element should behave as if the content of the

+     * element with the matching id attribute was inserted at this location. If

+     * specified, no other attributes or child content should be specified,

+     * other than "description".

+     *  

+     */

+    public void setRefid(Reference r) throws BuildException {

+        if (!defineList.isEmpty()) {

+            throw tooManyAttributes();

+        }

+        super.setRefid(r);

+    }

+    /**

+     * A comma-separated list of preprocessor macros to undefine.

+     * 

+     * @param undefList

+     *            comma-separated list of preprocessor macros

+     * @throws BuildException

+     *             throw if defineset is a reference

+     */

+    public void setUndefine(CUtil.StringArrayBuilder undefList)

+            throws BuildException {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        addDefines(undefList.getValue(), false);

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the define will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public final void setUnless(String propName) {

+        unlessCond = propName;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/FlexLong.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/FlexLong.java
new file mode 100644
index 0000000..d95959f
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/FlexLong.java
@@ -0,0 +1,59 @@
+/*

+ * 

+ * Copyright 2002-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import java.lang.reflect.Method;

+

+/**

+ * Helper class which can be used for Ant task attribute setter methods to

+ * allow the build file to specify a long in either decimal, octal, or

+ * hexadecimal format.

+ *  // FlexInteger author

+ * @author Erik Hatcher

+ * @see org.apache.tools.ant.types.FlexInteger

+ */

+public class FlexLong {

+    private Long value;

+    /**

+     * Constructor used by Ant's introspection mechanism for attribute

+     * population

+     */

+    public FlexLong(String value) {

+        // Java 1.1 did not support Long.decode().. so we call it by

+        // reflection.

+        try {

+            Method m = Long.class

+                    .getMethod("decode", new Class[]{String.class});

+            Object rc = m.invoke(null, new Object[]{value});

+            this.value = (Long) rc;

+        } catch (Exception e) {

+            // Try it the old fashioned way, we must be on a 1.1 jre

+            this.value = new Long(value);

+        }

+    }

+    /**

+     * Returns the decimal integer value

+     */

+    public long longValue() {

+        return value.longValue();

+    }

+    /**

+     * Overridden method to return the decimal value for display

+     */

+    public String toString() {

+        return value.toString();

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/IncludePath.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/IncludePath.java
new file mode 100644
index 0000000..edcc421
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/IncludePath.java
@@ -0,0 +1,38 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import org.apache.tools.ant.Project;

+/**

+ * An include path.

+ * 

+ * Works like other paths in Ant with with the addition of "if" and "unless"

+ * conditions.

+ * 

+ * @author Curt Arnold

+ */

+public class IncludePath extends ConditionalPath {

+    public IncludePath(Project project) {

+        super(project);

+    }

+    public IncludePath(Project p, String path) {

+        super(p, path);

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LibrarySet.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LibrarySet.java
new file mode 100644
index 0000000..d522ccc
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LibrarySet.java
@@ -0,0 +1,290 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import java.io.File;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.FileVisitor;

+import net.sf.antcontrib.cpptasks.compiler.Linker;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.DirectoryScanner;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.ProjectComponent;

+import org.apache.tools.ant.types.FileSet;

+import org.apache.tools.ant.types.PatternSet;

+/**

+ * A set of library names. Libraries can also be added to a link by specifying

+ * them in a fileset.

+ * 

+ * For most Unix-like compilers, libset will result in a series of -l and -L

+ * linker arguments. For Windows compilers, the library names will be used to

+ * locate the appropriate library files which will be added to the linkers

+ * input file list as if they had been specified in a fileset.

+ * 

+ * @author Mark A Russell <a

+ *         href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com

+ *         </a>

+ * @author Adam Murdoch

+ * @author Curt Arnold

+ */

+public class LibrarySet extends ProjectComponent {

+    private String dataset;

+    private boolean explicitCaseSensitive;

+    private String ifCond;

+    private String[] libnames;

+    private final FileSet set = new FileSet();

+    private String unlessCond;

+    private LibraryTypeEnum libraryType;

+    public LibrarySet() {

+        libnames = new String[0];

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /**

+     * Gets the dataset. Used on OS390 if the libs are in a dataset.

+     * 

+     * @return Returns a String

+     */

+    public String getDataset() {

+        return dataset;

+    }

+    public File getDir(Project project) {

+        return set.getDir(project);

+    }

+    protected FileSet getFileSet() {

+        return set;

+    }

+    public String[] getLibs() {

+        String[] retval = (String[]) libnames.clone();

+        return retval;

+    }

+    

+    /**

+     * Gets preferred library type

+     * 

+     * @return library type, may be null.

+     */

+    public LibraryTypeEnum getType() {

+    	return libraryType;

+    }

+    /**

+     * Returns true if the define's if and unless conditions (if any) are

+     * satisfied.

+     */

+    public boolean isActive(org.apache.tools.ant.Project p) {

+        if (p == null) {

+            throw new NullPointerException("p");

+        }

+        if (ifCond != null) {

+            String ifValue = p.getProperty(ifCond);

+            if (ifValue != null) {

+                if (ifValue.equals("no") || ifValue.equals("false")) {

+                    throw new BuildException(

+                            "property "

+                                    + ifCond

+                                    + " used as if condition has value "

+                                    + ifValue

+                                    + " which suggests a misunderstanding of if attributes");

+                }

+            } else {

+                return false;

+            }

+        }

+        if (unlessCond != null) {

+            String unlessValue = p.getProperty(unlessCond);

+            if (unlessValue != null) {

+                if (unlessValue.equals("no") || unlessValue.equals("false")) {

+                    throw new BuildException(

+                            "property "

+                                    + unlessCond

+                                    + " used as unless condition has value "

+                                    + unlessValue

+                                    + " which suggests a misunderstanding of unless attributes");

+                }

+                return false;

+            }

+        }

+        if (libnames.length == 0) {

+            p.log("libnames not specified or empty.", Project.MSG_WARN);

+            return false;

+        }

+        return true;

+    }

+    /**

+     * Sets case sensitivity of the file system. If not set, will default to

+     * the linker's case sensitivity.

+     * 

+     * @param isCaseSensitive

+     *            "true"|"on"|"yes" if file system is case sensitive,

+     *            "false"|"off"|"no" when not.

+     */

+    public void setCaseSensitive(boolean isCaseSensitive) {

+        explicitCaseSensitive = true;

+        set.setCaseSensitive(isCaseSensitive);

+    }

+    /**

+     * Sets the dataset. Used on OS390 if the libs are in a dataset.

+     * 

+     * @param dataset

+     *            The dataset to set

+     */

+    public void setDataset(String dataset) {

+        this.dataset = dataset;

+    }

+    /**

+     * Library directory.

+     * 

+     * @param dir

+     *            library directory

+     *  

+     */

+    public void setDir(File dir) throws BuildException {

+        set.setDir(dir);

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The library set will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     * 

+     * @param propName

+     *            property name

+     */

+    public void setIf(String propName) {

+        ifCond = propName;

+    }

+    /**

+     * Comma-separated list of library names without leading prefixes, such as

+     * "lib", or extensions, such as ".so" or ".a".

+     *  

+     */

+    public void setLibs(CUtil.StringArrayBuilder libs) throws BuildException {

+        libnames = libs.getValue();

+        // If this is not active.. then it's ok if the lib names are invalid.

+        // so we can do a: <libset if="x.lib" dir="." libs="${x.lib}"/>

+        if (!isActive(getProject()))

+            return;

+        for (int i = 0; i < libnames.length; i++) {

+            int lastDot = libnames[i].lastIndexOf('.');

+            if (lastDot >= 0) {

+                String extension = libnames[i].substring(lastDot);

+                if (extension.equalsIgnoreCase(".lib")

+                        || extension.equalsIgnoreCase(".so")

+                        || extension.equalsIgnoreCase(".a")) {

+                    getProject().log(

+                            "Suspicious library name ending with \""

+                                    + extension + "\": " + libnames[i], Project.MSG_DEBUG );

+                }

+            }

+            if (libnames[i].length() >= 3

+                    && libnames[i].substring(0, 3).equalsIgnoreCase("lib")) {

+                getProject().log(

+                        "Suspicious library name starting with \"lib\": "

+                                + libnames[i], Project.MSG_DEBUG);

+            }

+        }

+    }

+    public void setProject(Project project) {

+        set.setProject(project);

+        super.setProject(project);

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the library set will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public void setUnless(String propName) {

+        unlessCond = propName;

+    }

+    

+    /**

+     * Sets the preferred library type. Supported values "shared", "static", and

+     * "framework".  "framework" is equivalent to "shared" on non-Darwin platforms. 

+     */

+    public void setType(LibraryTypeEnum type) {

+    	this.libraryType = type;

+    }

+    

+    public void visitLibraries(Project project, Linker linker, File[] libpath,

+            FileVisitor visitor) throws BuildException {

+        FileSet localSet = (FileSet) set.clone();

+        //

+        //   unless explicitly set

+        //      will default to the linker case sensitivity

+        //

+        if (!explicitCaseSensitive) {

+            boolean linkerCaseSensitive = linker.isCaseSensitive();

+            localSet.setCaseSensitive(linkerCaseSensitive);

+        }

+        //

+        //  if there was a libs attribute then

+        //     add the corresponding patterns to the FileSet

+        //

+        if (libnames != null && libnames.length > 0) {

+            String[] patterns = linker.getLibraryPatterns(libnames, libraryType);

+            //

+            //  if no patterns, then linker does not support libraries

+            //

+            if (patterns.length > 0) {

+		        for (int i = 0; i < patterns.length; i++) {

+		             PatternSet.NameEntry entry = localSet.createInclude();

+		             entry.setName(patterns[i]);

+		        }

+		        //

+		        //  if there was no specified directory then

+		        //     run through the libpath backwards

+		        //

+		        if (localSet.getDir(project) == null) {

+		            //

+		            //  scan libpath in reverse order

+		            //     to give earlier entries priority

+		            //

+		            for (int j = libpath.length - 1; j >= 0; j--) {

+		                FileSet clone = (FileSet) localSet.clone();

+		                clone.setDir(libpath[j]);

+		                DirectoryScanner scanner = clone.getDirectoryScanner(project);

+		                File basedir = scanner.getBasedir();

+		                String[] files = scanner.getIncludedFiles();

+		                for (int k = 0; k < files.length; k++) {

+		                    visitor.visit(basedir, files[k]);

+		                }

+		            }

+		        } else {

+		            DirectoryScanner scanner = localSet.getDirectoryScanner(project);

+		            File basedir = scanner.getBasedir();

+		            String[] files = scanner.getIncludedFiles();

+		            for (int k = 0; k < files.length; k++) {

+		                visitor.visit(basedir, files[k]);

+		            }

+		        }

+        	}

+        }

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java
new file mode 100644
index 0000000..82d7947
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LibraryTypeEnum.java
@@ -0,0 +1,48 @@
+/*

+ * 

+ * Copyright 2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import org.apache.tools.ant.types.EnumeratedAttribute;

+/**

+ * Enumeration of library types for LibrarySet

+ * 

+ * @author Curt Arnold

+ *  

+ */

+public class LibraryTypeEnum extends EnumeratedAttribute {

+    /**

+     * Constructor

+     * 

+     * Set by default to "shared"

+     * 

+     * @see java.lang.Object#Object()

+     */

+    public LibraryTypeEnum() {

+        setValue("shared");

+    }

+    /**

+     * Gets list of acceptable values

+     * 

+     * @see org.apache.tools.ant.types.EnumeratedAttribute#getValues()

+     */

+    public String[] getValues() {

+        return new String[]{"shared", // prefer shared libraries

+                "static", // prefer static libraries

+                "framework" // framework libraries (Mac OS/X)

+				            //  equiv to shared on other platforms

+        };

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LinkerArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LinkerArgument.java
new file mode 100644
index 0000000..89bff18
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/LinkerArgument.java
@@ -0,0 +1,28 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+/**

+ * A linker command line argument.

+ */

+public class LinkerArgument extends CommandLineArgument {

+    public LinkerArgument() {

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java
new file mode 100644
index 0000000..be0dbd5
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/SystemIncludePath.java
@@ -0,0 +1,45 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import org.apache.tools.ant.Project;

+/**

+ * A system include path.

+ * 

+ * Files located using a system include path will not participate in dependency

+ * analysis.

+ * 

+ * Standard include paths for a compiler should not be specified since these

+ * should be determined from environment variables or configuration files by

+ * the compiler adapter.

+ * 

+ * Works like other paths in Ant with with the addition of "if" and "unless"

+ * conditions.

+ * 

+ * @author Curt Arnold

+ */

+public class SystemIncludePath extends ConditionalPath {

+    public SystemIncludePath(Project project) {

+        super(project);

+    }

+    public SystemIncludePath(Project p, String path) {

+        super(p, path);

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java
new file mode 100644
index 0000000..02d08c8
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/SystemLibrarySet.java
@@ -0,0 +1,37 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+/**

+ * A set of system library names. Timestamp or location of system libraries are

+ * not considered in dependency analysis.

+ * 

+ * Libraries can also be added to a link by specifying them in a fileset.

+ * 

+ * For most Unix-like compilers, syslibset will result in a series of -l and -L

+ * linker arguments. For Windows compilers, the library names will be used to

+ * locate the appropriate library files which will be added to the linkers

+ * input file list as if they had been specified in a fileset.

+ */

+public class SystemLibrarySet extends LibrarySet {

+    public SystemLibrarySet() {

+        super();

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/UndefineArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/UndefineArgument.java
new file mode 100644
index 0000000..2a18fca
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/types/UndefineArgument.java
@@ -0,0 +1,153 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.types;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CUtil;

+

+import org.apache.tools.ant.BuildException;

+/**

+ * Preprocessor macro undefinition.

+ * 

+ * @author Mark A Russell <a

+ *         href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com

+ *         </a>

+ */

+public class UndefineArgument {

+    /**

+     * This method returns an array of UndefineArgument and DefineArgument's by

+     * merging a base list with an override list.

+     * 

+     * Any define in the base list with a name that appears in the override

+     * list is suppressed. All entries in the override list are preserved

+     *  

+     */

+    public static UndefineArgument[] merge(UndefineArgument[] base,

+            UndefineArgument[] override) {

+        if (base.length == 0) {

+            UndefineArgument[] overrideClone = (UndefineArgument[]) override

+                    .clone();

+            return overrideClone;

+        }

+        if (override.length == 0) {

+            UndefineArgument[] baseClone = (UndefineArgument[]) base.clone();

+            return baseClone;

+        }

+        Vector unduplicated = new Vector(base.length);

+        for (int i = 0; i < base.length; i++) {

+            UndefineArgument current = base[i];

+            String currentName = current.getName();

+            boolean match = false;

+            if (currentName == null) {

+                match = true;

+            } else {

+                for (int j = 0; j < override.length; j++) {

+                    UndefineArgument over = override[j];

+                    String overName = over.getName();

+                    if (overName != null && overName.equals(currentName)) {

+                        match = true;

+                        break;

+                    }

+                }

+            }

+            if (!match) {

+                unduplicated.addElement(current);

+            }

+        }

+        UndefineArgument[] combined = new UndefineArgument[unduplicated.size()

+                + override.length];

+        unduplicated.copyInto(combined);

+        int offset = unduplicated.size();

+        for (int i = 0; i < override.length; i++) {

+            combined[offset + i] = override[i];

+        }

+        return combined;

+    }

+    private boolean define = false;

+    private String ifCond;

+    private String name;

+    private String unlessCond;

+    public UndefineArgument() {

+    }

+    protected UndefineArgument(boolean isDefine) {

+        this.define = isDefine;

+    }

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+    /** Returns the name of the define */

+    public final String getName() {

+        return name;

+    }

+    /** Returns the value of the define */

+    public String getValue() {

+        return null;

+    }

+    /**

+     * Returns true if the define's if and unless conditions (if any) are

+     * satisfied.

+     * 

+     * @exception BuildException

+     *                throws build exception if name is not set

+     */

+    public final boolean isActive(org.apache.tools.ant.Project p)

+            throws BuildException {

+        if (name == null) {

+            throw new BuildException("<define> is missing name attribute");

+        }

+        return CUtil.isActive(p, ifCond, unlessCond);

+    }

+    /** Returns true if this is a define, false if an undefine. */

+    public final boolean isDefine() {

+        return define;

+    }

+    /**

+     * Sets the property name for the 'if' condition.

+     * 

+     * The define will be ignored unless the property is defined.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") will throw an exception when

+     * evaluated.

+     * 

+     * @param propName

+     *            property name

+     */

+    public final void setIf(String propName) {

+        ifCond = propName;

+    }

+    /** Set the name attribute */

+    public final void setName(String name) {

+        this.name = name;

+    }

+    /**

+     * Set the property name for the 'unless' condition.

+     * 

+     * If named property is set, the define will be ignored.

+     * 

+     * The value of the property is insignificant, but values that would imply

+     * misinterpretation ("false", "no") of the behavior will throw an

+     * exception when evaluated.

+     * 

+     * @param propName

+     *            name of property

+     */

+    public final void setUnless(String propName) {

+        unlessCond = propName;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/CommandLineUserDefine.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/CommandLineUserDefine.java
new file mode 100644
index 0000000..7c66eb1
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/CommandLineUserDefine.java
@@ -0,0 +1,389 @@
+package net.sf.antcontrib.cpptasks.userdefine;

+

+import java.io.File;

+import java.util.Iterator;

+import java.util.StringTokenizer;

+import java.util.Vector;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import net.sf.antcontrib.cpptasks.CUtil;

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.DirectoryScanner;

+import org.apache.tools.ant.Project;

+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+public class CommandLineUserDefine {

+

+    String command;

+    

+    /*

+     * The follows variable set at child class.

+     */

+    String includeFileFlag = null;

+    String entryPointFlag = null;

+    String subSystemFlag = null;

+    String mapFlag = null;

+    String pdbFlag = null;

+    String outputFileFlag = null;

+    String includePathDelimiter = null;

+    

+    /*

+     * get lib string if Vendor = "gcc", it should respectively aadd "-(" and ")-" 

+     * at library set before and end. This value set at userDefineCompiler class.

+     */

+    Vector<String> libSetList = new Vector<String>();

+    Vector<String> fileList = new Vector<String>();

+    public void command(CCTask cctask, UserDefineDef userdefine){

+        File workdir;

+        File outdir;

+        Project project = cctask.getProject();

+        if(userdefine.getWorkdir() == null) {

+            workdir = new File(".");

+        }

+        else {

+            workdir = userdefine.getWorkdir();

+        } 

+        

+        /*

+         * generate cmdline= command + args + includepath + endargs + outfile

+         */ 

+        Vector args = new Vector();

+        Vector argsWithoutSpace = new Vector();

+        Vector endargs = new Vector();

+        Vector endargsWithoutSpace = new Vector();

+        Vector includePath = new Vector();

+        

+        /*

+         * Generate cmdline = command        + 

+         *                    general args   + 

+         *                    outputflag     + outputfile

+         *                    subsystemFlag  + subsystemValue  +

+         *                    includeFlag    + includeFile     +

+         *                    includeFileincludpath            + 

+         *                    entryPointFlag + entryPointValue +

+         *                    mapFlag        + mapValue        +

+         *                    pdbFlag        + pdbValue        +

+         *                    endargs                          + 

+         *                   

+         * 

+         */

+        /*

+         * get Args.

+         */

+        CommandLineArgument[] argument = userdefine.getActiveProcessorArgs();

+        for (int j = 0; j < argument.length; j++) {

+            if (argument[j].getLocation() == 0) {

+                args.addElement(argument[j].getValue());

+            } else {

+                endargs.addElement(argument[j].getValue());

+            }

+        }

+        /*

+         * get include path.

+         */

+        String[] incPath = userdefine.getActiveIncludePaths();

+        for (int j = 0; j < incPath.length; j++) {

+            if(incPath[j].indexOf(' ') >= 0) {

+                includePath.addElement( includePathDelimiter + incPath[j]);

+                //includePath.addElement( includePathDelimiter + "\"" + incPath[j] + "\"");

+            }

+            else {

+                includePath.addElement( includePathDelimiter + incPath[j]);

+            }

+        }

+        /*

+         * Remove space in args and endargs.

+         */

+        for ( int i=0; i < args.size(); i++) {

+            String str = (String)args.get(i);

+            StringTokenizer st = new StringTokenizer(str);

+            while(st.hasMoreTokens()) {

+                argsWithoutSpace.addElement(st.nextToken());

+            }

+        }

+        for ( int i=0; i < endargs.size(); i++) {

+            String str = (String)endargs.get(i);

+            StringTokenizer st = new StringTokenizer(str);

+            while(st.hasMoreTokens()) {

+                endargsWithoutSpace.addElement(st.nextToken());

+            }

+        }

+        

+        int cmdLen = 0;

+        if(userdefine.getOutdir() == null) {

+            outdir = new File(".");

+            /*

+             * command + args + endargs + includepath + sourcefile

+             */

+            cmdLen = 1 + argsWithoutSpace.size() + endargsWithoutSpace.size() + includePath.size() + 1;

+        }

+        else {

+            outdir = userdefine.getOutdir();

+            /*

+             * command + args + endargs + includepath + sourcefile + outfile

+             */

+            cmdLen = 1 + argsWithoutSpace.size() + endargsWithoutSpace.size() + includePath.size() + 2;

+        }

+        if (includeFileFlag != null && includeFileFlag.trim().length() > 0){

+            cmdLen++;

+        }

+        if (entryPointFlag != null && entryPointFlag.trim().length() > 0){

+            cmdLen++;

+        }

+        if (subSystemFlag != null && subSystemFlag.trim().length() > 0){

+            cmdLen++;

+        }

+        if (mapFlag != null && mapFlag.trim().length() > 0){

+            cmdLen++;

+        }

+        if (pdbFlag != null && pdbFlag.trim().length() > 0){

+            cmdLen++;

+        }

+        if (libSetList != null && libSetList.size() > 0){

+            cmdLen = cmdLen + libSetList.size();

+        }

+        if (fileList != null){

+            cmdLen = cmdLen + fileList.size();

+        }

+        /*

+         * In gcc the "cr" flag should follow space then add outputfile name, otherwise

+         * it will pop error. 

+         */

+        if (outputFileFlag != null && outputFileFlag.trim().length() > 0){

+            if (outputFileFlag.trim().equalsIgnoreCase("-cr")){

+                cmdLen = cmdLen + 2;

+            }else {

+                cmdLen++;

+            }

+            

+        }

+        /*

+         *  for every source file

+         *  if file is header file, just skip it (add later)

+         */

+        Vector srcSets = userdefine.getSrcSets();

+        if (srcSets.size() == 0) {

+            String[] cmd = new String[cmdLen - 1];

+            int index = 0;

+            cmd[index++] = this.command;

+            

+           

+            

+            Iterator iter = argsWithoutSpace.iterator();

+            while (iter.hasNext()) {

+                cmd[index++] = project.replaceProperties((String)iter.next());

+                //cmd[index++] = (String)iter.next();

+            }

+            

+            iter = endargsWithoutSpace.iterator();

+            while (iter.hasNext()) {

+                cmd[index++] = (String)iter.next();

+            }

+            

+            /*

+             * "OutputFlag + outputFile" as first option follow command.exe.

+             */

+            if (outputFileFlag != null && outputFileFlag.trim().length() > 0){

+                if (outputFileFlag.trim().equalsIgnoreCase("-cr")){

+                    cmd[index++] = outputFileFlag;

+                    cmd[index++] = userdefine.getOutputFile();

+                }else {

+                    cmd[index++] =  outputFileFlag + userdefine.getOutputFile();

+                }

+            }

+            

+            /*

+             * Add fileList to cmd 

+             */

+            if (fileList != null && fileList.size()> 0){

+                for (int i = 0; i < fileList.size(); i++){

+                    cmd[index++] = fileList.get(i);

+                }

+            }

+            

+            if (subSystemFlag != null && subSystemFlag.trim().length() > 0){

+                cmd[index++] = subSystemFlag + userdefine.getSubSystemvalue();

+            }

+            if (includeFileFlag != null && includeFileFlag.trim().length() > 0){

+                cmd[index++] = includeFileFlag + userdefine.getIncludeFile();

+            }

+         

+            iter = includePath.iterator();

+            while (iter.hasNext()) {

+                cmd[index++] = (String)iter.next();

+            }

+            

+            if (entryPointFlag != null && entryPointFlag.trim().length() > 0){

+                //

+                // If GCC link use __ModuleEntrypoint instead of _ModuleEntryPoint;

+                //

+                if (entryPointFlag.equalsIgnoreCase("-e")){

+                    cmd[index++] = entryPointFlag + "_" + userdefine.getEntryPointvalue();

+                } else {

+                    cmd[index++] = entryPointFlag + userdefine.getEntryPointvalue();

+                }

+                

+            }

+            if (mapFlag != null && mapFlag.trim().length() > 0){

+                cmd[index++] = mapFlag + userdefine.getMapvalue();

+            }

+            if (pdbFlag != null && pdbFlag.trim().length() > 0){

+                cmd[index++] = pdbFlag + userdefine.getPdbvalue();

+            }

+

+            if (userdefine.getOutdir() != null){

+                // will add code to generate outfile name and flag

+                cmd[index++] = "/nologo";

+            }

+            

+            if (libSetList != null && libSetList.size() > 0){

+                for (int i = 0; i < libSetList.size(); i++){

+                    cmd[index++] = libSetList.get(i);

+                }

+            }

+

+            // execute the command

+            int retval = runCommand(cctask, workdir, cmd);

+            // if with monitor, add more code

+            if (retval != 0) {

+               throw new BuildException(this.command

+                       + " failed with return code " + retval,

+                       cctask.getLocation());

+            }

+        }

+        

+        //

+        // if have source file append source file in command land.

+        //

+        for (int i = 0; i < srcSets.size(); i++) {

+            ConditionalFileSet srcSet = (ConditionalFileSet) srcSets

+                    .elementAt(i);

+            if (srcSet.isActive()) {

+                // Find matching source files

+                DirectoryScanner scanner = srcSet.getDirectoryScanner(project);

+                // Check each source file - see if it needs compilation

+                String[] fileNames = scanner.getIncludedFiles();

+                for (int j = 0; j < fileNames.length; j++){

+                    String[] cmd = new String[cmdLen];

+                    int index = 0;

+                    cmd[index++] = this.command;

+                    

+                    

+                    

+                    Iterator iter = argsWithoutSpace.iterator();

+                    while (iter.hasNext()) {

+                        cmd[index++] = (String)iter.next();

+                    }

+                    

+                    iter = endargsWithoutSpace.iterator();

+                    while (iter.hasNext()) {

+                        cmd[index++] = (String)iter.next();

+                    }

+                    

+                    /*

+                     * Add outputFileFlag and output file to cmd

+                     */

+                    if (outputFileFlag != null && outputFileFlag.length()> 0){

+                        if (outputFileFlag.trim().equalsIgnoreCase("-cr")){

+                            cmd[index++] = outputFileFlag;

+                            cmd[index++] = userdefine.getOutputFile();

+                        }else {

+                            cmd[index++] =  outputFileFlag + userdefine.getOutputFile();

+                        }

+                    }

+                    

+                    /*

+                     * Add fileList to cmd 

+                     */

+                    if (fileList != null && fileList.size()> 0){

+                        for (int s = 0; s < fileList.size(); s++){

+                            cmd[index++] = fileList.get(s);

+                        }

+                    }

+                    if (subSystemFlag != null && subSystemFlag.length()> 0){

+                        cmd[index++] = subSystemFlag + userdefine.getSubSystemvalue();

+                    }

+                    if (includeFileFlag != null && includeFileFlag.length()> 0){

+                        cmd[index++] = includeFileFlag + userdefine.getIncludeFile();

+                    }

+                    

+                    iter = includePath.iterator();

+                    while (iter.hasNext()) {

+                        cmd[index++] = (String)iter.next();

+                    }

+                    if (userdefine.getOutdir() != null){

+                        // will add code to generate outfile name and flag

+                        cmd[index++] = "/nologo";

+                    }

+                    

+                    if (entryPointFlag != null && entryPointFlag.length()> 0){

+                        cmd[index++] = entryPointFlag + userdefine.getEntryPointvalue();

+                    }

+                    if (mapFlag != null && mapFlag.length() > 0){

+                        cmd[index++] = mapFlag + userdefine.getMapvalue();

+                    }

+                    if (pdbFlag != null && pdbFlag.length() > 0){

+                        cmd[index++] = pdbFlag + userdefine.getPdbvalue();

+                    }

+                    

+                    if (libSetList != null && libSetList.size() > 0){

+                        for (int k = 0; k < libSetList.size(); k++){

+                            cmd[index++] = libSetList.get(k);

+                        }

+                    }

+                    

+                    // execute the command

+                    cmd[index++] = scanner.getBasedir() + "/" + fileNames[j];

+                    for (int k = 0; k < cmd.length; k++){

+                    }

+                    int retval = runCommand(cctask, workdir, cmd);

+                    // if with monitor, add more code

+                    if (retval != 0) {

+                       throw new BuildException(this.command

+                               + " failed with return code " + retval,

+                               cctask.getLocation());

+                    }

+                }

+            }

+        }

+    }

+    

+    protected int runCommand(CCTask task, File workingDir, String[] cmdline)

+                    throws BuildException {

+        return CUtil.runCommand(task, workingDir, cmdline, false, null);

+

+    }

+

+    protected String getInputFileArgument(File outputDir, String filename,

+                    int index) {

+        //

+        // if there is an embedded space,

+        // must enclose in quotes

+        if (filename.indexOf(' ') >= 0) {

+            StringBuffer buf = new StringBuffer("\"");

+            buf.append(filename);

+            buf.append("\"");

+            return buf.toString();

+        }

+        return filename;

+    }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineArgument.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineArgument.java
new file mode 100644
index 0000000..85d9a04
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineArgument.java
@@ -0,0 +1,31 @@
+/*

+ * 

+ * Copyright 2002-2006 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.userdefine;

+

+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;

+

+public class UserDefineArgument extends CommandLineArgument {

+    

+    public UserDefineArgument() {

+    }

+    

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                "Not an actual task, but looks like one for documentation purposes");

+    }

+

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineCompiler.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineCompiler.java
new file mode 100644
index 0000000..382975a
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineCompiler.java
@@ -0,0 +1,219 @@
+/*

+ * 

+ * Copyright 2002-2006 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.userdefine;

+

+import org.apache.tools.ant.Project;

+

+import net.sf.antcontrib.cpptasks.CCTask;

+import org.tianocore.build.toolchain.*;

+

+public class UserDefineCompiler extends CommandLineUserDefine {

+

+    public UserDefineCompiler(CCTask cctask, UserDefineDef userdefineDef) {

+        String arch = null;

+        String os = null;

+        String vendor = null;

+        String commandType = null;

+        Project project = cctask.getProject();

+        // get command string

+        if (cctask.getArch() == null) {

+            arch = project.getProperty("ARCH");

+            if (arch == null) {

+                arch = System.getProperty("os.arch");

+            }

+        } else {

+            arch = cctask.getArch();

+        }

+        arch = arch.toUpperCase();

+        if (cctask.getOs() == null) {

+            os = project.getProperty("OS");

+            if (os == null) {

+                os = System.getProperty("os.name");

+            }

+        } else {

+            os = cctask.getOs();

+        }

+

+        commandType = userdefineDef.getType();

+

+        if (commandType != null) {

+            if (ToolChainFactory.getValue(arch + "_" + commandType + "_VENDOR") != null

+                    && ToolChainFactory.getValue(

+                            arch + "_" + commandType + "_VENDOR").trim()

+                            .length() > 0) {

+                vendor = ToolChainFactory.getValue(arch + "_" + commandType

+                        + "_VENDOR");

+            } else if (ToolChainFactory.getValue(arch + "_VENDOR") != null) {

+                vendor = ToolChainFactory.getValue(arch + "_VENDOR");

+            }

+        }

+

+        // look if ARCH_VENDOR_OS_COMMANDTYPE is existed

+        if (arch != null && vendor != null && os != null && commandType != null) {

+            command = project.getProperty(arch + "_" + vendor + "_" + os + "_"

+                    + commandType);

+        }

+        // look if ARCH_VENDOR_COMMANDTYPE is existed

+        if (command == null) {

+            if (arch != null && vendor != null && commandType != null) {

+                command = project.getProperty(arch + "_" + vendor + "_"

+                        + commandType);

+            }

+        }

+        // look if ARCH_COMMANDTYPE is existed

+        if (command == null) {

+            if (arch != null && commandType != null) {

+                command = project.getProperty(arch + "_" + commandType);

+            }

+        }

+        // look if COMMANDTYPE is existed

+        if (command == null) {

+            if (commandType != null) {

+                command = project.getProperty(commandType);

+            }

+        }

+        // using the default value from VENDOR_OS_COMMANDTYPE or

+        // VENDOR_COMMANDTYPE

+        if (command == null) {

+            if (vendor != null && os != null && commandType != null) {

+                String str = vendor + "_" + os + "_" + commandType;

+                command = UserDefineMapping.getDefaultCommand(str);

+            }

+        }

+        // VENDOR_COMMANDTYPE

+        if (command == null) {

+            if (vendor != null && commandType != null) {

+                String str = vendor + "_" + commandType;

+                command = UserDefineMapping.getDefaultCommand(str);

+            }

+        }

+        // just give the name whatever

+        if (command == null) {

+            command = "cl";

+        }

+

+        // initialize the includePathDelimiter

+        if (userdefineDef.getIncludepathDelimiter() != null) {

+            includePathDelimiter = userdefineDef.getIncludepathDelimiter();

+        }

+        // else find VENDOR

+        else {

+            if (vendor != null) {

+                includePathDelimiter = UserDefineMapping

+                        .getIncludePathDelimiter(vendor, commandType);

+            }

+        }

+        if (includePathDelimiter == null) {

+            includePathDelimiter = "-I";

+        }

+        /*

+         * Set libSet.

+         */

+        if (userdefineDef.getLibSet() != null

+                && userdefineDef.getLibSet().size() > 0) {

+            String[] libList;

+            if (vendor.equalsIgnoreCase("GCC")) {

+                libSetList.add("-(");

+                for (int i = 0; i < userdefineDef.getLibSet().size(); i++) {

+                    libList = userdefineDef.getLibSet().get(i).getLibs();

+                    for (int j = 0; j < libList.length; j++) {

+                        libSetList.add(libList[j]);

+                    }

+                }

+                libSetList.add("-)");

+            } else {

+                for (int i = 0; i < userdefineDef.getLibSet().size(); i++) {

+                    libList = userdefineDef.getLibSet().get(i).getLibs();

+                    for (int j = 0; j < libList.length; j++) {

+                        libSetList.add(libList[j]);

+                    }

+                }

+            }

+        }

+        /*

+         * set includeFileFlag

+         */

+        if (userdefineDef.getIncludeFile() != null) {

+            if (userdefineDef.getIncludeFileFlag() != null) {

+                includeFileFlag = userdefineDef.getIncludeFileFlag();

+            } else {

+                includeFileFlag = UserDefineMapping.getCompellingIncFileFlag(

+                        vendor, commandType);

+            }

+        }

+        /*

+         * set entryPointFlag

+         */

+        if (userdefineDef.getEntryPointvalue() != null) {

+            if (userdefineDef.getEntryPointFlag() != null) {

+                entryPointFlag = userdefineDef.getEntryPointFlag();

+            } else {

+                entryPointFlag = UserDefineMapping.getEntryPointFlag(vendor,

+                        commandType);

+            }

+        }

+        /*

+         * set subSystemFlag

+         */

+        if (userdefineDef.getSubSystemvalue() != null) {

+            if (userdefineDef.getSubSystemFlag() != null) {

+                subSystemFlag = userdefineDef.getSubSystemFlag();

+            } else {

+                subSystemFlag = UserDefineMapping.getSubSystemFlag(vendor,

+                        commandType);

+            }

+        }

+        /*

+         * set mapFlag

+         */

+        if (userdefineDef.getMapvalue() != null) {

+            if (userdefineDef.getMapFlag() != null) {

+                mapFlag = userdefineDef.getMapFlag();

+            } else {

+                mapFlag = UserDefineMapping.getMapFlag(vendor, commandType);

+            }

+        }

+        /*

+         * set pdbFlag

+         */

+        if (userdefineDef.getPdbvalue() != null) {

+            if (userdefineDef.getPdbFlag() != null) {

+                pdbFlag = userdefineDef.getPdbFlag();

+            } else {

+                pdbFlag = UserDefineMapping.getPdbFlag(vendor, commandType);

+            }

+        }

+        /*

+         * set outputFileFlag

+         */

+        if (userdefineDef.getOutputFile() != null) {

+            if (userdefineDef.getOutPutFlag() != null) {

+                outputFileFlag = userdefineDef.getOutPutFlag();

+            } else {

+                outputFileFlag = UserDefineMapping.getOutputFileFlag(vendor,

+                        arch, commandType);

+            }

+        }

+

+        /*

+         * set fileList

+         */

+        if (userdefineDef.getFileList() != null) {

+            fileList = userdefineDef.getFileList();

+        }

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineDef.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineDef.java
new file mode 100644
index 0000000..f17edcf
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineDef.java
@@ -0,0 +1,497 @@
+/*

+ * 

+ * Copyright 2002-2006 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.userdefine;

+

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.util.Vector;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.types.FileList;

+import org.apache.tools.ant.types.FileSet;

+

+import sun.nio.cs.ext.TIS_620;

+

+import net.sf.antcontrib.cpptasks.ProcessorDef;

+import net.sf.antcontrib.cpptasks.types.AslcompilerArgument;

+import net.sf.antcontrib.cpptasks.types.ConditionalPath;

+import net.sf.antcontrib.cpptasks.types.IncludePath;

+import net.sf.antcontrib.cpptasks.types.LibrarySet;

+

+public class UserDefineDef extends ProcessorDef{

+    

+    public UserDefineDef () {}

+    

+    private String type = "CC";

+    private String includepathDelimiter;

+    

+    private File outdir;

+    private File workdir;

+

+    private String inputSuffix;

+    private String outputSuffix;

+    

+    private Vector<IncludePath> includePaths= new Vector<IncludePath>();

+    private Vector<FileList> fileSetList = new Vector<FileList>();

+    

+    /**

+     * New adding for support GCC toolchain.

+     * Most of those only have one value for example :

+     * entryPoint, mapFile, pdbFile, define those as element because 

+     * if attribut too much the command line is not good-lookinng.

+     */

+    

+    private Vector<UserDefineElement> includeFiles = new Vector<UserDefineElement>();

+    private Vector<UserDefineElement> outPutFiles = new Vector<UserDefineElement>();

+    private Vector<UserDefineElement> subSystem = new Vector<UserDefineElement>();

+    private Vector<UserDefineElement> entryPoint = new Vector<UserDefineElement>();

+    private Vector<UserDefineElement> map = new Vector<UserDefineElement>();

+    private Vector<UserDefineElement> pdb = new Vector<UserDefineElement>();

+    private Vector<LibrarySet> libSet = new Vector<LibrarySet>();

+    

+    public void execute() throws org.apache.tools.ant.BuildException {

+        throw new org.apache.tools.ant.BuildException(

+                        "Not an actual task, but looks like one for documentation purposes");

+    }

+

+

+    public void addConfiguredArgument(UserDefineArgument arg) {

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        addConfiguredProcessorArg(arg);

+    }

+    

+    /**

+     * Creates an include path.

+     */

+    public IncludePath createIncludePath() {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project must be set");

+        }

+        if (isReference()) {

+            throw noChildrenAllowed();

+        }

+        IncludePath path = new IncludePath(p);

+        includePaths.addElement(path);

+        return path;

+    }

+    

+    

+    /**

+     * Add a <includepath> if specify the file attribute

+     * 

+     * @throws BuildException

+     *             if the specify file not exist

+     */

+    protected void loadFile(Vector activePath, File file) throws BuildException {

+        FileReader fileReader;

+        BufferedReader in;

+        String str;

+        if (!file.exists()) {

+            throw new BuildException("The file " + file + " is not existed");

+        }

+        try {

+            fileReader = new FileReader(file);

+            in = new BufferedReader(fileReader);

+            while ((str = in.readLine()) != null) {

+                if (str.trim() == "") {

+                    continue;

+                }

+                str = getProject().replaceProperties(str);

+                activePath.addElement(str.trim());

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+    

+    /**

+     * Returns the specific include path.

+     */

+    public String[] getActiveIncludePaths() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getActiveIncludePaths();

+        }

+        return getActivePaths(includePaths);

+    }

+    

+    private String[] getActivePaths(Vector paths) {

+        Project p = getProject();

+        if (p == null) {

+            throw new java.lang.IllegalStateException("project not set");

+        }

+        Vector activePaths = new Vector(paths.size());

+        for (int i = 0; i < paths.size(); i++) {

+            ConditionalPath path = (ConditionalPath) paths.elementAt(i);

+            if (path.isActive(p)) {

+                if (path.getFile() == null) {

+                    String[] pathEntries = path.list();

+                    for (int j = 0; j < pathEntries.length; j++) {

+                        activePaths.addElement(pathEntries[j]);

+                    }

+                } else {

+                    loadFile(activePaths, path.getFile());

+                }

+            }

+        }

+        String[] pathNames = new String[activePaths.size()];

+        activePaths.copyInto(pathNames);

+        return pathNames;

+    }

+    

+    public String getIncludepathDelimiter() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getIncludepathDelimiter();

+        }

+        return includepathDelimiter;

+    }

+

+    public void setIncludepathDelimiter(String includepathDelimiter) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.includepathDelimiter = includepathDelimiter;

+    }

+

+    public String getInputSuffix() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getInputSuffix();

+        }

+        return inputSuffix;

+    }

+

+    public void setInputSuffix(String inputSuffix) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.inputSuffix = inputSuffix;

+    }

+

+    public File getOutdir() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getOutdir();

+        }

+        return outdir;

+    }

+

+    public void setOutdir(File outdir) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.outdir = outdir;

+    }

+

+    public String getOutputSuffix() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getOutputSuffix();

+        }

+        return outputSuffix;

+    }

+

+    public void setOutputSuffix(String outputSuffix) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.outputSuffix = outputSuffix;

+    }

+

+    public String getType() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getType();

+        }

+        return type;

+    }

+

+    public void setType(String type) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.type = type;

+    }

+

+    public File getWorkdir() {

+        if (isReference()) {

+            return ((UserDefineDef) getCheckedRef(UserDefineDef.class,

+                            "UserDefineDef")).getWorkdir();

+        }

+        return workdir;

+    }

+

+    public void setWorkdir(File workdir) {

+        if (isReference()) {

+            throw tooManyAttributes();

+        }

+        this.workdir = workdir;

+    }

+    

+    /**

+     * Add an libSet.

+     */

+    public LibrarySet createLibset() {

+        if (isReference()){

+            throw noChildrenAllowed();

+        }

+        LibrarySet lib = new LibrarySet();

+        libSet.addElement(lib);

+        return lib;        

+    }

+    

+    public String getLibSetString(){

+        String libString = null;

+        for (int i = 0; i < libSet.size(); i++){

+            String[] libList = libSet.get(i).getLibs();

+            for (int j = 0; j < libList.length; j++){

+                libString = libString + libList[j] + " ";

+            }

+        }

+        return libString;

+    }

+    

+    public Vector<LibrarySet> getLibSet(){

+        return this.libSet;        

+    }

+    

+    /**

+     * Add map element

+     */

+    public void addMap(UserDefineElement mapElement){

+        if (isReference()){

+            throw noChildrenAllowed();

+        }else{

+            this.map.addElement(mapElement);

+        }

+    }

+    

+    public Vector<UserDefineElement> getMap (){

+        return this.map;

+    }   

+    

+    public String getMapvalue (){

+        if (this.map.size() > 0){

+            /*

+             * If user set more than one map use the first one. 

+             */

+            return this.map.get(0).value;

+        }

+        return null;

+        

+    }

+    public String getMapFlag(){

+        if (this.map.size() > 0){

+            /*

+             * If user set more than one map use the first one. 

+             */

+            return this.map.get(0).flag;

+        }

+        return null;

+    }

+    /**

+     *  Add pdb element

+     */

+    public void addPdb(UserDefineElement pdbElement){

+        if (isReference()){

+            throw noChildrenAllowed();

+        }

+        this.pdb.addElement(pdbElement);

+    }

+    

+    public Vector<UserDefineElement> getPdb(){

+        return this.pdb;

+    }

+    public String getPdbvalue (){

+        if (this.pdb.size() > 0){

+            /*

+             * If user set more than one pdb use the first one. 

+             * 

+             */

+            return this.pdb.get(0).value;

+        }

+        return null;

+        

+    }

+    public String getPdbFlag(){

+        if (this.pdb.size() > 0){

+            /*

+             * If user set more than one pdb use the first one. 

+             */

+            return this.pdb.get(0).flag;

+        }

+        return null;

+    }

+    

+    /**

+     * add entryPoint element.

+     */

+    public void addEntryPoint(UserDefineElement entryPointElement){

+        if (isReference()){

+            throw noChildrenAllowed();

+        }

+        this.entryPoint.addElement(entryPointElement);

+    }

+    

+    public Vector<UserDefineElement> getEntryPoint(){

+        return this.entryPoint;

+    }

+    

+    public String getEntryPointvalue (){

+        if (this.entryPoint.size() > 0){

+            /*

+             * If user set more than one entryPoint use the first one. 

+             */

+            return this.entryPoint.get(0).value;

+        }

+        return null;

+        

+    }

+    public String getEntryPointFlag(){

+        if (this.entryPoint.size() > 0){

+            /*

+             * If user set more than one entry point use the first one. 

+             */

+            return this.entryPoint.get(0).flag;

+        }

+        return null;

+    }

+    

+    /**

+     * Add subSystem element.

+     */

+    public void addSubSystem (UserDefineElement subSystem){

+        if (isReference()){

+            throw noChildrenAllowed();

+        }

+        this.subSystem.addElement(subSystem);

+    }

+    public Vector<UserDefineElement> getSubSystem (){

+        return this.subSystem;

+    }

+    

+    public String getSubSystemvalue (){

+        if (this.subSystem.size() > 0){

+            /*

+             * If user set more than one subsystem use the first one. 

+             */

+            return this.subSystem.get(0).value;

+        }

+        return null;

+        

+    }

+    public String getSubSystemFlag(){

+        if (this.subSystem.size() > 0){

+            /*

+             * If user set more than one subsystem use the first one. 

+             */

+            return this.subSystem.get(0).flag;

+        }

+        return null;

+    }

+    /**

+     * Add includeFile element

+     */

+    public void addIncludeFile (UserDefineElement includeFile){

+        if (isReference()){

+            throw noChildrenAllowed();

+        }

+        this.includeFiles.addElement(includeFile);

+    }

+    public Vector<UserDefineElement> getIncludeFiles(){

+        return this.includeFiles;

+    }

+    

+    public String getIncludeFile (){

+        if (this.includeFiles.size() > 0){

+            /*

+             * If user set more than one map use the first one. 

+             */

+            return this.includeFiles.get(0).value;

+        }

+        return null;

+        

+    }

+    public String getIncludeFileFlag(){

+        if (this.includeFiles.size() > 0){

+            /*

+             * If user set more than one map use the first one. 

+             */

+            return this.includeFiles.get(0).flag;

+        }

+        return null;

+    }

+    

+    /**

+     * Add OutputFile element

+     */

+    public void addOutputFile (UserDefineElement outPutFile){

+        if (isReference()){

+            throw noChildrenAllowed();

+        }

+        this.outPutFiles.addElement(outPutFile);

+    }

+    

+    public Vector<UserDefineElement> getOutputFiles(){

+        return this.outPutFiles;

+    }

+    

+    public String getOutputFile (){

+        if (this.outPutFiles.size() > 0){

+            /*

+             * If user set more than one map use the first one. 

+             */

+            return this.outPutFiles.get(0).value;

+        }

+        return null;

+        

+    }

+    public String getOutPutFlag(){

+        if (this.outPutFiles.size() > 0){

+            /*

+             * If user set more than one map use the first one. 

+             */

+            return this.outPutFiles.get(0).flag;

+        }

+        return null;

+    }

+    

+    /**

+     * Add fileSet list

+     */

+    public void addFileList(FileList fileSet){

+        this.fileSetList.addElement(fileSet);

+    }

+    

+    public Vector<String> getFileList(){

+        Project p = getProject();

+        Vector<String> fileListVector = new Vector<String>();

+        for (int i = 0; i < this.fileSetList.size(); i++){

+            String[] tempStrList = this.fileSetList.get(i).getFiles(p);

+            for (int j = 0; j < tempStrList.length; j++){

+                fileListVector .addElement(tempStrList[j]);

+            }

+        }

+        return fileListVector;

+    }

+}

diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineElement.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineElement.java
new file mode 100644
index 0000000..b8c852c
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineElement.java
@@ -0,0 +1,23 @@
+package net.sf.antcontrib.cpptasks.userdefine;

+

+public class UserDefineElement {

+    String flag = null;

+    String value = null;

+

+    public String getValue() {

+        return value;

+    }

+

+    public void setValue(String value) {

+        this.value = value;

+    }

+

+    public String getFlag() {

+        return flag;

+    }

+

+    public void setFlag(String flag) {

+        this.flag = flag;

+    }

+    

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineMapping.java b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineMapping.java
new file mode 100644
index 0000000..bb290ef
--- /dev/null
+++ b/edk2/Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/userdefine/UserDefineMapping.java
@@ -0,0 +1,186 @@
+/*

+ * 

+ * Copyright 2001-2004 The Ant-Contrib project

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+package net.sf.antcontrib.cpptasks.userdefine;

+public class UserDefineMapping {

+    // list of Arch: EBC, ARM, IA32, X64, IPF, PPC, NT32

+    public final static String[] arch = { "EBC", "ARM", "IA32", "X64", "IPF",

+            "PPC", "NT32" };

+

+    // list of OS: Linux, Windows

+    public final static String[] os = { "WINDOWS", "LINUX" };

+

+    // list of Vendor: Microsoft, Intel, Cygwin, Gcc

+    public final static String[] vendor = { "MSFT", "INTEL", "GCC", "CYGWIN" };

+

+    // list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK

+    public final static String[] commandType = { "CC", "LIB", "LINK", "ASL",

+            "ASM", "ASMLINK", "PP" };

+

+    //

+    // flags mapping (Include compellingIncFileFlag,Path Delimiter, Output file

+    // flag,

+    // includepathfalge,

+    // )

+    // Examples: '/I' for MSFT cl.exe while '-I' for GCC

+    // '/Fo' for MSFT cl.exe while '-o' for GCC

+    //

+    public final static String[][] compellingIncFileFlag = {

+            { "MSFT_CC", "/FI" }, { "GCC_CC", "-include" },

+            { "INTEL_CC", "-FI" }, { "WINDDK_CC", "/FI" },

+            { "MSFT_ASM", "/FI" }, { "GCC_ASM", "-include" },

+            { "WINDDK_ASM", "/FI" } };

+

+    public final static String[][] includePathFlag = { { "MSFT_CC", "/I" },

+            { "GCC_CC", "-I" }, { "INTEL_CC", "/I" }, { "WINDDK_CC", "/I" },

+            { "MSFT_ASM", "/I" }, { "GCC_ASM", "-I" }, { "WINDDK_CC", "/I" },

+            { "MSFT_PP", "/I" }, { "GCC_PP", "-I" }, { "WINDDK_PP", "/I" } };

+

+    public final static String[][] outputFileFlag = { { "MSFT_CC", "/Fo" },

+            { "GCC_CC", "-o" }, { "INTEL_CC", "/Fo" }, { "WINDDK_CC", "/Fo" },

+            { "MSFT_LIB", "/OUT:" }, { "GCC_LIB", "-cr" },

+            { "INTEL_LIB", "/OUT:" }, { "WINDDK_LIB", "/OUT:" },

+            { "MSFT_LINK", "/OUT:" }, { "GCC_LINK", "-o" },

+            { "INTEL_LINK", "/OUT:" }, { "WINDDK_LINK", "/OUT:" },

+            { "MSFT_ASM", "/Fo" }, { "GCC_ASM", "-o" },

+            { "WINDDK_ASM", "/Fo" },{"WINDDK_IPF_ASM", "-o"} };

+

+    public final static String[][] subSystemFlag = {

+            { "MSFT_LIB", "/SUBSYSTEM:" }, { "GCC_LIB", "--subsystem=" },

+            { "WINDDk_LIB", "/SUBSYSTEM:" }, { "INTEL_LIB", "/SUBSYSTEM:" },

+            { "MSFT_LINK", "/SUBSYSTEM:" }, { "GCC_LINK", "--subsystem=" },

+            { "INTEL_LINK", "/SUBSYSTEM:" }, { "WINDDK_LINK", "/SUBSYSTEM:" } };

+

+    public final static String[][] outputFileSuffix = {

+            { "WINDOWS_ASM", ".obj" }, { "WINDOWS_CC", ".obj" },

+            { "LINUX_ASM", ".o" }, { "LINUX_CC", ".o" } };

+

+    public final static String[][] entryPointFlag = {

+            { "MSFT_LINK", "/ENTRY:" }, { "GCC_LINK", "-e" },

+            { "INTEL_LINK", "/ENTRY:" },

+            { "WINDDK_LINK", "/ENTRY:" } };

+

+    public final static String[][] mapFlag = { { "MSFT_LINK", "/MAP:" },

+            { "GCC_LINK", "" }, { "INTEL_LINK", "/MAP:" },

+            { "WINDDK_LINK", "/MAP:" } };

+

+    public final static String[][] pdbFlag = { { "MSFT_LINK", "/PDB:" },

+            { "GCC_LINK", "" }, { "INTEL_LINK", "" }, { "WINDDK_LINK", "/PDB:"} };

+

+    public static String getIncludePathDelimiter(String vendor,

+            String commandType) {

+        String key = vendor + "_" + commandType;

+        for (int i = 0; i < includePathFlag.length; i++) {

+            if (includePathFlag[i][0].equalsIgnoreCase(key)) {

+                return includePathFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    public static String getOutputFileFlag(String vendor, String arch, String commandType) {

+        /*

+         * First find outputfileFlag by vendor_arch_commandType

+         */

+        String key = vendor + "_" + arch + "_" + commandType;

+        for (int i = 0; i < outputFileFlag.length; i++) {

+            if (outputFileFlag[i][0].equalsIgnoreCase(key)) {

+                return outputFileFlag[i][1];

+            }

+        }

+        key = vendor + "_" + commandType;

+        for (int i = 0; i < outputFileFlag.length; i++) {

+            if (outputFileFlag[i][0].equalsIgnoreCase(key)) {

+                return outputFileFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    public static String getCompellingIncFileFlag(String vendor,

+            String commandType) {

+        String key = vendor + "_" + commandType;

+        for (int i = 0; i < compellingIncFileFlag.length; i++) {

+            if (compellingIncFileFlag[i][0].equalsIgnoreCase(key)) {

+                return compellingIncFileFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    public static String getSubSystemFlag(String vendor, String commandType) {

+        String key = vendor + "_" + commandType;

+        for (int i = 0; i < subSystemFlag.length; i++) {

+            if (subSystemFlag[i][0].equalsIgnoreCase(key)) {

+                return subSystemFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    public static String getEntryPointFlag(String vendor, String commandType) {

+        String key = vendor + "_" + commandType;

+        for (int i = 0; i < entryPointFlag.length; i++) {

+            if (entryPointFlag[i][0].equalsIgnoreCase(key)) {

+                return entryPointFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    public static String getMapFlag(String vendor, String commandType) {

+        String key = vendor + "_" + commandType;

+        for (int i = 0; i < mapFlag.length; i++) {

+            if (mapFlag[i][0].equalsIgnoreCase(key)) {

+                return mapFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    public static String getPdbFlag(String vendor, String commandType) {

+        String key = vendor + "_" + commandType;

+        for (int i = 0; i < pdbFlag.length; i++) {

+            if (pdbFlag[i][0].equalsIgnoreCase(key)) {

+                return pdbFlag[i][1];

+            }

+        }

+        return null;

+    }

+

+    //

+    // Well-known source file suffix and output file suffix relationship

+    // sourceExtension(Multiple),

+    // headExtension(Multiple) and outputSuffix(Single)

+    //

+

+    //

+    // Default command string such as 'cl' in MSFT while 'gcc' in GCC

+    //

+    public final static String[][] defaultCommand = { { "GCC", "gcc" },

+            { "MSFT_CC", "cl" }, { "MSFT_LIB", "lib" },

+            { "MSFT_LINK", "link" }, };

+

+    public static String getDefaultCommand(String toolchain) {

+        for (int i = 0; i < defaultCommand.length; i++) {

+            if (defaultCommand[i][0].equalsIgnoreCase(toolchain)) {

+                return defaultCommand[i][1];

+            }

+        }

+        return null;

+    }

+

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/build.xml b/edk2/Tools/Source/FrameworkTasks/build.xml
new file mode 100644
index 0000000..0a99a44
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/build.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="FrameworkTasks" default="all">

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env"/>

+  <property name="workspace" value="${env.WORKSPACE}"/>

+  <property name="buildDir" value="build"/>

+  <property name="installLocation" value="${workspace}/Tools/Jars"/>

+  <target name="all" depends="install"/>

+  <target name="source">

+    <mkdir dir="${buildDir}"/>

+    <javac srcdir="." destdir="${buildDir}">

+      <classpath>

+        <fileset dir="${workspace}/Tools/Jars">

+          <include name="*.jar"/>

+        </fileset>

+      </classpath>

+      <compilerarg value="-Xlint"/>

+    </javac>

+  </target>

+  <target name="clean">

+    <delete dir="${buildDir}"/>

+  </target>

+  <target name="cleanall">

+    <delete dir="${buildDir}"/>

+    <if>

+      <available file="${installLocation}/frameworktasks.jar"/>

+      <then>

+        <echo message="You must manually remove the file: ${installLocation}/frameworktasks.jar"/>

+        <echo message="Java has already loaded the file, and cannot remove it within ANT!"/>

+      </then>

+    </if>

+  </target>

+  <target name="install" depends="source">

+    <copy file="frameworktasks.tasks" toDir="${buildDir}"/>

+    <jar destfile="${installLocation}/frameworktasks.jar"

+      basedir="${buildDir}"

+      includes="**"

+    />

+  </target>

+</project>

diff --git a/edk2/Tools/Source/FrameworkTasks/frameworktasks.tasks b/edk2/Tools/Source/FrameworkTasks/frameworktasks.tasks
new file mode 100644
index 0000000..f8bafab
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/frameworktasks.tasks
@@ -0,0 +1,11 @@
+fwimage=org.tianocore.framework.tasks.FwImageTask

+setstamp=org.tianocore.framework.tasks.SetStampTask

+gendepex=org.tianocore.framework.tasks.GenDepexTask

+gensection=org.tianocore.framework.tasks.GenSectionTask

+genffsfile=org.tianocore.framework.tasks.GenFfsFileTask

+vfrcompile=org.tianocore.framework.tasks.VfrCompilerTask

+strgather=org.tianocore.framework.tasks.StrGatherTask

+genfvimage=org.tianocore.framework.tasks.GenFvImageTask

+guidchk= org.tianocore.framework.tasks.GuidChkTask

+gencrc32section=org.tianocore.framework.tasks.GenCRC32SectionTask

+makedeps=org.tianocore.framework.tasks.MakeDeps

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Compress.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Compress.java
new file mode 100644
index 0000000..4410ecd
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Compress.java
@@ -0,0 +1,78 @@
+/** @file

+ Compress class.

+

+ This class is to call CompressDll.dll to compress section.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+package org.tianocore.framework.tasks;

+

+import java.io.File;

+

+/**

+

+  This class is to call CompressDll.dll to compress section.

+ 

+**/

+public class Compress {

+    byte[] inputBuffer;

+    byte[] outputBuffer;

+    int    size;

+

+    static {

+        String dllPath;

+

+        dllPath = GenFfsFileTask.path;

+        dllPath = dllPath + 

+                  File.separator + 

+                  "CompressDll.dll";

+

+        System.load(dllPath);

+    }

+

+    /**

+      CallCompress

+    

+      This function is to call the compressDll.dll to compress the contents in

+      buffer.

+      

+      @param  inputBuffer       The input buffer.

+      @param  size              The size of buffer in byte.

+      @param  dllPath           The compressDll.dll path.

+      @return                   The buffer contained the comrpessed input.

+    **/

+    public native byte[] CallCompress (byte[] inputBuffer, int size, String dllPath);

+

+    /**

+      Construct function

+      

+      This function is to initialize the class member and call the compress 

+      function.

+      

+      @param inBuffer           The input buffer.         

+      @param size               The size of buffer in byte.

+    **/

+    public Compress (byte[] inBuffer, int size){

+        this.inputBuffer   = inBuffer;

+        this.size          = size;        

+        String path        = GenFfsFileTask.path;

+

+        //

+        //  Call Compress function.

+        //

+        this.outputBuffer  = CallCompress (

+                                          this.inputBuffer, 

+                                          this.size,

+                                          path                          

+                                          );

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/CompressHeader.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/CompressHeader.java
new file mode 100644
index 0000000..5992b1d
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/CompressHeader.java
@@ -0,0 +1,78 @@
+/** @file

+ CompressHeader class.

+

+ This class is to generate the compressed section header.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+  

+  Internal class: This class is to generate the compressed section header.

+

+**/

+public class CompressHeader {

+    

+    /**

+      CommonSectionHeader

+      

+      This class define the compressed header structor.

+    

+    **/

+    public class CommonSectionHeader {

+        byte[] Size = new byte[3];

+        byte   type;

+    }

+    

+    ///

+    /// Section header.

+    ///

+    public CommonSectionHeader SectionHeader = new CommonSectionHeader();

+    

+    ///

+    /// Length of uncompress section in byte.

+    ///

+    public int                 UncompressLen;

+    /// 

+    /// Compress type.

+    ///

+    public byte                CompressType;

+    

+    ///

+    /// The size of compress header in byte. 

+    ///

+    public int GetSize (){

+        return 9;

+    }

+    

+    ///

+    /// Write class member to buffer. 

+    ///

+    public void StructToBuffer (byte[] Buffer){

+        if (Buffer.length != GetSize()) {

+            throw new BuildException ("CompressHeader Buffer size is not correct!");

+        }

+        for (int i = 0; i < 3; i++){

+            Buffer[i] = SectionHeader.Size[i];

+        }

+        Buffer[3] = SectionHeader.type;

+        Buffer[4] = (byte)(UncompressLen  & 0xff);

+        Buffer[5] = (byte)((UncompressLen & 0xff00)>>8);

+        Buffer[6] = (byte)((UncompressLen & 0xff0000)>>16);

+        Buffer[7] = (byte)((UncompressLen & 0xff000000)>>24);

+        Buffer[8] = CompressType;

+    }

+    

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/CompressSection.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/CompressSection.java
new file mode 100644
index 0000000..8def4eb
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/CompressSection.java
@@ -0,0 +1,209 @@
+/** @file

+ CompressSection class.

+

+ CompressSection indicate that all section which in it should be compressed.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+

+package org.tianocore.framework.tasks;

+

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.apache.tools.ant.BuildException;

+

+

+/**

+  CompressSection

+  

+  CompressSection indicate that all section which in it should be compressed. 

+ 

+**/

+public class CompressSection implements Section, FfsTypes{

+    //

+    // The attribute of compressName.

+    //

+    String compressName = "";

+    //

+    // The list contained the SectFile element.

+    //

+    List<Object>   SectList     = new ArrayList<Object>();

+

+    /**

+      toBuffer

+      

+      This function is to collect all sectFile and compress it , then output

+      the result to buffer.

+      

+      @param Buffer     The point of output buffer

+      

+    **/

+    public void toBuffer (DataOutputStream Buffer){

+        

+        Section    sect;

+        File       compressOut;

+    

+        //

+        //  Get section file in compress node.

+        //

+        try{

+            compressOut = new File ("Compress.temp");

+            FileOutputStream fo = new FileOutputStream (compressOut.getName());

+            DataOutputStream Do = new DataOutputStream (fo);

+            

+            //

+            //  Get each section which under the compress {};

+            //  And add it is contains to File;

+            //

+            Iterator SectionIter = SectList.iterator();

+            while (SectionIter.hasNext()){

+                sect = (Section)SectionIter.next();

+                

+                //

+                //  Call each section class's toBuffer function.

+                //

+                try {

+                    sect.toBuffer(Do);

+                }

+                catch (BuildException e) {

+                    System.out.print(e.getMessage());

+                    throw new BuildException ("Compress.toBuffer failed at section");

+                }    

+                            

+            }

+            Do.close();    

+            

+            //

+            //  Get contain to Buffer

+            //

+            FileInputStream fi = new FileInputStream (compressOut.getName());

+            DataInputStream di = new DataInputStream (fi);

+            byte[] fileBuffer  = new byte[(int)compressOut.length()];

+            di.read(fileBuffer);

+            

+            //

+            //  Call compress

+            //

+            Compress myCompress = new Compress(fileBuffer, fileBuffer.length);            

+            

+            //

+            //  Add Compress header

+            //

+            CompressHeader Ch        = new CompressHeader();

+            Ch.SectionHeader.Size[0] = (byte)((myCompress.outputBuffer.length +

+                                               Ch.GetSize()) &

+                                               0xff

+                                              );

+            Ch.SectionHeader.Size[1] = (byte)(((myCompress.outputBuffer.length + 

+                                                Ch.GetSize())&

+                                               0xff00) >> 8

+                                              );

+            Ch.SectionHeader.Size[2] = (byte)(((myCompress.outputBuffer.length + 

+                                                Ch.GetSize()) & 

+                                               0xff0000) >> 16

+                                             );

+            Ch.SectionHeader.type    = (byte) EFI_SECTION_COMPRESSION;

+            

+            //

+            //  Note: The compressName was not effective now. Using the

+            //  EFI_STANDARD_COMPRSSION for compressType .

+            //  That is follow old Genffsfile tools. Some code will be added for 

+            //  the different compressName;

+            //

+            Ch.UncompressLen         = fileBuffer.length;

+            Ch.CompressType          = EFI_STANDARD_COMPRESSION; 

+            

+            //

+            //  Change header struct to byte buffer

+            //

+            byte [] headerBuffer = new byte[Ch.GetSize()];

+            Ch.StructToBuffer(headerBuffer);

+            

+            //

+            //  First add CompressHeader to Buffer, then add Compress data.

+            //

+            Buffer.write (headerBuffer);

+            Buffer.write(myCompress.outputBuffer);            

+                

+            //

+            //  4 Byte aligment 

+            //

+            int size = Ch.GetSize() + myCompress.outputBuffer.length;

+            

+            while ((size & 0x03) != 0){

+                size ++;

+                Buffer.writeByte(0);

+            }

+            

+            //

+            //  Delete temp file

+            //

+            di.close();

+            compressOut.delete();

+                

+        }

+        catch (Exception e){

+            throw new BuildException("compress.toBuffer failed!\n");

+        }    

+    }

+

+    /**

+      getCompressName

+      

+      This function is to get compressName.

+      

+      @return            The compressName.

+    **/

+    public String getCompressName() {

+        return compressName;

+    }

+

+    /**

+      setCompressName

+      

+      This function is to set compressName.

+      

+      @param compressName The string of compressName

+    **/

+    public void setCompressName(String compressName) {

+        this.compressName = compressName;

+    }

+

+    /**

+      addSectFile

+      

+      This function is to add sectFile element to SectList.

+      

+      @param sectFile    SectFile element which succeed from section class.

+    **/

+    public void addSectFile (SectFile sectFile) {

+        SectList.add(sectFile);

+            

+    }    

+    

+    /**

+      addTool

+      

+      This function is to add tool element to SectList.

+      @param tool        Tool element which succeed from section class.

+    **/

+    public void addTool (Tool tool) {

+        SectList.add(tool);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Database.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Database.java
new file mode 100644
index 0000000..8c3f6be
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Database.java
@@ -0,0 +1,112 @@
+/** @file

+ Database class.

+

+ Database represents an exceplicity name list of database file. 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+

+import java.io.File;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.StringTokenizer;

+

+/**

+  Database

+  

+  Database represents an exceplicity name list of database file. 

+ 

+**/

+public class Database implements NestElement{

+    ///

+    /// name of database file

+    ///

+    private String name = "";

+    ///

+    /// name of file including database files

+    /// 

+    private File file;

+    ///

+    /// the database file name list

+    ///

+    private List<String> nameList = new ArrayList<String>();

+    

+    /**

+      getName

+      

+      This function is to get class member "name".

+      

+      @return             class member "name".

+    **/

+    public String getName() {

+        return this.name;

+    }

+    /**

+      setName

+      

+      This function is to set class member "name".

+      

+      @param name : name of database file.

+    **/

+    public void setName(String name) {

+        this.name = " -db " + name;

+    }

+

+    /**

+      toString

+      

+      This function is to call getName() function.

+      @return       class member "name".  

+    **/

+    public String toString() {

+        return getName();

+    }

+    

+    /**

+      getFile

+      

+      This function is to get file which include the database file list.

+      

+      @return      class member "file"

+      

+    **/

+    public File getFile() {

+        return this.file;

+    }

+    /**

+      setFile

+      

+      This function is to set class member "file".

+      

+      @param file  The file which include the database file list. 

+    **/

+    public void setFile(File file) {

+        this.file = file;

+    }

+ 

+

+    public void setList(String fileNameList) {

+        if (fileNameList != null && fileNameList.length() > 0) {

+            StringTokenizer tokens = new StringTokenizer(fileNameList, " \t,;", false);

+            while (tokens.hasMoreTokens()) {

+                String fileName = tokens.nextToken().trim();

+                if (fileName.length() > 0) {

+                    this.nameList.add(fileName);

+                }

+            }

+        }

+    }

+

+    public List<String> getList() {

+        return nameList;

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/EfiDefine.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/EfiDefine.java
new file mode 100644
index 0000000..6f12f00
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/EfiDefine.java
@@ -0,0 +1,56 @@
+/** @file

+ EfiDefine class.

+

+ EfiDefine class records the UEFI return status value.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+package org.tianocore.framework.tasks;

+

+/**

+  EfiDefine class.

+

+  EfiDefine class records the UEFI return status value.

+**/

+public interface EfiDefine {

+    //

+    // EFI define Interface for define constant related to UEFI.

+    //  

+    static final int EFI_SUCCESS                = 0;

+    static final int EFI_LOAD_ERROR             = 0x80000001;

+    static final int EFI_INVALID_PARAMETER      = 0x80000002;

+    static final int EFI_UNSUPPORTED            = 0x80000003;

+    static final int EFI_BAD_BUFFER_SIZE        = 0x80000004;

+    static final int EFI_BUFFER_TOO_SMALL       = 0x80000005;

+    static final int EFI_NOT_READY              = 0x80000006;

+    static final int EFI_DEVICE_ERROR           = 0x80000007;

+    static final int EFI_WRITE_PROTECTED        = 0x80000008;

+    static final int EFI_OUT_OF_RESOURCES       = 0x80000009;

+    static final int EFI_VOLUME_CORRUPTED       = 0x8000000a;

+    static final int EFI_VOLUME_FULL            = 0x8000000b;

+    static final int EFI_NO_MEDIA               = 0x8000000c;

+    static final int EFI_MEDIA_CHANGED          = 0x8000000d;

+    static final int EFI_NOT_FOUND              = 0x8000000e;

+    static final int EFI_ACCESS_DENIED          = 0x8000000f;

+    static final int EFI_NO_RESPONSE            = 0x80000010;

+    static final int EFI_NO_MAPPING             = 0x80000011;

+    static final int EFI_TIMEOUT                = 0x80000012;

+    static final int EFI_NOT_STARTED            = 0x80000013;

+    static final int EFI_ALREADY_STARTED        = 0x80000014;

+    static final int EFI_ABORTED                = 0x80000015;

+    static final int EFI_ICMP_ERROR             = 0x80000016;

+    static final int EFI_TFTP_ERROR             = 0x80000017;

+    static final int EFI_PROTOCOL_ERROR         = 0x80000018;

+    static final int EFI_INCOMPATIBLE_VERSION   = 0x80000019;

+    static final int EFI_SECURITY_VIOLATION     = 0x80000020;

+    static final int EFI_CRC_ERROR              = 0x80000021;

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FfsHeader.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FfsHeader.java
new file mode 100644
index 0000000..4af4919
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FfsHeader.java
@@ -0,0 +1,185 @@
+/** @file

+ FfsHeader 

+

+ FfsHeader class describe the struct of Ffs file header.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+  FfsHeader

+  

+  FfsHeader class describe the struct of Ffs file header.

+**/

+public class FfsHeader {

+

+    /**

+      FfsGuid

+      

+      FfsGuid is interal class of FfsHeader, it describe the struct of Guid.

+    **/

+    public class FfsGuid {

+

+        int    data1      = 0;

+        short  data2      = 0;

+        short  data3      = 0;

+        byte[] data4      = new byte[8];        

+        byte[] dataBuffer = new byte[16];

+

+        /**

+          bufferToStruct 

+          

+          This function is to convert GUID to ffsGuid class member.

+          

+          @param   dataBuffer   Buffer contained the GUID value in byte.

+                                For example: if the input string as : "A6F691AC

+                                31C8 4444 854C E2C1A6950F92"

+                                Then Data1: AC91F6A6

+                                Data2: C831

+                                Data3: 4444

+                                Data4: 4C85E2C1A6950F92

+        **/     

+        public void bufferToStruct (byte[] dataBuffer){

+            if (dataBuffer.length != 16) {

+                throw new BuildException ("Buffer is not fitting GUID type!");

+            }

+

+            data1 = (int)(dataBuffer[3]& 0xff);

+            data1 = data1 << 8;     

+            data1 = (int)data1 | (dataBuffer[2]& 0xff);         

+            data1 = ((data1 << 8) & 0xffff00)   | (dataBuffer[1]& 0xff);

+            data1 = ((data1 << 8) & 0xffffff00) | (dataBuffer[0]& 0xff);

+

+

+            data2 = (short) (dataBuffer[5] & 0xff);

+            data2 = (short)((data2 << 8) | (dataBuffer[4]& 0xff));

+

+            data3 = (short)(dataBuffer[7] & 0xff);

+            data3 = (short)((data3 << 8) | (dataBuffer[6] & 0xff));

+

+            for (int i = 0; i < 8; i++) {

+                data4[i] = dataBuffer[i+8];

+            }

+

+        }

+

+        /**

+          structToBuffer

+          

+          This function is to store ffsHeader class member to buffer.

+          

+          @return        Byte buffer which contained the ffsHeader class member

+        **/

+        public byte[] structToBuffer (){

+

+            byte[] buffer = new byte [16];  

+

+            buffer[3] = (byte)(data1 & 0x000000ff);

+            buffer[2] = (byte)((data1 & 0x0000ff00)>> 8);

+            buffer[1] = (byte)((data1 & 0x00ff0000)>> 16); 

+            buffer[0] = (byte)((data1 & 0xff000000)>> 24);

+

+            buffer[5] = (byte)(data2 & 0x00ff);

+            buffer[4] = (byte)((data2 & 0xff00)>> 8);

+

+            buffer[7] = (byte)(data3 & 0x00ff);

+            buffer[6] = (byte)((data3 & 0xff00)>> 8);

+

+            for (int i = 8; i < 16; i++) {

+                buffer[i] = data4[i-8];

+            }               

+            return buffer;

+        }

+

+

+    }

+

+    /**

+      integrityCheckSum

+      

+      This class is used to record the struct of checksum.

+    **/

+    public class IntegrityCheckSum {

+        byte header;

+        byte file;

+    }

+

+    ///

+    /// Guid

+    ///

+    FfsGuid name = new FfsGuid();

+

+    ///

+    /// CheckSum

+    ///

+    IntegrityCheckSum integrityCheck = new IntegrityCheckSum();

+

+    ///

+    /// File type

+    ///

+    byte   fileType;

+    ///

+    /// Ffs attributes.

+    ///

+    byte   ffsAttributes;

+    ///

+    /// Ffs file size

+    ///

+    byte[] ffsFileSize = new byte[3];

+    ///

+    /// Ffs state.

+    ///

+    byte   ffsState;

+

+    /**

+      structToBuffer

+      

+      This function is to store FfsHeader class member to buffer.

+      

+      @return   Byte buffer which contained the FfsHeader class member.

+    **/

+    public byte[] structToBuffer () {

+        int i;

+        byte[] buffer1;         

+        byte[] buffer = new byte[24];

+        buffer1       = name.structToBuffer();

+

+        for (i = 0; i < 16; i++) {

+            buffer[i] = buffer1[i];

+        }

+

+        buffer[16] = integrityCheck.header;

+        buffer[17] = integrityCheck.file;

+        buffer[18] = fileType;

+        buffer[19] = ffsAttributes;

+

+        for (i=20; i < 23; i++) {

+            buffer[i] = ffsFileSize[i-20];

+        }

+

+        buffer[23] = ffsState;

+        return buffer;

+    }

+

+    /**

+      getSize

+      

+      This function is to get the size of FfsHeader in byte.

+      

+      @return          The size of FfsHeader.

+    **/

+    public int getSize(){

+        return 24;

+    }

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FfsTypes.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FfsTypes.java
new file mode 100644
index 0000000..6afc3a9
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FfsTypes.java
@@ -0,0 +1,115 @@
+/** @file

+ FfsTypes class.

+

+ FfsType class record the costant value of Ffs File attribute, type, and 

+ architecture.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+

+/**

+  FfsType

+  

+  FfsType class record the costant value of Ffs File attribute, type, and 

+  architecture.

+  

+**/

+public interface FfsTypes {

+    //

+    // Ffs file attributes

+    //

+    static final int FFS_ATTRIB_TAIL_PRESENT             = 0x01;

+

+    static final int FFS_ATTRIB_RECOVERY                 = 0x02;

+

+    static final int FFS_ATTRIB_HEADER_EXTENSION         = 0x04;

+

+    static final int FFS_ATTRIB_DATA_ALIGNMENT           = 0x38;

+

+    static final int FFS_ATTRIB_CHECKSUM                 = 0x40;

+

+    //

+    // Ffs states difinitions

+    //

+    static final int EFI_FILE_HEADER_CONSTRUCTION        = 0x01;

+

+    static final int EFI_FILE_HEADER_VALID               = 0x02;

+

+    static final int EFI_FILE_DATA_VALID                 = 0x04;

+

+    static final int EFI_FILE_MARKED_FOR_UPDATE          = 0x08;

+

+    static final int EFI_FILE_DELETED                    = 0x10;

+

+    static final int EFI_FILE_HEADER_INVALID             = 0x20;

+

+    //

+    // FFS_FIXED_CHECKSUM is the default checksum value used when the

+    // FFS_ATTRIB_CHECKSUM attribute bit is clear note this is NOT an

+    // architecturally defined value, but is in this file for implementation

+    // convenience

+    //

+    static final int FFS_FIXED_CHECKSUM = 0x5a;

+

+    //

+    // Architectural file types

+    //

+    static final int EFI_FV_FILETYPE_ALL                   = 0x00;

+

+    static final int EFI_FV_FILETYPE_RAW                   = 0x01;

+

+    static final int EFI_FV_FILETYPE_FREEFORM              = 0x02;

+

+    static final int EFI_FV_FILETYPE_SECURITY_CORE         = 0x03;

+

+    static final int EFI_FV_FILETYPE_PEI_CORE              = 0x04;

+

+    static final int EFI_FV_FILETYPE_DXE_CORE              = 0x05;

+

+    static final int EFI_FV_FILETYPE_PEIM                  = 0x06;

+

+    static final int EFI_FV_FILETYPE_DRIVER                = 0x07;

+

+    static final int EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER  = 0x08;

+

+    static final int EFI_FV_FILETYPE_APPLICATION           = 0x09;

+

+    static final int EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE = 0x0B;

+

+    static final int EFI_FV_FILETYPE_FFS_PAD               = 0xF0;

+

+    //

+    // Ffs file type

+    //

+    static final String EFI_FV_FFS_FILETYPE_STR            = ".FFS";

+    static final String EFI_FV_DXE_FILETYPE_STR            = ".DXE";

+    static final String EFI_FV_PEI_FILETYPE_STR            = ".PEI";

+    static final String EFI_FV_APP_FILETYPE_STR            = ".APP";

+    static final String EFI_FV_FVI_FILETYPE_STR            = ".FVI";

+    static final String EFI_FV_SEC_FILETYPE_STR            = ".SEC";

+    

+    //

+    //  Section Type copy from EfiImageFormat.h

+    //

+    static final int  EFI_SECTION_COMPRESSION              = 0x01;

+    static final int  EFI_SECTION_GUID_DEFINED             = 0x02;

+    

+    //

+    //  CompressionType values, we currently don't support 

+    //  "EFI_CUSTOMIZED_COMPRESSION".

+    //

+    static final int  EFI_NOT_COMPRESSED                   = 0x00;

+    static final int  EFI_STANDARD_COMPRESSION             = 0x01;

+    static final int  EFI_CUSTOMIZED_COMPRESSION           = 0x02;

+    

+

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FileParser.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FileParser.java
new file mode 100644
index 0000000..982fd65
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FileParser.java
@@ -0,0 +1,72 @@
+/** @file

+ FileParser class.

+

+ FileParser class is to parse file which contains the list of file name and 

+ add those files to list.

+  

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+import java.io.*;

+import java.util.List;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+

+/**

+  FileParser class.

+

+  FileParser class is to parse file which contains the list of file name and 

+  add those files to list.

+**/

+public class  FileParser {

+    /**

+      loadFile

+     

+      This function is to add files to array from input file which contains the 

+      files list.

+      @param  project  The current project.

+      @param  list     File array.

+      @param  file     File which contains the file list.

+      @param  tag      Target of architecture.

+      @throws BuildException

+    **/

+    public static synchronized void loadFile(Project project, List<Object> list, File file, String tag) throws BuildException{

+        FileReader fileReader;

+        BufferedReader in;

+        String str;

+        

+        if (!file.exists()) {

+            throw new BuildException("The file" + file + "is not exist");           

+        } 

+        try {

+            fileReader = new FileReader(file);

+            in = new BufferedReader(fileReader);

+            while((str=in.readLine())!= null){

+                if (str.trim()==""){

+                    continue;

+                }

+                str = project.replaceProperties(str);

+                if (str.trim().substring(0,2).equalsIgnoreCase(tag)) {

+                    list.add(str.trim());

+                } else {

+                    list.add(tag + " " + str.trim());

+                }

+                

+            }

+        } catch (Exception e){

+            System.out.println(e.getMessage());

+            

+        }

+    }

+    

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FwImageTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FwImageTask.java
new file mode 100644
index 0000000..19583b5
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FwImageTask.java
@@ -0,0 +1,199 @@
+/** @file

+ FwImageTask class.

+

+ FwImageTask is used to call FwImage.ext to generate the FwImage.

+  

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+/**

+  FwImageTask class.

+

+  FwImageTask is used to call FwImage.ext to generate the FwImage.

+**/

+public class FwImageTask extends Task implements EfiDefine{

+    ///

+    /// time&data 

+    ///

+    private String time = "";

+    ///

+    /// input PE image

+    /// 

+    private String peImage = "";

+    ///

+    /// output EFI image

+    /// 

+    private String outImage = "";

+    ///

+    /// component type

+    ///

+    private String componentType = "";

+

+    /**

+     * assemble tool command line & execute tool command line

+     * 

+     * @throws BuildException

+     */

+    /**

+      execute 

+      

+      FwimageTask execute function is to assemble tool command line & execute

+      tool command line

+      

+      @throws BuidException

+    **/

+    public void execute() throws BuildException {

+

+        Project project = this.getOwningTarget().getProject();

+        //

+        // absolute path of efi tools

+        //

+        String path = project.getProperty("env.Framework_Tools_Path");

+        String command;

+        if (path == null) {

+            command = "FwImage";

+        } else {

+            command = path + "/" + "FwImage";

+        }

+        //

+        // argument of tools

+        //

+        String argument = time + componentType + peImage + outImage;

+        //

+        // return value of fwimage execution

+        //

+        int revl = -1;

+

+        try {

+            Commandline cmdline = new Commandline();

+            cmdline.setExecutable(command);

+            cmdline.createArgument().setLine(argument);

+

+            LogStreamHandler streamHandler = new LogStreamHandler(this,

+                    Project.MSG_INFO, Project.MSG_WARN);

+            Execute runner = new Execute(streamHandler, null);

+

+            runner.setAntRun(project);

+            runner.setCommandline(cmdline.getCommandline());

+            System.out.println(Commandline.toString(cmdline.getCommandline()));

+

+            revl = runner.execute();

+            if (EFI_SUCCESS == revl) {

+                //

+                // command execution success

+                //

+                System.out.println("fwimage succeeded!");

+            } else {

+                //

+                // command execution fail

+                //

+                System.out.println("fwimage failed. (error="

+                        + Integer.toHexString(revl) + ")");

+                throw new BuildException("fwimage failed. (error="

+                        + Integer.toHexString(revl) + ")");

+

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+    /**

+      setTime

+      

+      This function is to set operation of class member "time".

+      

+      @param time            string of time

+    **/

+    public void setTime(String time) {

+        this.time = " -t " + time;

+    }

+

+    /**

+      getTime

+      

+      This function is to get class member "time"

+      @return time          string of time

+    **/

+    public String getTime() {

+        return this.time;

+    }

+

+    /**

+      getPeImage

+      

+      This function is to get class member "peImage".

+      @return                name of PE image

+    **/

+    public String getPeImage() {

+        return this.peImage;

+    }

+

+    /**

+      setPeImage

+      

+      This function is to set class member "peImage"

+      @param  peImage        name of PE image

+    **/

+    public void setPeImage(String peImage) {

+        this.peImage = " " + peImage;

+    }

+

+    /**

+      getOutImage

+      

+      This function is to get class member "outImage".

+      @return                 name of output EFI image

+    **/

+    public String getOutImage() {

+        return this.outImage;

+    }

+

+    /**

+      setOutImage

+      

+      This function is to set class member "outImage".

+      @param outImage         name of output EFI image

+    **/

+    public void setOutImage(String outImage) {

+        this.outImage = " " + outImage;

+    }

+

+    /**

+      getComponentType

+      

+      This function is to get class member "componentType".

+      

+      @return                 string of componentType

+    **/

+    public String getComponentType() {

+        return this.componentType;

+    }

+

+    /**

+      setComponentType

+      

+      This function is to set class member "componentType".

+      @param  componentType   string of component type

+    **/

+    public void setComponentType(String componentType) {

+        this.componentType = " " + componentType;

+    }

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenCRC32SectionTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenCRC32SectionTask.java
new file mode 100644
index 0000000..33115aa
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenCRC32SectionTask.java
@@ -0,0 +1,183 @@
+/** @file

+ GenCRC32SectionTask class.

+

+ GenCRC32SectionTask is to call GenCRC32Section.exe to generate crc32 section.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+package org.tianocore.framework.tasks;

+

+import java.util.*;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+/**

+  GenCRC32SectionTask

+  

+  GenCRC32SectionTask is to call GenCRC32Section.exe to generate crc32 section. 

+  

+**/

+public class GenCRC32SectionTask extends Task implements EfiDefine{

+    ///

+    /// output file

+    ///

+    private String outputFile;

+    ///

+    /// inputFile list

+    ///

+    private List<Object> inputFileList = new ArrayList<Object>();

+    

+    ///

+    /// Project

+    ///

+    static private Project project;

+    

+    /**

+      execute

+      

+      GenCRC32SectionTask execute is to assemble tool command line & execute

+      tool command line

+      

+      @throws BuildException

+    **/

+    public void execute() throws BuildException {

+        

+        project = this.getOwningTarget().getProject(); 

+        ///

+        /// absolute path of efi tools

+        ///

+        String path = project.getProperty("env.Framework_Tools_Path"); 

+        String command;

+        if (path == null) {

+            command = "GenCRC32Section";

+        } else {

+            command = path + "/" + "GenCRC32Section" ;

+        }

+        // 

+        // string line of input files 

+        // 

+        String inputFiles = list2Str(inputFileList, ""); 

+        // 

+        // assemble argument 

+        //

+        String argument =  inputFiles + outputFile; 

+        // 

+        // return value of fwimage execution 

+        //

+        int revl = -1; 

+        

+        try {

+            Commandline cmdline = new Commandline();

+            cmdline.setExecutable(command);

+            cmdline.createArgument().setLine(argument);

+            

+            LogStreamHandler streamHandler = new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN);

+            Execute runner = new Execute(streamHandler, null);

+            

+            runner.setAntRun(project);

+            runner.setCommandline(cmdline.getCommandline());

+            System.out.println(Commandline.toString(cmdline.getCommandline()));

+            

+            revl = runner.execute();

+            if (EFI_SUCCESS == revl){

+                //

+                //  command execution success 

+                //

+                System.out.println("gencrc32section succeeded!");

+            }

+            else

+            {

+                // 

+                // command execution fail

+                //

+                System.out.println("gencrc32section failed. (error=" + 

+                    Integer.toHexString(revl) + 

+                    ")"

+                    );

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+        

+    }

+

+    /**

+      addInputFile

+     

+      This function is to add a inputFile element into list

+      @param inputFile : inputFile element

+    **/

+    public void addInputfile(InputFile inputFile) {

+        inputFileList.add(inputFile);

+    }

+    

+    /**

+     get class member "outputFile"

+     * @return name of output file

+     */

+    public String getOutputFile() {

+        return this.outputFile;

+    }

+    /**

+     * set class member "outputFile"

+     * @param outputFile : outputFile parameter 

+     */

+    public void setOutputFile(String outputFile) {

+        this.outputFile = " -o " + outputFile;

+    };

+    

+    /**

+     * transfer List to String

+     * @param list : nested element list

+     * @param tag : interval tag of parameter

+     * @return string line of parameters 

+     */

+    private String list2Str(List list, String tag) {

+        /*

+         * string line for return

+         */

+        String paraStr = " -i"; 

+        /*

+         * nested element in list

+         */

+        NestElement element; 

+        /*

+         * iterator of nested element list

+         */

+        Iterator elementIter = list.iterator(); 

+        /*

+         * string parameter list

+         */

+        List<Object> strList = new ArrayList<Object>();   

+        

+        while (elementIter.hasNext()) {

+            element = (NestElement) elementIter.next();

+            if (null != element.getFile()) {

+                FileParser.loadFile(project, strList, element.getFile(), tag);

+            } else {

+                paraStr = paraStr + element.getName();

+            }

+        }

+        /*

+         * iterator of string parameter list

+         */

+        Iterator strIter = strList.iterator();  

+        while (strIter.hasNext()) {

+            paraStr = paraStr + " " + strIter.next();

+        }

+        return paraStr;

+    }   

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenDepexTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenDepexTask.java
new file mode 100644
index 0000000..8713945
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenDepexTask.java
@@ -0,0 +1,166 @@
+/** @file

+ GenDepexTask class.

+

+ GenDepexTask is to call GenDepex.exe to generate depex section.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+/**

+  GenDepexTask

+  

+  GenDepexTask is to call GenDepex.exe to generate depex section.

+

+**/

+public class GenDepexTask extends Task implements EfiDefine {

+    ///

+    /// output binary dependency files name

+    ///

+    private String outputFile = "";

+    ///

+    /// input pre-processed dependency text files name

+    ///

+    private String inputFile = "";

+    ///

+    /// padding integer value

+    ///

+    private String padding = "";

+    /**

+      execute

+      

+      GenDepexTask execute is to assemble tool command line & execute tool

+      command line.

+     */

+    public void execute() throws BuildException {

+

+        Project project = this.getOwningTarget().getProject();

+        //

+        // absolute path of edk tools

+        //

+        String path = project.getProperty("env.Framework_Tools_Path");

+        String command;

+        if (path == null) {

+            command = "GenDepex";

+        } else {

+            command = path + "/" + "GenDepex";

+        }

+        //

+        // argument of GenDepex tool

+        //

+        String argument = inputFile + outputFile + padding;

+        //

+        // reture value of GenDepex execution

+        //

+        int returnVal = -1;

+

+        try {

+            Commandline commandLine = new Commandline();

+            commandLine.setExecutable(command);

+            commandLine.createArgument().setLine(argument);

+

+            LogStreamHandler streamHandler = new LogStreamHandler(this,

+                    Project.MSG_INFO, Project.MSG_WARN);

+

+            Execute runner = new Execute(streamHandler, null);

+            runner.setAntRun(project);

+            runner.setCommandline(commandLine.getCommandline());

+

+            System.out.println(Commandline.toString(commandLine

+                    .getCommandline()));

+

+            returnVal = runner.execute();

+            if (EFI_SUCCESS == returnVal) {

+                //

+                // command execution success

+                //

+                System.out.println("GenDepex execute succeeded!");

+

+            } else {

+                //

+                // command execution fail

+                //

+                System.out.println("GenDepex failed. (error="

+                        + Integer.toHexString(returnVal) + ")");

+                throw new BuildException("GenDepex failed. (error="

+                        + Integer.toHexString(returnVal) + ")");

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+    /**

+      setOutputFile

+      

+      This function is to set class member "outputFile"

+      @param outputFileName        name of output file

+    **/

+    public void setOutputFile(String outputFileName) {

+        this.outputFile = " -O " + outputFileName;

+    }

+

+    /**

+      getOutputFile

+      

+      This function is to get class member "outputFile".

+     

+      @return name of ouput file

+    **/

+    public String getOutputFile() {

+        return this.outputFile;

+    }

+

+    /**

+      setInputFile

+      

+      This function is to set class member "inputFile".

+      @param inputFileName          name of inputFile

+    **/

+    public void setInputFile(String inputFileName) {

+        this.inputFile = " -I " + inputFileName;

+    }

+

+    /**

+      getInputFile

+      

+      This function is to get class member "inputFile"

+      @return                       name of input file

+    **/

+    public String getInputFile() {

+        return this.inputFile;

+    }

+

+    /**

+      setPadding

+      

+      This function is to set class member "padding"

+      @param paddingNum             padding value

+    **/

+    public void setPadding(String paddingNum) {

+        this.padding = " -P " + paddingNum;

+    }

+

+    /**

+      getPadding

+      

+      This function is to get class member "padding"

+      @return                       value of padding

+    **/

+    public String getPadding() {

+        return this.padding;

+    }

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFfsFileTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFfsFileTask.java
new file mode 100644
index 0000000..00712d8
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFfsFileTask.java
@@ -0,0 +1,878 @@
+/** @file

+ GenFfsFileTask class.

+

+ GenFfsFileTaks is to generate ffs file.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+

+/**

+  GenFfsFileTask

+  

+  GenFfsFileTaks is to generate ffs file.

+

+**/

+public class GenFfsFileTask extends Task implements EfiDefine, FfsTypes {

+    /**

+      *  GenFfsFile Task Class

+      *  class member 

+      *      -baseName               : module baseName

+      *      -ffsFileGuid            : module Guid.

+      *      -ffsFileType            : Ffs file type.  

+      *      -ffsAttributeRecovery   : The file is required for recovery.

+      *      -ffsAligment            : The file data alignment (0 if none required).  See FFS 

+      *                                specification for supported alignments (0-7 are only possible 

+      *                                 values).     *

+      *      -ffsAttributeCheckSum   : The file data is checksummed.  If this is FALSE a 

+      *                                value of 0x5A will be inserted in the file 

+      *                                checksum field of the file header.     *

+      *      -sectFileDir            : specifies the full path to the component build directory.

+      *                                Required.

+      *      -ffsAttrib              : Data recorde attribute added result.

+      *      -sectionList            : List recorded all section elemet in task.

+      */

+    ///

+    /// module baseName

+    ///

+    String  baseName        = "";

+    ///

+    /// module Guid

+    ///

+    String  ffsFileGuid        = "";

+    ///

+    /// Ffs file type

+    ///

+    String  ffsFileType        = "";

+    ///

+    /// ffsAttribHeaderExtension value is used to set the corresponding bit in 

+    /// the output FFS file header 

+    ///

+    boolean ffsAttribHeaderExtension = false;

+    ///

+    /// ffsAttribTailPresent value is used to set the corresponding bit in the 

+    /// output FFS file header

+    ///

+    boolean ffsAttribTailPresent     = false;

+    ///

+    /// ffsAttribRecovery value is used to set the corresponding bit in the 

+    /// output FFS file header

+    ///

+    boolean ffsAttribRecovery        = false;

+    ///

+    /// ffsAligenment value is used to set the corresponding bit in the output 

+    /// FFS file header.The specified FFS alignment must be a value between 0 

+    /// and 7 inclusive

+    ///

+    int     ffsAlignment       = 0;

+    ///

+    /// ffsAttribChecksum value is used to set the corresponding bit in the 

+    /// output FFS file header

+    ///

+    boolean FfsAttribChecksum        = false;

+    ///

+    /// Attribute is used to record the sum of all bit in the output FFS file.

+    ///

+    byte    attributes      = 0;

+    ///

+    /// The output directory of ffs file.

+    ///

+    String  outputDir       = "";

+    ///

+    /// List of section.

+    ///

+    List<Object> sectionList  = new ArrayList<Object>();

+

+    ///

+    /// The path of Framewor_Tools_Paht.

+    ///

+    static String path = "";  

+

+    /**

+      execute

+      

+      GenFfsFileTask execute is to generate ffs file according to input section 

+      dscriptive information.

+     */

+    public void execute() throws BuildException {

+        Section           sect;

+        int               fileSize;

+        int               fileDataSize;

+        File              ffsFile;

+        FfsHeader         ffsHeader = new FfsHeader();  

+        String            ffsSuffix = "";

+        String            outputPath = "";

+

+        //

+        //  Get Fraemwork_Tools_Path

+        //

+        Project pj = this.getOwningTarget().getProject();

+        path       = pj.getProperty("env.Framework_Tools_Path");

+

+        //

+        //  Check does the BaseName, Guid, FileType set value.

+        //

+        if (this.baseName.equals("")) {

+            throw new BuildException ("Must set BaseName!\n");

+        }

+

+        if (this.ffsFileGuid.equals("")) {

+            throw new BuildException ("Must set ffsFileGuid!\n");

+        }

+

+        if (this.ffsFileType.equals("")) {

+            throw new BuildException ("Must set ffsFileType!\n");

+        }

+

+        //

+        //  Create ffs file. File name = FfsFileGuid + BaseName + ffsSuffix.

+        //  If outputDir's value was set,  file will output to the outputDir.

+        //

+        ffsSuffix = TypeToSuffix (this.ffsFileType);

+        if (!this.outputDir.equals("")) {

+            String temp;

+            outputPath = this.outputDir;

+            temp       = outputPath.replace('\\', File.separatorChar);

+            outputPath = temp.replace('/', File.separatorChar);

+            if (outputPath.charAt(outputPath.length()-1) != File.separatorChar) {

+                outputPath = outputPath + File.separator;

+            }

+

+        }

+

+        ffsFile = new File (outputPath + this.ffsFileGuid + '-' + this.baseName + ffsSuffix);  

+        System.out.print("General Ffs file: file name is:\n");

+        System.out.print(outputPath + this.ffsFileGuid + '-' + this.baseName + ffsSuffix);

+        System.out.print("\n");

+

+        //

+        //  Create file output stream -- dataBuffer.

+        //   

+        try {

+            FileOutputStream dataFs     = new FileOutputStream (ffsFile.getAbsolutePath());

+            DataOutputStream dataBuffer = new DataOutputStream (dataFs);

+

+            //

+            //  Search SectionList find earch section and call it's 

+            //  ToBuffer function.

+            //

+            Iterator sectionIter = this.sectionList.iterator();

+            while (sectionIter.hasNext()) {

+                sect = (Section)sectionIter.next(); 

+

+                try {

+                    //

+                    //  The last section don't need 4 byte ffsAligment.

+                    //

+                    sect.toBuffer((DataOutputStream)dataBuffer);

+                } catch (Exception e) {

+                    throw new BuildException (e.getMessage());

+                }

+            }

+            dataBuffer.close();

+        } catch (Exception e) {

+            throw new BuildException (e.getMessage());

+        }

+

+        //

+        //  Creat Ffs file header

+        //

+        try {

+

+            //

+            //  create input stream to read file data

+            //

+            byte[] fileBuffer  = new byte[(int)ffsFile.length()];

+            FileInputStream fi = new FileInputStream (ffsFile.getAbsolutePath());

+            DataInputStream di = new DataInputStream (fi);

+            di.read(fileBuffer);

+            di.close(); 

+

+

+            //

+            //  Add GUID to header struct

+            //

+            if (this.ffsFileGuid != null) {

+                stringToGuid (this.ffsFileGuid, ffsHeader.name);

+            }

+

+            ffsHeader.ffsAttributes = this.attributes;

+            if ((ffsHeader.fileType = stringToType(this.ffsFileType))== -1) {

+                throw new BuildException ("FFS_FILE_TYPE unknow!\n");

+            }

+

+

+            //

+            //  Adjust file size. The function is used to tripe the last 

+            //  section padding of 4 binary boundary. 

+            //  

+            //

+            if (ffsHeader.fileType != EFI_FV_FILETYPE_RAW) {

+

+                fileDataSize = adjustFileSize (fileBuffer);

+

+            } else {

+                fileDataSize = fileBuffer.length;

+            }

+

+            //

+            //  1. add header size to file size

+            //

+            fileSize = fileDataSize + ffsHeader.getSize();

+

+            if ((ffsHeader.ffsAttributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {

+                if (ffsHeader.fileType == EFI_FV_FILETYPE_FFS_PAD) {

+

+                    throw new BuildException (

+                                             "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +

+                                             "invalid for PAD files"

+                                             );

+                }

+                if (fileSize == ffsHeader.getSize()) {

+                    throw new BuildException (

+                                             "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +

+                                             "invalid for 0-length files"

+                                             );            

+                }

+                fileSize = fileSize + 2;

+            }

+

+            //

+            //  2. set file size to header struct

+            //

+            ffsHeader.ffsFileSize[0] = (byte)(fileSize & 0x00FF);

+            ffsHeader.ffsFileSize[1] = (byte)((fileSize & 0x00FF00)>>8);

+            ffsHeader.ffsFileSize[2] = (byte)(((int)fileSize & 0xFF0000)>>16);

+

+            //

+            //  Fill in checksums and state, these must be zero for checksumming

+            //

+            ffsHeader.integrityCheck.header = calculateChecksum8 (

+                                                                 ffsHeader.structToBuffer(),

+                                                                 ffsHeader.getSize()

+                                                                 );

+

+            if ((this.attributes & FFS_ATTRIB_CHECKSUM) != 0) {

+                if ((this.attributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {

+                    ffsHeader.integrityCheck.file = calculateChecksum8 (

+                                                                       fileBuffer, 

+                                                                       fileDataSize

+                                                                       );

+                } else {

+                    ffsHeader.integrityCheck.file = calculateChecksum8 (

+                                                                       fileBuffer,

+                                                                       fileDataSize

+                                                                       );

+                }

+            } else {

+                ffsHeader.integrityCheck.file = FFS_FIXED_CHECKSUM;

+            }

+

+            //

+            //   Set the state now. Spec says the checksum assumes the state is 0.

+            //

+            ffsHeader.ffsState = EFI_FILE_HEADER_CONSTRUCTION | 

+                                 EFI_FILE_HEADER_VALID | 

+                                 EFI_FILE_DATA_VALID;

+

+

+            //

+            // create output stream to first write header data in file, then write sect data in file.

+            //

+            FileOutputStream headerFfs = new FileOutputStream (ffsFile.getAbsolutePath());

+            DataOutputStream ffsBuffer = new DataOutputStream (headerFfs);

+

+            //

+            //  Add header struct and file data to FFS file

+            //

+            ffsBuffer.write(ffsHeader.structToBuffer());

+            for (int i = 0; i< fileDataSize; i++) {

+                ffsBuffer.write(fileBuffer[i]);

+            }

+

+            //

+            //  If there is a tail, then set it

+            //

+            if ((this.attributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {

+                short tailValue ;

+                byte [] tailByte = new byte[2];

+

+                //

+                //  reverse tailvalue , integritycheck.file as hight byte, and 

+                //  integritycheck.header as low byte.

+                //

+                tailValue = (short)(ffsHeader.integrityCheck.header & 0xff);

+                tailValue = (short)((tailValue) | ((ffsHeader.integrityCheck.file << 8) & 0xff00)); 

+                tailValue = (short)~tailValue;

+

+                //

+                //  Change short to byte[2]

+                //

+                tailByte[0] = (byte)(tailValue & 0xff);

+                tailByte[1] = (byte)((tailValue & 0xff00)>>8);  

+                ffsBuffer.write(tailByte[0]);

+                ffsBuffer.write(tailByte[1]);

+            }

+

+            //

+            //  close output stream. Note if don't close output stream 

+            //  the buffer can't be rewritten to file. 

+            //

+            ffsBuffer.close();

+            System.out.print ("Successful create ffs file!\n");

+        } catch (Exception e) {

+            throw new BuildException (e.getMessage());

+        }

+    }   

+

+    /**

+      addCompress

+      

+      This function is to add compress section to section list.

+      @param compress   Section of compress   

+    **/

+    public void addCompress(CompressSection compress) {

+        this.sectionList.add(compress);

+    }

+

+    /**

+      addTool

+      

+      This function is to add tool section to section list.

+      @param tool       Section of tool

+    **/

+    public void addTool(Tool tool) {

+        this.sectionList.add(tool);

+    }

+

+    /**

+      addSectionFile

+      

+      This function is to add sectFile section to section list.

+      @param sectFile    Section of sectFile.

+    **/

+    public void addSectFile (SectFile sectFile) {

+        this.sectionList.add(sectFile);   

+    }

+

+    /**

+      getBaseName

+      

+      This function is to get basename

+      

+      @return              String of base name

+    **/

+    public String getBaseName() {

+        return this.baseName;

+    }

+

+    /**

+      setBaseName

+      

+      This function is to set base name.

+      @param  baseName

+    **/

+    public void setBaseName(String baseName) {

+        this.baseName = baseName.trim();

+    }

+

+    /**

+      getFfsAligment

+      

+      This function is to get the ffsAligment

+      @return  The value of ffsAligment.

+    **/

+    public int getFfsAligment() {

+        return this.ffsAlignment;

+    }

+

+    /**

+      setFfsAligment

+      

+      This function is to set ffsAligment 

+      @param  ffsAligment     The value of ffsAligment.

+    **/

+    public void setFfsAligment(int ffsAligment) {

+        this.ffsAlignment = ffsAligment;

+        if (this.ffsAlignment > 7) {

+            throw new BuildException ("FFS_ALIGMENT Scope is 0-7");

+        } else {

+            attributes |= (((byte)this.ffsAlignment) << 3);

+        }

+    }

+

+    /**

+      getFfsAttribCheckSum

+      

+      This function is to get ffsAttribCheckSum

+      

+      @return                      Value of ffsAttribChecksum 

+    **/

+    public boolean getFfsAttribChecksum() {

+        return this.FfsAttribChecksum;

+    }

+

+    /**

+      setFfsAttribChecksum

+      

+      This function is to set ffsAttribChecksum

+      @param ffsAttributeCheckSum  Value of ffsAttribCheckSum

+    **/

+    public void setFfsAttribChecksum(boolean ffsAttributeCheckSum) {

+        this.FfsAttribChecksum = ffsAttributeCheckSum;

+        if (ffsAttributeCheckSum) {

+            attributes |= FFS_ATTRIB_CHECKSUM;

+        }

+    }

+

+    /**

+      getFfsAttribRecovery

+      

+      This function is to get ffsAttribRecovery

+      @return                        Value of ffsAttribRecovery

+    **/

+    public boolean getFfsAttribRecovery() {

+        return this.ffsAttribRecovery;

+    }

+

+    /**

+      setRecovery

+      

+      This function is to set ffsAttributeRecovery

+      

+      @param  ffsAttributeRecovery    Value of ffsAttributeRecovery

+    **/

+    public void setRecovery(boolean ffsAttributeRecovery) {

+        this.ffsAttribRecovery = ffsAttributeRecovery;

+        if (ffsAttributeRecovery) {

+            attributes |= FFS_ATTRIB_RECOVERY;

+        }

+    }

+

+    /**

+      getFileGuid

+      

+      This function is to get fileGuid

+      @return          Guid

+    **/

+    public String getFileGuid() {

+        return this.ffsFileGuid;

+    }

+

+    /**

+      setFileGuid

+      

+      This function is to set fileGuid

+      @param ffsFileGuid    String of GUID

+    **/

+    public void setFileGuid(String ffsFileGuid) {

+        this.ffsFileGuid = ffsFileGuid.trim();

+    }

+

+    /**

+      getFfsFileType

+      

+      This function is to get ffsFileType.

+      

+      @return               value of ffsFileType

+    **/

+    public String getFfsFileType() {

+        return this.ffsFileType;

+    }

+

+    /**

+      setFfsFileType

+      

+      This function is to set ffsFileType.

+      

+      @param ffsFileType      

+    **/

+    public void setFfsFileType(String ffsFileType) {

+        this.ffsFileType = ffsFileType.trim();

+    }

+

+    /**

+      ffsAttribHeaderExtension

+      

+      This function is to get ffsAttribHeaderExtension

+      

+      @return             Value of ffsAttribHeaderExtension

+    **/

+    public boolean isFfsAttribHeaderExtension() {

+        return this.ffsAttribHeaderExtension;

+    }

+

+    /**

+      setHeaderExension

+      

+      This function is to set headerExtension

+      @param headerExtension     Value of headerExension

+    **/

+    public void setHeaderExtension(boolean headerExtension) {

+        this.ffsAttribHeaderExtension = headerExtension;

+        if (headerExtension) {

+            attributes |= FFS_ATTRIB_HEADER_EXTENSION;

+        }

+    }

+

+    /**

+      isFfsAttribTailPresent

+      

+      This function is to get ffsAttribTailPresent value.

+      @return          Value of ffsAttribTailPresent.

+    **/

+    public boolean isFfsAttribTailPresent() {

+        return this.ffsAttribTailPresent;

+    }

+

+    /**

+      setFfsAttribTailPresent

+      

+      This function is to set ffsAttribTailPresent.

+      @param tailPresent  Value of ffsAttribTailPresent.

+    **/

+    public void setFfsAttribTailPresent(boolean tailPresent) {

+        this.ffsAttribTailPresent = tailPresent;

+        if (tailPresent) {

+            attributes |= FFS_ATTRIB_TAIL_PRESENT;

+        }

+    }   

+

+

+    /**

+      stringToGuid

+      

+      This function is to convert string to GUID.

+     * @param GuidStr         String of GUID.

+     * @param Guid            GUID form.

+     */

+    private void stringToGuid (String GuidStr, FfsHeader.FfsGuid Guid){   

+

+        int i  = 0;

+        int j  = 0;

+        int k  = 0;

+        char   [] charArry;

+        String [] SplitStr;

+

+        byte[] buffer = new byte[16];

+        if (GuidStr.length()!=36) {

+            throw new BuildException ("Guid length is not correct!");

+        }

+

+

+        SplitStr = GuidStr.split("-");

+        if (SplitStr.length != 5) {

+            throw new BuildException ("Guid type is not correct!");

+        }

+

+

+

+        for (i= 0; i < SplitStr.length; i++) {

+            String str = SplitStr[i];         

+            charArry   = str.toCharArray();

+

+            for (j =0; j < (str.toCharArray().length)/2; j++) {

+

+                buffer[k] = hexCharToByte (charArry[j*2]);        

+                buffer[k] = (byte)( buffer[k]& 0x0f);       

+                buffer[k] = (byte)((buffer[k]<< 4));

+                buffer[k] = (byte)( buffer[k]& 0xf0);       

+                buffer[k] = (byte)( buffer[k]|hexCharToByte(charArry[j*2+1]));

+                k++;            

+            }

+        }

+        Guid.bufferToStruct(buffer);

+    }

+

+    /**

+      typeToSuffix

+      

+      This function is to get suffix of ffs file according to ffsFileType.

+      

+      @param  ffsFileType    ffsFileType

+      @return                The suffix of ffs file

+    **/

+    private String TypeToSuffix (String ffsFileType){

+        if (ffsFileType.equals("EFI_FV_FILETYPE_ALL")) {

+            return "";

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_RAW")) {

+            return EFI_FV_FFS_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_FREEFORM")) {

+            return EFI_FV_FFS_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_SECURITY_CORE")) {

+            return EFI_FV_SEC_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_PEI_CORE")) {

+            return EFI_FV_PEI_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_DXE_CORE")) {

+            return EFI_FV_DXE_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_PEIM")) {

+            return EFI_FV_PEI_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_DRIVER")) {

+            return  EFI_FV_DXE_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER")) {

+            return EFI_FV_PEI_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_APPLICATION")) {

+            return EFI_FV_APP_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE")) {

+            return EFI_FV_FVI_FILETYPE_STR;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_FFS_PAD")) {

+            return EFI_FV_FFS_FILETYPE_STR;

+        }

+        return "";

+    }

+

+

+    /**

+      stringToType

+      

+      This function is to get ffsFileType integer value according to ffsFileType.

+      @param   ffsFileType       String value of ffsFileType

+      @return                    Integer value of ffsFileType.

+    **/

+    private byte stringToType (String ffsFileType){

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_ALL")) {

+            return(byte)EFI_FV_FILETYPE_ALL;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_RAW")) {

+            return(byte)EFI_FV_FILETYPE_RAW;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_FREEFORM")) {

+            return(byte)EFI_FV_FILETYPE_SECURITY_CORE;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_SECURITY_CORE")) {

+            return(byte)EFI_FV_FILETYPE_SECURITY_CORE;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_PEI_CORE")) {

+            return(byte) EFI_FV_FILETYPE_PEI_CORE;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_DXE_CORE")) {

+            return(byte)EFI_FV_FILETYPE_DXE_CORE;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_PEIM")) {

+            return(byte)EFI_FV_FILETYPE_PEIM;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_DRIVER")) {

+            return(byte) EFI_FV_FILETYPE_DRIVER;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER")) {

+            return(byte)EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_APPLICATION")) {

+            return(byte)EFI_FV_FILETYPE_APPLICATION;

+        }

+

+        if (ffsFileType.equals("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE")) {

+            return(byte)EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE;

+        }

+        if (ffsFileType.equals("EFI_FV_FILETYPE_FFS_PAD")) {

+            return(byte) EFI_FV_FILETYPE_FFS_PAD;

+        }

+

+        return -1;

+    }

+

+

+

+    /**

+      calculateCheckSum8

+      

+      This function is to calculate the value needed for a valid UINT8 checksum

+      @param  buffer  Byte buffer containing byte data of component.

+      @param  size    Size of the buffer.

+      @return         The 8 bit checksum value needed.

+    **/

+    private byte calculateChecksum8 (byte[] buffer, int size){

+        return(byte) (0x100 - calculateSum8 (buffer, size));

+    }

+

+

+    /**

+      calculateSum8

+      

+      This function is to calculate the UINT8 sum for the requested region.

+      @param buffer   Byte buffer containing byte data of component

+      @param size     Size of the buffer.

+      @return         The 8 bit checksum value needed.

+    **/ 

+    private short calculateSum8 (byte[] buffer, int size){

+        int   Index;

+        byte  Sum;

+        Sum   = 0;

+

+        //

+        // Perform the word sum for buffer

+        //

+        for (Index = 0; Index < size; Index++) {

+            Sum = (byte) (Sum + buffer[Index]);     

+        }

+

+        return(byte) Sum; 

+    }

+

+    /**

+      hexCharToByte

+      

+      This function is to convert hex character to byte

+      

+      @param     hexChar          hex character

+      @return                     Byte which corresponding to the character.

+    **/

+    private byte hexCharToByte (char hexChar){

+        switch (hexChar) {

+        case '0':

+            return(byte)0x00;

+        case '1':

+            return(byte)0x01;

+        case '2':

+            return(byte)0x02;

+        case '3':

+            return(byte)0x03;

+        case '4':

+            return(byte)0x04;

+        case '5':

+            return(byte)0x05;

+        case '6':

+            return(byte)0x06;

+        case '7':

+            return(byte)0x07;

+        case '8':

+            return(byte)0x08;

+        case '9':

+            return(byte)0x09;

+        case 'a':

+        case 'A':

+            return(byte)0x0a;

+        case 'b':

+        case 'B':

+            return(byte)0x0b;

+        case 'c':

+        case 'C':

+            return(byte)0x0c;

+

+        case 'd':

+        case 'D':           

+            return(byte)0x0d;

+

+        case 'e':

+        case 'E':

+            return(byte)0x0e;

+        case 'f':

+        case 'F':

+            return(byte)0x0f;

+

+        default:

+            return(byte)0xff;  

+        }

+    }

+

+    /**

+      adjustFileSize

+      

+      This function is used to adjusts file size to insure sectioned file is exactly the right length such

+      that it ends on exactly the last byte of the last section.  ProcessScript()

+      may have padded beyond the end of the last section out to a 4 byte boundary.

+      This padding is stripped.  

+      

+      @param    buffer  Byte buffer contains a section stream

+      @return           Corrected size of file.

+    **/

+    private int adjustFileSize (byte[] buffer){ 

+

+        int orignalLen         = buffer.length;

+        int adjustLen          = 0;

+        int sectionPoint       = 0;

+        int nextSectionPoint   = 0;

+        int sectionLen         = 0;

+        int totalLen           = 0;

+        int firstSectionHeader = 0;

+

+

+        firstSectionHeader = buffer[0]& 0xff;

+        firstSectionHeader = ((buffer[1]&0xff)<<8) | firstSectionHeader;

+        firstSectionHeader = ((buffer[2]&0xff)<<16)| firstSectionHeader;

+

+

+        while (sectionPoint < buffer.length) {

+            sectionLen = buffer[0 + sectionPoint]& 0xff;

+            sectionLen = ((buffer[1 + sectionPoint]&0xff)<<8)| sectionLen;

+            sectionLen = ((buffer[2 + sectionPoint]&0xff)<<16)| sectionLen; 

+            totalLen   = totalLen + sectionLen;

+

+            if (totalLen == orignalLen) {

+                return totalLen;

+            }

+

+            sectionPoint     = sectionPoint + sectionLen;

+            adjustLen        = sectionPoint;

+

+            nextSectionPoint = (sectionPoint + 0x03) & (~0x03);

+            totalLen         = totalLen + nextSectionPoint - sectionLen;

+            sectionPoint     = nextSectionPoint;

+        }

+        return adjustLen;

+    }

+

+    /**

+      getOutputDir

+      

+      This function is to get output directory.

+      

+      @return                Path of output directory.

+    **/

+    public String getOutputDir() {

+        return outputDir;

+    }

+

+    /**

+      setOutputDir

+      

+      This function is to set output directory.

+      

+      @param outputDir        The output direcotry.

+    **/

+    public void setOutputDir(String outputDir) {

+        this.outputDir = outputDir;

+    }

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFvImageTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFvImageTask.java
new file mode 100644
index 0000000..6f3cd7b
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFvImageTask.java
@@ -0,0 +1,176 @@
+/** @file

+ GenFvImageTask class.

+

+ GenFvImageTask is to call GenFvImage.exe to generate FvImage.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+import java.io.File;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.InputStreamReader;

+import java.lang.ProcessBuilder;

+import java.util.ArrayList;

+import java.util.LinkedList;

+import java.util.List;

+import java.util.Map;

+

+/**

+  GenFvImageTask

+  

+  GenFvImageTask is to call GenFvImage.exe to generate the FvImage.

+  

+**/

+public class GenFvImageTask extends Task implements EfiDefine{

+    ///

+    /// tool name

+    ///

+    static final private String toolName = "GenFvImage";

+    ///

+    /// The name of input inf file

+    ///

+    private String infFile="";

+    ///

+    /// The target architecture.

+    ///

+    private String arch="";

+    ///

+    /// Output directory

+    ///

+    private String outputDir = ".";

+    ///

+    /// argument list

+    ///

+    LinkedList<String> argList = new LinkedList<String>();

+

+    /**

+      execute

+      

+      GenFvImageTask execute is to assemble tool command line & execute tool

+      command line.

+    **/

+    public void execute() throws BuildException  {

+        Project project = this.getOwningTarget().getProject();

+        String path = project.getProperty("env.Framework_Tools_Path");

+        if (path == null) {

+            path = "";

+        } else {

+            path += File.separatorChar;

+        }

+

+        if (arch != null && arch.length() > 0) {

+            argList.addFirst(path + toolName + "_" + arch);

+        } else {

+            argList.addFirst(path + toolName);

+        }

+

+        ///

+        /// lauch the program

+        ///

+        ProcessBuilder pb = new ProcessBuilder(argList);

+        pb.directory(new File(outputDir));

+        int exitCode = 0;

+        try {

+            Process cmdProc = pb.start();

+            InputStreamReader cmdOut = new InputStreamReader(cmdProc.getInputStream());

+            char[] buf = new char[1024];

+

+            exitCode = cmdProc.waitFor();

+            if (exitCode != 0) {

+                int len = cmdOut.read(buf, 0, 1024);

+                log(new String(buf, 0, len), Project.MSG_ERR);

+            } else {

+                log("GenFvImage - DONE!", Project.MSG_VERBOSE);

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        } finally {

+            if (exitCode != 0) {

+                throw new BuildException("GenFvImage: failed to generate FV file!");

+            }

+        }

+

+    }

+    /**

+      getInfFile

+      

+      This function is to get class member of infFile

+      @return String    name of infFile

+    **/

+    public String getInfFile() {

+        return infFile;

+    }

+    

+    /**

+      setInfFile

+      

+      This function is to set class member of infFile.

+      

+      @param infFile  name of infFile

+    **/

+    public void setInfFile(String infFile) {

+        this.infFile = infFile;

+        argList.add("-I");

+        argList.add(infFile);

+    }

+    

+    /**

+      getArch

+      

+      This function is to get class member of arch.

+      @return           The target architecture.

+    **/

+    public String getArch() {

+        return arch;

+    }

+    

+    /**

+      setArch

+      

+      This function is to set class member of arch. 

+      

+      @param arch       The target architecture.

+    **/

+    public void setArch(String arch) {

+        this.arch = arch;

+    }

+

+    /**

+      getOutputDir

+      

+      This function is to get output directory.

+      

+      @return                Path of output directory.

+    **/

+    public String getOutputDir() {

+        return outputDir;

+    }

+

+    /**

+      setOutputDir

+      

+      This function is to set output directory.

+      

+      @param outputDir        The output direcotry.

+    **/

+    public void setOutputDir(String outputDir) {

+        this.outputDir = outputDir;

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenSectionTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenSectionTask.java
new file mode 100644
index 0000000..61aefa6
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenSectionTask.java
@@ -0,0 +1,215 @@
+/** @file

+ GenSectionTask class.

+

+ GenSectionTask is to call GenSection.exe to generate Section.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+**/

+

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+public class GenSectionTask extends Task implements EfiDefine {

+    ///

+    /// inputfile name

+    ///

+    private String inputFile = "";

+    ///

+    /// outputfile name

+    ///

+    private String outputFile = "";

+    ///

+    /// section type

+    ///

+    private String sectionType = "";

+    ///

+    /// version number

+    ///

+    private String versionNum = "";

+    ///

+    /// interface string

+    ///

+    private String interfaceString = "";

+

+    /**

+      execute

+      

+      GenSectionTaks execute is to assemble tool command line & execute tool

+      command line.

+      

+      @throws BuildException

+    **/

+    public void execute() throws BuildException {

+        String command;

+        Project project = this.getOwningTarget().getProject();

+        //

+        // absolute path of efi tools

+        //

+        String path = project.getProperty("env.Framework_Tools_Path");

+        if (path == null) {

+            command = "GenSection";

+        } else {

+            command = path + "/" + "GenSection";

+        }

+        //

+        // argument of tools

+        //

+        String argument = inputFile + outputFile + sectionType + versionNum

+                + interfaceString;

+        //

+        // return value of gensection execution

+        //

+        int revl = -1;

+

+        try {

+            Commandline cmdline = new Commandline();

+            cmdline.setExecutable(command);

+            cmdline.createArgument().setLine(argument);

+

+            LogStreamHandler streamHandler = new LogStreamHandler(this,

+                    Project.MSG_INFO, Project.MSG_WARN);

+            Execute runner = new Execute(streamHandler, null);

+

+            runner.setAntRun(project);

+            runner.setCommandline(cmdline.getCommandline());

+            System.out.println(Commandline.toString(cmdline.getCommandline()));

+

+            revl = runner.execute();

+            if (EFI_SUCCESS == revl) {

+                //

+                // command execution success

+                //

+                System.out.println("gensection succeeded!");

+            } else {

+                //

+                // command execution fail

+                //

+                System.out.println("gensection failed. (error="

+                        + Integer.toHexString(revl) + ")");

+                throw new BuildException("gensection failed. (error="

+                        + Integer.toHexString(revl) + ")");

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+    /**

+      getInputFile

+      

+      This function is to get class member "inputFile".

+      

+      @return                    name of input file

+    **/

+    public String getInputFile() {

+        return this.inputFile;

+    }

+

+    /**

+      setInputFile

+      

+      This function is to set class member "inputFile".

+      

+      @param inputFile            name of input file

+    **/

+    public void setInputFile(String inputFile) {

+        this.inputFile = " -i " + inputFile;

+    }

+

+    /**

+      getOutputFile

+      

+      This function is to get class member "outputFile".

+      

+      @return                      name of output file

+    **/

+    public String getOutputFile() {

+        return this.outputFile;

+    }

+

+    /**

+      setOutputfile

+      

+      This function is to set class member "outputFile".

+      @param  outputFile            name of output file

+    **/

+    public void setOutputfile(String outputFile) {

+        this.outputFile = " -o " + outputFile;

+    }

+

+    /**

+      getSectionType

+      

+      This function is to get class member "sectionType".

+      

+      @return                        sectoin type

+    **/

+    public String getSectionType() {

+        return this.sectionType;

+    }

+

+    /**

+      setSectionType

+      

+      This function is to set class member "sectionType".

+      

+      @param sectionType              section type

+    **/

+    public void setSectionType(String sectionType) {

+        this.sectionType = " -s " + sectionType;

+    }

+

+    /**

+      getVersionNum

+      

+      This function is to get class member "versionNum".

+      @return                         version number

+    **/

+    public String getVersionNum() {

+        return this.versionNum;

+    }

+

+    /**

+      setVersionNume

+      

+      This function is to set class member "versionNum".

+      @param versionNum               version number

+    **/

+    public void setVersionNum(String versionNum) {

+        this.versionNum = " -v " + versionNum;

+    }

+

+    /**

+      getInterfaceString

+      

+      This function is to get class member "interfaceString".

+      @return                         interface string

+    **/

+    public String getInterfaceString() {

+        return this.interfaceString;

+    }

+

+    /**

+      setInterfaceString

+      

+      This funcion is to set class member "interfaceString".

+      @param interfaceString            interface string

+    **/

+    public void setInterfaceString(String interfaceString) {

+        this.interfaceString = " -a " + "\"" + interfaceString + "\"";

+    }

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GuidChkTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GuidChkTask.java
new file mode 100644
index 0000000..69feb4e
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GuidChkTask.java
@@ -0,0 +1,367 @@
+/** @file

+ GuidChkTask class.

+

+ GuidChkTask is to call GuidChk.exe to generate Section.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+**/

+package org.tianocore.framework.tasks;

+import java.io.BufferedReader;

+import java.io.InputStreamReader;

+import java.io.PrintWriter;

+import java.io.File;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+

+/**

+  GuidChkTask

+  

+  GuidChkTask is to call GuidChk.exe to generate Section.

+  

+**/

+public class GuidChkTask extends Task implements EfiDefine{

+    /**

+     *  GuidChk task class

+     *  class member

+     *    -exDir   : directory name of exclusion searching  

+     *    -exFile  : file name of exclusion searching

+     *    -exExt   : extension name of exclusion searching

+     *    -exSubDir: extesnion name of sub dir which excluded searching

+     *    -outFile : out put file wrote internal GUID+basename list

+     *    -chkGui  : check for duplicate guids

+     *    -chkSign : check for duplicate signatures

+     *    -printGuiDef : if set will print guid+defined symbol name

+     *    -printAllGuid: if set will print all GUIDS found

+     *    -outPut  : redirection file name

+     *    -fos     : out put redirect to this file 

+     *    

+     */

+    ///

+    /// Directory name of exclusion searching 

+    ///

+    private String exDir = "";

+    ///

+    /// File name of exclusion searching.

+    ///

+    private String exFile = "";

+    ///

+    /// Extension name of exclusion searching.

+    ///

+    private String exExt = "";

+    ///

+    /// Extesnion name of sub dir which excluded searching.

+    ///

+    private String exSubDir = "";

+    ///

+    /// Out put file wrote internal GUID+basename list

+    ///

+    private String outFile = "";

+    ///

+    /// Check for duplicate guids.

+    ///

+    private String chkGui = "";

+    ///

+    /// Check for duplicate signatures

+    ///

+    private String chkSign = "";

+    ///

+    /// If set will print guid+defined symbol name

+    ///

+    private String printGuiDef = "";

+    ///

+    /// If set will print all GUIDS found

+    ///

+    private String printAllGuid = "";

+    ///

+    /// redirection file name.

+    ///

+    private String outPut = "";

+    ///

+    /// out put redirect to this file.

+    ///

+    protected PrintWriter fos = null;

+    

+    //

+    // overload class execute method

+    //   

+    public void execute() throws BuildException {

+        Project project = this.getOwningTarget().getProject();

+        String path = project.getProperty("env.Framework_Tools_Path");

+        String command;

+        if (path == null) {

+            command = "GuidChk";

+        } else {

+            command = path + File.separatorChar + "GuidChk";

+        }

+        String argument = exDir +

+                          exFile +

+                          exExt +

+                          exSubDir +

+                          outFile +

+                          chkGui +

+                          chkSign +

+                          printGuiDef + 

+                          printAllGuid;     

+        try {

+            System.out.println(command + " " + argument);

+            //

+            // execute command line 

+            //

+            Process proc = Runtime.getRuntime().exec(command + "" + argument);

+            //

+            // if set output, redirect out put to output file, else print output to screen

+            //         

+            if ( !this.outPut.equals("")) {

+                fos = new PrintWriter(this.outPut);

+                BufferedReader bin = new BufferedReader(new InputStreamReader(proc.getInputStream()));

+                String line = bin.readLine();

+                while (line != null ){                  

+                fos.println(line);

+                line = bin.readLine();

+                }

+                fos.close();

+            }

+            else {

+                BufferedReader bin = new BufferedReader(new InputStreamReader(proc.getInputStream()));

+                String line = bin.readLine();

+                System.out.println(line);

+                while (line != null ){

+                    System.out.print(line);

+                    line = bin.readLine();

+                }               

+            }                      

+            System.out.println("GuidChkTask Success!");

+        } catch (Exception e) {

+            System.out.println("GuidChkTask failed!");

+            System.out.println(e.getMessage());

+            

+        }

+    }

+    /**

+      getChkGui

+      

+      This function is to get the string of flag of ChkGui

+      

+      @return                     string of flag of ChkGui

+    **/

+    public String getChkGui() {

+        return chkGui;

+    }

+    

+    /**

+      setChkGui

+      

+      This function is to set chkGui

+      

+      @param chkGui               set class member of chkGui

+    **/

+    public void setChkGui(String chkGui) {

+        if (chkGui.equals("on")||(chkGui.equals("ON"))){

+            this.chkGui = " -g ";

+        }

+        

+    }

+    

+    /**

+      getChkSign

+      

+      This function is to get chkSign

+      

+      @return                  chkSign

+    **/

+    public String getChkSign() {

+        return chkSign;

+    }

+    

+    /**

+      setChkSign

+      

+      This function is to set class member of chkSign

+     * @param chkSign

+     */

+    public void setChkSign(String chkSign) {

+        if (chkSign.equals("on")|| chkSign.equals("ON")){

+            this.chkSign = " -s ";

+        }       

+    }

+    /**

+      getExDir

+      

+      This function is to get class member of exDir

+      

+      @return                 exDir

+    **/

+    public String getExDir() {

+        return exDir;

+    }

+    

+    /**

+      setExDir

+      

+      This function is to set class member of exDir

+      

+      @param                   exDir

+    **/

+    public void setExDir(String exDir) {

+        this.exDir = " -d " + exDir;

+    }

+    

+    /**

+      getExExt

+      

+      This function is to get class member of exExt

+      

+      @return                    exExt

+    **/

+    public String getExExt() {

+        return exExt;

+    }

+    

+    /**

+      setExExt

+      

+      This function is to set class member of exExt

+      @param                      exExt

+    **/

+    public void setExExt(String exExt) {

+        this.exExt = " -e " + exExt;

+    }

+    

+    /**

+      getExFile

+      

+      This function is to get class member of exFile

+      @return                    exFile

+    **/

+    public String getExFile() {

+        return exFile;

+    }

+    

+    /**

+      setExFile

+      

+      This function is to set class member of exFile.

+      

+     @param                       exFile

+    **/

+    public void setExFile(String exFile) {

+        this.exFile = " -f " + exFile;

+    }

+    

+    /**

+      getExSubDir

+      

+      This function is to get class member of exSubDir

+      

+      @return                      exSubDir

+    **/

+    public String getExSubDir() {

+        return exSubDir;

+    }

+    

+    /**

+      setExSubDir

+      

+      This function is to set class member of exSubDir.

+     @param                         exSubDir

+    **/

+    public void setExSubDir(String exSubDir) {

+        this.exSubDir = " -u " + exSubDir;

+    }

+    

+    /**

+      getOutFile

+      

+      This function is to get outFile

+      

+     @return                        outFile

+    **/

+    public String getOutFile() {

+        return outFile;

+    }

+    /**

+     * set class member of outFile

+     * @param outFile

+     */

+    public void setOutFile(String outFile) {

+        this.outFile = " -b " + outFile;

+    }

+    /**

+      getPrintGuidDef

+      

+      This function is to get printGuidDef

+      

+      @return     flage of printing (guid+defined symbol name)

+    **/

+    public String getPrintGuiDef() {

+        return printGuiDef;

+    }

+    

+    

+    /**

+      setPrintGuidDef

+      

+      This function is to set class member of printGuiDef.

+      @param       printGuiDef

+    **/

+    public void setPrintGuiDef(String printGuiDef) {

+        if (printGuiDef.equals("on")|| printGuiDef.equals("ON")){

+            this.printGuiDef = " -x ";

+        }

+        

+    }

+    

+    /**

+      getOutput

+      

+      This function is to get output

+      

+      @return       name of outPut file

+    **/

+    public String getOutPut() {

+        return outPut;

+    }

+    

+    /**

+      setOutPut

+      

+      This function is to set class member of outPut.

+      @param outPut

+    **/

+    public void setOutPut(String outPut) {

+        this.outPut = outPut;

+    }

+    

+    /**

+      getPrintAllGuid

+      

+      This function is to get printAllGuid

+      @return         printAllGuid

+    **/

+    public String getPrintAllGuid() {

+        return printAllGuid;

+    }

+    

+    /**

+      setPrintAllGuid

+      

+      This function is to set class member of printAllGuid.

+      @param          printAllGuid

+    **/

+    public void setPrintAllGuid(String printAllGuid) {

+        if (printAllGuid.equals("on")||printAllGuid.equals("ON")) {

+            this.printAllGuid = " -p ";

+        }       

+    }

+}

+

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/IncludePath.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/IncludePath.java
new file mode 100644
index 0000000..3a30488
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/IncludePath.java
@@ -0,0 +1,123 @@
+/** @file

+This file is used to nest elements which is meant for include path name

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+

+package org.tianocore.framework.tasks;

+

+import java.io.File;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.StringTokenizer;

+

+public class IncludePath implements NestElement {

+    /**

+     IncludePath nested element Class

+     class member

+         -name : name of include path 

+         -file : name of file including include path

+     **/

+    private String path = "";

+    private File file;

+    private List<String> nameList = new ArrayList<String>();

+    

+    /**

+     get class member "file"

+

+     @returns   The File object

+     **/

+    public File getFile() {

+        return this.file;

+    }

+

+    /**

+     set class member "file"

+

+     @param     file    The name of include path

+     **/

+    public void setFile(File file) {

+        this.file = file;

+    }

+    

+    /**

+     get class member "file"

+

+     @returns   The name of include path

+     **/

+    public String getPath() {

+        return this.path;

+    }

+    

+    /**

+     get class member "name"

+

+     @returns   The name of include path

+     **/

+    public String getName() {

+        return this.path;

+    }

+    

+    /**

+     set class member "name"

+

+     @param     name    The name of include path

+     **/

+    public void setName(String name){

+        this.path = "-I " + name;

+    }

+

+    /**

+     set class member "path"

+

+     @param     name    name of file including include paths 

+     **/

+    public void setPath(String name) {

+        this.path = " -I " + name;

+    }

+

+    /**

+     override Object.toString()

+

+     @returns   name of file including include paths 

+     **/

+    public String toString() {

+        return getPath();

+    }

+ 

+    /**

+     set class member "list"

+

+     @param     fileNameList    name list of include paths, sperated by space, tab,

+                                comma or semi-comma

+     **/

+    public void setList(String fileNameList) {

+        if (fileNameList != null && fileNameList.length() > 0) {

+            StringTokenizer tokens = new StringTokenizer(fileNameList, " \t,;", false);

+            while (tokens.hasMoreTokens()) {

+                String fileName = tokens.nextToken().trim();

+                if (fileName.length() > 0) {

+                    this.nameList.add(fileName);

+                }

+            }

+        }

+    }

+

+    /**

+     get class member "list"

+

+     @returns   The include paths list.

+     **/

+    public List<String> getList() {

+        return nameList;

+    }

+}

+

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Input.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Input.java
new file mode 100644
index 0000000..b940e8d
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Input.java
@@ -0,0 +1,44 @@
+/** @file

+This file is used to nest elements which is meant for file path

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+/**

+ Input class is defined to be as nested elements of other elements, to specify 

+ the path of file(s)

+ **/

+public class Input {

+    private String filePath;

+    

+    public Input() {

+        

+    }

+

+    /**

+     Standard set method of ANT task, for "file" attribute

+

+     @param     path    The path of a file

+     **/

+    public void setFile(String path) {

+        filePath = path;

+    }

+

+    /**

+     Standard get method of ANT task, for "file" attribute

+

+     @returns   The path of current specified file.

+     **/

+    public String getFile() {

+        return filePath;

+    }

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/InputFile.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/InputFile.java
new file mode 100644
index 0000000..b08a380
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/InputFile.java
@@ -0,0 +1,95 @@
+/** @file

+This file is used to nest elements which is meant for specifying files

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.File;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.StringTokenizer;

+

+public class InputFile implements NestElement {

+    /**

+     InputFile nested element Class

+     class member

+         -name : name of input file 

+         -file : name of file including input files

+     **/

+    private String name = "";

+    private File file;

+    private List<String> nameList = new ArrayList<String>();

+    

+    /**

+     get class member "name"

+     @returns name parameter

+     **/

+    public String getName() {

+        return this.name;

+    }

+

+    /**

+     set class member "name"

+     @param     name    name of input file  

+     **/

+    public void setName(String name) {

+        this.name = " " + name;

+    }

+

+    public String toString() {

+        return getName();

+    }

+    

+    /**

+     get class member "file"

+     @returns file parameter

+     **/

+    public File getFile() {

+        return this.file;

+    }

+

+    /**

+     set class member "file"

+     @param     ext     name of file including input files  

+     **/

+    public void setFile(File file) {

+        this.file = file;

+    }

+

+    /**

+     set class member "list"

+

+     @param     fileNameList    name list of include paths, sperated by space, tab,

+                                comma or semi-comma

+     **/

+    public void setList(String fileNameList) {

+        if (fileNameList != null && fileNameList.length() > 0) {

+            StringTokenizer tokens = new StringTokenizer(fileNameList, " \t,;", false);

+            while (tokens.hasMoreTokens()) {

+                String fileName = tokens.nextToken().trim();

+                if (fileName.length() > 0) {

+                    this.nameList.add(fileName);

+                }

+            }

+        }

+    }

+

+    /**

+     get class member "list"

+

+     @returns   The include paths list.

+     **/

+    public List<String> getList() {

+        return nameList;

+    }

+}

+

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
new file mode 100644
index 0000000..a90d362
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
@@ -0,0 +1,443 @@
+/** @file

+This file is to wrap MakeDeps.exe tool as ANT task, which is used to generate

+dependency files for source code.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+import org.apache.tools.ant.types.Path;

+

+import java.io.File;

+import java.io.FileReader;

+import java.io.FileWriter;

+import java.io.IOException;

+import java.io.LineNumberReader;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+import java.util.StringTokenizer;

+import java.util.regex.Matcher;

+import java.util.regex.Pattern;

+

+/**

+ Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.

+ **/

+public class MakeDeps extends Task {

+

+    //

+    // private members, use set/get to access them

+    //

+    private static final String cmdName = "MakeDeps";

+    private static final String target  = "dummy";

+    private String              includePath = null;

+    private String              depsFile = null;

+    private String              subDir = null;

+    private boolean             quietMode = true;

+    private boolean             ignoreError = true;

+    private String              extraDeps = "";

+    private List<IncludePath>   includePathList = new ArrayList<IncludePath>();

+    private List<Input>         inputFileList = new ArrayList<Input>();

+

+    public MakeDeps() {

+

+    }

+

+    /**

+     The Standard execute method for ANT task. It will check if it's necessary

+     to generate the dependency list file. If no file is found or the dependency

+     is changed, it will compose the command line and call MakeDeps.exe to

+     generate the dependency list file.

+

+     @throws    BuildException

+     **/

+    public void execute() throws BuildException {

+        ///

+        /// check if the dependency list file is uptodate or not

+        ///

+        if (isUptodate()) {

+            return;

+        }

+

+        Project prj  = this.getOwningTarget().getProject();

+        String  toolPath = prj.getProperty("env.Framework_Tools_Path");

+        ///

+        /// compose full tool path

+        ///

+        if (toolPath == null || toolPath.length() == 0) {

+            toolPath = "./" + cmdName;

+        } else {

+            if (toolPath.endsWith("/") || toolPath.endsWith("\\")) {

+                toolPath = toolPath + cmdName;

+            } else {

+                toolPath = toolPath + "/" + cmdName;

+            }

+        }

+

+        ///

+        /// compose tool arguments

+        ///

+        StringBuffer args = new StringBuffer(4096);

+        if (ignoreError) {

+            args.append(" -ignorenotfound");

+        }

+        if (quietMode) {

+            args.append(" -q");

+        }

+        if (subDir != null && subDir.length() > 0) {

+            args.append(" -s ");

+            args.append(subDir);

+        }

+

+        ///

+        /// if there's no source files, we can do nothing about dependency

+        /// 

+        if (inputFileList.size() == 0) {

+            throw new BuildException("No source files specified to scan");

+        }

+

+        ///

+        /// compose source file arguments

+        ///

+        Iterator iterator = inputFileList.iterator();

+        while (iterator.hasNext()) {

+            Input inputFile = (Input)iterator.next();

+            args.append(" -f ");

+            args.append(cleanupPathName(inputFile.getFile()));

+        }

+

+        ///

+        /// compose search pathes argument

+        ///

+        StringBuffer includePathArg = new StringBuffer(4096);

+        if (includePath != null && includePath.length() > 0) {

+            StringTokenizer pathTokens = new StringTokenizer(includePath, ";");

+            while (pathTokens.hasMoreTokens()) {

+                String tmpPath = pathTokens.nextToken().trim();

+                if (tmpPath.length() == 0) {

+                    continue;

+                }

+

+                includePathArg.append(" -i ");

+                includePathArg.append(cleanupPathName(tmpPath));

+            }

+        }

+        iterator = includePathList.iterator();

+        while (iterator.hasNext()) {

+            IncludePath path = (IncludePath)iterator.next();

+            includePathArg.append(cleanupPathName(path.getPath()));

+        }

+        args.append(includePathArg);

+

+        ///

+        /// We don't need a real target. So just a "dummy" is given

+        ///

+        args.append(" -target dummy");

+        args.append(" -o ");

+        args.append(cleanupPathName(depsFile));

+

+        ///

+        /// prepare to execute the tool

+        ///

+        Commandline cmd = new Commandline();

+        cmd.setExecutable(toolPath);

+        cmd.createArgument().setLine(args.toString());

+

+        LogStreamHandler streamHandler = new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN);

+        Execute runner = new Execute(streamHandler, null);

+

+        runner.setAntRun(prj);

+        runner.setCommandline(cmd.getCommandline());

+

+        int result = 0;

+        try {

+            result = runner.execute();

+        } catch (IOException e) {

+            throw new BuildException(e.getMessage());

+        }

+

+        if (result != 0) {

+            log ("MakeDeps failed");

+            return;

+        }

+

+        // change the old DEP file format (makefile compatible) to just file list

+        if (!cleanup()) {

+            throw new BuildException(depsFile + " was not generated");

+        }

+    }

+

+    ///

+    /// Remove any duplicated path separator or inconsistent path separator

+    ///

+    private String cleanupPathName(String path) {

+        String separator = "\\" + File.separator;

+        String duplicateSeparator = separator + "{2}";

+        path = Path.translateFile(path);

+        path = path.replaceAll(duplicateSeparator, separator);

+

+        return path;

+    }

+

+    /**

+     Set method for "DepsFile" attribute

+

+     @param     name    The name of dependency list file

+     **/

+    public void setDepsFile(String name) {

+        depsFile = cleanupPathName(name);

+    }

+

+    /**

+     Get method for "DepsFile" attribute

+

+     @returns   The name of dependency list file

+     **/

+    public String getDepsFile() {

+        return depsFile;

+    }

+

+    /**

+     Set method for "IgnoreError" attribute

+

+     @param     ignore    flag to control error handling (true/false)

+     **/

+    public void setIgnoreError(boolean ignore) {

+        ignoreError = ignore;

+    }

+

+    /**

+     Get method for "IgnoreError" attribute

+

+     @returns   The value of current IgnoreError flag

+     **/

+    public boolean getIgnoreError() {

+        return ignoreError;

+    }

+

+    /**

+     Set method for "QuietMode" attribute

+

+     @param     quiet   flag to control the output information (true/false)

+     **/

+    public void setQuietMode(boolean quiet) {

+        quietMode = quiet;

+    }

+

+    /**

+     Get method for "QuietMode" attribute

+

+     @returns   value of current QuietMode flag

+     **/

+    public boolean getQuietMode() {

+        return quietMode;

+    }

+

+    /**

+     Set method for "SubDir" attribute

+

+     @param     dir     The name of sub-directory in which source files will be scanned

+     **/

+    public void setSubDir(String dir) {

+        subDir = dir;

+    }

+

+    /**

+     Get method for "SubDir" attribute

+

+     @returns   The name of sub-directory

+     **/

+    public String getSubDir() {

+        return subDir;

+    }

+

+    /**

+     Set method for "IncludePath" attribute

+

+     @param     path    The name of include path

+     **/

+    public void setIncludePath(String path) {

+        includePath = cleanupPathName(path);

+    }

+

+    /**

+     Get method for "IncludePath" attribute

+

+     @returns   The name of include path

+     **/

+    public String getIncludePath() {

+        return includePath;

+    }

+

+    /**

+     Set method for "ExtraDeps" attribute

+

+     @param     deps    The name of dependency file specified separately

+     **/

+    public void setExtraDeps(String deps) {

+        extraDeps = deps;

+    }

+

+    /**

+     Get method for "ExtraDeps" attribute

+

+     @returns   The name of dependency file specified separately

+     **/

+    public String getExtraDeps () {

+        return extraDeps;

+    }

+

+    /**

+     Add method for "IncludePath" nested element

+

+     @param     path    The IncludePath object from nested IncludePath type of element

+     **/

+    public void addIncludepath(IncludePath path) {

+        includePathList.add(path);

+    }

+

+    /**

+     Add method for "Input" nested element

+

+     @param     input   The Input object from nested Input type of element

+     **/

+    public void addInput(Input inputFile) {

+        inputFileList.add(inputFile);

+    }

+

+    /**

+     The original file generated by MakeDeps.exe is for makefile uses. The target

+     part (before :) is not useful for ANT. This method will do the removal.

+

+     @returns   true    if cleaned files is saved successfully

+     @returns   false   if error occurs in file I/O system

+     **/

+    private boolean cleanup() {

+        File df = new File(depsFile);

+

+        if (!df.exists()) {

+            return false;

+        }

+

+        LineNumberReader    lineReader = null;

+        FileReader          fileReader = null;

+        try {

+            fileReader = new FileReader(df);

+            lineReader = new LineNumberReader(fileReader);

+

+            ///

+            /// clean-up each line in deps file

+            //

+            String line = null;

+            StringBuffer cleanedLines = new StringBuffer(4096);

+            while ((line = lineReader.readLine()) != null) {

+                Pattern pattern = Pattern.compile(target + "[ ]*:[ ]*(.+)");

+                Matcher matcher = pattern.matcher(line);

+

+                while (matcher.find()) {

+                    ///

+                    /// keep the file name after ":"

+                    ///

+                    String filePath = line.substring(matcher.start(1), matcher.end(1));

+                    filePath = cleanupPathName(filePath);

+                    cleanedLines.append(filePath);

+                    cleanedLines.append("\n");

+                }

+            }

+            lineReader.close();

+            fileReader.close();

+

+            ///

+            /// we may have explicitly specified dependency files

+            ///

+            StringTokenizer fileTokens = new StringTokenizer(extraDeps, ";");

+            while (fileTokens.hasMoreTokens()) {

+                cleanedLines.append(cleanupPathName(fileTokens.nextToken()));

+                cleanedLines.append("\n");

+            }

+

+            ///

+            /// overwrite old dep file with new content

+            ///

+            FileWriter fileWriter = null;

+            fileWriter = new FileWriter(df);

+            fileWriter.write(cleanedLines.toString());

+            fileWriter.close();

+        } catch (IOException e) {

+            log (e.getMessage());

+        }

+

+        return true;

+    }

+

+    /**

+     Check if the dependency list file should be (re-)generated or not.

+

+     @returns   true    The dependency list file is uptodate. No re-generation is needed.

+     @returns   false   The dependency list file is outofdate. Re-generation is needed.

+     **/

+    private boolean isUptodate() {

+        File df = new File(depsFile);

+        if (!df.exists()) {

+            return false;

+        }

+

+        ///

+        /// If the source file(s) is newer than dependency list file, we need to

+        /// re-generate the dependency list file

+        ///

+        long depsFileTimeStamp = df.lastModified();

+        Iterator iterator = inputFileList.iterator();

+        while (iterator.hasNext()) {

+            Input inputFile = (Input)iterator.next();

+            File sf = new File(inputFile.getFile());

+            if (sf.lastModified() > depsFileTimeStamp) {

+                return false;

+            }

+        }

+

+        ///

+        /// If the source files haven't been changed since last time the dependency

+        /// list file was generated, we need to check each file in the file list to

+        /// see if any of them is changed or not. If anyone of them is newer than

+        /// the dependency list file, MakeDeps.exe is needed to run again.

+        ///

+        LineNumberReader    lineReader = null;

+        FileReader          fileReader = null;

+        boolean             ret = true;

+        try {

+            fileReader = new FileReader(df);

+            lineReader = new LineNumberReader(fileReader);

+

+            String line = null;

+            while ((line = lineReader.readLine()) != null) {

+                File sourceFile = new File(line);

+                if (sourceFile.lastModified() > depsFileTimeStamp) {

+                    ret = false;

+                    break;

+                }

+            }

+            lineReader.close();

+            fileReader.close();

+        } catch (IOException e) {

+            log (e.getMessage());

+        }

+

+        return ret;

+    }

+}

+

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java
new file mode 100644
index 0000000..f64fa7c
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java
@@ -0,0 +1,40 @@
+/** @file

+This file is to define common interfaces for nested element of frameworktasks

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.File;

+import java.util.List;

+

+/**

+ Interface NestElement is just to define common interfaces for nested element

+ **/

+public interface NestElement {

+    /**

+     nested element Interface for up-casting  

+     **/

+    

+    public String getName();

+

+    public void setName(String name);

+

+    public String toString();

+

+    public File getFile();

+

+    public void setFile(File file);

+

+    public void setList(String fileNameList);

+

+    public List<String> getList();

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SectFile.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SectFile.java
new file mode 100644
index 0000000..3557647
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SectFile.java
@@ -0,0 +1,108 @@
+/** @file

+This file is to define nested element which is meant for specifying section file

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import org.apache.tools.ant.BuildException;

+

+/**

+ Class SectFile is to define a class corresponding to ANT nested element. It's

+ used to specify section file(s) when used with GenFfsFile task

+ **/

+public class SectFile implements Section {

+    private String fileName = ""; /// section file name

+

+    /**

+     Get method of ANT task/datatype for "FileName" attribute

+  

+     @returns The name of section file

+     **/

+    public String getFileName() {

+        return fileName;

+    }

+

+    /**

+     Set method of ANT task/datatype for "FileName" attribute

+  

+     @param   fileName    The name of section file

+     **/

+    public void setFileName(String fileName) {

+        this.fileName = fileName;   

+    }

+

+    public SectFile (){

+    }

+

+    /**

+     Put the content of section file into specified buffer with extra bytes for 

+     alignment requirement.

+  

+     @param   Buffer  buffer to contain the section file content with alignment

+     **/

+    public void toBuffer (DataOutputStream Buffer){

+        File   sectFile;

+        byte   data;

+        long   fileLen;

+

+        ///

+        /// open file

+        ///

+        sectFile = new File (this.fileName);  

+

+        ///

+        /// check if file exist.

+        ///     

+        if (! sectFile.exists()) {

+            throw new BuildException("The file  " + this.fileName + "  is not exist!\n");     

+        }

+

+

+        ///

+        /// Read section file and add it's contains to buffer.

+        ///

+        try {

+

+            FileInputStream fs = new FileInputStream (sectFile.getAbsoluteFile());

+            DataInputStream In = new DataInputStream (fs);

+            fileLen            = sectFile.length();

+

+            int i = 0;

+            while (i < fileLen) {

+                data = In.readByte();

+                Buffer.writeByte(data);

+                i++;

+            }

+

+            ///

+            /// 4 byte alignment

+            ///

+            while ((fileLen & 0x03)!= 0) {

+                fileLen ++;

+                Buffer.writeByte(0);

+            } 

+

+            ///

+            /// close inputStream

+            ///

+            In.close();

+

+        } catch (Exception e) {

+            System.out.print(e.getMessage());

+            throw new BuildException("section file2Buffer failed!\n");            

+        }

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Section.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Section.java
new file mode 100644
index 0000000..3f56eaf
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Section.java
@@ -0,0 +1,23 @@
+/** @file

+This file is to define interface for manipulating section file

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.DataOutputStream;

+

+/**

+ Section interface is for geting the contain buffer form compress, tool, and sectFile  

+ **/

+public interface Section {

+    public void toBuffer (DataOutputStream Buffer);

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SetStampTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SetStampTask.java
new file mode 100644
index 0000000..af04702
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SetStampTask.java
@@ -0,0 +1,136 @@
+/** @file

+This file is to define an ANT task to wrap setstamp.exe tool

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+/**

+ Class SetStampTask is a wrap class for setstamp.exe.

+ **/

+public class SetStampTask extends Task implements EfiDefine {

+    /**

+     SetStamp Task Class

+     class member

+         -peFile  : file of PE

+         -timeFile: Txt file of time

+     **/ 

+    

+    private String peFile = "";

+

+    private String timeFile = "";

+

+    /**

+     assemble tool command line & execute tool command line

+     

+     @throws BuildException

+     **/

+    public void execute() throws BuildException {

+

+        Project project = this.getOwningTarget().getProject();

+        ///

+        /// absolute path of edk tools

+        ///

+        String path = project.getProperty("env.Framework_Tools_Path");

+        String command;

+        if (path == null) {

+            command = "setstamp";

+        } else {

+            command = path + "/" + "setstamp";

+        }

+        ///

+        /// argument of SetStamp tool

+        ///

+        String argument = peFile + timeFile;

+        ///

+        /// reture value of SetStamp execution

+        ///

+        int returnVal = -1;

+

+        try {

+            Commandline commandLine = new Commandline();

+            commandLine.setExecutable(command);

+            commandLine.createArgument().setLine(argument);

+

+            LogStreamHandler streamHandler = new LogStreamHandler(this,

+                    Project.MSG_INFO, Project.MSG_WARN);

+

+            Execute runner = new Execute(streamHandler, null);

+            runner.setAntRun(project);

+            runner.setCommandline(commandLine.getCommandline());

+

+            System.out.println(Commandline.toString(commandLine

+                    .getCommandline()));

+

+            returnVal = runner.execute();

+            if (EFI_SUCCESS == returnVal) {

+                ///

+                /// command execution success

+                ///

+                System.out.println("SetStamp execute succeeded!");

+            } else {

+                ///

+                /// command execution fail

+                ///

+                System.out.println("SetStamp failed. (error="

+                        + Integer.toHexString(returnVal) + ")");

+                throw new BuildException("SetStamp failed. (error="

+                        + Integer.toHexString(returnVal) + ")");

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+    /**

+     set operation of class member "peFile"

+     

+     @param     peFile  name of PE File

+     **/

+    public void setPeFile(String peFile) {

+        this.peFile = " " + peFile;

+    }

+

+    /**

+     get operation of class member "peFile"

+     

+     @return    peFile  name of PE file

+     **/

+    public String getPeFile() {

+        return this.peFile;

+    }

+

+    /**

+     set operation of class member "timeFile"

+     

+     @param     timeFile    name of time file

+     **/

+    public void setTimeFile(String timeFile) {

+        this.timeFile = " " + timeFile;

+    }

+

+    /**

+     get class member "timeFile"

+     

+     @returns   name of time file

+     **/

+    public String getTimeFile() {

+        return this.timeFile;

+    }

+

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SkipExt.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SkipExt.java
new file mode 100644
index 0000000..d766ed2
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/SkipExt.java
@@ -0,0 +1,83 @@
+/** @file

+This file is to define nested element which is meant for specifying skipped file list

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.File;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.StringTokenizer;

+

+/**

+ SkipExt nested element Class

+ class member

+     -name : extension name of skiped file 

+     -file : name of file including ext

+ **/

+public class SkipExt implements NestElement {

+    private String name = "";

+    private File file;

+    private List<String> nameList = new ArrayList<String>();

+    

+    /**

+     get class member "name"

+     @returns name parameter

+     **/

+    public String getName() {

+        return this.name;

+    }

+    /**

+     set class member "name"

+     @param     name    extension name of skiped file  

+     **/

+    public void setName(String name) {

+        this.name = " -skipext " + name;

+    }

+

+    public String toString() {

+        return getName();

+    }

+

+    /**

+     get class member "file"

+     @returns file parameter

+     **/

+    public File getFile() {

+        return this.file;

+    }

+    /**

+     set class member "file"

+     @param name of file including ext  

+     **/

+    public void setFile(File file) {

+        this.file = file;

+    }

+

+    public void setList(String fileNameList) {

+        if (fileNameList != null && fileNameList.length() > 0) {

+            StringTokenizer tokens = new StringTokenizer(fileNameList, " \t,;", false);

+            while (tokens.hasMoreTokens()) {

+                String fileName = tokens.nextToken().trim();

+                if (fileName.length() > 0) {

+                    this.nameList.add(fileName);

+                }

+            }

+        }

+    }

+

+    public List<String> getList() {

+        return nameList;

+    }

+ 

+}

+

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/StrGatherTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/StrGatherTask.java
new file mode 100644
index 0000000..c136f15
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/StrGatherTask.java
@@ -0,0 +1,527 @@
+/** @file

+This file is to define an ANT task which wraps StrGather.exe tool.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.util.*;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+/**

+ StrGather Task Class

+ class memberg

+      -commandType    : command type [parse/scan/dump] 

+      -baseName       : base name of component 

+      -verbose        : level of verbose [all/read/write]

+      -outputDatabase : file name of output database file

+      -databaseList   : file name list of database files

+      -inputFileList  : file name list of input files

+      -newDatabase    : whether to need new database [ture/false]

+      -unquotedString : whether to unquoted strings are used [ture/false]

+      -includePathList: path list of include paths

+      -ignoreNotFound : whether to ignore a given STRING_TOKEN(STR) is not found in database [ture/false]

+      -skipExtList    : skip scan of files with extension name

+      -outputString   : write string data to filename 

+      -outputDefines  : write string defines to filename 

+      -outputUnicode  : dump database to unicode file filename

+      -lang           : only dump for the language 

+      -indirectionFile: specify an indirection file

+      -outputHpk      : create an HII export pack of the strings

+ **/

+public class StrGatherTask extends Task implements EfiDefine {

+    ///

+    /// common options

+    ///

+    private String commandType = "";

+

+    private String baseName = "";

+

+    ///

+    /// "all/read/write"

+    ///

+    private String verbose = "";

+

+    private String outputDatabase = "";

+

+    private List<Object> databaseList = new ArrayList<Object>();

+

+    private List<Object> inputFileList = new ArrayList<Object>();

+

+    ///

+    /// parse options newDatabase -- "ture/false" unquoteString -- "ture/false"

+    ///

+    private String newDatabase = "";

+

+    private String unquotedString = "";

+

+    private List<Object> includePathList = new ArrayList<Object>();

+

+    ///

+    /// scan options ignoreNotFound -- "ture/false"

+    ///

+    private String ignoreNotFound = "";

+

+    private List<Object> skipExtList = new ArrayList<Object>();

+

+    ///

+    /// dump options

+    ///

+    private String outputString = "";

+

+    private String outputDefines = "";

+

+    private String outputUnicode = "";

+

+    private String lang = "";

+

+    private String indirectionFile = "";

+

+    private String outputHpk = "";

+

+    ///

+    /// global variable

+    ///

+    static private Project project;

+

+    /**

+     assemble tool command line & execute tool command line

+     

+     @throws BuildException

+     **/

+    public void execute() throws BuildException {

+

+        project = this.getOwningTarget().getProject();

+        ///

+        /// absolute path of efi tools

+        ///

+        String path = project.getProperty("env.Framework_Tools_Path"); 

+        String command;

+        if (path == null) {

+            command = "StrGather";

+        } else {

+            command = path + "/" + "StrGather";

+        }

+

+        ///

+        /// transfer nested elements into string

+        ///

+        String databases = list2Str(databaseList, "-db");

+        String skipExts = list2Str(skipExtList, "-skipext");

+        String includePaths = list2Str(includePathList, "-I");

+        String inputFiles = list2Str(inputFileList, "");

+

+        ///

+        /// assemble argument

+        ///

+        String argument = commandType + verbose + databases + baseName

+                + outputDatabase + includePaths + newDatabase + unquotedString

+                + skipExts + ignoreNotFound + outputString + outputDefines

+                + outputUnicode + lang + indirectionFile + outputHpk

+                + inputFiles;

+        ///

+        /// return value of fwimage execution

+        ///

+        int revl = -1;

+

+        try {

+            Commandline cmdline = new Commandline();

+            cmdline.setExecutable(command);

+            cmdline.createArgument().setLine(argument);

+

+            LogStreamHandler streamHandler = new LogStreamHandler(this,

+                    Project.MSG_INFO, Project.MSG_WARN);

+            Execute runner = new Execute(streamHandler, null);

+

+            runner.setAntRun(project);

+            runner.setCommandline(cmdline.getCommandline());

+            System.out.println(Commandline.toString(cmdline.getCommandline()));

+

+            revl = runner.execute();

+            if (EFI_SUCCESS == revl) {

+                ///

+                /// command execution success

+                ///

+                System.out.println("strgather succeeded!");

+            } else {

+                ///

+                /// command execution fail

+                ///

+                System.out.println("strgather failed. (error="

+                        + Integer.toHexString(revl) + ")");

+                throw new BuildException("strgather failed. (error="

+                        + Integer.toHexString(revl) + ")");

+            }

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+    /**

+     get class member "commandType"

+     

+     @returns commandType parameter

+     **/

+    public String getCommandType() {

+        return this.commandType;

+    }

+

+    /**

+     set class member ""

+     

+     @param     commandType     type of strgather command [parse/scan/dump]

+     **/

+    public void setCommandType(String commandType) {

+        this.commandType = " -" + commandType;

+    }

+

+    /**

+     get class member "verbose"

+     

+     @returns verbose parameter

+     **/

+    public String getVerbose() {

+        return this.verbose;

+    }

+

+    /**

+     set class member "verbose"

+     

+     @param     verbose     verbose level [all/read/write]

+     **/

+    public void setVerbose(String verbose) {

+        if (verbose.equals("all")) {

+            ///

+            /// for verbose output

+            ///

+            this.verbose = " -v ";

+        } else if (verbose.equals("read")) {

+            ///

+            /// for verbose output when reading database

+            ///

+            this.verbose = " -vdbr ";

+        } else if (verbose.equals("write")) {

+            ///

+            /// for verbose output when writing database

+            ///

+            this.verbose = " -vdbw ";

+        }

+    }

+

+    /**

+     get class member baseName

+     

+     @returns baseName parameter

+     **/

+    public String getBaseName() {

+        return this.baseName;

+    }

+

+    /**

+     set class member baseName

+     

+     @param     baseName    name of the output files of .c and .h

+     **/

+    public void setBaseName(String baseName) {

+        this.baseName = " -bn " + baseName;

+    }

+

+    /**

+     get class member "outputDatabase"

+     

+     @returns outputDatabase parameter

+     **/

+    public String getOutputDatabase() {

+        return this.outputDatabase;

+    }

+

+    /**

+     set class member "outputDatabase"

+     

+     @param     outputDatabase  filename of output database file

+     **/

+    public void setOutputDatabase(String outputDatabase) {

+        this.outputDatabase = " -od " + outputDatabase;

+    }

+

+    /**

+     get class member "newDatabase"

+     

+     @returns newDatabase parameter

+     **/

+    public String getNewDatabse() {

+        return this.newDatabase;

+    }

+

+    /**

+     set class member "newDatabase"

+     

+     @param     newDatabase     whether to not read in existing database file

+     **/

+    public void setNewDatabase(String newDatabase) {

+        if (newDatabase.equals("true")) {

+            this.newDatabase = " -newdb ";

+        }

+    }

+

+    /**

+     get class member "unquotedString"

+     

+     @returns unquotedString parameter

+     **/

+    public String getUnquotedString() {

+        return this.unquotedString;

+    }

+

+    /**

+     set class member "unquotedString"

+     

+     @param unquotedString :

+                whether to indicate that unquoted strings are used

+     **/

+    public void setUnquotedString(String unquotedString) {

+        if (unquotedString.equals("true")) {

+            this.unquotedString = " -uqs ";

+        }

+    }

+

+    /**

+     get class member "ignoreNotFound"

+     

+     @returns ignoreNotFound parameter

+     **/

+    public String getIgnoreNotFound() {

+        return this.ignoreNotFound;

+    }

+

+    /**

+     set class member "ignoreNotFound"

+     

+     @param     ignoreNotFound  whether to ignore if a given STRING_TOKEN(STR) 

+                                is not found in the database

+     **/

+    public void setIgnoreNotFound(String ignoreNotFound) {

+        if (ignoreNotFound.equals("true")) {

+            this.ignoreNotFound = " -ignorenotfound ";

+        }

+    }

+

+    /**

+     get class member "outputString"

+     

+     @returns outputString parameter

+     **/

+    public String getOutputString() {

+        return this.outputString;

+    }

+

+    /**

+     set class member "outputString"

+     

+     @param     outputString    filename of string data file

+     **/

+    public void setOutputString(String outputString) {

+        this.outputString = " -oc " + outputString;

+    }

+

+    /**

+     get class member "outputDefines"

+     

+     @returns outputDefines parameter

+     **/

+    public String getOutputDefines() {

+        return this.outputDefines;

+    }

+

+    /**

+     set class member "outputDefines"

+     

+     @param     outputDefines   filename of string defines file

+     **/

+    public void setOutputDefines(String outputDefines) {

+        this.outputDefines = " -oh " + outputDefines;

+    }

+

+    /**

+     get class member "outputUnicode"

+     

+     @returns outputUnicode parameter

+     **/

+    public String getOutputUnicode() {

+        return this.outputUnicode;

+    }

+

+    /**

+     set class member "outputUnicode"

+     

+     @param     outputUnicode   filename of unicode file to be dumped database

+     **/

+    public void setOutputUnicode(String outputUnicode) {

+        this.outputUnicode = " -ou " + outputUnicode;

+    }

+

+    /**

+     get class member "lang"

+     

+     @returns lang parameter

+     **/

+    public String getLang() {

+        return this.lang;

+    }

+

+    /**

+     set class member "lang"

+     

+     @param     lang    language of dump

+     **/

+    public void setLang(String lang) {

+        this.lang = " -lang " + lang;

+    }

+

+    /**

+     get class member "indirectionFile"

+     

+     @returns indirectionFile parameter

+     **/

+    public String getIndirectionFile() {

+        return this.indirectionFile;

+    }

+

+    /**

+     set class member "indirectionFile"

+     

+     @param     indirectionFile     filename of indirection file

+     **/

+    public void setIndirectionFile(String indirectionFile) {

+        this.indirectionFile = " -if " + indirectionFile;

+    }

+

+    /**

+     get class member "outputHpk"

+     

+     @returns outputHpk parameter

+     **/

+    public String getOutputHpk() {

+        return this.outputHpk;

+    }

+

+    /**

+     set class member "outputHpk"

+     

+     @param     outputHpk   filename of output HII export pack of the strings

+     **/

+    public void setOutputHpk(String outputHpk) {

+        this.outputHpk = " -hpk " + outputHpk;

+    }

+

+    /**

+     add a skipExt element into list

+     

+     @param     skipExt     skipExt element

+     **/

+    public void addSkipext(SkipExt skipExt) {

+        skipExtList.add(skipExt);

+    };

+

+    /**

+     add a includePath element into list

+     

+     @param     includePath     includePath element

+     **/

+    public void addIncludepath(IncludePath includePath) {

+        includePathList.add(includePath);

+    };

+

+    /**

+     add a inputFile element into list

+     

+     @param     inputFile   inputFile element

+     **/

+    public void addInputfile(InputFile inputFile) {

+        inputFileList.add(inputFile);

+    };

+

+    /**

+     add a database element into list

+     

+     @param database :

+                database element

+     **/

+    public void addDatabase(Database database) {

+        databaseList.add(database);

+    }

+

+    /**

+     transfer List to String

+     

+     @param     list    nested element list

+     @param     tag     interval tag of parameter

+

+     @returns string line of parameters

+     **/

+    private String list2Str(List list, String tag) {

+        ///

+        /// string line for return

+        ///

+        String paraStr = "";

+        ///

+        /// nested element in list

+        ///

+        NestElement element;

+        ///

+        /// iterator of nested element list

+        ///

+        Iterator elementIter = list.iterator();

+        ///

+        /// string parameter list

+        ///

+        List<Object> strList = new ArrayList<Object>();

+

+        while (elementIter.hasNext()) {

+            element = (NestElement) elementIter.next();

+            if (null != element.getFile()) {

+                ///

+                /// nested element include file

+                ///

+                FileParser.loadFile(project, strList, element.getFile(), tag);

+            } 

+

+            if (element.getName().length() > 0) {

+                ///

+                /// nested element include name 

+                ///

+                paraStr = paraStr + " " + element.getName();

+            }

+

+            List<String> nameList = element.getList();

+            if (nameList.size() > 0) {

+                Iterator nameIter = nameList.iterator();

+                while (nameIter.hasNext()) {

+                    paraStr = paraStr + " " + tag + " " + (String)nameIter.next();

+                }

+            }

+        }

+        ///

+        /// iterator of string parameter list

+        ///

+        Iterator strIter = strList.iterator();

+        while (strIter.hasNext()) {

+            paraStr = paraStr + " " + strIter.next();

+        }

+        return paraStr;

+    }

+

+}

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Tool.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Tool.java
new file mode 100644
index 0000000..36b095a
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/Tool.java
@@ -0,0 +1,194 @@
+/** @file

+This file is to define nested element which is meant for specifying a tool

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+ Class Tool is to define an external tool to be used for genffsfile

+ **/

+public class Tool implements EfiDefine, Section {

+

+    String toolName     = "";

+    List<Object>   toolArgList  = new ArrayList<Object>();

+    String outputPath;

+    String outPutFileName ;

+    List<Input>    inputFiles = new ArrayList<Input>();

+

+    /**

+     Call extern tool

+

+     @param     buffer  The buffer to put the result with alignment

+     **/

+    public void toBuffer (DataOutputStream buffer){

+        File           OutputFile;

+        byte           data;

+

+        ///

+        /// call extern tool

+        ///

+        try {

+            executeTool ();

+        } catch (Exception e) {

+            throw new BuildException("Call tools failed!\n");

+        }

+

+        ///

+        /// check if file exist

+        ///

+        OutputFile = new File (this.outPutFileName);

+        long fileLen = OutputFile.length();

+        if (!OutputFile.exists()) {

+            throw new BuildException("The file " + outPutFileName + " is not exist!\n");

+        }

+

+        ///

+        /// Read output file and write it's cotains to buffer

+        ///

+        try {

+            FileInputStream fs  = new FileInputStream (this.outPutFileName);

+            DataInputStream In  = new DataInputStream (fs);

+

+            int i = 0;

+            while (i < fileLen) {

+                data = In.readByte();

+                buffer.writeByte(data);

+                i ++;

+            }

+

+            ///

+            /// 4 byte alignment

+            ///

+            while ((fileLen & 0x03) != 0) {

+                fileLen++;

+                buffer.writeByte(0);

+            }

+            In.close();

+

+        } catch (Exception e) {

+            System.out.print(e.getMessage());

+            throw new BuildException("Call tool2buffer failed!\n");

+        }

+    }

+

+    ///

+    /// execute external tool for genffsfile

+    ///

+    private void executeTool () {

+        String command   = "";

+        String argument  = "";

+        command          = toolName;

+        Iterator argIter = toolArgList.iterator();

+        Iterator inputIter = inputFiles.iterator();

+        ToolArg toolArg;

+        Input file = null;

+

+        ///

+        /// argument of tools

+        ///

+        while (argIter.hasNext()) {

+            toolArg = (ToolArg)argIter.next();

+            argument = argument + toolArg.getLine() + " ";

+

+        }

+

+        ///

+        /// input files for tools

+        ///

+        argument = argument + "-i ";

+        while (inputIter.hasNext()) {

+            file = (Input)inputIter.next();

+            argument = argument + file.getFile() + " ";

+        }

+

+        outPutFileName = outputPath + File.separatorChar + (new File(file.getFile())).getName() + ".crc";

+        argument       = argument + " -o " + outPutFileName; 

+

+        try {

+

+            ///

+            /// execute command line

+            ///

+            Process crcProcess = Runtime.getRuntime().exec(command + " " + argument);

+            crcProcess.waitFor();

+        } catch (Exception e) {

+            System.out.print (e.getMessage());

+            throw new BuildException("Execute tools fails!\n");

+        }

+    }

+

+    /**

+     Add method of ANT task/datatype for nested ToolArg type of element

+

+     @param     toolArg     The ToolArg object containing arguments for the tool

+     **/

+    public void addToolArg (ToolArg toolArg) {

+        toolArgList.add (toolArg);

+    }

+

+    /**

+     Get method of ANT task/datatype for attribute "OutputPath"

+

+     @returns   The name of output path

+     **/

+    public String getOutputPath() {

+        return outputPath;

+    }

+

+    /**

+     Set method of ANT task/datatype for attribute "OutputPath"

+

+     @param     outputPath  The name of output path

+     **/

+    public void setOutputPath(String outPutPath) {

+        this.outputPath = outPutPath;

+    }

+

+    /**

+     Get method of ANT task/datatype for attribute "ToolName"

+

+     @returns   The name of the tool.

+     **/

+    public String getToolName() {

+        return toolName;

+    }

+

+    /**

+     Set method of ANT task/datatype for attribute "ToolName"

+

+     @param     toolName    The name of the tool

+     **/

+    public void setToolName(String toolName) {

+        this.toolName = toolName;

+    }

+

+    /**

+     Add method of ANT task/datatype for nested Input type of element

+

+     @param     file    The Input objec which represents a file

+     **/

+    public void addInput(Input file) {

+        inputFiles.add(file);

+    }

+}

+

+

diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/ToolArg.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/ToolArg.java
new file mode 100644
index 0000000..b5fbdfe
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/ToolArg.java
@@ -0,0 +1,42 @@
+/** @file

+This file is to define nested element which is meant for specifying tool arguments

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+/**

+ Class ToolArg is just used to specify arguments for genffsfile tool

+ **/

+public class ToolArg {

+    ///

+    /// keep the argument string

+    ///

+    private String line = "";

+

+    /**

+     Get method of ANT task/datatype for attribute "line"

+

+     @returns   The argument string

+     **/

+    public String getLine() {

+        return line;

+    }

+

+    /**

+     Set method of ANT task/datatype for attribute "line"

+

+     @param     line    The argument string

+     **/

+    public void setLine(String line) {

+        this.line = line;

+    }   

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/VfrCompilerTask.java b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/VfrCompilerTask.java
new file mode 100644
index 0000000..dbd796e
--- /dev/null
+++ b/edk2/Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/VfrCompilerTask.java
@@ -0,0 +1,221 @@
+/** @file

+This file is to define an ANT task which wraps VfrCompile.exe tool

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.framework.tasks;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Execute;

+import org.apache.tools.ant.taskdefs.LogStreamHandler;

+import org.apache.tools.ant.types.Commandline;

+

+/**

+ VfrcompilerTask Task Class

+  class member 

+      -createListFile  : create an output IFR listing file.

+      -outPutDir       : deposit all output files to directory OutputDir (default=cwd)

+      -createIfrBinFile: create an IFR HII pack file

+      -vfrFile         : name of the input VFR script file

+      -processArg      : c processer argument

+      -includepathList : add IncPath to the search path for VFR included files

+ **/

+public class VfrCompilerTask extends Task implements EfiDefine {

+    private String createListFile = "";

+    private String outPutDir = "";

+    private String createIfrBinFile = "";

+    private String processerArg ="";

+    private String vfrFile;

+

+    private List<Object> includepathList = new ArrayList<Object>();

+

+    /**

+     get class member of createList file

+

+     @returns file name of createList

+     **/

+    public String getCreateListFile() {

+        return createListFile;

+    }

+

+    /**

+     set class member of createList file

+

+     @param     createListFile  if createList string equal "on" set '-l' flag

+     **/

+    public void setCreateListFile(String createListFile) {

+        if (createListFile.equals("ON")||createListFile.equals("on"))

+            this.createListFile = " -l";

+    }

+

+    /**

+     get output dir 

+

+     @returns name of output dir

+     **/

+    public String getOutPutDir() {

+        return outPutDir;

+    }

+

+    /**

+     set class member of outPutDir

+

+     @param     outPutDir   The directory name for ouput file

+     **/

+    public void setOutPutDir(String outPutDir) {

+        this.outPutDir = " -od " + outPutDir;

+    }

+

+

+    /**

+     get class member of ifrBinFile

+

+     @return file name of ifrBinFile

+     **/

+    public String getCreateIfrBinFile() {

+        return createIfrBinFile;

+    }

+

+    /**

+     set class member of ifrBinFile 

+

+     @param     createIfrBinFile    The flag to specify if the IFR binary file should

+                                    be generated or not

+     */

+    public void setCreateIfrBinFile(String createIfrBinFile) {

+        if (createIfrBinFile.equals("ON") || createIfrBinFile.equals("on"));

+        this.createIfrBinFile = " -ibin";

+    }

+

+    /**

+     get class member of vfrFile

+

+     @returns name of vfrFile

+     **/

+    public String getVfrFile() {

+        return vfrFile;

+    }

+

+    /**

+     set class member of vfrFile 

+

+     @param     vfrFile The name of VFR file

+     **/

+    public void setVfrFile(String vfrFile) {

+        this.vfrFile = " " + vfrFile;

+    }

+

+    /**

+     add includePath in includepath List 

+

+     @param     includepath The IncludePath object which represents include path

+     **/

+    public void addIncludepath(IncludePath includepath){

+        includepathList.add(includepath);

+    }

+

+

+    /**

+     get class member of processerArg

+

+     @returns processer argument

+     **/

+    public String getProcesserArg() {

+        return processerArg;

+    }

+

+

+    /**

+     set class member of processerArg

+

+     @param     processerArg    The processor argument

+     */

+    public void setProcesserArg(String processerArg) {

+        this.processerArg = " -ppflag " + processerArg;

+    }

+

+    /**

+     The standard execute method of ANT task.

+     **/

+    public void execute() throws BuildException {

+        Project project = this.getProject();

+        String  toolPath= project.getProperty("env.Framework_Tools_Path");

+        String  command;

+        if (toolPath == null) {

+            command = "VfrCompile";

+        } else {

+            command = toolPath + "/" + "VfrCompile";

+        }

+        List<Object> includePath = new ArrayList<Object>();     

+        String incPath = "";        

+

+        int  count = includepathList.size();    

+        IncludePath path;

+        for (int i = 0; i < count; i++) {

+            path = (IncludePath) includepathList.get(i);

+            if (path.getFile() != null) {

+                FileParser.loadFile( project,includePath,path.getFile(), "-I");             

+            }

+        }

+        for (int i = 0; i < count; i++) {

+            incPath = incPath + " " + includepathList.get(i);

+        }

+        count =  includePath.size();

+        for (int i = 0; i < count; i++) {

+            incPath = incPath + " " + includePath.get(i);

+        }

+        String argument = this.createIfrBinFile +

+                          this.processerArg + 

+                          incPath +

+                          this.outPutDir + 

+                          this.createListFile +

+                          this.vfrFile ;

+        try {

+            ///

+            /// constructs the command-line

+            ///

+            Commandline commandLine = new Commandline();

+            commandLine.setExecutable(command);

+            commandLine.createArgument().setLine(argument);

+

+            ///

+            /// configures the Execute object

+            ///

+            LogStreamHandler streamHandler = new LogStreamHandler(this,

+                                                                  Project.MSG_INFO,

+                                                                  Project.MSG_WARN);

+

+            Execute runner = new Execute(streamHandler,null);

+            runner.setAntRun(project);

+            runner.setCommandline(commandLine.getCommandline());

+

+            System.out.println(Commandline.toString(commandLine.getCommandline()));         

+            int returnVal = runner.execute();

+            if (EFI_SUCCESS == returnVal) {

+                System.out.println("VfrCompiler execution succeeded!");

+            } else {

+                System.out.println("VfrCompiler failed. (error=" + 

+                                   Integer.toHexString(returnVal) + ")");  

+                throw new BuildException("VfrCompiler failed. (error=" + 

+                                         Integer.toHexString(returnVal) + ")");

+            }

+

+        } catch (IOException e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/GenBuild/GenBuild.tasks b/edk2/Tools/Source/GenBuild/GenBuild.tasks
new file mode 100644
index 0000000..c767cfb
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/GenBuild.tasks
@@ -0,0 +1,11 @@
+FPDParser          = org.tianocore.build.fpd.FpdParserTask

+bl                 = org.tianocore.build.global.VariableTask

+bf                 = org.tianocore.build.global.LibBuildFileGenerator

+GenBuild           = org.tianocore.build.GenBuildTask

+ToolChainSetup     = org.tianocore.build.toolchain.ToolChainTask

+Expand             = org.tianocore.build.ExpandTask

+OutputDirSetup     = org.tianocore.build.OutputDirSetupTask

+OnDependency       = org.tianocore.build.global.OnDependency

+sourcefiles        = org.tianocore.build.global.DpFileList

+targetfiles        = org.tianocore.build.global.DpFileList

+file               = org.tianocore.build.global.DpFile

diff --git a/edk2/Tools/Source/GenBuild/build.xml b/edk2/Tools/Source/GenBuild/build.xml
new file mode 100644
index 0000000..473646b
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/build.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="GenBuild" default="all" basedir=".">

+

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env"/>

+  <property name="WORKSPACE" value="${env.WORKSPACE}"/>

+  <path id="classpath">

+    <fileset dir="${WORKSPACE}/Tools/Jars" includes="SurfaceArea.jar"/>

+    <fileset dir="${env.XMLBEANS_HOME}/lib" includes="*.jar"/>

+  </path>

+  <property name="buildDir" value="build"/>

+  <property name="installLocation" value="${WORKSPACE}/Tools/Jars"/>

+  <target name="all" depends="install"/>

+  <target name="source">

+    <mkdir dir="${buildDir}"/>

+    <javac srcdir="." destdir="${buildDir}">

+      <classpath refid="classpath"/>

+      <compilerarg value="-Xlint"/>

+    </javac>

+  </target>

+  <target name="clean">

+    <delete dir="${buildDir}"/>

+  </target>

+  <target name="cleanall">

+    <delete dir="${buildDir}"/>

+    <if>

+      <available file="${installLocation}/GenBuild.jar"/>

+      <then>

+        <echo message="You must manually remove the file: ${installLocation}/GenBuild.jar"/>

+        <echo message="Java has already loaded the file, and cannot remove it within ANT!"/>

+      </then>

+    </if>

+  </target>

+  <target name="install" depends="source">

+    <copy file="GenBuild.tasks" toDir="${buildDir}"/>

+    <jar destfile="${installLocation}/GenBuild.jar"

+      basedir="${buildDir}"

+      includes="**"

+    />

+  </target>

+</project>

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
new file mode 100644
index 0000000..c4c53e0
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
@@ -0,0 +1,54 @@
+/** @file

+  This file is ANT task Expand. 

+  

+  Expand task is used to prepare ANT properties for further build. 

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+

+import org.tianocore.build.global.GlobalData;

+

+/**

+  Expand task is used to prepare ANT properties for further build. 

+  <p>Current, prepare the dependent Library instance list for <code>LIBS</code></p>

+ 

+  @since GenBuild 1.0

+**/

+public class ExpandTask extends Task {

+    

+    /**

+      Public construct method. It is necessary for ANT task.

+    **/

+    public ExpandTask () {

+    }

+    

+    /**

+      ANT task's entry point, will be called after init().

+      

+      Set <code>LIBS</code> for further build usage. 

+    **/

+    public void execute() throws BuildException {

+        String basename = getProject().getProperty("BASE_NAME");

+        String arch = getProject().getProperty("ARCH");

+        arch = arch.toUpperCase();

+        String[] libraries = GlobalData.getModuleLibrary(basename, arch);

+        String str = "";

+        for (int i = 0; i < libraries.length; i ++){

+            str += " " + GlobalData.getLibrary(libraries[i], arch);

+        }

+        getProject().setProperty("LIBS", str);

+       

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
new file mode 100644
index 0000000..267a50e
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
@@ -0,0 +1,390 @@
+/** @file

+  File is FfsProcess class which is used to get the corresponding FFS layout

+  information for driver module. 

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.InputStream;

+import java.util.Vector;

+

+import javax.xml.namespace.QName;

+import javax.xml.parsers.DocumentBuilder;

+import javax.xml.parsers.DocumentBuilderFactory;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.xmlbeans.XmlCursor;

+import org.apache.xmlbeans.XmlObject;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.NamedNodeMap;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+

+/** 

+  <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>

+  

+  <p>Property <code>COMMON_FILE</code> specified which file to search. The element

+  in <code>COMMON_FILE</code> is like following: </p>

+  

+  <pre>

+    &lt;Ffs type="APPLICATION"&gt;

+      &lt;Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" /&gt;

+      &lt;Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" /&gt;

+      &lt;Sections EncapsulationType="Compress"&gt;

+        &lt;Sections EncapsulationType="Guid-Defined"&gt;

+          &lt;Section SectionType="EFI_SECTION_PE32" /&gt; 

+          &lt;Section SectionType="EFI_SECTION_USER_INTERFACE" /&gt;

+          &lt;Section SectionType="EFI_SECTION_VERSION" /&gt; 

+        &lt;/Sections&gt;

+      &lt;/Sections&gt;

+    &lt;/Ffs&gt;

+  </pre>

+ 

+  @since GenBuild 1.0

+**/

+public class FfsProcess {

+

+    ///

+    /// Xml Document Node for corresponding FFS layout

+    ///

+    private Node ffs;

+

+    ///

+    /// ANT script to call GenFfs

+    ///

+    private Element ffsNode = null;

+

+    ///

+    /// Module base name

+    ///

+    private String basename;

+

+    ///

+    /// Sections type: normal

+    ///

+    private static int MODE_NONE = 0;

+

+    ///

+    /// Sections type: compress

+    ///

+    private static int MODE_COMPRESS = 1;

+

+    ///

+    /// Sections type: guid-define

+    ///

+    private static int MODE_GUID_DEFINED = 2;

+

+    ///

+    /// mapping from section type to section output file extension

+    ///

+    public static final String[][] sectionExt = { { "EFI_SECTION_FREEFORM_SUBTYPE_GUID", ".sec" },

+                                                 { "EFI_SECTION_VERSION", ".ver" },

+                                                 { "EFI_SECTION_USER_INTERFACE", ".ui" },

+                                                 { "EFI_SECTION_DXE_DEPEX", ".dpx" },

+                                                 { "EFI_SECTION_PEI_DEPEX", ".dpx" }, 

+                                                 { "EFI_SECTION_PE32", ".pe32" },

+                                                 { "EFI_SECTION_PIC", ".pic" }, 

+                                                 { "EFI_SECTION_TE", ".tes" },

+                                                 { "EFI_SECTION_RAW", ".sec" }, 

+                                                 { "EFI_SECTION_COMPRESSION", ".sec" },

+                                                 { "EFI_SECTION_GUID_DEFINED", ".sec" },

+                                                 { "EFI_SECTION_COMPATIBILITY16", ".sec" },

+                                                 { "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", ".sec" } };

+

+    /**

+      search in the type, if componentType is listed in type, return true; 

+      otherwise return false.

+      

+      @param type a list supported component type separated by comma

+      @param componentType current module component type

+      @return whether componentType is one of type 

+    **/

+    private boolean isMatch(String type, String componentType) {

+        String[] items = type.split("[ \t]*,[ \t]*");

+        for (int i = 0; i < items.length; i++) {

+            if (items[i].equalsIgnoreCase(componentType)) {

+                return true;

+            }

+        }

+        return false;

+    }

+

+    /**

+      Find the corresponding FFS layout in <code>COMMON_FILE</code> if it

+      does not specify in module's surface area. 

+      

+      @param buildType Current module's component type

+      @param project Ant project

+      @return whether find the corresponding FFS layout

+      @throws BuildException

+              If specified COMMON_FILE XML file is not valide.

+    **/

+    public boolean initSections(String buildType, Project project) throws BuildException {

+        //

+        // first try to sections defined in PLATFORM level

+        //

+

+        //

+        // if module specify sections itself, it's okay

+        // otherwise find sections from WORKSPACE default setting with

+        // ComponentType

+        //

+        if (ffs == null) {

+            File file = new File(project.getProperty("COMMON_FILE"));

+            //

+            // if common file is not existed, just return

+            //

+            if (!file.exists()) {

+                return false;

+            }

+            DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();

+            try {

+                DocumentBuilder dombuilder = domfac.newDocumentBuilder();

+                InputStream is = new FileInputStream(file);

+                Document doc = dombuilder.parse(is);

+                Element root = doc.getDocumentElement();

+                NodeList items = root.getChildNodes();

+                for (int i = 0; i < items.getLength(); i++) {

+                    Node node = items.item(i);

+                    if (node.getNodeType() == Node.ELEMENT_NODE) {

+                        String nodeName = node.getNodeName();

+                        if (nodeName.equalsIgnoreCase("Ffs")) {

+                            NamedNodeMap attr = node.getAttributes();

+                            Node type = attr.getNamedItem("type");

+                            if (type != null) {

+                                if (isMatch(type.getTextContent(), buildType)) {

+                                    ffs = node;

+                                    return true;

+                                }

+                            }

+                        }

+                    }

+                }

+            } catch (Exception e) {

+                throw new BuildException("Parse COMMON_FILE [" + file.getPath() + "] error!\n" + e.getMessage());

+            }

+        }

+        if (ffs == null) {

+            return false;

+        } else {

+            return true;

+        }

+    }

+    

+    /**

+      Recursive parse the FFS layout. Find out all section type here used. 

+      

+      @param document BaseName_build.xml Xml document

+      @param basename Module's base name

+      @param guid Module's GUID

+      @param targetFilename Module's final file name (GUID-BaseName.APP)

+      @return List of section type

+    **/

+    public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) {

+        this.basename = basename;

+        if (ffs == null) {

+            return new String[0];

+        }

+        Vector<String> sectionList = new Vector<String>();

+        XmlCursor cursor = null;

+        try {

+            cursor = XmlObject.Factory.parse(ffs).newCursor();

+        } catch (Exception e) {

+            return null;

+        }

+        int mode = MODE_NONE;

+        Element root = document.createElement("genffsfile");

+        root.setAttribute("outputDir", "${BIN_DIR}");

+        root.setAttribute("BaseName", basename);

+        root.setAttribute("fileGuid", guid);

+        cursor.toFirstChild();

+        if (cursor.toFirstChild()) {

+            do {

+                if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {

+                    String name = cursor.getAttributeText(new QName("Name"));

+                    String value = cursor.getAttributeText(new QName("Value"));

+                    root.setAttribute(changeAttributeName(name), value);

+                } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {

+                    cursor.push();

+                    dealSection(mode, document, root, cursor, sectionList);

+                    cursor.pop();

+                } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {

+                    cursor.push();

+                    dealSections(mode, document, root, cursor, sectionList);

+                    cursor.pop();

+                }

+            } while (cursor.toNextSibling());

+        }

+        //

+        // Check dependency 

+        //

+        Element outofdateEle = document.createElement("OnDependency");

+        Element sourceEle = document.createElement("sourcefiles");

+        String[] result = new String[sectionList.size()];

+        for (int i = 0; i < sectionList.size(); i++) {

+            result[i] = (String) sectionList.get(i);

+            Element pathEle = document.createElement("file");

+            pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename

+                                         + getSectionExt(result[i]));

+            sourceEle.appendChild(pathEle);

+        }

+        outofdateEle.appendChild(sourceEle);

+        Element targetEle = document.createElement("targetfiles");

+        Element fileEle = document.createElement("file");

+        fileEle.setAttribute("name", "${BIN_DIR}\\" + targetFilename);

+        targetEle.appendChild(fileEle);

+        outofdateEle.appendChild(targetEle);

+        Element sequentialEle = document.createElement("sequential");

+        sequentialEle.appendChild(root);

+        outofdateEle.appendChild(sequentialEle);

+        ffsNode = outofdateEle;

+        return result;

+    }

+

+    /**

+      Change the attribute name. For example: 

+      

+      <pre>

+          Before change: FFS_ATTRIB_CHECKSUM 

+          After  change: ffsATTRIBCHECKSUM

+      </pre>

+      

+      @param name Original attribute name

+      @return Changed attribute name

+    **/

+    private String changeAttributeName(String name) {

+        String[] strs = name.split("_");

+        String str = strs[0].toLowerCase();

+        for (int j = 1; j < strs.length; j++) {

+            str += strs[j];

+        }

+        return str;

+    }

+

+    /**

+      Recursively deal with Sections. If sections does not specify a type, then omit it.

+      

+      @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)

+      @param doc Xml Document

+      @param root Root Node

+      @param cursor Current FFS layout cursor

+      @param list List of section type here used

+    **/

+    private void dealSections(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {

+        String type = cursor.getAttributeText(new QName("EncapsulationType"));

+        if (type == null) {

+            if (cursor.toFirstChild()) {

+                do {

+                    if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {

+                        cursor.push();

+                        dealSection(mode, doc, root, cursor, list);

+                        cursor.pop();

+                    } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {

+                        cursor.push();

+                        dealSections(mode, doc, root, cursor, list);

+                        cursor.pop();

+                    }

+                } while (cursor.toNextSibling());

+            }

+            return;

+        }

+        Element ele;

+        if (type.equalsIgnoreCase("COMPRESS")) {

+            mode = MODE_COMPRESS;

+            //

+            // <compress compressName = "dummy">

+            //

+            ele = doc.createElement("compress");

+            ele.setAttribute("compressName", "dummy");

+        } else {

+            mode = MODE_GUID_DEFINED;

+            //

+            // <tool toolName="${OEMTOOLPATH}\toolname"

+            // outputPath = "${DEST_DIR_OUTPUT}">

+            //

+            ele = doc.createElement("tool");

+            ele.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"

+                                         + File.separatorChar + "GenCRC32Section");

+            ele.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");

+        }

+        if (cursor.toFirstChild()) {

+            do {

+                if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {

+                    cursor.push();

+                    dealSection(mode, doc, ele, cursor, list);

+                    cursor.pop();

+                } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {

+                    cursor.push();

+                    dealSections(mode, doc, ele, cursor, list);

+                    cursor.pop();

+                }

+            } while (cursor.toNextSibling());

+        }

+        root.appendChild(ele);

+    }

+    

+    /**

+      Recursively deal with section.

+      

+      @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)

+      @param doc Xml Document

+      @param root Root Node

+      @param cursor Current FFS layout cursor

+      @param list List of section type here used

+    **/

+    private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {

+        String type = cursor.getAttributeText(new QName("SectionType"));

+        list.addElement(type);

+        if (mode == MODE_GUID_DEFINED) {

+            //

+            // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>

+            //

+            Element ele = doc.createElement("input");

+            ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));

+            root.appendChild(ele);

+        } else {

+            //

+            // <sectFile fileName= "..."/>

+            //

+            Element ele = doc.createElement("sectFile");

+            ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));

+            root.appendChild(ele);

+        }

+    }

+

+    /**

+       Get the corresponding section file suffix.

+       

+      @param type Section type

+      @return Corresponding section file extension

+    **/

+    private String getSectionExt(String type) {

+        for (int i = 0; i < sectionExt.length; i++) {

+            if (sectionExt[i][0].equalsIgnoreCase(type)) {

+                return sectionExt[i][1];

+            }

+        }

+        return ".sec";

+    }

+

+    /**

+      Return the ANT script to call GenFfs Tool.

+      

+      @return ANT script to call GenFfs Tool

+    **/

+    public Element getFfsNode() {

+        return ffsNode;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
new file mode 100644
index 0000000..87650af
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
@@ -0,0 +1,225 @@
+/** @file

+  File is FileProcess class which is used to generate ANT script to build 

+  source files. 

+  

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build;

+

+import java.io.File;

+import java.util.Set;

+

+import org.apache.tools.ant.Project;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+/**

+  <p><code>FileProcess</code> is class to generate ANT script to build source

+  files.</p>

+  

+  <p>If file does not specify file type, <code>FileProcess</code> will judge 

+  by its extension. Following is the current supported extensions. </p>

+  

+  <pre>   

+          .c         |      C_Code

+          .asm       |      Assembly

+          .s         |      IPF_Assembly_Code

+          .h         |      Header

+          .lib       |      Static_Library

+          .i         |      IPF_PP_Code

+          .vfr       |      Vfr

+          .uni       |      Unicode

+          .dxs       |      Dependency_File

+          .bmp       |      Graphics

+          .efi       |      EFI

+  </pre>

+  

+  @since GenBuild 1.0

+**/

+public class FileProcess {

+    ///

+    ///  The mapping information about source suffix, result suffix, file type.

+    ///

+    public final String[][] fileTypes = { { ".c", ".obj", "C_Code" }, { ".asm", ".obj", "Assembly" },

+                                         { ".s", ".obj", "IPF_Assembly_Code" }, { ".h", "", "Header" },

+                                         { ".lib", "", "Static_Library" }, { ".src", ".c", "" },

+                                         { ".i", ".obj", "IPF_PP_Code" }, { ".vfr", ".obj", "Vfr" },

+                                         { ".uni", "", "Unicode" }, { ".dxs", "", "Dependency_File" },

+                                         { ".bmp", "", "Graphics" }, { ".efi", "", "EFI" } };

+

+    ///

+    /// Current ANT context. 

+    ///

+    private Project project;

+

+    ///

+    /// Current module's include pathes

+    ///

+    private Set<String> includes;

+

+    ///

+    /// Current source files. 

+    ///

+    private Set<String> sourceFiles;

+    

+    ///

+    /// Xml Document.

+    ///

+    private Document document;

+    

+    ///

+    /// The flag to ensure all unicode files build before others. 

+    ///

+    private boolean unicodeFirst = true;

+    

+    ///

+    /// The flag present whether current module contains Unicode files or not.

+    ///

+    private boolean unicodeExist = false;

+

+    /**

+      Initialize the project, includes, sourceFiles, document members.

+      

+      @param project ANT project

+      @param includes Module include pathes

+      @param sourceFiles Modules source files

+      @param document XML document

+    **/

+    public void init(Project project, Set<String> includes, Set<String> sourceFiles, Document document) {

+        this.document = document;

+        this.includes = includes;

+        this.project = project;

+        this.sourceFiles = sourceFiles;

+    }

+

+    /**

+      Parse file without file type. 

+      

+      @param filename Source file name

+      @param root Root node

+      @param unicodeFirst whether build Unicode file firstly or not

+    **/

+    public synchronized void parseFile(String filename, Node root, boolean unicodeFirst) {

+        this.unicodeFirst = unicodeFirst;

+        parseFile(filename, root);

+    }

+    

+    /**

+      Get whether current module contains Unicode files or not.

+      

+      @return Whether current module contains Unicode files or not

+    **/

+    public boolean isUnicodeExist() {

+        return unicodeExist;

+    }

+

+    /**

+      Parse file.

+      

+      @param filename Source file name

+      @param filetype Source file type

+      @param root Root node

+      @param unicodeFirst whether build Unicode file firstly or not

+    **/

+    public synchronized void parseFile(String filename, String filetype, Node root, boolean unicodeFirst) {

+        this.unicodeFirst = unicodeFirst;

+        parseFile(filename, filetype, root);

+    }

+    

+    /**

+      Find out source file's type. 

+      

+      @param filename Source file name

+      @param root Root node

+    **/

+    public synchronized void parseFile(String filename, Node root) {

+        boolean flag = false;

+        for (int i = 0; i < fileTypes.length; i++) {

+            if (filename.toLowerCase().endsWith(fileTypes[i][0])) {

+                flag = true;

+                parseFile(filename, fileTypes[i][2], root);

+            }

+        }

+        if (!flag) {

+            System.out.println("Warning: File " + filename + " is not known from its suffix.");

+        }

+    }

+

+    /**

+      Parse file. If flag <code>unicodeFirst</code> is true, then build all

+      unicode files firstly. 

+      

+      <p>Note that AutoGen.c is processed specially. It's output path is always

+      <code>${DEST_DIR_OUTPUT}</code>, others are <code>${DEST_DIR_OUTPUT}</code>

+      and relative to module path. </p>

+      

+      @param filename Source file name

+      @param filetype Source file type

+      @param root Root node

+    **/

+    public synchronized void parseFile(String filename, String filetype, Node root) {

+        if (unicodeFirst) {

+            if ( ! filetype.equalsIgnoreCase("Unicode")){

+                return ;

+            }

+            unicodeExist= true;

+        } else {

+            if (filetype.equalsIgnoreCase("Unicode")){

+                return ;

+            }

+        }

+        sourceFiles.add(filename);

+        if (filetype.equalsIgnoreCase("Header")) {

+            return;

+        }

+        if (filetype.equalsIgnoreCase("IPF_PP_Code")) {

+            return;

+        }

+        String module_path = project.getProperty("MODULE_DIR");

+        File moduleFile = new File(module_path);

+        File sourceFile = new File(filename);

+        // If source file is AutoGen.c, then Filepath is .

+        String sourceFilepath;

+        String sourceFilename;

+        if (sourceFile.getPath().endsWith("AutoGen.c")) {

+            sourceFilepath = ".";

+            sourceFilename = "AutoGen";

+            filetype = "AUTOGEN";

+        } else {

+            // sourceFile.

+            String str = sourceFile.getPath().substring(moduleFile.getPath().length() + 1);

+            int index = str.lastIndexOf(File.separatorChar);

+            sourceFilepath = ".";

+            if (index > 0) {

+                sourceFilepath = str.substring(0, index);

+                str = str.substring(index + 1);

+            }

+            sourceFilename = str;

+            index = str.lastIndexOf('.');

+            if (index > 0) {

+                sourceFilename = str.substring(0, index);

+            }

+        }

+        // <Build_filetype FILEPATH="" FILENAME="" />

+        Element ele = document.createElement("Build_" + filetype);

+        ele.setAttribute("FILEPATH", sourceFilepath);

+        ele.setAttribute("FILENAME", sourceFilename);

+        String[] includePaths = includes.toArray(new String[includes.size()]);

+        Element includesEle = document.createElement("EXTRA.INC");

+        for (int i = 0; i < includePaths.length; i++) {

+            Element includeEle = document.createElement("includepath");

+            includeEle.setAttribute("path", includePaths[i]);

+            includesEle.appendChild(includeEle);

+        }

+        ele.appendChild(includesEle);

+        root.appendChild(ele);

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
new file mode 100644
index 0000000..2d3318d
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
@@ -0,0 +1,1184 @@
+/** @file

+  This file is ANT task GenBuild. 

+ 

+  The file is used to parse a specified Module, and generate its build time 

+  ANT script build.xml, then call the the ANT script to build the module.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build;

+

+import java.io.File;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Iterator;

+import java.util.LinkedHashSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+import java.util.Vector;

+import java.util.regex.Matcher;

+import java.util.regex.Pattern;

+

+import javax.xml.parsers.DocumentBuilder;

+import javax.xml.parsers.DocumentBuilderFactory;

+import javax.xml.transform.OutputKeys;

+import javax.xml.transform.Result;

+import javax.xml.transform.Source;

+import javax.xml.transform.Transformer;

+import javax.xml.transform.TransformerFactory;

+import javax.xml.transform.dom.DOMSource;

+import javax.xml.transform.stream.StreamResult;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Project;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Ant;

+import org.apache.xmlbeans.XmlObject;

+import org.w3c.dom.Comment;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+import org.tianocore.build.autogen.AutoGen;

+import org.tianocore.build.autogen.CommonDefinition;

+import org.tianocore.build.fpd.FpdParserTask;

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.global.OutputManager;

+import org.tianocore.build.global.SurfaceAreaQuery;

+import org.tianocore.build.toolchain.ToolChainFactory;

+import org.tianocore.FilenameDocument;

+import org.tianocore.MsaHeaderDocument;

+import org.tianocore.MsaLibHeaderDocument;

+

+/**

+  <p>

+  <code>GenBuildTask</code> is an ANT task that can be used in ANT build

+  system. The main function of this task is to parse module's surface area,

+  then generate the corresponding <em>BaseName_build.xml</em> (the real ANT

+  build script) and call this to build the module.

+  </p>

+  

+  <p>

+  The usage is (take module <em>HelloWorld</em> for example):

+  </p>

+  

+  <pre>

+   &lt;GenBuild baseName=&quot;HelloWorld&quot; 

+             mbdFilename=&quot;${MODULE_DIR}/HelloWorld.mbd&quot; 

+             msaFilename=&quot;${MODULE_DIR}/HelloWorld.msa&quot;/&gt;

+  </pre>

+  

+  <p>

+  This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and

+  <em>AutoGen.h</em>. The task also parses the development environment

+  configuration files, such as collecting package information, setting compiler

+  flags and so on.

+  </p>

+  

+  

+  @since GenBuild 1.0

+**/

+public class GenBuildTask extends Task {

+

+    ///

+    /// Module surface area file.

+    ///

+    File msaFilename;

+

+    ///

+    /// Module build description file.

+    ///

+    File mbdFilename;

+

+    ///

+    /// Module surface area information after overrided.

+    ///

+    public Map<String, XmlObject> map = new HashMap<String, XmlObject>();

+

+    ///

+    /// Module's base name.

+    ///

+    private String baseName;

+

+    ///

+    /// Current build Arch, such as IA32, X64, IPF and so on.

+    ///

+    private String arch;

+

+    ///

+    /// Module's GUID (Globally Unique Identifier).

+    ///

+    private String guid;

+

+    ///

+    /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.

+    ///

+    private String componentType;

+

+    ///

+    /// This value is used in build time. Override module's component type. When

+    /// search FFS (Sections information) in common file, buildtype instead of

+    /// component type.

+    ///

+    private String buildType;

+

+    ///

+    /// List all required includes for current build module.

+    ///

+    public Set<String> includes = new LinkedHashSet<String>();

+

+    ///

+    /// List all libraries for current build module.

+    ///

+    public Set<String> libraries = new LinkedHashSet<String>();

+

+    ///

+    /// List all source files for current build module.

+    ///

+    public Set<String> sourceFiles = new LinkedHashSet<String>();

+

+    ///

+    /// Flag to identify what surface area files are specified. Current value is

+    /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,

+    /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.

+    /// 

+    /// @see org.tianocore.build.global.GlobaData

+    ///

+    private int flag = GlobalData.NO_SA;

+

+    ///

+    /// The information at the header of <em>build.xml</em>.

+    ///

+    private String info = "====================================================================\n"

+                        + "DO NOT EDIT \n"

+                        + "File auto-generated by build utility\n"

+                        + "\n"

+                        + "Abstract:\n"

+                        + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"

+                        + "=====================================================================";

+

+    /**

+      Public construct method. It is necessary for ANT task.

+    **/

+    public GenBuildTask() {

+    }

+

+    /**

+      ANT task's entry point, will be called after init(). The main steps is described

+      as following: 

+      <ul>

+      <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute

+      only once in whole build process; </li>

+      <li> Initialize global information (Framework DB, SPD files and all MSA files 

+      listed in SPD). This step will execute only once in whole build process; </li>

+      <li> Restore some important ANT property. If current build is single module 

+      build, here will set many default values; </li>

+      <li> Get the current module's overridded surface area information from 

+      global data; </li> 

+      <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and

+      DEST_DIR_DEBUG; </li>

+      <li> Get module dependent library instances and include pathes; </li>

+      <li> Judge whether current module is built. If yes, skip it; </li>

+      <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>

+      <li> Set up the compile flags; </li>

+      <li> Generate BaseName_build.xml; </li>

+      <li> Call to BaseName_build.xml, and build the current module. </li>

+      </ul>

+      

+      <p>Build is dependent on BuildMacro.xml which define many macro. </p> 

+      

+      @throws BuildException

+              From module build, exception from module surface area invalid.

+    **/

+    public void execute() throws BuildException {

+        System.out.println("Module [" + baseName + "] start.");

+        OutputManager.update(getProject());

+        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",

+                            getProject().getProperty("WORKSPACE_DIR"));

+        recallFixedProperties();

+        arch = getProject().getProperty("ARCH");

+        arch = arch.toUpperCase();

+        map = GlobalData.getDoc(baseName);

+        //

+        // Initialize SurfaceAreaQuery

+        //

+        SurfaceAreaQuery.setDoc(map);

+        //

+        // Setup Output Management

+        //

+        String[] outdir = SurfaceAreaQuery.getOutputDirectory();

+        OutputManager.update(getProject(), outdir[1], outdir[0]);

+

+        updateIncludesAndLibraries();

+

+        if (GlobalData.isModuleBuilt(baseName, arch)) {

+            return;

+        } else {

+            GlobalData.registerBuiltModule(baseName, arch);

+        }

+        //

+        // Call AutoGen

+        //

+        AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);

+        autogen.genAutogen();

+        //

+        // Update parameters

+        //

+        updateParameters();

+        //

+        // Update flags like CC_FLAGS, LIB_FLAGS etc.

+        //

+        flagsSetup();

+        GlobalData.addLibrary(baseName, arch, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");

+        GlobalData.addModuleLibrary(baseName, arch, libraries);

+        //

+        // If ComponentType is USER_DEFINED,

+        // then call the exist BaseName_build.xml directly.

+        //

+        if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {

+            System.out.println("Call user-defined " + baseName + "_build.xml");

+            Ant ant = new Ant();

+            ant.setProject(getProject());

+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");

+            ant.setInheritAll(true);

+            ant.init();

+            ant.execute();

+            return;

+        }

+        //

+        // Generate ${BASE_NAME}_build.xml file

+        //

+        System.out.println("Generate " + baseName + "_build.xml");

+        genBuildFile();

+        System.out.println("Call the " + baseName + "_build.xml");

+        Ant ant = new Ant();

+        ant.setProject(getProject());

+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");

+        ant.setInheritAll(true);

+        ant.init();

+        ant.execute();

+    }

+

+    /**

+      Return the name of the directory that corresponds to the architecture.

+      This is a translation from the XML Schema tag to a directory that

+      corresponds to our directory name coding convention.

+     

+    **/

+    private String archDir(String arch) {

+        return arch.replaceFirst("X64", "x64")

+                   .replaceFirst("IPF", "Ipf")

+                   .replaceFirst("IA32", "Ia32")

+                   .replaceFirst("ARM", "Arm")

+                   .replaceFirst("EBC", "Ebc");

+    }

+

+    /**

+      Get the dependent library instances and include package name from 

+      surface area, and initialize module include pathes. 

+     

+    **/

+    private void updateIncludesAndLibraries() {

+        List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);

+        if (rawIncludes != null) {

+            Iterator iter = rawIncludes.iterator();

+            while (iter.hasNext()) {

+                String packageName = (String) iter.next();

+                includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)

+                             + File.separatorChar + "Include");

+                includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)

+                             + File.separatorChar + "Include" + File.separatorChar + archDir(arch));

+            }

+        }

+        includes.add("${DEST_DIR_DEBUG}");

+        List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);

+        if (rawLibraries != null) {

+            Iterator iter = rawLibraries.iterator();

+            while (iter.hasNext()) {

+                libraries.add((String) iter.next());

+            }

+        }

+        normalize();

+    }

+

+    /**

+      Normalize all dependent library instance and include pathes' format. 

+     

+    **/

+    private void normalize() {

+        String[] includesArray = includes.toArray(new String[includes.size()]);

+        includes.clear();

+        for (int i = 0; i < includesArray.length; i++) {

+            includes.add((new File(includesArray[i])).getPath());

+        }

+        String[] librariesArray = libraries.toArray(new String[libraries.size()]);

+        libraries.clear();

+        for (int i = 0; i < librariesArray.length; i++) {

+            libraries.add((new File(librariesArray[i])).getPath());

+        }

+    }

+

+    /**

+      Restore some important ANT property. If current build is single module 

+      build, here will set many default values.

+      

+      <p> If current build is single module build, then the default <code>ARCH</code>

+      is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, 

+      <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>

+      

+      <p> Note that for package build, package name is stored in <code>PLATFORM</code>

+      and package directory is stored in <code>PLATFORM_DIR</code>. </p> 

+     

+      @see org.tianocore.build.global.OutputManager

+    **/

+    private void recallFixedProperties() {

+        //

+        // If build is for module build

+        //

+        if (getProject().getProperty("PACKAGE_DIR") == null) {

+            ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());

+            toolChainFactory.setupToolChain();

+            //

+            // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO

+            //

+            if (getProject().getProperty("ARCH") == null) {

+                getProject().setProperty("ARCH", "IA32");

+            }

+            String packageName = GlobalData.getPackageNameForModule(baseName);

+            getProject().setProperty("PACKAGE", packageName);

+            

+            String packageDir = GlobalData.getPackagePath(packageName);

+            getProject().setProperty("PACKAGE_DIR",

+                                     getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);

+            

+            getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());

+            

+            getProject().setProperty("MODULE_DIR",

+                                     getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));

+        }

+        if (OutputManager.PLATFORM != null) {

+            getProject().setProperty("PLATFORM", OutputManager.PLATFORM);

+        }

+        if (OutputManager.PLATFORM_DIR != null) {

+            getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);

+        }

+    }

+

+    /**

+      The whole BaseName_build.xml is composed of seven part. 

+      <ul>

+      <li> ANT properties; </li>

+      <li> Dependent module (dependent library instances in most case); </li>

+      <li> Source files; </li>

+      <li> Sections if module is not library; </li>

+      <li> Output (different for library module and driver module); </li>

+      <li> Clean; </li>

+      <li> Clean all. </li>

+      </ul>

+      

+      @throws BuildException

+              Error throws during BaseName_build.xml generating. 

+    **/

+    private void genBuildFile() throws BuildException {

+        FfsProcess fp = new FfsProcess();

+        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();

+        try {

+            DocumentBuilder dombuilder = domfac.newDocumentBuilder();

+            Document document = dombuilder.newDocument();

+            Comment rootComment = document.createComment(info);

+            //

+            // create root element and its attributes

+            //

+            Element root = document.createElement("project");

+            //

+            // root.setAttribute("name", base_name);

+            //

+            root.setAttribute("default", "main");

+            root.setAttribute("basedir", ".");

+            //

+            // element for External ANT tasks

+            //

+            root.appendChild(document.createComment("Apply external ANT tasks"));

+            Element ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "frameworktasks.tasks");

+            root.appendChild(ele);

+            ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "cpptasks.tasks");

+            root.appendChild(ele);

+            ele = document.createElement("typedef");

+            ele.setAttribute("resource", "cpptasks.types");

+            root.appendChild(ele);

+            ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");

+            root.appendChild(ele);

+            //

+            // elements for Properties

+            //

+            root.appendChild(document.createComment("All Properties"));

+            ele = document.createElement("property");

+            ele.setAttribute("name", "BASE_NAME");

+            ele.setAttribute("value", baseName);

+            root.appendChild(ele);

+            //

+            // Generate the default target,

+            // which depends on init, sections and output target

+            //

+            root.appendChild(document.createComment("Default target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "main");

+            ele.setAttribute("depends", "libraries, sourcefiles, sections, output");

+            root.appendChild(ele);

+            //

+            // compile all source files

+            //

+            root.appendChild(document.createComment("Compile all dependency Library instances."));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "libraries");

+            //

+            // Parse all sourfiles but files specified in sections

+            //

+            applyLibraryInstance(document, ele);

+            root.appendChild(ele);

+            //

+            // compile all source files

+            //

+            root.appendChild(document.createComment("sourcefiles target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "sourcefiles");

+            //

+            // Parse all sourfiles but files specified in sections

+            //

+            applyCompileElement(document, ele);

+            root.appendChild(ele);

+            //

+            // generate the init target

+            // main purpose is create all nessary pathes

+            // generate the sections target

+            //

+            root.appendChild(document.createComment("sections target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "sections");

+            applySectionsElement(document, ele, fp);

+            root.appendChild(ele);

+            //

+            // generate the output target

+            //

+            root.appendChild(document.createComment("output target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "output");

+            applyOutputElement(document, ele, fp);

+            root.appendChild(ele);

+            //

+            // generate the clean target

+            //

+            root.appendChild(document.createComment("clean target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "clean");

+            applyCleanElement(document, ele);

+            root.appendChild(ele);

+            //

+            // generate the Clean All target

+            //

+            root.appendChild(document.createComment("Clean All target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "cleanall");

+            applyDeepcleanElement(document, ele);

+            root.appendChild(ele);

+            //

+            // add the root element to the document

+            //

+            document.appendChild(rootComment);

+            document.appendChild(root);

+            //

+            // Prepare the DOM document for writing

+            //

+            Source source = new DOMSource(document);

+            //

+            // Prepare the output file

+            //

+            File file = new File(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName

+                                 + "_build.xml");

+            //

+            // generate all directory path

+            //

+            (new File(file.getParent())).mkdirs();

+            Result result = new StreamResult(file);

+            //

+            // Write the DOM document to the file

+            //

+            Transformer xformer = TransformerFactory.newInstance().newTransformer();

+            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

+            xformer.setOutputProperty(OutputKeys.INDENT, "yes");

+            xformer.transform(source, result);

+        } catch (Exception ex) {

+            throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());

+        }

+    }

+

+    /**

+      Generate the clean elements for BaseName_build.xml. 

+      

+      @param document current BaseName_build.xml XML document

+      @param root Root element for current

+    **/

+    private void applyCleanElement(Document document, Node root) {

+        String[] libinstances = libraries.toArray(new String[libraries.size()]);

+        for (int i = 0; i < libinstances.length; i++) {

+            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");

+

+            Element ifEle = document.createElement("if");

+            Element availableEle = document.createElement("available");

+            availableEle.setAttribute("file", file.getPath());

+            ifEle.appendChild(availableEle);

+            Element elseEle = document.createElement("then");

+

+            Element ele = document.createElement("ant");

+            ele.setAttribute("antfile", file.getPath());

+            ele.setAttribute("inheritAll", "false");

+            ele.setAttribute("target", libinstances[i] + "_clean");

+            //

+            // Workspace_DIR

+            //

+            Element property = document.createElement("property");

+            property.setAttribute("name", "WORKSPACE_DIR");

+            property.setAttribute("value", "${WORKSPACE_DIR}");

+            ele.appendChild(property);

+            //

+            // Package Dir

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "PACKAGE_DIR");

+            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar

+                                           + GlobalData.getPackagePathForModule(libinstances[i]));

+            ele.appendChild(property);

+            //

+            // ARCH

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "ARCH");

+            property.setAttribute("value", "${ARCH}");

+            ele.appendChild(property);

+            //

+            // TARGET

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "TARGET");

+            property.setAttribute("value", "${TARGET}");

+            ele.appendChild(property);

+            //

+            // PACKAGE

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "PACKAGE");

+            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));

+            ele.appendChild(property);

+

+            elseEle.appendChild(ele);

+            ifEle.appendChild(elseEle);

+            root.appendChild(ifEle);

+        }

+    }

+

+    /**

+      Generate the cleanall elements for BaseName_build.xml. 

+      

+      @param document current BaseName_build.xml XML document

+      @param root Root element for current

+    **/

+    private void applyDeepcleanElement(Document document, Node root) {

+        String[] libinstances = libraries.toArray(new String[libraries.size()]);

+        for (int i = 0; i < libinstances.length; i++) {

+            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");

+

+            Element ifEle = document.createElement("if");

+            Element availableEle = document.createElement("available");

+            availableEle.setAttribute("file", file.getPath());

+            ifEle.appendChild(availableEle);

+            Element elseEle = document.createElement("then");

+

+            Element ele = document.createElement("ant");

+            ele.setAttribute("antfile", file.getPath());

+            ele.setAttribute("inheritAll", "false");

+            ele.setAttribute("target", libinstances[i] + "_cleanall");

+            //

+            // Workspace_DIR

+            //

+            Element property = document.createElement("property");

+            property.setAttribute("name", "WORKSPACE_DIR");

+            property.setAttribute("value", "${WORKSPACE_DIR}");

+            ele.appendChild(property);

+            //

+            // Package Dir

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "PACKAGE_DIR");

+            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar

+                                           + GlobalData.getPackagePathForModule(libinstances[i]));

+            ele.appendChild(property);

+            //

+            // ARCH

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "ARCH");

+            property.setAttribute("value", "${ARCH}");

+            ele.appendChild(property);

+            //

+            // TARGET

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "TARGET");

+            property.setAttribute("value", "${TARGET}");

+            ele.appendChild(property);

+            //

+            // PACKAGE

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "PACKAGE");

+            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));

+            ele.appendChild(property);

+

+            elseEle.appendChild(ele);

+            ifEle.appendChild(elseEle);

+            root.appendChild(ifEle);

+        }

+    }

+

+    /**

+      Generate the dependent library instances elements for BaseName_build.xml. 

+      

+      @param document current BaseName_build.xml XML document

+      @param root Root element for current

+    **/

+    private void applyLibraryInstance(Document document, Node root) {

+        String[] libinstances = libraries.toArray(new String[libraries.size()]);

+        for (int i = 0; i < libinstances.length; i++) {

+            Element ele = document.createElement("ant");

+            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");

+            ele.setAttribute("antfile", file.getPath());

+            ele.setAttribute("inheritAll", "false");

+            ele.setAttribute("target", libinstances[i]);

+            //

+            // Workspace_DIR

+            //

+            Element property = document.createElement("property");

+            property.setAttribute("name", "WORKSPACE_DIR");

+            property.setAttribute("value", "${WORKSPACE_DIR}");

+            ele.appendChild(property);

+            //

+            // Package Dir

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "PACKAGE_DIR");

+            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar

+                                           + GlobalData.getPackagePathForModule(libinstances[i]));

+            ele.appendChild(property);

+            //

+            // ARCH

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "ARCH");

+            property.setAttribute("value", "${ARCH}");

+            ele.appendChild(property);

+            //

+            // TARGET

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "TARGET");

+            property.setAttribute("value", "${TARGET}");

+            ele.appendChild(property);

+            //

+            // PACKAGE

+            //

+            property = document.createElement("property");

+            property.setAttribute("name", "PACKAGE");

+            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));

+            ele.appendChild(property);

+            root.appendChild(ele);

+        }

+        Element expand = document.createElement("Expand");

+        root.appendChild(expand);

+    }

+    

+    /**

+      Generate the build source files elements for BaseName_build.xml. 

+      

+      @param document current BaseName_build.xml XML document

+      @param root Root element for current

+    **/

+    private void applyCompileElement(Document document, Node root) {

+        FileProcess fileProcess = new FileProcess();

+        fileProcess.init(getProject(), includes, sourceFiles, document);

+        Node[] files = this.getSourceFiles();

+        //

+        // Parse all unicode files

+        //

+        for (int i = 0; i < files.length; i++) {

+            String filetype = getFiletype(files[i]);

+            if (filetype != null) {

+                fileProcess.parseFile(getFilename(files[i]), filetype, root, true);

+            } else {

+                fileProcess.parseFile(getFilename(files[i]), root, true);

+            }

+        }

+        if (fileProcess.isUnicodeExist()) {

+            Element ele = document.createElement("Build_Unicode_Database");

+            ele.setAttribute("FILEPATH", ".");

+            ele.setAttribute("FILENAME", "${BASE_NAME}");

+            root.appendChild(ele);

+        }

+

+        //

+        // Parse AutoGen.c & AutoGen.h

+        //

+        if (!baseName.equalsIgnoreCase("Shell")) {

+            fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,

+                                  false);

+        }

+        //

+        // Parse all source files

+        //

+        for (int i = 0; i < files.length; i++) {

+            String filetype = getFiletype(files[i]);

+            if (filetype != null) {

+                fileProcess.parseFile(getFilename(files[i]), filetype, root, false);

+            } else {

+                fileProcess.parseFile(getFilename(files[i]), root, false);

+            }

+        }

+        //

+        // root.appendChild(parallelEle);

+        //

+        Iterator iter = sourceFiles.iterator();

+        String str = "";

+        while (iter.hasNext()) {

+            str += " " + (String) iter.next();

+        }

+        getProject().setProperty("SOURCE_FILES", str);

+    }

+

+    /**

+      Generate the section elements for BaseName_build.xml. Library module will

+      skip this process.  

+      

+      @param document current BaseName_build.xml XML document

+      @param root Root element for current

+    **/

+    private void applySectionsElement(Document document, Node root, FfsProcess fp) {

+        if (fp.initSections(buildType, getProject())) {

+            String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);

+            String[] list = fp.getGenSectionElements(document, baseName, guid, targetFilename);

+

+            for (int i = 0; i < list.length; i++) {

+                Element ele = document.createElement(list[i]);

+                ele.setAttribute("FILEPATH", ".");

+                ele.setAttribute("FILENAME", "${BASE_NAME}");

+                root.appendChild(ele);

+            }

+        }

+    }

+

+    /**

+      Generate the output elements for BaseName_build.xml. If module is library,

+      call the <em>LIB</em> command, else call the <em>GenFfs</em> command. 

+      

+      @param document current BaseName_build.xml XML document

+      @param root Root element for current

+    **/

+    private void applyOutputElement(Document document, Node root, FfsProcess fp) {

+        if (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {

+            //

+            // call Lib command

+            //

+            Element cc = document.createElement("Build_Library");

+            cc.setAttribute("FILENAME", baseName);

+            root.appendChild(cc);

+        }

+        //

+        // if it is a module but library

+        //

+        else {

+            if (fp.getFfsNode() != null) {

+                root.appendChild(fp.getFfsNode());

+            }

+        }

+    }

+

+    /**

+      Get file name from node. If some wrong, return string with zero length. 

+      

+       @param node Filename node of MSA/MBD or specified in each Section

+       @return File name

+    **/

+    private String getFilename(Node node) {

+        String path = null;

+        String filename = "${MODULE_DIR}" + File.separatorChar;

+        String str = "";

+        try {

+            FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);

+            str = file.getFilename().getStringValue().trim();

+            path = file.getFilename().getPath();

+        } catch (Exception e) {

+            str = "";

+        }

+        if (path != null) {

+            filename += path + File.separatorChar + str;

+        } else {

+            filename += str;

+        }

+        return getProject().replaceProperties(filename);

+    }

+

+    /**

+      Get file type from node. If some wrong or not specified, return 

+      <code>null</code>.  

+      

+      @param node Filename node of MSA/MBD or specified in each Section

+      @return File type

+    **/

+    private String getFiletype(Node node) {

+        String str = null;

+        try {

+            FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);

+            str = file.getFilename().getFileType();

+        } catch (Exception e) {

+            str = null;

+        }

+        return str;

+    }

+

+    /**

+      Return all source files but AutoGen.c.

+      

+      @return source files Node array

+    **/

+    public Node[] getSourceFiles() {

+        XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);

+        if (files == null) {

+            return new Node[0];

+        }

+        Vector<Node> vector = new Vector<Node>();

+        for (int i = 0; i < files.length; i++) {

+            vector.addElement(files[i].getDomNode());

+        }

+        //

+        // To be consider sourcefiles from Sections

+        //

+        return vector.toArray(new Node[vector.size()]);

+    }

+

+    /**

+      Get current module's base name. 

+      

+      @return base name

+    **/

+    public String getBaseName() {

+        return baseName;

+    }

+

+    /**

+      Set MBD surface area file. For ANT use.

+      

+      @param mbdFilename Surface Area file

+    **/

+    public void setMbdFilename(File mbdFilename) {

+        this.mbdFilename = mbdFilename;

+    }

+

+    /**

+      Set MSA surface area file. For ANT use.

+      

+      @param msaFilename Surface Area file

+    **/

+    public void setMsaFilename(File msaFilename) {

+        this.msaFilename = msaFilename;

+    }

+

+    /**

+      Compile flags setup. 

+      

+      <p> Take command <code>CC</code> and arch <code>IA32</code> for example, 

+      Those flags are from <code>ToolChainFactory</code>: </p>

+      <ul>

+      <li> IA32_CC </li>

+      <li> IA32_CC_STD_FLAGS </li>

+      <li> IA32_CC_GLOBAL_FLAGS </li>

+      <li> IA32_CC_GLOBAL_ADD_FLAGS </li>

+      <li> IA32_CC_GLOBAL_SUB_FLAGS </li>

+      </ul>

+      Those flags can user-define: 

+      <ul>

+      <li> IA32_CC_PROJ_FLAGS </li>

+      <li> IA32_CC_PROJ_ADD_FLAGS </li>

+      <li> IA32_CC_PROJ_SUB_FLAGS </li>

+      <li> CC_PROJ_FLAGS </li>

+      <li> CC_PROJ_ADD_FLAGS </li>

+      <li> CC_PROJ_SUB_FLAGS </li>

+      <li> CC_FLAGS </li>

+      <li> IA32_CC_FLAGS </li>

+      </ul>

+      

+      <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or

+      IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>

+      

+      Note that the <code>ToolChainFactory</code> executes only once 

+      during whole build process. 

+    **/

+    private void flagsSetup() {

+        Project project = getProject();

+        //

+        // If ToolChain has been set up before, do nothing.

+        //

+        ToolChainFactory toolChainFactory = new ToolChainFactory(project);

+        toolChainFactory.setupToolChain();

+

+        String[] cmd = ToolChainFactory.commandType;

+        Set<String> addSet = new HashSet<String>(40);

+        Set<String> subSet = new HashSet<String>(40);

+        for (int i = 0; i < cmd.length; i++) {

+            String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);

+            //

+            // Command line path+command name

+            //

+            if (str != null) {

+                project.setProperty(cmd[i], str);

+            }

+            //

+            // ARCH_CMD_STD_FLAGS

+            //

+            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+                project.setProperty(cmd[i] + "_STD_FLAGS", str);

+            }

+            //

+            // ARCH_CMD_GLOBAL_FLAGS

+            //

+            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+            }

+            //

+            // ARCH_CMD_GLOBAL_ADD_FLAGS

+            //

+            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+            }

+            //

+            // ARCH_CMD_GLOBAL_SUB_FLAGS

+            //

+            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");

+            if (str != null) {

+                putFlagsToSet(subSet, str);

+            }

+            //

+            // ARCH_CMD_PROJ_FLAGS

+            //

+            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+            }

+            //

+            // ARCH_CMD_PROG_FLAGS

+            //

+            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+            }

+            //

+            // ARCH_CMD_PROG_FLAGS

+            //

+            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");

+            if (str != null) {

+                putFlagsToSet(subSet, str);

+            }

+            //

+            // CMD_PROJ_FLAGS

+            //

+            str = project.getProperty(cmd[i] + "_PROJ_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+            }

+            //

+            // CMD_PROG_FLAGS

+            //

+            str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");

+            if (str != null) {

+                putFlagsToSet(addSet, str);

+            }

+            //

+            // CMD_PROG_FLAGS

+            //

+            str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");

+            if (str != null) {

+                putFlagsToSet(subSet, str);

+            }

+            //

+            // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions

+            //

+            if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {

+                project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));

+                addSet.clear();

+                subSet.clear();

+                putFlagsToSet(addSet, project.replaceProperties(str));

+                project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));

+                addSet.clear();

+                subSet.clear();

+            }

+            //

+            // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions

+            //

+            else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {

+                project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));

+                addSet.clear();

+                subSet.clear();

+                putFlagsToSet(addSet, project.replaceProperties(str));

+                project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));

+                addSet.clear();

+                subSet.clear();

+            } else {

+                project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));

+                addSet.clear();

+                subSet.clear();

+            }

+        }

+        project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));

+    }

+

+    /**

+      Initialize some properties will be used in current module build, including

+      user-defined option from <em>Option</em> of <em>BuildOptions</em> in 

+      surface area. 

+    **/

+    private void updateParameters() {

+        getProject().setProperty("OBJECTS", "");

+        getProject().setProperty("SDB_FILES", "");

+        getProject().setProperty("BASE_NAME", baseName);

+        if (map.get("MsaHeader") != null) {

+            flag = GlobalData.MSA_AND_MBD;

+            MsaHeaderDocument.MsaHeader header = ((MsaHeaderDocument) map.get("MsaHeader")).getMsaHeader();

+            guid = header.getGuid().getStringValue();

+            componentType = header.getComponentType().toString();

+        } 

+        

+        else if (map.get("MsaLibHeader") != null) {

+            flag = GlobalData.LIBMSA_AND_LIBMBD;

+            MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))

+                                                                                                       .getMsaLibHeader();

+            guid = header.getGuid().getStringValue();

+            componentType = header.getComponentType().toString();

+        }

+        

+        if (componentType != null) {

+            getProject().setProperty("COMPONENT_TYPE", componentType);

+        }

+        

+        if (guid != null) {

+            getProject().setProperty("FILE_GUID", guid);

+        }

+        //

+        // Get all options and set to properties

+        //

+        String[][] options = SurfaceAreaQuery.getOptions(arch);

+        for (int i = 0; i < options.length; i++) {

+            if (options[i][0] != null && options[i][1] != null) {

+                getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));

+            }

+        }

+

+        buildType = getProject().getProperty("BUILD_TYPE");

+        if (buildType == null) {

+            buildType = componentType;

+        }

+

+    }

+

+    /**

+      Separate the string and instore in set.

+       

+      <p> String is separated by Java Regulation Expression 

+      "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>

+      

+      <p>For example: </p>

+      

+      <pre>

+        "/nologo", "/W3", "/WX"

+        "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""

+      </pre>

+      

+      @param set store the separated string

+      @param str string to separate

+    **/

+    private void putFlagsToSet(Set<String> set, String str) {

+        Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");

+        Matcher matcher = myPattern.matcher(str + " ");

+        while (matcher.find()) {

+            String item = str.substring(matcher.start(1), matcher.end(1));

+            if (!set.contains(item)) {

+                set.add(item);

+            }

+        }

+    }

+    

+    /**

+      Generate the final flags string will be used by compile command. 

+      

+      @param add the add flags set

+      @param sub the sub flags set

+      @return final flags after add set substract sub set

+    **/

+    private String getFlags(Set<String> add, Set<String> sub) {

+        String result = "";

+        add.removeAll(sub);

+        Iterator iter = add.iterator();

+        while (iter.hasNext()) {

+            String str = getProject().replaceProperties((String) iter.next());

+            result += str.substring(1, str.length() - 1) + " ";

+        }

+        return result;

+    }

+

+    /**

+      Generate the flags string with original format. The format is defined by 

+      Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>

+      

+      <p>For example: </p>

+      

+      <pre>

+        "/nologo", "/W3", "/WX"

+        "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""

+      </pre>

+      

+      @param add the add flags set

+      @param sub the sub flags set

+      @return flags with original format

+    **/

+    private String getRawFlags(Set<String> add, Set<String> sub) {

+        String result = "";

+        add.removeAll(sub);

+        Iterator iter = add.iterator();

+        while (iter.hasNext()) {

+            String str = getProject().replaceProperties((String) iter.next());

+            result += "\"" + str.substring(1, str.length() - 1) + "\", ";

+        }

+        return result;

+    }

+

+    /**

+      Set base name. For ANT use.

+      

+      @param baseName Base name

+    **/

+    public void setBaseName(String baseName) {

+        this.baseName = baseName;

+    }

+

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
new file mode 100644
index 0000000..c2b7cc9
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
@@ -0,0 +1,190 @@
+/** @file

+  

+  This file is an ANT task OutputDirSetupTask. 

+  

+  This task main purpose is to setup some necessary properties for Package,

+  Platform or Module clean. 

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build;

+

+import java.io.File;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+import org.apache.xmlbeans.XmlObject;

+

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.global.OutputManager;

+import org.tianocore.build.global.SurfaceAreaQuery;

+import org.tianocore.build.toolchain.ToolChainFactory;

+

+/**

+  <code>OutputDirSetupTask</code> is an ANT task that can be used in ANT build

+  system. The main function of this task is to initialize some basic information

+  for Package|Platform|Module clean or cleanall usage. 

+  

+  <p>Here is an example: </p> 

+  <pre>

+     &lt;OutputDirSetup baseName="HelloWorld" 

+                     mbdFilename="${MODULE_DIR}\HelloWorld.mbd" 

+                     msaFilename="${MODULE_DIR}\HelloWorld.msa" /&gt;

+  </pre>

+  

+  <p>Note that all this task doing is part of GenBuildTask. </p>

+  

+  @since GenBuild 1.0

+  @see org.tianocore.build.GenBuildTask

+**/

+public class OutputDirSetupTask extends Task {

+    

+    ///

+    /// Module surface area file.

+    ///

+    File msaFilename;

+

+    ///

+    /// Module build description file.

+    ///

+    File mbdFilename;

+    

+    ///

+    /// Module surface area information after overrided.

+    ///

+    public Map<String, XmlObject> map = new HashMap<String, XmlObject>();

+    

+    ///

+    /// Module's base name.

+    ///

+    private String baseName;

+    

+    /**

+      Public construct method. It is necessary for ANT task.

+    **/

+    public OutputDirSetupTask () {

+    }

+    

+    /**

+      ANT task's entry point, will be called after init(). The main steps is described

+      as following: 

+      <ul>

+      <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute

+      only once in whole build process; </li>

+      <li> Initialize global information (Framework DB, SPD files and all MSA files 

+      listed in SPD). This step will execute only once in whole build process; </li>

+      <li> Restore some important ANT property. If current build is single module 

+      build, here will set many default values; </li>

+      <li> Get the current module's overridded surface area information from 

+      global data; </li> 

+      <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and

+      DEST_DIR_DEBUG; </li>

+      </ul>

+      

+      @throws BuildException

+              From module build, exception from module surface area invalid.

+    **/

+    public void execute() throws BuildException {

+        System.out.println("Deleting module [" + baseName + "] start.");

+        OutputManager.update(getProject());

+        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()

+                        .getProperty("WORKSPACE_DIR"));

+        recallFixedProperties();

+        map = GlobalData.getDoc(baseName);

+        //

+        // Initialize SurfaceAreaQuery

+        //

+        SurfaceAreaQuery.setDoc(map);

+        //

+        // Setup Output Management

+        //

+        String[] outdir = SurfaceAreaQuery.getOutputDirectory();

+        OutputManager.update(getProject(), outdir[1], outdir[0]);

+    }

+    

+    /**

+      Get current module's base name. 

+      

+      @return base name

+    **/

+    public String getBaseName() {

+        return baseName;

+    }

+

+    /**

+      Set base name. For ANT use.

+      

+      @param baseName Base name

+    **/

+    public void setBaseName(String baseName) {

+        this.baseName = baseName;

+    }

+

+    /**

+      Set MBD surface area file. For ANT use.

+      

+      @param mbdFilename Surface Area file

+    **/

+    public void setMbdFilename(File mbdFilename) {

+        this.mbdFilename = mbdFilename;

+    }

+

+    /**

+      Set MSA surface area file. For ANT use.

+      

+      @param msaFilename Surface Area file

+    **/

+    public void setMsaFilename(File msaFilename) {

+        this.msaFilename = msaFilename;

+    }

+    

+    /**

+      Restore some important ANT property. If current build is single module 

+      build, here will set many default values.

+      

+      <p> If current build is single module build, then the default <code>ARCH</code>

+      is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, 

+      <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>

+      

+      <p> Note that for package build, package name is stored in <code>PLATFORM</code>

+      and package directory is stored in <code>PLATFORM_DIR</code>. </p> 

+     

+      @see org.tianocore.build.global.OutputManager

+    **/

+    private void recallFixedProperties(){

+        //

+        // If build is for module build

+        //

+        if (getProject().getProperty("PACKAGE_DIR") == null) {

+            ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());

+            toolChainFactory.setupToolChain();

+            //

+            // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO

+            //

+            if (getProject().getProperty("ARCH") == null){

+                getProject().setProperty("ARCH", "IA32");

+            }

+            String packageName = GlobalData.getPackageNameForModule(baseName);

+            getProject().setProperty("PACKAGE", packageName);

+            String packageDir = GlobalData.getPackagePath(packageName);

+            getProject().setProperty("PACKAGE_DIR", getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);

+            getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());

+            getProject().setProperty("MODULE_DIR", getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));

+        }

+        if (OutputManager.PLATFORM != null) {

+            getProject().setProperty("PLATFORM", OutputManager.PLATFORM);

+        }

+        if (OutputManager.PLATFORM_DIR != null) {

+            getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);

+        }

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
new file mode 100644
index 0000000..62bb4c6
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
@@ -0,0 +1,2018 @@
+/** @file

+ AutoGen class.

+

+ This class is to generate Autogen.h and Autogen.c according to module surface area

+ or library surface area.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+package org.tianocore.build.autogen;

+

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.global.Spd;

+import org.tianocore.build.global.SurfaceAreaQuery;

+import org.tianocore.GuidsDocument;

+import org.tianocore.LibraryClassDocument.LibraryClass;

+import org.tianocore.PPIsDocument;

+import org.tianocore.ProtocolsDocument;

+import org.tianocore.build.pcd.action.PCDAutoGenAction;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.xmlbeans.XmlObject;

+

+import java.io.File;

+import java.io.FileReader;

+import java.io.FileWriter;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Map;

+

+/**

+  This class is to generate Autogen.h and Autogen.c according to module surface

+  area or library surface area.

+**/

+public class AutoGen {

+    ///

+    /// The output path of Autogen.h and Autogen.c

+    ///

+    private String outputPath;

+

+    ///

+    /// The base name of module or library.

+    ///

+    private String baseName;

+

+    ///

+    /// The build architecture

+    ///

+    private String arch;

+

+    ///

+    /// PcdAutogen instance which is used to manage how to generate the PCD

+    /// information.

+    ///

+    private PCDAutoGenAction myPcdAutogen;

+

+    ///

+    /// The protocl list which records in module or library surface area and

+    /// it's dependence on library instance surface area.

+    ///

+    private List<String> mProtocolList = new ArrayList<String>();

+

+    ///

+    /// The Ppi list which recorded in module or library surface area and its

+    /// dependency on library instance surface area.

+    ///

+    private List<String> mPpiList = new ArrayList<String>();

+

+    ///

+    /// The Guid list which recoreded in module or library surface are and it's

+    /// dependence on library instance surface area.

+    ///

+    private List<GuidsDocument.Guids.GuidEntry> mGuidList = new ArrayList<GuidsDocument.Guids.GuidEntry>();

+

+    /**

+      Construct function

+      

+      This function mainly initialize some member variable.

+      

+      @param outputPath    Output path of AutoGen file.

+      @param baseName      Module base name.

+      @param arch          Target architecture.

+    **/

+    public AutoGen(String outputPath, String baseName, String arch) {

+        this.outputPath = outputPath;

+        this.baseName = baseName;

+        this.arch = arch;

+

+    }

+

+    /**

+      saveFile function

+      

+      This function save the content in stringBuffer to file.

+      

+      @param fileName      The name of file.

+      @param fileBuffer    The content of AutoGen file in buffer.

+      @return              "true" successful, "false" failed.

+    **/

+    private boolean saveFile(String fileName, StringBuffer fileBuffer) {

+        try {

+            File autoGenH = new File(fileName);

+

+            //

+            // if the file exists, compare their content

+            //

+            if (autoGenH.exists()) {

+                FileReader fIn = new FileReader(autoGenH);

+                char[] oldFileBuffer = new char[(int) autoGenH.length()];

+                fIn.read(oldFileBuffer, 0, (int) autoGenH.length());

+                fIn.close();

+

+                //

+                // if we got the same file, don't re-generate it to prevent

+                // sources depending on it from re-building

+                //

+                if (fileBuffer.toString().compareTo(new String(oldFileBuffer)) == 0) {

+                    return true;

+                }

+            }

+            FileWriter fOut = new FileWriter(autoGenH);

+            fOut.write(fileBuffer.toString());

+            fOut.close();

+        } catch (Exception e) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+      genAutogen function

+      

+      This function call libGenAutoGen or moduleGenAutogen function, which

+      dependence on generate library autogen or module autogen.

+      

+      @throws BuildException    Failed to creat AutoGen.c & AutoGen.h.

+    **/

+    public void genAutogen() throws BuildException {

+        try {

+            //

+            // If outputPath do not exist, create it.

+            //

+            File path = new File(outputPath);

+            path.mkdirs();

+

+            //

+            // Check current is library or not, then call the corresponding

+            // function.

+            //

+            if (SurfaceAreaQuery.getComponentType().equalsIgnoreCase(

+                    CommonDefinition.LibraryStr)) {

+                libGenAutogen();

+            } else {

+                moduleGenAutogen();

+            }

+

+        } catch (Exception e) {

+            throw new BuildException(

+                    "Failed to create AutoGen.c & AutoGen.h!\n"

+                            + e.getMessage());

+        }

+    }

+

+    /** 

+      moduleGenAutogen function

+    

+      This function generates AutoGen.c & AutoGen.h for module.

+     

+      @throws BuildException  Faile to create module AutoGen.c & AutoGen.h.

+    **/

+    void moduleGenAutogen() throws BuildException {

+

+        try {

+            moduleGenAutogenC();

+            moduleGenAutogenH();

+        } catch (Exception e) {

+            throw new BuildException(

+                    "Faile to create module AutoGen.c & AutoGen.h!\n"

+                            + e.getMessage());

+        }

+    }

+

+    /**

+      libGenAutogen function

+      

+      This function generates AutoGen.c & AutoGen.h for library.

+      

+      @throws BuildException

+                  Faile to create library AutoGen.c & AutoGen.h

+    **/

+    void libGenAutogen() throws BuildException {

+        try {

+            libGenAutogenC();

+            libGenAutogenH();

+        } catch (Exception e) {

+            throw new BuildException(

+                    "Faile to create library AutoGen.c & AutoGen.h!\n"

+                            + e.getMessage());

+        }

+    }

+

+    /**

+      moduleGenAutogenH

+     

+      This function generates AutoGen.h for module.

+      

+      @throws BuildException

+                  Failed to generate AutoGen.h.

+    **/

+    void moduleGenAutogenH() throws BuildException {

+

+        List<String> libClassIncludeH;

+        String moduleType;

+        List<String> headerFileList;

+

+        StringBuffer fileBuffer = new StringBuffer(8192);

+        

+        //

+        // Write Autogen.h header notation 

+        //

+        fileBuffer.append(CommonDefinition.autogenHNotation);

+        

+        //

+        // Add #ifndef  ${BaseName}_AUTOGENH

+        //     #def     ${BseeName}_AUTOGENH

+        //

+        fileBuffer.append("#ifndef    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");

+        fileBuffer.append("#define    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");

+        

+        //

+        // Write the specification version and release version at the begine

+        // of autogen.h file.

+        // Note: the specification version and release version should

+        // be got from module surface area instead of hard code by it's moduleType.

+        //

+        moduleType = SurfaceAreaQuery.getModuleType();

+        switch (CommonDefinition.getModuleType(moduleType)) {

+        case CommonDefinition.ModuleTypeDxeCore:

+        case CommonDefinition.ModuleTypeDxeDriver:

+        case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+        case CommonDefinition.ModuleTypeDxeSmmDriver:

+        case CommonDefinition.ModuleTypeDxeSalDriver:

+        case CommonDefinition.ModuleTypeUefiDriver:

+        case CommonDefinition.ModuleTypeUefiApplication:

+            fileBuffer.append(CommonDefinition.autoGenHLine1);

+            break;

+        default:

+            fileBuffer.append(CommonDefinition.autoGenHVersionDefault);

+            break;

+        }

+        switch (CommonDefinition.getModuleType(moduleType)) {

+        case CommonDefinition.ModuleTypeUefiDriver:

+        case CommonDefinition.ModuleTypeUefiApplication:

+            fileBuffer.append(CommonDefinition.autoGenHReleaseDefault);

+            break;

+        default:

+            fileBuffer.append(CommonDefinition.autoGenHLine2);

+            break;

+        }

+

+        //

+        // Add "extern int __make_me_compile_correctly;" at begin of 

+        // AutoGen.h.

+        //

+        fileBuffer.append(CommonDefinition.autoGenHbegin);

+

+        //

+        // Write consumed package's mdouleInfo related .h file to autogen.h

+        //

+        List<String> consumedPkgList = SurfaceAreaQuery

+                .getIncludePackageName(this.arch);

+        if (consumedPkgList != null) {

+            headerFileList = IncludesToAutogenH(consumedPkgList, moduleType);

+            for (int i = 0; i < headerFileList.size(); i++) {

+                fileBuffer.append(headerFileList.get(i));

+            }

+        }

+

+        //

+        // Write library class's related *.h file to autogen.h.

+        //

+        LibraryClass[] libClassList = SurfaceAreaQuery

+                .getLibraryClassArray(CommonDefinition.AlwaysConsumed);

+        if (libClassList != null) {

+            libClassIncludeH = LibraryClassToAutogenH(libClassList);

+            for (int i = 0; i < libClassIncludeH.size(); i++) {

+                fileBuffer.append(libClassIncludeH.get(i));

+            }

+        }

+

+        libClassList = SurfaceAreaQuery

+                .getLibraryClassArray(CommonDefinition.AlwaysProduced);

+        if (libClassList != null) {

+            libClassIncludeH = LibraryClassToAutogenH(libClassList);

+            for (int i = 0; i < libClassIncludeH.size(); i++) {

+                fileBuffer.append(libClassIncludeH.get(i));

+            }

+        }

+        fileBuffer.append("\r\n");

+        

+        //

+        // Write PCD autogen information to AutoGen.h.

+        //

+        if (this.myPcdAutogen != null) {

+            fileBuffer.append(this.myPcdAutogen.OutputH());

+        }

+

+        //

+        // Append the #endif at AutoGen.h

+        //

+        fileBuffer.append("#endif\r\n");

+        

+        //

+        // Save string buffer content in AutoGen.h.

+        //

+        if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {

+            throw new BuildException("Failed to generate AutoGen.h !!!");

+        }

+    }

+    

+    /**

+      moduleGenAutogenC

+   

+      This function generates AutoGen.c for module.

+    

+      @throws BuildException

+                Failed to generate AutoGen.c.

+    **/

+    void moduleGenAutogenC() throws BuildException {

+

+        StringBuffer fileBuffer = new StringBuffer(8192);

+        //

+        // Write Autogen.c header notation 

+        //

+        fileBuffer.append(CommonDefinition.autogenCNotation);

+        

+        //

+        // Write #include <AutoGen.h> at beginning of AutoGen.c

+        //

+        fileBuffer.append(CommonDefinition.includeAutogenH);

+        

+        //

+        // Write DriverBinding/ComponentName/DriverConfiguration/DriverDialog

+        // to AutoGen.c

+        //

+        ExternsDriverBindingToAutoGenC(fileBuffer);

+

+        //

+        // Write DriverExitBootServicesEvent/DriverSetVirtualAddressMapEvent

+        // to Autogen.c

+        //

+        ExternCallBackToAutoGenC(fileBuffer);

+

+        //

+        // Write EntryPoint to autgoGen.c

+        //

+        String[] entryPointList = SurfaceAreaQuery.getModuleEntryPointArray();

+        if (entryPointList != null) {

+            EntryPointToAutoGen(entryPointList, fileBuffer);

+        }

+

+        //

+        // Write Guid to autogen.c

+        //

+        String guid = SurfaceAreaQuery.getModuleGuid();

+        fileBuffer

+                .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");

+        if (guid == null) {

+            throw new BuildException("Guid value must set!\n");

+        }

+

+        //

+        // Formate Guid as ANSI c form.Example:

+        // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0}}

+        //

+        fileBuffer.append(Spd.formatGuidName(guid));

+        fileBuffer.append("};\r\n");

+

+        //

+        // Generate library instance consumed protocol, guid, ppi, pcd list.

+        // Save those to this.protocolList, this.ppiList, this.pcdList,

+        // this.guidList. Write Consumed library constructor and desconstuct to

+        // autogen.c

+        //

+        LibInstanceToAutogenC(fileBuffer);

+

+        //

+        // Write consumed ppi, guid, protocol to autogen.c

+        //

+        ProtocolGuidToAutogenC(fileBuffer);

+        PpiGuidToAutogenC(fileBuffer);

+        GuidGuidToAutogenC(fileBuffer);

+

+        //

+        // Call pcd autogen. PCDAutoGenAction tool only need module name and

+        // isPcdEmulatedDriver as parameter. Library inherits PCD and module's

+        // PCD information has been collected in FPDParser task by

+        // CollectPCDAction. 

+        // Note : when PCD image tool ready,

+        // isPCDEmulatedDriver parameter will be removed.

+        //

+        try {

+            this.myPcdAutogen = new PCDAutoGenAction(baseName,

+                                                     null,

+                                                     null,

+                                                     null,

+                                                     this.arch,

+                                                     null,

+                                                     baseName.equalsIgnoreCase("PcdEmulatorPeim"),

+                                                     false);

+            this.myPcdAutogen.execute();

+        } catch (Exception e) {

+            throw new BuildException("PCD Autogen failed:" + e.getMessage());

+        }

+

+        if (this.myPcdAutogen != null) {

+            fileBuffer.append(this.myPcdAutogen.OutputC());

+        }

+

+        if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {

+            throw new BuildException("Failed to generate AutoGen.c !!!");

+        }

+

+    }

+    

+    /**

+      libGenAutogenH

+   

+      This function generates AutoGen.h for library.

+    

+      @throws BuildException

+                Failed to generate AutoGen.c.

+    **/

+    void libGenAutogenH() throws BuildException {

+

+        List<String> libClassIncludeH;

+        String moduleType;

+        List<String> headerFileList;

+        StringBuffer fileBuffer = new StringBuffer(10240);

+

+        //

+        // Write Autogen.h header notation 

+        //

+        fileBuffer.append(CommonDefinition.autogenHNotation);

+        

+        //

+        // Add #ifndef  ${BaseName}_AUTOGENH

+        //     #def     ${BseeName}_AUTOGENH

+        //

+        fileBuffer.append("#ifndef    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");

+        fileBuffer.append("#define    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");

+        

+        //

+        // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION 

+        // to autogen.h file.

+        // Note: the specification version and release version should

+        // be get from module surface area instead of hard code.

+        //

+        fileBuffer.append(CommonDefinition.autoGenHbegin);

+        fileBuffer.append(CommonDefinition.autoGenHLine1);

+        fileBuffer.append(CommonDefinition.autoGenHLine2);

+

+        //

+        // Write consumed package's mdouleInfo related *.h file to autogen.h.

+        // 

+        moduleType = SurfaceAreaQuery.getModuleType();

+        List<String> cosumedPkglist = SurfaceAreaQuery

+                .getIncludePackageName(this.arch);

+        headerFileList = IncludesToAutogenH(cosumedPkglist, moduleType);

+        for (int i = 0; i < headerFileList.size(); i++) {

+            fileBuffer.append(headerFileList.get(i));

+        }

+

+        //

+        // Write library class's related *.h file to autogen.h

+        //

+        LibraryClass[] libClassList = SurfaceAreaQuery

+                .getLibraryClassArray(CommonDefinition.AlwaysConsumed);

+        if (libClassList != null) {

+            libClassIncludeH = LibraryClassToAutogenH(libClassList);

+            for (int i = 0; i < libClassIncludeH.size(); i++) {

+                fileBuffer.append(libClassIncludeH.get(i));

+            }

+        }

+

+        libClassList = SurfaceAreaQuery

+                .getLibraryClassArray(CommonDefinition.AlwaysProduced);

+        if (libClassList != null) {

+            libClassIncludeH = LibraryClassToAutogenH(libClassList);

+            for (int i = 0; i < libClassIncludeH.size(); i++) {

+                fileBuffer.append(libClassIncludeH.get(i));

+            }

+        }

+        fileBuffer.append("\r\n");

+        

+        //

+        // Write PCD information to library AutoGen.h.

+        //

+        if (this.myPcdAutogen != null) {

+            fileBuffer.append(this.myPcdAutogen.OutputH());

+        }

+

+        //

+        // Append the #endif at AutoGen.h

+        //

+        fileBuffer.append("#endif\r\n");

+        

+        //

+        // Save content of string buffer to AutoGen.h file.

+        //

+        if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {

+            throw new BuildException("Failed to generate AutoGen.h !!!");

+        }

+    }

+

+    /**

+      libGenAutogenC

+   

+      This function generates AutoGen.h for library.

+    

+      @throws BuildException

+                Failed to generate AutoGen.c.

+    **/

+    void libGenAutogenC() throws BuildException {

+        StringBuffer fileBuffer = new StringBuffer(10240);

+

+        //

+        // Write Autogen.c header notation 

+        //

+        fileBuffer.append(CommonDefinition.autogenCNotation);

+        

+        fileBuffer.append(CommonDefinition.autoGenCLine1);

+        fileBuffer.append("\r\n");

+

+        //

+        // Call pcd autogen. PCDAutoGenAction tool only need module name and

+        // isPcdEmulatedDriver as parameter. Library inherit PCD and module's

+        // PCD information has been collected in FPDParser task by

+        // CollectPCDAction. 

+        // Note : when PCD image tool ready,

+        // isPCDEmulatedDriver parameter will be removed.

+        //

+        try {

+            this.myPcdAutogen = new PCDAutoGenAction(baseName, 

+                                                     null,

+                                                     null,

+                                                     null,

+                                                     this.arch,

+                                                     null,

+                                                     baseName.equalsIgnoreCase("PcdEmulatorPeim"), 

+                                                     true);

+            this.myPcdAutogen.execute();

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+

+        if (this.myPcdAutogen != null) {

+            fileBuffer.append(this.myPcdAutogen.OutputC());

+        }

+

+        if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {

+            throw new BuildException("Failed to generate AutoGen.c !!!");

+        }

+    }

+

+    /**

+      LibraryClassToAutogenH

+      

+      This function returns *.h files declared by library classes which are 

+      consumed or produced by current build module or library.

+      

+      @param   libClassList     List of library class which consumed or produce

+                                by current build module or library.

+      @return  includeStrList   List of *.h file.             

+    **/

+    List<String> LibraryClassToAutogenH(LibraryClass[] libClassList) {

+        List<String> includStrList = new ArrayList<String>();

+        String includerName;

+        String str = "";

+       

+        //

+        // Get include file from GlobalData's SPDTable according to 

+        // library class name.

+        //

+        for (int i = 0; i < libClassList.length; i++) {

+            includerName = GlobalData.getLibClassIncluder(libClassList[i]

+                    .getStringValue());

+            if (includerName != null) {

+                str = CommonDefinition.include + " " + "<";

+                str = str + includerName + ">\r\n";

+                includStrList.add(str);

+                includerName = null;

+            }

+        }

+        return includStrList;

+    }

+

+    /**

+      IncludesToAutogenH

+      

+      This function add include file in AutoGen.h file.

+      @param   packageNameList   List of module depended package.

+      @param   moduleType        Module type.

+      @return 

+    **/

+    List<String> IncludesToAutogenH(List<String> packageNameList,

+            String moduleType) {

+

+        List<String> includeStrList = new ArrayList<String>();

+        String packageName = "";

+        String includeStr = "";

+

+        //

+        // Get include file from moduleInfo file

+        //

+        for (int i = 0; i < packageNameList.size(); i++) {

+            packageName = packageNameList.get(i);

+            includeStr = GlobalData.getModuleInfoByPackageName(packageName,

+                    moduleType);

+            includeStrList.add(includeStr);

+        }

+        return includeStrList;

+    }

+

+    /**

+      EntryPointToAutoGen 

+      

+      This function convert <ModuleEntryPoint> & <ModuleUnloadImage> information

+      in mas to AutoGen.c

+      

+      @param  entryPointList    List of entry point.                            

+      @param  fileBuffer        String buffer fo AutoGen.c.

+      @throws Exception

+    **/

+    void EntryPointToAutoGen(String[] entryPointList, StringBuffer fileBuffer)

+            throws BuildException {

+

+        String typeStr = SurfaceAreaQuery.getModuleType();

+        

+        //

+        // The parameters and return value of entryPoint is difference

+        // for difference module type.

+        //

+        switch (CommonDefinition.getModuleType(typeStr)) {

+

+        case CommonDefinition.ModuleTypePeiCore:

+            if (entryPointList.length != 1 || entryPointList[0].equals("")) {

+                throw new BuildException(

+                        "Module type = 'PEI_CORE', only have one module entry point!");

+            } else {

+                fileBuffer.append("EFI_STATUS\r\n");

+                fileBuffer.append("EFIAPI\r\n");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append(" (\r\n");

+                fileBuffer

+                        .append("  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r\n");

+                fileBuffer

+                        .append("  IN VOID                        *OldCoreData\r\n");

+                fileBuffer.append("  );\r\n\r\n");

+

+                fileBuffer.append("EFI_STATUS\r\n");

+                fileBuffer.append("EFIAPI\r\n");

+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");

+                fileBuffer

+                        .append("  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r\n");

+                fileBuffer

+                        .append("  IN VOID                        *OldCoreData\r\n");

+                fileBuffer.append("  )\r\n\r\n");

+                fileBuffer.append("{\r\n");

+                fileBuffer.append("  return ");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append(" (PeiStartupDescriptor, OldCoreData);\r\n");

+                fileBuffer.append("}\r\n\r\n");

+            }

+            break;

+

+        case CommonDefinition.ModuleTypeDxeCore:

+            fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");

+            if (entryPointList.length != 1 || entryPointList[0].equals("")) {

+                throw new BuildException(

+                        "Module type = 'DXE_CORE', only have one module entry point!");

+            } else {

+

+                fileBuffer.append("VOID\r\n");

+                fileBuffer.append("EFIAPI\r\n");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append(" (\n");

+                fileBuffer.append("  IN VOID  *HobStart\r\n");

+                fileBuffer.append("  );\r\n\r\n");

+

+                fileBuffer.append("VOID\r\n");

+                fileBuffer.append("EFIAPI\r\n");

+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");

+                fileBuffer.append("  IN VOID  *HobStart\r\n");

+                fileBuffer.append("  )\r\n\r\n");

+                fileBuffer.append("{\r\n");

+                fileBuffer.append("  ");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append(" (HobStart);\r\n");

+                fileBuffer.append("}\r\n\r\n");

+            }

+            break;

+

+        case CommonDefinition.ModuleTypePeim:

+            int entryPointCount = 0;

+            fileBuffer

+                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n");

+            for (int i = 0; i < entryPointList.length; i++) {

+                if (!entryPointList[i].equals("")) {

+                    fileBuffer.append("EFI_STATUS\r\n");

+                    fileBuffer.append("EFIAPI\r\n");

+                    fileBuffer.append(entryPointList[i]);

+                    fileBuffer.append(" (\r\n");

+                    fileBuffer

+                            .append("  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r\n");

+                    fileBuffer

+                            .append("  IN EFI_PEI_SERVICES     **PeiServices\r\n");

+                    fileBuffer.append("  );\r\n");

+                    entryPointCount++;

+                } else {

+                    break;

+                }

+            }

+

+            fileBuffer.append("EFI_STATUS\r\n");

+            fileBuffer.append("EFIAPI\r\n");

+            fileBuffer.append("ProcessModuleEntryPointList (\r\n");

+            fileBuffer.append("  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r\n");

+            fileBuffer.append("  IN EFI_PEI_SERVICES     **PeiServices\r\n");

+            fileBuffer.append("  )\r\n\r\n");

+            fileBuffer.append("{\r\n");

+

+            if (entryPointCount == 0) {

+                fileBuffer.append("  return EFI_SUCCESS;\r\n");

+            } else if (entryPointCount == 1) {

+                fileBuffer.append("  return ");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append(" (FfsHeader, PeiServices);\r\n");

+            } else {

+                fileBuffer.append("  EFI_STATUS  Status;\r\n");

+                fileBuffer.append("  EFI_STATUS  CombinedStatus;\r\n\r\n");

+                fileBuffer.append("  CombinedStatus = EFI_LOAD_ERROR;\r\n\r\n");

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("  Status = ");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append(" (FfsHeader, PeiServices)\r\n");

+                        fileBuffer

+                                .append("  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r\n");

+                        fileBuffer.append("    CombinedStatus = Status;\r\n");

+                        fileBuffer.append("  }\r\n\r\n");

+                    } else {

+                        break;

+                    }

+                }

+                fileBuffer.append("  return CombinedStatus;\r\n");

+            }

+            fileBuffer.append("}\r\n\r\n");

+            break;

+

+        case CommonDefinition.ModuleTypeDxeSmmDriver:

+            entryPointCount = 0;

+            for (int i = 0; i < entryPointList.length; i++) {

+                if (!entryPointList[i].equals("")) {

+                    fileBuffer.append("EFI_STATUS\r\n");

+                    fileBuffer.append("EFIAPI\r\n");

+                    fileBuffer.append(entryPointList[i]);

+                    fileBuffer.append(" (\r\n");

+                    fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");

+                    fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");

+                    fileBuffer.append("  );\r\n");

+                    entryPointCount++;

+                } else {

+                    break;

+                }

+            }

+            fileBuffer

+                    .append("GLOBAL_REMOVE_IF_UNREFERENCED  const UINT8  _gDriverEntryPointCount = ");

+            fileBuffer.append(Integer.toString(entryPointCount));

+            fileBuffer.append(";\r\n");

+            fileBuffer

+                    .append("static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r\n");

+            fileBuffer

+                    .append("static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n\r\n");

+

+            fileBuffer.append("EFI_STATUS\r\n");

+            fileBuffer.append("EFIAPI\r\n");

+            fileBuffer.append("ProcessModuleEntryPointList (\r\n");

+            fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");

+            fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");

+            fileBuffer.append("  )\r\n\r\n");

+            fileBuffer.append("{\r\n");

+

+            for (int i = 0; i < entryPointList.length; i++) {

+                if (!entryPointList[i].equals("")) {

+                    fileBuffer

+                            .append("  if (SetJump (&mJumpContext) == 0) {\r\n");

+                    fileBuffer.append("    ExitDriver (");

+                    fileBuffer.append(entryPointList[i]);

+                    fileBuffer.append(" (ImageHandle, SystemTable));\r\n");

+                    fileBuffer.append("    ASSERT (FALSE);\r\n");

+                    fileBuffer.append("  }\r\n");

+                } else {

+                    break;

+                }

+            }

+            fileBuffer.append("  return mDriverEntryPointStatus;\r\n");

+            fileBuffer.append("}\r\n\r\n");

+

+            fileBuffer.append("VOID\r\n");

+            fileBuffer.append("EFIAPI\r\n");

+            fileBuffer.append("ExitDriver (\r\n");

+            fileBuffer.append("  IN EFI_STATUS  Status\n");

+            fileBuffer.append("  )\r\n\r\n");

+            fileBuffer.append("{\r\n");

+            fileBuffer

+                    .append("  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");

+            fileBuffer.append("    mDriverEntryPointStatus = Status;\r\n");

+            fileBuffer.append("  }\r\n");

+            fileBuffer.append("  LongJump (&mJumpContext, (UINTN)-1);\r\n");

+            fileBuffer.append("  ASSERT (FALSE);\r\n");

+            fileBuffer.append("}\r\n\r\n");

+

+            //

+            // Add "ModuleUnloadImage" for DxeSmmDriver module type;

+            //

+            entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();

+            entryPointCount = 0;

+            if (entryPointList != null) {

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("EFI_STATUS\r\n");

+                        fileBuffer.append("EFIAPI\r\n");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append(" (\r\n");

+                        fileBuffer

+                                .append("  EFI_HANDLE        ImageHandle\r\n");

+                        fileBuffer.append("  );\r\n");

+                        entryPointCount++;

+                    } else {

+                        break;

+                    }

+                }

+            }

+

+            fileBuffer

+                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");

+            fileBuffer.append(Integer.toString(entryPointCount));

+            fileBuffer.append(";\r\n\r\n");

+

+            if (entryPointList != null) {

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("EFI_STATUS\r\n");

+                        fileBuffer.append("EFIAPI\r\n");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append(" (\r\n");

+                        fileBuffer

+                                .append("  EFI_HANDLE        ImageHandle\r\n");

+                        fileBuffer.append("  );\r\n");

+                    } else {

+                        break;

+                    }

+                }

+            }

+

+            fileBuffer.append("EFI_STATUS\r\n");

+            fileBuffer.append("EFIAPI\r\n");

+            fileBuffer.append("ProcessModuleUnloadList (\r\n");

+            fileBuffer.append("  EFI_HANDLE  ImageHandle\r\n");

+            fileBuffer.append("  )\r\n");

+            fileBuffer.append("{\r\n");

+

+            if (entryPointCount == 0) {

+                fileBuffer.append("  return EFI_SUCCESS;\r\n");

+            } else if (entryPointCount == 1) {

+                fileBuffer.append("  return ");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append("(ImageHandle);\r\n");

+            } else {

+                fileBuffer.append("  EFI_STATUS  Status;\r\n\r\n");

+                fileBuffer.append("  Status = EFI_SUCCESS;\r\n\r\n");

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");

+                        fileBuffer.append("    ");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append("(ImageHandle);\r\n");

+                        fileBuffer.append("  } else {\r\n");

+                        fileBuffer.append("    Status = ");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append("(ImageHandle);\r\n");

+                        fileBuffer.append("  }\r\n");

+                    } else {

+                        break;

+                    }

+                }

+                fileBuffer.append("  return Status;\r\n");

+            }

+            fileBuffer.append("}\r\n\r\n");

+            break;

+

+        case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+        case CommonDefinition.ModuleTypeDxeDriver:

+        case CommonDefinition.ModuleTypeDxeSalDriver:

+        case CommonDefinition.ModuleTypeUefiDriver:

+        case CommonDefinition.ModuleTypeUefiApplication:

+            entryPointCount = 0;

+            fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");

+            for (int i = 0; i < entryPointList.length; i++) {

+                if (!entryPointList[i].equals("")) {

+                    fileBuffer.append("EFI_STATUS\r\n");

+                    fileBuffer.append("EFIAPI\r\n");

+                    fileBuffer.append(entryPointList[i]);

+                    fileBuffer.append(" (\r\n");

+                    fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");

+                    fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");

+                    fileBuffer.append("  );\r\n");

+                    entryPointCount++;

+                } else {

+                    break;

+                }

+            }

+

+            fileBuffer

+                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverEntryPointCount = ");

+            fileBuffer.append(Integer.toString(entryPointCount));

+            fileBuffer.append(";\r\n");

+            if (entryPointCount > 1) {

+                fileBuffer

+                        .append("static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r\n");

+                fileBuffer

+                        .append("static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n");

+            }

+            fileBuffer.append("\n");

+

+            fileBuffer.append("EFI_STATUS\r\n");

+            fileBuffer.append("EFIAPI\r\n");

+            fileBuffer.append("ProcessModuleEntryPointList (\r\n");

+            fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");

+            fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");

+            fileBuffer.append("  )\r\n\r\n");

+            fileBuffer.append("{\r\n");

+

+            if (entryPointCount == 0) {

+                fileBuffer.append("  return EFI_SUCCESS;\r\n");

+            } else if (entryPointCount == 1) {

+                fileBuffer.append("  return (");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append(" (ImageHandle, SystemTable));\r\n");

+            } else {

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer

+                                .append("  if (SetJump (&mJumpContext) == 0) {\r\n");

+                        fileBuffer.append("    ExitDriver (");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append(" (ImageHandle, SystemTable));\r\n");

+                        fileBuffer.append("    ASSERT (FALSE);\r\n");

+                        fileBuffer.append("  }\r\n");

+                    } else {

+                        break;

+                    }

+                }

+                fileBuffer.append("  return mDriverEntryPointStatus;\r\n");

+            }

+            fileBuffer.append("}\r\n\r\n");

+

+            fileBuffer.append("VOID\n");

+            fileBuffer.append("EFIAPI\n");

+            fileBuffer.append("ExitDriver (\r\n");

+            fileBuffer.append("  IN EFI_STATUS  Status\n");

+            fileBuffer.append("  )\r\n\r\n");

+            fileBuffer.append("{\r\n");

+            if (entryPointCount <= 1) {

+                fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");

+                fileBuffer

+                        .append("    ProcessLibraryDestructorList (gImageHandle, gST);\r\n");

+                fileBuffer.append("  }\r\n");

+                fileBuffer

+                        .append("  gBS->Exit (gImageHandle, Status, 0, NULL);\r\n");

+            } else {

+                fileBuffer

+                        .append("  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");

+                fileBuffer.append("    mDriverEntryPointStatus = Status;\r\n");

+                fileBuffer.append("  }\r\n");

+                fileBuffer.append("  LongJump (&mJumpContext, (UINTN)-1);\r\n");

+                fileBuffer.append("  ASSERT (FALSE);\r\n");

+            }

+            fileBuffer.append("}\r\n\r\n");

+

+            //

+            // Add ModuleUnloadImage for DxeDriver and UefiDriver module type.

+            //

+            entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();

+            entryPointCount = 0;

+            if (entryPointList != null) {

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("EFI_STATUS\r\n");

+                        fileBuffer.append("EFIAPI\r\n");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append(" (\r\n");

+                        fileBuffer

+                                .append("  EFI_HANDLE        ImageHandle\r\n");

+                        fileBuffer.append("  );\r\n");

+                        entryPointCount++;

+                    } else {

+                        break;

+                    }

+                }

+            }

+

+            fileBuffer

+                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");

+            fileBuffer.append(Integer.toString(entryPointCount));

+            fileBuffer.append(";\r\n\r\n");

+

+            if (entryPointList != null) {

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("EFI_STATUS\r\n");

+                        fileBuffer.append("EFIAPI\r\n");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append(" (\r\n");

+                        fileBuffer

+                                .append("  EFI_HANDLE        ImageHandle\r\n");

+                        fileBuffer.append("  );\r\n");

+                    } else {

+                        break;

+                    }

+                }

+            }

+

+            fileBuffer.append("EFI_STATUS\n");

+            fileBuffer.append("EFIAPI\n");

+            fileBuffer.append("ProcessModuleUnloadList (\r\n");

+            fileBuffer.append("  EFI_HANDLE  ImageHandle\r\n");

+            fileBuffer.append("  )\r\n");

+            fileBuffer.append("{\r\n");

+

+            if (entryPointCount == 0) {

+                fileBuffer.append("  return EFI_SUCCESS;\r\n");

+            } else if (entryPointCount == 1) {

+                fileBuffer.append("  return ");

+                fileBuffer.append(entryPointList[0]);

+                fileBuffer.append("(ImageHandle);\r\n");

+            } else {

+                fileBuffer.append("  EFI_STATUS  Status;\r\n\r\n");

+                fileBuffer.append("  Status = EFI_SUCCESS;\r\n\r\n");

+                for (int i = 0; i < entryPointList.length; i++) {

+                    if (!entryPointList[i].equals("")) {

+                        fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");

+                        fileBuffer.append("    ");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append("(ImageHandle);\r\n");

+                        fileBuffer.append("  } else {\r\n");

+                        fileBuffer.append("    Status = ");

+                        fileBuffer.append(entryPointList[i]);

+                        fileBuffer.append("(ImageHandle);\r\n");

+                        fileBuffer.append("  }\r\n");

+                    } else {

+                        break;

+                    }

+                }

+                fileBuffer.append("  return Status;\r\n");

+            }

+            fileBuffer.append("}\r\n\r\n");

+            break;

+        }

+    }

+

+    /**

+      PpiGuidToAutogenc 

+    

+      This function gets GUIDs from SPD file accrodeing to <PPIs> information and 

+      write those GUIDs to AutoGen.c.

+    

+      @param   fileBuffer         String Buffer for Autogen.c file.

+      @throws  BuildException     Guid must set value!

+    **/

+    void PpiGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {

+        String[] cNameGuid = null;

+        boolean isEqual = false;

+

+        PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery.getPpiArray(null);

+        if (ppiList != null) {

+            for (int i = 0; i < ppiList.length; i++) {

+                isEqual = false;

+                for (int j = 0; j < this.mPpiList.size(); j++) {

+                    if (this.mPpiList.get(j).equalsIgnoreCase(

+                            ppiList[i].getStringValue())) {

+                        isEqual = true;

+                    }

+                }

+                if (!isEqual) {

+                    this.mPpiList.add(ppiList[i].getStringValue());

+                }

+            }

+        }

+

+        PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery

+                .getPpiNotifyArray(null);

+        if (ppiNotifyList != null) {

+            for (int i = 0; i < ppiNotifyList.length; i++) {

+                isEqual = false;

+                for (int j = 0; j < this.mPpiList.size(); j++) {

+                    if (this.mPpiList.get(j).equalsIgnoreCase(

+                            ppiNotifyList[i].getStringValue())) {

+                        isEqual = true;

+                    }

+                }

+                if (!isEqual) {

+                    this.mPpiList.add(ppiNotifyList[i].getStringValue());

+                }

+            }

+        }

+

+        for (int i = 0; i < this.mPpiList.size(); i++) {

+            if (this.mPpiList.get(i) != null) {

+                cNameGuid = GlobalData.getPpiInfoGuid(this.mPpiList.get(i));

+                if (cNameGuid != null) {

+                    fileBuffer

+                            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");

+                    fileBuffer.append(cNameGuid[0]);

+                    fileBuffer.append(" =     { ");

+                    fileBuffer.append(cNameGuid[1]);

+                    fileBuffer.append(" } ;");

+                }

+            } else {

+                throw new BuildException("Guid must set value!");

+            }

+        }

+    }

+

+    /**

+      ProtocolGuidToAutogenc 

+    

+      This function gets GUIDs from SPD file accrodeing to <Protocol> 

+      information and write those GUIDs to AutoGen.c.

+    

+      @param   fileBuffer         String Buffer for Autogen.c file.

+      @throws  BuildException     Protocol name must set.

+    **/

+    void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {

+        String[] cNameGuid = null;

+        boolean isEqual = false;

+

+        ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery

+                .getProtocolArray(null);

+        if (protocolList != null) {

+            for (int i = 0; i < protocolList.length; i++) {

+                isEqual = false;

+                for (int j = 0; j < this.mProtocolList.size(); j++) {

+                    if (this.mProtocolList.get(j).equalsIgnoreCase(

+                            protocolList[i].getStringValue())) {

+                        isEqual = true;

+                    }

+                }

+                if (!isEqual) {

+                    this.mProtocolList.add(protocolList[i].getStringValue());

+

+                }

+            }

+        }

+

+        ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery

+                .getProtocolNotifyArray(null);

+        if (protocolNotifyList != null) {

+            for (int i = 0; i < protocolNotifyList.length; i++) {

+                isEqual = false;

+                for (int j = 0; j < this.mProtocolList.size(); j++) {

+                    if (this.mProtocolList.get(j).equalsIgnoreCase(

+                            protocolNotifyList[i].getStringValue())) {

+                        isEqual = true;

+                    }

+                }

+                if (!isEqual) {

+                    this.mProtocolList.add(protocolNotifyList[i]

+                            .getStringValue());

+

+                }

+            }

+        }

+        if (this.mProtocolList.size() > 0) {

+            for (int i = 0; i < this.mProtocolList.size(); i++) {

+                if (this.mProtocolList.get(i) != null) {

+                    cNameGuid = GlobalData

+                            .getProtocolInfoGuid(this.mProtocolList.get(i));

+                    if (cNameGuid != null) {

+                        fileBuffer

+                                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");

+                        fileBuffer.append(cNameGuid[0]);

+                        fileBuffer.append(" =     { ");

+                        fileBuffer.append(cNameGuid[1]);

+                        fileBuffer.append(" } ;");

+                    }

+                } else {

+                    throw new BuildException("Protocol name must set!");

+                }

+            }

+        }

+    }

+

+    /**

+      GuidGuidToAutogenc

+    

+      This function gets GUIDs from SPD file accrodeing to <Guids> information

+      and write those GUIDs to AutoGen.c.

+    

+      @param  fileBuffer       String Buffer for Autogen.c file.

+    

+    **/

+    void GuidGuidToAutogenC(StringBuffer fileBuffer) {

+        String[] cNameGuid = null;

+        boolean isEqual = false;

+        GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery

+                .getGuidEntryArray(null);

+

+        if (guidList != null) {

+            for (int i = 0; i < guidList.length; i++) {

+                for (int j = 0; j < this.mGuidList.size(); j++) {

+                    isEqual = false;

+                    if (this.mGuidList.get(j).getCName().equalsIgnoreCase(

+                            guidList[i].getCName().toString())) {

+                        isEqual = true;

+                        break;

+                    }

+                }

+                if (!isEqual) {

+                    this.mGuidList.add(guidList[i]);

+

+                }

+

+            }

+        }

+

+        for (int i = 0; i < this.mGuidList.size(); i++) {

+            if (this.mGuidList.get(i).getCName() != null) {

+                cNameGuid = GlobalData.getGuidInfoGuid(this.mGuidList.get(i)

+                        .getCName());

+                if (cNameGuid != null) {

+                    fileBuffer

+                            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");

+                    fileBuffer.append(cNameGuid[0]);

+                    fileBuffer.append(" =     { ");

+                    fileBuffer.append(cNameGuid[1]);

+                    fileBuffer.append("} ;");

+                }

+            }

+        }

+    }

+

+    /**

+      LibInstanceToAutogenC

+      

+      This function adds dependent library instance to autogen.c,which includeing 

+      library's constructor, destructor, and library dependent ppi, protocol, guid,

+      pcd information.

+         

+      @param  fileBuffer              String buffer for AutoGen.c

+      @throws BuildException          

+    **/

+    void LibInstanceToAutogenC(StringBuffer fileBuffer) throws BuildException {

+        int index;

+        boolean isEqual = false;

+

+        String moduleType = SurfaceAreaQuery.getModuleType();

+        List<String> libConstructList = new ArrayList<String>();

+        List<String> libDestructList = new ArrayList<String>();

+

+        String libConstructName = null;

+        String libDestructName = null;

+        List<String> libraryList = SurfaceAreaQuery.getLibraryInstance(

+                this.arch, CommonDefinition.AlwaysConsumed);

+

+        try {

+            if (libraryList != null) {

+                //

+                // Reorder library instance sequence.

+                //

+                AutogenLibOrder libOrder = new AutogenLibOrder(libraryList);

+                List orderList = libOrder.orderLibInstance();

+                

+                if (orderList != null) {

+                    //

+                    // Process library instance one by one.

+                    //

+                    for (int i = 0; i < orderList.size(); i++) {

+                        

+                        //

+                        // Get library instance basename.

+                        //

+                        String libInstanceName = orderList.get(i).toString();

+                        

+                        //

+                        // Get override map

+                        //

+                        Map<String, XmlObject> libDoc = GlobalData

+                                .getDoc(libInstanceName);

+                        SurfaceAreaQuery.push(libDoc);

+                        

+                        //

+                        // Get <PPis>, <Protocols>, <Guids> list of this library

+                        // instance.

+                        //

+                        PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery

+                                .getPpiArray(null);

+                        PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery

+                                .getPpiNotifyArray(null);

+                        ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery

+                                .getProtocolArray(null);

+                        ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery

+                                .getProtocolNotifyArray(null);

+                        GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery

+                                .getGuidEntryArray(null);

+

+                        //

+                        // Add those ppi, protocol, guid in global ppi, protocol, guid

+                        // list.

+                        //

+                        if (ppiList != null) {

+                            for (index = 0; index < ppiList.length; index++) {

+                                isEqual = false;

+                                for (int j = 0; j < this.mPpiList.size(); j++) {

+                                    if (this.mPpiList.get(j).equalsIgnoreCase(

+                                            ppiList[index].getStringValue())) {

+                                        isEqual = true;

+                                    }

+                                }

+                                if (!isEqual) {

+                                    this.mPpiList.add(ppiList[index]

+                                            .getStringValue());

+                                }

+                            }

+                        }

+                        if (ppiNotifyList != null) {

+                            for (index = 0; index < ppiNotifyList.length; index++) {

+                                isEqual = false;

+                                for (int j = 0; j < this.mPpiList.size(); j++) {

+                                    if (this.mPpiList.get(j).equalsIgnoreCase(

+                                            ppiNotifyList[index]

+                                                    .getStringValue())) {

+                                        isEqual = true;

+                                    }

+                                }

+                                if (!isEqual) {

+                                    this.mPpiList.add(ppiNotifyList[index]

+                                            .getStringValue());

+                                }

+                            }

+                        }

+                        if (protocolList != null) {

+                            for (index = 0; index < protocolList.length; index++) {

+                                isEqual = false;

+                                for (int j = 0; j < this.mProtocolList.size(); j++) {

+                                    if (this.mProtocolList.get(j)

+                                            .equalsIgnoreCase(

+                                                    protocolList[index]

+                                                            .getStringValue())) {

+                                        isEqual = true;

+                                    }

+                                }

+                                if (!isEqual) {

+                                    this.mProtocolList.add(protocolList[index]

+                                            .getStringValue());

+                                }

+                            }

+                        }

+                        if (protocolNotifyList != null) {

+                            for (index = 0; index < protocolNotifyList.length; index++) {

+                                isEqual = false;

+                                for (int j = 0; j < this.mProtocolList.size(); j++) {

+                                    if (this.mProtocolList.get(j)

+                                            .equalsIgnoreCase(

+                                                    protocolNotifyList[index]

+                                                            .getStringValue())) {

+                                        isEqual = true;

+                                    }

+                                }

+                                if (!isEqual) {

+                                    this.mProtocolList

+                                            .add(protocolNotifyList[index]

+                                                    .getStringValue());

+                                }

+                            }

+                        }

+                        if (guidList != null) {

+                            for (index = 0; index < guidList.length; index++) {

+                                isEqual = false;

+                                for (int j = 0; j < this.mGuidList.size(); j++) {

+                                    if (this.mGuidList.get(j).getCName()

+                                            .equalsIgnoreCase(

+                                                    guidList[index].getCName())) {

+                                        isEqual = true;

+                                    }

+                                }

+                                if (!isEqual) {

+                                    this.mGuidList.add(guidList[index]);

+                                }

+                            }

+                        }

+

+                        //

+                        // If not yet parse this library instance's constructor

+                        // element,parse it.

+                        //

+                        if (!GlobalData.isHaveLibInstance(libInstanceName)) {

+                            libConstructName = SurfaceAreaQuery

+                                    .getLibConstructorName();

+                            libDestructName = SurfaceAreaQuery

+                                    .getLibDestructorName();

+

+                            GlobalData.setLibInstanceInfo(libInstanceName,

+                                    libConstructName, libDestructName);

+                        } else {

+                            libConstructName = GlobalData

+                                    .getLibInstanceConstructor(libInstanceName);

+                            libDestructName = GlobalData

+                                    .getLibInstanceDestructor(libInstanceName);

+                        }

+                        SurfaceAreaQuery.pop();

+                        //

+                        // Add dependent library instance constructor function.

+                        //

+                        if (libConstructName != null) {

+                            libConstructList.add(libConstructName);

+                        }

+                        //

+                        // Add dependent library instance destructor fuction.

+                        //

+                        if (libDestructName != null) {

+                            libDestructList.add(libDestructName);

+                        }

+                    }

+

+                }

+

+                //

+                // Add library constructor to AutoGen.c

+                //

+                LibConstructorToAutogenC(libConstructList, moduleType,

+                        fileBuffer/* autogenC */);

+                //

+                // Add library destructor to AutoGen.c

+                //

+                LibDestructorToAutogenC(libDestructList, moduleType,

+                        fileBuffer/* autogenC */);

+            }

+

+        } catch (Exception e) {

+            throw new BuildException(e.getMessage());

+        }

+    }

+

+ 

+    /**

+      LibConstructorToAutogenc

+    

+      This function writes library constructor list to AutoGen.c. The library 

+      constructor's parameter and return value depend on module type.

+    

+      @param  libInstanceList        List of library construct name.

+      @param  moduleType             Module type.

+      @param  fileBuffer             String buffer for AutoGen.c

+      @throws Exception              

+    **/

+    void LibConstructorToAutogenC(List<String> libInstanceList,

+            String moduleType, StringBuffer fileBuffer) throws Exception {

+        boolean isFirst = true;

+

+        //

+        // The library constructor's parameter and return value depend on 

+        // module type.

+        //

+        for (int i = 0; i < libInstanceList.size(); i++) {

+            switch (CommonDefinition.getModuleType(moduleType)) {

+            case CommonDefinition.ModuleTypeBase:

+                fileBuffer.append("RETURN_STATUS\r\n");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (\r\n");

+                fileBuffer.append("  VOID\r\n");

+                fileBuffer.append("  );\r\n");

+                break;

+

+            case CommonDefinition.ModuleTypePeiCore:

+            case CommonDefinition.ModuleTypePeim:

+                fileBuffer.append("EFI_STATUS\r\n");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (\r\n");

+                fileBuffer

+                        .append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");

+                fileBuffer

+                        .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");

+                fileBuffer.append("  );\r\n");

+                break;

+

+            case CommonDefinition.ModuleTypeDxeCore:

+            case CommonDefinition.ModuleTypeDxeDriver:

+            case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+            case CommonDefinition.ModuleTypeDxeSmmDriver:

+            case CommonDefinition.ModuleTypeDxeSalDriver:

+            case CommonDefinition.ModuleTypeUefiDriver:

+            case CommonDefinition.ModuleTypeUefiApplication:

+                fileBuffer.append("EFI_STATUS\r\n");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (\r\n");

+                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");

+                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");

+                fileBuffer.append("  );\r\n");

+                break;

+            }

+        }

+

+        //

+        // Add ProcessLibraryConstructorList in AutoGen.c

+        //

+        fileBuffer.append("VOID\r\n");

+        fileBuffer.append("ProcessLibraryConstructorList (\r\n");

+        switch (CommonDefinition.getModuleType(moduleType)) {

+        case CommonDefinition.ModuleTypeBase:

+            fileBuffer.append("  VOID\r\n");

+            break;

+

+        case CommonDefinition.ModuleTypePeiCore:

+        case CommonDefinition.ModuleTypePeim:

+            fileBuffer.append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");

+            fileBuffer

+                    .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");

+            break;

+

+        case CommonDefinition.ModuleTypeDxeCore:

+        case CommonDefinition.ModuleTypeDxeDriver:

+        case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+        case CommonDefinition.ModuleTypeDxeSmmDriver:

+        case CommonDefinition.ModuleTypeDxeSalDriver:

+        case CommonDefinition.ModuleTypeUefiDriver:

+        case CommonDefinition.ModuleTypeUefiApplication:

+            fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");

+            fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");

+            break;

+        }

+

+        fileBuffer.append("  )\r\n");

+        fileBuffer.append("{\r\n");

+

+        for (int i = 0; i < libInstanceList.size(); i++) {

+            if (isFirst) {

+                fileBuffer.append("  EFI_STATUS  Status;\r\n");

+                fileBuffer.append("\r\n");

+                isFirst = false;

+            }

+            switch (CommonDefinition.getModuleType(moduleType)) {

+            case CommonDefinition.ModuleTypeBase:

+                fileBuffer.append("  Status = ");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append("();\r\n");

+                fileBuffer.append("  VOID\r\n");

+                break;

+            case CommonDefinition.ModuleTypePeiCore:

+            case CommonDefinition.ModuleTypePeim:

+                fileBuffer.append("  Status = ");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (FfsHeader, PeiServices);\r\n");

+                break;

+            case CommonDefinition.ModuleTypeDxeCore:

+            case CommonDefinition.ModuleTypeDxeDriver:

+            case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+            case CommonDefinition.ModuleTypeDxeSmmDriver:

+            case CommonDefinition.ModuleTypeDxeSalDriver:

+            case CommonDefinition.ModuleTypeUefiDriver:

+            case CommonDefinition.ModuleTypeUefiApplication:

+                fileBuffer.append("  Status = ");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (ImageHandle, SystemTable);\r\n");

+                break;

+            }

+            fileBuffer.append("  ASSERT_EFI_ERROR (Status);\r\n");

+        }

+        fileBuffer.append("}\r\n");

+    }

+

+    /**

+      LibDestructorToAutogenc

+    

+      This function writes library destructor list to AutoGen.c. The library 

+      destructor's parameter and return value depend on module type.

+    

+      @param  libInstanceList        List of library destructor name.

+      @param  moduleType             Module type.

+      @param  fileBuffer             String buffer for AutoGen.c

+      @throws Exception              

+    **/

+    void LibDestructorToAutogenC(List<String> libInstanceList,

+            String moduleType, StringBuffer fileBuffer) throws Exception {

+        boolean isFirst = true;

+        for (int i = 0; i < libInstanceList.size(); i++) {

+            switch (CommonDefinition.getModuleType(moduleType)) {

+            case CommonDefinition.ModuleTypeBase:

+                fileBuffer.append("RETURN_STATUS\n");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (\r\n");

+                fileBuffer.append("  VOID\r\n");

+                fileBuffer.append("  );\r\n");

+                break;

+            case CommonDefinition.ModuleTypePeiCore:

+            case CommonDefinition.ModuleTypePeim:

+                fileBuffer.append("EFI_STATUS\r\n");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (\r\n");

+                fileBuffer

+                        .append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");

+                fileBuffer

+                        .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");

+                fileBuffer.append("  );\r\n");

+                break;

+            case CommonDefinition.ModuleTypeDxeCore:

+            case CommonDefinition.ModuleTypeDxeDriver:

+            case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+            case CommonDefinition.ModuleTypeDxeSmmDriver:

+            case CommonDefinition.ModuleTypeDxeSalDriver:

+            case CommonDefinition.ModuleTypeUefiDriver:

+            case CommonDefinition.ModuleTypeUefiApplication:

+                fileBuffer.append("EFI_STATUS\r\n");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append(" (\r\n");

+                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");

+                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");

+                fileBuffer.append("  );\r\n");

+                break;

+            }

+        }

+

+        //

+        // Write ProcessLibraryDestructor list to autogen.c

+        //

+        switch (CommonDefinition.getModuleType(moduleType)) {

+        case CommonDefinition.ModuleTypeBase:

+        case CommonDefinition.ModuleTypePeiCore:

+        case CommonDefinition.ModuleTypePeim:

+            break;

+        case CommonDefinition.ModuleTypeDxeCore:

+        case CommonDefinition.ModuleTypeDxeDriver:

+        case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+        case CommonDefinition.ModuleTypeDxeSmmDriver:

+        case CommonDefinition.ModuleTypeDxeSalDriver:

+        case CommonDefinition.ModuleTypeUefiDriver:

+        case CommonDefinition.ModuleTypeUefiApplication:

+            fileBuffer.append("VOID\r\n");

+            fileBuffer.append("ProcessLibraryDestructorList (\r\n");

+            fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");

+            fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");

+            fileBuffer.append("  )\r\n");

+            fileBuffer.append("{\r\n");

+

+            for (int i = 0; i < libInstanceList.size(); i++) {

+                if (isFirst) {

+                    fileBuffer.append("  EFI_STATUS  Status;\r\n");

+                    fileBuffer.append("\r\n");

+                    isFirst = false;

+                }

+                fileBuffer.append("  Status = ");

+                fileBuffer.append(libInstanceList.get(i));

+                fileBuffer.append("(ImageHandle, SystemTable);\r\n");

+                fileBuffer.append("  ASSERT_EFI_ERROR (Status);\r\n");

+            }

+            fileBuffer.append("}\r\n");

+            break;

+        }

+    }

+

+    /**

+      ExternsDriverBindingToAutoGenC

+      

+      This function is to write DRIVER_BINDING, COMPONENT_NAME, 

+      DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c.

+      

+      @param  fileBuffer             String buffer for AutoGen.c

+     */

+    void ExternsDriverBindingToAutoGenC(StringBuffer fileBuffer)

+            throws BuildException {

+

+        //

+        // Check what <extern> contains. And the number of following elements

+        // under <extern> should be same. 1. DRIVER_BINDING 2. COMPONENT_NAME

+        // 3.DRIVER_CONFIGURATION 4. DRIVER_DIAGNOSTIC

+        //

+        

+        String[] drvBindList = SurfaceAreaQuery.getDriverBindingArray();

+        

+        //

+        // If component name protocol,component configuration protocol,

+        // component diagnostic protocol is not null or empty, check 

+        // if every one have the same number of the driver binding protocol.

+        //

+        if (drvBindList == null || drvBindList.length == 0) {

+            return;

+        }

+

+        String[] compNamList = SurfaceAreaQuery.getComponentNameArray();

+        String[] compConfList = SurfaceAreaQuery.getDriverConfigArray();

+        String[] compDiagList = SurfaceAreaQuery.getDriverDiagArray();

+

+        int BitMask = 0;

+

+        //

+        // Write driver binding protocol extern to autogen.c

+        //

+        for (int i = 0; i < drvBindList.length; i++) {

+            fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL ");

+            fileBuffer.append(drvBindList[i]);

+            fileBuffer.append(";\r\n");

+        }

+

+        //

+        // Write component name protocol extern to autogen.c

+        //

+        if (compNamList != null && compNamList.length != 0) {

+            if (drvBindList.length != compNamList.length) {

+                throw new BuildException(

+                        "Different number of Driver Binding and Component Name protocols!");

+            }

+

+            BitMask |= 0x01;

+            for (int i = 0; i < compNamList.length; i++) {

+                fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL ");

+                fileBuffer.append(compNamList[i]);

+                fileBuffer.append(";\r\n");

+            }

+        }

+

+        //

+        // Write driver configration protocol extern to autogen.c

+        //

+        if (compConfList != null && compConfList.length != 0) {

+            if (drvBindList.length != compConfList.length) {

+                throw new BuildException(

+                        "Different number of Driver Binding and Driver Configuration protocols!");

+            }

+

+            BitMask |= 0x02;

+            for (int i = 0; i < compConfList.length; i++) {

+                fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL ");

+                fileBuffer.append(compConfList[i]);

+                fileBuffer.append(";\r\n");

+            }

+        }

+

+        //

+        // Write driver dignastic protocol extern to autogen.c

+        //

+        if (compDiagList != null && compDiagList.length != 0) {

+            if (drvBindList.length != compDiagList.length) {

+                throw new BuildException(

+                        "Different number of Driver Binding and Driver Configuration protocols!");

+            }

+

+            BitMask |= 0x04;

+            for (int i = 0; i < compDiagList.length; i++) {

+                fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL ");

+                fileBuffer.append(compDiagList[i]);

+                fileBuffer.append(";\r\n");

+            }

+        }

+

+        //

+        // Write driver module protocol bitmask.

+        //

+        fileBuffer

+                .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverModelProtocolBitmask = ");

+        fileBuffer.append(Integer.toString(BitMask));

+        fileBuffer.append(";\r\n");

+

+        //

+        // Write driver module protocol list entry

+        //

+        fileBuffer

+                .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINTN  _gDriverModelProtocolListEntries = ");

+

+        fileBuffer.append(Integer.toString(drvBindList.length));

+        fileBuffer.append(";\r\n");

+

+        //

+        // Write drive module protocol list to autogen.c

+        //

+        fileBuffer

+                .append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST  _gDriverModelProtocolList[] = {");

+        for (int i = 0; i < drvBindList.length; i++) {

+            if (i != 0) {

+                fileBuffer.append(",");

+            }

+            fileBuffer.append("\r\n {\r\n");

+            fileBuffer.append("  &");

+            fileBuffer.append(drvBindList[i]);

+            fileBuffer.append(", \r\n");

+

+            if (compNamList != null) {

+                fileBuffer.append("  &");

+                fileBuffer.append(compNamList[i]);

+                fileBuffer.append(", \r\n");

+            } else {

+                fileBuffer.append("  NULL, \r\n");

+            }

+

+            if (compConfList != null) {

+                fileBuffer.append("  &");

+                fileBuffer.append(compConfList[i]);

+                fileBuffer.append(", \r\n");

+            } else {

+                fileBuffer.append("  NULL, \r\n");

+            }

+

+            if (compDiagList != null) {

+                fileBuffer.append("  &");

+                fileBuffer.append(compDiagList[i]);

+                fileBuffer.append(", \r\n");

+            } else {

+                fileBuffer.append("  NULL, \r\n");

+            }

+            fileBuffer.append("  }");

+        }

+        fileBuffer.append("\r\n};\r\n");

+    }

+

+    /**

+      ExternCallBackToAutoGenC

+    

+      This function adds <SetVirtualAddressMapCallBack> and <ExitBootServicesCallBack>

+      infomation to AutoGen.c

+    

+      @param  fileBuffer           String buffer for AutoGen.c

+      @throws BuildException

+    **/

+    void ExternCallBackToAutoGenC(StringBuffer fileBuffer)

+            throws BuildException {

+        String[] setVirtualList = SurfaceAreaQuery

+                .getSetVirtualAddressMapCallBackArray();

+        String[] exitBootList = SurfaceAreaQuery

+                .getExitBootServicesCallBackArray();

+        String moduleType = SurfaceAreaQuery.getModuleType();

+        boolean UefiOrDxeModule = false;

+        int Count = 0;

+        int i;

+

+        switch (CommonDefinition.getModuleType(moduleType)) {

+        case CommonDefinition.ModuleTypeDxeDriver:

+        case CommonDefinition.ModuleTypeDxeRuntimeDriver:

+        case CommonDefinition.ModuleTypeDxeSalDriver:

+        case CommonDefinition.ModuleTypeUefiDriver:

+        case CommonDefinition.ModuleTypeUefiApplication:

+            //

+            // Entry point lib for these module types needs to know the count

+            // of entryPoint.

+            //

+            UefiOrDxeModule = true;

+            fileBuffer

+                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED  const UINTN _gDriverSetVirtualAddressMapEventCount = ");

+

+            //

+            // If the list is not valid or has no entries set count to zero else

+            // set count to the number of valid entries

+            //

+            Count = 0;

+            if (setVirtualList != null) {

+                for (i = 0; i < setVirtualList.length; i++) {

+                    if (setVirtualList[i].equalsIgnoreCase("")) {

+                        break;

+                    }

+                }

+                Count = i;

+            }

+

+            fileBuffer.append(Integer.toString(Count));

+            fileBuffer.append(";\r\n\r\n");

+            break;

+        default:

+            break;

+        }

+

+        if (setVirtualList == null) {

+            if (UefiOrDxeModule) {

+                //

+                // No data so make a NULL list

+                //

+                fileBuffer

+                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {\r\n");

+                fileBuffer.append("  NULL\r\n");

+                fileBuffer.append("};\r\n\r\n");

+            }

+        } else {

+            //

+            // Write SetVirtualAddressMap function definition.

+            //

+            for (i = 0; i < setVirtualList.length; i++) {

+                if (setVirtualList[i].equalsIgnoreCase("")) {

+                    break;

+                }

+                fileBuffer.append("VOID\r\n");

+                fileBuffer.append("EFIAPI\n");

+                fileBuffer.append(setVirtualList[i]);

+                fileBuffer.append(" (\r\n");

+                fileBuffer.append("  IN EFI_EVENT  Event,\r\n");

+                fileBuffer.append("  IN VOID       *Context\r\n");

+                fileBuffer.append("  );\r\n\r\n");

+            }

+

+            //

+            // Write SetVirtualAddressMap entry point array.

+            //

+            fileBuffer

+                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {");

+            for (i = 0; i < setVirtualList.length; i++) {

+                if (setVirtualList[i].equalsIgnoreCase("")) {

+                    break;

+                }

+

+                if (i == 0) {

+                    fileBuffer.append("\r\n  ");

+                } else {

+                    fileBuffer.append(",\r\n  ");

+                }

+

+                fileBuffer.append(setVirtualList[i]);

+            }

+            if (Count == 0) {

+                fileBuffer.append("\r\n  NULL");

+            }

+            fileBuffer.append("\r\n};\r\n\r\n");

+        }

+

+        if (UefiOrDxeModule) {

+            //

+            // Entry point lib for these module types needs to know the count.

+            //

+            fileBuffer

+                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED  const UINTN _gDriverExitBootServicesEventCount = ");

+

+            //

+            // If the list is not valid or has no entries set count to zero else

+            // set count to the number of valid entries.

+            //

+            Count = 0;

+            if (exitBootList != null) {

+                if (setVirtualList != null) {

+                    for (i = 0; i < exitBootList.length; i++) {

+                        if (exitBootList[i].equalsIgnoreCase("")) {

+                            break;

+                        }

+                    }

+                    Count = i;

+                }

+            }

+            fileBuffer.append(Integer.toString(Count));

+            fileBuffer.append(";\r\n\r\n");

+        }

+

+        if (exitBootList == null) {

+            if (UefiOrDxeModule) {

+                //

+                // No data so make a NULL list.

+                //

+                fileBuffer

+                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {\r\n");

+                fileBuffer.append("  NULL\r\n");

+                fileBuffer.append("};\r\n\r\n");

+            }

+        } else {

+            //

+            // Write DriverExitBootServices function definition.

+            //

+            for (i = 0; i < exitBootList.length; i++) {

+                if (exitBootList[i].equalsIgnoreCase("")) {

+                    break;

+                }

+

+                fileBuffer.append("VOID\r\n");

+                fileBuffer.append("EFIAPI\n");

+                fileBuffer.append(exitBootList[i]);

+                fileBuffer.append(" (\r\n");

+                fileBuffer.append("  IN EFI_EVENT  Event,\r\n");

+                fileBuffer.append("  IN VOID       *Context\r\n");

+                fileBuffer.append("  );\r\n\r\n");

+            }

+

+            //

+            // Write DriverExitBootServices entry point array.

+            //

+            fileBuffer

+                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {");

+            for (i = 0; i < exitBootList.length; i++) {

+                if (exitBootList[i].equalsIgnoreCase("")) {

+                    break;

+                }

+

+                if (i == 0) {

+                    fileBuffer.append("\r\n  ");

+                } else {

+                    fileBuffer.append(",\r\n  ");

+                }

+                fileBuffer.append(exitBootList[i]);

+            }

+            if (Count == 0) {

+                fileBuffer.append("\r\n  NULL");

+            }

+            fileBuffer.append("\r\n};\r\n\r\n");

+        }

+

+    }

+

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
new file mode 100644
index 0000000..77404d4
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
@@ -0,0 +1,306 @@
+/**@file

+ AutogenLibOrder class.

+

+ This class is to reorder library instance sequence according to library 

+ dependence.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.build.autogen;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.LibraryClassDocument.LibraryClass;

+

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.global.SurfaceAreaQuery;

+

+/**

+  This class This class is to reorder library instance sequence according to

+  library dependence.

+**/

+public class AutogenLibOrder {

+    ///

+    /// The map of library class and its library instance.

+    ///

+    private Map<String, String> libClassMap = new HashMap<String, String>();

+

+    ///

+    /// The map of library instance and its implemet instance.

+    ///

+    private Map<String, String[]> libInstanceMap = new HashMap<String, String[]>();

+

+    ///

+    /// List of library instance. It is String[3] list, String[0] is libraryName,

+    /// String[1] is libraryConstructor name, String[2] is libDestructor name.

+    ///

+    private List<String[]> libInstanceList = new ArrayList<String[]>();

+    

+    /**

+      Constructor function

+    

+      This function mainly initialize some member variable.

+     

+      @param  libraryList   List of the library instance.

+      @throws Exception

+    **/

+    AutogenLibOrder(List<String> libraryList) throws Exception {

+        String[]       libInstance = new String[3];

+        LibraryClass[] libClassDeclList = null;

+        LibraryClass[] libClassConsmList = null;

+        

+        for (int i = 0; i < libraryList.size(); i++) {

+            //

+            // Add libraryInstance in to libInstanceList.

+            //

+            libInstance[0] = libraryList.get(i);

+            Map<String, XmlObject> libDoc = GlobalData.getDoc(libInstance[0]);

+            SurfaceAreaQuery.push(libDoc);

+            libInstance[1] = SurfaceAreaQuery.getLibConstructorName();

+            libInstance[2] = SurfaceAreaQuery.getLibDestructorName();

+            libInstanceList.add(libInstance.clone());

+            

+            //

+            // Add library instance and consumed library class list to

+            // libInstanceMap.

+            //

+            libClassConsmList = SurfaceAreaQuery

+                    .getLibraryClassArray(CommonDefinition.AlwaysConsumed);

+            if (libClassConsmList != null) {

+                String[] classStr = new String[libClassConsmList.length];

+                for (int k = 0; k < libClassConsmList.length; k++) {

+                    classStr[k] = libClassConsmList[k].getStringValue();

+                }

+                if (this.libInstanceMap.containsKey(libInstance[0])) {

+                    throw new Exception(

+                            libInstance[0]

+                                    + "this library instance is already exist, please check you library instance list!");

+                } else {

+                    this.libInstanceMap.put(libInstance[0], classStr);

+                }

+            }

+

+            //

+            // Add library class and library instance map.

+            //

+            libClassDeclList = SurfaceAreaQuery

+                    .getLibraryClassArray(CommonDefinition.AlwaysProduced);

+            if (libClassDeclList != null) {

+                for (int j = 0; j < libClassDeclList.length; j++) {

+                    if (this.libClassMap.containsKey(libClassDeclList[j]

+                            .getStringValue())) {

+                        System.out.println(libClassDeclList[j].getStringValue()

+                                + " class is already implement by "

+                                + this.libClassMap.get(libClassDeclList[j]

+                                        .getStringValue()));

+                        throw new Exception(libClassDeclList

+                                + " is already have library instance!");

+                    } else {

+                        this.libClassMap.put(libClassDeclList[j]

+                                .getStringValue(), libInstance[0]);

+                    }

+                }

+            }

+            SurfaceAreaQuery.pop();

+        }

+

+        //

+        // Check is the library instance list meet the require;

+        //

+        for (int s = 0; s < this.libInstanceList.size(); s++) {

+            String[] libClass = this.libInstanceMap.get(this.libInstanceList

+                    .get(s));

+            if (libClass != null) {

+                for (int t = 0; t < libClass.length; t++) {

+                    if (this.libClassMap.get(libClass[t]) == null) {

+                        //

+                        // Note: There exist a kind of module which depend on 

+                        // library class with no instance or whose instance will

+                        // never be linked into the module. 

+                        // For this satuation, the module has the description of 

+                        // library class in MSA file but no description of 

+                        // corresponding library instance in MBD file. There 

+                        // will be a warnig message given here after a standard 

+                        // log way has been decided.

+                        //

+                    }

+                }

+            }

+        }

+    }

+

+    /**

+      orderLibInstance

+      

+      This function reorder the library instance according the library class 

+      dependency.

+      

+      @return     List which content the ordered library instance.

+    **/

+    List orderLibInstance() {

+        List<String> orderList = new ArrayList<String>();

+        //

+        // Stack of node which track the library instance name ant its visiting

+        // flag.

+        //

+        List<Node> stackList = new ArrayList<Node>();

+        int stackSize = 0;

+        String libInstance = null;

+        if (libInstanceList.size() < 0) {

+            return null;

+        }

+

+        //

+        // Reorder the library instance.

+        //

+        for (int i = 0; i < libInstanceList.size(); i++) {

+            //

+            // If library instance is already in the order list skip it.

+            //

+            if (isInLibInstance(orderList, libInstanceList.get(i)[0])) {

+                continue;

+            }

+            

+            Node node = new Node(libInstanceList.get(i)[0], false);

+            //

+            // Use stack to reorder library instance.

+            // Push node to stack.

+            //

+            stackList.add(node);

+            while (stackList.size() > 0) {

+                stackSize = stackList.size() - 1;

+                //

+                // Pop the first node in stack. If the node flag has been visited

+                // add this node to orderlist and remove it from stack.

+                //

+                if (stackList.get(stackSize).isVisit) {

+                    if (!isInLibInstance(orderList,

+                            stackList.get(stackSize).nodeName)) {

+                        orderList.add(stackList.get(stackSize).nodeName);

+                        stackList.remove(stackSize);

+                    }

+                    

+                } else {

+                    //

+                    // Get the node value and set visit flag as true.

+                    //

+                    stackList.get(stackList.size() - 1).isVisit = true;

+                    String[] libClassList = this.libInstanceMap.get(stackList

+                            .get(stackSize).nodeName);

+                    //

+                    // Push the node dependence library instance to the stack.

+                    //

+                    if (libClassList != null) {

+                        for (int j = 0; j < libClassList.length; j++) {

+                            libInstance = this.libClassMap.get(libClassList[j]);

+                            if (libInstance != null

+                                    && !isInLibInstance(orderList, libInstance)) {

+                                //

+                                // If and only if the currently library instance

+                                // is not in stack and it have constructor or 

+                                // destructor function, push this library 

+                                // instacne in stack.

+                                //

+                                if (!isInStackList(stackList, this.libClassMap

+                                        .get(libClassList[j])) && isHaveConsDestructor(libInstance)) {

+                                    stackList.add(new Node(this.libClassMap

+                                            .get(libClassList[j]), false));

+                                }

+                            }

+                        }

+                    }

+                }

+            }

+        }

+        return orderList;

+    }

+

+    /**

+      isInLibInstance

+    

+      This function check does the library instance already in the list.

+    

+      @param list             List of the library instance.

+      @param instanceName     Name of library instance.

+      @return                 "true" the library instance in list |

+                              "false" the library instance is not in list.

+    **/

+    private boolean isInLibInstance(List list, String instanceName) {

+        for (int i = 0; i < list.size(); i++) {

+            if (instanceName.equalsIgnoreCase(list.get(i).toString())) {

+                return true;

+            }

+        }

+        return false;

+    }

+

+    /**

+      isInStackList 

+      

+      This function check if the node already in the stack.

+       

+      @param list        Stack.

+      @param nodeName    Name of node.

+      @return            "true" if node have in stack |

+                         "false" if node don't in stack.

+    **/ 

+    private boolean isInStackList(List<Node> list, String nodeName) {

+        for (int i = 0; i < list.size(); i++) {

+            if (nodeName.equalsIgnoreCase(list.get(i).nodeName)) {

+                return true;

+            }

+        }

+        return false;

+    }

+    

+    /**

+      isHaveConsDestructor

+      

+      This function check if the library have constructor or destructor 

+      function.

+      

+      @param  libName    Name of library

+      @return            "true" if library have constructor or desconstructor |

+                         "false" if library don't have constructor 

+                         and desconstructor.

+    **/

+    private boolean isHaveConsDestructor (String libName){

+        for (int i = 0; i < libInstanceList.size(); i++){

+            if (libInstanceList.get(i)[0].equalsIgnoreCase(libName)){

+                if (libInstanceList.get(i)[1] != null || libInstanceList.get(i)[2] != null){

+                    return true;

+                }

+            }

+        }

+        return false;

+    }

+}

+

+/**

+  Node 

+ 

+  This class is used as stack node.

+ 

+ **/

+class Node {

+    String nodeName;

+

+    boolean isVisit;

+

+    Node(String name, boolean isVisit) {

+        this.nodeName = name;

+        this.isVisit = false;

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
new file mode 100644
index 0000000..ce0bafe
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
@@ -0,0 +1,282 @@
+/** @file

+ CommonDefinition class.

+

+ This class is to define some common marcos and funcions, which used by AutoGen.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.build.autogen;

+

+/**

+  CommonDefinition

+  

+  This class is to define some common marcos, which used by AutoGen.

+  

+**/

+public class CommonDefinition {

+    public final static String spdSuffix = ".spd";

+    public final static String mbdSuffix = ".mbd";

+    public final static String msaSuffix = ".msa";

+    public final static String LibraryStr = "LIBRARY";

+    public final static String autoGenHbegin = "extern int __make_me_compile_correctly;\r\n";

+    public final static String include = "#include";

+    public final static String autoGenCLine1 = "\r\n";

+    

+    public final static String autoGenCLine2 = "const UINT8  _gDebugPropertyMask "

+                    + "= DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED"

+                    + "  | DEBUG_PROPERTY_DEBUG_PRINT_ENABLED"

+                    + "  | DEBUG_PROPERTY_DEBUG_CODE_ENABLED;\r\n";

+

+    public final static String autoGenCLine3 = "const UINTN  _gModuleDefaultErrorLevel"

+                    + " = EFI_D_ERROR | EFI_D_LOAD;\r\n";

+    

+    public final static String autoGenHLine1          = "#define EFI_SPECIFICATION_VERSION    0x00020000\r\n";

+    public final static String autoGenHVersionDefault = "#define EFI_SPECIFICATION_VERSION    0x00000000\r\n";

+    public final static String autoGenHLine2          = "#define EDK_RELEASE_VERSION        0x00090000\r\n";

+    public final static String autoGenHReleaseDefault = "#define EDK_RELEASE_VERSION        0x00000000\r\n";

+

+    public final static String includeAutogenH        = "#include    <AutoGen.h>\r\n" ;

+

+    public final static String gEfi = "gEfi";

+    public final static String protocolGuid = "ProtocolGuid";

+    public final static String ppiGuid = "PpiGuid";

+    public final static String guidGuid = "Guid";

+    

+    //

+    // AutoGen.h and AutoGen.c file's header

+    //

+    public final static String autogenHNotation = 

+      "/**\r\n" +

+      "  DO NOT EDIT\r\n" +

+      "  FILE auto-generated by GenBuild tasks\r\n" +

+      "  Module name:\r\n" +

+      "       AutoGen.h\r\n" +

+      "  Abstract:" +

+      "       Auto-generated AutoGen.h for building module or library.\r\n" +

+      "**/\r\n\r\n";

+        

+    public final static String autogenCNotation = 

+        "/**\r\n" +

+        "  DO NOT EDIT\r\n" +

+        "  FILE auto-generated by GenBuild tasks\r\n" +

+        "  Module name:\r\n" +

+        "       AutoGen.c\r\n" +

+        "  Abstract:" +

+        "       Auto-generated AutoGen.c for building module or library.\r\n" +

+        "**/\r\n\r\n";

+    

+    //

+    // module type

+    //

+    public final static int ModuleTypeBase = 0;

+    public final static int ModuleTypeSec = 1;

+    public final static int ModuleTypePeiCore = 2;

+    public final static int ModuleTypePeim = 3;

+    public final static int ModuleTypeDxeCore = 4;

+    public final static int ModuleTypeDxeDriver = 5;

+    public final static int ModuleTypeDxeRuntimeDriver = 6;

+    public final static int ModuleTypeDxeSmmDriver = 7;

+    public final static int ModuleTypeDxeSalDriver = 8;

+    public final static int ModuleTypeUefiDriver = 9;

+    public final static int ModuleTypeUefiApplication = 10;

+    public final static int ModuleTypeUnknown = 11;

+    

+   

+    //

+    // component type

+    //                           

+    public final static int  ComponentTypeNull = 0;

+    public final static int  ComponentTypeApriori = 1;

+    public final static int  ComponentTypeSec = 2;

+    public final static int  ComponentTypeLibrary = 3;

+    public final static int  ComponentTypeFvImageFile = 4;

+    public final static int  ComponentTypeBsDriver = 5;

+    public final static int  ComponentTypeRtDriver = 6;

+    public final static int  ComponentTypeSalRtDriver =7;

+    public final static int  ComponentTypePe32Peim = 8;

+    public final static int  ComponentTypePicPeim =9;

+    public final static int  ComponentTypeCombinedPeimDriver =10;

+    public final static int  ComponentTypePeiCore = 11;

+    public final static int  ComponentTypeDxeCore = 12;

+    public final static int  ComponentTypeApplication = 13;

+    public final static int  ComponentTypeBsDriverEfi = 14;

+    public final static int  ComponentTypeShellApp = 15;

+    public final static int  ComponentTypeBinary =16;

+    public final static int  ComponentTypeLogo = 17;

+    public final static int  ComponentTypeCustomBuild = 18;

+    public final static int  ComponentTypeUnknown = 19;

+

+    

+    //

+    // Usaged style

+    //

+    public final static String AlwaysConsumed = "ALWAYS_CONSUMED";

+    public final static String AlwaysProduced = "ALWAYS_PRODUCED";

+  

+

+    public static class MyEnum {

+        String moduleTypeStr;

+        int   type;

+

+        MyEnum (String str, int type) {

+            this.type    = type;

+            this.moduleTypeStr = str;

+        }

+

+        int ForInt(String str) {

+            if (str.equals(this.moduleTypeStr)) {

+                return this.type;

+            } else

+                return -1;

+        }

+    }

+    

+    //

+    // Module type

+    //

+    public static final MyEnum[] moduleEnum = new MyEnum[] {

+                    new MyEnum("BASE", ModuleTypeBase),

+                    new MyEnum("SEC", ModuleTypeSec),

+                    new MyEnum("PEI_CORE", ModuleTypePeiCore),

+                    new MyEnum("PEIM", ModuleTypePeim),

+                    new MyEnum("DXE_CORE", ModuleTypeDxeCore),

+                    new MyEnum("DXE_DRIVER", ModuleTypeDxeRuntimeDriver),

+                    new MyEnum("DXE_RUNTIME_DRIVER", ModuleTypeDxeRuntimeDriver),

+                    new MyEnum("DXE_SAL_DRIVER", ModuleTypeDxeSmmDriver),

+                    new MyEnum("DXE_SMM_DRIVER", ModuleTypeDxeSalDriver),

+                    new MyEnum("UEFI_DRIVER", ModuleTypeUefiDriver),

+                    new MyEnum("UEFI_APPLICATION", ModuleTypeUefiApplication) };

+    

+    //

+    // Component type

+    //

+    public static final MyEnum[] componentEnum = new MyEnum[]{

+                    new MyEnum("APRIORI", ComponentTypeApriori),

+                    new MyEnum("SEC", ComponentTypeSec),

+                    new MyEnum("LIBRARY", ComponentTypeLibrary),

+                    new MyEnum("FV_IMAGE_FILE", ComponentTypeFvImageFile),

+                    new MyEnum("BS_DRIVER", ComponentTypeBsDriver),

+                    new MyEnum("RT_DRIVER", ComponentTypeRtDriver),

+                    new MyEnum("SAL_RT_DRIVER", ComponentTypeSalRtDriver),

+                    new MyEnum("PE32_PEIM", ComponentTypePe32Peim),

+                    new MyEnum("PIC_PEIM", ComponentTypePicPeim),

+                    new MyEnum("COMBINED_PEIM_DRIVER", ComponentTypeCombinedPeimDriver),

+                    new MyEnum("PEI_CORE", ComponentTypePeiCore),

+                    new MyEnum("DXE_CORE", ComponentTypeDxeCore),

+                    new MyEnum("APPLICATION", ComponentTypeApplication),

+                    new MyEnum("BS_DRIVER_EFI", ComponentTypeBsDriverEfi),

+                    new MyEnum("SHELLAPP", ComponentTypeShellApp),

+                    new MyEnum("BINARY", ComponentTypeBinary),

+                    new MyEnum("LOGO", ComponentTypeLogo),

+                    new MyEnum("CUSTOM_BUILD", ComponentTypeCustomBuild)

+                    };

+   

+    /**

+      getModuleType

+      

+      This function get the module type value according module type string.

+      

+      @param  moduleTypeStr     String of modlue type.

+      @return                   

+    **/

+    static public int getModuleType(String moduleTypeStr) {

+        int returnValue = -1;

+        for (int i = 0; i < CommonDefinition.moduleEnum.length; i++) {

+            returnValue = CommonDefinition.moduleEnum[i].ForInt(moduleTypeStr);

+            if (returnValue != -1) {

+                return returnValue;

+            }

+        }

+        return CommonDefinition.ModuleTypeUnknown;

+    }

+

+    /**

+      getComponentType

+      

+      This function get the component type value according commponet type 

+      string.

+      

+      @param    componentTypeStr  String of component type.

+      @return

+    **/

+    static public int getComponentType (String componentTypeStr){

+        int returnValue = -1;

+        for (int i = 0; i < CommonDefinition.componentEnum.length; i++) {

+            returnValue = CommonDefinition.componentEnum[i].ForInt(componentTypeStr);

+            if (returnValue != -1) {

+                return returnValue;

+            }

+        }

+        return CommonDefinition.ComponentTypeUnknown;

+    }

+

+    /**

+    getComponentTypeString

+    

+    This function get the commponet type string according component type value.

+    

+    @param    componentType  Integer value of component type.

+    @return

+  **/

+    static public String getComponentTypeString (int componentType) {

+      if ((componentType > CommonDefinition.ComponentTypeUnknown) || 

+          (componentType < CommonDefinition.ComponentTypeNull)) {

+        return null;

+      }

+      for (int index = 0; index < CommonDefinition.componentEnum.length; index ++) {

+        if (componentType == CommonDefinition.componentEnum[index].type) {

+          return CommonDefinition.componentEnum[index].moduleTypeStr;

+        }

+      }

+      return null;

+    }

+

+    /**

+      isLibraryComponent 

+      

+      This function is to check does componet is library according to commponet

+      type value.

+      

+      @param   componentType     Integer value of component type.

+      @return

+    **/

+    static public boolean isLibraryComponent (int componentType) {

+      if (ComponentTypeLibrary == componentType) {

+        return true;

+      }

+      return false;

+    }

+

+		static public boolean isPeiPhaseComponent (int componentType) {

+			if (ComponentTypePe32Peim == componentType

+					|| ComponentTypePicPeim == componentType

+					|| ComponentTypeCombinedPeimDriver == componentType

+					|| ComponentTypePeiCore == componentType) {

+				return true;

+			}

+			return false;

+		}

+

+		static public boolean isPe32PeimComponent (int componentType) {

+			if (ComponentTypePe32Peim == componentType) {

+				return true;

+			}

+			return false;

+		}

+

+		static public boolean isBsDriverComponent (int componentType) {

+			if (ComponentTypeBsDriver == componentType) {

+				return true;

+			}

+			return false;

+		}

+		

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java
new file mode 100644
index 0000000..261cf58
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java
@@ -0,0 +1,131 @@
+/** @file

+  Java class FpdModuleIdentification is used to present a module identification

+  from BaseName, GUID, Version, PackageName, and ARCH. 

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build.fpd;

+

+/**

+  This class is used to identify a module with BaseName, GUID, Version, PackageName

+  and ARCH.

+  

+  @since GenBuild 1.0

+ **/

+public class FpdModuleIdentification {

+    

+    private String arch;

+    

+    private String fvBinding;

+    

+    private String baseName;

+    

+    private String packageName;

+    

+    private String guid;

+    

+    private String version;

+    

+    private String sequence;

+    

+    /**

+      

+      @param baseName the base name of the module

+      @param guid the GUID of the module

+      @param arch the ARCH of the module

+    **/

+    public FpdModuleIdentification(String baseName, String guid, String arch){

+        this.baseName = baseName;

+        this.guid = guid;

+        this.arch = arch;

+    }

+    

+    /**

+      Override java.lang.Object#equals. 

+      

+      <p>Currently, use BaseName and ARCH to identify a module. It will enhance

+      in the next version. </p>

+      

+      @see java.lang.Object#equals(java.lang.Object)

+    **/

+    public boolean equals(Object obj) {

+        if (obj instanceof FpdModuleIdentification) {

+            FpdModuleIdentification moduleIdObj = (FpdModuleIdentification)obj;

+            if ( baseName.equalsIgnoreCase(moduleIdObj.baseName) && arch.equalsIgnoreCase(moduleIdObj.arch)) {

+                return true;

+            }

+            // TBD

+            return false;

+        }

+        else {

+            return super.equals(obj);

+        }

+    }

+    

+    public void setArch(String arch) {

+        this.arch = arch;

+    }

+

+    public void setFvBinding(String fvBinding) {

+        this.fvBinding = fvBinding;

+    }

+

+    public void setSequence(String sequence) {

+        this.sequence = sequence;

+    }

+

+    public String toString(){

+        return arch + ":" + guid + "_" + baseName;

+    }

+

+    public void setBaseName(String baseName) {

+        this.baseName = baseName;

+    }

+

+    public void setGuid(String guid) {

+        this.guid = guid;

+    }

+

+    public void setPackageName(String packageName) {

+        this.packageName = packageName;

+    }

+

+    public void setVersion(String version) {

+        this.version = version;

+    }

+

+    public String getArch() {

+        return arch;

+    }

+

+    public String getBaseName() {

+        return baseName;

+    }

+

+    public String getFvBinding() {

+        return fvBinding;

+    }

+

+    public String getGuid() {

+        return guid;

+    }

+

+    public String getPackageName() {

+        return packageName;

+    }

+

+    public String getSequence() {

+        return sequence;

+    }

+

+    public String getVersion() {

+        return version;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
new file mode 100644
index 0000000..1e3de2a
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
@@ -0,0 +1,802 @@
+/** @file

+  This file is ANT task FpdParserTask. 

+ 

+  FpdParserTask is used to parse FPD (Framework Platform Description) and generate

+  build.out.xml. It is for Package or Platform build use. 

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build.fpd;

+

+import java.io.BufferedWriter;

+import java.io.File;

+import java.io.FileWriter;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.LinkedHashMap;

+import java.util.LinkedHashSet;

+import java.util.Map;

+import java.util.Set;

+import java.util.Vector;

+

+import javax.xml.parsers.DocumentBuilder;

+import javax.xml.parsers.DocumentBuilderFactory;

+import javax.xml.transform.OutputKeys;

+import javax.xml.transform.Result;

+import javax.xml.transform.Source;

+import javax.xml.transform.Transformer;

+import javax.xml.transform.TransformerFactory;

+import javax.xml.transform.dom.DOMSource;

+import javax.xml.transform.stream.StreamResult;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Property;

+import org.apache.xmlbeans.XmlObject;

+import org.w3c.dom.Comment;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.global.OutputManager;

+import org.tianocore.build.global.OverrideProcess;

+import org.tianocore.build.global.SurfaceAreaQuery;

+import org.tianocore.build.pcd.action.CollectPCDAction;

+import org.tianocore.build.pcd.action.ActionMessage;

+import org.tianocore.BuildOptionsDocument;

+import org.tianocore.FrameworkPlatformDescriptionDocument;

+import org.tianocore.ModuleSADocument;

+

+

+/**

+  <code>FpdParserTask</code> is an ANT task. The main function is parsing FPD

+  XML file and generating its ANT build script for Platform or Package. 

+  

+  <p>The usage is (take NT32 Platform for example):</p>

+  

+  <pre>

+    &lt;FPDParser fpdfilename="Build\Nt32.fpd" /&gt;

+  </pre>

+  

+  <p>The task will initialize all information through parsing Framework Database, 

+  SPD, Tool chain configuration files. </p>

+  

+  @since GenBuild 1.0

+**/

+public class FpdParserTask extends Task {

+

+    ///

+    /// FV dir: ${PLATFORM_DIR}/Build/FV

+    ///

+    public static final String FV_OUTPUT_DIR = "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "FV";

+

+    private File fpdFilename;

+

+    private File guiddatabase;

+

+    ///

+    /// Keep platform buildoption information

+    ///

+    public static XmlObject platformBuildOptions = null;

+

+    ///

+    /// Mapping from modules identification to out put file name

+    ///

+    private Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();

+

+    ///

+    /// Mapping from FV name to its modules

+    ///

+    private Map<String, Set<FpdModuleIdentification> > fvs = new HashMap<String, Set<FpdModuleIdentification> >();

+

+    ///

+    /// Mapping from sequence number to its modules

+    ///

+    private Map<String, Set<FpdModuleIdentification> > sequences = new HashMap<String, Set<FpdModuleIdentification> >();

+

+    ///

+    /// FpdParserTask can specify some ANT properties. 

+    ///

+    private Vector<Property> properties = new Vector<Property>();

+

+    private String info = "====================================================================\n"

+                    + "DO NOT EDIT \n"

+                    + "File auto-generated by build utility\n"

+                    + "\n"

+                    + "Abstract:\n"

+                    + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"

+                    + "=====================================================================";

+

+    /**

+      Public construct method. It is necessary for ANT task.

+    **/

+    public FpdParserTask () {

+    }

+

+    /**

+      ANT task's entry method. The main steps is described as following: 

+      

+      <ul>

+        <li>Initialize global information (Framework DB, SPD files and all MSA files 

+        listed in SPD). This step will execute only once in whole build process;</li>

+        <li>Parse specified FPD file; </li>

+        <li>Generate FV.inf files; </li>

+        <li>Generate build.out.xml file for Flatform or Package build; </li>

+        <li>Collect PCD information. </li>

+      </ul>

+      

+      @throws BuildException

+                  Surface area is not valid. 

+    **/

+    public void execute() throws BuildException {

+        OutputManager.update(getProject());

+        //

+        // Parse DB and SPDs files. Initialize Global Data

+        //

+        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()

+                        .getProperty("WORKSPACE_DIR"));

+        //

+        // Parse FPD file

+        //

+        parseFpdFile();

+        //

+        // Gen Fv.inf files

+        //

+        genFvInfFiles();

+        //

+        // Gen build.xml

+        //

+        genBuildFile();

+        //

+        // Collect PCD information 

+        // 

+        collectPCDInformation (); 

+    }

+    

+    /**

+      Generate Fv.inf files. The Fv.inf file is composed with four 

+      parts: Options, Attributes, Components and Files. The Fv.inf files 

+      will be under ${PLATFOMR_DIR}\Build\Fv.

+      

+      @throws BuildException

+              File write FV.inf files error. 

+    **/

+    private void genFvInfFiles() throws BuildException{

+        String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();

+        for (int i = 0; i < validFv.length; i++) {

+            getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase());

+            //

+            // Get all global variables from FPD and set them to properties

+            //

+            String[][] globalVariables = SurfaceAreaQuery

+                            .getFpdGlobalVariable();

+            for (int j = 0; j < globalVariables.length; j++) {

+                getProject().setProperty(globalVariables[j][0],

+                                globalVariables[j][1]);

+            }

+

+            File fvFile = new File(getProject().replaceProperties(

+                            FV_OUTPUT_DIR + File.separatorChar + validFv[i].toUpperCase()

+                                            + ".inf"));

+            fvFile.getParentFile().mkdirs();

+

+            try {

+                FileWriter fw = new FileWriter(fvFile);

+                BufferedWriter bw = new BufferedWriter(fw);

+                //

+                // Options

+                //

+                String[][] options = SurfaceAreaQuery.getFpdOptions(validFv[i]);

+                if (options.length > 0) {

+                    bw.write("[options]");

+                    bw.newLine();

+                    for (int j = 0; j < options.length; j++) {

+                        StringBuffer str = new StringBuffer(100);

+                        str.append(options[j][0]);

+                        while (str.length() < 40) {

+                            str.append(' ');

+                        }

+                        str.append("=  ");

+                        str.append(options[j][1]);

+                        bw.write(getProject().replaceProperties(str.toString()));

+                        bw.newLine();

+                    }

+                    bw.newLine();

+                }

+                //

+                // Attributes;

+                //

+                String[][] attributes = SurfaceAreaQuery

+                                .getFpdAttributes(validFv[i]);

+                if (attributes.length > 0) {

+                    bw.write("[attributes]");

+                    bw.newLine();

+                    for (int j = 0; j < attributes.length; j++) {

+                        StringBuffer str = new StringBuffer(100);

+                        str.append(attributes[j][0]);

+                        while (str.length() < 40) {

+                            str.append(' ');

+                        }

+                        str.append("=  ");

+                        str.append(attributes[j][1]);

+                        bw

+                                        .write(getProject().replaceProperties(

+                                                        str.toString()));

+                        bw.newLine();

+                    }

+                    bw.newLine();

+                }

+                //

+                // Components

+                //

+                String[][] components = SurfaceAreaQuery

+                                .getFpdComponents(validFv[i]);

+                if (components.length > 0) {

+                    bw.write("[components]");

+                    bw.newLine();

+                    for (int j = 0; j < components.length; j++) {

+                        StringBuffer str = new StringBuffer(100);

+                        str.append(components[j][0]);

+                        while (str.length() < 40) {

+                            str.append(' ');

+                        }

+                        str.append("=  ");

+                        str.append(components[j][1]);

+                        bw

+                                        .write(getProject().replaceProperties(

+                                                        str.toString()));

+                        bw.newLine();

+                    }

+                    bw.newLine();

+                }

+                //

+                // Files

+                //

+                Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i].toUpperCase());

+                if (filesSet != null) {

+                    FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet

+                                    .size()]);

+                    bw.write("[files]");

+                    bw.newLine();

+                    for (int j = 0; j < files.length; j++) {

+                        String str = outfiles.get(files[j]);

+                        bw.write(getProject().replaceProperties(

+                                        "EFI_FILE_NAME = " + str));

+                        bw.newLine();

+                    }

+                }

+                bw.flush();

+                bw.close();

+                fw.close();

+            } catch (Exception e) {

+                throw new BuildException("Generate Fv.inf file failed. \n" + e.getMessage());

+            }

+        }

+    }

+

+    /**

+      Parse FPD file. 

+    

+      @throws BuildException

+              FPD file is not valid. 

+    **/

+    private void parseFpdFile() throws BuildException {

+        try {

+            FrameworkPlatformDescriptionDocument doc = (FrameworkPlatformDescriptionDocument) XmlObject.Factory

+                            .parse(fpdFilename);

+            if ( ! doc.validate() ){

+                throw new BuildException("FPD file is invalid.");

+            }

+            platformBuildOptions = doc.getFrameworkPlatformDescription()

+                            .getBuildOptions();

+            HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();

+            map.put("FrameworkPlatformDescription", doc);

+            SurfaceAreaQuery.setDoc(map);

+            //

+            // Parse all list modules SA

+            //

+            parseModuleSAFiles();

+            SurfaceAreaQuery.setDoc(map);

+        } catch (Exception e) {

+            throw new BuildException("Load FPD file [" + fpdFilename.getPath()

+                            + "] error. \n" + e.getMessage());

+        }

+    }

+

+    /**

+      Parse all modules listed in FPD file. 

+    **/

+    private void parseModuleSAFiles() {

+        ModuleSADocument.ModuleSA[] moduleSAs = SurfaceAreaQuery

+                        .getFpdModules();

+        //

+        // For every Module lists in FPD file.

+        //

+        for (int i = 0; i < moduleSAs.length; i++) {

+            String defaultFv = "NULL";

+            String defaultArch = "IA32";

+            String baseName = moduleSAs[i].getModuleName();

+            if (baseName == null) {

+                System.out.println("Warning: Module Name is not specified.");

+                continue;

+            }

+            String fvBinding = moduleSAs[i].getFvBinding();

+            //

+            // If the module do not specify any FvBinding, use the default value.

+            // Else update the default FvBinding value to this value.

+            //

+            if (fvBinding == null) {

+                fvBinding = defaultFv;

+            }

+            else {

+                defaultFv = fvBinding;

+            }

+            String arch;

+            //

+            // If the module do not specify any Arch, use the default value.

+            // Else update the default Arch value to this value.

+            //

+            if (moduleSAs[i].getArch() == null ){

+                arch = defaultArch;

+            }

+            else {

+                arch = moduleSAs[i].getArch().toString();

+                defaultArch = arch;

+            }

+            Map<String, XmlObject> msaMap = GlobalData.getNativeMsa(baseName);

+            Map<String, XmlObject> mbdMap = GlobalData.getNativeMbd(baseName);

+            Map<String, XmlObject> map = new HashMap<String, XmlObject>();

+            //

+            // Whether the Module SA has parsed before or not

+            //

+            if (!GlobalData.isModuleParsed(baseName)) {

+                OverrideProcess op = new OverrideProcess();

+                //

+                // using overriding rules

+                // Here we can also put platform Build override

+                //

+                map = op.override(mbdMap, msaMap);

+                Map<String, XmlObject> overrideMap = op.override(

+                                getPlatformOverrideInfo(moduleSAs[i]),

+                                OverrideProcess.deal(map));

+                GlobalData.registerModule(baseName, overrideMap);

+            } else {

+                map = GlobalData.getDoc(baseName);

+            }

+            SurfaceAreaQuery.setDoc(map);

+            String guid = SurfaceAreaQuery.getModuleGuid();

+            String componentType = SurfaceAreaQuery.getComponentType();

+            FpdModuleIdentification moduleId = new FpdModuleIdentification(baseName, guid, arch);

+            updateFvs(fvBinding, moduleId);

+            outfiles.put(moduleId, "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar 

+                            + "${TARGET}" + File.separatorChar + arch

+                            + File.separatorChar + guid + "-" + baseName

+                            + getSuffix(componentType));

+        }

+    }

+

+    /**

+      Add the current module to corresponding FV. 

+    

+      @param fvName current FV name

+      @param moduleName current module identification

+    **/

+    private void updateFvs(String fvName, FpdModuleIdentification moduleName) {

+        String upcaseFvName = fvName.toUpperCase();

+        if (fvs.containsKey(upcaseFvName)) {

+            Set<FpdModuleIdentification> set = fvs.get(upcaseFvName);

+            set.add(moduleName);

+        } else {

+            Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();

+            set.add(moduleName);

+            fvs.put(upcaseFvName, set);

+        }

+    }

+

+    /**

+      Get the suffix based on component type. Current relationship are listed:  

+      

+      <pre>

+        <b>ComponentType</b>   <b>Suffix</b>

+           APPLICATION          .APP

+           SEC                  .SEC

+           PEI_CORE             .PEI

+           PE32_PEIM            .PEI

+           RELOCATABLE_PEIM     .PEI

+           PIC_PEIM             .PEI

+           COMBINED_PEIM_DRIVER .PEI

+           TE_PEIM              .PEI

+           LOGO                 .FFS

+           others               .DXE

+      </pre>

+    

+      @param componentType component type

+      @return

+      @throws BuildException

+              If component type is null

+    **/

+    public static String getSuffix(String componentType) throws BuildException{

+        if (componentType == null) {

+            throw new BuildException("Component type is not specified.");

+        }

+        String str = ".DXE";

+        if (componentType.equalsIgnoreCase("APPLICATION")) {

+            str = ".APP";

+        } else if (componentType.equalsIgnoreCase("SEC")) {

+            str = ".SEC";

+        } else if (componentType.equalsIgnoreCase("PEI_CORE")) {

+            str = ".PEI";

+        } else if (componentType.equalsIgnoreCase("PE32_PEIM")) {

+            str = ".PEI";

+        } else if (componentType.equalsIgnoreCase("RELOCATABLE_PEIM")) {

+            str = ".PEI";

+        } else if (componentType.equalsIgnoreCase("PIC_PEIM")) {

+            str = ".PEI";

+        } else if (componentType.equalsIgnoreCase("COMBINED_PEIM_DRIVER")) {

+            str = ".PEI";

+        } else if (componentType.equalsIgnoreCase("TE_PEIM")) {

+            str = ".PEI";

+        } else if (componentType.equalsIgnoreCase("LOGO")) {

+            str = ".FFS";

+        }

+        return str;

+    }

+

+    /**

+      Parse module surface are info described in FPD file and put them into map. 

+      

+      @param sa module surface area info descibed in FPD file

+      @return map list with top level elements

+    **/

+    private Map<String, XmlObject> getPlatformOverrideInfo(

+                    ModuleSADocument.ModuleSA sa) {

+        Map<String, XmlObject> map = new HashMap<String, XmlObject>();

+        map.put("SourceFiles", sa.getSourceFiles());

+        map.put("Includes", sa.getIncludes());

+        map.put("Libraries", sa.getLibraries());

+        map.put("Protocols", sa.getProtocols());

+        map.put("Events", sa.getEvents());

+        map.put("Hobs", sa.getHobs());

+        map.put("PPIs", sa.getPPIs());

+        map.put("Variables", sa.getVariables());

+        map.put("BootModes", sa.getBootModes());

+        map.put("SystemTables", sa.getSystemTables());

+        map.put("DataHubs", sa.getDataHubs());

+        map.put("Formsets", sa.getFormsets());

+        map.put("Guids", sa.getGuids());

+        map.put("Externs", sa.getExterns());

+        map.put("BuildOptions", platformBuildOptions);

+        return map;

+    }

+

+    /**

+      Generate build.out.xml file.

+      

+      @throws BuildException

+              build.out.xml XML document create error

+    **/

+    private void genBuildFile() throws BuildException {

+        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();

+        try {

+            DocumentBuilder dombuilder = domfac.newDocumentBuilder();

+            Document document = dombuilder.newDocument();

+            Comment rootComment = document.createComment(info);

+            //

+            // create root element and its attributes

+            //

+            Element root = document.createElement("project");

+            root.setAttribute("name", getProject().getProperty("PLATFORM"));

+            root.setAttribute("default", "main");

+            root.setAttribute("basedir", ".");

+            //

+            // element for External ANT tasks

+            //

+            root.appendChild(document.createComment("Apply external ANT tasks"));

+            Element ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "GenBuild.tasks");

+            root.appendChild(ele);

+

+            ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "frameworktasks.tasks");

+            root.appendChild(ele);

+

+            ele = document.createElement("property");

+            ele.setAttribute("environment", "env");

+            root.appendChild(ele);

+            //

+            // Default Target

+            //

+            root.appendChild(document.createComment("Default target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "main");

+            ele.setAttribute("depends", "modules, fvs");

+            root.appendChild(ele);

+            //

+            // Modules Target

+            //

+            root.appendChild(document.createComment("Modules target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "modules");

+

+            Set set = outfiles.keySet();

+            Iterator iter = set.iterator();

+            while (iter.hasNext()) {

+                FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();

+                String baseName = moduleId.getBaseName();

+                Element moduleEle = document.createElement("ant");

+                moduleEle.setAttribute("antfile", GlobalData

+                                .getModulePath(baseName)

+                                + File.separatorChar + "build.xml");

+                moduleEle.setAttribute("target", baseName);

+                //

+                // ARCH

+                //

+                Element property = document.createElement("property");

+                property.setAttribute("name", "ARCH");

+                property.setAttribute("value", moduleId.getArch());

+                moduleEle.appendChild(property);

+                //

+                // PACKAGE_DIR

+                //

+                property = document.createElement("property");

+                property.setAttribute("name", "PACKAGE_DIR");

+                property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar

+                                + GlobalData.getPackagePathForModule(baseName));

+                moduleEle.appendChild(property);

+                //

+                // PACKAGE

+                //

+                property = document.createElement("property");

+                property.setAttribute("name", "PACKAGE");

+                property.setAttribute("value", GlobalData

+                                .getPackageNameForModule(baseName));

+                moduleEle.appendChild(property);

+                ele.appendChild(moduleEle);

+            }

+            root.appendChild(ele);

+            //

+            // FVS Target

+            //

+            root.appendChild(document.createComment("FVs target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "fvs");

+

+            String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();

+            for (int i = 0; i < validFv.length; i++) {

+                String inputFile = FV_OUTPUT_DIR + "" + File.separatorChar

+                                + validFv[i].toUpperCase() + ".inf";

+                Element fvEle = document.createElement("genfvimage");

+                fvEle.setAttribute("infFile", inputFile);

+                ele.appendChild(fvEle);

+                Element moveEle = document.createElement("move");

+                moveEle.setAttribute("file", validFv[i].toUpperCase() + ".fv");

+                moveEle.setAttribute("todir", FV_OUTPUT_DIR);

+                ele.appendChild(moveEle);

+            }

+            root.appendChild(ele);

+            

+            boolean isUnified = false;

+            BuildOptionsDocument.BuildOptions buildOptions = (BuildOptionsDocument.BuildOptions)platformBuildOptions;

+            if (buildOptions.getOutputDirectory() != null){

+                if (buildOptions.getOutputDirectory().getIntermediateDirectories() != null){

+                    if (buildOptions.getOutputDirectory().getIntermediateDirectories().toString().equalsIgnoreCase("UNIFIED")){

+                        isUnified = true;

+                    }

+                }

+            }

+            //

+            // Clean Target

+            //

+            root.appendChild(document.createComment("Clean target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "clean");

+            

+            if (isUnified) {

+                Element cleanEle = document.createElement("delete");

+                cleanEle.setAttribute("includeemptydirs", "true");

+                Element filesetEle = document.createElement("fileset");

+                filesetEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");

+                filesetEle.setAttribute("includes", "**/OUTPUT/**");

+                cleanEle.appendChild(filesetEle);

+                ele.appendChild(cleanEle);

+            }

+            else {

+                set = outfiles.keySet();

+                iter = set.iterator();

+                while (iter.hasNext()) {

+                    FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();

+                    String baseName = moduleId.getBaseName();

+    

+                    Element ifEle = document.createElement("if");

+                    Element availableEle = document.createElement("available");

+                    availableEle.setAttribute("file", GlobalData

+                                    .getModulePath(baseName)

+                                    + File.separatorChar + "build.xml");

+                    ifEle.appendChild(availableEle);

+                    Element elseEle = document.createElement("then");

+    

+                    Element moduleEle = document.createElement("ant");

+                    moduleEle.setAttribute("antfile", GlobalData

+                                    .getModulePath(baseName)

+                                    + File.separatorChar + "build.xml");

+                    moduleEle.setAttribute("target", baseName + "_clean");

+                    //

+                    // ARCH

+                    //

+                    Element property = document.createElement("property");

+                    property.setAttribute("name", "ARCH");

+                    property.setAttribute("value", moduleId.getArch());

+                    moduleEle.appendChild(property);

+                    //

+                    // PACKAGE_DIR

+                    //

+                    property = document.createElement("property");

+                    property.setAttribute("name", "PACKAGE_DIR");

+                    property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar

+                                    + GlobalData.getPackagePathForModule(baseName));

+                    moduleEle.appendChild(property);

+                    //

+                    // PACKAGE

+                    //

+                    property = document.createElement("property");

+                    property.setAttribute("name", "PACKAGE");

+                    property.setAttribute("value", GlobalData

+                                    .getPackageNameForModule(baseName));

+                    moduleEle.appendChild(property);

+                    elseEle.appendChild(moduleEle);

+                    ifEle.appendChild(elseEle);

+                    ele.appendChild(ifEle);

+                }

+            }

+            root.appendChild(ele);

+            //

+            // Deep Clean Target

+            //

+            root.appendChild(document.createComment("Clean All target"));

+            ele = document.createElement("target");

+            ele.setAttribute("name", "cleanall");

+

+            if (isUnified) {

+                Element cleanAllEle = document.createElement("delete");

+                cleanAllEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");

+                ele.appendChild(cleanAllEle);

+            }

+            else {

+                set = outfiles.keySet();

+                iter = set.iterator();

+                while (iter.hasNext()) {

+                    FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();

+                    String baseName = moduleId.getBaseName();

+    

+                    Element ifEle = document.createElement("if");

+                    Element availableEle = document.createElement("available");

+                    availableEle.setAttribute("file", GlobalData

+                                    .getModulePath(baseName)

+                                    + File.separatorChar + "build.xml");

+                    ifEle.appendChild(availableEle);

+                    Element elseEle = document.createElement("then");

+    

+                    Element moduleEle = document.createElement("ant");

+                    moduleEle.setAttribute("antfile", GlobalData

+                                    .getModulePath(baseName)

+                                    + File.separatorChar + "build.xml");

+                    moduleEle.setAttribute("target", baseName + "_cleanall");

+                    //

+                    // ARCH

+                    //

+                    Element property = document.createElement("property");

+                    property.setAttribute("name", "ARCH");

+                    property.setAttribute("value", moduleId.getArch());

+                    moduleEle.appendChild(property);

+                    //

+                    // PACKAGE_DIR

+                    //

+                    property = document.createElement("property");

+                    property.setAttribute("name", "PACKAGE_DIR");

+                    property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar

+                                    + GlobalData.getPackagePathForModule(baseName));

+                    moduleEle.appendChild(property);

+                    //

+                    // PACKAGE

+                    //

+                    property = document.createElement("property");

+                    property.setAttribute("name", "PACKAGE");

+                    property.setAttribute("value", GlobalData

+                                    .getPackageNameForModule(baseName));

+                    moduleEle.appendChild(property);

+                    elseEle.appendChild(moduleEle);

+                    ifEle.appendChild(elseEle);

+                    ele.appendChild(ifEle);

+                }

+            }

+            root.appendChild(ele);

+            

+            document.appendChild(rootComment);

+            document.appendChild(root);

+            //

+            // Prepare the DOM document for writing

+            //

+            Source source = new DOMSource(document);

+            //

+            // Prepare the output file

+            //

+            File file = new File(getProject().getProperty("PLATFORM_DIR")

+                            + File.separatorChar + "build.out.xml");

+            //

+            // generate all directory path

+            //

+            (new File(file.getParent())).mkdirs();

+            Result result = new StreamResult(file);

+            //

+            // Write the DOM document to the file

+            //

+            Transformer xformer = TransformerFactory.newInstance()

+                            .newTransformer();

+            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

+            xformer.setOutputProperty(OutputKeys.INDENT, "yes");

+            xformer.transform(source, result);

+        } catch (Exception ex) {

+            throw new BuildException("Generate build.out.xml failed. \n" + ex.getMessage());

+        }

+    }

+

+    /**

+      Add a property. 

+      

+      @param p property

+    **/

+    public void addProperty(Property p) {

+        properties.addElement(p);

+    }

+

+    /**

+      Get FPD file name.

+       

+      @return FPD file name.

+    **/

+    public File getFpdFilename() {

+        return fpdFilename;

+    }

+

+    /**

+      Set FPD file name.

+      

+      @param fpdFilename FPD file name

+    **/

+    public void setFpdFilename(File fpdFilename) {

+        this.fpdFilename = fpdFilename;

+    }

+

+    public File getGuiddatabase() {

+        return guiddatabase;

+    }

+

+    public void setGuiddatabase(File guiddatabase) {

+        this.guiddatabase = guiddatabase;

+    }

+

+    public void collectPCDInformation() {

+      CollectPCDAction collectAction = new CollectPCDAction ();

+      //

+      // Collect all PCD information from FPD to MSA, and get help information from SPD.

+      // These all information will be stored into memory database for future usage such 

+      // as autogen.

+      //

+      try {

+        collectAction.perform (

+          getProject().getProperty("WORKSPACE_DIR"),

+          fpdFilename.getPath(),

+          ActionMessage.MAX_MESSAGE_LEVEL

+          );

+      } catch (Exception exp) {

+        throw new BuildException (String.format("Fail to do PCD preprocess from FPD file,  the cause is %s", exp.getMessage()));

+      }

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java
new file mode 100644
index 0000000..78cde75
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java
@@ -0,0 +1,129 @@
+/** @file

+This file is used to define class which represents dependency file in ANT task

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.global;

+

+import org.apache.tools.ant.types.DataType;

+import org.apache.tools.ant.types.Path;

+

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.LineNumberReader;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.regex.Matcher;

+import java.util.regex.Pattern;

+

+/**

+ DpFile is a ANT DataType which can be used to specify dependency files from

+ a file list file, from file list string separated by space, comma or semi-comma,

+ or from file name with absolute path

+ **/

+public class DpFile  extends DataType {

+    ///

+    /// keep the list of files path

+    ///

+    private List<String> nameList = new ArrayList<String>();

+

+    /**

+     Empty constructor just in case

+     **/

+    public DpFile() {

+    }

+

+    /**

+     Empty execute method of ANT task, just in case

+     **/

+    public void execute() {

+    }

+

+    /**

+     Standard set method of ANT task/datatype, for ListFile attribute. It simply

+     fetch one file path a line from specified list file, and put them in nameList

+

+     @param     fileListFile    file which contains a file list, one file a line,

+                                with full path

+     **/

+    public void setListFile(String fileListFile) {

+        File file = new File(fileListFile);

+        if (!file.exists()) {

+            return;

+        }

+

+        try {

+            FileReader fileReader = new FileReader(file);

+            LineNumberReader lineReader = new LineNumberReader(fileReader);

+

+            String filePath = null;

+            while ((filePath = lineReader.readLine()) != null) {

+                filePath = filePath.trim();

+                if (filePath.length() == 0) {

+                    continue;

+                }

+                this.nameList.add(filePath);

+            }

+

+            lineReader.close();

+            fileReader.close();

+        } catch (IOException e) {

+            System.out.println (e.getMessage());

+        }

+    }

+

+    /**

+     Standard set method of ANT task/datatype, for List attribute.

+

+     @param     fileList        string with file pathes separated by space, comma,

+                                or semi-comma

+     **/

+    public void setList(String fileList) {

+        //

+        // space, comma or semi-comma separated files list

+        //

+        Pattern pattern = Pattern.compile("([^ ,;\n\r]++)[ ,;\n\r]*+");

+        Matcher matcher = pattern.matcher(fileList);

+

+        while (matcher.find()) {

+            //

+            // keep each file name before " ,;\n\r"

+            //

+            String filePath = fileList.substring(matcher.start(1), matcher.end(1)).trim();

+            if (filePath.length() == 0) {

+                continue;

+            }

+            nameList.add(Path.translateFile(filePath));

+        }

+

+    }

+

+    /**

+     Standard set method of ANT task/datatype, for Name attribute.

+

+     @param     fileName        string of a file full path

+     **/

+    public void setName(String fileName) {

+        this.nameList.add(fileName);

+    }

+

+    /**

+     Fetch the file name list.

+

+     @returns   A string list which contains file names specified to check dependnecy

+     **/

+    public List<String> getList() {

+        return this.nameList;

+    }

+}

+

+

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/DpFileList.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/DpFileList.java
new file mode 100644
index 0000000..8b4b4a0
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/DpFileList.java
@@ -0,0 +1,50 @@
+/** @file

+This file is used to nest elements corresponding to DpFile

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.global;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ DpFileList is a container of Dpfile at the point of ANT task/datatype

+ **/

+public class DpFileList {

+    ///

+    /// Keep all the file names from all nested DpFile

+    ///

+    List<String> nameList = new ArrayList<String>();

+

+    /**

+     Empty constructor just in case

+     **/

+    public DpFileList() {

+    }

+

+    /**

+     Empty execute method of ANT task. ANT will call it even we don't need it.

+     **/

+    public void execute() {

+    }

+

+    /**

+     Standard add method of ANT task, for nested DpFile type of elements. It just

+     simply fetch the files list from DpFile and put them in its own nameList.

+

+     @param     f   a DpFile object which will be instantiated by ANT

+     **/

+    public void addConfiguredFile(DpFile f) {

+        this.nameList.addAll(f.getList());

+    }

+}

+

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
new file mode 100644
index 0000000..e457d6d
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
@@ -0,0 +1,637 @@
+/** @file

+  GlobalData class. 

+  

+  GlobalData provide initializing, instoring, querying and update global data.

+  It is a bridge to intercommunicate between multiple component, such as AutoGen,

+  PCD and so on.   

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build.global;

+

+import java.io.File;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.FrameworkDatabaseDocument;

+import org.tianocore.MsaFilesDocument;

+import org.tianocore.PackageListDocument;

+import org.tianocore.PackageSurfaceAreaDocument;

+import org.tianocore.MsaHeaderDocument.MsaHeader;

+import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;

+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;

+import org.tianocore.build.autogen.CommonDefinition;

+import org.tianocore.build.fpd.FpdParserTask;

+

+/**

+  GlobalData provide initializing, instoring, querying and update global data.

+  It is a bridge to intercommunicate between multiple component, such as AutoGen,

+  PCD and so on. 

+  

+  <p>Note that all global information are initialized incrementally. All data will 

+  parse and record only it is necessary during build time. </p>

+  

+  @since GenBuild 1.0

+**/

+public class GlobalData {

+

+    ///

+    /// means no surface area information for module

+    ///

+    public static final int NO_SA = 0;

+

+    ///

+    /// means only MSA

+    ///

+    public static final int ONLY_MSA = 1;

+

+    ///

+    /// means only Library MSA

+    ///

+    public static final int ONLY_LIBMSA = 2;

+

+    ///

+    /// means both MSA and MBD

+    ///

+    public static final int MSA_AND_MBD = 3;

+

+    ///

+    /// means both Library MSA and Library MBD

+    ///

+    public static final int LIBMSA_AND_LIBMBD = 4;

+

+    ///

+    /// Be used to ensure Global data will be initialized only once.

+    ///

+    public static boolean globalFlag = false;

+

+    ///

+    /// Record current WORKSPACE Directory

+    ///

+    private static String workspaceDir = "";

+

+    ///

+    /// Two columns: Package Name (Key), Package Path(ralative to WORKSPACE)

+    ///

+    private static final Map<String, String> packageInfo = new HashMap<String, String>();

+

+    ///

+    /// spdTable

+    /// Key: Package Name, Value: SPD detail info

+    ///

+    private static final Map<String, Spd> spdTable = new HashMap<String, Spd>();

+

+    ///

+    /// Three columns:

+    /// 1. Module Name | BaseName (Key)

+    /// 2. Module Path + Msa file name (relative to Package)

+    /// 3. Package Name (This module belong to which package)

+    ///

+    private static final Map<String, String[]> moduleInfo = new HashMap<String, String[]>();

+

+    ///

+    /// List all libraries for current build module

+    /// Key: Library BaseName, Value: output library path+name

+    ///

+    private static final Map<String, String> libraries = new HashMap<String, String>();

+

+    ///

+    /// Store every module's relative library instances BaseName

+    /// Key: Module BaseName, Value: All library instances module depends on.

+    ///

+    private static final Map<String, Set<String> > moduleLibraryMap = new HashMap<String, Set<String> >();

+

+    ///

+    /// Key: Module BaseName, Value: original MSA info

+    ///

+    private static final Map<String, Map<String, XmlObject> > nativeMsa = new HashMap<String, Map<String, XmlObject> >();

+

+    ///

+    /// Key: Module BaseName, Value: original MBD info

+    ///

+    private static final Map<String, Map<String, XmlObject> > nativeMbd = new HashMap<String, Map<String, XmlObject> >();

+

+    ///

+    /// Two columns: Module Name or Base Name as Key

+    /// Value is a HashMap with overridden data from MSA/MBD or/and Platform

+    ///

+    private static final Map<String, Map<String, XmlObject> > parsedModules = new HashMap<String, Map<String, XmlObject> >();

+

+    ///

+    /// List all built Module; Value is Module BaseName + Arch. TBD

+    ///

+    private static final Set<String> builtModules = new HashSet<String>();

+

+    ///

+    /// Library instance information table which recored the library and it's

+    /// constructor and distructor function

+    ///

+    private static final Map<String, String[]> libInstanceInfo = new HashMap<String, String[]>();

+

+    ///

+    /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.

+    ///

+    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();

+

+    /**

+      Query the module's absolute path with module base name. 

+      

+      @param moduleName the base name of the module

+      @return the absolute module path

+    **/

+    public synchronized static String getModulePath(String moduleName) {

+        String[] info = moduleInfo.get(moduleName);

+        String packagePath = (String) packageInfo.get(info[1]);

+        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);

+        return convertFile.getParent();

+    }

+

+    /**

+      Query the module's absolute MSA file path with module base name. 

+    

+      @param moduleName the base name of the module

+      @return the absolute MSA file name

+      @throws BuildException

+              Base name is not registered in any SPD files

+    **/

+    private synchronized static String getMsaFilename(String moduleName) throws BuildException {

+        String[] info = moduleInfo.get(moduleName);

+        if (info == null) {

+            throw new BuildException("Module base name [" + moduleName + "] can't found in all SPD.");

+        }

+        String packagePath = (String) packageInfo.get(info[1]);

+        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);

+        return convertFile.getPath();

+    }

+

+    /**

+      Query the module's absolute MBD file path with module base name. 

+    

+      @param moduleName the base name of the module

+      @return the absolute MBD file name

+      @throws BuildException

+              Base name is not registered in any SPD files

+    **/

+    private synchronized static String getMbdFilename(String moduleName) throws BuildException {

+        String[] info = moduleInfo.get(moduleName);

+        if (info == null) {

+            throw new BuildException("Info: Module base name [" + moduleName + "] can't found in all SPD.");

+        }

+        String packagePath = (String) packageInfo.get(info[1]);

+        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);

+        return convertFile.getPath().substring(0, convertFile.getPath().length() - 4) + ".mbd";

+    }

+

+    /**

+      Get the current WORKSPACE Directory. 

+      @return current workspace directory

+    **/

+    public synchronized static String getWorkspacePath() {

+        return workspaceDir;

+    }

+

+    /**

+      Query package relative path to WORKSPACE_DIR with package name. 

+      

+      @param packageName the name of the package

+      @return the path relative to WORKSPACE_DIR 

+    **/

+    public synchronized static String getPackagePath(String packageName) {

+        return (String) packageInfo.get(packageName);

+    }

+

+    /**

+      Query package (which the module belongs to) relative path to WORSPACE_DIR.  

+    

+      @param moduleName the base name of the module

+      @return the relative path to WORKSPACE_DIR of the package which the module belongs to

+    **/

+    public synchronized static String getPackagePathForModule(String moduleName) {

+        String[] info = moduleInfo.get(moduleName);

+        String packagePath = (String) packageInfo.get(info[1]);

+        return packagePath;

+    }

+

+    /**

+      Query the package name which the module belongs to with the module's base name.

+    

+      @param moduleName the base name of the module

+      @return the package name which the module belongs to

+    **/

+    public synchronized static String getPackageNameForModule(String moduleName) {

+        return moduleInfo.get(moduleName)[1];

+    }

+

+    /**

+      Parse framework database (DB) and all SPD files listed in DB to initialize

+      the environment for next build. This method will only be executed only once

+      in the whole build process.  

+      

+      @param workspaceDatabaseFile the file name of framework database

+      @param workspaceDir current workspace directory path

+      @throws BuildException

+              Framework Dababase or SPD or MSA file is not valid

+    **/

+    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws BuildException {

+        if (globalFlag) {

+            return;

+        }

+        globalFlag = true;

+        GlobalData.workspaceDir = workspaceDir;

+        File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);

+        try {

+            FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);

+            List<PackageListDocument.PackageList.Package> packages = db.getFrameworkDatabase().getPackageList()

+                                                                       .getPackageList();

+            Iterator iter = packages.iterator();

+            while (iter.hasNext()) {

+                PackageListDocument.PackageList.Package packageItem = (PackageListDocument.PackageList.Package) iter

+                                                                                                                    .next();

+                String name = packageItem.getPackageNameArray(0).getStringValue();

+                String path = packageItem.getPathArray(0).getStringValue();

+                packageInfo.put(name, path);

+                File spdFile = new File(workspaceDir + File.separatorChar + path + File.separatorChar + name + ".spd");

+                initPackageInfo(spdFile.getPath(), name);

+                // 

+                // SPD Parse.

+                //

+                PackageSurfaceAreaDocument spdDoc = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(spdFile);

+                Spd spd = new Spd(spdDoc, path);

+                spdTable.put(name, spd);

+

+            }

+        } catch (Exception e) {

+            throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());

+        }

+    }

+

+    /**

+      Parse every MSA files, get base name from MSA Header. And record those

+      values to ModuleInfo.

+      

+      @param packageFilename the file name of the package

+      @param packageName the name of the package

+      @throws BuildException

+              SPD or MSA file is not valid

+    **/

+    private synchronized static void initPackageInfo(String packageFilename, String packageName) throws BuildException {

+        File packageFile = new File(packageFilename);

+        try {

+            PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile);

+            List<MsaFilesDocument.MsaFiles.MsaFile> msasList = spd.getPackageSurfaceArea().getMsaFiles()

+                                                                  .getMsaFileList();

+            Iterator msasIter = msasList.iterator();

+            while (msasIter.hasNext()) {

+                MsaFilesDocument.MsaFiles.MsaFile msas = (MsaFilesDocument.MsaFiles.MsaFile) msasIter.next();

+                String msaFilename = msas.getFilename().getStringValue();

+                File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName)

+                                        + File.separatorChar + msaFilename);

+                SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();

+                Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);

+                String baseName = "";

+                XmlObject header = null;

+                if ((header = map.get("MsaHeader")) != null) {

+                    baseName = ((MsaHeader) header).getBaseName().getStringValue();

+                } else if ((header = map.get("MsaLibHeader")) != null) {

+                    baseName = ((MsaLibHeader) header).getBaseName().getStringValue();

+                } else {

+                    continue;

+                }

+                nativeMsa.put(baseName, map);

+                String[] info = { msaFilename, packageName };

+                moduleInfo.put(baseName, info);

+            }

+        } catch (Exception e) {

+            throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n"

+                                     + e.getMessage());

+        }

+    }

+

+    /**

+      Query the libraries which the module depends on.

+    

+      @param moduleName the base name of the module

+      @return the libraries which the module depends on

+    **/

+    public synchronized static String[] getModuleLibrary(String moduleName, String arch) {

+        Set<String> set = moduleLibraryMap.get(moduleName + "-" + arch);

+        return set.toArray(new String[set.size()]);

+    }

+

+    /**

+      Register module's library list which it depends on for later use. 

+      

+      @param moduleName the base name of the module

+      @param libraryList the libraries which the module depends on

+    **/

+    public synchronized static void addModuleLibrary(String moduleName, String arch, Set<String> libraryList) {

+        moduleLibraryMap.put(moduleName + "-" + arch, libraryList);

+    }

+

+    /**

+      Query the library absolute file name with library name. 

+      

+      @param library the base name of the library

+      @return the library absolute file name

+    **/

+    public synchronized static String getLibrary(String library, String arch) {

+        return libraries.get(library + "-" + arch);

+    }

+

+    /**

+      Register library absolute file name for later use.

+      

+      @param library the base name of the library

+      @param resultPath the library absolute file name

+    **/

+    public synchronized static void addLibrary(String library, String arch, String resultPath) {

+        libraries.put(library + "-" + arch, resultPath);

+    }

+

+    /**

+      Whether the module with ARCH has built in the previous build. 

+      

+      @param moduleName the base name of the module

+      @param arch current build ARCH

+      @return true if the module has built in previous, otherwise return false

+    **/

+    public synchronized static boolean isModuleBuilt(String moduleName, String arch) {

+        return builtModules.contains(moduleName + "-" + arch);

+    }

+

+    /**

+      Register the module with ARCH has built. 

+    

+      @param moduleName the base name of the module

+      @param arch current build ARCH

+    **/

+    public synchronized static void registerBuiltModule(String moduleName, String arch) {

+        builtModules.add(moduleName + "-" + arch);

+    }

+

+    /**

+      Whether the module's surface area has parsed in the previous build.

+      

+      @param moduleName the base name of the module

+      @return true if the module's surface area has parsed in previous, otherwise

+      return false

+    **/

+    public synchronized static boolean isModuleParsed(String moduleName) {

+        return parsedModules.containsKey(moduleName);

+    }

+

+    /**

+      Query overrided module surface area information. If current is Package

+      or Platform build, also include the information from FPD file. 

+      

+      <p>Note that surface area parsing is incremental. That means the method will 

+      only to parse the MSA and MBD files when never parsed before. </p>

+    

+      @param moduleName the base name of the module

+      @return the overrided module surface area information

+      @throws BuildException

+              MSA or MBD is not valid

+    **/

+    public synchronized static Map<String, XmlObject> getDoc(String moduleName) throws BuildException {

+        if (parsedModules.containsKey(moduleName)) {

+            return parsedModules.get(moduleName);

+        }

+        Map<String, XmlObject> msaMap = getNativeMsa(moduleName);

+        Map<String, XmlObject> mbdMap = getNativeMbd(moduleName);

+        OverrideProcess op = new OverrideProcess();

+        Map<String, XmlObject> map = op.override(mbdMap, msaMap);

+        //

+        // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM

+        //

+        if (FpdParserTask.platformBuildOptions != null) {

+            Map<String, XmlObject> platformMap = new HashMap<String, XmlObject>();

+            platformMap.put("BuildOptions", FpdParserTask.platformBuildOptions);

+            Map<String, XmlObject> overrideMap = op.override(platformMap, OverrideProcess.deal(map));

+            GlobalData.registerModule(moduleName, overrideMap);

+            return overrideMap;

+        } else {

+            parsedModules.put(moduleName, map);

+            return map;

+        }

+    }

+

+    /**

+      Query the native MSA information with module base name. 

+      

+      <p>Note that MSA parsing is incremental. That means the method will 

+      only to parse the MSA files when never parsed before. </p>

+      

+      @param moduleName the base name of the module

+      @return the native MSA information

+      @throws BuildException

+              MSA file is not valid

+    **/

+    public synchronized static Map<String, XmlObject> getNativeMsa(String moduleName) throws BuildException {

+        if (nativeMsa.containsKey(moduleName)) {

+            return nativeMsa.get(moduleName);

+        }

+        String msaFilename = getMsaFilename(moduleName);

+        File msaFile = new File(msaFilename);

+        if (!msaFile.exists()) {

+            throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found.");

+        }

+        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();

+        Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);

+        nativeMsa.put(moduleName, map);

+        return map;

+    }

+    

+    /**

+      Query the native MBD information with module base name. 

+      

+      <p>Note that MBD parsing is incremental. That means the method will 

+      only to parse the MBD files when never parsed before. </p>

+    

+      @param moduleName the base name of the module

+      @return the native MBD information

+      @throws BuildException

+              MBD file is not valid

+    **/

+    public synchronized static Map<String, XmlObject> getNativeMbd(String moduleName) throws BuildException {

+        if (nativeMbd.containsKey(moduleName)) {

+            return nativeMbd.get(moduleName);

+        }

+        String mbdFilename = getMbdFilename(moduleName);

+        File mbdFile = new File(mbdFilename);

+        if (!mbdFile.exists()) {

+            throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found.");

+        }

+        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();

+        Map<String, XmlObject> map = surfaceAreaParser.parseFile(mbdFile);

+        nativeMbd.put(moduleName, map);

+        return map;

+    }

+

+    /**

+      Register module overrided surface area information. If has existed, then update.

+      

+      @param moduleName the base name of the module

+      @param map the overrided surface area information

+    **/

+    public synchronized static void registerModule(String moduleName, Map<String, XmlObject> map) {

+        parsedModules.put(moduleName, map);

+    }

+

+    /**

+     * 

+     * @param protocolName

+     * @return

+     */

+    public synchronized static String[] getProtocolInfoGuid(String protocolName) {

+        Set set = spdTable.keySet();

+        Iterator iter = set.iterator();

+        String[] cNameGuid = null;

+

+        while (iter.hasNext()) {

+            Spd spd = (Spd) spdTable.get(iter.next());

+            cNameGuid = spd.getProtocolNameGuidArray(protocolName);

+            if (cNameGuid != null) {

+                break;

+            }

+        }

+        return cNameGuid;

+    }

+

+    public synchronized static String[] getPpiInfoGuid(String ppiName) {

+        Set set = spdTable.keySet();

+        Iterator iter = set.iterator();

+        String[] cNameGuid = null;

+

+        while (iter.hasNext()) {

+            Spd spd = (Spd) spdTable.get(iter.next());

+            cNameGuid = spd.getPpiCnameGuidArray(ppiName);

+

+            if (cNameGuid != null) {

+                break;

+            }

+        }

+        return cNameGuid;

+    }

+

+    /**

+     * 

+     * @param guidName

+     * @return

+     */

+    public synchronized static String[] getGuidInfoGuid(String guidName) {

+        String[] cNameGuid = null;

+        Set set = spdTable.keySet();

+        Iterator iter = set.iterator();

+

+        while (iter.hasNext()) {

+            Spd spd = (Spd) spdTable.get(iter.next());

+            cNameGuid = spd.getGuidNameArray(guidName);

+            if (cNameGuid != null) {

+                break;

+            }

+        }

+        return cNameGuid;

+    }

+

+    public synchronized static String getLibClassIncluder(String libName) {

+        String libIncluder = null;

+        Set set = spdTable.keySet();

+        Iterator iter = set.iterator();

+

+        while (iter.hasNext()) {

+            String packageName = (String) iter.next();

+            Spd spd = (Spd) spdTable.get(packageName);

+            libIncluder = spd.getLibClassIncluder(libName);

+            String packagePath = spd.packagePath;

+            if (packagePath != null) {

+                packagePath = packagePath.replace('\\', File.separatorChar);

+                packagePath = packagePath.replace('/', File.separatorChar);

+            } else {

+                packagePath = packageName;

+            }

+            if (libIncluder != null) {

+                libIncluder = libIncluder.replace('\\', File.separatorChar);

+                libIncluder = libIncluder.replace('/', File.separatorChar);

+                libIncluder = packageName + File.separatorChar + libIncluder;

+                break;

+            }

+        }

+        return libIncluder;

+    }

+

+    public synchronized static String getModuleInfoByPackageName(String packageName, String moduleType) {

+        Spd spd;

+        String includeFile = null;

+        String includeStr = "";

+        String cleanPath = "";

+

+        spd = (Spd) spdTable.get(packageName);

+        includeFile = spd.getModuleTypeIncluder(moduleType);

+        if (includeFile != null) {

+            includeFile = includeFile.replace('\\', File.separatorChar);

+            includeFile = includeFile.replace('/', File.separatorChar);

+            includeStr = CommonDefinition.include + " <" + includeStr;

+            cleanPath = spd.packagePath;

+            cleanPath = cleanPath.replace('\\', File.separatorChar);

+            cleanPath = cleanPath.replace('/', File.separatorChar);

+

+            if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) {

+                cleanPath = cleanPath + File.separatorChar;

+            }

+            includeStr = includeStr + cleanPath;

+            includeStr = includeStr + includeFile;

+            includeStr = includeStr + ">\r\n";

+        }

+

+        return includeStr;

+    }

+

+    public synchronized static void setLibInstanceInfo(String libName, String libConstructor, String libDesturctor) {

+        String[] libConsDes = new String[2];

+        libConsDes[0] = libConstructor;

+        libConsDes[1] = libDesturctor;

+

+        libInstanceInfo.put(libName, libConsDes);

+    }

+

+    public synchronized static boolean isHaveLibInstance(String libName) {

+        return libInstanceInfo.containsKey(libName);

+    }

+

+    public synchronized static String getLibInstanceConstructor(String libName) {

+        String[] libInstanceValue;

+        libInstanceValue = libInstanceInfo.get(libName);

+        if (libInstanceValue != null) {

+            return libInstanceValue[0];

+        } else {

+            return null;

+        }

+    }

+

+    public synchronized static String getLibInstanceDestructor(String libName) {

+        String[] libInstanceValue;

+        libInstanceValue = libInstanceInfo.get(libName);

+        if (libInstanceValue != null) {

+            return libInstanceValue[1];

+        } else {

+            return null;

+        }

+    }

+

+    public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {

+        return pcdDbManager;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
new file mode 100644
index 0000000..5912127
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
@@ -0,0 +1,178 @@
+/*++

+

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ Module Name:

+ ShareObject.java

+

+ Abstract:

+

+ --*/

+package org.tianocore.build.global;

+

+import java.util.*;

+

+import org.apache.tools.ant.*;

+import org.apache.tools.ant.types.DataType;

+

+public class GlobalShare extends DataType implements DynamicConfigurator {

+    private static final HashMap<String, Object> objStorage = new HashMap<String, Object>();

+

+    private DataObjectOp op;

+

+    private String objName;

+

+    private Object objInst;

+

+    private String objClassPackage = "org.tianocore";

+

+    public GlobalShare () {

+

+    }

+

+    public GlobalShare (String objName) {

+        this.objName = objName;

+        this.objInst = objStorage.get(this.objName);

+    }

+

+    public GlobalShare (String objName, Object obj) {

+        this.objName = objName;

+        this.objInst = obj;

+        objStorage.put(this.objName, this.objInst);

+    }

+

+    public Object createDynamicElement(String name) throws BuildException {

+        String className = objClassPackage + "." + name;

+        log("GlobalShare.createDynamicElement(" + name + ")",

+                        Project.MSG_VERBOSE);

+        try {

+            objInst = Class.forName(className).newInstance();

+        } catch (ClassNotFoundException e) {

+            throw new BuildException("class name is not found");

+        } catch (InstantiationException e) {

+            throw new BuildException("the class cannnot be instantiated");

+        } catch (IllegalAccessException e) {

+            throw new BuildException("cannot access the class");

+        }

+

+        return objInst;

+    }

+

+    public void setDynamicAttribute(String name, String value)

+                    throws BuildException {

+        log("name = " + name + " value = " + value, Project.MSG_VERBOSE);

+        throw new BuildException();

+    }

+

+    public void setName(String name) {

+        this.objName = name;

+        if (this.op != null) {

+            issueOperation();

+        }

+    }

+

+    public String getName() {

+        return this.objName;

+    }

+

+    public void setPackage(String name) {

+        log("ShareObject.setPackage(" + name + ")", Project.MSG_VERBOSE);

+        this.objClassPackage = name;

+    }

+

+    public String getPackage() {

+        return this.objClassPackage;

+    }

+

+    public void setOperation(String opName) {

+        log("ShareObject.setOperation(" + opName + ")", Project.MSG_VERBOSE);

+        this.op = DataObjectOp.formString(opName);

+

+        if (this.objName != null) {

+            issueOperation();

+        }

+    }

+

+    public String getOperation() {

+        return this.op.toString();

+    }

+

+    public void issueOperation() {

+        if (this.op == DataObjectOp.ADD) {

+

+            log("ShareObject: adding ... " + this.objName, Project.MSG_VERBOSE);

+            objStorage.put(this.objName, this.objInst);

+

+        } else if (this.op == DataObjectOp.GET) {

+

+            log("ShareObject: fetching ... " + this.objName,

+                            Project.MSG_VERBOSE);

+            objInst = objStorage.get(objName);

+

+        } else if (this.op == DataObjectOp.DEL) {

+

+            log("ShareObject: removing ... " + this.objName,

+                            Project.MSG_VERBOSE);

+            objInst = objStorage.remove(objName);

+

+        } else {

+            throw new BuildException("not supported operation");

+        }

+    }

+

+    public Object get() {

+        return this.objInst;

+    }

+

+    public static int getObjectNum() {

+        return objStorage.size();

+    }

+

+    public static Object add(String objName, Object obj) {

+        return objStorage.put(objName, obj);

+    }

+

+    public static Object retrieve(String objName) {

+        return objStorage.get(objName);

+    }

+

+    public static Object remove(String objName) {

+        return objStorage.remove(objName);

+    }

+

+    public static void empty() {

+        objStorage.clear();

+    }

+}

+

+class DataObjectOp {

+    private static final HashMap<String, DataObjectOp> opMap = new HashMap<String, DataObjectOp>();

+

+    private final String opName;

+

+    private DataObjectOp (String name) {

+        this.opName = name;

+        opMap.put(this.opName, this);

+    }

+

+    public String toString() {

+        return opName;

+    }

+

+    public static DataObjectOp formString(String opName) {

+        return opMap.get(opName);

+    }

+

+    public static final DataObjectOp ADD = new DataObjectOp("ADD");

+

+    public static final DataObjectOp GET = new DataObjectOp("GET");

+

+    public static final DataObjectOp DEL = new DataObjectOp("DEL");

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
new file mode 100644
index 0000000..4d7e870
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
@@ -0,0 +1,412 @@
+/** @file

+  This file is an ANT task.

+  

+  LibBuildFileGenerator task is used to generate module's build.xml file.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.global;

+

+import java.io.File;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.Map;

+import java.util.Set;

+import java.util.Vector;

+

+import javax.xml.parsers.DocumentBuilder;

+import javax.xml.parsers.DocumentBuilderFactory;

+import javax.xml.transform.OutputKeys;

+import javax.xml.transform.Result;

+import javax.xml.transform.Source;

+import javax.xml.transform.Transformer;

+import javax.xml.transform.TransformerFactory;

+import javax.xml.transform.dom.DOMSource;

+import javax.xml.transform.stream.StreamResult;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.MsaHeaderDocument.MsaHeader;

+import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+/**

+  This class <code>LibBuildFileGenerator</code> is an ANT task to generate 

+  build.xml for each module. Here are two usages. 

+  

+  <ul>

+    <li>

+      For one module (<b>bf</b> is LibBuildFileGenerator task name):

+      <pre>

+        &lt;bf buildFile="Application\HelloWorld\HelloWorld.msa" /&gt;

+      </pre>

+    </li>

+    <li>

+      For one package:

+      <pre>

+        &lt;bf recursive="true" /&gt;

+      </pre>

+    </li>

+  </ul>

+  

+  @since GenBuild 1.0

+**/

+public class LibBuildFileGenerator extends Task {

+

+    private File buildFile;

+

+    private boolean recursive = false;

+    

+    private String license = " Copyright (c) 2006, Intel Corporation \n"

+                    + "All rights reserved. This program and the accompanying materials \n"

+                    + "are licensed and made available under the terms and conditions of the BSD License \n"

+                    + "which accompanies this distribution.  The full text of the license may be found at  \n"

+                    + "http://opensource.org/licenses/bsd-license.php \n"

+                    + "\n"

+                    + "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, \n"

+                    + "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.";

+

+    private String base_name;

+    

+    private String module_relative_path;

+    

+    private File base_file = new File(".");

+    

+    /**

+      Public construct method. It is necessary for ANT task.

+    **/

+    public LibBuildFileGenerator () {

+    }

+

+    /**

+      ANT task's entry point, will be called after init(). 

+      

+      @throws BuildException

+              buildFile do not specify while recursive set to false

+    **/

+    public void execute() throws BuildException {

+        if(recursive){

+            searchMsa(new File("."));

+        }

+        else {

+            Map<String,File> map = new HashMap<String,File>();

+            String basename = buildFile.getName();

+            int k = basename.lastIndexOf('.');

+            base_name = basename.substring(0, k);

+            map.put(base_name, buildFile);

+            genBuildFile(map);

+        }

+    }

+    

+    /**

+      Recursivly find all MSA files and record all modules. 

+      

+      @param path Package path

+    **/

+    private void searchMsa(File path){

+        File[] files = path.listFiles();

+        Vector<File> vec = new Vector<File>();

+        for(int i=0; i < files.length; i ++){

+            if (files[i].isFile()){

+                if(files[i].getName().endsWith(".msa")){

+                    System.out.println("#" + files[i].getPath());

+                    vec.add(files[i]);

+                }

+            }

+        }

+        Map<String,File> mapBasename = new HashMap<String,File>();

+        if (vec.size() > 0){

+            base_name = null;

+            for ( int j = 0 ; j < vec.size(); j++){

+                if ( vec.size() > 1){

+                  System.out.println("##" + vec.get(0));

+                }

+                File f = (File)vec.get(j);

+                SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();

+                Map<String, XmlObject> map = surfaceAreaParser.parseFile(f);

+                String baseName = "";

+                XmlObject header = null;

+                if ( (header = map.get("MsaHeader")) != null ){

+                    baseName = ((MsaHeader)header).getBaseName().getStringValue();

+                }

+                else if ( (header = map.get("MsaLibHeader")) != null){

+                    baseName = ((MsaLibHeader)header).getBaseName().getStringValue();

+                } else {

+                    continue ;

+                }

+                if ( base_name == null || base_name.length() > baseName.length()){

+                    base_name = baseName;

+                    buildFile = f;

+                    try {

+                    module_relative_path = buildFile.getParent().substring(base_file.getPath().length() + 1);

+                    }

+                    catch(Exception e){

+                        module_relative_path = ".";

+                    }

+                }

+                mapBasename.put(baseName, f);

+            }

+            genBuildFile(mapBasename);

+        }

+

+        for(int i=0; i < files.length; i ++){

+            if (files[i].isDirectory()){

+                searchMsa(files[i]);

+            }

+        }

+    }

+    

+    /**

+      Generate build.xml.

+      

+      @param map All base name under one module directory

+    **/

+    private void genBuildFile(Map map) {

+        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();

+        try {

+            DocumentBuilder dombuilder = domfac.newDocumentBuilder();

+            Document document = dombuilder.newDocument();

+            //

+            // create root element and its attributes

+            //

+            document.appendChild(document.createComment(license));

+            Element root = document.createElement("project");

+            root.setAttribute("default", base_name);

+            root.setAttribute("basedir", ".");

+            //

+            // element for External ANT tasks

+            //

+            root.appendChild(document.createComment("Apply external ANT tasks"));

+            Element ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "GenBuild.tasks");

+            root.appendChild(ele);

+            //

+            // <taskdef resource="net/sf/antcontrib/antlib.xml" />

+            //

+            ele = document.createElement("taskdef");

+            ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");

+            root.appendChild(ele);

+            

+            ele = document.createElement("property");

+            ele.setAttribute("environment", "env");

+            root.appendChild(ele);

+

+            ele = document.createElement("property");

+            ele.setAttribute("name", "WORKSPACE_DIR");

+            ele.setAttribute("value", "${env.WORKSPACE}");

+            root.appendChild(ele);

+            

+            ele = document.createElement("import");

+            ele.setAttribute("file", "${WORKSPACE_DIR}"+File.separatorChar+"Tools"+File.separatorChar+"Conf"+File.separatorChar+"BuildMacro.xml");

+            root.appendChild(ele);

+            

+            root.appendChild(document.createComment("MODULE_RELATIVE PATH is relative to PACKAGE_DIR"));

+            ele = document.createElement("property");

+            ele.setAttribute("name", "MODULE_RELATIVE_PATH");

+            ele.setAttribute("value", module_relative_path);

+            root.appendChild(ele);

+

+            ele = document.createElement("property");

+            ele.setAttribute("name", "MODULE_DIR");

+            ele.setAttribute("value", "${PACKAGE_DIR}" + File.separatorChar + "${MODULE_RELATIVE_PATH}");

+            root.appendChild(ele);

+

+            ele = document.createElement("property");

+            ele.setAttribute("name", "COMMON_FILE");

+            ele.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar + "Tools"

+                            + File.separatorChar + "Conf" + File.separatorChar + "Common.xml");

+            root.appendChild(ele);

+            

+            //

+            // generate the buildfmd target

+            //

+            Set set = map.keySet();

+            Iterator iter = set.iterator();

+            while (iter.hasNext()){

+                String bName = (String)iter.next();

+                File msaFile = (File)map.get(bName);

+                String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();

+                String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";

+                ele = document.createElement("target");

+                ele.setAttribute("name", bName);

+                Element target = document.createElement("GenBuild");

+                target.setAttribute("msaFilename", msaFilename);

+                target.setAttribute("mbdFilename", mbdFilename);

+                target.setAttribute("baseName", bName);

+                ele.appendChild(target);

+                root.appendChild(ele);

+            }

+

+            root.appendChild(ele);

+            //

+            // Default clean

+            //

+            ele = document.createElement("target");

+            ele.setAttribute("name", "clean");

+            ele.setAttribute("depends", base_name + "_clean");

+            root.appendChild(ele);

+            //

+            // Default Clean ALl

+            //

+            ele = document.createElement("target");

+            ele.setAttribute("name", "cleanall");

+            ele.setAttribute("depends", base_name + "_cleanall");

+            root.appendChild(ele);

+            //

+            // Every clean target for each BaseName

+            //

+            set = map.keySet();

+            iter = set.iterator();

+            while (iter.hasNext()){

+                String bName = (String)iter.next();

+                File msaFile = (File)map.get(bName);

+                String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();

+                String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";

+                

+                ele = document.createElement("target");

+                ele.setAttribute("name", bName + "_clean");

+                //

+                // Output Dir

+                //

+                Element target = document.createElement("OutputDirSetup");

+                target.setAttribute("msaFilename", msaFilename);

+                target.setAttribute("mbdFilename", mbdFilename);

+                target.setAttribute("baseName", bName);

+                ele.appendChild(target);

+                //

+                // Call BaseName_build.xml clean

+                //

+                Element ifEle = document.createElement("if");

+                Element availableEle = document.createElement("available");

+                availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");

+                ifEle.appendChild(availableEle);

+                Element elseEle = document.createElement("then");

+                

+                Element moduleEle = document.createElement("ant");

+                moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");

+                moduleEle.setAttribute("target", "clean");

+                

+                elseEle.appendChild(moduleEle);

+                ifEle.appendChild(elseEle);

+                ele.appendChild(ifEle);

+                //

+                // just delete

+                //

+                Element clean = document.createElement("delete");

+                clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");

+                clean.setAttribute("excludes", "*.xml");

+                ele.appendChild(clean);

+                

+                root.appendChild(ele);

+            }

+            //

+            // Every Clean ALl target for each BaseName

+            //

+            set = map.keySet();

+            iter = set.iterator();

+            while (iter.hasNext()){

+                String bName = (String)iter.next();

+                File msaFile = (File)map.get(bName);

+                String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();

+                String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";

+                

+                ele = document.createElement("target");

+                ele.setAttribute("name", bName + "_cleanall");

+                //

+                // Output Dir

+                //

+                Element target = document.createElement("OutputDirSetup");

+                target.setAttribute("msaFilename", msaFilename);

+                target.setAttribute("mbdFilename", mbdFilename);

+                target.setAttribute("baseName", bName);

+                ele.appendChild(target);

+                //

+                // Call BaseName_build.xml clean

+                //

+                Element ifEle = document.createElement("if");

+                Element availableEle = document.createElement("available");

+                availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");

+                ifEle.appendChild(availableEle);

+                Element elseEle = document.createElement("then");

+                

+                Element moduleEle = document.createElement("ant");

+                moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");

+                moduleEle.setAttribute("target", "cleanall");

+                

+                elseEle.appendChild(moduleEle);

+                ifEle.appendChild(elseEle);

+                ele.appendChild(ifEle);

+                //

+                // just delete

+                //

+                Element clean = document.createElement("delete");

+                clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");

+                ele.appendChild(clean);

+                

+                clean = document.createElement("delete");

+                clean.setAttribute("dir", "${DEST_DIR_DEBUG}");

+                ele.appendChild(clean);

+                

+                clean = document.createElement("delete");

+                Element fileset = document.createElement("fileset");

+                fileset.setAttribute("dir", "${BIN_DIR}");

+                fileset.setAttribute("includes", "**" + bName + "*");

+                clean.appendChild(fileset);

+                ele.appendChild(clean);

+                

+                root.appendChild(ele);

+            }

+            document.appendChild(root);

+            //

+            // Prepare the DOM document for writing

+            //

+            Source source = new DOMSource(document);

+            //

+            // Prepare the output file

+            //

+            String filename = buildFile.getParent() + File.separatorChar + "build.xml";

+            File file = new File(getProject().replaceProperties(filename));

+            //

+            // generate all directory path

+            //

+            Result result = new StreamResult(file);

+            //

+            // Write the DOM document to the file

+            //

+            Transformer xformer = TransformerFactory.newInstance()

+                            .newTransformer();

+            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

+            xformer.setOutputProperty(OutputKeys.INDENT, "yes");

+            xformer.transform(source, result);

+        } catch (Exception ex) {

+            System.out.println("##" + ex);

+        }

+    }

+    

+    

+    public File getBuildFile() {

+        return buildFile;

+    }

+

+    public void setBuildFile(File buildFile) {

+        this.buildFile = buildFile;

+    }

+

+    public boolean isRecursive() {

+        return recursive;

+    }

+

+    public void setRecursive(boolean recursive) {

+        this.recursive = recursive;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
new file mode 100644
index 0000000..74311d4
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
@@ -0,0 +1,55 @@
+package org.tianocore.build.global;

+

+public class ModuleIdentification {

+

+    private String baseName;

+    

+    private String packageName;

+    

+    private String guid;

+    

+    private String version;

+    

+    public ModuleIdentification(String baseName, String packageName, String guid, String version){

+        this.baseName = baseName;

+        this.packageName = packageName;

+        this.guid = guid;

+        this.version = version;

+    }

+    

+    public boolean equals(Object obj) {

+        if (obj instanceof ModuleIdentification) {

+            ModuleIdentification moduleIdObj = (ModuleIdentification)obj;

+            if ( baseName.equalsIgnoreCase(moduleIdObj.baseName)) {

+                return true;

+            }

+            // TBD

+            return false;

+        }

+        else {

+            return super.equals(obj);

+        }

+    }

+    

+    public String toString(){

+        return packageName + ":" + guid + "_" + baseName + "_" + version;

+    }

+

+    public void setBaseName(String baseName) {

+        this.baseName = baseName;

+    }

+

+    public void setGuid(String guid) {

+        this.guid = guid;

+    }

+

+    public void setPackageName(String packageName) {

+        this.packageName = packageName;

+    }

+

+    public void setVersion(String version) {

+        this.version = version;

+    }

+    

+    

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java
new file mode 100644
index 0000000..936dac8
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java
@@ -0,0 +1,121 @@
+/** @file

+This file is to define OnDependency class.

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+--*/

+package org.tianocore.build.global;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.taskdefs.Sequential;

+

+import java.io.File;

+import java.util.Iterator;

+

+/**

+ Class OnDepdendency is used to check the timestamp between source files and

+ target files, which can be used to determine if the target files are needed to

+ be re-generated from source files.

+ **/

+public class OnDependency extends Task {

+    ///

+    /// source files list

+    ///

+    private DpFileList sources = null;

+    ///

+    /// target files list

+    ///

+    private DpFileList targets = null;

+    ///

+    /// tasks to be performed to generate target files

+    ///

+    private Sequential  task = null;

+

+    ///

+    /// An empty constructor for an ANT task can avoid some potential issues

+    ///

+    public OnDependency(){

+    }

+

+    /**

+     Standard execute method of ANT task

+     **/

+    public void execute() {

+        if (isOutOfDate() && task != null) {

+            task.perform();

+        }

+    }

+

+    ///

+    /// check if the target files are outofdate

+    ///

+    private boolean isOutOfDate() {

+        ///

+        /// if no source files specified, take it as a fresh start

+        ///

+        if (sources.nameList.size() == 0) {

+            return true;

+        }

+

+        Iterator dstIt = targets.nameList.iterator();

+        while (dstIt.hasNext()) {

+            String dstFileName = (String)dstIt.next();

+            File dstFile = new File(dstFileName);

+            if (!dstFile.exists()) {

+                return true;

+            }

+

+            long dstTimeStamp = dstFile.lastModified();

+            Iterator srcIt = sources.nameList.iterator();

+            while (srcIt.hasNext()) {

+                String srcFileName = (String)srcIt.next();

+                File srcFile = new File(srcFileName);

+                if (!srcFile.exists()) {

+                    throw new BuildException(srcFileName + " doesn't exist !!!");

+                }

+

+                if (dstTimeStamp < srcFile.lastModified()) {

+                    return true;

+                }

+            }

+        }

+

+        return false;

+    }

+

+    /**

+     Add method of ANT task for nested element with Sequential type

+

+     @param     task    Sequential object which contains tasks for generating target files

+     **/

+    public void addSequential(Sequential task) {

+        this.task = task;

+    }

+

+    /**

+     Add method of ANT task for nested element with DpFileList type

+

+     @param     sources DpFileList object which contains the list of source files

+     **/

+    public void addSourcefiles(DpFileList sources) {

+        this.sources = sources;

+    }

+

+    /**

+     Add method of ANT task for nested element with DpFileList type

+

+     @param     targets DpFileList object which contains the list of target files

+     **/

+    public void addTargetfiles(DpFileList targets) {

+        this.targets = targets;

+    }

+}

+

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
new file mode 100644
index 0000000..01e24e6
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
@@ -0,0 +1,176 @@
+/** @file

+  OutputManager class.

+  

+  OutputManager class set output directories for every module by BUILD_MODE.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build.global;

+

+import org.apache.tools.ant.Project;

+import java.io.File;

+

+/**

+  OutputManager class is used to setup output directories (BIN_DIR, DEST_DIR_OUTPUT, 

+  DEST_DIR_DEBUG) according to BUILD_MODE. 

+  

+  @since GenBuild 1.0

+**/

+public class OutputManager {

+    

+    ///

+    /// Single Module build

+    ///

+    public static final String MODULE_BUILD = "MODULE";

+

+    ///

+    /// Package build

+    ///

+    public static final String PACKAGE_BUILD = "PACKAGE";

+

+    ///

+    /// Platform build

+    ///

+    public static final String PLATFORM_BUILD = "PLATFORM";

+    

+    public static String buildMode = MODULE_BUILD;

+    

+    ///

+    /// For Package build, PLATFORM represent PACKAGE

+    ///

+    public static String PLATFORM;

+    

+    ///

+    /// For Platform build, PLATFORM_DIR represent PACKAGE_DIR

+    ///

+    public static String PLATFORM_DIR;

+    

+    ///

+    /// means intermediate files will put under Module's dir

+    ///

+    public static final String MODULE = "MODULE";

+    

+    ///

+    /// mean intermediate files will put under a unify dir

+    ///

+    public static final String UNIFIED = "UNIFIED";

+    

+    ///

+    /// Flag to ensure the function <code>update</code> will be called only one in the whole build.

+    ///

+    private static boolean flag = true;

+    

+    /**

+      If BUILD_MODE is PLATFORM or PACKAGE, record PLATFORM and PLARFORM_DIR.

+      Reminder that for PACKAGE build, here set value PACKAGE to PLATFORM and

+      PACKAGE_DIR to PLARFORM_DIR, and also update the ant properties. 

+      

+      <p>Note that this function will be called only once in the whole build.</p> 

+      

+      @param project current ANT build Project

+    **/

+    public synchronized static void update(Project project) {

+        if (flag){

+            flag = false;

+            String str = project.getProperty("BUILD_MODE");

+            if (str != null){

+                if (str.equals(PLATFORM_BUILD)) {

+                    buildMode = PLATFORM_BUILD;

+                    PLATFORM = project.getProperty("PLATFORM");

+                    PLATFORM_DIR = project.getProperty("PLATFORM_DIR");

+                }

+                else if (str.equals(PACKAGE_BUILD)) {

+                    buildMode = PACKAGE_BUILD;

+                    PLATFORM = project.getProperty("PACKAGE");

+                    PLATFORM_DIR = project.getProperty("PACKAGE_DIR");

+                    project.setProperty("PLATFORM", PLATFORM);

+                    project.setProperty("PLATFORM_DIR", PLATFORM_DIR);

+                }

+            }

+        }

+    }

+    

+    /**

+      Setup BIN_DIR, DEST_DIR_OUTPUT and DEST_DIR_OUTPUT, following are the rules:

+      

+      <pre>

+        Those three variables are defined as following

+        DEST_DIR_OUTPUT (intermediate files)

+        DEST_DIR_DEBUG (intermediate debug files)

+        BIN_DIR (final files)

+        

+        Output Dir (MODULE or UNIFIED):

+        For <b>Module</b> build: 

+        All intermediate files are at ${MODULE_DIR}/Build/${TARGET}/${ARCH}/DEBUG|OUTPUT

+        All final files are at ${MODULE_DIR}/Build/${TARGET}/${ARCH}

+        

+        For <b>Platform</b> build:

+        If specified with MODULE

+        Intermediate files->${MODULE_DIR}/Build/${PLATFORM}/${TARGET}/${ARCH}/DEBUG|OUTPUT

+        Final files -> ${PLARFORM_DIR}/Build/${TARGET}/${ARCH}

+        

+        Else if specified with UNIFIED

+        Intermediate files->${PLARFORM_DIR}/Build/${TARGET}/${ARCH}/${PACKAGE}/${SOURCE_RELATIVE_PATH}/DEBUG|OUTPUT

+        Final files -> ${PLARFORM_DIR}/Build/${TARGET}/${ARCH}

+        

+        For <b>Package</b> build:

+        If specified with MODULE

+        Intermediate files->${MODULE_DIR}/Build/${PACKAGE}/${TARGET}/${ARCH}/DEBUG|OUTPUT

+        Final files -> ${PACKAGE_DIR}/Build/${TARGET}/${ARCH}

+        

+        Else if specified with UNIFIED

+        Intermediate files->${PACKAGE_DIR}/Build/${TARGET}/${ARCH}/${PACKAGE}/${SOURCE_RELATIVE_PATH}/DEBUG|OUTPUT

+        Final files -> ${PACKAGE_DIR}/Build/${TARGET}/${ARCH}

+      </pre>

+      

+      @param project current ANT build Project

+      @param userdir user-defined directory

+      @param type the module build type (MODULE or UNIFIED)

+    **/

+    public synchronized static void update(Project project, String userdir, String type) {

+        //

+        // userdir TBD

+        //

+       if(  type == null || ! type.equals(MODULE)){

+           type = UNIFIED;

+       }

+       if (buildMode.equals(MODULE_BUILD)){

+           project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}"

+                        + File.separatorChar + "Build" + File.separatorChar + "${TARGET}"

+                        + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));

+           project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));

+           project.setProperty("BIN_DIR", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));

+       }

+       else if (buildMode.equals(PLATFORM_BUILD)) {

+           if (type.equals(MODULE)) {

+               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));

+               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));

+               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));

+           }

+           else if (type.equals(UNIFIED)){

+               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "OUTPUT"));

+               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "DEBUG"));

+               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));

+           }

+       }

+       else if (buildMode.equals(PACKAGE_BUILD)) {

+           if (type.equals(MODULE)) {

+               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));

+               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));

+               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));

+           }

+           else if (type.equals(UNIFIED)){

+               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "OUTPUT"));

+               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "DEBUG"));

+               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));

+           }

+       }

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
new file mode 100644
index 0000000..dae2ca2
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
@@ -0,0 +1,354 @@
+/** @file

+  OverrideProcess class.

+  

+  OverrideProcess class is used to override surface area information. 

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.global;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import javax.xml.namespace.QName;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.xmlbeans.XmlCursor;

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.BootModesDocument;

+import org.tianocore.BuildOptionsDocument;

+import org.tianocore.DataHubsDocument;

+import org.tianocore.EventsDocument;

+import org.tianocore.ExternsDocument;

+import org.tianocore.FormsetsDocument;

+import org.tianocore.GuidsDocument;

+import org.tianocore.HobsDocument;

+import org.tianocore.IncludesDocument;

+import org.tianocore.LibrariesDocument;

+import org.tianocore.LibraryClassDefinitionsDocument;

+import org.tianocore.MsaHeaderDocument;

+import org.tianocore.MsaLibHeaderDocument;

+import org.tianocore.PCDsDocument;

+import org.tianocore.PPIsDocument;

+import org.tianocore.ProtocolsDocument;

+import org.tianocore.SourceFilesDocument;

+import org.tianocore.SystemTablesDocument;

+import org.tianocore.VariablesDocument;

+

+/**

+  This class is used to override surface area information. For example, MBD can

+  overried MSA, Platform can override all information of the module. 

+  

+  <p>Override will take effect if two element satisfy one of following two condition: </p>

+  <ul>

+    <li>Element name and its attribute OverrideID equal each other. </li>

+    <li>Element is defined as exclusive which mean such element can be

+    only appeared in the surface area. </li>

+  </ul>

+  

+  <p>For example, here OutputDirectory element is exclusive: </p>

+  

+  <pre>

+  Low priority Xml Document fragment:

+     &lt;Libraries&gt;

+       &lt;Arch ArchType="IA32"&gt;

+         &lt;Library OverrideID="8888"&gt;EdkPeCoffLoaderLib&lt;/Library&gt;

+         &lt;Library OverrideID="8888"&gt;BasePeCoffLib&lt;/Library&gt;

+       &lt;/Arch&gt;

+     &lt;/Libraries&gt; 

+     &lt;BuildOptions&gt;

+       &lt;OutputDirectory IntermediateDirectories="MODULE"/&gt;

+       &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;

+     &lt;BuildOptions&gt;

+ 

+  High priority Xml Document fragment:

+     &lt;Libraries&gt;

+       &lt;Arch ArchType="IA32"&gt;

+         &lt;Library OverrideID="8888">Nt32PeCoffLoaderLib&lt;/Library&gt;

+       &lt;/Arch&gt;

+     &lt;/Libraries&gt;

+     &lt;BuildOptions&gt;

+       &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;

+       &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;

+     &lt;BuildOptions&gt;

+     

+   The result is: 

+     &lt;Libraries&gt;

+       &lt;Arch ArchType="IA32"&gt;

+         &lt;Library OverrideID="8888"&gt;Nt32PeCoffLoaderLib&lt;/Library&gt;

+       &lt;/Arch&gt;

+     &lt;/Libraries&gt;

+     &lt;BuildOptions&gt;

+       &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;

+       &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;

+       &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;

+     &lt;BuildOptions&gt;

+   

+  </pre>

+  

+  <p>Note that using XmlBeans to walk through the whole XML document tree.</p> 

+  

+  @since GenBuild 1.0

+  @see org.apache.xmlbeans.XmlBeans

+**/

+public class OverrideProcess {

+

+    ///

+    /// URI, the namespace of current XML schema

+    ///

+    public static String prefix = "http://www.TianoCore.org/2006/Edk2.0";

+

+    ///

+    /// list of top elements of surface area

+    ///

+    public static String[] topElements = { "LibraryClassDefinitions",

+                    "SourceFiles", "Includes", "Libraries", "Protocols",

+                    "Events", "Hobs", "PPIs", "Variables", "BootModes",

+                    "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",

+                    "PCDs", "BuildOptions" };

+

+    ///

+    /// list of exclusive elements

+    ///

+    public static String[] exclusiveElements = {"OutputDirectory"};

+    

+    /**

+      Recursively find out all elements specified with OverrideId attribute

+      and exclusive elements in current XML object. 

+      

+      @param o curent parsing XML object

+      @param map Map to list elements specified OverrideID attribute

+      @param execlusiveMap Map to list exclusive elements appeared in current XMl object

+      @param level the depth in XML document tree

+    **/

+    private void listOverrideID(XmlObject o, Map<String,Object> map, Map<String,Object> execlusiveMap, int level) {

+        XmlCursor cursor = o.newCursor();

+        String name = cursor.getName().getLocalPart();

+        for (int i = 0 ; i < exclusiveElements.length; i++){

+            if (name.equalsIgnoreCase(exclusiveElements[i])){

+                execlusiveMap.put(exclusiveElements[i], cursor.getObject());

+            }

+        }

+        String overrideID = cursor.getAttributeText(new QName("OverrideID"));

+        if (overrideID != null) {

+            map.put(name + ":" + overrideID, cursor.getObject());

+        }

+        if (cursor.toFirstChild()) {

+            do {

+                listOverrideID(cursor.getObject(), map, execlusiveMap, level + 1);

+            } while (cursor.toNextSibling());

+        }

+    }

+

+    /**

+      This function is used to prepare for overriding with changing data. 

+      

+      @param map original surface area information 

+      @return after normalize surface area information

+    **/

+    public synchronized static Map<String, XmlObject> deal(Map<String, XmlObject> map) {

+        Map<String, XmlObject> newMap = new HashMap<String, XmlObject>();

+        if (map.get("MsaHeader") != null) {

+            newMap.put("MsaHeader", ((MsaHeaderDocument) map.get("MsaHeader"))

+                            .getMsaHeader());

+        }

+        if (map.get("MsaLibHeader") != null) {

+            newMap.put("MsaLibHeader", ((MsaLibHeaderDocument) map

+                            .get("MsaLibHeader")).getMsaLibHeader());

+        }

+        if (map.get("LibraryClassDefinitions") != null) {

+            newMap.put("LibraryClassDefinitions",

+                            ((LibraryClassDefinitionsDocument) map

+                                            .get("LibraryClassDefinitions"))

+                                            .getLibraryClassDefinitions());

+        }

+        if (map.get("SourceFiles") != null) {

+            newMap.put("SourceFiles", ((SourceFilesDocument) map

+                            .get("SourceFiles")).getSourceFiles());

+        }

+        if (map.get("Includes") != null) {

+            newMap.put("Includes", ((IncludesDocument) map.get("Includes"))

+                            .getIncludes());

+        }

+        if (map.get("Libraries") != null) {

+            newMap.put("Libraries", ((LibrariesDocument) map.get("Libraries"))

+                            .getLibraries());

+        }

+        if (map.get("Protocols") != null) {

+            newMap.put("Protocols", ((ProtocolsDocument) map.get("Protocols"))

+                            .getProtocols());

+        }

+        if (map.get("Events") != null) {

+            newMap.put("Events", ((EventsDocument) map.get("Events"))

+                            .getEvents());

+        }

+        if (map.get("Hobs") != null) {

+            newMap.put("Hobs", ((HobsDocument) map.get("Hobs")).getHobs());

+        }

+        if (map.get("PPIs") != null) {

+            newMap.put("PPIs", ((PPIsDocument) map.get("PPIs")).getPPIs());

+        }

+        if (map.get("Variables") != null) {

+            newMap.put("Variables", ((VariablesDocument) map.get("Variables"))

+                            .getVariables());

+        }

+        if (map.get("BootModes") != null) {

+            newMap.put("BootModes", ((BootModesDocument) map.get("BootModes"))

+                            .getBootModes());

+        }

+        if (map.get("SystemTables") != null) {

+            newMap.put("SystemTables", ((SystemTablesDocument) map

+                            .get("SystemTables")).getSystemTables());

+        }

+        if (map.get("DataHubs") != null) {

+            newMap.put("DataHubs", ((DataHubsDocument) map.get("DataHubs"))

+                            .getDataHubs());

+        }

+        if (map.get("Formsets") != null) {

+            newMap.put("Formsets", ((FormsetsDocument) map.get("Formsets"))

+                            .getFormsets());

+        }

+        if (map.get("Guids") != null) {

+            newMap.put("Guids", ((GuidsDocument) map.get("Guids")).getGuids());

+        }

+        if (map.get("Externs") != null) {

+            newMap.put("Externs", ((ExternsDocument) map.get("Externs"))

+                            .getExterns());

+        }

+        if (map.get("PCDs") != null) {

+            newMap.put("PCDs", ((PCDsDocument) map.get("PCDs")).getPCDs());

+        }

+        if (map.get("BuildOptions") != null) {

+            newMap.put("BuildOptions", ((BuildOptionsDocument) map

+                            .get("BuildOptions")).getBuildOptions());

+        }

+        return newMap;

+    }

+

+    /**

+      Recursively remove all subelement in Xml Object l (with low priority) 

+      based on OverrideID or exclusive elements. 

+    

+      @param l the XML object to process

+      @param map list of elements with OverrideID in high priority XML object

+      @param execusiveMap  list of exclusive elements in high priority XML object

+    **/

+    private void cut(XmlCursor l, Map map, Map execusiveMap) {

+        String name = l.getName().getLocalPart();

+        if (execusiveMap.containsKey(name)){

+            l.removeXml();

+            return;

+        }

+        String overrideID = l.getAttributeText(new QName("OverrideID"));

+        if (overrideID != null) {

+            if (map.containsKey(name + ":" + overrideID)) {

+                l.removeXml();

+                return;

+            }

+        }

+        if (l.toFirstChild()) {

+            do {

+                cut(l, map, execusiveMap);

+            } while (l.toNextSibling());

+        }

+    }

+

+    private XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {

+        XmlObject result = null;

+        try {

+            result = XmlObject.Factory.parse(object.getDomNode()

+                            .cloneNode(deep));

+        } catch (Exception ex) {

+            throw new BuildException(ex.getMessage());

+        }

+        return result;

+    }

+

+    /**

+      Process every item list in h and l.

+    

+      @param h surface area info with high priority

+      @param l surface area info with low priority

+      @return surface area after override

+    **/

+    public Map<String, XmlObject> override(Map<String, XmlObject> h,

+                    Map<String, XmlObject> l) {

+        Map<String, XmlObject> result = new HashMap<String, XmlObject>();

+        result.put("MsaHeader", override(l.get("MsaHeader"), null));

+        result.put("MsaLibHeader", override(l.get("MsaLibHeader"), null));

+        for (int i = 0; i < topElements.length; i++) {

+            result.put(topElements[i], override(h.get(topElements[i]), l

+                            .get(topElements[i])));

+        }

+        return result;

+    }

+

+    /**

+      Recursively override two Xml Objects.

+      

+      @param h Xml Object info with high priority

+      @param l Xml Object info with low priority

+      @return Xml Object after area

+    **/

+    public XmlObject override(XmlObject h, XmlObject l) {

+        if (l == null && h == null) {

+            return null;

+        }

+        if (h == null) {

+            return cloneXmlObject(l, true);

+        }

+        if (l == null) {

+            return cloneXmlObject(h, true);

+        }

+        XmlCursor hc = h.newCursor();

+        if (h.getClass() != l.getClass()) {

+            System.out

+                            .println("Error: Two XmlObject does not with compliant format.");

+            return null;

+        }

+        if (!hc.toFirstChild()) {

+            return cloneXmlObject(l, true);

+        }

+

+        XmlCursor result = cloneXmlObject(h, true).newCursor();

+        XmlCursor lcursor = cloneXmlObject(l, true).newCursor();

+        result.push();

+        result.toNextToken();

+        result.insertNamespace("", prefix);

+        result.toFirstChild();

+        //

+        // found out all element specified a OverrideID

+        //

+        Map<String,Object> hmap = new HashMap<String,Object>();

+        Map<String,Object> execlusiveMap = new HashMap<String,Object>();

+        listOverrideID(h, hmap, execlusiveMap, 0);

+        lcursor.toNextToken();

+        lcursor.push();

+        //

+        // for every direct subelement of l, cut all element satisfied with

+        // override rule

+        //

+        if (lcursor.toFirstChild()) {

+            do {

+                cut(lcursor, hmap, execlusiveMap);

+            } while (lcursor.toNextSibling());

+        }

+        lcursor.pop();

+        if (lcursor.toFirstChild()) {

+            do {

+                lcursor.copyXml(result);

+                result.insertChars("\n");

+            } while (lcursor.toNextSibling());

+        }

+        result.pop();

+        return result.getObject();

+    }

+}
\ No newline at end of file
diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
new file mode 100644
index 0000000..54c1391
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
@@ -0,0 +1,414 @@
+/** @file

+ Spd class.

+

+ This class is to generate a global table for the content of spd file.

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.build.global;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.tianocore.PackageSurfaceAreaDocument;

+import org.tianocore.GuidDeclarationsDocument.GuidDeclarations;

+import org.tianocore.IncludeHeaderDocument.IncludeHeader;

+import org.tianocore.LibraryClassDeclarationDocument.LibraryClassDeclaration;

+import org.tianocore.LibraryClassDeclarationsDocument.LibraryClassDeclarations;

+import org.tianocore.PackageHeadersDocument.PackageHeaders;

+import org.tianocore.PackageSurfaceAreaDocument.PackageSurfaceArea;

+import org.tianocore.PpiDeclarationsDocument.PpiDeclarations;

+import org.tianocore.ProtocolDeclarationsDocument.ProtocolDeclarations;

+

+/**

+ 

+  This class is to generate a global table for the content of spd file.

+  

+**/

+public class Spd {

+    ///

+    /// Map of module name and package it belongs to.

+    /// Key : Module BaseName

+    /// Value: Relative Path to Package

+    ///

+    Map<String, String[]> msaInfo = new HashMap<String, String[]>();

+

+    ///

+    /// Map of module info. 

+    /// Key : moduletype

+    /// Value: moduletype related include file

+    ///

+    Map<String, String> moduleInfo = new HashMap<String, String>();

+

+    ///

+    /// Map of PPI info.

+    /// Key : PPI name

+    /// value: String[] a. PPI C_NAME; b. PPI GUID;

+    ///

+    Map<String, String[]> ppiInfo = new HashMap<String, String[]>();

+

+    ///

+    /// Map of Protocol info.

+    /// Key : Protocol name

+    /// value: String[] a. Protocol C_NAME; b. Protocol GUID;

+    ///

+    Map<String, String[]> protocolInfo = new HashMap<String, String[]>();

+

+    ///

+    /// Map of Guid info.

+    /// Key : Guid name

+    /// value: String[] a. Guid C_NAME; b. Guid's GUID;

+    ///

+    Map<String, String[]> guidInfo = new HashMap<String, String[]>();

+

+

+    ///

+    /// Map of library class and its exposed header file.

+    /// Key : library class name

+    /// value : library class corresponding header file

+    ///

+    Map<String, String> libClassHeaderList = new HashMap<String, String>();

+

+    ///

+    /// Package path.

+    ///

+    String packagePath = null;

+

+    /**

+      Constructor function

+      

+      This function mainly initialize some member variables. 

+   

+      @param spdDoc      Handle of spd document.

+      @param spdPath     Path of spd file.

+     **/

+    Spd (PackageSurfaceAreaDocument spdDoc, String spdPath) {

+

+        PackageSurfaceArea spd = spdDoc.getPackageSurfaceArea();

+        this.packagePath = spdPath;

+

+        GuidDeclarations spdGuidInfo = spd.getGuidDeclarations();

+        genGuidInfoList(spdGuidInfo);

+

+        PpiDeclarations spdPpiInfo = spd.getPpiDeclarations();

+        genPpiInfoList(spdPpiInfo);

+

+        ProtocolDeclarations spdProtocolInfo = spd.getProtocolDeclarations();

+        genProtocolInfoList(spdProtocolInfo);

+

+        LibraryClassDeclarations spdLibClassDeclare = spd

+                        .getLibraryClassDeclarations();

+        genLibClassDeclare(spdLibClassDeclare);

+

+        PackageHeaders spdPackageHeaderInfo = spd.getPackageHeaders();

+        genModuleInfoList(spdPackageHeaderInfo);

+

+    }

+

+    /**

+      genModuleInfoList

+      

+      This function is to generate Module info map.

+      

+      @param packageHeader   The information of packageHeader which descripted

+                             in spd file.    

+    **/

+    public void genModuleInfoList(PackageHeaders packageHeader) {

+

+        if (packageHeader != null) {

+            List<IncludeHeader> headerList = packageHeader.getIncludeHeaderList();

+            for (int i = 0; i < headerList.size(); i++) {

+                try {

+                    this.moduleInfo

+                                    .put(headerList.get(i).getModuleType()

+                                                    .toString(), headerList.get(i)

+                                                    .getStringValue());

+                } catch (Exception e) {

+                    System.out

+                                    .print("can't find ModuleHeaders ModuleType & includeHeader!\n");

+                }

+            }

+        }

+    }

+

+  /**

+    genPpiInfoList

+    

+    This function is to generate Ppi info map.

+    

+    @param  ppiInfo           The information of PpiDeclarations which descripted

+                              in spd file.    

+  **/

+    public void genPpiInfoList(PpiDeclarations ppiInfo) {

+        String[] cNameGuid = new String[2];

+

+        if (ppiInfo != null) {

+            List<PpiDeclarations.Entry> ppiEntryList = ppiInfo.getEntryList();

+            for (int i = 0; i < ppiEntryList.size(); i++) {

+                try {

+                    cNameGuid[0] = ppiEntryList.get(i).getCName();

+                    cNameGuid[1] = formatGuidName(ppiEntryList.get(i)

+                                    .getGuid().getStringValue());

+                    this.ppiInfo.put(ppiEntryList.get(i).getName(), new String[] {

+                                    cNameGuid[0], cNameGuid[1] });

+                } catch (Exception e) {

+                    System.out

+                                    .print("can't find GuidDeclarations C_Name & Guid!\n");

+                }

+            }

+        }

+    }

+

+    /**

+      genProtocolInfoList 

+      

+      This function is to generate Protocol info map.

+      

+      @param   proInfo    The information of ProtocolDeclarations which 

+                          descripted in spd file.

+    **/

+    public void genProtocolInfoList(ProtocolDeclarations proInfo) {

+        String[] cNameGuid = new String[2];

+        if (proInfo != null) {

+            List<ProtocolDeclarations.Entry> protocolEntryList = proInfo.getEntryList();

+            for (int i = 0; i < protocolEntryList.size(); i++) {

+                try {

+                    cNameGuid[0] = protocolEntryList.get(i).getCName();

+                    cNameGuid[1] = formatGuidName(protocolEntryList.get(i)

+                                    .getGuid().getStringValue());

+

+                    String temp = new String(protocolEntryList.get(i).getName());

+                    this.protocolInfo.put(temp, new String[] { cNameGuid[0],

+                                    cNameGuid[1] });

+                } catch (Exception e) {

+                    System.out

+                                    .print("can't find ProtocolDeclarations C_Name & Guid!\n");

+                }

+            }

+        }

+    }

+

+    /**

+      genGuidInfoList

+      

+      This function is to generate GUID inf map.

+      

+      @param guidInfo     The information of GuidDeclarations which descripted

+                          in spd file.

+      

+    **/

+    public void genGuidInfoList(GuidDeclarations guidInfo) {

+        String[] cNameGuid = new String[2];

+        if (guidInfo != null) {

+            

+            List<GuidDeclarations.Entry> guidEntryList = guidInfo.getEntryList();

+            for (int i = 0; i < guidEntryList.size(); i++) {

+                cNameGuid[0] = guidEntryList.get(i).getCName();

+                cNameGuid[1] = formatGuidName(guidEntryList.get(i)

+                                .getGuid().getStringValue());

+                this.guidInfo.put(guidEntryList.get(i).getName(), new String[] {

+                                cNameGuid[0], cNameGuid[1] });

+            }

+        }

+    }

+

+    /**

+      genLibClassDeclare

+      

+      This function is to generate the libClassHeader list.

+      

+      @param libClassDeclares  The information of LibraryClassDeclarations which

+                               descripted in spd file.

+    **/

+    public void genLibClassDeclare(LibraryClassDeclarations libClassDeclares) {

+        if (libClassDeclares != null && libClassDeclares.getLibraryClassDeclarationList() != null) {

+            if (libClassDeclares.getLibraryClassDeclarationList().size() > 0) {

+                List<LibraryClassDeclaration> libDeclareList = libClassDeclares.getLibraryClassDeclarationList();

+                for (int i = 0; i < libDeclareList.size(); i++) {

+                    libClassHeaderList.put(libDeclareList.get(i).getLibraryClass()

+                                    .getStringValue(), libDeclareList.get(i)

+                                    .getIncludeHeader().getStringValue());

+                }

+            }

+        }

+    }

+

+    /**

+      getPpiGuid

+      

+      This function is to get ppi GUID according ppi name.

+    

+      @param   ppiStr    Name of ppi.

+      @return            PPi's GUID.

+    **/

+    public String getPpiGuid(String ppiStr) {

+        if (ppiInfo.get(ppiStr) != null) {

+            return ppiInfo.get(ppiStr)[1];

+        } else {

+            return null;

+        }

+

+    }

+

+    /**

+      getPpiCnameGuidArray

+      

+      This function is to get the ppi CName and it's GUID according to ppi name.

+      

+      @param   ppiName      Name of ppi.

+      @return               Ppi CName and it's GUID.

+    **/

+    public String[] getPpiCnameGuidArray(String ppiName) {

+        return this.ppiInfo.get(ppiName);

+    }

+

+    /**

+      getProtocolGuid

+      

+      This function is to get the protocol GUID according to protocol's name.

+      

+      @param   protocolStr    Name of protocol.

+      @return                 Protocol's GUID.

+    **/

+    public String getProtocolGuid(String protocolStr) {

+        if (protocolInfo.get(protocolStr) != null) {

+            return this.protocolInfo.get(protocolStr)[0];

+        } else {

+            return null;

+        }

+    }

+

+    /**

+      getProtocolNameGuidArray

+      

+      This function is to get the protocol's CName ant it's GUID according to

+      protocol's namej.

+      

+      @param  protocolName   Name of protocl.

+      @return                Protocol's CName and it's GUID.

+    **/

+    public String[] getProtocolNameGuidArray(String protocolName) {

+        return this.protocolInfo.get(protocolName);

+    }

+

+    /**

+      getGUIDGuid

+      

+      This function is to get the GUID according to GUID's name

+      

+      @param  guidStr        Name of GUID

+      @return                GUID.

+    **/

+    public String getGUIDGuid(String guidStr) {

+        if (guidInfo.get(guidStr) != null) {

+            return guidInfo.get(guidStr)[1];

+        } else {

+            return null;

+        }

+

+    }

+

+    /**

+      getGuidNameArray

+      

+      This function is to get the GUID's CName and it's GUID according to 

+      GUID's name

+      

+      @param   guidName     Name of GUID

+      @return               CName and GUID.

+    **/

+    public String[] getGuidNameArray(String guidName) {

+        return this.guidInfo.get(guidName);

+    }

+

+    /**

+      getLibClassInclude 

+      

+      This function is to get the library exposed header file name according 

+      library class name.

+      

+      @param     libName    Name of library class   

+      @return               Name of header file

+    **/

+    String getLibClassIncluder(String libName) {

+        return libClassHeaderList.get(libName);

+    }

+

+    /**

+      getModuleTypeIncluder

+      

+      This function is to get the header file name from module info map 

+      according to module type.

+     

+      @param   moduleType    Module type.

+      @return                Name of header file.

+    **/

+    String getModuleTypeIncluder(String moduleType) {

+        return moduleInfo.get(moduleType);

+    }

+

+    /**

+      formateGuidName

+      

+      This function is to formate GUID to ANSI c form.

+     

+      @param  guidNameCon      String of GUID.

+      @return                  Formated GUID.

+    **/

+    public static String formatGuidName (String guidNameConv) {

+        String[] strList;

+        String guid = "";

+        int index = 0;

+        if (guidNameConv

+                        .matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}")) {

+            strList = guidNameConv.split("-");

+            guid = "0x" + strList[0] + ", ";

+            guid = guid + "0x" + strList[1] + ", ";

+            guid = guid + "0x" + strList[2] + ", ";

+            guid = guid + "{";

+            guid = guid + "0x" + strList[3].substring(0, 2) + ", ";

+            guid = guid + "0x" + strList[3].substring(2, 4);

+

+            while (index < strList[4].length()) {

+                guid = guid + ", ";

+                guid = guid + "0x" + strList[4].substring(index, index + 2);

+                index = index + 2;

+            }

+            guid = guid + "}";

+            return guid;

+        } else if (guidNameConv

+                        .matches("0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?")) {

+            strList = guidNameConv.split(",");

+            

+            //

+            // chang Microsoft specific form to ANSI c form

+            //

+            for (int i = 0; i < 3; i++){

+                guid = guid + strList[i] + ",";

+            }

+            guid = guid + "{";

+            

+            for (int i = 3; i < strList.length; i++){

+                if (i == strList.length - 1){

+                    guid = guid + strList[i];

+                } else {

+                    guid = guid + strList[i] + ",";

+                }

+            }

+            guid = guid + "}";            

+            return guid;

+        } else {

+            System.out.println("Check GUID Value, it don't conform to the schema!!!");

+            return "0";

+

+        }

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
new file mode 100644
index 0000000..96003c2
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
@@ -0,0 +1,218 @@
+/** @file

+  SurfaceAreaParser class.

+  

+  SurfaceAreaParser class is used to parse module surface area include both 

+  driver and library. 

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build.global;

+

+import java.io.File;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.LibraryModuleBuildDescriptionDocument;

+import org.tianocore.LibraryModuleSurfaceAreaDocument;

+import org.tianocore.ModuleBuildDescriptionDocument;

+import org.tianocore.ModuleSurfaceAreaDocument;

+

+/**

+  This class is used to parse module surface area (MSA & MBD) include both 

+  driver and library. 

+

+  @since GenBuild 1.0

+**/

+public class SurfaceAreaParser {

+

+    /**

+      Using XmlBeans to parse and valid surface area file. 

+    

+      @param surfaceAreaFile the surface area file to parse

+      @return top level elements and its value mapping information

+      @throws BuildException

+              If surface area is not well-formed or invalid

+    **/

+    public Map<String, XmlObject> parseFile(File surfaceAreaFile) throws BuildException {

+        Map<String, XmlObject> map = new HashMap<String, XmlObject>();

+        try {

+            XmlObject sadoc = XmlObject.Factory.parse(surfaceAreaFile);

+            // Validate File if they obey XML Schema

+            

+            if ( ! sadoc.validate()){

+                throw new BuildException("Surface Area file [" + surfaceAreaFile.getPath() + "] is invalid.");

+            }

+            if (sadoc instanceof ModuleSurfaceAreaDocument){

+                parseFile((ModuleSurfaceAreaDocument) sadoc, map);

+            }

+            else if(sadoc instanceof ModuleBuildDescriptionDocument){

+                parseFile((ModuleBuildDescriptionDocument) sadoc, map);

+            }

+            else if(sadoc instanceof LibraryModuleSurfaceAreaDocument){

+                parseFile((LibraryModuleSurfaceAreaDocument) sadoc, map);

+            }

+            else if(sadoc instanceof LibraryModuleBuildDescriptionDocument){

+                parseFile((LibraryModuleBuildDescriptionDocument) sadoc, map);

+            }

+        }

+        catch (Exception ex){

+            throw new BuildException(ex.getMessage());

+        }

+        return map;

+    }

+    

+    

+    /**

+      Parse MSA.

+    

+      @param doc top level surface area XML document

+      @param msaMap the map to store the result

+    **/

+    private void parseFile(ModuleSurfaceAreaDocument doc, Map<String, XmlObject> msaMap) {

+        msaMap.put("MsaHeader", doc.getModuleSurfaceArea().getMsaHeader());

+        msaMap.put("LibraryClassDefinitions", doc.getModuleSurfaceArea()

+                        .getLibraryClassDefinitions());

+        msaMap.put("SourceFiles", doc.getModuleSurfaceArea().getSourceFiles());

+        msaMap.put("Includes", doc.getModuleSurfaceArea().getIncludes());

+        msaMap.put("Protocols", doc.getModuleSurfaceArea().getProtocols());

+

+        msaMap.put("Events", doc.getModuleSurfaceArea().getEvents());

+        msaMap.put("Hobs", doc.getModuleSurfaceArea().getHobs());

+        msaMap.put("PPIs", doc.getModuleSurfaceArea().getPPIs());

+        msaMap.put("Variables", doc.getModuleSurfaceArea().getVariables());

+        msaMap.put("BootModes", doc.getModuleSurfaceArea().getBootModes());

+

+        msaMap

+                        .put("SystemTables", doc.getModuleSurfaceArea()

+                                        .getSystemTables());

+        msaMap.put("DataHubs", doc.getModuleSurfaceArea().getDataHubs());

+        msaMap.put("Formsets", doc.getModuleSurfaceArea().getFormsets());

+        msaMap.put("Guids", doc.getModuleSurfaceArea().getGuids());

+        msaMap.put("Externs", doc.getModuleSurfaceArea().getExterns());

+

+        msaMap.put("PCDs", doc.getModuleSurfaceArea().getPCDs());

+        msaMap

+                        .put("BuildOptions", doc.getModuleSurfaceArea()

+                                        .getBuildOptions());

+    }

+

+    /**

+      Parse MBD.

+  

+      @param doc top level surface area XML document

+      @param msaMap the map to store the result

+    **/

+    private void parseFile(ModuleBuildDescriptionDocument doc, Map<String, XmlObject> mbdMap) {

+        mbdMap.put("MbdHeader", doc.getModuleBuildDescription().getMbdHeader());

+        mbdMap.put("Libraries", doc.getModuleBuildDescription().getLibraries());

+        mbdMap.put("SourceFiles", doc.getModuleBuildDescription()

+                        .getSourceFiles());

+        mbdMap.put("Includes", doc.getModuleBuildDescription().getIncludes());

+        mbdMap.put("Protocols", doc.getModuleBuildDescription().getProtocols());

+

+        mbdMap.put("Events", doc.getModuleBuildDescription().getEvents());

+        mbdMap.put("Hobs", doc.getModuleBuildDescription().getHobs());

+        mbdMap.put("PPIs", doc.getModuleBuildDescription().getPPIs());

+        mbdMap.put("Variables", doc.getModuleBuildDescription().getVariables());

+        mbdMap.put("BootModes", doc.getModuleBuildDescription().getBootModes());

+

+        mbdMap.put("SystemTables", doc.getModuleBuildDescription()

+                        .getSystemTables());

+        mbdMap.put("DataHubs", doc.getModuleBuildDescription().getDataHubs());

+        mbdMap.put("Formsets", doc.getModuleBuildDescription().getFormsets());

+        mbdMap.put("Guids", doc.getModuleBuildDescription().getGuids());

+        mbdMap.put("Externs", doc.getModuleBuildDescription().getExterns());

+

+        mbdMap.put("PCDs", doc.getModuleBuildDescription().getPCDs());

+        mbdMap.put("BuildOptions", doc.getModuleBuildDescription()

+                        .getBuildOptions());

+    }

+    /**

+      Parse Library MSA.

+

+      @param doc top level surface area XML document

+      @param msaMap the map to store the result

+    **/

+    private void parseFile(LibraryModuleSurfaceAreaDocument doc, Map<String, XmlObject> msaMap) {

+        msaMap.put("MsaLibHeader", doc.getLibraryModuleSurfaceArea()

+                        .getMsaLibHeader());

+        msaMap.put("LibraryClassDefinitions", doc.getLibraryModuleSurfaceArea()

+                        .getLibraryClassDefinitions());

+        msaMap.put("SourceFiles", doc.getLibraryModuleSurfaceArea()

+                        .getSourceFiles());

+        msaMap.put("Includes", doc.getLibraryModuleSurfaceArea().getIncludes());

+        msaMap.put("Protocols", doc.getLibraryModuleSurfaceArea()

+                        .getProtocols());

+

+        msaMap.put("Events", doc.getLibraryModuleSurfaceArea().getEvents());

+        msaMap.put("Hobs", doc.getLibraryModuleSurfaceArea().getHobs());

+        msaMap.put("PPIs", doc.getLibraryModuleSurfaceArea().getPPIs());

+        msaMap.put("Variables", doc.getLibraryModuleSurfaceArea()

+                        .getVariables());

+        msaMap.put("BootModes", doc.getLibraryModuleSurfaceArea()

+                        .getBootModes());

+

+        msaMap.put("SystemTables", doc.getLibraryModuleSurfaceArea()

+                        .getSystemTables());

+        msaMap.put("DataHubs", doc.getLibraryModuleSurfaceArea().getDataHubs());

+        msaMap.put("Formsets", doc.getLibraryModuleSurfaceArea().getFormsets());

+        msaMap.put("Guids", doc.getLibraryModuleSurfaceArea().getGuids());

+        msaMap.put("Externs", doc.getLibraryModuleSurfaceArea().getExterns());

+

+        msaMap.put("PCDs", doc.getLibraryModuleSurfaceArea().getPCDs());

+        msaMap.put("BuildOptions", doc.getLibraryModuleSurfaceArea()

+                        .getBuildOptions());

+    }

+

+    /**

+      Parse Library MBD.

+

+      @param doc top level surface area XML document

+      @param msaMap the map to store the result

+    **/

+    private void parseFile(LibraryModuleBuildDescriptionDocument doc, Map<String, XmlObject> mbdMap) {

+        mbdMap.put("MbdLibHeader", doc.getLibraryModuleBuildDescription()

+                        .getMbdLibHeader());

+        mbdMap.put("Libraries", doc.getLibraryModuleBuildDescription()

+                        .getLibraries());

+        mbdMap.put("SourceFiles", doc.getLibraryModuleBuildDescription()

+                        .getSourceFiles());

+        mbdMap.put("Includes", doc.getLibraryModuleBuildDescription()

+                        .getIncludes());

+        mbdMap.put("Protocols", doc.getLibraryModuleBuildDescription()

+                        .getProtocols());

+

+        mbdMap

+                        .put("Events", doc.getLibraryModuleBuildDescription()

+                                        .getEvents());

+        mbdMap.put("Hobs", doc.getLibraryModuleBuildDescription().getHobs());

+        mbdMap.put("PPIs", doc.getLibraryModuleBuildDescription().getPPIs());

+        mbdMap.put("Variables", doc.getLibraryModuleBuildDescription()

+                        .getVariables());

+        mbdMap.put("BootModes", doc.getLibraryModuleBuildDescription()

+                        .getBootModes());

+

+        mbdMap.put("SystemTables", doc.getLibraryModuleBuildDescription()

+                        .getSystemTables());

+        mbdMap.put("DataHubs", doc.getLibraryModuleBuildDescription()

+                        .getDataHubs());

+        mbdMap.put("Formsets", doc.getLibraryModuleBuildDescription()

+                        .getFormsets());

+        mbdMap.put("Guids", doc.getLibraryModuleBuildDescription().getGuids());

+        mbdMap.put("Externs", doc.getLibraryModuleBuildDescription()

+                        .getExterns());

+

+        mbdMap.put("PCDs", doc.getLibraryModuleBuildDescription().getPCDs());

+        mbdMap.put("BuildOptions", doc.getLibraryModuleBuildDescription()

+                        .getBuildOptions());

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
new file mode 100644
index 0000000..03c8d43
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
@@ -0,0 +1,1109 @@
+/** @file

+ This file is for surface area information retrieval.

+

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.build.global;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Stack;

+import java.util.regex.Matcher;

+import java.util.regex.Pattern;

+

+import org.apache.xmlbeans.XmlNormalizedString;

+import org.apache.xmlbeans.XmlObject;

+import org.apache.xmlbeans.XmlString;

+import org.tianocore.BuildOptionsDocument;

+import org.tianocore.CName;

+import org.tianocore.ExternsDocument;

+import org.tianocore.FfsDocument;

+import org.tianocore.FileNameConvention;

+import org.tianocore.FrameworkComponentTypes;

+import org.tianocore.FvImageOptionsDocument;

+import org.tianocore.GuidDocument;

+import org.tianocore.GuidsDocument;

+import org.tianocore.LibrariesDocument;

+import org.tianocore.LibraryClassDocument;

+import org.tianocore.LibraryUsage;

+import org.tianocore.ModuleSADocument;

+import org.tianocore.ModuleTypeDef;

+import org.tianocore.NameValueDocument;

+import org.tianocore.OutputDirectoryDocument;

+import org.tianocore.PPIsDocument;

+import org.tianocore.PackageNameDocument;

+import org.tianocore.ProtocolsDocument;

+import org.tianocore.PCDsDocument.PCDs;

+

+/**

+  SurfaceAreaQuery class is used to query Surface Area information from msa, mbd,

+  spd and fpd files. 

+  

+  This class should not instantiated. All the public interfaces is static.

+  

+  @since GenBuild 1.0

+ **/

+public class SurfaceAreaQuery {

+    /// 

+    /// Contains name/value pairs of Surface Area document object. The name is

+    /// always the top level element name.

+    ///  

+    private static Map<String, XmlObject> map = null;

+    

+    ///

+    /// mapStack is used to do nested query

+    ///

+    private static Stack< Map<String, XmlObject> > mapStack = new Stack< Map<String, XmlObject> >();

+    

+    /// 

+    /// prefix of name space

+    /// 

+    private static String nsPrefix = "sans";

+    

+    ///

+    /// xmlbeans needs a name space for each Xpath element 

+    ///

+    private static String ns = null;

+    

+    ///

+    /// keep the namep declaration for xmlbeans Xpath query

+    ///

+    private static String queryDeclaration = null;

+

+    /**

+     Set a Surface Area document for query later

+     

+     @param     map     A Surface Area document in TopLevelElementName/XmlObject format.

+     **/

+    public static void setDoc(Map<String, XmlObject> map) {

+        ns = OverrideProcess.prefix;

+        queryDeclaration = "declare namespace " + nsPrefix + "='" + ns + "'; ";

+        SurfaceAreaQuery.map = map;

+    }

+

+    /**

+     Push current used Surface Area document into query stack. The given new 

+     document  will be used for any immediately followed getXXX() callings, 

+     untill pop() is called.

+     

+     @param     newMap  The TopLevelElementName/XmlObject format of a Surface Area document.

+     **/

+    public static void push(Map<String, XmlObject> newMap) {

+        mapStack.push(SurfaceAreaQuery.map);

+        SurfaceAreaQuery.map = newMap;

+    }

+    

+    /**

+     Discard current used Surface Area document and use the top document in stack

+     instead.

+     **/

+    public static void pop() {

+        SurfaceAreaQuery.map = mapStack.pop();

+    }

+    

+    ///

+    /// Convert xPath to be namespace qualified, which is necessary for XmlBeans

+    /// selectPath(). For example, converting /MsaHeader/ModuleType to

+    /// /ns:MsaHeader/ns:ModuleType

+    ///     

+    private static String normalizeQueryString(String[] exp, String from) {

+        StringBuffer normQueryString = new StringBuffer(4096);

+

+        int i = 0;

+        while (i < exp.length) {

+            String newExp = from + exp[i];

+            Pattern pattern = Pattern.compile("([^/]*)(/|//)([^/]+)");

+            Matcher matcher = pattern.matcher(newExp);

+

+            while (matcher.find()) {

+                String starter = newExp.substring(matcher.start(1), matcher.end(1));

+                String seperator = newExp.substring(matcher.start(2), matcher.end(2));

+                String token = newExp.substring(matcher.start(3), matcher.end(3));

+                

+                normQueryString.append(starter);

+                normQueryString.append(seperator);

+                normQueryString.append(nsPrefix);

+                normQueryString.append(":");

+                normQueryString.append(token);

+            }

+

+            ++i;

+            if (i < exp.length) {

+                normQueryString.append(" | ");

+            }

+        }

+

+        return normQueryString.toString();

+    }

+

+    /**

+      Search all XML documents stored in "map" for the specified xPath, using

+      relative path (starting with '$this')

+     

+     @param     xPath   xpath query string array

+     @returns   An array of XmlObject   if elements are found at the specified xpath

+     @returns   NULL                    if nothing is at the specified xpath

+     **/

+    public static XmlObject[] get(String[] xPath) {

+        if (map == null) {

+            return null;

+        }

+        

+        String[] keys = (String[]) map.keySet().toArray(new String[map.size()]);

+        List<XmlObject> result = new ArrayList<XmlObject>();

+        for (int i = 0; i < keys.length; ++i) {

+            XmlObject rootNode = (XmlObject) map.get(keys[i]);

+            if (rootNode == null) {

+                continue;

+            }

+            

+            String query = queryDeclaration + normalizeQueryString(xPath, "$this/" + keys[i]);

+            XmlObject[] tmp = rootNode.selectPath(query);

+            for (int j = 0; j < tmp.length; ++j) {

+                result.add(tmp[j]);

+            }

+        }

+        

+        int size = result.size();

+        if (size <= 0) {

+            return null;

+        }

+        

+        return (XmlObject[]) result.toArray(new XmlObject[size]);

+    }

+

+    /**

+     Search XML documents named by "rootName" for the given xPath, using

+     relative path (starting with '$this')

+     

+     @param     rootName    The top level element name 

+     @param     xPath       The xpath query string array

+     @returns   An array of XmlObject   if elements are found at the given xpath

+     @returns   NULL                    if nothing is found at the given xpath

+     **/

+    public static XmlObject[] get(String rootName, String[] xPath) {

+        if (map == null) {

+            return null;

+        }

+        

+        XmlObject root = (XmlObject) map.get(rootName);

+        if (root == null) {

+            return null;

+        }

+

+        String query = queryDeclaration + normalizeQueryString(xPath, "$this/" + rootName);

+        XmlObject[] result = root.selectPath(query);

+        if (result.length > 0) {

+            return result;

+        }

+

+        query = queryDeclaration + normalizeQueryString(xPath, "/" + rootName);

+        result = root.selectPath(query);

+        if (result.length > 0) {

+            return result;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve SourceFiles/Filename for specified ARCH type

+      

+     @param     arch        architecture name

+     @returns   An array of XmlObject   if elements are found at the known xpath

+     @returns   NULL                    if nothing is found at the known xpath

+     **/

+    public static XmlObject[] getSourceFiles(String arch) {

+        String[] xPath;

+

+        if (arch == null || arch.equals("")) {

+            xPath = new String[] {

+                "/Filename",

+                "/Arch/Filename"

+                };

+        } else {

+            xPath = new String[] {

+                "/Filename[not(@ArchType) or @ArchType='ALL' or @ArchType='" + arch + "']",

+                "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/Filename"

+                };

+        }

+

+        return get("SourceFiles", xPath);

+    }

+

+    /**

+     Retrieve BuildOptions/Ffs

+

+     @returns   FfsDocument.Ffs object  if elements are found at the known xpath

+     @returns   NULL                    if nothing is found at the known xpath

+     **/

+    public static FfsDocument.Ffs getFfs() {

+        String[] xPath = new String[] { "/Ffs" };

+

+        XmlObject[] returns = get("BuildOptions", xPath);

+        if (returns != null && returns.length > 0) {

+            return (FfsDocument.Ffs) returns[0];

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve BuildOptions/OutputDirectory

+

+     @returns   Directory names array   if elements are found at the known xpath

+     @returns   Empty                   if nothing is found at the known xpath

+     **/

+    public static String[] getOutputDirectory() {

+        String[] xPath = new String[] { "/OutputDirectory" };

+

+        XmlObject[] returns = get("BuildOptions", xPath);

+        if (returns != null && returns.length > 0) {

+            String[] dirString = new String[2];

+

+            OutputDirectoryDocument.OutputDirectory[] dir = (OutputDirectoryDocument.OutputDirectory[]) returns;

+            dirString[0] = dir[0].getIntermediateDirectories().toString();

+            dirString[1] = dir[0].getStringValue();

+

+            return dirString;

+        }

+

+        return new String[] { "UNIFIED", null };

+    }

+

+    /**

+     Retrieve BuildOptions/Option or Arch/Option

+

+     @param     arch    architecture name

+

+     @returns   name/value pairs of options if elements are found at the known xpath

+     @returns   Empty array                 if nothing is there

+     **/

+    public static String[][] getOptions(String arch){

+        String[] xPath;

+

+        if (arch == null || arch.equals("")) {

+            xPath = new String[] {

+                "/Option",

+                "/Arch/Option"

+                };

+        } else {

+            xPath = new String[] {

+                "/Option",

+                "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/Option"

+                };

+        }

+

+        XmlObject[] returns = get("BuildOptions", xPath);

+        if (returns == null){

+            return new String[0][2];

+        }

+        

+        String[][] result = new String[returns.length][2];

+        for (int i = 0; i < returns.length; i ++){

+            String str;

+            String name = null;

+            String value = null;

+

+            if (returns[i] instanceof BuildOptionsDocument.BuildOptions.Option) {

+                BuildOptionsDocument.BuildOptions.Option option = (BuildOptionsDocument.BuildOptions.Option)returns[i];

+                str = option.getStringValue();

+            } else if (returns[i] instanceof BuildOptionsDocument.BuildOptions.Arch.Option) {

+                BuildOptionsDocument.BuildOptions.Arch.Option archOption = (BuildOptionsDocument.BuildOptions.Arch.Option)returns[i];

+                str = archOption.getStringValue();

+            } else {

+                continue;

+            }

+            

+            int equalIndex = str.indexOf('=');

+            if ( equalIndex > 0) {

+                name = str.substring(0, equalIndex).trim();

+                value = str.substring(equalIndex + 1).trim();

+                // TBD remove some forbidden name: BASE_NAME, ARCH and so on

+                if (name.length() == 0){

+                    name = null;

+                }

+            }

+            result[i][0] = name;

+            result[i][1] = value;

+        }

+

+        return result;

+    }

+    

+    /**

+     Retrieve <xxxHeader>/ModuleType

+

+     @returns   The module type name    if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String getModuleType() {

+        String[] xPath = new String[] { "/ModuleType" };

+

+        XmlObject[] returns = get(xPath);

+        if (returns != null && returns.length > 0) {

+            ModuleTypeDef type = (ModuleTypeDef) returns[0];

+            return type.enumValue().toString();

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve <xxxHeader>/ComponentType

+     

+     @returns   The component type name if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String getComponentType() {

+        String[] xPath = new String[] { "/ComponentType" };

+

+        XmlObject[] returns = get(xPath);

+        if (returns != null && returns.length > 0) {

+            FrameworkComponentTypes type = (FrameworkComponentTypes) returns[0];

+            return type.enumValue().toString();

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve Includes/PackageName

+

+     @param     arch    Architecture name

+

+     @returns   package name list       if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static List<String> getIncludePackageName(String arch) {

+        String[] xPath;

+

+        if (arch == null || arch.equals("")) {

+            xPath = new String[] {

+                "/PackageName",

+                "/Arch/PackageName"

+                };

+        } else {

+            xPath = new String[] {

+                "/PackageName",

+                "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/PackageName"

+                };

+        }

+        

+        XmlObject[] returns = get("Includes", xPath);

+        if (returns == null || returns.length == 0) {

+            return null;

+        }

+

+        List<String> packageNames = new ArrayList<String>();

+        PackageNameDocument.PackageName[] nameObj = (PackageNameDocument.PackageName[])returns;

+        for (int i = 0; i < returns.length; ++i) {

+            packageNames.add(nameObj[i].getStringValue());

+        }

+        

+        return packageNames;

+    }

+

+    /**

+     Retrieve LibraryClassDefinitions/LibraryClass for specified usage

+

+     @param     usage   Library class usage

+

+     @returns   LibraryClass objects list   if elements are found at the known xpath

+     @returns   null                        if nothing is there

+     **/

+    public static LibraryClassDocument.LibraryClass[] getLibraryClassArray(String usage) {

+        String[] xPath;

+

+        if (usage == null || usage.equals("")) {

+            xPath = new String[] {"/LibraryClass"};

+        } else {

+            xPath = new String[] {"/LibraryClass[@Usage='" + usage + "']"};

+        }

+

+        XmlObject[] returns = get("LibraryClassDefinitions", xPath);

+        if (returns != null && returns.length > 0) {

+            return (LibraryClassDocument.LibraryClass[]) returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve ModuleEntryPoint names

+

+     @returns   ModuleEntryPoint name list  if elements are found at the known xpath

+     @returns   null                        if nothing is there

+     **/

+    public static String[] getModuleEntryPointArray() {

+        String[] xPath = new String[] { "/Extern/ModuleEntryPoint" };

+

+        XmlObject[] returns = get("Externs", xPath);

+

+        if (returns != null && returns.length > 0) {

+            String[] entryPoints = new String[returns.length];

+

+            for (int i = 0; i < returns.length; ++i) {

+                entryPoints[i] = ((XmlNormalizedString) returns[i])

+                                .getStringValue();

+            }

+

+            return entryPoints;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve module Guid string

+ 

+     @returns   GUILD string            if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String getModuleGuid() {

+        String[] xPath = new String[] { "/Guid" };

+

+        XmlObject[] returns = get(xPath);

+        if (returns != null && returns.length > 0) {

+            GuidDocument.Guid guid = (GuidDocument.Guid) returns[0];

+            return guid.getStringValue();

+        }

+

+        return null;

+    }

+

+    /**

+     retrieve Protocol for specified usage

+

+     @param     usage   Protocol usage

+

+     @returns   Protocol objects list   if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static ProtocolsDocument.Protocols.Protocol[] getProtocolArray(String usage) {

+        String[] xPath;

+

+        if (usage == null || usage.equals("")) {

+            xPath = new String[] {"/Protocol"};

+        } else {

+            xPath = new String[] {"/Protocol[@Usage='" + usage + "']"};

+        }

+

+        XmlObject[] returns = get("Protocols", xPath);

+        if (returns != null && returns.length > 0) {

+            return (ProtocolsDocument.Protocols.Protocol[]) returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve ProtocolNotify for specified usage

+    

+     @param     usage   ProtocolNotify usage

+

+     @returns   ProtocolNotify objects list     if elements are found at the known xpath

+     @returns   null                            if nothing is there

+     **/

+    public static ProtocolsDocument.Protocols.ProtocolNotify[] getProtocolNotifyArray(String usage) {

+        String[] xPath;

+

+        if (usage == null || usage.equals("")) {

+            xPath = new String[] {"/ProtocolNotify"};

+        } else {

+            xPath = new String[] {"/ProtocolNotify[@Usage='" + usage + "']"};

+        }

+

+        XmlObject[] returns = get("Protocols", xPath);

+        if (returns != null && returns.length > 0) {

+            return (ProtocolsDocument.Protocols.ProtocolNotify[]) returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve ModuleUnloadImage names

+

+     @returns   ModuleUnloadImage name list     if elements are found at the known xpath

+     @returns   null                            if nothing is there

+     **/

+    public static String[] getModuleUnloadImageArray() {

+        String[] xPath = new String[] { "/Extern/ModuleUnloadImage" };

+

+        XmlObject[] returns = get("Externs", xPath);

+        if (returns != null && returns.length > 0) {

+            String[] stringArray = new String[returns.length];

+            XmlNormalizedString[] doc = (XmlNormalizedString[])returns;

+

+            for (int i = 0; i < returns.length; ++i) {

+                stringArray[i] = doc[i].getStringValue();

+            }

+

+            return stringArray;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve Extern

+

+     @returns   Extern objects list     if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static ExternsDocument.Externs.Extern[] getExternArray() {

+        String[] xPath = new String[] { "/Extern" };

+

+        XmlObject[] returns = get("Externs", xPath);

+        if (returns != null && returns.length > 0) {

+            return (ExternsDocument.Externs.Extern[]) returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve Ppi information

+

+     @param     usage   Ppi usage

+

+     @returns   Ppi objects list        if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static PPIsDocument.PPIs.Ppi[] getPpiArray(String usage) {

+        String[] xPath;

+

+        if (usage == null || usage.equals("")) {

+            xPath = new String[] { "/Ppi" };

+        } else {

+            xPath = new String[] { "/Ppi[@Usage='" + usage + "']" };

+        }

+

+        XmlObject[] returns = get("PPIs", xPath);

+        if (returns != null && returns.length > 0) {

+            return (PPIsDocument.PPIs.Ppi[])returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrive PpiNotify information

+    

+     @param usage

+

+     @returns   PpiNotify objects list  if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static PPIsDocument.PPIs.PpiNotify[] getPpiNotifyArray(String usage) {

+        String[] xPath;

+

+        if (usage == null || usage.equals("")) {

+            xPath = new String[] { "/PpiNotify" };

+        } else {

+            xPath = new String[] { "/PpiNotify[@Usage='" + usage + "']" };

+        }

+

+        XmlObject[] returns = get("PPIs", xPath);

+        if (returns != null && returns.length > 0) {

+            return (PPIsDocument.PPIs.PpiNotify[])returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve GuidEntry information for specified usage

+

+     @param     usage   GuidEntry usage

+

+     @returns   GuidEntry objects list  if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static GuidsDocument.Guids.GuidEntry[] getGuidEntryArray(String usage) {

+        String[] xPath;

+

+        if (usage == null || usage.equals("")) {

+            xPath = new String[] { "/GuidEntry" };

+        } else {

+            xPath = new String[] { "/GuidEntry[@Usage='" + usage + "']" };

+        }

+

+        XmlObject[] returns = get("Guids", xPath);

+        if (returns != null && returns.length > 0) {

+            return (GuidsDocument.Guids.GuidEntry[])returns;

+        }

+

+        return null;

+    }

+

+    /**

+     Retrieve Library instance information

+

+     @param     arch    Architecture name

+     @param     usage   Library instance usage

+

+     @returns   library instance name list  if elements are found at the known xpath

+     @returns   null                        if nothing is there

+     **/

+    public static List<String> getLibraryInstance(String arch, String usage) {

+        String[] xPath;

+        String   archAttribute = "";

+        String   usageAttribute = "";

+

+        if ((arch != null) || (!arch.equals(""))) {

+            archAttribute = "[@ArchType='ALL' or @ArchType='" + arch + "']";

+        }

+        

+        if ((usage != null) || (!usage.equals(""))) {

+            // if no Usage attribute specified, default to ALWAYS_CONSUMED

+            if (usage.equals(LibraryUsage.ALWAYS_CONSUMED.toString())) {

+                usageAttribute = "[not(@Usage) or @Usage='" + usage + "']";

+            } else {

+                usageAttribute = "[@Usage='" + usage + "']";

+            }

+        }

+        

+        xPath = new String[] {

+                "/Library" + usageAttribute,

+                "/Arch" + archAttribute + "/Library" + usageAttribute

+                };

+

+        XmlObject[] returns = get("Libraries", xPath);

+        if (returns == null || returns.length == 0) {

+            return null;

+        }

+        

+        List<String> instances = new ArrayList<String>();

+        for (int i = 0; i < returns.length; ++i) {

+            if (returns[i] instanceof LibrariesDocument.Libraries.Library) {

+                LibrariesDocument.Libraries.Library lib = (LibrariesDocument.Libraries.Library)returns[i];

+                instances.add(lib.getStringValue());

+            } else if (returns[i] instanceof LibrariesDocument.Libraries.Arch.Library) {

+                LibrariesDocument.Libraries.Arch.Library lib = (LibrariesDocument.Libraries.Arch.Library)returns[i];

+                instances.add(lib.getStringValue());

+            }

+        }

+

+        return instances;

+    }

+

+    ///

+    /// This method is used for retrieving the elements information which has 

+    /// CName sub-element

+    ///

+    private static String[] getCNames(String from, String xPath[]) {

+        XmlObject[] returns = get(from, xPath);

+        if (returns == null || returns.length == 0) {

+            return null;

+        }

+        

+        String[] strings = new String[returns.length];

+        for (int i = 0; i < returns.length; ++i) {

+            strings[i] = ((CName)returns[i]).getStringValue(); 

+        }

+        

+        return strings;            

+    }

+    

+    /**

+     Retrive library's constructor name

+

+     @returns   constructor name list   if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String getLibConstructorName() {

+        String[] xPath = new String[] {"/Extern/Constructor"};

+

+        XmlObject[] returns = get("Externs", xPath);

+        if (returns != null && returns.length > 0) {

+            CName constructor = (CName)returns[0]; 

+            return constructor.getStringValue();            

+        }

+

+        return null;

+    }

+

+    /**

+     Retrive library's destructor name

+

+     @returns   destructor name list    if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String getLibDestructorName() {

+        String[] xPath = new String[] {"/Extern/Destructor"};

+

+        XmlObject[] returns = get("Externs", xPath);

+        if (returns != null && returns.length > 0) {

+            CName destructor = (CName)returns[0]; 

+            return destructor.getStringValue();            

+        }

+

+        return null;

+    }

+    

+    /**

+     Retrive DriverBinding names

+

+     @returns   DriverBinding name list if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String[] getDriverBindingArray() {

+        String[] xPath = new String[] {"/Extern/DriverBinding"};

+        return getCNames("Externs", xPath);

+    }

+    

+    /**

+     Retrive ComponentName names

+

+     @returns   ComponentName name list if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String[] getComponentNameArray() {

+        String[] xPath = new String[] {"/Extern/ComponentName"};

+        return getCNames("Externs", xPath);

+    }

+    

+    /**

+     Retrive DriverConfig names

+

+     @returns   DriverConfig name list  if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String[] getDriverConfigArray() {

+        String[] xPath = new String[] {"/Extern/DriverConfig"};

+        return getCNames("Externs", xPath);

+    }

+    

+    /**

+     Retrive DriverDiag names

+

+     @returns   DriverDiag name list    if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String[] getDriverDiagArray() {

+        String[] xPath = new String[] {"/Extern/DriverDiag"};

+        return getCNames("Externs", xPath);

+    }

+

+    /**

+     Retrive SetVirtualAddressMapCallBack names

+

+     @returns   SetVirtualAddressMapCallBack name list  

+                                        if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String[] getSetVirtualAddressMapCallBackArray() {

+        String[] xPath = new String[] {"/Extern/SetVirtualAddressMapCallBack"};

+        return getCNames("Externs", xPath);

+    }

+    

+    /**

+     Retrive ExitBootServicesCallBack names

+

+     @returns   ExitBootServicesCallBack name list  

+                                        if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String[] getExitBootServicesCallBackArray() {

+        String[] xPath = new String[] {"/Extern/ExitBootServicesCallBack"};

+        return getCNames("Externs", xPath);

+    }

+

+    /**

+     Retrieve module surface area file information

+

+     @returns   ModuleSA objects list   if elements are found at the known xpath

+     @returns   Empty ModuleSA list     if nothing is there

+     **/

+    public static ModuleSADocument.ModuleSA[] getFpdModules() {

+        String[] xPath = new String[] { "/TianoImage/*/ModuleSA" };

+

+        XmlObject[] result = get("FrameworkPlatformDescription", xPath);

+        if (result == null) {

+            return new ModuleSADocument.ModuleSA[0];

+        }

+

+        return (ModuleSADocument.ModuleSA[]) result;

+    }

+

+    /**

+     Retrieve variables for FV images

+

+     @returns   name/value list        if elements are found at the known xpath

+     @returns   empty list             if nothing is there

+     **/

+    public static String[][] getFpdGlobalVariable() {

+        String[] xPath = new String[] { "/Flash/FvImages/NameValue" };

+

+        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);

+        if (queryResult == null) {

+            return new String[0][];

+        }

+

+        String[][] result = new String[queryResult.length][2];

+        for (int i = 0; i < queryResult.length; i++){

+            result[i][0] = ((NameValueDocument.NameValue)queryResult[i]).getName();

+            result[i][1] = ((NameValueDocument.NameValue)queryResult[i]).getValue();

+        }

+

+        return result;

+    }

+    

+    /**

+     Retrieve valid image names

+

+     @returns   valid iamges name list  if elements are found at the known xpath

+     @returns   empty list              if nothing is there

+     **/

+    public static String[] getFpdValidImageNames(){

+        String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='ValidImageNames']/FvImageNames" };

+

+        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);

+        if (queryResult == null) {

+            return new String[0];

+        }

+

+        String[] result = new String[queryResult.length];

+        for (int i = 0; i < queryResult.length; i++){

+            result[i] = ((XmlString)queryResult[i]).getStringValue();

+        }

+

+        return result;

+    }

+

+    /**

+     Retrieve FV image option information

+

+     @param fvName  FV image name

+

+     @returns   option name/value list if elements are found at the known xpath

+     @returns   empty list             if nothing is there

+     **/

+    public static String[][] getFpdOptions(String fvName){

+        String[] xPath = new String[] {"/Flash/FvImages/FvImageName[@Name='" + fvName.toUpperCase() + "']/FvImageOptions/NameValue" };

+

+        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);

+        if (queryResult == null) {

+            return new String[0][];

+        }

+

+        String[][] result = new String[queryResult.length][2];

+        for (int i = 0; i < queryResult.length; i++){

+            result[i][0] = ((NameValueDocument.NameValue)queryResult[i]).getName();

+            result[i][1] = ((NameValueDocument.NameValue)queryResult[i]).getValue();

+        }

+

+        return result;

+    }

+    

+    /**

+     Retrieve FV image attributes information

+

+     @param     fvName  FV image name

+

+     @returns   attribute name/value list   if elements are found at the known xpath

+     @returns   empty list                  if nothing is there

+     **/

+    public static String[][] getFpdAttributes(String fvName){

+        String[] xPath = new String[] {"/Flash/FvImages/FvImage[@Type='Attributes' and ./FvImageNames='" + fvName.toUpperCase() + "']/FvImageOptions" };

+

+        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);

+        if (queryResult == null) {

+            return new String[0][];

+        }

+

+        ArrayList<String[]> list = new ArrayList<String[]>();

+        for (int i = 0 ; i < queryResult.length; i++){

+            FvImageOptionsDocument.FvImageOptions item = (FvImageOptionsDocument.FvImageOptions)queryResult[i];

+

+            List<NameValueDocument.NameValue> namevalues = item.getNameValueList();

+            Iterator iter = namevalues.iterator();

+            while (iter.hasNext()) {

+                NameValueDocument.NameValue nvItem = (NameValueDocument.NameValue)iter.next();

+                list.add(new String[]{nvItem.getName(), nvItem.getValue()});

+            }

+

+            List<String> enables = item.getEnableList();

+            iter = enables.iterator();

+            while (iter.hasNext()) {

+                String enableItem = (String)iter.next();

+                list.add(new String[]{enableItem, "TRUE"});

+            }

+

+            List<String> disables = item.getDisableList();

+            iter = disables.iterator();

+            while (iter.hasNext()) {

+                String disableItem = (String)iter.next();

+                list.add(new String[]{disableItem, "FALSE"});

+            }

+        }

+

+        String[][] result = new String[list.size()][2];

+        for (int i = 0; i < list.size(); i++){

+            result[i][0] = list.get(i)[0];

+            result[i][1] = list.get(i)[1];

+        }

+

+        return result;

+    }

+    

+    /**

+     Retrieve flash definition file name

+

+     @returns   file name               if elements are found at the known xpath

+     @returns   null                    if nothing is there

+     **/

+    public static String getFlashDefinitionFile(){

+        String[] xPath = new String[] {"/Flash/FlashDefinitionFile" };

+

+        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);

+        if (queryResult == null || queryResult.length == 0) {

+            return null;

+        }

+

+        FileNameConvention filename = (FileNameConvention)queryResult[queryResult.length - 1];

+        return filename.getStringValue();

+    }

+    

+    /**

+     Retrieve FV image component options

+

+     @param     fvName  FV image name

+

+     @returns   name/value pairs list   if elements are found at the known xpath

+     @returns   empty list              if nothing is there

+     **/

+    public static String[][] getFpdComponents(String fvName){

+        String[] xPath = new String[] {"/Flash/FvImages/FvImage[@Type='Components' and ./FvImageNames='" + fvName.toUpperCase() + "']/FvImageOptions" };

+

+        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);

+        if (queryResult == null) {

+            return new String[0][];

+        }

+

+        ArrayList<String[]> list = new ArrayList<String[]>();

+        for (int i = 0 ; i < queryResult.length; i++){

+            FvImageOptionsDocument.FvImageOptions item = (FvImageOptionsDocument.FvImageOptions)queryResult[i];

+

+            List<NameValueDocument.NameValue> namevalues = item.getNameValueList();

+            Iterator iter = namevalues.iterator();

+            while (iter.hasNext()) {

+                NameValueDocument.NameValue nvItem = (NameValueDocument.NameValue)iter.next();

+                list.add(new String[]{nvItem.getName(), nvItem.getValue()});

+            }

+

+            List<String> enables = item.getEnableList();

+            iter = enables.iterator();

+            while (iter.hasNext()) {

+                String enableItem = (String)iter.next();

+                list.add(new String[]{enableItem, "TRUE"});

+            }

+

+            List<String> disables = item.getDisableList();

+            iter = disables.iterator();

+            while (iter.hasNext()) {

+                String disableItem = (String)iter.next();

+                list.add(new String[]{disableItem, "FALSE"});

+            }

+        }

+

+        String[][] result = new String[list.size()][2];

+        for (int i = 0; i < list.size(); i++){

+            result[i][0] = list.get(i)[0];

+            result[i][1] = list.get(i)[1];

+        }

+

+        return result;

+    }

+    

+    /**

+     Retrieve PCD tokens

+

+     @returns   CName/ItemType pairs list   if elements are found at the known xpath

+     @returns   null                        if nothing is there

+     **/

+    public static String[][] getPcdTokenArray() {

+        String[] xPath = new String[] {"/PcdData"};

+        

+        XmlObject[] returns = get("PCDs", xPath);

+        if (returns == null || returns.length == 0) {

+            return null;

+        }

+        

+        PCDs.PcdData[] pcds = (PCDs.PcdData[]) returns;

+        String[][] result = new String[pcds.length][2];

+        for (int i = 0; i < returns.length; ++i) {

+            if (pcds[i].getItemType() != null) {

+                result[i][1] = pcds[i].getItemType().toString();

+            } else {

+                result[i][1] = null;

+            }

+            result[i][0] = pcds[i].getCName();

+        }

+            

+        return result;

+    }

+

+    /**

+     Get the PcdToken array from module's surface area document.

+     The array should contains following data:

+     <p>-------------------------------------------------------------------</p>

+     <p>CName | ItemType | TokenspaceName | DefaultValue | Usage | HelpText</p>

+     <p>-------------------------------------------------------------------</p>

+     <p>Note: Until new schema applying, now we can only get CName, ItemType,</p>

+     

+     @return  2-array table contains all information of PCD token retrieved from MSA.

+     **/

+    public static Object[][] getModulePCDTokenArray () {

+      int             index;

+      Object[][]      result;

+      PCDs.PcdData[]  pcds;

+      String[]        xPath   = new String[] {"/PcdData"};

+      XmlObject[]     returns = get ("PCDs", xPath);

+

+      if ((returns == null) || (returns.length == 0)) {

+        return null;

+      }

+

+      pcds     = (PCDs.PcdData[]) returns;

+      result   = new Object[pcds.length][6];

+      for (index = 0; index < pcds.length; index ++) {

+        //

+        // Get CName

+        //

+        result [index][0] = pcds[index].getCName();

+        //

+        // Get ItemType: FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODLE, DYNAMIC, DYNAMIC_EX

+        //

+        if (pcds[index].getItemType() != null) {

+          result [index][1] = pcds[index].getItemType().toString();

+        } else {

+          result [index][1] = null;

+        }

+        

+        //

+        // BUGBUG: following field can *not* be got from current MSA until schema changed.

+        //

+        //result [index][2] = pcds[index].getTokenSpaceName();

+        result [index][2] = null;

+        result [index][3] = pcds[index].getDefaultValue();

+        //result [index][4] = pcds[index].getUsage ();

+        result [index][4] = null;

+        //result [index][5] = pcds[index].getHelpText ();

+        result [index][5] = null;

+      }

+      return result;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/global/VariableTask.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/VariableTask.java
new file mode 100644
index 0000000..f830e0a
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/global/VariableTask.java
@@ -0,0 +1,71 @@
+/** @file

+ * This file is ANT task VariableTask. 

+ *

+ * VariableTask task implements part of ANT property task. The difference is

+ * this task will override variable with same name, but ANT property task do not.

+ *

+ * Copyright (c) 2006, Intel Corporation

+ * All rights reserved. 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.

+ */

+package org.tianocore.build.global;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+

+/**

+ * VariableTask task implements part of ANT property task. The difference is

+ * this task will override variable with same name, but ANT property task do not.

+ * 

+ * @since GenBuild 1.0

+ */

+public class VariableTask extends Task {

+

+   /**

+    * property value

+    */

+   private String value;

+   

+   /**

+    * property name

+    */

+   private String name;

+

+   /**

+    * Set property name.

+    *

+    * @param name property name

+    */

+   public void setName( String name ) {

+      this.name = name;

+   }

+

+

+   /**

+    * Set property value.

+    *

+    * @param value  property value

+    */

+   public void setValue( String value ) {

+      this.value = value;

+   }

+

+   /**

+    * ANT task's entry point, will be called after init(). 

+    *

+    * @exception BuildException

+    *            If name or value is null

+    */

+   public void execute() throws BuildException {

+       if (name == null || value == null) {

+           throw new BuildException("Name or value must not null.");

+       }

+       getProject().setProperty(name, value);

+   }

+}

+

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java
new file mode 100644
index 0000000..a67d2f9
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java
@@ -0,0 +1,129 @@
+/** @file

+  ActionMessage class.

+

+  ActionMessage class take over all message for loging and waning. This class should

+  dispatch message into different class according to instance class type.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.pcd.action;

+

+import org.apache.tools.ant.Task;

+import org.tianocore.build.pcd.action.BuildAction;

+import org.tianocore.build.pcd.action.UIAction;

+

+/** ActionMessage class take over all message for loging and waning. This class 

+    should dispatch message into different Action class according to instance 

+    class type.

+**/

+public class ActionMessage {

+    ///

+    /// Macro definition for NULL messge level. 

+    /// In this meessage level, all message will be hidden.

+    ///

+    public final static int NULL_MESSAGE_LEVEL    = 0; 

+    ///

+    /// Macro definition for Log messge level.

+    /// In this message level, Only log information will be shown.

+    ///

+    public final static int LOG_MESSAGE_LEVEL     = 1;

+    ///

+    /// Macro definition for Warning message level.  

+    /// In this message level, log and waning message will be shown.

+    ///

+    public final static int WARNING_MESSAGE_LEVEL = 2;

+    ///

+    /// Macro definition for Debug mesage level.

+    /// In this message level, log, warning, debug message will be shown.

+    ///

+    public final static int DEBUG_MESSAGE_LEVEL   = 3;

+    ///

+    /// Macor definition for MAX message level.

+    /// In this message level, all message will be shown.

+    ///

+    public final static int MAX_MESSAGE_LEVEL     = 4;

+    ///

+    /// Current message level. It will control all message output for PCD tool.

+    ///

+    public       static int messageLevel          = NULL_MESSAGE_LEVEL;

+

+    /**

+      Log() function provide common log information functionality for all 

+      PCD tool includes all function

+

+      This function will dispatch message to special class such as BuildAction

+      Class, Entity Class etc.

+     

+      @param thisClass   The class object who want log information.

+      @param logStr      The string contains log information.

+    **/

+    public static void log(Object thisClass, String logStr) {

+        if(messageLevel < LOG_MESSAGE_LEVEL) {

+            return;

+        }

+

+        if(thisClass instanceof Task) {

+            BuildAction.logMsg(thisClass, "$$LOG$$:" + logStr);

+        } else if(thisClass instanceof UIAction) {

+            UIAction.logMsg(thisClass, "$$LOG$$:" + logStr);

+        } else {

+            System.out.println("$$LOG$$:" + logStr);

+        }

+    }

+

+    /**

+      Warning() function provide common warning information functionality for all 

+      PCD tool.

+

+      This function will dispatch message to special class such as BuildAction

+      Class, Entity Class etc.

+     

+      @param thisClass   The class object who want warn information.

+      @param warningStr  The string contains warning information.

+    **/  

+    public static void warning(Object thisClass, String warningStr) {

+        if(messageLevel < WARNING_MESSAGE_LEVEL) {

+            return;

+        }

+

+        if(thisClass instanceof Task) {

+            BuildAction.warningMsg(thisClass, "**WARNING**:" + warningStr);

+        } else if(thisClass instanceof UIAction) {

+            UIAction.warningMsg(thisClass, "**WARNING**:" + warningStr);

+        } else {

+            System.out.println("**WARNING**:" + warningStr);

+        }

+    }

+

+    /**

+      Debug() function provide common Debug information functionality for all 

+      PCD tool.

+

+      This function will dispatch message to special class such as BuildAction

+      Class, Entity Class etc.

+     

+      @param thisClass   The class object who want Debug information.

+      @param debugStr    The string contains Debug information.

+    **/  

+    public static void debug(Object thisClass, String debugStr) {

+        if(messageLevel < DEBUG_MESSAGE_LEVEL) {

+            return;

+        }

+

+        if(thisClass instanceof Task) {

+            BuildAction.logMsg(thisClass, "%%DEBUG%%:" + debugStr);

+        } else if(thisClass instanceof UIAction) {

+            UIAction.logMsg(thisClass, "%%DEBUG%%:" + debugStr);

+        } else {

+            System.out.println("%%DEBUG%%:" + debugStr);

+        }

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java
new file mode 100644
index 0000000..3614547
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java
@@ -0,0 +1,105 @@
+/** @file

+  BuildAction class.

+

+  BuildAction is the parent class for all action related to ant Task. This class will

+  define some common utility functionality, such as logMsg, warningMsg..etc.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.pcd.action;

+

+import org.apache.tools.ant.Task;

+import org.apache.tools.ant.Project;

+import org.tianocore.build.pcd.exception.BuildActionException;

+

+/** BuildAction is the parent class for all action related to ant Task. This class will

+    define some common utility functionality, such as logMsg, warningMsg..etc.

+**/

+abstract class BuildAction extends Task {

+    ///

+    /// Original message level before this action. This value will 

+    /// be restored when quit this action.

+    ///

+    private int originalMessageLevel;

+

+    /**

+      checkParameter function check all parameter valid.

+

+      This function will be overrided by child class.

+    **/

+    abstract void checkParameter() throws BuildActionException;

+

+    /**

+     performAction is to execute the detail action.

+      

+     This function will be overrided by child class.

+    **/

+    abstract void performAction() throws BuildActionException;

+

+    /**

+      setMessageLevel function set current message for task instance object.

+

+      The message should be restored when this action exit.

+

+      @param messageLevel The message level for this action.

+    **/

+    public void setMessageLevel(int messageLevel) {

+        originalMessageLevel        = ActionMessage.messageLevel;

+        ActionMessage.messageLevel  = messageLevel;

+    }

+

+    /**

+      logMsg function provide common log information functionality for all 

+      PCD tool extends from ANT task class.

+

+      This function will use the log function in Ant task class.

+     

+      @param action     The class object who want log information.

+      @param logStr     The string contains log information.

+    **/

+    public static void logMsg(Object action, String logStr) {

+        ((Task) action).log(logStr, Project.MSG_INFO);

+    }

+

+    /**

+      warningMsg function provide common warning information functionality for all 

+      PCD tool.

+

+      This function will dispatch message to special class such as BuildAction

+      Class, Entity Class etc.

+     

+      @param action      The class object who want warn information.

+      @param warningStr  The string contains warning information.

+    **/  

+    public static void warningMsg(Object action, String warningStr) {

+        ((Task) action).log(warningStr, Project.MSG_WARN);

+    }

+

+    /**

+      execute function is the main flow for all build action class.

+

+      This workflow will be:

+      1) Check paramet of this action.

+      2) Perform the child class action function.

+      3) Restore the message level.

+     

+      @throws BuildActionException

+    **/  

+    public void execute() throws BuildActionException {

+        checkParameter();

+        performAction();

+

+        //

+        // Restore orignal message level when exist the action.

+        //

+        ActionMessage.messageLevel = originalMessageLevel;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
new file mode 100644
index 0000000..4001558
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
@@ -0,0 +1,1858 @@
+/** @file

+  CollectPCDAction class.

+

+  This action class is to collect PCD information from MSA, SPD, FPD xml file.

+  This class will be used for wizard and build tools, So it can *not* inherit

+  from buildAction or wizardAction.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.pcd.action;

+

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.UUID;

+

+import org.apache.xmlbeans.XmlException;

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.FrameworkModulesDocument;

+import org.tianocore.FrameworkPlatformDescriptionDocument;

+import org.tianocore.FrameworkPlatformDescriptionDocument.FrameworkPlatformDescription;

+import org.tianocore.ModuleSADocument;

+import org.tianocore.ModuleSADocument.ModuleSA;

+import org.tianocore.PackageSurfaceAreaDocument;

+import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData;

+import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData.SkuData;

+import org.tianocore.PcdDefinitionsDocument.PcdDefinitions;

+import org.tianocore.PcdDynamicBuildDeclarationsDocument.PcdDynamicBuildDeclarations;

+import org.tianocore.build.autogen.CommonDefinition;

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.global.SurfaceAreaQuery;

+import org.tianocore.build.pcd.action.ActionMessage;

+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;

+import org.tianocore.build.pcd.entity.SkuInstance;

+import org.tianocore.build.pcd.entity.Token;

+import org.tianocore.build.pcd.entity.UsageInstance;

+import org.tianocore.build.pcd.exception.EntityException;

+

+class StringTable {

+    private ArrayList<String>   al; 

+    private ArrayList<String>   alComments;

+    private String              phase;

+    int                         len; 

+    int                         bodyStart;

+    int                         bodyLineNum;

+

+    public StringTable (String phase) {

+        this.phase = phase;

+        al = new ArrayList<String>();

+        alComments = new ArrayList<String>();

+        len = 0;

+        bodyStart = 0;

+        bodyLineNum = 0;

+    }

+

+    public String getSizeMacro () {

+        return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());

+    }

+

+    private int getSize () {

+        //

+        // We have at least one Unicode Character in the table.

+        //

+        return len == 0 ? 1 : len;

+    }

+

+    public int getTableLen () {

+        return al.size() == 0 ? 1 : al.size();

+    }

+

+    public String getExistanceMacro () {

+        return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");

+    }

+

+    public String getTypeDeclaration () {

+

+        String output;

+

+        final String stringTable = "StringTable";

+        final String tab = "\t";

+        final String newLine = ";\r\n";

+

+        output =  "/* StringTable */\r\n";

+

+        if (al.size() == 0) {

+            output += tab + String.format("UINT16 %s[1] /* StringTable is Empty */", stringTable) + newLine;

+        }

+

+        for (int i = 0; i < al.size(); i++) {

+            String str = al.get(i);

+

+            if (i == 0) {

+                //

+                // StringTable is a well-known name in the PCD DXE driver

+                //

+                output += tab + String.format("UINT16       %s[%d] /* %s */", stringTable, str.length() + 1, alComments.get(i)) + newLine;

+            } else {

+                output += tab + String.format("UINT16       %s_%d[%d] /* %s */", stringTable, i, str.length() + 1, alComments.get(i)) + newLine;

+            }

+        }

+

+        return output;

+

+    }

+

+    public ArrayList<String> getInstantiation () {

+        ArrayList<String> output = new ArrayList<String>();

+

+        output.add("/* StringTable */"); 

+

+        if (al.size() == 0) {

+            output.add("{ 0 }");

+        } else {

+            String str;

+

+            for (int i = 0; i < al.size(); i++) {

+                str = String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));

+                if (i != al.size() - 1) {

+                    str += ",";

+                }

+                output.add(str);

+            }

+        }

+

+        return output;

+    }

+

+    public int add (String str, Token token) {

+        int i;

+

+        i = len;

+        //

+        // Include the NULL character at the end of String

+        //

+        len += str.length() + 1; 

+        al.add(str);

+        alComments.add(token.getPrimaryKeyString());

+

+        return i;

+    }

+}

+

+class SizeTable {

+    private ArrayList<Integer>  al;

+    private ArrayList<String>   alComments;

+    private String              phase;

+    private int                 len;

+    private int             bodyStart;

+    private int             bodyLineNum;

+

+    public SizeTable (String phase) {

+        this.phase = phase;

+        al = new ArrayList<Integer>();

+        alComments = new ArrayList<String>();

+        len = 0;

+        bodyStart = 0;

+        bodyLineNum = 0;

+    }

+

+    public String getTypeDeclaration () {

+        return String.format(PcdDatabase.SizeTableDeclaration, phase);

+    }

+

+    public ArrayList<String> getInstantiation () {

+        ArrayList<String> Output = new ArrayList<String>();

+

+        Output.add("/* SizeTable */");

+        Output.add("{");

+        bodyStart = 2;

+

+        if (al.size() == 0) {

+            Output.add("0");

+        } else {

+            for (int index = 0; index < al.size(); index++) {

+                Integer n = al.get(index);

+                String str = n.toString();

+

+                if (index != (al.size() - 1)) {

+                    str += ",";

+                }

+

+                str += " /* " + alComments.get(index) + " */"; 

+                Output.add(str);

+                bodyLineNum++;

+    

+            }

+        }

+        Output.add("}");

+

+        return Output;

+    }

+

+    public int getBodyStart() {

+        return bodyStart;

+    }

+

+    public int getBodyLineNum () {

+        return bodyLineNum;

+    }

+

+    public int add (Token token) {

+        int index = len;

+

+        len++; 

+        al.add(token.datumSize);

+        alComments.add(token.getPrimaryKeyString());

+

+        return index;

+    }

+    

+    private int getDatumSize(Token token) {

+        /*

+        switch (token.datumType) {

+        case Token.DATUM_TYPE.UINT8:

+            return 1;

+        default:

+            return 0;

+        }

+        */

+        return 0;

+    }

+

+    public int getTableLen () {

+        return al.size() == 0 ? 1 : al.size();

+    }

+

+}

+

+class GuidTable {

+    private ArrayList<UUID> al;

+    private ArrayList<String> alComments;

+    private String          phase;

+    private int             len;

+    private int             bodyStart;

+    private int             bodyLineNum;

+

+    public GuidTable (String phase) {

+        this.phase = phase;

+        al = new ArrayList<UUID>();

+        alComments = new ArrayList<String>();

+        len = 0;

+        bodyStart = 0;

+        bodyLineNum = 0;

+    }

+

+    public String getSizeMacro () {

+        return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());

+    }

+

+    private int getSize () {

+        return (al.size() == 0)? 1 : al.size();

+    }

+

+    public String getExistanceMacro () {

+        return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");

+    }

+

+    public String getTypeDeclaration () {

+        return String.format(PcdDatabase.GuidTableDeclaration, phase);

+    }

+

+    private String getUuidCString (UUID uuid) {

+        String[]  guidStrArray;

+

+        guidStrArray =(uuid.toString()).split("-");

+

+        return String.format("{ 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } }",

+                                         guidStrArray[0],

+                                         guidStrArray[1],

+                                         guidStrArray[2],

+                                        (guidStrArray[3].substring(0, 2)),

+                                        (guidStrArray[3].substring(2, 4)),

+                                        (guidStrArray[4].substring(0, 2)),

+                                        (guidStrArray[4].substring(2, 4)),

+                                        (guidStrArray[4].substring(4, 6)),

+                                        (guidStrArray[4].substring(6, 8)),

+                                        (guidStrArray[4].substring(8, 10)),

+                                        (guidStrArray[4].substring(10, 12))

+                                        );

+    }

+

+    public ArrayList<String> getInstantiation () {

+        ArrayList<String> Output = new ArrayList<String>();

+

+        Output.add("/* GuidTable */");

+        Output.add("{");

+        bodyStart = 2;

+

+        if (al.size() == 0) {

+            Output.add(getUuidCString(new UUID(0, 0)));

+        }

+        

+        for (Object u : al) {

+            UUID uuid = (UUID)u;

+            String str = getUuidCString(uuid);

+

+            if (al.indexOf(u) != (al.size() - 1)) {

+                str += ",";

+            }

+            Output.add(str);

+            bodyLineNum++;

+

+        }

+        Output.add("}");

+

+        return Output;

+    }

+

+    public int getBodyStart() {

+        return bodyStart;

+    }

+

+    public int getBodyLineNum () {

+        return bodyLineNum;

+    }

+

+    public int add (UUID uuid, String name) {

+        int index = len;

+        //

+        // Include the NULL character at the end of String

+        //

+        len++; 

+        al.add(uuid);

+

+        return index;

+    }

+

+    public int getTableLen () {

+        return al.size() == 0 ? 0 : al.size();

+    }

+

+}

+

+class SkuIdTable {

+    private ArrayList<Integer[]> al;

+    private ArrayList<String>    alComment;

+    private String               phase;

+    private int                  len;

+    private int                   bodyStart;

+    private int                   bodyLineNum;

+

+    public SkuIdTable (String phase) {

+        this.phase = phase;

+        al = new ArrayList<Integer[]>();

+        alComment = new ArrayList<String>();

+        bodyStart = 0;

+        bodyLineNum = 0;

+        len = 0;

+    }

+

+    public String getSizeMacro () {

+        return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());

+    }

+

+    private int getSize () {

+        return (al.size() == 0)? 1 : al.size();

+    }

+

+    public String getExistanceMacro () {

+        return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");

+    }

+

+    public String getTypeDeclaration () {

+        return String.format(PcdDatabase.SkuIdTableDeclaration, phase);

+    }

+

+    public ArrayList<String> getInstantiation () {

+        ArrayList<String> Output = new ArrayList<String> ();

+

+        Output.add("/* SkuIdTable */");

+        Output.add("{");

+        bodyStart = 2;

+

+        if (al.size() == 0) {

+            Output.add("0");

+        }

+        

+        for (int index = 0; index < al.size(); index++) {

+            String str;

+

+            str = "/* " + alComment.get(index) + "*/ ";

+            str += "/* MaxSku */ ";

+

+

+            Integer[] ia = al.get(index);

+

+            str += ia[0].toString() + ", ";

+            for (int index2 = 1; index2 < ia.length; index2++) {

+               str += ia[index2].toString();

+               if (index != al.size() - 1) {

+                   str += ", ";

+               }

+            }

+

+            Output.add(str);

+            bodyLineNum++;

+

+        }

+

+        Output.add("}");

+

+        return Output;

+    }

+

+    public int add (Token token) {

+

+        int index;

+

+        Integer [] skuIds = new Integer[token.maxSkuCount + 1];

+        skuIds[0] = new Integer(token.maxSkuCount);

+        for (index = 1; index < skuIds.length; index++) {

+            skuIds[index] = new Integer(token.skuData.get(index - 1).id);

+        }

+

+        index = len;

+

+        len += skuIds.length; 

+        al.add(skuIds);

+        alComment.add(token.getPrimaryKeyString());

+

+        return index;

+    }

+

+    public int getTableLen () {

+        return al.size() == 0 ? 1 : al.size();

+    }

+

+}

+

+class LocalTokenNumberTable {

+    private ArrayList<String>    al;

+    private ArrayList<String>    alComment;

+    private String               phase;

+    private int                  len;

+

+    public LocalTokenNumberTable (String phase) {

+        this.phase = phase;

+        al = new ArrayList<String>();

+        alComment = new ArrayList<String>();

+

+        len = 0;

+    }

+

+    public String getSizeMacro () {

+    	return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())

+    			+ String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());

+    }

+

+    public int getSize () {

+        return (al.size() == 0)? 1 : al.size();

+    }

+

+    public String getExistanceMacro () {

+        return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");

+    }

+

+    public String getTypeDeclaration () {

+        return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);

+    }

+

+    public ArrayList<String> getInstantiation () {

+        ArrayList<String> output = new ArrayList<String>();

+

+        output.add("/* LocalTokenNumberTable */");

+        output.add("{");

+

+        if (al.size() == 0) {

+            output.add("0");

+        }

+        

+        for (int index = 0; index < al.size(); index++) {

+            String str;

+

+            str = (String)al.get(index);

+

+            str += " /* " + alComment.get(index) + " */ ";

+

+

+            if (index != (al.size() - 1)) {

+                str += ",";

+            }

+

+            output.add(str);

+

+        }

+

+        output.add("}");

+

+        return output;

+    }

+

+    public int add (Token token) {

+        int index = len;

+        String str;

+

+        len++; 

+

+        str =  String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());

+

+        if (token.isStringType()) {

+            str += " | PCD_TYPE_STRING";

+        }

+

+        if (token.skuEnabled) {

+            str += " | PCD_TYPE_SKU_ENABLED";

+        }

+

+        if (token.hiiEnabled) {

+            str += " | PCD_TYPE_HII";

+        }

+

+        if (token.vpdEnabled) {

+            str += " | PCD_TYPE_VPD";

+        }

+        

+        al.add(str);

+        alComment.add(token.getPrimaryKeyString());

+

+        return index;

+    }

+}

+

+class ExMapTable {

+

+    class ExTriplet {

+        public Integer guidTableIdx;

+        public Long exTokenNumber;

+        public Long localTokenIdx;

+    

+        public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {

+            this.guidTableIdx = new Integer(guidTableIdx);

+            this.exTokenNumber = new Long(exTokenNumber);

+            this.localTokenIdx = new Long(localTokenIdx);

+        }

+    }

+

+    private ArrayList<ExTriplet> al;

+    private ArrayList<String>    alComment;

+    private String               phase;

+    private int                  len;

+    private int                   bodyStart;

+    private int                   bodyLineNum;

+    private int                   base;

+

+    public ExMapTable (String phase) {

+        this.phase = phase;

+        al = new ArrayList<ExTriplet>();

+        alComment = new ArrayList<String>();

+        bodyStart = 0;

+        bodyLineNum = 0;

+        len = 0;

+    }

+

+    public String getSizeMacro () {

+        return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())

+             + String.format(PcdDatabase.ExTokenNumber, phase, al.size());

+    }

+

+    private int getSize () {

+        return (al.size() == 0)? 1 : al.size();

+    }

+

+    public String getExistanceMacro () {

+        return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");

+    }

+

+    public String getTypeDeclaration () {

+        return String.format(PcdDatabase.ExMapTableDeclaration, phase);

+    }

+

+    public ArrayList<String> getInstantiation () {

+        ArrayList<String> Output = new ArrayList<String>();

+

+        Output.add("/* ExMapTable */");

+        Output.add("{");

+        bodyStart = 2;

+

+        if (al.size() == 0) {

+            Output.add("{0, 0, 0}");

+        }

+        

+        int index;

+        for (index = 0; index < al.size(); index++) {

+            String str;

+

+            ExTriplet e = (ExTriplet)al.get(index);

+

+            str = "{ " + e.exTokenNumber.toString() + ", ";

+            str += e.localTokenIdx.toString() + ", ";

+            str += e.guidTableIdx.toString();

+

+            str += " /* " + alComment.get(index) + " */";

+

+            if (index != al.size() - 1) {

+                str += ",";

+            }

+

+            Output.add(str);

+            bodyLineNum++;

+

+        }

+

+        Output.add("}");

+

+        return Output;

+    }

+

+    public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {

+        int index = len;

+

+        len++; 

+        al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));

+        alComment.add(name);

+

+        return index;

+    }

+

+    public int getTableLen () {

+        return al.size() == 0 ? 1 : al.size();

+    }

+

+}

+

+class PcdDatabase {

+

+    public final static String ExMapTableDeclaration            = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";

+    public final static String GuidTableDeclaration             = "EFI_GUID          GuidTable[%s_GUID_TABLE_SIZE];\r\n";

+    public final static String LocalTokenNumberTableDeclaration = "UINT32            LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";

+    public final static String StringTableDeclaration           = "UINT16            StringTable[%s_STRING_TABLE_SIZE];\r\n";

+    public final static String SizeTableDeclaration             = "UINT16            SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";

+    public final static String SkuIdTableDeclaration              = "UINT8             SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";

+

+

+    public final static String ExMapTableSizeMacro              = "#define %s_EXMAPPING_TABLE_SIZE  %d\r\n";

+    public final static String ExTokenNumber                    = "#define %s_EX_TOKEN_NUMBER       %d\r\n";

+    public final static String GuidTableSizeMacro               = "#define %s_GUID_TABLE_SIZE         %d\r\n";

+    public final static String LocalTokenNumberTableSizeMacro   = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE            %d\r\n";

+    public final static String LocalTokenNumberSizeMacro   		= "#define %s_LOCAL_TOKEN_NUMBER            %d\r\n";

+    public final static String StringTableSizeMacro             = "#define %s_STRING_TABLE_SIZE       %d\r\n";

+    public final static String SkuIdTableSizeMacro              = "#define %s_SKUID_TABLE_SIZE        %d\r\n";

+

+

+    public final static String ExMapTableExistenceMacro         = "#define %s_EXMAP_TABLE_EMPTY    %s\r\n"; 

+    public final static String GuidTableExistenceMacro          = "#define %s_GUID_TABLE_EMPTY     %s\r\n";

+    public final static String DatabaseExistenceMacro           = "#define %s_DATABASE_EMPTY       %s\r\n";

+    public final static String StringTableExistenceMacro        = "#define %s_STRING_TABLE_EMPTY   %s\r\n";

+    public final static String SkuTableExistenceMacro           = "#define %s_SKUID_TABLE_EMPTY    %s\r\n";

+

+    public final static String offsetOfSkuHeadStrTemplate       = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";

+    public final static String offsetOfStrTemplate              = "offsetof(%s_PCD_DATABASE, %s.%s)";

+

+    private StringTable stringTable;

+    private GuidTable   guidTable;

+    private LocalTokenNumberTable localTokenNumberTable;

+    private SkuIdTable  skuIdTable;

+    private SizeTable   sizeTable;

+    private ExMapTable  exMapTable;

+

+    private ArrayList<Token> alTokens;

+    private String phase;

+    private int assignedTokenNumber;

+    

+    //

+    // After Major changes done to the PCD

+    // database generation class PcdDatabase

+    // Please increment the version and please

+    // also update the version number in PCD

+    // service PEIM and DXE driver accordingly.

+    //

+    private final int version = 1;

+

+    private String hString;

+    private String cString;

+

+

+    class AlignmentSizeComp implements Comparator<Token> {

+        public int compare (Token a, Token b) {

+            return getAlignmentSize(b) 

+                    - getAlignmentSize(a);

+        }

+    }

+

+    public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {

+       phase = exePhase;

+

+       stringTable = new StringTable(phase);

+       guidTable = new GuidTable(phase);

+       localTokenNumberTable = new LocalTokenNumberTable(phase);

+       skuIdTable = new SkuIdTable(phase);

+       sizeTable = new SizeTable(phase);

+       exMapTable = new ExMapTable(phase); 

+

+       assignedTokenNumber = startLen;

+       this.alTokens = alTokens;

+    }

+

+    private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {

+        for (int i = 0; i < alTokens.size(); i++) {

+            Token t = (Token)alTokens.get(i);

+            if (t.hasDefaultValue()) {

+                initTokens.add(t);

+            } else {

+                uninitTokens.add(t);

+            }

+        }

+

+        return;

+    }

+

+    private int getAlignmentSize (Token token) {

+        if (token.hiiEnabled) {

+            return 2;

+        }

+

+        if (token.vpdEnabled) {

+            return 4;

+        }

+

+        if (token.isStringType()) {

+            return 2;

+        }

+

+        switch (token.datumType) {

+            case UINT8:

+                return 1;

+            case UINT16:

+                return 2;

+            case UINT32:

+                return 4;

+            case UINT64:

+                return 8;

+            case POINTER:

+                return 1;

+            case BOOLEAN:

+                return 1;

+            }

+            return 1;

+     }

+

+    public String getCString () {

+        return cString;

+    }

+

+    public String getHString () {

+        return hString;

+    }

+

+     public void genCode () {

+

+        final String newLine                        = "\r\n";

+        final String declNewLine                    = ";\r\n";

+        final String tab                            = "\t";

+        final String commaNewLine                   = ", \r\n";

+

+        int i;

+        ArrayList<String> decla;

+        ArrayList<String> inst;

+

+        String macroStr   = "";

+        String initDeclStr = "";

+        String initInstStr = "";

+        String uninitDeclStr = "";

+

+        List<Token> initTokens = new ArrayList<Token> ();

+        List<Token> uninitTokens = new ArrayList<Token> ();

+        

+        HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();

+        HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();

+

+        getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);

+

+        //

+        // Generate Structure Declaration for PcdTokens without Default Value

+        // PEI_PCD_DATABASE_INIT

+        //

+        java.util.Comparator<Token> comparator = new AlignmentSizeComp();

+        java.util.Collections.sort(initTokens, comparator);

+        initCode = processTokens(initTokens);

+

+        //

+        // Generate Structure Declaration for PcdTokens without Default Value

+        // PEI_PCD_DATABASE_UNINIT

+        //

+        java.util.Collections.sort(uninitTokens, comparator);

+        uninitCode = processTokens(uninitTokens);

+

+        //

+        // Generate size info Macro for all Tables

+        //

+        macroStr += guidTable.getSizeMacro();

+        macroStr += stringTable.getSizeMacro();

+        macroStr += skuIdTable.getSizeMacro();

+        macroStr += localTokenNumberTable.getSizeMacro();

+        macroStr += exMapTable.getSizeMacro();

+

+        //

+        // Generate existance info Macro for all Tables

+        //

+        macroStr += guidTable.getExistanceMacro();

+        macroStr += stringTable.getExistanceMacro();

+        macroStr += skuIdTable.getExistanceMacro();

+        macroStr += localTokenNumberTable.getExistanceMacro();

+        macroStr += exMapTable.getExistanceMacro();

+

+        //

+        // Generate Structure Declaration for PcdTokens with Default Value

+        // for example PEI_PCD_DATABASE_INIT

+        //

+        initDeclStr += "typedef struct {" + newLine;

+            {

+                initDeclStr += tab + exMapTable.getTypeDeclaration();

+                initDeclStr += tab + guidTable.getTypeDeclaration();

+                initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();

+                initDeclStr += tab + stringTable.getTypeDeclaration();

+                initDeclStr += tab + sizeTable.getTypeDeclaration();

+                initDeclStr += tab + skuIdTable.getTypeDeclaration();

+                if (phase.equalsIgnoreCase("PEI")) {

+                    initDeclStr += tab + "SKU_ID            SystemSkuId;" + newLine;

+                }

+

+                decla = initCode.get(new String("Declaration"));

+                for (i = 0; i < decla.size(); i++)  {

+                    initDeclStr += tab + decla.get(i) + declNewLine;

+                }

+

+                //

+                // Generate Structure Declaration for PcdToken with SkuEnabled

+                //

+                decla = initCode.get("DeclarationForSku");

+

+                for (i = 0; i < decla.size(); i++) {

+                    initDeclStr += tab + decla.get(i) + declNewLine;

+                }

+            }

+        initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);

+

+        //

+        // Generate MACRO for structure intialization of PCDTokens with Default Value

+        // The sequence must match the sequence of declaration of the memembers in the structure

+        String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());

+        initInstStr +=  tmp + newLine;

+        initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;

+        initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;

+        initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine; 

+        initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;

+        initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;

+        initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;

+        //

+        // For SystemSkuId

+        //

+        if (phase.equalsIgnoreCase("PEI")) {

+            initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;

+        }

+

+        inst = initCode.get("Instantiation");

+        for (i = 0; i < inst.size(); i++) {

+            initInstStr += tab + inst.get(i) + commaNewLine;

+        }

+

+        inst = initCode.get("InstantiationForSku");

+        for (i = 0; i < inst.size(); i++) {

+            initInstStr += tab + inst.get(i);

+            if (i != inst.size() - 1) {

+                initInstStr += commaNewLine;

+            }

+        }

+

+        initInstStr += "};";

+

+        uninitDeclStr += "typedef struct {" + newLine;

+            {

+                decla = uninitCode.get("Declaration");

+                if (decla.size() == 0) {

+                    uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;

+                } else {

+    

+                    for (i = 0; i < decla.size(); i++) {

+                        uninitDeclStr += tab + decla.get(i) + declNewLine;

+                    }

+    

+                    decla = uninitCode.get("DeclarationForSku");

+    

+                    for (i = 0; i < decla.size(); i++) {

+                        uninitDeclStr += tab + decla.get(i) + declNewLine;

+                    }

+                }

+            }

+        uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);

+

+        cString = initInstStr + newLine;

+        hString = macroStr      + newLine  

+              + initDeclStr   + newLine

+              + uninitDeclStr + newLine

+              + newLine;

+        

+        hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION			%d", phase, version);

+

+    }

+

+    private String genInstantiationStr (ArrayList<String> alStr) {

+        String str = "";

+        for (int i = 0; i< alStr.size(); i++) {

+            str += "\t" + alStr.get(i);

+            if (i != alStr.size() - 1) {

+                str += "\r\n";

+            }

+        }

+

+        return str;

+    }

+

+    private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) {

+

+        HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();

+

+        ArrayList<String> decl = new ArrayList<String>();

+        ArrayList<String> declForSkuEnableType = new ArrayList<String>();

+        ArrayList<String> inst = new ArrayList<String>();

+        ArrayList<String> instForSkuEnableType = new ArrayList<String>();

+

+        for (int index = 0; index < alToken.size(); index++) {

+            Token token = alToken.get(index);

+

+            if (token.skuEnabled) {

+                //

+                // BugBug: Schema only support Data type now

+                //

+                int tableIdx;

+

+                tableIdx = skuIdTable.add(token);

+

+                decl.add(getSkuEnabledTypeDeclaration(token));

+                if (token.hasDefaultValue()) {

+                    inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx)); 

+                }

+

+                declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));

+                if (token.hasDefaultValue()) {

+                    instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));

+                }

+

+            } else {

+                if (token.hiiEnabled) {

+                    decl.add(getVariableEnableTypeDeclaration(token));

+                    inst.add(getVariableEnableInstantiation(token));

+                } else if (token.vpdEnabled) {

+                    decl.add(getVpdEnableTypeDeclaration(token));

+                    inst.add(getVpdEnableTypeInstantiation(token));

+                } else if (token.isStringType()) {

+                    decl.add(getStringTypeDeclaration(token));

+                    inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));

+                }

+                else {

+                    decl.add(getDataTypeDeclaration(token));

+                    if (token.hasDefaultValue()) {

+                        inst.add(getDataTypeInstantiation(token));

+                    }

+                }

+            }

+

+            sizeTable.add(token);

+            localTokenNumberTable.add(token);

+            token.tokenNumber = assignedTokenNumber++;

+

+        }

+

+        map.put("Declaration",  decl);

+        map.put("DeclarationForSku", declForSkuEnableType);

+        map.put("Instantiation", inst);

+        map.put("InstantiationForSku", instForSkuEnableType);

+

+        return map;

+    }

+

+    private String getSkuEnabledTypeDeclaration (Token token) {

+        return String.format("SKU_HEAD %s;\r\n", token.getPrimaryKeyString());

+    }

+

+    private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {

+

+        String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());

+        return String.format("{ %s, %d }", offsetof, SkuTableIdx);

+    }

+

+    private String getDataTypeDeclarationForSkuEnabled (Token token) {

+        String typeStr = "";

+

+        if (token.datumType == Token.DATUM_TYPE.UINT8) {

+            typeStr = "UINT8 %s_%s[%d];\r\n";

+        } else if (token.datumType == Token.DATUM_TYPE.UINT16) {

+            typeStr = "UINT16 %s_%s[%d];\r\n";

+        } else if (token.datumType == Token.DATUM_TYPE.UINT32) {

+            typeStr = "UINT32 %s_%s[%d];\r\n";

+        } else if (token.datumType == Token.DATUM_TYPE.UINT64) {

+            typeStr = "UINT64 %s_%s[%d];\r\n";

+        } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {

+            typeStr = "BOOLEAN %s_%s[%d];\r\n";

+        } else if (token.datumType == Token.DATUM_TYPE.POINTER) {

+            return String.format("UINT8 %s_s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);

+        } 

+

+        return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.maxSkuCount);

+

+    }

+

+    private String getDataTypeInstantiationForSkuEnabled (Token token) {

+        String str = "";

+

+        if (token.datumType == Token.DATUM_TYPE.POINTER) {

+            return String.format("UINT8 %s_s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);

+        } else {

+            str = "{ ";

+            for (int idx = 0; idx < token.maxSkuCount; idx++) {

+                str += token.skuData.get(idx).toString();

+                if (idx != token.maxSkuCount - 1) {

+                    str += ", ";

+                }

+            }

+            str += "}";

+

+            return str;

+        }

+

+    }

+

+    private String getDataTypeInstantiation (Token token) {

+

+        if (token.datumType == Token.DATUM_TYPE.POINTER) {

+            return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());

+        } else {

+            return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());

+        }

+    }

+

+

+    private String getDataTypeDeclaration (Token token) {

+

+        String typeStr = "";

+

+        if (token.datumType == Token.DATUM_TYPE.UINT8) {

+            typeStr = "UINT8";

+        } else if (token.datumType == Token.DATUM_TYPE.UINT16) {

+            typeStr = "UINT16";

+        } else if (token.datumType == Token.DATUM_TYPE.UINT32) {

+            typeStr = "UINT32";

+        } else if (token.datumType == Token.DATUM_TYPE.UINT64) {

+            typeStr = "UINT64";

+        } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {

+            typeStr = "BOOLEAN";

+        } else if (token.datumType == Token.DATUM_TYPE.POINTER) {

+            return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);

+        } else {

+        }

+

+        return String.format("%s    %s", typeStr, token.getPrimaryKeyString());

+    }

+

+    private String getVpdEnableTypeDeclaration (Token token) {

+        return String.format("VPD_HEAD %s", token.getPrimaryKeyString());

+    }

+

+    private String getVpdEnableTypeInstantiation (Token token) {

+        return String.format("{ %d } /* %s */", token.vpdOffset,

+                                                token.getPrimaryKeyString());

+    }

+

+    private String getStringTypeDeclaration (Token token) {

+        return String.format("UINT16  %s", token.getPrimaryKeyString());

+    }

+

+    private String getStringTypeInstantiation (int StringTableIdx, Token token) {

+        return String.format ("%d /* %s */", StringTableIdx,

+                                             token.getPrimaryKeyString()); 

+    }

+

+

+    private String getVariableEnableTypeDeclaration (Token token) {

+      return String.format("VARIABLE_HEAD  %s", token.getPrimaryKeyString());

+    }

+

+    private String getVariableEnableInstantiation (Token token) {

+        return String.format("{ %d, %d, %d } /* %s */", guidTable.add(token.variableGuid, token.getPrimaryKeyString()),

+                                                        stringTable.add(token.variableName, token),

+                                                        token.variableOffset, 

+                                                        token.getPrimaryKeyString());

+    }

+

+    public int getTotalTokenNumber () {

+        return sizeTable.getTableLen();

+    }

+

+    public static String getPcdDatabaseCommonDefinitions () 

+        throws EntityException {

+

+        String retStr = "";

+        try {

+            File file = new File(GlobalData.getWorkspacePath() + File.separator + 

+                                 "Tools" + File.separator + 

+                                 "Conf" + File.separator +

+                                 "Pcd" + File.separator +

+                                 "PcdDatabaseCommonDefinitions.sample");

+            FileReader reader = new FileReader(file);

+            BufferedReader  in = new BufferedReader(reader);

+            String str;

+            while ((str = in.readLine()) != null) {

+                retStr = retStr +"\r\n" + str;

+            }

+        } catch (Exception ex) {

+            throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");

+        }

+

+        return retStr;

+    }

+

+    public static String getPcdDxeDatabaseDefinitions () 

+        throws EntityException {

+

+        String retStr = "";

+        try {

+            File file = new File(GlobalData.getWorkspacePath() + File.separator + 

+                                 "Tools" + File.separator + 

+                                 "Conf" + File.separator +

+                                 "Pcd" + File.separator +

+                                 "PcdDatabaseDxeDefinitions.sample");

+            FileReader reader = new FileReader(file);

+            BufferedReader  in = new BufferedReader(reader);

+            String str;

+            while ((str = in.readLine()) != null) {

+                retStr = retStr +"\r\n" + str;

+            }

+        } catch (Exception ex) {

+            throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");

+        }

+

+        return retStr;

+    }

+

+    public static String getPcdPeiDatabaseDefinitions () 

+        throws EntityException {

+

+        String retStr = "";

+        try {

+            File file = new File(GlobalData.getWorkspacePath() + File.separator + 

+                                 "Tools" + File.separator + 

+                                 "Conf" + File.separator +

+                                 "Pcd" + File.separator +

+                                 "PcdDatabasePeiDefinitions.sample");

+            FileReader reader = new FileReader(file);

+            BufferedReader  in = new BufferedReader(reader);

+            String str;

+            while ((str = in.readLine()) != null) {

+                retStr = retStr +"\r\n" + str;

+            }

+        } catch (Exception ex) {

+            throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");

+        }

+

+        return retStr;

+    }

+

+}

+

+class ModuleInfo {

+    public ModuleSADocument.ModuleSA module;

+    public UsageInstance.MODULE_TYPE type;

+

+    public ModuleInfo (ModuleSADocument.ModuleSA module, UsageInstance.MODULE_TYPE type) {

+        this.module = module;

+        this.type   = type;

+    }

+}

+

+/** This action class is to collect PCD information from MSA, SPD, FPD xml file.

+    This class will be used for wizard and build tools, So it can *not* inherit

+    from buildAction or UIAction.

+**/

+public class CollectPCDAction {

+    /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.

+    private MemoryDatabaseManager dbManager;

+

+    /// Workspacepath hold the workspace information.

+    private String                workspacePath;

+

+    /// FPD file is the root file. 

+    private String                fpdFilePath;

+

+    /// Message level for CollectPCDAction.

+    private int                   originalMessageLevel;

+

+    /// Cache the fpd docment instance for private usage.

+    private FrameworkPlatformDescriptionDocument fpdDocInstance;

+

+    /**

+      Set WorkspacePath parameter for this action class.

+

+      @param workspacePath parameter for this action

+    **/

+    public void setWorkspacePath(String workspacePath) {

+        this.workspacePath = workspacePath;

+    }

+

+    /**

+      Set action message level for CollectPcdAction tool.

+

+      The message should be restored when this action exit.

+

+      @param actionMessageLevel parameter for this action

+    **/

+    public void setActionMessageLevel(int actionMessageLevel) {

+        originalMessageLevel       = ActionMessage.messageLevel;

+        ActionMessage.messageLevel = actionMessageLevel;

+    }

+

+    /**

+      Set FPDFileName parameter for this action class.

+

+      @param fpdFilePath    fpd file path

+    **/

+    public void setFPDFilePath(String fpdFilePath) {

+        this.fpdFilePath = fpdFilePath;

+    }

+

+    /**

+      Common function interface for outer.

+      

+      @param workspacePath The path of workspace of current build or analysis.

+      @param fpdFilePath   The fpd file path of current build or analysis.

+      @param messageLevel  The message level for this Action.

+      

+      @throws  Exception The exception of this function. Because it can *not* be predict

+                         where the action class will be used. So only Exception can be throw.

+      

+    **/

+    public void perform(String workspacePath, String fpdFilePath, 

+                        int messageLevel) throws Exception {

+        setWorkspacePath(workspacePath);

+        setFPDFilePath(fpdFilePath);

+        setActionMessageLevel(messageLevel);

+        checkParameter();

+        execute();

+        ActionMessage.messageLevel = originalMessageLevel;

+    }

+

+    /**

+      Core execution function for this action class.

+     

+      This function work flows will be:

+      1) Collect and prepocess PCD information from FPD file, all PCD

+      information will be stored into memory database.

+      2) Generate 3 strings for

+        a) All modules using Dynamic(Ex) PCD entry.(Token Number)

+        b) PEI PCDDatabase (C Structure) for PCD Service PEIM.

+        c) DXE PCD Database (C structure) for PCD Service DXE.

+                                

+      

+      @throws  EntityException Exception indicate failed to execute this action.

+      

+    **/

+    private void execute() throws EntityException {

+        //

+        // Get memoryDatabaseManager instance from GlobalData.

+        // The memoryDatabaseManager should be initialized for whatever build

+        // tools or wizard tools

+        //

+        if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {

+            throw new EntityException("The instance of PCD memory database manager is null");

+        }

+

+        //

+        // Collect all PCD information defined in FPD file.

+        // Evenry token defind in FPD will be created as an token into 

+        // memory database.

+        //

+        createTokenInDBFromFPD();

+

+        

+        //

+        // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver

+        // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.

+        //

+        genPcdDatabaseSourceCode ();

+        

+    }

+

+    /**

+      This function generates source code for PCD Database.

+     

+      @param void

+      @throws EntityException  If the token does *not* exist in memory database.

+

+    **/

+    private void genPcdDatabaseSourceCode()

+        throws EntityException {

+        String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();

+

+        ArrayList<Token> alPei = new ArrayList<Token> ();

+        ArrayList<Token> alDxe = new ArrayList<Token> ();

+

+        dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);

+        PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);

+        pcdPeiDatabase.genCode();

+        dbManager.PcdPeimHString        = PcdCommonHeaderString + pcdPeiDatabase.getHString()

+                                            + PcdDatabase.getPcdPeiDatabaseDefinitions();

+        dbManager.PcdPeimCString        = pcdPeiDatabase.getCString();

+

+        PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe, 

+                                                      "DXE",

+                                                      alPei.size()

+                                                      );

+        pcdDxeDatabase.genCode();

+        dbManager.PcdDxeHString   = dbManager.PcdPeimHString + pcdDxeDatabase.getHString()

+                                      + PcdDatabase.getPcdDxeDatabaseDefinitions();

+        dbManager.PcdDxeCString   = pcdDxeDatabase.getCString();

+    }

+

+    /**

+      Get component array from FPD.

+      

+      This function maybe provided by some Global class.

+      

+      @return List<ModuleInfo> the component array.

+      

+     */

+    private List<ModuleInfo> getComponentsFromFPD() 

+        throws EntityException {

+        HashMap<String, XmlObject>  map         = new HashMap<String, XmlObject>();

+        List<ModuleInfo>            allModules  = new ArrayList<ModuleInfo>();

+        ModuleInfo                  current     = null;

+        int                         index       = 0;

+        org.tianocore.Components    components  = null;

+        FrameworkModulesDocument.FrameworkModules fModules = null;

+        java.util.List<ModuleSADocument.ModuleSA> modules  = null;

+        

+

+        if (fpdDocInstance == null) {

+            try {

+                fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));

+            } catch(IOException ioE) {

+                throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());

+            } catch(XmlException xmlE) {

+                throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());

+            }

+

+        }

+

+        //

+        // Check whether FPD contians <FramworkModules>

+        // 

+        fModules = fpdDocInstance.getFrameworkPlatformDescription().getFrameworkModules();

+        if (fModules == null) {

+            return null;

+        }

+

+        //

+        // BUGBUG: The following is work around code, the final component type should be get from

+        // GlobalData class.

+        // 

+        components = fModules.getSEC();

+        if (components != null) {

+            modules = components.getModuleSAList();

+            for (index = 0; index < modules.size(); index ++) {

+                allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.SEC));

+            }

+        }

+

+        components = fModules.getPEICORE();

+        if (components != null) {

+            modules = components.getModuleSAList();

+            for (index = 0; index < modules.size(); index ++) {

+                allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEI_CORE));

+            }

+        }

+

+        components = fModules.getPEIM();

+        if (components != null) {

+            modules = components.getModuleSAList();

+            for (index = 0; index < modules.size(); index ++) {

+                allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEIM));

+            }

+        }

+

+        components = fModules.getDXECORE();

+        if (components != null) {

+            modules = components.getModuleSAList();

+            for (index = 0; index < modules.size(); index ++) {

+                allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_CORE));

+            }

+        }

+

+        components = fModules.getDXEDRIVERS();

+        if (components != null) {

+            modules = components.getModuleSAList();

+            for (index = 0; index < modules.size(); index ++) {

+                allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_DRIVERS));

+            }

+        }

+

+        components = fModules.getOTHERCOMPONENTS();

+        if (components != null) {

+            modules = components.getModuleSAList();

+            for (index = 0; index < modules.size(); index ++) {

+                allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.OTHER_COMPONENTS));

+            }

+        }

+        

+        return allModules;

+    }

+

+    /**

+      Create token instance object into memory database, the token information

+      comes for FPD file. Normally, FPD file will contain all token platform 

+      informations.

+      

+      @return FrameworkPlatformDescriptionDocument   The FPD document instance for furture usage.

+      

+      @throws EntityException                        Failed to parse FPD xml file.

+      

+    **/

+    private void createTokenInDBFromFPD() 

+        throws EntityException {

+        int                                 index             = 0;

+        int                                 index2            = 0;

+        int                                 pcdIndex          = 0;

+        List<PcdBuildData>                  pcdBuildDataArray = new ArrayList<PcdBuildData>();

+        PcdBuildData                        pcdBuildData      = null;

+        Token                               token             = null;

+        UUID                                nullUUID          = new UUID(0,0);

+        UUID                                platformTokenSpace= nullUUID;

+        SkuInstance                         skuInstance       = null;

+        int                                 skuIndex          = 0;

+        List<ModuleInfo>                    modules           = null;

+        String                              primaryKey        = null;

+        PcdBuildData.SkuData[]              skuDataArray      = null;

+        String                              exceptionString   = null;

+        UsageInstance                       usageInstance     = null;

+        String                              primaryKey1       = null;

+        String                              primaryKey2       = null;

+        boolean                             isDuplicate       = false;

+        java.util.List<java.lang.String>    tokenGuidStringArray = null;

+

+        //

+        // Get all <ModuleSA> from FPD file.

+        // 

+        modules = getComponentsFromFPD();

+

+        if (modules == null) {

+            throw new EntityException("No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");

+        }

+

+        //

+        // Loop all modules to process <PcdBuildDeclarations> for each module.

+        // 

+        for (index = 0; index < modules.size(); index ++) {

+            isDuplicate =  false;

+            for (index2 = 0; index2 < index; index2 ++) {

+                //

+                // BUGBUG: For transition schema, we can *not* get module's version from 

+                // <ModuleSAs>, It is work around code.

+                // 

+                primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).module.getModuleName(), 

+                                                          translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()),

+                                                          modules.get(index).module.getPackageName(), 

+                                                          translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()), 

+                                                          modules.get(index).module.getArch().toString(),

+                                                          null);

+                primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(), 

+                                                          translateSchemaStringToUUID(modules.get(index2).module.getModuleGuid()), 

+                                                          modules.get(index2).module.getPackageName(), 

+                                                          translateSchemaStringToUUID(modules.get(index2).module.getPackageGuid()), 

+                                                          modules.get(index2).module.getArch().toString(), 

+                                                          null);

+                if (primaryKey1.equalsIgnoreCase(primaryKey2)) {

+                    isDuplicate = true;

+                    break;

+                }

+            }

+

+            if (isDuplicate) {

+                continue;

+            }

+

+            if (modules.get(index).module.getPcdBuildDeclarations() == null) {

+                continue;

+            }

+            pcdBuildDataArray = modules.get(index).module.getPcdBuildDeclarations().getPcdBuildDataList();

+            if (pcdBuildDataArray == null) {

+                continue;

+            }

+            if (pcdBuildDataArray.size() == 0) {

+                continue;

+            }

+

+            //

+            // Loop all Pcd entry for a module and add it into memory database.

+            // 

+            for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {

+                pcdBuildData = pcdBuildDataArray.get(pcdIndex);

+                primaryKey   = Token.getPrimaryKeyString(pcdBuildData.getCName(),

+                                                         translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));

+

+

+                if (dbManager.isTokenInDatabase(primaryKey)) {

+                    //

+                    // If the token is already exist in database, do some necessary checking

+                    // and add a usage instance into this token in database

+                    // 

+                    token = dbManager.getTokenByKey(primaryKey);

+

+                    //

+                    // Checking for DatumSize

+                    // 

+                    if (token.datumSize != pcdBuildData.getDatumSize()) {

+                        exceptionString = String.format("The datum size of PCD entry %s is %d, which is different with %d defined in before!",

+                                                        pcdBuildData.getCName(),  pcdBuildData.getDatumSize(), token.datumSize);

+                        throw new EntityException(exceptionString);

+                    }

+

+                    //

+                    // checking for DatumType

+                    // 

+                    if (token.datumType != Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString())) {

+                        exceptionString = String.format("The datum type of PCD entry %s is %s, which is different with  %s defined in before!",

+                                                        pcdBuildData.getCName(), 

+                                                        pcdBuildData.getDatumType().toString(), 

+                                                        Token.getStringOfdatumType(token.datumType));

+                        throw new EntityException(exceptionString);

+                    }

+                } else {

+                    //

+                    // If the token is not in database, create a new token instance and add

+                    // a usage instance into this token in database.

+                    // 

+                    token = new Token(pcdBuildData.getCName(), 

+                                      translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));

+

+                    token.datum         = pcdBuildData.getDefaultValue();

+                    token.pcdType       = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());

+                    token.datumType     = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());

+                    token.datumSize     = pcdBuildData.getDatumSize();

+                    token.skuId         = Integer.decode(pcdBuildData.getSkuId());

+

+                    if (pcdBuildData.getToken() == null) {

+                        exceptionString = String.format("In FPD file, No <TokenNumber> defined for PCD entry %s in module %s",

+                                                        token.cName,

+                                                        modules.get(index).module.getModuleName());

+                        throw new EntityException(exceptionString);

+                    }

+                    token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());

+

+                    if ((token.pcdType == Token.PCD_TYPE.DYNAMIC) ||

+                        (token.pcdType == Token.PCD_TYPE.DYNAMIC_EX)) {

+                        updateDynamicInformation(modules.get(index).module.getModuleName(),  token);

+                    }

+

+                    dbManager.addTokenToDatabase(primaryKey, token);

+                }

+

+                //

+                // Create an usage instance for this token

+                // 

+                usageInstance = new UsageInstance(token, 

+                                                  Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()),

+                                                  modules.get(index).module.getModuleName(), 

+                                                  translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()),

+                                                  modules.get(index).module.getPackageName(),

+                                                  translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()),

+                                                  modules.get(index).type, 

+                                                  Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()),

+                                                  modules.get(index).module.getArch().toString(), 

+                                                  null,

+                                                  pcdBuildData.getDefaultValue());

+                token.addUsageInstance(usageInstance);

+            }

+        }

+    }

+

+    /**

+       Update dynamic information for PCD entry.

+       

+       Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in

+       FPD file.

+       

+       @param moduleName

+       @param token

+       

+       @return Token

+    **/

+    private Token updateDynamicInformation(String moduleName, Token token) 

+        throws EntityException {

+        PcdDynamicBuildDeclarations                pcdDynamicBuildDescriptions = null;

+        

+        boolean                                    isFound                     = false;            

+        int                                        index                       = 0;

+        String                                     primaryKey                  = null;

+        SkuInstance                                skuInstance                 = null;

+        int                                        skuIndex                    = 0;

+        String                                     exceptionString             = null;

+        PcdDynamicBuildDeclarations.PcdBuildData.SkuData[] skuDataArray             = null;

+        List<PcdDynamicBuildDeclarations.PcdBuildData>     pcdDynamicBuildDataArray = null;

+

+        //

+        // If FPD document is not be opened, open and initialize it.

+        // 

+        if (fpdDocInstance == null) {

+            try {

+                fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));

+            } catch(IOException ioE) {

+                throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());

+            } catch(XmlException xmlE) {

+                throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());

+            }

+        }

+

+        pcdDynamicBuildDescriptions = fpdDocInstance.getFrameworkPlatformDescription().getPcdDynamicBuildDeclarations();

+        if (pcdDynamicBuildDescriptions == null) {

+            throw new EntityException(String.format("There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+

+                                                    "PCD entry %s in module %s!",

+                                                    token.cName,

+                                                    moduleName));

+        }

+

+        pcdDynamicBuildDataArray    = pcdDynamicBuildDescriptions.getPcdBuildDataList();

+        if (pcdDynamicBuildDataArray == null) {

+            throw new EntityException(String.format("There are no PcdDynamicBuildData in <PcdDynamicBuildDeclaration> section but contains Dynamic type"+

+                                                    "PCD entry %s in module %s.!",

+                                                    token.cName,

+                                                    moduleName));

+        }

+

+        isFound = false;

+        for (index = 0; index < pcdDynamicBuildDataArray.size(); index ++) {

+            if (pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().size() != 0) {

+                primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(), 

+                                                       translateSchemaStringToUUID(pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().get(0)));

+            } else {

+                primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(), 

+                                                       translateSchemaStringToUUID(null));

+            }

+

+            if (primaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {

+                isFound = true;

+

+                //

+                // For Hii related value

+                // 

+                token.hiiEnabled    = pcdDynamicBuildDataArray.get(index).getHiiEnable();

+                if (token.hiiEnabled) {

+                    token.variableGuid      = Token.getGUIDFromSchemaObject(pcdDynamicBuildDataArray.get(index).getVariableGuid());

+                    if (token.variableGuid == null) {

+                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +

+                                                                "but no <VariableGuid> is found! Please fix the FPD file!",

+                                                                token.cName));

+

+                    }

+                    token.variableName      = pcdDynamicBuildDataArray.get(index).getVariableName();

+                    if (token.variableName == null) {

+                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +

+                                                                "but no <VariableName> is found! Please fix the FPD file!",

+                                                                token.cName));

+                    }

+

+                    if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) {

+                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +

+                                                                "but no <DataOffset> is found! Please fix the FPD file!",

+                                                                token.cName));

+                    }

+                    token.variableOffset    = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset());

+                }

+

+                //

+                // For Vpd related value

+                // 

+                token.vpdEnabled    = pcdDynamicBuildDataArray.get(index).getVpdEnable();

+                if (token.vpdEnabled) {

+                    if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) {

+                        throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, VpdEnable is true" +

+                                                                "but no <DataOffset> is found! Please fix the FPD file!",

+                                                                token.cName));

+                    }

+                    token.vpdOffset         = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset());

+                }

+

+                //

+                // For SkuData

+                // 

+                token.skuEnabled    = pcdDynamicBuildDataArray.get(index).getSkuEnable();

+                if (token.skuEnabled) {

+                    skuDataArray      = (PcdDynamicBuildDeclarations.PcdBuildData.SkuData[])pcdDynamicBuildDataArray.get(index).getSkuDataList().toArray();

+                    token.maxSkuCount = Integer.decode(pcdDynamicBuildDataArray.get(index).getMaxSku());

+                    if (skuDataArray == null) {

+                        exceptionString = String.format("In FPD file, the <SkuEnable> is true for PCD entry %s in module %s, But no any sku data.",

+                                                        token.cName, moduleName);

+                        throw new EntityException(exceptionString);

+                    }

+                    if (token.maxSkuCount != pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray()) {

+                        exceptionString = String.format("In FPD file, <MaxSku> is not equal to the size of <SkuDataArray> for PCD entry %s in module %s",

+                                                        token.cName, moduleName);

+                        throw new EntityException(exceptionString);

+                    }

+

+                    for (skuIndex = 0; skuIndex < pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray(); skuIndex ++) {

+                        skuInstance = new SkuInstance(skuDataArray[skuIndex].getId(),

+                                                      skuDataArray[skuIndex].getValue());

+                        token.skuData.add(skuInstance);

+                    }

+                }

+                break;

+            }

+        }

+        if (!isFound) {

+            exceptionString = String.format("In FPD file, No dynamic PCD data for PCD entry %s in module %s",

+                                            token.cName,

+                                            moduleName);

+            throw new EntityException(exceptionString);

+        }

+

+        return token;

+    }

+

+    /**

+       Translate the schema string to UUID instance.

+       

+       In schema, the string of UUID is defined as following two types string:

+        1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(

+        )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?

+       

+        2) GuidNamingConvention: pattern =

+        [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}

+       

+       This function will convert string and create uuid instance.

+       

+       @param uuidString    UUID string in XML file

+       

+       @return UUID         UUID instance

+    **/

+    private UUID translateSchemaStringToUUID(String uuidString) 

+        throws EntityException {

+        String      temp;

+        String[]    splitStringArray;

+        int         index;

+        int         chIndex;

+        int         chLen;

+

+        if (uuidString == null) {

+            return null;

+        }

+

+        if (uuidString.length() == 0) {

+            return null;

+        }

+

+        //

+        // If the UUID schema string is GuidArrayType type then need translate 

+        // to GuidNamingConvention type at first.

+        // 

+        if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {

+            splitStringArray = uuidString.split("," );

+            if (splitStringArray.length != 11) {

+                throw new EntityException ("Wrong format for UUID string: " + uuidString);

+            }

+

+            //

+            // Remove blank space from these string and remove header string "0x"

+            // 

+            for (index = 0; index < 11; index ++) {

+                splitStringArray[index] = splitStringArray[index].trim();

+                splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());

+            }

+

+            //

+            // Add heading '0' to normalize the string length

+            // 

+            for (index = 3; index < 11; index ++) {

+                chLen = splitStringArray[index].length();

+                for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {

+                    splitStringArray[index] = "0" + splitStringArray[index];

+                }

+            }

+

+            //

+            // construct the final GuidNamingConvention string

+            // 

+            temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",

+                                 splitStringArray[0],

+                                 splitStringArray[1],

+                                 splitStringArray[2],

+                                 splitStringArray[3],

+                                 splitStringArray[4],

+                                 splitStringArray[5],

+                                 splitStringArray[6],

+                                 splitStringArray[7],

+                                 splitStringArray[8],

+                                 splitStringArray[9],

+                                 splitStringArray[10]);

+            uuidString = temp;

+        }

+

+        return UUID.fromString(uuidString);

+    }

+

+    /**

+      check parameter for this action.

+      

+      @throws EntityException  Bad parameter.

+    **/

+    private void checkParameter() throws EntityException {

+        File file = null;

+

+        if((fpdFilePath    == null) ||(workspacePath  == null)) {

+            throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");

+        }

+

+        if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {

+            throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");

+        }

+

+        file = new File(workspacePath);

+        if(!file.exists()) {

+            throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");

+        }

+

+        file = new File(fpdFilePath);

+

+        if(!file.exists()) {

+            throw new EntityException("FPD File " + fpdFilePath + " does not exist!");

+        }

+    }

+

+    /**

+      Test case function

+

+      @param argv  parameter from command line

+    **/

+    public static void main(String argv[]) throws EntityException {

+        CollectPCDAction ca = new CollectPCDAction();

+        ca.setWorkspacePath("M:/ForPcd/edk2");

+        ca.setFPDFilePath("M:/ForPcd/edk2/EdkNt32Pkg/Nt32.fpd");

+        ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);

+        GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",

+                            "M:/ForPcd/edk2");

+        ca.execute();

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
new file mode 100644
index 0000000..04e585b
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
@@ -0,0 +1,449 @@
+/** @file

+  PCDAutoGenAction class.

+

+  This class is to manage how to generate the PCD information into Autogen.c and

+  Autogen.h.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.pcd.action;

+

+import java.io.File;

+import java.util.List;

+import java.util.UUID;

+

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;

+import org.tianocore.build.pcd.entity.Token;

+import org.tianocore.build.pcd.entity.UsageInstance;

+import org.tianocore.build.pcd.exception.BuildActionException;

+import org.tianocore.build.pcd.exception.EntityException;

+

+/** This class is to manage how to generate the PCD information into Autogen.c and

+    Autogen.h.

+**/

+public class PCDAutoGenAction extends BuildAction {

+    ///

+    /// The reference of DBManager in GlobalData class.

+    ///

+    private MemoryDatabaseManager dbManager;

+    ///

+    /// The name of module which is analysised currently.

+    ///

+    private String                moduleName;

+    ///

+    /// The Guid of module which is analyzed currently.

+    /// 

+    private UUID                  moduleGuid;

+    ///

+    /// The name of package whose module is analysized currently.

+    /// 

+    private String                packageName;

+    ///

+    /// The Guid of package whose module is analyszed curretnly.

+    /// 

+    private UUID                  packageGuid;

+    ///

+    /// The arch of current module

+    /// 

+    private String                arch;

+    ///

+    /// The version of current module

+    /// 

+    private String                version;

+    ///

+    /// Wheter current module is PCD emulated driver. It is only for 

+    /// emulated PCD driver and will be kept until PCD IMAGE tool ready.

+    ///

+    private boolean               isEmulatedPCDDriver;

+    ///

+    /// Whether current autogen is for building library used by current module.

+    /// 

+    private boolean               isBuildUsedLibrary;

+    ///

+    /// The generated string for header file.

+    ///

+    private String                hAutoGenString;

+    ///

+    /// The generated string for C code file.

+    ///

+    private String                cAutoGenString;       

+

+    /**

+      Set parameter ModuleName

+  

+      @param moduleName   the module name parameter.

+    **/

+    public void setModuleName(String moduleName) {

+        this.moduleName = moduleName;

+    }

+

+    public void setModuleGuid(UUID moduleGuid) {

+        this.moduleGuid = moduleGuid;

+    }

+

+    public void setPackageName(String packageName) {

+        this.packageName = packageName;

+    }

+

+    public void setPackageGuid(UUID packageGuid) {

+        this.packageGuid = packageGuid;

+    }

+

+    public void setArch(String arch) {

+        this.arch = arch;

+    }

+

+    public void setVersion(String version) {

+        this.version = version;

+    }

+

+    /**

+      Set parameter isEmulatedPCDDriver

+  

+      @param isEmulatedPCDDriver  whether this module is PeiEmulatedPCD driver

+    **/

+    public void setIsEmulatedPCDDriver(boolean isEmulatedPCDDriver) {

+        this.isEmulatedPCDDriver = isEmulatedPCDDriver;

+    }

+

+    public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) {

+        this.isBuildUsedLibrary = isBuildUsedLibrary;

+    }

+

+    /**

+      Get the output of generated string for header file.

+  

+      @return the string of header file for PCD

+    **/

+    public String OutputH() {

+        return hAutoGenString;

+    }

+

+    /**

+      Get the output of generated string for C Code file.

+  

+      @return the string of C code file for PCD

+    **/

+    public String OutputC() {

+        return cAutoGenString;

+    }

+

+    /**

+      Construct function

+  

+      This function mainly initialize some member variable.

+     

+      @param moduleName            Parameter of this action class.

+      @param isEmulatedPCDDriver   Parameter of this action class.

+    **/

+    public PCDAutoGenAction(String  moduleName, 

+                            UUID    moduleGuid, 

+                            String  packageName,

+                            UUID    packageGuid,

+                            String  arch,

+                            String  version,

+                            boolean isEmulatedPCDDriver, 

+                            boolean isBuildUsedLibrary) {

+        dbManager       = null;

+        hAutoGenString  = "";

+        cAutoGenString  = "";

+

+        setIsEmulatedPCDDriver(isEmulatedPCDDriver);

+        setModuleName(moduleName);

+        setModuleGuid(moduleGuid);

+        setPackageName(packageName);

+        setPackageGuid(packageGuid);

+        setArch(arch);

+        setVersion(version);

+        setIsBuildUsedLibrary(isBuildUsedLibrary);

+    }

+

+    /**

+      check the parameter for action class.

+      

+      @throws BuildActionException Bad parameter.

+    **/

+    void checkParameter() throws BuildActionException {

+        if(!isEmulatedPCDDriver &&(moduleName == null)) {

+            throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");

+        }

+

+        if(!isEmulatedPCDDriver && moduleName.length() == 0) {

+            throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");

+        }

+    }

+

+    /**

+      Core execution function for this action class.

+     

+      All PCD information of this module comes from memory dabase. The collection

+      work should be done before this action execution.

+      Currently, we should generated all PCD information(maybe all dynamic) as array 

+      in Pei emulated driver for simulating PCD runtime database. 

+      

+      @throws BuildActionException Failed to execute this aciton class.

+    **/

+    void performAction() throws BuildActionException {

+        ActionMessage.debug(this, 

+                            "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");

+        //

+        // Check the PCD memory database manager is valid.

+        //

+        if(GlobalData.getPCDMemoryDBManager() == null) {

+            throw new BuildActionException("Memory database has not been initlizated!");

+        }

+

+        dbManager = GlobalData.getPCDMemoryDBManager();

+

+        if(dbManager.getDBSize() == 0) {

+            return;

+        }

+

+        ActionMessage.debug(this,

+                            "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");

+

+

+

+        generateAutogenForModule();

+    }

+

+    /**

+      Generate the autogen string for a common module.

+     

+      All PCD information of this module comes from memory dabase. The collection

+      work should be done before this action execution.

+    **/

+    private void generateAutogenForModule()

+    {

+        int                   index;

+        List<UsageInstance>   usageInstanceArray;

+

+        if (!isBuildUsedLibrary) {

+            usageInstanceArray  = dbManager.getUsageInstanceArrayByModuleName(moduleName,

+                                                                              moduleGuid,

+                                                                              packageName,

+                                                                              packageGuid,

+                                                                              arch,

+                                                                              version);

+            dbManager.UsageInstanceContext = usageInstanceArray;

+            dbManager.CurrentModuleName    = moduleName; 

+        } else {

+            usageInstanceArray = dbManager.UsageInstanceContext;

+            //

+            // For building MDE package, although all module are library, but PCD entries of 

+            // these library should be used to autogen.

+            // 

+            if (usageInstanceArray == null) {

+                usageInstanceArray  = dbManager.getUsageInstanceArrayByModuleName(moduleName,

+                                                                                  moduleGuid,

+                                                                                  packageName,

+                                                                                  packageGuid,

+                                                                                  arch,

+                                                                                  version);

+            }

+        }

+

+        if(usageInstanceArray.size() != 0) {

+            //

+            // Add "#include 'PcdLib.h'" for Header file

+            //

+            hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";

+        }

+

+        for(index = 0; index < usageInstanceArray.size(); index ++) {

+            ActionMessage.debug(this,

+                                "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) + 

+                                "]: " + usageInstanceArray.get(index).parentToken.cName);

+            try {

+                usageInstanceArray.get(index).generateAutoGen(isBuildUsedLibrary);

+                hAutoGenString += usageInstanceArray.get(index).getHAutogenStr() + "\r\n";

+                cAutoGenString += usageInstanceArray.get(index).getCAutogenStr() + "\r\n";

+            } catch(EntityException exp) {

+                throw new BuildActionException(exp.getMessage());

+            }

+        }

+

+        //

+        // Work around code, In furture following code should be modified that get 

+        // these information from Uplevel Autogen tools.

+        // 

+        if (moduleName.equalsIgnoreCase("PcdPeim")) {

+            hAutoGenString += dbManager.PcdPeimHString;

+            cAutoGenString += dbManager.PcdPeimCString;

+        } else if (moduleName.equalsIgnoreCase("PcdDxe")) {

+            hAutoGenString += dbManager.PcdDxeHString;

+            cAutoGenString += dbManager.PcdDxeCString;

+        }

+

+        ActionMessage.debug(this,

+                            "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"

+                           );

+        ActionMessage.debug(this,

+                             "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"

+                            );

+    }

+

+    /**

+      Generate unreference token definition string for PCD emulated string. 

+      

+      Maybe some PCD token definition in FPD but not used by any module or library, we 

+      should also generate token definition in autoge.h/autogen.c, because maybe some

+      driver loaded in shell will use this PCD. 

+

+     @param token   The token who want be generated autogen string.

+    

+    **/

+    private void generateUnReferencePcdAutogenString(Token token) {

+        hAutoGenString += String.format("#define _PCD_TOKEN_%s   0x%016x\r\n", 

+                                        token.cName, token.tokenNumber);

+        switch (token.pcdType) {

+        case FEATURE_FLAG:

+            hAutoGenString += String.format(

+                                "#define _PCD_VALUE_%s   %s\r\n", 

+                                token.cName, 

+                                token.datum.toString()

+                                );

+            hAutoGenString += String.format(

+                                "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", 

+                                token.cName

+                                );

+            cAutoGenString += String.format(

+                                "GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",

+                                token.cName,

+                                token.cName

+                                );

+            hAutoGenString += String.format(

+                                "#define _PCD_MODE_%s_%s  _PCD_VALUE_%s\r\n",

+                                Token.GetAutogenDefinedatumTypeString(token.datumType),

+                                token.cName,

+                                token.cName

+                                );

+            break;

+        case FIXED_AT_BUILD:

+            hAutoGenString += String.format(

+                                "#define _PCD_VALUE_%s   %s\r\n", 

+                                token.cName, 

+                                token.datum.toString()

+                                );

+            hAutoGenString += String.format(

+                                "extern const %s _gPcd_FixedAtBuild_%s;\r\n",

+                                Token.getAutogendatumTypeString(token.datumType),

+                                token.cName

+                                );

+            cAutoGenString += String.format(

+                                "GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",

+                                Token.getAutogendatumTypeString(token.datumType),

+                                token.cName,

+                                token.cName

+                                );

+            hAutoGenString += String.format(

+                                "#define _PCD_MODE_%s_%s  _PCD_VALUE_%s\r\n",

+                                Token.GetAutogenDefinedatumTypeString(token.datumType),

+                                token.cName,

+                                token.cName

+                                );

+            break;

+        case PATCHABLE_IN_MODULE:

+            hAutoGenString += String.format(

+                                 "#define _PCD_VALUE_%s   %s\r\n", 

+                                 token.cName, 

+                                 token.datum.toString()

+                                 );

+            hAutoGenString += String.format(

+                                 "extern %s _gPcd_BinaryPatch_%s;\r\n",

+                                 Token.getAutogendatumTypeString(token.datumType),

+                                 token.cName

+                                 );

+            cAutoGenString += String.format(

+                                 "GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n",

+                                 Token.getAutogendatumTypeString(token.datumType),

+                                 token.cName,

+                                 token.cName

+                                 );

+            hAutoGenString += String.format(

+                                 "#define _PCD_MODE_%s_%s  _gPcd_BinaryPatch_%s\r\n",

+                                 Token.GetAutogenDefinedatumTypeString(token.datumType),

+                                 token.cName,

+                                 token.cName

+                                 );

+            break;

+        case DYNAMIC:

+            hAutoGenString += String.format(

+                                "#define _PCD_MODE_%s_%s  LibPcdGet%s(_PCD_TOKEN_%s)\r\n",

+                                Token.GetAutogenDefinedatumTypeString(token.datumType),

+                                token.cName,

+                                Token.getAutogenLibrarydatumTypeString(token.datumType),

+                                token.cName

+                                );

+            break;

+        case DYNAMIC_EX:

+            break;

+        default:

+            ActionMessage.warning(this, 

+                                  "The PCD_TYPE setted by platform is unknown"

+                                  );

+        }

+

+        hAutoGenString += "\r\n";

+        cAutoGenString += "\r\n";

+    }

+        

+    /**

+      Test case function

+

+      @param argv  paramter from command line

+    **/

+    public static void main(String argv[]) {

+

+        String WorkSpace = "M:/ForPcd/edk2";

+        String logFilePath = WorkSpace  + "/MdePkg/MdePkg.fpd";

+

+        //

+        // At first, CollectPCDAction should be invoked to collect

+        // all PCD information from SPD, MSA, FPD.

+        //

+        CollectPCDAction collectionAction = new CollectPCDAction();

+        GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",

+                            WorkSpace);

+

+        try {

+            collectionAction.perform(WorkSpace, 

+                                     logFilePath,

+                                     ActionMessage.MAX_MESSAGE_LEVEL);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+

+        //

+        // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c

+        //

+        PCDAutoGenAction autogenAction = new PCDAutoGenAction("BaseLib",

+                                                              null,

+                                                              null,

+                                                              null,

+                                                              null,

+                                                              null,

+                                                              false,

+                                                              false

+                                                              );

+        autogenAction.execute();

+

+        System.out.println(autogenAction.OutputH());

+        System.out.println("WQWQWQWQWQ");

+        System.out.println(autogenAction.OutputC());

+

+

+        System.out.println (autogenAction.hAutoGenString);

+        System.out.println (autogenAction.cAutoGenString);

+

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java
new file mode 100644
index 0000000..8af8123
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java
@@ -0,0 +1,131 @@
+/** @file

+  ShowPCDDatabase class.

+

+  This class is the action to diplay the PCD database.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.pcd.action;

+

+import java.io.File;

+

+import org.tianocore.build.global.GlobalData;

+import org.tianocore.build.pcd.exception.UIException;

+import org.tianocore.build.pcd.ui.PCDDatabaseFrame;

+

+/** This class is the action to show PCD database.

+**/

+public class ShowPCDDatabaseAction extends UIAction {

+    ///

+    /// The workspace path parameter.

+    ///

+    private String workspacePath;

+    ///

+    /// The FpdfileName parameter.

+    ///

+    private String fpdFilePath;

+

+    /**

+     set workspace path parameter for this action.

+      

+     @param workspacePath the string of workspace path.

+    **/

+    public void setWorkspacePath(String workspacePath) {

+        this.workspacePath = workspacePath;

+    }

+

+    /**

+      set fpd file path parameter for this action.

+

+      @param fpdFilePath file path string

+    **/

+    public void setFPDFilePath(String fpdFilePath) {

+        this.fpdFilePath = "./" + fpdFilePath;

+    }

+

+    /**

+      check paramter for this action.

+      

+      @throw UIException wrong paramter.

+    **/

+    void checkParamter() throws UIException {

+        File file = null;

+

+        if((fpdFilePath    == null) ||(workspacePath  == null)) {

+            throw new UIException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");

+        }

+

+        if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {

+            throw new UIException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");

+        }

+

+        file = new File(workspacePath);

+        if(!file.exists()) {

+            throw new UIException("WorkpacePath " + workspacePath + " does not exist!");

+        }

+

+        file = new File(fpdFilePath);

+

+        if(!file.exists()) {

+            throw new UIException("FPD File " + fpdFilePath + " does not exist!");

+        }

+    }

+

+    /**

+      Core workflow function.

+      

+      @throw UIException Fail to show PCD database.

+    **/

+    void performAction() throws UIException {

+        CollectPCDAction  collectAction = null;

+        PCDDatabaseFrame  dbFrame       = null;

+

+        //

+        // Initialize global data.

+        //

+        GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",

+                            workspacePath);

+

+        //

+        // Collect PCD information.

+        //

+        collectAction = new CollectPCDAction();

+

+        try {

+            collectAction.perform(workspacePath,

+                                  fpdFilePath,

+                                  ActionMessage.LOG_MESSAGE_LEVEL);

+        } catch(Exception exp) {

+            throw new UIException(exp.getMessage());

+        }

+

+        //

+        // Start tree windows.

+        //

+        dbFrame = new PCDDatabaseFrame(GlobalData.getPCDMemoryDBManager());

+    }

+

+    /**

+      Entry function.

+      

+      The action is run from command line.

+     

+      @param argv command line parameter.

+    **/

+    public static void main(String[] argv) throws UIException {

+        ShowPCDDatabaseAction showAction = new ShowPCDDatabaseAction();

+        //showAction.setWorkspacePath(argv[0]);

+        //showAction.setFPDFilePath(argv[1]);

+        showAction.setWorkspacePath("M:/tianocore/edk2/trunk/edk2");

+        showAction.setFPDFilePath("EdkNt32Pkg/Nt32.fpd");

+        showAction.execute();

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java
new file mode 100644
index 0000000..2cde9b2
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java
@@ -0,0 +1,83 @@
+/** @file

+  UIAction class.

+

+  This class is the parent action class of UI wizard.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+

+package org.tianocore.build.pcd.action;

+

+import org.tianocore.build.pcd.exception.UIException;

+

+/** This class is the parent class for all UI wizard action.

+**/

+public abstract class UIAction {

+    ///

+    /// original message level. when finish this action, original 

+    /// message level will be restored.

+    ///

+    private int originalMessageLevel;

+

+    /**

+      Check the parameter for this aciton.

+      

+      This function will be overrided by child class.

+    **/

+    abstract void checkParamter() throws UIException;

+

+    /**

+      Perform action.

+      

+      This function will be overrided by child class.

+    **/

+    abstract void performAction() throws UIException;

+

+    /**

+     set the message level for this action.

+

+     @param messageLevel  message level wanted.

+    **/

+    public void setMessageLevel(int messageLevel) {

+        originalMessageLevel        = ActionMessage.messageLevel;

+        ActionMessage.messageLevel  = messageLevel;

+    }

+

+    /**

+     log message for UI wizard aciton.

+

+     @param actionObj  aciton instance object.

+     @param logStr     log message string

+    **/

+    public static void logMsg(Object actionObj, String logStr) {

+        System.out.println(logStr);

+    }

+

+    /**

+     Warning message for UI wizard action.

+

+     @param warningObj action instance object.

+     @param warningStr warning message string.

+    **/

+    public static void warningMsg(Object warningObj, String warningStr) {

+        System.out.println(warningStr);

+    }

+

+    /**

+      Entry function for all UI wizard actions.

+    **/

+    public void execute() throws UIException {

+        checkParamter();

+        performAction();

+

+        ActionMessage.messageLevel = originalMessageLevel;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java
new file mode 100644
index 0000000..b03cdde
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java
@@ -0,0 +1,292 @@
+/** @file

+  MemoryDatabaseManager class.

+

+  Database hold all PCD information comes from SPD, MSA, FPD file in memory.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.pcd.entity;

+

+import java.io.BufferedWriter;

+import java.io.File;

+import java.io.FileWriter;

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.HashMap;

+import java.util.Hashtable;

+import java.util.List;

+import java.util.Map;

+import java.util.UUID;

+

+import org.tianocore.build.pcd.action.ActionMessage;

+

+/** Database hold all PCD information comes from SPD, MSA, FPD file in memory.

+**/

+public class MemoryDatabaseManager {

+    ///

+    ///  Memory database. The string "cName + SpaceNameGuid" is primary key.

+    ///  memory database is in global scope, and it will be used for others PCD tools.

+    ///

+    private static Map<String, Token>  memoryDatabase       = null;

+

+    ///

+    /// Before build a module, the used libary will be build firstly, the PCD of these

+    /// libarry is inheritted by the module, so stored module's PCD information as PCD

+    /// context of building libary.

+    /// 

+    public static List<UsageInstance> UsageInstanceContext = null;

+    ///

+    /// 

+    /// 

+    public static String CurrentModuleName                 = null;

+    public static String PcdPeimHString       = "";

+    public static String PcdPeimCString       = "";

+    public static String PcdDxeHString        = "";

+    public static String PcdDxeCString        = "";

+

+    /**

+      Constructure function

+    **/

+    public MemoryDatabaseManager() {

+        //

+        // Allocate memory for new database in global scope.

+        //

+        if (memoryDatabase == null) {

+            memoryDatabase = new HashMap<String, Token>();

+        }

+    }

+

+    /**

+      Judege whether token exists in memory database

+      

+      @param primaryKey    the primaryKey for searching token

+      

+      @retval  TRUE  - token already exist in database.

+      @retval  FALSE - token does not exist in database.

+    **/

+    public boolean isTokenInDatabase(String primaryKey) {

+        return (memoryDatabase.get(primaryKey) != null);

+    }

+

+    /**

+      Add a pcd token into memory database.

+      

+      @param primaryKey   the primary key for searching token

+      @param token        token instance

+    **/

+    public void addTokenToDatabase(String primaryKey, Token token) {

+        memoryDatabase.put(primaryKey, token);

+    }

+

+    /**

+      Get a token instance from memory database with primary key.

+  

+      @param primaryKey   the primary key for searching token

+    

+      @return token instance.

+    **/

+    public Token getTokenByKey(String primaryKey) {

+        return memoryDatabase.get(primaryKey);

+    }

+

+    /**

+      Get the number of PCD token record in memory database.

+      

+      @return the number of PCD token record in memory database.

+    **/

+    public int getDBSize() {

+        return memoryDatabase.size();

+    }

+

+    /**

+      Get the token record array contained all PCD token in memory database.

+      

+      @return the token record array contained all PCD token in memory database.

+    **/

+    public Token[] getRecordArray() {

+        Token[]     tokenArray  = null;

+        Object[]    dataArray   = null;

+        Map.Entry   entry       = null;

+        int         index       = 0;

+

+        if (memoryDatabase == null) {

+            return null;

+        }

+

+        dataArray  = memoryDatabase.entrySet().toArray();

+        tokenArray = new Token[memoryDatabase.size()];

+        for (index = 0; index < memoryDatabase.size(); index ++) {

+            entry =(Map.Entry) dataArray [index];

+            tokenArray[index] =(Token) entry.getValue();

+        }

+

+        return tokenArray;

+    }

+

+    /**

+       Get record array only contains DYNAMIC or DYNAMIC_EX type PCD.

+       

+       @return ArrayList

+     */

+    private ArrayList getDynamicRecordArray() {

+        Token[]     tokenArray  =   getRecordArray();

+        int         index       =   0;

+        int         count       =   0;

+        ArrayList<Token>   al   =   new ArrayList<Token>();

+

+        for (index = 0; index < tokenArray.length; index++) {

+            if (tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC ||

+                tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC_EX) {

+                al.add(tokenArray[index]);

+            }

+        }

+

+        return al;

+    }

+

+

+    /**

+      Get the token record array contained all PCD token referenced by PEI phase.

+          The output array is sorted based on descending order of the size of alignment for each feilds.

+

+      @return the token record array contained all PCD token referenced in PEI phase.

+    **/

+    public void getTwoPhaseDynamicRecordArray(ArrayList<Token> pei, ArrayList<Token> dxe) {

+        int                     usageInstanceIndex  =   0;

+        int                     index               =   0;

+        ArrayList               tokenArrayList      =   getDynamicRecordArray();

+        Object[]                usageInstanceArray  =   null;

+        UsageInstance           usageInstance       =   null;

+

+        //pei = new ArrayList<Token>();

+        //dxe = new ArrayList<Token>();

+

+        for (index = 0; index < tokenArrayList.size(); index++) {

+            boolean found   =   false;

+            Token       token = (Token) tokenArrayList.get(index);

+            if (token.consumers != null) {

+                usageInstanceArray = token.consumers.entrySet().toArray();

+                for (usageInstanceIndex = 0; usageInstanceIndex < token.consumers.size(); usageInstanceIndex ++) {

+                    usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue());

+                    if (usageInstance.isPeiPhaseComponent()) {

+                        pei.add(token);

+                        found = true;

+                        break;

+                    }

+                }

+            }

+

+            // If no PEI components reference the PCD entry, we insert it to DXE list

+            //

+            if (!found) {

+                dxe.add(token);

+            }

+        }

+

+        return;

+    }

+

+    /**

+      Get all PCD record for a module according to module's name, module's GUID,

+      package name, package GUID, arch, version information.

+     

+      @param moduleName  the name of module.

+      

+      @return  all usage instance for this module in memory database.

+    **/

+    public List<UsageInstance> getUsageInstanceArrayByModuleName(String moduleName,

+                                                                 UUID   moduleGuid,

+                                                                 String packageName,

+                                                                 UUID   packageGuid,

+                                                                 String arch,

+                                                                 String version) {

+

+        String primaryKey = UsageInstance.getPrimaryKey(moduleName, 

+                                                        moduleGuid,

+                                                        packageName,

+                                                        packageGuid,

+                                                        arch,

+                                                        version);

+

+        return getUsageInstanceArrayByKeyString(primaryKey);

+    }

+

+    /**

+       Get all PCD token for a usage instance according to primary key.

+       

+       @param primaryKey    the primary key of usage instance.

+       

+       @return List<UsageInstance>

+     */

+    public List<UsageInstance> getUsageInstanceArrayByKeyString(String primaryKey) {

+        Token[]               tokenArray          = null;

+        int                   recordIndex         = 0; 

+        UsageInstance         usageInstance       = null;

+        List<UsageInstance>   returnArray         = new ArrayList<UsageInstance>();

+

+        tokenArray = getRecordArray();

+

+        //

+        // Loop to find all PCD record related to current module

+        //

+        for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) {

+            if (tokenArray[recordIndex].consumers.size() != 0) {

+                usageInstance = tokenArray[recordIndex].consumers.get(primaryKey);

+                if (usageInstance != null) {

+                    returnArray.add(usageInstance);

+                }

+            }

+        }

+

+        return returnArray;

+    }

+

+    /**

+      Get all modules name who contains PCD information

+     

+      @return Array for module name

+    **/

+    public List<String> getAllModuleArray()

+    {

+        int                       indexToken    = 0;

+        int                       usageIndex    = 0;

+        int                       moduleIndex   = 0;

+        Token[]                   tokenArray    = null;

+        Object[]                  usageInstanceArray = null;

+        List<String>              moduleNames   = new ArrayList<String>();

+        UsageInstance             usageInstance = null;

+        boolean                   bFound        = false;

+

+        tokenArray = getRecordArray();

+        //

+        // Find all consumer usage instance for retrieving module's name

+        //

+        for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {

+            usageInstanceArray = tokenArray[indexToken].consumers.entrySet().toArray();

+            for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) {

+                usageInstance = (UsageInstance)((Map.Entry)usageInstanceArray[usageIndex]).getValue();

+                bFound        = false;

+                for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {

+                    if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.getPrimaryKey())) {

+                        bFound = true;

+                        break;

+                    }

+                }

+                if (!bFound) {

+                    moduleNames.add(usageInstance.getPrimaryKey());

+                }

+            }

+        }

+        return moduleNames;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java
new file mode 100644
index 0000000..2886506
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java
@@ -0,0 +1,40 @@
+/** @file

+  SkuInstance class.

+

+  Sku instance contains ID and value, A pcd token maybe contains more than one Sku instance.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/ 

+package org.tianocore.build.pcd.entity;

+

+/** Sku instance contains ID and value, A pcd token maybe contains more than one Sku instance.

+**/

+public class SkuInstance {

+    ///

+    /// The id number of this SKU instance

+    ///

+    public int    id;

+    ///

+    /// The value of this SKU instance

+    ///

+    public Object value;

+

+    /**

+      Constructure function

+

+      @param id     sku id 

+      @param value  sku value for this id.

+    **/

+    public SkuInstance(int id, Object value) {

+        this.id    = id;

+        this.value = value;

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
new file mode 100644
index 0000000..3136864
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
@@ -0,0 +1,583 @@
+/** @file

+  Token class.

+

+  This module contains all classes releted to PCD token.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/  

+package org.tianocore.build.pcd.entity;

+

+import java.util.ArrayList;

+import java.util.List;

+import java.util.UUID;

+import java.util.Map;

+import java.util.HashMap;

+

+import org.tianocore.build.pcd.action.ActionMessage;

+import org.tianocore.build.pcd.exception.EntityException;

+

+/** This class is to descript a PCD token object. The information of a token mainly 

+    comes from MSA, SPD and setting produced by platform developer. 

+**/

+public class Token {

+    ///

+    /// Enumeration macro defintion for PCD type.

+    /// BUGBUG: Not use upcase charater is to facility for reading. It may be changed

+    ///         in coding review.

+    public enum             PCD_TYPE {FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODULE, DYNAMIC, 

+                                      DYNAMIC_EX, UNKNOWN}

+

+    ///

+    /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.

+    /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in 

+    /// prompt dialog.

+    ///

+    public enum             DATUM_TYPE {UINT8, UINT16, UINT32, UINT64, BOOLEAN, POINTER, UNKNOWN}

+

+    ///

+    /// Enumeration macor defintion for usage of PCD

+    ///

+    public enum             PCD_USAGE {ALWAYS_PRODUCED, ALWAYS_CONSUMED, SOMETIMES_PRODUCED,

+                                       SOMETIMES_CONSUMED, UNKNOWN}

+

+    ///

+    /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.

+    /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.

+    ///

+    public String           cName;

+

+    ///

+    /// Token space name is the guid defined by token itself in package or module level. This

+    /// name mainly for DynamicEx type. For other PCD type token, his token space name is the 

+    /// assignedtokenSpaceName as follows.

+    /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.

+    ///

+    public UUID             tokenSpaceName;

+

+    ///

+    /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in

+    /// platform token space.

+    /// tokenNumber is defined in SPD, FPD.

+    ///

+    public int              tokenNumber;

+

+    ///

+    /// pcdType is the PCD item type defined by platform developer.

+    ///

+    public PCD_TYPE         pcdType;

+

+    ///

+    /// datumSize is to descript the fix size or max size for this token. 

+    /// datumSize is defined in SPD.

+    ///

+    public int              datumSize;

+

+    ///

+    /// datum type is to descript what type can be expressed by a PCD token.

+    /// datumType is defined in SPD.

+    ///

+    public DATUM_TYPE       datumType;

+

+    ///

+    /// hiiEnabled is to indicate whether the token support Hii functionality.

+    /// hiiEnabled is defined in FPD.

+    ///

+    public boolean          hiiEnabled;

+

+    ///

+    /// variableName is valid only when this token support Hii functionality. variableName

+    /// indicates the value of token is associated with what variable.

+    /// variableName is defined in FPD.

+    ///

+    public String           variableName;

+

+    ///

+    /// variableGuid is the GUID this token associated with.

+    /// variableGuid is defined in FPD.

+    ///

+    public UUID             variableGuid;

+

+    ///

+    /// Variable offset indicate the associated variable's offset in NV storage.

+    /// variableOffset is defined in FPD.

+    ///

+    public int              variableOffset;

+

+    ///

+    /// skuEnabled is to indicate whether the token support Sku functionality.

+    /// skuEnabled is defined in FPD.

+    ///

+    public boolean          skuEnabled;

+

+    ///

+    /// skuData contains all value for SkuNumber of token.

+    /// skuData is defined in FPD.

+    ///

+    public List<SkuInstance> skuData;

+

+    ///

+    /// maxSkuCount indicate the max count of sku data.

+    /// maxSkuCount is defined in FPD.

+    ///

+    public int              maxSkuCount;

+

+    ///

+    /// SkuId is the id of current selected SKU.

+    /// SkuId is defined in FPD.

+    ///

+    public int              skuId;

+

+    ///

+    /// datum is the value set by platform developer.

+    /// datum is defined in FPD.

+    ///

+    public Object           datum;

+

+    ///

+    /// BUGBUG: fix comment

+    /// vpdEnabled is defined in FPD.

+    ///

+    public boolean          vpdEnabled;

+

+    ///

+    /// BUGBUG: fix comment

+    /// vpdOffset is defined in FPD.

+    ///

+    public long             vpdOffset;

+

+    ///

+    /// consumers array record all module private information who consume this PCD token.

+    ///

+    public Map<String, UsageInstance>  consumers;

+

+    public Token(String cName, UUID tokenSpaceName) {

+        UUID    nullUUID = new UUID(0, 0);

+

+        this.cName                  = cName;

+        this.tokenSpaceName         = (tokenSpaceName == null) ? nullUUID : tokenSpaceName;

+        this.tokenNumber            = 0;

+        this.pcdType                = PCD_TYPE.UNKNOWN;

+        this.datumType              = DATUM_TYPE.UNKNOWN;

+        this.datumSize              = -1;

+        this.datum                  = null;

+        this.hiiEnabled             = false;

+        this.variableGuid           = null;

+        this.variableName           = "";

+        this.variableOffset         = -1;

+        this.skuEnabled             = false;

+        this.skuId                  = -1;

+        this.maxSkuCount            = -1;

+        this.skuData                = new ArrayList<SkuInstance>();

+        this.vpdEnabled             = false;

+        this.vpdOffset              = -1;

+

+        this.consumers              = new HashMap<String, UsageInstance>();

+    }

+

+    /**

+      Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database

+      

+      @param   cName                     Token name.

+      @param   tokenSpaceName            The token space guid defined in MSA or SPD

+      @param   platformtokenSpaceName    The token space guid for current platform token space,

+      

+      @return  primary key for this token in token database.

+    **/

+    public static String getPrimaryKeyString(String cName, UUID tokenSpaceName) {

+        UUID  nullUUID = new UUID(0, 0);

+

+        if (tokenSpaceName == null) {

+            return cName + "_" + nullUUID.toString().replace('-', '_');

+        } else {

+            return cName + "_" + tokenSpaceName.toString().replace('-', '_');

+        }

+    }

+

+    /**

+       Get the token primary key in token database.

+       

+       @return String

+     */

+    public String getPrimaryKeyString () {

+        return Token.getPrimaryKeyString(cName, tokenSpaceName);

+    }

+

+    /**

+      Judge datumType is valid

+      

+      @param type  The datumType want to be judged.

+      

+      @retval TRUE  - The type is valid.

+      @retval FALSE - The type is invalid.

+    **/

+    public static boolean isValiddatumType(DATUM_TYPE type) {

+        if ((type.ordinal() < DATUM_TYPE.UINT8.ordinal() ) || 

+            (type.ordinal() > DATUM_TYPE.POINTER.ordinal())) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+      Judge pcdType is valid

+      

+      @param  type The PCdType want to be judged.

+      

+      @retval TRUE  - The type is valid.

+      @retval FALSE - The type is invalid.

+    **/

+    public static boolean isValidpcdType(PCD_TYPE  type) {

+        if ((type.ordinal() < PCD_TYPE.FEATURE_FLAG.ordinal() ) || 

+            (type.ordinal() > PCD_TYPE.DYNAMIC_EX.ordinal())) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+      Add an usage instance for token

+      

+      @param usageInstance   The usage instance

+     

+      @retval TRUE  - Success to add usage instance.

+      @retval FALSE - Fail to add usage instance

+    **/

+    public boolean addUsageInstance(UsageInstance usageInstance) 

+        throws EntityException {

+        String exceptionStr;

+

+        if (isUsageInstanceExist(usageInstance.moduleName,

+                                 usageInstance.moduleGUID,

+                                 usageInstance.packageName,

+                                 usageInstance.packageGUID,

+                                 usageInstance.arch,

+                                 usageInstance.version)) {

+            exceptionStr = String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+

+                                         "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",

+                                         usageInstance.parentToken.cName,

+                                         usageInstance.moduleName);

+            throw new EntityException(exceptionStr);

+        }

+

+        consumers.put(usageInstance.getPrimaryKey(), usageInstance);

+        return true;

+    }

+

+    /**

+       Judge whether exist an usage instance for this token

+       

+       @param moduleName    the name of module

+       @param moduleGuid    the GUID name of modules

+       @param packageName   the name of package contains this module

+       @param packageGuid   the GUID name of package contains this module

+       @param arch          the architecture string

+       @param version       the version string

+       

+       @return boolean      whether exist an usage instance for this token.

+     */

+    public boolean isUsageInstanceExist(String moduleName,

+                                        UUID   moduleGuid,

+                                        String packageName,

+                                        UUID   packageGuid,

+                                        String arch,

+                                        String version) {

+        String keyStr = UsageInstance.getPrimaryKey(moduleName, 

+                                                    moduleGuid, 

+                                                    packageName, 

+                                                    packageGuid, 

+                                                    arch, 

+                                                    version);

+        return (consumers.get(keyStr) != null);

+    }

+

+    /**

+      Get the PCD_TYPE according to the string of PCD_TYPE

+      

+      @param pcdTypeStr    The string of PCD_TYPE

+      

+      @return PCD_TYPE

+    **/

+    public static PCD_TYPE getpcdTypeFromString(String pcdTypeStr) {

+        if (pcdTypeStr == null) {

+            return PCD_TYPE.UNKNOWN;

+        }

+

+        if (pcdTypeStr.equalsIgnoreCase("FEATURE_FLAG")) {

+            return PCD_TYPE.FEATURE_FLAG;

+        } else if (pcdTypeStr.equalsIgnoreCase("FIXED_AT_BUILD")) {

+            return PCD_TYPE.FIXED_AT_BUILD;

+        } else if (pcdTypeStr.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {

+            return PCD_TYPE.PATCHABLE_IN_MODULE;

+        } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC")) {

+            return PCD_TYPE.DYNAMIC;

+        } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC_EX")) {

+            return PCD_TYPE.DYNAMIC_EX;

+        } else {

+            return PCD_TYPE.UNKNOWN;

+        }

+    }

+

+    /**

+      Get the string of given datumType. This string will be used for generating autogen files

+     

+      @param datumType   Given datumType

+     

+      @return The string of datum type.

+    **/

+    public static String getStringOfdatumType(DATUM_TYPE  datumType) {

+        switch (datumType) {

+        case UINT8:

+            return "UINT8";

+        case UINT16:

+            return "UINT16";

+        case UINT32:

+            return "UINT32";

+        case UINT64:

+            return "UINT64";

+        case POINTER:

+            return "POINTER";

+        case BOOLEAN:

+            return "BOOLEAN";

+        }

+        return "UNKNOWN";

+    }

+

+    /**

+      Get the datumType according to a string.

+      

+      @param datumTypeStr    The string of datumType

+     

+      @return DATUM_TYPE

+    **/

+    public static DATUM_TYPE getdatumTypeFromString(String datumTypeStr) {

+        if (datumTypeStr.equalsIgnoreCase("UINT8")) {

+            return DATUM_TYPE.UINT8;

+        } else if (datumTypeStr.equalsIgnoreCase("UINT16")) {

+            return DATUM_TYPE.UINT16;

+        } else if (datumTypeStr.equalsIgnoreCase("UINT32")) {

+            return DATUM_TYPE.UINT32;

+        } else if (datumTypeStr.equalsIgnoreCase("UINT64")) {

+            return DATUM_TYPE.UINT64;

+        } else if (datumTypeStr.equalsIgnoreCase("VOID*")) {

+            return DATUM_TYPE.POINTER;

+        } else if (datumTypeStr.equalsIgnoreCase("BOOLEAN")) {

+            return DATUM_TYPE.BOOLEAN;

+        }

+        return DATUM_TYPE.UNKNOWN;

+    }

+

+    /**

+      Get string of given pcdType

+      

+      @param pcdType  The given PcdType

+      

+      @return The string of PCD_TYPE.

+    **/

+    public static String getStringOfpcdType(PCD_TYPE pcdType) {

+        switch (pcdType) {

+        case FEATURE_FLAG:

+            return "FEATURE_FLAG";

+        case FIXED_AT_BUILD:

+            return "FIXED_AT_BUILD";

+        case PATCHABLE_IN_MODULE:

+            return "PATCHABLE_IN_MODULE";

+        case DYNAMIC:

+            return "DYNAMIC";

+        case DYNAMIC_EX:

+            return "DYNAMIC_EX";

+        }

+        return "UNKNOWN";

+    }

+

+    /**

+      Get the PCD_USAGE according to a string

+      

+      @param usageStr  The string of PCD_USAGE

+      

+      @return The PCD_USAGE

+    **/

+    public static PCD_USAGE getUsageFromString(String usageStr) {

+        if (usageStr == null) {

+            return PCD_USAGE.UNKNOWN;

+        }

+

+        if (usageStr.equalsIgnoreCase("ALWAYS_PRODUCED")) {

+            return PCD_USAGE.ALWAYS_PRODUCED;

+        } else if (usageStr.equalsIgnoreCase("SOMETIMES_PRODUCED")) {

+            return PCD_USAGE.SOMETIMES_PRODUCED;

+        } else if (usageStr.equalsIgnoreCase("ALWAYS_CONSUMED")) {

+            return PCD_USAGE.ALWAYS_CONSUMED;

+        } else if (usageStr.equalsIgnoreCase("SOMETIMES_CONSUMED")) {

+            return PCD_USAGE.SOMETIMES_CONSUMED;

+        }

+

+        return PCD_USAGE.UNKNOWN;

+    }

+

+    /**

+      Get the string of given PCD_USAGE

+      

+      @param   usage   The given PCD_USAGE

+      

+      @return The string of PDC_USAGE.

+    **/

+    public static String getStringOfUsage(PCD_USAGE usage) {

+        switch (usage) {

+        case ALWAYS_PRODUCED:

+            return "ALWAYS_PRODUCED";

+        case ALWAYS_CONSUMED:

+            return "ALWAYS_CONSUMED";

+        case SOMETIMES_PRODUCED:

+            return "SOMETIMES_PRODUCED";

+        case SOMETIMES_CONSUMED:

+            return "SOMETIMES_CONSUMED";

+        }

+        return "UNKNOWN";

+    }

+

+    /**

+      Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h

+      

+      @param datumType The given datumType

+

+      @return string of datum type for autogen.

+    **/

+    public static String GetAutogenDefinedatumTypeString(DATUM_TYPE datumType) {

+        switch (datumType) {

+        

+        case UINT8:

+            return "8";

+        case UINT16:

+            return "16";

+        case BOOLEAN:

+            return "BOOL";

+        case POINTER:

+            return "PTR";

+        case UINT32:

+            return "32";

+        case UINT64:

+            return "64";

+        default:

+            return null;

+        }

+    }

+

+    /**

+      Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen

+      

+      @param datumType   The given datumType

+

+      @return string of datum type.

+    **/

+    public static String getAutogendatumTypeString(DATUM_TYPE datumType) {

+        switch (datumType) {

+        case UINT8:

+            return "UINT8";

+        case UINT16:

+            return "UINT16";

+        case UINT32:

+            return "UINT32";

+        case UINT64:

+            return "UINT64";

+        case POINTER:

+            return "VOID*";

+        case BOOLEAN:

+            return "BOOLEAN";

+        }

+        return null;

+    }

+

+    /**

+      Get the datumType string for generating some MACROs in autogen file of Library

+      

+      @param   datumType  The given datumType

+

+      @return String of datum for genrating bit charater.

+    **/

+    public static String getAutogenLibrarydatumTypeString(DATUM_TYPE datumType) {

+        switch (datumType) {

+        case UINT8:

+            return "8";

+        case UINT16:

+            return "16";

+        case BOOLEAN:

+            return "Bool";

+        case POINTER:

+            return "Ptr";

+        case UINT32:

+            return "32";

+        case UINT64:

+            return "64";

+        default:

+            return null;

+        }

+    }

+

+    /**

+      UUID defined in Schems is object, this function is to tranlate this object 

+      to UUID data.

+      

+      @param uuidObj The object comes from schema.

+      

+      @return The traslated UUID instance.

+    **/

+    public static UUID getGUIDFromSchemaObject(Object uuidObj) {

+        UUID uuid;

+        if (uuidObj.toString().equalsIgnoreCase("0")) {

+            uuid = new UUID(0,0);

+        } else {

+            uuid = UUID.fromString(uuidObj.toString());

+        }

+

+        return uuid;

+    }

+

+    //

+    // BugBug: We need change this algorithm accordingly when schema is updated

+    //          to support no default value.

+    //

+    public boolean hasDefaultValue () {

+

+        if (hiiEnabled) {

+            return true;

+        }

+

+        if (vpdEnabled) {

+            return true;

+        }

+

+        if (datum.toString().compareTo("NoDefault") == 0) {

+            return false;

+        }

+

+        return true;

+    }

+

+    public boolean isStringType () {

+        String str = datum.toString();

+

+        if (datumType == Token.DATUM_TYPE.POINTER &&

+            str.startsWith("L\"") && 

+            str.endsWith("\"")) {

+            return true;

+        }

+

+        return false;

+    }

+

+    public String getStringTypeString () {                       

+        return datum.toString().substring(2, datum.toString().length() - 1);

+    }

+}

+

+

+

+

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java
new file mode 100644
index 0000000..90c0f63
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java
@@ -0,0 +1,371 @@
+/** @file

+  UsageInstance class.

+

+  This class indicate an usage instance for a PCD token. This instance maybe a module

+  or platform setting. When a module produce or cosume a PCD token, then this module

+  is an usage instance for this PCD token.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/  

+package org.tianocore.build.pcd.entity;

+

+

+import java.util.UUID;

+

+import org.tianocore.build.autogen.CommonDefinition;

+import org.tianocore.build.pcd.action.ActionMessage;

+import org.tianocore.build.pcd.exception.EntityException;

+

+/**

+  This class indicate an usage instance for a PCD token. This instance maybe a module

+  or platform setting. When a module produce or cosume a PCD token, then this module

+  is an usage instance for this PCD token.

+**/

+public class UsageInstance {

+  ///

+  /// The module type of usage instance.

+  /// 

+  public enum MODULE_TYPE {SEC, PEI_CORE, PEIM, DXE_CORE, DXE_DRIVERS, OTHER_COMPONENTS}

+  ///

+  /// This parent that this usage instance belongs to.

+  ///

+  public Token            parentToken;

+  ///

+  /// The name of the module who contains this PCD.

+  ///

+  public String           moduleName;

+  ///

+  /// The GUID of the module who contains this PCD. 

+  /// 

+  public UUID             moduleGUID;

+  ///

+  /// The name of the package whose module contains this PCD.

+  ///

+  public String           packageName;

+  ///

+  /// The GUID of the package whose module contains this PCD.

+  /// 

+  public UUID             packageGUID;

+  ///

+  /// The PCD type defined for module 

+  /// 

+  public Token.PCD_TYPE   modulePcdType;

+  ///

+  /// The arch string of module contains this PCD

+  ///

+  public String           arch;

+  ///

+  /// The version of module contains this PCD

+  /// 

+  public String           version;

+  ///

+  /// The module type for this usage instance.

+  ///

+  public MODULE_TYPE      moduleType;

+  ///

+  /// The value of the PCD in this usage instance. 

+  /// 

+  public Object           datum;

+  ///

+  /// Autogen string for header file.

+  ///

+  public String           hAutogenStr;

+  /**

+   * Auotgen string for C code file.

+   */

+  public String           cAutogenStr;

+

+  /**

+     Constructure function

+     

+     @param parentToken         Member variable.

+     @param pcdType             Member variable.

+     @param moduleName          Member variable.

+     @param moduleGUID          Member variable.

+     @param packageName         Member variable.

+     @param packageGUID         Member variable.

+     @param moduleType          Member variable.

+     @param modulePcdType       Member variable.

+     @param arch                Member variable.

+     @param version             Member variable.

+     @param value               Member variable.

+  **/

+  public UsageInstance (Token             parentToken,

+                        Token.PCD_TYPE    pcdType,

+                        String            moduleName,

+                        UUID              moduleGUID,

+                        String            packageName,

+                        UUID              packageGUID,

+                        MODULE_TYPE       moduleType,

+                        Token.PCD_TYPE    modulePcdType,

+                        String            arch,

+                        String            version,

+                        Object            value) {

+      this.parentToken      = parentToken;

+      this.moduleName       = moduleName;

+      this.moduleGUID       = moduleGUID;

+      this.packageName      = packageName;

+      this.packageGUID      = packageGUID;

+      this.moduleType       = moduleType;

+      this.modulePcdType    = modulePcdType;

+      this.arch             = arch;

+      this.version          = version;

+      this.datum            = value;

+      this.modulePcdType    = pcdType;

+  }

+

+  /**

+     Get the primary key for usage instance array for every token.

+     

+     @param moduleName      the name of module

+     @param moduleGUID      the GUID name of module

+     @param packageName     the name of package who contains this module

+     @param packageGUID     the GUID name of package

+     @param arch            the archtecture string

+     @param version         the version of this module

+     

+     @return String         primary key

+   */

+  public static String getPrimaryKey(String moduleName,  

+                                     UUID   moduleGUID,  

+                                     String packageName,  

+                                     UUID   packageGUID,

+                                     String arch,

+                                     String version) {

+      //

+      // Because currently transition schema not require write moduleGuid, package Name, Packge GUID in

+      // <ModuleSA> section, So currently no expect all paramter must be valid.

+      return (moduleName                                                              + "_" +

+              ((moduleGUID  != null) ? moduleGUID.toString() : "NullModuleGuid")      + "_" +

+              ((packageName != null) ? packageName : "NullPackageName")               + "_" +

+              ((packageGUID != null) ? packageGUID.toString() : "NullPackageGuid")    + "_" +

+              ((arch        != null) ? arch : "NullArch")                             + "_" +

+              ((version     != null) ? version : "NullVersion"));

+  }

+

+  /**

+     Get primary key string for this usage instance

+     

+     @return String primary key string

+  **/

+  public String getPrimaryKey() {

+      return UsageInstance.getPrimaryKey(moduleName, moduleGUID, packageName, packageGUID, arch, version);

+  }

+

+  /**

+     Judget whether current module is PEI driver

+     

+     @return boolean

+   */

+  public boolean isPeiPhaseComponent() {

+      if ((moduleType == MODULE_TYPE.PEI_CORE) ||

+          (moduleType == MODULE_TYPE.PEIM)) {

+          return true;

+      }

+      return false;

+  }

+

+  /**

+     Generate autogen string for header file and C code file.

+     

+     @throws EntityException Fail to generate.

+     

+     @param isBuildUsedLibrary  whether the autogen is for library.

+   */

+  public void generateAutoGen(boolean isBuildUsedLibrary) 

+    throws EntityException {

+

+    hAutogenStr = "";

+    cAutogenStr = "";

+

+    hAutogenStr += String.format("#define _PCD_TOKEN_%s   0x%016x\r\n", 

+                                 parentToken.cName, parentToken.tokenNumber);

+    switch(modulePcdType) {

+    case FEATURE_FLAG:

+      if(isBuildUsedLibrary) {

+          hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", 

+                                       parentToken.cName);

+          hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_FixedAtBuild_%s\r\n",

+                                       parentToken.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                       parentToken.cName,

+                                       parentToken.cName);

+      } else {

+          hAutogenStr += String.format("#define _PCD_VALUE_%s   %s\r\n", 

+                                       parentToken.cName, 

+                                       datum.toString());

+          hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", 

+                                       parentToken.cName);

+          cAutogenStr += String.format("GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",

+                                       parentToken.cName,

+                                       parentToken.cName);

+          hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _PCD_VALUE_%s\r\n",

+                                       Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                       parentToken.cName,

+                                       parentToken.cName);

+      }

+      break;

+    case FIXED_AT_BUILD:

+      if(isBuildUsedLibrary) {

+        hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s;\r\n",

+                                     Token.getAutogendatumTypeString(parentToken.datumType),

+                                     parentToken.cName);

+        hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_FixedAtBuild_%s\r\n",

+                                     Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                     parentToken.cName,

+                                     parentToken.cName);

+      } else {

+        hAutogenStr += String.format("#define _PCD_VALUE_%s   %s\r\n", 

+                                     parentToken.cName, 

+                                     datum.toString());

+        hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s;\r\n",

+                                     Token.getAutogendatumTypeString(parentToken.datumType),

+                                     parentToken.cName);

+        cAutogenStr += String.format("GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",

+                                     Token.getAutogendatumTypeString(parentToken.datumType),

+                                     parentToken.cName,

+                                     parentToken.cName);

+        hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _PCD_VALUE_%s\r\n",

+                                     Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                     parentToken.cName,

+                                     parentToken.cName);

+      }

+      break;

+    case PATCHABLE_IN_MODULE:

+      if(isBuildUsedLibrary) {

+        hAutogenStr += String.format("extern %s _gPcd_BinaryPatch_%s;\r\n",

+                                     Token.getAutogendatumTypeString(parentToken.datumType),

+                                     parentToken.cName);

+        hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_BinaryPatch_%s\r\n",

+                                     Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                     parentToken.cName,

+                                     parentToken.cName);

+      } else {

+        hAutogenStr += String.format("#define _PCD_VALUE_%s   %s\r\n", 

+                                     parentToken.cName, 

+                                     datum.toString());

+        hAutogenStr += String.format("extern %s _gPcd_BinaryPatch_%s;\r\n",

+                                     Token.getAutogendatumTypeString(parentToken.datumType),

+                                     parentToken.cName);

+        cAutogenStr += String.format("GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n",

+                                     Token.getAutogendatumTypeString(parentToken.datumType),

+                                     parentToken.cName,

+                                     parentToken.cName);

+        hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_BinaryPatch_%s\r\n",

+                                     Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                     parentToken.cName,

+                                     parentToken.cName);

+      }

+

+      break;

+    case DYNAMIC:

+      switch(parentToken.pcdType) {

+        case FEATURE_FLAG:

+          if(isBuildUsedLibrary) {

+            hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", 

+                                         parentToken.cName);

+            hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_FixedAtBuild_%s\r\n",

+                                         Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                         parentToken.cName,

+                                         parentToken.cName);

+          } else {

+            hAutogenStr += String.format("#define _PCD_VALUE_%s   %s\r\n", 

+                                         parentToken.cName, 

+                                         datum.toString());

+            hAutogenStr += String.format("extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", 

+                                         parentToken.cName);

+            cAutogenStr += String.format("const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",

+                                         parentToken.cName,

+                                         parentToken.cName);

+            hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _PCD_VALUE_%s\r\n",

+                                         Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                         parentToken.cName,

+                                         parentToken.cName);

+          }

+          break;

+        case FIXED_AT_BUILD:

+          if(isBuildUsedLibrary) {

+            hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s;\r\n",

+                                         Token.getAutogendatumTypeString(parentToken.datumType),

+                                         parentToken.cName);

+            hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_FixedAtBuild_%s\r\n",

+                                         Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                         parentToken.cName,

+                                         parentToken.cName);

+

+          } else {

+            hAutogenStr += String.format("#define _PCD_VALUE_%s   %s\r\n", 

+                                         parentToken.cName, 

+                                         datum.toString());

+            hAutogenStr += String.format("extern const %s _gPcd_FixedAtBuild_%s\r\n",

+                                         Token.getAutogendatumTypeString(parentToken.datumType),

+                                         parentToken.cName);

+            cAutogenStr += String.format("const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",

+                                         Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                         parentToken.cName,

+                                         parentToken.cName);

+            hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _PCD_VALUE_%s\r\n",

+                                         Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                         parentToken.cName,

+                                         parentToken.cName);

+          }

+          break;

+        case PATCHABLE_IN_MODULE:

+          hAutogenStr += String.format("#define _PCD_VALUE_%s   %s\r\n", 

+                                       parentToken.cName, 

+                                       datum.toString());

+          hAutogenStr += String.format("extern %s _gPcd_BinaryPatch_%s;\r\n",

+                                       Token.getAutogendatumTypeString(parentToken.datumType),

+                                       parentToken.cName,

+                                       parentToken.cName);

+          cAutogenStr += String.format("%s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;",

+                                       Token.getAutogendatumTypeString(parentToken.datumType),

+                                       parentToken.cName,

+                                       parentToken.cName);

+          hAutogenStr += String.format("#define _PCD_MODE_%s_%s  _gPcd_BinaryPatch_%s\r\n",

+                                       Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                       parentToken.cName,

+                                       parentToken.cName);

+          break;

+      case DYNAMIC:

+          hAutogenStr += String.format("#define _PCD_MODE_%s_%s  LibPcdGet%s(_PCD_TOKEN_%s)\r\n",

+                                       Token.GetAutogenDefinedatumTypeString(parentToken.datumType),

+                                       parentToken.cName,

+                                       Token.getAutogenLibrarydatumTypeString(parentToken.datumType),

+                                       parentToken.cName);

+          break;

+      default:

+          throw new EntityException ("The PCD type is unknown");

+      }

+      break;

+    case DYNAMIC_EX:

+      break;

+    }

+  }

+

+  /**

+    Get the autogen string for header file.

+    

+    @return The string of header file.

+  **/

+  public String getHAutogenStr() {

+    return hAutogenStr;

+  }

+

+  /**

+    Get the autogen string for C code file.

+    

+    @return The string of C Code file.

+  **/

+  public String getCAutogenStr() {

+    return cAutogenStr;

+  }

+}

+

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java
new file mode 100644
index 0000000..357ebf0
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java
@@ -0,0 +1,33 @@
+/** @file

+  BuildActionException class.

+

+  BuildAction Exception deals with all build action exceptions.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/   

+package org.tianocore.build.pcd.exception;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+  BuildAction Exception deals with all build action exceptions.

+**/

+public class BuildActionException extends BuildException {

+    static final long serialVersionUID = -7034897190740066939L;

+    /**

+      Constructure function

+      

+      @param reason exception message string.

+    **/

+    public BuildActionException(String reason) {

+        super(reason);

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java
new file mode 100644
index 0000000..070c2db
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java
@@ -0,0 +1,31 @@
+/** @file

+  EntityException class.

+

+  The class handle the exception throwed by entity class.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/   

+package org.tianocore.build.pcd.exception;

+

+/**

+  The class handle the exception throwed by entity class.

+**/

+public class EntityException extends Exception {

+    static final long serialVersionUID = -8034897190740066939L;

+    /**

+      Constructure function

+        

+      @param expStr exception message string.

+    **/

+    public EntityException(String expStr) {

+        super("[PCD EntityException]:" + expStr);

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java
new file mode 100644
index 0000000..96575a1
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java
@@ -0,0 +1,31 @@
+/** @file

+  UIException class.

+

+  The class handle the exception throwed by UI action class.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/   

+package org.tianocore.build.pcd.exception;

+

+/**

+  The class handle the exception throwed by UI action class.

+**/

+public class UIException extends Exception {

+    static final long serialVersionUID = -7034897190740066930L;

+    /**

+      Constructure function

+        

+      @param reason exception message string.

+    **/

+    public UIException(String reason) {

+        super(reason);

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java
new file mode 100644
index 0000000..661260d
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java
@@ -0,0 +1,174 @@
+/** @file

+  PCDDatabaseFrame class.

+

+  The class is the frame class for displaying PCD database in tree method.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/   

+package org.tianocore.build.pcd.ui;

+

+import java.awt.*;

+import java.awt.event.*;

+import java.util.Map;

+

+import javax.swing.*;

+import javax.swing.tree.DefaultMutableTreeNode;

+

+import org.tianocore.build.pcd.action.ActionMessage;

+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;

+import org.tianocore.build.pcd.entity.Token;

+import org.tianocore.build.pcd.entity.UsageInstance;

+

+/**

+  The class is the frame class for displaying PCD database in tree method.

+**/

+public class PCDDatabaseFrame extends JFrame {

+    static final long serialVersionUID = -7034897190740068939L;

+    ///

+    /// Database instance 

+    ///

+    private MemoryDatabaseManager dbManager;

+    ///

+    /// The token and module tree

+    ///

+    private JTree                 databaseTree;

+

+    /**

+      Constructure function. 

+     

+      Create the UI component and display frame.

+

+      @param dbManager databaase manager instance.

+    **/

+    public PCDDatabaseFrame(MemoryDatabaseManager dbManager) {

+        if (dbManager != null) {

+            this.dbManager = dbManager;

+        }

+        //

+        // Put the frame into center of desktop.

+        //

+        setLocation(100, 100);

+        initializeComponent();

+

+        setTitle("PCD View Tool");

+        pack();

+        setVisible(true);

+    }

+

+    /**

+       Initliaze the UI component in Display frame.

+    **/

+    public void initializeComponent() {

+        JScrollPane scrollPane = new JScrollPane();

+        Container contentPane  = getContentPane();

+

+        contentPane.setLayout(new BorderLayout());

+        scrollPane.setViewportView(initializeTree());

+        contentPane.add(scrollPane);

+

+        addWindowListener(new PCDDatabaseFrameAdapter());

+    }

+

+    /**

+      Initiliaze the TREE control.

+    **/

+    public JTree initializeTree() {

+        Token[]                tokenArray     = null;

+        Token                  token          = null;

+        DefaultMutableTreeNode root           = new DefaultMutableTreeNode("PCDTreeRoot");

+        DefaultMutableTreeNode rootByPCD      = new DefaultMutableTreeNode("By PCD");

+        DefaultMutableTreeNode rootByModule   = new DefaultMutableTreeNode("By Module");

+        DefaultMutableTreeNode tokenNode      = null;

+        DefaultMutableTreeNode usageNode      = null;

+        DefaultMutableTreeNode moduleNode     = null;

+        java.util.List<String> moduleNames    = null;

+        int                    index          = 0; 

+        int                    usageIndex     = 0;

+        int                    moduleIndex    = 0;

+        Object[]               objectArray    = null;

+        java.util.List<UsageInstance>    usageArray     = null;

+        UsageInstance          usageInstance  = null;

+

+        root.add(rootByPCD);

+        //

+        // By PCD Node

+        //

+

+        tokenArray = dbManager.getRecordArray();

+        for (index = 0; index < tokenArray.length; index ++) {

+            token = tokenArray[index];

+            ActionMessage.debug(this, token.cName);

+            tokenNode = new DefaultMutableTreeNode(token.cName);

+            tokenNode.add(new DefaultMutableTreeNode(String.format("TOKEN NUMBER: 0x%08x", token.tokenNumber)));

+            tokenNode.add(new DefaultMutableTreeNode("TOKEN SPACE NAME: " + token.tokenSpaceName.toString()));

+            tokenNode.add(new DefaultMutableTreeNode("PCD TYPE: " + Token.getStringOfpcdType(token.pcdType)));

+            tokenNode.add(new DefaultMutableTreeNode("DATUM TYPE: " +Token.getStringOfdatumType(token.datumType)));

+            tokenNode.add(new DefaultMutableTreeNode("DATUM: " + token.datum.toString()));

+            tokenNode.add(new DefaultMutableTreeNode("HIIENABLE: " +(token.hiiEnabled?"true":"false")));

+            tokenNode.add(new DefaultMutableTreeNode("VARIABLE NAME: " + token.variableName));

+            //tokenNode.add(new DefaultMutableTreeNode("VARIABLE GUID: " + token.variableGuid.toString()));

+            tokenNode.add(new DefaultMutableTreeNode("SKUENABLE: " +(token.skuEnabled?"true":"false")));

+            tokenNode.add(new DefaultMutableTreeNode(String.format("SKUID: %d", token.skuId)));

+            tokenNode.add(new DefaultMutableTreeNode(String.format("MAX SKU COUNT: %d", token.maxSkuCount)));

+            tokenNode.add(new DefaultMutableTreeNode("VPDENABLE: " +(token.vpdEnabled?"true":"false")));

+

+            usageNode = new DefaultMutableTreeNode("PRODUCER");

+            tokenNode.add(usageNode);

+

+

+            //

+            // Prepare consumer's leaf node

+            //

+            usageNode = new DefaultMutableTreeNode("CONSUMER");

+            tokenNode.add(usageNode);

+            objectArray = token.consumers.entrySet().toArray();

+            for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) {

+                usageInstance = (UsageInstance) ((Map.Entry)objectArray[usageIndex]).getValue();

+                usageNode.add(new DefaultMutableTreeNode(usageInstance.getPrimaryKey()));

+            }

+

+            rootByPCD.add(tokenNode);

+        }

+

+        //

+        // BY MODULE Node

+        //

+        root.add(rootByModule);

+        moduleNames = dbManager.getAllModuleArray();

+        for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {

+            ActionMessage.debug(this, "ModuleName:" + moduleNames.get(moduleIndex));

+        }

+        for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {

+            moduleNode = new DefaultMutableTreeNode(moduleNames.get(moduleIndex));

+            usageArray = dbManager.getUsageInstanceArrayByKeyString(moduleNames.get(moduleIndex));

+            for (usageIndex = 0; usageIndex < usageArray.size(); usageIndex ++) {

+                usageInstance = usageArray.get(usageIndex);

+                usageNode = new DefaultMutableTreeNode(usageInstance.parentToken.cName);

+                usageNode.add(new DefaultMutableTreeNode("MODULE PCD TYPE: " + Token.getStringOfpcdType(usageInstance.modulePcdType)));

+                moduleNode.add(usageNode);

+            }

+            rootByModule.add(moduleNode);

+        }

+

+        databaseTree = new JTree(root);

+        return databaseTree;

+    }

+}

+

+/**

+  The adatper class for PCDDatabaseFrame. This class instance many windows message 

+  callback function.

+**/

+class PCDDatabaseFrameAdapter  extends WindowAdapter {

+    public void windowClosing(WindowEvent e) {

+        System.exit(0);

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
new file mode 100644
index 0000000..f487359
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
@@ -0,0 +1,218 @@
+/** @file

+  ConfigReader class.

+  

+  ConfigReader is used to read tool chain config file with flat format. 

+  

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.build.toolchain;

+

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.Map;

+import java.util.Set;

+import java.util.Vector;

+

+import org.apache.tools.ant.BuildException;

+

+/**

+  

+  ConfigReader is used to read tool chain config file with flat format. Comments

+  is line starting with character '#'.

+  

+  @since GenBuild 1.0

+**/

+public class ConfigReader {

+

+    private static String confPath = ".";

+

+    /**

+      Public construct method. 

+    **/

+    public ConfigReader () {

+    }

+

+    /**

+      Default filepath is ".".

+    

+      @param filename the config file name like "target.txt"

+      @return the variables defined in file

+    **/

+    public static synchronized String[][] parse(String filename) {

+        return parse(confPath, filename);

+    }

+

+    /**

+      Get all variables defined in config file. the config file format is flat

+      with "A=B". If line started with '#' looks as comments. 

+    

+      @param confPath the path of config file

+      @param filename the file name of the config file

+      @return the variables defined in the config file

+      @throws BuildException

+              Config file's format is not valid

+    **/

+    public static synchronized String[][] parse(String confPath, String filename) throws BuildException {

+        try {

+            Map<String, String> map = new HashMap<String, String>(20);

+            File file = new File(confPath + File.separatorChar + filename);

+            FileReader reader = new FileReader(file);

+            BufferedReader in = new BufferedReader(reader);

+            String str;

+            while ((str = in.readLine()) != null) {

+                str = str.trim();

+                //

+                // if str is empty line or comments (start with '#')

+                //

+                if (str.equalsIgnoreCase("") || str.startsWith("#")) {

+                    continue;

+                }

+                //

+                // if str without '=' or start with '='

+                //

+                if (str.indexOf('=') <= 0) {

+                    continue;

+                }

+                //

+                // look as line "A = B"

+                //

+                int index = str.indexOf('=');

+                String key = str.substring(0, index).trim();

+                String value = str.substring(index + 1).trim();

+                //

+                // if key is existed, then update

+                //

+                if (map.containsKey(key)) {

+                    map.remove(key);

+                }

+                map.put(key, value);

+            }

+            Set keyset = map.keySet();

+            Iterator iter = keyset.iterator();

+            String[][] result = new String[map.size()][2];

+            int i = 0;

+            while (iter.hasNext()) {

+                String key = (String) iter.next();

+                result[i][0] = key;

+                result[i++][1] = (String) map.get(key);

+            }

+            return result;

+        } catch (Exception e) {

+            throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());

+        }

+    }

+

+    /**

+      Parse global flags table. The format is like such(global flag name, value, 

+      vendor_arch_cmd, [add flags], [sub flags]): 

+      

+      <pre>

+        # EFI_DEBUG

+        EFI_DEBUG YES MSFT_IA32_ASM    ADD.["/Zi", "/DEBUG"]

+        EFI_DEBUG YES MSFT_IA32_CC     ADD.["/Zi", "/Gm", "/D EFI_DEBUG"] SUB.["/nologo", "/WX"]

+        EFI_DEBUG YES MSFT_IA32_LINK   ADD.["/DEBUG"]

+        EFI_DEBUG YES MSFT_NT32_CC     ADD.["/DEBUG"]

+      </pre>

+     

+      @param confPath the file path of config file

+      @param filename the file name of config file

+      @return the value list

+      @throws BuildException

+              Config file is not valid

+    **/

+    public static synchronized String[][] parseTable(String confPath,

+                    String filename) throws BuildException {

+        try {

+            Vector<String[]> vector = new Vector<String[]>(20);

+            File file = new File(confPath + File.separatorChar + filename);

+            FileReader reader = new FileReader(file);

+            BufferedReader in = new BufferedReader(reader);

+            String str;

+            while ((str = in.readLine()) != null) {

+                str = str.trim();

+                //

+                // if str is empty line or comments (start with '#')

+                //

+                if (str.equalsIgnoreCase("") || str.startsWith("#")) {

+                    continue;

+                }

+                String[] item = new String[5];

+                for(int i=0; i < item.length; i++){

+                    item[i] = "";

+                }

+                //

+                // EFI_DEBUG YES MSFT_IA32_ASM    ADD.["/Zi", "/DEBUG"]

+                // FLAGS: EFI_DEBUG

+                //

+                int index = str.indexOf(" ");

+                item[0] = str.substring(0, index);

+                str = str.substring(index + 1).trim();

+                //

+                // Setting: YES

+                //

+                index = str.indexOf(" ");

+                item[1] = str.substring(0, index);

+                str = str.substring(index + 1).trim();

+                //

+                // Vendor_Arch_Commandtype: MSFT_IA32_ASM

+                //

+                index = str.indexOf(" ");

+                item[2] = str.substring(0, index);

+                str = str.substring(index + 1).trim();

+                //

+                // Add or/and Sub

+                //

+                if (str.startsWith("ADD.")) {

+                    index = str.indexOf("]");

+                    if ( index > 0){

+                        item[3] = str.substring(5, index);

+                        str = str.substring(index + 1).trim();

+                    }

+                }

+                else if(str.startsWith("SUB.")){

+                    index = str.indexOf("]");

+                    if ( index > 0){

+                        item[4] = str.substring(5, index);

+                        str = str.substring(index + 1).trim();

+                    }

+                }

+                else {

+                    throw new BuildException("File [" + filename + "] never conform to Global Flags Table format.");

+                }

+                

+                if (str.startsWith("ADD.")) {

+                    index = str.indexOf("]");

+                    if ( index > 0){

+                        item[3] = str.substring(5, index);

+                        str = str.substring(index + 1).trim();

+                    }

+                }

+                else if(str.startsWith("SUB.")){

+                    index = str.indexOf("]");

+                    if ( index > 0){

+                        item[4] = str.substring(5, index);

+                        str = str.substring(index + 1).trim();

+                    }

+                }

+                vector.addElement(item);

+            }

+            String[][] result = new String[vector.size()][5];

+            for(int i=0; i < vector.size(); i++){

+                result[i] = (String[])vector.get(i);

+            }

+            return result;

+        } catch (Exception e) {

+            throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
new file mode 100644
index 0000000..ce8e93f
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
@@ -0,0 +1,529 @@
+/** @file

+  ToolChainFactory class.

+  

+  ToolChainFactory class parse all config files and get STD_FLAGS, GLOBAL_FLAGS,

+  and also command path + name.

+  

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+**/

+package org.tianocore.build.toolchain;

+

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.Map;

+import java.util.Set;

+import java.util.StringTokenizer;

+import java.io.File;

+

+import org.apache.tools.ant.Project;

+

+

+/**

+  This class parse all config files and get STD_FLAGS, GLOBAL_FLAGS, and also 

+  command path + name.

+  

+  @since GenBuild 1.0

+**/

+public class ToolChainFactory {

+    ///

+    /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC

+    ///

+    public final static String[] arch = { "EBC", "ARM", "IA32", "X64", "IPF",

+                    "PPC"};

+

+    ///

+    /// list of OS: Linux, Windows

+    ///

+    public final static String[] os = { "WINDOWS", "LINUX" };

+

+    ///

+    /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP

+    ///

+    public final static String[] commandType = { "CC", "LIB", "LINK", "ASL",

+                    "ASM", "ASMLINK", "PP" };

+

+    ///

+    /// default command name for every command

+    ///

+    public final static String[][] defaultCmdName = { { "CC", "cl" },

+                    { "LIB", "lib" }, { "LINK", "link" }, { "ASL", "iasl" },

+                    { "ASM", "ml" }, { "ASMLINK", "link" }, { "PP", "cl" } };

+

+    private String confPath = ".";

+    

+    private String toolChainName = "MSFT";

+

+    private String sTargetFilename = "target.txt";

+

+    private String sToolsdefFilename = "tools_def.txt";

+

+    private String sWorkspaceTarget = "WORKSPACE_TARGET";

+

+    private String sTargetArch = "TARGET_ARCH";

+

+    private HashMap<String,String[][]> filesMap = new HashMap<String,String[][]>();

+    

+    private HashMap<String,String> globalFlagsMap = new HashMap<String,String>();

+    

+    private String[][] globalFlagTable;

+    

+    private String currentTarget = "RELEASE";

+

+    ///

+    /// toolchain array list all results by parsing config files

+    ///

+    public static String[][] toolchain = null;

+    

+    /**

+      Public construct method.

+    **/

+    public ToolChainFactory () {

+    }

+

+    /**

+      Public construct method.

+      

+      @param project current ANT Project.

+    **/

+    public ToolChainFactory (Project project) {

+        this.confPath = project.replaceProperties("${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Conf");

+    }

+    

+    /**

+      Public construct method.

+      

+      @param confPath the path of config files

+      @param toolChainName TOOL_CHAIN name

+    **/

+    public ToolChainFactory (String confPath, String toolChainName) {

+        this.confPath = confPath;

+        //

+        // If set tool used the set one, otherwise use default one.

+        // toolChain used to define open tools define txt file.

+        //

+        if (toolChainName != null && toolChainName.length() > 0){

+            this.toolChainName = toolChainName;

+        }

+    }

+

+    /**

+      Parse all config files, following are the detail steps:

+      

+      <ul>

+        <li>Parse target.txt file. This file define the current build TARGET 

+        and supported ARCH list. </li>

+        <li>Parse tools_def.txt file. This file define every command name, path

+        and vendor. </li>

+        <li>For every supported ARCH and Command Type, find out STD_FLAGS, 

+        GLOBAL_ADD_FLAGS, GLOBAL_SUB_FLAGS. </li>

+      </ul>

+      

+      <p>Note that this method will be called only once during the whole build

+      process. </p>

+    **/

+    public void setupToolChain() {

+        if (toolchain != null) {

+            return ;

+        }

+        Map<String, String> map = new HashMap<String, String>(40);

+        //

+        // parse target.txt

+        //

+        String[][] target = ConfigReader.parse(confPath, sTargetFilename);

+        //

+        // get workspace_target and initialize global flags setting

+        //

+        currentTarget = getValue(sWorkspaceTarget, target);

+        parseGlobalSetting(currentTarget);

+        String[] archList = getArchs(getValue(sTargetArch, target));

+        

+        //

+        // If user write the ${toolChain}_Tools_Def.txt use this one,

+        // otherwise used "tools_def.txt" file.

+        //

+        File tempFile = new File (confPath + File.separator + toolChainName.toLowerCase() + "_tools_def.txt");

+        if (tempFile.exists()){

+            sToolsdefFilename = toolChainName.toLowerCase() + "_tools_def.txt";

+        }

+        

+        System.out.println("Tools definition file is: " + sToolsdefFilename);

+        //

+        // parse tools_def.txt

+        //

+        String[][] tools_def = ConfigReader.parse(confPath, sToolsdefFilename);

+        //

+        // for each arch find all command's path&name and flags

+        //

+        for (int i = 0; i < archList.length; i++) {

+            for (int j = 0; j < commandType.length; j++) {

+                //

+                // Path & Name

+                //

+                map.put(archList[i] + "_" + commandType[j], getAbsoluteCmdPath(

+                                archList[i], commandType[j], tools_def));

+                //

+                // Flags: CMD_STD_FLAGS + CMD_GLOBAL_FLAGS + CMD_PROJ_FLAGS

+                // ARCH_CMD_STD_FLAGS

+                //

+                map.put(archList[i] + "_" + commandType[j] + "_STD_FLAGS",

+                                getStdFlags(archList[i], commandType[j],

+                                                tools_def));

+                //

+                // Flags:ARCH_CMD_VENDOR or ARCH_VENDOR

+                //

+                map.put(archList[i]+ "_"+commandType[j]+"_VENDOR", getVendorFlag(archList[i],

+                        commandType[j], tools_def));

+                //

+                // ARCH_CMD_GLOBAL_FLAGS

+                //

+                String[] globalFlags = getGlobalFlags(archList[i], commandType[j],

+                                tools_def);

+                map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_ADD_FLAGS",

+                                globalFlags[0]);

+                map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_SUB_FLAGS",

+                                globalFlags[1]);

+                //

+                // ARCH_CMD_GLOBAL_FLAGS, default is "".

+                //

+                map.put(archList[i] + "_" + commandType[j] + "_PROJ_FLAGS", "");

+            }

+            map.put(archList[i]+"_VENDOR", getVendorFlag(archList[i], null, tools_def));

+        }

+        Set keyset = map.keySet();

+        Iterator iter = keyset.iterator();

+        String[][] result = new String[map.size()][2];

+        int i = 0;

+        while (iter.hasNext()) {

+            String key = (String) iter.next();

+            result[i][0] = key;

+            result[i++][1] = (String) map.get(key);

+        }

+        toolchain = result;

+    }

+

+    /**

+      Get the standard flags (STD_FLAGS) for specified arch and command type. 

+      

+      <ul>

+        <li>Find out Vendor that cmd Command Type with arch ARCH used. The 

+        search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here

+        we suppose default Vendor is MSFT.</li>

+        <li>Search ${Vendor}_tools.txt file, and get the corrsponding flags. 

+        </li>

+      </ul>

+      

+      @param arch the ARCH

+      @param cmd the command type

+      @param map detail flags information of tools_def.txt

+      @return the standard flags of arch ARCH and cmd Command Type 

+    **/

+    private String getStdFlags(String arch, String cmd, String[][] map) {

+        //

+        // first is to find out its Vendor in map

+        // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"

+        // Here we suppose default Vendor is MSFT.

+        //

+        String vendor = "MSFT";

+        String str;

+        if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {

+            vendor = str;

+        } else if ((str = getValue(arch + "_VENDOR", map)) != null) {

+            vendor = str;

+        }

+        //

+        // change to low letter

+        //

+        vendor = vendor.toLowerCase();

+        //

+        // parse the corresponding file and get arch_cmd value

+        //

+        String filename = vendor + "_tools.txt";

+        String[][] flagsMap;

+        if (filesMap.containsKey(filename)) {

+            flagsMap = (String[][]) filesMap.get(filename);

+        } else {

+            //

+            // read file and store in filesMap

+            //

+            flagsMap = ConfigReader.parse(confPath, vendor + "_tools.txt");

+            filesMap.put(filename, flagsMap);

+        }

+        if ((str = getValue(arch + "_" + cmd, flagsMap)) != null) {

+            return str;

+        }

+        return "";

+    }

+

+    /**

+      Get the global flags (GLOBAL_ADD_FLAGS & GLOBAL_SUB_FLAGS) for specified 

+      arch and command type. 

+      

+      <ul>

+        <li>Find out Vendor that cmd Command Type with arch ARCH used. The 

+        search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here

+        we suppose default Vendor is MSFT.</li>

+        <li>Search efi_flags_table.txt file, and get the corrsponding flags. 

+        </li>

+      </ul>

+      

+      @param arch the ARCH

+      @param cmd the command type

+      @param map detail flags information of tools_def.txt

+      @return two values, first is GLOBAL_ADD_FLAGS and another value is 

+      GLOBAL_SUB_FLAGS

+    **/

+    private String[] getGlobalFlags(String arch, String cmd, String[][] map) {

+        String addStr = "";

+        String subStr = "";

+        //

+        // first is to find out its Vendor in map

+        // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"

+        // Here we suppose default Vendor is MSFT.

+        //

+        String vendor = "MSFT";

+        String str;

+        if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {

+            vendor = str;

+        } else if ((str = getValue(arch + "_VENDOR", map)) != null) {

+            vendor = str;

+        }

+        //

+        // parse global flags table

+        //

+        if (globalFlagTable == null) {

+            globalFlagTable =  ConfigReader.parseTable(confPath, "efi_flags_table.txt");

+        }

+        for (int i=0; i < globalFlagTable.length; i++){

+            String[] item = globalFlagTable[i];

+            if (item[2].equalsIgnoreCase(vendor + "_" + arch + "_" + cmd)){

+                //

+                // if item[0] == item[1] is existed in globalFlagsMap

+                //

+                if (globalFlagsMap.containsKey(item[0])){

+                    if( item[1].equalsIgnoreCase((String)globalFlagsMap.get(item[0]))){

+                        addStr += item[3] + " ";

+                        subStr += item[4] + " ";

+                    }

+                }

+            }

+        }

+        

+        return new String[]{addStr, subStr};

+    }

+

+    /**

+      Find out command path and command name. 

+      

+      <pre>

+        Command path searching sequence in tools_def.txt file:

+        Path: ARCH_CMD_PATH -> ARCH_PATH -> Set to "".

+        

+        Command name searching sequence in tools_def.txt file:

+        Name: ARCH_CMD_NAME -> CMD_NAME -> Default Value.

+      </pre>

+      

+      @param arch the ARCH

+      @param cmd the Command Type

+      @param map detail flags information of tools_def.txt

+      @return the absolute command path and name

+    **/

+    private String getAbsoluteCmdPath(String arch, String cmd, String[][] map) {

+        String path = "";

+        String name = "";

+        String str;

+        //

+        // find Path

+        //

+        if ((str = getValue(arch + "_" + cmd + "_PATH", map)) != null) {

+            path = str;

+        } else if ((str = getValue(arch + "_PATH", map)) != null) {

+            path = str;

+        }

+        //

+        // find Name

+        //

+        if ((str = getValue(arch + "_" + cmd + "_NAME", map)) != null) {

+            name = str;

+        } else if ((str = getValue(cmd + "_NAME", map)) != null) {

+            name = str;

+        } else {

+            name = getValue(cmd, defaultCmdName);

+        }

+        if (path.equalsIgnoreCase("")) {

+            return name;

+        }

+        return path + File.separatorChar + name;

+    }

+

+    /**

+      Find out all global flags value, such as EFI_DEBUG equal YES or NO. Here 

+      are three type files: global_efi_flags.txt, ${TARGET}_efi_flags.txt, 

+      my_efi_flags.txt. global_efi_flags.txt with the highest priority while 

+      my_efi_flags.txt with the lowest priority. 

+      

+      <p>All global flags value will store in <code>globalFlagsMap</code> for 

+      getGlobalFlags using. </p> 

+      

+      @param target current build TARGET value

+    **/

+    private void parseGlobalSetting(String target){

+        //

+        // parse global_efi_flags -> ${TARGET}_efi_flags -> my_efi_flags

+        // parse global_efi_flags

+        //

+        String[][] map = ConfigReader.parse(confPath, "global_efi_flags.txt");

+        for (int i = 0; i < map.length; i++){

+            if(globalFlagsMap.containsKey(map[i][0])){

+                globalFlagsMap.remove(map[i][0]);

+            }

+            globalFlagsMap.put(map[i][0], map[i][1]);

+        }

+        //

+        // parse ${TARGET}_efi_flags

+        //

+        map = ConfigReader.parse(confPath, target.toLowerCase() + "_efi_flags.txt");

+        for (int i = 0; i < map.length; i++){

+            if(globalFlagsMap.containsKey(map[i][0])){

+                globalFlagsMap.remove(map[i][0]);

+            }

+            globalFlagsMap.put(map[i][0], map[i][1]);

+        }

+        //

+        // parse my_efi_flags.txt

+        //

+        map = ConfigReader.parse(confPath, "my_efi_flags.txt");

+        for (int i = 0; i < map.length; i++){

+            if(globalFlagsMap.containsKey(map[i][0])){

+                globalFlagsMap.remove(map[i][0]);

+            }

+            globalFlagsMap.put(map[i][0], map[i][1]);

+        }

+    }

+    

+    /**

+      Find value with key from map. If not found, return null. 

+      

+      <p>Note that default is case-insensitive</p>

+      

+      @param key key value

+      @param map mapping information

+      @return the related value of key

+    **/

+    private String getValue(String key, String[][] map) {

+        return getValue(key, map, false);

+    }

+

+    /**

+      Find value with key from map. If not found, return null. 

+      

+      @param key key value

+      @param map mapping information

+      @param caseSensitive whether case sesitive or not

+      @return the related value of key

+    **/

+    private String getValue(String key, String[][] map, boolean caseSensitive) {

+        for (int i = 0; i < map.length; i++) {

+            if (caseSensitive) {

+                if (key.compareTo(map[i][0]) == 0) {

+                    return map[i][1];

+                }

+            } else {

+                if (key.compareToIgnoreCase(map[i][0]) == 0) {

+                    return map[i][1];

+                }

+            }

+        }

+        return null;

+    }

+

+    /**

+      Find value with key from <code>toolchain</code>. If not found, return null. 

+    

+      @param key key value

+      @return the related value of key

+    **/

+    public static String getValue(String key){

+        for (int i = 0; i < toolchain.length; i++) {

+            if (key.compareToIgnoreCase(toolchain[i][0]) == 0) {

+                return toolchain[i][1];

+            }

+        }

+        return null;

+    }

+    

+    /**

+      Get Arch list from a string separated with comma. 

+      

+      <pre>

+        For example:

+          If the arch string is "IA32, X64, EBC".

+          Then the result is {"IA32", "X64", "EBC"}. 

+      </pre>

+    

+      @param arch string separated with comma

+      @return Arch list

+    **/

+    public String[] getArchs(String arch) {

+        if (arch == null) {

+            return new String[0];

+        }

+        StringTokenizer st = new StringTokenizer(arch, " \t,");

+        String[] archs = new String[st.countTokens()];

+        int i = 0;

+        while (st.hasMoreTokens()) {

+            archs[i++] = st.nextToken().toUpperCase();

+        }

+        return archs;

+    }

+

+    /**

+      Get current target value.

+    

+      @return current target value

+    **/

+    public String getCurrentTarget() {

+        return currentTarget;

+    }

+

+    /**

+      Find out Vendor that cmd Command Type with arch ARCH used. The 

+      search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here

+      we suppose default Vendor is MSFT.

+      

+      @param arch the ARCH

+      @param cmd the Command Type

+      @param map detail flags information of tools_def.txt

+      @return the related vendor name

+    **/

+    public String getVendorFlag (String arch, String cmdType, String[][] map){

+        //

+        // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"

+        // Here we suppose default Vendor is MSFT.

+        //

+        String str;

+        String vendor = "";

+        if (cmdType != null){

+            if ((str = getValue(arch + "_" + cmdType + "_VENDOR", map)) != null) {

+                vendor = str; 

+            }else {

+                vendor = "";

+            }

+        }else if (arch != null){

+            if ((str = getValue(arch + "_VENDOR", map)) != null) {

+                vendor = str; 

+            }else {

+                vendor = "";

+            }

+        }

+        return vendor;

+    }

+    

+}

diff --git a/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java b/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
new file mode 100644
index 0000000..04dab1c
--- /dev/null
+++ b/edk2/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
@@ -0,0 +1,60 @@
+/** @file

+  ToolChainTask class.

+  

+  ToolChainTask class's main fucntion is read all tool chain related config files. 

+

+Copyright (c) 2006, Intel Corporation                                                         

+All rights reserved. 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.  

+

+**/

+package org.tianocore.build.toolchain;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+

+/**

+  This class is an ANT task. The main function is to read all tool chain related

+  config files. 

+  

+  @since GenBuild 1.0

+**/

+public class ToolChainTask extends Task{

+

+    private String confPath = ".";

+    

+    /**

+      Public construct method. It is necessary for ANT task.

+    **/

+    public ToolChainTask(){

+    }

+    

+    /**

+      ANT task's entry point, will be called after init(). Using

+      <code>ToolChainFactory</code> to parse all config files, and

+      set TARGET property. 

+    

+      @throws BuildException

+              Config files are invalid.

+    **/

+    public void execute() throws BuildException {

+        String toolChain = getProject().getProperty("env.TOOL_CHAIN");

+        ToolChainFactory toolchain = new ToolChainFactory(confPath, toolChain);

+        toolchain.setupToolChain();

+        getProject().setProperty("TARGET", toolchain.getCurrentTarget());

+    }

+

+    /**

+      Set the path of config files.

+      

+      @param confPath the path of config files

+    **/

+    public void setConfPath(String confPath) {

+        this.confPath = confPath;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/MANIFEST.MF b/edk2/Tools/Source/ModuleEditor/MANIFEST.MF
new file mode 100644
index 0000000..544cd0b
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0

+Main-Class: org.tianocore.packaging.module.ui.ModuleMain

diff --git a/edk2/Tools/Source/ModuleEditor/build.xml b/edk2/Tools/Source/ModuleEditor/build.xml
new file mode 100644
index 0000000..2696c71
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/build.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="ModuleEditor" default="all" basedir=".">

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env"/>

+  <property name="WORKSPACE" value="${env.WORKSPACE}"/>

+  <path id="classpath">

+    <fileset dir="${WORKSPACE}/Tools/Jars" includes="*.jar"/>

+    <fileset dir="${env.XMLBEANS_HOME}/lib" includes="*.jar"/>

+  </path>

+  <property name="buildDir" value="build"/>

+  <property name="installLocation" value="${WORKSPACE}/Tools/bin"/>

+  <target name="all" depends="install"/>

+  <target name="source">

+    <mkdir dir="${buildDir}"/>

+    <javac srcdir="src" destdir="${buildDir}">

+      <classpath refid="classpath"/>

+      <!-- <compilerarg value="-Xlint"/> -->

+    </javac>

+  </target>

+  <target name="clean">

+    <delete dir="${buildDir}"/>

+  </target>

+  <target name="cleanall">

+    <delete dir="${buildDir}"/>

+    <delete file="${installLocation}/ModuleEditor.jar"/>

+  </target>

+  <target name="install" depends="source">

+    <jar destfile="${installLocation}/ModuleEditor.jar"

+      basedir="${buildDir}"

+      includes="**"

+      manifest="MANIFEST.MF"

+    />

+  </target>

+</project>

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/DataType.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/DataType.java
new file mode 100644
index 0000000..ea0731b
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/DataType.java
@@ -0,0 +1,44 @@
+/** @file

+ 

+ The file is used to define all used final variables

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+package org.tianocore.common;

+

+/**

+ The class is used to define all used final variables

+ 

+ @since ModuleEditor 1.0

+

+**/

+public class DataType {

+

+    /**

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+    

+    //

+    // Define all used final variables

+    //

+    public static final String DOS_LINE_SEPARATOR = "\r\n";

+

+    public static final String UNXI_LINE_SEPARATOR = "\n";

+    

+    public static final String EMPTY_SELECT_ITEM = "----";

+

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/DataValidation.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/DataValidation.java
new file mode 100644
index 0000000..4747343
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/DataValidation.java
@@ -0,0 +1,905 @@
+/** @file

+ 

+ The file is used to provides all kinds of Data Validation interface 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+

+ **/

+

+package org.tianocore.common;

+

+import java.util.regex.Matcher;

+import java.util.regex.Pattern;

+

+/**

+ The class is used to provides all kinds of data validation interface

+

+ <p>All provided interfaces are in static mode</p>

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class DataValidation {

+

+    /**

+     Reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    //

+    // The below is used to check common data types

+    //

+

+    /**

+     Check if the imput data is int

+     

+     @param strInt The input string which needs validation

+     

+     @retval true - The input is Int

+     @retval false - The input is not Int

+     

+     **/

+    public static boolean isInt(String strInt) {

+        return isMatch("^-?[0-9]\\d*$", strInt);

+    }

+

+    /**

+     Check if the input data is int and it is in the valid scope

+     The scope is provided by String

+     

+     @param strNumber The input string which needs validation

+     @param BeginNumber The left boundary of the scope

+     @param EndNumber The right boundary of the scope

+     

+     @retval true - The input is Int and in the scope;

+     @retval false - The input is not Int or not in the scope

+     

+     **/

+    public static boolean isInt(String strNumber, int BeginNumber, int EndNumber) {

+        //

+        //Check if the input data is int first

+        //

+        if (!isInt(strNumber)) {

+            return false;

+        }

+        //

+        //And then check if the data is between the scope

+        //

+        Integer intTemp = new Integer(strNumber);

+        if ((intTemp.intValue() < BeginNumber) || (intTemp.intValue() > EndNumber)) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Check if the input data is int and it is in the valid scope

+     The scope is provided by String

+     

+     @param strNumber The input string which needs validation

+     @param strBeginNumber The left boundary of the scope

+     @param strEndNumber The right boundary of the scope

+     

+     @retval true - The input is Int and in the scope;

+     @retval false - The input is not Int or not in the scope

+     

+     **/

+    public static boolean isInt(String strNumber, String strBeginNumber, String strEndNumber) {

+        //

+        //Check if all input data are int

+        //

+        if (!isInt(strNumber)) {

+            return false;

+        }

+        if (!isInt(strBeginNumber)) {

+            return false;

+        }

+        if (!isInt(strEndNumber)) {

+            return false;

+        }

+        //

+        //And then check if the data is between the scope

+        //

+        Integer intI = new Integer(strNumber);

+        Integer intJ = new Integer(strBeginNumber);

+        Integer intK = new Integer(strEndNumber);

+        if ((intI.intValue() < intJ.intValue()) || (intI.intValue() > intK.intValue())) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Use regex to check if the input data is in valid format

+     

+     @param strPattern The input regex

+     @param strMatcher The input data need be checked

+     

+     @retval true - The data matches the regex

+     @retval false - The data doesn't match the regex

+     

+     **/

+    public static boolean isMatch(String strPattern, String strMatcher) {

+        Pattern pattern = Pattern.compile(strPattern);

+        Matcher matcher = pattern.matcher(strMatcher);

+

+        return matcher.find();

+    }

+

+    //

+    // The below is used to check common customized data types

+    //

+

+    /**

+     Check if the input data is BaseNameConvention

+     

+     @param strBaseNameConvention The input string need be checked

+     

+     @retval true - The input is BaseNameConvention

+     @retval false - The input is not BaseNameConvention

+     

+     **/

+    public static boolean isBaseNameConvention(String strBaseNameConvention) {

+        return isMatch("[A-Z]([a-zA-Z0-9])*(_)?([a-zA-Z0-9])*", strBaseNameConvention);

+    }

+

+    /**

+     Check if the input data is GuidArrayType

+     

+     @param strGuidArrayType The input string need be checked

+     

+     @retval true - The input is GuidArrayType

+     @retval false - The input is not GuidArrayType

+     

+     **/

+    public static boolean isGuidArrayType(String strGuidArrayType) {

+        return isMatch(

+                       "0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?",

+                       strGuidArrayType);

+    }

+

+    /**

+     Check if the input data is GuidNamingConvention

+     

+     @param strGuidNamingConvention The input string need be checked

+     

+     @retval true - The input is GuidNamingConvention

+     @retval false - The input is not GuidNamingConvention

+     

+     **/

+    public static boolean isGuidNamingConvention(String strGuidNamingConvention) {

+        return isMatch("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}",

+                       strGuidNamingConvention);

+    }

+

+    /**

+     Check if the input data is GuidType 

+     

+     @param strGuidType The input string need be checked

+     

+     @retval true - The input is GuidType

+     @reture false is not GuidType

+     

+     **/

+    public static boolean isGuidType(String strGuidType) {

+        return (isGuidArrayType(strGuidType) || isGuidNamingConvention(strGuidType));

+    }

+

+    /**

+     Check if the input data is Guid 

+     

+     @param strGuid The input string need be checked

+     

+     @retval true - The input is Guid

+     @retval false - The input is not Guid

+     

+     **/

+    public static boolean isGuid(String strGuid) {

+        return isGuidType(strGuid);

+    }

+

+    /**

+     Check if the input data is Sentence

+     

+     @param strSentence The input string need be checked

+     

+     @retval true - The input is Sentence

+     @retval false - The input is not Sentence

+     

+     **/

+    public static boolean isSentence(String strSentence) {

+        return isMatch("(\\w+\\W*)+( )+(\\W*\\w*\\W*\\s*)*", strSentence);

+    }

+

+    /**

+     Check if the input data is DateType

+     

+     @param strDateType The input string need be checked

+     

+     @retval true - The input is DateType

+     @retval false - The input is not DateType

+     

+     **/

+    public static boolean isDateType(String strDateType) {

+        return isMatch("[1-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]", strDateType);

+    }

+

+    /**

+     Check if the input data is DosPath

+     

+     @param strDosPath The input string need be checked

+     

+     @retval true - The input is DosPath

+     @retval false - The input is not DosPath

+     

+     **/

+    public static boolean isDosPath(String strDosPath) {

+        return isMatch("([a-zA-Z]:\\\\)?(((\\\\?_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\\\\)?)*", strDosPath);

+    }

+

+    /**

+     Check if the input data is UnixPath

+     

+     @param strUnixPath The input string need be checked

+     

+     @retval true - The input is UnixPath

+     @retval false - The input is not UnixPath

+     

+     **/

+    public static boolean isUnixPath(String strUnixPath) {

+        return isMatch("(\\/)?(((_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\\/)?)*", strUnixPath);

+    }

+

+    /**

+     Check if the input data is DirectoryNamingConvention

+     

+     @param strDirectoryNamingConvention The input string need be checked

+     

+     @retval true - The input is DirectoryNamingConvention

+     @retval false - The input is not DirectoryNamingConvention

+     

+     **/

+    public static boolean isDirectoryNamingConvention(String strDirectoryNamingConvention) {

+        return (isDosPath(strDirectoryNamingConvention) || isUnixPath(strDirectoryNamingConvention));

+    }

+

+    /**

+     Check if the input data is HexDoubleWordDataType

+     

+     @param strHexDoubleWordDataType  The input string need be checked

+     

+     @retval true - The input is HexDoubleWordDataType

+     @retval false - The input is not HexDoubleWordDataType

+     

+     **/

+    public static boolean isHexDoubleWordDataType(String strHexDoubleWordDataType) {

+        return isMatch("0x[a-fA-F0-9]{1,8}", strHexDoubleWordDataType);

+    }

+

+    /**

+     Check if the input data is V1

+     

+     @param strV1 The input string need be checked

+     

+     @retval true - The input is V1

+     @retval false - The input is not V1

+     

+     **/

+    public static boolean isV1(String strV1) {

+        return isMatch("((%[A-Z](_*[A-Z0-9]*)*%)+((((\\\\)?_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\\\\)?)*)", strV1);

+    }

+

+    /**

+     Check if the input data is V2

+     

+     @param strV2 The input string need be checked

+     

+     @retval true - The input is V2

+     @retval false - The input is not V2

+     

+     **/

+    public static boolean isV2(String strV2) {

+        return isMatch(

+                       "(($[A-Z](_*[A-Z0-9]*)*)+||($\\([A-Z](_*[A-Z0-9]*)*\\))+||($\\{[A-Z](_*[A-Z0-9]*)*\\})+)+(\\/)?(((((_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\\/)?)*)*)",

+                       strV2);

+    }

+

+    /**

+     Check if the input data is VariableConvention

+     

+     @param strVariableConvention The input string need be checked

+     

+     @retval true - The input is VariableConvention

+     @retval false - The input is not VariableConvention

+     

+     **/

+    public static boolean isVariableConvention(String strVariableConvention) {

+        return (isV1(strVariableConvention) || isV2(strVariableConvention));

+    }

+

+    /**

+     Check if the input data is UCName

+     

+     @param strUCName The input string need be checked

+     

+     @retval true - The input is UCName

+     @retval false - The input is not UCName

+     

+     **/

+    public static boolean isUCName(String strUCName) {

+        return isMatch("[A-Z]+(_*[A-Z0-9]*( )*)*", strUCName);

+    }

+

+    /**

+     Check if the input data is HexByteDataType

+     

+     @param strHex64BitDataType The input string need be checked 

+     

+     @retval true - The input is HexByteDataType

+     @retval false - The input is not HexByteDataType

+     

+     **/

+    public static boolean isHexByteDataType(String strHex64BitDataType) {

+        return isMatch("(0x)?[a-fA-F0-9]{1,2}", strHex64BitDataType);

+    }

+

+    /**

+     Check if the input data is Hex64BitDataType

+     

+     @param strHex64BitDataType The input string need be checked

+     

+     @retval true - The input is Hex64BitDataType

+     @retval false - The input is not Hex64BitDataType

+     

+     **/

+    public static boolean isHex64BitDataType(String strHex64BitDataType) {

+        return isMatch("(0x)?[a-fA-F0-9]{1,16}", strHex64BitDataType);

+    }

+

+    /**

+     Check if the input data is HexWordDataType

+     

+     @param strHexWordDataType The input string need be checked

+     

+     @retval true - The input is HexWordDataType

+     @retval false - The input is not HexWordDataType

+     

+     **/

+    public static boolean isHexWordDataType(String strHexWordDataType) {

+        return isMatch("0x[a-fA-F0-9]{1,4}", strHexWordDataType);

+    }

+

+    /**

+     Check if the input data is CName

+     

+     @param strCName The input string need be checked

+     

+     @retval true - The input is CName

+     @retval false - The input is not CName

+     

+     **/

+    public static boolean isCName(String strCName) {

+        return isMatch("((_)*([a-zA-Z])+((_)*[a-zA-Z0-9]*))*", strCName);

+    }

+

+    /**

+     Check if the input data is OverrideID

+     

+     @param strOverrideID The input string need be checked

+     

+     @retval true - The input is OverrideID

+     @retval false - The input is not OverrideID

+     

+     **/

+    public static boolean isOverrideID(String strOverrideID) {

+        return isInt(strOverrideID);

+    }

+

+    //

+    //The below is used to check msaheader data type

+    //

+

+    /**

+     Check if the input data is BaseName

+     

+     @param strBaseName The input string need be checked

+     

+     @retval true - The input is BaseName

+     @retval false - The input is not BaseName

+     

+     **/

+    public static boolean isBaseName(String strBaseName) {

+        return isBaseNameConvention(strBaseName);

+    }

+

+    /**

+     Check if the input data is Abstract

+     

+     @param strAbstract The input string need be checked

+     

+     @retval true - The input is Abstract

+     @retval false - The input is not Abstract

+     

+     **/

+    public static boolean isAbstract(String strAbstract) {

+        return isSentence(strAbstract);

+    }

+

+    /**

+     Check if the input data is Copyright

+     

+     @param strCopyright The input string need be checked

+     

+     @retval true - The input is Copyright

+     @retval false - The input is not Copyright

+     

+     **/

+    public static boolean isCopyright(String strCopyright) {

+        return isSentence(strCopyright);

+    }

+

+    /**

+     Check if the input data is Created

+     

+     @param strCreated The input string need be checked

+     

+     @retval true - The input is Created

+     @retval false - The input is not Created

+     

+     **/

+    public static boolean isCreated(String strCreated) {

+        return isDateType(strCreated);

+    }

+

+    /**

+     Check if the input data is Updated

+     

+     @param strUpdated The input string need be checked

+     

+     @retval true - The input is Updated

+     @retval false - The input is not Updated

+     

+     **/

+    public static boolean isUpdated(String strUpdated) {

+        return isDateType(strUpdated);

+    }

+

+    //

+    // The below is used to check LibraryClass data types

+    //

+

+    /**

+     Check if the input data is LibraryClass

+     

+     @param strLibraryClass The input string need be checked

+     

+     @retval true - The input is LibraryClass

+     @retval false - The input is not LibraryClass

+     

+     **/

+    public static boolean isLibraryClass(String strLibraryClass) {

+        return isBaseNameConvention(strLibraryClass);

+    }

+

+    //

+    // The below is used to check sourcefiles data types

+    //

+

+    /**

+     Check if the input data is Path

+     

+     @param strPath The input string need be checked

+     

+     @retval true - The input is Path

+     @retval false - The input is not Path

+     

+     **/

+    public static boolean isPath(String strPath) {

+        return isDirectoryNamingConvention(strPath);

+    }

+

+    /**

+     Check if the input data is FileName

+     

+     @param strFileName The input string need be checked

+     

+     @retval true - The input is FileName

+     @retval false - The input is not FileName

+     

+     **/

+    public static boolean isFileName(String strFileName) {

+        return isVariableConvention(strFileName);

+    }

+

+    //

+    // The below is used to check includes data types

+    //

+

+    /**

+     Check if the input data is UpdatedDate

+     

+     @param strUpdatedDate The input string need be checked

+     

+     @retval true - The input is UpdatedDate

+     @retval false - The input is not UpdatedDate

+     

+     **/

+    public static boolean isUpdatedDate(String strUpdatedDate) {

+        return isDateType(strUpdatedDate);

+    }

+

+    /**

+     Check if the input data is PackageName

+     

+     @param strPackageName The input string need be checked

+     

+     @retval true - The input is PackageName

+     @retval false - The input is not PackageName

+     

+     **/

+    public static boolean isPackageName(String strPackageName) {

+        return isBaseNameConvention(strPackageName);

+    }

+

+    //

+    // The below is used to check protocols data types

+    //

+

+    /**

+     Check if the input data is ProtocolName

+     

+     @param strProtocolName The input string need be checked

+     

+     @retval true - The input is ProtocolName

+     @retval false - The input is not ProtocolName

+     

+     **/

+    public static boolean isProtocolName(String strProtocolName) {

+        return isCName(strProtocolName);

+    }

+

+    /**

+     Check if the input data is ProtocolNotifyName

+     

+     @param strProtocolNotifyName The input string need be checked

+     

+     @retval true - The input is ProtocolNotifyName

+     @retval false - The input is not ProtocolNotifyName

+     

+     **/

+    public static boolean isProtocolNotifyName(String strProtocolNotifyName) {

+        return isCName(strProtocolNotifyName);

+    }

+

+    //

+    // The below is used to check ppis data types

+    //

+

+    /**

+     Check if the input data is PpiName

+     

+     @param strPpiName The input string need be checked

+     

+     @retval true - The input is PpiName

+     @retval false - The input is not PpiName

+     

+     **/

+    public static boolean isPpiName(String strPpiName) {

+        return isCName(strPpiName);

+    }

+

+    /**

+     Check if the input data is PpiNotifyName

+     

+     @param strPpiNotifyName The input string need be checked

+     

+     @retval true - The input is PpiNotifyName

+     @retval false - The input is not PpiNotifyName

+     

+     **/

+    public static boolean isPpiNotifyName(String strPpiNotifyName) {

+        return isCName(strPpiNotifyName);

+    }

+

+    /**

+     Check if the input data is FeatureFlag

+     

+     @param strFeatureFlag The input string need be checked

+     

+     @retval true - The input is FeatureFlag

+     @retval false - The input is not FeatureFlag

+     

+     **/

+    public static boolean isFeatureFlag(String strFeatureFlag) {

+        return isCName(strFeatureFlag);

+    }

+

+    //

+    // The below is used to check variable data types

+    //

+

+    /**

+     Check if the input data is ByteOffset

+     

+     @param strByteOffset The input string need be checked

+     

+     @retval true - The input is ByteOffset

+     @retval false - The input is not ByteOffset

+     

+     **/

+    public static boolean isByteOffset(String strByteOffset) {

+        return isByteOffset(strByteOffset);

+    }

+

+    /**

+     Check if the input data is BitOffset

+     

+     @param strBitOffset The input string need be checked

+     

+     @retval true - The input is BitOffset

+     @retval false - The input is not BitOffset

+     

+     **/

+    public static boolean isBitOffset(String strBitOffset) {

+        return isInt(strBitOffset, 0, 8);

+    }

+

+    /**

+     Check if the input data is OffsetBitSize

+     

+     @param strOffsetBitSize The input string need be checked

+     

+     @retval true - The input is OffsetBitSize

+     @retval false - The input is not OffsetBitSize

+     

+     **/

+    public static boolean isOffsetBitSize(String strOffsetBitSize) {

+        return isInt(strOffsetBitSize, 0, 7);

+    }

+

+    //

+    // The below is used to check formsets data types

+    //

+

+    /**

+     Check if the input data is Formsets

+     

+     @param strFormsets The input string need be checked

+     

+     @retval true - The input is Formsets

+     @retval false - The input is not Formsets

+     

+     **/

+    public static boolean isFormsets(String strFormsets) {

+        return isCName(strFormsets);

+    }

+

+    //

+    // The below is used to check externs data types

+    //

+

+    /**

+     Check if the input data is Constructor

+     

+     @param strConstructor The input string need be checked

+     

+     @retval true - The input is Constructor

+     @retval false - The input is not Constructor

+     

+     **/

+    public static boolean isConstructor(String strConstructor) {

+        return isCName(strConstructor);

+    }

+

+    /**

+     Check if the input data is Destructor

+     

+     @param strDestructor The input string need be checked

+     

+     @retval true - The input is Destructor

+     @retval false - The input is not Destructor

+     

+     **/

+    public static boolean isDestructor(String strDestructor) {

+        return isCName(strDestructor);

+    }

+

+    /**

+     Check if the input data is DriverBinding

+     

+     @param strDriverBinding The input string need be checked

+     

+     @retval true - The input is DriverBinding

+     @retval false - The input is not DriverBinding

+     

+     **/

+    public static boolean isDriverBinding(String strDriverBinding) {

+        return isCName(strDriverBinding);

+    }

+

+    /**

+     Check if the input data is ComponentName

+     

+     @param strComponentName The input string need be checked

+     

+     @retval true - The input is ComponentName

+     @retval false - The input is not ComponentName

+     

+     **/

+    public static boolean isComponentName(String strComponentName) {

+        return isCName(strComponentName);

+    }

+

+    /**

+     Check if the input data is DriverConfig

+     

+     @param strDriverConfig The input string need be checked

+     

+     @retval true - The input is DriverConfig

+     @retval false - The input is not DriverConfig

+     

+     **/

+    public static boolean isDriverConfig(String strDriverConfig) {

+        return isCName(strDriverConfig);

+    }

+

+    /**

+     Check if the input data is DriverDiag

+     

+     @param strDriverDiag The input string need be checked

+     

+     @retval true - The input is DriverDiag

+     @retval false - The input is not DriverDiag

+     

+     **/

+    public static boolean isDriverDiag(String strDriverDiag) {

+        return isCName(strDriverDiag);

+    }

+

+    /**

+     Check if the input data is SetVirtualAddressMapCallBack

+     

+     @param strSetVirtualAddressMapCallBack The input string need be checked

+     

+     @retval true - The input is SetVirtualAddressMapCallBack

+     @retval false - The input is not SetVirtualAddressMapCallBack

+     

+     **/

+    public static boolean isSetVirtualAddressMapCallBack(String strSetVirtualAddressMapCallBack) {

+        return isCName(strSetVirtualAddressMapCallBack);

+    }

+

+    /**

+     Check if the input data is ExitBootServicesCallBack

+     

+     @param strExitBootServicesCallBack The input string need be checked

+     

+     @retval true - The input is ExitBootServicesCallBack

+     @retval false - The input is not ExitBootServicesCallBack

+     

+     **/

+    public static boolean isExitBootServicesCallBack(String strExitBootServicesCallBack) {

+        return isCName(strExitBootServicesCallBack);

+    }

+

+    /**

+     Check if the input data is UserDefined

+     

+     @param strUserDefined The input string need be checked

+     

+     @retval true - The input is UserDefined

+     @retval false - The input is not UserDefined

+     

+     **/

+    public static boolean isUserDefined(String strUserDefined) {

+        return isCName(strUserDefined);

+    }

+

+    //

+    // The below is used to check PCDs data types

+    //

+

+    /**

+     Check if the input data is Token

+     

+     @param strToken The input string need be checked

+     

+     @retval true - The input is Token

+     @retval false - The input is not Token

+     

+     **/

+    public static boolean isToken(String strToken) {

+        return isHexDoubleWordDataType(strToken);

+    }

+

+    /**

+     Check if the input data is MaxSku

+     

+     @param strMaxSku The input string need be checked

+     

+     @retval true - The input is MaxSku

+     @retval false - The input is not MaxSku

+     

+     **/

+    public static boolean isMaxSku(String strMaxSku) {

+        return isHexByteDataType(strMaxSku);

+    }

+

+    /**

+     Check if the input data is SkuId

+     

+     @param strSkuId The input string need be checked

+     

+     @retval true - The input is SkuId

+     @retval false - The input is not SkuId

+     

+     **/

+    public static boolean isSkuId(String strSkuId) {

+        return isHexByteDataType(strSkuId);

+    }

+

+    /**

+     Check if the input data is DatumSize

+     

+     @param strDatumSize The input string need be checked

+     

+     @retval true - The input is DatumSize

+     @retval false - The input is not DatumSize

+     

+     **/

+    public static boolean isDatumSize(String strDatumSize) {

+        return isInt(strDatumSize, 1, 16777215);

+    }

+

+    /**

+     Check if the input data is VariableGuid

+     

+     @param strVariableGuid The input string need be checked

+     

+     @retval true - The input is VariableGuid

+     @retval false - The input is not VariableGuid

+     

+     **/

+    public static boolean isVariableGuid(String strVariableGuid) {

+        return (isGuid(strVariableGuid) || strVariableGuid.equals("0"));

+    }

+

+    /**

+     Check if the input data is DataOffset

+     

+     @param strDataOffset The input string need be checked

+     

+     @retval true - The input is DataOffset

+     @retval false - The input is not DataOffset

+     

+     **/

+    public static boolean isDataOffset(String strDataOffset) {

+        return isHex64BitDataType(strDataOffset);

+    }

+

+    /**

+     Check if the input data is GuidOffset

+     

+     @param strGuidOffset The input string need be checked

+     

+     @retval true - The input is GuidOffset

+     @retval false - The input is not GuidOffset

+     

+     **/

+    public static boolean isGuidOffset(String strGuidOffset) {

+        return isHex64BitDataType(strGuidOffset);

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/IFileFilter.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/IFileFilter.java
new file mode 100644
index 0000000..1daf7fa
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/IFileFilter.java
@@ -0,0 +1,87 @@
+/** @file

+ 

+ The file is used to override FileFilter to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.common;

+

+import java.io.File;

+

+import javax.swing.filechooser.FileFilter;

+

+/**

+ The class is used to override FileFilter to provides customized interfaces

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class IFileFilter extends FileFilter {

+

+    private String strExt;

+

+    /**

+     Reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     This is the default constructor

+     

+     @param ext

+     

+     **/

+    public IFileFilter(String ext) {

+        this.strExt = ext;

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.filechooser.FileFilter#accept(java.io.File)

+     * 

+     * Override method "accept"

+     * 

+     */

+    public boolean accept(File file) {

+        if (file.isDirectory()) {

+            return true;

+        }

+        String strFileName = file.getName();

+        int intIndex = strFileName.lastIndexOf('.');

+        if (intIndex > 0 && intIndex < strFileName.length() - 1) {

+            String strExtension = strFileName.substring(intIndex + 1).toLowerCase();

+            if (strExtension.equals(strExt))

+                return true;

+        }

+        return false;

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.filechooser.FileFilter#getDescription()

+     * 

+     * Override method "getDescription" to config description via different file type 

+     * 

+     */

+    public String getDescription() {

+        if (strExt.equals("msa"))

+            return "Module Surface Area File(*.msa)";

+        if (strExt.equals("mbd"))

+            return "Module Build Description File(*.mbd)";

+        return "";

+    }

+

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/Log.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/Log.java
new file mode 100644
index 0000000..0759fc6
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/Log.java
@@ -0,0 +1,211 @@
+/** @file

+ 

+ The file is used to provides static interfaces to save log and error information 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.common;

+

+import java.io.File;

+import java.io.FileNotFoundException;

+import java.io.FileOutputStream;

+import java.io.IOException;

+

+import javax.swing.JOptionPane;

+

+/**

+ The class is used to provides static interfaces to save log and error information

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class Log {

+

+    //

+    //Log file

+    //

+    private static File fleLogFile = null;

+

+    //

+    //Err file

+    //

+    private static File fleErrFile = null;

+

+    //

+    //Log file name

+    //

+    static String strLogFileName = "Log.log";

+

+    //

+    //Err file name

+    //

+    static String strErrFileName = "Err.log";

+

+    /**

+     Main class, used for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        try {

+            Log.log("Test", "test");

+            Log.err("Test1", "test1");

+            Log.err("sdfsdfsd fsdfsdfsdfsdfj dsfksdjflsdjf sdkfjsdklfjsdkf dskfsjdkfjks dskfjsdklfjsdkf sdkfjsdlf sdkfjsdk kdfjskdf sdkfjsdkf ksdjfksdfjskdf sdkfsjdfksd fskdfjsdf", "dfsdf sdfksdf sd sdfksd fsdf");

+        } catch (Exception e) {

+            e.printStackTrace();

+        }

+    }

+

+    /**

+     This is the default constructor

+     Do nothing

+     

+     **/

+    public Log() {

+    }

+

+    /**

+     Call writeToLogFile to save log item and log information to log file

+     

+     @param strItem The log item

+     @param strLog The log information

+     

+     **/

+    public static void log(String strItem, String strLog) {

+        try {

+            writeToLogFile(strItem + ":" + strLog);

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+

+    /**

+     Call writeToLogFile to save log information to log file

+     

+     @param strLog The log information

+     

+     **/

+    public static void log(String strLog) {

+        try {

+            writeToLogFile(strLog);

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+

+    /**

+     Call writeToErrFile to save err item and err information to err file

+     

+     @param strItem The err item

+     @param strLog The err information

+     

+     **/

+    public static void err(String strItem, String strErr) {

+        try {

+            writeToErrFile("Error when " + strItem + "::" + strErr);

+            showErrMessage("Error when " + strItem + "::" + strErr);

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+

+    /**

+     Call writeToErrFile to save err information to err file

+     

+     @param strLog The err information

+     

+     **/

+    public static void err(String strErr) {

+        try {

+            writeToErrFile("Error::" + strErr);

+            showErrMessage("Error::" + strErr);

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+

+    /**

+     Brings up a dialog to show err message

+     When the message's length > defined max length, wrap the text to the next line.

+     

+     @param strErr The input data of err message

+     

+     **/

+    private static void showErrMessage(String strErr) {

+        int intMaxLength = 40;

+        String strReturn = "";

+        String strTemp = "";

+        while (strErr.length() > 0) {

+            if (strErr.length() > intMaxLength) {

+                strTemp = strErr.substring(0, intMaxLength);

+                strErr = strErr.substring(strTemp.length());

+                strReturn = strReturn + strTemp + DataType.UNXI_LINE_SEPARATOR;

+                

+            } else if (strErr.length() <= intMaxLength) {

+                strReturn = strReturn + strErr;

+                strErr = "";

+            }

+        }

+        JOptionPane.showConfirmDialog(null, strReturn, "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);

+    }

+

+    /**

+     Open log file and write log information

+     

+     @param strLog The log information

+     @throws IOException

+     

+     **/

+    private static void writeToLogFile(String strLog) throws IOException {

+        try {

+            if (fleLogFile == null) {

+                fleLogFile = new File(strLogFileName);

+                fleLogFile.createNewFile();

+            }

+            FileOutputStream fos = new FileOutputStream(fleLogFile, true);

+            fos.write((Tools.getCurrentDateTime() + DataType.DOS_LINE_SEPARATOR).getBytes());

+            fos.write((strLog + DataType.DOS_LINE_SEPARATOR).getBytes());

+            fos.flush();

+            fos.close();

+        } catch (FileNotFoundException e) {

+            e.printStackTrace();

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+

+    /**

+     Open err file and write err information

+     

+     @param strLog The log information

+     @throws IOException

+     

+     **/

+    private static void writeToErrFile(String strLog) throws IOException {

+        try {

+            if (fleErrFile == null) {

+                fleErrFile = new File(strErrFileName);

+                fleErrFile.createNewFile();

+            }

+            FileOutputStream fos = new FileOutputStream(fleErrFile, true);

+            fos.write((Tools.getCurrentDateTime() + DataType.DOS_LINE_SEPARATOR).getBytes());

+            fos.write((strLog + DataType.DOS_LINE_SEPARATOR).getBytes());

+            fos.flush();

+            fos.close();

+        } catch (FileNotFoundException e) {

+            e.printStackTrace();

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/Tools.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/Tools.java
new file mode 100644
index 0000000..a11df00
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/common/Tools.java
@@ -0,0 +1,120 @@
+/** @file

+ 

+ The file is used to provides some useful interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.common;

+

+import java.io.File;

+import java.text.SimpleDateFormat;

+import java.util.Date;

+import java.util.UUID;

+

+/**

+ The class is used to provides some useful interfaces 

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class Tools {

+

+    /**

+     Used for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        System.out.println(getCurrentDateTime());

+    }

+

+    /**

+     Get current date and time and format it as "yyyy-MM-dd HH:mm"

+     

+     @return formatted current date and time

+     

+     **/

+    public static String getCurrentDateTime() {

+        Date now = new Date(System.currentTimeMillis());

+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+        return sdf.format(now);

+    }

+

+    /**

+     Delete a folder and all its files

+     

+     @param fleFolderName The name of the folder which need be deleted

+     

+     @retval true - Delete successfully

+     @retval false - Delete successfully

+     

+     **/

+    public static boolean deleteFolder(File fleFolderName) {

+        boolean blnIsDeleted = true;

+        File[] aryAllFiles = fleFolderName.listFiles();

+

+        for (int indexI = 0; indexI < aryAllFiles.length; indexI++) {

+            if (blnIsDeleted) {

+                if (aryAllFiles[indexI].isDirectory()) {

+                    //

+                    //If is a directory, recursively call this function to delete sub folders

+                    //

+                    blnIsDeleted = deleteFolder(aryAllFiles[indexI]);

+                } else if (aryAllFiles[indexI].isFile()) {

+                    //

+                    //If is a file, delete it

+                    //

+                    if (!aryAllFiles[indexI].delete()) {

+                        blnIsDeleted = false;

+                    }

+                }

+            }

+        }

+        if (blnIsDeleted) {

+            fleFolderName.delete();

+        }

+        return blnIsDeleted;

+    }

+

+    /**

+     Generate a UUID

+     

+     @return the created UUID

+     

+     **/

+    public static String generateUuidString() {

+        return UUID.randomUUID().toString();

+    }

+

+    /**

+     Get all system properties and output to the console

+     

+     **/

+    public static void getSystemProperties() {

+        System.out.println(System.getProperty("java.class.version"));

+        System.out.println(System.getProperty("java.class.path"));

+        System.out.println(System.getProperty("java.ext.dirs"));

+        System.out.println(System.getProperty("os.name"));

+        System.out.println(System.getProperty("os.arch"));

+        System.out.println(System.getProperty("os.version"));

+        System.out.println(System.getProperty("file.separator"));

+        System.out.println(System.getProperty("path.separator"));

+        System.out.println(System.getProperty("line.separator"));

+        System.out.println(System.getProperty("user.name"));

+        System.out.println(System.getProperty("user.home"));

+        System.out.println(System.getProperty("user.dir"));

+        System.out.println(System.getProperty("PATH"));

+

+        System.out.println(System.getenv("PROCESSOR_REVISION"));

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/ExitConfirm.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/ExitConfirm.java
new file mode 100644
index 0000000..2ff84b6
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/ExitConfirm.java
@@ -0,0 +1,265 @@
+/** @file

+ 

+ The file is used to popup a exit confirmation window when program exists

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.awt.event.WindowEvent;

+import java.awt.event.WindowListener;

+

+import javax.swing.JButton;

+import javax.swing.JDialog;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+

+/**

+ The class is used to popup a exit confirmation window when program exists

+ It extends JDialog and implements ActionListener and WindowListener

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class ExitConfirm extends JDialog implements ActionListener, WindowListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -5875921789385911029L;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelMessage = null;

+

+    private JLabel jLabelResume = null;

+

+    private JLabel jLabelExit = null;

+

+    private JButton jButtonResume = null;

+

+    private JButton jButtonExit = null;

+

+    public boolean isCancel = false;

+

+    /**

+     This method initializes jButtonResume

+     

+     @return javax.swing.JButton jButtonResume

+     

+     **/

+    private JButton getJButtonResume() {

+        if (jButtonResume == null) {

+            jButtonResume = new JButton();

+            jButtonResume.setText("Resume");

+            jButtonResume.setSize(new java.awt.Dimension(90, 20));

+            jButtonResume.setLocation(new java.awt.Point(150, 105));

+            jButtonResume.setMnemonic('R');

+            jButtonResume.addActionListener(this);

+        }

+        return jButtonResume;

+    }

+

+    /**

+     This method initializes jButtonExit

+     

+     @return javax.swing.JButton jButtonExit

+     

+     **/

+    private JButton getJButtonExit() {

+        if (jButtonExit == null) {

+            jButtonExit = new JButton();

+            jButtonExit.setText("Exit");

+            jButtonExit.setSize(new java.awt.Dimension(90, 20));

+            jButtonExit.setLocation(new java.awt.Point(260, 105));

+            jButtonExit.setMnemonic('x');

+            jButtonExit.addActionListener(this);

+        }

+        return jButtonExit;

+    }

+

+    /**

+     Main clasee, reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ExitConfirm(IFrame parentFrame, boolean modal) {

+        super(parentFrame, modal);

+        initialize();

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     

+     **/

+    private void initialize() {

+        this.setSize(500, 170);

+        this.setTitle("Exit");

+        this.setResizable(false);

+        this.setContentPane(getJContentPane());

+        this.addWindowListener(this);

+        //

+        //Set DO_NOTHING_ON_CLOSE when click Close button on title bar

+        //

+        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

+        centerWindow();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelExit = new JLabel();

+            jLabelExit.setSize(new java.awt.Dimension(450, 20));

+            jLabelExit.setLocation(new java.awt.Point(25, 70));

+            jLabelResume = new JLabel();

+            jLabelResume.setSize(new java.awt.Dimension(450, 20));

+            jLabelResume.setLocation(new java.awt.Point(25, 40));

+            jLabelMessage = new JLabel();

+            jLabelMessage.setSize(new java.awt.Dimension(450, 20));

+            jLabelMessage.setLocation(new java.awt.Point(25, 10));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelMessage, null);

+            jContentPane.add(jLabelResume, null);

+            jContentPane.add(jLabelExit, null);

+            jContentPane.add(getJButtonResume(), null);

+            jContentPane.add(getJButtonExit(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     Call setWarningMessage to set messages of frame when it is used for Setup

+     

+     **/

+    public void setSetupMessage() {

+        String strTitle = "Exit Setup";

+        String strMessage = "Setup is not complete. If you quit now, the program will not be installed.";

+        String strResume = "You may run the setup program at a later time to complete the installation.";

+        String strExit = "To continue installing, click Resume. To quit the Setup program, click Exit.";

+        setWarningMessage(strTitle, strMessage, strResume, strExit);

+    }

+

+    /**

+     Call setWarningMessage to set messages of frame when it is used for Module Main GUI

+     

+     **/

+    public void setModuleMessage() {

+        String strTitle = "Exit";

+        String strMessage = "Do you really want to quit now?";

+        String strResume = "All unsaved module information will be lost.";

+        String strExit = "To continue editing module, click Resume. To quit the program, click Exit.";

+        setWarningMessage(strTitle, strMessage, strResume, strExit);

+    }

+

+    /**

+     Set message information via input data

+     

+     @param strTitle The title value

+     @param strMessage The main message value

+     @param strResume The resume message value

+     @param strExit The exit message value

+     

+     **/

+    private void setWarningMessage(String strTitle, String strMessage, String strResume, String strExit) {

+        this.setTitle(strTitle);

+        jLabelMessage.setText(strMessage);

+        jLabelResume.setText(strResume);

+        jLabelExit.setText(strExit);

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     * 

+     * Override actionPerformed to listern all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        //

+        //Set isCancel true when click button "Exit"

+        //

+        Object obj = arg0.getSource();

+        if (obj == jButtonResume) {

+            isCancel = false;

+        }

+        if (obj == jButtonExit) {

+            isCancel = true;

+        }

+        this.setVisible(false);

+    }

+

+    /**

+     Make the window in the center of the screen

+     

+     **/

+    private void centerWindow() {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - this.getSize().width) / 2, (d.height - this.getSize().height) / 2);

+    }

+

+    public void windowActivated(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowClosed(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowClosing(WindowEvent arg0) {

+        isCancel = false;

+        this.setVisible(false);

+    }

+

+    public void windowDeactivated(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowDeiconified(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowIconified(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowOpened(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IComboBox.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IComboBox.java
new file mode 100644
index 0000000..f60ebcf
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IComboBox.java
@@ -0,0 +1,196 @@
+/** @file

+ 

+ The file is used to override JComboBox to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.common.ui;

+

+import java.awt.event.FocusEvent;

+import java.awt.event.FocusListener;

+import java.awt.event.KeyEvent;

+import java.awt.event.KeyListener;

+import java.awt.event.MouseEvent;

+import java.awt.event.MouseListener;

+

+import javax.swing.JComboBox;

+import javax.swing.JFrame;

+import javax.swing.JPanel;

+

+/**

+ The class is used to override JComboBox to provides customized interfaces

+ It extends JComboBox implements KeyListener, MouseListener and FocusListener

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class IComboBox extends JComboBox implements KeyListener, MouseListener, FocusListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -1940262568168458911L;

+

+    public void focusGained(FocusEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)

+     * 

+     * Override focusLost to exit edit mode

+     * 

+     */

+    public void focusLost(FocusEvent arg0) {

+        this.closeEdit();

+    }

+

+    /**

+     Main class, used for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        JFrame jf = new JFrame();

+        jf.setSize(500, 200);

+        JPanel jp = new JPanel();

+        jp.setLayout(null);

+        IComboBox icb = new IComboBox();

+        jp.add(icb, null);

+        jf.setContentPane(jp);

+        jf.setVisible(true);

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public IComboBox() {

+        super();

+        init();

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(320, 20);

+        this.setEditable(false);

+        this.editor.addActionListener(this);

+        this.addMouseListener(this);

+        this.addKeyListener(this);

+        this.getEditor().getEditorComponent().addKeyListener(this);

+        this.getEditor().getEditorComponent().addFocusListener(this);

+    }

+

+    public void keyPressed(KeyEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)

+     * 

+     * Override keyReleased to listen key action

+     * 

+     */

+    public void keyReleased(KeyEvent arg0) {

+        //

+        //Add new item to list when press ENTER

+        //

+        if (arg0.getSource() == this.getEditor().getEditorComponent()) {

+            if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {

+                String strCurrentText = this.getEditor().getItem().toString().trim();

+                if (strCurrentText.length() == 0) {

+                    if (this.getItemCount() > 0) {

+                        this.setSelectedIndex(0);

+                    }

+                } else {

+                    this.addItem(strCurrentText);

+                    this.setSelectedItem(strCurrentText);

+                }

+                this.setEditable(false);

+            }

+            if (arg0.getKeyCode() == KeyEvent.VK_ESCAPE) {

+                closeEdit();

+            }

+        }

+

+        if (arg0.getSource() == this) {

+            //

+            //Remove item from the list when press DEL

+            //

+            if (arg0.getKeyCode() == KeyEvent.VK_DELETE) {

+                int intSelected = this.getSelectedIndex();

+                if (intSelected > -1) {

+                    this.removeItemAt(this.getSelectedIndex());

+                    if (this.getItemCount() > 0) {

+                        this.setSelectedIndex(0);

+                    } else {

+                        this.removeAllItems();

+                    }

+                }

+            }

+        }

+    }

+

+    public void keyTyped(KeyEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)

+     * 

+     * Override mouseClicked to enter edit mode when double click mouse

+     * 

+     */

+    public void mouseClicked(MouseEvent arg0) {

+        if (arg0.getClickCount() == 2) {

+            this.setEditable(true);

+            this.getEditor().setItem("");

+        }

+

+    }

+

+    public void mouseEntered(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mouseExited(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mousePressed(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mouseReleased(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     Exit edit mode

+     

+     **/

+    private void closeEdit() {

+        this.setEditable(false);

+        this.getEditor().setItem("");

+        if (this.getItemCount() > 0) {

+            this.setSelectedIndex(0);

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDefaultMutableTreeNode.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDefaultMutableTreeNode.java
new file mode 100644
index 0000000..ae51c5f
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDefaultMutableTreeNode.java
@@ -0,0 +1,307 @@
+/** @file

+ 

+ 

+ The file is used to override DefaultMutableTreeNode to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import javax.swing.tree.DefaultMutableTreeNode;

+

+/**

+ The class is used to override DefaultMutableTreeNode to provides customized interfaces

+ It extends DefaultMutableTreeNode

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class IDefaultMutableTreeNode extends DefaultMutableTreeNode {

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -1947340717458069548L;

+

+    //

+    //Static final definitions for all kinds of node

+    //

+    public static final int MSA_HEADER = 0;

+

+    public static final int LIBRARYCLASSDEFINITIONS = 1;

+

+    public static final int SOURCEFILES = 2;

+

+    public static final int INCLUDES = 3;

+

+    public static final int PROTOCOLS = 4;

+

+    public static final int EVENTS = 5;

+

+    public static final int HOBS = 6;

+

+    public static final int PPIS = 7;

+

+    public static final int VARIABLES = 8;

+

+    public static final int BOOTMODES = 9;

+

+    public static final int SYSTEMTABLES = 10;

+

+    public static final int DATAHUBS = 11;

+

+    public static final int FORMSETS = 12;

+

+    public static final int GUIDS = 13;

+

+    public static final int EXTERNS = 14;

+

+    public static final int PCDS = 15;

+

+    public static final int MBD_HEADER = 20;

+

+    public static final int MLSA_HEADER = 21;

+

+    public static final int MLBD_HEADER = 22;

+

+    public static final int LIBRARIES = 23;

+

+    public static final int LIBRARY_CLASS_DEFINITION = 101;

+

+    public static final int SOURCEFILES_FILENAME = 210;

+

+    public static final int SOURCEFILES_FILENAME_ITEM = 211;

+

+    public static final int SOURCEFILES_ARCH = 220;

+

+    public static final int SOURCEFILES_ARCH_ITEM = 221;

+

+    public static final int INCLUDES_PACKAGENAME = 310;

+

+    public static final int INCLUDES_PACKAGENAME_ITEM = 311;

+

+    public static final int INCLUDES_ARCH = 320;

+

+    public static final int INCLUDES_ARCH_ITEM = 321;

+

+    public static final int PROTOCOLS_PROTOCOL = 410;

+

+    public static final int PROTOCOLS_PROTOCOL_ITEM = 411;

+

+    public static final int PROTOCOLS_PROTOCOLNOTIFY = 420;

+

+    public static final int PROTOCOLS_PROTOCOLNOTIFY_ITEM = 421;

+

+    public static final int EVENTS_CREATEEVENTS = 510;

+

+    public static final int EVENTS_CREATEEVENTS_ITEM = 511;

+

+    public static final int EVENTS_SIGNALEVENTS = 520;

+

+    public static final int EVENTS_SIGNALEVENTS_ITEM = 521;

+

+    public static final int HOBS_HOB_ITEM = 611;

+

+    public static final int PPIS_PPI = 710;

+

+    public static final int PPIS_PPI_ITEM = 711;

+

+    public static final int PPIS_PPINOTIFY = 720;

+

+    public static final int PPIS_PPINOTIFY_ITEM = 721;

+

+    public static final int VARIABLES_VARIABLE_ITEM = 811;

+

+    public static final int BOOTMODES_BOOTMODE_ITEM = 911;

+

+    public static final int SYSTEMTABLES_SYSTEMTABLE_ITEM = 1011;

+

+    public static final int DATAHUBS_DATAHUB_ITEM = 1111;

+

+    public static final int FORMSETS_FORMSET_ITEM = 1211;

+

+    public static final int GUIDS_GUIDENTRY_ITEM = 1311;

+

+    public static final int EXTERNS_EXTERN_ITEM = 1411;

+

+    public static final int PCDS_PCDDATA_ITEM = 1511;

+

+    public static final int LIBRARIES_LIBRARY = 2310;

+

+    public static final int LIBRARIES_LIBRARY_ITEM = 2311;

+

+    public static final int LIBRARIES_ARCH = 2320;

+

+    public static final int LIBRARIES_ARCH_ITEM = 2321;

+

+    //

+    //Static final definitions for operation

+    //

+    public static final int OPERATION_NULL = 0;

+

+    public static final int OPERATION_ADD = 1;

+

+    public static final int OPERATION_UPDATE = 2;

+

+    public static final int OPERATION_DELETE = 4;

+

+    public static final int OPERATION_ADD_UPDATE = 3;

+

+    public static final int OPERATION_ADD_DELETE = 5;

+

+    public static final int OPERATION_UPDATE_DELETE = 6;

+

+    public static final int OPERATION_ADD_UPDATE_DELETE = 7;

+

+    //

+    //Define 4 node attributes

+    //

+    private int category = 0;

+

+    private int operation = 0;

+

+    private int location = 0;

+

+    private String nodeName = "";

+

+    /**

+     Main class, reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public IDefaultMutableTreeNode() {

+        super();

+    }

+

+    /**

+     This is the overrided constructor

+     Init clase members with input data

+     

+     @param strNodeName The name of node

+     @param intCategory The category of node

+     @param intOperation The operation of node

+     

+     **/

+    public IDefaultMutableTreeNode(String strNodeName, int intCategory, int intOperation) {

+        super(strNodeName);

+        this.nodeName = strNodeName;

+        this.category = intCategory;

+        this.operation = intOperation;

+    }

+

+    /**

+     This is the overrided constructor

+     Init clase members with input data

+     

+     @param strNodeName The name of node

+     @param intCategory The category of node

+     @param intOperation The operation of node

+     @param intLocation The location of node

+     

+     **/

+    public IDefaultMutableTreeNode(String strNodeName, int intCategory, int intOperation, int intLocation) {

+        super(strNodeName);

+        this.nodeName = strNodeName;

+        this.category = intCategory;

+        this.operation = intOperation;

+        this.location = intLocation;

+    }

+

+    /**

+     Get category of node 

+     

+     @return The category of node

+     

+     **/

+    public int getCategory() {

+        return category;

+    }

+

+    /**

+     Set category of node

+     

+     @param category The input data of node category

+     

+     **/

+    public void setCategory(int category) {

+        this.category = category;

+    }

+

+    /**

+     Get name of node

+     

+     @return The name of node

+     

+     **/

+    public String getNodeName() {

+        return nodeName;

+    }

+

+    /**

+     Set name of node

+     

+     @param nodeName The input data of node name

+     

+     **/

+    public void setNodeName(String nodeName) {

+        this.nodeName = nodeName;

+    }

+

+    /**

+     Get operation of node

+     

+     @return The operation of node

+     

+     **/

+    public int getOperation() {

+        return operation;

+    }

+

+    /**

+     Set operation of node

+     

+     @param operation The input data of node operation

+     

+     **/

+    public void setOperation(int operation) {

+        this.operation = operation;

+    }

+

+    /**

+     Get location of node

+     

+     @return The location of node

+     

+     **/

+    public int getLocation() {

+        return location;

+    }

+

+    /**

+     Set location of node

+     

+     @param location The input data of node location

+     

+     **/

+    public void setLocation(int location) {

+        this.location = location;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDesktopManager.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDesktopManager.java
new file mode 100644
index 0000000..b86aa6b
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDesktopManager.java
@@ -0,0 +1,76 @@
+/** @file

+ 

+ The file is used to override DefaultDesktopManager to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import javax.swing.DefaultDesktopManager;

+import javax.swing.JComponent;

+

+/**

+ The class is used to override DefaultDesktopManager to provides customized interfaces

+ It extends DefaultDesktopManager

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class IDesktopManager extends DefaultDesktopManager {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -4596986878722011062L;

+

+    /**

+     Main class, reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.DesktopManager#dragFrame(javax.swing.JComponent, int, int)

+     * 

+     * Override dragFrame to do nothing to forbid internalframe to be draged 

+     * 

+     */

+    public void dragFrame(JComponent f, int newX, int newY) {

+

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.DesktopManager#endDraggingFrame(javax.swing.JComponent)

+     * 

+     * Override endDraggingFrame to do nothing to forbid internalframe to be draged

+     * 

+     */

+    public void endDraggingFrame(JComponent f) {

+

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.DesktopManager#beginResizingFrame(javax.swing.JComponent, int)

+     * 

+     * Override beginResizingFrame to do nothing to forbid internalframe to be draged

+     * 

+     */

+    public void beginResizingFrame(JComponent f, int direction) {

+

+    }

+

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDialog.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDialog.java
new file mode 100644
index 0000000..622b54b
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IDialog.java
@@ -0,0 +1,144 @@
+/** @file

+ 

+ The file is used to override Dialog to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.swing.JDialog;

+

+/**

+ The class is used to override Dialog to provides customized interfaces

+ It extends JDialog implements ActionListener

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class IDialog extends JDialog implements ActionListener {

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -7692623863358631984L;

+    //

+    //Define class members

+    //

+    private boolean isEdited = false;

+

+    public void actionPerformed(ActionEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     Main class, used for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        IDialog id = new IDialog();

+        id.setVisible(true);

+    }

+

+    /**

+     This is the default constructor

+     **/

+    public IDialog() {

+        super();

+        initialize();

+    }

+

+    /**

+     * This is the override constructor

+     */

+    /**

+     This is the override constructor

+     

+     @param parentFrame The parent frame which open the dialog

+     @param modal true means the dialog is modal dialog; false means the dialog is not modal dialog

+     **/

+    public IDialog(IFrame parentFrame, boolean modal) {

+        super(parentFrame, modal);

+        initialize();

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setResizable(false);

+    }

+

+    /**

+     Start the dialog at the center of screen

+     

+     @param intWidth The width of the dialog

+     @param intHeight The height of the dialog

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the dialog at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     Get if the dialog has been edited

+     

+     @retval true - The dialog has been edited

+     @retval false - The dialog hasn't been edited

+     

+     **/

+    public boolean isEdited() {

+        return isEdited;

+    }

+

+    /**

+     Set if the dialog has been edited

+     

+     @param isEdited The input data which identify if the dialog has been edited

+     

+     **/

+    public void setEdited(boolean isEdited) {

+        this.isEdited = isEdited;

+    }

+

+    /**

+     Check the input data is empty or not

+     

+     @param strValue The input data which need be checked

+     

+     @retval true - The input data is empty

+     @retval fals - The input data is not empty

+     

+     **/

+    public boolean isEmpty(String strValue) {

+        if (strValue.length() > 0) {

+            return false;

+        }

+        return true;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IFrame.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IFrame.java
new file mode 100644
index 0000000..4e36bd4
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IFrame.java
@@ -0,0 +1,204 @@
+/** @file

+ 

+ The file is used to override Frame to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.awt.event.WindowEvent;

+import java.awt.event.WindowListener;

+

+import javax.swing.JFrame;

+

+/**

+ The class is used to override Frame to provides customized interfaces 

+ It extends JFrame implements ActionListener and WindowListener

+ 

+ @since ModuleEditor 1.0

+ 

+ **/

+public class IFrame extends JFrame implements ActionListener, WindowListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -3324138961029300427L;

+

+    //

+    //Define class members

+    //

+    private ExitConfirm ec = null;

+

+    //

+    // To indicate the status while quit

+    // 0 - When setup (Default)

+    // 1 - Whne editing module

+    //

+    private int intExitType = 0;

+

+    /**

+     Main class, used for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        IFrame i = new IFrame();

+        i.setVisible(true);

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public IFrame() {

+        super();

+        initialize();

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    public void initialize() {

+        this.setResizable(false);

+        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

+        this.addWindowListener(this);

+    }

+

+    /**

+     Start the dialog at the center of screen

+     

+     @param intWidth The width of the dialog

+     @param intHeight The height of the dialog

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the dialog at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     Set the exit window type

+     

+     @param ExitType The input data of ExitType

+     

+     **/

+    protected void setExitType(int ExitType) {

+        this.intExitType = ExitType;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.WindowListener#windowClosing(java.awt.event.WindowEvent)

+     *

+     * Override windowClosing to call this.onDisvisible()

+     * 

+     */

+    public void windowClosing(WindowEvent arg0) {

+        this.onDisvisible();

+    }

+

+    public void windowOpened(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowClosed(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowIconified(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowDeiconified(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowActivated(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void windowDeactivated(WindowEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     Define the actions when exit

+     

+     **/

+    public void onExit() {

+        ec = new ExitConfirm(this, true);

+        //

+        //Show different warning message via different ExitType

+        //

+        switch (intExitType) {

+        case 0:

+            ec.setSetupMessage();

+            break;

+        case 1:

+            ec.setModuleMessage();

+            break;

+        }

+        ec.setVisible(true);

+        if (ec.isCancel) {

+            this.dispose();

+            System.exit(0);

+        }

+    }

+

+    /**

+     Define the actions when disvisible

+     

+     **/

+    public void onDisvisible() {

+        ec = new ExitConfirm(this, true);

+        //

+        //Show different warning message via different ExitType

+        //

+        switch (intExitType) {

+        case 0:

+            ec.setSetupMessage();

+            break;

+        case 1:

+            ec.setModuleMessage();

+            break;

+        }

+        ec.setVisible(true);

+        if (ec.isCancel) {

+            this.dispose();

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IInternalFrame.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IInternalFrame.java
new file mode 100644
index 0000000..8fc9d9b
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/IInternalFrame.java
@@ -0,0 +1,109 @@
+/** @file

+ 

+ The file is used to override JInternalFrame to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.swing.JInternalFrame;

+

+/**

+ The class is used to override JInternalFrame to provides customized interfaces

+ It extends JInternalFrame implements ActionListener

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class IInternalFrame extends JInternalFrame implements ActionListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -609841772384875886L;

+    //

+    //Define class members

+    //

+    private boolean isEdited = false;

+

+    /**

+     Main class, reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public IInternalFrame() {

+        super();

+        initialize();

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 500));

+    }

+

+    /**

+     Get if the InternalFrame has been edited

+     

+     @retval true - The InternalFrame has been edited

+     @retval false - The InternalFrame hasn't been edited

+     

+     **/

+    public boolean isEdited() {

+        return isEdited;

+    }

+

+    /**

+     Set if the InternalFrame has been edited

+     

+     @param isEdited The input data which identify if the InternalFrame has been edited

+     

+     **/

+    public void setEdited(boolean isEdited) {

+        this.isEdited = isEdited;

+    }

+

+    /**

+     Check the input data is empty or not

+     

+     @param strValue The input data which need be checked

+     

+     @retval true - The input data is empty

+     @retval fals - The input data is not empty

+     

+     **/

+    public boolean isEmpty(String strValue) {

+        if (strValue.length() > 0) {

+            return false;

+        }

+        return true;

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/ITree.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/ITree.java
new file mode 100644
index 0000000..eeb51fc
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/ITree.java
@@ -0,0 +1,204 @@
+/** @file

+ 

+ The file is used to override JTree to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import javax.swing.JTree;

+import javax.swing.tree.DefaultMutableTreeNode;

+import javax.swing.tree.DefaultTreeModel;

+import javax.swing.tree.TreeNode;

+import javax.swing.tree.TreePath;

+

+/**

+ The class is used to override JTree to provides customized interfaces 

+ It extends JTree

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ITree extends JTree {

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -7907086164518295327L;

+    

+    //

+    // Define class members

+    //

+    DefaultTreeModel treeModel = null;

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ITree() {

+        super();

+    }

+

+    /**

+     This is the overrided constructor

+     Init class members with input data

+     

+     @param iDmtRoot The root node of the tree

+     

+     **/

+    public ITree(IDefaultMutableTreeNode iDmtRoot) {

+        super(iDmtRoot);

+    }

+

+    /**

+     Get category of selected node

+     

+     @return The category of selected node

+     

+     **/

+    public int getSelectCategory() {

+        int intCategory = 0;

+        TreePath path = this.getSelectionPath();

+        IDefaultMutableTreeNode node = (IDefaultMutableTreeNode) path.getLastPathComponent();

+        intCategory = node.getCategory();

+        return intCategory;

+    }

+

+    /**

+     Get operation of selected node

+     

+     @return The operation of selected node

+     

+     **/

+    public int getSelectOperation() {

+        int intOperation = 0;

+        TreePath path = this.getSelectionPath();

+        IDefaultMutableTreeNode node = (IDefaultMutableTreeNode) path.getLastPathComponent();

+        intOperation = node.getOperation();

+        return intOperation;

+    }

+

+    /**

+     Get selectLoaction of selected node

+     

+     @return The selectLoaction of selected node

+     

+     **/

+    public int getSelectLoaction() {

+        int intLocation = 0;

+        TreePath path = this.getSelectionPath();

+        IDefaultMutableTreeNode node = (IDefaultMutableTreeNode) path.getLastPathComponent();

+        intLocation = node.getLocation();

+        return intLocation;

+    }

+

+    /**

+     Main class, reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+    }

+

+    /**

+     Add input node as child node for current selected node

+     

+     @param strNewNode The name of the node which need be added

+     

+     **/

+    public void addNode(String strNewNode) {

+        DefaultMutableTreeNode parentNode = null;

+        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(strNewNode);

+        newNode.setAllowsChildren(true);

+        TreePath parentPath = this.getSelectionPath();

+

+        /**

+         * Get parent node of new node

+         */

+        parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent());

+

+        /**

+         * Insert new node

+         */

+        treeModel.insertNodeInto(newNode, parentNode, parentNode.getChildCount());

+        this.scrollPathToVisible(new TreePath(newNode.getPath()));

+    }

+

+    /**

+     Add input node as child node for current selected node

+     

+     @param newNode The node need be added

+     

+     **/

+    public void addNode(IDefaultMutableTreeNode newNode) {

+        IDefaultMutableTreeNode parentNode = null;

+        newNode.setAllowsChildren(true);

+        TreePath parentPath = this.getSelectionPath();

+        parentNode = (IDefaultMutableTreeNode) (parentPath.getLastPathComponent());

+        treeModel.insertNodeInto(newNode, parentNode, parentNode.getChildCount());

+        this.scrollPathToVisible(new TreePath(newNode.getPath()));

+    }

+

+    /**

+     Remove current selectd node

+     

+     **/

+    public void removeNode() {

+        TreePath treepath = this.getSelectionPath();

+        if (treepath != null) {

+            DefaultMutableTreeNode selectionNode = (DefaultMutableTreeNode) treepath.getLastPathComponent();

+            TreeNode parent = (TreeNode) selectionNode.getParent();

+            if (parent != null) {

+                treeModel.removeNodeFromParent(selectionNode);

+            }

+        }

+    }

+

+    /**

+     Remove all node on a same level

+     

+     **/

+    public void removeNodeOnSameLevel() {

+        TreePath treepath = this.getSelectionPath();

+        IDefaultMutableTreeNode parentNode = (IDefaultMutableTreeNode) treepath.getLastPathComponent();

+        parentNode.removeAllChildren();

+        treeModel.reload();

+    }

+

+    /**

+     Remove the input node by name

+     

+     @param strRemovedNode

+     

+     **/

+    public void removeNode(String strRemovedNode) {

+        TreePath treepath = this.getSelectionPath();

+        if (treepath != null) {

+            DefaultMutableTreeNode selectionNode = (DefaultMutableTreeNode) treepath.getLastPathComponent();

+            TreeNode parent = (TreeNode) selectionNode.getParent();

+            if (parent != null) {

+                treeModel.removeNodeFromParent(selectionNode);

+            }

+        }

+    }

+

+    /**

+     Remove all nodes of the tree

+     

+     **/

+    public void removeAllNode() {

+        DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) treeModel.getRoot();

+        rootNode.removeAllChildren();

+        treeModel.reload();

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/StarLabel.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/StarLabel.java
new file mode 100644
index 0000000..c451ac5
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/common/ui/StarLabel.java
@@ -0,0 +1,64 @@
+/** @file

+ 

+ The file is used to override JLabel to provides customized interfaces 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.common.ui;

+

+import javax.swing.JLabel;

+

+/**

+ The class is used to override JLabel to provides customized interfaces 

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class StarLabel extends JLabel {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -6702981027831543919L;

+

+    /**

+     Main class, reserved for test

+     

+     @param args

+     

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public StarLabel() {

+        super();

+        init();

+    }

+

+    /**

+     To create a RED, BOLD and 14 size "*"

+     

+     **/

+    private void init() {

+        this.setText("*");

+        this.setSize(new java.awt.Dimension(10, 20));

+        this.setForeground(java.awt.Color.red);

+        this.setFont(new java.awt.Font("DialogInput", java.awt.Font.BOLD, 14));

+        this.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdHeader.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdHeader.java
new file mode 100644
index 0000000..c9e65d1
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdHeader.java
@@ -0,0 +1,583 @@
+/** @file

+ 

+ This file is used to create, update MbdHeader of a MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JScrollPane;

+import javax.swing.JTextArea;

+import javax.swing.JTextField;

+

+import org.tianocore.BaseNameDocument;

+import org.tianocore.GuidDocument;

+import org.tianocore.LicenseDocument;

+import org.tianocore.MbdHeaderDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ This class is used to create, update MbdHeader of a MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class MbdHeader extends IInternalFrame {

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -2015726615436197378L;

+

+    //

+    // Define class members

+    //

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelBaseName = null;

+

+    private JTextField jTextFieldBaseName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelLicense = null;

+

+    private JTextArea jTextAreaLicense = null;

+

+    private JLabel jLabelCopyright = null;

+

+    private JLabel jLabelDescription = null;

+

+    private JTextArea jTextAreaDescription = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JScrollPane jScrollPaneLicense = null;

+

+    private JScrollPane jScrollPaneDescription = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+

+    private StarLabel jStarLabel5 = null;

+

+    private StarLabel jStarLabel6 = null;

+

+    private MbdHeaderDocument.MbdHeader mbdHeader = null;

+

+    private JTextField jTextFieldCopyright = null;

+

+    /**

+     This method initializes jTextFieldBaseName

+     

+     @return javax.swing.JTextField jTextFieldBaseName

+     

+     **/

+    private JTextField getJTextFieldBaseName() {

+        if (jTextFieldBaseName == null) {

+            jTextFieldBaseName = new JTextField();

+            jTextFieldBaseName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldBaseName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldVersion 

+     

+     @return javax.swing.JTextField jTextFieldVersion

+     

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextAreaLicense 

+     

+     @return javax.swing.JTextArea jTextAreaLicense

+     

+     **/

+    private JTextArea getJTextAreaLicense() {

+        if (jTextAreaLicense == null) {

+            jTextAreaLicense = new JTextArea();

+            jTextAreaLicense.setText("");

+            jTextAreaLicense.setLineWrap(true);

+        }

+        return jTextAreaLicense;

+    }

+

+    /**

+     This method initializes jTextAreaDescription 

+     

+     @return javax.swing.JTextArea jTextAreaDescription

+     

+     **/

+    private JTextArea getJTextAreaDescription() {

+        if (jTextAreaDescription == null) {

+            jTextAreaDescription = new JTextArea();

+            jTextAreaDescription.setLineWrap(true);

+        }

+        return jTextAreaDescription;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 345, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 345, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPaneLicense 

+     

+     @return javax.swing.JScrollPane jScrollPaneLicense

+     

+     **/

+    private JScrollPane getJScrollPaneLicense() {

+        if (jScrollPaneLicense == null) {

+            jScrollPaneLicense = new JScrollPane();

+            jScrollPaneLicense.setBounds(new java.awt.Rectangle(160, 85, 320, 80));

+            jScrollPaneLicense.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneLicense.setViewportView(getJTextAreaLicense());

+        }

+        return jScrollPaneLicense;

+    }

+

+    /**

+     This method initializes jScrollPaneDescription 

+     

+     @return javax.swing.JScrollPane jScrollPaneDescription

+     

+     **/

+    private JScrollPane getJScrollPaneDescription() {

+        if (jScrollPaneDescription == null) {

+            jScrollPaneDescription = new JScrollPane();

+            jScrollPaneDescription.setBounds(new java.awt.Rectangle(160, 195, 320, 80));

+            jScrollPaneDescription.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneDescription.setViewportView(getJTextAreaDescription());

+        }

+        return jScrollPaneDescription;

+    }

+

+    /**

+     * This method initializes jTextFieldCopyright	

+     * 	

+     * @return javax.swing.JTextField	

+     */

+    private JTextField getJTextFieldCopyright() {

+        if (jTextFieldCopyright == null) {

+            jTextFieldCopyright = new JTextField();

+            jTextFieldCopyright.setBounds(new java.awt.Rectangle(160,170,320,20));

+        }

+        return jTextFieldCopyright;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public MbdHeader() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     **/

+    public MbdHeader(MbdHeaderDocument.MbdHeader inMbdHeader) {

+        super();

+        init(inMbdHeader);

+        this.setVisible(true);

+        this.setViewMode(false);

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Module Build Description Header");

+        initFrame();

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inMbdHeader The input MbdHeaderDocument.MbdHeader

+     

+     **/

+    private void init(MbdHeaderDocument.MbdHeader inMbdHeader) {

+        init();

+        setMbdHeader(inMbdHeader);

+        if (inMbdHeader != null) {

+            if (this.mbdHeader.getBaseName() != null) {

+                this.jTextFieldBaseName.setText(this.mbdHeader.getBaseName().getStringValue());

+            }

+            if (this.mbdHeader.getGuid() != null) {

+                this.jTextFieldGuid.setText(this.mbdHeader.getGuid().getStringValue());

+            }

+            if (this.mbdHeader.getVersion() != null) {

+                this.jTextFieldVersion.setText(this.mbdHeader.getVersion());

+            }

+            if (this.mbdHeader.getLicense() != null) {

+                this.jTextAreaLicense.setText(this.mbdHeader.getLicense().getStringValue());

+            }

+            if (this.mbdHeader.getCopyright() != null) {

+                this.jTextFieldCopyright.setText(this.mbdHeader.getCopyright());

+            }

+            if (this.mbdHeader.getDescription() != null) {

+                this.jTextAreaDescription.setText(this.mbdHeader.getDescription());

+            }

+        }

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldBaseName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jTextFieldVersion.setEnabled(!isView);

+            this.jTextAreaLicense.setEnabled(!isView);

+            this.jTextFieldCopyright.setEnabled(!isView);

+            this.jTextAreaDescription.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelDescription = new JLabel();

+            jLabelDescription.setText("Description");

+            jLabelDescription.setBounds(new java.awt.Rectangle(15, 195, 140, 20));

+            jLabelCopyright = new JLabel();

+            jLabelCopyright.setText("Copyright");

+            jLabelCopyright.setBounds(new java.awt.Rectangle(15, 170, 140, 20));

+            jLabelLicense = new JLabel();

+            jLabelLicense.setText("License");

+            jLabelLicense.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelVersion = new JLabel();

+            jLabelVersion.setText("Version");

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setPreferredSize(new java.awt.Dimension(25, 15));

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelBaseName = new JLabel();

+            jLabelBaseName.setText("Base Name");

+            jLabelBaseName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setLocation(new java.awt.Point(0, 0));

+            jContentPane.setSize(new java.awt.Dimension(500, 524));

+            jContentPane.add(jLabelBaseName, null);

+            jContentPane.add(getJTextFieldBaseName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelLicense, null);

+            jContentPane.add(jLabelCopyright, null);

+            jContentPane.add(jLabelDescription, null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPaneLicense(), null);

+            jContentPane.add(getJScrollPaneDescription(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 85));

+            jStarLabel5 = new StarLabel();

+            jStarLabel5.setLocation(new java.awt.Point(0, 170));

+            jStarLabel6 = new StarLabel();

+            jStarLabel6.setLocation(new java.awt.Point(0, 195));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+            jContentPane.add(jStarLabel5, null);

+            jContentPane.add(jStarLabel6, null);

+            jContentPane.add(getJTextFieldCopyright(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.dispose();

+            this.save();

+            this.setEdited(true);

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+            this.setEdited(false);

+        }

+        //

+        // Generate GUID

+        //

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldBaseName.getText())) {

+            Log.err("Base Name couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldGuid.getText())) {

+            Log.err("Guid couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldVersion.getText())) {

+            Log.err("Version couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaLicense.getText())) {

+            Log.err("License couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldCopyright.getText())) {

+            Log.err("Copyright couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaDescription.getText())) {

+            Log.err("Description couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isBaseName(this.jTextFieldBaseName.getText())) {

+            Log.err("Incorrect data type for Base Name");

+            return false;

+        }

+        if (!DataValidation.isGuid((this.jTextFieldGuid).getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!DataValidation.isCopyright(this.jTextFieldCopyright.getText())) {

+            Log.err("Incorrect data type for Copyright");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Save all components of Mbd Header

+     if exists mbdHeader, set the value directly

+     if not exists mbdHeader, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.mbdHeader == null) {

+                mbdHeader = MbdHeaderDocument.MbdHeader.Factory.newInstance();

+            }

+            if (this.mbdHeader.getBaseName() != null) {

+                this.mbdHeader.getBaseName().setStringValue(this.jTextFieldBaseName.getText());

+            } else {

+                BaseNameDocument.BaseName mBaseName = BaseNameDocument.BaseName.Factory.newInstance();

+                mBaseName.setStringValue(this.jTextFieldBaseName.getText());

+                this.mbdHeader.setBaseName(mBaseName);

+            }

+

+            if (this.mbdHeader.getGuid() != null) {

+                this.mbdHeader.getGuid().setStringValue(this.jTextFieldGuid.getText());

+            } else {

+                GuidDocument.Guid mGuid = GuidDocument.Guid.Factory.newInstance();

+                mGuid.setStringValue(this.jTextFieldGuid.getText());

+                this.mbdHeader.setGuid(mGuid);

+            }

+

+            this.mbdHeader.setVersion(this.jTextFieldVersion.getText());

+

+            if (this.mbdHeader.getLicense() != null) {

+                this.mbdHeader.getLicense().setStringValue(this.jTextAreaLicense.getText());

+            } else {

+                LicenseDocument.License mLicense = LicenseDocument.License.Factory.newInstance();

+                mLicense.setStringValue(this.jTextAreaLicense.getText());

+                this.mbdHeader.setLicense(mLicense);

+            }

+

+            this.mbdHeader.setCopyright(this.jTextFieldCopyright.getText());

+            this.mbdHeader.setDescription(this.jTextAreaDescription.getText());

+

+            if (this.mbdHeader.getCreated() == null) {

+                this.mbdHeader.setCreated(Tools.getCurrentDateTime());

+            } else {

+                this.mbdHeader.setModified(Tools.getCurrentDateTime());

+            }

+

+        } catch (Exception e) {

+            Log.err("Save Module Buid Description", e.getMessage());

+        }

+    }

+

+    /**

+     This method initializes module type and compontent type

+     

+     **/

+    private void initFrame() {

+

+    }

+

+    /**

+     Get MbdHeaderDocument.MbdHeader

+     

+     @return MbdHeaderDocument.MbdHeader mbdHeader

+     

+     **/

+    public MbdHeaderDocument.MbdHeader getMbdHeader() {

+        return mbdHeader;

+    }

+

+    /**

+     Set MbdHeaderDocument.MbdHeader

+     

+     @param mbdHeader The input MbdHeaderDocument.MbdHeader

+     

+     **/

+    public void setMbdHeader(MbdHeaderDocument.MbdHeader mbdHeader) {

+        this.mbdHeader = mbdHeader;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdLibHeader.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdLibHeader.java
new file mode 100644
index 0000000..8adde84
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdLibHeader.java
@@ -0,0 +1,581 @@
+/** @file

+ 

+ The file is used to create, update MbdLibHeader of a MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JScrollPane;

+import javax.swing.JTextArea;

+import javax.swing.JTextField;

+

+import org.tianocore.BaseNameDocument;

+import org.tianocore.GuidDocument;

+import org.tianocore.LicenseDocument;

+import org.tianocore.MbdLibHeaderDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update MbdLibHeader of a MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class MbdLibHeader extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -4881447351274201866L;

+

+    //

+    //Define class members

+    //

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelBaseName = null;

+

+    private JTextField jTextFieldBaseName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelLicense = null;

+

+    private JTextArea jTextAreaLicense = null;

+

+    private JLabel jLabelCopyright = null;

+

+    private JLabel jLabelDescription = null;

+

+    private JTextArea jTextAreaDescription = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JScrollPane jScrollPaneLicense = null;

+

+    private JScrollPane jScrollPaneDescription = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+

+    private StarLabel jStarLabel5 = null;

+

+    private StarLabel jStarLabel6 = null;

+

+    private MbdLibHeaderDocument.MbdLibHeader mbdLibHeader = null;

+

+    private JTextField jTextFieldCopyright = null;

+

+    /**

+     This method initializes jTextFieldBaseName 

+     

+     @return javax.swing.JTextField jTextFieldBaseName

+     

+     **/

+    private JTextField getJTextFieldBaseName() {

+        if (jTextFieldBaseName == null) {

+            jTextFieldBaseName = new JTextField();

+            jTextFieldBaseName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldBaseName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldVersion 

+     

+     @return javax.swing.JTextField jTextFieldVersion

+     

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextAreaLicense 

+     

+     @return javax.swing.JTextArea jTextAreaLicense

+     

+     **/

+    private JTextArea getJTextAreaLicense() {

+        if (jTextAreaLicense == null) {

+            jTextAreaLicense = new JTextArea();

+            jTextAreaLicense.setText("");

+            jTextAreaLicense.setLineWrap(true);

+        }

+        return jTextAreaLicense;

+    }

+

+    /**

+     This method initializes jTextAreaDescription 

+     

+     @return javax.swing.JTextArea jTextAreaDescription

+     

+     **/

+    private JTextArea getJTextAreaDescription() {

+        if (jTextAreaDescription == null) {

+            jTextAreaDescription = new JTextArea();

+            jTextAreaDescription.setLineWrap(true);

+        }

+        return jTextAreaDescription;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 345, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 345, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPaneLicense 

+     

+     @return javax.swing.JScrollPane jScrollPaneLicense 

+     

+     **/

+    private JScrollPane getJScrollPaneLicense() {

+        if (jScrollPaneLicense == null) {

+            jScrollPaneLicense = new JScrollPane();

+            jScrollPaneLicense.setBounds(new java.awt.Rectangle(160, 85, 320, 80));

+            jScrollPaneLicense.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneLicense.setViewportView(getJTextAreaLicense());

+        }

+        return jScrollPaneLicense;

+    }

+

+    /**

+     This method initializes jScrollPaneDescription 

+     

+     @return javax.swing.JScrollPane jScrollPaneDescription

+     

+     **/

+    private JScrollPane getJScrollPaneDescription() {

+        if (jScrollPaneDescription == null) {

+            jScrollPaneDescription = new JScrollPane();

+            jScrollPaneDescription.setBounds(new java.awt.Rectangle(160, 195, 320, 80));

+            jScrollPaneDescription.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneDescription.setViewportView(getJTextAreaDescription());

+        }

+        return jScrollPaneDescription;

+    }

+

+    /**

+      This method initializes jTextFieldCopyright	

+      	

+      @return javax.swing.JTextField jTextFieldCopyright

+     

+     **/

+    private JTextField getJTextFieldCopyright() {

+        if (jTextFieldCopyright == null) {

+            jTextFieldCopyright = new JTextField();

+            jTextFieldCopyright.setBounds(new java.awt.Rectangle(160,170,320,20));

+        }

+        return jTextFieldCopyright;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public MbdLibHeader() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inMbdLibHeader The input MbdLibHeaderDocument.MbdLibHeader

+     

+     **/

+    public MbdLibHeader(MbdLibHeaderDocument.MbdLibHeader inMbdLibHeader) {

+        super();

+        init(inMbdLibHeader);

+        this.setVisible(true);

+        this.setViewMode(false);

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Library Module Build Description Header");

+        initFrame();

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inMbdLibHeader The input MbdLibHeaderDocument.MbdLibHeader

+     

+     **/

+    private void init(MbdLibHeaderDocument.MbdLibHeader inMbdLibHeader) {

+        init();

+        setMbdLibHeader(inMbdLibHeader);

+        if (inMbdLibHeader != null) {

+            if (this.mbdLibHeader.getBaseName() != null) {

+                this.jTextFieldBaseName.setText(this.mbdLibHeader.getBaseName().getStringValue());

+            }

+            if (this.mbdLibHeader.getGuid() != null) {

+                this.jTextFieldGuid.setText(this.mbdLibHeader.getGuid().getStringValue());

+            }

+            if (this.mbdLibHeader.getVersion() != null) {

+                this.jTextFieldVersion.setText(this.mbdLibHeader.getVersion());

+            }

+            if (this.mbdLibHeader.getLicense() != null) {

+                this.jTextAreaLicense.setText(this.mbdLibHeader.getLicense().getStringValue());

+            }

+            if (this.mbdLibHeader.getCopyright() != null) {

+                this.jTextFieldCopyright.setText(this.mbdLibHeader.getCopyright());

+            }

+            if (this.mbdLibHeader.getDescription() != null) {

+                this.jTextAreaDescription.setText(this.mbdLibHeader.getDescription());

+            }

+        }

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldBaseName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jTextFieldVersion.setEnabled(!isView);

+            this.jTextAreaLicense.setEnabled(!isView);

+            this.jTextFieldCopyright.setEnabled(!isView);

+            this.jTextAreaDescription.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelDescription = new JLabel();

+            jLabelDescription.setText("Description");

+            jLabelDescription.setBounds(new java.awt.Rectangle(15, 195, 140, 20));

+            jLabelCopyright = new JLabel();

+            jLabelCopyright.setText("Copyright");

+            jLabelCopyright.setBounds(new java.awt.Rectangle(15, 170, 140, 20));

+            jLabelLicense = new JLabel();

+            jLabelLicense.setText("License");

+            jLabelLicense.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelVersion = new JLabel();

+            jLabelVersion.setText("Version");

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setPreferredSize(new java.awt.Dimension(25, 15));

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelBaseName = new JLabel();

+            jLabelBaseName.setText("Base Name");

+            jLabelBaseName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setLocation(new java.awt.Point(0, 0));

+            jContentPane.setSize(new java.awt.Dimension(500, 524));

+            jContentPane.add(jLabelBaseName, null);

+            jContentPane.add(getJTextFieldBaseName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelLicense, null);

+            jContentPane.add(jLabelCopyright, null);

+            jContentPane.add(jLabelDescription, null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPaneLicense(), null);

+            jContentPane.add(getJScrollPaneDescription(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 85));

+            jStarLabel5 = new StarLabel();

+            jStarLabel5.setLocation(new java.awt.Point(0, 170));

+            jStarLabel6 = new StarLabel();

+            jStarLabel6.setLocation(new java.awt.Point(0, 195));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+            jContentPane.add(jStarLabel5, null);

+            jContentPane.add(jStarLabel6, null);

+            jContentPane.add(getJTextFieldCopyright(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.dispose();

+            this.save();

+            this.setEdited(true);

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+            this.setEdited(false);

+        }

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldBaseName.getText())) {

+            Log.err("Base Name couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldGuid.getText())) {

+            Log.err("Guid couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldVersion.getText())) {

+            Log.err("Version couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaLicense.getText())) {

+            Log.err("License couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldCopyright.getText())) {

+            Log.err("Copyright couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaDescription.getText())) {

+            Log.err("Description couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isBaseName(this.jTextFieldBaseName.getText())) {

+            Log.err("Incorrect data type for Base Name");

+            return false;

+        }

+        if (!DataValidation.isGuid((this.jTextFieldGuid).getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!DataValidation.isCopyright(this.jTextFieldCopyright.getText())) {

+            Log.err("Incorrect data type for Copyright");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Save all components of Mbd Lib Header

+     if exists mbdLibHeader, set the value directly

+     if not exists mbdLibHeader, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.mbdLibHeader == null) {

+                mbdLibHeader = MbdLibHeaderDocument.MbdLibHeader.Factory.newInstance();

+            }

+            if (this.mbdLibHeader.getBaseName() != null) {

+                this.mbdLibHeader.getBaseName().setStringValue(this.jTextFieldBaseName.getText());

+            } else {

+                BaseNameDocument.BaseName mBaseName = BaseNameDocument.BaseName.Factory.newInstance();

+                mBaseName.setStringValue(this.jTextFieldBaseName.getText());

+                this.mbdLibHeader.setBaseName(mBaseName);

+            }

+

+            if (this.mbdLibHeader.getGuid() != null) {

+                this.mbdLibHeader.getGuid().setStringValue(this.jTextFieldGuid.getText());

+            } else {

+                GuidDocument.Guid mGuid = GuidDocument.Guid.Factory.newInstance();

+                mGuid.setStringValue(this.jTextFieldGuid.getText());

+                this.mbdLibHeader.setGuid(mGuid);

+            }

+

+            this.mbdLibHeader.setVersion(this.jTextFieldVersion.getText());

+

+            if (this.mbdLibHeader.getLicense() != null) {

+                this.mbdLibHeader.getLicense().setStringValue(this.jTextAreaLicense.getText());

+            } else {

+                LicenseDocument.License mLicense = LicenseDocument.License.Factory.newInstance();

+                mLicense.setStringValue(this.jTextAreaLicense.getText());

+                this.mbdLibHeader.setLicense(mLicense);

+            }

+

+            this.mbdLibHeader.setCopyright(this.jTextFieldCopyright.getText());

+            this.mbdLibHeader.setDescription(this.jTextAreaDescription.getText());

+

+            if (this.mbdLibHeader.getCreated() == null) {

+                this.mbdLibHeader.setCreated(Tools.getCurrentDateTime());

+            } else {

+                this.mbdLibHeader.setModified(Tools.getCurrentDateTime());

+            }

+        } catch (Exception e) {

+            Log.err("Save Module Buid Description", e.getMessage());

+        }

+    }

+

+    /**

+     This method initializes module type and compontent type

+     

+     **/

+    private void initFrame() {

+    }

+

+    /**

+     Get MbdLibHeaderDocument.MbdLibHeader

+     

+     @return MbdLibHeaderDocument.MbdLibHeader

+     

+     **/

+    public MbdLibHeaderDocument.MbdLibHeader getMbdLibHeader() {

+        return mbdLibHeader;

+    }

+

+    /**

+     Set MbdLibHeaderDocument.MbdLibHeader

+     

+     @param mbdLibHeader The input MbdLibHeaderDocument.MbdLibHeader

+     

+     **/

+    public void setMbdLibHeader(MbdLibHeaderDocument.MbdLibHeader mbdLibHeader) {

+        this.mbdLibHeader = mbdLibHeader;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdLibraries.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdLibraries.java
new file mode 100644
index 0000000..ffbb3eb
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MbdLibraries.java
@@ -0,0 +1,1048 @@
+/** @file

+ 

+ The file is used to create, update MbdLibraries of a MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.ItemEvent;

+import java.awt.event.ItemListener;

+import java.util.Vector;

+

+import javax.swing.JButton;

+import javax.swing.JCheckBox;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.LibrariesDocument;

+import org.tianocore.LibraryUsage;

+import org.tianocore.SupportedArchitectures;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update MbdLibraries of a MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class MbdLibraries extends IInternalFrame implements ItemListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 8042998899875417568L;

+

+    //

+    //Define class members

+    //

+    private LibrariesDocument.Libraries libraries = null;

+

+    private int location = -1;

+    

+    private int intSelectedItemId = 0;

+

+    //

+    //1 - Add; 2 - Update

+    //

+    private int operation = -1;

+

+    private Vector<String> vName = new Vector<String>();

+

+    private Vector<String> vGuid = new Vector<String>();

+

+    private Vector<String> vLibraryClass = new Vector<String>();

+

+    private Vector<String> vClassGuid = new Vector<String>();

+

+    private Vector<String> vVersion = new Vector<String>();

+

+    private Vector<String> vUsage = new Vector<String>();

+

+    private Vector<String> vOverrideID = new Vector<String>();

+

+    private JPanel jContentPane = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelName = null;

+

+    private JTextField jTextFieldFileName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JComboBox jComboBoxArch = null;

+

+    private JLabel jLabelLibraryClass = null;

+

+    private JTextField jTextFieldLibraryClass = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JLabel jLabelClassGuid = null;

+

+    private JTextField jTextFieldClassGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private JComboBox jComboBoxFileList = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonRemove = null;

+

+    private JButton jButtonUpdate = null;

+

+    private JCheckBox jCheckBoxArch = null;

+

+    private JButton jButtonGenerateGuid2 = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk 

+     

+     **/

+    private JButton getJButton() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 240, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     *This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 240, 90, 20));

+            jButtonCancel.setPreferredSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldFileName 

+     

+     @return javax.swing.JTextField jTextFieldFileName

+     

+     **/

+    private JTextField getJTextFieldSourceFilesDirectory() {

+        if (jTextFieldFileName == null) {

+            jTextFieldFileName = new JTextField();

+            jTextFieldFileName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldFileName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jComboBoxArch 

+     

+     @return javax.swing.JComboBox jComboBoxArch

+     

+     **/

+    private JComboBox getJComboBoxArch() {

+        if (jComboBoxArch == null) {

+            jComboBoxArch = new JComboBox();

+            jComboBoxArch.setBounds(new java.awt.Rectangle(140, 210, 340, 20));

+            jComboBoxArch.setEnabled(false);

+        }

+        return jComboBoxArch;

+    }

+

+    /**

+     This method initializes jTextFieldLibraryClass 

+     

+     @return javax.swing.JTextField jTextFieldLibraryClass

+     

+     **/

+    private JTextField getJTextFieldLibraryClass() {

+        if (jTextFieldLibraryClass == null) {

+            jTextFieldLibraryClass = new JTextField();

+            jTextFieldLibraryClass.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldLibraryClass;

+    }

+

+    /**

+     This method initializes jTextFieldClassGuid 

+     

+     @return javax.swing.JTextField jTextFieldClassGuid

+     

+     **/

+    private JTextField getJTextFieldClassGuid() {

+        if (jTextFieldClassGuid == null) {

+            jTextFieldClassGuid = new JTextField();

+            jTextFieldClassGuid.setBounds(new java.awt.Rectangle(160, 85, 250, 20));

+        }

+        return jTextFieldClassGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 160, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jComboBoxFileList 

+     

+     @return javax.swing.JComboBox jComboBoxFileList

+     

+     **/

+    private JComboBox getJComboBoxFileList() {

+        if (jComboBoxFileList == null) {

+            jComboBoxFileList = new JComboBox();

+            jComboBoxFileList.setBounds(new java.awt.Rectangle(15, 185, 210, 20));

+            jComboBoxFileList.addItemListener(this);

+            jComboBoxFileList.addActionListener(this);

+        }

+        return jComboBoxFileList;

+    }

+

+    /**

+     This method initializes jButtonAdd 

+     

+     @return javax.swing.JButton jButtonAdd 

+     

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(230, 185, 80, 20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+     This method initializes jButtonRemove 

+     

+     @return javax.swing.JButton jButtonRemove

+     

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(400, 185, 80, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+     This method initializes jButtonUpdate 

+     

+     @return javax.swing.JButton jButtonUpdate

+     

+     **/

+    private JButton getJButtonUpdate() {

+        if (jButtonUpdate == null) {

+            jButtonUpdate = new JButton();

+            jButtonUpdate.setBounds(new java.awt.Rectangle(315, 185, 80, 20));

+            jButtonUpdate.setText("Update");

+            jButtonUpdate.addActionListener(this);

+        }

+        return jButtonUpdate;

+    }

+

+    /**

+     This method initializes jCheckBoxArch 

+     

+     @return javax.swing.JCheckBox jCheckBoxArch

+     

+     **/

+    private JCheckBox getJCheckBoxArch() {

+        if (jCheckBoxArch == null) {

+            jCheckBoxArch = new JCheckBox();

+            jCheckBoxArch.setBounds(new java.awt.Rectangle(10, 210, 119, 20));

+            jCheckBoxArch.setText("Specific Arch");

+            jCheckBoxArch.addActionListener(this);

+        }

+        return jCheckBoxArch;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid2 

+     

+     @return javax.swing.JButton jButtonGenerateGuid2

+     

+     **/

+    private JButton getJButtonGenerateGuid2() {

+        if (jButtonGenerateGuid2 == null) {

+            jButtonGenerateGuid2 = new JButton();

+            jButtonGenerateGuid2.setBounds(new java.awt.Rectangle(415, 85, 65, 20));

+            jButtonGenerateGuid2.setText("GEN");

+            jButtonGenerateGuid2.addActionListener(this);

+        }

+        return jButtonGenerateGuid2;

+    }

+

+    /**

+     This method initializes jTextFieldVersion 

+     

+     @return javax.swing.JTextField jTextFieldVersion

+     

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 110, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public MbdLibraries() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inLibraries The input LibrariesDocument.Libraries

+     

+     **/

+    public MbdLibraries(LibrariesDocument.Libraries inLibraries) {

+        super();

+        init(inLibraries);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inLibraries The input LibrariesDocument.Libraries

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public MbdLibraries(LibrariesDocument.Libraries inLibraries, int type, int index) {

+        super();

+        init(inLibraries);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inLibraries The input LibrariesDocument.Libraries

+     @param type The input data of node type

+     @param index The input data of node index

+     @param inOperation The input data of operation type

+     

+     **/

+    public MbdLibraries(LibrariesDocument.Libraries inLibraries, int type, int index, int inOperation) {

+        super();

+        init(inLibraries, type, index, inOperation);

+        this.operation = inOperation;

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inLibraries LibrariesDocument.Libraries

+     

+     **/

+    private void init(LibrariesDocument.Libraries inLibraries) {

+        init();

+        this.setLibraries(inLibraries);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inLibraries LibrariesDocument.Libraries

+     @param type The input data of node type

+     @param index The input data of node index

+     @param inOperation The input data of operation type

+     

+     **/

+    private void init(LibrariesDocument.Libraries inLibraries, int type, int index, int inOperation) {

+        init(inLibraries);

+        this.location = index;

+        this.operation = inOperation;

+

+        if (operation == 2) {

+            this.jCheckBoxArch.setEnabled(false);

+            this.jComboBoxArch.setEnabled(false);

+

+            if (type == IDefaultMutableTreeNode.LIBRARIES_LIBRARY) {

+                if (this.libraries.getLibraryList().size() > 0) {

+                    for (int indexI = 0; indexI < this.libraries.getLibraryList().size(); indexI++) {

+                        if (this.libraries.getLibraryArray(indexI).getStringValue() != null) {

+                            vName.addElement(this.libraries.getLibraryArray(indexI).getStringValue());

+                        } else {

+                            vName.addElement("");

+                        }

+                        if (this.libraries.getLibraryArray(indexI).getGuid() != null) {

+                            vGuid.addElement(this.libraries.getLibraryArray(indexI).getGuid());

+                        } else {

+                            vGuid.addElement("");

+                        }

+                        if (this.libraries.getLibraryArray(indexI).getLibraryClass() != null) {

+                            vLibraryClass.addElement(this.libraries.getLibraryArray(indexI).getLibraryClass());

+                        } else {

+                            vLibraryClass.addElement("");

+                        }

+                        if (this.libraries.getLibraryArray(indexI).getClassGuid() != null) {

+                            vClassGuid.addElement(this.libraries.getLibraryArray(indexI).getClassGuid());

+                        } else {

+                            vClassGuid.addElement("");

+                        }

+                        if (this.libraries.getLibraryArray(indexI).getVersion() != null) {

+                            vVersion.addElement(this.libraries.getLibraryArray(indexI).getVersion());

+                        } else {

+                            vVersion.addElement("");

+                        }

+                        if (this.libraries.getLibraryArray(indexI).getUsage() != null) {

+                            vUsage.addElement(this.libraries.getLibraryArray(indexI).getUsage().toString());

+                        } else {

+                            vUsage.addElement("ALWAYS_CONSUMED");

+                        }

+                        vOverrideID.addElement(String.valueOf(this.libraries.getLibraryArray(indexI).getOverrideID()));

+                        jComboBoxFileList.addItem(this.libraries.getLibraryArray(indexI).getStringValue());

+                    }

+                }

+            }

+            if (type == IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM) {

+                this.jCheckBoxArch.setSelected(true);

+                this.jComboBoxArch.setSelectedItem(this.libraries.getArchArray(index).getArchType().toString());

+                for (int indexI = 0; indexI < this.libraries.getArchArray(index).getLibraryList().size(); indexI++) {

+                    if (this.libraries.getArchArray(index).getLibraryArray(indexI).getStringValue() != null) {

+                        vName.addElement(this.libraries.getArchArray(index).getLibraryArray(indexI).getStringValue());

+                    } else {

+                        vName.addElement("");

+                    }

+                    if (this.libraries.getArchArray(index).getLibraryArray(indexI).getGuid() != null) {

+                        vGuid.addElement(this.libraries.getArchArray(index).getLibraryArray(indexI).getGuid());

+                    } else {

+                        vGuid.addElement("");

+                    }

+                    if (this.libraries.getArchArray(index).getLibraryArray(indexI).getLibraryClass() != null) {

+                        vLibraryClass.addElement(this.libraries.getArchArray(index).getLibraryArray(indexI)

+                                                               .getLibraryClass());

+                    } else {

+                        vLibraryClass.addElement("");

+                    }

+                    if (this.libraries.getArchArray(index).getLibraryArray(indexI).getClassGuid() != null) {

+                        vClassGuid

+                                  .addElement(this.libraries.getArchArray(index).getLibraryArray(indexI).getClassGuid());

+                    } else {

+                        vClassGuid.addElement("");

+                    }

+                    if (this.libraries.getArchArray(index).getLibraryArray(indexI).getVersion() != null) {

+                        vVersion.addElement(this.libraries.getArchArray(index).getLibraryArray(indexI).getVersion());

+                    } else {

+                        vVersion.addElement("");

+                    }

+                    if (this.libraries.getArchArray(index).getLibraryArray(indexI).getUsage() != null) {

+                        vUsage.addElement(this.libraries.getArchArray(index).getLibraryArray(indexI).getUsage()

+                                                        .toString());

+                    } else {

+                        vUsage.addElement("");

+                    }

+                    vOverrideID.addElement(String.valueOf(this.libraries.getArchArray(index).getLibraryArray(indexI).getOverrideID()));

+                    jComboBoxFileList.addItem(this.libraries.getArchArray(index).getLibraryArray(indexI)

+                                                            .getStringValue());

+                }

+            }

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setName("JFrame");

+        this.setContentPane(getJContentPane());

+        this.setTitle("Source Files");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldFileName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jComboBoxArch.setEnabled(!isView);

+            this.jTextFieldLibraryClass.setEnabled(!isView);

+            this.jTextFieldClassGuid.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jButtonAdd.setEnabled(!isView);

+            this.jButtonRemove.setEnabled(!isView);

+            this.jButtonUpdate.setEnabled(!isView);

+            this.jCheckBoxArch.setEnabled(!isView);

+            this.jTextFieldVersion.setEnabled(!isView);

+

+            this.jButtonOk.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonGenerateGuid2.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelVersion = new JLabel();

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelVersion.setText("Version");

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelClassGuid = new JLabel();

+            jLabelClassGuid.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelClassGuid.setText("Class Guid");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelUsage.setText("Usage");

+            jLabelLibraryClass = new JLabel();

+            jLabelLibraryClass.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelLibraryClass.setText("Library Class");

+            jLabelGuid = new JLabel();

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelName = new JLabel();

+            jLabelName.setText("Name");

+            jLabelName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelName, null);

+            jContentPane.add(getJTextFieldSourceFilesDirectory(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(getJComboBoxArch(), null);

+            jContentPane.add(jLabelLibraryClass, null);

+            jContentPane.add(getJTextFieldLibraryClass(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(jLabelClassGuid, null);

+            jContentPane.add(getJTextFieldClassGuid(), null);

+            jContentPane.add(getJButtonGenerateGuid2(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+            jContentPane.add(getJComboBoxUsage(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(getJComboBoxFileList(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(getJButtonUpdate(), null);

+            jContentPane.add(getJCheckBoxArch(), null);

+

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+        if (arg0.getSource() == jButtonGenerateGuid2) {

+            jTextFieldClassGuid.setText(Tools.generateUuidString());

+        }

+        if (arg0.getSource() == jButtonAdd) {

+            if (!checkAdd()) {

+                return;

+            }

+            addToList();

+        }

+        if (arg0.getSource() == jButtonRemove) {

+            removeFromList();

+        }

+        if (arg0.getSource() == jButtonUpdate) {

+            if (!checkAdd()) {

+                return;

+            }

+            updateForList();

+        }

+        if (arg0.getSource() == jCheckBoxArch) {

+            if (this.jCheckBoxArch.isSelected()) {

+                this.jComboBoxArch.setEnabled(true);

+            } else {

+                this.jComboBoxArch.setEnabled(false);

+            }

+        }

+    }

+

+    /**

+     Init the items of Usage and Arch

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("DEFAULT");

+        jComboBoxUsage.addItem("PRIVATE");

+

+        jComboBoxArch.addItem("ALL");

+        jComboBoxArch.addItem("EBC");

+        jComboBoxArch.addItem("ARM");

+        jComboBoxArch.addItem("IA32");

+        jComboBoxArch.addItem("X64");

+        jComboBoxArch.addItem("IPF");

+        jComboBoxArch.addItem("PPC");

+    }

+

+    /**

+     Add current item to Vector

+     

+     **/

+    private void addToList() {

+        intSelectedItemId = vName.size();

+        vName.addElement(this.jTextFieldFileName.getText());

+        vGuid.addElement(this.jTextFieldGuid.getText());

+        vLibraryClass.addElement(this.jTextFieldLibraryClass.getText());

+        vClassGuid.addElement(this.jTextFieldClassGuid.getText());

+        vVersion.addElement(this.jTextFieldVersion.getText());

+        vUsage.addElement(this.jComboBoxUsage.getSelectedItem().toString());

+        vOverrideID.addElement(this.jTextFieldOverrideID.getText());

+        jComboBoxFileList.addItem(this.jTextFieldFileName.getText());

+        jComboBoxFileList.setSelectedItem(this.jTextFieldFileName.getText());

+        

+        //

+        // Reset select item index

+        //

+        intSelectedItemId = vName.size();

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Remove current item from Vector

+     

+     **/

+    private void removeFromList() {

+        int intTempIndex = intSelectedItemId;

+        if (vName.size() < 1) {

+            return;

+        }

+        

+        jComboBoxFileList.removeItemAt(intSelectedItemId);

+        

+        vName.removeElementAt(intTempIndex);

+        vGuid.removeElementAt(intTempIndex);

+        vLibraryClass.removeElementAt(intTempIndex);

+        vClassGuid.removeElementAt(intTempIndex);

+        vVersion.removeElementAt(intTempIndex);

+        vUsage.removeElementAt(intTempIndex);

+        vOverrideID.removeElementAt(intTempIndex);

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Update current item of Vector

+     

+     **/

+    private void updateForList() {

+        //

+        // Backup selected item index

+        //

+        int intTempIndex = intSelectedItemId;

+        vName.setElementAt(this.jTextFieldFileName.getText(), intSelectedItemId);

+        vGuid.setElementAt(this.jTextFieldGuid.getText(), intSelectedItemId);

+        vLibraryClass.setElementAt(this.jTextFieldLibraryClass.getText(), intSelectedItemId);

+        vClassGuid.setElementAt(this.jTextFieldClassGuid.getText(), intSelectedItemId);

+        vVersion.setElementAt(this.jTextFieldVersion.getText(), intSelectedItemId);

+        vUsage.setElementAt(this.jComboBoxUsage.getSelectedItem().toString(), intSelectedItemId);

+        vOverrideID.setElementAt(this.jTextFieldOverrideID.getText(), intSelectedItemId);

+        

+        jComboBoxFileList.removeAllItems();

+        for (int index = 0; index < vName.size(); index++) {

+            jComboBoxFileList.addItem(vName.elementAt(index));

+        }

+        

+        //

+        // Restore selected item index

+        //

+        intSelectedItemId = intTempIndex;

+        

+        //

+        // Reset select item index

+        //

+        jComboBoxFileList.setSelectedIndex(intSelectedItemId);

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Refresh all fields' values of selected item of Vector

+     

+     **/

+    private void reloadFromList() {

+        if (vName.size() > 0) {

+            //

+            // Get selected item index

+            //

+            intSelectedItemId = jComboBoxFileList.getSelectedIndex();

+            

+            this.jTextFieldFileName.setText(vName.elementAt(intSelectedItemId).toString());

+            this.jComboBoxUsage.setSelectedItem(vUsage.elementAt(intSelectedItemId).toString());

+            this.jTextFieldGuid.setText(vGuid.elementAt(intSelectedItemId).toString());

+            this.jTextFieldLibraryClass.setText(vLibraryClass.elementAt(intSelectedItemId).toString());

+            this.jTextFieldClassGuid.setText(vClassGuid.elementAt(intSelectedItemId).toString());

+            this.jTextFieldVersion.setText(vVersion.elementAt(intSelectedItemId).toString());

+            this.jTextFieldOverrideID.setText(vOverrideID.elementAt(intSelectedItemId).toString());

+        } else {

+            this.jTextFieldFileName.setText("");

+            this.jComboBoxUsage.setSelectedIndex(0);

+            this.jTextFieldGuid.setText("");

+            this.jTextFieldLibraryClass.setText("");

+            this.jTextFieldClassGuid.setText("");

+            this.jTextFieldVersion.setText("");

+            this.jTextFieldOverrideID.setText("");

+        }

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)

+     *

+     * Reflesh the frame when selected item changed 

+     */

+    public void itemStateChanged(ItemEvent arg0) {

+        if (arg0.getStateChange() == ItemEvent.SELECTED) {

+            reloadFromList();

+        }

+    }

+

+    /**

+     Data validation for all fields before save

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        if (this.jComboBoxFileList.getItemCount() < 1) {

+            Log.err("Must have one Library at least!");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Data validation for all fields before add current item to Vector

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean checkAdd() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldFileName.getText())) {

+            Log.err("File Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isBaseName(this.jTextFieldFileName.getText())) {

+            Log.err("Incorrect data type for Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldLibraryClass.getText())

+            && !DataValidation.isPath(this.jTextFieldLibraryClass.getText())) {

+            Log.err("Incorrect data type for Path");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldClassGuid.getText()) && !DataValidation.isGuid(this.jTextFieldClassGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Mbd Libraries

+     if exists libraries, set the value directly

+     if not exists libraries, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.libraries == null) {

+                libraries = LibrariesDocument.Libraries.Factory.newInstance();

+            }

+            //

+            //Save as file name

+            //

+            if (!this.jCheckBoxArch.isSelected()) {

+                if (this.operation == 2) { //Add new filename

+                    //

+                    //First remove all existed filename

+                    //

+                    if (libraries.getLibraryList().size() > 0) {

+                        for (int index = libraries.getLibraryList().size() - 1; index >= 0; index--) {

+                            libraries.removeLibrary(index);

+                        }

+                    }

+                }

+                LibrariesDocument.Libraries.Library library = LibrariesDocument.Libraries.Library.Factory.newInstance();

+                for (int index = 0; index < vName.size(); index++) {

+                    if (!isEmpty(vName.elementAt(index).toString())) {

+                        library.setStringValue(vName.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vGuid.elementAt(index).toString())) {

+                        library.setGuid(vGuid.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vLibraryClass.elementAt(index).toString())) {

+                        library.setLibraryClass(vLibraryClass.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vClassGuid.elementAt(index).toString())) {

+                        library.setClassGuid(vClassGuid.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vVersion.elementAt(index).toString())) {

+                        library.setVersion(vVersion.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vUsage.elementAt(index).toString())) {

+                        library.setUsage(LibraryUsage.Enum.forString(vUsage.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vOverrideID.elementAt(index).toString())) {

+                        library.setOverrideID(Integer.parseInt(vOverrideID.elementAt(index).toString()));

+                    }

+                    libraries.addNewLibrary();

+                    libraries.setLibraryArray(libraries.getLibraryList().size() - 1, library);

+                }

+            }

+            //

+            //Save as Arch

+            //

+            if (this.jCheckBoxArch.isSelected()) {

+                LibrariesDocument.Libraries.Arch arch = LibrariesDocument.Libraries.Arch.Factory.newInstance();

+                if (this.operation == 2) {

+                    //First remove all existed filename

+                    for (int index = libraries.getArchArray(location).getLibraryList().size() - 1; index >= 0; index--) {

+                        libraries.getArchArray(location).removeLibrary(index);

+                    }

+                }

+                for (int index = 0; index < vName.size(); index++) {

+                    LibrariesDocument.Libraries.Arch.Library library = LibrariesDocument.Libraries.Arch.Library.Factory.newInstance();

+                    if (!isEmpty(vName.elementAt(index).toString())) {

+                        library.setStringValue(vName.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vGuid.elementAt(index).toString())) {

+                        library.setGuid(vGuid.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vLibraryClass.elementAt(index).toString())) {

+                        library.setLibraryClass(vLibraryClass.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vClassGuid.elementAt(index).toString())) {

+                        library.setClassGuid(vClassGuid.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vVersion.elementAt(index).toString())) {

+                        library.setVersion(vVersion.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vUsage.elementAt(index).toString())) {

+                        library.setUsage(LibraryUsage.Enum.forString(vUsage.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vOverrideID.elementAt(index).toString())) {

+                        library.setOverrideID(Integer.parseInt(vOverrideID.elementAt(index).toString()));

+                    }

+                    arch.addNewLibrary();

+                    arch.setLibraryArray(arch.getLibraryList().size() - 1, library);

+                }

+                arch

+                    .setArchType(SupportedArchitectures.Enum.forString(this.jComboBoxArch.getSelectedItem().toString()));

+                if (location > -1) {

+                    libraries.setArchArray(location, arch);

+                } else {

+                    libraries.addNewArch();

+                    libraries.setArchArray(libraries.getArchList().size() - 1, arch);

+                }

+            }

+        } catch (Exception e) {

+            Log.err("Update Source Files", e.getMessage());

+        }

+    }

+

+    /**

+     Get LibrariesDocument.Libraries

+     

+     @return LibrariesDocument.Libraries

+     

+     **/

+    public LibrariesDocument.Libraries getLibraries() {

+        return libraries;

+    }

+

+    /**

+     Set LibrariesDocument.Libraries

+     

+     @param libraries The input LibrariesDocument.Libraries

+     

+     **/

+    public void setLibraries(LibrariesDocument.Libraries libraries) {

+        this.libraries = libraries;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleAbout.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleAbout.java
new file mode 100644
index 0000000..eb217f5
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleAbout.java
@@ -0,0 +1,146 @@
+/** @file

+ 

+ To show a about window with copyright information

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.WindowEvent;

+

+import javax.swing.JButton;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+

+import org.tianocore.packaging.common.ui.IDialog;

+

+/**

+ The class is used to show a about window with copyright information

+ It extends IDialog

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleAbout extends IDialog {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 2958136136667310962L;

+

+    //

+    //Define class members

+    //

+    private JPanel jContentPane = null;

+

+    private JLabel jLabel = null;

+

+    private JLabel jLabel1 = null;

+

+    private JLabel jLabel2 = null;

+

+    private JButton jButtonOK = null;

+

+    /**

+     This method initializes jButtonOK 

+     

+     @return javax.swing.JButton jButtonOK

+     

+     **/

+    private JButton getJButtonOK() {

+        if (jButtonOK == null) {

+            jButtonOK = new JButton();

+            jButtonOK.setBounds(new java.awt.Rectangle(105, 120, 90, 20));

+            jButtonOK.setText("OK");

+            jButtonOK.addActionListener(this);

+        }

+        return jButtonOK;

+    }

+

+    public static void main(String[] args) {

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleAbout() {

+        super();

+        init();

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(300, 200);

+        this.setContentPane(getJContentPane());

+        this.setTitle("About...");

+        this.getRootPane().setDefaultButton(jButtonOK);

+        this.centerWindow();

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabel2 = new JLabel();

+            jLabel2.setBounds(new java.awt.Rectangle(15, 80, 270, 20));

+            jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

+            jLabel2.setText("All rights reserved");

+            jLabel1 = new JLabel();

+            jLabel1.setBounds(new java.awt.Rectangle(15, 50, 270, 20));

+            jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

+            jLabel1.setText("Copyright (c) 2006, Intel Corporation");

+            jLabel = new JLabel();

+            jLabel.setToolTipText("");

+            jLabel.setBounds(new java.awt.Rectangle(15, 20, 270, 20));

+            jLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

+            jLabel.setText("Framework Development Package System 1.0");

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(jLabel1, null);

+            jContentPane.add(jLabel2, null);

+            jContentPane.add(getJButtonOK(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     * 

+     * Override actionPerformed to listen all actions

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOK) {

+            this.dispose();

+        }

+    }

+

+    /**

+     Dispose when windows is closing

+     

+     @param arg0

+     

+     **/

+    public void windowClosing(WindowEvent arg0) {

+        this.dispose();

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleBootModes.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleBootModes.java
new file mode 100644
index 0000000..308b17d
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleBootModes.java
@@ -0,0 +1,456 @@
+/** @file

+ 

+ The file is used to create, update BootModes of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.BootModeNames;

+import org.tianocore.BootModeUsage;

+import org.tianocore.BootModesDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update BootModes of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleBootModes extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -3888558623432442561L;

+

+    //

+    //Define class members

+    //

+    private BootModesDocument.BootModes bootModes = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelBootModeName = null;

+

+    private JComboBox jComboBoxBootModeName = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid 

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jComboBoxBootModeName 

+     

+     @return javax.swing.JComboBox jComboBoxBootModeName

+     

+     **/

+    private JComboBox getJComboBoxBootModeName() {

+        if (jComboBoxBootModeName == null) {

+            jComboBoxBootModeName = new JComboBox();

+            jComboBoxBootModeName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jComboBoxBootModeName;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(280, 115, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 115, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 85, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    public static void main(String[] args) {

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleBootModes() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inBootModes The input BootModesDocument.BootModes

+     

+     **/

+    public ModuleBootModes(BootModesDocument.BootModes inBootModes) {

+        super();

+        init(inBootModes);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inBootModes The input BootModesDocument.BootModes

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleBootModes(BootModesDocument.BootModes inBootModes, int type, int index) {

+        super();

+        init(inBootModes, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+

+     @param inBootModes BootModesDocument.BootModes

+     

+     **/

+    private void init(BootModesDocument.BootModes inBootModes) {

+        init();

+        this.setBootModes(inBootModes);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inBootModes The input BootModesDocument.BootModes

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(BootModesDocument.BootModes inBootModes, int type, int index) {

+        init(inBootModes);

+        this.location = index;

+        if (this.bootModes.getBootModeList().size() > 0) {

+            if (this.bootModes.getBootModeArray(index).getBootModeName() != null) {

+                this.jComboBoxBootModeName.setSelectedItem(this.bootModes.getBootModeArray(index).getBootModeName()

+                                                                         .toString());

+            }

+            if (this.bootModes.getBootModeArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.bootModes.getBootModeArray(index).getGuid());

+            }

+            if (this.bootModes.getBootModeArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.bootModes.getBootModeArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.bootModes.getBootModeArray(index).getOverrideID()));

+        }

+    }

+

+    /**

+     * This method initializes this

+     * 

+     * @return void

+     */

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Boot Mode");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 515));

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jComboBoxBootModeName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelBootModeName = new JLabel();

+            jLabelBootModeName.setText("Boot Mode Name");

+            jLabelBootModeName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelBootModeName, null);

+            jContentPane.add(getJComboBoxBootModeName(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes BootModeName groups and Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+

+        jComboBoxBootModeName.addItem("FULL");

+        jComboBoxBootModeName.addItem("MINIMAL");

+        jComboBoxBootModeName.addItem("NO_CHANGE");

+        jComboBoxBootModeName.addItem("DIAGNOSTICS");

+        jComboBoxBootModeName.addItem("DEFAULT");

+        jComboBoxBootModeName.addItem("S2_RESUME");

+        jComboBoxBootModeName.addItem("S3_RESUME");

+        jComboBoxBootModeName.addItem("S4_RESUME");

+        jComboBoxBootModeName.addItem("S5_RESUME");

+        jComboBoxBootModeName.addItem("FLASH_UPDATE");

+        jComboBoxBootModeName.addItem("RECOVERY");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Get BootModesDocument.BootModes

+     

+     @return BootModesDocument.BootModes

+     

+     **/

+    public BootModesDocument.BootModes getBootModes() {

+        return bootModes;

+    }

+

+    /**

+     Set BootModesDocument.BootModes

+     

+     @param bootModes BootModesDocument.BootModes

+     

+     **/

+    public void setBootModes(BootModesDocument.BootModes bootModes) {

+        this.bootModes = bootModes;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Mbd Header

+     if exists bootModes, set the value directly

+     if not exists bootModes, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.bootModes == null) {

+                bootModes = BootModesDocument.BootModes.Factory.newInstance();

+            }

+            BootModesDocument.BootModes.BootMode bootMode = BootModesDocument.BootModes.BootMode.Factory.newInstance();

+            bootMode.setBootModeName(BootModeNames.Enum.forString(jComboBoxBootModeName.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldGuid.getText())) {

+                bootMode.setGuid(this.jTextFieldGuid.getText());

+            }

+            bootMode.setUsage(BootModeUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                bootMode.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+            if (location > -1) {

+                bootModes.setBootModeArray(location, bootMode);

+            } else {

+                bootModes.addNewBootMode();

+                bootModes.setBootModeArray(bootModes.getBootModeList().size() - 1, bootMode);

+            }

+        } catch (Exception e) {

+            Log.err("Update Boot Modes", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleDataHubs.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleDataHubs.java
new file mode 100644
index 0000000..79613d2
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleDataHubs.java
@@ -0,0 +1,457 @@
+/** @file

+ 

+ The file is used to create, update DataHub of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.DataHubUsage;

+import org.tianocore.DataHubsDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update DataHub of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleDataHubs extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -3667906991966638892L;

+

+    //

+    //Define class members

+    //

+    private DataHubsDocument.DataHubs dataHubs = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelDataHubRecord = null;

+

+    private JTextField jTextFieldDataHubRecord = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(280, 115, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 115, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldDataHubRecord 

+     

+     @return javax.swing.JTextField jTextFieldDataHubRecord

+     

+     **/

+    private JTextField getJTextFieldDataHubRecord() {

+        if (jTextFieldDataHubRecord == null) {

+            jTextFieldDataHubRecord = new JTextField();

+            jTextFieldDataHubRecord.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldDataHubRecord;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 85, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleDataHubs() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inDataHubs The input DataHubsDocument.DataHubs

+     

+     **/

+    public ModuleDataHubs(DataHubsDocument.DataHubs inDataHubs) {

+        super();

+        init(inDataHubs);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inDataHubs DataHubsDocument.DataHubs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleDataHubs(DataHubsDocument.DataHubs inDataHubs, int type, int index) {

+        super();

+        init(inDataHubs, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inDataHubs The input DataHubsDocument.DataHubs

+     

+     **/

+    private void init(DataHubsDocument.DataHubs inDataHubs) {

+        init();

+        this.setDataHubs(inDataHubs);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inDataHubs The input DataHubsDocument.DataHubs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(DataHubsDocument.DataHubs inDataHubs, int type, int index) {

+        init(inDataHubs);

+        this.location = index;

+        if (this.dataHubs.getDataHubRecordList().size() > 0) {

+            if (this.dataHubs.getDataHubRecordArray(index).getStringValue() != null) {

+                this.jTextFieldDataHubRecord.setText(this.dataHubs.getDataHubRecordArray(index).getStringValue()

+                                                                  .toString());

+            }

+            if (this.dataHubs.getDataHubRecordArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.dataHubs.getDataHubRecordArray(index).getGuid());

+            }

+            if (this.dataHubs.getDataHubRecordArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.dataHubs.getDataHubRecordArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID

+                                     .setText(String

+                                                    .valueOf(this.dataHubs.getDataHubRecordArray(index).getOverrideID()));

+        }

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldDataHubRecord.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Data Hubs");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelDataHubRecord = new JLabel();

+            jLabelDataHubRecord.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelDataHubRecord.setText("Data Hub Record");

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelDataHubRecord, null);

+            jContentPane.add(getJTextFieldDataHubRecord(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Get DataHubsDocument.DataHubs

+     

+     @return DataHubsDocument.DataHubs

+     

+     **/

+    public DataHubsDocument.DataHubs getDataHubs() {

+        return dataHubs;

+    }

+

+    /**

+     Set DataHubsDocument.DataHubs

+     

+     @param dataHubs DataHubsDocument.DataHubs

+     

+     **/

+    public void setDataHubs(DataHubsDocument.DataHubs dataHubs) {

+        this.dataHubs = dataHubs;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldDataHubRecord.getText())) {

+            Log.err("Data Hub Record couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of DataHubs

+     if exists dataHubs, set the value directly

+     if not exists dataHubs, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.dataHubs == null) {

+                dataHubs = DataHubsDocument.DataHubs.Factory.newInstance();

+            }

+            DataHubsDocument.DataHubs.DataHubRecord dataHubRecord = DataHubsDocument.DataHubs.DataHubRecord.Factory

+                                                                                                                   .newInstance();

+            if (!isEmpty(this.jTextFieldDataHubRecord.getText())) {

+                dataHubRecord.setStringValue(this.jTextFieldDataHubRecord.getText());

+            }

+            if (!isEmpty(this.jTextFieldGuid.getText())) {

+                dataHubRecord.setGuid(this.jTextFieldGuid.getText());

+            }

+            dataHubRecord.setUsage(DataHubUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                dataHubRecord.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+            if (location > -1) {

+                dataHubs.setDataHubRecordArray(location, dataHubRecord);

+            } else {

+                dataHubs.addNewDataHubRecord();

+                dataHubs.setDataHubRecordArray(dataHubs.getDataHubRecordList().size() - 1, dataHubRecord);

+            }

+        } catch (Exception e) {

+            Log.err("Update Data Hubs", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleEvents.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleEvents.java
new file mode 100644
index 0000000..5d6151f
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleEvents.java
@@ -0,0 +1,626 @@
+/** @file

+ 

+ The file is used to create, update Event of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.Dimension;

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+

+import org.tianocore.EventTypes;

+import org.tianocore.EventUsage;

+import org.tianocore.EventsDocument;

+import org.tianocore.GuidDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Event of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleEvents extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -4396143706422842331L;

+

+    //

+    //Define class members

+    //

+    private EventsDocument.Events events = null;

+

+    private EventsDocument.Events.CreateEvents createEvent = null;

+

+    private EventsDocument.Events.SignalEvents signalEvent = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelEventType = null;

+

+    private JRadioButton jRadioButtonEventCreate = null;

+

+    private JRadioButton jRadioButtonEventSignal = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelEventGroup = null;

+

+    private JComboBox jComboBoxEventGroup = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    /**

+     This method initializes jRadioButtonEnentType 

+     

+     @return javax.swing.JRadioButton jRadioButtonEventCreate

+     

+     **/

+    private JRadioButton getJRadioButtonEventCreate() {

+        if (jRadioButtonEventCreate == null) {

+            jRadioButtonEventCreate = new JRadioButton();

+            jRadioButtonEventCreate.setText("Create");

+            jRadioButtonEventCreate.setBounds(new java.awt.Rectangle(160, 10, 90, 20));

+            jRadioButtonEventCreate.addActionListener(this);

+            jRadioButtonEventCreate.setSelected(true);

+        }

+        return jRadioButtonEventCreate;

+    }

+

+    /**

+     This method initializes jRadioButtonEventSignal 

+     

+     @return javax.swing.JRadioButton jRadioButtonEventSignal

+     

+     **/

+    private JRadioButton getJRadioButtonEventSignal() {

+        if (jRadioButtonEventSignal == null) {

+            jRadioButtonEventSignal = new JRadioButton();

+            jRadioButtonEventSignal.setText("Signal");

+            jRadioButtonEventSignal.setBounds(new java.awt.Rectangle(320, 10, 90, 20));

+            jRadioButtonEventSignal.addActionListener(this);

+        }

+        return jRadioButtonEventSignal;

+    }

+

+    /**

+     This method initializes jTextFieldC_Name 

+     

+     @return javax.swing.JTextField jTextFieldC_Name

+     

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 60, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jComboBoxEventGroup 

+     

+     @return javax.swing.JComboBox jComboBoxEventGroup

+     

+     **/

+    private JComboBox getJComboBoxEventGroup() {

+        if (jComboBoxEventGroup == null) {

+            jComboBoxEventGroup = new JComboBox();

+            jComboBoxEventGroup.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return jComboBoxEventGroup;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 110, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButton() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 165, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 165, 90, 20));

+            jButtonCancel.setPreferredSize(new Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 60, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 135, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleEvents() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inEvents The input EventsDocument.Events

+     

+     **/

+    public ModuleEvents(EventsDocument.Events inEvents) {

+        super();

+        init(inEvents);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inEvents The input EventsDocument.Events

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleEvents(EventsDocument.Events inEvents, int type, int index) {

+        super();

+        init(inEvents, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inEvents The input EventsDocument.Events

+     

+     **/

+    private void init(EventsDocument.Events inEvents) {

+        init();

+        this.setEvents(inEvents);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inEvents EventsDocument.Events

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(EventsDocument.Events inEvents, int type, int index) {

+        init(inEvents);

+        this.location = index;

+        if (type == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS_ITEM) {

+            this.jRadioButtonEventCreate.setSelected(true);

+            this.jRadioButtonEventSignal.setSelected(false);

+            if (this.events.getCreateEvents().getEventArray(index).getCName() != null) {

+                this.jTextFieldC_Name.setText(this.events.getCreateEvents().getEventArray(index).getCName());

+            }

+            if (this.events.getCreateEvents().getEventArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.events.getCreateEvents().getEventArray(index).getGuid()

+                                                       .getStringValue());

+            }

+            if (this.events.getCreateEvents().getEventArray(index).getEventGroup() != null) {

+                this.jComboBoxEventGroup.setSelectedItem(this.events.getCreateEvents().getEventArray(index)

+                                                                    .getEventGroup().toString());

+            }

+            if (this.events.getCreateEvents().getEventArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.events.getCreateEvents().getEventArray(index).getUsage()

+                                                               .toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.events.getCreateEvents().getEventArray(index)

+                                                                        .getOverrideID()));

+        } else if (type == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS_ITEM) {

+            this.jRadioButtonEventCreate.setSelected(false);

+            this.jRadioButtonEventSignal.setSelected(true);

+            this.jComboBoxUsage.setEnabled(false);

+            if (this.events.getSignalEvents().getEventArray(index).getCName() != null) {

+                this.jTextFieldC_Name.setText(this.events.getSignalEvents().getEventArray(index).getCName());

+            }

+            if (this.events.getSignalEvents().getEventArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.events.getSignalEvents().getEventArray(index).getGuid().toString());

+            }

+            if (this.events.getSignalEvents().getEventArray(index).getEventGroup() != null) {

+                this.jComboBoxEventGroup.setSelectedItem(this.events.getSignalEvents().getEventArray(index)

+                                                                    .getEventGroup().toString());

+            }

+            if (this.events.getSignalEvents().getEventArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.events.getSignalEvents().getEventArray(index).getUsage()

+                                                               .toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.events.getSignalEvents().getEventArray(index)

+                                                                        .getOverrideID()));

+        }

+        this.jRadioButtonEventCreate.setEnabled(false);

+        this.jRadioButtonEventSignal.setEnabled(false);

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Events");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jRadioButtonEventCreate.setEnabled(!isView);

+            this.jRadioButtonEventSignal.setEnabled(!isView);

+            this.jTextFieldC_Name.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxEventGroup.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelEventGroup = new JLabel();

+            jLabelEventGroup.setText("Event Group");

+            jLabelEventGroup.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelEventType = new JLabel();

+            jLabelEventType.setText("Event Type");

+            jLabelEventType.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelEventType, null);

+            jContentPane.add(getJRadioButtonEventCreate(), null);

+            jContentPane.add(getJRadioButtonEventSignal(), null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelEventGroup, null);

+            jContentPane.add(getJComboBoxEventGroup(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setBounds(new java.awt.Rectangle(0, 10, 10, 20));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setBounds(new java.awt.Rectangle(0, 35, 10, 20));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes events groups and usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxEventGroup.addItem("EVENT_GROUP_EXIT_BOOT_SERVICES");

+        jComboBoxEventGroup.addItem("EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE");

+        jComboBoxEventGroup.addItem("EVENT_GROUP_MEMORY_MAP_CHANGE");

+        jComboBoxEventGroup.addItem("EVENT_GROUP_READY_TO_BOOT");

+        jComboBoxEventGroup.addItem("EVENT_GROUP_LEGACY_BOOT");

+

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jRadioButtonEventCreate) {

+            if (jRadioButtonEventCreate.isSelected()) {

+                jRadioButtonEventSignal.setSelected(false);

+            }

+            if (!jRadioButtonEventSignal.isSelected() && !jRadioButtonEventCreate.isSelected()) {

+                jRadioButtonEventCreate.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonEventSignal) {

+            if (jRadioButtonEventSignal.isSelected()) {

+                jRadioButtonEventCreate.setSelected(false);

+            }

+            if (!jRadioButtonEventSignal.isSelected() && !jRadioButtonEventCreate.isSelected()) {

+                jRadioButtonEventSignal.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    public EventsDocument.Events getEvents() {

+        return events;

+    }

+

+    public void setEvents(EventsDocument.Events events) {

+        this.events = events;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldC_Name.getText())) {

+            Log.err("C_Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isCName(this.jTextFieldC_Name.getText())) {

+            Log.err("Incorrect data type for C_Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Events

+     if exists events, set the value directly

+     if not exists events, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.events == null) {

+                events = EventsDocument.Events.Factory.newInstance();

+                createEvent = EventsDocument.Events.CreateEvents.Factory.newInstance();

+                signalEvent = EventsDocument.Events.SignalEvents.Factory.newInstance();

+            } else {

+                if (events.getCreateEvents() != null) {

+                    createEvent = events.getCreateEvents();

+                } else {

+                    createEvent = EventsDocument.Events.CreateEvents.Factory.newInstance();

+                }

+                if (events.getSignalEvents() != null) {

+                    signalEvent = events.getSignalEvents();

+                } else {

+                    signalEvent = EventsDocument.Events.SignalEvents.Factory.newInstance();

+                }

+

+            }

+            if (this.jRadioButtonEventCreate.isSelected()) {

+                EventsDocument.Events.CreateEvents.Event event = EventsDocument.Events.CreateEvents.Event.Factory

+                                                                                                                 .newInstance();

+                event.setCName(this.jTextFieldC_Name.getText());

+                if (!isEmpty(this.jTextFieldGuid.getText())) {

+                    GuidDocument.Guid guid = GuidDocument.Guid.Factory.newInstance();

+                    guid.setStringValue(this.jTextFieldGuid.getText());

+                    event.setGuid(guid);

+                }

+                event.setEventGroup(EventTypes.Enum.forString(jComboBoxEventGroup.getSelectedItem().toString()));

+                event.setUsage(EventUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+                if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                    event.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+                }

+                if (location > -1) {

+                    createEvent.setEventArray(location, event);

+                } else {

+                    createEvent.addNewEvent();

+                    createEvent.setEventArray(createEvent.getEventList().size() - 1, event);

+                }

+                events.setCreateEvents(createEvent);

+            }

+            if (this.jRadioButtonEventSignal.isSelected()) {

+                EventsDocument.Events.SignalEvents.Event event = EventsDocument.Events.SignalEvents.Event.Factory

+                                                                                                                 .newInstance();

+                event.setCName(this.jTextFieldC_Name.getText());

+                if (!isEmpty(this.jTextFieldGuid.getText())) {

+                    GuidDocument.Guid guid = GuidDocument.Guid.Factory.newInstance();

+                    guid.setStringValue(this.jTextFieldGuid.getText());

+                    event.setGuid(guid);

+                }

+                event.setEventGroup(EventTypes.Enum.forString(jComboBoxEventGroup.getSelectedItem().toString()));

+                event.setUsage(EventUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+                if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                    event.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+                }

+                if (location > -1) {

+                    signalEvent.setEventArray(location, event);

+                } else {

+                    signalEvent.addNewEvent();

+                    signalEvent.setEventArray(signalEvent.getEventList().size() - 1, event);

+                }

+                events.setSignalEvents(signalEvent);

+            }

+        } catch (Exception e) {

+            Log.err("Update Events", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleExterns.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleExterns.java
new file mode 100644
index 0000000..263f1b4
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleExterns.java
@@ -0,0 +1,1030 @@
+/** @file

+ 

+ The file is used to create, update DataHub of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.ItemEvent;

+import java.awt.event.ItemListener;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.ExternUsage;

+import org.tianocore.ExternsDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.packaging.common.ui.IComboBox;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+

+/**

+ The class is used to create, update DataHub of MSA/MBD file 

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleExterns extends IInternalFrame implements ItemListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -7382008402932047191L;

+

+    //

+    //Define class members

+    //

+    private ExternsDocument.Externs externs = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelName = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private JPanel jPanelType1 = null;

+

+    private JLabel jLabelModuleEntryPoint = null;

+

+    private JLabel jLabelModuleUnloadImage = null;

+

+    private IComboBox iComboBoxModuleEntryPoint = null;

+

+    private IComboBox iComboBoxModuleUnloadImage = null;

+

+    private JPanel jPanelType2 = null;

+

+    private JLabel jLabelConstructor = null;

+

+    private JTextField jTextFieldConstructor = null;

+

+    private JLabel jLabelDestructor = null;

+

+    private JTextField jTextFieldDestructor = null;

+

+    private JComboBox jComboBoxType = null;

+

+    private JPanel jPanelType3 = null;

+

+    private JLabel jLabelDriverBinding = null;

+

+    private JLabel jLabelComponentName = null;

+

+    private IComboBox iComboBoxComponentName = null;

+

+    private IComboBox iComboBoxDriverBinding = null;

+

+    private JLabel jLabelDriverConfig = null;

+

+    private JLabel jLabelDriverDiag = null;

+

+    private IComboBox iComboBoxDriverDiag = null;

+

+    private IComboBox iComboBoxDriverConfig = null;

+

+    private JPanel jPanelType4 = null;

+

+    private JLabel jLabelSetVirtualAddressMapCallBack = null;

+

+    private IComboBox iComboBoxSetVirtualAddressMapCallBack = null;

+

+    private JLabel jLabelExitBootServicesCallBack = null;

+

+    private IComboBox iComboBoxExitBootServicesCallBack = null;

+

+    private JPanel jPanelType5 = null;

+

+    private JLabel jLabelUserDefined = null;

+

+    private IComboBox iComboBoxUserDefined = null;

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setLocation(new java.awt.Point(290, 215));

+            jButtonOk.setSize(new java.awt.Dimension(90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setLocation(new java.awt.Point(390, 215));

+            jButtonCancel.setSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 60, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    /**

+     This method initializes jPanelType1 

+     

+     @return javax.swing.JPanel jPanelType1

+     

+     **/

+    private JPanel getJPanelType1() {

+        if (jPanelType1 == null) {

+            jLabelModuleUnloadImage = new JLabel();

+            jLabelModuleUnloadImage.setBounds(new java.awt.Rectangle(15, 30, 140, 20));

+            jLabelModuleUnloadImage.setText("Module Unload Image");

+            jLabelModuleEntryPoint = new JLabel();

+            jLabelModuleEntryPoint.setBounds(new java.awt.Rectangle(15, 5, 140, 20));

+            jLabelModuleEntryPoint.setText("Module Entry Point");

+            jPanelType1 = new JPanel();

+            jPanelType1.setLayout(null);

+            jPanelType1.setBounds(new java.awt.Rectangle(0, 105, 490, 55));

+            jPanelType1.add(jLabelModuleEntryPoint, null);

+            jPanelType1.add(jLabelModuleUnloadImage, null);

+            jPanelType1.add(getIComboBoxModuleUnloadImage(), null);

+            jPanelType1.add(getIComboBoxModuleEntryPoint(), null);

+        }

+        return jPanelType1;

+    }

+

+    /**

+     This method initializes jComboBoxModuleEntryPoint 

+     

+     @return javax.swing.JComboBox iComboBoxModuleEntryPoint

+     

+     **/

+    private IComboBox getIComboBoxModuleEntryPoint() {

+        if (iComboBoxModuleEntryPoint == null) {

+            iComboBoxModuleEntryPoint = new IComboBox();

+            iComboBoxModuleEntryPoint.setBounds(new java.awt.Rectangle(160, 5, 320, 20));

+        }

+        return iComboBoxModuleEntryPoint;

+    }

+

+    /**

+     This method initializes jComboBoxModuleUnloadImage 

+     

+     @return javax.swing.JComboBox iComboBoxModuleUnloadImage

+     

+     **/

+    private IComboBox getIComboBoxModuleUnloadImage() {

+        if (iComboBoxModuleUnloadImage == null) {

+            iComboBoxModuleUnloadImage = new IComboBox();

+            iComboBoxModuleUnloadImage.setBounds(new java.awt.Rectangle(160, 30, 320, 20));

+        }

+        return iComboBoxModuleUnloadImage;

+    }

+

+    /**

+     This method initializes jPanelType2 

+     

+     @return javax.swing.JPanel jPanelType2

+     

+     **/

+    private JPanel getJPanelType2() {

+        if (jPanelType2 == null) {

+            jLabelDestructor = new JLabel();

+            jLabelDestructor.setBounds(new java.awt.Rectangle(15, 30, 140, 20));

+            jLabelDestructor.setText("Destructor");

+            jLabelConstructor = new JLabel();

+            jLabelConstructor.setBounds(new java.awt.Rectangle(15, 5, 140, 20));

+            jLabelConstructor.setText("Constructor");

+            jPanelType2 = new JPanel();

+            jPanelType2.setLayout(null);

+            jPanelType2.setBounds(new java.awt.Rectangle(0, 105, 490, 55));

+            jPanelType2.add(jLabelConstructor, null);

+            jPanelType2.add(getJTextFieldConstructor(), null);

+            jPanelType2.add(jLabelDestructor, null);

+            jPanelType2.add(getJTextFieldDestructor(), null);

+        }

+        return jPanelType2;

+    }

+

+    /**

+     This method initializes jTextFieldConstructor 

+     

+     @return javax.swing.JTextField jTextFieldConstructor

+     

+     **/

+    private JTextField getJTextFieldConstructor() {

+        if (jTextFieldConstructor == null) {

+            jTextFieldConstructor = new JTextField();

+            jTextFieldConstructor.setBounds(new java.awt.Rectangle(160, 5, 320, 20));

+        }

+        return jTextFieldConstructor;

+    }

+

+    /**

+     This method initializes jTextFieldDestructor 

+     

+     @return javax.swing.JTextField jTextFieldDestructor

+     

+     **/

+    private JTextField getJTextFieldDestructor() {

+        if (jTextFieldDestructor == null) {

+            jTextFieldDestructor = new JTextField();

+            jTextFieldDestructor.setBounds(new java.awt.Rectangle(160, 30, 320, 20));

+        }

+        return jTextFieldDestructor;

+    }

+

+    /**

+     This method initializes jComboBoxType 

+     

+     @return javax.swing.JComboBox jComboBoxType

+     

+     **/

+    private JComboBox getJComboBoxType() {

+        if (jComboBoxType == null) {

+            jComboBoxType = new JComboBox();

+            jComboBoxType.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+            jComboBoxType.addItemListener(this);

+        }

+        return jComboBoxType;

+    }

+

+    /**

+     This method initializes jPanelType3 

+     

+     @return javax.swing.JPanel jPanelType3

+     

+     **/

+    private JPanel getJPanelType3() {

+        if (jPanelType3 == null) {

+            jLabelDriverDiag = new JLabel();

+            jLabelDriverDiag.setBounds(new java.awt.Rectangle(15, 80, 140, 20));

+            jLabelDriverDiag.setText("Driver Diag");

+            jLabelDriverConfig = new JLabel();

+            jLabelDriverConfig.setBounds(new java.awt.Rectangle(15, 55, 140, 20));

+            jLabelDriverConfig.setText("Driver Config");

+            jLabelComponentName = new JLabel();

+            jLabelComponentName.setBounds(new java.awt.Rectangle(15, 30, 140, 20));

+            jLabelComponentName.setText("Component Name");

+            jLabelDriverBinding = new JLabel();

+            jLabelDriverBinding.setBounds(new java.awt.Rectangle(15, 5, 140, 20));

+            jLabelDriverBinding.setText("Driver Binding");

+            jPanelType3 = new JPanel();

+            jPanelType3.setLayout(null);

+            jPanelType3.setBounds(new java.awt.Rectangle(0, 105, 490, 105));

+            jPanelType3.add(jLabelDriverBinding, null);

+            jPanelType3.add(jLabelComponentName, null);

+            jPanelType3.add(getIComboBoxComponentName(), null);

+            jPanelType3.add(getIComboBoxDriverBinding(), null);

+            jPanelType3.add(jLabelDriverConfig, null);

+            jPanelType3.add(jLabelDriverDiag, null);

+            jPanelType3.add(getIComboBoxDriverDiag(), null);

+            jPanelType3.add(getIComboBoxDriverConfig(), null);

+        }

+        return jPanelType3;

+    }

+

+    /**

+     This method initializes jComboBoxComponentName 

+     

+     @return javax.swing.JComboBox iComboBoxComponentName

+     

+     **/

+    private IComboBox getIComboBoxComponentName() {

+        if (iComboBoxComponentName == null) {

+            iComboBoxComponentName = new IComboBox();

+            iComboBoxComponentName.setBounds(new java.awt.Rectangle(160, 30, 320, 20));

+        }

+        return iComboBoxComponentName;

+    }

+

+    /**

+     This method initializes jComboBoxDriverBinding 

+     

+     @return javax.swing.JComboBox iComboBoxDriverBinding

+     

+     **/

+    private IComboBox getIComboBoxDriverBinding() {

+        if (iComboBoxDriverBinding == null) {

+            iComboBoxDriverBinding = new IComboBox();

+            iComboBoxDriverBinding.setBounds(new java.awt.Rectangle(160, 5, 320, 20));

+        }

+        return iComboBoxDriverBinding;

+    }

+

+    /**

+     This method initializes jComboBoxDriverDiag 

+     

+     @return javax.swing.JComboBox iComboBoxDriverDiag

+     

+     **/

+    private IComboBox getIComboBoxDriverDiag() {

+        if (iComboBoxDriverDiag == null) {

+            iComboBoxDriverDiag = new IComboBox();

+            iComboBoxDriverDiag.setBounds(new java.awt.Rectangle(160, 80, 320, 20));

+        }

+        return iComboBoxDriverDiag;

+    }

+

+    /**

+     This method initializes jComboBoxDriverConfig 

+     

+     @return javax.swing.JComboBox iComboBoxDriverConfig

+     

+     */

+    private IComboBox getIComboBoxDriverConfig() {

+        if (iComboBoxDriverConfig == null) {

+            iComboBoxDriverConfig = new IComboBox();

+            iComboBoxDriverConfig.setBounds(new java.awt.Rectangle(160, 55, 320, 20));

+        }

+        return iComboBoxDriverConfig;

+    }

+

+    /**

+     This method initializes jPanelType4 

+     

+     @return javax.swing.JPanel jPanelType4

+     

+     **/

+    private JPanel getJPanelType4() {

+        if (jPanelType4 == null) {

+            jLabelExitBootServicesCallBack = new JLabel();

+            jLabelExitBootServicesCallBack.setBounds(new java.awt.Rectangle(15, 30, 200, 20));

+            jLabelExitBootServicesCallBack.setText("Exit Boot Services Call Back");

+            jLabelSetVirtualAddressMapCallBack = new JLabel();

+            jLabelSetVirtualAddressMapCallBack.setBounds(new java.awt.Rectangle(15, 5, 200, 20));

+            jLabelSetVirtualAddressMapCallBack.setText("Set Virtual Address Map Call Back");

+            jPanelType4 = new JPanel();

+            jPanelType4.setLayout(null);

+            jPanelType4.setBounds(new java.awt.Rectangle(0, 105, 490, 55));

+            jPanelType4.add(jLabelSetVirtualAddressMapCallBack, null);

+            jPanelType4.add(getIComboBoxSetVirtualAddressMapCallBack(), null);

+            jPanelType4.add(jLabelExitBootServicesCallBack, null);

+            jPanelType4.add(getIComboBoxExitBootServicesCallBack(), null);

+        }

+        return jPanelType4;

+    }

+

+    /**

+     This method initializes jComboBoxSetVirtualAddressMapCallBack 

+     

+     @return javax.swing.JComboBox iComboBoxSetVirtualAddressMapCallBack

+     

+     **/

+    private IComboBox getIComboBoxSetVirtualAddressMapCallBack() {

+        if (iComboBoxSetVirtualAddressMapCallBack == null) {

+            iComboBoxSetVirtualAddressMapCallBack = new IComboBox();

+            iComboBoxSetVirtualAddressMapCallBack.setBounds(new java.awt.Rectangle(220, 5, 260, 20));

+        }

+        return iComboBoxSetVirtualAddressMapCallBack;

+    }

+

+    /**

+     This method initializes jComboBoxExitBootServicesCallBack 

+     

+     @return javax.swing.JComboBox iComboBoxExitBootServicesCallBack

+     

+     **/

+    private IComboBox getIComboBoxExitBootServicesCallBack() {

+        if (iComboBoxExitBootServicesCallBack == null) {

+            iComboBoxExitBootServicesCallBack = new IComboBox();

+            iComboBoxExitBootServicesCallBack.setBounds(new java.awt.Rectangle(220, 30, 260, 20));

+        }

+        return iComboBoxExitBootServicesCallBack;

+    }

+

+    /**

+     This method initializes jPanelType5 

+     

+     @return javax.swing.JPanel jPanelType5

+     

+     **/

+    private JPanel getJPanelType5() {

+        if (jPanelType5 == null) {

+            jLabelUserDefined = new JLabel();

+            jLabelUserDefined.setBounds(new java.awt.Rectangle(15, 5, 140, 20));

+            jLabelUserDefined.setText("User Defined");

+            jPanelType5 = new JPanel();

+            jPanelType5.setLayout(null);

+            jPanelType5.setBounds(new java.awt.Rectangle(0, 105, 490, 30));

+            jPanelType5.add(jLabelUserDefined, null);

+            jPanelType5.add(getIComboBoxUserDefined(), null);

+        }

+        return jPanelType5;

+    }

+

+    /**

+     This method initializes jComboBoxUserDefined 

+     

+     @return javax.swing.JComboBox iComboBoxUserDefined

+     

+     **/

+    private IComboBox getIComboBoxUserDefined() {

+        if (iComboBoxUserDefined == null) {

+            iComboBoxUserDefined = new IComboBox();

+            iComboBoxUserDefined.setBounds(new java.awt.Rectangle(160, 5, 320, 20));

+        }

+        return iComboBoxUserDefined;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleExterns() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inExterns The input data of ExternsDocument.Externs

+     

+     **/

+    public ModuleExterns(ExternsDocument.Externs inExterns) {

+        super();

+        init(inExterns);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inExterns The input data of ExternsDocument.Externs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleExterns(ExternsDocument.Externs inExterns, int type, int index) {

+        super();

+        init(inExterns, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inExterns The input data of ExternsDocument.Externs

+     

+     **/

+    private void init(ExternsDocument.Externs inExterns) {

+        init();

+        this.setExterns(inExterns);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inExterns The input data of ExternsDocument.Externs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(ExternsDocument.Externs inExterns, int type, int index) {

+        init(inExterns);

+        this.location = index;

+        if (this.externs.getExternList().size() > 0) {

+            //

+            //Get common fields

+            //

+            if (this.externs.getExternArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.externs.getExternArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.externs.getExternArray(index).getOverrideID()));

+            //

+            //Type 1

+            //

+            if (this.externs.getExternArray(index).getModuleEntryPointList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(0);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getModuleEntryPointList().size(); indexI++) {

+                    this.iComboBoxModuleEntryPoint.addItem(this.externs.getExternArray(index)

+                                                                       .getModuleEntryPointArray(indexI));

+                }

+            }

+            if (this.externs.getExternArray(index).getModuleUnloadImageList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(0);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getModuleUnloadImageList().size(); indexI++) {

+                    this.iComboBoxModuleUnloadImage.addItem(this.externs.getExternArray(index)

+                                                                        .getModuleUnloadImageArray(indexI));

+                }

+            }

+

+            //

+            //Type 2

+            //

+            if (this.externs.getExternArray(index).getConstructor() != null) {

+                this.jComboBoxType.setSelectedIndex(1);

+                this.jTextFieldConstructor.setText(this.externs.getExternArray(index).getConstructor());

+            }

+            if (this.externs.getExternArray(index).getDestructor() != null) {

+                this.jComboBoxType.setSelectedIndex(1);

+                this.jTextFieldDestructor.setText(this.externs.getExternArray(index).getDestructor());

+            }

+

+            //

+            //Type 3

+            //

+            if (this.externs.getExternArray(index).getDriverBindingList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(2);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getDriverBindingList().size(); indexI++) {

+                    this.iComboBoxDriverBinding.addItem(this.externs.getExternArray(index)

+                                                                    .getDriverBindingArray(indexI));

+                }

+            }

+            if (this.externs.getExternArray(index).getComponentNameList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(2);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getComponentNameList().size(); indexI++) {

+                    this.iComboBoxComponentName.addItem(this.externs.getExternArray(index)

+                                                                    .getComponentNameArray(indexI));

+                }

+            }

+            if (this.externs.getExternArray(index).getDriverConfigList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(2);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getDriverConfigList().size(); indexI++) {

+                    this.iComboBoxDriverConfig.addItem(this.externs.getExternArray(index).getDriverConfigArray(indexI));

+                }

+            }

+            if (this.externs.getExternArray(index).getDriverDiagList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(2);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getDriverDiagList().size(); indexI++) {

+                    this.iComboBoxDriverDiag.addItem(this.externs.getExternArray(index).getDriverDiagArray(indexI));

+                }

+            }

+

+            //

+            //Type 4

+            //

+            if (this.externs.getExternArray(index).getSetVirtualAddressMapCallBackList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(3);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getSetVirtualAddressMapCallBackList()

+                                                          .size(); indexI++) {

+                    this.iComboBoxSetVirtualAddressMapCallBack

+                                                              .addItem(this.externs

+                                                                                   .getExternArray(index)

+                                                                                   .getSetVirtualAddressMapCallBackArray(

+                                                                                                                         indexI));

+                }

+            }

+            if (this.externs.getExternArray(index).getExitBootServicesCallBackList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(3);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getExitBootServicesCallBackList()

+                                                          .size(); indexI++) {

+                    this.iComboBoxExitBootServicesCallBack

+                                                          .addItem(this.externs

+                                                                               .getExternArray(index)

+                                                                               .getExitBootServicesCallBackArray(indexI));

+                }

+            }

+

+            //

+            //Type 5

+            //

+            if (this.externs.getExternArray(index).getUserDefinedList().size() > 0) {

+                this.jComboBoxType.setSelectedIndex(4);

+                for (int indexI = 0; indexI < this.externs.getExternArray(index).getUserDefinedList().size(); indexI++) {

+                    this.iComboBoxUserDefined.addItem(this.externs.getExternArray(index).getUserDefinedArray(indexI));

+                }

+            }

+

+            this.jComboBoxType.setEnabled(false);

+            switchType();

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Externs");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            //

+            //Type 1

+            //

+            this.iComboBoxModuleEntryPoint.setEnabled(!isView);

+            this.iComboBoxModuleUnloadImage.setEnabled(!isView);

+

+            //

+            //Type 2

+            //

+            this.jTextFieldConstructor.setEnabled(!isView);

+            this.jTextFieldDestructor.setEnabled(!isView);

+

+            //

+            //Type 3

+            //

+            this.iComboBoxDriverBinding.setEnabled(!isView);

+            this.iComboBoxComponentName.setEnabled(!isView);

+            this.iComboBoxDriverConfig.setEnabled(!isView);

+            this.iComboBoxDriverDiag.setEnabled(!isView);

+

+            //

+            //Type 4

+            //

+            this.iComboBoxSetVirtualAddressMapCallBack.setEnabled(!isView);

+            this.iComboBoxExitBootServicesCallBack.setEnabled(!isView);

+

+            //

+            //Type 5

+            //

+            this.iComboBoxUserDefined.setEnabled(!isView);

+

+            this.jComboBoxType.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelName = new JLabel();

+            jLabelName.setText("Choose Type");

+            jLabelName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setSize(new java.awt.Dimension(490, 244));

+            jContentPane.add(getJPanelType2(), null);

+            jContentPane.add(jLabelName, null);

+            jContentPane.add(getJComboBoxType(), null);

+            jContentPane.add(getJPanelType3(), null);

+            jContentPane.add(getJPanelType4(), null);

+            jContentPane.add(getJPanelType5(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jContentPane.add(getJPanelType1(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type and Externs type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+

+        jComboBoxType.addItem("Entry/Unload");

+        jComboBoxType.addItem("Library");

+        jComboBoxType.addItem("Driver Bindings");

+        jComboBoxType.addItem("Call Backs");

+        jComboBoxType.addItem("Other");

+

+        jPanelType1.setVisible(true);

+        jPanelType2.setVisible(false);

+        jPanelType3.setVisible(false);

+        jPanelType4.setVisible(false);

+        jPanelType5.setVisible(false);

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+    }

+

+    public void itemStateChanged(ItemEvent arg0) {

+        if (arg0.getSource() == jComboBoxType) {

+            if (arg0.getStateChange() == ItemEvent.SELECTED) {

+                switchType();

+            }

+        }

+    }

+

+    /**

+     Show/Hide relevant fields via select different types

+     

+     **/

+    private void switchType() {

+        if (jComboBoxType.getSelectedIndex() == 0) {

+            jPanelType1.setVisible(true);

+            jPanelType2.setVisible(false);

+            jPanelType3.setVisible(false);

+            jPanelType4.setVisible(false);

+            jPanelType5.setVisible(false);

+        }

+        if (jComboBoxType.getSelectedIndex() == 1) {

+            jPanelType1.setVisible(false);

+            jPanelType2.setVisible(true);

+            jPanelType3.setVisible(false);

+            jPanelType4.setVisible(false);

+            jPanelType5.setVisible(false);

+        }

+        if (jComboBoxType.getSelectedIndex() == 2) {

+            jPanelType1.setVisible(false);

+            jPanelType2.setVisible(false);

+            jPanelType3.setVisible(true);

+            jPanelType4.setVisible(false);

+            jPanelType5.setVisible(false);

+        }

+        if (jComboBoxType.getSelectedIndex() == 3) {

+            jPanelType1.setVisible(false);

+            jPanelType2.setVisible(false);

+            jPanelType3.setVisible(false);

+            jPanelType4.setVisible(true);

+            jPanelType5.setVisible(false);

+        }

+        if (jComboBoxType.getSelectedIndex() == 4) {

+            jPanelType1.setVisible(false);

+            jPanelType2.setVisible(false);

+            jPanelType3.setVisible(false);

+            jPanelType4.setVisible(false);

+            jPanelType5.setVisible(true);

+        }

+    }

+

+    /**

+     Set ExternsDocument.Externs

+     

+     @return ExternsDocument.Externs

+     

+     

+     **/

+    public ExternsDocument.Externs getExterns() {

+        return externs;

+    }

+

+    /**

+     Get ExternsDocument.Externs

+     

+     @param externs The input ExternsDocument.Externs

+     

+     **/

+    public void setExterns(ExternsDocument.Externs externs) {

+        this.externs = externs;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all fields have correct data types 

+        //

+        if (this.jComboBoxType.getSelectedIndex() == 1) {

+            if (!isEmpty(this.jTextFieldConstructor.getText())

+                && !DataValidation.isConstructor(this.jTextFieldConstructor.getText())) {

+                Log.err("Incorrect data type for Constructor");

+                return false;

+            }

+            if (!isEmpty(this.jTextFieldDestructor.getText())

+                && !DataValidation.isDestructor(this.jTextFieldDestructor.getText())) {

+                Log.err("Incorrect data type for Destructor");

+                return false;

+            }

+        }

+

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Externs

+     if exists externs, set the value directly

+     if not exists externs, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.externs == null) {

+                externs = ExternsDocument.Externs.Factory.newInstance();

+            }

+            ExternsDocument.Externs.Extern extern = ExternsDocument.Externs.Extern.Factory.newInstance();

+            //

+            //Save common fields

+            //

+            extern.setUsage(ExternUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                extern.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+

+            //

+            //Save type 1

+            //

+            if (this.jComboBoxType.getSelectedIndex() == 0) {

+                if (this.iComboBoxModuleEntryPoint.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxModuleEntryPoint.getItemCount(); index++) {

+                        extern.addNewModuleEntryPoint();

+                        extern.setModuleEntryPointArray(index, this.iComboBoxModuleEntryPoint.getItemAt(index)

+                                                                                             .toString());

+                    }

+                }

+                if (this.iComboBoxModuleEntryPoint.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxModuleUnloadImage.getItemCount(); index++) {

+                        extern.addNewModuleUnloadImage();

+                        extern.setModuleUnloadImageArray(index, this.iComboBoxModuleUnloadImage.getItemAt(index)

+                                                                                               .toString());

+                    }

+                }

+            }

+

+            //

+            //Save type 2

+            //

+            if (this.jComboBoxType.getSelectedIndex() == 1) {

+                if (!isEmpty(this.jTextFieldConstructor.getText())) {

+                    extern.setConstructor(this.jTextFieldConstructor.getText());

+                }

+                if (!isEmpty(this.jTextFieldDestructor.getText())) {

+                    extern.setDestructor(this.jTextFieldDestructor.getText());

+                }

+            }

+

+            //

+            //Save type 3

+            //

+            if (this.jComboBoxType.getSelectedIndex() == 2) {

+                if (this.iComboBoxDriverBinding.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxDriverBinding.getItemCount(); index++) {

+                        extern.addNewDriverBinding();

+                        extern.setDriverBindingArray(index, this.iComboBoxDriverBinding.getItemAt(index).toString());

+                    }

+                }

+                if (this.iComboBoxComponentName.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxComponentName.getItemCount(); index++) {

+                        extern.addNewComponentName();

+                        extern.setComponentNameArray(index, this.iComboBoxComponentName.getItemAt(index).toString());

+                    }

+                }

+                if (this.iComboBoxDriverConfig.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxDriverConfig.getItemCount(); index++) {

+                        extern.addNewDriverConfig();

+                        extern.setDriverConfigArray(index, this.iComboBoxDriverConfig.getItemAt(index).toString());

+                    }

+                }

+                if (this.iComboBoxDriverDiag.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxDriverDiag.getItemCount(); index++) {

+                        extern.addNewDriverDiag();

+                        extern.setDriverDiagArray(index, this.iComboBoxDriverDiag.getItemAt(index).toString());

+                    }

+                }

+            }

+

+            //

+            //Save type 4

+            //

+            if (this.jComboBoxType.getSelectedIndex() == 3) {

+                if (this.iComboBoxSetVirtualAddressMapCallBack.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxSetVirtualAddressMapCallBack.getItemCount(); index++) {

+                        extern.addNewSetVirtualAddressMapCallBack();

+                        extern

+                              .setSetVirtualAddressMapCallBackArray(

+                                                                    index,

+                                                                    this.iComboBoxSetVirtualAddressMapCallBack

+                                                                                                              .getItemAt(

+                                                                                                                         index)

+                                                                                                              .toString());

+                    }

+                }

+                if (this.iComboBoxExitBootServicesCallBack.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxExitBootServicesCallBack.getItemCount(); index++) {

+                        extern.addNewExitBootServicesCallBack();

+                        extern.setExitBootServicesCallBackArray(index,

+                                                                this.iComboBoxExitBootServicesCallBack.getItemAt(index)

+                                                                                                      .toString());

+                    }

+                }

+            }

+            //

+            //Save type 5

+            //

+            if (this.jComboBoxType.getSelectedIndex() == 4) {

+                if (this.iComboBoxUserDefined.getItemCount() > 0) {

+                    for (int index = 0; index < this.iComboBoxUserDefined.getItemCount(); index++) {

+                        extern.addNewUserDefined();

+                        extern.setUserDefinedArray(index, this.iComboBoxUserDefined.getItemAt(index).toString());

+                    }

+                }

+            }

+

+            if (location > -1) {

+                externs.setExternArray(location, extern);

+            } else {

+                externs.addNewExtern();

+                externs.setExternArray(externs.getExternList().size() - 1, extern);

+            }

+        } catch (Exception e) {

+            Log.err("Update Externs", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleFormsets.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleFormsets.java
new file mode 100644
index 0000000..192c029
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleFormsets.java
@@ -0,0 +1,457 @@
+/** @file

+ 

+ The file is used to create, update Formset of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.FormSetUsage;

+import org.tianocore.FormsetsDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Formset of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleFormsets extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -6851574146786158116L;

+

+    //

+    //Define class members

+    //

+    private FormsetsDocument.Formsets formsets = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelName = null;

+

+    private JTextField jTextFieldName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    /**

+     This method initializes jTextFieldName 

+     

+     @return javax.swing.JTextField jTextFieldName

+     

+     **/

+    private JTextField getJTextFieldName() {

+        if (jTextFieldName == null) {

+            jTextFieldName = new JTextField();

+            jTextFieldName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(280, 115, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 115, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 85, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleFormsets() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     * 

+     */

+    /**

+     This is the override edit constructor

+     

+     @param inFormsets The input data of FormsetsDocument.Formsets

+     

+     **/

+    public ModuleFormsets(FormsetsDocument.Formsets inFormsets) {

+        super();

+        init(inFormsets);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inFormsets The input data of FormsetsDocument.Formsets

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleFormsets(FormsetsDocument.Formsets inFormsets, int type, int index) {

+        super();

+        init(inFormsets, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inFormsets The input data of FormsetsDocument.Formsets

+     

+     **/

+    private void init(FormsetsDocument.Formsets inFormsets) {

+        init();

+        this.setFormsets(inFormsets);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inFormsets The input data of FormsetsDocument.Formsets

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(FormsetsDocument.Formsets inFormsets, int type, int index) {

+        init(inFormsets);

+        this.location = index;

+        if (this.formsets.getFormsetList().size() > 0) {

+            if (this.formsets.getFormsetArray(index).getStringValue() != null) {

+                this.jTextFieldName.setText(this.formsets.getFormsetArray(index).getStringValue().toString());

+            }

+            if (this.formsets.getFormsetArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.formsets.getFormsetArray(index).getGuid());

+            }

+            if (this.formsets.getFormsetArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.formsets.getFormsetArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.formsets.getFormsetArray(index).getOverrideID()));

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Form Sets");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 515));

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelName = new JLabel();

+            jLabelName.setText("Name");

+            jLabelName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelName, null);

+            jContentPane.add(getJTextFieldName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Set FormsetsDocument.Formsets

+     

+     @return FormsetsDocument.Formsets

+     

+     **/

+    public FormsetsDocument.Formsets getFormsets() {

+        return formsets;

+    }

+

+    /**

+     Get FormsetsDocument.Formsets

+     

+     @param formsets The input FormsetsDocument.Formsets

+     

+     **/

+    public void setFormsets(FormsetsDocument.Formsets formsets) {

+        this.formsets = formsets;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldName.getText())) {

+            Log.err("Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isCName(this.jTextFieldName.getText())) {

+            Log.err("Incorrect data type for Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Formsets

+     if exists formset, set the value directly

+     if not exists formset, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.formsets == null) {

+                formsets = FormsetsDocument.Formsets.Factory.newInstance();

+            }

+            FormsetsDocument.Formsets.Formset formset = FormsetsDocument.Formsets.Formset.Factory.newInstance();

+            if (!isEmpty(this.jTextFieldName.getText())) {

+                formset.setStringValue(this.jTextFieldName.getText());

+            }

+            if (!isEmpty(this.jTextFieldGuid.getText())) {

+                formset.setGuid(this.jTextFieldGuid.getText());

+            }

+            formset.setUsage(FormSetUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                formset.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+            if (location > -1) {

+                formsets.setFormsetArray(location, formset);

+            } else {

+                formsets.addNewFormset();

+                formsets.setFormsetArray(formsets.getFormsetList().size() - 1, formset);

+            }

+        } catch (Exception e) {

+            Log.err("Update Formsets", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleGuids.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleGuids.java
new file mode 100644
index 0000000..c4ac34b
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleGuids.java
@@ -0,0 +1,675 @@
+/** @file

+ 

+ The file is used to create, update Guids of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+

+import org.tianocore.ConditionalExpressionDocument;

+import org.tianocore.DefaultValueDocument;

+import org.tianocore.GuidUsage;

+import org.tianocore.GuidsDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IComboBox;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Guids of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleGuids extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 6710858997766979803L;

+

+    //

+    //Define class members

+    //

+    private GuidsDocument.Guids guids = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuidValue = null;

+

+    private JTextField jTextFieldGuidValue = null;

+

+    private JLabel jLabelFeatureFlag = null;

+

+    private IComboBox iComboBoxFeatureFlag = null;

+

+    private JLabel jLabelConditionalExpression = null;

+

+    private IComboBox iComboBoxConditionalExpression = null;

+

+    private JLabel jLabelDefault = null;

+

+    private JTextField jTextFieldDefaultValue = null;

+

+    private JLabel jLabelHelpText = null;

+

+    private JTextField jTextFieldHelpText = null;

+

+    private JLabel jLabelEnableFeature = null;

+

+    private JRadioButton jRadioButtonEnableFeature = null;

+

+    private JRadioButton jRadioButtonDisableFeature = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    /**

+     This method initializes jTextFieldC_Name 

+     

+     @return javax.swing.JTextField jTextFieldC_Name

+     

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldGuidValsue 

+     

+     @return javax.swing.JTextField jTextFieldGuidValue

+     

+     **/

+    private JTextField getJTextFieldGuidValsue() {

+        if (jTextFieldGuidValue == null) {

+            jTextFieldGuidValue = new JTextField();

+            jTextFieldGuidValue.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuidValue;

+    }

+

+    /**

+     This method initializes jTextFieldFeatureFlag 

+     

+     @return javax.swing.JTextField iComboBoxFeatureFlag

+     

+     **/

+    private IComboBox getIComboBoxFeatureFlag() {

+        if (iComboBoxFeatureFlag == null) {

+            iComboBoxFeatureFlag = new IComboBox();

+            iComboBoxFeatureFlag.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return iComboBoxFeatureFlag;

+    }

+

+    /**

+     This method initializes jTextFieldConditionalExpression 

+     

+     @return javax.swing.JTextField iComboBoxConditionalExpression

+     

+     **/

+    private IComboBox getIComboBoxConditionalExpression() {

+        if (iComboBoxConditionalExpression == null) {

+            iComboBoxConditionalExpression = new IComboBox();

+            iComboBoxConditionalExpression.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return iComboBoxConditionalExpression;

+    }

+

+    /**

+     This method initializes jTextFieldDefault 

+     

+     @return javax.swing.JTextField jTextFieldDefaultValue

+     

+     **/

+    private JTextField getJTextFieldDefaultValue() {

+        if (jTextFieldDefaultValue == null) {

+            jTextFieldDefaultValue = new JTextField();

+            jTextFieldDefaultValue.setBounds(new java.awt.Rectangle(160, 110, 320, 20));

+        }

+        return jTextFieldDefaultValue;

+    }

+

+    /**

+     This method initializes jTextFieldHelpText 

+     

+     @return javax.swing.JTextField jTextFieldHelpText

+     

+     **/

+    private JTextField getJTextFieldHelpText() {

+        if (jTextFieldHelpText == null) {

+            jTextFieldHelpText = new JTextField();

+            jTextFieldHelpText.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jTextFieldHelpText;

+    }

+

+    /**

+     This method initializes jRadioButtonEnableFeature 

+     

+     @return javax.swing.JRadioButton jRadioButtonEnableFeature

+     

+     **/

+    private JRadioButton getJRadioButtonEnableFeature() {

+        if (jRadioButtonEnableFeature == null) {

+            jRadioButtonEnableFeature = new JRadioButton();

+            jRadioButtonEnableFeature.setText("Enable");

+            jRadioButtonEnableFeature.setBounds(new java.awt.Rectangle(160, 160, 90, 20));

+            jRadioButtonEnableFeature.setSelected(true);

+            jRadioButtonEnableFeature.addActionListener(this);

+        }

+        return jRadioButtonEnableFeature;

+    }

+

+    /**

+     This method initializes jRadioButtonDisableFeature 

+     

+     @return javax.swing.JRadioButton jRadioButtonDisableFeature

+     

+     **/

+    private JRadioButton getJRadioButtonDisableFeature() {

+        if (jRadioButtonDisableFeature == null) {

+            jRadioButtonDisableFeature = new JRadioButton();

+            jRadioButtonDisableFeature.setText("Disable");

+            jRadioButtonDisableFeature.setBounds(new java.awt.Rectangle(320, 160, 90, 20));

+            jRadioButtonDisableFeature.addActionListener(this);

+        }

+        return jRadioButtonDisableFeature;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 185, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 240, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 240, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 210, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleGuids() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inGuids The input data of GuidsDocument.Guids

+     

+     **/

+    public ModuleGuids(GuidsDocument.Guids inGuids) {

+        super();

+        init(inGuids);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inGuids The input data of GuidsDocument.Guids

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleGuids(GuidsDocument.Guids inGuids, int type, int index) {

+        super();

+        init(inGuids, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inGuids The input data of GuidsDocument.Guids

+     

+     **/

+    private void init(GuidsDocument.Guids inGuids) {

+        init();

+        this.setGuids(inGuids);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inGuids The input data of GuidsDocument.Guids

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(GuidsDocument.Guids inGuids, int type, int index) {

+        init(inGuids);

+        this.location = index;

+        if (this.guids.getGuidEntryList().size() > 0) {

+            if (this.guids.getGuidEntryArray(index).getCName() != null) {

+                this.jTextFieldC_Name.setText(this.guids.getGuidEntryArray(index).getCName());

+            }

+            if (this.guids.getGuidEntryArray(index).getGuidValue() != null) {

+                this.jTextFieldGuidValue.setText(this.guids.getGuidEntryArray(index).getGuidValue());

+            }

+            if (this.guids.getGuidEntryArray(index).getFeatureFlagList().size() > 0) {

+                for (int indexI = 0; indexI < this.guids.getGuidEntryArray(index).getFeatureFlagList().size(); indexI++) {

+                    this.iComboBoxFeatureFlag.addItem(this.guids.getGuidEntryArray(index).getFeatureFlagArray(indexI));

+                }

+            }

+            if (this.guids.getGuidEntryArray(index).getConditionalExpressionList().size() > 0) {

+                for (int indexI = 0; indexI < this.guids.getGuidEntryArray(index).getConditionalExpressionArray(0)

+                                                        .getConditionList().size(); indexI++) {

+                    this.iComboBoxConditionalExpression.addItem(this.guids.getGuidEntryArray(index)

+                                                                          .getConditionalExpressionArray(0)

+                                                                          .getConditionArray(indexI));

+                }

+            }

+            if (this.guids.getGuidEntryArray(index).getDefaultValue() != null) {

+                this.jTextFieldDefaultValue.setText(this.guids.getGuidEntryArray(index).getDefaultValue()

+                                                              .getStringValue());

+            }

+            if (this.guids.getGuidEntryArray(index).getHelpText() != null) {

+                this.jTextFieldHelpText.setText(this.guids.getGuidEntryArray(index).getHelpText());

+            }

+            if (this.guids.getGuidEntryArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.guids.getGuidEntryArray(index).getUsage().toString());

+            }

+            this.jRadioButtonEnableFeature.setSelected(this.guids.getGuidEntryArray(index).getEnableFeature());

+            this.jRadioButtonDisableFeature.setSelected(!this.guids.getGuidEntryArray(index).getEnableFeature());

+            this.jTextFieldOverrideID.setText(String.valueOf(this.guids.getGuidEntryArray(index).getOverrideID()));

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Guids");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldC_Name.setEnabled(!isView);

+            this.jTextFieldGuidValue.setEnabled(!isView);

+            this.iComboBoxFeatureFlag.setEnabled(!isView);

+            this.iComboBoxConditionalExpression.setEnabled(!isView);

+            this.jTextFieldDefaultValue.setEnabled(!isView);

+            this.jTextFieldHelpText.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jRadioButtonEnableFeature.setEnabled(!isView);

+            this.jRadioButtonDisableFeature.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 210, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 185, 140, 20));

+            jLabelEnableFeature = new JLabel();

+            jLabelEnableFeature.setText("Enable Feature");

+            jLabelEnableFeature.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelHelpText = new JLabel();

+            jLabelHelpText.setText("Help Text");

+            jLabelHelpText.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelDefault = new JLabel();

+            jLabelDefault.setText("Default Value");

+            jLabelDefault.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelConditionalExpression = new JLabel();

+            jLabelConditionalExpression.setText("Conditional Expression");

+            jLabelConditionalExpression.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelFeatureFlag = new JLabel();

+            jLabelFeatureFlag.setText("Feature Flag");

+            jLabelFeatureFlag.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuidValue = new JLabel();

+            jLabelGuidValue.setText("Guid Value");

+            jLabelGuidValue.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(jLabelGuidValue, null);

+            jContentPane.add(getJTextFieldGuidValsue(), null);

+            jContentPane.add(jLabelFeatureFlag, null);

+            jContentPane.add(getIComboBoxFeatureFlag(), null);

+            jContentPane.add(jLabelConditionalExpression, null);

+            jContentPane.add(getIComboBoxConditionalExpression(), null);

+            jContentPane.add(jLabelDefault, null);

+            jContentPane.add(getJTextFieldDefaultValue(), null);

+            jContentPane.add(jLabelHelpText, null);

+            jContentPane.add(getJTextFieldHelpText(), null);

+            jContentPane.add(jLabelEnableFeature, null);

+            jContentPane.add(getJRadioButtonEnableFeature(), null);

+            jContentPane.add(getJRadioButtonDisableFeature(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            StarLabel jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+

+            initFrame();

+

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("DEFAULT");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuidValue.setText(Tools.generateUuidString());

+        }

+

+        //

+        //Contorl the selected status when click RadionButton

+        //Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonEnableFeature) {

+            if (jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonDisableFeature) {

+            if (jRadioButtonDisableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(true);

+            }

+        }

+    }

+

+    /**

+     Get GuidsDocument.Guids

+     

+     @return GuidsDocument.Guids

+     

+     **/

+    public GuidsDocument.Guids getGuids() {

+        return guids;

+    }

+

+    /**

+     Set GuidsDocument.Guids

+     

+     @param guids The input GuidsDocument.Guids

+     

+     **/

+    public void setGuids(GuidsDocument.Guids guids) {

+        this.guids = guids;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldC_Name.getText())) {

+            Log.err("C_Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isCName(this.jTextFieldC_Name.getText())) {

+            Log.err("Incorrect data type for C_Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuidValue.getText()) && !DataValidation.isGuid(this.jTextFieldGuidValue.getText())) {

+            Log.err("Incorrect data type for Guid Value");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Guids

+     if exists guids, set the value directly

+     if not exists guids, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.guids == null) {

+                guids = GuidsDocument.Guids.Factory.newInstance();

+            }

+            GuidsDocument.Guids.GuidEntry guid = GuidsDocument.Guids.GuidEntry.Factory.newInstance();

+            if (!isEmpty(this.jTextFieldC_Name.getText())) {

+                guid.setCName(this.jTextFieldC_Name.getText());

+            }

+            if (!isEmpty(this.jTextFieldGuidValue.getText())) {

+                guid.setGuidValue(this.jTextFieldGuidValue.getText());

+            }

+            if (this.iComboBoxFeatureFlag.getItemCount() > 0) {

+                for (int index = 0; index < this.iComboBoxFeatureFlag.getItemCount(); index++) {

+                    guid.addNewFeatureFlag();

+                    guid.setFeatureFlagArray(index, this.iComboBoxFeatureFlag.getItemAt(index).toString());

+                }

+            }

+            if (this.iComboBoxConditionalExpression.getItemCount() > 0) {

+                ConditionalExpressionDocument.ConditionalExpression ce = ConditionalExpressionDocument.ConditionalExpression.Factory

+                                                                                                                                    .newInstance();

+                for (int index = 0; index < this.iComboBoxConditionalExpression.getItemCount(); index++) {

+                    ce.addCondition(this.iComboBoxConditionalExpression.getItemAt(index).toString());

+                }

+                if (guid.getConditionalExpressionList().size() < 1) {

+                    guid.addNewConditionalExpression();

+                }

+                guid.setConditionalExpressionArray(0, ce);

+            }

+            if (!isEmpty(this.jTextFieldDefaultValue.getText())) {

+                DefaultValueDocument.DefaultValue dv = DefaultValueDocument.DefaultValue.Factory.newInstance();

+                dv.setStringValue(this.jTextFieldDefaultValue.getText());

+                guid.setDefaultValue(dv);

+            }

+            if (!isEmpty(this.jTextFieldHelpText.getText())) {

+                guid.setHelpText(this.jTextFieldHelpText.getText());

+            }

+            guid.setUsage(GuidUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            guid.setEnableFeature(this.jRadioButtonEnableFeature.isSelected());

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                guid.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+

+            if (location > -1) {

+                guids.setGuidEntryArray(location, guid);

+            } else {

+                guids.addNewGuidEntry();

+                guids.setGuidEntryArray(guids.getGuidEntryList().size() - 1, guid);

+            }

+        } catch (Exception e) {

+            Log.err("Update Guids", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleHobs.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleHobs.java
new file mode 100644
index 0000000..0ea8ac8
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleHobs.java
@@ -0,0 +1,596 @@
+/** @file

+ 

+ The file is used to create, update Hob of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+

+import org.tianocore.GuidDocument;

+import org.tianocore.HobTypes;

+import org.tianocore.HobUsage;

+import org.tianocore.HobsDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Hob of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleHobs extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -553473437579358325L;

+

+    //

+    //Define class members

+    //

+    private HobsDocument.Hobs hobs = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabel = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelName = null;

+

+    private JTextField jTextFieldName = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JLabel jLabelHobType = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JComboBox jComboBoxHobType = null;

+

+    private JLabel jLabelHobEnabled = null;

+

+    private JRadioButton jRadioButtonHobEnable = null;

+

+    private JRadioButton jRadioButtonHobDisable = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    /**

+     This method initializes jTextField 

+     

+     @return javax.swing.JTextField jTextFieldC_Name

+     

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextField 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 60, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldName 

+     

+     @return javax.swing.JTextField jTextFieldName

+     

+     **/

+    private JTextField getJTextFieldName() {

+        if (jTextFieldName == null) {

+            jTextFieldName = new JTextField();

+            jTextFieldName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldName;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jComboBoxHobType 

+     

+     @return javax.swing.JComboBox jComboBoxHobType

+     

+     **/

+    private JComboBox getJComboBoxHobType() {

+        if (jComboBoxHobType == null) {

+            jComboBoxHobType = new JComboBox();

+            jComboBoxHobType.setBounds(new java.awt.Rectangle(160, 110, 320, 20));

+        }

+        return jComboBoxHobType;

+    }

+

+    /**

+     This method initializes jRadioButtonEnable 

+     

+     @return javax.swing.JRadioButton jRadioButtonHobEnable

+     

+     **/

+    private JRadioButton getJRadioButtonHobEnable() {

+        if (jRadioButtonHobEnable == null) {

+            jRadioButtonHobEnable = new JRadioButton();

+            jRadioButtonHobEnable.setText("Enable");

+            jRadioButtonHobEnable.setBounds(new java.awt.Rectangle(160, 135, 90, 20));

+            jRadioButtonHobEnable.setSelected(true);

+            jRadioButtonHobEnable.addActionListener(this);

+        }

+        return jRadioButtonHobEnable;

+    }

+

+    /**

+     This method initializes jRadioButtonDisable 

+     

+     @return javax.swing.JRadioButton jRadioButtonHobDisable

+     

+     **/

+    private JRadioButton getJRadioButtonHobDisable() {

+        if (jRadioButtonHobDisable == null) {

+            jRadioButtonHobDisable = new JRadioButton();

+            jRadioButtonHobDisable.setText("Disable");

+            jRadioButtonHobDisable.setBounds(new java.awt.Rectangle(320, 135, 90, 20));

+            jRadioButtonHobDisable.addActionListener(this);

+        }

+        return jRadioButtonHobDisable;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 190, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 190, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 60, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 160, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleHobs() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inHobs The input data of HobsDocument.Hobs

+     

+     **/

+    public ModuleHobs(HobsDocument.Hobs inHobs) {

+        super();

+        init(inHobs);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inHobs The input data of HobsDocument.Hobs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleHobs(HobsDocument.Hobs inHobs, int type, int index) {

+        super();

+        init(inHobs, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inHobs The input data of HobsDocument.Hobs

+     

+     **/

+    private void init(HobsDocument.Hobs inHobs) {

+        init();

+        this.setHobs(inHobs);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inHobs The input data of HobsDocument.Hobs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(HobsDocument.Hobs inHobs, int type, int index) {

+        init(inHobs);

+        this.location = index;

+        if (this.hobs.getHobList().size() > 0) {

+            if (this.hobs.getHobArray(index).getName() != null) {

+                this.jTextFieldName.setText(this.hobs.getHobArray(index).getName());

+            }

+            if (this.hobs.getHobArray(index).getCName() != null) {

+                this.jTextFieldC_Name.setText(this.hobs.getHobArray(index).getCName());

+            }

+            if (this.hobs.getHobArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.hobs.getHobArray(index).getGuid().getStringValue());

+            }

+            if (this.hobs.getHobArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.hobs.getHobArray(index).getUsage().toString());

+            }

+            this.jRadioButtonHobEnable.setSelected(this.hobs.getHobArray(index).getHobEnabled());

+            this.jRadioButtonHobDisable.setSelected(!this.hobs.getHobArray(index).getHobEnabled());

+            this.jTextFieldOverrideID.setText(String.valueOf(this.hobs.getHobArray(index).getOverrideID()));

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Hobs");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldName.setEnabled(!isView);

+            this.jTextFieldC_Name.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jComboBoxHobType.setEnabled(!isView);

+            this.jRadioButtonHobEnable.setEnabled(!isView);

+            this.jRadioButtonHobDisable.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    public JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelHobEnabled = new JLabel();

+            jLabelHobEnabled.setText("Hob Enabled");

+            jLabelHobEnabled.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelHobType = new JLabel();

+            jLabelHobType.setText("Hob Type");

+            jLabelHobType.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelName = new JLabel();

+            jLabelName.setText("Name");

+            jLabelName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabel = new JLabel();

+            jLabel.setText("C_Name");

+            jLabel.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(jLabelName, null);

+            jContentPane.add(getJTextFieldName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(jLabelHobType, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJComboBoxHobType(), null);

+            jContentPane.add(jLabelHobEnabled, null);

+            jContentPane.add(getJRadioButtonHobEnable(), null);

+            jContentPane.add(getJRadioButtonHobDisable(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jContentPane.add(jStarLabel1, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type and Hob type

+     

+     **/

+    private void initFrame() {

+        jComboBoxHobType.addItem("PHIT");

+        jComboBoxHobType.addItem("MEMORY_ALLOCATION");

+        jComboBoxHobType.addItem("RESOURCE_DESCRIPTOR");

+        jComboBoxHobType.addItem("GUID_EXTENSION");

+        jComboBoxHobType.addItem("FIRMWARE_VOLUME");

+        jComboBoxHobType.addItem("CPU");

+        jComboBoxHobType.addItem("POOL");

+        jComboBoxHobType.addItem("CAPSULE_VOLUME");

+

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        //

+        // Contorl the selected status when click RadionButton

+        // Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonHobEnable) {

+            if (jRadioButtonHobEnable.isSelected()) {

+                jRadioButtonHobDisable.setSelected(false);

+            }

+            if (!jRadioButtonHobDisable.isSelected() && !jRadioButtonHobEnable.isSelected()) {

+                jRadioButtonHobEnable.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonHobDisable) {

+            if (jRadioButtonHobDisable.isSelected()) {

+                jRadioButtonHobEnable.setSelected(false);

+            }

+            if (!jRadioButtonHobDisable.isSelected() && !jRadioButtonHobEnable.isSelected()) {

+                jRadioButtonHobDisable.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Get HobsDocument.Hobs

+     

+     @return HobsDocument.Hobs

+     

+     **/

+    public HobsDocument.Hobs getHobs() {

+        return hobs;

+    }

+

+    /**

+     Set HobsDocument.Hobs

+     

+     @param hobs The input data of HobsDocument.Hobs

+     

+     **/

+    public void setHobs(HobsDocument.Hobs hobs) {

+        this.hobs = hobs;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldName.getText())) {

+            Log.err("Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isCName(this.jTextFieldC_Name.getText())) {

+            Log.err("Incorrect data type for C_Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Hobs

+     if exists hobs, set the value directly

+     if not exists hobs, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.hobs == null) {

+                hobs = HobsDocument.Hobs.Factory.newInstance();

+            }

+            HobsDocument.Hobs.Hob hob = HobsDocument.Hobs.Hob.Factory.newInstance();

+            if (!isEmpty(this.jTextFieldName.getText())) {

+                hob.setName(this.jTextFieldName.getText());

+            }

+            if (!isEmpty(this.jTextFieldC_Name.getText())) {

+                hob.setCName(this.jTextFieldC_Name.getText());

+            }

+            if (!isEmpty(this.jTextFieldGuid.getText())) {

+                GuidDocument.Guid guid = GuidDocument.Guid.Factory.newInstance();

+                guid.setStringValue(this.jTextFieldGuid.getText());

+                hob.setGuid(guid);

+            }

+            hob.setUsage(HobUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            hob.setHobType(HobTypes.Enum.forString(jComboBoxHobType.getSelectedItem().toString()));

+            hob.setHobEnabled(this.jRadioButtonHobEnable.isSelected());

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                hob.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+            if (location > -1) {

+                hobs.setHobArray(location, hob);

+            } else {

+                hobs.addNewHob();

+                hobs.setHobArray(hobs.getHobList().size() - 1, hob);

+            }

+        } catch (Exception e) {

+            Log.err("Update Hobs", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleIncludes.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleIncludes.java
new file mode 100644
index 0000000..b4dcce7
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleIncludes.java
@@ -0,0 +1,865 @@
+/** @file

+ 

+ The file is used to create, update Include of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.ItemEvent;

+import java.awt.event.ItemListener;

+import java.util.Vector;

+

+import javax.swing.JButton;

+import javax.swing.JCheckBox;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.IncludesDocument;

+import org.tianocore.PackageNameDocument;

+import org.tianocore.PackageType;

+import org.tianocore.PackageUsage;

+import org.tianocore.SupportedArchitectures;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+import org.tianocore.packaging.workspace.common.Workspace;

+

+/**

+ The class is used to create, update Include of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleIncludes extends IInternalFrame implements ItemListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 3465193035145152131L;

+

+    //

+    //Define class members

+    //

+    private IncludesDocument.Includes includes = null;

+

+    private int location = -1;

+    

+    private int intSelectedItemId = 0;

+

+    //

+    //  1 - Add; 2 - Update

+    //

+    private int operation = -1;

+

+    private Vector<String> vPackageName = new Vector<String>();

+

+    private Vector<String> vUsage = new Vector<String>();

+

+    private Vector<String> vPackageType = new Vector<String>();

+

+    private Vector<String> vUpdatedDate = new Vector<String>();

+

+    private JPanel jContentPane = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelPackageName = null;

+

+    private JLabel jLabelPackageType = null;

+

+    private JComboBox jComboBoxPackageType = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private JComboBox jComboBoxFileList = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonUpdate = null;

+

+    private JButton jButtonRemove = null;

+

+    private JLabel jLabelUpdatedDate = null;

+

+    private JTextField jTextFieldUpdatedDate = null;

+

+    private JCheckBox jCheckBoxArch = null;

+

+    private JComboBox jComboBoxArch = null;

+

+    private JComboBox jComboBoxPackageName = null;

+    

+    private Workspace ws = null;

+    

+    private Vector vecPackageName = null;

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButton() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 165, 90, 20));

+            jButtonOk.addActionListener(this);

+

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButton1() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 165, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jComboBoxPackageType 

+     

+     @return javax.swing.JComboBox jComboBoxPackageType

+     

+     **/

+    private JComboBox getJComboBoxPackageType() {

+        if (jComboBoxPackageType == null) {

+            jComboBoxPackageType = new JComboBox();

+            jComboBoxPackageType.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jComboBoxPackageType;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jComboBoxFileList 

+     

+     @return javax.swing.JComboBox jComboBoxFileList

+     

+     **/

+    private JComboBox getJComboBoxFileList() {

+        if (jComboBoxFileList == null) {

+            jComboBoxFileList = new JComboBox();

+            jComboBoxFileList.setBounds(new java.awt.Rectangle(15, 110, 210, 20));

+            jComboBoxFileList.addActionListener(this);

+            jComboBoxFileList.addItemListener(this);

+        }

+        return jComboBoxFileList;

+    }

+

+    /**

+     This method initializes jButtonAdd 

+     

+     @return javax.swing.JButton jButtonAdd

+     

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(230, 110, 80, 20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+     This method initializes jButtonUpdate 

+     

+     @return javax.swing.JButton jButtonUpdate

+     

+     **/

+    private JButton getJButtonUpdate() {

+        if (jButtonUpdate == null) {

+            jButtonUpdate = new JButton();

+            jButtonUpdate.setBounds(new java.awt.Rectangle(315, 110, 80, 20));

+            jButtonUpdate.setText("Update");

+            jButtonUpdate.addActionListener(this);

+        }

+        return jButtonUpdate;

+    }

+

+    /**

+     This method initializes jButtonRemove 

+     

+     @return javax.swing.JButton jButtonRemove

+     

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(400, 110, 80, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+     This method initializes jTextFieldUpdatedDate 

+     

+     @return javax.swing.JTextField jTextFieldUpdatedDate

+     

+     **/

+    private JTextField getJTextFieldUpdatedDate() {

+        if (jTextFieldUpdatedDate == null) {

+            jTextFieldUpdatedDate = new JTextField();

+            jTextFieldUpdatedDate.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return jTextFieldUpdatedDate;

+    }

+

+    /**

+     This method initializes jCheckBoxArch 

+     

+     @return javax.swing.JCheckBox jCheckBoxArch

+     

+     **/

+    private JCheckBox getJCheckBoxArch() {

+        if (jCheckBoxArch == null) {

+            jCheckBoxArch = new JCheckBox();

+            jCheckBoxArch.setBounds(new java.awt.Rectangle(10, 135, 120, 20));

+            jCheckBoxArch.setText("Specific Arch");

+            jCheckBoxArch.addActionListener(this);

+        }

+        return jCheckBoxArch;

+    }

+

+    /**

+     This method initializes jComboBoxArch 

+     

+     @return javax.swing.JComboBox jComboBoxArch

+     

+     **/

+    private JComboBox getJComboBoxArch() {

+        if (jComboBoxArch == null) {

+            jComboBoxArch = new JComboBox();

+            jComboBoxArch.setBounds(new java.awt.Rectangle(140, 135, 340, 20));

+            jComboBoxArch.setEnabled(false);

+        }

+        return jComboBoxArch;

+    }

+

+    /**

+     * This method initializes jComboBoxPackageName	

+     * 	

+     * @return javax.swing.JComboBox	

+     */

+    private JComboBox getJComboBoxPackageName() {

+        if (jComboBoxPackageName == null) {

+            jComboBoxPackageName = new JComboBox();

+            jComboBoxPackageName.setBounds(new java.awt.Rectangle(160,10,320,20));

+        }

+        return jComboBoxPackageName;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleIncludes() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inIncludes The input data of IncludesDocument.Includes

+     

+     **/

+    public ModuleIncludes(IncludesDocument.Includes inIncludes) {

+        super();

+        init(inIncludes);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inIncludes The input data of IncludesDocument.Includes

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleIncludes(IncludesDocument.Includes inIncludes, int type, int index) {

+        super();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inIncludes The input data of IncludesDocument.Includes

+     @param type The input data of node type

+     @param index The input data of node index

+     @param inOperation The input data of current operation type

+     

+     **/

+    public ModuleIncludes(IncludesDocument.Includes inIncludes, int type, int index, int inOperation) {

+        super();

+        init(inIncludes, type, index, inOperation);

+        this.operation = inOperation;

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inIncludes

+     

+     **/

+    private void init(IncludesDocument.Includes inIncludes) {

+        init();

+        this.setIncludes(inIncludes);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inIncludes The input data of IncludesDocument.Includes

+     @param type The input data of node type

+     @param index The input data of node index

+     @param inOperation The input data of current operation type

+     

+     **/

+    private void init(IncludesDocument.Includes inIncludes, int type, int index, int inOperation) {

+        init(inIncludes);

+        this.location = index;

+        this.operation = inOperation;

+

+        if (operation == 2) {

+            this.jCheckBoxArch.setEnabled(false);

+            this.jComboBoxArch.setEnabled(false);

+

+            if (type == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME) {

+                if (this.includes.getPackageNameList().size() > 0) {

+                    for (int indexI = 0; indexI < this.includes.getPackageNameList().size(); indexI++) {

+                        if (this.includes.getPackageNameArray(indexI).getStringValue() != null) {

+                            vPackageName.addElement(this.includes.getPackageNameArray(indexI).getStringValue());

+                        } else {

+                            vPackageName.addElement("");

+                        }

+                        if (this.includes.getPackageNameArray(indexI).getUsage() != null) {

+                            vUsage.addElement(this.includes.getPackageNameArray(indexI).getUsage().toString());

+                        } else {

+                            vUsage.addElement("ALWAYS_CONSUMED");

+                        }

+                        if (this.includes.getPackageNameArray(indexI).getPackageType() != null) {

+                            vPackageType.addElement(this.includes.getPackageNameArray(indexI).getPackageType()

+                                                                 .toString());

+                        } else {

+                            vPackageType.addElement("SOURCE");

+                        }

+                        if (this.includes.getPackageNameArray(indexI).getUpdatedDate() != null) {

+                            vUpdatedDate.addElement(this.includes.getPackageNameArray(indexI).getUpdatedDate());

+                        } else {

+                            vUpdatedDate.addElement("");

+                        }

+                        jComboBoxFileList.addItem(this.includes.getPackageNameArray(indexI).getStringValue());

+                    }

+                }

+            }

+            if (type == IDefaultMutableTreeNode.INCLUDES_ARCH_ITEM) {

+                this.jCheckBoxArch.setSelected(true);

+                this.jComboBoxArch.setSelectedItem(this.includes.getArchArray(index).getArchType().toString());

+                for (int indexI = 0; indexI < this.includes.getArchArray(index).getPackageNameList().size(); indexI++) {

+                    if (this.includes.getArchArray(index).getPackageNameArray(indexI).getStringValue() != null) {

+                        vPackageName.addElement(this.includes.getArchArray(index).getPackageNameArray(indexI)

+                                                             .getStringValue());

+                    } else {

+                        vPackageName.addElement("");

+                    }

+                    if (this.includes.getArchArray(index).getPackageNameArray(indexI).getUsage() != null) {

+                        vUsage.addElement(this.includes.getArchArray(index).getPackageNameArray(indexI).getUsage()

+                                                       .toString());

+                    } else {

+                        vUsage.addElement("");

+                    }

+                    if (this.includes.getArchArray(index).getPackageNameArray(indexI).getPackageType() != null) {

+                        vPackageType.addElement(this.includes.getArchArray(index).getPackageNameArray(indexI)

+                                                             .getPackageType().toString());

+                    } else {

+                        vPackageType.addElement("");

+                    }

+                    if (this.includes.getArchArray(index).getPackageNameArray(indexI).getUpdatedDate() != null) {

+                        vUpdatedDate.addElement(this.includes.getArchArray(index).getPackageNameArray(indexI)

+                                                             .getUpdatedDate());

+                    } else {

+                        vUpdatedDate.addElement("");

+                    }

+                    jComboBoxFileList.addItem(this.includes.getArchArray(index).getPackageNameArray(indexI)

+                                                           .getStringValue());

+                }

+            }

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Includes");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jComboBoxPackageType.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jComboBoxPackageName.setEnabled(!isView);

+            this.jButtonAdd.setEnabled(!isView);

+            this.jButtonUpdate.setEnabled(!isView);

+            this.jButtonRemove.setEnabled(!isView);

+            this.jTextFieldUpdatedDate.setEnabled(!isView);

+            this.jCheckBoxArch.setEnabled(!isView);

+            this.jComboBoxArch.setEnabled(!isView);

+

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelUpdatedDate = new JLabel();

+            jLabelUpdatedDate.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelUpdatedDate.setText("Updated Date");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelUsage.setText("Usage");

+            jLabelPackageType = new JLabel();

+            jLabelPackageType.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelPackageType.setText("Package Type");

+            jLabelPackageName = new JLabel();

+            jLabelPackageName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelPackageName.setText("Package Name");

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButton1(), null);

+            jContentPane.add(jLabelPackageName, null);

+            jContentPane.add(jLabelPackageType, null);

+            jContentPane.add(getJComboBoxPackageType(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(getJComboBoxFileList(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonUpdate(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(jLabelUpdatedDate, null);

+            jContentPane.add(getJTextFieldUpdatedDate(), null);

+            jContentPane.add(getJCheckBoxArch(), null);

+            jContentPane.add(getJComboBoxArch(), null);

+            jContentPane.add(getJComboBoxPackageName(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonAdd) {

+            if (!checkAdd()) {

+                return;

+            }

+            addToList();

+        }

+        if (arg0.getSource() == jButtonRemove) {

+            removeFromList();

+        }

+        if (arg0.getSource() == jButtonUpdate) {

+            if (!checkAdd()) {

+                return;

+            }

+            updateForList();

+        }

+

+        //

+        //When and only when checked Arch box then can choose different arch types

+        //

+        if (arg0.getSource() == jCheckBoxArch) {

+            if (this.jCheckBoxArch.isSelected()) {

+                this.jComboBoxArch.setEnabled(true);

+            } else {

+                this.jComboBoxArch.setEnabled(false);

+            }

+        }

+    }

+

+    /**

+     This method initializes Usage type, Package type and Arch type

+     

+     **/

+    private void initFrame() {

+        ws = new Workspace();

+        vecPackageName = ws.getAllPackageName();

+        for (int index = 0; index < vecPackageName.size(); index++) {

+            jComboBoxPackageName.addItem(vecPackageName.elementAt(index));

+        }

+        

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("DEFAULT");

+

+        jComboBoxPackageType.addItem("SOURCE");

+        jComboBoxPackageType.addItem("BINARY");

+        jComboBoxPackageType.addItem("MIXED");

+

+        jComboBoxArch.addItem("ALL");

+        jComboBoxArch.addItem("EBC");

+        jComboBoxArch.addItem("ARM");

+        jComboBoxArch.addItem("IA32");

+        jComboBoxArch.addItem("X64");

+        jComboBoxArch.addItem("IPF");

+        jComboBoxArch.addItem("PPC");

+    }

+

+    /**

+     Add current item to Vector

+     

+     **/

+    private void addToList() {

+        intSelectedItemId = vPackageName.size();

+        vPackageName.addElement(this.jComboBoxPackageName.getSelectedItem().toString());

+        vUsage.addElement(this.jComboBoxUsage.getSelectedItem().toString());

+        vPackageType.addElement(this.jComboBoxPackageType.getSelectedItem().toString());

+        vUpdatedDate.addElement(this.jTextFieldUpdatedDate.getText());

+        jComboBoxFileList.addItem(this.jComboBoxPackageName.getSelectedItem().toString());

+        jComboBoxFileList.setSelectedItem(this.jComboBoxPackageName.getSelectedItem().toString());

+        

+        //

+        // Reset select item index

+        //

+        intSelectedItemId = vPackageName.size();

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Remove item from Vector

+     

+     **/

+    private void removeFromList() {

+        int intTempIndex = intSelectedItemId;

+        if (vPackageName.size() < 1) {

+            return;

+        }

+        

+        jComboBoxFileList.removeItemAt(intSelectedItemId);

+        

+        vPackageName.removeElementAt(intTempIndex);

+        vUsage.removeElementAt(intTempIndex);

+        vPackageType.removeElementAt(intTempIndex);

+        vUpdatedDate.removeElementAt(intTempIndex);

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Update current item of Vector

+     

+     **/

+    private void updateForList() {

+        //

+        // Backup selected item index

+        //

+        int intTempIndex = intSelectedItemId;

+        

+        vPackageName.setElementAt(this.jComboBoxPackageName.getSelectedItem().toString(), intSelectedItemId);

+        vUsage.setElementAt(this.jComboBoxUsage.getSelectedItem().toString(), intSelectedItemId);

+        vPackageType.setElementAt(this.jComboBoxPackageType.getSelectedItem().toString(), intSelectedItemId);

+        vUpdatedDate.setElementAt(this.jTextFieldUpdatedDate.getText(), intSelectedItemId);

+        

+        jComboBoxFileList.removeAllItems();

+        for (int index = 0; index < vPackageName.size(); index++) {

+            jComboBoxFileList.addItem(vPackageName.elementAt(index));

+        }

+        

+        //

+        // Restore selected item index

+        //

+        intSelectedItemId = intTempIndex;

+        

+        //

+        // Reset select item index

+        //

+        jComboBoxFileList.setSelectedIndex(intSelectedItemId);

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Refresh all fields' values of selected item of Vector

+     

+     **/

+    private void reloadFromList() {

+        if (vPackageName.size() > 0) {

+            //

+            // Get selected item index

+            //

+            intSelectedItemId = jComboBoxFileList.getSelectedIndex();

+            

+            this.jComboBoxPackageName.setSelectedItem(vPackageName.elementAt(intSelectedItemId).toString());

+            this.jComboBoxUsage.setSelectedItem(vUsage.elementAt(intSelectedItemId).toString());

+            this.jComboBoxPackageType.setSelectedItem(vPackageType.elementAt(intSelectedItemId).toString());

+            this.jTextFieldUpdatedDate.setText(vUpdatedDate.elementAt(intSelectedItemId).toString());

+        } else {

+            this.jComboBoxPackageName.setSelectedIndex(0);

+            this.jComboBoxUsage.setSelectedIndex(0);

+            this.jComboBoxPackageType.setSelectedIndex(0);

+            this.jTextFieldUpdatedDate.setText("");

+        }

+    }

+

+    /**

+     Get IncludesDocument.Includes

+     

+     @return IncludesDocument.Includes

+     

+     **/

+    public IncludesDocument.Includes getIncludes() {

+        return includes;

+    }

+

+    /**

+     Set IncludesDocument.Includes

+     

+     @param includes IncludesDocument.Includes

+     

+     **/

+    public void setIncludes(IncludesDocument.Includes includes) {

+        this.includes = includes;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)

+     *

+     * Reflesh the frame when selected item changed

+     * 

+     */

+    public void itemStateChanged(ItemEvent arg0) {

+        if (arg0.getStateChange() == ItemEvent.SELECTED) {

+            reloadFromList();

+        }

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        if (this.jComboBoxFileList.getItemCount() < 1) {

+            Log.err("Must have one include at least!");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Data validation for all fields before add current item to Vector

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean checkAdd() {

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!isEmpty(this.jTextFieldUpdatedDate.getText())

+            && !DataValidation.isDateType(this.jTextFieldUpdatedDate.getText())) {

+            Log.err("Incorrect data type for Update Date");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Includes

+     if exists includes, set the value directly

+     if not exists includes, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.includes == null) {

+                includes = IncludesDocument.Includes.Factory.newInstance();

+            }

+            //

+            //Save as file name

+            //

+            if (!this.jCheckBoxArch.isSelected()) {

+                if (this.operation == 2) { //Add new packageName

+                    //

+                    //First remove all existed packageName

+                    //

+                    if (includes.getPackageNameList().size() > 0) {

+                        for (int index = includes.getPackageNameList().size() - 1; index >= 0; index--) {

+                            includes.removePackageName(index);

+                        }

+                    }

+                }

+                for (int index = 0; index < vPackageName.size(); index++) {

+                    PackageNameDocument.PackageName packageName = PackageNameDocument.PackageName.Factory.newInstance();

+                    if (!isEmpty(vPackageName.elementAt(index).toString())) {

+                        packageName.setStringValue(vPackageName.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vUsage.elementAt(index).toString())) {

+                        packageName.setUsage(PackageUsage.Enum.forString(vUsage.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vPackageType.elementAt(index).toString())) {

+                        packageName

+                                   .setPackageType(PackageType.Enum.forString(vPackageType.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vUpdatedDate.elementAt(index).toString())) {

+                        packageName.setUpdatedDate(vUpdatedDate.elementAt(index).toString());

+                    }

+                    includes.addNewPackageName();

+                    includes.setPackageNameArray(includes.getPackageNameList().size() - 1, packageName);

+                }

+            }

+            //

+            //Save as Arch

+            //

+            if (this.jCheckBoxArch.isSelected()) {

+                IncludesDocument.Includes.Arch arch = IncludesDocument.Includes.Arch.Factory.newInstance();

+                if (this.operation == 2) {

+                    //

+                    //First remove all existed filename

+                    //

+                    for (int index = includes.getArchArray(location).getPackageNameList().size() - 1; index >= 0; index--) {

+                        includes.getArchArray(location).removePackageName(index);

+                    }

+                }

+

+                for (int index = 0; index < vPackageName.size(); index++) {

+                    PackageNameDocument.PackageName packageName = PackageNameDocument.PackageName.Factory.newInstance();

+                    if (!isEmpty(vPackageName.elementAt(index).toString())) {

+                        packageName.setStringValue(vPackageName.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vUsage.elementAt(index).toString())) {

+                        packageName.setUsage(PackageUsage.Enum.forString(vUsage.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vPackageType.elementAt(index).toString())) {

+                        packageName

+                                   .setPackageType(PackageType.Enum.forString(vPackageType.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vUpdatedDate.elementAt(index).toString())) {

+                        packageName.setUpdatedDate(vUpdatedDate.elementAt(index).toString());

+                    }

+                    arch.addNewPackageName();

+                    arch.setPackageNameArray(arch.getPackageNameList().size() - 1, packageName);

+                }

+                arch

+                    .setArchType(SupportedArchitectures.Enum.forString(this.jComboBoxArch.getSelectedItem().toString()));

+                if (location > -1) {

+                    includes.setArchArray(location, arch);

+                } else {

+                    includes.addNewArch();

+                    includes.setArchArray(includes.getArchList().size() - 1, arch);

+                }

+            }

+        } catch (Exception e) {

+            Log.err("Update Source Files", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleLibraryClassDefinitions.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleLibraryClassDefinitions.java
new file mode 100644
index 0000000..ed81e8e
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleLibraryClassDefinitions.java
@@ -0,0 +1,625 @@
+/** @file

+ 

+ The file is used to create, update Library Class Definition of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.DefaultListModel;

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JList;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JScrollPane;

+import javax.swing.JTextField;

+

+import org.tianocore.LibraryClassDefinitionsDocument;

+import org.tianocore.LibraryClassDocument;

+import org.tianocore.LibraryUsage;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+

+/**

+ The class is used to create, update Library Class Definition of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleLibraryClassDefinitions extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -1743248695411382857L;

+

+    //

+    //Define class members

+    //

+    private static String Separator = "::";

+

+    private DefaultListModel listItem = new DefaultListModel();

+

+    private LibraryClassDefinitionsDocument.LibraryClassDefinitions libraryClassDefinitions = null;

+

+    private JPanel jContentPane = null;

+

+    private JRadioButton jRadioButtonAdd = null;

+

+    private JRadioButton jRadioButtonSelect = null;

+

+    private JTextField jTextFieldAdd = null;

+

+    private JComboBox jComboBoxSelect = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JList jListLibraryClassDefinitions = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonRemove = null;

+

+    private JButton jButtonClearAll = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonOk = null;

+

+    /**

+     This method initializes jRadioButtonAdd 

+     

+     @return javax.swing.JRadioButton jRadioButtonAdd

+     

+     **/

+    private JRadioButton getJRadioButtonAdd() {

+        if (jRadioButtonAdd == null) {

+            jRadioButtonAdd = new JRadioButton();

+            jRadioButtonAdd.setBounds(new java.awt.Rectangle(15, 35, 205, 20));

+            jRadioButtonAdd.setText("Add a new Library Class");

+            jRadioButtonAdd.addActionListener(this);

+            jRadioButtonAdd.setSelected(false);

+        }

+        return jRadioButtonAdd;

+    }

+

+    /**

+     This method initializes jRadioButtonSelect 

+     

+     @return javax.swing.JRadioButton jRadioButtonSelect

+     

+     **/

+    private JRadioButton getJRadioButtonSelect() {

+        if (jRadioButtonSelect == null) {

+            jRadioButtonSelect = new JRadioButton();

+            jRadioButtonSelect.setBounds(new java.awt.Rectangle(15, 10, 205, 20));

+            jRadioButtonSelect.setText("Select an existing Library Class");

+            jRadioButtonSelect.addActionListener(this);

+            jRadioButtonSelect.setSelected(true);

+        }

+        return jRadioButtonSelect;

+    }

+

+    /**

+     This method initializes jTextFieldAdd 

+     

+     @return javax.swing.JTextField jTextFieldAdd

+     

+     **/

+    private JTextField getJTextFieldAdd() {

+        if (jTextFieldAdd == null) {

+            jTextFieldAdd = new JTextField();

+            jTextFieldAdd.setBounds(new java.awt.Rectangle(220, 35, 260, 20));

+            jTextFieldAdd.setEnabled(false);

+        }

+        return jTextFieldAdd;

+    }

+

+    /**

+     This method initializes jComboBoxSelect 

+     

+     @return javax.swing.JComboBox jComboBoxSelect

+     

+     **/

+    private JComboBox getJComboBoxSelect() {

+        if (jComboBoxSelect == null) {

+            jComboBoxSelect = new JComboBox();

+            jComboBoxSelect.setBounds(new java.awt.Rectangle(220, 10, 260, 20));

+            jComboBoxSelect.setEnabled(true);

+        }

+        return jComboBoxSelect;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(220, 60, 260, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jScrollPane 

+     

+     @return javax.swing.JScrollPane jScrollPane

+     

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(15, 95, 350, 200));

+            jScrollPane.setViewportView(getJListLibraryClassDefinitions());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jListLibraryClassDefinitions 

+     

+     @return javax.swing.JList jListLibraryClassDefinitions

+     

+     **/

+    private JList getJListLibraryClassDefinitions() {

+        if (jListLibraryClassDefinitions == null) {

+            jListLibraryClassDefinitions = new JList(listItem);

+        }

+        return jListLibraryClassDefinitions;

+    }

+

+    /**

+     This method initializes jButtonAdd 

+     

+     @return javax.swing.JButton jButtonAdd

+     

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(380, 115, 90, 20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+     This method initializes jButtonRemove

+     

+     @return javax.swing.JButton jButtonRemove 

+     

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(380, 230, 90, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+     This method initializes jButtonRemoveAll 

+     

+     @return javax.swing.JButton jButtonClearAll

+     

+     **/

+    private JButton getJButtonClearAll() {

+        if (jButtonClearAll == null) {

+            jButtonClearAll = new JButton();

+            jButtonClearAll.setBounds(new java.awt.Rectangle(380, 260, 90, 20));

+            jButtonClearAll.setText("Clear All");

+            jButtonClearAll.addActionListener(this);

+        }

+        return jButtonClearAll;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setPreferredSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.setLocation(new java.awt.Point(390, 305));

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setSize(new java.awt.Dimension(90, 20));

+            jButtonOk.setText("OK");

+            jButtonOk.setLocation(new java.awt.Point(290, 305));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleLibraryClassDefinitions() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inLibraryClassDefinitions The input data of LibraryClassDefinitionsDocument.LibraryClassDefinitions

+     

+     **/

+    public ModuleLibraryClassDefinitions(

+                                         LibraryClassDefinitionsDocument.LibraryClassDefinitions inLibraryClassDefinitions) {

+        super();

+        init(inLibraryClassDefinitions);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inLibraryClassDefinitions The input data of LibraryClassDefinitionsDocument.LibraryClassDefinitions

+     

+     **/

+    private void init(LibraryClassDefinitionsDocument.LibraryClassDefinitions inLibraryClassDefinitions) {

+        init();

+        this.setLibraryClassDefinitions(inLibraryClassDefinitions);

+        if (this.libraryClassDefinitions != null) {

+            if (this.libraryClassDefinitions.getLibraryClassList().size() > 0) {

+                for (int index = 0; index < this.libraryClassDefinitions.getLibraryClassList().size(); index++) {

+                    listItem.addElement(this.libraryClassDefinitions.getLibraryClassArray(index).getUsage().toString()

+                                        + ModuleLibraryClassDefinitions.Separator

+                                        + this.libraryClassDefinitions.getLibraryClassArray(index).getStringValue());

+                    this.libraryClassDefinitions.getLibraryClassList();

+                }

+            }

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Library Class Definitions");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 515));

+        //this.centerWindow();

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jRadioButtonAdd.setEnabled(!isView);

+            this.jRadioButtonSelect.setEnabled(!isView);

+            this.jTextFieldAdd.setEnabled(!isView);

+            this.jComboBoxSelect.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jButtonAdd.setEnabled(!isView);

+            this.jButtonRemove.setEnabled(!isView);

+            this.jButtonClearAll.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelUsage = new JLabel();

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 60, 205, 20));

+            jLabelUsage.setText("Usage");

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJRadioButtonAdd(), null);

+            jContentPane.add(getJRadioButtonSelect(), null);

+            jContentPane.add(getJTextFieldAdd(), null);

+            jContentPane.add(getJComboBoxSelect(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(getJButtonClearAll(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonOk(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes all existing libraries and usage types

+     

+     **/

+    private void initFrame() {

+        jComboBoxSelect.addItem("BaseCpuICacheFlush");

+        jComboBoxSelect.addItem("BaseDebugLibNull");

+        jComboBoxSelect.addItem("BaseDebugLibReportStatusCode");

+        jComboBoxSelect.addItem("BaseIoLibIntrinsic");

+        jComboBoxSelect.addItem("BaseLib");

+        jComboBoxSelect.addItem("BaseMemoryLib");

+        jComboBoxSelect.addItem("BaseMemoryLibMmx");

+        jComboBoxSelect.addItem("BaseMemoryLibSse2");

+        jComboBoxSelect.addItem("BasePeCoffGetEntryPointLib");

+        jComboBoxSelect.addItem("BasePeCoffLib");

+        jComboBoxSelect.addItem("BasePrintLib");

+        jComboBoxSelect.addItem("BaseReportStatusCodeLibNull");

+        jComboBoxSelect.addItem("CommonPciCf8Lib");

+        jComboBoxSelect.addItem("CommonPciExpressLib");

+        jComboBoxSelect.addItem("CommonPciLibCf8");

+        jComboBoxSelect.addItem("CommonPciLibPciExpress");

+        jComboBoxSelect.addItem("DxeCoreEntryPoint");

+        jComboBoxSelect.addItem("DxeHobLib");

+        jComboBoxSelect.addItem("DxeIoLibCpuIo");

+        jComboBoxSelect.addItem("DxeLib");

+        jComboBoxSelect.addItem("DxePcdLib");

+        jComboBoxSelect.addItem("DxeReportStatusCodeLib");

+        jComboBoxSelect.addItem("DxeServicesTableLib");

+        jComboBoxSelect.addItem("PeiCoreEntryPoint");

+        jComboBoxSelect.addItem("PeiMemoryLib");

+        jComboBoxSelect.addItem("PeimEntryPoint");

+        jComboBoxSelect.addItem("PeiReportStatusCodeLib");

+        jComboBoxSelect.addItem("PeiServicesTablePointerLib");

+        jComboBoxSelect.addItem("PeiServicesTablePointerLibMm7");

+        jComboBoxSelect.addItem("UefiDebugLibConOut");

+        jComboBoxSelect.addItem("UefiDebugLibStdErr");

+        jComboBoxSelect.addItem("UefiDriverEntryPointMultiple");

+        jComboBoxSelect.addItem("UefiDriverEntryPointSingle");

+        jComboBoxSelect.addItem("UefiDriverEntryPointSingleUnload");

+        jComboBoxSelect.addItem("UefiDriverModelLib");

+        jComboBoxSelect.addItem("UefiDriverModelLibNoConfigNoDiag");

+        jComboBoxSelect.addItem("UefiLib");

+        jComboBoxSelect.addItem("UefiMemoryLib");

+

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("DEFAULT");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.dispose();

+            this.setEdited(true);

+            this.save();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+            this.setEdited(false);

+        }

+

+        //

+        // Add current Library and its usage to the list

+        //

+        if (arg0.getSource() == jButtonAdd) {

+            if (!checkAdd()) {

+                return;

+            }

+            String strLibClass = "";

+            String strUsage = "";

+            if (jRadioButtonAdd.isSelected()) {

+                strLibClass = jTextFieldAdd.getText();

+            }

+            if (jRadioButtonSelect.isSelected()) {

+                strLibClass = jComboBoxSelect.getSelectedItem().toString();

+            }

+            strUsage = jComboBoxUsage.getSelectedItem().toString();

+            listItem.addElement(strUsage + ModuleLibraryClassDefinitions.Separator + strLibClass);

+        }

+

+        //

+        // Remove current Library and its usage of the list

+        //

+        if (arg0.getSource() == jButtonRemove) {

+            int intSelected[] = jListLibraryClassDefinitions.getSelectedIndices();

+            if (intSelected.length > 0) {

+                for (int index = intSelected.length - 1; index > -1; index--) {

+                    listItem.removeElementAt(intSelected[index]);

+                }

+            }

+            jListLibraryClassDefinitions.getSelectionModel().clearSelection();

+        }

+

+        if (arg0.getSource() == jButtonClearAll) {

+            listItem.removeAllElements();

+        }

+

+        //

+        // Contorl the selected status when click RadionButton

+        // Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonAdd) {

+            if (jRadioButtonAdd.isSelected()) {

+                jRadioButtonSelect.setSelected(false);

+                jTextFieldAdd.setEnabled(true);

+                jComboBoxSelect.setEnabled(false);

+            }

+            if (!jRadioButtonSelect.isSelected() && !jRadioButtonAdd.isSelected()) {

+                jRadioButtonAdd.setSelected(true);

+                jTextFieldAdd.setEnabled(true);

+                jComboBoxSelect.setEnabled(false);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonSelect) {

+            if (jRadioButtonSelect.isSelected()) {

+                jRadioButtonAdd.setSelected(false);

+                jTextFieldAdd.setEnabled(false);

+                jComboBoxSelect.setEnabled(true);

+            }

+            if (!jRadioButtonSelect.isSelected() && !jRadioButtonAdd.isSelected()) {

+                jRadioButtonSelect.setSelected(true);

+                jTextFieldAdd.setEnabled(false);

+                jComboBoxSelect.setEnabled(true);

+            }

+        }

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        if (listItem.getSize() < 1) {

+            Log.err("Must have one Library Class at least!");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean checkAdd() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (this.jRadioButtonAdd.isSelected() && isEmpty(this.jTextFieldAdd.getText())) {

+            Log.err("Library Class couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (this.jRadioButtonAdd.isSelected() && !DataValidation.isLibraryClass(this.jTextFieldAdd.getText())) {

+            Log.err("Incorrect data type for Library Class");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Save all components of Mbd Header

+     if exists mbdHeader, set the value directly

+     if not exists mbdHeader, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            int intLibraryCount = listItem.getSize();

+

+            if (this.libraryClassDefinitions == null) {

+                libraryClassDefinitions = LibraryClassDefinitionsDocument.LibraryClassDefinitions.Factory.newInstance();

+            }

+

+            if (intLibraryCount > 0) {

+                LibraryClassDocument.LibraryClass mLibraryClass = LibraryClassDocument.LibraryClass.Factory

+                                                                                                           .newInstance();

+                for (int index = this.libraryClassDefinitions.getLibraryClassList().size() - 1; index > -1; index--) {

+                    this.libraryClassDefinitions.removeLibraryClass(index);

+                }

+                for (int index = 0; index < intLibraryCount; index++) {

+                    String strAll = listItem.get(index).toString();

+                    String strUsage = strAll.substring(0, strAll.indexOf(ModuleLibraryClassDefinitions.Separator));

+                    String strLibraryClass = strAll.substring(strAll.indexOf(ModuleLibraryClassDefinitions.Separator)

+                                                              + ModuleLibraryClassDefinitions.Separator.length());

+                    mLibraryClass.setStringValue(strLibraryClass);

+                    mLibraryClass.setUsage(LibraryUsage.Enum.forString(strUsage));

+                    this.libraryClassDefinitions.addNewLibraryClass();

+                    this.libraryClassDefinitions.setLibraryClassArray(index, mLibraryClass);

+                }

+            } else {

+                this.libraryClassDefinitions.setNil();

+            }

+        } catch (Exception e) {

+            Log.err("Update Library Class Definitions", e.getMessage());

+        }

+    }

+

+    /**

+     Get LibraryClassDefinitionsDocument.LibraryClassDefinitions

+     

+     @return LibraryClassDefinitionsDocument.LibraryClassDefinitions

+     

+     **/

+    public LibraryClassDefinitionsDocument.LibraryClassDefinitions getLibraryClassDefinitions() {

+        return libraryClassDefinitions;

+    }

+

+    /**

+     Set LibraryClassDefinitionsDocument.LibraryClassDefinitions

+     

+     @param libraryClassDefinitions The input data of LibraryClassDefinitionsDocument.LibraryClassDefinitions

+     

+     **/

+    public void setLibraryClassDefinitions(

+                                           LibraryClassDefinitionsDocument.LibraryClassDefinitions libraryClassDefinitions) {

+        this.libraryClassDefinitions = libraryClassDefinitions;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleMain.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleMain.java
new file mode 100644
index 0000000..883c0a5
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleMain.java
@@ -0,0 +1,4422 @@
+/** @file

+ 

+ The main GUI for module editor. 

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.MouseEvent;

+import java.awt.event.MouseListener;

+import java.awt.event.WindowEvent;

+import java.io.File;

+import java.io.IOException;

+

+import javax.swing.JButton;

+import javax.swing.JDesktopPane;

+import javax.swing.JFileChooser;

+import javax.swing.JInternalFrame;

+import javax.swing.JMenu;

+import javax.swing.JMenuBar;

+import javax.swing.JMenuItem;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JPopupMenu;

+import javax.swing.JScrollPane;

+import javax.swing.border.BevelBorder;

+import javax.swing.event.TreeSelectionEvent;

+import javax.swing.event.TreeSelectionListener;

+

+import org.apache.xmlbeans.XmlCursor;

+import org.apache.xmlbeans.XmlException;

+import org.apache.xmlbeans.XmlObject;

+import org.apache.xmlbeans.XmlOptions;

+import org.tianocore.BootModesDocument;

+import org.tianocore.BuildOptionsDocument;

+import org.tianocore.DataHubsDocument;

+import org.tianocore.EventsDocument;

+import org.tianocore.ExternsDocument;

+import org.tianocore.FormsetsDocument;

+import org.tianocore.GuidsDocument;

+import org.tianocore.HobsDocument;

+import org.tianocore.IncludesDocument;

+import org.tianocore.LibrariesDocument;

+import org.tianocore.LibraryClassDefinitionsDocument;

+import org.tianocore.LibraryModuleBuildDescriptionDocument;

+import org.tianocore.LibraryModuleSurfaceAreaDocument;

+import org.tianocore.MbdHeaderDocument;

+import org.tianocore.MbdLibHeaderDocument;

+import org.tianocore.ModuleBuildDescriptionDocument;

+import org.tianocore.ModuleSurfaceAreaDocument;

+import org.tianocore.MsaHeaderDocument;

+import org.tianocore.MsaLibHeaderDocument;

+import org.tianocore.PCDsDocument;

+import org.tianocore.PPIsDocument;

+import org.tianocore.ProtocolsDocument;

+import org.tianocore.SourceFilesDocument;

+import org.tianocore.SystemTablesDocument;

+import org.tianocore.VariablesDocument;

+import org.tianocore.common.IFileFilter;

+import org.tianocore.common.Log;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IDesktopManager;

+import org.tianocore.packaging.common.ui.IFrame;

+import org.tianocore.packaging.common.ui.ITree;

+import org.tianocore.packaging.workspace.common.Workspace;

+

+/**

+ The class is used to show main GUI of ModuleEditor

+ It extends IFrame implements MouseListener, TreeSelectionListener

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleMain extends IFrame implements MouseListener, TreeSelectionListener {

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -7103240960573031772L;

+

+    //

+    //Define class members

+    //

+    private String currentModule = "";

+

+    private String saveFileName = "";

+

+    ///

+    ///  0 - reserved; 1 - msa; 2 - mbd; 3 - lmsa; 4 - lmbd;

+    ///

+    private int currentModuleType = 0;

+

+    private int currentNodeType = -1;

+

+    private String windowTitle = "ModuleEditor 1.0 ";

+

+    private ModuleSurfaceAreaDocument xmlMsaDoc = null;

+

+    private ModuleBuildDescriptionDocument xmlMbdDoc = null;

+

+    private LibraryModuleSurfaceAreaDocument xmlMlsaDoc = null;

+

+    private LibraryModuleBuildDescriptionDocument xmlMlbdDoc = null;

+

+    private MsaHeaderDocument.MsaHeader xmlmh = null;

+

+    private MbdHeaderDocument.MbdHeader xmlmbdh = null;

+

+    private MsaLibHeaderDocument.MsaLibHeader xmlmlh = null;

+

+    private MbdLibHeaderDocument.MbdLibHeader xmlmlbdh = null;

+

+    private LibraryClassDefinitionsDocument.LibraryClassDefinitions xmllcd = null;

+

+    private LibrariesDocument.Libraries xmllib = null;

+

+    private SourceFilesDocument.SourceFiles xmlsf = null;

+

+    private IncludesDocument.Includes xmlic = null;

+

+    private ProtocolsDocument.Protocols xmlpl = null;

+

+    private EventsDocument.Events xmlen = null;

+

+    private HobsDocument.Hobs xmlhob = null;

+

+    private PPIsDocument.PPIs xmlppi = null;

+

+    private VariablesDocument.Variables xmlvb = null;

+

+    private BootModesDocument.BootModes xmlbm = null;

+

+    private SystemTablesDocument.SystemTables xmlst = null;

+

+    private DataHubsDocument.DataHubs xmldh = null;

+

+    private FormsetsDocument.Formsets xmlfs = null;

+

+    private GuidsDocument.Guids xmlgu = null;

+

+    private ExternsDocument.Externs xmlet = null;

+

+    private PCDsDocument.PCDs xmlpcd = null;

+

+    private BuildOptionsDocument.BuildOptions xmlbo = null;

+

+    IDefaultMutableTreeNode dmtnRoot = null;

+

+    private JPanel jContentPane = null;

+

+    private JMenuBar jMenuBar = null;

+

+    private JMenu jMenuModule = null;

+

+    private JMenu jMenuModuleNew = null;

+

+    private JMenuItem jMenuItemModuleNewModule = null;

+

+    private JMenuItem jMenuItemModuleSaveAs = null;

+

+    private JMenuItem jMenuItemModuleExit = null;

+

+    private JMenu jMenuEdit = null;

+

+    private JMenuItem jMenuItemEditAddLibraryClassDefinitions = null;

+

+    private JMenuItem jMenuItemEditAddSourceFiles = null;

+

+    private JMenuItem jMenuItemEditAddIncludes = null;

+

+    private JMenuItem jMenuItemEditAddProtocols = null;

+

+    private JMenuItem jMenuItemEditAddEvents = null;

+

+    private JMenuItem jMenuItemEditAddHobs = null;

+

+    private JMenuItem jMenuItemEditAddPPIs = null;

+

+    private JMenuItem jMenuItemEditAddVariables = null;

+

+    private JMenuItem jMenuItemEditAddBootModes = null;

+

+    private JMenuItem jMenuItemEditAddSystemTables = null;

+

+    private JMenuItem jMenuItemEditAddDataHubs = null;

+

+    private JMenuItem jMenuItemEditAddFormsets = null;

+

+    private JMenuItem jMenuItemEditAddGuids = null;

+

+    private JMenuItem jMenuItemEditAddExterns = null;

+

+    private JMenuItem jMenuItemEditAddPCDs = null;

+

+    private JDesktopPane jDesktopPane = null;

+

+    private IDesktopManager iDesktopManager = new IDesktopManager();

+

+    private JScrollPane jScrollPaneTree = null;

+

+    private ITree iTree = null;

+

+    private JMenu jMenuHelp = null;

+

+    private JMenuItem jMenuItemHelpAbout = null;

+

+    private JMenu jMenuEditAdd = null;

+

+    private JMenuItem jMenuItemEditDelete = null;

+

+    private JMenuItem jMenuItemEditUpdate = null;

+

+    private JPopupMenu jPopupMenu = null;

+

+    private JMenuItem jMenuItemPopupAdd = null;

+

+    private JMenuItem jMenuItemPopupUpdate = null;

+

+    private JMenuItem jMenuItemPopupDelete = null;

+

+    private Workspace ws = new Workspace();

+

+    private static final int OPENED = 0;

+

+    private static final int CLOSED = 1;

+

+    private static final int NEW_WITHOUT_CHANGE = 2;

+

+    private static final int NEW_WITH_CHANGE = 3;

+

+    private static final int UPDATE_WITHOUT_CHANGE = 4;

+

+    private static final int UPDATE_WITH_CHANGE = 5;

+

+    private static final int SAVE_WITHOUT_CHANGE = 6;

+

+    private static final int SAVE_WITH_CHANGE = 7;

+

+    private static final int ADD = 1;

+

+    private static final int UPDATE = 2;

+

+    //private static final int DELETE = 3;

+

+    private static final int VIEW = 4;

+

+    private MsaHeader msa = null;

+

+    private MbdHeader mbd = null;

+

+    private MsaLibHeader mlsa = null;

+

+    private MbdLibHeader mlbd = null;

+

+    private ModuleLibraryClassDefinitions mlcd = null;

+

+    private MbdLibraries mlib = null;

+

+    private ModuleSourceFiles msf = null;

+

+    private ModuleIncludes mic = null;

+

+    private ModuleProtocols mp = null;

+

+    private ModuleEvents mev = null;

+

+    private ModuleHobs mh = null;

+

+    private ModulePpis mpp = null;

+

+    private ModuleVariables mv = null;

+

+    private ModuleBootModes mbm = null;

+

+    private ModuleSystemTables mst = null;

+

+    private ModuleDataHubs mdh = null;

+

+    private ModuleFormsets mf = null;

+

+    private ModuleGuids mg = null;

+

+    private ModuleExterns met = null;

+

+    private ModulePCDs mpcd = null;

+

+    private JMenuItem jMenuItemModuleOpenModule = null;

+

+    private JMenuItem jMenuItemModuleNewModuleBuildDescription = null;

+

+    private JMenuItem jMenuItemModuleNewLibraryModule = null;

+

+    private JMenuItem jMenuItemModuleNewLibraryModuleBuildDescription = null;

+

+    private JMenu jMenuModuleOpen = null;

+

+    private JMenuItem jMenuItemModuleOpenModuleBuildDescription = null;

+

+    private JMenuItem jMenuItemModuleOpenLibraryModule = null;

+

+    private JMenuItem jMenuItemModuleOpenLibraryModuleBuildDescription = null;

+

+    private JMenuItem jMenuItemModuleSave = null;

+

+    private JMenuItem jMenuItemModuleClose = null;

+

+    private JMenu jMenuTools = null;

+

+    private JMenu jMenuWindow = null;

+

+    private JMenuItem jMenuItemEditAddLibraries = null;

+

+    private JPanel jPanelOperation = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    /**

+     This method initializes jMenuBar 

+     

+     @return javax.swing.JMenuBar Main menu bar for the entire GUI

+     

+     **/

+    private JMenuBar getjJMenuBar() {

+        if (jMenuBar == null) {

+            jMenuBar = new JMenuBar();

+            jMenuBar.setPreferredSize(new java.awt.Dimension(0, 18));

+            jMenuBar.add(getJMenuModule());

+            jMenuBar.add(getJMenuEdit());

+            jMenuBar.add(getJMenuTools());

+            jMenuBar.add(getJMenuWindow());

+            jMenuBar.add(getJMenuHelp());

+        }

+        return jMenuBar;

+    }

+

+    /**

+     This method initializes jMenuFile 

+     

+     @return javax.swing.JMenu jMenuModule

+     

+     **/

+    private JMenu getJMenuModule() {

+        if (jMenuModule == null) {

+            jMenuModule = new JMenu();

+            jMenuModule.setText("Module");

+            jMenuModule.add(getJMenuModuleNew());

+            jMenuModule.addSeparator();

+            jMenuModule.add(getJMenuModuleOpen());

+            jMenuModule.addSeparator();

+            jMenuModule.add(getJMenuItemModuleSave());

+            jMenuModule.add(getJMenuItemModuleSaveAs());

+            jMenuModule.addSeparator();

+            jMenuModule.add(getJMenuItemModuleClose());

+            jMenuModule.addSeparator();

+            jMenuModule.add(getJMenuItemModuleExit());

+        }

+        return jMenuModule;

+    }

+

+    /**

+     This method initializes jMenuItemModuleNewModule 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleNewModule

+     

+     **/

+    private JMenuItem getJMenuItemModuleNewModule() {

+        if (jMenuItemModuleNewModule == null) {

+            jMenuItemModuleNewModule = new JMenuItem();

+            jMenuItemModuleNewModule.setText("Module (.msa)");

+            jMenuItemModuleNewModule.addActionListener(this);

+        }

+        return jMenuItemModuleNewModule;

+    }

+

+    /**

+     This method initializes jMenuItemModuleSaveAs 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleSaveAs

+     

+     **/

+    private JMenuItem getJMenuItemModuleSaveAs() {

+        if (jMenuItemModuleSaveAs == null) {

+            jMenuItemModuleSaveAs = new JMenuItem();

+            jMenuItemModuleSaveAs.setText("Save As...");

+            jMenuItemModuleSaveAs.addActionListener(this);

+            jMenuItemModuleSaveAs.setEnabled(false);

+        }

+        return jMenuItemModuleSaveAs;

+    }

+

+    /**

+     This method initializes jMenuItemModuleExit 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleExit

+     

+     **/

+    private JMenuItem getJMenuItemModuleExit() {

+        if (jMenuItemModuleExit == null) {

+            jMenuItemModuleExit = new JMenuItem();

+            jMenuItemModuleExit.setText("Exit");

+            jMenuItemModuleExit.addActionListener(this);

+        }

+        return jMenuItemModuleExit;

+    }

+

+    /**

+     This method initializes jMenuEdit 

+     

+     @return javax.swing.JMenu jMenuEdit

+     

+     **/

+    private JMenu getJMenuEdit() {

+        if (jMenuEdit == null) {

+            jMenuEdit = new JMenu();

+            jMenuEdit.setText("Edit");

+            jMenuEdit.add(getJMenu());

+            jMenuEdit.add(getJMenuItemEditUpdate());

+            jMenuEdit.add(getJMenuItemEditDelete());

+        }

+        return jMenuEdit;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddLibraryClassDefinitions 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddLibraryClassDefinitions

+     

+     **/

+    private JMenuItem getJMenuItemEditAddLibraryClassDefinitions() {

+        if (jMenuItemEditAddLibraryClassDefinitions == null) {

+            jMenuItemEditAddLibraryClassDefinitions = new JMenuItem();

+            jMenuItemEditAddLibraryClassDefinitions.setText("Library Class Definitions");

+            jMenuItemEditAddLibraryClassDefinitions.addActionListener(this);

+        }

+        return jMenuItemEditAddLibraryClassDefinitions;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddSourceFiles 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddSourceFiles

+     

+     **/

+    private JMenuItem getJMenuItemEditAddSourceFiles() {

+        if (jMenuItemEditAddSourceFiles == null) {

+            jMenuItemEditAddSourceFiles = new JMenuItem();

+            jMenuItemEditAddSourceFiles.setText("Source Files");

+            jMenuItemEditAddSourceFiles.addActionListener(this);

+        }

+        return jMenuItemEditAddSourceFiles;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddIncludes 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddIncludes

+     

+     **/

+    private JMenuItem getJMenuItemEditAddIncludes() {

+        if (jMenuItemEditAddIncludes == null) {

+            jMenuItemEditAddIncludes = new JMenuItem();

+            jMenuItemEditAddIncludes.setText("Includes");

+            jMenuItemEditAddIncludes.addActionListener(this);

+        }

+        return jMenuItemEditAddIncludes;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddProtocols 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddProtocols

+     

+     **/

+    private JMenuItem getJMenuItemEditAddProtocols() {

+        if (jMenuItemEditAddProtocols == null) {

+            jMenuItemEditAddProtocols = new JMenuItem();

+            jMenuItemEditAddProtocols.setText("Protocols");

+            jMenuItemEditAddProtocols.addActionListener(this);

+        }

+        return jMenuItemEditAddProtocols;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddEvents 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddEvents

+     

+     **/

+    private JMenuItem getJMenuItemEditAddEvents() {

+        if (jMenuItemEditAddEvents == null) {

+            jMenuItemEditAddEvents = new JMenuItem();

+            jMenuItemEditAddEvents.setText("Events");

+            jMenuItemEditAddEvents.addActionListener(this);

+        }

+        return jMenuItemEditAddEvents;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddHobs 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddHobs

+     

+     **/

+    private JMenuItem getJMenuItemEditAddHobs() {

+        if (jMenuItemEditAddHobs == null) {

+            jMenuItemEditAddHobs = new JMenuItem();

+            jMenuItemEditAddHobs.setText("Hobs");

+            jMenuItemEditAddHobs.addActionListener(this);

+        }

+        return jMenuItemEditAddHobs;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddPPIs 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddPPIs

+     

+     **/

+    private JMenuItem getJMenuItemEditAddPPIs() {

+        if (jMenuItemEditAddPPIs == null) {

+            jMenuItemEditAddPPIs = new JMenuItem();

+            jMenuItemEditAddPPIs.setText("PPIs");

+            jMenuItemEditAddPPIs.addActionListener(this);

+        }

+        return jMenuItemEditAddPPIs;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddVariables 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddVariables

+     

+     **/

+    private JMenuItem getJMenuItemEditAddVariables() {

+        if (jMenuItemEditAddVariables == null) {

+            jMenuItemEditAddVariables = new JMenuItem();

+            jMenuItemEditAddVariables.setText("Variables");

+            jMenuItemEditAddVariables.addActionListener(this);

+        }

+        return jMenuItemEditAddVariables;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddBootModes 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddBootModes

+     

+     **/

+    private JMenuItem getJMenuItemAddBootModes() {

+        if (jMenuItemEditAddBootModes == null) {

+            jMenuItemEditAddBootModes = new JMenuItem();

+            jMenuItemEditAddBootModes.setText("Boot Modes");

+            jMenuItemEditAddBootModes.addActionListener(this);

+        }

+        return jMenuItemEditAddBootModes;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddSystemTables 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddSystemTables

+     

+     **/

+    private JMenuItem getJMenuItemAddSystemTables() {

+        if (jMenuItemEditAddSystemTables == null) {

+            jMenuItemEditAddSystemTables = new JMenuItem();

+            jMenuItemEditAddSystemTables.setText("System Tables");

+            jMenuItemEditAddSystemTables.addActionListener(this);

+        }

+        return jMenuItemEditAddSystemTables;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddDataHubs 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddDataHubs

+     

+     **/

+    private JMenuItem getJMenuItemEditAddDataHubs() {

+        if (jMenuItemEditAddDataHubs == null) {

+            jMenuItemEditAddDataHubs = new JMenuItem();

+            jMenuItemEditAddDataHubs.setText("Data Hubs");

+            jMenuItemEditAddDataHubs.addActionListener(this);

+        }

+        return jMenuItemEditAddDataHubs;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddFormsets 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddFormsets

+     

+     **/

+    private JMenuItem getJMenuItemEditAddFormsets() {

+        if (jMenuItemEditAddFormsets == null) {

+            jMenuItemEditAddFormsets = new JMenuItem();

+            jMenuItemEditAddFormsets.setText("Formsets");

+            jMenuItemEditAddFormsets.addActionListener(this);

+        }

+        return jMenuItemEditAddFormsets;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddGuids 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddGuids

+     

+     **/

+    private JMenuItem getJMenuItemEditAddGuids() {

+        if (jMenuItemEditAddGuids == null) {

+            jMenuItemEditAddGuids = new JMenuItem();

+            jMenuItemEditAddGuids.setText("Guids");

+            jMenuItemEditAddGuids.addActionListener(this);

+        }

+        return jMenuItemEditAddGuids;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddExterns 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddExterns

+     

+     **/

+    private JMenuItem getJMenuItemEditAddExterns() {

+        if (jMenuItemEditAddExterns == null) {

+            jMenuItemEditAddExterns = new JMenuItem();

+            jMenuItemEditAddExterns.setText("Externs");

+            jMenuItemEditAddExterns.addActionListener(this);

+        }

+        return jMenuItemEditAddExterns;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddPCDs 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddPCDs

+     

+     **/

+    private JMenuItem getJMenuItemEditAddPCDs() {

+        if (jMenuItemEditAddPCDs == null) {

+            jMenuItemEditAddPCDs = new JMenuItem();

+            jMenuItemEditAddPCDs.setText("PCDs");

+            jMenuItemEditAddPCDs.addActionListener(this);

+        }

+        return jMenuItemEditAddPCDs;

+    }

+

+    /**

+     This method initializes jDesktopPane 

+     

+     @return javax.swing.JDesktopPane jDesktopPane

+     

+     **/

+    private JDesktopPane getJDesktopPane() {

+        if (jDesktopPane == null) {

+            jDesktopPane = new JDesktopPane();

+            jDesktopPane.setBounds(new java.awt.Rectangle(295, 1, 500, 515));

+            jDesktopPane.setDesktopManager(iDesktopManager);

+        }

+        return jDesktopPane;

+    }

+

+    /**

+     This method initializes jScrollPaneTree 

+     

+     @return javax.swing.JScrollPane jScrollPaneTree

+     

+     **/

+    private JScrollPane getJScrollPaneTree() {

+        if (jScrollPaneTree == null) {

+            jScrollPaneTree = new JScrollPane();

+            jScrollPaneTree.setBounds(new java.awt.Rectangle(0, 1, 290, 545));

+            jScrollPaneTree.setViewportView(getITree());

+        }

+        return jScrollPaneTree;

+    }

+

+    /**

+     This method initializes iTree 

+     

+     @return org.tianocore.packaging.common.ui.ITree iTree

+     

+     **/

+    private ITree getITree() {

+        //

+        //Before open a real module, use an empty root node for the tree

+        //

+        IDefaultMutableTreeNode root = new IDefaultMutableTreeNode("No Msa/Mbd file opened", -1, -1);

+        iTree = new ITree(root);

+        return iTree;

+    }

+

+    /**

+     This method initializes jMenuHelp 

+     

+     @return javax.swing.JMenu jMenuHelp

+     

+     **/

+    private JMenu getJMenuHelp() {

+        if (jMenuHelp == null) {

+            jMenuHelp = new JMenu();

+            jMenuHelp.setText("Help");

+            jMenuHelp.add(getJMenuItemHelpAbout());

+        }

+        return jMenuHelp;

+    }

+

+    /**

+     This method initializes jMenuItemHelpAbout 

+     

+     @return javax.swing.JMenuItem jMenuItemHelpAbout

+     

+     **/

+    private JMenuItem getJMenuItemHelpAbout() {

+        if (jMenuItemHelpAbout == null) {

+            jMenuItemHelpAbout = new JMenuItem();

+            jMenuItemHelpAbout.setText("About...");

+            jMenuItemHelpAbout.addActionListener(this);

+        }

+        return jMenuItemHelpAbout;

+    }

+

+    /**

+     This method initializes jMenuEditAdd 

+     

+     @return javax.swing.JMenu jMenuEditAdd

+     

+     **/

+    private JMenu getJMenu() {

+        if (jMenuEditAdd == null) {

+            jMenuEditAdd = new JMenu();

+            jMenuEditAdd.setText("Add");

+            //

+            //Add all menu items of menu "Add"

+            //

+            jMenuEditAdd.add(getJMenuItemEditAddLibraries());

+            jMenuEditAdd.add(getJMenuItemEditAddLibraryClassDefinitions());

+            jMenuEditAdd.add(getJMenuItemEditAddSourceFiles());

+            jMenuEditAdd.add(getJMenuItemEditAddIncludes());

+            jMenuEditAdd.add(getJMenuItemEditAddProtocols());

+            jMenuEditAdd.add(getJMenuItemEditAddEvents());

+            jMenuEditAdd.add(getJMenuItemEditAddHobs());

+            jMenuEditAdd.add(getJMenuItemEditAddPPIs());

+            jMenuEditAdd.add(getJMenuItemEditAddVariables());

+            jMenuEditAdd.add(getJMenuItemAddBootModes());

+            jMenuEditAdd.add(getJMenuItemAddSystemTables());

+            jMenuEditAdd.add(getJMenuItemEditAddDataHubs());

+            jMenuEditAdd.add(getJMenuItemEditAddFormsets());

+            jMenuEditAdd.add(getJMenuItemEditAddGuids());

+            jMenuEditAdd.add(getJMenuItemEditAddExterns());

+            jMenuEditAdd.add(getJMenuItemEditAddPCDs());

+            jMenuEditAdd.setEnabled(false);

+        }

+        return jMenuEditAdd;

+    }

+

+    /**

+     This method initializes jMenuItemEditDelete 

+     

+     @return javax.swing.JMenuItem jMenuItemEditDelete

+     

+     **/

+    private JMenuItem getJMenuItemEditDelete() {

+        if (jMenuItemEditDelete == null) {

+            jMenuItemEditDelete = new JMenuItem();

+            jMenuItemEditDelete.setText("Delete");

+            jMenuItemEditDelete.addActionListener(this);

+            //

+            //Disabled when no module is open

+            //

+            jMenuItemEditDelete.setEnabled(false);

+        }

+        return jMenuItemEditDelete;

+    }

+

+    /**

+     This method initializes jMenuItemEditUpdate 

+     

+     @return javax.swing.JMenuItem jMenuItemEditUpdate

+     

+     **/

+    private JMenuItem getJMenuItemEditUpdate() {

+        if (jMenuItemEditUpdate == null) {

+            jMenuItemEditUpdate = new JMenuItem();

+            jMenuItemEditUpdate.setText("Update");

+            jMenuItemEditUpdate.addActionListener(this);

+            //

+            //Disabled when no module is open

+            //

+            jMenuItemEditUpdate.setEnabled(false);

+        }

+        return jMenuItemEditUpdate;

+    }

+

+    /**

+     This method initializes jPopupMenu 

+     

+     @return javax.swing.JPopupMenu jPopupMenu

+     

+     **/

+    private JPopupMenu getJPopupMenu() {

+        if (jPopupMenu == null) {

+            jPopupMenu = new JPopupMenu();

+            //

+            //Add menu items of popup menu

+            //

+            jPopupMenu.add(getJMenuItemPopupAdd());

+            jPopupMenu.add(getJMenuItemPopupUpdate());

+            jPopupMenu.add(getJMenuItemPopupDelete());

+            jPopupMenu.setBorder(new BevelBorder(BevelBorder.RAISED));

+            jPopupMenu.addMouseListener(this);

+        }

+        return jPopupMenu;

+    }

+

+    /**

+     This method initializes jMenuItemPopupAdd 

+     

+     @return javax.swing.JMenuItem jMenuItemPopupAdd

+     

+     **/

+    private JMenuItem getJMenuItemPopupAdd() {

+        if (jMenuItemPopupAdd == null) {

+            jMenuItemPopupAdd = new JMenuItem();

+            jMenuItemPopupAdd.setText("Add");

+            jMenuItemPopupAdd.addActionListener(this);

+            jMenuItemPopupAdd.setEnabled(false);

+        }

+        return jMenuItemPopupAdd;

+    }

+

+    /**

+     This method initializes jMenuItemPopupUpdate 

+     

+     @return javax.swing.JMenuItem jMenuItemPopupUpdate

+     

+     **/

+    private JMenuItem getJMenuItemPopupUpdate() {

+        if (jMenuItemPopupUpdate == null) {

+            jMenuItemPopupUpdate = new JMenuItem();

+            jMenuItemPopupUpdate.setText("Update");

+            jMenuItemPopupUpdate.addActionListener(this);

+            jMenuItemPopupUpdate.setEnabled(false);

+        }

+        return jMenuItemPopupUpdate;

+    }

+

+    /**

+     This method initializes jMenuItemPopupDelete 

+     

+     @return javax.swing.JMenuItem jMenuItemPopupDelete

+     

+     **/

+    private JMenuItem getJMenuItemPopupDelete() {

+        if (jMenuItemPopupDelete == null) {

+            jMenuItemPopupDelete = new JMenuItem();

+            jMenuItemPopupDelete.setText("Delete");

+            jMenuItemPopupDelete.addActionListener(this);

+            jMenuItemPopupDelete.setEnabled(false);

+        }

+        return jMenuItemPopupDelete;

+    }

+

+    /**

+     This method initializes jMenuModuleNew 

+     

+     @return javax.swing.JMenu jMenuModuleNew

+     

+     **/

+    private JMenu getJMenuModuleNew() {

+        if (jMenuModuleNew == null) {

+            jMenuModuleNew = new JMenu();

+            jMenuModuleNew.setText("New");

+            jMenuModuleNew.add(getJMenuItemModuleNewModule());

+            jMenuModuleNew.add(getJMenuItemModuleNewModuleBuildDescription());

+            jMenuModuleNew.add(getJMenuItemModuleNewLibraryModule());

+            jMenuModuleNew.add(getJMenuItemModuleNewLibraryModuleBuildDescription());

+        }

+        return jMenuModuleNew;

+    }

+

+    /**

+     This method initializes jMenuItemModuleOpenModule 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleOpenModule

+     

+     **/

+    private JMenuItem getJMenuItemModuleOpenModule() {

+        if (jMenuItemModuleOpenModule == null) {

+            jMenuItemModuleOpenModule = new JMenuItem();

+            jMenuItemModuleOpenModule.setText("Module (.msa)");

+            jMenuItemModuleOpenModule.addActionListener(this);

+        }

+        return jMenuItemModuleOpenModule;

+    }

+

+    /**

+     This method initializes jMenuItemFileNewModuleBuildDescription 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleNewModuleBuildDescription

+     

+     **/

+    private JMenuItem getJMenuItemModuleNewModuleBuildDescription() {

+        if (jMenuItemModuleNewModuleBuildDescription == null) {

+            jMenuItemModuleNewModuleBuildDescription = new JMenuItem();

+            jMenuItemModuleNewModuleBuildDescription.setText("Module Build Description (.mbd)");

+            jMenuItemModuleNewModuleBuildDescription.addActionListener(this);

+        }

+        return jMenuItemModuleNewModuleBuildDescription;

+    }

+

+    /**

+     This method initializes jMenuItemFileNewLibraryModule 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleNewLibraryModule

+     

+     **/

+    private JMenuItem getJMenuItemModuleNewLibraryModule() {

+        if (jMenuItemModuleNewLibraryModule == null) {

+            jMenuItemModuleNewLibraryModule = new JMenuItem();

+            jMenuItemModuleNewLibraryModule.setText("Library Module (*.msa)");

+            jMenuItemModuleNewLibraryModule.addActionListener(this);

+        }

+        return jMenuItemModuleNewLibraryModule;

+    }

+

+    /**

+     This method initializes jMenuItemFileNewLibraryModuleBuildDescription 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleNewLibraryModuleBuildDescription

+     

+     **/

+    private JMenuItem getJMenuItemModuleNewLibraryModuleBuildDescription() {

+        if (jMenuItemModuleNewLibraryModuleBuildDescription == null) {

+            jMenuItemModuleNewLibraryModuleBuildDescription = new JMenuItem();

+            jMenuItemModuleNewLibraryModuleBuildDescription.setText("Library Module Build Description (.mbd)");

+            jMenuItemModuleNewLibraryModuleBuildDescription.addActionListener(this);

+        }

+        return jMenuItemModuleNewLibraryModuleBuildDescription;

+    }

+

+    /**

+     This method initializes jMenuOpen 

+     

+     @return javax.swing.JMenu jMenuModuleOpen

+     

+     **/

+    private JMenu getJMenuModuleOpen() {

+        if (jMenuModuleOpen == null) {

+            jMenuModuleOpen = new JMenu();

+            jMenuModuleOpen.setText("Open");

+            jMenuModuleOpen.add(getJMenuItemModuleOpenModule());

+            jMenuModuleOpen.add(getJMenuItemModuleOpenModuleBuildDescription());

+            jMenuModuleOpen.add(getJMenuItemModuleOpenLibraryModule());

+            jMenuModuleOpen.add(getJMenuItemModuleOpenLibraryModuleBuildDescription());

+        }

+        return jMenuModuleOpen;

+    }

+

+    /**

+     This method initializes jMenuItemFileOpenModuleBuildDescription 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleOpenModuleBuildDescription

+     

+     **/

+    private JMenuItem getJMenuItemModuleOpenModuleBuildDescription() {

+        if (jMenuItemModuleOpenModuleBuildDescription == null) {

+            jMenuItemModuleOpenModuleBuildDescription = new JMenuItem();

+            jMenuItemModuleOpenModuleBuildDescription.setText("Module Build Description (.mbd)");

+            jMenuItemModuleOpenModuleBuildDescription.addActionListener(this);

+        }

+        return jMenuItemModuleOpenModuleBuildDescription;

+    }

+

+    /**

+     This method initializes jMenuItemFileOpenLibraryModule 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleOpenLibraryModule

+     

+     **/

+    private JMenuItem getJMenuItemModuleOpenLibraryModule() {

+        if (jMenuItemModuleOpenLibraryModule == null) {

+            jMenuItemModuleOpenLibraryModule = new JMenuItem();

+            jMenuItemModuleOpenLibraryModule.setText("Library Module (.msa)");

+            jMenuItemModuleOpenLibraryModule.addActionListener(this);

+        }

+        return jMenuItemModuleOpenLibraryModule;

+    }

+

+    /**

+     This method initializes jMenuItemFileOpenLibraryModuleBuildDescription 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleOpenLibraryModuleBuildDescription

+     

+     **/

+    private JMenuItem getJMenuItemModuleOpenLibraryModuleBuildDescription() {

+        if (jMenuItemModuleOpenLibraryModuleBuildDescription == null) {

+            jMenuItemModuleOpenLibraryModuleBuildDescription = new JMenuItem();

+            jMenuItemModuleOpenLibraryModuleBuildDescription.setText("Library Module Build Description (.mbd)");

+            jMenuItemModuleOpenLibraryModuleBuildDescription.addActionListener(this);

+        }

+        return jMenuItemModuleOpenLibraryModuleBuildDescription;

+    }

+

+    /**

+     This method initializes jMenuItemFileSave 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleSave

+     

+     **/

+    private JMenuItem getJMenuItemModuleSave() {

+        if (jMenuItemModuleSave == null) {

+            jMenuItemModuleSave = new JMenuItem();

+            jMenuItemModuleSave.setText("Save");

+            jMenuItemModuleSave.addActionListener(this);

+            jMenuItemModuleSave.setEnabled(false);

+        }

+        return jMenuItemModuleSave;

+    }

+

+    /**

+     This method initializes jMenuItemModuleClose 

+     

+     @return javax.swing.JMenuItem jMenuItemModuleClose

+     

+     **/

+    private JMenuItem getJMenuItemModuleClose() {

+        if (jMenuItemModuleClose == null) {

+            jMenuItemModuleClose = new JMenuItem();

+            jMenuItemModuleClose.setText("Close");

+            jMenuItemModuleClose.setEnabled(false);

+            jMenuItemModuleClose.addActionListener(this);

+        }

+        return jMenuItemModuleClose;

+    }

+

+    /**

+     This method initializes jMenuTools

+     Reserved 

+     

+     @return javax.swing.JMenu jMenuTools

+     

+     **/

+    private JMenu getJMenuTools() {

+        if (jMenuTools == null) {

+            jMenuTools = new JMenu();

+            jMenuTools.setText("Tools");

+            jMenuTools.addActionListener(this);

+            jMenuTools.setEnabled(false);

+        }

+        return jMenuTools;

+    }

+

+    /**

+     This method initializes jMenuWindow 

+     Reserved

+     

+     @return javax.swing.JMenu jMenuWindow

+     

+     **/

+    private JMenu getJMenuWindow() {

+        if (jMenuWindow == null) {

+            jMenuWindow = new JMenu();

+            jMenuWindow.setText("Window");

+            jMenuWindow.setEnabled(false);

+            jMenuWindow.addActionListener(this);

+        }

+        return jMenuWindow;

+    }

+

+    /**

+     This method initializes jMenuItemEditAddLibraries 

+     

+     @return javax.swing.JMenuItem jMenuItemEditAddLibraries

+     

+     **/

+    private JMenuItem getJMenuItemEditAddLibraries() {

+        if (jMenuItemEditAddLibraries == null) {

+            jMenuItemEditAddLibraries = new JMenuItem();

+            jMenuItemEditAddLibraries.setText("Libraries");

+            jMenuItemEditAddLibraries.addActionListener(this);

+        }

+        return jMenuItemEditAddLibraries;

+    }

+

+    /**

+     This method initializes jPanelOperation 

+     

+     @return javax.swing.JPanel jPanelOperation

+     

+     **/

+    private JPanel getJPanelOperation() {

+        if (jPanelOperation == null) {

+            jPanelOperation = new JPanel();

+            jPanelOperation.setLayout(null);

+            jPanelOperation.setBounds(new java.awt.Rectangle(295, 520, 500, 25));

+            jPanelOperation.add(getJButtonOk(), null);

+            jPanelOperation.add(getJButtonCancel(), null);

+        }

+        return jPanelOperation;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setBounds(new java.awt.Rectangle(395, 2, 90, 20));

+            jButtonOk.setText("Ok");

+            jButtonOk.setEnabled(false);

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setBounds(new java.awt.Rectangle(395, 2, 90, 20));

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setEnabled(false);

+            jButtonCancel.addActionListener(this);

+            jButtonCancel.setVisible(false);

+        }

+        return jButtonCancel;

+    }

+

+    /* (non-Javadoc)

+     * @see org.tianocore.packaging.common.ui.IFrame#main(java.lang.String[])

+     *

+     * Main class, start the GUI

+     * 

+     */

+    public static void main(String[] args) {

+        ModuleMain module = new ModuleMain();

+        module.setVisible(true);

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleMain() {

+        super();

+        init();

+    }

+

+    /**

+     This method initializes this

+     

+     

+     **/

+    private void init() {

+        //

+        // Check if exists WORKSPACE

+        // 

+        //

+        if (!ws.checkCurrentWorkspace()) {

+            JOptionPane.showConfirmDialog(null, "You haven't a workspace yet. Please setup first.", "Warning",

+                                          JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);

+            this.dispose();

+            System.exit(0);

+        }

+

+        this.setSize(800, 600);

+        this.setResizable(false);

+        this.setJMenuBar(getjJMenuBar());

+        this.setContentPane(getJContentPane());

+        this.setTitle(windowTitle + "- [" + ws.getCurrentWorkspace() + "]");

+        this.setExitType(1);

+        this.centerWindow();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJPanelOperation(), null);

+            jContentPane.add(getJDesktopPane(), null);

+            jContentPane.add(getJScrollPaneTree(), null);

+            jContentPane.add(getJPopupMenu(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     *

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        //

+        // Open relevant frame via clicking different menu items

+        //

+        if (arg0.getSource() == jMenuItemHelpAbout) {

+            ModuleAbout ma = new ModuleAbout();

+            ma.setEdited(false);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddLibraries) {

+            showLibraries(ModuleMain.ADD, IDefaultMutableTreeNode.LIBRARIES, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddLibraryClassDefinitions) {

+            showLibraryClassDefinitions(ModuleMain.ADD, IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddSourceFiles) {

+            showSourceFiles(ModuleMain.ADD, IDefaultMutableTreeNode.SOURCEFILES, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddIncludes) {

+            showIncludes(ModuleMain.ADD, IDefaultMutableTreeNode.INCLUDES, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddProtocols) {

+            showProtocols(ModuleMain.ADD, IDefaultMutableTreeNode.PROTOCOLS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddEvents) {

+            showEvents(ModuleMain.ADD, IDefaultMutableTreeNode.EVENTS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddHobs) {

+            showHobs(ModuleMain.ADD, IDefaultMutableTreeNode.HOBS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddPPIs) {

+            showPpis(ModuleMain.ADD, IDefaultMutableTreeNode.PPIS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddVariables) {

+            showVariables(ModuleMain.ADD, IDefaultMutableTreeNode.VARIABLES, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddBootModes) {

+            showBootModes(ModuleMain.ADD, IDefaultMutableTreeNode.BOOTMODES, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddSystemTables) {

+            showSystemTables(ModuleMain.ADD, IDefaultMutableTreeNode.SYSTEMTABLES, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddDataHubs) {

+            showDataHubs(ModuleMain.ADD, IDefaultMutableTreeNode.DATAHUBS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddFormsets) {

+            showFormsets(ModuleMain.ADD, IDefaultMutableTreeNode.FORMSETS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddGuids) {

+            showGuids(ModuleMain.ADD, IDefaultMutableTreeNode.GUIDS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddExterns) {

+            showExterns(ModuleMain.ADD, IDefaultMutableTreeNode.EXTERNS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemEditAddPCDs) {

+            showPCDs(ModuleMain.ADD, IDefaultMutableTreeNode.PCDS, -1);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleNewModule) {

+            this.closeCurrentModule();

+            showMsaHeader(ModuleMain.ADD);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleNewModuleBuildDescription) {

+            this.closeCurrentModule();

+            showMbdHeader(ModuleMain.ADD);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleNewLibraryModule) {

+            this.closeCurrentModule();

+            showMlsaHeader(ModuleMain.ADD);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleNewLibraryModuleBuildDescription) {

+            this.closeCurrentModule();

+            showMlbdHeader(ModuleMain.ADD);

+        }

+

+        //

+        // Open Msa, Mbd, Lmsa and Lmbd

+        //

+        if (arg0.getSource() == jMenuItemModuleOpenModule) {

+            openFile(1, 1);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleOpenModuleBuildDescription) {

+            openFile(1, 2);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleOpenLibraryModule) {

+            openFile(1, 3);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleOpenLibraryModuleBuildDescription) {

+            openFile(1, 4);

+        }

+

+        //

+        // Listen popup menu items

+        //

+        if (arg0.getSource() == jMenuItemPopupAdd) {

+            int intCategory = iTree.getSelectCategory();

+            int intLocation = iTree.getSelectLoaction();

+            addCurrentModule(intCategory, intLocation);

+        }

+

+        if (arg0.getSource() == jMenuItemPopupUpdate || arg0.getSource() == jMenuItemEditUpdate) {

+            int intCategory = iTree.getSelectCategory();

+            int intLocation = iTree.getSelectLoaction();

+            updateCurrentModule(intCategory, intLocation);

+        }

+

+        if (arg0.getSource() == jMenuItemPopupDelete || arg0.getSource() == jMenuItemEditDelete) {

+            int intCategory = iTree.getSelectCategory();

+            int intLocation = iTree.getSelectLoaction();

+            deleteCurrentModule(intCategory, intLocation);

+        }

+

+        if (arg0.getSource() == jMenuItemModuleExit) {

+            this.onExit();

+        }

+

+        if (arg0.getSource() == jMenuItemModuleClose) {

+            closeCurrentModule();

+        }

+

+        if (arg0.getSource() == jMenuItemModuleSaveAs) {

+            saveAsCurrentModule();

+        }

+

+        if (arg0.getSource() == jMenuItemModuleSave) {

+            saveCurrentModule();

+        }

+

+        if (arg0.getSource() == jButtonOk) {

+            save();

+        }

+

+        if (arg0.getSource() == jButtonCancel) {

+

+        }

+    }

+

+    /**

+     Open file

+     

+     @param intOperationType Open - 1 or Save - 2

+     @param intFileType Msa - 1, Mbd - 2, Lmsa - 3, Lmbd - 4

+     @return opened file path

+     

+     **/

+    private void openFile(int intOperationType, int intFileType) {

+        String strCurrentPath = "";

+        if (this.currentModule == "") {

+            strCurrentPath = ws.getCurrentWorkspace();

+        } else {

+            strCurrentPath = this.currentModule

+                                               .substring(

+                                                          0,

+                                                          this.currentModule

+                                                                            .lastIndexOf(System

+                                                                                               .getProperty("file.separator")));

+        }

+

+        JFileChooser fc = new JFileChooser(strCurrentPath);

+        fc.setAcceptAllFileFilterUsed(false);

+        switch (intOperationType) {

+        case 1:

+            fc.setDialogTitle("Open");

+            break;

+        case 2:

+            fc.setDialogTitle("Save As");

+            break;

+        }

+        //

+        // Config File Filter via different file types

+        //

+        switch (intFileType) {

+        case 1:

+            fc.addChoosableFileFilter(new IFileFilter("msa"));

+            break;

+        case 2:

+            fc.addChoosableFileFilter(new IFileFilter("mbd"));

+            break;

+        case 3:

+            fc.addChoosableFileFilter(new IFileFilter("msa"));

+            break;

+        case 4:

+            fc.addChoosableFileFilter(new IFileFilter("mbd"));

+            break;

+        }

+

+        int result = fc.showOpenDialog(new JPanel());

+        //

+        // Open relevanf file after click "OK"

+        //

+        if (result == JFileChooser.APPROVE_OPTION) {

+            switch (intOperationType) {

+            case 1:

+                closeCurrentModule();

+                switch (intFileType) {

+                case 1:

+                    openMsaFile(fc.getSelectedFile().getPath());

+                    break;

+                case 2:

+                    openMbdFile(fc.getSelectedFile().getPath());

+                    break;

+                case 3:

+                    openMlsaFile(fc.getSelectedFile().getPath());

+                    break;

+                case 4:

+                    openMlbdFile(fc.getSelectedFile().getPath());

+                    break;

+                }

+                break;

+            case 2:

+                switch (intFileType) {

+                case 1:

+                    this.saveFileName = fc.getSelectedFile().getPath();

+                    break;

+                case 2:

+                    this.saveFileName = fc.getSelectedFile().getPath();

+                    break;

+                case 3:

+                    this.saveFileName = fc.getSelectedFile().getPath();

+                    break;

+                case 4:

+                    this.saveFileName = fc.getSelectedFile().getPath();

+                    break;

+                }

+                break;

+            }

+        } else {

+            if (intOperationType == 2) {

+                this.saveFileName = "";

+            }

+        }

+    }

+

+    /**

+     Open specificed Msa file and read its content

+     

+     @param strMsaFilePath The input data of Msa File Path

+     

+     **/

+    private void openMsaFile(String strMsaFilePath) {

+        Log.log("Open Msa", strMsaFilePath);

+        try {

+            File msaFile = new File(strMsaFilePath);

+            xmlMsaDoc = (ModuleSurfaceAreaDocument) XmlObject.Factory.parse(msaFile);

+            this.currentModule = strMsaFilePath;

+            this.saveFileName = strMsaFilePath;

+            this.currentModuleType = 1;

+        } catch (IOException e) {

+            Log.err("Open Msa " + strMsaFilePath, e.getMessage());

+            return;

+        } catch (XmlException e) {

+            Log.err("Open Msa " + strMsaFilePath, e.getMessage());

+            return;

+        } catch (Exception e) {

+            Log.err("Open Msa " + strMsaFilePath, "Invalid file type");

+            return;

+        }

+

+        xmlmh = xmlMsaDoc.getModuleSurfaceArea().getMsaHeader();

+        xmllcd = xmlMsaDoc.getModuleSurfaceArea().getLibraryClassDefinitions();

+        xmlsf = xmlMsaDoc.getModuleSurfaceArea().getSourceFiles();

+        xmlic = xmlMsaDoc.getModuleSurfaceArea().getIncludes();

+        xmlpl = xmlMsaDoc.getModuleSurfaceArea().getProtocols();

+        xmlen = xmlMsaDoc.getModuleSurfaceArea().getEvents();

+        xmlhob = xmlMsaDoc.getModuleSurfaceArea().getHobs();

+        xmlppi = xmlMsaDoc.getModuleSurfaceArea().getPPIs();

+        xmlvb = xmlMsaDoc.getModuleSurfaceArea().getVariables();

+        xmlbm = xmlMsaDoc.getModuleSurfaceArea().getBootModes();

+        xmlst = xmlMsaDoc.getModuleSurfaceArea().getSystemTables();

+        xmldh = xmlMsaDoc.getModuleSurfaceArea().getDataHubs();

+        xmlfs = xmlMsaDoc.getModuleSurfaceArea().getFormsets();

+        xmlgu = xmlMsaDoc.getModuleSurfaceArea().getGuids();

+        xmlet = xmlMsaDoc.getModuleSurfaceArea().getExterns();

+        xmlpcd = xmlMsaDoc.getModuleSurfaceArea().getPCDs();

+        xmlbo = xmlMsaDoc.getModuleSurfaceArea().getBuildOptions();

+

+        this.showMsaHeader(ModuleMain.VIEW);

+        reloadTreeAndTable(ModuleMain.OPENED);

+        jMenuEditAdd.setEnabled(true);

+    }

+

+    /**

+     Open specificed Mbd file and read its content

+     

+     @param strMbdFilePath The input data of Mbd File Path

+     

+     **/

+    private void openMbdFile(String strMbdFilePath) {

+        Log.log("Open Mbd", strMbdFilePath);

+        try {

+            File mbdFile = new File(strMbdFilePath);

+            xmlMbdDoc = (ModuleBuildDescriptionDocument) XmlObject.Factory.parse(mbdFile);

+            this.currentModule = strMbdFilePath;

+            this.saveFileName = strMbdFilePath;

+            this.currentModuleType = 2;

+        } catch (IOException e) {

+            Log.err("Open Mbd " + strMbdFilePath, e.getMessage());

+            return;

+        } catch (XmlException e) {

+            Log.err("Open Mbd " + strMbdFilePath, e.getMessage());

+            return;

+        } catch (Exception e) {

+            Log.err("Open Mbd " + strMbdFilePath, "Invalid file type");

+            return;

+        }

+

+        xmlmbdh = xmlMbdDoc.getModuleBuildDescription().getMbdHeader();

+        xmllib = xmlMbdDoc.getModuleBuildDescription().getLibraries();

+        xmlsf = xmlMbdDoc.getModuleBuildDescription().getSourceFiles();

+        xmlic = xmlMbdDoc.getModuleBuildDescription().getIncludes();

+        xmlpl = xmlMbdDoc.getModuleBuildDescription().getProtocols();

+        xmlen = xmlMbdDoc.getModuleBuildDescription().getEvents();

+        xmlhob = xmlMbdDoc.getModuleBuildDescription().getHobs();

+        xmlppi = xmlMbdDoc.getModuleBuildDescription().getPPIs();

+        xmlvb = xmlMbdDoc.getModuleBuildDescription().getVariables();

+        xmlbm = xmlMbdDoc.getModuleBuildDescription().getBootModes();

+        xmlst = xmlMbdDoc.getModuleBuildDescription().getSystemTables();

+        xmldh = xmlMbdDoc.getModuleBuildDescription().getDataHubs();

+        xmlfs = xmlMbdDoc.getModuleBuildDescription().getFormsets();

+        xmlgu = xmlMbdDoc.getModuleBuildDescription().getGuids();

+        xmlet = xmlMbdDoc.getModuleBuildDescription().getExterns();

+        xmlpcd = xmlMbdDoc.getModuleBuildDescription().getPCDs();

+        xmlbo = xmlMbdDoc.getModuleBuildDescription().getBuildOptions();

+

+        this.showMbdHeader(ModuleMain.VIEW);

+        reloadTreeAndTable(ModuleMain.OPENED);

+        jMenuEditAdd.setEnabled(true);

+    }

+

+    /**

+     Open specificed Mlsa file and read its content

+     

+     @param strMlsaFilePath The input data of Mlsa File Path

+     

+     **/

+    private void openMlsaFile(String strMlsaFilePath) {

+        Log.log("Open Mlsa", strMlsaFilePath);

+        try {

+            File mlsaFile = new File(strMlsaFilePath);

+            xmlMlsaDoc = (LibraryModuleSurfaceAreaDocument) XmlObject.Factory.parse(mlsaFile);

+            this.currentModule = strMlsaFilePath;

+            this.saveFileName = strMlsaFilePath;

+            this.currentModuleType = 3;

+        } catch (IOException e) {

+            Log.err("Open Mlsa " + strMlsaFilePath, e.getMessage());

+            return;

+        } catch (XmlException e) {

+            Log.err("Open Mlsa " + strMlsaFilePath, e.getMessage());

+            return;

+        } catch (Exception e) {

+            Log.err("Open Mlsa " + strMlsaFilePath, "Invalid file type");

+            return;

+        }

+

+        xmlmlh = xmlMlsaDoc.getLibraryModuleSurfaceArea().getMsaLibHeader();

+        xmllcd = xmlMlsaDoc.getLibraryModuleSurfaceArea().getLibraryClassDefinitions();

+        xmlsf = xmlMlsaDoc.getLibraryModuleSurfaceArea().getSourceFiles();

+        xmlic = xmlMlsaDoc.getLibraryModuleSurfaceArea().getIncludes();

+        xmlpl = xmlMlsaDoc.getLibraryModuleSurfaceArea().getProtocols();

+        xmlen = xmlMlsaDoc.getLibraryModuleSurfaceArea().getEvents();

+        xmlhob = xmlMlsaDoc.getLibraryModuleSurfaceArea().getHobs();

+        xmlppi = xmlMlsaDoc.getLibraryModuleSurfaceArea().getPPIs();

+        xmlvb = xmlMlsaDoc.getLibraryModuleSurfaceArea().getVariables();

+        xmlbm = xmlMlsaDoc.getLibraryModuleSurfaceArea().getBootModes();

+        xmlst = xmlMlsaDoc.getLibraryModuleSurfaceArea().getSystemTables();

+        xmldh = xmlMlsaDoc.getLibraryModuleSurfaceArea().getDataHubs();

+        xmlfs = xmlMlsaDoc.getLibraryModuleSurfaceArea().getFormsets();

+        xmlgu = xmlMlsaDoc.getLibraryModuleSurfaceArea().getGuids();

+        xmlet = xmlMlsaDoc.getLibraryModuleSurfaceArea().getExterns();

+        xmlpcd = xmlMlsaDoc.getLibraryModuleSurfaceArea().getPCDs();

+        xmlbo = xmlMlsaDoc.getLibraryModuleSurfaceArea().getBuildOptions();

+

+        this.showMlsaHeader(ModuleMain.VIEW);

+        reloadTreeAndTable(ModuleMain.OPENED);

+        jMenuEditAdd.setEnabled(true);

+    }

+

+    /**

+     Open specificed Mlbd file and read its content

+     

+     @param strMlbdFilePath The input data of Mlbd File Path

+     

+     **/

+    private void openMlbdFile(String strMlbdFilePath) {

+        Log.log("Open Mlbd", strMlbdFilePath);

+        try {

+            File mlbdFile = new File(strMlbdFilePath);

+            xmlMlbdDoc = (LibraryModuleBuildDescriptionDocument) XmlObject.Factory.parse(mlbdFile);

+            this.currentModule = strMlbdFilePath;

+            this.saveFileName = strMlbdFilePath;

+            this.currentModuleType = 4;

+        } catch (IOException e) {

+            Log.err("Open Mlbd " + strMlbdFilePath, e.getMessage());

+            return;

+        } catch (XmlException e) {

+            Log.err("Open Mlbd " + strMlbdFilePath, e.getMessage());

+            return;

+        } catch (Exception e) {

+            Log.err("Open Mlbd " + strMlbdFilePath, "Invalid file type");

+            return;

+        }

+

+        xmlmlbdh = xmlMlbdDoc.getLibraryModuleBuildDescription().getMbdLibHeader();

+        xmllib = xmlMlbdDoc.getLibraryModuleBuildDescription().getLibraries();

+        xmlsf = xmlMlbdDoc.getLibraryModuleBuildDescription().getSourceFiles();

+        xmlic = xmlMlbdDoc.getLibraryModuleBuildDescription().getIncludes();

+        xmlpl = xmlMlbdDoc.getLibraryModuleBuildDescription().getProtocols();

+        xmlen = xmlMlbdDoc.getLibraryModuleBuildDescription().getEvents();

+        xmlhob = xmlMlbdDoc.getLibraryModuleBuildDescription().getHobs();

+        xmlppi = xmlMlbdDoc.getLibraryModuleBuildDescription().getPPIs();

+        xmlvb = xmlMlbdDoc.getLibraryModuleBuildDescription().getVariables();

+        xmlbm = xmlMlbdDoc.getLibraryModuleBuildDescription().getBootModes();

+        xmlst = xmlMlbdDoc.getLibraryModuleBuildDescription().getSystemTables();

+        xmldh = xmlMlbdDoc.getLibraryModuleBuildDescription().getDataHubs();

+        xmlfs = xmlMlbdDoc.getLibraryModuleBuildDescription().getFormsets();

+        xmlgu = xmlMlbdDoc.getLibraryModuleBuildDescription().getGuids();

+        xmlet = xmlMlbdDoc.getLibraryModuleBuildDescription().getExterns();

+        xmlpcd = xmlMlbdDoc.getLibraryModuleBuildDescription().getPCDs();

+        xmlbo = xmlMlbdDoc.getLibraryModuleBuildDescription().getBuildOptions();

+

+        this.showMlbdHeader(ModuleMain.VIEW);

+        reloadTreeAndTable(ModuleMain.OPENED);

+        jMenuEditAdd.setEnabled(true);

+    }

+

+    /**

+     Create an empty tree if no file is open

+     

+     **/

+    private void makeEmptyTree() {

+        dmtnRoot = new IDefaultMutableTreeNode("No Msa/Mbd file opened", -1, -1);

+        iTree = new ITree(dmtnRoot);

+        jScrollPaneTree.setViewportView(iTree);

+    }

+

+    /**

+     Create the tree to display all components of current open file.

+     First to check if the component is null or not

+     If not null, hangs it to the tree

+     If null, skip it

+     

+     **/

+    private void makeTree() {

+        iTree.removeAll();

+

+        //

+        //Make an empty tree when closing

+        //

+        if (this.currentModuleType == 0) {

+            makeEmptyTree();

+            return;

+        }

+

+        //

+        //Msa File

+        //

+        if (this.currentModuleType == 1) {

+            //

+            //Add MsaHeader Node

+            //

+            if (xmlmh != null) {

+                dmtnRoot = new IDefaultMutableTreeNode(xmlmh.getBaseName().getStringValue(),

+                                                       IDefaultMutableTreeNode.MSA_HEADER,

+                                                       IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE);

+            } else {

+                makeEmptyTree();

+                return;

+            }

+

+            //

+            //Add LibraryClassDefinitions Node

+            //

+            if (xmllcd != null && xmllcd.getLibraryClassList().size() > 0) {

+                IDefaultMutableTreeNode libraryClassDefinitions = new IDefaultMutableTreeNode(

+                                                                                              "Library Class Definitions",

+                                                                                              IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS,

+                                                                                              IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE);

+                for (int indexI = 0; indexI < xmllcd.getLibraryClassList().size(); indexI++) {

+                    libraryClassDefinitions

+                                           .add(new IDefaultMutableTreeNode(

+                                                                            xmllcd.getLibraryClassArray(indexI)

+                                                                                  .getStringValue(),

+                                                                            IDefaultMutableTreeNode.LIBRARY_CLASS_DEFINITION,

+                                                                            IDefaultMutableTreeNode.OPERATION_NULL));

+                }

+                dmtnRoot.add(libraryClassDefinitions);

+            }

+        }

+

+        //

+        //Mbd File

+        //

+        if (this.currentModuleType == 2) {

+            //

+            //Add MsaHeader Node

+            //

+            if (xmlmbdh != null) {

+                dmtnRoot = new IDefaultMutableTreeNode(xmlmbdh.getBaseName().getStringValue(),

+                                                       IDefaultMutableTreeNode.MBD_HEADER,

+                                                       IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE);

+            } else {

+                makeEmptyTree();

+                return;

+            }

+

+            //

+            //Add Libraries Node

+            //

+            if (xmllib != null) {

+                IDefaultMutableTreeNode libraries = new IDefaultMutableTreeNode(

+                                                                                "Libraries",

+                                                                                IDefaultMutableTreeNode.LIBRARIES,

+                                                                                IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+                if (xmllib.getArchList().size() > 0) {

+                    IDefaultMutableTreeNode librariesArch = new IDefaultMutableTreeNode(

+                                                                                        "Arch",

+                                                                                        IDefaultMutableTreeNode.LIBRARIES_ARCH,

+                                                                                        IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+                    for (int indexI = 0; indexI < xmllib.getArchList().size(); indexI++) {

+                        librariesArch.add(new IDefaultMutableTreeNode(xmllib.getArchArray(indexI).getArchType()

+                                                                            .toString(),

+                                                                      IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM,

+                                                                      IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                      indexI));

+                    }

+                    libraries.add(librariesArch);

+                }

+                if (xmllib.getLibraryList().size() > 0) {

+                    IDefaultMutableTreeNode library = new IDefaultMutableTreeNode(

+                                                                                  "Library",

+                                                                                  IDefaultMutableTreeNode.LIBRARIES_LIBRARY,

+                                                                                  IDefaultMutableTreeNode.OPERATION_ADD_UPDATE_DELETE);

+                    for (int indexI = 0; indexI < xmllib.getLibraryList().size(); indexI++) {

+                        library.add(new IDefaultMutableTreeNode(xmllib.getLibraryArray(indexI).getStringValue(),

+                                                                IDefaultMutableTreeNode.LIBRARIES_LIBRARY_ITEM,

+                                                                IDefaultMutableTreeNode.OPERATION_DELETE));

+                    }

+                    libraries.add(library);

+                }

+                dmtnRoot.add(libraries);

+            }

+        }

+

+        //

+        //MLsa File

+        //

+        if (this.currentModuleType == 3) {

+            //

+            //Add MsaHeader Node

+            //

+            if (xmlmlh != null) {

+                dmtnRoot = new IDefaultMutableTreeNode(xmlmlh.getBaseName().getStringValue(),

+                                                       IDefaultMutableTreeNode.MLSA_HEADER,

+                                                       IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE);

+            } else {

+                makeEmptyTree();

+                return;

+            }

+

+            //

+            //Add LibraryClassDefinitions Node

+            //

+            if (xmllcd != null && xmllcd.getLibraryClassList().size() > 0) {

+                IDefaultMutableTreeNode libraryClassDefinitions = new IDefaultMutableTreeNode(

+                                                                                              "Library Class Definitions",

+                                                                                              IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS,

+                                                                                              IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE);

+                for (int indexI = 0; indexI < xmllcd.getLibraryClassList().size(); indexI++) {

+                    libraryClassDefinitions

+                                           .add(new IDefaultMutableTreeNode(

+                                                                            xmllcd.getLibraryClassArray(indexI)

+                                                                                  .getStringValue(),

+                                                                            IDefaultMutableTreeNode.LIBRARY_CLASS_DEFINITION,

+                                                                            IDefaultMutableTreeNode.OPERATION_NULL));

+                }

+                dmtnRoot.add(libraryClassDefinitions);

+            }

+        }

+

+        //

+        //Mlbd File

+        //

+        if (this.currentModuleType == 4) {

+            //

+            //Add MsaHeader Node

+            //

+            if (xmlmlbdh != null) {

+                dmtnRoot = new IDefaultMutableTreeNode(xmlmlbdh.getBaseName().getStringValue(),

+                                                       IDefaultMutableTreeNode.MLBD_HEADER,

+                                                       IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE);

+            } else {

+                makeEmptyTree();

+                return;

+            }

+

+            //

+            //Add Libraries Node

+            //

+            if (xmllib != null) {

+                IDefaultMutableTreeNode libraries = new IDefaultMutableTreeNode(

+                                                                                "Libraries",

+                                                                                IDefaultMutableTreeNode.LIBRARIES,

+                                                                                IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+                if (xmllib.getArchList().size() > 0) {

+                    IDefaultMutableTreeNode librariesArch = new IDefaultMutableTreeNode(

+                                                                                        "Arch",

+                                                                                        IDefaultMutableTreeNode.LIBRARIES_ARCH,

+                                                                                        IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+                    for (int indexI = 0; indexI < xmllib.getArchList().size(); indexI++) {

+                        librariesArch.add(new IDefaultMutableTreeNode(xmllib.getArchArray(indexI).getArchType()

+                                                                            .toString(),

+                                                                      IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM,

+                                                                      IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                      indexI));

+                    }

+                    libraries.add(librariesArch);

+                }

+                if (xmllib.getLibraryList().size() > 0) {

+                    IDefaultMutableTreeNode library = new IDefaultMutableTreeNode(

+                                                                                  "Library",

+                                                                                  IDefaultMutableTreeNode.LIBRARIES_LIBRARY,

+                                                                                  IDefaultMutableTreeNode.OPERATION_ADD_UPDATE_DELETE);

+                    for (int indexI = 0; indexI < xmllib.getLibraryList().size(); indexI++) {

+                        library.add(new IDefaultMutableTreeNode(xmllib.getLibraryArray(indexI).getStringValue(),

+                                                                IDefaultMutableTreeNode.LIBRARIES_LIBRARY_ITEM,

+                                                                IDefaultMutableTreeNode.OPERATION_DELETE));

+                    }

+                    libraries.add(library);

+                }

+                dmtnRoot.add(libraries);

+            }

+        }

+

+        //

+        //Add SourceFiles Node

+        //

+        if (xmlsf != null) {

+            IDefaultMutableTreeNode sourceFiles = new IDefaultMutableTreeNode(

+                                                                              "Source Files",

+                                                                              IDefaultMutableTreeNode.SOURCEFILES,

+                                                                              IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlsf.getArchList().size() > 0) {

+                IDefaultMutableTreeNode sourceFilesArch = new IDefaultMutableTreeNode(

+                                                                                      "Arch",

+                                                                                      IDefaultMutableTreeNode.SOURCEFILES_ARCH,

+                                                                                      IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+                for (int indexI = 0; indexI < xmlsf.getArchList().size(); indexI++) {

+                    sourceFilesArch

+                                   .add(new IDefaultMutableTreeNode(

+                                                                    xmlsf.getArchArray(indexI).getArchType().toString(),

+                                                                    IDefaultMutableTreeNode.SOURCEFILES_ARCH_ITEM,

+                                                                    IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                    indexI));

+                }

+                sourceFiles.add(sourceFilesArch);

+            }

+            if (xmlsf.getFilenameList().size() > 0) {

+                IDefaultMutableTreeNode sourceFilesFileName = new IDefaultMutableTreeNode(

+                                                                                          "File Name",

+                                                                                          IDefaultMutableTreeNode.SOURCEFILES_FILENAME,

+                                                                                          IDefaultMutableTreeNode.OPERATION_ADD_UPDATE_DELETE);

+                for (int indexI = 0; indexI < xmlsf.getFilenameList().size(); indexI++) {

+                    sourceFilesFileName

+                                       .add(new IDefaultMutableTreeNode(

+                                                                        xmlsf.getFilenameArray(indexI).getStringValue(),

+                                                                        IDefaultMutableTreeNode.SOURCEFILES_FILENAME_ITEM,

+                                                                        IDefaultMutableTreeNode.OPERATION_DELETE));

+                }

+                sourceFiles.add(sourceFilesFileName);

+            }

+            dmtnRoot.add(sourceFiles);

+        }

+

+        //

+        //Add includes

+        //

+        if (xmlic != null) {

+            IDefaultMutableTreeNode includes = new IDefaultMutableTreeNode("Includes",

+                                                                           IDefaultMutableTreeNode.INCLUDES,

+                                                                           IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlic.getArchList().size() > 0) {

+                IDefaultMutableTreeNode includesArch = new IDefaultMutableTreeNode(

+                                                                                   "Arch",

+                                                                                   IDefaultMutableTreeNode.INCLUDES_ARCH,

+                                                                                   IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+                for (int indexI = 0; indexI < xmlic.getArchList().size(); indexI++) {

+                    includesArch.add(new IDefaultMutableTreeNode(xmlic.getArchArray(indexI).getArchType().toString(),

+                                                                 IDefaultMutableTreeNode.INCLUDES_ARCH_ITEM,

+                                                                 IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                 indexI));

+                }

+                includes.add(includesArch);

+            }

+            if (xmlic.getPackageNameList().size() > 0) {

+                IDefaultMutableTreeNode includesPackageName = new IDefaultMutableTreeNode(

+                                                                                          "Package Name",

+                                                                                          IDefaultMutableTreeNode.INCLUDES_PACKAGENAME,

+                                                                                          IDefaultMutableTreeNode.OPERATION_ADD_UPDATE_DELETE);

+                for (int indexI = 0; indexI < xmlic.getPackageNameList().size(); indexI++) {

+                    includesPackageName

+                                       .add(new IDefaultMutableTreeNode(

+                                                                        xmlic.getPackageNameArray(indexI)

+                                                                             .getStringValue(),

+                                                                        IDefaultMutableTreeNode.INCLUDES_PACKAGENAME_ITEM,

+                                                                        IDefaultMutableTreeNode.OPERATION_DELETE));

+                }

+                includes.add(includesPackageName);

+            }

+            dmtnRoot.add(includes);

+        }

+

+        //

+        //Add protocols

+        //

+        if (xmlpl != null) {

+            IDefaultMutableTreeNode dmtnProtocols = new IDefaultMutableTreeNode(

+                                                                                "Protocols",

+                                                                                IDefaultMutableTreeNode.PROTOCOLS,

+                                                                                IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            IDefaultMutableTreeNode dmtnProtocol = new IDefaultMutableTreeNode(

+                                                                               "Protocol",

+                                                                               IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL,

+                                                                               IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            IDefaultMutableTreeNode dmtnProtocolNotify = new IDefaultMutableTreeNode(

+                                                                                     "Protocol Notify",

+                                                                                     IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY,

+                                                                                     IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlpl.getProtocolList().size() > 0) {

+                for (int indexI = 0; indexI < xmlpl.getProtocolList().size(); indexI++) {

+                    dmtnProtocol.add(new IDefaultMutableTreeNode(xmlpl.getProtocolArray(indexI).getStringValue(),

+                                                                 IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL_ITEM,

+                                                                 IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                 indexI));

+                }

+                dmtnProtocols.add(dmtnProtocol);

+            }

+            if (xmlpl.getProtocolNotifyList().size() > 0) {

+                for (int indexI = 0; indexI < xmlpl.getProtocolNotifyList().size(); indexI++) {

+                    dmtnProtocolNotify

+                                      .add(new IDefaultMutableTreeNode(

+                                                                       xmlpl.getProtocolNotifyArray(indexI)

+                                                                            .getStringValue(),

+                                                                       IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY_ITEM,

+                                                                       IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                       indexI));

+                }

+                dmtnProtocols.add(dmtnProtocolNotify);

+            }

+            dmtnRoot.add(dmtnProtocols);

+        }

+

+        //

+        //Add events

+        //

+        if (xmlen != null) {

+            IDefaultMutableTreeNode dmtnEvents = new IDefaultMutableTreeNode(

+                                                                             "Events",

+                                                                             IDefaultMutableTreeNode.EVENTS,

+                                                                             IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            IDefaultMutableTreeNode dmtnCreateEvents = new IDefaultMutableTreeNode(

+                                                                                   "Create",

+                                                                                   IDefaultMutableTreeNode.EVENTS_CREATEEVENTS,

+                                                                                   IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            IDefaultMutableTreeNode dmtnSignalEvents = new IDefaultMutableTreeNode(

+                                                                                   "Signal",

+                                                                                   IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS,

+                                                                                   IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlen.getCreateEvents() != null && xmlen.getCreateEvents().getEventList().size() > 0) {

+                for (int indexI = 0; indexI < xmlen.getCreateEvents().getEventList().size(); indexI++) {

+                    dmtnCreateEvents.add(new IDefaultMutableTreeNode(xmlen.getCreateEvents().getEventArray(indexI)

+                                                                          .getCName(),

+                                                                     IDefaultMutableTreeNode.EVENTS_CREATEEVENTS_ITEM,

+                                                                     IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                     indexI));

+                }

+                dmtnEvents.add(dmtnCreateEvents);

+            }

+            if (xmlen.getSignalEvents() != null && xmlen.getSignalEvents().getEventList().size() > 0) {

+                for (int indexI = 0; indexI < xmlen.getSignalEvents().getEventList().size(); indexI++) {

+                    dmtnSignalEvents.add(new IDefaultMutableTreeNode(xmlen.getSignalEvents().getEventArray(indexI)

+                                                                          .getCName(),

+                                                                     IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS_ITEM,

+                                                                     IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                     indexI));

+                }

+                dmtnEvents.add(dmtnSignalEvents);

+            }

+            dmtnRoot.add(dmtnEvents);

+        }

+

+        //

+        //Add hobs

+        //

+        if (xmlhob != null) {

+            IDefaultMutableTreeNode dmtnHobs = new IDefaultMutableTreeNode("Hobs", IDefaultMutableTreeNode.HOBS,

+                                                                           IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlhob.getHobList().size() > 0) {

+                for (int indexI = 0; indexI < xmlhob.getHobList().size(); indexI++) {

+                    dmtnHobs.add(new IDefaultMutableTreeNode(xmlhob.getHobArray(indexI).getName(),

+                                                             IDefaultMutableTreeNode.HOBS_HOB_ITEM,

+                                                             IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE, indexI));

+                }

+            }

+            dmtnRoot.add(dmtnHobs);

+        }

+

+        //

+        //Add ppis

+        //

+        if (xmlppi != null) {

+            IDefaultMutableTreeNode dmtnPpis = new IDefaultMutableTreeNode("Ppis", IDefaultMutableTreeNode.PPIS,

+                                                                           IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            IDefaultMutableTreeNode dmtnPpi = new IDefaultMutableTreeNode("Ppi", IDefaultMutableTreeNode.PPIS_PPI,

+                                                                          IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            IDefaultMutableTreeNode dmtnPpiNotify = new IDefaultMutableTreeNode(

+                                                                                "Ppi Notify",

+                                                                                IDefaultMutableTreeNode.PPIS_PPINOTIFY,

+                                                                                IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlppi.getPpiList().size() > 0) {

+                for (int indexI = 0; indexI < xmlppi.getPpiList().size(); indexI++) {

+                    dmtnPpi.add(new IDefaultMutableTreeNode(xmlppi.getPpiArray(indexI).getStringValue(),

+                                                            IDefaultMutableTreeNode.PPIS_PPI_ITEM,

+                                                            IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE, indexI));

+                }

+                dmtnPpis.add(dmtnPpi);

+            }

+            if (xmlppi.getPpiNotifyList().size() > 0) {

+                for (int indexI = 0; indexI < xmlppi.getPpiNotifyList().size(); indexI++) {

+                    dmtnPpiNotify.add(new IDefaultMutableTreeNode(xmlppi.getPpiNotifyArray(indexI).getStringValue(),

+                                                                  IDefaultMutableTreeNode.PPIS_PPINOTIFY_ITEM,

+                                                                  IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                  indexI));

+                }

+                dmtnPpis.add(dmtnPpiNotify);

+            }

+            dmtnRoot.add(dmtnPpis);

+        }

+

+        //

+        //Add variables

+        //

+        if (xmlvb != null) {

+            IDefaultMutableTreeNode dmtnVariables = new IDefaultMutableTreeNode(

+                                                                                "Variables",

+                                                                                IDefaultMutableTreeNode.VARIABLES,

+                                                                                IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlvb.getVariableList().size() > 0) {

+                for (int indexI = 0; indexI < xmlvb.getVariableList().size(); indexI++) {

+                    dmtnVariables.add(new IDefaultMutableTreeNode(xmlvb.getVariableArray(indexI).getString(),

+                                                                  IDefaultMutableTreeNode.VARIABLES_VARIABLE_ITEM,

+                                                                  IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                  indexI));

+                }

+            }

+            dmtnRoot.add(dmtnVariables);

+        }

+

+        //

+        //Add bootmodes

+        //

+        if (xmlbm != null) {

+            IDefaultMutableTreeNode dmtnBootModes = new IDefaultMutableTreeNode(

+                                                                                "BootModes",

+                                                                                IDefaultMutableTreeNode.BOOTMODES,

+                                                                                IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlbm.getBootModeList().size() > 0) {

+                for (int indexI = 0; indexI < xmlbm.getBootModeList().size(); indexI++) {

+                    dmtnBootModes.add(new IDefaultMutableTreeNode(xmlbm.getBootModeArray(indexI).getBootModeName()

+                                                                       .toString(),

+                                                                  IDefaultMutableTreeNode.BOOTMODES_BOOTMODE_ITEM,

+                                                                  IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                  indexI));

+                }

+            }

+            dmtnRoot.add(dmtnBootModes);

+        }

+

+        //

+        //Add systemtables

+        //

+        if (xmlst != null) {

+            IDefaultMutableTreeNode dmtnSystemTables = new IDefaultMutableTreeNode(

+                                                                                   "SystemTables",

+                                                                                   IDefaultMutableTreeNode.SYSTEMTABLES,

+                                                                                   IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlst.getSystemTableList().size() > 0) {

+                for (int indexI = 0; indexI < xmlst.getSystemTableList().size(); indexI++) {

+                    dmtnSystemTables

+                                    .add(new IDefaultMutableTreeNode(

+                                                                     xmlst.getSystemTableArray(indexI).getEntry(),

+                                                                     IDefaultMutableTreeNode.SYSTEMTABLES_SYSTEMTABLE_ITEM,

+                                                                     IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                     indexI));

+                }

+            }

+            dmtnRoot.add(dmtnSystemTables);

+        }

+

+        //

+        //Add datahubs

+        //

+        if (xmldh != null) {

+            IDefaultMutableTreeNode dmtnDataHubs = new IDefaultMutableTreeNode(

+                                                                               "DataHubs",

+                                                                               IDefaultMutableTreeNode.DATAHUBS,

+                                                                               IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmldh.getDataHubRecordList().size() > 0) {

+                for (int indexI = 0; indexI < xmldh.getDataHubRecordList().size(); indexI++) {

+                    dmtnDataHubs.add(new IDefaultMutableTreeNode(xmldh.getDataHubRecordArray(indexI).getStringValue(),

+                                                                 IDefaultMutableTreeNode.DATAHUBS_DATAHUB_ITEM,

+                                                                 IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                 indexI));

+                }

+            }

+            dmtnRoot.add(dmtnDataHubs);

+        }

+

+        //

+        //Add formsets

+        //

+        if (xmlfs != null) {

+            IDefaultMutableTreeNode dmtnFormsets = new IDefaultMutableTreeNode(

+                                                                               "Formsets",

+                                                                               IDefaultMutableTreeNode.FORMSETS,

+                                                                               IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlfs.getFormsetList().size() > 0) {

+                for (int indexI = 0; indexI < xmlfs.getFormsetList().size(); indexI++) {

+                    dmtnFormsets.add(new IDefaultMutableTreeNode(xmlfs.getFormsetArray(indexI).getStringValue(),

+                                                                 IDefaultMutableTreeNode.FORMSETS_FORMSET_ITEM,

+                                                                 IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE,

+                                                                 indexI));

+                }

+            }

+            dmtnRoot.add(dmtnFormsets);

+        }

+

+        //

+        //Add guids

+        //

+        if (xmlgu != null) {

+            IDefaultMutableTreeNode dmtnGuids = new IDefaultMutableTreeNode(

+                                                                            "Guids",

+                                                                            IDefaultMutableTreeNode.GUIDS,

+                                                                            IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlgu.getGuidEntryList().size() > 0) {

+                for (int indexI = 0; indexI < xmlgu.getGuidEntryList().size(); indexI++) {

+                    dmtnGuids.add(new IDefaultMutableTreeNode(xmlgu.getGuidEntryArray(indexI).getCName(),

+                                                              IDefaultMutableTreeNode.GUIDS_GUIDENTRY_ITEM,

+                                                              IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE, indexI));

+                }

+            }

+            dmtnRoot.add(dmtnGuids);

+        }

+

+        //

+        //Add externs

+        //

+        if (xmlet != null) {

+            IDefaultMutableTreeNode dmtnExterns = new IDefaultMutableTreeNode(

+                                                                              "Externs",

+                                                                              IDefaultMutableTreeNode.EXTERNS,

+                                                                              IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlet.getExternList().size() > 0) {

+                for (int indexI = 0; indexI < xmlet.getExternList().size(); indexI++) {

+                    dmtnExterns

+                               .add(new IDefaultMutableTreeNode("Extern " + Integer.valueOf(indexI + 1),

+                                                                IDefaultMutableTreeNode.EXTERNS_EXTERN_ITEM,

+                                                                IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE, indexI));

+                }

+            }

+            dmtnRoot.add(dmtnExterns);

+        }

+

+        //

+        //Add pcds

+        //

+        if (xmlpcd != null) {

+            IDefaultMutableTreeNode dmtnPCDs = new IDefaultMutableTreeNode("PCDs", IDefaultMutableTreeNode.PCDS,

+                                                                           IDefaultMutableTreeNode.OPERATION_ADD_DELETE);

+            if (xmlpcd.getPcdDataList().size() > 0) {

+                for (int indexI = 0; indexI < xmlpcd.getPcdDataList().size(); indexI++) {

+                    dmtnPCDs.add(new IDefaultMutableTreeNode(xmlpcd.getPcdDataArray(indexI).getCName(),

+                                                             IDefaultMutableTreeNode.PCDS_PCDDATA_ITEM,

+                                                             IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE, indexI));

+                }

+            }

+            dmtnRoot.add(dmtnPCDs);

+        }

+

+        iTree = new ITree(dmtnRoot);

+        iTree.addMouseListener(this);

+        iTree.addTreeSelectionListener(this);

+        jScrollPaneTree.setViewportView(iTree);

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.WindowListener#windowClosing(java.awt.event.WindowEvent)

+     *

+     * Override windowClosing to popup warning message to confirm quit

+     * 

+     */

+    public void windowClosing(WindowEvent arg0) {

+        this.onExit();

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)

+     * 

+     * Override mouseClicked to check if need display popup menu

+     * 

+     */

+    public void mouseClicked(MouseEvent arg0) {

+        if (arg0.getButton() == MouseEvent.BUTTON1) {

+

+        }

+        if (arg0.getButton() == MouseEvent.BUTTON3) {

+            jPopupMenu.show(arg0.getComponent(), arg0.getX(), arg0.getY());

+        }

+    }

+

+    public void mouseEntered(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+

+    public void mouseExited(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+

+    public void mousePressed(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+

+    public void mouseReleased(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+    }

+

+    /**

+     Init popup menu

+     

+     **/

+    public void valueChanged(TreeSelectionEvent arg0) {

+        int intOperation = iTree.getSelectOperation();

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_NULL) {

+            setMenuItemAddEnabled(false);

+            setMenuItemUpdateEnabled(false);

+            setMenuItemDeleteEnabled(false);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_ADD) {

+            setMenuItemAddEnabled(true);

+            setMenuItemUpdateEnabled(false);

+            setMenuItemDeleteEnabled(false);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_UPDATE) {

+            setMenuItemAddEnabled(false);

+            setMenuItemUpdateEnabled(true);

+            setMenuItemDeleteEnabled(false);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_DELETE) {

+            setMenuItemAddEnabled(false);

+            setMenuItemUpdateEnabled(false);

+            setMenuItemDeleteEnabled(true);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_ADD_UPDATE) {

+            setMenuItemAddEnabled(true);

+            setMenuItemUpdateEnabled(true);

+            setMenuItemDeleteEnabled(false);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_ADD_DELETE) {

+            setMenuItemAddEnabled(true);

+            setMenuItemUpdateEnabled(false);

+            setMenuItemDeleteEnabled(true);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_UPDATE_DELETE) {

+            setMenuItemAddEnabled(false);

+            setMenuItemUpdateEnabled(true);

+            setMenuItemDeleteEnabled(true);

+        }

+        if (intOperation == IDefaultMutableTreeNode.OPERATION_ADD_UPDATE_DELETE) {

+            setMenuItemAddEnabled(true);

+            setMenuItemUpdateEnabled(true);

+            setMenuItemDeleteEnabled(true);

+        }

+        viewCurrentModule();

+    }

+

+    /**

+     Enable/Disable add menu item

+     

+     **/

+    private void setMenuItemAddEnabled(boolean isEnable) {

+        jMenuItemPopupAdd.setEnabled(isEnable);

+    }

+

+    /**

+     Enable/Disable update menu item

+     

+     **/

+    private void setMenuItemUpdateEnabled(boolean isEnable) {

+        jMenuItemPopupUpdate.setEnabled(isEnable);

+        jMenuItemEditUpdate.setEnabled(isEnable);

+    }

+

+    /**

+     Enable/Disable delete menu item

+     

+     **/

+    private void setMenuItemDeleteEnabled(boolean isEnable) {

+        jMenuItemPopupDelete.setEnabled(isEnable);

+        jMenuItemEditDelete.setEnabled(isEnable);

+    }

+

+    /**

+     Close current open module

+

+     **/

+    private void closeCurrentModule() {

+        cleanAllXml();

+

+        reloadTreeAndTable(ModuleMain.CLOSED);

+        setMenuItemAddEnabled(false);

+        setMenuItemUpdateEnabled(false);

+        setMenuItemDeleteEnabled(false);

+        cleanDesktopPane();

+    }

+

+    /**

+     Remove all Internal Frame of Desktop Pane

+     

+     **/

+    private void cleanDesktopPane() {

+        JInternalFrame[] iif = this.jDesktopPane.getAllFrames();

+        for (int index = 0; index < iif.length; index++) {

+            iif[index].dispose();

+        }

+    }

+

+    /**

+     Set all xml document null

+     

+     **/

+    private void cleanAllXml() {

+        this.currentModule = "";

+        this.saveFileName = "";

+        this.currentModuleType = 0;

+        this.currentNodeType = 0;

+

+        xmlMsaDoc = null;

+        xmlMbdDoc = null;

+        xmlMlsaDoc = null;

+        xmlMlbdDoc = null;

+        xmlmh = null;

+        xmllcd = null;

+        xmllib = null;

+        xmlsf = null;

+        xmlic = null;

+        xmlpl = null;

+        xmlen = null;

+        xmlhob = null;

+        xmlppi = null;

+        xmlvb = null;

+        xmlbm = null;

+        xmlst = null;

+        xmldh = null;

+        xmlfs = null;

+        xmlgu = null;

+        xmlet = null;

+        xmlpcd = null;

+        xmlbo = null;

+    }

+

+    /**

+     Execute add operation for current node 

+     

+     @param intCategory The category of current node

+     @param intLocation The location of current node

+     

+     **/

+    private void addCurrentModule(int intCategory, int intLocation) {

+        //

+        //Add new libraries

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES

+            || intCategory == IDefaultMutableTreeNode.LIBRARIES_LIBRARY

+            || intCategory == IDefaultMutableTreeNode.LIBRARIES_ARCH) {

+            showLibraries(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new sourcefiles

+        //

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES

+            || intCategory == IDefaultMutableTreeNode.SOURCEFILES_FILENAME

+            || intCategory == IDefaultMutableTreeNode.SOURCEFILES_ARCH) {

+            showSourceFiles(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new includes

+        //

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES

+            || intCategory == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME

+            || intCategory == IDefaultMutableTreeNode.INCLUDES_ARCH) {

+            showIncludes(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new protocols

+        //

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS

+            || intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL

+            || intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY) {

+            showProtocols(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new events

+        //

+        if (intCategory == IDefaultMutableTreeNode.EVENTS || intCategory == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS

+            || intCategory == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS) {

+            showEvents(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new hobs

+        //

+        if (intCategory == IDefaultMutableTreeNode.HOBS || intCategory == IDefaultMutableTreeNode.HOBS_HOB_ITEM) {

+            showHobs(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new ppis

+        //

+        if (intCategory == IDefaultMutableTreeNode.PPIS || intCategory == IDefaultMutableTreeNode.PPIS_PPI

+            || intCategory == IDefaultMutableTreeNode.PPIS_PPINOTIFY) {

+            showPpis(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new variables

+        //

+        if (intCategory == IDefaultMutableTreeNode.VARIABLES

+            || intCategory == IDefaultMutableTreeNode.VARIABLES_VARIABLE_ITEM) {

+            showVariables(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new BootModes

+        //

+        if (intCategory == IDefaultMutableTreeNode.BOOTMODES

+            || intCategory == IDefaultMutableTreeNode.BOOTMODES_BOOTMODE_ITEM) {

+            showBootModes(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new SystemTables

+        //

+        if (intCategory == IDefaultMutableTreeNode.SYSTEMTABLES

+            || intCategory == IDefaultMutableTreeNode.SYSTEMTABLES_SYSTEMTABLE_ITEM) {

+            showSystemTables(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new DataHubs

+        //

+        if (intCategory == IDefaultMutableTreeNode.DATAHUBS

+            || intCategory == IDefaultMutableTreeNode.DATAHUBS_DATAHUB_ITEM) {

+            showDataHubs(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new Formsets

+        //

+        if (intCategory == IDefaultMutableTreeNode.FORMSETS

+            || intCategory == IDefaultMutableTreeNode.FORMSETS_FORMSET_ITEM) {

+            showFormsets(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new Guids

+        //

+        if (intCategory == IDefaultMutableTreeNode.GUIDS || intCategory == IDefaultMutableTreeNode.GUIDS_GUIDENTRY_ITEM) {

+            showGuids(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new Externs

+        //

+        if (intCategory == IDefaultMutableTreeNode.EXTERNS

+            || intCategory == IDefaultMutableTreeNode.EXTERNS_EXTERN_ITEM) {

+            showExterns(ModuleMain.ADD, intCategory, -1);

+        }

+

+        //

+        //Add new PCDs

+        //

+        if (intCategory == IDefaultMutableTreeNode.PCDS || intCategory == IDefaultMutableTreeNode.PCDS_PCDDATA_ITEM) {

+            showPCDs(ModuleMain.ADD, intCategory, -1);

+        }

+    }

+

+    /**

+     Execute delete operation of current node

+     

+     @param intCategory The category of current node

+     @param intLocation The location of current node

+     

+     **/

+    private void deleteCurrentModule(int intCategory, int intLocation) {

+        //

+        // Delete Msa Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MSA_HEADER || intCategory == IDefaultMutableTreeNode.MBD_HEADER

+            || intCategory == IDefaultMutableTreeNode.MLSA_HEADER || intCategory == IDefaultMutableTreeNode.MLBD_HEADER) {

+            if (JOptionPane.showConfirmDialog(null, "The module will be deleted permanently, do you want to continue?") == JOptionPane.YES_OPTION) {

+                try {

+                    File f = new File(currentModule);

+                    f.delete();

+                    closeCurrentModule();

+                } catch (Exception e) {

+                    Log.err("Delete " + currentModule, e.getMessage());

+                }

+            } else {

+                return;

+            }

+        }

+

+        //

+        //Delete LIBRARY CLASS DEFINITIONS

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS) {

+            xmllcd = null;

+        }

+

+        //

+        //Delete Libraries

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES) {

+            xmllib = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES_LIBRARY) {

+            for (int indexI = xmllib.getLibraryList().size() - 1; indexI > -1; indexI--) {

+                xmllib.removeLibrary(indexI);

+            }

+            if (xmllib.getArchList().size() < 1 && xmllib.getLibraryList().size() < 1) {

+                xmllib = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES_ARCH) {

+            for (int indexI = xmllib.getArchList().size() - 1; indexI > -1; indexI--) {

+                xmllib.removeArch(indexI);

+            }

+            if (xmllib.getArchList().size() < 1 && xmllib.getLibraryList().size() < 1) {

+                xmllib = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM) {

+            xmllib.removeArch(intLocation);

+        }

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES_LIBRARY_ITEM) {

+            xmllib.removeLibrary(intLocation);

+        }

+

+        //

+        //Delete SourceFiles

+        //

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES) {

+            xmlsf = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES_FILENAME) {

+            for (int indexI = xmlsf.getFilenameList().size() - 1; indexI > -1; indexI--) {

+                xmlsf.removeFilename(indexI);

+            }

+            if (xmlsf.getArchList().size() < 1 && xmlsf.getFilenameList().size() < 1) {

+                xmlsf = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES_ARCH) {

+            for (int indexI = xmlsf.getArchList().size() - 1; indexI > -1; indexI--) {

+                xmlsf.removeArch(indexI);

+            }

+            if (xmlsf.getArchList().size() < 1 && xmlsf.getFilenameList().size() < 1) {

+                xmlsf = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES_ARCH_ITEM) {

+            xmlsf.removeArch(intLocation);

+        }

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES_FILENAME_ITEM) {

+            xmlsf.removeFilename(intLocation);

+        }

+

+        //

+        //Delete Includes

+        //

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES) {

+            xmlic = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME) {

+            for (int indexI = xmlic.getPackageNameList().size() - 1; indexI > -1; indexI--) {

+                xmlic.removePackageName(indexI);

+            }

+            if (xmlic.getArchList().size() < 1 && xmlic.getPackageNameList().size() < 1) {

+                xmlic = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES_ARCH) {

+            for (int indexI = xmlic.getArchList().size() - 1; indexI > -1; indexI--) {

+                xmlic.removeArch(indexI);

+            }

+            if (xmlic.getArchList().size() < 1 && xmlic.getPackageNameList().size() < 1) {

+                xmlic = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES_ARCH_ITEM) {

+            xmlic.removeArch(intLocation);

+        }

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME_ITEM) {

+            xmlic.removePackageName(intLocation);

+        }

+

+        //

+        //Delete Protocols

+        //

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS) {

+            xmlpl = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL) {

+            for (int indexI = xmlpl.getProtocolList().size() - 1; indexI > -1; indexI--) {

+                xmlpl.removeProtocol(indexI);

+            }

+            if (xmlpl.getProtocolList().size() < 1 && xmlpl.getProtocolNotifyList().size() < 1) {

+                xmlpl = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY) {

+            for (int indexI = xmlpl.getProtocolList().size() - 1; indexI > -1; indexI--) {

+                xmlpl.removeProtocolNotify(indexI);

+            }

+            if (xmlpl.getProtocolList().size() < 1 && xmlpl.getProtocolNotifyList().size() < 1) {

+                xmlpl = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL_ITEM) {

+            xmlpl.removeProtocol(intLocation);

+        }

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY_ITEM) {

+            xmlpl.removeProtocolNotify(intLocation);

+        }

+

+        //

+        //Delete Events

+        //

+        if (intCategory == IDefaultMutableTreeNode.EVENTS) {

+            xmlen = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS) {

+            for (int indexI = xmlen.getCreateEvents().getEventList().size() - 1; indexI > -1; indexI--) {

+                xmlen.getCreateEvents().removeEvent(indexI);

+            }

+            if (xmlen.getCreateEvents().getEventList().size() < 1 && xmlen.getSignalEvents().getEventList().size() < 1) {

+                xmlen = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS) {

+            for (int indexI = xmlen.getSignalEvents().getEventList().size() - 1; indexI > -1; indexI--) {

+                xmlen.getSignalEvents().removeEvent(indexI);

+            }

+            if (xmlen.getCreateEvents().getEventList().size() < 1 && xmlen.getSignalEvents().getEventList().size() < 1) {

+                xmlen = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS_ITEM) {

+            xmlen.getCreateEvents().removeEvent(intLocation);

+        }

+        if (intCategory == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS_ITEM) {

+            xmlen.getSignalEvents().removeEvent(intLocation);

+        }

+

+        //

+        //Delete Hobs

+        //

+        if (intCategory == IDefaultMutableTreeNode.HOBS) {

+            xmlhob = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.HOBS_HOB_ITEM) {

+            xmlhob.removeHob(intLocation);

+            if (xmlhob.getHobList().size() < 1) {

+                xmlhob = null;

+            }

+        }

+

+        //

+        //Delete Ppis

+        //

+        if (intCategory == IDefaultMutableTreeNode.PPIS) {

+            xmlppi = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.PPIS_PPI) {

+            for (int indexI = xmlppi.getPpiList().size() - 1; indexI > -1; indexI--) {

+                xmlppi.removePpi(indexI);

+            }

+            if (xmlppi.getPpiList().size() < 1 && xmlppi.getPpiNotifyList().size() < 1) {

+                xmlppi = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.PPIS_PPINOTIFY) {

+            for (int indexI = xmlppi.getPpiNotifyList().size() - 1; indexI > -1; indexI--) {

+                xmlppi.removePpiNotify(indexI);

+            }

+            if (xmlppi.getPpiList().size() < 1 && xmlppi.getPpiNotifyList().size() < 1) {

+                xmlppi = null;

+            }

+        }

+        if (intCategory == IDefaultMutableTreeNode.PPIS_PPI_ITEM) {

+            xmlppi.removePpi(intLocation);

+        }

+        if (intCategory == IDefaultMutableTreeNode.PPIS_PPINOTIFY_ITEM) {

+            xmlppi.removePpiNotify(intLocation);

+        }

+

+        //

+        //Delete Variables

+        //

+        if (intCategory == IDefaultMutableTreeNode.VARIABLES) {

+            xmlvb = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.VARIABLES_VARIABLE_ITEM) {

+            xmlvb.removeVariable(intLocation);

+            if (xmlvb.getVariableList().size() < 1) {

+                xmlvb = null;

+            }

+        }

+

+        //

+        //Delete BootModes

+        //

+        if (intCategory == IDefaultMutableTreeNode.BOOTMODES) {

+            xmlbm = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.BOOTMODES_BOOTMODE_ITEM) {

+            xmlbm.removeBootMode(intLocation);

+            if (xmlbm.getBootModeList().size() < 1) {

+                xmlbm = null;

+            }

+        }

+

+        //

+        //Delete SystemTables

+        //

+        if (intCategory == IDefaultMutableTreeNode.SYSTEMTABLES) {

+            xmlst = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.SYSTEMTABLES_SYSTEMTABLE_ITEM) {

+            xmlst.removeSystemTable(intLocation);

+            if (xmlst.getSystemTableList().size() < 1) {

+                xmlst = null;

+            }

+        }

+

+        //

+        //Delete DataHubs

+        //

+        if (intCategory == IDefaultMutableTreeNode.DATAHUBS) {

+            xmldh = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.DATAHUBS_DATAHUB_ITEM) {

+            xmldh.removeDataHubRecord(intLocation);

+            if (xmldh.getDataHubRecordList().size() < 1) {

+                xmldh = null;

+            }

+        }

+

+        //

+        //Delete Formsets

+        //

+        if (intCategory == IDefaultMutableTreeNode.FORMSETS) {

+            xmlfs = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.FORMSETS_FORMSET_ITEM) {

+            xmlfs.removeFormset(intLocation);

+            if (xmlfs.getFormsetList().size() < 1) {

+                xmlfs = null;

+            }

+        }

+

+        //

+        //Delete Guids

+        //

+        if (intCategory == IDefaultMutableTreeNode.GUIDS) {

+            xmlgu = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.GUIDS_GUIDENTRY_ITEM) {

+            xmlgu.removeGuidEntry(intLocation);

+            if (xmlgu.getGuidEntryList().size() < 1) {

+                xmlgu = null;

+            }

+        }

+

+        //

+        //Delete Externs

+        //

+        if (intCategory == IDefaultMutableTreeNode.EXTERNS) {

+            xmlet = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.EXTERNS_EXTERN_ITEM) {

+            xmlet.removeExtern(intLocation);

+            if (xmlet.getExternList().size() < 1) {

+                xmlet = null;

+            }

+        }

+

+        //

+        //Delete PCDs

+        //

+        if (intCategory == IDefaultMutableTreeNode.PCDS) {

+            xmlpcd = null;

+        }

+        if (intCategory == IDefaultMutableTreeNode.PCDS_PCDDATA_ITEM) {

+            xmlpcd.removePcdData(intLocation);

+            if (xmlpcd.getPcdDataList().size() < 1) {

+                xmlpcd = null;

+            }

+        }

+        this.cleanDesktopPane();

+        reloadTreeAndTable(UPDATE_WITH_CHANGE);

+    }

+

+    /**

+     View current Module

+     

+     **/

+    private void viewCurrentModule() {

+        int intCategory = iTree.getSelectCategory();

+        int intLocation = iTree.getSelectLoaction();

+        //

+        //View Msa Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MSA_HEADER) {

+            showMsaHeader(ModuleMain.VIEW);

+        }

+

+        //

+        //View Mbd Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MBD_HEADER) {

+            showMbdHeader(ModuleMain.VIEW);

+        }

+

+        //

+        //View Msa Lib Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MLSA_HEADER) {

+            showMlsaHeader(ModuleMain.VIEW);

+        }

+

+        //

+        //View Mbd Lib Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MLBD_HEADER) {

+            showMlbdHeader(ModuleMain.VIEW);

+        }

+

+        //

+        //View Libraries

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES_LIBRARY

+            || intCategory == IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM) {

+            showLibraries(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View LIBRARY CLASS DEFINITIONS

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS) {

+            showLibraryClassDefinitions(ModuleMain.VIEW, intCategory);

+        }

+

+        //

+        //View Source Files

+        //

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES_FILENAME

+            || intCategory == IDefaultMutableTreeNode.SOURCEFILES_ARCH_ITEM) {

+            showSourceFiles(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Includes

+        //

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME

+            || intCategory == IDefaultMutableTreeNode.INCLUDES_ARCH_ITEM) {

+            showIncludes(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Protocols

+        //

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL_ITEM

+            || intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY_ITEM) {

+            showProtocols(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Hobs

+        //

+        if (intCategory == IDefaultMutableTreeNode.HOBS_HOB_ITEM) {

+            showHobs(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Events

+        //

+        if (intCategory == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS_ITEM

+            || intCategory == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS_ITEM) {

+            showEvents(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Ppis

+        //

+        if (intCategory == IDefaultMutableTreeNode.PPIS_PPI_ITEM

+            || intCategory == IDefaultMutableTreeNode.PPIS_PPINOTIFY_ITEM) {

+            showPpis(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Variables

+        //

+        if (intCategory == IDefaultMutableTreeNode.VARIABLES_VARIABLE_ITEM) {

+            showVariables(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View BootModes

+        //

+        if (intCategory == IDefaultMutableTreeNode.BOOTMODES_BOOTMODE_ITEM) {

+            showBootModes(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View SystemTables

+        //

+        if (intCategory == IDefaultMutableTreeNode.SYSTEMTABLES_SYSTEMTABLE_ITEM) {

+            showSystemTables(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View DataHubs

+        //

+        if (intCategory == IDefaultMutableTreeNode.DATAHUBS_DATAHUB_ITEM) {

+            showDataHubs(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Formsets

+        //

+        if (intCategory == IDefaultMutableTreeNode.FORMSETS_FORMSET_ITEM) {

+            showFormsets(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Guids

+        //

+        if (intCategory == IDefaultMutableTreeNode.GUIDS_GUIDENTRY_ITEM) {

+            showGuids(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View Externs

+        //

+        if (intCategory == IDefaultMutableTreeNode.EXTERNS_EXTERN_ITEM) {

+            showExterns(ModuleMain.VIEW, intCategory, intLocation);

+        }

+

+        //

+        //View PCDs

+        //

+        if (intCategory == IDefaultMutableTreeNode.PCDS_PCDDATA_ITEM) {

+            showPCDs(ModuleMain.VIEW, intCategory, intLocation);

+        }

+    }

+

+    /**

+     Execute update operation of current module

+     

+     @param intCategory The category of current node

+     @param intLocation The location of current node

+     

+     **/

+    private void updateCurrentModule(int intCategory, int intLocation) {

+        //

+        //Update Msa Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MSA_HEADER) {

+            showMsaHeader(ModuleMain.UPDATE);

+        }

+

+        //

+        //Update Mbd Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MBD_HEADER) {

+            showMbdHeader(ModuleMain.UPDATE);

+        }

+

+        //

+        //Update Msa Lib Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MLSA_HEADER) {

+            showMlsaHeader(ModuleMain.UPDATE);

+        }

+

+        //

+        //Update Mbd Lib Header

+        //

+        if (intCategory == IDefaultMutableTreeNode.MLBD_HEADER) {

+            showMlbdHeader(ModuleMain.UPDATE);

+        }

+

+        //

+        //Update Libraries

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARIES_LIBRARY

+            || intCategory == IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM) {

+            showLibraries(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update LIBRARY CLASS DEFINITIONS

+        //

+        if (intCategory == IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS) {

+            showLibraryClassDefinitions(ModuleMain.UPDATE, intCategory);

+        }

+

+        //

+        //Update Source Files

+        //

+        if (intCategory == IDefaultMutableTreeNode.SOURCEFILES_FILENAME

+            || intCategory == IDefaultMutableTreeNode.SOURCEFILES_ARCH_ITEM) {

+            showSourceFiles(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Includes

+        //

+        if (intCategory == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME

+            || intCategory == IDefaultMutableTreeNode.INCLUDES_ARCH_ITEM) {

+            showIncludes(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Protocols

+        //

+        if (intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL_ITEM

+            || intCategory == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY_ITEM) {

+            showProtocols(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Hobs

+        //

+        if (intCategory == IDefaultMutableTreeNode.HOBS_HOB_ITEM) {

+            showHobs(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Events

+        //

+        if (intCategory == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS_ITEM

+            || intCategory == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS_ITEM) {

+            showEvents(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Ppis

+        //

+        if (intCategory == IDefaultMutableTreeNode.PPIS_PPI_ITEM

+            || intCategory == IDefaultMutableTreeNode.PPIS_PPINOTIFY_ITEM) {

+            showPpis(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Variables

+        //

+        if (intCategory == IDefaultMutableTreeNode.VARIABLES_VARIABLE_ITEM) {

+            showVariables(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update BootModes

+        //

+        if (intCategory == IDefaultMutableTreeNode.BOOTMODES_BOOTMODE_ITEM) {

+            showBootModes(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update SystemTables

+        //

+        if (intCategory == IDefaultMutableTreeNode.SYSTEMTABLES_SYSTEMTABLE_ITEM) {

+            showSystemTables(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update DataHubs

+        //

+        if (intCategory == IDefaultMutableTreeNode.DATAHUBS_DATAHUB_ITEM) {

+            showDataHubs(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Formsets

+        //

+        if (intCategory == IDefaultMutableTreeNode.FORMSETS_FORMSET_ITEM) {

+            showFormsets(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Guids

+        //

+        if (intCategory == IDefaultMutableTreeNode.GUIDS_GUIDENTRY_ITEM) {

+            showGuids(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update Externs

+        //

+        if (intCategory == IDefaultMutableTreeNode.EXTERNS_EXTERN_ITEM) {

+            showExterns(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+

+        //

+        //Update PCDs

+        //

+        if (intCategory == IDefaultMutableTreeNode.PCDS_PCDDATA_ITEM) {

+            showPCDs(ModuleMain.UPDATE, intCategory, intLocation);

+        }

+    }

+

+    /**

+     Save current module

+     Call relevant function via different file types

+     

+     **/

+    private void saveCurrentModule() {

+        if (this.saveFileName == "") {

+            openFile(2, this.currentModuleType);

+        }

+        if (this.saveFileName == "") {

+            this.saveFileName = this.currentModule;

+            return;

+        } else {

+            switch (this.currentModuleType) {

+            case 1:

+                saveMsa();

+                break;

+            case 2:

+                saveMbd();

+                break;

+            case 3:

+                saveMlsa();

+                break;

+            case 4:

+                saveMlbd();

+                break;

+            }

+

+        }

+

+        reloadTreeAndTable(SAVE_WITH_CHANGE);

+    }

+

+    /**

+     Save current module as

+     

+     **/

+    private void saveAsCurrentModule() {

+        this.saveFileName = "";

+        saveCurrentModule();

+    }

+

+    /**

+     Save file as msa

+     

+     **/

+    private void saveMsa() {

+        File f = new File(this.saveFileName);

+        ModuleSurfaceAreaDocument msaDoc = ModuleSurfaceAreaDocument.Factory.newInstance();

+        ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = ModuleSurfaceAreaDocument.ModuleSurfaceArea.Factory

+                                                                                                             .newInstance();

+

+        //

+        //Add all components into xml doc file

+        //

+        if (xmlmh != null) {

+            msa.setMsaHeader(xmlmh);

+        }

+        if (xmllcd != null) {

+            msa.setLibraryClassDefinitions(xmllcd);

+        }

+        if (xmlsf != null) {

+            msa.setSourceFiles(xmlsf);

+        }

+        if (xmlic != null) {

+            msa.setIncludes(xmlic);

+        }

+        if (xmlpl != null) {

+            msa.setProtocols(xmlpl);

+        }

+        if (xmlen != null) {

+            msa.setEvents(xmlen);

+        }

+        if (xmlhob != null) {

+            msa.setHobs(xmlhob);

+        }

+        if (xmlppi != null) {

+            msa.setPPIs(xmlppi);

+        }

+        if (xmlvb != null) {

+            msa.setVariables(xmlvb);

+        }

+        if (xmlbm != null) {

+            msa.setBootModes(xmlbm);

+        }

+        if (xmlst != null) {

+            msa.setSystemTables(xmlst);

+        }

+        if (xmldh != null) {

+            msa.setDataHubs(xmldh);

+        }

+        if (xmlfs != null) {

+            msa.setFormsets(xmlfs);

+        }

+        if (xmlgu != null) {

+            msa.setGuids(xmlgu);

+        }

+        if (xmlet != null) {

+            msa.setExterns(xmlet);

+        }

+        if (xmlpcd != null) {

+            msa.setPCDs(xmlpcd);

+        }

+        if (xmlbo != null) {

+            msa.setBuildOptions(xmlbo);

+        }

+        //

+        //Init namespace

+        //

+        XmlCursor cursor = msa.newCursor();

+        String uri = "http://www.TianoCore.org/2006/Edk2.0";

+        cursor.push();

+        cursor.toNextToken();

+        cursor.insertNamespace("", uri);

+        cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

+        cursor.pop();

+

+        //

+        //Config file format

+        //

+        XmlOptions options = new XmlOptions();

+        options.setCharacterEncoding("UTF-8");

+        options.setSavePrettyPrint();

+        options.setSavePrettyPrintIndent(2);

+

+        //

+        //Create finial doc

+        //

+        msaDoc.addNewModuleSurfaceArea();

+        msaDoc.setModuleSurfaceArea((ModuleSurfaceAreaDocument.ModuleSurfaceArea) cursor.getObject());

+        try {

+            //

+            //Save the file

+            //

+            msaDoc.save(f, options);

+            this.currentModule = this.saveFileName;

+        } catch (Exception e) {

+            Log.err("Save Msa", e.getMessage());

+        }

+    }

+

+    /**

+     Save file as mbd

+     

+     **/

+    private void saveMbd() {

+        File f = new File(this.saveFileName);

+        ModuleBuildDescriptionDocument mbdDoc = ModuleBuildDescriptionDocument.Factory.newInstance();

+        ModuleBuildDescriptionDocument.ModuleBuildDescription mbd = ModuleBuildDescriptionDocument.ModuleBuildDescription.Factory

+                                                                                                                                 .newInstance();

+        //

+        //Add all components into xml doc file

+        //

+        if (xmlmbdh != null) {

+            mbd.setMbdHeader(xmlmbdh);

+        }

+        if (xmllib != null) {

+            mbd.setLibraries(xmllib);

+        }

+        if (xmlsf != null) {

+            mbd.setSourceFiles(xmlsf);

+        }

+        if (xmlic != null) {

+            mbd.setIncludes(xmlic);

+        }

+        if (xmlpl != null) {

+            mbd.setProtocols(xmlpl);

+        }

+        if (xmlen != null) {

+            mbd.setEvents(xmlen);

+        }

+        if (xmlhob != null) {

+            mbd.setHobs(xmlhob);

+        }

+        if (xmlppi != null) {

+            mbd.setPPIs(xmlppi);

+        }

+        if (xmlvb != null) {

+            mbd.setVariables(xmlvb);

+        }

+        if (xmlbm != null) {

+            mbd.setBootModes(xmlbm);

+        }

+        if (xmlst != null) {

+            mbd.setSystemTables(xmlst);

+        }

+        if (xmldh != null) {

+            mbd.setDataHubs(xmldh);

+        }

+        if (xmlfs != null) {

+            mbd.setFormsets(xmlfs);

+        }

+        if (xmlgu != null) {

+            mbd.setGuids(xmlgu);

+        }

+        if (xmlet != null) {

+            mbd.setExterns(xmlet);

+        }

+        if (xmlpcd != null) {

+            mbd.setPCDs(xmlpcd);

+        }

+        if (xmlbo != null) {

+            mbd.setBuildOptions(xmlbo);

+        }

+        //

+        //Init namespace

+        //

+        XmlCursor cursor = mbd.newCursor();

+        String uri = "http://www.TianoCore.org/2006/Edk2.0";

+        cursor.push();

+        cursor.toNextToken();

+        cursor.insertNamespace("", uri);

+        cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

+        cursor.pop();

+

+        //

+        //Config file format

+        //

+        XmlOptions options = new XmlOptions();

+        options.setCharacterEncoding("UTF-8");

+        options.setSavePrettyPrint();

+        options.setSavePrettyPrintIndent(2);

+

+        //

+        //Create finial doc

+        //

+        mbdDoc.addNewModuleBuildDescription();

+        mbdDoc.setModuleBuildDescription((ModuleBuildDescriptionDocument.ModuleBuildDescription) cursor.getObject());

+        try {

+            //

+            //Save the file

+            //

+            mbdDoc.save(f, options);

+            this.currentModule = this.saveFileName;

+        } catch (Exception e) {

+            Log.err("Save Mbd", e.getMessage());

+        }

+    }

+

+    /**

+     Save file as mlsa

+     

+     **/

+    private void saveMlsa() {

+        File f = new File(this.saveFileName);

+        LibraryModuleSurfaceAreaDocument mlsaDoc = LibraryModuleSurfaceAreaDocument.Factory.newInstance();

+        LibraryModuleSurfaceAreaDocument.LibraryModuleSurfaceArea mlsa = LibraryModuleSurfaceAreaDocument.LibraryModuleSurfaceArea.Factory

+                                                                                                                                          .newInstance();

+        //

+        //Add all components into xml doc file

+        //

+        if (xmlmlh != null) {

+            mlsa.setMsaLibHeader(xmlmlh);

+        }

+        if (xmllcd != null) {

+            mlsa.setLibraryClassDefinitions(xmllcd);

+        }

+        if (xmlsf != null) {

+            mlsa.setSourceFiles(xmlsf);

+        }

+        if (xmlic != null) {

+            mlsa.setIncludes(xmlic);

+        }

+        if (xmlpl != null) {

+            mlsa.setProtocols(xmlpl);

+        }

+        if (xmlen != null) {

+            mlsa.setEvents(xmlen);

+        }

+        if (xmlhob != null) {

+            mlsa.setHobs(xmlhob);

+        }

+        if (xmlppi != null) {

+            mlsa.setPPIs(xmlppi);

+        }

+        if (xmlvb != null) {

+            mlsa.setVariables(xmlvb);

+        }

+        if (xmlbm != null) {

+            mlsa.setBootModes(xmlbm);

+        }

+        if (xmlst != null) {

+            mlsa.setSystemTables(xmlst);

+        }

+        if (xmldh != null) {

+            mlsa.setDataHubs(xmldh);

+        }

+        if (xmlfs != null) {

+            mlsa.setFormsets(xmlfs);

+        }

+        if (xmlgu != null) {

+            mlsa.setGuids(xmlgu);

+        }

+        if (xmlet != null) {

+            mlsa.setExterns(xmlet);

+        }

+        if (xmlpcd != null) {

+            mlsa.setPCDs(xmlpcd);

+        }

+        if (xmlbo != null) {

+            mlsa.setBuildOptions(xmlbo);

+        }

+        //

+        //Init namespace

+        //

+        XmlCursor cursor = mlsa.newCursor();

+        String uri = "http://www.TianoCore.org/2006/Edk2.0";

+        cursor.push();

+        cursor.toNextToken();

+        cursor.insertNamespace("", uri);

+        cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

+        cursor.pop();

+

+        //

+        //Config file format

+        //

+        XmlOptions options = new XmlOptions();

+        options.setCharacterEncoding("UTF-8");

+        options.setSavePrettyPrint();

+        options.setSavePrettyPrintIndent(2);

+

+        //

+        //Create finial doc

+        //

+        mlsaDoc.addNewLibraryModuleSurfaceArea();

+        mlsaDoc

+               .setLibraryModuleSurfaceArea((LibraryModuleSurfaceAreaDocument.LibraryModuleSurfaceArea) cursor

+                                                                                                              .getObject());

+        try {

+            //

+            //Save the file

+            //

+            mlsaDoc.save(f, options);

+            this.currentModule = this.saveFileName;

+        } catch (Exception e) {

+            Log.err("Save Mlsa", e.getMessage());

+        }

+    }

+

+    /**

+     Save file as mbd

+     

+     **/

+    private void saveMlbd() {

+        File f = new File(this.saveFileName);

+        LibraryModuleBuildDescriptionDocument mlbdDoc = LibraryModuleBuildDescriptionDocument.Factory.newInstance();

+        LibraryModuleBuildDescriptionDocument.LibraryModuleBuildDescription mlbd = LibraryModuleBuildDescriptionDocument.LibraryModuleBuildDescription.Factory

+                                                                                                                                                              .newInstance();

+        //

+        //Add all components into xml doc file

+        //

+        if (xmlmlbdh != null) {

+            mlbd.setMbdLibHeader(xmlmlbdh);

+        }

+        if (xmllib != null) {

+            mlbd.setLibraries(xmllib);

+        }

+        if (xmlsf != null) {

+            mlbd.setSourceFiles(xmlsf);

+        }

+        if (xmlic != null) {

+            mlbd.setIncludes(xmlic);

+        }

+        if (xmlpl != null) {

+            mlbd.setProtocols(xmlpl);

+        }

+        if (xmlen != null) {

+            mlbd.setEvents(xmlen);

+        }

+        if (xmlhob != null) {

+            mlbd.setHobs(xmlhob);

+        }

+        if (xmlppi != null) {

+            mlbd.setPPIs(xmlppi);

+        }

+        if (xmlvb != null) {

+            mlbd.setVariables(xmlvb);

+        }

+        if (xmlbm != null) {

+            mlbd.setBootModes(xmlbm);

+        }

+        if (xmlst != null) {

+            mlbd.setSystemTables(xmlst);

+        }

+        if (xmldh != null) {

+            mlbd.setDataHubs(xmldh);

+        }

+        if (xmlfs != null) {

+            mlbd.setFormsets(xmlfs);

+        }

+        if (xmlgu != null) {

+            mlbd.setGuids(xmlgu);

+        }

+        if (xmlet != null) {

+            mlbd.setExterns(xmlet);

+        }

+        if (xmlpcd != null) {

+            mlbd.setPCDs(xmlpcd);

+        }

+        if (xmlbo != null) {

+            mlbd.setBuildOptions(xmlbo);

+        }

+        //

+        //Init namespace

+        //

+        XmlCursor cursor = mlbd.newCursor();

+        String uri = "http://www.TianoCore.org/2006/Edk2.0";

+        cursor.push();

+        cursor.toNextToken();

+        cursor.insertNamespace("", uri);

+        cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

+        cursor.pop();

+

+        //

+        //Config file format

+        //

+        XmlOptions options = new XmlOptions();

+        options.setCharacterEncoding("UTF-8");

+        options.setSavePrettyPrint();

+        options.setSavePrettyPrintIndent(2);

+

+        //

+        //Create finial doc

+        //

+        mlbdDoc.addNewLibraryModuleBuildDescription();

+        mlbdDoc

+               .setLibraryModuleBuildDescription((LibraryModuleBuildDescriptionDocument.LibraryModuleBuildDescription) cursor

+                                                                                                                             .getObject());

+        try {

+            //

+            //Save the file

+            //

+            mlbdDoc.save(f, options);

+            this.currentModule = this.saveFileName;

+        } catch (Exception e) {

+            Log.err("Save Mbd", e.getMessage());

+        }

+    }

+

+    /**

+     Reflash the tree via current value of xml documents.

+     

+     @param intMode The input data of current operation type

+     

+     **/

+    private void reloadTreeAndTable(int intMode) {

+        makeTree();

+        if (intMode == ModuleMain.OPENED) {

+            this.jMenuItemModuleClose.setEnabled(true);

+            this.jMenuItemModuleSaveAs.setEnabled(true);

+            this.jMenuEditAdd.setEnabled(true);

+            this.setTitle(windowTitle + "- [" + this.currentModule + "]");

+            this.jButtonOk.setEnabled(false);

+            this.jButtonCancel.setEnabled(false);

+        }

+        if (intMode == ModuleMain.CLOSED) {

+            this.jMenuItemModuleClose.setEnabled(false);

+            this.jMenuItemModuleSave.setEnabled(false);

+            this.jMenuItemModuleSaveAs.setEnabled(false);

+            this.jMenuEditAdd.setEnabled(false);

+            this.setTitle(windowTitle + "- [" + ws.getCurrentWorkspace() + "]");

+            this.setButtonEnable(false);

+        }

+        if (intMode == ModuleMain.NEW_WITHOUT_CHANGE) {

+

+        }

+

+        if (intMode == ModuleMain.NEW_WITH_CHANGE) {

+            this.jMenuItemModuleClose.setEnabled(true);

+            this.jMenuItemModuleSave.setEnabled(true);

+            this.jMenuItemModuleSaveAs.setEnabled(true);

+            this.jMenuEditAdd.setEnabled(true);

+            setButtonEnable(false);

+        }

+        if (intMode == ModuleMain.UPDATE_WITHOUT_CHANGE) {

+

+        }

+        if (intMode == ModuleMain.UPDATE_WITH_CHANGE) {

+            this.jMenuItemModuleClose.setEnabled(true);

+            this.jMenuItemModuleSave.setEnabled(true);

+            this.jMenuItemModuleSaveAs.setEnabled(true);

+        }

+        if (intMode == ModuleMain.SAVE_WITHOUT_CHANGE) {

+            this.jMenuItemModuleClose.setEnabled(true);

+            this.jMenuItemModuleSave.setEnabled(true);

+            this.jMenuItemModuleSaveAs.setEnabled(true);

+            this.jButtonOk.setEnabled(false);

+            this.jButtonCancel.setEnabled(false);

+        }

+        if (intMode == ModuleMain.SAVE_WITH_CHANGE) {

+            this.jMenuItemModuleClose.setEnabled(true);

+            this.jMenuItemModuleSave.setEnabled(false);

+            this.jMenuItemModuleSaveAs.setEnabled(true);

+            this.jMenuItemEditUpdate.setEnabled(false);

+            this.jMenuItemEditDelete.setEnabled(false);

+            this.setTitle(windowTitle + "- [" + this.currentModule + "]");

+            this.jButtonOk.setEnabled(false);

+            this.jButtonCancel.setEnabled(false);

+        }

+

+        if (this.currentModuleType == 1 || this.currentModuleType == 3) {

+            this.jMenuItemEditAddLibraries.setEnabled(false);

+            this.jMenuItemEditAddLibraryClassDefinitions.setEnabled(true);

+        }

+        if (this.currentModuleType == 2 || this.currentModuleType == 4) {

+            this.jMenuItemEditAddLibraries.setEnabled(true);

+            this.jMenuItemEditAddLibraryClassDefinitions.setEnabled(false);

+        }

+    }

+

+    /**

+     Enable/Disable button Ok and Cancel

+     

+     @param isEnabled The input data to indicate if button is enabled or not

+     

+     **/

+    private void setButtonEnable(boolean isEnabled) {

+        this.jButtonCancel.setEnabled(isEnabled);

+        this.jButtonOk.setEnabled(isEnabled);

+    }

+

+    /**

+     Show msa header

+     When the operation is VIEW, disable all fields of internal frame

+     

+     @param type The input data of operation type

+     

+     **/

+    private void showMsaHeader(int type) {

+        msa = null;

+        msa = new MsaHeader(this.xmlmh);

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(msa, 1);

+        this.currentNodeType = IDefaultMutableTreeNode.MSA_HEADER;

+        this.currentModuleType = 1;

+        if (type == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            msa.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show MbdHeader

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showMbdHeader(int type) {

+        mbd = null;

+        mbd = new MbdHeader(this.xmlmbdh);

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mbd, 1);

+        this.currentNodeType = IDefaultMutableTreeNode.MBD_HEADER;

+        this.currentModuleType = 2;

+        if (type == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mbd.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show MlsaHeader

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showMlsaHeader(int type) {

+        mlsa = null;

+        mlsa = new MsaLibHeader(this.xmlmlh);

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mlsa, 1);

+        this.currentNodeType = IDefaultMutableTreeNode.MLSA_HEADER;

+        this.currentModuleType = 3;

+        if (type == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mlsa.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show MlbdHeader

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showMlbdHeader(int type) {

+        mlbd = null;

+        mlbd = new MbdLibHeader(this.xmlmlbdh);

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mlbd, 1);

+        this.currentNodeType = IDefaultMutableTreeNode.MLBD_HEADER;

+        this.currentModuleType = 4;

+        if (type == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mlbd.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Libraries

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showLibraries(int operationType, int nodeType, int location) {

+        mlib = null;

+        if (operationType == ModuleMain.ADD) {

+            mlib = new MbdLibraries(this.xmllib, -1, -1, 1);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mlib = new MbdLibraries(this.xmllib, nodeType, location, 2);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mlib, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mlib.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show LibraryClassDefinitions

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showLibraryClassDefinitions(int operationType, int nodeType) {

+        mlcd = null;

+        if (operationType == ModuleMain.ADD) {

+            mlcd = new ModuleLibraryClassDefinitions(this.xmllcd);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mlcd = new ModuleLibraryClassDefinitions(this.xmllcd);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mlcd, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mlcd.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show SourceFiles

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showSourceFiles(int operationType, int nodeType, int location) {

+        msf = null;

+        if (operationType == ModuleMain.ADD) {

+            msf = new ModuleSourceFiles(this.xmlsf, -1, -1, 1);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            msf = new ModuleSourceFiles(this.xmlsf, nodeType, location, 2);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(msf, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            msf.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Includes

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showIncludes(int operationType, int nodeType, int location) {

+        mic = null;

+        if (operationType == ModuleMain.ADD) {

+            mic = new ModuleIncludes(this.xmlic, -1, -1, 1);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mic = new ModuleIncludes(this.xmlic, nodeType, location, 2);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mic, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mic.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Protocols

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showProtocols(int operationType, int nodeType, int location) {

+        mp = null;

+        if (operationType == ModuleMain.ADD) {

+            mp = new ModuleProtocols(this.xmlpl);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mp = new ModuleProtocols(this.xmlpl, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mp, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mp.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Events

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showEvents(int operationType, int nodeType, int location) {

+        mev = null;

+        if (operationType == ModuleMain.ADD) {

+            mev = new ModuleEvents(this.xmlen);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mev = new ModuleEvents(this.xmlen, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mev, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mev.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Hobs

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showHobs(int operationType, int nodeType, int location) {

+        mh = null;

+        if (operationType == ModuleMain.ADD) {

+            mh = new ModuleHobs(this.xmlhob);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mh = new ModuleHobs(this.xmlhob, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mh, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mh.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Ppis

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showPpis(int operationType, int nodeType, int location) {

+        mpp = null;

+        if (operationType == ModuleMain.ADD) {

+            mpp = new ModulePpis(this.xmlppi);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mpp = new ModulePpis(this.xmlppi, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mpp, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mpp.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Variables

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showVariables(int operationType, int nodeType, int location) {

+        mv = null;

+        if (operationType == ModuleMain.ADD) {

+            mv = new ModuleVariables(this.xmlvb);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mv = new ModuleVariables(this.xmlvb, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mv, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mv.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show BootModes

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showBootModes(int operationType, int nodeType, int location) {

+        mbm = null;

+        if (operationType == ModuleMain.ADD) {

+            mbm = new ModuleBootModes(this.xmlbm);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mbm = new ModuleBootModes(this.xmlbm, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mbm, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mbm.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show SystemTables

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showSystemTables(int operationType, int nodeType, int location) {

+        mst = null;

+        if (operationType == ModuleMain.ADD) {

+            mst = new ModuleSystemTables(this.xmlst);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mst = new ModuleSystemTables(this.xmlst, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mst, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mst.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show DataHubs

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showDataHubs(int operationType, int nodeType, int location) {

+        mdh = null;

+        if (operationType == ModuleMain.ADD) {

+            mdh = new ModuleDataHubs(this.xmldh);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mdh = new ModuleDataHubs(this.xmldh, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mdh, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mdh.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Formsets

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showFormsets(int operationType, int nodeType, int location) {

+        mf = null;

+        if (operationType == ModuleMain.ADD) {

+            mf = new ModuleFormsets(this.xmlfs);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mf = new ModuleFormsets(this.xmlfs, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mf, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mf.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Show Guids

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showGuids(int operationType, int nodeType, int location) {

+        mg = null;

+        if (operationType == ModuleMain.ADD || operationType == ModuleMain.VIEW) {

+            mg = new ModuleGuids(this.xmlgu);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mg = new ModuleGuids(this.xmlgu, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mg, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mg.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show Externs

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showExterns(int operationType, int nodeType, int location) {

+        met = null;

+        if (operationType == ModuleMain.ADD) {

+            met = new ModuleExterns(this.xmlet);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            met = new ModuleExterns(this.xmlet, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(met, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            met.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Show PCDs

+    When the operation is VIEW, disable all fields of internal frame

+    

+    @param type The input data of operation type

+    

+    **/

+    private void showPCDs(int operationType, int nodeType, int location) {

+        mpcd = null;

+        if (operationType == ModuleMain.ADD) {

+            mpcd = new ModulePCDs(this.xmlpcd);

+        }

+        if (operationType == ModuleMain.UPDATE || operationType == ModuleMain.VIEW) {

+            mpcd = new ModulePCDs(this.xmlpcd, nodeType, location);

+        }

+        this.jDesktopPane.removeAll();

+        this.jDesktopPane.add(mpcd, 1);

+        this.currentNodeType = nodeType;

+        if (operationType == ModuleMain.VIEW) {

+            setButtonEnable(false);

+            mpcd.setViewMode(true);

+        } else {

+            setButtonEnable(true);

+        }

+    }

+

+    /**

+    Save currentModule when press button OK

+    

+    **/

+    private void save() {

+        if (this.currentNodeType == IDefaultMutableTreeNode.MSA_HEADER) {

+            if (!msa.check()) {

+                return;

+            }

+            msa.save();

+            msa.setViewMode(true);

+            this.xmlmh = msa.getMsaHeader();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.MBD_HEADER) {

+            if (!mbd.check()) {

+                return;

+            }

+            mbd.save();

+            mbd.setViewMode(true);

+            this.xmlmbdh = mbd.getMbdHeader();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.MLSA_HEADER) {

+            if (!mlsa.check()) {

+                return;

+            }

+            mlsa.save();

+            mlsa.setViewMode(true);

+            this.xmlmlh = mlsa.getMsaLibHeader();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.MLBD_HEADER) {

+            if (!mlbd.check()) {

+                return;

+            }

+            mlbd.save();

+            mlbd.setViewMode(true);

+            this.xmlmlbdh = mlbd.getMbdLibHeader();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.LIBRARIES

+            || this.currentNodeType == IDefaultMutableTreeNode.LIBRARIES_ARCH

+            || this.currentNodeType == IDefaultMutableTreeNode.LIBRARIES_ARCH_ITEM

+            || this.currentNodeType == IDefaultMutableTreeNode.LIBRARIES_LIBRARY

+            || this.currentNodeType == IDefaultMutableTreeNode.LIBRARIES_LIBRARY_ITEM) {

+            if (!mlib.check()) {

+                return;

+            }

+            mlib.save();

+            mlib.setViewMode(true);

+            this.xmllib = mlib.getLibraries();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.LIBRARYCLASSDEFINITIONS

+            || this.currentNodeType == IDefaultMutableTreeNode.LIBRARY_CLASS_DEFINITION) {

+            if (!mlcd.check()) {

+                return;

+            }

+            mlcd.save();

+            mlcd.setViewMode(true);

+            this.xmllcd = mlcd.getLibraryClassDefinitions();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.SOURCEFILES

+            || this.currentNodeType == IDefaultMutableTreeNode.SOURCEFILES_ARCH

+            || this.currentNodeType == IDefaultMutableTreeNode.SOURCEFILES_ARCH_ITEM

+            || this.currentNodeType == IDefaultMutableTreeNode.SOURCEFILES_FILENAME

+            || this.currentNodeType == IDefaultMutableTreeNode.SOURCEFILES_FILENAME_ITEM) {

+            if (!msf.check()) {

+                return;

+            }

+            msf.save();

+            msf.setViewMode(true);

+            this.xmlsf = msf.getSourceFiles();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.INCLUDES

+            || this.currentNodeType == IDefaultMutableTreeNode.INCLUDES_ARCH

+            || this.currentNodeType == IDefaultMutableTreeNode.INCLUDES_ARCH_ITEM

+            || this.currentNodeType == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME

+            || this.currentNodeType == IDefaultMutableTreeNode.INCLUDES_PACKAGENAME_ITEM) {

+            if (!mic.check()) {

+                return;

+            }

+            mic.save();

+            mic.setViewMode(true);

+            this.xmlic = mic.getIncludes();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.PROTOCOLS

+            || this.currentNodeType == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL

+            || this.currentNodeType == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL_ITEM

+            || this.currentNodeType == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY

+            || this.currentNodeType == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY_ITEM) {

+            if (!mp.check()) {

+                return;

+            }

+            mp.save();

+            mp.setViewMode(true);

+            this.xmlpl = mp.getProtocols();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.EVENTS

+            || this.currentNodeType == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS

+            || this.currentNodeType == IDefaultMutableTreeNode.EVENTS_CREATEEVENTS_ITEM

+            || this.currentNodeType == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS

+            || this.currentNodeType == IDefaultMutableTreeNode.EVENTS_SIGNALEVENTS_ITEM) {

+            if (!mev.check()) {

+                return;

+            }

+            mev.save();

+            mev.setViewMode(true);

+            this.xmlen = mev.getEvents();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.HOBS

+            || this.currentNodeType == IDefaultMutableTreeNode.HOBS_HOB_ITEM) {

+            if (!mh.check()) {

+                return;

+            }

+            mh.save();

+            mh.setViewMode(true);

+            this.xmlhob = mh.getHobs();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.PPIS

+            || this.currentNodeType == IDefaultMutableTreeNode.PPIS_PPI

+            || this.currentNodeType == IDefaultMutableTreeNode.PPIS_PPI_ITEM

+            || this.currentNodeType == IDefaultMutableTreeNode.PPIS_PPINOTIFY

+            || this.currentNodeType == IDefaultMutableTreeNode.PPIS_PPINOTIFY_ITEM) {

+            if (!mpp.check()) {

+                return;

+            }

+            mpp.save();

+            mpp.setViewMode(true);

+            this.xmlppi = mpp.getPpis();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.VARIABLES

+            || this.currentNodeType == IDefaultMutableTreeNode.VARIABLES_VARIABLE_ITEM) {

+            if (!mv.check()) {

+                return;

+            }

+            mv.save();

+            mv.setViewMode(true);

+            this.xmlvb = mv.getVariables();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.BOOTMODES

+            || this.currentNodeType == IDefaultMutableTreeNode.BOOTMODES_BOOTMODE_ITEM) {

+            if (!mbm.check()) {

+                return;

+            }

+            mbm.save();

+            mbm.setViewMode(true);

+            this.xmlbm = mbm.getBootModes();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.SYSTEMTABLES

+            || this.currentNodeType == IDefaultMutableTreeNode.SYSTEMTABLES_SYSTEMTABLE_ITEM) {

+            if (!mst.check()) {

+                return;

+            }

+            mst.save();

+            mst.setViewMode(true);

+            this.xmlst = mst.getSystemTables();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.DATAHUBS

+            || this.currentNodeType == IDefaultMutableTreeNode.DATAHUBS_DATAHUB_ITEM) {

+            if (!mdh.check()) {

+                return;

+            }

+            mdh.save();

+            mdh.setViewMode(true);

+            this.xmldh = mdh.getDataHubs();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.FORMSETS

+            || this.currentNodeType == IDefaultMutableTreeNode.FORMSETS_FORMSET_ITEM) {

+            if (!mf.check()) {

+                return;

+            }

+            mf.save();

+            mf.setViewMode(true);

+            this.xmlfs = mf.getFormsets();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.GUIDS

+            || this.currentNodeType == IDefaultMutableTreeNode.GUIDS_GUIDENTRY_ITEM) {

+            if (!mg.check()) {

+                return;

+            }

+            mg.save();

+            mg.setViewMode(true);

+            this.xmlgu = mg.getGuids();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.EXTERNS

+            || this.currentNodeType == IDefaultMutableTreeNode.EXTERNS_EXTERN_ITEM) {

+            if (!met.check()) {

+                return;

+            }

+            met.save();

+            met.setViewMode(true);

+            this.xmlet = met.getExterns();

+        }

+

+        if (this.currentNodeType == IDefaultMutableTreeNode.PCDS

+            || this.currentNodeType == IDefaultMutableTreeNode.PCDS_PCDDATA_ITEM) {

+            if (!mpcd.check()) {

+                return;

+            }

+            mpcd.save();

+            mpcd.setViewMode(true);

+            this.xmlpcd = mpcd.getPcds();

+        }

+

+        reloadTreeAndTable(NEW_WITH_CHANGE);

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModulePCDs.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModulePCDs.java
new file mode 100644
index 0000000..827efe9
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModulePCDs.java
@@ -0,0 +1,519 @@
+/** @file

+ 

+ The file is used to create, update PCD of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.PCDsDocument;

+import org.tianocore.PcdDataTypes;

+import org.tianocore.PcdItemTypes;

+import org.tianocore.PcdUsage;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update PCD of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModulePCDs extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 2227717658188438696L;

+

+    //

+    //Define class members

+    //

+    private PCDsDocument.PCDs pcds = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelItemType = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JComboBox jComboBoxItemType = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelToken = null;

+

+    private JTextField jTextFieldToken = null;

+

+    private JLabel jLabelDefaultValue = null;

+

+    private JTextField jTextFieldDefaultValue = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelDatumType = null;

+

+    private JComboBox jComboBoxDatumType = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+    

+    /**

+     This method initializes jComboBoxItemType 

+     

+     @return javax.swing.JComboBox jComboBoxItemType

+     

+     **/

+    private JComboBox getJComboBoxItemType() {

+        if (jComboBoxItemType == null) {

+            jComboBoxItemType = new JComboBox();

+            jComboBoxItemType.setBounds(new java.awt.Rectangle(160, 110, 320, 20));

+        }

+        return jComboBoxItemType;

+    }

+

+    /**

+     This method initializes jTextFieldC_Name 

+     

+     @return javax.swing.JTextField jTextFieldC_Name

+     

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldToken 

+     

+     @return javax.swing.JTextField jTextFieldToken

+     

+     **/

+    private JTextField getJTextFieldToken() {

+        if (jTextFieldToken == null) {

+            jTextFieldToken = new JTextField();

+            jTextFieldToken.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jTextFieldToken;

+    }

+

+    /**

+     This method initializes jTextFieldDefaultValue 

+     

+     @return javax.swing.JTextField jTextFieldDefaultValue

+     

+     **/

+    private JTextField getJTextFieldDefaultValue() {

+        if (jTextFieldDefaultValue == null) {

+            jTextFieldDefaultValue = new JTextField();

+            jTextFieldDefaultValue.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return jTextFieldDefaultValue;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(280, 290, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 290, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldDatumType 

+     

+     @return javax.swing.JTextField jComboBoxDatumType

+     

+     **/

+    private JComboBox getJComboBoxDatumType() {

+        if (jComboBoxDatumType == null) {

+            jComboBoxDatumType = new JComboBox();

+            jComboBoxDatumType.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jComboBoxDatumType;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModulePCDs() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inPcds The input data of PCDsDocument.PCDs

+     

+     **/

+    public ModulePCDs(PCDsDocument.PCDs inPcds) {

+        super();

+        init(inPcds);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inPcds The input data of PCDsDocument.PCDs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModulePCDs(PCDsDocument.PCDs inPcds, int type, int index) {

+        super();

+        init(inPcds, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inPcds The input data of PCDsDocument.PCDs

+     

+     **/

+    private void init(PCDsDocument.PCDs inPcds) {

+        init();

+        this.setPcds(inPcds);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inPcds The input data of PCDsDocument.PCDs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(PCDsDocument.PCDs inPcds, int type, int index) {

+        init(inPcds);

+        this.location = index;

+        if (this.pcds.getPcdDataList().size() > 0) {

+            if (this.pcds.getPcdDataArray(index).getCName() != null) {

+                this.jTextFieldC_Name.setText(this.pcds.getPcdDataArray(index).getCName());

+            }

+            if (this.pcds.getPcdDataArray(index).getToken() != null) {

+                this.jTextFieldToken.setText(this.pcds.getPcdDataArray(index).getToken());

+            }

+            if (this.pcds.getPcdDataArray(index).getDatumType() != null) {

+                this.jComboBoxDatumType.setSelectedItem(this.pcds.getPcdDataArray(index).getDatumType().toString());

+            }

+            if (this.pcds.getPcdDataArray(index).getDefaultValue() != null) {

+                this.jTextFieldDefaultValue.setText(this.pcds.getPcdDataArray(index).getDefaultValue());

+            }

+            if (this.pcds.getPcdDataArray(index).getPcdUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.pcds.getPcdDataArray(index).getPcdUsage().toString());

+            }

+            if (this.pcds.getPcdDataArray(index).getItemType() != null) {

+                this.jComboBoxItemType.setSelectedItem(this.pcds.getPcdDataArray(index).getItemType().toString());

+            }

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("PCDs");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldC_Name.setEnabled(!isView);

+            this.jTextFieldToken.setEnabled(!isView);

+            this.jComboBoxDatumType.setEnabled(!isView);

+            this.jTextFieldDefaultValue.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jComboBoxItemType.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelDatumType = new JLabel();

+            jLabelDatumType.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelDatumType.setText("Datum Type");

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelDefaultValue = new JLabel();

+            jLabelDefaultValue.setText("Default Value");

+            jLabelDefaultValue.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelToken = new JLabel();

+            jLabelToken.setText("Token");

+            jLabelToken.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelItemType = new JLabel();

+            jLabelItemType.setText("Item Type");

+            jLabelItemType.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setSize(new java.awt.Dimension(480,336));

+            jContentPane.add(jLabelItemType, null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(jLabelToken, null);

+            jContentPane.add(getJTextFieldToken(), null);

+            jContentPane.add(jLabelDefaultValue, null);

+            jContentPane.add(getJTextFieldDefaultValue(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJComboBoxItemType(), null);

+            jContentPane.add(jLabelDatumType, null);

+            jContentPane.add(getJComboBoxDatumType(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 110));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type, Item type and Datum type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("DEFAULT");

+

+        jComboBoxItemType.addItem("FEATURE_FLAG");

+        jComboBoxItemType.addItem("FIXED_AT_BUILD");

+        jComboBoxItemType.addItem("PATCHABLE_IN_MODULE");

+        jComboBoxItemType.addItem("DYNAMIC");

+        jComboBoxItemType.addItem("DYNAMIC_EX");

+

+        jComboBoxDatumType.addItem("UINT8");

+        jComboBoxDatumType.addItem("UINT16");

+        jComboBoxDatumType.addItem("UINT32");

+        jComboBoxDatumType.addItem("UINT64");

+        jComboBoxDatumType.addItem("VOID*");

+        jComboBoxDatumType.addItem("BOOLEAN");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+    }

+

+    /**

+     Get PCDsDocument.PCDs

+     

+     @return PCDsDocument.PCDs

+     

+     **/

+    public PCDsDocument.PCDs getPcds() {

+        return pcds;

+    }

+

+    /**

+     Set PCDsDocument.PCDs

+     

+     @param pcds The input data of PCDsDocument.PCDs

+     

+     **/

+    public void setPcds(PCDsDocument.PCDs pcds) {

+        this.pcds = pcds;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldC_Name.getText())) {

+            Log.err("C_Name couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldToken.getText())) {

+            Log.err("Token couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!isEmpty(this.jTextFieldC_Name.getText()) && !DataValidation.isCName(this.jTextFieldC_Name.getText())) {

+            Log.err("Incorrect data type for C_Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldToken.getText()) && !DataValidation.isToken(this.jTextFieldToken.getText())) {

+            Log.err("Incorrect data type for Token");

+            return false;

+        }

+        

+        return true;

+    }

+

+    /**

+     Save all components of PCDs

+     if exists pcds, set the value directly

+     if not exists pcds, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.pcds == null) {

+                pcds = PCDsDocument.PCDs.Factory.newInstance();

+            }

+            PCDsDocument.PCDs.PcdData pcdData = PCDsDocument.PCDs.PcdData.Factory.newInstance();

+            if (!isEmpty(this.jTextFieldC_Name.getText())) {

+                pcdData.setCName(this.jTextFieldC_Name.getText());

+            }

+            if (!isEmpty(this.jTextFieldToken.getText())) {

+                pcdData.setToken(this.jTextFieldToken.getText());

+            }

+            pcdData.setDatumType(PcdDataTypes.Enum.forString(this.jComboBoxDatumType.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldDefaultValue.getText())) {

+                pcdData.setDefaultValue(this.jTextFieldDefaultValue.getText());

+            }

+            pcdData.setItemType(PcdItemTypes.Enum.forString(this.jComboBoxItemType.getSelectedItem().toString()));

+            pcdData.setPcdUsage(PcdUsage.Enum.forString(this.jComboBoxUsage.getSelectedItem().toString()));

+           

+

+            if (location > -1) {

+                pcds.setPcdDataArray(location, pcdData);

+            } else {

+                pcds.addNewPcdData();

+                pcds.setPcdDataArray(pcds.getPcdDataList().size() - 1, pcdData);

+            }

+        } catch (Exception e) {

+            Log.err("Update Hobs", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModulePpis.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModulePpis.java
new file mode 100644
index 0000000..42d0fb8
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModulePpis.java
@@ -0,0 +1,711 @@
+/** @file

+ 

+ The file is used to create, update Ppi of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+

+import org.tianocore.PPIsDocument;

+import org.tianocore.PpiNotifyUsage;

+import org.tianocore.PpiUsage;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Ppi of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModulePpis extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -4284901202357037724L;

+

+    //

+    //Define class members

+    //

+    private PPIsDocument.PPIs ppis = null;

+

+    private int location = -1;

+

+    private static int PPI = 1;

+

+    private static int PPI_NOTIFY = 2;

+

+    private JPanel jContentPane = null;

+

+    private JRadioButton jRadioButtonPpi = null;

+

+    private JRadioButton jRadioButtonPpiNotify = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JTextField jTextFieldFeatureFlag = null;

+

+    private JLabel jLabelFeatureFlag = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JLabel jLabelEnableFeature = null;

+

+    private JRadioButton jRadioButtonEnableFeature = null;

+

+    private JRadioButton jRadioButtonDisableFeature = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelPpiType = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    /**

+     This method initializes jRadioButtonPpi 

+     

+     @return javax.swing.JRadioButton jRadioButtonPpi

+     

+     **/

+    private JRadioButton getJRadioButtonPpiType() {

+        if (jRadioButtonPpi == null) {

+            jRadioButtonPpi = new JRadioButton();

+            jRadioButtonPpi.setText("Ppi");

+            jRadioButtonPpi.setBounds(new java.awt.Rectangle(160, 10, 100, 20));

+            jRadioButtonPpi.addActionListener(this);

+            jRadioButtonPpi.setSelected(true);

+        }

+        return jRadioButtonPpi;

+    }

+

+    /**

+     This method initializes jRadioButtonPpiNotify 

+     

+     @return javax.swing.JRadioButton jRadioButtonPpiNotify

+     

+     **/

+    private JRadioButton getJRadioButtonPpiNotify() {

+        if (jRadioButtonPpiNotify == null) {

+            jRadioButtonPpiNotify = new JRadioButton();

+            jRadioButtonPpiNotify.setText("Ppi Notify");

+            jRadioButtonPpiNotify.setBounds(new java.awt.Rectangle(320, 10, 100, 20));

+            jRadioButtonPpiNotify.addActionListener(this);

+        }

+        return jRadioButtonPpiNotify;

+    }

+

+    /**

+     This method initializes jTextFieldC_Name 

+     

+     @return javax.swing.JTextField jTextFieldC_Name

+     

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 60, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldFeatureFlag 

+     

+     @return javax.swing.JTextField jTextFieldFeatureFlag

+     

+     **/

+    private JTextField getJTextFieldFeatureFlag() {

+        if (jTextFieldFeatureFlag == null) {

+            jTextFieldFeatureFlag = new JTextField();

+            jTextFieldFeatureFlag.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jTextFieldFeatureFlag;

+    }

+

+    /**

+     This method initializes jComboBox

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBox() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jRadioButtonEnableFeature 

+     

+     @return javax.swing.JRadioButton jRadioButtonEnableFeature

+     

+     **/

+    private JRadioButton getJRadioButtonEnableFeature() {

+        if (jRadioButtonEnableFeature == null) {

+            jRadioButtonEnableFeature = new JRadioButton();

+            jRadioButtonEnableFeature.setText("Enable");

+            jRadioButtonEnableFeature.setBounds(new java.awt.Rectangle(160, 110, 90, 20));

+            jRadioButtonEnableFeature.addActionListener(this);

+            jRadioButtonEnableFeature.setSelected(true);

+        }

+        return jRadioButtonEnableFeature;

+    }

+

+    /**

+     This method initializes jRadioButtonDisableFeature 

+     

+     @return javax.swing.JRadioButton jRadioButtonDisableFeature

+     

+     **/

+    private JRadioButton getJRadioButtonDisableFeature() {

+        if (jRadioButtonDisableFeature == null) {

+            jRadioButtonDisableFeature = new JRadioButton();

+            jRadioButtonDisableFeature.setText("Disable");

+            jRadioButtonDisableFeature.setBounds(new java.awt.Rectangle(320, 110, 90, 20));

+            jRadioButtonDisableFeature.addActionListener(this);

+        }

+        return jRadioButtonDisableFeature;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 190, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 190, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 60, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 160, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModulePpis() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inPpis The input data of PPIsDocument.PPIs

+     

+     **/

+    public ModulePpis(PPIsDocument.PPIs inPpis) {

+        super();

+        init(inPpis);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inPpis The input data of PPIsDocument.PPIs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModulePpis(PPIsDocument.PPIs inPpis, int type, int index) {

+        super();

+        init(inPpis, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inPpis The input data of PPIsDocument.PPIs

+     

+     **/

+    private void init(PPIsDocument.PPIs inPpis) {

+        init();

+        this.setPpis(inPpis);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inPpis The input data of PPIsDocument.PPIs

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(PPIsDocument.PPIs inPpis, int type, int index) {

+        init(inPpis);

+        this.location = index;

+        if (type == IDefaultMutableTreeNode.PPIS_PPI_ITEM) {

+            initUsage(ModulePpis.PPI);

+            this.jRadioButtonPpi.setSelected(true);

+            this.jRadioButtonPpiNotify.setSelected(false);

+            if (this.ppis.getPpiArray(index).getStringValue() != null) {

+                this.jTextFieldC_Name.setText(this.ppis.getPpiArray(index).getStringValue());

+            }

+            if (this.ppis.getPpiArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.ppis.getPpiArray(index).getGuid());

+            }

+            if (this.ppis.getPpiArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.ppis.getPpiArray(index).getUsage().toString());

+            }

+            this.jRadioButtonEnableFeature.setSelected(this.ppis.getPpiArray(index).getEnableFeature());

+            this.jRadioButtonDisableFeature.setSelected(!this.ppis.getPpiArray(index).getEnableFeature());

+            if (this.ppis.getPpiArray(index).getFeatureFlag() != null) {

+                this.jTextFieldFeatureFlag.setText(this.ppis.getPpiArray(index).getFeatureFlag());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.ppis.getPpiArray(index).getOverrideID()));

+        } else if (type == IDefaultMutableTreeNode.PPIS_PPINOTIFY_ITEM) {

+            initUsage(ModulePpis.PPI_NOTIFY);

+            this.jRadioButtonPpi.setSelected(false);

+            this.jRadioButtonPpiNotify.setSelected(true);

+            if (this.ppis.getPpiNotifyArray(index).getStringValue() != null) {

+                this.jTextFieldC_Name.setText(this.ppis.getPpiNotifyArray(index).getStringValue());

+            }

+            if (this.ppis.getPpiNotifyArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.ppis.getPpiNotifyArray(index).getGuid());

+            }

+            if (this.ppis.getPpiNotifyArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.ppis.getPpiNotifyArray(index).getUsage().toString());

+            }

+            this.jRadioButtonEnableFeature.setSelected(this.ppis.getPpiNotifyArray(index).getEnableFeature());

+            this.jRadioButtonDisableFeature.setSelected(!this.ppis.getPpiNotifyArray(index).getEnableFeature());

+            if (this.ppis.getPpiNotifyArray(index).getFeatureFlag() != null) {

+                this.jTextFieldFeatureFlag.setText(this.ppis.getPpiNotifyArray(index).getFeatureFlag());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.ppis.getPpiNotifyArray(index).getOverrideID()));

+        }

+        this.jRadioButtonPpi.setEnabled(false);

+        this.jRadioButtonPpiNotify.setEnabled(false);

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Ppis");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 515));

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jRadioButtonPpi.setEnabled(!isView);

+            this.jRadioButtonPpiNotify.setEnabled(!isView);

+            this.jTextFieldC_Name.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jRadioButtonEnableFeature.setEnabled(!isView);

+            this.jRadioButtonDisableFeature.setEnabled(!isView);

+            this.jTextFieldFeatureFlag.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelPpiType = new JLabel();

+            jLabelPpiType.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelPpiType.setText("Ppi Type");

+            jLabelEnableFeature = new JLabel();

+            jLabelEnableFeature.setText("Enable Feature");

+            jLabelEnableFeature.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelFeatureFlag = new JLabel();

+            jLabelFeatureFlag.setText("Feature Flag");

+            jLabelFeatureFlag.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJRadioButtonPpiType(), null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(getJTextFieldFeatureFlag(), null);

+            jContentPane.add(jLabelFeatureFlag, null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBox(), null);

+            jContentPane.add(jLabelEnableFeature, null);

+            jContentPane.add(getJRadioButtonEnableFeature(), null);

+            jContentPane.add(getJRadioButtonDisableFeature(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJRadioButtonPpiNotify(), null);

+            jContentPane.add(jLabelPpiType, null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setBounds(new java.awt.Rectangle(0, 10, 10, 20));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setBounds(new java.awt.Rectangle(0, 35, 10, 20));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        //

+        //Contorl the selected status when click RadionButton

+        //Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonPpi) {

+            if (jRadioButtonPpi.isSelected()) {

+                jRadioButtonPpiNotify.setSelected(false);

+                initUsage(ModulePpis.PPI);

+            }

+            if (!jRadioButtonPpiNotify.isSelected() && !jRadioButtonPpi.isSelected()) {

+                jRadioButtonPpi.setSelected(true);

+                initUsage(ModulePpis.PPI);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonPpiNotify) {

+            if (jRadioButtonPpiNotify.isSelected()) {

+                jRadioButtonPpi.setSelected(false);

+                initUsage(ModulePpis.PPI_NOTIFY);

+            }

+            if (!jRadioButtonPpiNotify.isSelected() && !jRadioButtonPpi.isSelected()) {

+                jRadioButtonPpiNotify.setSelected(true);

+                initUsage(ModulePpis.PPI_NOTIFY);

+            }

+        }

+

+        //

+        //Contorl the selected status when click RadionButton

+        //Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonEnableFeature) {

+            if (jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonDisableFeature) {

+            if (jRadioButtonDisableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Get PPIsDocument.PPIs

+     

+     @return PPIsDocument.PPIs

+     

+     **/

+    public PPIsDocument.PPIs getPpis() {

+        return ppis;

+    }

+

+    /**

+     Set PPIsDocument.PPIs

+     

+     @param ppis The input data of PPIsDocument.PPIs

+     

+     **/

+    public void setPpis(PPIsDocument.PPIs ppis) {

+        this.ppis = ppis;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldC_Name.getText())) {

+            Log.err("C_Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isCName(this.jTextFieldC_Name.getText())) {

+            Log.err("Incorrect data type for C_Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldFeatureFlag.getText())

+            && !DataValidation.isFeatureFlag(this.jTextFieldFeatureFlag.getText())) {

+            Log.err("Incorrect data type for Feature Flag");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of PPIs

+     if exists ppis, set the value directly

+     if not exists ppis, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.ppis == null) {

+                ppis = PPIsDocument.PPIs.Factory.newInstance();

+            }

+            if (this.jRadioButtonPpi.isSelected()) {

+                PPIsDocument.PPIs.Ppi ppi = PPIsDocument.PPIs.Ppi.Factory.newInstance();

+                ppi.setStringValue(this.jTextFieldC_Name.getText());

+                if (!isEmpty(this.jTextFieldGuid.getText())) {

+                    ppi.setGuid(this.jTextFieldGuid.getText());

+                }

+                ppi.setUsage(PpiUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+                ppi.setEnableFeature(this.jRadioButtonEnableFeature.isSelected());

+                if (!isEmpty(this.jTextFieldFeatureFlag.getText())) {

+                    ppi.setFeatureFlag(this.jTextFieldFeatureFlag.getText());

+                }

+                if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                    ppi.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+                }

+                if (location > -1) {

+                    ppis.setPpiArray(location, ppi);

+                } else {

+                    ppis.addNewPpi();

+                    ppis.setPpiArray(ppis.getPpiList().size() - 1, ppi);

+                }

+            }

+            if (this.jRadioButtonPpiNotify.isSelected()) {

+                PPIsDocument.PPIs.PpiNotify ppiNotify = PPIsDocument.PPIs.PpiNotify.Factory.newInstance();

+                ppiNotify.setStringValue(this.jTextFieldC_Name.getText());

+                if (!isEmpty(this.jTextFieldGuid.getText())) {

+                    ppiNotify.setGuid(this.jTextFieldGuid.getText());

+                }

+                ppiNotify.setUsage(PpiNotifyUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+                ppiNotify.setEnableFeature(this.jRadioButtonEnableFeature.isSelected());

+                if (!isEmpty(this.jTextFieldFeatureFlag.getText())) {

+                    ppiNotify.setFeatureFlag(this.jTextFieldFeatureFlag.getText());

+                }

+                if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                    ppiNotify.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+                }

+                if (location > -1) {

+                    ppis.setPpiNotifyArray(location, ppiNotify);

+                } else {

+                    ppis.addNewPpiNotify();

+                    ppis.setPpiNotifyArray(ppis.getPpiNotifyList().size() - 1, ppiNotify);

+                }

+            }

+        } catch (Exception e) {

+            Log.err("Update Protocols", e.getMessage());

+        }

+    }

+

+    /**

+     Enable/Disable relevant fields via different PPI types

+     

+     @param intType The input data of PPI type

+     

+     **/

+    private void initUsage(int intType) {

+        jComboBoxUsage.removeAllItems();

+        if (intType == ModulePpis.PPI) {

+            jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+            jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+            jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+            jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+            jComboBoxUsage.addItem("PRIVATE");

+        }

+        if (intType == ModulePpis.PPI_NOTIFY) {

+            jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleProtocols.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleProtocols.java
new file mode 100644
index 0000000..46955ce
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleProtocols.java
@@ -0,0 +1,705 @@
+/** @file

+ 

+ The file is used to create, update Protocol of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.Dimension;

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+

+import org.tianocore.ProtocolNotifyUsage;

+import org.tianocore.ProtocolUsage;

+import org.tianocore.ProtocolsDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Protocol of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleProtocols extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -9084913640747858848L;

+

+    //

+    //Define class members

+    //

+    private ProtocolsDocument.Protocols protocols = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelFeatureFlag = null;

+

+    private JTextField jTextFieldFeatureFlag = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JLabel jLabelEnableFeature = null;

+

+    private JRadioButton jRadioButtonEnableFeature = null;

+

+    private JRadioButton jRadioButtonDisableFeature = null;

+

+    private JRadioButton jRadioButtonProtocol = null;

+

+    private JRadioButton jRadioButtonProtocolNotify = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private JLabel jLabelProtocolType = null;

+

+    /**

+     This method initializes jTextFieldC_Name 

+     

+     @return javax.swing.JTextField jTextFieldC_Name

+     

+     **/

+    private JTextField getJTextFieldProtocolName() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 60, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldFeatureFlag 

+     

+     @return javax.swing.JTextField jTextFieldFeatureFlag

+     

+     **/

+    private JTextField getJTextFieldFeatureFlag() {

+        if (jTextFieldFeatureFlag == null) {

+            jTextFieldFeatureFlag = new JTextField();

+            jTextFieldFeatureFlag.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jTextFieldFeatureFlag;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 190, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 190, 90, 20));

+            jButtonCancel.setPreferredSize(new Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxProtocolUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 85, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jRadioButtonEnableFeature 

+     

+     @return javax.swing.JRadioButton jRadioButtonEnableFeature

+     

+     **/

+    private JRadioButton getJRadioButtonEnableFeature() {

+        if (jRadioButtonEnableFeature == null) {

+            jRadioButtonEnableFeature = new JRadioButton();

+            jRadioButtonEnableFeature.setText("Enable");

+            jRadioButtonEnableFeature.setBounds(new java.awt.Rectangle(160, 110, 90, 20));

+            jRadioButtonEnableFeature.addActionListener(this);

+            jRadioButtonEnableFeature.setSelected(true);

+        }

+        return jRadioButtonEnableFeature;

+    }

+

+    /**

+     This method initializes jRadioButtonDisableFeature 

+     

+     @return javax.swing.JRadioButton jRadioButtonDisableFeature

+     

+     **/

+    private JRadioButton getJRadioButtonDisableFeature() {

+        if (jRadioButtonDisableFeature == null) {

+            jRadioButtonDisableFeature = new JRadioButton();

+            jRadioButtonDisableFeature.setText("Disable");

+            jRadioButtonDisableFeature.setBounds(new java.awt.Rectangle(320, 110, 90, 20));

+            jRadioButtonDisableFeature.addActionListener(this);

+        }

+        return jRadioButtonDisableFeature;

+    }

+

+    /**

+     This method initializes jRadioButtonProtocol 

+     

+     @return javax.swing.JRadioButton jRadioButtonProtocol

+     

+     **/

+    private JRadioButton getJRadioButtonProtocol() {

+        if (jRadioButtonProtocol == null) {

+            jRadioButtonProtocol = new JRadioButton();

+            jRadioButtonProtocol.setText("Protocol");

+            jRadioButtonProtocol.setBounds(new java.awt.Rectangle(160, 10, 90, 20));

+            jRadioButtonProtocol.setSelected(true);

+            jRadioButtonProtocol.addActionListener(this);

+        }

+        return jRadioButtonProtocol;

+    }

+

+    /**

+     This method initializes jRadioButtonProtocolNotify 

+     

+     @return javax.swing.JRadioButton jRadioButtonProtocolNotify

+     

+     **/

+    private JRadioButton getJRadioButtonProtocolNotify() {

+        if (jRadioButtonProtocolNotify == null) {

+            jRadioButtonProtocolNotify = new JRadioButton();

+            jRadioButtonProtocolNotify.setText("Protocol Notify");

+            jRadioButtonProtocolNotify.setBounds(new java.awt.Rectangle(320, 10, 120, 20));

+            jRadioButtonProtocolNotify.addActionListener(this);

+        }

+        return jRadioButtonProtocolNotify;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 60, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 160, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleProtocols() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inProtocol The input data of ProtocolsDocument.Protocols

+     

+     **/

+    public ModuleProtocols(ProtocolsDocument.Protocols inProtocol) {

+        super();

+        init(inProtocol);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inProtocol The input data of ProtocolsDocument.Protocols

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleProtocols(ProtocolsDocument.Protocols inProtocol, int type, int index) {

+        super();

+        init(inProtocol, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inProtocol The input data of ProtocolsDocument.Protocols

+     

+     **/

+    private void init(ProtocolsDocument.Protocols inProtocol) {

+        init();

+        this.setProtocols(inProtocol);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inProtocol The input data of ProtocolsDocument.Protocols

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(ProtocolsDocument.Protocols inProtocol, int type, int index) {

+        init(inProtocol);

+        this.location = index;

+        if (type == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOL_ITEM) {

+            this.jRadioButtonProtocol.setSelected(true);

+            this.jRadioButtonProtocolNotify.setSelected(false);

+            if (this.protocols.getProtocolArray(index).getStringValue() != null) {

+                this.jTextFieldC_Name.setText(this.protocols.getProtocolArray(index).getStringValue());

+            }

+            if (this.protocols.getProtocolArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.protocols.getProtocolArray(index).getGuid());

+            }

+            if (this.protocols.getProtocolArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.protocols.getProtocolArray(index).getUsage().toString());

+            }

+            this.jRadioButtonEnableFeature.setSelected(this.protocols.getProtocolArray(index).getEnableFeature());

+            this.jRadioButtonDisableFeature.setSelected(!this.protocols.getProtocolArray(index).getEnableFeature());

+            if (this.protocols.getProtocolArray(index).getFeatureFlag() != null) {

+                this.jTextFieldFeatureFlag.setText(this.protocols.getProtocolArray(index).getFeatureFlag());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.protocols.getProtocolArray(index).getOverrideID()));

+        } else if (type == IDefaultMutableTreeNode.PROTOCOLS_PROTOCOLNOTIFY_ITEM) {

+            this.jRadioButtonProtocol.setSelected(false);

+            this.jRadioButtonProtocolNotify.setSelected(true);

+            this.jTextFieldFeatureFlag.setEditable(false);

+            this.jRadioButtonDisableFeature.setEnabled(false);

+            this.jRadioButtonEnableFeature.setEnabled(false);

+            this.jComboBoxUsage.setEnabled(false);

+            if (this.protocols.getProtocolNotifyArray(index).getStringValue() != null) {

+                this.jTextFieldC_Name.setText(this.protocols.getProtocolNotifyArray(index).getStringValue());

+            }

+            if (this.protocols.getProtocolNotifyArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.protocols.getProtocolNotifyArray(index).getGuid());

+            }

+            if (this.protocols.getProtocolNotifyArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.protocols.getProtocolNotifyArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.protocols.getProtocolNotifyArray(index)

+                                                                           .getOverrideID()));

+        }

+        this.jRadioButtonProtocol.setEnabled(false);

+        this.jRadioButtonProtocolNotify.setEnabled(false);

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setName("JFrame");

+        this.setContentPane(getJContentPane());

+        this.setTitle("Protocols");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jRadioButtonProtocol.setEnabled(!isView);

+            this.jRadioButtonProtocolNotify.setEnabled(!isView);

+            this.jTextFieldC_Name.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jRadioButtonEnableFeature.setEnabled(!isView);

+            this.jRadioButtonDisableFeature.setEnabled(!isView);

+            this.jTextFieldFeatureFlag.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelProtocolType = new JLabel();

+            jLabelProtocolType.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jLabelProtocolType.setText("Protocol Type");

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelEnableFeature = new JLabel();

+            jLabelEnableFeature.setText("Enable Feature");

+            jLabelEnableFeature.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelFeatureFlag = new JLabel();

+            jLabelFeatureFlag.setText("Feature Flag");

+            jLabelFeatureFlag.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldProtocolName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelFeatureFlag, null);

+            jContentPane.add(getJTextFieldFeatureFlag(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxProtocolUsage(), null);

+            jContentPane.add(jLabelEnableFeature, null);

+            jContentPane.add(getJRadioButtonEnableFeature(), null);

+            jContentPane.add(getJRadioButtonDisableFeature(), null);

+            jContentPane.add(getJRadioButtonProtocol(), null);

+            jContentPane.add(getJRadioButtonProtocolNotify(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+            jContentPane.add(jLabelProtocolType, null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setBounds(new java.awt.Rectangle(0, 10, 10, 20));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setBounds(new java.awt.Rectangle(0, 35, 10, 20));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("TO_START");

+        jComboBoxUsage.addItem("BY_START");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     * 

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        //

+        // Contorl the selected status when click RadionButton

+        // Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonProtocol) {

+            if (jRadioButtonProtocol.isSelected()) {

+                jRadioButtonProtocolNotify.setSelected(false);

+                jRadioButtonEnableFeature.setEnabled(true);

+                jRadioButtonDisableFeature.setEnabled(true);

+                jTextFieldFeatureFlag.setEnabled(true);

+                jComboBoxUsage.setEnabled(true);

+            }

+            if (!jRadioButtonProtocolNotify.isSelected() && !jRadioButtonProtocol.isSelected()) {

+                jRadioButtonProtocol.setSelected(true);

+                jRadioButtonEnableFeature.setEnabled(true);

+                jRadioButtonDisableFeature.setEnabled(true);

+                jTextFieldFeatureFlag.setEnabled(true);

+                jComboBoxUsage.setEnabled(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonProtocolNotify) {

+            if (jRadioButtonProtocolNotify.isSelected()) {

+                jRadioButtonProtocol.setSelected(false);

+                jRadioButtonEnableFeature.setEnabled(false);

+                jRadioButtonDisableFeature.setEnabled(false);

+                jTextFieldFeatureFlag.setEnabled(false);

+                jComboBoxUsage.setSelectedIndex(1);

+                jComboBoxUsage.setEnabled(false);

+            }

+            if (!jRadioButtonProtocolNotify.isSelected() && !jRadioButtonProtocol.isSelected()) {

+                jRadioButtonProtocolNotify.setSelected(true);

+                jRadioButtonEnableFeature.setEnabled(false);

+                jRadioButtonDisableFeature.setEnabled(false);

+                jTextFieldFeatureFlag.setEnabled(false);

+                jComboBoxUsage.setSelectedIndex(1);

+                jComboBoxUsage.setEnabled(false);

+            }

+        }

+

+        //

+        // Contorl the selected status when click RadionButton

+        // Do not use Radio Button Group

+        //

+        if (arg0.getSource() == jRadioButtonEnableFeature) {

+            if (jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonDisableFeature) {

+            if (jRadioButtonDisableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Get ProtocolsDocument.Protocols

+     

+     @return ProtocolsDocument.Protocols

+     

+     **/

+    public ProtocolsDocument.Protocols getProtocols() {

+        return protocols;

+    }

+

+    /**

+     Set ProtocolsDocument.Protocols

+     

+     @param protocols The input data of ProtocolsDocument.Protocols

+     

+     **/

+    public void setProtocols(ProtocolsDocument.Protocols protocols) {

+        this.protocols = protocols;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldC_Name.getText())) {

+            Log.err("C_Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isCName(this.jTextFieldC_Name.getText())) {

+            Log.err("Incorrect data type for C_Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldFeatureFlag.getText())

+            && !DataValidation.isFeatureFlag(this.jTextFieldFeatureFlag.getText())) {

+            Log.err("Incorrect data type for Feature Flag");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Protocols

+     if exists protocols, set the value directly

+     if not exists protocols, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.protocols == null) {

+                protocols = ProtocolsDocument.Protocols.Factory.newInstance();

+            }

+            if (this.jRadioButtonProtocol.isSelected()) {

+                ProtocolsDocument.Protocols.Protocol protocol = ProtocolsDocument.Protocols.Protocol.Factory

+                                                                                                            .newInstance();

+                protocol.setStringValue(this.jTextFieldC_Name.getText());

+                if (!isEmpty(this.jTextFieldGuid.getText())) {

+                    protocol.setGuid(this.jTextFieldGuid.getText());

+                }

+                protocol.setUsage(ProtocolUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+                protocol.setEnableFeature(this.jRadioButtonEnableFeature.isSelected());

+                if (!isEmpty(this.jTextFieldFeatureFlag.getText())) {

+                    protocol.setFeatureFlag(this.jTextFieldFeatureFlag.getText());

+                }

+                if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                    protocol.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+                }

+                if (location > -1) {

+                    protocols.setProtocolArray(location, protocol);

+                } else {

+                    protocols.addNewProtocol();

+                    protocols.setProtocolArray(protocols.getProtocolList().size() - 1, protocol);

+                }

+            }

+            if (this.jRadioButtonProtocolNotify.isSelected()) {

+                ProtocolsDocument.Protocols.ProtocolNotify protocolNofity = ProtocolsDocument.Protocols.ProtocolNotify.Factory

+                                                                                                                              .newInstance();

+                protocolNofity.setStringValue(this.jTextFieldC_Name.getText());

+                if (!isEmpty(this.jTextFieldGuid.getText())) {

+                    protocolNofity.setGuid(this.jTextFieldGuid.getText());

+                }

+                protocolNofity

+                              .setUsage(ProtocolNotifyUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+

+                if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                    protocolNofity.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+                }

+                if (location > -1) {

+                    protocols.setProtocolNotifyArray(location, protocolNofity);

+                } else {

+                    protocols.addNewProtocolNotify();

+                    protocols.setProtocolNotifyArray(protocols.getProtocolNotifyList().size() - 1, protocolNofity);

+                }

+            }

+        } catch (Exception e) {

+            Log.err("Update Protocols", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleSourceFiles.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleSourceFiles.java
new file mode 100644
index 0000000..036ca9a
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleSourceFiles.java
@@ -0,0 +1,1060 @@
+/** @file

+ 

+ The file is used to create, update SourceFile of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+import java.awt.event.ItemEvent;

+import java.awt.event.ItemListener;

+import java.util.Vector;

+

+import javax.swing.JButton;

+import javax.swing.JCheckBox;

+import javax.swing.JComboBox;

+import javax.swing.JFileChooser;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.FilenameDocument;

+import org.tianocore.SourceFilesDocument;

+import org.tianocore.SupportedArchitectures;

+import org.tianocore.ToolChains;

+import org.tianocore.common.DataType;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IDefaultMutableTreeNode;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+import org.tianocore.packaging.workspace.common.Workspace;

+import javax.swing.JScrollPane;

+import javax.swing.JTextArea;

+

+/**

+ The class is used to create, update SourceFile of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleSourceFiles extends IInternalFrame implements ItemListener {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -6765742852142775378L;

+

+    //

+    // Define class members

+    //

+    private SourceFilesDocument.SourceFiles sourceFiles = null;

+

+    private int location = -1;

+    

+    private int intSelectedItemId = 0;

+

+    //

+    // 1 - Add; 2 - Update

+    //

+    private int operation = -1;

+

+    private Workspace ws = new Workspace();

+

+    private Vector<String> vFileName = new Vector<String>();

+

+    private Vector<String> vGuid = new Vector<String>();

+

+    private Vector<String> vPath = new Vector<String>();

+

+    private Vector<String> vFileType = new Vector<String>();

+

+    private Vector<String> vToolChain = new Vector<String>();

+

+    private Vector<String> vOverrideID = new Vector<String>();

+

+    private JPanel jContentPane = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelFileName = null;

+

+    private JTextField jTextFieldFileName = null;

+

+    private JButton jButtonOpenFile = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JComboBox jComboBoxArch = null;

+

+    private JLabel jLabelPath = null;

+

+    private JTextField jTextFieldPath = null;

+

+    private JLabel jLabelFileType = null;

+

+    private JTextField jTextFieldFileType = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private JComboBox jComboBoxFileList = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonRemove = null;

+

+    private JButton jButtonUpdate = null;

+

+    private JCheckBox jCheckBoxArch = null;

+

+    private JLabel jLabelToolChain = null;

+

+    private JComboBox jComboBoxToolChain = null;

+

+    private JScrollPane jScrollPaneFileList = null;

+

+    private JTextArea jTextAreaFileList = null;

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButton() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 340, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButton1() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 340, 90, 20));

+            jButtonCancel.setPreferredSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldFileName 

+     

+     @return javax.swing.JTextField jTextFieldFileName

+     

+     **/

+    private JTextField getJTextFieldSourceFilesDirectory() {

+        if (jTextFieldFileName == null) {

+            jTextFieldFileName = new JTextField();

+            jTextFieldFileName.setBounds(new java.awt.Rectangle(140,10,250,20));

+        }

+        return jTextFieldFileName;

+    }

+

+    /**

+     This method initializes jButtonOpenFile 

+     

+     @return javax.swing.JButton jButtonOpenFile

+     

+     **/

+    private JButton getJButtonOpenFile() {

+        if (jButtonOpenFile == null) {

+            jButtonOpenFile = new JButton();

+            jButtonOpenFile.setText("Browse");

+            jButtonOpenFile.setBounds(new java.awt.Rectangle(395,10,85,20));

+            jButtonOpenFile.addActionListener(this);

+        }

+        return jButtonOpenFile;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(140,35,250,20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(395,35,85,20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jComboBoxArch 

+     

+     @return javax.swing.JComboBox jComboBoxArch

+     

+     **/

+    private JComboBox getJComboBoxArch() {

+        if (jComboBoxArch == null) {

+            jComboBoxArch = new JComboBox();

+            jComboBoxArch.setBounds(new java.awt.Rectangle(140, 160, 340, 20));

+            jComboBoxArch.setEnabled(false);

+        }

+        return jComboBoxArch;

+    }

+

+    /**

+     This method initializes jTextFieldPath 

+     

+     @return javax.swing.JTextField jTextFieldPath

+     

+     **/

+    private JTextField getJTextFieldPath() {

+        if (jTextFieldPath == null) {

+            jTextFieldPath = new JTextField();

+            jTextFieldPath.setBounds(new java.awt.Rectangle(140, 60, 340, 20));

+        }

+        return jTextFieldPath;

+    }

+

+    /**

+     This method initializes jTextFieldFileType 

+     

+     @return javax.swing.JTextField jTextFieldFileType

+     

+     **/

+    private JTextField getJTextFieldFileType() {

+        if (jTextFieldFileType == null) {

+            jTextFieldFileType = new JTextField();

+            jTextFieldFileType.setBounds(new java.awt.Rectangle(140, 85, 340, 20));

+        }

+        return jTextFieldFileType;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(140, 135, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    /**

+     This method initializes jComboBoxFileList 

+     

+     @return javax.swing.JComboBox jComboBoxFileList

+     

+     **/

+    private JComboBox getJComboBoxFileList() {

+        if (jComboBoxFileList == null) {

+            jComboBoxFileList = new JComboBox();

+            jComboBoxFileList.setBounds(new java.awt.Rectangle(15, 185, 210, 20));

+            jComboBoxFileList.addItemListener(this);

+            jComboBoxFileList.addActionListener(this);

+        }

+        return jComboBoxFileList;

+    }

+

+    /**

+     This method initializes jButtonAdd 

+     

+     @return javax.swing.JButton jButtonAdd

+     

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(230, 185, 80, 20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+     This method initializes jButtonRemove 

+     

+     @return javax.swing.JButton jButtonRemove

+     

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(400, 185, 80, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+     This method initializes jButtonUpdate 

+     

+     @return javax.swing.JButton jButtonUpdate

+     

+     **/

+    private JButton getJButtonUpdate() {

+        if (jButtonUpdate == null) {

+            jButtonUpdate = new JButton();

+            jButtonUpdate.setBounds(new java.awt.Rectangle(315, 185, 80, 20));

+            jButtonUpdate.setText("Update");

+            jButtonUpdate.addActionListener(this);

+        }

+        return jButtonUpdate;

+    }

+

+    /**

+     This method initializes jCheckBoxArch 

+     

+     @return javax.swing.JCheckBox jCheckBoxArch

+     

+     **/

+    private JCheckBox getJCheckBoxArch() {

+        if (jCheckBoxArch == null) {

+            jCheckBoxArch = new JCheckBox();

+            jCheckBoxArch.setBounds(new java.awt.Rectangle(15, 160, 120, 20));

+            jCheckBoxArch.setText("Specific Arch");

+            jCheckBoxArch.addActionListener(this);

+        }

+        return jCheckBoxArch;

+    }

+

+    /**

+     This method initializes jComboBoxToolChain 

+     

+     @return javax.swing.JComboBox jComboBoxToolChain

+     

+     **/

+    private JComboBox getJComboBoxToolChain() {

+        if (jComboBoxToolChain == null) {

+            jComboBoxToolChain = new JComboBox();

+            jComboBoxToolChain.setBounds(new java.awt.Rectangle(140, 110, 340, 20));

+        }

+        return jComboBoxToolChain;

+    }

+

+    /**

+     * This method initializes jScrollPaneFileList	

+     * 	

+     * @return javax.swing.JScrollPane	

+     */

+    private JScrollPane getJScrollPaneFileList() {

+        if (jScrollPaneFileList == null) {

+            jScrollPaneFileList = new JScrollPane();

+            jScrollPaneFileList.setBounds(new java.awt.Rectangle(15,210,465,240));

+            jScrollPaneFileList.setViewportView(getJTextAreaFileList());

+        }

+        return jScrollPaneFileList;

+    }

+

+    /**

+     * This method initializes jTextAreaFileList	

+     * 	

+     * @return javax.swing.JTextArea	

+     */

+    private JTextArea getJTextAreaFileList() {

+        if (jTextAreaFileList == null) {

+            jTextAreaFileList = new JTextArea();

+            jTextAreaFileList.setEditable(false);

+        }

+        return jTextAreaFileList;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleSourceFiles() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inSourceFiles The input data of SourceFilesDocument.SourceFiles

+     

+     **/

+    public ModuleSourceFiles(SourceFilesDocument.SourceFiles inSourceFiles) {

+        super();

+        init(inSourceFiles);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inSourceFiles The input data of SourceFilesDocument.SourceFiles

+     @param type The input data of node type

+     @param index The input data of node index

+     @param inOperation The input data of current operation type

+     

+     **/

+    public ModuleSourceFiles(SourceFilesDocument.SourceFiles inSourceFiles, int type, int index, int inOperation) {

+        super();

+        init(inSourceFiles, type, index, inOperation);

+        this.operation = inOperation;

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inSourceFiles The input data of SourceFilesDocument.SourceFiles

+     

+     **/

+    private void init(SourceFilesDocument.SourceFiles inSourceFiles) {

+        init();

+        this.setSourceFiles(inSourceFiles);

+    }

+

+    /**         

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     

+     @param inSourceFiles The input data of SourceFilesDocument.SourceFiles

+     @param type The input data of node type

+     @param index The input data of node index

+     @param inOperation The input data of current operation type

+     

+     **/

+    private void init(SourceFilesDocument.SourceFiles inSourceFiles, int type, int index, int inOperation) {

+        init(inSourceFiles);

+        this.location = index;

+        this.operation = inOperation;

+

+        //

+        // When update

+        //

+        if (operation == 2) {

+            this.jCheckBoxArch.setEnabled(false);

+            this.jComboBoxArch.setEnabled(false);

+

+            if (type == IDefaultMutableTreeNode.SOURCEFILES_FILENAME) {

+                if (this.sourceFiles.getFilenameList().size() > 0) {

+                    for (int indexI = 0; indexI < this.sourceFiles.getFilenameList().size(); indexI++) {

+                        if (this.sourceFiles.getFilenameArray(indexI).getStringValue() != null) {

+                            vFileName.addElement(this.sourceFiles.getFilenameArray(indexI).getStringValue());

+                        } else {

+                            vFileName.addElement("");

+                        }

+                        if (this.sourceFiles.getFilenameArray(indexI).getGuid() != null) {

+                            vGuid.addElement(this.sourceFiles.getFilenameArray(indexI).getGuid());

+                        } else {

+                            vGuid.addElement("");

+                        }

+                        if (this.sourceFiles.getFilenameArray(indexI).getPath() != null) {

+                            vPath.addElement(this.sourceFiles.getFilenameArray(indexI).getPath());

+                        } else {

+                            vPath.addElement("");

+                        }

+                        if (this.sourceFiles.getFilenameArray(indexI).getFileType() != null) {

+                            vFileType.addElement(this.sourceFiles.getFilenameArray(indexI).getFileType());

+                        } else {

+                            vFileType.addElement("");

+                        }

+                        if (this.sourceFiles.getFilenameArray(indexI).getToolChain() != null) {

+                            vToolChain.addElement(this.sourceFiles.getFilenameArray(indexI).getToolChain().toString());

+                        } else {

+                            vToolChain.addElement(DataType.EMPTY_SELECT_ITEM);

+                        }

+                        vOverrideID.addElement(String.valueOf(this.sourceFiles.getFilenameArray(indexI).getOverrideID()));

+                        jComboBoxFileList.addItem(this.sourceFiles.getFilenameArray(indexI).getStringValue());

+                    }

+                }

+            }

+            if (type == IDefaultMutableTreeNode.SOURCEFILES_ARCH_ITEM) {

+                this.jCheckBoxArch.setSelected(true);

+                this.jComboBoxArch.setSelectedItem(this.sourceFiles.getArchArray(index).getArchType().toString());

+                for (int indexI = 0; indexI < this.sourceFiles.getArchArray(index).getFilenameList().size(); indexI++) {

+                    if (this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getStringValue() != null) {

+                        vFileName.addElement(this.sourceFiles.getArchArray(index).getFilenameArray(indexI)

+                                                             .getStringValue());

+                    } else {

+                        vFileName.addElement("");

+                    }

+                    if (this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getGuid() != null) {

+                        vGuid.addElement(this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getGuid());

+                    } else {

+                        vGuid.addElement("");

+                    }

+                    if (this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getPath() != null) {

+                        vPath.addElement(this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getPath());

+                    } else {

+                        vPath.addElement("");

+                    }

+                    if (this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getFileType() != null) {

+                        vFileType.addElement(this.sourceFiles.getArchArray(index).getFilenameArray(indexI)

+                                                             .getFileType());

+                    } else {

+                        vFileType.addElement("");

+                    }

+                    if (this.sourceFiles.getArchArray(index).getFilenameArray(indexI).getToolChain() != null) {

+                        vToolChain.addElement(this.sourceFiles.getArchArray(index).getFilenameArray(indexI)

+                                                              .getToolChain().toString());

+                    } else {

+                        vToolChain.addElement("");

+                    }

+                    vOverrideID.addElement(String.valueOf(this.sourceFiles.getArchArray(index).getFilenameArray(indexI)

+                                                           .getOverrideID()));

+                    jComboBoxFileList.addItem(this.sourceFiles.getArchArray(index).getFilenameArray(indexI)

+                                                              .getStringValue());

+                }

+            }

+            //

+            // Update the file list

+            //

+            reloadFileListArea();

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Source Files");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jButtonOk.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jTextFieldFileName.setEnabled(!isView);

+            this.jButtonOpenFile.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jTextFieldPath.setEnabled(!isView);

+            this.jTextFieldFileType.setEnabled(!isView);

+            this.jComboBoxToolChain.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+

+            this.jButtonAdd.setEnabled(!isView);

+            this.jButtonRemove.setEnabled(!isView);

+            this.jButtonUpdate.setEnabled(!isView);

+            this.jCheckBoxArch.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelToolChain = new JLabel();

+            jLabelToolChain.setBounds(new java.awt.Rectangle(15, 110, 120, 20));

+            jLabelToolChain.setText("Tool Chain");

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 135, 120, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelFileType = new JLabel();

+            jLabelFileType.setBounds(new java.awt.Rectangle(15, 85, 120, 20));

+            jLabelFileType.setText("File Type");

+            jLabelPath = new JLabel();

+            jLabelPath.setBounds(new java.awt.Rectangle(15, 60, 120, 20));

+            jLabelPath.setText("Path");

+            jLabelGuid = new JLabel();

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 120, 20));

+            jLabelGuid.setText("Guid");

+            jLabelFileName = new JLabel();

+            jLabelFileName.setText("File Name");

+            jLabelFileName.setBounds(new java.awt.Rectangle(15, 10, 120, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setSize(new java.awt.Dimension(480,400));

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButton1(), null);

+            jContentPane.add(jLabelFileName, null);

+            jContentPane.add(getJTextFieldSourceFilesDirectory(), null);

+            jContentPane.add(getJButtonOpenFile(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(getJComboBoxArch(), null);

+            jContentPane.add(jLabelPath, null);

+            jContentPane.add(getJTextFieldPath(), null);

+            jContentPane.add(jLabelFileType, null);

+            jContentPane.add(getJTextFieldFileType(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(getJComboBoxFileList(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(getJButtonUpdate(), null);

+            jContentPane.add(getJCheckBoxArch(), null);

+            jContentPane.add(jLabelToolChain, null);

+            jContentPane.add(getJComboBoxToolChain(), null);

+

+            jContentPane.add(getJScrollPaneFileList(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     *  

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+        if (arg0.getSource() == jButtonOpenFile) {

+            selectFile();

+        }

+        if (arg0.getSource() == jButtonAdd) {

+            if (!checkAdd()) {

+                return;

+            }

+            addToList();

+        }

+        if (arg0.getSource() == jButtonRemove) {

+            removeFromList();

+        }

+        if (arg0.getSource() == jButtonUpdate) {

+            if (!checkAdd()) {

+                return;

+            }

+            updateForList();

+        }

+

+        //

+        //When and only when checked Arch box then can choose different arch types

+        //

+        if (arg0.getSource() == jCheckBoxArch) {

+            if (this.jCheckBoxArch.isSelected()) {

+                this.jComboBoxArch.setEnabled(true);

+            } else {

+                this.jComboBoxArch.setEnabled(false);

+            }

+        }

+    }

+

+    /**

+     This method initializes Usage type and Arch type

+     

+     **/

+    private void initFrame() {

+        jComboBoxArch.addItem("ALL");

+        jComboBoxArch.addItem("EBC");

+        jComboBoxArch.addItem("ARM");

+        jComboBoxArch.addItem("IA32");

+        jComboBoxArch.addItem("X64");

+        jComboBoxArch.addItem("IPF");

+        jComboBoxArch.addItem("PPC");

+

+        jComboBoxToolChain.addItem(DataType.EMPTY_SELECT_ITEM);

+        jComboBoxToolChain.addItem("MSFT");

+        jComboBoxToolChain.addItem("INTEL");

+        jComboBoxToolChain.addItem("GCC");

+        jComboBoxToolChain.addItem("CYGWIN");

+    }

+

+    /**

+     Add current item to Vector

+     

+     **/

+    private void addToList() {

+        intSelectedItemId = vFileName.size();

+        vFileName.addElement(this.jTextFieldFileName.getText());

+        vGuid.addElement(this.jTextFieldGuid.getText());

+        vPath.addElement(this.jTextFieldPath.getText());

+        vFileType.addElement(this.jTextFieldFileType.getText());

+        vToolChain.addElement(this.jComboBoxToolChain.getSelectedItem().toString());

+        vOverrideID.addElement(this.jTextFieldOverrideID.getText());

+        jComboBoxFileList.addItem(this.jTextFieldFileName.getText());

+        jComboBoxFileList.setSelectedItem(this.jTextFieldFileName.getText());

+        

+        //

+        // Reset select item index

+        //

+        intSelectedItemId = vFileName.size();

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Remove current item from Vector

+     

+     **/

+    private void removeFromList() {

+        int intTempIndex = intSelectedItemId;

+        if (vFileName.size() < 1) {

+            return;

+        }

+        

+        jComboBoxFileList.removeItemAt(intSelectedItemId);

+        

+        vFileName.removeElementAt(intTempIndex);

+        vGuid.removeElementAt(intTempIndex);

+        vPath.removeElementAt(intTempIndex);

+        vFileType.removeElementAt(intTempIndex);

+        vToolChain.removeElementAt(intTempIndex);

+        vOverrideID.removeElementAt(intTempIndex);

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Update current item of Vector

+     

+     **/

+    private void updateForList() {

+        //

+        // Backup selected item index

+        //

+        int intTempIndex = intSelectedItemId;

+        vFileName.setElementAt(this.jTextFieldFileName.getText(), intSelectedItemId);

+        vGuid.setElementAt(this.jTextFieldGuid.getText(), intSelectedItemId);

+        vPath.setElementAt(this.jTextFieldPath.getText(), intSelectedItemId);

+        vFileType.setElementAt(this.jTextFieldFileType.getText(), intSelectedItemId);

+        vToolChain.setElementAt(this.jComboBoxToolChain.getSelectedItem().toString(), intSelectedItemId);

+        vOverrideID.setElementAt(this.jTextFieldOverrideID.getText(), intSelectedItemId);

+        jComboBoxFileList.removeAllItems();

+        for (int index = 0; index < vFileName.size(); index++) {

+            jComboBoxFileList.addItem(vFileName.elementAt(index));

+        }

+        

+        //

+        // Restore selected item index

+        //

+        intSelectedItemId = intTempIndex;

+        

+        //

+        // Reset select item index

+        //

+        jComboBoxFileList.setSelectedIndex(intSelectedItemId);

+        

+        //

+        // Reload all fields of selected item

+        //

+        reloadFromList();

+    }

+

+    /**

+     Refresh all fields' values of selected item of Vector

+     

+     **/

+    private void reloadFromList() {

+        if (vFileName.size() > 0) {

+            //

+            // Get selected item index

+            //

+            intSelectedItemId = jComboBoxFileList.getSelectedIndex();

+            

+            this.jTextFieldFileName.setText(vFileName.elementAt(intSelectedItemId).toString());

+            this.jTextFieldGuid.setText(vGuid.elementAt(intSelectedItemId).toString());

+            this.jTextFieldPath.setText(vPath.elementAt(intSelectedItemId).toString());

+            this.jTextFieldFileType.setText(vFileType.elementAt(intSelectedItemId).toString());

+            this.jComboBoxToolChain.setSelectedItem(vToolChain.elementAt(intSelectedItemId).toString());

+            this.jTextFieldOverrideID.setText(vOverrideID.elementAt(intSelectedItemId).toString());    

+        } else {

+            this.jTextFieldFileName.setText("");

+            this.jTextFieldGuid.setText("");

+            this.jTextFieldPath.setText("");

+            this.jTextFieldFileType.setText("");

+            this.jComboBoxToolChain.setSelectedItem(DataType.EMPTY_SELECT_ITEM);

+            this.jTextFieldOverrideID.setText("");

+        }

+        

+        reloadFileListArea();

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)

+     *

+     * Reflesh the frame when selected item changed

+     * 

+     */

+    public void itemStateChanged(ItemEvent arg0) {

+        if (arg0.getStateChange() == ItemEvent.SELECTED) {

+            reloadFromList();

+        }

+    }

+

+    /**

+     Get SourceFilesDocument.SourceFiles

+     

+     @return SourceFilesDocument.SourceFiles

+     

+     **/

+    public SourceFilesDocument.SourceFiles getSourceFiles() {

+        return sourceFiles;

+    }

+

+    /**

+     Set SourceFilesDocument.SourceFiles

+     

+     @param sourceFiles The input data of SourceFilesDocument.SourceFiles

+     

+     **/

+    public void setSourceFiles(SourceFilesDocument.SourceFiles sourceFiles) {

+        this.sourceFiles = sourceFiles;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        if (this.jComboBoxFileList.getItemCount() < 1) {

+            Log.err("Must have one file at least!");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean checkAdd() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldFileName.getText())) {

+            Log.err("File Name couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isFileName(this.jTextFieldFileName.getText())) {

+            Log.err("Incorrect data type for File Name");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldPath.getText()) && !DataValidation.isPath(this.jTextFieldPath.getText())) {

+            Log.err("Incorrect data type for Path");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of SourceFiles

+     if exists sourceFiles, set the value directly

+     if not exists sourceFiles, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.sourceFiles == null) {

+                sourceFiles = SourceFilesDocument.SourceFiles.Factory.newInstance();

+            }

+            //

+            //Save as file name

+            //

+            if (!this.jCheckBoxArch.isSelected()) {

+                if (this.operation == 2) { //Add new filename

+                    //

+                    //First remove all existed filename

+                    //

+                    if (sourceFiles.getFilenameList().size() > 0) {

+                        for (int index = sourceFiles.getFilenameList().size() - 1; index >= 0; index--) {

+                            sourceFiles.removeFilename(index);

+                        }

+                    }

+                }

+                for (int index = 0; index < vFileName.size(); index++) {

+                    FilenameDocument.Filename filename = FilenameDocument.Filename.Factory.newInstance();

+                    if (!isEmpty(vFileName.elementAt(index).toString())) {

+                        filename.setStringValue(vFileName.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vGuid.elementAt(index).toString())) {

+                        filename.setGuid(vGuid.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vPath.elementAt(index).toString())) {

+                        filename.setPath(vPath.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vFileType.elementAt(index).toString())) {

+                        filename.setFileType(vFileType.elementAt(index).toString());

+                    }

+                    if (!vToolChain.elementAt(index).toString().equals(DataType.EMPTY_SELECT_ITEM)) {

+                        filename.setToolChain(ToolChains.Enum.forString(vToolChain.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vOverrideID.elementAt(index).toString())) {

+                        filename.setOverrideID(Integer.parseInt(vOverrideID.elementAt(index).toString()));

+                    }

+                    sourceFiles.addNewFilename();

+                    sourceFiles.setFilenameArray(sourceFiles.getFilenameList().size() - 1, filename);

+                }

+            }

+            //

+            //Save as Arch

+            //

+            if (this.jCheckBoxArch.isSelected()) {

+                SourceFilesDocument.SourceFiles.Arch arch = SourceFilesDocument.SourceFiles.Arch.Factory.newInstance();

+                if (this.operation == 2) {

+                    //

+                    //First remove all existed filename

+                    //

+                    for (int index = sourceFiles.getArchArray(location).getFilenameList().size() - 1; index >= 0; index--) {

+                        sourceFiles.getArchArray(location).removeFilename(index);

+                    }

+                }

+                for (int index = 0; index < vFileName.size(); index++) {

+                    FilenameDocument.Filename filename = FilenameDocument.Filename.Factory.newInstance();

+                    if (!isEmpty(vFileName.elementAt(index).toString())) {

+                        filename.setStringValue(vFileName.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vGuid.elementAt(index).toString())) {

+                        filename.setGuid(vGuid.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vPath.elementAt(index).toString())) {

+                        filename.setPath(vPath.elementAt(index).toString());

+                    }

+                    if (!isEmpty(vFileType.elementAt(index).toString())) {

+                        filename.setFileType(vFileType.elementAt(index).toString());

+                    }

+                    if (!vToolChain.elementAt(index).toString().equals(DataType.EMPTY_SELECT_ITEM)) {

+                        filename.setToolChain(ToolChains.Enum.forString(vToolChain.elementAt(index).toString()));

+                    }

+                    if (!isEmpty(vOverrideID.elementAt(index).toString())) {

+                        filename.setOverrideID(Integer.parseInt(vOverrideID.elementAt(index).toString()));

+                    }

+                    arch.addNewFilename();

+                    arch.setFilenameArray(arch.getFilenameList().size() - 1, filename);

+                }

+                arch

+                    .setArchType(SupportedArchitectures.Enum.forString(this.jComboBoxArch.getSelectedItem().toString()));

+                if (location > -1) {

+                    sourceFiles.setArchArray(location, arch);

+                } else {

+                    sourceFiles.addNewArch();

+                    sourceFiles.setArchArray(sourceFiles.getArchList().size() - 1, arch);

+                }

+            }

+        } catch (Exception e) {

+            Log.err("Update Source Files", e.getMessage());

+        }

+    }

+

+    /**

+     Display a file open browser to let user select file

+     

+     **/

+    private void selectFile() {

+        JFileChooser fc = new JFileChooser(ws.getCurrentWorkspace());

+

+        int result = fc.showOpenDialog(new JPanel());

+        if (result == JFileChooser.APPROVE_OPTION) {

+            this.jTextFieldFileName.setText(fc.getSelectedFile().getName());

+        }

+    }

+    

+    /**

+    Update file list pane via the elements of Vector

+    

+    **/

+    private void reloadFileListArea() {

+        String strFileList = "";

+        for (int index = 0; index < vFileName.size(); index++) {

+            strFileList = strFileList + vFileName.elementAt(index).toString() + DataType.UNXI_LINE_SEPARATOR;

+        }

+        this.jTextAreaFileList.setText(strFileList);

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleSystemTables.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleSystemTables.java
new file mode 100644
index 0000000..aff195e
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleSystemTables.java
@@ -0,0 +1,393 @@
+/** @file

+

+ The file is used to create, update SystemTable of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.SystemTableUsage;

+import org.tianocore.SystemTablesDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update SystemTable of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleSystemTables extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 7488769180379442276L;

+

+    //

+    //Define class members

+    //

+    private SystemTablesDocument.SystemTables systemTables = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelEntry = null;

+

+    private JTextField jTextFieldEntry = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    /**

+     This method initializes jTextFieldEntry 

+     

+     @return javax.swing.JTextField jTextFieldEntry

+     

+     **/

+    private JTextField getJTextFieldEntry() {

+        if (jTextFieldEntry == null) {

+            jTextFieldEntry = new JTextField();

+            jTextFieldEntry.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldEntry;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(280, 90, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 90, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 60, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleSystemTables() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inSystemTables The input data of SystemTablesDocument.SystemTables

+     

+     **/

+    public ModuleSystemTables(SystemTablesDocument.SystemTables inSystemTables) {

+        super();

+        init(inSystemTables);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inSystemTables The input data of SystemTablesDocument.SystemTables

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleSystemTables(SystemTablesDocument.SystemTables inSystemTables, int type, int index) {

+        super();

+        init(inSystemTables, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inSystemTables The input data of SystemTablesDocument.SystemTables

+     

+     **/

+    private void init(SystemTablesDocument.SystemTables inSystemTables) {

+        init();

+        this.setSystemTables(inSystemTables);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inSystemTables The input data of SystemTablesDocument.SystemTables

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(SystemTablesDocument.SystemTables inSystemTables, int type, int index) {

+        init(inSystemTables);

+        this.location = index;

+        if (this.systemTables.getSystemTableList().size() > 0) {

+            if (this.systemTables.getSystemTableArray(index).getEntry() != null) {

+                this.jTextFieldEntry.setText(this.systemTables.getSystemTableArray(index).getEntry());

+            }

+            if (this.systemTables.getSystemTableArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.systemTables.getSystemTableArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.systemTables.getSystemTableArray(index)

+                                                                              .getOverrideID()));

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("System Tables");

+        initFrame();

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldEntry.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelOverrideID.setText("Override ID");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelEntry = new JLabel();

+            jLabelEntry.setText("Entry");

+            jLabelEntry.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelEntry, null);

+            jContentPane.add(getJTextFieldEntry(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setBounds(new java.awt.Rectangle(0, 10, 10, 20));

+

+            jContentPane.add(jStarLabel1, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     *  Override actionPerformed to listen all actions

+     *  

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+    }

+

+    /**

+     Get SystemTablesDocument.SystemTables

+     

+     @return SystemTablesDocument.SystemTables

+     

+     **/

+    public SystemTablesDocument.SystemTables getSystemTables() {

+        return systemTables;

+    }

+

+    /**

+     Set SystemTablesDocument.SystemTables

+     

+     @param systemTables The input data of SystemTablesDocument.SystemTables

+     

+     **/

+    public void setSystemTables(SystemTablesDocument.SystemTables systemTables) {

+        this.systemTables = systemTables;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldEntry.getText())) {

+            Log.err("Entry couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of SystemTables

+     if exists systemTables, set the value directly

+     if not exists systemTables, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.systemTables == null) {

+                systemTables = SystemTablesDocument.SystemTables.Factory.newInstance();

+            }

+            SystemTablesDocument.SystemTables.SystemTable systemTable = SystemTablesDocument.SystemTables.SystemTable.Factory

+                                                                                                                             .newInstance();

+            systemTable.setEntry(this.jTextFieldEntry.getText());

+

+            systemTable.setUsage(SystemTableUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                systemTable.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+            if (location > -1) {

+                systemTables.setSystemTableArray(location, systemTable);

+            } else {

+                systemTables.addNewSystemTable();

+                systemTables.setSystemTableArray(systemTables.getSystemTableList().size() - 1, systemTable);

+            }

+        } catch (Exception e) {

+            Log.err("Update System Tables", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleVariables.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleVariables.java
new file mode 100644
index 0000000..90a2859
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/ModuleVariables.java
@@ -0,0 +1,601 @@
+/** @file

+ 

+ The file is used to create, update Variable of MSA/MBD file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JTextField;

+

+import org.tianocore.GuidDocument;

+import org.tianocore.VariableUsage;

+import org.tianocore.VariablesDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update Variable of MSA/MBD file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class ModuleVariables extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -6998982978030439446L;

+

+    //

+    //Define class members

+    //

+    private VariablesDocument.Variables variables = null;

+

+    private int location = -1;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelString = null;

+

+    private JTextField jTextFieldString = null;

+

+    private JLabel jLabelBitOffset = null;

+

+    private JTextField jTextFieldBitOffset = null;

+

+    private JLabel jLabelByteOffset = null;

+

+    private JTextField jTextFieldByteOffset = null;

+

+    private JLabel jLabelOffsetBitSize = null;

+

+    private JTextField jTextFieldOffsetBitSize = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private JLabel jLabelByteOffsetHint = null;

+

+    private JLabel jLabelBitOffsetHint = null;

+

+    private JLabel jLabelOffsetBitSizeHint = null;

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setSize(new java.awt.Dimension(250, 20));

+            jTextFieldGuid.setLocation(new java.awt.Point(160, 35));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldString 

+     

+     @return javax.swing.JTextField jTextFieldString

+     

+     **/

+    private JTextField getJTextFieldString() {

+        if (jTextFieldString == null) {

+            jTextFieldString = new JTextField();

+            jTextFieldString.setSize(new java.awt.Dimension(320, 20));

+            jTextFieldString.setLocation(new java.awt.Point(160, 10));

+        }

+        return jTextFieldString;

+    }

+

+    /**

+     This method initializes jTextFieldBitOffset 

+     

+     @return javax.swing.JTextField jTextFieldBitOffset

+     

+     **/

+    private JTextField getJTextFieldBitOffset() {

+        if (jTextFieldBitOffset == null) {

+            jTextFieldBitOffset = new JTextField();

+            jTextFieldBitOffset.setSize(new java.awt.Dimension(80, 20));

+            jTextFieldBitOffset.setLocation(new java.awt.Point(160, 85));

+        }

+        return jTextFieldBitOffset;

+    }

+

+    /**

+     This method initializes jTextFieldByteOffset 

+     

+     @return javax.swing.JTextField jTextFieldByteOffset

+     

+     **/

+    private JTextField getJTextFieldByteOffset() {

+        if (jTextFieldByteOffset == null) {

+            jTextFieldByteOffset = new JTextField();

+            jTextFieldByteOffset.setLocation(new java.awt.Point(160, 60));

+            jTextFieldByteOffset.setSize(new java.awt.Dimension(80, 20));

+        }

+        return jTextFieldByteOffset;

+    }

+

+    /**

+     This method initializes jTextFieldBitSize 

+     

+     @return javax.swing.JTextField jTextFieldOffsetBitSize

+     

+     **/

+    private JTextField getJTextFieldOffsetBitSize() {

+        if (jTextFieldOffsetBitSize == null) {

+            jTextFieldOffsetBitSize = new JTextField();

+            jTextFieldOffsetBitSize.setSize(new java.awt.Dimension(80, 20));

+            jTextFieldOffsetBitSize.setLocation(new java.awt.Point(160, 110));

+        }

+        return jTextFieldOffsetBitSize;

+    }

+

+    /**

+     This method initializes jComboBoxUsage 

+     

+     @return javax.swing.JComboBox jComboBoxUsage

+     

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 190, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 190, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID 

+     

+     @return javax.swing.JTextField jTextFieldOverrideID

+     

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(160, 160, 50, 20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public ModuleVariables() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inVariables The input data of VariablesDocument.Variables

+     

+     **/

+    public ModuleVariables(VariablesDocument.Variables inVariables) {

+        super();

+        init(inVariables);

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inVariables The input data of VariablesDocument.Variables

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    public ModuleVariables(VariablesDocument.Variables inVariables, int type, int index) {

+        super();

+        init(inVariables, type, index);

+        this.setVisible(true);

+    }

+

+    /**

+     This method initializes this

+     

+     @param inVariables The input data of VariablesDocument.Variables

+     

+     **/

+    private void init(VariablesDocument.Variables inVariables) {

+        init();

+        this.setVariables(inVariables);

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inVariables The input data of VariablesDocument.Variables

+     @param type The input data of node type

+     @param index The input data of node index

+     

+     **/

+    private void init(VariablesDocument.Variables inVariables, int type, int index) {

+        init(inVariables);

+        this.location = index;

+        if (this.variables.getVariableList().size() > 0) {

+            if (this.variables.getVariableArray(index).getString() != null) {

+                this.jTextFieldString.setText(this.variables.getVariableArray(index).getString());

+            }

+            if (this.variables.getVariableArray(index).getGuid() != null) {

+                this.jTextFieldGuid.setText(this.variables.getVariableArray(index).getGuid().getStringValue());

+            }

+            if (this.variables.getVariableArray(index).getByteOffset() != null) {

+                this.jTextFieldByteOffset

+                                         .setText(String

+                                                        .valueOf(this.variables.getVariableArray(index).getByteOffset()));

+            }

+            if (String.valueOf(this.variables.getVariableArray(index).getBitOffset()) != null) {

+                this.jTextFieldBitOffset.setText(String.valueOf(this.variables.getVariableArray(index).getBitOffset()));

+            }

+            if (String.valueOf(this.variables.getVariableArray(index).getOffsetBitSize()) != null) {

+                this.jTextFieldOffsetBitSize.setText(String.valueOf(this.variables.getVariableArray(index)

+                                                                                  .getOffsetBitSize()));

+            }

+            if (this.variables.getVariableArray(index).getUsage() != null) {

+                this.jComboBoxUsage.setSelectedItem(this.variables.getVariableArray(index).getUsage().toString());

+            }

+            this.jTextFieldOverrideID.setText(String.valueOf(this.variables.getVariableArray(index).getOverrideID()));

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Add Variables");

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldString.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jTextFieldByteOffset.setEnabled(!isView);

+            this.jTextFieldBitOffset.setEnabled(!isView);

+            this.jTextFieldOffsetBitSize.setEnabled(!isView);

+            this.jComboBoxUsage.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jTextFieldOverrideID.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelByteOffsetHint = new JLabel();

+            jLabelByteOffsetHint.setBounds(new java.awt.Rectangle(245,60,235,20));

+            jLabelByteOffsetHint.setText("0x00");

+            jLabelOffsetBitSizeHint = new JLabel();

+            jLabelOffsetBitSizeHint.setBounds(new java.awt.Rectangle(245,110,235,20));

+            jLabelOffsetBitSizeHint.setText("1~7");

+            jLabelBitOffsetHint = new JLabel();

+            jLabelBitOffsetHint.setBounds(new java.awt.Rectangle(245,85,235,20));

+            jLabelBitOffsetHint.setText("0~7");

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setText("Override ID");

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelUsage = new JLabel();

+            jLabelUsage.setText("Usage");

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelOffsetBitSize = new JLabel();

+            jLabelOffsetBitSize.setText("Offset Bit Size");

+            jLabelOffsetBitSize.setLocation(new java.awt.Point(15, 110));

+            jLabelOffsetBitSize.setSize(new java.awt.Dimension(140, 20));

+            jLabelByteOffset = new JLabel();

+            jLabelByteOffset.setText("Byte Offset");

+            jLabelByteOffset.setLocation(new java.awt.Point(15, 60));

+            jLabelByteOffset.setSize(new java.awt.Dimension(140, 20));

+            jLabelBitOffset = new JLabel();

+            jLabelBitOffset.setText("Bit Offset");

+            jLabelBitOffset.setLocation(new java.awt.Point(15, 85));

+            jLabelBitOffset.setSize(new java.awt.Dimension(140, 20));

+            jLabelString = new JLabel();

+            jLabelString.setText("String");

+            jLabelString.setLocation(new java.awt.Point(15, 10));

+            jLabelString.setSize(new java.awt.Dimension(140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setLocation(new java.awt.Point(15, 35));

+            jLabelGuid.setSize(new java.awt.Dimension(140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelString, null);

+            jContentPane.add(getJTextFieldString(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelByteOffset, null);

+            jContentPane.add(getJTextFieldByteOffset(), null);

+            jContentPane.add(jLabelBitOffset, null);

+            jContentPane.add(getJTextFieldBitOffset(), null);

+            jContentPane.add(jLabelOffsetBitSize, null);

+            jContentPane.add(getJTextFieldOffsetBitSize(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+

+            jContentPane.add(jLabelByteOffsetHint, null);

+            jContentPane.add(jLabelBitOffsetHint, null);

+            jContentPane.add(jLabelOffsetBitSizeHint, null);

+            initFrame();

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     *  

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.setEdited(true);

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     This method initializes Usage type

+     

+     **/

+    private void initFrame() {

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /**

+     Get VariablesDocument.Variables

+     

+     @return VariablesDocument.Variables

+     

+     **/

+    public VariablesDocument.Variables getVariables() {

+        return variables;

+    }

+

+    /**

+     Set VariablesDocument.Variables

+     

+     @param variables The input data of VariablesDocument.Variables

+     

+     **/

+    public void setVariables(VariablesDocument.Variables variables) {

+        this.variables = variables;

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldString.getText())) {

+            Log.err("String couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldGuid.getText())) {

+            Log.err("Guid couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!isEmpty(this.jTextFieldGuid.getText()) && !DataValidation.isGuid(this.jTextFieldGuid.getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldByteOffset.getText())

+            && !DataValidation.isByteOffset(this.jTextFieldByteOffset.getText())) {

+            Log.err("Incorrect data type for Byte Offset");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldBitOffset.getText())

+            && !DataValidation.isBitOffset(this.jTextFieldBitOffset.getText())) {

+            Log.err("Incorrect data type for Bit Offset");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOffsetBitSize.getText())

+            && !DataValidation.isOffsetBitSize(this.jTextFieldOffsetBitSize.getText())) {

+            Log.err("Incorrect data type for Bit Offset");

+            return false;

+        }

+        if (!isEmpty(this.jTextFieldOverrideID.getText())

+            && !DataValidation.isOverrideID(this.jTextFieldOverrideID.getText())) {

+            Log.err("Incorrect data type for Override ID");

+            return false;

+        }

+

+        return true;

+    }

+

+    /**

+     Save all components of Variables

+     if exists variables, set the value directly

+     if not exists variables, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.variables == null) {

+                variables = VariablesDocument.Variables.Factory.newInstance();

+            }

+            VariablesDocument.Variables.Variable variable = VariablesDocument.Variables.Variable.Factory.newInstance();

+            if (!isEmpty(this.jTextFieldString.getText())) {

+                variable.setString(this.jTextFieldString.getText());

+            }

+            if (!isEmpty(this.jTextFieldGuid.getText())) {

+                GuidDocument.Guid guid = GuidDocument.Guid.Factory.newInstance();

+                guid.setStringValue(this.jTextFieldGuid.getText());

+                variable.setGuid(guid);

+            }

+            if (!isEmpty(this.jTextFieldByteOffset.getText())) {

+                variable.setByteOffset(this.jTextFieldByteOffset.getText());

+            }

+            if (!isEmpty(this.jTextFieldBitOffset.getText())) {

+                variable.setBitOffset(Integer.parseInt(this.jTextFieldBitOffset.getText()));

+            }

+            if (!isEmpty(this.jTextFieldBitOffset.getText())) {

+                variable.setOffsetBitSize(Integer.parseInt(this.jTextFieldBitOffset.getText()));

+            }

+            variable.setUsage(VariableUsage.Enum.forString(jComboBoxUsage.getSelectedItem().toString()));

+            if (!isEmpty(this.jTextFieldOverrideID.getText())) {

+                variable.setOverrideID(Integer.parseInt(this.jTextFieldOverrideID.getText()));

+            }

+            if (location > -1) {

+                variables.setVariableArray(location, variable);

+            } else {

+                variables.addNewVariable();

+                variables.setVariableArray(variables.getVariableList().size() - 1, variable);

+            }

+        } catch (Exception e) {

+            Log.err("Update Variables", e.getMessage());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MsaHeader.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MsaHeader.java
new file mode 100644
index 0000000..e168288
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MsaHeader.java
@@ -0,0 +1,795 @@
+/** @file

+ 

+ The file is used to create, update MsaHeader of MSA file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JScrollPane;

+import javax.swing.JTextArea;

+import javax.swing.JTextField;

+

+import org.tianocore.AbstractDocument;

+import org.tianocore.BaseNameDocument;

+import org.tianocore.FrameworkComponentTypes;

+import org.tianocore.GuidDocument;

+import org.tianocore.LicenseDocument;

+import org.tianocore.ModuleTypeDef;

+import org.tianocore.MsaHeaderDocument;

+import org.tianocore.SpecificationDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update MsaHeader of MSA file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class MsaHeader extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = -8152099582923006900L;

+

+    //

+    //Define class members

+    //

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelBaseName = null;

+

+    private JTextField jTextFieldBaseName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelLicense = null;

+

+    private JTextArea jTextAreaLicense = null;

+

+    private JLabel jLabelCopyright = null;

+

+    private JLabel jLabelDescription = null;

+

+    private JTextArea jTextAreaDescription = null;

+

+    private JLabel jLabelSpecification = null;

+

+    private JTextField jTextFieldSpecification = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JScrollPane jScrollPaneLicense = null;

+

+    private JScrollPane jScrollPaneDescription = null;

+

+    private JLabel jLabelAbstract = null;

+

+    private JTextField jTextFieldAbstract = null;

+

+    private JLabel jLabelModuleType = null;

+

+    private JLabel jLabelCompontentType = null;

+

+    private JComboBox jComboBoxCompontentType = null;

+

+    private JComboBox jComboBoxModuleType = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+

+    private StarLabel jStarLabel5 = null;

+

+    private StarLabel jStarLabel6 = null;

+

+    private StarLabel jStarLabel7 = null;

+

+    private StarLabel jStarLabel8 = null;

+

+    private StarLabel jStarLabel9 = null;

+

+    private MsaHeaderDocument.MsaHeader msaHeader = null;

+

+    private JLabel jLabelURL = null;

+

+    private JTextField jTextFieldAbstractURL = null;

+

+    private JTextField jTextFieldCopyright = null;

+

+    /**

+     This method initializes jTextFieldBaseName 

+     

+     @return javax.swing.JTextField jTextFieldBaseName

+     

+     **/

+    private JTextField getJTextFieldBaseName() {

+        if (jTextFieldBaseName == null) {

+            jTextFieldBaseName = new JTextField();

+            jTextFieldBaseName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldBaseName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldVersion 

+     

+     @return javax.swing.JTextField jTextFieldVersion

+     

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextAreaLicense 

+     

+     @return javax.swing.JTextArea jTextAreaLicense

+     

+     **/

+    private JTextArea getJTextAreaLicense() {

+        if (jTextAreaLicense == null) {

+            jTextAreaLicense = new JTextArea();

+            jTextAreaLicense.setText("");

+            jTextAreaLicense.setLineWrap(true);

+        }

+        return jTextAreaLicense;

+    }

+

+    /**

+     This method initializes jTextAreaDescription 

+     

+     @return javax.swing.JTextArea jTextAreaDescription

+     

+     **/

+    private JTextArea getJTextAreaDescription() {

+        if (jTextAreaDescription == null) {

+            jTextAreaDescription = new JTextArea();

+            jTextAreaDescription.setLineWrap(true);

+        }

+        return jTextAreaDescription;

+    }

+

+    /**

+     This method initializes jTextFieldSpecification 

+     

+     @return javax.swing.JTextField jTextFieldSpecification

+     

+     **/

+    private JTextField getJTextFieldSpecification() {

+        if (jTextFieldSpecification == null) {

+            jTextFieldSpecification = new JTextField();

+            jTextFieldSpecification.setBounds(new java.awt.Rectangle(160, 280, 320, 20));

+        }

+        return jTextFieldSpecification;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 445, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 445, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPaneLicense 

+     

+     @return javax.swing.JScrollPane jScrollPaneLicense

+     

+     **/

+    private JScrollPane getJScrollPaneLicense() {

+        if (jScrollPaneLicense == null) {

+            jScrollPaneLicense = new JScrollPane();

+            jScrollPaneLicense.setBounds(new java.awt.Rectangle(160, 85, 320, 80));

+            jScrollPaneLicense.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneLicense.setViewportView(getJTextAreaLicense());

+        }

+        return jScrollPaneLicense;

+    }

+

+    /**

+     This method initializes jScrollPaneDescription 

+     

+     @return javax.swing.JScrollPane jScrollPaneDescription

+     

+     **/

+    private JScrollPane getJScrollPaneDescription() {

+        if (jScrollPaneDescription == null) {

+            jScrollPaneDescription = new JScrollPane();

+            jScrollPaneDescription.setBounds(new java.awt.Rectangle(160, 195, 320, 80));

+            jScrollPaneDescription.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneDescription.setViewportView(getJTextAreaDescription());

+        }

+        return jScrollPaneDescription;

+    }

+

+    /**

+     This method initializes jTextFieldAbstract 

+     

+     @return javax.swing.JTextField jTextFieldAbstract

+     

+     **/

+    private JTextField getJTextFieldAbstract() {

+        if (jTextFieldAbstract == null) {

+            jTextFieldAbstract = new JTextField();

+            jTextFieldAbstract.setBounds(new java.awt.Rectangle(160, 305, 320, 20));

+        }

+        return jTextFieldAbstract;

+    }

+

+    /**

+     This method initializes jComboBoxCompontentType 

+     

+     @return javax.swing.JComboBox jComboBoxCompontentType

+     

+     **/

+    private JComboBox getJComboBoxCompontentType() {

+        if (jComboBoxCompontentType == null) {

+            jComboBoxCompontentType = new JComboBox();

+            jComboBoxCompontentType.setBounds(new java.awt.Rectangle(160, 380, 320, 20));

+        }

+        return jComboBoxCompontentType;

+    }

+

+    /**

+     This method initializes jComboBoxModuleType 

+     

+     @return javax.swing.JComboBox jComboBoxModuleType

+     

+     **/

+    private JComboBox getJComboBoxModuleType() {

+        if (jComboBoxModuleType == null) {

+            jComboBoxModuleType = new JComboBox();

+            jComboBoxModuleType.setBounds(new java.awt.Rectangle(160, 355, 320, 20));

+        }

+        return jComboBoxModuleType;

+    }

+

+    /**

+     This method initializes jTextFieldAbstractURL 

+     

+     @return javax.swing.JTextField jTextFieldAbstractURL

+     

+     **/

+    private JTextField getJTextFieldAbstractURL() {

+        if (jTextFieldAbstractURL == null) {

+            jTextFieldAbstractURL = new JTextField();

+            jTextFieldAbstractURL.setBounds(new java.awt.Rectangle(160, 330, 320, 20));

+        }

+        return jTextFieldAbstractURL;

+    }

+

+    /**

+      This method initializes jTextFieldCopyright	

+      	

+      @return javax.swing.JTextField jTextFieldCopyright

+     

+     **/

+    private JTextField getJTextFieldCopyright() {

+        if (jTextFieldCopyright == null) {

+            jTextFieldCopyright = new JTextField();

+            jTextFieldCopyright.setBounds(new java.awt.Rectangle(160,170,320, 20));

+        }

+        return jTextFieldCopyright;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public MsaHeader() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inMsaHeader The input data of MsaHeaderDocument.MsaHeader

+     

+     **/

+    public MsaHeader(MsaHeaderDocument.MsaHeader inMsaHeader) {

+        super();

+        init(inMsaHeader);

+        this.setVisible(true);

+        this.setViewMode(false);

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldBaseName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jTextFieldVersion.setEnabled(!isView);

+            this.jTextAreaLicense.setEnabled(!isView);

+            this.jTextFieldCopyright.setEnabled(!isView);

+            this.jTextAreaDescription.setEnabled(!isView);

+            this.jTextFieldSpecification.setEnabled(!isView);            

+            this.jTextFieldAbstract.setEnabled(!isView);

+            this.jTextFieldAbstractURL.setEnabled(!isView);

+            this.jComboBoxModuleType.setEnabled(!isView);

+            this.jComboBoxCompontentType.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Module Surface Area Header");

+        initFrame();

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inMsaHeader  The input data of MsaHeaderDocument.MsaHeader

+     

+     **/

+    private void init(MsaHeaderDocument.MsaHeader inMsaHeader) {

+        init();

+        if (inMsaHeader != null) {

+            setMsaHeader(inMsaHeader);

+            if (this.msaHeader.getBaseName() != null) {

+                this.jTextFieldBaseName.setText(this.msaHeader.getBaseName().getStringValue());

+            }

+            if (this.msaHeader.getGuid() != null) {

+                this.jTextFieldGuid.setText(this.msaHeader.getGuid().getStringValue());

+            }

+            if (this.msaHeader.getVersion() != null) {

+                this.jTextFieldVersion.setText(this.msaHeader.getVersion());

+            }

+            if (this.msaHeader.getLicense() != null) {

+                this.jTextAreaLicense.setText(this.msaHeader.getLicense().getStringValue());

+            }

+            if (this.msaHeader.getCopyright() != null) {

+                this.jTextFieldCopyright.setText(this.msaHeader.getCopyright());

+            }

+            if (this.msaHeader.getDescription() != null) {

+                this.jTextAreaDescription.setText(this.msaHeader.getDescription());

+            }

+            if (this.msaHeader.getSpecification() != null) {

+                this.jTextFieldSpecification.setText(this.msaHeader.getSpecification().getStringValue());

+            }

+            if (this.msaHeader.getAbstract() != null) {

+                this.jTextFieldAbstract.setText(this.msaHeader.getAbstract().getStringValue());

+                this.jTextFieldAbstractURL.setText(this.msaHeader.getAbstract().getURL());

+            }

+            if (this.msaHeader.getModuleType() != null) {

+                this.jComboBoxModuleType.setSelectedItem(this.msaHeader.getModuleType().toString());

+            }

+            if (this.msaHeader.getComponentType() != null) {

+                this.jComboBoxCompontentType.setSelectedItem(this.msaHeader.getComponentType().toString());

+            }

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelURL = new JLabel();

+            jLabelURL.setBounds(new java.awt.Rectangle(15,330,140,20));

+            jLabelURL.setText("URL");

+            jLabelCompontentType = new JLabel();

+            jLabelCompontentType.setBounds(new java.awt.Rectangle(15, 380, 140, 20));

+            jLabelCompontentType.setText("Compontent Type");

+            jLabelModuleType = new JLabel();

+            jLabelModuleType.setBounds(new java.awt.Rectangle(15, 355, 140, 20));

+            jLabelModuleType.setText("Module Type");

+            jLabelAbstract = new JLabel();

+            jLabelAbstract.setBounds(new java.awt.Rectangle(15, 305, 140, 20));

+            jLabelAbstract.setText("Abstract");

+            jLabelSpecification = new JLabel();

+            jLabelSpecification.setText("Specification");

+            jLabelSpecification.setBounds(new java.awt.Rectangle(15, 280, 140, 20));

+            jLabelDescription = new JLabel();

+            jLabelDescription.setText("Description");

+            jLabelDescription.setBounds(new java.awt.Rectangle(15, 195, 140, 20));

+            jLabelCopyright = new JLabel();

+            jLabelCopyright.setText("Copyright");

+            jLabelCopyright.setBounds(new java.awt.Rectangle(15, 170, 140, 20));

+            jLabelLicense = new JLabel();

+            jLabelLicense.setText("License");

+            jLabelLicense.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelVersion = new JLabel();

+            jLabelVersion.setText("Version");

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setPreferredSize(new java.awt.Dimension(25, 15));

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelBaseName = new JLabel();

+            jLabelBaseName.setText("Base Name");

+            jLabelBaseName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setLocation(new java.awt.Point(0, 0));

+            jContentPane.setSize(new java.awt.Dimension(500, 524));

+            jContentPane.add(jLabelBaseName, null);

+            jContentPane.add(getJTextFieldBaseName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelLicense, null);

+            jContentPane.add(jLabelCopyright, null);

+            jContentPane.add(jLabelDescription, null);

+            jContentPane.add(jLabelSpecification, null);

+            jContentPane.add(getJTextFieldSpecification(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPaneLicense(), null);

+            jContentPane.add(getJScrollPaneDescription(), null);

+            jContentPane.add(jLabelAbstract, null);

+            jContentPane.add(getJTextFieldAbstract(), null);

+            jContentPane.add(jLabelModuleType, null);

+            jContentPane.add(jLabelCompontentType, null);

+            jContentPane.add(getJComboBoxCompontentType(), null);

+            jContentPane.add(getJComboBoxModuleType(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 85));

+            jStarLabel5 = new StarLabel();

+            jStarLabel5.setLocation(new java.awt.Point(0, 170));

+            jStarLabel6 = new StarLabel();

+            jStarLabel6.setLocation(new java.awt.Point(0, 195));

+            jStarLabel7 = new StarLabel();

+            jStarLabel7.setLocation(new java.awt.Point(0, 305));

+            jStarLabel8 = new StarLabel();

+            jStarLabel8.setLocation(new java.awt.Point(0, 355));

+            jStarLabel9 = new StarLabel();

+            jStarLabel9.setLocation(new java.awt.Point(0, 380));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+            jContentPane.add(jStarLabel5, null);

+            jContentPane.add(jStarLabel6, null);

+            jContentPane.add(jStarLabel7, null);

+            jContentPane.add(jStarLabel8, null);

+            jContentPane.add(jStarLabel9, null);

+            jContentPane.add(jLabelURL, null);

+            jContentPane.add(getJTextFieldAbstractURL(), null);

+            jContentPane.add(getJTextFieldCopyright(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     *

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.setEdited(true);

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.setEdited(false);

+        }

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldBaseName.getText())) {

+            Log.err("Base Name couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldGuid.getText())) {

+            Log.err("Guid couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldVersion.getText())) {

+            Log.err("Version couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaLicense.getText())) {

+            Log.err("License couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldCopyright.getText())) {

+            Log.err("Copyright couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaDescription.getText())) {

+            Log.err("Description couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldAbstract.getText())) {

+            Log.err("Abstract couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isBaseName(this.jTextFieldBaseName.getText())) {

+            Log.err("Incorrect data type for Base Name");

+            return false;

+        }

+        if (!DataValidation.isGuid((this.jTextFieldGuid).getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!DataValidation.isAbstract(this.jTextFieldAbstract.getText())) {

+            Log.err("Incorrect data type for Abstract");

+            return false;

+        }

+        if (!DataValidation.isCopyright(this.jTextFieldCopyright.getText())) {

+            Log.err("Incorrect data type for Copyright");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Save all components of Msa Header

+     if exists msaHeader, set the value directly

+     if not exists msaHeader, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.msaHeader == null) {

+                msaHeader = MsaHeaderDocument.MsaHeader.Factory.newInstance();

+            }

+            if (this.msaHeader.getBaseName() != null) {

+                this.msaHeader.getBaseName().setStringValue(this.jTextFieldBaseName.getText());

+            } else {

+                BaseNameDocument.BaseName mBaseName = BaseNameDocument.BaseName.Factory.newInstance();

+                mBaseName.setStringValue(this.jTextFieldBaseName.getText());

+                this.msaHeader.setBaseName(mBaseName);

+            }

+

+            if (this.msaHeader.getGuid() != null) {

+                this.msaHeader.getGuid().setStringValue(this.jTextFieldGuid.getText());

+            } else {

+                GuidDocument.Guid mGuid = GuidDocument.Guid.Factory.newInstance();

+                mGuid.setStringValue(this.jTextFieldGuid.getText());

+                this.msaHeader.setGuid(mGuid);

+            }

+

+            this.msaHeader.setVersion(this.jTextFieldVersion.getText());

+

+            if (this.msaHeader.getLicense() != null) {

+                this.msaHeader.getLicense().setStringValue(this.jTextAreaLicense.getText());

+            } else {

+                LicenseDocument.License mLicense = LicenseDocument.License.Factory.newInstance();

+                mLicense.setStringValue(this.jTextAreaLicense.getText());

+                this.msaHeader.setLicense(mLicense);

+            }

+

+            this.msaHeader.setCopyright(this.jTextFieldCopyright.getText());

+            this.msaHeader.setDescription(this.jTextAreaDescription.getText());

+

+            if (this.msaHeader.getSpecification() != null) {

+                this.msaHeader.getSpecification().setStringValue(this.jTextFieldSpecification.getText());

+            } else {

+                SpecificationDocument.Specification mSpecification = SpecificationDocument.Specification.Factory

+                                                                                                                .newInstance();

+                mSpecification.setStringValue(this.jTextFieldSpecification.getText());

+                this.msaHeader.setSpecification(mSpecification);

+            }

+

+            if (this.msaHeader.getAbstract() != null) {

+                this.msaHeader.getAbstract().setStringValue(this.jTextFieldAbstract.getText());

+                this.msaHeader.getAbstract().setURL(this.jTextFieldAbstractURL.getText());

+            } else {

+                AbstractDocument.Abstract mAbstract = AbstractDocument.Abstract.Factory.newInstance();

+                mAbstract.setStringValue(this.jTextFieldAbstract.getText());

+                mAbstract.setURL(this.jTextFieldAbstractURL.getText());

+                this.msaHeader.setAbstract(mAbstract);

+            }

+            this.msaHeader.setModuleType(ModuleTypeDef.Enum.forString(this.jComboBoxModuleType.getSelectedItem()

+                                                                                              .toString()));

+            this.msaHeader

+                          .setComponentType(FrameworkComponentTypes.Enum

+                                                                        .forString(this.jComboBoxCompontentType

+                                                                                                               .getSelectedItem()

+                                                                                                               .toString()));

+            if (this.msaHeader.getCreated() == null) {

+                this.msaHeader.setCreated(Tools.getCurrentDateTime());

+            } else {

+                this.msaHeader.setUpdated(Tools.getCurrentDateTime());

+            }

+

+        } catch (Exception e) {

+            Log.err("Save Module", e.getMessage());

+        }

+    }

+

+    /**

+     This method initializes Module type and Compontent type

+     

+     **/

+    private void initFrame() {

+        jComboBoxModuleType.addItem("BASE");

+        jComboBoxModuleType.addItem("SEC");

+        jComboBoxModuleType.addItem("PEI_CORE");

+        jComboBoxModuleType.addItem("PEIM");

+        jComboBoxModuleType.addItem("DXE_CORE");

+        jComboBoxModuleType.addItem("DXE_DRIVER");

+        jComboBoxModuleType.addItem("DXE_RUNTIME_DRIVER");

+        jComboBoxModuleType.addItem("DXE_SAL_DRIVER");

+        jComboBoxModuleType.addItem("DXE_SMM_DRIVER");

+        jComboBoxModuleType.addItem("TOOLS");

+        jComboBoxModuleType.addItem("UEFI_DRIVER");

+        jComboBoxModuleType.addItem("UEFI_APPLICATION");

+        jComboBoxModuleType.addItem("USER_DEFINED");

+

+        jComboBoxCompontentType.addItem("APRIORI");

+        jComboBoxCompontentType.addItem("LIBRARY");

+        jComboBoxCompontentType.addItem("FV_IMAGE_FILE");

+        jComboBoxCompontentType.addItem("BS_DRIVER");

+        jComboBoxCompontentType.addItem("RT_DRIVER");

+        jComboBoxCompontentType.addItem("SAL_RT_DRIVER");

+        jComboBoxCompontentType.addItem("PE32_PEIM");

+        jComboBoxCompontentType.addItem("PIC_PEIM");

+        jComboBoxCompontentType.addItem("COMBINED_PEIM_DRIVER");

+        jComboBoxCompontentType.addItem("PEI_CORE");

+        jComboBoxCompontentType.addItem("DXE_CORE");

+        jComboBoxCompontentType.addItem("APPLICATION");

+        jComboBoxCompontentType.addItem("BS_DRIVER_EFI");

+        jComboBoxCompontentType.addItem("SHELLAPP");

+    }

+

+    /**

+     Get MsaHeaderDocument.MsaHeader

+     

+     @return MsaHeaderDocument.MsaHeader

+     

+     **/

+    public MsaHeaderDocument.MsaHeader getMsaHeader() {

+        return msaHeader;

+    }

+

+    /**

+     Set MsaHeaderDocument.MsaHeader

+     

+     @param msaHeader The input data of MsaHeaderDocument.MsaHeader

+     

+     **/

+    public void setMsaHeader(MsaHeaderDocument.MsaHeader msaHeader) {

+        this.msaHeader = msaHeader;

+    }

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MsaLibHeader.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MsaLibHeader.java
new file mode 100644
index 0000000..c35c84f
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/module/ui/MsaLibHeader.java
@@ -0,0 +1,796 @@
+/** @file

+ 

+ The file is used to create, update MsaLibHeader of a MSA file

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.module.ui;

+

+import java.awt.event.ActionEvent;

+

+import javax.swing.JButton;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JPanel;

+import javax.swing.JScrollPane;

+import javax.swing.JTextArea;

+import javax.swing.JTextField;

+

+import org.tianocore.AbstractDocument;

+import org.tianocore.BaseNameDocument;

+import org.tianocore.FrameworkComponentTypes;

+import org.tianocore.GuidDocument;

+import org.tianocore.LicenseDocument;

+import org.tianocore.ModuleTypeDef;

+import org.tianocore.MsaLibHeaderDocument;

+import org.tianocore.SpecificationDocument;

+import org.tianocore.common.DataValidation;

+import org.tianocore.common.Log;

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.IInternalFrame;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ The class is used to create, update MsaLibHeader of a MSA file

+ It extends IInternalFrame

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class MsaLibHeader extends IInternalFrame {

+

+    ///

+    /// Define class Serial Version UID

+    ///

+    private static final long serialVersionUID = 5526729363068526262L;

+

+    //

+    //Define class members

+    //

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelBaseName = null;

+

+    private JTextField jTextFieldBaseName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelLicense = null;

+

+    private JTextArea jTextAreaLicense = null;

+

+    private JLabel jLabelCopyright = null;

+

+    private JLabel jLabelDescription = null;

+

+    private JTextArea jTextAreaDescription = null;

+

+    private JLabel jLabelSpecification = null;

+

+    private JTextField jTextFieldSpecification = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JScrollPane jScrollPaneLicense = null;

+

+    private JScrollPane jScrollPaneDescription = null;

+

+    private JLabel jLabelAbstract = null;

+

+    private JTextField jTextFieldAbstract = null;

+

+    private JLabel jLabelModuleType = null;

+

+    private JLabel jLabelCompontentType = null;

+

+    private JComboBox jComboBoxCompontentType = null;

+

+    private JComboBox jComboBoxModuleType = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+

+    private StarLabel jStarLabel5 = null;

+

+    private StarLabel jStarLabel6 = null;

+

+    private StarLabel jStarLabel7 = null;

+

+    private StarLabel jStarLabel8 = null;

+

+    private StarLabel jStarLabel9 = null;

+

+    private MsaLibHeaderDocument.MsaLibHeader msaLibHeader = null;

+

+    private JLabel jLabelURL = null;

+

+    private JTextField jTextFieldAbstractURL = null;

+

+    private JTextField jTextFieldCopyright = null;

+

+    /**

+     This method initializes jTextFieldBaseName 

+     

+     @return javax.swing.JTextField jTextFieldBaseName

+     

+     **/

+    private JTextField getJTextFieldBaseName() {

+        if (jTextFieldBaseName == null) {

+            jTextFieldBaseName = new JTextField();

+            jTextFieldBaseName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldBaseName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid 

+     

+     @return javax.swing.JTextField jTextFieldGuid

+     

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 250, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldVersion 

+     

+     @return javax.swing.JTextField jTextFieldVersion

+     

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid 

+     

+     @return javax.swing.JButton jButtonGenerateGuid

+     

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(415, 35, 65, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextAreaLicense 

+     

+     @return javax.swing.JTextArea jTextAreaLicense

+     

+     **/

+    private JTextArea getJTextAreaLicense() {

+        if (jTextAreaLicense == null) {

+            jTextAreaLicense = new JTextArea();

+            jTextAreaLicense.setText("");

+            jTextAreaLicense.setLineWrap(true);

+        }

+        return jTextAreaLicense;

+    }

+

+    /**

+     This method initializes jTextAreaDescription 

+     

+     @return javax.swing.JTextArea jTextAreaDescription

+     

+     **/

+    private JTextArea getJTextAreaDescription() {

+        if (jTextAreaDescription == null) {

+            jTextAreaDescription = new JTextArea();

+            jTextAreaDescription.setLineWrap(true);

+        }

+        return jTextAreaDescription;

+    }

+

+    /**

+     This method initializes jTextFieldSpecification 

+     

+     @return javax.swing.JTextField jTextFieldSpecification

+     

+     **/

+    private JTextField getJTextFieldSpecification() {

+        if (jTextFieldSpecification == null) {

+            jTextFieldSpecification = new JTextField();

+            jTextFieldSpecification.setBounds(new java.awt.Rectangle(160, 280, 320, 20));

+        }

+        return jTextFieldSpecification;

+    }

+

+    /**

+     This method initializes jButtonOk 

+     

+     @return javax.swing.JButton jButtonOk

+     

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 445, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel 

+     

+     @return javax.swing.JButton jButtonCancel

+     

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 445, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPaneLicense 

+     

+     @return javax.swing.JScrollPane  jScrollPaneLicense

+     

+     **/

+    private JScrollPane getJScrollPaneLicense() {

+        if (jScrollPaneLicense == null) {

+            jScrollPaneLicense = new JScrollPane();

+            jScrollPaneLicense.setBounds(new java.awt.Rectangle(160, 85, 320, 80));

+            jScrollPaneLicense.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneLicense.setViewportView(getJTextAreaLicense());

+        }

+        return jScrollPaneLicense;

+    }

+

+    /**

+     This method initializes jScrollPaneDescription 

+     

+     @return javax.swing.JScrollPane jScrollPaneDescription

+     

+     **/

+    private JScrollPane getJScrollPaneDescription() {

+        if (jScrollPaneDescription == null) {

+            jScrollPaneDescription = new JScrollPane();

+            jScrollPaneDescription.setBounds(new java.awt.Rectangle(160, 195, 320, 80));

+            jScrollPaneDescription.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneDescription.setViewportView(getJTextAreaDescription());

+        }

+        return jScrollPaneDescription;

+    }

+

+    /**

+     This method initializes jTextFieldAbstract 

+     

+     @return javax.swing.JTextField jTextFieldAbstract

+     

+     **/

+    private JTextField getJTextFieldAbstract() {

+        if (jTextFieldAbstract == null) {

+            jTextFieldAbstract = new JTextField();

+            jTextFieldAbstract.setBounds(new java.awt.Rectangle(160, 305, 320, 20));

+        }

+        return jTextFieldAbstract;

+    }

+

+    /**

+     This method initializes jComboBoxCompontentType 

+     

+     @return javax.swing.JComboBox jComboBoxCompontentType

+     

+     **/

+    private JComboBox getJComboBoxCompontentType() {

+        if (jComboBoxCompontentType == null) {

+            jComboBoxCompontentType = new JComboBox();

+            jComboBoxCompontentType.setBounds(new java.awt.Rectangle(160, 380, 320, 20));

+        }

+        return jComboBoxCompontentType;

+    }

+

+    /**

+     This method initializes jComboBoxModuleType 

+     

+     @return javax.swing.JComboBox jComboBoxModuleType

+     

+     **/

+    private JComboBox getJComboBoxModuleType() {

+        if (jComboBoxModuleType == null) {

+            jComboBoxModuleType = new JComboBox();

+            jComboBoxModuleType.setBounds(new java.awt.Rectangle(160, 355, 320, 20));

+        }

+        return jComboBoxModuleType;

+    }

+

+    /**

+     This method initializes jTextFieldAbstractURL 

+     

+     @return javax.swing.JTextField jTextFieldAbstractURL

+     

+     **/

+    private JTextField getJTextFieldAbstractURL() {

+        if (jTextFieldAbstractURL == null) {

+            jTextFieldAbstractURL = new JTextField();

+            jTextFieldAbstractURL.setBounds(new java.awt.Rectangle(160,330,320,20));

+        }

+        return jTextFieldAbstractURL;

+    }

+

+    /**

+     * This method initializes jTextFieldCopyright	

+     * 	

+     * @return javax.swing.JTextField	

+     */

+    private JTextField getJTextFieldCopyright() {

+        if (jTextFieldCopyright == null) {

+            jTextFieldCopyright = new JTextField();

+            jTextFieldCopyright.setBounds(new java.awt.Rectangle(160,170,320,20));

+        }

+        return jTextFieldCopyright;

+    }

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     

+     **/

+    public MsaLibHeader() {

+        super();

+        init();

+        this.setVisible(true);

+    }

+

+    /**

+     This is the override edit constructor

+     

+     @param inMsaLibHeader The input data of MsaLibHeaderDocument.MsaLibHeader

+     

+     **/

+    public MsaLibHeader(MsaLibHeaderDocument.MsaLibHeader inMsaLibHeader) {

+        super();

+        init(inMsaLibHeader);

+        this.setVisible(true);

+        this.setViewMode(false);

+    }

+

+    /**

+     This method initializes this

+     

+     **/

+    private void init() {

+        this.setSize(500, 515);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Library Module");

+        initFrame();

+    }

+

+    /**

+     This method initializes this

+     Fill values to all fields if these values are not empty

+     

+     @param inMsaLibHeader The input data of MsaLibHeaderDocument.MsaLibHeader

+     

+     **/

+    private void init(MsaLibHeaderDocument.MsaLibHeader inMsaLibHeader) {

+        init();

+        this.setMsaLibHeader(inMsaLibHeader);

+        if (inMsaLibHeader != null) {

+            if (this.msaLibHeader.getBaseName() != null) {

+                this.jTextFieldBaseName.setText(this.msaLibHeader.getBaseName().getStringValue());

+            }

+            if (this.msaLibHeader.getGuid() != null) {

+                this.jTextFieldGuid.setText(this.msaLibHeader.getGuid().getStringValue());

+            }

+            if (this.msaLibHeader.getVersion() != null) {

+                this.jTextFieldVersion.setText(this.msaLibHeader.getVersion());

+            }

+            if (this.msaLibHeader.getLicense() != null) {

+                this.jTextAreaLicense.setText(this.msaLibHeader.getLicense().getStringValue());

+            }

+            if (this.msaLibHeader.getCopyright() != null) {

+                this.jTextFieldCopyright.setText(this.msaLibHeader.getCopyright());

+            }

+            if (this.msaLibHeader.getDescription() != null) {

+                this.jTextAreaDescription.setText(this.msaLibHeader.getDescription());

+            }

+            if (this.msaLibHeader.getSpecification() != null) {

+                this.jTextFieldSpecification.setText(this.msaLibHeader.getSpecification().getStringValue());

+            }

+            if (this.msaLibHeader.getAbstract() != null) {

+                this.jTextFieldAbstract.setText(this.msaLibHeader.getAbstract().getStringValue());

+                this.jTextFieldAbstractURL.setText(this.msaLibHeader.getAbstract().getURL());

+            }

+            if (this.msaLibHeader.getModuleType() != null) {

+                this.jComboBoxModuleType.setSelectedItem(this.msaLibHeader.getModuleType().toString());

+            }

+            if (this.msaLibHeader.getComponentType() != null) {

+                this.jComboBoxCompontentType.setSelectedItem(this.msaLibHeader.getComponentType().toString());

+            }

+        }

+    }

+

+    /**

+     Disable all components when the mode is view

+     

+     @param isView true - The view mode; false - The non-view mode

+     

+     **/

+    public void setViewMode(boolean isView) {

+        this.jButtonOk.setVisible(false);

+        this.jButtonCancel.setVisible(false);

+        if (isView) {

+            this.jTextFieldBaseName.setEnabled(!isView);

+            this.jTextFieldGuid.setEnabled(!isView);

+            this.jTextFieldVersion.setEnabled(!isView);

+            this.jTextAreaLicense.setEnabled(!isView);

+            this.jTextFieldCopyright.setEnabled(!isView);

+            this.jTextAreaDescription.setEnabled(!isView);

+            this.jTextFieldSpecification.setEnabled(!isView);

+            this.jTextFieldAbstract.setEnabled(!isView);

+            this.jTextFieldAbstractURL.setEnabled(!isView);

+            this.jComboBoxModuleType.setEnabled(!isView);

+            this.jComboBoxCompontentType.setEnabled(!isView);

+            this.jButtonCancel.setEnabled(!isView);

+            this.jButtonGenerateGuid.setEnabled(!isView);

+            this.jButtonOk.setEnabled(!isView);

+        }

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel jContentPane

+     

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelURL = new JLabel();

+            jLabelURL.setBounds(new java.awt.Rectangle(15,330,140,20));

+            jLabelURL.setText("URL");

+            jLabelCompontentType = new JLabel();

+            jLabelCompontentType.setBounds(new java.awt.Rectangle(15, 380, 140, 20));

+            jLabelCompontentType.setText("Compontent Type");

+            jLabelModuleType = new JLabel();

+            jLabelModuleType.setBounds(new java.awt.Rectangle(15, 355, 140, 20));

+            jLabelModuleType.setText("Module Type");

+            jLabelAbstract = new JLabel();

+            jLabelAbstract.setBounds(new java.awt.Rectangle(15, 305, 140, 20));

+            jLabelAbstract.setText("Abstract");

+            jLabelSpecification = new JLabel();

+            jLabelSpecification.setText("Specification");

+            jLabelSpecification.setBounds(new java.awt.Rectangle(15, 280, 140, 20));

+            jLabelDescription = new JLabel();

+            jLabelDescription.setText("Description");

+            jLabelDescription.setBounds(new java.awt.Rectangle(15, 195, 140, 20));

+            jLabelCopyright = new JLabel();

+            jLabelCopyright.setText("Copyright");

+            jLabelCopyright.setBounds(new java.awt.Rectangle(15, 170, 140, 20));

+            jLabelLicense = new JLabel();

+            jLabelLicense.setText("License");

+            jLabelLicense.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelVersion = new JLabel();

+            jLabelVersion.setText("Version");

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setPreferredSize(new java.awt.Dimension(25, 15));

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelBaseName = new JLabel();

+            jLabelBaseName.setText("Base Name");

+            jLabelBaseName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setLocation(new java.awt.Point(0, 0));

+            jContentPane.setSize(new java.awt.Dimension(500, 524));

+            jContentPane.add(jLabelBaseName, null);

+            jContentPane.add(getJTextFieldBaseName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelLicense, null);

+            jContentPane.add(jLabelCopyright, null);

+            jContentPane.add(jLabelDescription, null);

+            jContentPane.add(jLabelSpecification, null);

+            jContentPane.add(getJTextFieldSpecification(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPaneLicense(), null);

+            jContentPane.add(getJScrollPaneDescription(), null);

+            jContentPane.add(jLabelAbstract, null);

+            jContentPane.add(getJTextFieldAbstract(), null);

+            jContentPane.add(jLabelModuleType, null);

+            jContentPane.add(jLabelCompontentType, null);

+            jContentPane.add(getJComboBoxCompontentType(), null);

+            jContentPane.add(getJComboBoxModuleType(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 85));

+            jStarLabel5 = new StarLabel();

+            jStarLabel5.setLocation(new java.awt.Point(0, 170));

+            jStarLabel6 = new StarLabel();

+            jStarLabel6.setLocation(new java.awt.Point(0, 195));

+            jStarLabel7 = new StarLabel();

+            jStarLabel7.setLocation(new java.awt.Point(0, 305));

+            jStarLabel8 = new StarLabel();

+            jStarLabel8.setLocation(new java.awt.Point(0, 355));

+            jStarLabel9 = new StarLabel();

+            jStarLabel9.setLocation(new java.awt.Point(0, 380));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+            jContentPane.add(jStarLabel5, null);

+            jContentPane.add(jStarLabel6, null);

+            jContentPane.add(jStarLabel7, null);

+            jContentPane.add(jStarLabel8, null);

+            jContentPane.add(jStarLabel9, null);

+            jContentPane.add(jLabelURL, null);

+            jContentPane.add(getJTextFieldAbstractURL(), null);

+            jContentPane.add(getJTextFieldCopyright(), null);

+        }

+        return jContentPane;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     *

+     * Override actionPerformed to listen all actions

+     *  

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.dispose();

+            this.save();

+            this.setEdited(true);

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+            this.setEdited(false);

+        }

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Data validation for all fields

+     

+     @retval true - All datas are valid

+     @retval false - At least one data is invalid

+     

+     **/

+    public boolean check() {

+        //

+        // Check if all required fields are not empty

+        //

+        if (isEmpty(this.jTextFieldBaseName.getText())) {

+            Log.err("Base Name couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldGuid.getText())) {

+            Log.err("Guid couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldVersion.getText())) {

+            Log.err("Version couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaLicense.getText())) {

+            Log.err("License couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldCopyright.getText())) {

+            Log.err("Copyright couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextAreaDescription.getText())) {

+            Log.err("Description couldn't be empty");

+            return false;

+        }

+        if (isEmpty(this.jTextFieldAbstract.getText())) {

+            Log.err("Abstract couldn't be empty");

+            return false;

+        }

+

+        //

+        // Check if all fields have correct data types 

+        //

+        if (!DataValidation.isBaseName(this.jTextFieldBaseName.getText())) {

+            Log.err("Incorrect data type for Base Name");

+            return false;

+        }

+        if (!DataValidation.isGuid((this.jTextFieldGuid).getText())) {

+            Log.err("Incorrect data type for Guid");

+            return false;

+        }

+        if (!DataValidation.isAbstract(this.jTextFieldAbstract.getText())) {

+            Log.err("Incorrect data type for Abstract");

+            return false;

+        }

+        if (!DataValidation.isCopyright(this.jTextFieldCopyright.getText())) {

+            Log.err("Incorrect data type for Copyright");

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Save all components of Msa Lib Header

+     if exists msaLibHeader, set the value directly

+     if not exists msaLibHeader, new an instance first

+     

+     **/

+    public void save() {

+        try {

+            if (this.msaLibHeader == null) {

+                msaLibHeader = MsaLibHeaderDocument.MsaLibHeader.Factory.newInstance();

+            }

+            if (this.msaLibHeader.getBaseName() != null) {

+                this.msaLibHeader.getBaseName().setStringValue(this.jTextFieldBaseName.getText());

+            } else {

+                BaseNameDocument.BaseName mBaseName = BaseNameDocument.BaseName.Factory.newInstance();

+                mBaseName.setStringValue(this.jTextFieldBaseName.getText());

+                this.msaLibHeader.setBaseName(mBaseName);

+            }

+

+            if (this.msaLibHeader.getGuid() != null) {

+                this.msaLibHeader.getGuid().setStringValue(this.jTextFieldGuid.getText());

+            } else {

+                GuidDocument.Guid mGuid = GuidDocument.Guid.Factory.newInstance();

+                mGuid.setStringValue(this.jTextFieldGuid.getText());

+                this.msaLibHeader.setGuid(mGuid);

+            }

+

+            this.msaLibHeader.setVersion(this.jTextFieldVersion.getText());

+

+            if (this.msaLibHeader.getLicense() != null) {

+                this.msaLibHeader.getLicense().setStringValue(this.jTextAreaLicense.getText());

+            } else {

+                LicenseDocument.License mLicense = LicenseDocument.License.Factory.newInstance();

+                mLicense.setStringValue(this.jTextAreaLicense.getText());

+                this.msaLibHeader.setLicense(mLicense);

+            }

+

+            this.msaLibHeader.setCopyright(this.jTextFieldCopyright.getText());

+            this.msaLibHeader.setDescription(this.jTextAreaDescription.getText());

+

+            if (this.msaLibHeader.getSpecification() != null) {

+                this.msaLibHeader.getSpecification().setStringValue(this.jTextFieldSpecification.getText());

+            } else {

+                SpecificationDocument.Specification mSpecification = SpecificationDocument.Specification.Factory

+                                                                                                                .newInstance();

+                mSpecification.setStringValue(this.jTextFieldSpecification.getText());

+                this.msaLibHeader.setSpecification(mSpecification);

+            }

+

+            if (this.msaLibHeader.getAbstract() != null) {

+                this.msaLibHeader.getAbstract().setStringValue(this.jTextFieldAbstract.getText());

+                this.msaLibHeader.getAbstract().setURL(this.jTextFieldAbstractURL.getText());

+            } else {

+                AbstractDocument.Abstract mAbstract = AbstractDocument.Abstract.Factory.newInstance();

+                mAbstract.setStringValue(this.jTextFieldAbstract.getText());

+                mAbstract.setURL(this.jTextFieldAbstractURL.getText());

+                this.msaLibHeader.setAbstract(mAbstract);

+            }

+

+            this.msaLibHeader.setModuleType(ModuleTypeDef.Enum.forString(this.jComboBoxModuleType.getSelectedItem()

+                                                                                                 .toString()));

+            this.msaLibHeader

+                             .setComponentType(FrameworkComponentTypes.Enum

+                                                                           .forString(this.jComboBoxCompontentType

+                                                                                                                  .getSelectedItem()

+                                                                                                                  .toString()));

+

+            if (this.msaLibHeader.getCreated() == null) {

+                this.msaLibHeader.setCreated(Tools.getCurrentDateTime());

+            } else {

+                this.msaLibHeader.setUpdated(Tools.getCurrentDateTime());

+            }

+        } catch (Exception e) {

+            Log.err("Save Module", e.getMessage());

+        }

+    }

+

+    /**

+     This method initializes module type and compontent type

+     

+     **/

+    private void initFrame() {

+        jComboBoxModuleType.addItem("BASE");

+        jComboBoxModuleType.addItem("SEC");

+        jComboBoxModuleType.addItem("PEI_CORE");

+        jComboBoxModuleType.addItem("PEIM");

+        jComboBoxModuleType.addItem("DXE_CORE");

+        jComboBoxModuleType.addItem("DXE_DRIVER");

+        jComboBoxModuleType.addItem("DXE_RUNTIME_DRIVER");

+        jComboBoxModuleType.addItem("DXE_SMM_DRIVER");

+        jComboBoxModuleType.addItem("DXE_SAL_DRIVER");

+        jComboBoxModuleType.addItem("UEFI_DRIVER");

+        jComboBoxModuleType.addItem("UEFI_APPLICATION");

+

+        jComboBoxCompontentType.addItem("APRIORI");

+        jComboBoxCompontentType.addItem("LIBRARY");

+        jComboBoxCompontentType.addItem("FV_IMAGE_FILE");

+        jComboBoxCompontentType.addItem("BS_DRIVER");

+        jComboBoxCompontentType.addItem("RT_DRIVER");

+        jComboBoxCompontentType.addItem("SAL_RT_DRIVER");

+        jComboBoxCompontentType.addItem("PE32_PEIM");

+        jComboBoxCompontentType.addItem("PIC_PEIM");

+        jComboBoxCompontentType.addItem("COMBINED_PEIM_DRIVER");

+        jComboBoxCompontentType.addItem("PEI_CORE");

+        jComboBoxCompontentType.addItem("DXE_CORE");

+        jComboBoxCompontentType.addItem("APPLICATION");

+        jComboBoxCompontentType.addItem("BS_DRIVER_EFI");

+        jComboBoxCompontentType.addItem("SHELLAPP");

+    }

+

+    /**

+     Get MsaLibHeaderDocument.MsaLibHeader

+     

+     @return MsaLibHeaderDocument.MsaLibHeader

+     

+     **/

+    public MsaLibHeaderDocument.MsaLibHeader getMsaLibHeader() {

+        return msaLibHeader;

+    }

+

+    /**

+     Set MsaLibHeaderDocument.MsaLibHeader

+     

+     @param msaLibHeader The input data of MsaLibHeaderDocument.MsaLibHeader

+     

+     **/

+    public void setMsaLibHeader(MsaLibHeaderDocument.MsaLibHeader msaLibHeader) {

+        this.msaLibHeader = msaLibHeader;

+    }

+

+}

diff --git a/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/workspace/common/Workspace.java b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/workspace/common/Workspace.java
new file mode 100644
index 0000000..fd27f18
--- /dev/null
+++ b/edk2/Tools/Source/ModuleEditor/src/org/tianocore/packaging/workspace/common/Workspace.java
@@ -0,0 +1,169 @@
+/** @file

+ 

+ The file is used to init workspace and get basic information of workspace

+ 

+ Copyright (c) 2006, Intel Corporation

+ All rights reserved. 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.

+ 

+ **/

+

+package org.tianocore.packaging.workspace.common;

+

+import java.io.File;

+import java.util.Vector;

+

+import org.apache.xmlbeans.XmlException;

+import org.apache.xmlbeans.XmlObject;

+import org.tianocore.FrameworkDatabaseDocument;

+import org.tianocore.common.Log;

+

+/**

+ The file is used to init workspace and get basic information of workspace

+ 

+ @since ModuleEditor 1.0

+

+ **/

+public class Workspace {

+

+    //

+    // Define class members

+    //

+    private String currentWorkspace = null;

+

+    private FrameworkDatabaseDocument xmlFrameworkDbDoc = null;

+    

+    //private PackageDocument xmlPackage = null;

+

+    private String strWorkspaceDatabaseFile = System.getProperty("file.separator") + "Tools"

+                                              + System.getProperty("file.separator") + "Conf"

+                                              + System.getProperty("file.separator") + "FrameworkDatabase.db";

+

+    public static void main(String[] args) {

+

+    }

+

+    /**

+     This is the default constructor

+     Get current WORKSPACE from system environment variable

+     

+     **/

+    public Workspace() {

+        this.currentWorkspace = System.getenv("WORKSPACE");

+    }

+

+    /**

+     Check if current workspace exists of not

+     

+     @retval true - The current WORKSPACE exists

+     @retval false - The current WORKSPACE doesn't exist

+     

+     **/

+    public boolean checkCurrentWorkspace() {

+        return checkCurrentWorkspace(getCurrentWorkspace());

+    }

+

+    /**

+     Check if current workspace exists or not via input workspace path

+     

+     @param strWorkspace The input data of WORKSPACE path

+     @retval true - The current WORKSPACE exists

+     @retval false - The current WORKSPACE doesn't exist

+     

+     **/

+    public boolean checkCurrentWorkspace(String strWorkspace) {

+        if (strWorkspace == null || strWorkspace == "") {

+            return false;

+        }

+        File f = new File(strWorkspace);

+        if (!f.isDirectory()) {

+            return false;

+        }

+        if (!f.exists()) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     Get Current Workspace

+     

+     @return currentWorkspace

+     

+     **/

+    public String getCurrentWorkspace() {

+        return currentWorkspace;

+    }

+

+    /**

+     Set Current Workspace

+     

+     @param currentWorkspace The input data of currentWorkspace

+     

+     **/

+    public void setCurrentWorkspace(String currentWorkspace) {

+        this.currentWorkspace = currentWorkspace;

+    }

+

+    /**

+     Open Framework Database file

+     

+     **/

+    private void openFrameworkDb() {

+        String strFrameworkDbFilePath = this.getCurrentWorkspace() + strWorkspaceDatabaseFile;

+        File db = new File(strFrameworkDbFilePath);

+        try {

+            xmlFrameworkDbDoc = (FrameworkDatabaseDocument) XmlObject.Factory.parse(db);

+        } catch (XmlException e) {

+            Log.err("Open Framework Database " + strFrameworkDbFilePath, e.getMessage());

+            return;

+        } catch (Exception e) {

+            Log.err("Open Framework Database " + strFrameworkDbFilePath, "Invalid file type");

+            return;

+        }

+    }

+

+    /**

+     Get FrameworkDatabaseDocument

+     

+     @return FrameworkDatabaseDocument

+     

+     **/

+    public FrameworkDatabaseDocument getXmlFrameworkDbDoc() {

+        openFrameworkDb();

+        return xmlFrameworkDbDoc;

+    }

+

+    /**

+     Set FrameworkDatabaseDocument

+     

+     @param xmlFrameworkDbDoc The input data of FrameworkDatabaseDocument

+     

+     **/

+    public void setXmlFrameworkDbDoc(FrameworkDatabaseDocument xmlFrameworkDbDoc) {

+        this.xmlFrameworkDbDoc = xmlFrameworkDbDoc;

+    }

+

+    /**

+     Get all package name form the FrameworkDatabase.db file

+     

+     @return vPackageName A vector includes all package names

+     

+     **/

+    public Vector getAllPackageName() {

+        Vector<String> vPackageName = new Vector<String>();

+        openFrameworkDb();

+

+        for (int index = 0; index < xmlFrameworkDbDoc.getFrameworkDatabase().getPackageList().sizeOfPackageArray(); index++) {

+            vPackageName.addElement(xmlFrameworkDbDoc.getFrameworkDatabase().getPackageList().getPackageArray(index)

+                                                     .getPackageNameArray(0).getStringValue());

+        }

+

+        return vPackageName;

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/MANIFEST.MF b/edk2/Tools/Source/PackageEditor/MANIFEST.MF
new file mode 100644
index 0000000..8a92b4f
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0

+Main-Class: org.tianocore.packaging.PackagingMain

+

diff --git a/edk2/Tools/Source/PackageEditor/build.xml b/edk2/Tools/Source/PackageEditor/build.xml
new file mode 100644
index 0000000..982e159
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/build.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="PackageEditor" default="all" basedir=".">

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env"/>

+  <property name="WORKSPACE" value="${env.WORKSPACE}"/>

+  <path id="classpath">

+    <fileset dir="${WORKSPACE}/Tools/Jars" includes="*.jar"/>

+    <fileset dir="${env.XMLBEANS_HOME}/lib" includes="*.jar"/>

+  </path>

+  <property name="buildDir" value="build"/>

+  <property name="installLocation" value="${WORKSPACE}/Tools/bin"/>

+  <target name="all" depends="install"/>

+  <target name="source">

+    <mkdir dir="${buildDir}"/>

+    <javac srcdir="src" destdir="${buildDir}">

+      <classpath refid="classpath"/>

+      <!-- <compilerarg value="-Xlint"/> -->

+    </javac>

+  </target>

+  <target name="clean">

+    <delete dir="${buildDir}"/>

+  </target>

+  <target name="cleanall">

+    <delete dir="${buildDir}"/>

+    <delete file="${installLocation}/PackageEditor.jar"/>

+  </target>

+  <target name="install" depends="source">

+    <jar destfile="${installLocation}/PackageEditor.jar"

+      basedir="${buildDir}"

+      includes="**"

+      manifest="MANIFEST.MF"

+    />

+  </target>

+</project>

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/common/Tools.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/common/Tools.java
new file mode 100644
index 0000000..311370d
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/common/Tools.java
@@ -0,0 +1,159 @@
+/** @file

+  Java class Tools contains common use procedures.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.common;

+

+import java.io.File;

+import java.text.SimpleDateFormat;

+import java.util.Calendar;

+import java.util.Date;

+import java.util.UUID;

+

+/**

+ This class contains static methods for some common operations

+  

+ @since PackageEditor 1.0

+**/

+public class Tools {

+	

+        public static final String guidArrayPat = "0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?";

+	public static final String guidRegistryPat = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";

+	/**

+	  get current date and time, then return

+	  @return String

+	 **/

+	public static String getCurrentDateTime() {

+		Date now = new Date(System.currentTimeMillis());

+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+	    return sdf.format(now);

+	}

+	

+	/**

+	  Delete a folder and all its files

+	  @param strFolderName

+	  @return boolean

+	 **/

+	public static boolean deleteFolder(File fleFolderName) {

+		boolean blnIsDeleted = true;

+		File[] aryAllFiles = fleFolderName.listFiles();

+		

+		for (int indexI = 0; indexI < aryAllFiles.length; indexI++) {

+			if (blnIsDeleted) {

+				if (aryAllFiles[indexI].isDirectory()) {

+					blnIsDeleted  = deleteFolder(aryAllFiles[indexI]);

+				} else if (aryAllFiles[indexI].isFile()) {

+					if (!aryAllFiles[indexI].delete()) {

+						blnIsDeleted = false;

+					}

+				}

+			}

+		}

+		if (blnIsDeleted) {

+			fleFolderName.delete();

+		}

+		return blnIsDeleted;

+	}

+	

+	/**

+	 Get a new GUID

+     

+	 @return String

+	**/

+	public static String generateUuidString() {

+		return UUID.randomUUID().toString();

+	}

+	

+    public static String formatGuidString (String guidNameConv) {

+        String[] strList;

+        String guid = "";

+        int index = 0;

+        if (guidNameConv

+                        .matches(Tools.guidRegistryPat)) {

+            strList = guidNameConv.split("-");

+            guid = "0x" + strList[0] + ", ";

+            guid = guid + "0x" + strList[1] + ", ";

+            guid = guid + "0x" + strList[2] + ", ";

+//            guid = guid + "{";

+            guid = guid + "0x" + strList[3].substring(0, 2) + ", ";

+            guid = guid + "0x" + strList[3].substring(2, 4);

+

+            while (index < strList[4].length()) {

+                guid = guid + ", ";

+                guid = guid + "0x" + strList[4].substring(index, index + 2);

+                index = index + 2;

+            }

+//            guid = guid + "}";

+            return guid;

+        }

+        else if (guidNameConv

+                        .matches(Tools.guidArrayPat)) {

+            strList = guidNameConv.split(",");

+            

+            //

+            // chang ANSI c form to registry form

+            //

+            for (int i = 0; i < strList.length; i++){

+                strList[i] = strList[i].substring(strList[i].lastIndexOf("x") + 1);

+            }

+            if (strList[strList.length - 1].endsWith("}")) {

+                strList[strList.length -1] = strList[strList.length-1].substring(0, strList[strList.length-1].length()-1); 

+            }

+            //

+            //inserting necessary leading zeros

+            //

+            

+            int segLen = strList[0].length();

+            if (segLen < 8){

+                for (int i = 0; i < 8 - segLen; ++i){

+                    strList[0] = "0" + strList[0];

+                }

+            }

+            

+            segLen = strList[1].length();

+            if (segLen < 4){

+                for (int i = 0; i < 4 - segLen; ++i){

+                    strList[1] = "0" + strList[1];

+                }

+            }

+            segLen = strList[2].length();

+            if (segLen < 4){

+                for (int i = 0; i < 4 - segLen; ++i){

+                    strList[2] = "0" + strList[2];

+                }

+            }

+            for (int i = 3; i < 11; ++i) {

+                segLen = strList[i].length();

+                if (segLen < 2){

+                    strList[i] = "0" + strList[i];

+                }

+            }

+            

+            for (int i = 0; i < 3; i++){

+                guid += strList[i] + "-";

+            }

+            

+            guid += strList[3];

+            guid += strList[4] + "-";

+            

+            for (int i = 5; i < strList.length; ++i){

+                guid += strList[i];

+            }

+            

+            

+            return guid;

+        } else {

+            

+            return "0";

+

+        }

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/CreateFdp.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/CreateFdp.java
new file mode 100644
index 0000000..6988b5a
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/CreateFdp.java
@@ -0,0 +1,93 @@
+/** @file

+  Java class CreateFdp is used to create a distributable package containing 

+  FDPManifest.xml file in its root directory.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.io.*;

+import java.util.jar.*;

+

+/**

+ This class contains static method create to generate *.fdp format package.

+ 

+ @since PackageEditor 1.0

+**/

+public class CreateFdp {

+

+    /**

+     recursively add contents under dir into output package.

+     

+     @param dir The directory with files that will be put into package

+     @param jos Stream used to create output package

+     @param wkDir The position of source directory

+     @throws Exception Any exception occurred during this process

+    **/

+    public static void create(File dir, JarOutputStream jos, String wkDir) throws Exception {

+        

+        String[] list = dir.list();

+        

+        try {

+            byte[] buffer = new byte[1024];

+            int bytesRead;

+

+            //

+            // Loop through the file names provided.

+            //

+            for (int i = 0; i < list.length; i++) {

+                

+                File f = new File(dir, list[i]);

+                if (f.getName().equals("..")) {

+                    continue;

+                }

+                if (f.isDirectory()) {

+                    //

+                    // Call this method recursively for directory

+                    //

+                    CreateFdp.create(f, jos, wkDir);

+                    continue;

+                }

+

+                try {

+                    //

+                    // Open the file

+                    //

+                    FileInputStream fis = new FileInputStream(f);

+

+                    try {

+                        //

+                        // Create a Jar entry and add it, keep relative path only.

+                        //

+                        JarEntry entry = new JarEntry(f.getPath().substring(wkDir.length() + 1));

+                        jos.putNextEntry(entry);

+

+                        //

+                        // Read the file and write it to the Jar.

+                        //

+                        while ((bytesRead = fis.read(buffer)) != -1) {

+                            jos.write(buffer, 0, bytesRead);

+                        }

+

+                        System.out.println(entry.getName() + " added.");

+                    } catch (Exception ex) {

+                        System.out.println(ex);

+                    } finally {

+                        fis.close();

+                    }

+                } catch (IOException ex) {

+                    System.out.println(ex);

+                }

+            }

+        } finally {

+            System.out.println(dir.getPath() + " processed.");

+        }

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/DbFileContents.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/DbFileContents.java
new file mode 100644
index 0000000..4f5fb37
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/DbFileContents.java
@@ -0,0 +1,315 @@
+/** @file

+  Java class DbFileContents is used to deal with FrameworkDatabase.db file cotents.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.io.File;

+import java.io.IOException;

+import java.util.LinkedList;

+import java.util.List;

+import java.util.ListIterator;

+import java.util.Date;

+import java.text.SimpleDateFormat;

+

+import org.apache.xmlbeans.XmlCursor;

+import org.apache.xmlbeans.XmlObject;

+import org.apache.xmlbeans.XmlOptions;

+

+import org.tianocore.*;

+

+/**

+ This class provides methods for add, remove, query FrameworkDatabase.db file.

+  

+ @since PackageEditor 1.0

+**/

+public class DbFileContents {

+

+    ///

+    /// return values for various conditions. 

+    ///

+    static final int BASE_PACKAGE_NOT_INSTALLED = 1;

+

+    static final int VERSION_NOT_EQUAL = 2;

+

+    static final int GUID_NOT_EQUAL = 3;

+

+    static final int SAME_ALL = 4;

+

+    private File dbFile = null;

+

+    private FrameworkDatabaseDocument fdd = null;

+

+    private FrameworkDatabaseDocument.FrameworkDatabase fddRoot = null;

+    

+    private PackageListDocument.PackageList pkgList = null;

+

+    public DbFileContents() {

+        super();

+        // TODO Auto-generated constructor stub

+    }

+

+    /**

+       Parse file f, store its xml data in fdd, store root xml element in fddRoot.

+       

+       @param f DB file to parse

+    **/

+    public DbFileContents(File f) {

+        try {

+            dbFile = f;

+            if (fdd == null) {

+                fdd = ((FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile));

+            }

+            fddRoot = fdd.getFrameworkDatabase();

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+    

+    /**

+     Generate the Package element in FrameworkDatabase.db

+     

+     @param baseName Base name of package

+     @param ver Version of package

+     @param guid GUID of package

+     @param path Where the package installed

+     @param installDate When the package installed

+    **/

+    public void genPackage (String baseName, String ver, String guid, String path, String installDate) {

+        if (getPkgList() == null) {

+            pkgList = fddRoot.addNewPackageList();

+        }

+        PackageListDocument.PackageList.Package p = pkgList.addNewPackage();

+        p.addNewPackageName().setStringValue(baseName);

+        p.addNewGuid().setStringValue(guid);

+        p.addVersion(ver);

+        p.addNewPath().setStringValue(path);

+        p.addNewInstalledDate().setStringValue(installDate);

+    }

+    

+    /**

+     Get PackageList

+     

+     @return PackageListDocument.PackageList

+    **/

+    public PackageListDocument.PackageList getPkgList() {

+        if (pkgList == null) {

+            pkgList = fddRoot.getPackageList();

+        }

+        return pkgList;

+    }

+    

+    /**

+     Remove PackageList and all elements under it.

+    **/

+    public void removePackageList() {

+        XmlObject o = fddRoot.getPackageList();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+    }

+    /**

+     Get the number of Package elements.

+     

+     @return int

+    **/

+    public int getPackageCount () {

+        return fddRoot.getPackageList().getPackageList().size();

+    }

+    

+    /**

+     Get all Package contents into String array

+     

+     @param pkg Two dimentional array to store Package info.

+    **/

+    public void getPackageList(String[][] pkg) {

+        List<PackageListDocument.PackageList.Package> l = fddRoot.getPackageList().getPackageList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) li

+                                                                                                                                      .next();

+            if (p.getPackageNameArray(0)!= null) {

+                pkg[i][0] = p.getPackageNameArray(0).getStringValue();

+            }

+            

+            pkg[i][1] = p.getVersionArray(0);

+            

+            if (p.getGuidArray(0) != null) {

+                pkg[i][2] = p.getGuidArray(0).getStringValue();

+            }

+            if (p.getPathArray(0) != null) {

+                pkg[i][3] = p.getPathArray(0).getStringValue();

+            }

+            if (p.getInstalledDateArray(0) != null) {

+                pkg[i][4] = p.getInstalledDateArray(0);

+            }

+            i++;

+        }

+    }

+    /**

+     Check whether destDir has been used by one Package

+     

+     @param destDir The directory to check.

+     @retval <1> destDir has been used

+     @retval <0> destDir has not been used

+     @return int

+    **/

+    public int checkDir(String destDir) {

+        List<PackageListDocument.PackageList.Package> lp = fddRoot.getPackageList().getPackageList();

+

+        ListIterator lpi = lp.listIterator();

+        while (lpi.hasNext()) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) lpi.next();

+            if (p.getPathArray(0).getStringValue().equals(destDir)) {

+                return 1;

+            }

+        }

+        return 0;

+    }

+

+    /**

+     Find the package info. and store results into list of same base name or list

+     of same version.

+     

+     @param base The base name of package

+     @param version The version of package

+     @param guid the GUID of package

+     @param lpSameBase The list to store package info with the same base name with "base"

+     @param lpSameVersion The list to store package info from lpSameBase and same version

+            with "version"

+     @retval <0> No package installed has base name "base"

+     @retval <VERSION_NOT_EQUAL> At least one package installed with "base" but no "version"

+     @retval <GUID_NOT_EQUAL> At least one package installed with "base" and "version" but no "guid"

+     @retval <SAME_ALL> One installed package has the same base, version and guid

+     @return int

+    **/

+    public int query(String base, String version, String guid,

+                     List<PackageListDocument.PackageList.Package> lpSameBase,

+                     List<PackageListDocument.PackageList.Package> lpSameVersion) {

+

+        List<PackageListDocument.PackageList.Package> lp = fddRoot.getPackageList().getPackageList();

+

+        ListIterator lpi = lp.listIterator();

+        while (lpi.hasNext()) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) lpi.next();

+            if (p.getPackageNameArray(0).getStringValue().equals(base)) {

+                lpSameBase.add(p);

+            }

+        }

+

+        if (lpSameBase.size() == 0) {

+            return 0;

+        }

+

+        for (ListIterator li = lpSameBase.listIterator(); li.hasNext();) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) li.next();

+            if (p.getVersionArray(0).equals(version)) {

+                lpSameVersion.add(p);

+            }

+        }

+

+        if (lpSameVersion.size() == 0) {

+            return VERSION_NOT_EQUAL;

+        }

+

+        for (ListIterator li = lpSameVersion.listIterator(); li.hasNext();) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) li.next();

+            if (!p.getGuidArray(0).getStringValue().equals(guid)) {

+                return GUID_NOT_EQUAL;

+            }

+        }

+

+        return SAME_ALL;

+

+    }

+

+    /**

+     Update package info (name, version, guid) with installDir, newVer, newGuid.

+     And update install date with current date. if no package info available, add 

+     a new entry.

+     

+     @param name Original base name

+     @param version Original version

+     @param guid Original GUID

+     @param installDir original path

+     @param newVer Version value of package to be installed

+     @param newGuid GUID value of package to be installed

+     @throws IOException Exception during file operation

+    **/

+    public void updatePkgInfo(String name, String version, String guid, String installDir, String newVer, String newGuid)

+                                                                                                                         throws IOException {

+        List<PackageListDocument.PackageList.Package> lp = fddRoot.getPackageList().getPackageList();

+

+        ListIterator lpi = lp.listIterator();

+        while (lpi.hasNext()) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) lpi.next();

+            if (p.getPackageNameArray(0).getStringValue().equals(name)) {

+                if (p.getVersionArray(0).equals(version)) {

+                    if (p.getGuidArray(0).getStringValue().equals(guid)) {

+                        p.setVersionArray(0, newVer);

+                        p.getGuidArray(0).setStringValue(newGuid);

+                        p.getPathArray(0).setStringValue(installDir);

+                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+                        Date date = new Date();

+                        p.setInstalledDateArray(0, format.format(date));

+                        saveAs();

+                        return;

+

+                    }

+                }

+            }

+        }

+

+        addNewPkgInfo(name, newVer, newGuid, installDir);

+    }

+

+    /**

+     Add one new package entry.

+     

+     @param name Package base name

+     @param version Package version

+     @param guid Package Guid

+     @param installDir Package path

+     @throws IOException Exception during file operation

+    **/

+    public void addNewPkgInfo(String name, String version, String guid, String installDir) throws IOException {

+

+        PackageListDocument.PackageList.Package p = fddRoot.getPackageList().addNewPackage();

+        p.addNewPackageName().setStringValue(name);

+        p.addNewGuid().setStringValue(guid);

+        p.addNewVersion().setStringValue(version);

+        p.addNewPath().setStringValue(installDir + "/");

+

+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+        Date date = new Date();

+        p.addNewInstalledDate().setStringValue(format.format(date));

+        saveAs();

+    }

+

+    /**

+     Save the fdd into file with format options

+    **/

+    public void saveAs() {

+        XmlOptions options = new XmlOptions();

+

+        options.setCharacterEncoding("UTF-8");

+        options.setSavePrettyPrint();

+        options.setSavePrettyPrintIndent(2);

+        try {

+            fdd.save(dbFile, options);

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ForceInstallPkg.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ForceInstallPkg.java
new file mode 100644
index 0000000..4fe88b4
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ForceInstallPkg.java
@@ -0,0 +1,80 @@
+/** @file

+  Java class ForceInstallPkg is used to install a package without DB check.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.io.*;

+import java.util.jar.*;

+import org.apache.xmlbeans.XmlException;

+

+/**

+ Derived class from FrameworkPkg, installation skipping some checks.

+  

+ @since PackageEditor 1.0

+**/

+public class ForceInstallPkg extends FrameworkPkg {

+

+    private String oldVer = null;

+

+    private String oldGuid = null;

+

+    /**

+       Constructor with parameters

+       

+       @param s Package path to be installed 

+       @param d Destination directory

+    **/

+    public ForceInstallPkg(String s, String d) {

+        super(s, d);

+       

+    }

+

+    public void setOldVersion(String v) {

+        oldVer = v;

+    }

+

+    public void setOldGuid(String guid) {

+        oldGuid = guid;

+    }

+

+    /**

+     Set jar file to package name to be installed

+     **/

+    protected void pre_install() throws DirSame, IOException {

+        setJf(new JarFile(getPkg()));

+        

+    }

+

+    /**

+     Update database file contents after install

+     **/

+    protected void post_install() throws IOException, XmlException {

+        //

+        // Get package info. from FDPManifest.xml file

+        //

+        setJf(new JarFile(getPkg()));

+        ManifestContents manFile = new ManifestContents(getManifestInputStream(getJf()));

+        setBName(manFile.getBaseName());

+        setPVer(manFile.getVersion());

+        setPGuid(manFile.getGuid());

+        getJf().close();

+

+        //

+        // Add force installed package info. into database file

+        //

+        setDbFile(new File(getWkSpace() + System.getProperty("file.separator") + FrameworkPkg.dbConfigFile));

+        setDfc(new DbFileContents(new File(getWkSpace() + System.getProperty("file.separator") + dbConfigFile)));

+        getDfc().updatePkgInfo(getBName(), oldVer, oldGuid, getWkDir().substring(getWkSpace().length() + 1), getPVer(),

+                               getPGuid());

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/FrameworkPkg.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/FrameworkPkg.java
new file mode 100644
index 0000000..b184cf9
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/FrameworkPkg.java
@@ -0,0 +1,402 @@
+/** @file

+  Java class FrameworkPkg is used to do package related operations.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.io.*;

+import java.util.Enumeration;

+import java.util.LinkedList;

+import java.util.List;

+import java.util.jar.*;

+import org.apache.xmlbeans.*;

+

+import org.tianocore.PackageListDocument;

+

+/**

+ This class deals with package related operations

+  

+ @since PackageEditor 1.0

+**/

+public class FrameworkPkg {

+

+    private String pkg = null;

+

+    private JarFile jf = null;

+

+    ///

+    /// where the package will be extracted to

+    /// 

+    private String wkDir = null;

+

+    private String bName = null;

+

+    private String pVer = null;

+

+    private String pGuid = null;

+

+    ///

+    /// current WORKSPACE location

+    ///

+    private String wkSpace = null;

+

+    private File dbFile = null;

+

+    private DbFileContents dfc = null;

+

+    ///

+    /// relative path of FrameworkDatabase.db file

+    ///

+    final static String dbConfigFile = "Tools" + System.getProperty("file.separator") + "Conf"

+                                       + System.getProperty("file.separator") + "FrameworkDatabase.db";

+

+

+    public FrameworkPkg() {

+

+    }

+

+    public FrameworkPkg(String package_name, String work_space) {

+        pkg = package_name;

+        wkSpace = work_space;

+    }

+

+    /**

+     install package (*.fdp file) to dir

+     

+     @param dir Destination directory

+     @retval <0> Install successfully

+     @return int

+     @throws IOException

+     @throws XmlException Xml file exception

+     @throws DirSame One package already installed to dir

+     @throws BasePkgNotInstalled Some package must be installed first

+     @throws VerNotEqual At least one package info with same base name but version different

+     @throws GuidNotEqual At least one package info with same base name and version but guid different

+     @throws SameAll At least one package info with same base name, version and guid same

+    **/

+    public int install(final String dir) throws IOException, XmlException, DirSame, BasePkgNotInstalled, VerNotEqual,

+                                        GuidNotEqual, SameAll {

+        wkDir = dir;

+        pre_install();

+        extract(wkDir);

+        post_install();

+        return 0;

+    }

+

+    public int uninstall() {

+

+        return 0;

+    }

+

+    /**

+     Check package info. against Frameworkdatabase.db

+     

+     @throws IOException

+     @throws XmlException Xml file exception

+     @throws DirSame One package already installed to dir

+     @throws BasePkgNotInstalled Some package must be installed first

+     @throws VerNotEqual At least one package info with same base name but version different

+     @throws GuidNotEqual At least one package info with same base name and version but guid different

+     @throws SameAll At least one package info with same base name, version and guid same

+    **/

+    protected void pre_install() throws IOException, XmlException, DirSame, BasePkgNotInstalled, VerNotEqual,

+                                GuidNotEqual, SameAll {

+

+        jf = new JarFile(pkg);

+

+        ManifestContents manFile = new ManifestContents(getManifestInputStream(jf));

+

+        String baseName = manFile.getBaseName();

+        String pkgVersion = manFile.getVersion();

+        String pkgGuid = manFile.getGuid();

+        bName = baseName;

+        pVer = pkgVersion;

+        pGuid = pkgGuid;

+

+        if (dbFile == null) {

+            dbFile = new File(wkSpace + System.getProperty("file.separator") + dbConfigFile);

+        }

+        //

+        // the db file should exist if base packages have been installed

+        //

+        if (!dbFile.exists()) {

+            throw new BasePkgNotInstalled();

+        }

+

+        if (dfc == null) {

+            dfc = new DbFileContents(dbFile);

+        }

+        if (dfc.checkDir(wkDir) != 0) {

+            throw new DirSame();

+        }

+        

+        //

+        // Get database info into lists

+        //

+        List<PackageListDocument.PackageList.Package> lpSameBase = new LinkedList<PackageListDocument.PackageList.Package>();

+        List<PackageListDocument.PackageList.Package> lpSameVersion = new LinkedList<PackageListDocument.PackageList.Package>();

+        int i = dfc.query(baseName, pkgVersion, pkgGuid, lpSameBase, lpSameVersion);

+

+        //

+        // throw various kind of exceptions according to query return value.

+        //

+        if (i == DbFileContents.VERSION_NOT_EQUAL) {

+

+            jf.close();

+            throw new VerNotEqual(lpSameBase);

+        }

+        if (i == DbFileContents.GUID_NOT_EQUAL) {

+

+            jf.close();

+            throw new GuidNotEqual(lpSameVersion);

+        }

+        if (i == DbFileContents.SAME_ALL) {

+            jf.close();

+            throw new SameAll(lpSameVersion);

+        }

+

+    }

+

+    /**

+     Add package info into db file.

+     

+     @throws IOException

+     @throws XmlException

+    **/

+    protected void post_install() throws IOException, XmlException {

+

+        dfc.addNewPkgInfo(bName, pVer, pGuid, wkDir.substring(wkSpace.length() + 1));

+

+    }

+

+    /**

+     Extract package to dir

+     

+     @param dir Destination directory

+     @throws DirSame

+     @throws IOException

+    **/

+    private void extract(String dir) throws DirSame, IOException {

+

+        new File(dir).mkdirs();

+        dir += System.getProperty("file.separator");

+        try {

+            for (Enumeration e = jf.entries(); e.hasMoreElements();) {

+                JarEntry je = (JarEntry) e.nextElement();

+                

+                //

+                // jar entry contains directory only, make these directories

+                //

+                if (je.isDirectory()) {

+                    new File(dir + je.getName()).mkdirs();

+                    continue;

+                }

+                

+                //

+                // jar entry contains relative path and file name, make relative directories

+                // under destination dir

+                //

+                int index = je.getName().lastIndexOf(System.getProperty("file.separator"));

+                if (index != -1) {

+                    String dirPath = je.getName().substring(0, index);

+                    new File(dir + dirPath).mkdirs();

+                }

+                

+                if (je != null) {

+                    //

+                    // Get an input stream for this entry.

+                    //

+                    InputStream entryStream = jf.getInputStream(je);

+

+                    try {

+                        //

+                        // Create the output file (clobbering the file if it exists).

+                        //

+                        FileOutputStream file = new FileOutputStream(dir + je.getName());

+

+                        try {

+

+                            byte[] buffer = new byte[1024];

+                            int bytesRead;

+                            //

+                            // Read the entry data and write it to the output file.

+                            //

+                            while ((bytesRead = entryStream.read(buffer)) != -1) {

+                                file.write(buffer, 0, bytesRead);

+                            }

+

+                            System.out.println(je.getName() + " extracted.");

+                        } finally {

+                            file.close();

+                        }

+                    } finally {

+                        entryStream.close();

+                    }

+                }

+

+            }

+

+        } finally {

+            jf.close();

+

+        }

+

+    }

+

+    public String getBName() {

+        return bName;

+    }

+

+    public void setBName(String name) {

+        bName = name;

+    }

+

+    public File getDbFile() {

+        return dbFile;

+    }

+

+    public void setDbFile(File dbFile) {

+        this.dbFile = dbFile;

+    }

+

+    public DbFileContents getDfc() {

+        return dfc;

+    }

+

+    public void setDfc(DbFileContents dfc) {

+        this.dfc = dfc;

+    }

+

+    public String getPGuid() {

+        return pGuid;

+    }

+

+    public void setPGuid(String guid) {

+        pGuid = guid;

+    }

+

+    public String getPVer() {

+        return pVer;

+    }

+

+    public void setPVer(String ver) {

+        pVer = ver;

+    }

+

+    public String getWkDir() {

+        return wkDir;

+    }

+

+    public void setWkDir(String wkDir) {

+        this.wkDir = wkDir;

+    }

+

+    public String getWkSpace() {

+        return wkSpace;

+    }

+

+    public void setWkSpace(String wkSpace) {

+        this.wkSpace = wkSpace;

+    }

+

+    public JarFile getJf() {

+        return jf;

+    }

+

+    public void setJf(JarFile jf) {

+        this.jf = jf;

+    }

+

+    public String getPkg() {

+        return pkg;

+    }

+

+    public void setPkg(String pkg) {

+        this.pkg = pkg;

+    }

+

+    /**

+     Get the input stream of FDPManifest.xml file from jar entry

+     

+     @param jf The Jar file that contains FDPManifest.xml file

+     @return InputStream

+     @throws IOException

+    **/

+    protected InputStream getManifestInputStream(JarFile jf) throws IOException {

+        JarEntry je = null;

+        for (Enumeration e = jf.entries(); e.hasMoreElements();) {

+            je = (JarEntry) e.nextElement();

+            if (je.getName().contains("FDPManifest.xml"))

+                return jf.getInputStream(je);

+        }

+

+        return null;

+    }

+

+}

+

+

+/**

+ Various Exception classes for what happened when database info and package info

+ are compared.

+  

+ @since PackageEditor 1.0

+**/

+class DirSame extends Exception {

+    final static long serialVersionUID = 0;

+}

+

+class BasePkgNotInstalled extends Exception {

+    final static long serialVersionUID = 0;

+}

+

+class VerNotEqual extends Exception {

+    final static long serialVersionUID = 0;

+

+    //private String version = null;

+    List<PackageListDocument.PackageList.Package> lppSameBase = null;

+

+    VerNotEqual(List<PackageListDocument.PackageList.Package> ver) {

+        lppSameBase = ver;

+    }

+

+    public List<PackageListDocument.PackageList.Package> getVersion() {

+        return lppSameBase;

+    }

+}

+

+class GuidNotEqual extends Exception {

+    final static long serialVersionUID = 0;

+

+    private List<PackageListDocument.PackageList.Package> lppSameVer = null;

+

+    GuidNotEqual(List<PackageListDocument.PackageList.Package> ver) {

+        lppSameVer = ver;

+    }

+

+    public List<PackageListDocument.PackageList.Package> getGuid() {

+        return lppSameVer;

+    }

+}

+

+class SameAll extends Exception {

+    final static long serialVersionUID = 0;

+

+    private List<PackageListDocument.PackageList.Package> version = null;

+

+    SameAll(List<PackageListDocument.PackageList.Package> ver) {

+        version = ver;

+    }

+

+    public List<PackageListDocument.PackageList.Package> getVersion() {

+        return version;

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GenGuidDialog.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GenGuidDialog.java
new file mode 100644
index 0000000..c58010a
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GenGuidDialog.java
@@ -0,0 +1,391 @@
+/** @file

+  Java class GenGuidDialog.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+

+import javax.swing.JPanel;

+import javax.swing.JDialog;

+import java.awt.GridLayout;

+

+import javax.swing.JFrame;

+import javax.swing.JOptionPane;

+import javax.swing.JTextField;

+import javax.swing.JLabel;

+import javax.swing.JRadioButton;

+import javax.swing.ButtonGroup;

+import javax.swing.JButton;

+

+import org.tianocore.common.Tools;

+

+import java.awt.FlowLayout;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.awt.event.WindowAdapter;

+import java.awt.event.WindowEvent;

+

+/**

+ Dialog for GUID generation. 

+ @since PackageEditor 1.0

+**/

+public class GenGuidDialog extends JDialog implements ActionListener{

+

+    static private JFrame frame;

+    private JPanel jContentPane = null;

+    private JPanel jPanel = null;

+    private JPanel jPanel1 = null;

+    private JPanel jPanel2 = null;

+    private JPanel jPanel3 = null;

+    private JPanel jPanel4 = null;

+    private JTextField jTextField = null;

+    private JLabel jLabel = null;

+    private JRadioButton jRadioButton = null;

+    private JRadioButton jRadioButton1 = null;

+    private JButton jButton = null;

+    private JButton jButton1 = null;

+    private JButton jButton2 = null;

+    

+//    private String guid = null;

+

+    public void actionPerformed(ActionEvent arg0) {

+        // TODO Auto-generated method stub

+        if (arg0.getSource() == jButton1){

+            String uuid = Tools.generateUuidString();

+            if (jRadioButton1.isSelected()) {

+                jTextField.setText(uuid);

+            }

+            else {

+                //ToDo: transform to comma-sep guid

+                String s = Tools.formatGuidString(uuid);

+                if (s.equals("0")) {

+                    JOptionPane.showMessageDialog(frame, "Check GUID Value, it don't conform to the schema.");

+                    return;

+                }

+                jTextField.setText(s);

+            }

+        }

+        

+        if (arg0.getSource() == jRadioButton1){

+            

+            //ToDo: check text field value against RegExp and transform if needed

+            if (jTextField.getText().matches(Tools.guidRegistryPat)){

+                return;

+            }

+            if (jTextField.getText().matches(Tools.guidArrayPat)) {

+                jTextField.setText(Tools.formatGuidString(jTextField.getText()));

+                return;

+            }

+            

+            JOptionPane.showMessageDialog(frame, "Check GUID Value, it don't conform to the schema.");

+                    

+        }

+        

+        if (arg0.getSource() == jRadioButton){

+            

+            //ToDo: check text field value against RegExp and transform if needed

+            if (jTextField.getText().matches(Tools.guidArrayPat)){

+                return;

+            }

+            if (jTextField.getText().matches(Tools.guidRegistryPat)) {

+                jTextField.setText(Tools.formatGuidString(jTextField.getText()));

+                return;

+            }

+            

+            JOptionPane.showMessageDialog(frame, "Check GUID Value, it don't conform to the schema.");

+            

+        }

+        

+        if (arg0.getSource() == jButton2){

+//            if (jTextField.getText().matches(Tools.guidArrayPat) 

+//                            || jTextField.getText().matches(Tools.guidRegistryPat)){

+//                this.setVisible(false);

+//            }

+//            else {

+//                JOptionPane.showMessageDialog(frame, "Incorrect GUID Value Format.");

+//            }

+            this.dispose();

+        }

+        

+        if (arg0.getSource() == jButton){

+            this.dispose();

+        }

+    }

+

+    /**

+     * This method initializes jPanel	

+     * 	

+     * @return javax.swing.JPanel	

+     */

+    private JPanel getJPanel() {

+        if (jPanel == null) {

+            FlowLayout flowLayout = new FlowLayout();

+            flowLayout.setVgap(10);

+            jPanel = new JPanel();

+            jPanel.setLayout(flowLayout);

+            jPanel.setPreferredSize(new java.awt.Dimension(100,30));

+            jPanel.add(getJButton1(), null);

+            jPanel.add(getJButton2(), null);

+            jPanel.add(getJButton(), null);

+        }

+        return jPanel;

+    }

+

+    /**

+     * This method initializes jPanel1	

+     * 	

+     * @return javax.swing.JPanel	

+     */

+    private JPanel getJPanel1() {

+        if (jPanel1 == null) {

+            jPanel1 = new JPanel();

+        }

+        return jPanel1;

+    }

+

+    /**

+     * This method initializes jPanel2	

+     * 	

+     * @return javax.swing.JPanel	

+     */

+    private JPanel getJPanel2() {

+        if (jPanel2 == null) {

+            jPanel2 = new JPanel();

+        }

+        return jPanel2;

+    }

+

+    /**

+     * This method initializes jPanel3	

+     * 	

+     * @return javax.swing.JPanel	

+     */

+    private JPanel getJPanel3() {

+        if (jPanel3 == null) {

+            jPanel3 = new JPanel();

+        }

+        return jPanel3;

+    }

+

+    /**

+     * This method initializes jPanel4	

+     * 	

+     * @return javax.swing.JPanel	

+     */

+    private JPanel getJPanel4() {

+        if (jPanel4 == null) {

+            jLabel = new JLabel();

+            jLabel.setText("GUID Value");

+            GridLayout gridLayout = new GridLayout();

+            gridLayout.setRows(4);

+            jPanel4 = new JPanel();

+            jPanel4.setLayout(gridLayout);

+            jPanel4.add(getJRadioButton1(), null);

+            jPanel4.add(getJRadioButton(), null);

+            jPanel4.add(jLabel, null);

+            jPanel4.add(getJTextField(), null);

+            ButtonGroup bg = new ButtonGroup();

+            bg.add(jRadioButton1);

+            bg.add(jRadioButton);

+        }

+        return jPanel4;

+    }

+

+    /**

+     * This method initializes jTextField	

+     * 	

+     * @return javax.swing.JTextField	

+     */

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setHorizontalAlignment(JTextField.LEADING);

+            jTextField.setPreferredSize(new java.awt.Dimension(100,20));

+        }

+        return jTextField;

+    }

+

+    /**

+     * This method initializes jRadioButton	

+     * 	

+     * @return javax.swing.JRadioButton	

+     */

+    private JRadioButton getJRadioButton() {

+        if (jRadioButton == null) {

+            jRadioButton = new JRadioButton();

+            jRadioButton.setText("Comma-Seperated Format");

+            jRadioButton.addActionListener(this);

+        }

+        return jRadioButton;

+    }

+

+    /**

+     * This method initializes jRadioButton1	

+     * 	

+     * @return javax.swing.JRadioButton	

+     */

+    private JRadioButton getJRadioButton1() {

+        if (jRadioButton1 == null) {

+            jRadioButton1 = new JRadioButton();

+            jRadioButton1.setText("Registry Format");

+            jRadioButton1.setSelected(true);

+            jRadioButton1.addActionListener(this);

+        }

+        return jRadioButton1;

+    }

+

+    /**

+     * This method initializes jButton	

+     * 	

+     * @return javax.swing.JButton	

+     */

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setPreferredSize(new java.awt.Dimension(80,20));

+            jButton.setText("Cancel");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+

+    /**

+     * This method initializes jButton1	

+     * 	

+     * @return javax.swing.JButton	

+     */

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setPreferredSize(new java.awt.Dimension(80,20));

+            jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);

+            jButton1.setText("New");

+            jButton1.addActionListener(this);

+        }

+        return jButton1;

+    }

+

+    /**

+     * This method initializes jButton2	

+     * 	

+     * @return javax.swing.JButton	

+     */

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setPreferredSize(new java.awt.Dimension(80,20));

+            jButton2.setText("Ok");

+            jButton2.addActionListener(this);

+        }

+        return jButton2;

+    }

+

+    /**

+     

+     @param args

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+        new GenGuidDialog().setVisible(true);

+    }

+

+    public String getGuid(){

+        return jTextField.getText();

+    }

+    

+    public void setGuid(String s){

+        jTextField.setText(s);

+    }

+    /**

+     * This is the default constructor

+     */

+    public GenGuidDialog() {

+        super();

+        initialize();

+    }

+    

+    public GenGuidDialog(ActionListener i){

+        super();

+        initialize();

+        jButton2.addActionListener(i);

+        this.addWindowListener(new WindowAdapter(){

+

+            @Override

+            public void windowActivated(WindowEvent arg0) {

+                // TODO Auto-generated method stub

+                super.windowActivated(arg0);

+                if ((jRadioButton1.isSelected() && jTextField.getText().matches(Tools.guidArrayPat))

+                                || (jRadioButton.isSelected() && jTextField.getText().matches(Tools.guidRegistryPat))) {

+                    jTextField.setText(Tools.formatGuidString(jTextField.getText()));

+                }

+                

+//                if (!jTextField.getText().matches(Tools.guidArrayPat) || !jTextField.getText().matches(Tools.guidRegistryPat)) {

+//                  JOptionPane.showMessageDialog(frame, "InitVal: Incorrect GUID Value Format.");

+//                  return;

+//                }

+            }

+            

+        });

+    }

+

+    /**

+     * This method initializes this

+     * 

+     * @return void

+     */

+    private void initialize() {

+        this.setSize(466, 157);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setModal(true);

+        this.setTitle("Editing GUID Value");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+

+    /**

+     * This method initializes jContentPane

+     * 

+     * @return javax.swing.JPanel

+     */

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(new BorderLayout());

+            jContentPane.add(getJPanel(), java.awt.BorderLayout.EAST);

+            jContentPane.add(getJPanel1(), java.awt.BorderLayout.WEST);

+            jContentPane.add(getJPanel2(), java.awt.BorderLayout.NORTH);

+            jContentPane.add(getJPanel3(), java.awt.BorderLayout.SOUTH);

+            jContentPane.add(getJPanel4(), java.awt.BorderLayout.CENTER);

+        }

+        return jContentPane;

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+    

+}  //  @jve:decl-index=0:visual-constraint="10,10"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuiPkgInstall.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuiPkgInstall.java
new file mode 100644
index 0000000..3e75720
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuiPkgInstall.java
@@ -0,0 +1,804 @@
+/** @file

+  Java class GuiPkgInstall is GUI for package installation.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JButton;

+import javax.swing.JFileChooser;

+import javax.swing.JLabel;

+import javax.swing.JOptionPane;

+import javax.swing.JTextField;

+

+import java.awt.Dimension;

+import java.awt.GridLayout;

+import java.awt.Toolkit;

+

+import java.awt.FlowLayout;

+import java.awt.event.MouseEvent;

+import java.awt.event.MouseListener;

+import java.awt.event.WindowAdapter;

+import java.awt.event.WindowEvent;

+

+import java.awt.ComponentOrientation;

+import java.io.File;

+import java.util.Hashtable;

+

+import javax.swing.SwingConstants;

+import javax.swing.JProgressBar;

+import javax.swing.filechooser.FileFilter;

+

+import org.apache.xmlbeans.XmlException;

+

+

+/**

+ GUI for package installation. 

+  

+ @since PackageEditor 1.0

+**/

+public class GuiPkgInstall extends JFrame implements MouseListener {

+

+    final static long serialVersionUID = 0;

+

+    static JFrame frame;

+

+    ///

+    /// backup of "this". As we cannot use "this" to refer outer class inside inner class

+    ///

+    private JFrame pThis = null;

+

+    private JFileChooser chooser = null;

+

+    private JPanel jPanel = null;

+

+    private JPanel jPanel1 = null;

+

+    private JTextField jTextField = null;

+

+    private JButton jButton = null;

+

+    private JPanel jPanel2 = null;

+

+    private JLabel jLabel1 = null;

+

+    private JPanel jPanel4 = null;

+

+    private JTextField jTextField1 = null;

+

+    private JButton jButton1 = null;

+

+    private JPanel jPanel5 = null;

+

+    private JPanel jPanel6 = null;

+

+    private JPanel jPanel7 = null;

+

+    private JLabel jLabel2 = null;

+

+    private JTextField jTextField2 = null;

+

+    private JButton jButton2 = null;

+

+    private JButton jButton3 = null;

+

+    private JPanel jPanel3 = null;

+

+    private JLabel jLabel = null;

+

+    private JProgressBar jProgressBar = null;

+

+    private JButton jButton4 = null;

+

+

+    public GuiPkgInstall() {

+        super();

+        initialize();

+

+    }

+

+    /**

+     GUI initialization

+    **/

+    private void initialize() {

+        this.setSize(new java.awt.Dimension(454, 313));

+        this.setContentPane(getJPanel());

+        this.setTitle("Package Installation");

+        this.addWindowListener(new GuiPkgInstallAdapter(this));

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);

+        this.centerWindow();

+        pThis = this;

+    }

+

+    /**

+     make window appear center of screen

+     

+     @param intWidth

+     @param intHeight

+    **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+    **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes jPanel

+     @return javax.swing.JPanel

+    **/

+    private JPanel getJPanel() {

+        if (jPanel == null) {

+            GridLayout gridLayout = new GridLayout();

+            gridLayout.setRows(7);

+            gridLayout.setColumns(1);

+            jPanel = new JPanel();

+            jPanel.setLayout(gridLayout);

+            jPanel.add(getJPanel3(), null);

+            jPanel.add(getJPanel1(), null);

+            jPanel.add(getJPanel2(), null);

+            jPanel.add(getJPanel4(), null);

+            jPanel.add(getJPanel5(), null);

+            jPanel.add(getJPanel6(), null);

+            jPanel.add(getJPanel7(), null);

+        }

+        return jPanel;

+    }

+

+    /**

+      This method initializes jPanel1	

+     	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel1() {

+        if (jPanel1 == null) {

+            FlowLayout flowLayout = new FlowLayout();

+            flowLayout.setAlignment(java.awt.FlowLayout.LEFT);

+            jPanel1 = new JPanel();

+            jPanel1.setLayout(flowLayout);

+            jPanel1.add(getJTextField(), null);

+            jPanel1.add(getJButton(), null);

+        }

+        return jPanel1;

+    }

+

+    /**

+      This method initializes jTextField	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setHorizontalAlignment(javax.swing.JTextField.LEFT);

+            jTextField.setPreferredSize(new java.awt.Dimension(350, 20));

+        }

+        return jTextField;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+    **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);

+            jButton.setText("Browse");

+            jButton.setComponentOrientation(java.awt.ComponentOrientation.LEFT_TO_RIGHT);

+            jButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

+            jButton.setToolTipText("Where is the package?");

+            jButton.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 12));

+

+            jButton.setPreferredSize(new java.awt.Dimension(80, 20));

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (chooser == null) {

+                        chooser = new JFileChooser();

+                    }

+                    //

+                    // disable multi-selection, you can only select one item each time.

+                    //

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

+                    chooser.setFileFilter(new PkgFileFilter("fdp"));

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+

+                        File theFile = chooser.getSelectedFile();

+                        jTextField.setText(theFile.getPath());

+                        //

+                        // set a default directory for installation (WORKSPACE\PackageFileName)

+                        //

+                        if (jTextField1.getText().length() > 0) {

+                            int indexbegin = jTextField.getText().lastIndexOf(System.getProperty("file.separator"));

+                            int indexend = jTextField.getText().lastIndexOf('.');

+                            if (indexbegin >= 0 && indexend >= 0) {

+                                jTextField2.setText(jTextField1.getText()

+                                                    + jTextField.getText().substring(indexbegin, indexend));

+                            } else {

+                                JOptionPane.showMessageDialog(frame, "Wrong Path:" + jTextField.getText());

+                            }

+                        }

+                    }

+                }

+            });

+        }

+        return jButton;

+    }

+

+    /**

+      This method initializes jPanel2	

+      	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel2() {

+        if (jPanel2 == null) {

+            FlowLayout flowLayout1 = new FlowLayout();

+            flowLayout1.setAlignment(java.awt.FlowLayout.LEFT);

+            flowLayout1.setVgap(20);

+            jLabel1 = new JLabel();

+            jLabel1.setText("Enter Workspace Location");

+            jLabel1.setComponentOrientation(java.awt.ComponentOrientation.UNKNOWN);

+            jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.TRAILING);

+            jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);

+            jPanel2 = new JPanel();

+            jPanel2.setLayout(flowLayout1);

+            jPanel2.add(jLabel1, null);

+        }

+        return jPanel2;

+    }

+

+    /**

+      This method initializes jPanel4	

+      	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel4() {

+        if (jPanel4 == null) {

+            FlowLayout flowLayout2 = new FlowLayout();

+            flowLayout2.setAlignment(java.awt.FlowLayout.LEFT);

+            jPanel4 = new JPanel();

+            jPanel4.setLayout(flowLayout2);

+            jPanel4.add(getJTextField1(), null);

+            jPanel4.add(getJButton1(), null);

+        }

+        return jPanel4;

+    }

+

+    /**

+      This method initializes jTextField1	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField1() {

+        if (jTextField1 == null) {

+            jTextField1 = new JTextField();

+            jTextField1.setPreferredSize(new java.awt.Dimension(350, 20));

+

+        }

+        //

+        // default value is WORKSPACE environmental variable value

+        //

+        jTextField1.setText(System.getenv("WORKSPACE"));

+        return jTextField1;

+    }

+

+    /**

+      This method initializes jButton1	

+      	

+      @return javax.swing.JButton	

+    **/

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setComponentOrientation(java.awt.ComponentOrientation.LEFT_TO_RIGHT);

+            

+            jButton1.setHorizontalAlignment(javax.swing.SwingConstants.LEADING);

+            jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.TRAILING);

+            jButton1.setText("Browse");

+            jButton1.setPreferredSize(new java.awt.Dimension(80, 20));

+            jButton1.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (chooser == null) {

+                        chooser = new JFileChooser();

+                    }

+                    //

+                    // only directories can be selected for workspace location.

+                    //

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

+

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+

+                        File theFile = chooser.getSelectedFile();

+                        jTextField1.setText(theFile.getPath());

+                        //

+                        // set a default directory for installation (WORKSPACE\PackageFileName)

+                        //

+                        if (jTextField.getText().length() > 0) {

+                            int indexbegin = jTextField.getText().lastIndexOf(System.getProperty("file.separator"));

+                            int indexend = jTextField.getText().lastIndexOf('.');

+                            if (indexbegin >= 0 && indexend >= 0) {

+                                jTextField2.setText(jTextField1.getText()

+                                                    + jTextField.getText().substring(indexbegin, indexend));

+                            } else {

+                                JOptionPane.showMessageDialog(frame, "Wrong Path:" + jTextField.getText());

+                            }

+                        }

+                    }

+

+                }

+            });

+        }

+        return jButton1;

+    }

+

+    /**

+      This method initializes jButton4 

+       

+      @return javax.swing.JButton  

+     **/

+    private JButton getJButton4() {

+        if (jButton4 == null) {

+            jButton4 = new JButton();

+            jButton4.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

+            

+            jButton4.setHorizontalAlignment(SwingConstants.LEADING);

+            jButton4.setHorizontalTextPosition(SwingConstants.TRAILING);

+            jButton4.setText("Browse");

+            jButton4.setPreferredSize(new Dimension(80, 20));

+            jButton4.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    JFileChooser chooser = new JFileChooser(jTextField1.getText());

+                    

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

+

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        //

+                        // specify installation directory from file chooser 

+                        //

+                        File theFile = chooser.getSelectedFile();

+                        jTextField2.setText(theFile.getPath());

+                        

+                    }

+                }

+            });

+            

+        }

+        return jButton4;

+    }

+    /**

+      This method initializes jPanel5	

+      	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel5() {

+        if (jPanel5 == null) {

+            FlowLayout flowLayout3 = new FlowLayout();

+            flowLayout3.setAlignment(java.awt.FlowLayout.LEFT);

+            flowLayout3.setVgap(20);

+            jLabel2 = new JLabel();

+            jLabel2.setComponentOrientation(java.awt.ComponentOrientation.UNKNOWN);

+            jLabel2.setHorizontalTextPosition(javax.swing.SwingConstants.TRAILING);

+            jLabel2.setText("Enter Installation  Location Within Workspace");

+            jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);

+            jPanel5 = new JPanel();

+            jPanel5.setLayout(flowLayout3);

+            jPanel5.add(jLabel2, null);

+        }

+        return jPanel5;

+    }

+

+    /**

+      This method initializes jPanel6	

+      	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel6() {

+        if (jPanel6 == null) {

+            FlowLayout flowLayout4 = new FlowLayout();

+            flowLayout4.setAlignment(java.awt.FlowLayout.LEFT);

+            jPanel6 = new JPanel();

+            jPanel6.setLayout(flowLayout4);

+            jPanel6.add(getJTextField2(), null);

+            jPanel6.add(getJButton4(), null);

+        }

+        return jPanel6;

+    }

+

+    /**

+      This method initializes jPanel7	

+      	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel7() {

+        if (jPanel7 == null) {

+            FlowLayout flowLayout5 = new FlowLayout();

+            flowLayout5.setAlignment(java.awt.FlowLayout.RIGHT);

+            jPanel7 = new JPanel();

+            jPanel7.setLayout(flowLayout5);

+            jPanel7.add(getJProgressBar(), null);

+            jPanel7.add(getJButton2(), null);

+            jPanel7.add(getJButton3(), null);

+        }

+        return jPanel7;

+    }

+

+    /**

+      This method initializes jTextField2	

+     	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField2() {

+        if (jTextField2 == null) {

+            jTextField2 = new JTextField();

+            jTextField2.setPreferredSize(new java.awt.Dimension(350, 20));

+        }

+        return jTextField2;

+    }

+

+    /**

+      This method initializes jButton2	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setPreferredSize(new java.awt.Dimension(80, 20));

+            jButton2.setText("Ok");

+            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    try {

+                        //

+                        // The installation directory must under workspace directory

+                        //

+                        locationcheck(jTextField.getText(), jTextField1.getText(), jTextField2.getText());

+                    } catch (Exception ee) {

+                        JOptionPane.showMessageDialog(frame, "Package Location Error!");

+                        return;

+                    }

+                    

+                    try {

+                        //

+                        // create a new FrameworkPkg object with user-selected package, current workspace location.

+                        // install the package to dest dir from jTextField2

+                        //

+                        int i = new FrameworkPkg(jTextField.getText(), jTextField1.getText())

+                                                                                             .install(jTextField2

+                                                                                                                 .getText());

+                        //

+                        // the package is installed smoothly

+                        //

+                        if (i == 0) {

+                            JOptionPane.showMessageDialog(frame, "Package" + jTextField.getText()

+                                                                 + " Installed Successfully!");

+                        }

+                    } catch (BasePkgNotInstalled bpni) {

+                        //

+                        // exception no base package installed

+                        //

+                        JOptionPane

+                                   .showMessageDialog(frame,

+                                                      "The Edk package needs to be installed before installing any other packages.");

+                    } catch (VerNotEqual vne) {

+                        //

+                        // show modal GUI PkgInstallTypeChooser with user selected package name, 

+                        // current workspace location and the list of package info with same base name

+                        //

+                        ModalFrameUtil.showAsModal(new PkgInstallTypeChooser(jTextField.getText(),

+                                                                             jTextField1.getText(), vne.getVersion()),

+                                                   pThis);

+

+                    } catch (GuidNotEqual gne) {

+                        //

+                        // show modal GUI PkgInstallTypeChooser with user selected package name, 

+                        // current workspace location and the list of package info with same base name and version

+                        //

+                        ModalFrameUtil.showAsModal(new PkgInstallTypeChooser(jTextField.getText(),

+                                                                             jTextField1.getText(), gne.getGuid()),

+                                                   pThis);

+

+                    } catch (SameAll sa) {

+                        //

+                        // the package with same (base, version, guid) already exists. confirm user action.

+                        // quit or replace the original info. (So only one package info entry in db file that may be triple same)

+                        //

+                        int retVal = JOptionPane

+                                                .showConfirmDialog(

+                                                                   frame,

+                                                                   "Package already exists. Would you like to replace it?",

+                                                                   "Package Installation", JOptionPane.YES_NO_OPTION);

+                        if (retVal == JOptionPane.YES_OPTION) {

+                            String installDir = sa.getVersion().listIterator().next().getPathArray(0).getStringValue();

+                            try {

+                                ForceInstallPkg f = new ForceInstallPkg(jTextField.getText(), jTextField1.getText());

+                                //

+                                // Get old packag info to meet the calling parameter layout of DbFileContents.updatePkgInfo

+                                // ForceInstallPkg will call it after installation to update package info.

+                                //

+                                f.setOldVersion(sa.getVersion().listIterator().next().getVersionArray(0));

+                                f.setOldGuid(sa.getVersion().listIterator().next().getGuidArray(0).getStringValue());

+                                int i = f.install(jTextField1.getText() + System.getProperty("file.separator") + installDir);

+                                if (i == 0) {

+                                    JOptionPane.showMessageDialog(frame, "Package" + jTextField.getText()

+                                                                         + " Installed Successfully!");

+                                }

+                            } catch (Exception sae) {

+                                System.out.println(sae.toString());

+                                JOptionPane.showMessageDialog(frame, "Extraction Error!");

+                            }

+                        }

+                        return;

+                    } catch (XmlException xmle) {

+                        System.out.println(xmle.toString());

+                        JOptionPane.showMessageDialog(frame, "Package Format Error!");

+                    } catch (DirSame ds) {

+                        //

+                        // You cannot install different packages into the same directory.

+                        //

+                        System.out.println(ds.toString());

+                        JOptionPane.showMessageDialog(frame,

+                                                      "Another Package Exists There, Please Select Another Directory!");

+                    } catch (Exception ext) {

+                        System.out.println(ext.toString());

+                        JOptionPane.showMessageDialog(frame, "Extraction Error!");

+                    }

+                }

+            });

+        }

+        return jButton2;

+    }

+

+    /**

+     * This method initializes jButton3	

+     * 	

+     * @return javax.swing.JButton	

+     */

+    private JButton getJButton3() {

+        if (jButton3 == null) {

+            jButton3 = new JButton();

+            jButton3.setPreferredSize(new java.awt.Dimension(80, 20));

+            jButton3.setText("Cancel");

+            jButton3.addMouseListener(this);

+        }

+        return jButton3;

+

+    }

+

+    /**

+      This method initializes jPanel3	

+      	

+      @return javax.swing.JPanel	

+     */

+    private JPanel getJPanel3() {

+        if (jPanel3 == null) {

+            jLabel = new JLabel();

+            jLabel.setComponentOrientation(ComponentOrientation.UNKNOWN);

+            jLabel.setHorizontalTextPosition(SwingConstants.TRAILING);

+            jLabel.setText("Enter Package Location");

+            jLabel.setHorizontalAlignment(SwingConstants.TRAILING);

+            FlowLayout flowLayout6 = new FlowLayout();

+            flowLayout6.setVgap(20);

+            flowLayout6.setAlignment(FlowLayout.LEFT);

+            jPanel3 = new JPanel();

+            jPanel3.setLayout(flowLayout6);

+            jPanel3.add(jLabel, null);

+        }

+        return jPanel3;

+    }

+

+    /**

+     check user input validity

+    

+     @param s package path

+     @param s1 workspace path

+     @param s2 installation path

+     @throws Exception

+    **/

+    private void locationcheck(String s, String s1, String s2) throws Exception {

+        if (new File(s).isFile() == false)

+            throw new Exception();

+        if (new File(s1).isDirectory() == false)

+            throw new Exception();

+        if (s2.startsWith(s1) == false)

+            throw new Exception();

+    }

+

+ 

+    public void mouseClicked(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+        int retVal = JOptionPane.showConfirmDialog(frame, "Are you sure to exit?", "Quit", JOptionPane.YES_NO_OPTION);

+        if (retVal == JOptionPane.YES_OPTION) {

+            this.dispose();

+        }

+        return;

+    }

+

+    public void mouseEntered(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mouseExited(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mousePressed(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mouseReleased(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    /**

+      This method initializes jProgressBar	

+      	

+      @return javax.swing.JProgressBar	

+     **/

+    private JProgressBar getJProgressBar() {

+        if (jProgressBar == null) {

+            jProgressBar = new JProgressBar();

+            jProgressBar.setComponentOrientation(java.awt.ComponentOrientation.LEFT_TO_RIGHT);

+            jProgressBar.setVisible(false);

+        }

+        return jProgressBar;

+    }

+

+   

+

+} //  @jve:decl-index=0:visual-constraint="24,82"

+

+/**

+Derived from WindowAdapter, Event adapter for windowClosing event

+ 

+@since PackageEditor 1.0

+**/

+class GuiPkgInstallAdapter extends WindowAdapter {

+

+   private JFrame frame = null;

+

+   GuiPkgInstallAdapter(JFrame f) {

+       super();

+       frame = f;

+   }

+

+   /* (non-Javadoc)

+    * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)

+    */

+   @Override

+   public void windowClosing(WindowEvent arg0) {

+       // TODO Auto-generated method stub

+       super.windowClosing(arg0);

+       int retVal = JOptionPane.showConfirmDialog(frame, "Are you sure to exit?", "Quit",

+                                                  JOptionPane.YES_NO_OPTION);

+       if (retVal == JOptionPane.YES_OPTION) {

+           frame.dispose();

+       }

+

+   }

+

+}

+

+/**

+ Filter out some specific type of file

+ 

+ @since PackageEditor 1.0

+**/

+class PkgFileFilter extends FileFilter {

+

+    ///

+    /// hash table used to store filter info.

+    ///

+    private Hashtable<String, String> filters = null;

+    

+

+    public PkgFileFilter() {

+        this.filters = new Hashtable<String, String>();

+    }

+    

+    /**

+       Create filter and add extension to hash table

+        

+       @param extension file extension string (e.g. "exe")

+    **/

+    public PkgFileFilter(String extension) {

+        this();

+        if(extension!=null) {

+            addExtension(extension);

+        }

+    

+    }

+

+    public PkgFileFilter(String[] fileFilters) {

+        this();

+        int i = 0; 

+        while (i < fileFilters.length) {

+            // add filters one by one

+            addExtension(fileFilters[i]);

+            i++;

+        }

+    

+    }

+

+ 

+    /* (non-Javadoc)

+     * @see javax.swing.filechooser.FileFilter#accept(java.io.File)

+     */

+    public boolean accept(File f) {

+        if (f != null) {

+            if (f.isDirectory()) {

+                return true;

+            }

+            

+            if (getExtension(f) != null && filters.get(getExtension(f)) != null) {

+                return true;

+            }

+        }

+        return false;

+    }

+

+    

+    /**

+     Get the extension string of file

+     

+     @param f target file

+     @return String

+    **/

+    public String getExtension(File f) {

+        if (f != null) {

+            int i = f.getName().lastIndexOf('.');

+            if (i>0 && i<f.getName().length()-1) {

+                return f.getName().substring(i+1).toLowerCase();

+            }

+        }

+        return null;

+    }

+

+    

+    /**

+     Add extension info into hash table

+     

+     @param ext extension string for file name

+    **/

+    public void addExtension(String ext) {

+        if (filters == null) {

+            filters = new Hashtable<String, String>(5);

+        }

+        filters.put(ext.toLowerCase(), "ext");

+   

+    }

+    

+    /* (non-Javadoc)

+     * @see javax.swing.filechooser.FileFilter#getDescription()

+     */

+    public String getDescription() {

+        return null;

+    }

+

+}

+

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuiPkgUninstall.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuiPkgUninstall.java
new file mode 100644
index 0000000..667f65b
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuiPkgUninstall.java
@@ -0,0 +1,370 @@
+/** @file

+  Java class GuiPkgUninstall is GUI for package installation.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import java.awt.FlowLayout;

+//import java.awt.GridLayout;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import java.awt.Dimension;

+import javax.swing.JButton;

+import java.awt.ComponentOrientation;

+import java.awt.Font;

+import java.awt.Toolkit;

+import java.io.File;

+

+import javax.swing.JFileChooser;

+import javax.swing.JOptionPane;

+import javax.swing.SwingConstants;

+import javax.swing.JList;

+import javax.swing.JTextPane;

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.DefaultTableModel;

+

+/**

+ GUI for package uninstallation.

+ 

+ @since PackageEditor 1.0

+**/

+public class GuiPkgUninstall extends JFrame {

+

+    final static long serialVersionUID = 0;

+    

+    static JFrame frame;

+

+    private JPanel jPanel = null;

+

+    private JLabel jLabel = null;

+

+    private JTextField jTextField = null;

+

+    private JButton jButton = null;

+

+    private JLabel jLabel1 = null;

+

+    private JPanel jPanel1 = null;

+

+    private JButton jButton1 = null;

+

+    private JButton jButton2 = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private JButton jButton3 = null;

+    

+    private PkgRemoveTableModel model = null;

+    

+    private DbFileContents dfc = null;

+    

+    private JFrame pThis = null;

+

+    

+    public GuiPkgUninstall() {

+        super();

+        initialize();

+    }

+

+   

+    private void initialize() {

+        this.setSize(481, 404);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setContentPane(getJPanel());

+        this.setTitle("Package Uninstallation");

+        this.centerWindow();

+        pThis = this;

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     initialize table contents from db file

+     

+     @param f FrameworkDatabase.db file under workspace

+    **/

+    protected void loadDB(File f) {

+        if (!f.exists()) {

+            JOptionPane.showMessageDialog(frame,

+                                          "No FrameworkDatabase.db File!");

+            return;

+        }

+        dfc = new DbFileContents(f);

+        if (dfc.getPackageCount() == 0) {

+            return;

+        }

+        //

+        // Get package list info. and add them one by one into table

+        //

+        String[][] saa = new String[dfc.getPackageCount()][5];

+        dfc.getPackageList(saa);

+        int i = 0;

+        while (i < saa.length) {

+            model.addRow(saa[i]);

+            i++;

+        }

+ 

+    }

+    /**

+     save package info. from table to db file

+    **/

+    protected void save() {

+        dfc.removePackageList();

+        int rowCount = jTable.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            

+            dfc.genPackage(jTable.getValueAt(i, 0).toString(), jTable.getValueAt(i, 1).toString(),

+                           jTable.getValueAt(i, 2).toString(), jTable.getValueAt(i, 3).toString(),

+                           jTable.getValueAt(i, 4).toString());

+            i++;

+        }

+        dfc.saveAs();

+    }

+ 

+    private JPanel getJPanel() {

+        if (jPanel == null) {

+            jLabel1 = new JLabel();

+            jLabel1.setBounds(new java.awt.Rectangle(20, 83, 141, 16));

+            jLabel1.setText("  Packages Installed");

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(17, 16, 171, 16));

+            jLabel.setText(" Enter Workspace Location");

+            jPanel = new JPanel();

+            jPanel.setLayout(null);

+            jPanel.add(jLabel, null);

+            jPanel.add(getJTextField(), null);

+            jPanel.add(getJButton(), null);

+            jPanel.add(jLabel1, null);

+            jPanel.add(getJPanel1(), null);

+            jPanel.add(getJScrollPane(), null);

+        }

+        return jPanel;

+    }

+

+    /**

+      This method initializes jTextField	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setBounds(new java.awt.Rectangle(16, 41, 350, 20));

+            jTextField.setHorizontalAlignment(JTextField.LEFT);

+            jTextField.setEditable(false);

+            jTextField.setText(System.getenv("WORKSPACE"));

+            jTextField.setPreferredSize(new Dimension(350, 20));

+        }

+        return jTextField;

+    }

+

+    /**

+      This method initializes jButton	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(372,40,78,20));

+            jButton.setFont(new Font("Dialog", Font.BOLD, 12));

+            jButton.setPreferredSize(new Dimension(80, 20));

+            jButton.setToolTipText("Where is the package?");

+            jButton.setHorizontalAlignment(SwingConstants.LEFT);

+            jButton.setHorizontalTextPosition(SwingConstants.CENTER);

+            jButton.setText("Browse");

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    //

+                    // user can select another workspace directory

+                    //

+                    JFileChooser chooser = new JFileChooser();

+                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

+                    chooser.setMultiSelectionEnabled(false);

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        //

+                        // update table when user selects a new workspace directory

+                        //

+                        jTextField.setText(chooser.getSelectedFile().getPath());

+                        File f = new File(chooser.getSelectedFile(), FrameworkPkg.dbConfigFile);

+                        loadDB(f);

+                    }

+                }

+            });

+        }

+        return jButton;

+    }

+

+    /**

+      This method initializes jPanel1	

+      	

+      @return javax.swing.JPanel	

+     **/

+    private JPanel getJPanel1() {

+        if (jPanel1 == null) {

+            FlowLayout flowLayout = new FlowLayout();

+            flowLayout.setAlignment(java.awt.FlowLayout.LEFT);

+            flowLayout.setHgap(20);

+            jPanel1 = new JPanel();

+            jPanel1.setLayout(flowLayout);

+            jPanel1.setBounds(new java.awt.Rectangle(133,310,318,53));

+            jPanel1.add(getJButton3(), null);

+            jPanel1.add(getJButton1(), null);

+            jPanel1.add(getJButton2(), null);

+        }

+        return jPanel1;

+    }

+

+    /**

+      This method initializes jButton1	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setPreferredSize(new java.awt.Dimension(85, 20));

+            jButton1.setText("Ok");

+            jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);

+            jButton1.setEnabled(true);

+            jButton1.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (dfc != null) {

+                        //

+                        // save package info. to file before exit

+                        //

+                        save();

+                    }

+                    pThis.dispose();

+                }

+            });

+        }

+        return jButton1;

+    }

+

+    /**

+      This method initializes jButton2	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setPreferredSize(new java.awt.Dimension(85, 20));

+            jButton2.setText("Cancel");

+            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    pThis.dispose();

+                }

+            });

+        }

+        return jButton2;

+    }

+

+    /**

+      This method initializes jScrollPane	

+      	

+      @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(20,108,431,194));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+      This method initializes jTable	

+      	

+      @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new PkgRemoveTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            jTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);

+            jTable.setRowSelectionAllowed(true);

+            model.addColumn("PackageName");

+            model.addColumn("Version");

+            model.addColumn("GUID");

+            model.addColumn("Path");

+            model.addColumn("InstallDate");

+            File f = new File(jTextField.getText(), FrameworkPkg.dbConfigFile);

+            loadDB(f);

+        }

+        return jTable;

+    }

+

+    /**

+      This method initializes jButton3	

+      	

+      @return javax.swing.JButton	

+    **/

+    private JButton getJButton3() {

+        if (jButton3 == null) {

+            jButton3 = new JButton();

+            jButton3.setText("Remove");

+            jButton3.setPreferredSize(new java.awt.Dimension(85,20));

+            jButton3.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (model != null){

+                        int index = jTable.getSelectedRow();

+                        if (index > -1) {

+                            model.removeRow(index);

+                        }

+                    }

+                }

+            });

+        }

+        return jButton3;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="10,10"

+

+/**

+ Derived table model which disables table edit

+  

+ @since PackageEditor 1.0

+**/

+class PkgRemoveTableModel extends DefaultTableModel {

+    PkgRemoveTableModel() {

+        super();

+    }

+    

+    public boolean isCellEditable (int row, int col) {

+        return false;

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuidEditor.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuidEditor.java
new file mode 100644
index 0000000..cac74df
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/GuidEditor.java
@@ -0,0 +1,93 @@
+/** @file

+ Java class GuidEditor.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+ 

+**/

+package org.tianocore.packaging;

+

+import java.awt.Component;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.swing.AbstractCellEditor;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+import javax.swing.JOptionPane;

+import javax.swing.JTable;

+import javax.swing.table.TableCellEditor;

+

+import org.tianocore.common.Tools;

+

+/**

+ Editor for table cell with GUID value.

+ @since PackageEditor 1.0

+ **/

+public class GuidEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {

+

+    String currentGuid;

+    JButton button;

+    static JFrame frame;

+    GenGuidDialog dialog;

+    protected static final String EDIT = "edit";

+

+    public GuidEditor() {

+        

+        button = new JButton();

+        button.setActionCommand(EDIT);

+        button.addActionListener(this);

+        button.setBorderPainted(false);

+

+        

+        dialog = new GenGuidDialog(this);

+        

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int)

+     */

+    public Component getTableCellEditorComponent(JTable arg0, Object arg1, boolean arg2, int arg3, int arg4) {

+        // TODO Auto-generated method stub

+        currentGuid = (String)arg1;

+        return button;

+    }

+

+    /* (non-Javadoc)

+     * @see javax.swing.CellEditor#getCellEditorValue()

+     */

+    public Object getCellEditorValue() {

+        // TODO Auto-generated method stub

+        return currentGuid;

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        // TODO Auto-generated method stub

+        if (EDIT.equals(arg0.getActionCommand())) {

+            //The user has clicked the cell, so

+            //bring up the dialog.

+            button.setText(currentGuid);

+            dialog.setGuid(currentGuid);

+            dialog.setVisible(true);

+

+            //Make the renderer reappear.

+            fireEditingStopped();

+        }

+        else { //User pressed dialog's "OK" button.

+            currentGuid = dialog.getGuid();

+//            button.setText(currentGuid);

+//            fireEditingStopped();

+        }

+

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ManifestContents.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ManifestContents.java
new file mode 100644
index 0000000..7bebc62
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ManifestContents.java
@@ -0,0 +1,74 @@
+/** @file

+  Java class ManifestContents is used to deal with FDPManifest.xml file related

+  operations.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import org.apache.xmlbeans.XmlException;

+

+import org.tianocore.*;

+import java.io.*;

+

+/**

+ This class operates on FDPManifest.xml file

+  

+ @since PackageEditor 1.0

+**/

+public class ManifestContents {

+

+    ///

+    /// it is more convenient to get input stream from Jar entry of to-be-installed package file.

+    /// so i use InputStream instead of File

+    ///

+    private InputStream manIs = null;

+

+    FrameworkDevPkgManifestDocument manDoc = null;

+

+    HeaderDocument hdr = null;

+

+    FrameworkDevPkgManifestDocument.FrameworkDevPkgManifest manRoot = null;

+

+    public ManifestContents(InputStream fis) throws XmlException, IOException {

+

+        manIs = fis;

+        manDoc = FrameworkDevPkgManifestDocument.Factory.parse(manIs);

+        manRoot = manDoc.getFrameworkDevPkgManifest();

+

+    }

+

+    /**

+     Get package name from manifest file header.

+     

+     @return String

+    **/

+    public String getBaseName() {

+        return manRoot.getHeader().getPackageName().getStringValue();

+    }

+

+    /**

+     Get package version from manifest file header.

+     

+     @return String

+    **/

+    public String getVersion() {

+        return manRoot.getHeader().getVersion();

+    }

+

+    /**

+     Get package GUID from manifest file header.

+     

+     @return String

+    **/

+    public String getGuid() {

+        return manRoot.getHeader().getGuid().getStringValue();

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ModalFrameUtil.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ModalFrameUtil.java
new file mode 100644
index 0000000..a748a82
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/ModalFrameUtil.java
@@ -0,0 +1,107 @@
+/** @file

+  Java class ModalFrameUtil is used to show modal frame.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.*;

+import java.awt.*;

+import java.awt.event.WindowAdapter;

+import java.awt.event.WindowEvent;

+import java.lang.reflect.InvocationHandler;

+import java.lang.reflect.Method;

+import java.lang.reflect.Proxy;

+

+/**

+ This class is used to show modal frame.

+  

+ @since PackageEditor 1.0

+**/

+public class ModalFrameUtil {

+    /**

+     Invocation handler for event threads

+      

+     @since PackageEditor 1.0

+    **/

+    static class EventPump implements InvocationHandler {

+        Frame frame;

+

+        public EventPump(Frame frame) {

+            this.frame = frame;

+        }

+

+        /**

+         Invocation handler invoked by Method.invoke

+         **/

+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

+            //

+            // return frame showing status for Conditional.evaluate()

+            //

+            return frame.isShowing() ? Boolean.TRUE : Boolean.FALSE;

+        }

+

+        public void start() throws Exception {

+            Class clazz = Class.forName("java.awt.Conditional");

+            //

+            // Conditional proxy instance will invoke "this" InvocationHandler.invoke when calling its methods

+            //

+            Object conditional = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, this);

+            //

+            // EventDisaptchThread.pumpEvents will be called under Conditional "conditional"

+            //

+            Method pumpMethod = Class.forName("java.awt.EventDispatchThread").getDeclaredMethod("pumpEvents",

+                                                                                                new Class[] { clazz });

+            pumpMethod.setAccessible(true);

+            //

+            // pumpEvents when conditional.evaluate() == true (frame.isShowing() in EventPump.invoke)

+            //

+            pumpMethod.invoke(Thread.currentThread(), new Object[] { conditional });

+        }

+    }

+

+    /**

+     Show modal frame, return only when frame closed.

+     

+     @param frame Frame to be modal

+     @param owner Parent Frame

+    **/

+    public static void showAsModal(final Frame frame, final Frame owner) {

+        frame.addWindowListener(new WindowAdapter() {

+            public void windowOpened(WindowEvent e) {

+                owner.setEnabled(false);

+            }

+

+            public void windowClosed(WindowEvent e) {

+                owner.setEnabled(true);

+                owner.setVisible(true);

+                owner.removeWindowListener(this);

+            }

+        });

+

+        owner.addWindowListener(new WindowAdapter() {

+            public void windowActivated(WindowEvent e) {

+                if (frame.isShowing()) {

+                    frame.setExtendedState(JFrame.NORMAL);

+                    frame.toFront();

+                } else {

+                    owner.removeWindowListener(this);

+                }

+            }

+        });

+

+        frame.setVisible(true);

+        try {

+            new EventPump(frame).start();

+        } catch (Throwable throwable) {

+            throw new RuntimeException(throwable);

+        }

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageAction.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageAction.java
new file mode 100644
index 0000000..03e1607
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageAction.java
@@ -0,0 +1,352 @@
+/** @file

+  Java class PackageAction is GUI for create spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+

+import javax.swing.JFileChooser;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import java.awt.GridLayout;

+import java.io.File;

+

+import javax.swing.JButton;

+import javax.swing.filechooser.FileFilter;

+

+/**

+ GUI for create spd file

+  

+ @since PackageEditor 1.0

+**/

+public class PackageAction extends JFrame {

+

+    static JFrame frame;

+

+    private JPanel jContentPane = null;

+

+    private JButton jButton = null;

+

+    private JButton jButton1 = null;

+

+    private JButton jButton2 = null;

+

+    private JButton jButton3 = null;

+

+    private JButton jButton4 = null;

+

+    private JButton jButton5 = null;

+

+    private JButton jButton6 = null;

+

+    private JButton jButton7 = null;

+

+    ///

+    /// SpdFileContents object passed from main

+    ///

+    private SpdFileContents sfc = null;

+

+    private JFrame pThis = null;  //  @jve:decl-index=0:visual-constraint="304,10"

+

+    private JButton jButton8 = null;

+

+    private JButton jButton9 = null;  //  @jve:decl-index=0:visual-constraint="116,388"

+

+    /**

+      This is the default constructor

+     **/

+    public PackageAction(SpdFileContents sfc) {

+        super();

+        initialize();

+        this.sfc = sfc;

+    }

+

+    /**

+      This method initializes this

+      

+      @return void

+     **/

+    private void initialize() {

+        this.setSize(305, 385);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Please Choose an Action");

+        this.centerWindow();

+        this.pThis = this;

+     

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+      This method initializes jContentPane

+      

+      @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            GridLayout gridLayout = new GridLayout();

+            gridLayout.setRows(10);

+            gridLayout.setColumns(1);

+            jContentPane = new JPanel();

+            jContentPane.setPreferredSize(new java.awt.Dimension(200,300));

+            jContentPane.setLayout(gridLayout);

+            jContentPane.add(getJButton8(), null);

+            jContentPane.add(getJButton7(), null);

+            jContentPane.add(getJButton6(), null);

+            jContentPane.add(getJButton5(), null);

+            jContentPane.add(getJButton4(), null);

+            jContentPane.add(getJButton3(), null);

+            jContentPane.add(getJButton2(), null);

+            jContentPane.add(getJButton1(), null);

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButton9(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+      This method initializes jButton	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        final FileFilter filter = new PkgFileFilter("spd");

+        

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setText("Save");

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    //

+                    // save sfc contents to file

+                    //

+                    JFileChooser chooser = new JFileChooser(PackagingMain.dirForNewSpd);

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileFilter(filter);

+

+                    int retval = chooser.showSaveDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        try {

+                            File theFile = chooser.getSelectedFile();

+                            if (theFile.exists()) {

+                                int retVal = JOptionPane.showConfirmDialog(frame, "Are you sure to replace the exising one?", "File Exists",

+                                                                           JOptionPane.YES_NO_OPTION);

+                                if (retVal == JOptionPane.NO_OPTION) {

+                                    return;

+                                } 

+                            }

+                            sfc.saveAs(theFile);

+

+                        } catch (Exception ee) {

+                            System.out.println(ee.toString());

+                        }

+//                        pThis.dispose();

+                    }

+

+                }

+            });

+        }

+        return jButton;

+    }

+

+    /**

+      This method initializes jButton1	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setText("Add PCD Information");

+            jButton1.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    //

+                    // Add PCD frame show modal

+                    //

+                    ModalFrameUtil.showAsModal(new PackagePCD(sfc), pThis);

+                }

+            });

+        }

+        return jButton1;

+    }

+

+    /**

+      This method initializes jButton2	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setText("Add PPI Declarations");

+            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    //

+                    // Add PPI frame show modal

+                    //

+                    ModalFrameUtil.showAsModal(new PackagePpi(sfc), pThis);

+                }

+            });

+        }

+        return jButton2;

+    }

+

+    /**

+      This method initializes jButton3	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton3() {

+        if (jButton3 == null) {

+            jButton3 = new JButton();

+            jButton3.setText("Add Protocol Declarations");

+            jButton3.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new PackageProtocols(sfc), pThis);

+                }

+            });

+        }

+        return jButton3;

+    }

+

+    /**

+      This method initializes jButton4	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton4() {

+        if (jButton4 == null) {

+            jButton4 = new JButton();

+            jButton4.setText("Add GUID Declarations");

+            jButton4.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new PackageGuids(sfc), pThis);

+                }

+            });

+        }

+        return jButton4;

+    }

+

+    /**

+      This method initializes jButton5	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton5() {

+        if (jButton5 == null) {

+            jButton5 = new JButton();

+            jButton5.setText("Add Package Headers");

+            jButton5.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new PackagePkgHeader(sfc), pThis);

+                }

+            });

+        }

+        return jButton5;

+    }

+

+    /**

+      This method initializes jButton6	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton6() {

+        if (jButton6 == null) {

+            jButton6 = new JButton();

+            jButton6.setText("Add MSA Files");

+            jButton6.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new PackageMsaFile(sfc), pThis);

+                }

+            });

+        }

+        return jButton6;

+    }

+

+    /**

+      This method initializes jButton7	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton7() {

+        if (jButton7 == null) {

+            jButton7 = new JButton();

+            jButton7.setText("Add Library Classes");

+            jButton7.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new PackageLibraryClass(sfc), pThis);

+                }

+            });

+        }

+        return jButton7;

+    }

+

+    /**

+      This method initializes jButton8	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton8() {

+        if (jButton8 == null) {

+            jButton8 = new JButton();

+            jButton8.setText("Add SPD Header");

+            jButton8.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new PackageNew(sfc), pThis);

+                }

+            });

+        }

+        return jButton8;

+    }

+

+    /**

+      This method initializes jButton9	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButton9() {

+        if (jButton9 == null) {

+            jButton9 = new JButton();

+            jButton9.setText("Done");

+            jButton9.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    //

+                    // quit current frame

+                    //

+                    pThis.dispose();

+                   

+                }

+            });

+        }

+        return jButton9;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="104,41"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageGuids.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageGuids.java
new file mode 100644
index 0000000..6562a27
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageGuids.java
@@ -0,0 +1,354 @@
+/** @file

+  Java class PackageGuids is GUI for create GUID elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.swing.DefaultListModel;

+import javax.swing.JPanel;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JRadioButton;

+import javax.swing.JComboBox;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+

+import javax.swing.JScrollPane;

+import javax.swing.JList;

+

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ GUI for create GUID elements of spd file

+  

+ @since PackageEditor 1.0

+**/

+public class PackageGuids extends JFrame implements ActionListener {

+

+    private SpdFileContents sfc = null;

+

+    private static String separator = "::";

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuidValue = null;

+

+    private JTextField jTextFieldGuidValue = null;

+

+    private JLabel jLabelHelpText = null;

+

+    private JTextField jTextFieldName = null;

+

+    private JLabel jLabelEnableFeature = null;

+

+    private JRadioButton jRadioButtonEnableFeature = null;

+

+    private JRadioButton jRadioButtonDisableFeature = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private StarLabel starLabel = null;

+

+    private StarLabel starLabel1 = null;

+

+    /**

+      This method initializes this

+      

+     **/

+    private void initialize() {

+        this.setTitle("Guid Declarations");

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+      This method initializes jTextFieldC_Name	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+      This method initializes jTextFieldGuidValsue	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldGuidValsue() {

+        if (jTextFieldGuidValue == null) {

+            jTextFieldGuidValue = new JTextField();

+            jTextFieldGuidValue.setBounds(new java.awt.Rectangle(160, 35, 240, 20));

+        }

+        return jTextFieldGuidValue;

+    }

+

+    /**

+      This method initializes jTextFieldName	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldName() {

+        if (jTextFieldName == null) {

+            jTextFieldName = new JTextField();

+            jTextFieldName.setBounds(new java.awt.Rectangle(160, 70, 320, 20));

+        }

+        return jTextFieldName;

+    }

+

+    /**

+      This method initializes jRadioButtonEnableFeature	

+      	

+      @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonEnableFeature() {

+        if (jRadioButtonEnableFeature == null) {

+            jRadioButtonEnableFeature = new JRadioButton();

+            jRadioButtonEnableFeature.setText("Enable");

+            jRadioButtonEnableFeature.setBounds(new java.awt.Rectangle(160, 104, 90, 20));

+            jRadioButtonEnableFeature.setEnabled(false);

+            jRadioButtonEnableFeature.setSelected(true);

+        }

+        return jRadioButtonEnableFeature;

+    }

+

+    /**

+      This method initializes jRadioButtonDisableFeature	

+      	

+      @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonDisableFeature() {

+        if (jRadioButtonDisableFeature == null) {

+            jRadioButtonDisableFeature = new JRadioButton();

+            jRadioButtonDisableFeature.setText("Disable");

+            jRadioButtonDisableFeature.setEnabled(false);

+            jRadioButtonDisableFeature.setBounds(new java.awt.Rectangle(250, 104, 90, 20));

+        }

+        return jRadioButtonDisableFeature;

+    }

+

+    /**

+      This method initializes jButtonOk	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(300, 240, 75, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+      This method initializes jButtonCancel	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 240, 74, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+      This method initializes jButtonGenerateGuid	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(405, 35, 75, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+      This is the default constructor

+     **/

+    public PackageGuids(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.setVisible(true);

+        this.sfc = sfc;

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+      This method initializes this

+      

+      @return void

+     **/

+    private void init() {

+        this.setSize(500, 300);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Add Guids");

+        this.centerWindow();

+        initFrame();

+    }

+

+    /**

+      This method initializes jContentPane

+      

+      @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            starLabel1 = new StarLabel();

+            starLabel1.setBounds(new java.awt.Rectangle(5, 34, 10, 20));

+            starLabel = new StarLabel();

+            starLabel.setBounds(new java.awt.Rectangle(6, 10, 10, 20));

+            jLabelEnableFeature = new JLabel();

+            jLabelEnableFeature.setText("Enable Feature");

+            jLabelEnableFeature.setEnabled(false);

+            jLabelEnableFeature.setBounds(new java.awt.Rectangle(15, 104, 140, 20));

+            jLabelHelpText = new JLabel();

+            jLabelHelpText.setText("Name");

+            jLabelHelpText.setBounds(new java.awt.Rectangle(15, 70, 140, 20));

+            jLabelGuidValue = new JLabel();

+            jLabelGuidValue.setText("Guid Value");

+            jLabelGuidValue.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(jLabelGuidValue, null);

+            jContentPane.add(getJTextFieldGuidValsue(), null);

+

+            jContentPane.add(jLabelHelpText, null);

+            jContentPane.add(getJTextFieldName(), null);

+            jContentPane.add(jLabelEnableFeature, null);

+            jContentPane.add(getJRadioButtonEnableFeature(), null);

+            jContentPane.add(getJRadioButtonDisableFeature(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+

+            jContentPane.add(starLabel, null);

+            jContentPane.add(starLabel1, null);

+

+            initFrame();

+

+        }

+        return jContentPane;

+    }

+

+    /**

+      This method initializes events groups and usage type

+      

+     **/

+    private void initFrame() {

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        //

+        // save and exit

+        //

+        if (arg0.getSource() == jButtonOk) {

+

+            this.save();

+            this.dispose();

+        }

+        //

+        // exit

+        //

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+        //

+        // generate a new GUID

+        //

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuidValue.setText(Tools.generateUuidString());

+        }

+        

+        if (arg0.getSource() == jRadioButtonEnableFeature) {

+            if (jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonDisableFeature) {

+            if (jRadioButtonDisableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(true);

+            }

+        }

+    }

+

+    /**

+     Add GUID entry to SpdFileContents object with element values from jTextFields*

+    **/

+    protected void save() {

+        try {

+            String strName = jTextFieldName.getText();

+            String strCName = jTextFieldC_Name.getText();

+            String strGuid = jTextFieldGuidValue.getText();

+            sfc.genSpdGuidDeclarations(strName, strCName, strGuid, null);

+

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+} //  @jve:decl-index=0:visual-constraint="10,10"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageLibraryClass.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageLibraryClass.java
new file mode 100644
index 0000000..bf8c70b
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageLibraryClass.java
@@ -0,0 +1,560 @@
+/** @file

+  Java class PackageLibraryClass is GUI for create library definition elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.File;

+import java.util.Vector;

+

+import javax.swing.DefaultListModel;

+import javax.swing.JFileChooser;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JList;

+import javax.swing.JScrollPane;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+

+/**

+ GUI for create library definition elements of spd file.

+  

+ @since PackageEditor 1.0

+**/

+public class PackageLibraryClass extends JFrame implements ActionListener {

+    static JFrame frame;

+    

+    private static String Separator = "::";

+

+    private DefaultListModel listItem = new DefaultListModel();

+

+    private SpdFileContents sfc = null;

+

+    private JPanel jContentPane = null;

+

+    private JRadioButton jRadioButtonAdd = null;

+

+    private JRadioButton jRadioButtonSelect = null;

+

+    private JTextField jTextFieldAdd = null;

+

+    private JComboBox jComboBoxSelect = null;

+

+    private JLabel jLabelUsage = null;

+

+    private JComboBox jComboBoxUsage = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JList jListLibraryClassDefinitions = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonRemove = null;

+

+    private JButton jButtonClearAll = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonOk = null;

+

+    private JLabel jLabel = null;

+

+    private JTextField jTextField = null;

+

+    private JButton jButtonBrowse = null;

+

+    /**

+      This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setTitle("Library Declarations");

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+      This method initializes jRadioButtonAdd	

+      	

+      @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonAdd() {

+        if (jRadioButtonAdd == null) {

+            jRadioButtonAdd = new JRadioButton();

+            jRadioButtonAdd.setBounds(new java.awt.Rectangle(10, 35, 205, 20));

+            jRadioButtonAdd.setText("Add a new Library Class");

+            jRadioButtonAdd.addActionListener(this);

+            jRadioButtonAdd.setSelected(false);

+        }

+        return jRadioButtonAdd;

+    }

+

+    /**

+      This method initializes jRadioButtonSelect	

+      	

+      @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonSelect() {

+        if (jRadioButtonSelect == null) {

+            jRadioButtonSelect = new JRadioButton();

+            jRadioButtonSelect.setBounds(new java.awt.Rectangle(10, 10, 205, 20));

+            jRadioButtonSelect.setText("Select Existing Library Class");

+            jRadioButtonSelect.addActionListener(this);

+            jRadioButtonSelect.setSelected(true);

+        }

+        return jRadioButtonSelect;

+    }

+

+    /**

+      This method initializes jTextFieldAdd	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldAdd() {

+        if (jTextFieldAdd == null) {

+            jTextFieldAdd = new JTextField();

+            jTextFieldAdd.setBounds(new java.awt.Rectangle(220, 35, 260, 20));

+            jTextFieldAdd.setEnabled(false);

+        }

+        return jTextFieldAdd;

+    }

+

+    /**

+      This method initializes jComboBoxSelect	

+      	

+      @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxSelect() {

+        if (jComboBoxSelect == null) {

+            jComboBoxSelect = new JComboBox();

+            jComboBoxSelect.setBounds(new java.awt.Rectangle(220, 10, 260, 20));

+            jComboBoxSelect.setEnabled(true);

+        }

+        return jComboBoxSelect;

+    }

+

+    /**

+      This method initializes jComboBoxUsage	

+      	

+      @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxUsage() {

+        if (jComboBoxUsage == null) {

+            jComboBoxUsage = new JComboBox();

+            jComboBoxUsage.setBounds(new java.awt.Rectangle(220, 60, 260, 20));

+            jComboBoxUsage.setEnabled(false);

+        }

+        return jComboBoxUsage;

+    }

+

+    /**

+      This method initializes jScrollPane	

+      	

+      @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(10,149,350,146));

+            jScrollPane.setViewportView(getJListLibraryClassDefinitions());

+        }

+        return jScrollPane;

+    }

+

+    /**

+      This method initializes jListLibraryClassDefinitions	

+      	

+      @return javax.swing.JList	

+     **/

+    private JList getJListLibraryClassDefinitions() {

+        if (jListLibraryClassDefinitions == null) {

+            jListLibraryClassDefinitions = new JList(listItem);

+        }

+        return jListLibraryClassDefinitions;

+    }

+

+    /**

+      This method initializes jButtonAdd	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(375,152,90,20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+      This method initializes jButtonRemove	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(375, 230, 90, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+      This method initializes jButtonRemoveAll	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonClearAll() {

+        if (jButtonClearAll == null) {

+            jButtonClearAll = new JButton();

+            jButtonClearAll.setBounds(new java.awt.Rectangle(375, 260, 90, 20));

+            jButtonClearAll.setText("Clear All");

+            jButtonClearAll.addActionListener(this);

+        }

+        return jButtonClearAll;

+    }

+

+    /**

+      This method initializes jButtonCancel	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setPreferredSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.setLocation(new java.awt.Point(390, 305));

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+      This method initializes jButton	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setSize(new java.awt.Dimension(90, 20));

+            jButtonOk.setText("OK");

+            jButtonOk.setLocation(new java.awt.Point(290, 305));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+      This is the default constructor

+     **/

+    public PackageLibraryClass(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.sfc = sfc;

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+      This method initializes this

+      

+      @return void

+     **/

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Library Class Declarations");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 370));

+        this.centerWindow();

+        initFrame();

+    }

+

+    /**

+      This method initializes jContentPane

+      

+      @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(14, 85, 201, 22));

+            jLabel.setText("Include Header for Selected Class");

+            jLabelUsage = new JLabel();

+            jLabelUsage.setBounds(new java.awt.Rectangle(15, 60, 200, 20));

+            jLabelUsage.setEnabled(false);

+            jLabelUsage.setText("Usage");

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJRadioButtonAdd(), null);

+            jContentPane.add(getJRadioButtonSelect(), null);

+            jContentPane.add(getJTextFieldAdd(), null);

+            jContentPane.add(getJComboBoxSelect(), null);

+            jContentPane.add(jLabelUsage, null);

+            jContentPane.add(getJComboBoxUsage(), null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(getJButtonClearAll(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJTextField(), null);

+            jContentPane.add(getJButtonBrowse(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     fill ComboBoxes with pre-defined contents

+    **/

+    private void initFrame() {

+        jComboBoxSelect.addItem("BaseCpuICacheFlush");

+        jComboBoxSelect.addItem("BaseDebugLibNull");

+        jComboBoxSelect.addItem("BaseDebugLibReportStatusCode");

+        jComboBoxSelect.addItem("BaseIoLibIntrinsic");

+        jComboBoxSelect.addItem("BaseLib");

+        jComboBoxSelect.addItem("BaseMemoryLib");

+        jComboBoxSelect.addItem("BaseMemoryLibMmx");

+        jComboBoxSelect.addItem("BaseMemoryLibSse2");

+        jComboBoxSelect.addItem("BasePeCoffGetEntryPointLib");

+        jComboBoxSelect.addItem("BasePeCoffLib");

+        jComboBoxSelect.addItem("BasePrintLib");

+        jComboBoxSelect.addItem("BaseReportStatusCodeLibNull");

+        jComboBoxSelect.addItem("CommonPciCf8Lib");

+        jComboBoxSelect.addItem("CommonPciExpressLib");

+        jComboBoxSelect.addItem("CommonPciLibCf8");

+        jComboBoxSelect.addItem("CommonPciLibPciExpress");

+        jComboBoxSelect.addItem("DxeCoreEntryPoint");

+        jComboBoxSelect.addItem("DxeHobLib");

+        jComboBoxSelect.addItem("DxeIoLibCpuIo");

+        jComboBoxSelect.addItem("DxeLib");

+        jComboBoxSelect.addItem("DxePcdLib");

+        jComboBoxSelect.addItem("DxeReportStatusCodeLib");

+        jComboBoxSelect.addItem("DxeServicesTableLib");

+        jComboBoxSelect.addItem("PeiCoreEntryPoint");

+        jComboBoxSelect.addItem("PeiMemoryLib");

+        jComboBoxSelect.addItem("PeimEntryPoint");

+        jComboBoxSelect.addItem("PeiReportStatusCodeLib");

+        jComboBoxSelect.addItem("PeiServicesTablePointerLib");

+        jComboBoxSelect.addItem("PeiServicesTablePointerLibMm7");

+        jComboBoxSelect.addItem("UefiDebugLibConOut");

+        jComboBoxSelect.addItem("UefiDebugLibStdErr");

+        jComboBoxSelect.addItem("UefiDriverEntryPointMultiple");

+        jComboBoxSelect.addItem("UefiDriverEntryPointSingle");

+        jComboBoxSelect.addItem("UefiDriverEntryPointSingleUnload");

+        jComboBoxSelect.addItem("UefiDriverModelLib");

+        jComboBoxSelect.addItem("UefiDriverModelLibNoConfigNoDiag");

+        jComboBoxSelect.addItem("UefiLib");

+        jComboBoxSelect.addItem("UefiMemoryLib");

+

+        jComboBoxUsage.addItem("ALWAYS_CONSUMED");

+        jComboBoxUsage.addItem("SOMETIMES_CONSUMED");

+        jComboBoxUsage.addItem("ALWAYS_PRODUCED");

+        jComboBoxUsage.addItem("SOMETIMES_PRODUCED");

+        jComboBoxUsage.addItem("DEFAULT");

+        jComboBoxUsage.addItem("PRIVATE");

+    }

+

+    /* (non-Javadoc)

+     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)

+     */

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonAdd) {

+            String strLibClass = "";

+            if (jRadioButtonAdd.isSelected()) {

+                strLibClass = jTextFieldAdd.getText();

+            }

+            if (jRadioButtonSelect.isSelected()) {

+                strLibClass = jComboBoxSelect.getSelectedItem().toString();

+            }

+            listItem.addElement(jTextField.getText().replace('\\', '/') + this.Separator + strLibClass);

+        }

+        //

+        // remove selected line

+        //

+        if (arg0.getSource() == jButtonRemove) {

+            int intSelected[] = jListLibraryClassDefinitions.getSelectedIndices();

+            if (intSelected.length > 0) {

+                for (int index = intSelected.length - 1; index > -1; index--) {

+                    listItem.removeElementAt(intSelected[index]);

+                }

+            }

+            jListLibraryClassDefinitions.getSelectionModel().clearSelection();

+        }

+

+        if (arg0.getSource() == jButtonClearAll) {

+            listItem.removeAllElements();

+        }

+

+        if (arg0.getSource() == jRadioButtonAdd) {

+            if (jRadioButtonAdd.isSelected()) {

+                jRadioButtonSelect.setSelected(false);

+                jTextFieldAdd.setEnabled(true);

+                jComboBoxSelect.setEnabled(false);

+            }

+            if (!jRadioButtonSelect.isSelected() && !jRadioButtonAdd.isSelected()) {

+                jRadioButtonAdd.setSelected(true);

+                jTextFieldAdd.setEnabled(true);

+                jComboBoxSelect.setEnabled(false);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonSelect) {

+            if (jRadioButtonSelect.isSelected()) {

+                jRadioButtonAdd.setSelected(false);

+                jTextFieldAdd.setEnabled(false);

+                jComboBoxSelect.setEnabled(true);

+            }

+            if (!jRadioButtonSelect.isSelected() && !jRadioButtonAdd.isSelected()) {

+                jRadioButtonSelect.setSelected(true);

+                jTextFieldAdd.setEnabled(false);

+                jComboBoxSelect.setEnabled(true);

+            }

+        }

+    }

+

+    /**

+     Add contents in list to sfc

+    **/

+    protected void save() {

+        try {

+            int intLibraryCount = listItem.getSize();

+

+            if (intLibraryCount > 0) {

+

+                for (int index = 0; index < intLibraryCount; index++) {

+                    String strAll = listItem.get(index).toString();

+                    String strInclude = strAll.substring(0, strAll.indexOf(Separator));

+                    String strLibraryClass = strAll.substring(strAll.indexOf(Separator) + Separator.length());

+                    sfc.genSpdLibClassDeclarations(strLibraryClass, null, strInclude, null, null, null, null, null,

+                                                   null, null);

+                }

+            } else {

+

+            }

+

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+

+    /**

+      This method initializes jTextField	

+      	

+      @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setBounds(new java.awt.Rectangle(12,112,346,21));

+        }

+        return jTextField;

+    }

+

+    /**

+      This method initializes jButtonBrowse	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonBrowse() {

+        if (jButtonBrowse == null) {

+            jButtonBrowse = new JButton();

+            jButtonBrowse.setBounds(new java.awt.Rectangle(374,111,92,21));

+            jButtonBrowse.setText("Browse");

+            jButtonBrowse.setPreferredSize(new java.awt.Dimension(34,20));

+            jButtonBrowse.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    //

+                    // Select files from current workspace

+                    //

+                    JFileChooser chooser = new JFileChooser(System.getenv("WORKSPACE"));

+                    File theFile = null;

+                    String headerDest = null;

+                    

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+

+                        theFile = chooser.getSelectedFile();

+                        String file = theFile.getPath();

+                        if (!file.startsWith(System.getenv("WORKSPACE"))) {

+                            JOptionPane.showMessageDialog(frame, "You can only select files in current workspace!");

+                            return;

+                        }

+                        

+                        

+                    }

+                    else {

+                        return;

+                    }

+                    

+                    if (!theFile.getPath().startsWith(PackagingMain.dirForNewSpd)) {

+                        //

+                        //ToDo: copy elsewhere header file to new pkg dir, prompt user to chooser a location

+                        //

+                        JOptionPane.showMessageDialog(frame, "You must copy header file into current package directory!");

+                        return;

+                    }

+                    

+                    headerDest = theFile.getPath();

+                    int fileIndex = headerDest.indexOf(System.getProperty("file.separator"), PackagingMain.dirForNewSpd.length());

+                    

+                    jTextField.setText(headerDest.substring(fileIndex + 1).replace('\\', '/'));

+                        

+                }

+            });

+        }

+        return jButtonBrowse;

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageMsaFile.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageMsaFile.java
new file mode 100644
index 0000000..824c372
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageMsaFile.java
@@ -0,0 +1,371 @@
+/** @file

+  Java class PackageMsaFile is GUI for create MsaFile elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.File;

+import java.util.Vector;

+

+import javax.swing.DefaultListModel;

+import javax.swing.JFileChooser;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JList;

+import javax.swing.JScrollPane;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+import javax.swing.filechooser.FileFilter;

+

+/**

+ GUI for create MsaFile elements of spd file

+  

+ @since PackageEditor 1.0

+**/

+public class PackageMsaFile extends JFrame implements ActionListener {

+    static JFrame frame;

+    

+    private DefaultListModel listItem = new DefaultListModel();

+

+    private SpdFileContents sfc = null;

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JList jListLibraryClassDefinitions = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonRemove = null;

+

+    private JButton jButtonClearAll = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonOk = null;

+

+    private JLabel jLabel = null;

+

+    private JTextField jTextField = null;

+

+    private JButton jButton = null;

+

+    /**

+      This method initializes this

+      

+     **/

+    private void initialize() {

+        this.setTitle("MSA Files");

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+      This method initializes jScrollPane	

+      	

+      @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(10, 85, 350, 210));

+            jScrollPane.setViewportView(getJListLibraryClassDefinitions());

+        }

+        return jScrollPane;

+    }

+

+    /**

+      This method initializes jListLibraryClassDefinitions	

+      	

+      @return javax.swing.JList	

+     **/

+    private JList getJListLibraryClassDefinitions() {

+        if (jListLibraryClassDefinitions == null) {

+            jListLibraryClassDefinitions = new JList(listItem);

+        }

+        return jListLibraryClassDefinitions;

+    }

+

+    /**

+      This method initializes jButtonAdd	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(375, 132, 90, 20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+      This method initializes jButtonRemove	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(375, 230, 90, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+      This method initializes jButtonRemoveAll	

+      	

+      @return javax.swing.JButton	

+     **/

+    private JButton getJButtonClearAll() {

+        if (jButtonClearAll == null) {

+            jButtonClearAll = new JButton();

+            jButtonClearAll.setBounds(new java.awt.Rectangle(375, 260, 90, 20));

+            jButtonClearAll.setText("Clear All");

+            jButtonClearAll.addActionListener(this);

+        }

+        return jButtonClearAll;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setPreferredSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.setLocation(new java.awt.Point(390, 305));

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setSize(new java.awt.Dimension(90, 20));

+            jButtonOk.setText("OK");

+            jButtonOk.setLocation(new java.awt.Point(290, 305));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This is the default constructor

+     **/

+    public PackageMsaFile(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.sfc = sfc;

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     */

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Library Class Declarations");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 370));

+        this.centerWindow();

+        initFrame();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(11,20,143,22));

+            jLabel.setText("Msa File Path and Name");

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(getJButtonClearAll(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJTextField(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    private void initFrame() {

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.dispose();

+            this.save();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonAdd) {

+

+            listItem.addElement(jTextField.getText());

+        }

+

+        if (arg0.getSource() == jButtonRemove) {

+            int intSelected[] = jListLibraryClassDefinitions.getSelectedIndices();

+            if (intSelected.length > 0) {

+                for (int index = intSelected.length - 1; index > -1; index--) {

+                    listItem.removeElementAt(intSelected[index]);

+                }

+            }

+            jListLibraryClassDefinitions.getSelectionModel().clearSelection();

+        }

+

+        if (arg0.getSource() == jButtonClearAll) {

+            listItem.removeAllElements();

+        }

+

+    }

+

+    protected void save() {

+        try {

+            int intLibraryCount = listItem.getSize();

+

+            if (intLibraryCount > 0) {

+

+                for (int index = 0; index < intLibraryCount; index++) {

+                    String strAll = listItem.get(index).toString();

+                    sfc.genSpdMsaFiles(strAll, null);

+                }

+            } else {

+

+            }

+

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+

+    /**

+     This method initializes jTextField	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setBounds(new java.awt.Rectangle(11,44,349,21));

+        }

+        return jTextField;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        final FileFilter filter = new PkgFileFilter("msa");

+        

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(377,46,89,20));

+            jButton.setText("Browse");

+            jButton.setPreferredSize(new java.awt.Dimension(34,20));

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    JFileChooser chooser = new JFileChooser(System.getenv("WORKSPACE"));

+                    File theFile = null;

+                    String msaDest = null;

+                    

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

+                    chooser.setFileFilter(filter);

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+

+                        theFile = chooser.getSelectedFile();

+                        String file = theFile.getPath();

+                        if (!file.startsWith(System.getenv("WORKSPACE"))) {

+                            JOptionPane.showMessageDialog(frame, "You can only select files in current workspace!");

+                            return;

+                        }

+                        

+                    }

+                    else {

+                        return;

+                    }

+                    

+                    if (!theFile.getPath().startsWith(PackagingMain.dirForNewSpd)) {

+                        //

+                        //ToDo: copy elsewhere msa to new pkg dir, prompt user to chooser a location

+                        //

+                        JOptionPane.showMessageDialog(frame, "You must copy msa file into current package directory!");

+                        return;

+                    }

+                    

+                    msaDest = theFile.getPath();

+                    int fileIndex = msaDest.indexOf(System.getProperty("file.separator"), PackagingMain.dirForNewSpd.length());

+                    

+                    jTextField.setText(msaDest.substring(fileIndex + 1).replace('\\', '/'));

+                }

+            });

+        }

+        return jButton;

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageNew.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageNew.java
new file mode 100644
index 0000000..85676a4
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageNew.java
@@ -0,0 +1,533 @@
+/** @file

+  Java class PackageNew is the top level GUI for create spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.text.SimpleDateFormat;

+import java.util.Date;

+

+import javax.swing.JFrame;

+import javax.swing.JPanel;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+import javax.swing.JTextArea;

+import javax.swing.JScrollPane;

+import javax.swing.JComboBox;

+

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ This class contains GUI components to show various GUIs for creating spd file elements

+  

+ @since PackageEditor 1.0

+**/

+public class PackageNew extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null; //  @jve:decl-index=0:visual-constraint="128,4"

+

+    private JLabel jLabelBaseName = null;

+

+    private JTextField jTextFieldBaseName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelLicense = null;

+

+    private JTextArea jTextAreaLicense = null;

+

+    private JLabel jLabelCopyright = null;

+

+    private JTextArea jTextAreaCopyright = null;

+

+    private JLabel jLabelDescription = null;

+

+    private JTextArea jTextAreaDescription = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JScrollPane jScrollPaneLicense = null;

+

+    private JScrollPane jScrollPaneDescription = null;

+

+    private JLabel jLabelAbstract = null;

+

+    private JTextField jTextFieldAbstract = null;

+

+    private JLabel jLabelModuleType = null;

+

+    private JLabel jLabelCompontentType = null;

+

+    private JComboBox jComboBox1 = null;

+

+    private JComboBox jComboBoxModuleType = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+

+    private StarLabel jStarLabel5 = null;

+

+    private StarLabel jStarLabel6 = null;

+

+    private StarLabel jStarLabel7 = null;

+

+    private StarLabel jStarLabel8 = null;

+

+    private JLabel jLabelURL = null;

+

+    private JTextField jTextFieldAbstractURL = null;

+

+    private JLabel jLabel = null;

+

+    private JComboBox jComboBox = null;

+

+    private SpdFileContents sfc = null;

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+     This method initializes jTextFieldBaseName	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldBaseName() {

+        if (jTextFieldBaseName == null) {

+            jTextFieldBaseName = new JTextField();

+            jTextFieldBaseName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldBaseName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 240, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldVersion	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(405, 35, 75, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextAreaLicense	

+     	

+     @return javax.swing.JTextArea	

+     **/

+    private JTextArea getJTextAreaLicense() {

+        if (jTextAreaLicense == null) {

+            jTextAreaLicense = new JTextArea();

+            jTextAreaLicense.setText("");

+            jTextAreaLicense.setLineWrap(true);

+        }

+        return jTextAreaLicense;

+    }

+

+    /**

+     This method initializes jTextAreaCopyright	

+     	

+     @return javax.swing.JTextArea	

+     **/

+    private JTextArea getJTextAreaCopyright() {

+        if (jTextAreaCopyright == null) {

+            jTextAreaCopyright = new JTextArea();

+            jTextAreaCopyright.setLineWrap(true);

+            jTextAreaCopyright.setBounds(new java.awt.Rectangle(160,172,319,20));

+        }

+        return jTextAreaCopyright;

+    }

+

+    /**

+     This method initializes jTextAreaDescription	

+     	

+     @return javax.swing.JTextArea	

+     **/

+    private JTextArea getJTextAreaDescription() {

+        if (jTextAreaDescription == null) {

+            jTextAreaDescription = new JTextArea();

+            jTextAreaDescription.setLineWrap(true);

+        }

+        return jTextAreaDescription;

+    }

+

+    /**

+     This method initializes jButtonNext	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 481, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 481, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPaneLicense() {

+        if (jScrollPaneLicense == null) {

+            jScrollPaneLicense = new JScrollPane();

+            jScrollPaneLicense.setBounds(new java.awt.Rectangle(160, 85, 320, 80));

+            jScrollPaneLicense.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneLicense.setViewportView(getJTextAreaLicense());

+        }

+        return jScrollPaneLicense;

+    }

+

+    /**

+     This method initializes jScrollPane2	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPaneDescription() {

+        if (jScrollPaneDescription == null) {

+            jScrollPaneDescription = new JScrollPane();

+            jScrollPaneDescription.setBounds(new java.awt.Rectangle(160, 322, 320, 80));

+            jScrollPaneDescription.setViewportView(getJTextAreaDescription());

+            jScrollPaneDescription.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+        }

+        return jScrollPaneDescription;

+    }

+

+    /**

+     This method initializes jTextFieldAbstract	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldAbstract() {

+        if (jTextFieldAbstract == null) {

+            jTextFieldAbstract = new JTextField();

+            jTextFieldAbstract.setBounds(new java.awt.Rectangle(159,218,318,70));

+        }

+        return jTextFieldAbstract;

+    }

+

+    /**

+     This method initializes jComboBoxCompontentType	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBox1() {

+        if (jComboBox1 == null) {

+            jComboBox1 = new JComboBox();

+            jComboBox1.setBounds(new java.awt.Rectangle(160, 465, 91, 20));

+        }

+        return jComboBox1;

+    }

+

+    /**

+     This method initializes jComboBoxModuleType	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxModuleType() {

+        if (jComboBoxModuleType == null) {

+            jComboBoxModuleType = new JComboBox();

+            jComboBoxModuleType.setBounds(new java.awt.Rectangle(160, 440, 91, 20));

+        }

+        return jComboBoxModuleType;

+    }

+

+    /**

+     This method initializes jTextFieldAbstractURL	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldAbstractURL() {

+        if (jTextFieldAbstractURL == null) {

+            jTextFieldAbstractURL = new JTextField();

+            jTextFieldAbstractURL.setBounds(new java.awt.Rectangle(159, 414, 320, 20));

+        }

+        return jTextFieldAbstractURL;

+    }

+

+    public PackageNew(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.setVisible(true);

+        this.sfc = sfc;

+

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setSize(500, 560);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setContentPane(getJContentPane());

+        this.setTitle("SPD File Header");

+        this.centerWindow();

+        //this.getRootPane().setDefaultButton(jButtonOk);

+        initFrame();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(15, 490, 140, 21));

+            jLabel.setText("Re-Package");

+            jLabelURL = new JLabel();

+            jLabelURL.setBounds(new java.awt.Rectangle(16, 414, 25, 20));

+            jLabelURL.setText("URL");

+            jLabelCompontentType = new JLabel();

+            jLabelCompontentType.setBounds(new java.awt.Rectangle(15, 465, 140, 20));

+            jLabelCompontentType.setText("Read Only");

+            jLabelModuleType = new JLabel();

+            jLabelModuleType.setBounds(new java.awt.Rectangle(15, 440, 140, 20));

+            jLabelModuleType.setText("Package Type");

+            jLabelAbstract = new JLabel();

+            jLabelAbstract.setBounds(new java.awt.Rectangle(15,218,140,20));

+            jLabelAbstract.setText("Abstract");

+            jLabelDescription = new JLabel();

+            jLabelDescription.setText("Description");

+            jLabelDescription.setBounds(new java.awt.Rectangle(16, 325, 140, 20));

+            jLabelCopyright = new JLabel();

+            jLabelCopyright.setText("Copyright");

+            jLabelCopyright.setBounds(new java.awt.Rectangle(15, 171, 140, 20));

+            jLabelLicense = new JLabel();

+            jLabelLicense.setText("License");

+            jLabelLicense.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelVersion = new JLabel();

+            jLabelVersion.setText("Version");

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setPreferredSize(new java.awt.Dimension(25, 15));

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelBaseName = new JLabel();

+            jLabelBaseName.setText("Package Name");

+            jLabelBaseName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setLocation(new java.awt.Point(0, 0));

+            jContentPane.setSize(new java.awt.Dimension(500, 524));

+            jContentPane.add(jLabelBaseName, null);

+            jContentPane.add(getJTextFieldBaseName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelLicense, null);

+            jContentPane.add(jLabelCopyright, null);

+            jContentPane.add(jLabelDescription, null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPaneLicense(), null);

+            jContentPane.add(getJScrollPaneDescription(), null);

+            jContentPane.add(jLabelAbstract, null);

+            jContentPane.add(getJTextFieldAbstract(), null);

+            jContentPane.add(jLabelModuleType, null);

+            jContentPane.add(jLabelCompontentType, null);

+            jContentPane.add(getJComboBox1(), null);

+            jContentPane.add(getJComboBoxModuleType(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 85));

+            jStarLabel5 = new StarLabel();

+            jStarLabel5.setLocation(new java.awt.Point(0, 171));

+            jStarLabel6 = new StarLabel();

+            jStarLabel6.setLocation(new java.awt.Point(1, 325));

+            jStarLabel7 = new StarLabel();

+            jStarLabel7.setLocation(new java.awt.Point(0,218));

+            jStarLabel8 = new StarLabel();

+            jStarLabel8.setLocation(new java.awt.Point(0, 440));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+            jContentPane.add(jStarLabel5, null);

+            jContentPane.add(jStarLabel6, null);

+            jContentPane.add(jStarLabel7, null);

+            jContentPane.add(jStarLabel8, null);

+            jContentPane.add(jLabelURL, null);

+            jContentPane.add(getJTextFieldAbstractURL(), null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJComboBox(), null);

+            jContentPane.add(getJTextAreaCopyright(), null);

+        }

+        return jContentPane;

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Save all components of Msa Header

+     if exist, set the value directly

+     if not exist, new instance first

+     

+     **/

+    private void save() {

+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+        Date date = new Date();

+        sfc.genSpdHeader(jTextFieldBaseName.getText(), jTextFieldGuid.getText(), jTextFieldVersion.getText(),

+                         jTextFieldAbstract.getText(), jTextAreaDescription.getText(), jTextAreaCopyright.getText(),

+                         jTextAreaLicense.getText(), format.format(date), format.format(date),

+                         jTextFieldAbstractURL.getText(), jComboBoxModuleType.getSelectedItem().toString(),

+                         jComboBox1.getSelectedItem().toString(), jComboBox.getSelectedItem().toString(), null, null);

+    }

+

+    /**

+     This method initializes module type and compontent type

+     

+     **/

+    private void initFrame() {

+        jComboBoxModuleType.addItem("SOURCE");

+        jComboBoxModuleType.addItem("BINARY");

+        jComboBoxModuleType.addItem("MIXED");

+

+        jComboBox1.addItem("true");

+        jComboBox1.addItem("false");

+

+        jComboBox.addItem("false");

+        jComboBox.addItem("true");

+

+    }

+

+    /**

+     This method initializes jComboBox	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBox() {

+        if (jComboBox == null) {

+            jComboBox = new JComboBox();

+            jComboBox.setBounds(new java.awt.Rectangle(160, 490, 90, 20));

+        }

+        return jComboBox;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="38,-22"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePCD.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePCD.java
new file mode 100644
index 0000000..910540c
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePCD.java
@@ -0,0 +1,321 @@
+/** @file

+  Java class PackagePCD is GUI for create PCD definition elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.swing.ButtonGroup;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JComboBox;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ GUI for create PCD definition elements of spd file

+  

+ @since PackageEditor 1.0

+**/

+public class PackagePCD extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelItemType = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JComboBox jComboBoxItemType = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelToken = null;

+

+    private JTextField jTextFieldToken = null;

+

+    private JLabel jLabelDataType = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JComboBox jComboBoxDataType = null;

+

+    private JLabel jLabelOverrideID = null;

+

+    private JTextField jTextFieldOverrideID = null;

+

+    private ButtonGroup bg1 = null;

+

+    private ButtonGroup bg2 = null;

+

+    private ButtonGroup bg3 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private SpdFileContents sfc = null;

+

+    private StarLabel jStarLabel = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setTitle("PCD Definition");

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+     This method initializes jComboBoxItemType	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxItemType() {

+        if (jComboBoxItemType == null) {

+            jComboBoxItemType = new JComboBox();

+            jComboBoxItemType.setBounds(new java.awt.Rectangle(160, 110, 320, 20));

+        }

+        return jComboBoxItemType;

+    }

+

+    /**

+     This method initializes jTextFieldC_Name	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldC_Name() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldToken	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldToken() {

+        if (jTextFieldToken == null) {

+            jTextFieldToken = new JTextField();

+            jTextFieldToken.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+        }

+        return jTextFieldToken;

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(279,247,90,20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(389,247,90,20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jComboBoxDataType	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxDataType() {

+        if (jComboBoxDataType == null) {

+            jComboBoxDataType = new JComboBox();

+            jComboBoxDataType.setBounds(new java.awt.Rectangle(160, 160, 320, 20));

+        }

+        return jComboBoxDataType;

+    }

+

+    /**

+     This method initializes jTextFieldOverrideID	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldOverrideID() {

+        if (jTextFieldOverrideID == null) {

+            jTextFieldOverrideID = new JTextField();

+            jTextFieldOverrideID.setBounds(new java.awt.Rectangle(159,198,320,20));

+        }

+        return jTextFieldOverrideID;

+    }

+

+    /**

+     This is the default constructor

+     **/

+    public PackagePCD(SpdFileContents sfc) {

+        super();

+        init();

+        initialize();

+        this.sfc = sfc;

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setSize(500, 450);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Add PCDs");

+        this.centerWindow();

+        this.getRootPane().setDefaultButton(jButtonOk);

+        initFrame();

+        this.setVisible(true);

+    }

+

+    /**

+     Start the window at the center of screen

+     *

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     *

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabelOverrideID = new JLabel();

+            jLabelOverrideID.setBounds(new java.awt.Rectangle(14,197,140,20));

+            jLabelOverrideID.setText("Default Value");

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelDataType = new JLabel();

+            jLabelDataType.setText("Data Type");

+            jLabelDataType.setBounds(new java.awt.Rectangle(15, 160, 140, 20));

+            jLabelToken = new JLabel();

+            jLabelToken.setText("Token");

+            jLabelToken.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelItemType = new JLabel();

+            jLabelItemType.setText("Item Type");

+            jLabelItemType.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            bg1 = new ButtonGroup();

+            bg2 = new ButtonGroup();

+            bg3 = new ButtonGroup();

+            //bg1.add(getJRadioButtonPCData());

+            //bg2.add(getJRadioButtonPcdBuildData());

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            //jContentPane.add(bg1);

+            jContentPane.add(jLabelItemType, null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldC_Name(), null);

+            jContentPane.add(jLabelToken, null);

+            jContentPane.add(getJTextFieldToken(), null);

+            jContentPane.add(jLabelDataType, null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJComboBoxItemType(), null);

+            jContentPane.add(getJComboBoxDataType(), null);

+            jContentPane.add(jLabelOverrideID, null);

+            jContentPane.add(getJTextFieldOverrideID(), null);

+

+            jStarLabel = new StarLabel();

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setBounds(new java.awt.Rectangle(6, 59, 10, 20));

+            jStarLabel2 = new StarLabel();

+            jStarLabel3 = new StarLabel();

+            jStarLabel.setLocation(new java.awt.Point(6, 110));

+            jStarLabel.setLocation(new java.awt.Point(5, 85));

+            jStarLabel2.setLocation(new java.awt.Point(5, 134));

+            jStarLabel3.setLocation(new java.awt.Point(5, 159));

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel, null);

+            jContentPane.add(jStarLabel1, null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes comboboxes			

+     

+     **/

+    private void initFrame() {

+

+        jComboBoxItemType.addItem("FEATURE_FLAG");

+        jComboBoxItemType.addItem("FIXED_AT_BUILD");

+        jComboBoxItemType.addItem("PATCHABLE_IN_MODULE");

+        jComboBoxItemType.addItem("DYNAMIC");

+        jComboBoxItemType.addItem("DYNAMIC_EX");

+

+        jComboBoxDataType.addItem("UINT8");

+        jComboBoxDataType.addItem("UINT16");

+        jComboBoxDataType.addItem("UINT32");

+        jComboBoxDataType.addItem("UINT64");

+        jComboBoxDataType.addItem("VOID*");

+        jComboBoxDataType.addItem("BOOLEAN");

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+        

+

+    }

+

+    protected void save() {

+        

+        sfc.genSpdPcdDefinitions(jComboBoxItemType.getSelectedItem().toString(), jTextFieldC_Name.getText(),

+                                 jTextFieldToken.getText(), jComboBoxDataType.getSelectedItem().toString(), null,

+                                 null, null, null, null, null, jTextFieldOverrideID.getText());

+    }

+} //  @jve:decl-index=0:visual-constraint="22,11"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePkgHeader.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePkgHeader.java
new file mode 100644
index 0000000..8d0eb7d
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePkgHeader.java
@@ -0,0 +1,454 @@
+/** @file

+  Java class PackagePkgHeader is GUI for create Package header elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.util.Vector;

+

+import javax.swing.DefaultListModel;

+import javax.swing.JPanel;

+import javax.swing.JRadioButton;

+import javax.swing.JTextField;

+import javax.swing.JComboBox;

+import javax.swing.JLabel;

+import javax.swing.JList;

+import javax.swing.JScrollPane;

+import javax.swing.JButton;

+import javax.swing.JFrame;

+

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ GUI for create Package header elements of spd file

+  

+ @since PackageEditor 1.0

+**/

+public class PackagePkgHeader extends JFrame implements ActionListener {

+    private static String Separator = "::";

+

+    private DefaultListModel listItem = new DefaultListModel();

+

+    private SpdFileContents sfc = null;

+

+    private JPanel jContentPane = null;

+

+    private JRadioButton jRadioButtonAdd = null;

+

+    private JRadioButton jRadioButtonSelect = null;

+

+    private JTextField jTextFieldAdd = null;

+

+    private JComboBox jComboBoxSelect = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JList jListLibraryClassDefinitions = null;

+

+    private JButton jButtonAdd = null;

+

+    private JButton jButtonRemove = null;

+

+    private JButton jButtonClearAll = null;

+

+    private JButton jButtonCancel = null;

+

+    private JButton jButtonOk = null;

+

+    private JLabel jLabel = null;

+

+    private JTextField jTextField = null;

+

+    private StarLabel starLabel = null;

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setTitle("Package Headers");

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+     This method initializes jRadioButtonAdd	

+     	

+     @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonAdd() {

+        if (jRadioButtonAdd == null) {

+            jRadioButtonAdd = new JRadioButton();

+            jRadioButtonAdd.setBounds(new java.awt.Rectangle(10, 35, 205, 20));

+            jRadioButtonAdd.setText("Add a new Module Type");

+            jRadioButtonAdd.setEnabled(false);

+            jRadioButtonAdd.addActionListener(this);

+            jRadioButtonAdd.setSelected(false);

+        }

+        return jRadioButtonAdd;

+    }

+

+    /**

+     This method initializes jRadioButtonSelect	

+     	

+     @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonSelect() {

+        if (jRadioButtonSelect == null) {

+            jRadioButtonSelect = new JRadioButton();

+            jRadioButtonSelect.setBounds(new java.awt.Rectangle(10, 10, 205, 20));

+            jRadioButtonSelect.setText("Select an existed Module Type");

+            jRadioButtonSelect.setActionCommand("Select an existed Module Type");

+            jRadioButtonSelect.addActionListener(this);

+            jRadioButtonSelect.setSelected(true);

+        }

+        return jRadioButtonSelect;

+    }

+

+    /**

+     This method initializes jTextFieldAdd	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldAdd() {

+        if (jTextFieldAdd == null) {

+            jTextFieldAdd = new JTextField();

+            jTextFieldAdd.setBounds(new java.awt.Rectangle(220, 35, 260, 20));

+            jTextFieldAdd.setEditable(false);

+            jTextFieldAdd.setEnabled(false);

+        }

+        return jTextFieldAdd;

+    }

+

+    /**

+     This method initializes jComboBoxSelect	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxSelect() {

+        if (jComboBoxSelect == null) {

+            jComboBoxSelect = new JComboBox();

+            jComboBoxSelect.setBounds(new java.awt.Rectangle(220, 10, 260, 20));

+            jComboBoxSelect.setEnabled(true);

+        }

+        return jComboBoxSelect;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(10, 121, 350, 174));

+            jScrollPane.setViewportView(getJListLibraryClassDefinitions());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jListLibraryClassDefinitions	

+     	

+     @return javax.swing.JList	

+     **/

+    private JList getJListLibraryClassDefinitions() {

+        if (jListLibraryClassDefinitions == null) {

+            jListLibraryClassDefinitions = new JList(listItem);

+        }

+        return jListLibraryClassDefinitions;

+    }

+

+    /**

+     This method initializes jButtonAdd	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonAdd() {

+        if (jButtonAdd == null) {

+            jButtonAdd = new JButton();

+            jButtonAdd.setBounds(new java.awt.Rectangle(375, 132, 90, 20));

+            jButtonAdd.setText("Add");

+            jButtonAdd.addActionListener(this);

+        }

+        return jButtonAdd;

+    }

+

+    /**

+     This method initializes jButtonRemove	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonRemove() {

+        if (jButtonRemove == null) {

+            jButtonRemove = new JButton();

+            jButtonRemove.setBounds(new java.awt.Rectangle(375, 230, 90, 20));

+            jButtonRemove.setText("Remove");

+            jButtonRemove.addActionListener(this);

+        }

+        return jButtonRemove;

+    }

+

+    /**

+     This method initializes jButtonRemoveAll	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonClearAll() {

+        if (jButtonClearAll == null) {

+            jButtonClearAll = new JButton();

+            jButtonClearAll.setBounds(new java.awt.Rectangle(375, 260, 90, 20));

+            jButtonClearAll.setText("Clear All");

+            jButtonClearAll.addActionListener(this);

+        }

+        return jButtonClearAll;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setPreferredSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.setLocation(new java.awt.Point(390, 305));

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setSize(new java.awt.Dimension(90, 20));

+            jButtonOk.setText("OK");

+            jButtonOk.setLocation(new java.awt.Point(290, 305));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This is the default constructor

+     **/

+    public PackagePkgHeader(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.sfc = sfc;

+    }

+

+    /**

+     Start the window at the center of screen

+     *

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     *

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    //	private void init(LibraryClassDefinitionsDocument.LibraryClassDefinitions inLibraryClassDefinitions) {

+    //		init();

+    //		this.setLibraryClassDefinitions(inLibraryClassDefinitions);

+    //		int intLibraryCount = this.libraryClassDefinitions.getLibraryClassArray().length;

+    //		if (intLibraryCount > 0) {

+    //			for (int index = 0; index < intLibraryCount; index++) {

+    //				listItem.addElement(this.libraryClassDefinitions.getLibraryClassArray(index).getUsage().toString() + 

+    //									this.Separator + 

+    //									this.libraryClassDefinitions.getLibraryClassArray(index).getStringValue());

+    //				this.libraryClassDefinitions.getLibraryClassArray();

+    //			}

+    //		}

+    //	}

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setContentPane(getJContentPane());

+        this.setTitle("Library Class Declarations");

+        this.setBounds(new java.awt.Rectangle(0, 0, 500, 370));

+        this.centerWindow();

+        initFrame();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            starLabel = new StarLabel();

+            starLabel.setBounds(new java.awt.Rectangle(5, 85, 10, 20));

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(14, 85, 201, 22));

+            jLabel.setText("Include Header for Selected Type");

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJRadioButtonAdd(), null);

+            jContentPane.add(getJRadioButtonSelect(), null);

+            jContentPane.add(getJTextFieldAdd(), null);

+            jContentPane.add(getJComboBoxSelect(), null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonAdd(), null);

+            jContentPane.add(getJButtonRemove(), null);

+            jContentPane.add(getJButtonClearAll(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJTextField(), null);

+            jContentPane.add(starLabel, null);

+        }

+        return jContentPane;

+    }

+

+    private void initFrame() {

+        jComboBoxSelect.addItem("BASE");

+        jComboBoxSelect.addItem("SEC");

+        jComboBoxSelect.addItem("PEI_CORE");

+        jComboBoxSelect.addItem("PEIM");

+        jComboBoxSelect.addItem("DXE_CORE");

+        jComboBoxSelect.addItem("DXE_DRIVER");

+        jComboBoxSelect.addItem("DXE_RUNTIME_DRIVER");

+        jComboBoxSelect.addItem("DXE_SAL_DRIVER");

+        jComboBoxSelect.addItem("DXE_SMM_DRIVER");

+        jComboBoxSelect.addItem("TOOLS");

+        jComboBoxSelect.addItem("UEFI_DRIVER");

+        jComboBoxSelect.addItem("UEFI_APPLICATION");

+        jComboBoxSelect.addItem("USER_DEFINED");

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jButtonAdd) {

+            String strLibClass = "";

+

+            if (jRadioButtonAdd.isSelected()) {

+                strLibClass = jTextFieldAdd.getText();

+            }

+            if (jRadioButtonSelect.isSelected()) {

+                strLibClass = jComboBoxSelect.getSelectedItem().toString();

+            }

+

+            listItem.addElement(jTextField.getText().replace('\\', '/') + Separator + strLibClass);

+        }

+

+        if (arg0.getSource() == jButtonRemove) {

+            int intSelected[] = jListLibraryClassDefinitions.getSelectedIndices();

+            if (intSelected.length > 0) {

+                for (int index = intSelected.length - 1; index > -1; index--) {

+                    listItem.removeElementAt(intSelected[index]);

+                }

+            }

+            jListLibraryClassDefinitions.getSelectionModel().clearSelection();

+        }

+

+        if (arg0.getSource() == jButtonClearAll) {

+            listItem.removeAllElements();

+        }

+

+        if (arg0.getSource() == jRadioButtonAdd) {

+            if (jRadioButtonAdd.isSelected()) {

+                jRadioButtonSelect.setSelected(false);

+                jTextFieldAdd.setEnabled(true);

+                jComboBoxSelect.setEnabled(false);

+            }

+            if (!jRadioButtonSelect.isSelected() && !jRadioButtonAdd.isSelected()) {

+                jRadioButtonAdd.setSelected(true);

+                jTextFieldAdd.setEnabled(true);

+                jComboBoxSelect.setEnabled(false);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonSelect) {

+            if (jRadioButtonSelect.isSelected()) {

+                jRadioButtonAdd.setSelected(false);

+                jTextFieldAdd.setEnabled(false);

+                jComboBoxSelect.setEnabled(true);

+            }

+            if (!jRadioButtonSelect.isSelected() && !jRadioButtonAdd.isSelected()) {

+                jRadioButtonSelect.setSelected(true);

+                jTextFieldAdd.setEnabled(false);

+                jComboBoxSelect.setEnabled(true);

+            }

+        }

+    }

+

+    private void save() {

+        try {

+            int intLibraryCount = listItem.getSize();

+

+            if (intLibraryCount > 0) {

+

+                for (int index = 0; index < intLibraryCount; index++) {

+                    String strAll = listItem.get(index).toString();

+                    String strInclude = strAll.substring(0, strAll.indexOf(Separator));

+                    String strType = strAll.substring(strAll.indexOf(Separator) + Separator.length());

+                    sfc.genSpdModuleHeaders(strType, strInclude, null, null, null, null, null, null);

+                }

+            } else {

+

+            }

+

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+

+    /**

+     This method initializes jTextField	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setBounds(new java.awt.Rectangle(221, 86, 257, 21));

+        }

+        return jTextField;

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePpi.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePpi.java
new file mode 100644
index 0000000..7b62d80
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagePpi.java
@@ -0,0 +1,41 @@
+/** @file

+  Java class PackagePpi is GUI for create Ppi definition elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+/**

+ GUI derived from PackageProtocols class, override save() method

+  

+ @since PackageEditor 1.0

+**/

+public class PackagePpi extends PackageProtocols {

+

+    private SpdFileContents sfc = null;

+

+    public PackagePpi(SpdFileContents sfc) {

+        super(sfc);

+        // TODO Auto-generated constructor stub

+        this.sfc = sfc;

+    }

+

+    /**

+      add ppi definitions from GUI to SpdFileContents object passed in.

+     **/

+    protected void save() {

+        try {

+            sfc.genSpdPpiDeclarations(getJTextField().getText(), getJTextFieldC_Name().getText(),

+                                      getJTextFieldGuid().getText(), null);

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageProtocols.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageProtocols.java
new file mode 100644
index 0000000..d99d18b
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackageProtocols.java
@@ -0,0 +1,377 @@
+/** @file

+  Java class PackageProtocols is GUI for create Protocol definition elements of spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+import javax.swing.JComboBox;

+import javax.swing.JRadioButton;

+import javax.swing.JFrame;

+

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ GUI for create Protocol definition elements of spd file.

+  

+ @since PackageEditor 1.0

+**/

+public class PackageProtocols extends JFrame implements ActionListener {

+

+    private int location = -1;

+

+    private SpdFileContents sfc = null;

+

+    private JPanel jContentPane = null;

+

+    private JLabel jLabelC_Name = null;

+

+    private JTextField jTextFieldC_Name = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelFeatureFlag = null;

+

+    private JTextField jTextFieldFeatureFlag = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JLabel jLabelEnableFeature = null;

+

+    private JRadioButton jRadioButtonEnableFeature = null;

+

+    private JRadioButton jRadioButtonDisableFeature = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel starLabel = null;

+

+    private JLabel jLabel = null;

+

+    private JTextField jTextField = null;

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+     This method initializes jTextFieldProtocolName	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldProtocolName() {

+        if (jTextFieldC_Name == null) {

+            jTextFieldC_Name = new JTextField();

+            jTextFieldC_Name.setBounds(new java.awt.Rectangle(160, 35, 320, 20));

+        }

+        return jTextFieldC_Name;

+    }

+

+    /**

+     This method initializes jTextFieldGuid	

+     	

+     @return javax.swing.JTextField	

+     **/

+    public JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 60, 240, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldFeatureFlag	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldFeatureFlag() {

+        if (jTextFieldFeatureFlag == null) {

+            jTextFieldFeatureFlag = new JTextField();

+            jTextFieldFeatureFlag.setBounds(new java.awt.Rectangle(160, 135, 320, 20));

+            jTextFieldFeatureFlag.setEnabled(false);

+        }

+        return jTextFieldFeatureFlag;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 190, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButton1	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 190, 90, 20));

+            jButtonCancel.setPreferredSize(new Dimension(90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jRadioButtonEnableFeature	

+     	

+     @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonEnableFeature() {

+        if (jRadioButtonEnableFeature == null) {

+            jRadioButtonEnableFeature = new JRadioButton();

+            jRadioButtonEnableFeature.setText("Enable");

+            jRadioButtonEnableFeature.setBounds(new java.awt.Rectangle(160, 110, 90, 20));

+            jRadioButtonEnableFeature.setEnabled(false);

+            jRadioButtonEnableFeature.addActionListener(this);

+            jRadioButtonEnableFeature.setSelected(true);

+        }

+        return jRadioButtonEnableFeature;

+    }

+

+    /**

+     This method initializes jRadioButtonDisableFeature	

+     	

+     @return javax.swing.JRadioButton	

+     **/

+    private JRadioButton getJRadioButtonDisableFeature() {

+        if (jRadioButtonDisableFeature == null) {

+            jRadioButtonDisableFeature = new JRadioButton();

+            jRadioButtonDisableFeature.setText("Disable");

+            jRadioButtonDisableFeature.setEnabled(false);

+            jRadioButtonDisableFeature.setBounds(new java.awt.Rectangle(320, 110, 90, 20));

+            jRadioButtonDisableFeature.addActionListener(this);

+        }

+        return jRadioButtonDisableFeature;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(405, 60, 75, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This is the default constructor

+     **/

+    public PackageProtocols(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.setVisible(true);

+        this.sfc = sfc;

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setSize(500, 250);

+        this.setName("JFrame");

+        this.setContentPane(getJContentPane());

+        this.setTitle("Add Protocols");

+        this.centerWindow();

+        //this.getRootPane().setDefaultButton(jButtonOk);

+        initFrame();

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(16, 10, 138, 16));

+            jLabel.setText("Name");

+            starLabel = new StarLabel();

+            starLabel.setBounds(new java.awt.Rectangle(0, 9, 10, 20));

+            jLabelEnableFeature = new JLabel();

+            jLabelEnableFeature.setText("Enable Feature");

+            jLabelEnableFeature.setEnabled(false);

+            jLabelEnableFeature.setBounds(new java.awt.Rectangle(15, 110, 140, 20));

+            jLabelFeatureFlag = new JLabel();

+            jLabelFeatureFlag.setText("Feature Flag");

+            jLabelFeatureFlag.setEnabled(false);

+            jLabelFeatureFlag.setBounds(new java.awt.Rectangle(15, 135, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setText("Guid");

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelC_Name = new JLabel();

+            jLabelC_Name.setText("C_Name");

+            jLabelC_Name.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(jLabelC_Name, null);

+            jContentPane.add(getJTextFieldProtocolName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelFeatureFlag, null);

+            jContentPane.add(getJTextFieldFeatureFlag(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(jLabelEnableFeature, null);

+            jContentPane.add(getJRadioButtonEnableFeature(), null);

+            jContentPane.add(getJRadioButtonDisableFeature(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setBounds(new java.awt.Rectangle(0, 35, 10, 20));

+

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(starLabel, null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJTextField(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes protocol usage type

+     

+     **/

+    private void initFrame() {

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+

+            this.save();

+            this.dispose();

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+        }

+

+        if (arg0.getSource() == jRadioButtonEnableFeature) {

+            if (jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jRadioButtonDisableFeature) {

+            if (jRadioButtonDisableFeature.isSelected()) {

+                jRadioButtonEnableFeature.setSelected(false);

+            }

+            if (!jRadioButtonDisableFeature.isSelected() && !jRadioButtonEnableFeature.isSelected()) {

+                jRadioButtonDisableFeature.setSelected(true);

+            }

+        }

+

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    protected void save() {

+        try {

+            sfc.genSpdProtocolDeclarations(jTextField.getText(), jTextFieldC_Name.getText(), jTextFieldGuid.getText(),

+                                           null);

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+

+    /**

+     This method initializes jTextField	

+     	

+     @return javax.swing.JTextField	

+     **/

+    public JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setBounds(new java.awt.Rectangle(160, 8, 319, 23));

+        }

+        return jTextField;

+    }

+

+    public JTextField getJTextFieldC_Name() {

+        return jTextFieldC_Name;

+    }

+

+    public void setJTextFieldC_Name(JTextField textFieldC_Name) {

+        jTextFieldC_Name = textFieldC_Name;

+    }

+

+    public void setJTextField(JTextField textField) {

+        jTextField = textField;

+    }

+

+    public void setJTextFieldGuid(JTextField textFieldGuid) {

+        jTextFieldGuid = textFieldGuid;

+    }

+} //  @jve:decl-index=0:visual-constraint="10,10"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagingMain.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagingMain.java
new file mode 100644
index 0000000..7d4654a
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PackagingMain.java
@@ -0,0 +1,330 @@
+/** @file

+  Java class PackagingMain is top level GUI for PackageEditor.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+

+import javax.swing.JFileChooser;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import java.awt.FlowLayout;

+import javax.swing.JButton;

+import java.awt.GridLayout;

+import java.io.File;

+import java.io.FileOutputStream;

+import java.util.jar.JarOutputStream;

+

+/**

+ GUI for show various GUI wizards for create, update spd file; install, remove package;

+ create distributable package file.

+  

+ @since PackageEditor 1.0

+**/

+public class PackagingMain extends JFrame {

+

+    static JFrame frame;

+

+    static String dirForNewSpd = null;

+

+    private JPanel jContentPane = null;

+

+    private JButton jButton = null;

+

+    private JButton jButton1 = null;

+

+    private JButton jButton2 = null;

+

+    private JButton jButton3 = null;

+

+    private JButton jButton4 = null;

+

+    private JButton jButton5 = null;

+

+    private JFrame pThis = null;

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setEnabled(true);

+            jButton.setText("Exit");

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    pThis.dispose();

+                }

+            });

+        }

+        return jButton;

+    }

+

+    /**

+     This method initializes jButton1	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setText("Create an Installable Package");

+            jButton1.setEnabled(true);

+            jButton1.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    File theFile = null;

+                    JFileChooser chooser = new JFileChooser();

+                    //

+                    // select the directory that contains files to be distribute

+                    //

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        try {

+                            theFile = chooser.getSelectedFile();

+                            //

+                            // find the FDPManifest.xml file that should exist 

+                            // in the root directory of package 

+                            //

+                            String[] list = theFile.list();

+                            boolean manifestExists = false;

+                            for (int i = 0; i < list.length; i++) {

+                                if (list[i].equals("FDPManifest.xml")) {

+                                    manifestExists = true;

+                                    break;

+                                }

+                            }

+                            if (!manifestExists) {

+                                JOptionPane.showMessageDialog(frame,

+                                                              "Please Put the FDPManifest.xml File under the Directory You Selected!");

+                                return;

+                            }

+                            //

+                            // create the distribute package .fdp file in the same directory with 

+                            // the package root directory selected above.

+                            //

+                            JarOutputStream jos = new JarOutputStream(new FileOutputStream(theFile.getPath() + ".fdp"));

+                            CreateFdp.create(theFile, jos, theFile.getPath());

+                            jos.close();

+                            JOptionPane.showMessageDialog(frame,

+                                                          "FDP File Created Successfully!");

+          

+                            

+                        } catch (Exception ee) {

+                            System.out.println(ee.toString());

+                        } 

+                    } else {

+                        return;

+                    }

+                }

+            });

+        }

+        return jButton1;

+    }

+

+    /**

+     This method initializes jButton2	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setText("Remove Package");

+            jButton2.setEnabled(true);

+            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new GuiPkgUninstall(), pThis);

+                }

+            });

+        }

+        return jButton2;

+    }

+

+    /**

+     This method initializes jButton3	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton3() {

+        if (jButton3 == null) {

+            jButton3 = new JButton();

+            jButton3.setText("Install Package");

+            jButton3.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new GuiPkgInstall(), pThis);

+                }

+            });

+        }

+        return jButton3;

+    }

+

+    /**

+     This method initializes jButton4	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton4() {

+        if (jButton4 == null) {

+            jButton4 = new JButton();

+            jButton4.setText("Update Package Description File");

+            jButton4.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    File theFile = null;

+                    JFileChooser chooser = new JFileChooser();

+                    //

+                    // select the spd file to be updated first

+                    //

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileFilter(new PkgFileFilter("spd"));

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        try {

+                            theFile = chooser.getSelectedFile();

+                            if (!theFile.isFile()) {

+                                JOptionPane.showMessageDialog(frame, "Please Select one Spd File!");

+                                return;

+                            }

+

+                        } catch (Exception ee) {

+                            System.out.println(ee.toString());

+                        }

+                    } else {

+                        return;

+                    }

+                    //

+                    // create a SpdFileContents for this file and pass it to GUI

+                    //

+                    SpdFileContents sfc = new SpdFileContents(theFile);

+                    ModalFrameUtil.showAsModal(new UpdateAction(sfc), pThis);

+                }

+            });

+        }

+        return jButton4;

+    }

+

+    /**

+     This method initializes jButton5	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton5() {

+        if (jButton5 == null) {

+            jButton5 = new JButton();

+            jButton5.setText("Create Package Description File");

+            jButton5.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    JFileChooser chooser = new JFileChooser(System.getenv("WORKSPACE"));

+                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setDialogTitle("Please specify where to save the new spd file");

+

+                    int retval = chooser.showSaveDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        try {

+                            File theFile = chooser.getSelectedFile();

+                            PackagingMain.dirForNewSpd = theFile.getPath();

+

+                        } catch (Exception ee) {

+                            System.out.println(ee.toString());

+                        }

+//                        pThis.dispose();

+                    }

+                    else {

+                        return;

+                    }

+                    SpdFileContents sfc = new SpdFileContents();

+                    ModalFrameUtil.showAsModal(new PackageAction(sfc), pThis);

+                }

+            });

+        }

+        return jButton5;

+    }

+

+    /**

+     Main for all package editor

+     

+     @param args

+     **/

+    public static void main(String[] args) {

+        // TODO Auto-generated method stub

+        new PackagingMain().setVisible(true);

+    }

+

+    /**

+     This is the default constructor

+     **/

+    public PackagingMain() {

+        super();

+        initialize();

+        pThis = this;

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(300, 357);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Packaging");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            GridLayout gridLayout = new GridLayout();

+            gridLayout.setRows(6);

+            gridLayout.setColumns(1);

+            jContentPane = new JPanel();

+            jContentPane.setLayout(gridLayout);

+            jContentPane.add(getJButton5(), null);

+            jContentPane.add(getJButton4(), null);

+            jContentPane.add(getJButton3(), null);

+            jContentPane.add(getJButton2(), null);

+            jContentPane.add(getJButton1(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="125,31"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PkgInstallTypeChooser.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PkgInstallTypeChooser.java
new file mode 100644
index 0000000..099c55a
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/PkgInstallTypeChooser.java
@@ -0,0 +1,373 @@
+/** @file

+  Java class PkgInstallTypeChooser is GUI for upgrade package installation.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.MouseEvent;

+import java.awt.event.MouseListener;

+import java.io.File;

+import java.util.List;

+import java.util.ListIterator;

+import java.util.Vector;

+

+import javax.swing.JFileChooser;

+import javax.swing.JFrame;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JDialog;

+import javax.swing.JRadioButton;

+import javax.swing.JButton;

+

+import org.tianocore.PackageListDocument;

+import javax.swing.JList;

+import javax.swing.JTextField;

+import javax.swing.JScrollPane;

+

+/**

+ GUI for speicial circumstances of package installation.

+  

+ @since PackageEditor 1.0

+**/

+public class PkgInstallTypeChooser extends JFrame implements MouseListener {

+

+    final static long serialVersionUID = 0;

+

+    static JFrame frame;

+

+    private JPanel jContentPane = null;

+

+    private JRadioButton jRadioButton = null;

+

+    private JRadioButton jRadioButton1 = null;

+

+    private JButton jButton = null;

+

+    private JButton jButton1 = null;

+

+    private String pn = null;

+

+    ///

+    /// list of package info from db file

+    ///

+    private List<PackageListDocument.PackageList.Package> dd = null;

+

+    private String wk = null;

+

+    private JList jList = null;

+    

+    private JScrollPane jScrollPane = null;

+

+    private JTextField jTextField = null;

+

+    private JButton jButton2 = null;

+

+    private JFileChooser chooser = null;

+

+    /**

+      This is the default constructor

+     **/

+    public PkgInstallTypeChooser(String pkgName, String wkSpace, List<PackageListDocument.PackageList.Package> destDir) {

+        super();

+        pn = pkgName;

+        dd = destDir;

+        wk = wkSpace;

+        initialize();

+    }

+

+    /**

+      This method initializes this

+      

+      @return void

+     **/

+    private void initialize() {

+        this.setSize(359, 328);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Chooser Installation Type");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+        this.insertList();

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+      Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     initialize jList with package info. from db file

+    **/

+    private void insertList() {

+

+        Vector<String> v = new Vector<String>();

+

+        ListIterator lpi = dd.listIterator();

+        while (lpi.hasNext()) {

+            PackageListDocument.PackageList.Package p = (PackageListDocument.PackageList.Package) lpi.next();

+            v.addElement(p.getPackageNameArray(0).getStringValue() + " " + p.getVersionArray(0) + " "

+                         + p.getGuidArray(0).getStringValue());

+        }

+        jList.setListData(v);

+    }

+

+    /**

+      This method initializes jContentPane

+      

+      @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJRadioButton(), null);

+            jContentPane.add(getJRadioButton1(), null);

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButton1(), null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJTextField(), null);

+            jContentPane.add(getJButton2(), null);

+        }

+        return jContentPane;

+    }

+

+ 

+    private JRadioButton getJRadioButton() {

+        if (jRadioButton == null) {

+            jRadioButton = new JRadioButton();

+            jRadioButton.setBounds(new java.awt.Rectangle(17, 39, 186, 21));

+            jRadioButton.setSelected(true);

+            jRadioButton.setText("Reinstall Existing Package");

+            jRadioButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (jRadioButton.isSelected()) {

+                        jRadioButton1.setSelected(false);

+                        jButton2.setEnabled(false);

+                        jTextField.setEnabled(false);

+                        jList.setEnabled(true);

+                        return;

+                    }

+                    if (jRadioButton1.isSelected()) {

+                        jRadioButton.setSelected(true);

+                        jRadioButton1.setSelected(false);

+                        jList.setEnabled(true);

+                        return;

+                    }

+

+                }

+            });

+        }

+        return jRadioButton;

+    }

+

+    private JRadioButton getJRadioButton1() {

+        if (jRadioButton1 == null) {

+            jRadioButton1 = new JRadioButton();

+            jRadioButton1.setBounds(new java.awt.Rectangle(17, 155, 176, 21));

+            jRadioButton1.setText("Install to Directory");

+            jRadioButton1.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (jRadioButton1.isSelected()) {

+                        jRadioButton.setSelected(false);

+                        jList.setEnabled(false);

+                        jButton2.setEnabled(true);

+                        jTextField.setEnabled(true);

+                        return;

+                    }

+                    if (jRadioButton.isSelected()) {

+                        jRadioButton1.setSelected(true);

+                        jRadioButton.setSelected(false);

+                        jButton2.setEnabled(true);

+                        jTextField.setEnabled(true);

+                        return;

+                    }

+                }

+            });

+        }

+        return jRadioButton1;

+    }

+

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setPreferredSize(new java.awt.Dimension(34, 20));

+            jButton.setSize(new java.awt.Dimension(76, 20));

+            jButton.setText("Ok");

+            jButton.setLocation(new java.awt.Point(141, 241));

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    try {

+                        int i = -1;

+                        //

+                        // user selects replace existing package

+                        //

+                        if (jRadioButton.isSelected()) {

+                            int j = jList.getSelectedIndex();

+                            if (j == -1) {

+                                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),

+                                                              "Please Select One Package to Replace!");

+                                return;

+                            }

+                            //

+                            // the sequence of jList is the same with List

+                            //

+                            String destDir = dd.get(j).getPathArray(0).getStringValue();

+                            ForceInstallPkg f = new ForceInstallPkg(pn, wk);

+                            //

+                            // record the package info. to be replaced

+                            //

+                            f.setOldVersion(dd.get(j).getVersionArray(0));

+                            f.setOldGuid(dd.get(j).getGuidArray(0).getStringValue());

+                            i = f.install(wk + System.getProperty("file.separator") + destDir);

+                        } else {

+                            //

+                            // user selects install to another directory

+                            //

+                            File f = new File(wk + System.getProperty("file.separator") + FrameworkPkg.dbConfigFile);

+                            if (new DbFileContents(f).checkDir(jTextField.getText().substring(wk.length() + 1)) != 0) {

+                                throw new DirSame();

+                            }

+                            i = new ForceInstallPkg(pn, wk).install(jTextField.getText());

+                        }

+                        if (i == 0) {

+                            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Package " + pn

+                                                                                      + " Installed Successfully!");

+                        }

+                    } catch (DirSame ds) {

+                        System.out.println(ds.toString());

+                        JOptionPane.showMessageDialog(frame,

+                                                      "Another Package Exists There, Please Select Another Directory!");

+                    } catch (Exception ee) {

+                        System.out.println(ee.toString());

+                    }

+                }

+            });

+        }

+        return jButton;

+    }

+

+    /**

+     * This method initializes jButton1	

+     * 	

+     * @return javax.swing.JButton	

+     */

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setBounds(new java.awt.Rectangle(238, 241, 78, 20));

+            jButton1.setText("Cancel");

+            jButton1.setPreferredSize(new java.awt.Dimension(34, 20));

+            jButton1.addMouseListener(this);

+        }

+        return jButton1;

+    }

+

+    public void mouseClicked(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+        this.dispose();

+    }

+

+    public void mouseEntered(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mouseExited(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mousePressed(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void mouseReleased(MouseEvent arg0) {

+        // TODO Auto-generated method stub

+

+    }

+

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(22, 68, 318, 58));

+            jScrollPane.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPane.setViewportView(getJList());

+        }

+        return jScrollPane;

+    }

+   

+    private JList getJList() {

+        if (jList == null) {

+            jList = new JList();

+            

+          jList.setBounds(new java.awt.Rectangle(22, 68, 318, 58));

+

+        }

+        return jList;

+    }

+

+    /**

+     * This method initializes jTextField	

+     * 	

+     * @return javax.swing.JTextField	

+     */

+    private JTextField getJTextField() {

+        if (jTextField == null) {

+            jTextField = new JTextField();

+            jTextField.setBounds(new java.awt.Rectangle(22, 184, 224, 20));

+            jTextField.setEnabled(false);

+            jTextField.setText(wk);

+        }

+        return jTextField;

+    }

+

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setLocation(new java.awt.Point(259, 183));

+            jButton2.setText("Browse");

+            jButton2.setEnabled(false);

+            jButton2.setSize(new java.awt.Dimension(81, 20));

+            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    if (chooser == null) {

+                        chooser = new JFileChooser(wk);

+                    }

+                    chooser.setMultiSelectionEnabled(false);

+                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

+

+                    int retval = chooser.showOpenDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        jTextField.setText(chooser.getSelectedFile().getPath());

+

+                    }

+

+                }

+            });

+        }

+        return jButton2;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="134,45"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/SpdFileContents.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/SpdFileContents.java
new file mode 100644
index 0000000..17a5a0c
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/SpdFileContents.java
@@ -0,0 +1,1287 @@
+/** @file

+  Java class SpdFileContents is used to parse spd xml file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.io.File;

+import java.io.IOException;

+import java.util.List;

+import java.util.ListIterator;

+

+import org.apache.xmlbeans.XmlObject;

+import org.apache.xmlbeans.XmlOptions;

+import org.apache.xmlbeans.XmlCursor;

+

+import org.tianocore.AbstractDocument;

+import org.tianocore.GuidDeclarationsDocument;

+import org.tianocore.GuidDocument;

+import org.tianocore.IncludeHeaderDocument;

+import org.tianocore.LibraryClassDeclarationDocument;

+import org.tianocore.LibraryClassDeclarationsDocument;

+import org.tianocore.LibraryClassDocument;

+import org.tianocore.LibraryUsage;

+import org.tianocore.LicenseDocument;

+import org.tianocore.ModuleTypeDef;

+import org.tianocore.MsaFilesDocument;

+import org.tianocore.OutputDirectoryDocument;

+import org.tianocore.PackageDependenciesDocument;

+import org.tianocore.PackageHeadersDocument;

+import org.tianocore.PackageNameDocument;

+import org.tianocore.PackageSurfaceAreaDocument;

+import org.tianocore.PackageType;

+import org.tianocore.PackageUsage;

+import org.tianocore.PcdDataTypes;

+import org.tianocore.PcdDefinitionsDocument;

+import org.tianocore.PcdItemTypes;

+import org.tianocore.PpiDeclarationsDocument;

+import org.tianocore.ProtocolDeclarationsDocument;

+import org.tianocore.SpdHeaderDocument;

+import org.tianocore.SpecificationDocument;

+import org.tianocore.GuidDeclarationsDocument.GuidDeclarations;

+

+/**

+ This class processes spd file contents such as add remove xml elements.

+  

+ @since PackageEditor 1.0

+**/

+public class SpdFileContents {

+

+    private File file = null;

+

+    private PackageSurfaceAreaDocument psad = null;

+

+    private PackageSurfaceAreaDocument.PackageSurfaceArea psaRoot = null;

+

+    private SpdHeaderDocument.SpdHeader spdHdr = null;

+

+    private PackageNameDocument.PackageName spdHdrPkgName = null;

+

+    private GuidDocument.Guid spdHdrGuid = null;

+

+    private AbstractDocument.Abstract spdHdrAbs = null;

+

+    private LicenseDocument.License spdHdrLicense = null;

+

+    private SpecificationDocument.Specification spdHdrSpec = null;

+

+    private OutputDirectoryDocument.OutputDirectory spdHdrOutDir = null;

+

+    private LibraryClassDeclarationsDocument.LibraryClassDeclarations spdLibClassDeclarations = null;

+

+    private PackageDependenciesDocument.PackageDependencies spdPkgDeps = null;

+

+    private MsaFilesDocument.MsaFiles spdMsaFiles = null;

+

+    private PackageHeadersDocument.PackageHeaders spdModHdrs = null;

+

+    private GuidDeclarationsDocument.GuidDeclarations spdGuidDeclarations = null;

+

+    private ProtocolDeclarationsDocument.ProtocolDeclarations spdProtocolDeclarations = null;

+

+    private PpiDeclarationsDocument.PpiDeclarations spdPpiDeclarations = null;

+

+    private PcdDefinitionsDocument.PcdDefinitions spdPcdDefinitions = null;

+

+    /**

+     Constructor to create a new spd file

+    **/

+    public SpdFileContents() {

+

+        psad = PackageSurfaceAreaDocument.Factory.newInstance();

+        psaRoot = psad.addNewPackageSurfaceArea();

+

+    }

+

+    /**

+     Constructor based on an existing spd file

+     

+     @param f Existing spd file

+    **/

+    public SpdFileContents(File f) {

+        try {

+            psad = PackageSurfaceAreaDocument.Factory.parse(f);

+            psaRoot = psad.getPackageSurfaceArea();

+            file = f;

+        } catch (Exception e) {

+            System.out.println(e.toString());

+        }

+    }

+

+    /**

+     Remove existing pcd definitions elements using XmlCursor

+    **/

+    public void removeSpdPcdDefinition() {

+        XmlObject o = psaRoot.getPcdDefinitions();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdPcdDefinitions = null;

+    }

+

+    /**

+     Remove existing ppi declarations using XmlCursor

+    **/

+    public void removeSpdPpiDeclaration() {

+        XmlObject o = psaRoot.getPpiDeclarations();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdPpiDeclarations = null;

+    }

+

+    /**

+     Remove existing protocols declarations using XmlCursor

+    **/

+    public void removeSpdProtocolDeclaration() {

+        XmlObject o = psaRoot.getProtocolDeclarations();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdProtocolDeclarations = null;

+    }

+

+    /**

+     Remove existing GUID declarations using XmlCursor

+    **/

+    public void removeSpdGuidDeclaration() {

+        XmlObject o = psaRoot.getGuidDeclarations();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdGuidDeclarations = null; 

+    }

+

+    /**

+     Remove existing spd package include files using XmlCursor

+    **/

+    public void removeSpdPkgHeader() {

+        XmlObject o = psaRoot.getPackageHeaders();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdModHdrs = null;

+    }

+

+    /**

+     Remove existing msa files using XmlCursor

+    **/

+    public void removeSpdMsaFile() {

+        XmlObject o = psaRoot.getMsaFiles();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdMsaFiles = null;

+    }

+

+    /**

+     Remove existing library class declarations using XmlCursor

+    **/

+    public void removeSpdLibClass() {

+        XmlObject o = psaRoot.getLibraryClassDeclarations();

+        if (o == null)

+            return;

+        XmlCursor cursor = o.newCursor();

+        cursor.removeXml();

+        spdLibClassDeclarations = null;

+    }

+

+    /**

+     Get spd file header contents into String array

+     

+     @param s Caller allocated String array

+    **/

+    public void getSpdHdrDetails(String[] s) {

+        if (getSpdHdr() == null) {

+            spdHdr = psaRoot.addNewSpdHeader();

+        }

+        s[0] = getSpdHdrPkgName().getStringValue();

+        s[1] = getSpdHdrGuid().getStringValue();

+        s[2] = getSpdHdrVer();

+        s[3] = getSpdHdrAbs().getStringValue();

+        s[4] = getSpdHdr().getDescription();

+        s[5] = getSpdHdr().getCopyright();

+        s[6] = getSpdHdrLicense().getStringValue();

+        s[7] = getSpdHdr().getCreated();

+        s[8] = getSpdHdr().getURL();

+        if (getSpdHdr().getPackageType() != null) {

+            s[9] = getSpdHdr().getPackageType().toString();

+        }

+        //

+        // convert boolean to String by adding empty String ""

+        //

+        s[10] = getSpdHdr().getReadOnly() + "";

+        s[11] = getSpdHdr().getReadOnly() + "";

+    }

+

+    /**

+     Get the number of library class declarations from the size of List

+     

+     @return int

+    **/

+    public int getSpdLibClassDeclarationCount() {

+        if (psaRoot.getLibraryClassDeclarations() == null

+            || psaRoot.getLibraryClassDeclarations().getLibraryClassDeclarationList() == null) {

+            return 0;

+        }

+        return psaRoot.getLibraryClassDeclarations().getLibraryClassDeclarationList().size();

+    }

+

+    /**

+     Get available library class declaration into String array

+     @param libClass Caller allocated two-dimentional String array

+    **/

+    public void getSpdLibClassDeclarations(String[][] libClass) {

+        List<LibraryClassDeclarationDocument.LibraryClassDeclaration> l = psaRoot.getLibraryClassDeclarations()

+                                                                                 .getLibraryClassDeclarationList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            LibraryClassDeclarationDocument.LibraryClassDeclaration lcd = (LibraryClassDeclarationDocument.LibraryClassDeclaration) li

+                                                                                                                                      .next();

+            if (lcd.getLibraryClass() != null) {

+                libClass[i][0] = lcd.getLibraryClass().getStringValue();

+            }

+            if (lcd.getIncludeHeader() != null) {

+                libClass[i][1] = lcd.getIncludeHeader().getStringValue();

+            }

+

+            i++;

+        }

+

+    }

+    

+    /**

+    Get the number of Msa files from the size of List

+    

+    @return int

+   **/

+    public int getSpdMsaFileCount() {

+        if (psaRoot.getMsaFiles() == null || psaRoot.getMsaFiles().getMsaFileList() == null) {

+            return 0;

+        }

+        return psaRoot.getMsaFiles().getMsaFileList().size();

+    }

+    

+    /**

+    Get available Msa file into String array

+    

+    @param msaFile Caller allocated two-dimentional String array

+   **/

+    public void getSpdMsaFiles(String[][] msaFile) {

+        List<MsaFilesDocument.MsaFiles.MsaFile> l = psaRoot.getMsaFiles().getMsaFileList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            MsaFilesDocument.MsaFiles.MsaFile m = (MsaFilesDocument.MsaFiles.MsaFile) li.next();

+            if (m.getFilename() != null) {

+                msaFile[i][0] = m.getFilename().getStringValue();

+            }

+

+            i++;

+        }

+    }

+

+    /**

+    Get the number of include header files in PackageHeaders from the size of List

+    

+    @return int

+   **/

+    public int getSpdPackageHeaderCount() {

+        if (psaRoot.getPackageHeaders() == null || psaRoot.getPackageHeaders().getIncludeHeaderList() == null) {

+            return 0;

+        }

+        return psaRoot.getPackageHeaders().getIncludeHeaderList().size();

+    }

+

+    /**

+    Get available package header contents into String array

+    

+    @param pkgHeader Caller allocated two-dimentional String array

+   **/

+    public void getSpdPackageHeaders(String[][] pkgHeader) {

+        List<IncludeHeaderDocument.IncludeHeader> l = psaRoot.getPackageHeaders().getIncludeHeaderList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            IncludeHeaderDocument.IncludeHeader ih = (IncludeHeaderDocument.IncludeHeader) li.next();

+            if (ih.getModuleType() != null) {

+                pkgHeader[i][0] = ih.getModuleType().toString();

+            }

+

+            pkgHeader[i][1] = ih.getStringValue();

+            i++;

+        }

+    }

+

+    /**

+    Get the number of GUID declarations from the size of List

+    

+    @return int

+   **/

+    public int getSpdGuidDeclarationCount() {

+        if (psaRoot.getGuidDeclarations() == null || psaRoot.getGuidDeclarations().getEntryList() == null) {

+            return 0;

+        }

+        return psaRoot.getGuidDeclarations().getEntryList().size();

+    }

+

+    /**

+    Get available Guid declaration contents into String array

+    

+    @param guid Caller allocated two-dimentional String array

+   **/

+    public void getSpdGuidDeclarations(String[][] guid) {

+        List<GuidDeclarationsDocument.GuidDeclarations.Entry> l = psaRoot.getGuidDeclarations().getEntryList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            GuidDeclarationsDocument.GuidDeclarations.Entry e = (GuidDeclarationsDocument.GuidDeclarations.Entry) li

+                                                                                                                    .next();

+            guid[i][0] = e.getName();

+            guid[i][1] = e.getCName();

+            if (e.getGuid() != null) {

+                guid[i][2] = e.getGuid().getStringValue();

+            }

+            i++;

+        }

+    }

+

+    /**

+    Get the number of protocol declarations from the size of List

+    

+    @return int

+   **/

+    public int getSpdProtocolDeclarationCount() {

+        if (psaRoot.getProtocolDeclarations() == null || psaRoot.getProtocolDeclarations().getEntryList() == null) {

+            return 0;

+        }

+        return psaRoot.getProtocolDeclarations().getEntryList().size();

+    }

+

+    /**

+    Get available protocol declaration contents into String array

+    

+    @param protocol Caller allocated two-dimentional String array

+   **/

+    public void getSpdProtocolDeclarations(String[][] protocol) {

+        List<ProtocolDeclarationsDocument.ProtocolDeclarations.Entry> l = psaRoot.getProtocolDeclarations()

+                                                                                 .getEntryList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            ProtocolDeclarationsDocument.ProtocolDeclarations.Entry e = (ProtocolDeclarationsDocument.ProtocolDeclarations.Entry) li

+                                                                                                                                    .next();

+            protocol[i][0] = e.getName();

+            protocol[i][1] = e.getCName();

+            if (e.getGuid() != null) {

+                protocol[i][2] = e.getGuid().getStringValue();

+            }

+            i++;

+        }

+    }

+

+    /**

+    Get the number of Ppi declarations from the size of List

+    

+    @return int

+   **/

+    public int getSpdPpiDeclarationCount() {

+        if (psaRoot.getPpiDeclarations() == null || psaRoot.getPpiDeclarations().getEntryList() == null) {

+            return 0;

+        }

+        return psaRoot.getPpiDeclarations().getEntryList().size();

+    }

+

+    /**

+    Get available Ppi declaration contents into String array

+    

+    @param ppi Caller allocated two-dimentional String array

+   **/

+    public void getSpdPpiDeclarations(String[][] ppi) {

+        List<PpiDeclarationsDocument.PpiDeclarations.Entry> l = psaRoot.getPpiDeclarations().getEntryList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            PpiDeclarationsDocument.PpiDeclarations.Entry e = (PpiDeclarationsDocument.PpiDeclarations.Entry) li.next();

+            ppi[i][0] = e.getName();

+            ppi[i][1] = e.getCName();

+            if (e.getGuid() != null) {

+                ppi[i][2] = e.getGuid().getStringValue();

+            }

+

+            i++;

+        }

+    }

+

+    /**

+    Get the number of Pcd definitions from the size of List

+    

+    @return int

+   **/

+    public int getSpdPcdDefinitionCount() {

+        if (psaRoot.getPcdDefinitions() == null || psaRoot.getPcdDefinitions().getPcdEntryList() == null) {

+            return 0;

+        }

+        return psaRoot.getPcdDefinitions().getPcdEntryList().size();

+    }

+

+    /**

+    Get available Pcd definition contents into String array

+    

+    @param pcd Caller allocated two-dimentional String array

+   **/

+    public void getSpdPcdDefinitions(String[][] pcd) {

+        List<PcdDefinitionsDocument.PcdDefinitions.PcdEntry> l = psaRoot.getPcdDefinitions().getPcdEntryList();

+        int i = 0;

+        ListIterator li = l.listIterator();

+        while (li.hasNext()) {

+            PcdDefinitionsDocument.PcdDefinitions.PcdEntry e = (PcdDefinitionsDocument.PcdDefinitions.PcdEntry) li

+                                                                                                                  .next();

+            if (e.getItemType() != null) {

+                pcd[i][0] = e.getItemType().toString();

+            }

+

+            pcd[i][1] = e.getCName();

+            pcd[i][2] = e.getToken();

+            if (e.getDatumType() != null) {

+                pcd[i][3] = e.getDatumType().toString();

+            }

+

+            if (e.getDefaultValue() != null) {

+                pcd[i][4] = e.getDefaultValue().toString();

+            }

+

+            i++;

+        }

+    }

+

+    /**

+     Save the processed xml contents to file

+     

+     @param spdFile The file to save xml contents

+     @throws IOException Exceptions during file operation

+    **/

+    public void saveAs(File spdFile) throws IOException {

+

+        XmlOptions options = new XmlOptions();

+

+        options.setCharacterEncoding("UTF-8");

+        options.setSavePrettyPrint();

+        options.setSavePrettyPrintIndent(2);

+        try {

+            psad.save(spdFile, options);

+        } catch (IOException e) {

+            e.printStackTrace();

+        }

+

+    }

+

+    /**

+     Generate SpdHeader contents using parameters passed in.

+     

+     @param pkgName PackageName 

+     @param pkgGuid Guid

+     @param pkgVer Version

+     @param pkgAbs Abstract

+     @param pkgDes Description

+     @param pkgCpRight Copyright

+     @param pkgLicense License

+     @param pkgCreateDate Created

+     @param pkgUpdateDate Updated

+     @param pkgURL URL

+     @param pkgType PackageType

+     @param pkgRdOnly ReadOnly

+     @param pkgRePkg RePackage

+     @param pkgSpec Reserved

+     @param pkgOutDir Reserved

+    **/

+    public void genSpdHeader(String pkgName, String pkgGuid, String pkgVer, String pkgAbs, String pkgDes,

+                             String pkgCpRight, String pkgLicense, String pkgCreateDate, String pkgUpdateDate,

+                             String pkgURL, String pkgType, String pkgRdOnly, String pkgRePkg, String pkgSpec,

+                             String pkgOutDir) {

+        if (getSpdHdr() == null) {

+            spdHdr = psaRoot.addNewSpdHeader();

+        }

+

+        setSpdHdrPkgName(pkgName);

+        setSpdHdrGuid(pkgGuid);

+        setSpdHdrVer(pkgVer);

+        setSpdHdrAbs(pkgAbs);

+        setSpdHdrDes(pkgDes);

+        setSpdHdrCpRit(pkgCpRight);

+        setSpdHdrLicense(pkgLicense);

+        setSpdHdrCreateDate(pkgCreateDate);

+        setSpdHdrUpdateDate(pkgUpdateDate);

+        setSpdHdrURL(pkgURL);

+        setSpdHdrPkgType(pkgType);

+        setSpdHdrRdOnly(pkgRdOnly);

+        setSpdHdrRePkg(pkgRePkg);

+        setSpdHdrSpec(pkgSpec);

+        setSpdHdrOutDir(pkgOutDir);

+    }

+

+    /**

+     Generate library class declaration element using parameters passed in

+     

+     @param libClassBaseName LibraryClass element value

+     @param libClassUsage Reserved

+     @param incHdrFileName IncludeHeader element value

+     @param incHdrAttribGuid Reserved

+     @param incHdrAttribArch Reserved

+     @param incHdrAttribPath Reserved

+     @param incHdrAttribClass Reserved

+     @param incHdrAttribVer Reserved

+     @param incHdrAttribOverrideID Reserved

+     @param incHdrAttribModuleType Reserved

+    **/

+    public void genSpdLibClassDeclarations(String libClassBaseName, String libClassUsage, String incHdrFileName,

+                                           String incHdrAttribGuid, String incHdrAttribArch, String incHdrAttribPath,

+                                           String incHdrAttribClass, String incHdrAttribVer,

+                                           String incHdrAttribOverrideID, String incHdrAttribModuleType) {

+        if (getSpdLibClassDeclarations() == null) {

+            spdLibClassDeclarations = psaRoot.addNewLibraryClassDeclarations();

+        }

+        //

+        // add contents under LibraryClassDeclarations tag 

+        //

+        setSpdLibClassDeclaration(libClassBaseName, libClassUsage, incHdrFileName, incHdrAttribGuid, incHdrAttribArch,

+                                  incHdrAttribPath, incHdrAttribClass, incHdrAttribVer, incHdrAttribOverrideID,

+                                  incHdrAttribModuleType, spdLibClassDeclarations);

+    }

+

+    /**

+     Set library class declaration contents under parent tag

+     

+     @param clsName LibraryClass element value

+     @param clsUsage Reserved

+     @param hdrFile IncludeHeader element value

+     @param hdrAttribGuid Reserved

+     @param hdrAttribArch Reserved

+     @param hdrAttribPath Reserved

+     @param hdrAttribClass Reserved

+     @param hdrAttribVer Reserved

+     @param hdrAttribOverID Reserved

+     @param hdrAttribModType Reserved

+     @param parent The tag under which library class declaration goes to

+    **/

+    public void setSpdLibClassDeclaration(String clsName, String clsUsage, String hdrFile, String hdrAttribGuid,

+                                          String hdrAttribArch, String hdrAttribPath, String hdrAttribClass,

+                                          String hdrAttribVer, String hdrAttribOverID, String hdrAttribModType,

+                                          XmlObject parent) {

+

+        LibraryClassDeclarationDocument.LibraryClassDeclaration lcd = ((LibraryClassDeclarationsDocument.LibraryClassDeclarations) parent)

+                                                                                                                                          .addNewLibraryClassDeclaration();

+

+        setSpdLibraryClass(clsName, clsUsage, lcd);

+

+        setSpdIncludeHeader(null, hdrFile, hdrAttribGuid, hdrAttribArch, hdrAttribPath, hdrAttribClass, hdrAttribVer,

+                            hdrAttribOverID, lcd);

+    }

+

+    /**

+     Set the contents of LibraryClass under parent element

+     

+     @param clsName LibraryClass element value 

+     @param clsUsage Reserved

+     @param parent The tag under which library class declaration goes to

+    **/

+    public void setSpdLibraryClass(String clsName, String clsUsage, XmlObject parent) {

+        LibraryClassDeclarationDocument.LibraryClassDeclaration.LibraryClass lc = ((LibraryClassDeclarationDocument.LibraryClassDeclaration) parent).addNewLibraryClass();

+        lc.setStringValue(clsName);

+    }

+

+    /**

+     Set contents of IncludeHeader under parent element

+     

+     @param modType Reserved

+     @param hdrFile IncludeHeader element value

+     @param hdrAttribGuid Reserved

+     @param hdrAttribArch Reserved

+     @param hdrAttribPath Reserved

+     @param hdrAttribClass Reserved

+     @param hdrAttribVer Reserved

+     @param hdrAttribOverID Reserved

+     @param parent The tag under which library class declaration goes to

+    **/

+    public void setSpdIncludeHeader(String modType, String hdrFile, String hdrAttribGuid, String hdrAttribArch,

+                                    String hdrAttribPath, String hdrAttribClass, String hdrAttribVer,

+                                    String hdrAttribOverID, XmlObject parent) {

+        IncludeHeaderDocument.IncludeHeader ih = null;

+        if (parent instanceof LibraryClassDeclarationDocument.LibraryClassDeclaration) {

+            ih = ((LibraryClassDeclarationDocument.LibraryClassDeclaration) parent).addNewIncludeHeader();

+        } else if (parent instanceof PackageHeadersDocument.PackageHeaders) {

+            ih = ((PackageHeadersDocument.PackageHeaders) parent).addNewIncludeHeader();

+        } else {

+            return;

+        }

+

+        ih.setStringValue(hdrFile);

+        if (hdrAttribGuid != null) {

+            ih.setGuid(hdrAttribGuid);

+        }

+        if (hdrAttribPath != null) {

+            ih.setPath(hdrAttribPath);

+        }

+        if (hdrAttribClass != null) {

+            ih.setClass1(hdrAttribClass);

+        }

+        if (hdrAttribVer != null) {

+            ih.setVersion(hdrAttribVer);

+        }

+        if (hdrAttribOverID != null) {

+            ih.setOverrideID(Integer.parseInt(hdrAttribOverID));

+        }

+        if (modType != null) {

+            ih.setModuleType(ModuleTypeDef.Enum.forString(modType));

+

+        }

+

+    }

+

+    /**

+     Reserved method

+     

+     @param pkgDepPkgName

+     @param pkgDepPkgAttribGuid

+     @param pkgDepPkgAttribVer

+     @param pkgDepPkgAttribType

+     @param pkgDepPkgAttribUsage

+     @param pkgDepPkgAttribInstallDate

+     @param pkgDepPkgAttribUpdateDate

+     @param pkgDepPkgAttribPath

+    **/

+    public void genSpdPackageDependencies(String pkgDepPkgName, String pkgDepPkgAttribGuid, String pkgDepPkgAttribVer,

+                                          String pkgDepPkgAttribType, String pkgDepPkgAttribUsage,

+                                          String pkgDepPkgAttribInstallDate, String pkgDepPkgAttribUpdateDate,

+                                          String pkgDepPkgAttribPath) {

+        if (spdPkgDeps == null) {

+            spdPkgDeps = psaRoot.addNewPackageDependencies();

+        }

+

+        setSpdPackageName(pkgDepPkgName, pkgDepPkgAttribGuid, pkgDepPkgAttribVer, pkgDepPkgAttribType,

+                          pkgDepPkgAttribUsage, pkgDepPkgAttribInstallDate, pkgDepPkgAttribUpdateDate,

+                          pkgDepPkgAttribPath, spdPkgDeps);

+    }

+

+    /**

+     Reserved method

+     

+     @param pkgName

+     @param pkgAttribGuid

+     @param pkgAttribVer

+     @param pkgAttribType

+     @param pkgAttribUsage

+     @param pkgAttribInstallDate

+     @param pkgAttribUpdateDate

+     @param pkgAttribPath

+     @param parent

+    **/

+    public void setSpdPackageName(String pkgName, String pkgAttribGuid, String pkgAttribVer, String pkgAttribType,

+                                  String pkgAttribUsage, String pkgAttribInstallDate, String pkgAttribUpdateDate,

+                                  String pkgAttribPath, XmlObject parent) {

+

+        PackageNameDocument.PackageName pn = ((PackageDependenciesDocument.PackageDependencies) parent)

+                                                                                                       .addNewPackageName();

+        pn.setStringValue(pkgName);

+        pn.setPackageType(PackageType.Enum.forString(pkgAttribType));

+        pn.setUsage(PackageUsage.Enum.forString(pkgAttribUsage));

+        pn.setUpdatedDate(pkgAttribUpdateDate);

+    }

+

+    /**

+     Generate MsaFile element.

+     

+     @param msaFileName MsaFile element value

+     @param archType Reserved

+    **/

+    public void genSpdMsaFiles(String msaFileName, String archType) {

+        if (getSpdMsaFiles() == null) {

+            spdMsaFiles = psaRoot.addNewMsaFiles();

+        }

+        setSpdMsaFile(msaFileName, spdMsaFiles);

+        

+    }

+

+    /**

+     Set MsaFile contents under parent element.

+     

+     @param msaFileName MsaFile element value

+     @param parent Element under which MsaFile goes to

+    **/

+    public void setSpdMsaFile(String msaFileName, XmlObject parent) {

+

+        ((MsaFilesDocument.MsaFiles) parent).addNewMsaFile().addNewFilename().setStringValue(msaFileName);

+    }

+

+    /**

+     Generate PackageHeader element using parameters passed in.

+     

+     @param ModHdrModType ModuleType attribute of IncludeHeader element

+     @param hdrFile IncludeHeader element value

+     @param hdrAttribGuid Reserved

+     @param hdrAttribArch Reserved

+     @param hdrAttribPath Reserved

+     @param hdrAttribClass Reserved

+     @param hdrAttribVer Reserved

+     @param hdrAttribOverID Reserved

+    **/

+    public void genSpdModuleHeaders(String ModHdrModType, String hdrFile, String hdrAttribGuid, String hdrAttribArch,

+                                    String hdrAttribPath, String hdrAttribClass, String hdrAttribVer,

+                                    String hdrAttribOverID) {

+        if (getSpdModHdrs() == null) {

+            spdModHdrs = psaRoot.addNewPackageHeaders();

+        }

+

+        //

+        // add IncludeHeader under PackageHeaders element

+        //

+        setSpdIncludeHeader(ModHdrModType, hdrFile, hdrAttribGuid, hdrAttribArch, hdrAttribPath, hdrAttribClass,

+                            hdrAttribVer, hdrAttribOverID, spdModHdrs);

+    }

+

+    /**

+     Generate GUID declaration element using parameters passed in.

+     

+     @param guidDeclEntryName Name attribute of Entry element

+     @param guidDeclCName CName element value

+     @param guidDeclGuid Guid element value

+     @param guidDeclFeatureFlag Reserved

+    **/

+    public void genSpdGuidDeclarations(String guidDeclEntryName, String guidDeclCName, String guidDeclGuid,

+                                       String guidDeclFeatureFlag) {

+        if (getSpdGuidDeclarations() == null) {

+            spdGuidDeclarations = psaRoot.addNewGuidDeclarations();

+        }

+

+        setSpdEntry(guidDeclEntryName, guidDeclCName, guidDeclGuid, guidDeclFeatureFlag, spdGuidDeclarations);

+    }

+

+    /**

+    Generate protocol declaration element using parameters passed in.

+    

+    @param protocolDeclEntryName Name attribute of Entry element

+    @param protocolDeclCName CName element value

+    @param protocolDeclGuid Guid element value

+    @param protocolDeclFeatureFlag Reserved

+   **/

+    public void genSpdProtocolDeclarations(String protocolDeclEntryName, String protocolDeclCName,

+                                           String protocolDeclGuid, String protocolDeclFeatureFlag) {

+        if (getSpdProtocolDeclarations() == null) {

+            spdProtocolDeclarations = psaRoot.addNewProtocolDeclarations();

+        }

+

+        setSpdEntry(protocolDeclEntryName, protocolDeclCName, protocolDeclGuid, protocolDeclFeatureFlag,

+                    spdProtocolDeclarations);

+    }

+

+    /**

+    Generate PPI declaration element using parameters passed in.

+    

+    @param ppiDeclEntryName Name attribute of Entry element

+    @param ppiDeclCName CName element value

+    @param ppiDeclGuid Guid element value

+    @param ppiDeclFeatureFlag Reserved

+   **/

+    public void genSpdPpiDeclarations(String ppiDeclEntryName, String ppiDeclCName, String ppiDeclGuid,

+                                      String ppiDeclFeatureFlag) {

+        if (getSpdPpiDeclarations() == null) {

+            spdPpiDeclarations = psaRoot.addNewPpiDeclarations();

+        }

+

+        setSpdEntry(ppiDeclEntryName, ppiDeclCName, ppiDeclGuid, ppiDeclFeatureFlag, spdPpiDeclarations);

+    }

+

+    /**

+     Set Entry contents using parameters passed in

+     

+     @param entryName Name attribute of Entry element

+     @param cName CName element value

+     @param guid Guid element value

+     @param featureFlag Reserved

+     @param parent The tag under which Entry element goes to

+    **/

+    public void setSpdEntry(String entryName, String cName, String guid, String featureFlag, XmlObject parent) {

+

+        if (parent instanceof GuidDeclarationsDocument.GuidDeclarations) {

+            GuidDeclarationsDocument.GuidDeclarations.Entry e = ((GuidDeclarations) parent).addNewEntry();

+            e.setName(entryName);

+            e.setCName(cName);

+            e.addNewGuid().setStringValue(guid);

+            if (featureFlag != null) {

+                e.addNewFeatureFlag().setStringValue(featureFlag);

+            }

+            return;

+        }

+        if (parent instanceof ProtocolDeclarationsDocument.ProtocolDeclarations) {

+            ProtocolDeclarationsDocument.ProtocolDeclarations.Entry pe = ((ProtocolDeclarationsDocument.ProtocolDeclarations) parent)

+                                                                                                                                     .addNewEntry();

+            pe.setName(entryName);

+            pe.setCName(cName);

+            pe.addNewGuid().setStringValue(guid);

+            if (featureFlag != null) {

+                pe.addNewFeatureFlag().setStringValue(featureFlag);

+            }

+            return;

+        }

+        if (parent instanceof PpiDeclarationsDocument.PpiDeclarations) {

+            PpiDeclarationsDocument.PpiDeclarations.Entry ppe = ((PpiDeclarationsDocument.PpiDeclarations) parent)

+                                                                                                                  .addNewEntry();

+            ppe.setName(entryName);

+            ppe.setCName(cName);

+            ppe.addNewGuid().setStringValue(guid);

+            if (featureFlag != null) {

+                ppe.addNewFeatureFlag().setStringValue(featureFlag);

+            }

+            return;

+        }

+

+        return;

+

+    }

+

+    /**

+     Generate Pcd definition using parameters passed in

+     

+     @param pcdItemTypes ItemType attribute of PcdEntry element

+     @param cName C_Name element value

+     @param token Token element value

+     @param dataType DatumType element value

+     @param skuEnable Reserved

+     @param sku Reserved

+     @param maxSku Reserved

+     @param hiiEnable Reserved

+     @param varGuid Reserved

+     @param varName Reserved

+     @param defaultString DefaultString element value

+    **/

+    public void genSpdPcdDefinitions(String pcdItemTypes, String cName, String token, String dataType,

+                                     String skuEnable, String sku, String maxSku, String hiiEnable, String varGuid,

+                                     String varName, String defaultString) {

+        if (getSpdPcdDefinitions() == null) {

+            spdPcdDefinitions = psaRoot.addNewPcdDefinitions();

+        }

+

+        setSpdPcdEntry(pcdItemTypes, cName, token, dataType, skuEnable, sku, maxSku, hiiEnable, varGuid, varName,

+                       defaultString, spdPcdDefinitions);

+    }

+

+    /**

+     Set Pcd entry contents under parent tag

+     

+     @param pcdItemTypes ItemType attribute of PcdEntry element

+     @param cName C_Name element value

+     @param token Token element value

+     @param dataType DatumType element value

+     @param skuEnable Reserved

+     @param sku Reserved

+     @param maxSku Reserved

+     @param hiiEnable Reserved

+     @param varGuid Reserved

+     @param varName Reserved

+     @param defaultString DefaultString element value

+     @param parent Tag under which PcdEntry goes to

+    **/

+    public void setSpdPcdEntry(String pcdItemTypes, String cName, String token, String dataType, String skuEnable,

+                               String sku, String maxSku, String hiiEnable, String varGuid, String varName,

+                               String defaultString, XmlObject parent) {

+

+        PcdDefinitionsDocument.PcdDefinitions.PcdEntry pe = ((PcdDefinitionsDocument.PcdDefinitions) parent)

+                                                                                                            .addNewPcdEntry();

+        pe.setItemType(PcdItemTypes.Enum.forString(pcdItemTypes));

+        pe.setCName(cName);

+        pe.setToken(token);

+        pe.setDatumType(PcdDataTypes.Enum.forString(dataType));

+        pe.setDefaultValue(defaultString);

+        

+    }

+

+    /**

+     Get PpiDeclarations element

+     

+     @return PpiDeclarationsDocument.PpiDeclarations

+    **/

+    public PpiDeclarationsDocument.PpiDeclarations getSpdPpiDeclarations() {

+        if (spdPpiDeclarations == null) {

+            spdPpiDeclarations = psaRoot.getPpiDeclarations();

+        }

+        return spdPpiDeclarations;

+    }

+

+    /**

+    Get ProtocolDeclarations element

+    

+    @return ProtocolDeclarationsDocument.ProtocolDeclarations

+    **/

+    public ProtocolDeclarationsDocument.ProtocolDeclarations getSpdProtocolDeclarations() {

+        if (spdProtocolDeclarations == null) {

+            spdProtocolDeclarations = psaRoot.getProtocolDeclarations();

+        }

+        return spdProtocolDeclarations;

+    }

+

+    /**

+    Get GuidDeclarations element

+    

+    @return GuidDeclarationsDocument.GuidDeclarations

+    **/

+    public GuidDeclarationsDocument.GuidDeclarations getSpdGuidDeclarations() {

+        if (spdGuidDeclarations == null) {

+            spdGuidDeclarations = psaRoot.getGuidDeclarations();

+        }

+        return spdGuidDeclarations;

+    }

+

+    /**

+     Get PcdDefinitions element

+     

+     @return PcdDefinitionsDocument.PcdDefinitions

+    **/

+    public PcdDefinitionsDocument.PcdDefinitions getSpdPcdDefinitions() {

+        if (spdPcdDefinitions == null) {

+            spdPcdDefinitions = psaRoot.getPcdDefinitions();

+        }

+        return spdPcdDefinitions;

+    }

+

+    /**

+     Get PackageHeaders element

+     

+     @return PackageHeadersDocument.PackageHeaders

+    **/

+    public PackageHeadersDocument.PackageHeaders getSpdModHdrs() {

+        if (spdModHdrs == null) {

+            spdModHdrs = psaRoot.getPackageHeaders();

+        }

+        return spdModHdrs;

+    }

+

+    /**

+     Get MsaFiles element

+     

+     @return MsaFilesDocument.MsaFiles

+    **/

+    public MsaFilesDocument.MsaFiles getSpdMsaFiles() {

+        if (spdMsaFiles == null) {

+            spdMsaFiles = psaRoot.getMsaFiles();

+        }

+        return spdMsaFiles;

+    }

+

+    /**

+     Get LibraryClassDeclarations element

+     

+     @return LibraryClassDeclarationsDocument.LibraryClassDeclarations

+    **/

+    public LibraryClassDeclarationsDocument.LibraryClassDeclarations getSpdLibClassDeclarations() {

+        if (spdLibClassDeclarations == null) {

+            spdLibClassDeclarations = psaRoot.getLibraryClassDeclarations();

+        }

+        return spdLibClassDeclarations;

+    }

+

+    /**

+     Get SpdHeader element

+     

+     @return SpdHeaderDocument.SpdHeader

+    **/

+    public SpdHeaderDocument.SpdHeader getSpdHdr() {

+        if (spdHdr == null) {

+            spdHdr = psaRoot.getSpdHeader();

+        }

+        return spdHdr;

+    }

+

+    /**

+     Get Abstract element under tag SpdHeader

+     

+     @return AbstractDocument.Abstract

+    **/

+    public AbstractDocument.Abstract getSpdHdrAbs() {

+        if (spdHdrAbs == null) {

+            spdHdrAbs = getSpdHdr().getAbstract();

+        }

+        return spdHdrAbs;

+    }

+

+    /**

+     Set value to Abstract element

+     

+     @param abs The value set to Abstract element

+    **/

+    public void setSpdHdrAbs(String abs) {

+

+        if (getSpdHdrAbs() != null) {

+            getSpdHdrAbs().setStringValue(abs);

+        } else {

+            spdHdrAbs = getSpdHdr().addNewAbstract();

+            spdHdrAbs.setStringValue(abs);

+        }

+    }

+

+    /**

+     Set value to Copyright element

+     

+     @param cpRit The value set to Copyright element

+    **/

+    public void setSpdHdrCpRit(String cpRit) {

+

+        getSpdHdr().setCopyright(cpRit);

+

+    }

+

+    /**

+     Set value to Created element

+     

+     @param createDate The value set to Created element

+    **/

+    public void setSpdHdrCreateDate(String createDate) {

+

+        getSpdHdr().setCreated(createDate);

+

+    }

+

+    /**

+     Set value to Description element

+     

+     @param des The value set to Description element

+    **/

+    public void setSpdHdrDes(String des) {

+        getSpdHdr().setDescription(des);

+    }

+

+    /**

+     Get Guid element under SpdHdr

+     

+     @return GuidDocument.Guid

+    **/

+    public GuidDocument.Guid getSpdHdrGuid() {

+        if (spdHdrGuid == null) {

+            spdHdrGuid = getSpdHdr().getGuid();

+        }

+        return spdHdrGuid;

+    }

+

+    /**

+     Set value to Guid element

+     

+     @param guid The value set to Guid element

+    **/

+    public void setSpdHdrGuid(String guid) {

+        if (getSpdHdrGuid() != null) {

+            getSpdHdrGuid().setStringValue(guid);

+        } else {

+            spdHdrGuid = getSpdHdr().addNewGuid();

+            spdHdrGuid.setStringValue(guid);

+        }

+    }

+

+    /**

+    Get Version element under SpdHdr

+    

+    @return String

+   **/

+    public String getSpdHdrVer() {

+        if (spdHdr != null)

+            return spdHdr.getVersion();

+        else

+            return null;

+    }

+

+    /**

+    Set value to Version element

+    

+    @param ver The value set to Version element

+   **/

+    public void setSpdHdrVer(String ver) {

+        if (spdHdr != null) {

+            spdHdr.setVersion(ver);

+        }

+

+    }

+

+    /**

+    Get License element under SpdHdr

+    

+    @return LicenseDocument.License

+   **/

+    public LicenseDocument.License getSpdHdrLicense() {

+        if (spdHdrLicense == null) {

+            spdHdrLicense = getSpdHdr().getLicense();

+        }

+        return spdHdrLicense;

+    }

+

+    /**

+    Set value to License element

+    

+    @param license The value set to License element

+   **/

+    public void setSpdHdrLicense(String license) {

+        if (getSpdHdrLicense() != null) {

+            getSpdHdrLicense().setStringValue(license);

+        } else {

+            spdHdrLicense = getSpdHdr().addNewLicense();

+            spdHdrLicense.setStringValue(license);

+        }

+    }

+

+    /**

+     Reserved method

+     

+     @return

+    **/

+    public OutputDirectoryDocument.OutputDirectory getSpdHdrOutDir() {

+        return spdHdrOutDir;

+    }

+

+    /**

+     Reserved method

+     

+     @param outdir

+    **/

+    public void setSpdHdrOutDir(String outdir) {

+        if (outdir == null) {

+            return;

+        }

+        if (getSpdHdrOutDir() != null) {

+            getSpdHdrOutDir().setStringValue(outdir);

+        } else {

+            spdHdrOutDir = getSpdHdr().addNewOutputDirectory();

+            spdHdrOutDir.setStringValue(outdir);

+        }

+    }

+

+    /**

+    Get PackageName element under SpdHdr

+    

+    @return PackageNameDocument.PackageName

+   **/

+    public PackageNameDocument.PackageName getSpdHdrPkgName() {

+        if (spdHdrPkgName == null) {

+            spdHdrPkgName = getSpdHdr().getPackageName();

+        }

+        return spdHdrPkgName;

+    }

+

+    /**

+    Set value to PackageName element

+    

+    @param pkgName The value set to PackageName element

+   **/

+    public void setSpdHdrPkgName(String pkgName) {

+

+        if (getSpdHdrPkgName() != null) {

+            getSpdHdrPkgName().setStringValue(pkgName);

+        } else {

+            spdHdrPkgName = getSpdHdr().addNewPackageName();

+            spdHdrPkgName.setStringValue(pkgName);

+        }

+    }

+

+    /**

+    Reserved method

+    

+    @return SpecificationDocument.Specification

+   **/

+    public SpecificationDocument.Specification getSpdHdrSpec() {

+        return spdHdrSpec;

+    }

+

+    /**

+    Reserved method

+    

+    @param spec 

+   **/

+    public void setSpdHdrSpec(String spec) {

+        if (spec == null) {

+            return;

+        }

+        if (getSpdHdrSpec() != null) {

+            getSpdHdrSpec().setStringValue(spec);

+        } else {

+            spdHdrSpec = getSpdHdr().addNewSpecification();

+            spdHdrSpec.setStringValue(spec);

+        }

+    }

+

+    /**

+    Set value to PackageType element

+    

+    @param pkgType The value set to PackageType element

+   **/

+    public void setSpdHdrPkgType(String pkgType) {

+        getSpdHdr().setPackageType(PackageType.Enum.forString(pkgType));

+    }

+

+    /**

+    Set value to ReadOnly element

+    

+    @param rdOnly The value set to ReadOnly element

+   **/

+    public void setSpdHdrRdOnly(String rdOnly) {

+

+        getSpdHdr().setReadOnly(new Boolean(rdOnly));

+    }

+

+    /**

+    Set value to RePackage element

+    

+    @param rePkg The value set to RePackage element

+   **/

+    public void setSpdHdrRePkg(String rePkg) {

+

+        getSpdHdr().setRePackage(new Boolean(rePkg));

+    }

+

+    /**

+    Set value to Updated element

+    

+    @param updateDate The value set to Updated element

+   **/

+    public void setSpdHdrUpdateDate(String updateDate) {

+        getSpdHdr().setUpdated(updateDate);

+    }

+

+    /**

+    Set value to URL element

+    

+    @param url The value set to URL element

+   **/

+    public void setSpdHdrURL(String url) {

+        getSpdHdr().setURL(url);

+    }

+

+    /**

+     Get xml file

+     

+     @return File

+    **/

+    public File getFile() {

+        return file;

+    }

+

+    /**

+     Set file

+     

+     @param file File with xml format

+    **/

+    public void setFile(File file) {

+        this.file = file;

+    }

+

+}

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateAction.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateAction.java
new file mode 100644
index 0000000..a7ff016
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateAction.java
@@ -0,0 +1,328 @@
+/** @file

+  Java class UpdateAction is GUI for update spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.BorderLayout;

+import java.awt.Dimension;

+import java.awt.Toolkit;

+

+import javax.swing.JFileChooser;

+import javax.swing.JOptionPane;

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import java.awt.GridLayout;

+import java.io.File;

+

+import javax.swing.JButton;

+

+/**

+GUI for update spd file

+ 

+@since PackageEditor 1.0

+**/

+public class UpdateAction extends JFrame {

+

+    static JFrame frame;

+

+    private JPanel jContentPane = null;

+

+    private JButton jButton = null;

+

+    private JButton jButton1 = null;

+

+    private JButton jButton2 = null;

+

+    private JButton jButton3 = null;

+

+    private JButton jButton4 = null;

+

+    private JButton jButton5 = null;

+

+    private JButton jButton6 = null;

+

+    private JButton jButton7 = null;

+

+    private SpdFileContents sfc = null;

+

+    private JFrame pThis = null;  //  @jve:decl-index=0:visual-constraint="322,10"

+

+    private JButton jButton8 = null;

+    

+    private JButton jButton9 = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdateAction(SpdFileContents sfc) {

+        super();

+        initialize();

+        this.sfc = sfc;

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(300, 333);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setContentPane(getJContentPane());

+        this.setTitle("Please Choose an Action");

+        this.centerWindow();

+        this.pThis = this;

+        pThis.setSize(new java.awt.Dimension(316,399));

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            GridLayout gridLayout = new GridLayout();

+            gridLayout.setRows(10);

+            gridLayout.setColumns(1);

+            jContentPane = new JPanel();

+            jContentPane.setLayout(gridLayout);

+            jContentPane.add(getJButton8(), null);

+            jContentPane.add(getJButton7(), null);

+            jContentPane.add(getJButton6(), null);

+            jContentPane.add(getJButton5(), null);

+            jContentPane.add(getJButton4(), null);

+            jContentPane.add(getJButton3(), null);

+            jContentPane.add(getJButton2(), null);

+            jContentPane.add(getJButton1(), null);

+            jContentPane.add(getJButton(), null);

+            jContentPane.add(getJButton9(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setText("Save");

+            jButton.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    JFileChooser chooser = new JFileChooser(sfc.getFile());

+                    chooser.setMultiSelectionEnabled(false);

+

+                    int retval = chooser.showSaveDialog(frame);

+                    if (retval == JFileChooser.APPROVE_OPTION) {

+                        try {

+                            File theFile = chooser.getSelectedFile();

+                            if (theFile.exists()) {

+                                int retVal = JOptionPane.showConfirmDialog(frame, "Are you sure to replace the exising one?", "File Exists",

+                                                                           JOptionPane.YES_NO_OPTION);

+                                if (retVal == JOptionPane.NO_OPTION) {

+                                    return;

+                                } 

+                            }

+                            sfc.saveAs(theFile);

+

+                        } catch (Exception ee) {

+                            System.out.println(ee.toString());

+                        }

+//                        pThis.dispose();

+                    }

+

+                }

+            });

+        }

+        return jButton;

+    }

+

+    /**

+     This method initializes jButton1	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton1() {

+        if (jButton1 == null) {

+            jButton1 = new JButton();

+            jButton1.setText("Update PCD Information");

+            jButton1.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdatePCD(sfc), pThis);

+                }

+            });

+        }

+        return jButton1;

+    }

+

+    /**

+     This method initializes jButton2	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton2() {

+        if (jButton2 == null) {

+            jButton2 = new JButton();

+            jButton2.setText("Update PPI Declarations");

+            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdatePpi(sfc), pThis);

+                }

+            });

+        }

+        return jButton2;

+    }

+

+    /**

+     This method initializes jButton3	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton3() {

+        if (jButton3 == null) {

+            jButton3 = new JButton();

+            jButton3.setText("Update Protocol Declarations");

+            jButton3.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdateProtocols(sfc), pThis);

+                }

+            });

+        }

+        return jButton3;

+    }

+

+    /**

+     This method initializes jButton4	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton4() {

+        if (jButton4 == null) {

+            jButton4 = new JButton();

+            jButton4.setText("Update GUID Declarations");

+            jButton4.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdateGuids(sfc), pThis);

+                }

+            });

+        }

+        return jButton4;

+    }

+

+    /**

+     This method initializes jButton5	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton5() {

+        if (jButton5 == null) {

+            jButton5 = new JButton();

+            jButton5.setText("Update Package Headers");

+            jButton5.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdatePkgHeader(sfc), pThis);

+                }

+            });

+        }

+        return jButton5;

+    }

+

+    /**

+     This method initializes jButton6	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton6() {

+        if (jButton6 == null) {

+            jButton6 = new JButton();

+            jButton6.setText("Update MSA Files");

+            jButton6.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdateMsaFile(sfc), pThis);

+                }

+            });

+        }

+        return jButton6;

+    }

+

+    /**

+     This method initializes jButton7	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton7() {

+        if (jButton7 == null) {

+            jButton7 = new JButton();

+            jButton7.setText("Update Library Classes");

+            jButton7.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdateLibraryClass(sfc), pThis);

+                }

+            });

+        }

+        return jButton7;

+    }

+

+    /**

+     This method initializes jButton8	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton8() {

+        if (jButton8 == null) {

+            jButton8 = new JButton();

+            jButton8.setText("Update SPD Header");

+            jButton8.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    ModalFrameUtil.showAsModal(new UpdateNew(sfc), pThis);

+                }

+            });

+        }

+        return jButton8;

+    }

+

+    private JButton getJButton9() {

+        if (jButton9 == null) {

+            jButton9 = new JButton();

+            jButton9.setText("Done");

+            jButton9.addMouseListener(new java.awt.event.MouseAdapter() {

+                public void mouseClicked(java.awt.event.MouseEvent e) {

+                    

+                        pThis.dispose();

+               

+                }

+            });

+        }

+        return jButton9;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="104,41"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateGuids.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateGuids.java
new file mode 100644
index 0000000..6193073
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateGuids.java
@@ -0,0 +1,249 @@
+/** @file

+  Java class UpdateGuids is GUI for update GUID declarations in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.*;

+

+/**

+ GUI for update GUID declarations in spd file

+  

+ @since PackageEditor 1.0

+**/

+public class UpdateGuids extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdateGuids(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButton) {

+            String[] o = { "", "", "" };

+            model.addRow(o);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(669, 568);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update GUID Declarations");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(38,45,586,315));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("Name");

+            model.addColumn("C_Name");

+            model.addColumn("GUID");

+            if (sfc.getSpdGuidDeclarationCount() == 0) {

+                return jTable;

+            }

+            //

+            // initialize table using SpdFileContents object

+            //

+            String[][] saa = new String[sfc.getSpdGuidDeclarationCount()][3];

+            sfc.getSpdGuidDeclarations(saa);

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+

+            jTable.getColumnModel().getColumn(2).setCellEditor(new GuidEditor());

+        }

+        return jTable;

+    }

+

+    /**

+     Remove original GUID declarations before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdGuidDeclaration();

+        int rowCount = model.getRowCount();

+        int i = 0;

+

+        while (i < rowCount) {

+            String name = null;

+            if (model.getValueAt(i, 0) != null) {

+                name = model.getValueAt(i, 0).toString();

+            }

+            String cName = null;

+            if (model.getValueAt(i, 1) != null) {

+                cName = model.getValueAt(i, 1).toString();

+            }

+            String guid = null;

+            if (model.getValueAt(i, 2) != null) {

+                guid = model.getValueAt(i, 2).toString();

+            }

+            sfc.genSpdGuidDeclarations(name, cName, guid, null);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(316, 486));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(411, 486));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(219, 487, 78, 18));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+} //  @jve:decl-index=0:visual-constraint="11,7"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateLibraryClass.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateLibraryClass.java
new file mode 100644
index 0000000..4bd6a13
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateLibraryClass.java
@@ -0,0 +1,243 @@
+/** @file

+  Java class UpdateLibraryClass is GUI for update library class in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.*;

+

+/**

+ GUI for update library class in spd file

+  

+ @since PackageEditor 1.0

+**/

+public class UpdateLibraryClass extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdateLibraryClass(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+

+        if (arg0.getSource() == jButton) {

+            String[] o = { "", "" };

+            model.addRow(o);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(604, 553);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update Library Class Declarations");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(38, 45, 453, 419));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("LibraryClass");

+            model.addColumn("IncludeHeader");

+            if (sfc.getSpdLibClassDeclarationCount() == 0) {

+                return jTable;

+            }

+            //

+            // initialize table using SpdFileContents object

+            //

+            String[][] saa = new String[sfc.getSpdLibClassDeclarationCount()][2];

+            sfc.getSpdLibClassDeclarations(saa);

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+

+        }

+        return jTable;

+    }

+

+    /**

+    Remove original library classes before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdLibClass();

+        int rowCount = model.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            String libClass = null;

+            if (model.getValueAt(i, 0) != null) {

+                libClass = model.getValueAt(i, 0).toString();

+            }

+            String headerFile = null;

+            if (model.getValueAt(i, 1) != null) {

+                headerFile = model.getValueAt(i, 1).toString();

+            }

+            sfc.genSpdLibClassDeclarations(libClass, null, headerFile, null, null, null, null, null, null, null);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(316, 486));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(411, 486));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(221, 486, 79, 19));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+} //  @jve:decl-index=0:visual-constraint="11,7"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateMsaFile.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateMsaFile.java
new file mode 100644
index 0000000..4327fd5
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateMsaFile.java
@@ -0,0 +1,237 @@
+/** @file

+  Java class UpdateLibraryClass is GUI for msa files in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+

+/**

+ GUI for msa files in spd file

+  

+ @since PackageEditor 1.0

+**/

+public class UpdateMsaFile extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdateMsaFile(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButton) {

+            String[] o = { "" };

+            model.addRow(o);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(604, 553);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update MSA Files");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(38, 45, 453, 419));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("MSA File");

+

+            if (sfc.getSpdMsaFileCount() == 0) {

+                return jTable;

+            }

+            //

+            // initialize table using SpdFileContents object

+            //

+            String[][] saa = new String[sfc.getSpdMsaFileCount()][1];

+            sfc.getSpdMsaFiles(saa);            

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+        }

+        return jTable;

+    }

+

+    /**

+    Remove original Msa files before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdMsaFile();

+        int rowCount = jTable.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            String msaFile = null;

+            if (jTable.getValueAt(i, 0) != null) {

+                msaFile = jTable.getValueAt(i, 0).toString();

+            }

+            sfc.genSpdMsaFiles(msaFile, null);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(316, 486));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(411, 486));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(219, 486, 79, 19));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="11,7"

+

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateNew.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateNew.java
new file mode 100644
index 0000000..46ba748
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateNew.java
@@ -0,0 +1,573 @@
+/** @file

+  Java class UpdateNew is GUI for SpdHeader in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.text.SimpleDateFormat;

+import java.util.Date;

+

+import javax.swing.JFrame;

+import javax.swing.JPanel;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+import javax.swing.JTextArea;

+import javax.swing.JScrollPane;

+

+import javax.swing.JComboBox;

+

+import org.tianocore.common.Tools;

+import org.tianocore.packaging.common.ui.StarLabel;

+

+/**

+ GUI for update SpdHeader contents

+  

+ @since PackageEditor 1.0

+**/

+public class UpdateNew extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null; //  @jve:decl-index=0:visual-constraint="128,4"

+

+    private JLabel jLabelBaseName = null;

+

+    private JTextField jTextFieldBaseName = null;

+

+    private JLabel jLabelGuid = null;

+

+    private JTextField jTextFieldGuid = null;

+

+    private JLabel jLabelVersion = null;

+

+    private JTextField jTextFieldVersion = null;

+

+    private JButton jButtonGenerateGuid = null;

+

+    private JLabel jLabelLicense = null;

+

+    private JTextArea jTextAreaLicense = null;

+

+    private JLabel jLabelCopyright = null;

+

+    private JTextArea jTextAreaCopyright = null;

+

+    private JLabel jLabelDescription = null;

+

+    private JTextArea jTextAreaDescription = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private JScrollPane jScrollPaneLicense = null;

+

+    private JScrollPane jScrollPaneCopyright = null;

+

+    private JScrollPane jScrollPaneDescription = null;

+

+    private JLabel jLabelAbstract = null;

+

+    private JTextField jTextFieldAbstract = null;

+

+    private JLabel jLabelModuleType = null;

+

+    private JLabel jLabelCompontentType = null;

+

+    private JComboBox jComboBox1 = null;

+

+    private JComboBox jComboBoxModuleType = null;

+

+    private StarLabel jStarLabel1 = null;

+

+    private StarLabel jStarLabel2 = null;

+

+    private StarLabel jStarLabel3 = null;

+

+    private StarLabel jStarLabel4 = null;

+

+    private StarLabel jStarLabel5 = null;

+

+    private StarLabel jStarLabel6 = null;

+

+    private StarLabel jStarLabel7 = null;

+

+    private StarLabel jStarLabel8 = null;

+

+    private JLabel jLabelURL = null;

+

+    private JTextField jTextFieldAbstractURL = null;

+

+    private JLabel jLabel = null;

+

+    private JComboBox jComboBox = null;

+

+    private SpdFileContents sfc = null;

+

+    private String createTime = null;

+

+    /**

+     This method initializes this

+     

+     **/

+    private void initialize() {

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+

+    }

+

+    /**

+     This method initializes jTextFieldBaseName	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldBaseName() {

+        if (jTextFieldBaseName == null) {

+            jTextFieldBaseName = new JTextField();

+            jTextFieldBaseName.setBounds(new java.awt.Rectangle(160, 10, 320, 20));

+        }

+        return jTextFieldBaseName;

+    }

+

+    /**

+     This method initializes jTextFieldGuid	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldGuid() {

+        if (jTextFieldGuid == null) {

+            jTextFieldGuid = new JTextField();

+            jTextFieldGuid.setBounds(new java.awt.Rectangle(160, 35, 240, 20));

+        }

+        return jTextFieldGuid;

+    }

+

+    /**

+     This method initializes jTextFieldVersion	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldVersion() {

+        if (jTextFieldVersion == null) {

+            jTextFieldVersion = new JTextField();

+            jTextFieldVersion.setBounds(new java.awt.Rectangle(160, 60, 320, 20));

+        }

+        return jTextFieldVersion;

+    }

+

+    /**

+     This method initializes jButtonGenerateGuid	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonGenerateGuid() {

+        if (jButtonGenerateGuid == null) {

+            jButtonGenerateGuid = new JButton();

+            jButtonGenerateGuid.setBounds(new java.awt.Rectangle(405, 35, 75, 20));

+            jButtonGenerateGuid.setText("GEN");

+            jButtonGenerateGuid.addActionListener(this);

+        }

+        return jButtonGenerateGuid;

+    }

+

+    /**

+     This method initializes jTextAreaLicense	

+     	

+     @return javax.swing.JTextArea	

+     **/

+    private JTextArea getJTextAreaLicense() {

+        if (jTextAreaLicense == null) {

+            jTextAreaLicense = new JTextArea();

+            jTextAreaLicense.setText("");

+            jTextAreaLicense.setLineWrap(true);

+        }

+        return jTextAreaLicense;

+    }

+

+    /**

+     This method initializes jTextAreaCopyright	

+     	

+     @return javax.swing.JTextArea	

+     **/

+    private JTextArea getJTextAreaCopyright() {

+        if (jTextAreaCopyright == null) {

+            jTextAreaCopyright = new JTextArea();

+            jTextAreaCopyright.setLineWrap(true);

+        }

+        return jTextAreaCopyright;

+    }

+

+    /**

+     This method initializes jTextAreaDescription	

+     	

+     @return javax.swing.JTextArea	

+     **/

+    private JTextArea getJTextAreaDescription() {

+        if (jTextAreaDescription == null) {

+            jTextAreaDescription = new JTextArea();

+            jTextAreaDescription.setLineWrap(true);

+        }

+        return jTextAreaDescription;

+    }

+

+    /**

+     This method initializes jButtonNext	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("OK");

+            jButtonOk.setBounds(new java.awt.Rectangle(290, 481, 90, 20));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setBounds(new java.awt.Rectangle(390, 481, 90, 20));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPaneLicense() {

+        if (jScrollPaneLicense == null) {

+            jScrollPaneLicense = new JScrollPane();

+            jScrollPaneLicense.setBounds(new java.awt.Rectangle(160, 85, 320, 80));

+            jScrollPaneLicense.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+            jScrollPaneLicense.setViewportView(getJTextAreaLicense());

+        }

+        return jScrollPaneLicense;

+    }

+

+    /**

+     This method initializes jScrollPane1	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPaneCopyright() {

+        if (jScrollPaneCopyright == null) {

+            jScrollPaneCopyright = new JScrollPane();

+            jScrollPaneCopyright.setBounds(new java.awt.Rectangle(160,170,320,26));

+            jScrollPaneCopyright.setViewportView(getJTextAreaCopyright());

+            jScrollPaneCopyright.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+        }

+        return jScrollPaneCopyright;

+    }

+

+    /**

+     This method initializes jScrollPane2	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPaneDescription() {

+        if (jScrollPaneDescription == null) {

+            jScrollPaneDescription = new JScrollPane();

+            jScrollPaneDescription.setBounds(new java.awt.Rectangle(160, 322, 320, 80));

+            jScrollPaneDescription.setViewportView(getJTextAreaDescription());

+            jScrollPaneDescription.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

+        }

+        return jScrollPaneDescription;

+    }

+

+    /**

+     This method initializes jTextFieldAbstract	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldAbstract() {

+        if (jTextFieldAbstract == null) {

+            jTextFieldAbstract = new JTextField();

+            jTextFieldAbstract.setBounds(new java.awt.Rectangle(161,216,318,73));

+        }

+        return jTextFieldAbstract;

+    }

+

+    /**

+     This method initializes jComboBoxCompontentType	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBox1() {

+        if (jComboBox1 == null) {

+            jComboBox1 = new JComboBox();

+            jComboBox1.setBounds(new java.awt.Rectangle(160, 465, 91, 20));

+        }

+        return jComboBox1;

+    }

+

+    /**

+     This method initializes jComboBoxModuleType	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBoxModuleType() {

+        if (jComboBoxModuleType == null) {

+            jComboBoxModuleType = new JComboBox();

+            jComboBoxModuleType.setBounds(new java.awt.Rectangle(160, 440, 91, 20));

+        }

+        return jComboBoxModuleType;

+    }

+

+    /**

+     This method initializes jTextFieldAbstractURL	

+     	

+     @return javax.swing.JTextField	

+     **/

+    private JTextField getJTextFieldAbstractURL() {

+        if (jTextFieldAbstractURL == null) {

+            jTextFieldAbstractURL = new JTextField();

+            jTextFieldAbstractURL.setBounds(new java.awt.Rectangle(159, 414, 320, 20));

+        }

+        return jTextFieldAbstractURL;

+    }

+

+    public UpdateNew(SpdFileContents sfc) {

+        super();

+        initialize();

+        init();

+        this.setVisible(true);

+        this.sfc = sfc;

+        initShow();

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void init() {

+        this.setSize(500, 560);

+        this.setContentPane(getJContentPane());

+        this.setTitle("SPD File Header");

+        this.centerWindow();

+        //this.getRootPane().setDefaultButton(jButtonOk);

+        initFrame();

+    }

+

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jLabel = new JLabel();

+            jLabel.setBounds(new java.awt.Rectangle(15, 490, 140, 21));

+            jLabel.setText("Re-Package");

+            jLabelURL = new JLabel();

+            jLabelURL.setBounds(new java.awt.Rectangle(16, 414, 25, 20));

+            jLabelURL.setText("URL");

+            jLabelCompontentType = new JLabel();

+            jLabelCompontentType.setBounds(new java.awt.Rectangle(15, 465, 140, 20));

+            jLabelCompontentType.setText("Read Only");

+            jLabelModuleType = new JLabel();

+            jLabelModuleType.setBounds(new java.awt.Rectangle(15, 440, 140, 20));

+            jLabelModuleType.setText("Package Type");

+            jLabelAbstract = new JLabel();

+            jLabelAbstract.setBounds(new java.awt.Rectangle(17,216,140,20));

+            jLabelAbstract.setText("Abstract");

+            jLabelDescription = new JLabel();

+            jLabelDescription.setText("Description");

+            jLabelDescription.setBounds(new java.awt.Rectangle(16, 325, 140, 20));

+            jLabelCopyright = new JLabel();

+            jLabelCopyright.setText("Copyright");

+            jLabelCopyright.setBounds(new java.awt.Rectangle(15, 171, 140, 20));

+            jLabelLicense = new JLabel();

+            jLabelLicense.setText("License");

+            jLabelLicense.setBounds(new java.awt.Rectangle(15, 85, 140, 20));

+            jLabelVersion = new JLabel();

+            jLabelVersion.setText("Version");

+            jLabelVersion.setBounds(new java.awt.Rectangle(15, 60, 140, 20));

+            jLabelGuid = new JLabel();

+            jLabelGuid.setPreferredSize(new java.awt.Dimension(25, 15));

+            jLabelGuid.setBounds(new java.awt.Rectangle(15, 35, 140, 20));

+            jLabelGuid.setText("Guid");

+            jLabelBaseName = new JLabel();

+            jLabelBaseName.setText("Package Name");

+            jLabelBaseName.setBounds(new java.awt.Rectangle(15, 10, 140, 20));

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.setLocation(new java.awt.Point(0, 0));

+            jContentPane.setSize(new java.awt.Dimension(500, 524));

+            jContentPane.add(jLabelBaseName, null);

+            jContentPane.add(getJTextFieldBaseName(), null);

+            jContentPane.add(jLabelGuid, null);

+            jContentPane.add(getJTextFieldGuid(), null);

+            jContentPane.add(jLabelVersion, null);

+            jContentPane.add(getJTextFieldVersion(), null);

+            jContentPane.add(getJButtonGenerateGuid(), null);

+            jContentPane.add(jLabelLicense, null);

+            jContentPane.add(jLabelCopyright, null);

+            jContentPane.add(jLabelDescription, null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPaneLicense(), null);

+            jContentPane.add(getJScrollPaneCopyright(), null);

+            jContentPane.add(getJScrollPaneDescription(), null);

+            jContentPane.add(jLabelAbstract, null);

+            jContentPane.add(getJTextFieldAbstract(), null);

+            jContentPane.add(jLabelModuleType, null);

+            jContentPane.add(jLabelCompontentType, null);

+            jContentPane.add(getJComboBox1(), null);

+            jContentPane.add(getJComboBoxModuleType(), null);

+

+            jStarLabel1 = new StarLabel();

+            jStarLabel1.setLocation(new java.awt.Point(0, 10));

+            jStarLabel2 = new StarLabel();

+            jStarLabel2.setLocation(new java.awt.Point(0, 35));

+            jStarLabel3 = new StarLabel();

+            jStarLabel3.setLocation(new java.awt.Point(0, 60));

+            jStarLabel4 = new StarLabel();

+            jStarLabel4.setLocation(new java.awt.Point(0, 85));

+            jStarLabel5 = new StarLabel();

+            jStarLabel5.setLocation(new java.awt.Point(0, 171));

+            jStarLabel6 = new StarLabel();

+            jStarLabel6.setLocation(new java.awt.Point(1, 325));

+            jStarLabel7 = new StarLabel();

+            jStarLabel7.setLocation(new java.awt.Point(2,216));

+            jStarLabel8 = new StarLabel();

+            jStarLabel8.setLocation(new java.awt.Point(0, 440));

+

+            jContentPane.add(jStarLabel1, null);

+            jContentPane.add(jStarLabel2, null);

+            jContentPane.add(jStarLabel3, null);

+            jContentPane.add(jStarLabel4, null);

+            jContentPane.add(jStarLabel5, null);

+            jContentPane.add(jStarLabel6, null);

+            jContentPane.add(jStarLabel7, null);

+            jContentPane.add(jStarLabel8, null);

+            jContentPane.add(jLabelURL, null);

+            jContentPane.add(getJTextFieldAbstractURL(), null);

+            jContentPane.add(jLabel, null);

+            jContentPane.add(getJComboBox(), null);

+        }

+        return jContentPane;

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonGenerateGuid) {

+            jTextFieldGuid.setText(Tools.generateUuidString());

+        }

+    }

+

+    /**

+     Save all components of Msa Header, update time modified.

+     

+     **/

+    private void save() {

+        //		sfc.removeSpdHdr();

+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+        Date date = new Date();

+        sfc.genSpdHeader(jTextFieldBaseName.getText(), jTextFieldGuid.getText(), jTextFieldVersion.getText(),

+                         jTextFieldAbstract.getText(), jTextAreaDescription.getText(), jTextAreaCopyright.getText(),

+                         jTextAreaLicense.getText(), createTime, format.format(date), jTextFieldAbstractURL.getText(),

+                         jComboBoxModuleType.getSelectedItem().toString(), jComboBox1.getSelectedItem().toString(),

+                         jComboBox.getSelectedItem().toString(), null, null);

+        //		ModalFrameUtil.showAsModal(new PackageAction(sfc), pThis);

+    }

+

+    /**

+     This method initializes module type and compontent type

+     

+     **/

+    private void initFrame() {

+        jComboBoxModuleType.addItem("SOURCE");

+        jComboBoxModuleType.addItem("BINARY");

+        jComboBoxModuleType.addItem("MIXED");

+

+        jComboBox1.addItem("true");

+        jComboBox1.addItem("false");

+

+        jComboBox.addItem("false");

+        jComboBox.addItem("true");

+

+    }

+

+    /**

+     Display original SpdHeader contents during init

+    **/

+    private void initShow() {

+        String[] s = new String[12];

+

+        sfc.getSpdHdrDetails(s);

+        jTextFieldBaseName.setText(s[0]);

+        jTextFieldGuid.setText(s[1]);

+        jTextFieldVersion.setText(s[2]);

+        jTextFieldAbstract.setText(s[3]);

+        jTextAreaDescription.setText(s[4]);

+        jTextAreaCopyright.setText(s[5]);

+        jTextAreaLicense.setText(s[6]);

+        createTime = s[7];

+        jTextFieldAbstractURL.setText(s[8]);

+        jComboBoxModuleType.setSelectedItem(s[9]);

+        jComboBox1.setSelectedIndex(s[10].equals("true") ? 0 : 1);

+        jComboBox.setSelectedIndex(s[11].equals("true") ? 0 : 1);

+

+    }

+

+    /**

+     This method initializes jComboBox	

+     	

+     @return javax.swing.JComboBox	

+     **/

+    private JComboBox getJComboBox() {

+        if (jComboBox == null) {

+            jComboBox = new JComboBox();

+            jComboBox.setBounds(new java.awt.Rectangle(160, 490, 90, 20));

+        }

+        return jComboBox;

+    }

+

+} //  @jve:decl-index=0:visual-constraint="38,-22"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePCD.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePCD.java
new file mode 100644
index 0000000..765e331
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePCD.java
@@ -0,0 +1,277 @@
+/** @file

+  Java class UpdatePCD is GUI for update PCD definitions in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.DefaultCellEditor;

+import javax.swing.JComboBox;

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.*;

+

+/**

+ GUI for update PCD definitions in spd file

+  

+ @since PackageEditor 1.0

+**/

+public class UpdatePCD extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private String[][] saa = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdatePCD(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButton) {

+            String[] o = { "FEATURE_FLAG", "", "", "UINT8", "0" };

+            model.addRow(o);

+        }

+

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(916, 486);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update PCD Definitions");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+    Remove original Pcd definitions before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdPcdDefinition();

+        int rowCount = model.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            String cName = null;

+            if (model.getValueAt(i, 1) != null) {

+                cName = model.getValueAt(i, 1).toString();

+            }

+            String token = null;

+            if (model.getValueAt(i, 2) != null) {

+                token = model.getValueAt(i, 2).toString();

+            }

+            String defaultVal = null;

+            if (model.getValueAt(i, 4) != null) {

+                defaultVal = model.getValueAt(i, 4).toString();

+            }

+            sfc.genSpdPcdDefinitions(model.getValueAt(i, 0).toString(), cName, token,

+                                     model.getValueAt(i, 3).toString(), null, null, null, null, null, null, defaultVal);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(605, 404));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(712, 404));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

+            jScrollPane.setBounds(new java.awt.Rectangle(51, 62, 782, 304));

+            jScrollPane.setViewportView(getJTable2());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable2() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("ItemType");

+            model.addColumn("C_Name");

+            model.addColumn("Token");

+            model.addColumn("DataType");

+            model.addColumn("DefaultValue");

+            //

+            // Using combobox to display ItemType in table

+            //

+            JComboBox jComboBoxItemType = new JComboBox();

+            jComboBoxItemType.addItem("FEATURE_FLAG");

+            jComboBoxItemType.addItem("FIXED_AT_BUILD");

+            jComboBoxItemType.addItem("PATCHABLE_IN_MODULE");

+            jComboBoxItemType.addItem("DYNAMIC");

+            jComboBoxItemType.addItem("DYNAMIC_EX");

+            TableColumn itemTypeColumn = jTable.getColumnModel().getColumn(0);

+            itemTypeColumn.setCellEditor(new DefaultCellEditor(jComboBoxItemType));

+            //

+            // Using combobox to display data type in table

+            //

+            JComboBox jComboBoxDataType = new JComboBox();

+            jComboBoxDataType.addItem("UINT8");

+            jComboBoxDataType.addItem("UINT16");

+            jComboBoxDataType.addItem("UINT32");

+            jComboBoxDataType.addItem("UINT64");

+            jComboBoxDataType.addItem("VOID*");

+            jComboBoxDataType.addItem("BOOLEAN");

+            TableColumn dataTypeColumn = jTable.getColumnModel().getColumn(3);

+            dataTypeColumn.setCellEditor(new DefaultCellEditor(jComboBoxDataType));

+

+            if (sfc.getSpdPcdDefinitionCount() == 0) {

+

+                return jTable;

+            }

+            saa = new String[sfc.getSpdPcdDefinitionCount()][5];

+            sfc.getSpdPcdDefinitions(saa);

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+

+        }

+        return jTable;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(499, 404, 77, 20));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+} //  @jve:decl-index=0:visual-constraint="11,7"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePkgHeader.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePkgHeader.java
new file mode 100644
index 0000000..5f9356c
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePkgHeader.java
@@ -0,0 +1,257 @@
+/** @file

+  Java class UpdatePkgHeader is GUI for update Package Header in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.DefaultCellEditor;

+import javax.swing.JComboBox;

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.*;

+

+/**

+ GUI for update Package Header in spd file

+  

+ @since PackageEditor 1.0

+**/

+public class UpdatePkgHeader extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdatePkgHeader(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+

+        if (arg0.getSource() == jButton) {

+            String[] o = { "BASE", "" };

+            model.addRow(o);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(604, 553);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update Package Headers");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(38, 45, 453, 419));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("ModuleType");

+            model.addColumn("IncludeHeader");

+            //

+            // Using combobox to display ModuleType in table

+            //

+            TableColumn typeColumn = jTable.getColumnModel().getColumn(0);

+            JComboBox jComboBoxSelect = new JComboBox();

+            jComboBoxSelect.addItem("BASE");

+            jComboBoxSelect.addItem("SEC");

+            jComboBoxSelect.addItem("PEI_CORE");

+            jComboBoxSelect.addItem("PEIM");

+            jComboBoxSelect.addItem("DXE_CORE");

+            jComboBoxSelect.addItem("DXE_DRIVER");

+            jComboBoxSelect.addItem("DXE_RUNTIME_DRIVER");

+            jComboBoxSelect.addItem("DXE_SAL_DRIVER");

+            jComboBoxSelect.addItem("DXE_SMM_DRIVER");

+            jComboBoxSelect.addItem("TOOLS");

+            jComboBoxSelect.addItem("UEFI_DRIVER");

+            jComboBoxSelect.addItem("UEFI_APPLICATION");

+            jComboBoxSelect.addItem("USER_DEFINED");

+            typeColumn.setCellEditor(new DefaultCellEditor(jComboBoxSelect));

+

+            if (sfc.getSpdPackageHeaderCount() == 0) {

+                return jTable;

+            }

+            String[][] saa = new String[sfc.getSpdPackageHeaderCount()][2];

+            sfc.getSpdPackageHeaders(saa);

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+

+        }

+        return jTable;

+    }

+

+    /**

+    Remove original package headers before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdPkgHeader();

+        int rowCount = model.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            String headFile = null;

+            if (model.getValueAt(i, 1) != null) {

+                headFile = model.getValueAt(i, 1).toString();

+            }

+            sfc.genSpdModuleHeaders(model.getValueAt(i, 0).toString(), headFile, null, null, null, null, null, null);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(316, 486));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(411, 486));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(220, 486, 85, 20));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+} //  @jve:decl-index=0:visual-constraint="11,7"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePpi.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePpi.java
new file mode 100644
index 0000000..be58e1c
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdatePpi.java
@@ -0,0 +1,248 @@
+/** @file

+  Java class UpdatePpi is GUI for update Ppi declarations in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.*;

+

+/**

+ GUI for update Ppi declarations in spd file.

+  

+ @since PackageEditor 1.0

+**/

+public class UpdatePpi extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdatePpi(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+

+        if (arg0.getSource() == jButton) {

+            String[] o = { "", "", "" };

+            model.addRow(o);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(604, 553);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update PPI Declarations");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(38, 45, 453, 419));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("Name");

+            model.addColumn("C_Name");

+            model.addColumn("GUID");

+            //

+            // initialize table using SpdFileContents object

+            //

+            if (sfc.getSpdPpiDeclarationCount() == 0) {

+                return jTable;

+            }

+            String[][] saa = new String[sfc.getSpdPpiDeclarationCount()][3];

+            sfc.getSpdPpiDeclarations(saa);

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+

+            jTable.getColumnModel().getColumn(2).setCellEditor(new GuidEditor());

+        }

+        return jTable;

+    }

+

+    /**

+    Remove original ppi declarations before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdPpiDeclaration();

+        int rowCount = model.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            String name = null;

+            if (model.getValueAt(i, 0) != null) {

+                name = model.getValueAt(i, 0).toString();

+            }

+            String cName = null;

+            if (model.getValueAt(i, 1) != null) {

+                cName = model.getValueAt(i, 1).toString();

+            }

+            String guid = null;

+            if (model.getValueAt(i, 2) != null) {

+                guid = model.getValueAt(i, 2).toString();

+            }

+            sfc.genSpdPpiDeclarations(name, cName, guid, null);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(316, 486));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(411, 486));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(224, 488, 72, 18));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+} //  @jve:decl-index=0:visual-constraint="11,7"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateProtocols.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateProtocols.java
new file mode 100644
index 0000000..4408ec1
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/UpdateProtocols.java
@@ -0,0 +1,250 @@
+/** @file

+  Java class UpdateProtocols is GUI for update protocol declarations in spd file.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging;

+

+import javax.swing.JPanel;

+import javax.swing.JFrame;

+import javax.swing.JLabel;

+import javax.swing.JTextField;

+import javax.swing.JButton;

+

+import javax.swing.JScrollPane;

+import javax.swing.JTable;

+import javax.swing.table.*;

+

+import org.tianocore.common.Tools;

+

+import java.awt.Dimension;

+import java.awt.Toolkit;

+import java.awt.event.ActionEvent;

+import java.awt.event.ActionListener;

+import java.io.*;

+

+/**

+ GUI for update protocol declarations in spd file

+  

+ @since PackageEditor 1.0

+**/

+public class UpdateProtocols extends JFrame implements ActionListener {

+

+    private JPanel jContentPane = null;

+

+    private JScrollPane jScrollPane = null;

+

+    private JTable jTable = null;

+

+    private SpdFileContents sfc = null;

+

+    private JButton jButtonOk = null;

+

+    private JButton jButtonCancel = null;

+

+    private DefaultTableModel model = null;

+

+    private JButton jButton = null;

+

+    /**

+     This is the default constructor

+     **/

+    public UpdateProtocols(SpdFileContents sfc) {

+        super();

+        this.sfc = sfc;

+        initialize();

+

+    }

+

+    public void actionPerformed(ActionEvent arg0) {

+        if (arg0.getSource() == jButtonOk) {

+            this.save();

+            this.dispose();

+

+        }

+        if (arg0.getSource() == jButtonCancel) {

+            this.dispose();

+

+        }

+

+        if (arg0.getSource() == jButton) {

+            String[] o = { "", "", "" };

+            model.addRow(o);

+        }

+    }

+

+    /**

+     This method initializes this

+     

+     @return void

+     **/

+    private void initialize() {

+        this.setSize(604, 553);

+        this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

+        this.setTitle("Update Protocol Declarations");

+        this.setContentPane(getJContentPane());

+        this.centerWindow();

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow(int intWidth, int intHeight) {

+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

+        this.setLocation((d.width - intWidth) / 2, (d.height - intHeight) / 2);

+    }

+

+    /**

+     Start the window at the center of screen

+     

+     **/

+    protected void centerWindow() {

+        centerWindow(this.getSize().width, this.getSize().height);

+    }

+    /**

+     This method initializes jContentPane

+     

+     @return javax.swing.JPanel

+     **/

+    private JPanel getJContentPane() {

+        if (jContentPane == null) {

+            jContentPane = new JPanel();

+            jContentPane.setLayout(null);

+            jContentPane.add(getJScrollPane(), null);

+            jContentPane.add(getJButtonOk(), null);

+            jContentPane.add(getJButtonCancel(), null);

+            jContentPane.add(getJButton(), null);

+        }

+        return jContentPane;

+    }

+

+    /**

+     This method initializes jScrollPane	

+     	

+     @return javax.swing.JScrollPane	

+     **/

+    private JScrollPane getJScrollPane() {

+        if (jScrollPane == null) {

+            jScrollPane = new JScrollPane();

+            jScrollPane.setBounds(new java.awt.Rectangle(38, 45, 453, 419));

+            jScrollPane.setViewportView(getJTable());

+        }

+        return jScrollPane;

+    }

+

+    /**

+     This method initializes jTable	

+     	

+     @return javax.swing.JTable	

+     **/

+    private JTable getJTable() {

+        if (jTable == null) {

+            model = new DefaultTableModel();

+            jTable = new JTable(model);

+            jTable.setRowHeight(20);

+            model.addColumn("Name");

+            model.addColumn("C_Name");

+            model.addColumn("GUID");

+            //

+            // initialize table using SpdFileContents object

+            //

+            if (sfc.getSpdProtocolDeclarationCount() == 0) {

+                return jTable;

+            }

+            String[][] saa = new String[sfc.getSpdProtocolDeclarationCount()][3];

+            sfc.getSpdProtocolDeclarations(saa);

+            int i = 0;

+            while (i < saa.length) {

+                model.addRow(saa[i]);

+                i++;

+            }

+

+            jTable.getColumnModel().getColumn(2).setCellEditor(new GuidEditor());

+

+        }

+        return jTable;

+    }

+

+    /**

+    Remove original protocol declarations before saving updated ones

+    **/

+    protected void save() {

+        if (jTable.isEditing()) {

+            jTable.getCellEditor().stopCellEditing();

+        }

+        sfc.removeSpdProtocolDeclaration();

+        int rowCount = model.getRowCount();

+        int i = 0;

+        while (i < rowCount) {

+            String name = null;

+            if (model.getValueAt(i, 0) != null) {

+                name = model.getValueAt(i, 0).toString();

+            }

+            String cName = null;

+            if (model.getValueAt(i, 1) != null) {

+                cName = model.getValueAt(i, 1).toString();

+            }

+            String guid = null;

+            if (model.getValueAt(i, 2) != null) {

+                guid = model.getValueAt(i, 2).toString();

+            }

+            sfc.genSpdProtocolDeclarations(name, cName, guid, null);

+            i++;

+        }

+    }

+

+    /**

+     This method initializes jButtonOk	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonOk() {

+        if (jButtonOk == null) {

+            jButtonOk = new JButton();

+            jButtonOk.setText("Ok");

+            jButtonOk.setSize(new java.awt.Dimension(84, 20));

+            jButtonOk.setLocation(new java.awt.Point(316, 486));

+            jButtonOk.addActionListener(this);

+        }

+        return jButtonOk;

+    }

+

+    /**

+     This method initializes jButtonCancel	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButtonCancel() {

+        if (jButtonCancel == null) {

+            jButtonCancel = new JButton();

+            jButtonCancel.setText("Cancel");

+            jButtonCancel.setSize(new java.awt.Dimension(82, 20));

+            jButtonCancel.setLocation(new java.awt.Point(411, 486));

+            jButtonCancel.addActionListener(this);

+        }

+        return jButtonCancel;

+    }

+

+    /**

+     This method initializes jButton	

+     	

+     @return javax.swing.JButton	

+     **/

+    private JButton getJButton() {

+        if (jButton == null) {

+            jButton = new JButton();

+            jButton.setBounds(new java.awt.Rectangle(232, 486, 71, 19));

+            jButton.setText("Insert");

+            jButton.addActionListener(this);

+        }

+        return jButton;

+    }

+} //  @jve:decl-index=0:visual-constraint="11,7"

diff --git a/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/common/ui/StarLabel.java b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/common/ui/StarLabel.java
new file mode 100644
index 0000000..ad19472
--- /dev/null
+++ b/edk2/Tools/Source/PackageEditor/src/org/tianocore/packaging/common/ui/StarLabel.java
@@ -0,0 +1,41 @@
+/** @file

+  Java class StarLabel is used to create star label.

+ 

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+**/

+package org.tianocore.packaging.common.ui;

+

+import javax.swing.JLabel;

+

+/**

+ Derived from JLabel class to have a red star on it.

+  

+ @since PackageEditor 1.0

+**/

+public class StarLabel extends JLabel{

+	/**

+	 * This is the default constructor

+	 */

+	public StarLabel() {

+		super();

+		init();

+	}

+	

+	/**

+	 Create a label with red star * appear on it

+	**/

+	private void init() {

+		this.setText("*");

+		this.setSize(new java.awt.Dimension(10,20));

+		this.setForeground(java.awt.Color.red);

+		this.setFont(new java.awt.Font("DialogInput", java.awt.Font.BOLD, 14));

+		this.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

+	}

+}

diff --git a/edk2/Tools/Source/Prototype/Auto.java b/edk2/Tools/Source/Prototype/Auto.java
new file mode 100644
index 0000000..07d6094
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/Auto.java
@@ -0,0 +1,8 @@
+import java.util.*;

+

+public class Auto

+{

+  public static void main(String args[]) 

+  {

+  }

+}

diff --git a/edk2/Tools/Source/Prototype/Component.java b/edk2/Tools/Source/Prototype/Component.java
new file mode 100644
index 0000000..4e4e3a1
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/Component.java
@@ -0,0 +1,43 @@
+import java.util.*;

+

+public class Component extends Module

+{

+  Component()

+  {

+  }

+  Component(String n)

+  {

+    name=n;

+  }

+  String name;

+

+  // These are the libs we want to build with.

+  public Set<LibInst> buildLibs;

+

+  public String name() { return name; }

+

+  public boolean autoBuild()

+  {

+    // buildLibs must contain a list of libInstances. We need to check that

+    // These libs meet certain criterea.

+    if(!duplicateLibClasses(buildLibs).isEmpty())

+    {

+      // Error: The lib instance implement the same lib twice.

+      return false;

+    }

+    if(! libClassesProduced(buildLibs).containsAll(consumesLibClasses))

+    {

+      // We can not cover the libclasses consumed with these instances.

+      return false;

+    }

+    getConstructorOrder(buildLibs);

+    getDestructorOrder(buildLibs);

+

+    // Get PPI, Protocol, GUID, PCDs from the lib instances. These are all simple unions of

+    // the corresponding sets in the modules. There is no ordering needed.

+    // TODO

+

+    return true;

+  }

+

+}

diff --git a/edk2/Tools/Source/Prototype/DAG.java b/edk2/Tools/Source/Prototype/DAG.java
new file mode 100644
index 0000000..1edad27
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/DAG.java
@@ -0,0 +1,176 @@
+import java.util.*;

+

+// A directed Acyclic Graph class. The main purpose is to provide a set of nodes

+// and the dependency relations between them.  Then ask for a topological sort of

+// the nodes.

+

+public class DAG<Node>

+{

+  // Constructor.

+  DAG()

+  {

+    children = new HashMap<Node,Set<Node>>();

+  }

+

+  public Set<Node> nodes() { return children.keySet(); }

+  public Set<Node> children(Node parent) { return children.get(parent); }

+

+  // Add the relations from a compatible DAG to this one.

+  public void add(DAG<Node> newDag)

+  {

+    for(Node parent : newDag.children.keySet())

+    {

+      children.put(parent, newDag.children(parent));

+    }

+  }

+

+  // The central data structure is a one-to-many map. Each node is 

+  // treated as a parent. It is mapped to a list of its children. Leaf

+  // nodes are also treated as parents and map to an empty list of

+  // children.

+  Map<Node,Set<Node>> children;

+

+  public void remove(Collection<Node> nodes)

+  {

+    // Remove it as a parent

+    for(Node node : nodes)

+    {

+      children.remove(node);

+    }

+

+    for(Set<Node> childlist : children.values())

+    {

+      // Remove it as a child

+      childlist.removeAll(nodes);

+    }

+  }

+

+  // Remove every occurrence of node from the DAG.

+  public void remove(Node node)

+  {

+    // Remove it as a parent

+    children.remove(node);

+

+    for(Set<Node> childlist : children.values())

+    {

+      // Remove it as a child

+      childlist.remove(node);

+    }

+  }

+

+  // Return true iff parent is a direct parent of child.

+  public boolean directDepends(Node parent, Node child)

+  {

+    return children.containsKey(parent) ? 

+           children(parent).contains(child) :

+           false;

+  }

+

+  // Return true iff parent is a direct or indirect parent of child.

+  // This is the transitive closure of the dependency relation.

+  public boolean depends(Node parent, Node child)

+  {

+    if(!children.containsKey(parent))

+    {

+      return false;

+    }

+    if( directDepends(parent, child) )

+    {

+      return true;

+    }

+    else

+    {

+      for(Node descendent : children(parent) )

+      {

+        // Recursively call depends() to compute the transitive closure of

+        // the relation.

+        if(depends(descendent, child))

+        {

+          return true;

+        }

+      }

+      return false;

+    } 

+  }

+

+  // Add a parent child relation to the dag. Fail if there is already

+  // a dependency from the child to the parent. This implies a cycle.

+  // Our invariant is that the DAG must never contain a cycle. That

+  // way it lives up to its name.

+  public void add(Node parent, Node child)

+  {

+    if(depends(child, parent))

+    {

+      System.out.format("Error: There is a cycle from %s to %s.\n", parent, child);

+      return;

+    }

+    if(children.containsKey(parent))

+    {

+      children(parent).add(child);

+    }

+    else

+    {

+      Set<Node> cs = new HashSet<Node>();

+      cs.add(child);

+      children.put(parent, cs);

+    }

+    if(!children.containsKey(child))

+    {

+      children.put(child,new HashSet<Node>());

+    }

+  }

+

+  // Perform a topological sort on the DAG.

+  public List<Node> sort()

+  {

+    // Make an ordered list to hold the topo sort.

+    List<Node> sorted = new LinkedList<Node>();

+

+    // We add the leaves to the beginning of the list until

+    // the sorted list contains all the nodes in the DAG.

+    while(!sorted.containsAll(nodes()))

+    {

+      // Ignoring the ones we have found, what are the leaves of this

+      // DAG?

+      Set<Node> leaves = leaves(sorted);

+      // Put the new leaves at the beginning of the list.

+      sorted.addAll(0, leaves);

+    }

+    return sorted;

+  }

+

+  // Return the set of nodes that have no children. Pretend

+  // the nodes in the exclude list are not present.

+  public Set<Node> leaves(Collection<Node> exclude)

+  {

+    Set<Node> leaves=new HashSet<Node>();

+    for(Node parent : children.keySet())

+    {

+      if(exclude.contains(parent))

+      {

+        continue;

+      }

+      // If the children of parent are a subset of the exclude set,

+      // then parent is a leaf.

+      if(exclude.containsAll(children(parent)))

+      {

+        leaves.add(parent);

+      }

+    }

+    return leaves;

+  }

+

+  // Return the set of nodes that have no children.

+  public Set<Node> leaves()

+  {

+    Set<Node> leaves=new HashSet<Node>();

+    for(Node parent : children.keySet())

+    {

+      if( children(parent).isEmpty())

+      {

+        leaves.add(parent);

+      }

+    }

+    return leaves;

+  }

+}

diff --git a/edk2/Tools/Source/Prototype/Database.java b/edk2/Tools/Source/Prototype/Database.java
new file mode 100644
index 0000000..bc0a7b0
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/Database.java
@@ -0,0 +1,14 @@
+import java.util.*;

+

+public class Database

+{

+  Database()

+  {

+  }

+  Database(String n)

+  {

+    name=n;

+  }

+  public String name;

+  Map<String,Set<Package>> packages;

+}

diff --git a/edk2/Tools/Source/Prototype/GuidDecl.java b/edk2/Tools/Source/Prototype/GuidDecl.java
new file mode 100644
index 0000000..7aa928f
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/GuidDecl.java
@@ -0,0 +1,16 @@
+import java.util.*;

+

+public class GuidDecl

+{

+  GuidDecl()

+  {

+  }

+  GuidDecl(String n)

+  {

+    name=n;

+  }

+  public String name;

+  public String cName;

+  public String guid;

+  public String name() { return name; }

+}

diff --git a/edk2/Tools/Source/Prototype/LibClass.java b/edk2/Tools/Source/Prototype/LibClass.java
new file mode 100644
index 0000000..c49f7dd
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/LibClass.java
@@ -0,0 +1,14 @@
+import java.util.*;

+

+public class LibClass

+{

+  LibClass()

+  {

+  }

+  LibClass(String n)

+  {

+    name=n;

+  }

+  String name;

+  public String name() { return name; }

+}

diff --git a/edk2/Tools/Source/Prototype/LibInst.java b/edk2/Tools/Source/Prototype/LibInst.java
new file mode 100644
index 0000000..3e4dac3
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/LibInst.java
@@ -0,0 +1,22 @@
+import java.util.*;

+

+public class LibInst extends Module

+{

+  LibInst()

+  {

+  }

+  LibInst(String n)

+  {

+    name=n;

+  }

+

+  public Set<LibClass> producesLibClasses;

+

+  public String constructorName, destructorName;

+

+  public boolean autoBuild()

+  {

+    // A simple compile, without link.

+    return true;

+  }

+}

diff --git a/edk2/Tools/Source/Prototype/Module.java b/edk2/Tools/Source/Prototype/Module.java
new file mode 100644
index 0000000..79557f4
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/Module.java
@@ -0,0 +1,178 @@
+import java.util.*;

+

+public class Module

+{

+  Module()

+  {

+  }

+  Module(String n)

+  {

+    name=n;

+  }

+  String name;

+

+  public String name() { return name; }

+

+  public Set<LibClass> consumesLibClasses;

+

+  // The set of packages that this module depends upon.

+  Set<Package> packageDepends;

+  public Set<Package> packageDeps() { return packageDepends; }

+

+  public boolean autoBuild()

+  {

+    // This should be implemented in the derived class.

+    return true;

+  }

+

+  // Make sure that each class in this set of libclasses is declared in one

+  // of the packages that this module depends on.

+  public boolean validateLibClasses(Set<LibClass> classes)

+  {

+    for(LibClass lc : classes)

+    {

+      // Assume we will not find it.

+      boolean found = false;

+

+      for(Package p : packageDepends)

+      {

+        if(p.libClassDecls.contains(lc))

+        {

+          found=true;

+          break;

+        }

+      }

+      if(found == false)

+      {

+        // Error: This LibClass is not found in any of our Packages.

+        return false;

+      }

+    }

+    // Well, we never came up empty handed, so it looks good.

+    return true;

+  }

+

+  public Set<LibClass> libClassesProduced(Collection<LibInst> instances)

+  {

+    // given a set of lib instances, what is the set of lib classes produced?

+

+    Set<LibClass> classes = new HashSet<LibClass>();

+

+    for(LibInst li : instances)

+    {

+      classes.addAll(li.producesLibClasses);

+    }

+    return classes;

+  }

+

+  // Search the given set of lib instance to see if, among them, they

+  // produce the same LibClass more than once.

+  public Set<LibClass> duplicateLibClasses(Set<LibInst> libs)

+  {

+    // Return true iff each class produced is produced only once.

+

+    List<LibClass> classes = new LinkedList<LibClass>();

+    Set<LibClass> dups = new HashSet<LibClass>();

+

+    for(LibInst li : libs)

+    {

+      classes.addAll(li.producesLibClasses);

+    }

+

+    for(LibClass c : classes)

+    {

+      for(LibClass inner : classes)

+      {

+        if(c.equals(inner))

+        {

+          dups.add(c);

+        }

+      }

+    }

+    return dups;

+  }

+

+  public Set<LibInst> getProducers(LibClass lc, Set<LibInst> libs)

+  {

+    // Return the subset of the given libs that produce this LibClass.

+

+    Set<LibInst> producers = new HashSet<LibInst>();

+

+    for(LibInst li : libs)

+    {

+      if(li.producesLibClasses.contains(lc))

+      {

+        producers.add(li);

+      }

+    }

+    return producers;

+  }

+ 

+  // 

+  // The central dependency relationship between library instances is as follows.

+  // A LibInst "A" depends upon LibInst "B" if, and only if, there exists a LibClass

+  // "C" such that A consumes C and B produces C. This is the partial order over which 

+  // we construct a Directed Acyclic Graph (DAG). The DAG can be used to detect

+  // cycles in the depends relation (which are illegal) and it can be used to implement a

+  // topological sort which is a total ordering over LibInstances. This total order on 

+  // lib instances is what is needed in order to call the constructors and destructors

+  // in the proper sequence.

+  //

+  public DAG<LibInst> makeDAG(Set<LibInst> libs)

+  {

+    DAG<LibInst> dag = new DAG<LibInst>();

+

+    if(duplicateLibClasses(libs).size()>0)

+    {

+      System.out.format("Error: The library instances implement at least one "

+        + "library class more than once.\n");

+    }

+

+    for(LibInst consumer : libs)

+    {

+      // Find all the producers for each LC that li consumes. 

+      for(LibClass lc : consumer.consumesLibClasses )

+      {

+        Set<LibInst> producers = getProducers(lc, libs);

+        if(producers.isEmpty())

+        {

+          System.out.format("Error: Unmet dependency libclass:%s .", lc.name() );

+          return null;

+        }

+

+        // There is exactly one lib inst that produces this class.

+        LibInst producer = producers.iterator().next();

+

+        // Now we are ready to add the dependency to the dag. It will flag  

+        // circular dependencies for us.

+        dag.add(consumer, producer);

+      }

+    }

+    return dag;

+  }

+

+  // As you evaluate each node in the graph (starting with the module node), you

+  // must call the constructors for all the child nodes before you call the

+  // constructor for the current node.   

+  public List<LibInst> getConstructorOrder(Set<LibInst> libs)

+  {

+    List<LibInst> rev = new LinkedList<LibInst>();

+

+    for(LibInst li : getDestructorOrder(libs))

+      rev.add(0, li);    

+

+    return rev;

+  }

+

+  // The destructor order is exactly the reverese of the constructor order.

+  // As you evaluate each node in the graph (starting with the module node), you

+  // must call the destructor for the all the parent nodes before calling the

+  // destructors for the current node, and then call the destructors for all the

+  // child nodes. 

+  public List<LibInst> getDestructorOrder(Set<LibInst> libs)

+  {

+    DAG<LibInst> dag = makeDAG(libs);

+

+    return dag.sort();

+  }

+}

diff --git a/edk2/Tools/Source/Prototype/Package.java b/edk2/Tools/Source/Prototype/Package.java
new file mode 100644
index 0000000..dac0802
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/Package.java
@@ -0,0 +1,44 @@
+import java.util.*;

+

+public class Package

+{

+  Package()

+  {

+  }

+  Package(String n)

+  {

+    name=n;

+  }

+  public String name;

+

+  public Set<LibClass>     libClassDecls;

+  public Set<GuidDecl>     guidDecls;

+  public Set<PpiDecl>      ppiDecls;

+  public Set<ProtocolDecl> protocolDecls;

+  public Set<Module>       modules;

+  public Set<Package>      depends;

+

+  public void genBuild()

+  {

+    for(Module m : modules)

+    {

+      m.autoBuild();

+    }

+  }

+

+  // Figure out what this package depends on based on what the modules 

+  // depend on.

+  public void calculateDependencies()

+  {

+    depends = new HashSet<Package>();

+    for(Module m : modules)

+    {

+      depends.addAll(m.packageDeps());

+    }

+  }

+

+  public void makeJar(String name) {};

+

+  public void addModule(Module m) {};

+  public void removeModule(Module m) {};

+}

diff --git a/edk2/Tools/Source/Prototype/PpiDecl.java b/edk2/Tools/Source/Prototype/PpiDecl.java
new file mode 100644
index 0000000..581fb13
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/PpiDecl.java
@@ -0,0 +1,16 @@
+import java.util.*;

+

+public class PpiDecl

+{

+  PpiDecl()

+  {

+  }

+  PpiDecl(String n)

+  {

+    name=n;

+  }

+  public String name;

+  public String cName;

+  public String guid;

+  public String name() { return name; }

+}

diff --git a/edk2/Tools/Source/Prototype/ProtocolDecl.java b/edk2/Tools/Source/Prototype/ProtocolDecl.java
new file mode 100644
index 0000000..62a45e6
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/ProtocolDecl.java
@@ -0,0 +1,16 @@
+import java.util.*;

+

+public class ProtocolDecl

+{

+  ProtocolDecl()

+  {

+  }

+  ProtocolDecl(String n)

+  {

+    name=n;

+  }

+  public String name;

+  public String cName;

+  public String guid;

+  public String name() { return name; }

+}

diff --git a/edk2/Tools/Source/Prototype/TSort.java b/edk2/Tools/Source/Prototype/TSort.java
new file mode 100644
index 0000000..88765e1
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/TSort.java
@@ -0,0 +1,24 @@
+import java.util.*;

+

+public class TSort

+{

+  public static void main(String args[]) 

+  {

+    DAG<String> dag = new DAG<String>();

+    int i;

+

+    if(args.length % 2==1)

+    {

+      System.out.println("Error: Odd number of elements");

+      return;

+    }

+    for(i=0; i< args.length/2; i++)

+    {

+      dag.add(args[i*2], args[i*2+1]);

+      // System.out.println(pair.left);

+      // System.out.println(pair.right);

+    }

+    System.out.println(dag.sort().toString());

+    System.out.println(dag.sort().toString());

+  }

+}

diff --git a/edk2/Tools/Source/Prototype/build.xml b/edk2/Tools/Source/Prototype/build.xml
new file mode 100644
index 0000000..de4cde9
--- /dev/null
+++ b/edk2/Tools/Source/Prototype/build.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="proto" default="all">

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <target name="all">

+    <javac srcdir=".">

+      <compilerarg value="-Xlint"/>

+    </javac>

+    <jar destfile="Prototype.jar"

+      basedir="."

+      includes="*.class"

+      excludes="**/Not this one.class"

+    />

+  </target>

+

+  <target name="clean"/>

+  <target name="cleanall"/>

+</project>

diff --git a/edk2/Tools/Source/SurfaceArea/build.xml b/edk2/Tools/Source/SurfaceArea/build.xml
new file mode 100644
index 0000000..b43d335
--- /dev/null
+++ b/edk2/Tools/Source/SurfaceArea/build.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="all" basedir="." name="SurfaceArea">

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env" />

+  <property name="WORKSPACE" value="${env.WORKSPACE}"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <path id="classpath">

+    <fileset dir="${WORKSPACE}/Tools/Jars">

+      <include name="*.jar"/>

+    </fileset>

+    <fileset dir="${env.XMLBEANS_HOME}/lib">

+      <include name="*.jar"/>

+    </fileset>

+    <pathelement path = "${env.CLASSPATH}"/>

+  </path>

+

+  <target name="init">

+    <uptodate targetfile="${WORKSPACE}/Tools/Jars/SurfaceArea.jar" property="jar.newer">

+      <srcfiles dir="${WORKSPACE}/Tools/XMLSchema" includes="*.xsd"/>

+    </uptodate>

+  </target>

+

+  <!--

+    Generate SurfaceArea.jar and source code 

+    -->

+  <target name="SurfaceArea.jar" depends="init">

+    <java classname="org.apache.xmlbeans.impl.tool.SchemaCompiler">

+      <classpath refid="classpath"/>

+      <arg value="-javasource"/>

+      <arg value="1.5"/>

+      <arg value="-dl"/>

+      <arg value="-out"/>

+      <arg value="${WORKSPACE}/Tools/Jars/SurfaceArea.jar"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsd"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/FDPManifest.xsd"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsdconfig"/>

+    </java>

+  </target>

+  

+  <target name="SurfaceArea.java" depends="init">

+    <antcall target="SurfaceArea.java.clean"/>

+    <java classname="org.apache.xmlbeans.impl.tool.SchemaCompiler">

+      <classpath refid="classpath"/>

+      <arg value="-javasource"/>

+      <arg value="1.5"/>

+      <arg value="-dl"/>

+      <arg value="-srconly"/>

+      <arg value="-src"/>

+      <arg value="${WORKSPACE}/Tools/Source/SurfaceArea"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsd"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/FDPManifest.xsd"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsdconfig"/>

+    </java>

+  </target>

+  

+  <target name="SurfaceArea" depends="init" unless="jar.newer">

+    <antcall target="SurfaceArea.java.clean"/>

+    <java classname="org.apache.xmlbeans.impl.tool.SchemaCompiler">

+      <classpath refid="classpath"/>

+      <arg value="-javasource"/>

+      <arg value="1.5"/>

+      <arg value="-dl"/>

+      <arg value="-src"/>

+      <arg value="${WORKSPACE}/Tools/Source/SurfaceArea"/>

+      <arg value="-out"/>

+      <arg value="${WORKSPACE}/Tools/Jars/SurfaceArea.jar"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsd"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/FDPManifest.xsd"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsdconfig"/>

+    </java>

+  </target>

+  

+  <target name="SurfaceArea.java.clean">

+    <delete includeemptydirs="true">

+      <fileset dir="${WORKSPACE}/Tools/Source/SurfaceArea" includes="**/*" excludes="build.xml"/>

+    </delete>

+  </target>

+

+  <target name="SurfaceArea.jar.clean">

+  </target>

+  

+  <!--

+    Surface Area Description file validation

+    -->

+  <target name="validate">

+    <echo message="Validating ... ${SURFACE_AREA_FILE}"/>

+    <!--

+      java -classpath %cp% org.apache.xmlbeans.impl.tool.InstanceValidator %*

+    -->

+    <copy file="${SURFACE_AREA_FILE}" tofile="${SURFACE_AREA_FILE}.xml"/>

+    <java classname="org.apache.xmlbeans.impl.tool.InstanceValidator" 

+      outputproperty="XMLBEANS_OUTPUT" >

+          

+      <classpath refid="classpath"/>

+      <arg value="-dl"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsd"/>

+      <arg value="${SURFACE_AREA_FILE}.xml"/>

+      

+    </java>   

+

+    <delete file="${SURFACE_AREA_FILE}.xml" quiet="true"/>

+    <echo message="Result ... ${XMLBEANS_OUTPUT}"/>

+  </target>

+  

+  <!--

+    beautify xml file

+    -->

+  <target name="pretty">

+    <echo message="Beautify ... ${SURFACE_AREA_FILE}"/>

+    <!--

+      java -classpath %cp% org.apache.xmlbeans.impl.tool.PrettyPrinter %*

+    -->

+    <java classname="org.apache.xmlbeans.impl.tool.PrettyPrinter" 

+      errorproperty="XMLBEANS_OUTPUT"

+      output="${SURFACE_AREA_FILE}">

+          

+      <classpath refid="classpath"/>

+      <arg value="-indent"/>

+      <arg value="2"/>

+      <arg value="${SURFACE_AREA_FILE}"/>

+      

+    </java>

+

+    <if>

+      <equals arg1="${XMLBEANS_OUTPUT}" arg2=""/>

+      <then>

+        <echo message="Result ... DONE"/>

+      </then>

+      <else>

+        <echo message="Result ... ${XMLBEANS_OUTPUT}"/>

+      </else>

+    </if>

+  </target>

+

+  <!--

+    generate Surface Area template file from schema

+    -->

+  <target name="generate">

+    <echo message="Generating ... ${SURFACE_AREA_FILE}"/>

+    <!--

+      java -classpath %cp% org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator %*

+    -->

+    <java classname="org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator" fork="true"

+      errorproperty="XMLBEANS_OUTPUT" 

+      output="${SURFACE_AREA_FILE}.tmp">

+          

+      <classpath refid="classpath"/>

+      <arg value="-dl"/>

+      <arg value="${WORKSPACE}/Tools/XMLSchema/SurfaceArea.xsd"/>

+      <arg value="-name"/>

+      <arg value="${SURFACE_AREA_ELEMENT}"/>

+      

+    </java>

+

+    <concat destfile="${SURFACE_AREA_FILE}">

+      <header trimleading="yes" filtering="no"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>]]>

+      </header>

+      <fileset file="${SURFACE_AREA_FILE}.tmp"/>

+    </concat>

+    

+    <delete file="${SURFACE_AREA_FILE}.tmp" deleteonexit="true" quiet="true"/>

+    <if>

+      <equals arg1="${XMLBEANS_OUTPUT}" arg2=""/>

+      <then>

+        <echo message="Result ... DONE"/>

+      </then>

+      <else>

+        <echo message="Result ... ${XMLBEANS_OUTPUT}"/>

+      </else>

+    </if>

+  </target>

+

+  <target name="clean" depends="SurfaceArea.java.clean">

+  </target>

+

+  <target name="cleanall" depends="SurfaceArea.jar.clean">

+    <if>

+      <available file="${WORKSPACE}/Tools/Jars/SurfaceArea.jar"/>

+      <then>

+        <echo message="You must manually remove the file: ${WORKSPACE}/Tools/Jars/SurfaceArea.jar"/>

+        <echo message="Java has already loaded the file, and cannot remove it within ANT!"/>

+      </then>

+    </if>

+  </target>

+

+  <target name="all" depends="SurfaceArea">

+  </target>

+

+  <target name="install" depends="SurfaceArea.jar">

+  </target>

+

+</project>  

diff --git a/edk2/Tools/Source/TianoTools/Common/CommonLib.c b/edk2/Tools/Source/TianoTools/Common/CommonLib.c
new file mode 100644
index 0000000..77f49a7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/CommonLib.c
@@ -0,0 +1,508 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CommonLib.c

+

+Abstract:

+

+  Common Library Functions

+ 

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include "CommonLib.h"

+

+VOID

+PeiZeroMem (

+  IN VOID   *Buffer,

+  IN UINTN  Size

+  )

+/*++

+

+Routine Description:

+

+  Set Buffer to zero for Size bytes.

+

+Arguments:

+

+  Buffer  - Memory to set.

+

+  Size    - Number of bytes to set

+

+Returns:

+

+  None

+

+--*/

+{

+  INT8  *Ptr;

+

+  Ptr = Buffer;

+  while (Size--) {

+    *(Ptr++) = 0;

+  }

+}

+

+VOID

+PeiCopyMem (

+  IN VOID   *Destination,

+  IN VOID   *Source,

+  IN UINTN  Length

+  )

+/*++

+

+Routine Description:

+

+  Copy Length bytes from Source to Destination.

+

+Arguments:

+

+  Destination - Target of copy

+

+  Source      - Place to copy from

+

+  Length      - Number of bytes to copy

+

+Returns:

+

+  None

+

+--*/

+{

+  CHAR8 *Destination8;

+  CHAR8 *Source8;

+

+  Destination8  = Destination;

+  Source8       = Source;

+  while (Length--) {

+    *(Destination8++) = *(Source8++);

+  }

+}

+

+VOID

+ZeroMem (

+  IN VOID   *Buffer,

+  IN UINTN  Size

+  )

+{

+  PeiZeroMem (Buffer, Size);

+}

+

+VOID

+CopyMem (

+  IN VOID   *Destination,

+  IN VOID   *Source,

+  IN UINTN  Length

+  )

+{

+  PeiCopyMem (Destination, Source, Length);

+}

+

+INTN

+CompareGuid (

+  IN EFI_GUID     *Guid1,

+  IN EFI_GUID     *Guid2

+  )

+/*++

+

+Routine Description:

+

+  Compares to GUIDs

+

+Arguments:

+

+  Guid1 - guid to compare

+  Guid2 - guid to compare

+

+Returns:

+  =  0  if Guid1 == Guid2

+  != 0  if Guid1 != Guid2 

+

+--*/

+{

+  INT32 *g1;

+  INT32 *g2;

+  INT32 r;

+

+  //

+  // Compare 32 bits at a time

+  //

+  g1  = (INT32 *) Guid1;

+  g2  = (INT32 *) Guid2;

+

+  r   = g1[0] - g2[0];

+  r |= g1[1] - g2[1];

+  r |= g1[2] - g2[2];

+  r |= g1[3] - g2[3];

+

+  return r;

+}

+

+EFI_STATUS

+GetFileImage (

+  IN CHAR8    *InputFileName,

+  OUT CHAR8   **InputFileImage,

+  OUT UINT32  *BytesRead

+  )

+/*++

+

+Routine Description:

+

+  This function opens a file and reads it into a memory buffer.  The function 

+  will allocate the memory buffer and returns the size of the buffer.

+

+Arguments:

+

+  InputFileName     The name of the file to read.

+  InputFileImage    A pointer to the memory buffer.

+  BytesRead         The size of the memory buffer.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_ABORTED              An error occurred.

+  EFI_OUT_OF_RESOURCES     No resource to complete operations.

+

+--*/

+{

+  FILE    *InputFile;

+  UINT32  FileSize;

+

+  //

+  // Verify input parameters.

+  //

+  if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Open the file and copy contents into a memory buffer.

+  //

+  //

+  // Open the file

+  //

+  InputFile = fopen (InputFileName, "rb");

+  if (InputFile == NULL) {

+    printf ("ERROR: Could not open input file \"%s\".\n", InputFileName);

+    return EFI_ABORTED;

+  }

+  //

+  // Go to the end so that we can determine the file size

+  //

+  if (fseek (InputFile, 0, SEEK_END)) {

+    printf ("ERROR: System error reading input file \"%s\".\n", InputFileName);

+    fclose (InputFile);

+    return EFI_ABORTED;

+  }

+  //

+  // Get the file size

+  //

+  FileSize = ftell (InputFile);

+  if (FileSize == -1) {

+    printf ("ERROR: System error parsing input file \"%s\".\n", InputFileName);

+    fclose (InputFile);

+    return EFI_ABORTED;

+  }

+  //

+  // Allocate a buffer

+  //

+  *InputFileImage = malloc (FileSize);

+  if (*InputFileImage == NULL) {

+    fclose (InputFile);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Reset to the beginning of the file

+  //

+  if (fseek (InputFile, 0, SEEK_SET)) {

+    printf ("ERROR: System error reading input file \"%s\".\n", InputFileName);

+    fclose (InputFile);

+    free (*InputFileImage);

+    *InputFileImage = NULL;

+    return EFI_ABORTED;

+  }

+  //

+  // Read all of the file contents.

+  //

+  *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);

+  if (*BytesRead != sizeof (UINT8) * FileSize) {

+    printf ("ERROR: Reading file \"%s\"%i.\n", InputFileName);

+    fclose (InputFile);

+    free (*InputFileImage);

+    *InputFileImage = NULL;

+    return EFI_ABORTED;

+  }

+  //

+  // Close the file

+  //

+  fclose (InputFile);

+

+  return EFI_SUCCESS;

+}

+

+UINT8

+CalculateChecksum8 (

+  IN UINT8        *Buffer,

+  IN UINTN        Size

+  )

+/*++

+  

+Routine Description:

+

+  This function calculates the value needed for a valid UINT8 checksum

+

+Arguments:

+

+  Buffer      Pointer to buffer containing byte data of component.

+  Size        Size of the buffer

+

+Returns:

+

+  The 8 bit checksum value needed.

+

+--*/

+{

+  return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));

+}

+

+UINT8

+CalculateSum8 (

+  IN UINT8  *Buffer,

+  IN UINT32 Size

+  )

+/*++

+  

+Routine Description::

+

+  This function calculates the UINT8 sum for the requested region.

+

+Arguments:

+

+  Buffer      Pointer to buffer containing byte data of component.

+  Size        Size of the buffer

+

+Returns:

+

+  The 8 bit checksum value needed.

+

+--*/

+{

+  UINTN Index;

+  UINT8 Sum;

+

+  Sum = 0;

+

+  //

+  // Perform the byte sum for buffer

+  //

+  for (Index = 0; Index < Size; Index++) {

+    Sum = (UINT8) (Sum + Buffer[Index]);

+  }

+

+  return Sum;

+}

+

+UINT16

+CalculateChecksum16 (

+  IN UINT16       *Buffer,

+  IN UINTN        Size

+  )

+/*++

+  

+Routine Description::

+

+  This function calculates the value needed for a valid UINT16 checksum

+

+Arguments:

+

+  Buffer      Pointer to buffer containing byte data of component.

+  Size        Size of the buffer

+

+Returns:

+

+  The 16 bit checksum value needed.

+

+--*/

+{

+  return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));

+}

+

+UINT16

+CalculateSum16 (

+  IN UINT16       *Buffer,

+  IN UINTN        Size

+  )

+/*++

+  

+Routine Description:

+

+  This function calculates the UINT16 sum for the requested region.

+

+Arguments:

+

+  Buffer      Pointer to buffer containing byte data of component.

+  Size        Size of the buffer

+

+Returns:

+

+  The 16 bit checksum

+

+--*/

+{

+  UINTN   Index;

+  UINT16  Sum;

+

+  Sum = 0;

+

+  //

+  // Perform the word sum for buffer

+  //

+  for (Index = 0; Index < Size; Index++) {

+    Sum = (UINT16) (Sum + Buffer[Index]);

+  }

+

+  return (UINT16) Sum;

+}

+

+EFI_STATUS

+PrintGuid (

+  IN EFI_GUID *Guid

+  )

+/*++

+

+Routine Description:

+

+  This function prints a GUID to STDOUT.

+

+Arguments:

+

+  Guid    Pointer to a GUID to print.

+

+Returns:

+

+  EFI_SUCCESS             The GUID was printed.

+  EFI_INVALID_PARAMETER   The input was NULL.

+

+--*/

+{

+  if (Guid == NULL) {

+    printf ("ERROR: PrintGuid called with a NULL value.\n");

+    return EFI_INVALID_PARAMETER;

+  }

+

+  printf (

+    "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",

+    Guid->Data1,

+    Guid->Data2,

+    Guid->Data3,

+    Guid->Data4[0],

+    Guid->Data4[1],

+    Guid->Data4[2],

+    Guid->Data4[3],

+    Guid->Data4[4],

+    Guid->Data4[5],

+    Guid->Data4[6],

+    Guid->Data4[7]

+    );

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PrintGuidToBuffer (

+  IN EFI_GUID     *Guid,

+  IN OUT UINT8    *Buffer,

+  IN UINT32       BufferLen,

+  IN BOOLEAN      Uppercase

+  )

+/*++

+

+Routine Description:

+

+  This function prints a GUID to a buffer

+

+Arguments:

+

+  Guid      - Pointer to a GUID to print.

+  Buffer    - Pointer to a user-provided buffer to print to

+  BufferLen - Size of the Buffer

+  Uppercase - If use upper case.

+

+Returns:

+

+  EFI_SUCCESS             The GUID was printed.

+  EFI_INVALID_PARAMETER   The input was NULL.

+  EFI_BUFFER_TOO_SMALL    The input buffer was not big enough

+  

+--*/

+{

+  if (Guid == NULL) {

+    printf ("ERROR: PrintGuidToBuffer() called with a NULL value\n");

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {

+    printf ("ERORR: PrintGuidToBuffer() called with invalid buffer size\n");

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  if (Uppercase) {

+    sprintf (

+      Buffer,

+      "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",

+      Guid->Data1,

+      Guid->Data2,

+      Guid->Data3,

+      Guid->Data4[0],

+      Guid->Data4[1],

+      Guid->Data4[2],

+      Guid->Data4[3],

+      Guid->Data4[4],

+      Guid->Data4[5],

+      Guid->Data4[6],

+      Guid->Data4[7]

+      );

+  } else {

+    sprintf (

+      Buffer,

+      "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",

+      Guid->Data1,

+      Guid->Data2,

+      Guid->Data3,

+      Guid->Data4[0],

+      Guid->Data4[1],

+      Guid->Data4[2],

+      Guid->Data4[3],

+      Guid->Data4[4],

+      Guid->Data4[5],

+      Guid->Data4[6],

+      Guid->Data4[7]

+      );

+  }

+

+  return EFI_SUCCESS;

+}

+

+#ifdef __GNUC__

+#ifndef __CYGWIN__

+char *strlwr(char *s)

+{

+  char *p = s;

+  for(;*s;s++) {

+    *s = tolower(*s);

+  }

+  return p;

+}

+#endif

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/CommonLib.h b/edk2/Tools/Source/TianoTools/Common/CommonLib.h
new file mode 100644
index 0000000..80cd883
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/CommonLib.h
@@ -0,0 +1,141 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  CommonLib.h

+

+Abstract:

+

+  Common library assistance routines.

+

+--*/

+

+#ifndef _EFI_COMMON_LIB_H

+#define _EFI_COMMON_LIB_H

+

+/*

+#include "TianoCommon.h"

+#include "TianoCommon.h"

+#include "PeiHob.h"

+*/

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _MAX_PATH

+#define _MAX_PATH 500

+#endif

+

+#define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination

+//

+// Function declarations

+//

+VOID

+PeiZeroMem (

+  IN VOID   *Buffer,

+  IN UINTN  Size

+  )

+;

+

+VOID

+PeiCopyMem (

+  IN VOID   *Destination,

+  IN VOID   *Source,

+  IN UINTN  Length

+  )

+;

+

+VOID

+ZeroMem (

+  IN VOID   *Buffer,

+  IN UINTN  Size

+  )

+;

+

+VOID

+CopyMem (

+  IN VOID   *Destination,

+  IN VOID   *Source,

+  IN UINTN  Length

+  )

+;

+

+INTN

+CompareGuid (

+  IN EFI_GUID     *Guid1,

+  IN EFI_GUID     *Guid2

+  )

+;

+

+EFI_STATUS

+GetFileImage (

+  IN CHAR8    *InputFileName,

+  OUT CHAR8   **InputFileImage,

+  OUT UINT32  *BytesRead

+  )

+;

+

+UINT8

+CalculateChecksum8 (

+  IN UINT8        *Buffer,

+  IN UINTN        Size

+  )

+;

+

+UINT8

+CalculateSum8 (

+  IN UINT8        *Buffer,

+  IN UINTN        Size

+  )

+;

+

+UINT16

+CalculateChecksum16 (

+  IN UINT16       *Buffer,

+  IN UINTN        Size

+  )

+;

+

+UINT16

+CalculateSum16 (

+  IN UINT16       *Buffer,

+  IN UINTN        Size

+  )

+;

+

+EFI_STATUS

+PrintGuid (

+  IN EFI_GUID                     *Guid

+  )

+;

+

+#define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination

+EFI_STATUS

+PrintGuidToBuffer (

+  IN EFI_GUID     *Guid,

+  IN OUT UINT8    *Buffer,

+  IN UINT32       BufferLen,

+  IN BOOLEAN      Uppercase

+  )

+;

+

+#define ASSERT(x) assert(x)

+

+#ifdef __GNUC__

+#define stricmp strcasecmp

+#define strnicmp strncasecmp

+#define strcmpi strcasecmp

+#ifndef __CYGWIN__

+char *strlwr(char *s);

+#endif

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/Crc32.c b/edk2/Tools/Source/TianoTools/Common/Crc32.c
new file mode 100644
index 0000000..4ae5eb4
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/Crc32.c
@@ -0,0 +1,326 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  crc32.c

+

+Abstract:

+

+  CalcuateCrc32 routine.

+  

+--*/

+

+#include <stdlib.h>

+#include "Crc32.h"

+

+UINT32  mCrcTable[256] = {

+  0x00000000,

+  0x77073096,

+  0xEE0E612C,

+  0x990951BA,

+  0x076DC419,

+  0x706AF48F,

+  0xE963A535,

+  0x9E6495A3,

+  0x0EDB8832,

+  0x79DCB8A4,

+  0xE0D5E91E,

+  0x97D2D988,

+  0x09B64C2B,

+  0x7EB17CBD,

+  0xE7B82D07,

+  0x90BF1D91,

+  0x1DB71064,

+  0x6AB020F2,

+  0xF3B97148,

+  0x84BE41DE,

+  0x1ADAD47D,

+  0x6DDDE4EB,

+  0xF4D4B551,

+  0x83D385C7,

+  0x136C9856,

+  0x646BA8C0,

+  0xFD62F97A,

+  0x8A65C9EC,

+  0x14015C4F,

+  0x63066CD9,

+  0xFA0F3D63,

+  0x8D080DF5,

+  0x3B6E20C8,

+  0x4C69105E,

+  0xD56041E4,

+  0xA2677172,

+  0x3C03E4D1,

+  0x4B04D447,

+  0xD20D85FD,

+  0xA50AB56B,

+  0x35B5A8FA,

+  0x42B2986C,

+  0xDBBBC9D6,

+  0xACBCF940,

+  0x32D86CE3,

+  0x45DF5C75,

+  0xDCD60DCF,

+  0xABD13D59,

+  0x26D930AC,

+  0x51DE003A,

+  0xC8D75180,

+  0xBFD06116,

+  0x21B4F4B5,

+  0x56B3C423,

+  0xCFBA9599,

+  0xB8BDA50F,

+  0x2802B89E,

+  0x5F058808,

+  0xC60CD9B2,

+  0xB10BE924,

+  0x2F6F7C87,

+  0x58684C11,

+  0xC1611DAB,

+  0xB6662D3D,

+  0x76DC4190,

+  0x01DB7106,

+  0x98D220BC,

+  0xEFD5102A,

+  0x71B18589,

+  0x06B6B51F,

+  0x9FBFE4A5,

+  0xE8B8D433,

+  0x7807C9A2,

+  0x0F00F934,

+  0x9609A88E,

+  0xE10E9818,

+  0x7F6A0DBB,

+  0x086D3D2D,

+  0x91646C97,

+  0xE6635C01,

+  0x6B6B51F4,

+  0x1C6C6162,

+  0x856530D8,

+  0xF262004E,

+  0x6C0695ED,

+  0x1B01A57B,

+  0x8208F4C1,

+  0xF50FC457,

+  0x65B0D9C6,

+  0x12B7E950,

+  0x8BBEB8EA,

+  0xFCB9887C,

+  0x62DD1DDF,

+  0x15DA2D49,

+  0x8CD37CF3,

+  0xFBD44C65,

+  0x4DB26158,

+  0x3AB551CE,

+  0xA3BC0074,

+  0xD4BB30E2,

+  0x4ADFA541,

+  0x3DD895D7,

+  0xA4D1C46D,

+  0xD3D6F4FB,

+  0x4369E96A,

+  0x346ED9FC,

+  0xAD678846,

+  0xDA60B8D0,

+  0x44042D73,

+  0x33031DE5,

+  0xAA0A4C5F,

+  0xDD0D7CC9,

+  0x5005713C,

+  0x270241AA,

+  0xBE0B1010,

+  0xC90C2086,

+  0x5768B525,

+  0x206F85B3,

+  0xB966D409,

+  0xCE61E49F,

+  0x5EDEF90E,

+  0x29D9C998,

+  0xB0D09822,

+  0xC7D7A8B4,

+  0x59B33D17,

+  0x2EB40D81,

+  0xB7BD5C3B,

+  0xC0BA6CAD,

+  0xEDB88320,

+  0x9ABFB3B6,

+  0x03B6E20C,

+  0x74B1D29A,

+  0xEAD54739,

+  0x9DD277AF,

+  0x04DB2615,

+  0x73DC1683,

+  0xE3630B12,

+  0x94643B84,

+  0x0D6D6A3E,

+  0x7A6A5AA8,

+  0xE40ECF0B,

+  0x9309FF9D,

+  0x0A00AE27,

+  0x7D079EB1,

+  0xF00F9344,

+  0x8708A3D2,

+  0x1E01F268,

+  0x6906C2FE,

+  0xF762575D,

+  0x806567CB,

+  0x196C3671,

+  0x6E6B06E7,

+  0xFED41B76,

+  0x89D32BE0,

+  0x10DA7A5A,

+  0x67DD4ACC,

+  0xF9B9DF6F,

+  0x8EBEEFF9,

+  0x17B7BE43,

+  0x60B08ED5,

+  0xD6D6A3E8,

+  0xA1D1937E,

+  0x38D8C2C4,

+  0x4FDFF252,

+  0xD1BB67F1,

+  0xA6BC5767,

+  0x3FB506DD,

+  0x48B2364B,

+  0xD80D2BDA,

+  0xAF0A1B4C,

+  0x36034AF6,

+  0x41047A60,

+  0xDF60EFC3,

+  0xA867DF55,

+  0x316E8EEF,

+  0x4669BE79,

+  0xCB61B38C,

+  0xBC66831A,

+  0x256FD2A0,

+  0x5268E236,

+  0xCC0C7795,

+  0xBB0B4703,

+  0x220216B9,

+  0x5505262F,

+  0xC5BA3BBE,

+  0xB2BD0B28,

+  0x2BB45A92,

+  0x5CB36A04,

+  0xC2D7FFA7,

+  0xB5D0CF31,

+  0x2CD99E8B,

+  0x5BDEAE1D,

+  0x9B64C2B0,

+  0xEC63F226,

+  0x756AA39C,

+  0x026D930A,

+  0x9C0906A9,

+  0xEB0E363F,

+  0x72076785,

+  0x05005713,

+  0x95BF4A82,

+  0xE2B87A14,

+  0x7BB12BAE,

+  0x0CB61B38,

+  0x92D28E9B,

+  0xE5D5BE0D,

+  0x7CDCEFB7,

+  0x0BDBDF21,

+  0x86D3D2D4,

+  0xF1D4E242,

+  0x68DDB3F8,

+  0x1FDA836E,

+  0x81BE16CD,

+  0xF6B9265B,

+  0x6FB077E1,

+  0x18B74777,

+  0x88085AE6,

+  0xFF0F6A70,

+  0x66063BCA,

+  0x11010B5C,

+  0x8F659EFF,

+  0xF862AE69,

+  0x616BFFD3,

+  0x166CCF45,

+  0xA00AE278,

+  0xD70DD2EE,

+  0x4E048354,

+  0x3903B3C2,

+  0xA7672661,

+  0xD06016F7,

+  0x4969474D,

+  0x3E6E77DB,

+  0xAED16A4A,

+  0xD9D65ADC,

+  0x40DF0B66,

+  0x37D83BF0,

+  0xA9BCAE53,

+  0xDEBB9EC5,

+  0x47B2CF7F,

+  0x30B5FFE9,

+  0xBDBDF21C,

+  0xCABAC28A,

+  0x53B39330,

+  0x24B4A3A6,

+  0xBAD03605,

+  0xCDD70693,

+  0x54DE5729,

+  0x23D967BF,

+  0xB3667A2E,

+  0xC4614AB8,

+  0x5D681B02,

+  0x2A6F2B94,

+  0xB40BBE37,

+  0xC30C8EA1,

+  0x5A05DF1B,

+  0x2D02EF8D

+};

+

+EFI_STATUS

+CalculateCrc32 (

+  IN  UINT8                             *Data,

+  IN  UINTN                             DataSize,

+  IN OUT UINT32                         *CrcOut

+  )

+/*++

+

+Routine Description:

+

+  The CalculateCrc32 routine.

+

+Arguments:

+

+  Data        - The buffer contaning the data to be processed

+  DataSize    - The size of data to be processed

+  CrcOut      - A pointer to the caller allocated UINT32 that on

+                contains the CRC32 checksum of Data

+

+Returns:

+

+  EFI_SUCCESS               - Calculation is successful.

+  EFI_INVALID_PARAMETER     - Data / CrcOut = NULL, or DataSize = 0

+

+--*/

+{

+  UINT32  Crc;

+  UINTN   Index;

+  UINT8   *Ptr;

+

+  if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Crc = 0xffffffff;

+  for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {

+    Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];

+  }

+

+  *CrcOut = Crc ^ 0xffffffff;

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/Common/Crc32.h b/edk2/Tools/Source/TianoTools/Common/Crc32.h
new file mode 100644
index 0000000..0d24004
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/Crc32.h
@@ -0,0 +1,57 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  Crc32.h

+

+Abstract:

+

+  Header file for CalcuateCrc32 routine

+  

+--*/

+

+/*

+#include "TianoCommon.h"

+*/

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _CRC32_H

+#define _CRC32_H

+EFI_STATUS

+CalculateCrc32 (

+  IN  UINT8                             *Data,

+  IN  UINTN                             DataSize,

+  IN OUT UINT32                         *CrcOut

+  )

+;

+

+/*++

+

+Routine Description:

+

+  The CalculateCrc32 routine.

+

+Arguments:

+

+  Data        - The buffer contaning the data to be processed

+  DataSize    - The size of data to be processed

+  CrcOut      - A pointer to the caller allocated UINT32 that on

+                contains the CRC32 checksum of Data

+

+Returns:

+

+  EFI_SUCCESS               - Calculation is successful.

+  EFI_INVALID_PARAMETER     - Data / CrcOut = NULL, or DataSize = 0

+

+--*/

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiCompress.c b/edk2/Tools/Source/TianoTools/Common/EfiCompress.c
new file mode 100644
index 0000000..0a60a46
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiCompress.c
@@ -0,0 +1,1745 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiCompress.c

+

+Abstract:

+

+  Compression routine. The compression algorithm is a mixture of

+  LZ77 and Huffman coding. LZ77 transforms the source data into a

+  sequence of Original Characters and Pointers to repeated strings.

+  This sequence is further divided into Blocks and Huffman codings

+  are applied to each Block.

+

+--*/

+

+/*

+#include "TianoCommon.h"

+*/

+#include "EfiCompress.h"

+

+//

+// Macro Definitions

+//

+typedef INT32 NODE;

+#define UINT8_BIT     8

+#define THRESHOLD     3

+#define INIT_CRC      0

+#define WNDBIT        19

+#define WNDSIZ        (1U << WNDBIT)

+#define MAXMATCH      256

+#define BLKSIZ        (1U << 14)  // 16 * 1024U

+#define PERC_FLAG     0x80000000U

+#define CODE_BIT      16

+#define NIL           0

+#define MAX_HASH_VAL  (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)

+#define HASH(p, c)    ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)

+#define CRCPOLY       0xA001

+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)

+

+//

+// C: the Char&Len Set; P: the Position Set; T: the exTra Set

+//

+#define NC    (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)

+#define CBIT  9

+#define NP    (WNDBIT + 1)

+#define PBIT  5

+#define NT    (CODE_BIT + 3)

+#define TBIT  5

+#if NT > NP

+#define NPT NT

+#else

+#define NPT NP

+#endif

+//

+// Function Prototypes

+//

+STATIC VOID PutDword(IN UINT32 Data);

+

+STATIC

+EFI_STATUS

+AllocateMemory (

+  VOID

+  );

+

+STATIC

+VOID

+FreeMemory (

+  VOID

+  );

+

+STATIC

+VOID

+InitSlide (

+  VOID

+  );

+

+STATIC

+NODE

+Child (

+  IN NODE   NodeQ,

+  IN UINT8  CharC

+  );

+

+STATIC

+VOID

+MakeChild (

+  IN NODE  NodeQ,

+  IN UINT8 CharC,

+  IN NODE  NodeR

+  );

+

+STATIC

+VOID

+Split (

+  IN NODE Old

+  );

+

+STATIC

+VOID

+InsertNode (

+  VOID

+  );

+

+STATIC

+VOID

+DeleteNode (

+  VOID

+  );

+

+STATIC

+VOID

+GetNextMatch (

+  VOID

+  );

+

+STATIC

+EFI_STATUS

+Encode (

+  VOID

+  );

+

+STATIC

+VOID

+CountTFreq (

+  VOID

+  );

+

+STATIC

+VOID

+WritePTLen (

+  IN INT32 Number,

+  IN INT32 nbit,

+  IN INT32 Special

+  );

+

+STATIC

+VOID

+WriteCLen (

+  VOID

+  );

+

+STATIC

+VOID

+EncodeC (

+  IN INT32 Value

+  );

+

+STATIC

+VOID

+EncodeP (

+  IN UINT32 Value

+  );

+

+STATIC

+VOID

+SendBlock (

+  VOID

+  );

+

+STATIC

+VOID

+Output (

+  IN UINT32 c,

+  IN UINT32 p

+  );

+

+STATIC

+VOID

+HufEncodeStart (

+  VOID

+  );

+

+STATIC

+VOID

+HufEncodeEnd (

+  VOID

+  );

+

+STATIC

+VOID

+MakeCrcTable (

+  VOID

+  );

+

+STATIC

+VOID

+PutBits (

+  IN INT32  Number,

+  IN UINT32 Value

+  );

+

+STATIC

+INT32

+FreadCrc (

+  OUT UINT8 *Pointer,

+  IN  INT32 Number

+  );

+

+STATIC

+VOID

+InitPutBits (

+  VOID

+  );

+

+STATIC

+VOID

+CountLen (

+  IN INT32 Index

+  );

+

+STATIC

+VOID

+MakeLen (

+  IN INT32 Root

+  );

+

+STATIC

+VOID

+DownHeap (

+  IN INT32 Index

+  );

+

+STATIC

+VOID

+MakeCode (

+  IN  INT32       Number,

+  IN  UINT8 Len[  ],

+  OUT UINT16 Code[]

+  );

+

+STATIC

+INT32

+MakeTree (

+  IN  INT32            NParm,

+  IN  UINT16  FreqParm[],

+  OUT UINT8   LenParm[ ],

+  OUT UINT16  CodeParm[]

+  );

+

+//

+//  Global Variables

+//

+static UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;

+

+static UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;

+static INT16  mHeap[NC + 1];

+static INT32  mRemainder, mMatchLen, mBitCount, mHeapSize, mN;

+static UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;

+static UINT32 mCompSize, mOrigSize;

+

+static UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],

+  mCFreq[2 * NC - 1], mCTable[4096], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];

+

+static NODE   mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;

+

+//

+// functions

+//

+EFI_STATUS

+Compress (

+  IN      UINT8   *SrcBuffer,

+  IN      UINT32  SrcSize,

+  IN      UINT8   *DstBuffer,

+  IN OUT  UINT32  *DstSize

+  )

+/*++

+

+Routine Description:

+

+  The main compression routine.

+

+Arguments:

+

+  SrcBuffer   - The buffer storing the source data

+  SrcSize     - The size of source data

+  DstBuffer   - The buffer to store the compressed data

+  DstSize     - On input, the size of DstBuffer; On output,

+                the size of the actual compressed data.

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,

+                DstSize contains the size needed.

+  EFI_SUCCESS           - Compression is successful.

+  EFI_OUT_OF_RESOURCES  - No resource to complete function.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Initializations

+  //

+  mBufSiz         = 0;

+  mBuf            = NULL;

+  mText           = NULL;

+  mLevel          = NULL;

+  mChildCount     = NULL;

+  mPosition       = NULL;

+  mParent         = NULL;

+  mPrev           = NULL;

+  mNext           = NULL;

+

+  mSrc            = SrcBuffer;

+  mSrcUpperLimit  = mSrc + SrcSize;

+  mDst            = DstBuffer;

+  mDstUpperLimit  = mDst +*DstSize;

+

+  PutDword (0L);

+  PutDword (0L);

+

+  MakeCrcTable ();

+

+  mOrigSize             = mCompSize = 0;

+  mCrc                  = INIT_CRC;

+

+  //

+  // Compress it

+  //

+  Status = Encode ();

+  if (EFI_ERROR (Status)) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Null terminate the compressed data

+  //

+  if (mDst < mDstUpperLimit) {

+    *mDst++ = 0;

+  }

+  //

+  // Fill in compressed size and original size

+  //

+  mDst = DstBuffer;

+  PutDword (mCompSize + 1);

+  PutDword (mOrigSize);

+

+  //

+  // Return

+  //

+  if (mCompSize + 1 + 8 > *DstSize) {

+    *DstSize = mCompSize + 1 + 8;

+    return EFI_BUFFER_TOO_SMALL;

+  } else {

+    *DstSize = mCompSize + 1 + 8;

+    return EFI_SUCCESS;

+  }

+

+}

+

+STATIC

+VOID

+PutDword (

+  IN UINT32 Data

+  )

+/*++

+

+Routine Description:

+

+  Put a dword to output stream

+  

+Arguments:

+

+  Data    - the dword to put

+  

+Returns: (VOID)

+  

+--*/

+{

+  if (mDst < mDstUpperLimit) {

+    *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);

+  }

+

+  if (mDst < mDstUpperLimit) {

+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);

+  }

+

+  if (mDst < mDstUpperLimit) {

+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);

+  }

+

+  if (mDst < mDstUpperLimit) {

+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);

+  }

+}

+

+STATIC

+EFI_STATUS

+AllocateMemory (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Allocate memory spaces for data structures used in compression process

+  

+Argements: 

+  VOID

+

+Returns:

+

+  EFI_SUCCESS           - Memory is allocated successfully

+  EFI_OUT_OF_RESOURCES  - Allocation fails

+

+--*/

+{

+  UINT32  Index;

+

+  mText = malloc (WNDSIZ * 2 + MAXMATCH);

+  for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {

+    mText[Index] = 0;

+  }

+

+  mLevel      = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));

+  mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));

+  mPosition   = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));

+  mParent     = malloc (WNDSIZ * 2 * sizeof (*mParent));

+  mPrev       = malloc (WNDSIZ * 2 * sizeof (*mPrev));

+  mNext       = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));

+

+  mBufSiz     = BLKSIZ;

+  mBuf        = malloc (mBufSiz);

+  while (mBuf == NULL) {

+    mBufSiz = (mBufSiz / 10U) * 9U;

+    if (mBufSiz < 4 * 1024U) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    mBuf = malloc (mBufSiz);

+  }

+

+  mBuf[0] = 0;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+FreeMemory (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Called when compression is completed to free memory previously allocated.

+  

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  if (mText != NULL) {

+    free (mText);

+  }

+

+  if (mLevel != NULL) {

+    free (mLevel);

+  }

+

+  if (mChildCount != NULL) {

+    free (mChildCount);

+  }

+

+  if (mPosition != NULL) {

+    free (mPosition);

+  }

+

+  if (mParent != NULL) {

+    free (mParent);

+  }

+

+  if (mPrev != NULL) {

+    free (mPrev);

+  }

+

+  if (mNext != NULL) {

+    free (mNext);

+  }

+

+  if (mBuf != NULL) {

+    free (mBuf);

+  }

+

+  return ;

+}

+

+STATIC

+VOID

+InitSlide (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Initialize String Info Log data structures

+  

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  NODE  Index;

+

+  for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) {

+    mLevel[Index]     = 1;

+    mPosition[Index]  = NIL;  /* sentinel */

+  }

+

+  for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) {

+    mParent[Index] = NIL;

+  }

+

+  mAvail = 1;

+  for (Index = 1; Index < WNDSIZ - 1; Index++) {

+    mNext[Index] = (NODE) (Index + 1);

+  }

+

+  mNext[WNDSIZ - 1] = NIL;

+  for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) {

+    mNext[Index] = NIL;

+  }

+}

+

+STATIC

+NODE

+Child (

+  IN NODE  NodeQ,

+  IN UINT8 CharC

+  )

+/*++

+

+Routine Description:

+

+  Find child node given the parent node and the edge character

+  

+Arguments:

+

+  NodeQ       - the parent node

+  CharC       - the edge character

+  

+Returns:

+

+  The child node (NIL if not found)  

+  

+--*/

+{

+  NODE  NodeR;

+

+  NodeR = mNext[HASH (NodeQ, CharC)];

+  //

+  // sentinel

+  //

+  mParent[NIL] = NodeQ;

+  while (mParent[NodeR] != NodeQ) {

+    NodeR = mNext[NodeR];

+  }

+

+  return NodeR;

+}

+

+STATIC

+VOID

+MakeChild (

+  IN NODE  Parent,

+  IN UINT8 CharC,

+  IN NODE  Child

+  )

+/*++

+

+Routine Description:

+

+  Create a new child for a given parent node.

+  

+Arguments:

+

+  Parent       - the parent node

+  CharC   - the edge character

+  Child       - the child node

+  

+Returns: (VOID)

+

+--*/

+{

+  NODE  Node1;

+  NODE  Node2;

+

+  Node1           = (NODE) HASH (Parent, CharC);

+  Node2           = mNext[Node1];

+  mNext[Node1]    = Child;

+  mNext[Child]    = Node2;

+  mPrev[Node2]    = Child;

+  mPrev[Child]    = Node1;

+  mParent[Child]  = Parent;

+  mChildCount[Parent]++;

+}

+

+STATIC

+VOID

+Split (

+  NODE Old

+  )

+/*++

+

+Routine Description:

+

+  Split a node.

+  

+Arguments:

+

+  Old     - the node to split

+  

+Returns: (VOID)

+

+--*/

+{

+  NODE  New;

+  NODE  TempNode;

+

+  New               = mAvail;

+  mAvail            = mNext[New];

+  mChildCount[New]  = 0;

+  TempNode          = mPrev[Old];

+  mPrev[New]        = TempNode;

+  mNext[TempNode]   = New;

+  TempNode          = mNext[Old];

+  mNext[New]        = TempNode;

+  mPrev[TempNode]   = New;

+  mParent[New]      = mParent[Old];

+  mLevel[New]       = (UINT8) mMatchLen;

+  mPosition[New]    = mPos;

+  MakeChild (New, mText[mMatchPos + mMatchLen], Old);

+  MakeChild (New, mText[mPos + mMatchLen], mPos);

+}

+

+STATIC

+VOID

+InsertNode (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Insert string info for current position into the String Info Log

+  

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  NODE  NodeQ;

+  NODE  NodeR;

+  NODE  Index2;

+  NODE  NodeT;

+  UINT8 CharC;

+  UINT8 *t1;

+  UINT8 *t2;

+

+  if (mMatchLen >= 4) {

+    //

+    // We have just got a long match, the target tree

+    // can be located by MatchPos + 1. Travese the tree

+    // from bottom up to get to a proper starting point.

+    // The usage of PERC_FLAG ensures proper node deletion

+    // in DeleteNode() later.

+    //

+    mMatchLen--;

+    NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ);

+    NodeQ = mParent[NodeR];

+    while (NodeQ == NIL) {

+      NodeR = mNext[NodeR];

+      NodeQ = mParent[NodeR];

+    }

+

+    while (mLevel[NodeQ] >= mMatchLen) {

+      NodeR = NodeQ;

+      NodeQ = mParent[NodeQ];

+    }

+

+    NodeT = NodeQ;

+    while (mPosition[NodeT] < 0) {

+      mPosition[NodeT]  = mPos;

+      NodeT             = mParent[NodeT];

+    }

+

+    if (NodeT < WNDSIZ) {

+      mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG);

+    }

+  } else {

+    //

+    // Locate the target tree

+    //

+    NodeQ = (NODE) (mText[mPos] + WNDSIZ);

+    CharC = mText[mPos + 1];

+    NodeR = Child (NodeQ, CharC);

+    if (NodeR == NIL) {

+      MakeChild (NodeQ, CharC, mPos);

+      mMatchLen = 1;

+      return ;

+    }

+

+    mMatchLen = 2;

+  }

+  //

+  // Traverse down the tree to find a match.

+  // Update Position value along the route.

+  // Node split or creation is involved.

+  //

+  for (;;) {

+    if (NodeR >= WNDSIZ) {

+      Index2    = MAXMATCH;

+      mMatchPos = NodeR;

+    } else {

+      Index2    = mLevel[NodeR];

+      mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);

+    }

+

+    if (mMatchPos >= mPos) {

+      mMatchPos -= WNDSIZ;

+    }

+

+    t1  = &mText[mPos + mMatchLen];

+    t2  = &mText[mMatchPos + mMatchLen];

+    while (mMatchLen < Index2) {

+      if (*t1 != *t2) {

+        Split (NodeR);

+        return ;

+      }

+

+      mMatchLen++;

+      t1++;

+      t2++;

+    }

+

+    if (mMatchLen >= MAXMATCH) {

+      break;

+    }

+

+    mPosition[NodeR]  = mPos;

+    NodeQ             = NodeR;

+    NodeR             = Child (NodeQ, *t1);

+    if (NodeR == NIL) {

+      MakeChild (NodeQ, *t1, mPos);

+      return ;

+    }

+

+    mMatchLen++;

+  }

+

+  NodeT           = mPrev[NodeR];

+  mPrev[mPos]     = NodeT;

+  mNext[NodeT]    = mPos;

+  NodeT           = mNext[NodeR];

+  mNext[mPos]     = NodeT;

+  mPrev[NodeT]    = mPos;

+  mParent[mPos]   = NodeQ;

+  mParent[NodeR]  = NIL;

+

+  //

+  // Special usage of 'next'

+  //

+  mNext[NodeR] = mPos;

+

+}

+

+STATIC

+VOID

+DeleteNode (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Delete outdated string info. (The Usage of PERC_FLAG

+  ensures a clean deletion)

+  

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  NODE  NodeQ;

+  NODE  NodeR;

+  NODE  NodeS;

+  NODE  NodeT;

+  NODE  NodeU;

+

+  if (mParent[mPos] == NIL) {

+    return ;

+  }

+

+  NodeR         = mPrev[mPos];

+  NodeS         = mNext[mPos];

+  mNext[NodeR]  = NodeS;

+  mPrev[NodeS]  = NodeR;

+  NodeR         = mParent[mPos];

+  mParent[mPos] = NIL;

+  if (NodeR >= WNDSIZ) {

+    return ;

+  }

+

+  mChildCount[NodeR]--;

+  if (mChildCount[NodeR] > 1) {

+    return ;

+  }

+

+  NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);

+  if (NodeT >= mPos) {

+    NodeT -= WNDSIZ;

+  }

+

+  NodeS = NodeT;

+  NodeQ = mParent[NodeR];

+  NodeU = mPosition[NodeQ];

+  while (NodeU & (UINT32) PERC_FLAG) {

+    NodeU &= (UINT32)~PERC_FLAG;

+    if (NodeU >= mPos) {

+      NodeU -= WNDSIZ;

+    }

+

+    if (NodeU > NodeS) {

+      NodeS = NodeU;

+    }

+

+    mPosition[NodeQ]  = (NODE) (NodeS | WNDSIZ);

+    NodeQ             = mParent[NodeQ];

+    NodeU             = mPosition[NodeQ];

+  }

+

+  if (NodeQ < WNDSIZ) {

+    if (NodeU >= mPos) {

+      NodeU -= WNDSIZ;

+    }

+

+    if (NodeU > NodeS) {

+      NodeS = NodeU;

+    }

+

+    mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG);

+  }

+

+  NodeS           = Child (NodeR, mText[NodeT + mLevel[NodeR]]);

+  NodeT           = mPrev[NodeS];

+  NodeU           = mNext[NodeS];

+  mNext[NodeT]    = NodeU;

+  mPrev[NodeU]    = NodeT;

+  NodeT           = mPrev[NodeR];

+  mNext[NodeT]    = NodeS;

+  mPrev[NodeS]    = NodeT;

+  NodeT           = mNext[NodeR];

+  mPrev[NodeT]    = NodeS;

+  mNext[NodeS]    = NodeT;

+  mParent[NodeS]  = mParent[NodeR];

+  mParent[NodeR]  = NIL;

+  mNext[NodeR]    = mAvail;

+  mAvail          = NodeR;

+}

+

+STATIC

+VOID

+GetNextMatch (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Advance the current position (read in new data if needed).

+  Delete outdated string info. Find a match string for current position.

+

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  INT32 Number;

+

+  mRemainder--;

+  mPos++;

+  if (mPos == WNDSIZ * 2) {

+    memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);

+    Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);

+    mRemainder += Number;

+    mPos = WNDSIZ;

+  }

+

+  DeleteNode ();

+  InsertNode ();

+}

+

+STATIC

+EFI_STATUS

+Encode (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  The main controlling routine for compression process.

+

+Arguments: (VOID)

+

+Returns:

+  

+  EFI_SUCCESS           - The compression is successful

+  EFI_OUT_0F_RESOURCES  - Not enough memory for compression process

+

+--*/

+{

+  EFI_STATUS  Status;

+  INT32       LastMatchLen;

+  NODE        LastMatchPos;

+

+  Status = AllocateMemory ();

+  if (EFI_ERROR (Status)) {

+    FreeMemory ();

+    return Status;

+  }

+

+  InitSlide ();

+

+  HufEncodeStart ();

+

+  mRemainder  = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);

+

+  mMatchLen   = 0;

+  mPos        = WNDSIZ;

+  InsertNode ();

+  if (mMatchLen > mRemainder) {

+    mMatchLen = mRemainder;

+  }

+

+  while (mRemainder > 0) {

+    LastMatchLen  = mMatchLen;

+    LastMatchPos  = mMatchPos;

+    GetNextMatch ();

+    if (mMatchLen > mRemainder) {

+      mMatchLen = mRemainder;

+    }

+

+    if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {

+      //

+      // Not enough benefits are gained by outputting a pointer,

+      // so just output the original character

+      //

+      Output (mText[mPos - 1], 0);

+

+    } else {

+

+      if (LastMatchLen == THRESHOLD) {

+        if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) {

+          Output (mText[mPos - 1], 0);

+          continue;

+        }

+      }

+      //

+      // Outputting a pointer is beneficial enough, do it.

+      //

+      Output (

+        LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),

+        (mPos - LastMatchPos - 2) & (WNDSIZ - 1)

+        );

+      LastMatchLen--;

+      while (LastMatchLen > 0) {

+        GetNextMatch ();

+        LastMatchLen--;

+      }

+

+      if (mMatchLen > mRemainder) {

+        mMatchLen = mRemainder;

+      }

+    }

+  }

+

+  HufEncodeEnd ();

+  FreeMemory ();

+  return EFI_SUCCESS;

+}

+

+STATIC

+VOID

+CountTFreq (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Count the frequencies for the Extra Set

+  

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  INT32 Index;

+  INT32 Index3;

+  INT32 Number;

+  INT32 Count;

+

+  for (Index = 0; Index < NT; Index++) {

+    mTFreq[Index] = 0;

+  }

+

+  Number = NC;

+  while (Number > 0 && mCLen[Number - 1] == 0) {

+    Number--;

+  }

+

+  Index = 0;

+  while (Index < Number) {

+    Index3 = mCLen[Index++];

+    if (Index3 == 0) {

+      Count = 1;

+      while (Index < Number && mCLen[Index] == 0) {

+        Index++;

+        Count++;

+      }

+

+      if (Count <= 2) {

+        mTFreq[0] = (UINT16) (mTFreq[0] + Count);

+      } else if (Count <= 18) {

+        mTFreq[1]++;

+      } else if (Count == 19) {

+        mTFreq[0]++;

+        mTFreq[1]++;

+      } else {

+        mTFreq[2]++;

+      }

+    } else {

+      mTFreq[Index3 + 2]++;

+    }

+  }

+}

+

+STATIC

+VOID

+WritePTLen (

+  IN INT32 Number,

+  IN INT32 nbit,

+  IN INT32 Special

+  )

+/*++

+

+Routine Description:

+

+  Outputs the code length array for the Extra Set or the Position Set.

+  

+Arguments:

+

+  Number       - the number of symbols

+  nbit    - the number of bits needed to represent 'n'

+  Special - the special symbol that needs to be take care of

+  

+Returns: (VOID)

+

+--*/

+{

+  INT32 Index;

+  INT32 Index3;

+

+  while (Number > 0 && mPTLen[Number - 1] == 0) {

+    Number--;

+  }

+

+  PutBits (nbit, Number);

+  Index = 0;

+  while (Index < Number) {

+    Index3 = mPTLen[Index++];

+    if (Index3 <= 6) {

+      PutBits (3, Index3);

+    } else {

+      PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2);

+    }

+

+    if (Index == Special) {

+      while (Index < 6 && mPTLen[Index] == 0) {

+        Index++;

+      }

+

+      PutBits (2, (Index - 3) & 3);

+    }

+  }

+}

+

+STATIC

+VOID

+WriteCLen (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Outputs the code length array for Char&Length Set

+  

+Arguments: (VOID)

+

+Returns: (VOID)

+

+--*/

+{

+  INT32 Index;

+  INT32 Index3;

+  INT32 Number;

+  INT32 Count;

+

+  Number = NC;

+  while (Number > 0 && mCLen[Number - 1] == 0) {

+    Number--;

+  }

+

+  PutBits (CBIT, Number);

+  Index = 0;

+  while (Index < Number) {

+    Index3 = mCLen[Index++];

+    if (Index3 == 0) {

+      Count = 1;

+      while (Index < Number && mCLen[Index] == 0) {

+        Index++;

+        Count++;

+      }

+

+      if (Count <= 2) {

+        for (Index3 = 0; Index3 < Count; Index3++) {

+          PutBits (mPTLen[0], mPTCode[0]);

+        }

+      } else if (Count <= 18) {

+        PutBits (mPTLen[1], mPTCode[1]);

+        PutBits (4, Count - 3);

+      } else if (Count == 19) {

+        PutBits (mPTLen[0], mPTCode[0]);

+        PutBits (mPTLen[1], mPTCode[1]);

+        PutBits (4, 15);

+      } else {

+        PutBits (mPTLen[2], mPTCode[2]);

+        PutBits (CBIT, Count - 20);

+      }

+    } else {

+      PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]);

+    }

+  }

+}

+

+STATIC

+VOID

+EncodeC (

+  IN INT32 Value

+  )

+{

+  PutBits (mCLen[Value], mCCode[Value]);

+}

+

+STATIC

+VOID

+EncodeP (

+  IN UINT32 Value

+  )

+{

+  UINT32  Index;

+  UINT32  NodeQ;

+

+  Index = 0;

+  NodeQ = Value;

+  while (NodeQ) {

+    NodeQ >>= 1;

+    Index++;

+  }

+

+  PutBits (mPTLen[Index], mPTCode[Index]);

+  if (Index > 1) {

+    PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1)));

+  }

+}

+

+STATIC

+VOID

+SendBlock (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Huffman code the block and output it.

+  

+Arguments: 

+  (VOID)

+

+Returns: 

+  (VOID)

+

+--*/

+{

+  UINT32  Index;

+  UINT32  Index2;

+  UINT32  Index3;

+  UINT32  Flags;

+  UINT32  Root;

+  UINT32  Pos;

+  UINT32  Size;

+  Flags = 0;

+

+  Root  = MakeTree (NC, mCFreq, mCLen, mCCode);

+  Size  = mCFreq[Root];

+  PutBits (16, Size);

+  if (Root >= NC) {

+    CountTFreq ();

+    Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);

+    if (Root >= NT) {

+      WritePTLen (NT, TBIT, 3);

+    } else {

+      PutBits (TBIT, 0);

+      PutBits (TBIT, Root);

+    }

+

+    WriteCLen ();

+  } else {

+    PutBits (TBIT, 0);

+    PutBits (TBIT, 0);

+    PutBits (CBIT, 0);

+    PutBits (CBIT, Root);

+  }

+

+  Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);

+  if (Root >= NP) {

+    WritePTLen (NP, PBIT, -1);

+  } else {

+    PutBits (PBIT, 0);

+    PutBits (PBIT, Root);

+  }

+

+  Pos = 0;

+  for (Index = 0; Index < Size; Index++) {

+    if (Index % UINT8_BIT == 0) {

+      Flags = mBuf[Pos++];

+    } else {

+      Flags <<= 1;

+    }

+

+    if (Flags & (1U << (UINT8_BIT - 1))) {

+      EncodeC (mBuf[Pos++] + (1U << UINT8_BIT));

+      Index3 = mBuf[Pos++];

+      for (Index2 = 0; Index2 < 3; Index2++) {

+        Index3 <<= UINT8_BIT;

+        Index3 += mBuf[Pos++];

+      }

+

+      EncodeP (Index3);

+    } else {

+      EncodeC (mBuf[Pos++]);

+    }

+  }

+

+  for (Index = 0; Index < NC; Index++) {

+    mCFreq[Index] = 0;

+  }

+

+  for (Index = 0; Index < NP; Index++) {

+    mPFreq[Index] = 0;

+  }

+}

+

+STATIC

+VOID

+Output (

+  IN UINT32 CharC,

+  IN UINT32 Pos

+  )

+/*++

+

+Routine Description:

+

+  Outputs an Original Character or a Pointer

+

+Arguments:

+

+  CharC     - The original character or the 'String Length' element of a Pointer

+  Pos     - The 'Position' field of a Pointer

+

+Returns: (VOID)

+

+--*/

+{

+  static UINT32 CPos;

+

+  if ((mOutputMask >>= 1) == 0) {

+    mOutputMask = 1U << (UINT8_BIT - 1);

+    //

+    // Check the buffer overflow per outputing UINT8_BIT symbols

+    // which is an Original Character or a Pointer. The biggest

+    // symbol is a Pointer which occupies 5 bytes.

+    //

+    if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) {

+      SendBlock ();

+      mOutputPos = 0;

+    }

+

+    CPos        = mOutputPos++;

+    mBuf[CPos]  = 0;

+  }

+

+  mBuf[mOutputPos++] = (UINT8) CharC;

+  mCFreq[CharC]++;

+  if (CharC >= (1U << UINT8_BIT)) {

+    mBuf[CPos] |= mOutputMask;

+    mBuf[mOutputPos++]  = (UINT8) (Pos >> 24);

+    mBuf[mOutputPos++]  = (UINT8) (Pos >> 16);

+    mBuf[mOutputPos++]  = (UINT8) (Pos >> (UINT8_BIT));

+    mBuf[mOutputPos++]  = (UINT8) Pos;

+    CharC               = 0;

+    while (Pos) {

+      Pos >>= 1;

+      CharC++;

+    }

+

+    mPFreq[CharC]++;

+  }

+}

+

+STATIC

+VOID

+HufEncodeStart (

+  VOID

+  )

+{

+  INT32 Index;

+

+  for (Index = 0; Index < NC; Index++) {

+    mCFreq[Index] = 0;

+  }

+

+  for (Index = 0; Index < NP; Index++) {

+    mPFreq[Index] = 0;

+  }

+

+  mOutputPos = mOutputMask = 0;

+  InitPutBits ();

+  return ;

+}

+

+STATIC

+VOID

+HufEncodeEnd (

+  VOID

+  )

+{

+  SendBlock ();

+

+  //

+  // Flush remaining bits

+  //

+  PutBits (UINT8_BIT - 1, 0);

+

+  return ;

+}

+

+STATIC

+VOID

+MakeCrcTable (

+  VOID

+  )

+{

+  UINT32  Index;

+  UINT32  Index2;

+  UINT32  Temp;

+

+  for (Index = 0; Index <= UINT8_MAX; Index++) {

+    Temp = Index;

+    for (Index2 = 0; Index2 < UINT8_BIT; Index2++) {

+      if (Temp & 1) {

+        Temp = (Temp >> 1) ^ CRCPOLY;

+      } else {

+        Temp >>= 1;

+      }

+    }

+

+    mCrcTable[Index] = (UINT16) Temp;

+  }

+}

+

+STATIC

+VOID

+PutBits (

+  IN INT32  Number,

+  IN UINT32 Value

+  )

+/*++

+

+Routine Description:

+

+  Outputs rightmost n bits of x

+

+Arguments:

+

+  Number   - the rightmost n bits of the data is used

+  x   - the data 

+

+Returns: (VOID)

+

+--*/

+{

+  UINT8 Temp;

+

+  while (Number >= mBitCount) {

+    //

+    // Number -= mBitCount should never equal to 32

+    //

+    Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount)));

+    if (mDst < mDstUpperLimit) {

+      *mDst++ = Temp;

+    }

+

+    mCompSize++;

+    mSubBitBuf  = 0;

+    mBitCount   = UINT8_BIT;

+  }

+

+  mSubBitBuf |= Value << (mBitCount -= Number);

+}

+

+STATIC

+INT32

+FreadCrc (

+  OUT UINT8 *Pointer,

+  IN  INT32 Number

+  )

+/*++

+

+Routine Description:

+

+  Read in source data

+  

+Arguments:

+

+  Pointer   - the buffer to hold the data

+  Number   - number of bytes to read

+

+Returns:

+

+  number of bytes actually read

+  

+--*/

+{

+  INT32 Index;

+

+  for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) {

+    *Pointer++ = *mSrc++;

+  }

+

+  Number = Index;

+

+  Pointer -= Number;

+  mOrigSize += Number;

+  Index--;

+  while (Index >= 0) {

+    UPDATE_CRC (*Pointer++);

+    Index--;

+  }

+

+  return Number;

+}

+

+STATIC

+VOID

+InitPutBits (

+  VOID

+  )

+{

+  mBitCount   = UINT8_BIT;

+  mSubBitBuf  = 0;

+}

+

+STATIC

+VOID

+CountLen (

+  IN INT32 Index

+  )

+/*++

+

+Routine Description:

+

+  Count the number of each code length for a Huffman tree.

+  

+Arguments:

+

+  Index   - the top node

+  

+Returns: (VOID)

+

+--*/

+{

+  static INT32  Depth = 0;

+

+  if (Index < mN) {

+    mLenCnt[(Depth < 16) ? Depth : 16]++;

+  } else {

+    Depth++;

+    CountLen (mLeft[Index]);

+    CountLen (mRight[Index]);

+    Depth--;

+  }

+}

+

+STATIC

+VOID

+MakeLen (

+  IN INT32 Root

+  )

+/*++

+

+Routine Description:

+

+  Create code length array for a Huffman tree

+  

+Arguments:

+

+  Root   - the root of the tree

+  

+Returns:

+

+  VOID

+

+--*/

+{

+  INT32   Index;

+  INT32   Index3;

+  UINT32  Cum;

+

+  for (Index = 0; Index <= 16; Index++) {

+    mLenCnt[Index] = 0;

+  }

+

+  CountLen (Root);

+

+  //

+  // Adjust the length count array so that

+  // no code will be generated longer than its designated length

+  //

+  Cum = 0;

+  for (Index = 16; Index > 0; Index--) {

+    Cum += mLenCnt[Index] << (16 - Index);

+  }

+

+  while (Cum != (1U << 16)) {

+    mLenCnt[16]--;

+    for (Index = 15; Index > 0; Index--) {

+      if (mLenCnt[Index] != 0) {

+        mLenCnt[Index]--;

+        mLenCnt[Index + 1] += 2;

+        break;

+      }

+    }

+

+    Cum--;

+  }

+

+  for (Index = 16; Index > 0; Index--) {

+    Index3 = mLenCnt[Index];

+    Index3--;

+    while (Index3 >= 0) {

+      mLen[*mSortPtr++] = (UINT8) Index;

+      Index3--;

+    }

+  }

+}

+

+STATIC

+VOID

+DownHeap (

+  IN INT32 Index

+  )

+{

+  INT32 Index2;

+  INT32 Index3;

+

+  //

+  // priority queue: send Index-th entry down heap

+  //

+  Index3  = mHeap[Index];

+  Index2  = 2 * Index;

+  while (Index2 <= mHeapSize) {

+    if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) {

+      Index2++;

+    }

+

+    if (mFreq[Index3] <= mFreq[mHeap[Index2]]) {

+      break;

+    }

+

+    mHeap[Index]  = mHeap[Index2];

+    Index         = Index2;

+    Index2        = 2 * Index;

+  }

+

+  mHeap[Index] = (INT16) Index3;

+}

+

+STATIC

+VOID

+MakeCode (

+  IN  INT32       Number,

+  IN  UINT8 Len[  ],

+  OUT UINT16 Code[]

+  )

+/*++

+

+Routine Description:

+

+  Assign code to each symbol based on the code length array

+  

+Arguments:

+

+  Number     - number of symbols

+  Len   - the code length array

+  Code  - stores codes for each symbol

+

+Returns: (VOID)

+

+--*/

+{

+  INT32   Index;

+  UINT16  Start[18];

+

+  Start[1] = 0;

+  for (Index = 1; Index <= 16; Index++) {

+    Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1);

+  }

+

+  for (Index = 0; Index < Number; Index++) {

+    Code[Index] = Start[Len[Index]]++;

+  }

+}

+

+STATIC

+INT32

+MakeTree (

+  IN  INT32            NParm,

+  IN  UINT16  FreqParm[],

+  OUT UINT8   LenParm[ ],

+  OUT UINT16  CodeParm[]

+  )

+/*++

+

+Routine Description:

+

+  Generates Huffman codes given a frequency distribution of symbols

+  

+Arguments:

+

+  NParm    - number of symbols

+  FreqParm - frequency of each symbol

+  LenParm  - code length for each symbol

+  CodeParm - code for each symbol

+  

+Returns:

+

+  Root of the Huffman tree.

+  

+--*/

+{

+  INT32 Index;

+  INT32 Index2;

+  INT32 Index3;

+  INT32 Avail;

+

+  //

+  // make tree, calculate len[], return root

+  //

+  mN        = NParm;

+  mFreq     = FreqParm;

+  mLen      = LenParm;

+  Avail     = mN;

+  mHeapSize = 0;

+  mHeap[1]  = 0;

+  for (Index = 0; Index < mN; Index++) {

+    mLen[Index] = 0;

+    if (mFreq[Index]) {

+      mHeapSize++;

+      mHeap[mHeapSize] = (INT16) Index;

+    }

+  }

+

+  if (mHeapSize < 2) {

+    CodeParm[mHeap[1]] = 0;

+    return mHeap[1];

+  }

+

+  for (Index = mHeapSize / 2; Index >= 1; Index--) {

+    //

+    // make priority queue

+    //

+    DownHeap (Index);

+  }

+

+  mSortPtr = CodeParm;

+  do {

+    Index = mHeap[1];

+    if (Index < mN) {

+      *mSortPtr++ = (UINT16) Index;

+    }

+

+    mHeap[1] = mHeap[mHeapSize--];

+    DownHeap (1);

+    Index2 = mHeap[1];

+    if (Index2 < mN) {

+      *mSortPtr++ = (UINT16) Index2;

+    }

+

+    Index3        = Avail++;

+    mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]);

+    mHeap[1]      = (INT16) Index3;

+    DownHeap (1);

+    mLeft[Index3]   = (UINT16) Index;

+    mRight[Index3]  = (UINT16) Index2;

+  } while (mHeapSize > 1);

+

+  mSortPtr = CodeParm;

+  MakeLen (Index3);

+  MakeCode (NParm, LenParm, CodeParm);

+

+  //

+  // return root

+  //

+  return Index3;

+}

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiCompress.h b/edk2/Tools/Source/TianoTools/Common/EfiCompress.h
new file mode 100644
index 0000000..a129f2c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiCompress.h
@@ -0,0 +1,68 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiCompress.h

+

+Abstract:

+

+  Header file for compression routine

+  

+--*/

+

+#include <string.h>

+#include <stdlib.h>

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _EFICOMPRESS_H

+#define _EFICOMPRESS_H

+EFI_STATUS

+Compress (

+  IN      UINT8   *SrcBuffer,

+  IN      UINT32  SrcSize,

+  IN      UINT8   *DstBuffer,

+  IN OUT  UINT32  *DstSize

+  )

+;

+

+/*++

+

+Routine Description:

+

+  The compression routine.

+

+Arguments:

+

+  SrcBuffer   - The buffer storing the source data

+  SrcSize     - The size of source data

+  DstBuffer   - The buffer to store the compressed data

+  DstSize     - On input, the size of DstBuffer; On output,

+                the size of the actual compressed data.

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,

+                DstSize contains the size needed.

+  EFI_SUCCESS           - Compression is successful.

+

+--*/

+typedef

+EFI_STATUS

+(*COMPRESS_FUNCTION) (

+  IN      UINT8   *SrcBuffer,

+  IN      UINT32  SrcSize,

+  IN      UINT8   *DstBuffer,

+  IN OUT  UINT32  *DstSize

+  );

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiCustomizedCompress.h b/edk2/Tools/Source/TianoTools/Common/EfiCustomizedCompress.h
new file mode 100644
index 0000000..4953e42
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiCustomizedCompress.h
@@ -0,0 +1,141 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  EfiCustomizedCompress.h

+

+Abstract:

+

+  Header file for Customized compression routine

+  

+--*/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _EFICUSTOMIZEDCOMPRESS_H

+#define _EFICUSTOMIZEDCOMPRESS_H

+EFI_STATUS

+SetCustomizedCompressionType (

+  IN  CHAR8   *Type

+  )

+;

+

+/*++

+

+Routine Description:

+

+The implementation of Customized SetCompressionType().

+

+Arguments:

+  Type        - The type if compression.

+    

+Returns:

+    

+  EFI_SUCCESS           - The type has been set.

+  EFI_UNSUPPORTED       - This type is unsupported.

+

+    

+--*/

+EFI_STATUS

+CustomizedGetInfo (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  OUT     UINT32  *DstSize,

+  OUT     UINT32  *ScratchSize

+  )

+;

+

+/*++

+

+Routine Description:

+

+  The implementation of Customized GetInfo().

+

+Arguments:

+

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  DstSize     - The size of destination buffer.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  EFI_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+EFI_STATUS

+CustomizedDecompress (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  IN OUT  VOID    *Destination,

+  IN      UINT32  DstSize,

+  IN OUT  VOID    *Scratch,

+  IN      UINT32  ScratchSize

+  )

+;

+

+/*++

+

+Routine Description:

+

+  The implementation of Customized Decompress().

+

+Arguments:

+

+  This        - The protocol instance pointer

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  Destination - The destination buffer to store the decompressed data

+  DstSize     - The size of destination buffer.

+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - Decompression is successfull

+  EFI_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+EFI_STATUS

+CustomizedCompress (

+  IN      UINT8   *SrcBuffer,

+  IN      UINT32  SrcSize,

+  IN      UINT8   *DstBuffer,

+  IN OUT  UINT32  *DstSize

+  )

+;

+

+/*++

+

+Routine Description:

+

+  The Customized compression routine.

+

+Arguments:

+

+  SrcBuffer   - The buffer storing the source data

+  SrcSize     - The size of source data

+  DstBuffer   - The buffer to store the compressed data

+  DstSize     - On input, the size of DstBuffer; On output,

+                the size of the actual compressed data.

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,

+                          DstSize contains the size needed.

+  EFI_SUCCESS           - Compression is successful.

+

+--*/

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiDecompress.c b/edk2/Tools/Source/TianoTools/Common/EfiDecompress.c
new file mode 100644
index 0000000..288c425
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiDecompress.c
@@ -0,0 +1,790 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  EfiDecompress.c

+

+Abstract:

+

+  Decompressor. Algorithm Ported from OPSD code (Decomp.asm)

+  

+--*/

+

+#include "EfiDecompress.h"

+

+//

+// Decompression algorithm begins here

+//

+#define BITBUFSIZ 32

+#define MAXMATCH  256

+#define THRESHOLD 3

+#define CODE_BIT  16

+#define BAD_TABLE - 1

+

+//

+// C: Char&Len Set; P: Position Set; T: exTra Set

+//

+#define NC    (0xff + MAXMATCH + 2 - THRESHOLD)

+#define CBIT  9

+#define PBIT  5

+#define TBIT  5

+#define MAXNP ((1U << PBIT) - 1)

+#define NT    (CODE_BIT + 3)

+#if NT > MAXNP

+#define NPT NT

+#else

+#define NPT MAXNP

+#endif

+

+typedef struct {

+  UINT8   *mSrcBase;  // Starting address of compressed data

+  UINT8   *mDstBase;  // Starting address of decompressed data

+  UINT32  mOutBuf;

+  UINT32  mInBuf;

+

+  UINT16  mBitCount;

+  UINT32  mBitBuf;

+  UINT32  mSubBitBuf;

+  UINT16  mBlockSize;

+  UINT32  mCompSize;

+  UINT32  mOrigSize;

+

+  UINT16  mBadTableFlag;

+

+  UINT16  mLeft[2 * NC - 1];

+  UINT16  mRight[2 * NC - 1];

+  UINT8   mCLen[NC];

+  UINT8   mPTLen[NPT];

+  UINT16  mCTable[4096];

+  UINT16  mPTTable[256];

+} SCRATCH_DATA;

+

+STATIC

+VOID

+FillBuf (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+/*++

+

+Routine Description:

+

+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.

+

+Arguments:

+

+  Sd        - The global scratch data

+  NumOfBit  - The number of bits to shift and read.

+

+Returns: (VOID)

+

+--*/

+{

+  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);

+

+  while (NumOfBits > Sd->mBitCount) {

+

+    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));

+

+    if (Sd->mCompSize > 0) {

+      //

+      // Get 1 byte into SubBitBuf

+      //

+      Sd->mCompSize--;

+      Sd->mSubBitBuf  = 0;

+      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];

+      Sd->mBitCount   = 8;

+

+    } else {

+      //

+      // No more bits from the source, just pad zero bit.

+      //

+      Sd->mSubBitBuf  = 0;

+      Sd->mBitCount   = 8;

+

+    }

+  }

+

+  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);

+  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;

+}

+

+STATIC

+UINT32

+GetBits (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+/*++

+

+Routine Description:

+

+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent 

+  NumOfBits of bits from source. Returns NumOfBits of bits that are 

+  popped out.

+

+Arguments:

+

+  Sd            - The global scratch data.

+  NumOfBits     - The number of bits to pop and read.

+

+Returns:

+

+  The bits that are popped out.

+

+--*/

+{

+  UINT32  OutBits;

+

+  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));

+

+  FillBuf (Sd, NumOfBits);

+

+  return OutBits;

+}

+

+STATIC

+UINT16

+MakeTable (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfChar,

+  IN  UINT8         *BitLen,

+  IN  UINT16        TableBits,

+  OUT UINT16        *Table

+  )

+/*++

+

+Routine Description:

+

+  Creates Huffman Code mapping table according to code length array.

+

+Arguments:

+

+  Sd        - The global scratch data

+  NumOfChar - Number of symbols in the symbol set

+  BitLen    - Code length array

+  TableBits - The width of the mapping table

+  Table     - The table

+  

+Returns:

+  

+  0         - OK.

+  BAD_TABLE - The table is corrupted.

+

+--*/

+{

+  UINT16  Count[17];

+  UINT16  Weight[17];

+  UINT16  Start[18];

+  UINT16  *Pointer;

+  UINT16  Index3;

+  UINT16  Index;

+  UINT16  Len;

+  UINT16  Char;

+  UINT16  JuBits;

+  UINT16  Avail;

+  UINT16  NextCode;

+  UINT16  Mask;

+

+  for (Index = 1; Index <= 16; Index++) {

+    Count[Index] = 0;

+  }

+

+  for (Index = 0; Index < NumOfChar; Index++) {

+    Count[BitLen[Index]]++;

+  }

+

+  Start[1] = 0;

+

+  for (Index = 1; Index <= 16; Index++) {

+    Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));

+  }

+

+  if (Start[17] != 0) {

+    /*(1U << 16)*/

+    return (UINT16) BAD_TABLE;

+  }

+

+  JuBits = (UINT16) (16 - TableBits);

+

+  for (Index = 1; Index <= TableBits; Index++) {

+    Start[Index] >>= JuBits;

+    Weight[Index] = (UINT16) (1U << (TableBits - Index));

+  }

+

+  while (Index <= 16) {

+    Weight[Index++] = (UINT16) (1U << (16 - Index));

+  }

+

+  Index = (UINT16) (Start[TableBits + 1] >> JuBits);

+

+  if (Index != 0) {

+    Index3 = (UINT16) (1U << TableBits);

+    while (Index != Index3) {

+      Table[Index++] = 0;

+    }

+  }

+

+  Avail = NumOfChar;

+  Mask  = (UINT16) (1U << (15 - TableBits));

+

+  for (Char = 0; Char < NumOfChar; Char++) {

+

+    Len = BitLen[Char];

+    if (Len == 0) {

+      continue;

+    }

+

+    NextCode = (UINT16) (Start[Len] + Weight[Len]);

+

+    if (Len <= TableBits) {

+

+      for (Index = Start[Len]; Index < NextCode; Index++) {

+        Table[Index] = Char;

+      }

+

+    } else {

+

+      Index3  = Start[Len];

+      Pointer = &Table[Index3 >> JuBits];

+      Index   = (UINT16) (Len - TableBits);

+

+      while (Index != 0) {

+        if (*Pointer == 0) {

+          Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;

+          *Pointer = Avail++;

+        }

+

+        if (Index3 & Mask) {

+          Pointer = &Sd->mRight[*Pointer];

+        } else {

+          Pointer = &Sd->mLeft[*Pointer];

+        }

+

+        Index3 <<= 1;

+        Index--;

+      }

+

+      *Pointer = Char;

+

+    }

+

+    Start[Len] = NextCode;

+  }

+  //

+  // Succeeds

+  //

+  return 0;

+}

+

+STATIC

+UINT32

+DecodeP (

+  IN  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Decodes a position value.

+

+Arguments:

+

+  Sd      - the global scratch data

+

+Returns:

+

+  The position value decoded.

+

+--*/

+{

+  UINT16  Val;

+  UINT32  Mask;

+  UINT32  Pos;

+

+  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+

+  if (Val >= MAXNP) {

+    Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+    do {

+

+      if (Sd->mBitBuf & Mask) {

+        Val = Sd->mRight[Val];

+      } else {

+        Val = Sd->mLeft[Val];

+      }

+

+      Mask >>= 1;

+    } while (Val >= MAXNP);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mPTLen[Val]);

+

+  Pos = Val;

+  if (Val > 1) {

+    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));

+  }

+

+  return Pos;

+}

+

+STATIC

+UINT16

+ReadPTLen (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        nn,

+  IN  UINT16        nbit,

+  IN  UINT16        Special

+  )

+/*++

+

+Routine Description:

+

+  Reads code lengths for the Extra Set or the Position Set

+

+Arguments:

+

+  Sd        - The global scratch data

+  nn        - Number of symbols

+  nbit      - Number of bits needed to represent nn

+  Special   - The special symbol that needs to be taken care of 

+

+Returns:

+

+  0         - OK.

+  BAD_TABLE - Table is corrupted.

+

+--*/

+{

+  UINT16  Number;

+  UINT16  CharC;

+  UINT16  Index;

+  UINT32  Mask;

+

+  Number = (UINT16) GetBits (Sd, nbit);

+

+  if (Number == 0) {

+    CharC = (UINT16) GetBits (Sd, nbit);

+

+    for (Index = 0; Index < 256; Index++) {

+      Sd->mPTTable[Index] = CharC;

+    }

+

+    for (Index = 0; Index < nn; Index++) {

+      Sd->mPTLen[Index] = 0;

+    }

+

+    return 0;

+  }

+

+  Index = 0;

+

+  while (Index < Number) {

+

+    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));

+

+    if (CharC == 7) {

+      Mask = 1U << (BITBUFSIZ - 1 - 3);

+      while (Mask & Sd->mBitBuf) {

+        Mask >>= 1;

+        CharC += 1;

+      }

+    }

+

+    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));

+

+    Sd->mPTLen[Index++] = (UINT8) CharC;

+

+    if (Index == Special) {

+      CharC = (UINT16) GetBits (Sd, 2);

+      CharC--;

+      while ((INT16) (CharC) >= 0) {

+        Sd->mPTLen[Index++] = 0;

+        CharC--;

+      }

+    }

+  }

+

+  while (Index < nn) {

+    Sd->mPTLen[Index++] = 0;

+  }

+

+  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);

+}

+

+STATIC

+VOID

+ReadCLen (

+  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Reads code lengths for Char&Len Set.

+

+Arguments:

+

+  Sd    - the global scratch data

+

+Returns: (VOID)

+

+--*/

+{

+  UINT16  Number;

+  UINT16  CharC;

+  UINT16  Index;

+  UINT32  Mask;

+

+  Number = (UINT16) GetBits (Sd, CBIT);

+

+  if (Number == 0) {

+    CharC = (UINT16) GetBits (Sd, CBIT);

+

+    for (Index = 0; Index < NC; Index++) {

+      Sd->mCLen[Index] = 0;

+    }

+

+    for (Index = 0; Index < 4096; Index++) {

+      Sd->mCTable[Index] = CharC;

+    }

+

+    return ;

+  }

+

+  Index = 0;

+  while (Index < Number) {

+

+    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+    if (CharC >= NT) {

+      Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+      do {

+

+        if (Mask & Sd->mBitBuf) {

+          CharC = Sd->mRight[CharC];

+        } else {

+          CharC = Sd->mLeft[CharC];

+        }

+

+        Mask >>= 1;

+

+      } while (CharC >= NT);

+    }

+    //

+    // Advance what we have read

+    //

+    FillBuf (Sd, Sd->mPTLen[CharC]);

+

+    if (CharC <= 2) {

+

+      if (CharC == 0) {

+        CharC = 1;

+      } else if (CharC == 1) {

+        CharC = (UINT16) (GetBits (Sd, 4) + 3);

+      } else if (CharC == 2) {

+        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);

+      }

+

+      CharC--;

+      while ((INT16) (CharC) >= 0) {

+        Sd->mCLen[Index++] = 0;

+        CharC--;

+      }

+

+    } else {

+

+      Sd->mCLen[Index++] = (UINT8) (CharC - 2);

+

+    }

+  }

+

+  while (Index < NC) {

+    Sd->mCLen[Index++] = 0;

+  }

+

+  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);

+

+  return ;

+}

+

+STATIC

+UINT16

+DecodeC (

+  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Decode a character/length value.

+

+Arguments:

+

+  Sd    - The global scratch data.

+

+Returns:

+

+  The value decoded.

+

+--*/

+{

+  UINT16  Index2;

+  UINT32  Mask;

+

+  if (Sd->mBlockSize == 0) {

+    //

+    // Starting a new block

+    //

+    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);

+    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+

+    ReadCLen (Sd);

+

+    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, PBIT, (UINT16) (-1));

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+  }

+

+  Sd->mBlockSize--;

+  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];

+

+  if (Index2 >= NC) {

+    Mask = 1U << (BITBUFSIZ - 1 - 12);

+

+    do {

+      if (Sd->mBitBuf & Mask) {

+        Index2 = Sd->mRight[Index2];

+      } else {

+        Index2 = Sd->mLeft[Index2];

+      }

+

+      Mask >>= 1;

+    } while (Index2 >= NC);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mCLen[Index2]);

+

+  return Index2;

+}

+

+STATIC

+VOID

+Decode (

+  SCRATCH_DATA  *Sd

+  )

+/*++

+

+Routine Description:

+

+  Decode the source data and put the resulting data into the destination buffer.

+

+Arguments:

+

+  Sd            - The global scratch data

+

+Returns: (VOID)

+

+ --*/

+{

+  UINT16  BytesRemain;

+  UINT32  DataIdx;

+  UINT16  CharC;

+

+  BytesRemain = (UINT16) (-1);

+

+  DataIdx     = 0;

+

+  for (;;) {

+    CharC = DecodeC (Sd);

+    if (Sd->mBadTableFlag != 0) {

+      return ;

+    }

+

+    if (CharC < 256) {

+      //

+      // Process an Original character

+      //

+      Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;

+      if (Sd->mOutBuf >= Sd->mOrigSize) {

+        return ;

+      }

+

+    } else {

+      //

+      // Process a Pointer

+      //

+      CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));

+

+      BytesRemain = CharC;

+

+      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;

+

+      BytesRemain--;

+      while ((INT16) (BytesRemain) >= 0) {

+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];

+        if (Sd->mOutBuf >= Sd->mOrigSize) {

+          return ;

+        }

+

+        BytesRemain--;

+      }

+    }

+  }

+

+  return ;

+}

+

+EFI_STATUS

+GetInfo (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  OUT     UINT32  *DstSize,

+  OUT     UINT32  *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  DstSize     - The size of destination buffer.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  EFI_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  UINT8 *Src;

+

+  *ScratchSize  = sizeof (SCRATCH_DATA);

+

+  Src           = Source;

+  if (SrcSize < 8) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+Decompress (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  IN OUT  VOID    *Destination,

+  IN      UINT32  DstSize,

+  IN OUT  VOID    *Scratch,

+  IN      UINT32  ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  This        - The protocol instance pointer

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  Destination - The destination buffer to store the decompressed data

+  DstSize     - The size of destination buffer.

+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - Decompression is successfull

+  EFI_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+{

+  UINT32        Index;

+  UINT32        CompSize;

+  UINT32        OrigSize;

+  EFI_STATUS    Status;

+  SCRATCH_DATA  *Sd;

+  UINT8         *Src;

+  UINT8         *Dst;

+

+  Status  = EFI_SUCCESS;

+  Src     = Source;

+  Dst     = Destination;

+

+  if (ScratchSize < sizeof (SCRATCH_DATA)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Sd = (SCRATCH_DATA *) Scratch;

+

+  if (SrcSize < 8) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);

+  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);

+

+  if (SrcSize < CompSize + 8) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (DstSize != OrigSize) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Src = Src + 8;

+

+  for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {

+    ((UINT8 *) Sd)[Index] = 0;

+  }

+

+  Sd->mSrcBase  = Src;

+  Sd->mDstBase  = Dst;

+  Sd->mCompSize = CompSize;

+  Sd->mOrigSize = OrigSize;

+

+  //

+  // Fill the first BITBUFSIZ bits

+  //

+  FillBuf (Sd, BITBUFSIZ);

+

+  //

+  // Decompress it

+  //

+  Decode (Sd);

+

+  if (Sd->mBadTableFlag != 0) {

+    //

+    // Something wrong with the source

+    //

+    Status = EFI_INVALID_PARAMETER;

+  }

+

+  return Status;

+}

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiDecompress.h b/edk2/Tools/Source/TianoTools/Common/EfiDecompress.h
new file mode 100644
index 0000000..c5004a7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiDecompress.h
@@ -0,0 +1,105 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  EfiDecompress.h

+

+Abstract:

+

+  Header file for compression routine

+  

+--*/

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _EFI_DECOMPRESS_H

+#define _EFI_DECOMPRESS_H

+EFI_STATUS

+GetInfo (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  OUT     UINT32  *DstSize,

+  OUT     UINT32  *ScratchSize

+  );

+

+/*++

+

+Routine Description:

+

+  The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().

+

+Arguments:

+

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  DstSize     - The size of destination buffer.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  EFI_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+EFI_STATUS

+Decompress (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  IN OUT  VOID    *Destination,

+  IN      UINT32  DstSize,

+  IN OUT  VOID    *Scratch,

+  IN      UINT32  ScratchSize

+  )

+;

+

+/*++

+

+Routine Description:

+

+  The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().

+

+Arguments:

+

+  This        - The protocol instance pointer

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  Destination - The destination buffer to store the decompressed data

+  DstSize     - The size of destination buffer.

+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - Decompression is successfull

+  EFI_INVALID_PARAMETER - The source data is corrupted

+

+--*/

+typedef

+EFI_STATUS

+(*GETINFO_FUNCTION) (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  OUT     UINT32  *DstSize,

+  OUT     UINT32  *ScratchSize

+  );

+

+typedef

+EFI_STATUS

+(*DECOMPRESS_FUNCTION) (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  IN OUT  VOID    *Destination,

+  IN      UINT32  DstSize,

+  IN OUT  VOID    *Scratch,

+  IN      UINT32  ScratchSize

+  );

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiUtilityMsgs.c b/edk2/Tools/Source/TianoTools/Common/EfiUtilityMsgs.c
new file mode 100644
index 0000000..6312c17
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiUtilityMsgs.c
@@ -0,0 +1,758 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  EfiUtilityMsgs.c

+  

+Abstract:

+

+  EFI tools utility functions to display warning, error, and informational

+  messages.

+  

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <ctype.h>

+#include <stdarg.h>

+

+/*

+#include "Tiano.h"

+*/

+#include "EfiUtilityMsgs.h"

+

+#define MAX_LINE_LEN  200

+

+//

+// Declare module globals for keeping track of the the utility's

+// name and other settings.

+//

+static STATUS mStatus                 = STATUS_SUCCESS;

+static CHAR8  mUtilityName[50]        = { 0 };

+static UINT32 mDebugMsgMask           = 0;

+static CHAR8  *mSourceFileName        = NULL;

+static UINT32 mSourceFileLineNum      = 0;

+static UINT32 mErrorCount             = 0;

+static UINT32 mWarningCount           = 0;

+static UINT32 mMaxErrors              = 0;

+static UINT32 mMaxWarnings            = 0;

+static UINT32 mMaxWarningsPlusErrors  = 0;

+static INT8   mPrintLimitsSet         = 0;

+

+static

+void

+PrintMessage (

+  CHAR8   *Type,

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  CHAR8   *Text,

+  CHAR8   *MsgFmt,

+  va_list List

+  );

+

+static

+void

+PrintLimitExceeded (

+  VOID

+  );

+

+void

+Error (

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  CHAR8   *Text,

+  CHAR8   *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Prints an error message.

+  

+Arguments:

+  All arguments are optional, though the printed message may be useless if

+  at least something valid is not specified.

+  

+  FileName - name of the file or application. If not specified, then the

+             utilty name (as set by the utility calling SetUtilityName()

+             earlier) is used. Otherwise "Unknown utility" is used.

+  

+  LineNumber - the line number of error, typically used by parsers. If the

+               utility is not a parser, then 0 should be specified. Otherwise

+               the FileName and LineNumber info can be used to cause

+               MS Visual Studio to jump to the error.

+               

+  MessageCode - an application-specific error code that can be referenced in

+              other documentation. 

+

+  Text        - the text in question, typically used by parsers.

+  

+  MsgFmt - the format string for the error message. Can contain formatting

+           controls for use with the varargs.

+           

+Returns:

+  None.

+  

+Notes:

+  We print the following (similar to the Warn() and Debug() 

+  W

+  Typical error/warning message format:

+

+  bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters

+

+  BUGBUG -- these three utility functions are almost identical, and

+  should be modified to share code.

+

+  Visual Studio does not find error messages with:

+  

+     " error :"

+     " error 1:"

+     " error c1:"

+     " error 1000:"

+     " error c100:"

+

+  It does find:

+     " error c1000:"     

+--*/

+{

+  va_list List;

+  //

+  // If limits have been set, then check that we have not exceeded them

+  //

+  if (mPrintLimitsSet) {

+    //

+    // See if we've exceeded our total count

+    //

+    if (mMaxWarningsPlusErrors != 0) {

+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+    //

+    // See if we've exceeded our error count

+    //

+    if (mMaxErrors != 0) {

+      if (mErrorCount > mMaxErrors) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+  }

+

+  mErrorCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_ERROR) {

+    mStatus = STATUS_ERROR;

+  }

+}

+

+void

+ParserError (

+  UINT32  MessageCode,

+  CHAR8   *Text,

+  CHAR8   *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a parser error, using the source file name and line number

+  set by a previous call to SetParserPosition().

+

+Arguments:

+  MessageCode   - application-specific error code

+  Text          - text to print in the error message

+  MsgFmt        - format string to print at the end of the error message

+

+Returns:

+  NA

+

+--*/

+{

+  va_list List;

+  //

+  // If limits have been set, then check them

+  //

+  if (mPrintLimitsSet) {

+    //

+    // See if we've exceeded our total count

+    //

+    if (mMaxWarningsPlusErrors != 0) {

+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+    //

+    // See if we've exceeded our error count

+    //

+    if (mMaxErrors != 0) {

+      if (mErrorCount > mMaxErrors) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+  }

+

+  mErrorCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_ERROR) {

+    mStatus = STATUS_ERROR;

+  }

+}

+

+void

+ParserWarning (

+  UINT32  ErrorCode,

+  CHAR8   *OffendingText,

+  CHAR8   *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a parser warning, using the source file name and line number

+  set by a previous call to SetParserPosition().

+

+Arguments:

+  ErrorCode     - application-specific error code

+  OffendingText - text to print in the warning message

+  MsgFmt        - format string to print at the end of the warning message

+

+Returns:

+  NA

+

+--*/

+{

+  va_list List;

+  //

+  // If limits have been set, then check them

+  //

+  if (mPrintLimitsSet) {

+    //

+    // See if we've exceeded our total count

+    //

+    if (mMaxWarningsPlusErrors != 0) {

+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+    //

+    // See if we've exceeded our warning count

+    //

+    if (mMaxWarnings != 0) {

+      if (mWarningCount > mMaxWarnings) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+  }

+

+  mWarningCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_WARNING) {

+    mStatus = STATUS_WARNING;

+  }

+}

+

+void

+Warning (

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  CHAR8   *Text,

+  CHAR8   *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a warning message.

+

+Arguments:

+  FileName    - name of the file where the warning was detected, or the name

+                of the application that detected the warning

+  

+  LineNumber  - the line number where the warning was detected (parsers).

+                0 should be specified if the utility is not a parser.

+               

+  MessageCode - an application-specific warning code that can be referenced in

+                other documentation. 

+

+  Text        - the text in question (parsers)

+  

+  MsgFmt      - the format string for the warning message. Can contain formatting

+                controls for use with varargs.

+           

+Returns:

+  None.

+

+--*/

+{

+  va_list List;

+  //

+  // If limits have been set, then check them

+  //

+  if (mPrintLimitsSet) {

+    //

+    // See if we've exceeded our total count

+    //

+    if (mMaxWarningsPlusErrors != 0) {

+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+    //

+    // See if we've exceeded our warning count

+    //

+    if (mMaxWarnings != 0) {

+      if (mWarningCount > mMaxWarnings) {

+        PrintLimitExceeded ();

+        return ;

+      }

+    }

+  }

+

+  mWarningCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_WARNING) {

+    mStatus = STATUS_WARNING;

+  }

+}

+

+void

+DebugMsg (

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  MsgMask,

+  CHAR8   *Text,

+  CHAR8   *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a warning message.

+

+Arguments:

+  FileName    - typically the name of the utility printing the debug message, but

+                can be the name of a file being parsed.

+  

+  LineNumber  - the line number in FileName (parsers) 

+               

+  MsgMask     - an application-specific bitmask that, in combination with mDebugMsgMask,

+                determines if the debug message gets printed.

+

+  Text        - the text in question (parsers)

+  

+  MsgFmt      - the format string for the debug message. Can contain formatting

+                controls for use with varargs.

+           

+Returns:

+  None.

+

+--*/

+{

+  va_list List;

+  //

+  // If the debug mask is not applicable, then do nothing.

+  //

+  if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) {

+    return ;

+  }

+

+  va_start (List, MsgFmt);

+  PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List);

+  va_end (List);

+}

+

+static

+void

+PrintMessage (

+  CHAR8   *Type,

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  CHAR8   *Text,

+  CHAR8   *MsgFmt,

+  va_list List

+  )

+/*++

+

+Routine Description:

+  Worker routine for all the utility printing services. Prints the message in

+  a format that Visual Studio will find when scanning build outputs for

+  errors or warnings.

+

+Arguments:

+  Type        - "warning" or "error" string to insert into the message to be

+                printed. The first character of this string (converted to uppercase)

+                is used to preceed the MessageCode value in the output string.

+

+  FileName    - name of the file where the warning was detected, or the name

+                of the application that detected the warning

+  

+  LineNumber  - the line number where the warning was detected (parsers).

+                0 should be specified if the utility is not a parser.

+               

+  MessageCode - an application-specific warning code that can be referenced in

+                other documentation. 

+

+  Text        - part of the message to print

+  

+  MsgFmt      - the format string for the message. Can contain formatting

+                controls for use with varargs.

+  List        - the variable list.

+           

+Returns:

+  None.

+

+Notes:

+  If FileName == NULL then this utility will use the string passed into SetUtilityName(). 

+  

+  LineNumber is only used if the caller is a parser, in which case FileName refers to the

+  file being parsed.

+

+  Text and MsgFmt are both optional, though it would be of little use calling this function with

+  them both NULL.

+

+  Output will typically be of the form:

+    <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>

+

+    Parser (LineNumber != 0)

+      VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters

+    Generic utility (LineNumber == 0) 

+      UtilityName : error E1234 : Text string : MsgFmt string and args

+

+--*/

+{

+  CHAR8 Line[MAX_LINE_LEN];

+  CHAR8 Line2[MAX_LINE_LEN];

+  CHAR8 *Cptr;

+  //

+  // If given a filename, then add it (and the line number) to the string.

+  // If there's no filename, then use the program name if provided.

+  //

+  if (FileName != NULL) {

+    Cptr = FileName;

+  } else if (mUtilityName[0] != 0) {

+    Cptr = mUtilityName;

+  } else {

+    Cptr = "Unknown utility";

+  }

+

+  strcpy (Line, Cptr);

+  if (LineNumber != 0) {

+    sprintf (Line2, "(%d)", LineNumber);

+    strcat (Line, Line2);

+  }

+  //

+  // Have to print an error code or Visual Studio won't find the

+  // message for you. It has to be decimal digits too.

+  //

+  sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode);

+  strcat (Line, Line2);

+  fprintf (stdout, "%s", Line);

+  //

+  // If offending text was provided, then print it

+  //

+  if (Text != NULL) {

+    fprintf (stdout, ": %s ", Text);

+  }

+  //

+  // Print formatted message if provided

+  //

+  if (MsgFmt != NULL) {

+    vsprintf (Line2, MsgFmt, List);

+    fprintf (stdout, ": %s", Line2);

+  }

+

+  fprintf (stdout, "\n");

+}

+

+void

+ParserSetPosition (

+  CHAR8   *SourceFileName,

+  UINT32  LineNum

+  )

+/*++

+

+Routine Description:

+  Set the position in a file being parsed. This can be used to 

+  print error messages deeper down in a parser.

+

+Arguments:

+  SourceFileName - name of the source file being parsed

+  LineNum        - line number of the source file being parsed

+

+Returns:

+  NA

+

+--*/

+{

+  mSourceFileName     = SourceFileName;

+  mSourceFileLineNum  = LineNum;

+}

+

+void

+SetUtilityName (

+  CHAR8   *UtilityName

+  )

+/*++

+

+Routine Description:

+  All printed error/warning/debug messages follow the same format, and

+  typically will print a filename or utility name followed by the error

+  text. However if a filename is not passed to the print routines, then

+  they'll print the utility name if you call this function early in your

+  app to set the utility name.

+  

+Arguments:

+  UtilityName  -  name of the utility, which will be printed with all

+                  error/warning/debug messags.

+

+Returns:

+  NA

+  

+--*/

+{

+  //

+  // Save the name of the utility in our local variable. Make sure its

+  // length does not exceed our buffer.

+  //

+  if (UtilityName != NULL) {

+    if (strlen (UtilityName) >= sizeof (mUtilityName)) {

+      Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");

+      strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);

+      mUtilityName[sizeof (mUtilityName) - 1] = 0;

+      return ;

+    } else {

+      strcpy (mUtilityName, UtilityName);

+    }

+  } else {

+    Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");

+  }

+}

+

+STATUS

+GetUtilityStatus (

+  VOID

+  )

+/*++

+

+Routine Description:

+  When you call Error() or Warning(), this module keeps track of it and

+  sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility

+  exits, it can call this function to get the status and use it as a return

+  value.

+  

+Arguments:

+  None.

+

+Returns:

+  Worst-case status reported, as defined by which print function was called.

+  

+--*/

+{

+  return mStatus;

+}

+

+void

+SetDebugMsgMask (

+  UINT32  DebugMask

+  )

+/*++

+

+Routine Description:

+  Set the debug printing mask. This is used by the DebugMsg() function

+  to determine when/if a debug message should be printed.

+

+Arguments:

+  DebugMask  - bitmask, specific to the calling application

+

+Returns:

+  NA

+

+--*/

+{

+  mDebugMsgMask = DebugMask;

+}

+

+void

+SetPrintLimits (

+  UINT32  MaxErrors,

+  UINT32  MaxWarnings,

+  UINT32  MaxWarningsPlusErrors

+  )

+/*++

+

+Routine Description:

+  Set the limits of how many errors, warnings, and errors+warnings

+  we will print.

+

+Arguments:

+  MaxErrors       - maximum number of error messages to print

+  MaxWarnings     - maximum number of warning messages to print

+  MaxWarningsPlusErrors 

+                  - maximum number of errors+warnings to print

+

+Returns:

+  NA

+

+--*/

+{

+  mMaxErrors              = MaxErrors;

+  mMaxWarnings            = MaxWarnings;

+  mMaxWarningsPlusErrors  = MaxWarningsPlusErrors;

+  mPrintLimitsSet         = 1;

+}

+

+static

+void

+PrintLimitExceeded (

+  VOID

+  )

+{

+  static INT8 mPrintLimitExceeded = 0;

+  //

+  // If we've already printed the message, do nothing. Otherwise

+  // temporarily increase our print limits so we can pass one

+  // more message through.

+  //

+  if (mPrintLimitExceeded == 0) {

+    mPrintLimitExceeded++;

+    mMaxErrors++;

+    mMaxWarnings++;

+    mMaxWarningsPlusErrors++;

+    Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);

+    mMaxErrors--;

+    mMaxWarnings--;

+    mMaxWarningsPlusErrors--;

+  }

+}

+

+#if 0

+void

+TestUtilityMessages (

+  VOID

+  )

+{

+  char *ArgStr = "ArgString";

+  int  ArgInt;

+

+  ArgInt  = 0x12345678;

+  //

+  // Test without setting utility name

+  //

+  fprintf (stdout, "* Testing without setting utility name\n");

+  fprintf (stdout, "** Test debug message not printed\n");

+  DebugMsg (NULL, 0, 0x00000001, NULL, NULL);

+  fprintf (stdout, "** Test warning with two strings and two args\n");

+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+  fprintf (stdout, "** Test error with two strings and two args\n");

+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+  fprintf (stdout, "** Test parser warning with nothing\n");

+  ParserWarning (0, NULL, NULL);

+  fprintf (stdout, "** Test parser error with nothing\n");

+  ParserError (0, NULL, NULL);

+  //

+  // Test with utility name set now

+  //

+  fprintf (stdout, "** Testingin with utility name set\n");

+  SetUtilityName ("MyUtilityName");

+  //

+  // Test debug prints

+  //

+  SetDebugMsgMask (2);

+  fprintf (stdout, "** Test debug message with one string\n");

+  DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);

+  fprintf (stdout, "** Test debug message with one string\n");

+  DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");

+  fprintf (stdout, "** Test debug message with two strings\n");

+  DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");

+  fprintf (stdout, "** Test debug message with two strings and two args\n");

+  DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+  //

+  // Test warning prints

+  //

+  fprintf (stdout, "** Test warning with no strings\n");

+  Warning (NULL, 0, 1234, NULL, NULL);

+  fprintf (stdout, "** Test warning with one string\n");

+  Warning (NULL, 0, 1234, "Text1", NULL);

+  fprintf (stdout, "** Test warning with one string\n");

+  Warning (NULL, 0, 1234, NULL, "Text2");

+  fprintf (stdout, "** Test warning with two strings and two args\n");

+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+  //

+  // Test error prints

+  //

+  fprintf (stdout, "** Test error with no strings\n");

+  Error (NULL, 0, 1234, NULL, NULL);

+  fprintf (stdout, "** Test error with one string\n");

+  Error (NULL, 0, 1234, "Text1", NULL);

+  fprintf (stdout, "** Test error with one string\n");

+  Error (NULL, 0, 1234, NULL, "Text2");

+  fprintf (stdout, "** Test error with two strings and two args\n");

+  Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+  //

+  // Test parser prints

+  //

+  fprintf (stdout, "** Test parser errors\n");

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserError (1234, NULL, NULL);

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserError (1234, "Text1", NULL);

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserError (1234, NULL, "Text2");

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserError (1234, "Text1", "Text2");

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+

+  fprintf (stdout, "** Test parser warnings\n");

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserWarning (4321, NULL, NULL);

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserWarning (4321, "Text1", NULL);

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserWarning (4321, NULL, "Text2");

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserWarning (4321, "Text1", "Text2");

+  ParserSetPosition (__FILE__, __LINE__ + 1);

+  ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);

+}

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/EfiUtilityMsgs.h b/edk2/Tools/Source/TianoTools/Common/EfiUtilityMsgs.h
new file mode 100644
index 0000000..777cacf
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/EfiUtilityMsgs.h
@@ -0,0 +1,138 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiUtilityMsgs.h

+

+Abstract:

+

+  Defines and prototypes for common EFI utility error and debug messages.

+  

+--*/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _EFI_UTILITY_MSGS_H_

+#define _EFI_UTILITY_MSGS_H_

+

+//

+// Status codes returned by EFI utility programs and functions

+//

+#define STATUS_SUCCESS  0

+#define STATUS_WARNING  1

+#define STATUS_ERROR    2

+#define VOID void 

+

+typedef int STATUS;

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+//

+// When we call Error() or Warning(), the module keeps track of the worst

+// case reported. GetUtilityStatus() will get the worst-case results, which

+// can be used as the return value from the app.

+//

+STATUS

+GetUtilityStatus (

+  void

+  );

+

+//

+// If someone prints an error message and didn't specify a source file name,

+// then we print the utility name instead. However they must tell us the

+// utility name early on via this function.

+//

+void

+SetUtilityName (

+  CHAR8 *ProgramName

+  )

+;

+

+void

+Error (

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  ErrorCode,

+  CHAR8   *OffendingText,

+  CHAR8   *MsgFmt,

+  ...

+  )

+;

+

+void

+Warning (

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  ErrorCode,

+  CHAR8   *OffendingText,

+  CHAR8   *MsgFmt,

+  ...

+  )

+;

+

+void

+DebugMsg (

+  CHAR8   *FileName,

+  UINT32  LineNumber,

+  UINT32  MsgLevel,

+  CHAR8   *OffendingText,

+  CHAR8   *MsgFmt,

+  ...

+  )

+;

+

+void

+SetDebugMsgMask (

+  UINT32    MsgMask

+  )

+;

+

+void

+ParserSetPosition (

+  CHAR8   *SourceFileName,

+  UINT32  LineNum

+  )

+;

+

+void

+ParserError (

+  UINT32  ErrorCode,

+  CHAR8   *OffendingText,

+  CHAR8   *MsgFmt,

+  ...

+  )

+;

+

+void

+ParserWarning (

+  UINT32  ErrorCode,

+  CHAR8   *OffendingText,

+  CHAR8   *MsgFmt,

+  ...

+  )

+;

+

+void

+SetPrintLimits (

+  UINT32  NumErrors,

+  UINT32  NumWarnings,

+  UINT32  NumWarningsPlusErrors

+  )

+;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif // #ifndef _EFI_UTILITY_MSGS_H_

diff --git a/edk2/Tools/Source/TianoTools/Common/FvLib.c b/edk2/Tools/Source/TianoTools/Common/FvLib.c
new file mode 100644
index 0000000..9bfd843
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/FvLib.c
@@ -0,0 +1,788 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FvLib.c

+

+Abstract:

+

+  These functions assist in parsing and manipulating a Firmware Volume.

+

+--*/

+

+//

+// Include files

+//

+#include "FvLib.h"

+#include "CommonLib.h"

+#include "EfiUtilityMsgs.h"

+#include "MultiPhase.h"

+/*

+#include <CommonBuild.h>

+*/

+

+/*

+#include EFI_GUID_DEFINITION (FirmwareFileSystem)

+*/

+

+//

+// Module global variables

+//

+EFI_FIRMWARE_VOLUME_HEADER  *mFvHeader  = NULL;

+UINT32                      mFvLength   = 0;

+

+//

+// External function implementations

+//

+EFI_STATUS

+InitializeFvLib (

+  IN VOID                         *Fv,

+  IN UINT32                       FvLength

+  )

+/*++

+

+Routine Description:

+

+  This initializes the FV lib with a pointer to the FV and length.  It does not

+  verify the FV in any way.

+

+Arguments:

+

+  Fv            Buffer containing the FV.

+  FvLength      Length of the FV

+    

+Returns:

+ 

+  EFI_SUCCESS             Function Completed successfully.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+

+--*/

+{

+  //

+  // Verify input arguments

+  //

+  if (Fv == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv;

+  mFvLength = FvLength;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetFvHeader (

+  OUT EFI_FIRMWARE_VOLUME_HEADER  **FvHeader,

+  OUT UINT32                      *FvLength

+  )

+/*++

+

+Routine Description:

+

+  This function returns a pointer to the current FV and the size.

+

+Arguments:

+

+  FvHeader      Pointer to the FV buffer.

+  FvLength      Length of the FV

+    

+Returns:

+ 

+  EFI_SUCCESS             Function Completed successfully.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+  EFI_ABORTED             The library needs to be initialized.

+

+--*/

+{

+  //

+  // Verify library has been initialized.

+  //

+  if (mFvHeader == NULL || mFvLength == 0) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify input arguments

+  //

+  if (FvHeader == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *FvHeader = mFvHeader;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetNextFile (

+  IN EFI_FFS_FILE_HEADER          *CurrentFile,

+  OUT EFI_FFS_FILE_HEADER         **NextFile

+  )

+/*++

+

+Routine Description:

+

+  This function returns the next file.  If the current file is NULL, it returns

+  the first file in the FV.  If the function returns EFI_SUCCESS and the file 

+  pointer is NULL, then there are no more files in the FV.

+

+Arguments:

+

+  CurrentFile   Pointer to the current file, must be within the current FV.

+  NextFile      Pointer to the next file in the FV.

+    

+Returns:

+ 

+  EFI_SUCCESS             Function completed successfully.

+  EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.

+  EFI_ABORTED             The library needs to be initialized.

+

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Verify library has been initialized.

+  //

+  if (mFvHeader == NULL || mFvLength == 0) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify input arguments

+  //

+  if (NextFile == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Verify FV header

+  //

+  Status = VerifyFv (mFvHeader);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Get first file

+  //

+  if (CurrentFile == NULL) {

+    CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength);

+

+    //

+    // Verify file is valid

+    //

+    Status = VerifyFfsFile (CurrentFile);

+    if (EFI_ERROR (Status)) {

+      //

+      // no files in this FV

+      //

+      *NextFile = NULL;

+      return EFI_SUCCESS;

+    } else {

+      //

+      // Verify file is in this FV.

+      //

+      if ((UINTN) CurrentFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FFS_FILE_HEADER)) {

+        *NextFile = NULL;

+        return EFI_SUCCESS;

+      }

+

+      *NextFile = CurrentFile;

+      return EFI_SUCCESS;

+    }

+  }

+  //

+  // Verify current file is in range

+  //

+  if (((UINTN) CurrentFile < (UINTN) mFvHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER)) ||

+      ((UINTN) CurrentFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER))

+      ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Get next file, compensate for 8 byte alignment if necessary.

+  //

+  *NextFile = (EFI_FFS_FILE_HEADER *) (((UINTN) CurrentFile + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3));

+

+  //

+  // Verify file is in this FV.

+  //

+  if ((UINTN) *NextFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FFS_FILE_HEADER)) {

+    *NextFile = NULL;

+    return EFI_SUCCESS;

+  }

+  //

+  // Verify file is valid

+  //

+  Status = VerifyFfsFile (*NextFile);

+  if (EFI_ERROR (Status)) {

+    //

+    // no more files in this FV

+    //

+    *NextFile = NULL;

+    return EFI_SUCCESS;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetFileByName (

+  IN EFI_GUID                     *FileName,

+  OUT EFI_FFS_FILE_HEADER         **File

+  )

+/*++

+

+Routine Description:

+

+  Find a file by name.  The function will return NULL if the file is not found.

+

+Arguments:

+

+  FileName    The GUID file name of the file to search for.

+  File        Return pointer.  In the case of an error, contents are undefined.

+

+Returns:

+

+  EFI_SUCCESS             The function completed successfully.

+  EFI_ABORTED             An error was encountered.

+  EFI_INVALID_PARAMETER   One of the parameters was NULL.

+

+--*/

+{

+  EFI_FFS_FILE_HEADER *CurrentFile;

+  EFI_STATUS          Status;

+

+  //

+  // Verify library has been initialized.

+  //

+  if (mFvHeader == NULL || mFvLength == 0) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify input parameters

+  //

+  if (FileName == NULL || File == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Verify FV header

+  //

+  Status = VerifyFv (mFvHeader);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Get the first file

+  //

+  Status = GetNextFile (NULL, &CurrentFile);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "error parsing the FV", NULL);

+    return EFI_ABORTED;

+  }

+  //

+  // Loop as long as we have a valid file

+  //

+  while (CurrentFile) {

+    if (!CompareGuid (&CurrentFile->Name, FileName)) {

+      *File = CurrentFile;

+      return EFI_SUCCESS;

+    }

+

+    Status = GetNextFile (CurrentFile, &CurrentFile);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "error parsing the FV", NULL);

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // File not found in this FV.

+  //

+  *File = NULL;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetFileByType (

+  IN EFI_FV_FILETYPE              FileType,

+  IN UINTN                        Instance,

+  OUT EFI_FFS_FILE_HEADER         **File

+  )

+/*++

+

+Routine Description:

+

+  Find a file by type and instance.  An instance of 1 is the first instance.

+  The function will return NULL if a matching file cannot be found.

+  File type EFI_FV_FILETYPE_ALL means any file type is valid.

+

+Arguments:

+

+  FileType    Type of file to search for.

+  Instance    Instace of the file type to return.

+  File        Return pointer.  In the case of an error, contents are undefined.

+

+Returns:

+

+  EFI_SUCCESS             The function completed successfully.

+  EFI_ABORTED             An error was encountered.

+  EFI_INVALID_PARAMETER   One of the parameters was NULL.

+

+--*/

+{

+  EFI_FFS_FILE_HEADER *CurrentFile;

+  EFI_STATUS          Status;

+  UINTN               FileCount;

+

+  //

+  // Verify library has been initialized.

+  //

+  if (mFvHeader == NULL || mFvLength == 0) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify input parameters

+  //

+  if (File == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Verify FV header

+  //

+  Status = VerifyFv (mFvHeader);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Initialize the number of matching files found.

+  //

+  FileCount = 0;

+

+  //

+  // Get the first file

+  //

+  Status = GetNextFile (NULL, &CurrentFile);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "error parsing FV", NULL);

+    return EFI_ABORTED;

+  }

+  //

+  // Loop as long as we have a valid file

+  //

+  while (CurrentFile) {

+    if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) {

+      FileCount++;

+    }

+

+    if (FileCount == Instance) {

+      *File = CurrentFile;

+      return EFI_SUCCESS;

+    }

+

+    Status = GetNextFile (CurrentFile, &CurrentFile);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "error parsing the FV", NULL);

+      return EFI_ABORTED;

+    }

+  }

+

+  *File = NULL;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetSectionByType (

+  IN EFI_FFS_FILE_HEADER          *File,

+  IN EFI_SECTION_TYPE             SectionType,

+  IN UINTN                        Instance,

+  OUT EFI_FILE_SECTION_POINTER    *Section

+  )

+/*++

+

+Routine Description:

+

+  Find a section in a file by type and instance.  An instance of 1 is the first 

+  instance.  The function will return NULL if a matching section cannot be found.

+  The function will not handle encapsulating sections.

+

+Arguments:

+

+  File        The file to search.

+  SectionType Type of file to search for.

+  Instance    Instace of the section to return.

+  Section     Return pointer.  In the case of an error, contents are undefined.

+

+Returns:

+

+  EFI_SUCCESS             The function completed successfully.

+  EFI_ABORTED             An error was encountered.

+  EFI_INVALID_PARAMETER   One of the parameters was NULL.

+  EFI_NOT_FOUND           No found.

+--*/

+{

+  EFI_FILE_SECTION_POINTER  CurrentSection;

+  EFI_STATUS                Status;

+  UINTN                     SectionCount;

+

+  //

+  // Verify input parameters

+  //

+  if (File == NULL || Instance == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Verify FFS header

+  //

+  Status = VerifyFfsFile (File);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "invalid FFS file", NULL);

+    return EFI_ABORTED;

+  }

+  //

+  // Initialize the number of matching sections found.

+  //

+  SectionCount = 0;

+

+  //

+  // Get the first section

+  //

+  CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));

+

+  //

+  // Loop as long as we have a valid file

+  //

+  while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) {

+    if (CurrentSection.CommonHeader->Type == SectionType) {

+      SectionCount++;

+    }

+

+    if (SectionCount == Instance) {

+      *Section = CurrentSection;

+      return EFI_SUCCESS;

+    }

+    //

+    // Find next section (including compensating for alignment issues.

+    //

+    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));

+  }

+  //

+  // Section not found

+  //

+  (*Section).Code16Section = NULL;

+  return EFI_NOT_FOUND;

+}

+//

+// will not parse compressed sections

+//

+EFI_STATUS

+VerifyFv (

+  IN EFI_FIRMWARE_VOLUME_HEADER   *FvHeader

+  )

+/*++

+

+Routine Description:

+

+  Verify the current pointer points to a valid FV header.

+

+Arguments:

+

+  FvHeader     Pointer to an alleged FV file.

+

+Returns:

+

+  EFI_SUCCESS             The FV header is valid.

+  EFI_VOLUME_CORRUPTED    The FV header is not valid.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+  EFI_ABORTED             Operation aborted.

+

+--*/

+{

+  UINT16  Checksum;

+

+  //

+  // Verify input parameters

+  //

+  if (FvHeader == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (FvHeader->Signature != EFI_FVH_SIGNATURE) {

+    Error (NULL, 0, 0, "invalid FV header signature", NULL);

+    return EFI_VOLUME_CORRUPTED;

+  }

+  //

+  // Verify header checksum

+  //

+  Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));

+

+  if (Checksum != 0) {

+    Error (NULL, 0, 0, "invalid FV header checksum", NULL);

+    return EFI_ABORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+VerifyFfsFile (

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+

+  Verify the current pointer points to a FFS file header.

+

+Arguments:

+

+  FfsHeader     Pointer to an alleged FFS file.

+

+Returns:

+

+  EFI_SUCCESS           The Ffs header is valid.

+  EFI_NOT_FOUND         This "file" is the beginning of free space.

+  EFI_VOLUME_CORRUPTED  The Ffs header is not valid.

+  EFI_ABORTED           The erase polarity is not known.

+

+--*/

+{

+  BOOLEAN             ErasePolarity;

+  EFI_STATUS          Status;

+  EFI_FFS_FILE_HEADER BlankHeader;

+  UINT8               Checksum;

+  UINT32              FileLength;

+  UINT32              OccupiedFileLength;

+  EFI_FFS_FILE_TAIL   *Tail;

+  UINT8               SavedChecksum;

+  UINT8               SavedState;

+  UINT8               FileGuidString[80];

+  UINT32              TailSize;

+  //

+  // Verify library has been initialized.

+  //

+  if (mFvHeader == NULL || mFvLength == 0) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify FV header

+  //

+  Status = VerifyFv (mFvHeader);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Get the erase polarity.

+  //

+  Status = GetErasePolarity (&ErasePolarity);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Check if we have free space

+  //

+  if (ErasePolarity) {

+    memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));

+  } else {

+    memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));

+  }

+

+  if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {

+    return EFI_NOT_FOUND;

+  }

+  //

+  // Convert the GUID to a string so we can at least report which file

+  // if we find an error.

+  //

+  PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE);

+  if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+    TailSize = sizeof (EFI_FFS_FILE_TAIL);

+  } else {

+    TailSize = 0;

+  }

+  //

+  // Verify file header checksum

+  //

+  SavedState = FfsHeader->State;

+  FfsHeader->State = 0;

+  SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;

+  FfsHeader->IntegrityCheck.Checksum.File = 0;

+  Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));

+  FfsHeader->State = SavedState;

+  FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;

+  if (Checksum != 0) {

+    Error (NULL, 0, 0, FileGuidString, "invalid FFS file header checksum");

+    return EFI_ABORTED;

+  }

+  //

+  // Verify file checksum

+  //

+  if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) {

+    //

+    // Verify file data checksum

+    //

+    FileLength          = GetLength (FfsHeader->Size);

+    OccupiedFileLength  = (FileLength + 0x07) & (-1 << 3);

+    Checksum            = CalculateSum8 ((UINT8 *) FfsHeader, FileLength - TailSize);

+    Checksum            = (UINT8) (Checksum - FfsHeader->State);

+    if (Checksum != 0) {

+      Error (NULL, 0, 0, FileGuidString, "invalid FFS file checksum");

+      return EFI_ABORTED;

+    }

+  } else {

+    //

+    // File does not have a checksum

+    // Verify contents are 0x5A as spec'd

+    //

+    if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {

+      Error (NULL, 0, 0, FileGuidString, "invalid fixed FFS file header checksum");

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // Check if the tail is present and verify it if it is.

+  //

+  if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+    //

+    // Verify tail is complement of integrity check field in the header.

+    //

+    Tail = (EFI_FFS_FILE_TAIL *) ((UINTN) FfsHeader + GetLength (FfsHeader->Size) - sizeof (EFI_FFS_FILE_TAIL));

+    if (FfsHeader->IntegrityCheck.TailReference != (EFI_FFS_FILE_TAIL)~(*Tail)) {

+      Error (NULL, 0, 0, FileGuidString, "invalid FFS file tail");

+      return EFI_ABORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+UINT32

+GetLength (

+  UINT8     *ThreeByteLength

+  )

+/*++

+

+Routine Description:

+

+  Converts a three byte length value into a UINT32.

+

+Arguments:

+

+  ThreeByteLength   Pointer to the first of the 3 byte length.

+

+Returns:

+

+  UINT32      Size of the section

+

+--*/

+{

+  UINT32  Length;

+

+  if (ThreeByteLength == NULL) {

+    return 0;

+  }

+

+  Length  = *((UINT32 *) ThreeByteLength);

+  Length  = Length & 0x00FFFFFF;

+

+  return Length;

+}

+

+EFI_STATUS

+GetErasePolarity (

+  OUT BOOLEAN   *ErasePolarity

+  )

+/*++

+

+Routine Description:

+

+  This function returns with the FV erase polarity.  If the erase polarity

+  for a bit is 1, the function return TRUE.

+

+Arguments:

+

+  ErasePolarity   A pointer to the erase polarity.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_ABORTED              Operation aborted.

+  

+--*/

+{

+  EFI_STATUS  Status;

+

+  //

+  // Verify library has been initialized.

+  //

+  if (mFvHeader == NULL || mFvLength == 0) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify FV header

+  //

+  Status = VerifyFv (mFvHeader);

+  if (EFI_ERROR (Status)) {

+    return EFI_ABORTED;

+  }

+  //

+  // Verify input parameters.

+  //

+  if (ErasePolarity == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (mFvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {

+    *ErasePolarity = TRUE;

+  } else {

+    *ErasePolarity = FALSE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+UINT8

+GetFileState (

+  IN BOOLEAN              ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+/*++

+

+Routine Description:

+

+  This function returns a the highest state bit in the FFS that is set.

+  It in no way validate the FFS file.

+

+Arguments:

+  

+  ErasePolarity The erase polarity for the file state bits.

+  FfsHeader     Pointer to a FFS file.

+

+Returns:

+

+  UINT8   The hightest set state of the file.

+

+--*/

+{

+  UINT8 FileState;

+  UINT8 HighestBit;

+

+  FileState = FfsHeader->State;

+

+  if (ErasePolarity) {

+    FileState = (UINT8)~FileState;

+  }

+

+  HighestBit = 0x80;

+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {

+    HighestBit >>= 1;

+  }

+

+  return HighestBit;

+}

diff --git a/edk2/Tools/Source/TianoTools/Common/FvLib.h b/edk2/Tools/Source/TianoTools/Common/FvLib.h
new file mode 100644
index 0000000..4a10a3d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/FvLib.h
@@ -0,0 +1,185 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  FvLib.h

+

+Abstract:

+

+  These functions assist in parsing and manipulating a Firmware Volume.

+

+--*/

+

+#ifndef _EFI_FV_LIB_H

+#define _EFI_FV_LIB_H

+

+//

+// Include files

+//

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <Common/EfiImage.h>

+#include <Common/FirmwareVolumeImageFormat.h>

+#include <Common/FirmwareFileSystem.h>

+#include <Common/FirmwareVolumeHeader.h>

+/*

+#include "TianoCommon.h"

+#include "EfiFirmwareVolumeHeader.h"

+#include "EfiFirmwareFileSystem.h"

+*/

+#include <string.h>

+

+EFI_STATUS

+InitializeFvLib (

+  IN VOID                         *Fv,

+  IN UINT32                       FvLength

+  )

+;

+

+EFI_STATUS

+GetFvHeader (

+  OUT EFI_FIRMWARE_VOLUME_HEADER  **FvHeader,

+  OUT UINT32                      *FvLength

+  )

+;

+

+EFI_STATUS

+GetNextFile (

+  IN EFI_FFS_FILE_HEADER          *CurrentFile,

+  OUT EFI_FFS_FILE_HEADER         **NextFile

+  )

+;

+

+EFI_STATUS

+GetFileByName (

+  IN EFI_GUID                     *FileName,

+  OUT EFI_FFS_FILE_HEADER         **File

+  )

+;

+

+EFI_STATUS

+GetFileByType (

+  IN EFI_FV_FILETYPE              FileType,

+  IN UINTN                        Instance,

+  OUT EFI_FFS_FILE_HEADER         **File

+  )

+;

+

+EFI_STATUS

+GetSectionByType (

+  IN EFI_FFS_FILE_HEADER          *File,

+  IN EFI_SECTION_TYPE             SectionType,

+  IN UINTN                        Instance,

+  OUT EFI_FILE_SECTION_POINTER    *Section

+  )

+;

+//

+// will not parse compressed sections

+//

+EFI_STATUS

+VerifyFv (

+  IN EFI_FIRMWARE_VOLUME_HEADER   *FvHeader

+  )

+;

+

+EFI_STATUS

+VerifyFfsFile (

+  IN EFI_FFS_FILE_HEADER          *FfsHeader

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Verify the current pointer points to a FFS file header.

+

+Arguments:

+

+  FfsHeader     Pointer to an alleged FFS file.

+

+Returns:

+

+  EFI_SUCCESS           The Ffs header is valid.

+  EFI_NOT_FOUND         This "file" is the beginning of free space.

+  EFI_VOLUME_CORRUPTED  The Ffs header is not valid.

+

+--*/

+UINT32

+GetLength (

+  UINT8                           *ThreeByteLength

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Converts a three byte length value into a UINT32.

+

+Arguments:

+

+  ThreeByteLength   Pointer to the first of the 3 byte length.

+

+Returns:

+

+  UINT32      Size of the section

+

+--*/

+EFI_STATUS

+GetErasePolarity (

+  OUT BOOLEAN   *ErasePolarity

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function returns with the FV erase polarity.  If the erase polarity

+  for a bit is 1, the function return TRUE.

+

+Arguments:

+

+  ErasePolarity   A pointer to the erase polarity.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+

+--*/

+UINT8

+GetFileState (

+  IN BOOLEAN              ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function returns a the highest state bit in the FFS that is set.

+  It in no way validate the FFS file.

+

+Arguments:

+  

+  ErasePolarity The erase polarity for the file state bits.

+  FfsHeader     Pointer to a FFS file.

+

+Returns:

+

+  UINT8   The hightest set state of the file.

+

+--*/

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/MyAlloc.c b/edk2/Tools/Source/TianoTools/Common/MyAlloc.c
new file mode 100644
index 0000000..39fddf7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/MyAlloc.c
@@ -0,0 +1,516 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MyAlloc.c

+

+Abstract:

+

+  File for memory allocation tracking functions.

+

+--*/

+

+#include "MyAlloc.h"

+

+#if USE_MYALLOC

+//

+// Get back to original alloc/free calls.

+//

+#undef malloc

+#undef calloc

+#undef realloc

+#undef free

+//

+// Start of allocation list.

+//

+static MY_ALLOC_STRUCT  *MyAllocData = NULL;

+

+//

+//

+//

+static UINT32           MyAllocHeadMagik  = MYALLOC_HEAD_MAGIK;

+static UINT32           MyAllocTailMagik  = MYALLOC_TAIL_MAGIK;

+

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+//

+VOID

+MyCheck (

+  BOOLEAN      Final,

+  UINT8        File[],

+  UINTN        Line

+  )

+// *++

+// Description:

+//

+//  Check for corruptions in the allocated memory chain.  If a corruption

+//  is detection program operation stops w/ an exit(1) call.

+//

+// Parameters:

+//

+//  Final := When FALSE, MyCheck() returns if the allocated memory chain

+//           has not been corrupted.  When TRUE, MyCheck() returns if there

+//           are no un-freed allocations.  If there are un-freed allocations,

+//           they are displayed and exit(1) is called.

+//

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  n/a

+//

+// --*/

+//

+{

+  MY_ALLOC_STRUCT *Tmp;

+

+  //

+  // Check parameters.

+  //

+  if (File == NULL || Line == 0) {

+    printf (

+      "\nMyCheck(Final=%u, File=%xh, Line=%u)"

+      "Invalid parameter(s).\n",

+      Final,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+

+  if (strlen (File) == 0) {

+    printf (

+      "\nMyCheck(Final=%u, File=%s, Line=%u)"

+      "Invalid parameter.\n",

+      Final,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+  //

+  // Check structure contents.

+  //

+  for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {

+    if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) ||

+        memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) {

+      break;

+    }

+  }

+  //

+  // If Tmp is not NULL, the structure is corrupt.

+  //

+  if (Tmp != NULL) {

+    printf (

+      "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!"

+      "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",

+      Final,

+      File,

+      Line,

+      Tmp->File,

+      Tmp->Line,

+      Tmp->Size,

+      *(UINT32 *) (Tmp->Buffer),

+      *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])

+      );

+

+    exit (1);

+  }

+  //

+  // If Final is TRUE, display the state of the structure chain.

+  //

+  if (Final) {

+    if (MyAllocData != NULL) {

+      printf (

+        "\nMyCheck(Final=%u, File=%s, Line=%u)"

+        "\nSome allocated items have not been freed.\n",

+        Final,

+        File,

+        Line

+        );

+

+      for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {

+        printf (

+          "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",

+          Tmp->File,

+          Tmp->Line,

+          Tmp->Size,

+          *(UINT32 *) (Tmp->Buffer),

+          *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])

+          );

+      }

+    }

+  }

+}

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+//

+VOID *

+MyAlloc (

+  UINTN      Size,

+  UINT8 File[],

+  UINTN      Line

+  )

+// *++

+// Description:

+//

+//  Allocate a new link in the allocation chain along with enough storage

+//  for the File[] string, requested Size and alignment overhead.  If

+//  memory cannot be allocated or the allocation chain has been corrupted,

+//  exit(1) will be called.

+//

+// Parameters:

+//

+//  Size := Number of bytes (UINT8) requested by the called.

+//          Size cannot be zero.

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  Pointer to the caller's buffer.

+//

+// --*/

+//

+{

+  MY_ALLOC_STRUCT *Tmp;

+  UINTN           Len;

+

+  //

+  // Check for invalid parameters.

+  //

+  if (Size == 0 || File == NULL || Line == 0) {

+    printf (

+      "\nMyAlloc(Size=%u, File=%xh, Line=%u)"

+      "\nInvalid parameter(s).\n",

+      Size,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+

+  Len = strlen (File);

+  if (Len == 0) {

+    printf (

+      "\nMyAlloc(Size=%u, File=%s, Line=%u)"

+      "\nInvalid parameter.\n",

+      Size,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+  //

+  // Check the allocation list for corruption.

+  //

+  MyCheck (0, __FILE__, __LINE__);

+

+  //

+  // Allocate a new entry.

+  //

+  Tmp = calloc (

+          1,

+          sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik)

+          );

+

+  if (Tmp == NULL) {

+    printf (

+      "\nMyAlloc(Size=%u, File=%s, Line=%u)"

+      "\nOut of memory.\n",

+      Size,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+  //

+  // Fill in the new entry.

+  //

+  Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT);

+  strcpy (Tmp->File, File);

+  Tmp->Line   = Line;

+  Tmp->Size   = Size;

+  Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7);

+

+  memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik);

+

+  memcpy (

+    &Tmp->Buffer[Size + sizeof (UINT32)],

+    &MyAllocTailMagik,

+    sizeof MyAllocTailMagik

+    );

+

+  Tmp->Next   = MyAllocData;

+  Tmp->Cksum  = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer);

+

+  MyAllocData = Tmp;

+

+  return Tmp->Buffer + sizeof (UINT32);

+}

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+//

+VOID *

+MyRealloc (

+  VOID       *Ptr,

+  UINTN      Size,

+  UINT8 File[],

+  UINTN      Line

+  )

+// *++

+// Description:

+//

+//  This does a MyAlloc(), memcpy() and MyFree().  There is no optimization

+//  for shrinking or expanding buffers.  An invalid parameter will cause

+//  MyRealloc() to fail with a call to exit(1).

+//

+// Parameters:

+//

+//  Ptr := Pointer to the caller's buffer to be re-allocated.

+//

+//  Size := Size of new buffer.  Size cannot be zero.

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  Pointer to new caller's buffer.

+//

+// --*/

+//

+{

+  MY_ALLOC_STRUCT *Tmp;

+  VOID            *Buffer;

+

+  //

+  // Check for invalid parameter(s).

+  //

+  if (Size == 0 || File == NULL || Line == 0) {

+    printf (

+      "\nMyRealloc(Ptr=%xh, Size=%u, File=%xh, Line=%u)"

+      "\nInvalid parameter(s).\n",

+      Ptr,

+      Size,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+

+  if (strlen (File) == 0) {

+    printf (

+      "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)"

+      "\nInvalid parameter.\n",

+      Ptr,

+      Size,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+  //

+  // Find existing buffer in allocation list.

+  //

+  if (Ptr == NULL) {

+    Tmp = NULL;

+  } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {

+    Tmp = MyAllocData;

+  } else {

+    for (Tmp = MyAllocData;; Tmp = Tmp->Next) {

+      if (Tmp->Next == NULL) {

+        printf (

+          "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)"

+          "\nCould not find buffer.\n",

+          Ptr,

+          Size,

+          File,

+          Line

+          );

+

+        exit (1);

+      }

+

+      Tmp = Tmp->Next;

+    }

+  }

+  //

+  // Allocate new buffer, copy old data, free old buffer.

+  //

+  Buffer = MyAlloc (Size, File, Line);

+

+  if (Buffer != NULL && Tmp != NULL) {

+    memcpy (

+      Buffer,

+      &Tmp->Buffer[sizeof (UINT32)],

+      ((Size <= Tmp->Size) ? Size : Tmp->Size)

+      );

+

+    MyFree (Ptr, __FILE__, __LINE__);

+  }

+

+  return Buffer;

+}

+//

+// ////////////////////////////////////////////////////////////////////////////

+//

+//

+VOID

+MyFree (

+  VOID       *Ptr,

+  UINT8 File[],

+  UINTN      Line

+  )

+// *++

+// Description:

+//

+//  Release a previously allocated buffer.  Invalid parameters will cause

+//  MyFree() to fail with an exit(1) call.

+//

+// Parameters:

+//

+//  Ptr := Pointer to the caller's buffer to be freed.

+//         A NULL pointer will be ignored.

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  n/a

+//

+// --*/

+//

+{

+  MY_ALLOC_STRUCT *Tmp;

+  MY_ALLOC_STRUCT *Tmp2;

+

+  //

+  // Check for invalid parameter(s).

+  //

+  if (File == NULL || Line == 0) {

+    printf (

+      "\nMyFree(Ptr=%xh, File=%xh, Line=%u)"

+      "\nInvalid parameter(s).\n",

+      Ptr,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+

+  if (strlen (File) == 0) {

+    printf (

+      "\nMyFree(Ptr=%xh, File=%s, Line=%u)"

+      "\nInvalid parameter.\n",

+      Ptr,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+  //

+  // Freeing NULL is always valid.

+  //

+  if (Ptr == NULL) {

+    return ;

+  }

+  //

+  // Fail if nothing is allocated.

+  //

+  if (MyAllocData == NULL) {

+    printf (

+      "\nMyFree(Ptr=%xh, File=%s, Line=%u)"

+      "\nCalled before memory allocated.\n",

+      Ptr,

+      File,

+      Line

+      );

+

+    exit (1);

+  }

+  //

+  // Check for corrupted allocation list.

+  //

+  MyCheck (0, __FILE__, __LINE__);

+

+  //

+  // Need special check for first item in list.

+  //

+  if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {

+    //

+    // Unlink first item in list.

+    //

+    Tmp         = MyAllocData;

+    MyAllocData = MyAllocData->Next;

+  } else {

+    //

+    // Walk list looking for matching item.

+    //

+    for (Tmp = MyAllocData;; Tmp = Tmp->Next) {

+      //

+      // Fail if end of list is reached.

+      //

+      if (Tmp->Next == NULL) {

+        printf (

+          "\nMyFree(Ptr=%xh, File=%s, Line=%u)\n"

+          "\nNot found.\n",

+          Ptr,

+          File,

+          Line

+          );

+

+        exit (1);

+      }

+      //

+      // Leave loop when match is found.

+      //

+      if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) {

+        break;

+      }

+    }

+    //

+    // Unlink item from list.

+    //

+    Tmp2      = Tmp->Next;

+    Tmp->Next = Tmp->Next->Next;

+    Tmp       = Tmp2;

+  }

+  //

+  // Release item.

+  //

+  free (Tmp);

+}

+

+#endif /* USE_MYALLOC */

+

+/* eof - MyAlloc.c */

diff --git a/edk2/Tools/Source/TianoTools/Common/MyAlloc.h b/edk2/Tools/Source/TianoTools/Common/MyAlloc.h
new file mode 100644
index 0000000..d766682
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/MyAlloc.h
@@ -0,0 +1,225 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MyAlloc.h

+

+Abstract:

+

+  Header file for memory allocation tracking functions.

+

+--*/

+

+#ifndef _MYALLOC_H_

+#define _MYALLOC_H_

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <Base.h>

+

+/*

+#include "Tiano.h"

+*/

+

+//

+// Default operation is to use the memory allocation tracking functions.

+// To over-ride add "#define USE_MYALLOC 0" to your program header and/or

+// source files as needed.  Or, just do not include this header file in

+// your project.

+//

+#ifndef USE_MYALLOC

+#define USE_MYALLOC 1

+#endif

+

+#if USE_MYALLOC

+//

+// Replace C library allocation routines with MyAlloc routines.

+//

+#define malloc(size)        MyAlloc ((size), __FILE__, __LINE__)

+#define calloc(count, size) MyAlloc ((count) * (size), __FILE__, __LINE__)

+#define realloc(ptr, size)  MyRealloc ((ptr), (size), __FILE__, __LINE__)

+#define free(ptr)           MyFree ((ptr), __FILE__, __LINE__)

+#define alloc_check(final)  MyCheck ((final), __FILE__, __LINE__)

+

+//

+// Structure for checking/tracking memory allocations.

+//

+typedef struct MyAllocStruct {

+  UINTN                 Cksum;

+  struct MyAllocStruct  *Next;

+  UINTN                 Line;

+  UINTN                 Size;

+  UINT8                 *File;

+  UINT8                 *Buffer;

+} MY_ALLOC_STRUCT;

+//

+// Cksum := (UINTN)This + (UINTN)Next + Line + Size + (UINTN)File +

+//          (UINTN)Buffer;

+//

+// Next := Pointer to next allocation structure in the list.

+//

+// Line := __LINE__

+//

+// Size := Size of allocation request.

+//

+// File := Pointer to __FILE__ string stored immediately following

+//         MY_ALLOC_STRUCT in memory.

+//

+// Buffer := Pointer to UINT32 aligned storage immediately following

+//           the NULL terminated __FILE__ string.  This is UINT32

+//           aligned because the underflow signature is 32-bits and

+//           this will place the first caller address on a 64-bit

+//           boundary.

+//

+//

+// Signatures used to check for buffer overflow/underflow conditions.

+//

+#define MYALLOC_HEAD_MAGIK  0xBADFACED

+#define MYALLOC_TAIL_MAGIK  0xDEADBEEF

+

+VOID

+MyCheck (

+  BOOLEAN      Final,

+  UINT8        File[],

+  UINTN        Line

+  )

+;

+//

+// *++

+// Description:

+//

+//  Check for corruptions in the allocated memory chain.  If a corruption

+//  is detection program operation stops w/ an exit(1) call.

+//

+// Parameters:

+//

+//  Final := When FALSE, MyCheck() returns if the allocated memory chain

+//           has not been corrupted.  When TRUE, MyCheck() returns if there

+//           are no un-freed allocations.  If there are un-freed allocations,

+//           they are displayed and exit(1) is called.

+//

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  n/a

+//

+// --*/

+//

+VOID  *

+MyAlloc (

+  UINTN      Size,

+  UINT8      File[],

+  UINTN      Line

+  )

+;

+//

+// *++

+// Description:

+//

+//  Allocate a new link in the allocation chain along with enough storage

+//  for the File[] string, requested Size and alignment overhead.  If

+//  memory cannot be allocated or the allocation chain has been corrupted,

+//  exit(1) will be called.

+//

+// Parameters:

+//

+//  Size := Number of bytes (UINT8) requested by the called.

+//          Size cannot be zero.

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  Pointer to the caller's buffer.

+//

+// --*/

+//

+VOID  *

+MyRealloc (

+  VOID       *Ptr,

+  UINTN      Size,

+  UINT8      File[],

+  UINTN      Line

+  )

+;

+//

+// *++

+// Description:

+//

+//  This does a MyAlloc(), memcpy() and MyFree().  There is no optimization

+//  for shrinking or expanding buffers.  An invalid parameter will cause

+//  MyRealloc() to fail with a call to exit(1).

+//

+// Parameters:

+//

+//  Ptr := Pointer to the caller's buffer to be re-allocated.

+//         Ptr cannot be NULL.

+//

+//  Size := Size of new buffer.  Size cannot be zero.

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  Pointer to new caller's buffer.

+//

+// --*/

+//

+VOID

+MyFree (

+  VOID       *Ptr,

+  UINT8      File[],

+  UINTN      Line

+  )

+;

+//

+// *++

+// Description:

+//

+//  Release a previously allocated buffer.  Invalid parameters will cause

+//  MyFree() to fail with an exit(1) call.

+//

+// Parameters:

+//

+//  Ptr := Pointer to the caller's buffer to be freed.

+//         A NULL pointer will be ignored.

+//

+//  File := Set to __FILE__ by macro expansion.

+//

+//  Line := Set to __LINE__ by macro expansion.

+//

+// Returns:

+//

+//  n/a

+//

+// --*/

+//

+#else /* USE_MYALLOC */

+

+//

+// Nothing to do when USE_MYALLOC is zero.

+//

+#define alloc_check(final)

+

+#endif /* USE_MYALLOC */

+#endif /* _MYALLOC_H_ */

+

+/* eof - MyAlloc.h */

diff --git a/edk2/Tools/Source/TianoTools/Common/ParseInf.c b/edk2/Tools/Source/TianoTools/Common/ParseInf.c
new file mode 100644
index 0000000..989add7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/ParseInf.c
@@ -0,0 +1,630 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ParseInf.c

+

+Abstract:

+

+  This contains some useful functions for parsing INF files.

+

+--*/

+

+#include "ParseInf.h"

+#include <assert.h>

+#include <string.h>

+#include <ctype.h>

+#include <stdlib.h>

+

+#ifndef _MAX_PATH

+#define _MAX_PATH 500

+#endif

+

+CHAR8 *

+ReadLine (

+  IN MEMORY_FILE    *InputFile,

+  IN OUT CHAR8      *InputBuffer,

+  IN UINTN          MaxLength

+  )

+/*++

+

+Routine Description:

+

+  This function reads a line, stripping any comments.

+  The function reads a string from the input stream argument and stores it in 

+  the input string. ReadLine reads characters from the current file position 

+  to and including the first newline character, to the end of the stream, or 

+  until the number of characters read is equal to MaxLength - 1, whichever 

+  comes first.  The newline character, if read, is replaced with a \0. 

+

+Arguments:

+

+  InputFile     Memory file image.

+  InputBuffer   Buffer to read into, must be _MAX_PATH size.

+  MaxLength     The maximum size of the input buffer.

+

+Returns:

+

+  NULL if error or EOF

+  InputBuffer otherwise

+

+--*/

+{

+  CHAR8 *CharPtr;

+  CHAR8 *EndOfLine;

+  UINTN CharsToCopy;

+

+  //

+  // Verify input parameters are not null

+  //

+  assert (InputBuffer);

+  assert (InputFile->FileImage);

+  assert (InputFile->Eof);

+  assert (InputFile->CurrentFilePointer);

+

+  //

+  // Check for end of file condition

+  //

+  if (InputFile->CurrentFilePointer >= InputFile->Eof) {

+    return NULL;

+  }

+  //

+  // Find the next newline char

+  //

+  EndOfLine = strchr (InputFile->CurrentFilePointer, '\n');

+

+  //

+  // Determine the number of characters to copy.

+  //

+  if (EndOfLine == 0) {

+    //

+    // If no newline found, copy to the end of the file.

+    //

+    CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;

+  } else if (EndOfLine >= InputFile->Eof) {

+    //

+    // If the newline found was beyond the end of file, copy to the eof.

+    //

+    CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;

+  } else {

+    //

+    // Newline found in the file.

+    //

+    CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;

+  }

+  //

+  // If the end of line is too big for the current buffer, set it to the max

+  // size of the buffer (leaving room for the \0.

+  //

+  if (CharsToCopy > MaxLength - 1) {

+    CharsToCopy = MaxLength - 1;

+  }

+  //

+  // Copy the line.

+  //

+  memcpy (InputBuffer, InputFile->CurrentFilePointer, CharsToCopy);

+

+  //

+  // Add the null termination over the 0x0D

+  //

+  InputBuffer[CharsToCopy - 1] = '\0';

+

+  //

+  // Increment the current file pointer (include the 0x0A)

+  //

+  InputFile->CurrentFilePointer += CharsToCopy + 1;

+

+  //

+  // Strip any comments

+  //

+  CharPtr = strstr (InputBuffer, "//");

+  if (CharPtr != 0) {

+    CharPtr[0] = 0;

+  }

+  //

+  // Return the string

+  //

+  return InputBuffer;

+}

+

+BOOLEAN

+FindSection (

+  IN MEMORY_FILE    *InputFile,

+  IN CHAR8          *Section

+  )

+/*++

+

+Routine Description:

+

+  This function parses a file from the beginning to find a section.

+  The section string may be anywhere within a line.

+

+Arguments:

+

+  InputFile     Memory file image.

+  Section       Section to search for

+

+Returns:

+

+  FALSE if error or EOF

+  TRUE if section found

+

+--*/

+{

+  CHAR8 InputBuffer[_MAX_PATH];

+  CHAR8 *CurrentToken;

+

+  //

+  // Verify input is not NULL

+  //

+  assert (InputFile->FileImage);

+  assert (InputFile->Eof);

+  assert (InputFile->CurrentFilePointer);

+  assert (Section);

+

+  //

+  // Rewind to beginning of file

+  //

+  InputFile->CurrentFilePointer = InputFile->FileImage;

+

+  //

+  // Read lines until the section is found

+  //

+  while (InputFile->CurrentFilePointer < InputFile->Eof) {

+    //

+    // Read a line

+    //

+    ReadLine (InputFile, InputBuffer, _MAX_PATH);

+

+    //

+    // Check if the section is found

+    //

+    CurrentToken = strstr (InputBuffer, Section);

+    if (CurrentToken != NULL) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+EFI_STATUS

+FindToken (

+  IN MEMORY_FILE    *InputFile,

+  IN CHAR8          *Section,

+  IN CHAR8          *Token,

+  IN UINTN          Instance,

+  OUT CHAR8         *Value

+  )

+/*++

+

+Routine Description:

+

+  Finds a token value given the section and token to search for.

+

+Arguments:

+

+  InputFile Memory file image.

+  Section   The section to search for, a string within [].

+  Token     The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.

+  Instance  The instance of the token to search for.  Zero is the first instance.

+  Value     The string that holds the value following the =.  Must be _MAX_PATH in size.

+

+Returns:

+

+  EFI_SUCCESS             Value found.

+  EFI_ABORTED             Format error detected in INF file.

+  EFI_INVALID_PARAMETER   Input argument was null.

+  EFI_LOAD_ERROR          Error reading from the file.

+  EFI_NOT_FOUND           Section/Token/Value not found.

+

+--*/

+{

+  CHAR8   InputBuffer[_MAX_PATH];

+  CHAR8   *CurrentToken;

+  BOOLEAN ParseError;

+  BOOLEAN ReadError;

+  UINTN   Occurrance;

+

+  //

+  // Check input parameters

+  //

+  if (InputFile->FileImage == NULL ||

+      InputFile->Eof == NULL ||

+      InputFile->CurrentFilePointer == NULL ||

+      Section == NULL ||

+      strlen (Section) == 0 ||

+      Token == NULL ||

+      strlen (Token) == 0 ||

+      Value == NULL

+      ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Initialize error codes

+  //

+  ParseError  = FALSE;

+  ReadError   = FALSE;

+

+  //

+  // Initialize our instance counter for the search token

+  //

+  Occurrance = 0;

+

+  if (FindSection (InputFile, Section)) {

+    //

+    // Found the desired section, find and read the desired token

+    //

+    do {

+      //

+      // Read a line from the file

+      //

+      if (ReadLine (InputFile, InputBuffer, _MAX_PATH) == NULL) {

+        //

+        // Error reading from input file

+        //

+        ReadError = TRUE;

+        break;

+      }

+      //

+      // Get the first non-whitespace string

+      //

+      CurrentToken = strtok (InputBuffer, " \t\n");

+      if (CurrentToken == NULL) {

+        //

+        // Whitespace line found (or comment) so continue

+        //

+        CurrentToken = InputBuffer;

+        continue;

+      }

+      //

+      // Make sure we have not reached the end of the current section

+      //

+      if (CurrentToken[0] == '[') {

+        break;

+      }

+      //

+      // Compare the current token with the desired token

+      //

+      if (strcmp (CurrentToken, Token) == 0) {

+        //

+        // Found it

+        //

+        //

+        // Check if it is the correct instance

+        //

+        if (Instance == Occurrance) {

+          //

+          // Copy the contents following the =

+          //

+          CurrentToken = strtok (NULL, "= \t\n");

+          if (CurrentToken == NULL) {

+            //

+            // Nothing found, parsing error

+            //

+            ParseError = TRUE;

+          } else {

+            //

+            // Copy the current token to the output value

+            //

+            strcpy (Value, CurrentToken);

+            return EFI_SUCCESS;

+          }

+        } else {

+          //

+          // Increment the occurrance found

+          //

+          Occurrance++;

+        }

+      }

+    } while (

+      !ParseError &&

+      !ReadError &&

+      InputFile->CurrentFilePointer < InputFile->Eof &&

+      CurrentToken[0] != '[' &&

+      Occurrance <= Instance

+    );

+  }

+  //

+  // Distinguish between read errors and INF file format errors.

+  //

+  if (ReadError) {

+    return EFI_LOAD_ERROR;

+  }

+

+  if (ParseError) {

+    return EFI_ABORTED;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+StringToGuid (

+  IN CHAR8      *AsciiGuidBuffer,

+  OUT EFI_GUID  *GuidBuffer

+  )

+/*++

+

+Routine Description: 

+

+  Converts a string to an EFI_GUID.  The string must be in the 

+  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.

+

+Arguments:  

+

+  AsciiGuidBuffer - pointer to ascii string

+  GuidBuffer      - pointer to destination Guid

+

+Returns:  

+

+  EFI_ABORTED             Could not convert the string

+  EFI_SUCCESS             The string was successfully converted

+  EFI_INVALID_PARAMETER   Input parameter is invalid.

+

+--*/

+{

+  INT32 Index;

+  UINTN Data1;

+  UINTN Data2;

+  UINTN Data3;

+  UINTN Data4[8];

+

+  if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Scan the guid string into the buffer

+  //

+  Index = sscanf (

+            AsciiGuidBuffer,

+            "%08x-%04x-%04x-%02x%02x-%02hx%02hx%02hx%02hx%02hx%02hx",

+            &Data1,

+            &Data2,

+            &Data3,

+            &Data4[0],

+            &Data4[1],

+            &Data4[2],

+            &Data4[3],

+            &Data4[4],

+            &Data4[5],

+            &Data4[6],

+            &Data4[7]

+            );

+

+  //

+  // Verify the correct number of items were scanned.

+  //

+  if (Index != 11) {

+    printf ("ERROR: Malformed GUID \"%s\".\n\n", AsciiGuidBuffer);

+    return EFI_ABORTED;

+  }

+  //

+  // Copy the data into our GUID.

+  //

+  GuidBuffer->Data1     = (UINT32) Data1;

+  GuidBuffer->Data2     = (UINT16) Data2;

+  GuidBuffer->Data3     = (UINT16) Data3;

+  GuidBuffer->Data4[0]  = (UINT8) Data4[0];

+  GuidBuffer->Data4[1]  = (UINT8) Data4[1];

+  GuidBuffer->Data4[2]  = (UINT8) Data4[2];

+  GuidBuffer->Data4[3]  = (UINT8) Data4[3];

+  GuidBuffer->Data4[4]  = (UINT8) Data4[4];

+  GuidBuffer->Data4[5]  = (UINT8) Data4[5];

+  GuidBuffer->Data4[6]  = (UINT8) Data4[6];

+  GuidBuffer->Data4[7]  = (UINT8) Data4[7];

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AsciiStringToUint64 (

+  IN CONST CHAR8  *AsciiString,

+  IN BOOLEAN      IsHex,

+  OUT UINT64      *ReturnValue

+  )

+/*++

+

+Routine Description:

+

+  Converts a null terminated ascii string that represents a number into a 

+  UINT64 value.  A hex number may be preceeded by a 0x, but may not be 

+  succeeded by an h.  A number without 0x or 0X is considered to be base 10 

+  unless the IsHex input is true.

+

+Arguments:

+

+  AsciiString   The string to convert.

+  IsHex         Force the string to be treated as a hex number.

+  ReturnValue   The return value.

+

+Returns:

+

+  EFI_SUCCESS   Number successfully converted.

+  EFI_ABORTED   Invalid character encountered.

+

+--*/

+{

+  UINT8   Index;

+  UINT64  HexNumber;

+  CHAR8   CurrentChar;

+

+  //

+  // Initialize the result

+  //

+  HexNumber = 0;

+

+  //

+  // Add each character to the result

+  //

+  if (IsHex || (AsciiString[0] == '0' && (AsciiString[1] == 'x' || AsciiString[1] == 'X'))) {

+    //

+    // Verify string is a hex number

+    //

+    for (Index = 2; Index < strlen (AsciiString); Index++) {

+      if (isxdigit (AsciiString[Index]) == 0) {

+        return EFI_ABORTED;

+      }

+    }

+    //

+    // Convert the hex string.

+    //

+    for (Index = 2; AsciiString[Index] != '\0'; Index++) {

+      CurrentChar = AsciiString[Index];

+      HexNumber *= 16;

+      if (CurrentChar >= '0' && CurrentChar <= '9') {

+        HexNumber += CurrentChar - '0';

+      } else if (CurrentChar >= 'a' && CurrentChar <= 'f') {

+        HexNumber += CurrentChar - 'a' + 10;

+      } else if (CurrentChar >= 'A' && CurrentChar <= 'F') {

+        HexNumber += CurrentChar - 'A' + 10;

+      } else {

+        //

+        // Unrecognized character

+        //

+        return EFI_ABORTED;

+      }

+    }

+

+    *ReturnValue = HexNumber;

+  } else {

+    //

+    // Verify string is a number

+    //

+    for (Index = 0; Index < strlen (AsciiString); Index++) {

+      if (isdigit (AsciiString[Index]) == 0) {

+        return EFI_ABORTED;

+      }

+    }

+

+    *ReturnValue = atol (AsciiString);

+  }

+

+  return EFI_SUCCESS;

+};

+

+CHAR8 *

+ReadLineInStream (

+  IN FILE       *InputFile,

+  IN OUT CHAR8  *InputBuffer

+  )

+/*++

+

+Routine Description:

+

+  This function reads a line, stripping any comments.

+  // BUGBUG:  This is obsolete once genmake goes away...

+

+Arguments:

+

+  InputFile     Stream pointer.

+  InputBuffer   Buffer to read into, must be _MAX_PATH size.

+

+Returns:

+

+  NULL if error or EOF

+  InputBuffer otherwise

+

+--*/

+{

+  CHAR8 *CharPtr;

+

+  //

+  // Verify input parameters are not null

+  //

+  assert (InputFile);

+  assert (InputBuffer);

+

+  //

+  // Read a line

+  //

+  if (fgets (InputBuffer, _MAX_PATH, InputFile) == NULL) {

+    return NULL;

+  }

+  //

+  // Strip any comments

+  //

+  CharPtr = strstr (InputBuffer, "//");

+  if (CharPtr != 0) {

+    CharPtr[0] = 0;

+  }

+

+  CharPtr = strstr (InputBuffer, "#");

+  if (CharPtr != 0) {

+    CharPtr[0] = 0;

+  }

+  //

+  // Return the string

+  //

+  return InputBuffer;

+}

+

+BOOLEAN

+FindSectionInStream (

+  IN FILE       *InputFile,

+  IN CHAR8      *Section

+  )

+/*++

+

+Routine Description:

+

+  This function parses a stream file from the beginning to find a section.

+  The section string may be anywhere within a line.

+  // BUGBUG:  This is obsolete once genmake goes away...

+

+Arguments:

+

+  InputFile     Stream pointer.

+  Section       Section to search for

+

+Returns:

+

+  FALSE if error or EOF

+  TRUE if section found

+

+--*/

+{

+  CHAR8 InputBuffer[_MAX_PATH];

+  CHAR8 *CurrentToken;

+

+  //

+  // Verify input is not NULL

+  //

+  assert (InputFile);

+  assert (Section);

+

+  //

+  // Rewind to beginning of file

+  //

+  if (fseek (InputFile, 0, SEEK_SET) != 0) {

+    return FALSE;

+  }

+  //

+  // Read lines until the section is found

+  //

+  while (feof (InputFile) == 0) {

+    //

+    // Read a line

+    //

+    ReadLineInStream (InputFile, InputBuffer);

+

+    //

+    // Check if the section is found

+    //

+    CurrentToken = strstr (InputBuffer, Section);

+    if (CurrentToken != NULL) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

diff --git a/edk2/Tools/Source/TianoTools/Common/ParseInf.h b/edk2/Tools/Source/TianoTools/Common/ParseInf.h
new file mode 100644
index 0000000..5691e53
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/ParseInf.h
@@ -0,0 +1,235 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  ParseInf.h

+

+Abstract:

+

+  Header file for helper functions useful for parsing INF files.

+

+--*/

+

+#ifndef _EFI_PARSE_INF_H

+#define _EFI_PARSE_INF_H

+

+/* #include "TianoCommon.h" */

+#include <Base.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <UefiBaseTypes.h>

+

+//

+// Common data structures

+//

+typedef struct {

+  CHAR8 *FileImage;

+  CHAR8 *Eof;

+  CHAR8 *CurrentFilePointer;

+} MEMORY_FILE;

+

+//

+// Functions declarations

+//

+CHAR8 *

+ReadLine (

+  IN MEMORY_FILE    *InputFile,

+  IN OUT CHAR8      *InputBuffer,

+  IN UINT32         MaxLength

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function reads a line, stripping any comments.

+  The function reads a string from the input stream argument and stores it in 

+  the input string. ReadLine reads characters from the current file position 

+  to and including the first newline character, to the end of the stream, or 

+  until the number of characters read is equal to MaxLength - 1, whichever 

+  comes first.  The newline character, if read, is replaced with a \0. 

+

+Arguments:

+

+  InputFile     Memory file image.

+  InputBuffer   Buffer to read into, must be _MAX_PATH size.

+  MaxLength     The maximum size of the input buffer.

+

+Returns:

+

+  NULL if error or EOF

+  InputBuffer otherwise

+

+--*/

+BOOLEAN

+FindSection (

+  IN MEMORY_FILE    *InputFile,

+  IN CHAR8          *Section

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function parses a file from the beginning to find a section.

+  The section string may be anywhere within a line.

+

+Arguments:

+

+  InputFile     Memory file image.

+  Section       Section to search for

+

+Returns:

+

+  FALSE if error or EOF

+  TRUE if section found

+

+--*/

+EFI_STATUS

+FindToken (

+  IN MEMORY_FILE    *InputFile,

+  IN CHAR8          *Section,

+  IN CHAR8          *Token,

+  IN UINTN          Instance,

+  OUT CHAR8         *Value

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Finds a token value given the section and token to search for.

+

+Arguments:

+

+  InputFile Memory file image.

+  Section   The section to search for, a string within [].

+  Token     The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.

+  Instance  The instance of the token to search for.  Zero is the first instance.

+  Value     The string that holds the value following the =.  Must be _MAX_PATH in size.

+

+Returns:

+

+  EFI_SUCCESS             Value found.

+  EFI_ABORTED             Format error detected in INF file.

+  EFI_INVALID_PARAMETER   Input argument was null.

+  EFI_LOAD_ERROR          Error reading from the file.

+  EFI_NOT_FOUND           Section/Token/Value not found.

+

+--*/

+EFI_STATUS

+StringToGuid (

+  IN CHAR8        *AsciiGuidBuffer,

+  OUT EFI_GUID    *GuidBuffer

+  )

+;

+

+/*++

+

+Routine Description: 

+

+  Converts a string to an EFI_GUID.  The string must be in the 

+  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.

+

+Arguments:  

+

+  GuidBuffer      - pointer to destination Guid

+  AsciiGuidBuffer - pointer to ascii string

+

+Returns:  

+

+  EFI_ABORTED    Could not convert the string

+  EFI_SUCCESS    The string was successfully converted

+

+--*/

+EFI_STATUS

+AsciiStringToUint64 (

+  IN CONST CHAR8  *AsciiString,

+  IN BOOLEAN      IsHex,

+  OUT UINT64      *ReturnValue

+  )

+;

+

+/*++

+

+Routine Description:

+

+  Converts a null terminated ascii string that represents a number into a 

+  UINT64 value.  A hex number may be preceeded by a 0x, but may not be 

+  succeeded by an h.  A number without 0x or 0X is considered to be base 10 

+  unless the IsHex input is true.

+

+Arguments:

+

+  AsciiString   The string to convert.

+  IsHex         Force the string to be treated as a hex number.

+  ReturnValue   The return value.

+

+Returns:

+

+  EFI_SUCCESS   Number successfully converted.

+  EFI_ABORTED   Invalid character encountered.

+

+--*/

+CHAR8 *

+ReadLineInStream (

+  IN FILE       *InputFile,

+  IN OUT CHAR8  *InputBuffer

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function reads a line, stripping any comments.

+

+Arguments:

+

+  InputFile     Stream pointer.

+  InputBuffer   Buffer to read into, must be _MAX_PATH size.

+

+Returns:

+

+  NULL if error or EOF

+  InputBuffer otherwise

+

+--*/

+BOOLEAN

+FindSectionInStream (

+  IN FILE       *InputFile,

+  IN CHAR8      *Section

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function parses a stream file from the beginning to find a section.

+  The section string may be anywhere within a line.

+

+Arguments:

+

+  InputFile     Stream pointer.

+  Section       Section to search for

+

+Returns:

+

+  FALSE if error or EOF

+  TRUE if section found

+

+--*/

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/SimpleFileParsing.c b/edk2/Tools/Source/TianoTools/Common/SimpleFileParsing.c
new file mode 100644
index 0000000..3ee3349
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/SimpleFileParsing.c
@@ -0,0 +1,1460 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SimpleFileParsing.c  

+

+Abstract:

+

+  Generic but simple file parsing routines.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+/*

+#include "Tiano.h"

+*/

+#include "EfiUtilityMsgs.h"

+#include "SimpleFileParsing.h"

+

+#ifndef MAX_PATH

+#define MAX_PATH  255

+#endif

+//

+// just in case we get in an endless loop.

+//

+#define MAX_NEST_DEPTH  20

+//

+// number of wchars

+//

+#define MAX_STRING_IDENTIFIER_NAME  100

+

+#define MAX_LINE_LEN                400

+

+#define T_CHAR_SPACE                ' '

+#define T_CHAR_NULL                 0

+#define T_CHAR_CR                   '\r'

+#define T_CHAR_TAB                  '\t'

+#define T_CHAR_LF                   '\n'

+#define T_CHAR_SLASH                '/'

+#define T_CHAR_BACKSLASH            '\\'

+#define T_CHAR_DOUBLE_QUOTE         '"'

+#define T_CHAR_LC_X                 'x'

+#define T_CHAR_0                    '0'

+#define T_CHAR_STAR                 '*'

+

+//

+// We keep a linked list of these for the source files we process

+//

+typedef struct _SOURCE_FILE {

+  FILE                *Fptr;

+  T_CHAR              *FileBuffer;

+  T_CHAR              *FileBufferPtr;

+  unsigned int        FileSize;

+  char                FileName[MAX_PATH];

+  unsigned int        LineNum;

+  BOOLEAN             EndOfFile;

+  BOOLEAN             SkipToHash;

+  struct _SOURCE_FILE *Previous;

+  struct _SOURCE_FILE *Next;

+  T_CHAR              ControlCharacter;

+} SOURCE_FILE;

+

+typedef struct {

+  T_CHAR  *FileBufferPtr;

+} FILE_POSITION;

+

+//

+// Keep all our module globals in this structure

+//

+static struct {

+  SOURCE_FILE SourceFile;

+  BOOLEAN     VerboseFile;

+  BOOLEAN     VerboseToken;

+} mGlobals;

+

+static

+unsigned int

+t_strcmp (

+  T_CHAR *Buffer,

+  T_CHAR *Str

+  );

+

+static

+unsigned int

+t_strncmp (

+  T_CHAR *Str1,

+  T_CHAR *Str2,

+  int    Len

+  );

+

+static

+unsigned int

+t_strlen (

+  T_CHAR *Str

+  );

+

+static

+void

+RewindFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+IsWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+unsigned int

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+PreprocessFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+T_CHAR  *

+t_strcpy (

+  T_CHAR *Dest,

+  T_CHAR *Src

+  );

+

+static

+STATUS

+ProcessIncludeFile (

+  SOURCE_FILE *SourceFile,

+  SOURCE_FILE *ParentSourceFile

+  );

+

+static

+STATUS

+ParseFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+FILE    *

+FindFile (

+  char          *FileName,

+  char          *FoundFileName,

+  unsigned int  FoundFileNameLen

+  );

+

+static

+STATUS

+ProcessFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+STATUS

+GetFilePosition (

+  FILE_POSITION *Fpos

+  );

+

+static

+STATUS

+SetFilePosition (

+  FILE_POSITION *Fpos

+  );

+

+STATUS

+SFPInit (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+  None.

+

+Returns:

+  STATUS_SUCCESS always

+

+--*/

+{

+  memset ((void *) &mGlobals, 0, sizeof (mGlobals));

+  return STATUS_SUCCESS;

+}

+

+unsigned

+int

+SFPGetLineNumber (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return the line number of the file we're parsing. Used

+  for error reporting purposes.

+

+Arguments:

+  None.

+

+Returns:

+  The line number, or 0 if no file is being processed

+

+--*/

+{

+  return mGlobals.SourceFile.LineNum;

+}

+

+T_CHAR *

+SFPGetFileName (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return the name of the file we're parsing. Used

+  for error reporting purposes.

+

+Arguments:

+  None.

+

+Returns:

+  A pointer to the file name. Null if no file is being

+  processed.

+

+--*/

+{

+  if (mGlobals.SourceFile.FileName[0]) {

+    return mGlobals.SourceFile.FileName;

+  }

+

+  return NULL;

+}

+

+STATUS

+SFPOpenFile (

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+  Open a file for parsing.

+

+Arguments:

+  FileName  - name of the file to parse

+

+Returns:

+  

+

+--*/

+{

+  STATUS  Status;

+  t_strcpy (mGlobals.SourceFile.FileName, FileName);

+  Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL);

+  return Status;

+}

+

+BOOLEAN

+SFPIsToken (

+  T_CHAR *Str

+  )

+/*++

+

+Routine Description:

+  Check to see if the specified token is found at

+  the current position in the input file.

+

+Arguments:

+  Str - the token to look for

+

+Returns:

+  TRUE - the token is next

+  FALSE - the token is not next

+

+Notes:

+  We do a simple string comparison on this function. It is

+  the responsibility of the caller to ensure that the token

+  is not a subset of some other token.

+

+  The file pointer is advanced past the token in the input file.

+

+--*/

+{

+  unsigned int  Len;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {

+    mGlobals.SourceFile.FileBufferPtr += Len;

+    if (mGlobals.VerboseToken) {

+      printf ("Token: '%s'\n", Str);

+    }

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+SFPIsKeyword (

+  T_CHAR *Str

+  )

+/*++

+

+Routine Description:

+  Check to see if the specified keyword is found at

+  the current position in the input file.

+

+Arguments:

+  Str - keyword to look for

+

+Returns:

+  TRUE - the keyword is next

+  FALSE - the keyword is not next

+

+Notes:

+  A keyword is defined as a "special" string that has a non-alphanumeric

+  character following it.

+

+--*/

+{

+  unsigned int  Len;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {

+    if (isalnum (mGlobals.SourceFile.FileBufferPtr[Len])) {

+      return FALSE;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr += Len;

+    if (mGlobals.VerboseToken) {

+      printf ("Token: '%s'\n", Str);

+    }

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+SFPGetNextToken (

+  T_CHAR        *Str,

+  unsigned int  Len

+  )

+/*++

+

+Routine Description:

+  Get the next token from the input stream. 

+

+Arguments:

+  Str - pointer to a copy of the next token

+  Len - size of buffer pointed to by Str

+

+Returns:

+  TRUE  - next token successfully returned

+  FALSE - otherwise

+

+Notes:

+  Preceeding white space is ignored. 

+  The parser's buffer pointer is advanced past the end of the

+  token.

+

+--*/

+{

+  unsigned int  Index;

+  T_CHAR        TempChar;

+

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+  //

+  // Have to have enough string for at least one char and a null-terminator

+  //

+  if (Len < 2) {

+    return FALSE;

+  }

+  //

+  // Look at the first character. If it's an identifier, then treat it

+  // as such

+  //

+  TempChar = mGlobals.SourceFile.FileBufferPtr[0];

+  if (((TempChar >= 'a') && (TempChar <= 'z')) || ((TempChar >= 'A') && (TempChar <= 'Z')) || (TempChar == '_')) {

+    Str[0] = TempChar;

+    mGlobals.SourceFile.FileBufferPtr++;

+    Index = 1;

+    while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {

+      TempChar = mGlobals.SourceFile.FileBufferPtr[0];

+      if (((TempChar >= 'a') && (TempChar <= 'z')) ||

+          ((TempChar >= 'A') && (TempChar <= 'Z')) ||

+          ((TempChar >= '0') && (TempChar <= '9')) ||

+          (TempChar == '_')

+          ) {

+        Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];

+        mGlobals.SourceFile.FileBufferPtr++;

+        Index++;

+      } else {

+        //

+        // Invalid character for symbol name, so break out

+        //

+        break;

+      }

+    }

+    //

+    // Null terminate and return success

+    //

+    Str[Index] = 0;

+    return TRUE;

+  } else if ((TempChar == ')') || (TempChar == '(') || (TempChar == '*')) {

+    Str[0] = mGlobals.SourceFile.FileBufferPtr[0];

+    mGlobals.SourceFile.FileBufferPtr++;

+    Str[1] = 0;

+    return TRUE;

+  } else {

+    //

+    // Everything else is white-space (or EOF) separated

+    //

+    Index = 0;

+    while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {

+      if (IsWhiteSpace (&mGlobals.SourceFile)) {

+        if (Index > 0) {

+          Str[Index] = 0;

+          return TRUE;

+        }

+

+        return FALSE;

+      } else {

+        Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];

+        mGlobals.SourceFile.FileBufferPtr++;

+        Index++;

+      }

+    }

+    //

+    // See if we just ran out of file contents, but did find a token

+    //

+    if ((Index > 0) && EndOfFile (&mGlobals.SourceFile)) {

+      Str[Index] = 0;

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+SFPGetGuidToken (

+  T_CHAR *Str,

+  UINT32 Len

+  )

+/*++

+

+Routine Description:

+  Parse a GUID from the input stream. Stop when you discover white space.

+

+Arguments:

+  Str - pointer to a copy of the next token

+  Len - size of buffer pointed to by Str

+

+Returns:

+  TRUE  - GUID string returned successfully

+  FALSE - otherwise

+

+--*/

+{

+  UINT32  Index;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  Index = 0;

+  while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {

+    if (IsWhiteSpace (&mGlobals.SourceFile)) {

+      if (Index > 0) {

+        Str[Index] = 0;

+        return TRUE;

+      }

+

+      return FALSE;

+    } else {

+      Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];

+      mGlobals.SourceFile.FileBufferPtr++;

+      Index++;

+    }

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+SFPSkipToToken (

+  T_CHAR *Str

+  )

+{

+  unsigned int  Len;

+  T_CHAR        *SavePos;

+  Len     = t_strlen (Str);

+  SavePos = mGlobals.SourceFile.FileBufferPtr;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  while (!EndOfFile (&mGlobals.SourceFile)) {

+    if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) {

+      mGlobals.SourceFile.FileBufferPtr += Len;

+      return TRUE;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr++;

+    SkipWhiteSpace (&mGlobals.SourceFile);

+  }

+

+  mGlobals.SourceFile.FileBufferPtr = SavePos;

+  return FALSE;

+}

+

+BOOLEAN

+SFPGetNumber (

+  unsigned int *Value

+  )

+/*++

+

+Routine Description:

+  Check the token at the current file position for a numeric value.

+  May be either decimal or hex.

+

+Arguments:

+  Value  - pointer where to store the value

+

+Returns:

+  FALSE    - current token is not a number

+  TRUE     - current token is a number

+

+--*/

+{

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+    //

+    // Check for hex value

+    //

+    if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) {

+      if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) {

+        return FALSE;

+      }

+

+      mGlobals.SourceFile.FileBufferPtr += 2;

+      sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value);

+      while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+        mGlobals.SourceFile.FileBufferPtr++;

+      }

+

+      return TRUE;

+    } else {

+      *Value = atoi (mGlobals.SourceFile.FileBufferPtr);

+      while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+        mGlobals.SourceFile.FileBufferPtr++;

+      }

+

+      return TRUE;

+    }

+  } else {

+    return FALSE;

+  }

+}

+

+STATUS

+SFPCloseFile (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Close the file being parsed.

+

+Arguments:

+  None.

+

+Returns:

+  STATUS_SUCCESS - the file was closed 

+  STATUS_ERROR   - no file is currently open

+

+--*/

+{

+  if (mGlobals.SourceFile.FileBuffer != NULL) {

+    free (mGlobals.SourceFile.FileBuffer);

+    memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile));

+    return STATUS_SUCCESS;

+  }

+

+  return STATUS_ERROR;

+}

+

+static

+STATUS

+ProcessIncludeFile (

+  SOURCE_FILE *SourceFile,

+  SOURCE_FILE *ParentSourceFile

+  )

+/*++

+

+Routine Description:

+

+  Given a source file, open the file and parse it

+  

+Arguments:

+

+  SourceFile        - name of file to parse

+  ParentSourceFile  - for error reporting purposes, the file that #included SourceFile.

+

+Returns:

+

+  Standard status.

+  

+--*/

+{

+  static unsigned int NestDepth = 0;

+  char                FoundFileName[MAX_PATH];

+  STATUS              Status;

+

+  Status = STATUS_SUCCESS;

+  NestDepth++;

+  //

+  // Print the file being processed. Indent so you can tell the include nesting

+  // depth.

+  //

+  if (mGlobals.VerboseFile) {

+    fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);

+    fprintf (stdout, "Parent source file = '%s'\n", ParentSourceFile);

+  }

+

+  //

+  // Make sure we didn't exceed our maximum nesting depth

+  //

+  if (NestDepth > MAX_NEST_DEPTH) {

+    Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);

+    Status = STATUS_ERROR;

+    goto Finish;

+  }

+  //

+  // Try to open the file locally, and if that fails try along our include paths.

+  //

+  strcpy (FoundFileName, SourceFile->FileName);

+  if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) {

+    return STATUS_ERROR;

+  }

+  //

+  // Process the file found

+  //

+  ProcessFile (SourceFile);

+Finish:

+  //

+  // Close open files and return status

+  //

+  if (SourceFile->Fptr != NULL) {

+    fclose (SourceFile->Fptr);

+    SourceFile->Fptr = NULL;

+  }

+

+  return Status;

+}

+

+static

+STATUS

+ProcessFile (

+  SOURCE_FILE *SourceFile

+  )

+/*++

+

+Routine Description:

+

+  Given a source file that's been opened, read the contents into an internal

+  buffer and pre-process it to remove comments.

+  

+Arguments:

+

+  SourceFile        - structure containing info on the file to process

+

+Returns:

+

+  Standard status.

+  

+--*/

+{

+  //

+  // Get the file size, and then read the entire thing into memory.

+  // Allocate extra space for a terminator character.

+  //

+  fseek (SourceFile->Fptr, 0, SEEK_END);

+  SourceFile->FileSize = ftell (SourceFile->Fptr);

+  if (mGlobals.VerboseFile) {

+    printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize);

+  }

+

+  fseek (SourceFile->Fptr, 0, SEEK_SET);

+  SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR));

+  if (SourceFile->FileBuffer == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  fread ((void *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);

+  SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL;

+  //

+  // Pre-process the file to replace comments with spaces

+  //

+  PreprocessFile (SourceFile);

+  SourceFile->LineNum = 1;

+  return STATUS_SUCCESS;

+}

+

+static

+void

+PreprocessFile (

+  SOURCE_FILE *SourceFile

+  )

+/*++

+

+Routine Description:

+  Preprocess a file to replace all carriage returns with NULLs so

+  we can print lines (as part of error messages) from the file to the screen.

+  

+Arguments:

+  SourceFile - structure that we use to keep track of an input file.

+

+Returns:

+  Nothing.

+  

+--*/

+{

+  BOOLEAN InComment;

+  BOOLEAN SlashSlashComment;

+  int     LineNum;

+

+  RewindFile (SourceFile);

+  InComment         = FALSE;

+  SlashSlashComment = FALSE;

+  while (!EndOfFile (SourceFile)) {

+    //

+    // If a line-feed, then no longer in a comment if we're in a // comment

+    //

+    if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      if (InComment && SlashSlashComment) {

+        InComment         = FALSE;

+        SlashSlashComment = FALSE;

+      }

+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {

+      //

+      // Replace all carriage returns with a NULL so we can print stuff

+      //

+      SourceFile->FileBufferPtr[0] = 0;

+      SourceFile->FileBufferPtr++;

+      //

+      // Check for */ comment end

+      //

+    } else if (InComment &&

+             !SlashSlashComment &&

+             (SourceFile->FileBufferPtr[0] == T_CHAR_STAR) &&

+             (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)

+            ) {

+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;

+      SourceFile->FileBufferPtr++;

+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;

+      SourceFile->FileBufferPtr++;

+      InComment = FALSE;

+    } else if (InComment) {

+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;

+      SourceFile->FileBufferPtr++;

+      //

+      // Check for // comments

+      //

+    } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) {

+      InComment         = TRUE;

+      SlashSlashComment = TRUE;

+      //

+      // Check for /* comment start

+      //

+    } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_STAR)) {

+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;

+      SourceFile->FileBufferPtr++;

+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;

+      SourceFile->FileBufferPtr++;

+      SlashSlashComment = FALSE;

+      InComment         = TRUE;

+    } else {

+      SourceFile->FileBufferPtr++;

+    }

+  }

+  //

+  // Could check for end-of-file and still in a comment, but

+  // should not be necessary. So just restore the file pointers.

+  //

+  RewindFile (SourceFile);

+  //

+  // Dump the reformatted file if verbose mode

+  //

+  if (mGlobals.VerboseFile) {

+    LineNum = 1;

+    printf ("%04d: ", LineNum);

+    while (!EndOfFile (SourceFile)) {

+      if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {

+        printf ("'\n%04d: '", ++LineNum);

+      } else {

+        printf ("%c", SourceFile->FileBufferPtr[0]);

+      }

+

+      SourceFile->FileBufferPtr++;

+    }

+

+    printf ("'\n");

+    printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize);

+    RewindFile (SourceFile);

+  }

+}

+

+BOOLEAN

+SFPGetQuotedString (

+  T_CHAR      *Str,

+  int         Length

+  )

+/*++

+

+Routine Description:

+  Retrieve a quoted-string from the input file. 

+  

+Arguments:

+  Str    - pointer to a copy of the quoted string parsed

+  Length - size of buffer pointed to by Str

+

+Returns:

+  TRUE    - next token in input stream was a quoted string, and

+            the string value was returned in Str

+  FALSE   - otherwise

+  

+--*/

+{

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {

+    mGlobals.SourceFile.FileBufferPtr++;

+    while (Length > 0) {

+      if (EndOfFile (&mGlobals.SourceFile)) {

+        return FALSE;

+      }

+      //

+      // Check for closing quote

+      //

+      if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {

+        mGlobals.SourceFile.FileBufferPtr++;

+        *Str = 0;

+        return TRUE;

+      }

+

+      *Str = mGlobals.SourceFile.FileBufferPtr[0];

+      Str++;

+      Length--;

+      mGlobals.SourceFile.FileBufferPtr++;

+    }

+  }

+  //

+  // First character was not a quote, or the input string length was

+  // insufficient to contain the quoted string, so return failure code.

+  //

+  return FALSE;

+}

+

+BOOLEAN

+SFPIsEOF (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return TRUE of FALSE to indicate whether or not we've reached the end of the

+  file we're parsing.

+  

+Arguments:

+  NA

+

+Returns:

+  TRUE    - EOF reached

+  FALSE   - otherwise

+  

+--*/

+{

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  return EndOfFile (&mGlobals.SourceFile);

+}

+

+#if 0

+static

+T_CHAR *

+GetQuotedString (

+  SOURCE_FILE *SourceFile,

+  BOOLEAN     Optional

+  )

+{

+  T_CHAR        *String;

+  T_CHAR        *Start;

+  T_CHAR        *Ptr;

+  unsigned int  Len;

+  BOOLEAN       PreviousBackslash;

+

+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {

+    if (Optional == FALSE) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);

+    }

+

+    return NULL;

+  }

+

+  Len = 0;

+  SourceFile->FileBufferPtr++;

+  Start             = Ptr = SourceFile->FileBufferPtr;

+  PreviousBackslash = FALSE;

+  while (!EndOfFile (SourceFile)) {

+    if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (PreviousBackslash == FALSE)) {

+      break;

+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {

+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);

+      PreviousBackslash = FALSE;

+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) {

+      PreviousBackslash = TRUE;

+    } else {

+      PreviousBackslash = FALSE;

+    }

+

+    SourceFile->FileBufferPtr++;

+    Len++;

+  }

+

+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {

+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);

+  } else {

+    SourceFile->FileBufferPtr++;

+  }

+  //

+  // Now allocate memory for the string and save it off

+  //

+  String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR));

+  if (String == NULL) {

+    Error (NULL, 0, 0, "memory allocation failed", NULL);

+    return NULL;

+  }

+  //

+  // Copy the string from the file buffer to the local copy.

+  // We do no reformatting of it whatsoever at this point.

+  //

+  Ptr = String;

+  while (Len > 0) {

+    *Ptr = *Start;

+    Start++;

+    Ptr++;

+    Len--;

+  }

+

+  *Ptr = 0;

+  return String;

+}

+#endif

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  //

+  // The file buffer pointer will typically get updated before the End-of-file flag in the

+  // source file structure, so check it first.

+  //

+  if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) {

+    SourceFile->EndOfFile = TRUE;

+    return TRUE;

+  }

+

+  if (SourceFile->EndOfFile) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+#if 0

+static

+void

+ProcessTokenInclude (

+  SOURCE_FILE *SourceFile

+  )

+{

+  char          IncludeFileName[MAX_PATH];

+  char          *To;

+  unsigned int  Len;

+  BOOLEAN       ReportedError;

+  SOURCE_FILE   IncludedSourceFile;

+

+  ReportedError = FALSE;

+  if (SkipWhiteSpace (SourceFile) == 0) {

+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);

+  }

+  //

+  // Should be quoted file name

+  //

+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);

+    goto FailDone;

+  }

+

+  SourceFile->FileBufferPtr++;

+  //

+  // Copy the filename as ascii to our local string

+  //

+  To  = IncludeFileName;

+  Len = 0;

+  while (!EndOfFile (SourceFile)) {

+    if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);

+      goto FailDone;

+    }

+

+    if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {

+      SourceFile->FileBufferPtr++;

+      break;

+    }

+    //

+    // If too long, then report the error once and process until the closing quote

+    //

+    Len++;

+    if (!ReportedError && (Len >= sizeof (IncludeFileName))) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);

+      ReportedError = TRUE;

+    }

+

+    if (!ReportedError) {

+      *To = (T_CHAR) SourceFile->FileBufferPtr[0];

+      To++;

+    }

+

+    SourceFile->FileBufferPtr++;

+  }

+

+  if (!ReportedError) {

+    *To = 0;

+    memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));

+    strcpy (IncludedSourceFile.FileName, IncludeFileName);

+    ProcessIncludeFile (&IncludedSourceFile, SourceFile);

+  }

+

+  return ;

+FailDone:

+  //

+  // Error recovery -- skip to next #

+  //

+  SourceFile->SkipToHash = TRUE;

+}

+#endif

+static

+BOOLEAN

+IsWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+{

+  switch (*SourceFile->FileBufferPtr) {

+  case T_CHAR_NULL:

+  case T_CHAR_CR:

+  case T_CHAR_SPACE:

+  case T_CHAR_TAB:

+  case T_CHAR_LF:

+    return TRUE;

+

+  default:

+    return FALSE;

+  }

+}

+

+unsigned int

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+{

+  unsigned int  Count;

+

+  Count = 0;

+  while (!EndOfFile (SourceFile)) {

+    Count++;

+    switch (*SourceFile->FileBufferPtr) {

+    case T_CHAR_NULL:

+    case T_CHAR_CR:

+    case T_CHAR_SPACE:

+    case T_CHAR_TAB:

+      SourceFile->FileBufferPtr++;

+      break;

+

+    case T_CHAR_LF:

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      break;

+

+    default:

+      return Count - 1;

+    }

+  }

+  //

+  // Some tokens require trailing whitespace. If we're at the end of the

+  // file, then we count that as well.

+  //

+  if ((Count == 0) && (EndOfFile (SourceFile))) {

+    Count++;

+  }

+

+  return Count;

+}

+

+static

+unsigned int

+t_strcmp (

+  T_CHAR *Buffer,

+  T_CHAR *Str

+  )

+/*++

+

+Routine Description:

+  Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,

+  so only compare up to the length of Str.

+

+Arguments:

+  Buffer  - pointer to first (possibly not null-terminated) string

+  Str     - pointer to null-terminated string to compare to Buffer

+

+Returns:

+  Number of bytes matched if exact match

+  0 if Buffer does not start with Str

+

+--*/

+{

+  unsigned int  Len;

+

+  Len = 0;

+  while (*Str && (*Str == *Buffer)) {

+    Buffer++;

+    Str++;

+    Len++;

+  }

+

+  if (*Str) {

+    return 0;

+  }

+

+  return Len;

+}

+

+static

+unsigned int

+t_strlen (

+  T_CHAR *Str

+  )

+{

+  unsigned int  Len;

+  Len = 0;

+  while (*Str) {

+    Len++;

+    Str++;

+  }

+

+  return Len;

+}

+

+static

+unsigned int

+t_strncmp (

+  T_CHAR *Str1,

+  T_CHAR *Str2,

+  int    Len

+  )

+{

+  while (Len > 0) {

+    if (*Str1 != *Str2) {

+      return Len;

+    }

+

+    Len--;

+    Str1++;

+    Str2++;

+  }

+

+  return 0;

+}

+

+static

+T_CHAR *

+t_strcpy (

+  T_CHAR *Dest,

+  T_CHAR *Src

+  )

+{

+  T_CHAR  *SaveDest;

+  SaveDest = Dest;

+  while (*Src) {

+    *Dest = *Src;

+    Dest++;

+    Src++;

+  }

+

+  *Dest = 0;

+  return SaveDest;

+}

+

+static

+void

+RewindFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  SourceFile->LineNum       = 1;

+  SourceFile->FileBufferPtr = SourceFile->FileBuffer;

+  SourceFile->EndOfFile     = 0;

+}

+

+static

+UINT32

+GetHexChars (

+  T_CHAR      *Buffer,

+  UINT32      BufferLen

+  )

+{

+  UINT32  Len;

+  Len = 0;

+  while (!EndOfFile (&mGlobals.SourceFile) && (BufferLen > 0)) {

+    if (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+      *Buffer = mGlobals.SourceFile.FileBufferPtr[0];

+      Buffer++;

+      Len++;

+      BufferLen--;

+      mGlobals.SourceFile.FileBufferPtr++;

+    } else {

+      break;

+    }

+  }

+  //

+  // Null terminate if we can

+  //

+  if ((Len > 0) && (BufferLen > 0)) {

+    *Buffer = 0;

+  }

+

+  return Len;

+}

+

+BOOLEAN

+SFPGetGuid (

+  int         GuidStyle,

+  EFI_GUID    *Value

+  )

+/*++

+

+Routine Description:

+  Parse a GUID from the input stream. Stop when you discover white space.

+

+Arguments:

+  GuidStyle - Style of the following GUID token

+  Value     - pointer to EFI_GUID struct for output

+

+Returns:

+  TRUE  - GUID string parsed successfully

+  FALSE - otherwise

+

+  GUID styles

+    Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD

+

+--*/

+{

+  UINT32        Value32;

+  UINT32        Index;

+  FILE_POSITION FPos;

+  T_CHAR        TempString[20];

+  T_CHAR        TempString2[3];

+  T_CHAR        *From;

+  T_CHAR        *To;

+  UINT32        Len;

+  BOOLEAN       Status;

+

+  Status = FALSE;

+  //

+  // Skip white space, then start parsing

+  //

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  GetFilePosition (&FPos);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  if (GuidStyle == PARSE_GUID_STYLE_5_FIELDS) {

+    //

+    // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD

+    //

+    Len = GetHexChars (TempString, sizeof (TempString));

+    if ((Len == 0) || (Len > 8)) {

+      goto Done;

+    }

+

+    sscanf (TempString, "%x", &Value32);

+    Value->Data1 = Value32;

+    //

+    // Next two UINT16 fields

+    //

+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {

+      goto Done;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr++;

+    Len = GetHexChars (TempString, sizeof (TempString));

+    if ((Len == 0) || (Len > 4)) {

+      goto Done;

+    }

+

+    sscanf (TempString, "%x", &Value32);

+    Value->Data2 = (UINT16) Value32;

+

+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {

+      goto Done;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr++;

+    Len = GetHexChars (TempString, sizeof (TempString));

+    if ((Len == 0) || (Len > 4)) {

+      goto Done;

+    }

+

+    sscanf (TempString, "%x", &Value32);

+    Value->Data3 = (UINT16) Value32;

+    //

+    // Parse the "AAAA" as two bytes

+    //

+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {

+      goto Done;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr++;

+    Len = GetHexChars (TempString, sizeof (TempString));

+    if ((Len == 0) || (Len > 4)) {

+      goto Done;

+    }

+

+    sscanf (TempString, "%x", &Value32);

+    Value->Data4[0] = (UINT8) (Value32 >> 8);

+    Value->Data4[1] = (UINT8) Value32;

+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {

+      goto Done;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr++;

+    //

+    // Read the last 6 bytes of the GUID

+    //

+    //

+    Len = GetHexChars (TempString, sizeof (TempString));

+    if ((Len == 0) || (Len > 12)) {

+      goto Done;

+    }

+    //

+    // Insert leading 0's to make life easier

+    //

+    if (Len != 12) {

+      From            = TempString + Len - 1;

+      To              = TempString + 11;

+      TempString[12]  = 0;

+      while (From >= TempString) {

+        *To = *From;

+        To--;

+        From--;

+      }

+

+      while (To >= TempString) {

+        *To = '0';

+        To--;

+      }

+    }

+    //

+    // Now parse each byte

+    //

+    TempString2[2] = 0;

+    for (Index = 0; Index < 6; Index++) {

+      //

+      // Copy the two characters from the input string to something

+      // we can parse.

+      //

+      TempString2[0]  = TempString[Index * 2];

+      TempString2[1]  = TempString[Index * 2 + 1];

+      sscanf (TempString2, "%x", &Value32);

+      Value->Data4[Index + 2] = (UINT8) Value32;

+    }

+

+    Status = TRUE;

+  } else {

+    //

+    // Unsupported GUID style

+    //

+    return FALSE;

+  }

+

+Done:

+  if (Status == FALSE) {

+    SetFilePosition (&FPos);

+  }

+

+  return Status;

+}

+

+static

+STATUS

+GetFilePosition (

+  FILE_POSITION *Fpos

+  )

+{

+  Fpos->FileBufferPtr = mGlobals.SourceFile.FileBufferPtr;

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+SetFilePosition (

+  FILE_POSITION *Fpos

+  )

+{

+  //

+  // Should check range of pointer

+  //

+  mGlobals.SourceFile.FileBufferPtr = Fpos->FileBufferPtr;

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/Common/SimpleFileParsing.h b/edk2/Tools/Source/TianoTools/Common/SimpleFileParsing.h
new file mode 100644
index 0000000..ea1f5a0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/SimpleFileParsing.h
@@ -0,0 +1,121 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SimpleFileParsing.h

+

+Abstract:

+

+  Function prototypes and defines for the simple file parsing routines.

+

+--*/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+#ifndef _SIMPLE_FILE_PARSING_H_

+#define _SIMPLE_FILE_PARSING_H_

+

+#define T_CHAR  char

+

+STATUS

+SFPInit (

+  VOID

+  )

+;

+

+STATUS

+SFPOpenFile (

+  char    *FileName

+  )

+;

+

+BOOLEAN

+SFPIsKeyword (

+  T_CHAR *Str

+  )

+;

+

+BOOLEAN

+SFPIsToken (

+  T_CHAR *Str

+  )

+;

+

+BOOLEAN

+SFPGetNextToken (

+  T_CHAR        *Str,

+  unsigned int  Len

+  )

+;

+

+BOOLEAN

+SFPGetGuidToken (

+  T_CHAR *Str,

+  UINT32 Len

+  )

+;

+

+#define PARSE_GUID_STYLE_5_FIELDS 0

+

+BOOLEAN

+SFPGetGuid (

+  int         GuidStyle,

+  EFI_GUID    *Value

+  )

+;

+

+BOOLEAN

+SFPSkipToToken (

+  T_CHAR *Str

+  )

+;

+

+BOOLEAN

+SFPGetNumber (

+  unsigned int   *Value

+  )

+;

+

+BOOLEAN

+SFPGetQuotedString (

+  T_CHAR      *Str,

+  int         Length

+  )

+;

+

+BOOLEAN

+SFPIsEOF (

+  VOID

+  )

+;

+

+STATUS

+SFPCloseFile (

+  VOID

+  )

+;

+

+unsigned

+int

+SFPGetLineNumber (

+  VOID

+  )

+;

+

+T_CHAR  *

+SFPGetFileName (

+  VOID

+  )

+;

+

+#endif // #ifndef _SIMPLE_FILE_PARSING_H_

diff --git a/edk2/Tools/Source/TianoTools/Common/WinNtInclude.h b/edk2/Tools/Source/TianoTools/Common/WinNtInclude.h
new file mode 100644
index 0000000..80e45b4
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/WinNtInclude.h
@@ -0,0 +1,73 @@
+/*--

+

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+

+Module Name:

+  WinNtInclude.h

+

+Abstract:

+  Include file for the WinNt Library

+

+--*/

+

+#ifndef __WIN_NT_INCLUDE_H__

+#define __WIN_NT_INCLUDE_H__

+

+//

+// Win32 include files do not compile clean with /W4, so we use the warning

+// pragma to suppress the warnings for Win32 only. This way our code can stil

+// compile at /W4 (highest warning level) with /WX (warnings cause build

+// errors).

+//

+#pragma warning(disable : 4115)

+#pragma warning(disable : 4201)

+#pragma warning(disable : 4214)

+#pragma warning(disable : 4028)

+#pragma warning(disable : 4133)

+

+#define GUID  _WINNT_DUP_GUID_____

+#define _LIST_ENTRY  _WINNT_DUP_LIST_ENTRY_FORWARD

+#define LIST_ENTRY   _WINNT_DUP_LIST_ENTRY

+#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement

+#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement

+#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64

+#undef UNALIGNED

+#undef CONST

+#undef VOID

+

+#ifndef __GNUC__

+#include "windows.h"

+#endif

+

+#undef GUID

+#undef _LIST_ENTRY

+#undef LIST_ENTRY

+#undef InterlockedIncrement

+#undef InterlockedDecrement

+#undef InterlockedCompareExchange64

+#undef InterlockedCompareExchangePointer

+

+#define VOID void

+

+//

+// Prevent collisions with Windows API name macros that deal with Unicode/Not issues

+//

+#undef LoadImage

+#undef CreateEvent

+

+//

+// Set the warnings back on as the EFI code must be /W4.

+//

+#pragma warning(default : 4115)

+#pragma warning(default : 4201)

+#pragma warning(default : 4214)

+

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Common/build.xml b/edk2/Tools/Source/TianoTools/Common/build.xml
new file mode 100644
index 0000000..a8cec23
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Common/build.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="CommonTools.lib" basedir=".">

+<!--

+    EDK Common Tools Library

+  Copyright (c) 2006, Intel Corporation

+-->

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+  <property name="tmp" value="tmp"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/Common/tmp"/>

+

+  <target name="CommonTools.lib" depends="init, ToolsLibrary">

+    <echo message="Building the EDK CommonTools Library"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK CommonTools Library"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="ToolsLibrary" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${LIB_DIR}/CommonTools"

+        outtype="static"

+        optimize="speed">

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+

+      <fileset dir="${basedir}/Common" 

+        includes="*.c" />

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only from ${BUILD_DIR}"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Library: CommonTools${ext_static}"/>  

+    <delete dir="${BUILD_DIR}" failonerror="false">

+      <fileset dir="${LIB_DIR}" includes="CommonTools${ext_static}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/CompressDll/CompressDll.c b/edk2/Tools/Source/TianoTools/CompressDll/CompressDll.c
new file mode 100644
index 0000000..783587f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CompressDll/CompressDll.c
@@ -0,0 +1,89 @@
+#include "CompressDll.h"

+#include "EfiCompress.h"

+

+extern

+EFI_STATUS

+Compress (

+  IN      UINT8   *SrcBuffer,

+  IN      UINT32  SrcSize,

+  IN      UINT8   *DstBuffer,

+  IN OUT  UINT32  *DstSize

+  );

+  

+JNIEXPORT jbyteArray JNICALL  Java_org_tianocore_framework_tasks_Compress_CallCompress 

+(JNIEnv *env, jobject obj, jbyteArray SourceBuffer, jint SourceSize, jstring path)

+{

+  char*          DestBuffer;

+  int            DestSize;   

+  int            Result;

+  char           *InputBuffer;

+  jbyteArray     OutputBuffer;

+  jbyte          *TempByte;

+  

+  DestSize   = 0;

+  DestBuffer = NULL;

+  

+  TempByte = (*env)->GetByteArrayElements(env, SourceBuffer, 0);

+  InputBuffer = (char*) TempByte;

+

+  

+   //

+   //  First call compress function and get need buffer size

+   //

+

+   Result = Compress (

+			  (char*) InputBuffer, 

+			  SourceSize,  

+			  DestBuffer,

+			  &DestSize

+			  );

+

+   if (Result = EFI_BUFFER_TOO_SMALL) {

+	   DestBuffer = malloc (DestSize);

+   }

+

+   //

+   //  Second call compress and get the DestBuffer value

+   //

+   Result = Compress(

+              (char*) InputBuffer, 

+			  SourceSize,  

+			  DestBuffer,

+			  &DestSize  

+	   );

+

+   //

+   // new a MV array to store the return compressed buffer

+   //

+   OutputBuffer = (*env)->NewByteArray(env, DestSize);

+   (*env)->SetByteArrayRegion(env, OutputBuffer,0, DestSize, (jbyte*) DestBuffer);

+

+   //

+   // Free Ouputbuffer.

+   //

+   free (DestBuffer);

+  

+

+  if (Result != 0) {

+    return NULL;

+  } else {

+    return OutputBuffer;

+  }

+}

+

+#ifdef _MSC_VER

+BOOLEAN 

+__stdcall 

+DllMainCRTStartup(

+    unsigned int hDllHandle, 

+    unsigned int nReason,    

+    void*   Reserved    

+)

+{

+	return TRUE;

+}

+#else

+#ifdef __GNUC__

+#endif

+#endif

+

diff --git a/edk2/Tools/Source/TianoTools/CompressDll/CompressDll.h b/edk2/Tools/Source/TianoTools/CompressDll/CompressDll.h
new file mode 100644
index 0000000..3b0fbb2
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CompressDll/CompressDll.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */

+#include <jni.h>

+/* Header for class org_tianocore_frameworktasks_Compress */

+

+#ifndef _Included_org_tianocore_framework_tasks_Compress

+#define _Included_org_tianocore_framework_tasks_Compress

+#ifdef __cplusplus

+extern "C" {

+#endif

+/*

+ * Class:     org_tianocore_frameworktasks_Compress

+ * Method:    CallCompress

+ * Signature: ([BILjava/lang/String;)[B

+ */

+JNIEXPORT jbyteArray JNICALL Java_org_tianocore_framework_tasks_Compress_CallCompress

+  (JNIEnv *, jobject, jbyteArray, jint, jstring);

+

+#ifdef __cplusplus

+}

+#endif

+#endif

diff --git a/edk2/Tools/Source/TianoTools/CompressDll/build.xml b/edk2/Tools/Source/TianoTools/CompressDll/build.xml
new file mode 100644
index 0000000..40df87f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CompressDll/build.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+  <!--EDK GenDepex Tool

+  Copyright (c) 2006, Intel Corporation-->

+  <property environment="env"/>

+  <property name="WORKSPACE" value="${env.WORKSPACE}"/>

+  <property name="ToolName" value="CompressDll"/>

+  <property name="LibName" value="CompressDll"/>

+  <property name="FileSet" value="CompressDll.c CompressDll.h"/>

+  <property name="LibFileSet" value="CompressDll.c DepexParser.h"/>

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${WORKSPACE}/Tools/Source/TianoTools/${ToolName}/tmp"/>

+  <target name="GenTool" depends="init,Lib" >

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+      <elseif>

+        <os family="dos"/>

+        <then>

+          <echo message="Windows Family"/>

+          <property name="ToolChain" value="msvc"/>

+        </then>

+      </elseif>

+      <elseif>

+        <os family="unix"/>

+        <then>

+          <echo message="UNIX Family"/>

+          <property name="ToolChain" value="gcc"/>

+        </then>

+      </elseif>

+      <else>

+        <echo>Unsupported Operating System

+        Please Contact Intel Corporation</echo>

+      </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+  

+  <target name="Lib" depends="init">

+    <cc name="${ToolChain}" 

+      objdir="${BUILD_DIR}" 

+      outtype="shared" 

+      optimize="speed" 

+      outfile="${BIN_DIR}/${LibName}"

+      outputfileproperty="result"

+      >

+      <fileset dir="${ToolName}" includes="${LibFileSet}" defaultexcludes="TRUE" excludes="*.xml *.inf"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <includepath path="${env.JAVA_HOME}/include"/>

+      <includepath path="${env.JAVA_HOME}/include/win32" if="windows"/>

+      <includepath path="${env.JAVA_HOME}/include/linux" if="linux"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools"/>

+      <syslibset libs="kernel32" unless="gcc"/>

+    </cc>

+    <copy file="${result}" tofile="${BIN_DIR}/CompressDll.dll"/>

+    <chmod file="${BIN_DIR}/CompressDll.dll" perm="ugo+x"/>

+  </target>

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_dynamic}"/>

+    </delete>

+  </target>

+</project>

diff --git a/edk2/Tools/Source/TianoTools/CreateMtFile/CreateMtFile.c b/edk2/Tools/Source/TianoTools/CreateMtFile/CreateMtFile.c
new file mode 100644
index 0000000..055c187
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CreateMtFile/CreateMtFile.c
@@ -0,0 +1,247 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  CreateMtFile.c

+

+Abstract:

+

+  Simple utility to create a pad file containing fixed data.

+  

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include "UefiBaseTypes.h"

+#include "Base.h"

+

+#define PROGRAM_NAME  "CreateMtFile"

+

+typedef struct {

+  INT8    *OutFileName;

+  INT8    ByteValue;

+  UINT32  FileSize;

+} OPTIONS;

+

+static

+EFI_STATUS

+ProcessArgs (

+  IN INT32          Argc,

+  IN INT8           *Argv[],

+  IN OUT OPTIONS    *Options

+  );

+

+static

+void

+Usage (

+  VOID

+  );

+

+int

+main (

+  IN INT32  Argc,

+  IN INT8   *Argv[]

+  )

+/*++

+

+Routine Description:

+  

+  Main entry point for this utility.

+

+Arguments:

+

+  Standard C entry point args Argc and Argv

+

+Returns:

+

+  EFI_SUCCESS if good to go

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment

+// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment

+{

+  FILE    *OutFptr;

+  OPTIONS Options;

+

+  //

+  // Process the command-line arguments.

+  //

+  if (ProcessArgs (Argc, Argv, &Options) != EFI_SUCCESS) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Open the output file

+  //

+  if ((OutFptr = fopen (Options.OutFileName, "wb")) == NULL) {

+    fprintf (

+      stdout,

+      PROGRAM_NAME " ERROR: Could not open output file '%s' for writing\n",

+      Options.OutFileName

+      );

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Write the pad bytes. Do it the slow way (one at a time) for now.

+  //

+  while (Options.FileSize > 0) {

+    if (fwrite (&Options.ByteValue, 1, 1, OutFptr) != 1) {

+      fclose (OutFptr);

+      fprintf (stdout, PROGRAM_NAME " ERROR: Failed to write to output file\n");

+      return EFI_DEVICE_ERROR;

+    }

+

+    Options.FileSize--;

+  }

+  //

+  // Close the file

+  //

+  fclose (OutFptr);

+  return EFI_SUCCESS;

+}

+

+static

+EFI_STATUS

+ProcessArgs (

+  IN INT32          Argc,

+  IN INT8           *Argv[],

+  IN OUT OPTIONS    *Options

+  )

+/*++

+

+Routine Description:

+  

+  Process the command line arguments.

+

+Arguments:

+

+  Argc    - argument count as passed in to the entry point function

+  Argv    - array of arguments as passed in to the entry point function

+  Options - stucture of where to put the values of the parsed arguments

+

+Returns:

+

+  EFI_SUCCESS if everything looks good

+  EFI_INVALID_PARAMETER otherwise

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+{

+  UINT32  Multiplier;

+

+  //

+  // Clear the options

+  //

+  memset ((char *) Options, 0, sizeof (OPTIONS));

+

+  //

+  // Skip program name

+  //

+  Argv++;

+  Argc--;

+  if (Argc < 2) {

+    Usage ();

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // If first arg is dash-option, then print usage.

+  //

+  if (Argv[0][0] == '-') {

+    Usage ();

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // First arg is file name

+  //

+  Options->OutFileName = Argv[0];

+  Argc--;

+  Argv++;

+

+  //

+  // Second arg is file size. Allow 0x1000, 0x100K, 1024, 1K

+  //

+  Multiplier = 1;

+  if ((Argv[0][strlen (Argv[0]) - 1] == 'k') || (Argv[0][strlen (Argv[0]) - 1] == 'K')) {

+    Multiplier = 1024;

+  }

+  //

+  // Look for 0x prefix on file size

+  //

+  if ((Argv[0][0] == '0') && ((Argv[0][1] == 'x') || (Argv[0][1] == 'X'))) {

+    if (sscanf (Argv[0], "%x", &Options->FileSize) != 1) {

+      fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]);

+      Usage ();

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // Otherwise must be a decimal number

+    //

+  } else {

+    if (sscanf (Argv[0], "%d", &Options->FileSize) != 1) {

+      fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]);

+      Usage ();

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+

+  Options->FileSize *= Multiplier;

+  //

+  // Assume byte value of 0xff

+  //

+  Options->ByteValue = (INT8) (UINT8) 0xFF;

+  return EFI_SUCCESS;

+}

+//

+// Print utility usage info

+//

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  UINT32            Index;

+  static const INT8 *Text[] = {

+    " ",

+    "Usage:  "PROGRAM_NAME " OutFileName FileSize",

+    "  where:",

+    "    OutFileName is the name of the output file to generate",

+    "    FileSize is the size of the file to create",

+    "  Examples:",

+    "    "PROGRAM_NAME " OutFile.bin 32K",

+    "    "PROGRAM_NAME " OutFile.bin 0x1000",

+    " ",

+    NULL

+  };

+

+  for (Index = 0; Text[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Text[Index]);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/CreateMtFile/Makefile b/edk2/Tools/Source/TianoTools/CreateMtFile/Makefile
new file mode 100644
index 0000000..d6574fc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CreateMtFile/Makefile
@@ -0,0 +1,67 @@
+#/*++

+#  

+#  Copyright (c)  1999 - 2001 Intel Corporation. All rights reserved

+#  This software and associated documentation (if any) is furnished

+#  under a license and may only be used or copied in accordance

+#  with the terms of the license. Except as permitted by such

+#  license, no part of this software or documentation may be

+#  reproduced, stored in a retrieval system, or transmitted in any

+#  form or by any means without the express written consent of

+#  Intel Corporation.

+#  

+#  

+#  Module Name:

+#  

+#    Makefile

+#  

+#  Abstract:

+#  

+#    makefile for building the CreateMtFile utility.

+#  

+#  Revision History

+#  

+#--*/

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+#

+# Define the toolchain which is used to set build options and toolchain paths

+#

+TOOLCHAIN = TOOLCHAIN_MSVC

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = CreateMtFile

+TARGET_SRC_DIR      = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\CreateMtFile.obj

+            

+#

+# Build the EXE by compiling the source files, then linking the resultant

+# object files together.

+#

+

+$(TIANO_TOOLS_OUTPUT)\CreateMtFile.obj : $(TARGET_SRC_DIR)\CreateMtFile.c

+  $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\CreateMtFile.c /Fo$@

+

+$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/CreateMtFile/build.xml b/edk2/Tools/Source/TianoTools/CreateMtFile/build.xml
new file mode 100644
index 0000000..56cff1f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CreateMtFile/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK CreateMtFile Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="CreateMtFile"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/CustomizedCompress/CustomizedCompress.c b/edk2/Tools/Source/TianoTools/CustomizedCompress/CustomizedCompress.c
new file mode 100644
index 0000000..ca0ea17
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CustomizedCompress/CustomizedCompress.c
@@ -0,0 +1,147 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  CustomizedCompress.c

+

+Abstract:

+

+  Header file for Customized compression routine

+  

+--*/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+

+EFI_STATUS

+SetCustomizedCompressionType (

+  IN  CHAR8   *Type

+  )

+/*++

+

+Routine Description:

+

+The implementation of Customized SetCompressionType().

+

+Arguments:

+  Type        - The type if compression.

+    

+Returns:

+    

+  EFI_SUCCESS           - The type has been set.

+  EFI_UNSUPPORTED       - This type is unsupported.

+

+    

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+CustomizedGetInfo (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  OUT     UINT32  *DstSize,

+  OUT     UINT32  *ScratchSize

+  )

+/*++

+

+Routine Description:

+

+The implementation of Customized GetInfo().

+

+Arguments:

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  DstSize     - The size of destination buffer.

+  ScratchSize - The size of scratch buffer.

+    

+Returns:

+    

+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.

+  EFI_INVALID_PARAMETER - The source data is corrupted

+  EFI_UNSUPPORTED       - The operation is unsupported.

+

+    

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+CustomizedDecompress (

+  IN      VOID    *Source,

+  IN      UINT32  SrcSize,

+  IN OUT  VOID    *Destination,

+  IN      UINT32  DstSize,

+  IN OUT  VOID    *Scratch,

+  IN      UINT32  ScratchSize

+  )

+/*++

+

+Routine Description:

+

+  The implementation of Customized Decompress().

+

+Arguments:

+

+  This        - The protocol instance pointer

+  Source      - The source buffer containing the compressed data.

+  SrcSize     - The size of source buffer

+  Destination - The destination buffer to store the decompressed data

+  DstSize     - The size of destination buffer.

+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.

+  ScratchSize - The size of scratch buffer.

+

+Returns:

+

+  EFI_SUCCESS           - Decompression is successfull

+  EFI_INVALID_PARAMETER - The source data is corrupted

+  EFI_UNSUPPORTED       - The operation is unsupported.

+

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+CustomizedCompress (

+  IN      UINT8   *SrcBuffer,

+  IN      UINT32  SrcSize,

+  IN      UINT8   *DstBuffer,

+  IN OUT  UINT32  *DstSize

+  )

+/*++

+

+Routine Description:

+

+  The Customized compression routine.

+

+Arguments:

+

+  SrcBuffer   - The buffer storing the source data

+  SrcSize     - The size of source data

+  DstBuffer   - The buffer to store the compressed data

+  DstSize     - On input, the size of DstBuffer; On output,

+                the size of the actual compressed data.

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,

+                DstSize contains the size needed.

+  EFI_SUCCESS           - Compression is successful.

+

+  EFI_UNSUPPORTED       - The operation is unsupported.

+--*/

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/edk2/Tools/Source/TianoTools/CustomizedCompress/build.xml b/edk2/Tools/Source/TianoTools/CustomizedCompress/build.xml
new file mode 100644
index 0000000..388550a
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/CustomizedCompress/build.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="CustomizedCompress.lib" basedir=".">

+<!--

+    EDK Customized Compress Library

+  Copyright (c) 2006, Intel Corporation

+-->

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/CustomizedCompress/tmp"/>

+

+  <target name="CustomizedCompress.lib" depends="ToolsLibrary">

+    <echo message="Building the EDK CustomizedCompress Library"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK CustomizedCompress Library"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<property name="HOST_ARCH" value="IA32" />

+		<ToolChainSetup confPath="${WORKSPACE}/Tools/Conf" />

+    <echo message="Compiler: ${CC}"/>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="ToolsLibrary" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${LIB_DIR}/CustomizedCompress"

+        outtype="static"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/CustomizedCompress" 

+        includes="*.h *.c" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+    </cc>

+    <if>

+      <os family="dos"/>

+      <then>

+        <exec dir="${BUILD_DIR}" executable="lib" failonerror="false">

+          <arg line="/NOLOGO *.lib /OUT:${LIB_DIR}/CustomizedCompress${ext_static}"/>

+        </exec>

+      </then>

+    </if>

+  </target>

+

+  <target name="clean">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall">

+    <echo message="Removing Object Files and the Library: CustomizedCompress${ext_static}"/>  

+    <delete dir="${BUILD_DIR}" failonerror="false">

+      <fileset dir="${LIB_DIR}" includes="CustomizedCompress${ext_static}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/EfiCompress/EfiCompressMain.c b/edk2/Tools/Source/TianoTools/EfiCompress/EfiCompressMain.c
new file mode 100644
index 0000000..5964eb5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/EfiCompress/EfiCompressMain.c
@@ -0,0 +1,164 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  

+  EfiCompressMain.c

+

+Abstract:

+

+  The main function for the compression utility.

+  

+--*/

+

+#include <stdlib.h>

+#include <string.h>

+#include <ctype.h>

+#include <stdarg.h>

+#include <stdio.h>

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include "EfiCompress.h"

+

+int

+main (

+  INT32 argc,

+  CHAR8 *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Compresses the input files

+

+Arguments:

+

+  argc   - number of arguments passed into the command line.

+  argv[] - files to compress and files to output compressed data to.

+

+Returns:

+

+  int: 0 for successful execution of the function.

+

+--*/

+{

+  EFI_STATUS  Status;

+  FILE        *infile;

+  FILE        *outfile;

+  UINT32      SrcSize;

+  UINT32      DstSize;

+  UINT8       *SrcBuffer;

+  UINT8       *DstBuffer;

+  UINT8       Buffer[8];

+

+  //

+  //  Added for makefile debug - KCE

+  //

+  INT32       arg_counter;

+  printf ("\n\n");

+  for (arg_counter = 0; arg_counter < argc; arg_counter++) {

+    printf ("%s ", argv[arg_counter]);

+  }

+

+  printf ("\n\n");

+

+  SrcBuffer             = DstBuffer = NULL;

+

+  infile                = outfile = NULL;

+

+  if (argc != 3) {

+    printf ("Usage: EFICOMPRESS <infile> <outfile>\n");

+    goto Done;

+  }

+

+  if ((outfile = fopen (argv[2], "wb")) == NULL) {

+    printf ("Can't open output file\n");

+    goto Done;

+  }

+

+  if ((infile = fopen (argv[1], "rb")) == NULL) {

+    printf ("Can't open input file\n");

+    goto Done;

+  }

+  //

+  // Get the size of source file

+  //

+  SrcSize = 0;

+  while (fread (Buffer, 1, 1, infile)) {

+    SrcSize++;

+

+  }

+  //

+  // Read in the source data

+  //

+  if ((SrcBuffer = malloc (SrcSize)) == NULL) {

+    printf ("Can't allocate memory\n");

+    goto Done;

+  }

+

+  rewind (infile);

+  if (fread (SrcBuffer, 1, SrcSize, infile) != SrcSize) {

+    printf ("Can't read from source\n");

+    goto Done;

+  }

+  //

+  // Get destination data size and do the compression

+  //

+  DstSize = 0;

+  Status  = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    if ((DstBuffer = malloc (DstSize)) == NULL) {

+      printf ("Can't allocate memory\n");

+      goto Done;

+    }

+

+    Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize);

+  }

+

+  if (EFI_ERROR (Status)) {

+    printf ("Compress Error\n");

+    goto Done;

+  }

+

+  printf ("\nOrig Size = %ld\n", SrcSize);

+  printf ("Comp Size = %ld\n", DstSize);

+

+  if (DstBuffer == NULL) {

+    printf ("No destination to write to.\n");

+    goto Done;

+  }

+  //

+  // Write out the result

+  //

+  if (fwrite (DstBuffer, 1, DstSize, outfile) != DstSize) {

+    printf ("Can't write to destination file\n");

+  }

+

+Done:

+  if (SrcBuffer) {

+    free (SrcBuffer);

+  }

+

+  if (DstBuffer) {

+    free (DstBuffer);

+  }

+

+  if (infile) {

+    fclose (infile);

+  }

+

+  if (outfile) {

+    fclose (outfile);

+  }

+

+  return 0;

+}

diff --git a/edk2/Tools/Source/TianoTools/EfiCompress/build.xml b/edk2/Tools/Source/TianoTools/EfiCompress/build.xml
new file mode 100644
index 0000000..adf40d9
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/EfiCompress/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK EfiCompress Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="EfiCompress"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/EfiCompress/makefile b/edk2/Tools/Source/TianoTools/EfiCompress/makefile
new file mode 100644
index 0000000..b20a219
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/EfiCompress/makefile
@@ -0,0 +1,77 @@
+#/*++

+#   

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Define some macros we use here. Should get rid of them someday and 

+# get rid of the extra level of indirection.

+#

+COMMON_SOURCE      = $(EDK_TOOLS_COMMON)

+

+#

+# BUGBUG: Override standard flags, cannot be built without warnings.

+#

+

+C_FLAGS=/nologo /W4 /GX /Zi /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /c 

+

+#

+# Common information

+#

+

+INC=$(INC)

+

+#

+# Target specific information

+#

+

+TARGET_NAME=EfiCompress

+TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+

+TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\EfiCompressMain.c"

+TARGET_EXE_INCLUDE = "$(COMMON_SOURCE)\EfiCompress.h"

+TARGET_EXE_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib"

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+#

+# Build EXE

+#

+

+$(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj

+

+$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS) $(TARGET_DLL)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* > NUL

diff --git a/edk2/Tools/Source/TianoTools/EfiRom/EfiRom.c b/edk2/Tools/Source/TianoTools/EfiRom/EfiRom.c
new file mode 100644
index 0000000..5fb99ab
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/EfiRom/EfiRom.c
@@ -0,0 +1,1545 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+Module Name:

+

+  EfiRom.c

+  

+Abstract:

+

+  Utility program to create an EFI option ROM image from binary and 

+  EFI PE32 files.

+

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+

+//

+// Includes for EFI 1.1 build

+//

+// #include "Tiano.h"        // required defines for Compress.h

+// #include "EfiImage.h"   // for PE32 structure definitions

+// #include "Compress.h"   // for compression function

+// Includes for Tiano build

+//

+#include <UefiBaseTypes.h>

+#include <EfiImage.h> // for PE32 structure definitions

+#include <EfiCompress.h>

+#include <CommonLib.h>

+#include <MultiPhase.h>

+

+//

+// END include differences

+//

+#include "pci22.h"  // for option ROM header structures

+//

+// Version of this utility

+//

+#define UTILITY_VERSION "v2.5"

+

+//

+// Define some status return values

+//

+#define STATUS_SUCCESS  0

+#define STATUS_WARNING  1

+#define STATUS_ERROR    2

+

+//

+// Define the max length of a filename

+//

+#define MAX_PATH                  200

+

+#define DEFAULT_OUTPUT_EXTENSION  ".rom"

+

+//

+// Max size for an option ROM image

+//

+#define MAX_OPTION_ROM_SIZE (1024 * 1024 * 16)  // 16MB

+//

+// Values for the indicator field in the PCI data structure

+//

+#define INDICATOR_LAST  0x80  // last file in series of files

+//

+// Masks for the FILE_LIST.FileFlags field

+//

+#define FILE_FLAG_BINARY    0x01

+#define FILE_FLAG_EFI       0x02

+#define FILE_FLAG_COMPRESS  0x04

+

+//

+// Use this linked list structure to keep track of all the filenames

+// specified on the command line.

+//

+typedef struct _FILE_LIST {

+  struct _FILE_LIST *Next;

+  INT8              *FileName;

+  UINT32            FileFlags;

+  UINT32            ClassCode;

+  UINT16            CodeRevision;

+} FILE_LIST;

+

+//

+// Use this to track our command-line options

+//

+typedef struct {

+  INT8      OutFileName[MAX_PATH];

+  INT8      NoLast;

+  INT8      Verbose;

+  INT8      DumpOption;

+  UINT8     DevIdValid;

+  UINT8     VendIdValid;

+  UINT16    VendId;

+  UINT16    DevId;

+  FILE_LIST *FileList;

+} OPTIONS;

+

+//

+// Make a global structure to keep track of command-line options

+//

+static OPTIONS  mOptions;

+

+//

+// Use these to convert from machine type value to a named type

+//

+typedef struct {

+  UINT16  Value;

+  char    *Name;

+} STRING_LOOKUP;

+

+static STRING_LOOKUP  mMachineTypes[] = {

+  EFI_IMAGE_MACHINE_IA32,

+  "IA32",

+  EFI_IMAGE_MACHINE_IA64,

+  "IA64",

+  EFI_IMAGE_MACHINE_EBC,

+  "EBC",

+  0,

+  NULL

+};

+

+static STRING_LOOKUP  mSubsystemTypes[] = {

+  EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,

+  "EFI application",

+  EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,

+  "EFI boot service driver",

+  EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,

+  "EFI runtime driver",

+  0,

+  NULL

+};

+//

+//  Function prototypes

+//

+static

+void

+Usage (

+  VOID

+  );

+

+static

+int

+ParseCommandLine (

+  int       Argc,

+  char      *Argv[],

+  OPTIONS   *Options

+  );

+

+static

+int

+CheckPE32File (

+  FILE      *Fptr,

+  UINT16    *MachineType,

+  UINT16    *SubSystem

+  );

+

+static

+int

+ProcessEfiFile (

+  FILE      *OutFptr,

+  FILE_LIST *InFile,

+  UINT16    VendId,

+  UINT16    DevId,

+  UINT32    *Size

+  );

+

+static

+int

+ProcessBinFile (

+  FILE      *OutFptr,

+  FILE_LIST *InFile,

+  UINT32    *Size

+  );

+

+static

+void

+DumpImage (

+  FILE_LIST *InFile

+  );

+

+char                  *

+GetMachineTypeStr (

+  UINT16    MachineType

+  );

+

+static

+char                  *

+GetSubsystemTypeStr (

+  UINT16  SubsystemType

+  );

+

+main (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+  

+  Given an EFI image filename, create a ROM-able image by creating an option 

+  ROM header and PCI data structure, filling them in, and then writing the

+  option ROM header + PCI data structure + EFI image out to the output file.

+

+Arguments:

+

+  Argc            - standard C main() argument count

+

+  Argv            - standard C main() argument list

+

+Returns:

+

+  0             success

+  non-zero      otherwise

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+{

+  INT8      *Ext;

+  FILE      *FptrOut;

+  UINT32    Status;

+  FILE_LIST *FList;

+  UINT32    TotalSize;

+  UINT32    Size;

+

+  Status  = STATUS_SUCCESS;

+  FptrOut = NULL;

+

+  //

+  // Parse the command line arguments

+  //

+  if (ParseCommandLine (Argc, Argv, &mOptions)) {

+    return STATUS_ERROR;

+  }

+  //

+  // If dumping an image, then do that and quit

+  //

+  if (mOptions.DumpOption) {

+    DumpImage (mOptions.FileList);

+    goto BailOut;

+  }

+  //

+  // Determine the output filename. Either what they specified on

+  // the command line, or the first input filename with a different extension.

+  //

+  if (!mOptions.OutFileName[0]) {

+    strcpy (mOptions.OutFileName, mOptions.FileList->FileName);

+    //

+    // Find the last . on the line and replace the filename extension with

+    // the default

+    //

+    for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;

+         (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');

+         Ext--

+        )

+      ;

+    //

+    // If dot here, then insert extension here, otherwise append

+    //

+    if (*Ext != '.') {

+      Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);

+    }

+

+    strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);

+  }

+  //

+  // Make sure we don't have the same filename for input and output files

+  //

+  for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {

+    if (stricmp (mOptions.OutFileName, FList->FileName) == 0) {

+      Status = STATUS_ERROR;

+      fprintf (

+        stdout,

+        "ERROR: Input and output file names must be different - %s = %s\n",

+        FList->FileName,

+        mOptions.OutFileName

+        );

+      goto BailOut;

+    }

+  }

+  //

+  // Now open our output file

+  //

+  if ((FptrOut = fopen (mOptions.OutFileName, "w+b")) == NULL) {

+    fprintf (stdout, "ERROR: Failed to open output file %s\n", mOptions.OutFileName);

+    goto BailOut;

+  }

+  //

+  // Process all our files

+  //

+  TotalSize = 0;

+  for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {

+    Size = 0;

+    if (FList->FileFlags & FILE_FLAG_EFI) {

+      if (mOptions.Verbose) {

+        fprintf (stdout, "Processing EFI file    %s\n", FList->FileName);

+      }

+

+      Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size);

+    } else if (FList->FileFlags & FILE_FLAG_BINARY) {

+      if (mOptions.Verbose) {

+        fprintf (stdout, "Processing binary file %s\n", FList->FileName);

+      }

+

+      Status = ProcessBinFile (FptrOut, FList, &Size);

+    } else {

+      fprintf (stdout, "ERROR: File not specified as EFI or binary: %s\n", FList->FileName);

+      Status = STATUS_ERROR;

+    }

+

+    if (mOptions.Verbose) {

+      fprintf (stdout, "  Output size = 0x%X\n", Size);

+    }

+

+    if (Status != STATUS_SUCCESS) {

+      break;

+    }

+

+    TotalSize += Size;

+  }

+  //

+  // Check total size

+  //

+  if (TotalSize > MAX_OPTION_ROM_SIZE) {

+    fprintf (

+      stdout,

+      "ERROR: Option ROM image size exceeds limit 0x%X bytes\n",

+      MAX_OPTION_ROM_SIZE

+      );

+    Status = STATUS_ERROR;

+  }

+

+BailOut:

+  if (FptrOut != NULL) {

+    fclose (FptrOut);

+  }

+  //

+  // Clean up our file list

+  //

+  while (mOptions.FileList != NULL) {

+    FList = mOptions.FileList->Next;

+    free (mOptions.FileList);

+    mOptions.FileList = FList;

+  }

+

+  return Status;

+}

+

+static

+int

+ProcessBinFile (

+  FILE      *OutFptr,

+  FILE_LIST *InFile,

+  UINT32    *Size

+  )

+/*++

+

+Routine Description:

+  

+  Process a binary input file.

+

+Arguments:

+

+  OutFptr     - file pointer to output binary ROM image file we're creating

+  InFile      - structure contains information on the binary file to process

+  Size        - pointer to where to return the size added to the output file

+

+Returns:

+

+  0 - successful

+

+--*/

+{

+  FILE                      *InFptr;

+  UINT32                    TotalSize;

+  UINT32                    FileSize;

+  UINT8                     *Buffer;

+  UINT32                    Status;

+  PCI_EXPANSION_ROM_HEADER  *RomHdr;

+  PCI_DATA_STRUCTURE        *PciDs;

+  UINT32                    Index;

+  UINT8                     ByteCheckSum;

+

+  Status = STATUS_SUCCESS;

+

+  //

+  // Try to open the input file

+  //

+  if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) {

+    fprintf (stdout, "ERROR: Failed to open input file %s\n", InFile->FileName);

+    return STATUS_ERROR;

+  }

+  //

+  // Seek to the end of the input file and get the file size. Then allocate

+  // a buffer to read it in to.

+  //

+  fseek (InFptr, 0, SEEK_END);

+  FileSize = ftell (InFptr);

+  if (mOptions.Verbose) {

+    fprintf (stdout, "  File size   = 0x%X\n", FileSize);

+  }

+

+  fseek (InFptr, 0, SEEK_SET);

+  Buffer = (INT8 *) malloc (FileSize);

+  if (Buffer == NULL) {

+    fprintf (stdout, "ERROR: Memory allocation failed\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+

+  if (fread (Buffer, FileSize, 1, InFptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to read all bytes from input file\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // Total size must be an even multiple of 512 bytes, and can't exceed

+  // the option ROM image size.

+  //

+  TotalSize = FileSize;

+  if (TotalSize & 0x1FF) {

+    TotalSize = (TotalSize + 0x200) &~0x1ff;

+  }

+

+  if (TotalSize > MAX_OPTION_ROM_SIZE) {

+    fprintf (

+      stdout,

+      "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n",

+      InFile->FileName,

+      MAX_OPTION_ROM_SIZE

+      );

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // Return the size to the caller so they can keep track of the running total.

+  //

+  *Size = TotalSize;

+

+  //

+  // Crude check to make sure it's a legitimate ROM image

+  //

+  RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;

+  if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {

+    fprintf (stdout, "ERROR: ROM image file has invalid ROM signature\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // Make sure the pointer to the PCI data structure is within the size of the image.

+  // Then check it for valid signature.

+  //

+  if ((RomHdr->PcirOffset > FileSize) || (RomHdr->PcirOffset == 0)) {

+    fprintf (stdout, "ERROR: Invalid PCI data structure offset\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+

+  PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);

+  if (PciDs->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {

+    fprintf (stdout, "ERROR: PCI data structure has invalid signature\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // If this is the last image, then set the LAST bit unless requested not

+  // to via the command-line -l argument. Otherwise, make sure you clear it.

+  //

+  if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {

+    PciDs->Indicator = INDICATOR_LAST;

+  } else {

+    PciDs->Indicator = 0;

+  }

+

+  ByteCheckSum = 0;

+  for (Index = 0; Index < FileSize - 1; Index++) {

+    ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]);

+  }

+

+  Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1);

+  fprintf (stdout, "CheckSUm = %02x\n", (UINT32) Buffer[FileSize - 1]);

+

+  //

+  // Now copy the input file contents out to the output file

+  //

+  if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+

+  TotalSize -= FileSize;

+  //

+  // Pad the rest of the image to make it a multiple of 512 bytes

+  //

+  while (TotalSize > 0) {

+    putc (~0, OutFptr);

+    TotalSize--;

+  }

+

+BailOut:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+  //

+  // Print the file name if errors occurred

+  //

+  if (Status != STATUS_SUCCESS) {

+    fprintf (stdout, "Error processing binary file %s\n", InFile->FileName);

+  }

+

+  return Status;

+}

+

+static

+int

+ProcessEfiFile (

+  FILE      *OutFptr,

+  FILE_LIST *InFile,

+  UINT16    VendId,

+  UINT16    DevId,

+  UINT32    *Size

+  )

+/*++

+

+Routine Description:

+  

+  Process a PE32 EFI file.

+

+Arguments:

+

+  OutFptr     - file pointer to output binary ROM image file we're creating

+  InFile      - structure contains information on the PE32 file to process

+  VendId      - vendor ID as required in the option ROM header

+  DevId       - device ID as required in the option ROM header

+  Size        - pointer to where to return the size added to the output file

+

+Returns:

+

+  0 - successful

+

+--*/

+{

+  UINT32                        Status;

+  FILE                          *InFptr;

+  EFI_PCI_EXPANSION_ROM_HEADER  RomHdr;

+  PCI_DATA_STRUCTURE            PciDs;

+  UINT32                        FileSize;

+  UINT32                        CompressedFileSize;

+  UINT8                         *Buffer;

+  UINT8                         *CompressedBuffer;

+  UINT8                         *TempBufferPtr;

+  UINT32                        TotalSize;

+  UINT32                        HeaderSize;

+  UINT16                        MachineType;

+  UINT16                        SubSystem;

+  UINT32                        HeaderPadBytes;

+

+  //

+  // Try to open the input file

+  //

+  if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) {

+    fprintf (stdout, "ERROR: Failed to open input file %s\n", InFile->FileName);

+    return STATUS_ERROR;

+  }

+  //

+  // Initialize our buffer pointers to null.

+  //

+  Buffer            = NULL;

+  CompressedBuffer  = NULL;

+

+  //

+  // Double-check the file to make sure it's what we expect it to be

+  //

+  Status = CheckPE32File (InFptr, &MachineType, &SubSystem);

+  if (Status != STATUS_SUCCESS) {

+    goto BailOut;

+  }

+  //

+  // Seek to the end of the input file and get the file size

+  //

+  fseek (InFptr, 0, SEEK_END);

+  FileSize = ftell (InFptr);

+

+  //

+  // Get the size of the headers we're going to put in front of the image. The

+  // EFI header must be aligned on a 4-byte boundary, so pad accordingly.

+  //

+  if (sizeof (RomHdr) & 0x03) {

+    HeaderPadBytes = 4 - (sizeof (RomHdr) & 0x03);

+  } else {

+    HeaderPadBytes = 0;

+  }

+

+  HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);

+  if (mOptions.Verbose) {

+    fprintf (stdout, "  File size   = 0x%X\n", FileSize);

+  }

+  //

+  // Allocate memory for the entire file (in case we have to compress), then

+  // seek back to the beginning of the file and read it into our buffer.

+  //

+  Buffer = (INT8 *) malloc (FileSize);

+  if (Buffer == NULL) {

+    fprintf (stdout, "ERROR: Memory allocation failed\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+

+  fseek (InFptr, 0, SEEK_SET);

+  if (fread (Buffer, FileSize, 1, InFptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to read all bytes from input file\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // Now determine the size of the final output file. It's either the header size

+  // plus the file's size, or the header size plus the compressed file size.

+  //

+  if (InFile->FileFlags & FILE_FLAG_COMPRESS) {

+    //

+    // Allocate a buffer into which we can compress the image, compress it,

+    // and use that size as the new size.

+    //

+    CompressedBuffer = (INT8 *) malloc (FileSize);

+    if (CompressedBuffer == NULL) {

+      fprintf (stdout, "ERROR: Memory allocation failed\n");

+      Status = STATUS_ERROR;

+      goto BailOut;

+    }

+

+    CompressedFileSize  = FileSize;

+    Status              = Compress (Buffer, FileSize, CompressedBuffer, &CompressedFileSize);

+    if (Status != STATUS_SUCCESS) {

+      fprintf (stdout, "ERROR: Compression failed\n");

+      goto BailOut;

+    }

+    //

+    // Now compute the size, then swap buffer pointers.

+    //

+    if (mOptions.Verbose) {

+      fprintf (stdout, "  Comp size   = 0x%X\n", CompressedFileSize);

+    }

+

+    TotalSize         = CompressedFileSize + HeaderSize;

+    FileSize          = CompressedFileSize;

+    TempBufferPtr     = Buffer;

+    Buffer            = CompressedBuffer;

+    CompressedBuffer  = TempBufferPtr;

+  } else {

+    TotalSize = FileSize + HeaderSize;

+  }

+  //

+  // Total size must be an even multiple of 512 bytes

+  //

+  if (TotalSize & 0x1FF) {

+    TotalSize = (TotalSize + 0x200) &~0x1ff;

+  }

+  //

+  // Check size

+  //

+  if (TotalSize > MAX_OPTION_ROM_SIZE) {

+    fprintf (

+      stdout,

+      "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n",

+      InFile->FileName,

+      MAX_OPTION_ROM_SIZE

+      );

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // Return the size to the caller so they can keep track of the running total.

+  //

+  *Size = TotalSize;

+

+  //

+  // Now fill in the ROM header. These values come from chapter 18 of the

+  // EFI 1.02 specification.

+  //

+  memset (&RomHdr, 0, sizeof (RomHdr));

+  RomHdr.Signature            = PCI_EXPANSION_ROM_HEADER_SIGNATURE;

+  RomHdr.InitializationSize   = (UINT16) (TotalSize / 512);

+  RomHdr.EfiSignature         = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;

+  RomHdr.EfiSubsystem         = SubSystem;

+  RomHdr.EfiMachineType       = MachineType;

+  RomHdr.EfiImageHeaderOffset = (UINT16) HeaderSize;

+  RomHdr.PcirOffset           = (UINT16) (sizeof (RomHdr) + HeaderPadBytes);

+  //

+  // Set image as compressed or not

+  //

+  if (InFile->FileFlags & FILE_FLAG_COMPRESS) {

+    RomHdr.CompressionType = EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED;

+  }

+  //

+  // Fill in the PCI data structure

+  //

+  memset (&PciDs, 0, sizeof (PCI_DATA_STRUCTURE));

+

+  PciDs.Signature = PCI_DATA_STRUCTURE_SIGNATURE;

+  PciDs.VendorId  = VendId;

+  PciDs.DeviceId  = DevId;

+  PciDs.Length    = (UINT16) sizeof (PCI_DATA_STRUCTURE);

+  PciDs.Revision  = 0;

+  //

+  // Class code and code revision from the command line (optional)

+  //

+  PciDs.ClassCode[0]  = (UINT8) InFile->ClassCode;

+  PciDs.ClassCode[1]  = (UINT8) (InFile->ClassCode >> 8);

+  PciDs.ClassCode[2]  = (UINT8) (InFile->ClassCode >> 16);

+  PciDs.ImageLength   = RomHdr.InitializationSize;

+  PciDs.CodeRevision  = InFile->CodeRevision;

+  PciDs.CodeType      = PCI_CODE_TYPE_EFI_IMAGE;

+

+  //

+  // If this is the last image, then set the LAST bit unless requested not

+  // to via the command-line -l argument.

+  //

+  if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {

+    PciDs.Indicator = INDICATOR_LAST;

+  }

+  //

+  // Write the ROM header to the output file

+  //

+  if (fwrite (&RomHdr, sizeof (RomHdr), 1, OutFptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to write ROM header to output file\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+

+  //

+  // Write pad bytes to align the PciDs

+  //

+  while (HeaderPadBytes > 0) {

+    if (putc (0, OutFptr) == EOF) {

+      fprintf (stdout, "ERROR: Failed to write ROM header pad bytes to output file\n");

+      Status = STATUS_ERROR;

+      goto BailOut;

+    }

+

+    HeaderPadBytes--;

+  }

+  //

+  // Write the PCI data structure header to the output file

+  //

+  if (fwrite (&PciDs, sizeof (PciDs), 1, OutFptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to write PCI ROM header to output file\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+  //

+  // Keep track of how many bytes left to write

+  //

+  TotalSize -= HeaderSize;

+

+  //

+  // Now dump the input file's contents to the output file

+  //

+  if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n");

+    Status = STATUS_ERROR;

+    goto BailOut;

+  }

+

+  TotalSize -= FileSize;

+  //

+  // Pad the rest of the image to make it a multiple of 512 bytes

+  //

+  while (TotalSize > 0) {

+    if (putc (~0, OutFptr) == EOF) {

+      fprintf (stdout, "ERROR: Failed to write trailing pad bytes output file\n");

+      Status = STATUS_ERROR;

+      goto BailOut;

+    }

+

+    TotalSize--;

+  }

+

+BailOut:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+

+  //

+  // Free up our buffers

+  //

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+

+  if (CompressedBuffer != NULL) {

+    free (CompressedBuffer);

+  }

+  //

+  // Print the file name if errors occurred

+  //

+  if (Status != STATUS_SUCCESS) {

+    fprintf (stdout, "Error processing EFI file %s\n", InFile->FileName);

+  }

+

+  return Status;

+}

+

+static

+int

+CheckPE32File (

+  FILE      *Fptr,

+  UINT16    *MachineType,

+  UINT16    *SubSystem

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  Fptr        - GC_TODO: add argument description

+  MachineType - GC_TODO: add argument description

+  SubSystem   - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  /*++

+

+Routine Description:

+  

+  Given a file pointer to a supposed PE32 image file, verify that it is indeed a

+  PE32 image file, and then return the machine type in the supplied pointer.

+

+Arguments:

+

+  Fptr          File pointer to the already-opened PE32 file

+  MachineType   Location to stuff the machine type of the PE32 file. This is needed

+                because the image may be Itanium-based, IA32, or EBC.

+

+Returns:

+

+  0             success

+  non-zero      otherwise

+

+--*/

+  EFI_IMAGE_DOS_HEADER      DosHeader;

+  EFI_IMAGE_FILE_HEADER     FileHdr;

+  EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;

+  UINT32                    PESig;

+

+  //

+  // Position to the start of the file

+  //

+  fseek (Fptr, 0, SEEK_SET);

+

+  //

+  // Read the DOS header

+  //

+  if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to read the DOS stub from the input file\n");

+    return STATUS_ERROR;

+  }

+  //

+  // Check the magic number (0x5A4D)

+  //

+  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    fprintf (stdout, "ERROR: Input file does not appear to be a PE32 image (magic number)\n");

+    return STATUS_ERROR;

+  }

+  //

+  // Position into the file and check the PE signature

+  //

+  fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);

+  if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to read PE signature bytes from input file\n");

+    return STATUS_ERROR;

+  }

+  //

+  // Check the PE signature in the header "PE\0\0"

+  //

+  if (PESig != EFI_IMAGE_NT_SIGNATURE) {

+    fprintf (stdout, "ERROR: Input file does not appear to be a PE32 image (signature)\n");

+    return STATUS_ERROR;

+  }

+  //

+  // Read the file header and stuff their MachineType

+  //

+  if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to read PE file header from input file\n");

+    return STATUS_ERROR;

+  }

+

+  memcpy ((char *) MachineType, &FileHdr.Machine, 2);

+

+  //

+  // Read the optional header so we can get the subsystem

+  //

+  if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {

+    fprintf (stdout, "ERROR: Failed to read COFF optional header from input file\n");

+    return STATUS_ERROR;

+  }

+

+  *SubSystem = OptionalHdr.Subsystem;

+  if (mOptions.Verbose) {

+    fprintf (stdout, "  Got subsystem = 0x%X from image\n", (int) *SubSystem);

+  }

+  //

+  // Good to go

+  //

+  return STATUS_SUCCESS;

+}

+

+static

+int

+ParseCommandLine (

+  int         Argc,

+  char        *Argv[],

+  OPTIONS     *Options

+  )

+/*++

+

+Routine Description:

+  

+  Given the Argc/Argv program arguments, and a pointer to an options structure,

+  parse the command-line options and check their validity.

+

+

+Arguments:

+

+  Argc            - standard C main() argument count

+  Argv[]          - standard C main() argument list

+  Options         - pointer to a structure to store the options in

+

+Returns:

+

+  STATUS_SUCCESS    success

+  non-zero          otherwise

+

+--*/

+//

+{

+  FILE_LIST *FileList;

+

+  FILE_LIST *PrevFileList;

+  UINT32    FileFlags;

+  UINT32    ClassCode;

+  UINT32    CodeRevision;

+

+  FileFlags = 0;

+

+  //

+  // Clear out the options

+  //

+  memset ((char *) Options, 0, sizeof (OPTIONS));

+

+  //

+  // To avoid compile warnings

+  //

+  FileList                = PrevFileList = NULL;

+

+  ClassCode               = 0;

+  CodeRevision            = 0;

+  //

+  // Skip over the program name

+  //

+  Argc--;

+  Argv++;

+

+  //

+  // If no arguments, assume they want usage info

+  //

+  if (Argc == 0) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Process until no more arguments

+  //

+  while (Argc > 0) {

+    if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) {

+      //

+      // To simplify string comparisons, replace slashes with dashes

+      //

+      Argv[0][0] = '-';

+

+      //

+      // Vendor ID specified with -v

+      //

+      if (stricmp (Argv[0], "-v") == 0) {

+        //

+        // Make sure there's another parameter

+        //

+        if (Argc > 1) {

+          Options->VendId       = (UINT16) strtol (Argv[1], NULL, 16);

+          Options->VendIdValid  = 1;

+        } else {

+          fprintf (

+            stdout,

+            "ERROR: Missing Vendor ID with %s\n\n",

+            Argv[0]

+            );

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        Argv++;

+        Argc--;

+      } else if (stricmp (Argv[0], "-d") == 0) {

+        //

+        // Device ID specified with -d

+        // Make sure there's another parameter

+        //

+        if (Argc > 1) {

+          Options->DevId      = (UINT16) strtol (Argv[1], NULL, 16);

+          Options->DevIdValid = 1;

+        } else {

+          fprintf (

+            stdout,

+            "ERROR: Missing Device ID with %s\n\n",

+            Argv[0]

+            );

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        Argv++;

+        Argc--;

+      } else if (stricmp (Argv[0], "-o") == 0) {

+        //

+        // Output filename specified with -o

+        // Make sure there's another parameter

+        //

+        if (Argc > 1) {

+          strcpy (Options->OutFileName, Argv[1]);

+        } else {

+          fprintf (

+            stdout,

+            "ERROR: Missing output file name with %s\n\n",

+            Argv[0]

+            );

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        Argv++;

+        Argc--;

+      } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {

+        //

+        // Help option

+        //

+        Usage ();

+        return STATUS_ERROR;

+      } else if (stricmp (Argv[0], "-b") == 0) {

+        //

+        // Specify binary files with -b

+        //

+        FileFlags = (FileFlags &~FILE_FLAG_EFI) | FILE_FLAG_BINARY;

+      } else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) {

+        //

+        // Specify EFI files with -e. Specify EFI-compressed with -ec.

+        //

+        FileFlags = (FileFlags &~FILE_FLAG_BINARY) | FILE_FLAG_EFI;

+        if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) {

+          FileFlags |= FILE_FLAG_COMPRESS;

+        }

+        //

+        // Specify not to set the LAST bit in the last file with -l

+        //

+      } else if (stricmp (Argv[0], "-l") == 0) {

+        Options->NoLast = 1;

+      } else if (stricmp (Argv[0], "-p") == 0) {

+        //

+        // -v for verbose would have been nicer, but it's already used. Let's use

+        // -p for prolix (wordy) output

+        //

+        Options->Verbose = 1;

+      } else if (stricmp (Argv[0], "-dump") == 0) {

+        //

+        // -dump for dumping a ROM image. In this case, say that the device id

+        // and vendor id are valid so we don't have to specify bogus ones on the

+        // command line.

+        //

+        Options->DumpOption   = 1;

+

+        Options->VendIdValid  = 1;

+        Options->DevIdValid   = 1;

+        FileFlags             = FILE_FLAG_BINARY;

+      } else if (stricmp (Argv[0], "-cc") == 0) {

+        //

+        // Class code value for the next file in the list.

+        // Make sure there's another parameter

+        //

+        if (Argc > 1) {

+          //

+          // No error checking on the return value. Could check for LONG_MAX,

+          // LONG_MIN, or 0 class code value if desired. Check range (3 bytes)

+          // at least.

+          //

+          ClassCode = (UINT32) strtol (Argv[1], NULL, 16);

+          if (ClassCode & 0xFF000000) {

+            fprintf (stdout, "ERROR: Class code %s out of range\n", Argv[1]);

+            return STATUS_ERROR;

+          }

+        } else {

+          fprintf (

+            stdout,

+            "ERROR: Missing class code value with %s\n\n",

+            Argv[0]

+            );

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        Argv++;

+        Argc--;

+      } else if (stricmp (Argv[0], "-rev") == 0) {

+        //

+        // Code revision in the PCI data structure. The value is for the next

+        // file in the list.

+        // Make sure there's another parameter

+        //

+        if (Argc > 1) {

+          //

+          // No error checking on the return value. Could check for LONG_MAX,

+          // LONG_MIN, or 0 value if desired. Check range (2 bytes)

+          // at least.

+          //

+          CodeRevision = (UINT32) strtol (Argv[1], NULL, 16);

+          if (CodeRevision & 0xFFFF0000) {

+            fprintf (stdout, "ERROR: Code revision %s out of range\n", Argv[1]);

+            return STATUS_ERROR;

+          }

+        } else {

+          fprintf (

+            stdout,

+            "ERROR: Missing code revision value with %s\n\n",

+            Argv[0]

+            );

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        Argv++;

+        Argc--;

+      } else {

+        fprintf (stdout, "ERROR: Invalid option specified: %s\n\n", Argv[0]);

+        Usage ();

+        return STATUS_ERROR;

+      }

+    } else {

+      //

+      // Not a slash-option argument. Must be a file name. Make sure they've specified

+      // -e or -b already.

+      //

+      if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) {

+        fprintf (stdout, "ERROR: Missing -e or -b with input file %s\n", Argv[0]);

+        return STATUS_ERROR;

+      }

+      //

+      // Create a new file structure

+      //

+      FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST));

+      if (FileList == NULL) {

+        fprintf (stdout, "ERROR: Memory allocation failure\n");

+        return STATUS_ERROR;

+      }

+

+      memset ((char *) FileList, 0, sizeof (FILE_LIST));

+      FileList->FileName  = Argv[0];

+      FileList->FileFlags = FileFlags;

+      if (Options->FileList == NULL) {

+        Options->FileList = FileList;

+      } else {

+        if (PrevFileList == NULL) {

+          PrevFileList = FileList;

+        } else {          

+          PrevFileList->Next = FileList;

+        }

+      }

+

+      PrevFileList = FileList;

+      //

+      // Set the class code and code revision for this file, then reset the values.

+      //

+      FileList->ClassCode     = ClassCode;

+      FileList->CodeRevision  = (UINT16) CodeRevision;

+      ClassCode               = 0;

+      CodeRevision            = 0;

+    }

+    //

+    // Next argument

+    //

+    Argv++;

+    Argc--;

+  }

+  //

+  // Make sure they specified a device ID and vendor ID

+  //

+  if (!Options->VendIdValid) {

+    fprintf (stdout, "ERROR: Missing Vendor ID on command line\n\n");

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  if (!Options->DevIdValid) {

+    fprintf (stdout, "ERROR: Missing Device ID on command line\n\n");

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Must have specified some files

+  //

+  if (Options->FileList == NULL) {

+    fprintf (stdout, "ERROR: Missing input file name\n");

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  return 0;

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Print usage information for this utility.

+

+Arguments:

+

+  None.

+

+Returns:

+

+  Nothing.

+

+--*/

+{

+  int               Index;

+  static const char *Msg[] = {

+    "EfiRom "UTILITY_VERSION " - Intel EFI Make Option ROM utility",

+    "  Copyright (C), 1999-2002 Intel Coproration\n",

+    "  Create an option ROM image from a list of input files",

+    "  Usage: efirom {-p} [-v VendorId] [-d DeviceId] {-o OutFileName} ",

+    "                [-e|-b] [FileName(s)]",

+    "    where:",

+    "      VendorId       - required hex PCI Vendor ID for the device",

+    "      DeviceId       - required hex PCI Device ID for the device",

+    "      OutFileName    - optional output file name. Default is the first input",

+    "                       file name with a "DEFAULT_OUTPUT_EXTENSION " file extension",

+    "      FileNames      - input PE32 or binary file name(s)",

+    "      BinFileName    - input binary file name(s)",

+    "      -p             - for verbose output",

+    "      -l             - to not automatically set the LAST bit on the last file",

+    "      -b             - following FileNames are binary files",

+    "      -e             - following FileNames are EFI PE32 image files",

+    "      -ec            - following FileNames are EFI PE32 image files, and should",

+    "                       be compressed by this utility",

+    "      -cc ClassCode  - to use hex ClassCode in the PCI data structure header for",

+    "                       the following FileName",

+    "      -rev Revision  - to use hex Revision in the PCI data structure header for",

+    "                       the following FileName",

+    "      -dump          - to dump the headers of an existing option ROM image",

+    "",

+    "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ",

+    "",

+    NULL

+  };

+

+  for (Index = 0; Msg[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Msg[Index]);

+  }

+}

+

+static

+void

+DumpImage (

+  FILE_LIST *InFile

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  InFile  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  PCI_EXPANSION_ROM_HEADER      PciRomHdr;

+  FILE                          *InFptr;

+  UINT32                        ImageStart;

+  UINT32                        ImageCount;

+  EFI_PCI_EXPANSION_ROM_HEADER  EfiRomHdr;

+  PCI_DATA_STRUCTURE            PciDs;

+

+  //

+  // Open the input file

+  //

+  if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) {

+    fprintf (

+      stdout,

+      "ERROR: Could not open input file %s\n",

+      InFile->FileName

+      );

+    return ;

+  }

+  //

+  // Go through the image and dump the header stuff for each

+  //

+  ImageCount = 0;

+  for (;;) {

+    //

+    // Save our postition in the file, since offsets in the headers

+    // are relative to the particular image.

+    //

+    ImageStart = ftell (InFptr);

+    ImageCount++;

+

+    //

+    // Read the option ROM header. Have to assume a raw binary image for now.

+    //

+    if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) {

+      fprintf (stdout, "ERROR: Failed to read PCI ROM header from file\n");

+      goto BailOut;

+    }

+

+    //

+    // Dump the contents of the header

+    //

+    fprintf (stdout, "Image %d -- Offset 0x%X\n", ImageCount, ImageStart);

+    fprintf (stdout, "  ROM header contents\n");

+    fprintf (stdout, "    Signature              0x%04X\n", (UINT32) PciRomHdr.Signature);

+    fprintf (stdout, "    PCIR offset            0x%04X\n", (UINT32) PciRomHdr.PcirOffset);

+    //

+    // Find PCI data structure

+    //

+    if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) {

+      fprintf (stdout, "ERROR: Failed to seek to PCI data structure\n");

+      goto BailOut;

+    }

+    //

+    // Read and dump the PCI data structure

+    //

+    if (fread (&PciDs, sizeof (PciDs), 1, InFptr) != 1) {

+      fprintf (stdout, "ERROR: Failed to read PCI data structure from file\n");

+      goto BailOut;

+    }

+

+    fprintf (stdout, "  PCI Data Structure\n");

+    fprintf (

+      stdout,

+      "    Signature              %c%c%c%c\n",

+      (char) PciDs.Signature,

+      (char) (PciDs.Signature >> 8),

+      (char) (PciDs.Signature >> 16),

+      (char) (PciDs.Signature >> 24)

+      );

+    fprintf (stdout, "    Vendor ID              0x%04X\n", PciDs.VendorId);

+    fprintf (stdout, "    Device ID              0x%04X\n", PciDs.DeviceId);

+    fprintf (

+      stdout,

+      "    Class Code             0x%06X\n",

+      (UINT32) (PciDs.ClassCode[0] | (PciDs.ClassCode[1] << 8) | (PciDs.ClassCode[2] << 16))

+      );

+    fprintf (stdout, "    Image size             0x%X\n", PciDs.ImageLength * 512);

+    fprintf (stdout, "    Code revision:         0x%04X\n", PciDs.CodeRevision);

+    fprintf (stdout, "    Indicator              0x%02X", (UINT32) PciDs.Indicator);

+    //

+    // Print the indicator, used to flag the last image

+    //

+    if (PciDs.Indicator == INDICATOR_LAST) {

+      fprintf (stdout, "   (last image)\n");

+    } else {

+      fprintf (stdout, "\n");

+    }

+    //

+    // Print the code type. If EFI code, then we can provide more info.

+    //

+    fprintf (stdout, "    Code type              0x%02X", (UINT32) PciDs.CodeType);

+    if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {

+      fprintf (stdout, "   (EFI image)\n");

+      //

+      // Re-read the header as an EFI ROM header, then dump more info

+      //

+      fprintf (stdout, "  EFI ROM header contents\n");

+      if (fseek (InFptr, ImageStart, SEEK_SET)) {

+        fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n");

+        goto BailOut;

+      }

+

+      if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) {

+        fprintf (stdout, "ERROR: Failed to read EFI PCI ROM header from file\n");

+        goto BailOut;

+      }

+      //

+      // Now dump more info

+      //

+      fprintf (stdout, "    EFI Signature          0x%04X\n", EfiRomHdr.EfiSignature);

+      fprintf (

+        stdout,

+        "    Compression Type       0x%04X ",

+        (UINT32) EfiRomHdr.CompressionType

+        );

+      if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {

+        fprintf (stdout, "(compressed)\n");

+      } else {

+        fprintf (stdout, "(not compressed)\n");

+      }

+

+      fprintf (

+        stdout,

+        "    Machine type           0x%04X (%s)\n",

+        EfiRomHdr.EfiMachineType,

+        GetMachineTypeStr (EfiRomHdr.EfiMachineType)

+        );

+      fprintf (

+        stdout,

+        "    Subsystem              0x%04X (%s)\n",

+        EfiRomHdr.EfiSubsystem,

+        GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem)

+        );

+      fprintf (

+        stdout,

+        "    EFI image offset       0x%04X (@0x%X)\n",

+        (UINT32) EfiRomHdr.EfiImageHeaderOffset,

+        (UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart)

+        );

+

+    } else {

+      //

+      // Not an EFI image

+      //

+      fprintf (stdout, "\n");

+    }

+    //

+    // If code type is EFI image, then dump it as well?

+    //

+    // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {

+    // }

+    //

+    // If last image, then we're done

+    //

+    if (PciDs.Indicator == INDICATOR_LAST) {

+      goto BailOut;

+    }

+    //

+    // Seek to the start of the next image

+    //

+    if (fseek (InFptr, ImageStart + (PciDs.ImageLength * 512), SEEK_SET)) {

+      fprintf (stdout, "ERROR: Failed to seek to next image\n");

+      goto BailOut;

+    }

+  }

+

+BailOut:

+  fclose (InFptr);

+}

+

+char *

+GetMachineTypeStr (

+  UINT16    MachineType

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  MachineType - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  int Index;

+

+  for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {

+    if (mMachineTypes[Index].Value == MachineType) {

+      return mMachineTypes[Index].Name;

+    }

+  }

+

+  return "unknown";

+}

+

+static

+char *

+GetSubsystemTypeStr (

+  UINT16  SubsystemType

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  SubsystemType - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  int Index;

+

+  for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {

+    if (mSubsystemTypes[Index].Value == SubsystemType) {

+      return mSubsystemTypes[Index].Name;

+    }

+  }

+

+  return "unknown";

+}

diff --git a/edk2/Tools/Source/TianoTools/EfiRom/Makefile b/edk2/Tools/Source/TianoTools/EfiRom/Makefile
new file mode 100644
index 0000000..5ba3607
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/EfiRom/Makefile
@@ -0,0 +1,70 @@
+#/*++

+#  

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#  

+#  Module Name:

+#  

+#    makefile

+#    

+#  Abstract:

+#  

+#    makefile for building the EfiRom utility.

+#  

+#  Revision History

+#  

+#--*/

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+#

+# Define the toolchain which is used to set build options and toolchain paths

+#

+TOOLCHAIN = TOOLCHAIN_MSVC

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = EfiRom

+TARGET_SRC_DIR      = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\EfiRom.exe

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\EfiRom.obj \

+            $(TIANO_TOOLS_OUTPUT)\EfiCompress.obj

+            

+#

+# Build the EXE by compiling the source files, then linking the resultant

+# object files together.

+#

+

+$(TIANO_TOOLS_OUTPUT)\EfiRom.obj : $(TARGET_SRC_DIR)\EfiRom.c

+  $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\EfiRom.c /Fo$@

+

+$(TIANO_TOOLS_OUTPUT)\EfiCompress.obj : $(EDK_TOOLS_SOURCE)\Common\EfiCompress.c

+  $(CC) $(C_FLAGS) $(EDK_TOOLS_SOURCE)\Common\EfiCompress.c /Fo$@

+  

+$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/EfiRom/build.xml b/edk2/Tools/Source/TianoTools/EfiRom/build.xml
new file mode 100644
index 0000000..619e9fc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/EfiRom/build.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK EfiRom Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="EfiRom"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/IndustryStandard"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/FlashDefFile.c b/edk2/Tools/Source/TianoTools/FlashMap/FlashDefFile.c
new file mode 100644
index 0000000..a4de901
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/FlashDefFile.c
@@ -0,0 +1,2790 @@
+/*++

+

+Copyright (c)  2004-2005 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  FlashDefFile.c

+

+Abstract:

+

+  Utility for flash management in the Intel Platform Innovation Framework

+  for EFI build environment.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <UefiBaseTypes.h>

+#include <Base.h>

+

+#include "EfiUtilityMsgs.h"

+#include "FlashDefFile.h"

+#include "SimpleFileParsing.h"

+#include "Symbols.h"

+// #include "EfiFirmwareVolumeHeader.h"

+#include "MultiPhase.h"

+#include "FirmwareVolumeHeader.h"

+

+//

+// #include "TrackMallocFree.h"

+//

+#define WCHAR_T           char

+#define MAX_STRING_LEN    256

+#define MAX_NAME_LEN      128

+#define BUFFER_SIZE       1024

+#define MAX_ATTR_LEN      128

+#define MAX_AREATYPE_LEN  128

+#define COLUMN2_START     60

+#define COLUMN3_START     70

+//

+// Information for each subregions defined in the fdf file will be saved in these

+//

+typedef struct _FLASH_SUBREGION_DESCRIPTION {

+  struct _FLASH_SUBREGION_DESCRIPTION *Next;

+  int                                 CreateHob;                  // to add to the auto-created HOB array

+  WCHAR_T                             Name[MAX_NAME_LEN];         // each subregion within a region must have a unique name

+  unsigned int                        Size;                       // size, in bytes, of this subregion

+  unsigned int                        SizeLeft;                   // used when creating the image

+  WCHAR_T                             Attributes[MAX_ATTR_LEN];   // subregion attributes used in the output HOB

+  WCHAR_T                             AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB

+  EFI_GUID                            NameGuid;                   // used in the output HOB

+  WCHAR_T                             NameGuidString[MAX_NAME_LEN];

+  EFI_GUID                            AreaTypeGuid;               // used in the output HOB

+  WCHAR_T                             AreaTypeGuidString[MAX_NAME_LEN];

+  EFI_GUID                            FileSystemGuid;             // used in the output HOB

+  WCHAR_T                             FileSystemGuidString[MAX_NAME_LEN];

+} FLASH_SUBREGION_DESCRIPTION;

+

+//

+// Information for each block in a flash device will be saved in one of these.

+// We'll also use it for region definitions.

+//

+typedef struct _FLASH_BLOCK_DESCRIPTION {

+  struct _FLASH_BLOCK_DESCRIPTION *Next;                      // next block in the linked list

+  WCHAR_T                         Name[MAX_NAME_LEN];         // each block must have a unique name

+  unsigned int                    Size;                       // size, in bytes, of this block

+  unsigned int                    SizeLeft;                   // for use when creating image

+  unsigned int                    Flags;                      // user-defined flags for the block

+  unsigned int                    Alignment;                  // power of 2 alignment

+  WCHAR_T                         Attributes[MAX_ATTR_LEN];   // only used for Region definitions

+  WCHAR_T                         AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions

+  FLASH_SUBREGION_DESCRIPTION     *Subregions;

+  FLASH_SUBREGION_DESCRIPTION     *LastSubregion;

+} FLASH_BLOCK_DESCRIPTION;

+

+//

+// Information for each flash device will be saved in one of these

+//

+typedef struct _FLASH_DEVICE_DESCRIPTION {

+  struct _FLASH_DEVICE_DESCRIPTION  *Next;              // next flash device in our linked list

+  int                               ErasePolarity;      // erase polarity of the flash device

+  unsigned int                      BaseAddress;        // base address of the flash device

+  unsigned int                      Size;               // total size, in bytes, of the flash device

+  WCHAR_T                           Name[MAX_NAME_LEN]; // name of the flash device

+  FLASH_BLOCK_DESCRIPTION           *PBlocks;           // linked list of physical block descriptors

+  FLASH_BLOCK_DESCRIPTION           *LastPBlock;        // last block in the linked list

+  FLASH_BLOCK_DESCRIPTION           *Regions;           // linked list of flash region descriptors

+  FLASH_BLOCK_DESCRIPTION           *LastRegion;        // last region in the linked list

+} FLASH_DEVICE_DESCRIPTION;

+

+//

+// For image definitions, they can specify a file name or raw data bytes. Keep a linked list.

+//

+typedef struct _IMAGE_DEFINITION_ENTRY {

+  struct _IMAGE_DEFINITION_ENTRY  *Next;

+  WCHAR_T                         RegionName[MAX_NAME_LEN];

+  WCHAR_T                         SubregionName[MAX_NAME_LEN];

+  WCHAR_T                         Name[MAX_NAME_LEN]; // file or data name

+  int                             IsRawData;          // non-zero if raw data bytes

+  unsigned int                    RawDataSize;

+  char                            *RawData;

+  int                             Optional;           // optional file (don't include if it doesn't exist)

+} IMAGE_DEFINITION_ENTRY;

+

+//

+// When we parse an image definition, save all the data for each in one of these

+//

+typedef struct _IMAGE_DEFINITION {

+  struct _IMAGE_DEFINITION  *Next;

+  WCHAR_T                   Name[MAX_NAME_LEN];

+  IMAGE_DEFINITION_ENTRY    *Entries;

+  IMAGE_DEFINITION_ENTRY    *LastEntry;

+} IMAGE_DEFINITION;

+

+typedef struct {

+  char  *BufferStart;

+  char  *BufferEnd;

+  char  *BufferPos;

+} BUFFER_DATA;

+

+static const char               *CIncludeHeader = "/*++\n\n"

+"  DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n""#ifndef _FLASH_MAP_H_\n"

+"#define _FLASH_MAP_H_\n\n";

+//

+//  "#include \"EfiFlashMap.h\"\n\n";

+//

+static const char               *CIncludeFooter = "#endif // #ifndef _FLASH_MAP_H_\n\n";

+

+static const char               *CFlashMapDataFileHeader = "/*++\n\n"

+"  DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n";

+

+static FLASH_DEVICE_DESCRIPTION *mFlashDevices      = NULL;

+static IMAGE_DEFINITION         *mImageDefinitions  = NULL;

+

+//

+// Local function prototypes

+//

+static

+BUFFER_DATA                     *

+CreateBufferData (

+  VOID

+  );

+

+static

+BOOLEAN

+AddBufferDataByte (

+  BUFFER_DATA *Buffer,

+  char        Data

+  );

+

+static

+void

+FreeBufferData (

+  BUFFER_DATA *Buffer,

+  BOOLEAN     FreeData

+  );

+

+static

+char                            *

+GetBufferData (

+  BUFFER_DATA *Buffer,

+  int         *BufferSize

+  );

+

+static

+FLASH_SUBREGION_DESCRIPTION     *

+ParseSubregionDefinition (

+  unsigned int  SizeLeft

+  );

+

+void

+FDFConstructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Initialization routine for the services that operate on a flash

+  definition file.

+

+Arguments:

+  None.

+

+Returns:

+  NA

+

+--*/

+{

+  mFlashDevices     = NULL;

+  mImageDefinitions = NULL;

+}

+

+void

+FDFDestructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Finalization/cleanup routine for the services that operate on a flash

+  definition file.

+

+Arguments:

+  None.

+

+Returns:

+  NA

+

+--*/

+{

+  FLASH_BLOCK_DESCRIPTION     *FBNext;

+  FLASH_DEVICE_DESCRIPTION    *FDNext;

+  IMAGE_DEFINITION            *IDNext;

+  IMAGE_DEFINITION_ENTRY      *IDENext;

+  FLASH_SUBREGION_DESCRIPTION *SubNext;

+  //

+  // Go through all our flash devices and free the memory

+  //

+  while (mFlashDevices != NULL) {

+    //

+    // Free the physical block definitions

+    //

+    while (mFlashDevices->PBlocks != NULL) {

+      FBNext = mFlashDevices->PBlocks->Next;

+      _free (mFlashDevices->PBlocks);

+      mFlashDevices->PBlocks = FBNext;

+    }

+    //

+    // Free the region definitions

+    //

+    while (mFlashDevices->Regions != NULL) {

+      FBNext = mFlashDevices->Regions->Next;

+      //

+      // First free the subregion definitions

+      //

+      while (mFlashDevices->Regions->Subregions != NULL) {

+        SubNext = mFlashDevices->Regions->Subregions->Next;

+        _free (mFlashDevices->Regions->Subregions);

+        mFlashDevices->Regions->Subregions = SubNext;

+      }

+

+      _free (mFlashDevices->Regions);

+      mFlashDevices->Regions = FBNext;

+    }

+

+    FDNext = mFlashDevices->Next;

+    _free (mFlashDevices);

+    mFlashDevices = FDNext;

+  }

+  //

+  // Free up the image definitions, and the data

+  //

+  while (mImageDefinitions != NULL) {

+    //

+    // Free the entries

+    //

+    while (mImageDefinitions->Entries != NULL) {

+      IDENext = mImageDefinitions->Entries->Next;

+      if (mImageDefinitions->Entries->RawData != NULL) {

+        _free (mImageDefinitions->Entries->RawData);

+      }

+

+      _free (mImageDefinitions->Entries);

+      mImageDefinitions->Entries = IDENext;

+    }

+

+    IDNext = mImageDefinitions->Next;

+    _free (mImageDefinitions);

+    mImageDefinitions = IDNext;

+  }

+}

+

+STATUS

+FDFParseFile (

+  char    *FileName

+  )

+/*++

+

+Routine Description:

+  Parse the specified flash definition file, saving the definitions in

+  file-static variables for use by other functions.

+  

+Arguments:

+  FileName    - name of the input flash definition text file.

+

+Returns:

+  STATUS_SUCCESS    - file parsed with no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered while parsing

+  STATUS_ERROR      - errors were encountered while parsing

+  

+--*/

+{

+  FILE                        *Fptr;

+  STATUS                      Status;

+  unsigned int                Num;

+  FLASH_DEVICE_DESCRIPTION    *FDDesc;

+  FLASH_BLOCK_DESCRIPTION     *FBlockDesc;

+  FLASH_BLOCK_DESCRIPTION     *TempBlockDesc;

+  FLASH_SUBREGION_DESCRIPTION *Subregion;

+  FLASH_SUBREGION_DESCRIPTION *TempSubregion;

+  unsigned int                BlockSizeLeft;

+  unsigned int                RegionSizeLeft;

+  unsigned int                SubregionSizeLeft;

+  int                         ErrorCount;

+  int                         WarningCount;

+  IMAGE_DEFINITION            *ImageDef;

+  IMAGE_DEFINITION_ENTRY      *ImageDefEntry;

+  IMAGE_DEFINITION_ENTRY      *TempImageDefEntry;

+  BUFFER_DATA                 *BufferData;

+  char                        Str[100];

+  BOOLEAN                     PreviousComma;

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open input flash definition file for reading");

+    return STATUS_ERROR;

+  }

+

+  fclose (Fptr);

+  Status        = STATUS_SUCCESS;

+  ErrorCount    = 0;

+  WarningCount  = 0;

+  //

+  // Initialize the simple-file-parsing routines

+  //

+  SFPInit ();

+  //

+  // Open the file

+  //

+  if ((Status = SFPOpenFile (FileName)) != STATUS_SUCCESS) {

+    return Status;

+  }

+  //

+  // Parse the file. Should start with a series of these:

+  // FlashDevice {

+  //   Name = "FLASH_1234", Size = 0x2004, BaseAddress = 0xFFF0000, ErasePolarity = 1,

+  //   Block { Name = "BLOCK1",  Size = 0x1000, Flags = 0x0001 }

+  //   Block { Name = "BLOCK2",  Size = 0x1004, Flags = 0x0002 }

+  //   Region  { Name = "REGION_NAME", Size = 0x2004, Align= 4 }

+  // }

+  //

+  while (SFPIsKeyword ("FlashDevice")) {

+    //

+    // Allocate memory for new flash device description block

+    //

+    FDDesc = (FLASH_DEVICE_DESCRIPTION *) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION));

+    if (FDDesc == NULL) {

+      Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    memset (FDDesc, 0, sizeof (FLASH_DEVICE_DESCRIPTION));

+    //

+    // Open brace -- warning if not there

+    //

+    if (!SFPIsToken ("{")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);

+      WarningCount++;

+    }

+    //

+    // Parse:  Name = "DeviceName",

+    //

+    if (!SFPIsKeyword ("Name")) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPGetQuotedString (FDDesc->Name, sizeof (FDDesc->Name))) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken (",")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL);

+      WarningCount++;

+    }

+    //

+    // Parse: Size = 0x20000,

+    //

+    if (!SFPIsKeyword ("Size")) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPGetNumber (&FDDesc->Size)) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+    //

+    // Check for 0 size

+    //

+    if (FDDesc->Size == 0) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc->Name, "Size field cannot be 0", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    SFPIsToken (",");

+    //

+    // Parse: BaseAddress = 0xFFF0000,

+    //

+    if (!SFPIsKeyword ("BaseAddress")) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPGetNumber (&FDDesc->BaseAddress)) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken (",")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL);

+      WarningCount++;

+    }

+    //

+    // Parse: ErasePolarity = 1,

+    //

+    if (!SFPIsKeyword ("ErasePolarity")) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPGetNumber (&Num) || ((Num != 0) && (Num != 1))) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    FDDesc->ErasePolarity = Num;

+    if (!SFPIsToken (",")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL);

+      WarningCount++;

+    }

+    //

+    // Parse array of:

+    //   Block {  Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }

+    //

+    // Keep track of size to make sure the sum of the physical blocks and region sizes do not

+    // exceed the size of the flash device.

+    //

+    BlockSizeLeft   = FDDesc->Size;

+    RegionSizeLeft  = FDDesc->Size;

+    while (SFPIsKeyword ("Block")) {

+      //

+      // Allocate memory for a new physical block descriptor

+      //

+      FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));

+      if (FBlockDesc == NULL) {

+        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));

+      //

+      // Open brace -- warning if not there

+      //

+      if (!SFPIsToken ("{")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);

+        WarningCount++;

+      }

+      //

+      // Parse:  Name = "BlockName",

+      //

+      if (!SFPIsKeyword ("Name")) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+        WarningCount++;

+      }

+

+      if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+      //

+      // Make sure there are no other physical block names with this same name

+      //

+      for (TempBlockDesc = FDDesc->PBlocks; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {

+        if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {

+          Error (

+            SFPGetFileName (),

+            SFPGetLineNumber (),

+            0,

+            TempBlockDesc->Name,

+            "physical block with this name already defined"

+            );

+          ErrorCount++;

+        }

+      }

+

+      if (!SFPIsToken (",")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL);

+        WarningCount++;

+      }

+      //

+      // Parse: Size = 0x2000,

+      //

+      if (!SFPIsKeyword ("Size")) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+        WarningCount++;

+      }

+

+      if (!SFPGetNumber (&FBlockDesc->Size)) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+      //

+      // Make sure the sum of physical blocks so far does not exceed flash device size

+      //

+      if (BlockSizeLeft < FBlockDesc->Size) {

+        Error (

+          SFPGetFileName (),

+          SFPGetLineNumber (),

+          0,

+          "sum of physical block sizes exceeds flash device size",

+          NULL

+          );

+        ErrorCount++;

+      }

+

+      BlockSizeLeft -= FBlockDesc->Size;

+      SFPIsToken (",");

+      //

+      // Optional parse: Flags = 0xFFF0000,

+      //

+      if (SFPIsKeyword ("Flags")) {

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetNumber (&FBlockDesc->Flags)) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+      }

+

+      if (!SFPIsToken ("}")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL);

+        WarningCount++;

+      }

+      //

+      // Add the physical block descriptor to the end of the linked list

+      //

+      if (FDDesc->LastPBlock != NULL) {

+        FDDesc->LastPBlock->Next = FBlockDesc;

+      } else {

+        FDDesc->PBlocks = FBlockDesc;

+      }

+

+      FDDesc->LastPBlock = FBlockDesc;

+    }

+    //

+    // Make sure sum of sizes of physical blocks added up to size of flash device

+    //

+    if (BlockSizeLeft != 0) {

+      Error (

+        SFPGetFileName (),

+        SFPGetLineNumber (),

+        0,

+        NULL,

+        "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",

+        FDDesc->Size - BlockSizeLeft,

+        FDDesc->Size,

+        BlockSizeLeft

+        );

+      ErrorCount++;

+    }

+    //

+    // Parse array of:

+    //   Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" }

+    //

+    while (SFPIsKeyword ("Region")) {

+      //

+      // Allocate memory for a new physical block descriptor

+      //

+      FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));

+      if (FBlockDesc == NULL) {

+        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));

+      //

+      // Open brace -- warning if not there

+      //

+      if (!SFPIsToken ("{")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);

+        WarningCount++;

+      }

+      //

+      // Parse:  Name = "BlockName",

+      //

+      if (!SFPIsKeyword ("Name")) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+        WarningCount++;

+      }

+

+      if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+      //

+      // Make sure there are no other region names with this same name

+      //

+      for (TempBlockDesc = FDDesc->Regions; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {

+        if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {

+          Error (

+            SFPGetFileName (),

+            SFPGetLineNumber (),

+            0,

+            TempBlockDesc->Name,

+            "Region with this name already defined"

+            );

+          ErrorCount++;

+        }

+      }

+

+      if (!SFPIsToken (",")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);

+        WarningCount++;

+      }

+      //

+      // Parse: Size = 0x2000,

+      //

+      if (!SFPIsKeyword ("Size")) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+        WarningCount++;

+      }

+

+      if (!SFPGetNumber (&FBlockDesc->Size)) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken (",")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);

+      }

+      //

+      // Make sure the sum of regions so far does not exceed flash device size

+      //

+      if (RegionSizeLeft < FBlockDesc->Size) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL);

+        ErrorCount++;

+      }

+

+      RegionSizeLeft -= FBlockDesc->Size;

+      //

+      // Optional parse: Flags = 0xFFF0000,

+      //

+      if (SFPIsKeyword ("Flags")) {

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetNumber (&FBlockDesc->Flags)) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+        //

+        // comma

+        //

+        if (!SFPIsToken (",")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);

+        }

+      }

+      //

+      // Optional parse: Alignment = 4

+      //

+      if (SFPIsKeyword ("Alignment")) {

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetNumber (&FBlockDesc->Alignment)) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+        //

+        // comma

+        //

+        if (!SFPIsToken (",")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);

+        }

+      }

+      //

+      // Parse:  Attributes = "String",

+      //

+      if (!SFPIsKeyword ("Attributes")) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+        WarningCount++;

+      }

+

+      if (!SFPGetQuotedString (FBlockDesc->Attributes, sizeof (FBlockDesc->Attributes))) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken (",")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);

+      }

+      //

+      // Parse:  AreaType = "String",

+      //

+      if (!SFPIsKeyword ("AreaType")) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+        WarningCount++;

+      }

+

+      if (!SFPGetQuotedString (FBlockDesc->AreaType, sizeof (FBlockDesc->AreaType))) {

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);

+        ErrorCount++;

+        goto Done;

+      }

+

+      PreviousComma = SFPIsToken (",");

+      //

+      // Parse optional Subregion definitions

+      //

+      SubregionSizeLeft = FBlockDesc->Size;

+      while (SFPIsToken ("Subregion")) {

+        if (!PreviousComma) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL);

+          WarningCount++;

+          PreviousComma = TRUE;

+        }

+

+        Subregion = ParseSubregionDefinition (SubregionSizeLeft);

+        if (Subregion == NULL) {

+          ErrorCount++;

+          goto Done;

+        }

+

+        SubregionSizeLeft -= Subregion->Size;

+        //

+        // Add it to the end of our list

+        //

+        if (FBlockDesc->Subregions == NULL) {

+          FBlockDesc->Subregions = Subregion;

+        } else {

+          FBlockDesc->LastSubregion->Next = Subregion;

+        }

+

+        FBlockDesc->LastSubregion = Subregion;

+        //

+        // Make sure all subregion names are unique. We do this each time

+        // through so that we catch the error immediately after it happens, in

+        // which case the reported line number is at least close to where the

+        // problem lies. We don't exit on the error because we can continue parsing

+        // the script to perhaps catch other errors or warnings.

+        //

+        for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+          for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) {

+            if (strcmp (Subregion->Name, TempSubregion->Name) == 0) {

+              Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name");

+              ErrorCount++;

+            }

+          }

+        }

+      }

+

+      if (!SFPIsToken ("}")) {

+        Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL);

+        WarningCount++;

+      }

+      //

+      // Add the region descriptor to the end of the linked list

+      //

+      if (FDDesc->LastRegion != NULL) {

+        FDDesc->LastRegion->Next = FBlockDesc;

+      } else {

+        FDDesc->Regions = FBlockDesc;

+      }

+

+      FDDesc->LastRegion = FBlockDesc;

+    }

+    //

+    // Make sure sum of sizes of regions adds up to size of flash device

+    //

+    if (RegionSizeLeft != 0) {

+      Error (

+        SFPGetFileName (),

+        SFPGetLineNumber (),

+        0,

+        NULL,

+        "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",

+        FDDesc->Size - RegionSizeLeft,

+        FDDesc->Size,

+        RegionSizeLeft

+        );

+      ErrorCount++;

+    }

+    //

+    // Look for closing brace

+    //

+    if (!SFPIsToken ("}")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL);

+      WarningCount++;

+    }

+    //

+    // Add this flash description to the list

+    //

+    FDDesc->Next  = mFlashDevices;

+    mFlashDevices = FDDesc;

+  }

+

+  while (SFPIsKeyword ("FlashDeviceImage")) {

+    //

+    // Allocate memory for a new FD image definition

+    //

+    ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION));

+    if (ImageDef == NULL) {

+      Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    memset (ImageDef, 0, sizeof (IMAGE_DEFINITION));

+    //

+    // Open brace -- warning if not there

+    //

+    if (!SFPIsToken ("{")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);

+      WarningCount++;

+    }

+    //

+    // Parse:  Name = "ImageName",

+    //

+    if (!SFPIsKeyword ("Name")) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL);

+      ErrorCount++;

+      goto Done;

+    }

+

+    if (!SFPIsToken (",")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL);

+      WarningCount++;

+    }

+

+    while (1) {

+      //

+      // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE }

+      //

+      if (SFPIsKeyword ("File")) {

+        ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));

+        if (ImageDefEntry == NULL) {

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));

+        //

+        // Open brace -- warning if not there

+        //

+        if (!SFPIsToken ("{")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);

+          WarningCount++;

+        }

+        //

+        // Parse: Name = "FileName.txt"

+        //

+        if (!SFPIsKeyword ("Name")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken (",")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL);

+          WarningCount++;

+        }

+        //

+        // Parse: Region = "REGION_NAME"

+        //

+        if (!SFPIsKeyword ("Region")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken (",")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);

+          WarningCount++;

+        }

+        //

+        // Parse optional: Subregion = "SUBREGION_NAME"

+        //

+        if (SFPIsKeyword ("Subregion")) {

+          if (!SFPIsToken ("=")) {

+            Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+            WarningCount++;

+          }

+

+          if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {

+            Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);

+            ErrorCount++;

+            goto Done;

+          }

+

+          if (!SFPIsToken (",")) {

+            Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);

+            WarningCount++;

+          }

+          //

+          // For a given region, you can only place data using the region name, or the subregion names.

+          // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that

+          // here by checking that any previous entries with the same Region name had a Subregion specified

+          // as well.

+          //

+          for (TempImageDefEntry = ImageDef->Entries;

+               TempImageDefEntry != NULL;

+               TempImageDefEntry = TempImageDefEntry->Next

+              ) {

+            if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {

+              if (TempImageDefEntry->SubregionName[0] == 0) {

+                Error (

+                  SFPGetFileName (),

+                  SFPGetLineNumber (),

+                  0,

+                  TempImageDefEntry->RegionName,

+                  "data already placed on a region-basis in the region, can't place data using subregions"

+                  );

+                ErrorCount++;

+              }

+            }

+          }

+        }

+        //

+        // Optional parse: Optional = TRUE | FALSE

+        //

+        if (SFPIsKeyword ("Optional")) {

+          if (!SFPIsToken ("=")) {

+            Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+            WarningCount++;

+          }

+

+          if (!SFPIsKeyword ("TRUE")) {

+            ImageDefEntry->Optional = 1;

+          } else if (SFPIsKeyword ("FALSE")) {

+            //

+            // Already set to 0

+            //

+          } else {

+            Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);

+            ErrorCount++;

+            goto Done;

+          }

+

+          SFPIsToken (",");

+        }

+        //

+        // Closing brace

+        //

+        if (!SFPIsToken ("}")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+        //

+        // Add the entry to the end of the list

+        //

+        if (ImageDef->LastEntry != NULL) {

+          ImageDef->LastEntry->Next = ImageDefEntry;

+        } else {

+          ImageDef->Entries = ImageDefEntry;

+        }

+

+        ImageDef->LastEntry = ImageDefEntry;

+      } else if (SFPIsKeyword ("RawData")) {

+        //

+        // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }}

+        //

+        ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));

+        if (ImageDefEntry == NULL) {

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));

+        ImageDefEntry->IsRawData = 1;

+        //

+        // Open brace -- warning if not there

+        //

+        if (!SFPIsToken ("{")) {

+          Warning (

+            SFPGetFileName (),

+            SFPGetLineNumber (),

+            0,

+            "expected '{' opening brace for RawData definition",

+            NULL

+            );

+          WarningCount++;

+        }

+        //

+        // Parse: Name = "PadBytes"

+        //

+        if (!SFPIsKeyword ("Name")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken (",")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL);

+          WarningCount++;

+        }

+        //

+        // Parse: Region = "REGION_NAME"

+        //

+        if (!SFPIsKeyword ("Region")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken (",")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);

+          WarningCount++;

+        }

+        //

+        // Parse optional: Subregion = "SUBREGION_NAME"

+        //

+        if (SFPIsKeyword ("Subregion")) {

+          if (!SFPIsToken ("=")) {

+            Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+            WarningCount++;

+          }

+

+          if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {

+            Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);

+            ErrorCount++;

+            goto Done;

+          }

+

+          if (!SFPIsToken (",")) {

+            Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);

+            WarningCount++;

+          }

+          //

+          // For a given region, you can only place data using the region name, or the subregion names.

+          // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that

+          // here by checking that any previous entries with the same Region name had a Subregion specified

+          // as well.

+          //

+          for (TempImageDefEntry = ImageDef->Entries;

+               TempImageDefEntry != NULL;

+               TempImageDefEntry = TempImageDefEntry->Next

+              ) {

+            if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {

+              if (TempImageDefEntry->SubregionName[0] == 0) {

+                Error (

+                  SFPGetFileName (),

+                  SFPGetLineNumber (),

+                  0,

+                  TempImageDefEntry->RegionName,

+                  "data already placed on a region-basis in the region, can't place data using subregions"

+                  );

+                ErrorCount++;

+              }

+            }

+          }

+        }

+        //

+        // Parse: Data = { 0x78, 0x56, 0x34, 0x12 }

+        //

+        if (!SFPIsKeyword ("Data")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+

+        if (!SFPIsToken ("=")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+          WarningCount++;

+        }

+

+        if (!SFPIsToken ("{")) {

+          Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL);

+          WarningCount++;

+        }

+

+        if ((BufferData = CreateBufferData ()) == NULL) {

+          ErrorCount++;

+          goto Done;

+        }

+        //

+        // Read bytes from input file until closing brace

+        //

+        while (!SFPIsToken ("}")) {

+          if (!SFPGetNumber (&Num)) {

+            SFPGetNextToken (Str, sizeof (Str));

+            Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str);

+            ErrorCount++;

+            FreeBufferData (BufferData, TRUE);

+            goto Done;

+          } else {

+            //

+            // Only allow bytes

+            //

+            if (Num > 0xFF) {

+              Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL);

+              ErrorCount++;

+              FreeBufferData (BufferData, TRUE);

+              goto Done;

+            }

+

+            AddBufferDataByte (BufferData, (char) Num);

+            SFPIsToken (",");

+          }

+        }

+        //

+        // Now get the data and save it in our image entry

+        //

+        ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize);

+        FreeBufferData (BufferData, 0);

+        //

+        // Closing brace for RawData {}

+        //

+        if (!SFPIsToken ("}")) {

+          Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL);

+          ErrorCount++;

+          goto Done;

+        }

+        //

+        // Add the entry to the end of the list

+        //

+        if (ImageDef->LastEntry != NULL) {

+          ImageDef->LastEntry->Next = ImageDefEntry;

+        } else {

+          ImageDef->Entries = ImageDefEntry;

+        }

+

+        ImageDef->LastEntry = ImageDefEntry;

+      } else if (SFPIsToken ("}")) {

+        //

+        // Closing brace for FDImage {}

+        //

+        break;

+      } else {

+        SFPGetNextToken (Str, sizeof (Str));

+        Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str);

+        ErrorCount++;

+        goto Done;

+      }

+    }

+    //

+    // Add this image definition to our global list

+    //

+    ImageDef->Next    = mImageDefinitions;

+    mImageDefinitions = ImageDef;

+  }

+  //

+  // Check for end-of-file

+  //

+  if (!SFPIsEOF ()) {

+    SFPGetNextToken (Str, sizeof (Str));

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str);

+    ErrorCount++;

+  }

+

+Done:

+  SFPCloseFile ();

+  if (ErrorCount != 0) {

+    return STATUS_ERROR;

+  } else if (WarningCount != 0) {

+    return STATUS_WARNING;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+FLASH_SUBREGION_DESCRIPTION *

+ParseSubregionDefinition (

+  unsigned int  SizeLeft

+  )

+/*++

+  

+Routine Description:

+

+  Parse Subregion definitions from the input flash definition file. Format:

+

+    Subregion {

+      CreateHob       = TRUE,

+      Name            = "FOO",

+      Size            = 0xA000,

+      Attributes      = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV",

+      AreaType        = "EFI_FLASH_AREA_EFI_VARIABLES",

+      NameGuid        = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"),

+      AreaTypeGuid    = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)

+      FileSystemGuid  = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)

+    }

+

+    NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace.

+

+Arguments:

+   

+   SizeLeft   - in the flash definition file, a Region can be broken up into

+                one or more subregions. As we parse the subregion definitions,

+                the caller keeps track of how much space is left in the region

+                that we're parsing subregions for. SizeLeft is that size, and

+                so the size of the subregion we're now parsing better not

+                exceed the size left.

+  Returns:

+

+    NULL    - unrecoverable errors detected while parsing the subregion definition

+

+    pointer to a subregion definition created from the parsed subregion

+

+--*/

+{

+  FLASH_SUBREGION_DESCRIPTION *Subregion;

+  int                         ErrorCount;

+  int                         WarningCount;

+  unsigned int                Number;

+  BOOLEAN                     PreviousComma;

+  //

+  // Allocate memory for the new subregion descriptor

+  //

+  ErrorCount    = 0;

+  WarningCount  = 0;

+  Subregion     = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION));

+  if (Subregion == NULL) {

+    Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION));

+  //

+  // Open brace -- warning if not there

+  //

+  if (!SFPIsToken ("{")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);

+    WarningCount++;

+  }

+  //

+  // Parse:  CreateHob = TRUE | FALSE,

+  //

+  if (!SFPIsKeyword ("CreateHob")) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken ("=")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+    WarningCount++;

+  }

+

+  if (SFPIsToken ("TRUE")) {

+    Subregion->CreateHob = 1;

+  } else if (SFPIsToken ("FALSE")) {

+    //

+    // Subregion->CreateHob = 0; -- not required since we did a memset earlier

+    //

+  } else {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken (",")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL);

+    WarningCount++;

+  }

+  //

+  // Parse:  Name = "Name",

+  //

+  if (!SFPIsKeyword ("Name")) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken ("=")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+    WarningCount++;

+  }

+

+  if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken (",")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);

+    WarningCount++;

+  }

+  //

+  // Parse: Size = 0x2000,

+  //

+  if (!SFPIsKeyword ("Size")) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken ("=")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+    WarningCount++;

+  }

+

+  if (!SFPGetNumber (&Subregion->Size)) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  //

+  // Check that the size does not exceed the size left passed in

+  //

+  if (Subregion->Size > SizeLeft) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken (",")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL);

+  }

+  //

+  // Parse:  Attributes = Number | "String",

+  //

+  if (!SFPIsKeyword ("Attributes")) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken ("=")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+    WarningCount++;

+  }

+

+  if (SFPGetNumber (&Number)) {

+    sprintf (Subregion->Attributes, "0x%X", Number);

+  } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken (",")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);

+  }

+  //

+  // Parse:  AreaType = Number | "String",

+  // AreaType is a UINT8, so error if it exceeds the size

+  //

+  if (!SFPIsKeyword ("AreaType")) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken ("=")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+    WarningCount++;

+  }

+

+  if (SFPGetNumber (&Number)) {

+    if (Number > 0xFF) {

+      Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL);

+      ErrorCount++;

+    }

+

+    sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF);

+  } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken (",")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL);

+  }

+  //

+  // Parse the three GUIDs (last two are optional)

+  //

+  //    NameGuid        = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID")

+  //    AreaTypeGuid    = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")

+  //    FileSysteGuid   = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")

+  //

+  if (!SFPIsKeyword ("NameGuid")) {

+    Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL);

+    ErrorCount++;

+    goto Done;

+  }

+

+  if (!SFPIsToken ("=")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+    WarningCount++;

+  }

+  //

+  // Allow a GUID or a quoted string identifier, which we'll just copy as a string

+  //

+  if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) {

+    //

+    // Nothing else to do

+    //

+  } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) {

+    Error (

+      SFPGetFileName (),

+      SFPGetLineNumber (),

+      0,

+      "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",

+      NULL

+      );

+    ErrorCount++;

+    goto Done;

+  }

+  //

+  // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid

+  //

+  PreviousComma = SFPIsToken (",");

+  if (SFPIsKeyword ("AreaTypeGuid")) {

+    //

+    // Check for preceeding comma now

+    //

+    if (!PreviousComma) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+

+    if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) {

+      //

+      // Nothing else to do

+      //

+    } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) {

+      Error (

+        SFPGetFileName (),

+        SFPGetLineNumber (),

+        0,

+        "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",

+        NULL

+        );

+      ErrorCount++;

+      goto Done;

+    }

+

+    PreviousComma = SFPIsToken (",");

+  }

+

+  if (SFPIsKeyword ("FileSystemGuid")) {

+    //

+    // Check for preceeding comma now

+    //

+    if (!PreviousComma) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL);

+      WarningCount++;

+    }

+

+    if (!SFPIsToken ("=")) {

+      Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);

+      WarningCount++;

+    }

+    //

+    // Allow a GUID or a quoted string identifier, which we'll just copy as a string

+    //

+    if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) {

+      //

+      // Nothing else to do

+      //

+    } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) {

+      Error (

+        SFPGetFileName (),

+        SFPGetLineNumber (),

+        0,

+        "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",

+        NULL

+        );

+      ErrorCount++;

+      goto Done;

+    }

+

+    SFPIsToken (",");

+  }

+  //

+  // Look for subregion closing brace

+  //

+  if (!SFPIsToken ("}")) {

+    Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL);

+    WarningCount++;

+  }

+

+Done:

+  //

+  // If any errors were encountered, then delete the subregion definition

+  //

+  if (ErrorCount != 0) {

+    _free (Subregion);

+    Subregion = NULL;

+  }

+

+  return Subregion;

+}

+

+STATUS

+FDFCreateCIncludeFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+  Create a header file with #define definitions per an already-parsed

+  flash definition file.

+

+Arguments:

+  FlashDeviceName - name of flash device (from the flash definition file)

+                    to use

+  FileName        - name of output file to create

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  FILE                        *OutFptr;

+  FLASH_BLOCK_DESCRIPTION     *FBlock;

+  FLASH_DEVICE_DESCRIPTION    *FDev;

+  FLASH_SUBREGION_DESCRIPTION *Subregion;

+  unsigned int                Offset;

+  unsigned int                SubregionOffset;

+  int                         CreateHobs;

+  //

+  // Find the definition we're supposed to use

+  //

+  for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {

+    if (strcmp (FDev->Name, FlashDeviceName) == 0) {

+      break;

+    }

+  }

+

+  if (FDev == NULL) {

+    Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");

+    return STATUS_ERROR;

+  }

+

+  if ((OutFptr = fopen (FileName, "w")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+  //

+  // Write a header

+  //

+  fprintf (OutFptr, CIncludeHeader);

+  //

+  // Write flash block base and size defines

+  //

+  fprintf (OutFptr, "#define FLASH_BASE                                          0x%08X\n", FDev->BaseAddress);

+  fprintf (OutFptr, "#define FLASH_SIZE                                          0x%08X\n\n", FDev->Size);

+  //

+  // Write flash regions base, size and offset defines

+  //

+  Offset      = 0;

+  CreateHobs  = 0;

+  for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {

+    fprintf (

+      OutFptr,

+      "#define FLASH_REGION_%s_BASE              %*c0x%08X\n",

+      FBlock->Name,

+      COLUMN2_START - 40 - strlen (FBlock->Name),

+      ' ',

+      Offset + FDev->BaseAddress

+      );

+    fprintf (

+      OutFptr,

+      "#define FLASH_REGION_%s_SIZE              %*c0x%08X\n",

+      FBlock->Name,

+      COLUMN2_START - 40 - strlen (FBlock->Name),

+      ' ',

+      FBlock->Size

+      );

+    fprintf (

+      OutFptr,

+      "#define FLASH_REGION_%s_OFFSET            %*c0x%08X\n",

+      FBlock->Name,

+      COLUMN2_START - 40 - strlen (FBlock->Name),

+      ' ',

+      Offset

+      );

+    //

+    // Create defines for any subregions

+    //

+    SubregionOffset = 0;

+    for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+      fprintf (

+        OutFptr,

+        "#define FLASH_REGION_%s_SUBREGION_%s_BASE     %*c0x%08X\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        FDev->BaseAddress + Offset + SubregionOffset

+        );

+      fprintf (

+        OutFptr,

+        "#define FLASH_REGION_%s_SUBREGION_%s_SIZE     %*c0x%08X\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        Subregion->Size

+        );

+      fprintf (

+        OutFptr,

+        "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET   %*c0x%08X\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        Offset + SubregionOffset

+        );

+      SubregionOffset += Subregion->Size;

+      if (Subregion->CreateHob != 0) {

+        CreateHobs = 1;

+      }

+    }

+

+    Offset += FBlock->Size;

+  }

+  //

+  // Now create a #define for the flash map data definition

+  //

+  fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n");

+  //

+  // Emit entry for each region

+  //

+  Offset = 0;

+  for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {

+    fprintf (OutFptr, "  /* %s region */\\\n", FBlock->Name);

+    fprintf (OutFptr, "  {\\\n");

+    fprintf (OutFptr, "    FLASH_REGION_%s_BASE,\\\n", FBlock->Name);

+    fprintf (OutFptr, "    FLASH_REGION_%s_SIZE,\\\n", FBlock->Name);

+    fprintf (OutFptr, "    %s,\\\n", FBlock->Attributes);

+    fprintf (OutFptr, "    %s,\\\n  },\\\n", FBlock->AreaType);

+  }

+

+  fprintf (OutFptr, "\n\n");

+  //

+  // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition

+  //

+  if (CreateHobs != 0) {

+    fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n");

+    fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION");

+    for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {

+      //

+      // See if the block has subregions, and that the CreateHobs flag is set

+      // for any of them.

+      //

+      CreateHobs = 0;

+      for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+        if (Subregion->CreateHob != 0) {

+          CreateHobs = 1;

+          break;

+        }

+      }

+      //

+      // If any of the subregions had the CreateHobs flag set, then create the entries in the

+      // output file

+      //

+      if (CreateHobs != 0) {

+        for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+          if (Subregion->CreateHob != 0) {

+            fprintf (OutFptr, " \\\n");

+            fprintf (OutFptr, "  /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name);

+            fprintf (OutFptr, "  {\\\n");

+            fprintf (OutFptr, "    EFI_HOB_TYPE_GUID_EXTENSION,\\\n");

+            fprintf (OutFptr, "    sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n");

+            fprintf (OutFptr, "    0,\\\n");

+            //

+            // The NameGuid may have been specified in the input flash definition file as a GUID, or

+            // as a quoted string. Do the right one.

+            //

+            if (Subregion->NameGuidString[0] != 0) {

+              fprintf (OutFptr, "    %s, \\\n", Subregion->NameGuidString);

+            } else {

+              fprintf (

+                OutFptr,

+                "    { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",

+                Subregion->NameGuid.Data1,

+                (unsigned int) Subregion->NameGuid.Data2,

+                (unsigned int) Subregion->NameGuid.Data3,

+                (unsigned int) Subregion->NameGuid.Data4[0],

+                (unsigned int) Subregion->NameGuid.Data4[1],

+                (unsigned int) Subregion->NameGuid.Data4[2],

+                (unsigned int) Subregion->NameGuid.Data4[3],

+                (unsigned int) Subregion->NameGuid.Data4[4],

+                (unsigned int) Subregion->NameGuid.Data4[5],

+                (unsigned int) Subregion->NameGuid.Data4[6],

+                (unsigned int) Subregion->NameGuid.Data4[7]

+                );

+            }

+

+            fprintf (OutFptr, "    0, 0, 0,\\\n");

+            fprintf (OutFptr, "    %s,\\\n", Subregion->AreaType);

+            //

+            // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or

+            // as a quoted string. Do the right one.

+            //

+            if (Subregion->AreaTypeGuidString[0] != 0) {

+              fprintf (OutFptr, "    %s, \\\n", Subregion->AreaTypeGuidString);

+            } else {

+              fprintf (

+                OutFptr,

+                "    { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",

+                Subregion->AreaTypeGuid.Data1,

+                (unsigned int) Subregion->AreaTypeGuid.Data2,

+                (unsigned int) Subregion->AreaTypeGuid.Data3,

+                (unsigned int) Subregion->AreaTypeGuid.Data4[0],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[1],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[2],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[3],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[4],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[5],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[6],

+                (unsigned int) Subregion->AreaTypeGuid.Data4[7]

+                );

+            }

+

+            fprintf (OutFptr, "    1,\\\n");

+            fprintf (OutFptr, "    {\\\n");

+            fprintf (OutFptr, "      %s,\\\n", Subregion->Attributes);

+            fprintf (OutFptr, "      0,\\\n");

+            fprintf (OutFptr, "      FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name);

+            fprintf (OutFptr, "      FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name);

+            //

+            // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or

+            // as a quoted string. Do the right one.

+            //

+            if (Subregion->FileSystemGuidString[0] != 0) {

+              fprintf (OutFptr, "      %s, \\\n", Subregion->FileSystemGuidString);

+            } else {

+              fprintf (

+                OutFptr,

+                "      { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",

+                Subregion->FileSystemGuid.Data1,

+                (unsigned int) Subregion->FileSystemGuid.Data2,

+                (unsigned int) Subregion->FileSystemGuid.Data3,

+                (unsigned int) Subregion->FileSystemGuid.Data4[0],

+                (unsigned int) Subregion->FileSystemGuid.Data4[1],

+                (unsigned int) Subregion->FileSystemGuid.Data4[2],

+                (unsigned int) Subregion->FileSystemGuid.Data4[3],

+                (unsigned int) Subregion->FileSystemGuid.Data4[4],

+                (unsigned int) Subregion->FileSystemGuid.Data4[5],

+                (unsigned int) Subregion->FileSystemGuid.Data4[6],

+                (unsigned int) Subregion->FileSystemGuid.Data4[7]

+                );

+            }

+

+            fprintf (OutFptr, "    },\\\n");

+            fprintf (OutFptr, "  },");

+          }

+        }

+      }

+    }

+

+    fprintf (OutFptr, "\n\n");

+  }

+

+  //

+  // Write the file's closing #endif

+  //

+  fprintf (OutFptr, CIncludeFooter);

+  fclose (OutFptr);

+  return STATUS_SUCCESS;

+}

+

+STATUS

+FDFCreateAsmIncludeFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+  Create an assembly header file with equate definitions per an already-parsed

+  flash definition file.

+

+Arguments:

+  FlashDeviceName - name of flash device (from the flash definition file)

+                    to use

+  FileName        - name of output file to create

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  FILE                        *OutFptr;

+  FLASH_BLOCK_DESCRIPTION     *FBlock;

+  FLASH_DEVICE_DESCRIPTION    *FDev;

+  unsigned int                Offset;

+  FLASH_SUBREGION_DESCRIPTION *Subregion;

+  unsigned int                SubregionOffset;

+  //

+  // Find the definition we're supposed to use

+  //

+  for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {

+    if (strcmp (FDev->Name, FlashDeviceName) == 0) {

+      break;

+    }

+  }

+

+  if (FDev == NULL) {

+    Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");

+    return STATUS_ERROR;

+  }

+

+  if ((OutFptr = fopen (FileName, "w")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+  //

+  // Write a header

+  //

+  fprintf (OutFptr, "\n\n");

+  //

+  // Write flash block size and offset defines

+  //

+  fprintf (

+    OutFptr,

+    "FLASH_BASE                               %*cequ 0%08Xh\n",

+    COLUMN2_START - 40,

+    ' ',

+    FDev->BaseAddress

+    );

+  fprintf (OutFptr, "FLASH_SIZE                               %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size);

+  //

+  // Write flash region size and offset defines

+  //

+  fprintf (OutFptr, "\n");

+  Offset = 0;

+  for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {

+    fprintf (

+      OutFptr,

+      "FLASH_REGION_%s_BASE   %*cequ 0%08Xh\n",

+      FBlock->Name,

+      COLUMN2_START - 20 - strlen (FBlock->Name),

+      ' ',

+      FDev->BaseAddress + Offset

+      );

+    fprintf (

+      OutFptr,

+      "FLASH_REGION_%s_SIZE   %*cequ 0%08Xh\n",

+      FBlock->Name,

+      COLUMN2_START - 20 - strlen (FBlock->Name),

+      ' ',

+      FBlock->Size

+      );

+    fprintf (

+      OutFptr,

+      "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n",

+      FBlock->Name,

+      COLUMN2_START - 20 - strlen (FBlock->Name),

+      ' ',

+      Offset

+      );

+    //

+    // Create defines for any subregions

+    //

+    SubregionOffset = 0;

+    for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+      fprintf (

+        OutFptr,

+        "FLASH_REGION_%s_SUBREGION_%s_BASE     %*cequ 0%08Xh\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        FDev->BaseAddress + Offset + SubregionOffset

+        );

+      fprintf (

+        OutFptr,

+        "FLASH_REGION_%s_SUBREGION_%s_SIZE     %*cequ 0%08Xh\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        Subregion->Size

+        );

+      fprintf (

+        OutFptr,

+        "FLASH_REGION_%s_SUBREGION_%s_OFFSET   %*cequ 0%08Xh\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        Offset + SubregionOffset

+        );

+      SubregionOffset += Subregion->Size;

+    }

+

+    Offset += FBlock->Size;

+  }

+

+  //

+  // Write closing \n

+  //

+  fprintf (OutFptr, "\n\n");

+  fclose (OutFptr);

+  return STATUS_SUCCESS;

+}

+

+STATUS

+FDFCreateSymbols (

+  char      *FlashDeviceName

+  )

+/*++

+

+Routine Description:

+  Using the given flash device name, add symbols to the global symbol table. This

+  allows other functions to use the symbol definitions for other purposes.

+

+Arguments:

+  FlashDeviceName - name of flash device (from the flash definition file)

+                    to use

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  FLASH_BLOCK_DESCRIPTION     *FBlock;

+  FLASH_DEVICE_DESCRIPTION    *FDev;

+  unsigned int                Offset;

+  char                        SymName[120];

+  char                        SymValue[120];

+  FLASH_SUBREGION_DESCRIPTION *Subregion;

+  unsigned int                SubregionOffset;

+  //

+  // Find the definition we're supposed to use

+  //

+  for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {

+    if (strcmp (FDev->Name, FlashDeviceName) == 0) {

+      break;

+    }

+  }

+

+  if (FDev == NULL) {

+    Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");

+    return STATUS_ERROR;

+  }

+

+  sprintf (SymValue, "0x%08X", FDev->BaseAddress);

+  SymbolAdd ("FLASH_BASE", SymValue, 0);

+  sprintf (SymValue, "0x%08X", FDev->Size);

+  SymbolAdd ("FLASH_SIZE", SymValue, 0);

+  //

+  // Add flash block size and offset defines

+  //

+  // Offset = 0;

+  // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) {

+  //  sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name);

+  //  sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);

+  //  SymbolAdd (SymName, SymValue, 0);

+  //  sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name);

+  //  sprintf (SymValue, "0x%08X", FBlock->Size);

+  //  SymbolAdd (SymName, SymValue, 0);

+  //  sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name);

+  //  sprintf (SymValue, "0x%08X", Offset);

+  //  SymbolAdd (SymName, SymValue, 0);

+  //  Offset += FBlock->Size;

+  // }

+  //

+  // Add flash region block base, size, and offset defines

+  //

+  Offset = 0;

+  for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {

+    sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name);

+    sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);

+    SymbolAdd (SymName, SymValue, 0);

+    sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name);

+    sprintf (SymValue, "0x%08X", FBlock->Size);

+    SymbolAdd (SymName, SymValue, 0);

+    sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name);

+    sprintf (SymValue, "0x%08X", Offset);

+    SymbolAdd (SymName, SymValue, 0);

+    //

+    // Add subregion symbols

+    //

+    if (FBlock->Subregions != NULL) {

+      SubregionOffset = 0;

+      for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+        sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name);

+        sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset);

+        SymbolAdd (SymName, SymValue, 0);

+        sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name);

+        sprintf (SymValue, "0x%08X", Subregion->Size);

+        SymbolAdd (SymName, SymValue, 0);

+        sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name);

+        sprintf (SymValue, "0x%08X", Offset + SubregionOffset);

+        SymbolAdd (SymName, SymValue, 0);

+        SubregionOffset += Subregion->Size;

+      }

+    }

+

+    Offset += FBlock->Size;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+STATUS

+FDFCreateImage (

+  char      *FlashDeviceName,

+  char      *ImageName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+  Create a flash image using the given device and image names.

+

+Arguments:

+  FlashDeviceName - name of flash device (from the flash definition file)

+                    to use

+  ImageName       - name of image (from the flash definition file) to create

+  FileName        - name of output file to create

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  STATUS                      Status;

+  FILE                        *OutFptr;

+  FLASH_BLOCK_DESCRIPTION     *RegionDef;

+  FLASH_DEVICE_DESCRIPTION    *FDev;

+  IMAGE_DEFINITION            *ImageDef;

+  unsigned int                Offset;

+  char                        *Buffer;

+  FILE                        *InFptr;

+  long                        FileSize;

+  IMAGE_DEFINITION_ENTRY      *IDefEntry;

+  FLASH_SUBREGION_DESCRIPTION *SubregionDef;

+  //

+  // Find the flash definition we're supposed to use

+  //

+  InFptr  = NULL;

+  Status  = STATUS_ERROR;

+  for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {

+    if (strcmp (FDev->Name, FlashDeviceName) == 0) {

+      break;

+    }

+  }

+

+  if (FDev == NULL) {

+    Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");

+    return STATUS_ERROR;

+  }

+  //

+  // Find the image name we're supposed to create

+  //

+  for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) {

+    if (strcmp (ImageDef->Name, ImageName) == 0) {

+      break;

+    }

+  }

+

+  if (ImageDef == NULL) {

+    Error (NULL, 0, 0, ImageName, "image definition not found in image definitions");

+    return STATUS_ERROR;

+  }

+  //

+  // Open the output file

+  //

+  if ((OutFptr = fopen (FileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+  //

+  // Allocate a buffer to copy the input data to

+  //

+  Buffer = (char *) _malloc (FDev->Size);

+  if (Buffer == NULL) {

+    Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL);

+    goto Done;

+  }

+  //

+  // Set contents of buffer to the erased value

+  //

+  if (FDev->ErasePolarity) {

+    memset (Buffer, 0xFF, FDev->Size);

+  } else {

+    memset (Buffer, 0, FDev->Size);

+  }

+  //

+  // Set all region and subregion size-left fields to the size of the region/subregion

+  //

+  for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {

+    RegionDef->SizeLeft = RegionDef->Size;

+    for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {

+      SubregionDef->SizeLeft = SubregionDef->Size;

+    }

+  }

+  //

+  // Now go through the image list, read files into the buffer.

+  //

+  for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) {

+    //

+    // If it's a file name, open the file, get the size, find the corresponding

+    // flash region it's in, and copy the data.

+    //

+    if (IDefEntry->IsRawData == 0) {

+      if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) {

+        Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading");

+        goto Done;

+      }

+

+      fseek (InFptr, 0, SEEK_END);

+      FileSize = ftell (InFptr);

+      fseek (InFptr, 0, SEEK_SET);

+    } else {

+      FileSize = IDefEntry->RawDataSize;

+    }

+    //

+    // Find the region/subregion it's in, see if we have space left

+    //

+    Offset = 0;

+    for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {

+      if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) {

+        break;

+      }

+

+      Offset += RegionDef->Size;

+    }

+

+    if (RegionDef == NULL) {

+      Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name);

+      goto Done;

+    }

+

+    //

+    // Check for subregion

+    //

+    if (IDefEntry->SubregionName[0] != 0) {

+      for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {

+        if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) {

+          break;

+        }

+

+        Offset += SubregionDef->Size;

+      }

+

+      if (SubregionDef == NULL) {

+        Error (

+          NULL,

+          0,

+          0,

+          IDefEntry->SubregionName,

+          "Subregion name not found in FlashDevice %s.%s Region definition",

+          FDev->Name,

+          RegionDef->Name

+          );

+        goto Done;

+      }

+      //

+      // Enough space in the subregion?

+      //

+      if (SubregionDef->SizeLeft < (unsigned int) FileSize) {

+        Error (

+          NULL,

+          0,

+          0,

+          IDefEntry->Name,

+          "insufficient space in Subregion (at least 0x%X additional bytes required)",

+          FileSize - SubregionDef->SizeLeft

+          );

+        goto Done;

+      }

+

+      //

+      // Read the file into the buffer if it's a file. Otherwise copy the raw data

+      //

+      if (IDefEntry->IsRawData == 0) {

+        if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) {

+          Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");

+          goto Done;

+        }

+

+        fclose (InFptr);

+        InFptr = NULL;

+      } else {

+        memcpy (

+          Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft),

+          IDefEntry->RawData,

+          IDefEntry->RawDataSize

+          );

+      }

+

+      SubregionDef->SizeLeft -= FileSize;

+      //

+      // Align based on the Region alignment requirements.

+      //

+      if (RegionDef->Alignment != 0) {

+        while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) {

+          if (SubregionDef->SizeLeft == 0) {

+            break;

+          }

+

+          SubregionDef->SizeLeft--;

+        }

+      }

+    } else {

+      //

+      // Placing data in a region. Check for enough space in the region left.

+      //

+      if (RegionDef->SizeLeft < (unsigned int) FileSize) {

+        Error (

+          NULL,

+          0,

+          0,

+          IDefEntry->Name,

+          "insufficient space in Region (at least 0x%X additional bytes required)",

+          FileSize - RegionDef->SizeLeft

+          );

+        goto Done;

+      }

+

+      //

+      // Read the file into the buffer if it's a file. Otherwise copy the raw data

+      //

+      if (IDefEntry->IsRawData == 0) {

+        if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) {

+          Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");

+          goto Done;

+        }

+

+        fclose (InFptr);

+        InFptr = NULL;

+      } else {

+        memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize);

+      }

+

+      RegionDef->SizeLeft -= FileSize;

+      //

+      // Align

+      //

+      if (RegionDef->Alignment != 0) {

+        while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) {

+          if (RegionDef->SizeLeft == 0) {

+            break;

+          }

+

+          RegionDef->SizeLeft--;

+        }

+      }

+    }

+  }

+

+  if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL);

+    goto Done;

+  }

+

+  Status = STATUS_SUCCESS;

+Done:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+

+  if (Buffer != NULL) {

+    _free (Buffer);

+  }

+

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+    if (Status == STATUS_ERROR) {

+      remove (FileName);

+    }

+  }

+

+  return Status;

+}

+

+STATUS

+FDFCreateDscFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+  Create a DSC-style output file with equates for flash management.

+

+Arguments:

+  FlashDeviceName - name of flash device (from the flash definition file)

+                    to use

+  FileName        - name of output file to create

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  FILE                        *OutFptr;

+  FLASH_BLOCK_DESCRIPTION     *FBlock;

+  FLASH_DEVICE_DESCRIPTION    *FDev;

+  unsigned int                Offset;

+  FLASH_SUBREGION_DESCRIPTION *Subregion;

+  unsigned int                SubregionOffset;

+  //

+  // Find the definition we're supposed to use

+  //

+  for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {

+    if (strcmp (FDev->Name, FlashDeviceName) == 0) {

+      break;

+    }

+  }

+

+  if (FDev == NULL) {

+    Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");

+    return STATUS_ERROR;

+  }

+

+  if ((OutFptr = fopen (FileName, "w")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+  //

+  // Write the flash base address and size

+  //

+  fprintf (OutFptr, "\n");

+  fprintf (OutFptr, "FLASH_BASE                                      = 0x%08X\n", FDev->BaseAddress);

+  fprintf (OutFptr, "FLASH_SIZE                                      = 0x%08X\n\n", FDev->Size);

+  //

+  // Write flash block size and offset defines

+  //

+  Offset = 0;

+  for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {

+    fprintf (

+      OutFptr,

+      "FLASH_REGION_%s_BASE          %*c= 0x%08X\n",

+      FBlock->Name,

+      COLUMN2_START - 40 - strlen (FBlock->Name),

+      ' ',

+      Offset + FDev->BaseAddress

+      );

+    fprintf (

+      OutFptr,

+      "FLASH_REGION_%s_SIZE          %*c= 0x%08X\n",

+      FBlock->Name,

+      COLUMN2_START - 40 - strlen (FBlock->Name),

+      ' ',

+      FBlock->Size

+      );

+    fprintf (

+      OutFptr,

+      "FLASH_REGION_%s_SIZE_BLOCKS   %*c= 0x%x\n",

+      FBlock->Name,

+      COLUMN2_START - 40 - strlen (FBlock->Name),

+      ' ',

+      (FBlock->Size)/(FDev->PBlocks->Size)

+      );      

+    //

+    // Create defines for any subregions

+    //

+    SubregionOffset = 0;

+    for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {

+      fprintf (

+        OutFptr,

+        "FLASH_REGION_%s_SUBREGION_%s_BASE     %*c= 0x%08X\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        FDev->BaseAddress + Offset + SubregionOffset

+        );

+      fprintf (

+        OutFptr,

+        "FLASH_REGION_%s_SUBREGION_%s_SIZE     %*c= 0x%08X\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        Subregion->Size

+        );

+      fprintf (

+        OutFptr,

+        "FLASH_REGION_%s_SUBREGION_%s_OFFSET   %*c= 0x%08X\n",

+        FBlock->Name,

+        Subregion->Name,

+        COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),

+        ' ',

+        Offset + SubregionOffset

+        );

+

+      SubregionOffset += Subregion->Size;

+    }

+

+    Offset += FBlock->Size;

+  }

+  //

+  // Close file

+  //

+  fprintf (OutFptr, "\n");

+  fclose (OutFptr);

+  return STATUS_SUCCESS;

+}

+

+

+/*++

+

+Routine Description:

+  The following buffer management routines are used to encapsulate functionality

+  for managing a growable data buffer.

+

+Arguments:

+  BUFFER_DATA     - structure that is used to maintain a data buffer

+

+Returns:

+  NA

+

+--*/

+static

+BUFFER_DATA *

+CreateBufferData (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Create a growable data buffer with default buffer length.

+

+Arguments:

+

+  None

+

+Returns:

+

+  NULL          - error occured during data buffer creation

+  Not NULL      - the pointer to the newly created data buffer

+

+--*/

+{

+  BUFFER_DATA *BD;

+  BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA));

+  if (BD == NULL) {

+    Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+    return NULL;

+  }

+

+  memset (BD, 0, sizeof (BUFFER_DATA));

+  BD->BufferStart = (char *) _malloc (BUFFER_SIZE);

+  if (BD->BufferStart == NULL) {

+    _free (BD);

+    Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+    return NULL;

+  }

+

+  BD->BufferEnd = BD->BufferStart + BUFFER_SIZE;

+  BD->BufferPos = BD->BufferStart;

+  return BD;

+}

+

+static

+BOOLEAN

+AddBufferDataByte (

+  BUFFER_DATA *Buffer,

+  char        Data

+  )

+/*++

+

+Routine Description:

+

+  Add a single byte to a growable data buffer, growing the buffer if required.

+

+Arguments:

+

+  Buffer  - pointer to the growable data buffer to add a single byte to

+  Data    - value of the single byte data to be added

+

+Returns:

+

+  TRUE    - the single byte data was successfully added

+  FALSE   - error occurred, the single byte data was not added

+

+--*/

+{

+  int   Size;

+  char  *NewBuffer;

+  //

+  // See if we have to grow the buffer

+  //

+  if (Buffer->BufferPos >= Buffer->BufferEnd) {

+    Size      = (int) Buffer->BufferEnd - (int) Buffer->BufferStart;

+    NewBuffer = (char *) _malloc (Size + BUFFER_SIZE);

+    if (NewBuffer == NULL) {

+      Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+      return FALSE;

+    }

+

+    memcpy (NewBuffer, Buffer->BufferStart, Size);

+    _free (Buffer->BufferStart);

+    Buffer->BufferStart = NewBuffer;

+    Buffer->BufferPos   = Buffer->BufferStart + Size;

+    Buffer->BufferEnd   = Buffer->BufferStart + Size + BUFFER_SIZE;

+  }

+

+  *Buffer->BufferPos = Data;

+  Buffer->BufferPos++;

+  return TRUE;

+}

+

+static

+void

+FreeBufferData (

+  BUFFER_DATA *Buffer,

+  BOOLEAN     FreeData

+  )

+/*++

+

+Routine Description:

+

+  Free memory used to manage a growable data buffer.

+

+Arguments:

+

+  Buffer    - pointer to the growable data buffer to be destructed

+  FreeData  - TRUE, free memory containing the buffered data

+              FALSE, do not free the buffered data memory

+

+Returns:

+

+  None

+

+--*/

+{

+  if (Buffer != NULL) {

+    if (FreeData && (Buffer->BufferStart != NULL)) {

+      _free (Buffer->BufferStart);

+    }

+

+    _free (Buffer);

+  }

+}

+

+static

+char *

+GetBufferData (

+  BUFFER_DATA *Buffer,

+  int         *BufferSize

+  )

+/*++

+

+Routine Description:

+

+  Return a pointer and size of the data in a growable data buffer.

+

+Arguments:

+

+  Buffer      - pointer to the growable data buffer

+  BufferSize  - size of the data in the growable data buffer

+

+Returns:

+

+  pointer of the data in the growable data buffer

+

+--*/

+{

+  *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart;

+  return Buffer->BufferStart;

+}

+

+STATUS

+FDDiscover (

+  char          *FDFileName,

+  unsigned int  BaseAddr

+  )

+/*++

+

+Routine Description:

+  Walk a binary image and see if you find anything that looks like a

+  firmware volume.

+

+Arguments:

+  FDFileName        - name of input FD image to parse

+  BaseAddr          - base address of input FD image

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_WARNING    - warnings, but no errors, were encountered

+  STATUS_ERROR      - errors were encountered

+

+NOTE:

+  This routine is used for debug purposes only.

+

+--*/

+{

+  FILE                        *InFptr;

+  long                        FileSize;

+  long                        Offset;

+  EFI_FIRMWARE_VOLUME_HEADER  FVHeader;

+  EFI_GUID

+    FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF };

+

+  if ((InFptr = fopen (FDFileName, "rb")) == NULL) {

+    Error (NULL, 0, 0, FDFileName, "failed to open file for reading");

+    return STATUS_ERROR;

+  }

+

+  fseek (InFptr, 0, SEEK_END);

+  FileSize = ftell (InFptr);

+  fseek (InFptr, 0, SEEK_SET);

+  Offset = 0;

+  while (Offset < FileSize) {

+    fseek (InFptr, Offset, SEEK_SET);

+    //

+    // Read the contents of the file, see if it's an FV header

+    //

+    if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) {

+      //

+      // Check version and GUID

+      //

+      if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) {

+        fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength);

+        if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) {

+          fprintf (stdout, "standard FFS file system\n");

+        } else {

+          fprintf (stdout, "non-standard FFS file system\n");

+        }

+      }

+    }

+

+    Offset += 16 * 1024;

+  }

+

+  fclose (InFptr);

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/FlashDefFile.h b/edk2/Tools/Source/TianoTools/FlashMap/FlashDefFile.h
new file mode 100644
index 0000000..1ffbfb1
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/FlashDefFile.h
@@ -0,0 +1,281 @@
+/*++

+

+Copyright (c)  2004 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  FlashDefFile.h

+

+Abstract:

+

+  Header file for flash management utility in the Intel Platform 

+  Innovation Framework for EFI build environment.

+

+--*/

+

+#ifndef _FLASH_DEF_FILE_H_

+#define _FLASH_DEF_FILE_H_

+

+#ifdef __cplusplus

+extern "C"

+{

+#endif

+

+void

+FDFConstructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+void

+FDFDestructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFParseFile (

+  char    *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FileName  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFCreateCIncludeFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FlashDeviceName - GC_TODO: add argument description

+  FileName        - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFCreateCFlashMapDataFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FlashDeviceName - GC_TODO: add argument description

+  FileName        - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFCreateAsmIncludeFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FlashDeviceName - GC_TODO: add argument description

+  FileName        - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFParseFile (

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FileName  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFCreateImage (

+  char      *FlashDeviceName,

+  char      *ImageName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FlashDeviceName - GC_TODO: add argument description

+  ImageName       - GC_TODO: add argument description

+  FileName        - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFCreateDscFile (

+  char      *FlashDeviceName,

+  char      *FileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FlashDeviceName - GC_TODO: add argument description

+  FileName        - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDFCreateSymbols (

+  char      *FlashDeviceName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FlashDeviceName - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+FDDiscover (

+  char          *FDFileName,

+  unsigned int  BaseAddr

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FDFileName  - GC_TODO: add argument description

+  BaseAddr    - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif // #ifndef _FLASH_DEF_FILE_H_

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/FlashMap.c b/edk2/Tools/Source/TianoTools/FlashMap/FlashMap.c
new file mode 100644
index 0000000..ce20157
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/FlashMap.c
@@ -0,0 +1,741 @@
+/*++

+

+Copyright (c)  2004-2005 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+Module Name:

+

+  FlashMap.c

+

+Abstract:

+

+  Utility for flash management in the Intel Platform Innovation Framework

+  for EFI build environment.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+#include <UefiBaseTypes.h>

+#include <Base.h>

+

+#include "EfiUtilityMsgs.h"

+#include "Microcode.h"

+#include "FlashDefFile.h"

+#include "Symbols.h"

+

+#define UTILITY_NAME  "FlashMap"

+

+typedef struct _STRING_LIST {

+  struct _STRING_LIST *Next;

+  char                *Str;

+} STRING_LIST;

+

+//

+// Keep our globals in one of these structures

+//

+static struct {

+  char          *CIncludeFileName;

+  char          *FlashDevice;

+  char          *FlashDeviceImage;

+  char          *MCIFileName;

+  char          *MCOFileName;

+  char          *ImageOutFileName;

+  char          *DscFileName;

+  char          *AsmIncludeFileName;

+  char          *FlashDefinitionFileName;

+  char          *StringReplaceInFileName;

+  char          *StringReplaceOutFileName;

+  char          *DiscoverFDImageName;

+  char          MicrocodePadByteValue;

+  unsigned int  MicrocodeAlignment;

+  STRING_LIST   *MCIFileNames;

+  STRING_LIST   *LastMCIFileNames;

+  unsigned int  BaseAddress;

+} mGlobals;

+

+#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF

+#define DEFAULT_MC_ALIGNMENT      16

+

+static

+STATUS

+ProcessCommandLine (

+  int     argc,

+  char    *argv[]

+  );

+

+static

+STATUS

+MergeMicrocodeFiles (

+  char            *OutFileName,

+  STRING_LIST     *FileNames,

+  unsigned int    Alignment,

+  char            PadByteValue

+  );

+

+static

+void

+Usage (

+  VOID

+  );

+

+int

+main (

+  int   argc,

+  char  *argv[]

+  )

+/*++

+

+Routine Description:

+  Parse the command line arguments and then call worker functions to do the work

+  

+Arguments:

+  argc      - number of elements in argv

+  argv      - array of command-line arguments

+

+Returns:

+  STATUS_SUCCESS    - no problems encountered while processing

+  STATUS_WARNING    - warnings, but no errors, were encountered while processing

+  STATUS_ERROR      - errors were encountered while processing

+  

+--*/

+{

+  STATUS  Status;

+

+  SetUtilityName (UTILITY_NAME);

+  Status = ProcessCommandLine (argc, argv);

+  if (Status != STATUS_SUCCESS) {

+    return Status;

+  }

+  //

+  // Check for discovery of an FD (command line option)

+  //

+  if (mGlobals.DiscoverFDImageName != NULL) {

+    Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress);

+    goto Done;

+  }

+  //

+  // If they're doing microcode file parsing, then do that

+  //

+  if (mGlobals.MCIFileName != NULL) {

+    MicrocodeConstructor ();

+    MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName);

+    MicrocodeDestructor ();

+  }

+  //

+  // If they're doing microcode file merging, then do that now

+  //

+  if (mGlobals.MCIFileNames != NULL) {

+    MergeMicrocodeFiles (

+      mGlobals.MCOFileName,

+      mGlobals.MCIFileNames,

+      mGlobals.MicrocodeAlignment,

+      mGlobals.MicrocodePadByteValue

+      );

+  }

+  //

+  // If using a flash definition file, then process that and return

+  //

+  if (mGlobals.FlashDefinitionFileName != NULL) {

+    FDFConstructor ();

+    SymbolsConstructor ();

+    Status = FDFParseFile (mGlobals.FlashDefinitionFileName);

+    if (GetUtilityStatus () != STATUS_ERROR) {

+      //

+      // If they want us to do a string-replace on a file, then add the symbol definitions to

+      // the symbol table, and then do the string replace.

+      //

+      if (mGlobals.StringReplaceInFileName != NULL) {

+        Status  = FDFCreateSymbols (mGlobals.FlashDevice);

+        Status  = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName);

+      }

+      //

+      // If they want us to create a .h defines file or .c flashmap data file, then do so now

+      //

+      if (mGlobals.CIncludeFileName != NULL) {

+        Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName);

+      }

+      if (mGlobals.AsmIncludeFileName != NULL) {

+        Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName);

+      }

+      //

+      // If they want us to create an image, do that now

+      //

+      if (mGlobals.ImageOutFileName != NULL) {

+        Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName);

+      }

+      //

+      // If they want to create an output DSC file, do that now

+      //

+      if (mGlobals.DscFileName != NULL) {

+        Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName);

+      }

+    }

+    SymbolsDestructor ();

+    FDFDestructor ();

+  }

+Done:

+  //

+  // Free up memory

+  //

+  while (mGlobals.MCIFileNames != NULL) {

+    mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next;

+    _free (mGlobals.MCIFileNames);

+    mGlobals.MCIFileNames = mGlobals.LastMCIFileNames;

+  }

+  return GetUtilityStatus ();

+}

+

+static

+STATUS

+MergeMicrocodeFiles (

+  char            *OutFileName,

+  STRING_LIST     *FileNames,

+  unsigned int    Alignment,

+  char            PadByteValue

+  )

+/*++

+

+Routine Description:

+

+  Merge binary microcode files into a single file, taking into consideration

+  the alignment and pad value.

+

+Arguments:

+

+  OutFileName     - name of the output file to create

+  FileNames       - linked list of input microcode files to merge

+  Alignment       - alignment for each microcode file in the output image

+  PadByteValue    - value to use when padding to meet alignment requirements

+

+Returns:

+

+  STATUS_SUCCESS  - merge completed successfully or with acceptable warnings

+  STATUS_ERROR    - merge failed, output file not created

+

+--*/

+{

+  long    FileSize;

+  long    TotalFileSize;

+  FILE    *InFptr;

+  FILE    *OutFptr;

+  char    *Buffer;

+  STATUS  Status;

+

+  //

+  // Open the output file

+  //

+  if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+  //

+  // Walk the list of files

+  //

+  Status        = STATUS_ERROR;

+  Buffer        = NULL;

+  InFptr        = NULL;

+  TotalFileSize = 0;

+  while (FileNames != NULL) {

+    //

+    // Open the file, determine the size, then read it in and write

+    // it back out.

+    //

+    if ((InFptr = fopen (FileNames->Str, "rb")) == NULL) {

+      Error (NULL, 0, 0, FileNames->Str, "failed to open input file for reading");

+      goto Done;

+    }

+    fseek (InFptr, 0, SEEK_END);

+    FileSize = ftell (InFptr);

+    fseek (InFptr, 0, SEEK_SET);

+    if (FileSize != 0) {

+      Buffer = (char *) _malloc (FileSize);

+      if (Buffer == NULL) {

+        Error (NULL, 0, 0, "memory allocation failure", NULL);

+        goto Done;

+      }

+      if (fread (Buffer, FileSize, 1, InFptr) != 1) {

+        Error (NULL, 0, 0, FileNames->Str, "failed to read file contents");

+        goto Done;

+      }

+      //

+      // Align

+      //

+      if (Alignment != 0) {

+        while ((TotalFileSize % Alignment) != 0) {

+          if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) {

+            Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file");

+            goto Done;

+          }

+          TotalFileSize++;

+        }

+      }

+      TotalFileSize += FileSize;

+      if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, OutFileName, "failed to write to output file");

+        goto Done;

+      }

+      _free (Buffer);

+      Buffer = NULL;

+    } else {

+      Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered");

+    }

+    fclose (InFptr);

+    InFptr    = NULL;

+    FileNames = FileNames->Next;

+  }

+  Status = STATUS_SUCCESS;

+Done:

+  fclose (OutFptr);

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+  if (Buffer != NULL) {

+    _free (Buffer);

+  }

+  if (Status == STATUS_ERROR) {

+    remove (OutFileName);

+  }

+  return Status;

+}

+

+static

+STATUS

+ProcessCommandLine (

+  int   argc,

+  char  *argv[]

+  )

+/*++

+

+Routine Description:

+  Process the command line arguments

+  

+Arguments:

+  argc   - Standard C entry point arguments

+  argv[] - Standard C entry point arguments

+

+Returns:

+  STATUS_SUCCESS    - no problems encountered while processing

+  STATUS_WARNING    - warnings, but no errors, were encountered while processing

+  STATUS_ERROR      - errors were encountered while processing

+  

+--*/

+{

+  int           ThingsToDo;

+  unsigned int  Temp;

+  STRING_LIST   *Str;

+  //

+  // Skip program name arg, process others

+  //

+  argc--;

+  argv++;

+  if (argc == 0) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Clear out our globals, then start walking the arguments

+  //

+  memset ((void *) &mGlobals, 0, sizeof (mGlobals));

+  mGlobals.MicrocodePadByteValue  = DEFAULT_MC_PAD_BYTE_VALUE;

+  mGlobals.MicrocodeAlignment     = DEFAULT_MC_ALIGNMENT;

+  ThingsToDo                      = 0;

+  while (argc > 0) {

+    if (strcmp (argv[0], "-?") == 0) {

+      Usage ();

+      return STATUS_ERROR;

+    } else if (strcmp (argv[0], "-hfile") == 0) {

+      //

+      // -hfile FileName

+      //

+      // Used to specify an output C #include file to create that contains

+      // #define statements for all the flashmap region offsets and sizes.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an output file name");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.CIncludeFileName = argv[0];

+      ThingsToDo++;

+    } else if (strcmp (argv[0], "-flashdevice") == 0) {

+      //

+      // -flashdevice FLASH_DEVICE_NAME

+      //

+      // Used to select which flash device definition to operate on.

+      // Check for additional argument

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires a flash device name to use");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.FlashDevice = argv[0];

+    } else if (strcmp (argv[0], "-mco") == 0) {

+      //

+      // -mco OutFileName

+      //

+      // Used to specify a microcode output binary file to create.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.MCOFileName = argv[0];

+      ThingsToDo++;

+    } else if (strcmp (argv[0], "-asmincfile") == 0) {

+      //

+      // -asmincfile FileName

+      //

+      // Used to specify the name of the output assembly include file that contains

+      // equates for the flash region addresses and sizes.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.AsmIncludeFileName = argv[0];

+      ThingsToDo++;

+    } else if (strcmp (argv[0], "-mci") == 0) {

+      //

+      // -mci FileName

+      //

+      // Used to specify an input microcode text file to parse.

+      // Check for additional argument

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.MCIFileName = argv[0];

+    } else if (strcmp (argv[0], "-flashdeviceimage") == 0) {

+      //

+      // -flashdeviceimage FlashDeviceImage

+      //

+      // Used to specify which flash device image definition from the input flash definition file

+      // to create.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.FlashDeviceImage = argv[0];

+    } else if (strcmp (argv[0], "-imageout") == 0) {

+      //

+      // -imageout FileName

+      //

+      // Used to specify the name of the output FD image file to create.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an output image filename to create");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.ImageOutFileName = argv[0];

+      ThingsToDo++;

+    } else if (strcmp (argv[0], "-dsc") == 0) {

+      //

+      // -dsc FileName

+      //

+      // Used to specify the name of the output DSC file to create.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.DscFileName = argv[0];

+      ThingsToDo++;

+    } else if (strcmp (argv[0], "-fdf") == 0) {

+      //

+      // -fdf FileName

+      //

+      // Used to specify the name of the input flash definition file.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.FlashDefinitionFileName = argv[0];

+    } else if (strcmp (argv[0], "-discover") == 0) {

+      //

+      // -discover FDFileName

+      //

+      // Debug functionality used to scan an existing FD image, trying to find

+      // firmware volumes at 64K boundaries.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an input FD image file name");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.DiscoverFDImageName = argv[0];

+      ThingsToDo++;

+    } else if (strcmp (argv[0], "-baseaddr") == 0) {

+      //

+      // -baseaddr Addr

+      //

+      // Used to specify a base address when doing a discover of an FD image.

+      // Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires a base address");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      if (tolower (argv[0][1]) == 'x') {

+        sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress);

+      } else {

+        sscanf (argv[0], "%d", &mGlobals.BaseAddress);

+      }

+    } else if (strcmp (argv[0], "-padvalue") == 0) {

+      //

+      // -padvalue Value

+      //

+      // Used to specify the value to pad with when aligning data while

+      // creating an FD image. Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires a byte value");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      if (tolower (argv[0][1]) == 'x') {

+        sscanf (argv[0] + 2, "%x", &Temp);

+        mGlobals.MicrocodePadByteValue = (char) Temp;

+      } else {

+        sscanf (argv[0], "%d", &Temp);

+        mGlobals.MicrocodePadByteValue = (char) Temp;

+      }

+    } else if (strcmp (argv[0], "-align") == 0) {

+      //

+      // -align Alignment

+      //

+      // Used to specify how each data file is aligned in the region

+      // when creating an FD image. Check for additional argument.

+      //

+      if (argc < 2) {

+        Error (NULL, 0, 0, argv[0], "option requires an alignment");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      if (tolower (argv[0][1]) == 'x') {

+        sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment);

+      } else {

+        sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment);

+      }

+    } else if (strcmp (argv[0], "-mcmerge") == 0) {

+      //

+      // -mcmerge FileName(s)

+      //

+      // Used to concatenate multiple microde binary files. Can specify

+      // multiple file names with the one -mcmerge flag. Check for additional argument.

+      //

+      if ((argc < 2) || (argv[1][0] == '-')) {

+        Error (NULL, 0, 0, argv[0], "option requires one or more input file names");

+        return STATUS_ERROR;

+      }

+      //

+      // Take input files until another option or end of list

+      //

+      ThingsToDo++;

+      while ((argc > 1) && (argv[1][0] != '-')) {

+        Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST));

+        if (Str == NULL) {

+          Error (NULL, 0, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+        memset (Str, 0, sizeof (STRING_LIST));

+        Str->Str = argv[1];

+        if (mGlobals.MCIFileNames == NULL) {

+          mGlobals.MCIFileNames = Str;

+        } else {

+          mGlobals.LastMCIFileNames->Next = Str;

+        }

+        mGlobals.LastMCIFileNames = Str;

+        argc--;

+        argv++;

+      }

+    } else if (strcmp (argv[0], "-strsub") == 0) {

+      //

+      // -strsub SrcFile DestFile

+      //

+      // Used to perform string substitutions on a file, writing the result to a new

+      // file. Check for two additional arguments.

+      //

+      if (argc < 3) {

+        Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution");

+        return STATUS_ERROR;

+      }

+      argc--;

+      argv++;

+      mGlobals.StringReplaceInFileName = argv[0];

+      argc--;

+      argv++;

+      mGlobals.StringReplaceOutFileName = argv[0];

+      ThingsToDo++;

+    } else {

+      Error (NULL, 0, 0, argv[0], "invalid option");

+      return STATUS_ERROR;

+    }

+    argc--;

+    argv++;

+  }

+  //

+  // If no outputs requested, then report an error

+  //

+  if (ThingsToDo == 0) {

+    Error (NULL, 0, 0, "nothing to do", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // If they want an asm file, #include file, or C file to be created, then they have to specify a

+  // flash device name and flash definition file name.

+  //

+  if ((mGlobals.CIncludeFileName != NULL) &&

+      ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {

+    Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL);

+    return STATUS_ERROR;

+  }

+  if ((mGlobals.AsmIncludeFileName != NULL) &&

+      ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {

+    Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // If they want a dsc file to be created, then they have to specify a

+  // flash device name and a flash definition file name

+  //

+  if (mGlobals.DscFileName != NULL) {

+    if (mGlobals.FlashDevice == NULL) {

+      Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL);

+      return STATUS_ERROR;

+    }

+    if (mGlobals.FlashDefinitionFileName == NULL) {

+      Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL);

+      return STATUS_ERROR;

+    }

+  }

+  //

+  // If they specified an output microcode file name, then they have to specify an input

+  // file name, and vice versa.

+  //

+  if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) {

+    Error (NULL, 0, 0, "must specify output microcode file name", NULL);

+    return STATUS_ERROR;

+  }

+  if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) {

+    Error (NULL, 0, 0, "must specify input microcode file name", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // If doing merge, then have to specify output file name

+  //

+  if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) {

+    Error (NULL, 0, 0, "must specify output microcode file name", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // If they want an output image to be created, then they have to specify

+  // the flash device and the flash device image to use.

+  //

+  if (mGlobals.ImageOutFileName != NULL) {

+    if (mGlobals.FlashDevice == NULL) {

+      Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL);

+      return STATUS_ERROR;

+    }

+    if (mGlobals.FlashDeviceImage == NULL) {

+      Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL);

+      return STATUS_ERROR;

+    }

+    if (mGlobals.FlashDefinitionFileName == NULL) {

+      Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL);

+      return STATUS_ERROR;

+    }

+  }

+  return STATUS_SUCCESS;

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Print utility command line help

+  

+Arguments:

+  None

+

+Returns:

+  NA

+

+--*/

+{

+  int   i;

+  char  *Msg[] = {

+    "Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice",

+    "                 -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile",

+    "                 -discover FDImage -dsc DscFile -asmincfile AsmIncFile",

+    "                 -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile",

+    "                 -baseaddr BaseAddr -align Alignment -padvalue PadValue",

+    "                 -mcmerge MCIFile(s)",

+    "  where",

+    "    FlashDefFile     - input Flash Definition File",

+    "    FlashDevice      - flash device to use (from flash definition file)",

+    "    FlashDeviceImage - flash device image to use (from flash definition file)",

+    "    MCIFile          - input microcode file to parse",

+    "    MCOFile          - output binary microcode image to create from MCIFile",

+    "    HFile            - output #include file to create",

+    "    FDImage          - name of input FDImage file to scan",

+    "    ImageOutFile     - output image file to create",

+    "    DscFile          - output DSC file to create",

+    "    AsmIncFile       - output ASM include file to create",

+    "    InStrFile        - input file to replace symbol names, writing result to OutStrFile",

+    "    BaseAddr         - base address of FDImage (used with -discover)",

+    "    Alignment        - alignment to use when merging microcode binaries",

+    "    PadValue         - byte value to use as pad value when aligning microcode binaries",

+    "    MCIFile(s)       - one or more microcode binary files to merge/concatenate",

+    "",

+    NULL

+  };

+  for (i = 0; Msg[i] != NULL; i++) {

+    fprintf (stdout, "%s\n", Msg[i]);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/Makefile b/edk2/Tools/Source/TianoTools/FlashMap/Makefile
new file mode 100644
index 0000000..6b6d011
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/Makefile
@@ -0,0 +1,81 @@
+#/*++

+#  

+#  Copyright (c) 2004 Intel Corporation. All rights reserved

+#  This software and associated documentation (if any) is furnished

+#  under a license and may only be used or copied in accordance

+#  with the terms of the license. Except as permitted by such

+#  license, no part of this software or documentation may be

+#  reproduced, stored in a retrieval system, or transmitted in any

+#  form or by any means without the express written consent of

+#  Intel Corporation.

+#  

+#  

+#  Module Name:

+#  

+#    Makefile

+#  

+#  Abstract:

+#  

+#    makefile for building the FlashMap utility

+#    

+#--*/

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+

+!INCLUDE PlatformTools.env

+

+INCLUDE_PATHS = -I $(TIANO_TOOLS_SOURCE)\Common

+

+#

+# Target specific information

+#

+TARGET_NAME         = FlashMap

+TARGET_SRC_DIR      = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\FlashMap.exe

+LIBS                = $(LIBS) "$(TIANO_TOOLS_OUTPUT)\Common.lib"

+

+#

+# Build targets

+#

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\FlashMap.obj  \

+            $(TIANO_TOOLS_OUTPUT)\FlashDefFile.obj \

+            $(TIANO_TOOLS_OUTPUT)\Symbols.obj \

+            $(TIANO_TOOLS_OUTPUT)\Microcode.obj 

+            

+#            $(TIANO_TOOLS_OUTPUT)\TrackMallocFree.obj 

+ 

+#C_FLAGS  = $(C_FLAGS) /D TRACK_MALLOC_FREE

+C_FLAGS   = $(C_FLAGS) /D _malloc=malloc /D _free=free

+           

+#

+# Compile each source file

+#

+$(TIANO_TOOLS_OUTPUT)\FlashMap.obj : $(TARGET_SRC_DIR)\FlashMap.c $(TARGET_SRC_DIR)\Symbols.h $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(INCLUDE_PATHS) $(TARGET_SRC_DIR)\FlashMap.c /Fo$@

+

+$(TIANO_TOOLS_OUTPUT)\Symbols.obj : $(TARGET_SRC_DIR)\Symbols.c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(INCLUDE_PATHS) $(TARGET_SRC_DIR)\Symbols.c /Fo$@

+

+$(TIANO_TOOLS_OUTPUT)\Microcode.obj : $(TARGET_SRC_DIR)\Microcode.c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\Microcode.c /Fo$@

+

+$(TIANO_TOOLS_OUTPUT)\FlashDefFile.obj : $(TARGET_SRC_DIR)\FlashDefFile.c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\FlashDefFile.c /Fo$@

+

+$(TIANO_TOOLS_OUTPUT)\TrackMallocFree.obj : $(TARGET_SRC_DIR)\TrackMallocFree.c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\TrackMallocFree.c /Fo$@

+

+#

+# Link the object files together to create the final executable

+#

+$(TARGET_EXE) : $(OBJECTS) $(LIBS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

+

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/Microcode.c b/edk2/Tools/Source/TianoTools/FlashMap/Microcode.c
new file mode 100644
index 0000000..f5bea09
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/Microcode.c
@@ -0,0 +1,304 @@
+/*++

+

+Copyright (c)  2004 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+Module Name:

+

+  Microcode.c

+

+Abstract:

+

+  Utility for working with microcode patch files in the Intel 

+  Platform Innovation Framework for EFI build environment.

+

+--*/

+

+#include <stdio.h>

+#include <string.h> // for memset()

+#include <ctype.h>

+#include <stdlib.h> // for malloc()

+

+#include "EfiUtilityMsgs.h"

+#include "Microcode.h"

+

+#define MAX_LINE_LEN  256

+

+//

+// Structure definition for a microcode header

+//

+typedef struct {

+  unsigned int  HeaderVersion;

+  unsigned int  PatchId;

+  unsigned int  Date;

+  unsigned int  CpuId;

+  unsigned int  Checksum;

+  unsigned int  LoaderVersion;

+  unsigned int  PlatformId;

+  unsigned int  DataSize;   // if 0, then TotalSize = 2048, and TotalSize field is invalid

+  unsigned int  TotalSize;  // number of bytes

+  unsigned int  Reserved[3];

+} MICROCODE_IMAGE_HEADER;

+

+static

+STATUS

+MicrocodeReadData (

+  FILE          *InFptr,

+  unsigned int  *Data

+  );

+

+void

+MicrocodeConstructor (

+  void

+  )

+/*++

+

+Routine Description:

+

+  Constructor of module Microcode

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+}

+

+void

+MicrocodeDestructor (

+  void

+  )

+/*++

+

+Routine Description:

+

+  Destructor of module Microcode

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+}

+

+static

+STATUS

+MicrocodeReadData (

+  FILE          *InFptr,

+  unsigned int  *Data

+  )

+/*++

+

+Routine Description:

+  Read a 32-bit microcode data value from a text file and convert to raw binary form.

+

+Arguments:

+  InFptr    - file pointer to input text file

+  Data      - pointer to where to return the data parsed

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings, Data contains valid information

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  char  Line[MAX_LINE_LEN];

+  char  *cptr;

+

+  Line[MAX_LINE_LEN - 1]  = 0;

+  *Data                   = 0;

+  if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {

+    return STATUS_ERROR;

+  }

+  //

+  // If it was a binary file, then it may have overwritten our null terminator

+  //

+  if (Line[MAX_LINE_LEN - 1] != 0) {

+    return STATUS_ERROR;

+  }

+  //

+  // Look for

+  // dd 000000001h ; comment

+  // dd XXXXXXXX

+  // DD  XXXXXXXXX

+  //  DD XXXXXXXXX

+  //

+  for (cptr = Line; *cptr && isspace(*cptr); cptr++) {

+  }

+  if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {

+    //

+    // Skip blanks and look for a hex digit

+    //

+    cptr += 3;

+    for (; *cptr && isspace(*cptr); cptr++) {

+    }

+    if (isxdigit (*cptr)) {

+      if (sscanf (cptr, "%X", Data) != 1) {

+        return STATUS_ERROR;

+      }

+    }

+    return STATUS_SUCCESS;

+  }

+  return STATUS_ERROR;

+}

+

+STATUS

+MicrocodeParseFile (

+  char  *InFileName,

+  char  *OutFileName

+  )

+/*++

+

+Routine Description:

+  Parse a microcode text file, and write the binary results to an output file.

+

+Arguments:

+  InFileName  - input text file to parse

+  OutFileName - output file to write raw binary data from parsed input file

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_ERROR      - errors were encountered

+

+--*/

+{

+  FILE                    *InFptr;

+  FILE                    *OutFptr;

+  STATUS                  Status;

+  MICROCODE_IMAGE_HEADER  *Header;

+  unsigned int            Size;

+  unsigned int            Size2;

+  unsigned int            Data;

+  unsigned int            Checksum;

+  char                    *Buffer;

+  char                    *Ptr;

+  unsigned int            TotalSize;

+

+  Status  = STATUS_ERROR;

+  InFptr  = NULL;

+  OutFptr = NULL;

+  Buffer  = NULL;

+  //

+  // Open the input text file

+  //

+  if ((InFptr = fopen (InFileName, "r")) == NULL) {

+    Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Make two passes on the input file. The first pass is to determine how

+  // much data is in the file so we can allocate a working buffer. Then

+  // we'll allocate a buffer and re-read the file into the buffer for processing.

+  //

+  Size = 0;

+  do {

+    Status = MicrocodeReadData (InFptr, &Data);

+    if (Status == STATUS_SUCCESS) {

+      Size += sizeof (Data);

+    }

+  } while (Status == STATUS_SUCCESS);

+  //

+  // Error if no data.

+  //

+  if (Size == 0) {

+    Error (NULL, 0, 0, InFileName, "no parse-able data found in file");

+    goto Done;

+  }

+  if (Size < sizeof (MICROCODE_IMAGE_HEADER)) {

+    Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header");

+    goto Done;

+  }

+  //

+  // Allocate a buffer for the data

+  //

+  Buffer = (char *) _malloc (Size);

+  if (Buffer == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    goto Done;

+  }

+  //

+  // Re-read the file, storing the data into our buffer

+  //

+  fseek (InFptr, 0, SEEK_SET);

+  Ptr = Buffer;

+  do {

+    Status = MicrocodeReadData (InFptr, &Data);

+    if (Status == STATUS_SUCCESS) {

+      *(unsigned int *) Ptr = Data;

+      Ptr += sizeof (Data);

+    }

+  } while (Status == STATUS_SUCCESS);

+  //

+  // Can't do much checking on the header because, per the spec, the

+  // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,

+  // and the TotalSize field is invalid (actually missing). Thus we can't

+  // even verify the Reserved fields are 0.

+  //

+  Header = (MICROCODE_IMAGE_HEADER *) Buffer;

+  if (Header->DataSize == 0) {

+    TotalSize = 2048;

+  } else {

+    TotalSize = Header->TotalSize;

+  }

+  if (TotalSize != Size) {

+    Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize);

+    goto Done;

+  }

+  //

+  // Checksum the contents

+  //

+  Ptr       = Buffer;

+  Checksum  = 0;

+  Size2     = 0;

+  while (Size2 < Size) {

+    Checksum += *(unsigned int *) Ptr;

+    Ptr += 4;

+    Size2 += 4;

+  }

+  if (Checksum != 0) {

+    Error (NULL, 0, 0, InFileName, "checksum failed on file contents");

+    goto Done;

+  }

+  //

+  // Open the output file and write the buffer contents

+  //

+  if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing");

+    goto Done;

+  }

+  if (fwrite (Buffer, Size, 1, OutFptr) != 1) {

+    Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file");

+    goto Done;

+  }

+  Status = STATUS_SUCCESS;

+Done:

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+    if (Status == STATUS_ERROR) {

+      remove (OutFileName);

+    }

+  }

+  return Status;

+}

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/Microcode.h b/edk2/Tools/Source/TianoTools/FlashMap/Microcode.h
new file mode 100644
index 0000000..5f5a13e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/Microcode.h
@@ -0,0 +1,87 @@
+/*++

+

+Copyright (c)  2004 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+Module Name:

+

+  Microcode.h

+

+Abstract:

+

+  Header file for flash management utility in the Intel Platform 

+  Innovation Framework for EFI build environment.

+

+--*/

+

+#ifndef _MICROCODE_H_

+#define _MICROCODE_H_

+

+void

+MicrocodeConstructor (

+  void

+  );

+/*++

+

+Routine Description:

+

+  Constructor of module Microcode

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+

+void

+MicrocodeDestructor (

+  void

+  );

+/*++

+

+Routine Description:

+

+  Destructor of module Microcode

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+

+STATUS

+MicrocodeParseFile (

+  char  *InFileName,

+  char  *OutFileName

+  );

+/*++

+

+Routine Description:

+  Parse a microcode text file, and write the binary results to an output file.

+

+Arguments:

+  InFileName  - input text file to parse

+  OutFileName - output file to write raw binary data from parsed input file

+

+Returns:

+  STATUS_SUCCESS    - no errors or warnings

+  STATUS_ERROR      - errors were encountered

+

+--*/

+

+

+#endif // #ifndef _MICROCODE_H_

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/Symbols.c b/edk2/Tools/Source/TianoTools/FlashMap/Symbols.c
new file mode 100644
index 0000000..b83f150
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/Symbols.c
@@ -0,0 +1,650 @@
+/*++

+

+Copyright (c)  2004 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  Symbol.c

+

+Abstract:

+

+  Class-like implementation for a symbol table.

+

+--*/

+

+// GC_TODO: fix comment to set correct module name: Symbols.c

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+//

+// for isspace()

+//

+#include <ctype.h>

+

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include <CommonLib.h>

+

+#include "EfiUtilityMsgs.h"

+#include "Symbols.h"

+

+#define MAX_LINE_LEN  512

+

+//

+// Linked list to keep track of all symbols

+//

+typedef struct _SYMBOL {

+  struct _SYMBOL  *Next;

+  int             Type;

+  char            *Name;

+  char            *Value;

+} SYMBOL;

+

+static

+SYMBOL        *

+FreeSymbols (

+  SYMBOL *Syms

+  );

+

+static

+int

+ExpandMacros (

+  char  *SourceLine,

+  char  *DestLine,

+  int   LineLen

+  );

+

+static SYMBOL *mSymbolTable = NULL;

+

+void

+SymbolsConstructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  SymbolsDestructor ();

+}

+

+void

+SymbolsDestructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  mSymbolTable = FreeSymbols (mSymbolTable);

+}

+

+char *

+GetSymbolValue (

+  char *SymbolName

+  )

+/*++

+

+Routine Description:

+  

+  Look up a symbol in our symbol table.

+

+Arguments:

+

+  SymbolName

+

+Returns:

+

+  Pointer to the value of the symbol if found

+  NULL if the symbol is not found

+

+--*/

+// GC_TODO:    SymbolName - add argument and description to function comment

+{

+  SYMBOL  *Symbol;

+  //

+  // Walk the symbol table

+  //

+  Symbol = mSymbolTable;

+  while (Symbol) {

+    if (stricmp (SymbolName, Symbol->Name) == 0) {

+      return Symbol->Value;

+    }

+

+    Symbol = Symbol->Next;

+  }

+

+  return NULL;

+}

+

+int

+SymbolAdd (

+  char    *Name,

+  char    *Value,

+  int     Mode

+  )

+/*++

+

+Routine Description:

+  

+  Add a symbol name/value to the symbol table

+

+Arguments:

+

+  Name  - name of symbol to add

+  Value - value of symbol to add

+  Mode  - currrently unused

+

+Returns:

+

+  Length of symbol added.

+

+Notes:

+  If Value == NULL, then this routine will assume that the Name field

+  looks something like "MySymName = MySymValue", and will try to parse

+  it that way and add the symbol name/pair from the string.

+

+--*/

+{

+  SYMBOL  *Symbol;

+

+  SYMBOL  *NewSymbol;

+  int     Len;

+  char    *Start;

+  char    *Cptr;

+  char    CSave;

+  char    *SaveCptr;

+

+  Len       = 0;

+  SaveCptr  = NULL;

+  CSave     = 0;

+  //

+  // If value pointer is null, then they passed us a line something like:

+  //    varname = value, or simply var =

+  //

+  if (Value == NULL) {

+    Start = Name;

+    while (*Name && isspace (*Name)) {

+      Name++;

+    }

+

+    if (Name == NULL) {

+      return -1;

+    }

+    //

+    // Find the end of the name. Either space or a '='.

+    //

+    for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++)

+      ;

+    if (Value == NULL) {

+      return -1;

+    }

+    //

+    // Look for the '='

+    //

+    Cptr = Value;

+    while (*Value && (*Value != '=')) {

+      Value++;

+    }

+

+    if (Value == NULL) {

+      return -1;

+    }

+    //

+    // Now truncate the name

+    //

+    *Cptr = 0;

+    //

+    // Skip over the = and then any spaces

+    //

+    Value++;

+    while (*Value && isspace (*Value)) {

+      Value++;

+

+    }

+    //

+    // Find end of string, checking for quoted string

+    //

+    if (*Value == '\"') {

+      Value++;

+      for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++)

+        ;

+    } else {

+      for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++)

+        ;

+    }

+    //

+    // Null terminate the value string

+    //

+    CSave     = *Cptr;

+    SaveCptr  = Cptr;

+    *Cptr     = 0;

+    Len       = (int) (Cptr - Start);

+  }

+  //

+  // We now have a symbol name and a value. Look for an existing variable

+  // and overwrite it.

+  //

+  Symbol = mSymbolTable;

+  while (Symbol) {

+    //

+    // Check for symbol name match

+    //

+    if (stricmp (Name, Symbol->Name) == 0) {

+      _free (Symbol->Value);

+      Symbol->Value = (char *) _malloc (strlen (Value) + 1);

+      if (Symbol->Value == NULL) {

+        Error (NULL, 0, 0, NULL, "failed to allocate memory");

+        return -1;

+      }

+

+      strcpy (Symbol->Value, Value);

+      //

+      // If value == "NULL", then make it a 0-length string

+      //

+      if (stricmp (Symbol->Value, "NULL") == 0) {

+        Symbol->Value[0] = 0;

+      }

+

+      return Len;

+    }

+

+    Symbol = Symbol->Next;

+  }

+  //

+  // Does not exist, create a new one

+  //

+  NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL));

+  if (NewSymbol == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation failure");

+    return -1;

+  }

+

+  memset ((char *) NewSymbol, 0, sizeof (SYMBOL));

+  NewSymbol->Name = (char *) _malloc (strlen (Name) + 1);

+  if (NewSymbol->Name == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation failure");

+    _free (NewSymbol);

+    return -1;

+  }

+

+  NewSymbol->Value = (char *) _malloc (strlen (Value) + 1);

+  if (NewSymbol->Value == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation failure");

+    _free (NewSymbol->Name);

+    _free (NewSymbol);

+    return -1;

+  }

+

+  strcpy (NewSymbol->Name, Name);

+  strcpy (NewSymbol->Value, Value);

+  //

+  // Remove trailing spaces

+  //

+  Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1;

+  while (Cptr > NewSymbol->Value) {

+    if (isspace (*Cptr)) {

+      *Cptr = 0;

+      Cptr--;

+    } else {

+      break;

+    }

+  }

+  //

+  // Add it to the head of the list.

+  //

+  NewSymbol->Next = mSymbolTable;

+  mSymbolTable    = NewSymbol;

+  //

+  // If value == "NULL", then make it a 0-length string

+  //

+  if (stricmp (NewSymbol->Value, "NULL") == 0) {

+    NewSymbol->Value[0] = 0;

+  }

+  //

+  // Restore the terminator we inserted if they passed in var=value

+  //

+  if (SaveCptr != NULL) {

+    *SaveCptr = CSave;

+  }

+  _free (NewSymbol->Value);

+  _free (NewSymbol->Name);

+  _free (NewSymbol);

+  return Len;

+}

+

+static

+STATUS

+RemoveSymbol (

+  char *Name,

+  char SymbolType

+  )

+/*++

+

+Routine Description:

+  

+  Remove a symbol name/value from the symbol table

+

+Arguments:

+

+  Name  - name of symbol to remove

+  SymbolType - type of symbol to remove

+

+Returns:

+

+  STATUS_SUCCESS - matching symbol found and removed

+  STATUS_ERROR   - matching symbol not found in symbol table

+

+--*/

+{

+  SYMBOL  *Symbol;

+

+  SYMBOL  *PrevSymbol;

+

+  PrevSymbol  = NULL;

+  Symbol      = mSymbolTable;

+  //

+  // Walk the linked list of symbols in the symbol table looking

+  // for a match of both symbol name and type.

+  //

+  while (Symbol) {

+    if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) {

+      //

+      // If the symbol has a value associated with it, free the memory

+      // allocated for the value.

+      // Then free the memory allocated for the symbols string name.

+      //

+      if (Symbol->Value) {

+        _free (Symbol->Value);

+      }

+

+      _free (Symbol->Name);

+      //

+      // Link the previous symbol to the next symbol to effectively

+      // remove this symbol from the linked list.

+      //

+      if (PrevSymbol) {

+        PrevSymbol->Next = Symbol->Next;

+      } else {

+        mSymbolTable = Symbol->Next;

+      }

+

+      _free (Symbol);

+      return STATUS_SUCCESS;

+    }

+

+    PrevSymbol  = Symbol;

+    Symbol      = Symbol->Next;

+  }

+

+  return STATUS_WARNING;

+}

+

+static

+SYMBOL *

+FreeSymbols (

+  SYMBOL *Syms

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  Syms  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  SYMBOL  *Next;

+  while (Syms) {

+    if (Syms->Name != NULL) {

+      _free (Syms->Name);

+    }

+

+    if (Syms->Value != NULL) {

+      _free (Syms->Value);

+    }

+

+    Next = Syms->Next;

+    _free (Syms);

+    Syms = Next;

+  }

+

+  return Syms;

+}

+

+static

+int

+ExpandMacros (

+  char  *SourceLine,

+  char  *DestLine,

+  int   LineLen

+  )

+/*++

+

+Routine Description:

+  

+  Given a line of text, replace all variables of format $(NAME) with values

+  from our symbol table.

+

+Arguments:

+

+  SourceLine    - input line of text to do symbol replacements on

+  DestLine      - on output, SourceLine with symbols replaced

+  LineLen       - length of DestLine, so we don't exceed its allocated length

+

+Returns:

+

+  STATUS_SUCCESS - no problems encountered

+  STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine

+  STATUS_ERROR   - memory allocation failure

+

+--*/

+{

+  static int  NestDepth = 0;

+  char        *FromPtr;

+  char        *ToPtr;

+  char        *SaveStart;

+  char        *Cptr;

+  char        *value;

+  int         Expanded;

+  int         ExpandedCount;

+  INT8        *LocalDestLine;

+  STATUS      Status;

+  int         LocalLineLen;

+

+  NestDepth++;

+  Status        = STATUS_SUCCESS;

+  LocalDestLine = (char *) _malloc (LineLen);

+  if (LocalDestLine == NULL) {

+    Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);

+    return STATUS_ERROR;

+  }

+

+  FromPtr = SourceLine;

+  ToPtr   = LocalDestLine;

+  //

+  // Walk the entire line, replacing $(MACRO_NAME).

+  //

+  LocalLineLen  = LineLen;

+  ExpandedCount = 0;

+  while (*FromPtr && (LocalLineLen > 0)) {

+    if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {

+      //

+      // Save the start in case it's undefined, in which case we copy it as-is.

+      //

+      SaveStart = FromPtr;

+      Expanded  = 0;

+      //

+      // Macro expansion time. Find the end (no spaces allowed)

+      //

+      FromPtr += 2;

+      for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++)

+        ;

+      if (*Cptr) {

+        //

+        // Truncate the string at the closing parenthesis for ease-of-use.

+        // Then copy the string directly to the destination line in case we don't find

+        // a definition for it.

+        //

+        *Cptr = 0;

+        strcpy (ToPtr, SaveStart);

+        if ((value = GetSymbolValue (FromPtr)) != NULL) {

+          strcpy (ToPtr, value);

+          LocalLineLen -= strlen (value);

+          ToPtr += strlen (value);

+          Expanded = 1;

+          ExpandedCount++;

+        }

+

+        if (!Expanded) {

+          //

+          // Restore closing parenthesis, and advance to next character

+          //

+          *Cptr   = ')';

+          FromPtr = SaveStart + 1;

+          ToPtr++;

+        } else {

+          FromPtr = Cptr + 1;

+        }

+      } else {

+        Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro");

+        strcpy (ToPtr, FromPtr);

+        Status = STATUS_WARNING;

+        goto Done;

+      }

+    } else {

+      *ToPtr = *FromPtr;

+      FromPtr++;

+      ToPtr++;

+      LocalLineLen--;

+    }

+  }

+

+  if (*FromPtr == 0) {

+    *ToPtr = 0;

+  }

+

+  //

+  // If we expanded at least one string successfully, then make a recursive call to try again.

+  //

+  if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) {

+    Status = ExpandMacros (LocalDestLine, DestLine, LineLen);

+    _free (LocalDestLine);

+    NestDepth = 0;

+    return Status;

+  }

+

+Done:

+  if (Status != STATUS_ERROR) {

+    strcpy (DestLine, LocalDestLine);

+  }

+

+  NestDepth = 0;

+  _free (LocalDestLine);

+  return Status;

+}

+

+STATUS

+SymbolsFileStringsReplace (

+  char    *InFileName,

+  char    *OutFileName

+  )

+/*++

+

+Routine Description:

+  

+  Given input and output file names, read in the input file, replace variable

+  references of format $(NAME) with appropriate values from our symbol table,

+  and write the result out to the output file.

+

+Arguments:

+

+  InFileName  - name of input text file to replace variable references

+  OutFileName - name of output text file to write results to

+

+Returns:

+

+  STATUS_SUCCESS - no problems encountered

+  STATUS_ERROR   - failed to open input or output file

+

+--*/

+{

+  STATUS  Status;

+  FILE    *InFptr;

+  FILE    *OutFptr;

+  char    Line[MAX_LINE_LEN];

+  char    OutLine[MAX_LINE_LEN];

+

+  Status = STATUS_ERROR;

+  //

+  // Open input and output files

+  //

+  InFptr  = NULL;

+  OutFptr = NULL;

+  if ((InFptr = fopen (InFileName, "r")) == NULL) {

+    Error (NULL, 0, 0, InFileName, "failed to open input file for reading");

+    goto Done;

+  }

+

+  if ((OutFptr = fopen (OutFileName, "w")) == NULL) {

+    Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");

+    goto Done;

+  }

+  //

+  // Read lines from input file until done

+  //

+  while (fgets (Line, sizeof (Line), InFptr) != NULL) {

+    ExpandMacros (Line, OutLine, sizeof (OutLine));

+    fprintf (OutFptr, OutLine);

+  }

+

+  Status = STATUS_SUCCESS;

+Done:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+  }

+

+  return Status;

+}

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/Symbols.h b/edk2/Tools/Source/TianoTools/FlashMap/Symbols.h
new file mode 100644
index 0000000..1d93910
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/Symbols.h
@@ -0,0 +1,125 @@
+/*++

+

+Copyright (c)  2004 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  Symbols.h

+

+Abstract:

+

+  Defines and prototypes for a class-like symbol table service.

+

+--*/

+

+#ifndef _SYMBOLS_H_

+#define _SYMBOLS_H_

+

+#ifdef __cplusplus

+extern "C"

+{

+#endif

+

+int

+SymbolAdd (

+  char    *Name,

+  char    *Value,

+  int     Mode

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  Name  - GC_TODO: add argument description

+  Value - GC_TODO: add argument description

+  Mode  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+STATUS

+SymbolsFileStringsReplace (

+  char    *InFileName,

+  char    *OutFileName

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  InFileName  - GC_TODO: add argument description

+  OutFileName - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+void

+SymbolsConstructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+void

+SymbolsDestructor (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif // #ifndef _SYMBOLS_H_

diff --git a/edk2/Tools/Source/TianoTools/FlashMap/build.xml b/edk2/Tools/Source/TianoTools/FlashMap/build.xml
new file mode 100644
index 0000000..d2bfdd5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FlashMap/build.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK FlashMap Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="FlashMap"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <defineset>

+        <define name="_malloc" value="malloc"/>

+        <define name="_free" value="free"/>

+      </defineset>

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/FwImage/build.xml b/edk2/Tools/Source/TianoTools/FwImage/build.xml
new file mode 100644
index 0000000..13ecb1f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FwImage/build.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK FwImage Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="FwImage"/>

+  <property name="FileSet" value="fwimage.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DRI}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/FwImage/fwimage.c b/edk2/Tools/Source/TianoTools/FwImage/fwimage.c
new file mode 100644
index 0000000..e2e0d49
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/FwImage/fwimage.c
@@ -0,0 +1,332 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    fwimage.c

+

+Abstract:

+

+    Converts a pe32+ image to an FW image type

+

+--*/

+

+#include <WinNtInclude.h>

+#ifndef __GNUC__

+#include <windows.h>

+#endif

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <time.h>

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <CommonLib.h>

+#include <EfiImage.h>

+#include <EfiUtilityMsgs.c>

+

+#define UTILITY_NAME  "FwImage"

+

+#ifdef __GNUC__

+typedef unsigned long ULONG;

+typedef unsigned char UCHAR;

+typedef unsigned char *PUCHAR;

+typedef unsigned short USHORT;

+#endif

+

+VOID

+Usage (

+  VOID

+  )

+{

+  printf ("Usage: " UTILITY_NAME "  {-t time-date} [APPLICATION|BS_DRIVER|RT_DRIVER|SAL_RT_DRIVER|COMBINED_PEIM_DRIVER|SECURITY_CORE|PEI_CORE|PE32_PEIM|RELOCATABLE_PEIM] peimage [outimage]");

+}

+

+static

+STATUS

+FCopyFile (

+  FILE    *in,

+  FILE    *out

+  )

+{

+  ULONG filesize;

+  ULONG offset;

+  ULONG length;

+  UCHAR Buffer[8 * 1024];

+

+  fseek (in, 0, SEEK_END);

+  filesize = ftell (in);

+

+  fseek (in, 0, SEEK_SET);

+  fseek (out, 0, SEEK_SET);

+

+  offset = 0;

+  while (offset < filesize) {

+    length = sizeof (Buffer);

+    if (filesize - offset < length) {

+      length = filesize - offset;

+    }

+

+    fread (Buffer, length, 1, in);

+    fwrite (Buffer, length, 1, out);

+    offset += length;

+  }

+

+  if ((ULONG) ftell (out) != filesize) {

+    Error (NULL, 0, 0, "write error", NULL);

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+int

+main (

+  int  argc,

+  char *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Main function.

+

+Arguments:

+

+  argc - Number of command line parameters.

+  argv - Array of pointers to command line parameter strings.

+

+Returns:

+  STATUS_SUCCESS - Utility exits successfully.

+  STATUS_ERROR   - Some error occurred during execution.

+

+--*/

+{

+  ULONG             Type;

+  PUCHAR            Ext;

+  PUCHAR            p;

+  PUCHAR            pe;

+  PUCHAR            OutImageName;

+  UCHAR             outname[500];

+  FILE              *fpIn;

+  FILE              *fpOut;

+  EFI_IMAGE_DOS_HEADER  DosHdr;

+  EFI_IMAGE_NT_HEADERS  PeHdr;

+  time_t            TimeStamp;

+  struct tm         TimeStruct;

+  EFI_IMAGE_DOS_HEADER  BackupDosHdr;

+  ULONG             Index;

+  BOOLEAN           TimeStampPresent;

+

+  SetUtilityName (UTILITY_NAME);

+  //

+  // Assign to fix compile warning

+  //

+  OutImageName      = NULL;

+  Type              = 0;

+  Ext               = 0;

+  TimeStamp         = 0;

+  TimeStampPresent  = FALSE;

+

+  //

+  // Look for -t time-date option first. If the time is "0", then

+  // skip it.

+  //

+  if ((argc > 2) && !strcmp (argv[1], "-t")) {

+    TimeStampPresent = TRUE;

+    if (strcmp (argv[2], "0") != 0) {

+      //

+      // Convert the string to a value

+      //

+      memset ((char *) &TimeStruct, 0, sizeof (TimeStruct));

+      if (sscanf(

+          argv[2], "%d/%d/%d,%d:%d:%d",

+          &TimeStruct.tm_mon,   /* months since January - [0,11] */

+          &TimeStruct.tm_mday,  /* day of the month - [1,31] */

+          &TimeStruct.tm_year,  /* years since 1900 */

+          &TimeStruct.tm_hour,  /* hours since midnight - [0,23] */

+          &TimeStruct.tm_min,   /* minutes after the hour - [0,59] */

+          &TimeStruct.tm_sec    /* seconds after the minute - [0,59] */

+            ) != 6) {

+        Error (NULL, 0, 0, argv[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format");

+        return STATUS_ERROR;

+      }

+      //

+      // Now fixup some of the fields

+      //

+      TimeStruct.tm_mon--;

+      TimeStruct.tm_year -= 1900;

+      //

+      // Sanity-check values?

+      // Convert

+      //

+      TimeStamp = mktime (&TimeStruct);

+      if (TimeStamp == (time_t) - 1) {

+        Error (NULL, 0, 0, argv[2], "failed to convert time");

+        return STATUS_ERROR;

+      }

+    }

+    //

+    // Skip over the args

+    //

+    argc -= 2;

+    argv += 2;

+  }

+  //

+  // Check for enough args

+  //

+  if (argc < 3) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  if (argc == 4) {

+    OutImageName = argv[3];

+  }

+  //

+  // Get new image type

+  //

+  p = argv[1];

+  if (*p == '/' || *p == '\\') {

+    p += 1;

+  }

+

+  if (stricmp (p, "app") == 0 || stricmp (p, "APPLICATION") == 0) {

+    Type  = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;

+    Ext   = ".efi";

+

+  } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "BS_DRIVER") == 0) {

+    Type  = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;

+    Ext   = ".efi";

+

+  } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "RT_DRIVER") == 0) {

+    Type  = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;

+    Ext   = ".efi";

+

+  } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "SAL_RT_DRIVER") == 0) {

+    Type  = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;

+    Ext   = ".efi";

+  } else if (stricmp (p, "SECURITY_CORE") == 0) {

+    Type  = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;

+    Ext   = ".sec";

+  } else if (stricmp (p, "peim") == 0 ||

+           stricmp (p, "PEI_CORE") == 0 ||

+           stricmp (p, "PE32_PEIM") == 0 ||

+           stricmp (p, "RELOCATABLE_PEIM") == 0 ||

+           stricmp (p, "combined_peim_driver") == 0

+          ) {

+    Type  = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;

+    Ext   = ".pei";

+  } else {

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // open source file

+  //

+  fpIn = fopen (argv[2], "rb");

+  if (!fpIn) {

+    Error (NULL, 0, 0, argv[2], "failed to open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read the dos & pe hdrs of the image

+  //

+  fseek (fpIn, 0, SEEK_SET);

+  fread (&DosHdr, sizeof (DosHdr), 1, fpIn);

+  if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image");

+    fclose (fpIn);

+    return STATUS_ERROR;

+  }

+

+  fseek (fpIn, DosHdr.e_lfanew, SEEK_SET);

+  fread (&PeHdr, sizeof (PeHdr), 1, fpIn);

+  if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {

+    Error (NULL, 0, 0, argv[2], "PE header signature not found in source image");

+    fclose (fpIn);

+    return STATUS_ERROR;

+  }

+  //

+  // open output file

+  //

+  strcpy (outname, argv[2]);

+  pe = NULL;

+  for (p = outname; *p; p++) {

+    if (*p == '.') {

+      pe = p;

+    }

+  }

+

+  if (!pe) {

+    pe = p;

+  }

+

+  strcpy (pe, Ext);

+

+  if (!OutImageName) {

+    OutImageName = outname;

+  }

+

+  fpOut = fopen (OutImageName, "w+b");

+  if (!fpOut) {

+    Error (NULL, 0, 0, OutImageName, "could not open output file for writing");

+    fclose (fpIn);

+    return STATUS_ERROR;

+  }

+  //

+  // Copy the file

+  //

+  if (FCopyFile (fpIn, fpOut) != STATUS_SUCCESS) {

+    fclose (fpIn);

+    fclose (fpOut);

+    return STATUS_ERROR;

+  }

+  //

+  // Zero all unused fields of the DOS header

+  //

+  memcpy (&BackupDosHdr, &DosHdr, sizeof (DosHdr));

+  memset (&DosHdr, 0, sizeof (DosHdr));

+  DosHdr.e_magic  = BackupDosHdr.e_magic;

+  DosHdr.e_lfanew = BackupDosHdr.e_lfanew;

+  fseek (fpOut, 0, SEEK_SET);

+  fwrite (&DosHdr, sizeof (DosHdr), 1, fpOut);

+

+  fseek (fpOut, sizeof (DosHdr), SEEK_SET);

+  for (Index = sizeof (DosHdr); Index < (ULONG) DosHdr.e_lfanew; Index++) {

+    fwrite (&DosHdr.e_cp, 1, 1, fpOut);

+  }

+  //

+  // Path the PE header

+  //

+  PeHdr.OptionalHeader.Subsystem = (USHORT) Type;

+  if (TimeStampPresent) {

+    PeHdr.FileHeader.TimeDateStamp = (UINT32) TimeStamp;

+  }

+

+  PeHdr.OptionalHeader.SizeOfStackReserve = 0;

+  PeHdr.OptionalHeader.SizeOfStackCommit  = 0;

+  PeHdr.OptionalHeader.SizeOfHeapReserve  = 0;

+  PeHdr.OptionalHeader.SizeOfHeapCommit   = 0;

+  fseek (fpOut, DosHdr.e_lfanew, SEEK_SET);

+  fwrite (&PeHdr, sizeof (PeHdr), 1, fpOut);

+

+  //

+  // Done

+  //

+  fclose (fpIn);

+  fclose (fpOut);

+  //

+  // printf ("Created %s\n", OutImageName);

+  //

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenAcpiTable/GenAcpiTable.c b/edk2/Tools/Source/TianoTools/GenAcpiTable/GenAcpiTable.c
new file mode 100644
index 0000000..c0b9147
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenAcpiTable/GenAcpiTable.c
@@ -0,0 +1,543 @@
+/*++

+

+Copyright (c)  2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+Module Name:

+

+  GenAcpiTable.c

+  

+Abstract:

+

+  A utility that extracts the .DATA section from a PE/COFF image.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include <CommonLib.h>

+#include "EfiImage.h" // for PE32 structure definitions

+#include "EfiUtilityMsgs.h"

+

+//

+// Version of this utility

+//

+#define UTILITY_NAME    "GenAcpiTable"

+#define UTILITY_VERSION "v0.11"

+

+//

+// Define the max length of a filename

+//

+#define MAX_PATH                  256

+#define DEFAULT_OUTPUT_EXTENSION  ".acpi"

+

+//

+// Use this to track our command-line options and globals

+//

+struct {

+  INT8  OutFileName[MAX_PATH];

+  INT8  InFileName[MAX_PATH];

+} mOptions;

+

+//

+// Use these to convert from machine type value to a named type

+//

+typedef struct {

+  UINT16  Value;

+  INT8    *Name;

+} STRING_LOOKUP;

+

+static STRING_LOOKUP  mMachineTypes[] = {

+  EFI_IMAGE_MACHINE_IA32,

+  "IA32",

+  EFI_IMAGE_MACHINE_IA64,

+  "IA64",

+  EFI_IMAGE_MACHINE_EBC,

+  "EBC",

+  0,

+  NULL

+};

+

+static STRING_LOOKUP  mSubsystemTypes[] = {

+  EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,

+  "EFI application",

+  EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,

+  "EFI boot service driver",

+  EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,

+  "EFI runtime driver",

+  0,

+  NULL

+};

+//

+//  Function prototypes

+//

+static

+void

+Usage (

+  VOID

+  );

+

+static

+STATUS

+ParseCommandLine (

+  int       Argc,

+  char      *Argv[]

+  );

+

+static

+STATUS

+CheckPE32File (

+  INT8      *FileName,

+  FILE      *Fptr,

+  UINT16    *MachineType,

+  UINT16    *SubSystem

+  );

+

+static

+STATUS

+ProcessFile (

+  INT8      *InFileName,

+  INT8      *OutFileName

+  );

+

+static

+void

+DumpImage (

+  INT8      *FileName

+  );

+

+main (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+  

+

+Arguments:

+

+  Argc            - standard C main() argument count

+

+  Argv            - standard C main() argument list

+

+Returns:

+

+  0             success

+  non-zero      otherwise

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+{

+  UINT32  Status;

+

+  SetUtilityName (UTILITY_NAME);

+  //

+  // Parse the command line arguments

+  //

+  if (ParseCommandLine (Argc, Argv)) {

+    return STATUS_ERROR;

+  }

+  //

+  // Make sure we don't have the same filename for input and output files

+  //

+  if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {

+    Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");

+    goto Finish;

+  }

+  //

+  // Process the file

+  //

+  ProcessFile (mOptions.InFileName, mOptions.OutFileName);

+Finish:

+  Status = GetUtilityStatus ();

+  return Status;

+}

+

+static

+STATUS

+ProcessFile (

+  INT8      *InFileName,

+  INT8      *OutFileName

+  )

+/*++

+

+Routine Description:

+  

+  Process a PE32 EFI file.

+

+Arguments:

+

+  InFileName - Name of the PE32 EFI file to process.

+  OutFileName - Name of the output file for the processed data.

+

+Returns:

+

+  0 - successful

+

+--*/

+{

+  STATUS                      Status;

+  UINTN                       Index;

+  FILE                        *InFptr;

+  FILE                        *OutFptr;

+  UINT16                      MachineType;

+  UINT16                      SubSystem;

+  UINT32                      PESigOffset;

+  EFI_IMAGE_FILE_HEADER       FileHeader;

+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;

+  EFI_IMAGE_SECTION_HEADER    SectionHeader;

+  UINT8                       *Buffer;

+  long                        SaveFilePosition;

+

+  InFptr  = NULL;

+  OutFptr = NULL;

+  Buffer  = NULL;

+  Status  = STATUS_ERROR;

+  //

+  // Try to open the input file

+  //

+  if ((InFptr = fopen (InFileName, "rb")) == NULL) {

+    Error (NULL, 0, 0, InFileName, "failed to open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Double-check the file to make sure it's what we expect it to be

+  //

+  if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {

+    goto Finish;

+  }

+  //

+  // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit

+  // offset (from the start of the file) to the PE signature, which always

+  // follows the MSDOS stub. The PE signature is immediately followed by the

+  // COFF file header.

+  //

+  //

+  if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {

+    Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);

+    goto Finish;

+  }

+

+  if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");

+    goto Finish;

+  }

+

+  if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {

+    Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");

+    goto Finish;

+  }

+  //

+  // We should now be at the COFF file header. Read it in and verify it's

+  // of an image type we support.

+  //

+  if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read file header from image");

+    goto Finish;

+  }

+

+  if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64) && (FileHeader.Machine != EFI_IMAGE_MACHINE_X64)) {

+    Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);

+    goto Finish;

+  }

+  //

+  // Read in the optional header. Assume PE32, and if not, then re-read as PE32+

+  //

+  SaveFilePosition = ftell (InFptr);

+  if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");

+    goto Finish;

+  }

+

+  if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {

+    if (fseek (InFptr, SaveFilePosition, SEEK_SET) != 0) {

+      Error (NULL, 0, 0, InFileName, "failed to seek to .data section");

+      goto Finish;

+    }

+

+    if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {

+      Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");

+      goto Finish;

+    }

+  }

+  //

+  // Search for the ".data" section

+  //

+  for (Index = 0; Index < FileHeader.NumberOfSections; Index++) {

+    if (fread (&SectionHeader, sizeof (EFI_IMAGE_SECTION_HEADER), 1, InFptr) != 1) {

+      Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");

+      goto Finish;

+    }

+

+    if (strcmp (SectionHeader.Name, ".data") == 0) {

+      if (fseek (InFptr, SectionHeader.PointerToRawData, SEEK_SET) != 0) {

+        Error (NULL, 0, 0, InFileName, "failed to seek to .data section");

+        goto Finish;

+      }

+

+      Buffer = (UINT8 *) malloc (SectionHeader.Misc.VirtualSize);

+      if (Buffer == NULL) {

+        Status = EFI_OUT_OF_RESOURCES;

+        goto Finish;

+      }

+      if (fread (Buffer, SectionHeader.Misc.VirtualSize, 1, InFptr) != 1) {

+        Error (NULL, 0, 0, InFileName, "failed to .data section");

+        goto Finish;

+      }

+      //

+      // Now open our output file

+      //

+      if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {

+        Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");

+        goto Finish;

+      }

+

+      if (fwrite (Buffer, SectionHeader.Misc.VirtualSize, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, OutFileName, "failed to write .data section");

+        goto Finish;

+      }

+

+      Status = STATUS_SUCCESS;

+      goto Finish;

+    }

+  }

+

+  Status = STATUS_ERROR;

+

+Finish:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+  //

+  // Close the output file. If there was an error, delete the output file so

+  // that a subsequent build will rebuild it.

+  //

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+    if (GetUtilityStatus () == STATUS_ERROR) {

+      remove (OutFileName);

+    }

+  }

+

+  //

+  // Free up our buffer

+  //

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+

+  return Status;

+}

+

+static

+STATUS

+CheckPE32File (

+  INT8      *FileName,

+  FILE      *Fptr,

+  UINT16    *MachineType,

+  UINT16    *SubSystem

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FileName    - GC_TODO: add argument description

+  Fptr        - GC_TODO: add argument description

+  MachineType - GC_TODO: add argument description

+  SubSystem   - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  /*++

+

+Routine Description:

+  

+  Given a file pointer to a supposed PE32 image file, verify that it is indeed a

+  PE32 image file, and then return the machine type in the supplied pointer.

+

+Arguments:

+

+  Fptr          File pointer to the already-opened PE32 file

+  MachineType   Location to stuff the machine type of the PE32 file. This is needed

+                because the image may be Itanium-based, IA32, or EBC.

+

+Returns:

+

+  0             success

+  non-zero      otherwise

+

+--*/

+  EFI_IMAGE_DOS_HEADER      DosHeader;

+  EFI_IMAGE_FILE_HEADER     FileHdr;

+  EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;

+  UINT32                    PESig;

+  STATUS                    Status;

+

+  Status = STATUS_ERROR;

+  //

+  // Position to the start of the file

+  //

+  fseek (Fptr, 0, SEEK_SET);

+  //

+  // Read the DOS header

+  //

+  if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");

+    goto Finish;

+  }

+  //

+  // Check the magic number (0x5A4D)

+  //

+  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");

+    goto Finish;

+  }

+  //

+  // Position into the file and check the PE signature

+  //

+  fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);

+  if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");

+    goto Finish;

+  }

+  //

+  // Check the PE signature in the header "PE\0\0"

+  //

+  if (PESig != EFI_IMAGE_NT_SIGNATURE) {

+    Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");

+    goto Finish;

+  }

+  //

+  // Read the file header

+  //

+  if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");

+    goto Finish;

+  }

+  //

+  // Read the optional header so we can get the subsystem

+  //

+  if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");

+    goto Finish;

+  }

+

+  *SubSystem = OptionalHdr.Subsystem;

+  //

+  // Good to go

+  //

+  Status = STATUS_SUCCESS;

+Finish:

+  fseek (Fptr, 0, SEEK_SET);

+  return Status;

+}

+

+static

+int

+ParseCommandLine (

+  int         Argc,

+  char        *Argv[]

+  )

+/*++

+

+Routine Description:

+  

+  Given the Argc/Argv program arguments, and a pointer to an options structure,

+  parse the command-line options and check their validity.

+

+

+Arguments:

+

+  Argc            - standard C main() argument count

+  Argv            - standard C main() argument list

+

+Returns:

+

+  STATUS_SUCCESS    success

+  non-zero          otherwise

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+{

+  //

+  // Clear out the options

+  //

+  memset ((char *) &mOptions, 0, sizeof (mOptions));

+  //

+  // Skip over the program name

+  //

+  Argc--;

+  Argv++;

+

+  if (Argc != 2) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  strcpy (mOptions.InFileName, Argv[0]);

+  //

+  // Next argument

+  //

+  Argv++;

+  Argc--;

+

+  strcpy (mOptions.OutFileName, Argv[0]);

+

+  return STATUS_SUCCESS;

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Print usage information for this utility.

+

+Arguments:

+

+  None.

+

+Returns:

+

+  Nothing.

+

+--*/

+{

+  int               Index;

+  static const char *Msg[] = {

+    UTILITY_NAME " version "UTILITY_VERSION " - Generate ACPI Table image utility",

+    "  Generate an ACPI Table image from an EFI PE32 image",

+    "  Usage: "UTILITY_NAME " InFileName OutFileName",

+    "    where:",

+    "      InFileName     - name of the input PE32 file",

+    "      OutFileName    - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,

+    "",

+    NULL

+  };

+  for (Index = 0; Msg[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Msg[Index]);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/GenAcpiTable/Makefile b/edk2/Tools/Source/TianoTools/GenAcpiTable/Makefile
new file mode 100644
index 0000000..c4df9bc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenAcpiTable/Makefile
@@ -0,0 +1,68 @@
+#/*++

+#  

+#  Copyright (c) 2002 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#  

+#  Module Name:

+#  

+#    makefile

+#    

+#  Abstract:

+#  

+#    makefile for building the GenAcpiTable utility.

+#  

+#--*/

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+#

+# Define the toolchain which is used to set build options and toolchain paths

+#

+TOOLCHAIN = TOOLCHAIN_MSVC

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = GenAcpiTable

+TARGET_SRC_DIR      = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj 

+

+LIBS      = $(TIANO_TOOLS_OUTPUT)\Common.lib

+

+INC_DEPS  = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h

+          

+#

+# Build the EXE by compiling the source files, then linking the resultant

+# object files together.

+#

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@

+

+$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/GenAcpiTable/build.xml b/edk2/Tools/Source/TianoTools/GenAcpiTable/build.xml
new file mode 100644
index 0000000..b6f2427
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenAcpiTable/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenAcpiTable Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenAcpiTable"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenCRC32Section/GenCRC32Section.c b/edk2/Tools/Source/TianoTools/GenCRC32Section/GenCRC32Section.c
new file mode 100644
index 0000000..b99cf2f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCRC32Section/GenCRC32Section.c
@@ -0,0 +1,286 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+    GenCRC32Section.c

+

+Abstract:

+

+  This file contains functions required to generate a Firmware File System 

+  file. The code is compliant with the Tiano C Coding standards.

+

+--*/

+

+#include "GenCRC32Section.h"

+

+#define TOOLVERSION   "0.2"

+

+#define UTILITY_NAME  "GenCrc32Section"

+

+EFI_GUID  gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;

+

+EFI_STATUS

+SignSectionWithCrc32 (

+  IN OUT UINT8  *FileBuffer,

+  IN OUT UINT32 *BufferSize,

+  IN UINT32     DataSize

+  )

+/*++

+        

+Routine Description:

+           

+  Signs the section with CRC32 and add GUIDed section header for the 

+  signed data. data stays in same location (overwrites source data).

+            

+Arguments:

+               

+  FileBuffer  - Buffer containing data to sign

+                

+  BufferSize  - On input, the size of FileBuffer. On output, the size of 

+                actual section data (including added section header).              

+

+  DataSize    - Length of data to Sign

+

+  Key         - Key to use when signing. Currently only CRC32 is supported.

+                                       

+Returns:

+                       

+  EFI_SUCCESS           - Successful

+  EFI_OUT_OF_RESOURCES  - Not enough resource to complete the operation.

+                        

+--*/

+{

+

+  UINT32                Crc32Checksum;

+  EFI_STATUS            Status;

+  UINT32                TotalSize;

+  CRC32_SECTION_HEADER  Crc32Header;

+  UINT8                 *SwapBuffer;

+

+  Crc32Checksum = 0;

+  SwapBuffer    = NULL;

+

+  if (DataSize == 0) {

+    *BufferSize = 0;

+

+    return EFI_SUCCESS;

+  }

+

+  Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE;

+  Crc32Header.GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;

+  Crc32Header.GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalSize & 0xff);

+  Crc32Header.GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalSize & 0xff00) >> 8);

+  Crc32Header.GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalSize & 0xff0000) >> 16);

+  memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));

+  Crc32Header.GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;

+  Crc32Header.GuidSectionHeader.DataOffset  = CRC32_SECTION_HEADER_SIZE;

+  Crc32Header.CRC32Checksum                 = Crc32Checksum;

+

+  SwapBuffer = (UINT8 *) malloc (DataSize);

+  if (SwapBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  memcpy (SwapBuffer, FileBuffer, DataSize);

+  memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE);

+  memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize);

+

+  //

+  // Make sure section ends on a DWORD boundary

+  //

+  while ((TotalSize & 0x03) != 0) {

+    FileBuffer[TotalSize] = 0;

+    TotalSize++;

+  }

+

+  *BufferSize = TotalSize;

+

+  if (SwapBuffer != NULL) {

+    free (SwapBuffer);

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+PrintUsage (

+  VOID

+  )

+{

+  printf ("Usage:\n");

+  printf (UTILITY_NAME " -i \"inputfile1\" \"inputfile2\" -o \"outputfile\" \n");

+  printf ("   -i \"inputfile\":\n ");

+  printf ("       specifies the input files that would be signed to CRC32 Guided section.\n");

+  printf ("   -o \"outputfile\":\n");

+  printf ("       specifies the output file that is a CRC32 Guided section.\n");

+}

+

+INT32

+ReadFilesContentsIntoBuffer (

+  IN      CHAR8   *argv[],

+  IN      INT32   Start,

+  IN OUT  UINT8   **FileBuffer,

+  IN OUT  UINT32  *BufferSize,

+  OUT     UINT32  *ContentSize,

+  IN      INT32   MaximumArguments

+  )

+{

+  INT32   Index;

+  CHAR8   *FileName;

+  FILE    *InputFile;

+  UINT8   Temp;

+  UINT32  Size;

+

+  FileName  = NULL;

+  InputFile = NULL;

+  Size      = 0;

+  Index     = 0;

+

+  //

+  // read all input files into one file buffer

+  //

+  while (argv[Start + Index][0] != '-') {

+

+    FileName  = argv[Start + Index];

+    InputFile = fopen (FileName, "rb");

+    if (InputFile == NULL) {

+      Error (NULL, 0, 0, FileName, "failed to open input binary file");

+      return -1;

+    }

+

+    fread (&Temp, sizeof (UINT8), 1, InputFile);

+    while (!feof (InputFile)) {

+      (*FileBuffer)[Size++] = Temp;

+      fread (&Temp, sizeof (UINT8), 1, InputFile);

+    }

+

+    fclose (InputFile);

+    InputFile = NULL;

+

+    //

+    // Make sure section ends on a DWORD boundary

+    //

+    while ((Size & 0x03) != 0) {

+      (*FileBuffer)[Size] = 0;

+      Size++;

+    }

+

+    Index++;

+    if (Index == MaximumArguments) {

+      break;

+    }

+  }

+

+  *ContentSize = Size;

+  return Index;

+}

+

+int

+main (

+  INT32 argc,

+  CHAR8 *argv[]

+  )

+{

+  FILE        *OutputFile;

+  UINT8       *FileBuffer;

+  UINT32      BufferSize;

+  EFI_STATUS  Status;

+  UINT32      ContentSize;

+  CHAR8       *OutputFileName;

+  INT32       ReturnValue;

+  INT32       Index;

+

+  OutputFile      = NULL;

+  FileBuffer      = NULL;

+  ContentSize     = 0;

+  OutputFileName  = NULL;

+

+  SetUtilityName (UTILITY_NAME);

+

+  if (argc == 1) {

+    PrintUsage ();

+    return -1;

+  }

+

+  BufferSize  = 1024 * 1024 * 16;

+  FileBuffer  = (UINT8 *) malloc (BufferSize * sizeof (UINT8));

+  if (FileBuffer == NULL) {

+    Error (NULL, 0, 0, "memory allocation failed", NULL);

+    return -1;

+  }

+

+  ZeroMem (FileBuffer, BufferSize);

+

+  for (Index = 0; Index < argc; Index++) {

+    if (strcmpi (argv[Index], "-i") == 0) {

+      ReturnValue = ReadFilesContentsIntoBuffer (

+                      argv,

+                      (Index + 1),

+                      &FileBuffer,

+                      &BufferSize,

+                      &ContentSize,

+                      (argc - (Index + 1))

+                      );

+      if (ReturnValue == -1) {

+        Error (NULL, 0, 0, "failed to read file contents", NULL);

+        return -1;

+      }

+

+      Index += ReturnValue;

+    }

+

+    if (strcmpi (argv[Index], "-o") == 0) {

+      OutputFileName = argv[Index + 1];

+    }

+  }

+

+  OutputFile = fopen (OutputFileName, "wb");

+  if (OutputFile == NULL) {

+    Error (NULL, 0, 0, OutputFileName, "failed to open output binary file");

+    free (FileBuffer);

+    return -1;

+  }

+

+  /*  

+  //

+  // make sure section ends on a DWORD boundary ??

+  //

+  while ( (Size & 0x03) != 0 ) {

+    FileBuffer[Size] = 0;

+    Size ++;

+  }

+*/

+  Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "failed to sign section", NULL);

+    free (FileBuffer);

+    fclose (OutputFile);

+    return -1;

+  }

+

+  ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile);

+  if (ContentSize != BufferSize) {

+    Error (NULL, 0, 0, "failed to write output buffer", NULL);

+    ReturnValue = -1;

+  } else {

+    ReturnValue = 0;

+  }

+

+  free (FileBuffer);

+  fclose (OutputFile);

+  return ReturnValue;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenCRC32Section/GenCRC32Section.h b/edk2/Tools/Source/TianoTools/GenCRC32Section/GenCRC32Section.h
new file mode 100644
index 0000000..574231d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCRC32Section/GenCRC32Section.h
@@ -0,0 +1,64 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenCRC32Section.h 

+

+Abstract:

+

+  Header file for GenFfsFile. Mainly defines the header of section

+  header for CRC32 GUID defined sections. Share with GenSection.c

+

+--*/

+

+//

+// External Files Referenced

+//

+

+/* Standard Headers */

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <assert.h>

+

+/* MDE Headers */

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <Common/EfiImage.h>

+#include <Common/FirmwareVolumeImageFormat.h>

+#include <Common/FirmwareFileSystem.h>

+#include <Common/FirmwareVolumeHeader.h>

+#include <Protocol/GuidedSectionExtraction.h>

+

+/* Tool Headers */

+#include <CommonLib.h>

+#include <Crc32.h>

+#include <EfiCompress.h>

+#include <EfiUtilityMsgs.h>

+#include <ParseInf.h>

+

+//

+// Module Coded to Tiano Coding Conventions

+//

+#ifndef _EFI_GEN_CRC32_SECTION_H

+#define _EFI_GEN_CRC32_SECTION_H

+

+

+typedef struct {

+  EFI_GUID_DEFINED_SECTION  GuidSectionHeader;

+  UINT32                    CRC32Checksum;

+} CRC32_SECTION_HEADER;

+

+#define EFI_SECTION_CRC32_GUID_DEFINED  0

+#define CRC32_SECTION_HEADER_SIZE       (sizeof (CRC32_SECTION_HEADER))

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenCRC32Section/build.xml b/edk2/Tools/Source/TianoTools/GenCRC32Section/build.xml
new file mode 100644
index 0000000..a432c86
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCRC32Section/build.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenCRC32Section Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenCRC32Section"/>

+  <property name="FileSet" value="GenCRC32Section.c GenCRC32Section.h"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools"/>

+

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenCapsuleHdr/CreateGuid.c b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/CreateGuid.c
new file mode 100644
index 0000000..05234e8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/CreateGuid.c
@@ -0,0 +1,50 @@
+/*++

+

+Copyright (c)  2003 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  CreateGuid.c  

+

+Abstract:

+

+  Library routine to create a GUID

+

+--*/

+

+#include <windows.h>

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+void

+CreateGuid (

+  GUID *Guid

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  Guid  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  CoCreateGuid (Guid);

+}

diff --git a/edk2/Tools/Source/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c
new file mode 100644
index 0000000..88944cc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c
@@ -0,0 +1,2674 @@
+/*++

+

+Copyright (c)  2002 - 2005, Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  GenCapsuleHdr.c  

+

+Abstract:

+

+  Generate a capsule header for a file, and optionally prepend the

+  header to a file or list of files.

+

+--*/

+

+#define _UNICODE

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include <CommonLib.h>

+

+#include "EfiUtilityMsgs.h"

+#include "MultiPhase.h"

+#include "Capsule.h"

+#include "Guid/Capsule.h"

+#include "FirmwareVolumeImageFormat.h"

+#include "FirmwareVolumeHeader.h"

+#include "FirmwareFileSystem.h"  // for FV header GUID

+#include "Guid/FirmwareFileSystem.h"  // for FV header GUID

+#define MAX_PATH                  256

+#define PROGRAM_NAME              "GenCapsuleHdr"

+

+#define UNICODE_BACKSLASH         L'\\'

+#define UNICODE_FILE_START        0xFEFF

+#define UNICODE_CR                0x000D

+#define UNICODE_LF                0x000A

+#define UNICODE_NULL              0x0000

+#define UNICODE_SPACE             L' '

+#define UNICODE_SLASH             L'/'

+#define UNICODE_DOUBLE_QUOTE      L'"'

+#define UNICODE_A                 L'A'

+#define UNICODE_F                 L'F'

+#define UNICODE_Z                 L'Z'

+#define UNICODE_a                 L'a'

+#define UNICODE_f                 L'f'

+#define UNICODE_z                 L'z'

+#define UNICODE_0                 L'0'

+#define UNICODE_9                 L'9'

+#define UNICODE_TAB               L'\t'

+

+#define OEM_HEADER_STRING         L"OemHeader"

+#define AUTHOR_INFO_STRING        L"AuthorInfo"

+#define REVISION_INFO_STRING      L"RevisionInfo"

+#define SHORT_DESCRIPTION_STRING  L"ShortDescription"

+#define LONG_DESCRIPTION_STRING   L"LongDescription"

+#define EQUAL_STRING              L"="

+#define OPEN_BRACE_STRING         L"{"

+#define CLOSE_BRACE_STRING        L"}"

+#define GUID_STRING               L"GUID"

+#define DATA_STRING               L"DATA"

+

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+#define UEFI_CAPSULE_HEADER_NO_FALAGS      0

+#define UEFI_CAPSULE_HEADER_RESET_FALAGS   CAPSULE_FLAGS_PERSIST_ACROSS_RESET

+#define UEFI_CAPSULE_HEADER_ALL_FALAGS     (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)

+#endif

+

+typedef wchar_t WCHAR;

+

+typedef struct _FILE_LIST {

+  struct _FILE_LIST *Next;

+  INT8              FileName[MAX_PATH];

+} FILE_LIST;

+

+typedef struct _SIZE_LIST {

+  struct _SIZE_LIST *Next;

+  UINT32            Size;

+} SIZE_LIST;

+

+typedef struct {

+  INT8    FileName[MAX_PATH];

+  WCHAR   *FileBuffer;

+  WCHAR   *FileBufferPtr;

+  UINT32  FileSize;

+  FILE    *FilePtr;

+  BOOLEAN EndOfFile;

+  UINT32  LineNum;

+} SOURCE_FILE;

+

+//

+// Here's all our globals.

+//

+static struct {

+  BOOLEAN   Dump;

+  BOOLEAN   Verbose;

+  BOOLEAN   JoinMode;

+  INT8      ScriptFileName[MAX_PATH];

+  INT8      OutputFileName[MAX_PATH];

+  FILE_LIST *FileList;

+  FILE      *OutFptr;

+  SIZE_LIST *SizeList;

+  SIZE_LIST *LastSize;

+  SIZE_LIST *CurrentSize;

+} mOptions;

+

+static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;

+

+void

+CreateGuid (

+  EFI_GUID *Guid

+  );

+

+static

+STATUS

+ProcessArgs (

+  int   Argc,

+  char  *Argv[]

+  );

+

+static

+void

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+STATUS

+GetHexValue (

+  SOURCE_FILE  *SourceFile,

+  UINT32       *Value,

+  UINT32       NumDigits

+  );

+

+static

+BOOLEAN

+GetSplitFileName (

+  INT8    *BaseFileName,

+  INT8    *NewFileName,

+  UINT32  SequenceNumber

+  );

+

+static

+STATUS

+SplitCapsule (

+  INT8 *CapsuleFileName

+  );

+

+static

+void

+Usage (

+  VOID

+  );

+

+static

+void

+DumpCapsule (

+  VOID

+  );

+

+static

+STATUS

+JoinCapsule (

+  VOID

+  );

+

+static

+STATUS

+DumpCapsuleHeaderStrings (

+  UINT8   *SectionName,

+  WCHAR   *Buffer

+  );

+

+static

+STATUS

+CheckFirmwareVolumeHeader (

+  INT8    *FileName,

+  INT8    *Buffer,

+  UINT32  BufferSize

+  );

+

+static

+BOOLEAN

+IsToken (

+  SOURCE_FILE *File,

+  WCHAR       *Token

+  );

+

+static

+BOOLEAN

+GetNumber (

+  INT8    *Str,

+  UINT32  *Value

+  );

+

+static

+STATUS

+ProcessScriptFile (

+  INT8                *ScriptFileName,

+  FILE                *OutFptr,

+  EFI_CAPSULE_HEADER  *CapsuleHeader

+  );

+

+static

+STATUS

+ParseCapsuleInfo (

+  SOURCE_FILE       *SourceFile,

+  FILE              *OutFptr,

+  WCHAR             *SectionName

+  );

+

+static

+STATUS

+CreateCapsule (

+  VOID

+  );

+

+static

+STATUS

+ParseOemInfo (

+  SOURCE_FILE       *SourceFile,

+  FILE              *OutFptr

+  );

+

+static

+BOOLEAN

+IsWhiteSpace (

+  WCHAR Char

+  );

+

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *File

+  );

+

+int

+main (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+  Call the routine to process the command-line arguments, then

+  dispatch to the appropriate function.

+  

+Arguments:

+  Standard C main() argc and argv.

+

+Returns:

+  0      if successful

+  nonzero otherwise

+  

+--*/

+// GC_TODO:    Argc - add argument and description to function comment

+// GC_TODO:    ] - add argument and description to function comment

+{

+  STATUS    Status;

+  FILE_LIST *NextFile;

+  //

+  // Specify our program name to the error printing routines.

+  //

+  SetUtilityName (PROGRAM_NAME);

+  //

+  // Process the command-line arguments

+  //

+  Status = ProcessArgs (Argc, Argv);

+  if (Status == STATUS_SUCCESS) {

+    if (mOptions.Dump) {

+      DumpCapsule ();

+    } else if (mOptions.JoinMode) {

+      JoinCapsule ();

+    } else {

+      CreateCapsule ();

+    }

+  }

+  //

+  // Cleanup

+  //

+  while (mOptions.FileList != NULL) {

+    NextFile = mOptions.FileList->Next;

+    free (mOptions.FileList);

+    mOptions.FileList = NextFile;

+  }

+

+  while (mOptions.SizeList != NULL) {

+    mOptions.CurrentSize = mOptions.SizeList->Next;

+    free (mOptions.SizeList);

+    mOptions.SizeList = mOptions.CurrentSize;

+  }

+

+  return GetUtilityStatus ();

+}

+

+static

+STATUS

+CreateCapsule (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  FILE                        *InFptr;

+  FILE_LIST                   *FileList;

+  INT8                        *Buffer;

+  UINT32                      Size;

+  EFI_CAPSULE_HEADER          CapsuleHeader;

+  UINT8                       Zero;

+  UINT8                       FirstFile;

+  UINT32                      CapsuleHeaderSize;

+  long                        InsertedBlockMapEntryOffset;

+  EFI_FV_BLOCK_MAP_ENTRY      InsertedBlockMapEntry;

+  UINT64                      FirmwareVolumeSize;

+  long                        FileSize;

+  EFI_FIRMWARE_VOLUME_HEADER  FVHeader;

+

+  Buffer                      = NULL;

+  InFptr                      = NULL;

+  FirmwareVolumeSize          = 0;

+  CapsuleHeaderSize           = 0;

+  InsertedBlockMapEntryOffset = 0;

+  memset (&InsertedBlockMapEntry, 0, sizeof (EFI_FV_BLOCK_MAP_ENTRY));

+  memset (&FVHeader, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER));

+

+  if ((mOptions.OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) &CapsuleHeader, 0, sizeof (CapsuleHeader));

+  memcpy ((void *) &CapsuleHeader.CapsuleGuid, (void *) &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID));

+  CapsuleHeader.HeaderSize        = sizeof (EFI_CAPSULE_HEADER);

+  CapsuleHeader.CapsuleImageSize  = sizeof (EFI_CAPSULE_HEADER);

+  if (mOptions.ScriptFileName[0] != 0) {

+    if (ProcessScriptFile (mOptions.ScriptFileName, mOptions.OutFptr, &CapsuleHeader) != STATUS_SUCCESS) {

+      goto Done;

+    }

+  } else {

+    //

+    // Insert a default capsule header

+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)

+    CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER);

+    CapsuleHeader.Flags   = UEFI_CAPSULE_HEADER_ALL_FALAGS;

+#endif

+    CapsuleHeader.OffsetToCapsuleBody = sizeof (EFI_CAPSULE_HEADER);

+

+   if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) {

+     Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+     goto Done;

+   }

+ }

+

+  CapsuleHeaderSize = CapsuleHeader.OffsetToCapsuleBody;

+  //

+  // Now copy the contents of any other files specified on the command

+  // line to the output file. Files must be FFS files, which are aligned

+  // on 8-byte boundaries. Don't align the first file, since it's the start

+  // of the image once the capsule header has been removed.

+  //

+  FileList  = mOptions.FileList;

+  FirstFile = 1;

+  Zero      = 0;

+  while (FileList != NULL) {

+    if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) {

+      Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading");

+      goto Done;

+    }

+    //

+    // Allocate a buffer into which we can read the file.

+    //

+    fseek (InFptr, 0, SEEK_END);

+    Size = ftell (InFptr);

+    rewind (InFptr);

+    Buffer = (char *) malloc (Size);

+    if (Buffer == NULL) {

+      Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into");

+      goto Done;

+    }

+

+    if (fread ((void *) Buffer, Size, 1, InFptr) != 1) {

+      Error (NULL, 0, 0, FileList->FileName, "failed to read file contents");

+      goto Done;

+    }

+

+    if (Size > 0) {

+      //

+      // Align the write of the first bytes from the file if not the first file

+      //

+      if (FirstFile) {

+        //

+        // First file must be a firmware volume. Double-check, and then insert

+        // an additional block map entry so we can add more files from the command line

+        //

+        if (CheckFirmwareVolumeHeader (FileList->FileName, Buffer, Size) != STATUS_SUCCESS) {

+          goto Done;

+        }

+        //

+        // Save a copy of the firmware volume header for later

+        //

+        memcpy (&FVHeader, Buffer, sizeof (EFI_FIRMWARE_VOLUME_HEADER));

+        FirmwareVolumeSize = FVHeader.FvLength;

+        if (FileList->Next != NULL) {

+          //

+          // Copy the firmware volume header

+          //

+          InsertedBlockMapEntryOffset = CapsuleHeaderSize + FVHeader.HeaderLength;

+          if (fwrite (Buffer, FVHeader.HeaderLength, 1, mOptions.OutFptr) != 1) {

+            Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+            goto Done;

+          }

+

+          if (fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr) != 1) {

+            Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+            goto Done;

+          }

+

+          if (fwrite (

+                Buffer + FVHeader.HeaderLength,

+                Size - FVHeader.HeaderLength,

+                1,

+                mOptions.OutFptr

+                ) != 1) {

+            Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+            goto Done;

+          }

+        } else {

+          //

+          // Copy the file contents as-is

+          //

+          if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) {

+            Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+            goto Done;

+          }

+        }

+      } else {

+        while ((ftell (mOptions.OutFptr) - CapsuleHeaderSize) & 0x07) {

+          if (fwrite ((void *) &Zero, 1, 1, mOptions.OutFptr) != 1) {

+            Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+            goto Done;

+          }

+        }

+

+        if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) {

+          Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+          goto Done;

+        }

+      }

+

+      FirstFile = 0;

+    }

+

+    free (Buffer);

+    Buffer = NULL;

+    fclose (InFptr);

+    InFptr    = NULL;

+    FileList  = FileList->Next;

+  }

+

+Done:

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+  //

+  // If we inserted an additional block map entry, then fix it up. Fix up the

+  // FV header as well to reflect our new size.

+  //

+  if (InsertedBlockMapEntryOffset != 0) {

+    FileSize                        = ftell (mOptions.OutFptr);

+    InsertedBlockMapEntry.NumBlocks = 1;

+    InsertedBlockMapEntry.BlockLength = (UINT32) ((UINT64) FileSize - (UINT64) CapsuleHeaderSize - FirmwareVolumeSize - sizeof (EFI_FV_BLOCK_MAP_ENTRY));

+    fseek (mOptions.OutFptr, InsertedBlockMapEntryOffset, SEEK_SET);

+    fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr);

+    //

+    // Fix up the firmware volume header and write it out

+    //

+    fseek (mOptions.OutFptr, CapsuleHeaderSize, SEEK_SET);

+    FVHeader.FvLength = FileSize - CapsuleHeaderSize;

+    FVHeader.HeaderLength += sizeof (EFI_FV_BLOCK_MAP_ENTRY);

+    fwrite (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr);

+    //

+    // Reposition to the end of the file

+    //

+  }

+  //

+  // Close files and free the global string lists we allocated memory for

+  //

+  if (mOptions.OutFptr != NULL) {

+    //

+    // We should now know the full capsule image size. Update the header and write it again.

+    //

+    fseek (mOptions.OutFptr, 0, SEEK_END);

+    Size  = ftell (mOptions.OutFptr);

+    CapsuleHeader.CapsuleImageSize = Size;

+    fseek (mOptions.OutFptr, 0, SEEK_SET);

+    if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) {

+      Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+    }

+

+    fseek (mOptions.OutFptr, 0, SEEK_END);

+    fclose (mOptions.OutFptr);

+    mOptions.OutFptr = NULL;

+  }

+  //

+  // If they are doing split capsule output, then split it up now.

+  //

+  if ((mOptions.Dump == 0) && (GetUtilityStatus () == STATUS_SUCCESS) && (mOptions.SizeList != NULL)) {

+    SplitCapsule (mOptions.OutputFileName);

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+ProcessScriptFile (

+  INT8                *ScriptFileName,

+  FILE                *OutFptr,

+  EFI_CAPSULE_HEADER  *CapsuleHeader

+  )

+/*++

+

+Routine Description:

+  Parse a capsule header script file.

+

+Arguments:

+  ScriptFileName    - name of script file to parse

+  OutFptr           - output to dump binary data

+  CapsuleHeader     - capsule header to update with size info

+                      of parsed fields in the script file

+

+Returns:

+  STATUS_SUCCESS - if all went well

+

+--*/

+{

+#if 0

+  STATUS      Status;

+  SOURCE_FILE SourceFile;

+  WCHAR       *WScriptFileName;

+  BOOLEAN     InComment;

+

+  if (fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write capsule header to output file", NULL);

+    return STATUS_ERROR;

+  }

+

+  memset (&SourceFile, 0, sizeof (SOURCE_FILE));

+  strcpy (SourceFile.FileName, ScriptFileName);

+

+  Status = STATUS_ERROR;

+  //

+  // Open the input unicode script file and read it into a buffer

+  //

+  WScriptFileName = (WCHAR *) malloc ((strlen (ScriptFileName) + 1) * sizeof (WCHAR));

+  if (WScriptFileName == NULL) {

+    Error (__FILE__, __LINE__, 0, "failed to allocate memory", NULL);

+    return STATUS_ERROR;

+  }

+

+  swprintf (WScriptFileName, L"%S", ScriptFileName);

+  if ((SourceFile.FilePtr = _wfopen (WScriptFileName, L"r")) == NULL) {

+    free (WScriptFileName);

+    Error (NULL, 0, 0, ScriptFileName, "failed to open script file for reading");

+    goto Done;

+  }

+

+  free (WScriptFileName);

+  fseek (SourceFile.FilePtr, 0, SEEK_END);

+  SourceFile.FileSize = ftell (SourceFile.FilePtr);

+  rewind (SourceFile.FilePtr);

+  SourceFile.FileBuffer = (WCHAR *) malloc (SourceFile.FileSize + sizeof (WCHAR));

+  if (SourceFile.FileBuffer == NULL) {

+    Error (__FILE__, __LINE__, 0, ScriptFileName, "failed to allocate memory to read in file contents");

+    goto Done;

+  }

+

+  if (fread (SourceFile.FileBuffer, SourceFile.FileSize, 1, SourceFile.FilePtr) != 1) {

+    Error (NULL, 0, 0, ScriptFileName, "failed to read file contents");

+    goto Done;

+  }

+

+  SourceFile.FileBufferPtr  = SourceFile.FileBuffer;

+  SourceFile.LineNum        = 1;

+  if (SourceFile.FileBuffer[0] != UNICODE_FILE_START) {

+    Error (ScriptFileName, 1, 0, "file does not appear to be a unicode file", NULL);

+    goto Done;

+  }

+

+  SourceFile.FileBufferPtr++;

+  SourceFile.FileBuffer[SourceFile.FileSize / sizeof (WCHAR)] = 0;

+  //

+  // Walk the source file buffer and replace all carriage returns with 0 so

+  // we can print from the file contents on parse errors.

+  //

+  InComment = 0;

+  while (!EndOfFile (&SourceFile)) {

+    if (SourceFile.FileBufferPtr[0] == UNICODE_CR) {

+      SourceFile.FileBufferPtr[0] = 0;

+      InComment                   = 0;

+    } else if (SourceFile.FileBufferPtr[0] == UNICODE_LF) {

+      InComment = 0;

+    } else if (InComment) {

+      SourceFile.FileBufferPtr[0] = UNICODE_SPACE;

+    } else if ((SourceFile.FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile.FileBufferPtr[1] == UNICODE_SLASH)) {

+      InComment                   = 1;

+      SourceFile.FileBufferPtr[0] = UNICODE_SPACE;

+    }

+

+    SourceFile.FileBufferPtr++;

+  }

+  //

+  // Reposition to the start of the file, but skip over the unicode file start

+  //

+  SourceFile.FileBufferPtr = SourceFile.FileBuffer;

+  SourceFile.FileBufferPtr++;

+  SourceFile.EndOfFile                    = 0;

+  CapsuleHeader->OffsetToOemDefinedHeader = ftell (OutFptr);

+  //

+  // Parse the OEM bytes

+  //

+  if (ParseOemInfo (&SourceFile, OutFptr) != STATUS_SUCCESS) {

+    goto Done;

+  }

+  //

+  // Parse the author information

+  //

+  CapsuleHeader->OffsetToAuthorInformation = ftell (OutFptr);

+  if (ParseCapsuleInfo (&SourceFile, OutFptr, AUTHOR_INFO_STRING) != STATUS_SUCCESS) {

+    goto Done;

+  }

+  //

+  // Parse the revision information

+  //

+  CapsuleHeader->OffsetToRevisionInformation = ftell (OutFptr);

+  if (ParseCapsuleInfo (&SourceFile, OutFptr, REVISION_INFO_STRING) != STATUS_SUCCESS) {

+    goto Done;

+  }

+  //

+  // Parse the short description

+  //

+  CapsuleHeader->OffsetToShortDescription = ftell (OutFptr);

+  if (ParseCapsuleInfo (&SourceFile, OutFptr, SHORT_DESCRIPTION_STRING) != STATUS_SUCCESS) {

+    goto Done;

+  }

+  //

+  // Parse the long description

+  //

+  CapsuleHeader->OffsetToLongDescription = ftell (OutFptr);

+  if (ParseCapsuleInfo (&SourceFile, OutFptr, LONG_DESCRIPTION_STRING) != STATUS_SUCCESS) {

+    goto Done;

+  }

+  //

+  // Better be end of contents

+  //

+  SkipWhiteSpace (&SourceFile);

+  if (!EndOfFile (&SourceFile)) {

+    Error (ScriptFileName, SourceFile.LineNum, 0, NULL, "expected end-of-file, not %.20S", SourceFile.FileBufferPtr);

+    goto Done;

+  }

+

+  CapsuleHeader->OffsetToCapsuleBody = ftell (OutFptr);

+  rewind (OutFptr);

+  fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr);

+  fseek (OutFptr, 0, SEEK_END);

+  Status = STATUS_SUCCESS;

+Done:

+  if (SourceFile.FilePtr != NULL) {

+    fclose (SourceFile.FilePtr);

+  }

+

+  if (SourceFile.FileBuffer != NULL) {

+    free (SourceFile.FileBuffer);

+  }

+

+  return Status;

+

+#endif

+  return STATUS_SUCCESS;

+}

+//

+// Parse the OEM data of format:

+//      OemInfo {

+//            GUID = 12345676-1234-1234-123456789ABC

+//            DATA = 0x01, 0x02, 0x03...

+//      }

+//

+static

+STATUS

+ParseOemInfo (

+  SOURCE_FILE       *SourceFile,

+  FILE              *OutFptr

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  SourceFile  - GC_TODO: add argument description

+  OutFptr     - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  long                    OemHeaderOffset;

+  UINT32                  Data;

+  EFI_CAPSULE_OEM_HEADER  OemHeader;

+  STATUS                  Status;

+  UINT32                  DigitCount;

+  WCHAR                   *SaveFilePos;

+  UINT8                   ByteData;

+

+  Status = STATUS_ERROR;

+  memset (&OemHeader, 0, sizeof (EFI_CAPSULE_OEM_HEADER));

+  OemHeaderOffset       = ftell (OutFptr);

+  OemHeader.HeaderSize  = sizeof (EFI_CAPSULE_OEM_HEADER);

+  if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write OEM header to output file", NULL);

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, OEM_HEADER_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      OEM_HEADER_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, EQUAL_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      EQUAL_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, OPEN_BRACE_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      OPEN_BRACE_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+  //

+  // Look for:  GUID = xxxxxxx-xxxx-xxxx-xxxxxxxxxxxxx

+  //

+  if (!IsToken (SourceFile, GUID_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      GUID_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, EQUAL_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      EQUAL_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+  //

+  // Parse the xxxxxxxx-xxxx-xxxx-xxxx portion of the GUID

+  //

+  SkipWhiteSpace (SourceFile);

+  if (GetHexValue (SourceFile, &Data, 8) != STATUS_SUCCESS) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL);

+    goto Done;

+  }

+

+  OemHeader.OemGuid.Data1 = Data;

+  if (!IsToken (SourceFile, L"-")) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected dash in GUID, not %S",

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+  //

+  // Get 3 word values

+  //

+  for (DigitCount = 0; DigitCount < 3; DigitCount++) {

+    if (GetHexValue (SourceFile, &Data, 4) != STATUS_SUCCESS) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL);

+      goto Done;

+    }

+

+    switch (DigitCount) {

+    case 0:

+      OemHeader.OemGuid.Data2 = (UINT16) Data;

+      break;

+

+    case 1:

+      OemHeader.OemGuid.Data3 = (UINT16) Data;

+      break;

+

+    case 2:

+      OemHeader.OemGuid.Data4[1]  = (UINT8) Data;

+      OemHeader.OemGuid.Data4[0]  = (UINT8) (Data >> 8);

+      break;

+    }

+

+    if (!IsToken (SourceFile, L"-")) {

+      Error (

+        SourceFile->FileName,

+        SourceFile->LineNum,

+        0,

+        NULL,

+        "expected dash in GUID, not %S",

+        SourceFile->FileBufferPtr

+        );

+      goto Done;

+    }

+  }

+  //

+  // Pick up the last 6 bytes of the GUID

+  //

+  SaveFilePos = SourceFile->FileBufferPtr;

+  for (DigitCount = 0; DigitCount < 6; DigitCount++) {

+    if (GetHexValue (SourceFile, &Data, 2) != STATUS_SUCCESS) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL);

+      goto Done;

+    }

+

+    OemHeader.OemGuid.Data4[DigitCount + 2] = (UINT8) Data;

+  }

+  //

+  // Now read raw OEM data bytes. May or may not be present.

+  //    DATA = 0x01, 0x02, 0x02...

+  //

+  if (IsToken (SourceFile, CLOSE_BRACE_STRING)) {

+    Status = STATUS_SUCCESS;

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, DATA_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      DATA_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, EQUAL_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      EQUAL_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  while (!EndOfFile (SourceFile)) {

+    if (IsToken (SourceFile, CLOSE_BRACE_STRING)) {

+      Status = STATUS_SUCCESS;

+      goto Done;

+    }

+

+    if (IsToken (SourceFile, L"0x")) {

+      if (swscanf (SourceFile->FileBufferPtr, L"%x", &Data) != 1) {

+        Error (

+          SourceFile->FileName,

+          SourceFile->LineNum,

+          0,

+          NULL,

+          "expected hex byte value, not %.20S",

+          SourceFile->FileBufferPtr

+          );

+        goto Done;

+      }

+

+      if (Data &~0xFF) {

+        Error (

+          SourceFile->FileName,

+          SourceFile->LineNum,

+          0,

+          NULL,

+          "expected byte hex byte value at %.20S",

+          SourceFile->FileBufferPtr

+          );

+        goto Done;

+      }

+      //

+      // Skip over the hex digits, then write the data

+      //

+      while (iswxdigit (SourceFile->FileBufferPtr[0])) {

+        SourceFile->FileBufferPtr++;

+      }

+

+      ByteData = (UINT8) Data;

+      if (fwrite (&ByteData, 1, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, "failed to write OEM data to output file", NULL);

+        goto Done;

+      }

+

+      OemHeader.HeaderSize++;

+      //

+      // Optional comma

+      //

+      IsToken (SourceFile, L",");

+    } else {

+      Error (

+        SourceFile->FileName,

+        SourceFile->LineNum,

+        0,

+        NULL,

+        "expected hex OEM data, not %.20S",

+        SourceFile->FileBufferPtr

+        );

+      goto Done;

+    }

+  }

+

+  if (EndOfFile (SourceFile)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S close to OEM header data",

+      CLOSE_BRACE_STRING

+      );

+    goto Done;

+  }

+

+  Status = STATUS_SUCCESS;

+Done:

+  //

+  // re-write the oem header if no errors

+  //

+  if (Status == STATUS_SUCCESS) {

+    fseek (OutFptr, OemHeaderOffset, SEEK_SET);

+    if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) {

+      Error (NULL, 0, 0, "failed to write OEM header to output file", NULL);

+      goto Done;

+    }

+

+    fseek (OutFptr, 0, SEEK_END);

+  }

+

+  return Status;

+}

+

+static

+STATUS

+ParseCapsuleInfo (

+  SOURCE_FILE       *SourceFile,

+  FILE              *OutFptr,

+  WCHAR             *SectionName

+  )

+// GC_TODO: function comment should start with '/*++'

+//

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    SourceFile - add argument and description to function comment

+// GC_TODO:    OutFptr - add argument and description to function comment

+// GC_TODO:    SectionName - add argument and description to function comment

+// Parse:  eng "string " "parts"

+//          spa "string " "parts"

+// Write out: "eng string parts\0spa string parts\0\0

+//

+{

+  STATUS  Status;

+  int     StringCount;

+  WCHAR   Zero;

+  WCHAR   Spacebar;

+

+  Status    = STATUS_ERROR;

+  Zero      = 0;

+  Spacebar  = UNICODE_SPACE;

+

+  if (!IsToken (SourceFile, SectionName)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      SectionName,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, EQUAL_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      EQUAL_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  if (!IsToken (SourceFile, OPEN_BRACE_STRING)) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      NULL,

+      "expected %S, not %.20S",

+      OPEN_BRACE_STRING,

+      SourceFile->FileBufferPtr

+      );

+    goto Done;

+  }

+

+  while (!EndOfFile (SourceFile)) {

+    if (IsToken (SourceFile, CLOSE_BRACE_STRING)) {

+      break;

+    }

+    //

+    // Look for language identifier (3 lowercase chars)

+    //

+    if ((SourceFile->FileBufferPtr[0] >= UNICODE_a) &&

+        (SourceFile->FileBufferPtr[0] <= UNICODE_z) &&

+        (SourceFile->FileBufferPtr[1] >= UNICODE_a) &&

+        (SourceFile->FileBufferPtr[1] <= UNICODE_z) &&

+        (SourceFile->FileBufferPtr[2] >= UNICODE_a) &&

+        (SourceFile->FileBufferPtr[2] <= UNICODE_z) &&

+        IsWhiteSpace (SourceFile->FileBufferPtr[3])

+          ) {

+      //

+      // Write the 3 chars followed by a spacebar, and then look for opening quote

+      //

+      fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);

+      SourceFile->FileBufferPtr++;

+      fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);

+      SourceFile->FileBufferPtr++;

+      fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);

+      SourceFile->FileBufferPtr++;

+      fwrite (&Spacebar, sizeof (WCHAR), 1, OutFptr);

+      StringCount = 0;

+      while (IsToken (SourceFile, L"\"")) {

+        StringCount++;

+        while (!EndOfFile (SourceFile)) {

+          if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {

+            SourceFile->FileBufferPtr++;

+            break;

+          } else if ((SourceFile->FileBufferPtr[0] == UNICODE_LF) || (SourceFile->FileBufferPtr[0] == 0)) {

+            Error (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", NULL);

+            goto Done;

+          } else {

+            fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);

+            SourceFile->FileBufferPtr++;

+          }

+        }

+      }

+

+      if (StringCount == 0) {

+        Error (

+          SourceFile->FileName,

+          SourceFile->LineNum,

+          0,

+          NULL,

+          "expected quoted string, not %.20S",

+          SourceFile->FileBufferPtr

+          );

+        goto Done;

+      }

+      //

+      // This string's null terminator

+      //

+      fwrite (&Zero, sizeof (WCHAR), 1, OutFptr);

+    } else {

+      Error (

+        SourceFile->FileName,

+        SourceFile->LineNum,

+        0,

+        NULL,

+        "expected valid language identifer, not %.20S",

+        SourceFile->FileBufferPtr

+        );

+      goto Done;

+    }

+  }

+  //

+  // Double null terminator

+  //

+  fwrite (&Zero, sizeof (WCHAR), 1, OutFptr);

+  Status = STATUS_SUCCESS;

+Done:

+  return Status;

+}

+

+static

+STATUS

+SplitCapsule (

+  INT8    *CapsuleFileName

+  )

+/*++

+

+Routine Description:

+  We've created an entire capsule image. Now split it up into the 

+  size pieces they requested.

+

+Arguments:

+  CapsuleFileName  - name of an existing capsule file on disk

+

+Returns:

+  STATUS_SUCCESS - if no problems

+

+Notes:

+  This implementation reads in the entire capsule image from

+  disk, then overwrites the original file with the first

+  in the series.

+

+--*/

+{

+#if 0

+  EFI_CAPSULE_HEADER  *CapHdr;

+

+  EFI_CAPSULE_HEADER  Hdr;

+  FILE                *CapFptr;

+  FILE                *OutFptr;

+  UINT32              SizeLeft;

+  UINT32              CurrentSize;

+  UINT32              DataSize;

+  UINT32              SequenceNumber;

+  INT8                *Buffer;

+  INT8                FileName[MAX_PATH];

+  STATUS              Status;

+  UINT32              FileSize;

+  //

+  // Figure out the total size, then rewind the input file and

+  // read the entire thing in

+  //

+  if ((CapFptr = fopen (CapsuleFileName, "rb")) == NULL) {

+    Error (NULL, 0, 0, CapsuleFileName, "failed to open capsule image for reading");

+    return STATUS_ERROR;

+  }

+

+  OutFptr = NULL;

+  Status  = STATUS_SUCCESS;

+  fseek (CapFptr, 0, SEEK_END);

+  SizeLeft = ftell (CapFptr);

+  fseek (CapFptr, 0, SEEK_SET);

+  CapHdr = (EFI_CAPSULE_HEADER *) malloc (SizeLeft);

+  if (CapHdr == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    goto FailDone;

+  }

+

+  if (fread (CapHdr, SizeLeft, 1, CapFptr) != 1) {

+    Error (NULL, 0, 0, "failed to read capsule contents", "split failed");

+    goto FailDone;

+  }

+

+  fclose (CapFptr);

+  CapFptr = NULL;

+  //

+  // Get a GUID to fill in the InstanceId GUID in the header

+  //

+  CreateGuid (&CapHdr->InstanceId);

+  SequenceNumber = 0;

+  //

+  // If the split size is larger than the original capsule image, then

+  // we're done.

+  //

+  if (mOptions.SizeList->Size >= SizeLeft) {

+    mOptions.SizeList->Size = SizeLeft;

+    goto Done;

+  }

+  //

+  // First size has to be big enough for the original header

+  //

+  if (mOptions.SizeList->Size < CapHdr->OffsetToCapsuleBody) {

+    Error (NULL, 0, 0, "first split size is insufficient for the original capsule header", NULL);

+    goto FailDone;

+  }

+  //

+  // Initialize the header we'll use on all but the first part

+  //

+  memset (&Hdr, 0, sizeof (Hdr));

+  Hdr.CapsuleGuid         = CapHdr->CapsuleGuid;

+  Hdr.HeaderSize          = sizeof (Hdr);

+  Hdr.Flags               = CapHdr->Flags;

+  Hdr.InstanceId          = CapHdr->InstanceId;

+  Hdr.CapsuleImageSize    = CapHdr->CapsuleImageSize;

+  Hdr.OffsetToCapsuleBody = Hdr.HeaderSize;

+  Hdr.SequenceNumber      = 1;

+  //

+  // printf ("Created %s - 0x%X bytes\n", CapsuleFileName, mOptions.SizeList->Size);

+  //

+  Buffer = (UINT8 *) CapHdr;

+  //

+  // Walk the list of sizes and write out a capsule header, and

+  // then the raw capsule data.

+  //

+  //  SizeLeft -= mOptions.SizeList->Size;

+  //

+  mOptions.CurrentSize = mOptions.SizeList;

+  while (SizeLeft) {

+    CurrentSize = mOptions.CurrentSize->Size;

+    GetSplitFileName (mOptions.OutputFileName, FileName, SequenceNumber);

+    if ((OutFptr = fopen (FileName, "wb")) == NULL) {

+      Error (NULL, 0, 0, FileName, "failed to open split file for writing");

+      goto FailDone;

+    }

+

+    if (Buffer == (UINT8 *) CapHdr) {

+      //

+      // First part -- write out original header and data

+      //

+      if (fwrite (Buffer, CurrentSize, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, FileName, "failed to write to split image file");

+        goto FailDone;

+      }

+

+      SizeLeft -= CurrentSize;

+      Buffer += CurrentSize;

+      DataSize  = CurrentSize;

+      FileSize  = CurrentSize;

+    } else {

+      //

+      // Not the first part. Write the default header, and then the raw bytes from the

+      // original image.

+      //

+      if (CurrentSize <= sizeof (Hdr)) {

+        Error (NULL, 0, 0, "split size too small for capsule header + data", "0x%X", CurrentSize);

+        goto FailDone;

+      }

+

+      DataSize = CurrentSize - sizeof (Hdr);

+      if (DataSize > SizeLeft) {

+        DataSize = SizeLeft;

+      }

+

+      if (fwrite (&Hdr, sizeof (Hdr), 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, FileName, "failed to write capsule header to output file");

+        fclose (OutFptr);

+        goto FailDone;

+      }

+

+      if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, FileName, "failed to write capsule data to output file");

+        fclose (OutFptr);

+        goto FailDone;

+      }

+

+      Hdr.SequenceNumber++;

+      Buffer += DataSize;

+      SizeLeft -= DataSize;

+      FileSize = DataSize + sizeof (Hdr);

+    }

+    //

+    // Next size in list if there is one

+    //

+    if (mOptions.CurrentSize->Next != NULL) {

+      mOptions.CurrentSize = mOptions.CurrentSize->Next;

+    }

+

+    SequenceNumber++;

+    fclose (OutFptr);

+    OutFptr = NULL;

+    printf ("Created %s - 0x%X bytes (0x%X bytes of data)\n", FileName, FileSize, DataSize);

+  }

+

+  goto Done;

+FailDone:

+  Status = STATUS_ERROR;

+Done:

+  if (CapHdr != NULL) {

+    free (CapHdr);

+  }

+

+  if (CapFptr != NULL) {

+    fclose (CapFptr);

+  }

+

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+  }

+

+  return Status;

+

+#endif

+   return STATUS_SUCCESS;

+}

+

+static

+BOOLEAN

+GetSplitFileName (

+  INT8    *BaseFileName,

+  INT8    *NewFileName,

+  UINT32  SequenceNumber

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  BaseFileName    - GC_TODO: add argument description

+  NewFileName     - GC_TODO: add argument description

+  SequenceNumber  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  /*++

+

+Routine Description:

+  Given an initial split capsule file name and a sequence number,

+  create an appropriate file name for this split of a capsule image.

+

+Arguments:

+  BaseFileName   - name of of the first split file in the series

+  NewFileName    - output name of the split file

+  SequenceNumber - 0-based sequence number of split images

+

+Returns:

+  TRUE   - name created successfully

+  FALSE  - otherwise

+

+--*/

+  INT8    *Ptr;

+  INT8    *Part2Start;

+  UINT32  Digits;

+  UINT32  Len;

+  UINT32  BaseOffset;

+  //

+  // Work back from the end of the file name and see if there is a number somewhere

+  //

+  for (Ptr = BaseFileName + strlen (BaseFileName) - 1; (Ptr > BaseFileName) && !isdigit (*Ptr); Ptr--)

+    ;

+  if ((Ptr == BaseFileName) && (!isdigit (*Ptr))) {

+    //

+    // Found no number, so just add it to the end

+    //

+    sprintf (NewFileName, "%s%d", BaseFileName, SequenceNumber);

+    return TRUE;

+  } else {

+    //

+    // Found a number. Look back to find the first digit.

+    //

+    Part2Start = Ptr + 1;

+    for (Digits = 1; isdigit (*Ptr) && (Ptr > BaseFileName); Ptr--, Digits++)

+      ;

+    if (!isdigit (*Ptr)) {

+      Ptr++;

+      Digits--;

+    }

+

+    BaseOffset      = atoi (Ptr);

+    SequenceNumber  = SequenceNumber + BaseOffset;

+    if (Digits > 1) {

+      //

+      // Copy the first part of the original file name to the new filename

+      // This is the path for filenames with format path\name001.cap

+      //

+      Len = (UINT32) Ptr - (UINT32) BaseFileName;

+      strncpy (NewFileName, BaseFileName, Len);

+      sprintf (NewFileName + Len, "%0*d", Digits, SequenceNumber);

+      strcat (NewFileName, Part2Start);

+      return TRUE;

+    } else {

+      //

+      // Only one digit found. This is the path for filenames with

+      // format path\name1.cap

+      //

+      Len = (UINT32) Ptr - (UINT32) BaseFileName + 1;

+      strncpy (NewFileName, BaseFileName, Len);

+      sprintf (NewFileName + Len - 1, "%d", SequenceNumber);

+      strcat (NewFileName, Part2Start);

+      return TRUE;

+    }

+  }

+}

+

+static

+BOOLEAN

+IsWhiteSpace (

+  WCHAR  Char

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  Char  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  switch (Char) {

+  case UNICODE_SPACE:

+  case UNICODE_TAB:

+  case UNICODE_NULL:

+  case UNICODE_CR:

+  case UNICODE_LF:

+    return TRUE;

+

+  default:

+    return FALSE;

+  }

+}

+

+static

+BOOLEAN

+IsToken (

+  SOURCE_FILE *File,

+  WCHAR       *Token

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  File  - GC_TODO: add argument description

+  Token - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  SkipWhiteSpace (File);

+  if (EndOfFile (File)) {

+    return FALSE;

+  }

+

+  if (wcsncmp (Token, File->FileBufferPtr, wcslen (Token)) == 0) {

+    File->FileBufferPtr += wcslen (Token);

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+static

+STATUS

+CheckFirmwareVolumeHeader (

+  INT8    *FileName,

+  INT8    *Buffer,

+  UINT32  BufferSize

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FileName    - GC_TODO: add argument description

+  Buffer      - GC_TODO: add argument description

+  BufferSize  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  EFI_FIRMWARE_VOLUME_HEADER  *Hdr;

+  EFI_GUID                    FVHeaderGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID;

+

+  Hdr           = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;

+  if (Hdr->Signature != EFI_FVH_SIGNATURE) {

+    Error (NULL, 0, 0, FileName, "file does not appear to be a firmware volume (bad signature)");

+    return STATUS_ERROR;

+  }

+

+  if (Hdr->Revision != EFI_FVH_REVISION) {

+    Error (NULL, 0, 0, FileName, "unsupported firmware volume header version");

+    return STATUS_ERROR;

+  }

+

+  if (Hdr->FvLength > BufferSize) {

+    Error (NULL, 0, 0, FileName, "malformed firmware volume -- FvLength > file size");

+    return STATUS_ERROR;

+  }

+

+  if (memcmp (&Hdr->FileSystemGuid, &FVHeaderGuid, sizeof (EFI_GUID)) != 0) {

+    Error (NULL, 0, 0, FileName, "invalid FFS GUID in firmware volume header");

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+void

+DumpCapsule (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+#if 0

+  FILE                        *InFptr;

+  FILE_LIST                   *FileList;

+  EFI_CAPSULE_HEADER          CapsuleHeader;

+  EFI_FIRMWARE_VOLUME_HEADER  FVHeader;

+  EFI_CAPSULE_OEM_HEADER      *OemHeader;

+  UINT8                       *BPtr;

+  UINT32                      FileSize;

+  UINT32                      CapsuleHeaderDataSize;

+  UINT8                       ByteCount;

+  UINT8                       *CapsuleHeaderData;

+  BOOLEAN                     SplitImage;

+

+  InFptr            = NULL;

+  CapsuleHeaderData = NULL;

+  FileList          = mOptions.FileList;

+  while (FileList != NULL) {

+    if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) {

+      Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading");

+      goto Done;

+    }

+

+    if (fread (&CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, InFptr) != 1) {

+      Error (NULL, 0, 0, FileList->FileName, "failed to read capsule header");

+      goto Done;

+    }

+

+    fseek (InFptr, 0, SEEK_END);

+    FileSize = ftell (InFptr);

+    if (CapsuleHeader.CapsuleImageSize > FileSize) {

+      SplitImage = TRUE;

+    } else {

+      SplitImage = FALSE;

+    }

+

+    printf (

+      "Capsule %s Size=0x%X CargoSize=0x%X\n",

+      FileList->FileName,

+      FileSize,

+      FileSize - CapsuleHeader.OffsetToCapsuleBody

+      );

+    printf (

+      "  GUID                  %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",

+      CapsuleHeader.CapsuleGuid.Data1,

+      (UINT32) CapsuleHeader.CapsuleGuid.Data2,

+      (UINT32) CapsuleHeader.CapsuleGuid.Data3,

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[0],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[1],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[2],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[3],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[4],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[5],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[6],

+      (UINT32) CapsuleHeader.CapsuleGuid.Data4[7]

+      );

+    if (memcmp (&CapsuleHeader.CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) {

+      printf ("  INVALID GUID");

+    }

+

+    printf ("\n");

+    printf ("  Header size           0x%08X\n", CapsuleHeader.HeaderSize);

+    printf ("  Flags                 0x%08X\n", CapsuleHeader.Flags);

+    if (!SplitImage) {

+      printf ("  Capsule image size    0x%08X\n", CapsuleHeader.CapsuleImageSize);

+    } else {

+      printf ("  Capsule image size    0x%08X (split)\n", CapsuleHeader.CapsuleImageSize);

+    }

+

+    printf ("  Sequence number       %d\n", CapsuleHeader.SequenceNumber);

+    printf (

+      "  InstanceId            %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",

+      CapsuleHeader.InstanceId.Data1,

+      (UINT32) CapsuleHeader.InstanceId.Data2,

+      (UINT32) CapsuleHeader.InstanceId.Data3,

+      (UINT32) CapsuleHeader.InstanceId.Data4[0],

+      (UINT32) CapsuleHeader.InstanceId.Data4[1],

+      (UINT32) CapsuleHeader.InstanceId.Data4[2],

+      (UINT32) CapsuleHeader.InstanceId.Data4[3],

+      (UINT32) CapsuleHeader.InstanceId.Data4[4],

+      (UINT32) CapsuleHeader.InstanceId.Data4[5],

+      (UINT32) CapsuleHeader.InstanceId.Data4[6],

+      (UINT32) CapsuleHeader.InstanceId.Data4[7]

+      );

+    printf ("  Offset to capsule     0x%X\n", CapsuleHeader.OffsetToCapsuleBody);

+    //

+    // Dump header data if there

+    //

+    CapsuleHeaderDataSize = CapsuleHeader.OffsetToCapsuleBody - CapsuleHeader.HeaderSize;

+    if (CapsuleHeaderDataSize != 0) {

+      CapsuleHeaderData = (UINT8 *) malloc (CapsuleHeaderDataSize);

+      if (CapsuleHeaderData == NULL) {

+        Error (

+          NULL,

+          0,

+          0,

+          "failed to allocate memory to read in capsule header data",

+          "0x%X bytes",

+          CapsuleHeaderDataSize

+          );

+        goto Done;

+      }

+

+      fseek (InFptr, CapsuleHeader.HeaderSize, SEEK_SET);

+      if (fread (CapsuleHeaderData, CapsuleHeaderDataSize, 1, InFptr) != 1) {

+        Error (

+          NULL,

+          0,

+          0,

+          "failed to read capsule header data contents from file",

+          "0x%X bytes",

+          CapsuleHeaderDataSize

+          );

+        goto Done;

+      }

+      //

+      // ************************************************************************

+      //

+      // OEM HEADER

+      //

+      // ************************************************************************

+      //

+      if (CapsuleHeader.OffsetToOemDefinedHeader != 0) {

+        OemHeader = (EFI_CAPSULE_OEM_HEADER *) (CapsuleHeaderData + CapsuleHeader.OffsetToOemDefinedHeader - CapsuleHeader.HeaderSize);

+        printf ("  OEM Header\n");

+        printf (

+          "    GUID                %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",

+          OemHeader->OemGuid.Data1,

+          (UINT32) OemHeader->OemGuid.Data2,

+          (UINT32) OemHeader->OemGuid.Data3,

+          (UINT32) OemHeader->OemGuid.Data4[0],

+          (UINT32) OemHeader->OemGuid.Data4[1],

+          (UINT32) OemHeader->OemGuid.Data4[2],

+          (UINT32) OemHeader->OemGuid.Data4[3],

+          (UINT32) OemHeader->OemGuid.Data4[4],

+          (UINT32) OemHeader->OemGuid.Data4[5],

+          (UINT32) OemHeader->OemGuid.Data4[6],

+          (UINT32) OemHeader->OemGuid.Data4[7]

+          );

+        printf ("    Header size:        0x%X\n", OemHeader->HeaderSize);

+        printf ("    OEM data");

+        BPtr = (UINT8 *) (OemHeader + 1);

+        for (ByteCount = 0; ByteCount < OemHeader->HeaderSize - sizeof (EFI_CAPSULE_OEM_HEADER); ByteCount++) {

+          if ((ByteCount & 0x7) == 0) {

+            printf ("\n      ");

+          }

+

+          printf ("%02X ", (UINT32) *BPtr);

+          BPtr++;

+        }

+

+        printf ("\n");

+      }

+      //

+      // ************************************************************************

+      //

+      // Author, revision, short description, and long description information

+      //

+      // ************************************************************************

+      //

+      if (CapsuleHeader.OffsetToAuthorInformation != 0) {

+        if (DumpCapsuleHeaderStrings (

+              "Author information",

+              (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToAuthorInformation - CapsuleHeader.HeaderSize)

+              ) != STATUS_SUCCESS) {

+          goto Done;

+        }

+      }

+

+      if (CapsuleHeader.OffsetToRevisionInformation != 0) {

+        if (DumpCapsuleHeaderStrings (

+              "Revision information",

+              (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToRevisionInformation - CapsuleHeader.HeaderSize)

+              ) != STATUS_SUCCESS) {

+          goto Done;

+        }

+      }

+

+      if (CapsuleHeader.OffsetToShortDescription != 0) {

+        if (DumpCapsuleHeaderStrings (

+              "Short description",

+              (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToShortDescription - CapsuleHeader.HeaderSize)

+              ) != STATUS_SUCCESS) {

+          goto Done;

+        }

+      }

+

+      if (CapsuleHeader.OffsetToLongDescription != 0) {

+        if (DumpCapsuleHeaderStrings (

+              "Long description",

+              (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToLongDescription - CapsuleHeader.HeaderSize)

+              ) != STATUS_SUCCESS) {

+          goto Done;

+        }

+      }

+    }

+    //

+    // If it's not a split image, or it is a split image and this is the first in the series, then

+    // dump the cargo volume.

+    //

+    if ((!SplitImage) || (CapsuleHeader.SequenceNumber == 0)) {

+      printf ("  Cargo FV dump\n");

+      fseek (InFptr, CapsuleHeader.OffsetToCapsuleBody, SEEK_SET);

+      if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) != 1) {

+        Error (NULL, 0, 0, FileList->FileName, "failed to read cargo FV header");

+        goto Done;

+      }

+

+      printf ("    FV length           0x%X", FVHeader.FvLength);

+      if (FileSize - CapsuleHeader.OffsetToCapsuleBody != FVHeader.FvLength) {

+        if (!SplitImage) {

+          printf (" ERROR: expected 0x%X to jive with file size on disk", FileSize - CapsuleHeader.OffsetToCapsuleBody);

+        }

+      }

+

+      printf ("\n");

+      printf ("    Signature           0x%X ", FVHeader.Signature);

+      if (FVHeader.Signature == EFI_FVH_SIGNATURE) {

+        printf ("_FVH\n");

+      } else {

+        printf ("INVALID\n");

+      }

+

+      printf ("    FV header length    0x%X\n", (UINT32) FVHeader.HeaderLength);

+      printf ("    Revision            0x%X\n", (UINT32) FVHeader.Revision);

+      printf ("\n");

+    }

+

+    FileList = FileList->Next;

+  }

+

+Done:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+

+  if (CapsuleHeaderData != NULL) {

+    free (CapsuleHeaderData);

+  }

+#endif

+}

+

+static

+STATUS

+JoinCapsule (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Join split capsule images into a single image. This is the

+  support function for the -j command-line option.

+

+Arguments:

+  None.

+

+Returns:

+  STATUS_SUCCESS - no problems encountered

+

+--*/

+{

+#if 0

+  UINT32              Size;

+  FILE                *InFptr;

+  FILE                *OutFptr;

+  INT8                *Buffer;

+  FILE_LIST           *FileList;

+  STATUS              Status;

+  EFI_CAPSULE_HEADER  CapHdr;

+  EFI_CAPSULE_HEADER  *CapHdrPtr;

+  UINT32              SizeLeft;

+  UINT32              SequenceNumber;

+  //

+  // Must have at least two files for join mode

+  //

+  if ((mOptions.FileList == NULL) || (mOptions.FileList->Next == NULL)) {

+    Error (NULL, 0, 0, "must specify at least two file names to join", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // Open the output file

+  //

+  if ((OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+

+  FileList        = mOptions.FileList;

+  Buffer          = NULL;

+  SequenceNumber  = 0;

+  InFptr          = NULL;

+  SizeLeft        = 0;

+  while (FileList != NULL) {

+    if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) {

+      Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading");

+      goto FailDone;

+    }

+    //

+    // Allocate a buffer into which we can read the file.

+    //

+    fseek (InFptr, 0, SEEK_END);

+    Size = ftell (InFptr);

+    rewind (InFptr);

+    Buffer = (char *) malloc (Size);

+    if (Buffer == NULL) {

+      Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into");

+      goto FailDone;

+    }

+

+    CapHdrPtr = (EFI_CAPSULE_HEADER *) Buffer;

+    if (fread ((void *) Buffer, Size, 1, InFptr) != 1) {

+      Error (NULL, 0, 0, FileList->FileName, "failed to read file contents");

+      goto FailDone;

+    }

+    //

+    // Check the header for validity. Check size first.

+    //

+    if (Size < sizeof (EFI_CAPSULE_HEADER)) {

+      Error (NULL, 0, 0, FileList->FileName, "file size is insufficient for a capsule header");

+      goto FailDone;

+    }

+    //

+    // Check GUID

+    //

+    if (memcmp (&CapHdrPtr->CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) {

+      Error (NULL, 0, 0, FileList->FileName, "invalid capsule GUID");

+      goto FailDone;

+    }

+    //

+    // Check sequence number

+    //

+    if (CapHdrPtr->SequenceNumber != SequenceNumber) {

+      Error (

+        NULL,

+        0,

+        0,

+        FileList->FileName,

+        "invalid sequence number %d (expected %d)",

+        CapHdrPtr->SequenceNumber,

+        SequenceNumber

+        );

+      goto FailDone;

+    }

+    //

+    // If the first file, read save the capsule header

+    //

+    if (SequenceNumber == 0) {

+      memcpy (&CapHdr, CapHdrPtr, sizeof (EFI_CAPSULE_HEADER));

+      //

+      // Erase the InstanceId GUID

+      //

+      memset (&CapHdrPtr->InstanceId, 0, sizeof (EFI_GUID));

+      if (fwrite (Buffer, Size, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, FileList->FileName, "failed to write contents to output file");

+        goto FailDone;

+      }

+

+      if (CapHdr.CapsuleImageSize < Size) {

+        Error (NULL, 0, 0, FileList->FileName, "capsule image size in capsule header < image size");

+        goto FailDone;

+      }

+

+      SizeLeft = CapHdr.CapsuleImageSize - Size;

+    } else {

+      //

+      // Check the GUID against the first file's GUID

+      //

+      if (memcmp (&CapHdr.CapsuleGuid, &CapHdrPtr->CapsuleGuid, sizeof (EFI_GUID)) != 0) {

+        Error (NULL, 0, 0, FileList->FileName, "GUID does not match first file's GUID");

+        goto FailDone;

+      }

+      //

+      // Make sure we're not throwing out any header info

+      //

+      if (CapHdrPtr->OffsetToCapsuleBody > sizeof (EFI_CAPSULE_HEADER)) {

+        //

+        // Could be the split information, so just emit a warning

+        //

+        Warning (

+          NULL,

+          0,

+          0,

+          FileList->FileName,

+          "image appears to have additional capsule header information -- ignoring"

+          );

+      } else if (CapHdrPtr->OffsetToCapsuleBody < sizeof (EFI_CAPSULE_HEADER)) {

+        Error (NULL, 0, 0, FileList->FileName, "offset to capsule body in capsule header is insufficient");

+        goto FailDone;

+      }

+

+      if (fwrite (Buffer + CapHdrPtr->OffsetToCapsuleBody, Size - CapHdrPtr->OffsetToCapsuleBody, 1, OutFptr) != 1) {

+        Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");

+        goto FailDone;

+      }

+

+      if (SizeLeft < (Size - CapHdrPtr->OffsetToCapsuleBody)) {

+        Error (NULL, 0, 0, "sum of image sizes exceeds size specified in initial capsule header", NULL);

+        goto FailDone;

+      }

+      //

+      // printf ("FILE: %s OffsetToCapsuleBody=0x%X\n", FileList->FileName, CapHdrPtr->OffsetToCapsuleBody);

+      //

+      SizeLeft = SizeLeft - (Size - CapHdrPtr->OffsetToCapsuleBody);

+    }

+    //

+    // printf ("FILE: %s sizeleft=0x%X\n", FileList->FileName, SizeLeft);

+    //

+    fclose (InFptr);

+    InFptr = NULL;

+    free (Buffer);

+    Buffer    = NULL;

+    FileList  = FileList->Next;

+    SequenceNumber++;

+  }

+

+  if (SizeLeft) {

+    Error (NULL, 0, 0, "sum of capsule images is insufficient", "0x%X bytes missing", SizeLeft);

+    goto FailDone;

+  }

+

+  Status = STATUS_SUCCESS;

+  goto Done;

+FailDone:

+  Status = STATUS_ERROR;

+Done:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+  }

+

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+

+  return Status;

+

+#endif

+return STATUS_SUCCESS;

+}

+

+static

+STATUS

+DumpCapsuleHeaderStrings (

+  UINT8   *SectionName,

+  WCHAR   *Buffer

+  )

+/*++

+

+Routine Description:

+  Given a pointer to string data from a capsule header, dump

+  the strings.

+

+Arguments:

+  SectionName  - name of the capsule header section to which

+                 the string data pertains

+  Buffer       - pointer to string data from a capsule header

+

+Returns:

+  STATUS_SUCCESS - all went well

+

+--*/

+{

+  printf ("  %s\n", SectionName);

+  while (*Buffer) {

+    printf ("    Language: %S\n", Buffer);

+    while (*Buffer) {

+      Buffer++;

+    }

+

+    Buffer++;

+    while (*Buffer) {

+      if (wcslen (Buffer) > 60) {

+        printf ("      %.60S\n", Buffer);

+        Buffer += 60;

+      } else {

+        printf ("      %S\n", Buffer);

+        Buffer += wcslen (Buffer);

+      }

+    }

+

+    Buffer++;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+GetHexValue (

+  SOURCE_FILE  *SourceFile,

+  UINT32       *Value,

+  UINT32       NumDigits

+  )

+/*++

+

+Routine Description:

+  Scan a hex value from the input stream.

+  

+Arguments:

+  SourceFile   - input file contents

+  Value        - returned value

+  NumDigits    - number of digits to read

+

+Returns:

+  STATUS_SUCCESS - if NumDigits were read from the file

+  STATUS_ERROR   - otherwise

+

+  

+--*/

+{

+  WCHAR   *SaveFilePos;

+  UINT32  Digits;

+  WCHAR   Nibble;

+

+  SaveFilePos = SourceFile->FileBufferPtr;

+  *Value      = 0;

+  Digits      = NumDigits;

+  while (Digits > 0) {

+    Nibble = SourceFile->FileBufferPtr[0];

+    if ((Nibble >= UNICODE_0) && (Nibble <= UNICODE_9)) {

+      *Value = (*Value << 4) | (Nibble - UNICODE_0);

+    } else if ((Nibble >= UNICODE_A) && (Nibble <= UNICODE_F)) {

+      *Value = (*Value << 4) | (Nibble - UNICODE_A + 0x10);

+    } else if ((Nibble >= UNICODE_a) && (Nibble <= UNICODE_f)) {

+      *Value = (*Value << 4) | (Nibble - UNICODE_a + 0x10);

+    } else {

+      Error (

+        SourceFile->FileName,

+        SourceFile->LineNum,

+        0,

+        NULL,

+        "expected %d valid hex nibbles at %.20S",

+        NumDigits,

+        SaveFilePos

+        );

+      return STATUS_ERROR;

+    }

+

+    SourceFile->FileBufferPtr++;

+    Digits--;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *File

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  File  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  if ((UINT32) File->FileBufferPtr - (UINT32) File->FileBuffer >= File->FileSize) {

+    File->EndOfFile = TRUE;

+  }

+  //

+  // Reposition to the end of the file if we went beyond

+  //

+  if (File->EndOfFile) {

+    File->FileBufferPtr = File->FileBuffer + File->FileSize / sizeof (WCHAR);

+  }

+

+  return File->EndOfFile;

+}

+

+static

+void

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  SourceFile  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  while (!EndOfFile (SourceFile)) {

+    switch (*SourceFile->FileBufferPtr) {

+    case UNICODE_NULL:

+    case UNICODE_CR:

+    case UNICODE_SPACE:

+    case UNICODE_TAB:

+      SourceFile->FileBufferPtr++;

+      break;

+

+    case UNICODE_LF:

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      break;

+

+    default:

+      return ;

+    }

+  }

+}

+//

+// Parse a number. Possible format:

+//   1234

+//   1234k

+//   1234K

+//   1M

+//   1m

+//   0x100

+//

+static

+BOOLEAN

+GetNumber (

+  INT8    *Str,

+  UINT32  *Value

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  Str   - GC_TODO: add argument description

+  Value - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  UINT32  LValue;

+

+  *Value  = 0;

+  LValue  = 0;

+  if (!isdigit (Str[0])) {

+    return FALSE;

+  }

+  //

+  // Look for hex number

+  //

+  if ((Str[0] == '0') && (tolower (Str[1]) == 'x')) {

+    Str += 2;

+    if (Str[0] == 0) {

+      return FALSE;

+    }

+

+    while (Str[0]) {

+      if ((Str[0] >= '0') && (Str[0] <= '9')) {

+        LValue = (LValue << 4) | (Str[0] - '0');

+      } else if ((Str[0] >= 'A') && (Str[0] <= 'F')) {

+        LValue = (LValue << 4) | (Str[0] - 'A' + 0x10);

+      } else if ((Str[0] >= 'a') && (Str[0] <= 'f')) {

+        LValue = (LValue << 4) | (Str[0] - 'a' + 0x10);

+      } else {

+        break;

+      }

+

+      Str++;

+    }

+  } else {

+    LValue = atoi (Str);

+    while (isdigit (*Str)) {

+      Str++;

+    }

+  }

+  //

+  // If string left over, better be one character we recognize

+  //

+  if (Str[0]) {

+    if (Str[1]) {

+      return FALSE;

+    }

+

+    switch (Str[0]) {

+    case 'k':

+    case 'K':

+      LValue *= 1024;

+      break;

+

+    case 'm':

+    case 'M':

+      LValue *= 1024 * 1024;

+      break;

+

+    default:

+      return FALSE;

+    }

+  }

+

+  *Value = LValue;

+  return TRUE;

+}

+//

+// Process the command-line arguments

+//

+static

+STATUS

+ProcessArgs (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+

+  Processes command line arguments.

+

+Arguments:

+

+  Argc   - Number of command line arguments

+  Argv[] - Array of files input on command line  

+

+Returns:

+

+  STATUS_ERROR    - Function exited with an error

+  STATUS_SUCCESS  - Function executed successfully

+

+--*/

+{

+  FILE_LIST *NewFile;

+

+  FILE_LIST *LastFile;

+  SIZE_LIST *NewSize;

+  

+  NewFile = NULL;

+  NewSize = NULL;

+  

+  //

+  // Clear our globals

+  //

+  memset ((char *) &mOptions, 0, sizeof (mOptions));

+

+  //

+  // Skip program name

+  //

+  Argc--;

+  Argv++;

+

+  if (Argc == 0) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Process until no more options

+  //

+  while ((Argc > 0) && (Argv[0][0] == '-')) {

+    if (stricmp (Argv[0], "-script") == 0) {

+      //

+      // Check for one more arg

+      //

+      if (Argc > 1) {

+        //

+        // Save the file name

+        //

+        if (strlen (Argv[1]) >= sizeof (mOptions.ScriptFileName)) {

+          Error (NULL, 0, 0, NULL, "input script file name length exceeds internal buffer size");

+          

+          if (NewFile != NULL) {

+            free (NewFile);

+          }

+          if (NewSize != NULL) {

+            free (NewSize);

+          }

+          

+          return STATUS_ERROR;

+        }

+

+        strcpy (mOptions.ScriptFileName, Argv[1]);

+      } else {

+        Error (NULL, 0, 0, Argv[0], "missing script file name with option");

+        Usage ();

+        

+        if (NewFile != NULL) {

+          free (NewFile);

+        }

+        if (NewSize != NULL) {

+          free (NewSize);

+        }       

+

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+      //

+      // -o outfilename -- specify output file name (required)

+      //

+    } else if (stricmp (Argv[0], "-o") == 0) {

+      //

+      // check for one more arg

+      //

+      if (Argc > 1) {

+        //

+        // Try to open the file

+        //

+        // if ((mOptions.OutFptr = fopen (Argv[1], "wb")) == NULL) {

+        //  Error (NULL, 0, 0, Argv[1], "failed to open output file for writing");

+        //  return STATUS_ERROR;

+        // }

+        //

+        strcpy (mOptions.OutputFileName, Argv[1]);

+      } else {

+        Error (NULL, 0, 0, Argv[0], "missing output filename with option");

+        Usage ();

+        

+        if (NewFile != NULL) {

+          free (NewFile);

+        }

+        if (NewSize != NULL) {

+          free (NewSize);

+        }

+                

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-j") == 0) {

+      mOptions.JoinMode = TRUE;

+      //

+      // -split <size> option (multiple allowed)

+      //

+    } else if (stricmp (Argv[0], "-split") == 0) {

+      if (Argc > 1) {

+        NewSize = (SIZE_LIST *) malloc (sizeof (SIZE_LIST));

+        if (NewSize == NULL) {

+          Error (NULL, 0, 0, "memory allocation failure", NULL);

+

+          if (NewFile != NULL) {

+            free (NewFile);

+          }

+          if (NewSize != NULL) {

+            free (NewSize);

+          }

+          

+          return STATUS_ERROR;

+        }

+

+        memset (NewSize, 0, sizeof (SIZE_LIST));

+        //

+        // Get the size from the next arg, and then add this size

+        // to our size list

+        //

+        if (!GetNumber (Argv[1], &NewSize->Size)) {

+          Error (NULL, 0, 0, Argv[1], "invalid split size argument");

+

+          if (NewFile != NULL) {

+            free (NewFile);

+          }

+          if (NewSize != NULL) {

+            free (NewSize);

+          }       

+          

+          return STATUS_ERROR;

+        }

+

+        if (mOptions.SizeList == NULL) {

+          mOptions.SizeList     = NewSize;

+          mOptions.CurrentSize  = NewSize;

+        } else {

+          mOptions.LastSize->Next = NewSize;

+        }

+

+        mOptions.LastSize = NewSize;

+        free (NewSize);

+      } else {

+        Error (NULL, 0, 0, Argv[0], "missing size parameter with option");

+        Usage ();

+

+        if (NewFile != NULL) {

+          free (NewFile);

+        }

+        if (NewSize != NULL) {

+          free (NewSize);

+        }

+        

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;      

+    } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {

+      Usage ();

+      

+      if (NewFile != NULL) {

+        free (NewFile);

+      }

+      if (NewSize != NULL) {

+        free (NewSize);

+      }

+      

+      return STATUS_ERROR;

+      //

+      // Default minimum header

+      //

+    } else if (stricmp (Argv[0], "-dump") == 0) {

+      mOptions.Dump = TRUE;

+    } else if (stricmp (Argv[0], "-v") == 0) {

+      mOptions.Verbose = TRUE;

+    } else {

+      Error (NULL, 0, 0, Argv[0], "unrecognized option");

+      Usage ();

+      

+      if (NewFile != NULL) {

+        free (NewFile);

+      }

+      if (NewSize != NULL) {

+        free (NewSize);

+      }

+      

+      return STATUS_ERROR;

+    }

+

+    Argc--;

+    Argv++;

+  }

+  //

+  // Can't -j join files and -s split output capsule

+  //

+  if ((mOptions.SizeList != NULL) && (mOptions.JoinMode)) {

+    Error (NULL, 0, 0, "cannot specify both -j and -size", NULL);

+    

+    if (NewFile != NULL) {

+      free (NewFile);

+    }

+    if (NewSize != NULL) {

+      free (NewSize);

+    }

+    

+    return STATUS_ERROR;

+  }

+  //

+  // Must have specified an output file name if not -dump

+  //

+  if ((mOptions.Dump == 0) && (mOptions.OutputFileName[0] == 0)) {

+    Error (NULL, 0, 0, NULL, "-o OutputFileName must be specified");

+    Usage ();

+    

+    if (NewFile != NULL) {

+      free (NewFile);

+    }

+    if (NewSize != NULL) {

+      free (NewSize);

+    }

+    

+    return STATUS_ERROR;

+  }

+  //

+  // Rest of arguments are input files. The first one is a firmware

+  // volume image, and the rest are FFS files that are to be inserted

+  // into the firmware volume.

+  //

+  LastFile = NULL;

+  while (Argc > 0) {

+    NewFile = (FILE_LIST *) malloc (sizeof (FILE_LIST));

+    if (NewFile == NULL) {

+      Error (NULL, 0, 0, "memory allocation failure", NULL);

+

+      if (NewFile != NULL) {

+        free (NewFile);

+      }

+      if (NewSize != NULL) {

+        free (NewSize);

+      }

+    

+      return STATUS_ERROR;

+    }

+

+    memset ((char *) NewFile, 0, sizeof (FILE_LIST));

+    strcpy (NewFile->FileName, Argv[0]);

+    if (mOptions.FileList == NULL) {

+      mOptions.FileList = NewFile;

+    } else {

+      if (LastFile == NULL) {

+        LastFile = NewFile;

+      } else {

+        LastFile->Next = NewFile;

+      }      

+    }

+

+    LastFile = NewFile;

+    Argc--;

+    Argv++;

+  }

+

+  //

+  // Must have provided at least one file name

+  //

+  if (mOptions.FileList == NULL) {

+    Error (NULL, 0, 0, "must specify at least one file name", NULL);

+    Usage ();

+    

+    if (NewFile != NULL) {

+      free (NewFile);

+    }

+    if (NewSize != NULL) {

+      free (NewSize);

+    }

+    

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Print usage information for this utility.

+  

+Arguments:

+

+  None.

+

+Returns:

+

+  Nothing.

+  

+--*/

+{

+  int               Index;

+  static const char *Str[] = {

+    PROGRAM_NAME " -- create a capsule header",

+    "  Usage: "PROGRAM_NAME " {options} [CapsuleFV]",

+    //

+    // {FfsFileNames}",

+    //

+    "    Options include:",

+    "      -h or -?         for this help information",

+    "      -script fname    to take capsule header info from unicode script",

+    "                       file fname",

+    "      -o fname         write output to file fname (required)",

+    "      -split size      split capsule image into multiple output files",

+    "      -dump            to dump a capsule header",

+    "      -v               for verbose output\n",

+    "      -j               to join split capsule images into a single image",

+    "",

+    "    CapsuleFV is the name of an existing well-formed Tiano firmware",

+    "    volume file.",

+    //

+    // FfsFileNames are the names of one or more Tiano FFS files to",

+    // "    insert into the output capsule image.",

+    //

+    NULL

+  };

+  for (Index = 0; Str[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Str[Index]);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/GenCapsuleHdr/Makefile b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/Makefile
new file mode 100644
index 0000000..1979c3d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/Makefile
@@ -0,0 +1,75 @@
+#/*++

+#  

+#  Copyright (c)  2002 Intel Corporation. All rights reserved

+#  This software and associated documentation (if any) is furnished

+#  under a license and may only be used or copied in accordance

+#  with the terms of the license. Except as permitted by such

+#  license, no part of this software or documentation may be

+#  reproduced, stored in a retrieval system, or transmitted in any

+#  form or by any means without the express written consent of

+#  Intel Corporation.

+#  

+#  

+#  Module Name:

+#  

+#    Makefile

+#  

+#  Abstract:

+#  

+#    makefile for the GenCapsuleHdr utility.

+#    

+#--*/  

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+

+TARGET_NAME         = GenCapsuleHdr

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+SRC                 = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+ETO                 = $(TIANO_TOOLS_OUTPUT)

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+LIBS    = $(LIBS) "$(TIANO_TOOLS_OUTPUT)\Common.lib" ole32.lib

+

+OBJECTS = $(ETO)\$(TARGET_NAME).obj \

+          $(ETO)\CreateGuid.obj

+

+#

+# Compile each source file

+#

+$(ETO)\$(TARGET_NAME).obj : $(SRC)\$(TARGET_NAME).c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(SRC)\$(TARGET_NAME).c /Fo$@

+

+$(ETO)\CreateGuid.obj : $(SRC)\CreateGuid.c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(SRC)\CreateGuid.c /Fo$@

+

+#

+# Link the object files together

+#

+$(TARGET_EXE) : $(OBJECTS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

+

+clean:

diff --git a/edk2/Tools/Source/TianoTools/GenCapsuleHdr/build.xml b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/build.xml
new file mode 100644
index 0000000..8862307
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenCapsuleHdr/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenCapsuleHdr Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenCapsuleHdr"/>

+  <property name="FileSet" value="GenCapsuleHdr.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenDepex/DepexParser.c b/edk2/Tools/Source/TianoTools/GenDepex/DepexParser.c
new file mode 100644
index 0000000..9f0a0cb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenDepex/DepexParser.c
@@ -0,0 +1,903 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  DepexParser.c

+

+Abstract:

+

+  Validate Dependency Expression syntax

+  recursive descent Algorithm

+

+  The original BNF grammar(taken from "Pre EFI Initialization Core Interface Specification 

+  draft review 0.9") is thus:

+       <depex>    ::= BEFORE <guid> END

+                    | AFTER <guid> END

+                    | SOR <bool> END

+                    | <bool> END    

+       <bool>     ::= <bool> AND <term> 

+                    | <bool> OR <term>  

+                    | <term>            

+       <term>     ::= NOT <factor>      

+                    | <factor>          

+       <factor>   ::= <bool>            

+                    | TRUE 

+                    | FALSE 

+                    | GUID

+

+       <guid>     ::= '{' <hex32> ',' <hex16> ',' <hex16> ','

+                      <hex8> ',' <hex8> ',' <hex8> ',' <hex8> ',' 

+                      <hex8> ',' <hex8> ',' <hex8> ',' <hex8> '}'

+       <hex32>    ::= <hexprefix> <hexvalue>

+       <hex16>    ::= <hexprefix> <hexvalue>

+       <hex8>     ::= <hexprefix> <hexvalue>

+       <hexprefix>::= '0' 'x'

+                    | '0' 'X'

+       <hexvalue> ::= <hexdigit> <hexvalue>

+                    | <hexdigit>

+       <hexdigit> ::= [0-9]

+                    | [a-f]

+                    | [A-F]

+

+  After cleaning left recursive and parentheses supported, the BNF grammar used in this module is thus:

+       <depex>    ::= BEFORE <guid>

+                    | AFTER <guid>

+                    | SOR <bool>

+                    | <bool>

+       <bool>     ::= <term><rightbool>

+       <rightbool>::= AND <term><rightbool>

+                    | OR <term><rightbool>

+                    | ''

+       <term>     ::= NOT <factor>

+                    | <factor>

+       <factor>   ::= '('<bool>')'<rightfactor>

+                    | NOT <factor> <rightbool> <rightfactor>

+                    | TRUE <rightfactor>

+                    | FALSE <rightfactor>

+                    | END <rightfactor>

+                    | <guid> <rightfactor>                    

+       <rightfactor> ::=AND <term><rightbool> <rightfactor>   

+                    | OR <term><rightbool> <rightfactor>                 

+                    | ''

+       <guid>     ::= '{' <hex32> ',' <hex16> ',' <hex16> ','

+                      <hex8> ',' <hex8> ',' <hex8> ',' <hex8> ',' 

+                      <hex8> ',' <hex8> ',' <hex8> ',' <hex8> '}'

+       <hex32>    ::= <hexprefix> <hexvalue>

+       <hex16>    ::= <hexprefix> <hexvalue>

+       <hex8>     ::= <hexprefix> <hexvalue>

+       <hexprefix>::= '0' 'x'

+                    | '0' 'X'

+       <hexvalue> ::= <hexdigit> <hexvalue>

+                    | <hexdigit>

+       <hexdigit> ::= [0-9]

+                    | [a-f]

+                    | [A-F]

+ 

+  Note: 1. There's no precedence in operators except parentheses;

+        2. For hex32, less and equal than 8 bits is valid, more than 8 bits is invalid.

+           Same constraint for hex16 is 4, hex8 is 2. All hex should contains at least 1 bit.

+        3. "<factor>   ::= '('<bool>')'<rightfactor>" is added to support parentheses;

+        4. "<factor>   ::= GUID" is changed to "<factor>   ::= <guid>";

+        5. "DEPENDENCY_END" is the terminal of the expression. But it has been filtered by caller. 

+           During parsing, "DEPENDENCY_END" will be treated as illegal factor;

+    

+  This code should build in any environment that supports a standard C-library w/ string

+  operations and File I/O services.

+

+  As an example of usage, consider the following:

+

+  The input string could be something like: 

+    

+      NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72,

+        0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69,

+        0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27,

+        0x3f, 0xc1, 0x4d } AND

+

+  It's invalid for an extra "AND" in the end.

+

+  Complies with Tiano C Coding Standards Document, version 0.33, 16 Aug 2001.

+

+--*/

+

+#include "DepexParser.h"

+

+BOOLEAN

+ParseBool (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  );

+

+BOOLEAN

+ParseTerm (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  );

+

+BOOLEAN

+ParseRightBool (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  );

+

+BOOLEAN

+ParseFactor (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  );

+

+VOID

+LeftTrim (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Left trim the space, '\n' and '\r' character in string.

+  The space at the end does not need trim.

+

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  None

+

+

+--*/

+{

+  while

+  (

+    ((*Pindex) < (Pbegin + length)) &&

+    ((strncmp (*Pindex, " ", 1) == 0) || (strncmp (*Pindex, "\n", 1) == 0) || (strncmp (*Pindex, "\r", 1) == 0))

+  ) {

+    (*Pindex)++;

+  }

+}

+

+BOOLEAN

+ParseHexdigit (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse Hex bit in dependency expression.  

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    Length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If parses a valid hex bit, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  //

+  // <hexdigit> ::= [0-9] | [a-f] | [A-F]

+  //

+  if (((**Pindex) >= '0' && (**Pindex) <= '9') ||

+      ((**Pindex) >= 'a' && (**Pindex) <= 'f') ||

+      ((**Pindex) >= 'A' && (**Pindex) <= 'F')

+      ) {

+    (*Pindex)++;

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseHex32 (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse Hex32 in dependency expression.  

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    Length of the string

+  Pindex    The pointer of point to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If parses a valid hex32, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT32 Index;

+  INT8  *Pin;

+

+  Index = 0;

+  Pin   = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) {

+    return FALSE;

+  }

+  (*Pindex) += 2;

+

+  while (ParseHexdigit (Pbegin, length, Pindex)) {

+    Index++;

+  }

+

+  if (Index > 0 && Index <= 8) {

+    return TRUE;

+  } else {

+    *Pindex = Pin;

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseHex16 (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse Hex16 in dependency expression.  

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    Length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If parses a valid hex16, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  int   Index;

+  INT8  *Pin;

+

+  Index = 0;

+  Pin   = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) {

+    return FALSE;

+  }

+  (*Pindex) += 2;

+

+  while (ParseHexdigit (Pbegin, length, Pindex)) {

+    Index++;

+  }

+

+  if (Index > 0 && Index <= 4) {

+    return TRUE;

+  } else {

+    *Pindex = Pin;

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseHex8 (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse Hex8 in dependency expression.  

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    Length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If parses a valid hex8, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  int   Index;

+  INT8  *Pin;

+

+  Index = 0;

+  Pin   = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) {

+    return FALSE;

+  }

+  (*Pindex) += 2;

+

+  while (ParseHexdigit (Pbegin, length, Pindex)) {

+    Index++;

+  }

+

+  if (Index > 0 && Index <= 2) {

+    return TRUE;

+  } else {

+    *Pindex = Pin;

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseGuid (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse guid in dependency expression.

+  There can be any number of spaces between '{' and hexword, ',' and hexword, 

+  hexword and ',', hexword and '}'. The hexword include hex32, hex16 and hex8.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If parses a valid guid, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT32 Index;

+  INT8  *Pin;

+  Pin = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+  if (strncmp (*Pindex, "{", 1) != 0) {

+    return FALSE;

+  }

+  (*Pindex)++;

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (!ParseHex32 (Pbegin, length, Pindex)) {

+    *Pindex = Pin;

+    return FALSE;

+  }

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (strncmp (*Pindex, ",", 1) != 0) {

+    return FALSE;

+  } else {

+    (*Pindex)++;

+  }

+

+  for (Index = 0; Index < 2; Index++) {

+    LeftTrim (Pbegin, length, Pindex);

+    if (!ParseHex16 (Pbegin, length, Pindex)) {

+      *Pindex = Pin;

+      return FALSE;

+    }

+

+    LeftTrim (Pbegin, length, Pindex);

+    if (strncmp (*Pindex, ",", 1) != 0) {

+      return FALSE;

+    } else {

+      (*Pindex)++;

+    }

+  }

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (strncmp (*Pindex, "{", 1) != 0) {

+    return FALSE;

+  }

+  (*Pindex)++;

+

+  for (Index = 0; Index < 7; Index++) {

+    LeftTrim (Pbegin, length, Pindex);

+    if (!ParseHex8 (Pbegin, length, Pindex)) {

+      *Pindex = Pin;

+      return FALSE;

+    }

+

+    LeftTrim (Pbegin, length, Pindex);

+    if (strncmp (*Pindex, ",", 1) != 0) {

+      return FALSE;

+    } else {

+      (*Pindex)++;

+    }

+  }

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (!ParseHex8 (Pbegin, length, Pindex)) {

+    *Pindex = Pin;

+    return FALSE;

+  }

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (strncmp (*Pindex, "}", 1) != 0) {

+    return FALSE;

+  } else {

+    (*Pindex)++;

+  }

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (strncmp (*Pindex, "}", 1) != 0) {

+    return FALSE;

+  } else {

+    (*Pindex)++;

+  }

+

+  return TRUE;

+}

+

+BOOLEAN

+ParseRightFactor (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse rightfactor in bool expression.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If string is a valid rightfactor expression, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT8  *Pin;

+

+  Pin = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  //

+  // <rightfactor> ::=AND <term> <rightbool> <rightfactor>

+  //

+  if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {

+    *Pindex += strlen (OPERATOR_AND);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseTerm (Pbegin, length, Pindex)) {

+      LeftTrim (Pbegin, length, Pindex);

+

+      if (ParseRightBool (Pbegin, length, Pindex)) {

+        LeftTrim (Pbegin, length, Pindex);

+        if (ParseRightFactor (Pbegin, length, Pindex)) {

+          return TRUE;

+        } else {

+          *Pindex = Pin;

+        }

+      } else {

+        *Pindex = Pin;

+      }

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <rightfactor> ::=OR <term> <rightbool> <rightfactor>

+  //

+  if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {

+    *Pindex += strlen (OPERATOR_OR);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseTerm (Pbegin, length, Pindex)) {

+      LeftTrim (Pbegin, length, Pindex);

+

+      if (ParseRightBool (Pbegin, length, Pindex)) {

+        LeftTrim (Pbegin, length, Pindex);

+        if (ParseRightFactor (Pbegin, length, Pindex)) {

+          return TRUE;

+        } else {

+          *Pindex = Pin;

+        }

+      } else {

+        *Pindex = Pin;

+      }

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <rightfactor> ::= ''

+  //

+  *Pindex = Pin;

+  return TRUE;

+}

+

+BOOLEAN

+ParseRightBool (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse rightbool in bool expression.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If string is a valid rightbool expression, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT8  *Pin;

+

+  Pin = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  //

+  // <rightbool>::= AND <term><rightbool>

+  //

+  if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {

+    *Pindex += strlen (OPERATOR_AND);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseTerm (Pbegin, length, Pindex)) {

+      LeftTrim (Pbegin, length, Pindex);

+

+      if (ParseRightBool (Pbegin, length, Pindex)) {

+        return TRUE;

+      } else {

+        *Pindex = Pin;

+      }

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <rightbool>::=  OR <term><rightbool>

+  //

+  if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {

+    *Pindex += strlen (OPERATOR_OR);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseTerm (Pbegin, length, Pindex)) {

+      LeftTrim (Pbegin, length, Pindex);

+

+      if (ParseRightBool (Pbegin, length, Pindex)) {

+        return TRUE;

+      } else {

+        *Pindex = Pin;

+      }

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <rightbool>::= ''

+  //

+  *Pindex = Pin;

+  return TRUE;

+}

+

+BOOLEAN

+ParseFactor (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse factor in bool expression.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If string is a valid factor, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT8  *Pin;

+

+  Pin = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  //

+  // <factor>   ::= '('<bool>')'<rightfactor>

+  //

+  if (strncmp (*Pindex, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {

+    *Pindex += strlen (OPERATOR_LEFT_PARENTHESIS);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (!ParseBool (Pbegin, length, Pindex)) {

+      *Pindex = Pin;

+    } else {

+      LeftTrim (Pbegin, length, Pindex);

+

+      if (strncmp (*Pindex, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {

+        *Pindex += strlen (OPERATOR_RIGHT_PARENTHESIS);

+        LeftTrim (Pbegin, length, Pindex);

+

+        if (ParseRightFactor (Pbegin, length, Pindex)) {

+          return TRUE;

+        } else {

+          *Pindex = Pin;

+        }

+      }

+    }

+  }

+  //

+  // <factor>   ::= NOT <factor> <rightbool> <rightfactor>

+  //

+  if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {

+    *Pindex += strlen (OPERATOR_NOT);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseFactor (Pbegin, length, Pindex)) {

+      LeftTrim (Pbegin, length, Pindex);

+

+      if (ParseRightBool (Pbegin, length, Pindex)) {

+        LeftTrim (Pbegin, length, Pindex);

+

+        if (ParseRightFactor (Pbegin, length, Pindex)) {

+          return TRUE;

+        } else {

+          *Pindex = Pin;

+        }

+      } else {

+        *Pindex = Pin;

+      }

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <factor>   ::= TRUE <rightfactor>

+  //

+  if (strncmp (*Pindex, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {

+    *Pindex += strlen (OPERATOR_TRUE);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseRightFactor (Pbegin, length, Pindex)) {

+      return TRUE;

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <factor>   ::= FALSE <rightfactor>

+  //

+  if (strncmp (*Pindex, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {

+    *Pindex += strlen (OPERATOR_FALSE);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseRightFactor (Pbegin, length, Pindex)) {

+      return TRUE;

+    } else {

+      *Pindex = Pin;

+    }

+  }

+  //

+  // <factor>   ::= <guid> <rightfactor>

+  //

+  if (ParseGuid (Pbegin, length, Pindex)) {

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (ParseRightFactor (Pbegin, length, Pindex)) {

+      return TRUE;

+    } else {

+      *Pindex = Pin;

+      return FALSE;

+    }

+  } else {

+    *Pindex = Pin;

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseTerm (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse term in bool expression.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If string is a valid term, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT8  *Pin;

+

+  Pin = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  //

+  // <term>     ::= NOT <factor>

+  //

+  if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {

+    *Pindex += strlen (OPERATOR_NOT);

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (!ParseFactor (Pbegin, length, Pindex)) {

+      *Pindex = Pin;

+    } else {

+      return TRUE;

+    }

+  }

+  //

+  // <term>     ::=<factor>

+  //

+  if (ParseFactor (Pbegin, length, Pindex)) {

+    return TRUE;

+  } else {

+    *Pindex = Pin;

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseBool (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length,

+  IN OUT  INT8      **Pindex

+  )

+/*++

+

+Routine Description:

+

+  Parse bool expression.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+  Pindex    The pointer of pointer to the next parse character in the string

+

+Returns:

+

+  BOOLEAN   If string is a valid bool expression, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  INT8  *Pin;

+  Pin = *Pindex;

+  LeftTrim (Pbegin, length, Pindex);

+

+  if (ParseTerm (Pbegin, length, Pindex)) {

+    LeftTrim (Pbegin, length, Pindex);

+

+    if (!ParseRightBool (Pbegin, length, Pindex)) {

+      *Pindex = Pin;

+      return FALSE;

+    } else {

+      return TRUE;

+    }

+  } else {

+    *Pindex = Pin;

+    return FALSE;

+  }

+}

+

+BOOLEAN

+ParseDepex (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length

+  )

+/*++

+

+Routine Description:

+

+  Parse whole dependency expression.

+

+Arguments:

+

+  Pbegin    The pointer to the string  

+  length    length of the string

+

+Returns:

+

+  BOOLEAN   If string is a valid dependency expression, return TRUE, otherwise FALSE

+

+

+--*/

+{

+  BOOLEAN Result;

+  INT8    **Pindex;

+  INT8    *temp;

+

+  Result  = FALSE;

+  temp    = Pbegin;

+  Pindex  = &temp;

+

+  LeftTrim (Pbegin, length, Pindex);

+  if (strncmp (*Pindex, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {

+    (*Pindex) += strlen (OPERATOR_BEFORE);

+    Result = ParseGuid (Pbegin, length, Pindex);

+

+  } else if (strncmp (*Pindex, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {

+    (*Pindex) += strlen (OPERATOR_AFTER);

+    Result = ParseGuid (Pbegin, length, Pindex);

+

+  } else if (strncmp (*Pindex, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {

+    (*Pindex) += strlen (OPERATOR_SOR);

+    Result = ParseBool (Pbegin, length, Pindex);

+

+  } else {

+    Result = ParseBool (Pbegin, length, Pindex);

+

+  }

+

+  LeftTrim (Pbegin, length, Pindex);

+  return (BOOLEAN) (Result && (*Pindex) >= (Pbegin + length));

+}

diff --git a/edk2/Tools/Source/TianoTools/GenDepex/DepexParser.h b/edk2/Tools/Source/TianoTools/GenDepex/DepexParser.h
new file mode 100644
index 0000000..29e0884
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenDepex/DepexParser.h
@@ -0,0 +1,26 @@
+/*++

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:  

+          GenDepex.h

+

+  Abstract:

+          This file contains the relevant declarations required

+          to generate a binary Dependency File

+

+  Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.

+

+--*/

+

+// TODO: fix comment to set correct module name: DepexParser.h

+#ifndef _EFI_DEPEX_PARSER_H_

+#define _EFI_DEPEX_PARSER_H_

+#include "GenDepex.h"

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenDepex/GenDepex.c b/edk2/Tools/Source/TianoTools/GenDepex/GenDepex.c
new file mode 100644
index 0000000..608e27e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenDepex/GenDepex.c
@@ -0,0 +1,928 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenDepex.c

+

+Abstract:

+

+  Generate Dependency Expression ("GenDepex")

+

+  Infix to Postfix Algorithm

+

+  This code has been scrubbed to be free of having any EFI core tree dependencies.

+  It should build in any environment that supports a standard C-library w/ string

+  operations and File I/O services.

+

+  As an example of usage, consider the following:

+

+  The input user file could be something like "Sample.DXS" whose contents are

+

+    #include "Tiano.h"

+

+    DEPENDENCY_START

+      NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL) 

+        OR EFI_PXE_BASE_CODE_PROTOCOL

+    DEPENDENCY_END

+

+  This file is then washed through the C-preprocessor, viz.,

+

+    cl /EP Sample.DXS > Sample.TMP1

+

+  This yields the following file "Sample.TMP1" whose contents are

+

+    DEPENDENCY_START

+      NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72,

+        0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69,

+        0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27,

+        0x3f, 0xc1, 0x4d }

+    DEPENDENCY_END

+

+  This file, in turn, will be fed into the utility, viz.,

+

+    GenDepex Sample.TMP1 Sample.TMP2

+

+  With a file that is 55 bytes long:

+

+     55 bytes for the grammar binary

+        PUSH opcode         - 1  byte

+        GUID Instance       - 16 bytes

+        PUSH opcode         - 1  byte

+        GUID Instance       - 16 bytes

+        AND opcode          - 1  byte

+        NOT opcode          - 1  byte

+        PUSH opcode         - 1  byte

+        GUID Instance       - 16 bytes

+        OR opcode           - 1  byte

+        END opcode          - 1  byte

+

+  The file "Sample.TMP2" could be fed via a Section-builder utility 

+  (GenSection) that would be used for the creation of a dependency

+  section file (.DPX) which in turn would be used by a generate FFS

+  utility (GenFfsFile) to produce a DXE driver/core (.DXE) or 

+  a DXE application (.APP) file.

+

+  Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.

+

+--*/

+

+#include "GenDepex.h"

+

+#define TOOL_NAME "GenDepex"

+

+extern

+ParseDepex (

+  IN      INT8      *Pbegin,

+  IN      UINT32    length

+  );

+

+VOID

+PrintGenDepexUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "%s, Tiano Dependency Expression Generation Utility. Version %d.%d.\n",

+    UTILITY_NAME,

+    UTILITY_MAJOR_VERSION,

+    UTILITY_MINOR_VERSION

+    );

+  printf ("Copyright (C) 1996-2002 Intel Corporation.  All rights reserved.\n\n");

+}

+

+VOID

+PrintGenDepexUsageInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "Usage: %s -I <INFILE> -O <OUTFILE> [-P <Optional Boundary for padding up>] \n",

+    UTILITY_NAME

+    );

+  printf (" Where:\n");

+  printf ("  <INFILE> is the input pre-processed dependency text files name.\n");

+  printf ("  <OUTFILE> is the output binary dependency files name.\n");

+  printf ("  <Optional Boundary for padding up> is the padding integer value.\n");

+  printf ("    This is the boundary to align the output file size to.\n");

+}

+

+DEPENDENCY_OPCODE

+PopOpCode (

+  IN OUT VOID **Stack

+  )

+/*++

+

+Routine Description:

+

+  Pop an element from the Opcode stack.

+

+Arguments:

+

+  Stack               Current top of the OpCode stack location

+

+Returns:

+

+  DEPENDENCY_OPCODE   OpCode at the top of the OpCode stack.

+  Stack               New top of the OpCode stack location

+

+

+--*/

+{

+  DEPENDENCY_OPCODE *OpCodePtr;

+

+  OpCodePtr = *Stack;

+  OpCodePtr--;

+  *Stack = OpCodePtr;

+  return *OpCodePtr;

+}

+

+VOID

+PushOpCode (

+  IN OUT  VOID                **Stack,

+  IN      DEPENDENCY_OPCODE   OpCode

+  )

+/*++

+

+Routine Description:

+

+  Push an element onto the Opcode Stack

+

+Arguments:

+

+  Stack     Current top of the OpCode stack location

+  OpCode    OpCode to push onto the stack

+

+Returns:

+

+  Stack     New top of the OpCode stack location

+

+--*/

+{

+  DEPENDENCY_OPCODE *OpCodePtr;

+

+  OpCodePtr   = *Stack;

+  *OpCodePtr  = OpCode;

+  OpCodePtr++;

+  *Stack = OpCodePtr;

+}

+

+EFI_STATUS

+GenerateDependencyExpression (

+  IN     FILE           *InFile,

+  IN OUT FILE           *OutFile,

+  IN     UINT8          Padding  OPTIONAL

+  )

+/*++

+

+Routine Description:

+

+  This takes the pre-compiled dependency text file and 

+  converts it into a binary dependency file.

+

+  The BNF for the dependency expression is as follows 

+  (from the DXE 1.0 Draft specification).

+

+  The inputted BNF grammar is thus:

+    <depex> ::= sor <dep> | 

+                before GUID <dep> | 

+                after GUID <dep> | 

+                <bool>

+

+    <dep> ::=   <bool> |

+

+    <bool> ::=  <bool> and <term> | 

+                <bool> or <term> | 

+                <term>

+

+    <term> ::=  not <factor> | 

+                <factor>

+

+    <factor> ::= ( <bool> ) | 

+                 <term> <term> | 

+                 GUID | 

+                 <boolval>

+

+    <boolval> ::= true | 

+                  false

+

+  The outputed binary grammer is thus:

+    <depex> ::= sor <dep> | 

+                before <depinst> <dep> | 

+                after <depinst> <dep> | 

+                <bool>

+

+    <dep> ::=   <bool> |

+

+    <bool> ::=  <bool> and <term> | 

+                <bool> or <term> | <term>

+

+    <term> ::=  not <factor> | 

+                <factor>

+

+    <factor> ::= ( <bool> ) | 

+                 <term> <term> | 

+                 <boolval> | 

+                 <depinst> | 

+                 <termval>

+

+    <boolval> ::= true | 

+                  false

+

+    <depinst> ::= push GUID

+

+    <termval> ::= end

+

+  BugBug: A correct grammer is parsed correctly. A file that violates the

+          grammer may parse when it should generate an error. There is some

+          error checking and it covers most of the case when it's an include

+          of definition issue. An ill formed expresion may not be detected.

+

+Arguments:

+

+  InFile -  Input pre-compiled text file of the dependency expression.

+            This needs to be in ASCII.

+            The file pointer can not be NULL.

+

+  OutFile - Binary dependency file.

+            The file pointer can not be NULL.

+

+  Padding - OPTIONAL integer value to pad the output file to.

+

+

+Returns:

+

+  EFI_SUCCESS             The function completed successfully.

+  EFI_INVALID_PARAMETER   One of the parameters in the text file was invalid.

+  EFI_OUT_OF_RESOURCES    Unable to allocate memory.

+  EFI_ABORTED             An misc error occurred.

+

+--*/

+{

+  INT8              *Ptrx;

+  INT8              *Pend;

+  INT8              *EvaluationStack;

+  INT8              *StackPtr;

+  INT8              *Buffer;

+  INT8              Line[LINESIZE];

+  UINTN             Index;

+  UINTN             OutFileSize;

+  UINTN             FileSize;

+  UINTN             Results;

+  BOOLEAN           NotDone;

+  BOOLEAN           Before_Flag;

+  BOOLEAN           After_Flag;

+  BOOLEAN           Dep_Flag;

+  BOOLEAN           SOR_Flag;

+  EFI_GUID          Guid;

+  UINTN             ArgCountParsed;

+  DEPENDENCY_OPCODE Opcode;

+

+  Before_Flag = FALSE;

+  After_Flag  = FALSE;

+  Dep_Flag    = FALSE;

+  SOR_Flag    = FALSE;

+

+  memset (Line, 0, LINESIZE);

+

+  OutFileSize     = 0;

+

+  EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE);

+

+  if (EvaluationStack != NULL) {

+    StackPtr = EvaluationStack;

+  } else {

+    printf ("Unable to allocate memory to EvaluationStack - Out of resources\n");

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Results = (UINTN) fseek (InFile, 0, SEEK_END);

+

+  if (Results != 0) {

+    printf ("FSEEK failed - Aborted\n");

+    return EFI_ABORTED;

+  }

+

+  FileSize = ftell (InFile);

+

+  if (FileSize == -1L) {

+    printf ("FTELL failed - Aborted\n");

+    return EFI_ABORTED;

+  }

+

+  Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE);

+

+  if (Buffer == NULL) {

+    printf ("Unable to allocate memory to Buffer - Out of resources\n");

+    free (EvaluationStack);

+

+    Results = (UINTN) fclose (InFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    Results = (UINTN) fclose (OutFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Results = (UINTN) fseek (InFile, 0, SEEK_SET);

+

+  if (Results != 0) {

+    printf ("FSEEK failed - Aborted\n");

+    return EFI_ABORTED;

+  }

+

+  fread (Buffer, FileSize, 1, InFile);

+

+  Ptrx    = Buffer;

+  Pend    = Ptrx + FileSize - strlen (DEPENDENCY_END);

+  Index   = FileSize;

+

+  NotDone = TRUE;

+  while ((Index--) && NotDone) {

+

+    if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {

+      NotDone = FALSE;

+    } else {

+      Pend--;

+    }

+  }

+

+  if (NotDone) {

+    printf ("Couldn't find end string %s\n", DEPENDENCY_END);

+

+    Results = (UINTN) fclose (InFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    Results = (UINTN) fclose (OutFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    free (Buffer);

+    free (EvaluationStack);

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Index   = FileSize;

+

+  NotDone = TRUE;

+  while ((Index--) && NotDone) {

+

+    if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) {

+      Ptrx += sizeof (DEPENDENCY_START);

+      NotDone = FALSE;

+      //

+      // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)?

+      //

+    } else {

+      Ptrx++;

+    }

+  }

+

+  if (NotDone) {

+    printf ("Couldn't find start string %s\n", DEPENDENCY_START);

+

+    Results = (UINTN) fclose (InFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    Results = (UINTN) fclose (OutFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    free (Buffer);

+    free (EvaluationStack);

+

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  //  validate the syntax of expression

+  //

+  if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) {

+    printf ("The syntax of expression is wrong\n");

+

+    Results = (UINTN) fclose (InFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    Results = (UINTN) fclose (OutFile);

+    if (Results != 0) {

+      printf ("FCLOSE failed\n");

+    }

+

+    free (Buffer);

+    free (EvaluationStack);

+

+    return EFI_INVALID_PARAMETER;

+  }

+

+  NotDone = TRUE;

+

+  while ((Index--) && NotDone) {

+

+    if (*Ptrx == ' ') {

+      Ptrx++;

+    } else if (*Ptrx == '\n' || *Ptrx == '\r') {

+      Ptrx++;

+    } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {

+      //

+      //  Checks for some invalid dependencies

+      //

+      if (Before_Flag) {

+

+        printf ("A BEFORE operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (After_Flag) {

+

+        printf ("An AFTER operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (SOR_Flag) {

+

+        printf ("Another SOR operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (Dep_Flag) {

+

+        printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else {

+        //

+        //  BUGBUG - This was not in the spec but is in the CORE code

+        //  An OPERATOR_SOR has to be first - following the DEPENDENCY_START

+        //

+        fputc (EFI_DEP_SOR, OutFile);

+        OutFileSize++;

+        Ptrx += sizeof (OPERATOR_SOR);

+        SOR_Flag = TRUE;

+

+      }

+    } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {

+      //

+      //  Checks for some invalid dependencies

+      //

+      if (Before_Flag) {

+

+        printf ("Another BEFORE operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (After_Flag) {

+

+        printf ("An AFTER operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (SOR_Flag) {

+

+        printf ("A SOR operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (Dep_Flag) {

+

+        printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else {

+        fputc (EFI_DEP_BEFORE, OutFile);

+        OutFileSize++;

+        Ptrx += sizeof (OPERATOR_BEFORE);

+        Before_Flag = TRUE;

+      }

+    } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {

+      //

+      //  Checks for some invalid dependencies

+      //

+      if (Before_Flag) {

+

+        printf ("A BEFORE operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (After_Flag) {

+

+        printf ("Another AFTER operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (SOR_Flag) {

+

+        printf ("A SOR operator was detected.\n");

+        printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else if (Dep_Flag) {

+

+        printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n");

+        return EFI_INVALID_PARAMETER;

+

+      } else {

+        fputc (EFI_DEP_AFTER, OutFile);

+        OutFileSize++;

+        Ptrx += sizeof (OPERATOR_AFTER);

+        Dep_Flag    = TRUE;

+        After_Flag  = TRUE;

+      }

+    } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {

+      while (StackPtr != EvaluationStack) {

+        Opcode = PopOpCode ((VOID **) &StackPtr);

+        if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {

+          fputc (Opcode, OutFile);

+          OutFileSize++;

+        } else {

+          PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);

+          break;

+        }

+      }

+

+      PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND);

+      Ptrx += sizeof (OPERATOR_AND);

+      Dep_Flag = TRUE;

+

+    } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {

+      while (StackPtr != EvaluationStack) {

+        Opcode = PopOpCode ((VOID **) &StackPtr);

+        if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {

+          fputc (Opcode, OutFile);

+          OutFileSize++;

+        } else {

+          PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);

+          break;

+        }

+      }

+

+      PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR);

+      Ptrx += sizeof (OPERATOR_OR);

+      Dep_Flag = TRUE;

+

+    } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {

+      while (StackPtr != EvaluationStack) {

+        Opcode = PopOpCode ((VOID **) &StackPtr);

+        if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {

+          fputc (Opcode, OutFile);

+          OutFileSize++;

+        } else {

+          PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);

+          break;

+        }

+      }

+

+      PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT);

+      Ptrx += sizeof (OPERATOR_NOT);

+      Dep_Flag = TRUE;

+

+    } else if (*Ptrx == '\t') {

+

+      printf ("File contains tabs. This violates the coding standard\n");

+      return EFI_INVALID_PARAMETER;

+

+    } else if (*Ptrx == '\n') {

+      //

+      // Skip the newline character in the file

+      //

+      Ptrx++;

+

+    } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {

+      PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);

+

+      Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS);

+      Dep_Flag = TRUE;

+

+    } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {

+      while (StackPtr != EvaluationStack) {

+        Opcode = PopOpCode ((VOID **) &StackPtr);

+        if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {

+          fputc (Opcode, OutFile);

+          OutFileSize++;

+        } else {

+          break;

+        }

+      }

+

+      Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS);

+      Dep_Flag = TRUE;

+

+    } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {

+

+      fputc (EFI_DEP_TRUE, OutFile);

+

+      OutFileSize++;

+

+      //

+      // OutFileSize += sizeof (EFI_DEP_TRUE);

+      //

+      Dep_Flag = TRUE;

+

+      Ptrx += strlen (OPERATOR_TRUE);

+

+    } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {

+

+      fputc (EFI_DEP_FALSE, OutFile);

+

+      OutFileSize++;

+

+      //

+      // OutFileSize += sizeof (EFI_DEP_FALSE);

+      //

+      Dep_Flag = TRUE;

+

+      Ptrx += strlen (OPERATOR_FALSE);

+

+    } else if (*Ptrx == '{') {

+      Ptrx++;

+

+      if (*Ptrx == ' ') {

+        Ptrx++;

+      }

+

+      {

+        int byte_index;

+        // This is an array of UINT32s. sscanf will trash memory

+        // if you try to read into a UINT8 with a %x formatter.

+        UINT32 Guid_Data4[8];

+

+        ArgCountParsed = sscanf (

+                         Ptrx,

+            "%x, %x, %x, { %x, %x, %x, %x, %x, %x, %x, %x }",

+                         &Guid.Data1,

+                         &Guid.Data2,

+                         &Guid.Data3,

+                         &Guid_Data4[0],

+                         &Guid_Data4[1],

+                         &Guid_Data4[2],

+                         &Guid_Data4[3],

+                         &Guid_Data4[4],

+                         &Guid_Data4[5],

+                         &Guid_Data4[6],

+                         &Guid_Data4[7]

+                         );

+        

+        // Now we can copy the 32 bit ints into the GUID.

+        for (byte_index=0; byte_index<8; byte_index++) {

+          Guid.Data4[byte_index] = (UINT8) Guid_Data4[byte_index];

+        }

+      }

+

+      if (ArgCountParsed != 11) {

+        printf ("We have found an illegal GUID\n");

+        printf ("Fix your depex\n");

+        exit (-1);

+      }

+

+      while (*Ptrx != '}') {

+        Ptrx++;

+      }

+

+	  Ptrx++;

+      while (*Ptrx != '}') {

+        Ptrx++;

+      }

+	  //

+      // Absorb the closing }

+      //

+      Ptrx++;

+

+      //

+      // Don't provide a PUSH Opcode for the Before and After case

+      //

+      if ((!Before_Flag) && (!After_Flag)) {

+        fputc (EFI_DEP_PUSH, OutFile);

+        OutFileSize++;

+      }

+

+      fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);

+

+      OutFileSize += sizeof (EFI_GUID);

+      Dep_Flag = TRUE;

+

+    } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {

+      NotDone = FALSE;

+    } else {

+      //

+      // Not a valid construct. Null terminate somewhere out there and

+      // print an error message.

+      //

+      *(Ptrx + 20) = 0;

+      printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  //  DRAIN();

+  //

+  while (StackPtr != EvaluationStack) {

+    fputc (PopOpCode ((VOID **) &StackPtr), OutFile);

+    OutFileSize++;

+  }

+

+  if (OutFileSize == 0) {

+    printf ("Grammer contains no operators or constants\n");

+    return EFI_INVALID_PARAMETER;

+  }

+

+  fputc (EFI_DEP_END, OutFile);

+

+  OutFileSize++;

+

+  //

+  //  Checks for invalid padding values

+  //

+  if (Padding < 0) {

+

+    printf ("The inputted padding value was %d\n", Padding);

+    printf ("The optional padding value can not be less than ZERO\n");

+    return EFI_INVALID_PARAMETER;

+

+  } else if (Padding > 0) {

+

+    while ((OutFileSize % Padding) != 0) {

+

+      fputc (' ', OutFile);

+      OutFileSize++;

+    }

+  }

+

+  Results = (UINTN) fclose (InFile);

+  if (Results != 0) {

+    printf ("FCLOSE failed\n");

+  }

+

+  Results = (UINTN) fclose (OutFile);

+  if (Results != 0) {

+    printf ("FCLOSE failed\n");

+  }

+

+  free (Buffer);

+  free (EvaluationStack);

+

+  return EFI_SUCCESS;

+} // End GenerateDependencyExpression function

+

+int

+main (

+  IN UINTN argc,

+  IN CHAR8 *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Parse user entries.  Print some rudimentary help

+

+Arguments:

+

+  argc    The count of input arguments

+  argv    The input arguments string array

+

+Returns:

+

+  EFI_SUCCESS             The function completed successfully.

+  EFI_INVALID_PARAMETER   One of the input parameters was invalid or one of the parameters in the text file was invalid.

+  EFI_OUT_OF_RESOURCES    Unable to allocate memory.

+  EFI_ABORTED             Unable to open/create a file or a misc error.

+

+--*/

+// TODO:    ] - add argument and description to function comment

+{

+  FILE    *OutFile;

+  FILE    *InFile;

+  UINT8   Padding;

+  UINTN   Index;

+  BOOLEAN Input_Flag;

+  BOOLEAN Output_Flag;

+  BOOLEAN Pad_Flag;

+

+  InFile      = NULL;

+  OutFile     = NULL;

+  Padding     = 0;

+  Input_Flag  = FALSE;

+  Output_Flag = FALSE;

+  Pad_Flag    = FALSE;

+

+  //

+  //  Output the calling arguments

+  //

+  printf ("\n\n");

+  for (Index = 0; Index < argc; Index++) {

+    printf ("%s ", argv[Index]);

+  }

+

+  printf ("\n\n");

+

+  if (argc < 5) {

+    printf ("Not enough arguments\n");

+    PrintGenDepexUsageInfo ();

+    return EFI_INVALID_PARAMETER;

+  }

+

+  for (Index = 1; Index < argc - 1; Index++) {

+

+    if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {

+

+      if (!Input_Flag) {

+

+        InFile      = fopen (argv[Index + 1], "rb");

+        Input_Flag  = TRUE;

+

+      } else {

+        printf ("GenDepex only allows one INPUT (-I) argument\n");

+        return EFI_INVALID_PARAMETER;

+      }

+

+    } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {

+

+      if (!Output_Flag) {

+

+        OutFile     = fopen (argv[Index + 1], "wb");

+        Output_Flag = TRUE;

+

+      } else {

+        printf ("GenDepex only allows one OUTPUT (-O) argument\n");

+        return EFI_INVALID_PARAMETER;

+      }

+

+    } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {

+

+      if (!Pad_Flag) {

+

+        Padding   = (UINT8) atoi (argv[Index + 1]);

+        Pad_Flag  = TRUE;

+

+      } else {

+        printf ("GenDepex only allows one PADDING (-P) argument\n");

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+

+  PrintGenDepexUtilityInfo ();

+

+  if (InFile == NULL) {

+    printf ("Can not open <INFILE> for reading.\n");

+    PrintGenDepexUsageInfo ();

+    return EFI_ABORTED;

+  }

+

+  if (OutFile == NULL) {

+    printf ("Can not open <OUTFILE> for writting.\n");

+    PrintGenDepexUsageInfo ();

+    return EFI_ABORTED;

+  }

+

+  return GenerateDependencyExpression (InFile, OutFile, Padding);

+}

diff --git a/edk2/Tools/Source/TianoTools/GenDepex/GenDepex.h b/edk2/Tools/Source/TianoTools/GenDepex/GenDepex.h
new file mode 100644
index 0000000..cfba0f2
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenDepex/GenDepex.h
@@ -0,0 +1,71 @@
+/*++

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+  Module Name:  

+          GenDepex.h

+

+  Abstract:

+          This file contains the relevant declarations required

+          to generate a binary Dependency File

+

+  Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.

+

+--*/

+

+#ifndef _EFI_GEN_DEPEX_H

+#define _EFI_GEN_DEPEX_H

+

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <memory.h>

+#include <string.h>

+#ifndef __GNUC__

+#include <malloc.h>

+#endif

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <Dependency.h>

+

+#define DEPENDENCY_START            "DEPENDENCY_START"

+#define OPERATOR_BEFORE             "BEFORE"

+#define OPERATOR_AFTER              "AFTER"

+#define OPERATOR_AND                "AND"

+#define OPERATOR_OR                 "OR"

+#define OPERATOR_NOT                "NOT"

+#define OPERATOR_TRUE               "TRUE"

+#define OPERATOR_FALSE              "FALSE"

+#define OPERATOR_SOR                "SOR"

+#define OPERATOR_END                "END"

+#define OPERATOR_LEFT_PARENTHESIS   "("

+#define OPERATOR_RIGHT_PARENTHESIS  ")"

+#define DEPENDENCY_END              "DEPENDENCY_END"

+

+#define DXE_DEP_LEFT_PARENTHESIS    0x0a

+#define DXE_DEP_RIGHT_PARENTHESIS   0x0b

+

+#define LINESIZE                    320

+#define SIZE_A_SYMBOL               60

+#define DEPENDENCY_OPCODE           UINT8

+#define EVAL_STACK_SIZE             0x1024

+#define BUFFER_SIZE                 0x100

+

+//

+// Utility Name

+//

+#define UTILITY_NAME  "GenDepex"

+

+//

+// Utility version information

+//

+#define UTILITY_MAJOR_VERSION 0

+#define UTILITY_MINOR_VERSION 5

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenDepex/build.xml b/edk2/Tools/Source/TianoTools/GenDepex/build.xml
new file mode 100644
index 0000000..9b4b895
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenDepex/build.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenDepex Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenDepex"/>

+  <property name="FileSet" value="DepexParser.c GenDepex.c GenDepex.h"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        debug="false"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" />

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools"/>

+    </cc>

+	</target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImage.h b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImage.h
new file mode 100644
index 0000000..d9c2686
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImage.h
@@ -0,0 +1,88 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  

+  GenFdImage.h

+

+Abstract:

+

+  This file contains the relevant declarations required

+  to generate the Firmware Device

+

+--*/

+

+//

+// Coded to EFI 2.0 Coding Standard

+//

+#ifndef _EFI_GEN_FD_IMAGE_H

+#define _EFI_GEN_FD_IMAGE_H

+

+//

+// Included Header files

+//

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+// #include <io.h>

+#include <assert.h>

+#include "ParseInf.h"

+// #include "GenFvImage.h"

+

+//

+// Defines

+//

+#define FILE_NAME_SIZE  256

+

+//

+// Type Definition

+//

+typedef struct {

+  UINT64  FdSize;

+  UINT64  FdBaseAddress;

+  UINT8   PadValue;

+  CHAR8   OutFileName[FILE_NAME_SIZE];

+} FDINFO;

+

+//

+// Exported Function Prototype

+//

+EFI_STATUS

+GenerateFdImage (

+  IN UINT64  BaseAddress,

+  IN UINT64  Size,

+  IN UINT8   PadByte,

+  IN CHAR8   *OutFile,

+  IN CHAR8   **FileList

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  BaseAddress - GC_TODO: add argument description

+  Size        - GC_TODO: add argument description

+  PadByte     - GC_TODO: add argument description

+  OutFile     - GC_TODO: add argument description

+  FileList    - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
new file mode 100644
index 0000000..ff78aee
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
@@ -0,0 +1,865 @@
+/*++

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+  Module Name:  

+          GenFdImageDll.C

+

+  Abstarct:

+          This file contains the relevant functions required to complete

+          the API to generate Firmware Device

+--*/

+

+// GC_TODO: fix comment to add:  Abstract:

+//

+// This tells the compiler to export the DLL functions

+//

+#define GEN_FD_IMAGE_EXPORTS

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+// #include <io.h>

+#include <assert.h>

+#include "UefiBaseTypes.h"

+#include "Base.h"

+#include "GenFdImage.h"

+// #include "GenFvImage.h"

+#include "ParseInf.h"

+

+//

+// Global declaration

+//

+UINTN         ValidLineNum  = 0;

+

+UINTN         NumFvFiles    = 0;

+static UINT64 LastAddress   = 0;

+

+CHAR8         **TokenStr;

+CHAR8         **OrgStrTokPtr;

+

+FDINFO        *FdInfo;

+FDINFO        *OrgFdInfoPtr;

+

+FVINFO        **FvInfo;

+FVINFO        **OrgFvInfoPtr;

+

+//

+// Global function declarations

+//

+EFI_STATUS

+BuildFirmwareDeviceBinaryFromFwVolumes (

+  IN UINT64   FvBaseAddress,

+  IN CHAR8    *FvFileName,

+  IN CHAR8    *FdFileName

+  );

+

+INTN

+CompareItems (

+  IN  const VOID *Arg1,

+  IN  const VOID *Arg2

+  )

+/*++

+Description:

+

+    This function is used by qsort to sort the Fv list based on FvBaseAddress

+

+Input:

+    Arg1

+    Arg2

+

+Return:

+

+    None

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    Arg1 - add argument and description to function comment

+// GC_TODO:    Arg2 - add argument and description to function comment

+{

+  if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {

+    return 1;

+  } else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {

+    return -1;

+  } else {

+    return 0;

+  }

+}

+

+VOID

+BuildTokenList (

+  IN  CHAR8 *Token

+  )

+/*++

+Description:

+

+    This function builds the token list in an array which will be parsed later

+

+Input:

+    Token    String,

+

+Return:

+

+    None

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    Token - add argument and description to function comment

+{

+

+  strcpy (*TokenStr, Token);

+  TokenStr++;

+}

+

+VOID

+TrimLine (

+  IN  CHAR8 *Line

+  )

+/*++

+Description:

+

+  This function cleans up the line by removing all whitespace and 

+  comments

+

+Input:

+

+  Line    String,

+

+Return:

+    None

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    Line - add argument and description to function comment

+{

+  CHAR8 TmpLine[FILE_NAME_SIZE];

+  CHAR8 c;

+  CHAR8 *Ptr0;

+  UINTN i;

+  UINTN j;

+

+  //

+  // Change '#' to '//' for Comment style

+  //

+  //  if((Ptr0=strchr(Line, '#')) != NULL) {

+  //

+  if ((Ptr0 = strstr (Line, "//")) != NULL) {

+    Line[Ptr0 - Line] = 0;

+  }

+

+  i = j = 0;

+

+  while ((c = Line[i]) != 0) {

+    if ((c != ' ') && (c != '\t') && (c != '\n')) {

+      TmpLine[j++] = c;

+    }

+

+    i++;

+  }

+

+  TmpLine[j] = 0;

+  strcpy (Line, TmpLine);

+}

+

+VOID

+ValidLineCount (

+  IN  FILE *Fp

+  )

+/*++

+

+Description:

+

+  This function calculated number of valid lines in a input file.

+  

+Input:

+

+  Fp     Pointer to a file handle which has been opened.

+

+Return:

+

+  None

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    Fp - add argument and description to function comment

+{

+  CHAR8 Buff[FILE_NAME_SIZE];

+

+  while (fgets (Buff, sizeof (Buff), Fp)) {

+    TrimLine (Buff);

+    if (Buff[0] == 0) {

+      continue;

+    }

+

+    ValidLineNum++;

+  }

+}

+

+VOID

+ParseInputFile (

+  IN  FILE *Fp

+  )

+/*++

+  

+Description:

+

+  This function parses the input file and tokenize the string

+  

+Input:

+

+  Fp     Pointer to a file handle which has been opened.

+  

+Return:

+

+  None

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    Fp - add argument and description to function comment

+{

+  CHAR8 *Token;

+  CHAR8 Buff[FILE_NAME_SIZE];

+  CHAR8 OrgLine[FILE_NAME_SIZE];

+  CHAR8 Str[FILE_NAME_SIZE];

+  CHAR8 Delimit[] = "=";

+

+  while (fgets (Buff, sizeof (Buff), Fp) != NULL) {

+    strcpy (OrgLine, Buff);

+    TrimLine (Buff);

+

+    if (Buff[0] == 0) {

+      continue;

+    }

+

+    Token = strtok (Buff, Delimit);

+

+    while (Token != NULL) {

+      strcpy (Str, Token);

+      BuildTokenList (Str);

+      Token = strtok (NULL, Delimit);

+    }

+  }

+}

+

+EFI_STATUS

+InitializeComps (

+  VOID

+  )

+/*++

+

+Description:

+

+  This function intializes the relevant global variable which is being

+  used to store the information retrieved from INF file.

+  

+Input:

+

+  None

+

+Return:

+

+  EFI_STATUS

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINTN Index;

+

+  FdInfo = malloc (sizeof (FDINFO));

+

+  if (FdInfo == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  OrgFdInfoPtr  = FdInfo;

+

+  FvInfo        = malloc (sizeof (int) * NumFvFiles);

+

+  if (FvInfo == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  OrgFvInfoPtr = FvInfo;

+

+  for (Index = 0; Index < NumFvFiles; Index++) {

+    *FvInfo = malloc (sizeof (FVINFO));

+

+    if (*FvInfo == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    memset (*FvInfo, 0, sizeof (FVINFO));

+    FvInfo++;

+  }

+

+  FvInfo = OrgFvInfoPtr;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+InitializeInFileInfo (

+  VOID

+  )

+/*++

+

+Description:

+

+  This function intializes the relevant global variable which is being

+  used to store the information retrieved from INF file.

+

+Input:

+

+  NONE

+

+Return:

+

+  NONE

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+{

+  UINTN   OptionFlag;

+  UINT64  StringValue;

+

+  OptionFlag  = 0;

+  TokenStr    = OrgStrTokPtr;

+

+  while (*TokenStr != NULL) {

+    if (stricmp (*TokenStr, "[options]") == 0) {

+      OptionFlag = 1;

+    }

+

+    if (OptionFlag) {

+      if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {

+        *TokenStr++;

+        if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {

+          printf ("\nERROR: Cannot determine the FV base address.");

+          return ;

+        }

+        (*FvInfo)->FvBaseAddress = StringValue;

+      } else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {

+        *TokenStr++;

+        strcpy ((*FvInfo)->FvFile, *TokenStr);

+      }

+    }

+

+    TokenStr++;

+  }

+}

+

+EFI_STATUS

+GetFvRelatedInfoFromInfFile (

+  IN  CHAR8 *FileName

+  )

+/*++

+  

+Description:

+

+  This function reads the input file, parse it and create a list of tokens

+  which is parsed and used, to intialize the data related to Firmware Volume.

+  

+Input:

+

+  FileName  FileName which needed to be read to parse data

+

+Return:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    FileName - add argument and description to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  FILE  *Fp;

+  UINTN Index;

+

+  Fp = fopen (FileName, "r");

+

+  if (Fp == NULL) {

+    printf ("Error in opening %s file\n", FileName);

+    return EFI_ABORTED;

+  }

+

+  ValidLineCount (Fp);

+

+  if (ValidLineNum == 0) {

+    printf ("\nFile doesn't contain any valid informations");

+    return EFI_ABORTED;

+  }

+

+  TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));

+  memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));

+  OrgStrTokPtr = TokenStr;

+

+  for (Index = 0; Index < (2 * ValidLineNum); Index++) {

+    *TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);

+    memset (*TokenStr, 0, FILE_NAME_SIZE);

+    TokenStr++;

+  }

+

+  *TokenStr = NULL;

+  TokenStr  = OrgStrTokPtr;

+  fseek (Fp, 0L, SEEK_SET);

+

+  ParseInputFile (Fp);

+  InitializeInFileInfo ();

+

+  if (Fp) {

+    fclose (Fp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WriteFwBinary (

+  IN  CHAR8   *FileName,

+  IN  UINT64  StartAddress,

+  IN  UINT64  Size,

+  IN  UINT8   *Buffer

+  )

+/*++

+  

+Description:

+

+  This function reads the input file, parse it and create a list of tokens

+  which is parsed and used, to intialize the data related to Firmware Volume.

+  

+Input:

+

+  FileName        FileName which needed to be read to parse data

+  StartAddress    This will set the file position.

+  Size            Size in bytes needed to be written

+  Buffer          Buffer needed to e written

+

+Return:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    FileName - add argument and description to function comment

+// GC_TODO:    StartAddress - add argument and description to function comment

+// GC_TODO:    Size - add argument and description to function comment

+// GC_TODO:    Buffer - add argument and description to function comment

+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  FILE  *Fp;

+  UINTN NumByte;

+

+  Fp = fopen (FileName, "a+b");

+

+  if (Fp == NULL) {

+    printf ("\nERROR:Error in opening file %s ", FileName);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  fseek (Fp, (UINTN) StartAddress, SEEK_SET);

+  NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);

+

+  //

+  // Check to ensure that buffer has been copied successfully

+  //

+  if (NumByte != Size) {

+    printf ("\nERROR: Error in copying the buffer into file");

+    return EFI_ABORTED;

+  }

+

+  if (Fp) {

+    fclose (Fp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BuildFirmwareDeviceBinaryFromFwVolumes (

+  IN UINT64   FvBaseAddress,

+  IN CHAR8    *FvFileName,

+  IN CHAR8    *FdFileName

+  )

+/*++

+  

+Description:

+

+  This function reads the input file, parse it and create a list of tokens

+  which is parsed and used, to intialize the data related to Firmware Volume.

+  

+Input:

+

+  FvBaseAddress   Base Address. This info is retrieved from INF file

+  FvFileName      InputFileName

+  FdFileName      Output File Name

+

+Return:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    FvBaseAddress - add argument and description to function comment

+// GC_TODO:    FvFileName - add argument and description to function comment

+// GC_TODO:    FdFileName - add argument and description to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  FILE          *Fp;

+  UINT64        FileSize;

+  UINT64        NumByteRead;

+  UINT64        PadByteSize;

+  UINTN         Index;

+  UINT64        BaseAddress;

+  UINT8         *Buffer;

+  EFI_STATUS    Status;

+  static UINT64 StartAddress  = 0;

+

+  Fp                          = fopen (FvFileName, "r+b");

+

+  if (Fp == NULL) {

+    printf ("\nERROR:Error in opening file %s", FvFileName);

+    return EFI_ABORTED;

+  }

+

+  BaseAddress = FdInfo->FdBaseAddress;

+

+  //

+  // Check if Base Address of Firmware Volume falls below the Base Address

+  // Firmware Device, if yes, then abort this process.

+  //

+  if (FvBaseAddress < BaseAddress) {

+    printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");

+    return EFI_ABORTED;

+  }

+  //

+  // Check if there are any hole between two Firmware Volumes. If any hole

+  // exists, fill the hole with PadByte data.

+  //

+  if (FvBaseAddress > LastAddress) {

+    PadByteSize = (FvBaseAddress - LastAddress);

+    Buffer      = malloc ((UINTN) PadByteSize);

+

+    for (Index = 0; Index < PadByteSize; Index++) {

+      *Buffer = FdInfo->PadValue;

+      Buffer++;

+    }

+

+    Buffer -= PadByteSize;

+    Status = WriteFwBinary (FdFileName, StartAddress, (UINT64) PadByteSize, Buffer);

+

+    if (Buffer) {

+      free (Buffer);

+    }

+

+    if (Status != EFI_SUCCESS) {

+      printf ("\nERROR: Error in writing the binary image to file");

+      return Status;

+    }

+

+    StartAddress += PadByteSize;

+    LastAddress += PadByteSize;

+  }

+  //

+  // Proceed with next Firmware Volume updates

+  //

+  FileSize = _filelength (fileno (Fp));

+

+  if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {

+    printf (

+      "\nERROR:Unable to update Firmware Device. File %s is larger than \

+                                  available space.",

+      FvFileName

+      );

+    if (Fp) {

+      fclose (Fp);

+    }

+

+    return EFI_ABORTED;

+  }

+

+  Buffer = malloc ((UINTN) FileSize);

+

+  if (Buffer == NULL) {

+    printf ("Error in allocating buffer to read specific file\n");

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);

+

+  Status      = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);

+

+  if (Buffer) {

+    free ((VOID *) Buffer);

+  }

+

+  if (Fp) {

+    fclose (Fp);

+  }

+

+  if (Status != EFI_SUCCESS) {

+    printf ("\nERROR: Error in writing the binary image to file");

+    return Status;

+  }

+

+  StartAddress += NumByteRead;

+  LastAddress += FileSize;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+CleanUpMemory (

+  VOID

+  )

+/*++

+

+Description:

+

+  This function cleans up any allocated buffer

+  

+Input:

+

+  NONE

+

+Return:

+  

+  NONE

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+{

+  UINTN Index;

+

+  if (FdInfo) {

+    free (FdInfo);

+  }

+

+  FvInfo = OrgFvInfoPtr;

+

+  if (FvInfo) {

+    for (Index = 0; Index < NumFvFiles; Index++) {

+      if (*FvInfo) {

+        free (*FvInfo);

+      }

+

+      FvInfo++;

+    }

+

+    FvInfo = OrgFvInfoPtr;

+    free (FvInfo);

+  }

+}

+

+GEN_FD_IMAGE_API

+EFI_STATUS

+GenerateFdImage (

+  IN  UINT64  BaseAddress,

+  IN  UINT64  Size,

+  IN  UINT8   PadByte,

+  IN  CHAR8   *OutFile,

+  IN  CHAR8   **FileList

+  )

+/*++

+  

+Description:

+

+  This function reads the input file, parse it and create a list of tokens

+  which is parsed and used, to intialize the data related to Firmware Volume.

+  

+Input:

+

+  BaseAddress   Base Address for this Firmware Device

+  Size,         Total Size of the Firmware Device

+  PadByte       Pad byte data

+  OutFile       Output File Name

+  FileList      File List pointer to INF file names.

+

+Return:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO: function comment is missing 'Routine Description:'

+// GC_TODO: function comment is missing 'Arguments:'

+// GC_TODO: function comment is missing 'Returns:'

+// GC_TODO:    BaseAddress - add argument and description to function comment

+// GC_TODO:    Size - add argument and description to function comment

+// GC_TODO:    PadByte - add argument and description to function comment

+// GC_TODO:    OutFile - add argument and description to function comment

+// GC_TODO:    FileList - add argument and description to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+  UINTN       Index;

+  UINTN       PadSize;

+  UINTN       FileSize;

+  CHAR8       **InFile;

+  FILE        *Fp;

+  UINT8       *Buffer;

+  UINTN       NumByte;

+

+  //

+  // Ensure, if there are any previous Firmware Device exists,

+  // If yes, make it to 0 bytes

+  //

+  if ((Fp = fopen (OutFile, "w")) != NULL) {

+    fclose (Fp);

+  }

+

+  InFile = FileList;

+

+  while (*InFile != NULL) {

+    NumFvFiles++;

+    InFile++;

+  }

+

+  InitializeComps ();

+

+  //

+  // Restore the orginal pointers

+  //

+  FvInfo  = OrgFvInfoPtr;

+  InFile  = FileList;

+

+  while (*InFile != NULL) {

+    strcpy ((*FvInfo)->FvInfoFile, *InFile);

+    Status = GetFvRelatedInfoFromInfFile (*InFile);

+

+    if (Status != EFI_SUCCESS) {

+      printf ("\nERROR: Error occurred in processsing INF file");

+      CleanUpMemory ();

+      return Status;

+    }

+

+    InFile++;

+    FvInfo++;

+  }

+

+  FdInfo->FdSize        = Size;

+  FdInfo->FdBaseAddress = BaseAddress;

+  FdInfo->PadValue      = PadByte;

+  FvInfo                = OrgFvInfoPtr;

+  strcpy (FdInfo->OutFileName, OutFile);

+

+  for (Index = 0; Index < NumFvFiles; Index++) {

+    Status = GenerateFvImage ((*FvInfo)->FvInfoFile);

+

+    if (Status != EFI_SUCCESS) {

+      CleanUpMemory ();

+      return Status;

+    }

+

+    FvInfo++;

+  }

+

+  FvInfo = OrgFvInfoPtr;

+

+  //

+  // Sort the Firmware Volume informations. Firmware Volume with lower

+  // base addresses will be processed first and hiher base address one

+  // will be processed later.

+  //

+  qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);

+

+  LastAddress = (*FvInfo)->FvBaseAddress;

+

+  for (Index = 0; Index < NumFvFiles; Index++) {

+    Status = BuildFirmwareDeviceBinaryFromFwVolumes (

+              (*FvInfo)->FvBaseAddress,

+              (*FvInfo)->FvFile,

+              FdInfo->OutFileName

+              );

+    if (Status != EFI_SUCCESS) {

+      CleanUpMemory ();

+      return Status;

+    }

+

+    FvInfo++;

+  }

+  //

+  // Check if any space left after copying data from all Firmware Volumes

+  // If yes, then fill those location with PadValue.

+  //

+  if ((FdInfo->FdBaseAddress + Size) > LastAddress) {

+

+    PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);

+    Buffer  = malloc (PadSize);

+

+    if (Buffer == NULL) {

+      CleanUpMemory ();

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    for (Index = 0; Index < PadSize; Index++) {

+      *Buffer = FdInfo->PadValue;

+      Buffer++;

+    }

+

+    Buffer -= PadSize;

+

+    Fp = fopen (OutFile, "a+b");

+

+    if (Fp == NULL) {

+      printf ("\nERROR:Opening file %s", OutFile);

+      CleanUpMemory ();

+      return EFI_ABORTED;

+    }

+

+    FileSize = _filelength (fileno (Fp));

+    fseek (Fp, FileSize, SEEK_SET);

+    NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);

+

+    if (Buffer) {

+      free (Buffer);

+    }

+

+    fclose (Fp);

+

+    if (NumByte != (sizeof (UINT8) * PadSize)) {

+      printf ("\nERROR: Copying data from buffer to File %s ", OutFile);

+      CleanUpMemory ();

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // Clean up all the memory which has been allocated so far.

+  //

+  CleanUpMemory ();

+  return EFI_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageExe.c b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageExe.c
new file mode 100644
index 0000000..9c56d06
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageExe.c
@@ -0,0 +1,330 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  GenFdImageExe.c

+

+Abstract:

+

+  This contains all code necessary to build the GenFdImage.exe utility.

+  This utility relies heavily on the GenFdImage Lib.  Definitions for both     

+  can be found in the GenFdImage Utility Specification, review draft.

+

+--*/

+

+//

+// Coded to EFI 2.0 Coding Standards

+//

+//

+// Include files

+//

+#include "GenFdImage.h"

+#include "GenFdImageExe.h"

+

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "%s, EFI 2.0 Firmware Device Image Generation Utility. ""Version %i.%i, %s.\n\n",

+    UTILITY_NAME,

+    UTILITY_MAJOR_VERSION,

+    UTILITY_MINOR_VERSION,

+    UTILITY_DATE

+    );

+}

+

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "Usage: %s -B BaseAddress -S Size -F FillByte"" [-I FvInfFileName] -O OutputFileName \n",

+    UTILITY_NAME

+    );

+  printf ("  Where:\n");

+  printf ("\tBaseAddress is the starting address of the FD Image\n\n");

+  printf ("\tSize is the size of the FD Image.\n\n");

+  printf ("\tFillByte is the desired value of free space in the Image\n\n");

+  printf ("\tFvInfFileName is the name of an FV Image description file.\n\n");

+  printf ("\tOutputFileName is the desired output file name.\n\n");

+}

+

+EFI_STATUS

+main (

+  IN INTN   argc,

+  IN CHAR8  **argv

+  )

+/*++

+

+Routine Description:

+

+  This utility uses GenFdImage.lib to build a Firmware Device Image

+  which will include several Firmware Volume Images.

+

+Arguments:

+

+  Base Address      Base Address of the firmware volume..

+  Size              Size of the Firmware Volume

+  FillByte          The byte value which would be needed to pad

+                    between various Firmware Volumes

+  FvInfFile         Fv inf file

+  OutputFileName    The name of output file which would be created

+

+Returns:

+

+  EFI_SUCCESS            No error conditions detected.

+  EFI_INVALID_PARAMETER  One or more of the input parameters is invalid.

+  EFI_OUT_OF_RESOURCES   A resource required by the utility was unavailable.  

+                         Most commonly this will be memory allocation or 

+                         file creation.

+  EFI_LOAD_ERROR         GenFvImage.lib could not be loaded.

+  EFI_ABORTED            Error executing the GenFvImage lib.

+

+--*/

+// GC_TODO:    argc - add argument and description to function comment

+// GC_TODO:    argv - add argument and description to function comment

+{

+  UINTN       Index;

+  UINTN       FvFilesCount;

+

+  UINT8       i;

+

+  UINT64      StartAddress;

+  UINT64      Size;

+  UINT64      FillByteVal;

+

+  CHAR8       **FvInfFileList;

+  CHAR8       **OrgFvInfFileList;

+  CHAR8       OutputFileName[_MAX_PATH];

+

+  EFI_STATUS  Status;

+

+  INTN        arg_counter;

+

+  //

+  //  Echo for makefile debug

+  //

+  printf ("\n\n");

+  for (arg_counter = 0; arg_counter < argc; arg_counter++) {

+    printf ("%s ", argv[arg_counter]);

+  }

+

+  printf ("\n\n");

+

+  //

+  // Display utility information

+  //

+  PrintUtilityInfo ();

+

+  //

+  // Verify the correct number of arguments

+  //

+  if (argc < MIN_ARGS) {

+    printf ("ERROR: missing 1 or more input arguments.\n\n");

+    PrintUsage ();

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Initialize variables

+  //

+  StartAddress  = 0;

+  Size          = 0;

+  FillByteVal   = 0;

+  FvFilesCount  = 0;

+

+  for (i = 1; i < argc; i++) {

+    if (stricmp (argv[i], "-I") == 0) {

+      FvFilesCount++;

+    }

+  }

+

+  FvInfFileList = malloc (sizeof (UINTN) * (FvFilesCount + 1));

+  if (FvInfFileList == NULL) {

+    printf ("ERROR: allocating memory for FvInfFileList in -main- function.\n");

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  memset (FvInfFileList, 0, sizeof (UINTN) * (FvFilesCount + 1));

+

+  OrgFvInfFileList = FvInfFileList;

+

+  for (Index = 0; Index < FvFilesCount; Index++) {

+    *FvInfFileList = malloc (_MAX_PATH);

+    memset (*FvInfFileList, 0, _MAX_PATH);

+    FvInfFileList++;

+  }

+

+  strcpy (OutputFileName, "");

+

+  //

+  // Parse the command line arguments

+  //

+  FvInfFileList = OrgFvInfFileList;

+

+  for (i = 1; i < argc; i += 2) {

+    //

+    // Make sure argument pair begin with - or /

+    //

+    if (argv[i][0] != '-' && argv[i][0] != '/') {

+      PrintUsage ();

+      printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // Make sure argument specifier is only one letter

+    //

+    if (argv[i][2] != 0) {

+      PrintUsage ();

+      printf ("ERROR: Unrecognized argument \"%s\".\n", argv[i]);

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // Determine argument to read

+    //

+    switch (argv[i][1]) {

+

+    case 'I':

+    case 'i':

+      if ((FvInfFileList != NULL) && (strlen (*FvInfFileList) == 0)) {

+        strcpy (*FvInfFileList, argv[i + 1]);

+        FvInfFileList++;

+      } else {

+        printf ("ERROR: FvInfFile Name is more than specifed.\n");

+        return EFI_INVALID_PARAMETER;

+      }

+      break;

+

+    case 'O':

+    case 'o':

+      if (strlen (OutputFileName) == 0) {

+        strcpy (OutputFileName, argv[i + 1]);

+      } else {

+        PrintUsage ();

+        printf ("ERROR: OutputFileName may only be specified once.\n");

+        return EFI_INVALID_PARAMETER;

+      }

+      break;

+

+    case 'B':

+    case 'b':

+      Status = AsciiStringToUint64 (argv[i + 1], FALSE, &StartAddress);

+      if (Status != EFI_SUCCESS) {

+        printf ("\nERROR: Bad FD Image start address specified");

+        return EFI_INVALID_PARAMETER;

+      }

+      break;

+

+    case 'S':

+    case 's':

+      Status = AsciiStringToUint64 (argv[i + 1], FALSE, &Size);

+      if (Status != EFI_SUCCESS) {

+        printf ("\nERROR: Bad FD Image size specified");

+        return EFI_INVALID_PARAMETER;

+      }

+      break;

+

+    case 'F':

+    case 'f':

+      Status = AsciiStringToUint64 (argv[i + 1], FALSE, &FillByteVal);

+      if (Status != EFI_SUCCESS) {

+        printf ("\nERROR: Not a recognized Fill Byte value");

+        return EFI_INVALID_PARAMETER;

+      }

+      break;

+

+    default:

+      PrintUsage ();

+      printf ("ERROR: Unrecognized argument \"%s\".\n", argv[i]);

+      return EFI_INVALID_PARAMETER;

+      break;

+    }

+  }

+  //

+  // Call the GenFdImage Lib

+  //

+  FvInfFileList = OrgFvInfFileList;

+

+  Status = GenerateFdImage (

+            StartAddress,

+            Size,

+            (UINT8) FillByteVal,

+            OutputFileName,

+            FvInfFileList

+            );

+

+  if (EFI_ERROR (Status)) {

+    switch (Status) {

+

+    case EFI_INVALID_PARAMETER:

+      printf ("\nERROR: Invalid parameter passed to GenFdImage lib.\n");

+      break;

+

+    case EFI_ABORTED:

+      printf ("\nERROR: Error detected while creating the file image.\n");

+      break;

+

+    case EFI_OUT_OF_RESOURCES:

+      printf ("\nERROR: GenFdImage Lib could not allocate required resources.\n");

+      break;

+

+    case EFI_VOLUME_CORRUPTED:

+      printf ("\nERROR: No base address was specified \n");

+      break;

+

+    case EFI_LOAD_ERROR:

+      printf ("\nERROR: An error occurred loading one of the required support Lib.\n");

+      break;

+

+    default:

+      printf ("\nERROR: GenFdImage lib returned unknown status %X.\n", Status);

+      break;

+    }

+

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageExe.h b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageExe.h
new file mode 100644
index 0000000..e07cb23
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageExe.h
@@ -0,0 +1,91 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  GenFdImageExe.h

+

+Abstract:

+

+  Definitions for the Boot Strap File Image generation utility.

+

+--*/

+

+#ifndef _EFI_GEN_FD_IMAGE_EXE_H

+#define _EFI_GEN_FD_IMAGE_EXE_H

+

+//

+// Utility Name

+//

+#define UTILITY_NAME  "GenFdImage"

+

+//

+// Utility version information

+//

+#define UTILITY_MAJOR_VERSION 0

+#define UTILITY_MINOR_VERSION 0

+#define UTILITY_DATE          __DATE__

+

+//

+// The maximum number of arguments accepted from the command line.

+//

+#define MIN_ARGS  10

+

+//

+// The function that displays general utility information

+//

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+//

+// The function that displays the utility usage message.

+//

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageLib.c b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageLib.c
new file mode 100644
index 0000000..39698d9
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFdImage/GenFdImageLib.c
@@ -0,0 +1,848 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  

+  GenFdImageLib.C

+

+Abstract:

+

+  This file contains the functions required to generate 

+  the Firmware Device

+

+--*/

+

+//

+// Coded to EFI 2.0 Coding Standards

+//

+//

+// Include file in build

+//

+#include "GenFdImage.h"

+

+//

+// Global declarations

+//

+UINTN         ValidLineNum  = 0;

+UINTN         NumFvFiles    = 0;

+

+static UINT64 LastAddress   = 0;

+

+CHAR8         **TokenStr;

+CHAR8         **OrgStrTokPtr;

+

+FDINFO        *FdInfo;

+FDINFO        *OrgFdInfoPtr;

+

+FVINFO        **FvInfo;

+FVINFO        **OrgFvInfoPtr;

+

+//

+// Internal Functions

+//

+INTN

+CompareItems (

+  IN const VOID  *Arg1,

+  IN const VOID  *Arg2

+  )

+/*++

+

+Routine Description:

+

+    This function is used by qsort to sort the Fv list based on FvBaseAddress  

+

+Arguments:

+

+    Arg1

+    Arg2

+

+Returns:

+

+    None

+

+--*/

+// GC_TODO:    Arg1 - add argument and description to function comment

+// GC_TODO:    Arg2 - add argument and description to function comment

+{

+  if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {

+    return 1;

+  } else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {

+    return -1;

+  } else {

+    return 0;

+  }

+}

+

+VOID

+BuildTokenList (

+  IN CHAR8  *Token

+  )

+/*++

+

+Routine Description:

+

+    This function builds the token list in an array which will be parsed later

+

+Arguments:

+

+    Token    String,

+

+Returns:

+

+    None

+

+--*/

+{

+  strcpy (*TokenStr, Token);

+  TokenStr++;

+}

+

+VOID

+TrimLine (

+  IN CHAR8  *Line

+  )

+/*++

+

+Routine Description:

+

+  This function cleans up the line by removing all whitespace and 

+  comments.

+

+Arguments:

+

+  Line    String,

+

+Returns:

+

+    None

+

+--*/

+{

+  CHAR8 TmpLine[FILE_NAME_SIZE];

+  CHAR8 c;

+  CHAR8 *Ptr0;

+

+  UINTN i;

+  UINTN j;

+

+  //

+  // Change '#' to '//' for Comment style

+  //

+  //  if((Ptr0=strchr(Line, '#')) != NULL) {

+  //

+  if ((Ptr0 = strstr (Line, "//")) != NULL) {

+    Line[Ptr0 - Line] = 0;

+  }

+

+  i = 0;

+  j = 0;

+  while ((c = Line[i]) != 0) {

+    if ((c != ' ') && (c != '\t') && (c != '\n')) {

+      TmpLine[j++] = c;

+    }

+

+    i++;

+  }

+

+  TmpLine[j] = 0;

+  strcpy (Line, TmpLine);

+}

+

+VOID

+ValidLineCount (

+  IN FILE  *Fp

+  )

+/*++

+

+Routine Description:

+

+  This function calculates number of valid lines in a input file.

+  

+Arguments:

+

+  Fp     Pointer to a file handle which has been opened.

+

+Returns:

+

+  None

+

+--*/

+{

+  CHAR8 Buff[FILE_NAME_SIZE];

+

+  while (fgets (Buff, sizeof (Buff), Fp)) {

+    TrimLine (Buff);

+    if (Buff[0] == 0) {

+      continue;

+    }

+

+    ValidLineNum++;

+  }

+}

+

+VOID

+ParseInputFile (

+  IN FILE  *Fp

+  )

+/*++

+  

+Routine Description:

+

+  This function parses the input file and tokenizes the string

+  

+Arguments:

+

+  Fp     Pointer to a file handle which has been opened.

+  

+Returns:

+

+  None

+

+--*/

+{

+  CHAR8 *Token;

+  CHAR8 Buff[FILE_NAME_SIZE];

+  CHAR8 OrgLine[FILE_NAME_SIZE];

+  CHAR8 Str[FILE_NAME_SIZE];

+  CHAR8 Delimit[] = "=";

+

+  while (fgets (Buff, sizeof (Buff), Fp) != NULL) {

+    strcpy (OrgLine, Buff);

+    TrimLine (Buff);

+

+    if (Buff[0] == 0) {

+      continue;

+    }

+

+    Token = strtok (Buff, Delimit);

+

+    while (Token != NULL) {

+      strcpy (Str, Token);

+      BuildTokenList (Str);

+      Token = strtok (NULL, Delimit);

+    }

+  }

+}

+

+EFI_STATUS

+InitializeComps (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function intializes the relevant global variable 

+  used to store the information retrieved from the INF file.

+  

+Arguments:

+

+  None

+

+Returns:

+

+  EFI_STATUS

+

+--*/

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  UINTN Index;

+

+  FdInfo = malloc (sizeof (FDINFO));

+

+  if (FdInfo == NULL) {

+    printf ("ERROR: allocating memory (struct FDINFO) in"" function InitializeComps.\n");

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  OrgFdInfoPtr  = FdInfo;

+

+  FvInfo        = malloc (sizeof (INTN) * NumFvFiles);

+

+  if (FvInfo == NULL) {

+    printf ("ERROR: allocating memory (INTN * NumFvFiles) in"" function InitializeComps.\n");

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  OrgFvInfoPtr = FvInfo;

+

+  for (Index = 0; Index < NumFvFiles; Index++) {

+    *FvInfo = malloc (sizeof (FVINFO));

+

+    if (*FvInfo == NULL) {

+      printf ("ERROR: allocating memory (FVINFO) in"" function InitializeComps.\n");

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    memset (*FvInfo, 0, sizeof (FVINFO));

+    FvInfo++;

+  }

+

+  FvInfo = OrgFvInfoPtr;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+InitializeInFileInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function intializes the relevant global variable 

+  used to store the information retrieved from the INF file.

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN   OptionFlag;

+

+  UINT64  StringValue;

+

+  OptionFlag  = 0;

+  TokenStr    = OrgStrTokPtr;

+

+  while (*TokenStr != NULL) {

+    if (stricmp (*TokenStr, "[options]") == 0) {

+      OptionFlag = 1;

+    }

+

+    if (OptionFlag) {

+      if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {

+        *TokenStr++;

+        if (AsciiStringToUint64 (

+              *TokenStr,

+              FALSE,

+              &StringValue

+              ) != EFI_SUCCESS) {

+          printf ("\nERROR: Cannot determine the FV base address.");

+          return ;

+        }

+        (*FvInfo)->FvBaseAddress = StringValue;

+      } else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {

+        *TokenStr++;

+        strcpy ((*FvInfo)->FvFile, *TokenStr);

+      }

+    }

+

+    TokenStr++;

+  }

+}

+

+EFI_STATUS

+GetFvRelatedInfoFromInfFile (

+  IN CHAR8  *FileName

+  )

+/*++

+  

+Routine Description:

+

+  This function reads the input file, parses it and create a list of tokens

+  which are parsed and used, to intialize the data related to the Firmware 

+  Volume.

+  

+Arguments:

+

+  FileName  FileName which needed to be read to parse data

+

+Returns:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  FILE  *Fp;

+

+  UINTN Index;

+

+  Fp = fopen (FileName, "r");

+

+  if (Fp == NULL) {

+    printf ("Error in opening %s file\n", FileName);

+    return EFI_ABORTED;

+  }

+

+  ValidLineCount (Fp);

+

+  if (ValidLineNum == 0) {

+    printf ("\nFile doesn't contain any valid informations");

+    return EFI_ABORTED;

+  }

+

+  TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));

+  memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));

+  OrgStrTokPtr = TokenStr;

+

+  for (Index = 0; Index < (2 * ValidLineNum); Index++) {

+    *TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);

+    memset (*TokenStr, 0, FILE_NAME_SIZE);

+    TokenStr++;

+  }

+

+  *TokenStr = NULL;

+  TokenStr  = OrgStrTokPtr;

+  fseek (Fp, 0L, SEEK_SET);

+

+  ParseInputFile (Fp);

+  InitializeInFileInfo ();

+

+  if (Fp) {

+    fclose (Fp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+WriteFwBinary (

+  IN CHAR8   *FileName,

+  IN UINT64  StartAddress,

+  IN UINT64  Size,

+  IN UINT8   *Buffer

+  )

+/*++

+  

+Routine Description:

+

+  This function reads the input file, parses it and creates a list of tokens

+  which are parsed and used to intialize the data related to the Firmware 

+  Volume.

+  

+Arguments:

+

+  FileName        FileName which needed to be read to parse data

+  StartAddress    This will set the file position.

+  Size            Size in bytes needed to be written

+  Buffer          Buffer needed to e written

+

+Returns:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  FILE  *Fp;

+

+  UINTN NumByte;

+

+  Fp = fopen (FileName, "a+b");

+

+  if (Fp == NULL) {

+    printf ("\nERROR:Error in opening file %s ", FileName);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  fseek (Fp, (UINTN) StartAddress, SEEK_SET);

+  NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);

+

+  //

+  // Check to ensure that buffer has been copied successfully

+  //

+  if (NumByte != Size) {

+    printf ("\nERROR: Error in copying the buffer into file");

+    return EFI_ABORTED;

+  }

+

+  if (Fp) {

+    fclose (Fp);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BuildFirmwareDeviceBinaryFromFwVolumes (

+  IN UINT64  FvBaseAddress,

+  IN CHAR8   *FvFileName,

+  IN CHAR8   *FdFileName

+  )

+/*++

+  

+Routine Description:

+

+  This function reads the input file, parses it and creates a list of tokens

+  which are parsed and used to intialize the data related to the Firmware 

+  Volume.

+  

+Arguments:

+

+  FvBaseAddress   Base Address. This info is retrieved from INF file

+  FvFileName      InputFileName

+  FdFileName      Output File Name

+

+Returns:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  FILE          *Fp;

+

+  UINT64        FileSize;

+  UINT64        NumByteRead;

+  UINT64        PadByteSize;

+  UINT64        BaseAddress;

+

+  UINTN         Index;

+

+  UINT8         *Buffer;

+

+  EFI_STATUS    Status;

+

+  static UINT64 StartAddress  = 0;

+

+  Fp                          = fopen (FvFileName, "r+b");

+

+  if (Fp == NULL) {

+    printf ("\nERROR:Error in opening file %s", FvFileName);

+    return EFI_ABORTED;

+  }

+

+  BaseAddress = FdInfo->FdBaseAddress;

+

+  //

+  // Check if Base Address of Firmware Volume falls below the Base Address

+  // Firmware Device, if yes, then abort this process.

+  //

+  if (FvBaseAddress < BaseAddress) {

+    printf ("\nERROR: Firmware Volume Base Address falls below Firmware ""Device Address.\n");

+    return EFI_ABORTED;

+  }

+  //

+  // Check if there are any holes between two Firmware Volumes. If any holes

+  // exist, fill the hole with PadByted data.

+  //

+  if (FvBaseAddress > LastAddress) {

+    PadByteSize = (FvBaseAddress - LastAddress);

+    Buffer      = malloc ((UINTN) PadByteSize);

+    if (Buffer == NULL) {

+      printf ("ERROR: allocating (Buffer) memory in"" function BuildFirmwareDeviceBinaryFromFwVolumes.\n");

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    for (Index = 0; Index < PadByteSize; Index++) {

+      *Buffer = FdInfo->PadValue;

+      Buffer++;

+    }

+

+    Buffer -= PadByteSize;

+    Status = WriteFwBinary (

+              FdFileName,

+              StartAddress,

+              (UINT64) PadByteSize,

+              Buffer

+              );

+

+    if (Buffer) {

+      free (Buffer);

+    }

+

+    if (Status != EFI_SUCCESS) {

+      printf ("\nERROR: Error in writing the binary image to file");

+      return Status;

+    }

+

+    StartAddress += PadByteSize;

+    LastAddress += PadByteSize;

+  }

+  //

+  // Proceed with next Firmware Volume updates

+  //

+  FileSize = _filelength (fileno (Fp));

+

+  if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {

+    printf (

+      "\nERROR:Unable to update Firmware Device. File %s is larger than \

+                                  available space.",

+      FvFileName

+      );

+    if (Fp) {

+      fclose (Fp);

+    }

+

+    return EFI_ABORTED;

+  }

+

+  Buffer = malloc ((UINTN) FileSize);

+

+  if (Buffer == NULL) {

+    printf ("Error in allocating buffer to read specific file\n");

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);

+

+  Status      = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);

+

+  if (Buffer) {

+    free ((VOID *) Buffer);

+  }

+

+  if (Fp) {

+    fclose (Fp);

+  }

+

+  if (Status != EFI_SUCCESS) {

+    printf ("\nERROR: Error in writing the binary image to file");

+    return Status;

+  }

+

+  StartAddress += NumByteRead;

+  LastAddress += FileSize;

+

+  return EFI_SUCCESS;

+}

+

+VOID

+CleanUpMemory (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  This function cleans up any allocated buffer

+  

+Arguments:

+

+  None

+

+Returns:

+  

+  None

+

+--*/

+{

+  UINTN Index;

+

+  if (FdInfo) {

+    free (FdInfo);

+  }

+

+  FvInfo = OrgFvInfoPtr;

+

+  if (FvInfo) {

+    for (Index = 0; Index < NumFvFiles; Index++) {

+      if (*FvInfo) {

+        free (*FvInfo);

+      }

+

+      FvInfo++;

+    }

+

+    FvInfo = OrgFvInfoPtr;

+    free (FvInfo);

+  }

+}

+

+EFI_STATUS

+GenerateFdImage (

+  IN UINT64  BaseAddress,

+  IN UINT64  Size,

+  IN UINT8   PadByte,

+  IN CHAR8   *OutFile,

+  IN CHAR8   **FileList

+  )

+/*++

+  

+Routine Description:

+

+  This function reads the input file, parses it and creates a list of tokens

+  which are parsed and used to intialize the data related to the Firmware 

+  Volume.

+  

+Arguments:

+

+  BaseAddress   Base Address for this Firmware Device

+  Size,         Total Size of the Firmware Device

+  PadByte       Pad byte data

+  OutFile       Output File Name

+  FileList      File List pointer to INF file names.

+

+Returns:

+

+  EFI_STATUS

+    

+--*/

+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_ABORTED - add return value to function comment

+// GC_TODO:    EFI_SUCCESS - add return value to function comment

+{

+  EFI_STATUS  Status;

+

+  UINTN       Index;

+  UINTN       PadSize;

+  UINTN       FileSize;

+  UINTN       NumByte;

+

+  CHAR8       **InFile;

+

+  FILE        *Fp;

+

+  UINT8       *Buffer;

+

+  //

+  // If any previous Firmware Device existed,

+  // make it to 0 bytes

+  //

+  if ((Fp = fopen (OutFile, "w")) != NULL) {

+    fclose (Fp);

+  }

+

+  InFile = FileList;

+

+  while (*InFile != NULL) {

+    NumFvFiles++;

+    InFile++;

+  }

+

+  InitializeComps ();

+

+  //

+  // Restore the orginal pointers

+  //

+  FvInfo  = OrgFvInfoPtr;

+  InFile  = FileList;

+

+  while (*InFile != NULL) {

+    strcpy ((*FvInfo)->FvInfoFile, *InFile);

+    Status = GetFvRelatedInfoFromInfFile (*InFile);

+

+    if (Status != EFI_SUCCESS) {

+      printf ("\nERROR: Error occurred in processsing INF file");

+      CleanUpMemory ();

+      return Status;

+    }

+

+    InFile++;

+    FvInfo++;

+  }

+

+  FdInfo->FdSize        = Size;

+  FdInfo->FdBaseAddress = BaseAddress;

+  FdInfo->PadValue      = PadByte;

+  FvInfo                = OrgFvInfoPtr;

+  strcpy (FdInfo->OutFileName, OutFile);

+

+  for (Index = 0; Index < NumFvFiles; Index++) {

+    Status = GenerateFvImage ((*FvInfo)->FvInfoFile);

+

+    if (Status != EFI_SUCCESS) {

+      CleanUpMemory ();

+      return Status;

+    }

+

+    FvInfo++;

+  }

+

+  FvInfo = OrgFvInfoPtr;

+

+  //

+  // Sort the Firmware Volume information. Firmware Volume with lower

+  // base addresses will be processed first and higher base address one

+  // will be processed later.

+  //

+  qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);

+

+  LastAddress = (*FvInfo)->FvBaseAddress;

+

+  for (Index = 0; Index < NumFvFiles; Index++) {

+    Status = BuildFirmwareDeviceBinaryFromFwVolumes (

+              (*FvInfo)->FvBaseAddress,

+              (*FvInfo)->FvFile,

+              FdInfo->OutFileName

+              );

+    if (Status != EFI_SUCCESS) {

+      CleanUpMemory ();

+      return Status;

+    }

+

+    FvInfo++;

+  }

+  //

+  // Check if any space left after copying data from all Firmware Volumes

+  // If yes, then fill those location with PadValue.

+  //

+  if ((FdInfo->FdBaseAddress + Size) > LastAddress) {

+

+    PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);

+    Buffer  = malloc (PadSize);

+

+    if (Buffer == NULL) {

+      printf ("\nERROR: allocating PadSize memory in function GenerateFdImage.\n");

+      CleanUpMemory ();

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    for (Index = 0; Index < PadSize; Index++) {

+      *Buffer = FdInfo->PadValue;

+      Buffer++;

+    }

+

+    Buffer -= PadSize;

+

+    Fp = fopen (OutFile, "a+b");

+

+    if (Fp == NULL) {

+      printf ("\nERROR:Opening file %s", OutFile);

+      CleanUpMemory ();

+      return EFI_ABORTED;

+    }

+

+    FileSize = _filelength (fileno (Fp));

+    fseek (Fp, FileSize, SEEK_SET);

+    NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);

+

+    if (Buffer) {

+      free (Buffer);

+    }

+

+    fclose (Fp);

+

+    if (NumByte != (sizeof (UINT8) * PadSize)) {

+      printf ("\nERROR: Copying data from buffer to File %s ", OutFile);

+      CleanUpMemory ();

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // Clean up all the memory which has been allocated so far.

+  //

+  CleanUpMemory ();

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFdImage/Makefile b/edk2/Tools/Source/TianoTools/GenFdImage/Makefile
new file mode 100644
index 0000000..94fafaf
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFdImage/Makefile
@@ -0,0 +1,100 @@
+#/*++

+#   

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Define some macros we use here. Should get rid of them someday and 

+# get rid of the extra level of indirection.

+#

+COMMON_SOURCE      = $(EDK_TOOLS_COMMON)

+

+#

+# Common information

+#

+

+INC=$(INC) \

+    -I "$(TIANO_TOOLS_SOURCE)\GenFvImage"

+

+#

+# Target specific information

+#

+

+TARGET_NAME=GenFdImage

+TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+

+TARGET_LIB = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).lib

+TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenFdImageExe.c"

+TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\GenFdImageExe.h" \

+                     "$(TARGET_SOURCE_DIR)\GenFdImage.h" \

+                     "$(COMMON_SOURCE)\ParseInf.h" \

+                     "$(EDK_SOURCE)\Foundation\Include\TianoCommon.h"

+TARGET_EXE_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib" \

+                  "$(TIANO_TOOLS_OUTPUT)\GenFvImage.lib" \

+                  "$(TIANO_TOOLS_OUTPUT)\PeimFixup.lib"

+

+TARGET_LIB_SOURCE = "$(TARGET_SOURCE_DIR)\GenFdImageLib.c"

+TARGET_LIB_INCLUDE = "$(TARGET_SOURCE_DIR)\GenFdImage.h" \

+                     "$(TIANO_TOOLS_SOURCE)\GenFvImage\GenFvImage.h" \

+                     "$(COMMON_SOURCE)\ParseInf.h" \

+                     "$(EDK_SOURCE)\Foundation\Include\TianoCommon.h"

+TARGET_LIB_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib" \

+                  "$(TIANO_TOOLS_OUTPUT)\GenFvImage.lib" \

+                  "$(TIANO_TOOLS_OUTPUT)\PeimFixup.lib"

+

+

+#

+# Build targets

+#

+

+all: $(TARGET_LIB) $(TARGET_EXE)

+

+#

+# Build EXE

+#

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj

+

+$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_LIB)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)

+

+#

+# Build LIB

+#

+

+$(TARGET_LIB): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj $(TARGET_LIB_LIBS)

+  $(LIB) $(LIB_FLAGS) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj /OUT:$(TARGET_LIB)

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj:  $(TARGET_LIB_SOURCE) $(TARGET_LIB_INCLUDE)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_LIB_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj

+

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* > NUL

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/GenFfsFile/GenFfsFile.c b/edk2/Tools/Source/TianoTools/GenFfsFile/GenFfsFile.c
new file mode 100644
index 0000000..0e93a47
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFfsFile/GenFfsFile.c
@@ -0,0 +1,2645 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenFfsFile.c

+

+Abstract:

+

+  This file contains functions required to generate a Firmware File System

+  file.

+

+--*/

+

+#include "Base.h"

+#include "UefiBaseTypes.h"

+#include "FirmwareVolumeImageFormat.h"

+#include "FirmwareFileSystem.h"

+#include "FirmwareVolumeHeader.h"

+#include "FirmwareVolumeImageFormat.h"

+#include "ParseInf.h"

+#include "EfiCompress.h"

+#include "EfiCustomizedCompress.h"

+#include "Crc32.h"

+#include "GenFfsFile.h"

+#include <stdio.h>

+#include <ctype.h>  // for isalpha()

+//

+// include file for _spawnv

+//

+#ifndef __GNUC__

+#include <process.h>

+#endif

+#include <stdlib.h>

+#include <string.h>

+#include "CommonLib.h"

+#include "EfiUtilityMsgs.h"

+#include "SimpleFileParsing.h"

+

+#define UTILITY_NAME    "GenFfsFile"

+#define TOOLVERSION     "0.32"

+#define MAX_ARRAY_SIZE  100

+

+static

+INT32

+GetNextLine (

+  OUT CHAR8       *Destination,

+  IN FILE         *Package,

+  IN OUT UINT32   *LineNumber

+  );

+

+static

+void

+CheckSlash (

+  IN OUT CHAR8  *String,

+  IN FILE       *In,

+  IN OUT UINT32 *LineNumber

+  );

+

+static

+INT32

+FindSectionInPackage (

+  IN CHAR8        *BuildDirectory,

+  IN FILE         *OverridePackage,

+  IN OUT UINT32   *LineNumber

+  );

+

+static

+STATUS

+ProcessCommandLineArgs (

+  int     Argc,

+  char    *Argv[]

+  );

+

+static

+void

+PrintUsage (

+  void

+  );

+

+//

+// Keep globals in this structure

+//

+static struct {

+  UINT8   BuildDirectory[_MAX_PATH];

+  UINT8   PrimaryPackagePath[_MAX_PATH];

+  UINT8   OverridePackagePath[_MAX_PATH];

+  BOOLEAN Verbose;

+} mGlobals;

+

+static EFI_GUID mZeroGuid = { 0 };

+

+static

+void

+StripQuotes (

+  IN OUT CHAR8 *String

+  )

+/*++

+

+Routine Description:

+

+  Removes quotes and/or whitespace from around a string

+

+Arguments:

+

+ String    - String to remove quotes from

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Index;

+  UINTN Index2;

+  UINTN StrLen;

+

+  Index2  = strspn (String, "\" \t\n");

+  StrLen  = strlen (String);

+

+  for (Index = Index2; String[Index] != '\"', Index < StrLen; Index++) {

+    String[Index - Index2] = String[Index];

+  }

+

+  String[Index - Index2] = 0;

+}

+

+static

+void

+PrintUsage (

+  void

+  )

+/*++

+

+Routine Description:

+

+  Print Error / Help message.

+

+Arguments:

+

+  void

+

+Returns:

+

+  None

+

+--*/

+{

+  printf ("Usage:\n");

+  printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\" -v\n");

+  printf ("   -b \"build directory\":\n ");

+  printf ("       specifies the full path to the component build directory.\n");

+  printf ("   -p1 \"P1_path\":\n");

+  printf ("       specifies fully qualified file name to the primary package file.\n");

+  printf ("       This file will normally exist in the same directory as the makefile\n");

+  printf ("       for the component. Required.\n");

+  printf ("   -p2 \"P2_path\":\n");

+  printf ("       specifies fully qualified file name to the override package file.\n");

+  printf ("       This file will normally exist in the build tip. Optional.\n");

+}

+

+static

+INT32

+TestComment (

+  IN CHAR8  *String,

+  IN FILE   *In

+  )

+/*++

+

+Routine Description:

+

+  Tests input string to see if it is a comment, and if so goes to the next line in the file that is not a comment

+

+Arguments:

+

+  String      - String to test

+

+  In          - Open file to move pointer within

+

+Returns:

+

+  -1          - End of file reached

+   0          - Not a comment

+   1          - Comment bypassed

+

+--*/

+{

+  CHAR8 CharBuffer;

+

+  CharBuffer = 0;

+  if ((String[0] == '/') && (String[1] == '/')) {

+    while (CharBuffer != '\n') {

+      fscanf (In, "%c", &CharBuffer);

+      if (feof (In)) {

+        return -1;

+      }

+    }

+  } else {

+    return 0;

+  }

+

+  return 1;

+}

+

+static

+void

+BreakString (

+  IN CONST CHAR8 *Source,

+  OUT CHAR8      *Destination,

+  IN INTN        Direction

+  )

+/*++

+

+Routine Description:

+

+  Takes an input string and returns either the part before the =, or the part after the =, depending on direction

+

+Arguments:

+

+  Source      - String to break

+

+  Destination - Buffer to place new string in

+

+  Direction   - 0 to return all of source string before =

+                1 to return all of source string after =

+

+Returns:

+

+  None

+

+--*/

+{

+  UINTN Index;

+  UINTN Index2;

+

+  Index   = 0;

+  Index2  = 0;

+

+  if (strchr (Source, '=') == NULL) {

+    strcpy (Destination, Source);

+

+    return ;

+  }

+

+  if (Direction == 0) {

+    //

+    // return part of string before =

+    //

+    while (Source[Index] != '=') {

+      Destination[Index] = Source[Index++];

+    }

+

+    Destination[Index] = 0;

+  } else {

+    //

+    // return part of string after =

+    //

+    strcpy (Destination, strchr (Source, '=') + 1);

+  }

+}

+

+static

+INT32

+GetNextLine (

+  OUT CHAR8       *Destination,

+  IN FILE         *Package,

+  IN OUT UINT32   *LineNumber

+  )

+/*++

+

+Routine Description:

+

+  Gets the next non-commented line from the file

+

+Arguments:

+

+  Destination - Where to put string

+

+  Package     - Package to get string from

+  

+  LineNumber  - The actual line number.

+

+Returns:

+

+  -1          - End of file reached

+   0          - Success

+

+--*/

+{

+  CHAR8 String[_MAX_PATH];

+  fscanf (Package, "%s", &String);

+  if (feof (Package)) {

+    return -1;

+  }

+

+  while (TestComment (String, Package) == 1) {

+    fscanf (Package, "%s", &String);

+    if (feof (Package)) {

+      return -1;

+    }

+  }

+

+  strcpy (Destination, String);

+  return 0;

+}

+

+static

+VOID

+CheckSlash (

+  IN OUT CHAR8  *String,

+  IN FILE       *In,

+  IN OUT UINT32 *LineNumber

+  )

+/*++

+

+Routine Description:

+

+  Checks to see if string is line continuation character, if so goes to next valid line

+

+Arguments:

+

+  String      - String to test

+

+  In          - Open file to move pointer within

+  

+  LineNumber  - The line number.

+

+Returns:

+

+  None

+

+--*/

+{

+  CHAR8 ByteBuffer;

+  ByteBuffer = 0;

+

+  switch (String[0]) {

+

+  case '\\':

+    while (String[0] == '\\') {

+      while (ByteBuffer != '\n') {

+        fscanf (In, "%c", &ByteBuffer);

+      }

+      (*LineNumber)++;

+      if (GetNextLine (String, In, LineNumber) == -1) {

+        return ;

+      }

+    }

+    break;

+

+  case '\n':

+    (*LineNumber)++;

+    while (String[0] == '\n') {

+      if (GetNextLine (String, In, LineNumber) == -1) {

+        return ;

+      }

+    }

+    break;

+

+  default:

+    break;

+

+  }

+

+}

+

+static

+INT32

+FindSectionInPackage (

+  IN CHAR8        *BuildDirectory,

+  IN FILE         *OverridePackage,

+  IN OUT UINT32   *LineNumber

+  )

+/*++

+

+Routine Description:

+

+  Finds the matching section within the package

+

+Arguments:

+

+  BuildDirectory  - name of section to find

+

+  OverridePackage - Package file to search within

+  

+  LineNumber      - The line number.

+

+Returns:

+

+  -1          - End of file reached

+   0          - Success

+

+--*/

+{

+  CHAR8 String[_MAX_PATH];

+  CHAR8 NewString[_MAX_PATH];

+  String[0] = 0;

+

+  while (strcmp (BuildDirectory, String) != 0) {

+    if (GetNextLine (NewString, OverridePackage, LineNumber) != 0) {

+      return -1;

+    }

+

+    if (NewString[0] == '[') {

+      if (NewString[strlen (NewString) - 1] != ']') {

+        //

+        // have to construct string.

+        //

+        strcpy (String, NewString + 1);

+

+        while (1) {

+          fscanf (OverridePackage, "%s", &NewString);

+          if (feof (OverridePackage)) {

+            return -1;

+          }

+

+          if (NewString[0] != ']') {

+            if (strlen (String) != 0) {

+              strcat (String, " ");

+            }

+

+            strcat (String, NewString);

+            if (String[strlen (String) - 1] == ']') {

+              String[strlen (String) - 1] = 0;

+              break;

+            }

+          } else {

+            break;

+          }

+        }

+      } else {

+        NewString[strlen (NewString) - 1] = 0;

+        strcpy (String, NewString + 1);

+      }

+    }

+  }

+

+  return 0;

+}

+

+static

+EFI_STATUS

+GenSimpleGuidSection (

+  IN OUT UINT8  *FileBuffer,

+  IN OUT UINT32 *BufferSize,

+  IN UINT32     DataSize,

+  IN EFI_GUID   SignGuid,

+  IN UINT16     GuidedSectionAttributes

+  )

+/*++

+

+Routine Description:

+

+  add GUIDed section header for the data buffer.

+  data stays in same location (overwrites source data).

+

+Arguments:

+

+  FileBuffer  - Buffer containing data to sign

+

+  BufferSize  - On input, the size of FileBuffer. On output, the size of

+                actual section data (including added section header).

+

+  DataSize    - Length of data to Sign

+

+  SignGuid    - Guid to be add.

+  

+  GuidedSectionAttributes - The section attribute.

+

+Returns:

+

+  EFI_SUCCESS           - Successful

+  EFI_OUT_OF_RESOURCES  - Not enough resource.

+

+--*/

+{

+  UINT32                    TotalSize;

+

+  EFI_GUID_DEFINED_SECTION  GuidSectionHeader;

+  UINT8                     *SwapBuffer;

+

+  SwapBuffer = NULL;

+

+  if (DataSize == 0) {

+    *BufferSize = 0;

+

+    return EFI_SUCCESS;

+  }

+

+  TotalSize = DataSize + sizeof (EFI_GUID_DEFINED_SECTION);

+  GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;

+  GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalSize & 0xff);

+  GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalSize & 0xff00) >> 8);

+  GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalSize & 0xff0000) >> 16);

+  memcpy (&(GuidSectionHeader.SectionDefinitionGuid), &SignGuid, sizeof (EFI_GUID));

+  GuidSectionHeader.Attributes  = GuidedSectionAttributes;

+  GuidSectionHeader.DataOffset  = sizeof (EFI_GUID_DEFINED_SECTION);

+

+  SwapBuffer                    = (UINT8 *) malloc (DataSize);

+  if (SwapBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  memcpy (SwapBuffer, FileBuffer, DataSize);

+  memcpy (FileBuffer, &GuidSectionHeader, sizeof (EFI_GUID_DEFINED_SECTION));

+  memcpy (FileBuffer + sizeof (EFI_GUID_DEFINED_SECTION), SwapBuffer, DataSize);

+

+  //

+  // Make sure section ends on a DWORD boundary

+  //

+  while ((TotalSize & 0x03) != 0) {

+    FileBuffer[TotalSize] = 0;

+    TotalSize++;

+  }

+

+  *BufferSize = TotalSize;

+

+  if (SwapBuffer != NULL) {

+    free (SwapBuffer);

+  }

+

+  return EFI_SUCCESS;

+}

+

+static

+EFI_STATUS

+CompressSection (

+  UINT8  *FileBuffer,

+  UINT32 *BufferSize,

+  UINT32 DataSize,

+  CHAR8  *Type

+  )

+/*++

+

+Routine Description:

+

+  Compress the data and add section header for the compressed data.

+  Compressed data (with section header) stays in same location as the source

+  (overwrites source data).

+

+Arguments:

+

+  FileBuffer  - Buffer containing data to Compress

+

+  BufferSize  - On input, the size of FileBuffer. On output, the size of

+                actual compressed data (including added section header).

+                When buffer is too small, this value indicates the size needed.

+

+  DataSize    - The size of data to compress

+

+  Type        - The compression type (not used currently).

+                Assume EFI_HEAVY_COMPRESSION.

+

+Returns:

+

+  EFI_BUFFER_TOO_SMALL - Buffer size is too small.

+  EFI_UNSUPPORTED      - Compress type can not be supported.

+  EFI_SUCCESS          - Successful

+  EFI_OUT_OF_RESOURCES - Not enough resource.

+

+--*/

+{

+  EFI_STATUS              Status;

+  UINT8                   *CompData;

+  UINT32                  CompSize;

+  UINT32                  TotalSize;

+  EFI_COMPRESSION_SECTION CompressionSet;

+  UINT8                   CompressionType;

+  COMPRESS_FUNCTION       CompressFunction;

+

+  Status            = EFI_SUCCESS;

+  CompData          = NULL;

+  CompSize          = 0;

+  TotalSize         = 0;

+  CompressFunction  = NULL;

+

+  //

+  // Get the compress type

+  //

+  if (strcmpi (Type, "Dummy") == 0) {

+    //

+    // Added "Dummy" to keep backward compatibility.

+    //

+    CompressionType   = EFI_STANDARD_COMPRESSION;

+    CompressFunction  = (COMPRESS_FUNCTION) Compress;

+

+  } else if (strcmpi (Type, "LZH") == 0) {

+    //

+    // EFI stardard compression (LZH)

+    //

+    CompressionType   = EFI_STANDARD_COMPRESSION;

+    CompressFunction  = (COMPRESS_FUNCTION) Compress;

+

+  } else {

+    //

+    // Customized compression

+    //

+    Status = SetCustomizedCompressionType (Type);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    CompressionType   = EFI_CUSTOMIZED_COMPRESSION;

+    CompressFunction  = (COMPRESS_FUNCTION) CustomizedCompress;

+  }

+  //

+  // Compress the raw data

+  //

+  Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    CompData = malloc (CompSize);

+    if (!CompData) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize);

+  }

+

+  if (EFI_ERROR (Status)) {

+    if (CompData != NULL) {

+      free (CompData);

+    }

+

+    return Status;

+  }

+

+  TotalSize = CompSize + sizeof (EFI_COMPRESSION_SECTION);

+

+  //

+  // Buffer too small?

+  //

+  if (TotalSize > *BufferSize) {

+    *BufferSize = TotalSize;

+    if (CompData != NULL) {

+      free (CompData);

+    }

+

+    return EFI_BUFFER_TOO_SMALL;

+  }

+  //

+  // Add the section header for the compressed data

+  //

+  CompressionSet.CommonHeader.Type    = EFI_SECTION_COMPRESSION;

+  CompressionSet.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff);

+  CompressionSet.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8);

+  CompressionSet.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16);

+  CompressionSet.CompressionType      = CompressionType;

+  CompressionSet.UncompressedLength   = DataSize;

+

+  //

+  // Copy header and data to the buffer

+  //

+  memcpy (FileBuffer, &CompressionSet, sizeof (EFI_COMPRESSION_SECTION));

+  memcpy (FileBuffer + sizeof (CompressionSet), CompData, CompSize);

+

+  //

+  // Make sure section ends on a DWORD boundary

+  //

+  while ((TotalSize & 0x03) != 0) {

+    FileBuffer[TotalSize] = 0;

+    TotalSize++;

+  }

+

+  *BufferSize = TotalSize;

+

+  if (CompData != NULL) {

+    free (CompData);

+  }

+

+  return EFI_SUCCESS;

+}

+

+static

+void

+StripParens (

+  IN OUT CHAR8 *String

+  )

+/*++

+

+Routine Description:

+

+  Removes Parenthesis from around a string

+

+Arguments:

+

+ String    - String to remove parens from

+

+Returns:

+

+  None

+

+--*/

+{

+  INT32 Index;

+

+  if (String[0] != '(') {

+    return ;

+  }

+

+  for (Index = 1; String[Index] != ')'; Index++) {

+    String[Index - 1] = String[Index];

+    if (String[Index] == 0) {

+      return ;

+    }

+  }

+

+  String[Index - 1] = 0;

+

+  return ;

+}

+

+static

+void

+StripEqualMark (

+  IN OUT CHAR8 *String

+  )

+/*++

+

+Routine Description:

+

+  Removes Equal Mark from around a string

+

+Arguments:

+

+ String    - String to remove equal mark from

+

+Returns:

+

+  None

+

+--*/

+{

+  INT32 Index;

+

+  if (String[0] != '=' && String[strlen (String) - 1] != '=') {

+    return ;

+  }

+

+  if (String[0] == '=') {

+

+    for (Index = 1; String[Index] != 0; Index++) {

+      String[Index - 1] = String[Index];

+    }

+

+    String[Index - 1] = 0;

+  }

+

+  if (String[strlen (String) - 1] == '=') {

+    String[strlen (String) - 1] = 0;

+  }

+

+  return ;

+}

+

+static

+INT32

+ProcessEnvironmentVariable (

+  IN CHAR8  *Buffer,

+  OUT CHAR8 *NewBuffer

+  )

+/*++

+

+Routine Description:

+

+  Converts environment variables to values

+

+Arguments:

+

+  Buffer      - Buffer containing Environment Variable String

+

+  NewBuffer   - Buffer containing value of environment variable

+

+

+Returns:

+

+  Number of characters from Buffer used

+

+--*/

+{

+  INT32 Index;

+  INT32 Index2;

+  CHAR8 VariableBuffer[_MAX_PATH];

+

+  Index   = 2;

+  Index2  = 0;

+

+  while (Buffer[Index] != ')') {

+    VariableBuffer[Index - 2] = Buffer[Index++];

+  }

+

+  VariableBuffer[Index - 2] = 0;

+  Index++;

+

+  if (getenv (VariableBuffer) != NULL) {

+    strcpy (NewBuffer, getenv (VariableBuffer));

+  } else {

+    printf ("Environment variable %s not found!\n", VariableBuffer);

+  }

+

+  return Index;

+}

+

+static

+void

+SplitAttributesField (

+  IN CHAR8       *Buffer,

+  IN CHAR8       *AttributesArray[],

+  IN OUT UINT32  *NumberOfAttributes

+  )

+/*

+  NumberOfAttributes: on input, it specifies the current number of attributes

+                      stored in AttributeArray.

+                      on output, it is updated to the latest number of attributes

+                      stored in AttributesArray.

+*/

+{

+  UINT32  Index;

+  UINT32  Index2;

+  UINT32  z;

+  CHAR8   *CharBuffer;

+

+  CharBuffer  = NULL;

+  CharBuffer  = (CHAR8 *) malloc (_MAX_PATH);

+  ZeroMem (CharBuffer, _MAX_PATH);

+

+  for (Index = 0, z = 0, Index2 = 0; Index < strlen (Buffer); Index++) {

+

+    if (Buffer[Index] != '|') {

+      CharBuffer[z] = Buffer[Index];

+      z++;

+    } else {

+

+      CharBuffer[z] = 0;

+      AttributesArray[*NumberOfAttributes + Index2] = CharBuffer;

+      Index2++;

+

+      //

+      // allocate new char buffer for the next attributes string

+      //

+      CharBuffer = (CHAR8 *) malloc (_MAX_PATH);

+      ZeroMem (CharBuffer, _MAX_PATH);

+      z = 0;

+    }

+  }

+

+  CharBuffer[z] = 0;

+  //

+  // record the last attributes string in the Buffer

+  //

+  AttributesArray[*NumberOfAttributes + Index2] = CharBuffer;

+  Index2++;

+

+  *NumberOfAttributes += Index2;

+

+  return ;

+}

+

+static

+INT32

+GetToolArguments (

+  CHAR8       *ToolArgumentsArray[],

+  FILE        *Package,

+  CHAR8       **PtrInputFileName,

+  CHAR8       **PtrOutputFileName,

+  EFI_GUID    *Guid,

+  UINT16      *GuidedSectionAttributes

+  )

+{

+  CHAR8       Buffer[_MAX_PATH];

+  BOOLEAN     ArgumentsFlag;

+  BOOLEAN     InputFlag;

+  BOOLEAN     OutputFlag;

+  BOOLEAN     GuidFlag;

+  BOOLEAN     AttributesFlag;

+  UINT32      argc;

+  UINT32      Index2;

+  UINT32      z;

+  CHAR8       *CharBuffer;

+  INT32       Index;

+  INT32       ReturnValue;

+  EFI_STATUS  Status;

+

+  CHAR8       *AttributesArray[MAX_ARRAY_SIZE];

+  UINT32      NumberOfAttributes;

+  CHAR8       *InputFileName;

+  CHAR8       *OutputFileName;

+  UINT32      LineNumber;

+  Buffer[_MAX_PATH];

+

+  ArgumentsFlag   = FALSE;

+  InputFlag       = FALSE;

+  OutputFlag      = FALSE;

+  GuidFlag        = FALSE;

+  AttributesFlag  = FALSE;

+  //

+  // Start at 1, since ToolArgumentsArray[0]

+  // is the program name.

+  //

+  argc            = 1;

+  Index2              = 0;

+

+  z                   = 0;

+  ReturnValue         = 0;

+  NumberOfAttributes  = 0;

+  InputFileName       = NULL;

+  OutputFileName      = NULL;

+

+  ZeroMem (Buffer, _MAX_PATH);

+  ZeroMem (AttributesArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE);

+  LineNumber = 0;

+  while (Buffer[0] != ')') {

+

+    if (GetNextLine (Buffer, Package, &LineNumber) != -1) {

+      CheckSlash (Buffer, Package, &LineNumber);

+      StripEqualMark (Buffer);

+    } else {

+      Error (NULL, 0, 0, "failed to get next line from package file", NULL);

+      return -1;

+    }

+

+    if (Buffer[0] == ')') {

+      break;

+    } else if (strcmpi (Buffer, "ARGS") == 0) {

+

+      ArgumentsFlag   = TRUE;

+      AttributesFlag  = FALSE;

+      continue;

+

+    } else if (strcmpi (Buffer, "INPUT") == 0) {

+

+      InputFlag       = TRUE;

+      ArgumentsFlag   = FALSE;

+      AttributesFlag  = FALSE;

+      continue;

+

+    } else if (strcmpi (Buffer, "OUTPUT") == 0) {

+

+      OutputFlag      = TRUE;

+      ArgumentsFlag   = FALSE;

+      AttributesFlag  = FALSE;

+      continue;

+

+    } else if (strcmpi (Buffer, "GUID") == 0) {

+

+      GuidFlag        = TRUE;

+      ArgumentsFlag   = FALSE;

+      AttributesFlag  = FALSE;

+      //

+      // fetch the GUID for the section

+      //

+      continue;

+

+    } else if (strcmpi (Buffer, "ATTRIBUTES") == 0) {

+

+      AttributesFlag  = TRUE;

+      ArgumentsFlag   = FALSE;

+      //

+      // fetch the GUIDed Section's Attributes

+      //

+      continue;

+

+    } else if (strcmpi (Buffer, "") == 0) {

+      continue;

+    }

+    //

+    // get all command arguments into ToolArgumentsArray

+    //

+    if (ArgumentsFlag) {

+

+      StripEqualMark (Buffer);

+

+      CharBuffer = (CHAR8 *) malloc (_MAX_PATH);

+      if (CharBuffer == NULL) {

+        goto ErrorExit;

+      }

+

+      ZeroMem (CharBuffer, sizeof (_MAX_PATH));

+

+      ToolArgumentsArray[argc] = CharBuffer;

+

+      if (Buffer[0] == '$') {

+        Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]);

+        //

+        // if there is string after the environment variable, cat it.

+        //

+        if ((UINT32) Index < strlen (Buffer)) {

+          strcat (ToolArgumentsArray[argc], &Buffer[Index]);

+        }

+      } else {

+        strcpy (ToolArgumentsArray[argc], Buffer);

+      }

+

+      argc += 1;

+      ToolArgumentsArray[argc] = NULL;

+      continue;

+    }

+

+    if (InputFlag) {

+

+      StripEqualMark (Buffer);

+

+      InputFileName = (CHAR8 *) malloc (_MAX_PATH);

+      if (InputFileName == NULL) {

+        goto ErrorExit;

+      }

+

+      ZeroMem (InputFileName, sizeof (_MAX_PATH));

+

+      if (Buffer[0] == '$') {

+        Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName);

+        //

+        // if there is string after the environment variable, cat it.

+        //

+        if ((UINT32) Index < strlen (Buffer)) {

+          strcat (InputFileName, &Buffer[Index]);

+        }

+      } else {

+        strcpy (InputFileName, Buffer);

+      }

+

+      InputFlag = FALSE;

+      continue;

+    }

+

+    if (OutputFlag) {

+

+      StripEqualMark (Buffer);

+

+      OutputFileName = (CHAR8 *) malloc (_MAX_PATH);

+      if (OutputFileName == NULL) {

+        goto ErrorExit;

+      }

+

+      ZeroMem (OutputFileName, sizeof (_MAX_PATH));

+

+      if (Buffer[0] == '$') {

+        Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName);

+        //

+        // if there is string after the environment variable, cat it.

+        //

+        if ((UINT32) Index < strlen (Buffer)) {

+          strcat (OutputFileName, &Buffer[Index]);

+        }

+      } else {

+        strcpy (OutputFileName, Buffer);

+      }

+

+      OutputFlag = FALSE;

+      continue;

+    }

+

+    if (GuidFlag) {

+

+      StripEqualMark (Buffer);

+

+      Status = StringToGuid (Buffer, Guid);

+      if (EFI_ERROR (Status)) {

+        ReturnValue = -1;

+        goto ErrorExit;

+      }

+

+      GuidFlag = FALSE;

+    }

+

+    if (AttributesFlag) {

+

+      StripEqualMark (Buffer);

+

+      //

+      // there might be no space between each attribute in the statement,

+      // split them aside and return each attribute string

+      // in the AttributesArray

+      //

+      SplitAttributesField (Buffer, AttributesArray, &NumberOfAttributes);

+    }

+  }

+  //

+  // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"INPUT",InputVariable,j);

+  // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"OUTPUT",&TargetFileName,1);

+  //

+  for (z = 0; z < NumberOfAttributes; z++) {

+    if (strcmpi (AttributesArray[z], "PROCESSING_REQUIRED") == 0) {

+      *GuidedSectionAttributes |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;

+    } else if (strcmpi (AttributesArray[z], "AUTH_STATUS_VALID") == 0) {

+      *GuidedSectionAttributes |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;

+    }

+  }

+

+ErrorExit:

+

+  for (Index2 = 0; Index2 < MAX_ARRAY_SIZE; Index2++) {

+    if (AttributesArray[Index2] == NULL) {

+      break;

+    }

+

+    free (AttributesArray[Index2]);

+  }

+

+  *PtrInputFileName   = InputFileName;

+  *PtrOutputFileName  = OutputFileName;

+

+  return ReturnValue;

+}

+

+static

+INT32

+ProcessScript (

+  IN OUT UINT8   *FileBuffer,

+  IN FILE        *Package,

+  IN CHAR8       *BuildDirectory,

+  IN BOOLEAN     ForceUncompress

+  )

+/*++

+

+Routine Description:

+

+  Signs the section, data stays in same location

+

+Arguments:

+

+  FileBuffer  - Data Buffer

+

+  Package     - Points to curly brace in Image Script

+

+  BuildDirectory     - Name of the source directory parameter

+  

+  ForceUncompress   - Whether to force uncompress.

+

+Returns:

+

+  Number of bytes added to file buffer

+  -1 on error

+

+--*/

+{

+  EFI_STATUS  Status;

+  UINT32      Size;

+  CHAR8       Buffer[_MAX_PATH];

+  CHAR8       Type[_MAX_PATH];

+  CHAR8       FileName[_MAX_PATH];

+  CHAR8       NewBuffer[_MAX_PATH];

+  INT32       Index3;

+  INT32       Index2;

+  UINT32      ReturnValue;

+  UINT8       ByteBuffer;

+  FILE        *InFile;

+  UINT32      SourceDataSize;

+  CHAR8       *ToolArgumentsArray[MAX_ARRAY_SIZE];

+  CHAR8       *OutputFileName;

+  CHAR8       *InputFileName;

+  CHAR8       ToolName[_MAX_PATH];

+  FILE        *OutputFile;

+  FILE        *InputFile;

+  UINT8       Temp;

+  int         returnint;

+  INT32       Index;

+  UINT32      LineNumber;

+  BOOLEAN     IsError;

+  EFI_GUID    SignGuid;

+  UINT16      GuidedSectionAttributes;

+  UINT8       *TargetFileBuffer;

+

+  OutputFileName          = NULL;

+  InputFileName           = NULL;

+  OutputFile              = NULL;

+  InputFile               = NULL;

+  IsError                 = FALSE;

+  GuidedSectionAttributes = 0;

+  TargetFileBuffer        = NULL;

+

+  Size                    = 0;

+  LineNumber              = 0;

+  Buffer[0]               = 0;

+  for (Index3 = 0; Index3 < MAX_ARRAY_SIZE; ++Index3) {

+    ToolArgumentsArray[Index3] = NULL;

+  }

+

+  while (Buffer[0] != '}') {

+    if (GetNextLine (Buffer, Package, &LineNumber) != -1) {

+      CheckSlash (Buffer, Package, &LineNumber);

+    } else {

+      printf ("ERROR in IMAGE SCRIPT!\n");

+      IsError = TRUE;

+      goto Done;

+    }

+

+    if (strcmpi (Buffer, "Compress") == 0) {

+      //

+      // Handle compress

+      //

+      //

+      // read compression type

+      //

+      if (GetNextLine (Buffer, Package, &LineNumber) != -1) {

+        CheckSlash (Buffer, Package, &LineNumber);

+      }

+

+      StripParens (Buffer);

+      if (Buffer[0] == '$') {

+        ProcessEnvironmentVariable (&Buffer[0], Type);

+      } else {

+        strcpy (Type, Buffer);

+      }

+      //

+      // build buffer

+      //

+      while (Buffer[0] != '{') {

+        if (GetNextLine (Buffer, Package, &LineNumber) != -1) {

+          CheckSlash (Buffer, Package, &LineNumber);

+        }

+      }

+

+      ReturnValue = ProcessScript (&FileBuffer[Size], Package, BuildDirectory, ForceUncompress);

+      if (ReturnValue == -1) {

+        IsError = TRUE;

+        goto Done;

+      }

+      //

+      // Call compress routine on buffer.

+      // Occasionally, compressed data + section header would

+      // be largere than the source and EFI_BUFFER_TOO_SMALL is

+      // returned from CompressSection()

+      //

+      SourceDataSize = ReturnValue;

+

+      if (!ForceUncompress) {

+

+        Status = CompressSection (

+                  &FileBuffer[Size],

+                  &ReturnValue,

+                  SourceDataSize,

+                  Type

+                  );

+

+        if (Status == EFI_BUFFER_TOO_SMALL) {

+          Status = CompressSection (

+                    &FileBuffer[Size],

+                    &ReturnValue,

+                    SourceDataSize,

+                    Type

+                    );

+        }

+

+        if (EFI_ERROR (Status)) {

+          IsError = TRUE;

+          goto Done;

+        }

+      }

+

+      Size += ReturnValue;

+

+    } else if (strcmpi (Buffer, "Tool") == 0) {

+

+      ZeroMem (ToolName, _MAX_PATH);

+      ZeroMem (ToolArgumentsArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE);

+      ZeroMem (&SignGuid, sizeof (EFI_GUID));

+

+      //

+      // handle signing Tool

+      //

+      while (Buffer[0] != '(') {

+        if (GetNextLine (Buffer, Package, &LineNumber) != -1) {

+          CheckSlash (Buffer, Package, &LineNumber);

+        }

+      }

+

+      if (strcmpi (Buffer, "(") == 0) {

+        if (GetNextLine (Buffer, Package, &LineNumber) != -1) {

+          CheckSlash (Buffer, Package, &LineNumber);

+        }

+      }

+

+      StripParens (Buffer);

+

+      if (Buffer[0] == '$') {

+        Index = ProcessEnvironmentVariable (&Buffer[0], ToolName);

+        //

+        // if there is string after the environment variable, cat it.

+        //

+        if ((UINT32) Index < strlen (Buffer)) {

+          strcat (ToolName, &Buffer[Index]);

+        }

+      } else {

+        strcpy (ToolName, Buffer);

+      }

+

+      ToolArgumentsArray[0] = ToolName;

+

+      //

+      // read ARGS

+      //

+      if (GetToolArguments (

+            ToolArgumentsArray,

+            Package,

+            &InputFileName,

+            &OutputFileName,

+            &SignGuid,

+            &GuidedSectionAttributes

+            ) == -1) {

+        IsError = TRUE;

+        goto Done;

+      }

+      //

+      // if the tool need input file,

+      // dump the file buffer to the specified input file.

+      //

+      if (InputFileName != NULL) {

+        InputFile = fopen (InputFileName, "wb");

+        if (InputFile == NULL) {

+          Error (NULL, 0, 0, InputFileName, "failed to open output file for writing");

+          IsError = TRUE;

+          goto Done;

+        }

+

+        fwrite (FileBuffer, sizeof (UINT8), Size, InputFile);

+        fclose (InputFile);

+        InputFile = NULL;

+        free (InputFileName);

+        InputFileName = NULL;

+      }

+      //

+      // dispatch signing tool

+      //

+#ifdef __GNUC__

+      {

+        char CommandLine[1000];

+        sprintf(CommandLine, "%s %s", ToolName, ToolArgumentsArray);

+        returnint = system(CommandLine);

+      }

+#else

+      returnint = _spawnv (_P_WAIT, ToolName, ToolArgumentsArray);

+#endif

+      if (returnint != 0) {

+        Error (NULL, 0, 0, ToolName, "external tool failed");

+        IsError = TRUE;

+        goto Done;

+      }

+      //

+      // if the tool has output file,

+      // dump the output file to the file buffer

+      //

+      if (OutputFileName != NULL) {

+

+        OutputFile = fopen (OutputFileName, "rb");

+        if (OutputFile == NULL) {

+          Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");

+          IsError = TRUE;

+          goto Done;

+        }

+

+        TargetFileBuffer  = &FileBuffer[Size];

+        SourceDataSize    = Size;

+

+        fread (&Temp, sizeof (UINT8), 1, OutputFile);

+        while (!feof (OutputFile)) {

+          FileBuffer[Size++] = Temp;

+          fread (&Temp, sizeof (UINT8), 1, OutputFile);

+        }

+

+        while ((Size & 0x03) != 0) {

+          FileBuffer[Size] = 0;

+          Size++;

+        }

+

+        SourceDataSize = Size - SourceDataSize;

+

+        fclose (OutputFile);

+        OutputFile = NULL;

+        free (OutputFileName);

+        OutputFileName = NULL;

+

+        if (CompareGuid (&SignGuid, &mZeroGuid) != 0) {

+          ReturnValue = SourceDataSize;

+          Status = GenSimpleGuidSection (

+                    TargetFileBuffer,

+                    &ReturnValue,

+                    SourceDataSize,

+                    SignGuid,

+                    GuidedSectionAttributes

+                    );

+          if (EFI_ERROR (Status)) {

+            IsError = TRUE;

+            goto Done;

+          }

+

+          Size = ReturnValue;

+        }

+      }

+

+    } else if (Buffer[0] != '}') {

+      //

+      // if we are here, we should see either a file name,

+      // or a }.

+      //

+      Index3      = 0;

+      FileName[0] = 0;

+      //

+      // Prepend the build directory to the file name if the

+      // file name does not already contain a full path.

+      //

+      if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) {

+        sprintf (FileName, "%s\\", BuildDirectory);

+      }

+

+      while (Buffer[Index3] != '\n') {

+        if (Buffer[Index3] == '$') {

+          Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer);

+          strcat (FileName, NewBuffer);

+        }

+

+        if (Buffer[Index3] == 0) {

+          break;

+        } else {

+          Index2              = strlen (FileName);

+          FileName[Index2++]  = Buffer[Index3++];

+          FileName[Index2]    = 0;

+        }

+      }

+

+      InFile = fopen (FileName, "rb");

+      if (InFile == NULL) {

+        Error (NULL, 0, 0, FileName, "failed to open file for reading");

+        IsError = TRUE;

+        goto Done;

+      }

+

+      fread (&ByteBuffer, sizeof (UINT8), 1, InFile);

+      while (!feof (InFile)) {

+        FileBuffer[Size++] = ByteBuffer;

+        fread (&ByteBuffer, sizeof (UINT8), 1, InFile);

+      }

+

+      fclose (InFile);

+      InFile = NULL;

+

+      //

+      // Make sure section ends on a DWORD boundary

+      //

+      while ((Size & 0x03) != 0) {

+        FileBuffer[Size] = 0;

+        Size++;

+      }

+

+    }

+  }

+

+Done:

+  for (Index3 = 1; Index3 < MAX_ARRAY_SIZE; Index3++) {

+    if (ToolArgumentsArray[Index3] == NULL) {

+      break;

+    }

+

+    free (ToolArgumentsArray[Index3]);

+  }

+

+  if (IsError) {

+    return -1;

+  }

+

+  return Size;

+

+}

+

+static

+UINT8

+StringToType (

+  IN CHAR8 *String

+  )

+/*++

+

+Routine Description:

+

+  Converts File Type String to value.  EFI_FV_FILETYPE_ALL indicates that an

+  unrecognized file type was specified.

+

+Arguments:

+

+  String    - File type string

+

+Returns:

+

+  File Type Value

+

+--*/

+{

+  if (strcmpi (String, "EFI_FV_FILETYPE_RAW") == 0) {

+    return EFI_FV_FILETYPE_RAW;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_FREEFORM") == 0) {

+    return EFI_FV_FILETYPE_FREEFORM;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_SECURITY_CORE") == 0) {

+    return EFI_FV_FILETYPE_SECURITY_CORE;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_PEI_CORE") == 0) {

+    return EFI_FV_FILETYPE_PEI_CORE;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_DXE_CORE") == 0) {

+    return EFI_FV_FILETYPE_DXE_CORE;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_PEIM") == 0) {

+    return EFI_FV_FILETYPE_PEIM;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_DRIVER") == 0) {

+    return EFI_FV_FILETYPE_DRIVER;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER") == 0) {

+    return EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_APPLICATION") == 0) {

+    return EFI_FV_FILETYPE_APPLICATION;

+  }

+

+  if (strcmpi (String, "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE") == 0) {

+    return EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE;

+  }

+

+  return EFI_FV_FILETYPE_ALL;

+}

+

+static

+UINT32

+AdjustFileSize (

+  IN UINT8  *FileBuffer,

+  IN UINT32 FileSize

+  )

+/*++

+

+Routine Description:

+  Adjusts file size to insure sectioned file is exactly the right length such

+  that it ends on exactly the last byte of the last section.  ProcessScript()

+  may have padded beyond the end of the last section out to a 4 byte boundary.

+  This padding is stripped.

+

+Arguments:

+  FileBuffer  - Data Buffer - contains a section stream

+  FileSize    - Size of FileBuffer as returned from ProcessScript()

+

+Returns:

+  Corrected size of file.

+

+--*/

+{

+  UINT32                    TotalLength;

+  UINT32                    CurrentLength;

+  UINT32                    SectionLength;

+  UINT32                    SectionStreamLength;

+  EFI_COMMON_SECTION_HEADER *SectionHeader;

+  EFI_COMMON_SECTION_HEADER *NextSectionHeader;

+

+  TotalLength         = 0;

+  CurrentLength       = 0;

+  SectionStreamLength = FileSize;

+

+  SectionHeader       = (EFI_COMMON_SECTION_HEADER *) FileBuffer;

+

+  while (TotalLength < SectionStreamLength) {

+    SectionLength = *((UINT32 *) SectionHeader->Size) & 0x00ffffff;

+    TotalLength += SectionLength;

+

+    if (TotalLength == SectionStreamLength) {

+      return TotalLength;

+    }

+    //

+    // Move to the next byte following the section...

+    //

+    SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength);

+    CurrentLength = (UINTN) SectionHeader - (UINTN) FileBuffer;

+

+    //

+    // Figure out where the next section begins

+    //

+    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + 3);

+    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader &~ (UINTN) 3);

+    TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;

+    SectionHeader = NextSectionHeader;

+  }

+

+  return CurrentLength;

+}

+

+static

+INT32

+MainEntry (

+  INT32     argc,

+  CHAR8     *argv[],

+  BOOLEAN   ForceUncompress

+  )

+/*++

+

+Routine Description:

+

+  MainEntry function.

+

+Arguments:

+

+  argc            - Number of command line parameters.

+  argv            - Array of pointers to command line parameter strings.

+  ForceUncompress - If TRUE, force to do not compress the sections even if compression

+                    is specified in the script. Otherwise, FALSE.

+

+Returns:

+  STATUS_SUCCESS  - Function exits successfully.

+  STATUS_ERROR    - Some error occurred during execution.

+

+--*/

+{

+  FILE                    *PrimaryPackage;

+  FILE                    *OverridePackage;

+  FILE                    *Out;

+  CHAR8                   BaseName[_MAX_PATH];

+  EFI_GUID                FfsGuid;

+  CHAR8                   GuidString[_MAX_PATH];

+  EFI_FFS_FILE_HEADER     FileHeader;

+  CHAR8                   FileType[_MAX_PATH];

+  EFI_FFS_FILE_ATTRIBUTES FfsAttrib;

+  EFI_FFS_FILE_ATTRIBUTES FfsAttribDefined;

+  UINT64                  FfsAlignment;

+  UINT32                  FfsAlignment32;

+  CHAR8                   InputString[_MAX_PATH];

+  BOOLEAN                 ImageScriptInOveride;

+  UINT32                  FileSize;

+  UINT8                   *FileBuffer;

+  EFI_STATUS              Status;

+  UINT32                  LineNumber;

+  EFI_FFS_FILE_TAIL       TailValue;

+

+  BaseName[0]       = 0;

+  FileType[0]       = 0;

+  FfsAttrib         = 0;

+  FfsAttribDefined  = 0;

+  FfsAlignment      = 0;

+  FfsAlignment32    = 0;

+  PrimaryPackage    = NULL;

+  Out               = NULL;

+  OverridePackage   = NULL;

+  FileBuffer        = NULL;

+

+  strcpy (GuidString, "00000000-0000-0000-0000-000000000000");

+  Status = StringToGuid (GuidString, &FfsGuid);

+  if (Status != 0) {

+    Error (NULL, 0, 0, GuidString, "error parsing GUID string");

+    return STATUS_ERROR;

+  }

+

+  GuidString[0]         = 0;

+  ImageScriptInOveride  = FALSE;

+  //

+  // Initialize the simple file parsing routines. Then open

+  // the primary package file for parsing.

+  //

+  SFPInit ();

+  if (SFPOpenFile (mGlobals.PrimaryPackagePath) != STATUS_SUCCESS) {

+    Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file");

+    goto Done;

+  }

+  //

+  // First token in the file must be "PACKAGE.INF"

+  //

+  if (!SFPIsToken ("PACKAGE.INF")) {

+    Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'PACKAGE.INF'", NULL);

+    goto Done;

+  }

+  //

+  // Find the [.] section

+  //

+  if (!SFPSkipToToken ("[.]")) {

+    Error (mGlobals.PrimaryPackagePath, 1, 0, "could not locate [.] section in package file", NULL);

+    goto Done;

+  }

+  //

+  // Start parsing the data. The algorithm is essentially the same for each keyword:

+  //   1. Identify the keyword

+  //   2. Verify that the keyword/value pair has not already been defined

+  //   3. Set some flag indicating that the keyword/value pair has been defined

+  //   4. Skip over the "="

+  //   5. Get the value, which may be a number, TRUE, FALSE, or a string.

+  //

+  while (1) {

+    if (SFPIsToken ("BASE_NAME")) {

+      //

+      // Found BASE_NAME, format:

+      //   BASE_NAME = MyBaseName

+      //

+      if (BaseName[0] != 0) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "BASE_NAME already defined", NULL);

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (!SFPGetNextToken (BaseName, sizeof (BaseName))) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid base name", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("IMAGE_SCRIPT")) {

+      //

+      // Found IMAGE_SCRIPT. Break out and process below.

+      //

+      break;

+    } else if (SFPIsToken ("FFS_FILEGUID")) {

+      //

+      // found FILEGUID, format:

+      //   FFS_FILEGUID = F7845C4F-EDF5-42C5-BD8F-A02AF63DD93A

+      //

+      if (GuidString[0] != 0) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILEGUID already defined", NULL);

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (SFPGetGuidToken (GuidString, sizeof (GuidString)) != TRUE) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected file GUID", NULL);

+        goto Done;

+      }

+

+      Status = StringToGuid (GuidString, &FfsGuid);

+      if (Status != 0) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid file GUID", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("FFS_FILETYPE")) {

+      //

+      // ***********************************************************************

+      //

+      // Found FFS_FILETYPE, format:

+      //  FFS_FILETYPE = EFI_FV_FILETYPE_APPLICATION

+      //

+      if (FileType[0] != 0) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILETYPE previously defined", NULL);

+        goto Done;

+      }

+

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (!SFPGetNextToken (FileType, sizeof (FileType))) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid FFS_FILETYPE", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("FFS_ATTRIB_HEADER_EXTENSION")) {

+      //

+      // ***********************************************************************

+      //

+      // Found: FFS_ATTRIB_HEADER_EXTENSION = FALSE

+      // Spec says the bit is for future expansion, and must be false.

+      //

+      if (FfsAttribDefined & FFS_ATTRIB_HEADER_EXTENSION) {

+        Error (

+          mGlobals.PrimaryPackagePath,

+          SFPGetLineNumber (),

+          0,

+          "FFS_ATTRIB_HEADER_EXTENSION previously defined",

+          NULL

+          );

+        goto Done;

+      }

+

+      FfsAttribDefined |= FFS_ATTRIB_HEADER_EXTENSION;

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (SFPIsToken ("TRUE")) {

+        Error (

+          mGlobals.PrimaryPackagePath,

+          SFPGetLineNumber (),

+          0,

+          "only FFS_ATTRIB_HEADER_EXTENSION = FALSE is supported",

+          NULL

+          );

+        goto Done;

+      } else if (SFPIsToken ("FALSE")) {

+        //

+        // Default is FALSE

+        //

+      } else {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'FALSE'", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("FFS_ATTRIB_TAIL_PRESENT")) {

+      //

+      // ***********************************************************************

+      //

+      // Found: FFS_ATTRIB_TAIL_PRESENT = TRUE | FALSE

+      //

+      if (FfsAttribDefined & FFS_ATTRIB_TAIL_PRESENT) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_TAIL_PRESENT previously defined", NULL);

+        goto Done;

+      }

+

+      FfsAttribDefined |= FFS_ATTRIB_TAIL_PRESENT;

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (SFPIsToken ("TRUE")) {

+        FfsAttrib |= FFS_ATTRIB_TAIL_PRESENT;

+      } else if (SFPIsToken ("FALSE")) {

+        //

+        // Default is FALSE

+        //

+      } else {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("FFS_ATTRIB_RECOVERY")) {

+      //

+      // ***********************************************************************

+      //

+      // Found: FFS_ATTRIB_RECOVERY = TRUE | FALSE

+      //

+      if (FfsAttribDefined & FFS_ATTRIB_RECOVERY) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_RECOVERY previously defined", NULL);

+        goto Done;

+      }

+

+      FfsAttribDefined |= FFS_ATTRIB_RECOVERY;

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (SFPIsToken ("TRUE")) {

+        FfsAttrib |= FFS_ATTRIB_RECOVERY;

+      } else if (SFPIsToken ("FALSE")) {

+        //

+        // Default is FALSE

+        //

+      } else {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("FFS_ATTRIB_CHECKSUM")) {

+      //

+      // ***********************************************************************

+      //

+      // Found: FFS_ATTRIB_CHECKSUM = TRUE | FALSE

+      //

+      if (FfsAttribDefined & FFS_ATTRIB_CHECKSUM) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_CHECKSUM previously defined", NULL);

+        goto Done;

+      }

+

+      FfsAttribDefined |= FFS_ATTRIB_CHECKSUM;

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (SFPIsToken ("TRUE")) {

+        FfsAttrib |= FFS_ATTRIB_CHECKSUM;

+      } else if (SFPIsToken ("FALSE")) {

+        //

+        // Default is FALSE

+        //

+      } else {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);

+        goto Done;

+      }

+    } else if (SFPIsToken ("FFS_ALIGNMENT") || SFPIsToken ("FFS_ATTRIB_DATA_ALIGNMENT")) {

+      //

+      // ***********************************************************************

+      //

+      // Found FFS_ALIGNMENT, formats:

+      //   FFS_ALIGNMENT = 0-7

+      //   FFS_ATTRIB_DATA_ALIGNMENT = 0-7

+      //

+      if (FfsAttribDefined & FFS_ATTRIB_DATA_ALIGNMENT) {

+        Error (

+          mGlobals.PrimaryPackagePath,

+          SFPGetLineNumber (),

+          0,

+          "FFS_ALIGNMENT/FFS_ATTRIB_DATA_ALIGNMENT previously defined",

+          NULL

+          );

+        goto Done;

+      }

+

+      FfsAttribDefined |= FFS_ATTRIB_DATA_ALIGNMENT;

+      if (!SFPIsToken ("=")) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL);

+        goto Done;

+      }

+

+      if (!SFPGetNumber (&FfsAlignment32)) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected numeric value for alignment", NULL);

+        goto Done;

+      }

+

+      if (FfsAlignment32 > 7) {

+        Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 0 <= alignment <= 7", NULL);

+        goto Done;

+      }

+

+      FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment32) << 3);

+    } else {

+      SFPGetNextToken (InputString, sizeof (InputString));

+      Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, InputString, "unrecognized/unexpected token");

+      goto Done;

+    }

+  }

+  //

+  // Close the primary package file

+  //

+  SFPCloseFile ();

+  //

+  // TODO: replace code below with basically a copy of the code above. Don't

+  // forget to reset the FfsAttribDefined variable first. Also, you'll need

+  // to somehow keep track of whether or not the basename is defined multiple

+  // times in the override package. Ditto on the file GUID.

+  //

+  if (mGlobals.OverridePackagePath[0] != 0) {

+    OverridePackage = fopen (mGlobals.OverridePackagePath, "r");

+    //

+    // NOTE: For package override to work correctly, the code below must be modified to

+    //       SET or CLEAR bits properly. For example, if the primary package set

+    //       FFS_ATTRIB_CHECKSUM = TRUE, and the override set FFS_ATTRIB_CHECKSUM = FALSE, then

+    //       we'd need to clear the bit below. Since this is not happening, I'm guessing that

+    //       the override functionality is not being used, so should be made obsolete. If I'm

+    //       wrong, and it is being used, then it needs to be fixed. Thus emit an error if it is

+    //       used, and we'll address it then.  4/10/2003

+    //

+    Error (__FILE__, __LINE__, 0, "package override functionality is not implemented correctly", NULL);

+    goto Done;

+  } else {

+    OverridePackage = NULL;

+  }

+

+#ifdef OVERRIDE_SUPPORTED

+  if (OverridePackage != NULL) {

+    //

+    // Parse override package file

+    //

+    fscanf (OverridePackage, "%s", &InputString);

+    if (strcmpi (InputString, "PACKAGE.INF") != 0) {

+      Error (mGlobals.OverridePackagePath, 1, 0, "invalid package file", "expected 'PACKAGE.INF'");

+      goto Done;

+    }

+    //

+    // Match [dir] to Build Directory

+    //

+    if (FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber) != 0) {

+      Error (mGlobals.OverridePackagePath, 1, 0, mGlobals.BuildDirectory, "section not found in package file");

+      goto Done;

+    }

+

+    InputString[0] = 0;

+    while ((InputString[0] != '[') && (!feof (OverridePackage))) {

+      if (GetNextLine (InputString, OverridePackage, &LineNumber) != -1) {

+        if (InputString[0] != '[') {

+here:

+          if (strcmpi (InputString, "BASE_NAME") == 0) {

+            //

+            // found BASE_NAME, next is = and string.

+            //

+            fscanf (OverridePackage, "%s", &InputString);

+            CheckSlash (InputString, OverridePackage, &LineNumber);

+            if (strlen (InputString) == 1) {

+              //

+              // string is just =

+              //

+              fscanf (OverridePackage, "%s", &InputString);

+              CheckSlash (InputString, OverridePackage, &LineNumber);

+              strcpy (BaseName, InputString);

+            } else {

+              BreakString (InputString, InputString, 1);

+              strcpy (BaseName, InputString);

+            }

+          } else if (strcmpi (InputString, "IMAGE_SCRIPT") == 0) {

+            //

+            // found IMAGE_SCRIPT, come back later to process it

+            //

+            ImageScriptInOveride = TRUE;

+            fscanf (OverridePackage, "%s", &InputString);

+          } else if (strcmpi (InputString, "FFS_FILEGUID") == 0) {

+            //

+            // found FILEGUID, next is = and string.

+            //

+            fscanf (OverridePackage, "%s", &InputString);

+            CheckSlash (InputString, OverridePackage, &LineNumber);

+            if (strlen (InputString) == 1) {

+              //

+              // string is just =

+              //

+              fscanf (OverridePackage, "%s", &InputString);

+              CheckSlash (InputString, OverridePackage, &LineNumber);

+              Status = StringToGuid (InputString, &FfsGuid);

+              if (Status != 0) {

+                Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format");

+                goto Done;

+              }

+            } else {

+              BreakString (InputString, InputString, 1);

+              Status = StringToGuid (InputString, &FfsGuid);

+              if (Status != 0) {

+                Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format");

+                goto Done;

+              }

+            }

+          } else if (strcmpi (InputString, "FFS_FILETYPE") == 0) {

+            //

+            // found FILETYPE, next is = and string.

+            //

+            fscanf (OverridePackage, "%s", &InputString);

+            CheckSlash (InputString, OverridePackage, &LineNumber);

+            if (strlen (InputString) == 1) {

+              //

+              // string is just =

+              //

+              fscanf (OverridePackage, "%s", &InputString);

+              CheckSlash (InputString, OverridePackage, &LineNumber);

+              strcpy (FileType, InputString);

+            } else {

+              BreakString (InputString, InputString, 1);

+              strcpy (FileType, InputString);

+            }

+

+          } else if (strcmpi (InputString, "FFS_ATTRIB_RECOVERY") == 0) {

+            //

+            // found FFS_ATTRIB_RECOVERY, next is = and string.

+            //

+            fscanf (OverridePackage, "%s", &InputString);

+            CheckSlash (InputString, OverridePackage, &LineNumber);

+            if (strlen (InputString) == 1) {

+              //

+              // string is just =

+              //

+              fscanf (OverridePackage, "%s", &InputString);

+              CheckSlash (InputString, OverridePackage, &LineNumber);

+              if (strcmpi (InputString, "TRUE") == 0) {

+                FfsAttrib |= FFS_ATTRIB_RECOVERY;

+              }

+            } else {

+              BreakString (InputString, InputString, 1);

+              if (strcmpi (InputString, "TRUE") == 0) {

+                FfsAttrib |= FFS_ATTRIB_RECOVERY;

+              }

+            }

+          } else if (strcmpi (InputString, "FFS_ATTRIB_CHECKSUM") == 0) {

+            //

+            // found FFS_ATTRIB_CHECKSUM, next is = and string.

+            //

+            fscanf (OverridePackage, "%s", &InputString);

+            CheckSlash (InputString, OverridePackage, &LineNumber);

+            if (strlen (InputString) == 1) {

+              //

+              // string is just =

+              //

+              fscanf (OverridePackage, "%s", &InputString);

+              CheckSlash (InputString, OverridePackage, &LineNumber);

+              if (strcmpi (InputString, "TRUE") == 0) {

+                FfsAttrib |= FFS_ATTRIB_CHECKSUM;

+              }

+            } else {

+              BreakString (InputString, InputString, 1);

+              if (strcmpi (InputString, "TRUE") == 0) {

+                FfsAttrib |= FFS_ATTRIB_CHECKSUM;

+              }

+            }

+          } else if (strcmpi (InputString, "FFS_ALIGNMENT") == 0) {

+            //

+            // found FFS_ALIGNMENT, next is = and string.

+            //

+            fscanf (OverridePackage, "%s", &InputString);

+            CheckSlash (InputString, OverridePackage, &LineNumber);

+            if (strlen (InputString) == 1) {

+              //

+              // string is just =

+              //

+              fscanf (OverridePackage, "%s", &InputString);

+              CheckSlash (InputString, OverridePackage, &LineNumber);

+            } else {

+              BreakString (InputString, InputString, 1);

+            }

+

+            AsciiStringToUint64 (InputString, FALSE, &FfsAlignment);

+            if (FfsAlignment > 7) {

+              Error (mGlobals.OverridePackagePath, 1, 0, InputString, "invalid FFS_ALIGNMENT value");

+              goto Done;

+            }

+

+            FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment) << 3);

+          } else if (strchr (InputString, '=') != NULL) {

+            BreakString (InputString, String, 1);

+            fseek (OverridePackage, (-1 * (strlen (String) + 1)), SEEK_CUR);

+            BreakString (InputString, InputString, 0);

+            goto here;

+          }

+        }

+      }

+    }

+  }

+#endif // #ifdef OVERRIDE_SUPPORTED

+  //

+  // Require that they specified a file GUID at least, since that's how we're

+  // naming the file.

+  //

+  if (GuidString[0] == 0) {

+    Error (mGlobals.PrimaryPackagePath, 1, 0, "FFS_FILEGUID must be specified", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // Build Header and process image script

+  //

+  FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 16) * sizeof (UINT8));

+  if (FileBuffer == NULL) {

+    Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);

+    goto Done;

+  }

+

+  FileSize = 0;

+  if (ImageScriptInOveride) {

+#ifdef OVERRIDE_SUPORTED

+    rewind (OverridePackage);

+    LineNumber = 0;

+    FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber);

+    while (strcmpi (InputString, "IMAGE_SCRIPT") != 0) {

+      GetNextLine (InputString, OverridePackage, &LineNumber);

+      CheckSlash (InputString, OverridePackage, &LineNumber);

+      if (strchr (InputString, '=') != NULL) {

+        BreakString (InputString, InputString, 0);

+      }

+    }

+

+    while (InputString[0] != '{') {

+      GetNextLine (InputString, OverridePackage, &LineNumber);

+      CheckSlash (InputString, OverridePackage, &LineNumber);

+    }

+    //

+    // Found start of image script, process it

+    //

+    FileSize += ProcessScript (FileBuffer, OverridePackage, mGlobals.BuildDirectory, ForceUncompress);

+    if (FileSize == -1) {

+      return -1;

+    }

+

+    if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) {

+      FileSize = AdjustFileSize (FileBuffer, FileSize);

+    }

+

+    if (BaseName[0] == '\"') {

+      StripQuotes (BaseName);

+    }

+

+    if (BaseName[0] != 0) {

+      sprintf (InputString, "%s-%s", GuidString, BaseName);

+    } else {

+      strcpy (InputString, GuidString);

+    }

+

+    switch (StringToType (FileType)) {

+

+    case EFI_FV_FILETYPE_SECURITY_CORE:

+      strcat (InputString, ".SEC");

+      break;

+

+    case EFI_FV_FILETYPE_PEIM:

+    case EFI_FV_FILETYPE_PEI_CORE:

+    case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:

+      strcat (InputString, ".PEI");

+      break;

+

+    case EFI_FV_FILETYPE_DRIVER:

+    case EFI_FV_FILETYPE_DXE_CORE:

+      strcat (InputString, ".DXE");

+      break;

+

+    case EFI_FV_FILETYPE_APPLICATION:

+      strcat (InputString, ".APP");

+      break;

+

+    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:

+      strcat (InputString, ".FVI");

+      break;

+

+    case EFI_FV_FILETYPE_ALL:

+      Error (mGlobals.OverridePackagePath, 1, 0, "invalid FFS file type for this utility", NULL);

+      goto Done;

+

+    default:

+      strcat (InputString, ".FFS");

+      break;

+    }

+

+    if (ForceUncompress) {

+      strcat (InputString, ".ORG");

+    }

+

+    Out = fopen (InputString, "wb");

+    if (Out == NULL) {

+      Error (NULL, 0, 0, InputString, "could not open output file for writing");

+      goto Done;

+    }

+    //

+    // create ffs header

+    //

+    memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));

+    memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID));

+    FileHeader.Type       = StringToType (FileType);

+    FileHeader.Attributes = FfsAttrib;

+    //

+    // Now FileSize includes the EFI_FFS_FILE_HEADER

+    //

+    FileSize += sizeof (EFI_FFS_FILE_HEADER);

+    FileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);

+    FileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);

+    FileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);

+    //

+    // Fill in checksums and state, these must be zero for checksumming

+    //

+    // FileHeader.IntegrityCheck.Checksum.Header = 0;

+    // FileHeader.IntegrityCheck.Checksum.File = 0;

+    // FileHeader.State = 0;

+    //

+    FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (

+                                                  (UINT8 *) &FileHeader,

+                                                  sizeof (EFI_FFS_FILE_HEADER)

+                                                  );

+    if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {

+      FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) &FileHeader, FileSize);

+    } else {

+      FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+    }

+

+    FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

+    //

+    // write header

+    //

+    if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) {

+      Error (NULL, 0, 0, "failed to write file header to output file", NULL);

+      goto Done;

+    }

+    //

+    // write data

+    //

+    if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) {

+      Error (NULL, 0, 0, "failed to write all bytes to output file", NULL);

+      goto Done;

+    }

+

+    fclose (Out);

+    Out = NULL;

+#endif // #ifdef OVERRIDE_SUPPORTED

+  } else {

+    //

+    // Open primary package file and process the IMAGE_SCRIPT section

+    //

+    PrimaryPackage = fopen (mGlobals.PrimaryPackagePath, "r");

+    if (PrimaryPackage == NULL) {

+      Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file");

+      goto Done;

+    }

+

+    LineNumber = 1;

+    FindSectionInPackage (".", PrimaryPackage, &LineNumber);

+    while (strcmpi (InputString, "IMAGE_SCRIPT") != 0) {

+      GetNextLine (InputString, PrimaryPackage, &LineNumber);

+      CheckSlash (InputString, PrimaryPackage, &LineNumber);

+      if (strchr (InputString, '=') != NULL) {

+        BreakString (InputString, InputString, 0);

+      }

+    }

+

+    while (InputString[0] != '{') {

+      GetNextLine (InputString, PrimaryPackage, &LineNumber);

+      CheckSlash (InputString, PrimaryPackage, &LineNumber);

+    }

+    //

+    // Found start of image script, process it

+    //

+    FileSize += ProcessScript (FileBuffer, PrimaryPackage, mGlobals.BuildDirectory, ForceUncompress);

+    if (FileSize == -1) {

+      goto Done;

+    }

+

+    if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) {

+      FileSize = AdjustFileSize (FileBuffer, FileSize);

+    }

+

+    if (BaseName[0] == '\"') {

+      StripQuotes (BaseName);

+    }

+

+    if (BaseName[0] != 0) {

+      sprintf (InputString, "%s-%s", GuidString, BaseName);

+    } else {

+      strcpy (InputString, GuidString);

+    }

+

+    switch (StringToType (FileType)) {

+

+    case EFI_FV_FILETYPE_SECURITY_CORE:

+      strcat (InputString, ".SEC");

+      break;

+

+    case EFI_FV_FILETYPE_PEIM:

+    case EFI_FV_FILETYPE_PEI_CORE:

+    case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:

+      strcat (InputString, ".PEI");

+      break;

+

+    case EFI_FV_FILETYPE_DRIVER:

+    case EFI_FV_FILETYPE_DXE_CORE:

+      strcat (InputString, ".DXE");

+      break;

+

+    case EFI_FV_FILETYPE_APPLICATION:

+      strcat (InputString, ".APP");

+      break;

+

+    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:

+      strcat (InputString, ".FVI");

+      break;

+

+    case EFI_FV_FILETYPE_ALL:

+      Error (mGlobals.PrimaryPackagePath, 1, 0, "invalid FFS file type for this utility", NULL);

+      goto Done;

+

+    default:

+      strcat (InputString, ".FFS");

+      break;

+    }

+

+    if (ForceUncompress) {

+      strcat (InputString, ".ORG");

+    }

+

+    Out = fopen (InputString, "wb");

+    if (Out == NULL) {

+      Error (NULL, 0, 0, InputString, "failed to open output file for writing");

+      goto Done;

+    }

+    //

+    // Initialize the FFS file header

+    //

+    memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));

+    memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID));

+    FileHeader.Type       = StringToType (FileType);

+    FileHeader.Attributes = FfsAttrib;

+    //

+    // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER

+    //

+    FileSize += sizeof (EFI_FFS_FILE_HEADER);

+    //

+    // If using a tail, then it adds two bytes

+    //

+    if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+      //

+      // Tail is not allowed for pad and 0-length files

+      //

+      if ((FileHeader.Type == EFI_FV_FILETYPE_FFS_PAD) || (FileSize == sizeof (EFI_FFS_FILE_HEADER))) {

+        Error (

+          mGlobals.PrimaryPackagePath,

+          1,

+          0,

+          "FFS_ATTRIB_TAIL_PRESENT=TRUE is invalid for PAD or 0-length files",

+          NULL

+          );

+        goto Done;

+      }

+

+      FileSize += sizeof (EFI_FFS_FILE_TAIL);

+    }

+

+    FileHeader.Size[0]  = (UINT8) (FileSize & 0xFF);

+    FileHeader.Size[1]  = (UINT8) ((FileSize & 0xFF00) >> 8);

+    FileHeader.Size[2]  = (UINT8) ((FileSize & 0xFF0000) >> 16);

+    //

+    // Fill in checksums and state, they must be 0 for checksumming.

+    //

+    // FileHeader.IntegrityCheck.Checksum.Header = 0;

+    // FileHeader.IntegrityCheck.Checksum.File = 0;

+    // FileHeader.State = 0;

+    //

+    FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (

+                                                  (UINT8 *) &FileHeader,

+                                                  sizeof (EFI_FFS_FILE_HEADER)

+                                                  );

+    if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {

+      //

+      // Cheating here.  Since the header checksums, just calculate the checksum of the body.

+      // Checksum does not include the tail

+      //

+      if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+        FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (

+                                                    FileBuffer,

+                                                    FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL)

+                                                    );

+      } else {

+        FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (

+                                                    FileBuffer,

+                                                    FileSize - sizeof (EFI_FFS_FILE_HEADER)

+                                                    );

+      }

+    } else {

+      FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+    }

+    //

+    // Set the state now. Spec says the checksum assumes the state is 0

+    //

+    FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

+    //

+    // If there is a tail, then set it

+    //

+    if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+      TailValue = FileHeader.IntegrityCheck.TailReference;

+      TailValue = (UINT16) (~TailValue);

+      memcpy (

+        (UINT8 *) FileBuffer + FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL),

+        &TailValue,

+        sizeof (TailValue)

+        );

+    }

+    //

+    // Write the FFS file header

+    //

+    if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) {

+      Error (NULL, 0, 0, "failed to write file header contents", NULL);

+      goto Done;

+    }

+    //

+    // Write data

+    //

+    if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) {

+      Error (NULL, 0, 0, "failed to write file contents", NULL);

+      goto Done;

+    }

+  }

+

+Done:

+  SFPCloseFile ();

+  if (Out != NULL) {

+    fclose (Out);

+  }

+

+  if (PrimaryPackage != NULL) {

+    fclose (PrimaryPackage);

+  }

+

+  if (FileBuffer != NULL) {

+    free (FileBuffer);

+  }

+

+  if (OverridePackage != NULL) {

+    fclose (OverridePackage);

+  }

+

+  return GetUtilityStatus ();

+}

+

+int

+main (

+  INT32 argc,

+  CHAR8 *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Main function.

+

+Arguments:

+

+  argc - Number of command line parameters.

+  argv - Array of pointers to parameter strings.

+

+Returns:

+  STATUS_SUCCESS - Utility exits successfully.

+  STATUS_ERROR   - Some error occurred during execution.

+

+--*/

+{

+  STATUS  Status;

+  //

+  // Set the name of our utility for error reporting purposes.

+  //

+  SetUtilityName (UTILITY_NAME);

+  Status = ProcessCommandLineArgs (argc, argv);

+  if (Status != STATUS_SUCCESS) {

+    return Status;

+  }

+

+  Status = MainEntry (argc, argv, TRUE);

+  if (Status == STATUS_SUCCESS) {

+    MainEntry (argc, argv, FALSE);

+  }

+  //

+  // If any errors were reported via the standard error reporting

+  // routines, then the status has been saved. Get the value and

+  // return it to the caller.

+  //

+  return GetUtilityStatus ();

+}

+

+static

+STATUS

+ProcessCommandLineArgs (

+  int     Argc,

+  char    *Argv[]

+  )

+/*++

+

+Routine Description:

+  Process the command line arguments.

+

+Arguments:

+  Argc - as passed in to main()

+  Argv - as passed in to main()

+

+Returns:

+  STATUS_SUCCESS    - arguments all ok

+  STATUS_ERROR      - problem with args, so caller should exit

+

+--*/

+{

+  //

+  // If no args, then print usage instructions and return an error

+  //

+  if (Argc == 1) {

+    PrintUsage ();

+    return STATUS_ERROR;

+  }

+

+  memset (&mGlobals, 0, sizeof (mGlobals));

+  Argc--;

+  Argv++;

+  while (Argc > 0) {

+    if (strcmpi (Argv[0], "-b") == 0) {

+      //

+      // OPTION: -b BuildDirectory

+      // Make sure there is another argument, then save it to our globals.

+      //

+      if (Argc < 2) {

+        Error (NULL, 0, 0, "-b option requires the build directory name", NULL);

+        return STATUS_ERROR;

+      }

+

+      if (mGlobals.BuildDirectory[0]) {

+        Error (NULL, 0, 0, Argv[0], "option can only be specified once");

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.BuildDirectory, Argv[1]);

+      Argc--;

+      Argv++;

+    } else if (strcmpi (Argv[0], "-p1") == 0) {

+      //

+      // OPTION: -p1 PrimaryPackageFile

+      // Make sure there is another argument, then save it to our globals.

+      //

+      if (Argc < 2) {

+        Error (NULL, 0, 0, Argv[0], "option requires the primary package file name");

+        return STATUS_ERROR;

+      }

+

+      if (mGlobals.PrimaryPackagePath[0]) {

+        Error (NULL, 0, 0, Argv[0], "option can only be specified once");

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.PrimaryPackagePath, Argv[1]);

+      Argc--;

+      Argv++;

+    } else if (strcmpi (Argv[0], "-p2") == 0) {

+      //

+      // OPTION: -p2 OverridePackageFile

+      // Make sure there is another argument, then save it to our globals.

+      //

+      if (Argc < 2) {

+        Error (NULL, 0, 0, Argv[0], "option requires the override package file name");

+        return STATUS_ERROR;

+      }

+

+      if (mGlobals.OverridePackagePath[0]) {

+        Error (NULL, 0, 0, Argv[0], "option can only be specified once");

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.OverridePackagePath, Argv[1]);

+      Argc--;

+      Argv++;

+    } else if (strcmpi (Argv[0], "-v") == 0) {

+      //

+      // OPTION: -v       verbose

+      //

+      mGlobals.Verbose = TRUE;

+    } else if (strcmpi (Argv[0], "-h") == 0) {

+      //

+      // OPTION: -h      help

+      //

+      PrintUsage ();

+      return STATUS_ERROR;

+    } else if (strcmpi (Argv[0], "-?") == 0) {

+      //

+      // OPTION:  -?      help

+      //

+      PrintUsage ();

+      return STATUS_ERROR;

+    } else {

+      Error (NULL, 0, 0, Argv[0], "unrecognized option");

+      PrintUsage ();

+      return STATUS_ERROR;

+    }

+

+    Argv++;

+    Argc--;

+  }

+  //

+  // Must have at least specified the package file name

+  //

+  if (mGlobals.PrimaryPackagePath[0] == 0) {

+    Error (NULL, 0, 0, "must specify primary package file", NULL);

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFfsFile/GenFfsFile.h b/edk2/Tools/Source/TianoTools/GenFfsFile/GenFfsFile.h
new file mode 100644
index 0000000..695809c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFfsFile/GenFfsFile.h
@@ -0,0 +1,36 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenFfsFile.h 

+

+Abstract:

+

+  Header file for GenFfsFile.

+

+--*/

+

+//

+// Module Coded to Tiano Coding Conventions

+//

+#ifndef _EFI_GEN_FFSFILE_H

+#define _EFI_GEN_FFSFILE_H

+

+//

+// External Files Referenced

+//

+#include "Base.h"

+#include "UefiBaseTypes.h"

+#include "FirmwareVolumeImageFormat.h"

+#include "MyAlloc.h"

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFfsFile/SimpleFileParsing.c b/edk2/Tools/Source/TianoTools/GenFfsFile/SimpleFileParsing.c
new file mode 100644
index 0000000..d3933db
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFfsFile/SimpleFileParsing.c
@@ -0,0 +1,969 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  SimpleFileParsing.c  

+

+Abstract:

+

+  Generic but simple file parsing routines.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+#include "Base.h"

+#include "UefiBaseTypes.h"

+#include "EfiUtilityMsgs.h"

+#include "SimpleFileParsing.h"

+

+#define MAX_PATH                    255

+#define MAX_NEST_DEPTH              20  // just in case we get in an endless loop.

+#define MAX_STRING_IDENTIFIER_NAME  100 // number of wchars

+#define MAX_LINE_LEN                400

+

+#define T_CHAR_SPACE                ' '

+#define T_CHAR_NULL                 0

+#define T_CHAR_CR                   '\r'

+#define T_CHAR_TAB                  '\t'

+#define T_CHAR_LF                   '\n'

+#define T_CHAR_SLASH                '/'

+#define T_CHAR_BACKSLASH            '\\'

+#define T_CHAR_DOUBLE_QUOTE         '"'

+#define T_CHAR_LC_X                 'x'

+#define T_CHAR_0                    '0'

+

+//

+// We keep a linked list of these for the source files we process

+//

+typedef struct _SOURCE_FILE {

+  FILE                *Fptr;

+  T_CHAR              *FileBuffer;

+  T_CHAR              *FileBufferPtr;

+  UINT32              FileSize;

+  INT8                FileName[MAX_PATH];

+  UINT32              LineNum;

+  BOOLEAN             EndOfFile;

+  BOOLEAN             SkipToHash;

+  struct _SOURCE_FILE *Previous;

+  struct _SOURCE_FILE *Next;

+  T_CHAR              ControlCharacter;

+} SOURCE_FILE;

+

+//

+// Here's all our module globals.

+//

+static struct {

+  SOURCE_FILE SourceFile;

+  BOOLEAN     Verbose;

+} mGlobals;

+

+static

+UINT32

+t_strcmp (

+  T_CHAR *Buffer,

+  T_CHAR *Str

+  );

+

+static

+UINT32

+t_strncmp (

+  T_CHAR *Str1,

+  T_CHAR *Str2,

+  UINT32 Len

+  );

+

+static

+UINT32

+t_strlen (

+  T_CHAR *Str

+  );

+

+static

+void

+RewindFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+SkipTo (

+  SOURCE_FILE *SourceFile,

+  T_CHAR      TChar,

+  BOOLEAN     StopAfterNewline

+  );

+

+static

+BOOLEAN

+IsWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+UINT32

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+PreprocessFile (

+  SOURCE_FILE *SourceFile

+  );

+

+//

+// static

+// T_CHAR *

+// GetQuotedString (

+//  SOURCE_FILE *SourceFile,

+//  BOOLEAN     Optional

+//  );

+//

+static

+T_CHAR  *

+t_strcpy (

+  T_CHAR *Dest,

+  T_CHAR *Src

+  );

+

+static

+STATUS

+ProcessIncludeFile (

+  SOURCE_FILE *SourceFile,

+  SOURCE_FILE *ParentSourceFile

+  );

+

+static

+STATUS

+ParseFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+FILE    *

+FindFile (

+  IN INT8     *FileName,

+  OUT INT8    *FoundFileName,

+  IN UINT32   FoundFileNameLen

+  );

+

+static

+STATUS

+ProcessFile (

+  SOURCE_FILE *SourceFile

+  );

+

+STATUS

+SFPInit (

+  VOID

+  )

+{

+  memset ((void *) &mGlobals, 0, sizeof (mGlobals));

+  return STATUS_SUCCESS;

+}

+

+UINT32

+SFPGetLineNumber (

+  VOID

+  )

+{

+  return mGlobals.SourceFile.LineNum;

+}

+

+/*++

+

+Routine Description:

+  Return the line number of the file we're parsing. Used

+  for error reporting purposes.

+

+Arguments:

+  None.

+

+Returns:

+  The line number, or 0 if no file is being processed

+

+--*/

+T_CHAR *

+SFPGetFileName (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Return the name of the file we're parsing. Used

+  for error reporting purposes.

+

+Arguments:

+  None.

+

+Returns:

+  A pointer to the file name. Null if no file is being

+  processed.

+

+--*/

+{

+  if (mGlobals.SourceFile.FileName[0]) {

+    return mGlobals.SourceFile.FileName;

+  }

+

+  return NULL;

+}

+

+STATUS

+SFPOpenFile (

+  IN INT8   *FileName

+  )

+/*++

+

+Routine Description:

+  Open a file for parsing.

+

+Arguments:

+  FileName  - name of the file to parse

+

+Returns:

+  

+

+--*/

+{

+  STATUS  Status;

+  t_strcpy (mGlobals.SourceFile.FileName, FileName);

+  Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL);

+  return Status;

+}

+

+BOOLEAN

+SFPIsToken (

+  T_CHAR *Str

+  )

+/*++

+

+Routine Description:

+  Check to see if the specified token is found at

+  the current position in the input file.

+

+Arguments:

+  Str - the token to look for

+

+Returns:

+  TRUE - the token is next

+  FALSE - the token is not next

+

+Notes:

+  We do a simple string comparison on this function. It is

+  the responsibility of the caller to ensure that the token

+  is not a subset of some other token.

+

+  The file pointer is advanced past the token in the input file.

+

+--*/

+{

+  UINT32  Len;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+

+  if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {

+    mGlobals.SourceFile.FileBufferPtr += Len;

+    return TRUE;

+  }

+

+  return FALSE;

+

+}

+

+BOOLEAN

+SFPGetNextToken (

+  T_CHAR *Str,

+  UINT32 Len

+  )

+{

+  UINT32  Index;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  Index = 0;

+  while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {

+    if (IsWhiteSpace (&mGlobals.SourceFile)) {

+      if (Index > 0) {

+        Str[Index] = 0;

+        return TRUE;

+      }

+

+      return FALSE;

+    } else {

+      Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];

+      mGlobals.SourceFile.FileBufferPtr++;

+      Index++;

+    }

+  }

+

+  return FALSE;

+}

+

+BOOLEAN

+SFPSkipToToken (

+  T_CHAR *Str

+  )

+{

+  UINT32  Len;

+  T_CHAR  *SavePos;

+  Len     = t_strlen (Str);

+  SavePos = mGlobals.SourceFile.FileBufferPtr;

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  while (!EndOfFile (&mGlobals.SourceFile)) {

+    if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) {

+      mGlobals.SourceFile.FileBufferPtr += Len;

+      return TRUE;

+    }

+

+    mGlobals.SourceFile.FileBufferPtr++;

+    SkipWhiteSpace (&mGlobals.SourceFile);

+  }

+

+  mGlobals.SourceFile.FileBufferPtr = SavePos;

+  return FALSE;

+}

+

+BOOLEAN

+SFPGetNumber (

+  UINT32   *Value

+  )

+/*++

+

+Routine Description:

+  Check the token at the current file position for a numeric value.

+  May be either decimal or hex.

+

+Arguments:

+  Value  - pointer where to store the value

+

+Returns:

+  FALSE    - current token is not a number

+  TRUE     - current token is a number

+

+--*/

+{

+  //

+  //  UINT32 Len;

+  //

+  SkipWhiteSpace (&mGlobals.SourceFile);

+  if (EndOfFile (&mGlobals.SourceFile)) {

+    return FALSE;

+  }

+

+  if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+    //

+    // Check for hex value

+    //

+    if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) {

+      if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) {

+        return FALSE;

+      }

+

+      mGlobals.SourceFile.FileBufferPtr += 2;

+      sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value);

+      while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+        mGlobals.SourceFile.FileBufferPtr++;

+      }

+

+      return TRUE;

+    } else {

+      *Value = atoi (mGlobals.SourceFile.FileBufferPtr);

+      while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {

+        mGlobals.SourceFile.FileBufferPtr++;

+      }

+

+      return TRUE;

+    }

+  } else {

+    return FALSE;

+  }

+}

+

+STATUS

+SFPCloseFile (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Close the file being parsed.

+

+Arguments:

+  None.

+

+Returns:

+  STATUS_SUCCESS - the file was closed 

+  STATUS_ERROR   - no file is currently open

+

+--*/

+{

+  if (mGlobals.SourceFile.FileBuffer != NULL) {

+    free (mGlobals.SourceFile.FileBuffer);

+    memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile));

+    return STATUS_SUCCESS;

+  }

+

+  return STATUS_ERROR;

+}

+

+static

+STATUS

+ProcessIncludeFile (

+  SOURCE_FILE *SourceFile,

+  SOURCE_FILE *ParentSourceFile

+  )

+/*++

+

+Routine Description:

+

+  Given a source file, open the file and parse it

+  

+Arguments:

+

+  SourceFile        - name of file to parse

+  ParentSourceFile  - for error reporting purposes, the file that #included SourceFile.

+

+Returns:

+

+  Standard status.

+  

+--*/

+{

+  static UINT32 NestDepth = 0;

+  INT8          FoundFileName[MAX_PATH];

+  STATUS        Status;

+

+  Status = STATUS_SUCCESS;

+  NestDepth++;

+  //

+  // Print the file being processed. Indent so you can tell the include nesting

+  // depth.

+  //

+  if (mGlobals.Verbose) {

+    fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);

+  }

+

+  //

+  // Make sure we didn't exceed our maximum nesting depth

+  //

+  if (NestDepth > MAX_NEST_DEPTH) {

+    Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);

+    Status = STATUS_ERROR;

+    goto Finish;

+  }

+  //

+  // Try to open the file locally, and if that fails try along our include paths.

+  //

+  strcpy (FoundFileName, SourceFile->FileName);

+  if ((SourceFile->Fptr = fopen (FoundFileName, "r")) == NULL) {

+    //

+    // Try to find it among the paths if it has a parent (that is, it is included

+    // by someone else).

+    //

+    Error (NULL, 0, 0, SourceFile->FileName, "file not found");

+    return STATUS_ERROR;

+  }

+  //

+  // Process the file found

+  //

+  ProcessFile (SourceFile);

+Finish:

+  //

+  // Close open files and return status

+  //

+  if (SourceFile->Fptr != NULL) {

+    fclose (SourceFile->Fptr);

+    SourceFile->Fptr = NULL;

+  }

+

+  return Status;

+}

+

+static

+STATUS

+ProcessFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  //

+  // Get the file size, and then read the entire thing into memory.

+  // Allocate space for a terminator character.

+  //

+  fseek (SourceFile->Fptr, 0, SEEK_END);

+  SourceFile->FileSize = ftell (SourceFile->Fptr);

+  fseek (SourceFile->Fptr, 0, SEEK_SET);

+  SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR));

+  if (SourceFile->FileBuffer == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);

+  SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL;

+  //

+  // Pre-process the file to replace comments with spaces

+  //

+  PreprocessFile (SourceFile);

+  SourceFile->LineNum = 1;

+  return STATUS_SUCCESS;

+}

+

+static

+void

+PreprocessFile (

+  SOURCE_FILE *SourceFile

+  )

+/*++

+

+Routine Description:

+  Preprocess a file to replace all carriage returns with NULLs so

+  we can print lines from the file to the screen.

+  

+Arguments:

+  SourceFile - structure that we use to keep track of an input file.

+

+Returns:

+  Nothing.

+  

+--*/

+{

+  BOOLEAN InComment;

+

+  RewindFile (SourceFile);

+  InComment = FALSE;

+  while (!EndOfFile (SourceFile)) {

+    //

+    // If a line-feed, then no longer in a comment

+    //

+    if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      InComment = 0;

+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {

+      //

+      // Replace all carriage returns with a NULL so we can print stuff

+      //

+      SourceFile->FileBufferPtr[0] = 0;

+      SourceFile->FileBufferPtr++;

+    } else if (InComment) {

+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;

+      SourceFile->FileBufferPtr++;

+    } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) {

+      SourceFile->FileBufferPtr += 2;

+      InComment = TRUE;

+    } else {

+      SourceFile->FileBufferPtr++;

+    }

+  }

+  //

+  // Could check for end-of-file and still in a comment, but

+  // should not be necessary. So just restore the file pointers.

+  //

+  RewindFile (SourceFile);

+}

+

+#if 0

+static

+T_CHAR *

+GetQuotedString (

+  SOURCE_FILE *SourceFile,

+  BOOLEAN     Optional

+  )

+{

+  T_CHAR  *String;

+  T_CHAR  *Start;

+  T_CHAR  *Ptr;

+  UINT32  Len;

+  BOOLEAN PreviousBackslash;

+

+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {

+    if (!Optional) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);

+    }

+

+    return NULL;

+  }

+

+  Len = 0;

+  SourceFile->FileBufferPtr++;

+  Start             = Ptr = SourceFile->FileBufferPtr;

+  PreviousBackslash = FALSE;

+  while (!EndOfFile (SourceFile)) {

+    if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (!PreviousBackslash)) {

+      break;

+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {

+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);

+      PreviousBackslash = FALSE;

+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) {

+      PreviousBackslash = TRUE;

+    } else {

+      PreviousBackslash = FALSE;

+    }

+

+    SourceFile->FileBufferPtr++;

+    Len++;

+  }

+

+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {

+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);

+  } else {

+    SourceFile->FileBufferPtr++;

+  }

+  //

+  // Now allocate memory for the string and save it off

+  //

+  String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR));

+  if (String == NULL) {

+    Error (NULL, 0, 0, "memory allocation failed", NULL);

+    return NULL;

+  }

+  //

+  // Copy the string from the file buffer to the local copy.

+  // We do no reformatting of it whatsoever at this point.

+  //

+  Ptr = String;

+  while (Len > 0) {

+    *Ptr = *Start;

+    Start++;

+    Ptr++;

+    Len--;

+  }

+

+  *Ptr = 0;

+  return String;

+}

+#endif

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  //

+  // The file buffer pointer will typically get updated before the End-of-file flag in the

+  // source file structure, so check it first.

+  //

+  if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) {

+    SourceFile->EndOfFile = TRUE;

+    return TRUE;

+  }

+

+  if (SourceFile->EndOfFile) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+#if 0

+static

+void

+ProcessTokenInclude (

+  SOURCE_FILE *SourceFile

+  )

+{

+  INT8        IncludeFileName[MAX_PATH];

+  INT8        *To;

+  UINT32      Len;

+  BOOLEAN     ReportedError;

+  SOURCE_FILE IncludedSourceFile;

+

+  ReportedError = FALSE;

+  if (SkipWhiteSpace (SourceFile) == 0) {

+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);

+  }

+  //

+  // Should be quoted file name

+  //

+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);

+    goto FailDone;

+  }

+

+  SourceFile->FileBufferPtr++;

+  //

+  // Copy the filename as ascii to our local string

+  //

+  To  = IncludeFileName;

+  Len = 0;

+  while (!EndOfFile (SourceFile)) {

+    if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);

+      goto FailDone;

+    }

+

+    if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {

+      SourceFile->FileBufferPtr++;

+      break;

+    }

+    //

+    // If too long, then report the error once and process until the closing quote

+    //

+    Len++;

+    if (!ReportedError && (Len >= sizeof (IncludeFileName))) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);

+      ReportedError = TRUE;

+    }

+

+    if (!ReportedError) {

+      //

+      // *To = UNICODE_TO_ASCII(SourceFile->FileBufferPtr[0]);

+      //

+      *To = (T_CHAR) SourceFile->FileBufferPtr[0];

+      To++;

+    }

+

+    SourceFile->FileBufferPtr++;

+  }

+

+  if (!ReportedError) {

+    *To = 0;

+    memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));

+    strcpy (IncludedSourceFile.FileName, IncludeFileName);

+    //

+    // IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER;

+    //

+    ProcessIncludeFile (&IncludedSourceFile, SourceFile);

+    //

+    // printf ("including file '%s'\n", IncludeFileName);

+    //

+  }

+

+  return ;

+FailDone:

+  //

+  // Error recovery -- skip to next #

+  //

+  SourceFile->SkipToHash = TRUE;

+}

+#endif

+static

+BOOLEAN

+IsWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+{

+  switch (*SourceFile->FileBufferPtr) {

+  case T_CHAR_NULL:

+  case T_CHAR_CR:

+  case T_CHAR_SPACE:

+  case T_CHAR_TAB:

+  case T_CHAR_LF:

+    return TRUE;

+

+  default:

+    return FALSE;

+  }

+}

+

+UINT32

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+{

+  UINT32  Count;

+

+  Count = 0;

+  while (!EndOfFile (SourceFile)) {

+    Count++;

+    switch (*SourceFile->FileBufferPtr) {

+    case T_CHAR_NULL:

+    case T_CHAR_CR:

+    case T_CHAR_SPACE:

+    case T_CHAR_TAB:

+      SourceFile->FileBufferPtr++;

+      break;

+

+    case T_CHAR_LF:

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      if (mGlobals.Verbose) {

+        printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);

+      }

+      break;

+

+    default:

+      return Count - 1;

+    }

+  }

+  //

+  // Some tokens require trailing whitespace. If we're at the end of the

+  // file, then we count that as well.

+  //

+  if ((Count == 0) && (EndOfFile (SourceFile))) {

+    Count++;

+  }

+

+  return Count;

+}

+

+static

+UINT32

+t_strcmp (

+  T_CHAR *Buffer,

+  T_CHAR *Str

+  )

+{

+  UINT32  Len;

+

+  Len = 0;

+  while (*Str == *Buffer) {

+    Buffer++;

+    Str++;

+    Len++;

+  }

+

+  if (*Str) {

+    return 0;

+  }

+

+  return Len;

+}

+

+static

+UINT32

+t_strlen (

+  T_CHAR *Str

+  )

+{

+  UINT32  Len;

+  Len = 0;

+  while (*Str) {

+    Len++;

+    Str++;

+  }

+

+  return Len;

+}

+

+static

+UINT32

+t_strncmp (

+  T_CHAR *Str1,

+  T_CHAR *Str2,

+  UINT32 Len

+  )

+{

+  while (Len > 0) {

+    if (*Str1 != *Str2) {

+      return Len;

+    }

+

+    Len--;

+    Str1++;

+    Str2++;

+  }

+

+  return 0;

+}

+

+static

+T_CHAR *

+t_strcpy (

+  T_CHAR *Dest,

+  T_CHAR *Src

+  )

+{

+  T_CHAR  *SaveDest;

+  SaveDest = Dest;

+  while (*Src) {

+    *Dest = *Src;

+    Dest++;

+    Src++;

+  }

+

+  *Dest = 0;

+  return SaveDest;

+}

+

+#if 0

+static

+BOOLEAN

+IsValidIdentifierChar (

+  INT8      Char,

+  BOOLEAN   FirstChar

+  )

+{

+  //

+  // If it's the first character of an identifier, then

+  // it must be one of [A-Za-z_].

+  //

+  if (FirstChar) {

+    if (isalpha (Char) || (Char == '_')) {

+      return TRUE;

+    }

+  } else {

+    //

+    // If it's not the first character, then it can

+    // be one of [A-Za-z_0-9]

+    //

+    if (isalnum (Char) || (Char == '_')) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+#endif

+static

+void

+RewindFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  SourceFile->LineNum       = 1;

+  SourceFile->FileBufferPtr = SourceFile->FileBuffer;

+  SourceFile->EndOfFile     = 0;

+}

+

+#if 0

+static

+BOOLEAN

+SkipTo (

+  SOURCE_FILE  *SourceFile,

+  T_CHAR       TChar,

+  BOOLEAN      StopAfterNewline

+  )

+{

+  while (!EndOfFile (SourceFile)) {

+    //

+    // Check for the character of interest

+    //

+    if (SourceFile->FileBufferPtr[0] == TChar) {

+      return TRUE;

+    } else {

+      if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {

+        SourceFile->LineNum++;

+        if (StopAfterNewline) {

+          SourceFile->FileBufferPtr++;

+          if (SourceFile->FileBufferPtr[0] == 0) {

+            SourceFile->FileBufferPtr++;

+          }

+

+          return FALSE;

+        }

+      }

+

+      SourceFile->FileBufferPtr++;

+    }

+  }

+

+  return FALSE;

+}

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFfsFile/build.xml b/edk2/Tools/Source/TianoTools/GenFfsFile/build.xml
new file mode 100644
index 0000000..00a1266
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFfsFile/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenFfsFile Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenFfsFile"/>

+  <property name="FileSet" value="GenFfsFile.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+        <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/Ebc/PeCoffLoaderEx.c b/edk2/Tools/Source/TianoTools/GenFvImage/Ebc/PeCoffLoaderEx.c
new file mode 100644
index 0000000..e8cf8b6
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/Ebc/PeCoffLoaderEx.c
@@ -0,0 +1,57 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeCoffLoaderEx.c

+

+Abstract:

+

+    EBC Specific relocation fixups

+

+Revision History

+

+--*/

+

+

+

+

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+

+  Performs an IA-32 specific relocation fixup

+

+Arguments:

+

+  Reloc      - Pointer to the relocation record

+

+  Fixup      - Pointer to the address to fix up

+

+  FixupData  - Pointer to a buffer to log the fixups

+

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+

+  EFI_UNSUPPORTED   - Unsupported now

+

+--*/

+{

+  return RETURN_UNSUPPORTED;

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageExe.c b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageExe.c
new file mode 100644
index 0000000..d0117b8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageExe.c
@@ -0,0 +1,299 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenFvImageExe.c

+

+Abstract:

+

+  This contains all code necessary to build the GenFvImage.exe utility.       

+  This utility relies heavily on the GenFvImage Lib.  Definitions for both

+  can be found in the Tiano Firmware Volume Generation Utility 

+  Specification, review draft.

+

+--*/

+

+//

+// File included in build

+//

+#include "GenFvImageExe.h"

+#include "CommonLib.h"

+#include "EfiUtilityMsgs.h"

+

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "%s - Tiano Firmware Volume Generation Utility."" Version %i.%i\n\n",

+    UTILITY_NAME,

+    UTILITY_MAJOR_VERSION,

+    UTILITY_MINOR_VERSION

+    );

+}

+

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf ("Usage: %s -I FvInfFileName\n", UTILITY_NAME);

+  printf ("  Where:\n");

+  printf ("\tFvInfFileName is the name of the image description file.\n\n");

+}

+

+int

+main (

+  IN INTN   argc,

+  IN CHAR8  **argv

+  )

+/*++

+

+Routine Description:

+

+  This utility uses GenFvImage.Lib to build a firmware volume image.

+

+Arguments:

+

+  FvInfFileName      The name of an FV image description file.

+

+  Arguments come in pair in any order.

+    -I FvInfFileName 

+

+Returns:

+

+  EFI_SUCCESS            No error conditions detected.

+  EFI_INVALID_PARAMETER  One or more of the input parameters is invalid.

+  EFI_OUT_OF_RESOURCES   A resource required by the utility was unavailable.  

+                         Most commonly this will be memory allocation 

+                         or file creation.

+  EFI_LOAD_ERROR         GenFvImage.lib could not be loaded.

+  EFI_ABORTED            Error executing the GenFvImage lib.

+

+--*/

+{

+  EFI_STATUS  Status;

+  CHAR8       InfFileName[_MAX_PATH];

+  CHAR8       *InfFileImage;

+  UINTN       InfFileSize;

+  UINT8       *FvImage;

+  UINTN       FvImageSize;

+  UINT8       Index;

+  CHAR8       FvFileNameBuffer[_MAX_PATH];

+  CHAR8       *FvFileName;

+  FILE        *FvFile;

+  FILE        *SymFile;

+  CHAR8       SymFileNameBuffer[_MAX_PATH];

+  CHAR8       *SymFileName;

+  UINT8       *SymImage;

+  UINTN       SymImageSize;

+  CHAR8       *CurrentSymString;

+

+  FvFileName  = FvFileNameBuffer;

+  SymFileName = SymFileNameBuffer;

+

+  SetUtilityName (UTILITY_NAME);

+  //

+  // Display utility information

+  //

+  PrintUtilityInfo ();

+

+  //

+  // Verify the correct number of arguments

+  //

+  if (argc != MAX_ARGS) {

+    Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);

+    PrintUsage ();

+    return GetUtilityStatus ();

+  }

+  //

+  // Initialize variables

+  //

+  strcpy (InfFileName, "");

+

+  //

+  // Parse the command line arguments

+  //

+  for (Index = 1; Index < MAX_ARGS; Index += 2) {

+    //

+    // Make sure argument pair begin with - or /

+    //

+    if (argv[Index][0] != '-' && argv[Index][0] != '/') {

+      Error (NULL, 0, 0, argv[Index], "argument pair must begin with \"-\" or \"/\"");

+      PrintUsage ();

+      return GetUtilityStatus ();

+    }

+    //

+    // Make sure argument specifier is only one letter

+    //

+    if (argv[Index][2] != 0) {

+      Error (NULL, 0, 0, argv[Index], "unrecognized argument");

+      PrintUsage ();

+      return GetUtilityStatus ();

+    }

+    //

+    // Determine argument to read

+    //

+    switch (argv[Index][1]) {

+

+    case 'I':

+    case 'i':

+      if (strlen (InfFileName) == 0) {

+        strcpy (InfFileName, argv[Index + 1]);

+      } else {

+        Error (NULL, 0, 0, argv[Index + 1], "FvInfFileName may only be specified once");

+        PrintUsage ();

+        return GetUtilityStatus ();

+      }

+      break;

+

+    default:

+      Error (NULL, 0, 0, argv[Index], "unrecognized argument");

+      PrintUsage ();

+      return GetUtilityStatus ();

+      break;

+    }

+  }

+  //

+  // Read the INF file image

+  //

+  Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);

+  if (EFI_ERROR (Status)) {

+    return STATUS_ERROR;

+  }

+  //

+  // Call the GenFvImage lib

+  //

+  Status = GenerateFvImage (

+            InfFileImage,

+            InfFileSize,

+            &FvImage,

+            &FvImageSize,

+            &FvFileName,

+            &SymImage,

+            &SymImageSize,

+            &SymFileName

+            );

+

+  if (EFI_ERROR (Status)) {

+    switch (Status) {

+

+    case EFI_INVALID_PARAMETER:

+      Error (NULL, 0, 0, "invalid parameter passed to GenFvImage Lib", NULL);

+      return GetUtilityStatus ();

+      break;

+

+    case EFI_ABORTED:

+      Error (NULL, 0, 0, "error detected while creating the file image", NULL);

+      return GetUtilityStatus ();

+      break;

+

+    case EFI_OUT_OF_RESOURCES:

+      Error (NULL, 0, 0, "GenFvImage Lib could not allocate required resources", NULL);

+      return GetUtilityStatus ();

+      break;

+

+    case EFI_VOLUME_CORRUPTED:

+      Error (NULL, 0, 0, "no base address was specified, but the FV.INF included a PEI or BSF file", NULL);

+      return GetUtilityStatus ();

+      break;

+

+    case EFI_LOAD_ERROR:

+      Error (NULL, 0, 0, "could not load FV image generation library", NULL);

+      return GetUtilityStatus ();

+      break;

+

+    default:

+      Error (NULL, 0, 0, "GenFvImage Lib returned unknown status", "status returned = 0x%X", Status);

+      return GetUtilityStatus ();

+      break;

+    }

+  }

+  //

+  // Write file

+  //

+  FvFile = fopen (FvFileName, "wb");

+  if (FvFile == NULL) {

+    Error (NULL, 0, 0, FvFileName, "could not open output file");

+    free (FvImage);

+    free (SymImage);

+    return GetUtilityStatus ();

+  }

+

+  if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) {

+    Error (NULL, 0, 0, FvFileName, "failed to write to output file");

+    free (FvImage);

+    free (SymImage);

+    fclose (FvFile);

+    return GetUtilityStatus ();

+  }

+

+  fclose (FvFile);

+  free (FvImage);

+

+  //

+  // Write symbol file

+  //

+  if (strcmp (SymFileName, "")) {

+    SymFile = fopen (SymFileName, "wt");

+    if (SymFile == NULL) {

+      Error (NULL, 0, 0, SymFileName, "could not open output symbol file");

+      free (SymImage);

+      return GetUtilityStatus ();

+    }

+

+    fprintf (SymFile, "TEXTSYM format | V1.0\n");

+

+    CurrentSymString = SymImage;

+    while (((UINTN) CurrentSymString - (UINTN) SymImage) < SymImageSize) {

+      fprintf (SymFile, "%s", CurrentSymString);

+      CurrentSymString = (CHAR8 *) (((UINTN) CurrentSymString) + strlen (CurrentSymString) + 1);

+    }

+

+    fclose (SymFile);

+  }

+

+  free (SymImage);

+

+  return GetUtilityStatus ();

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageExe.h b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageExe.h
new file mode 100644
index 0000000..9b97935
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageExe.h
@@ -0,0 +1,98 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  GenFvImageExe.h

+

+Abstract:

+

+  Definitions for the PeimFixup exe utility.

+

+--*/

+

+//

+// Coded to Tiano Coding Standards

+//

+#ifndef _EFI_GEN_FV_IMAGE_EXE_H

+#define _EFI_GEN_FV_IMAGE_EXE_H

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include "GenFvImageLib.h"

+

+//

+// Utility Name

+//

+#define UTILITY_NAME  "GenFvImage"

+

+//

+// Utility version information

+//

+#define UTILITY_MAJOR_VERSION 0

+#define UTILITY_MINOR_VERSION 1

+#define UTILITY_DATE          __DATE__

+

+//

+// The maximum number of arguments accepted from the command line.

+//

+#define MAX_ARGS  3

+

+//

+// The function that displays general utility information

+//

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+//

+// The function that displays the utility usage message.

+//

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLib.c b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLib.c
new file mode 100644
index 0000000..c451500
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLib.c
@@ -0,0 +1,2871 @@
+/*++

+i

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenFvImageLib.c

+

+Abstract:

+

+  This file contains functions required to generate a Firmware Volume.

+

+--*/

+

+//

+// Include files

+//

+#define EFI_SPECIFICATION_VERSION 0x00020000

+#define EDK_RELEASE_VERSION       0x00020000

+#ifdef __GNUC__

+#include <uuid/uuid.h>

+#include <sys/stat.h>

+#endif

+#include <string.h>

+#ifndef __GNUC__

+#include <io.h>

+#endif

+#include <assert.h>

+#include <Dxe.h>

+#include <Library/PeCoffLib.h>

+#include "GenFvImageLib.h"

+#include "GenFvImageLibInternal.h"

+#include <CommonLib.h>

+#include <FirmwareVolumeImageFormat.h>

+#include <Crc32.h>

+#include <EfiUtilityMsgs.h>

+#include <FvLib.h>

+#include <EfiCompress.h>

+#include <Variable.h>

+#include <WinNtInclude.h>

+#include <WorkingBlockHeader.h>

+

+

+//

+// Local function prototypes

+//

+EFI_STATUS

+GetPe32Info (

+  IN UINT8                  *Pe32,

+  OUT UINT32                *EntryPoint,

+  OUT UINT32                *BaseOfCode,

+  OUT UINT16                *MachineType

+  );

+

+//

+// Local function implementations.

+//

+EFI_GUID  FfsGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID;

+EFI_GUID  DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f };

+

+//

+// This data array will be located at the base of the Firmware Volume Header (FVH)

+// in the boot block.  It must not exceed 14 bytes of code.  The last 2 bytes

+// will be used to keep the FVH checksum consistent.

+// This code will be run in response to a starutp IPI for HT-enabled systems.

+//

+#define SIZEOF_STARTUP_DATA_ARRAY 0x10

+

+UINT8                                   m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {

+  //

+  // EA D0 FF 00 F0               ; far jmp F000:FFD0

+  // 0, 0, 0, 0, 0, 0, 0, 0, 0,   ; Reserved bytes

+  // 0, 0                         ; Checksum Padding

+  //

+  0xEA,

+  0xD0,

+  0xFF,

+  0x0,

+  0xF0,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00

+};

+

+UINT8                                   m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {

+  //

+  // EB CE                               ; jmp short ($-0x30)

+  // ; (from offset 0x0 to offset 0xFFD0)

+  // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes

+  // 0, 0                                ; Checksum Padding

+  //

+  0xEB,

+  0xCE,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00,

+  0x00

+};

+

+EFI_STATUS

+ParseFvInf (

+  IN MEMORY_FILE  *InfFile,

+  IN FV_INFO      *FvInfo

+  )

+/*++

+

+Routine Description:

+

+  This function parses a FV.INF file and copies info into a FV_INFO structure.

+

+Arguments:

+

+  InfFile         Memory file image.

+  FvInfo          Information read from INF file.

+

+Returns:

+

+  EFI_SUCCESS       INF file information successfully retrieved.

+  EFI_ABORTED       INF file has an invalid format.

+  EFI_NOT_FOUND     A required string was not found in the INF file.

+--*/

+{

+  CHAR8       Value[_MAX_PATH];

+  UINT64      Value64;

+  UINTN       Index;

+  EFI_STATUS  Status;

+

+  //

+  // Initialize FV info

+  //

+  memset (FvInfo, 0, sizeof (FV_INFO));

+

+  //

+  // Read the FV base address

+  //

+  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Get the base address

+    //

+    Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "invalid value");

+      return EFI_ABORTED;

+    }

+

+    FvInfo->BaseAddress = Value64;

+  } else {

+    Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "could not find value");

+    return EFI_ABORTED;

+  }

+  //

+  // Read the FV Guid

+  //

+  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_GUID_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Get the guid value

+    //

+    Status = StringToGuid (Value, &FvInfo->FvGuid);

+    if (EFI_ERROR (Status)) {

+      memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID));

+    }

+  } else {

+    memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID));

+  }

+  //

+  // Read the FV file name

+  //

+  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // copy the file name

+    //

+    strcpy (FvInfo->FvName, Value);

+  } else {

+    Error (NULL, 0, 0, EFI_FV_FILE_NAME_STRING, "value not specified");

+    return EFI_ABORTED;

+  }

+  //

+  // Read the Sym file name

+  //

+  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_SYM_FILE_NAME_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // copy the file name

+    //

+    strcpy (FvInfo->SymName, Value);

+  } else {

+    //

+    // Symbols not required, so init to NULL.

+    //

+    strcpy (FvInfo->SymName, "");

+  }

+  //

+  // Read the read disabled capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_DISABLED_CAP_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the read disabled flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_READ_DISABLED_CAP;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the read enabled capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_ENABLED_CAP_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the read disabled flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_READ_ENABLED_CAP;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the read status attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_STATUS_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the read disabled flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_READ_STATUS;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the write disabled capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_DISABLED_CAP_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the write disabled flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_WRITE_DISABLED_CAP;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the write enabled capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_ENABLED_CAP_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the write disabled flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_WRITE_ENABLED_CAP;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the write status attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_STATUS_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the write disabled flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_WRITE_STATUS;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the lock capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_CAP_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the attribute flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_LOCK_CAP;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the lock status attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_STATUS_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the attribute flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_LOCK_STATUS;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the sticky write attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_STICKY_WRITE_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the attribute flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_STICKY_WRITE;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the memory mapped attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_MEMORY_MAPPED_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the attribute flag

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_MEMORY_MAPPED;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the erase polarity attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ERASE_POLARITY_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update the attribute flag

+    //

+    if (strcmp (Value, ONE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ERASE_POLARITY;

+    } else if (strcmp (Value, ZERO_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the alignment capabilities attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_CAP_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_CAP;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the word alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the dword alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the word alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the qword alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 32 byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 64 byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 128 byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_128_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_128;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 256 byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_256_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_256;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 512 byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_512_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_512;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 1K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_1K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_1K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 2K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 4K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 8K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 16K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 32K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "value not specified");

+    return Status;

+  }

+  //

+  // Read the 64K byte alignment capability attribute

+  //

+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64K_STRING, 0, Value);

+

+  if (Status == EFI_SUCCESS) {

+    //

+    // Update attribute

+    //

+    if (strcmp (Value, TRUE_STRING) == 0) {

+      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64K;

+    } else if (strcmp (Value, FALSE_STRING) != 0) {

+      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

+      return EFI_ABORTED;

+    }

+  } else {

+    Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "value not specified");

+    return Status;

+  }

+

+  if (!(FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_CAP) &&

+      (

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_128) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_256) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_512) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_1K) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2K) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4K) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8K) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16K) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32K) ||

+        (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64K)

+      )

+     ) {

+    Error (

+      NULL,

+      0,

+      0,

+      "illegal combination of alignment attributes",

+      "if %s is not %s, no individual alignments can be %s",

+      EFI_FVB_ALIGNMENT_CAP_STRING,

+      TRUE_STRING,

+      TRUE_STRING

+      );

+    return EFI_ABORTED;

+  }

+  //

+  // Read block maps

+  //

+  for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) {

+    //

+    // Read the number of blocks

+    //

+    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Update the number of blocks

+      //

+      Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+      if (EFI_ERROR (Status)) {

+        Error (NULL, 0, 0, Value, "invalid value for %s", EFI_NUM_BLOCKS_STRING);

+        return EFI_ABORTED;

+      }

+

+      FvInfo->FvBlocks[Index].NumBlocks = (UINT32) Value64;

+    } else {

+      //

+      // If there is no number of blocks, but there is a size, then we have a mismatched pair

+      // and should return an error.

+      //

+      Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value);

+      if (!EFI_ERROR (Status)) {

+        Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING);

+        return EFI_ABORTED;

+      } else {

+        //

+        // We are done

+        //

+        break;

+      }

+    }

+    //

+    // Read the size of blocks

+    //

+    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Update the number of blocks

+      //

+      Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+      if (EFI_ERROR (Status)) {

+        Error (NULL, 0, 0, Value, "invalid value specified for %s", EFI_BLOCK_SIZE_STRING);

+        return EFI_ABORTED;

+      }

+

+      FvInfo->FvBlocks[Index].BlockLength = (UINT32) Value64;

+    } else {

+      //

+      // There is a number of blocks, but there is no size, so we have a mismatched pair

+      // and should return an error.

+      //

+      Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING);

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // Read files

+  //

+  for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {

+    //

+    // Read the number of blocks

+    //

+    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Add the file

+      //

+      strcpy (FvInfo->FvFiles[Index], Value);

+    } else {

+      break;

+    }

+  }

+

+  if (FindSection (InfFile, COMPONENT_SECTION_STRING)) {

+    Index = 0;

+    //

+    // Read component FV_VARIABLE

+    //

+    Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_VARIABLE_STRING, 0, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Add the component

+      //

+      strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING);

+      Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+      if (EFI_ERROR (Status)) {

+        printf ("ERROR: %s is not a valid integer.\n", EFI_NV_VARIABLE_STRING);

+        return EFI_ABORTED;

+      }

+

+      FvInfo->FvComponents[Index].Size = (UINTN) Value64;

+    } else {

+      printf ("WARNING: Could not read %s.\n", EFI_NV_VARIABLE_STRING);

+    }

+

+    Index++;

+    //

+    // Read component FV_EVENT_LOG

+    //

+    Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_EVENT_LOG_STRING, 0, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Add the component

+      //

+      strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING);

+      Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+      if (EFI_ERROR (Status)) {

+        printf ("ERROR: %s is not a valid integer.\n", EFI_NV_EVENT_LOG_STRING);

+        return EFI_ABORTED;

+      }

+

+      FvInfo->FvComponents[Index].Size = (UINTN) Value64;

+    } else {

+      printf ("WARNING: Could not read %s.\n", EFI_NV_EVENT_LOG_STRING);

+    }

+

+    Index++;

+    //

+    // Read component FV_FTW_WORKING

+    //

+    Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_WORKING_STRING, 0, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Add the component

+      //

+      strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING);

+      Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+      if (EFI_ERROR (Status)) {

+        printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_WORKING_STRING);

+        return EFI_ABORTED;

+      }

+

+      FvInfo->FvComponents[Index].Size = (UINTN) Value64;

+    } else {

+      printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_WORKING_STRING);

+    }

+

+    Index++;

+    //

+    // Read component FV_FTW_SPARE

+    //

+    Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_SPARE_STRING, 0, Value);

+

+    if (Status == EFI_SUCCESS) {

+      //

+      // Add the component

+      //

+      strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING);

+      Status = AsciiStringToUint64 (Value, FALSE, &Value64);

+      if (EFI_ERROR (Status)) {

+        printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_SPARE_STRING);

+        return EFI_ABORTED;

+      }

+

+      FvInfo->FvComponents[Index].Size = (UINTN) Value64;

+    } else {

+      printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_SPARE_STRING);

+    }

+  }

+  //

+  // Compute size for easy access later

+  //

+  FvInfo->Size = 0;

+  for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) {

+    FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].BlockLength;

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+UpdateFfsFileState (

+  IN EFI_FFS_FILE_HEADER          *FfsFile,

+  IN EFI_FIRMWARE_VOLUME_HEADER   *FvHeader

+  )

+/*++

+

+Routine Description:

+

+  This function changes the FFS file attributes based on the erase polarity

+  of the FV.

+

+Arguments:

+

+  FfsFile   File header.

+  FvHeader  FV header.

+

+Returns:

+

+  None

+

+--*/

+{

+  if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {

+    FfsFile->State = (UINT8)~(FfsFile->State);

+  }

+}

+

+EFI_STATUS

+ReadFfsAlignment (

+  IN EFI_FFS_FILE_HEADER    *FfsFile,

+  IN OUT UINT32             *Alignment

+  )

+/*++

+

+Routine Description:

+

+  This function determines the alignment of the FFS input file from the file

+  attributes.

+

+Arguments:

+

+  FfsFile       FFS file to parse

+  Alignment     The minimum required alignment of the FFS file, in bytes

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_ABORTED              An error occurred.

+

+--*/

+{

+  //

+  // Verify input parameters.

+  //

+  if (FfsFile == NULL || Alignment == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  switch ((FfsFile->Attributes >> 3) & 0x07) {

+

+  case 0:

+    //

+    // 1 byte alignment

+    //

+    *Alignment = (1 << 0);

+    break;

+

+  case 1:

+    //

+    // 16 byte alignment

+    //

+    *Alignment = (1 << 4);

+    break;

+

+  case 2:

+    //

+    // 128 byte alignment

+    //

+    *Alignment = (1 << 7);

+    break;

+

+  case 3:

+    //

+    // 512 byte alignment

+    //

+    *Alignment = (1 << 9);

+    break;

+

+  case 4:

+    //

+    // 1K byte alignment

+    //

+    *Alignment = (1 << 10);

+    break;

+

+  case 5:

+    //

+    // 4K byte alignment

+    //

+    *Alignment = (1 << 12);

+    break;

+

+  case 6:

+    //

+    // 32K byte alignment

+    //

+    *Alignment = (1 << 15);

+    break;

+

+  case 7:

+    //

+    // 64K byte alignment

+    //

+    *Alignment = (1 << 16);

+    break;

+

+  default:

+    Error (NULL, 0, 0, "nvalid file attribute calculated, this is most likely a utility error", NULL);

+    return EFI_ABORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddPadFile (

+  IN OUT MEMORY_FILE  *FvImage,

+  IN UINT32           DataAlignment

+  )

+/*++

+

+Routine Description:

+

+  This function adds a pad file to the FV image if it required to align the

+  data of the next file.

+

+Arguments:

+

+  FvImage         The memory image of the FV to add it to.  The current offset

+                  must be valid.

+  DataAlignment   The data alignment of the next FFS file.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_OUT_OF_RESOURCES     Insufficient resources exist in the FV to complete

+                           the pad file add.

+

+--*/

+{

+  EFI_FFS_FILE_HEADER *PadFile;

+  EFI_GUID            PadFileGuid;

+  UINTN               PadFileSize;

+

+  //

+  // Verify input parameters.

+  //

+  if (FvImage == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Basic assumption is we start from an 8 byte aligned address

+  // and our file header is a multiple of 8 bytes

+  //

+  assert ((UINTN) FvImage->CurrentFilePointer % 8 == 0);

+  assert (sizeof (EFI_FFS_FILE_HEADER) % 8 == 0);

+

+  //

+  // Check if a pad file is necessary

+  //

+  if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER)) % DataAlignment == 0) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Write pad file header

+  //

+  PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;

+

+  //

+  // Verify that we have enough space for the file header

+  //

+  if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+#ifdef __GNUC__

+  {

+    uuid_t tmp_id;

+    uuid_generate (tmp_id);

+    memcpy (&PadFileGuid, tmp_id, sizeof (EFI_GUID));

+  }

+#else

+  UuidCreate (&PadFileGuid);

+#endif

+  memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER));

+  memcpy (&PadFile->Name, &PadFileGuid, sizeof (EFI_GUID));

+  PadFile->Type       = EFI_FV_FILETYPE_FFS_PAD;

+  PadFile->Attributes = 0;

+

+  //

+  // Calculate the pad file size

+  //

+  //

+  // This is the earliest possible valid offset (current plus pad file header

+  // plus the next file header)

+  //

+  PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2);

+

+  //

+  // Add whatever it takes to get to the next aligned address

+  //

+  while ((PadFileSize % DataAlignment) != 0) {

+    PadFileSize++;

+  }

+  //

+  // Subtract the next file header size

+  //

+  PadFileSize -= sizeof (EFI_FFS_FILE_HEADER);

+

+  //

+  // Subtract the starting offset to get size

+  //

+  PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;

+

+  //

+  // Write pad file size (calculated size minus next file header size)

+  //

+  PadFile->Size[0]  = (UINT8) (PadFileSize & 0xFF);

+  PadFile->Size[1]  = (UINT8) ((PadFileSize >> 8) & 0xFF);

+  PadFile->Size[2]  = (UINT8) ((PadFileSize >> 16) & 0xFF);

+

+  //

+  // Fill in checksums and state, they must be 0 for checksumming.

+  //

+  PadFile->IntegrityCheck.Checksum.Header = 0;

+  PadFile->IntegrityCheck.Checksum.File   = 0;

+  PadFile->State                          = 0;

+  PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER));

+  if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+    PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, PadFileSize);

+  } else {

+    PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+  }

+

+  PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

+  UpdateFfsFileState (

+    (EFI_FFS_FILE_HEADER *) PadFile,

+    (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage

+    );

+

+  //

+  // Verify that we have enough space (including the padding

+  //

+  if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Update the current FV pointer

+  //

+  FvImage->CurrentFilePointer += PadFileSize;

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+IsVtfFile (

+  IN EFI_FFS_FILE_HEADER    *FileBuffer

+  )

+/*++

+

+Routine Description:

+

+  This function checks the header to validate if it is a VTF file

+

+Arguments:

+

+  FileBuffer     Buffer in which content of a file has been read.

+

+Returns:

+

+  TRUE    If this is a VTF file

+  FALSE   If this is not a VTF file

+

+--*/

+{

+  EFI_GUID  VtfGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;

+  if (!memcmp (&FileBuffer->Name, &VtfGuid, sizeof (EFI_GUID))) {

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+EFI_STATUS

+FfsRebaseImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINT32  *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

+

+Arguments:

+

+  FileHandle - The handle to the PE/COFF file

+

+  FileOffset - The offset, in bytes, into the file to read

+

+  ReadSize   - The number of bytes to read from the file starting at FileOffset

+

+  Buffer     - A pointer to the buffer to read the data into.

+

+Returns:

+

+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

+

+--*/

+{

+  CHAR8   *Destination8;

+  CHAR8   *Source8;

+  UINT32  Length;

+

+  Destination8  = Buffer;

+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);

+  Length        = *ReadSize;

+  while (Length--) {

+    *(Destination8++) = *(Source8++);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+RebaseFfsFile (

+  IN OUT EFI_FFS_FILE_HEADER    *FfsFile,

+  IN EFI_PHYSICAL_ADDRESS       BaseAddress

+  )

+/*++

+

+Routine Description:

+

+  This function determines if a file is XIP and should be rebased.  It will

+  rebase any PE32 sections found in the file using the base address.

+

+Arguments:

+

+  FfsFile           A pointer to Ffs file image.

+  BaseAddress       The base address to use for rebasing the file image.

+

+Returns:

+

+  EFI_SUCCESS             The image was properly rebased.

+  EFI_INVALID_PARAMETER   An input parameter is invalid.

+  EFI_ABORTED             An error occurred while rebasing the input file image.

+  EFI_OUT_OF_RESOURCES    Could not allocate a required resource.

+

+--*/

+{

+  EFI_STATUS                            Status;

+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;

+  UINTN                                 MemoryImagePointer;

+  UINTN                                 MemoryImagePointerAligned;

+

+  EFI_PHYSICAL_ADDRESS                  ImageAddress;

+  UINT64                                ImageSize;

+  EFI_PHYSICAL_ADDRESS                  EntryPoint;

+

+  UINT32                                Pe32FileSize;

+  UINT32                                NewPe32BaseAddress;

+

+  UINTN                                 Index;

+  EFI_FILE_SECTION_POINTER              CurrentPe32Section;

+  UINT8                                 FileGuidString[80];

+

+  //

+  // Verify input parameters

+  //

+  if (FfsFile == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Convert the GUID to a string so we can at least report which file

+  // if we find an error.

+  //

+  PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE);

+

+  //

+  // Do some nominal checks on the file, then check for XIP.

+  //

+  Status = VerifyFfsFile (FfsFile);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "invalid FFS file", FileGuidString);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&

+      FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&

+      FfsFile->Type != EFI_FV_FILETYPE_PEIM

+      ) {

+    //

+    // File is not XIP, so don't rebase

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // Rebase each PE32 section

+  //

+  for (Index = 1;; Index++) {

+    Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+    //

+    // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section

+    //

+    NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section - (UINTN) FfsFile);

+

+    //

+    // Initialize context

+    //

+    memset (&ImageContext, 0, sizeof (ImageContext));

+    ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));

+    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;

+

+    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);

+

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "GetImageInfo() failed", FileGuidString);

+      return Status;

+    }

+    //

+    // Allocate a buffer for the image to be loaded into.

+    //

+    Pe32FileSize              = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size);

+    MemoryImagePointer        = (UINTN) (malloc (Pe32FileSize + 0x1000));

+    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);

+    if (MemoryImagePointerAligned == 0) {

+      Error (NULL, 0, 0, "memory allocation failure", NULL);

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    //

+    // bugbug

+    //

+    ImageContext.ImageAddress = MemoryImagePointerAligned;

+    Status = PeCoffLoaderLoadImage (&ImageContext);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "LoadImage() failure", FileGuidString);

+      free ((VOID *) MemoryImagePointer);

+      return Status;

+    }

+

+    Status = PeCoffLoaderRelocateImage (&ImageContext);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "RelocateImage() failure", FileGuidString);

+      free ((VOID *) MemoryImagePointer);

+      return Status;

+    }

+

+    ImageAddress  = ImageContext.ImageAddress;

+    ImageSize     = ImageContext.ImageSize;

+    EntryPoint    = ImageContext.EntryPoint;

+

+    if (ImageSize > Pe32FileSize) {

+      Error (

+        NULL,

+        0,

+        0,

+        "rebased PE32 is larger than original PE32 image",

+        "0x%X > 0x%X on file %s",

+        ImageSize,

+        Pe32FileSize,

+        FileGuidString

+        );

+      free ((VOID *) MemoryImagePointer);

+      return EFI_ABORTED;

+    }

+

+    memcpy (CurrentPe32Section.Pe32Section, (VOID *) MemoryImagePointerAligned, Pe32FileSize);

+

+    free ((VOID *) MemoryImagePointer);

+  }

+  //

+  // the above for loop will always exit with EFI_NOT_FOUND if it completes

+  // normally.  If Index == 1 at exit, then no PE32 sections were found.  If it

+  // exits with any other error code, then something broke...

+  //

+  if (Status != EFI_NOT_FOUND) {

+    Error (NULL, 0, 0, "failed to parse PE32 section", FileGuidString);

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddSymFile (

+  IN UINT64               BaseAddress,

+  IN EFI_FFS_FILE_HEADER  *FfsFile,

+  IN OUT MEMORY_FILE      *SymImage,

+  IN CHAR8                *SourceFileName

+  )

+/*++

+

+Routine Description:

+

+  This function adds the SYM tokens in the source file to the destination file.

+  The SYM tokens are updated to reflect the base address.

+

+Arguments:

+

+  BaseAddress     The base address for the new SYM tokens.

+  FfsFile         Pointer to the beginning of the FFS file in question.

+  SymImage        The memory file to update with symbol information.

+  SourceFileName  The source file.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_ABORTED              An error occurred.

+

+--*/

+{

+  FILE                      *SourceFile;

+

+  CHAR8                     Buffer[_MAX_PATH];

+  CHAR8                     Type[_MAX_PATH];

+  CHAR8                     Address[_MAX_PATH];

+  CHAR8                     Section[_MAX_PATH];

+  CHAR8                     Token[_MAX_PATH];

+  CHAR8                     SymFileName[_MAX_PATH];

+  CHAR8                     CodeModuleName[_MAX_PATH];

+  CHAR8                     *Ptr;

+

+  UINT64                    TokenAddress;

+

+  EFI_STATUS                Status;

+  EFI_FILE_SECTION_POINTER  Pe32Section;

+  UINT32                    EntryPoint;

+  UINT32                    BaseOfCode;

+  UINT16                    MachineType;

+  EFI_TE_IMAGE_HEADER       *TeHdr;

+

+  TeHdr = NULL;

+  //

+  // Verify input parameters.

+  //

+  if (BaseAddress == 0 || FfsFile == NULL || SymImage == NULL || SourceFileName == NULL) {

+    Error (NULL, 0, 0, "invalid parameter passed to AddSymFile()", NULL);

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Check if we want to add this file

+  //

+  //

+  // Get the file name

+  //

+  strcpy (Buffer, SourceFileName);

+

+  //

+  // Copy the file name for the path of the sym file and truncate the name portion.

+  //

+  strcpy (SymFileName, Buffer);

+  Ptr = strrchr (SymFileName, '\\');

+  assert (Ptr);

+  Ptr[0] = 0;

+

+  //

+  // Find the file extension and make it lower case

+  //

+  Ptr = strrchr (SymFileName, '.');

+  if (Ptr != NULL) {

+    strlwr (Ptr);

+  }

+  //

+  // Check if it is PEI file

+  //

+  if (strstr (Buffer, ".pei") != NULL) {

+    //

+    // Find the human readable portion

+    //

+    if (!strtok (Buffer, "-") ||

+        !strtok (NULL, "-") ||

+        !strtok (NULL, "-") ||

+        !strtok (NULL, "-") ||

+        !strtok (NULL, "-") ||

+        !strcpy (Buffer, strtok (NULL, "."))

+          ) {

+      Error (NULL, 0, 0, "failed to find human readable portion of the file name in AddSymFile()", NULL);

+      return EFI_ABORTED;

+    }

+    //

+    // Save code module name

+    //

+    strcpy (CodeModuleName, Buffer);

+

+    //

+    // Add the symbol file name and extension to the file path.

+    //

+    strcat (Buffer, ".sym");

+    strcat (SymFileName, "\\");

+    strcat (SymFileName, Buffer);

+  } else {

+    //

+    // Only handle PEIM files.

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // Find PE32 section

+  //

+  Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, 1, &Pe32Section);

+

+  //

+  // BUGBUG: Assume if no PE32 section it is PIC and hardcode base address

+  //

+  if (Status == EFI_NOT_FOUND) {

+    Status = GetSectionByType (FfsFile, EFI_SECTION_TE, 1, &Pe32Section);

+    if (Status == EFI_NOT_FOUND) {

+      BaseOfCode = 0x60;

+    } else {

+      TeHdr       = (EFI_TE_IMAGE_HEADER *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));

+      BaseOfCode  = TeHdr->BaseOfCode - TeHdr->StrippedSize;

+    }

+  } else if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "could not parse a PE32 section from the PEI file", NULL);

+    return Status;

+  } else {

+    Status = GetPe32Info (

+              (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),

+              &EntryPoint,

+              &BaseOfCode,

+              &MachineType

+              );

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "GetPe32Info() could not get PE32 entry point for PEI file", NULL);

+      return Status;

+    }

+  }

+  //

+  // Open the source file

+  //

+  SourceFile = fopen (SymFileName, "r");

+  if (SourceFile == NULL) {

+    //

+    // SYM files are not required.

+    //

+    return EFI_SUCCESS;

+  }

+  //

+  // Read the first line

+  //

+  if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) {

+    Buffer[0] = 0;

+  }

+  //

+  // Make sure it matches the expected sym format

+  //

+  if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) {

+    fclose (SourceFile);

+    Error (NULL, 0, 0, "AddSymFile() found unexpected sym format in input file", NULL);

+    return EFI_ABORTED;

+  }

+  //

+  // Read in the file

+  //

+  while (feof (SourceFile) == 0) {

+    //

+    // Read a line

+    //

+    if (fscanf (

+          SourceFile,

+          "%s | %s | %s | %s\n",

+          Type,

+          Address,

+          Section,

+          Token

+          ) == 4) {

+      //

+      // If the token starts with "??" ignore it

+      //

+      if (Token[0] == '?' && Token[1] == '?') {

+        continue;

+      }

+      //

+      // Get the token address

+      //

+      AsciiStringToUint64 (Address, TRUE, &TokenAddress);

+

+      //

+      // Add the base address

+      //

+      TokenAddress += BaseAddress;

+

+      //

+      // If PE32 then find the start of code.  For PIC it is hardcoded.

+      //

+      if (TeHdr == NULL && Pe32Section.Pe32Section) {

+        //

+        // Add the offset of the PE32 section

+        //

+        TokenAddress += (UINTN) Pe32Section.Pe32Section - (UINTN) FfsFile;

+

+        //

+        // Add the size of the PE32 section header

+        //

+        TokenAddress += sizeof (EFI_PE32_SECTION);

+      } else if (TeHdr != NULL) {

+        //

+        // Add the Te section and FfsHeader

+        //

+        //

+        //  BUGBUG: Don't know why this is 0x28 bytes.

+        //

+        TokenAddress += (UINTN) TeHdr - (UINTN) FfsFile + 0x28;

+      } else {

+        //

+        // BUGBUG: Don't know why this is 0x28 bytes.

+        //

+        TokenAddress += 0x28;

+      }

+      //

+      // Add the beginning of the code

+      //

+      TokenAddress += BaseOfCode;

+

+      sprintf (

+        Buffer,

+        "%s | %016I64X | %s | _%s%s\n",

+        Type,

+        TokenAddress,

+        Section,

+        CodeModuleName,

+        Token

+        );

+      memcpy (SymImage->CurrentFilePointer, Buffer, strlen (Buffer) + 1);

+      SymImage->CurrentFilePointer = (UINT8 *) (((UINTN) SymImage->CurrentFilePointer) + strlen (Buffer) + 1);

+    }

+  }

+

+  fclose (SourceFile);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddFile (

+  IN OUT MEMORY_FILE          *FvImage,

+  IN FV_INFO                  *FvInfo,

+  IN UINTN                    Index,

+  IN OUT EFI_FFS_FILE_HEADER  **VtfFileImage,

+  IN OUT MEMORY_FILE          *SymImage

+  )

+/*++

+

+Routine Description:

+

+  This function adds a file to the FV image.  The file will pad to the

+  appropriate alignment if required.

+

+Arguments:

+

+  FvImage       The memory image of the FV to add it to.  The current offset

+                must be valid.

+  FvInfo        Pointer to information about the FV.

+  Index         The file in the FvInfo file list to add.

+  VtfFileImage  A pointer to the VTF file within the FvImage.  If this is equal

+                to the end of the FvImage then no VTF previously found.

+  SymImage      The memory image of the Sym file to update if symbols are present.

+                The current offset must be valid.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_ABORTED              An error occurred.

+  EFI_OUT_OF_RESOURCES     Insufficient resources exist to complete the add.

+

+--*/

+{

+  FILE                  *NewFile;

+  UINTN                 FileSize;

+  UINT8                 *FileBuffer;

+  UINTN                 NumBytesRead;

+  UINT32                CurrentFileAlignment;

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  CurrentFileBaseAddress;

+  UINT8                 VtfHeaderChecksum;

+  UINT8                 VtfFileChecksum;

+  UINT8                 FileState;

+  EFI_FFS_FILE_TAIL     TailValue;

+  UINT32                TailSize;

+  //

+  // Verify input parameters.

+  //

+  if (FvImage == NULL || FvInfo == NULL || FvInfo->FvFiles[Index][0] == 0 || VtfFileImage == NULL || SymImage == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Read the file to add

+  //

+  NewFile = fopen (FvInfo->FvFiles[Index], "rb");

+

+  if (NewFile == NULL) {

+    Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to open file for reading");

+    return EFI_ABORTED;

+  }

+  //

+  // Get the file size

+  //

+#ifdef __GNUC__

+  {

+    struct stat stat_buf;

+    fstat(fileno(NewFile), &stat_buf);

+    FileSize = stat_buf.st_size;

+  }

+#else

+  FileSize = _filelength (fileno (NewFile));

+#endif

+

+  //

+  // Read the file into a buffer

+  //

+  FileBuffer = malloc (FileSize);

+  if (FileBuffer == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NumBytesRead = fread (FileBuffer, sizeof (UINT8), FileSize, NewFile);

+

+  //

+  // Done with the file, from this point on we will just use the buffer read.

+  //

+  fclose (NewFile);

+

+  //

+  // Verify read successful

+  //

+  if (NumBytesRead != sizeof (UINT8) * FileSize) {

+    free (FileBuffer);

+    Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to read input file contents");

+    return EFI_ABORTED;

+  }

+  //

+  // Verify space exists to add the file

+  //

+  if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) {

+    Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient space remains to add the file");

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Update the file state based on polarity of the FV.

+  //

+  UpdateFfsFileState (

+    (EFI_FFS_FILE_HEADER *) FileBuffer,

+    (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage

+    );

+

+  //

+  // If we have a VTF file, add it at the top.

+  //

+  if (IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer)) {

+    if ((UINTN) *VtfFileImage == (UINTN) FvImage->Eof) {

+      //

+      // No previous VTF, add this one.

+      //

+      *VtfFileImage = (EFI_FFS_FILE_HEADER *) (UINTN) ((UINTN) FvImage->FileImage + FvInfo->Size - FileSize);

+      //

+      // Sanity check. The file MUST align appropriately

+      //

+      if ((((UINTN) *VtfFileImage) & 0x07) != 0) {

+        Error (NULL, 0, 0, "VTF file does not align on 8-byte boundary", NULL);

+      }

+      //

+      // copy VTF File Header

+      //

+      memcpy (*VtfFileImage, FileBuffer, sizeof (EFI_FFS_FILE_HEADER));

+

+      //

+      // Copy VTF body

+      //

+      memcpy (

+        (UINT8 *) *VtfFileImage + sizeof (EFI_FFS_FILE_HEADER),

+        FileBuffer + sizeof (EFI_FFS_FILE_HEADER),

+        FileSize - sizeof (EFI_FFS_FILE_HEADER)

+        );

+

+      //

+      // re-calculate the VTF File Header

+      //

+      FileState = (*VtfFileImage)->State;

+      (*VtfFileImage)->State = 0;

+      *(UINT32 *) ((*VtfFileImage)->Size) = FileSize;

+      (*VtfFileImage)->IntegrityCheck.Checksum.Header = 0;

+      (*VtfFileImage)->IntegrityCheck.Checksum.File = 0;

+

+      VtfHeaderChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, sizeof (EFI_FFS_FILE_HEADER));

+      (*VtfFileImage)->IntegrityCheck.Checksum.Header = VtfHeaderChecksum;

+      //

+      // Determine if it has a tail

+      //

+      if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+        TailSize = sizeof (EFI_FFS_FILE_TAIL);

+      } else {

+        TailSize = 0;

+      }

+

+      if ((*VtfFileImage)->Attributes & FFS_ATTRIB_CHECKSUM) {

+        VtfFileChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, FileSize - TailSize);

+        (*VtfFileImage)->IntegrityCheck.Checksum.File = VtfFileChecksum;

+      } else {

+        (*VtfFileImage)->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+      }

+      //

+      // If it has a file tail, update it

+      //

+      if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+        TailValue = (EFI_FFS_FILE_TAIL) (~((*VtfFileImage)->IntegrityCheck.TailReference));

+        *(EFI_FFS_FILE_TAIL *) (((UINTN) (*VtfFileImage) + GetLength ((*VtfFileImage)->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;

+      }

+      (*VtfFileImage)->State = FileState;

+      free (FileBuffer);

+      return EFI_SUCCESS;

+    } else {

+      //

+      // Already found a VTF file.

+      //

+      Error (NULL, 0, 0, "multiple VTF files are illegal in a single FV", NULL);

+      free (FileBuffer);

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // Check if alignment is required

+  //

+  Status = ReadFfsAlignment ((EFI_FFS_FILE_HEADER *) FileBuffer, &CurrentFileAlignment);

+  if (EFI_ERROR (Status)) {

+    printf ("ERROR: Could not determine alignment of file %s.\n", FvInfo->FvFiles[Index]);

+    free (FileBuffer);

+    return EFI_ABORTED;

+  }

+  //

+  // Add pad file if necessary

+  //

+  Status = AddPadFile (FvImage, CurrentFileAlignment);

+  if (EFI_ERROR (Status)) {

+    printf ("ERROR: Could not align the file data properly.\n");

+    free (FileBuffer);

+    return EFI_ABORTED;

+  }

+  //

+  // Add file

+  //

+  if ((FvImage->CurrentFilePointer + FileSize) < FvImage->Eof) {

+    //

+    // Copy the file

+    //

+    memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);

+

+    //

+    // If the file is XIP, rebase

+    //

+    CurrentFileBaseAddress = FvInfo->BaseAddress + ((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage);

+    //

+    //    Status = RebaseFfsFile ((EFI_FFS_FILE_HEADER*) FvImage->CurrentFilePointer, CurrentFileBaseAddress);

+    //    if (EFI_ERROR(Status)) {

+    //      printf ("ERROR: Could not rebase the file %s.\n", FvInfo->FvFiles[Index]);

+    //      return EFI_ABORTED;

+    //    }

+    //

+    // Update Symbol file

+    //

+    Status = AddSymFile (

+              CurrentFileBaseAddress,

+              (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer,

+              SymImage,

+              FvInfo->FvFiles[Index]

+              );

+    assert (!EFI_ERROR (Status));

+

+    //

+    // Update the current pointer in the FV image

+    //

+    FvImage->CurrentFilePointer += FileSize;

+  } else {

+    printf ("ERROR: The firmware volume is out of space, could not add file %s.\n", FvInfo->FvFiles[Index]);

+    return EFI_ABORTED;

+  }

+  //

+  // Make next file start at QWord Boundry

+  //

+  while (((UINTN) FvImage->CurrentFilePointer & 0x07) != 0) {

+    FvImage->CurrentFilePointer++;

+  }

+  //

+  // Free allocated memory.

+  //

+  free (FileBuffer);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddVariableBlock (

+  IN UINT8                    *FvImage,

+  IN UINTN                    Size,

+  IN FV_INFO                  *FvInfo

+  )

+{

+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

+  VARIABLE_STORE_HEADER       *VarStoreHeader;

+  //

+  // Variable block should exclude FvHeader. Since the length of

+  // FvHeader depends on the block map, which is variable length,

+  // we could only decide the actual variable block length here.

+  //

+  FvHeader                  = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage;

+  FvImage                   = FvImage + FvHeader->HeaderLength;

+

+  VarStoreHeader            = (VARIABLE_STORE_HEADER *) FvImage;

+

+  VarStoreHeader->Signature = VARIABLE_STORE_SIGNATURE;

+  VarStoreHeader->Size      = Size - FvHeader->HeaderLength;

+  VarStoreHeader->Format    = VARIABLE_STORE_FORMATTED;

+  VarStoreHeader->State     = VARIABLE_STORE_HEALTHY;

+  VarStoreHeader->Reserved  = 0;

+  VarStoreHeader->Reserved1 = 0;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddEventLogBlock (

+  IN UINT8                    *FvImage,

+  IN UINTN                    Size,

+  IN FV_INFO                  *FvInfo

+  )

+{

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddFTWWorkingBlock (

+  IN UINT8                    *FvImage,

+  IN UINTN                    Size,

+  IN FV_INFO                  *FvInfo

+  )

+{

+  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FTWHeader;

+  UINT32                                  Crc32;

+

+  Crc32     = 0;

+  FTWHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FvImage;

+  memcpy (&FTWHeader->Signature, &(FvInfo->FvGuid), sizeof (EFI_GUID));

+  FTWHeader->WriteQueueSize = Size - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);

+  CalculateCrc32 (FvImage, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), &Crc32);

+  FTWHeader->Crc = Crc32;

+  if (FvInfo->FvAttributes & EFI_FVB_ERASE_POLARITY) {

+    FTWHeader->WorkingBlockValid    = 0;

+    FTWHeader->WorkingBlockInvalid  = 1;

+  } else {

+    FTWHeader->WorkingBlockValid    = 1;

+    FTWHeader->WorkingBlockInvalid  = 0;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+AddFTWSpareBlock (

+  IN UINT8                    *FvImage,

+  IN UINTN                    Size,

+  IN FV_INFO                  *FvInfo

+  )

+{

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GenNonFFSFv (

+  IN UINT8                    *FvImage,

+  IN FV_INFO                  *FvInfo

+  )

+/*++

+

+Routine Description:

+

+  This function generate the non FFS FV image, such as the working block

+  and spare block. How each component of the FV is built is component

+  specific.

+

+Arguments:

+

+  FvImage       The memory image of the FV to add it to.  The current offset

+                must be valid.

+  FvInfo        Pointer to information about the FV.

+

+Returns:

+

+  EFI_SUCCESS              The function completed successfully.

+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.

+  EFI_ABORTED              An error occurred.

+  EFI_OUT_OF_RESOURCES     Insufficient resources exist to complete the add.

+

+--*/

+{

+  UINTN                       Index;

+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

+  UINT64                      TotalSize;

+

+  FvHeader  = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage;

+  TotalSize = 0;

+

+  for (Index = 0; FvInfo->FvComponents[Index].Size != 0; Index++) {

+    if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING) == 0) {

+      AddVariableBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo);

+    } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING) == 0) {

+      AddEventLogBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo);

+    } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING) == 0) {

+      AddFTWWorkingBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo);

+    } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING) == 0) {

+      AddFTWSpareBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo);

+    } else {

+      printf ("Error. Unknown Non-FFS block %s \n", FvInfo->FvComponents[Index].ComponentName);

+      return EFI_ABORTED;

+    }

+

+    FvImage   = FvImage + FvInfo->FvComponents[Index].Size;

+    TotalSize = TotalSize + FvInfo->FvComponents[Index].Size;

+  }

+  //

+  // Index and TotalSize is zero mean there's no component, so this is an empty fv

+  //

+  if ((Index != 0 || TotalSize != 0) && TotalSize != FvInfo->Size) {

+    printf ("Error. Component size does not sum up to FV size.\n");

+    return EFI_ABORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PadFvImage (

+  IN MEMORY_FILE          *FvImage,

+  IN EFI_FFS_FILE_HEADER  *VtfFileImage

+  )

+/*++

+

+Routine Description:

+

+  This function places a pad file between the last file in the FV and the VTF

+  file if the VTF file exists.

+

+Arguments:

+

+  FvImage       Memory file for the FV memory image

+  VtfFileImage  The address of the VTF file.  If this is the end of the FV

+                image, no VTF exists and no pad file is needed.

+

+Returns:

+

+  EFI_SUCCESS             Completed successfully.

+  EFI_INVALID_PARAMETER   One of the input parameters was NULL.

+

+--*/

+{

+  EFI_FFS_FILE_HEADER *PadFile;

+  UINTN               FileSize;

+

+  //

+  // If there is no VTF or the VTF naturally follows the previous file without a

+  // pad file, then there's nothing to do

+  //

+  if ((UINTN) VtfFileImage == (UINTN) FvImage->Eof || (void *) FvImage->CurrentFilePointer == (void *) VtfFileImage) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Pad file starts at beginning of free space

+  //

+  PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;

+

+  //

+  // write header

+  //

+  memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER));

+  memcpy (&PadFile->Name, &DefaultFvPadFileNameGuid, sizeof (EFI_GUID));

+  PadFile->Type       = EFI_FV_FILETYPE_FFS_PAD;

+  PadFile->Attributes = 0;

+

+  //

+  // FileSize includes the EFI_FFS_FILE_HEADER

+  //

+  FileSize          = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer;

+  PadFile->Size[0]  = (UINT8) (FileSize & 0x000000FF);

+  PadFile->Size[1]  = (UINT8) ((FileSize & 0x0000FF00) >> 8);

+  PadFile->Size[2]  = (UINT8) ((FileSize & 0x00FF0000) >> 16);

+

+  //

+  // Fill in checksums and state, must be zero during checksum calculation.

+  //

+  PadFile->IntegrityCheck.Checksum.Header = 0;

+  PadFile->IntegrityCheck.Checksum.File   = 0;

+  PadFile->State                          = 0;

+  PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER));

+  if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+    PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, FileSize);

+  } else {

+    PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+  }

+

+  PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

+

+  UpdateFfsFileState (

+    (EFI_FFS_FILE_HEADER *) PadFile,

+    (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage

+    );

+  //

+  // Update the current FV pointer

+  //

+  FvImage->CurrentFilePointer = FvImage->Eof;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UpdateResetVector (

+  IN MEMORY_FILE            *FvImage,

+  IN FV_INFO                *FvInfo,

+  IN EFI_FFS_FILE_HEADER    *VtfFile

+  )

+/*++

+

+Routine Description:

+

+  This parses the FV looking for the PEI core and then plugs the address into

+  the SALE_ENTRY point of the BSF/VTF for IPF and does BUGBUG TBD action to

+  complete an IA32 Bootstrap FV.

+

+Arguments:

+

+  FvImage       Memory file for the FV memory image

+  FvInfo        Information read from INF file.

+  VtfFile       Pointer to the VTF file in the FV image.

+

+Returns:

+

+  EFI_SUCCESS             Function Completed successfully.

+  EFI_ABORTED             Error encountered.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+  EFI_NOT_FOUND           PEI Core file not found.

+

+--*/

+{

+  EFI_FFS_FILE_HEADER       *PeiCoreFile;

+  EFI_FFS_FILE_HEADER       *SecCoreFile;

+  EFI_STATUS                Status;

+  EFI_FILE_SECTION_POINTER  Pe32Section;

+  UINT32                    EntryPoint;

+  UINT32                    BaseOfCode;

+  UINT16                    MachineType;

+  EFI_PHYSICAL_ADDRESS      PeiCorePhysicalAddress;

+  EFI_PHYSICAL_ADDRESS      SecCorePhysicalAddress;

+  EFI_PHYSICAL_ADDRESS      *SecCoreEntryAddressPtr;

+  UINT32                    *Ia32ResetAddressPtr;

+  UINT8                     *BytePointer;

+  UINT8                     *BytePointer2;

+  UINT16                    *WordPointer;

+  UINT16                    CheckSum;

+  UINTN                     Index;

+  EFI_FFS_FILE_STATE        SavedState;

+  EFI_FFS_FILE_TAIL         TailValue;

+  UINT32                    TailSize;

+  UINT64                    FitAddress;

+  FIT_TABLE                 *FitTablePtr;

+

+  //

+  // Verify input parameters

+  //

+  if (FvImage == NULL || FvInfo == NULL || VtfFile == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Initialize FV library

+  //

+  InitializeFvLib (FvImage->FileImage, (UINTN) FvImage->Eof - (UINTN) FvImage->FileImage);

+

+  //

+  // Verify VTF file

+  //

+  Status = VerifyFfsFile (VtfFile);

+  if (EFI_ERROR (Status)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Find the PEI Core

+  //

+  Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile);

+  if (EFI_ERROR (Status) || PeiCoreFile == NULL) {

+    Error (NULL, 0, 0, "could not find the PEI core in the FV", NULL);

+    return EFI_ABORTED;

+  }

+  //

+  // PEI Core found, now find PE32 section

+  //

+  Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "could not find PE32 section in PEI core file", NULL);

+    return EFI_ABORTED;

+  }

+

+  Status = GetPe32Info (

+            (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),

+            &EntryPoint,

+            &BaseOfCode,

+            &MachineType

+            );

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "could not get PE32 entry point for PEI core", NULL);

+    return EFI_ABORTED;

+  }

+  //

+  // Physical address is FV base + offset of PE32 + offset of the entry point

+  //

+  PeiCorePhysicalAddress = FvInfo->BaseAddress;

+  PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;

+  PeiCorePhysicalAddress += EntryPoint;

+

+  if (MachineType == EFI_IMAGE_MACHINE_IA64) {

+    //

+    // Update PEI_CORE address

+    //

+    //

+    // Set the uncached attribute bit in the physical address

+    //

+    PeiCorePhysicalAddress |= 0x8000000000000000ULL;

+

+    //

+    // Check if address is aligned on a 16 byte boundary

+    //

+    if (PeiCorePhysicalAddress & 0xF) {

+      printf (

+        "ERROR: PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n",

+        PeiCorePhysicalAddress

+        );

+      return EFI_ABORTED;

+    }

+    //

+    // First Get the FIT table address

+    //

+    FitAddress  = (*(UINT64 *) (FvImage->Eof - IPF_FIT_ADDRESS_OFFSET)) & 0xFFFFFFFF;

+

+    FitTablePtr = (FIT_TABLE *) (FvImage->FileImage + (FitAddress - FvInfo->BaseAddress));

+

+    Status      = UpdatePeiCoreEntryInFit (FitTablePtr, PeiCorePhysicalAddress);

+

+    if (!EFI_ERROR (Status)) {

+      UpdateFitCheckSum (FitTablePtr);

+    }

+    //

+    // Find the Sec Core

+    //

+    Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile);

+    if (EFI_ERROR (Status) || SecCoreFile == NULL) {

+      Error (NULL, 0, 0, "could not find the Sec core in the FV", NULL);

+      return EFI_ABORTED;

+    }

+    //

+    // Sec Core found, now find PE32 section

+    //

+    Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "could not find PE32 section in SEC core file", NULL);

+      return EFI_ABORTED;

+    }

+

+    Status = GetPe32Info (

+              (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),

+              &EntryPoint,

+              &BaseOfCode,

+              &MachineType

+              );

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "could not get PE32 entry point for SEC core", NULL);

+      return EFI_ABORTED;

+    }

+    //

+    // Physical address is FV base + offset of PE32 + offset of the entry point

+    //

+    SecCorePhysicalAddress = FvInfo->BaseAddress;

+    SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;

+    SecCorePhysicalAddress += EntryPoint;

+

+    //

+    // Update SEC_CORE address

+    //

+    //

+    // Set the uncached attribute bit in the physical address

+    //

+    SecCorePhysicalAddress |= 0x8000000000000000ULL;

+

+    //

+    // Update the address

+    //

+    SecCoreEntryAddressPtr  = (EFI_PHYSICAL_ADDRESS *) ((UINTN) FvImage->Eof - IPF_SALE_ENTRY_ADDRESS_OFFSET);

+    *SecCoreEntryAddressPtr = SecCorePhysicalAddress;

+

+    //

+    // Check if address is aligned on a 16 byte boundary

+    //

+    if (SecCorePhysicalAddress & 0xF) {

+      printf (

+        "ERROR: SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n",

+        SecCorePhysicalAddress

+        );

+      return EFI_ABORTED;

+    }

+  } else if (MachineType == EFI_IMAGE_MACHINE_IA32) {

+    //

+    // Get the location to update

+    //

+    Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - IA32_PEI_CORE_ENTRY_OFFSET);

+

+    //

+    // Write lower 32 bits of physical address

+    //

+    *Ia32ResetAddressPtr = (UINT32) PeiCorePhysicalAddress;

+

+    //

+    // Update the BFV base address

+    //

+    Ia32ResetAddressPtr   = (UINT32 *) ((UINTN) FvImage->Eof - 4);

+    *Ia32ResetAddressPtr  = (UINT32) (FvInfo->BaseAddress);

+

+    CheckSum              = 0x0000;

+

+    //

+    // Update the Startup AP in the FVH header block ZeroVector region.

+    //

+    BytePointer   = (UINT8 *) ((UINTN) FvImage->FileImage);

+    BytePointer2  = (FvInfo->Size == 0x10000) ? m64kRecoveryStartupApDataArray : m128kRecoveryStartupApDataArray;

+    for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY; Index++) {

+      *BytePointer++ = *BytePointer2++;

+    }

+    //

+    // Calculate the checksum

+    //

+    WordPointer = (UINT16 *) ((UINTN) FvImage->FileImage);

+    for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY / 2; Index++) {

+      CheckSum = (UINT16) (CheckSum + ((UINT16) *WordPointer));

+      WordPointer++;

+    }

+    //

+    // Update the checksum field

+    //

+    BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage);

+    BytePointer += (SIZEOF_STARTUP_DATA_ARRAY - 2);

+    WordPointer   = (UINT16 *) BytePointer;

+    *WordPointer  = (UINT16) (0x10000 - (UINT32) CheckSum);

+  } else {

+    Error (NULL, 0, 0, "invalid machine type in PEI core", "machine type=0x%X", (UINT32) MachineType);

+    return EFI_ABORTED;

+  }

+  //

+  // Determine if it has an FFS file tail.

+  //

+  if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+    TailSize = sizeof (EFI_FFS_FILE_TAIL);

+  } else {

+    TailSize = 0;

+  }

+  //

+  // Now update file checksum

+  //

+  SavedState  = VtfFile->State;

+  VtfFile->IntegrityCheck.Checksum.File = 0;

+  VtfFile->State                        = 0;

+  if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+    VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (

+                                              (UINT8 *) VtfFile,

+                                              GetLength (VtfFile->Size) - TailSize

+                                              );

+  } else {

+    VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+  }

+

+  VtfFile->State = SavedState;

+

+  //

+  // Update tail if present

+  //

+  if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+    TailValue = (EFI_FFS_FILE_TAIL) (~(VtfFile->IntegrityCheck.TailReference));

+    *(EFI_FFS_FILE_TAIL *) (((UINTN) (VtfFile) + GetLength (VtfFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetPe32Info (

+  IN UINT8                  *Pe32,

+  OUT UINT32                *EntryPoint,

+  OUT UINT32                *BaseOfCode,

+  OUT UINT16                *MachineType

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the PE32 entry point offset and machine type.  See EfiImage.h for

+  machine types.  The entry point offset is from the beginning of the PE32

+  buffer passed in.

+

+Arguments:

+

+  Pe32          Beginning of the PE32.

+  EntryPoint    Offset from the beginning of the PE32 to the image entry point.

+  BaseOfCode    Base address of code.

+  MachineType   Magic number for the machine type.

+

+Returns:

+

+  EFI_SUCCESS             Function completed successfully.

+  EFI_ABORTED             Error encountered.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+  EFI_UNSUPPORTED         The operation is unsupported.

+

+--*/

+{

+  EFI_IMAGE_DOS_HEADER  *DosHeader;

+  EFI_IMAGE_NT_HEADERS  *NtHeader;

+

+  //

+  // Verify input parameters

+  //

+  if (Pe32 == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // First is the DOS header

+  //

+  DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32;

+

+  //

+  // Verify DOS header is expected

+  //

+  if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    printf ("ERROR: Unknown magic number in the DOS header, 0x%04X.\n", DosHeader->e_magic);

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Immediately following is the NT header.

+  //

+  NtHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32 + DosHeader->e_lfanew);

+

+  //

+  // Verify NT header is expected

+  //

+  if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) {

+    printf ("ERROR: Unrecognized image signature 0x%08X.\n", NtHeader->Signature);

+    return EFI_UNSUPPORTED;

+  }

+  //

+  // Get output

+  //

+  *EntryPoint   = NtHeader->OptionalHeader.AddressOfEntryPoint;

+  *BaseOfCode   = NtHeader->OptionalHeader.BaseOfCode;

+  *MachineType  = NtHeader->FileHeader.Machine;

+

+  //

+  // Verify machine type is supported

+  //

+  if (*MachineType != EFI_IMAGE_MACHINE_IA32 && *MachineType != EFI_IMAGE_MACHINE_IA64 && *MachineType != EFI_IMAGE_MACHINE_X64 && *MachineType != EFI_IMAGE_MACHINE_EBC) {

+    printf ("ERROR: Unrecognized machine type in the PE32 file.\n");

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+//

+// Exposed function implementations (prototypes are defined in GenFvImageLib.h)

+//

+EFI_STATUS

+GenerateFvImage (

+  IN CHAR8    *InfFileImage,

+  IN UINTN    InfFileSize,

+  OUT UINT8   **FvImage,

+  OUT UINTN   *FvImageSize,

+  OUT CHAR8   **FvFileName,

+  OUT UINT8   **SymImage,

+  OUT UINTN   *SymImageSize,

+  OUT CHAR8   **SymFileName

+  )

+/*++

+

+Routine Description:

+

+  This is the main function which will be called from application.

+

+Arguments:

+

+  InfFileImage  Buffer containing the INF file contents.

+  InfFileSize   Size of the contents of the InfFileImage buffer.

+  FvImage       Pointer to the FV image created.

+  FvImageSize   Size of the FV image created and pointed to by FvImage.

+  FvFileName    Requested name for the FV file.

+  SymImage      Pointer to the Sym image created.

+  SymImageSize  Size of the Sym image created and pointed to by SymImage.

+  SymFileName   Requested name for the Sym file.

+

+Returns:

+

+  EFI_SUCCESS             Function completed successfully.

+  EFI_OUT_OF_RESOURCES    Could not allocate required resources.

+  EFI_ABORTED             Error encountered.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+

+--*/

+{

+  EFI_STATUS                  Status;

+  MEMORY_FILE                 InfMemoryFile;

+  MEMORY_FILE                 FvImageMemoryFile;

+  MEMORY_FILE                 SymImageMemoryFile;

+  FV_INFO                     FvInfo;

+  UINTN                       Index;

+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

+  EFI_FFS_FILE_HEADER         *VtfFileImage;

+

+  //

+  // Check for invalid parameter

+  //

+  if (InfFileImage == NULL || FvImage == NULL || FvImageSize == NULL || FvFileName == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Initialize file structures

+  //

+  InfMemoryFile.FileImage           = InfFileImage;

+  InfMemoryFile.CurrentFilePointer  = InfFileImage;

+  InfMemoryFile.Eof                 = InfFileImage + InfFileSize;

+

+  //

+  // Parse the FV inf file for header information

+  //

+  Status = ParseFvInf (&InfMemoryFile, &FvInfo);

+  if (EFI_ERROR (Status)) {

+    printf ("ERROR: Could not parse the input INF file.\n");

+    return EFI_ABORTED;

+  }

+  //

+  // Update the file name return values

+  //

+  strcpy (*FvFileName, FvInfo.FvName);

+  strcpy (*SymFileName, FvInfo.SymName);

+

+  //

+  // Calculate the FV size

+  //

+  *FvImageSize = FvInfo.Size;

+

+  //

+  // Allocate the FV

+  //

+  *FvImage = malloc (*FvImageSize);

+  if (*FvImage == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Allocate space for symbol file storage

+  //

+  *SymImage = malloc (SYMBOL_FILE_SIZE);

+  if (*SymImage == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Initialize the FV to the erase polarity

+  //

+  if (FvInfo.FvAttributes & EFI_FVB_ERASE_POLARITY) {

+    memset (*FvImage, -1, *FvImageSize);

+  } else {

+    memset (*FvImage, 0, *FvImageSize);

+  }

+  //

+  // Initialize FV header

+  //

+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) *FvImage;

+

+  //

+  // Initialize the zero vector to all zeros.

+  //

+  memset (FvHeader->ZeroVector, 0, 16);

+

+  //

+  // Copy the FFS GUID

+  //

+  memcpy (&FvHeader->FileSystemGuid, &FvInfo.FvGuid, sizeof (EFI_GUID));

+

+  FvHeader->FvLength    = *FvImageSize;

+  FvHeader->Signature   = EFI_FVH_SIGNATURE;

+  FvHeader->Attributes  = FvInfo.FvAttributes;

+  FvHeader->Revision    = EFI_FVH_REVISION;

+  FvHeader->Reserved[0] = 0;

+  FvHeader->Reserved[1] = 0;

+  FvHeader->Reserved[2] = 0;

+

+  //

+  // Copy firmware block map

+  //

+  for (Index = 0; FvInfo.FvBlocks[Index].NumBlocks != 0; Index++) {

+    FvHeader->FvBlockMap[Index].NumBlocks   = FvInfo.FvBlocks[Index].NumBlocks;

+    FvHeader->FvBlockMap[Index].BlockLength = FvInfo.FvBlocks[Index].BlockLength;

+  }

+  //

+  // Add block map terminator

+  //

+  FvHeader->FvBlockMap[Index].NumBlocks   = 0;

+  FvHeader->FvBlockMap[Index].BlockLength = 0;

+

+  //

+  // Complete the header

+  //

+  FvHeader->HeaderLength  = (UINT16) (((UINTN) &(FvHeader->FvBlockMap[Index + 1])) - (UINTN) *FvImage);

+  FvHeader->Checksum      = 0;

+  FvHeader->Checksum      = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));

+

+  //

+  // If there is no FFS file, find and generate each components of the FV

+  //

+  if (FvInfo.FvFiles[0][0] == 0) {

+    Status = GenNonFFSFv (*FvImage, &FvInfo);

+    if (EFI_ERROR (Status)) {

+      printf ("ERROR: Could not generate NonFFS FV.\n");

+      free (*FvImage);

+      return EFI_ABORTED;

+    }

+

+    return EFI_SUCCESS;

+  }

+  //

+  // Initialize our "file" view of the buffer

+  //

+  FvImageMemoryFile.FileImage           = *FvImage;

+  FvImageMemoryFile.CurrentFilePointer  = *FvImage + FvHeader->HeaderLength;

+  FvImageMemoryFile.Eof                 = *FvImage +*FvImageSize;

+

+  //

+  // Initialize our "file" view of the symbol file.

+  //

+  SymImageMemoryFile.FileImage          = *SymImage;

+  SymImageMemoryFile.CurrentFilePointer = *SymImage;

+  SymImageMemoryFile.Eof                = *FvImage + SYMBOL_FILE_SIZE;

+

+  //

+  // Initialize the FV library.

+  //

+  InitializeFvLib (FvImageMemoryFile.FileImage, FvInfo.Size);

+

+  //

+  // Files start on 8 byte alignments, so move to the next 8 byte aligned

+  // address.  For now, just assert if it isn't.  Currently FV header is

+  // always a multiple of 8 bytes.

+  // BUGBUG: Handle this better

+  //

+  assert ((((UINTN) FvImageMemoryFile.CurrentFilePointer) % 8) == 0);

+

+  //

+  // Initialize the VTF file address.

+  //

+  VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof;

+

+  //

+  // Add files to FV

+  //

+  for (Index = 0; FvInfo.FvFiles[Index][0] != 0; Index++) {

+    //

+    // Add the file

+    //

+    Status = AddFile (&FvImageMemoryFile, &FvInfo, Index, &VtfFileImage, &SymImageMemoryFile);

+

+    //

+    // Exit if error detected while adding the file

+    //

+    if (EFI_ERROR (Status)) {

+      printf ("ERROR: Could not add file %s.\n", FvInfo.FvFiles[Index]);

+      free (*FvImage);

+      return EFI_ABORTED;

+    }

+  }

+  //

+  // If there is a VTF file, some special actions need to occur.

+  //

+  if ((UINTN) VtfFileImage != (UINTN) FvImageMemoryFile.Eof) {

+    //

+    // Pad from the end of the last file to the beginning of the VTF file.

+    //

+    Status = PadFvImage (&FvImageMemoryFile, VtfFileImage);

+    if (EFI_ERROR (Status)) {

+      printf ("ERROR: Could not create the pad file between the last file and the VTF file.\n");

+      free (*FvImage);

+      return EFI_ABORTED;

+    }

+    //

+    // Update reset vector (SALE_ENTRY for IPF)

+    // Now for IA32 and IA64 platform, the fv which has bsf file must have the 

+    // EndAddress of 0xFFFFFFFF. Thus, only this type fv needs to update the   

+    // reset vector. If the PEI Core is found, the VTF file will probably get  

+    // corrupted by updating the entry point.                                  

+    //

+    if ((FvInfo.BaseAddress + FvInfo.Size) == FV_IMAGES_TOP_ADDRESS) {       

+      Status = UpdateResetVector (&FvImageMemoryFile, &FvInfo, VtfFileImage);

+      if (EFI_ERROR(Status)) {                                               

+        printf ("ERROR: Could not update the reset vector.\n");              

+        free (*FvImage);                                                     

+        return EFI_ABORTED;                                                  

+      }                                                                      

+    }

+  } 

+  //

+  // Determine final Sym file size

+  //

+  *SymImageSize = SymImageMemoryFile.CurrentFilePointer - SymImageMemoryFile.FileImage;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+UpdatePeiCoreEntryInFit (

+  IN FIT_TABLE     *FitTablePtr,

+  IN UINT64        PeiCorePhysicalAddress

+  )

+/*++

+

+Routine Description:

+

+  This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from

+  Sec to Pei Core

+

+Arguments:

+

+  FitTablePtr             - The pointer of FIT_TABLE.

+  PeiCorePhysicalAddress  - The address of Pei Core entry.

+

+Returns:

+

+  EFI_SUCCESS             - The PEI_CORE FIT entry was updated successfully.

+  EFI_NOT_FOUND           - Not found the PEI_CORE FIT entry.

+

+--*/

+{

+  FIT_TABLE *TmpFitPtr;

+  UINTN     Index;

+  UINTN     NumFitComponents;

+

+  TmpFitPtr         = FitTablePtr;

+  NumFitComponents  = TmpFitPtr->CompSize;

+

+  for (Index = 0; Index < NumFitComponents; Index++) {

+    if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_PEICORE) {

+      TmpFitPtr->CompAddress = PeiCorePhysicalAddress;

+      return EFI_SUCCESS;

+    }

+

+    TmpFitPtr++;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+VOID

+UpdateFitCheckSum (

+  IN FIT_TABLE   *FitTablePtr

+  )

+/*++

+

+Routine Description:

+

+  This function is used to update the checksum for FIT.

+

+

+Arguments:

+

+  FitTablePtr             - The pointer of FIT_TABLE.

+

+Returns:

+

+  None.

+

+--*/

+{

+  if ((FitTablePtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {

+    FitTablePtr->CheckSum = 0;

+    FitTablePtr->CheckSum = CalculateChecksum8 ((UINT8 *) FitTablePtr, FitTablePtr->CompSize * 16);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLib.h b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLib.h
new file mode 100644
index 0000000..cc761b8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLib.h
@@ -0,0 +1,140 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  GenFvImageLib.h

+

+Abstract:

+

+  This file contains describes the public interfaces to the GenFvImage Library.

+  The basic purpose of the library is to create Firmware Volume images.

+

+--*/

+

+#ifndef _EFI_GEN_FV_IMAGE_LIB_H

+#define _EFI_GEN_FV_IMAGE_LIB_H

+

+//

+// Include files

+//

+// #include "Efi2WinNT.h"

+#include "ParseInf.h"

+

+//

+// Following definition is used for FIT in IPF

+//

+#define COMP_TYPE_FIT_PEICORE 0x10

+#define COMP_TYPE_FIT_UNUSED  0x7F

+

+#define FIT_TYPE_MASK         0x7F

+#define CHECKSUM_BIT_MASK     0x80

+

+#pragma pack(1)

+

+typedef struct {

+  UINT64  CompAddress;

+  UINT32  CompSize;

+  UINT16  CompVersion;

+  UINT8   CvAndType;

+  UINT8   CheckSum;

+} FIT_TABLE;

+

+#pragma pack()

+//

+// Exported function prototypes

+//

+EFI_STATUS

+GenerateFvImage (

+  IN CHAR8    *InfFileImage,

+  IN UINTN    InfFileSize,

+  OUT UINT8   **FvImage,

+  OUT UINTN   *FvImageSize,

+  OUT CHAR8   **FvFileName,

+  OUT UINT8   **SymImage,

+  OUT UINTN   *SymImageSize,

+  OUT CHAR8   **SymFileName

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This is the main function which will be called from application.

+

+Arguments:

+

+  InfFileImage  Buffer containing the INF file contents.

+  InfFileSize   Size of the contents of the InfFileImage buffer.

+  FvImage       Pointer to the FV image created.

+  FvImageSize   Size of the FV image created and pointed to by FvImage.

+  FvFileName    Requested name for the FV file.

+  SymImage      Pointer to the Sym image created.

+  SymImageSize  Size of the Sym image created and pointed to by SymImage.

+  SymFileName   Requested name for the Sym file.

+    

+Returns:

+ 

+  EFI_SUCCESS             Function completed successfully.

+  EFI_OUT_OF_RESOURCES    Could not allocate required resources.

+  EFI_ABORTED             Error encountered.

+  EFI_INVALID_PARAMETER   A required parameter was NULL.

+

+--*/

+EFI_STATUS

+UpdatePeiCoreEntryInFit (

+  IN FIT_TABLE     *FitTablePtr,

+  IN UINT64        PeiCorePhysicalAddress

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from

+  Sec to Pei Core

+

+Arguments:

+

+  FitTablePtr             - The pointer of FIT_TABLE.

+  PeiCorePhysicalAddress  - The address of Pei Core entry.

+

+Returns:

+

+  EFI_SUCCESS             - The PEI_CORE FIT entry was updated successfully.

+  EFI_NOT_FOUND           - Not found the PEI_CORE FIT entry.

+

+--*/

+VOID

+UpdateFitCheckSum (

+  IN FIT_TABLE   *FitTablePtr

+  )

+;

+

+/*++

+

+Routine Description:

+

+  This function is used to update the checksum for FIT.

+

+

+Arguments:

+

+  FitTablePtr             - The pointer of FIT_TABLE.

+

+Returns:

+

+  None.

+

+--*/

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLibInternal.h b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLibInternal.h
new file mode 100644
index 0000000..f38fe11
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/GenFvImageLibInternal.h
@@ -0,0 +1,170 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  

+  GenFvImageLibInternal.h

+

+Abstract:

+

+  This file contains describes the private declarations for the GenFvImage Library.

+  The basic purpose of the library is to create Firmware Volume images.

+

+--*/

+

+#ifndef _EFI_GEN_FV_IMAGE_LIB_INTERNAL_H

+#define _EFI_GEN_FV_IMAGE_LIB_INTERNAL_H

+

+//

+// Include files

+//

+#include "GenFvImageLib.h"

+#include <stdlib.h>

+#include <CommonLib.h>

+#include "FirmwareVolumeHeader.h"

+

+//

+// Private data declarations

+//

+//

+// The maximum number of block map entries supported by the library

+//

+#define MAX_NUMBER_OF_FV_BLOCKS 100

+

+//

+// The maximum number of files in the FV supported by the library

+//

+#define MAX_NUMBER_OF_FILES_IN_FV       1000

+#define MAX_NUMBER_OF_COMPONENTS_IN_FV  10

+

+//

+// INF file strings

+//

+#define OPTIONS_SECTION_STRING            "[options]"

+#define ATTRIBUTES_SECTION_STRING         "[attributes]"

+#define FILES_SECTION_STRING              "[files]"

+#define COMPONENT_SECTION_STRING          "[components]"

+

+#define EFI_FV_BASE_ADDRESS_STRING        "EFI_BASE_ADDRESS"

+#define EFI_FV_FILE_NAME_STRING           "EFI_FILE_NAME"

+#define EFI_SYM_FILE_NAME_STRING          "EFI_SYM_FILE_NAME"

+#define EFI_NUM_BLOCKS_STRING             "EFI_NUM_BLOCKS"

+#define EFI_BLOCK_SIZE_STRING             "EFI_BLOCK_SIZE"

+#define EFI_FV_GUID_STRING                "EFI_FV_GUID"

+

+#define EFI_FVB_READ_DISABLED_CAP_STRING  "EFI_READ_DISABLED_CAP"

+#define EFI_FVB_READ_ENABLED_CAP_STRING   "EFI_READ_ENABLED_CAP"

+#define EFI_FVB_READ_STATUS_STRING        "EFI_READ_STATUS"

+

+#define EFI_FVB_WRITE_DISABLED_CAP_STRING "EFI_WRITE_DISABLED_CAP"

+#define EFI_FVB_WRITE_ENABLED_CAP_STRING  "EFI_WRITE_ENABLED_CAP"

+#define EFI_FVB_WRITE_STATUS_STRING       "EFI_WRITE_STATUS"

+

+#define EFI_FVB_LOCK_CAP_STRING           "EFI_LOCK_CAP"

+#define EFI_FVB_LOCK_STATUS_STRING        "EFI_LOCK_STATUS"

+

+#define EFI_FVB_STICKY_WRITE_STRING       "EFI_STICKY_WRITE"

+#define EFI_FVB_MEMORY_MAPPED_STRING      "EFI_MEMORY_MAPPED"

+#define EFI_FVB_ERASE_POLARITY_STRING     "EFI_ERASE_POLARITY"

+

+#define EFI_FVB_ALIGNMENT_CAP_STRING      "EFI_ALIGNMENT_CAP"

+#define EFI_FVB_ALIGNMENT_2_STRING        "EFI_ALIGNMENT_2"

+#define EFI_FVB_ALIGNMENT_4_STRING        "EFI_ALIGNMENT_4"

+#define EFI_FVB_ALIGNMENT_8_STRING        "EFI_ALIGNMENT_8"

+#define EFI_FVB_ALIGNMENT_16_STRING       "EFI_ALIGNMENT_16"

+#define EFI_FVB_ALIGNMENT_32_STRING       "EFI_ALIGNMENT_32"

+#define EFI_FVB_ALIGNMENT_64_STRING       "EFI_ALIGNMENT_64"

+#define EFI_FVB_ALIGNMENT_128_STRING      "EFI_ALIGNMENT_128"

+#define EFI_FVB_ALIGNMENT_256_STRING      "EFI_ALIGNMENT_256"

+#define EFI_FVB_ALIGNMENT_512_STRING      "EFI_ALIGNMENT_512"

+#define EFI_FVB_ALIGNMENT_1K_STRING       "EFI_ALIGNMENT_1K"

+#define EFI_FVB_ALIGNMENT_2K_STRING       "EFI_ALIGNMENT_2K"

+#define EFI_FVB_ALIGNMENT_4K_STRING       "EFI_ALIGNMENT_4K"

+#define EFI_FVB_ALIGNMENT_8K_STRING       "EFI_ALIGNMENT_8K"

+#define EFI_FVB_ALIGNMENT_16K_STRING      "EFI_ALIGNMENT_16K"

+#define EFI_FVB_ALIGNMENT_32K_STRING      "EFI_ALIGNMENT_32K"

+#define EFI_FVB_ALIGNMENT_64K_STRING      "EFI_ALIGNMENT_64K"

+

+//

+// Component sections

+//

+#define EFI_NV_VARIABLE_STRING    "EFI_NV_VARIABLE"

+#define EFI_NV_EVENT_LOG_STRING   "EFI_NV_EVENT_LOG"

+#define EFI_NV_FTW_WORKING_STRING "EFI_NV_FTW_WORKING"

+#define EFI_NV_FTW_SPARE_STRING   "EFI_NV_FTW_SPARE"

+

+#define EFI_FILE_NAME_STRING      "EFI_FILE_NAME"

+

+#define ONE_STRING                "1"

+#define ZERO_STRING               "0"

+#define TRUE_STRING               "TRUE"

+#define FALSE_STRING              "FALSE"

+#define NULL_STRING               "NULL"

+

+//

+// Defines to calculate the offset for PEI CORE entry points

+//

+#define IA32_PEI_CORE_ENTRY_OFFSET  0x20

+

+//

+// Defines to calculate the FIT table

+//

+#define IPF_FIT_ADDRESS_OFFSET  0x20

+

+//

+// Defines to calculate the offset for SALE_ENTRY

+//

+#define IPF_SALE_ENTRY_ADDRESS_OFFSET 0x18

+

+//

+// Symbol file definitions, current max size if 512K

+//

+#define SYMBOL_FILE_SIZE  0x80000

+

+#define FV_IMAGES_TOP_ADDRESS             0x100000000ULL

+

+//

+// Private data types

+//

+//

+// Component information

+//

+typedef struct {

+  UINTN Size;

+  CHAR8 ComponentName[_MAX_PATH];

+} COMPONENT_INFO;

+

+//

+// FV information holder

+//

+typedef struct {

+  EFI_PHYSICAL_ADDRESS    BaseAddress;

+  EFI_GUID                FvGuid;

+  UINTN                   Size;

+  CHAR8                   FvName[_MAX_PATH];

+  CHAR8                   SymName[_MAX_PATH];

+  EFI_FV_BLOCK_MAP_ENTRY  FvBlocks[MAX_NUMBER_OF_FV_BLOCKS];

+  EFI_FVB_ATTRIBUTES      FvAttributes;

+  CHAR8                   FvFiles[MAX_NUMBER_OF_FILES_IN_FV][_MAX_PATH];

+  COMPONENT_INFO          FvComponents[MAX_NUMBER_OF_COMPONENTS_IN_FV];

+} FV_INFO;

+

+//

+// Private function prototypes

+//

+EFI_STATUS

+ParseFvInf (

+  IN MEMORY_FILE  *InfFile,

+  IN FV_INFO      *FvInfo

+  )

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenFvImage/build.xml b/edk2/Tools/Source/TianoTools/GenFvImage/build.xml
new file mode 100644
index 0000000..d29a2ec
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenFvImage/build.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenFvImage Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenFvImage"/>

+  <property name="FileSet" value="GenFvImageLib.c GenFvImageExe.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR_IA32" value="${PACKAGE_DIR}/${ToolName}/tmp/Ia32"/>

+  <property name="BUILD_DIR_X64" value="${PACKAGE_DIR}/${ToolName}/tmp/X64"/>

+  <property name="BUILD_DIR_IPF" value="${PACKAGE_DIR}/${ToolName}/tmp/Ipf"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR_IA32}"/>

+    <mkdir dir="${BUILD_DIR_X64}"/>

+    <mkdir dir="${BUILD_DIR_IPF}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+        <property name="ToolChain" value="gcc"/>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+

+    <condition property="syslibdirs" value="">

+      <os family="mac"/>

+    </condition>

+    

+    <condition property="syslibs" value="">

+      <os family="mac"/>

+    </condition>

+    

+    <condition property="syslibdirs" value="${env.CYGWIN_HOME}/lib/e2fsprogs">

+      <os family="windows"/>

+    </condition>

+    

+    <condition property="syslibs" value="uuid">

+      <os family="windows"/>

+    </condition>

+    

+    <condition property="syslibdirs" value="/usr/lib">

+      <os name="Linux"/>

+    </condition>

+    

+    <condition property="syslibs" value="uuid">

+      <os name="Linux"/>

+    </condition>

+    

+  </target>

+

+  <target name="Tool" depends="init, GenFvImage, GenFvImage_Ia32, GenFvImage_X64, GenFvImage_Ipf"/>

+

+  <target name="GenFvImage" >

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_IA32}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_IA32_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${PACKAGE_DIR}/${ToolName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/ToBeRemoved"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_Ia32"/>

+      <linkerarg value="/nodefaultlib:libc.lib" unless="gcc"/>

+      <syslibset dir="${syslibdirs}" libs="${syslibs}" if="gcc"/>

+      <syslibset libs="RpcRT4" unless="gcc"/>

+    </cc>

+  </target>

+

+  <target name="GenFvImage_Ia32">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_IA32}" 

+        outfile="${BIN_DIR}/${ToolName}_Ia32"

+        outtype="executable"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_IA32_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${PACKAGE_DIR}/${ToolName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/ToBeRemoved"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_Ia32"/>

+      <linkerarg value="/nodefaultlib:libc.lib" unless="gcc"/>

+      <syslibset dir="${syslibdirs}" libs="${syslibs}" if="gcc"/>

+      <syslibset libs="RpcRT4" unless="gcc"/>

+    </cc>

+  </target>

+

+  <target name="GenFvImage_X64">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_X64}" 

+        outfile="${BIN_DIR}/${ToolName}_X64"

+        outtype="executable"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_X64_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${PACKAGE_DIR}/${ToolName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/ToBeRemoved"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_X64"/>

+      <linkerarg value="/nodefaultlib:libc.lib" unless="gcc"/>

+      <syslibset dir="${syslibdirs}" libs="${syslibs}" if="gcc"/>

+      <syslibset libs="RpcRT4" unless="gcc"/>

+    </cc>

+  </target>

+

+  <target name="GenFvImage_Ipf">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_IPF}" 

+        outfile="${BIN_DIR}/${ToolName}_Ipf"

+        outtype="executable"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_IPF_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${PACKAGE_DIR}/${ToolName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/ToBeRemoved"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_Ipf"/>

+      <linkerarg value="/nodefaultlib:libc.lib" unless="gcc"/>

+      <syslibset dir="${syslibdirs}" libs="${syslibs}" if="gcc"/>

+      <syslibset libs="RpcRT4" unless="gcc"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR_IA32}" includes="*.obj"/>

+      <fileset dir="${BUILD_DIR_X64}" includes="*.obj"/>

+      <fileset dir="${BUILD_DIR_IPF}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${PACKAGE_DIR}/${ToolName}/tmp">

+      

+      <fileset dir="${BIN_DIR}" includes="${ToolName}_Ia32${ext_exe}"/>

+      <fileset dir="${BIN_DIR}" includes="${ToolName}_X64${ext_exe}"/>

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+      <fileset dir="${BIN_DIR}" includes="${ToolName}_Ipf${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenSection/GenSection.c b/edk2/Tools/Source/TianoTools/GenSection/GenSection.c
new file mode 100644
index 0000000..8ae0a9c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenSection/GenSection.c
@@ -0,0 +1,939 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenSection.c

+

+Abstract:

+

+  Creates output file that is a properly formed section per the FV spec.

+

+--*/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include "FirmwareVolumeImageFormat.h"

+#include "CommonLib.h"

+#include "EfiCompress.h"

+#include "EfiCustomizedCompress.h"

+#include "Crc32.h"

+#include "EfiUtilityMsgs.h"

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include "GenSection.h"

+

+#include <GuidedSectionExtraction.h>

+

+#define UTILITY_NAME            "GenSection"

+

+#define PARAMETER_NOT_SPECIFIED "Parameter not specified"

+#define MAXIMUM_INPUT_FILE_NUM  10

+

+char      *SectionTypeName[] = {

+  NULL,                                 // 0x00 - reserved

+  "EFI_SECTION_COMPRESSION",            // 0x01

+  "EFI_SECTION_GUID_DEFINED",           // 0x02

+  NULL,                                 // 0x03 - reserved

+  NULL,                                 // 0x04 - reserved

+  NULL,                                 // 0x05 - reserved

+  NULL,                                 // 0x06 - reserved

+  NULL,                                 // 0x07 - reserved

+  NULL,                                 // 0x08 - reserved

+  NULL,                                 // 0x09 - reserved

+  NULL,                                 // 0x0A - reserved

+  NULL,                                 // 0x0B - reserved

+  NULL,                                 // 0x0C - reserved

+  NULL,                                 // 0x0D - reserved

+  NULL,                                 // 0x0E - reserved

+  NULL,                                 // 0x0F - reserved

+  "EFI_SECTION_PE32",                   // 0x10

+  "EFI_SECTION_PIC",                    // 0x11

+  "EFI_SECTION_TE",                     // 0x12

+  "EFI_SECTION_DXE_DEPEX",              // 0x13

+  "EFI_SECTION_VERSION",                // 0x14

+  "EFI_SECTION_USER_INTERFACE",         // 0x15

+  "EFI_SECTION_COMPATIBILITY16",        // 0x16

+  "EFI_SECTION_FIRMWARE_VOLUME_IMAGE",  // 0x17

+  "EFI_SECTION_FREEFORM_SUBTYPE_GUID",  // 0x18

+  "EFI_SECTION_RAW",                    // 0x19

+  NULL,                                 // 0x1A

+  "EFI_SECTION_PEI_DEPEX"               // 0x1B

+};

+

+char      *CompressionTypeName[]    = { "NONE", "STANDARD" };

+char      *GUIDedSectionTypeName[]  = { "CRC32" };

+EFI_GUID  gEfiCrc32SectionGuid      = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;

+

+static

+VOID

+PrintUsageMessage (

+  VOID

+  )

+{

+  UINTN SectionType;

+  UINTN DisplayCount;

+

+  printf ("Usage: "UTILITY_NAME "  -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n");

+  printf ("    Where SectionType is one of the following section types:\n\n");

+

+  DisplayCount = 0;

+  for (SectionType = 0; SectionType <= EFI_SECTION_LAST_SECTION_TYPE; SectionType++) {

+    if (SectionTypeName[SectionType] != NULL) {

+      printf ("       %s\n", SectionTypeName[SectionType]);

+    }

+  }

+

+  printf ("\n    and SectionType dependent parameters are as follows:\n\n");

+  printf (

+    "       %s:       -t < %s | %s >\n",

+    SectionTypeName[EFI_SECTION_COMPRESSION],

+    CompressionTypeName[EFI_NOT_COMPRESSED],

+    CompressionTypeName[EFI_STANDARD_COMPRESSION]

+    );

+  printf (

+    "       %s:      -t < %s >\n""                          // Currently only CRC32 is supported\n\n",

+    SectionTypeName[EFI_SECTION_GUID_DEFINED],

+    GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED]

+    );

+  printf (

+    "       %s:           -v VersionNumber\n""                          [-a \"Version string\"]\n\n",

+    SectionTypeName[EFI_SECTION_VERSION]

+    );

+  printf (

+    "       %s:    -a \"Human readable name\"\n\n",

+    SectionTypeName[EFI_SECTION_USER_INTERFACE]

+    );

+}

+

+VOID

+Ascii2UnicodeWriteString (

+  char    *String,

+  FILE    *OutFile,

+  BOOLEAN WriteLangCode

+  )

+{

+  UINTN Index;

+  UINT8 AsciiNull;

+  //

+  // BUGBUG need to get correct language code...

+  //

+  char  *EnglishLangCode = "eng";

+  AsciiNull = 0;

+  //

+  // first write the language code (english only)

+  //

+  if (WriteLangCode) {

+    fwrite (EnglishLangCode, 1, 4, OutFile);

+  }

+  //

+  // Next, write out the string... Convert ASCII to Unicode in the process.

+  //

+  Index = 0;

+  do {

+    fwrite (&String[Index], 1, 1, OutFile);

+    fwrite (&AsciiNull, 1, 1, OutFile);

+  } while (String[Index++] != 0);

+}

+

+STATUS

+GenSectionCommonLeafSection (

+  char    **InputFileName,

+  int     InputFileNum,

+  UINTN   SectionType,

+  FILE    *OutFile

+  )

+/*++

+        

+Routine Description:

+           

+  Generate a leaf section of type other than EFI_SECTION_VERSION

+  and EFI_SECTION_USER_INTERFACE. Input file must be well formed.

+  The function won't validate the input file's contents. For

+  common leaf sections, the input file may be a binary file.

+  The utility will add section header to the file.

+            

+Arguments:

+               

+  InputFileName  - Name of the input file.

+                

+  InputFileNum   - Number of input files. Should be 1 for leaf section.

+

+  SectionType    - A valid section type string

+

+  OutFile        - Output file handle

+

+Returns:

+                       

+  STATUS_ERROR            - can't continue

+  STATUS_SUCCESS          - successful return

+

+--*/

+{

+  UINT64                    InputFileLength;

+  FILE                      *InFile;

+  UINT8                     *Buffer;

+  INTN                      TotalLength;

+  EFI_COMMON_SECTION_HEADER CommonSect;

+  STATUS                    Status;

+

+  if (InputFileNum > 1) {

+    Error (NULL, 0, 0, "invalid parameter", "more than one input file specified");

+    return STATUS_ERROR;

+  } else if (InputFileNum < 1) {

+    Error (NULL, 0, 0, "no input file specified", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // Open the input file

+  //

+  InFile = fopen (InputFileName[0], "rb");

+  if (InFile == NULL) {

+    Error (NULL, 0, 0, InputFileName[0], "failed to open input file");

+    return STATUS_ERROR;

+  }

+

+  Status  = STATUS_ERROR;

+  Buffer  = NULL;

+  //

+  // Seek to the end of the input file so we can determine its size

+  //

+  fseek (InFile, 0, SEEK_END);

+  fgetpos (InFile, &InputFileLength);

+  fseek (InFile, 0, SEEK_SET);

+  //

+  // Fill in the fields in the local section header structure

+  //

+  CommonSect.Type = (EFI_SECTION_TYPE) SectionType;

+  TotalLength     = sizeof (CommonSect) + (INTN) InputFileLength;

+  //

+  // Size must fit in 3 bytes

+  //

+  if (TotalLength >= 0x1000000) {

+    Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit", TotalLength);

+    goto Done;

+  }

+  //

+  // Now copy the size into the section header and write out the section header

+  //

+  memcpy (&CommonSect.Size, &TotalLength, 3);

+  fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);

+  //

+  // Allocate a buffer to read in the contents of the input file. Then

+  // read it in as one block and write it to the output file.

+  //

+  if (InputFileLength != 0) {

+    Buffer = (UINT8 *) malloc ((size_t) InputFileLength);

+    if (Buffer == NULL) {

+      Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+      goto Done;

+    }

+

+    if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) {

+      Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file");

+      goto Done;

+    }

+

+    if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) {

+      Error (NULL, 0, 0, "failed to write to output file", NULL);

+      goto Done;

+    }

+  }

+

+  Status = STATUS_SUCCESS;

+Done:

+  fclose (InFile);

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+GetSectionContents (

+  char    **InputFileName,

+  int     InputFileNum,

+  UINT8   *FileBuffer,

+  UINTN   *BufferLength

+  )

+/*++

+        

+Routine Description:

+           

+  Get the contents of all section files specified in InputFileName

+  into FileBuffer.

+            

+Arguments:

+               

+  InputFileName  - Name of the input file.

+                

+  InputFileNum   - Number of input files. Should be at least 1.

+

+  FileBuffer     - Output buffer to contain data

+

+  BufferLength   - Actual length of the data 

+

+Returns:

+                       

+  EFI_SUCCESS on successful return

+  EFI_INVALID_PARAMETER if InputFileNum is less than 1

+  EFI_ABORTED if unable to open input file.

+

+--*/

+{

+  UINTN   Size;

+  UINTN   FileSize;

+  INTN    Index;

+  FILE    *InFile;

+

+  if (InputFileNum < 1) {

+    Error (NULL, 0, 0, "must specify at least one input file", NULL);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Size = 0;

+  //

+  // Go through our array of file names and copy their contents

+  // to the output buffer.

+  //

+  for (Index = 0; Index < InputFileNum; Index++) {

+    InFile = fopen (InputFileName[Index], "rb");

+    if (InFile == NULL) {

+      Error (NULL, 0, 0, InputFileName[Index], "failed to open input file");

+      return EFI_ABORTED;

+    }

+

+    fseek (InFile, 0, SEEK_END);

+    FileSize = ftell (InFile);

+    fseek (InFile, 0, SEEK_SET);

+    //

+    // Now read the contents of the file into the buffer

+    //

+    if (FileSize > 0) {

+      if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {

+        Error (NULL, 0, 0, InputFileName[Index], "failed to read contents of input file");

+        fclose (InFile);

+        return EFI_ABORTED;

+      }

+    }

+

+    fclose (InFile);

+    Size += (UINTN) FileSize;

+    //

+    // make sure section ends on a DWORD boundary

+    //

+    while ((Size & 0x03) != 0) {

+      FileBuffer[Size] = 0;

+      Size++;

+    }

+  }

+

+  *BufferLength = Size;

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GenSectionCompressionSection (

+  char    **InputFileName,

+  int     InputFileNum,

+  UINTN   SectionType,

+  UINTN   SectionSubType,

+  FILE    *OutFile

+  )

+/*++

+        

+Routine Description:

+           

+  Generate an encapsulating section of type EFI_SECTION_COMPRESSION

+  Input file must be already sectioned. The function won't validate

+  the input files' contents. Caller should hand in files already 

+  with section header.

+            

+Arguments:

+               

+  InputFileName  - Name of the input file.

+                

+  InputFileNum   - Number of input files. Should be at least 1.

+

+  SectionType    - Section type to generate. Should be 

+                   EFI_SECTION_COMPRESSION

+

+  SectionSubType - Specify the compression algorithm requested. 

+  

+  OutFile        - Output file handle

+

+Returns:

+                       

+  EFI_SUCCESS           on successful return

+  EFI_INVALID_PARAMETER if InputFileNum is less than 1

+  EFI_ABORTED           if unable to open input file.

+  EFI_OUT_OF_RESOURCES  No resource to complete the operation.

+--*/

+{

+  UINTN                   TotalLength;

+  UINTN                   InputLength;

+  UINTN                   CompressedLength;

+  UINT8                   *FileBuffer;

+  UINT8                   *OutputBuffer;

+  EFI_STATUS              Status;

+  EFI_COMPRESSION_SECTION CompressionSect;

+  COMPRESS_FUNCTION       CompressFunction;

+

+  if (SectionType != EFI_SECTION_COMPRESSION) {

+    Error (NULL, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  InputLength       = 0;

+  FileBuffer        = NULL;

+  OutputBuffer      = NULL;

+  CompressedLength  = 0;

+  FileBuffer        = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8));

+  if (FileBuffer == NULL) {

+    Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // read all input file contents into a buffer

+  //

+  Status = GetSectionContents (

+            InputFileName,

+            InputFileNum,

+            FileBuffer,

+            &InputLength

+            );

+  if (EFI_ERROR (Status)) {

+    free (FileBuffer);

+    return Status;

+  }

+

+  CompressFunction = NULL;

+

+  //

+  // Now data is in FileBuffer, compress the data

+  //

+  switch (SectionSubType) {

+  case EFI_NOT_COMPRESSED:

+    CompressedLength = InputLength;

+    break;

+

+  case EFI_STANDARD_COMPRESSION:

+    CompressFunction = (COMPRESS_FUNCTION) Compress;

+    break;

+

+  case EFI_CUSTOMIZED_COMPRESSION:

+    CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress;

+    break;

+

+  default:

+    Error (NULL, 0, 0, "unknown compression type", NULL);

+    free (FileBuffer);

+    return EFI_ABORTED;

+  }

+

+  if (CompressFunction != NULL) {

+

+    Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+      OutputBuffer = malloc (CompressedLength);

+      if (!OutputBuffer) {

+        free (FileBuffer);

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);

+    }

+

+    free (FileBuffer);

+    FileBuffer = OutputBuffer;

+

+    if (EFI_ERROR (Status)) {

+      if (FileBuffer != NULL) {

+        free (FileBuffer);

+      }

+

+      return Status;

+    }

+  }

+

+  TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);

+  //

+  // Add the section header for the compressed data

+  //

+  CompressionSect.CommonHeader.Type     = (EFI_SECTION_TYPE) SectionType;

+  CompressionSect.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);

+  CompressionSect.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);

+  CompressionSect.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);

+  CompressionSect.CompressionType       = (UINT8) SectionSubType;

+  CompressionSect.UncompressedLength    = InputLength;

+

+  fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile);

+  fwrite (FileBuffer, CompressedLength, 1, OutFile);

+  free (FileBuffer);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GenSectionGuidDefinedSection (

+  char    **InputFileName,

+  int     InputFileNum,

+  UINTN   SectionType,

+  UINTN   SectionSubType,

+  FILE    *OutFile

+  )

+/*++

+        

+Routine Description:

+           

+  Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED

+  Input file must be already sectioned. The function won't validate

+  the input files' contents. Caller should hand in files already 

+  with section header.

+            

+Arguments:

+               

+  InputFileName  - Name of the input file.

+                

+  InputFileNum   - Number of input files. Should be at least 1.

+

+  SectionType    - Section type to generate. Should be 

+                   EFI_SECTION_GUID_DEFINED

+

+  SectionSubType - Specify the authentication algorithm requested. 

+  

+  OutFile        - Output file handle

+

+Returns:

+                       

+  EFI_SUCCESS on successful return

+  EFI_INVALID_PARAMETER if InputFileNum is less than 1

+  EFI_ABORTED if unable to open input file.

+  EFI_OUT_OF_RESOURCES  No resource to complete the operation.

+

+--*/

+{

+  INTN                  TotalLength;

+  INTN                  InputLength;

+  UINT8                 *FileBuffer;

+  UINT32                Crc32Checksum;

+  EFI_STATUS            Status;

+  CRC32_SECTION_HEADER  Crc32GuidSect;

+

+  if (SectionType != EFI_SECTION_GUID_DEFINED) {

+    Error (NULL, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  InputLength = 0;

+  FileBuffer  = NULL;

+  FileBuffer  = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8));

+  if (FileBuffer == NULL) {

+    Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // read all input file contents into a buffer

+  //

+  Status = GetSectionContents (

+            InputFileName,

+            InputFileNum,

+            FileBuffer,

+            &InputLength

+            );

+  if (EFI_ERROR (Status)) {

+    free (FileBuffer);

+    return Status;

+  }

+  //

+  // Now data is in FileBuffer, compress the data

+  //

+  switch (SectionSubType) {

+  case EFI_SECTION_CRC32_GUID_DEFINED:

+    Crc32Checksum = 0;

+    CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);

+    if (EFI_ERROR (Status)) {

+      free (FileBuffer);

+      return Status;

+    }

+

+    TotalLength = InputLength + CRC32_SECTION_HEADER_SIZE;

+    Crc32GuidSect.GuidSectionHeader.CommonHeader.Type     = (EFI_SECTION_TYPE) SectionType;

+    Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);

+    Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);

+    Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);

+    memcpy (&(Crc32GuidSect.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));

+    Crc32GuidSect.GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;

+    Crc32GuidSect.GuidSectionHeader.DataOffset  = CRC32_SECTION_HEADER_SIZE;

+    Crc32GuidSect.CRC32Checksum                 = Crc32Checksum;

+

+    break;

+

+  default:

+    Error (NULL, 0, 0, "invalid parameter", "unknown GUID defined type");

+    free (FileBuffer);

+    return EFI_ABORTED;

+  }

+

+  fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile);

+  fwrite (FileBuffer, InputLength, 1, OutFile);

+

+  free (FileBuffer);

+

+  return EFI_SUCCESS;

+}

+

+int

+main (

+  int  argc,

+  char *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Main

+

+Arguments:

+

+  command line parameters

+

+Returns:

+

+  EFI_SUCCESS    Section header successfully generated and section concatenated.

+  EFI_ABORTED    Could not generate the section

+  EFI_OUT_OF_RESOURCES  No resource to complete the operation.

+

+--*/

+{

+  INTN                      Index;

+  INTN                      VersionNumber;

+  UINTN                     SectionType;

+  UINTN                     SectionSubType;

+  BOOLEAN                   InputFileRequired;

+  BOOLEAN                   SubTypeRequired;

+  FILE                      *InFile;

+  FILE                      *OutFile;

+  INTN                      InputFileNum;

+

+  char                      **InputFileName;

+  char                      *OutputFileName;

+  char                      AuxString[500] = { 0 };

+

+  char                      *ParamSectionType;

+  char                      *ParamSectionSubType;

+  char                      *ParamLength;

+  char                      *ParamVersion;

+  char                      *ParamDigitalSignature;

+

+  EFI_STATUS                Status;

+  EFI_COMMON_SECTION_HEADER CommonSect;

+

+  InputFileName         = NULL;

+  OutputFileName        = PARAMETER_NOT_SPECIFIED;

+  ParamSectionType      = PARAMETER_NOT_SPECIFIED;

+  ParamSectionSubType   = PARAMETER_NOT_SPECIFIED;

+  ParamLength           = PARAMETER_NOT_SPECIFIED;

+  ParamVersion          = PARAMETER_NOT_SPECIFIED;

+  ParamDigitalSignature = PARAMETER_NOT_SPECIFIED;

+  Status                = EFI_SUCCESS;

+

+  VersionNumber         = 0;

+  SectionType           = 0;

+  SectionSubType        = 0;

+  InputFileRequired     = TRUE;

+  SubTypeRequired       = FALSE;

+  InFile                = NULL;

+  OutFile               = NULL;

+  InputFileNum          = 0;

+  Status                = EFI_SUCCESS;

+

+  SetUtilityName (UTILITY_NAME);

+  if (argc == 1) {

+    PrintUsageMessage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Parse command line

+  //

+  Index = 1;

+  while (Index < argc) {

+    if (strcmpi (argv[Index], "-i") == 0) {

+      //

+      // Input File found

+      //

+      Index++;

+      InputFileName = (char **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (char *));

+      if (InputFileName == NULL) {

+        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)));

+      InputFileName[InputFileNum] = argv[Index];

+      InputFileNum++;

+      Index++;

+      //

+      // Parse subsequent parameters until another switch is encountered

+      //

+      while ((Index < argc) && (argv[Index][0] != '-')) {

+        if ((InputFileNum % MAXIMUM_INPUT_FILE_NUM) == 0) {

+          //

+          // InputFileName buffer too small, need to realloc

+          //

+          InputFileName = (char **) realloc (

+                                      InputFileName,

+                                      (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (char *)

+                                      );

+          if (InputFileName == NULL) {

+            Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");

+            return EFI_OUT_OF_RESOURCES;

+          }

+

+          memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)));

+        }

+

+        InputFileName[InputFileNum] = argv[Index];

+        InputFileNum++;

+        Index++;

+      }

+

+    }

+

+    if (strcmpi (argv[Index], "-o") == 0) {

+      //

+      // Output file found

+      //

+      Index++;

+      OutputFileName = argv[Index];

+    } else if (strcmpi (argv[Index], "-s") == 0) {

+      //

+      // Section Type found

+      //

+      Index++;

+      ParamSectionType = argv[Index];

+    } else if (strcmpi (argv[Index], "-t") == 0) {

+      //

+      // Compression or Authentication type

+      //

+      Index++;

+      ParamSectionSubType = argv[Index];

+    } else if (strcmpi (argv[Index], "-l") == 0) {

+      //

+      // Length

+      //

+      Index++;

+      ParamLength = argv[Index];

+    } else if (strcmpi (argv[Index], "-v") == 0) {

+      //

+      // VersionNumber

+      //

+      Index++;

+      ParamVersion = argv[Index];

+    } else if (strcmpi (argv[Index], "-a") == 0) {

+      //

+      // Aux string

+      //

+      Index++;

+      //

+      // Note, the MSVC C-Start parses out and consolidates quoted strings from the command

+      // line.  Quote characters are stripped.  If this tool is ported to other environments

+      // this will need to be taken into account

+      //

+      strncpy (AuxString, argv[Index], 499);

+    } else if (strcmpi (argv[Index], "-d") == 0) {

+      //

+      // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1)

+      //

+      Index++;

+      ParamDigitalSignature = argv[Index];

+    } else if (strcmpi (argv[Index], "-?") == 0) {

+      PrintUsageMessage ();

+      return STATUS_ERROR;

+    } else {

+      Error (NULL, 0, 0, argv[Index], "unknown option");

+      return GetUtilityStatus ();

+    }

+

+    Index++;

+  }

+  //

+  // At this point, all command line parameters are verified as not being totally

+  // bogus.  Next verify the command line parameters are complete and make

+  // sense...

+  //

+  if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {

+    SectionType     = EFI_SECTION_COMPRESSION;

+    SubTypeRequired = TRUE;

+    if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {

+      SectionSubType = EFI_NOT_COMPRESSED;

+    } else if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {

+      SectionSubType = EFI_STANDARD_COMPRESSION;

+    } else {

+      Error (NULL, 0, 0, ParamSectionSubType, "unknown compression type");

+      PrintUsageMessage ();

+      return GetUtilityStatus ();

+    }

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {

+    SectionType     = EFI_SECTION_GUID_DEFINED;

+    SubTypeRequired = TRUE;

+    if (stricmp (ParamSectionSubType, GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED]) == 0) {

+      SectionSubType = EFI_SECTION_CRC32_GUID_DEFINED;

+    } else {

+      Error (NULL, 0, 0, ParamSectionSubType, "unknown GUID defined section type", ParamSectionSubType);

+      PrintUsageMessage ();

+      return GetUtilityStatus ();

+    }

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PE32]) == 0) {

+    SectionType = EFI_SECTION_PE32;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PIC]) == 0) {

+    SectionType = EFI_SECTION_PIC;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_TE]) == 0) {

+    SectionType = EFI_SECTION_TE;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {

+    SectionType = EFI_SECTION_DXE_DEPEX;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_VERSION]) == 0) {

+    SectionType       = EFI_SECTION_VERSION;

+    InputFileRequired = FALSE;

+    Index             = sscanf (ParamVersion, "%d", &VersionNumber);

+    if (Index != 1 || VersionNumber < 0 || VersionNumber > 65565) {

+      Error (NULL, 0, 0, ParamVersion, "illegal version number");

+      PrintUsageMessage ();

+      return GetUtilityStatus ();

+    }

+

+    if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) {

+      AuxString[0] = 0;

+    }

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {

+    SectionType       = EFI_SECTION_USER_INTERFACE;

+    InputFileRequired = FALSE;

+    if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) {

+      Error (NULL, 0, 0, "user interface string not specified", NULL);

+      PrintUsageMessage ();

+      return GetUtilityStatus ();

+    }

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {

+    SectionType = EFI_SECTION_COMPATIBILITY16;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {

+    SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {

+    SectionType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_RAW]) == 0) {

+    SectionType = EFI_SECTION_RAW;

+  } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {

+    SectionType = EFI_SECTION_PEI_DEPEX;

+  } else {

+    Error (NULL, 0, 0, ParamSectionType, "unknown section type");

+    PrintUsageMessage ();

+    return GetUtilityStatus ();

+  }

+  //

+  // Open output file

+  //

+  OutFile = fopen (OutputFileName, "wb");

+  if (OutFile == NULL) {

+    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");

+    if (InFile != NULL) {

+      fclose (InFile);

+    }

+

+    return GetUtilityStatus ();

+  }

+  //

+  // At this point, we've fully validated the command line, and opened appropriate

+  // files, so let's go and do what we've been asked to do...

+  //

+  //

+  // Within this switch, build and write out the section header including any

+  // section type specific pieces.  If there's an input file, it's tacked on later

+  //

+  switch (SectionType) {

+  case EFI_SECTION_COMPRESSION:

+    Status = GenSectionCompressionSection (

+              InputFileName,

+              InputFileNum,

+              SectionType,

+              SectionSubType,

+              OutFile

+              );

+    break;

+

+  case EFI_SECTION_GUID_DEFINED:

+    Status = GenSectionGuidDefinedSection (

+              InputFileName,

+              InputFileNum,

+              SectionType,

+              SectionSubType,

+              OutFile

+              );

+    break;

+

+  case EFI_SECTION_VERSION:

+    CommonSect.Type = (EFI_SECTION_TYPE) SectionType;

+

+    Index           = sizeof (CommonSect);

+    //

+    // 2 characters for the build number

+    //

+    Index += 2;

+    //

+    // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.

+    //

+    Index += (strlen (AuxString) * 2) + 2;

+    memcpy (&CommonSect.Size, &Index, 3);

+    fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);

+    fwrite (&VersionNumber, 2, 1, OutFile);

+    Ascii2UnicodeWriteString (AuxString, OutFile, FALSE);

+    break;

+

+  case EFI_SECTION_USER_INTERFACE:

+    CommonSect.Type = (EFI_SECTION_TYPE) SectionType;

+    Index           = sizeof (CommonSect);

+    //

+    // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null.

+    //

+    Index += (strlen (AuxString) * 2) + 2;

+    memcpy (&CommonSect.Size, &Index, 3);

+    fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);

+    Ascii2UnicodeWriteString (AuxString, OutFile, FALSE);

+    break;

+

+  default:

+    //

+    // All other section types are caught by default (they're all the same)

+    //

+    Status = GenSectionCommonLeafSection (

+              InputFileName,

+              InputFileNum,

+              SectionType,

+              OutFile

+              );

+    break;

+  }

+

+  if (InputFileName != NULL) {

+    free (InputFileName);

+  }

+

+  fclose (OutFile);

+  //

+  // If we had errors, then delete the output file

+  //

+  if (GetUtilityStatus () == STATUS_ERROR) {

+    remove (OutputFileName);

+  }

+

+  return GetUtilityStatus ();

+}

diff --git a/edk2/Tools/Source/TianoTools/GenSection/GenSection.h b/edk2/Tools/Source/TianoTools/GenSection/GenSection.h
new file mode 100644
index 0000000..847b3eb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenSection/GenSection.h
@@ -0,0 +1,43 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GenSection.h 

+

+Abstract:

+

+  Header file for GenSection.

+

+--*/

+

+//

+// Module Coded to Tiano Coding Conventions

+//

+#ifndef _EFI_GEN_SECTION_H

+#define _EFI_GEN_SECTION_H

+

+//

+// External Files Referenced

+//

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include "FirmwareVolumeImageFormat.h"

+

+typedef struct {

+  EFI_GUID_DEFINED_SECTION  GuidSectionHeader;

+  UINT32                    CRC32Checksum;

+} CRC32_SECTION_HEADER;

+

+#define EFI_SECTION_CRC32_GUID_DEFINED  0

+#define CRC32_SECTION_HEADER_SIZE       (sizeof (CRC32_SECTION_HEADER))

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GenSection/build.xml b/edk2/Tools/Source/TianoTools/GenSection/build.xml
new file mode 100644
index 0000000..34be36e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenSection/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenSection Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenSection"/>

+  <property name="FileSet" value="GenSection.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GenTEImage/GenTEImage.c b/edk2/Tools/Source/TianoTools/GenTEImage/GenTEImage.c
new file mode 100644
index 0000000..8313f96
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenTEImage/GenTEImage.c
@@ -0,0 +1,921 @@
+/*++

+

+Copyright (c) 1999-2004 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+Module Name:

+

+  GenTEImage.c

+  

+Abstract:

+

+  Utility program to shrink a PE32 image down by replacing

+  the DOS, PE, and optional headers with a minimal header.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include <CommonLib.h>

+

+#include "EfiImage.h" // for PE32 structure definitions

+#include "EfiUtilityMsgs.h"

+

+//

+// Version of this utility

+//

+#define UTILITY_NAME    "GenTEImage"

+#define UTILITY_VERSION "v0.11"

+

+//

+// Define the max length of a filename

+//

+#define MAX_PATH                  256

+#define DEFAULT_OUTPUT_EXTENSION  ".te"

+

+//

+// Use this to track our command-line options and globals

+//

+struct {

+  INT8  OutFileName[MAX_PATH];

+  INT8  InFileName[MAX_PATH];

+  INT8  Verbose;

+  INT8  Dump;

+} mOptions;

+

+//

+// Use these to convert from machine type value to a named type

+//

+typedef struct {

+  UINT16  Value;

+  INT8    *Name;

+} STRING_LOOKUP;

+

+static STRING_LOOKUP  mMachineTypes[] = {

+  EFI_IMAGE_MACHINE_IA32,

+  "IA32",

+  EFI_IMAGE_MACHINE_IA64,

+  "IA64",

+  EFI_IMAGE_MACHINE_EBC,

+  "EBC",

+  0,

+  NULL

+};

+

+static STRING_LOOKUP  mSubsystemTypes[] = {

+  EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,

+  "EFI application",

+  EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,

+  "EFI boot service driver",

+  EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,

+  "EFI runtime driver",

+  0,

+  NULL

+};

+//

+//  Function prototypes

+//

+static

+void

+Usage (

+  VOID

+  );

+

+static

+STATUS

+ParseCommandLine (

+  int       Argc,

+  char      *Argv[]

+  );

+

+static

+STATUS

+CheckPE32File (

+  INT8      *FileName,

+  FILE      *Fptr,

+  UINT16    *MachineType,

+  UINT16    *SubSystem

+  );

+

+static

+STATUS

+ProcessFile (

+  INT8      *InFileName,

+  INT8      *OutFileName

+  );

+

+static

+void

+DumpImage (

+  INT8      *FileName

+  );

+

+static

+INT8                  *

+GetMachineTypeStr (

+  UINT16    MachineType

+  );

+

+static

+INT8                  *

+GetSubsystemTypeStr (

+  UINT16  SubsystemType

+  );

+

+main (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+  

+

+Arguments:

+

+  Argc            - standard C main() argument count

+

+  Argv            - standard C main() argument list

+

+Returns:

+

+  0             success

+  non-zero      otherwise

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+{

+  INT8    *Ext;

+  UINT32  Status;

+

+  SetUtilityName (UTILITY_NAME);

+  //

+  // Parse the command line arguments

+  //

+  if (ParseCommandLine (Argc, Argv)) {

+    return STATUS_ERROR;

+  }

+  //

+  // If dumping an image, then do that and quit

+  //

+  if (mOptions.Dump) {

+    DumpImage (mOptions.InFileName);

+    goto Finish;

+  }

+  //

+  // Determine the output filename. Either what they specified on

+  // the command line, or the first input filename with a different extension.

+  //

+  if (!mOptions.OutFileName[0]) {

+    strcpy (mOptions.OutFileName, mOptions.InFileName);

+    //

+    // Find the last . on the line and replace the filename extension with

+    // the default

+    //

+    for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;

+         (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');

+         Ext--

+        )

+      ;

+    //

+    // If dot here, then insert extension here, otherwise append

+    //

+    if (*Ext != '.') {

+      Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);

+    }

+

+    strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);

+  }

+  //

+  // Make sure we don't have the same filename for input and output files

+  //

+  if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {

+    Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");

+    goto Finish;

+  }

+  //

+  // Process the file

+  //

+  ProcessFile (mOptions.InFileName, mOptions.OutFileName);

+Finish:

+  Status = GetUtilityStatus ();

+  return Status;

+}

+

+static

+STATUS

+ProcessFile (

+  INT8      *InFileName,

+  INT8      *OutFileName

+  )

+/*++

+

+Routine Description:

+  

+  Process a PE32 EFI file.

+

+Arguments:

+  

+  InFileName      - the file name pointer to the input file

+  OutFileName     - the file name pointer to the output file

+

+Returns:

+

+  STATUS_SUCCESS  - the process has been finished successfully

+  STATUS_ERROR    - error occured during the processing

+

+--*/

+{

+  STATUS                      Status;

+  FILE                        *InFptr;

+  FILE                        *OutFptr;

+  UINT16                      MachineType;

+  UINT16                      SubSystem;

+  EFI_TE_IMAGE_HEADER         TEImageHeader;

+  UINT32                      PESigOffset;

+  EFI_IMAGE_FILE_HEADER       FileHeader;

+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;

+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64;

+  UINT32                      BytesStripped;

+  UINT32                      FileSize;

+  UINT8                       *Buffer;

+  long                        SaveFilePosition;

+

+  InFptr  = NULL;

+  OutFptr = NULL;

+  Buffer  = NULL;

+  Status  = STATUS_ERROR;

+

+  //

+  // Try to open the input file

+  //

+  if ((InFptr = fopen (InFileName, "rb")) == NULL) {

+    Error (NULL, 0, 0, InFileName, "failed to open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Double-check the file to make sure it's what we expect it to be

+  //

+  if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {

+    goto Finish;

+  }

+  //

+  // Initialize our new header

+  //

+  memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER));

+

+  //

+  // Seek to the end to get the file size

+  //

+  fseek (InFptr, 0, SEEK_END);

+  FileSize = ftell (InFptr);

+  fseek (InFptr, 0, SEEK_SET);

+

+  //

+  // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit

+  // offset (from the start of the file) to the PE signature, which always

+  // follows the MSDOS stub. The PE signature is immediately followed by the

+  // COFF file header.

+  //

+  //

+  if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {

+    Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);

+    goto Finish;

+  }

+

+  if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");

+    goto Finish;

+  }

+

+  if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {

+    Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");

+    goto Finish;

+  }

+  //

+  // We should now be at the COFF file header. Read it in and verify it's

+  // of an image type we support.

+  //

+  if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read file header from image");

+    goto Finish;

+  }

+

+  if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) {

+    Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);

+    goto Finish;

+  }

+  //

+  // Calculate the total number of bytes we're going to strip off. The '4' is for the

+  // PE signature PE\0\0. Then sanity check the size.

+  //

+  BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader;

+  if (BytesStripped >= FileSize) {

+    Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size");

+    goto Finish;

+  }

+

+  if (BytesStripped &~0xFFFF) {

+    Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL);

+    goto Finish;

+  }

+

+  TEImageHeader.StrippedSize = (UINT16) BytesStripped;

+

+  //

+  // Read in the optional header. Assume PE32, and if not, then re-read as PE32+

+  //

+  SaveFilePosition = ftell (InFptr);

+  if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");

+    goto Finish;

+  }

+

+  if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+    //

+    // Fill in our new header with required data directory entries

+    //

+    TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint;

+    //

+    // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);

+    //

+    // We're going to pack the subsystem into 1 byte. Make sure it fits

+    //

+    if (OptionalHeader32.Subsystem &~0xFF) {

+      Error (

+        NULL,

+        0,

+        0,

+        InFileName,

+        NULL,

+        "image subsystem 0x%X cannot be packed into 1 byte",

+        (UINT32) OptionalHeader32.Subsystem

+        );

+      goto Finish;

+    }

+

+    TEImageHeader.Subsystem   = (UINT8) OptionalHeader32.Subsystem;

+    TEImageHeader.BaseOfCode  = OptionalHeader32.BaseOfCode;

+    TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));

+    if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

+    }

+

+    if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;

+    }

+  } else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {

+    //

+    // Rewind and re-read the optional header

+    //

+    fseek (InFptr, SaveFilePosition, SEEK_SET);

+    if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {

+      Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file");

+      goto Finish;

+    }

+

+    TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint;

+    //

+    // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);

+    //

+    // We're going to pack the subsystem into 1 byte. Make sure it fits

+    //

+    if (OptionalHeader64.Subsystem &~0xFF) {

+      Error (

+        NULL,

+        0,

+        0,

+        InFileName,

+        NULL,

+        "image subsystem 0x%X cannot be packed into 1 byte",

+        (UINT32) OptionalHeader64.Subsystem

+        );

+      goto Finish;

+    }

+

+    TEImageHeader.Subsystem   = (UINT8) OptionalHeader64.Subsystem;

+    TEImageHeader.BaseOfCode  = OptionalHeader32.BaseOfCode;

+    TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));

+    if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

+    }

+

+    if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;

+      TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;

+    }

+  } else {

+    Error (

+      NULL,

+      0,

+      0,

+      InFileName,

+      "unsupported magic number 0x%X found in optional header",

+      (UINT32) OptionalHeader32.Magic

+      );

+    goto Finish;

+  }

+  //

+  // Fill in the remainder of our new image header

+  //

+  TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE;

+  TEImageHeader.Machine   = FileHeader.Machine;

+  //

+  // We're going to pack the number of sections into a single byte. Make sure it fits.

+  //

+  if (FileHeader.NumberOfSections &~0xFF) {

+    Error (

+      NULL,

+      0,

+      0,

+      InFileName,

+      NULL,

+      "image's number of sections 0x%X cannot be packed into 1 byte",

+      (UINT32) FileHeader.NumberOfSections

+      );

+    goto Finish;

+  }

+

+  TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections;

+

+  //

+  // Now open our output file

+  //

+  if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");

+    goto Finish;

+  }

+  //

+  // Write the TE header

+  //

+  if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write image header to output file", NULL);

+    goto Finish;

+  }

+  //

+  // Position into the input file, read the part we're not stripping, and

+  // write it out.

+  //

+  fseek (InFptr, BytesStripped, SEEK_SET);

+  Buffer = (UINT8 *) malloc (FileSize - BytesStripped);

+  if (Buffer == NULL) {

+    Error (NULL, 0, 0, "application error", "failed to allocate memory");

+    goto Finish;

+  }

+

+  if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) {

+    Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file");

+    goto Finish;

+  }

+

+  if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) {

+    Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file");

+    goto Finish;

+  }

+

+  Status = STATUS_SUCCESS;

+

+Finish:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+  //

+  // Close the output file. If there was an error, delete the output file so

+  // that a subsequent build will rebuild it.

+  //

+  if (OutFptr != NULL) {

+    fclose (OutFptr);

+    if (GetUtilityStatus () == STATUS_ERROR) {

+      remove (OutFileName);

+    }

+  }

+

+  //

+  // Free up our buffer

+  //

+  if (Buffer != NULL) {

+    free (Buffer);

+  }

+

+  return Status;

+}

+

+static

+STATUS

+CheckPE32File (

+  INT8      *FileName,

+  FILE      *Fptr,

+  UINT16    *MachineType,

+  UINT16    *SubSystem

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FileName    - GC_TODO: add argument description

+  Fptr        - GC_TODO: add argument description

+  MachineType - GC_TODO: add argument description

+  SubSystem   - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  /*++

+

+Routine Description:

+  

+  Given a file pointer to a supposed PE32 image file, verify that it is indeed a

+  PE32 image file, and then return the machine type in the supplied pointer.

+

+Arguments:

+

+  Fptr          File pointer to the already-opened PE32 file

+  MachineType   Location to stuff the machine type of the PE32 file. This is needed

+                because the image may be Itanium-based, IA32, or EBC.

+

+Returns:

+

+  0             success

+  non-zero      otherwise

+

+--*/

+  EFI_IMAGE_DOS_HEADER      DosHeader;

+  EFI_IMAGE_FILE_HEADER     FileHdr;

+  EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;

+  UINT32                    PESig;

+  STATUS                    Status;

+

+  Status = STATUS_ERROR;

+  //

+  // Position to the start of the file

+  //

+  fseek (Fptr, 0, SEEK_SET);

+  //

+  // Read the DOS header

+  //

+  if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");

+    goto Finish;

+  }

+  //

+  // Check the magic number (0x5A4D)

+  //

+  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");

+    goto Finish;

+  }

+  //

+  // Position into the file and check the PE signature

+  //

+  fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);

+  if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");

+    goto Finish;

+  }

+  //

+  // Check the PE signature in the header "PE\0\0"

+  //

+  if (PESig != EFI_IMAGE_NT_SIGNATURE) {

+    Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");

+    goto Finish;

+  }

+  //

+  // Read the file header

+  //

+  if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");

+    goto Finish;

+  }

+  //

+  // Read the optional header so we can get the subsystem

+  //

+  if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");

+    goto Finish;

+  }

+

+  *SubSystem = OptionalHdr.Subsystem;

+  if (mOptions.Verbose) {

+    fprintf (stdout, "  Got subsystem = 0x%X from image\n", (int) *SubSystem);

+  }

+  //

+  // Good to go

+  //

+  Status = STATUS_SUCCESS;

+Finish:

+  fseek (Fptr, 0, SEEK_SET);

+  return Status;

+}

+

+static

+int

+ParseCommandLine (

+  int         Argc,

+  char        *Argv[]

+  )

+/*++

+

+Routine Description:

+  

+  Given the Argc/Argv program arguments, and a pointer to an options structure,

+  parse the command-line options and check their validity.

+

+

+Arguments:

+

+  Argc            - standard C main() argument count

+  Argv            - standard C main() argument list

+

+Returns:

+

+  STATUS_SUCCESS    success

+  non-zero          otherwise

+

+--*/

+// GC_TODO:    ] - add argument and description to function comment

+{

+  //

+  // Clear out the options

+  //

+  memset ((char *) &mOptions, 0, sizeof (mOptions));

+  //

+  // Skip over the program name

+  //

+  Argc--;

+  Argv++;

+  //

+  // If no arguments, assume they want usage info

+  //

+  if (Argc == 0) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Process until no more arguments

+  //

+  while ((Argc > 0) && ((Argv[0][0] == '-') || (Argv[0][0] == '/'))) {

+    //

+    // To simplify string comparisons, replace slashes with dashes

+    //

+    Argv[0][0] = '-';

+    if (stricmp (Argv[0], "-o") == 0) {

+      //

+      // Output filename specified with -o

+      // Make sure there's another parameter

+      //

+      if (Argc > 1) {

+        strcpy (mOptions.OutFileName, Argv[1]);

+      } else {

+        Error (NULL, 0, 0, Argv[0], "missing output file name with option");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      Argv++;

+      Argc--;

+    } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {

+      //

+      // Help option

+      //

+      Usage ();

+      return STATUS_ERROR;

+    } else if (stricmp (Argv[0], "-v") == 0) {

+      //

+      // -v for verbose

+      //

+      mOptions.Verbose = 1;

+    } else if (stricmp (Argv[0], "-dump") == 0) {

+      //

+      // -dump for dumping an image

+      //

+      mOptions.Dump = 1;

+    } else {

+      Error (NULL, 0, 0, Argv[0], "unrecognized option");

+      Usage ();

+      return STATUS_ERROR;

+    }

+    //

+    // Next argument

+    //

+    Argv++;

+    Argc--;

+  }

+  //

+  // Better be one more arg for input file name

+  //

+  if (Argc == 0) {

+    Error (NULL, 0, 0, "input file name required", NULL);

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  if (Argc != 1) {

+    Error (NULL, 0, 0, Argv[1], "extra arguments on command line");

+    return STATUS_ERROR;

+  }

+

+  strcpy (mOptions.InFileName, Argv[0]);

+  return STATUS_SUCCESS;

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+  

+  Print usage information for this utility.

+

+Arguments:

+

+  None.

+

+Returns:

+

+  Nothing.

+

+--*/

+{

+  int               Index;

+  static const char *Msg[] = {

+    UTILITY_NAME " version "UTILITY_VERSION " - TE image utility",

+    "  Generate a TE image from an EFI PE32 image",

+    "  Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName",

+    "                [-e|-b] [FileName(s)]",

+    "    where:",

+    "      -v             - for verbose output",

+    "      -dump          - to dump the input file to a text file",

+    "      -h -?          - for this help information",

+    "      -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,

+    "      InFileName     - name of the input PE32 file",

+    "",

+    NULL

+  };

+  for (Index = 0; Msg[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Msg[Index]);

+  }

+}

+

+static

+VOID

+DumpImage (

+  INT8    *FileName

+  )

+/*++

+

+Routine Description:

+  

+  Dump a specified image information

+

+Arguments:

+  

+  FileName - File name pointer to the image to dump

+

+Returns:

+

+  Nothing.

+

+--*/

+{

+  FILE                *InFptr;

+  EFI_TE_IMAGE_HEADER TEImageHeader;

+  INT8                *NamePtr;

+

+  //

+  // Open the input file

+  //

+  InFptr  = NULL;

+

+  if ((InFptr = fopen (FileName, "rb")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open input file for reading");

+    return ;

+  }

+

+  if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) {

+    Error (NULL, 0, 0, FileName, "failed to read image header from input file");

+    goto Finish;

+  }

+

+  if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {

+    Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)");

+    goto Finish;

+  }

+  //

+  // Dump the header

+  //

+  fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER));

+  fprintf (stdout, "  Signature:          0x%04X (TE)\n", (UINT32) TEImageHeader.Signature);

+  NamePtr = GetMachineTypeStr (TEImageHeader.Machine);

+  fprintf (stdout, "  Machine:            0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr);

+  NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem);

+  fprintf (stdout, "  Subsystem:          0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr);

+  fprintf (stdout, "  Number of sections  0x%02X\n", (UINT32) TEImageHeader.NumberOfSections);

+  fprintf (stdout, "  Stripped size:      0x%04X\n", (UINT32) TEImageHeader.StrippedSize);

+  fprintf (stdout, "  Entry point:        0x%08X\n", TEImageHeader.AddressOfEntryPoint);

+  fprintf (stdout, "  Base of code:       0x%08X\n", TEImageHeader.BaseOfCode);

+  fprintf (stdout, "  Data directories:\n");

+  fprintf (

+    stdout,

+    "    %8X [%8X] RVA [size] of Base Relocation Directory\n",

+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,

+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size

+    );

+  fprintf (

+    stdout,

+    "    %8X [%8X] RVA [size] of Debug Directory\n",

+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,

+    TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size

+    );

+

+Finish:

+  if (InFptr != NULL) {

+    fclose (InFptr);

+  }

+}

+

+static

+INT8 *

+GetMachineTypeStr (

+  UINT16    MachineType

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  MachineType - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  int Index;

+

+  for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {

+    if (mMachineTypes[Index].Value == MachineType) {

+      return mMachineTypes[Index].Name;

+    }

+  }

+

+  return "unknown";

+}

+

+static

+INT8 *

+GetSubsystemTypeStr (

+  UINT16  SubsystemType

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  SubsystemType - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  int Index;

+

+  for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {

+    if (mSubsystemTypes[Index].Value == SubsystemType) {

+      return mSubsystemTypes[Index].Name;

+    }

+  }

+

+  return "unknown";

+}

diff --git a/edk2/Tools/Source/TianoTools/GenTEImage/Makefile b/edk2/Tools/Source/TianoTools/GenTEImage/Makefile
new file mode 100644
index 0000000..f731b6d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenTEImage/Makefile
@@ -0,0 +1,68 @@
+#/*++

+#  

+#  Copyright (c) 2002 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#  

+#  Module Name:

+#  

+#    makefile

+#    

+#  Abstract:

+#  

+#    makefile for building the GenTEImage utility.

+#  

+#--*/

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+#

+# Define the toolchain which is used to set build options and toolchain paths

+#

+TOOLCHAIN = TOOLCHAIN_MSVC

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = GenTEImage

+TARGET_SRC_DIR      = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj 

+

+LIBS      = $(TIANO_TOOLS_OUTPUT)\Common.lib

+

+INC_DEPS  = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h

+          

+#

+# Build the EXE by compiling the source files, then linking the resultant

+# object files together.

+#

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@

+

+$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/GenTEImage/build.xml b/edk2/Tools/Source/TianoTools/GenTEImage/build.xml
new file mode 100644
index 0000000..c0e2c82
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GenTEImage/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GenTEImage Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GenTEImage"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/CommonUtils.h b/edk2/Tools/Source/TianoTools/GuidChk/CommonUtils.h
new file mode 100644
index 0000000..f7a331e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/CommonUtils.h
@@ -0,0 +1,57 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  CommonUtils.h

+  

+Abstract:

+

+  Common utility defines and structure definitions.

+  

+--*/

+

+#ifndef _COMMON_UTILS_H_

+#define _COMMON_UTILS_H_

+

+//

+// Basic types

+//

+typedef unsigned char UINT8;

+typedef char INT8;

+typedef unsigned short UINT16;

+typedef unsigned int UINT32;

+

+typedef UINT8 BOOLEAN;

+typedef UINT32 STATUS;

+

+#define TRUE            1

+#define FALSE           0

+

+#define STATUS_SUCCESS  0

+#define STATUS_WARNING  1

+#define STATUS_ERROR    2

+

+//

+// Linked list of strings

+//

+typedef struct _STRING_LIST {

+  struct _STRING_LIST *Next;

+  char                *Str;

+} STRING_LIST;

+

+int

+CreateGuidList (

+  INT8    *OutFileName

+  )

+;

+

+#endif // #ifndef _COMMON_UTILS_H_

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/FileSearch.c b/edk2/Tools/Source/TianoTools/GuidChk/FileSearch.c
new file mode 100644
index 0000000..8b5b58f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/FileSearch.c
@@ -0,0 +1,285 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  FileSearch.c

+  

+Abstract:

+

+  Module used to support file searches on the system.

+  

+--*/

+

+#include <stdio.h>

+

+#include "CommonUtils.h"

+#include "FileSearch.h"

+#include "UtilsMsgs.h"

+

+//

+// Internal file search flag for sanity checks

+//

+#define FILE_SEARCH_STARTED 0x8000

+#define FILE_SEARCH_INITED  0x4000

+

+static

+BOOLEAN

+FileSearchMeetsCriteria (

+  FILE_SEARCH_DATA    *FSData

+  );

+

+/*****************************************************************************/

+STATUS

+FileSearchInit (

+  FILE_SEARCH_DATA    *FSData

+  )

+{

+  memset ((char *) FSData, 0, sizeof (FILE_SEARCH_DATA));

+  FSData->Handle          = INVALID_HANDLE_VALUE;

+  FSData->FileSearchFlags = FILE_SEARCH_INITED;

+  FSData->FileName[0]     = 0;

+  return STATUS_SUCCESS;

+}

+

+STATUS

+FileSearchStart (

+  FILE_SEARCH_DATA    *FSData,

+  char                *FileMask,

+  UINT32              SearchFlags

+  )

+{

+  BOOLEAN Done;

+

+  //

+  // Save their flags, and set a flag to indicate that they called this

+  // start function so we can perform extended checking in the other

+  // routines we have in this module.

+  //

+  FSData->FileSearchFlags |= (SearchFlags | FILE_SEARCH_STARTED);

+  FSData->FileName[0] = 0;

+

+  //

+  // Begin the search

+  //

+  FSData->Handle = FindFirstFile (FileMask, &(FSData->FindData));

+  if (FSData->Handle == INVALID_HANDLE_VALUE) {

+    return STATUS_ERROR;

+  }

+  //

+  // Keep looping through until we find a file meeting the caller's

+  // criteria per the search flags

+  //

+  Done = FALSE;

+  while (!Done) {

+    //

+    // If we're done (we found a match) copy the file name found and return

+    //

+    Done = FileSearchMeetsCriteria (FSData);

+    if (Done) {

+      return STATUS_SUCCESS;

+    }

+    //

+    // Go on to next file

+    //

+    if (!FindNextFile (FSData->Handle, &(FSData->FindData))) {

+      return STATUS_NOT_FOUND;

+    }

+  }

+  //

+  // Not reached

+  //

+  return STATUS_NOT_FOUND;

+}

+

+//

+// Find the next file meeting their criteria and return it.

+//

+STATUS

+FileSearchFindNext (

+  FILE_SEARCH_DATA    *FSData

+  )

+{

+  BOOLEAN Done;

+

+  Done = FALSE;

+  while (!Done) {

+    if (!FindNextFile (FSData->Handle, &(FSData->FindData))) {

+      return STATUS_NOT_FOUND;

+    }

+    //

+    // See if it matches their criteria

+    //

+    Done = FileSearchMeetsCriteria (FSData);

+    if (Done) {

+      return STATUS_SUCCESS;

+    }

+  }

+  //

+  // Not reached

+  //

+  return STATUS_NOT_FOUND;

+}

+//

+// Perform any cleanup necessary to close down a search

+//

+STATUS

+FileSearchDestroy (

+  FILE_SEARCH_DATA    *FSData

+  )

+{

+  if (FSData->Handle != INVALID_HANDLE_VALUE) {

+    FindClose (FSData->Handle);

+    FSData->Handle = INVALID_HANDLE_VALUE;

+  }

+

+  FSData->FileName[0]     = 0;

+  FSData->FileSearchFlags = 0;

+  return STATUS_SUCCESS;

+}

+

+static

+BOOLEAN

+FileSearchMeetsCriteria (

+  FILE_SEARCH_DATA    *FSData

+  )

+{

+  BOOLEAN     Status;

+  STRING_LIST *StrList;

+  UINT32      ExtLen;

+  UINT32      FileNameLen;

+

+  Status = FALSE;

+

+  //

+  // First clear the flag indicating this is neither a file or a

+  // directory.

+  //

+  FSData->FileFlags &= ~(FILE_SEARCH_DIR | FILE_SEARCH_FILE);

+

+  //

+  // We found a file. See if it matches the user's search criteria. First

+  // check for this being a directory, and they want directories, and

+  // it's not "." and it's not ".."

+  //

+  if ((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&

+      (FSData->FileSearchFlags & FILE_SEARCH_DIR) &&

+      (strcmp (FSData->FindData.cFileName, ".")) &&

+      (strcmp (FSData->FindData.cFileName, ".."))

+      ) {

+    //

+    // Assume we'll make it past this check

+    //

+    Status = TRUE;

+    //

+    // If they have a list of exclude directories, then check for those

+    //

+    StrList = FSData->ExcludeDirs;

+    while (StrList != NULL) {

+      if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) {

+        Status = FALSE;

+        break;

+      }

+

+      StrList = StrList->Next;

+    }

+    //

+    // If we didn't fail due to excluded directories, then set the dir flag

+    //

+    if (Status) {

+      FSData->FileFlags |= FILE_SEARCH_DIR;

+    }

+    //

+    // Else check for a file, and they want files....

+    //

+  } else if (((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) &&

+           (FSData->FileSearchFlags & FILE_SEARCH_FILE)

+          ) {

+    //

+    // See if it's in our list of excluded files

+    //

+    Status  = TRUE;

+    StrList = FSData->ExcludeFiles;

+    while (StrList != NULL) {

+      if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) {

+        Status = FALSE;

+        break;

+      }

+

+      StrList = StrList->Next;

+    }

+

+    if (Status) {

+      //

+      // See if it's in our list of excluded file extensions

+      //

+      FileNameLen = strlen (FSData->FindData.cFileName);

+      StrList     = FSData->ExcludeExtensions;

+      while (StrList != NULL) {

+        ExtLen = strlen (StrList->Str);

+        if (stricmp (

+              FSData->FindData.cFileName + FileNameLen - ExtLen,

+              StrList->Str

+              ) == 0) {

+          Status = FALSE;

+          break;

+        }

+

+        StrList = StrList->Next;

+      }

+    }

+

+    if (Status) {

+      FSData->FileFlags |= FILE_SEARCH_FILE;

+    }

+  }

+  //

+  // If it's a match, copy the filename into another field of the structure

+  // for portability.

+  //

+  if (Status) {

+    strcpy (FSData->FileName, FSData->FindData.cFileName);

+  }

+

+  return Status;

+}

+//

+// Exclude a list of subdirectories.

+//

+STATUS

+FileSearchExcludeDirs (

+  FILE_SEARCH_DATA    *FSData,

+  STRING_LIST         *StrList

+  )

+{

+  FSData->ExcludeDirs = StrList;

+  return STATUS_SUCCESS;

+}

+

+STATUS

+FileSearchExcludeFiles (

+  FILE_SEARCH_DATA    *FSData,

+  STRING_LIST         *StrList

+  )

+{

+  FSData->ExcludeFiles = StrList;

+  return STATUS_SUCCESS;

+}

+

+STATUS

+FileSearchExcludeExtensions (

+  FILE_SEARCH_DATA    *FSData,

+  STRING_LIST         *StrList

+  )

+{

+  FSData->ExcludeExtensions = StrList;

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/FileSearch.h b/edk2/Tools/Source/TianoTools/GuidChk/FileSearch.h
new file mode 100644
index 0000000..bc40265
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/FileSearch.h
@@ -0,0 +1,108 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  FileSearch.h

+  

+Abstract:

+

+  Header file to support file searching.

+  

+--*/

+

+#ifndef _FILE_SEARCH_H_

+#define _FILE_SEARCH_H_

+

+//

+// Since the file searching routines are OS dependent, put the

+// necessary include paths in this header file so that the non-OS-dependent

+// files don't need to include these windows-specific header files.

+//

+#include <stdio.h>

+#include <string.h>

+#include <ctype.h>

+#include <direct.h>

+#include <windows.h>

+

+//

+// Return codes of some of the file search routines

+//

+#define STATUS_NOT_FOUND  0x1000

+

+//

+// Flags for what to search for. Also used in the FileFlags return field.

+//

+#define FILE_SEARCH_DIR   0x0001

+#define FILE_SEARCH_FILE  0x0002

+

+//

+// Here's our class definition

+//

+typedef struct {

+  HANDLE          Handle;

+  WIN32_FIND_DATA FindData;

+  UINT32          FileSearchFlags;    // DIRS, FILES, etc

+  UINT32          FileFlags;

+  INT8            FileName[MAX_PATH]; // for portability

+  STRING_LIST     *ExcludeDirs;

+  STRING_LIST     *ExcludeFiles;

+  STRING_LIST     *ExcludeExtensions;

+} FILE_SEARCH_DATA;

+

+//

+// Here's our member functions

+//

+STATUS

+FileSearchInit (

+  FILE_SEARCH_DATA    *FSData

+  )

+;

+

+STATUS

+FileSearchDestroy (

+  FILE_SEARCH_DATA    *FSData

+  )

+;

+

+STATUS

+FileSearchStart (

+  FILE_SEARCH_DATA    *FSData,

+  char                *FileMask,

+  UINT32              SearchFlags

+  )

+;

+

+STATUS

+FileSearchFindNext (

+  FILE_SEARCH_DATA    *FSData

+  )

+;

+

+STATUS

+FileSearchExcludeDirs (

+  FILE_SEARCH_DATA    *FSData,

+  STRING_LIST         *StrList

+  )

+;

+STATUS

+FileSearchExcludeExtensions (

+  FILE_SEARCH_DATA    *FSData,

+  STRING_LIST         *StrList

+  )

+;

+STATUS

+FileSearchExcludeFiles (

+  FILE_SEARCH_DATA    *FSData,

+  STRING_LIST         *StrList

+  )

+;

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/GuidChk.c b/edk2/Tools/Source/TianoTools/GuidChk/GuidChk.c
new file mode 100644
index 0000000..de88405
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/GuidChk.c
@@ -0,0 +1,2348 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  GuidChk.c 

+  

+Abstract:

+

+  Parse files in a directory and subdirectories to find all guid definitions.

+  Then check them against each other to make sure there are no duplicates.

+  

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+#include "CommonUtils.h"

+#include "FileSearch.h"

+#include "UtilsMsgs.h"

+

+#define MAX_LINE_LEN  180 // we concatenate two lines sometimes

+// Define a structure that correlates filename extensions to an enumerated

+// type.

+//

+typedef struct {

+  INT8  *Extension;

+  INT8  ExtensionCode;

+} FILE_TYPE_TABLE_ENTRY;

+

+#define FILE_EXTENSION_UNKNOWN  0

+#define FILE_EXTENSION_C        1

+#define FILE_EXTENSION_H        2

+#define FILE_EXTENSION_IA32_ASM 3

+#define FILE_EXTENSION_IA32_INC 4

+#define FILE_EXTENSION_IA64_ASM 5

+#define FILE_EXTENSION_IA64_INC 6

+#define FILE_EXTENSION_PKG      7

+#define FILE_EXTENSION_INF      8

+

+FILE_TYPE_TABLE_ENTRY FileTypeTable[] = {

+  ".c",

+  FILE_EXTENSION_C,

+  ".h",

+  FILE_EXTENSION_H,

+  ".inc",

+  FILE_EXTENSION_IA32_INC,

+  ".asm",

+  FILE_EXTENSION_IA32_ASM,

+  ".s",

+  FILE_EXTENSION_IA64_ASM,

+  ".pkg",

+  FILE_EXTENSION_PKG,

+  ".inf",

+  FILE_EXTENSION_INF,

+  ".i",

+  FILE_EXTENSION_IA64_INC,

+  NULL,

+  0

+};

+

+typedef struct EFI_GUID {

+  UINT32  Data1;

+  UINT16  Data2;

+  UINT16  Data3;

+  UINT8   Data4[8];

+} EFI_GUID;

+

+typedef struct {

+  INT8  Data[4];

+  INT8  DataLen;

+} EFI_SIGNATURE;

+

+typedef struct _GUID_RECORD {

+  struct _GUID_RECORD *Next;

+  BOOLEAN             Reported;

+  INT8                *FileName;

+  INT8                *SymName;

+  EFI_GUID            Guid;

+} GUID_RECORD;

+

+typedef struct _SIGNATURE_RECORD {

+  struct _SIGNATURE_RECORD  *Next;

+  BOOLEAN                   Reported;

+  INT8                      *FileName;

+  EFI_SIGNATURE             Signature;

+} SIGNATURE_RECORD;

+

+//

+// Utility options

+//

+typedef struct {

+  INT8        DatabaseOutputFileName[MAX_PATH]; // with -b option

+  STRING_LIST *ExcludeDirs;                     // list of directory names not to process

+  STRING_LIST *ExcludeSubDirs;                  // list of directory names to not process subdirectories (build)

+  STRING_LIST *ExcludeFiles;                    // list of files to exclude (make.inf)

+  STRING_LIST *ExcludeExtensions;               // list of filename extensions to exclude (.inf, .pkg)

+  BOOLEAN     Verbose;

+  BOOLEAN     PrintFound;

+  BOOLEAN     CheckGuids;

+  BOOLEAN     CheckSignatures;

+  BOOLEAN     GuidXReference;

+} OPTIONS;

+

+static

+STATUS

+ProcessArgs (

+  int     Argc,

+  char    *Argv[]

+  );

+

+static

+VOID

+Usage (

+  VOID

+  );

+

+static

+STATUS

+ProcessDirectory (

+  INT8        *Path,

+  INT8        *DirectoryName

+  );

+

+static

+STATUS

+ProcessFile (

+  INT8                *DirectoryName,

+  INT8                *FileName

+  );

+

+static

+UINT32

+GetFileExtension (

+  INT8        *FileName

+  );

+

+static

+UINT32

+SkipWhiteSpace (

+  INT8    *Str

+  );

+

+static

+UINT32

+ValidSymbolName (

+  INT8    *Name

+  );

+

+static

+STATUS

+ProcessCFileGuids (

+  INT8    *FileName

+  );

+

+static

+STATUS

+AddSignature (

+  INT8      *FileName,

+  INT8      *StrDef,

+  UINT32    SigSize

+  );

+

+static

+STATUS

+ProcessCFileSigs (

+  INT8    *FileName

+  );

+

+static

+STATUS

+ProcessINFFileGuids (

+  INT8    *FileName

+  );

+

+static

+STATUS

+ProcessPkgFileGuids (

+  INT8    *FileName

+  );

+

+static

+STATUS

+ProcessIA32FileGuids (

+  INT8    *FileName

+  );

+

+static

+STATUS

+ProcessIA64FileGuids (

+  INT8    *FileName

+  );

+

+static

+BOOLEAN

+IsIA64GuidLine (

+  INT8      *Line,

+  UINT32    *GuidHigh,

+  UINT32    *GuidLow,

+  BOOLEAN   *Low,

+  INT8      *SymName

+  );

+

+static

+STATUS

+AddGuid11 (

+  INT8      *FileName,

+  UINT32    *Data,

+  INT8      *SymName

+  );

+

+static

+STATUS

+AddPkgGuid (

+  INT8      *FileName,

+  UINT32    *Data,

+  UINT64    *Data64

+  );

+

+static

+STATUS

+AddGuid16 (

+  INT8      *FileName,

+  UINT32    *Data

+  );

+

+static

+STATUS

+AddGuid64x2 (

+  INT8      *FileName,

+  UINT32    DataHH,                             // Upper 32-bits of upper 64 bits of guid

+  UINT32    DataHL,                             // Lower 32-bits of upper 64 bits

+  UINT32    DataLH,

+  UINT32    DataLL

+  );

+

+static

+VOID

+FreeGuids (

+  VOID

+  );

+

+static

+VOID

+FreeSigs (

+  VOID

+  );

+

+static

+STATUS

+CheckDuplicates (

+  VOID

+  );

+

+//

+// static

+// VOID

+// ReportGuid (

+//  INT8        *FileName,

+//  GUID_RECORD *FileRecord

+//  );

+//

+static

+VOID

+FreeOptions (

+  VOID

+  );

+

+static

+BOOLEAN

+CheckGuidData (

+  UINT32    *GuidData,

+  UINT32    DataCount

+  );

+

+/**************************** GLOBALS ****************************************/

+static GUID_RECORD      *gGuidList      = NULL;

+static SIGNATURE_RECORD *gSignatureList = NULL;

+static OPTIONS          gOptions;

+

+/*****************************************************************************/

+int

+main (

+  int     Argc,

+  char    *Argv[]

+  )

+{

+  INT8    *Cwd;

+  STATUS  Status;

+

+  SetUtilityName ("GuidChk");

+  //

+  // Get the current working directory and then process the command line

+  // arguments.

+  //

+  Cwd     = _getcwd (NULL, 0);

+  Status  = ProcessArgs (Argc, Argv);

+  if (Status != STATUS_SUCCESS) {

+    return Status;

+  }

+

+  if (gOptions.CheckGuids || gOptions.CheckSignatures) {

+    Status = ProcessDirectory (Cwd, NULL);

+    if (Status == STATUS_SUCCESS) {

+      //

+      // Check for duplicates

+      //

+      Status = CheckDuplicates ();

+    }

+  }

+

+  if (gOptions.DatabaseOutputFileName[0] != 0) {

+    CreateGuidList (gOptions.DatabaseOutputFileName);

+  }

+  //

+  // Free up the memory

+  //

+  free (Cwd);

+  FreeGuids ();

+  FreeSigs ();

+  FreeOptions ();

+  return GetUtilityStatus ();

+}

+

+static

+STATUS

+ProcessArgs (

+  int     Argc,

+  char    *Argv[]

+  )

+{

+  STRING_LIST *StrList;

+

+  memset ((char *) &gOptions, 0, sizeof (gOptions));

+  //

+  // skip over program name

+  //

+  Argc--;

+  Argv++;

+

+  if (Argc == 0) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  while (Argc > 0) {

+    //

+    // Look for options

+    //

+    if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) {

+      switch (Argv[0][1]) {

+      //

+      // Help option

+      //

+      case 'h':

+      case 'H':

+      case '?':

+        Usage ();

+        return STATUS_ERROR;

+        break;

+

+      //

+      // Check guids option

+      //

+      case 'g':

+      case 'G':

+        gOptions.CheckGuids = TRUE;

+        break;

+

+      //

+      // Check signatures option

+      //

+      case 's':

+      case 'S':

+        gOptions.CheckSignatures = TRUE;

+        break;

+

+      //

+      // Print guids found option

+      //

+      case 'p':

+      case 'P':

+        gOptions.PrintFound = TRUE;

+        break;

+

+      //

+      // Exclude files option

+      //

+      case 'f':

+      case 'F':

+        //

+        // Check for another arg

+        //

+        if (Argc < 2) {

+          Error (NULL, 0, 0, Argv[0], "missing argument with option");

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        StrList = malloc (sizeof (STRING_LIST));

+        if (StrList == NULL) {

+          Error (NULL, 0, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        memset ((char *) StrList, 0, sizeof (STRING_LIST));

+        StrList->Str          = Argv[1];

+        StrList->Next         = gOptions.ExcludeFiles;

+        gOptions.ExcludeFiles = StrList;

+        Argc--;

+        Argv++;

+        break;

+

+      //

+      // Exclude directories option

+      //

+      case 'd':

+      case 'D':

+        //

+        // Check for another arg

+        //

+        if (Argc < 2) {

+          Error (NULL, 0, 0, Argv[0], "missing argument with option");

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        StrList = malloc (sizeof (STRING_LIST));

+        if (StrList == NULL) {

+          Error (NULL, 0, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        memset ((char *) StrList, 0, sizeof (STRING_LIST));

+        StrList->Str          = Argv[1];

+        StrList->Next         = gOptions.ExcludeDirs;

+        gOptions.ExcludeDirs  = StrList;

+        Argc--;

+        Argv++;

+        break;

+

+      //

+      // -u  exclude all subdirectories of a given directory option

+      //

+      case 'u':

+      case 'U':

+        //

+        // Check for another arg

+        //

+        if (Argc < 2) {

+          Error (NULL, 0, 0, Argv[0], "missing argument with option");

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        StrList = malloc (sizeof (STRING_LIST));

+        if (StrList == NULL) {

+          Error (NULL, 0, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        memset ((char *) StrList, 0, sizeof (STRING_LIST));

+        StrList->Str            = Argv[1];

+        StrList->Next           = gOptions.ExcludeSubDirs;

+        gOptions.ExcludeSubDirs = StrList;

+        Argc--;

+        Argv++;

+        break;

+

+      //

+      // -e  exclude by filename extension option

+      //

+      case 'e':

+      case 'E':

+        //

+        // Check for another arg

+        //

+        if (Argc < 2) {

+          Error (NULL, 0, 0, Argv[0], "missing argument with option");

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        StrList = malloc (sizeof (STRING_LIST));

+        if (StrList == NULL) {

+          Error (NULL, 0, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        memset ((char *) StrList, 0, sizeof (STRING_LIST));

+        //

+        // Let them put a * in front of the filename extension

+        //

+        StrList->Str = Argv[1];

+        if (StrList->Str[0] == '*') {

+          StrList->Str++;

+        }

+

+        StrList->Next               = gOptions.ExcludeExtensions;

+        gOptions.ExcludeExtensions  = StrList;

+        Argc--;

+        Argv++;

+        break;

+

+      //

+      // Print guid with matching symbol name for guid definitions found

+      //

+      case 'x':

+      case 'X':

+        gOptions.GuidXReference = 1;

+        break;

+

+      //

+      // -b   Print the internal database list to a file

+      //

+      case 'b':

+      case 'B':

+        //

+        // Check for one more arg

+        //

+        if (Argc < 2) {

+          Error (NULL, 0, 0, Argv[0], "must specify file name with option");

+          Usage ();

+          return STATUS_ERROR;

+        }

+

+        strcpy (gOptions.DatabaseOutputFileName, Argv[1]);

+        Argc--;

+        Argv++;

+        break;

+

+      default:

+        Error (NULL, 0, 0, Argv[0], "invalid option");

+        Usage ();

+        return STATUS_ERROR;

+      }

+    } else {

+      break;

+    }

+    //

+    // Next arg

+    //

+    Argc--;

+    Argv++;

+  }

+

+  if (Argc > 0) {

+    Error (NULL, 0, 0, Argv[0], "invalid argument");

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Have to check signatures, GUIDs, or dump the GUID database.

+  //

+  if ((!gOptions.CheckGuids) && (!gOptions.CheckSignatures) && (gOptions.DatabaseOutputFileName[0] == 0)) {

+    Error (NULL, 0, 0, "nothing to do", "must specify -g, -s, and/or -b");

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+//

+// Print usage instructions

+//

+static

+VOID

+Usage (

+  VOID

+  )

+{

+  int   Index;

+  char  *Str[] = {

+    "GuidChk - scan files for duplicate GUID or signature definitions",

+    "",

+    "Usage:  GuidChk {options}\n",

+    "  Options: ",

+    "    -d dirname     exclude searching of a directory",

+    "    -f filename    exclude searching of a file",

+    "    -e extension   exclude searching of files by extension",

+    "    -p             print all GUIDS found",

+    "    -g             check for duplicate guids",

+    "    -s             check for duplicate signatures",

+    "    -x             print guid+defined symbol name",

+    "    -b outfile     write internal GUID+basename list to outfile",

+    "    -u dirname     exclude searching all subdirectories of a directory",

+    "    -h -?          print this help text",

+    " ",

+    "   Example: GuidChk -g -u build -d fv -f make.inf -e .pkg",

+    "",

+    NULL

+  };

+  for (Index = 0; Str[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Str[Index]);

+  }

+}

+//

+// Process an entire directory by name

+//

+static

+STATUS

+ProcessDirectory (

+  INT8          *Path,

+  INT8          *DirectoryName

+  )

+{

+  FILE_SEARCH_DATA  FSData;

+  char              *FileMask;

+  BOOLEAN           Done;

+  UINT32            Len;

+  BOOLEAN           NoSubdirs;

+  STRING_LIST       *SLPtr;

+

+  //

+  // Root directory may be null

+  //

+  if (DirectoryName != NULL) {

+    //

+    // printf ("Processing directory: %s\n", DirectoryName);

+    //

+  }

+  //

+  // Initialize our file searching

+  //

+  FileSearchInit (&FSData);

+

+  //

+  // Exclude some directories, files, and extensions

+  //

+  FileSearchExcludeDirs (&FSData, gOptions.ExcludeDirs);

+  FileSearchExcludeExtensions (&FSData, gOptions.ExcludeExtensions);

+  FileSearchExcludeFiles (&FSData, gOptions.ExcludeFiles);

+  //

+  // See if this directory is in the list of directories that they

+  // don't want to process subdirectories of

+  //

+  NoSubdirs = FALSE;

+  if (DirectoryName != NULL) {

+    for (SLPtr = gOptions.ExcludeSubDirs; SLPtr != NULL; SLPtr = SLPtr->Next) {

+      if (stricmp (SLPtr->Str, DirectoryName) == 0) {

+        //

+        // printf ("not processing subdirectories of %s\n", DirectoryName);

+        //

+        NoSubdirs = TRUE;

+        break;

+      }

+    }

+  }

+  //

+  // Create a filemask of files to search for. We'll append "\*.*" on the

+  // end, so allocate some extra bytes.

+  //

+  Len = strlen (Path) + 10;

+  if (DirectoryName != NULL) {

+    Len += strlen (DirectoryName);

+  }

+

+  FileMask = malloc (Len);

+  if (FileMask == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // Now put it all together

+  //

+  strcpy (FileMask, Path);

+  if ((DirectoryName != NULL) && (strlen (DirectoryName) > 0)) {

+    strcat (FileMask, "\\");

+    strcat (FileMask, DirectoryName);

+  }

+

+  strcat (FileMask, "\\*.*");

+

+  //

+  // Start file searching for files and directories

+  //

+  FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR);

+

+  //

+  // Now hack the "\*.*" off the end of the filemask so we can use it to pass

+  // the full directory path on recursive calls to process directories.

+  //

+  FileMask[strlen (FileMask) - 4] = 0;

+

+  //

+  // Loop until no more files

+  //

+  Done = FALSE;

+  while (!Done) {

+    //

+    // printf ("Found %s...", FSData.FileName);

+    //

+    if (FSData.FileFlags & FILE_SEARCH_DIR) {

+      //

+      // printf ("directory\n");

+      //

+      if (!NoSubdirs) {

+        ProcessDirectory (FileMask, FSData.FileName);

+      }

+    } else if (FSData.FileFlags & FILE_SEARCH_FILE) {

+      //

+      // printf ("file\n");

+      //

+      ProcessFile (FileMask, FSData.FileName);

+    } else {

+      //

+      // printf ("unknown\n");

+      //

+    }

+

+    if (FileSearchFindNext (&FSData) != STATUS_SUCCESS) {

+      Done = TRUE;

+    }

+  }

+  //

+  // Free up allocated memory

+  //

+  free (FileMask);

+

+  //

+  // Free up our file searching

+  //

+  FileSearchDestroy (&FSData);

+

+  return STATUS_SUCCESS;

+}

+//

+// Process a single file.

+//

+static

+STATUS

+ProcessFile (

+  INT8                *DirectoryName,

+  INT8                *FileName

+  )

+{

+  STATUS  Status;

+  UINT32  FileExtension;

+  INT8    FullFileName[MAX_PATH];

+

+  Status = STATUS_SUCCESS;

+

+  sprintf (FullFileName, "%s\\%s", DirectoryName, FileName);

+  //

+  // printf ("Found file: %s\n", FullFileName);

+  //

+  FileExtension = GetFileExtension (FileName);

+

+  //

+  // Process these for GUID checks

+  //

+  if (gOptions.CheckGuids) {

+    switch (FileExtension) {

+    case FILE_EXTENSION_C:

+    case FILE_EXTENSION_H:

+      Status = ProcessCFileGuids (FullFileName);

+      break;

+

+    case FILE_EXTENSION_PKG:

+      Status = ProcessPkgFileGuids (FullFileName);

+      break;

+

+    case FILE_EXTENSION_IA32_INC:

+    case FILE_EXTENSION_IA32_ASM:

+      Status = ProcessIA32FileGuids (FullFileName);

+      break;

+

+    case FILE_EXTENSION_INF:

+      Status = ProcessINFFileGuids (FullFileName);

+      break;

+

+    case FILE_EXTENSION_IA64_INC:

+    case FILE_EXTENSION_IA64_ASM:

+      Status = ProcessIA64FileGuids (FullFileName);

+      break;

+

+    default:

+      //

+      // No errors anyway

+      //

+      Status = STATUS_SUCCESS;

+      break;

+    }

+  }

+

+  if (gOptions.CheckSignatures) {

+    switch (FileExtension) {

+    case FILE_EXTENSION_C:

+    case FILE_EXTENSION_H:

+      Status = ProcessCFileSigs (FullFileName);

+      break;

+

+    default:

+      //

+      // No errors anyway

+      //

+      Status = STATUS_SUCCESS;

+      break;

+    }

+  }

+

+  return Status;

+}

+//

+// Return a code indicating the file name extension.

+//

+static

+UINT32

+GetFileExtension (

+  INT8        *FileName

+  )

+{

+  INT8  *Extension;

+  int   Index;

+

+  //

+  // Look back for a filename extension

+  //

+  for (Extension = FileName + strlen (FileName) - 1; Extension >= FileName; Extension--) {

+    if (*Extension == '.') {

+      for (Index = 0; FileTypeTable[Index].Extension != NULL; Index++) {

+        if (stricmp (FileTypeTable[Index].Extension, Extension) == 0) {

+          return FileTypeTable[Index].ExtensionCode;

+        }

+      }

+    }

+  }

+

+  return FILE_TYPE_UNKNOWN;

+}

+//

+// Process a .pkg file.

+//

+// Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7

+//

+static

+STATUS

+ProcessPkgFileGuids (

+  INT8    *FileName

+  )

+{

+  FILE    *Fptr;

+  INT8    Line[MAX_LINE_LEN * 2];

+  INT8    *Cptr;

+  INT8    *Cptr2;

+  UINT32  GuidScan[11];

+  UINT64  Guid64;

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read lines from the file until done

+  //

+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+    Cptr = Line;

+    Cptr += SkipWhiteSpace (Line);

+    if (strncmp (Cptr, "FFS_FILEGUID", 12) == 0) {

+      Cptr += 12;

+      Cptr += SkipWhiteSpace (Cptr);

+      if (*Cptr == '=') {

+        Cptr++;

+        Cptr += SkipWhiteSpace (Cptr + 1);

+        //

+        // Blank out dashes on the line.

+        //

+        for (Cptr2 = Cptr; *Cptr2; Cptr2++) {

+          if (*Cptr2 == '-') {

+            *Cptr2 = ' ';

+          }

+        }

+

+        if (sscanf (

+              Cptr,

+              "%X %X %X %X %I64X",

+              &GuidScan[0],

+              &GuidScan[1],

+              &GuidScan[2],

+              &GuidScan[3],

+              &Guid64

+              ) == 5) {

+          AddPkgGuid (FileName, GuidScan, &Guid64);

+        } else {

+          DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");

+        }

+      }

+    }

+  }

+

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+//

+// Process an IA32 assembly file.

+//

+// Look for:

+// FIND_FD_GUID_VAL equ  01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h

+// PEI_GUID_FileNameGuid_Gmch815  equ  081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h

+//

+static

+STATUS

+ProcessIA32FileGuids (

+  INT8    *FileName

+  )

+{

+  FILE    *Fptr;

+  INT8    Line[MAX_LINE_LEN];

+  INT8    *Cptr;

+  INT8    CSave;

+  INT8    *CSavePtr;

+  UINT32  Len;

+  UINT32  GuidData[16];

+  UINT32  Index;

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read lines from the file until done

+  //

+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+    Cptr = Line;

+    Cptr += SkipWhiteSpace (Line);

+    //

+    // Look for xxxGUIDyyy equ 01h, 02h, 03h, ...

+    //

+    Len = ValidSymbolName (Cptr);

+    if (Len) {

+      //

+      // Terminate the line after the symbol name, then look for "guid" in

+      // the name.

+      //

+      CSavePtr  = Cptr + Len;

+      CSave     = *CSavePtr;

+      *CSavePtr = 0;

+      while (*Cptr) {

+        if (strnicmp (Cptr, "guid", 4) == 0) {

+          break;

+        }

+

+        Cptr++;

+      }

+      //

+      // If we found the string "guid", continue

+      //

+      if (*Cptr) {

+        //

+        // Restore the character on the line where we null-terminated the symbol

+        //

+        *CSavePtr = CSave;

+        Cptr      = CSavePtr;

+        Len       = SkipWhiteSpace (Cptr);

+        //

+        // Had to be some white space

+        //

+        if (Len) {

+          Cptr += Len;

+          //

+          // now look for "equ"

+          //

+          if (strnicmp (Cptr, "equ", 3) == 0) {

+            Cptr += 3;

+            Cptr += SkipWhiteSpace (Cptr);

+            //

+            // Now scan all the data

+            //

+            for (Index = 0; Index < 16; Index++) {

+              if (sscanf (Cptr, "%X", &GuidData[Index]) != 1) {

+                break;

+              }

+              //

+              // Skip to next

+              //

+              while (isxdigit (*Cptr)) {

+                Cptr++;

+              }

+

+              if ((*Cptr != 'h') && (*Cptr != 'H')) {

+                break;

+              } else {

+                Cptr++;

+                while (*Cptr && (isspace (*Cptr) || (*Cptr == ','))) {

+                  Cptr++;

+                }

+              }

+            }

+            //

+            // Now see which form we had

+            //

+            if (Index == 16) {

+              AddGuid16 (FileName, GuidData);

+            } else if (Index == 11) {

+              AddGuid11 (FileName, GuidData, NULL);

+            }

+          }

+        }

+      }

+    }

+  }

+

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+//

+// Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list

+// of guids.

+//

+static

+STATUS

+AddGuid16 (

+  INT8      *FileName,

+  UINT32    *Data

+  )

+{

+  GUID_RECORD *NewRec;

+  int         Index;

+

+  //

+  // Sanity check the data

+  //

+  if (!CheckGuidData (Data, 16)) {

+    return STATUS_ERROR;

+  }

+  //

+  // Allocate memory for a new guid structure

+  //

+  NewRec = malloc (sizeof (GUID_RECORD));

+  if (NewRec == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) NewRec, 0, sizeof (GUID_RECORD));

+  NewRec->FileName = malloc (strlen (FileName) + 1);

+  if (NewRec->FileName == NULL) {

+    free (NewRec);

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  strcpy (NewRec->FileName, FileName);

+  NewRec->Guid.Data1  = (UINT32) (Data[0] | (Data[1] << 8) | (Data[2] << 16) | (Data[3] << 24));

+  NewRec->Guid.Data2  = (UINT16) (Data[4] | (Data[5] << 8));

+  NewRec->Guid.Data3  = (UINT16) (Data[6] | (Data[7] << 8));

+  for (Index = 0; Index < 8; Index++) {

+    NewRec->Guid.Data4[Index] = (UINT8) Data[Index + 8];

+  }

+  //

+  // Add it to the list

+  //

+  NewRec->Next  = gGuidList;

+  gGuidList     = NewRec;

+

+  //

+  // Report it

+  // ReportGuid (FileName, NewRec);

+  //

+  return STATUS_SUCCESS;

+}

+//

+// Add a GUID defined as GuidLow: 0x1122334455667788

+//                       GuidHi:  0x99AABBCCDDEEFF00

+//

+// These are equivalent:

+// { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 }

+//    and:

+// Low: 00FFEEDDCCBBAA99

+// Hi:  7788556611223344

+//

+static

+STATUS

+AddGuid64x2 (

+  INT8      *FileName,

+  UINT32    DataHH, // Upper 32-bits of upper 64 bits of guid

+  UINT32    DataHL, // Lower 32-bits of upper 64 bits

+  UINT32    DataLH,

+  UINT32    DataLL

+  )

+{

+  GUID_RECORD *NewRec;

+  int         Index;

+

+  //

+  // Allocate memory for a new guid structure

+  //

+  NewRec = malloc (sizeof (GUID_RECORD));

+  if (NewRec == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) NewRec, 0, sizeof (GUID_RECORD));

+  NewRec->FileName = malloc (strlen (FileName) + 1);

+  if (NewRec->FileName == NULL) {

+    free (NewRec);

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  strcpy (NewRec->FileName, FileName);

+  NewRec->Guid.Data1  = DataHL;

+  NewRec->Guid.Data2  = (UINT16) DataHH;

+  NewRec->Guid.Data3  = (UINT16) (DataHH >> 16);

+  for (Index = 0; Index < 4; Index++) {

+    NewRec->Guid.Data4[Index] = (UINT8) DataLL;

+    DataLL >>= 8;

+  }

+

+  for (Index = 0; Index < 4; Index++) {

+    NewRec->Guid.Data4[Index + 4] = (UINT8) DataLH;

+    DataLH >>= 8;

+  }

+  //

+  // Add it to the list

+  //

+  NewRec->Next  = gGuidList;

+  gGuidList     = NewRec;

+

+  //

+  // Report it

+  // ReportGuid (FileName, NewRec);

+  //

+  return STATUS_SUCCESS;

+}

+//

+// Process INF files. Look for:

+// FILE_GUID            = 240612B6-A063-11d4-9A3A-0090273FC14D

+//

+static

+STATUS

+ProcessINFFileGuids (

+  INT8    *FileName

+  )

+{

+  FILE    *Fptr;

+  INT8    Line[MAX_LINE_LEN * 2];

+  INT8    *Cptr;

+  INT8    *Cptr2;

+  UINT32  GuidScan[11];

+  UINT64  Guid64;

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read lines from the file until done

+  //

+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+    Cptr = Line;

+    Cptr += SkipWhiteSpace (Line);

+    if (strncmp (Cptr, "FILE_GUID", 9) == 0) {

+      Cptr += 9;

+      Cptr += SkipWhiteSpace (Cptr);

+      if (*Cptr == '=') {

+        Cptr++;

+        Cptr += SkipWhiteSpace (Cptr + 1);

+        //

+        // Blank out dashes on the line.

+        //

+        for (Cptr2 = Cptr; *Cptr2; Cptr2++) {

+          if (*Cptr2 == '-') {

+            *Cptr2 = ' ';

+          }

+        }

+

+        if (sscanf (

+              Cptr,

+              "%X %X %X %X %I64X",

+              &GuidScan[0],

+              &GuidScan[1],

+              &GuidScan[2],

+              &GuidScan[3],

+              &Guid64

+              ) == 5) {

+          AddPkgGuid (FileName, GuidScan, &Guid64);

+        } else {

+          DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");

+        }

+      }

+    }

+  }

+

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+//

+// Parse ('g','m','a','p','a','b','c','d')

+//

+static

+STATUS

+AddSignature (

+  INT8      *FileName,

+  INT8      *StrDef,

+  UINT32    SigSize

+  )

+{

+  SIGNATURE_RECORD  *NewRec;

+  INT8              *Cptr;

+  UINT32            Index;

+  BOOLEAN           Fail;

+

+  //

+  // Allocate memory for the new record

+  //

+  Fail    = FALSE;

+  NewRec  = malloc (sizeof (SIGNATURE_RECORD));

+  if (NewRec == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // Allocate memory to save the file name

+  //

+  NewRec->FileName = malloc (strlen (FileName) + 1);

+  if (NewRec->FileName == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    free (NewRec);

+    return STATUS_ERROR;

+  }

+  //

+  // Fill in the fields

+  //

+  strcpy (NewRec->FileName, FileName);

+  NewRec->Signature.DataLen = (UINT8) SigSize;

+  //

+  // Skip to open parenthesis

+  //

+  Cptr = StrDef;

+  Cptr += SkipWhiteSpace (Cptr);

+  if (*Cptr != '(') {

+    Fail = TRUE;

+    goto Done;

+  }

+

+  Cptr++;

+  //

+  // Skip to first ' and start processing

+  //

+  while (*Cptr && (*Cptr != '\'')) {

+    Cptr++;

+  }

+

+  for (Index = 0; Index < SigSize; Index++) {

+    if (*Cptr == '\'') {

+      Cptr++;

+      NewRec->Signature.Data[Index] = (INT8) *Cptr;

+      //

+      // Skip to closing quote

+      //

+      Cptr++;

+      if (*Cptr != '\'') {

+        Fail = TRUE;

+        break;

+      }

+      //

+      // Skip over closing quote, go to next one

+      //

+      Cptr++;

+      while (*Cptr && (*Cptr != '\'')) {

+        Cptr++;

+      }

+    } else {

+      Fail = TRUE;

+      DebugMsg (NULL, 0, 0, StrDef, "failed to parse signature");

+      break;

+    }

+  }

+

+Done:

+  if (Fail) {

+    free (NewRec->FileName);

+    free (NewRec);

+    return STATUS_ERROR;

+  }

+

+  NewRec->Next    = gSignatureList;

+  gSignatureList  = NewRec;

+  return STATUS_SUCCESS;

+}

+//

+// Look for:

+// #define POOL_HEAD_SIGNATURE         EFI_SIGNATURE_16('p','h')

+// #define GCD_MEMORY_MAP_SIGNATURE    EFI_SIGNATURE_32('g','m','a','p')

+// #define GCD_MEMORY_MAP_SIGNATURE    EFI_SIGNATURE_64('g','m','a','p','a','b','c','d')

+//

+static

+STATUS

+ProcessCFileSigs (

+  INT8    *FileName

+  )

+{

+  FILE    *Fptr;

+  INT8    Line[MAX_LINE_LEN * 2];

+  INT8    *Cptr;

+  UINT32  Len;

+  UINT32  LineLen;

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read lines from the file until done

+  //

+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+    Cptr = Line;

+    Cptr += SkipWhiteSpace (Line);

+    //

+    // look for #define xxxGUIDxxx value

+    //

+    if (*Cptr == '#') {

+      Cptr++;

+      Cptr += SkipWhiteSpace (Cptr);

+      //

+      // Look for "define"

+      //

+      if (!strncmp (Cptr, "define", 6)) {

+        Cptr += 6;

+        //

+        // Better be whitespace

+        //

+        Len = SkipWhiteSpace (Cptr);

+        if (Len) {

+          Cptr += Len;

+          //

+          // See if it's a valid symbol name

+          //

+          Len = ValidSymbolName (Cptr);

+          if (Len) {

+            //

+            // It is a valid symbol name. See if there's a line continuation,

+            // and if so, read one more line.

+            // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx"

+            //

+            LineLen = strlen (Line);

+            if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {

+              fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr);

+            } else if (Line[LineLen - 1] == '\\') {

+              fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr);

+            }

+

+            Cptr += Len;

+            Cptr += SkipWhiteSpace (Cptr);

+            if (strncmp (Cptr, "EFI_SIGNATURE_16", 16) == 0) {

+              AddSignature (FileName, Cptr + 16, 2);

+            } else if (strncmp (Cptr, "EFI_SIGNATURE_32", 16) == 0) {

+              AddSignature (FileName, Cptr + 16, 4);

+            } else if (strncmp (Cptr, "EFI_SIGNATURE_64", 16) == 0) {

+              AddSignature (FileName, Cptr + 16, 8);

+            }

+          }

+        }

+      }

+    }

+  }

+

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+//

+// look for #define xxxGUIDyyy { 0x...}

+// xxx EFI_GUID  GuidName = { 0x... };

+//

+static

+STATUS

+ProcessCFileGuids (

+  INT8    *FileName

+  )

+{

+  FILE    *Fptr;

+  INT8    Line[MAX_LINE_LEN * 2];

+  INT8    *Cptr;

+  INT8    CSave;

+  INT8    *CSavePtr;

+  INT8    *TempCptr;

+  INT8    *SymName;

+  UINT32  Len;

+  UINT32  LineLen;

+  UINT32  GuidScan[11];

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read lines from the file until done

+  //

+  while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+    Cptr = Line;

+    Cptr += SkipWhiteSpace (Line);

+    //

+    // look for #define xxxGUIDxxx value

+    //

+    if (*Cptr == '#') {

+      Cptr++;

+      Cptr += SkipWhiteSpace (Cptr);

+      //

+      // Look for "define"

+      //

+      if (!strncmp (Cptr, "define", 6)) {

+        Cptr += 6;

+        //

+        // Better be whitespace

+        //

+        Len = SkipWhiteSpace (Cptr);

+        if (Len) {

+          Cptr += Len;

+          //

+          // See if it's a valid symbol name

+          //

+          Len = ValidSymbolName (Cptr);

+          if (Len) {

+            //

+            // It is a valid symbol name. See if there's a line continuation,

+            // and if so, read one more line.

+            // Then truncate after the symbol name, look for the string "GUID",

+            // and continue.

+            //

+            SymName = Cptr;

+            LineLen = strlen (Line);

+            if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {

+              fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr);

+            } else if (Line[LineLen - 1] == '\\') {

+              fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr);

+            }

+

+            CSavePtr  = Cptr + Len;

+            CSave     = *CSavePtr;

+            *CSavePtr = 0;

+            while (*Cptr) {

+              if (strncmp (Cptr, "GUID", 4) == 0) {

+                break;

+              }

+

+              Cptr++;

+            }

+            //

+            // If we didn't run out of string, then we found the GUID string.

+            // Now look for { 0x....... }

+            //

+            if (*Cptr) {

+              Cptr      = CSavePtr;

+              *CSavePtr = CSave;

+              Cptr += SkipWhiteSpace (Cptr);

+              if (*Cptr == '{') {

+                *Cptr = 0;

+                Cptr++;

+                //

+                // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }

+                // If you have one suffixed with "L", then it doesn't work. So hack off 'L' characters

+                // in the string.

+                //

+                for (TempCptr = Cptr; *TempCptr; TempCptr++) {

+                  if (*TempCptr == 'L') {

+                    if (*(TempCptr + 1) == ',') {

+                      *TempCptr       = ',';

+                      *(TempCptr + 1) = ' ';

+                    }

+                  }

+                }

+

+                if (sscanf (

+                      Cptr,

+                      "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X",

+                      &GuidScan[0],

+                      &GuidScan[1],

+                      &GuidScan[2],

+                      &GuidScan[3],

+                      &GuidScan[4],

+                      &GuidScan[5],

+                      &GuidScan[6],

+                      &GuidScan[7],

+                      &GuidScan[8],

+                      &GuidScan[9],

+                      &GuidScan[10]

+                      ) == 11) {

+                  AddGuid11 (FileName, GuidScan, SymName);

+                }

+              }

+            }

+          }

+        }

+      }

+      //

+      // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... };

+      //

+    } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) {

+      //

+      // Read the next line if line continuation

+      //

+      LineLen = strlen (Line);

+      if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {

+        fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr);

+      } else if (Line[LineLen - 1] == '\\') {

+        fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr);

+      }

+

+      Cptr = CSavePtr + 8;

+      Cptr += SkipWhiteSpace (Cptr);

+      //

+      // Should be variable name next

+      //

+      Len     = ValidSymbolName (Cptr);

+      SymName = Cptr;

+      Cptr += Len;

+      Cptr += SkipWhiteSpace (Cptr);

+      if (*Cptr == '=') {

+        Cptr++;

+        Cptr += SkipWhiteSpace (Cptr);

+        //

+        // Should be open-brace next to define guid

+        //

+        if (*Cptr == '{') {

+          Cptr++;

+          //

+          // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }

+          //

+          if (sscanf (

+                Cptr,

+                "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X",

+                &GuidScan[0],

+                &GuidScan[1],

+                &GuidScan[2],

+                &GuidScan[3],

+                &GuidScan[4],

+                &GuidScan[5],

+                &GuidScan[6],

+                &GuidScan[7],

+                &GuidScan[8],

+                &GuidScan[9],

+                &GuidScan[10]

+                ) == 11) {

+            AddGuid11 (FileName, GuidScan, Cptr);

+            //

+            // printf ("Found guid: %s", Cptr);

+            //

+          }

+        }

+      }

+    }

+  }

+

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+//

+// Process Intel Itanium(TM) GUID definitions. Look for:

+// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA

+// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0

+// in either order.

+// This function assumes no blank lines between definitions.

+//

+static

+STATUS

+ProcessIA64FileGuids (

+  INT8    *FileName

+  )

+{

+  FILE    *Fptr;

+  INT8    Line[MAX_LINE_LEN];

+  UINT32  Guid1H;

+  UINT32  Guid1L;

+  UINT32  Guid2H;

+  UINT32  Guid2L;

+  INT8    SymName1[MAX_LINE_LEN];

+  INT8    SymName2[MAX_LINE_LEN];

+  BOOLEAN Done;

+  BOOLEAN LowFirst;

+  BOOLEAN FoundLow;

+

+  if ((Fptr = fopen (FileName, "r")) == NULL) {

+    Error (NULL, 0, 0, FileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+

+  Done = FALSE;

+  if (fgets (Line, sizeof (Line), Fptr) == NULL) {

+    Done = 1;

+  }

+  //

+  // Read lines from the file until done. Since the guid definition takes

+  // two lines, we read lines in different places to recover gracefully

+  // from mismatches. For example, if you thought you found the first half,

+  // but the next line had a symbol mismatch, then you have to process the

+  // line again in case it's the start of a new definition.

+  //

+  while (!Done) {

+    //

+    // Check current line for GUID definition. Assume low define first.

+    //

+    if (IsIA64GuidLine (Line, &Guid1H, &Guid1L, &FoundLow, SymName1)) {

+      //

+      // Might have to swap guids later. Save off if we found the LOW first

+      //

+      if (FoundLow) {

+        LowFirst = TRUE;

+      } else {

+        LowFirst = FALSE;

+      }

+      //

+      // Read the next line and try for the rest of the guid definition

+      //

+      if (fgets (Line, sizeof (Line), Fptr) == NULL) {

+        Done = 1;

+      } else {

+        if (IsIA64GuidLine (Line, &Guid2H, &Guid2L, &FoundLow, SymName2)) {

+          //

+          // Found another. If the symbol names match, then save it off.

+          //

+          if (strcmp (SymName1, SymName2) == 0) {

+            //

+            // Yea, found one. Save it off.

+            //

+            if (LowFirst) {

+              AddGuid64x2 (FileName, Guid2H, Guid2L, Guid1H, Guid1L);

+            } else {

+              AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L);

+            }

+            //

+            // Read the next line for processing

+            //

+            if (fgets (Line, sizeof (Line), Fptr) == NULL) {

+              Done = 1;

+            }

+          } else {

+            //

+            // Don't get another line so that we reprocess this line in case it

+            // contains the start of a new definition.

+            // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n",

+            //    FileName, SymName1, SymName2);

+            //

+          }

+        } else {

+          //

+          // Second line was not a guid definition. Get the next line from the

+          // file.

+          //

+          if (fgets (Line, sizeof (Line), Fptr) == NULL) {

+            Done = 1;

+          }

+        }

+      }

+    } else {

+      //

+      // Not a guid define line. Next.

+      //

+      if (fgets (Line, sizeof (Line), Fptr) == NULL) {

+        Done = 1;

+      }

+    }

+  }

+

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+//

+// Given a line from an Itanium-based assembly file, check the line for a guid

+// defininition. One of either:

+// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA

+// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0

+// Return the defined value as two 32-bit values, and whether it's a high

+// or low guid.

+//

+static

+BOOLEAN

+IsIA64GuidLine (

+  INT8      *Line,

+  UINT32    *GuidHigh,

+  UINT32    *GuidLow,

+  BOOLEAN   *FoundLow,

+  INT8      *SymName

+  )

+{

+  INT8    *Cptr;

+  INT8    CSave;

+  INT8    *CSavePtr;

+  INT8    *SymStart;

+  UINT32  Len;

+

+  Cptr = Line;

+  Cptr += SkipWhiteSpace (Cptr);

+  //

+  // look for #define xxxGUID[L|H] 0xHexValue

+  //

+  if (*Cptr == '#') {

+    Cptr++;

+    Cptr += SkipWhiteSpace (Cptr);

+    //

+    // Look for "define"

+    //

+    if (!strncmp (Cptr, "define", 6)) {

+      Cptr += 6;

+      //

+      // Better be whitespace

+      //

+      Len = SkipWhiteSpace (Cptr);

+      if (Len) {

+        Cptr += Len;

+        //

+        // See if it's a valid symbol name

+        //

+        Len = ValidSymbolName (Cptr);

+        if (Len) {

+          //

+          // Save the start so we can copy it to their string if later checks are ok

+          //

+          SymStart = Cptr;

+          //

+          // It is a valid symbol name, look for the string GuidL or GuidH

+          //

+          CSavePtr  = Cptr + Len;

+          CSave     = *CSavePtr;

+          *CSavePtr = 0;

+          while (*Cptr) {

+            if (strncmp (Cptr, "GuidL", 5) == 0) {

+              *FoundLow = 1;

+              break;

+            } else if (strncmp (Cptr, "GuidH", 5) == 0) {

+              *FoundLow = 0;

+              break;

+            }

+

+            Cptr++;

+          }

+          //

+          // If we didn't run out of string, then we found the GUID string.

+          // Restore the null character we inserted above and continue.

+          // Now look for  0x.......

+          //

+          if (*Cptr) {

+            //

+            // Return symbol name less the "L" or "H"

+            //

+            strcpy (SymName, SymStart);

+            SymName[strlen (SymName) - 1] = 0;

+            Cptr                          = CSavePtr;

+            *CSavePtr                     = CSave;

+            Cptr += SkipWhiteSpace (Cptr);

+            if ((*Cptr == '0') && (*(Cptr + 1) == 'x')) {

+              //

+              // skip over "0x"

+              //

+              Cptr += 2;

+              //

+              // 0x0123456789ABCDEF -- null terminate after 8 characters,

+              // scan, replace the character and scan at that point.

+              //

+              CSave       = *(Cptr + 8);

+              *(Cptr + 8) = 0;

+              if (sscanf (Cptr, "%X", GuidHigh) == 1) {

+                *(Cptr + 8) = CSave;

+                if (sscanf (Cptr + 8, "%X", GuidLow) == 1) {

+                  return TRUE;

+                }

+              }

+            }

+          }

+        }

+      }

+    }

+  }

+

+  return FALSE;

+}

+//

+// Look at the characters in the string and determine if it's a valid

+// symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]*

+//

+static

+UINT32

+ValidSymbolName (

+  INT8    *Name

+  )

+{

+  int Len;

+

+  Len = 0;

+

+  //

+  // Test first character

+  //

+  if (((*Name >= 'a') && (*Name <= 'z')) || ((*Name >= 'A') && (*Name <= 'Z')) || (*Name == '_')) {

+    Name++;

+    Len = 1;

+    while (*Name) {

+      if (((*Name >= 'a') && (*Name <= 'z')) ||

+          ((*Name >= 'A') && (*Name <= 'Z')) ||

+          ((*Name >= '0') && (*Name <= '9')) ||

+          (*Name == '_')

+          ) {

+        Name++;

+        Len++;

+      } else {

+        break;

+      }

+    }

+  }

+

+  return Len;

+}

+

+static

+UINT32

+SkipWhiteSpace (

+  INT8    *Str

+  )

+{

+  UINT32  Len;

+  Len = 0;

+  while (isspace (*Str) && *Str) {

+    Len++;

+    Str++;

+  }

+

+  return Len;

+}

+//

+// found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7

+//

+static

+STATUS

+AddPkgGuid (

+  INT8      *FileName,

+  UINT32    *Data,

+  UINT64    *Data64

+  )

+{

+  GUID_RECORD *NewRec;

+  int         Index;

+

+  //

+  // Sanity check the data

+  //

+  if ((Data[1] | Data[2] | Data[3]) & 0xFFFF0000) {

+    Error (NULL, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // More checks for Data64?

+  // Allocate memory for a new one guid structure

+  //

+  NewRec = malloc (sizeof (GUID_RECORD));

+  if (NewRec == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) NewRec, 0, sizeof (GUID_RECORD));

+  NewRec->FileName = malloc (strlen (FileName) + 1);

+  if (NewRec->FileName == NULL) {

+    free (NewRec);

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  strcpy (NewRec->FileName, FileName);

+  NewRec->Guid.Data1    = Data[0];

+  NewRec->Guid.Data2    = (UINT16) Data[1];

+  NewRec->Guid.Data3    = (UINT16) Data[2];

+  NewRec->Guid.Data4[0] = (UINT8) Data[3];

+  NewRec->Guid.Data4[1] = (UINT8) (Data[3] >> 8);

+  for (Index = 2; Index < 8; Index++) {

+    NewRec->Guid.Data4[Index] = (UINT8) *Data64;

+    *Data64 >>= 8;

+  }

+  //

+  // Add it to the list

+  //

+  NewRec->Next  = gGuidList;

+  gGuidList     = NewRec;

+

+  //

+  // Report it

+  // ReportGuid (FileName, NewRec);

+  //

+  return STATUS_SUCCESS;

+}

+//

+// Add a guid consisting of 11 fields to our list of guids

+//

+static

+STATUS

+AddGuid11 (

+  INT8      *FileName,

+  UINT32    *Data,

+  INT8      *SymName

+  )

+{

+  GUID_RECORD *NewRec;

+  int         Index;

+

+  //

+  // Sanity check the data

+  //

+  if (!CheckGuidData (Data, 11)) {

+    return STATUS_ERROR;

+  }

+  //

+  // Allocate memory for a new one guid structure

+  //

+  NewRec = malloc (sizeof (GUID_RECORD));

+  if (NewRec == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) NewRec, 0, sizeof (GUID_RECORD));

+  NewRec->FileName = malloc (strlen (FileName) + 1);

+  if (NewRec->FileName == NULL) {

+    free (NewRec);

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  strcpy (NewRec->FileName, FileName);

+  if (SymName != NULL) {

+    NewRec->SymName = malloc (strlen (SymName) + 1);

+    if (NewRec->SymName == NULL) {

+      free (NewRec);

+      Error (NULL, 0, 0, "memory allocation failure", NULL);

+      return STATUS_ERROR;

+    }

+  }

+

+  strcpy (NewRec->SymName, SymName);

+

+  NewRec->Guid.Data1  = Data[0];

+  NewRec->Guid.Data2  = (UINT16) Data[1];

+  NewRec->Guid.Data3  = (UINT16) Data[2];

+  for (Index = 0; Index < 8; Index++) {

+    NewRec->Guid.Data4[Index] = (UINT8) Data[3 + Index];

+  }

+  //

+  // Add it to the list

+  //

+  NewRec->Next  = gGuidList;

+  gGuidList     = NewRec;

+

+  //

+  // Report it

+  // ReportGuid (FileName, NewRec);

+  //

+  return STATUS_SUCCESS;

+}

+//

+// For debug purposes, print each guid found

+//

+// static

+// VOID

+// ReportGuid (

+//  INT8        *FileName,

+// GUID_RECORD *NewGuid

+//  )

+// {

+//  //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1);

+// }

+//

+// Free up memory we allocated to keep track of guids defined.

+//

+static

+VOID

+FreeGuids (

+  VOID

+  )

+{

+  GUID_RECORD *NextRec;

+  while (gGuidList != NULL) {

+    NextRec = gGuidList->Next;

+    if (gGuidList->FileName != NULL) {

+      free (gGuidList->FileName);

+    }

+

+    if (gGuidList->SymName != NULL) {

+      free (gGuidList->SymName);

+    }

+

+    free (gGuidList);

+    gGuidList = NextRec;

+  }

+}

+

+static

+VOID

+FreeSigs (

+  VOID

+  )

+{

+  SIGNATURE_RECORD  *NextRec;

+  while (gSignatureList != NULL) {

+    NextRec = gSignatureList->Next;

+    if (gSignatureList->FileName != NULL) {

+      free (gSignatureList->FileName);

+    }

+

+    free (gSignatureList);

+    gSignatureList = NextRec;

+  }

+}

+//

+// Scan through all guids defined and compare each for duplicates.

+//

+static

+STATUS

+CheckDuplicates (

+  VOID

+  )

+{

+  GUID_RECORD       *CurrentFile;

+

+  GUID_RECORD       *TempFile;

+  SIGNATURE_RECORD  *CurrentSig;

+  SIGNATURE_RECORD  *TempSig;

+  STATUS            Status;

+  int               Index;

+  int               DupCount;

+  int               Len;

+  BOOLEAN           Same;

+  UINT32            GuidSum;

+  INT8              *SymName;

+

+  Status = STATUS_SUCCESS;

+

+  //

+  // If we're checking guids.....

+  //

+  if (gOptions.CheckGuids) {

+    //

+    // If -p option, print all guids found

+    //

+    if (gOptions.PrintFound) {

+      CurrentFile = gGuidList;

+      while (CurrentFile != NULL) {

+        fprintf (

+          stdout,

+          "GUID:  0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X %s\n",

+          (UINT32) CurrentFile->Guid.Data1,

+          (UINT32) CurrentFile->Guid.Data2,

+          (UINT32) CurrentFile->Guid.Data3,

+          (UINT32) CurrentFile->Guid.Data4[0],

+          (UINT32) CurrentFile->Guid.Data4[1],

+          (UINT32) CurrentFile->Guid.Data4[2],

+          (UINT32) CurrentFile->Guid.Data4[3],

+          (UINT32) CurrentFile->Guid.Data4[4],

+          (UINT32) CurrentFile->Guid.Data4[5],

+          (UINT32) CurrentFile->Guid.Data4[6],

+          (UINT32) CurrentFile->Guid.Data4[7],

+          CurrentFile->FileName

+          );

+        CurrentFile = CurrentFile->Next;

+      }

+    }

+

+    if (gOptions.GuidXReference) {

+      CurrentFile = gGuidList;

+      while (CurrentFile != NULL) {

+        //

+        // If no symbol name, print "unknown"

+        //

+        SymName = CurrentFile->SymName;

+        if (SymName == NULL) {

+          SymName = "unknown";

+        }

+

+        fprintf (

+          stdout,

+          "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n",

+          (UINT32) CurrentFile->Guid.Data1,

+          (UINT32) CurrentFile->Guid.Data2,

+          (UINT32) CurrentFile->Guid.Data3,

+          (UINT32) CurrentFile->Guid.Data4[0],

+          (UINT32) CurrentFile->Guid.Data4[1],

+          (UINT32) CurrentFile->Guid.Data4[2],

+          (UINT32) CurrentFile->Guid.Data4[3],

+          (UINT32) CurrentFile->Guid.Data4[4],

+          (UINT32) CurrentFile->Guid.Data4[5],

+          (UINT32) CurrentFile->Guid.Data4[6],

+          (UINT32) CurrentFile->Guid.Data4[7],

+          SymName

+          );

+        CurrentFile = CurrentFile->Next;

+      }

+    }

+    //

+    // Now go through all guids and report duplicates.

+    //

+    CurrentFile = gGuidList;

+    while (CurrentFile != NULL) {

+      DupCount  = 0;

+      TempFile  = CurrentFile->Next;

+      while (TempFile) {

+        //

+        // Compare the guids

+        //

+        if ((CurrentFile->Guid.Data1 == TempFile->Guid.Data1) &&

+            (CurrentFile->Guid.Data2 == TempFile->Guid.Data2) &&

+            (CurrentFile->Guid.Data3 == TempFile->Guid.Data3)

+            ) {

+          //

+          // OR in all the guid bytes so we can ignore NULL-guid definitions.

+          //

+          GuidSum = CurrentFile->Guid.Data1 | CurrentFile->Guid.Data2 | CurrentFile->Guid.Data3;

+          Same    = TRUE;

+          for (Index = 0; Index < 8; Index++) {

+            GuidSum |= CurrentFile->Guid.Data4[Index];

+            if (CurrentFile->Guid.Data4[Index] != TempFile->Guid.Data4[Index]) {

+              Same = FALSE;

+              break;

+            }

+          }

+          //

+          // If they're the same, and the guid was non-zero, print a message.

+          //

+          if (Same && GuidSum) {

+            if (DupCount == 0) {

+              Error (NULL, 0, 0, "duplicate GUIDS found", NULL);

+              fprintf (stdout, "   FILE1: %s\n", CurrentFile->FileName);

+            }

+

+            DupCount++;

+            fprintf (stdout, "   FILE%d: %s\n", DupCount + 1, TempFile->FileName);

+            //

+            // Flag it as reported so we don't report it again if there's three or more

+            //

+            TempFile->Reported = TRUE;

+          }

+        }

+        //

+        // Next one

+        //

+        TempFile = TempFile->Next;

+      }

+      //

+      // Print the guid if we found duplicates

+      //

+      if (DupCount) {

+        fprintf (

+          stdout,

+          "   GUID:  0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",

+          (UINT32) CurrentFile->Guid.Data1,

+          (UINT32) CurrentFile->Guid.Data2,

+          (UINT32) CurrentFile->Guid.Data3,

+          (UINT32) CurrentFile->Guid.Data4[0],

+          (UINT32) CurrentFile->Guid.Data4[1],

+          (UINT32) CurrentFile->Guid.Data4[2],

+          (UINT32) CurrentFile->Guid.Data4[3],

+          (UINT32) CurrentFile->Guid.Data4[4],

+          (UINT32) CurrentFile->Guid.Data4[5],

+          (UINT32) CurrentFile->Guid.Data4[6],

+          (UINT32) CurrentFile->Guid.Data4[7]

+          );

+        //

+        // return STATUS_ERROR;

+        //

+      }

+      //

+      // Find the next one that hasn't been reported

+      //

+      do {

+        CurrentFile = CurrentFile->Next;

+      } while ((CurrentFile != NULL) && (CurrentFile->Reported));

+    }

+  }

+

+  if (gOptions.CheckSignatures) {

+    //

+    // Print ones found if specified

+    //

+    if (gOptions.PrintFound) {

+      CurrentSig = gSignatureList;

+      while (CurrentSig != NULL) {

+        Len = CurrentSig->Signature.DataLen;

+        for (Index = 0; Index < Len; Index++) {

+          fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);

+        }

+

+        fprintf (stdout, "  %s\n", CurrentSig->FileName);

+        CurrentSig = CurrentSig->Next;

+      }

+    }

+

+    CurrentSig = gSignatureList;

+    while (CurrentSig != NULL) {

+      DupCount  = 0;

+      TempSig   = CurrentSig->Next;

+      Len       = CurrentSig->Signature.DataLen;

+      while (TempSig) {

+        //

+        // Check for same length, then do string compare

+        //

+        if (Len == TempSig->Signature.DataLen) {

+          if (strncmp (CurrentSig->Signature.Data, TempSig->Signature.Data, Len) == 0) {

+            //

+            // Print header message if first failure for this sig

+            //

+            if (DupCount == 0) {

+              Error (NULL, 0, 0, "duplicate signatures found", NULL);

+              fprintf (stdout, "   FILE1: %s\n", CurrentSig->FileName);

+            }

+

+            DupCount++;

+            fprintf (stdout, "   FILE%d: %s\n", DupCount + 1, TempSig->FileName);

+            TempSig->Reported = TRUE;

+          }

+        }

+

+        TempSig = TempSig->Next;

+      }

+

+      if (DupCount) {

+        fprintf (stdout, "   SIG:   ");

+        for (Index = 0; Index < Len; Index++) {

+          fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);

+        }

+

+        fprintf (stdout, "\n");

+      }

+      //

+      // On to the next one that hasn't been reported

+      //

+      do {

+        CurrentSig = CurrentSig->Next;

+      } while ((CurrentSig != NULL) && (CurrentSig->Reported));

+    }

+  }

+

+  return Status;

+}

+

+static

+VOID

+FreeOptions (

+  VOID

+  )

+/*++

+

+Routine Description:

+  Free up any memory we allocated when processing command-line options.

+

+Arguments:

+  None.

+

+Returns:

+  NA

+

+Notes:

+  We don't free up the ->Str fields because we did not allocate them.

+  Instead, we just set the pointer to point to the actual parameter

+  from the command line.

+

+--*/

+{

+  STRING_LIST *Ptr;

+  while (gOptions.ExcludeDirs != NULL) {

+    Ptr = gOptions.ExcludeDirs->Next;

+    //

+    // free (gOptions.ExcludeDirs->Str);

+    //

+    free (gOptions.ExcludeDirs);

+    gOptions.ExcludeDirs = Ptr;

+  }

+

+  while (gOptions.ExcludeSubDirs != NULL) {

+    Ptr = gOptions.ExcludeSubDirs->Next;

+    //

+    // free (gOptions.ExcludeSubDirs->Str);

+    //

+    free (gOptions.ExcludeSubDirs);

+    gOptions.ExcludeSubDirs = Ptr;

+  }

+

+  while (gOptions.ExcludeExtensions != NULL) {

+    Ptr = gOptions.ExcludeExtensions->Next;

+    //

+    // free (gOptions.ExcludeExtensions->Str);

+    //

+    free (gOptions.ExcludeExtensions);

+    gOptions.ExcludeExtensions = Ptr;

+  }

+

+  while (gOptions.ExcludeFiles != NULL) {

+    Ptr = gOptions.ExcludeFiles->Next;

+    //

+    // free (gOptions.ExcludeFiles->Str);

+    //

+    free (gOptions.ExcludeFiles);

+    gOptions.ExcludeFiles = Ptr;

+  }

+}

+//

+// Given an array of 32-bit data, validate the data for the given number of

+// guid data. For example, it might have been scanned as 16 bytes of data, or

+// 11 fields of data.

+//

+static

+BOOLEAN

+CheckGuidData (

+  UINT32    *Data,

+  UINT32    DataCount

+  )

+{

+  UINT32  Index;

+

+  if (DataCount == 16) {

+    for (Index = 0; Index < 16; Index++) {

+      if (Data[Index] &~0xFF) {

+        return FALSE;

+      }

+    }

+

+    return TRUE;

+  } else if (DataCount == 11) {

+    //

+    // Data[0] never out of range (32-bit)

+    //

+    if ((Data[1] | Data[2]) &~0xFFFF) {

+      //

+      // Error ("Out of range value for GUID data word(s) [1] and/or [2]");

+      //

+      return FALSE;

+    }

+

+    for (Index = 0; Index < 8; Index++) {

+      if (Data[Index + 3] &~0xFF) {

+        //

+        // Error ("Out of range value for GUID data byte(s) [4] - [11]");

+        //

+        return FALSE;

+      }

+    }

+

+    return TRUE;

+  }

+

+  return FALSE;

+}

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/GuidList.c b/edk2/Tools/Source/TianoTools/GuidChk/GuidList.c
new file mode 100644
index 0000000..0e8afde
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/GuidList.c
@@ -0,0 +1,188 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  GuidList.c  

+

+Abstract:

+

+  Utility to create a GUID-to-name listing file that can

+  be used by other utilities. Basic operation is to take the

+  table of name+GUIDs that we have compiled into this utility,

+  and create a text file that can be parsed by other utilities

+  to do replacement of "name" with "GUID".

+

+Notes:

+  To add a new GUID to this database:

+    1. Add a "#include EFI_GUID_DEFINITION(name)" statement below

+    2. Modify the mGuidList[] array below to add the new GUID name

+

+  The only issue that may come up is that, if the source GUID file

+  is not in the standard GUID directory, then this utility won't

+  compile because the #include fails. In this case you'd need

+  to define a new macro (if it's in a standard place) or modify

+  this utility's makefile to add the path to your new .h file.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <UgaDraw.h>

+#include "EfiUtilityMsgs.h"

+

+#include <Apriori.h>

+#include <AcpiTableStorage.h>

+// #include <Bmp.h>

+

+#define GUID_XREF(varname, guid) { \

+    #varname, #guid, guid \

+  }

+

+#define NULL_GUID \

+  { \

+    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 \

+  }

+

+typedef struct {

+  INT8      *VariableName;

+  INT8      *DefineName;

+  EFI_GUID  Guid;

+} GUID_LIST;

+

+//

+// This is our table of all GUIDs we want to print out to create

+// a GUID-to-name cross reference.

+// Use the #defined name from the GUID definition's source .h file.

+//

+static GUID_LIST  mGuidList[] = {

+  GUID_XREF(gAprioriGuid, EFI_APRIORI_GUID),

+  GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID),

+  // FIXME The next line was removed in the port to R9.

+  // GUID_XREF(gEfiDefaultBmpLogoGuid, EFI_DEFAULT_BMP_LOGO_GUID),

+  GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID),

+  //

+  // Terminator

+  //

+  {

+    NULL,

+    NULL,

+    NULL_GUID

+  }

+};

+

+void

+PrintGuidText (

+  FILE      *OutFptr,

+  INT8      *VariableName,

+  INT8      *DefineName,

+  EFI_GUID  *Guid

+  );

+

+int

+CreateGuidList (

+  INT8    *OutFileName

+  )

+/*++

+

+Routine Description:

+  Print our GUID/name list to the specified output file.

+  

+Arguments:

+  OutFileName  - name of the output file to write our results to.

+

+Returns:

+  0       if successful

+  nonzero otherwise

+  

+--*/

+{

+  FILE  *OutFptr;

+  int   Index;

+

+  //

+  // Open output file for writing. If the name is NULL, then write to stdout

+  //

+  if (OutFileName != NULL) {

+    OutFptr = fopen (OutFileName, "w");

+    if (OutFptr == NULL) {

+      Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");

+      return STATUS_ERROR;

+    }

+  } else {

+    OutFptr = stdout;

+  }

+

+  for (Index = 0; mGuidList[Index].VariableName != NULL; Index++) {

+    PrintGuidText (OutFptr, mGuidList[Index].VariableName, mGuidList[Index].DefineName, &mGuidList[Index].Guid);

+  }

+  //

+  // Close the output file if they specified one.

+  //

+  if (OutFileName != NULL) {

+    fclose (OutFptr);

+  }

+

+  return STATUS_SUCCESS;

+}

+

+void

+PrintGuidText (

+  FILE      *OutFptr,

+  INT8      *VariableName,

+  INT8      *DefineName,

+  EFI_GUID  *Guid

+  )

+/*++

+

+Routine Description:

+  Print a GUID/name combo in INF-style format

+

+  guid-guid-guid-guid DEFINE_NAME gName

+

+Arguments:

+  OutFptr       - file pointer to which to write the output

+  VariableName  - the GUID variable's name

+  DefineName    - the name used in the #define

+  Guid          - pointer to the GUID value

+

+Returns:

+  NA

+

+--*/

+{

+  if (OutFptr == NULL) {

+    OutFptr = stdout;

+  }

+

+  fprintf (

+    OutFptr,

+    "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s %s\n",

+    Guid->Data1,

+    Guid->Data2,

+    Guid->Data3,

+    Guid->Data4[0],

+    Guid->Data4[1],

+    Guid->Data4[2],

+    Guid->Data4[3],

+    Guid->Data4[4],

+    Guid->Data4[5],

+    Guid->Data4[6],

+    Guid->Data4[7],

+    DefineName,

+    VariableName

+    );

+}

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/UtilsMsgs.c b/edk2/Tools/Source/TianoTools/GuidChk/UtilsMsgs.c
new file mode 100644
index 0000000..b9fcab0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/UtilsMsgs.c
@@ -0,0 +1,490 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  UtilsMsgs.c

+  

+Abstract:

+

+  EFI tools utility functions to display warning, error, and informational

+  messages.

+  

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <ctype.h>

+#include <stdarg.h>

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include "EfiUtilityMsgs.h"

+

+#define MAX_LINE_LEN  200

+

+//

+// Declare module globals for keeping track of the the utility's

+// name and other settings.

+//

+static STATUS mStatus             = STATUS_SUCCESS;

+static INT8   mUtilityName[50]    = { 0 };

+static INT8   *mSourceFileName    = NULL;

+static UINT32 mSourceFileLineNum  = 0;

+static UINT32 mErrorCount         = 0;

+static UINT32 mWarningCount       = 0;

+static UINT32 mDebugMsgMask       = 0;

+

+static

+void

+PrintMessage (

+  INT8    *Type,

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  INT8    *Text,

+  INT8    *MsgFmt,

+  va_list List

+  );

+

+void

+Error (

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  INT8    *Text,

+  INT8    *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Prints an error message.

+  

+Arguments:

+  All arguments are optional, though the printed message may be useless if

+  at least something valid is not specified.

+  

+  FileName - name of the file or application. If not specified, then the

+             utilty name (as set by the utility calling SetUtilityName()

+             earlier) is used. Otherwise "Unknown utility" is used.

+  

+  LineNumber - the line number of error, typically used by parsers. If the

+               utility is not a parser, then 0 should be specified. Otherwise

+               the FileName and LineNumber info can be used to cause

+               MS Visual Studio to jump to the error.

+               

+  MessageCode - an application-specific error code that can be referenced in

+              other documentation. 

+

+  Text        - the text in question, typically used by parsers.

+  

+  MsgFmt - the format string for the error message. Can contain formatting

+           controls for use with the varargs.

+           

+Returns:

+  None.

+  

+Notes:

+  We print the following (similar to the Warn() and Debug() 

+  W

+  Typical error/warning message format:

+

+  bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters

+

+  BUGBUG -- these three utility functions are almost identical, and

+  should be modified to share code.

+

+  Visual Studio does not find error messages with:

+  

+     " error :"

+     " error 1:"

+     " error c1:"

+     " error 1000:"

+     " error c100:"

+

+  It does find:

+     " error c1000:"     

+--*/

+{

+  va_list List;

+  mErrorCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_ERROR) {

+    mStatus = STATUS_ERROR;

+  }

+}

+

+void

+ParserError (

+  UINT32  MessageCode,

+  INT8    *Text,

+  INT8    *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a parser error, using the source file name and line number

+  set by a previous call to SetParserPosition().

+

+Arguments:

+  MessageCode   - application-specific error code

+  Text          - text to print in the error message

+  MsgFmt        - format string to print at the end of the error message

+  ...

+

+Returns:

+  NA

+

+--*/

+{

+  va_list List;

+  mErrorCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_ERROR) {

+    mStatus = STATUS_ERROR;

+  }

+}

+

+void

+ParserWarning (

+  UINT32  ErrorCode,

+  INT8    *OffendingText,

+  INT8    *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a parser warning, using the source file name and line number

+  set by a previous call to SetParserPosition().

+

+Arguments:

+  ErrorCode     - application-specific error code

+  OffendingText - text to print in the warning message

+  MsgFmt        - format string to print at the end of the warning message

+  ...

+

+Returns:

+  NA

+

+--*/

+{

+  va_list List;

+  mWarningCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_WARNING) {

+    mStatus = STATUS_WARNING;

+  }

+}

+

+void

+Warning (

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  INT8    *Text,

+  INT8    *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a warning message.

+

+Arguments:

+  FileName    - name of the file where the warning was detected, or the name

+                of the application that detected the warning

+  

+  LineNumber  - the line number where the warning was detected (parsers).

+                0 should be specified if the utility is not a parser.

+               

+  MessageCode - an application-specific warning code that can be referenced in

+                other documentation. 

+

+  Text        - the text in question (parsers)

+  

+  MsgFmt      - the format string for the warning message. Can contain formatting

+                controls for use with varargs.

+                

+  ...

+           

+Returns:

+  None.

+

+--*/

+{

+  va_list List;

+  mWarningCount++;

+  va_start (List, MsgFmt);

+  PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List);

+  va_end (List);

+  //

+  // Set status accordingly

+  //

+  if (mStatus < STATUS_WARNING) {

+    mStatus = STATUS_WARNING;

+  }

+}

+

+void

+DebugMsg (

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  MsgMask,

+  INT8    *Text,

+  INT8    *MsgFmt,

+  ...

+  )

+/*++

+

+Routine Description:

+  Print a warning message.

+

+Arguments:

+  FileName    - typically the name of the utility printing the debug message, but

+                can be the name of a file being parsed.

+  

+  LineNumber  - the line number in FileName (parsers) 

+               

+  MsgMask     - an application-specific bitmask that, in combination with mDebugMsgMask,

+                determines if the debug message gets printed.

+

+  Text        - the text in question (parsers)

+  

+  MsgFmt      - the format string for the debug message. Can contain formatting

+                controls for use with varargs.

+          

+  ... 

+Returns:

+  None.

+

+--*/

+{

+  va_list List;

+  //

+  // If the debug mask is not applicable, then do nothing.

+  //

+  if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) {

+    return ;

+  }

+

+  va_start (List, MsgFmt);

+  PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List);

+  va_end (List);

+}

+

+static

+void

+PrintMessage (

+  INT8    *Type,

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  MessageCode,

+  INT8    *Text,

+  INT8    *MsgFmt,

+  va_list List

+  )

+/*++

+

+Routine Description:

+  Worker routine for all the utility printing services. Prints the message in

+  a format that Visual Studio will find when scanning build outputs for

+  errors or warnings.

+

+Arguments:

+  Type        - "warning" or "error" string to insert into the message to be

+                printed. The first character of this string (converted to uppercase)

+                is used to preceed the MessageCode value in the output string.

+

+  FileName    - name of the file where the warning was detected, or the name

+                of the application that detected the warning

+  

+  LineNumber  - the line number where the warning was detected (parsers).

+                0 should be specified if the utility is not a parser.

+               

+  MessageCode - an application-specific warning code that can be referenced in

+                other documentation. 

+

+  Text        - part of the message to print

+  

+  MsgFmt      - the format string for the message. Can contain formatting

+                controls for use with varargs.

+

+  List        - Variable function parameter list.           

+Returns:

+  None.

+

+Notes:

+  If FileName == NULL then this utility will use the string passed into SetUtilityName(). 

+  

+  LineNumber is only used if the caller is a parser, in which case FileName refers to the

+  file being parsed.

+

+  Text and MsgFmt are both optional, though it would be of little use calling this function with

+  them both NULL.

+

+  Output will typically be of the form:

+    <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>

+

+    Parser (LineNumber != 0)

+      VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters

+    Generic utility (LineNumber == 0) 

+      UtilityName : error E1234 : Text string : MsgFmt string and args

+

+--*/

+{

+  INT8  Line[MAX_LINE_LEN];

+  INT8  Line2[MAX_LINE_LEN];

+  INT8  *Cptr;

+  //

+  // If given a filename, then add it (and the line number) to the string.

+  // If there's no filename, then use the program name if provided.

+  //

+  if (FileName != NULL) {

+    Cptr = FileName;

+  } else if (mUtilityName[0] != 0) {

+    Cptr = mUtilityName;

+  } else {

+    Cptr = "Unknown utility";

+  }

+

+  strcpy (Line, Cptr);

+  if (LineNumber != 0) {

+    sprintf (Line2, "(%d)", LineNumber);

+    strcat (Line, Line2);

+  }

+  //

+  // Have to print an error code or Visual Studio won't find the

+  // message for you. It has to be decimal digits too.

+  //

+  sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode);

+  strcat (Line, Line2);

+  fprintf (stdout, "%s", Line);

+  //

+  // If offending text was provided, then print it

+  //

+  if (Text != NULL) {

+    fprintf (stdout, ": %s ", Text);

+  }

+  //

+  // Print formatted message if provided

+  //

+  if (MsgFmt != NULL) {

+    vsprintf (Line2, MsgFmt, List);

+    fprintf (stdout, ": %s", Line2);

+  }

+

+  fprintf (stdout, "\n");

+}

+

+void

+ParserSetPosition (

+  INT8    *SourceFileName,

+  UINT32  LineNum

+  )

+/*++

+

+Routine Description:

+  Set the position in a file being parsed. This can be used to 

+  print error messages deeper down in a parser.

+

+Arguments:

+  SourceFileName - name of the source file being parsed

+  LineNum        - line number of the source file being parsed

+

+Returns:

+  NA

+

+--*/

+{

+  mSourceFileName     = SourceFileName;

+  mSourceFileLineNum  = LineNum;

+}

+

+void

+SetUtilityName (

+  INT8    *UtilityName

+  )

+/*++

+

+Routine Description:

+  All printed error/warning/debug messages follow the same format, and

+  typically will print a filename or utility name followed by the error

+  text. However if a filename is not passed to the print routines, then

+  they'll print the utility name if you call this function early in your

+  app to set the utility name.

+  

+Arguments:

+  UtilityName  -  name of the utility, which will be printed with all

+                  error/warning/debug messags.

+

+Returns:

+  NA

+  

+--*/

+{

+  //

+  // Save the name of the utility in our local variable. Make sure its

+  // length does not exceed our buffer.

+  //

+  if (UtilityName != NULL) {

+    if (strlen (UtilityName) >= sizeof (mUtilityName)) {

+      Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");

+      strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);

+      mUtilityName[sizeof (mUtilityName) - 1] = 0;

+      return ;

+    } else {

+      strcpy (mUtilityName, UtilityName);

+    }

+  } else {

+    Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");

+  }

+}

+

+STATUS

+GetUtilityStatus (

+  VOID

+  )

+/*++

+

+Routine Description:

+  When you call Error() or Warning(), this module keeps track of it and

+  sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility

+  exits, it can call this function to get the status and use it as a return

+  value.

+  

+Arguments:

+  None.

+

+Returns:

+  Worst-case status reported, as defined by which print function was called.

+  

+--*/

+{

+  return mStatus;

+}

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/UtilsMsgs.h b/edk2/Tools/Source/TianoTools/GuidChk/UtilsMsgs.h
new file mode 100644
index 0000000..5f6c701
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/UtilsMsgs.h
@@ -0,0 +1,106 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:  

+

+  UtilsMsgs.h

+  

+Abstract:

+

+  Prototypes for the EFI tools utility functions.

+  

+--*/

+

+#ifndef _UTILS_MESSAGES_H_

+#define _UTILS_MESSAGES_H_

+

+STATUS

+GetUtilityStatus (

+  VOID

+  )

+;

+

+//

+// If someone prints an error message and didn't specify a source file name,

+// then we print the utility name instead. However they must tell us the

+// utility name early on via this function.

+//

+VOID

+SetUtilityName (

+  INT8 *ProgramName

+  )

+;

+

+void

+Error (

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  ErrorCode,

+  INT8    *OffendingText,

+  INT8    *MsgFmt,

+  ...

+  )

+;

+

+void

+Warning (

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  ErrorCode,

+  INT8    *OffendingText,

+  INT8    *MsgFmt,

+  ...

+  )

+;

+

+void

+DebugMsg (

+  INT8    *FileName,

+  UINT32  LineNumber,

+  UINT32  MsgLevel,

+  INT8    *OffendingText,

+  INT8    *MsgFmt,

+  ...

+  )

+;

+

+void

+SetDebugMsgMask (

+  UINT32    MsgMask

+  )

+;

+

+void

+ParserSetPosition (

+  INT8    *SourceFileName,

+  UINT32  LineNum

+  )

+;

+

+void

+ParserError (

+  UINT32  ErrorCode,

+  INT8    *OffendingText,

+  INT8    *MsgFmt,

+  ...

+  )

+;

+

+void

+ParserWarning (

+  UINT32  ErrorCode,

+  INT8    *OffendingText,

+  INT8    *MsgFmt,

+  ...

+  )

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/GuidChk/build.xml b/edk2/Tools/Source/TianoTools/GuidChk/build.xml
new file mode 100644
index 0000000..d7b7fba
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/GuidChk/build.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK GuidChk Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="GuidChk"/>

+  <property name="FileSet" value="*.c *.h"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init" unless="gcc">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Guid"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<linkerarg value="${LIB_DIR}/CommonTools.lib"/>

+			<linkerarg value="${LIB_DIR}/CustomizedCompress.lib"/>

+

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/MakeDeps/MakeDeps.c b/edk2/Tools/Source/TianoTools/MakeDeps/MakeDeps.c
new file mode 100755
index 0000000..96ce31e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/MakeDeps/MakeDeps.c
@@ -0,0 +1,1286 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  MakeDeps.c  

+

+Abstract:

+

+  Recursively scan source files to find include files and emit them to 

+  create dependency lists.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include "EfiUtilityMsgs.h"

+#include <CommonLib.h>

+

+//

+// Structure to maintain a linked list of strings

+//

+typedef struct _STRING_LIST {

+  struct _STRING_LIST *Next;

+  char                *Str;

+} STRING_LIST;

+

+#define UTILITY_NAME      "MakeDeps"

+

+#define MAX_LINE_LEN      2048

+#define MAX_PATH          2048

+#define START_NEST_DEPTH  1

+#define MAX_NEST_DEPTH    1000  // just in case we get in an endless loop.

+//

+// Define the relative paths used by the special #include macros

+//

+#define PROTOCOL_DIR_PATH       "Protocol\\"

+#define GUID_DIR_PATH           "Guid\\"

+#define ARCH_PROTOCOL_DIR_PATH  "ArchProtocol\\"

+#define PPI_PROTOCOL_DIR_PATH   "Ppi\\"

+

+//

+// Use this structure to keep track of all the special #include forms

+//

+typedef struct {

+  INT8  *IncludeMacroName;

+  INT8  *PathName;

+} INCLUDE_MACRO_CONVERSION;

+

+//

+// This data is used to convert #include macros like:

+//    #include EFI_PROTOCOL_DEFINITION(xxx)

+// into

+//    #include Protocol/xxx/xxx.h

+//

+static const INCLUDE_MACRO_CONVERSION mMacroConversion[] = {

+  "EFI_PROTOCOL_DEFINITION",

+  PROTOCOL_DIR_PATH,

+  "EFI_GUID_DEFINITION",

+  GUID_DIR_PATH,

+  "EFI_ARCH_PROTOCOL_DEFINITION",

+  ARCH_PROTOCOL_DIR_PATH,

+  "EFI_PROTOCOL_PRODUCER",

+  PROTOCOL_DIR_PATH,

+  "EFI_PROTOCOL_CONSUMER",

+  PROTOCOL_DIR_PATH,

+  "EFI_PROTOCOL_DEPENDENCY",

+  PROTOCOL_DIR_PATH,

+  "EFI_ARCH_PROTOCOL_PRODUCER",

+  ARCH_PROTOCOL_DIR_PATH,

+  "EFI_ARCH_PROTOCOL_CONSUMER",

+  ARCH_PROTOCOL_DIR_PATH,

+  "EFI_ARCH_PROTOCOL_DEPENDENCY",

+  ARCH_PROTOCOL_DIR_PATH,

+  "EFI_PPI_DEFINITION",

+  PPI_PROTOCOL_DIR_PATH,

+  "EFI_PPI_PRODUCER",

+  PPI_PROTOCOL_DIR_PATH,

+  "EFI_PPI_CONSUMER",

+  PPI_PROTOCOL_DIR_PATH,

+  "EFI_PPI_DEPENDENCY",

+  PPI_PROTOCOL_DIR_PATH,

+  NULL,

+  NULL

+};

+

+typedef struct _SYMBOL {

+  struct _SYMBOL  *Next;

+  INT8            *Name;

+  INT8            *Value;

+} SYMBOL;

+

+//

+// Here's all our globals. We need a linked list of include paths, a linked

+// list of source files, a linked list of subdirectories (appended to each

+// include path when searching), and flags to keep track of command-line options.

+//

+static struct {

+  STRING_LIST *IncludePaths;            // all include paths to search

+  STRING_LIST *SourceFiles;             // all source files to parse

+  STRING_LIST *SubDirs;                 // appended to each include path when searching

+  SYMBOL      *SymbolTable;             // for replacement strings

+  FILE        *OutFptr;                 // output dependencies to this file

+  BOOLEAN     Verbose;                  // for more detailed output

+  BOOLEAN     IgnoreNotFound;           // no warnings if files not found

+  BOOLEAN     QuietMode;                // -q - don't print missing file warnings

+  BOOLEAN     NoSystem;                 // don't process #include <system> files

+  BOOLEAN     NeverFail;                // always return success

+  BOOLEAN     NoDupes;                  // to not list duplicate dependency files (for timing purposes)

+  BOOLEAN     UseSumDeps;               // use summary dependency files if found

+  INT8        TargetFileName[MAX_PATH]; // target object filename

+  INT8        SumDepsPath[MAX_PATH];    // path to summary files

+  INT8        *OutFileName;             // -o option

+} mGlobals;

+

+static

+STATUS

+ProcessFile (

+  INT8            *TargetFileName,

+  INT8            *FileName,

+  UINT32          NestDepth,

+  STRING_LIST     *ProcessedFiles

+  );

+

+static

+FILE  *

+FindFile (

+  INT8    *FileName,

+  UINT32  FileNameLen

+  );

+

+static

+void

+PrintDependency (

+  INT8    *Target,

+  INT8    *DependentFile

+  );

+

+static

+void

+ReplaceSymbols (

+  INT8    *Str,

+  UINT32  StrSize

+  );

+

+static

+STATUS

+ProcessArgs (

+  int   Argc,

+  char  *Argv[]

+  );

+

+static

+void

+Usage (

+  VOID

+  );

+

+static

+void

+FreeLists (

+  VOID

+  );

+

+int

+main (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+

+  Call the routine to parse the command-line options, then process each file

+  to build dependencies.

+  

+Arguments:

+

+  Argc - Standard C main() argc.

+  Argv - Standard C main() argv.

+

+Returns:

+

+  0       if successful

+  nonzero otherwise

+  

+--*/

+{

+  STRING_LIST *File;

+  STRING_LIST ProcessedFiles;

+  STRING_LIST *TempList;

+  STATUS      Status;

+  INT8        *Cptr;

+  INT8        TargetFileName[MAX_PATH];

+

+  SetUtilityName (UTILITY_NAME);

+  //

+  // Process the command-line arguments

+  //

+  Status = ProcessArgs (Argc, Argv);

+  if (Status != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+  //

+  // Go through the list of source files and process each.

+  //

+  memset (&ProcessedFiles, 0, sizeof (STRING_LIST));

+  File = mGlobals.SourceFiles;

+  while (File != NULL) {

+    //

+    // Clear out our list of processed files

+    //

+    TempList = ProcessedFiles.Next;

+    while (ProcessedFiles.Next != NULL) {

+      TempList = ProcessedFiles.Next->Next;

+      free (ProcessedFiles.Next->Str);

+      free (ProcessedFiles.Next);

+      ProcessedFiles.Next = TempList;

+    }

+    //

+    // Replace filename extension with ".obj" if they did not

+    // specifically specify the target file

+    //

+    if (mGlobals.TargetFileName[0] == 0) {

+      strcpy (TargetFileName, File->Str);

+      //

+      // Find the .extension

+      //

+      for (Cptr = TargetFileName + strlen (TargetFileName) - 1;

+           (*Cptr != '\\') && (Cptr > TargetFileName) && (*Cptr != '.');

+           Cptr--

+          )

+        ;

+      if (Cptr == TargetFileName) {

+        Error (NULL, 0, 0, File->Str, "could not locate extension in filename");

+        goto Finish;

+      }

+      //

+      // Tack on the ".obj"

+      //

+      strcpy (Cptr, ".obj");

+    } else {

+      //

+      // Copy the target filename they specified

+      //

+      strcpy (TargetFileName, mGlobals.TargetFileName);

+    }

+

+    Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles);

+    if (Status != STATUS_SUCCESS) {

+      goto Finish;

+    }

+

+    File = File->Next;

+  }

+

+Finish:

+  //

+  // Free up memory

+  //

+  FreeLists ();

+  //

+  // Free up our processed files list

+  //

+  TempList = ProcessedFiles.Next;

+  while (ProcessedFiles.Next != NULL) {

+    TempList = ProcessedFiles.Next->Next;

+    free (ProcessedFiles.Next->Str);

+    free (ProcessedFiles.Next);

+    ProcessedFiles.Next = TempList;

+  }

+  //

+  // Close our output file

+  //

+  if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) {

+    fclose (mGlobals.OutFptr);

+  }

+

+  if (mGlobals.NeverFail) {

+    return STATUS_SUCCESS;

+  }

+  //

+  // If any errors, then delete our output so that it will get created

+  // again on a rebuild.

+  //

+  if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) {

+    remove (mGlobals.OutFileName);

+  }

+

+  return GetUtilityStatus ();

+}

+

+static

+STATUS

+ProcessFile (

+  INT8            *TargetFileName,

+  INT8            *FileName,

+  UINT32          NestDepth,

+  STRING_LIST     *ProcessedFiles

+  )

+/*++

+

+Routine Description:

+

+  Given a source file name, open the file and parse all #include lines.

+  

+Arguments:

+

+  TargetFileName - name of the usually .obj target

+  FileName       - name of the file to process

+  NestDepth      - how deep we're nested in includes

+  ProcessedFiles - list of processed files.

+

+Returns:

+

+  standard status.

+  

+--*/

+{

+  FILE        *Fptr;

+  INT8        Line[MAX_LINE_LEN];

+  INT8        *Cptr;

+  INT8        *EndPtr;

+  INT8        *SaveCptr;

+  INT8        EndChar;

+  INT8        FileNameCopy[MAX_PATH];

+  INT8        MacroIncludeFileName[MAX_LINE_LEN];

+  INT8        SumDepsFile[MAX_PATH];

+  STATUS      Status;

+  UINT32      Index;

+  UINT32      LineNum;

+  STRING_LIST *ListPtr;

+

+  Status  = STATUS_SUCCESS;

+  Fptr    = NULL;

+  //

+  // Print the file being processed. Indent so you can tell the include nesting

+  // depth.

+  //

+  if (mGlobals.Verbose) {

+    fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', FileName);

+  }

+  //

+  // If we're using summary dependency files, and a matching .dep file is

+  // found for this file, then just emit the summary dependency file as

+  // a dependency and return.

+  //

+  if (mGlobals.UseSumDeps) {

+    strcpy (SumDepsFile, mGlobals.SumDepsPath);

+    strcat (SumDepsFile, FileName);

+    for (Cptr = SumDepsFile + strlen (SumDepsFile) - 1;

+         (*Cptr != '\\') && (Cptr > SumDepsFile) && (*Cptr != '.');

+         Cptr--

+        )

+      ;

+    if (*Cptr == '.') {

+      strcpy (Cptr, ".dep");

+    } else {

+      strcat (SumDepsFile, ".dep");

+    }

+    //

+    // See if the summary dep file exists. Could use _stat() function, but

+    // it's less portable.

+    //

+    if ((Fptr = fopen (SumDepsFile, "r")) != NULL) {

+      PrintDependency (TargetFileName, SumDepsFile);

+      return STATUS_SUCCESS;

+    }

+  }

+  //

+  // If we're not doing duplicates, and we've already seen this filename,

+  // then return

+  //

+  if (mGlobals.NoDupes) {

+    for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) {

+      if (stricmp (FileName, ListPtr->Str) == 0) {

+        break;

+      }

+    }

+    //

+    // If we found a match, we're done. If we didn't, create a new element

+    // and add it to the list.

+    //

+    if (ListPtr != NULL) {

+      //

+      // Print a message if verbose mode

+      //

+      if (mGlobals.Verbose) {

+        DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again");

+      }

+

+      return STATUS_SUCCESS;

+    }

+

+    ListPtr       = malloc (sizeof (STRING_LIST));

+    ListPtr->Str  = malloc (strlen (FileName) + 1);

+    strcpy (ListPtr->Str, FileName);

+    ListPtr->Next         = ProcessedFiles->Next;

+    ProcessedFiles->Next  = ListPtr;

+  }

+

+  //

+  // Make sure we didn't exceed our maximum nesting depth

+  //

+  if (NestDepth > MAX_NEST_DEPTH) {

+    Error (NULL, 0, 0, FileName, "max nesting depth exceeded on file");

+    goto Finish;

+  }

+  //

+  // Make a local copy of the filename. Then we can manipulate it

+  // if we have to.

+  //

+  strcpy (FileNameCopy, FileName);

+  //

+  // Try to open the file locally

+  //

+  if ((Fptr = fopen (FileNameCopy, "r")) == NULL) {

+    //

+    // Try to find it among the paths.

+    //

+    Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy));

+    if (Fptr == NULL) {

+      //

+      // If this is not the top-level file, and the command-line argument

+      // said to ignore missing files, then return ok

+      //

+      if (NestDepth != START_NEST_DEPTH) {

+        if (mGlobals.IgnoreNotFound) {

+          if (!mGlobals.QuietMode) {

+            DebugMsg (NULL, 0, 0, FileNameCopy, "could not find file");

+          }

+

+          return STATUS_SUCCESS;

+        } else {

+          Error (NULL, 0, 0, FileNameCopy, "could not find file");

+          return STATUS_ERROR;

+        }

+      } else {

+        //

+        // Top-level (first) file. Emit an error.

+        //

+        Error (NULL, 0, 0, FileNameCopy, "could not find file");

+        return STATUS_ERROR;

+      }

+    }

+  }

+  //

+  // Print the dependency, with string substitution

+  //

+  PrintDependency (TargetFileName, FileNameCopy);

+

+  //

+  // Now read in lines and find all #include lines. Allow them to indent, and

+  // to put spaces between the # and include.

+  //

+  LineNum = 0;

+  while ((fgets (Line, sizeof (Line), Fptr) != NULL) && (Status == STATUS_SUCCESS)) {

+    LineNum++;

+    Cptr = Line;

+    //

+    // Skip preceeding spaces on the line

+    //

+    while (*Cptr && (isspace (*Cptr))) {

+      Cptr++;

+    }

+    //

+    // Check for # character

+    //

+    if (*Cptr == '#') {

+      Cptr++;

+      //

+      // Check for "include"

+      //

+      while (*Cptr && (isspace (*Cptr))) {

+        Cptr++;

+      }

+

+      if (strncmp (Cptr, "include", 7) == 0) {

+        //

+        // Skip over "include" and move on to filename as "file" or <file>

+        //

+        Cptr += 7;

+        while (*Cptr && (isspace (*Cptr))) {

+          Cptr++;

+        }

+

+        if (*Cptr == '<') {

+          EndChar = '>';

+        } else if (*Cptr == '"') {

+          EndChar = '"';

+        } else {

+          //

+          // Handle special #include MACRO_NAME(file)

+          // Set EndChar to null so we fall through on processing below.

+          //

+          EndChar = 0;

+          //

+          // Look for all the special include macros and convert accordingly.

+          //

+          for (Index = 0; mMacroConversion[Index].IncludeMacroName != NULL; Index++) {

+            //

+            // Save the start of the string in case some macros are substrings

+            // of others.

+            //

+            SaveCptr = Cptr;

+            if (strncmp (

+                  Cptr,

+                  mMacroConversion[Index].IncludeMacroName,

+                  strlen (mMacroConversion[Index].IncludeMacroName)

+                  ) == 0) {

+              //

+              // Skip over the macro name

+              //

+              Cptr += strlen (mMacroConversion[Index].IncludeMacroName);

+              //

+              // Skip over open parenthesis, blank spaces, then find closing

+              // parenthesis or blank space

+              //

+              while (*Cptr && (isspace (*Cptr))) {

+                Cptr++;

+              }

+

+              if (*Cptr == '(') {

+                Cptr++;

+                while (*Cptr && (isspace (*Cptr))) {

+                  Cptr++;

+                }

+

+                EndPtr = Cptr;

+                while (*EndPtr && !isspace (*EndPtr) && (*EndPtr != ')')) {

+                  EndPtr++;

+                }

+

+                *EndPtr = 0;

+                //

+                // Create the path

+                //

+                strcpy (MacroIncludeFileName, mMacroConversion[Index].PathName);

+                strcat (MacroIncludeFileName, Cptr);

+                strcat (MacroIncludeFileName, "\\");

+                strcat (MacroIncludeFileName, Cptr);

+                strcat (MacroIncludeFileName, ".h");

+                //

+                // Process immediately, then break out of the outside FOR loop.

+                //

+                Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles);

+                break;

+              }

+            }

+            //

+            // Restore the start

+            //

+            Cptr = SaveCptr;

+          }

+          //

+          // Don't recognize the include line? Ignore it. We assume that the

+          // file compiles anyway.

+          //

+          if (mMacroConversion[Index].IncludeMacroName == NULL) {

+            //

+            // Warning (FileNameCopy, LineNum, 0, "could not parse line", NULL);

+            // Status = STATUS_WARNING;

+            //

+          }

+        }

+        //

+        // Process "normal" includes. If the endchar is 0, then the

+        // file has already been processed. Otherwise look for the

+        // endchar > or ", and process the include file.

+        //

+        if (EndChar != 0) {

+          Cptr++;

+          EndPtr = Cptr;

+          while (*EndPtr && (*EndPtr != EndChar)) {

+            EndPtr++;

+          }

+

+          if (*EndPtr == EndChar) {

+            //

+            // If we're processing it, do it

+            //

+            if ((EndChar != '>') || (!mGlobals.NoSystem)) {

+              //

+              // Null terminate the filename and try to process it.

+              //

+              *EndPtr = 0;

+              Status  = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles);

+            }

+          } else {

+            Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar);

+            Status = STATUS_WARNING;

+            goto Finish;

+          }

+        }

+      }

+    }

+  }

+

+Finish:

+  //

+  // Close open files and return status

+  //

+  if (Fptr != NULL) {

+    fclose (Fptr);

+  }

+

+  return Status;

+}

+

+static

+void

+PrintDependency (

+  INT8    *TargetFileName,

+  INT8    *DependentFile

+  )

+/*++

+

+Routine Description:

+

+  Given a target (.obj) file name, and a dependent file name, do any string

+  substitutions (per the command line options) on the file names, then

+  print the dependency line of form:

+  

+  TargetFileName : DependentFile

+  

+Arguments:

+

+  TargetFileName - build target file name

+  DependentFile  - file on which TargetFileName depends

+

+Returns:

+

+  None

+  

+--*/

+{

+  INT8  Str[MAX_PATH];

+

+  //

+  // Go through the symbols and do replacements

+  //

+  strcpy (Str, TargetFileName);

+  ReplaceSymbols (Str, sizeof (Str));

+  fprintf (mGlobals.OutFptr, "%s : ", Str);

+  strcpy (Str, DependentFile);

+  ReplaceSymbols (Str, sizeof (Str));

+  fprintf (mGlobals.OutFptr, "%s\n", Str);

+}

+

+static

+void

+ReplaceSymbols (

+  INT8    *Str,

+  UINT32  StrSize

+  )

+{

+  SYMBOL  *Sym;

+  INT8    StrCopy[MAX_LINE_LEN];

+  INT8    *From;

+  INT8    *To;

+  BOOLEAN Replaced;

+

+  //

+  // Go through the entire string to look for replacement strings at

+  // every position.

+  //

+  From  = Str;

+  To    = StrCopy;

+  while (*From) {

+    //

+    // Copy the character

+    //

+    *To       = *From;

+    Replaced  = FALSE;

+    //

+    // Go through each symbol and try to find a string substitution

+    //

+    Sym = mGlobals.SymbolTable;

+    while (Sym != NULL) {

+      if (strnicmp (From, Sym->Value, strlen (Sym->Value)) == 0) {

+        //

+        // Replace the string, then advance the pointers past the

+        // replaced strings

+        //

+        strcpy (To, Sym->Name);

+        To += strlen (Sym->Name);

+        From += strlen (Sym->Value);

+        Replaced = TRUE;

+        //

+        // Break from the while()

+        //

+        break;

+      } else {

+        Sym = Sym->Next;

+      }

+    }

+

+    if (!Replaced) {

+      From++;

+      To++;

+    }

+  }

+  //

+  // Null terminate, and return it

+  //

+  *To = 0;

+  if (strlen (StrCopy) < StrSize) {

+    strcpy (Str, StrCopy);

+  }

+}

+//

+// Given a filename, try to find it along the include paths.

+//

+static

+FILE *

+FindFile (

+  INT8    *FileName,

+  UINT32  FileNameLen

+  )

+{

+  FILE        *Fptr;

+  STRING_LIST *List;

+  STRING_LIST *SubDir;

+  INT8        FullFileName[MAX_PATH * 2];

+

+  //

+  // Traverse the list of paths and try to find the file

+  //

+  List = mGlobals.IncludePaths;

+  while (List != NULL) {

+    //

+    // Put the path and filename together

+    //

+    if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) {

+      Error (

+        __FILE__,

+        __LINE__,

+        0,

+        "application error",

+        "cannot concatenate '%s' + '%s'",

+        List->Str,

+        FileName

+        );

+      return NULL;

+    }

+    //

+    // Append the filename to this include path and try to open the file.

+    //

+    strcpy (FullFileName, List->Str);

+    strcat (FullFileName, FileName);

+    if ((Fptr = fopen (FullFileName, "r")) != NULL) {

+      //

+      // Return the file name

+      //

+      if (FileNameLen <= strlen (FullFileName)) {

+        Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length");

+        //

+        // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName);

+        //

+        return NULL;

+      }

+

+      strcpy (FileName, FullFileName);

+      return Fptr;

+    }

+    //

+    // Didn't find it there. Now try this directory with every subdirectory

+    // the user specified on the command line

+    //

+    for (SubDir = mGlobals.SubDirs; SubDir != NULL; SubDir = SubDir->Next) {

+      strcpy (FullFileName, List->Str);

+      strcat (FullFileName, SubDir->Str);

+      strcat (FullFileName, FileName);

+      if ((Fptr = fopen (FullFileName, "r")) != NULL) {

+        //

+        // Return the file name

+        //

+        if (FileNameLen <= strlen (FullFileName)) {

+          Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length");

+          return NULL;

+        }

+

+        strcpy (FileName, FullFileName);

+        return Fptr;

+      }

+    }

+

+    List = List->Next;

+  }

+  //

+  // Not found

+  //

+  return NULL;

+}

+//

+// Process the command-line arguments

+//

+static

+STATUS

+ProcessArgs (

+  int   Argc,

+  char  *Argv[]

+  )

+{

+  STRING_LIST *NewList;

+  STRING_LIST *LastIncludePath;

+  STRING_LIST *LastSourceFile;

+  SYMBOL      *Symbol;

+  int         Index;

+  //

+  // Clear our globals

+  //

+  memset ((char *) &mGlobals, 0, sizeof (mGlobals));

+  mGlobals.NoDupes = TRUE;

+  //

+  // Skip program name

+  //

+  Argc--;

+  Argv++;

+  //

+  // Initialize locals

+  //

+  LastIncludePath = NULL;

+  LastSourceFile  = NULL;

+  //

+  // Process until no more args

+  //

+  while (Argc) {

+    //

+    // -i path    add include search path

+    //

+    if (stricmp (Argv[0], "-i") == 0) {

+      //

+      // check for one more arg

+      //

+      if (Argc > 1) {

+        //

+        // Allocate memory for a new list element, fill it in, and

+        // add it to our list of include paths. Always make sure it

+        // has a "\" on the end of it.

+        //

+        NewList = malloc (sizeof (STRING_LIST));

+        if (NewList == NULL) {

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        NewList->Next = NULL;

+        NewList->Str  = malloc (strlen (Argv[1]) + 2);

+        if (NewList->Str == NULL) {

+          free (NewList);

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        strcpy (NewList->Str, Argv[1]);

+        if (NewList->Str[strlen (NewList->Str) - 1] != '\\') {

+          strcat (NewList->Str, "\\");

+        }

+        //

+        // Add it to the end of the our list of include paths

+        //

+        if (mGlobals.IncludePaths == NULL) {

+          mGlobals.IncludePaths = NewList;

+        } else {

+          LastIncludePath->Next = NewList;

+        }

+

+        LastIncludePath = NewList;

+        //

+        // fprintf (stdout, "Added path: %s\n", NewList->Str);

+        //

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires an include path");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-f") == 0) {

+      //

+      // Check for one more arg

+      //

+      if (Argc > 1) {

+        //

+        // Allocate memory for a new list element, fill it in, and

+        // add it to our list of source files.

+        //

+        NewList = malloc (sizeof (STRING_LIST));

+        if (NewList == NULL) {

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        NewList->Next = NULL;

+        //

+        // Allocate space to replace ".c" with ".obj", plus null termination

+        //

+        NewList->Str = malloc (strlen (Argv[1]) + 5);

+        if (NewList->Str == NULL) {

+          free (NewList);

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        strcpy (NewList->Str, Argv[1]);

+        if (mGlobals.SourceFiles == NULL) {

+          mGlobals.SourceFiles = NewList;

+        } else {

+          LastSourceFile->Next = NewList;

+        }

+

+        LastSourceFile = NewList;

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires a file name");

+        Usage ();

+        return STATUS_ERROR;

+      }

+      //

+      // The C compiler first looks for #include files in the directory where

+      // the source file came from. Add the file's source directory to the

+      // list of include paths.

+      //

+      NewList = malloc (sizeof (STRING_LIST));

+      if (NewList == NULL) {

+        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+        return STATUS_ERROR;

+      }

+

+      NewList->Next = NULL;

+      NewList->Str  = malloc (strlen (Argv[1]) + 3);

+      if (NewList->Str == NULL) {

+        free (NewList);

+        Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+        return STATUS_ERROR;

+      }

+

+      strcpy (NewList->Str, Argv[1]);

+      //

+      // Back up in the source file name to the last backslash and terminate after it.

+      //

+      for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\'); Index--)

+        ;

+      if (Index < 0) {

+        strcpy (NewList->Str, ".\\");

+      } else {

+        NewList->Str[Index + 1] = 0;

+      }

+      //

+      // Add it to the end of the our list of include paths

+      //

+      if (mGlobals.IncludePaths == NULL) {

+        mGlobals.IncludePaths = NewList;

+      } else {

+        LastIncludePath->Next = NewList;

+      }

+

+      if (mGlobals.Verbose) {

+        fprintf (stdout, "Adding include path: %s\n", NewList->Str);

+      }

+

+      LastIncludePath = NewList;

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-s") == 0) {

+      //

+      // -s subdir    add subdirectory subdir to list of subdirecties to scan.

+      // Check for one more arg first.

+      //

+      if (Argc > 1) {

+        //

+        // Allocate memory for a new list element, fill it in, and

+        // add it to our list of subdirectory include paths. Always

+        // make sure it has a "\" on the end of it.

+        //

+        NewList = malloc (sizeof (STRING_LIST));

+        if (NewList == NULL) {

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        NewList->Str = malloc (strlen (Argv[1]) + 2);

+        if (NewList->Str == NULL) {

+          free (NewList);

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        strcpy (NewList->Str, Argv[1]);

+        if (NewList->Str[strlen (NewList->Str) - 1] != '\\') {

+          strcat (NewList->Str, "\\");

+        }

+

+        NewList->Next     = mGlobals.SubDirs;

+        mGlobals.SubDirs  = NewList;

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires a subdirectory name");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-sub") == 0) {

+      //

+      // -sub symname symvalue  to do string substitution in the output

+      //

+      if (Argc > 2) {

+        //

+        // Allocate memory for the symbol object

+        //

+        Symbol = malloc (sizeof (SYMBOL));

+        if (Symbol == NULL) {

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+        //

+        // Allocate memory for the symbol name and value, then save copies

+        //

+        Symbol->Name = malloc (strlen (Argv[1]) + 1);

+        if (Symbol->Name == NULL) {

+          free (Symbol);

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        strcpy (Symbol->Name, Argv[1]);

+        Symbol->Value = malloc (strlen (Argv[2]) + 1);

+        if (Symbol->Value == NULL) {

+          free (Symbol->Name);

+          free (Symbol);

+          Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);

+          return STATUS_ERROR;

+        }

+

+        strcpy (Symbol->Value, Argv[2]);

+        //

+        // Add it to the list

+        //

+        Symbol->Next          = mGlobals.SymbolTable;

+        mGlobals.SymbolTable  = Symbol;

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires a symbol name and value");

+        Usage ();

+        return STATUS_ERROR;

+      }

+      //

+      // Skip over args

+      //

+      Argc -= 2;

+      Argv += 2;

+    } else if (stricmp (Argv[0], "-nosystem") == 0) {

+      mGlobals.NoSystem = TRUE;

+    } else if (stricmp (Argv[0], "-nodupes") == 0) {

+      mGlobals.NoDupes = TRUE;

+    } else if (stricmp (Argv[0], "-nodups") == 0) {

+      mGlobals.NoDupes = TRUE;

+    } else if (stricmp (Argv[0], "-target") == 0) {

+      //

+      // -target TargetFileName  - Target object file (only one allowed right

+      // now) is TargetFileName rather than SourceFile.obj

+      //

+      if (Argc > 1) {

+        strcpy (mGlobals.TargetFileName, Argv[1]);

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires a target file name");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-usesumdeps") == 0) {

+      //

+      // -usesumdeps Path - if we find an included file xxx.h, and file

+      // Path/xxx.dep exists, list Path/xxx.dep as a dependency rather than

+      // xxx.h and don't parse xxx.h. This allows you to create a dependency

+      // file for a commonly included file, and have its dependency file updated

+      // only if its included files are updated. Then anyone else including this

+      // common include file can simply have a dependency on that file's .dep file

+      // rather than on all the files included by it. Confusing enough?

+      //

+      mGlobals.UseSumDeps = 1;

+      if (Argc > 1) {

+        strcpy (mGlobals.SumDepsPath, Argv[1]);

+        //

+        // Add slash on end if not there

+        //

+        if (mGlobals.SumDepsPath[strlen (mGlobals.SumDepsPath) - 1] != '\\') {

+          strcat (mGlobals.SumDepsPath, "\\");

+        }

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires path to summary dependency files");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+

+    } else if (stricmp (Argv[0], "-o") == 0) {

+      //

+      // -o OutputFileName    - specify an output filename for dependency list

+      // check for one more arg

+      //

+      if (Argc > 1) {

+        //

+        // Try to open the file

+        //

+        if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) {

+          Error (NULL, 0, 0, Argv[1], "could not open file for writing");

+          return STATUS_ERROR;

+        }

+

+        mGlobals.OutFileName = Argv[1];

+      } else {

+        Error (NULL, 0, 0, Argv[0], "option requires output file name");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-v") == 0) {

+      mGlobals.Verbose = TRUE;

+    } else if (stricmp (Argv[0], "-neverfail") == 0) {

+      mGlobals.NeverFail = TRUE;

+    } else if (stricmp (Argv[0], "-q") == 0) {

+      mGlobals.QuietMode = TRUE;

+    } else if (stricmp (Argv[0], "-ignorenotfound") == 0) {

+      mGlobals.IgnoreNotFound = TRUE;

+    } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {

+      Usage ();

+      return STATUS_ERROR;

+    } else {

+      Error (NULL, 0, 0, Argv[0], "unrecognized option");

+      Usage ();

+      return STATUS_ERROR;

+    }

+

+    Argc--;

+    Argv++;

+  }

+  //

+  // Had to specify at least one source file

+  //

+  if (mGlobals.SourceFiles == NULL) {

+    Error (NULL, 0, 0, "must specify one source file name", NULL);

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Assume output to stdout if not specified

+  //

+  if (mGlobals.OutFptr == NULL) {

+    mGlobals.OutFptr = stdout;

+  }

+

+  return STATUS_SUCCESS;

+}

+//

+// Free the global string lists we allocated memory for

+//

+static

+void

+FreeLists (

+  VOID

+  )

+{

+  STRING_LIST *Temp;

+  SYMBOL      *NextSym;

+

+  //

+  // printf ("Free lists.....");

+  //

+  // Traverse the include paths, freeing each

+  // printf ("freeing include paths\n");

+  //

+  while (mGlobals.IncludePaths != NULL) {

+    Temp = mGlobals.IncludePaths->Next;

+    //

+    // printf ("Freeing include path string '%s' at 0x%X\n",

+    //  mGlobals.IncludePaths->Str, (int)(mGlobals.IncludePaths->Str));

+    //

+    free (mGlobals.IncludePaths->Str);

+    //

+    // printf ("Freeing include path object at 0x%X\n", (int)(mGlobals.IncludePaths));

+    //

+    free (mGlobals.IncludePaths);

+    mGlobals.IncludePaths = Temp;

+  }

+  //

+  // Traverse the source files, freeing each

+  //

+  while (mGlobals.SourceFiles != NULL) {

+    Temp = mGlobals.SourceFiles->Next;

+    free (mGlobals.SourceFiles->Str);

+    free (mGlobals.SourceFiles);

+    mGlobals.SourceFiles = Temp;

+  }

+  //

+  // Traverse the subdirectory list, freeing each

+  //

+  while (mGlobals.SubDirs != NULL) {

+    Temp = mGlobals.SubDirs->Next;

+    free (mGlobals.SubDirs->Str);

+    free (mGlobals.SubDirs);

+    mGlobals.SubDirs = Temp;

+  }

+  //

+  // Free the symbol table

+  //

+  while (mGlobals.SymbolTable != NULL) {

+    NextSym = mGlobals.SymbolTable->Next;

+    free (mGlobals.SymbolTable->Name);

+    free (mGlobals.SymbolTable->Value);

+    mGlobals.SymbolTable = NextSym;

+  }

+  //

+  // printf ("done\n");

+  //

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Print usage information for this utility.

+  

+Arguments:

+

+  None.

+

+Returns:

+

+  Nothing.

+  

+--*/

+{

+  int               Index;

+  static const char *Str[] = {

+    UTILITY_NAME " -- make dependencies",

+    "  Usage: MakeDeps [options]",

+    "    Options include:",

+    "      -h or -?         for this help information",

+    "      -f SourceFile    add SourceFile to list of files to scan",

+    "      -i IncludePath   add IncludePath to list of search paths",

+    "      -o OutputFile    write output dependencies to OutputFile",

+    "      -s SubDir        for each IncludePath, also search IncludePath\\SubDir",

+    "      -v               for verbose output",

+    "      -ignorenotfound  don't warn for files not found",

+    "      -target Target   for single SourceFile, target is Target, not SourceFile.obj",

+    "      -q               quiet mode to not report files not found if ignored",

+    "      -sub sym str     replace all occurrances of 'str' with 'sym' in the output",

+    "      -nosystem        not process system <include> files",

+    "      -neverfail       always return a success return code",

+    //

+    //    "      -nodupes         keep track of include files, don't rescan duplicates",

+    //

+    "      -usesumdeps path use summary dependency files in 'path' directory.",

+    "",

+    NULL

+  };

+  for (Index = 0; Str[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Str[Index]);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/MakeDeps/build.xml b/edk2/Tools/Source/TianoTools/MakeDeps/build.xml
new file mode 100755
index 0000000..10cad4e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/MakeDeps/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK MakeDeps Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="MakeDeps"/>

+  <property name="FileSet" value="*.c *.h"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_131.txt b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_131.txt
new file mode 100644
index 0000000..500d84f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_131.txt
@@ -0,0 +1,522 @@
+CHANGES FROM 1.31

+

+This file contains the migration of PCCTS from 1.31 in the order that

+changes were made.  1.32b7 is the last beta before full 1.32.

+Terence Parr, Parr Research Corporation 1995.

+

+

+======================================================================

+1.32b1

+Added Russell Quong to banner, changed banner for output slightly

+Fixed it so that you have before / after actions for C++ in class def

+Fixed bug in optimizer that made it sometimes forget to set internal

+        token pointers.  Only showed up when a {...} was in the "wrong spot".

+

+======================================================================

+1.32b2

+Added fixes by Dave Seidel for PC compilers in 32 bit mode (config.h

+and set.h).

+

+======================================================================

+1.32b3

+Fixed hideous bug in code generator for wildcard and for ~token op.

+

+from Dave Seidel

+

+   Added pcnames.bat

+   1. in antlr/main.c: change strcasecmp() to stricmp()

+

+   2. in dlg/output.c: use DLEXER_C instead on "DLexer.C"

+

+   3. in h/PBlackBox.h: use <iostream.h> instead of <stream.h>

+

+======================================================================

+1.32b4

+When the -ft option was used, any path prefix screwed up

+the gate on the .h files

+

+Fixed yet another bug due to the optimizer.

+

+The exception handling thing was a bit wacko:

+

+a : ( A B )? A B

+  | A C

+  ;

+  exception ...

+

+caused an exception if "A C" was the input.  In other words,

+it found that A C didn't match the (A B)? pred and caused

+an exception rather than trying the next alt.  All I did

+was to change the zzmatch_wsig() macros.

+

+Fixed some problems in gen.c relating to the name of token

+class bit sets in the output.

+

+Added the tremendously cool generalized predicate.  For the

+moment, I'll give this bried description.

+

+a : <<predicate>>? blah

+  | foo

+  ;

+

+This implies that (assuming blah and foo are syntactically

+ambiguous) "predicate" indicates the semantic validity of

+applying "blah".  If "predicate" is false, "foo" is attempted.

+

+Previously, you had to say:

+

+a : <<LA(1)==ID ? predicate : 1>>? ID

+  | ID

+  ;

+

+Now, you can simply use "predicate" without the ?: operator

+if you turn on ANTLR command line option: "-prc on".  This

+tells ANTLR to compute that all by itself.  It computes n

+tokens of lookahead where LT(n) or LATEXT(n) is the farthest

+ahead you look.

+

+If you give a predicate using "-prc on" that is followed

+by a construct that can recognize more than one n-sequence,

+you will get a warning from ANTLR.  For example,

+

+a : <<isTypeName(LT(1)->getText())>>? (ID|INT)

+  ;

+

+This is wrong because the predicate will be applied to INTs

+as well as ID's.  You should use this syntax to make

+the predicate more specific:

+

+a : (ID)? => <<isTypeName(LT(1)->getText())>>? (ID|INT)

+  ;

+

+which says "don't apply the predicate unless ID is the

+current lookahead context".

+

+You cannot currently have anything in the "(context)? =>"

+except sequences such as:

+

+( LPAREN ID | LPAREN SCOPE )? => <<pred>>?

+

+I haven't tested this THAT much, but it does work for the

+C++ grammar.

+

+======================================================================

+1.32b5

+

+Added getLine() to the ANTLRTokenBase and DLGBasedToken classes

+left line() for backward compatibility.

+----

+Removed SORCERER_TRANSFORM from the ast.h stuff.

+-------

+Fixed bug in code gen of ANTLR such that nested syn preds work more

+efficiently now.  The ANTLRTokenBuffer was getting very large

+with nested predicates.

+------

+Memory leak is now gone from ANTLRTokenBuf; all tokens are deleted.

+For backward compatibility reasons, you have to say parser->deleteTokens()

+or mytokenbuffer->deleteTokens() but later it will be the default mode.

+Say this after the parser is constructed. E.g.,

+

+    ParserBlackBox<DLGLexer, MyParser, ANTLRToken> p(stdin);

+    p.parser()->deleteTokens();

+    p.parser()->start_symbol();

+

+

+==============================

+1.32b6

+

+Changed so that deleteTokens() will do a delete ((ANTLRTokenBase *))

+on the ptr.  This gets the virtual destructor.

+

+Fixed some weird things in the C++ header files (a few return types).

+

+Made the AST routines correspond to the book and SORCERER stuff.

+

+New token stuff:  See testcpp/14/test.g

+

+ANTLR accepts a #pragma gc_tokens which says

+[1]     Generate label = copy(LT(1)) instead of label=LT(1) for

+        all labeled token references.

+[2]     User now has to define ANTLRTokenPtr (as a class or a typedef

+        to just a pointer) as well as the ANTLRToken class itself.

+		See the example.

+

+To delete tokens in token buffer, use deleteTokens() message on parser.

+

+        All tokens that fall off the ANTLRTokenBuffer get deleted

+        which is what currently happens when deleteTokens() message

+        has been sent to token buffer.

+

+We always generate ANTLRTokenPtr instead of 'ANTLRToken *' now.

+Then if no pragma set, ANTLR generates a

+

+        class ANTLRToken;

+        typedef ANTLRToken *ANTLRTokenPtr;

+

+in each file.

+

+Made a warning for x:rule_ref <<$x>>; still no warning for $i's, however.

+class BB {

+

+a : x:b y:A <<$x

+$y>>

+  ;

+

+b : B;

+

+}

+generates

+Antlr parser generator   Version 1.32b6   1989-1995

+test.g, line 3: error: There are no token ptrs for rule references: '$x'

+

+===================

+1.32b7:

+

+[With respect to token object garbage collection (GC), 1.32b7

+ backtracks from 1.32b6, but results in better and less intrusive GC.

+ This is the last beta version before full 1.32.]

+

+BIGGEST CHANGES:

+

+o	The "#pragma gc_tokens" is no longer used.

+

+o	.C files are now .cpp files (hence, makefiles will have to

+	be changed; or you can rerun genmk).  This is a good move,

+	but causes some backward incompatibility problems.  You can

+	avoid this by changing CPP_FILE_SUFFIX to ".C" in pccts/h/config.h.

+

+o	The token object class hierarchy has been flattened to include

+	only three classes: ANTLRAbstractToken, ANTLRCommonToken, and

+	ANTLRCommonNoRefCountToken.  The common token now does garbage

+	collection via ref counting.

+

+o	"Smart" pointers are now used for garbage collection.  That is,

+	ANTLRTokenPtr is used instead of "ANTLRToken *".

+

+o	The antlr.1 man page has been cleaned up slightly.

+

+o	The SUN C++ compiler now complains less about C++ support code.

+

+o	Grammars which subclass ANTLRCommonToken must wrap all token

+	pointer references in mytoken(token_ptr).  This is the only

+	serious backward incompatibility.  See below.

+

+

+MINOR CHANGES:

+

+--------------------------------------------------------

+1	deleteTokens()

+

+The deleteTokens() message to the parser or token buffer has been changed

+to one of:

+

+    void noGarbageCollectTokens()   { inputTokens->noGarbageCollectTokens(); }

+    void garbageCollectTokens()     { inputTokens->garbageCollectTokens(); }

+

+The token buffer deletes all non-referenced tokens by default now.

+

+--------------------------------------------------------

+2	makeToken()

+

+The makeToken() message returns a new type.  The function should look

+like:

+

+    virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,

+                                          ANTLRChar *txt,

+                                          int line)

+    {

+        ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt);

+        t->setLine(line);

+        return t;

+    }

+

+--------------------------------------------------------

+3	TokenType

+

+Changed TokenType-> ANTLRTokenType  (often forces changes in AST defs due

+to #[] constructor called to AST(tokentype, string)).

+

+--------------------------------------------------------

+4	AST()

+

+You must define AST(ANTLRTokenPtr t) now in your AST class definition.

+You might also have to include ATokPtr.h above the definition; e.g.,

+if AST is defined in a separate file, such as AST.h, it's a good idea

+to include ATOKPTR_H (ATokPtr.h).  For example,

+

+	#include ATOKPTR_H

+	class AST : public ASTBase {

+	protected:

+	    ANTLRTokenPtr token;

+	public:

+	    AST(ANTLRTokenPtr t) { token = t; }

+	    void preorder_action() {

+	        char *s = token->getText();

+	        printf(" %s", s);

+	    }

+	};

+

+Note the use of smart pointers rather than "ANTLRToken *".

+

+--------------------------------------------------------

+5	SUN C++

+

+From robertb oakhill.sps.mot.com Bob Bailey. Changed ANTLR C++ output

+to avoid an error in Sun C++ 3.0.1.  Made "public" return value

+structs created to hold multiple return values public.

+

+--------------------------------------------------------

+6	genmk

+

+Fixed genmk so that target List.* is not included anymore.  It's

+called SList.* anyway.

+

+--------------------------------------------------------

+7	\r vs \n

+

+Scott Vorthmann <vorth cmu.edu> fixed antlr.g in ANTLR so that \r

+is allowed as the return character as well as \n.

+

+--------------------------------------------------------

+8	Exceptions

+

+Bug in exceptions attached to labeled token/tokclass references.  Didn't gen

+code for exceptions.  This didn't work:

+

+a : "help" x:ID

+  ;

+        exception[x]

+        catch MismatchedToken : <<printf("eh?\n");>>

+

+Now ANTLR generates (which is kinda big, but necessary):

+

+        if ( !_match_wsig(ID) ) {

+                if ( guessing ) goto fail;

+                _signal=MismatchedToken;

+                switch ( _signal ) {

+                case MismatchedToken :

+                        printf("eh?\n");

+                        _signal = NoSignal;

+                        break;

+                default :

+                        goto _handler;

+                }

+        }

+

+which implies that you can recover and continue parsing after a missing/bad

+token reference.

+

+--------------------------------------------------------

+9	genmk

+

+genmk now correctly uses config file for CPP_FILE_SUFFIX stuff.

+

+--------------------------------------------------------

+10	general cleanup / PURIFY

+

+Anthony Green <green vizbiz.com> suggested a bunch of good general

+clean up things for the code; he also suggested a few things to

+help out the "PURIFY" memory allocation checker.

+

+--------------------------------------------------------

+11	$-variable references.

+

+Manuel ORNATO indicated that a $-variable outside of a rule caused

+ANTLR to crash.  I fixed this.

+

+12	Tom Moog suggestion

+

+Fail action of semantic predicate needs "{}" envelope.  FIXED.

+

+13	references to LT(1).

+

+I have enclosed all assignments such as:

+

+             _t22 = (ANTLRTokenPtr)LT(1);

+

+in "if ( !guessing )" so that during backtracking the reference count

+for token objects is not increased.

+

+

+TOKEN OBJECT GARBAGE COLLECTION

+

+1	INTRODUCTION

+

+The class ANTLRCommonToken is now garbaged collected through a "smart"

+pointer called ANTLRTokenPtr using reference counting.  Any token

+object not referenced by your grammar actions is destroyed by the

+ANTLRTokenBuffer when it must make room for more token objects.

+Referenced tokens are then destroyed in your parser when local

+ANTLRTokenPtr objects are deleted.  For example,

+

+a : label:ID ;

+

+would be converted to something like:

+

+void yourclass::a(void)

+{

+	zzRULE;

+	ANTLRTokenPtr label=NULL;	// used to be ANTLRToken *label;

+        zzmatch(ID);

+        label = (ANTLRTokenPtr)LT(1);

+	consume();

+	...

+}

+

+When the "label" object is destroyed (it's just a pointer to your

+input token object LT(1)), it decrements the reference count on the

+object created for the ID.  If the count goes to zero, the object

+pointed by label is deleted.

+

+To correctly manage the garbage collection, you should use

+ANTLRTokenPtr instead of "ANTLRToken *".  Most ANTLR support code

+(visible to the user) has been modified to use the smart pointers.

+

+***************************************************************

+Remember that any local objects that you create are not deleted when a

+lonjmp() is executed.  Unfortunately, the syntactic predicates (...)?

+use setjmp()/longjmp().  There are some situations when a few tokens

+will "leak".

+***************************************************************

+

+2	DETAILS

+

+o	The default is to perform token object garbage collection.

+	You may use parser->noGarbageCollectTokens() to turn off

+	garbage collection.

+

+

+o	The type ANTLRTokenPtr is always defined now (automatically).

+	If you do not wish to use smart pointers, you will have to

+	redefined ANTLRTokenPtr by subclassing, changing the header

+	file or changing ANTLR's code generation (easy enough to

+	do in gen.c).

+

+o	If you don't use ParserBlackBox, the new initialization sequence is:

+

+	    ANTLRTokenPtr aToken = new ANTLRToken;

+	    scan.setToken(mytoken(aToken));

+

+	where mytoken(aToken) gets an ANTLRToken * from the smart pointer.

+

+o	Define C++ preprocessor symbol DBG_REFCOUNTTOKEN to see a bunch of

+	debugging stuff for reference counting if you suspect something.

+

+

+3	WHY DO I HAVE TO TYPECAST ALL MY TOKEN POINTERS NOW??????

+

+If you subclass ANTLRCommonToken and then attempt to refer to one of

+your token members via a token pointer in your grammar actions, the

+C++ compiler will complain that your token object does not have that

+member.  For example, if you used to do this

+

+<<

+class ANTLRToken : public ANTLRCommonToken {

+        int muck;

+	...

+};

+>>

+

+class Foo {

+a : t:ID << t->muck = ...; >> ;

+}

+

+Now, you must do change the t->muck reference to:

+

+a : t:ID << mytoken(t)->muck = ...; >> ;

+

+in order to downcast 't' to be an "ANTLRToken *" not the

+"ANTLRAbstractToken *" resulting from ANTLRTokenPtr::operator->().

+The macro is defined as:

+

+/*

+ * Since you cannot redefine operator->() to return one of the user's

+ * token object types, we must down cast.  This is a drag.  Here's

+ * a macro that helps.  template: "mytoken(a-smart-ptr)->myfield".

+ */

+#define mytoken(tp) ((ANTLRToken *)(tp.operator->()))

+

+You have to use macro mytoken(grammar-label) now because smart

+pointers are not specific to a parser's token objects.  In other

+words, the ANTLRTokenPtr class has a pointer to a generic

+ANTLRAbstractToken not your ANTLRToken; the ANTLR support code must

+use smart pointers too, but be able to work with any kind of

+ANTLRToken.  Sorry about this, but it's C++'s fault not mine.  Some

+nebulous future version of the C++ compilers should obviate the need

+to downcast smart pointers with runtime type checking (and by allowing

+different return type of overridden functions).

+

+A way to have backward compatible code is to shut off the token object

+garbage collection; i.e., use parser->noGarbageCollectTokens() and

+change the definition of ANTLRTokenPtr (that's why you get source code

+<wink>).

+

+

+PARSER EXCEPTION HANDLING

+

+I've noticed some weird stuff with the exception handling.  I intend

+to give this top priority for the "book release" of ANTLR.

+

+==========

+1.32 Full Release

+

+o	Changed Token class hierarchy to be (Thanks to Tom Moog):

+

+        ANTLRAbstractToken

+          ANTLRRefCountToken

+             ANTLRCommonToken

+          ANTLRNoRefCountCommonToken

+

+o	Added virtual panic() to ANTLRAbstractToken.  Made ANTLRParser::panic()

+	virtual also.

+

+o	Cleaned up the dup() stuff in AST hierarchy to use shallowCopy() to

+	make node copies.  John Farr at Medtronic suggested this.  I.e.,

+	if you want to use dup() with either ANTLR or SORCERER or -transform

+	mode with SORCERER, you must defined shallowCopy() as:

+

+	virtual PCCTS_AST *shallowCopy()

+	{

+	    return new AST;

+	    p->setDown(NULL);

+	    p->setRight(NULL);

+	    return p;

+	}

+

+	or

+

+	virtual PCCTS_AST *shallowCopy()

+	{

+	    return new AST(*this);

+	}

+	

+	if you have defined a copy constructor such as

+

+	AST(const AST &t)	// shallow copy constructor

+	{

+		token = t.token;

+		iconst = t.iconst;

+		setDown(NULL);

+		setRight(NULL);

+	}

+

+o	Added a warning with -CC and -gk are used together.  This is broken,

+	hence a warning is appropriate.

+

+o	Added warning when #-stuff is used w/o -gt option.

+

+o	Updated MPW installation.

+

+o	"Miller, Philip W." <MILLERPW f1groups.fsd.jhuapl.edu> suggested

+	that genmk be use RENAME_OBJ_FLAG RENAME_EXE_FLAG instead of

+	hardcoding "-o" in genmk.c.

+

+o	made all exit() calls use EXIT_SUCCESS or EXIT_FAILURE.

+

+===========================================================================

+1.33

+

+EXIT_FAILURE and EXIT_SUCCESS were not always defined.  I had to modify

+a bunch of files to use PCCTS_EXIT_XXX, which forces a new version.  Sorry

+about that.

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_133.txt b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_133.txt
new file mode 100644
index 0000000..2128c4f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_133.txt
@@ -0,0 +1,2448 @@
+=======================================================================

+List of Implemented Fixes and Changes for Maintenance Releases of PCCTS

+=======================================================================

+

+                               DISCLAIMER

+

+ The software and these notes are provided "as is".  They may include

+ typographical or technical errors and their authors disclaims all

+ liability of any kind or nature for damages due to error, fault,

+ defect, or deficiency regardless of cause.  All warranties of any

+ kind, either express or implied, including, but not limited to, the

+ implied  warranties of merchantability and fitness for a particular

+ purpose are disclaimed.

+

+

+        -------------------------------------------------------

+        Note:  Items #153 to #1 are now in a separate file named

+                CHANGES_FROM_133_BEFORE_MR13.txt

+        -------------------------------------------------------

+        

+#312. (Changed in MR33) Bug caused by change #299.

+

+	In change #299 a warning message was suppressed when there was

+	no LT(1) in a semantic predicate and max(k,ck) was 1.  The 

+	changed caused the code which set a default predicate depth for

+	the semantic predicate to be left as 0 rather than set to 1.

+	

+	This manifested as an error at line #1559 of mrhost.c

+	

+	Reported by Peter Dulimov.

+	    

+#311. (Changed in MR33) Added sorcer/lib to Makefile.

+

+    Reported by Dale Martin.

+            

+#310. (Changed in MR32) In C mode zzastPush was spelled zzastpush in one case.

+

+    Reported by Jean-Claude Durand

+    

+#309. (Changed in MR32) Renamed baseName because of VMS name conflict

+

+    Renamed baseName to pcctsBaseName to avoid library name conflict with

+    VMS library routine.  Reported by Jean-François PIÉRONNE.

+    

+#308. (Changed in MR32) Used "template" as name of formal in C routine

+

+	In astlib.h routine ast_scan a formal was named "template".  This caused

+	problems when the C code was compiled with a C++ compiler.  Reported by

+	Sabyasachi Dey.

+            

+#307. (Changed in MR31) Compiler dependent bug in function prototype generation

+    

+    The code which generated function prototypes contained a bug which

+    was compiler/optimization dependent.  Under some circumstance an

+    extra character would be included in portions of a function prototype.

+    

+    Reported by David Cook.

+    

+#306. (Changed in MR30) Validating predicate following a token

+

+    A validating predicate which immediately followed a token match 

+    consumed the token after the predicate rather than before.  Prior

+    to this fix (in the following example) isValidTimeScaleValue() in

+    the predicate would test the text for TIMESCALE rather than for

+    NUMBER:

+     

+		time_scale :

+    		TIMESCALE

+    		<<isValidTimeScaleValue(LT(1)->getText())>>?

+    		ts:NUMBER

+    		( us:MICROSECOND << tVal = ...>>

+    		| ns:NANOSECOND << tVal = ...  >>

+    		)

+	

+	Reported by Adalbert Perbandt.

+	

+#305. (Changed in MR30) Alternatives with guess blocks inside (...)* blocks.

+

+	In MR14 change #175 fixed a bug in the prediction expressions for guess

+	blocks which were of the form (alpha)? beta.  Unfortunately, this

+	resulted in a new bug as exemplified by the example below, which computed

+	the first set for r as {B} rather than {B C}:

+	

+					r : ( (A)? B

+					    | C

+						)*

+  

+    This example doesn't make any sense as A is not a prefix of B, but it

+    illustrates the problem.  This bug did not appear for:

+    

+    				r : ( (A)?

+    				    | C

+    				    )*

+

+	because it does not use the (alpha)? beta form.

+

+	Item #175 fixed an asymmetry in ambiguity messages for the following

+	constructs which appear to have identical ambiguities (between repeating

+	the loop vs. exiting the loop).  MR30 retains this fix, but the implementation

+	is slightly different.

+	

+	          r_star : ( (A B)? )* A ;

+	          r_plus : ( (A B)? )+ A ;

+

+    Reported by Arpad Beszedes (beszedes inf.u-szeged.hu).

+    

+#304. (Changed in MR30) Crash when mismatch between output value counts.

+

+	For a rule such as:

+	

+		r1 : r2>[i,j];

+		r2 >[int i, int j] : A;

+		

+	If there were extra actuals for the reference to rule r2 from rule r1

+	there antlr would crash.  This bug was introduced by change #276.

+

+	Reported by Sinan Karasu.

+	

+#303. (Changed in MR30) DLGLexerBase::replchar

+

+	DLGLexerBase::replchar and the C mode routine zzreplchar did not work 

+	properly when the new character was 0.

+      

+    Reported with fix by Philippe Laporte

+

+#302. (Changed in MR28) Fix significant problems in initial release of MR27.

+

+#301. (Changed in MR27) Default tab stops set to 2 spaces.

+

+    To have antlr generate true tabs rather than spaces, use "antlr -tab 0".

+    To generate 4 spaces per tab stop use "antlr -tab 4"

+    

+#300. (Changed in MR27)

+

+	Consider the following methods of constructing an AST from ID:

+	

+        rule1!

+                : id:ID << #0 = #[id]; >> ;

+        

+        rule2!

+                : id:ID << #0 = #id; >> ;

+        

+        rule3

+                : ID ;

+        

+        rule4

+                : id:ID << #0 = #id; >> ;

+        

+    For rule_2, the AST corresponding to id would always be NULL.  This

+    is because the user explicitly suppressed AST construction using the

+    "!" operator on the rule.  In MR27 the use of an AST expression

+    such as #id overrides the "!" operator and forces construction of

+    the AST.

+    

+    This fix does not apply to C mode ASTs when the ASTs are referenced

+    using numbers rather than symbols.

+

+	For C mode, this requires that the (optional) function/macro zzmk_ast

+	be defined.  This functions copies information from an attribute into

+	a previously allocated AST.

+

+    Reported by Jan Langer (jan langernetz.de)

+

+#299. (Changed in MR27) Don't warn if k=1 and semantic predicate missing LT(i)

+

+    If a semantic does not have a reference to LT(i) or (C mode LATEXT(i))

+    then pccts doesn't know how many lookahead tokens to use for context.

+    However, if max(k,ck) is 1 then there is really only one choice and

+    the warning is unnecessary.

+    

+#298. (Changed in MR27) Removed "register" for lastpos in dlgauto.c zzgettok

+

+#297. (Changed in MR27) Incorrect prototypes when used with classic C

+

+    There were a number of errors in function headers when antlr was

+    built with compilers that do not have __STDC__ or __cplusplus set.

+    

+    The functions which have variable length argument lists now use

+    PCCTS_USE_STDARG rather than __USE_PROTOTYPES__ to determine

+    whether to use stdargs or varargs.

+

+#296. (Changed in MR27) Complex return types in rules.

+

+    The following return type was not properly handled when 

+    unpacking a struct with containing multiple return values:

+    

+      rule > [int i, IIR_Bool (IIR_Decl::*constraint)()] : ...    

+

+    Instead of using "constraint", the program got lost and used

+    an empty string.

+    

+    Reported by P.A. Wilsey.

+

+#295. (Changed in MR27) Extra ";" following zzGUESS_DONE sometimes.

+

+    Certain constructs with guess blocks in MR23 led to extra ";"

+    preceding the "else" clause of an "if".

+

+    Reported by P.A. Wilsey.

+    

+#294. (Changed in MR27) Infinite loop in antlr for nested blocks

+

+    An oversight in detecting an empty alternative sometimes led

+    to an infinite loop in antlr when it encountered a rule with

+    nested blocks and guess blocks.

+    

+    Reported by P.A. Wilsey.

+    

+#293. (Changed in MR27) Sorcerer optimization of _t->type()

+

+    Sorcerer generated code may contain many calls to _t->type() in a

+    single statement.  This change introduces a temporary variable

+    to eliminate unnnecesary function calls.

+

+    Change implemented by Tom Molteno (tim videoscript.com).

+

+#292. (Changed in MR27)

+

+    WARNING:  Item #267 changes the signature of methods in the AST class.

+

+    **** Be sure to revise your AST functions of the same name  ***

+

+#291. (Changed in MR24)

+

+    Fix to serious code generation error in MR23 for (...)+ block.

+

+#290. (Changed in MR23) 

+

+    Item #247 describes a change in the way {...} blocks handled

+    an error.  Consider:

+

+            r1 : {A} b ;

+            b  : B;

+                

+                with input "C".

+

+    Prior to change #247, the error would resemble "expected B -

+    found C".  This is correct but incomplete, and therefore

+    misleading.  In #247 it was changed to "expected A, B - found

+    C".  This was fine, except for users of parser exception

+    handling because the exception was generated in the epilogue 

+    for {...} block rather than in rule b.  This made it difficult

+    for users of parser exception handling because B was not

+    expected in that context. Those not using parser exception

+    handling didn't notice the difference.

+

+    The current change restores the behavior prior to #247 when

+    parser exceptions are present, but retains the revised behavior

+    otherwise.  This change should be visible only when exceptions

+    are in use and only for {...} blocks and sub-blocks of the form

+    (something|something | something | epsilon) where epsilon represents

+    an empty production and it is the last alternative of a sub-block.

+    In contrast, (something | epsilon | something) should generate the

+    same code as before, even when exceptions are used.

+    

+    Reported by Philippe Laporte (philippe at transvirtual.com).

+

+#289. (Changed in MR23) Bug in matching complement of a #tokclass

+

+    Prior to MR23 when a #tokclass was matched in both its complemented form

+    and uncomplemented form, the bit set generated for its first use was used

+    for both cases.  However, the prediction expression was correctly computed

+    in both cases.  This meant that the second case would never be matched

+    because, for the second appearance, the prediction expression and the 

+    set to be matched would be complements of each other.

+        

+    Consider:

+        

+                #token A "a"

+                #token B "b"

+                #token C "c"

+                #tokclass AB {A B}

+                

+                r1 : AB    /* alt 1x */

+                   | ~AB   /* alt 1y */

+                   ;

+        

+    Prior to MR23, this resulted in alternative 1y being unreachable.  Had it

+    been written:

+        

+                r2 : ~AB  /* alt 2x */

+                   : AB   /* alt 2y */

+                   

+    then alternative 2y would have become unreachable.        

+        

+    This bug was only for the case of complemented #tokclass.  For complemented

+    #token the proper code was generated.           

+        

+#288. (Changed in MR23) #errclass not restricted to choice points

+

+    The #errclass directive is supposed to allow a programmer to define

+    print strings which should appear in syntax error messages as a replacement

+    for some combinations of tokens. For instance:

+    

+            #errclass Operator {PLUS MINUS TIMES DIVIDE}

+            

+    If a syntax message includes all four of these tokens, and there is no

+    "better" choice of error class, the word "Operator" will be used rather

+    than a list of the four token names.

+        

+    Prior to MR23 the #errclass definitions were used only at choice points

+    (which call the FAIL macro). In other cases where there was no choice

+    (e.g. where a single token or token class were matched) the #errclass

+    information was not used.

+

+    With MR23 the #errclass declarations are used for syntax error messages

+    when matching a #tokclass, a wildcard (i.e. "*"), or the complement of a

+    #token or #tokclass (e.g. ~Operator).

+

+    Please note that #errclass may now be defined using #tokclass names 

+    (see Item #284).

+

+    Reported by Philip A. Wilsey.

+

+#287. (Changed in MR23) Print name for #tokclass

+

+    Item #148 describes how to give a print name to a #token so that,for

+    example, #token ID could have the expression "identifier" in syntax

+    error messages.  This has been extended to #tokclass:

+    

+            #token ID("identifier")  "[a-zA-Z]+"

+            #tokclass Primitive("primitive type") 

+                                    {INT, FLOAT, CHAR, FLOAT, DOUBLE, BOOL} 

+

+    This is really a cosmetic change, since #tokclass names do not appear

+    in any error messages.

+        

+#286. (Changed in MR23) Makefile change to use of cd

+

+    In cases where a pccts subdirectory name matched a directory identified

+    in a $CDPATH environment variable the build would fail.  All makefile

+    cd commands have been changed from "cd xyz" to "cd ./xyz" in order

+    to avoid this problem.

+        

+#285. (Changed in MR23) Check for null pointers in some dlg structures

+

+    An invalid regular expression can cause dlg to build an invalid

+    structure to represent the regular expression even while it issues 

+    error messages.  Additional pointer checks were added.

+

+    Reported by Robert Sherry.

+

+#284. (Changed in MR23) Allow #tokclass in #errclass definitions

+

+    Previously, a #tokclass reference in the definition of an

+    #errclass was not handled properly. Instead of being expanded

+    into the set of tokens represented by the #tokclass it was

+    treated somewhat like an #errclass.  However, in a later phase

+    when all #errclass were expanded into the corresponding tokens

+    the #tokclass reference was not expanded (because it wasn't an

+    #errclass).  In effect the reference was ignored.

+

+    This has been fixed.

+

+    Problem reported by Mike Dimmick (mike dimmick.demon.co.uk).

+

+#283. (Changed in MR23) Option -tmake invoke's parser's tmake 

+

+    When the string #(...) appears in an action antlr replaces it with

+    a call to ASTBase::tmake(...) to construct an AST.  It is sometimes

+    useful to change the tmake routine so that it has access to information

+    in the parser - something which is not possible with a static method

+    in an application where they may be multiple parsers active.

+

+    The antlr option -tmake replaces the call to ASTBase::tmake with a call

+    to a user supplied tmake routine.

+   

+#282. (Changed in MR23) Initialization error for DBG_REFCOUNTTOKEN

+

+    When the pre-processor symbol DBG_REFCOUNTTOKEN is defined 

+    incorrect code is generated to initialize ANTLRRefCountToken::ctor and

+    dtor.

+

+    Fix reported by Sven Kuehn (sven sevenkuehn.de).

+   

+#281. (Changed in MR23) Addition of -noctor option for Sorcerer

+

+    Added a -noctor option to suppress generation of the blank ctor

+    for users who wish to define their own ctor.

+

+    Contributed by Jan Langer (jan langernetz.de).

+

+#280. (Changed in MR23) Syntax error message for EOF token

+

+    The EOF token now receives special treatment in syntax error messages

+    because there is no text matched by the eof token.  The token name

+    of the eof token is used unless it is "@" - in which case the string

+    "<eof>" is used.

+

+    Problem reported by Erwin Achermann (erwin.achermann switzerland.org).

+

+#279. (Changed in MR23) Exception groups

+

+    There was a bug in the way that exception groups were attached to

+    alternatives which caused problems when there was a block contained

+    in an alternative.  For instance, in the following rule;

+

+        statement : IF S { ELSE S } 

+                        exception ....

+        ;

+

+    the exception would be attached to the {...} block instead of the 

+    entire alternative because it was attached, in error, to the last

+    alternative instead of the last OPEN alternative.

+

+    Reported by Ty Mordane (tymordane hotmail.com).

+    

+#278. (Changed in MR23) makefile changes

+

+    Contributed by Tomasz Babczynski (faster lab05-7.ict.pwr.wroc.pl).

+

+    The -cfile option is not absolutely needed: when extension of

+    source file is one of the well-known C/C++ extensions it is 

+    treated as C/C++ source

+

+    The gnu make defines the CXX variable as the default C++ compiler

+    name, so I added a line to copy this (if defined) to the CCC var.

+

+    Added a -sor option: after it any -class command defines the class

+    name for sorcerer, not for ANTLR.  A file extended with .sor is 

+    treated as sorcerer input.  Because sorcerer can be called multiple

+    times, -sor option can be repeated.  Any files and classes (one class

+    per group) after each -sor makes one tree parser.

+

+    Not implemented:

+

+        1. Generate dependences for user c/c++ files.

+        2. Support for -sor in c mode not.

+

+    I have left the old genmk program in the directory as genmk_old.c.

+

+#277. (Changed in MR23) Change in macro for failed semantic predicates

+

+    In the past, a semantic predicate that failed generated a call to

+    the macro zzfailed_pred:

+

+        #ifndef zzfailed_pred

+        #define zzfailed_pred(_p) \

+          if (guessing) { \

+            zzGUESS_FAIL; \

+          } else { \

+            something(_p)

+          }

+        #endif

+

+    If a user wished to use the failed action option for semantic predicates:

+

+        rule : <<my_predicate>>? [my_fail_action] A

+             | ...

+

+           

+    the code for my_fail_action would have to contain logic for handling

+    the guess part of the zzfailed_pred macro.  The user should not have

+    to be aware of the guess logic in writing the fail action.

+

+    The zzfailed_pred has been rewritten to have three arguments:

+

+            arg 1: the stringized predicate of the semantic predicate

+            arg 2: 0 => there is no user-defined fail action

+                   1 => there is a user-defined fail action

+            arg 3: the user-defined fail action (if defined)

+                   otherwise a no-operation

+

+    The zzfailed_pred macro is now defined as:

+

+        #ifndef zzfailed_pred

+        #define zzfailed_pred(_p,_hasuseraction,_useraction) \

+          if (guessing) { \

+            zzGUESS_FAIL; \

+          } else { \

+            zzfailed_pred_action(_p,_hasuseraction,_useraction) \

+          }

+        #endif

+

+

+    With zzfailed_pred_action defined as:

+

+        #ifndef zzfailed_pred_action

+        #define zzfailed_pred_action(_p,_hasuseraction,_useraction) \

+            if (_hasUserAction) { _useraction } else { failedSemanticPredicate(_p); }

+        #endif

+

+    In C++ mode failedSemanticPredicate() is a virtual function.

+    In C mode the default action is a fprintf statement.

+

+    Suggested by Erwin Achermann (erwin.achermann switzerland.org).

+

+#276. (Changed in MR23) Addition of return value initialization syntax

+

+    In an attempt to reduce the problems caused by the PURIFY macro I have

+    added new syntax for initializing the return value of rules and the

+    antlr option "-nopurify".

+

+    A rule with a single return argument:

+

+        r1 > [Foo f = expr] :

+

+    now generates code that resembles:

+

+        Foo r1(void) {

+          Foo _retv = expr;

+          ...

+        }

+  

+    A rule with more than one return argument:

+

+        r2 > [Foo f = expr1, Bar b = expr2 ] :

+

+    generates code that resembles:

+

+        struct _rv1 {

+            Foo f;

+            Bar b;

+        }

+

+        _rv1 r2(void) {

+          struct _rv1 _retv;

+          _retv.f = expr1;

+          _retv.b = expr2;

+          ...

+        }

+

+    C++ style comments appearing in the initialization list may cause problems.

+

+#275. (Changed in MR23) Addition of -nopurify option to antlr

+

+    A long time ago the PURIFY macro was introduced to initialize

+    return value arguments and get rid of annying messages from program

+    that checked for unitialized variables.

+

+    This has caused significant annoyance for C++ users that had

+    classes with virtual functions or non-trivial contructors because

+    it would zero the object, including the pointer to the virtual

+    function table.  This could be defeated by redefining

+    the PURIFY macro to be empty, but it was a constant surprise to

+    new C++ users of pccts.

+

+    I would like to remove it, but I fear that some existing programs

+    depend on it and would break.  My temporary solution is to add

+    an antlr option -nopurify which disables generation of the PURIFY

+    macro call.

+

+    The PURIFY macro should be avoided in favor of the new syntax

+    for initializing return arguments described in item #275.

+

+    To avoid name clash, the PURIFY macro has been renamed PCCTS_PURIFY.

+

+#274. (Changed in MR23) DLexer.cpp renamed to DLexer.h

+      (Changed in MR23) ATokPtr.cpp renamed to ATokPtrImpl.h

+

+    These two files had .cpp extensions but acted like .h files because

+    there were included in other files. This caused problems for many IDE.

+    I have renamed them.  The ATokPtrImpl.h was necessary because there was

+    already an ATokPtr.h.

+

+#273. (Changed in MR23) Default win32 library changed to multi-threaded DLL

+

+    The model used for building the Win32 debug and release libraries has changed

+    to multi-threaded DLL.

+

+    To make this change in your MSVC 6 project:

+

+        Project -> Settings

+        Select the C++ tab in the right pane of the dialog box

+        Select "Category: Code Generation"

+        Under "Use run-time library" select one of the following:

+

+            Multi-threaded DLL

+            Debug Multi-threaded DLL

+           

+    Suggested by Bill Menees (bill.menees gogallagher.com) 

+    

+#272. (Changed in MR23) Failed semantic predicate reported via virtual function

+

+    In the past, a failed semantic predicated reported the problem via a

+    macro which used fprintf().  The macro now expands into a call on 

+    the virtual function ANTLRParser::failedSemanticPredicate().

+

+#271. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions

+

+    An bug (or at least an oddity) is that a reference to LT(1), LA(1),

+    or LATEXT(1) in an action which immediately follows a token match

+    in a rule refers to the token matched, not the token which is in

+    the lookahead buffer.  Consider:

+

+        r : abc <<action alpha>> D <<action beta>> E;

+

+    In this case LT(1) in action alpha will refer to the next token in

+    the lookahead buffer ("D"), but LT(1) in action beta will refer to

+    the token matched by D - the preceding token.

+

+    A warning has been added for users about this when an action

+    following a token match contains a reference to LT(1), LA(1), or LATEXT(1).

+

+    This behavior should be changed, but it appears in too many programs

+    now.  Another problem, perhaps more significant, is that the obvious

+    fix (moving the consume() call to before the action) could change the 

+    order in which input is requested and output appears in existing programs.

+

+    This problem was reported, along with a fix by Benjamin Mandel

+    (beny sd.co.il).  However, I felt that changing the behavior was too

+    dangerous for existing code.

+

+#270. (Changed in MR23) Removed static objects from PCCTSAST.cpp

+

+    There were some statically allocated objects in PCCTSAST.cpp

+    These were changed to non-static.

+

+#269. (Changed in MR23) dlg output for initializing static array

+

+    The output from dlg contains a construct similar to the

+    following:

+   

+        struct XXX {

+          static const int size;

+          static int array1[5];

+        };

+

+        const int XXX::size = 4;

+        int XXX::array1[size+1];

+

+    

+    The problem is that although the expression "size+1" used in

+    the definition of array1 is equal to 5 (the expression used to

+    declare array), it is not considered equivalent by some compilers.

+

+    Reported with fix by Volker H. Simonis (simonis informatik.uni-tuebingen.de)

+

+#268. (Changed in MR23) syn() routine output when k > 1

+

+    The syn() routine is supposed to print out the text of the

+    token causing the syntax error.  It appears that it always

+    used the text from the first lookahead token rather than the

+    appropriate one.  The appropriate one is computed by comparing

+    the token codes of lookahead token i (for i = 1 to k) with

+    the FIRST(i) set.

+    

+    This has been corrected in ANTLRParser::syn().

+

+    Reported by Bill Menees (bill.menees gogallagher.com) 

+

+#267. (Changed in MR23) AST traversal functions client data argument

+

+    The AST traversal functions now take an extra (optional) parameter

+    which can point to client data:

+

+        preorder_action(void* pData = NULL)

+        preorder_before_action(void* pData = NULL)

+        preorder_after_action(void* pData = NULL)

+

+    ****       Warning: this changes the AST signature.         ***

+    **** Be sure to revise your AST functions of the same name  ***

+

+    Bill Menees (bill.menees gogallagher.com) 

+    

+#266. (Changed in MR23) virtual function printMessage()

+

+    Bill Menees (bill.menees gogallagher.com) has completed the

+    tedious taks of replacing all calls to fprintf() with calls

+    to the virtual function printMessage().  For classes which

+    have a pointer to the parser it forwards the printMessage()

+    call to the parser's printMessage() routine.

+

+    This should make it significanly easier to redirect pccts

+    error and warning messages.

+

+#265. (Changed in MR23) Remove "labase++" in C++ mode

+

+    In C++ mode labase++ is called when a token is matched.

+    It appears that labase is not used in C++ mode at all, so

+    this code has been commented out.

+    

+#264. (Changed in MR23) Complete rewrite of ParserBlackBox.h

+

+    The parser black box (PBlackBox.h) was completely rewritten

+    by Chris Uzdavinis (chris atdesk.com) to improve its robustness.

+

+#263. (Changed in MR23) -preamble and -preamble_first rescinded

+

+    Changes for item #253 have been rescinded.

+

+#262. (Changed in MR23) Crash with -alpha option during traceback

+

+    Under some circumstances a -alpha traceback was started at the

+    "wrong" time.  As a result, internal data structures were not

+    initialized.

+

+    Reported by Arpad Beszedes (beszedes inf.u-szeged.hu).

+

+#261. (Changed in MR23) Defer token fetch for C++ mode

+

+    Item #216 has been revised to indicate that use of the defer fetch

+    option (ZZDEFER_FETCH) requires dlg option -i.

+

+#260. (MR22) Raise default lex buffer size from 8,000 to 32,000 bytes.

+

+    ZZLEXBUFSIZE is the size (in bytes) of the buffer used by dlg 

+    generated lexers.  The default value has been raised to 32,000 and

+    the value used by antlr, dlg, and sorcerer has also been raised to

+    32,000.

+

+#259. (MR22) Default function arguments in C++ mode.

+

+    If a rule is declared:

+

+            rr [int i = 0] : ....

+

+    then the declaration generated by pccts resembles:

+

+            void rr(int i = 0);

+

+    however, the definition must omit the default argument:

+

+            void rr(int i) {...}

+

+    In the past the default value was not omitted.  In MR22

+    the generated code resembles:

+

+            void rr(int i /* = 0 */ ) {...}

+

+    Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de)

+

+

+    Note: In MR23 this was changed so that nested C style comments

+    ("/* ... */") would not cause problems.

+

+#258. (MR22)  Using a base class for your parser

+

+    In item #102 (MR10) the class statement was extended to allow one

+    to specify a base class other than ANTLRParser for the generated

+    parser.  It turned out that this was less than useful because

+    the constructor still specified ANTLRParser as the base class.

+

+    The class statement now uses the first identifier appearing after

+    the ":" as the name of the base class.  For example:

+

+        class MyParser : public FooParser {

+

+    Generates in MyParser.h:

+

+            class MyParser : public FooParser {

+

+    Generates in MyParser.cpp something that resembles:

+

+            MyParser::MyParser(ANTLRTokenBuffer *input) :

+                                         FooParser(input,1,0,0,4)

+            {

+                token_tbl = _token_tbl;

+                traceOptionValueDefault=1;    // MR10 turn trace ON

+            }

+

+    The base class constructor must have a signature similar to

+    that of ANTLRParser.

+

+#257. (MR21a) Removed dlg statement that -i has no effect in C++ mode.

+

+    This was incorrect.

+

+#256. (MR21a) Malformed syntax graph causes crash after error message.

+

+    In the past, certain kinds of errors in the very first grammar

+    element could cause the construction of a malformed graph 

+    representing the grammar.  This would eventually result in a

+    fatal internal error.  The code has been changed to be more

+    resistant to this particular error.

+

+#255. (MR21a) ParserBlackBox(FILE* f) 

+

+    This constructor set openByBlackBox to the wrong value.

+

+    Reported by Kees Bakker (kees_bakker tasking.nl).

+

+#254. (MR21a) Reporting syntax error at end-of-file

+

+    When there was a syntax error at the end-of-file the syntax

+    error routine would substitute "<eof>" for the programmer's

+    end-of-file symbol.  This substitution is now done only when

+    the programmer does not define his own end-of-file symbol

+    or the symbol begins with the character "@".

+

+    Reported by Kees Bakker (kees_bakker tasking.nl).

+

+#253. (MR21) Generation of block preamble (-preamble and -preamble_first)

+

+        *** This change was rescinded by item #263 ***

+

+    The antlr option -preamble causes antlr to insert the code

+    BLOCK_PREAMBLE at the start of each rule and block.  It does

+    not insert code before rules references, token references, or

+    actions.  By properly defining the macro BLOCK_PREAMBLE the

+    user can generate code which is specific to the start of blocks.

+

+    The antlr option -preamble_first is similar, but inserts the

+    code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol

+    PreambleFirst_123 is equivalent to the first set defined by

+    the #FirstSetSymbol described in Item #248.

+

+    I have not investigated how these options interact with guess

+    mode (syntactic predicates).

+

+#252. (MR21) Check for null pointer in trace routine

+

+    When some trace options are used when the parser is generated

+    without the trace enabled, the current rule name may be a

+    NULL pointer.  A guard was added to check for this in

+    restoreState.

+

+    Reported by Douglas E. Forester (dougf projtech.com).

+

+#251. (MR21) Changes to #define zzTRACE_RULES

+

+    The macro zzTRACE_RULES was being use to pass information to

+    AParser.h.  If this preprocessor symbol was not properly

+    set the first time AParser.h was #included, the declaration

+    of zzTRACEdata would be omitted (it is used by the -gd option).

+    Subsequent #includes of AParser.h would be skipped because of 

+    the #ifdef guard, so the declaration of zzTracePrevRuleName would

+    never be made.  The result was that proper compilation was very 

+    order dependent.

+

+    The declaration of zzTRACEdata was made unconditional and the

+    problem of removing unused declarations will be left to optimizers.

+    

+    Diagnosed by Douglas E. Forester (dougf projtech.com).

+

+#250. (MR21) Option for EXPERIMENTAL change to error sets for blocks

+

+    The antlr option -mrblkerr turns on an experimental feature

+    which is supposed to provide more accurate syntax error messages

+    for k=1, ck=1 grammars.  When used with k>1 or ck>1 grammars the

+    behavior should be no worse than the current behavior.

+

+    There is no problem with the matching of elements or the computation

+    of prediction expressions in pccts.  The task is only one of listing

+    the most appropriate tokens in the error message.  The error sets used

+    in pccts error messages are approximations of the exact error set when

+    optional elements in (...)* or (...)+ are involved.  While entirely

+    correct, the error messages are sometimes not 100% accurate.  

+

+    There is also a minor philosophical issue.  For example, suppose the

+    grammar expects the token to be an optional A followed by Z, and it 

+    is X.  X, of course, is neither A nor Z, so an error message is appropriate.

+    Is it appropriate to say "Expected Z" ?  It is correct, it is accurate,

+    but it is not complete.  

+

+    When k>1 or ck>1 the problem of providing the exactly correct

+    list of tokens for the syntax error messages ends up becoming

+    equivalent to evaluating the prediction expression for the

+    alternatives twice. However, for k=1 ck=1 grammars the prediction

+    expression can be computed easily and evaluated cheaply, so I

+    decided to try implementing it to satisfy a particular application.

+    This application uses the error set in an interactive command language

+    to provide prompts which list the alternatives available at that

+    point in the parser.  The user can then enter additional tokens to

+    complete the command line.  To do this required more accurate error 

+    sets then previously provided by pccts.

+

+    In some cases the default pccts behavior may lead to more robust error

+    recovery or clearer error messages then having the exact set of tokens.

+    This is because (a) features like -ge allow the use of symbolic names for

+    certain sets of tokens, so having extra tokens may simply obscure things

+    and (b) the error set is use to resynchronize the parser, so a good

+    choice is sometimes more important than having the exact set.

+

+    Consider the following example:

+

+            Note:  All examples code has been abbreviated

+            to the absolute minimum in order to make the

+            examples concise.

+

+        star1 : (A)* Z;

+

+    The generated code resembles:

+

+           old                new (with -mrblkerr)

+        --//-----------         --------------------

+        for (;;) {            for (;;) {

+            match(A);           match(A);

+        }                     }

+        match(Z);             if (! A and ! Z) then

+                                FAIL(...{A,Z}...);

+                              }

+                              match(Z);

+

+

+        With input X

+            old message: Found X, expected Z

+            new message: Found X, expected A, Z

+

+    For the example:

+

+        star2 : (A|B)* Z;

+

+           old                      new (with -mrblkerr)

+        -------------               --------------------

+        for (;;) {                  for (;;) {

+          if (!A and !B) break;       if (!A and !B) break;

+          if (...) {                  if (...) {

+            <same ...>                  <same ...>

+          }                           }

+          else {                      else {

+            FAIL(...{A,B,Z}...)         FAIL(...{A,B}...);

+          }                           }

+        }                           }

+        match(B);                   if (! A and ! B and !Z) then

+                                        FAIL(...{A,B,Z}...);

+                                    }

+                                    match(B);

+

+        With input X

+            old message: Found X, expected Z

+            new message: Found X, expected A, B, Z

+        With input A X

+            old message: Found X, expected Z

+            new message: Found X, expected A, B, Z

+

+            This includes the choice of looping back to the

+            star block.

+

+    The code for plus blocks:

+

+        plus1 : (A)+ Z;

+

+    The generated code resembles:

+

+           old                  new (with -mrblkerr)

+        -------------           --------------------

+        do {                    do {

+          match(A);               match(A);

+        } while (A)             } while (A)

+        match(Z);               if (! A and ! Z) then

+                                  FAIL(...{A,Z}...);

+                                }

+                                match(Z);

+

+        With input A X

+            old message: Found X, expected Z

+            new message: Found X, expected A, Z

+

+            This includes the choice of looping back to the

+            plus block.

+

+    For the example:

+

+        plus2 : (A|B)+ Z;

+

+           old                    new (with -mrblkerr)

+        -------------             --------------------

+        do {                        do {

+          if (A) {                    <same>

+            match(A);                 <same>

+          } else if (B) {             <same>

+            match(B);                 <same>

+          } else {                    <same>

+            if (cnt > 1) break;       <same>

+            FAIL(...{A,B,Z}...)         FAIL(...{A,B}...);

+          }                           }

+          cnt++;                      <same>

+        }                           }

+

+        match(Z);                   if (! A and ! B and !Z) then

+                                        FAIL(...{A,B,Z}...);

+                                    }

+                                    match(B);

+

+        With input X

+            old message: Found X, expected A, B, Z

+            new message: Found X, expected A, B

+        With input A X

+            old message: Found X, expected Z

+            new message: Found X, expected A, B, Z

+

+            This includes the choice of looping back to the

+            star block.

+    

+#249. (MR21) Changes for DEC/VMS systems

+

+    Jean-François Piéronne (jfp altavista.net) has updated some

+    VMS related command files and fixed some minor problems related

+    to building pccts under the DEC/VMS operating system.  For DEC/VMS

+    users the most important differences are:

+

+        a.  Revised makefile.vms

+        b.  Revised genMMS for genrating VMS style makefiles.

+

+#248. (MR21) Generate symbol for first set of an alternative

+

+    pccts can generate a symbol which represents the tokens which may

+    appear at the start of a block:

+

+        rr : #FirstSetSymbol(rr_FirstSet)  ( Foo | Bar ) ;

+

+    This will generate the symbol rr_FirstSet of type SetWordType with

+    elements Foo and Bar set. The bits can be tested using code similar 

+    to the following:

+

+        if (set_el(Foo, &rr_FirstSet)) { ...

+

+    This can be combined with the C array zztokens[] or the C++ routine

+    tokenName() to get the print name of the token in the first set.

+

+    The size of the set is given by the newly added enum SET_SIZE, a 

+    protected member of the generated parser's class.  The number of

+    elements in the generated set will not be exactly equal to the 

+    value of SET_SIZE because of synthetic tokens created by #tokclass,

+    #errclass, the -ge option, and meta-tokens such as epsilon, and

+    end-of-file.

+

+    The #FirstSetSymbol must appear immediately before a block

+    such as (...)+, (...)*, and {...}, and (...).  It may not appear

+    immediately before a token, a rule reference, or action.  However

+    a token or rule reference can be enclosed in a (...) in order to

+    make the use of #pragma FirstSetSymbol legal.

+

+            rr_bad : #FirstSetSymbol(rr_bad_FirstSet) Foo;   //  Illegal

+

+            rr_ok :  #FirstSetSymbol(rr_ok_FirstSet) (Foo);  //  Legal

+    

+    Do not confuse FirstSetSymbol sets with the sets used for testing

+    lookahead. The sets used for FirstSetSymbol have one element per bit,

+    so the number of bytes  is approximately the largest token number

+    divided by 8.  The sets used for testing lookahead store 8 lookahead 

+    sets per byte, so the length of the array is approximately the largest

+    token number.

+

+    If there is demand, a similar routine for follow sets can be added.

+

+#247. (MR21) Misleading error message on syntax error for optional elements.

+

+        ===================================================

+        The behavior has been revised when parser exception

+        handling is used.  See Item #290

+        ===================================================

+

+    Prior to MR21, tokens which were optional did not appear in syntax

+    error messages if the block which immediately followed detected a 

+    syntax error.

+

+    Consider the following grammar which accepts Number, Word, and Other:

+

+            rr : {Number} Word;

+

+    For this rule the code resembles:

+

+            if (LA(1) == Number) {

+                match(Number);

+                consume();

+            }

+            match(Word);

+

+    Prior to MR21, the error message for input "$ a" would be:

+

+            line 1: syntax error at "$" missing Word

+

+    With MR21 the message will be:

+

+            line 1: syntax error at "$" expecting Word, Number.

+

+    The generate code resembles:

+

+            if ( (LA(1)==Number) ) {

+                zzmatch(Number);

+                consume();

+            }

+            else {

+                if ( (LA(1)==Word) ) {

+                    /* nothing */

+                }

+                else {

+                    FAIL(... message for both Number and Word ...);

+                }

+            }

+            match(Word);

+        

+    The code generated for optional blocks in MR21 is slightly longer

+    than the previous versions, but it should give better error messages.

+

+    The code generated for:

+

+            { a | b | c }

+

+    should now be *identical* to:

+

+            ( a | b | c | )

+

+    which was not the case prior to MR21.

+

+    Reported by Sue Marvin (sue siara.com).

+

+#246. (Changed in MR21) Use of $(MAKE) for calls to make

+

+    Calls to make from the makefiles were replaced with $(MAKE)

+    because of problems when using gmake.

+

+    Reported with fix by Sunil K.Vallamkonda (sunil siara.com).

+

+#245. (Changed in MR21) Changes to genmk

+

+    The following command line options have been added to genmk:

+

+        -cfiles ... 

+            

+            To add a user's C or C++ files into makefile automatically.

+            The list of files must be enclosed in apostrophes.  This

+            option may be specified multiple times.

+

+        -compiler ...

+    

+            The name of the compiler to use for $(CCC) or $(CC).  The

+            default in C++ mode is "CC".  The default in C mode is "cc".

+

+        -pccts_path ...

+

+            The value for $(PCCTS), the pccts directory.  The default

+            is /usr/local/pccts.

+

+    Contributed by Tomasz Babczynski (t.babczynski ict.pwr.wroc.pl).

+

+#244. (Changed in MR21) Rename variable "not" in antlr.g

+

+    When antlr.g is compiled with a C++ compiler, a variable named

+    "not" causes problems.  Reported by Sinan Karasu

+    (sinan.karasu boeing.com).

+

+#243  (Changed in MR21) Replace recursion with iteration in zzfree_ast

+

+    Another refinement to zzfree_ast in ast.c to limit recursion.

+

+    NAKAJIMA Mutsuki (muc isr.co.jp).

+

+

+#242.  (Changed in MR21) LineInfoFormatStr

+

+    Added an #ifndef/#endif around LineInfoFormatStr in pcctscfg.h.

+

+#241. (Changed in MR21) Changed macro PURIFY to a no-op

+

+                ***********************

+                *** NOT IMPLEMENTED ***

+                ***********************

+

+        The PURIFY macro was changed to a no-op because it was causing 

+        problems when passing C++ objects.

+    

+        The old definition:

+    

+            #define PURIFY(r,s)     memset((char *) &(r),'\\0',(s));

+    

+        The new definition:

+    

+            #define PURIFY(r,s)     /* nothing */

+#endif

+

+#240. (Changed in MR21) sorcerer/h/sorcerer.h _MATCH and _MATCHRANGE

+

+    Added test for NULL token pointer.

+

+    Suggested by Peter Keller (keller ebi.ac.uk)

+

+#239. (Changed in MR21) C++ mode AParser::traceGuessFail

+

+    If tracing is turned on when the code has been generated

+    without trace code, a failed guess generates a trace report

+    even though there are no other trace reports.  This

+    make the behavior consistent with other parts of the

+    trace system.

+

+    Reported by David Wigg (wiggjd sbu.ac.uk).

+

+#238. (Changed in MR21) Namespace version #include files

+

+    Changed reference from CStdio to cstdio (and other

+    #include file names) in the namespace version of pccts.

+    Should have known better.

+

+#237. (Changed in MR21) ParserBlackBox(FILE*)

+    

+    In the past, ParserBlackBox would close the FILE in the dtor

+    even though it was not opened by ParserBlackBox.  The problem

+    is that there were two constructors, one which accepted a file   

+    name and did an fopen, the other which accepted a FILE and did

+    not do an fopen.  There is now an extra member variable which

+    remembers whether ParserBlackBox did the open or not.

+

+    Suggested by Mike Percy (mpercy scires.com).

+

+#236. (Changed in MR21) tmake now reports down pointer problem

+

+    When ASTBase::tmake attempts to update the down pointer of 

+    an AST it checks to see if the down pointer is NULL.  If it

+    is not NULL it does not do the update and returns NULL.

+    An attempt to update the down pointer is almost always a

+    result of a user error.  This can lead to difficult to find

+    problems during tree construction.

+

+    With this change, the routine calls a virtual function

+    reportOverwriteOfDownPointer() which calls panic to

+    report the problem.  Users who want the old behavior can

+    redefined the virtual function in their AST class.

+

+    Suggested by Sinan Karasu (sinan.karasu boeing.com)

+

+#235. (Changed in MR21) Made ANTLRParser::resynch() virtual

+

+    Suggested by Jerry Evans (jerry swsl.co.uk).

+

+#234. (Changed in MR21) Implicit int for function return value

+

+    ATokenBuffer:bufferSize() did not specify a type for the

+    return value.

+

+    Reported by Hai Vo-Ba (hai fc.hp.com).

+

+#233. (Changed in MR20) Converted to MSVC 6.0

+

+    Due to external circumstances I have had to convert to MSVC 6.0

+    The MSVC 5.0 project files (.dsw and .dsp) have been retained as

+    xxx50.dsp and xxx50.dsw.  The MSVC 6.0 files are named xxx60.dsp

+    and xxx60.dsw (where xxx is the related to the directory/project).

+

+#232. (Changed in MR20) Make setwd bit vectors protected in parser.h

+

+    The access for the setwd array in the parser header was not

+    specified.  As a result, it would depend on the code which 

+    preceded it.  In MR20 it will always have access "protected".

+

+    Reported by Piotr Eljasiak (eljasiak zt.gdansk.tpsa.pl).

+

+#231. (Changed in MR20) Error in token buffer debug code.

+

+    When token buffer debugging is selected via the pre-processor

+    symbol DEBUG_TOKENBUFFER there is an erroneous check in

+    AParser.cpp:

+

+        #ifdef DEBUG_TOKENBUFFER

+            if (i >= inputTokens->bufferSize() ||

+                inputTokens->minTokens() < LLk )     /* MR20 Was "<=" */

+        ...

+        #endif

+

+    Reported by David Wigg (wiggjd sbu.ac.uk).

+

+#230. (Changed in MR20) Fixed problem with #define for -gd option

+

+    There was an error in setting zzTRACE_RULES for the -gd (trace) option.

+

+    Reported by Gary Funck (gary intrepid.com).

+

+#229. (Changed in MR20) Additional "const" for literals

+

+    "const" was added to the token name literal table.

+    "const" was added to some panic() and similar routine

+

+#228. (Changed in MR20) dlg crashes on "()"

+

+    The following token defintion will cause DLG to crash.

+

+        #token "()"

+

+    When there is a syntax error in a regular expression

+    many of the dlg routines return a structure which has

+    null pointers.  When this is accessed by callers it

+    generates the crash.

+

+    I have attempted to fix the more common cases.

+

+    Reported by  Mengue Olivier (dolmen bigfoot.com).

+

+#227. (Changed in MR20) Array overwrite

+

+    Steveh Hand (sassth unx.sas.com) reported a problem which

+    was traced to a temporary array which was not properly

+    resized for deeply nested blocks.  This has been fixed.

+

+#226. (Changed in MR20) -pedantic conformance

+   

+    G. Hobbelt (i_a mbh.org) and THM made many, many minor 

+    changes to create prototypes for all the functions and

+    bring antlr, dlg, and sorcerer into conformance with

+    the gcc -pedantic option.

+

+    This may require uses to add pccts/h/pcctscfg.h to some

+    files or makefiles in order to have __USE_PROTOS defined.

+

+#225  (Changed in MR20) AST stack adjustment in C mode

+

+    The fix in #214 for AST stack adjustment in C mode missed 

+    some cases.

+

+    Reported with fix by Ger Hobbelt (i_a mbh.org).

+

+#224  (Changed in MR20) LL(1) and LL(2) with #pragma approx

+

+    This may take a record for the oldest, most trival, lexical

+    error in pccts.  The regular expressions for LL(1) and LL(2)

+    lacked an escape for the left and right parenthesis.

+

+    Reported by Ger Hobbelt (i_a mbh.org).

+

+#223  (Changed in MR20) Addition of IBM_VISUAL_AGE directory

+

+    Build files for antlr, dlg, and sorcerer under IBM Visual Age 

+    have been contributed by Anton Sergeev (ags mlc.ru).  They have

+    been placed in the pccts/IBM_VISUAL_AGE directory.

+

+#222  (Changed in MR20) Replace __STDC__ with __USE_PROTOS

+

+    Most occurrences of __STDC__ replaced with __USE_PROTOS due to

+    complaints from several users.

+

+#221  (Changed in MR20) Added #include for DLexerBase.h to PBlackBox.

+

+    Added #include for DLexerBase.h to PBlackBox.

+

+#220  (Changed in MR19) strcat arguments reversed in #pred parse

+

+    The arguments to strcat are reversed when creating a print

+    name for a hash table entry for use with #pred feature.

+

+    Problem diagnosed and fix reported by Scott Harrington 

+    (seh4 ix.netcom.com).

+

+#219. (Changed in MR19) C Mode routine zzfree_ast

+

+    Changes to reduce use of recursion for AST trees with only right

+    links or only left links in the C mode routine zzfree_ast.

+

+    Implemented by SAKAI Kiyotaka (ksakai isr.co.jp).

+

+#218. (Changed in MR19) Changes to support unsigned char in C mode

+

+    Changes to antlr.h and err.h to fix omissions in use of zzchar_t

+

+    Implemented by SAKAI Kiyotaka (ksakai isr.co.jp).

+

+#217. (Changed in MR19) Error message when dlg -i and -CC options selected

+    

+    *** This change was rescinded by item #257 ***

+

+    The parsers generated by pccts in C++ mode are not able to support the

+    interactive lexer option (except, perhaps, when using the deferred fetch

+    parser option.(Item #216).

+

+    DLG now warns when both -i and -CC are selected.

+

+    This warning was suggested by David Venditti (07751870267-0001 t-online.de).

+

+#216. (Changed in MR19) Defer token fetch for C++ mode

+

+    Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de)

+

+    Normally, pccts keeps the lookahead token buffer completely filled.

+    This requires max(k,ck) tokens of lookahead.  For some applications

+    this can cause deadlock problems.  For example, there may be cases

+    when the parser can't tell when the input has been completely consumed

+    until the parse is complete, but the parse can't be completed because 

+    the input routines are waiting for additional tokens to fill the

+    lookahead buffer.

+    

+    When the ANTLRParser class is built with the pre-processor option 

+    ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred

+    until LA(i) or LT(i) is called. 

+

+    To test whether this option has been built into the ANTLRParser class

+    use "isDeferFetchEnabled()".

+

+    Using the -gd trace option with the default tracein() and traceout()

+    routines will defeat the effort to defer the fetch because the

+    trace routines print out information about the lookahead token at

+    the start of the rule.

+    

+    Because the tracein and traceout routines are virtual it is 

+    easy to redefine them in your parser:

+

+        class MyParser {

+        <<

+            virtual void tracein(ANTLRChar * ruleName)

+                { fprintf(stderr,"Entering: %s\n", ruleName); }

+            virtual void traceout(ANTLRChar * ruleName)

+                { fprintf(stderr,"Leaving: %s\n", ruleName); }

+        >>

+ 

+    The originals for those routines are pccts/h/AParser.cpp

+ 

+    This requires use of the dlg option -i (interactive lexer).

+

+    This is implemented only for C++ mode.

+

+    This is experimental.  The interaction with guess mode (syntactic

+    predicates)is not known.

+

+#215. (Changed in MR19) Addition of reset() to DLGLexerBase

+

+    There was no obvious way to reset the lexer for reuse.  The

+    reset() method now does this.

+

+    Suggested by David Venditti (07751870267-0001 t-online.de).

+

+#214. (Changed in MR19)  C mode: Adjust AST stack pointer at exit

+

+    In C mode the AST stack pointer needs to be reset if there will

+    be multiple calls to the ANTLRx macros.

+

+    Reported with fix by Paul D. Smith (psmith baynetworks.com).

+

+#213. (Changed in MR18)  Fatal error with -mrhoistk (k>1 hoisting)

+

+    When rearranging code I forgot to un-comment a critical line of

+    code that handles hoisting of predicates with k>1 lookahead.  This

+    is now fixed.

+

+    Reported by Reinier van den Born (reinier vnet.ibm.com).

+

+#212. (Changed in MR17)  Mac related changes by Kenji Tanaka

+

+    Kenji Tanaka (kentar osa.att.ne.jp) has made a number of changes for

+    Macintosh users.

+

+    a.  The following Macintosh MPW files aid in installing pccts on Mac:

+

+            pccts/MPW_Read_Me

+

+            pccts/install68K.mpw

+            pccts/installPPC.mpw

+

+            pccts/antlr/antlr.r

+            pccts/antlr/antlr68K.make

+            pccts/antlr/antlrPPC.make

+

+            pccts/dlg/dlg.r

+            pccts/dlg/dlg68K.make

+            pccts/dlg/dlgPPC.make

+

+            pccts/sorcerer/sor.r

+            pccts/sorcerer/sor68K.make

+            pccts/sorcerer/sorPPC.make

+    

+       They completely replace the previous Mac installation files.

+            

+    b. The most significant is a change in the MAC_FILE_CREATOR symbol

+       in pcctscfg.h:

+

+        old: #define MAC_FILE_CREATOR 'MMCC'   /* Metrowerks C/C++ Text files */

+        new: #define MAC_FILE_CREATOR 'CWIE'   /* Metrowerks C/C++ Text files */

+

+    c.  Added calls to special_fopen_actions() where necessary.

+

+#211. (Changed in MR16a)  C++ style comment in dlg

+

+    This has been fixed.

+

+#210. (Changed in MR16a)  Sor accepts \r\n, \r, or \n for end-of-line

+

+    A user requested that Sorcerer be changed to accept other forms

+    of end-of-line.

+

+#209. (Changed in MR16) Name of files changed.

+

+        Old:  CHANGES_FROM_1.33

+        New:  CHANGES_FROM_133.txt

+

+        Old:  KNOWN_PROBLEMS

+        New:  KNOWN_PROBLEMS.txt

+

+#208. (Changed in MR16) Change in use of pccts #include files

+

+    There were problems with MS DevStudio when mixing Sorcerer and

+    PCCTS in the same source file.  The problem is caused by the

+    redefinition of setjmp in the MS header file setjmp.h.  In

+    setjmp.h the pre-processor symbol setjmp was redefined to be

+    _setjmp.  A later effort to execute #include <setjmp.h> resulted 

+    in an effort to #include <_setjmp.h>.  I'm not sure whether this

+    is a bug or a feature.  In any case, I decided to fix it by

+    avoiding the use of pre-processor symbols in #include statements

+    altogether.  This has the added benefit of making pre-compiled

+    headers work again.

+

+    I've replaced statements:

+

+        old: #include PCCTS_SETJMP_H

+        new: #include "pccts_setjmp.h"

+

+    Where pccts_setjmp.h contains:

+

+            #ifndef __PCCTS_SETJMP_H__

+            #define __PCCTS_SETJMP_H__

+    

+            #ifdef PCCTS_USE_NAMESPACE_STD

+            #include <Csetjmp>

+            #else

+            #include <setjmp.h>

+            #endif

+

+            #endif

+        

+    A similar change has been made for other standard header files

+    required by pccts and sorcerer: stdlib.h, stdarg.h, stdio.h, etc.

+

+    Reported by Jeff Vincent (JVincent novell.com) and Dale Davis

+    (DalDavis spectrace.com).

+

+#207. (Changed in MR16) dlg reports an invalid range for: [\0x00-\0xff]

+

+     -----------------------------------------------------------------

+     Note from MR23:  This fix does not work.  I am investigating why.

+     -----------------------------------------------------------------

+

+    dlg will report that this is an invalid range.

+

+    Diagnosed by Piotr Eljasiak (eljasiak no-spam.zt.gdansk.tpsa.pl):

+

+        I think this problem is not specific to unsigned chars

+        because dlg reports no error for the range [\0x00-\0xfe].

+

+        I've found that information on range is kept in field

+        letter (unsigned char) of Attrib struct. Unfortunately

+        the letter value internally is for some reasons increased

+        by 1, so \0xff is represented here as 0.

+

+        That's why dlg complains about the range [\0x00-\0xff] in

+        dlg_p.g:

+

+        if ($$.letter > $2.letter) {

+          error("invalid range  ", zzline);

+        } 

+

+    The fix is:

+

+        if ($$.letter > $2.letter && 255 != $$2.letter) {

+          error("invalid range  ", zzline);

+        } 

+

+#206. (Changed in MR16) Free zzFAILtext in ANTLRParser destructor

+

+    The ANTLRParser destructor now frees zzFAILtext.

+

+    Problem and fix reported by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#205. (Changed in MR16) DLGStringReset argument now const

+

+    Changed: void DLGStringReset(DLGChar *s) {...}

+    To:      void DLGStringReset(const DLGChar *s) {...}

+

+    Suggested by Dale Davis (daldavis spectrace.com)

+

+#204. (Changed in MR15a) Change __WATCOM__ to __WATCOMC__ in pcctscfg.h

+    

+    Reported by Oleg Dashevskii (olegdash my-dejanews.com).

+

+#203. (Changed in MR15) Addition of sorcerer to distribution kit

+

+    I have finally caved in to popular demand.  The pccts 1.33mr15

+    kit will include sorcerer.  The separate sorcerer kit will be

+    discontinued.

+

+#202. (Changed) in MR15) Organization of MS Dev Studio Projects in Kit

+

+    Previously there was one workspace that contained projects for

+    all three parts of pccts: antlr, dlg, and sorcerer.  Now each

+    part (and directory) has its own workspace/project and there

+    is an additional workspace/project to build a library from the

+    .cpp files in the pccts/h directory.

+

+    The library build will create pccts_debug.lib or pccts_release.lib

+    according to the configuration selected.  

+

+    If you don't want to build pccts 1.33MR15 you can download a

+    ready-to-run kit for win32 from http://www.polhode.com/win32.zip.

+    The ready-to-run for win32 includes executables, a pre-built static

+    library for the .cpp files in the pccts/h directory, and a  sample

+    application

+

+    You will need to define the environment variable PCCTS to point to

+    the root of the pccts directory hierarchy.

+

+#201. (Changed in MR15) Several fixes by K.J. Cummings (cummings peritus.com)

+

+      Generation of SETJMP rather than SETJMP_H in gen.c.

+

+      (Sor B19) Declaration of ref_vars_inits for ref_var_inits in

+      pccts/sorcerer/sorcerer.h.

+

+#200. (Changed in MR15) Remove operator=() in AToken.h

+

+      User reported that WatCom couldn't handle use of

+      explicit operator =().  Replace with equivalent

+      using cast operator.

+

+#199. (Changed in MR15) Don't allow use of empty #tokclass

+

+      Change antlr.g to disallow empty #tokclass sets.

+

+      Reported by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#198. Revised ANSI C grammar due to efforts by Manuel Kessler

+

+      Manuel Kessler (mlkessler cip.physik.uni-wuerzburg.de)

+

+          Allow trailing ... in function parameter lists.

+          Add bit fields.

+          Allow old-style function declarations.

+          Support cv-qualified pointers.

+          Better checking of combinations of type specifiers.

+          Release of memory for local symbols on scope exit.

+          Allow input file name on command line as well as by redirection.

+

+              and other miscellaneous tweaks.

+

+      This is not part of the pccts distribution kit. It must be

+      downloaded separately from:

+

+            http://www.polhode.com/ansi_mr15.zip

+

+#197. (Changed in MR14) Resetting the lookahead buffer of the parser

+

+      Explanation and fix by Sinan Karasu (sinan.karasu boeing.com)

+

+      Consider the code used to prime the lookahead buffer LA(i)

+      of the parser when init() is called:

+

+        void

+        ANTLRParser::

+        prime_lookahead()

+        {

+            int i;

+            for(i=1;i<=LLk; i++) consume();

+            dirty=0;

+            //lap = 0;      // MR14 - Sinan Karasu (sinan.karusu boeing.com)

+            //labase = 0;   // MR14

+            labase=lap;     // MR14

+        }

+

+      When the parser is instantiated, lap=0,labase=0 is set.

+

+      The "for" loop runs LLk times. In consume(), lap = lap +1 (mod LLk) is

+      computed.  Therefore, lap(before the loop) == lap (after the loop).

+

+      Now the only problem comes in when one does an init() of the parser

+      after an Eof has been seen. At that time, lap could be non zero.

+      Assume it was lap==1. Now we do a prime_lookahead(). If LLk is 2,

+      then

+

+        consume()

+        {

+            NLA = inputTokens->getToken()->getType();

+            dirty--;

+            lap = (lap+1)&(LLk-1);

+        }

+

+      or expanding NLA,

+

+        token_type[lap&(LLk-1)]) = inputTokens->getToken()->getType();

+        dirty--;

+        lap = (lap+1)&(LLk-1);

+

+      so now we prime locations 1 and 2.  In prime_lookahead it used to set

+      lap=0 and labase=0.  Now, the next token will be read from location 0,

+      NOT 1 as it should have been.

+

+      This was never caught before, because if a parser is just instantiated,

+      then lap and labase are 0, the offending assignment lines are

+      basically no-ops, since the for loop wraps around back to 0.

+

+#196. (Changed in MR14) Problems with "(alpha)? beta" guess

+

+    Consider the following syntactic predicate in a grammar

+    with 2 tokens of lookahead (k=2 or ck=2):

+

+        rule  : ( alpha )? beta ;

+        alpha : S t ;

+        t     : T U

+              | T

+              ;

+        beta  : S t Z ;

+

+    When antlr computes the prediction expression with one token

+    of lookahead for alts 1 and 2 of rule t it finds an ambiguity.

+

+    Because the grammar has a lookahead of 2 it tries to compute

+    two tokens of lookahead for alts 1 and 2 of t.  Alt 1 clearly

+    has a lookahead of (T U).  Alt 2 is one token long so antlr

+    tries to compute the follow set of alt 2, which means finding

+    the things which can follow rule t in the context of (alpha)?.

+    This cannot be computed, because alpha is only part of a rule,

+    and antlr can't tell what part of beta is matched by alpha and

+    what part remains to be matched.  Thus it impossible for antlr

+    to  properly determine the follow set of rule t.

+

+    Prior to 1.33MR14, the follow of (alpha)? was computed as

+    FIRST(beta) as a result of the internal representation of

+    guess blocks.

+

+    With MR14 the follow set will be the empty set for that context.

+

+    Normally, one expects a rule appearing in a guess block to also

+    appear elsewhere.  When the follow context for this other use

+    is "ored" with the empty set, the context from the other use

+    results, and a reasonable follow context results.  However if

+    there is *no* other use of the rule, or it is used in a different

+    manner then the follow context will be inaccurate - it was

+    inaccurate even before MR14, but it will be inaccurate in a

+    different way.

+

+    For the example given earlier, a reasonable way to rewrite the

+    grammar:

+

+        rule  : ( alpha )? beta

+        alpha : S t ;

+        t     : T U

+              | T

+              ;

+        beta  : alpha Z ;

+

+    If there are no other uses of the rule appearing in the guess

+    block it will generate a test for EOF - a workaround for

+    representing a null set in the lookahead tests.

+

+    If you encounter such a problem you can use the -alpha option

+    to get additional information:

+

+    line 2: error: not possible to compute follow set for alpha

+              in an "(alpha)? beta" block.

+

+    With the antlr -alpha command line option the following information

+    is inserted into the generated file:

+

+    #if 0

+

+      Trace of references leading to attempt to compute the follow set of

+      alpha in an "(alpha)? beta" block. It is not possible for antlr to

+      compute this follow set because it is not known what part of beta has

+      already been matched by alpha and what part remains to be matched.

+

+      Rules which make use of the incorrect follow set will also be incorrect

+

+         1 #token T              alpha/2   line 7     brief.g

+         2 end alpha             alpha/3   line 8     brief.g

+         2 end (...)? block at   start/1   line 2     brief.g

+

+    #endif

+

+    At the moment, with the -alpha option selected the program marks

+    any rules which appear in the trace back chain (above) as rules with

+    possible problems computing follow set.

+

+    Reported by Greg Knapen (gregory.knapen bell.ca).

+

+#195. (Changed in MR14) #line directive not at column 1

+

+      Under certain circunstances a predicate test could generate

+      a #line directive which was not at column 1.

+

+      Reported with fix by David Kågedal  (davidk lysator.liu.se)

+      (http://www.lysator.liu.se/~davidk/).

+

+#194. (Changed in MR14) (C Mode only) Demand lookahead with #tokclass

+

+      In C mode with the demand lookahead option there is a bug in the

+      code which handles matches for #tokclass (zzsetmatch and

+      zzsetmatch_wsig).

+

+      The bug causes the lookahead pointer to get out of synchronization

+      with the current token pointer.

+

+      The problem was reported with a fix by Ger Hobbelt (hobbelt axa.nl).

+

+#193. (Changed in MR14) Use of PCCTS_USE_NAMESPACE_STD

+

+      The pcctscfg.h now contains the following definitions:

+

+        #ifdef PCCTS_USE_NAMESPACE_STD

+        #define PCCTS_STDIO_H     <Cstdio>

+        #define PCCTS_STDLIB_H    <Cstdlib>

+        #define PCCTS_STDARG_H    <Cstdarg>

+        #define PCCTS_SETJMP_H    <Csetjmp>

+        #define PCCTS_STRING_H    <Cstring>

+        #define PCCTS_ASSERT_H    <Cassert>

+        #define PCCTS_ISTREAM_H   <istream>

+        #define PCCTS_IOSTREAM_H  <iostream>

+        #define PCCTS_NAMESPACE_STD     namespace std {}; using namespace std;

+        #else

+        #define PCCTS_STDIO_H     <stdio.h>

+        #define PCCTS_STDLIB_H    <stdlib.h>

+        #define PCCTS_STDARG_H    <stdarg.h>

+        #define PCCTS_SETJMP_H    <setjmp.h>

+        #define PCCTS_STRING_H    <string.h>

+        #define PCCTS_ASSERT_H    <assert.h>

+        #define PCCTS_ISTREAM_H   <istream.h>

+        #define PCCTS_IOSTREAM_H  <iostream.h>

+        #define PCCTS_NAMESPACE_STD

+        #endif

+

+      The runtime support in pccts/h uses these pre-processor symbols

+      consistently.

+

+      Also, antlr and dlg have been changed to generate code which uses

+      these pre-processor symbols rather than having the names of the

+      #include files hard-coded in the generated code.

+

+      This required the addition of "#include pcctscfg.h" to a number of

+      files in pccts/h.

+

+      It appears that this sometimes causes problems for MSVC 5 in

+      combination with the "automatic" option for pre-compiled headers.

+      In such cases disable the "automatic" pre-compiled headers option.

+

+      Suggested by Hubert Holin (Hubert.Holin Bigfoot.com).

+

+#192. (Changed in MR14) Change setText() to accept "const ANTLRChar *"

+

+      Changed ANTLRToken::setText(ANTLRChar *) to setText(const ANTLRChar *).

+      This allows literal strings to be used to initialize tokens.  Since

+      the usual token implementation (ANTLRCommonToken)  makes a copy of the

+      input string, this was an unnecessary limitation.

+

+      Suggested by Bob McWhirter (bob netwrench.com).

+

+#191. (Changed in MR14) HP/UX aCC compiler compatibility problem

+

+      Needed to explicitly declare zzINF_DEF_TOKEN_BUFFER_SIZE and

+      zzINF_BUFFER_TOKEN_CHUNK_SIZE as ints in pccts/h/AParser.cpp.

+

+      Reported by David Cook (dcook bmc.com).

+

+#190. (Changed in MR14) IBM OS/2 CSet compiler compatibility problem

+

+      Name conflict with "_cs" in pccts/h/ATokenBuffer.cpp

+

+      Reported by David Cook (dcook bmc.com).

+

+#189. (Changed in MR14) -gxt switch in C mode

+

+      The -gxt switch in C mode didn't work because of incorrect

+      initialization.

+

+      Reported by Sinan Karasu (sinan boeing.com).

+

+#188. (Changed in MR14) Added pccts/h/DLG_stream_input.h

+

+      This is a DLG stream class based on C++ istreams.

+

+      Contributed by Hubert Holin (Hubert.Holin Bigfoot.com).

+

+#187. (Changed in MR14) Rename config.h to pcctscfg.h

+

+      The PCCTS configuration file has been renamed from config.h to

+      pcctscfg.h.  The problem with the original name is that it led

+      to name collisions when pccts parsers were combined with other

+      software.

+

+      All of the runtime support routines in pccts/h/* have been

+      changed to use the new name.  Existing software can continue

+      to use pccts/h/config.h. The contents of pccts/h/config.h is

+      now just "#include "pcctscfg.h".

+

+      I don't have a record of the user who suggested this.

+

+#186. (Changed in MR14) Pre-processor symbol DllExportPCCTS class modifier

+

+      Classes in the C++ runtime support routines are now declared:

+

+        class DllExportPCCTS className ....

+

+      By default, the pre-processor symbol is defined as the empty

+      string.  This if for use by MSVC++ users to create DLL classes.

+

+      Suggested by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#185. (Changed in MR14) Option to not use PCCTS_AST base class for ASTBase

+

+      Normally, the ASTBase class is derived from PCCTS_AST which contains

+      functions useful to Sorcerer.  If these are not necessary then the

+      user can define the pre-processor symbol "PCCTS_NOT_USING_SOR" which

+      will cause the ASTBase class to replace references to PCCTS_AST with

+      references to ASTBase where necessary.

+

+      The class ASTDoublyLinkedBase will contain a pure virtual function

+      shallowCopy() that was formerly defined in class PCCTS_AST.

+

+      Suggested by Bob McWhirter (bob netwrench.com).

+

+#184. (Changed in MR14) Grammars with no tokens generate invalid tokens.h

+

+      Reported by Hubert Holin (Hubert.Holin bigfoot.com).

+

+#183. (Changed in MR14) -f to specify file with names of grammar files

+

+      In DEC/VMS it is difficult to specify very long command lines.

+      The -f option allows one to place the names of the grammar files

+      in a data file in order to bypass limitations of the DEC/VMS

+      command language interpreter.

+

+      Addition supplied by Bernard Giroud (b_giroud decus.ch).

+

+#182. (Changed in MR14) Output directory option for DEC/VMS

+

+      Fix some problems with the -o option under DEC/VMS.

+

+      Fix supplied by Bernard Giroud (b_giroud decus.ch).

+

+#181. (Changed in MR14) Allow chars > 127 in DLGStringInput::nextChar()

+

+      Changed DLGStringInput to cast the character using (unsigned char)

+      so that languages with character codes greater than 127 work

+      without changes.

+

+      Suggested by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#180. (Added in MR14) ANTLRParser::getEofToken()

+

+      Added "ANTLRToken ANTLRParser::getEofToken() const" to match the

+      setEofToken routine.

+

+      Requested by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#179. (Fixed in MR14) Memory leak for BufFileInput subclass of DLGInputStream

+

+      The BufFileInput class described in Item #142 neglected to release

+      the allocated buffer when an instance was destroyed.

+

+      Reported by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#178. (Fixed in MR14) Bug in "(alpha)? beta" guess blocks first sets

+

+      In 1.33 vanilla, and all maintenance releases prior to MR14

+      there is a bug in the handling of guess blocks which use the

+      "long" form:

+

+                  (alpha)? beta

+

+      inside a (...)*, (...)+, or {...} block.

+

+      This problem does *not* apply to the case where beta is omitted

+      or when the syntactic predicate is on the leading edge of an

+      alternative.

+

+      The problem is that both alpha and beta are stored in the

+      syntax diagram, and that some analysis routines would fail

+      to skip the alpha portion when it was not on the leading edge.

+      Consider the following grammar with -ck 2:

+

+                r : ( (A)? B )* C D

+

+                  | A B      /* forces -ck 2 computation for old antlr    */

+                             /*              reports ambig for alts 1 & 2 */

+

+                  | B C      /* forces -ck 2 computation for new antlr    */

+                             /*              reports ambig for alts 1 & 3 */

+                  ;

+

+      The prediction expression for the first alternative should be

+      LA(1)={B C} LA(2)={B C D}, but previous versions of antlr

+      would compute the prediction expression as LA(1)={A C} LA(2)={B D}

+

+      Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided

+      a very clear example of the problem and identified the probable cause.

+

+#177. (Changed in MR14) #tokdefs and #token with regular expression

+

+      In MR13 the change described by Item #162 caused an existing

+      feature of antlr to fail.  Prior to the change it was possible

+      to give regular expression definitions and actions to tokens

+      which were defined via the #tokdefs directive.

+

+      This now works again.

+

+      Reported by Manfred Kogler (km cast.uni-linz.ac.at).

+

+#176. (Changed in MR14) Support for #line in antlr source code

+

+      Note: this was implemented by Arpad Beszedes (beszedes inf.u-szeged.hu).

+

+      In 1.33MR14 it is possible for a pre-processor to generate #line

+      directives in the antlr source and have those line numbers and file

+      names used in antlr error messages and in the #line directives

+      generated by antlr.

+

+      The #line directive may appear in the following forms:

+

+            #line ll "sss" xx xx ...

+

+      where ll represents a line number, "sss" represents the name of a file

+      enclosed in quotation marks, and xxx are arbitrary integers.

+

+      The following form (without "line") is not supported at the moment:

+

+            # ll "sss" xx xx ...

+

+      The result:

+

+        zzline

+

+            is replaced with ll from the # or #line directive

+

+        FileStr[CurFile]

+

+            is updated with the contents of the string (if any)

+            following the line number

+

+      Note

+      ----

+      The file-name string following the line number can be a complete

+      name with a directory-path. Antlr generates the output files from

+      the input file name (by replacing the extension from the file-name

+      with .c or .cpp).

+

+      If the input file (or the file-name from the line-info) contains

+      a path:

+

+        "../grammar.g"

+

+      the generated source code will be placed in "../grammar.cpp" (i.e.

+      in the parent directory).  This is inconvenient in some cases

+      (even the -o switch can not be used) so the path information is

+      removed from the #line directive.  Thus, if the line-info was

+

+        #line 2 "../grammar.g"

+

+      then the current file-name will become "grammar.g"

+

+      In this way, the generated source code according to the grammar file

+      will always be in the current directory, except when the -o switch

+      is used.

+

+#175. (Changed in MR14) Bug when guess block appears at start of (...)*

+

+      In 1.33 vanilla and all maintenance releases prior to 1.33MR14

+      there is a bug when a guess block appears at the start of a (...)+.

+      Consider the following k=1 (ck=1) grammar:

+

+            rule :

+                  ( (STAR)? ZIP )* ID ;

+

+      Prior to 1.33MR14, the generated code resembled:

+

+        ...

+        zzGUESS_BLOCK

+        while ( 1 ) {

+            if ( ! LA(1)==STAR) break;

+            zzGUESS

+            if ( !zzrv ) {

+                zzmatch(STAR);

+                zzCONSUME;

+                zzGUESS_DONE

+                zzmatch(ZIP);

+                zzCONSUME;

+            ...

+

+      Note that the routine uses STAR for the prediction expression

+      rather than ZIP.  With 1.33MR14 the generated code resembles:

+

+        ...

+        while ( 1 ) {

+            if ( ! LA(1)==ZIP) break;

+        ...

+

+      This problem existed only with (...)* blocks and was caused

+      by the slightly more complicated graph which represents (...)*

+      blocks.  This caused the analysis routine to compute the first

+      set for the alpha part of the "(alpha)? beta" rather than the

+      beta part.

+

+      Both (...)+ and {...} blocks handled the guess block correctly.

+

+      Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided

+      a very clear example of the problem and identified the probable cause.

+

+#174. (Changed in MR14) Bug when action precedes syntactic predicate

+

+      In 1.33 vanilla, and all maintenance releases prior to MR14,

+      there was a bug when a syntactic predicate was immediately

+      preceded by an action.  Consider the following -ck 2 grammar:

+

+            rule :

+                   <<int i;>>

+                   (alpha)? beta C

+                 | A B

+                 ;

+

+            alpha : A ;

+            beta  : A B;

+

+      Prior to MR14, the code generated for the first alternative

+      resembled:

+

+        ...

+        zzGUESS

+        if ( !zzrv && LA(1)==A && LA(2)==A) {

+            alpha();

+            zzGUESS_DONE

+            beta();

+            zzmatch(C);

+            zzCONSUME;

+        } else {

+        ...

+

+      The prediction expression (i.e. LA(1)==A && LA(2)==A) is clearly

+      wrong because LA(2) should be matched to B (first[2] of beta is {B}).

+

+      With 1.33MR14 the prediction expression is:

+

+        ...

+        if ( !zzrv && LA(1)==A && LA(2)==B) {

+            alpha();

+            zzGUESS_DONE

+            beta();

+            zzmatch(C);

+            zzCONSUME;

+        } else {

+        ...

+

+      This will only affect users in which alpha is shorter than

+      than max(k,ck) and there is an action immediately preceding

+      the syntactic predicate.

+

+      This problem was reported by reported by Arpad Beszedes

+      (beszedes inf.u-szeged.hu) who provided a very clear example

+      of the problem and identified the presence of the init-action

+      as the likely culprit.

+

+#173. (Changed in MR13a) -glms for Microsoft style filenames with -gl

+

+      With the -gl option antlr generates #line directives using the

+      exact name of the input files specified on the command line.

+      An oddity of the Microsoft C and C++ compilers is that they

+      don't accept file names in #line directives containing "\"

+      even though these are names from the native file system.

+

+      With -glms option, the "\" in file names appearing in #line

+      directives is replaced with a "/" in order to conform to

+      Microsoft compiler requirements.

+

+      Reported by Erwin Achermann (erwin.achermann switzerland.org).

+

+#172. (Changed in MR13) \r\n in antlr source counted as one line

+

+      Some MS software uses \r\n to indicate a new line.  Antlr

+      now recognizes this in counting lines.

+

+      Reported by Edward L. Hepler (elh ece.vill.edu).

+

+#171. (Changed in MR13) #tokclass L..U now allowed

+

+      The following is now allowed:

+

+            #tokclass ABC { A..B C }

+

+      Reported by Dave Watola (dwatola amtsun.jpl.nasa.gov)

+

+#170. (Changed in MR13) Suppression for predicates with lookahead depth >1

+

+      In MR12 the capability for suppression of predicates with lookahead

+      depth=1 was introduced.  With MR13 this had been extended to

+      predicates with lookahead depth > 1 and released for use by users

+      on an experimental basis.

+

+      Consider the following grammar with -ck 2 and the predicate in rule

+      "a" with depth 2:

+

+            r1  : (ab)* "@"

+                ;

+

+            ab  : a

+                | b

+                ;

+

+            a   : (A B)? => <<p(LATEXT(2))>>? A B C

+                ;

+

+            b   : A B C

+                ;

+

+      Normally, the predicate would be hoisted into rule r1 in order to

+      determine whether to call rule "ab".  However it should *not* be

+      hoisted because, even if p is false, there is a valid alternative

+      in rule b.  With "-mrhoistk on" the predicate will be suppressed.

+

+      If "-info p" command line option is present the following information

+      will appear in the generated code:

+

+                while ( (LA(1)==A)

+        #if 0

+

+        Part (or all) of predicate with depth > 1 suppressed by alternative

+            without predicate

+

+        pred  <<  p(LATEXT(2))>>?

+                  depth=k=2  ("=>" guard)  rule a  line 8  t1.g

+          tree context:

+            (root = A

+               B

+            )

+

+        The token sequence which is suppressed: ( A B )

+        The sequence of references which generate that sequence of tokens:

+

+           1 to ab          r1/1       line 1     t1.g

+           2 ab             ab/1       line 4     t1.g

+           3 to b           ab/2       line 5     t1.g

+           4 b              b/1        line 11    t1.g

+           5 #token A       b/1        line 11    t1.g

+           6 #token B       b/1        line 11    t1.g

+

+        #endif

+

+      A slightly more complicated example:

+

+            r1  : (ab)* "@"

+                ;

+

+            ab  : a

+                | b

+                ;

+

+            a   : (A B)? => <<p(LATEXT(2))>>? (A  B | D E)

+                ;

+

+            b   : <<q(LATEXT(2))>>? D E

+                ;

+

+

+      In this case, the sequence (D E) in rule "a" which lies behind

+      the guard is used to suppress the predicate with context (D E)

+      in rule b.

+

+                while ( (LA(1)==A || LA(1)==D)

+            #if 0

+

+            Part (or all) of predicate with depth > 1 suppressed by alternative

+                without predicate

+

+            pred  <<  q(LATEXT(2))>>?

+                              depth=k=2  rule b  line 11  t2.g

+              tree context:

+                (root = D

+                   E

+                )

+

+            The token sequence which is suppressed: ( D E )

+            The sequence of references which generate that sequence of tokens:

+

+               1 to ab          r1/1       line 1     t2.g

+               2 ab             ab/1       line 4     t2.g

+               3 to a           ab/1       line 4     t2.g

+               4 a              a/1        line 8     t2.g

+               5 #token D       a/1        line 8     t2.g

+               6 #token E       a/1        line 8     t2.g

+

+            #endif

+            &&

+            #if 0

+

+            pred  <<  p(LATEXT(2))>>?

+                              depth=k=2  ("=>" guard)  rule a  line 8  t2.g

+              tree context:

+                (root = A

+                   B

+                )

+

+            #endif

+

+            (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) )  {

+                ab();

+                ...

+

+#169. (Changed in MR13) Predicate test optimization for depth=1 predicates

+

+      When the MR12 generated a test of a predicate which had depth 1

+      it would use the depth >1 routines, resulting in correct but

+      inefficient behavior.  In MR13, a bit test is used.

+

+#168. (Changed in MR13) Token expressions in context guards

+

+      The token expressions appearing in context guards such as:

+

+            (A B)? => <<test(LT(1))>>?  someRule

+

+      are computed during an early phase of antlr processing.  As

+      a result, prior to MR13, complex expressions such as:

+

+            ~B

+            L..U

+            ~L..U

+            TokClassName

+            ~TokClassName

+

+      were not computed properly.  This resulted in incorrect

+      context being computed for such expressions.

+

+      In MR13 these context guards are verified for proper semantics

+      in the initial phase and then re-evaluated after complex token

+      expressions have been computed in order to produce the correct

+      behavior.

+

+      Reported by Arpad Beszedes (beszedes inf.u-szeged.hu).

+

+#167. (Changed in MR13) ~L..U

+

+      Prior to MR13, the complement of a token range was

+      not properly computed.

+

+#166. (Changed in MR13) token expression L..U

+

+      The token U was represented as an unsigned char, restricting

+      the use of L..U to cases where U was assigned a token number

+      less than 256.  This is corrected in MR13.

+

+#165. (Changed in MR13) option -newAST

+

+      To create ASTs from an ANTLRTokenPtr antlr usually calls

+      "new AST(ANTLRTokenPtr)".  This option generates a call

+      to "newAST(ANTLRTokenPtr)" instead.  This allows a user

+      to define a parser member function to create an AST object.

+

+      Similar changes for ASTBase::tmake and ASTBase::link were not

+      thought necessary since they do not create AST objects, only

+      use existing ones.

+

+#164. (Changed in MR13) Unused variable _astp

+

+      For many compilations, we have lived with warnings about

+      the unused variable _astp.  It turns out that this varible

+      can *never* be used because the code which references it was

+      commented out.

+

+      This investigation was sparked by a note from Erwin Achermann

+      (erwin.achermann switzerland.org).

+

+#163. (Changed in MR13) Incorrect makefiles for testcpp examples

+

+      All the examples in pccts/testcpp/* had incorrect definitions

+      in the makefiles for the symbol "CCC".  Instead of CCC=CC they

+      had CC=$(CCC).

+

+      There was an additional problem in testcpp/1/test.g due to the

+      change in ANTLRToken::getText() to a const member function

+      (Item #137).

+

+      Reported by Maurice Mass (maas cuci.nl).

+

+#162. (Changed in MR13) Combining #token with #tokdefs

+

+      When it became possible to change the print-name of a

+      #token (Item #148) it became useful to give a #token

+      statement whose only purpose was to giving a print name

+      to the #token.  Prior to this change this could not be

+      combined with the #tokdefs feature.

+

+#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h

+

+#160. (Changed in MR13) Omissions in list of names for remap.h

+

+      When a user selects the -gp option antlr creates a list

+      of macros in remap.h to rename some of the standard

+      antlr routines from zzXXX to userprefixXXX.

+

+      There were number of omissions from the remap.h name

+      list related to the new trace facility.  This was reported,

+      along with a fix, by Bernie Solomon (bernard ug.eds.com).

+

+#159. (Changed in MR13) Violations of classic C rules

+

+      There were a number of violations of classic C style in

+      the distribution kit.  This was reported, along with fixes,

+      by Bernie Solomon (bernard ug.eds.com).

+

+#158. (Changed in MR13) #header causes problem for pre-processors

+

+      A user who runs the C pre-processor on antlr source suggested

+      that another syntax be allowed.  With MR13 such directives

+      such as #header, #pragma, etc. may be written as "\#header",

+      "\#pragma", etc.  For escaping pre-processor directives inside

+      a #header use something like the following:

+

+            \#header

+            <<

+                \#include <stdio.h>

+            >>

+

+#157. (Fixed in MR13) empty error sets for rules with infinite recursion

+

+      When the first set for a rule cannot be computed due to infinite

+      left recursion and it is the only alternative for a block then

+      the error set for the block would be empty.  This would result

+      in a fatal error.

+

+      Reported by Darin Creason (creason genedax.com)

+

+#156. (Changed in MR13) DLGLexerBase::getToken() now public

+

+#155. (Changed in MR13) Context behind predicates can suppress

+

+      With -mrhoist enabled the context behind a guarded predicate can

+      be used to suppress other predicates.  Consider the following grammar:

+

+        r0 : (r1)+;

+

+        r1  : rp

+            | rq

+            ;

+        rp  : <<p LATEXT(1)>>? B ;

+        rq : (A)? => <<q LATEXT(1)>>? (A|B);

+

+      In earlier versions both predicates "p" and "q" would be hoisted into

+      rule r0. With MR12c predicate p is suppressed because the context which

+      follows predicate q includes "B" which can "cover" predicate "p".  In

+      other words, in trying to decide in r0 whether to call r1, it doesn't

+      really matter whether p is false or true because, either way, there is

+      a valid choice within r1.

+

+#154. (Changed in MR13) Making hoist suppression explicit using <<nohoist>>

+

+      A common error, even among experienced pccts users, is to code

+      an init-action to inhibit hoisting rather than a leading action.

+      An init-action does not inhibit hoisting.

+

+      This was coded:

+

+        rule1 : <<;>> rule2

+

+      This is what was meant:

+

+        rule1 : <<;>> <<;>> rule2

+

+      With MR13, the user can code:

+

+        rule1 : <<;>> <<nohoist>> rule2

+

+      The following will give an error message:

+

+        rule1 : <<nohoist>> rule2

+

+      If the <<nohoist>> appears as an init-action rather than a leading

+      action an error message is issued.  The meaning of an init-action

+      containing "nohoist" is unclear: does it apply to just one

+      alternative or to all alternatives ?

+

+

+

+

+

+

+

+

+        -------------------------------------------------------

+        Note:  Items #153 to #1 are now in a separate file named

+                CHANGES_FROM_133_BEFORE_MR13.txt

+        -------------------------------------------------------

diff --git a/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt
new file mode 100644
index 0000000..bba5ecd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt
@@ -0,0 +1,3666 @@
+

+    ------------------------------------------------------------

+           This is the second part of a two part file.

+      This is a list of changes to pccts 1.33 prior to MR13

+       For more recent information see CHANGES_FROM_133.txt

+    ------------------------------------------------------------

+

+                               DISCLAIMER

+

+ The software and these notes are provided "as is".  They may include

+ typographical or technical errors and their authors disclaims all

+ liability of any kind or nature for damages due to error, fault,

+ defect, or deficiency regardless of cause.  All warranties of any

+ kind, either express or implied, including, but not limited to, the

+ implied  warranties of merchantability and fitness for a particular

+ purpose are disclaimed.

+

+

+#153. (Changed in MR12b) Bug in computation of -mrhoist suppression set

+

+      Consider the following grammar with k=1 and "-mrhoist on":

+

+            r1  : (A)? => ((p>>? x      /* l1 */

+                | r2                    /* l2 */

+                ;

+            r2  :  A                    /* l4 */

+                | (B)? => <<q>>? y      /* l5 */

+                ;

+

+      In earlier versions the mrhoist routine would see that both l1 and

+      l2 contained predicates and would assume that this prevented either

+      from acting to suppress the other predicate.  In the example above

+      it didn't realize the A at line l4 is capable of suppressing the

+      predicate at l1 even though alt l2 contains (indirectly) a predicate.

+

+      This is fixed  in MR12b.

+

+      Reported by Reinier van den Born (reinier@vnet.ibm.com)

+

+#153. (Changed in MR12a) Bug in computation of -mrhoist suppression set

+

+      An oversight similar to that described in Item #152 appeared in

+      the computation of the set that "covered" a predicate.  If a

+      predicate expression included a term such as p=AND(q,r) the context

+      of p was taken to be context(q) & context(r), when it should have

+      been context(q) | context(r).  This is fixed in MR12a.

+

+#152. (Changed in MR12) Bug in generation of predicate expressions

+

+      The primary purpose for MR12 is to make quite clear that MR11 is

+      obsolete and to fix the bug related to predicate expressions.

+

+      In MR10 code was added to optimize the code generated for

+      predicate expression tests.  Unfortunately, there was a

+      significant oversight in the code which resulted in a bug in

+      the generation of code for predicate expression tests which

+      contained predicates combined using AND:

+

+            r0 : (r1)* "@" ;

+            r1 : (AAA)? => <<p LATEXT(1)>>? r2 ;

+            r2 : (BBB)? => <<q LATEXT(1)>>? Q

+               | (BBB)? => <<r LATEXT(1)>>? Q

+               ;

+

+      In MR11 (and MR10 when using "-mrhoist on") the code generated

+      for r0 to predict r1 would be equivalent to:

+

+        if ( LA(1)==Q &&

+                (LA(1)==AAA && LA(1)==BBB) &&

+                    ( p && ( q || r )) ) {

+

+      This is incorrect because it expresses the idea that LA(1)

+      *must* be AAA in order to attempt r1, and *must* be BBB to

+      attempt r2.  The result was that r1 became unreachable since

+      both condition can not be simultaneously true.

+

+      The general philosophy of code generation for predicates

+      can be summarized as follows:

+

+            a. If the context is true don't enter an alt

+               for which the corresponding predicate is false.

+

+               If the context is false then it is okay to enter

+               the alt without evaluating the predicate at all.

+

+            b. A predicate created by ORing of predicates has

+               context which is the OR of their individual contexts.

+

+            c. A predicate created by ANDing of predicates has

+               (surprise) context which is the OR of their individual

+               contexts.

+

+            d. Apply these rules recursively.

+

+            e. Remember rule (a)

+

+      The correct code should express the idea that *if* LA(1) is

+      AAA then p must be true to attempt r1, but if LA(1) is *not*

+      AAA then it is okay to attempt r1, provided that *if* LA(1) is

+      BBB then one of q or r must be true.

+

+        if ( LA(1)==Q &&

+                ( !(LA(1)==AAA || LA(1)==BBB) ||

+                    ( ! LA(1) == AAA || p) &&

+                    ( ! LA(1) == BBB || q || r ) ) ) {

+

+      I believe this is fixed in MR12.

+

+      Reported by Reinier van den Born (reinier@vnet.ibm.com)

+

+#151a. (Changed in MR12) ANTLRParser::getLexer()

+

+      As a result of several requests, I have added public methods to

+      get a pointer to the lexer belonging to a parser.

+

+            ANTLRTokenStream *ANTLRParser::getLexer() const

+

+                Returns a pointer to the lexer being used by the

+                parser.  ANTLRTokenStream is the base class of

+                DLGLexer

+

+            ANTLRTokenStream *ANTLRTokenBuffer::getLexer() const

+

+                Returns a pointer to the lexer being used by the

+                ANTLRTokenBuffer.  ANTLRTokenStream is the base

+                class of DLGLexer

+

+      You must manually cast the ANTLRTokenStream to your program's

+      lexer class. Because the name of the lexer's class is not fixed.

+      Thus it is impossible to incorporate it into the DLGLexerBase

+      class.

+

+#151b.(Changed in MR12) ParserBlackBox member getLexer()

+

+      The template class ParserBlackBox now has a member getLexer()

+      which returns a pointer to the lexer.

+

+#150. (Changed in MR12) syntaxErrCount and lexErrCount now public

+

+      See Item #127 for more information.

+

+#149. (Changed in MR12) antlr option -info o (letter o for orphan)

+

+      If there is more than one rule which is not referenced by any

+      other rule then all such rules are listed.  This is useful for

+      alerting one to rules which are not used, but which can still

+      contribute to ambiguity.  For example:

+

+            start : a Z ;

+            unused: a A ;

+            a     : (A)+ ;

+

+      will cause an ambiguity report for rule "a" which will be

+      difficult to understand if the user forgets about rule "unused"

+      simply because it is not used in the grammar.

+

+#148. (Changed in MR11) #token names appearing in zztokens,token_tbl

+

+      In a #token statement like the following:

+

+            #token Plus "\+"

+

+      the string "Plus" appears in the zztokens array (C mode) and

+      token_tbl (C++ mode).  This string is used in most error

+      messages.  In MR11 one has the option of using some other string,

+      (e.g.  "+") in those tables.

+

+      In MR11 one can write:

+

+            #token Plus ("+")             "\+"

+            #token RP   ("(")             "\("

+            #token COM  ("comment begin") "/\*"

+

+      A #token statement is allowed to appear in more than one #lexclass

+      with different regular expressions.  However, the token name appears

+      only once in the zztokens/token_tbl array.  This means that only

+      one substitute can be specified for a given #token name.  The second

+      attempt to define a substitute name (different from the first) will

+      result in an error message.

+

+#147. (Changed in MR11) Bug in follow set computation

+

+      There is a bug in 1.33 vanilla and all maintenance releases

+      prior to MR11 in the computation of the follow set.  The bug is

+      different than that described in Item #82 and probably more

+      common.  It was discovered in the ansi.g grammar while testing

+      the "ambiguity aid" (Item #119). The search for a bug started

+      when the ambiguity aid was unable to discover the actual source

+      of an ambiguity reported by antlr.

+

+      The problem appears when an optimization of the follow set

+      computation is used inappropriately.  The result is that the

+      follow set used is the "worst case".  In other words, the error

+      can lead to false reports of ambiguity.  The good news is that

+      if you have a grammar in which you have addressed all reported

+      ambiguities you are ok.  The bad news is that you may have spent

+      time fixing ambiguities that were not real, or used k=2 when

+      ck=2 might have been sufficient, and so on.

+

+      The following grammar demonstrates the problem:

+

+        ------------------------------------------------------------

+            expr          :   ID ;

+

+            start         :   stmt SEMI ;

+

+            stmt          :   CASE expr COLON

+                          |   expr SEMI

+                          |   plain_stmt

+                          ;

+

+            plain_stmt    :   ID COLON ;

+        ------------------------------------------------------------

+

+      When compiled with k=1 and ck=2 it will report:

+

+         warning: alts 2 and 3 of the rule itself ambiguous upon

+                                             { IDENTIFIER }, { COLON }

+

+      When antlr analyzes "stmt" it computes the first[1] set of all

+      alternatives.  It finds an ambiguity between alts 2 and 3 for ID.

+      It then computes the first[2] set for alternatives 2 and 3 to resolve

+      the ambiguity.  In computing the first[2] set of "expr" (which is

+      only one token long) it needs to determine what could follow "expr".

+      Under a certain combination of circumstances antlr forgets that it

+      is trying to analyze "stmt" which can only be followed by SEMI and

+      adds to the first[2] set of "expr" the "global" follow set (including

+      "COLON") which could follow "expr" (under other conditions) in the

+      phrase "CASE expr COLON".

+

+#146. (Changed in MR11) Option -treport for locating "difficult" alts

+

+      It can be difficult to determine which alternatives are causing

+      pccts to work hard to resolve an ambiguity.  In some cases the

+      ambiguity is successfully resolved after much CPU time so there

+      is no message at all.

+

+      A rough measure of the amount of work being peformed which is

+      independent of the CPU speed and system load is the number of

+      tnodes created.  Using "-info t" gives information about the

+      total number of tnodes created and the peak number of tnodes.

+

+        Tree Nodes:  peak 1300k  created 1416k  lost 0

+

+      It also puts in the generated C or C++ file the number of tnodes

+      created for a rule (at the end of the rule).  However this

+      information is not sufficient to locate the alternatives within

+      a rule which are causing the creation of tnodes.

+

+      Using:

+

+             antlr -treport 100000 ....

+

+      causes antlr to list on stdout any alternatives which require the

+      creation of more than 100,000 tnodes, along with the lookahead sets

+      for those alternatives.

+

+      The following is a trivial case from the ansi.g grammar which shows

+      the format of the report.  This report might be of more interest

+      in cases where 1,000,000 tuples were created to resolve the ambiguity.

+

+      -------------------------------------------------------------------------

+        There were 0 tuples whose ambiguity could not be resolved

+             by full lookahead

+        There were 157 tnodes created to resolve ambiguity between:

+

+          Choice 1: statement/2  line 475  file ansi.g

+          Choice 2: statement/3  line 476  file ansi.g

+

+            Intersection of lookahead[1] sets:

+

+               IDENTIFIER

+

+            Intersection of lookahead[2] sets:

+

+               LPARENTHESIS     COLON            AMPERSAND        MINUS

+               STAR             PLUSPLUS         MINUSMINUS       ONESCOMPLEMENT

+               NOT              SIZEOF           OCTALINT         DECIMALINT

+               HEXADECIMALINT   FLOATONE         FLOATTWO         IDENTIFIER

+               STRING           CHARACTER

+      -------------------------------------------------------------------------

+

+#145. (Documentation)  Generation of Expression Trees

+

+      Item #99 was misleading because it implied that the optimization

+      for tree expressions was available only for trees created by

+      predicate expressions and neglected to mention that it required

+      the use of "-mrhoist on".  The optimization applies to tree

+      expressions created for grammars with k>1 and for predicates with

+      lookahead depth >1.

+

+      In MR11 the optimized version is always used so the -mrhoist on

+      option need not be specified.

+

+#144. (Changed in MR11) Incorrect test for exception group

+

+      In testing for a rule's exception group the label a pointer

+      is compared against '\0'.  The intention is "*pointer".

+

+      Reported by Jeffrey C. Fried (Jeff@Fried.net).

+

+#143. (Changed in MR11) Optional ";" at end of #token statement

+

+      Fixes problem of:

+

+            #token X "x"

+

+            <<

+                parser action

+            >>

+

+      Being confused with:

+

+            #token X "x" <<lexical action>>

+

+#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream

+

+      Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class

+      BufFileInput derived from DLGInputStream which provides a

+      function lookahead(char *string) to test characters in the

+      input stream more than one character ahead.

+

+      The default amount of lookahead is specified by the constructor

+      and defaults to 8 characters.  This does *not* include the one

+      character of lookahead maintained internally by DLG in member "ch"

+      and which is not available for testing via BufFileInput::lookahead().

+

+      This is a useful class for overcoming the one-character-lookahead

+      limitation of DLG without resorting to a lexer capable of

+      backtracking (like flex) which is not integrated with antlr as is

+      DLG.

+

+      There are no restrictions on copying or using BufFileInput.* except

+      that the authorship and related information must be retained in the

+      source code.

+

+      The class is located in pccts/h/BufFileInput.* of the kit.

+

+#141. (Changed in MR11) ZZDEBUG_CONSUME for ANTLRParser::consume()

+

+      A debug aid has been added to file ANTLRParser::consume() in

+      file AParser.cpp:

+

+            #ifdef ZZDEBUG_CONSUME_ACTION

+                zzdebug_consume_action();

+            #endif

+

+      Suggested by Sramji Ramanathan (ps@kumaran.com).

+

+#140. (Changed in MR11) #pred to define predicates

+

+      +---------------------------------------------------+

+      | Note: Assume "-prc on" for this entire discussion |

+      +---------------------------------------------------+

+

+      A problem with predicates is that each one is regarded as

+      unique and capable of disambiguating cases where two

+      alternatives have identical lookahead.  For example:

+

+        rule : <<pred(LATEXT(1))>>? A

+             | <<pred(LATEXT(1))>>? A

+             ;

+

+      will not cause any error messages or warnings to be issued

+      by earlier versions of pccts.  To compare the text of the

+      predicates is an incomplete solution.

+

+      In 1.33MR11 I am introducing the #pred statement in order to

+      solve some problems with predicates.  The #pred statement allows

+      one to give a symbolic name to a "predicate literal" or a

+      "predicate expression" in order to refer to it in other predicate

+      expressions or in the rules of the grammar.

+

+      The predicate literal associated with a predicate symbol is C

+      or C++ code which can be used to test the condition.  A

+      predicate expression defines a predicate symbol in terms of other

+      predicate symbols using "!", "&&", and "||".  A predicate symbol

+      can be defined in terms of a predicate literal, a predicate

+      expression, or *both*.

+

+      When a predicate symbol is defined with both a predicate literal

+      and a predicate expression, the predicate literal is used to generate

+      code, but the predicate expression is used to check for two

+      alternatives with identical predicates in both alternatives.

+

+      Here are some examples of #pred statements:

+

+        #pred  IsLabel       <<isLabel(LATEXT(1))>>?

+        #pred  IsLocalVar    <<isLocalVar(LATEXT(1))>>?

+        #pred  IsGlobalVar   <<isGlobalVar(LATEXT(1)>>?

+        #pred  IsVar         <<isVar(LATEXT(1))>>?       IsLocalVar || IsGlobalVar

+        #pred  IsScoped      <<isScoped(LATEXT(1))>>?    IsLabel || IsLocalVar

+

+      I hope that the use of EBNF notation to describe the syntax of the

+      #pred statement will not cause problems for my readers (joke).

+

+        predStatement : "#pred"

+                            CapitalizedName

+                              (

+                                  "<<predicate_literal>>?"

+                                | "<<predicate_literal>>?"  predOrExpr

+                                | predOrExpr

+                              )

+                      ;

+

+        predOrExpr    : predAndExpr ( "||" predAndExpr ) * ;

+

+        predAndExpr   : predPrimary ( "&&" predPrimary ) * ;

+

+        predPrimary   : CapitalizedName

+                      | "!" predPrimary

+                      | "(" predOrExpr ")"

+                      ;

+

+      What is the purpose of this nonsense ?

+

+      To understand how predicate symbols help, you need to realize that

+      predicate symbols are used in two different ways with two different

+      goals.

+

+        a. Allow simplification of predicates which have been combined

+           during predicate hoisting.

+

+        b. Allow recognition of identical predicates which can't disambiguate

+           alternatives with common lookahead.

+

+      First we will discuss goal (a).  Consider the following rule:

+

+            rule0: rule1

+                 | ID

+                 | ...

+                 ;

+

+            rule1: rule2

+                 | rule3

+                 ;

+

+            rule2: <<isX(LATEXT(1))>>? ID ;

+            rule3: <<!isX(LATEXT(1)>>? ID ;

+

+      When the predicates in rule2 and rule3 are combined by hoisting

+      to create a prediction expression for rule1 the result is:

+

+            if ( LA(1)==ID

+                && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ...

+

+      This is inefficient, but more importantly, can lead to false

+      assumptions that the predicate expression distinguishes the rule1

+      alternative with some other alternative with lookahead ID.  In

+      MR11 one can write:

+

+            #pred IsX     <<isX(LATEXT(1))>>?

+

+            ...

+

+            rule2: <<IsX>>? ID  ;

+            rule3: <<!IsX>>? ID ;

+

+      During hoisting MR11 recognizes this as a special case and

+      eliminates the predicates.  The result is a prediction

+      expression like the following:

+

+            if ( LA(1)==ID ) { rule1(); ...

+

+      Please note that the following cases which appear to be equivalent

+      *cannot* be simplified by MR11 during hoisting because the hoisting

+      logic only checks for a "!" in the predicate action, not in the

+      predicate expression for a predicate symbol.

+

+        *Not* equivalent and is not simplified during hoisting:

+

+            #pred IsX      <<isX(LATEXT(1))>>?

+            #pred NotX     <<!isX(LATEXT(1))>>?

+            ...

+            rule2: <<IsX>>? ID  ;

+            rule3: <<NotX>>? ID ;

+

+        *Not* equivalent and is not simplified during hoisting:

+

+            #pred IsX      <<isX(LATEXT(1))>>?

+            #pred NotX     !IsX

+            ...

+            rule2: <<IsX>>? ID  ;

+            rule3: <<NotX>>? ID ;

+

+      Now we will discuss goal (b).

+

+      When antlr discovers that there is a lookahead ambiguity between

+      two alternatives it attempts to resolve the ambiguity by searching

+      for predicates in both alternatives.  In the past any predicate

+      would do, even if the same one appeared in both alternatives:

+

+            rule: <<p(LATEXT(1))>>? X

+                | <<p(LATEXT(1))>>? X

+                ;

+

+      The #pred statement is a start towards solving this problem.

+      During ambiguity resolution (*not* predicate hoisting) the

+      predicates for the two alternatives are expanded and compared.

+      Consider the following example:

+

+            #pred Upper     <<isUpper(LATEXT(1))>>?

+            #pred Lower     <<isLower(LATEXT(1))>>?

+            #pred Alpha     <<isAlpha(LATEXT(1))>>?  Upper || Lower

+

+            rule0: rule1

+                 | <<Alpha>>? ID

+                 ;

+

+            rule1:

+                 | rule2

+                 | rule3

+                 ...

+                 ;

+

+            rule2: <<Upper>>? ID;

+            rule3: <<Lower>>? ID;

+

+      The definition of #pred Alpha expresses:

+

+            a. to test the predicate use the C code "isAlpha(LATEXT(1))"

+

+            b. to analyze the predicate use the information that

+               Alpha is equivalent to the union of Upper and Lower,

+

+      During ambiguity resolution the definition of Alpha is expanded

+      into "Upper || Lower" and compared with the predicate in the other

+      alternative, which is also "Upper || Lower".  Because they are

+      identical MR11 will report a problem.

+

+    -------------------------------------------------------------------------

+      t10.g, line 5: warning: the predicates used to disambiguate rule rule0

+             (file t10.g alt 1 line 5 and alt 2 line 6)

+             are identical when compared without context and may have no

+             resolving power for some lookahead sequences.

+    -------------------------------------------------------------------------

+

+      If you use the "-info p" option the output file will contain:

+

+    +----------------------------------------------------------------------+

+    |#if 0                                                                 |

+    |                                                                      |

+    |The following predicates are identical when compared without          |

+    |  lookahead context information.  For some ambiguous lookahead        |

+    |  sequences they may not have any power to resolve the ambiguity.     |

+    |                                                                      |

+    |Choice 1: rule0/1  alt 1  line 5  file t10.g                          |

+    |                                                                      |

+    |  The original predicate for choice 1 with available context          |

+    |    information:                                                      |

+    |                                                                      |

+    |    OR expr                                                           |

+    |                                                                      |

+    |      pred  <<  Upper>>?                                              |

+    |                        depth=k=1  rule rule2  line 14  t10.g         |

+    |        set context:                                                  |

+    |           ID                                                         |

+    |                                                                      |

+    |      pred  <<  Lower>>?                                              |

+    |                        depth=k=1  rule rule3  line 15  t10.g         |

+    |        set context:                                                  |

+    |           ID                                                         |

+    |                                                                      |

+    |  The predicate for choice 1 after expansion (but without context     |

+    |    information):                                                     |

+    |                                                                      |

+    |    OR expr                                                           |

+    |                                                                      |

+    |      pred  <<  isUpper(LATEXT(1))>>?                                 |

+    |                        depth=k=1  rule   line 1  t10.g               |

+    |                                                                      |

+    |      pred  <<  isLower(LATEXT(1))>>?                                 |

+    |                        depth=k=1  rule   line 2  t10.g               |

+    |                                                                      |

+    |                                                                      |

+    |Choice 2: rule0/2  alt 2  line 6  file t10.g                          |

+    |                                                                      |

+    |  The original predicate for choice 2 with available context          |

+    |    information:                                                      |

+    |                                                                      |

+    |  pred  <<  Alpha>>?                                                  |

+    |                    depth=k=1  rule rule0  line 6  t10.g              |

+    |    set context:                                                      |

+    |       ID                                                             |

+    |                                                                      |

+    |  The predicate for choice 2 after expansion (but without context     |

+    |    information):                                                     |

+    |                                                                      |

+    |  OR expr                                                             |

+    |                                                                      |

+    |    pred  <<  isUpper(LATEXT(1))>>?                                   |

+    |                      depth=k=1  rule   line 1  t10.g                 |

+    |                                                                      |

+    |    pred  <<  isLower(LATEXT(1))>>?                                   |

+    |                      depth=k=1  rule   line 2  t10.g                 |

+    |                                                                      |

+    |                                                                      |

+    |#endif                                                                |

+    +----------------------------------------------------------------------+

+

+      The comparison of the predicates for the two alternatives takes

+      place without context information, which means that in some cases

+      the predicates will be considered identical even though they operate

+      on disjoint lookahead sets.  Consider:

+

+            #pred Alpha

+

+            rule1: <<Alpha>>? ID

+                 | <<Alpha>>? Label

+                 ;

+

+      Because the comparison of predicates takes place without context

+      these will be considered identical.  The reason for comparing

+      without context is that otherwise it would be necessary to re-evaluate

+      the entire predicate expression for each possible lookahead sequence.

+      This would require more code to be written and more CPU time during

+      grammar analysis, and it is not yet clear whether anyone will even make

+      use of the new #pred facility.

+

+      A temporary workaround might be to use different #pred statements

+      for predicates you know have different context.  This would avoid

+      extraneous warnings.

+

+      The above example might be termed a "false positive".  Comparison

+      without context will also lead to "false negatives".  Consider the

+      following example:

+

+            #pred Alpha

+            #pred Beta

+

+            rule1: <<Alpha>>? A

+                 | rule2

+                 ;

+

+            rule2: <<Alpha>>? A

+                 | <<Beta>>?  B

+                 ;

+

+      The predicate used for alt 2 of rule1 is (Alpha || Beta).  This

+      appears to be different than the predicate Alpha used for alt1.

+      However, the context of Beta is B.  Thus when the lookahead is A

+      Beta will have no resolving power and Alpha will be used for both

+      alternatives.  Using the same predicate for both alternatives isn't

+      very helpful, but this will not be detected with 1.33MR11.

+

+      To properly handle this the predicate expression would have to be

+      evaluated for each distinct lookahead context.

+

+      To determine whether two predicate expressions are identical is

+      difficult.  The routine may fail to identify identical predicates.

+

+      The #pred feature also compares predicates to see if a choice between

+      alternatives which is resolved by a predicate which makes the second

+      choice unreachable.  Consider the following example:

+

+            #pred A         <<A(LATEXT(1)>>?

+            #pred B         <<B(LATEXT(1)>>?

+            #pred A_or_B    A || B

+

+            r   : s

+                | t

+                ;

+            s   : <<A_or_B>>? ID

+                ;

+            t   : <<A>>? ID

+                ;

+

+        ----------------------------------------------------------------------------

+        t11.g, line 5: warning: the predicate used to disambiguate the

+               first choice of  rule r

+             (file t11.g alt 1 line 5 and alt 2 line 6)

+             appears to "cover" the second predicate when compared without context.

+             The second predicate may have no resolving power for some lookahead

+               sequences.

+        ----------------------------------------------------------------------------

+

+#139. (Changed in MR11) Problem with -gp in C++ mode

+

+      The -gp option to add a prefix to rule names did not work in

+      C++ mode.  This has been fixed.

+

+      Reported by Alexey Demakov (demakov@kazbek.ispras.ru).

+

+#138. (Changed in MR11) Additional makefiles for non-MSVC++ MS systems

+

+      Sramji Ramanathan (ps@kumaran.com) has supplied makefiles for

+      building antlr and dlg with Win95/NT development tools that

+      are not based on MSVC5.  They are pccts/antlr/AntlrMS.mak and

+      pccts/dlg/DlgMS.mak.

+

+      The first line of the makefiles require a definition of PCCTS_HOME.

+

+      These are in additiion to the AntlrMSVC50.* and DlgMSVC50.*

+      supplied by Jeff Vincent (JVincent@novell.com).

+

+#137. (Changed in MR11) Token getType(), getText(), getLine() const members

+

+      --------------------------------------------------------------------

+      If you use ANTLRCommonToken this change probably does not affect you.

+      --------------------------------------------------------------------

+

+      For a long time it has bothered me that these accessor functions

+      in ANTLRAbstractToken were not const member functions.  I have

+      refrained from changing them because it require users to modify

+      existing token class definitions which are derived directly

+      from ANTLRAbstractToken.  I think it is now time.

+

+      For those who are not used to C++, a "const member function" is a

+      member function which does not modify its own object - the thing

+      to which "this" points. This is quite different from a function

+      which does not modify its arguments

+

+      Most token definitions based on ANTLRAbstractToken have something like

+      the following in order to create concrete definitions of the pure

+      virtual methods in ANTLRAbstractToken:

+

+        class MyToken : public ANTLRAbstractToken {

+            ...

+            ANTLRTokenType getType() {return _type; }

+            int getLine()            {return _line; }

+            ANTLRChar * getText()    {return _text; }

+            ...

+        }

+

+      The required change is simply to put "const" following the function

+      prototype in the header (.h file) and the definition file (.cpp if

+      it is not inline):

+

+        class MyToken : public ANTLRAbstractToken {

+            ...

+            ANTLRTokenType getType() const {return _type; }

+            int getLine() const            {return _line; }

+            ANTLRChar * getText() const    {return _text; }

+            ...

+        }

+

+      This was originally proposed a long time ago by Bruce

+      Guenter (bruceg@qcc.sk.ca).

+

+#136. (Changed in MR11) Added getLength() to ANTLRCommonToken

+

+      Classes ANTLRCommonToken and ANTLRCommonTokenNoRefCountToken

+      now have a member function:

+

+            int getLength() const { return strlen(getText()) }

+

+      Suggested by Sramji Ramanathan (ps@kumaran.com).

+

+#135. (Changed in MR11) Raised antlr's own default ZZLEXBUFSIZE to 8k

+

+#134a. (ansi_mr10.zip)  T.J. Parr's ANSI C grammar made 1.33MR11 compatible

+

+       There is a typographical error in the definition of BITWISEOREQ:

+

+        #token BITWISEOREQ "!=" should be "\|="

+

+       When this change is combined with the bugfix to the follow set cache

+       problem (Item #147) and a minor rearrangement of the grammar

+       (Item #134b) it becomes a k=1 ck=2 grammar.

+

+#134b. (ansi_mr10.zip)  T.J. Parr's ANSI C grammar made 1.33MR11 compatible

+

+      The following changes were made in the ansi.g grammar (along with

+      using -mrhoist on):

+

+        ansi.g

+        ======

+        void tracein(char *)     ====>    void tracein(const char *)

+        void traceout(char *)    ====>    void traceout(const char *)

+

+        <LT(1)->getType()==IDENTIFIER ? isTypeName(LT(1)->getText()) : 1>>?

+        ====> <<isTypeName(LT(1)->getText())>>?

+

+        <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \

+                        isTypeName(LT(2)->getText()) : 1>>?

+        ====> (LPARENTHESIS IDENTIFIER)? => <<isTypeName(LT(2)->getText())>>?

+

+        <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \

+                        isTypeName(LT(2)->getText()) : 1>>?

+        ====> (LPARENTHESIS IDENTIFIER)? => <<isTypeName(LT(2)->getText())>>?

+

+        added to init(): traceOptionValueDefault=0;

+        added to init(): traceOption(-1);

+

+        change rule "statement":

+

+            statement

+                :   plain_label_statement

+                |   case_label_statement

+                |   <<;>> expression SEMICOLON

+                |   compound_statement

+                |   selection_statement

+                |   iteration_statement

+                |   jump_statement

+                |   SEMICOLON

+                ;

+

+            plain_label_statement

+                :   IDENTIFIER COLON statement

+                ;

+

+            case_label_statement

+                :   CASE constant_expression COLON statement

+                |   DEFAULT COLON statement

+            ;

+

+        support.cpp

+        ===========

+        void tracein(char *)     ====>    void tracein(const char *)

+        void traceout(char *)    ====>    void traceout(const char *)

+

+        added to tracein():  ANTLRParser::tracein(r);  // call superclass method

+        added to traceout(): ANTLRParser::traceout(r); // call superclass method

+

+        Makefile

+        ========

+        added to AFLAGS: -mrhoist on -prc on

+

+#133. (Changed in 1.33MR11) Make trace options public in ANTLRParser

+

+      In checking T.J. Parr's ANSI C grammar for compatibility with

+      1.33MR11 discovered that it was inconvenient to have the

+      trace facilities with protected access.

+

+#132. (Changed in 1.33MR11) Recognition of identical predicates in alts

+

+      Prior to 1.33MR11, there would be no ambiguity warning when the

+      very same predicate was used to disambiguate both alternatives:

+

+        test: ref B

+            | ref C

+            ;

+

+        ref : <<pred(LATEXT(1)>>? A

+

+      In 1.33MR11 this will cause the warning:

+

+        warning: the predicates used to disambiguate rule test

+            (file v98.g alt 1 line 1 and alt 2 line 2)

+             are identical and have no resolving power

+

+        -----------------  Note  -----------------

+

+          This is different than the following case

+

+                test: <<pred(LATEXT(1))>>? A B

+                    | <<pred(LATEXT(1)>>?  A C

+                    ;

+

+          In this case there are two distinct predicates

+          which have exactly the same text.  In the first

+          example there are two references to the same

+          predicate.  The problem represented by this

+          grammar will be addressed later.

+

+#131. (Changed in 1.33MR11) Case insensitive command line options

+

+      Command line switches like "-CC" and keywords like "on", "off",

+      and "stdin" are no longer case sensitive in antlr, dlg, and sorcerer.

+

+#130. (Changed in 1.33MR11) Changed ANTLR_VERSION to int from string

+

+      The ANTLR_VERSION was not an integer, making it difficult to

+      perform conditional compilation based on the antlr version.

+

+      Henceforth, ANTLR_VERSION will be:

+

+            (base_version * 10000) + release number

+

+            thus 1.33MR11 will be: 133*100+11 = 13311

+

+      Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE).

+

+#129. (Changed in 1.33MR11) Addition of ANTLR_VERSION to <parserName>.h

+

+      The following code is now inserted into <parserName>.h amd

+      stdpccts.h:

+

+            #ifndef ANTLR_VERSION

+            #define ANTLR_VERSION 13311

+            #endif

+

+      Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE)

+

+#128. (Changed in 1.33MR11) Redundant predicate code in (<<pred>>? ...)+

+

+      Prior to 1.33MR11, the following grammar would generate

+      redundant tests for the "while" condition.

+

+        rule2 : (<<pred>>? X)+ X

+              | B

+              ;

+

+      The code would resemble:

+

+            if (LA(1)==X) {

+                if (pred) {

+                    do {

+                        if (!pred) {zzfailed_pred("  pred");}

+                        zzmatch(X); zzCONSUME;

+                    } while (LA(1)==X && pred && pred);

+            } else {...

+

+      With 1.33MR11 the redundant predicate test is omitted.

+

+#127. (Changed in 1.33MR11)

+

+                    Count Syntax Errors     Count DLG Errors

+                    -------------------     ----------------

+

+       C++ mode     ANTLRParser::           DLGLexerBase::

+                      syntaxErrCount          lexErrCount

+       C mode       zzSyntaxErrCount        zzLexErrCount

+

+       The C mode variables are global and initialized to 0.

+       They are *not* reset to 0 automatically when antlr is

+       restarted.

+

+       The C++ mode variables are public.  They are initialized

+       to 0 by the constructors.  They are *not* reset to 0 by the

+       ANTLRParser::init() method.

+

+       Suggested by Reinier van den Born (reinier@vnet.ibm.com).

+

+#126. (Changed in 1.33MR11) Addition of #first <<...>>

+

+       The #first <<...>> inserts the specified text in the output

+       files before any other #include statements required by pccts.

+       The only things before the #first text are comments and

+       a #define ANTLR_VERSION.

+

+       Requested by  and Esa Pulkkinen (esap@cs.tut.fi) and Alexin

+       Zoltan (alexin@inf.u-szeged.hu).

+

+#125. (Changed in 1.33MR11) Lookahead for (guard)? && <<p>>? predicates

+

+       When implementing the new style of guard predicate (Item #113)

+       in 1.33MR10 I decided to temporarily ignore the problem of

+       computing the "narrowest" lookahead context.

+

+       Consider the following k=1 grammar:

+

+            start : a

+                  | b

+                  ;

+

+            a     : (A)? && <<pred1(LATEXT(1))>>? ab ;

+            b     : (B)? && <<pred2(LATEXT(1))>>? ab ;

+

+            ab    : A | B ;

+

+       In MR10 the context for both "a" and "b" was {A B} because this is

+       the first set of rule "ab".  Normally, this is not a problem because

+       the predicate which follows the guard inhibits any ambiguity report

+       by antlr.

+

+       In MR11 the first set for rule "a" is {A} and for rule "b" it is {B}.

+

+#124. A Note on the New "&&" Style Guarded Predicates

+

+        I've been asked several times, "What is the difference between

+        the old "=>" style guard predicates and the new style "&&" guard

+        predicates, and how do you choose one over the other" ?

+

+        The main difference is that the "=>" does not apply the

+        predicate if the context guard doesn't match, whereas

+        the && form always does.  What is the significance ?

+

+        If you have a predicate which is not on the "leading edge"

+        it cannot be hoisted.  Suppose you need a predicate that

+        looks at LA(2).  You must introduce it manually.  The

+        classic example is:

+

+            castExpr :

+                     LP typeName RP

+                     | ....

+                     ;

+

+            typeName : <<isTypeName(LATEXT(1))>>?  ID

+                     | STRUCT ID

+                     ;

+

+        The problem  is that typeName isn't on the leading edge

+        of castExpr, so the predicate isTypeName won't be hoisted into

+        castExpr to help make a decision on which production to choose.

+

+        The *first* attempt to fix it is this:

+

+            castExpr :

+                     <<isTypeName(LATEXT(2))>>?

+                                        LP typeName RP

+                     | ....

+                     ;

+

+        Unfortunately, this won't work because it ignores

+        the problem of STRUCT.  The solution is to apply

+        isTypeName() in castExpr if LA(2) is an ID and

+        don't apply it when LA(2) is STRUCT:

+

+            castExpr :

+                     (LP ID)? => <<isTypeName(LATEXT(2))>>?

+                                        LP typeName RP

+                     | ....

+                     ;

+

+        In conclusion, the "=>" style guarded predicate is

+        useful when:

+

+            a. the tokens required for the predicate

+               are not on the leading edge

+            b. there are alternatives in the expression

+               selected by the predicate for which the

+               predicate is inappropriate

+

+        If (b) were false, then one could use a simple

+        predicate (assuming "-prc on"):

+

+            castExpr :

+                     <<isTypeName(LATEXT(2))>>?

+                                        LP typeName RP

+                     | ....

+                     ;

+

+            typeName : <<isTypeName(LATEXT(1))>>?  ID

+                     ;

+

+        So, when do you use the "&&" style guarded predicate ?

+

+        The new-style "&&" predicate should always be used with

+        predicate context.  The context guard is in ADDITION to

+        the automatically computed context.  Thus it useful for

+        predicates which depend on the token type for reasons

+        other than context.

+

+        The following example is contributed by Reinier van den Born

+        (reinier@vnet.ibm.com).

+

+ +-------------------------------------------------------------------------+

+ | This grammar has two ways to call functions:                            |

+ |                                                                         |

+ |  - a "standard" call syntax with parens and comma separated args        |

+ |  - a shell command like syntax (no parens and spacing separated args)   |

+ |                                                                         |

+ | The former also allows a variable to hold the name of the function,     |

+ | the latter can also be used to call external commands.                  |

+ |                                                                         |

+ | The grammar (simplified) looks like this:                               |

+ |                                                                         |

+ |   fun_call   :     ID "(" { expr ("," expr)* } ")"                      |

+ |                                  /* ID is function name */              |

+ |              | "@" ID "(" { expr ("," expr)* } ")"                      |

+ |                                  /* ID is var containing fun name */    |

+ |              ;                                                          |

+ |                                                                         |

+ |   command    : ID expr*          /* ID is function name */              |

+ |              | path expr*        /* path is external command name */    |

+ |              ;                                                          |

+ |                                                                         |

+ |   path       : ID                /* left out slashes and such */        |

+ |              | "@" ID            /* ID is environment var */            |

+ |              ;                                                          |

+ |                                                                         |

+ |   expr       : ....                                                     |

+ |              | "(" expr ")";                                            |

+ |                                                                         |

+ |   call       : fun_call                                                 |

+ |              | command                                                  |

+ |              ;                                                          |

+ |                                                                         |

+ | Obviously the call is wildly ambiguous. This is more or less how this   |

+ | is to be resolved:                                                      |

+ |                                                                         |

+ |    A call begins with an ID or an @ followed by an ID.                  |

+ |                                                                         |

+ |    If it is an ID and if it is an ext. command name  -> command         |

+ |                       if followed by a paren         -> fun_call        |

+ |                       otherwise                      -> command         |

+ |                                                                         |

+ |    If it is an @  and if the ID is a var name        -> fun_call        |

+ |                       otherwise                      -> command         |

+ |                                                                         |

+ | One can implement these rules quite neatly using && predicates:         |

+ |                                                                         |

+ |   call       : ("@" ID)? && <<isVarName(LT(2))>>? fun_call              |

+ |              | (ID)?     && <<isExtCmdName>>?     command               |

+ |              | (ID "(")?                          fun_call              |

+ |              |                                    command               |

+ |              ;                                                          |

+ |                                                                         |

+ | This can be done better, so it is not an ideal example, but it          |

+ | conveys the principle.                                                  |

+ +-------------------------------------------------------------------------+

+

+#123. (Changed in 1.33MR11) Correct definition of operators in ATokPtr.h

+

+        The return value of operators in ANTLRTokenPtr:

+

+        changed: unsigned ... operator !=(...)

+             to: int ... operator != (...)

+        changed: unsigned ... operator ==(...)

+             to: int ... operator == (...)

+

+        Suggested by R.A. Nelson (cowboy@VNET.IBM.COM)

+

+#122. (Changed in 1.33MR11)  Member functions to reset DLG in C++ mode

+

+         void DLGFileReset(FILE *f) { input = f; found_eof = 0; }

+         void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; }

+

+        Supplied by R.A. Nelson (cowboy@VNET.IBM.COM)

+

+#121. (Changed in 1.33MR11)  Another attempt to fix -o (output dir) option

+

+      Another attempt is made to improve the -o option of antlr, dlg,

+      and sorcerer.  This one by JVincent (JVincent@novell.com).

+

+      The current rule:

+

+        a. If -o  is not specified than any explicit directory

+           names are retained.

+

+        b. If -o is specified than the -o directory name overrides any

+           explicit directory names.

+

+        c. The directory name of the grammar file is *not* stripped

+           to create the main output file.  However it is stil subject

+           to override by the -o directory name.

+

+#120. (Changed in 1.33MR11) "-info f" output to stdout rather than stderr

+

+      Added option 0 (e.g. "-info 0") which is a noop.

+

+#119. (Changed in 1.33MR11) Ambiguity aid for grammars

+

+      The user can ask for additional information on ambiguities reported

+      by antlr to stdout.  At the moment, only one ambiguity report can

+      be created in an antlr run.

+

+      This feature is enabled using the "-aa" (Ambiguity Aid)  option.

+

+      The following options control the reporting of ambiguities:

+

+          -aa ruleName       Selects reporting by name of rule

+          -aa lineNumber     Selects reporting by line number

+                               (file name not compared)

+

+          -aam               Selects "multiple" reporting for a token

+                             in the intersection set of the

+                             alternatives.

+

+                             For instance, the token ID may appear dozens

+                             of times in various paths as the program

+                             explores the rules which are reachable from

+                             the point of an ambiguity. With option -aam

+                             every possible path the search program

+                             encounters is reported.

+

+                             Without -aam only the first encounter is

+                             reported.  This may result in incomplete

+                             information, but the information may be

+                             sufficient and much shorter.

+

+          -aad depth         Selects the depth of the search.

+                             The default value is 1.

+

+                             The number of paths to be searched, and the

+                             size of the report can grow geometrically

+                             with the -ck value if a full search for all

+                             contributions to the source of the ambiguity

+                             is explored.

+

+                             The depth represents the number of tokens

+                             in the lookahead set which are matched against

+                             the set of ambiguous tokens.  A depth of 1

+                             means that the search stops when a lookahead

+                             sequence of just one token is matched.

+

+                             A k=1 ck=6 grammar might generate 5,000 items

+                             in a report if a full depth 6 search is made

+                             with the Ambiguity Aid.  The source of the

+                             problem may be in the first token and obscured

+                             by the volume of data - I hesitate to call

+                             it information.

+

+                             When the user selects a depth > 1, the search

+                             is first performed at depth=1 for both

+                             alternatives, then depth=2 for both alternatives,

+                             etc.

+

+      Sample output for rule grammar in antlr.g itself:

+

+  +---------------------------------------------------------------------+

+  | Ambiguity Aid                                                       |

+  |                                                                     |

+  |   Choice 1: grammar/70                 line 632  file a.g           |

+  |   Choice 2: grammar/82                 line 644  file a.g           |

+  |                                                                     |

+  |   Intersection of lookahead[1] sets:                                |

+  |                                                                     |

+  |      "\}"             "class"          "#errclass"      "#tokclass" |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:1  ("#errclass")                        |

+  |  1 in (...)* block                grammar/70       line 632   a.g   |

+  |  2 to error                       grammar/73       line 635   a.g   |

+  |  3 error                          error/1          line 894   a.g   |

+  |  4 #token "#errclass"             error/2          line 895   a.g   |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:2  ("#tokclass")                        |

+  |  2 to tclass                      grammar/74       line 636   a.g   |

+  |  3 tclass                         tclass/1         line 937   a.g   |

+  |  4 #token "#tokclass"             tclass/2         line 938   a.g   |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:3  ("class")                            |

+  |  2 to class_def                   grammar/75       line 637   a.g   |

+  |  3 class_def                      class_def/1      line 669   a.g   |

+  |  4 #token "class"                 class_def/3      line 671   a.g   |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:4  ("\}")                               |

+  |  2 #token "\}"                    grammar/76       line 638   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:5  ("#errclass")                        |

+  |  1 in (...)* block                grammar/83       line 645   a.g   |

+  |  2 to error                       grammar/93       line 655   a.g   |

+  |  3 error                          error/1          line 894   a.g   |

+  |  4 #token "#errclass"             error/2          line 895   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:6  ("#tokclass")                        |

+  |  2 to tclass                      grammar/94       line 656   a.g   |

+  |  3 tclass                         tclass/1         line 937   a.g   |

+  |  4 #token "#tokclass"             tclass/2         line 938   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:7  ("class")                            |

+  |  2 to class_def                   grammar/95       line 657   a.g   |

+  |  3 class_def                      class_def/1      line 669   a.g   |

+  |  4 #token "class"                 class_def/3      line 671   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:8  ("\}")                               |

+  |  2 #token "\}"                    grammar/96       line 658   a.g   |

+  +---------------------------------------------------------------------+

+

+      For a linear lookahead set ambiguity (where k=1 or for k>1 but

+      when all lookahead sets [i] with i<k all have degree one) the

+      reports appear in the following order:

+

+        for (depth=1 ; depth <= "-aad depth" ; depth++) {

+          for (alternative=1; alternative <=2 ; alternative++) {

+            while (matches-are-found) {

+              group++;

+              print-report

+            };

+          };

+       };

+

+      For reporting a k-tuple ambiguity, the reports appear in the

+      following order:

+

+        for (depth=1 ; depth <= "-aad depth" ; depth++) {

+          while (matches-are-found) {

+            for (alternative=1; alternative <=2 ; alternative++) {

+              group++;

+              print-report

+            };

+          };

+       };

+

+      This is because matches are generated in different ways for

+      linear lookahead and k-tuples.

+

+#118. (Changed in 1.33MR11) DEC VMS makefile and VMS related changes

+

+      Revised makefiles for DEC/VMS operating system for antlr, dlg,

+      and sorcerer.

+

+      Reduced names of routines with external linkage to less than 32

+      characters to conform to DEC/VMS linker limitations.

+

+      Jean-Francois Pieronne discovered problems with dlg and antlr

+      due to the VMS linker not being case sensitive for names with

+      external linkage.  In dlg the problem was with "className" and

+      "ClassName".  In antlr the problem was with "GenExprSets" and

+      "genExprSets".

+

+      Added genmms, a version of genmk for the DEC/VMS version of make.

+      The source is in directory pccts/support/DECmms.

+

+      All VMS contributions by Jean-Francois Pieronne (jfp@iname.com).

+

+#117. (Changed in 1.33MR10) new EXPERIMENTAL predicate hoisting code

+

+      The hoisting of predicates into rules to create prediction

+      expressions is a problem in antlr.  Consider the following

+      example (k=1 with -prc on):

+

+        start   : (a)* "@" ;

+        a       : b | c ;

+        b       : <<isUpper(LATEXT(1))>>? A ;

+        c       : A ;

+

+      Prior to 1.33MR10 the code generated for "start" would resemble:

+

+        while {

+            if (LA(1)==A &&

+                    (!LA(1)==A || isUpper())) {

+              a();

+            }

+        };

+

+      This code is wrong because it makes rule "c" unreachable from

+      "start".  The essence of the problem is that antlr fails to

+      recognize that there can be a valid alternative within "a" even

+      when the predicate <<isUpper(LATEXT(1))>>? is false.

+

+      In 1.33MR10 with -mrhoist the hoisting of the predicate into

+      "start" is suppressed because it recognizes that "c" can

+      cover all the cases where the predicate is false:

+

+        while {

+            if (LA(1)==A) {

+              a();

+            }

+        };

+

+      With the antlr "-info p" switch the user will receive information

+      about the predicate suppression in the generated file:

+

+      --------------------------------------------------------------

+        #if 0

+

+        Hoisting of predicate suppressed by alternative without predicate.

+        The alt without the predicate includes all cases where

+            the predicate is false.

+

+           WITH predicate: line 7  v1.g

+           WITHOUT predicate: line 7  v1.g

+

+        The context set for the predicate:

+

+             A

+

+        The lookahead set for the alt WITHOUT the semantic predicate:

+

+             A

+

+        The predicate:

+

+          pred <<  isUpper(LATEXT(1))>>?

+                          depth=k=1  rule b  line 9  v1.g

+            set context:

+               A

+            tree context: null

+

+        Chain of referenced rules:

+

+            #0  in rule start (line 5 v1.g) to rule a

+            #1  in rule a (line 7 v1.g)

+

+        #endif

+      --------------------------------------------------------------

+

+      A predicate can be suppressed by a combination of alternatives

+      which, taken together, cover a predicate:

+

+        start   : (a)* "@" ;

+

+        a       : b | ca | cb | cc ;

+

+        b       : <<isUpper(LATEXT(1))>>? ( A | B | C ) ;

+

+        ca      : A ;

+        cb      : B ;

+        cc      : C ;

+

+      Consider a more complex example in which "c" covers only part of

+      a predicate:

+

+        start   : (a)* "@" ;

+

+        a       : b

+                | c

+                ;

+

+        b       : <<isUpper(LATEXT(1))>>?

+                    ( A

+                    | X

+                    );

+

+        c       : A

+                ;

+

+      Prior to 1.33MR10 the code generated for "start" would resemble:

+

+        while {

+            if ( (LA(1)==A || LA(1)==X) &&

+                    (! (LA(1)==A || LA(1)==X) || isUpper()) {

+              a();

+            }

+        };

+

+      With 1.33MR10 and -mrhoist the predicate context is restricted to

+      the non-covered lookahead.  The code resembles:

+

+        while {

+            if ( (LA(1)==A || LA(1)==X) &&

+                  (! (LA(1)==X) || isUpper()) {

+              a();

+            }

+        };

+

+      With the antlr "-info p" switch the user will receive information

+      about the predicate restriction in the generated file:

+

+      --------------------------------------------------------------

+        #if 0

+

+        Restricting the context of a predicate because of overlap

+          in the lookahead set between the alternative with the

+          semantic predicate and one without

+        Without this restriction the alternative without the predicate

+          could not be reached when input matched the context of the

+          predicate and the predicate was false.

+

+           WITH predicate: line 11  v4.g

+           WITHOUT predicate: line 12  v4.g

+

+        The original context set for the predicate:

+

+             A                X

+

+        The lookahead set for the alt WITHOUT the semantic predicate:

+

+             A

+

+        The intersection of the two sets

+

+             A

+

+        The original predicate:

+

+          pred <<  isUpper(LATEXT(1))>>?

+                          depth=k=1  rule b  line 15  v4.g

+            set context:

+               A                X

+            tree context: null

+

+        The new (modified) form of the predicate:

+

+          pred <<  isUpper(LATEXT(1))>>?

+                          depth=k=1  rule b  line 15  v4.g

+            set context:

+               X

+            tree context: null

+

+        #endif

+      --------------------------------------------------------------

+

+      The bad news about -mrhoist:

+

+        (a) -mrhoist does not analyze predicates with lookahead

+            depth > 1.

+

+        (b) -mrhoist does not look past a guarded predicate to

+            find context which might cover other predicates.

+

+      For these cases you might want to use syntactic predicates.

+      When a semantic predicate fails during guess mode the guess

+      fails and the next alternative is tried.

+

+      Limitation (a) is illustrated by the following example:

+

+        start    : (stmt)* EOF ;

+

+        stmt     : cast

+                 | expr

+                 ;

+        cast     : <<isTypename(LATEXT(2))>>? LP ID RP ;

+

+        expr     : LP ID RP ;

+

+      This is not much different from the first example, except that

+      it requires two tokens of lookahead context to determine what

+      to do.  This predicate is NOT suppressed because the current version

+      is unable to handle predicates with depth > 1.

+

+      A predicate can be combined with other predicates during hoisting.

+      In those cases the depth=1 predicates are still handled.  Thus,

+      in the following example the isUpper() predicate will be suppressed

+      by line #4 when hoisted from "bizarre" into "start", but will still

+      be present in "bizarre" in order to predict "stmt".

+

+        start    : (bizarre)* EOF ;     // #1

+                                        // #2

+        bizarre  : stmt                 // #3

+                 | A                    // #4

+                 ;

+

+        stmt     : cast

+                 | expr

+                 ;

+

+        cast     : <<isTypename(LATEXT(2))>>? LP ID RP ;

+

+        expr     : LP ID RP ;

+                 | <<isUpper(LATEXT(1))>>? A

+

+      Limitation (b) is illustrated by the following example of a

+      context guarded predicate:

+

+        rule : (A)? <<p>>?          // #1

+                     (A             // #2

+                     |B             // #3

+                     )              // #4

+             | <<q>> B              // #5

+             ;

+

+      Recall that this means that when the lookahead is NOT A then

+      the predicate "p" is ignored and it attempts to match "A|B".

+      Ideally, the "B" at line #3 should suppress predicate "q".

+      However, the current version does not attempt to look past

+      the guard predicate to find context which might suppress other

+      predicates.

+

+      In some cases -mrhoist will lead to the reporting of ambiguities

+      which were not visible before:

+

+        start   : (a)* "@";

+        a       : bc | d;

+        bc      : b  | c ;

+

+        b       : <<isUpper(LATEXT(1))>>? A;

+        c       : A ;

+

+        d       : A ;

+

+      In this case there is a true ambiguity in "a" between "bc" and "d"

+      which can both match "A".  Without -mrhoist the predicate in "b"

+      is hoisted into "a" and there is no ambiguity reported.  However,

+      with -mrhoist, the predicate in "b" is suppressed by "c" (as it

+      should be) making the ambiguity in "a" apparent.

+

+      The motivations for these changes were hoisting problems reported

+      by Reinier van den Born (reinier@vnet.ibm.com) and several others.

+

+#116. (Changed in 1.33MR10) C++ mode: tracein/traceout rule name is (const char *)

+

+      The prototype for C++ mode routine tracein (and traceout) has changed from

+      "char *" to "const char *".

+

+#115. (Changed in 1.33MR10) Using guess mode with exception handlers in C mode

+

+      The definition of the C mode macros zzmatch_wsig and zzsetmatch_wsig

+      neglected to consider guess mode.  When control passed to the rule's

+      parse exception handler the routine would exit without ever closing the

+      guess block. This would lead to unpredictable behavior.

+

+      In 1.33MR10 the behavior of exceptions in C mode and C++ mode should be

+      identical.

+

+#114. (Changed in 1.33MR10) difference in [zz]resynch() between C and C++ modes

+

+      There was a slight difference in the way C and C++ mode resynchronized

+      following a parsing error.  The C routine would sometimes skip an extra

+      token before attempting to resynchronize.

+

+      The C routine was changed to match the C++ routine.

+

+#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <<p>>? expr

+

+      The existing context guarded predicate:

+

+            rule : (guard)? => <<p>>? expr

+                 | next_alternative

+                 ;

+

+      generates code which resembles:

+

+            if (lookahead(expr) && (!guard || pred)) {

+              expr()

+            } else ....

+

+      This is not suitable for some applications because it allows

+      expr() to be invoked when the predicate is false.  This is

+      intentional because it is meant to mimic automatically computed

+      predicate context.

+

+      The new context guarded predicate uses the guard information

+      differently because it has a different goal.  Consider:

+

+            rule : (guard)? && <<p>>? expr

+                 | next_alternative

+                 ;

+

+      The new style of context guarded predicate is equivalent to:

+

+            rule : <<guard==true && pred>>? expr

+                 | next_alternative

+                 ;

+

+      It generates code which resembles:

+

+            if (lookahead(expr) && guard && pred) {

+                expr();

+            } else ...

+

+      Both forms of guarded predicates severely restrict the form of

+      the context guard: it can contain no rule references, no

+      (...)*, no (...)+, and no {...}.  It may contain token and

+      token class references, and alternation ("|").

+

+      Addition for 1.33MR11: in the token expression all tokens must

+      be at the same height of the token tree:

+

+            (A ( B | C))? && ...            is ok (all height 2)

+            (A ( B |  ))? && ...            is not ok (some 1, some 2)

+            (A B C D | E F G H)? && ...     is ok (all height 4)

+            (A B C D | E )? && ...          is not ok (some 4, some 1)

+

+      This restriction is required in order to properly compute the lookahead

+      set for expressions like:

+

+            rule1 : (A B C)? && <<pred>>? rule2 ;

+            rule2 : (A|X) (B|Y) (C|Z);

+

+      This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com)

+

+#112. (Changed in 1.33MR10) failed validation predicate in C guess mode

+

+      John Lilley (jlilley@empathy.com) suggested that failed validation

+      predicates abort a guess rather than reporting a failed error.

+      This was installed in C++ mode (Item #4).  Only now was it noticed

+      that the fix was never installed for C mode.

+

+#111. (Changed in 1.33MR10) moved zzTRACEIN to before init action

+

+      When the antlr -gd switch is present antlr generates calls to

+      zzTRACEIN at the start of a rule and zzTRACEOUT at the exit

+      from a rule.  Prior to 1.33MR10 Tthe call to zzTRACEIN was

+      after the init-action, which could cause confusion because the

+      init-actions were reported with the name of the enclosing rule,

+      rather than the active rule.

+

+#110. (Changed in 1.33MR10) antlr command line copied to generated file

+

+      The antlr command line is now copied to the generated file near

+      the start.

+

+#109. (Changed in 1.33MR10) improved trace information

+

+      The quality of the trace information provided by the "-gd"

+      switch has been improved significantly.  Here is an example

+      of the output from a test program.  It shows the rule name,

+      the first token of lookahead, the call depth, and the guess

+      status:

+

+        exit rule gusxx {"?"} depth 2

+        enter rule gusxx {"?"} depth 2

+        enter rule gus1 {"o"} depth 3 guessing

+        guess done - returning to rule gus1 {"o"} at depth 3

+                    (guess mode continues - an enclosing guess is still active)

+        guess done - returning to rule gus1 {"Z"} at depth 3

+                    (guess mode continues - an enclosing guess is still active)

+        exit rule gus1 {"Z"} depth 3 guessing

+        guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends)

+        enter rule gus1 {"o"} depth 3

+        guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends)

+        guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends)

+        exit rule gus1 {"Z"} depth 3

+        line 1: syntax error at "Z" missing SC

+            ...

+

+      Rule trace reporting is controlled by the value of the integer

+      [zz]traceOptionValue:  when it is positive tracing is enabled,

+      otherwise it is disabled.  Tracing during guess mode is controlled

+      by the value of the integer [zz]traceGuessOptionValue.  When

+      it is positive AND [zz]traceOptionValue is positive rule trace

+      is reported in guess mode.

+

+      The values of [zz]traceOptionValue and [zz]traceGuessOptionValue

+      can be adjusted by subroutine calls listed below.

+

+      Depending on the presence or absence of the antlr -gd switch

+      the variable [zz]traceOptionValueDefault is set to 0 or 1.  When

+      the parser is initialized or [zz]traceReset() is called the

+      value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue.

+      The value of [zz]traceGuessOptionValue is always initialzed to 1,

+      but, as noted earlier, nothing will be reported unless

+      [zz]traceOptionValue is also positive.

+

+      When the parser state is saved/restored the value of the trace

+      variables are also saved/restored.  If a restore causes a change in

+      reporting behavior from on to off or vice versa this will be reported.

+

+      When the -gd option is selected, the macro "#define zzTRACE_RULES"

+      is added to appropriate output files.

+

+        C++ mode

+        --------

+        int     traceOption(int delta)

+        int     traceGuessOption(int delta)

+        void    traceReset()

+        int     traceOptionValueDefault

+

+        C mode

+        --------

+        int     zzTraceOption(int delta)

+        int     zzTraceGuessOption(int delta)

+        void    zzTraceReset()

+        int     zzTraceOptionValueDefault

+

+      The argument "delta" is added to the traceOptionValue.  To

+      turn on trace when inside a particular rule one:

+

+        rule : <<traceOption(+1);>>

+               (

+                rest-of-rule

+               )

+               <<traceOption(-1);>>

+       ;  /* fail clause */ <<traceOption(-1);>>

+

+      One can use the same idea to turn *off* tracing within a

+      rule by using a delta of (-1).

+

+      An improvement in the rule trace was suggested by Sramji

+      Ramanathan (ps@kumaran.com).

+

+#108. A Note on Deallocation of Variables Allocated in Guess Mode

+

+                            NOTE

+        ------------------------------------------------------

+        This mechanism only works for heap allocated variables

+        ------------------------------------------------------

+

+      The rewrite of the trace provides the machinery necessary

+      to properly free variables or undo actions following a

+      failed guess.

+

+      The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded

+      as part of the zzGUESS macro.  When a guess is opened

+      the value of zzrv is 0.  When a longjmp() is executed to

+      undo the guess, the value of zzrv will be 1.

+

+      The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded

+      as part of the zzGUESS_DONE macro.  This is executed

+      whether the guess succeeds or fails as part of closing

+      the guess.

+

+      The guessSeq is a sequence number which is assigned to each

+      guess and is incremented by 1 for each guess which becomes

+      active.  It is needed by the user to associate the start of

+      a guess with the failure and/or completion (closing) of a

+      guess.

+

+      Guesses are nested.  They must be closed in the reverse

+      of the order that they are opened.

+

+      In order to free memory used by a variable during a guess

+      a user must write a routine which can be called to

+      register the variable along with the current guess sequence

+      number provided by the zzUSER_GUESS_HOOK macro. If the guess

+      fails, all variables tagged with the corresponding guess

+      sequence number should be released.  This is ugly, but

+      it would require a major rewrite of antlr 1.33 to use

+      some mechanism other than setjmp()/longjmp().

+

+      The order of calls for a *successful* guess would be:

+

+        zzUSER_GUESS_HOOK(guessSeq,0);

+        zzUSER_GUESS_DONE_HOOK(guessSeq);

+

+      The order of calls for a *failed* guess would be:

+

+        zzUSER_GUESS_HOOK(guessSeq,0);

+        zzUSER_GUESS_HOOK(guessSeq,1);

+        zzUSER_GUESS_DONE_HOOK(guessSeq);

+

+      The default definitions of these macros are empty strings.

+

+      Here is an example in C++ mode.  The zzUSER_GUESS_HOOK and

+      zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine

+      can be used without change in both C and C++ versions.

+

+      ----------------------------------------------------------------------

+        <<

+

+        #include "AToken.h"

+

+        typedef ANTLRCommonToken ANTLRToken;

+

+        #include "DLGLexer.h"

+

+        int main() {

+

+          {

+            DLGFileInput     in(stdin);

+            DLGLexer         lexer(&in,2000);

+            ANTLRTokenBuffer pipe(&lexer,1);

+            ANTLRCommonToken aToken;

+            P                parser(&pipe);

+

+            lexer.setToken(&aToken);

+            parser.init();

+            parser.start();

+          };

+

+          fclose(stdin);

+          fclose(stdout);

+          return 0;

+        }

+

+        >>

+

+        <<

+        char *s=NULL;

+

+        #undef zzUSER_GUESS_HOOK

+        #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv);

+        #undef zzUSER_GUESS_DONE_HOOK

+        #define zzUSER_GUESS_DONE_HOOK(guessSeq)   myGuessHook(guessSeq,2);

+

+        void myGuessHook(int guessSeq,int zzrv) {

+          if (zzrv == 0) {

+            fprintf(stderr,"User hook: starting guess #%d\n",guessSeq);

+          } else if (zzrv == 1) {

+            free (s);

+            s=NULL;

+            fprintf(stderr,"User hook: failed guess #%d\n",guessSeq);

+          } else if (zzrv == 2) {

+            free (s);

+            s=NULL;

+            fprintf(stderr,"User hook: ending guess #%d\n",guessSeq);

+          };

+        }

+

+        >>

+

+        #token A    "a"

+        #token      "[\t \ \n]"     <<skip();>>

+

+        class P {

+

+        start : (top)+

+              ;

+

+        top   : (which) ?   <<fprintf(stderr,"%s is a which\n",s); free(s); s=NULL; >>

+              | other       <<fprintf(stderr,"%s is an other\n",s); free(s); s=NULL; >>

+              ; <<if (s != NULL) free(s); s=NULL; >>

+

+        which : which2

+              ;

+

+        which2 : which3

+              ;

+        which3

+              : (label)?         <<fprintf(stderr,"%s is a label\n",s);>>

+              | (global)?        <<fprintf(stderr,"%s is a global\n",s);>>

+              | (exclamation)?   <<fprintf(stderr,"%s is an exclamation\n",s);>>

+              ;

+

+        label :       <<s=strdup(LT(1)->getText());>> A ":" ;

+

+        global :      <<s=strdup(LT(1)->getText());>> A "::" ;

+

+        exclamation : <<s=strdup(LT(1)->getText());>> A "!" ;

+

+        other :       <<s=strdup(LT(1)->getText());>> "other" ;

+

+        }

+      ----------------------------------------------------------------------

+

+      This is a silly example, but illustrates the idea.  For the input

+      "a ::" with tracing enabled the output begins:

+

+      ----------------------------------------------------------------------

+        enter rule "start" depth 1

+        enter rule "top" depth 2

+        User hook: starting guess #1

+        enter rule "which" depth 3 guessing

+        enter rule "which2" depth 4 guessing

+        enter rule "which3" depth 5 guessing

+        User hook: starting guess #2

+        enter rule "label" depth 6 guessing

+        guess failed

+        User hook: failed guess #2

+        guess done - returning to rule "which3" at depth 5 (guess mode continues

+                                                 - an enclosing guess is still active)

+        User hook: ending guess #2

+        User hook: starting guess #3

+        enter rule "global" depth 6 guessing

+        exit rule "global" depth 6 guessing

+        guess done - returning to rule "which3" at depth 5 (guess mode continues

+                                                 - an enclosing guess is still active)

+        User hook: ending guess #3

+        enter rule "global" depth 6 guessing

+        exit rule "global" depth 6 guessing

+        exit rule "which3" depth 5 guessing

+        exit rule "which2" depth 4 guessing

+        exit rule "which" depth 3 guessing

+        guess done - returning to rule "top" at depth 2 (guess mode ends)

+        User hook: ending guess #1

+        enter rule "which" depth 3

+        .....

+      ----------------------------------------------------------------------

+

+      Remember:

+

+        (a) Only init-actions are executed during guess mode.

+        (b) A rule can be invoked multiple times during guess mode.

+        (c) If the guess succeeds the rule will be called once more

+              without guess mode so that normal actions will be executed.

+            This means that the init-action might need to distinguish

+              between guess mode and non-guess mode using the variable

+              [zz]guessing.

+

+#107. (Changed in 1.33MR10) construction of ASTs in guess mode

+

+      Prior to 1.33MR10, when using automatic AST construction in C++

+      mode for a rule, an AST would be constructed for elements of the

+      rule even while in guess mode.  In MR10 this no longer occurs.

+

+#106. (Changed in 1.33MR10) guess variable confusion

+

+      In C++ mode a guess which failed always restored the parser state

+      using zzGUESS_DONE as part of zzGUESS_FAIL. Prior to 1.33MR10,

+      C mode required an explicit call to zzGUESS_DONE after the

+      call to zzGUESS_FAIL.

+

+      Consider:

+

+        rule : (alpha)? beta

+             | ...

+             ;

+

+      The generated code resembles:

+

+            zzGUESS

+            if (!zzrv && LA(1)==ID) {   <==== line #1

+                alpha

+                zzGUESS_DONE

+                beta

+            } else {

+              if (! zzrv) zzGUESS_DONE  <==== line #2a

+              ....

+

+      However, in some cases line #2 was rendered:

+

+              if (guessing) zzGUESS_DONE  <==== line #2b

+

+      This would work for simple test cases, but would fail in

+      some cases where there was a guess while another guess was active.

+      One kind of failure would be to match up the zzGUESS_DONE at line

+      #2b with the "outer" guess which was still active.  The outer

+      guess would "succeed" when only the inner guess should have

+      succeeded.

+

+      In 1.33MR10 the behavior of zzGUESS and zzGUESS_FAIL in C and

+      and C++ mode should be identical.

+

+      The same problem appears in 1.33 vanilla in some places.  For

+      example:

+

+            start : { (sub)? } ;

+

+      or:

+

+            start : (

+                       B

+                    |  ( sub )?

+                    |  C

+                    )+

+                    ;

+

+      generates incorrect code.

+

+      The general principle is:

+

+        (a) use [zz]guessing only when deciding between a call to zzFAIL

+              or zzGUESS_FAIL

+

+        (b) use zzrv in all other cases

+

+      This problem was discovered while testing changes to item #105.

+      I believe this is now fixed.  My apologies.

+

+#105. (Changed in 1.33MR10) guess block as single alt of (...)+

+

+      Prior to 1.33MR10 the following constructs:

+

+        rule_plus : (

+                       (sub)?

+                    )+

+                    ;

+

+        rule_star : (

+                      (sub)?

+                    )*

+                    ;

+

+      generated incorrect code for the guess block (which could result

+      in runtime errors) because of an incorrect optimization of a

+      block with only a single alternative.

+

+      The fix caused some changes to the fix described in Item #49

+      because there are now three code generation sequences for (...)+

+      blocks containing a guess block:

+

+        a. single alternative which is a guess block

+        b. multiple alternatives in which the last is a guess block

+        c. all other cases

+

+      Forms like "rule_star" can have unexpected behavior when there

+      is a syntax error: if the subrule "sub" is not matched *exactly*

+      then "rule_star" will consume no tokens.

+

+      Reported by Esa Pulkkinen (esap@cs.tut.fi).

+

+#104. (Changed in 1.33MR10) -o option for dlg

+

+      There was problem with the code added by item #74 to handle the

+      -o option of dlg.  This should fix it.

+

+#103. (Changed in 1.33MR10) ANDed semantic predicates

+

+      Rescinded.

+

+      The optimization was a mistake.

+      The resulting problem is described in Item #150.

+

+#102. (Changed in 1.33MR10) allow "class parser : .... {"

+

+      The syntax of the class statement ("class parser-name {")

+      has been extended to allow for the specification of base

+      classes.  An arbirtrary number of tokens may now appear

+      between the class name and the "{".  They are output

+      again when the class declaration is generated.  For

+      example:

+

+        class Parser : public MyBaseClassANTLRparser {

+

+      This was suggested by a user, but I don't have a record

+      of who it was.

+

+#101. (Changed in 1.33MR10) antlr -info command line switch

+

+        -info

+

+            p   - extra predicate information in generated file

+

+            t   - information about tnode use:

+                    at the end of each rule in generated file

+                    summary on stderr at end of program

+

+            m   - monitor progress

+                    prints name of each rule as it is started

+                    flushes output at start of each rule

+

+            f   - first/follow set information to stdout

+

+            0   - no operation (added in 1.33MR11)

+

+      The options may be combined and may appear in any order.

+      For example:

+

+        antlr -info ptm -CC -gt -mrhoist on mygrammar.g

+

+#100a. (Changed in 1.33MR10) Predicate tree simplification

+

+      When the same predicates can be referenced in more than one

+      alternative of a block large predicate trees can be formed.

+

+      The difference that these optimizations make is so dramatic

+      that I have decided to use it even when -mrhoist is not selected.

+

+      Consider the following grammar:

+

+        start : ( all )* ;

+

+        all   : a

+              | d

+              | e

+              | f

+              ;

+

+        a     : c A B

+              | c A C

+              ;

+

+        c     : <<AAA(LATEXT(2))>>?

+              ;

+

+        d     : <<BBB(LATEXT(2))>>? B C

+              ;

+

+        e     : <<CCC(LATEXT(2))>>? B C

+              ;

+

+        f     : e X Y

+              ;

+

+      In rule "a" there is a reference to rule "c" in both alternatives.

+      The length of the predicate AAA is k=2 and it can be followed in

+      alternative 1 only by (A B) while in alternative 2 it can be

+      followed only by (A C).  Thus they do not have identical context.

+

+      In rule "all" the alternatives which refer to rules "e" and "f" allow

+      elimination of the duplicate reference to predicate CCC.

+

+      The table below summarized the kind of simplification performed by

+      1.33MR10.  In the table, X and Y stand for single predicates

+      (not trees).

+

+        (OR X (OR Y (OR Z)))  => (OR X Y Z)

+        (AND X (AND Y (AND Z)))  => (AND X Y Z)

+

+        (OR X  (... (OR  X Y) ... ))     => (OR X (... Y ... ))

+        (AND X (... (AND X Y) ... ))     => (AND X (... Y ... ))

+        (OR X  (... (AND X Y) ... ))     => (OR X (...  ... ))

+        (AND X (... (OR  X Y) ... ))     => (AND X (...  ... ))

+

+        (AND X)               => X

+        (OR X)                => X

+

+      In a test with a complex grammar for a real application, a predicate

+      tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)".

+

+      In 1.33MR10 there is a greater effort to release memory used

+      by predicates once they are no longer in use.

+

+#100b. (Changed in 1.33MR10) Suppression of extra predicate tests

+

+      The following optimizations require that -mrhoist be selected.

+

+      It is relatively easy to optimize the code generated for predicate

+      gates when they are of the form:

+

+            (AND X Y Z ...)

+        or  (OR  X Y Z ...)

+

+      where X, Y, Z, and "..." represent individual predicates (leaves) not

+      predicate trees.

+

+      If the predicate is an AND the contexts of the X, Y, Z, etc. are

+      ANDed together to create a single Tree context for the group and

+      context tests for the individual predicates are suppressed:

+

+            --------------------------------------------------

+            Note: This was incorrect.  The contexts should be

+            ORed together.  This has been fixed.  A more 

+            complete description is available in item #152.

+            ---------------------------------------------------

+

+      Optimization 1:  (AND X Y Z ...)

+

+        Suppose the context for Xtest is LA(1)==LP and the context for

+        Ytest is LA(1)==LP && LA(2)==ID.

+

+            Without the optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    !(LA(1)==LP && LA(1)==LP && LA(2)==ID) ||

+                        ( (! LA(1)==LP || Xtest) &&

+                          (! (LA(1)==LP || LA(2)==ID) || Xtest)

+                        )) {...

+

+            With the -mrhoist optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {...

+

+      Optimization 2: (OR X Y Z ...) with identical contexts

+

+        Suppose the context for Xtest is LA(1)==ID and for Ytest

+        the context is also LA(1)==ID.

+

+            Without the optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    ! (LA(1)==ID || LA(1)==ID) ||

+                        (LA(1)==ID && Xtest) ||

+                        (LA(1)==ID && Ytest) {...

+

+            With the -mrhoist optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    (! LA(1)==ID) || (Xtest || Ytest) {...

+

+      Optimization 3: (OR X Y Z ...) with distinct contexts

+

+        Suppose the context for Xtest is LA(1)==ID and for Ytest

+        the context is LA(1)==LP.

+

+            Without the optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    ! (LA(1)==ID || LA(1)==LP) ||

+                        (LA(1)==ID && Xtest) ||

+                        (LA(1)==LP && Ytest) {...

+

+            With the -mrhoist optimization the code would resemble:

+

+                if (lookaheadContext &&

+                        (zzpf=0,

+                            (LA(1)==ID && (zzpf=1) && Xtest) ||

+                            (LA(1)==LP && (zzpf=1) && Ytest) ||

+                            !zzpf) {

+

+            These may appear to be of similar complexity at first,

+            but the non-optimized version contains two tests of each

+            context while the optimized version contains only one

+            such test, as well as eliminating some of the inverted

+            logic (" !(...) || ").

+

+      Optimization 4: Computation of predicate gate trees

+

+        When generating code for the gates of predicate expressions

+        antlr 1.33 vanilla uses a recursive procedure to generate

+        "&&" and "||" expressions for testing the lookahead. As each

+        layer of the predicate tree is exposed a new set of "&&" and

+        "||" expressions on the lookahead are generated.  In many

+        cases the lookahead being tested has already been tested.

+

+        With -mrhoist a lookahead tree is computed for the entire

+        lookahead expression.  This means that predicates with identical

+        context or context which is a subset of another predicate's

+        context disappear.

+

+        This is especially important for predicates formed by rules

+        like the following:

+

+            uppperCaseVowel : <<isUpperCase(LATEXT(1))>>?  vowel;

+            vowel:          : <<isVowel(LATEXT(1))>>? LETTERS;

+

+        These predicates are combined using AND since both must be

+        satisfied for rule upperCaseVowel.  They have identical

+        context which makes this optimization very effective.

+

+      The affect of Items #100a and #100b together can be dramatic.  In

+      a very large (but real world) grammar one particular predicate

+      expression was reduced from an (unreadable) 50 predicate leaves,

+      195 LA(1) terms, and 5500 characters to an (easily comprehensible)

+      3 predicate leaves (all different) and a *single* LA(1) term.

+

+#99.  (Changed in 1.33MR10) Code generation for expression trees

+

+      Expression trees are used for k>1 grammars and predicates with

+      lookahead depth >1.  This optimization must be enabled using

+      "-mrhoist on".  (Clarification added for 1.33MR11).

+

+      In the processing of expression trees, antlr can generate long chains

+      of token comparisons.  Prior to 1.33MR10 there were many redundant

+      parenthesis which caused problems for compilers which could handle

+      expressions of only limited complexity.  For example, to test an

+      expression tree (root R A B C D), antlr would generate something

+      resembling:

+

+        (LA(1)==R && (LA(2)==A || (LA(2)==B || (LA(2)==C || LA(2)==D)))))

+

+      If there were twenty tokens to test then there would be twenty

+      parenthesis at the end of the expression.

+

+      In 1.33MR10 the generated code for tree expressions resembles:

+

+        (LA(1)==R && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D))

+

+      For "complex" expressions the output is indented to reflect the LA

+      number being tested:

+

+        (LA(1)==R

+            && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D

+               || LA(2)==E || LA(2)==F)

+        || LA(1)==S

+            && (LA(2)==G || LA(2)==H))

+

+

+      Suggested by S. Bochnak (S.Bochnak@@microTool.com.pl),

+

+#98.  (Changed in 1.33MR10) Option "-info p"

+

+      When the user selects option "-info p" the program will generate

+      detailed information about predicates.  If the user selects

+      "-mrhoist on" additional detail will be provided explaining

+      the promotion and suppression of predicates.  The output is part

+      of the generated file and sandwiched between #if 0/#endif statements.

+

+      Consider the following k=1 grammar:

+

+        start : ( all ) * ;

+

+        all   : ( a

+                | b

+                )

+                ;

+

+        a     : c B

+              ;

+

+        c     : <<LATEXT(1)>>?

+              | B

+              ;

+

+        b     : <<LATEXT(1)>>? X

+              ;

+

+      Below is an excerpt of the output for rule "start" for the three

+      predicate options (off, on, and maintenance release style hoisting).

+

+      For those who do not wish to use the "-mrhoist on" option for code

+      generation the option can be used in a "diagnostic" mode to provide

+      valuable information:

+

+            a. where one should insert null actions to inhibit hoisting

+            b. a chain of rule references which shows where predicates are

+               being hoisted

+

+      ======================================================================

+      Example of "-info p" with "-mrhoist on"

+      ======================================================================

+        #if 0

+

+        Hoisting of predicate suppressed by alternative without predicate.

+        The alt without the predicate includes all cases where the

+           predicate is false.

+

+           WITH predicate: line 11  v36.g

+           WITHOUT predicate: line 12  v36.g

+

+        The context set for the predicate:

+

+             B

+

+        The lookahead set for alt WITHOUT the semantic predicate:

+

+             B

+

+        The predicate:

+

+          pred <<  LATEXT(1)>>?  depth=k=1  rule c  line 11  v36.g

+

+            set context:

+               B

+            tree context: null

+

+        Chain of referenced rules:

+

+            #0  in rule start (line 1 v36.g) to rule all

+            #1  in rule all (line 3 v36.g) to rule a

+            #2  in rule a (line 8 v36.g) to rule c

+            #3  in rule c (line 11 v36.g)

+

+        #endif

+        &&

+        #if 0

+

+        pred <<  LATEXT(1)>>?  depth=k=1  rule b  line 15  v36.g

+

+          set context:

+             X

+          tree context: null

+

+        #endif

+      ======================================================================

+      Example of "-info p"  with the default -prc setting ( "-prc off")

+      ======================================================================

+        #if 0

+

+        OR

+          pred <<  LATEXT(1)>>?  depth=k=1  rule c  line 11  v36.g

+

+            set context:

+              nil

+            tree context: null

+

+          pred <<  LATEXT(1)>>?  depth=k=1  rule b  line 15  v36.g

+

+            set context:

+              nil

+            tree context: null

+

+        #endif

+      ======================================================================

+      Example of "-info p" with "-prc on" and "-mrhoist off"

+      ======================================================================

+        #if 0

+

+        OR

+          pred <<  LATEXT(1)>>?  depth=k=1  rule c  line 11  v36.g

+

+            set context:

+               B

+            tree context: null

+

+          pred <<  LATEXT(1)>>?  depth=k=1  rule b  line 15  v36.g

+

+            set context:

+               X

+            tree context: null

+

+        #endif

+      ======================================================================

+

+#97.  (Fixed in 1.33MR10) "Predicate applied for more than one ... "

+

+      In 1.33 vanilla, the grammar listed below produced this message for

+      the first alternative (only) of rule "b":

+

+            warning: predicate applied for >1 lookahead 1-sequences

+                [you may only want one lookahead 1-sequence to apply.

+                Try using a context guard '(...)? =>'

+

+      In 1.33MR10 the message is issued for both alternatives.

+

+          top     : (a)*;

+          a       : b | c ;

+

+          b       : <<PPP(LATEXT(1))>>? ( AAA | BBB )

+                  | <<QQQ(LATEXT(1))>>? ( XXX | YYY )

+                  ;

+

+          c       : AAA | XXX;

+

+#96.  (Fixed in 1.33MR10) Guard predicates ignored when -prc off

+

+      Prior to 1.33MR10, guard predicate code was not generated unless

+      "-prc on" was selected.

+

+      This was incorrect, since "-prc off"  (the default) is supposed to

+      disable only AUTOMATIC computation of predicate context, not the

+      programmer specified context supplied by guard predicates.

+

+#95.  (Fixed in 1.33MR10) Predicate guard context length was k, not max(k,ck)

+

+      Prior to 1.33MR10, predicate guards were computed to k tokens rather

+      than max(k,ck).  Consider the following grammar:

+

+        a     : ( A B C)? => <<AAA(LATEXT(1))>>? (A|X) (B|Y) (C|Z) ;

+

+      The code generated by 1.33 vanilla with "-k 1 -ck 3 -prc on"

+      for the predicate in "a" resembles:

+

+        if ( (! LA(1)==A) || AAA(LATEXT(1))) {...

+

+      With 1.33MR10 and the same options the code resembles:

+

+        if ( (! (LA(1)==A && LA(2)==B && LA(3)==C) || AAA(LATEXT(1))) {...

+

+#94.  (Fixed in 1.33MR10) Predicates followed by rule references

+

+      Prior to 1.33MR10, a semantic predicate which referenced a token

+      which was off the end of the rule caused an incomplete context

+      to be computed (with "-prc on") for the predicate under some circum-

+      stances.  In some cases this manifested itself as illegal C code

+      (e.g. "LA(2)==[Ep](1)" in the k=2 examples below:

+

+          all     : ( a ) *;

+

+          a       : <<AAA(LATEXT(2))>>? ID X

+                  | <<BBB(LATEXT(2))>>? Y

+                  | Z

+                  ;

+

+      This might also occur when the semantic predicate was followed

+      by a rule reference which was shorter than the length of the

+      semantic predicate:

+

+        all       : ( a ) *;

+

+        a         : <<AAA(LATEXT(2))>>? ID X

+                  | <<BBB(LATEXT(2))>>? y

+                  | Z

+                  ;

+

+        y         : Y ;

+

+      Depending on circumstance, the resulting context might be too

+      generous because it was too short, or too restrictive because

+      of missing alternatives.

+

+#93.  (Changed in 1.33MR10) Definition of Purify macro

+

+      Ofer Ben-Ami (gremlin@cs.huji.ac.il) has supplied a definition

+      for the Purify macro:

+

+        #define PURIFY(r, s) memset((char *) &(r), '\0', (s));

+

+      Note: This may not be the right thing to do for C++ objects that

+      have constructors.  Reported by Bonny Rais (bonny@werple.net.au).

+

+      For those cases one should #define PURIFY to an empty macro in the

+      #header or #first actions.

+

+#92.  (Fixed in 1.33MR10) Guarded predicates and hoisting

+

+      When a guarded predicate participates in hoisting it is linked into

+      a predicate expression tree.  Prior to 1.33MR10 this link was never

+      cleared and the next time the guard was used to construct a new

+      tree the link could contain a spurious reference to another element

+      which had previosly been joined to it in the semantic predicate tree.

+

+      For example:

+

+        start  : ( all ) *;

+        all    : ( a | b ) ;

+

+        start2 : ( all2 ) *;

+        all2    : ( a ) ;

+

+        a     : (A)? => <<AAA(LATEXT(1))>>?  A ;

+        b     : (B)? => <<BBB(LATEXT(1))>>?  B ;

+

+      Prior to 1.33MR10 the code for "start2" would include a spurious

+      reference to the BBB predicate which was left from constructing

+      the predicate tree for rule "start" (i.e. or(AAA,BBB) ).

+

+      In 1.33MR10 this problem is avoided by cloning the original guard

+      each time it is linked into a predicate tree.

+

+#91.  (Changed in 1.33MR10) Extensive changes to semantic pred hoisting

+

+            ============================================

+            This has been rendered obsolete by Item #117

+            ============================================

+

+#90.  (Fixed in 1.33MR10) Semantic pred with LT(i) and i>max(k,ck)

+

+      There is a bug in antlr 1.33 vanilla and all maintenance releases

+      prior to 1.33MR10 which allows semantic predicates to reference

+      an LT(i) or LATEXT(i) where i is larger than max(k,ck).  When

+      this occurs antlr will attempt to mark the ith element of an array

+      in which there are only max(k,ck) elements.  The result cannot

+      be predicted.

+

+      Using LT(i) or LATEXT(i) for i>max(k,ck) is reported as an error

+      in 1.33MR10.

+

+#89.  Rescinded

+

+#88.  (Fixed in 1.33MR10) Tokens used in semantic predicates in guess mode

+

+        Consider the behavior of a semantic predicate during guess mode:

+

+            rule : a:A (

+                         <<test($a)>>? b:B

+                         | c:C

+                       );

+

+        Prior to MR10 the assignment of the token or attribute to

+        $a did not occur during guess mode, which would cause the

+        semantic predicate to misbehave because $a would be null.

+

+        In 1.33MR10 a semantic predicate with a reference to an

+        element label (such as $a) forces the assignment to take

+        place even in guess mode.

+

+        In order to work, this fix REQUIRES use of the $label format

+        for token pointers and attributes referenced in semantic

+        predicates.

+

+        The fix does not apply to semantic predicates using the

+        numeric form to refer to attributes (e.g. <<test($1)>>?).

+        The user will receive a warning for this case.

+

+        Reported by Rob Trout (trout@mcs.cs.kent.edu).

+

+#87.  (Fixed in 1.33MR10) Malformed guard predicates

+

+      Context guard predicates may contain only references to

+      tokens.  They may not contain references to (...)+ and

+      (...)* blocks.  This is now checked.  This replaces the

+      fatal error message in item #78 with an appropriate

+      (non-fatal) error messge.

+

+      In theory, context guards should be allowed to reference

+      rules.  However, I have not had time to fix this.

+      Evaluation of the guard takes place before all rules have

+      been read, making it difficult to resolve a forward reference

+      to rule "zzz" - it hasn't been read yet !  To postpone evaluation

+      of the guard until all rules have been read is too much

+      for the moment.

+

+#86.  (Fixed in 1.33MR10) Unequal set size in set_sub

+

+      Routine set_sub() in pccts/support/set/set.h  did not work

+      correctly when the sets were of unequal sizes.  Rewrote

+      set_equ to make it simpler and remove unnecessary and

+      expensive calls to set_deg().  This routine was not used

+      in 1.33 vanila.

+

+#85.  (Changed in 1.33MR10) Allow redefinition of MaxNumFiles

+

+      Raised the maximum number of input files to 99 from 20.

+      Put a #ifndef/#endif around the "#define MaxNumFiles 99".

+

+#84.  (Fixed in 1.33MR10) Initialize zzBadTok in macro zzRULE

+

+      Initialize zzBadTok to NULL in zzRULE macro of AParser.h.

+      in order to get rid of warning messages.

+

+#83.  (Fixed in 1.33MR10) False warnings with -w2 for #tokclass

+

+      When -w2 is selected antlr gives inappropriate warnings about

+      #tokclass names not having any associated regular expressions.

+      Since a #tokclass is not a "real" token it will never have an

+      associated regular expression and there should be no warning.

+

+      Reported by Derek Pappas (derek.pappas@eng.sun.com)

+

+#82.  (Fixed in 1.33MR10) Computation of follow sets with multiple cycles

+

+      Reinier van den Born (reinier@vnet.ibm.com) reported a problem

+      in the computation of follow sets by antlr.  The problem (bug)

+      exists in 1.33 vanilla and all maintenance releases prior to 1.33MR10.

+

+      The problem involves the computation of follow sets when there are

+      cycles - rules which have mutual references.  I believe the problem

+      is restricted to cases where there is  more than one cycle AND

+      elements of those cycles have rules in common.  Even when this

+      occurs it may not affect the code generated - but it might.  It

+      might also lead to undetected ambiguities.

+

+      There were no changes in antlr or dlg output from the revised version.

+

+      The following fragment demonstates the problem by giving different

+      follow sets (option -pa) for var_access when built with k=1 and ck=2 on

+      1.33 vanilla and 1.33MR10:

+

+        echo_statement : ECHO ( echo_expr )*

+                       ;

+

+        echo_expr      : ( command )?

+                       | expression

+                       ;

+

+        command        : IDENTIFIER

+                             { concat }

+                       ;

+

+        expression     : operand ( OPERATOR operand )*

+                       ;

+

+        operand        : value

+                       | START command END

+                       ;

+

+        value          : concat

+                       | TYPE operand

+                       ;

+

+        concat         : var_access { CONCAT value }

+                       ;

+

+        var_access     : IDENTIFIER { INDEX }

+

+                       ;

+#81.  (Changed in 1.33MR10) C mode use of attributes and ASTs

+

+       Reported by Isaac Clark (irclark@mindspring.com).

+

+       C mode code ignores attributes returned by rules which are

+       referenced using element labels when ASTs are enabled (-gt option).

+

+         1. start : r:rule t:Token <<$start=$r;>>

+

+                The $r refrence will not work when combined with

+                the -gt option.

+

+         2. start : t:Token         <<$start=$t;>>

+

+                The $t reference works in all cases.

+

+         3. start : rule            <<$0=$1;>>

+

+                Numeric labels work in all cases.

+

+       With MR10 the user will receive an error message for case 1 when

+       the -gt option is used.

+

+#80.  (Fixed in 1.33MR10) (...)? as last alternative of block

+

+        A construct like the following:

+

+            rule : a

+                 | (b)?

+                 ;

+

+        does not make sense because there is no alternative when

+        the guess block fails.  This is now reported as a warning

+        to the user.

+

+        Previously, there was a code generation error for this case:

+        the guess block was not "closed"  when the guess failed.

+        This could cause an infinite loop or other problems.  This

+        is now fixed.

+

+        Example problem:

+

+            #header<<

+            #include <stdio.h>

+            #include "charptr.h"

+            >>

+

+            <<

+            #include "charptr.c"

+            main ()

+            {

+             ANTLR(start(),stdin);

+            }

+            >>

+

+            #token "[\ \t]+"        << zzskip(); >>

+            #token "[\n]"           << zzline++; zzskip(); >>

+

+            #token Word     "[a-z]+"

+            #token Number   "[0-9]+"

+

+

+            start : (test1)?

+                  | (test2)?

+                  ;

+            test1 : (Word Word Word Word)?

+                  | (Word Word Word Number)?

+                  ;

+            test2 : (Word Word Number Word)?

+                  | (Word Word Number Number)?

+            ;

+

+        Test data which caused infinite loop:

+

+            a 1 a a

+

+#79.  (Changed in 1.33MR10) Use of -fh with multiple parsers

+

+        Previously, antlr always used the pre-processor symbol

+        STDPCCTS_H as a gate for the file stdpccts.h.  This

+        caused problems when there were multiple parsers defined

+        because they used the same gate symbol.

+

+        In 1.33MR10, the -fh filename is used to generate the

+        gate file for stdpccts.h.  For instance:

+

+            antlr -fh std_parser1.h

+

+        generates the pre-processor symbol "STDPCCTS_std_parser1_H".

+

+        Reported by Ramanathan Santhanam (ps@kumaran.com).

+

+#78.  (Changed in 1.33MR9) Guard predicates that refer to rules

+

+                ------------------------

+                Please refer to Item #87

+                ------------------------

+

+        Guard predicates are processed during an early phase

+        of antlr (during parsing) before all data structures

+        are completed.

+

+        There is an apparent bug in earlier versions of 1.33

+        which caused guard predicates which contained references

+        to rules (rather than tokens) to reference a structure

+        which hadn't yet been initialized.

+

+        In some cases (perhaps all cases) references to rules

+        in guard predicates resulted in the use of "garbage".

+

+#79.  (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com)

+

+        Previously, the maximum length file name was set

+        arbitrarily to 300 characters in antlr, dlg, and sorcerer.

+

+        The config.h file now attempts to define the maximum length

+        filename using _MAX_PATH from stdlib.h before falling back

+        to using the value 300.

+

+#78.  (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com)

+

+        Put #ifndef/#endif around definition of ZZLEXBUFSIZE in

+        antlr.

+

+#77.  (Changed in 1.33MR9) Arithmetic overflow for very large grammars

+

+        In routine HandleAmbiguities() antlr attempts to compute the

+        number of possible elements in a set that is order of

+        number-of-tokens raised to the number-of-lookahead-tokens power.

+        For large grammars or large lookahead (e.g. -ck 7) this can

+        cause arithmetic overflow.

+

+        With 1.33MR9, arithmetic overflow in this computation is reported

+        the first time it happens.  The program continues to run and

+        the program branches based on the assumption that the computed

+        value is larger than any number computed by counting actual cases

+        because 2**31 is larger than the number of bits in most computers.

+

+        Before 1.33MR9 overflow was not reported.  The behavior following

+        overflow is not predictable by anyone but the original author.

+

+                            NOTE

+

+            In 1.33MR10 the warning message is suppressed.

+            The code which detects the overflow allows the

+            computation to continue without an error.  The

+            error message itself made made users worry.

+

+#76.  (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com)

+

+        Jeff Vincent has convinced me to make ANTLRCommonToken and

+        ANTLRCommonNoRefCountToken use variable length strings

+        allocated from the heap rather than fixed length strings.

+        By suitable definition of setText(), the copy constructor,

+        and operator =() it is possible to maintain "copy" semantics.

+        By "copy" semantics I mean that when a token is copied from

+        an existing token it receives its own, distinct, copy of the

+        text allocated from the heap rather than simply a pointer

+        to the original token's text.

+

+        ============================================================

+                        W * A * R * N * I * N * G

+        ============================================================

+

+        It is possible that this may cause problems for some users.

+        For those users I have included the old version of AToken.h as

+        pccts/h/AToken_traditional.h.

+

+#75.  (Changed in 1.33MR9) Bruce Guenter (bruceg@qcc.sk.ca)

+

+        Make DLGStringInput const correct.  Since this is infrequently

+        subclassed, it should affect few users, I hope.

+

+#74.  (Changed in 1.33MR9) -o (output directory) option

+

+        Antlr does not properly handle the -o output directory option

+        when the filename of the grammar contains a directory part.  For

+        example:

+

+            antlr -o outdir pccts_src/myfile.g

+

+        causes antlr create a file called "outdir/pccts_src/myfile.cpp.

+        It SHOULD create outdir/myfile.cpp

+

+        The suggested code fix has been installed in antlr, dlg, and

+        Sorcerer.

+

+#73.  (Changed in 1.33MR9) Hoisting of semantic predicates and -mrhoist

+

+            ============================================

+            This has been rendered obsolete by Item #117

+            ============================================

+

+#72.  (Changed in 1.33MR9) virtual saveState()/restoreState()/guess_XXX

+

+        The following methods in ANTLRParser were made virtual at

+        the request of S. Bochnak (S.Bochnak@microTool.com.pl):

+

+            saveState() and restoreState()

+            guess(), guess_fail(), and guess_done()

+

+#71.  (Changed in 1.33MR9) Access to omitted command line argument

+

+        If a switch requiring arguments is the last thing on the

+        command line, and the argument is omitted, antlr would core.

+

+            antlr test.g -prc

+

+        instead of

+

+            antlr test.g -prc off

+

+#70.  (Changed in 1.33MR9) Addition of MSVC .dsp and .mak build files

+

+        The following MSVC .dsp and .mak files for pccts and sorcerer

+        were contributed by Stanislaw Bochnak (S.Bochnak@microTool.com.pl)

+        and Jeff Vincent (JVincent@novell.com)

+

+        PCCTS Distribution Kit

+        ----------------------

+        pccts/PCCTSMSVC50.dsw

+

+        pccts/antlr/AntlrMSVC50.dsp

+        pccts/antlr/AntlrMSVC50.mak

+

+        pccts/dlg/DlgMSVC50.dsp

+        pccts/dlg/DlgMSVC50.mak

+

+        pccts/support/msvc.dsp

+

+        Sorcerer Distribution Kit

+        -------------------------

+        pccts/sorcerer/SorcererMSVC50.dsp

+        pccts/sorcerer/SorcererMSVC50.mak

+

+        pccts/sorcerer/lib/msvc.dsp

+

+#69.  (Changed in 1.33MR9) Change "unsigned int" to plain "int"

+

+       Declaration of max_token_num in misc.c as "unsigned int"

+       caused comparison between signed and unsigned ints giving

+       warning message without any special benefit.

+

+#68.  (Changed in 1.33MR9) Add void return for dlg internal_error()

+

+       Get rid of "no return value" message in internal_error()

+       in file dlg/support.c and dlg/dlg.h.

+

+#67.  (Changed in Sor) sor.g: lisp() has no return value

+

+       Added a "void" for the return type.

+

+#66.  (Added to Sor) sor.g: ZZLEXBUFSIZE enclosed in #ifndef/#endif

+

+       A user needed to be able to change the ZZLEXBUFSIZE for

+       sor. Put the definition of ZZLEXBUFSIZE inside #ifndef/#endif

+

+#65.  (Changed in 1.33MR9) PCCTSAST::deepCopy() and ast_dup() bug

+

+       Jeff Vincent (JVincent@novell.com) found that deepCopy()

+       made new copies of only the direct descendents.  No new

+       copies were made of sibling nodes,  Sibling pointers are

+       set to zero by shallowCopy().

+

+           PCCTS_AST::deepCopy() has been changed to make a

+           deep copy in the traditional sense.

+

+           The deepCopy() routine depends on the behavior of

+           shallowCopy().  In all sor examples I've found,

+           shallowCopy() zeroes the right and down pointers.

+

+       Original Tree       Original deepCopy()     Revised deepCopy

+       -------------       -------------------     ----------------

+            a->b->c         A                       A

+            |               |                       |

+            d->e->f         D                       D->E->F

+            |               |                       |

+            g->h->i         G                       G->H->I

+               |                                       |

+               j->k                                    J->K

+

+        While comparing deepCopy() for C++ mode with ast_dup for

+        C mode I found a problem with ast_dup().

+

+           Routine ast_dup() has been changed to make a deep copy

+           in the traditional sense.

+

+       Original Tree       Original ast_dup()      Revised ast_dup()

+       -------------       -------------------     ----------------

+            a->b->c         A->B->C                 A

+            |               |                       |

+            d->e->f         D->E->F                 D->E->F

+            |               |                       |

+            g->h->i         G->H->I                 G->H->I

+               |               |                       |

+               j->k            J->K                    J->K

+

+

+        I believe this affects transform mode sorcerer programs only.

+

+#64.  (Changed in 1.33MR9) anltr/hash.h prototype for killHashTable()

+

+#63.  (Changed in 1.33MR8) h/charptr.h does not zero pointer after free

+

+        The charptr.h routine now zeroes the pointer after free().

+

+        Reported by Jens Tingleff (jensting@imaginet.fr)

+

+#62.  (Changed in 1.33MR8) ANTLRParser::resynch had static variable

+

+        The static variable "consumed" in ANTLRParser::resynch was

+        changed into an instance variable of the class with the

+        name "resynchConsumed".

+

+        Reported by S.Bochnak@microTool.com.pl

+

+#61.  (Changed in 1.33MR8) Using rule>[i,j] when rule has no return values

+

+        Previously, the following code would cause antlr to core when

+        it tried to generate code for rule1 because rule2 had no return

+        values ("upward inheritance"):

+

+            rule1 : <<int i; int j>>

+                    rule2 > [i,j]

+                  ;

+

+            rule2 : Anything ;

+

+        Reported by S.Bochnak@microTool.com.pl

+

+        Verified correct operation of antlr MR8 when missing or extra

+        inheritance arguments for all combinations.  When there are

+        missing or extra arguments code will still be generated even

+        though this might cause the invocation of a subroutine with

+        the wrong number of arguments.

+

+#60.  (Changed in 1.33MR7) Major changes to exception handling

+

+        There were significant problems in the handling of exceptions

+        in 1.33 vanilla.  The general problem is that it can only

+        process one level of exception handler.  For example, a named

+        exception handler, an exception handler for an alternative, or

+        an exception for a subrule  always went to the rule's exception

+        handler if there was no "catch" which matched the exception.

+

+        In 1.33MR7 the exception handlers properly "nest".  If an

+        exception handler does not have a matching "catch" then the

+        nextmost outer exception handler is checked for an appropriate

+        "catch" clause, and so on until an exception handler with an

+        appropriate "catch" is found.

+

+        There are still undesirable features in the way exception

+        handlers are implemented, but I do not have time to fix them

+        at the moment:

+

+            The exception handlers for alternatives are outside the

+            block containing the alternative.  This makes it impossible

+            to access variables declared in a block or to resume the

+            parse by "falling through".  The parse can still be easily

+            resumed in other ways, but not in the most natural fashion.

+

+            This results in an inconsistentcy between named exception

+            handlers and exception handlers for alternatives.  When

+            an exception handler for an alternative "falls through"

+            it goes to the nextmost outer handler - not the "normal

+            action".

+

+        A major difference between 1.33MR7 and 1.33 vanilla is

+        the default action after an exception is caught:

+

+            1.33 Vanilla

+            ------------

+            In 1.33 vanilla the signal value is set to zero ("NoSignal")

+            and the code drops through to the code following the exception.

+            For named exception handlers this is the "normal action".

+            For alternative exception handlers this is the rule's handler.

+

+            1.33MR7

+            -------

+            In 1.33MR7 the signal value is NOT automatically set to zero.

+

+            There are two cases:

+

+                For named exception handlers: if the signal value has been

+                set to zero the code drops through to the "normal action".

+

+                For all other cases the code branches to the nextmost outer

+                exception handler until it reaches the handler for the rule.

+

+        The following macros have been defined for convenience:

+

+            C/C++ Mode Name

+            --------------------

+            (zz)suppressSignal

+                  set signal & return signal arg to 0 ("NoSignal")

+            (zz)setSignal(intValue)

+                  set signal & return signal arg to some value

+            (zz)exportSignal

+                  copy the signal value to the return signal arg

+

+        I'm not sure why PCCTS make a distinction between the local

+        signal value and the return signal argument, but I'm loathe

+        to change the code. The burden of copying the local signal

+        value to the return signal argument can be given to the

+        default signal handler, I suppose.

+

+#59.  (Changed in 1.33MR7) Prototypes for some functions

+

+        Added prototypes for the following functions to antlr.h

+

+            zzconsumeUntil()

+            zzconsumeUntilToken()

+

+#58.  (Changed in 1.33MR7) Added defintion of zzbufsize to dlgauto.h

+

+#57.  (Changed in 1.33MR7) Format of #line directive

+

+        Previously, the -gl directive for line 1234 would

+        resemble:  "# 1234 filename.g".  This caused problems

+        for some compilers/pre-processors.  In MR7 it generates

+        "#line 1234 filename.g".

+

+#56.  (Added in 1.33MR7) Jan Mikkelsen <janm@zeta.org.au>

+

+        Move PURIFY macro invocaton to after rule's init action.

+

+#55.  (Fixed in 1.33MR7) Unitialized variables in ANTLRParser

+

+        Member variables inf_labase and inf_last were not initialized.

+        (See item #50.)

+

+#54.  (Fixed in 1.33MR6) Brad Schick (schick@interacess.com)

+

+        Previously, the following constructs generated the same

+        code:

+

+        rule1 : (A B C)?

+              | something-else

+              ;

+

+        rule2 : (A B C)? ()

+              | something-else

+              ;

+

+        In all versions of pccts rule1 guesses (A B C) and then

+        consume all three tokens if the guess succeeds.  In MR6

+        rule2 guesses (A B C)  but consumes NONE of the tokens

+        when the guess succeeds because "()" matches epsilon.

+

+#53.  (Explanation for 1.33MR6) What happens after an exception is caught ?

+

+        The Book is silent about what happens after an exception

+        is caught.

+

+        The following code fragment prints "Error Action" followed

+        by "Normal Action".

+

+        test : Word ex:Number <<printf("Normal Action\n");>>

+                exception[ex]

+                   catch NoViableAlt:

+                        <<printf("Error Action\n");>>

+        ;

+

+        The reason for "Normal Action" is that the normal flow of the

+        program after a user-written exception handler is to "drop through".

+        In the case of an exception handler for a rule this results in

+        the exection of a "return" statement.  In the case of an

+        exception handler attached to an alternative, rule, or token

+        this is the code that would have executed had there been no

+        exception.

+

+        The user can achieve the desired result by using a "return"

+        statement.

+

+        test : Word ex:Number <<printf("Normal Action\n");>>

+                exception[ex]

+                   catch NoViableAlt:

+                        <<printf("Error Action\n"); return;>>

+        ;

+

+        The most powerful mechanism for recovery from parse errors

+        in pccts is syntactic predicates because they provide

+        backtracking.  Exceptions allow "return", "break",

+        "consumeUntil(...)", "goto _handler", "goto _fail", and

+        changing the _signal value.

+

+#52.  (Fixed in 1.33MR6) Exceptions without syntactic predicates

+

+        The following generates bad code in 1.33 if no syntactic

+        predicates are present in the grammar.

+

+        test : Word ex:Number <<printf("Normal Action\n");>>

+                exception[ex]

+                   catch NoViableAlt:

+                        <<printf("Error Action\n");>>

+

+        There is a reference to a guess variable.  In C mode

+        this causes a compiler error.  In C++ mode it generates

+        an extraneous check on member "guessing".

+

+        In MR6 correct code is generated for both C and C++ mode.

+

+#51.  (Added to 1.33MR6) Exception operator "@" used without exceptions

+

+        In MR6 added a warning when the exception operator "@" is

+        used and no exception group is defined.  This is probably

+        a case where "\@" or "@" is meant.

+

+#50.  (Fixed in 1.33MR6) Gunnar Rxnning (gunnar@candleweb.no)

+                                    http://www.candleweb.no/~gunnar/

+

+        Routines zzsave_antlr_state and zzrestore_antlr_state don't

+        save and restore all the data needed when switching states.

+

+        Suggested patch applied to antlr.h and err.h for MR6.

+

+#49.  (Fixed in 1.33MR6) Sinan Karasu (sinan@boeing.com)

+

+        Generated code failed to turn off guess mode when leaving a

+        (...)+ block which contained a guess block.  The result was

+        an infinite loop.  For example:

+

+                rule : (

+                         (x)?

+                         | y

+                       )+

+

+        Suggested code fix implemented in MR6.  Replaced

+

+            ... else if (zzcnt>1) break;

+

+        with:

+

+          C++ mode:

+              ... else if (zzcnt>1) {if (!zzrv) zzGUESS_DONE; break;};

+          C mode:

+              ... else if (zzcnt>1) {if (zzguessing) zzGUESS_DONE; break;};

+

+#48.  (Fixed in 1.33MR6) Invalid exception element causes core

+

+        A label attached to an invalid construct can cause

+        pccts to crash while processing the exception associated

+        with the label.  For example:

+

+        rule : t:(B C)

+                exception[t] catch MismatchedToken: <<printf(...);>>

+

+        Version MR6 generates the message:

+

+           reference in exception handler to undefined label 't'

+

+#47.  (Fixed in 1.33MR6) Manuel Ornato

+

+        Under some circumstances involving a k >1 or ck >1

+        grammar and a loop block (i.e.  (...)* ) pccts will

+        fail to detect a syntax error and loop indefinitely.

+        The problem did not exist in 1.20, but has existed

+        from 1.23 to the present.

+

+        Fixed in MR6.

+

+        ---------------------------------------------------

+        Complete test program

+        ---------------------------------------------------

+        #header<<

+        #include <stdio.h>

+        #include "charptr.h"

+        >>

+

+        <<

+        #include "charptr.c"

+        main ()

+        {

+         ANTLR(global(),stdin);

+        }

+        >>

+

+        #token "[\ \t]+"        << zzskip(); >>

+        #token "[\n]"           << zzline++; zzskip(); >>

+

+        #token B        "b"

+        #token C        "c"

+        #token D        "d"

+        #token E        "e"

+        #token LP       "\("

+        #token RP       "\)"

+

+        #token ANTLREOF "@"

+

+        global : (

+                   (E liste)

+                 | liste

+                 | listed

+                 )  ANTLREOF

+        ;

+

+        listeb : LP ( B ( B | C )* ) RP ;

+        listec : LP ( C ( B | C )* ) RP ;

+        listed : LP ( D ( B | C )* ) RP ;

+        liste : ( listeb | listec )* ;

+

+        ---------------------------------------------------

+        Sample data causing infinite loop

+        ---------------------------------------------------

+        e (d c)

+        ---------------------------------------------------

+

+#46.  (Fixed in 1.33MR6) Robert Richter

+                (Robert.Richter@infotech.tu-chemnitz.de)

+

+        This item from the list of known problems was

+        fixed by item #18 (below).

+

+#45.  (Fixed in 1.33MR6) Brad Schick (schick@interaccess.com)

+

+        The dependency scanner in VC++ mistakenly sees a

+        reference to an MPW #include file even though properly

+        #ifdef/#endif in config.h.  The suggested workaround

+        has been implemented:

+

+                #ifdef MPW

+                .....

+                #define MPW_CursorCtl_Header <CursorCtl.h>

+                #include MPW_CursorCtl_Header

+                .....

+                #endif

+

+#44.  (Fixed in 1.33MR6) cast malloc() to (char *) in charptr.c

+

+        Added (char *) cast for systems where malloc returns "void *".

+

+#43.  (Added to 1.33MR6) Bruce Guenter (bruceg@qcc.sk.ca)

+

+        Add setLeft() and setUp methods to ASTDoublyLinkedBase

+        for symmetry with setRight() and setDown() methods.

+

+#42.  (Fixed in 1.33MR6) Jeff Katcher (jkatcher@nortel.ca)

+

+        C++ style comment in antlr.c corrected.

+

+#41.  (Added in 1.33MR6) antlr -stdout

+

+        Using "antlr -stdout ..." forces the text that would

+        normally go to the grammar.c or grammar.cpp file to

+        stdout.

+

+#40.  (Added in 1.33MR6) antlr -tab to change tab stops

+

+        Using "antlr -tab number ..." changes the tab stops

+        for the grammar.c or grammar.cpp file.  The number

+        must be between 0 and 8.  Using 0 gives tab characters,

+        values between 1 and 8 give the appropriate number of

+        space characters.

+

+#39.  (Fixed in 1.33MR5) Jan Mikkelsen <janm@zeta.org.au>

+

+        Commas in function prototype still not correct under

+        some circumstances.  Suggested code fix installed.

+

+#38.  (Fixed in 1.33MR5) ANTLRTokenBuffer constructor

+

+        Have ANTLRTokenBuffer ctor initialize member "parser" to null.

+

+#37.  (Fixed in 1.33MR4) Bruce Guenter (bruceg@qcc.sk.ca)

+

+        In ANTLRParser::FAIL(int k,...) released memory pointed to by

+        f[i] (as well as f itself.  Should only free f itself.

+

+#36.  (Fixed in 1.33MR3) Cortland D. Starrett (cort@shay.ecn.purdue.edu)

+

+        Neglected to properly declare isDLGmaxToken() when fixing problem

+        reported by Andreas Magnusson.

+

+        Undo "_retv=NULL;" change which caused problems for return values

+        from rules whose return values weren't pointers.

+

+        Failed to create bin directory if it didn't exist.

+

+#35.  (Fixed in 1.33MR2) Andreas Magnusson

+(Andreas.Magnusson@mailbox.swipnet.se)

+

+        Repair bug introduced by 1.33MR1 for #tokdefs.  The original fix

+        placed "DLGmaxToken=9999" and "DLGminToken=0" in the TokenType enum

+        in order to fix a problem with an aggresive compiler assigning an 8

+        bit enum which might be too narrow.  This caused #tokdefs to assume

+        that there were 9999 real tokens.  The repair to the fix causes antlr to

+        ignore TokenTypes "DLGmaxToken" and "DLGminToken" in a #tokdefs file.

+

+#34.  (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue)

+

+        Previously there was no public function for changing the line

+        number maintained by the lexer.

+

+#33.  (Fixed in 1.33MR1) Franklin Chen   (chen@adi.com)

+

+        Accidental use of EXIT_FAILURE rather than PCCTS_EXIT_FAILURE

+        in pccts/h/AParser.cpp.

+

+#32.  (Fixed in 1.33MR1) Franklin Chen   (chen@adi.com)

+

+        In PCCTSAST.cpp lines 405 and 466:  Change

+

+                free (t)

+           to

+                free ( (char *)t );

+

+        to match prototype.

+

+#31.   (Added to 1.33MR1) Pointer to parser in ANTLRTokenBuffer

+                        Pointer to parser in DLGLexerBase

+

+        The ANTLRTokenBuffer class now contains a pointer to the

+        parser which is using it.  This is established by the

+        ANTLRParser constructor calling ANTLRTokenBuffer::

+        setParser(ANTLRParser *p).

+

+        When ANTLRTokenBuffer::setParser(ANTLRParser *p) is

+        called it saves the pointer to the parser and then

+        calls ANTLRTokenStream::setParser(ANTLRParser *p)

+        so that the lexer can also save a pointer to the

+        parser.

+

+        There is also a function getParser() in each class

+        with the obvious purpose.

+

+        It is possible that these functions will return NULL

+        under some circumstances (e.g. a non-DLG lexer is used).

+

+#30.   (Added to 1.33MR1) function tokenName(int token) standard

+

+        The generated parser class now includes the

+        function:

+

+          static const ANTLRChar * tokenName(int token)

+

+        which returns a pointer to the "name" corresponding

+        to the token.

+

+        The base class (ANTLRParser) always includes the

+        member function:

+

+          const ANTLRChar * parserTokenName(int token)

+

+        which can be accessed by objects which have a pointer

+        to an ANTLRParser, but do not know the name of the

+        parser class (e.g. ANTLRTokenBuffer and DLGLexerBase).

+

+#29.   (Added to 1.33MR1) Debugging DLG lexers

+

+        If the pre-processor symbol DEBUG_LEXER is defined

+        then DLexerBase will include code for printing out

+        key information about tokens which are recognized.

+

+        The debug feature of the lexer is controlled by:

+

+          int previousDebugValue=lexer.debugLexer(newValue);

+

+                        a value of 0 disables output

+                        a value of 1 enables output

+

+        Even if the lexer debug code is compiled into DLexerBase

+        it must be enabled before any output is generated.  For

+        example:

+

+           DLGFileInput         in(stdin);

+           MyDLG                lexer(&in,2000);

+

+           lexer.setToken(&aToken);

+

+           #if DEBUG_LEXER

+             lexer.debugLexer(1);       // enable debug information

+           #endif

+

+#28.   (Added to 1.33MR1) More control over DLG header

+

+        Version 1.33MR1 adds the following directives to PCCTS

+        for C++ mode:

+

+          #lexprefix  <<source code>>

+

+                Adds source code to the DLGLexer.h file

+                after the #include "DLexerBase.h" but

+                before the start of the class definition.

+

+          #lexmember  <<source code>>

+

+                Adds source code to the DLGLexer.h file

+                as part of the DLGLexer class body.  It

+                appears immediately after the start of

+                the class and a "public: statement.

+

+#27.   (Fixed in 1.33MR1) Comments in DLG actions

+

+        Previously, DLG would not recognize comments as a special case.

+        Thus, ">>" in the comments would cause errors.  This is fixed.

+

+#26.   (Fixed in 1.33MR1) Removed static variables from error routines

+

+        Previously, the existence of statically allocated variables

+        in some of the parser's member functions posed a danger when

+        there was more than one parser active.

+

+        Replaced with dynamically allocated/freed variables in 1.33MR1.

+

+#25.  (Fixed in 1.33MR1)  Use of string literals in semantic predicates

+

+        Previously, it was not possible to place a string literal in

+        a semantic predicate because it was not properly "stringized"

+        for the report of a failed predicate.

+

+#24.  (Fixed in 1.33MR1)  Continuation lines for semantic predicates

+

+        Previously, it was not possible to continue semantic

+        predicates across a line because it was not properly

+        "stringized" for the report of a failed predicate.

+

+                rule : <<ifXYZ()>>?[ a very

+                                        long statement ]

+

+#23.  (Fixed in 1.33MR1)  {...} envelope for failed semantic predicates

+

+        Previously, there was a code generation error for failed

+        semantic predicates:

+

+          rule : <<xyz()>>?[ stmt1; stmt2; ]

+

+        which generated code which resembled:

+

+          if (! xyz()) stmt1; stmt2;

+

+        It now puts the statements in a {...} envelope:

+

+          if (! xyz()) { stmt1; stmt2; };

+

+#22.  (Fixed in 1.33MR1)  Continuation of #token across lines using "\"

+

+        Previously, it was not possible to continue a #token regular

+        expression across a line.  The trailing "\" and newline caused

+        a newline to be inserted into the regular expression by DLG.

+

+        Fixed in 1.33MR1.

+

+#21.  (Fixed in 1.33MR1)  Use of ">>" (right shift operator in DLG actions

+

+        It is now possible to use the C++ right shift operator ">>"

+        in DLG actions by using the normal escapes:

+

+                #token "shift-right"     << value=value \>\> 1;>>

+

+#20.  (Version 1.33/19-Jan-97 Karl Eccleson <karle@microrobotics.co.uk>

+                            P.A. Keller (P.A.Keller@bath.ac.uk)

+

+        There is a problem due to using exceptions with the -gh option.

+

+        Suggested fix now in 1.33MR1.

+

+#19.  (Fixed in 1.33MR1)             Tom Piscotti and John Lilley

+

+        There were problems suppressing messages to stdin and stdout

+        when running in a window environment because some functions

+        which uses fprint were not virtual.

+

+        Suggested change now in 1.33MR1.

+

+        I believe all functions containing error messages (excluding those

+        indicating internal inconsistency) have been placed in functions

+        which are virtual.

+

+#18.  (Version 1.33/ 22-Nov-96)  John Bair (jbair@iftime.com)

+

+        Under some combination of options a required "return _retv" is

+        not generated.

+

+        Suggested fix now in 1.33MR1.

+

+#17.  (Version 1.33/3-Sep-96) Ron House  (house@helios.usq.edu.au)

+

+        The routine ASTBase::predorder_action omits two "tree->"

+        prefixes, which results in the preorder_action belonging

+        to the wrong node to be invoked.

+

+        Suggested fix now in 1.33MR1.

+

+#16.  (Version 1.33/7-Jun-96)       Eli Sternheim <eli@interhdl.com>

+

+        Routine consumeUntilToken() does not check for end-of-file

+        condition.

+

+        Suggested fix now in 1.33MR1.

+

+#15.  (Version 1.33/8 Apr 96)   Asgeir Olafsson <olafsson@cstar.ac.com>

+

+        Problem with tree duplication of doubly linked ASTs in ASTBase.cpp.

+

+        Suggested fix now in 1.33MR1.

+

+#14.  (Version 1.33/28-Feb-96)   Andreas.Magnusson@mailbox.swipnet.se

+

+        Problem with definition of operator = (const ANTLRTokenPtr rhs).

+

+        Suggested fix now in 1.33MR1.

+

+#13.  (Version 1.33/13-Feb-96) Franklin Chen (chen@adi.com)

+

+        Sun C++ Compiler 3.0.1 can't compile testcpp/1 due to goto in

+        block with destructors.

+

+        Apparently fixed. Can't locate "goto".

+

+#12.  (Version 1.33/10-Nov-95)  Minor problems with 1.33 code

+

+        The following items have been fixed in 1.33MR1:

+

+          1.  pccts/antlr/main.c line 142

+

+                "void" appears in classic C code

+

+          2.  no makefile in support/genmk

+

+          3.  EXIT_FAILURE/_SUCCESS instead of PCCTS_EXIT_FAILURE/_SUCCESS

+

+                pccts/h/PCCTSAST.cpp

+                pccts/h/DLexerBase.cpp

+                pccts/testcpp/6/test.g

+

+          4.  use of "signed int" isn't accepted by AT&T cfront

+

+                pccts/h/PCCTSAST.h line 42

+

+          5.  in call to ANTLRParser::FAIL the var arg err_k is passed as

+              "int" but is declared "unsigned int".

+

+          6.  I believe that a failed validation predicate still does not

+              get put in a "{...}" envelope, despite the release notes.

+

+          7. The #token ">>" appearing in the DLG grammar description

+             causes DLG to generate the string literal "\>\>" which

+             is non-conforming and will cause some compilers to

+             complain (scan.c function act10 line 143 of source code).

+

+#11.  (Version 1.32b6)  Dave Kuhlman     (dkuhlman@netcom.com)

+

+        Problem with file close in gen.c.  Already fixed in 1.33.

+

+#10.  (Version 1.32b6/29-Aug-95)

+

+        pccts/antlr/main.c contains a C++ style comments on lines 149

+        and 176 which causes problems for most C compilers.

+

+         Already fixed in 1.33.

+

+#9.   (Version 1.32b4/14-Mar-95) dlgauto.h #include "config.h"

+

+        The file pccts/h/dlgauto.h should probably contain a #include

+        "config.h" as it uses the #define symbol __USE_PROTOS.

+

+        Added to 1.33MR1.

+

+#8.   (Version 1.32b4/6-Mar-95)  Michael T. Richter (mtr@igs.net)

+

+        In C++ output mode anonymous tokens from in-line regular expressions

+        can create enum values which are too wide for the datatype of the enum

+        assigned by the C++ compiler.

+

+        Fixed in 1.33MR1.

+

+#7.   (Version 1.32b4/6-Mar-95)  C++ does not imply __STDC__

+

+        In err.h the combination of # directives assumes that a C++

+        compiler has __STDC__ defined.  This is not necessarily true.

+

+        This problem also appears in the use of __USE_PROTOS which

+        is appropriate for both Standard C and C++ in antlr/gen.c

+        and antlr/lex.c

+

+        Fixed in 1.33MR1.

+

+#6.   (Version 1.32 ?/15-Feb-95) Name conflict for "TokenType"

+

+        Already fixed in 1.33.

+

+#5.   (23-Jan-95)        Douglas_Cuthbertson.JTIDS@jtids_qmail.hanscom.af.mil

+

+        The fail action following a semantic predicate is not enclosed in

+        "{...}". This can lead to problems when the fail action contains

+        more than one statement.

+

+        Fixed in 1.33MR1.

+

+#4 .  (Version 1.33/31-Mar-96)   jlilley@empathy.com (John Lilley)

+

+        Put briefly, a semantic predicate ought to abort a guess if it fails.

+

+        Correction suggested by J. Lilley has been added to 1.33MR1.

+

+#3 .  (Version 1.33)             P.A.Keller@bath.ac.uk

+

+        Extra commas are placed in the K&R style argument list for rules

+        when using both exceptions and ASTs.

+

+        Fixed in 1.33MR1.

+

+#2.   (Version 1.32b6/2-Oct-95)  Brad Schick <schick@interaccess.com>

+

+        Construct #[] generates zzastnew() in C++ mode.

+

+        Already fixed in 1.33.

+

+#1.   (Version 1.33)     Bob Bailey (robert@oakhill.sps.mot.com)

+

+        Previously, config.h assumed that all PC systems required

+        "short" file names.  The user can now override that

+        assumption with "#define LONGFILENAMES".

+

+        Added to 1.33MR1.

diff --git a/edk2/Tools/Source/TianoTools/Pccts/CHANGES_SUMMARY.txt b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_SUMMARY.txt
new file mode 100644
index 0000000..91defae
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/CHANGES_SUMMARY.txt
@@ -0,0 +1,2049 @@
+======================================================================

+

+                       CHANGES_SUMMARY.TXT

+

+        A QUICK overview of changes from 1.33 in reverse order

+

+  A summary of additions rather than bug fixes and minor code changes.

+

+          Numbers refer to items in CHANGES_FROM_133*.TXT

+             which may contain additional information.

+

+                          DISCLAIMER

+

+ The software and these notes are provided "as is".  They may include

+ typographical or technical errors and their authors disclaims all

+ liability of any kind or nature for damages due to error, fault,

+ defect, or deficiency regardless of cause.  All warranties of any

+ kind, either express or implied, including, but not limited to, the

+ implied  warranties of merchantability and fitness for a particular

+ purpose are disclaimed.

+

+======================================================================

+

+#258. You can specify a user-defined base class for your parser

+

+    The base class must constructor must have a signature similar to

+    that of ANTLRParser.

+

+#253. Generation of block preamble (-preamble and -preamble_first)

+

+    The antlr option -preamble causes antlr to insert the code

+    BLOCK_PREAMBLE at the start of each rule and block.

+

+    The antlr option -preamble_first is similar, but inserts the

+    code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol

+    PreambleFirst_123 is equivalent to the first set defined by

+    the #FirstSetSymbol described in Item #248.

+

+#248. Generate symbol for first set of an alternative

+

+        rr : #FirstSetSymbol(rr_FirstSet)  ( Foo | Bar ) ;

+

+#216. Defer token fetch for C++ mode

+

+    When the ANTLRParser class is built with the pre-processor option 

+    ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred

+    until LA(i) or LT(i) is called. 

+

+#215. Use reset() to reset DLGLexerBase

+#188. Added pccts/h/DLG_stream_input.h

+#180. Added ANTLRParser::getEofToken()

+#173. -glms for Microsoft style filenames with -gl

+#170. Suppression for predicates with lookahead depth >1

+

+      Consider the following grammar with -ck 2 and the predicate in rule

+      "a" with depth 2:

+

+            r1  : (ab)* "@"

+                ;

+

+            ab  : a

+                | b

+                ;

+

+            a   : (A B)? => <<p(LATEXT(2))>>? A B C

+                ;

+

+            b   : A B C

+                ;

+

+      Normally, the predicate would be hoisted into rule r1 in order to

+      determine whether to call rule "ab".  However it should *not* be

+      hoisted because, even if p is false, there is a valid alternative

+      in rule b.  With "-mrhoistk on" the predicate will be suppressed.

+

+      If "-info p" command line option is present the following information

+      will appear in the generated code:

+

+                while ( (LA(1)==A)

+        #if 0

+

+        Part (or all) of predicate with depth > 1 suppressed by alternative

+            without predicate

+

+        pred  <<  p(LATEXT(2))>>?

+                  depth=k=2  ("=>" guard)  rule a  line 8  t1.g

+          tree context:

+            (root = A

+               B

+            )

+

+        The token sequence which is suppressed: ( A B )

+        The sequence of references which generate that sequence of tokens:

+

+           1 to ab          r1/1       line 1     t1.g

+           2 ab             ab/1       line 4     t1.g

+           3 to b           ab/2       line 5     t1.g

+           4 b              b/1        line 11    t1.g

+           5 #token A       b/1        line 11    t1.g

+           6 #token B       b/1        line 11    t1.g

+

+        #endif

+

+      A slightly more complicated example:

+

+            r1  : (ab)* "@"

+                ;

+

+            ab  : a

+                | b

+                ;

+

+            a   : (A B)? => <<p(LATEXT(2))>>? (A  B | D E)

+                ;

+

+            b   : <<q(LATEXT(2))>>? D E

+                ;

+

+

+      In this case, the sequence (D E) in rule "a" which lies behind

+      the guard is used to suppress the predicate with context (D E)

+      in rule b.

+

+                while ( (LA(1)==A || LA(1)==D)

+            #if 0

+

+            Part (or all) of predicate with depth > 1 suppressed by alternative

+                without predicate

+

+            pred  <<  q(LATEXT(2))>>?

+                              depth=k=2  rule b  line 11  t2.g

+              tree context:

+                (root = D

+                   E

+                )

+

+            The token sequence which is suppressed: ( D E )

+            The sequence of references which generate that sequence of tokens:

+

+               1 to ab          r1/1       line 1     t2.g

+               2 ab             ab/1       line 4     t2.g

+               3 to a           ab/1       line 4     t2.g

+               4 a              a/1        line 8     t2.g

+               5 #token D       a/1        line 8     t2.g

+               6 #token E       a/1        line 8     t2.g

+

+            #endif

+            &&

+            #if 0

+

+            pred  <<  p(LATEXT(2))>>?

+                              depth=k=2  ("=>" guard)  rule a  line 8  t2.g

+              tree context:

+                (root = A

+                   B

+                )

+

+            #endif

+

+            (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) )  {

+                ab();

+                ...

+

+#165. (Changed in MR13) option -newAST

+

+      To create ASTs from an ANTLRTokenPtr antlr usually calls

+      "new AST(ANTLRTokenPtr)".  This option generates a call

+      to "newAST(ANTLRTokenPtr)" instead.  This allows a user

+      to define a parser member function to create an AST object.

+

+#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h

+

+#158. (Changed in MR13) #header causes problem for pre-processors

+

+      A user who runs the C pre-processor on antlr source suggested

+      that another syntax be allowed.  With MR13 such directives

+      such as #header, #pragma, etc. may be written as "\#header",

+      "\#pragma", etc.  For escaping pre-processor directives inside

+      a #header use something like the following:

+

+            \#header

+            <<

+                \#include <stdio.h>

+            >>

+

+#155. (Changed in MR13) Context behind predicates can suppress

+

+      With -mrhoist enabled the context behind a guarded predicate can

+      be used to suppress other predicates.  Consider the following grammar:

+

+        r0 : (r1)+;

+

+        r1  : rp

+            | rq

+            ;

+        rp  : <<p LATEXT(1)>>? B ;

+        rq : (A)? => <<q LATEXT(1)>>? (A|B);

+

+      In earlier versions both predicates "p" and "q" would be hoisted into

+      rule r0. With MR12c predicate p is suppressed because the context which

+      follows predicate q includes "B" which can "cover" predicate "p".  In

+      other words, in trying to decide in r0 whether to call r1, it doesn't

+      really matter whether p is false or true because, either way, there is

+      a valid choice within r1.

+

+#154. (Changed in MR13) Making hoist suppression explicit using <<nohoist>>

+

+      A common error, even among experienced pccts users, is to code

+      an init-action to inhibit hoisting rather than a leading action.

+      An init-action does not inhibit hoisting.

+

+      This was coded:

+

+        rule1 : <<;>> rule2

+

+      This is what was meant:

+

+        rule1 : <<;>> <<;>> rule2

+

+      With MR13, the user can code:

+

+        rule1 : <<;>> <<nohoist>> rule2

+

+      The following will give an error message:

+

+        rule1 : <<nohoist>> rule2

+

+      If the <<nohoist>> appears as an init-action rather than a leading

+      action an error message is issued.  The meaning of an init-action

+      containing "nohoist" is unclear: does it apply to just one

+      alternative or to all alternatives ?

+

+#151a. Addition of ANTLRParser::getLexer(), ANTLRTokenStream::getLexer()

+

+      You must manually cast the ANTLRTokenStream to your program's

+      lexer class. Because the name of the lexer's class is not fixed.

+      Thus it is impossible to incorporate it into the DLGLexerBase

+      class.

+

+#151b.(Changed in MR12) ParserBlackBox member getLexer()

+

+#150. (Changed in MR12) syntaxErrCount and lexErrCount now public

+

+#149. (Changed in MR12) antlr option -info o (letter o for orphan)

+

+      If there is more than one rule which is not referenced by any

+      other rule then all such rules are listed.  This is useful for

+      alerting one to rules which are not used, but which can still

+      contribute to ambiguity.

+

+#148. (Changed in MR11) #token names appearing in zztokens,token_tbl

+

+      One can write:

+

+            #token Plus ("+")             "\+"

+            #token RP   ("(")             "\("

+            #token COM  ("comment begin") "/\*"

+

+      The string in parenthesis will be used in syntax error messages.

+

+#146. (Changed in MR11) Option -treport for locating "difficult" alts

+

+      It can be difficult to determine which alternatives are causing

+      pccts to work hard to resolve an ambiguity.  In some cases the

+      ambiguity is successfully resolved after much CPU time so there

+      is no message at all.

+

+      A rough measure of the amount of work being peformed which is

+      independent of the CPU speed and system load is the number of

+      tnodes created.  Using "-info t" gives information about the

+      total number of tnodes created and the peak number of tnodes.

+

+        Tree Nodes:  peak 1300k  created 1416k  lost 0

+

+      It also puts in the generated C or C++ file the number of tnodes

+      created for a rule (at the end of the rule).  However this

+      information is not sufficient to locate the alternatives within

+      a rule which are causing the creation of tnodes.

+

+      Using:

+

+             antlr -treport 100000 ....

+

+      causes antlr to list on stdout any alternatives which require the

+      creation of more than 100,000 tnodes, along with the lookahead sets

+      for those alternatives.

+

+      The following is a trivial case from the ansi.g grammar which shows

+      the format of the report.  This report might be of more interest

+      in cases where 1,000,000 tuples were created to resolve the ambiguity.

+

+      -------------------------------------------------------------------------

+        There were 0 tuples whose ambiguity could not be resolved

+             by full lookahead

+        There were 157 tnodes created to resolve ambiguity between:

+

+          Choice 1: statement/2  line 475  file ansi.g

+          Choice 2: statement/3  line 476  file ansi.g

+

+            Intersection of lookahead[1] sets:

+

+               IDENTIFIER

+

+            Intersection of lookahead[2] sets:

+

+               LPARENTHESIS     COLON            AMPERSAND        MINUS

+               STAR             PLUSPLUS         MINUSMINUS       ONESCOMPLEMENT

+               NOT              SIZEOF           OCTALINT         DECIMALINT

+               HEXADECIMALINT   FLOATONE         FLOATTWO         IDENTIFIER

+               STRING           CHARACTER

+      -------------------------------------------------------------------------

+

+#143. (Changed in MR11) Optional ";" at end of #token statement

+

+      Fixes problem of:

+

+            #token X "x"

+

+            <<

+                parser action

+            >>

+

+      Being confused with:

+

+            #token X "x" <<lexical action>>

+

+#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream

+

+      Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class

+      BufFileInput derived from DLGInputStream which provides a

+      function lookahead(char *string) to test characters in the

+      input stream more than one character ahead.

+      The class is located in pccts/h/BufFileInput.* of the kit.

+

+#140. #pred to define predicates

+

+      +---------------------------------------------------+

+      | Note: Assume "-prc on" for this entire discussion |

+      +---------------------------------------------------+

+

+      A problem with predicates is that each one is regarded as

+      unique and capable of disambiguating cases where two

+      alternatives have identical lookahead.  For example:

+

+        rule : <<pred(LATEXT(1))>>? A

+             | <<pred(LATEXT(1))>>? A

+             ;

+

+      will not cause any error messages or warnings to be issued

+      by earlier versions of pccts.  To compare the text of the

+      predicates is an incomplete solution.

+

+      In 1.33MR11 I am introducing the #pred statement in order to

+      solve some problems with predicates.  The #pred statement allows

+      one to give a symbolic name to a "predicate literal" or a

+      "predicate expression" in order to refer to it in other predicate

+      expressions or in the rules of the grammar.

+

+      The predicate literal associated with a predicate symbol is C

+      or C++ code which can be used to test the condition.  A

+      predicate expression defines a predicate symbol in terms of other

+      predicate symbols using "!", "&&", and "||".  A predicate symbol

+      can be defined in terms of a predicate literal, a predicate

+      expression, or *both*.

+

+      When a predicate symbol is defined with both a predicate literal

+      and a predicate expression, the predicate literal is used to generate

+      code, but the predicate expression is used to check for two

+      alternatives with identical predicates in both alternatives.

+

+      Here are some examples of #pred statements:

+

+        #pred  IsLabel       <<isLabel(LATEXT(1))>>?

+        #pred  IsLocalVar    <<isLocalVar(LATEXT(1))>>?

+        #pred  IsGlobalVar   <<isGlobalVar(LATEXT(1)>>?

+        #pred  IsVar         <<isVar(LATEXT(1))>>?       IsLocalVar || IsGlobalVar

+        #pred  IsScoped      <<isScoped(LATEXT(1))>>?    IsLabel || IsLocalVar

+

+      I hope that the use of EBNF notation to describe the syntax of the

+      #pred statement will not cause problems for my readers (joke).

+

+        predStatement : "#pred"

+                            CapitalizedName

+                              (

+                                  "<<predicate_literal>>?"

+                                | "<<predicate_literal>>?"  predOrExpr

+                                | predOrExpr

+                              )

+                      ;

+

+        predOrExpr    : predAndExpr ( "||" predAndExpr ) * ;

+

+        predAndExpr   : predPrimary ( "&&" predPrimary ) * ;

+

+        predPrimary   : CapitalizedName

+                      | "!" predPrimary

+                      | "(" predOrExpr ")"

+                      ;

+

+      What is the purpose of this nonsense ?

+

+      To understand how predicate symbols help, you need to realize that

+      predicate symbols are used in two different ways with two different

+      goals.

+

+        a. Allow simplification of predicates which have been combined

+           during predicate hoisting.

+

+        b. Allow recognition of identical predicates which can't disambiguate

+           alternatives with common lookahead.

+

+      First we will discuss goal (a).  Consider the following rule:

+

+            rule0: rule1

+                 | ID

+                 | ...

+                 ;

+

+            rule1: rule2

+                 | rule3

+                 ;

+

+            rule2: <<isX(LATEXT(1))>>? ID ;

+            rule3: <<!isX(LATEXT(1)>>? ID ;

+

+      When the predicates in rule2 and rule3 are combined by hoisting

+      to create a prediction expression for rule1 the result is:

+

+            if ( LA(1)==ID

+                && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ...

+

+      This is inefficient, but more importantly, can lead to false

+      assumptions that the predicate expression distinguishes the rule1

+      alternative with some other alternative with lookahead ID.  In

+      MR11 one can write:

+

+            #pred IsX     <<isX(LATEXT(1))>>?

+

+            ...

+

+            rule2: <<IsX>>? ID  ;

+            rule3: <<!IsX>>? ID ;

+

+      During hoisting MR11 recognizes this as a special case and

+      eliminates the predicates.  The result is a prediction

+      expression like the following:

+

+            if ( LA(1)==ID ) { rule1(); ...

+

+      Please note that the following cases which appear to be equivalent

+      *cannot* be simplified by MR11 during hoisting because the hoisting

+      logic only checks for a "!" in the predicate action, not in the

+      predicate expression for a predicate symbol.

+

+        *Not* equivalent and is not simplified during hoisting:

+

+            #pred IsX      <<isX(LATEXT(1))>>?

+            #pred NotX     <<!isX(LATEXT(1))>>?

+            ...

+            rule2: <<IsX>>? ID  ;

+            rule3: <<NotX>>? ID ;

+

+        *Not* equivalent and is not simplified during hoisting:

+

+            #pred IsX      <<isX(LATEXT(1))>>?

+            #pred NotX     !IsX

+            ...

+            rule2: <<IsX>>? ID  ;

+            rule3: <<NotX>>? ID ;

+

+      Now we will discuss goal (b).

+

+      When antlr discovers that there is a lookahead ambiguity between

+      two alternatives it attempts to resolve the ambiguity by searching

+      for predicates in both alternatives.  In the past any predicate

+      would do, even if the same one appeared in both alternatives:

+

+            rule: <<p(LATEXT(1))>>? X

+                | <<p(LATEXT(1))>>? X

+                ;

+

+      The #pred statement is a start towards solving this problem.

+      During ambiguity resolution (*not* predicate hoisting) the

+      predicates for the two alternatives are expanded and compared.

+      Consider the following example:

+

+            #pred Upper     <<isUpper(LATEXT(1))>>?

+            #pred Lower     <<isLower(LATEXT(1))>>?

+            #pred Alpha     <<isAlpha(LATEXT(1))>>?  Upper || Lower

+

+            rule0: rule1

+                 | <<Alpha>>? ID

+                 ;

+

+            rule1:

+                 | rule2

+                 | rule3

+                 ...

+                 ;

+

+            rule2: <<Upper>>? ID;

+            rule3: <<Lower>>? ID;

+

+      The definition of #pred Alpha expresses:

+

+            a. to test the predicate use the C code "isAlpha(LATEXT(1))"

+

+            b. to analyze the predicate use the information that

+               Alpha is equivalent to the union of Upper and Lower,

+

+      During ambiguity resolution the definition of Alpha is expanded

+      into "Upper || Lower" and compared with the predicate in the other

+      alternative, which is also "Upper || Lower".  Because they are

+      identical MR11 will report a problem.

+

+    -------------------------------------------------------------------------

+      t10.g, line 5: warning: the predicates used to disambiguate rule rule0

+             (file t10.g alt 1 line 5 and alt 2 line 6)

+             are identical when compared without context and may have no

+             resolving power for some lookahead sequences.

+    -------------------------------------------------------------------------

+

+      If you use the "-info p" option the output file will contain:

+

+    +----------------------------------------------------------------------+

+    |#if 0                                                                 |

+    |                                                                      |

+    |The following predicates are identical when compared without          |

+    |  lookahead context information.  For some ambiguous lookahead        |

+    |  sequences they may not have any power to resolve the ambiguity.     |

+    |                                                                      |

+    |Choice 1: rule0/1  alt 1  line 5  file t10.g                          |

+    |                                                                      |

+    |  The original predicate for choice 1 with available context          |

+    |    information:                                                      |

+    |                                                                      |

+    |    OR expr                                                           |

+    |                                                                      |

+    |      pred  <<  Upper>>?                                              |

+    |                        depth=k=1  rule rule2  line 14  t10.g         |

+    |        set context:                                                  |

+    |           ID                                                         |

+    |                                                                      |

+    |      pred  <<  Lower>>?                                              |

+    |                        depth=k=1  rule rule3  line 15  t10.g         |

+    |        set context:                                                  |

+    |           ID                                                         |

+    |                                                                      |

+    |  The predicate for choice 1 after expansion (but without context     |

+    |    information):                                                     |

+    |                                                                      |

+    |    OR expr                                                           |

+    |                                                                      |

+    |      pred  <<  isUpper(LATEXT(1))>>?                                 |

+    |                        depth=k=1  rule   line 1  t10.g               |

+    |                                                                      |

+    |      pred  <<  isLower(LATEXT(1))>>?                                 |

+    |                        depth=k=1  rule   line 2  t10.g               |

+    |                                                                      |

+    |                                                                      |

+    |Choice 2: rule0/2  alt 2  line 6  file t10.g                          |

+    |                                                                      |

+    |  The original predicate for choice 2 with available context          |

+    |    information:                                                      |

+    |                                                                      |

+    |  pred  <<  Alpha>>?                                                  |

+    |                    depth=k=1  rule rule0  line 6  t10.g              |

+    |    set context:                                                      |

+    |       ID                                                             |

+    |                                                                      |

+    |  The predicate for choice 2 after expansion (but without context     |

+    |    information):                                                     |

+    |                                                                      |

+    |  OR expr                                                             |

+    |                                                                      |

+    |    pred  <<  isUpper(LATEXT(1))>>?                                   |

+    |                      depth=k=1  rule   line 1  t10.g                 |

+    |                                                                      |

+    |    pred  <<  isLower(LATEXT(1))>>?                                   |

+    |                      depth=k=1  rule   line 2  t10.g                 |

+    |                                                                      |

+    |                                                                      |

+    |#endif                                                                |

+    +----------------------------------------------------------------------+

+

+      The comparison of the predicates for the two alternatives takes

+      place without context information, which means that in some cases

+      the predicates will be considered identical even though they operate

+      on disjoint lookahead sets.  Consider:

+

+            #pred Alpha

+

+            rule1: <<Alpha>>? ID

+                 | <<Alpha>>? Label

+                 ;

+

+      Because the comparison of predicates takes place without context

+      these will be considered identical.  The reason for comparing

+      without context is that otherwise it would be necessary to re-evaluate

+      the entire predicate expression for each possible lookahead sequence.

+      This would require more code to be written and more CPU time during

+      grammar analysis, and it is not yet clear whether anyone will even make

+      use of the new #pred facility.

+

+      A temporary workaround might be to use different #pred statements

+      for predicates you know have different context.  This would avoid

+      extraneous warnings.

+

+      The above example might be termed a "false positive".  Comparison

+      without context will also lead to "false negatives".  Consider the

+      following example:

+

+            #pred Alpha

+            #pred Beta

+

+            rule1: <<Alpha>>? A

+                 | rule2

+                 ;

+

+            rule2: <<Alpha>>? A

+                 | <<Beta>>?  B

+                 ;

+

+      The predicate used for alt 2 of rule1 is (Alpha || Beta).  This

+      appears to be different than the predicate Alpha used for alt1.

+      However, the context of Beta is B.  Thus when the lookahead is A

+      Beta will have no resolving power and Alpha will be used for both

+      alternatives.  Using the same predicate for both alternatives isn't

+      very helpful, but this will not be detected with 1.33MR11.

+

+      To properly handle this the predicate expression would have to be

+      evaluated for each distinct lookahead context.

+

+      To determine whether two predicate expressions are identical is

+      difficult.  The routine may fail to identify identical predicates.

+

+      The #pred feature also compares predicates to see if a choice between

+      alternatives which is resolved by a predicate which makes the second

+      choice unreachable.  Consider the following example:

+

+            #pred A         <<A(LATEXT(1)>>?

+            #pred B         <<B(LATEXT(1)>>?

+            #pred A_or_B    A || B

+

+            r   : s

+                | t

+                ;

+            s   : <<A_or_B>>? ID

+                ;

+            t   : <<A>>? ID

+                ;

+

+        ----------------------------------------------------------------------------

+        t11.g, line 5: warning: the predicate used to disambiguate the

+               first choice of  rule r

+             (file t11.g alt 1 line 5 and alt 2 line 6)

+             appears to "cover" the second predicate when compared without context.

+             The second predicate may have no resolving power for some lookahead

+               sequences.

+        ----------------------------------------------------------------------------

+

+#132. (Changed in 1.33MR11) Recognition of identical predicates in alts

+

+      Prior to 1.33MR11, there would be no ambiguity warning when the

+      very same predicate was used to disambiguate both alternatives:

+

+        test: ref B

+            | ref C

+            ;

+

+        ref : <<pred(LATEXT(1)>>? A

+

+      In 1.33MR11 this will cause the warning:

+

+        warning: the predicates used to disambiguate rule test

+            (file v98.g alt 1 line 1 and alt 2 line 2)

+             are identical and have no resolving power

+

+        -----------------  Note  -----------------

+

+          This is different than the following case

+

+                test: <<pred(LATEXT(1))>>? A B

+                    | <<pred(LATEXT(1)>>?  A C

+                    ;

+

+          In this case there are two distinct predicates

+          which have exactly the same text.  In the first

+          example there are two references to the same

+          predicate.  The problem represented by this

+          grammar will be addressed later.

+

+

+#127. (Changed in 1.33MR11)

+

+                    Count Syntax Errors     Count DLG Errors

+                    -------------------     ----------------

+

+       C++ mode     ANTLRParser::           DLGLexerBase::

+                      syntaxErrCount          lexErrCount

+       C mode       zzSyntaxErrCount        zzLexErrCount

+

+       The C mode variables are global and initialized to 0.

+       They are *not* reset to 0 automatically when antlr is

+       restarted.

+

+       The C++ mode variables are public.  They are initialized

+       to 0 by the constructors.  They are *not* reset to 0 by the

+       ANTLRParser::init() method.

+

+       Suggested by Reinier van den Born (reinier@vnet.ibm.com).

+

+#126. (Changed in 1.33MR11) Addition of #first <<...>>

+

+       The #first <<...>> inserts the specified text in the output

+       files before any other #include statements required by pccts.

+       The only things before the #first text are comments and

+       a #define ANTLR_VERSION.

+

+       Requested by  and Esa Pulkkinen (esap@cs.tut.fi) and Alexin

+       Zoltan (alexin@inf.u-szeged.hu).

+

+#124. A Note on the New "&&" Style Guarded Predicates

+

+        I've been asked several times, "What is the difference between

+        the old "=>" style guard predicates and the new style "&&" guard

+        predicates, and how do you choose one over the other" ?

+

+        The main difference is that the "=>" does not apply the

+        predicate if the context guard doesn't match, whereas

+        the && form always does.  What is the significance ?

+

+        If you have a predicate which is not on the "leading edge"

+        it is cannot be hoisted.  Suppose you need a predicate that

+        looks at LA(2).  You must introduce it manually.  The

+        classic example is:

+

+            castExpr :

+                     LP typeName RP

+                     | ....

+                     ;

+

+            typeName : <<isTypeName(LATEXT(1))>>?  ID

+                     | STRUCT ID

+                     ;

+

+        The problem  is that isTypeName() isn't on the leading edge

+        of typeName, so it won't be hoisted into castExpr to help

+        make a decision on which production to choose.

+

+        The *first* attempt to fix it is this:

+

+            castExpr :

+                     <<isTypeName(LATEXT(2))>>?

+                                        LP typeName RP

+                     | ....

+                     ;

+

+        Unfortunately, this won't work because it ignores

+        the problem of STRUCT.  The solution is to apply

+        isTypeName() in castExpr if LA(2) is an ID and

+        don't apply it when LA(2) is STRUCT:

+

+            castExpr :

+                     (LP ID)? => <<isTypeName(LATEXT(2))>>?

+                                        LP typeName RP

+                     | ....

+                     ;

+

+        In conclusion, the "=>" style guarded predicate is

+        useful when:

+

+            a. the tokens required for the predicate

+               are not on the leading edge

+            b. there are alternatives in the expression

+               selected by the predicate for which the

+               predicate is inappropriate

+

+        If (b) were false, then one could use a simple

+        predicate (assuming "-prc on"):

+

+            castExpr :

+                     <<isTypeName(LATEXT(2))>>?

+                                        LP typeName RP

+                     | ....

+                     ;

+

+            typeName : <<isTypeName(LATEXT(1))>>?  ID

+                     ;

+

+        So, when do you use the "&&" style guarded predicate ?

+

+        The new-style "&&" predicate should always be used with

+        predicate context.  The context guard is in ADDITION to

+        the automatically computed context.  Thus it useful for

+        predicates which depend on the token type for reasons

+        other than context.

+

+        The following example is contributed by Reinier van den Born

+        (reinier@vnet.ibm.com).

+

+ +-------------------------------------------------------------------------+

+ | This grammar has two ways to call functions:                            |

+ |                                                                         |

+ |  - a "standard" call syntax with parens and comma separated args        |

+ |  - a shell command like syntax (no parens and spacing separated args)   |

+ |                                                                         |

+ | The former also allows a variable to hold the name of the function,     |

+ | the latter can also be used to call external commands.                  |

+ |                                                                         |

+ | The grammar (simplified) looks like this:                               |

+ |                                                                         |

+ |   fun_call   :     ID "(" { expr ("," expr)* } ")"                      |

+ |                                  /* ID is function name */              |

+ |              | "@" ID "(" { expr ("," expr)* } ")"                      |

+ |                                  /* ID is var containing fun name */    |

+ |              ;                                                          |

+ |                                                                         |

+ |   command    : ID expr*          /* ID is function name */              |

+ |              | path expr*        /* path is external command name */    |

+ |              ;                                                          |

+ |                                                                         |

+ |   path       : ID                /* left out slashes and such */        |

+ |              | "@" ID            /* ID is environment var */            |

+ |              ;                                                          |

+ |                                                                         |

+ |   expr       : ....                                                     |

+ |              | "(" expr ")";                                            |

+ |                                                                         |

+ |   call       : fun_call                                                 |

+ |              | command                                                  |

+ |              ;                                                          |

+ |                                                                         |

+ | Obviously the call is wildly ambiguous. This is more or less how this   |

+ | is to be resolved:                                                      |

+ |                                                                         |

+ |    A call begins with an ID or an @ followed by an ID.                  |

+ |                                                                         |

+ |    If it is an ID and if it is an ext. command name  -> command         |

+ |                       if followed by a paren         -> fun_call        |

+ |                       otherwise                      -> command         |

+ |                                                                         |

+ |    If it is an @  and if the ID is a var name        -> fun_call        |

+ |                       otherwise                      -> command         |

+ |                                                                         |

+ | One can implement these rules quite neatly using && predicates:         |

+ |                                                                         |

+ |   call       : ("@" ID)? && <<isVarName(LT(2))>>? fun_call              |

+ |              | (ID)?     && <<isExtCmdName>>?     command               |

+ |              | (ID "(")?                          fun_call              |

+ |              |                                    command               |

+ |              ;                                                          |

+ |                                                                         |

+ | This can be done better, so it is not an ideal example, but it          |

+ | conveys the principle.                                                  |

+ +-------------------------------------------------------------------------+

+

+#122. (Changed in 1.33MR11)  Member functions to reset DLG in C++ mode

+

+         void DLGFileReset(FILE *f) { input = f; found_eof = 0; }

+         void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; }

+

+        Supplied by R.A. Nelson (cowboy@VNET.IBM.COM)

+

+#119. (Changed in 1.33MR11) Ambiguity aid for grammars

+

+      The user can ask for additional information on ambiguities reported

+      by antlr to stdout.  At the moment, only one ambiguity report can

+      be created in an antlr run.

+

+      This feature is enabled using the "-aa" (Ambiguity Aid)  option.

+

+      The following options control the reporting of ambiguities:

+

+          -aa ruleName       Selects reporting by name of rule

+          -aa lineNumber     Selects reporting by line number

+                               (file name not compared)

+

+          -aam               Selects "multiple" reporting for a token

+                             in the intersection set of the

+                             alternatives.

+

+                             For instance, the token ID may appear dozens

+                             of times in various paths as the program

+                             explores the rules which are reachable from

+                             the point of an ambiguity. With option -aam

+                             every possible path the search program

+                             encounters is reported.

+

+                             Without -aam only the first encounter is

+                             reported.  This may result in incomplete

+                             information, but the information may be

+                             sufficient and much shorter.

+

+          -aad depth         Selects the depth of the search.

+                             The default value is 1.

+

+                             The number of paths to be searched, and the

+                             size of the report can grow geometrically

+                             with the -ck value if a full search for all

+                             contributions to the source of the ambiguity

+                             is explored.

+

+                             The depth represents the number of tokens

+                             in the lookahead set which are matched against

+                             the set of ambiguous tokens.  A depth of 1

+                             means that the search stops when a lookahead

+                             sequence of just one token is matched.

+

+                             A k=1 ck=6 grammar might generate 5,000 items

+                             in a report if a full depth 6 search is made

+                             with the Ambiguity Aid.  The source of the

+                             problem may be in the first token and obscured

+                             by the volume of data - I hesitate to call

+                             it information.

+

+                             When the user selects a depth > 1, the search

+                             is first performed at depth=1 for both

+                             alternatives, then depth=2 for both alternatives,

+                             etc.

+

+      Sample output for rule grammar in antlr.g itself:

+

+  +---------------------------------------------------------------------+

+  | Ambiguity Aid                                                       |

+  |                                                                     |

+  |   Choice 1: grammar/70                 line 632  file a.g           |

+  |   Choice 2: grammar/82                 line 644  file a.g           |

+  |                                                                     |

+  |   Intersection of lookahead[1] sets:                                |

+  |                                                                     |

+  |      "\}"             "class"          "#errclass"      "#tokclass" |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:1  ("#errclass")                        |

+  |  1 in (...)* block                grammar/70       line 632   a.g   |

+  |  2 to error                       grammar/73       line 635   a.g   |

+  |  3 error                          error/1          line 894   a.g   |

+  |  4 #token "#errclass"             error/2          line 895   a.g   |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:2  ("#tokclass")                        |

+  |  2 to tclass                      grammar/74       line 636   a.g   |

+  |  3 tclass                         tclass/1         line 937   a.g   |

+  |  4 #token "#tokclass"             tclass/2         line 938   a.g   |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:3  ("class")                            |

+  |  2 to class_def                   grammar/75       line 637   a.g   |

+  |  3 class_def                      class_def/1      line 669   a.g   |

+  |  4 #token "class"                 class_def/3      line 671   a.g   |

+  |                                                                     |

+  |    Choice:1  Depth:1  Group:4  ("\}")                               |

+  |  2 #token "\}"                    grammar/76       line 638   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:5  ("#errclass")                        |

+  |  1 in (...)* block                grammar/83       line 645   a.g   |

+  |  2 to error                       grammar/93       line 655   a.g   |

+  |  3 error                          error/1          line 894   a.g   |

+  |  4 #token "#errclass"             error/2          line 895   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:6  ("#tokclass")                        |

+  |  2 to tclass                      grammar/94       line 656   a.g   |

+  |  3 tclass                         tclass/1         line 937   a.g   |

+  |  4 #token "#tokclass"             tclass/2         line 938   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:7  ("class")                            |

+  |  2 to class_def                   grammar/95       line 657   a.g   |

+  |  3 class_def                      class_def/1      line 669   a.g   |

+  |  4 #token "class"                 class_def/3      line 671   a.g   |

+  |                                                                     |

+  |    Choice:2  Depth:1  Group:8  ("\}")                               |

+  |  2 #token "\}"                    grammar/96       line 658   a.g   |

+  +---------------------------------------------------------------------+

+

+      For a linear lookahead set ambiguity (where k=1 or for k>1 but

+      when all lookahead sets [i] with i<k all have degree one) the

+      reports appear in the following order:

+

+        for (depth=1 ; depth <= "-aad depth" ; depth++) {

+          for (alternative=1; alternative <=2 ; alternative++) {

+            while (matches-are-found) {

+              group++;

+              print-report

+            };

+          };

+       };

+

+      For reporting a k-tuple ambiguity, the reports appear in the

+      following order:

+

+        for (depth=1 ; depth <= "-aad depth" ; depth++) {

+          while (matches-are-found) {

+            for (alternative=1; alternative <=2 ; alternative++) {

+              group++;

+              print-report

+            };

+          };

+       };

+

+      This is because matches are generated in different ways for

+      linear lookahead and k-tuples.

+

+#117. (Changed in 1.33MR10) new EXPERIMENTAL predicate hoisting code

+

+      The hoisting of predicates into rules to create prediction

+      expressions is a problem in antlr.  Consider the following

+      example (k=1 with -prc on):

+

+        start   : (a)* "@" ;

+        a       : b | c ;

+        b       : <<isUpper(LATEXT(1))>>? A ;

+        c       : A ;

+

+      Prior to 1.33MR10 the code generated for "start" would resemble:

+

+        while {

+            if (LA(1)==A &&

+                    (!LA(1)==A || isUpper())) {

+              a();

+            }

+        };

+

+      This code is wrong because it makes rule "c" unreachable from

+      "start".  The essence of the problem is that antlr fails to

+      recognize that there can be a valid alternative within "a" even

+      when the predicate <<isUpper(LATEXT(1))>>? is false.

+

+      In 1.33MR10 with -mrhoist the hoisting of the predicate into

+      "start" is suppressed because it recognizes that "c" can

+      cover all the cases where the predicate is false:

+

+        while {

+            if (LA(1)==A) {

+              a();

+            }

+        };

+

+      With the antlr "-info p" switch the user will receive information

+      about the predicate suppression in the generated file:

+

+      --------------------------------------------------------------

+        #if 0

+

+        Hoisting of predicate suppressed by alternative without predicate.

+        The alt without the predicate includes all cases where

+            the predicate is false.

+

+           WITH predicate: line 7  v1.g

+           WITHOUT predicate: line 7  v1.g

+

+        The context set for the predicate:

+

+             A

+

+        The lookahead set for the alt WITHOUT the semantic predicate:

+

+             A

+

+        The predicate:

+

+          pred <<  isUpper(LATEXT(1))>>?

+                          depth=k=1  rule b  line 9  v1.g

+            set context:

+               A

+            tree context: null

+

+        Chain of referenced rules:

+

+            #0  in rule start (line 5 v1.g) to rule a

+            #1  in rule a (line 7 v1.g)

+

+        #endif

+      --------------------------------------------------------------

+

+      A predicate can be suppressed by a combination of alternatives

+      which, taken together, cover a predicate:

+

+        start   : (a)* "@" ;

+

+        a       : b | ca | cb | cc ;

+

+        b       : <<isUpper(LATEXT(1))>>? ( A | B | C ) ;

+

+        ca      : A ;

+        cb      : B ;

+        cc      : C ;

+

+      Consider a more complex example in which "c" covers only part of

+      a predicate:

+

+        start   : (a)* "@" ;

+

+        a       : b

+                | c

+                ;

+

+        b       : <<isUpper(LATEXT(1))>>?

+                    ( A

+                    | X

+                    );

+

+        c       : A

+                ;

+

+      Prior to 1.33MR10 the code generated for "start" would resemble:

+

+        while {

+            if ( (LA(1)==A || LA(1)==X) &&

+                    (! (LA(1)==A || LA(1)==X) || isUpper()) {

+              a();

+            }

+        };

+

+      With 1.33MR10 and -mrhoist the predicate context is restricted to

+      the non-covered lookahead.  The code resembles:

+

+        while {

+            if ( (LA(1)==A || LA(1)==X) &&

+                  (! (LA(1)==X) || isUpper()) {

+              a();

+            }

+        };

+

+      With the antlr "-info p" switch the user will receive information

+      about the predicate restriction in the generated file:

+

+      --------------------------------------------------------------

+        #if 0

+

+        Restricting the context of a predicate because of overlap

+          in the lookahead set between the alternative with the

+          semantic predicate and one without

+        Without this restriction the alternative without the predicate

+          could not be reached when input matched the context of the

+          predicate and the predicate was false.

+

+           WITH predicate: line 11  v4.g

+           WITHOUT predicate: line 12  v4.g

+

+        The original context set for the predicate:

+

+             A                X

+

+        The lookahead set for the alt WITHOUT the semantic predicate:

+

+             A

+

+        The intersection of the two sets

+

+             A

+

+        The original predicate:

+

+          pred <<  isUpper(LATEXT(1))>>?

+                          depth=k=1  rule b  line 15  v4.g

+            set context:

+               A                X

+            tree context: null

+

+        The new (modified) form of the predicate:

+

+          pred <<  isUpper(LATEXT(1))>>?

+                          depth=k=1  rule b  line 15  v4.g

+            set context:

+               X

+            tree context: null

+

+        #endif

+      --------------------------------------------------------------

+

+      The bad news about -mrhoist:

+

+        (a) -mrhoist does not analyze predicates with lookahead

+            depth > 1.

+

+        (b) -mrhoist does not look past a guarded predicate to

+            find context which might cover other predicates.

+

+      For these cases you might want to use syntactic predicates.

+      When a semantic predicate fails during guess mode the guess

+      fails and the next alternative is tried.

+

+      Limitation (a) is illustrated by the following example:

+

+        start    : (stmt)* EOF ;

+

+        stmt     : cast

+                 | expr

+                 ;

+        cast     : <<isTypename(LATEXT(2))>>? LP ID RP ;

+

+        expr     : LP ID RP ;

+

+      This is not much different from the first example, except that

+      it requires two tokens of lookahead context to determine what

+      to do.  This predicate is NOT suppressed because the current version

+      is unable to handle predicates with depth > 1.

+

+      A predicate can be combined with other predicates during hoisting.

+      In those cases the depth=1 predicates are still handled.  Thus,

+      in the following example the isUpper() predicate will be suppressed

+      by line #4 when hoisted from "bizarre" into "start", but will still

+      be present in "bizarre" in order to predict "stmt".

+

+        start    : (bizarre)* EOF ;     // #1

+                                        // #2

+        bizarre  : stmt                 // #3

+                 | A                    // #4

+                 ;

+

+        stmt     : cast

+                 | expr

+                 ;

+

+        cast     : <<isTypename(LATEXT(2))>>? LP ID RP ;

+

+        expr     : LP ID RP ;

+                 | <<isUpper(LATEXT(1))>>? A

+

+      Limitation (b) is illustrated by the following example of a

+      context guarded predicate:

+

+        rule : (A)? <<p>>?          // #1

+                     (A             // #2

+                     |B             // #3

+                     )              // #4

+             | <<q>> B              // #5

+             ;

+

+      Recall that this means that when the lookahead is NOT A then

+      the predicate "p" is ignored and it attempts to match "A|B".

+      Ideally, the "B" at line #3 should suppress predicate "q".

+      However, the current version does not attempt to look past

+      the guard predicate to find context which might suppress other

+      predicates.

+

+      In some cases -mrhoist will lead to the reporting of ambiguities

+      which were not visible before:

+

+        start   : (a)* "@";

+        a       : bc | d;

+        bc      : b  | c ;

+

+        b       : <<isUpper(LATEXT(1))>>? A;

+        c       : A ;

+

+        d       : A ;

+

+      In this case there is a true ambiguity in "a" between "bc" and "d"

+      which can both match "A".  Without -mrhoist the predicate in "b"

+      is hoisted into "a" and there is no ambiguity reported.  However,

+      with -mrhoist, the predicate in "b" is suppressed by "c" (as it

+      should be) making the ambiguity in "a" apparent.

+

+      The motivations for these changes were hoisting problems reported

+      by Reinier van den Born (reinier@vnet.ibm.com) and several others.

+

+#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <<p>>? expr

+

+      The existing context guarded predicate:

+

+            rule : (guard)? => <<p>>? expr

+                 | next_alternative

+                 ;

+

+      generates code which resembles:

+

+            if (lookahead(expr) && (!guard || pred)) {

+              expr()

+            } else ....

+

+      This is not suitable for some applications because it allows

+      expr() to be invoked when the predicate is false.  This is

+      intentional because it is meant to mimic automatically computed

+      predicate context.

+

+      The new context guarded predicate uses the guard information

+      differently because it has a different goal.  Consider:

+

+            rule : (guard)? && <<p>>? expr

+                 | next_alternative

+                 ;

+

+      The new style of context guarded predicate is equivalent to:

+

+            rule : <<guard==true && pred>>? expr

+                 | next_alternative

+                 ;

+

+      It generates code which resembles:

+

+            if (lookahead(expr) && guard && pred) {

+                expr();

+            } else ...

+

+      Both forms of guarded predicates severely restrict the form of

+      the context guard: it can contain no rule references, no

+      (...)*, no (...)+, and no {...}.  It may contain token and

+      token class references, and alternation ("|").

+

+      Addition for 1.33MR11: in the token expression all tokens must

+      be at the same height of the token tree:

+

+            (A ( B | C))? && ...            is ok (all height 2)

+            (A ( B |  ))? && ...            is not ok (some 1, some 2)

+            (A B C D | E F G H)? && ...     is ok (all height 4)

+            (A B C D | E )? && ...          is not ok (some 4, some 1)

+

+      This restriction is required in order to properly compute the lookahead

+      set for expressions like:

+

+            rule1 : (A B C)? && <<pred>>? rule2 ;

+            rule2 : (A|X) (B|Y) (C|Z);

+

+      This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com)

+

+#109. (Changed in 1.33MR10) improved trace information

+

+      The quality of the trace information provided by the "-gd"

+      switch has been improved significantly.  Here is an example

+      of the output from a test program.  It shows the rule name,

+      the first token of lookahead, the call depth, and the guess

+      status:

+

+        exit rule gusxx {"?"} depth 2

+        enter rule gusxx {"?"} depth 2

+        enter rule gus1 {"o"} depth 3 guessing

+        guess done - returning to rule gus1 {"o"} at depth 3

+                    (guess mode continues - an enclosing guess is still active)

+        guess done - returning to rule gus1 {"Z"} at depth 3

+                    (guess mode continues - an enclosing guess is still active)

+        exit rule gus1 {"Z"} depth 3 guessing

+        guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends)

+        enter rule gus1 {"o"} depth 3

+        guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends)

+        guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends)

+        exit rule gus1 {"Z"} depth 3

+        line 1: syntax error at "Z" missing SC

+            ...

+

+      Rule trace reporting is controlled by the value of the integer

+      [zz]traceOptionValue:  when it is positive tracing is enabled,

+      otherwise it is disabled.  Tracing during guess mode is controlled

+      by the value of the integer [zz]traceGuessOptionValue.  When

+      it is positive AND [zz]traceOptionValue is positive rule trace

+      is reported in guess mode.

+

+      The values of [zz]traceOptionValue and [zz]traceGuessOptionValue

+      can be adjusted by subroutine calls listed below.

+

+      Depending on the presence or absence of the antlr -gd switch

+      the variable [zz]traceOptionValueDefault is set to 0 or 1.  When

+      the parser is initialized or [zz]traceReset() is called the

+      value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue.

+      The value of [zz]traceGuessOptionValue is always initialzed to 1,

+      but, as noted earlier, nothing will be reported unless

+      [zz]traceOptionValue is also positive.

+

+      When the parser state is saved/restored the value of the trace

+      variables are also saved/restored.  If a restore causes a change in

+      reporting behavior from on to off or vice versa this will be reported.

+

+      When the -gd option is selected, the macro "#define zzTRACE_RULES"

+      is added to appropriate output files.

+

+        C++ mode

+        --------

+        int     traceOption(int delta)

+        int     traceGuessOption(int delta)

+        void    traceReset()

+        int     traceOptionValueDefault

+

+        C mode

+        --------

+        int     zzTraceOption(int delta)

+        int     zzTraceGuessOption(int delta)

+        void    zzTraceReset()

+        int     zzTraceOptionValueDefault

+

+      The argument "delta" is added to the traceOptionValue.  To

+      turn on trace when inside a particular rule one:

+

+        rule : <<traceOption(+1);>>

+               (

+                rest-of-rule

+               )

+               <<traceOption(-1);>>

+       ;  /* fail clause */ <<traceOption(-1);>>

+

+      One can use the same idea to turn *off* tracing within a

+      rule by using a delta of (-1).

+

+      An improvement in the rule trace was suggested by Sramji

+      Ramanathan (ps@kumaran.com).

+

+#108. A Note on Deallocation of Variables Allocated in Guess Mode

+

+                            NOTE

+        ------------------------------------------------------

+        This mechanism only works for heap allocated variables

+        ------------------------------------------------------

+

+      The rewrite of the trace provides the machinery necessary

+      to properly free variables or undo actions following a

+      failed guess.

+

+      The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded

+      as part of the zzGUESS macro.  When a guess is opened

+      the value of zzrv is 0.  When a longjmp() is executed to

+      undo the guess, the value of zzrv will be 1.

+

+      The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded

+      as part of the zzGUESS_DONE macro.  This is executed

+      whether the guess succeeds or fails as part of closing

+      the guess.

+

+      The guessSeq is a sequence number which is assigned to each

+      guess and is incremented by 1 for each guess which becomes

+      active.  It is needed by the user to associate the start of

+      a guess with the failure and/or completion (closing) of a

+      guess.

+

+      Guesses are nested.  They must be closed in the reverse

+      of the order that they are opened.

+

+      In order to free memory used by a variable during a guess

+      a user must write a routine which can be called to

+      register the variable along with the current guess sequence

+      number provided by the zzUSER_GUESS_HOOK macro. If the guess

+      fails, all variables tagged with the corresponding guess

+      sequence number should be released.  This is ugly, but

+      it would require a major rewrite of antlr 1.33 to use

+      some mechanism other than setjmp()/longjmp().

+

+      The order of calls for a *successful* guess would be:

+

+        zzUSER_GUESS_HOOK(guessSeq,0);

+        zzUSER_GUESS_DONE_HOOK(guessSeq);

+

+      The order of calls for a *failed* guess would be:

+

+        zzUSER_GUESS_HOOK(guessSeq,0);

+        zzUSER_GUESS_HOOK(guessSeq,1);

+        zzUSER_GUESS_DONE_HOOK(guessSeq);

+

+      The default definitions of these macros are empty strings.

+

+      Here is an example in C++ mode.  The zzUSER_GUESS_HOOK and

+      zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine

+      can be used without change in both C and C++ versions.

+

+      ----------------------------------------------------------------------

+        <<

+

+        #include "AToken.h"

+

+        typedef ANTLRCommonToken ANTLRToken;

+

+        #include "DLGLexer.h"

+

+        int main() {

+

+          {

+            DLGFileInput     in(stdin);

+            DLGLexer         lexer(&in,2000);

+            ANTLRTokenBuffer pipe(&lexer,1);

+            ANTLRCommonToken aToken;

+            P                parser(&pipe);

+

+            lexer.setToken(&aToken);

+            parser.init();

+            parser.start();

+          };

+

+          fclose(stdin);

+          fclose(stdout);

+          return 0;

+        }

+

+        >>

+

+        <<

+        char *s=NULL;

+

+        #undef zzUSER_GUESS_HOOK

+        #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv);

+        #undef zzUSER_GUESS_DONE_HOOK

+        #define zzUSER_GUESS_DONE_HOOK(guessSeq)   myGuessHook(guessSeq,2);

+

+        void myGuessHook(int guessSeq,int zzrv) {

+          if (zzrv == 0) {

+            fprintf(stderr,"User hook: starting guess #%d\n",guessSeq);

+          } else if (zzrv == 1) {

+            free (s);

+            s=NULL;

+            fprintf(stderr,"User hook: failed guess #%d\n",guessSeq);

+          } else if (zzrv == 2) {

+            free (s);

+            s=NULL;

+            fprintf(stderr,"User hook: ending guess #%d\n",guessSeq);

+          };

+        }

+

+        >>

+

+        #token A    "a"

+        #token      "[\t \ \n]"     <<skip();>>

+

+        class P {

+

+        start : (top)+

+              ;

+

+        top   : (which) ?   <<fprintf(stderr,"%s is a which\n",s); free(s); s=NULL; >>

+              | other       <<fprintf(stderr,"%s is an other\n",s); free(s); s=NULL; >>

+              ; <<if (s != NULL) free(s); s=NULL; >>

+

+        which : which2

+              ;

+

+        which2 : which3

+              ;

+        which3

+              : (label)?         <<fprintf(stderr,"%s is a label\n",s);>>

+              | (global)?        <<fprintf(stderr,"%s is a global\n",s);>>

+              | (exclamation)?   <<fprintf(stderr,"%s is an exclamation\n",s);>>

+              ;

+

+        label :       <<s=strdup(LT(1)->getText());>> A ":" ;

+

+        global :      <<s=strdup(LT(1)->getText());>> A "::" ;

+

+        exclamation : <<s=strdup(LT(1)->getText());>> A "!" ;

+

+        other :       <<s=strdup(LT(1)->getText());>> "other" ;

+

+        }

+      ----------------------------------------------------------------------

+

+      This is a silly example, but illustrates the idea.  For the input

+      "a ::" with tracing enabled the output begins:

+

+      ----------------------------------------------------------------------

+        enter rule "start" depth 1

+        enter rule "top" depth 2

+        User hook: starting guess #1

+        enter rule "which" depth 3 guessing

+        enter rule "which2" depth 4 guessing

+        enter rule "which3" depth 5 guessing

+        User hook: starting guess #2

+        enter rule "label" depth 6 guessing

+        guess failed

+        User hook: failed guess #2

+        guess done - returning to rule "which3" at depth 5 (guess mode continues

+                                                 - an enclosing guess is still active)

+        User hook: ending guess #2

+        User hook: starting guess #3

+        enter rule "global" depth 6 guessing

+        exit rule "global" depth 6 guessing

+        guess done - returning to rule "which3" at depth 5 (guess mode continues

+                                                 - an enclosing guess is still active)

+        User hook: ending guess #3

+        enter rule "global" depth 6 guessing

+        exit rule "global" depth 6 guessing

+        exit rule "which3" depth 5 guessing

+        exit rule "which2" depth 4 guessing

+        exit rule "which" depth 3 guessing

+        guess done - returning to rule "top" at depth 2 (guess mode ends)

+        User hook: ending guess #1

+        enter rule "which" depth 3

+        .....

+      ----------------------------------------------------------------------

+

+      Remember:

+

+        (a) Only init-actions are executed during guess mode.

+        (b) A rule can be invoked multiple times during guess mode.

+        (c) If the guess succeeds the rule will be called once more

+              without guess mode so that normal actions will be executed.

+            This means that the init-action might need to distinguish

+              between guess mode and non-guess mode using the variable

+              [zz]guessing.

+

+#101. (Changed in 1.33MR10) antlr -info command line switch

+

+        -info

+

+            p   - extra predicate information in generated file

+

+            t   - information about tnode use:

+                    at the end of each rule in generated file

+                    summary on stderr at end of program

+

+            m   - monitor progress

+                    prints name of each rule as it is started

+                    flushes output at start of each rule

+

+            f   - first/follow set information to stdout

+

+            0   - no operation (added in 1.33MR11)

+

+      The options may be combined and may appear in any order.

+      For example:

+

+        antlr -info ptm -CC -gt -mrhoist on mygrammar.g

+

+#100a. (Changed in 1.33MR10) Predicate tree simplification

+

+      When the same predicates can be referenced in more than one

+      alternative of a block large predicate trees can be formed.

+

+      The difference that these optimizations make is so dramatic

+      that I have decided to use it even when -mrhoist is not selected.

+

+      Consider the following grammar:

+

+        start : ( all )* ;

+

+        all   : a

+              | d

+              | e

+              | f

+              ;

+

+        a     : c A B

+              | c A C

+              ;

+

+        c     : <<AAA(LATEXT(2))>>?

+              ;

+

+        d     : <<BBB(LATEXT(2))>>? B C

+              ;

+

+        e     : <<CCC(LATEXT(2))>>? B C

+              ;

+

+        f     : e X Y

+              ;

+

+      In rule "a" there is a reference to rule "c" in both alternatives.

+      The length of the predicate AAA is k=2 and it can be followed in

+      alternative 1 only by (A B) while in alternative 2 it can be

+      followed only by (A C).  Thus they do not have identical context.

+

+      In rule "all" the alternatives which refer to rules "e" and "f" allow

+      elimination of the duplicate reference to predicate CCC.

+

+      The table below summarized the kind of simplification performed by

+      1.33MR10.  In the table, X and Y stand for single predicates

+      (not trees).

+

+        (OR X (OR Y (OR Z)))  => (OR X Y Z)

+        (AND X (AND Y (AND Z)))  => (AND X Y Z)

+

+        (OR X  (... (OR  X Y) ... ))     => (OR X (... Y ... ))

+        (AND X (... (AND X Y) ... ))     => (AND X (... Y ... ))

+        (OR X  (... (AND X Y) ... ))     => (OR X (...  ... ))

+        (AND X (... (OR  X Y) ... ))     => (AND X (...  ... ))

+

+        (AND X)               => X

+        (OR X)                => X

+

+      In a test with a complex grammar for a real application, a predicate

+      tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)".

+

+      In 1.33MR10 there is a greater effort to release memory used

+      by predicates once they are no longer in use.

+

+#100b. (Changed in 1.33MR10) Suppression of extra predicate tests

+

+      The following optimizations require that -mrhoist be selected.

+

+      It is relatively easy to optimize the code generated for predicate

+      gates when they are of the form:

+

+            (AND X Y Z ...)

+        or  (OR  X Y Z ...)

+

+      where X, Y, Z, and "..." represent individual predicates (leaves) not

+      predicate trees.

+

+      If the predicate is an AND the contexts of the X, Y, Z, etc. are

+      ANDed together to create a single Tree context for the group and

+      context tests for the individual predicates are suppressed:

+

+            --------------------------------------------------

+            Note: This was incorrect.  The contexts should be

+            ORed together.  This has been fixed.  A more 

+            complete description is available in item #152.

+            ---------------------------------------------------

+

+      Optimization 1:  (AND X Y Z ...)

+

+        Suppose the context for Xtest is LA(1)==LP and the context for

+        Ytest is LA(1)==LP && LA(2)==ID.

+

+            Without the optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    !(LA(1)==LP && LA(1)==LP && LA(2)==ID) ||

+                        ( (! LA(1)==LP || Xtest) &&

+                          (! (LA(1)==LP || LA(2)==ID) || Xtest)

+                        )) {...

+

+            With the -mrhoist optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {...

+

+      Optimization 2: (OR X Y Z ...) with identical contexts

+

+        Suppose the context for Xtest is LA(1)==ID and for Ytest

+        the context is also LA(1)==ID.

+

+            Without the optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    ! (LA(1)==ID || LA(1)==ID) ||

+                        (LA(1)==ID && Xtest) ||

+                        (LA(1)==ID && Ytest) {...

+

+            With the -mrhoist optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    (! LA(1)==ID) || (Xtest || Ytest) {...

+

+      Optimization 3: (OR X Y Z ...) with distinct contexts

+

+        Suppose the context for Xtest is LA(1)==ID and for Ytest

+        the context is LA(1)==LP.

+

+            Without the optimization the code would resemble:

+

+                if (lookaheadContext &&

+                    ! (LA(1)==ID || LA(1)==LP) ||

+                        (LA(1)==ID && Xtest) ||

+                        (LA(1)==LP && Ytest) {...

+

+            With the -mrhoist optimization the code would resemble:

+

+                if (lookaheadContext &&

+                        (zzpf=0,

+                            (LA(1)==ID && (zzpf=1) && Xtest) ||

+                            (LA(1)==LP && (zzpf=1) && Ytest) ||

+                            !zzpf) {

+

+            These may appear to be of similar complexity at first,

+            but the non-optimized version contains two tests of each

+            context while the optimized version contains only one

+            such test, as well as eliminating some of the inverted

+            logic (" !(...) || ").

+

+      Optimization 4: Computation of predicate gate trees

+

+        When generating code for the gates of predicate expressions

+        antlr 1.33 vanilla uses a recursive procedure to generate

+        "&&" and "||" expressions for testing the lookahead. As each

+        layer of the predicate tree is exposed a new set of "&&" and

+        "||" expressions on the lookahead are generated.  In many

+        cases the lookahead being tested has already been tested.

+

+        With -mrhoist a lookahead tree is computed for the entire

+        lookahead expression.  This means that predicates with identical

+        context or context which is a subset of another predicate's

+        context disappear.

+

+        This is especially important for predicates formed by rules

+        like the following:

+

+            uppperCaseVowel : <<isUpperCase(LATEXT(1))>>?  vowel;

+            vowel:          : <<isVowel(LATEXT(1))>>? LETTERS;

+

+        These predicates are combined using AND since both must be

+        satisfied for rule upperCaseVowel.  They have identical

+        context which makes this optimization very effective.

+

+      The affect of Items #100a and #100b together can be dramatic.  In

+      a very large (but real world) grammar one particular predicate

+      expression was reduced from an (unreadable) 50 predicate leaves,

+      195 LA(1) terms, and 5500 characters to an (easily comprehensible)

+      3 predicate leaves (all different) and a *single* LA(1) term.

+

+#98.  (Changed in 1.33MR10) Option "-info p"

+

+      When the user selects option "-info p" the program will generate

+      detailed information about predicates.  If the user selects

+      "-mrhoist on" additional detail will be provided explaining

+      the promotion and suppression of predicates.  The output is part

+      of the generated file and sandwiched between #if 0/#endif statements.

+

+      Consider the following k=1 grammar:

+

+        start : ( all ) * ;

+

+        all   : ( a

+                | b

+                )

+                ;

+

+        a     : c B

+              ;

+

+        c     : <<LATEXT(1)>>?

+              | B

+              ;

+

+        b     : <<LATEXT(1)>>? X

+              ;

+

+      Below is an excerpt of the output for rule "start" for the three

+      predicate options (off, on, and maintenance release style hoisting).

+

+      For those who do not wish to use the "-mrhoist on" option for code

+      generation the option can be used in a "diagnostic" mode to provide

+      valuable information:

+

+            a. where one should insert null actions to inhibit hoisting

+            b. a chain of rule references which shows where predicates are

+               being hoisted

+

+      ======================================================================

+      Example of "-info p" with "-mrhoist on"

+      ======================================================================

+        #if 0

+

+        Hoisting of predicate suppressed by alternative without predicate.

+        The alt without the predicate includes all cases where the

+           predicate is false.

+

+           WITH predicate: line 11  v36.g

+           WITHOUT predicate: line 12  v36.g

+

+        The context set for the predicate:

+

+             B

+

+        The lookahead set for alt WITHOUT the semantic predicate:

+

+             B

+

+        The predicate:

+

+          pred <<  LATEXT(1)>>?  depth=k=1  rule c  line 11  v36.g

+

+            set context:

+               B

+            tree context: null

+

+        Chain of referenced rules:

+

+            #0  in rule start (line 1 v36.g) to rule all

+            #1  in rule all (line 3 v36.g) to rule a

+            #2  in rule a (line 8 v36.g) to rule c

+            #3  in rule c (line 11 v36.g)

+

+        #endif

+        &&

+        #if 0

+

+        pred <<  LATEXT(1)>>?  depth=k=1  rule b  line 15  v36.g

+

+          set context:

+             X

+          tree context: null

+

+        #endif

+      ======================================================================

+      Example of "-info p"  with the default -prc setting ( "-prc off")

+      ======================================================================

+        #if 0

+

+        OR

+          pred <<  LATEXT(1)>>?  depth=k=1  rule c  line 11  v36.g

+

+            set context:

+              nil

+            tree context: null

+

+          pred <<  LATEXT(1)>>?  depth=k=1  rule b  line 15  v36.g

+

+            set context:

+              nil

+            tree context: null

+

+        #endif

+      ======================================================================

+      Example of "-info p" with "-prc on" and "-mrhoist off"

+      ======================================================================

+        #if 0

+

+        OR

+          pred <<  LATEXT(1)>>?  depth=k=1  rule c  line 11  v36.g

+

+            set context:

+               B

+            tree context: null

+

+          pred <<  LATEXT(1)>>?  depth=k=1  rule b  line 15  v36.g

+

+            set context:

+               X

+            tree context: null

+

+        #endif

+      ======================================================================

+

+#60.  (Changed in 1.33MR7) Major changes to exception handling

+

+        There were significant problems in the handling of exceptions

+        in 1.33 vanilla.  The general problem is that it can only

+        process one level of exception handler.  For example, a named

+        exception handler, an exception handler for an alternative, or

+        an exception for a subrule  always went to the rule's exception

+        handler if there was no "catch" which matched the exception.

+

+        In 1.33MR7 the exception handlers properly "nest".  If an

+        exception handler does not have a matching "catch" then the

+        nextmost outer exception handler is checked for an appropriate

+        "catch" clause, and so on until an exception handler with an

+        appropriate "catch" is found.

+

+        There are still undesirable features in the way exception

+        handlers are implemented, but I do not have time to fix them

+        at the moment:

+

+            The exception handlers for alternatives are outside the

+            block containing the alternative.  This makes it impossible

+            to access variables declared in a block or to resume the

+            parse by "falling through".  The parse can still be easily

+            resumed in other ways, but not in the most natural fashion.

+

+            This results in an inconsistentcy between named exception

+            handlers and exception handlers for alternatives.  When

+            an exception handler for an alternative "falls through"

+            it goes to the nextmost outer handler - not the "normal

+            action".

+

+        A major difference between 1.33MR7 and 1.33 vanilla is

+        the default action after an exception is caught:

+

+            1.33 Vanilla

+            ------------

+            In 1.33 vanilla the signal value is set to zero ("NoSignal")

+            and the code drops through to the code following the exception.

+            For named exception handlers this is the "normal action".

+            For alternative exception handlers this is the rule's handler.

+

+            1.33MR7

+            -------

+            In 1.33MR7 the signal value is NOT automatically set to zero.

+

+            There are two cases:

+

+                For named exception handlers: if the signal value has been

+                set to zero the code drops through to the "normal action".

+

+                For all other cases the code branches to the nextmost outer

+                exception handler until it reaches the handler for the rule.

+

+        The following macros have been defined for convenience:

+

+            C/C++ Mode Name

+            --------------------

+            (zz)suppressSignal

+                  set signal & return signal arg to 0 ("NoSignal")

+            (zz)setSignal(intValue)

+                  set signal & return signal arg to some value

+            (zz)exportSignal

+                  copy the signal value to the return signal arg

+

+        I'm not sure why PCCTS make a distinction between the local

+        signal value and the return signal argument, but I'm loathe

+        to change the code. The burden of copying the local signal

+        value to the return signal argument can be given to the

+        default signal handler, I suppose.

+

+#53.  (Explanation for 1.33MR6) What happens after an exception is caught ?

+

+        The Book is silent about what happens after an exception

+        is caught.

+

+        The following code fragment prints "Error Action" followed

+        by "Normal Action".

+

+        test : Word ex:Number <<printf("Normal Action\n");>>

+                exception[ex]

+                   catch NoViableAlt:

+                        <<printf("Error Action\n");>>

+        ;

+

+        The reason for "Normal Action" is that the normal flow of the

+        program after a user-written exception handler is to "drop through".

+        In the case of an exception handler for a rule this results in

+        the exection of a "return" statement.  In the case of an

+        exception handler attached to an alternative, rule, or token

+        this is the code that would have executed had there been no

+        exception.

+

+        The user can achieve the desired result by using a "return"

+        statement.

+

+        test : Word ex:Number <<printf("Normal Action\n");>>

+                exception[ex]

+                   catch NoViableAlt:

+                        <<printf("Error Action\n"); return;>>

+        ;

+

+        The most powerful mechanism for recovery from parse errors

+        in pccts is syntactic predicates because they provide

+        backtracking.  Exceptions allow "return", "break",

+        "consumeUntil(...)", "goto _handler", "goto _fail", and

+        changing the _signal value.

+

+#41.  (Added in 1.33MR6) antlr -stdout

+

+        Using "antlr -stdout ..." forces the text that would

+        normally go to the grammar.c or grammar.cpp file to

+        stdout.

+

+#40.  (Added in 1.33MR6) antlr -tab to change tab stops

+

+        Using "antlr -tab number ..." changes the tab stops

+        for the grammar.c or grammar.cpp file.  The number

+        must be between 0 and 8.  Using 0 gives tab characters,

+        values between 1 and 8 give the appropriate number of

+        space characters.

+

+#34.  (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue)

+

+        Previously there was no public function for changing the line

+        number maintained by the lexer.

+

+#28.   (Added to 1.33MR1) More control over DLG header

+

+        Version 1.33MR1 adds the following directives to PCCTS

+        for C++ mode:

+

+          #lexprefix  <<source code>>

+

+                Adds source code to the DLGLexer.h file

+                after the #include "DLexerBase.h" but

+                before the start of the class definition.

+

+          #lexmember  <<source code>>

+

+                Adds source code to the DLGLexer.h file

+                as part of the DLGLexer class body.  It

+                appears immediately after the start of

+                the class and a "public: statement.

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/KNOWN_PROBLEMS.txt b/edk2/Tools/Source/TianoTools/Pccts/KNOWN_PROBLEMS.txt
new file mode 100644
index 0000000..5a9b22e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/KNOWN_PROBLEMS.txt
@@ -0,0 +1,241 @@
+

+    =======================================================

+    Known Problems In PCCTS - Last revised 14 November 1998

+    =======================================================

+

+#17. The dlg fix for handling characters up to 255 is incorrect.

+

+    See item #207.

+

+    Reported by Frank Hartmann.

+        

+#16. A note about "&&" predicates (Mike Dimmick)

+

+    Mike Dimmick has pointed out a potential pitfall in the use of the

+    "&&" style predicate.  Consider:

+    

+         r0: (g)? => <<P>>?  r1

+             | ...

+             ;

+         r1: A | B;

+         

+    If the context guard g is not a subset of the lookahead context for r1

+    (in other words g is neither A nor B) then the code may execute r1 

+    even when the lookahead context is not satisfied.  This is an error

+    by the person coding the grammer, and the error should be reported to

+    the user, but it isn't. expect.  Some examples I've run seem to

+    indicate that such an error actually results in the rule becoming

+    unreachable.

+    

+    When g is properly coded the code is correct, the problem is when g

+    is not properly coded.

+    

+    A second problem reported by Mike Dimmick is that the test for a

+    failed validation predicate is equivalent to a test on the predicate

+    along.  In other words, if the "&&" has not been hoisted then it may

+    falsely report a validation error.

+

+#15. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions

+

+    An bug (or at least an oddity) is that a reference to LT(1), LA(1),

+    or LATEXT(1) in an action which immediately follows a token match

+    in a rule refers to the token matched, not the token which is in

+    the lookahead buffer.  Consider:

+

+        r : abc <<action alpha>> D <<action beta>> E;

+

+    In this case LT(1) in action alpha will refer to the next token in

+    the lookahead buffer ("D"), but LT(1) in action beta will refer to

+    the token matched by D - the preceding token.

+

+    A warning has been added which warns users about this when an action

+    following a token match contains a reference to LT(1), LA(1), or LATEXT(1).

+

+    This behavior should be changed, but it appears in too many programs

+    now.  Another problem, perhaps more significant, is that the obvious

+    fix (moving the consume() call to before the action) could change the 

+    order in which input is requested and output appears in existing programs.

+

+    This problem was reported, along with a fix by Benjamin Mandel

+    (beny@sd.co.il).  However, I felt that changing the behavior was too

+    dangerous for existing code.

+

+#14. Parsing bug in dlg

+

+    THM: I have been unable to reproduce this problem.

+

+    Reported by Rick Howard Mijenix Corporation (rickh@mijenix.com).

+

+    The regular expression parser (in rexpr.c) fails while

+    trying to parse the following regular expression:

+

+            {[a-zA-Z]:}(\\\\[a-zA-Z0-9]*)+

+

+    See my comment in the following excerpt from rexpr.c:

+

+    /*

+     * <regExpr>        ::= <andExpr> ( '|' {<andExpr>} )*

+     *

+     * Return -1 if syntax error

+     * Return  0 if none found

+     * Return  1 if a regExrp was found

+     */

+	static

+	regExpr(g)

+	GraphPtr g;

+	{

+	    Graph g1, g2;

+	

+	    if ( andExpr(&g1) == -1 )

+	    {

+	        return -1;

+	    }

+	

+	    while ( token == '|' )

+	    {

+	        int a;

+	        next();

+	        a = andExpr(&g2);

+	        if ( a == -1 ) return -1;   /* syntax error below */

+	        else if ( !a ) return 1;    /* empty alternative */

+	        g1 = BuildNFA_AorB(g1, g2);

+	    }

+	

+	    if ( token!='\0' ) return -1;

+	*****

+	***** It appears to fail here becuause token is 125 - the closing '}'

+	***** If I change it to:

+	*****    if ( token!='\0' && token!='}' && token!= ')' ) return -1;

+	*****

+	***** It succeeds, but I'm not sure this is the corrrect approach.

+	*****

+	    *g = g1;

+	    return 1;

+	}

+

+#13. dlg reports an invalid range for: [\0x00-\0xff]

+

+    Diagnosed by Piotr Eljasiak (eljasiak@no-spam.zt.gdansk.tpsa.pl):

+

+    Fixed in MR16.

+

+#12. Strings containing comment actions

+

+     Sequences that looked like C style comments appearing in string

+     literals are improperly parsed by antlr/dlg.

+

+        << fprintf(out," /* obsolete */ ");

+

+     For this case use:

+

+        << fprintf(out," \/\* obsolete \*\/ ");

+

+     Reported by K.J. Cummings (cummings@peritus.com).

+

+#11. User hook for deallocation of variables on guess fail

+

+     The mechanism outlined in Item #108 works only for

+     heap allocated variables.

+

+#10. Label re-initialization in ( X {y:Y} )*

+

+     If a label assignment is optional and appears in a

+     (...)* or (...)+ block it will not be reset to NULL

+     when it is skipped by a subsequent iteration.

+

+     Consider the example:

+

+            ( X { y:Y })* Z

+

+     with input:

+

+            X Y X Z

+

+     The first time through the block Y will be matched and

+     y will be set to point to the token.  On the second

+     iteration of the (...)* block there is no match for Y.

+     But y will not be reset to NULL, as the user might

+     expect, it will contain a reference to the Y that was

+     matched in the first iteration.

+

+     The work-around is to manually reset y:

+

+            ( X << y = NULL; >> { y:Y } )* Z

+

+        or

+

+            ( X ( y:Y | << y = NULL; >> /* epsilon */ ) )* Z

+

+     Reported by Jeff Vincent (JVincent@novell.com).

+

+#9. PCCTAST.h PCCTSAST::setType() is a noop

+

+#8. #tokdefs with ~Token and .

+

+    THM: I have been unable to reproduce this problem.

+

+    When antlr uses #tokdefs to define tokens the fields of

+    #errclass and #tokclass do not get properly defined.

+    When it subsequently attempts to take the complement of

+    the set of tokens (using ~Token or .) it can refer to

+    tokens which don't have names, generating a fatal error.

+

+#7. DLG crashes on some invalid inputs

+

+    THM:  In MR20 have fixed the most common cases.

+

+    The following token defintion will cause DLG to crash.

+

+        #token "()"

+

+    Reported by  Mengue Olivier (dolmen@bigfoot.com).

+

+#6. On MS systems \n\r is treated as two new lines

+

+    Fixed.

+

+#5. Token expressions in #tokclass

+

+    #errclass does not support TOK1..TOK2 or ~TOK syntax.

+    #tokclass does not support ~TOKEN syntax

+

+    A workaround for #errclass TOK1..TOK2 is to use a

+    #tokclass.

+

+    Reported by Dave Watola (dwatola@amtsun.jpl.nasa.gov)

+

+#4. A #tokdef must appear "early" in the grammar file.

+

+    The "early" section of the grammar file is the only

+    place where the following directives may appear:

+

+        #header

+        #first

+        #tokdefs

+        #parser

+

+    Any other kind of statement signifiies the end of the

+    "early" section.

+

+#3. Use of PURIFY macro for C++ mode

+

+    Item #93 of the CHANGES_FROM_1.33 describes the use of

+    the PURIFY macro to zero arguments to be passed by

+    upward inheritance.

+

+        #define PURIFY(r, s) memset((char *) &(r), '\0', (s));

+

+    This may not be the right thing to do for C++ objects that

+    have constructors.  Reported by Bonny Rais (bonny@werple.net.au).

+

+    For those cases one should #define PURIFY to be an empty macro

+    in the #header or #first actions.

+

+#2. Fixed in 1.33MR10 - See CHANGES_FROM_1.33 Item #80.

+

+#1. The quality of support for systems with 8.3 file names leaves

+    much to be desired.  Since the kit is distributed using the

+    long file names and the make file uses long file names it requires

+    some effort to generate.  This will probably not be changed due

+    to the large number of systems already written using the long

+    file names.

diff --git a/edk2/Tools/Source/TianoTools/Pccts/MPW_Read_Me b/edk2/Tools/Source/TianoTools/Pccts/MPW_Read_Me
new file mode 100644
index 0000000..70a9d1b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/MPW_Read_Me
@@ -0,0 +1,21 @@
+

+1. You can control the creator type of generated files by changing a value of

+   #if control statement.

+

+

+   pccts:h:pcctscfg.h

+

+   line 225-231

+

+	#if 0

+	#define MAC_FILE_CREATOR 'MPS '   /* MPW Text files */

+	#endif

+	#if 0

+	#define MAC_FILE_CREATOR 'KAHL'   /* THINK C/Symantec C++ Text files */

+	#endif

+	#if 0

+	#define MAC_FILE_CREATOR 'CWIE'   /* Metrowerks C/C++ Text files */

+	#endif

+

+2.  If you want to build 68K version. You must convert all source files to Macintosh

+    format before compile.

diff --git a/edk2/Tools/Source/TianoTools/Pccts/NOTES.bcc b/edk2/Tools/Source/TianoTools/Pccts/NOTES.bcc
new file mode 100644
index 0000000..1ac05b1
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/NOTES.bcc
@@ -0,0 +1,184 @@
+March 95

+Version 1.32 of pccts

+ 

+At the moment this file is available via anonymous FTP at

+ 

+        Node: marvin.ecn.purdue.edu

+        File: pub/pccts/1.32/NOTES.BCC

+ 

+Mail corrections or additions to David Seidel <71333.1575@compuserve.com>

+===============================================================================

+Notes on Building PCCTS 1.32 with Borland C++

+ 

+David Seidel, Innovative Data Concepts Incorporated

+CompuServe: 71333,1575

+Internet:   71333.1575@compuserve.com

+            dseidel@delphi.com

+ 

+I have gotten ANTLR and DLG to succesfully build with BCC 4.0, but have found

+from experience that ANTLR, in particular, is likely to run out of memory

+with grammars over a certain size, or with larger values for the -k and -ck

+options.  Now that BCC 4.02 and the new Borland Power Pack for DOS is now

+available, I feel that there is no excuse not to build these tools as

+32-bit executables, as they ought to be.

+ 

+For people without the Power Pack, the makefiles below should be fairly easily

+modified to build 16-bit real-mode executables, but I don't really recommend

+it.  As an alternative, you might consider the highly regarded DJGPP compiler

+(a DOS port of the Gnu GCC compiler, with a DOS extender included).  Hopefully

+some other PCCTS who has DJGPP can provode whatever advice is necessary.  The

+Watcom compiler is also an excellent possibility (albeit a commercial one),

+and I hope to make available Watcom makefiles in the near future.

+ 

+Here are the makefiles I am using.  Both makefiles use a compiler configuration

+file that contains compiler switches such as optimization settings.  I call

+this file bor32.cfg and keep a copy in both the ANTLR and DLG subdirectories.

+ 

+==== File: bor32.cfg (cut here) ===============================================

+-w-

+-RT-

+-x-

+-N-

+-k-

+-d

+-O2-e-l

+-Z

+-D__STDC__=1

+==== End of file bor32.cfg (cut here) =========================================

+ 

+==== File: antlr\bor32.mak (cut here) =========================================

+#

+#  ANTLR 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by

+#  David Seidel

+#  Innovative Data Concepts Incorporated

+#  71333.1575@compuserve.com (or) dseidel@delphi.com

+#

+#  Notes:   1. Compiler switches (optimization etc.) are contained in the

+#              file bor32.cfg.

+#           2. This makefile requires Borland C++ 4.02 or greater with

+#              the DOS Power Pack add-on package.

+#           3. Change the BCCDIR macro below to the topmost directory in

+#              which BCC is installed on your system.

+#

+ 

+BCCDIR   =  d:\bc4

+CC       =  bcc32

+SET      =  ..\support\set

+PCCTS_H  =  ..\h

+ANTLR    =  ..\bin\antlr

+DLG      =  ..\bin\dlg

+CFLAGS   =  -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \

+ +bor32.cfg

+LIBS     =  dpmi32 cw32

+OBJ_EXT  =  obj

+OBJS     =  antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj fset.obj \

+ gen.obj globals.obj hash.obj lex.obj main.obj misc.obj pred.obj dialog.obj \

+ set.obj

+ 

+.c.obj:

+      $(CC) -c $(CFLAGS) {$&.c }

+ 

+antlr.exe: $(OBJS)

+   tlink32 @&&|

+-Tpe -ax -c -s -L$(BCCDIR)\lib +

+$(BCCDIR)\lib\c0x32 $**

+$@

+ 

+$(LIBS)

+;

+|

+   copy *.exe ..\bin

+ 

+ 

+# *********** Target list of PC machines ***********

+#

+# Don't worry about the ambiguity messages coming from antlr

+# for making antlr.c etc...  [should be 10 of them, I think]

+#

+ 

+# leave this commented out for initial build!

+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g

+#   $(ANTLR) antlr.g

+ 

+antlr.$(OBJ_EXT): antlr.c mode.h tokens.h

+ 

+scan.$(OBJ_EXT): scan.c mode.h tokens.h

+ 

+# leave this commented out for initial build!

+#scan.c mode.h: parser.dlg

+#   $(DLG) -C2 parser.dlg scan.c

+ 

+set.$(OBJ_EXT): $(SET)\set.c

+   $(CC) -c $(CFLAGS) $(SET)\set.c

+ 

+==== End of file antlr\bor32.mak (cut here) ===================================

+ 

+==== File: dlg\bor32.mak (cut here) ===========================================

+#

+#  DLG 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by

+#  David Seidel

+#  Innovative Data Concepts Incorporated

+#  71333.1575@compuserve.com (or) dseidel@delphi.com

+#

+#  Notes:   1. Compiler switches (optimization etc.) are contained in the

+#              file bor32.cfg.

+#           2. This makefile requires Borland C++ 4.02 or greater with

+#              the DOS Power Pack add-on package.

+#           3. Change the BCCDIR macro below to the topmost directory in

+#              which BCC is installed on your system.

+#

+ 

+ 

+BCCDIR   =  d:\bc4

+CC       =  bcc32

+SET      =  ..\support\set

+PCCTS_H  =  ..\h

+ANTLR    =  ..\bin\antlr

+DLG      =  ..\bin\dlg

+CFLAGS   =  -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \

+ +bor32.cfg

+LIBS     =  dpmi32 cw32

+OBJ_EXT  =  obj

+OBJS     =  dlg_p.obj dlg_a.obj main.obj err.obj support.obj \

+ output.obj relabel.obj automata.obj set.obj

+ 

+.c.obj:

+      $(CC) -c $(CFLAGS) {$&.c }

+ 

+dlg.exe : $(OBJS)

+   tlink32 @&&|

+-Tpe -ax -c -s -L$(BCCDIR)\lib +

+c0x32 $**

+$@

+ 

+$(LIBS)

+;

+|

+   copy *.exe ..\bin

+ 

+dlg_p.obj:  dlg_p.c

+ 

+dlg_a.obj:  dlg_a.c

+ 

+main.obj:   main.c

+ 

+err.obj:    err.c

+ 

+support.obj:   support.c

+ 

+output.obj: output.c

+ 

+relabel.obj:   relabel.c

+ 

+automata.obj:  automata.c

+ 

+set.$(OBJ_EXT): $(SET)\set.c

+   $(CC) -c $(CFLAGS) $(SET)\set.c

+ 

+==== End of file dlg\bor32.mak (cut here) =====================================

+ 

+ 

+ 

+

+

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/NOTES.msvc b/edk2/Tools/Source/TianoTools/Pccts/NOTES.msvc
new file mode 100644
index 0000000..86f8ed6
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/NOTES.msvc
@@ -0,0 +1,189 @@
+

+                        Microsoft Visual C Stuff

+

+

+[Tom Moog 2-Oct-98

+

+    Users of Microsoft Visual C++ should download a separate

+    ready-to-run zip file from my web site.  It contains 

+    binaries, static library, and a sample project.

+]

+

+[

+  Two notes added by Tom Moog 23-Sep-97.  I believe the *.dsp and

+  *.mak files that were once at the end of this file are now obsolete.

+  

+  The following MSVC .dsp and .mak files for pccts and sorcerer

+  were contributed by Stanislaw Bochnak (S.Bochnak@microtool.com.pl)

+  and Jeff Vincent (jvincent@novell.com)

+

+        PCCTS Distribution Kit

+        ----------------------

+        pccts/antlr/AntlrMSVC50.dsp

+        pccts/antlr/AntlrMSVC50.mak

+

+        pccts/dlg/DlgMSVC50.dsp

+        pccts/dlg/DlgMSVC50.mak

+

+        pccts/support/genmk/watgenmk.mak

+        pccts/support/msvc.dsp

+

+        Sorcerer Distribution Kit

+        -------------------------

+        pccts/sorcerer/SorcererMSVC50.dsp

+        pccts/sorcerer/SorcererMSVC50.mak

+

+        pccts/sorcerer/lib/msvc.dsp

+

+  I do not have an MS based computer.  If you discover problems

+  please report them so as to save trouble for others in the future.

+]

+

+[

+ Modified by Terence Parr (September 1995) to change .C to .cpp

+]

+

+[

+ This file contains notes on MSVC for Windows NT console execs by Dave

+ Seidel and an explanation of flags etc.. by John Hall; good luck,

+ Terence

+]

+

+===============================================================================

+Date: Sat, 31 Dec 1994 11:40:36 -0500 (EST)

+From: David Seidel <75342.2034@compuserve.com>

+

+I've succesfully build 1.31b3 with djgpp for DOS and MSVC 2.0 for Windows 

+NT.  The only (minor) problem I had was that GNU make (version 3.71, in the 

+djgpp port) complained about "multiple targets" in both the antlr and dlg 

+makefiles.  I got around the error by, in each makefile, commenting out the 

+$(SRC) dependency, for example:

+

+   antlr: $(OBJ) #$(SRC)

+

+I don't know why this is happenning, since you haven't changed that part of 

+the makefile at all, and I think this used to work ok...

+

+Here are the makefiles I built from within the MSVC 2.0 environment for antlr 

+and dlg and Windows NT console executables.  Please feel free to pass them 

+on.  Of course, as soon as 1.31 "goes gold", I will send you nice new 

+binaries.  I'm not going to bother to keep doing both Borland and djgpp for 

+DOS however.  Instead, I'll just keep the djgpp version up to date and also 

+provide WinNT binaries.

+

+Dave

+===============================================================================

+

+         How to port PCCTS 1.10 (and 1.32 hopefully) to Visual C++

+

+                                   By

+

+                       John Hall <jhall@ivy.wpi.edu>

+

+Here is how to compile an ANTLR grammar in Visual C++.  These steps

+describe how to have your ANTLR grammar parse the input file the user

+selects when they choose File Open in your Windows application.  (Even

+if you aren't using Visual C++, the steps should be portable enough to

+other compilers.)

+

+ * Make sure that ANTLR and DLG generate ANSI code (use the -ga

+   switch).

+

+ * Set the following compiler flags in Visual C++ (these are in the

+   Memory Model category of the compiler options in the Project

+   Options menu):

+

+   FLAG MEANING

+   ==== ==============================================================

+   /AL  Large memory model (multiple data segments; data items must be

+    smaller than 64K).

+

+   /Gtn Allocates all items whose size is greater than or equal to n

+    in a new data segment.  (I let n be 256: /Gt256.)

+

+   /Gx- All references to data items are done with far addressing in

+    case they are placed in a far segment.

+

+ * Add the following member variable to the attributes section of your

+   derived CDocument class (you will need to make sure you also

+   include stdio.h):

+

+   FILE *fp;

+

+ * Add the following method to your derived CDocument class:

+

+   BOOL CAppDoc::OnOpenDocument(const char* pszPathName)

+   {

+       // Call CDocument's OnOpenDocument to do housekeeping for us

+       // DON'T add anything to the loading section of Serialize

+       if (!CDocument::OnOpenDocument(pszPathName))

+           return FALSE;

+   

+       // Open input file

+       if ((fp = fopen(pszPathName, "r")) == NULL)

+           return FALSE;

+   

+       // Parse input file

+       ANTLR(start(), fp);

+   

+       // Close input file

+       fclose(fp);

+       return TRUE;

+   }

+

+   (Note: additional code may be necessary, depending on your parser.

+   For example, if your parser uses PCCTS's symbol table library, you

+   will need to insert calls to zzs_init and zzs_done.)

+

+ * Compile the generated C files as C++ files.  (I renamed the files

+   to have a .CPP extension to fool Visual C++ into thinking they were

+   C++ files.  One might also use the /Tp switch, but that switch

+   requires you separately include the filename.)  [I used this step

+   as an easy out for all the external linking errors I was getting

+   that I couldn't fix by declaring things extern "C".]

+

+ * Make sure the __STDC__ portion of the generated files gets

+   compiled.  (Either define __STDC__ yourself or else change all

+   occurrences of __STDC__ to __cplusplus in the generated files.  You

+   can define __STDC__ in the Preprocessor category of the compiler

+   options.)

+

+        ================================================================

+        = Note 23-Sep-97: This is probably not necessary any more.     =

+        = With 1.33MRxxx the use of __STDC__ was replaced with the     =

+        = macro __USE_PROTOS to control the compilation of prototypes. =

+        ================================================================

+                        

+That last step is important for Visual C++, but may not apply to other

+compilers.  For C++ compilers, whether __STDC__ is defined is

+implementation dependent (ARM, page 379).  Apparently, Visual C++ does

+not to define it; it also does not support "old style" C function

+definitions (which is okay, according to page 404 of the ARM).  Those

+two things together caused problems when trying to port the code.

+When it saw this:

+

+#ifdef __STDC__

+void

+globals(AST **_root)

+#else

+globals(_root)

+AST **_root;

+#endif

+

+it skipped the __STDC__ section and tried to process the "old style"

+function definition, where it choked.

+

+When you finally get your parser to compile and link without error,

+you may get General Protection Fault errors at run time.  The problem

+I had was that a NULL was passed to a variable argument function

+without an explicit cast.  The function grabbed a pointer (32-bits)

+off the stack using va_arg, but the NULL was passed silently as the

+integer 0 (16 bits), making the resulting pointer was invalid.  (This

+was in PCCTS's sample C parser.)

+

+There is one other thing I might suggest to help you avoid a run-time

+error.  Make sure you redefine the default error reporting function,

+zzsyn.  To do this, put "#define USER_ZZSYN" in your #header section

+and put your own zzsyn somewhere.  You can then pop up a MessageBox or

+print the error to some output window.

+===============================================================================

diff --git a/edk2/Tools/Source/TianoTools/Pccts/README b/edk2/Tools/Source/TianoTools/Pccts/README
new file mode 100644
index 0000000..d089b63
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/README
@@ -0,0 +1,159 @@
+

+                          Parr Research Corporation

+                                    with

+                  Purdue University Electrical Engineering

+                                    and

+                       University of Minnesota, AHPCRC

+

+                                Terence Parr

+                                Russell Quong

+                                 Will Cohen

+                                 Hank Dietz

+

+

+A central place for information about PCCTS 1.33 is:

+

+        http://www.polhode.com/pccts.html

+

+The maintenance release is available from:

+

+        http://www.polhode.com/pccts133mr.zip

+

+There is a ready-to-run version for win32 for Microsoft Visual Studio

+at the same site.  It is available from:

+

+        http://www.polhode.com/win32.zip

+

+New users should visit http://www.polhode.com/pccts.html in

+order to get the following document:

+

+        "Notes For New Users of PCCTS"

+

+This is a Postscript file of about 40 pages which is extremely 

+useful for someone starting out. It is a based on 1.33mr21

+

+When you have a little more experience, be sure to review the

+following documents in the distribution kit:

+

+            CHANGES_FROM_133.txt

+            CHANGES_FROM_133_BEFORE_MR13.txt

+            KNOWN_PROBLEMS.txt

+

+-------------------------------------------------------------------------

+                      INSTALLATION (Unix)

+-------------------------------------------------------------------------

+0. Download http://www.polhode.com/pccts133mr.zip

+

+1. Unzip the distribution kit to your preferred location.  

+   If there are newline problems try using zip -a ...

+

+2. cd to the main pccts directory.

+

+3. make

+

+   This will create:

+

+        antlr

+        dlg

+        sorcerer

+        genmk

+

+4. Copy to /usr/local/bin or /usr/local/bin if you like.  If you

+   don't wish to then add pccts/bin to your path.

+

+5. To get an up-to-date list of program options execute the

+   program with no command line options.  To get up-to-date

+   documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt

+   at:

+

+           http://www.polhode.com/pccts.html

+

+6. You need not create a library.  The makefile created by genmk

+   assumes that the files are not part of a library. 

+

+   If you wish to create a library from elements of pccts/h:

+

+   If the first letter of the filename is lowercase (uppercase) it is

+   related to the code generated using the pccts C mode (C++ mode).

+   Some of the .c and .cpp files in the h directory are not meant to

+   be placed in a library and will not compile because they are meant

+   to be #include in pccts generated files which are grammar specific.

+

+   For C++ users place the following elements in the library:

+

+        AParser.cpp

+        ASTBase.cpp

+        ATokenBuffer.cpp

+        BufFileInput.cpp (optional)

+        DLexerBase.cpp

+        PCCTSAST.cpp

+        SList.cpp

+

+-------------------------------------------------------------------------

+                    INSTALLATION (Win32)

+-------------------------------------------------------------------------

+

+I've tried to keep the win32 kit to the minimum necessary to get 

+up and running.  The complete kit contains additional information

+(some historical), source code, and DevStudio projects for 

+rebuilding pccts from the source code.

+

+The kit is now distributed with both MSVC 5 and MSVC6 style projects.

+

+0. Download http://www.polhode.com/win32.zip.

+

+   You may also wish to download:

+

+        http://www.polhode.com/CHANGES_FROM_133.txt

+        http://www.polhode.com/CHANGES_FROM_133_BEFORE_MR13.txt

+        http://www.polhode.com/KNOWN_PROBLEMS.txt

+

+1. Unzip the distribution kit to your preferred location.

+

+   This will create:

+

+         a pccts directory tree

+            pccts/bin/*.exe

+            pccts/lib/*.lib

+            pccts/h/*

+            sorcerer/lib/*

+            sorcerer/h/*

+

+         an example directory tree

+            pccts\example\calcAST\*

+            pccts\example\simple\*

+

+2. Define the environment variable PCCTS to point to the main

+   pccts directory.

+

+3. Try building the simple project: pccts\example\simple\simple50.dsw

+   or simple60.dsw.

+

+4. Try building the complex project: pccts\example\calcAST\calcAST50.dsw

+   or calcAST60.dsw.

+

+-------------------------------------------------------------------------

+                      INSTALLATION (DEC/VMS)

+-------------------------------------------------------------------------

+

+DEC/VMS support added by Piéronne Jean-François (jfp@altavista.net)

+

+0. Download http://www.polhode.com/pccts133mr.zip

+

+1. Unzip the distribution kit to your preferred location.

+

+2. set default to the main pccts directory.

+

+3. @makefile.vms

+

+   This will create in directory [.bin]:

+

+        antlr.exe

+        dlg.exe

+        sorcerer.exe

+        genmk.exe

+

+5. To get an up-to-date list of program options execute the

+   program with no command line options.  To get up-to-date

+   documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt

+   at http://www.polhode.com/pccts.html.

diff --git a/edk2/Tools/Source/TianoTools/Pccts/RIGHTS b/edk2/Tools/Source/TianoTools/Pccts/RIGHTS
new file mode 100644
index 0000000..9db175f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/RIGHTS
@@ -0,0 +1,26 @@
+

+SOFTWARE RIGHTS

+

+We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+company may do whatever they wish with source code distributed with

+PCCTS or the code generated by PCCTS, including the incorporation of

+PCCTS, or its output, into commerical software.

+

+We encourage users to develop software with PCCTS.  However, we do ask

+that credit is given to us for developing PCCTS.  By "credit", we mean

+that if you incorporate our source code into one of your programs

+(commercial product, research project, or otherwise) that you

+acknowledge this fact somewhere in the documentation, research report,

+etc...  If you like PCCTS and have developed a nice tool with the

+output, please mention that you developed it using PCCTS.  In

+addition, we ask that this header remain intact in our source code.

+As long as these guidelines are kept, we expect to continue enhancing

+this system and expect to make other tools available as they are

+completed.

+

+ANTLR 1.33

+Terence Parr

+Parr Research Corporation

+with Purdue University and AHPCRC, University of Minnesota

+1989-1995

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/AntlrMS.mak b/edk2/Tools/Source/TianoTools/Pccts/antlr/AntlrMS.mak
new file mode 100644
index 0000000..7c14993
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/AntlrMS.mak
@@ -0,0 +1,233 @@
+# PCCTS directory

+

+# You will need to set the LIB variable similar to this.

+# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib"

+

+# PCCTS_HOME=<your PCCTS_HOME>

+PCCTS_HOME=$(WORKSPACE)\Tools\Source\TianoTools\Pccts

+ANTLR_SRC=$(PCCTS_HOME)\antlr

+PCCTS_H=$(PCCTS_HOME)\h

+

+

+# Support directories

+SET=$(PCCTS_HOME)\support\set

+

+

+# Compiler stuff

+CC = cl

+CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \

+        -D "ZZLEXBUFSIZE=65536"  /D "LONGFILENAMES" /Zi /W3 -D__USE_PROTOS /wd4700

+

+ANTLR_OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \

+            fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \

+            misc.obj pred.obj egman.obj mrhoist.obj fcache.obj

+

+SUPPORT_OBJS = set.obj

+

+# Dependencies

+

+$(WORKSPACE)\Tools\bin\antlr.exe: $(ANTLR_OBJS) $(SUPPORT_OBJS)

+    $(CC) $(CFLAGS) -o antlr.exe $(ANTLR_OBJS) $(SUPPORT_OBJS)

+    del *.obj

+		move antlr.exe $(WORKSPACE)\Tools\bin

+

+

+antlr.obj: $(ANTLR_SRC)\antlr.c \

+	                $(PCCTS_H)\antlr.h \

+                	$(PCCTS_H)\config.h \

+	                $(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\mode.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+					$(ANTLR_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\antlr.c

+

+scan.obj: $(ANTLR_SRC)\scan.c \

+	                $(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgauto.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\mode.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+					$(ANTLR_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\scan.c

+

+err.obj: $(ANTLR_SRC)\err.c \

+					$(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(PCCTS_H)\err.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+					$(ANTLR_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\err.c

+

+bits.obj: $(ANTLR_SRC)\bits.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\bits.c

+

+build.obj: $(ANTLR_SRC)\build.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\build.c

+

+fset2.obj: $(ANTLR_SRC)\fset2.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset2.c

+

+fset.obj: $(ANTLR_SRC)\fset.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset.c

+

+gen.obj: $(ANTLR_SRC)\gen.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\gen.c

+

+globals.obj: $(ANTLR_SRC)\globals.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\globals.c

+

+hash.obj: $(ANTLR_SRC)\hash.c \

+					$(PCCTS_H)\config.h \

+					$(ANTLR_SRC)\hash.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\hash.c

+

+lex.obj: $(ANTLR_SRC)\lex.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\lex.c

+

+main.obj: $(ANTLR_SRC)\main.c \

+					$(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\mode.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\stdpccts.h \

+					$(ANTLR_SRC)\syn.h \

+					$(ANTLR_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\main.c

+

+misc.obj: $(ANTLR_SRC)\misc.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\misc.c

+

+pred.obj: $(ANTLR_SRC)\pred.c \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\pred.c

+

+egman.obj: $(ANTLR_SRC)\egman.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\egman.c

+

+mrhoist.obj: $(ANTLR_SRC)\mrhoist.c \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\mrhoist.c

+

+fcache.obj: $(ANTLR_SRC)\fcache.c \

+					$(ANTLR_SRC)\generic.h \

+					$(ANTLR_SRC)\hash.h \

+					$(ANTLR_SRC)\proto.h \

+					$(ANTLR_SRC)\syn.h \

+

+    $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fcache.c

+

+set.obj: $(SET)\set.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+

+    $(CC) -c $(CFLAGS) $(SET)\set.c

+

+clean:	

+    del *.obj

+

+distclean:

+    del *.obj

+    del $(WORKSPACE)\Tools\bin\antlr.exe

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/AntlrPPC.mak b/edk2/Tools/Source/TianoTools/Pccts/antlr/AntlrPPC.mak
new file mode 100644
index 0000000..9ede60d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/AntlrPPC.mak
@@ -0,0 +1,101 @@
+#   Target:     antlrPPC

+#   Sources:    ::support:set:set.c

+#               antlr.c

+#               bits.c

+#               build.c

+#               egman.c

+#               err.c

+#               fcache.c

+#               fset2.c

+#               fset.c

+#               gen.c

+#               globals.c

+#               hash.c

+#               lex.c

+#               main.c

+#               misc.c

+#               mrhoist.c

+#               pred.c

+#               scan.c

+#   Created:    Sunday, May 17, 1998 10:24:53 PM

+#	Author:		Kenji Tanaka

+MAKEFILE     = antlrPPC.make

+¥MondoBuild¥ = {MAKEFILE}  # Make blank to avoid rebuilds when makefile is modified

+Includes     = ¶

+		-i "::h:" ¶

+		-i "::support:set:"

+Sym¥PPC      = 

+ObjDir¥PPC   = :Obj:

+PPCCOptions  = {Includes} {Sym¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN

+Objects¥PPC  = ¶

+		"{ObjDir¥PPC}set.c.x" ¶

+		"{ObjDir¥PPC}antlr.c.x" ¶

+		"{ObjDir¥PPC}bits.c.x" ¶

+		"{ObjDir¥PPC}build.c.x" ¶

+		"{ObjDir¥PPC}egman.c.x" ¶

+		"{ObjDir¥PPC}err.c.x" ¶

+		"{ObjDir¥PPC}fcache.c.x" ¶

+		"{ObjDir¥PPC}fset2.c.x" ¶

+		"{ObjDir¥PPC}fset.c.x" ¶

+		"{ObjDir¥PPC}gen.c.x" ¶

+		"{ObjDir¥PPC}globals.c.x" ¶

+		"{ObjDir¥PPC}hash.c.x" ¶

+		"{ObjDir¥PPC}lex.c.x" ¶

+		"{ObjDir¥PPC}main.c.x" ¶

+		"{ObjDir¥PPC}misc.c.x" ¶

+		"{ObjDir¥PPC}mrhoist.c.x" ¶

+		"{ObjDir¥PPC}pred.c.x" ¶

+		"{ObjDir¥PPC}scan.c.x"

+antlrPPC ÄÄ {¥MondoBuild¥} {Objects¥PPC}

+	PPCLink ¶

+		-o {Targ} {Sym¥PPC} ¶

+		{Objects¥PPC} ¶

+		-t 'MPST' ¶

+		-c 'MPS ' ¶

+		"{SharedLibraries}InterfaceLib" ¶

+		"{SharedLibraries}StdCLib" ¶

+		#"{SharedLibraries}MathLib" ¶

+		"{PPCLibraries}StdCRuntime.o" ¶

+		"{PPCLibraries}PPCCRuntime.o" ¶

+		"{PPCLibraries}PPCToolLibs.o"

+"{ObjDir¥PPC}set.c.x" Ä {¥MondoBuild¥} "::support:set:set.c"

+	{PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}antlr.c.x" Ä {¥MondoBuild¥} antlr.c

+	{PPCC} antlr.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}bits.c.x" Ä {¥MondoBuild¥} bits.c

+	{PPCC} bits.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}build.c.x" Ä {¥MondoBuild¥} build.c

+	{PPCC} build.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}egman.c.x" Ä {¥MondoBuild¥} egman.c

+	{PPCC} egman.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}err.c.x" Ä {¥MondoBuild¥} err.c

+	{PPCC} err.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}fcache.c.x" Ä {¥MondoBuild¥} fcache.c

+	{PPCC} fcache.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}fset2.c.x" Ä {¥MondoBuild¥} fset2.c

+	{PPCC} fset2.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}fset.c.x" Ä {¥MondoBuild¥} fset.c

+	{PPCC} fset.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}gen.c.x" Ä {¥MondoBuild¥} gen.c

+	{PPCC} gen.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}globals.c.x" Ä {¥MondoBuild¥} globals.c

+	{PPCC} globals.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}hash.c.x" Ä {¥MondoBuild¥} hash.c

+	{PPCC} hash.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}lex.c.x" Ä {¥MondoBuild¥} lex.c

+	{PPCC} lex.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}main.c.x" Ä {¥MondoBuild¥} main.c

+	{PPCC} main.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}misc.c.x" Ä {¥MondoBuild¥} misc.c

+	{PPCC} misc.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}mrhoist.c.x" Ä {¥MondoBuild¥} mrhoist.c

+	{PPCC} mrhoist.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}pred.c.x" Ä {¥MondoBuild¥} pred.c

+	{PPCC} pred.c -o {Targ} {PPCCOptions}

+"{ObjDir¥PPC}scan.c.x" Ä {¥MondoBuild¥} scan.c

+	{PPCC} scan.c -o {Targ} {PPCCOptions}

+

+antlrPPC ÄÄ antlr.r

+	Rez antlr.r -o antlrPPC -a

+Install  Ä antlrPPC

+	Duplicate -y antlrPPC "{MPW}"Tools:antlr

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/README b/edk2/Tools/Source/TianoTools/Pccts/antlr/README
new file mode 100644
index 0000000..d7fc959
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/README
@@ -0,0 +1,19 @@
+                            ANTLR 1.33

+

+This directory contains the files necessary to build ANTLR.

+

+If you do a "make scrub", ANTLR will have to run on antlr.g and DLG

+will have to run on parser.dlg.  Either

+

+(1)     ANTLR uses the previous antlr in that directory to rebuild itself

+(2)     Needs to find antlr on the search path

+

+You will find that running "antlr -gh antlr.g" will result in about

+10 ambiguity warnings.  These are normal.  Don't worry.

+

+If you do a "make clean" right after installation, ANTLR and DLG should

+not need to run; only the C files will compile.

+

+Don't forget to go into the makefile to uncomment the appropriate

+definitions for your OS/architecture/compiler or see the appropriate

+NOTES.?? file.

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.1 b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.1
new file mode 100644
index 0000000..acfa85b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.1
@@ -0,0 +1,209 @@
+.TH ANTLR 1 "September 1995" "ANTLR" "PCCTS Manual Pages"

+.SH NAME

+antlr \- ANother Tool for Language Recognition

+.SH SYNTAX

+.LP

+\fBantlr\fR [\fIoptions\fR] \fIgrammar_files\fR

+.SH DESCRIPTION

+.PP

+\fIAntlr\fP converts an extended form of context-free grammar into a

+set of C functions which directly implement an efficient form of

+deterministic recursive-descent LL(k) parser.  Context-free grammars

+may be augmented with predicates to allow semantics to influence

+parsing; this allows a form of context-sensitive parsing.  Selective

+backtracking is also available to handle non-LL(k) and even

+non-LALR(k) constructs.  \fIAntlr\fP also produces a definition of a

+lexer which can be automatically converted into C code for a DFA-based

+lexer by \fIdlg\fR.  Hence, \fIantlr\fR serves a function much like

+that of \fIyacc\fR, however, it is notably more flexible and is more

+integrated with a lexer generator (\fIantlr\fR directly generates

+\fIdlg\fR code, whereas \fIyacc\fR and \fIlex\fR are given independent

+descriptions).  Unlike \fIyacc\fR which accepts LALR(1) grammars,

+\fIantlr\fR accepts LL(k) grammars in an extended BNF notation \(em

+which eliminates the need for precedence rules.

+.PP

+Like \fIyacc\fR grammars, \fIantlr\fR grammars can use

+automatically-maintained symbol attribute values referenced as dollar

+variables.  Further, because \fIantlr\fR generates top-down parsers,

+arbitrary values may be inherited from parent rules (passed like

+function parameters).  \fIAntlr\fP also has a mechanism for creating

+and manipulating abstract-syntax-trees.

+.PP

+There are various other niceties in \fIantlr\fR, including the ability to

+spread one grammar over multiple files or even multiple grammars in a single

+file, the ability to generate a version of the grammar with actions stripped

+out (for documentation purposes), and lots more.

+.SH OPTIONS

+.IP "\fB-ck \fIn\fR"

+Use up to \fIn\fR symbols of lookahead when using compressed (linear

+approximation) lookahead.  This type of lookahead is very cheap to

+compute and is attempted before full LL(k) lookahead, which is of

+exponential complexity in the worst case.  In general, the compressed

+lookahead can be much deeper (e.g, \f(CW-ck 10\fP) than the full

+lookahead (which usually must be less than 4).

+.IP \fB-CC\fP

+Generate C++ output from both ANTLR and DLG.

+.IP \fB-cr\fP

+Generate a cross-reference for all rules.  For each rule, print a list

+of all other rules that reference it.

+.IP \fB-e1\fP

+Ambiguities/errors shown in low detail (default).

+.IP \fB-e2\fP

+Ambiguities/errors shown in more detail.

+.IP \fB-e3\fP

+Ambiguities/errors shown in excruciating detail.

+.IP "\fB-fe\fP file"

+Rename \fBerr.c\fP to file.

+.IP "\fB-fh\fP file"

+Rename \fBstdpccts.h\fP header (turns on \fB-gh\fP) to file.

+.IP "\fB-fl\fP file"

+Rename lexical output, \fBparser.dlg\fP, to file.

+.IP "\fB-fm\fP file"

+Rename file with lexical mode definitions, \fBmode.h\fP, to file.

+.IP "\fB-fr\fP file"

+Rename file which remaps globally visible symbols, \fBremap.h\fP, to file.

+.IP "\fB-ft\fP file"

+Rename \fBtokens.h\fP to file.

+.IP \fB-ga\fP

+Generate ANSI-compatible code (default case).  This has not been

+rigorously tested to be ANSI XJ11 C compliant, but it is close.  The

+normal output of \fIantlr\fP is currently compilable under both K&R,

+ANSI C, and C++\(emthis option does nothing because \fIantlr\fP

+generates a bunch of #ifdef's to do the right thing depending on the

+language.

+.IP \fB-gc\fP

+Indicates that \fIantlr\fP should generate no C code, i.e., only

+perform analysis on the grammar.

+.IP \fB-gd\fP

+C code is inserted in each of the \fIantlr\fR generated parsing functions to

+provide for user-defined handling of a detailed parse trace.  The inserted

+code consists of calls to the user-supplied macros or functions called

+\fBzzTRACEIN\fR and \fBzzTRACEOUT\fP.  The only argument is a

+\fIchar *\fR pointing to a C-style string which is the grammar rule

+recognized by the current parsing function.  If no definition is given

+for the trace functions, upon rule entry and exit, a message will be

+printed indicating that a particular rule as been entered or exited.

+.IP \fB-ge\fP

+Generate an error class for each non-terminal.

+.IP \fB-gh\fP

+Generate \fBstdpccts.h\fP for non-ANTLR-generated files to include.

+This file contains all defines needed to describe the type of parser

+generated by \fIantlr\fP (e.g. how much lookahead is used and whether

+or not trees are constructed) and contains the \fBheader\fP action

+specified by the user.

+.IP \fB-gk\fP

+Generate parsers that delay lookahead fetches until needed.  Without

+this option, \fIantlr\fP generates parsers which always have \fIk\fP

+tokens of lookahead available.

+.IP \fB-gl\fP

+Generate line info about grammar actions in C parser of the form

+\fB#\ \fIline\fP\ "\fIfile\fP"\fR which makes error messages from

+the C/C++ compiler make more sense as they will \*Qpoint\*U into the

+grammar file not the resulting C file.  Debugging is easier as well,

+because you will step through the grammar not C file.

+.IP \fB-gs\fR

+Do not generate sets for token expression lists; instead generate a

+\fB||\fP-separated sequence of \fBLA(1)==\fItoken_number\fR.  The

+default is to generate sets.

+.IP \fB-gt\fP

+Generate code for Abstract-Syntax Trees.

+.IP \fB-gx\fP

+Do not create the lexical analyzer files (dlg-related).  This option

+should be given when the user wishes to provide a customized lexical

+analyzer.  It may also be used in \fImake\fR scripts to cause only the

+parser to be rebuilt when a change not affecting the lexical structure

+is made to the input grammars.

+.IP "\fB-k \fIn\fR"

+Set k of LL(k) to \fIn\fR; i.e. set tokens of look-ahead (default==1).

+.IP "\fB-o\fP dir

+Directory where output files should go (default=".").  This is very

+nice for keeping the source directory clear of ANTLR and DLG spawn.

+.IP \fB-p\fP

+The complete grammar, collected from all input grammar files and

+stripped of all comments and embedded actions, is listed to

+\fBstdout\fP.  This is intended to aid in viewing the entire grammar

+as a whole and to eliminate the need to keep actions concisely stated

+so that the grammar is easier to read.  Hence, it is preferable to

+embed even complex actions directly in the grammar, rather than to

+call them as subroutines, since the subroutine call overhead will be

+saved.

+.IP \fB-pa\fP

+This option is the same as \fB-p\fP except that the output is

+annotated with the first sets determined from grammar analysis.

+.IP "\fB-prc on\fR

+Turn on the computation and hoisting of predicate context.

+.IP "\fB-prc off\fR

+Turn off the computation and hoisting of predicate context.  This

+option makes 1.10 behave like the 1.06 release with option \fB-pr\fR

+on.  Context computation is off by default.

+.IP "\fB-rl \fIn\fR

+Limit the maximum number of tree nodes used by grammar analysis to

+\fIn\fP.  Occasionally, \fIantlr\fP is unable to analyze a grammar

+submitted by the user.  This rare situation can only occur when the

+grammar is large and the amount of lookahead is greater than one.  A

+nonlinear analysis algorithm is used by PCCTS to handle the general

+case of LL(k) parsing.  The average complexity of analysis, however, is

+near linear due to some fancy footwork in the implementation which

+reduces the number of calls to the full LL(k) algorithm.  An error

+message will be displayed, if this limit is reached, which indicates

+the grammar construct being analyzed when \fIantlr\fP hit a

+non-linearity.  Use this option if \fIantlr\fP seems to go out to

+lunch and your disk start thrashing; try \fIn\fP=10000 to start.  Once

+the offending construct has been identified, try to remove the

+ambiguity that \fIantlr\fP was trying to overcome with large lookahead

+analysis.  The introduction of (...)? backtracking blocks eliminates

+some of these problems\ \(em \fIantlr\fP does not analyze alternatives

+that begin with (...)? (it simply backtracks, if necessary, at run

+time).

+.IP \fB-w1\fR

+Set low warning level.  Do not warn if semantic predicates and/or

+(...)? blocks are assumed to cover ambiguous alternatives.

+.IP \fB-w2\fR

+Ambiguous parsing decisions yield warnings even if semantic predicates

+or (...)? blocks are used.  Warn if predicate context computed and

+semantic predicates incompletely disambiguate alternative productions.

+.IP \fB-\fR

+Read grammar from standard input and generate \fBstdin.c\fP as the

+parser file.

+.SH "SPECIAL CONSIDERATIONS"

+.PP

+\fIAntlr\fP works...  we think.  There is no implicit guarantee of

+anything.  We reserve no \fBlegal\fP rights to the software known as

+the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the

+public domain.  An individual or company may do whatever they wish

+with source code distributed with PCCTS or the code generated by

+PCCTS, including the incorporation of PCCTS, or its output, into

+commercial software.  We encourage users to develop software with

+PCCTS.  However, we do ask that credit is given to us for developing

+PCCTS.  By "credit", we mean that if you incorporate our source code

+into one of your programs (commercial product, research project, or

+otherwise) that you acknowledge this fact somewhere in the

+documentation, research report, etc...  If you like PCCTS and have

+developed a nice tool with the output, please mention that you

+developed it using PCCTS.  As long as these guidelines are followed,

+we expect to continue enhancing this system and expect to make other

+tools available as they are completed.

+.SH FILES

+.IP *.c

+output C parser.

+.IP *.cpp

+output C++ parser when C++ mode is used.

+.IP \fBparser.dlg\fP

+output \fIdlg\fR lexical analyzer.

+.IP \fBerr.c\fP

+token string array, error sets and error support routines.  Not used in

+C++ mode.

+.IP \fBremap.h\fP

+file that redefines all globally visible parser symbols.  The use of

+the #parser directive creates this file.  Not used in

+C++ mode.

+.IP \fBstdpccts.h\fP

+list of definitions needed by C files, not generated by PCCTS, that

+reference PCCTS objects.  This is not generated by default.  Not used in

+C++ mode.

+.IP \fBtokens.h\fP

+output \fI#defines\fR for tokens used and function prototypes for

+functions generated for rules.

+.SH "SEE ALSO"

+.LP

+dlg(1), pccts(1)

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.c
new file mode 100644
index 0000000..8aaef79
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.c
@@ -0,0 +1,3564 @@
+/*

+ * A n t l r  T r a n s l a t i o n  H e a d e r

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ *

+ *   ..\bin\antlr -gh antlr.g

+ *

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include "pcctscfg.h"

+#include "set.h"

+#include <ctype.h>

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#define zzcr_attr(attr,tok,t)

+#define zzSET_SIZE 20

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+#include "mode.h"

+

+/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */

+

+#ifndef PCCTS_PURIFY

+#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s));

+#endif

+

+ANTLR_INFO

+

+

+/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */

+#if defined(__TURBOC__)

+#pragma warn -aus  /* unused assignment of 'xxx' */

+#endif

+

+

+#ifdef __USE_PROTOS

+static void chkToken(char *, char *, char *, int);

+#else

+static void chkToken();

+#endif

+

+#ifdef __USE_PROTOS

+static int isDLGmaxToken(char *Token);				     /* MR3 */

+#else

+static int isDLGmaxToken();				                             /* MR3 */

+#endif

+

+static int class_nest_level = 0;

+

+/* MR20 G. Hobbelt extern definitions moved to antlr.h */

+

+  

+

+void

+#ifdef __USE_PROTOS

+grammar(void)

+#else

+grammar()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  Graph g;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    for (;;) {

+      if ( !((setwd1[LA(1)]&0x1))) break;

+      if ( (LA(1)==94) ) {

+        zzmatch(94); zzCONSUME;

+        zzmatch(Action);

+        

+        if ( HdrAction==NULL ) {

+          HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+          require(HdrAction!=NULL, "rule grammar: cannot allocate header action");

+          strcpy(HdrAction, LATEXT(1));

+        }

+        else warn("additional #header statement ignored");

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==95) ) {

+          zzmatch(95); zzCONSUME;

+          zzmatch(Action);

+          

+          if ( FirstAction==NULL ) {

+            FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+            require(FirstAction!=NULL, "rule grammar: cannot allocate #first action");

+            strcpy(FirstAction, LATEXT(1));

+          } else {

+            warn("additional #first statement ignored");

+          };

+ zzCONSUME;

+

+        }

+        else {

+          if ( (LA(1)==96) ) {

+            zzmatch(96); zzCONSUME;

+            zzmatch(QuotedTerm);

+            

+            if ( GenCC ) {

+              warn("#parser meta-op incompatible with -CC; ignored");

+            }

+            else {

+              if ( strcmp(ParserName,"zzparser")==0 ) {

+                ParserName=StripQuotes(mystrdup(LATEXT(1)));

+                if ( RulePrefix[0]!='\0' )

+                {

+                  warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored");

+                  RulePrefix[0]='\0';

+                }

+              }

+              else warn("additional #parser statement ignored");

+            }

+ zzCONSUME;

+

+          }

+          else {

+            if ( (LA(1)==97) ) {

+              zzmatch(97); zzCONSUME;

+              zzmatch(QuotedTerm);

+              {

+                char *fname;

+                zzantlr_state st; FILE *f; struct zzdlg_state dst;

+                UserTokenDefsFile = mystrdup(LATEXT(1));

+                zzsave_antlr_state(&st);

+                zzsave_dlg_state(&dst);

+                fname = mystrdup(LATEXT(1));

+                f = fopen(StripQuotes(fname), "r");

+                if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));}

+                else {

+                  ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE);

+                  UserDefdTokens = 1;

+                }

+                zzrestore_antlr_state(&st);

+                zzrestore_dlg_state(&dst);

+              }

+ zzCONSUME;

+

+            }

+            else break; /* MR6 code for exiting loop "for sure" */

+          }

+        }

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    for (;;) {

+      if ( !((setwd1[LA(1)]&0x2))) break;

+      if ( (LA(1)==Action) ) {

+        zzmatch(Action);

+        {

+          UserAction *ua = newUserAction(LATEXT(1));

+          ua->file = action_file; ua->line = action_line;

+          if ( class_nest_level>0 ) list_add(&class_before_actions, ua);

+          else list_add(&BeforeActions, ua);

+        }

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==108) ) {

+          laction();

+        }

+        else {

+          if ( (LA(1)==109) ) {

+            lmember();

+          }

+          else {

+            if ( (LA(1)==110) ) {

+              lprefix();

+            }

+            else {

+              if ( (LA(1)==116) ) {

+                aLexclass();

+              }

+              else {

+                if ( (LA(1)==120) ) {

+                  token();

+                }

+                else {

+                  if ( (LA(1)==117) ) {

+                    error();

+                  }

+                  else {

+                    if ( (LA(1)==118) ) {

+                      tclass();

+                    }

+                    else {

+                      if ( (LA(1)==111) ) {

+                        aPred();

+                      }

+                      else {

+                        if ( (LA(1)==133) ) {

+                          default_exception_handler();

+                        }

+                        else {

+                          if ( (LA(1)==99) ) {

+                            class_def();

+                          }

+                          else {

+                            if ( (LA(1)==98) ) {

+                              zzmatch(98);

+                              

+                              if ( class_nest_level==0 )

+                              warn("missing class definition for trailing '}'");

+                              class_nest_level--;

+ zzCONSUME;

+

+                            }

+                            else break; /* MR6 code for exiting loop "for sure" */

+                          }

+                        }

+                      }

+                    }

+                  }

+                }

+              }

+            }

+          }

+        }

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  rule();

+  g=zzaArg(zztasp1,3); SynDiag = (Junction *) zzaArg(zztasp1,3 ).left;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    for (;;) {

+      if ( !((setwd1[LA(1)]&0x4))) break;

+      if ( (LA(1)==NonTerminal) ) {

+        rule();

+        if ( zzaArg(zztasp2,1 ).left!=NULL ) {

+          g.right = NULL;

+          

+/* MR21a */             /*  Avoid use of a malformed graph when CannotContinue */

+          /* MR21a */             /*  is already set                                     */

+          /* MR21a */

+          /* MR21a */             if (! (CannotContinue && g.left == NULL)) {

+            /* MR21a */               g = Or(g, zzaArg(zztasp2,1));

+            /* MR21a */             }

+          /* MR21a */		      }

+      }

+      else {

+        if ( (LA(1)==116) ) {

+          aLexclass();

+        }

+        else {

+          if ( (LA(1)==120) ) {

+            token();

+          }

+          else {

+            if ( (LA(1)==117) ) {

+              error();

+            }

+            else {

+              if ( (LA(1)==118) ) {

+                tclass();

+              }

+              else {

+                if ( (LA(1)==111) ) {

+                  aPred();

+                }

+                else {

+                  if ( (LA(1)==99) ) {

+                    class_def();

+                  }

+                  else {

+                    if ( (LA(1)==98) ) {

+                      zzmatch(98);

+                      

+                      if ( class_nest_level==0 )

+                      warn("missing class definition for trailing '}'");

+                      class_nest_level--;

+ zzCONSUME;

+

+                    }

+                    else break; /* MR6 code for exiting loop "for sure" */

+                  }

+                }

+              }

+            }

+          }

+        }

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    for (;;) {

+      if ( !((setwd1[LA(1)]&0x8))) break;

+      if ( (LA(1)==Action) ) {

+        zzmatch(Action);

+        {

+          UserAction *ua = newUserAction(LATEXT(1));

+          ua->file = action_file; ua->line = action_line;

+          if ( class_nest_level>0 ) list_add(&class_after_actions, ua);

+          else list_add(&AfterActions, ua);

+        }

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==108) ) {

+          laction();

+        }

+        else {

+          if ( (LA(1)==109) ) {

+            lmember();

+          }

+          else {

+            if ( (LA(1)==110) ) {

+              lprefix();

+            }

+            else {

+              if ( (LA(1)==117) ) {

+                error();

+              }

+              else {

+                if ( (LA(1)==118) ) {

+                  tclass();

+                }

+                else {

+                  if ( (LA(1)==99) ) {

+                    class_def();

+                  }

+                  else {

+                    if ( (LA(1)==111) ) {

+                      aPred();

+                    }

+                    else {

+                      if ( (LA(1)==98) ) {

+                        zzmatch(98);

+                        

+                        if ( class_nest_level==0 )

+                        warn("missing class definition for trailing '}'");

+                        class_nest_level--;

+ zzCONSUME;

+

+                      }

+                      else break; /* MR6 code for exiting loop "for sure" */

+                    }

+                  }

+                }

+              }

+            }

+          }

+        }

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(Eof); zzCONSUME;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd1, 0x10);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+class_def(void)

+#else

+class_def()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  int go=1; char name[MaxRuleName+1];

+  zzmatch(99); zzCONSUME;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==NonTerminal) ) {

+      zzmatch(NonTerminal);

+      if(go) strncpy(name,LATEXT(1),MaxRuleName);

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==TokenTerm) ) {

+        zzmatch(TokenTerm);

+        if(go) strncpy(name,LATEXT(1),MaxRuleName);

+ zzCONSUME;

+

+      }

+      else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0

+  && GenCC ) {

+    err("only one grammar class allowed in this release");

+    go = 0;

+  }

+  else strcpy(CurrentClassName, name);

+  if ( !GenCC ) { err("class meta-op used without C++ option"); }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (setwd1[LA(1)]&0x20) ) {

+      zzsetmatch(zzerr2, zzerr3);

+      if (ClassDeclStuff == NULL) {

+        /* MR10 */                   ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char));

+        /* MR10 */              };

+      /* MR10 */              strncat(ClassDeclStuff," ",MaxClassDeclStuff);

+      /* MR10 */              strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff);

+      /* MR22 */              do {

+        /* MR22 */                if (0 == strcmp(LATEXT(1),"public")) break;

+        /* MR22 */                if (0 == strcmp(LATEXT(1),"private")) break;

+        /* MR22 */                if (0 == strcmp(LATEXT(1),"protected")) break;

+        /* MR22 */                if (0 == strcmp(LATEXT(1),"virtual")) break;

+        /* MR22 */                if (0 == strcmp(LATEXT(1),",")) break;

+        /* MR22 */                if (0 == strcmp(LATEXT(1),":")) break;

+        /* MR22 */                if (BaseClassName != NULL) break;

+        /* MR22 */                BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char));

+        /* MR22 */                require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name");

+        /* MR22 */				  strcpy(BaseClassName,LATEXT(1));

+        /* MR22 */              } while (0);

+      /* MR10 */

+ zzCONSUME;

+

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(102);

+  

+  no_classes_found = 0;

+  if ( class_nest_level>=1 ) {warn("cannot have nested classes");}

+  else class_nest_level++;

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd1, 0x40);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+rule(void)

+#else

+rule()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  

+  

+			ExceptionGroup *eg;

+  RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e;

+  set toksrefd, rulesrefd;

+  char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL;

+  CurExGroups = NULL;

+  CurElementLabels = NULL;

+  CurAstLabelsInActions = NULL; /* MR27 */

+  /* We want a new element label hash table for each rule */

+  if ( Elabel!=NULL ) killHashTable(Elabel);

+  Elabel = newHashTable();

+  attribsRefdFromAction = empty;

+  zzmatch(NonTerminal);

+  q=NULL;

+  if ( hash_get(Rname, LATEXT(1))!=NULL ) {

+    err(eMsg1("duplicate rule definition: '%s'",LATEXT(1)));

+    CannotContinue=TRUE;

+  }

+  else

+  {

+    q = (RuleEntry *)hash_add(Rname,

+    LATEXT(1),

+    (Entry *)newRuleEntry(LATEXT(1)));

+    CurRule = q->str;

+  }

+  CurRuleNode = q;

+  f = CurFile; l = zzline;

+  NumRules++;

+ zzCONSUME;

+

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==103) ) {

+      zzmatch(103);

+      if ( q!=NULL ) q->noAST = TRUE;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd1[LA(1)]&0x80) ) {

+      }

+      else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    ;

+    if ( (setwd2[LA(1)]&0x1) ) {

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==104) ) {

+          zzmatch(104); zzCONSUME;

+        }

+        else {

+          if ( (LA(1)==PassAction) ) {

+          }

+          else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      zzmatch(PassAction);

+      pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+      require(pdecl!=NULL, "rule rule: cannot allocate param decl");

+      strcpy(pdecl, LATEXT(1));

+      CurParmDef = pdecl;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd2[LA(1)]&0x2) ) {

+      }

+      else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==105) ) {

+      zzmatch(105); zzCONSUME;

+      zzmatch(PassAction);

+      ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+      require(ret!=NULL, "rule rule: cannot allocate ret type");

+      strcpy(ret, LATEXT(1));

+      CurRetDef = ret;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd2[LA(1)]&0x4) ) {

+      }

+      else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==QuotedTerm) ) {

+      zzmatch(QuotedTerm);

+      if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==106) ) {

+      }

+      else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  if ( GenEClasseForRules && q!=NULL ) {

+    e = newECnode;

+    require(e!=NULL, "cannot allocate error class node");

+    if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);}

+    else a = q->egroup;

+    if ( Tnum( a ) == 0 )

+    {

+      e->tok = addTname( a );

+      list_add(&eclasses, (char *)e);

+      if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);

+      /* refers to itself */

+      list_add(&(e->elist), mystrdup(q->str));

+    }

+    else {

+      warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a));

+      if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);

+      free((char *)e);

+    }

+  }

+  BlkLevel++;

+  if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");

+  /* MR23 */    CurBlockID_array[BlkLevel] = CurBlockID;

+  /* MR23 */    CurAltNum_array[BlkLevel] = CurAltNum;

+  zzmatch(106);

+  inAlt=1;

+ zzCONSUME;

+

+  block( &toksrefd, &rulesrefd );

+  r = makeBlk(zzaArg(zztasp1,7),0, NULL /* pFirstSetSymbol */ );

+  CurRuleBlk = (Junction *)r.left;

+  CurRuleBlk->blockid = CurBlockID;

+  CurRuleBlk->jtype = RuleBlk;

+  if ( q!=NULL ) CurRuleBlk->rname = q->str;

+  CurRuleBlk->file = f;

+  CurRuleBlk->line = l;

+  CurRuleBlk->pdecl = pdecl;

+  CurRuleBlk->ret = ret;

+  CurRuleBlk->lock = makelocks();

+  CurRuleBlk->pred_lock = makelocks();

+  CurRuleBlk->tokrefs = toksrefd;

+  CurRuleBlk->rulerefs = rulesrefd;

+  p = newJunction();	/* add EndRule Node */

+  ((Junction *)r.right)->p1 = (Node *)p;

+  r.right = (Node *) p;

+  p->jtype = EndRule;

+  p->lock = makelocks();

+  p->pred_lock = makelocks();

+  CurRuleBlk->end = p;

+  if ( q!=NULL ) q->rulenum = NumRules;

+  zzaArg(zztasp1,7) = r;

+  

+  /* MR23 */      CurBlockID_array[BlkLevel] = (-1);

+  /* MR23 */      CurAltNum_array[BlkLevel] = (-1);                

+  --BlkLevel;

+  altFixup();leFixup();egFixup();

+  zzmatch(107);

+  inAlt=0;

+ zzCONSUME;

+

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==Action) ) {

+      zzmatch(Action);

+      a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+      require(a!=NULL, "rule rule: cannot allocate error action");

+      strcpy(a, LATEXT(1));

+      CurRuleBlk->erraction = a;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd2[LA(1)]&0x8) ) {

+      }

+      else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==133) ) {

+       eg  = exception_group();

+

+      if ( eg!=NULL ) {

+        list_add(&CurExGroups, (void *)eg);

+        if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1;

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  if ( q==NULL ) zzaArg(zztasp1,0 ).left = NULL; else zzaArg(zztasp1,0) = zzaArg(zztasp1,7);

+  CurRuleBlk->exceptions = CurExGroups;

+  CurRuleBlk->el_labels = CurElementLabels;

+  CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions;

+  CurRuleNode = NULL;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x10);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+laction(void)

+#else

+laction()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  char *a;

+  zzmatch(108); zzCONSUME;

+  zzmatch(Action);

+  

+  a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+  require(a!=NULL, "rule laction: cannot allocate action");

+  strcpy(a, LATEXT(1));

+  list_add(&LexActions, a);

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x20);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+lmember(void)

+#else

+lmember()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  char *a;

+  zzmatch(109); zzCONSUME;

+  zzmatch(Action);

+  

+  /* MR1 */		if (! GenCC) {

+    /* MR1 */		  err("Use #lexmember only in C++ mode (to insert code in DLG class header");

+    /* MR1 */	        } else {

+    /* MR1 */		  a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+    /* MR1 */		  require(a!=NULL, "rule lmember: cannot allocate action");

+    /* MR1 */		  strcpy(a, LATEXT(1));

+    /* MR1 */		  list_add(&LexMemberActions, a);

+    /* MR1 */		};

+  /* MR1 */

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x40);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+lprefix(void)

+#else

+lprefix()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  char *a;

+  zzmatch(110); zzCONSUME;

+  zzmatch(Action);

+  

+  /* MR1 */		if (! GenCC) {

+    /* MR1 */		  err("Use #lexprefix only in C++ mode (to insert code in DLG class header");

+    /* MR1 */	        } else {

+    /* MR1 */		  a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+    /* MR1 */		  require(a!=NULL, "rule lprefix: cannot allocate action");

+    /* MR1 */		  strcpy(a, LATEXT(1));

+    /* MR1 */		  list_add(&LexPrefixActions, a);

+    /* MR1 */		};

+  /* MR1 */

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x80);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+aPred(void)

+#else

+aPred()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  PredEntry     *predEntry=NULL;

+  char          *name=NULL;

+  Predicate     *predExpr=NULL;

+  char          *predLiteral=NULL;

+  int           save_file;

+  int           save_line;

+  int           predExprPresent=0;

+  zzmatch(111);

+  

+  MR_usingPredNames=1;      /* will need to use -mrhoist version of genPredTree */

+ zzCONSUME;

+

+  zzmatch(TokenTerm);

+  name=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+  

+  /* don't free - referenced in predicates */

+  

+            CurPredName=(char *)calloc(1,strlen(name) + 10);

+  strcat(CurPredName,"#pred ");

+  strcat(CurPredName,name);

+  

+            predEntry=(PredEntry *) hash_get(Pname,name);

+  if (predEntry != NULL) {

+  warnFL(eMsg1("#pred %s previously defined - ignored",name),

+  FileStr[action_file],action_line);

+  name=NULL;

+};

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==Pred) ) {

+      zzmatch(Pred);

+      predLiteral=mystrdup(LATEXT(1));

+      save_line=action_line;

+      save_file=action_file;

+ zzCONSUME;

+

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (setwd3[LA(1)]&0x1) ) {

+           predExpr  = predOrExpr();

+

+          predExprPresent=1;

+        }

+        else {

+          if ( (setwd3[LA(1)]&0x2) ) {

+          }

+          else {zzFAIL(1,zzerr10,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      if (predLiteral != NULL && name != NULL) {

+        

+                      /*

+        *  predExpr may be NULL due to syntax errors

+        *    or simply omitted by the user

+        */

+        

+                      predEntry=newPredEntry(name);

+        predEntry->file=save_file;

+        predEntry->line=save_line;

+        predExpr=MR_predFlatten(predExpr);

+        predEntry->predLiteral=predLiteral;

+        if (! predExprPresent || predExpr == NULL) {

+          predExpr=new_pred();

+          predExpr->expr=predLiteral;

+          predExpr->source=newActionNode();

+          predExpr->source->action=predExpr->expr;

+          predExpr->source->rname=CurPredName;

+          predExpr->source->line=action_line;

+          predExpr->source->file=action_file;

+          predExpr->source->is_predicate=1;

+          predExpr->k=predicateLookaheadDepth(predExpr->source);

+        };

+        predEntry->pred=predExpr;

+        hash_add(Pname,name,(Entry *)predEntry);

+        predExpr=NULL;

+      };

+      predicate_free(predExpr);

+    }

+    else {

+      if ( (setwd3[LA(1)]&0x4) ) {

+        save_line=zzline; save_file=CurFile;

+         predExpr  = predOrExpr();

+

+        if (predExpr != NULL && name != NULL) {

+          predEntry=newPredEntry(name);

+          predEntry->file=CurFile;

+          predEntry->line=zzline;

+          predExpr=MR_predFlatten(predExpr);

+          predEntry->pred=predExpr;

+          hash_add(Pname,name,(Entry *)predEntry);

+          predExpr=NULL;

+        };

+        predicate_free(predExpr);

+      }

+      else {zzFAIL(1,zzerr11,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==107) ) {

+      zzmatch(107); zzCONSUME;

+    }

+    else {

+      if ( (setwd3[LA(1)]&0x8) ) {

+      }

+      else {zzFAIL(1,zzerr12,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  predicate_free(predExpr);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x10);

+  }

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+predOrExpr(void)

+#else

+predOrExpr()

+#endif

+{

+  Predicate *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(Predicate *  ))

+  zzMake0;

+  {

+  Predicate     *ORnode;

+  Predicate     *predExpr;

+  Predicate     **tail=NULL;

+   predExpr  = predAndExpr();

+

+  

+  ORnode=new_pred();

+  ORnode->expr=PRED_OR_LIST;

+  if (predExpr != NULL) {

+    ORnode->down=predExpr;

+    tail=&predExpr->right;

+  };

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==112) ) {

+      zzmatch(112); zzCONSUME;

+       predExpr  = predAndExpr();

+

+      

+      if (predExpr != NULL) {

+        *tail=predExpr;

+        tail=&predExpr->right;

+      };

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  _retv=ORnode;

+  ORnode=NULL;

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  predicate_free(ORnode);  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x20);

+  return _retv;

+  }

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+predAndExpr(void)

+#else

+predAndExpr()

+#endif

+{

+  Predicate *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(Predicate *  ))

+  zzMake0;

+  {

+  Predicate     *ANDnode;

+  Predicate     *predExpr;

+  Predicate     **tail=NULL;

+   predExpr  = predPrimary();

+

+  

+  ANDnode=new_pred();

+  ANDnode->expr=PRED_AND_LIST;

+  if (predExpr != NULL) {

+    ANDnode->down=predExpr;

+    tail=&predExpr->right;

+  };

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==113) ) {

+      zzmatch(113); zzCONSUME;

+       predExpr  = predPrimary();

+

+      

+      if (predExpr != NULL) {

+        *tail=predExpr;

+        tail=&predExpr->right;

+      };

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  _retv=ANDnode;

+  ANDnode=NULL;

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  predicate_free(ANDnode);  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x40);

+  return _retv;

+  }

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+predPrimary(void)

+#else

+predPrimary()

+#endif

+{

+  Predicate *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(Predicate *  ))

+  zzMake0;

+  {

+  

+  char          *name=NULL;

+  PredEntry     *predEntry=NULL;

+  Predicate     *predExpr=NULL;

+  if ( (LA(1)==TokenTerm) ) {

+    zzmatch(TokenTerm);

+    name=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+    

+    predEntry=(PredEntry *) hash_get(Pname,name);

+    if (predEntry == NULL) {

+      warnFL(eMsg1("no previously defined #pred with name \"%s\"",name),

+      FileStr[CurFile],zzline);

+      name=NULL;

+      _retv=NULL;

+    } else {

+      predExpr=predicate_dup(predEntry->pred);

+      predExpr->predEntry=predEntry;

+      _retv=predExpr;

+    };

+  }

+  else {

+    if ( (LA(1)==114) ) {

+      zzmatch(114); zzCONSUME;

+       predExpr  = predOrExpr();

+

+      zzmatch(115);

+      

+      _retv=predExpr;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==103) ) {

+        zzmatch(103); zzCONSUME;

+         predExpr  = predPrimary();

+

+        

+        predExpr->inverted=!predExpr->inverted;

+        _retv=predExpr;

+      }

+      else {zzFAIL(1,zzerr13,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+  }

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  

+  predicate_free(predExpr);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x80);

+  return _retv;

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+aLexclass(void)

+#else

+aLexclass()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  zzmatch(116); zzCONSUME;

+  zzmatch(TokenTerm);

+  lexclass(mystrdup(LATEXT(1)));

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd4, 0x1);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+error(void)

+#else

+error()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  char *t=NULL; ECnode *e; int go=1; TermEntry *p;

+  zzmatch(117); zzCONSUME;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    ;

+    if ( (LA(1)==TokenTerm) ) {

+      zzmatch(TokenTerm);

+      t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==QuotedTerm) ) {

+        zzmatch(QuotedTerm);

+        t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+      }

+      else {zzFAIL(1,zzerr14,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  e = newECnode;

+  require(e!=NULL, "cannot allocate error class node");

+  e->lexclass = CurrentLexClass;

+  if ( Tnum( (t=StripQuotes(t)) ) == 0 )

+  {

+    if ( hash_get(Texpr, t) != NULL )

+    warn(eMsg1("errclass name conflicts with regular expression  '%s'",t));

+    e->tok = addTname( t );

+    set_orel(e->tok, &imag_tokens);

+    require((p=(TermEntry *)hash_get(Tname, t)) != NULL,

+    "hash table mechanism is broken");

+    p->classname = 1;	/* entry is errclass name, not token */

+    list_add(&eclasses, (char *)e);

+  }

+  else

+  {

+  warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t));

+  free( (char *)e );

+  go=0;

+}

+  zzmatch(102); zzCONSUME;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==NonTerminal) ) {

+      zzmatch(NonTerminal);

+      if ( go ) t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==TokenTerm) ) {

+        zzmatch(TokenTerm);

+        if ( go ) t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==QuotedTerm) ) {

+          zzmatch(QuotedTerm);

+          if ( go ) t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+        }

+        else {zzFAIL(1,zzerr15,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+      }

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  if ( go ) list_add(&(e->elist), t);

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (setwd4[LA(1)]&0x2) ) {

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==NonTerminal) ) {

+          zzmatch(NonTerminal);

+          if ( go ) t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+        }

+        else {

+          if ( (LA(1)==TokenTerm) ) {

+            zzmatch(TokenTerm);

+            if ( go ) t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+          }

+          else {

+            if ( (LA(1)==QuotedTerm) ) {

+              zzmatch(QuotedTerm);

+              if ( go ) t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+            }

+            else {zzFAIL(1,zzerr16,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      if ( go ) list_add(&(e->elist), t);

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(98); zzCONSUME;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd4, 0x4);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+tclass(void)

+#else

+tclass()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm;

+  char *akaString=NULL; int save_file; int save_line;

+  char *totext=NULL;

+  zzmatch(118); zzCONSUME;

+  zzmatch(TokenTerm);

+  t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+  e = newTCnode;

+  require(e!=NULL, "cannot allocate token class node");

+  e->lexclass = CurrentLexClass;

+  if ( Tnum( t ) == 0 )

+  {

+    e->tok = addTname( t );

+    set_orel(e->tok, &imag_tokens);

+    set_orel(e->tok, &tokclasses);

+    require((p=(TermEntry *)hash_get(Tname, t)) != NULL,

+    "hash table mechanism is broken");

+    p->classname = 1;	/* entry is class name, not token */

+    p->tclass = e;		/* save ptr to this tclass def */

+    list_add(&tclasses, (char *)e);

+  }

+  else

+  {

+  warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t));

+  free( (char *)e );

+  go=0;

+}

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==114) ) {

+      zzmatch(114); zzCONSUME;

+      zzmatch(QuotedTerm);

+      akaString=mystrdup(StripQuotes(LATEXT(1)));

+      /* MR11 */                   save_file=CurFile;save_line=zzline;

+      /* MR23 */

+ zzCONSUME;

+

+      zzmatch(115); zzCONSUME;

+    }

+    else {

+      if ( (LA(1)==102) ) {

+      }

+      else {zzFAIL(1,zzerr17,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  /* MR23 */         if (p!= NULL && akaString != NULL) {

+    /* MR23 */           if (p->akaString != NULL) {

+      /* MR23 */             if (strcmp(p->akaString,akaString) != 0) {

+        /* MR23 */                warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement",

+        /* MR23 */                              t,p->akaString),

+        /* MR23 */			                    FileStr[save_file],save_line);

+        /* MR23 */             };

+      /* MR23 */            } else {

+      /* MR23 */              p->akaString=akaString;

+      /* MR23 */            };

+    /* MR23 */          };

+  /* MR23 */

+  zzmatch(102); zzCONSUME;

+  {

+    zzBLOCK(zztasp2);

+    int zzcnt=1;

+    zzMake0;

+    {

+    do {

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==TokenTerm) ) {

+          zzmatch(TokenTerm);

+          if ( go ) {

+            term = (TermEntry *) hash_get(Tname, LATEXT(1));

+            if ( term==NULL && UserDefdTokens ) {

+              err("implicit token definition not allowed with #tokdefs");

+              go = 0;

+            }

+            else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));}

+          }

+ zzCONSUME;

+

+          {

+            zzBLOCK(zztasp4);

+            zzMake0;

+            {

+            if ( (LA(1)==119) ) {

+              zzmatch(119); zzCONSUME;

+              zzmatch(TokenTerm);

+              if ( go ) {

+                toterm = (TermEntry *) hash_get(Tname, LATEXT(1));

+                if ( toterm==NULL && UserDefdTokens ) {

+                  err("implicit token definition not allowed with #tokdefs");

+                  go = 0;

+                } else {

+                  totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1));

+                }

+              }

+ zzCONSUME;

+

+            }

+            else {

+              if ( (setwd4[LA(1)]&0x8) ) {

+              }

+              else {zzFAIL(1,zzerr18,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp4);

+            }

+          }

+        }

+        else {

+          if ( (LA(1)==QuotedTerm) ) {

+            zzmatch(QuotedTerm);

+            if ( go ) {

+              term = (TermEntry *) hash_get(Texpr, LATEXT(1));

+              if ( term==NULL && UserDefdTokens ) {

+                err("implicit token definition not allowed with #tokdefs");

+                go = 0;

+              }

+              else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));}

+            }

+ zzCONSUME;

+

+          }

+          else {zzFAIL(1,zzerr19,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      if ( go ) {

+        if (totext == NULL) {

+          list_add(&(e->tlist), t);

+        } else {

+          list_add(&(e->tlist),"..");

+          list_add(&(e->tlist),t);

+          list_add(&(e->tlist),totext);

+        }

+        totext=NULL;

+      }

+      zzLOOP(zztasp2);

+    } while ( (setwd4[LA(1)]&0x10) );

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(98); zzCONSUME;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd4, 0x20);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+token(void)

+#else

+token()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  char *t=NULL, *e=NULL, *a=NULL; int tnum=0;

+  char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0;

+  zzmatch(120);

+  tokenActionActive=1;

+ zzCONSUME;

+

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==TokenTerm) ) {

+      zzmatch(TokenTerm);

+      t=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==114) ) {

+          zzmatch(114); zzCONSUME;

+          zzmatch(QuotedTerm);

+          akaString=mystrdup(StripQuotes(LATEXT(1)));

+          /* MR11 */                   save_file=CurFile;save_line=zzline;

+          /* MR11 */

+ zzCONSUME;

+

+          zzmatch(115); zzCONSUME;

+        }

+        else {

+          if ( (setwd4[LA(1)]&0x40) ) {

+          }

+          else {zzFAIL(1,zzerr20,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==121) ) {

+          zzmatch(121); zzCONSUME;

+          zzmatch(122);

+          tnum = atoi(LATEXT(1));

+ zzCONSUME;

+

+        }

+        else {

+          if ( (setwd4[LA(1)]&0x80) ) {

+          }

+          else {zzFAIL(1,zzerr21,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+    }

+    else {

+      if ( (setwd5[LA(1)]&0x1) ) {

+      }

+      else {zzFAIL(1,zzerr22,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==QuotedTerm) ) {

+      zzmatch(QuotedTerm);

+      e=mystrdup(LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd5[LA(1)]&0x2) ) {

+      }

+      else {zzFAIL(1,zzerr23,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==Action) ) {

+      zzmatch(Action);

+      

+      a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+      require(a!=NULL, "rule token: cannot allocate action");

+      strcpy(a, LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd5[LA(1)]&0x4) ) {

+      }

+      else {zzFAIL(1,zzerr24,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==107) ) {

+      zzmatch(107); zzCONSUME;

+    }

+    else {

+      if ( (setwd5[LA(1)]&0x8) ) {

+      }

+      else {zzFAIL(1,zzerr25,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  chkToken(t, e, a, tnum);

+  if (t != NULL) {

+    te=(TermEntry *)hash_get(Tname,t);

+    if (te != NULL && akaString != NULL) {

+      if (te->akaString != NULL) {

+        if (strcmp(te->akaString,akaString) != 0) {

+          warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement",

+          t,te->akaString),

+          FileStr[save_file],save_line);

+        };

+      } else {

+        te->akaString=akaString;

+      };

+    };

+  };

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd5, 0x10);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+block(set * toksrefd,set * rulesrefd)

+#else

+block(toksrefd,rulesrefd)

+ set *toksrefd;

+set *rulesrefd ;

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  

+  Graph g, b;

+  set saveblah;

+  int saveinalt = inAlt;

+  ExceptionGroup *eg;

+  * toksrefd = empty;

+  * rulesrefd = empty;

+  set_clr(AST_nodes_refd_in_actions);

+  CurBlockID++;

+  /* MR23 */      CurBlockID_array[BlkLevel] = CurBlockID;

+  CurAltNum = 1;

+  /* MR23 */      CurAltNum_array[BlkLevel] = CurAltNum;                

+  saveblah = attribsRefdFromAction;

+  attribsRefdFromAction = empty;

+  alt( toksrefd,rulesrefd );

+  b = g = zzaArg(zztasp1,1);

+  

+  if ( ((Junction *)g.left)->p1->ntype == nAction )

+  {

+    ActionNode *actionNode=(ActionNode *)

+    ( ( (Junction *)g.left) ->p1);

+    if (!actionNode->is_predicate )

+    {

+      actionNode->init_action = TRUE;

+      /* MR12c */  		if (actionNode->noHoist) {

+        /* MR12c */           errFL("<<nohoist>> appears as init-action - use <<>> <<nohoist>>",

+        /* MR12c */                       FileStr[actionNode->file],actionNode->line);

+        /* MR12c */         };

+    }

+  }

+  ((Junction *)g.left)->blockid = CurBlockID;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==133) ) {

+       eg  = exception_group();

+

+      

+      if ( eg!=NULL ) {

+        /* MR7 *****       	eg->altID = makeAltID(CurBlockID,CurAltNum);        *****/

+        /* MR7 *****		CurAltStart->exception_label = eg->altID;           *****/

+        list_add(&CurExGroups, (void *)eg);

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  CurAltNum++;

+  /* MR23 */    CurAltNum_array[BlkLevel] = CurAltNum;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==123) ) {

+      zzmatch(123);

+      inAlt=1;

+ zzCONSUME;

+

+      alt( toksrefd,rulesrefd );

+      g = Or(g, zzaArg(zztasp2,2));

+      

+      ((Junction *)g.left)->blockid = CurBlockID;

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        while ( (LA(1)==133) ) {

+           eg  = exception_group();

+

+          

+          if ( eg!=NULL ) {

+            /* MR7 *****       	eg->altID = makeAltID(CurBlockID,CurAltNum);        *****/

+            /* MR7 *****		CurAltStart->exception_label = eg->altID;           *****/

+            list_add(&CurExGroups, (void *)eg);

+          }

+          zzLOOP(zztasp3);

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      CurAltNum++;

+      /* MR23 */        CurAltNum_array[BlkLevel] = CurAltNum;

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzaArg(zztasp1,0) = b;

+  attribsRefdFromAction = saveblah; inAlt = saveinalt;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd5, 0x20);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+alt(set * toksrefd,set * rulesrefd)

+#else

+alt(toksrefd,rulesrefd)

+ set *toksrefd;

+set *rulesrefd ;

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif;

+  int first_on_line = 1, use_def_MT_handler = 0;

+  g.left=NULL; g.right=NULL;

+  

+			CurAltStart = NULL;

+  elems = empty;

+  inAlt = 1;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==88) ) {

+      zzmatch(88);

+      use_def_MT_handler = 1;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd5[LA(1)]&0x40) ) {

+      }

+      else {zzFAIL(1,zzerr26,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    ;

+    while ( (setwd5[LA(1)]&0x80) ) {

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        old_not=0;

+        if ( (LA(1)==124) ) {

+          zzmatch(124);

+          old_not=1;

+ zzCONSUME;

+

+        }

+        else {

+          if ( (setwd6[LA(1)]&0x1) ) {

+          }

+          else {zzFAIL(1,zzerr27,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+       node  = element( old_not, first_on_line, use_def_MT_handler );

+

+      if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0;

+      

+      if ( zzaArg(zztasp2,2 ).left!=NULL ) {

+        g = Cat(g, zzaArg(zztasp2,2));

+        n++;

+        if ( node!=NULL ) {

+          if ( node->ntype!=nAction ) e_num++;

+          /* record record number of all rule and token refs */

+          if ( node->ntype==nToken ) {

+            TokNode *tk = (TokNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1;

+            tk->elnum = e_num;

+            set_orel(e_num, &elems);

+          }

+          else if ( node->ntype==nRuleRef ) {

+            RuleRefNode *rn = (RuleRefNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1;

+            rn->elnum = e_num;

+            set_orel(e_num,  rulesrefd);

+          }

+        }

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  if ( n == 0 ) g = emptyAlt();

+  zzaArg(zztasp1,0) = g;

+  /* We want to reduce number of LT(i) calls and the number of

+  * local attribute variables in C++ mode (for moment, later we'll

+  * do for C also).  However, if trees are being built, they

+  * require most of the attrib variables to create the tree nodes

+  * with; therefore, we gen a token ptr for each token ref in C++

+  */

+  if ( GenCC && !GenAST )

+  {

+  /* This now free's the temp set -ATG 5/6/95 */

+  set temp;

+  temp = set_and(elems, attribsRefdFromAction);

+  set_orin( toksrefd, temp);

+  set_free(temp);

+}

+else set_orin( toksrefd, elems);

+if ( GenCC ) {

+  dif = set_dif(attribsRefdFromAction, elems);

+  if ( set_deg(dif)>0 )

+  err("one or more $i in action(s) refer to non-token elements");

+  set_free(dif);

+}

+set_free(elems);

+set_free(attribsRefdFromAction);

+inAlt = 0;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd6, 0x2);

+  }

+}

+

+LabelEntry *

+#ifdef __USE_PROTOS

+element_label(void)

+#else

+element_label()

+#endif

+{

+  LabelEntry *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(LabelEntry *  ))

+  zzMake0;

+  {

+  TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab;

+  zzmatch(LABEL);

+  lab = mystrdup(LATEXT(1));

+ zzCONSUME;

+

+  

+  UsedNewStyleLabel = 1;

+  if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i");

+  t = (TermEntry *) hash_get(Tname, lab);

+  if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab);

+  if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab);

+  if ( t!=NULL ) {

+    err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab));

+    _retv = NULL;

+  }

+  else if ( r!=NULL ) {

+    err(eMsg1("label definition clashes with rule definition: '%s'", lab));

+    _retv = NULL;

+  }

+  else {

+    /* we don't clash with anybody else */

+    l = (LabelEntry *) hash_get(Elabel, lab);

+    if ( l==NULL ) {	/* ok to add new element label */

+    l = (LabelEntry *)hash_add(Elabel,

+    lab,

+    (Entry *)newLabelEntry(lab));

+    /* add to list of element labels for this rule */

+    list_add(&CurElementLabels, (void *)lab);

+    /* MR7 */       leAdd(l);  /* list of labels waiting for exception group definitions */

+    _retv = l;

+  }

+  else {

+  err(eMsg1("label definitions must be unique per rule: '%s'", lab));

+  _retv = NULL;

+}

+}

+  zzmatch(106); zzCONSUME;

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd6, 0x4);

+  return _retv;

+  }

+}

+

+Node *

+#ifdef __USE_PROTOS

+element(int old_not,int first_on_line,int use_def_MT_handler)

+#else

+element(old_not,first_on_line,use_def_MT_handler)

+ int old_not;

+int first_on_line;

+int use_def_MT_handler ;

+#endif

+{

+  Node *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(Node *  ))

+  zzMake0;

+  {

+  

+  Attrib blk;

+  Predicate *pred = NULL;

+  int local_use_def_MT_handler=0;

+  ActionNode *act;

+  RuleRefNode *rr;

+  set toksrefd, rulesrefd;

+  TermEntry *term;

+  TokNode *p=NULL; RuleRefNode *q; int approx=0;

+  LabelEntry *label=NULL;

+  int predMsgDone=0;

+  int semDepth=0;

+  int   ampersandStyle;

+  int   height;         /* MR11 */

+  int   equal_height;   /* MR11 */

+  

+          char* pFirstSetSymbol = NULL; /* MR21 */

+  

+		  _retv = NULL;

+  if ( (setwd6[LA(1)]&0x8) ) {

+    {

+      zzBLOCK(zztasp2);

+      zzMake0;

+      {

+      if ( (LA(1)==LABEL) ) {

+         label  = element_label();

+

+      }

+      else {

+        if ( (setwd6[LA(1)]&0x10) ) {

+        }

+        else {zzFAIL(1,zzerr28,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+      }

+      zzEXIT(zztasp2);

+      }

+    }

+    {

+      zzBLOCK(zztasp2);

+      zzMake0;

+      {

+      if ( (LA(1)==TokenTerm) ) {

+        zzmatch(TokenTerm);

+        

+        term = (TermEntry *) hash_get(Tname, LATEXT(1));

+        if ( term==NULL && UserDefdTokens ) {

+          err("implicit token definition not allowed with #tokdefs");

+          zzaRet.left = zzaRet.right = NULL;

+        }

+        else {

+          zzaRet = buildToken(LATEXT(1));

+          p=((TokNode *)((Junction *)zzaRet.left)->p1);

+          term = (TermEntry *) hash_get(Tname, LATEXT(1));

+          require( term!= NULL, "hash table mechanism is broken");

+          p->tclass = term->tclass;

+          p->complement =  old_not;

+          if ( label!=NULL ) {

+            p->el_label = label->str;

+            label->elem = (Node *)p;

+          }

+        }

+ zzCONSUME;

+

+        {

+          zzBLOCK(zztasp3);

+          zzMake0;

+          {

+          if ( (LA(1)==119) ) {

+            zzmatch(119); zzCONSUME;

+            {

+              zzBLOCK(zztasp4);

+              zzMake0;

+              {

+              if ( (LA(1)==QuotedTerm) ) {

+                zzmatch(QuotedTerm);

+                if ( p!=NULL ) setUpperRange(p, LATEXT(1));

+ zzCONSUME;

+

+              }

+              else {

+                if ( (LA(1)==TokenTerm) ) {

+                  zzmatch(TokenTerm);

+                  if ( p!=NULL ) setUpperRange(p, LATEXT(1));

+ zzCONSUME;

+

+                }

+                else {zzFAIL(1,zzerr29,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+              }

+              zzEXIT(zztasp4);

+              }

+            }

+          }

+          else {

+            if ( (setwd6[LA(1)]&0x20) ) {

+            }

+            else {zzFAIL(1,zzerr30,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+          zzEXIT(zztasp3);

+          }

+        }

+        

+        if ( p!=NULL && (p->upper_range!=0 || p->tclass ||  old_not) )

+        list_add(&MetaTokenNodes, (void *)p);

+        {

+          zzBLOCK(zztasp3);

+          zzMake0;

+          {

+          if ( (LA(1)==125) ) {

+            zzmatch(125);

+            if ( p!=NULL ) p->astnode=ASTroot;

+ zzCONSUME;

+

+          }

+          else {

+            if ( (setwd6[LA(1)]&0x40) ) {

+              if ( p!=NULL ) p->astnode=ASTchild;

+            }

+            else {

+              if ( (LA(1)==103) ) {

+                zzmatch(103);

+                if ( p!=NULL ) p->astnode=ASTexclude;

+ zzCONSUME;

+

+              }

+              else {zzFAIL(1,zzerr31,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+          }

+          zzEXIT(zztasp3);

+          }

+        }

+        {

+          zzBLOCK(zztasp3);

+          zzMake0;

+          {

+          if ( (LA(1)==88) ) {

+            zzmatch(88);

+            local_use_def_MT_handler = 1;

+ zzCONSUME;

+

+          }

+          else {

+            if ( (setwd6[LA(1)]&0x80) ) {

+            }

+            else {zzFAIL(1,zzerr32,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+          zzEXIT(zztasp3);

+          }

+        }

+        

+        if ( p!=NULL &&  first_on_line ) {

+          CurAltStart = (Junction *)zzaRet.left;

+          altAdd(CurAltStart);                                 /* MR7 */

+          p->altstart = CurAltStart;

+        }

+        if ( p!=NULL )

+        p->use_def_MT_handler =  use_def_MT_handler || local_use_def_MT_handler;

+        _retv = (Node *)p;

+      }

+      else {

+        if ( (LA(1)==QuotedTerm) ) {

+          zzmatch(QuotedTerm);

+          

+          term = (TermEntry *) hash_get(Texpr, LATEXT(1));

+          if ( term==NULL && UserDefdTokens ) {

+            err("implicit token definition not allowed with #tokdefs");

+            zzaRet.left = zzaRet.right = NULL;

+          }

+          else {

+            zzaRet = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1);

+            p->complement =  old_not;

+            if ( label!=NULL ) {

+              p->el_label = label->str;

+              label->elem = (Node *)p;

+            }

+          }

+ zzCONSUME;

+

+          {

+            zzBLOCK(zztasp3);

+            zzMake0;

+            {

+            if ( (LA(1)==119) ) {

+              zzmatch(119); zzCONSUME;

+              {

+                zzBLOCK(zztasp4);

+                zzMake0;

+                {

+                if ( (LA(1)==QuotedTerm) ) {

+                  zzmatch(QuotedTerm);

+                  if ( p!=NULL ) setUpperRange(p, LATEXT(1));

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (LA(1)==TokenTerm) ) {

+                    zzmatch(TokenTerm);

+                    if ( p!=NULL ) setUpperRange(p, LATEXT(1));

+ zzCONSUME;

+

+                  }

+                  else {zzFAIL(1,zzerr33,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                }

+                zzEXIT(zztasp4);

+                }

+              }

+            }

+            else {

+              if ( (setwd7[LA(1)]&0x1) ) {

+              }

+              else {zzFAIL(1,zzerr34,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp3);

+            }

+          }

+          {

+            zzBLOCK(zztasp3);

+            zzMake0;

+            {

+            if ( (LA(1)==125) ) {

+              zzmatch(125);

+              if ( p!=NULL ) p->astnode=ASTroot;

+ zzCONSUME;

+

+            }

+            else {

+              if ( (setwd7[LA(1)]&0x2) ) {

+                if ( p!=NULL ) p->astnode=ASTchild;

+              }

+              else {

+                if ( (LA(1)==103) ) {

+                  zzmatch(103);

+                  if ( p!=NULL ) p->astnode=ASTexclude;

+ zzCONSUME;

+

+                }

+                else {zzFAIL(1,zzerr35,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+              }

+            }

+            zzEXIT(zztasp3);

+            }

+          }

+          {

+            zzBLOCK(zztasp3);

+            zzMake0;

+            {

+            if ( (LA(1)==88) ) {

+              zzmatch(88);

+              local_use_def_MT_handler = 1;

+ zzCONSUME;

+

+            }

+            else {

+              if ( (setwd7[LA(1)]&0x4) ) {

+              }

+              else {zzFAIL(1,zzerr36,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp3);

+            }

+          }

+          

+          if ( p!=NULL && (p->upper_range!=0 || p->tclass ||  old_not) )

+          list_add(&MetaTokenNodes, (void *)p);

+          

+          if (  first_on_line ) {

+            CurAltStart = (Junction *)zzaRet.left;

+            altAdd(CurAltStart);                                 /* MR7 */

+            p->altstart = CurAltStart;

+          }

+          if ( p!=NULL )

+          p->use_def_MT_handler =  use_def_MT_handler || local_use_def_MT_handler;

+          _retv = (Node *)p;

+        }

+        else {

+          if ( (LA(1)==WildCard) ) {

+            if (  old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')");

+            zzmatch(WildCard);

+            zzaRet = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1);

+ zzCONSUME;

+

+            {

+              zzBLOCK(zztasp3);

+              zzMake0;

+              {

+              if ( (LA(1)==125) ) {

+                zzmatch(125);

+                p->astnode=ASTroot;

+ zzCONSUME;

+

+              }

+              else {

+                if ( (setwd7[LA(1)]&0x8) ) {

+                  p->astnode=ASTchild;

+                }

+                else {

+                  if ( (LA(1)==103) ) {

+                    zzmatch(103);

+                    p->astnode=ASTexclude;

+ zzCONSUME;

+

+                  }

+                  else {zzFAIL(1,zzerr37,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                }

+              }

+              zzEXIT(zztasp3);

+              }

+            }

+            list_add(&MetaTokenNodes, (void *)p);

+            

+            if (  first_on_line ) {

+              CurAltStart = (Junction *)zzaRet.left;

+              altAdd(CurAltStart);                                 /* MR7 */

+              p->altstart = CurAltStart;

+              if ( label!=NULL ) {

+                p->el_label = label->str;

+                label->elem = (Node *)p;

+              }

+            }

+            _retv = (Node *)p;

+          }

+          else {

+            if ( (LA(1)==NonTerminal) ) {

+              if (  old_not ) warn("~ NONTERMINAL is an undefined operation");

+              zzmatch(NonTerminal);

+              zzaRet = buildRuleRef(LATEXT(1));

+ zzCONSUME;

+

+              {

+                zzBLOCK(zztasp3);

+                zzMake0;

+                {

+                if ( (LA(1)==103) ) {

+                  zzmatch(103);

+                  q = (RuleRefNode *) ((Junction *)zzaRet.left)->p1;

+                  q->astnode=ASTexclude;

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (setwd7[LA(1)]&0x10) ) {

+                  }

+                  else {zzFAIL(1,zzerr38,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                }

+                zzEXIT(zztasp3);

+                }

+              }

+              {

+                zzBLOCK(zztasp3);

+                zzMake0;

+                {

+                if ( (setwd7[LA(1)]&0x20) ) {

+                  {

+                    zzBLOCK(zztasp4);

+                    zzMake0;

+                    {

+                    if ( (LA(1)==104) ) {

+                      zzmatch(104); zzCONSUME;

+                    }

+                    else {

+                      if ( (LA(1)==PassAction) ) {

+                      }

+                      else {zzFAIL(1,zzerr39,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                    }

+                    zzEXIT(zztasp4);

+                    }

+                  }

+                  zzmatch(PassAction);

+                  addParm(((Junction *)zzaRet.left)->p1, LATEXT(1));

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (setwd7[LA(1)]&0x40) ) {

+                  }

+                  else {zzFAIL(1,zzerr40,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                }

+                zzEXIT(zztasp3);

+                }

+              }

+              rr=(RuleRefNode *) ((Junction *)zzaRet.left)->p1;

+              {

+                zzBLOCK(zztasp3);

+                zzMake0;

+                {

+                char *a;

+                if ( (LA(1)==105) ) {

+                  zzmatch(105); zzCONSUME;

+                  zzmatch(PassAction);

+                  

+                  a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+                  require(a!=NULL, "rule element: cannot allocate assignment");

+                  strcpy(a, LATEXT(1));

+                  rr->assign = a;

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (setwd7[LA(1)]&0x80) ) {

+                  }

+                  else {zzFAIL(1,zzerr41,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                }

+                zzEXIT(zztasp3);

+                }

+              }

+              

+              if ( label!=NULL ) {

+                rr->el_label = label->str;

+                label->elem = (Node *)rr;

+              }

+              if (  first_on_line ) {

+                CurAltStart = (Junction *)zzaRet.left;

+                altAdd(CurAltStart);                                 /* MR7 */

+                ((RuleRefNode *)((Junction *)zzaRet.left)->p1)->altstart = CurAltStart;

+              }

+              _retv = (Node *)rr;

+            }

+            else {zzFAIL(1,zzerr42,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+        }

+      }

+      zzEXIT(zztasp2);

+      }

+    }

+  }

+  else {

+    if ( (LA(1)==Action) ) {

+      if (  old_not )	warn("~ ACTION is an undefined operation");

+      zzmatch(Action);

+      zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 0);

+ zzCONSUME;

+

+      if (  first_on_line ) {                                /* MR7 */

+        CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left;                   /* MR7 */

+        altAdd(CurAltStart);                                 /* MR7 */

+      };

+      _retv = (Node *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1;

+    }

+    else {

+      if ( (LA(1)==Pred) ) {

+        if (  old_not )	warn("~ SEMANTIC-PREDICATE is an undefined operation");

+        zzmatch(Pred);

+        zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 1);

+ zzCONSUME;

+

+        act = (ActionNode *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1;

+        if (numericActionLabel) {             /* MR10 */

+          list_add(&NumericPredLabels,act);   /* MR10 */

+          numericActionLabel=0;               /* MR10 */

+        };                                    /* MR10 */

+        {

+          zzBLOCK(zztasp2);

+          zzMake0;

+          {

+          char *a;

+          if ( (LA(1)==PassAction) ) {

+            zzmatch(PassAction);

+            

+            a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+            require(a!=NULL, "rule element: cannot allocate predicate fail action");

+            strcpy(a, LATEXT(1));

+            act->pred_fail = a;

+ zzCONSUME;

+

+          }

+          else {

+            if ( (setwd8[LA(1)]&0x1) ) {

+            }

+            else {zzFAIL(1,zzerr43,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+          zzEXIT(zztasp2);

+          }

+        }

+        if (  first_on_line ) {                                /* MR7 */

+          CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left;                   /* MR7 */

+          altAdd(CurAltStart);                                 /* MR7 */

+        };

+        _retv = (Node *)act;

+      }

+      else {

+        if ( (setwd8[LA(1)]&0x2) ) {

+          if (  old_not )	warn("~ BLOCK is an undefined operation");

+          BlkLevel++;

+          if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");

+          /* MR23 */    CurBlockID_array[BlkLevel] = CurBlockID;

+          /* MR23 */    CurAltNum_array[BlkLevel] = CurAltNum;

+          {

+            zzBLOCK(zztasp2);

+            zzMake0;

+            {

+            if ( (LA(1)==Pragma) ) {

+              zzmatch(Pragma); zzCONSUME;

+              {

+                zzBLOCK(zztasp3);

+                zzMake0;

+                {

+                if ( (LA(1)==126) ) {

+                  zzmatch(126);

+                  approx=LL_k;

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (LA(1)==127) ) {

+                    zzmatch(127);

+                    approx = 1;

+ zzCONSUME;

+

+                  }

+                  else {

+                    if ( (LA(1)==128) ) {

+                      zzmatch(128);

+                      approx = 2;

+ zzCONSUME;

+

+                    }

+                    else {zzFAIL(1,zzerr44,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                  }

+                }

+                zzEXIT(zztasp3);

+                }

+              }

+            }

+            else {

+              if ( (setwd8[LA(1)]&0x4) ) {

+              }

+              else {zzFAIL(1,zzerr45,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp2);

+            }

+          }

+          {

+            zzBLOCK(zztasp2);

+            zzMake0;

+            {

+            if ( (LA(1)==FirstSetSymbol) ) {

+              zzmatch(FirstSetSymbol); zzCONSUME;

+              zzmatch(114); zzCONSUME;

+              {

+                zzBLOCK(zztasp3);

+                zzMake0;

+                {

+                if ( (LA(1)==NonTerminal) ) {

+                  zzmatch(NonTerminal);

+                  

+                  /* MR21 */                     pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,

+                  /* MR21 */                                                    sizeof(char));

+                  /* MR21 */                          require(pFirstSetSymbol!=NULL,

+                  /* MR21 */                                  "cannot allocate first set name");

+                  /* MR21 */                          strcpy(pFirstSetSymbol, LATEXT(1));

+                  /* MR21 */

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (LA(1)==TokenTerm) ) {

+                    zzmatch(TokenTerm);

+                    

+                    /* MR21 */                      pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,

+                    /* MR21 */                                                        sizeof(char));

+                    /* MR21 */                      require(pFirstSetSymbol!=NULL,

+                    /* MR21 */                              "cannot allocate first set name");

+                    /* MR21 */                      strcpy(pFirstSetSymbol, LATEXT(1));

+                    /* MR21 */

+ zzCONSUME;

+

+                  }

+                  else {zzFAIL(1,zzerr46,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                }

+                zzEXIT(zztasp3);

+                }

+              }

+              zzmatch(115); zzCONSUME;

+            }

+            else {

+              if ( (setwd8[LA(1)]&0x8) ) {

+              }

+              else {zzFAIL(1,zzerr47,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp2);

+            }

+          }

+          {

+            zzBLOCK(zztasp2);

+            zzMake0;

+            {

+            if ( (LA(1)==114) ) {

+              zzmatch(114); zzCONSUME;

+              block( &toksrefd,&rulesrefd );

+              zzmatch(115);

+              blk = zzaRet = zzaArg(zztasp2,2);

+              /* MR23 */      CurBlockID_array[BlkLevel] = (-1);

+              /* MR23 */      CurAltNum_array[BlkLevel] = (-1);                

+              --BlkLevel;

+ zzCONSUME;

+

+              {

+                zzBLOCK(zztasp3);

+                zzMake0;

+                {

+                if ( (LA(1)==129) ) {

+                  zzmatch(129);

+                  zzaRet = makeLoop(zzaRet,approx,pFirstSetSymbol);

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (LA(1)==130) ) {

+                    zzmatch(130);

+                    zzaRet = makePlus(zzaRet,approx,pFirstSetSymbol);

+ zzCONSUME;

+

+                  }

+                  else {

+                    if ( (LA(1)==131) ) {

+                      zzmatch(131); zzCONSUME;

+                      {

+                        zzBLOCK(zztasp4);

+                        zzMake0;

+                        {

+                        if ( (setwd8[LA(1)]&0x10) ) {

+                          {

+                            zzBLOCK(zztasp5);

+                            zzMake0;

+                            {

+                            if ( (LA(1)==132) ) {

+                              zzmatch(132);

+                              ampersandStyle=0;

+ zzCONSUME;

+

+                            }

+                            else {

+                              if ( (LA(1)==113) ) {

+                                zzmatch(113);

+                                ampersandStyle=1;

+ zzCONSUME;

+

+                              }

+                              else {zzFAIL(1,zzerr48,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                            }

+                            zzEXIT(zztasp5);

+                            }

+                          }

+                          zzmatch(Pred);

+                          zzaRet = buildAction(LATEXT(1),action_file,action_line,1);

+ zzCONSUME;

+

+                          act = (ActionNode *) ((Junction *)zzaRet.left)->p1;

+                          semDepth=predicateLookaheadDepth(act);

+                          if (numericActionLabel) {             /* MR10 */

+                            list_add(&NumericPredLabels,act);   /* MR10 */

+                            numericActionLabel=0;               /* MR10 */

+                          };                                    /* MR10 */

+                          {

+                            zzBLOCK(zztasp5);

+                            zzMake0;

+                            {

+                            char *a;

+                            if ( (LA(1)==PassAction) ) {

+                              zzmatch(PassAction);

+                              

+                              a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char));

+                              require(a!=NULL, "rule element: cannot allocate predicate fail action");

+                              strcpy(a, LATEXT(1));

+                              act->pred_fail = a;

+ zzCONSUME;

+

+                            }

+                            else {

+                              if ( (setwd8[LA(1)]&0x20) ) {

+                              }

+                              else {zzFAIL(1,zzerr49,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                            }

+                            zzEXIT(zztasp5);

+                            }

+                          }

+                          if ( first_on_line) {                      /* MR7 */

+                            CurAltStart=(Junction *)zzaRet.left;         /* MR7 */

+                            altAdd(CurAltStart);                     /* MR7 */

+                          };

+                          _retv = (Node *)act;

+                          

+                          pred = computePredFromContextGuard(blk,&predMsgDone);           /* MR10 */

+                          if ( pred==NULL) {                                              /* MR10 */

+                            if ( !predMsgDone) err("invalid or missing context guard");   /* MR10 */

+                            predMsgDone=1;                                                /* MR10 */

+                          } else {                                                        /* MR10 */

+                            act->guardNodes=(Junction *)blk.left;                       /* MR11 */

+                            pred->expr = act->action;

+                            pred->source = act;

+                            /* MR10 */                  pred->ampersandStyle = ampersandStyle;  /* 0 means (g)? => ... 1 means (g)? && ... */

+                            /* MR13 */                  if (pred->tcontext != NULL) {

+                              /* MR13 */                    height=MR_max_height_of_tree(pred->tcontext);

+                              /* MR13 */                    equal_height=MR_all_leaves_same_height(pred->tcontext,height);

+                              /* MR13 */                    if (! equal_height) {

+                                /* MR13 */                       errFL("in guarded predicates all tokens in the guard must be at the same height",

+                                /* MR13 */                              FileStr[act->file],act->line);

+                                /* MR13 */                    };

+                              /* MR13 */                  }

+                            /* MR10 */                  if (ampersandStyle) {

+                              /* MR10 */			  		  act->ampersandPred = pred;

+                              /* MR11 */                    if (! HoistPredicateContext) {

+                                /* MR11 */                      errFL("without \"-prc on\" (guard)? && <<pred>>? ... doesn't make sense",

+                                /* MR11 */                              FileStr[act->file],act->line);

+                                /* MR11 */                    };

+                              /* MR10 */                  } else {

+                              /* MR10 */			  		  act->guardpred = pred;

+                              /* MR10 */                  };

+                            /* MR10 */                  if (pred->k != semDepth) {

+                              /* MR10 */                     warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)",

+                              /* MR10 */                                  pred->k,semDepth));

+                              /* MR10 */                  };

+                          }

+                        }

+                        else {

+                          if ( (setwd8[LA(1)]&0x40) ) {

+                            zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol);

+                            FoundGuessBlk = 1;

+                            ((Junction *) ((Junction *)zzaRet.left)->p1)->guess=1;

+                            if ( ! first_on_line ) {

+                              err("(...)? predicate must be first element of production");

+                            }

+                          }

+                          else {zzFAIL(1,zzerr50,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                        }

+                        zzEXIT(zztasp4);

+                        }

+                      }

+                    }

+                    else {

+                      if ( (setwd8[LA(1)]&0x80) ) {

+                        zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol);

+                      }

+                      else {zzFAIL(1,zzerr51,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                    }

+                  }

+                }

+                zzEXIT(zztasp3);

+                }

+              }

+              

+              if ( pred==NULL && !predMsgDone) {                                      /* MR10 */

+                ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID;

+                ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd;

+                ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd;

+                if (  first_on_line ) {                         /* MR7 */

+                  CurAltStart = (Junction *)((Junction *)((Junction *)zzaRet.left)->p1);  /* MR7 */

+                  altAdd(CurAltStart);                         /* MR7 */

+                };                                              /* MR7 */

+                _retv = (Node *) ((Junction *)zzaRet.left)->p1;

+              }

+            }

+            else {

+              if ( (LA(1)==102) ) {

+                zzmatch(102); zzCONSUME;

+                block( &toksrefd,&rulesrefd );

+                zzaRet = makeOpt(zzaArg(zztasp2,2),approx,pFirstSetSymbol);

+                /* MR23 */      CurBlockID_array[BlkLevel] = (-1);

+                /* MR23 */      CurAltNum_array[BlkLevel] = (-1);                

+                --BlkLevel;

+                zzmatch(98);

+                

+                ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID;

+                ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd;

+                ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd;

+ zzCONSUME;

+

+                if (  first_on_line ) {                            /* MR7 */

+                  CurAltStart = (Junction *) ((Junction *)((Junction *)zzaRet.left)->p1);  /* MR7 */

+                  altAdd(CurAltStart);                             /* MR7 */

+                };

+                _retv = (Node *) ((Junction *)zzaRet.left)->p1;

+              }

+              else {zzFAIL(1,zzerr52,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp2);

+            }

+          }

+        }

+        else {

+          if ( (LA(1)==129) ) {

+            zzmatch(129);

+            warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE;

+ zzCONSUME;

+

+          }

+          else {

+            if ( (LA(1)==130) ) {

+              zzmatch(130);

+              warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE;

+ zzCONSUME;

+

+            }

+            else {

+              if ( (LA(1)==105) ) {

+                zzmatch(105);

+                warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE;

+ zzCONSUME;

+

+              }

+              else {

+                if ( (LA(1)==PassAction) ) {

+                  zzmatch(PassAction);

+                  warn("[...] out of context 'rule > [...]'");

+                  CannotContinue=TRUE;

+ zzCONSUME;

+

+                }

+                else {zzFAIL(1,zzerr53,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+              }

+            }

+          }

+        }

+      }

+    }

+  }

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd9, 0x1);

+  return _retv;

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+default_exception_handler(void)

+#else

+default_exception_handler()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+   DefaultExGroup  = exception_group();

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd9, 0x2);

+  }

+}

+

+ExceptionGroup *

+#ifdef __USE_PROTOS

+exception_group(void)

+#else

+exception_group()

+#endif

+{

+  ExceptionGroup *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(ExceptionGroup *  ))

+  zzMake0;

+  {

+  ExceptionHandler *h; LabelEntry *label=NULL;	  /* MR6 */

+  FoundException = 1; FoundExceptionGroup = 1;

+  zzmatch(133);

+  _retv = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));

+ zzCONSUME;

+

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    char *p;

+    if ( (LA(1)==PassAction) ) {

+      zzmatch(PassAction);

+      

+      p = LATEXT(1)+1;

+      p[strlen(p)-1] = '\0';		/* kill trailing space */

+      label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1);

+      if ( label==NULL )

+      {

+        err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1));

+      }

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd9[LA(1)]&0x4) ) {

+      }

+      else {zzFAIL(1,zzerr54,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==135) ) {

+       h  = exception_handler();

+

+      list_add(&(_retv->handlers), (void *)h);

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==134) ) {

+      zzmatch(134); zzCONSUME;

+      zzmatch(106); zzCONSUME;

+      zzmatch(Action);

+      {

+        ExceptionHandler *eh = (ExceptionHandler *)

+        calloc(1, sizeof(ExceptionHandler));

+        char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+        require(eh!=NULL, "exception: cannot allocate handler");

+        require(a!=NULL, "exception: cannot allocate action");

+        strcpy(a, LATEXT(1));

+        eh->action = a;

+        eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char));

+        require(eh->signalname!=NULL, "exception: cannot allocate sig name");

+        strcpy(eh->signalname, "default");

+        list_add(&(_retv->handlers), (void *)eh);

+      }

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd9[LA(1)]&0x8) ) {

+      }

+      else {zzFAIL(1,zzerr55,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  if ( label!=NULL ) {

+    /* Record ex group in sym tab for this label */

+    if ( label->ex_group!=NULL ) {

+      err(eMsg1("duplicate exception handler for label '%s'",label->str));

+    } else {

+      label->ex_group = _retv;

+      /* Label the exception group itself */

+      _retv->label = label->str;

+      /* Make the labelled element pt to the exception also */

+      /* MR6 */	  if (label->elem == NULL) {

+        /* MR6 */	     err(eMsg1("reference in exception handler to undefined label '%s'",label->str));

+        /* MR6 */	  } else {

+        switch ( label->elem->ntype ) {

+          case nRuleRef :

+          {

+            RuleRefNode *r = (RuleRefNode *)label->elem;

+            r->ex_group = _retv;

+            break;

+          }

+          case nToken :

+          {

+            TokNode *t = (TokNode *)label->elem;

+            t->ex_group = _retv;

+            break;

+          }

+        } /* end switch */

+        /* MR6 */	  }; /* end test on label->elem */

+    } /* end test on label->ex_group */

+    

+		} /* end test on exception label */

+  

+/* MR7 */

+  /* MR7 */   if (BlkLevel == 1 && label == NULL) {

+    /* MR7 */     _retv->forRule=1;

+    /* MR7 */   } else if (label == NULL) {

+    /* MR7 */     _retv->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]);

+    /* MR7 */     egAdd(_retv);

+    /* MR7 */   } else {

+    /* MR7 */     _retv->labelEntry=label;

+    /* MR7 */   };

+  /* MR7 */

+  /* MR7 */	    /* You may want to remove this exc from the rule list  */

+  /* MR7 */		/* and handle at the labeled element site.             */

+  /* MR7 */

+  /* MR7 */   if (label != NULL) {

+    /* MR7 */     _retv = NULL;

+    /* MR7 */   };

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd9, 0x10);

+  return _retv;

+  }

+}

+

+ExceptionHandler *

+#ifdef __USE_PROTOS

+exception_handler(void)

+#else

+exception_handler()

+#endif

+{

+  ExceptionHandler *   _retv;

+  zzRULE;

+  zzBLOCK(zztasp1);

+  PCCTS_PURIFY(_retv,sizeof(ExceptionHandler *  ))

+  zzMake0;

+  {

+  ;

+  zzmatch(135);

+  

+  _retv = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler));

+  require(_retv!=NULL, "exception: cannot allocate handler");

+ zzCONSUME;

+

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==NonTerminal) ) {

+      zzmatch(NonTerminal);

+      

+      _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+      require(_retv->signalname!=NULL, "exception: cannot allocate sig name");

+      strcpy(_retv->signalname, LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==TokenTerm) ) {

+        zzmatch(TokenTerm);

+        

+        _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+        require(_retv->signalname!=NULL, "exception: cannot allocate sig name");

+        strcpy(_retv->signalname, LATEXT(1));

+ zzCONSUME;

+

+      }

+      else {zzFAIL(1,zzerr56,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(106); zzCONSUME;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    _retv->action = NULL;

+    if ( (LA(1)==Action) ) {

+      zzmatch(Action);

+      

+      _retv->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+      require(_retv->action!=NULL, "exception: cannot allocate action");

+      strcpy(_retv->action, LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd9[LA(1)]&0x20) ) {

+      }

+      else {zzFAIL(1,zzerr57,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzEXIT(zztasp1);

+  return _retv;

+fail:

+  zzEXIT(zztasp1);

+  CannotContinue=TRUE;  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd9, 0x40);

+  return _retv;

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+enum_file(char * fname)

+#else

+enum_file(fname)

+ char *fname ;

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  if ( (setwd9[LA(1)]&0x80) ) {

+    {

+      zzBLOCK(zztasp2);

+      zzMake0;

+      {

+      if ( (LA(1)==143) ) {

+        zzmatch(143); zzCONSUME;

+        zzmatch(ID); zzCONSUME;

+        {

+          zzBLOCK(zztasp3);

+          zzMake0;

+          {

+          if ( (LA(1)==149) ) {

+            zzmatch(149); zzCONSUME;

+            zzmatch(ID); zzCONSUME;

+          }

+          else {

+            if ( (setwd10[LA(1)]&0x1) ) {

+            }

+            else {zzFAIL(1,zzerr58,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+          zzEXIT(zztasp3);

+          }

+        }

+      }

+      else {

+        if ( (setwd10[LA(1)]&0x2) ) {

+        }

+        else {zzFAIL(1,zzerr59,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+      }

+      zzEXIT(zztasp2);

+      }

+    }

+    {

+      zzBLOCK(zztasp2);

+      zzMake0;

+      {

+      if ( (LA(1)==151) ) {

+        {

+          zzBLOCK(zztasp3);

+          int zzcnt=1;

+          zzMake0;

+          {

+          do {

+            enum_def(  fname );

+            zzLOOP(zztasp3);

+          } while ( (LA(1)==151) );

+          zzEXIT(zztasp3);

+          }

+        }

+      }

+      else {

+        if ( (LA(1)==149) ) {

+          defines(  fname );

+        }

+        else {zzFAIL(1,zzerr60,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+      }

+      zzEXIT(zztasp2);

+      }

+    }

+  }

+  else {

+    if ( (LA(1)==Eof) ) {

+    }

+    else {zzFAIL(1,zzerr61,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd10, 0x4);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+defines(char * fname)

+#else

+defines(fname)

+ char *fname ;

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  int v; int maxt=(-1); char *t;

+  {

+    zzBLOCK(zztasp2);

+    int zzcnt=1;

+    zzMake0;

+    {

+    do {

+      zzmatch(149); zzCONSUME;

+      zzmatch(ID);

+      t = mystrdup(LATEXT(1));

+ zzCONSUME;

+

+      zzmatch(INT);

+      

+      v = atoi(LATEXT(1));

+      /*			fprintf(stderr, "#token %s=%d\n", t, v);*/

+      

+	/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */

+      /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs            */

+      /* MR2 Don't let #tokdefs be confused by 			*/

+      /* MR2   DLGminToken and DLGmaxToken     			*/

+      

+			if ( ! isDLGmaxToken(t)) {		/* MR2 */

+      TokenNum = v;

+      if ( v>maxt ) maxt=v;

+      if ( Tnum( t ) == 0 ) {

+      addForcedTname( t, v );

+    } else {

+    warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline);

+  };

+};

+ zzCONSUME;

+

+      zzLOOP(zztasp2);

+    } while ( (LA(1)==149) );

+    zzEXIT(zztasp2);

+    }

+  }

+  TokenNum = maxt + 1;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd10, 0x8);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+enum_def(char * fname)

+#else

+enum_def(fname)

+ char *fname ;

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  int v= 0; int maxt=(-1); char *t;

+  zzmatch(151); zzCONSUME;

+  zzmatch(ID); zzCONSUME;

+  zzmatch(152); zzCONSUME;

+  zzmatch(ID);

+  t = mystrdup(LATEXT(1));

+ zzCONSUME;

+

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==153) ) {

+      zzmatch(153); zzCONSUME;

+      zzmatch(INT);

+      v=atoi(LATEXT(1));

+ zzCONSUME;

+

+    }

+    else {

+      if ( (setwd10[LA(1)]&0x10) ) {

+        v++;

+      }

+      else {zzFAIL(1,zzerr62,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  

+  /*			fprintf(stderr, "#token %s=%d\n", t, v);*/

+  TokenNum = v;

+  if ( v>maxt ) maxt=v;				/* MR3 */

+  if ( Tnum( t ) == 0 ) addForcedTname( t, v );

+  else {

+    warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline);

+  }

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==154) ) {

+      zzmatch(154); zzCONSUME;

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==ID)&&(isDLGmaxToken(LATEXT(1))) ) {

+          if (!(isDLGmaxToken(LATEXT(1)))            ) {zzfailed_pred("  isDLGmaxToken(LATEXT(1))",0 /* report */, { 0; /* no user action */ } );}

+          zzmatch(ID); zzCONSUME;

+          {

+            zzBLOCK(zztasp4);

+            zzMake0;

+            {

+            if ( (LA(1)==153) ) {

+              zzmatch(153); zzCONSUME;

+              zzmatch(INT); zzCONSUME;

+            }

+            else {

+              if ( (setwd10[LA(1)]&0x20) ) {

+              }

+              else {zzFAIL(1,zzerr63,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+            }

+            zzEXIT(zztasp4);

+            }

+          }

+        }

+        else {

+          if ( (LA(1)==ID) ) {

+            zzmatch(ID);

+            t = mystrdup(LATEXT(1));

+ zzCONSUME;

+

+            {

+              zzBLOCK(zztasp4);

+              zzMake0;

+              {

+              if ( (LA(1)==153) ) {

+                zzmatch(153); zzCONSUME;

+                zzmatch(INT);

+                v=atoi(LATEXT(1));

+ zzCONSUME;

+

+              }

+              else {

+                if ( (setwd10[LA(1)]&0x40) ) {

+                  v++;

+                }

+                else {zzFAIL(1,zzerr64,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+              }

+              zzEXIT(zztasp4);

+              }

+            }

+            

+            /*					fprintf(stderr, "#token %s=%d\n", t, v);*/

+            TokenNum = v;

+            if ( v>maxt ) maxt=v;				/* MR3 */

+            if ( Tnum( t ) == 0 ) addForcedTname( t, v );

+            else {

+              warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline);

+            }

+          }

+          else {

+            if ( (setwd10[LA(1)]&0x80) ) {

+            }

+            else {zzFAIL(1,zzerr65,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+          }

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(155); zzCONSUME;

+  zzmatch(156);

+  TokenNum = maxt + 1;

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd11, 0x1);

+  }

+}

+

+

+/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */

+/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs            */

+/* MR2 Don't let #tokdefs be confused by 			*/

+/* MR2   DLGminToken and DLGmaxToken     			*/

+

+/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */

+

+#ifdef __USE_PROTOS

+static int isDLGmaxToken(char *Token)

+#else

+static int isDLGmaxToken(Token)

+char *	Token;

+#endif

+{

+static char checkStr1[] = "DLGmaxToken";

+static char checkStr2[] = "DLGminToken";

+

+   if (strcmp(Token, checkStr1) == 0)

+return 1;

+else if (strcmp(Token, checkStr2) == 0)

+return 1;

+else

+return 0;

+}

+

+/* semantics of #token */

+static void

+#ifdef __USE_PROTOS

+chkToken(char *t, char *e, char *a, int tnum)

+#else

+chkToken(t,e,a,tnum)

+char *t, *e, *a;

+int tnum;

+#endif

+{

+TermEntry *p;

+

+	/* check to see that they don't try to redefine a token as a token class */

+if ( t!=NULL ) {

+p = (TermEntry *) hash_get(Tname, t);

+if ( p!=NULL && p->classname ) {

+  err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t));

+  if ( a!=NULL ) free((char *)a);

+  return;

+}

+}

+

+	if ( t==NULL && e==NULL ) {			/* none found */

+err("#token requires at least token name or rexpr");

+}

+else if ( t!=NULL && e!=NULL ) {	/* both found */

+if ( UserDefdTokens ) {			/* if #tokdefs, must not define new */

+  p = (TermEntry *) hash_get(Tname, t);

+  if ( p == NULL) {

+    err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));

+    return;

+  };

+}

+Tklink(t, e);

+if ( a!=NULL ) {

+  if ( hasAction(e) ) {

+    err(eMsg1("redefinition of action for %s; ignored",e));

+  }

+  else setHasAction(e, a);

+}

+}

+else if ( t!=NULL ) {				/* only one found */

+if ( UserDefdTokens ) {

+  p = (TermEntry *) hash_get(Tname, t);

+  if (p == NULL) {

+    err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));

+  };

+  return;

+}

+if ( Tnum( t ) == 0 ) addTname( t );

+else {

+  err(eMsg1("redefinition of token %s; ignored",t));

+}

+if ( a!=NULL ) {

+  err(eMsg1("action cannot be attached to a token name (%s); ignored",t));

+  free((char *)a);

+}

+}

+else if ( e!=NULL ) {

+if ( Tnum( e ) == 0 ) addTexpr( e );

+else {

+  if ( hasAction(e) ) {

+    err(eMsg1("redefinition of action for expr %s; ignored",e));

+  }

+  else if ( a==NULL ) {

+    err(eMsg1("redefinition of expr %s; ignored",e));

+  }

+}

+if ( a!=NULL ) setHasAction(e, a);

+}

+

+	/* if a token type number was specified, then add the token ID and 'tnum'

+* pair to the ForcedTokens list.  (only applies if an id was given)

+*/

+if ( t!=NULL && tnum>0 )

+{

+if ( set_el(tnum, reserved_positions) )

+{

+  err(eMsgd("a token has already been forced to token number %d; ignored", tnum));

+}

+else

+{

+  list_add(&ForcedTokens, newForcedToken(t,tnum));

+  set_orel(tnum, &reserved_positions);

+}

+}

+}

+

+static int

+#ifdef __USE_PROTOS

+match_token(char *s, char **nxt)

+#else

+match_token(s,nxt)

+char *s;

+char **nxt;

+#endif

+{

+  if ( !(*s>='A' && *s<='Z') ) return 0;

+  s++;

+  while ( (*s>='a' && *s<='z') ||

+  (*s>='A' && *s<='Z') ||

+  (*s>='0' && *s<='9') ||

+  *s=='_' )

+  {

+    s++;

+  }

+  if ( *s!=' ' && *s!='}' ) return 0;

+  *nxt = s;

+  return 1;

+}

+

+static int

+#ifdef __USE_PROTOS

+match_rexpr(char *s, char **nxt)

+#else

+match_rexpr(s,nxt)

+char *s;

+char **nxt;

+#endif

+{

+  if ( *s!='"' ) return 0;

+  s++;

+  while ( *s!='"' )

+  {

+    if ( *s=='\n' || *s=='\r' )                   /* MR13 */

+    warn("eoln found in regular expression");

+    if ( *s=='\\' ) s++;

+    s++;

+  }

+  *nxt = s+1;

+  return 1;

+}

+

+/*

+* Walk a string "{ A .. Z }" where A..Z is a space separated list

+* of token references (either labels or reg exprs).  Return a

+* string "inlineX_set" for some unique integer X.  Basically,

+* we pretend as if we had seen "#tokclass inlineX { A .. Z }"

+* on the input stream outside of an action.

+*/

+char *

+#ifdef __USE_PROTOS

+inline_set(char *s)

+#else

+inline_set(s)

+char *s;

+#endif

+{

+  char *nxt;

+  fprintf(stderr, "found consumeUntil( {...} )\n");

+  while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}

+  if ( *s!='{' )

+  {

+    err("malformed consumeUntil( {...} ); missing '{'");

+    return "bad_set";

+  }

+  s++;

+  while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}

+  while ( *s!='}' )

+  {

+    if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s);

+    else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s);

+    else {

+      err("invalid element in consumeUntil( {...} )");

+      return "bad_set";

+    }

+    s = nxt;

+    while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}

+  }

+  return "inlineX_set";

+}

+

+/* ANTLR-specific syntax error message generator

+* (define USER_ZZSYN when compiling so don't get 2 definitions)

+*/

+void

+#ifdef __USE_PROTOS

+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok,

+int k, char *bad_text)

+#else

+zzsyn(text, tok, egroup, eset, etok, k, bad_text)

+char *text, *egroup, *bad_text;

+int tok;

+int etok;

+int k;

+SetWordType *eset;

+#endif

+{

+fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline);

+fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);

+if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}

+if ( k==1 ) fprintf(stderr, " missing");

+else

+{

+fprintf(stderr, "; \"%s\" not", bad_text);

+if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");

+}

+if ( zzset_deg(eset)>0 ) zzedecode(eset);

+else fprintf(stderr, " %s", zztokens[etok]);

+if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);

+fprintf(stderr, "\n");

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.g b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.g
new file mode 100644
index 0000000..e6eda60
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.g
@@ -0,0 +1,2586 @@
+/*

+ * antlr.g	--	PCCTS Version 1.xx ANTLR

+ *

+ * Parse an antlr input grammar and build a syntax-diagram.

+ *

+ * Written in itself (needs at least 1.06 to work)

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-1995

+ */

+

+/* MR1									*/

+/* MR1 10-Apr-97 MR1	Replace #if logic with #include "pcctscfg.h"	*/

+/* MR1									*/

+

+#header <<

+	#include "pcctscfg.h"

+	#include "set.h"

+	#include <ctype.h>

+	#include "syn.h"

+	#include "hash.h"

+	#include "generic.h"

+	#define zzcr_attr(attr,tok,t)

+	>>

+

+<<

+

+/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */

+#if defined(__TURBOC__)

+#pragma warn -aus  /* unused assignment of 'xxx' */

+#endif

+

+

+#ifdef __USE_PROTOS

+static void chkToken(char *, char *, char *, int);

+#else

+static void chkToken();

+#endif

+

+#ifdef __USE_PROTOS

+static int isDLGmaxToken(char *Token);				     /* MR3 */

+#else

+static int isDLGmaxToken();				                             /* MR3 */

+#endif

+

+static int class_nest_level = 0;

+

+/* MR20 G. Hobbelt extern definitions moved to antlr.h */

+

+>>

+

+#lexaction <<

+/* maintained, but not used for now */

+set AST_nodes_refd_in_actions = set_init;

+int inAlt = 0;

+set attribsRefdFromAction = set_init; /* MR20 */

+int UsedOldStyleAttrib = 0;

+int UsedNewStyleLabel = 0;

+#ifdef __USE_PROTOS

+char *inline_set(char *);

+#else

+char *inline_set();

+#endif

+

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	    */

+/* MR1					in DLG action			                    */

+

+int tokenActionActive=0;                                            /* MR1 */

+

+>>

+

+#lexclass STRINGS

+#token QuotedTerm "\""		<< zzmode(START); >>

+#token "\n|\r|\r\n"     	<<

+							zzline++;

+							warn("eoln found in string");

+							zzskip();

+							>>

+#token "\\(\n|\r|\r\n)"		<< zzline++; zzmore(); >>

+#token "\\~[]"				<< zzmore(); >>

+#token "~[\n\r\"\\]+"		<< zzmore(); >>

+

+#lexclass ACTION_STRINGS

+#token "\""					<< zzmode(ACTIONS); zzmore(); >>

+#token "\n|\r|\r\n"			<<

+							zzline++;

+							warn("eoln found in string (in user action)");

+							zzskip();

+							>>

+#token "\\(\n|\r|\r\n)"		<< zzline++; zzmore(); >>

+#token "\\~[]"				<< zzmore(); >>

+#token "~[\n\r\"\\]+"			<< zzmore(); >>

+

+#lexclass ACTION_CHARS

+#token "'"					<< zzmode(ACTIONS); zzmore(); >>

+#token "\n|\r|\r\n"			<<

+							zzline++;

+							warn("eoln found in char literal (in user action)");

+							zzskip();

+							>>

+#token "\\~[]"				<< zzmore(); >>

+#token "~[\n\r'\\]+"		<< zzmore(); >>

+

+#lexclass ACTION_COMMENTS

+#token "\*/"				<< zzmode(ACTIONS); zzmore(); >>

+#token "\*"					<< zzmore(); >>

+#token "\n|\r|\r\n"			<< zzline++; zzmore(); DAWDLE; >>

+#token "~[\n\r\*]+"			<< zzmore(); >>

+

+#lexclass TOK_DEF_COMMENTS

+#token "\*/"				<< zzmode(PARSE_ENUM_FILE);

+                              zzmore(); >>

+#token "\*"					<< zzmore(); >>

+#token "\n|\r|\r\n"			<< zzline++; zzmore(); DAWDLE; >>

+#token "~[\n\r\*]+"			<< zzmore(); >>

+

+#lexclass TOK_DEF_CPP_COMMENTS

+#token "\n|\r|\r\n"			<< zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >>

+#token "~[\n\r]+"			<< zzskip(); >>

+

+#lexclass ACTION_CPP_COMMENTS

+#token "\n|\r|\r\n"			<< zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >>

+#token "~[\n\r]+"			<< zzmore(); >>

+

+#lexclass CPP_COMMENTS

+#token "\n|\r|\r\n"			<< zzline++; zzmode(START); zzskip(); DAWDLE; >>

+#token "~[\n\r]+"			<< zzskip(); >>

+

+#lexclass COMMENTS

+#token "\*/"				<< zzmode(START); zzskip(); >>

+#token "\*"					<< zzskip(); >>

+#token "\n|\r|\r\n"			<< zzline++; zzskip(); DAWDLE; >>

+#token "~[\n\r\*]+"			<< zzskip(); >>

+

+/*

+ * This lexical class accepts actions of type [..] and <<..>>

+ *

+ * It translates the following special items for C:

+ *

+ * $j		--> "zzaArg(current zztasp, j)"

+ * $i.j		--> "zzaArg(zztaspi, j)"

+ * $i.nondigit> "zzaArg(current zztasp, i).nondigit"

+ * $$		--> "zzaRet"

+ * $alnum	--> "alnum"			(used to ref parameters)

+ * $rule	--> "zzaRet"

+ * $retval	--> "_retv.retval" if > 1 return values else "_retv"

+ * $[token, text] --> "zzconstr_attr(token, text)"

+ * $[]		--> "zzempty_attr()"

+ *

+ * It translates the following special items for C++:

+ * (attributes are now stored with 'Token' and $i's are only

+ *  pointers to the Tokens.  Rules don't have attributes now.)

+ *

+ * $j		--> "_tbj" where b is the block level

+ * $i.j		--> "_tij"

+ * $j->nondigit> "_tbj->nondigit"

+ * $$		--> "$$"

+ * $alnum	--> "alnum"			(used to ref parameters)

+ * $rule	--> "$rule"

+ * $retval	--> "_retv.retval" if > 1 return values else "_retv"

+ * $[token, text] --> invalid

+ * $[]		--> invalid

+ *

+ * And, for trees:

+ *

+ * #0		-->	"(*_root)"

+ * #i		--> "zzastArg(i)"

+ * #[args]	--> "zzmk_ast(zzastnew(), args)"

+ * #[]		--> "zzastnew()"

+ * #( root, child1, ..., childn )

+ *			--> "zztmake(root, child1, ...., childn, NULL)"

+ * #()		--> "NULL"

+ *

+ * For C++, ...

+ *

+ * #0		-->	"(*_root)"

+ * #i		--> "_astbi" where b is the block level

+ * #alnum	--> "alnum_ast"	(used to ref #label)

+ * #[args]	--> "new AST(args)"

+ * #[]		--> "new AST"

+ * #( root, child1, ..., childn )

+ *			--> "AST::tmake(root, child1, ...., childn, NULL)"

+ * #()		--> "NULL"

+ *

+ * To escape,

+ *

+ * \]		--> ]

+ * \)		--> )

+ * \$		--> $

+ * \#		--> #

+ *

+ * A stack is used to nest action terminators because they can be nested

+ * like crazy:  << #[$[..],..] >>

+ */

+#lexclass ACTIONS

+#token Action "\>\>"        << /* these do not nest */

+                              zzmode(START);

+                              NLATEXT[0] = ' ';

+                              NLATEXT[1] = ' ';

+                              zzbegexpr[0] = ' ';

+                              zzbegexpr[1] = ' ';

+							  if ( zzbufovf ) {

+								err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));

+							  }

+

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	*/

+/* MR1					in DLG action			*/

+/* MR1			Doesn't matter what kind of action it is - reset*/

+

+			      tokenActionActive=0;		 /* MR1 */

+                            >>

+#token Pred "\>\>?"			<< /* these do not nest */

+                              zzmode(START);

+                              NLATEXT[0] = ' ';

+                              NLATEXT[1] = ' ';

+                              zzbegexpr[0] = '\0';

+							  if ( zzbufovf ) {

+								err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));

+							  };

+#ifdef __cplusplus__

+/* MR10 */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+#ifdef __STDC__

+/* MR10 */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+#ifdef __USE_PROTOS

+/* MRxx */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+/* MR10 */                    list_apply(CurActionLabels,mark_label_used_in_sem_pred);

+#endif

+#endif

+#endif

+                            >>

+#token PassAction "\]"		<< if ( topint() == ']' ) {

+								  popint();

+								  if ( istackempty() )	/* terminate action */

+								  {

+									  zzmode(START);

+									  NLATEXT[0] = ' ';

+									  zzbegexpr[0] = ' ';

+									  if ( zzbufovf ) {

+										err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));

+									  }

+								  }

+								  else {

+									  /* terminate $[..] and #[..] */

+									  if ( GenCC ) zzreplstr("))");

+									  else zzreplstr(")");

+									  zzmore();

+								  }

+							   }

+							   else if ( topint() == '|' ) { /* end of simple [...] */

+								  popint();

+								  zzmore();

+							   }

+							   else zzmore();

+							>>

+#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)"

+   							<<

+   							zzmore();

+							zzreplstr(inline_set(zzbegexpr+

+									  strlen("consumeUntil(")));

+							>>

+#token "consumeUntil\( ~[\)]+ \)"

+							<< zzmore(); >>

+#token "\n|\r|\r\n"			<< zzline++; zzmore(); DAWDLE; >>

+#token "\>"					<< zzmore(); >>

+#token "$"					<< zzmore(); >>

+#token "$$"					<< if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}

+							   else err("$$ use invalid in C++ mode"); >>

+

+#token "$\[\]"				<< if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}

+							   else err("$[] use invalid in C++ mode"); >>

+#token "$\["				<<

+							pushint(']');

+							if ( !GenCC ) zzreplstr("zzconstr_attr(");

+							else err("$[..] use invalid in C++ mode");

+							zzmore();

+							>>

+#token "$[0-9]+"			<<{

+							static char buf[100];

+                            numericActionLabel=1;       /* MR10 */

+							if ( strlen(zzbegexpr)>(size_t)85 )

+								fatal("$i attrib ref too big");

+							set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);

+							if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",

+										BlkLevel-1,zzbegexpr+1);

+							else sprintf(buf,"_t%d%s",

+										BlkLevel-1,zzbegexpr+1);

+							zzreplstr(buf);

+							zzmore();

+							UsedOldStyleAttrib = 1;

+							if ( UsedNewStyleLabel )

+								err("cannot mix old-style $i with new-style labels");

+							}

+							>>

+#token "$[0-9]+."			<<{

+							static char buf[100];

+                            numericActionLabel=1;       /* MR10 */

+							if ( strlen(zzbegexpr)>(size_t)85 )

+								fatal("$i.field attrib ref too big");

+							zzbegexpr[strlen(zzbegexpr)-1] = ' ';

+							set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);

+							if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",

+										BlkLevel-1,zzbegexpr+1);

+							else sprintf(buf,"_t%d%s.",

+										BlkLevel-1,zzbegexpr+1);

+							zzreplstr(buf);

+							zzmore();

+							UsedOldStyleAttrib = 1;

+							if ( UsedNewStyleLabel )

+								err("cannot mix old-style $i with new-style labels");

+							}

+							>>

+#token "$[0-9]+.[0-9]+"		<<{

+							static char buf[100];

+							static char i[20], j[20];

+							char *p,*q;

+                            numericActionLabel=1;       /* MR10 */

+							if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");

+							for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {

+								if ( q == &i[20] )

+									 fatalFL("i of $i.j attrib ref too big",

+											 FileStr[CurFile], zzline );

+								*q++ = *p;

+							}

+							*q = '\0';

+							for (p++, q= &j[0]; *p!='\0'; p++) {

+								if ( q == &j[20] )

+									fatalFL("j of $i.j attrib ref too big",

+											FileStr[CurFile], zzline );

+								*q++ = *p;

+							}

+							*q = '\0';

+							if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);

+							else sprintf(buf,"_t%s%s",i,j);

+							zzreplstr(buf);

+							zzmore();

+							UsedOldStyleAttrib = 1;

+							if ( UsedNewStyleLabel )

+								err("cannot mix old-style $i with new-style labels");

+							}

+							>>

+#token "$[_a-zA-Z][_a-zA-Z0-9]*"

+							<<{ static char buf[300]; LabelEntry *el;

+							zzbegexpr[0] = ' ';

+							if ( CurRule != NULL &&

+								 strcmp(CurRule, &zzbegexpr[1])==0 ) {

+								if ( !GenCC ) zzreplstr("zzaRet");

+							}

+							else if ( CurRetDef != NULL &&

+									  strmember(CurRetDef, &zzbegexpr[1])) {

+								 if ( hasMultipleOperands( CurRetDef ) ) {

+									require (strlen(zzbegexpr)<=(size_t)285,

+											 "$retval attrib ref too big");

+									sprintf(buf,"_retv.%s",&zzbegexpr[1]);

+									zzreplstr(buf);

+								}

+								else zzreplstr("_retv");

+							}

+							else if ( CurParmDef != NULL &&

+									  strmember(CurParmDef, &zzbegexpr[1])) {

+								;

+							}

+							else if ( Elabel==NULL ) {

+								{ err("$-variables in actions outside of rules are not allowed"); }

+							} else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {

+/* MR10 */

+/* MR10 */                      /* element labels might exist without an elem when */

+/* MR10 */                      /*  it is a forward reference (to a rule)          */

+/* MR10 */

+/* MR10 */						if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )

+/* MR10 */							{ err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }

+/* MR10 */

+/* MR10 */						if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {

+/* MR10 */                          err("You can no longer use attributes returned by rules when also using ASTs");

+/* MR10 */                          err("   Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")");

+/* MR10 */                      };

+/* MR10 */

+/* MR10 */                      /* keep track of <<... $label ...>> for semantic predicates in guess mode */

+/* MR10 */                      /* element labels contain pointer to the owners node                      */

+/* MR10 */

+/* MR10 */                      if (el->elem != NULL && el->elem->ntype == nToken) {

+/* MR10 */                        list_add(&CurActionLabels,el);

+/* MR10 */                      };

+							}

+							else

+								warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));

+							}

+							zzmore();

+							>>

+#token "#0"					<< zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >>

+#token "#\[\]"				<< if ( GenCC ) {

+                                    if (NewAST) zzreplstr("(newAST)");

+                                        else zzreplstr("(new AST)");}

+							   else {zzreplstr("zzastnew()");} zzmore();

+							   chkGTFlag();

+							>>

+#token "#\(\)"				<< zzreplstr("NULL"); zzmore(); chkGTFlag(); >>

+#token "#[0-9]+"			<<{

+							static char buf[100];

+							if ( strlen(zzbegexpr)>(size_t)85 )

+								fatal("#i AST ref too big");

+							if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);

+							else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);

+							zzreplstr(buf);

+							zzmore();

+							set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);

+							chkGTFlag();

+ 							}

+							>>

+

+/* MR14 Arpad Beszedes  26-May-98

+        Add support for #line directives when antlr source is pre-processed

+        #lexclass ACTIONS

+*/

+

+#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)"

+        <<

+        zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();

+        getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);

+        >>

+

+#token "#line ~[\n\r]* (\n|\r|\r\n)"

+        <<

+        zzline++; zzmore();

+        >>

+

+/* MR14 end of a block to support #line in antlr source code */

+

+#token "#[_a-zA-Z][_a-zA-Z0-9]*"

+							<<

+							if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||

+								 strcmp(zzbegexpr, "#if")==0 ||

+								 strcmp(zzbegexpr, "#else")==0 ||

+								 strcmp(zzbegexpr, "#endif")==0 ||

+								 strcmp(zzbegexpr, "#ifndef")==0 ||

+								 strcmp(zzbegexpr, "#define")==0 ||

+								 strcmp(zzbegexpr, "#pragma")==0 ||

+								 strcmp(zzbegexpr, "#undef")==0 ||

+								 strcmp(zzbegexpr, "#import")==0 ||

+								 strcmp(zzbegexpr, "#line")==0 ||

+								 strcmp(zzbegexpr, "#include")==0 ||

+								 strcmp(zzbegexpr, "#error")==0) )

+							{

+								static char buf[100];

+								sprintf(buf, "%s_ast", zzbegexpr+1);

+/* MR27 */						list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));

+								zzreplstr(buf);

+								chkGTFlag();

+							}

+							zzmore();

+							>>

+#token "#\["				<<

+							pushint(']');

+							if ( GenCC ) {

+                                if (NewAST) zzreplstr("(newAST(");

+                                    else zzreplstr("(new AST("); }

+							else zzreplstr("zzmk_ast(zzastnew(),");

+							zzmore();

+							chkGTFlag();

+							>>

+#token "#\("				<<

+							pushint('}');

+							if ( GenCC ) {

+								if (tmakeInParser) {

+									zzreplstr("tmake(");

+								}

+								else {

+									zzreplstr("ASTBase::tmake(");

+								}

+							}

+							else {

+								zzreplstr("zztmake(");

+							}

+							zzmore();

+							chkGTFlag();

+							>>

+#token "#"					<< zzmore(); >>

+#token "\)"					<<

+							if ( istackempty() )

+								zzmore();

+							else if ( topint()==')' ) {

+								popint();

+							}

+							else if ( topint()=='}' ) {

+								popint();

+								/* terminate #(..) */

+								zzreplstr(", NULL)");

+							}

+							zzmore();

+							>>

+#token "\["					<<

+							pushint('|');	/* look for '|' to terminate simple [...] */

+							zzmore();

+							>>

+#token "\("					<<

+							pushint(')');

+							zzmore();

+							>>

+

+#token "\\\]"				<< zzreplstr("]");  zzmore(); >>

+#token "\\\)"				<< zzreplstr(")");  zzmore(); >>

+

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	*/

+/* MR1					in DLG action			*/

+

+#token "\\>"	<< if (! tokenActionActive) zzreplstr(">");	 /* MR1 */

+		   zzmore();				         /* MR1 */

+		>>					         /* MR1	*/

+

+

+#token "'"					<< zzmode(ACTION_CHARS); zzmore();>>

+#token "\""					<< zzmode(ACTION_STRINGS); zzmore();>>

+#token "\\$"				<< zzreplstr("$");  zzmore(); >>

+#token "\\#"				<< zzreplstr("#");  zzmore(); >>

+#token "\\(\n|\r|\r\n)"		<< zzline++; zzmore(); >>

+#token "\\~[\]\)>$#]"		<< zzmore(); >> /* escaped char, always ignore */

+#token "/"					<< zzmore(); >>

+#token "/\*"				<< zzmode(ACTION_COMMENTS); zzmore(); >>

+#token "\*/"				<< warn("Missing /*; found dangling */ in action"); zzmore(); >>

+#token "//"					<< zzmode(ACTION_CPP_COMMENTS); zzmore(); >>

+#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >>

+

+#lexclass START

+#token "[\t\ ]+"			<< zzskip(); >>				/* Ignore White */

+#token "\n|\r|\r\n"	   		<< zzline++; zzskip(); >>	/* Track Line # */

+#token "\["                 << zzmode(ACTIONS); zzmore();

+                               istackreset();

+                               pushint(']'); >>

+#token "\<\<"               << action_file=CurFile; action_line=zzline;

+                               zzmode(ACTIONS); zzmore();

+                               list_free(&CurActionLabels,0);       /* MR10 */

+                               numericActionLabel=0;                /* MR10 */

+                               istackreset();

+                               pushint('>'); >>

+#token "\""					<< zzmode(STRINGS); zzmore(); >>

+#token "/\*"				<< zzmode(COMMENTS); zzskip(); >>

+#token "\*/"				<< warn("Missing /*; found dangling */"); zzskip(); >>

+#token "//"					<< zzmode(CPP_COMMENTS); zzskip(); >>

+

+/* MR14 Arpad Beszedes  26-May-98

+        Add support for #line directives when antlr source is pre-processed

+        #lexclass START

+*/

+

+#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)"

+        <<

+        zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();

+        getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);

+        >>

+

+#token "#line ~[\n\r]* (\n|\r|\r\n)"

+        <<

+        zzline++; zzmore();

+        >>

+

+/* MR14 end of a block to support #line in antlr source code */

+

+/*                                                                          */

+/*  8-Apr-97	Regularize escape sequence for ">>"                         */

+/*			appearing in string literals                                    */

+/*                                                                          */

+

+#token "\>\>"			<< warn("Missing <<; found dangling \>\>"); zzskip(); >> /* MR1 */

+#token WildCard "."

+#token "\@"			<<FoundException = 1;		/* MR6 */

+    				  FoundAtOperator = 1;>>	/* MR6 */

+#token Eof					"@"

+							<<	/* L o o k  F o r  A n o t h e r  F i l e */

+							{

+							FILE *new_input;

+							new_input = NextFile();

+							if ( new_input == NULL ) { NLA=Eof; return; }

+							fclose( input );

+							input = new_input;

+							zzrdstream( input );

+							zzskip();	/* Skip the Eof (@) char i.e continue */

+							}

+							>>

+

+#token LABEL

+

+#errclass "grammar-element" { element }

+#errclass "meta-symbol"		{ "\}" "!" ";" "\|" "\~" "^" "\)" }

+

+#token Pragma			"{\\}#pragma"			/* MR21 */

+#token FirstSetSymbol	"{\\}#FirstSetSymbol"	/* MR21 */

+/*

+ * Get a grammar -- Build a list of rules like:

+ *

+ *	o-->Rule1--o

+ *	|

+ *	o-->Rule2--o

+ *	|

+ *	...

+ *	|

+ *	o-->RuleN--o

+ */

+

+/* rule grammar */

+

+grammar :	<<Graph g;>>

+			(	"{\\}#header" Action    /* MR13 */

+				<<

+				if ( HdrAction==NULL ) {

+				HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+				require(HdrAction!=NULL, "rule grammar: cannot allocate header action");

+				strcpy(HdrAction, LATEXT(1));

+				}

+				else warn("additional #header statement ignored");

+				>>

+            |   "{\\}#first" Action

+				<<

+    				if ( FirstAction==NULL ) {

+        				FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+        				require(FirstAction!=NULL, "rule grammar: cannot allocate #first action");

+        				strcpy(FirstAction, LATEXT(1));

+    				} else {

+                        warn("additional #first statement ignored");

+                    };

+				>>

+

+			|	"{\\}#parser" QuotedTerm

+				<<

+				if ( GenCC ) {

+					warn("#parser meta-op incompatible with -CC; ignored");

+				}

+				else {

+					if ( strcmp(ParserName,"zzparser")==0 ) {

+						ParserName=StripQuotes(mystrdup(LATEXT(1)));

+						if ( RulePrefix[0]!='\0' )

+						{

+							warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored");

+							RulePrefix[0]='\0';

+						}

+					}

+					else warn("additional #parser statement ignored");

+				}

+				>>

+			|	"{\\}#tokdefs" QuotedTerm

+				<<{

+				char *fname;

+				zzantlr_state st; FILE *f; struct zzdlg_state dst;

+				UserTokenDefsFile = mystrdup(LATEXT(1));

+				zzsave_antlr_state(&st);

+				zzsave_dlg_state(&dst);

+				fname = mystrdup(LATEXT(1));

+				f = fopen(StripQuotes(fname), "r");

+				if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));}

+				else {

+					ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE);

+					UserDefdTokens = 1;

+				}

+				zzrestore_antlr_state(&st);

+				zzrestore_dlg_state(&dst);

+				}>>

+			)*

+			(	Action

+				<<{

+				UserAction *ua = newUserAction(LATEXT(1));

+				ua->file = action_file; ua->line = action_line;

+				if ( class_nest_level>0 ) list_add(&class_before_actions, ua);

+				else list_add(&BeforeActions, ua);

+				}>>

+			|	laction

+			|	lmember				/* MR1 */

+			|	lprefix				/* MR1 */

+			|	aLexclass

+			|	token

+			|	error

+			|	tclass

+            |   aPred               /* MR11 */

+			|	default_exception_handler

+			|	class_def

+			|	"\}"

+				<<

+				if ( class_nest_level==0 )

+					warn("missing class definition for trailing '}'");

+				class_nest_level--;

+				>>

+			)*

+            

+			rule		<<g=$3; SynDiag = (Junction *) $3.left;>>

+			(	rule

+

+                	<<if ( $1.left!=NULL ) {

+                        g.right = NULL;

+

+/* MR21a */             /*  Avoid use of a malformed graph when CannotContinue */

+/* MR21a */             /*  is already set                                     */

+/* MR21a */

+/* MR21a */             if (! (CannotContinue && g.left == NULL)) {

+/* MR21a */               g = Or(g, $1);

+/* MR21a */             }

+/* MR21a */		      }

+                    >>

+

+			|	aLexclass

+			|	token

+			|	error

+			|	tclass

+            |   aPred               /* MR11 */

+			|	class_def

+			|	"\}"

+				<<

+				if ( class_nest_level==0 )

+					warn("missing class definition for trailing '}'");

+				class_nest_level--;

+				>>

+			)*

+			(	Action

+				<<{

+				UserAction *ua = newUserAction(LATEXT(1));

+				ua->file = action_file; ua->line = action_line;

+				if ( class_nest_level>0 ) list_add(&class_after_actions, ua);

+				else list_add(&AfterActions, ua);

+				}>>

+			|	laction

+			|	lmember				/* MR1 */

+			|	lprefix				/* MR1 */

+			|	error

+			|	tclass

+			|	class_def

+            |   aPred               /* MR11 */

+			|	"\}"

+				<<

+				if ( class_nest_level==0 )

+					warn("missing class definition for trailing '}'");

+				class_nest_level--;

+				>>

+			)*

+			Eof

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule class_def */

+

+class_def

+	:	<<int go=1; char name[MaxRuleName+1];>>

+		"class"

+		(	NonTerminal		<<if(go) strncpy(name,LATEXT(1),MaxRuleName);>>

+		|	TokenTerm		<<if(go) strncpy(name,LATEXT(1),MaxRuleName);>>

+		)

+		<<

+		if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0

+			 && GenCC ) {

+			err("only one grammar class allowed in this release");

+			go = 0;

+		}

+		else strcpy(CurrentClassName, name);

+		>>

+		<<if ( !GenCC ) { err("class meta-op used without C++ option"); }>>

+

+/* MR10 */  (~ "\{"

+/* MR10 */            <<if (ClassDeclStuff == NULL) {

+/* MR10 */                   ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char));

+/* MR10 */              };

+/* MR10 */              strncat(ClassDeclStuff," ",MaxClassDeclStuff);

+/* MR10 */              strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff);

+/* MR22 */              do {

+/* MR22 */                if (0 == strcmp(LATEXT(1),"public")) break;

+/* MR22 */                if (0 == strcmp(LATEXT(1),"private")) break;

+/* MR22 */                if (0 == strcmp(LATEXT(1),"protected")) break;

+/* MR22 */                if (0 == strcmp(LATEXT(1),"virtual")) break;

+/* MR22 */                if (0 == strcmp(LATEXT(1),",")) break;

+/* MR22 */                if (0 == strcmp(LATEXT(1),":")) break;

+/* MR22 */                if (BaseClassName != NULL) break;

+/* MR22 */                BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char));

+/* MR22 */                require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name");

+/* MR22 */				  strcpy(BaseClassName,LATEXT(1));

+/* MR22 */              } while (0);

+/* MR10 */            >>

+/* MR10 */  )*

+

+		"\{"

+		<<

+		no_classes_found = 0;

+		if ( class_nest_level>=1 ) {warn("cannot have nested classes");}

+		else class_nest_level++;

+		>>

+	;

+	<<CannotContinue=TRUE;>>

+

+/*

+ * Build -o-->o-R-o-->o-	where -o-R-o- is the block from rule 'block'.

+ * Construct the RuleBlk front and EndRule node on the end of the

+ * block.  This is used to add FOLLOW pointers to the rule end.  Add the

+ * new rule name to the Rname hash table and sets its rulenum.

+ * Store the parameter definitions if any are found.

+ *

+ * Note that locks are required on the RuleBlk and EndRule nodes to thwart

+ * infinite recursion.

+ *

+ * Return the left graph pointer == NULL to indicate error/dupl rule def.

+ */

+

+/* rule rule */

+

+rule	:	<<

+

+			ExceptionGroup *eg;

+			RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e;

+			set toksrefd, rulesrefd;

+			char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL;

+			CurExGroups = NULL;

+			CurElementLabels = NULL;

+			CurAstLabelsInActions = NULL; /* MR27 */

+			/* We want a new element label hash table for each rule */

+			if ( Elabel!=NULL ) killHashTable(Elabel);

+			Elabel = newHashTable();

+			attribsRefdFromAction = empty;

+			>>

+			NonTerminal

+			<<q=NULL;

+			  if ( hash_get(Rname, LATEXT(1))!=NULL ) {

+				  err(eMsg1("duplicate rule definition: '%s'",LATEXT(1)));

+				  CannotContinue=TRUE;

+			  }

+			  else

+			  {

+			  	  q = (RuleEntry *)hash_add(Rname,

+											LATEXT(1),

+											(Entry *)newRuleEntry(LATEXT(1)));

+			      CurRule = q->str;

+			  }

+			  CurRuleNode = q;

+			  f = CurFile; l = zzline;

+			  NumRules++;

+			>>

+			{	"!"  <<if ( q!=NULL ) q->noAST = TRUE;>> }

+			{	<<;>>

+				{"\<"}

+				PassAction

+				<<	pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+					require(pdecl!=NULL, "rule rule: cannot allocate param decl");

+					strcpy(pdecl, LATEXT(1));

+					CurParmDef = pdecl;

+				>>

+			}

+			{	"\>"

+				PassAction

+				<<	ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+				    require(ret!=NULL, "rule rule: cannot allocate ret type");

+					strcpy(ret, LATEXT(1));

+ 					CurRetDef = ret;

+				>>

+			}

+			{ QuotedTerm <<if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1));>> }

+			<<

+			if ( GenEClasseForRules && q!=NULL ) {

+				e = newECnode;

+				require(e!=NULL, "cannot allocate error class node");

+				if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);}

+				else a = q->egroup;

+				if ( Tnum( a ) == 0 )

+				{

+					e->tok = addTname( a );

+					list_add(&eclasses, (char *)e);

+					if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);

+					/* refers to itself */

+					list_add(&(e->elist), mystrdup(q->str));

+				}

+				else {

+					warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a));

+					if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);

+					free((char *)e);

+				}

+			}

+			>>

+			<<BlkLevel++;

+              if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");

+/* MR23 */    CurBlockID_array[BlkLevel] = CurBlockID;

+/* MR23 */    CurAltNum_array[BlkLevel] = CurAltNum;                

+            >>

+

+			":" <<inAlt=1;>>

+			block[&toksrefd, &rulesrefd]

+			<<r = makeBlk($7,0, NULL /* pFirstSetSymbol */ );

+			  CurRuleBlk = (Junction *)r.left;

+			  CurRuleBlk->blockid = CurBlockID;

+			  CurRuleBlk->jtype = RuleBlk;

+			  if ( q!=NULL ) CurRuleBlk->rname = q->str;

+			  CurRuleBlk->file = f;

+			  CurRuleBlk->line = l;

+			  CurRuleBlk->pdecl = pdecl;

+			  CurRuleBlk->ret = ret;

+			  CurRuleBlk->lock = makelocks();

+			  CurRuleBlk->pred_lock = makelocks();

+			  CurRuleBlk->tokrefs = toksrefd;

+			  CurRuleBlk->rulerefs = rulesrefd;

+			  p = newJunction();	/* add EndRule Node */

+			  ((Junction *)r.right)->p1 = (Node *)p;

+			  r.right = (Node *) p;

+			  p->jtype = EndRule;

+			  p->lock = makelocks();

+			  p->pred_lock = makelocks();

+			  CurRuleBlk->end = p;

+			  if ( q!=NULL ) q->rulenum = NumRules;

+			  $7 = r;

+			>>

+			<<

+                /* MR23 */      CurBlockID_array[BlkLevel] = (-1);

+                /* MR23 */      CurAltNum_array[BlkLevel] = (-1);                

+                --BlkLevel;

+            >>

+            <<altFixup();leFixup();egFixup();>>                      /* MR7 */

+			";" <<inAlt=0;>>

+			{	Action

+				<<	a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+					require(a!=NULL, "rule rule: cannot allocate error action");

+					strcpy(a, LATEXT(1));

+					CurRuleBlk->erraction = a;

+				>>

+			}

+			(	exception_group > [eg]

+				<<if ( eg!=NULL ) {

+					list_add(&CurExGroups, (void *)eg);

+					if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1;

+			    }

+				>>

+			)*

+			<<if ( q==NULL ) $0.left = NULL; else $0 = $7;>>

+			<<CurRuleBlk->exceptions = CurExGroups;>>

+			<<CurRuleBlk->el_labels = CurElementLabels;>>

+			<<CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions;>> /* MR27 */

+			<<CurRuleNode = NULL;>> /* MR27 Moved */

+		;

+		<<CannotContinue=TRUE;>>

+

+/*

+ * pragma	:	"{\\}#pragma" "dup\-labeled\-tokens"

+ *			<<Pragma_DupLabeledTokens=1;>>

+ *		;

+ */

+

+/* rule laction */

+

+laction	:	<<char *a;>>

+

+			"{\\}#lexaction"

+			Action

+			<<

+			a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+			require(a!=NULL, "rule laction: cannot allocate action");

+			strcpy(a, LATEXT(1));

+			list_add(&LexActions, a);

+			>>

+		;

+		<<CannotContinue=TRUE;>>

+

+/* MR1									    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+/* MR1			  via #lexmember <<....>> & #lexprefix <<...>>      */

+/* MR1									    */

+

+/* rule lmember */

+

+lmember:	<<char *a;>>					     /* MR1 */

+

+/* MR1 */		"{\\}#lexmember"

+/* MR1 */		Action

+/* MR1 */		<<

+/* MR1 */		if (! GenCC) {

+/* MR1 */		  err("Use #lexmember only in C++ mode (to insert code in DLG class header");

+/* MR1 */	        } else {

+/* MR1 */		  a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+/* MR1 */		  require(a!=NULL, "rule lmember: cannot allocate action");

+/* MR1 */		  strcpy(a, LATEXT(1));

+/* MR1 */		  list_add(&LexMemberActions, a);

+/* MR1 */		};

+/* MR1 */		>>

+/* MR1 */	;

+/* MR1 */	<<CannotContinue=TRUE;>>

+

+/* rule lprefix */

+

+lprefix:	<<char *a;>>					     /* MR1 */

+

+/* MR1 */		"{\\}#lexprefix"

+/* MR1 */		Action

+/* MR1 */		<<

+/* MR1 */		if (! GenCC) {

+/* MR1 */		  err("Use #lexprefix only in C++ mode (to insert code in DLG class header");

+/* MR1 */	        } else {

+/* MR1 */		  a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+/* MR1 */		  require(a!=NULL, "rule lprefix: cannot allocate action");

+/* MR1 */		  strcpy(a, LATEXT(1));

+/* MR1 */		  list_add(&LexPrefixActions, a);

+/* MR1 */		};

+/* MR1 */		>>

+/* MR1 */	;

+/* MR1 */	<<CannotContinue=TRUE;>>

+

+/*

+ * #pred upper        <<isupper()>>?            predicate literal

+ * #pred lower        <<islower()>>?            predicate literal

+ * #pred up_or_low    upper || lower            predicate expression

+ *                                                concealed interdependence

+ * #pred up_or_low_2  <<isletter()>>?  A || B   predicate literal equals predicate expr

+ *                                                analyze using lower||upper

+ *                                                generate using isLetter()

+ */

+

+/* rule aPref */

+

+aPred:  <<PredEntry     *predEntry=NULL;

+          char          *name=NULL;

+          Predicate     *predExpr=NULL;

+          char          *predLiteral=NULL;

+          int           save_file;

+          int           save_line;

+          int           predExprPresent=0;

+        >>

+

+        "{\\}#pred"

+

+        <<

+          MR_usingPredNames=1;      /* will need to use -mrhoist version of genPredTree */

+        >>

+

+                                    /* used to allow NonTerminal but it caused problems

+                                       when a rule name immediately followed a #pred statement */

+

+        TokenTerm     <<name=mystrdup(LATEXT(1));>>

+

+          <<

+            /* don't free - referenced in predicates */

+

+            CurPredName=(char *)calloc(1,strlen(name) + 10);

+            strcat(CurPredName,"#pred ");

+            strcat(CurPredName,name);

+

+            predEntry=(PredEntry *) hash_get(Pname,name);

+            if (predEntry != NULL) {

+              warnFL(eMsg1("#pred %s previously defined - ignored",name),

+                                              FileStr[action_file],action_line);

+              name=NULL;

+            };

+          >>

+

+        (

+

+            Pred    <<predLiteral=mystrdup(LATEXT(1));

+                      save_line=action_line;

+                      save_file=action_file;

+                    >>

+

+              {

+                    predOrExpr>[predExpr]   <<predExprPresent=1;>>

+              }

+

+              <<if (predLiteral != NULL && name != NULL) {

+

+                      /*

+                       *  predExpr may be NULL due to syntax errors

+                       *    or simply omitted by the user

+                      */

+

+                      predEntry=newPredEntry(name);

+                      predEntry->file=save_file;

+                      predEntry->line=save_line;

+                      predExpr=MR_predFlatten(predExpr);

+                      predEntry->predLiteral=predLiteral;

+                      if (! predExprPresent || predExpr == NULL) {

+                        predExpr=new_pred();

+                        predExpr->expr=predLiteral;

+                        predExpr->source=newActionNode();

+                        predExpr->source->action=predExpr->expr;

+                        predExpr->source->rname=CurPredName;

+                        predExpr->source->line=action_line;

+                        predExpr->source->file=action_file;

+                        predExpr->source->is_predicate=1;

+                        predExpr->k=predicateLookaheadDepth(predExpr->source);

+                      };

+                      predEntry->pred=predExpr;

+                      hash_add(Pname,name,(Entry *)predEntry);

+                      predExpr=NULL;

+                };

+                predicate_free(predExpr);

+              >>

+

+            |

+               <<save_line=zzline; save_file=CurFile;>>

+

+                predOrExpr>[predExpr]

+

+              <<if (predExpr != NULL && name != NULL) {

+                  predEntry=newPredEntry(name);

+                  predEntry->file=CurFile;

+                  predEntry->line=zzline;

+                  predExpr=MR_predFlatten(predExpr);

+                  predEntry->pred=predExpr;

+                  hash_add(Pname,name,(Entry *)predEntry);

+                  predExpr=NULL;

+                };

+                predicate_free(predExpr);

+              >>

+        )

+        {";"}

+;

+

+/* fail */

+

+<<predicate_free(predExpr);

+>>

+

+/* rule predOrExpr */

+

+predOrExpr>[Predicate *result] :

+            <<Predicate     *ORnode;

+              Predicate     *predExpr;

+              Predicate     **tail=NULL;

+            >>

+        predAndExpr>[predExpr]

+            <<

+                ORnode=new_pred();

+                ORnode->expr=PRED_OR_LIST;

+                if (predExpr != NULL) {

+                    ORnode->down=predExpr;

+                    tail=&predExpr->right;

+                };

+            >>

+        ( "\|\|"  predAndExpr>[predExpr]

+            <<

+                if (predExpr != NULL) {

+                    *tail=predExpr;

+                    tail=&predExpr->right;

+                };

+            >>

+        )*

+        <<

+            $result=ORnode;

+            ORnode=NULL;

+        >>

+;

+

+/* fail */

+

+<<predicate_free(ORnode);>>

+

+/* rule predAndExpr */

+

+predAndExpr>[Predicate *result] :

+            <<Predicate     *ANDnode;

+              Predicate     *predExpr;

+              Predicate     **tail=NULL;

+            >>

+        predPrimary>[predExpr]

+            <<

+                ANDnode=new_pred();

+                ANDnode->expr=PRED_AND_LIST;

+                if (predExpr != NULL) {

+                    ANDnode->down=predExpr;

+                    tail=&predExpr->right;

+                };

+            >>

+        ( "&&"  predPrimary>[predExpr]

+            <<

+                if (predExpr != NULL) {

+                    *tail=predExpr;

+                    tail=&predExpr->right;

+                };

+            >>

+        )*

+        <<

+            $result=ANDnode;

+            ANDnode=NULL;

+        >>

+;

+

+/* fail */

+

+<<predicate_free(ANDnode);>>

+

+

+/* rule predPrimary */

+

+predPrimary>[Predicate *result] :

+            <<

+              char          *name=NULL;

+              PredEntry     *predEntry=NULL;

+              Predicate     *predExpr=NULL;

+            >>

+

+        TokenTerm            <<name=mystrdup(LATEXT(1));>>

+

+            <<

+                predEntry=(PredEntry *) hash_get(Pname,name);

+                if (predEntry == NULL) {

+                  warnFL(eMsg1("no previously defined #pred with name \"%s\"",name),

+                        FileStr[CurFile],zzline);

+                  name=NULL;

+                  $result=NULL;

+                } else {

+                  predExpr=predicate_dup(predEntry->pred);

+                  predExpr->predEntry=predEntry;

+                  $result=predExpr;

+                };

+            >>

+

+        | "\(" predOrExpr>[predExpr] "\)"

+            <<

+                $result=predExpr;

+            >>

+

+        | "!" predPrimary>[predExpr]

+            <<

+                predExpr->inverted=!predExpr->inverted;

+                $result=predExpr;

+            >>

+;

+

+/* fail */  <<

+              predicate_free(predExpr);

+            >>

+

+/* rule aLexclass */

+

+aLexclass:	"{\\}#lexclass" TokenTerm <<lexclass(mystrdup(LATEXT(1)));>>

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule error */

+

+error	:	<<char *t=NULL; ECnode *e; int go=1; TermEntry *p;>>

+			"{\\}#errclass"

+			(<<;>>	TokenTerm  <<t=mystrdup(LATEXT(1));>>

+			|		QuotedTerm <<t=mystrdup(LATEXT(1));>>

+			)

+			<<e = newECnode;

+			  require(e!=NULL, "cannot allocate error class node");

+			  e->lexclass = CurrentLexClass;

+			  if ( Tnum( (t=StripQuotes(t)) ) == 0 )

+			  {

+				if ( hash_get(Texpr, t) != NULL )

+					warn(eMsg1("errclass name conflicts with regular expression  '%s'",t));

+			  	e->tok = addTname( t );

+				set_orel(e->tok, &imag_tokens);

+				require((p=(TermEntry *)hash_get(Tname, t)) != NULL,

+						"hash table mechanism is broken");

+				p->classname = 1;	/* entry is errclass name, not token */

+				list_add(&eclasses, (char *)e);

+			  }

+			  else

+			  {

+			  	warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t));

+				free( (char *)e );

+				go=0;

+			  }

+			>>

+			"\{"

+				( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>>

+				| TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>>

+				| QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>>

+				)

+				<<if ( go ) list_add(&(e->elist), t);>>

+				(

+					( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>>

+					| TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>>

+					| QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>>

+					)

+					<<if ( go ) list_add(&(e->elist), t);>>

+				)*

+			"\}"

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule tclass */

+

+tclass	:	<<char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm;>>

+            <<char *akaString=NULL; int save_file; int save_line;>>

+            <<char *totext=NULL; >>

+			"{\\}#tokclass" TokenTerm <<t=mystrdup(LATEXT(1));>>

+			<<e = newTCnode;

+			  require(e!=NULL, "cannot allocate token class node");

+			  e->lexclass = CurrentLexClass;

+			  if ( Tnum( t ) == 0 )

+			  {

+			  	e->tok = addTname( t );

+				set_orel(e->tok, &imag_tokens);

+				set_orel(e->tok, &tokclasses);

+				require((p=(TermEntry *)hash_get(Tname, t)) != NULL,

+						"hash table mechanism is broken");

+				p->classname = 1;	/* entry is class name, not token */

+				p->tclass = e;		/* save ptr to this tclass def */

+				list_add(&tclasses, (char *)e);

+			  }

+			  else

+			  {

+			  	warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t));

+				free( (char *)e );

+				go=0;

+			  }

+			>>

+/* MR23 */      {

+/* MR23 */          "\("

+/* MR23 */          QuotedTerm

+/* MR23 */                 <<akaString=mystrdup(StripQuotes(LATEXT(1)));

+/* MR11 */                   save_file=CurFile;save_line=zzline;

+/* MR23 */                 >>

+/* MR23 */          "\)"

+/* MR23 */      }

+/* MR23 */

+/* MR23 */

+/* MR23 */		<<

+/* MR23 */         if (p!= NULL && akaString != NULL) {

+/* MR23 */           if (p->akaString != NULL) {

+/* MR23 */             if (strcmp(p->akaString,akaString) != 0) {

+/* MR23 */                warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement",

+/* MR23 */                              t,p->akaString),

+/* MR23 */			                    FileStr[save_file],save_line);

+/* MR23 */             };

+/* MR23 */            } else {

+/* MR23 */              p->akaString=akaString;

+/* MR23 */            };

+/* MR23 */          };

+/* MR23 */		>>

+

+			"\{"

+				(

+    				( TokenTerm

+    				  <<if ( go ) {

+    					term = (TermEntry *) hash_get(Tname, LATEXT(1));

+    					if ( term==NULL && UserDefdTokens ) {

+    						err("implicit token definition not allowed with #tokdefs");

+    						go = 0;

+    					}

+    					else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));}

+    					}>>

+

+                        {

+                            ".."

+                            TokenTerm

+

+            				  <<if ( go ) {

+                					toterm = (TermEntry *) hash_get(Tname, LATEXT(1));

+                					if ( toterm==NULL && UserDefdTokens ) {

+                						err("implicit token definition not allowed with #tokdefs");

+                						go = 0;

+                					} else {

+                                        totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1));

+                                    }

+            				    }

+                              >>

+                        }

+

+    				| QuotedTerm

+    				  <<if ( go ) {

+    					term = (TermEntry *) hash_get(Texpr, LATEXT(1));

+    					if ( term==NULL && UserDefdTokens ) {

+    						err("implicit token definition not allowed with #tokdefs");

+    						go = 0;

+        					}

+    					else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));}

+    					}>>

+    				)

+    				<<if ( go ) {

+                        if (totext == NULL) {

+                            list_add(&(e->tlist), t);

+                        } else {

+                            list_add(&(e->tlist),"..");

+                            list_add(&(e->tlist),t);

+                            list_add(&(e->tlist),totext);

+                        }

+                        totext=NULL;

+                      }

+                    >>

+				)+  // MR15 Manfred Kogler - forbid empty #tokclass sets (was "+")

+			"\}"

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule token */

+

+token	:	<<char *t=NULL, *e=NULL, *a=NULL; int tnum=0;>>

+            <<char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0;>>           /* MR11 */

+			"{\\}#token"

+

+/* MR1 10-Apr-97 MR1 Allow shift right operator in DLG actions		   */

+/* MR1			Danger when parser feedback to lexer		           */

+/* MR1	                                                               */

+

+			<<tokenActionActive=1;>>		                    /* MR1 */

+			{	TokenTerm  <<t=mystrdup(LATEXT(1));>>

+

+/* MR11 */      {

+/* MR11 */          "\("

+/* MR11 */          QuotedTerm

+/* MR11 */                 <<akaString=mystrdup(StripQuotes(LATEXT(1)));

+/* MR11 */                   save_file=CurFile;save_line=zzline;

+/* MR11 */                 >>

+/* MR11 */          "\)"

+/* MR11 */      }

+

+				{	"=" "[0-9]+"		/* define the token type number */

+					<<tnum = atoi(LATEXT(1));>>

+				}

+			}

+			{ QuotedTerm <<e=mystrdup(LATEXT(1));>> }

+			{	Action

+				<<

+					a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+					require(a!=NULL, "rule token: cannot allocate action");

+					strcpy(a, LATEXT(1));

+				>>

+			}

+

+            { ";" }     /* MR11 */

+

+			<<chkToken(t, e, a, tnum);>>

+

+            <<if (t != NULL) {

+                te=(TermEntry *)hash_get(Tname,t);

+                if (te != NULL && akaString != NULL) {

+                  if (te->akaString != NULL) {

+                    if (strcmp(te->akaString,akaString) != 0) {

+                      warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement",

+                                    t,te->akaString),

+                        FileStr[save_file],save_line);

+                    };

+                  } else {

+                    te->akaString=akaString;

+                  };

+                };

+              };

+            >>

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule block */

+

+block[set *toksrefd, set *rulesrefd]

+		:	<<

+    			Graph g, b;

+    			set saveblah;

+    			int saveinalt = inAlt;

+    			ExceptionGroup *eg;

+    			*$toksrefd = empty;

+    			*$rulesrefd = empty;

+    			set_clr(AST_nodes_refd_in_actions);

+    			CurBlockID++;

+/* MR23 */      CurBlockID_array[BlkLevel] = CurBlockID;

+    			CurAltNum = 1;

+/* MR23 */      CurAltNum_array[BlkLevel] = CurAltNum;                

+    			saveblah = attribsRefdFromAction;

+    			attribsRefdFromAction = empty;

+			>>

+

+			alt[toksrefd,rulesrefd]		<<b = g = $1;>>

+

+			<<

+			if ( ((Junction *)g.left)->p1->ntype == nAction )

+			{

+                ActionNode *actionNode=(ActionNode *)

+                                         ( ( (Junction *)g.left) ->p1);

+				if (!actionNode->is_predicate )

+				{

+					actionNode->init_action = TRUE;

+/* MR12c */  		if (actionNode->noHoist) {

+/* MR12c */           errFL("<<nohoist>> appears as init-action - use <<>> <<nohoist>>",

+/* MR12c */                       FileStr[actionNode->file],actionNode->line);

+/* MR12c */         };

+				}

+			}

+			((Junction *)g.left)->blockid = CurBlockID;

+			>>

+

+			(	exception_group > [eg]

+				<<

+				if ( eg!=NULL ) {

+/* MR7 *****       	eg->altID = makeAltID(CurBlockID,CurAltNum);        *****/

+/* MR7 *****		CurAltStart->exception_label = eg->altID;           *****/

+					list_add(&CurExGroups, (void *)eg);

+				}

+				>>

+			)*

+			<<CurAltNum++;

+/* MR23 */    CurAltNum_array[BlkLevel] = CurAltNum;

+            >>

+

+			(	"\|" <<inAlt=1;>>

+				alt[toksrefd,rulesrefd]		<<g = Or(g, $2);>>

+				<<

+				((Junction *)g.left)->blockid = CurBlockID;

+				>>

+

+				(	exception_group > [eg]

+					<<

+					if ( eg!=NULL ) {

+/* MR7 *****       	eg->altID = makeAltID(CurBlockID,CurAltNum);        *****/

+/* MR7 *****		CurAltStart->exception_label = eg->altID;           *****/

+						list_add(&CurExGroups, (void *)eg);

+					}

+					>>

+				)*

+

+				<<CurAltNum++;

+/* MR23 */        CurAltNum_array[BlkLevel] = CurAltNum;                

+                >>

+

+			)*

+			<<$0 = b;>>

+			<<attribsRefdFromAction = saveblah; inAlt = saveinalt;>>

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule alt */

+

+alt[set *toksrefd, set *rulesrefd]

+		:	<<int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif;

+			int first_on_line = 1, use_def_MT_handler = 0;

+			g.left=NULL; g.right=NULL;

+

+			CurAltStart = NULL;

+			elems = empty;

+			inAlt = 1;

+			>>

+			{	"\@"	/* handle MismatchedToken signals with default handler */

+				<<use_def_MT_handler = 1;>>

+			}

+

+			(	<<;>>       /* MR9 Removed unreferenced variable "tok" */

+				{ <<old_not=0;>> "\~" <<old_not=1;>> }

+				element[old_not, first_on_line, use_def_MT_handler] > [node]

+				<<if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0;>>

+				<<

+				if ( $2.left!=NULL ) {

+					g = Cat(g, $2);

+					n++;

+					if ( node!=NULL ) {

+						if ( node->ntype!=nAction ) e_num++;

+						/* record record number of all rule and token refs */

+						if ( node->ntype==nToken ) {

+							TokNode *tk = (TokNode *)((Junction *)$2.left)->p1;

+							tk->elnum = e_num;

+							set_orel(e_num, &elems);

+						}

+						else if ( node->ntype==nRuleRef ) {

+							RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1;

+							rn->elnum = e_num;

+							set_orel(e_num, $rulesrefd);

+						}

+					}

+				}

+				>>

+			)*

+			<<if ( n == 0 ) g = emptyAlt();

+			  $0 = g;

+			  /* We want to reduce number of LT(i) calls and the number of

+			   * local attribute variables in C++ mode (for moment, later we'll

+			   * do for C also).  However, if trees are being built, they

+			   * require most of the attrib variables to create the tree nodes

+			   * with; therefore, we gen a token ptr for each token ref in C++

+			   */

+			  if ( GenCC && !GenAST )

+			  {

+				  /* This now free's the temp set -ATG 5/6/95 */

+				  set temp;

+				  temp = set_and(elems, attribsRefdFromAction);

+				  set_orin($toksrefd, temp);

+				  set_free(temp);

+			  }

+			  else set_orin($toksrefd, elems);

+			  if ( GenCC ) {

+				dif = set_dif(attribsRefdFromAction, elems);

+			  	if ( set_deg(dif)>0 )

+					err("one or more $i in action(s) refer to non-token elements");

+				set_free(dif);

+			  }

+			  set_free(elems);

+			  set_free(attribsRefdFromAction);

+			  inAlt = 0;

+   			>>

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule element_label */

+

+element_label > [LabelEntry *label]

+	:	<<TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab;>>

+		LABEL	<<lab = mystrdup(LATEXT(1));>>

+		<<

+		UsedNewStyleLabel = 1;

+		if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i");

+		t = (TermEntry *) hash_get(Tname, lab);

+		if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab);

+		if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab);

+		if ( t!=NULL ) {

+			err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab));

+			$label = NULL;

+		}

+		else if ( r!=NULL ) {

+			err(eMsg1("label definition clashes with rule definition: '%s'", lab));

+			$label = NULL;

+		}

+		else {

+			/* we don't clash with anybody else */

+			l = (LabelEntry *) hash_get(Elabel, lab);

+ 			if ( l==NULL ) {	/* ok to add new element label */

+				l = (LabelEntry *)hash_add(Elabel,

+										   lab,

+										   (Entry *)newLabelEntry(lab));

+				/* add to list of element labels for this rule */

+				list_add(&CurElementLabels, (void *)lab);

+/* MR7 */       leAdd(l);  /* list of labels waiting for exception group definitions */

+				$label = l;

+			}

+			else {

+				err(eMsg1("label definitions must be unique per rule: '%s'", lab));

+				$label = NULL;

+			}

+		}

+		>>

+		":"

+	;

+

+/* rule element */

+

+element[int old_not, int first_on_line, int use_def_MT_handler] > [Node *node]

+		: <<

+		  Attrib blk;

+		  Predicate *pred = NULL;

+		  int local_use_def_MT_handler=0;

+		  ActionNode *act;

+		  RuleRefNode *rr;

+		  set toksrefd, rulesrefd;

+		  TermEntry *term;

+		  TokNode *p=NULL; RuleRefNode *q; int approx=0;

+		  LabelEntry *label=NULL;

+          int predMsgDone=0;

+          int semDepth=0;

+          int   ampersandStyle;

+          int   height;         /* MR11 */

+          int   equal_height;   /* MR11 */

+

+          char* pFirstSetSymbol = NULL; /* MR21 */

+

+		  $node = NULL;

+		  >>

+		  {element_label>[label]}

+		  ( TokenTerm

+			<<

+			term = (TermEntry *) hash_get(Tname, LATEXT(1));

+			if ( term==NULL && UserDefdTokens ) {

+				err("implicit token definition not allowed with #tokdefs");

+				$$.left = $$.right = NULL;

+			}

+			else {

+				$$ = buildToken(LATEXT(1));

+				p=((TokNode *)((Junction *)$$.left)->p1);

+				term = (TermEntry *) hash_get(Tname, LATEXT(1));

+				require( term!= NULL, "hash table mechanism is broken");

+				p->tclass = term->tclass;

+				p->complement = $old_not;

+				if ( label!=NULL ) {

+					p->el_label = label->str;

+					label->elem = (Node *)p;

+				}

+			}

+			>>

+			{	".."

+				(	QuotedTerm

+					<<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>

+				|	TokenTerm

+					<<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>

+				)

+			}

+			<<

+			if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) )

+				list_add(&MetaTokenNodes, (void *)p);

+			>>

+			(	"^"	<<if ( p!=NULL ) p->astnode=ASTroot;>>

+			|		<<if ( p!=NULL ) p->astnode=ASTchild;>>

+			|	"!" <<if ( p!=NULL ) p->astnode=ASTexclude;>>

+			)

+			{ "\@" <<local_use_def_MT_handler = 1;>> }

+			<<

+			if ( p!=NULL && $first_on_line ) {

+				CurAltStart = (Junction *)$$.left;

+                altAdd(CurAltStart);                                 /* MR7 */

+				p->altstart = CurAltStart;

+			}

+   			if ( p!=NULL )

+				p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler;

+			$node = (Node *)p;

+			>>

+		  | QuotedTerm

+			<<

+			term = (TermEntry *) hash_get(Texpr, LATEXT(1));

+			if ( term==NULL && UserDefdTokens ) {

+				err("implicit token definition not allowed with #tokdefs");

+				$$.left = $$.right = NULL;

+			}

+			else {

+				$$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);

+				p->complement = $old_not;

+				if ( label!=NULL ) {

+					p->el_label = label->str;

+	   				label->elem = (Node *)p;

+				}

+			}

+			>>

+			{	".."

+				(	QuotedTerm

+					<<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>

+				|	TokenTerm

+					<<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>

+				)

+			}

+			(	"^"	<<if ( p!=NULL ) p->astnode=ASTroot;>>

+			|		<<if ( p!=NULL ) p->astnode=ASTchild;>>

+			|	"!" <<if ( p!=NULL ) p->astnode=ASTexclude;>>

+			)

+			{ "\@" <<local_use_def_MT_handler = 1;>> }

+			<<

+			if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) )

+				list_add(&MetaTokenNodes, (void *)p);

+			>>

+			<<

+			if ( $first_on_line ) {

+				CurAltStart = (Junction *)$$.left;

+                altAdd(CurAltStart);                                 /* MR7 */

+				p->altstart = CurAltStart;

+			}

+   			if ( p!=NULL )

+				p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler;

+			$node = (Node *)p;

+			>>

+

+		  | <<if ( $old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')");>>

+			"."

+			<<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>>

+			(	"^"	<<p->astnode=ASTroot;>>

+			|		<<p->astnode=ASTchild;>>

+			|	"!" <<p->astnode=ASTexclude;>>

+			)

+			<<list_add(&MetaTokenNodes, (void *)p);>>

+			<<

+			if ( $first_on_line ) {

+				CurAltStart = (Junction *)$$.left;

+                altAdd(CurAltStart);                                 /* MR7 */

+				p->altstart = CurAltStart;

+				if ( label!=NULL ) {

+					p->el_label = label->str;

+					label->elem = (Node *)p;

+				}

+			}

+			$node = (Node *)p;

+			>>

+

+		  | <<if ( $old_not ) warn("~ NONTERMINAL is an undefined operation");>>

+			NonTerminal

+			<<$$ = buildRuleRef(LATEXT(1));>>

+			{ "!" <<q = (RuleRefNode *) ((Junction *)$$.left)->p1;

+					q->astnode=ASTexclude;>>

+			}

+			{	{"\<"}

+				PassAction <<addParm(((Junction *)$$.left)->p1, LATEXT(1));>>

+			}

+			<<rr=(RuleRefNode *) ((Junction *)$$.left)->p1;>>

+			{	<<char *a;>>

+				"\>"

+				PassAction

+				<<

+					a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+					require(a!=NULL, "rule element: cannot allocate assignment");

+					strcpy(a, LATEXT(1));

+					rr->assign = a;

+				>>

+			}

+			<<

+			if ( label!=NULL ) {

+				rr->el_label = label->str;

+				label->elem = (Node *)rr;

+			}

+			if ( $first_on_line ) {

+				CurAltStart = (Junction *)$$.left;

+                altAdd(CurAltStart);                                 /* MR7 */

+				((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart;

+			}

+			$node = (Node *)rr;

+			>>

+		  )

+

+		|	<<if ( $old_not )	warn("~ ACTION is an undefined operation");>>

+			Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>>

+			<<if ( $first_on_line ) {                                /* MR7 */

+                CurAltStart = (Junction *)$0.left;                   /* MR7 */

+                altAdd(CurAltStart);                                 /* MR7 */

+              };>>                                                   /* MR7 */

+			<<$node = (Node *) ((Junction *)$0.left)->p1;>>

+

+		|	<<if ( $old_not )	warn("~ SEMANTIC-PREDICATE is an undefined operation");>>

+			Pred   <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>>

+			<<act = (ActionNode *) ((Junction *)$0.left)->p1;>>

+            <<if (numericActionLabel) {             /* MR10 */

+                list_add(&NumericPredLabels,act);   /* MR10 */

+                numericActionLabel=0;               /* MR10 */

+              };                                    /* MR10 */

+            >>

+			{	<<char *a;>>

+				PassAction

+				<<

+				a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+				require(a!=NULL, "rule element: cannot allocate predicate fail action");

+				strcpy(a, LATEXT(1));

+				act->pred_fail = a;

+				>>

+			}

+			<<if ( $first_on_line ) {                                /* MR7 */

+                CurAltStart = (Junction *)$0.left;                   /* MR7 */

+                altAdd(CurAltStart);                                 /* MR7 */

+              };>>                                                   /* MR7 */

+			<<$node = (Node *)act;>>

+

+		|	<<if ( $old_not )	warn("~ BLOCK is an undefined operation");>>

+			<<BlkLevel++;

+              if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");

+/* MR23 */    CurBlockID_array[BlkLevel] = CurBlockID;

+/* MR23 */    CurAltNum_array[BlkLevel] = CurAltNum;                

+            >>

+			{	Pragma

+				(	"approx" <<approx=LL_k;>>

+				|	"LL\(1\)"  <<approx = 1;>>  /* MR20 */

+				|	"LL\(2\)"  <<approx = 2;>>  /* MR20 */

+                )

+            }

+

+/* MR21 */  {  FirstSetSymbol

+/* MR21 */     "\("

+/* MR21 */    		(	NonTerminal

+/* MR21 */                <<

+/* MR21 */                     pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,

+/* MR21 */                                                    sizeof(char));

+/* MR21 */                          require(pFirstSetSymbol!=NULL,

+/* MR21 */                                  "cannot allocate first set name");

+/* MR21 */                          strcpy(pFirstSetSymbol, LATEXT(1));

+/* MR21 */                      >>

+/* MR21 */          |    TokenTerm

+/* MR21 */                  <<

+/* MR21 */                      pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,

+/* MR21 */                                                        sizeof(char));

+/* MR21 */                      require(pFirstSetSymbol!=NULL,

+/* MR21 */                              "cannot allocate first set name");

+/* MR21 */                      strcpy(pFirstSetSymbol, LATEXT(1));

+/* MR21 */                  >>

+/* MR21 */          )

+/* MR21 */      "\)"

+/* MR21 */  }

+

+            (

+

+        	"\(" block[&toksrefd,&rulesrefd] "\)"

+				<<blk = $$ = $2;

+                        /* MR23 */      CurBlockID_array[BlkLevel] = (-1);

+                        /* MR23 */      CurAltNum_array[BlkLevel] = (-1);                

+                  --BlkLevel;

+            >>

+

+				(	"\*"		<<$$ = makeLoop($$,approx,pFirstSetSymbol);>>

+				|	"\+"		<<$$ = makePlus($$,approx,pFirstSetSymbol);>>

+				|	"?"

+					(	

+                        ( "=>" <<ampersandStyle=0;>>

+                        | "&&" <<ampersandStyle=1;>>  /* MR10 (g)? && <<p>>? */

+                        )

+                        Pred	/* generalized predicate */

+						/* first make into a predicate */

+					    <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>>

+					    <<act = (ActionNode *) ((Junction *)$$.left)->p1;>>

+                        <<semDepth=predicateLookaheadDepth(act);>>  /* MR10 */

+                        <<if (numericActionLabel) {             /* MR10 */

+                            list_add(&NumericPredLabels,act);   /* MR10 */

+                            numericActionLabel=0;               /* MR10 */

+                          };                                    /* MR10 */

+                        >>

+						{	<<char *a;>>

+							PassAction

+							<<

+							a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char));

+							require(a!=NULL, "rule element: cannot allocate predicate fail action");

+							strcpy(a, LATEXT(1));

+							act->pred_fail = a;

+							>>

+						}

+						<<if ($first_on_line) {                      /* MR7 */

+                            CurAltStart=(Junction *)$$.left;         /* MR7 */

+                            altAdd(CurAltStart);                     /* MR7 */

+                          };>>

+						<<$node = (Node *)act;>>

+

+						/* for now, just snag context */

+						<<

+						pred = computePredFromContextGuard(blk,&predMsgDone);           /* MR10 */

+						if ( pred==NULL) {                                              /* MR10 */

+                          if ( !predMsgDone) err("invalid or missing context guard");   /* MR10 */

+                          predMsgDone=1;                                                /* MR10 */

+						} else {                                                        /* MR10 */

+                            act->guardNodes=(Junction *)blk.left;                       /* MR11 */

+							pred->expr = act->action;

+							pred->source = act;

+/* MR10 */                  pred->ampersandStyle = ampersandStyle;  /* 0 means (g)? => ... 1 means (g)? && ... */

+/* MR13 */                  if (pred->tcontext != NULL) {

+/* MR13 */                    height=MR_max_height_of_tree(pred->tcontext);

+/* MR13 */                    equal_height=MR_all_leaves_same_height(pred->tcontext,height);

+/* MR13 */                    if (! equal_height) {

+/* MR13 */                       errFL("in guarded predicates all tokens in the guard must be at the same height",

+/* MR13 */                              FileStr[act->file],act->line);

+/* MR13 */                    };

+/* MR13 */                  }

+/* MR10 */                  if (ampersandStyle) {

+/* MR10 */			  		  act->ampersandPred = pred;

+/* MR11 */                    if (! HoistPredicateContext) {

+/* MR11 */                      errFL("without \"-prc on\" (guard)? && <<pred>>? ... doesn't make sense",

+/* MR11 */                              FileStr[act->file],act->line);

+/* MR11 */                    };

+/* MR10 */                  } else {

+/* MR10 */			  		  act->guardpred = pred;

+/* MR10 */                  };

+/* MR10 */                  if (pred->k != semDepth) {

+/* MR10 */                     warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)",

+/* MR10 */                                  pred->k,semDepth));

+/* MR10 */                  };

+						}

+						>>

+					|	<<$$ = makeBlk($$,approx,pFirstSetSymbol);

+						  FoundGuessBlk = 1;

+						  ((Junction *) ((Junction *)$$.left)->p1)->guess=1;

+						  if ( !$first_on_line ) {

+							err("(...)? predicate must be first element of production");

+						  }

+						>>

+					)

+				|	<<$$ = makeBlk($$,approx,pFirstSetSymbol);>>

+				)

+				<<

+				if ( pred==NULL && !predMsgDone) {                                      /* MR10 */

+					((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID;

+					((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd;

+					((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd;

+					if ( $first_on_line ) {                         /* MR7 */

+					   CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1);  /* MR7 */

+                       altAdd(CurAltStart);                         /* MR7 */

+                    };                                              /* MR7 */

+					$node = (Node *) ((Junction *)$$.left)->p1;

+				}

+				>>

+

+			|	"\{"	block[&toksrefd,&rulesrefd]

+						<<$$ = makeOpt($2,approx,pFirstSetSymbol);

+                                /* MR23 */      CurBlockID_array[BlkLevel] = (-1);

+                                /* MR23 */      CurAltNum_array[BlkLevel] = (-1);                

+                                --BlkLevel;

+                        >>

+				"\}"

+				<<

+				((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID;

+				((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd;

+				((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd;

+				>>

+				<<if ( $first_on_line ) {                            /* MR7 */

+					CurAltStart = (Junction *) ((Junction *)((Junction *)$$.left)->p1);  /* MR7 */

+                    altAdd(CurAltStart);                             /* MR7 */

+                  };

+				>>

+				<<$node = (Node *) ((Junction *)$$.left)->p1;>>

+

+			)

+

+/* Error catching alternatives */

+		|	"\*"	<<warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE;>>

+		|	"\+"	<<warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE;>>

+		|	"\>"	<<warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE;>>

+		|	PassAction <<warn("[...] out of context 'rule > [...]'");

+						 CannotContinue=TRUE;>>

+		;

+		<<CannotContinue=TRUE;>>

+

+/* rule default_exception_handler */

+

+default_exception_handler

+	:	exception_group > [DefaultExGroup]

+	;

+

+/* rule exception_group */

+

+exception_group > [ExceptionGroup *eg]

+	:	<<ExceptionHandler *h; LabelEntry *label=NULL;	  /* MR6 */

+		  FoundException = 1; FoundExceptionGroup = 1;>>  /* MR6 */

+

+		"exception"	 <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>>

+		{	<<char *p;>>

+			PassAction		/* did they attach a label? */

+			<<

+			p = LATEXT(1)+1;

+			p[strlen(p)-1] = '\0';		/* kill trailing space */

+			label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1);

+			if ( label==NULL )

+			{

+				err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1));

+			}

+			>>

+		}

+		(	exception_handler > [h]

+			<<list_add(&($eg->handlers), (void *)h);>>

+		)*

+		{	"default" ":" Action

+			<<{

+			ExceptionHandler *eh = (ExceptionHandler *)

+				calloc(1, sizeof(ExceptionHandler));

+			char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+			require(eh!=NULL, "exception: cannot allocate handler");

+			require(a!=NULL, "exception: cannot allocate action");

+			strcpy(a, LATEXT(1));

+			eh->action = a;

+			eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char));

+			require(eh->signalname!=NULL, "exception: cannot allocate sig name");

+			strcpy(eh->signalname, "default");

+			list_add(&($eg->handlers), (void *)eh);

+			}>>

+		}

+

+		<<

+		if ( label!=NULL ) {

+            	/* Record ex group in sym tab for this label */

+		   if ( label->ex_group!=NULL ) {

+		      err(eMsg1("duplicate exception handler for label '%s'",label->str));

+		   } else {

+			  label->ex_group = $eg;

+				/* Label the exception group itself */

+			  $eg->label = label->str;

+				/* Make the labelled element pt to the exception also */

+/* MR6 */	  if (label->elem == NULL) {

+/* MR6 */	     err(eMsg1("reference in exception handler to undefined label '%s'",label->str));

+/* MR6 */	  } else {

+			   	 switch ( label->elem->ntype ) {

+				    case nRuleRef :

+                        {

+    					    RuleRefNode *r = (RuleRefNode *)label->elem;

+    					    r->ex_group = $eg;

+    				    	break;

+                        }

+     	            case nToken :

+				        {

+					        TokNode *t = (TokNode *)label->elem;

+					        t->ex_group = $eg;

+					        break;

+				        }

+				 } /* end switch */

+/* MR6 */	  }; /* end test on label->elem */

+		    } /* end test on label->ex_group */

+

+		} /* end test on exception label */

+

+/* MR7 */

+/* MR7 */   if (BlkLevel == 1 && label == NULL) {

+/* MR7 */     $eg->forRule=1;

+/* MR7 */   } else if (label == NULL) {

+/* MR7 */     $eg->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]);

+/* MR7 */     egAdd($eg);

+/* MR7 */   } else {

+/* MR7 */     $eg->labelEntry=label;

+/* MR7 */   };

+/* MR7 */

+/* MR7 */	    /* You may want to remove this exc from the rule list  */

+/* MR7 */		/* and handle at the labeled element site.             */

+/* MR7 */

+/* MR7 */   if (label != NULL) {

+/* MR7 */     $eg = NULL;

+/* MR7 */   };

+

+		>>

+	;

+	<<CannotContinue=TRUE;>>

+

+/* rule exception_handler */

+

+exception_handler > [ExceptionHandler *eh]

+	:	<<;>>                               /* MR9 Removed unreferenced variable "a" */

+		"catch"

+		<<

+		$eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler));

+		require($eh!=NULL, "exception: cannot allocate handler");

+		>>

+		(	NonTerminal

+			<<

+			$eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+			require($eh->signalname!=NULL, "exception: cannot allocate sig name");

+			strcpy($eh->signalname, LATEXT(1));

+			>>

+		|	TokenTerm

+			<<

+			$eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+			require($eh->signalname!=NULL, "exception: cannot allocate sig name");

+			strcpy($eh->signalname, LATEXT(1));

+			>>

+		)

+		":"

+		{	<<$eh->action = NULL;>>

+			Action

+			<<

+			$eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+			require($eh->action!=NULL, "exception: cannot allocate action");

+			strcpy($eh->action, LATEXT(1));

+			>>

+		}

+	;

+	<<CannotContinue=TRUE;>>

+

+#token NonTerminal		"[a-z] [A-Za-z0-9_]*"

+							<<

+							while ( zzchar==' ' || zzchar=='\t' ) {

+								zzadvance();

+							}

+							if ( zzchar == ':' && inAlt ) NLA = LABEL;

+							>>

+#token TokenTerm		"[A-Z] [A-Za-z0-9_]*"

+							<<

+							while ( zzchar==' ' || zzchar=='\t' ) {

+								zzadvance();

+							}

+							if ( zzchar == ':' && inAlt ) NLA = LABEL;

+							>>

+#token "{\\}#[A-Za-z0-9_]*"	<<warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); >>

+

+#lexclass PARSE_ENUM_FILE

+

+#token "[\t\ ]+"			<< zzskip(); >>				/* Ignore White */

+#token "\n|\r|\r\n"			<< zzline++; zzskip(); >>	/* Track Line # */

+#token "//"					<< zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >>

+#token "/\*"				<< zzmode(TOK_DEF_COMMENTS); zzskip(); >>

+#token "#ifdef"				<< zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>

+#token "#if"				<< zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>

+#token "#ifndef"			<< ; >>

+#token "#else"				<< zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>

+#token "#endif"				<< zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>

+#token "#undef"				<< zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>

+#token "#import"			<< zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>

+#token "@"					<< ; >>

+

+/* rule enum_file */

+

+enum_file[char *fname]

+	:	{	"#ifndef" ID

+			{	"#define" ID /* ignore if it smells like a gate */

+				/* First #define after the first #ifndef (if any) is ignored */

+			}

+		}

+		(	( enum_def[$fname] )+

+		|	defines[$fname]

+		)

+	|

+	;

+

+/* rule defines */

+

+defines[char *fname]

+	:	<<int v; int maxt=(-1); char *t;>>		/* MR3 */

+		(

+			"#define" ID

+			<<t = mystrdup(LATEXT(1));>>

+			INT

+			<<

+			v = atoi(LATEXT(1));

+/*			fprintf(stderr, "#token %s=%d\n", t, v);*/

+

+	/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */

+	/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs            */

+	/* MR2 Don't let #tokdefs be confused by 			*/

+	/* MR2   DLGminToken and DLGmaxToken     			*/

+

+			if ( ! isDLGmaxToken(t)) {		/* MR2 */

+			  TokenNum = v;

+			  if ( v>maxt ) maxt=v;

+			  if ( Tnum( t ) == 0 ) {

+			    addForcedTname( t, v );

+			  } else {

+			    warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);

+			  };

+	                };

+			>>

+		)+

+		<<TokenNum = maxt + 1;>>

+	;

+

+/* rule enum_def */

+

+enum_def[char *fname]

+	:	<<int v= 0; int maxt=(-1); char *t;>>			/* MR3 */

+		"enum" ID

+		"\{"

+			ID

+			<<t = mystrdup(LATEXT(1));>>

+			(	"=" INT	<<v=atoi(LATEXT(1));>>

+			|			<<v++;>>

+			)

+			<<

+/*			fprintf(stderr, "#token %s=%d\n", t, v);*/

+			TokenNum = v;

+			if ( v>maxt ) maxt=v;				/* MR3 */

+			if ( Tnum( t ) == 0 ) addForcedTname( t, v );

+			else {

+				warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);

+			}

+			>>

+			(	","

+

+				/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */

+				/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs            */

+				/* MR2 Don't let #tokdefs be confused by 			*/

+				/* MR2   DLGminToken and DLGmaxToken     			*/

+

+				{

+				  <<isDLGmaxToken(LATEXT(1))>>? ID { "=" INT }		/* MR2 */

+				| ID					                /* MR2 */

+					<<t = mystrdup(LATEXT(1));>>

+					(	"=" INT	<<v=atoi(LATEXT(1));>>

+					|			<<v++;>>

+					)

+					<<

+/*					fprintf(stderr, "#token %s=%d\n", t, v);*/

+					TokenNum = v;

+					if ( v>maxt ) maxt=v;				/* MR3 */

+					if ( Tnum( t ) == 0 ) addForcedTname( t, v );

+					else {

+						warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);

+					}

+					>>

+				}

+			)*

+		"\}"

+		";"

+		<<TokenNum = maxt + 1;>>					/* MR3 */

+	;

+

+#token INT	"[0-9]+"

+#token ID	"[a-zA-Z_][_a-zA-Z0-9]*"

+

+#lexclass START

+

+/* MR14 Arpad Beszedes  26-May-98

+        Add support for #line directives when antlr source is pre-processed

+*/

+

+#lexaction

+<<

+

+static char *

+#ifdef __USE_PROTOS

+getFileNameFromTheLineInfo(char *toStr, char *fromStr)

+#else

+getFileNameFromTheLineInfo(toStr, fromStr)

+char *toStr, *fromStr;

+#endif

+{

+  int i, j, k;

+

+  if (!fromStr || !toStr) return toStr;

+

+  /* find the first " */

+

+  for (i=0;

+        (i<MaxFileName) &&

+        (fromStr[i] != '\n') &&

+        (fromStr[i] != '\r') &&

+        (fromStr[i] != '\"');

+      i++) /* nothing */ ;

+

+  if ( (i == MaxFileName) ||

+       (fromStr[i] == '\n') ||

+       (fromStr[i] == '\r') ) {

+    return toStr;

+  }

+

+  /* find the second " */

+

+  for (j=i+1;

+        (j<MaxFileName) &&

+        (fromStr[j] != '\n') &&

+        (fromStr[j] != '\r') &&

+        (fromStr[j] != '\"');

+       j++) /* nothing */ ;

+

+  if ((j == MaxFileName) ||

+      (fromStr[j] == '\n') ||

+      (fromStr[j] == '\r') ) {

+    return toStr;

+  }

+

+  /* go back until the last / or \ */

+

+  for (k=j-1;

+        (fromStr[k] != '\"') &&

+        (fromStr[k] != '/') &&

+        (fromStr[k] != '\\');

+       k--) /* nothing */ ;

+

+  /* copy the string after " / or \ into toStr */

+

+  for (i=k+1; fromStr[i] != '\"'; i++) {

+    toStr[i-k-1] = fromStr[i];

+  }

+

+  toStr[i-k-1] = '\0';

+

+  return toStr;

+}

+

+/* MR14 end of a block to support #line in antlr source code */

+

+>>

+

+<<

+

+/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */

+/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs            */

+/* MR2 Don't let #tokdefs be confused by 			*/

+/* MR2   DLGminToken and DLGmaxToken     			*/

+

+/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */

+

+#ifdef __USE_PROTOS

+static int isDLGmaxToken(char *Token)

+#else

+static int isDLGmaxToken(Token)

+  char *	Token;

+#endif

+{

+   static char checkStr1[] = "DLGmaxToken";

+   static char checkStr2[] = "DLGminToken";

+

+   if (strcmp(Token, checkStr1) == 0)

+      return 1;

+   else if (strcmp(Token, checkStr2) == 0)

+      return 1;

+   else

+      return 0;

+}

+

+/* semantics of #token */

+static void

+#ifdef __USE_PROTOS

+chkToken(char *t, char *e, char *a, int tnum)

+#else

+chkToken(t,e,a,tnum)

+char *t, *e, *a;

+int tnum;

+#endif

+{

+	TermEntry *p;

+

+	/* check to see that they don't try to redefine a token as a token class */

+	if ( t!=NULL ) {

+		p = (TermEntry *) hash_get(Tname, t);

+		if ( p!=NULL && p->classname ) {

+			err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t));

+			if ( a!=NULL ) free((char *)a);

+			return;

+		}

+	}

+

+	if ( t==NULL && e==NULL ) {			/* none found */

+		err("#token requires at least token name or rexpr");

+	}

+	else if ( t!=NULL && e!=NULL ) {	/* both found */

+		if ( UserDefdTokens ) {			/* if #tokdefs, must not define new */

+			p = (TermEntry *) hash_get(Tname, t);

+			if ( p == NULL) {

+err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));

+	    		return;

+            };

+		}

+		Tklink(t, e);

+		if ( a!=NULL ) {

+			if ( hasAction(e) ) {

+				err(eMsg1("redefinition of action for %s; ignored",e));

+			}

+			else setHasAction(e, a);

+		}

+	}

+	else if ( t!=NULL ) {				/* only one found */

+		if ( UserDefdTokens ) {

+			p = (TermEntry *) hash_get(Tname, t);

+            if (p == NULL) {

+err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));

+            };

+   		    return;

+		}

+		if ( Tnum( t ) == 0 ) addTname( t );

+		else {

+			err(eMsg1("redefinition of token %s; ignored",t));

+		}

+		if ( a!=NULL ) {

+			err(eMsg1("action cannot be attached to a token name (%s); ignored",t));

+			free((char *)a);

+		}

+	}

+	else if ( e!=NULL ) {

+		if ( Tnum( e ) == 0 ) addTexpr( e );

+		else {

+			if ( hasAction(e) ) {

+				err(eMsg1("redefinition of action for expr %s; ignored",e));

+			}

+			else if ( a==NULL ) {

+				err(eMsg1("redefinition of expr %s; ignored",e));

+			}

+		}

+		if ( a!=NULL ) setHasAction(e, a);

+	}

+

+	/* if a token type number was specified, then add the token ID and 'tnum'

+	 * pair to the ForcedTokens list.  (only applies if an id was given)

+	 */

+	if ( t!=NULL && tnum>0 )

+	{

+		if ( set_el(tnum, reserved_positions) )

+		{

+			err(eMsgd("a token has already been forced to token number %d; ignored", tnum));

+		}

+		else

+		{

+			list_add(&ForcedTokens, newForcedToken(t,tnum));

+			set_orel(tnum, &reserved_positions);

+		}

+	}

+}

+>>

+

+<<

+static int

+#ifdef __USE_PROTOS

+match_token(char *s, char **nxt)

+#else

+match_token(s,nxt)

+char *s;

+char **nxt;

+#endif

+{

+    if ( !(*s>='A' && *s<='Z') ) return 0;

+	s++;

+    while ( (*s>='a' && *s<='z') ||

+		    (*s>='A' && *s<='Z') ||

+		    (*s>='0' && *s<='9') ||

+		    *s=='_' )

+    {

+	   s++;

+	}

+	if ( *s!=' ' && *s!='}' ) return 0;

+	*nxt = s;

+	return 1;

+}

+

+static int

+#ifdef __USE_PROTOS

+match_rexpr(char *s, char **nxt)

+#else

+match_rexpr(s,nxt)

+char *s;

+char **nxt;

+#endif

+{

+    if ( *s!='"' ) return 0;

+	s++;

+    while ( *s!='"' )

+    {

+	   if ( *s=='\n' || *s=='\r' )                   /* MR13 */

+		  warn("eoln found in regular expression");

+	   if ( *s=='\\' ) s++;

+	   s++;

+	}

+	*nxt = s+1;

+	return 1;

+}

+

+/*

+ * Walk a string "{ A .. Z }" where A..Z is a space separated list

+ * of token references (either labels or reg exprs).  Return a

+ * string "inlineX_set" for some unique integer X.  Basically,

+ * we pretend as if we had seen "#tokclass inlineX { A .. Z }"

+ * on the input stream outside of an action.

+ */

+char *

+#ifdef __USE_PROTOS

+inline_set(char *s)

+#else

+inline_set(s)

+char *s;

+#endif

+{

+	char *nxt;

+    fprintf(stderr, "found consumeUntil( {...} )\n");

+	while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}

+	if ( *s!='{' )

+	{

+	   err("malformed consumeUntil( {...} ); missing '{'");

+	   return "bad_set";

+	}

+	s++;

+	while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}

+	while ( *s!='}' )

+	{

+	    if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s);

+		else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s);

+		else {

+		    err("invalid element in consumeUntil( {...} )");

+			return "bad_set";

+		}

+		s = nxt;

+		while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}

+	}

+	return "inlineX_set";

+}

+>>

+

+<<

+/* ANTLR-specific syntax error message generator

+ * (define USER_ZZSYN when compiling so don't get 2 definitions)

+ */

+void

+#ifdef __USE_PROTOS

+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok,

+int k, char *bad_text)

+#else

+zzsyn(text, tok, egroup, eset, etok, k, bad_text)

+char *text, *egroup, *bad_text;

+int tok;

+int etok;

+int k;

+SetWordType *eset;

+#endif

+{

+	fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline);

+	fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);

+	if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}

+	if ( k==1 ) fprintf(stderr, " missing");

+	else

+	{

+		fprintf(stderr, "; \"%s\" not", bad_text);

+		if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");

+	}

+	if ( zzset_deg(eset)>0 ) zzedecode(eset);

+	else fprintf(stderr, " %s", zztokens[etok]);

+	if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);

+	fprintf(stderr, "\n");

+}

+>>

+

+#lexaction <<

+#ifdef __USE_PROTOS

+void mark_label_used_in_sem_pred(LabelEntry *le)              /* MR10 */

+#else

+void mark_label_used_in_sem_pred(le)                          /* MR10 */

+  LabelEntry    *le;

+#endif

+{

+  TokNode   *tn;

+  require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");

+  tn=(TokNode *)le->elem;

+  require (tn->label != 0,"mark_label_used... TokNode has no label");

+  tn->label_used_in_semantic_pred=1;

+}

+>>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.r b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.r
new file mode 100644
index 0000000..e3de387
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr.r
@@ -0,0 +1,787 @@
+/*

+	File:		antlrMPW.r

+	Target:		antlr 133MR

+	Created:    Monday, June 15, 1998 4:41:11 AM

+	Author:		Kenji Tanaka (kentar@osa.att.ne.jp)

+*/

+

+#include "cmdo.r"

+

+resource 'cmdo' (128, "Antlr") {

+	{	/* array dialogs: 5 elements */

+		/* [1] */

+		295,

+		"ANTLR -- Purdue Compiler Construction To"

+		"ol Set (PCCTS) LL(k) parser generator.",

+		{	/* array itemArray: 12 elements */

+			/* [1] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{18, 23, 33, 223},

+				"Read grammar from stdin",

+				"-",

+				"Read grammar from stdin."

+			},

+			/* [2] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{38, 23, 53, 310},

+				"Send grammar.c/grammar.cpp to stdout",

+				"-stdout",

+				"Send grammar.c/grammar.cpp to stdout."

+			},

+			/* [3] */

+			NotDependent {

+

+			},

+			MultiFiles {

+				"Grammar File(s)É",

+				"Choose the grammar specification files y"

+				"ou wish to have ANTLR process.",

+				{79, 22, 98, 152},

+				"Grammar specification:",

+				"",

+				MultiInputFiles {

+					{	/* array MultiTypesArray: 1 elements */

+						/* [1] */

+						text

+					},

+					".g",

+					"Files ending in .g",

+					"All text files"

+				}

+			},

+			/* [4] */

+			NotDependent {

+

+			},

+			Files {

+				DirOnly,

+				OptionalFile {

+					{58, 168, 74, 298},

+					{79, 169, 98, 299},

+					"Output Directory",

+					":",

+					"-o",

+					"",

+					"Choose the directory where ANTLR will pu"

+					"t its output.",

+					dim,

+					"Output DirectoryÉ",

+					"",

+					""

+				},

+				NoMore {

+

+				}

+			},

+			/* [5] */

+			NotDependent {

+

+			},

+			Redirection {

+				StandardOutput,

+				{126, 27}

+			},

+			/* [6] */

+			NotDependent {

+

+			},

+			Redirection {

+				DiagnosticOutput,

+				{126, 178}

+			},

+			/* [7] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{117, 20, 167, 300},

+				"Redirection"

+			},

+			/* [8] */

+			NotDependent {

+

+			},

+			NestedDialog {

+				5,

+				{20, 324, 40, 460},

+				"Parse OptionsÉ",

+				"Parse control options may be set with th"

+				"is button."

+			},

+			/* [9] */

+			NotDependent {

+

+			},

+			NestedDialog {

+				2,

+				{50, 324, 70, 460},

+				"Generate OptionsÉ",

+				"Various command line options may be set "

+				"with this button."

+			},

+			/* [10] */

+			NotDependent {

+

+			},

+			NestedDialog {

+				3,

+				{78, 324, 98, 460},

+				"More OptionsÉ",

+				"Antlr has ALOT of options. There are eve"

+				"n more to be found with this button."

+			},

+			/* [11] */

+			NotDependent {

+

+			},

+			NestedDialog {

+				4,

+				{106, 324, 126, 460},

+				"Rename OptionsÉ",

+				"Options for renaming output files may be"

+				" set with this button."

+			},

+			/* [12] */

+			NotDependent {

+

+			},

+			VersionDialog {

+				VersionString {

+					"1.33MR"

+				},

+				"PCCTS was written by Terence Parr, Russe"

+				"ll Quong, Will Cohen, and Hank Dietz: 19"

+				"89-1998. MPW port by Scott Haney.",

+				noDialog

+			}

+		},

+		/* [2] */

+		295,

+		"Use this dialog to specify command line "

+		"Generate Options.",

+		{	/* array itemArray: 15 elements */

+			/* [1] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{18, 25, 33, 225},

+				"Generate C++ code",

+				"-CC",

+				"Generate C++ output from both ANTLR and "

+				"DLG."

+			},

+			/* [2] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{38, 25, 53, 225},

+				"Generate ASTs",

+				"-gt",

+				"Generate code for Abstract-Syntax-Trees "

+				"(ASTs)."

+			},

+			/* [3] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{58, 25, 73, 225},

+				"Generate line info",

+				"-gl",

+				"If this option is checked, ANTLR will ge"

+				"nerate line info about grammaractions, t"

+				"hereby making debugging easier since com"

+				"pile errors will point to the grammar fi"

+				"le."

+			},

+			/* [4] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{78, 25, 93, 225},

+				"Generate error classes",

+				"-ge",

+				"If this option is checked, ANTLR will ge"

+				"nerate an error class foreach non-termin"

+				"al."

+			},

+			/* [5] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{98, 25, 113, 225},

+				"Don't generate Code",

+				"-gc",

+				"If this option is checked, ANTLR will ge"

+				"nerate no code, i.e. it will only perfor"

+				"m analysis on the grammar."

+			},

+			/* [6] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{118, 25, 133, 225},

+				"Delay lookahead fetches",

+				"-gk",

+				"If this option is checked, ANTLR will ge"

+				"nerate a parser that delays lookahead fe"

+				"tches until needed."

+			},

+			/* [7] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{138, 25, 153, 225},

+				"Use newAST(...)",

+				"-newAST",

+				"In C++ mode use \"newAST(...)\" rather tha"

+				"n \"new AST(...)\""

+			},

+			/* [8] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{18, 235, 33, 435},

+				"Support parse traces",

+				"-gd",

+				"If this option is checked, ANTLR inserts"

+				" code in each parsing function to provid"

+				"e for user-defined handling of a detaile"

+				"d parse trace. The code consists of call"

+				"s to zzTRACEIN and zzTRACEOUT."

+			},

+			/* [9] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{38, 235, 53, 435},

+				"Generate cross-references",

+				"-cr",

+				"If this option is checked, ANTLR will ge"

+				"nerate a cross reference for all rules. "

+				"For each rule it will print a list of al"

+				"l other rules that refrence it."

+			},

+			/* [10] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{58, 235, 73, 435},

+				"Don't create Lexer files",

+				"-gx",

+				"If this option is checked, ANTLR will no"

+				"t generate DLG-related output files. Thi"

+				"s option should be used if one wants a c"

+				"ustom lexical analyzer or if one has mad"

+				"e changes to the grammar not affecting t"

+				"he lexical structure."

+			},

+			/* [11] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{78, 235, 93, 460},

+				"Don't generate token expr sets",

+				"-gs",

+				"If this option is checked, ANTLR will no"

+				"t generate sets for token expression set"

+				"s; instead, it will generate a || separa"

+				"ted sequence of LA(1)==token #. "

+			},

+			/* [12] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{98, 235, 113, 460},

+				"Generate ANSI-compatible",

+				"-ga",

+				"Generate ANSI-compatible code (default=F"

+				"ALSE)"

+			},

+			/* [13] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{118, 235, 133, 460},

+				"Don't generate tokens.h",

+				"-gxt",

+				"Do not generate tokens.h (default=FALSE)"

+			},

+			/* [13] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{138, 235, 153, 460},

+				"Provide \"(alpha)? beta\" info",

+				"-alpha",

+				"Provide additional information for \"(alpha)? beta\" error messages"

+			},

+			/* [14] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Tabs(1 to 8):",

+				{162, 23, 177, 117},

+				{163, 125, 179, 196},

+				"",

+				keepCase,

+				"-tab",

+				"Width of tabs (1 to 8) for grammar.c/gra"

+				"mmar.cpp files."

+			},

+			/* [15] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Function Prefix:",

+				{161, 236, 177, 342},

+				{162, 345, 177, 454},

+				"",

+				keepCase,

+				"-gp",

+				"Prefix all generated rule functions with"

+				" a string."

+			}

+		},

+		/* [3] */

+		295,

+		"Use this dialog to specify still more co"

+		"mmand line options.",

+		{	/* array itemArray: 12 elements */

+			/* [1] */

+			NotDependent {

+

+			},

+			RadioButtons {

+				{	/* array radioArray: 3 elements */

+					/* [1] */

+					{38, 25, 53, 85}, "None", "", Set, "When this option is selected, ANTLR will"

+					" not print the grammar to stdout.",

+					/* [2] */

+					{38, 100, 53, 160}, "Yes", "-p", NotSet, "When this option is selected, ANTLR will"

+					" print the grammar, stripped of all acti"

+					"ons and comments, to stdout.",

+					/* [3] */

+					{38, 175, 53, 235}, "More", "-pa", NotSet, "When this option is selected, ANTLR will"

+					" print the grammar, stripped of all acti"

+					"ons and comments, to stdout. It will als"

+					"o annotate the output with the first set"

+					"s determined from grammar analysis."

+				}

+			},

+			/* [2] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{28, 15, 60, 250},

+				"Grammar Printing"

+			},

+			/* [3] */

+			NotDependent {

+

+			},

+			RadioButtons {

+				{	/* array radioArray: 3 elements */

+					/* [1] */

+					{88, 25, 103, 85}, "Low", "", Set, "When this option is selected, ANTLR will"

+					" show ambiguities/errors in low detail.",

+					/* [2] */

+					{88, 100, 103, 160}, "Medium", "-e2", NotSet, "When this option is selected, ANTLR will"

+					" show ambiguities/errors in more detail.",

+					/* [3] */

+					{88, 175, 103, 235}, "High", "-e3", NotSet, "When this option is selected, ANTLR will"

+					" show ambiguities/errors in excruciating"

+					" detail."

+				}

+			},

+			/* [4] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{78, 15, 110, 250},

+				"Error reporting"

+			},

+			/* [5] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{130, 22, 145, 222},

+				"More warnings",

+				"-w2",

+				"If this option is checked, ANTLR will wa"

+				"rn if semantic predicates and/or (É)? bl"

+				"ocks are assumed to cover ambiguous alte"

+				"rnatives."

+			},

+			/* [6] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Report when tnode usage exceeds:",

+				{162, 23, 180, 253},

+				{162, 255, 178, 326},

+				"",

+				keepCase,

+				"-treport",

+				"Report when tnode usage exceeds value du"

+				"ring ambiguity resolution."

+			},

+			/* [7] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{40, 292, 55, 431},

+				"Predicate",

+				"-info p",

+				"With the antlr \"-info p\" switch the user"

+				" will receive information about the pred"

+				"icate suppression in the generated file."

+			},

+			/* [8] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{60, 292, 75, 430},

+				"Tree Nodes",

+				"-info t",

+				"Using \"-info t\" gives information about "

+				"the total number of tnodes created and t"

+				"he peak number of tnodes."

+			},

+			/* [9] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{80, 292, 95, 425},

+				"First/follow",

+				"-info f",

+				"first/follow set information."

+			},

+			/* [10] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{100, 292, 115, 425},

+				"Monitor progress",

+				"-info m",

+				"prints name of each rule as it is starte"

+				"d and flushes output at start of each rule."

+			},

+			/* [11] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{120, 292, 135, 416},

+				"Orphan rules",

+				"-info o",

+				"If there is more than one rule which is "

+				"not referenced by any other rule then al"

+				"l such rules are listed."

+			},

+			/* [12] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{28, 279, 147, 451},

+				"Extra info"

+			}

+		},

+		/* [4] */

+		295,

+		"Use this dialog to specify command line "

+		"options relating to renaming output file"

+		"s.",

+		{	/* array itemArray: 7 elements */

+			/* [1] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Errors file name:",

+				{35, 25, 50, 205},

+				{35, 205, 51, 300},

+				"err.c",

+				keepCase,

+				"-fe",

+				"This entry specifies the name ANTLR uses"

+				" for the errors file."

+			},

+			/* [2] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Lexical output name:",

+				{60, 25, 75, 205},

+				{60, 205, 76, 300},

+				"parser.dlg",

+				keepCase,

+				"-fl",

+				"This entry specifies the name ANTLR uses"

+				" for the lexical output file."

+			},

+			/* [3] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Lexical modes name:",

+				{85, 25, 100, 205},

+				{85, 205, 101, 300},

+				"mode.h",

+				keepCase,

+				"-fm",

+				"This entry specifies the name ANTLR uses"

+				" for the lexical mode definitions file."

+			},

+			/* [4] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Remap file name:",

+				{110, 25, 125, 205},

+				{110, 205, 126, 300},

+				"remap.h",

+				keepCase,

+				"-fr",

+				"This entry specifies the name ANTLR uses"

+				" for the file that remaps globally visib"

+				"le symbols."

+			},

+			/* [5] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Tokens file name:",

+				{135, 25, 150, 205},

+				{135, 205, 151, 300},

+				"tokens.h",

+				keepCase,

+				"-ft",

+				"This entry specifies the name ANTLR uses"

+				" for the tokens file."

+			},

+			/* [6] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{160, 25, 175, 175},

+				"Create std header",

+				"-gh",

+				"If this option is checked, ANTLR will cr"

+				"eate a standard header file named, by de"

+				"fault 'stdpccts.h'. This name can be alt"

+				"ered using the entry right next door."

+			},

+			/* [7] */

+			Or {

+				{	/* array OrArray: 1 elements */

+					/* [1] */

+					6

+				}

+			},

+			RegularEntry {

+				"Std header file name:",

+				{160, 175, 175, 355},

+				{160, 355, 176, 450},

+				"stdpccts.h",

+				keepCase,

+				"-fh",

+				"This entry specifies the name ANTLR uses"

+				" for the standard header file."

+			}

+		},

+		/* [5] */

+		295,

+		"Use this dialog to specify parse options"

+		".",

+		{	/* array itemArray: 9 elements */

+			/* [1] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Lookahead:",

+				{23, 27, 38, 152},

+				{46, 29, 62, 154},

+				"1",

+				keepCase,

+				"-k",

+				"This entry specifies the number of token"

+				"s of lookahead."

+			},

+			/* [2] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Compr lookahead:",

+				{22, 167, 37, 292},

+				{46, 172, 62, 297},

+				"",

+				keepCase,

+				"-ck",

+				"This entry specifies the number of token"

+				"s of lookahead when using compressed (li"

+				"near approximation) lookahead. In genera"

+				"l, the compressed lookahead is much deep"

+				"er than the full lookahead."

+			},

+			/* [3] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Max tree nodes:",

+				{22, 312, 37, 437},

+				{46, 315, 62, 445},

+				"",

+				keepCase,

+				"-rl",

+				"This entry specifies the maximum number "

+				"of tokens of tree nodes used by the gram"

+				"mar analysis."

+			},

+			/* [4] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{76, 25, 91, 350},

+				"Maintenance Release style hoisting",

+				"-mrhoist",

+				"Turn on/off k=1 Maintenance Release styl"

+				"e hoisting."

+			},

+			/* [5] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{96, 25, 111, 431},

+				"EXPERIMENTAL Maintenance Release style h"

+				"oisting",

+				"-mrhoistk",

+				"Turn on/off k>1 EXPERIMENTAL Maintenance"

+				" Release style hoisting."

+			},

+			/* [6] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{116, 25, 131, 363},

+				"Compute context for hoisted predicates",

+				"-prc on",

+				"Turn on/off computation of context for h"

+				"oisted predicates."

+			},

+			/* [7] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Ambiguity aid:",

+				{140, 27, 155, 125},

+				{141, 135, 155, 209},

+				"",

+				keepCase,

+				"-aa",

+				"Ambiguity aid for a rule (rule name or l"

+				"ine number)."

+			},

+			/* [8] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Limits exp growth:",

+				{140, 236, 155, 361},

+				{139, 372, 155, 452},

+				"",

+				keepCase,

+				"-aad",

+				"Limits exp growth of -aa listing - defau"

+				"lt=1 (max=ck value)."

+			},

+			/* [9] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{164, 26, 179, 366},

+				"Lookahead token may appear multiple time"

+				"s",

+				"-aam",

+				"Lookahead token may appear multiple time"

+				"s in -aa listing."

+			}

+		}

+	}

+};

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr1.txt b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr1.txt
new file mode 100644
index 0000000..4a7d22e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/antlr1.txt
@@ -0,0 +1,264 @@
+

+

+

+ANTLR(1)               PCCTS Manual Pages                ANTLR(1)

+

+

+

+NAME

+     antlr - ANother Tool for Language Recognition

+

+SYNTAX

+     antlr [_o_p_t_i_o_n_s] _g_r_a_m_m_a_r__f_i_l_e_s

+

+DESCRIPTION

+     _A_n_t_l_r converts an extended form of context-free grammar into

+     a set of C functions which directly implement an efficient

+     form of deterministic recursive-descent LL(k) parser.

+     Context-free grammars may be augmented with predicates to

+     allow semantics to influence parsing; this allows a form of

+     context-sensitive parsing.  Selective backtracking is also

+     available to handle non-LL(k) and even non-LALR(k) con-

+     structs.  _A_n_t_l_r also produces a definition of a lexer which

+     can be automatically converted into C code for a DFA-based

+     lexer by _d_l_g.  Hence, _a_n_t_l_r serves a function much like that

+     of _y_a_c_c, however, it is notably more flexible and is more

+     integrated with a lexer generator (_a_n_t_l_r directly generates

+     _d_l_g code, whereas _y_a_c_c and _l_e_x are given independent

+     descriptions).  Unlike _y_a_c_c which accepts LALR(1) grammars,

+     _a_n_t_l_r accepts LL(k) grammars in an extended BNF notation -

+     which eliminates the need for precedence rules.

+

+     Like _y_a_c_c grammars, _a_n_t_l_r grammars can use automatically-

+     maintained symbol attribute values referenced as dollar

+     variables.  Further, because _a_n_t_l_r generates top-down

+     parsers, arbitrary values may be inherited from parent rules

+     (passed like function parameters).  _A_n_t_l_r also has a mechan-

+     ism for creating and manipulating abstract-syntax-trees.

+

+     There are various other niceties in _a_n_t_l_r, including the

+     ability to spread one grammar over multiple files or even

+     multiple grammars in a single file, the ability to generate

+     a version of the grammar with actions stripped out (for

+     documentation purposes), and lots more.

+

+OPTIONS

+     -ck _n

+          Use up to _n symbols of lookahead when using compressed

+          (linear approximation) lookahead.  This type of looka-

+          head is very cheap to compute and is attempted before

+          full LL(k) lookahead, which is of exponential complex-

+          ity in the worst case.  In general, the compressed loo-

+          kahead can be much deeper (e.g, -ck 10) _t_h_a_n _t_h_e _f_u_l_l

+          _l_o_o_k_a_h_e_a_d (_w_h_i_c_h _u_s_u_a_l_l_y _m_u_s_t _b_e _l_e_s_s _t_h_a_n _4).

+

+     -CC  Generate C++ output from both ANTLR and DLG.

+

+     -cr  Generate a cross-reference for all rules.  For each

+          rule, print a list of all other rules that reference

+          it.

+

+     -e1  Ambiguities/errors shown in low detail (default).

+

+     -e2  Ambiguities/errors shown in more detail.

+

+     -e3  Ambiguities/errors shown in excruciating detail.

+

+     -fe file

+          Rename err.c to file.

+

+     -fh file

+          Rename stdpccts.h header (turns on -gh) to file.

+

+     -fl file

+          Rename lexical output, parser.dlg, to file.

+

+     -fm file

+          Rename file with lexical mode definitions, mode.h, to

+          file.

+

+     -fr file

+          Rename file which remaps globally visible symbols,

+          remap.h, to file.

+

+     -ft file

+          Rename tokens.h to file.

+

+     -ga  Generate ANSI-compatible code (default case).  This has

+          not been rigorously tested to be ANSI XJ11 C compliant,

+          but it is close.  The normal output of _a_n_t_l_r is

+          currently compilable under both K&R, ANSI C, and C++-

+          this option does nothing because _a_n_t_l_r generates a

+          bunch of #ifdef's to do the right thing depending on

+          the language.

+

+     -gc  Indicates that _a_n_t_l_r should generate no C code, i.e.,

+          only perform analysis on the grammar.

+

+     -gd  C code is inserted in each of the _a_n_t_l_r generated pars-

+          ing functions to provide for user-defined handling of a

+          detailed parse trace.  The inserted code consists of

+          calls to the user-supplied macros or functions called

+          zzTRACEIN and zzTRACEOUT.  The only argument is a _c_h_a_r

+          * pointing to a C-style string which is the grammar

+          rule recognized by the current parsing function.  If no

+          definition is given for the trace functions, upon rule

+          entry and exit, a message will be printed indicating

+          that a particular rule as been entered or exited.

+

+     -ge  Generate an error class for each non-terminal.

+

+     -gh  Generate stdpccts.h for non-ANTLR-generated files to

+          include.  This file contains all defines needed to

+          describe the type of parser generated by _a_n_t_l_r (e.g.

+          how much lookahead is used and whether or not trees are

+          constructed) and contains the header action specified

+          by the user.

+

+     -gk  Generate parsers that delay lookahead fetches until

+          needed.  Without this option, _a_n_t_l_r generates parsers

+          which always have _k tokens of lookahead available.

+

+     -gl  Generate line info about grammar actions in C parser of

+          the form # _l_i_n_e "_f_i_l_e" which makes error messages from

+          the C/C++ compiler make more sense as they will point

+          into the grammar file not the resulting C file.

+          Debugging is easier as well, because you will step

+          through the grammar not C file.

+

+     -gs  Do not generate sets for token expression lists;

+          instead generate a ||-separated sequence of

+          LA(1)==_t_o_k_e_n__n_u_m_b_e_r.  The default is to generate sets.

+

+     -gt  Generate code for Abstract-Syntax Trees.

+

+     -gx  Do not create the lexical analyzer files (dlg-related).

+          This option should be given when the user wishes to

+          provide a customized lexical analyzer.  It may also be

+          used in _m_a_k_e scripts to cause only the parser to be

+          rebuilt when a change not affecting the lexical struc-

+          ture is made to the input grammars.

+

+     -k _n Set k of LL(k) to _n; i.e. set tokens of look-ahead

+          (default==1).

+

+     -o dir

+          Directory where output files should go (default=".").

+          This is very nice for keeping the source directory

+          clear of ANTLR and DLG spawn.

+

+     -p   The complete grammar, collected from all input grammar

+          files and stripped of all comments and embedded

+          actions, is listed to stdout.  This is intended to aid

+          in viewing the entire grammar as a whole and to elim-

+          inate the need to keep actions concisely stated so that

+          the grammar is easier to read.  Hence, it is preferable

+          to embed even complex actions directly in the grammar,

+          rather than to call them as subroutines, since the sub-

+          routine call overhead will be saved.

+

+     -pa  This option is the same as -p except that the output is

+          annotated with the first sets determined from grammar

+          analysis.

+

+     -prc on

+          Turn on the computation and hoisting of predicate con-

+          text.

+

+     -prc off

+          Turn off the computation and hoisting of predicate con-

+          text.  This option makes 1.10 behave like the 1.06

+          release with option -pr on.  Context computation is off

+          by default.

+

+     -rl _n

+          Limit the maximum number of tree nodes used by grammar

+          analysis to _n.  Occasionally, _a_n_t_l_r is unable to

+          analyze a grammar submitted by the user.  This rare

+          situation can only occur when the grammar is large and

+          the amount of lookahead is greater than one.  A non-

+          linear analysis algorithm is used by PCCTS to handle

+          the general case of LL(k) parsing.  The average com-

+          plexity of analysis, however, is near linear due to

+          some fancy footwork in the implementation which reduces

+          the number of calls to the full LL(k) algorithm.  An

+          error message will be displayed, if this limit is

+          reached, which indicates the grammar construct being

+          analyzed when _a_n_t_l_r hit a non-linearity.  Use this

+          option if _a_n_t_l_r seems to go out to lunch and your disk

+          start thrashing; try _n=10000 to start.  Once the

+          offending construct has been identified, try to remove

+          the ambiguity that _a_n_t_l_r was trying to overcome with

+          large lookahead analysis.  The introduction of (...)?

+          backtracking blocks eliminates some of these problems -

+          _a_n_t_l_r does not analyze alternatives that begin with

+          (...)? (it simply backtracks, if necessary, at run

+          time).

+

+     -w1  Set low warning level.  Do not warn if semantic

+          predicates and/or (...)? blocks are assumed to cover

+          ambiguous alternatives.

+

+     -w2  Ambiguous parsing decisions yield warnings even if

+          semantic predicates or (...)? blocks are used.  Warn if

+          predicate context computed and semantic predicates

+          incompletely disambiguate alternative productions.

+

+     -    Read grammar from standard input and generate stdin.c

+          as the parser file.

+

+SPECIAL CONSIDERATIONS

+     _A_n_t_l_r works...  we think.  There is no implicit guarantee of

+     anything.  We reserve no legal rights to the software known

+     as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS

+     is in the public domain.  An individual or company may do

+     whatever they wish with source code distributed with PCCTS

+     or the code generated by PCCTS, including the incorporation

+     of PCCTS, or its output, into commercial software.  We

+     encourage users to develop software with PCCTS.  However, we

+     do ask that credit is given to us for developing PCCTS.  By

+     "credit", we mean that if you incorporate our source code

+     into one of your programs (commercial product, research pro-

+     ject, or otherwise) that you acknowledge this fact somewhere

+     in the documentation, research report, etc...  If you like

+     PCCTS and have developed a nice tool with the output, please

+     mention that you developed it using PCCTS.  As long as these

+     guidelines are followed, we expect to continue enhancing

+     this system and expect to make other tools available as they

+     are completed.

+

+FILES

+     *.c  output C parser.

+

+     *.cpp

+          output C++ parser when C++ mode is used.

+

+     parser.dlg

+          output _d_l_g lexical analyzer.

+

+     err.c

+          token string array, error sets and error support rou-

+          tines.  Not used in C++ mode.

+

+     remap.h

+          file that redefines all globally visible parser sym-

+          bols.  The use of the #parser directive creates this

+          file.  Not used in C++ mode.

+

+     stdpccts.h

+          list of definitions needed by C files, not generated by

+          PCCTS, that reference PCCTS objects.  This is not gen-

+          erated by default.  Not used in C++ mode.

+

+     tokens.h

+          output #_d_e_f_i_n_e_s for tokens used and function prototypes

+          for functions generated for rules.

+

+

+SEE ALSO

+     dlg(1), pccts(1)

+

+

+

+

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/bits.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/bits.c
new file mode 100644
index 0000000..ddd9bd6
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/bits.c
@@ -0,0 +1,1025 @@
+/* bits.c -- manage creation and output of bit sets used by the parser.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <ctype.h>

+#include <assert.h>

+#include "pcctscfg.h"

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+

+/* char is only thing that is pretty much always known == 8 bits

+ * This allows output of antlr (set stuff, anyway) to be androgynous (portable)

+ */

+typedef unsigned char SetWordType;

+#define BitsPerByte		8

+#define BitsPerWord		BitsPerByte*sizeof(SetWordType)

+

+static SetWordType *setwd = NULL;

+int setnum = -1;

+int wordnum = 0;

+

+int esetnum = 0;

+

+/* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets,

+   to bytes that are most portable size-wise.

+   */

+void

+#ifdef __USE_PROTOS

+DumpIntAsChars( FILE *f, char *format, unsigned wd )

+#else

+DumpIntAsChars( f, format, wd )

+FILE *f;

+char *format;

+unsigned wd;

+#endif

+{

+	int i;

+	/* uses max of 32 bit unsigned integer for the moment */

+	static unsigned long byte_mask[sizeof(unsigned long)] =

+				{ 0xFF, 0xFF00UL, 0xFF0000UL, 0xFF000000UL };  /* MR20 G. Hobbelt */

+/*				  0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/

+

+	/* for each byte in the word */

+	assert(sizeof(unsigned) <= 4); /* M20 G. Hobbelt Sanity check */

+	for (i=0; i<sizeof(unsigned); i++)

+	{

+		/* mask out the ith byte and shift down to the first 8 bits */

+		fprintf(f, format, (wd&byte_mask[i])>>(i*BitsPerByte));

+		if ( i<sizeof(unsigned)-1) fprintf(f, ",");

+	}

+}

+

+/* Create a new setwd (ignoring [Ep] token on end) */

+void

+#ifdef __USE_PROTOS

+NewSetWd( void )

+#else

+NewSetWd( )

+#endif

+{

+	SetWordType *p;

+

+	if ( setwd == NULL )

+	{

+		setwd = (SetWordType *) calloc(TokenNum, sizeof(SetWordType));

+		require(setwd!=NULL, "NewSetWd: cannot alloc set wd\n");

+	}

+	for (p = setwd; p<&(setwd[TokenNum]); p++)  {*p=0;}

+	wordnum++;

+}

+

+void

+#ifdef __USE_PROTOS

+DumpSetWd( void )

+#else

+DumpSetWd( )

+#endif

+{

+	if ( GenCC ) DumpSetWdForCC();

+	else DumpSetWdForC();

+}

+

+/* Dump the current setwd to ErrFile. 0..MaxTokenVal */

+void

+#ifdef __USE_PROTOS

+DumpSetWdForC( void )

+#else

+DumpSetWdForC( )

+#endif

+{

+	int i,c=1;

+

+	if ( setwd==NULL ) return;

+	fprintf(DefFile, "extern SetWordType setwd%d[];\n", wordnum);

+	fprintf(ErrFile,

+			"SetWordType setwd%d[%d] = {", wordnum, TokenNum-1);

+	for (i=0; i<TokenNum-1; i++)

+	{

+		DAWDLE;

+		if ( i!=0 ) fprintf(ErrFile, ",");

+		if ( c == 8 ) {fprintf(ErrFile, "\n\t"); c=1;} else c++;

+		fprintf(ErrFile, "0x%x", setwd[i]);

+	}

+	fprintf(ErrFile, "};\n");

+}

+

+/* Dump the current setwd to Parser.C file. 0..MaxTokenVal;

+ * Only used if -CC on.

+ */

+void

+#ifdef __USE_PROTOS

+DumpSetWdForCC( void )

+#else

+DumpSetWdForCC( )

+#endif

+{

+	int i,c=1;

+

+	if ( setwd==NULL ) return;

+	fprintf(Parser_h, "\tstatic SetWordType setwd%d[%d];\n", wordnum, TokenNum-1);

+	fprintf(Parser_c,

+			"SetWordType %s::setwd%d[%d] = {", CurrentClassName, wordnum,

+			TokenNum-1);

+	for (i=0; i<TokenNum-1; i++)

+	{

+		DAWDLE;

+		if ( i!=0 ) fprintf(Parser_c, ",");

+		if ( c == 8 ) {fprintf(Parser_c, "\n\t"); c=1;} else c++;

+		fprintf(Parser_c, "0x%x", setwd[i]);

+	}

+	fprintf(Parser_c, "};\n");

+}

+

+/* Make a new set.  Dump old setwd and create new setwd if current setwd is full */

+void

+#ifdef __USE_PROTOS

+NewSet( void )

+#else

+NewSet( )

+#endif

+{

+	setnum++;

+	if ( setnum==BitsPerWord )		/* is current setwd full? */

+	{

+		DumpSetWd(); NewSetWd(); setnum = 0;

+	}

+}

+

+/* s is a set of tokens.  Turn on bit at each token position in set 'setnum' */

+void

+#ifdef __USE_PROTOS

+FillSet( set s )

+#else

+FillSet( s )

+set s;

+#endif

+{

+	SetWordType mask=(((unsigned)1)<<setnum);

+	unsigned int e;

+

+	while ( !set_nil(s) )

+	{

+		e = set_int(s);

+		set_rm(e, s);

+		setwd[e] |= mask;

+	}

+}

+

+					/* E r r o r  C l a s s  S t u f f */

+

+/* compute the FIRST of a rule for the error class stuff */

+static set

+#ifdef __USE_PROTOS

+Efirst( char *rule, ECnode *eclass )

+#else

+Efirst( rule, eclass )

+char *rule;

+ECnode *eclass;

+#endif

+{

+	set rk, a;

+	Junction *r;

+	RuleEntry *q = (RuleEntry *) hash_get(Rname, rule);

+

+	if ( q == NULL )

+	{

+		warnNoFL(eMsg2("undefined rule '%s' referenced in errclass '%s'; ignored",

+						rule, TokenString(eclass->tok)));

+		return empty;

+	}

+	r = RulePtr[q->rulenum];

+	r->end->halt = TRUE;		/* don't let reach fall off end of rule here */

+	rk = empty;

+	REACH(r, 1, &rk, a);

+	r->end->halt = FALSE;

+	return a;

+}

+

+/*

+ * scan the list of tokens/eclasses/nonterminals filling the new eclass

+ * with the set described by the list.  Note that an eclass can be

+ * quoted to allow spaces etc... However, an eclass must not conflict

+ * with a reg expr found elsewhere.  The reg expr will be taken over

+ * the eclass name.

+ */

+static void

+#ifdef __USE_PROTOS

+doEclass( char *eclass )

+#else

+doEclass( eclass )

+char *eclass;

+#endif

+{

+	TermEntry *q;

+	ECnode *p;

+	TCnode *tcnode;

+	ListNode *e;

+	unsigned int t;

+	unsigned deg=0;

+	set a;

+	require(eclass!=NULL, "doEclass: NULL eset");

+	

+	p = (ECnode *) eclass;

+	lexmode(p->lexclass);	/* switch to lexclass where errclass is defined */

+	p->eset = empty;

+	for (e = (p->elist)->next; e!=NULL; e=e->next)

+	{

+		q = NULL;								/* MR23 */

+

+		if ( islower( *((char *)e->elem) ) )	/* is it a rule ref? (alias FIRST request) */

+		{

+			a = Efirst((char *)e->elem, p);

+			set_orin(&p->eset, a);

+			deg += set_deg(a);

+			set_free( a );

+			continue;

+		}

+		else if ( *((char *)e->elem)=='"' )

+		{

+			t = 0;

+			q = (TermEntry *) hash_get(Texpr, (char *) e->elem);

+			if ( q == NULL )

+			{

+				/* if quoted and not an expr look for eclass name */

+				q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem));

+				if ( q != NULL ) t = q->token;

+			}

+			else t = q->token;

+		}

+		else	/* labelled token/eclass/tokclass */

+		{

+			q = (TermEntry *) hash_get(Tname, (char *)e->elem);

+			if ( q != NULL )

+			{

+				if ( strcmp((char *)e->elem, TokenString(p->tok))==0 )

+				{

+					warnNoFL(eMsg1("self-referential error class '%s'; ignored",

+								   (char *)e->elem));

+					continue;

+				}

+				else

+					t = q->token;

+			}

+			else t=0;

+		}

+		if ( t!=0 )

+		{

+			if (isTermEntryTokClass(q))  {			/* MR23 */

+			    tcnode = q->tclass;					/* MR23 */

+				set_orin(&p->eset, tcnode->tset);	/* MR23 */

+				deg = set_deg(p->eset);				/* MR23 */

+			}										/* MR23 */

+			else {

+				set_orel(t, &p->eset);

+				deg++;

+			}

+		}

+		else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored",

+							(char *)e->elem, TokenString(p->tok)));

+	}

+	p->setdeg = deg;

+}

+

+void

+#ifdef __USE_PROTOS

+ComputeErrorSets( void )

+#else

+ComputeErrorSets( )

+#endif

+{

+#ifdef __cplusplus

+    list_apply(eclasses, (void (*)(void *)) doEclass);

+#else

+#ifdef __USE_PROTOS

+    list_apply(eclasses, (void (*)(void *)) doEclass);

+#else

+    list_apply(eclasses, doEclass);

+#endif

+#endif

+}

+

+void

+#ifdef __USE_PROTOS

+ComputeTokSets( void )

+#else

+ComputeTokSets( )

+#endif

+{

+	ListNode *t, *e = NULL, *e1, *e2;

+	int something_changed;

+    int i;

+	TCnode *p;

+	TermEntry *q, *q1, *q2;

+

+	if ( tclasses == NULL ) return;

+

+	/* turn lists of token/tokclass references into sets */

+	for (t = tclasses->next; t!=NULL; t=t->next)

+	{

+		p = (TCnode *) t->elem;

+

+		/* if wild card, then won't have entries in tclass, assume all_tokens */

+		if ( p->tok == WildCardToken )

+		{

+			p->tset = set_dup(all_tokens);

+			continue;

+		}

+

+		lexmode(p->lexclass);	/* switch to lexclass where tokclass is defined */

+		p->tset = empty;

+

+		/* instantiate all tokens/token_classes into the tset */

+		for (e = (p->tlist)->next; e!=NULL; e=e->next)

+		{

+			char *tokstr;

+			tokstr = (char *)e->elem;

+			if ( *tokstr == '"' ) {

+                q = (TermEntry *) hash_get(Texpr, tokstr);

+    			require(q!=NULL, "ComputeTokSets: no token def");

+    			set_orel(q->token, &p->tset);

+			} else if (tokstr[0] == '.') {

+                e1=e->next;

+                e2=e1->next;

+                e=e2;

+                q1= (TermEntry *) hash_get(Tname, (char *)e1->elem);

+    			require(q1!=NULL, "ComputeTokSets: no token def");

+                q2= (TermEntry *) hash_get(Tname, (char *)e2->elem);

+    			require(q2!=NULL, "ComputeTokSets: no token def");

+

+                if (set_el(q1->token,imag_tokens)) {

+errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s",

+                        TokenString(p->tok),(char *)e1->elem) );

+                }

+                if (set_el(q2->token,imag_tokens)) {

+errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s",

+                        TokenString(p->tok),(char *)e2->elem) );

+                }

+                if (q1->token > q2->token) {

+errNoFL(eMsg3("for #tokclass %s %s..%s - first token number > second token number",

+                        TokenString(p->tok),(char *)e1->elem,(char *)e2->elem) );

+                  for (i=q2->token; i<=q1->token; i++) { set_orel(i, &p->tset); }

+                } else {

+                  for (i=q1->token; i<=q2->token; i++) { set_orel(i, &p->tset); }

+                }

+            } else {

+                q = (TermEntry *) hash_get(Tname, tokstr);

+    			require(q!=NULL, "ComputeTokSets: no token def");

+    			set_orel(q->token, &p->tset);

+            }

+		}

+	}

+

+	/* Go thru list of tokclasses again looking for tokclasses in sets */

+again:

+	something_changed = 0;

+	for (t = tclasses->next; t!=NULL; t=t->next)

+	{

+		set tcl;

+		p = (TCnode *) t->elem;

+		tcl = set_and(p->tset, tokclasses);

+		if ( !set_nil(tcl) )

+		{

+			int tk;

+			/* replace refs to tokclasses with the associated set of tokens */

+			something_changed = 1;

+			while ( !set_nil(tcl) )

+			{

+				tk = set_int(tcl);		/* grab one of the tok class refs */

+				set_rm(tk, tcl);

+				if ( p->tok != tk )		/* tokclass ref to yourself? */

+				{

+					q = (TermEntry *) hash_get(Tname, TokenString(tk));

+					require(q!=NULL, "#tokclass not in hash table");

+					set_orin(&p->tset, q->tclass->tset);

+				}

+				set_rm(tk, p->tset);	/* remove ref that we replaced */

+			}

+		}

+		set_free(tcl);

+	}

+	if ( something_changed ) goto again;

+}

+

+void

+#ifdef __USE_PROTOS

+DumpRemainingTokSets(void)

+#else

+DumpRemainingTokSets()

+#endif

+{

+	TCnode *p;

+	ListNode *t;

+

+	/* Go thru tclasses (for the last time) and dump the sets not dumped

+	 * during code gen; yes, this is a bogus way to do this, but ComputeTokSets()

+	 * can't dump the defs as the error file and tok file has not been created

+	 * yet etc...

+	 */

+	if ( tclasses==NULL ) return;

+	for (t = tclasses->next; t!=NULL; t=t->next)

+	{

+		unsigned e;

+		p = (TCnode *) t->elem;

+		if ( p->dumped ) continue;

+		e = DefErrSet(&(p->tset), 0, TokenString(p->tok));

+		p->dumped = 1;

+		p->setnum = e;

+	}

+}

+

+

+/* replace a subset of an error set with an error class name if a subset is found

+ * repeat process until no replacements made

+ */

+void

+#ifdef __USE_PROTOS

+SubstErrorClass( set *f )

+#else

+SubstErrorClass( f )

+set *f;

+#endif

+{

+	int max, done = 0;

+	ListNode *p;

+	ECnode *ec, *maxclass = NULL;

+	set a;

+	require(f!=NULL, "SubstErrorClass: NULL eset");

+

+	if ( eclasses == NULL ) return;

+	while ( !done )

+	{

+		max = 0;

+		maxclass = NULL;

+		for (p=eclasses->next; p!=NULL; p=p->next)	/* chk all error classes */

+		{

+			ec = (ECnode *) p->elem;

+			if ( ec->setdeg > max )

+			{

+				if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) )

+					{maxclass = ec; max=ec->setdeg;}

+			}

+		}

+		if ( maxclass != NULL )	/* if subset found, replace with token */

+		{

+			a = set_dif(*f, maxclass->eset);

+			set_orel((unsigned)maxclass->tok, &a);

+			set_free(*f);

+			*f = a;

+		}

+		else done = 1;

+	}

+}

+

+int

+#ifdef __USE_PROTOS

+DefErrSet1(int nilOK, set *f, int subst, char *name )

+#else

+DefErrSet1(nilOK, f, subst, name )

+int nilOK;

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+#endif

+{

+	if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, "_set");

+	else return DefErrSetForC1(nilOK, f, subst, name, "_set");

+}

+

+int

+#ifdef __USE_PROTOS

+DefErrSet( set *f, int subst, char *name )

+#else

+DefErrSet( f, subst, name )

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+#endif

+{

+    return DefErrSet1(0,f,subst,name);

+}

+

+int

+#ifdef __USE_PROTOS

+DefErrSetWithSuffix(int nilOK, set *f, int subst, char *name, const char* suffix)

+#else

+DefErrSetWithSuffix(nilOK, f, subst, name, suffix )

+int nilOK;

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+char *suffix;

+#endif

+{

+	if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, suffix );

+	else return DefErrSetForC1(nilOK, f, subst, name, suffix);

+}

+

+/* Define a new error set.  WARNING...set-implementation dependent.

+ */

+int

+#ifdef __USE_PROTOS

+DefErrSetForC1(int nilOK, set *f, int subst, char * name, const char * suffix)

+#else

+DefErrSetForC1(nilOK, f, subst, name, suffix)

+int nilOK;          /* MR13 */

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+const char *suffix;

+#endif

+{

+	unsigned *p, *endp;

+	int e=1;

+

+    if (!nilOK)	require(!set_nil(*f), "DefErrSetForC1: nil set to dump?");

+

+	if ( subst ) SubstErrorClass(f);

+	p = f->setword;

+	endp = &(f->setword[f->n]);

+	esetnum++;

+	if ( name!=NULL )

+		fprintf(DefFile, "extern SetWordType %s%s[];\n", name, suffix);

+	else

+		fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum);

+	if ( name!=NULL ) {

+		fprintf(ErrFile, "SetWordType %s%s[%d] = {",

+				name,

+                suffix,

+				NumWords(TokenNum-1)*sizeof(unsigned));

+	}

+	else {

+		fprintf(ErrFile, "SetWordType zzerr%d[%d] = {",

+				esetnum,

+				NumWords(TokenNum-1)*sizeof(unsigned));

+	}

+	while ( p < endp )

+	{

+		if ( e > 1 ) fprintf(ErrFile, ", ");

+		DumpIntAsChars(ErrFile, "0x%x", *p++);

+		if ( e == 3 )

+		{

+			DAWDLE;

+			if ( p < endp ) fprintf(ErrFile, ",");

+			fprintf(ErrFile, "\n\t");

+			e=1;

+		}

+		else e++;

+	}

+	fprintf(ErrFile, "};\n");

+

+	return esetnum;

+}

+

+int

+#ifdef __USE_PROTOS

+DefErrSetForC( set *f, int subst, char *name )

+#else

+DefErrSetForC( f, subst, name )

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+#endif

+{

+  return DefErrSetForC1(0,f,subst,name, "_set");

+}

+

+/* Define a new error set.  WARNING...set-implementation dependent;

+ * Only used when -CC on.

+ */

+

+int

+#ifdef __USE_PROTOS

+DefErrSetForCC1(int nilOK, set *f, int subst, char *name, const char *suffix )

+#else

+DefErrSetForCC1(nilOK, f, subst, name, suffix )

+int nilOK;          /* MR13 */

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+const char *suffix;

+#endif

+{

+	unsigned *p, *endp;

+	int e=1;

+

+    if (!nilOK)	require(!set_nil(*f), "DefErrSetForCC1: nil set to dump?");

+

+	if ( subst ) SubstErrorClass(f);

+	p = f->setword;

+	endp = &(f->setword[f->n]);

+	esetnum++;

+

+	if ( name!=NULL ) {

+		fprintf(Parser_h, "\tstatic SetWordType %s%s[%d];\n", name, suffix,

+				NumWords(TokenNum-1)*sizeof(unsigned));

+		fprintf(Parser_c, "SetWordType %s::%s%s[%d] = {",

+				CurrentClassName,

+				name,

+				suffix,

+				NumWords(TokenNum-1)*sizeof(unsigned));

+	}

+	else {

+		fprintf(Parser_c, "SetWordType %s::err%d[%d] = {",

+				CurrentClassName,

+				esetnum,

+				NumWords(TokenNum-1)*sizeof(unsigned));

+		fprintf(Parser_h, "\tstatic SetWordType err%d[%d];\n", esetnum,

+				NumWords(TokenNum-1)*sizeof(unsigned));

+	}

+

+	while ( p < endp )

+	{

+		if ( e > 1 ) fprintf(Parser_c, ", ");

+		DumpIntAsChars(Parser_c, "0x%x", *p++);

+		if ( e == 3 )

+		{

+			if ( p < endp ) fprintf(Parser_c, ",");

+			fprintf(Parser_c, "\n\t");

+			e=1;

+		}

+		else e++;

+	}

+	fprintf(Parser_c, "};\n");

+

+	return esetnum;

+}

+

+int

+#ifdef __USE_PROTOS

+DefErrSetForCC( set *f, int subst, char *name )

+#else

+DefErrSetForCC( f, subst, name )

+set *f;

+int subst;			/* should be substitute error classes? */

+char *name;

+#endif

+{

+  return DefErrSetForCC1(0,f,subst,name, "_set");

+}

+

+void

+#ifdef __USE_PROTOS

+GenParser_c_Hdr(void)

+#else

+GenParser_c_Hdr()

+#endif

+{

+	int i,j;

+    TermEntry   *te;

+    char * hasAkaName = NULL;									/* MR23 */

+

+	hasAkaName = (char *) malloc(TokenNum+1);					/* MR23 */

+	require(hasAkaName!=NULL, "Cannot alloc hasAkaName\n");		/* MR23 */

+	for (i = 0; i < TokenNum; i++) hasAkaName[i]='0';			/* MR23 */

+	hasAkaName[TokenNum] = 0;                                   /* MR23 */

+

+	fprintf(Parser_c, "/*\n");

+	fprintf(Parser_c, " * %s: P a r s e r  S u p p o r t\n", CurrentClassName);

+	fprintf(Parser_c, " *\n");

+	fprintf(Parser_c, " * Generated from:");

+	for (i=0; i<NumFiles; i++) fprintf(Parser_c, " %s", FileStr[i]);

+	fprintf(Parser_c, "\n");

+	fprintf(Parser_c, " *\n");

+	fprintf(Parser_c, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");

+	fprintf(Parser_c, " * Parr Research Corporation\n");

+	fprintf(Parser_c, " * with Purdue University Electrical Engineering\n");

+	fprintf(Parser_c, " * with AHPCRC, University of Minnesota\n");

+	fprintf(Parser_c, " * ANTLR Version %s\n", Version);

+	fprintf(Parser_c, " */\n\n");

+	

+  if ( FirstAction != NULL ) dumpAction(FirstAction,Parser_c, 0, -1, 0, 1);    /* MR11 MR15b */

+

+	fprintf(Parser_c, "#define ANTLR_VERSION	%s\n", VersionDef);

+

+	fprintf(Parser_c, "#include \"pcctscfg.h\"\n");

+	fprintf(Parser_c, "#include \"pccts_stdio.h\"\n");

+	fprintf(Parser_c, "#define ANTLR_SUPPORT_CODE\n");

+	if ( UserTokenDefsFile != NULL )

+	   fprintf(Parser_c, "#include %s\n", UserTokenDefsFile);

+	else

+	   fprintf(Parser_c, "#include \"%s\"\n", DefFileName);

+

+	fprintf(Parser_c, "#include \"%s.h\"\n\n", CurrentClassName);

+

+	fprintf(Parser_c, "const ANTLRChar *%s::tokenName(int tok) ",   /* MR1 */

+					CurrentClassName);                  	        /* MR1 */

+	fprintf(Parser_c, "  { return _token_tbl[tok]; }\n");	        /* MR1 */ /* MR10 */

+	/* Dump a Parser::tokens for each automaton */

+	fprintf(Parser_c, "\nconst ANTLRChar *%s::_token_tbl[]={\n",

+                                                 CurrentClassName); /* MR20 */

+	fprintf(Parser_c, "\t/* 00 */\t\"Invalid\"");

+

+	for (i=1; i<TokenNum-1; i++)

+	{

+		DAWDLE;

+		if ( i == EpToken ) continue;

+		/* remapped to invalid token? */

+		if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )

+		{

+			fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i);

+			continue;

+		}

+		if ( TokenString(i) != NULL ) {

+           te=(TermEntry *) hash_get(Tname,TokenString(i));                     /* MR11 */

+            if (te == NULL || te->akaString == NULL) {                          /* MR11 */

+  	   	      fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));

+            } else {

+			  hasAkaName[i] = '1';											    /* MR23 */

+  	   	      fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, te->akaString);   /* MR11 */

+            }

+        }

+		else

+		{

+			/* look in all lexclasses for the reg expr */

+			for (j=0; j<NumLexClasses; j++)

+			{

+				lexmode(j);

+				if ( ExprString(i) != NULL )

+				{

+					fprintf(Parser_c, ",\n\t/* %02d */\t", i);

+					dumpExpr(Parser_c, ExprString(i));

+					break;

+				}

+			}

+			if ( j>=NumLexClasses )

+			{

+				if ( UserDefdTokens )

+				{

+					fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i);

+				}

+				else

+					fatal_internal(eMsgd("No label or expr for token %d",i));

+			}

+		}

+	}

+	fprintf(Parser_c, "\n};\n");

+

+	/* Build constructors */

+	fprintf(Parser_c, "\n%s::", CurrentClassName);

+	fprintf(Parser_c,	"%s(ANTLRTokenBuffer *input) : %s(input,%d,%d,%d,%d)\n",

+						CurrentClassName,

+						(BaseClassName == NULL ? "ANTLRParser" : BaseClassName),

+						OutputLL_k,

+						FoundGuessBlk,

+						DemandLookahead,

+						NumWords(TokenNum-1)*sizeof(unsigned));

+	fprintf(Parser_c, "{\n");

+	fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n");

+    if (TraceGen) {

+      fprintf(Parser_c, "\ttraceOptionValueDefault=1;\t\t// MR10 turn trace ON\n");

+    } else {

+      fprintf(Parser_c, "\ttraceOptionValueDefault=0;\t\t// MR10 turn trace OFF\n");

+    };

+	fprintf(Parser_c, "}\n\n");

+	free ( (void *) hasAkaName);

+}

+

+void

+#ifdef __USE_PROTOS

+GenParser_h_Hdr(void)

+#else

+GenParser_h_Hdr()

+#endif

+{

+	int i;

+

+	fprintf(Parser_h, "/*\n");

+	fprintf(Parser_h, " * %s: P a r s e r  H e a d e r \n", CurrentClassName);

+	fprintf(Parser_h, " *\n");

+	fprintf(Parser_h, " * Generated from:");

+	for (i=0; i<NumFiles; i++) fprintf(Parser_h, " %s", FileStr[i]);

+	fprintf(Parser_h, "\n");

+	fprintf(Parser_h, " *\n");

+	fprintf(Parser_h, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");

+	fprintf(Parser_h, " * Parr Research Corporation\n");

+	fprintf(Parser_h, " * with Purdue University Electrical Engineering\n");

+	fprintf(Parser_h, " * with AHPCRC, University of Minnesota\n");

+	fprintf(Parser_h, " * ANTLR Version %s\n", Version);

+	fprintf(Parser_h, " */\n\n");

+

+  if ( FirstAction != NULL ) dumpAction( FirstAction, Parser_h, 0, -1, 0, 1);         /* MR11 MR15b */

+

+	fprintf(Parser_h, "#ifndef %s_h\n", CurrentClassName);

+	fprintf(Parser_h, "#define %s_h\n\n", CurrentClassName);

+

+    fprintf(Parser_h, "#ifndef ANTLR_VERSION\n");

+    fprintf(Parser_h, "#define ANTLR_VERSION %s\n",VersionDef);

+    fprintf(Parser_h, "#endif\n\n");

+

+	if ( GenAST ) fprintf(Parser_h, "class ASTBase;\n");

+    if (TraceGen) {

+      fprintf(Parser_h,"#ifndef zzTRACE_RULES\n");  /* MR20 */

+      fprintf(Parser_h,"#define zzTRACE_RULES\n");  /* MR20 */

+      fprintf(Parser_h,"#endif\n");                 /* MR22 */

+    };

+	fprintf(Parser_h, "#include \"%s\"\n\n", APARSER_H);

+

+	if ( HdrAction != NULL ) dumpAction( HdrAction, Parser_h, 0, -1, 0, 1);

+	

+/* MR10 */    if (ClassDeclStuff == NULL) {

+/* MR10 */  	fprintf(Parser_h, "class %s : public ANTLRParser {\n", CurrentClassName);

+/* MR10 */    } else {

+/* MR10 */      fprintf(Parser_h, "class %s %s {\n",CurrentClassName,ClassDeclStuff);

+/* MR10 */    };

+

+	fprintf(Parser_h, "public:\n");					          /* MR1 */

+	fprintf(Parser_h, "\tstatic  const ANTLRChar *tokenName(int tk);\n");/* MR1 */

+    fprintf(Parser_h, "\tenum { SET_SIZE = %i };\n",TokenNum-1);         /* MR21 */

+	fprintf(Parser_h, "protected:\n");

+	fprintf(Parser_h, "\tstatic const ANTLRChar *_token_tbl[];\n");     /* MR20 */

+	fprintf(Parser_h, "private:\n");

+}

+

+/* Currently, this is only used in !GenCC mode */

+void

+#ifdef __USE_PROTOS

+GenErrHdr( void )

+#else

+GenErrHdr( )

+#endif

+{

+	int i, j;

+    TermEntry   *te;

+

+	fprintf(ErrFile, "/*\n");

+	fprintf(ErrFile, " * A n t l r  S e t s / E r r o r  F i l e  H e a d e r\n");

+	fprintf(ErrFile, " *\n");

+	fprintf(ErrFile, " * Generated from:");

+	for (i=0; i<NumFiles; i++) fprintf(ErrFile, " %s", FileStr[i]);

+	fprintf(ErrFile, "\n");

+	fprintf(ErrFile, " *\n");

+	fprintf(ErrFile, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");

+	fprintf(ErrFile, " * Parr Research Corporation\n");

+	fprintf(ErrFile, " * with Purdue University Electrical Engineering\n");

+	fprintf(ErrFile, " * With AHPCRC, University of Minnesota\n");

+	fprintf(ErrFile, " * ANTLR Version %s\n", Version);

+	fprintf(ErrFile, " */\n\n");

+

+  if ( FirstAction != NULL ) dumpAction( FirstAction, ErrFile, 0, -1, 0, 1);         /* MR11 MR15b */

+	

+  fprintf(ErrFile, "#define ANTLR_VERSION	%s\n", VersionDef);

+

+  fprintf(ErrFile, "#include \"pcctscfg.h\"\n");

+	fprintf(ErrFile, "#include \"pccts_stdio.h\"\n");

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+		fprintf(ErrFile, "#define %s %s\n", DefaultParserName, ParserName);

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+		fprintf(ErrFile, "#include \"%s\"\n", RemapFileName);

+	if ( HdrAction != NULL ) dumpAction( HdrAction, ErrFile, 0, -1, 0, 1 );

+	if ( FoundGuessBlk )

+	{

+		fprintf(ErrFile, "#define ZZCAN_GUESS\n");

+		fprintf(ErrFile, "#include \"pccts_setjmp.h\"\n");

+	}

+    if (TraceGen) {

+      fprintf(ErrFile,"#ifndef zzTRACE_RULES\n");  /* MR20 */

+      fprintf(ErrFile,"#define zzTRACE_RULES\n");  /* MR20 */

+      fprintf(ErrFile,"#endif\n");                 /* MR22 */

+    };

+

+	if ( OutputLL_k > 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k);

+#ifdef DUM

+	if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));

+#endif

+	fprintf(ErrFile, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));

+	if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n");

+	fprintf(ErrFile, "#include \"antlr.h\"\n");

+	if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n");

+			

+    if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile);

+	/* still need this one as it has the func prototypes */

+	fprintf(ErrFile, "#include \"%s\"\n", DefFileName);

+	fprintf(ErrFile, "#include \"dlgdef.h\"\n");

+	fprintf(ErrFile, "#include \"err.h\"\n\n");

+

+	/* Dump a zztokens for each automaton */

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+	{

+		fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1);

+	}

+	else

+	{

+		fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1);

+	}

+	fprintf(ErrFile, "\t/* 00 */\t\"Invalid\"");

+	for (i=1; i<TokenNum-1; i++)

+	{

+		DAWDLE;

+		if ( i == EpToken ) continue;

+		/* remapped to invalid token? */

+		if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )

+		{

+			fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i);

+			continue;

+		}

+		if ( TokenString(i) != NULL ) {

+            te=(TermEntry *) hash_get(Tname,TokenString(i));                     /* MR11 */

+            if (te == NULL || te->akaString == NULL) {                          /* MR11 */

+  			  fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));

+            } else {

+  			  fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, te->akaString);    /* MR11 */

+            }

+        }

+		else

+		{

+			/* look in all lexclasses for the reg expr */

+			for (j=0; j<NumLexClasses; j++)

+			{

+				lexmode(j);

+				if ( ExprString(i) != NULL )

+				{

+					fprintf(ErrFile, ",\n\t/* %02d */\t", i);

+					dumpExpr(ErrFile, ExprString(i));

+					break;

+				}

+			}

+			if ( j>=NumLexClasses )

+			{

+				if ( UserDefdTokens )

+				{

+					fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i);

+				}

+				else

+					fatal_internal(eMsgd("No label or expr for token %d",i));

+			}

+		}

+	}

+	fprintf(ErrFile, "\n};\n");

+}

+

+void

+#ifdef __USE_PROTOS

+dumpExpr( FILE *f, char *e )

+#else

+dumpExpr( f, e )

+FILE *f;

+char *e;

+#endif

+{

+	while ( *e!='\0' )

+	{

+		if ( *e=='\\' && *(e+1)=='\\' )

+			{putc('\\', f); putc('\\', f); e+=2;}

+		else if ( *e=='\\' && *(e+1)=='"' )

+			{putc('\\', f); putc('"', f); e+=2;}

+		else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;}

+		else {putc(*e, f); e++;}

+	}

+}

+

+int

+#ifdef __USE_PROTOS

+isTermEntryTokClass(TermEntry *te)

+#else

+isTermEntryTokClass(te)

+TermEntry *te;

+#endif

+{

+	ListNode *t;

+	TCnode *p;

+	TermEntry *q;

+	char *tokstr;

+

+	if (tclasses == NULL) return 0;

+

+	for (t = tclasses->next; t!=NULL; t=t->next)

+	{

+		p = (TCnode *) t->elem;

+		tokstr = TokenString(p->tok);

+		lexmode(p->lexclass);	/* switch to lexclass where tokclass is defined */

+        q = (TermEntry *) hash_get(Tname, tokstr);

+		if (q == te) return 1;

+	}

+	return 0;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/build.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/build.c
new file mode 100644
index 0000000..4eb3b02
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/build.c
@@ -0,0 +1,813 @@
+/*

+ * build.c -- functions associated with building syntax diagrams.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <ctype.h>

+#include "pcctscfg.h"

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+

+#define SetBlk(g, t, approx, first_set_symbol) {         		        \

+			((Junction *)g.left)->jtype = t;					        \

+			((Junction *)g.left)->approx = approx;				        \

+			((Junction *)g.left)->pFirstSetSymbol = first_set_symbol;   \

+			((Junction *)g.left)->end = (Junction *) g.right;	        \

+			((Junction *)g.right)->jtype = EndBlk;}

+

+/* Add the parameter string 'parm' to the parms field of a block-type junction

+ * g.left points to the sentinel node on a block.  i.e. g.left->p1 points to

+ * the actual junction with its jtype == some block-type.

+ */

+void

+#ifdef __USE_PROTOS

+addParm( Node *p, char *parm )

+#else

+addParm( p, parm )

+Node *p;

+char *parm;

+#endif

+{

+	char *q = (char *) malloc( strlen(parm) + 1 );

+	require(p!=NULL, "addParm: NULL object\n");

+	require(q!=NULL, "addParm: unable to alloc parameter\n");

+

+	strcpy(q, parm);

+	if ( p->ntype == nRuleRef )

+	{

+		((RuleRefNode *)p)->parms = q;

+	}

+	else if ( p->ntype == nJunction )

+	{

+		((Junction *)p)->parm = q;	/* only one parameter allowed on subrules */

+	}

+	else fatal_internal("addParm: invalid node for adding parm");

+}

+

+/*

+ * Build an action node for the syntax diagram

+ *

+ * buildAction(ACTION) ::= --o-->ACTION-->o--

+ *

+ * Where o is a junction node.

+ */

+Graph

+#ifdef __USE_PROTOS

+buildAction( char *action, int file, int line, int is_predicate )

+#else

+buildAction( action, file, line, is_predicate )

+char *action;

+int file;

+int line;

+int is_predicate;

+#endif

+{

+	Junction *j1, *j2;

+	Graph g;

+	ActionNode *a;

+	require(action!=NULL, "buildAction: invalid action");

+	

+	j1 = newJunction();

+	j2 = newJunction();

+	a = newActionNode();

+	a->action = (char *) malloc( strlen(action)+1 );

+	require(a->action!=NULL, "buildAction: cannot alloc space for action\n");

+	strcpy(a->action, action);

+	j1->p1 = (Node *) a;

+	a->next = (Node *) j2;

+	a->is_predicate = is_predicate;

+

+    if (is_predicate) {

+        PredEntry   *predEntry;

+        char        *t;

+        char        *key;

+        char        *u;

+        int         inverted=0;

+

+        t=key=(char *)calloc(1,strlen(a->action)+1);

+

+        for (u=a->action; *u != '\0' ; u++) {

+          if (*u != ' ') {

+            if (t==key && *u=='!') {

+              inverted=!inverted;

+            } else {

+              *t++=*u;

+            };

+          };

+        };

+

+        *t='\0';

+

+

+        predEntry=(PredEntry *)hash_get(Pname,key);

+        a->predEntry=predEntry;

+        if (predEntry != NULL) a->inverted=inverted;

+    } else {

+/* MR12c */      char  *strStart=a->action;

+/* MR12c */      char  *strEnd;

+/* MR12c */      strEnd=strStart+strlen(strStart)-1;

+/* MR12c */      for ( ; strEnd >= strStart &&  isspace(*strEnd); strEnd--) *strEnd=0;

+/* MR12c */      while (*strStart != '\0' && isspace(*strStart)) strStart++;

+/* MR12c */      if (ci_strequ(strStart,"nohoist")) {

+/* MR12c */        a->noHoist=1;

+/* MR12c */      }

+	}

+

+	g.left = (Node *) j1; g.right = (Node *) j2;

+	a->file = file;

+	a->line = line;

+	a->rname = CurRule;     /* MR10 */

+	return g;

+}

+

+/*

+ * Build a token node for the syntax diagram

+ *

+ * buildToken(TOKEN) ::= --o-->TOKEN-->o--

+ *

+ * Where o is a junction node.

+ */

+Graph

+#ifdef __USE_PROTOS

+buildToken( char *text )

+#else

+buildToken( text )

+char *text;

+#endif

+{

+	Junction *j1, *j2;

+	Graph g;

+	TokNode *t;

+	require(text!=NULL, "buildToken: invalid token name");

+	

+	j1 = newJunction();

+	j2 = newJunction();

+	t = newTokNode();

+	t->altstart = CurAltStart;

+	if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}

+	else {t->label=TRUE; t->token = addTname( text );}

+	j1->p1 = (Node *) t;

+	t->next = (Node *) j2;

+	g.left = (Node *) j1; g.right = (Node *) j2;

+	return g;

+}

+

+/*

+ * Build a wild-card node for the syntax diagram

+ *

+ * buildToken(TOKEN) ::= --o-->'.'-->o--

+ *

+ * Where o is a junction node.

+ */

+Graph

+#ifdef __USE_PROTOS

+buildWildCard( char *text )

+#else

+buildWildCard( text )

+char *text;

+#endif

+{

+	Junction *j1, *j2;

+	Graph g;

+	TokNode *t;

+	TCnode *w;

+	TermEntry *p;

+	require(text!=NULL, "buildWildCard: invalid token name");

+	

+	j1 = newJunction();

+	j2 = newJunction();

+	t = newTokNode();

+

+	/* If the ref a wild card, make a token class for it */

+	if ( Tnum(WildCardString) == 0 )

+	{

+		w = newTCnode;

+	  	w->tok = addTname( WildCardString );

+		set_orel(w->tok, &imag_tokens);

+		set_orel(w->tok, &tokclasses);

+		WildCardToken = w->tok;

+		require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,

+				"hash table mechanism is broken");

+		p->classname = 1;	/* entry is class name, not token */

+		p->tclass = w;		/* save ptr to this tclass def */

+		list_add(&tclasses, (char *)w);

+	}

+	else {

+		p=(TermEntry *)hash_get(Tname, WildCardString);

+		require( p!= NULL, "hash table mechanism is broken");

+		w = p->tclass;

+	}

+

+	t->token = w->tok;

+	t->wild_card = 1;

+	t->tclass = w;

+

+	t->altstart = CurAltStart;

+	j1->p1 = (Node *) t;

+	t->next = (Node *) j2;

+	g.left = (Node *) j1; g.right = (Node *) j2;

+	return g;

+}

+

+void

+#ifdef __USE_PROTOS

+setUpperRange(TokNode *t, char *text)

+#else

+setUpperRange(t, text)

+TokNode *t;

+char *text;

+#endif

+{

+	require(t!=NULL, "setUpperRange: NULL token node");

+	require(text!=NULL, "setUpperRange: NULL token string");

+

+	if ( *text == '"' ) {t->upper_range = addTexpr( text );}

+	else {t->upper_range = addTname( text );}

+}

+

+/*

+ * Build a rule reference node of the syntax diagram

+ *

+ * buildRuleRef(RULE) ::= --o-->RULE-->o--

+ *

+ * Where o is a junction node.

+ *

+ * If rule 'text' has been defined already, don't alloc new space to store string.

+ * Set r->text to point to old copy in string table.

+ */

+Graph

+#ifdef __USE_PROTOS

+buildRuleRef( char *text )

+#else

+buildRuleRef( text )

+char *text;

+#endif

+{

+	Junction *j1, *j2;

+	Graph g;

+	RuleRefNode *r;

+	RuleEntry *p;

+	require(text!=NULL, "buildRuleRef: invalid rule name");

+	

+	j1 = newJunction();

+	j2 = newJunction();

+	r = newRNode();

+	r->altstart = CurAltStart;

+	r->assign = NULL;

+	if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;

+	else r->text = mystrdup( text );

+	j1->p1  = (Node *) r;

+	r->next = (Node *) j2;

+	g.left = (Node *) j1; g.right = (Node *) j2;

+	return g;

+}

+

+/*

+ * Or two subgraphs into one graph via:

+ *

+ * Or(G1, G2) ::= --o-G1-o--

+ *                  |    ^

+ *					v    |

+ *                  o-G2-o

+ *

+ * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.

+ * If, however, the G1 altnum is 0, make it 1 and then

+ * make G2 altnum = G1 altnum + 1.

+ */

+Graph

+#ifdef __USE_PROTOS

+Or( Graph g1, Graph g2 )

+#else

+Or( g1, g2 )

+Graph g1;

+Graph g2;

+#endif

+{

+	Graph g;

+	require(g1.left != NULL, "Or: invalid graph");

+	require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");

+

+	((Junction *)g1.left)->p2 = g2.left;

+	((Junction *)g2.right)->p1 = g1.right;

+	/* set altnums */

+	if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;

+	((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;

+	g.left = g2.left;

+	g.right = g1.right;

+	return g;

+}

+

+/*

+ * Catenate two subgraphs

+ *

+ * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--

+ * Cat(NULL,G2)::= --o-G2-o--

+ * Cat(G1,NULL)::= --o-G1-o--

+ */

+Graph

+#ifdef __USE_PROTOS

+Cat( Graph g1, Graph g2 )

+#else

+Cat( g1, g2 )

+Graph g1;

+Graph g2;

+#endif

+{

+	Graph g;

+	

+	if ( g1.left == NULL && g1.right == NULL ) return g2;

+	if ( g2.left == NULL && g2.right == NULL ) return g1;

+	((Junction *)g1.right)->p1 = g2.left;

+	g.left = g1.left;

+	g.right = g2.right;

+	return g;

+}

+

+/*

+ * Make a subgraph an optional block

+ *

+ * makeOpt(G) ::= --o-->o-G-o-->o--

+ *                      | 	    ^

+ *						v  	    |

+ *					    o-------o

+ *

+ * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.

+ *

+ * The node on the far right is added so that every block owns its own

+ * EndBlk node.

+ */

+Graph

+#ifdef __USE_PROTOS

+makeOpt( Graph g1, int approx, char * pFirstSetSymbol )

+#else

+makeOpt( g1, approx, pFirstSetSymbol )

+Graph g1;

+int approx;

+char * pFirstSetSymbol;

+#endif

+{

+	Junction *j1,*j2,*p;

+	Graph g;

+	require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");

+

+	j1 = newJunction();

+	j2 = newJunction();

+	((Junction *)g1.right)->p1 = (Node *) j2;	/* add node to G at end */

+

+    /*  MR21

+     *

+     *  There is code in genBlk which recognizes the node created

+     *  by emptyAlt() as a special case and bypasses it.  We don't

+     *  want this to happen for the optBlk.

+     */

+

+	g = emptyAlt3(); /* MR21 */

+	if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;

+	((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;

+	for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)

+		{;}										/* find last alt */

+	p->p2 = g.left;								/* add optional alternative */

+	((Junction *)g.right)->p1 = (Node *)j2;		/* opt alt points to EndBlk */

+	g1.right = (Node *)j2;

+	SetBlk(g1, aOptBlk, approx, pFirstSetSymbol);

+	j1->p1 = g1.left;							/* add generic node in front */

+	g.left = (Node *) j1;

+	g.right = g1.right;

+	return g;

+}

+

+/*

+ * Make a graph into subblock

+ *

+ * makeBlk(G) ::= --o-->o-G-o-->o--

+ *

+ * The node on the far right is added so that every block owns its own

+ * EndBlk node.

+ */

+Graph

+#ifdef __USE_PROTOS

+makeBlk( Graph g1, int approx, char * pFirstSetSymbol )

+#else

+makeBlk( g1, approx, pFirstSetSymbol )

+Graph g1;

+int approx;

+char * pFirstSetSymbol;

+#endif

+{

+	Junction *j,*j2;

+	Graph g;

+	require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");

+

+	j = newJunction();

+	j2 = newJunction();

+	((Junction *)g1.right)->p1 = (Node *) j2;	/* add node to G at end */

+	g1.right = (Node *)j2;

+	SetBlk(g1, aSubBlk, approx, pFirstSetSymbol);

+	j->p1 = g1.left;							/* add node in front */

+	g.left = (Node *) j;

+	g.right = g1.right;

+

+	return g;

+}

+

+/*

+ * Make a subgraph into a loop (closure) block -- (...)*

+ *

+ * makeLoop(G) ::=       |---|

+ *					     v   |

+ *			   --o-->o-->o-G-o-->o--

+ *                   |           ^

+ *                   v           |

+ *					 o-----------o

+ *

+ * After making loop, always place generic node out front.  It becomes

+ * the start of enclosing block.  The aLoopBlk is the target of the loop.

+ *

+ * Loop blks have TWO EndBlk nodes--the far right and the node that loops back

+ * to the aLoopBlk node.  Node with which we can branch past loop == aLoopBegin and

+ * one which is loop target == aLoopBlk.

+ * The branch-past (initial) aLoopBegin node has end

+ * pointing to the last EndBlk node.  The loop-target node has end==NULL.

+ *

+ * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.

+ */

+Graph

+#ifdef __USE_PROTOS

+makeLoop( Graph g1, int approx, char * pFirstSetSymbol )

+#else

+makeLoop( g1, approx, pFirstSetSymbol)

+Graph g1;

+int approx;

+char * pFirstSetSymbol;

+#endif

+{

+	Junction *back, *front, *begin;

+	Graph g;

+	require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");

+

+	back = newJunction();

+	front = newJunction();

+	begin = newJunction();

+	g = emptyAlt3();

+	((Junction *)g1.right)->p2 = g1.left;		/* add loop branch to G */

+	((Junction *)g1.right)->p1 = (Node *) back;	/* add node to G at end */

+	((Junction *)g1.right)->jtype = EndBlk;		/* mark 1st EndBlk node */

+	((Junction *)g1.left)->jtype = aLoopBlk;	/* mark 2nd aLoopBlk node */

+	((Junction *)g1.left)->end = (Junction *) g1.right;

+	((Junction *)g1.left)->lock = makelocks();

+	((Junction *)g1.left)->pred_lock = makelocks();

+	g1.right = (Node *) back;

+	begin->p1 = (Node *) g1.left;

+	g1.left = (Node *) begin;

+	begin->p2 = (Node *) g.left;				/* make bypass arc */

+	((Junction *)g.right)->p1 = (Node *) back;

+	SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol);

+	front->p1 = g1.left;						/* add node to front */

+	g1.left = (Node *) front;

+

+	return g1;

+}

+

+/*

+ * Make a subgraph into a plus block -- (...)+ -- 1 or more times

+ *

+ * makePlus(G) ::=	 |---|

+ *					 v   |

+ *			   --o-->o-G-o-->o--

+ *

+ * After making loop, always place generic node out front.  It becomes

+ * the start of enclosing block.  The aPlusBlk is the target of the loop.

+ *

+ * Plus blks have TWO EndBlk nodes--the far right and the node that loops back

+ * to the aPlusBlk node.

+ *

+ * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.

+ */

+Graph

+#ifdef __USE_PROTOS

+makePlus( Graph g1, int approx, char * pFirstSetSymbol)

+#else

+makePlus( g1, approx, pFirstSetSymbol)

+Graph g1;

+int approx;

+char * pFirstSetSymbol;

+#endif

+{

+	int has_empty_alt_already = 0;

+	Graph g;

+	Junction *j2, *j3, *first_alt;

+	Junction *last_alt=NULL, *p;

+	require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");

+

+	first_alt = (Junction *)g1.left;

+	j2 = newJunction();

+	j3 = newJunction();

+	if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;

+	((Junction *)g1.right)->p2 = g1.left;		/* add loop branch to G */

+	((Junction *)g1.right)->p1 = (Node *) j2;	/* add node to G at end */

+	((Junction *)g1.right)->jtype = EndBlk;		/* mark 1st EndBlk node */

+	g1.right = (Node *) j2;

+	SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol);

+	((Junction *)g1.left)->lock = makelocks();

+	((Junction *)g1.left)->pred_lock = makelocks();

+	j3->p1 = g1.left;							/* add node to front */

+	g1.left = (Node *) j3;

+

+	/* add an optional branch which is the "exit" branch of loop */

+	/* FIRST, check to ensure that there does not already exist

+	 * an optional path.

+	 */

+	/* find last alt */

+	for(p=first_alt; p!=NULL; p=(Junction *)p->p2)

+	{

+		if ( p->p1->ntype == nJunction &&

+			 p->p1!=NULL &&

+			 ((Junction *)p->p1)->jtype==Generic &&

+			 ((Junction *)p->p1)->p1!=NULL &&

+			 ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )

+		{

+			has_empty_alt_already = 1;

+		}

+		last_alt = p;

+	}

+	if ( !has_empty_alt_already )

+	{

+		require(last_alt!=NULL, "last_alt==NULL; bad (..)+");

+		g = emptyAlt();

+		last_alt->p2 = g.left;

+		((Junction *)g.right)->p1 = (Node *) j2;

+

+		/* make sure lookahead computation ignores this alt for

+		* FIRST("(..)+"); but it's still used for computing the FIRST

+		* of each alternative.

+		*/

+		((Junction *)g.left)->ignore = 1;

+	}

+

+	return g1;

+}

+

+/*

+ * Return an optional path:  --o-->o--

+ */

+

+Graph

+#ifdef __USE_PROTOS

+emptyAlt( void )

+#else

+emptyAlt( )

+#endif

+{

+	Junction *j1, *j2;

+	Graph g;

+

+	j1 = newJunction();

+	j2 = newJunction();

+	j1->p1 = (Node *) j2;

+	g.left = (Node *) j1;

+	g.right = (Node *) j2;

+	

+	return g;

+}

+

+/*  MR21

+ *

+ *  There is code in genBlk which recognizes the node created

+ *  by emptyAlt() as a special case and bypasses it.  We don't

+ *  want this to happen for the optBlk.

+ */

+

+Graph

+#ifdef __USE_PROTOS

+emptyAlt3( void )

+#else

+emptyAlt3( )

+#endif

+{

+	Junction *j1, *j2, *j3;

+	Graph g;

+

+	j1 = newJunction();

+	j2 = newJunction();

+    j3 = newJunction();

+	j1->p1 = (Node *) j2;

+	j2->p1 = (Node *) j3;

+	g.left = (Node *) j1;

+	g.right = (Node *) j3;

+	

+	return g;

+}

+

+/* N o d e  A l l o c a t i o n */

+

+TokNode *

+#ifdef __USE_PROTOS

+newTokNode( void )

+#else

+newTokNode( )

+#endif

+{

+	static TokNode *FreeList = NULL;

+	TokNode *p, *newblk;

+

+	if ( FreeList == NULL )

+	{

+		newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));

+		if ( newblk == NULL )

+			fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));

+		for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)

+		{

+			p->next = (Node *)FreeList;	/* add all new token nodes to FreeList */

+			FreeList = p;

+		}

+	}

+	p = FreeList;

+	FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */

+	p->next = NULL;						/* NULL the ptr we used */

+    memset( (char *) p, 0, sizeof(TokNode));        /* MR10 */

+	p->ntype = nToken;

+	p->rname = CurRule;

+	p->file = CurFile;

+	p->line = zzline;

+	p->altstart = NULL;

+

+	return p;

+}

+

+RuleRefNode *

+#ifdef __USE_PROTOS

+newRNode( void )

+#else

+newRNode( )

+#endif

+{

+	static RuleRefNode *FreeList = NULL;

+	RuleRefNode *p, *newblk;

+

+	if ( FreeList == NULL )

+	{

+		newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));

+		if ( newblk == NULL )

+			fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));

+		for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)

+		{

+			p->next = (Node *)FreeList;	/* add all new rref nodes to FreeList */

+			FreeList = p;

+		}

+	}

+	p = FreeList;

+	FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */

+	p->next = NULL;						/* NULL the ptr we used */

+    memset( (char *) p, 0, sizeof(RuleRefNode));        /* MR10 */

+	p->ntype = nRuleRef;

+	p->rname = CurRule;

+	p->file = CurFile;

+	p->line = zzline;

+	p->astnode = ASTinclude;

+	p->altstart = NULL;

+	

+	return p;

+}

+

+static int junctionSeqNumber=0;         /* MR10 */

+

+Junction *

+#ifdef __USE_PROTOS

+newJunction( void )

+#else

+newJunction( )

+#endif

+{

+	static Junction *FreeList = NULL;

+	Junction *p, *newblk;

+

+	if ( FreeList == NULL )

+	{

+		newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));

+		if ( newblk == NULL )

+			fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));

+		for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)

+		{

+			p->p1 = (Node *)FreeList;	/* add all new Junction nodes to FreeList */

+			FreeList = p;

+		}

+	}

+	p = FreeList;

+	FreeList = (Junction *)FreeList->p1;/* remove a Junction node */

+	p->p1 = NULL;						/* NULL the ptr we used */

+    memset( (char *) p, 0, sizeof(Junction));       /* MR10 */

+	p->ntype = nJunction;

+	p->visited = 0;

+	p->jtype = Generic;

+	p->rname = CurRule;

+	p->file = CurFile;

+	p->line = zzline;

+	p->exception_label = NULL;

+	p->fset = (set *) calloc(CLL_k+1, sizeof(set));

+	require(p->fset!=NULL, "cannot allocate fset in newJunction");

+    p->seq=++junctionSeqNumber;     /* MR10 */

+

+	return p;

+}

+

+ActionNode *

+#ifdef __USE_PROTOS

+newActionNode( void )

+#else

+newActionNode( )

+#endif

+{

+	static ActionNode *FreeList = NULL;

+	ActionNode *p, *newblk;

+

+	if ( FreeList == NULL )

+	{

+		newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));

+		if ( newblk == NULL )

+			fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));

+		for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)

+		{

+			p->next = (Node *)FreeList;	/* add all new Action nodes to FreeList */

+			FreeList = p;

+		}

+	}

+	p = FreeList;

+	FreeList = (ActionNode *)FreeList->next;/* remove an Action node */

+    memset( (char *) p, 0, sizeof(ActionNode));     /* MR10 */

+	p->ntype = nAction;

+	p->next = NULL;						/* NULL the ptr we used */

+	p->done = 0;

+	p->pred_fail = NULL;

+	p->guardpred = NULL;

+    p->ampersandPred = NULL;

+	return p;

+}

+

+/*

+ * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.

+ * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.

+ * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.

+ *

+ * if ( lock[k]==TRUE ) then we have been here before looking for k tokens

+ * of lookahead.

+ */

+char *

+#ifdef __USE_PROTOS

+makelocks( void )

+#else

+makelocks( )

+#endif

+{

+	char *p = (char *) calloc(CLL_k+1, sizeof(char));

+	require(p!=NULL, "cannot allocate lock array");

+	

+	return p;

+}

+

+#if 0

+** #ifdef __USE_PROTOS

+** void my_memset(char *p,char value,int count)

+** #else

+** void my_memset(p,value,count)

+**   char      *p;

+**   char      value;

+**   int       count;

+** #endif

+** {

+**    int      i;

+**

+**    for (i=0; i<count; i++) {

+**     p[i]=value;

+**   };

+** }

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/build.xml b/edk2/Tools/Source/TianoTools/Pccts/antlr/build.xml
new file mode 100644
index 0000000..6f30ecb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/build.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK antlr Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="antlr"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+		<condition property="CheckDepends">

+		  <uptodate targetfile="${WORKSPACE}/Tools/bin/antlr.exe">

+			  <srcfiles dir="." includes="*.c *.h *.g"/>

+			</uptodate>

+		</condition>

+		<if>

+		  <equals arg1="${CheckDepends}" arg2="true"/>

+			<then>

+				<echo message="Executable, antlr.exe, is up to date."/>

+			</then>

+		</if>

+  </target>

+

+  <target name="GenTool" depends="init" unless="CheckDepends">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="nmake" failonerror="TRUE">

+	    	  <arg line="-f AntlrMS.mak"/>

+    		</exec>

+		  </then>

+		<elseif>

+      <equals arg1="${ToolChain}" arg2="gcc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="make" failonerror="TRUE">

+	    	  <arg line="-f makefile"/>

+    		</exec>

+		  </then>

+		</elseif>

+		</if>

+	</target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="nmake" failonerror="TRUE">

+	    	  <arg line="-f AntlrMS.mak clean"/>

+    		</exec>

+		  </then>

+		<elseif>

+      <equals arg1="${ToolChain}" arg2="gcc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="make" failonerror="TRUE">

+	    	  <arg line="-f makefile clean"/>

+    		</exec>

+		  </then>

+		</elseif>

+		</if>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="nmake" failonerror="FALSE">

+	    	  <arg line="-f AntlrMS.mak clean"/>

+    		</exec>

+		  </then>

+		<elseif>

+      <equals arg1="${ToolChain}" arg2="gcc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="make" failonerror="FALSE">

+	    	  <arg line="-f makefile clean"/>

+    		</exec>

+		  </then>

+		</elseif>

+		</if>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/dumpcycles.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/dumpcycles.c
new file mode 100644
index 0000000..8156159
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/dumpcycles.c
@@ -0,0 +1,67 @@
+#include <stdio.h>

+#include <ctype.h>

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+

+void 

+#ifdef __USE_PROTOS

+dumpcycles(void)

+#else

+dumpcycles()

+#endif

+{

+  Cycle         *c;

+  CacheEntry    *f;

+  ListNode      *p;

+  int           i=0;

+  int           k;

+  int           degree;

+

+  for (k=1; k <= CLL_k; k++) {

+    if (Cycles[k] == NULL) continue;

+

+    for (p = Cycles[k]->next; p!=NULL; p=p->next) {

+  	  c = (Cycle *) p->elem;

+      degree=set_deg(c->cyclicDep);

+	  fprintf(stderr,"Cycle %d: (degree %d) %s -->\n", i++, degree, RulePtr[c->croot]->rname);

+      fprintf(stderr,"    *self*\n");

+      MR_dumpRuleSet(c->cyclicDep);

+      fprintf(stderr,"\n");

+	  f = (CacheEntry *)

+			hash_get(Fcache,Fkey(RulePtr[c->croot]->rname,'o',k));

+      if (f == NULL) {

+        fprintf(stderr,"    *** FOLLOW(%s) must be in cache but isn't ***\n",

+                                         RulePtr[c->croot]->rname);

+      };

+    };

+  };

+}

+

+void 

+#ifdef __USE_PROTOS

+dumpfostack(int k) 

+#else

+dumpfostack(k) 

+int k;

+#endif

+{

+  int   i=0;

+  int   *pi;

+

+  fprintf(stderr,"\n");

+  if (FoStack[k] == NULL) {

+    fprintf(stderr,"FoStack[%d] is null\n",k);

+  };

+  if (FoTOS[k] == NULL) {

+    fprintf(stderr,"FoTOS[%d] is null\n",k);

+  }

+  if (FoTOS[k] != NULL && FoStack[k] != NULL) {

+    for (pi=FoStack[k]; pi <= FoTOS[k]; pi++) {

+      i++;

+      fprintf(stderr,"#%d  rule %d  %s\n",i,*pi,RulePtr[*pi]->rname);

+    }

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/dumpnode.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/dumpnode.c
new file mode 100644
index 0000000..2a34c6f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/dumpnode.c
@@ -0,0 +1,423 @@
+#include <stdio.h>

+#include <ctype.h>

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+

+#ifdef __USE_PROTOS

+void dumpset1(set s)

+#else

+void dumpset1(s)

+  set   s;

+#endif

+{

+  if (set_nil(s)) {

+    fprintf(stderr,"{}");

+  } else {

+    s_fprT(stderr,s);

+  };

+}

+

+#ifdef __USE_PROTOS

+void dumpset(set s)

+#else

+void dumpset(s)

+  set   s;

+#endif

+{

+  dumpset1(s);

+  fprintf(stderr,"\n");

+}

+

+#ifdef __USE_PROTOS

+int isEndRule(Node * p)

+#else

+int isEndRule(p)

+  Node *    p;

+#endif

+{

+  int       result=0;

+  if ( p->ntype == nJunction &&

+       ( (Junction *) p)->jtype == EndRule) {

+    result=1;

+  };

+  return result;

+}

+

+#ifdef __USE_PROTOS

+void dumppred1(int depth,Predicate *p)

+#else

+void dumppred1(depth,p)

+  int           depth;

+  Predicate     *p;

+#endif

+{

+  int       i;

+  int       k;

+

+  for (i=0; i<depth ; i++) {

+    fprintf(stderr,"  ");

+  };

+  if (p->expr == PRED_AND_LIST ||

+      p->expr == PRED_OR_LIST) {

+    fprintf(stderr," %s", (p->expr == NULL ? "null expr" : p->expr));

+    if (p->inverted) fprintf(stderr," predicate inverted !");

+    if (p->redundant) {

+      fprintf(stderr," Redundant!");

+    };

+    if (p->isConst) fprintf(stderr," const %d !",p->constValue);

+    fprintf(stderr,"\n");

+  } else {

+    fprintf(stderr,"predicate k=%d",p->k);

+    k=set_int(p->completionSet);

+    if (k >= 0) {

+      fprintf(stderr," Incomplete Set=%d !",k);

+    };

+    k=set_int(p->completionTree);

+    if (k >= 0) {

+      fprintf(stderr," Incomplete Tree=%d !",k);

+    };

+    if (p->redundant) {

+      fprintf(stderr," Redundant!");

+    };

+    fprintf(stderr," \"%s\" (%x)", (p->expr == NULL ? "null expr" : p->expr) ,p);

+    if (p->source != NULL) {

+       fprintf(stderr,"line %d",p->source->line);

+    };

+    if (p->inverted) fprintf(stderr," predicate inverted !");

+    fprintf(stderr,"\n");

+    for (i=0; i<depth ; i++) {

+      fprintf(stderr,"  ");

+    };

+    fprintf(stderr,"scontext: ");

+    dumpset(p->scontext[1]);

+    for (i=0; i<depth ; i++) {

+      fprintf(stderr,"  ");

+    };

+    fprintf(stderr,"tcontext: ");

+    preorder(p->tcontext);

+    fprintf(stderr,"\n");

+  };

+  fprintf(stderr,"\n");

+  if (p->down != NULL) {

+    dumppred1(depth+1,p->down);

+  };

+  if (p->right != NULL) {

+    dumppred1(depth,p->right);

+  };

+}

+

+#ifdef __USE_PROTOS

+void dumppred(Predicate *p)

+#else

+void dumppred(p)

+  Predicate     *p;

+#endif

+{

+  fprintf(stderr,"---------------------------------\n");

+  dumppred1(0,p);

+  fprintf(stderr,"\n");

+}

+

+#ifdef __USE_PROTOS

+void dumppredtree(Predicate *p)

+#else

+void dumppredtree(p)

+  Predicate     *p;

+#endif

+{

+  fprintf(stderr,"predicate k=%d \"%s\" line %d\n",p->k,p->expr,p->source->line);

+  dumpset(p->scontext[1]);

+}

+

+#ifdef __USE_PROTOS

+void dumppredexpr(Predicate *p)

+#else

+void dumppredexpr(p)

+  Predicate     *p;

+#endif

+{

+  fprintf(stderr,"    pred expr \"%s\"\n",p->expr);

+}

+

+#ifdef __USE_PROTOS

+void dt(Tree *t)

+#else

+void dt(t)

+  Tree  *t;

+#endif

+{

+  MR_dumpTreeF(stderr,0,t,5);

+}

+

+#ifdef __USE_PROTOS

+void d(Node * p)

+#else

+void d(p)

+  Node *    p;

+#endif

+{

+

+  Junction      *j;

+  RuleRefNode   *r;

+  TokNode       *t;

+  ActionNode    *a;

+

+  if (p==NULL) {

+    fprintf(stderr,"dumpNode: Node is NULL");

+    return;

+  };

+

+  switch (p->ntype) {

+    case nJunction :

+      j = (Junction *) p;

+      fprintf(stderr, "Junction (#%d in rule %s line %d) ",j->seq,j->rname,j->line);

+      if (j->guess) fprintf(stderr,"guess block ");

+      switch (j->jtype ) {

+        case aSubBlk :

+          fprintf(stderr,"aSubBlk");

+          break;

+        case aOptBlk :

+          fprintf(stderr,"aOptBlk");

+          break;

+        case aLoopBegin :

+          fprintf(stderr,"aLoopBeginBlk");

+          break;

+        case aLoopBlk :

+          fprintf(stderr,"aLoopBlk");

+          break;

+        case aPlusBlk :

+          fprintf(stderr,"aPlusBlk");

+          break;

+        case EndBlk :

+          fprintf(stderr,"EndBlk");

+          break;

+        case RuleBlk :

+          fprintf(stderr,"RuleBlk");

+          break;

+        case Generic :

+          fprintf(stderr,"Generic");

+          break;

+        case EndRule :

+          fprintf(stderr,"EndRule");

+          break;

+      };

+      if (j->halt) fprintf(stderr,"  halt!");

+      if (j->p1) fprintf(stderr," p1 valid");

+      if (j->p2) {

+        if (j->p2->ntype == nJunction) {

+           fprintf(stderr," (p2=#%d)",( (Junction *) j->p2)->seq);

+        } else {

+           fprintf(stderr," (p2 valid)");

+        };

+      };

+	  if (j->ignore) fprintf(stderr, " ignore/plus-block-bypass");

+      if (j->fset != NULL && set_deg(*j->fset) != 0) {

+         fprintf(stderr,"\nfset:\n");

+         dumpset(*j->fset);

+      };

+      if (j->ftree != NULL) {

+         fprintf(stderr,"\nftree:\n");

+         preorder(j->ftree);

+      };

+      fprintf(stderr,"\n");

+      break;

+    case nRuleRef :

+       r = (RuleRefNode *) p;

+       fprintf(stderr, "RuleRefNode (in rule %s line %d) to rule %s\n", r->rname,r->line,r->text);

+       break;

+    case nToken :

+       t = (TokNode *) p;

+       fprintf(stderr, "TokNode (in rule %s line %d) token %s\n",t->rname,t->line,TerminalString(t->token));

+       break;

+    case nAction :

+       a =(ActionNode *) p;

+       if (a->is_predicate) {

+         fprintf(stderr, "Predicate (in rule %s line %d) %s",a->rname,a->line,a->action);

+         if (a->inverted) fprintf(stderr," action inverted !");

+         if (a->guardpred != NULL) {

+           fprintf(stderr," guarded");

+           dumppredexpr(a->guardpred);

+           if (a->ampersandPred) {

+             fprintf(stderr," \"&&\" style");

+           } else {

+             fprintf(stderr," \"=>\" style");

+           };

+         };

+         if (a->predEntry != NULL) fprintf(stderr," predEntry \"%s\" ",a->predEntry->str);

+         fprintf(stderr,"\n");

+       } else if (a->init_action) {

+         fprintf(stderr, "Init-Action (in rule %s line %d) %s\n",a->rname,a->line,a->action);

+       } else {

+         fprintf(stderr, "Action (in rule %s line %d) %s\n",a->rname,a->line,a->action);

+       };

+       break;

+   };

+}

+

+#ifdef __USE_PROTOS

+Node * dp1(Node * p)

+#else

+Node * dp1(p)

+  Node *    p;

+#endif

+{

+  Node  *result=NULL;

+

+  if (p->ntype == nJunction) {

+    result=( (Junction *) p )->p1;

+    d(result);

+  } else {

+    fprintf(stderr,"dp1: Not a Junction node");

+  };

+  return result;

+}

+

+#ifdef __USE_PROTOS

+Node * dp2(Node * p)

+#else

+Node * dp2(p)

+  Node *    p;

+#endif

+{

+  Node  *result=NULL;

+

+  if (p->ntype == nJunction) {

+    result=( (Junction *) p )->p2;

+    d(result);

+  } else {

+    fprintf(stderr,"dp2: Not a Junction node");

+  };

+  return result;

+}

+

+#ifdef __USE_PROTOS

+Node * dn(Node * p)

+#else

+Node * dn(p)

+  Node *    p;

+#endif

+

+{

+  Node  *result=NULL;

+

+  if (p->ntype == nRuleRef) {

+    result=( (RuleRefNode *)p )->next;

+  } else if (p->ntype == nAction) {

+    result=( (ActionNode *)p )->next;

+  } else if (p->ntype == nToken) {

+    result=( (TokNode *)p )->next;

+  } else {

+    fprintf(stderr,"No next field: Neither a RuleRefNode, ActionNode, nor TokNode");

+  };

+  if (result != NULL) d(result);

+  return result;

+}

+

+#ifdef __USE_PROTOS

+void df(Node * p)

+#else

+void df(p)

+  Node *    p;

+#endif

+{

+  int       count=0;

+  Node      *next;

+

+  fprintf(stderr,"\n#%d ",++count);

+  d(p);

+

+  for (next=p; next != NULL && !isEndRule(next) ; ) {

+    fprintf(stderr,"#%d ",++count);

+    if (next->ntype == nJunction) {

+      next=dp1(next);

+    } else {

+      next=dn(next);

+    };

+  };

+}

+

+#ifdef __USE_PROTOS

+Node * dfn(Node * p,int target)

+#else

+Node * dfn(p,target)

+  Node *    p;

+  int       target;

+#endif

+{

+  Node      *result=NULL;

+  int       count=0;

+  Node      *next;

+

+  fprintf(stderr,"#%d ",++count);

+  d(p);

+

+  for (next=p; next != NULL && !isEndRule(next) ; ) {

+    fprintf(stderr,"#%d ",++count);

+    if (next->ntype == nJunction) {

+      next=dp1(next);

+    } else {

+      next=dn(next);

+    };

+    if (count == target) {

+      result=next;

+      break;

+    };

+  };

+  return result;

+}

+

+

+static int findnodeMatch;

+

+#ifdef __USE_PROTOS

+Junction *findnode1(Node *n)

+#else

+Junction *findnode1(n)

+  Node  *n;

+#endif

+{

+   Node         *next;

+   Junction     *j;

+   Junction     *match;

+

+   if (n == NULL) return NULL;

+   if (n->ntype == nJunction) {

+     j=(Junction *) n;

+     if (j->seq == findnodeMatch) return j;

+     if (j->jtype == EndRule) return NULL;

+     if (j->jtype != RuleBlk && j->jtype != EndBlk) {

+       if (j->p2 != NULL && !j->ignore) {

+          match=findnode1(j->p2);

+          if (match != NULL) return match;

+       };

+     };

+   };

+   next=MR_advance(n);

+   return findnode1(next);

+}

+

+#ifdef __USE_PROTOS

+Junction *findnode(int match)

+#else

+Junction *findnode(match)

+  int   match;

+#endif

+{

+  Junction  *j;

+  Junction  *result=NULL;

+

+  findnodeMatch=match;

+

+  for (j=SynDiag; j != NULL; j=(Junction *)j->p2) {

+    require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block");

+    result=findnode1( (Node *) j);

+    if (result != NULL) break;

+  };

+  if (result != NULL) {

+    d( (Node *) result);

+  };

+  return result;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/egman.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/egman.c
new file mode 100644
index 0000000..c8a633f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/egman.c
@@ -0,0 +1,328 @@
+/*

+ * egman.c

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33MR10

+ * 2001

+ *

+ */

+

+#include <stdio.h>

+#include <stdlib.h>

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "proto.h"

+

+static ExceptionGroup **egArray=NULL;   /* ExceptionGroup by BlkLevel */

+static LabelEntry     **leArray=NULL;   /* LabelEntry by BlkLevel     */

+static Junction       **altArray=NULL;  /* start of alternates        */

+static int              arraySize=0;

+static int              highWater=0;

+static ExceptionGroup *lastEG=NULL;     /* used in altFixup()         */

+static int             lastBlkLevel=0;  /* used in altFixup()         */

+

+#ifdef __USE_PROTOS

+static void arrayCheck(void);

+#else

+static void arrayCheck();

+#endif

+

+/* Called to add an exception group for an alternative EG */

+

+#ifdef __USE_PROTOS

+void egAdd(ExceptionGroup * eg)

+#else

+void egAdd(eg)

+ExceptionGroup *eg;

+#endif

+{

+  int               i;

+

+  ExceptionGroup    *nextEG;

+  ExceptionGroup    *innerEG;

+

+  LabelEntry        *nextLE;

+  LabelEntry        *innerLE;

+

+  Junction          *nextAlt;

+  Junction          *innerAlt;

+

+  lastEG=eg;

+  lastBlkLevel=BlkLevel;

+

+  arrayCheck();

+  eg->pendingLink=egArray[BlkLevel];

+  egArray[BlkLevel]=eg;

+

+  /* EG for alternates already have their altID filled in      */

+

+  for (i=BlkLevel+1; i<=highWater ; i++) {

+    for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {

+      nextEG=innerEG->pendingLink;

+      innerEG->pendingLink=NULL;

+      innerEG->outerEG=eg;

+    };

+    egArray[i]=NULL;

+  };

+

+  /*

+   *  for patching up the LabelEntry you might use an EG for the

+   *  current alternative - unlike patching up an alternative EG

+   *    i.e. start the loop at BlkLevel rather than (BlkLevel+1)

+   *  fill it in only if the EG and the LE are for the very

+   *    same alternative if they're at the same BlkLevel

+   *  it's easier to leave the LE on this list (filled in) rather than

+   *    trying to selectively remove it.  It will eventually be

+   *    removed anyway when the BlkLevel gets small enough.

+   */

+

+  for (i=BlkLevel; i<=highWater ; i++) {

+    for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {

+      nextLE=innerLE->pendingLink;

+      if (BlkLevel != i ||

+        innerLE->curAltNum == CurAltNum_array[BlkLevel]) {

+        if (innerLE->outerEG == NULL) {

+          innerLE->outerEG=eg;

+        };

+      };

+    };

+    if (BlkLevel != i) leArray[i]=NULL;

+  };

+

+/*

+ * For the start of alternatives it is necessary to make a

+ * distinction between the exception group for the current

+ * alternative and the "fallback" EG for the block which

+ * contains the alternative

+ *

+ * The fallback outerEG is used to handle the case where

+ * no alternative of a block matches.  In that case the

+ * signal is "NoViableAlt" (or "NoSemViableAlt" and the

+ * generator needs the EG of the block CONTAINING the

+ * current one.

+ *

+ *      rule: ( ( ( a

+ *                | b

+ *                )

+ *              | c

+ *              )

+ *            | d

+ *            );

+ */

+

+  for (i=BlkLevel; i <= highWater ; i++) {

+    for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {

+      nextAlt=innerAlt->pendingLink;

+

+      /*  first fill in the EG for the current alternative         */

+      /*  but leave it on the list in order to get the fallback EG */

+      /*  if the EG is at the same LEVEL as the alternative then   */

+      /*    fill it in only if in the very same alternative        */

+      /*                                                           */

+      /*        rule: ( a                                          */

+      /*              | b                                          */

+      /*              | c  exception ...                           */

+      /*              )                                            */

+      /*                                                           */

+      /*  if the EG is outside the alternative (e.g. BlkLevel < i) */

+      /*    then it doesn't matter about the alternative           */

+      /*                                                           */

+      /*        rule: ( a                                          */

+      /*              | b                                          */

+      /*              | c                                          */

+      /*              )   exception ...                            */

+      /*                                                           */

+

+#if 0

+      printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%s\n",

+        BlkLevel,i,innerAlt->curAltNum,CurAltNum_array[BlkLevel],eg->altID);

+#endif

+      if (BlkLevel != i ||

+          innerAlt->curAltNum == CurAltNum_array[BlkLevel]) {

+        if (innerAlt->exception_label == NULL) {

+          innerAlt->exception_label=eg->altID;

+        };

+      };

+

+      /*  ocurs at a later pass then for the exception_label       */

+      /*  if an outerEG has been found then fill in the outer EG   */

+      /*  remove if from the list when the BlkLevel gets smaller   */

+

+      if (BlkLevel != i) {

+        if (innerAlt->outerEG == NULL) {

+          innerAlt->outerEG=eg;

+        };

+      };

+    };

+    if (BlkLevel != i) altArray[i]=NULL;

+  };

+}

+

+#ifdef __USE_PROTOS

+void leAdd(LabelEntry * le)

+#else

+void leAdd(le)

+LabelEntry *le;

+#endif

+

+{

+  arrayCheck();

+  le->pendingLink=leArray[BlkLevel];

+  le->curAltNum=CurAltNum_array[BlkLevel];

+  leArray[BlkLevel]=le;

+}

+

+#ifdef __USE_PROTOS

+void altAdd(Junction *alt)

+#else

+void altAdd(alt)

+Junction *alt;

+#endif

+

+{

+  arrayCheck();

+#if 0

+  printf("BlkLevel=%d CurAltNum=%d\n",

+            BlkLevel,CurAltNum_array[BlkLevel]);

+#endif

+  alt->curAltNum=CurAltNum_array[BlkLevel];

+  alt->pendingLink=altArray[BlkLevel];

+  altArray[BlkLevel]=alt;

+}

+

+static void 

+#ifdef __USE_PROTOS

+arrayCheck(void)

+#else

+arrayCheck()

+#endif

+{

+  ExceptionGroup    **egArrayNew;

+  LabelEntry        **leArrayNew;

+  Junction          **altArrayNew;

+  int               arraySizeNew;

+  int               i;

+

+  if (BlkLevel > highWater) highWater=BlkLevel;

+

+  if (BlkLevel >= arraySize) {

+    arraySizeNew=BlkLevel+5;	/* MR20 */

+    egArrayNew=(ExceptionGroup **)

+        calloc(arraySizeNew,sizeof(ExceptionGroup *));

+    leArrayNew=(LabelEntry **)

+        calloc(arraySizeNew,sizeof(LabelEntry *));

+    altArrayNew=(Junction **)

+        calloc(arraySizeNew,sizeof(Junction *));

+    for (i=0; i<arraySize ; i++) {

+      egArrayNew[i]=egArray[i];

+      leArrayNew[i]=leArray[i];

+      altArrayNew[i]=altArray[i];

+    };

+    arraySize=arraySizeNew;

+    if (egArray != NULL) free( (char *) egArray);

+    if (leArray != NULL) free( (char *) leArray);

+    if (altArray != NULL) free( (char *) altArray);

+    egArray=egArrayNew;

+    leArray=leArrayNew;

+    altArray=altArrayNew;

+  };

+}

+

+/* always call leFixup() BEFORE egFixup() */

+

+void 

+#ifdef __USE_PROTOS

+egFixup(void) 

+#else

+egFixup()

+#endif

+{

+  int               i;

+  ExceptionGroup    *nextEG;

+  ExceptionGroup    *innerEG;

+

+  for (i=1; i<=highWater ; i++) {

+    for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {

+      nextEG=innerEG->pendingLink;

+      innerEG->pendingLink=NULL;

+    };

+    egArray[i]=NULL;

+  };

+  lastEG=NULL;

+  lastBlkLevel=0;

+}

+

+/* always call leFixup() BEFORE egFixup() */

+

+#ifdef __USE_PROTOS

+void leFixup(void) 

+#else

+void leFixup() 

+#endif

+{

+

+  int               i;

+  LabelEntry        *nextLE;

+  LabelEntry        *innerLE;

+

+  for (i=BlkLevel; i<=highWater ; i++) {

+    for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {

+      nextLE=innerLE->pendingLink;

+      innerLE->pendingLink=NULL;

+    };

+    leArray[i]=NULL;

+  };

+}

+

+/* always call altFixup() BEFORE egFixup() */

+

+#ifdef __USE_PROTOS

+void altFixup(void)

+#else

+void altFixup() 

+#endif

+{

+

+  int               i;

+  Junction          *nextAlt;

+  Junction          *innerAlt;

+

+  for (i=BlkLevel; i<=highWater ; i++) {

+    for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {

+

+      /*  if an outerEG has been found then fill in the outer EG   */

+

+      if (lastBlkLevel <= i) {

+        if (innerAlt->outerEG == NULL) {

+          innerAlt->outerEG=lastEG;

+        };

+      };

+      nextAlt=innerAlt->pendingLink;

+      innerAlt->pendingLink=NULL;

+    };

+    altArray[i]=NULL;

+  };

+}

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/err.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/err.c
new file mode 100644
index 0000000..ca23939
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/err.c
@@ -0,0 +1,538 @@
+/*

+ * A n t l r  S e t s / E r r o r  F i l e  H e a d e r

+ *

+ * Generated from: antlr.g

+ *

+ * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001

+ * Parr Research Corporation

+ * with Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include "pcctscfg.h"

+#include "set.h"

+#include <ctype.h>

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#define zzcr_attr(attr,tok,t)

+#define zzSET_SIZE 20

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+#include "err.h"

+

+ANTLRChar *zztokens[157]={

+	/* 00 */	"Invalid",

+	/* 01 */	"Eof",

+	/* 02 */	"QuotedTerm",

+	/* 03 */	"\\n|\\r|\\r\\n",

+	/* 04 */	"\\(\\n|\\r|\\r\\n)",

+	/* 05 */	"\\~[]",

+	/* 06 */	"~[\\n\\r\"\\]+",

+	/* 07 */	"\"",

+	/* 08 */	"\\n|\\r|\\r\\n",

+	/* 09 */	"\\(\\n|\\r|\\r\\n)",

+	/* 10 */	"\\~[]",

+	/* 11 */	"~[\\n\\r\"\\]+",

+	/* 12 */	"'",

+	/* 13 */	"\\n|\\r|\\r\\n",

+	/* 14 */	"\\~[]",

+	/* 15 */	"~[\\n\\r'\\]+",

+	/* 16 */	"\\*/",

+	/* 17 */	"\\*",

+	/* 18 */	"\\n|\\r|\\r\\n",

+	/* 19 */	"~[\\n\\r\\*]+",

+	/* 20 */	"\\*/",

+	/* 21 */	"\\*",

+	/* 22 */	"\\n|\\r|\\r\\n",

+	/* 23 */	"~[\\n\\r\\*]+",

+	/* 24 */	"\\n|\\r|\\r\\n",

+	/* 25 */	"~[\\n\\r]+",

+	/* 26 */	"\\n|\\r|\\r\\n",

+	/* 27 */	"~[\\n\\r]+",

+	/* 28 */	"\\n|\\r|\\r\\n",

+	/* 29 */	"~[\\n\\r]+",

+	/* 30 */	"\\*/",

+	/* 31 */	"\\*",

+	/* 32 */	"\\n|\\r|\\r\\n",

+	/* 33 */	"~[\\n\\r\\*]+",

+	/* 34 */	"Action",

+	/* 35 */	"Pred",

+	/* 36 */	"PassAction",

+	/* 37 */	"consumeUntil\\( [\\ \\t]* \\{~[\\}]+\\} [\\ \\t]* \\)",

+	/* 38 */	"consumeUntil\\( ~[\\)]+ \\)",

+	/* 39 */	"\\n|\\r|\\r\\n",

+	/* 40 */	"\\>",

+	/* 41 */	"$",

+	/* 42 */	"$$",

+	/* 43 */	"$\\[\\]",

+	/* 44 */	"$\\[",

+	/* 45 */	"$[0-9]+",

+	/* 46 */	"$[0-9]+.",

+	/* 47 */	"$[0-9]+.[0-9]+",

+	/* 48 */	"$[_a-zA-Z][_a-zA-Z0-9]*",

+	/* 49 */	"#0",

+	/* 50 */	"#\\[\\]",

+	/* 51 */	"#\\(\\)",

+	/* 52 */	"#[0-9]+",

+	/* 53 */	"#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)",

+	/* 54 */	"#line ~[\\n\\r]* (\\n|\\r|\\r\\n)",

+	/* 55 */	"#[_a-zA-Z][_a-zA-Z0-9]*",

+	/* 56 */	"#\\[",

+	/* 57 */	"#\\(",

+	/* 58 */	"#",

+	/* 59 */	"\\)",

+	/* 60 */	"\\[",

+	/* 61 */	"\\(",

+	/* 62 */	"\\\\]",

+	/* 63 */	"\\\\)",

+	/* 64 */	"\\>",

+	/* 65 */	"'",

+	/* 66 */	"\"",

+	/* 67 */	"\\$",

+	/* 68 */	"\\#",

+	/* 69 */	"\\(\\n|\\r|\\r\\n)",

+	/* 70 */	"\\~[\\]\\)>$#]",

+	/* 71 */	"/",

+	/* 72 */	"/\\*",

+	/* 73 */	"\\*/",

+	/* 74 */	"//",

+	/* 75 */	"~[\\n\\r\\)\\(\\$#\\>\\]\\[\"'/]+",

+	/* 76 */	"[\\t\\ ]+",

+	/* 77 */	"\\n|\\r|\\r\\n",

+	/* 78 */	"\\[",

+	/* 79 */	"\\<\\<",

+	/* 80 */	"\"",

+	/* 81 */	"/\\*",

+	/* 82 */	"\\*/",

+	/* 83 */	"//",

+	/* 84 */	"#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)",

+	/* 85 */	"#line ~[\\n\\r]* (\\n|\\r|\\r\\n)",

+	/* 86 */	"\\>\\>",

+	/* 87 */	"WildCard",

+	/* 88 */	"\\@",

+	/* 89 */	"LABEL",

+	/* 90 */	"grammar-element",

+	/* 91 */	"meta-symbol",

+	/* 92 */	"Pragma",

+	/* 93 */	"FirstSetSymbol",

+	/* 94 */	"{\\}#header",

+	/* 95 */	"{\\}#first",

+	/* 96 */	"{\\}#parser",

+	/* 97 */	"{\\}#tokdefs",

+	/* 98 */	"\\}",

+	/* 99 */	"class",

+	/* 100 */	"NonTerminal",

+	/* 101 */	"TokenTerm",

+	/* 102 */	"\\{",

+	/* 103 */	"!",

+	/* 104 */	"\\<",

+	/* 105 */	"\\>",

+	/* 106 */	":",

+	/* 107 */	";",

+	/* 108 */	"{\\}#lexaction",

+	/* 109 */	"{\\}#lexmember",

+	/* 110 */	"{\\}#lexprefix",

+	/* 111 */	"{\\}#pred",

+	/* 112 */	"\\|\\|",

+	/* 113 */	"&&",

+	/* 114 */	"\\(",

+	/* 115 */	"\\)",

+	/* 116 */	"{\\}#lexclass",

+	/* 117 */	"{\\}#errclass",

+	/* 118 */	"{\\}#tokclass",

+	/* 119 */	"..",

+	/* 120 */	"{\\}#token",

+	/* 121 */	"=",

+	/* 122 */	"[0-9]+",

+	/* 123 */	"\\|",

+	/* 124 */	"\\~",

+	/* 125 */	"^",

+	/* 126 */	"approx",

+	/* 127 */	"LL\\(1\\)",

+	/* 128 */	"LL\\(2\\)",

+	/* 129 */	"\\*",

+	/* 130 */	"\\+",

+	/* 131 */	"?",

+	/* 132 */	"=>",

+	/* 133 */	"exception",

+	/* 134 */	"default",

+	/* 135 */	"catch",

+	/* 136 */	"{\\}#[A-Za-z0-9_]*",

+	/* 137 */	"[\\t\\ ]+",

+	/* 138 */	"\\n|\\r|\\r\\n",

+	/* 139 */	"//",

+	/* 140 */	"/\\*",

+	/* 141 */	"#ifdef",

+	/* 142 */	"#if",

+	/* 143 */	"#ifndef",

+	/* 144 */	"#else",

+	/* 145 */	"#endif",

+	/* 146 */	"#undef",

+	/* 147 */	"#import",

+	/* 148 */	"ID",

+	/* 149 */	"#define",

+	/* 150 */	"INT",

+	/* 151 */	"enum",

+	/* 152 */	"\\{",

+	/* 153 */	"=",

+	/* 154 */	",",

+	/* 155 */	"\\}",

+	/* 156 */	";"

+};

+SetWordType zzerr1[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr2[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xf3,

+	0xbf,0xff,0xff,0xff, 0xff,0xff,0xff,0x1f};

+SetWordType zzerr3[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xfb,

+	0x3b,0xf7,0xf7,0xc7, 0xff,0xff,0xff,0x1f};

+SetWordType zzerr4[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x80,0x7,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType setwd1[157] = {0x0,0x50,0xa0,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x6a,0x20,0xa0,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x0,0x0,0x20,0x20,0x21,

+	0x21,0x21,0x21,0x6e,0x6e,0x64,0x20,0x0,

+	0x20,0xa0,0xa0,0xa0,0x20,0x6a,0x6a,0x6a,

+	0x6e,0x20,0x20,0x20,0x20,0x66,0x6e,0x6e,

+	0x20,0x66,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

+	0x20,0x20,0x20,0x20,0x20,0x20};

+SetWordType zzerr5[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr6[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x7,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr7[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x6,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr8[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x4,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr9[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf0,0x70,0x1, 0x20,0x0,0x0,0x0};

+SetWordType setwd2[157] = {0x0,0xf8,0x6,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xf8,0x0,0x1,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xf8,0xf8,0xf8,0x0,0x0,

+	0x0,0x1,0x2,0x6,0x0,0xf8,0xf8,0xf8,

+	0xf8,0x0,0x0,0x0,0x0,0xf8,0xf8,0xf8,

+	0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0xe8,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr10[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0xbc,0xf8,0x74,0x1, 0x20,0x0,0x0,0x0};

+SetWordType zzerr11[20] = {0x0,0x0,0x0,0x0, 0x8,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr12[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};

+SetWordType zzerr13[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};

+SetWordType setwd3[157] = {0x0,0xfa,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xfa,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xfa,0xfa,0xfa,0x5,0x0,

+	0x5,0x0,0x0,0x0,0xe2,0xfa,0xfa,0xfa,

+	0xfa,0xc0,0x80,0x5,0xe0,0xfa,0xfa,0xfa,

+	0x0,0xfa,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0xfa,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr14[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr15[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr16[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr17[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr18[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x24,0x0,0x80,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr19[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr20[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x74,0x3, 0x20,0x0,0x0,0x0};

+SetWordType zzerr21[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x70,0x3, 0x20,0x0,0x0,0x0};

+SetWordType setwd4[157] = {0x0,0xe5,0xda,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xe5,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xed,0xe5,0xe7,0x1a,0x0,

+	0x0,0x0,0x0,0x0,0xc0,0xe5,0xe5,0xe5,

+	0xe5,0x0,0x0,0x0,0x0,0xe5,0xe5,0xe5,

+	0x0,0xe5,0x40,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0xe5,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr22[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x3c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};

+SetWordType zzerr23[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};

+SetWordType zzerr24[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};

+SetWordType zzerr25[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};

+SetWordType zzerr26[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5,

+	0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType setwd5[157] = {0x0,0x1f,0xc1,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xdf,0xc0,0xc0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0xc0,0x0,0xc0,0x0,0x0,0xc0,0xc0,0x0,

+	0x0,0x0,0x0,0x7f,0x1f,0xdf,0xc0,0xc0,

+	0x0,0x0,0xc0,0x0,0x67,0x1f,0x1f,0x1f,

+	0x1f,0x0,0x0,0xc0,0x60,0x1f,0x1f,0x1f,

+	0x0,0x1f,0x0,0x0,0x40,0xc0,0x0,0x0,

+	0x0,0x0,0xc0,0xc0,0x0,0x0,0x5f,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr27[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x0,0x0,0x0,0x10, 0x0,0x0,0x0,0x0};

+SetWordType zzerr28[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x2,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr29[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr30[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,

+	0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0};

+SetWordType zzerr31[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,

+	0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0};

+SetWordType zzerr32[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5,

+	0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr33[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType setwd6[157] = {0x0,0x0,0xfd,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0xfd,0x60,0xe9,0x0,0x0,0xe1,0xe1,0x0,

+	0x0,0x0,0x0,0xe2,0x0,0xfd,0xfd,0xe1,

+	0x20,0x0,0xe1,0x0,0xe2,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xe1,0xe2,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0xe2,0xe0,0x20,0x0,

+	0x0,0x0,0xe1,0xe1,0x0,0x0,0xe2,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr34[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,

+	0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0};

+SetWordType zzerr35[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,

+	0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0};

+SetWordType zzerr36[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5,

+	0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr37[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xc,

+	0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0};

+SetWordType zzerr38[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x84,0x9,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr39[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr40[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x4,0x9,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr41[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr42[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x0,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType setwd7[157] = {0x0,0x0,0xdf,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xdf,0xdf,0xff,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0xdf,0x3,0xdf,0x0,0x0,0xdf,0xdf,0x0,

+	0x0,0x0,0x0,0xdf,0x0,0xdf,0xdf,0xdf,

+	0x1,0x30,0xdf,0x0,0xdf,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xdf,0xdf,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0xdf,0xdf,0x1,0x0,

+	0x0,0x0,0xdf,0xdf,0x0,0x0,0xdf,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr43[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr44[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xc0, 0x1,0x0,0x0,0x0};

+SetWordType zzerr45[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x30,

+	0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr46[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr47[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x20,

+	0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr48[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x2,0x0, 0x10,0x0,0x0,0x0};

+SetWordType zzerr49[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};

+SetWordType zzerr50[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x4,0x8,0xa,0x18, 0x30,0x0,0x0,0x0};

+SetWordType zzerr51[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x4,0x8,0x8,0x18, 0x28,0x0,0x0,0x0};

+SetWordType zzerr52[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr53[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType setwd8[157] = {0x0,0x0,0xe1,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0xe1,0x0,0xe1,0x0,0x0,0xe3,0xe7,0x0,

+	0x0,0x0,0x0,0xe1,0x0,0xe1,0xe1,0xef,

+	0x0,0x0,0xe1,0x0,0xe1,0x0,0x0,0x0,

+	0x0,0x0,0x10,0xef,0xe1,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0xe1,0xe1,0x0,0x0,

+	0x0,0x0,0xe1,0xe1,0x0,0x10,0xe1,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr54[20] = {0x2,0x0,0x0,0x0, 0x14,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0};

+SetWordType zzerr55[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x78,0x9, 0x60,0x0,0x0,0x0};

+SetWordType zzerr56[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr57[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0};

+SetWordType setwd9[157] = {0x0,0x7c,0x1,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x7f,0x1,0x1,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x1,0x0,0x1,0x0,0x0,0x1,0x1,0x0,

+	0x0,0x0,0x0,0x7f,0x7e,0x7f,0x1,0x1,

+	0x0,0x0,0x1,0x0,0x7d,0x7e,0x7e,0x7e,

+	0x7e,0x0,0x0,0x1,0x7d,0x7e,0x7e,0x7e,

+	0x0,0x7e,0x0,0x0,0x7d,0x1,0x0,0x0,

+	0x0,0x0,0x1,0x1,0x0,0x0,0x7f,0x64,

+	0x64,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x0,

+	0x80,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr58[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0};

+SetWordType zzerr59[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0};

+SetWordType zzerr60[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0};

+SetWordType zzerr61[20] = {0x2,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0};

+SetWordType zzerr62[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe};

+SetWordType zzerr63[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe};

+SetWordType zzerr64[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe};

+SetWordType zzerr65[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0, 0x0,0x0,0x10,0xc};

+SetWordType setwd10[157] = {0x0,0xc,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,

+	0x3,0x0,0x0,0xf0,0xf0,0x0};

+SetWordType setwd11[157] = {0x0,0x1,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,

+	0x1,0x0,0x0,0x0,0x0,0x0};

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/fcache.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/fcache.c
new file mode 100644
index 0000000..ff7dcdf
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/fcache.c
@@ -0,0 +1,123 @@
+/*

+ * fcache.c

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33MR10

+ *

+ */

+

+#include <stdio.h>

+#include <ctype.h>

+

+#include "pcctscfg.h"

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+

+#ifdef __USE_PROTOS

+CacheEntry *dumpFcache1(char *prev)

+#else

+CacheEntry *dumpFcache1(prev)

+  char  *prev;

+#endif

+{

+    Entry   **table=Fcache;

+

+    int     low=0;

+    int     hi=0;

+

+    CacheEntry  *least=NULL;

+

+	Entry   **p;

+

+	for (p=table; p<&(table[HashTableSize]); p++) {

+

+		CacheEntry *q =(CacheEntry *) *p;

+		

+		if ( q != NULL && low==0 ) low = p-table;

+		while ( q != NULL ) {

+            if (strcmp(q->str,prev) > 0) {

+              if (least == NULL) {

+                least=q;

+              } else {

+                if (strcmp(q->str,least->str) < 0) {

+                  least=q;

+                };

+              };

+            };

+			q = q->next;

+		};

+

+		if ( *p != NULL ) hi = p-table;

+	}

+    return least;

+}

+

+#ifdef __USE_PROTOS

+void reportFcache(CacheEntry *q)

+#else

+void reportFcache(q)

+  CacheEntry    *q;

+#endif

+{

+    char        *qstr;

+

+    fprintf(stdout,"\nrule ");

+    for (qstr=q->str; *qstr != '*' ; qstr++) {

+      fprintf(stdout,"%c",*qstr);

+    };

+

+    qstr++;

+    if (*qstr == 'i') fprintf(stdout," First[");

+    if (*qstr == 'o') fprintf(stdout," Follow[");

+    qstr++;

+    fprintf(stdout,"%s]",qstr);

+    if (q->incomplete) fprintf(stdout," *** incomplete ***");

+    fprintf(stdout,"\n");

+    MR_dumpTokenSet(stdout,1,q->fset);

+}

+

+void 

+#ifdef __USE_PROTOS

+DumpFcache(void) 

+#else

+DumpFcache() 

+#endif

+{

+

+    char        *prev="";

+    int          n=0;

+    CacheEntry  *next;

+

+    fprintf(stdout,"\n\nDump of First/Follow Cache\n");

+

+    for(;;) {

+      next=dumpFcache1(prev);

+      if (next == NULL) break;

+      reportFcache(next);

+      ++n;

+      prev=next->str;

+    };

+    fprintf(stdout,"\nEnd dump of First/Follow Cache\n");

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/fset.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/fset.c
new file mode 100644
index 0000000..e1a76ec
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/fset.c
@@ -0,0 +1,1555 @@
+/*

+ * fset.c

+ *

+ * Compute FIRST and FOLLOW sets.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <stdlib.h>

+

+#include "pcctscfg.h"

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+#include "limits.h"

+

+#ifdef __USE_PROTOS

+static void ensure_predicates_cover_ambiguous_lookahead_sequences

+                                    (Junction *, Junction *, char *, Tree *);

+#else

+static void ensure_predicates_cover_ambiguous_lookahead_sequences();

+#endif

+

+/*

+ * What tokens are k tokens away from junction q?

+ *

+ * Follow both p1 and p2 paths (unless RuleBlk) to collect the tokens k away from this

+ * node.

+ * We lock the junction according to k--the lookahead.  If we have been at this

+ * junction before looking for the same, k, number of lookahead tokens, we will

+ * do it again and again...until we blow up the stack.  Locks are only used on aLoopBlk,

+ * RuleBlk, aPlusBlk and EndRule junctions to remove/detect infinite recursion from

+ * FIRST and FOLLOW calcs.

+ *

+ * If p->jtype == EndRule we are going to attempt a FOLLOW.  (FOLLOWs are really defined

+ * in terms of FIRST's, however).  To proceed with the FOLLOW, p->halt cannot be

+ * set.  p->halt is set to indicate that a reference to the current rule is in progress

+ * and the FOLLOW is not desirable.

+ *

+ * If we attempt a FOLLOW and find that there is no FOLLOW or REACHing beyond the EndRule

+ * junction yields an empty set, replace the empty set with EOF.  No FOLLOW means that

+ * only EOF can follow the current rule.  This normally occurs only on the start symbol

+ * since all other rules are referenced by another rule somewhere.

+ *

+ * Normally, both p1 and p2 are followed.  However, checking p2 on a RuleBlk node is

+ * the same as checking the next rule which is clearly incorrect.

+ *

+ * Cycles in the FOLLOW sense are possible.  e.g. Fo(c) requires Fo(b) which requires

+ * Fo(c).  Both Fo(b) and Fo(c) are defined to be Fo(b) union Fo(c).  Let's say

+ * Fo(c) is attempted first.  It finds all of the FOLLOW symbols and then attempts

+ * to do Fo(b) which finds of its FOLLOW symbols.  So, we have:

+ *

+ *                  Fo(c)

+ *                 /     \

+ *              a set    Fo(b)

+ *                      /     \

+ *                   a set    Fo(c) .....Hmmmm..... Infinite recursion!

+ *

+ * The 2nd Fo(c) is not attempted and Fo(b) is left deficient, but Fo(c) is now

+ * correctly Fo(c) union Fo(b).  We wish to pick up where we left off, so the fact

+ * that Fo(b) terminated early means that we lack Fo(c) in the Fo(b) set already

+ * laying around.  SOOOOoooo, we track FOLLOW cycles.  All FOLLOW computations are

+ * cached in a hash table.  After the sequence of FOLLOWs finish, we reconcile all

+ * cycles --> correct all Fo(rule) sets in the cache.

+ *

+ * Confused? Good! Read my MS thesis [Purdue Technical Report TR90-30].

+ * TJP 8/93 -- can now read PhD thesis from Purdue.

+ *

+ * Also, FIRST sets are cached in the hash table.  Keys are (rulename,Fi/Fo,k).

+ * Only FIRST sets, for which the FOLLOW is not included, are stored.

+ *

+ * SPECIAL CASE of (...)+ blocks:

+ * I added an optional alt so that the alts could see what

+ * was behind the (...)+ block--thus using enough lookahead

+ * to branch out rather than just enough to distinguish

+ * between alts in the (...)+.  However, when the FIRST("(...)+") is

+ * is needed, must not use this last "optional" alt.  This routine

+ * turns off this path by setting a new 'ignore' flag for

+ * the alt and then resetting it afterwards.

+ */

+

+set

+#ifdef __USE_PROTOS

+rJunc( Junction *p, int k, set *rk )

+#else

+rJunc( p, k, rk )

+Junction *p;

+int k;

+set *rk;

+#endif

+{

+	set     a, b;

+

+	require(p!=NULL,				"rJunc: NULL node");

+	require(p->ntype==nJunction,	"rJunc: not junction");

+

+#ifdef DBG_LL1

+	if ( p->jtype == RuleBlk ) fprintf(stderr, "FIRST(%s,%d) \n",((Junction *)p)->rname,k);

+	else fprintf(stderr, "rJunc: %s in rule %s\n",

+			decodeJType[p->jtype], ((Junction *)p)->rname);

+#endif

+	/* if this is one of the added optional alts for (...)+ then return */

+

+    /* no need to pop backtrace - hasn't been pushed */

+

+	if ( p->ignore ) return empty;

+

+    if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);

+

+/* MR14 */    if (AlphaBetaTrace && p->alpha_beta_guess_end) {

+/* MR14 */         warnFL(

+/* MR14 */           "not possible to compute follow set for alpha in an \"(alpha)? beta\" block.  ",

+/* MR14 */                 FileStr[p->file],p->line);

+/* MR14 */         MR_alphaBetaTraceReport();

+/* MR14 */    };

+

+/* MR14 */    if (p->alpha_beta_guess_end) {

+/* MR14 */      if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+/* MR14 */      return empty;

+/* MR14 */    }

+

+	/* locks are valid for aLoopBlk,aPlusBlk,RuleBlk,EndRule junctions only */

+	if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||

+		 p->jtype==aPlusBlk || p->jtype==EndRule )

+	{

+		require(p->lock!=NULL, "rJunc: lock array is NULL");

+		if ( p->lock[k] )

+		{

+			if ( p->jtype == EndRule )	/* FOLLOW cycle? */

+			{

+#ifdef DBG_LL1

+				fprintf(stderr, "FOLLOW cycle to %s: panic!\n", p->rname);

+#endif

+                if (! MR_AmbSourceSearch) RegisterCycle(p->rname, k);

+			}

+            if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+			return empty;

+		}

+		if ( p->jtype == RuleBlk &&

+                 p->end->halt  &&

+                     ! MR_AmbSourceSearch)	/* check for FIRST cache */

+		{

+			CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'i',k));

+			if ( q != NULL )

+			{

+				set_orin(rk, q->rk);

+                if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+   				return set_dup( q->fset );

+			}

+		}

+		if ( p->jtype == EndRule &&

+                !p->halt &&                     /* MR11 was using cache even when halt set */

+                     ! MR_AmbSourceSearch)		/* FOLLOW set cached already? */

+		{

+			CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k));

+			if ( q != NULL )

+			{

+#ifdef DBG_LL1

+				fprintf(stderr, "cache for FOLLOW(%s,%d):", p->rname,k);

+				s_fprT(stderr, q->fset);

+				if ( q->incomplete ) fprintf(stderr, " (incomplete)");

+				fprintf(stderr, "\n");

+#endif

+				if ( !q->incomplete )

+				{

+                    if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+					return set_dup( q->fset );

+				}

+			}

+		}

+		p->lock[k] = TRUE;	/* This rule is busy */

+	}

+

+	a = b = empty;

+

+	if ( p->jtype == EndRule )

+	{

+		if (p->halt )			/* don't want FOLLOW here? */ /* unless MR10 hoisting */

+		{

+ 	  	      p->lock[k] = FALSE;

+			  set_orel(k, rk);						/* indicate this k value needed */

+              if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+			  return empty;

+		}

+		if (! MR_AmbSourceSearch) FoPush(p->rname, k);		/* Attempting FOLLOW */

+		if ( p->p1 == NULL ) set_orel((TokenInd!=NULL?TokenInd[EofToken]:EofToken), &a);/* if no FOLLOW assume EOF */

+#ifdef DBG_LL1

+		fprintf(stderr, "-->FOLLOW(%s,%d)\n", p->rname,k);

+#endif

+	}

+

+	if ( p->p1 != NULL ) {

+/* MR14 */      if (p->guess) {

+/* MR14 */        if (p->guess_analysis_point == NULL) {

+/* MR14 */           Node * guess_point;

+/* MR14 */           guess_point=(Node *)analysis_point(p);

+/* MR14 */           if (guess_point == (Node *)p) {

+/* MR14 */             guess_point=p->p1;

+/* MR14 */           }

+/* MR14 */           p->guess_analysis_point=guess_point;

+/* MR14 */        }

+/* MR14 */        REACH(p->guess_analysis_point, k, rk, a);

+                } else {

+                  REACH(p->p1, k, rk, a);

+                }

+    }	

+

+	/* C a c h e  R e s u l t s */

+

+	if ( p->jtype == RuleBlk && p->end->halt && ! MR_AmbSourceSearch)		/* can save FIRST set? */

+	{

+		CacheEntry *q = newCacheEntry( Fkey(p->rname,'i',k) );

+		/*fprintf(stderr, "Caching %s FIRST %d\n", p->rname, k);*/

+		hash_add(Fcache, Fkey(p->rname,'i',k), (Entry *)q);

+		q->fset = set_dup( a );

+		q->rk = set_dup( *rk );

+	}

+

+	if ( p->jtype == EndRule &&

+            !p->halt &&                         /* MR11 was using cache even with halt set */

+                 ! MR_AmbSourceSearch)			/* just completed FOLLOW? */

+	{

+		/* Cache Follow set */

+		CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k));

+		if ( q==NULL )

+		{

+			q = newCacheEntry( Fkey(p->rname,'o',k) );

+			hash_add(Fcache, Fkey(p->rname,'o',k), (Entry *)q);

+		}

+		/*fprintf(stderr, "Caching %s FOLLOW %d\n", p->rname, k);*/

+		if ( set_nil(a) && !q->incomplete )

+		{

+			/* Don't ever save a nil set as complete.

+			 * Turn it into an eof set.

+			 */

+			set_orel(EofToken, &a);

+		}

+		set_orin(&(q->fset), a);

+		FoPop( k );

+		if ( FoTOS[k] == NULL && Cycles[k] != NULL ) ResolveFoCycles(k);

+#ifdef DBG_LL1

+		fprintf(stderr, "saving FOLLOW(%s,%d):", p->rname, k);

+		s_fprT(stderr, q->fset);

+		if ( q->incomplete ) fprintf(stderr, " (incomplete)");

+		fprintf(stderr, "\n");

+#endif

+	}

+	

+    if (p->jtype != RuleBlk && p->p2 != NULL && /* MR14 */ ! p->guess) {

+       REACH(p->p2, k, rk, b);

+    }	

+

+	if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||

+		 p->jtype==aPlusBlk || p->jtype==EndRule )

+		p->lock[k] = FALSE;							/* unlock node */

+

+	set_orin(&a, b);

+	set_free(b);

+    if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+	return a;

+}

+

+set

+#ifdef __USE_PROTOS

+rRuleRef( RuleRefNode *p, int k, set *rk_out )

+#else

+rRuleRef( p, k, rk_out )

+RuleRefNode *p;

+int k;

+set *rk_out;

+#endif

+{

+	set rk;

+	Junction *r;

+	int k2;

+	set a, rk2, b;

+	int save_halt;

+	RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);

+	require(p!=NULL,			"rRuleRef: NULL node");

+	require(p->ntype==nRuleRef,	"rRuleRef: not rule ref");

+

+#ifdef DBG_LL1

+	fprintf(stderr, "rRuleRef: %s\n", p->text);

+#endif

+

+    if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);

+

+	if ( q == NULL )

+	{

+		warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );

+		REACH(p->next, k, rk_out, a);

+        if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+		return a;

+	}

+	rk2 = empty;

+

+/* MR9 Problems with rule references in guarded predicates */

+/* MR9    Perhaps can use hash table to find rule ?        */

+

+/* MR9 */    if (RulePtr == NULL) {

+/* MR9 */        fatalFL(eMsg2("Rule %s uses rule %s via RulePtr before it has been initialized",

+/* MR9 */                                p->rname,q->str),FileStr[p->file],p->line);

+/* MR9 */    };

+

+	r = RulePtr[q->rulenum];

+	if ( r->lock[k] )

+	{

+		errNoFL( eMsg2("infinite left-recursion to rule %s from rule %s",

+						r->rname, p->rname) );

+

+        if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+

+		return empty;

+	}

+

+	save_halt = r->end->halt;

+	r->end->halt = TRUE;		/* don't let reach fall off end of rule here */

+	rk = empty;

+	REACH(r, k, &rk, a);

+	r->end->halt = save_halt;

+	while ( !set_nil(rk) ) {

+		k2 = set_int(rk);               /* MR11 this messes up the ambiguity search routine */

+		set_rm(k2, rk);

+		REACH(p->next, k2, &rk2, b);    /* MR11 by changing the value of k                  */

+		set_orin(&a, b);

+		set_free(b);

+	}

+	set_free(rk);				/* this has no members, but free it's memory */

+	set_orin(rk_out, rk2);		/* remember what we couldn't do */

+	set_free(rk2);

+    if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+	return a;

+}

+

+/*

+ * Return FIRST sub k ( token_node )

+ *

+ * TJP 10/11/93 modified this so that token nodes that are actually

+ * ranges (T1..T2) work.

+ */

+set

+#ifdef __USE_PROTOS

+rToken( TokNode *p, int k, set *rk )

+#else

+rToken( p, k, rk )

+TokNode *p;

+int k;

+set *rk;

+#endif

+{

+	set a;

+

+	require(p!=NULL,			"rToken: NULL node");

+	require(p->ntype==nToken,	"rToken: not token node");

+

+#ifdef DBG_LL1

+	fprintf(stderr, "rToken: %s\n", (TokenString(p->token)!=NULL)?TokenString(p->token):

+									ExprString(p->token));

+#endif

+

+

+    if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);

+

+    if (MR_AmbSourceSearch && (k-1) == 0) {

+

+      set       localConstrain;

+      set       intersection;

+

+      localConstrain=fset[maxk-k+1];

+

+      if (! set_nil(p->tset)) {

+        intersection=set_and(localConstrain,p->tset);

+        if (! set_nil(intersection)) {

+          MR_backTraceReport();

+        };

+        set_free(intersection);

+      } else {

+        if (set_el( (unsigned) p->token,localConstrain)) {

+          MR_backTraceReport();

+        }

+      };

+    };

+

+	if ( k-1 == 0 )	{

+

+        if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+

+		if ( !set_nil(p->tset) ) {

+            return set_dup(p->tset);

+        } else {

+    		return set_of(p->token);

+        };

+	}

+

+	REACH(p->next, k-1, rk, a);

+	

+    if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+

+	return a;

+}

+

+set

+#ifdef __USE_PROTOS

+rAction( ActionNode *p, int k, set *rk )

+#else

+rAction( p, k, rk )

+ActionNode *p;

+int k;

+set *rk;

+#endif

+{

+	set a;

+

+	require(p!=NULL,			"rJunc: NULL node");

+	require(p->ntype==nAction,	"rJunc: not action");

+	

+/* MR11 */    if (p->is_predicate && p->ampersandPred != NULL) {

+/* MR11 */      Predicate   *pred=p->ampersandPred;

+/* MR11 */      if (k <= pred->k) {

+/* MR11 */        REACH(p->guardNodes,k,rk,a);

+/* MR11 */        return a;

+/* MR11 */      };

+/* MR11 */    };

+

+    /* it might be a good idea when doing an MR_AmbSourceSearch

+       to *not* look behind predicates under some circumstances

+       we'll look into that later

+    */

+

+	REACH(p->next, k, rk, a);	/* ignore actions */

+	return a;

+}

+

+				/* A m b i g u i t y  R e s o l u t i o n */

+

+

+void

+#ifdef __USE_PROTOS

+dumpAmbigMsg( set *fset, FILE *f, int want_nls )

+#else

+dumpAmbigMsg( fset, f, want_nls )

+set *fset;

+FILE *f;

+int want_nls;

+#endif

+{

+	int i;

+

+    set     copy;               /* MR11 */

+

+	if ( want_nls ) fprintf(f, "\n\t");

+	else fprintf(f, " ");

+

+	for (i=1; i<=CLL_k; i++)

+	{

+        copy=set_dup(fset[i]);  /* MR11 */

+

+		if ( i>1 )

+		{

+			if ( !want_nls ) fprintf(f, ", ");

+		}

+		if ( set_deg(copy) > 3 && elevel == 1 )

+		{

+			int e,m;

+			fprintf(f, "{");

+			for (m=1; m<=3; m++)

+			{

+				e=set_int(copy);

+				fprintf(f, " %s", TerminalString(e));

+				set_rm(e, copy);

+			}

+			fprintf(f, " ... }");

+		}

+		else s_fprT(f, copy);

+		if ( want_nls ) fprintf(f, "\n\t");

+        set_free(copy);

+	}

+	fprintf(f, "\n");

+

+}

+

+static void

+#ifdef __USE_PROTOS

+verify_context(Predicate *predicate)

+#else

+verify_context(predicate)

+Predicate *predicate;

+#endif

+{

+	if ( predicate == NULL ) return;

+

+	if ( predicate->expr == PRED_OR_LIST ||

+		 predicate->expr == PRED_AND_LIST )

+	{

+		verify_context(predicate->down);

+		verify_context(predicate->right);       /* MR10 */

+		return;

+	}

+

+	if ( !predicate->source->ctxwarned && predicate->source->guardpred==NULL &&

+		 ((predicate->k > 1 &&

+		 !is_single_tuple(predicate->tcontext)) ||

+		 ( predicate->k == 1 &&

+			  set_deg(predicate->scontext[1])>1 )) )

+	{

+

+/* MR9 Suppress annoying messages caused by our own clever(?) fix */

+

+  		fprintf(stderr, ErrHdr, FileStr[predicate->source->file],

+				predicate->source->line);

+		fprintf(stderr, " warning: predicate applied for >1 lookahead %d-sequences\n", predicate->k);

+		fprintf(stderr, ErrHdr, FileStr[predicate->source->file],

+				predicate->source->line);

+		fprintf(stderr, "     predicate text: \"%s\"\n",

+                        (predicate->expr == NULL ? "(null)" : predicate->expr) );

+		fprintf(stderr, ErrHdr, FileStr[predicate->source->file],

+				predicate->source->line);

+		fprintf(stderr, "     You may only want one lookahead %d-sequence to apply\n", predicate->k);

+		fprintf(stderr, ErrHdr, FileStr[predicate->source->file],

+				predicate->source->line);

+		fprintf(stderr, "     Try using a context guard '(...)? =>'\n");

+		predicate->source->ctxwarned = 1;

+	}

+    verify_context(predicate->right);       /* MR10 */

+}

+

+/*

+ * If delta is the set of ambiguous lookahead sequences, then make sure that

+ * the predicate(s) for productions alt1,alt2 cover the sequences in delta.

+ *

+ * For example,

+ *	a : <<PRED1>>? (A B|A C)

+ *	  | b

+ *    ;

+ *	b : <<PRED2>>? A B

+ *	  | A C

+ *	  ;

+ *

+ * This should give a warning that (A C) predicts both productions and alt2

+ * does not have a predicate in the production that generates (A C).

+ *

+ * The warning detection is simple.  Let delta = LOOK(alt1) intersection LOOK(alt2).

+ * Now, if ( delta set-difference context(predicates-for-alt1) != empty then

+ * alt1 does not "cover" all ambiguous sequences.

+ *

+ * If ambig is nonempty, then ambig in LL(k) sense -> use tree info; else use fset

+ * info.  Actually, sets are used only if k=1 for this grammar.

+ */

+static void

+#ifdef __USE_PROTOS

+ensure_predicates_cover_ambiguous_lookahead_sequences

+                        ( Junction *alt1, Junction *alt2, char *sub, Tree *ambig )

+#else

+ensure_predicates_cover_ambiguous_lookahead_sequences( alt1, alt2, sub, ambig )

+Junction *alt1;

+Junction *alt2;

+char *sub;

+Tree *ambig;

+#endif

+{

+	if ( !ParseWithPredicates ) return;

+

+	if ( ambig!=NULL )

+	{

+		Tree *non_covered = NULL;

+		if ( alt1->predicate!=NULL )

+			non_covered = tdif(ambig, alt1->predicate, alt1->fset, alt2->fset);

+		if ( (non_covered!=NULL || alt1->predicate==NULL) && WarningLevel>1 )

+		{

+			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+			fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",

+							alt1->altnum, sub);

+			if ( alt1->predicate!=NULL && non_covered!=NULL )

+			{

+				fprintf(stderr, " upon");

+				preorder(non_covered);

+			}

+			else if ( alt1->predicate==NULL )

+			{

+				fprintf(stderr, " upon");

+				preorder(ambig->down);

+			}

+			fprintf(stderr, "\n");

+		}

+		Tfree(non_covered);

+		non_covered = NULL;

+		if ( alt2->predicate!=NULL )

+			non_covered = tdif(ambig, alt2->predicate, alt1->fset, alt2->fset);

+		if ( (non_covered!=NULL || alt2->predicate==NULL) && WarningLevel>1 )

+		{

+			fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line);

+			fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",

+							alt2->altnum, sub);

+			if ( alt2->predicate!=NULL && non_covered!=NULL )

+			{

+				fprintf(stderr, " upon");

+				preorder(non_covered);

+			}

+			else if ( alt2->predicate==NULL )

+			{

+				fprintf(stderr, " upon");

+				preorder(ambig->down);

+			}

+			fprintf(stderr, "\n");

+		}

+		Tfree(non_covered);

+	}

+	else if ( !set_nil(alt1->fset[1]) )

+	{

+		set delta, non_covered;

+		delta = set_and(alt1->fset[1], alt2->fset[1]);

+		non_covered = set_dif(delta, covered_set(alt1->predicate));

+		if ( set_deg(non_covered)>0 && WarningLevel>1 )

+		{

+			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+			fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",

+							alt1->altnum, sub);

+			if ( alt1->predicate!=NULL )

+			{

+				fprintf(stderr, " upon ");

+				s_fprT(stderr, non_covered);

+			}

+			fprintf(stderr, "\n");

+		}

+		set_free( non_covered );

+		non_covered = set_dif(delta, covered_set(alt2->predicate));

+		if ( set_deg(non_covered)>0 && WarningLevel>1 )

+		{

+			fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line);

+			fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",

+							alt2->altnum, sub);

+			if ( alt2->predicate!=NULL )

+			{

+				fprintf(stderr, " upon ");

+				s_fprT(stderr, non_covered);

+			}

+			fprintf(stderr, "\n");

+		}

+		set_free( non_covered );

+		set_free( delta );

+	}

+	else fatal_internal("productions have no lookahead in predicate checking routine");

+}

+

+#ifdef __USE_PROTOS

+void MR_doPredicatesHelp(int inGuessBlock,Junction *alt1,Junction *alt2,int jtype,char *sub)

+#else

+void MR_doPredicatesHelp(inGuessBlock,alt1,alt2,jtype,sub)

+  int       inGuessBlock;

+  Junction  *alt1;

+  Junction  *alt2;

+  int       jtype;

+  char      *sub;

+#endif

+{

+    Predicate   *p1;

+    Predicate   *p2;

+

+    Junction    *parentRule=MR_nameToRuleBlk(alt1->rname);

+

+    if (inGuessBlock && WarningLevel <= 1) return;

+

+    /* let antlr give the usual error message */

+

+    if (alt1->predicate == NULL && alt2->predicate == NULL) return;

+

+    if ( (jtype == RuleBlk || jtype == aSubBlk)

+             && (alt1->predicate == NULL && alt2->predicate != NULL)) {

+        fprintf(stderr, ErrHdr, FileStr[parentRule->file],parentRule->line);

+        fprintf(stderr," warning: alt %d line %d and alt %d line %d of %s\n%s%s%s",

+          alt1->altnum,

+          alt1->line,

+          alt2->altnum,

+          alt2->line,

+          sub,

+          "     These alts have ambig lookahead sequences resolved by a predicate for\n",

+          "     the second choice. The second choice may not be reachable.\n",

+          "     You may want to use a complementary predicate or rearrange the alts\n"

+        );

+        return;

+    };

+

+    /* first do the easy comparison.  then do the hard one */

+

+    if (MR_comparePredicates(alt1->predicate,alt2->predicate)) {

+

+      if (jtype == aLoopBegin || jtype == aPlusBlk ) {

+

+        /* I'm not sure this code is reachable.

+           Predicates following a (...)+ or (...)* block are probably

+             considered validation predicates and therefore not

+             participate in the predication expression

+        */

+

+      	fprintf(stderr, ErrHdr,FileStr[parentRule->file],parentRule->line);

+        fprintf(stderr," warning: %s of %s in rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s",

+          "the predicates used to disambiguate optional/exit paths of ",

+          sub,

+          CurRule,

+          FileStr[alt1->file],

+          alt1->altnum,

+          alt1->line,

+          alt2->altnum,

+          alt2->line,

+          "     are identical and have no resolving power\n");

+      } else {

+    	fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);

+        fprintf(stderr," warning: %s rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s",

+          "the predicates used to disambiguate",

+          CurRule,

+          FileStr[alt1->file],

+          alt1->altnum,

+          alt1->line,

+          alt2->altnum,

+          alt2->line,

+          "     are identical and have no resolving power\n");

+      };

+    } else {

+      p1=predicate_dup_without_context(alt1->predicate);

+      p1=MR_unfold(p1);

+      MR_clearPredEntry(p1);

+      MR_simplifyInverted(p1,0);

+      p1=MR_predSimplifyALL(p1);

+      p2=predicate_dup_without_context(alt2->predicate);

+      p2=MR_unfold(p2);

+      MR_clearPredEntry(p2);

+      MR_simplifyInverted(p2,0);

+      p2=MR_predSimplifyALL(p2);

+      if (MR_comparePredicates(p1,p2)) {

+        if (jtype == aLoopBegin || jtype == aPlusBlk ) {

+          fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);

+          fprintf(stderr," warning: %s of %s in rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s%s",

+            "the predicates used to disambiguate optional/exit paths of ",

+            sub,

+            CurRule,

+            FileStr[alt1->file],

+            alt1->altnum,

+            alt1->line,

+            alt2->altnum,

+            alt2->line,

+            "     are identical when compared without context and may have no\n",

+            "     resolving power for some lookahead sequences.\n");

+        } else {

+          fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);

+          fprintf(stderr," warning: %s rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s%s",

+            "the predicates used to disambiguate",

+            CurRule,

+            FileStr[alt1->file],

+            alt1->altnum,

+            alt1->line,

+            alt2->altnum,

+            alt2->line,

+            "     are identical when compared without context and may have no\n",

+            "     resolving power for some lookahead sequences.\n");

+        };

+        if (InfoP) {

+          fprintf(output,"\n#if 0\n\n");

+          fprintf(output,"The following predicates are identical when compared without\n");

+          fprintf(output,"  lookahead context information.  For some ambiguous lookahead\n");

+          fprintf(output,"  sequences they may not have any power to resolve the ambiguity.\n");

+          fprintf(output,"\n");

+

+          fprintf(output,"Choice 1: %s  alt %d  line %d  file %s\n\n",

+                  MR_ruleNamePlusOffset( (Node *) alt1),

+                  alt1->altnum,

+                  alt1->line,

+                  FileStr[alt1->file]);

+          fprintf(output,"  The original predicate for choice 1 with available context information:\n\n");

+          MR_dumpPred1(2,alt1->predicate,1);

+          fprintf(output,"  The predicate for choice 1 after expansion (but without context information):\n\n");

+          MR_dumpPred1(2,p1,0);

+          if (p1 == NULL) {

+            Predicate   *phelp;

+            fprintf(output,"  The predicate for choice 1 after expansion (but before simplification)\n\n");

+            phelp=predicate_dup_without_context(alt1->predicate);

+            phelp=MR_unfold(phelp);

+            MR_clearPredEntry(phelp);

+            MR_simplifyInverted(phelp,0);

+            phelp=MR_predSimplifyALLX(phelp,1);

+            MR_dumpPred1(2,phelp,0);

+            predicate_free(phelp);

+          };

+          fprintf(output,"\n");

+

+          fprintf(output,"Choice 2: %s  alt %d  line %d  file %s\n\n",

+                  MR_ruleNamePlusOffset( (Node *) alt2),

+                  alt2->altnum,

+                  alt2->line,

+                  FileStr[alt2->file]);

+          fprintf(output,"  The original predicate for choice 2 with available context information:\n\n");

+          MR_dumpPred1(1,alt2->predicate,1);

+          fprintf(output,"  The predicate for choice 2 after expansion (but without context information):\n\n");

+          MR_dumpPred1(1,p2,0);

+          if (p2 == NULL) {

+            Predicate   *phelp;

+            fprintf(output,"  The predicate for choice 2 after expansion (but before simplification)\n\n");

+            phelp=predicate_dup_without_context(alt2->predicate);

+            phelp=MR_unfold(phelp);

+            MR_clearPredEntry(phelp);

+            MR_simplifyInverted(phelp,0);

+            phelp=MR_predSimplifyALLX(phelp,1);

+            MR_dumpPred1(2,phelp,0);

+            predicate_free(phelp);

+          };

+          fprintf(output,"\n#endif\n");

+        };

+      } else if (MR_secondPredicateUnreachable(p1,p2)) {

+        if (jtype == aLoopBegin || jtype == aPlusBlk ) {

+          fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);

+          fprintf(stderr," warning: %s of %s in rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s%s",

+            "the predicate used to disambiguate the first choice of the optional/exit paths of ",

+            sub,

+            CurRule,

+            FileStr[alt1->file],

+            alt1->altnum,

+            alt1->line,

+            alt2->altnum,

+            alt2->line,

+            "     appears to \"cover\" the second predicate when compared without context.\n",

+            "     The second predicate may have no resolving power for some lookahead sequences.\n");

+        } else {

+          fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);

+          fprintf(stderr," warning: %s rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s%s",

+            "the predicate used to disambiguate the first choice of",

+            CurRule,

+            FileStr[alt1->file],

+            alt1->altnum,

+            alt1->line,

+            alt2->altnum,

+            alt2->line,

+            "     appears to \"cover\" the second predicate when compared without context.\n",

+            "     The second predicate may have no resolving power for some lookahead sequences.\n");

+        };

+        if (InfoP) {

+          fprintf(output,"\n#if 0\n\n");

+          fprintf(output,"The first predicate appears to \"cover\" the second predicate when they\n");

+          fprintf(output,"  are compared without lookahead context information.  For some ambiguous\n");

+          fprintf(output,"  lookahead sequences the second predicate may not have any power to\n");

+          fprintf(output,"  resolve the ambiguity.\n");

+          fprintf(output,"\n");

+          fprintf(output,"Choice 1: %s  alt %d  line %d  file %s\n\n",

+                  MR_ruleNamePlusOffset( (Node *) alt1),

+                  alt1->altnum,

+                  alt1->line,

+                  FileStr[alt1->file]);

+          fprintf(output,"  The original predicate for choice 1 with available context information:\n\n");

+          MR_dumpPred1(2,alt1->predicate,1);

+          fprintf(output,"  The predicate for choice 1 after expansion (but without context information):\n\n");

+          MR_dumpPred1(2,p1,0);

+          if (p1 == NULL) {

+            Predicate   *phelp;

+            fprintf(output,"  The predicate for choice 1 after expansion (but before simplification)\n\n");

+            phelp=predicate_dup_without_context(alt1->predicate);

+            phelp=MR_unfold(phelp);

+            MR_clearPredEntry(phelp);

+            MR_simplifyInverted(phelp,0);

+            phelp=MR_predSimplifyALLX(phelp,1);

+            MR_dumpPred1(2,phelp,0);

+            predicate_free(phelp);

+          };

+          fprintf(output,"\n");

+

+          fprintf(output,"Choice 2: %s  alt %d  line %d  file %s\n\n",

+                  MR_ruleNamePlusOffset( (Node *) alt2),

+                  alt2->altnum,

+                  alt2->line,

+                  FileStr[alt2->file]);

+          fprintf(output,"  The original predicate for choice 2 with available context information:\n\n");

+          MR_dumpPred1(1,alt2->predicate,1);

+          fprintf(output,"  The predicate for choice 2 after expansion (but without context information):\n\n");

+          MR_dumpPred1(1,p2,0);

+          if (p2 == NULL) {

+            Predicate   *phelp;

+            fprintf(output,"  The predicate for choice 2 after expansion (but before simplification)\n\n");

+            phelp=predicate_dup_without_context(alt2->predicate);

+            phelp=MR_unfold(phelp);

+            MR_clearPredEntry(phelp);

+            MR_simplifyInverted(phelp,0);

+            phelp=MR_predSimplifyALLX(phelp,1);

+            MR_dumpPred1(2,phelp,0);

+            predicate_free(phelp);

+          };

+          fprintf(output,"\n#endif\n");

+        };

+      };

+      predicate_free(p1);

+      predicate_free(p2);

+    };

+}

+

+static  int     totalOverflow=0;                /* MR9 */

+

+void

+#ifdef __USE_PROTOS

+HandleAmbiguity( Junction *block, Junction *alt1, Junction *alt2, int jtype )

+#else

+HandleAmbiguity( block, alt1, alt2, jtype )

+Junction *block;

+Junction *alt1;

+Junction *alt2;

+int jtype;

+#endif

+{

+	unsigned **ftbl;

+	set *fset, b;

+	int i, numAmbig,n2;

+	Tree *ambig=NULL, *t, *u;

+	char *sub = "";

+    long    n;

+    int     thisOverflow=0;             /* MR9 */

+    long    set_deg_value;              /* MR10 */

+    long    threshhold;                 /* MR10 */

+

+	require(block!=NULL, "NULL block");

+	require(block->ntype==nJunction, "invalid block");

+

+	/* These sets are used to constrain LL_k set, but are made CLL_k long anyway */

+	fset = (set *) calloc(CLL_k+1, sizeof(set));

+	require(fset!=NULL, "cannot allocate fset");

+	ftbl = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));

+	require(ftbl!=NULL, "cannot allocate ftbl");

+

+	/* create constraint table and count number of possible ambiguities (use<=LL_k) */

+	for (n=1,i=1; i<=CLL_k; i++)

+	{

+         		b = set_and(alt1->fset[i], alt2->fset[i]);

+/* MR9 */       set_deg_value = set_deg(b);

+/* MR10 */      if (n > 0) {

+/* MR10 */        threshhold = LONG_MAX / n;

+/* MR10 */        if (set_deg_value <= threshhold) {

+/* MR10 */       	n *= set_deg_value;

+/* MR10 */        } else {

+/* MR10 */          n=LONG_MAX;

+/* MR9 */           if (totalOverflow == 0) {

+#if 0

+                      /* MR10 comment this out because it just makes users worry */

+

+/* MR9 */             warnNoFL("Overflow in computing number of possible ambiguities in HandleAmbiguity\n");

+#endif

+/* MR9 */           };

+/* MR9 */           thisOverflow++;

+/* MR9 */           totalOverflow++;

+/* MR9 */         };

+/* MR10 */      } else {

+/* MR10 */        n *= set_deg_value;

+/* MR9 */       };

+		fset[i] = set_dup(b);

+		ftbl[i] = set_pdq(b);

+		set_free(b);

+	}

+

+	switch ( jtype )

+	{

+		case aSubBlk: sub = "of (..) "; break;

+		case aOptBlk: sub = "of {..} "; break;

+		case aLoopBegin: sub = "of (..)* "; break;

+		case aLoopBlk: sub = "of (..)* "; break;

+		case aPlusBlk: sub = "of (..)+ "; break;

+		case RuleBlk: sub = "of the rule itself "; break;

+		default : sub = ""; break;

+	}

+

+	/* If the block is marked as a compressed lookahead only block, then

+	 * simply return; ambiguity warning is given only at warning level 2.

+	 */

+	if ( block->approx>0 )

+	{

+		if ( ParseWithPredicates )

+		{

+            if (alt1->predicate != NULL) predicate_free(alt1->predicate);  /* MR12 */

+            if (alt2->predicate != NULL) predicate_free(alt2->predicate);  /* MR12 */

+

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+          	alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+            require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");

+            alt1->predicate=MR_predSimplifyALL(alt1->predicate);

+

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+    		alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+            require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");

+            alt2->predicate=MR_predSimplifyALL(alt2->predicate);

+

+            MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);

+

+			if ( HoistPredicateContext

+                    && (alt1->predicate!=NULL||alt2->predicate!=NULL) )

+			{

+				verify_context(alt1->predicate);

+				verify_context(alt2->predicate);

+			}

+

+			if ( HoistPredicateContext

+                     && (alt1->predicate!=NULL||alt2->predicate!=NULL)

+                     && WarningLevel>1 )

+			ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);

+		}

+

+		if ( WarningLevel>1 )

+		{

+			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+			if ( jtype == aLoopBegin || jtype == aPlusBlk )

+				fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);

+			else

+				fprintf(stderr, " warning(approx): alts %d and %d %sambiguous upon",

+						alt1->altnum, alt2->altnum, sub);

+			dumpAmbigMsg(fset, stderr, 0);

+            MR_traceAmbSource(fset,alt1,alt2);

+		}

+		for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+		free((char *)fset);

+		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+		free((char *)ftbl);

+		return;

+    }

+

+	/* if all sets have degree 1 for k<LL_k, then must be ambig upon >=1 permutation;

+	 * don't bother doing full LL(k) analysis.

+	 * (This "if" block handles the LL(1) case)

+	 */

+

+	n2 = 0;

+	for (i=1; i<LL_k; i++) n2 += set_deg(alt1->fset[i])+set_deg(alt2->fset[i]);

+

+    /* here STARTS the special case in which the lookahead sets for alt1 and alt2

+       all have degree 1 for k<LL_k (including LL_k=1)

+    */

+

+	if ( n2==2*(LL_k-1) )

+	{

+

+        /* TJP: added to fix the case where LL(1) and syntactic predicates didn't

+         * work.  It now recognizes syntactic predicates, but does not like combo:

+         * LL(1)/syn/sem predicates. (10/24/93)

+         */

+

+		if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL )

+		{

+			if ( WarningLevel==1 )

+			{

+				for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+				free((char *)fset);

+				for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+				free((char *)ftbl);

+				return;

+			}

+

+			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+			if ( jtype == aLoopBegin || jtype == aPlusBlk )

+			   fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);

+			else

+			   fprintf(stderr, " warning: alts %d and %d %sambiguous upon",

+					   alt1->altnum, alt2->altnum, sub);

+			dumpAmbigMsg(fset, stderr, 0);

+            MR_traceAmbSource(fset,alt1,alt2);

+		}

+

+		ambig = NULL;

+		if ( LL_k>1 ) ambig = make_tree_from_sets(alt1->fset, alt2->fset);

+		if ( ParseWithPredicates )

+		{

+           if (alt1->predicate != NULL) predicate_free(alt1->predicate);  /* MR12 */

+           if (alt2->predicate != NULL) predicate_free(alt2->predicate);  /* MR12 */

+

+           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+           alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);

+           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+           require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");

+           alt1->predicate=MR_predSimplifyALL(alt1->predicate);

+

+           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+    	   alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);

+           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+           require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");

+           alt2->predicate=MR_predSimplifyALL(alt2->predicate);

+

+           MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);

+

+		   if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )

+		   {

+				verify_context(alt1->predicate);

+				verify_context(alt2->predicate);

+		   }

+		   if (HoistPredicateContext&&(alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1)

+			  ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);

+		   if ( WarningLevel == 1 &&

+			   (alt1->predicate!=NULL||alt2->predicate!=NULL))

+		   {

+			  for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+			  free((char *)fset);

+			  for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+			  free((char *)ftbl);

+			  Tfree(ambig);

+			  return;

+		   }

+		}

+/* end TJP (10/24/93) */

+

+		fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+		if ( jtype == aLoopBegin || jtype == aPlusBlk )

+			fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);

+		else

+		   fprintf(stderr, " warning: alts %d and %d %sambiguous upon",

+				   alt1->altnum, alt2->altnum, sub);

+		if ( elevel == 3 && LL_k>1 )

+		{

+		   preorder(ambig);

+		   fprintf(stderr, "\n");

+  	       for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+    	   free((char *)fset);

+		   for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+		   free((char *)ftbl);

+		   Tfree(ambig);

+		   return;

+        };

+

+		Tfree(ambig);

+		dumpAmbigMsg(fset, stderr, 0);

+

+        /* because this is a special case in which both alt1 and alt2 have

+           lookahead sets of degree 1 for k<LL_k (including k=1) the linear

+           lookahead style search is adequate

+        */

+

+        MR_traceAmbSource(fset,alt1,alt2);

+

+		for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+		free((char *)fset);

+		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+		free((char *)ftbl);

+		return;

+	}

+

+    /* here ENDS the special case in which the lookahead sets for alt1 and alt2

+       all have degree 1 for k<LL_k (including LL_k=1)

+    */

+

+	/* in case tree construction runs out of memory, set info to make good err msg */

+

+	CurAmbigAlt1 = alt1->altnum;

+	CurAmbigAlt2 = alt2->altnum;

+	CurAmbigbtype = sub;

+	CurAmbigfile = alt1->file;

+	CurAmbigline = alt1->line;

+	

+	/* Don't do full LL(n) analysis if (...)? block because the block,

+	   by definition, defies LL(n) analysis.

+	   If guess (...)? block and ambiguous then don't remove anything from

+	   2nd alt to resolve ambig.

+	   Want to predict with LL sup 1 ( n ) decision not LL(n) if guess block

+	   since it is much cheaper than LL(n).  LL sup 1 ( n ) "covers" the LL(n)

+	   lookahead information.

+

+	   Note: LL(n) context cannot be computed for semantic predicates when

+	   followed by (..)?.

+

+	   If (..)? then we scream "AAAHHHH!  No LL(n) analysis will help"

+

+       Is 'ambig' always defined if we enter this if?  I hope so

+	   because the 'ensure...()' func references it. TJP Nov 1993.

+	   */

+

+	/* THM MR30:  Instead of using first_item_is_guss_block we use

+	   first_item_is_guess_block_extra which will look inside a

+	   loop block for a guess block.  In other words ( (...)? )*.

+	   It there is an ambiguity in this circumstance then we suppress

+	   the normal methods of resolving ambiguities.

+	*/

+

+	if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL )

+	{

+		if ( ParseWithPredicates )

+		{

+            if (alt1->predicate != NULL) predicate_free(alt1->predicate);  /* MR12 */

+            if (alt2->predicate != NULL) predicate_free(alt2->predicate);  /* MR12 */

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+        	alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+            require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");

+            alt1->predicate=MR_predSimplifyALL(alt1->predicate);

+

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+    		alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+            require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");

+            alt2->predicate=MR_predSimplifyALL(alt2->predicate);

+

+            MR_doPredicatesHelp(1,alt1,alt2,jtype,sub);

+

+			if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )

+			{

+				verify_context(alt1->predicate);

+				verify_context(alt2->predicate);

+			}

+			if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 )

+				ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);

+			if ( WarningLevel==1 &&

+				(alt1->predicate!=NULL||alt2->predicate!=NULL))

+			{

+				for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+				free((char *)fset);

+				for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+				free((char *)ftbl);

+				return;

+			}

+		}

+

+		if ( WarningLevel>1 )

+		{

+			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+			if ( jtype == aLoopBegin || jtype == aPlusBlk )

+				fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);

+			else

+				fprintf(stderr, " warning: alts %d and %d %sambiguous upon",

+						alt1->altnum, alt2->altnum, sub);

+			dumpAmbigMsg(fset, stderr, 0);

+            MR_traceAmbSource(fset,alt1,alt2);

+		}

+

+		for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+		free((char *)fset);

+		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+		free((char *)ftbl);

+		return;

+	}

+	

+	/* Not resolved with (..)? block.  Do full LL(n) analysis */

+	

+	/* ambig is the set of k-tuples truly in common between alt 1 and alt 2 */

+    /* MR11 VerifyAmbig once used fset destructively */

+

+	ambig = VerifyAmbig(alt1, alt2, ftbl, fset, &t, &u, &numAmbig);

+

+	/* are all things in intersection really ambigs? */

+

+	if (thisOverflow ||  numAmbig < n )                     /* MR9 */

+	{

+		Tree *v;

+

+		/* remove ambig permutation from 2nd alternative to resolve ambig;

+		 * We want to compute the set of artificial tuples, arising from

+		 * LL sup 1 (n) compression, that collide with real tuples from the

+		 * 2nd alternative.  This is the set of "special case" tuples that

+		 * the LL sup 1 (n) decision template maps incorrectly.

+		 */

+

+        /* when generating code in genExpr() it does

+         *

+         *      if ( genExprSets(j->fset) && !genExprTree(j->ftree)) {...

+         *

+         * Sooooo the j->ftree is the tree of alt2

+         *               after removal of conflicts, not alt1 !

+         */

+

+		if ( ambig!=NULL )

+		{

+            /* at the top of ambig is an ALT node */

+

+			for (v=ambig->down; v!=NULL; v=v->right)

+			{

+				u = trm_perm(u, v);     /* remove v FROM u */

+			}

+/*			fprintf(stderr, "after rm alt2:"); preorder(u); fprintf(stderr, "\n");*/

+		}

+		Tfree( t );

+		alt1->ftree = tappend(alt1->ftree, u);

+		alt1->ftree = tleft_factor(alt1->ftree);

+	}

+

+	if ( ambig==NULL )

+	{

+		for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+		free((char *)fset);

+		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+		free((char *)ftbl);

+		return;

+	}

+

+	ambig = tleft_factor(ambig);

+

+/* TJP:

+ * At this point, we surely have an LL(k) ambiguity.  Check for predicates

+ */

+	if ( ParseWithPredicates )

+	{

+        if (alt1->predicate != NULL) predicate_free(alt1->predicate);  /* MR12 */

+        if (alt2->predicate != NULL) predicate_free(alt2->predicate);  /* MR12 */

+        require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+    	alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);

+        require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+        require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");

+        alt1->predicate=MR_predSimplifyALL(alt1->predicate);

+

+        require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+		alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);

+        require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+        require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");

+        alt2->predicate=MR_predSimplifyALL(alt2->predicate);

+

+        MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);

+

+		if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )

+		{

+			verify_context(alt1->predicate);

+			verify_context(alt2->predicate);

+		}

+		if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 )

+		   ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);

+		if ( WarningLevel==1 &&

+ 			(alt1->predicate!=NULL||alt2->predicate!=NULL))

+		{

+

+			/* We found at least one pred for at least one of the alts;

+			 * If warnings are low, just return.

+			 */

+

+			Tfree(ambig);

+            for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+    	    free((char *)fset);

+    		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+    		free((char *)ftbl);

+			return;

+		}

+		/* else we're gonna give a warning */

+	}

+/* end TJP addition */

+

+	fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);

+	if ( jtype == aLoopBegin || jtype == aPlusBlk )

+		fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);

+	else

+		fprintf(stderr, " warning: alts %d and %d %sambiguous upon",

+					alt1->altnum, alt2->altnum, sub);

+	if ( elevel == 3 )

+	{

+		preorder(ambig->down);      /* <===== k>1 ambiguity message data */

+		fprintf(stderr, "\n");

+	} else {

+        MR_skipped_e3_report=1;

+    	dumpAmbigMsg(fset, stderr, 0);

+    };

+

+    MR_traceAmbSourceK(ambig,alt1,alt2);     /* <====== k>1 ambiguity aid */

+

+	Tfree(ambig);

+

+    for (i=1; i<=CLL_k; i++) set_free( fset[i] );

+	free((char *)fset);

+	for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );

+	free((char *)ftbl);

+}

+

+/* Don't analyze alpha block of (alpha)?beta; if (alpha)? then analyze

+ * Return the 1st node of the beta block if present else return j.

+ */

+Junction *

+#ifdef __USE_PROTOS

+analysis_point( Junction *j )

+#else

+analysis_point( j )

+Junction *j;

+#endif

+{

+	Junction *gblock;

+

+    /* MR13b  When there was an action/predicate preceding a guess block

+              the guess block became invisible at the analysis_point.

+

+              first_item_is_guess_block accepts any kind of node,

+              despite the fact that the formal is a junction.  But

+              I don't want to have to change it all over the place

+              until I know it works.

+    */

+

+	if ( j->ntype != nJunction && j->ntype != nAction) return j;

+

+	gblock = first_item_is_guess_block((Junction *)j);

+

+	if ( gblock!=NULL )

+	{

+		Junction *past = gblock->end;

+		Junction *p;

+		require(past!=NULL, "analysis_point: no end block on (...)? block");

+

+		for (p=(Junction *)past->p1; p!=NULL; )

+		{

+			if ( p->ntype==nAction )

+			{

+				p=(Junction *)((ActionNode *)p)->next;

+				continue;

+			}

+			if ( p->ntype!=nJunction )

+			{

+                past->alpha_beta_guess_end=1;           /* MR14 */

+				return (Junction *)past->p1;

+			}

+			if ( p->jtype==EndBlk || p->jtype==EndRule )

+			{

+				return j;

+			}

+/* MR6                                									      */

+/* MR6	A guess block is of the form "(alpha)? beta" or "(alpha)?".           */

+/* MR6  When beta is omitted (second form) this means "(alpha)? alpha".       */

+/* MR6  The program does not store another copy of alpha in this case.        */

+/* MR6  During analysis when the program needs to know what follows the       */

+/* MR6    guess clause.  It calls this routine.                               */

+/* MR6                                                                        */

+/* MR6      If it is of the form "(alpha)? beta" it returns a pointer to beta.*/

+/* MR6                                                                        */

+/* MR6      If it is of the form "(alpha)?" it returns a pointer to the guess */

+/* MR6        block itself thereby reusing the junction tree.                 */

+/* MR6                                                                        */

+/* MR6  It works by searching the "next in sequence" chain (skipping actions) */

+/* MR6    searching for a RuleRef or Token node.  (Those are the only 4 kinds */

+/* MR6    of nodes: Junctions, RuleRef, Token, and Action.)                   */

+/* MR6                                                                        */

+/* MR6  This won't work for the special case "(alpha)? ()" because it has no  */

+/* MR6    rule references or token nodes.  It eventually encounters a         */

+/* MR6	  junction of type EndBlk or EndRule and says to its caller: nothing  */

+/* MR6    more here to analyze - must be of the form "(alpha)?".              */

+/* MR6                                                                        */

+/* MR6  In the case of "(alpha)? ()" it should return a pointer to "()"       */

+/* MR6                                                                        */

+/* MR6  I think.                                                              */

+/* MR6                                                                        */

+			if ( p->jtype!=Generic) {		                           /* MR6 */

+                past->alpha_beta_guess_end=1;                          /* MR14 */

+				return (Junction *)past->p1;                           /* MR6 */

+			};					                                       /* MR6 */

+   			p=(Junction *)p->p1;

+		}

+	}

+	return j;

+}

+

+set

+#ifdef __USE_PROTOS

+First( Junction *j, int k, int jtype, int *max_k )

+#else

+First( j, k, jtype, max_k )

+Junction *j;

+int k;

+int jtype;

+int *max_k;

+#endif

+{

+	Junction *alt1, *alt2;

+	set a, rk, fCurBlk;

+	int savek;

+	int p1, p2;

+

+    int     save_maintainBackTrace;

+

+	require(j->ntype==nJunction, "First: non junction passed");

+

+	/* C o m p u t e  F I R S T  s e t  w i t h  k  l o o k a h e a d */

+	fCurBlk = rk = empty;

+	for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2 )

+	{

+		Junction * p = NULL;

+		Junction * p1junction = NULL;

+		p = analysis_point((Junction *)alt1->p1);

+		p1junction = (Junction *) (alt1->p1);

+#if 0

+		if (p != p1junction) {

+			fprintf(stdout,"Analysis point for #%d is #%d", p1junction->seq, p->seq); /* debug */

+		}

+#endif

+		REACH(p, k, &rk, alt1->fset[k]);

+		require(set_nil(rk), "rk != nil");

+		set_free(rk);

+		set_orin(&fCurBlk, alt1->fset[k]);

+	}

+

+	/* D e t e c t  A m b i g u i t i e s */

+	*max_k = 1;

+	for (p1=1,alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2, p1++)

+	{

+		for (p2=1,alt2=(Junction *)alt1->p2; alt2!=NULL; alt2 = (Junction *)alt2->p2, p2++)

+		{

+			savek = k;

+			a = set_and(alt1->fset[k], alt2->fset[k]);

+			while ( !set_nil(a) )

+			{

+				/* if we have hit the max k requested, just give warning */

+				if ( j->approx==k ) {

+				}

+

+				if ( k==CLL_k )

+				{

+#ifdef NOT_USED

+***					int save_LL_k = LL_k;

+***					int save_CLL_k = CLL_k;

+***					/* Get new LL_k from interactive feature if enabled */

+***					if ( AImode )

+***						AmbiguityDialog(j, jtype, alt1, alt2, &CLL_k, &LL_k);

+#endif

+					*max_k = CLL_k;

+                    save_maintainBackTrace=MR_MaintainBackTrace;

+                    if (AlphaBetaTrace) MR_MaintainBackTrace=0;

+					HandleAmbiguity(j, alt1, alt2, jtype);

+                    MR_MaintainBackTrace=save_maintainBackTrace;

+					break;

+				}

+				else

+				{

+					Junction *p = analysis_point((Junction *)alt1->p1);

+					Junction *q = analysis_point((Junction *)alt2->p1);

+					k++;	/* attempt ambig alts again with more lookahead */

+

+					REACH(p, k, &rk, alt1->fset[k]);

+					require(set_nil(rk), "rk != nil");

+					REACH(q, k, &rk, alt2->fset[k]);

+					require(set_nil(rk), "rk != nil");

+					set_free(a);

+					a = set_and(alt1->fset[k], alt2->fset[k]);

+					if ( k > *max_k ) *max_k = k;

+				}

+			}

+			set_free(a);

+			k = savek;

+		}

+	}

+

+	return fCurBlk;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/fset2.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/fset2.c
new file mode 100644
index 0000000..7f686a5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/fset2.c
@@ -0,0 +1,2250 @@
+/*

+ * fset2.c

+ *

+ * Compute FIRST sets for full LL(k)

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "pcctscfg.h"

+#include <stdlib.h>

+

+#ifdef PCCTS_USE_STDARG

+#include <stdarg.h>

+#else

+#include <varargs.h>

+#endif

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+

+/* ick! globals.  Used by permute() to track which elements of a set have been used */

+

+static int *findex;

+set *fset;              /* MR11 make global */

+static unsigned **ftbl;

+static set *constrain; /* pts into fset. constrains tToken() to 'constrain' */

+int ConstrainSearch;

+int maxk;               /* set to initial k upon tree construction request */

+                        /* MR11 make global */

+static Tree *FreeList = NULL;

+

+#ifdef __USE_PROTOS

+static int tmember_of_context(Tree *, Predicate *);

+#else

+static int tmember_of_context();

+#endif

+

+#if TREE_DEBUG

+set     set_of_tnodes_in_use;

+int     stop_on_tnode_seq_number=(-1);     /* (-1) to disable */

+#endif

+

+/* Do root

+ * Then each sibling

+ */

+

+void

+#ifdef __USE_PROTOS

+preorder( Tree *tree )

+#else

+preorder( tree )

+Tree *tree;

+#endif

+{

+	if ( tree == NULL ) return;

+	if ( tree->down != NULL ) fprintf(stderr, " (");

+	if ( tree->token == ALT ) fprintf(stderr, " ALT");

+	else fprintf(stderr, " %s", TerminalString(tree->token));

+	if ( tree->token==EpToken ) fprintf(stderr, "(%d)", tree->v.rk);

+	preorder(tree->down);

+	if ( tree->down != NULL ) fprintf(stderr, " )");

+	preorder(tree->right);

+}

+

+#ifdef __USE_PROTOS

+int MR_tree_matches_constraints(int k,set * constrain,Tree *t)

+#else

+int MR_tree_matches_constraints(k,constrain,t)

+  int       k;

+  set *     constrain;

+  Tree *    t;

+#endif

+{

+  int       i;

+  Tree      *u;

+

+  if (k == 0) return 1;

+

+  /* for testing guard predicates: if the guard tree is shorter

+     than the constraint then it is a match.  The reason is that

+     a guard of (A B) should be equivalent to a guard of (A B . . .)

+     where "." matches every token.  Thus a match which runs out

+     of tree before constraint is a match.

+  */

+

+  if (t == NULL) return 1;

+  require (set_deg(constrain[0]) == 1,

+            "MR_tree_matches_constraints: set_deg != 1");

+  i=set_int(constrain[0]);

+  if (t->token != i) return 0;

+  if (k-1 == 0) return 1;

+  for (u=t->down; u != NULL; u=u->right) {

+    if (MR_tree_matches_constraints(k-1,&constrain[1],u)) {

+       return 1;

+    };

+  };

+  return 0;

+}

+

+/* check the depth of each primary sibling to see that it is exactly

+ * k deep. e.g.;

+ *

+ *	ALT

+ *   |

+ *   A ------- B

+ *   |         |

+ *   C -- D    E

+ *

+ * Remove all branches <= k deep.

+ *

+ * Added by TJP 9-23-92 to make the LL(k) constraint mechanism to work.

+ */

+

+static int pruneCount=0;

+static int prunePeak=200;

+

+Tree *

+#ifdef __USE_PROTOS

+prune( Tree *t, int k )

+#else

+prune( t, k )

+Tree *t;

+int k;

+#endif

+{

+    pruneCount++;

+    if (pruneCount > prunePeak+100) {

+      prunePeak=pruneCount;

+#if 0

+***   fprintf(stderr,"pruneCount=%d\n",pruneCount);

+/***  preorder(t);   ***/

+***   fprintf(stderr,"\n",pruneCount);

+#endif

+    };

+    if ( t == NULL ) {

+        pruneCount--;

+        return NULL;

+    };

+    if ( t->token == ALT ) fatal_internal("prune: ALT node in FIRST tree");

+    if ( t->right!=NULL ) t->right = prune(t->right, k);

+    if ( k>1 )

+	{

+		if ( t->down!=NULL ) t->down = prune(t->down, k-1);

+		if ( t->down == NULL )

+		{

+			Tree *r = t->right;

+			t->right = NULL;

+			Tfree(t);

+            pruneCount--;

+			return r;

+		}

+	}

+    pruneCount--;

+    return t;

+}

+

+/* build a tree (root child1 child2 ... NULL) */

+#ifdef PCCTS_USE_STDARG

+Tree *tmake(Tree *root, ...)

+#else

+Tree *tmake(va_alist)

+va_dcl

+#endif

+{

+	Tree *w;

+	va_list ap;

+	Tree *child, *sibling=NULL, *tail=NULL;

+#ifndef PCCTS_USE_STDARG

+	Tree *root;

+#endif

+

+#ifdef PCCTS_USE_STDARG

+	va_start(ap, root);

+#else

+	va_start(ap);

+	root = va_arg(ap, Tree *);

+#endif

+	child = va_arg(ap, Tree *);

+	while ( child != NULL )

+	{

+#ifdef DUM

+		/* added "find end of child" thing TJP March 1994 */

+		for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */

+#else

+		w = child;

+#endif

+

+		if ( sibling == NULL ) {sibling = child; tail = w;}

+		else {tail->right = child; tail = w;}

+		child = va_arg(ap, Tree *);

+	}

+

+	/* was "root->down = sibling;" */

+	if ( root==NULL ) root = sibling;

+	else root->down = sibling;

+

+	va_end(ap);

+	return root;

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tnode( int tok )

+#else

+tnode( tok )

+int tok;

+#endif

+{

+	Tree *p, *newblk;

+	static int n=0;

+	

+	if ( FreeList == NULL )

+	{

+		/*fprintf(stderr, "tnode: %d more nodes\n", TreeBlockAllocSize);*/

+		if ( TreeResourceLimit > 0 )

+		{

+			if ( (n+TreeBlockAllocSize) >= TreeResourceLimit )

+			{

+				fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);

+				fprintf(stderr, " hit analysis resource limit while analyzing alts %d and %d %s\n",

+								CurAmbigAlt1,

+								CurAmbigAlt2,

+								CurAmbigbtype);

+				exit(PCCTS_EXIT_FAILURE);

+			}

+		}

+		newblk = (Tree *)calloc(TreeBlockAllocSize, sizeof(Tree));

+		if ( newblk == NULL )

+		{

+			fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);

+			fprintf(stderr, " out of memory while analyzing alts %d and %d %s\n",

+							CurAmbigAlt1,

+							CurAmbigAlt2,

+							CurAmbigbtype);

+			exit(PCCTS_EXIT_FAILURE);

+		}

+		n += TreeBlockAllocSize;

+		for (p=newblk; p<&(newblk[TreeBlockAllocSize]); p++)

+		{

+			p->right = FreeList;	/* add all new Tree nodes to Free List */

+			FreeList = p;

+		}

+	}

+	p = FreeList;

+	FreeList = FreeList->right;		/* remove a tree node */

+	p->right = NULL;				/* zero out ptrs */

+	p->down = NULL;

+	p->token = tok;

+

+    TnodesAllocated++;                                      /* MR10 */

+    TnodesInUse++;                                          /* MR10 */

+    if (TnodesInUse > TnodesPeak) TnodesPeak=TnodesInUse;   /* MR10 */

+

+#ifdef TREE_DEBUG

+	require(!p->in_use, "tnode: node in use!");

+	p->in_use = 1;

+    p->seq=TnodesAllocated;

+    set_orel( (unsigned) TnodesAllocated,&set_of_tnodes_in_use);

+    if (stop_on_tnode_seq_number == p->seq) {

+      fprintf(stderr,"\n*** just allocated tnode #%d ***\n",

+            stop_on_tnode_seq_number);

+    };

+#endif

+	return p;

+}

+

+static Tree *

+#ifdef __USE_PROTOS

+eofnode( int k )

+#else

+eofnode( k )

+int k;

+#endif

+{

+	Tree *t=NULL;

+	int i;

+

+	for (i=1; i<=k; i++)

+	{

+		t = tmake(tnode((TokenInd!=NULL?TokenInd[EofToken]:EofToken)), t, NULL);

+	}

+	return t;

+}

+

+

+

+void

+#ifdef __USE_PROTOS

+_Tfree( Tree *t )

+#else

+_Tfree( t )

+Tree *t;

+#endif

+{

+	if ( t!=NULL )

+	{

+#ifdef TREE_DEBUG

+        if (t->seq == stop_on_tnode_seq_number) {

+           fprintf(stderr,"\n*** just freed tnode #%d ***\n",t->seq);

+        };

+		require(t->in_use, "_Tfree: node not in use!");

+		t->in_use = 0;

+        set_rm( (unsigned) t->seq,set_of_tnodes_in_use);

+#endif

+		t->right = FreeList;

+		FreeList = t;

+        TnodesInUse--;                   /* MR10 */

+	}

+}

+

+/* tree duplicate */

+Tree *

+#ifdef __USE_PROTOS

+tdup( Tree *t )

+#else

+tdup( t )

+Tree *t;

+#endif

+{

+	Tree *u;

+	

+	if ( t == NULL ) return NULL;

+	u = tnode(t->token);

+	u->v.rk = t->v.rk;

+	u->right = tdup(t->right);

+	u->down = tdup(t->down);

+	return u;

+}

+

+/* tree duplicate (assume tree is a chain downwards) */

+Tree *

+#ifdef __USE_PROTOS

+tdup_chain( Tree *t )

+#else

+tdup_chain( t )

+Tree *t;

+#endif

+{

+	Tree *u;

+	

+	if ( t == NULL ) return NULL;

+	u = tnode(t->token);

+	u->v.rk = t->v.rk;

+	u->down = tdup(t->down);

+	return u;

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tappend( Tree *t, Tree *u )

+#else

+tappend( t, u )

+Tree *t;

+Tree *u;

+#endif

+{

+	Tree *w;

+

+/*** fprintf(stderr, "tappend(");

+ *** preorder(t); fprintf(stderr, ",");

+ *** preorder(u); fprintf(stderr, " )\n");

+*/

+	if ( t == NULL ) return u;

+	if ( t->token == ALT && t->right == NULL ) return tappend(t->down, u);

+	for (w=t; w->right!=NULL; w=w->right) {;}

+	w->right = u;

+	return t;

+}

+

+/* dealloc all nodes in a tree */

+void

+#ifdef __USE_PROTOS

+Tfree( Tree *t )

+#else

+Tfree( t )

+Tree *t;

+#endif

+{

+	if ( t == NULL ) return;

+	Tfree( t->down );

+	Tfree( t->right );

+	_Tfree( t );

+}

+

+/* find all children (alts) of t that require remaining_k nodes to be LL_k

+ * tokens long.

+ *

+ * t-->o

+ *     |

+ *     a1--a2--...--an		<-- LL(1) tokens

+ *     |   |        |

+ *     b1  b2  ...  bn		<-- LL(2) tokens

+ *     |   |        |

+ *     .   .        .

+ *     .   .        .

+ *     z1  z2  ...  zn		<-- LL(LL_k) tokens

+ *

+ * We look for all [Ep] needing remaining_k nodes and replace with u.

+ * u is not destroyed or actually used by the tree (a copy is made).

+ */

+Tree *

+#ifdef __USE_PROTOS

+tlink( Tree *t, Tree *u, int remaining_k )

+#else

+tlink( t, u, remaining_k )

+Tree *t;

+Tree *u;

+int remaining_k;

+#endif

+{

+	Tree *p;

+	require(remaining_k!=0, "tlink: bad tree");

+

+	if ( t==NULL ) return NULL;

+	/*fprintf(stderr, "tlink: u is:"); preorder(u); fprintf(stderr, "\n");*/

+	if ( t->token == EpToken && t->v.rk == remaining_k )

+	{

+		require(t->down==NULL, "tlink: invalid tree");

+		if ( u == NULL ) {

+/* MR10 */  Tree  *tt=t->right;

+/* MR10 */  _Tfree(t);

+/* MR10 */  return tt;

+        };

+		p = tdup( u );

+		p->right = t->right;

+		_Tfree( t );

+		return p;

+	}

+	t->down = tlink(t->down, u, remaining_k);

+	t->right = tlink(t->right, u, remaining_k);

+	return t;

+}

+

+/* remove as many ALT nodes as possible while still maintaining semantics */

+Tree *

+#ifdef __USE_PROTOS

+tshrink( Tree *t )

+#else

+tshrink( t )

+Tree *t;

+#endif

+{

+	if ( t == NULL ) return NULL;

+	t->down = tshrink( t->down );

+	t->right = tshrink( t->right );

+	if ( t->down == NULL )

+	{

+		if ( t->token == ALT )

+		{

+			Tree *u = t->right;

+			_Tfree(t);

+			return u;			/* remove useless alts */

+		}

+		return t;

+	}

+

+	/* (? (ALT (? ...)) s) ==> (? (? ...) s) where s = sibling, ? = match any */

+	if ( t->token == ALT && t->down->right == NULL)

+	{

+		Tree *u = t->down;

+		u->right = t->right;

+		_Tfree( t );

+		return u;

+	}

+	/* (? (A (ALT t)) s) ==> (? (A t) s) where A is a token; s,t siblings */

+	if ( t->token != ALT && t->down->token == ALT && t->down->right == NULL )

+	{

+		Tree *u = t->down->down;

+		_Tfree( t->down );

+		t->down = u;

+		return t;

+	}

+	return t;

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tflatten( Tree *t )

+#else

+tflatten( t )

+Tree *t;

+#endif

+{

+	if ( t == NULL ) return NULL;

+	t->down = tflatten( t->down );

+	t->right = tflatten( t->right );

+	if ( t->down == NULL ) return t;

+	

+	if ( t->token == ALT )

+	{

+		Tree *u;

+		/* find tail of children */

+		for (u=t->down; u->right!=NULL; u=u->right) {;}

+		u->right = t->right;

+		u = t->down;

+		_Tfree( t );

+		return u;

+	}

+	return t;

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tJunc( Junction *p, int k, set *rk )

+#else

+tJunc( p, k, rk )

+Junction *p;

+int k;

+set *rk;

+#endif

+{

+	Tree *t=NULL, *u=NULL;

+	Junction *alt;

+	Tree *tail=NULL, *r;

+

+#ifdef DBG_TRAV

+	fprintf(stderr, "tJunc(%d): %s in rule %s\n", k,

+			decodeJType[p->jtype], ((Junction *)p)->rname);

+#endif

+

+/* MR14 */    if (AlphaBetaTrace && p->alpha_beta_guess_end) {

+/* MR14 */         warnFL(

+/* MR14 */           "not possible to compute follow set for alpha in an \"(alpha)? beta\" block.  ",

+/* MR14 */                 FileStr[p->file],p->line);

+/* MR14 */         MR_alphaBetaTraceReport();

+/* MR14 */    };

+

+/* MR14 */    if (p->alpha_beta_guess_end) {

+/* MR14 */      return NULL;

+/* MR14 */    }

+

+	if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||

+		 p->jtype==aPlusBlk || p->jtype==aSubBlk || p->jtype==aOptBlk )

+	{

+		if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) {

+			require(p->lock!=NULL, "rJunc: lock array is NULL");

+			if ( p->lock[k] ) return NULL;

+			p->lock[k] = TRUE;

+		}

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR10 */    };

+

+		TRAV(p->p1, k, rk, tail);

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);

+/* MR10 */    };

+

+		if ( p->jtype==RuleBlk ) {p->lock[k] = FALSE; return tail;}

+		r = tmake(tnode(ALT), tail, NULL);

+		for (alt=(Junction *)p->p2; alt!=NULL; alt = (Junction *)alt->p2)

+		{

+			/* if this is one of the added optional alts for (...)+ then break */

+			if ( alt->ignore ) break;

+

+			if ( tail==NULL ) {TRAV(alt->p1, k, rk, tail); r->down = tail;}

+			else

+			{

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR10 */    };

+

+				TRAV(alt->p1, k, rk, tail->right);

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);

+/* MR10 */    };

+				if ( tail->right != NULL ) tail = tail->right;

+			}

+		}

+		if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) p->lock[k] = FALSE;

+#ifdef DBG_TREES

+		fprintf(stderr, "blk(%s) returns:",((Junction *)p)->rname); preorder(r); fprintf(stderr, "\n");

+#endif

+		if ( r->down == NULL ) {_Tfree(r); return NULL;}

+		return r;

+	}

+

+	if ( p->jtype==EndRule )

+	{

+		if ( p->halt )						/* don't want FOLLOW here? */

+		{

+/****		if ( ContextGuardTRAV ) return NULL; ****/

+			set_orel( (unsigned) k, rk);	/* indicate this k value needed */ /* MR10 cast */

+			t = tnode(EpToken);

+			t->v.rk = k;

+			return t;

+		}

+		require(p->lock!=NULL, "rJunc: lock array is NULL");

+		if ( p->lock[k] ) return NULL;

+		/* if no FOLLOW assume k EOF's */

+		if ( p->p1 == NULL ) return eofnode(k);

+		p->lock[k] = TRUE;

+	}

+

+/* MR14 */	if (p->p1 != NULL && p->guess &&  p->guess_analysis_point == NULL) {

+/* MR14 */    Node * guess_point;

+/* MR14 */    guess_point=(Node *)analysis_point(p);

+/* MR14 */    if (guess_point == (Node *)p) {

+/* MR14 */      guess_point=p->p1;

+/* MR14 */    }

+/* MR14 */    p->guess_analysis_point=guess_point;

+/* MR14 */  }	

+

+	if ( p->p2 == NULL )

+	{

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR10 */    };

+

+/* M14 */        if (p->guess_analysis_point != NULL) {

+/* M14 */ 		   TRAV(p->guess_analysis_point, k, rk,t);

+/* M14 */        } else {

+        		   TRAV(p->p1, k, rk,t);

+/* M14 */        }

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);

+/* MR10 */    };

+

+		if ( p->jtype==EndRule ) p->lock[k]=FALSE;

+		return t;

+	}

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR10 */    };

+

+/* M14 */        if (p->guess_analysis_point != NULL) {

+/* M14 */ 		   TRAV(p->guess_analysis_point, k, rk,t);

+/* M14 */        } else {

+        		   TRAV(p->p1, k, rk,t);

+/* M14 */        }

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);

+/* MR10 */    };

+

+	if ( p->jtype!=RuleBlk && /* MR14 */ !p->guess) TRAV(p->p2, k, rk, u);

+

+	if ( p->jtype==EndRule ) p->lock[k] = FALSE;/* unlock node */

+

+	if ( t==NULL ) return tmake(tnode(ALT), u, NULL);

+	return tmake(tnode(ALT), t, u, NULL);

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tRuleRef( RuleRefNode *p, int k, set *rk_out )

+#else

+tRuleRef( p, k, rk_out )

+RuleRefNode *p;

+int k;

+set *rk_out;

+#endif

+{

+	int k2;

+	Tree *t=NULL, *u=NULL;

+	Junction *r;

+	set rk, rk2;

+	int save_halt;

+	RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);

+	

+#ifdef DBG_TRAV

+	fprintf(stderr, "tRuleRef: %s\n", p->text);

+#endif

+	if ( q == NULL )

+	{

+		TRAV(p->next, k, rk_out, t);/* ignore undefined rules */

+		return t;

+	}

+	rk = rk2 = empty;

+    if (RulePtr == NULL) fatal("RulePtr==NULL");

+	r = RulePtr[q->rulenum];

+	if ( r->lock[k] ) return NULL;

+	save_halt = r->end->halt;

+	r->end->halt = TRUE;		/* don't let reach fall off end of rule here */

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR10 */    };

+

+	TRAV(r, k, &rk, t);

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      MR_pointerStackPop(&MR_BackTraceStack);

+/* MR10 */    };

+

+	r->end->halt = save_halt;

+#ifdef DBG_TREES

+	fprintf(stderr, "after ruleref, t is:"); preorder(t); fprintf(stderr, "\n");

+#endif

+	t = tshrink( t );

+	while ( !set_nil(rk) ) {	/* any k left to do? if so, link onto tree */

+		k2 = set_int(rk);

+		set_rm(k2, rk);

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR10 */    };

+

+		TRAV(p->next, k2, &rk2, u);

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      MR_pointerStackPop(&MR_BackTraceStack);

+/* MR10 */    };

+

+		t = tlink(t, u, k2);	/* any alts missing k2 toks, add u onto end */

+        Tfree(u);               /* MR10 */

+	}

+	set_free(rk);				/* rk is empty, but free it's memory */

+	set_orin(rk_out, rk2);		/* remember what we couldn't do */

+	set_free(rk2);

+	return t;

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tToken( TokNode *p, int k, set *rk )

+#else

+tToken( p, k, rk )

+TokNode *p;

+int k;

+set *rk;

+#endif

+{

+	Tree *t=NULL, *tset=NULL, *u;

+

+	if (ConstrainSearch) {

+      if (MR_AmbSourceSearch) {

+		require(constrain>=fset&&constrain<=&(fset[CLL_k]),"tToken: constrain is not a valid set");

+      } else {

+		require(constrain>=fset&&constrain<=&(fset[LL_k]),"tToken: constrain is not a valid set");

+      };

+      constrain = &fset[maxk-k+1];

+	}

+

+#ifdef DBG_TRAV

+        	fprintf(stderr, "tToken(%d): %s\n", k, TerminalString(p->token));

+        	if ( ConstrainSearch ) {

+        		fprintf(stderr, "constrain is:"); s_fprT(stderr, *constrain); fprintf(stderr, "\n");

+        	}

+#endif

+

+	/* is it a meta token (set of tokens)? */

+

+	if ( !set_nil(p->tset) )

+	{

+		unsigned e=0;

+		set a;

+		Tree *n, *tail = NULL;

+

+		if ( ConstrainSearch ) {

+          a = set_and(p->tset, *constrain);

+          if (set_nil(a)) {         /* MR10 */

+            set_free(a);            /* MR11 */

+            return NULL;            /* MR10 */

+          };                        /* MR10 */

+		} else {

+          a = set_dup(p->tset);

+        };

+

+		for (; !set_nil(a); set_rm(e, a))

+		{

+			e = set_int(a);

+			n = tnode(e);

+			if ( tset==NULL ) { tset = n; tail = n; }

+			else { tail->right = n; tail = n; }

+		}

+		set_free( a );

+	}

+	else if ( ConstrainSearch && !set_el(p->token, *constrain) )

+    {

+/*      fprintf(stderr, "ignoring token %s(%d)\n", TerminalString(p->token),

+                k);*/

+        return NULL;

+    }

+	else {

+        tset = tnode( p->token );

+    };

+

+/* MR10 */    if (MR_MaintainBackTrace) {

+/* MR10 */      if (k == 1) {

+/* MR10 */        MR_pointerStackPush(&MR_BackTraceStack,p);

+/* MR13 */        if (MR_SuppressSearch) {

+/* MR13 */          MR_suppressSearchReport();

+/* MR13 */        } else {

+/* MR10 */          MR_backTraceReport();

+/* MR13 */        };

+/* MR10 */        MR_pointerStackPop(&MR_BackTraceStack);

+/* MR11 */        Tfree(tset);

+/* MR11 */        return NULL;

+/* MR10 */      };

+/* MR10 */    };

+

+	if ( k == 1 ) return tset;

+

+    if (MR_MaintainBackTrace) {

+      MR_pointerStackPush(&MR_BackTraceStack,p);

+    };

+

+	TRAV(p->next, k-1, rk, t);

+

+    if (MR_MaintainBackTrace) {

+      Tfree(t);

+      Tfree(tset);

+      MR_pointerStackPop(&MR_BackTraceStack);

+      return NULL;

+    };

+

+	/* here, we are positive that, at least, this tree will not contribute

+	 * to the LL(2) tree since it will be too shallow, IF t==NULL.

+	 * If doing a context guard walk, then don't prune.

+	 */

+	if ( t == NULL && !ContextGuardTRAV )	/* tree will be too shallow */

+	{

+		if ( tset!=NULL ) Tfree( tset );

+		return NULL;

+	}

+#ifdef DBG_TREES

+	fprintf(stderr, "tToken(%d)->next:",k); preorder(t); fprintf(stderr, "\n");

+#endif

+

+	/* if single token root, then just make new tree and return */

+    /* MR10 - set_nil(p->tset) isn't a good test because of ConstraintSearch */

+

+	if (tset->right == NULL) return tmake(tset, t, NULL);    /* MR10 */

+

+	/* here we must make a copy of t as a child of each element of the tset;

+	 * e.g., "T1..T3 A" would yield ( nil ( T1 A ) ( T2 A ) ( T3 A ) )

+	 */

+	for (u=tset; u!=NULL; u=u->right)

+	{

+		/* make a copy of t and hook it onto bottom of u */

+		u->down = tdup(t);

+	}

+	Tfree( t );

+#ifdef DBG_TREES

+	fprintf(stderr, "range is:"); preorder(tset); fprintf(stderr, "\n");

+#endif

+	return tset;

+}

+

+Tree *

+#ifdef __USE_PROTOS

+tAction( ActionNode *p, int k, set *rk )

+#else

+tAction( p, k, rk )

+ActionNode *p;

+int k;

+set *rk;

+#endif

+{

+	Tree        *t=NULL;

+    set         *save_fset=NULL;

+    int         i;

+

+	/* fprintf(stderr, "tAction\n"); */

+

+/*  An MR_SuppressSearch is looking for things that can be

+      reached even when the predicate is false.

+

+    There are three kinds of predicates:

+        plain:              r1: <<p>>? r2

+        guarded:            r1: (A)? => <<p>>? r2

+        ampersand style:    r1: (A)? && <<p>>? r2

+

+    Of the three kinds of predicates, only a guard predicate

+      has things which are reachable even when the predicate

+      is false.  To be reachable the constraint must *not*

+      match the guard.

+

+*/

+

+    if (p->is_predicate && MR_SuppressSearch) {

+

+      Predicate     *pred=p->guardpred;

+

+      if (pred == NULL) {

+        t=NULL;

+        goto EXIT;

+      };

+      constrain = &fset[maxk-k+1];

+      if (pred->k == 1) {

+        set     dif;

+        dif=set_dif(*constrain,pred->scontext[1]);

+        if (set_nil(dif)) {

+          set_free(dif);

+          t=NULL;

+          goto EXIT;

+        };

+        set_free(dif);

+      } else {

+        if (MR_tree_matches_constraints(k,constrain,pred->tcontext)) {

+          t=NULL;

+          goto EXIT;

+        };

+      }

+    };

+

+    /* The ampersand predicate differs from the

+         other predicates because its first set

+         is a subset of the first set behind the predicate

+

+            r1: (A)? && <<p>>? r2 ;

+            r2: A | B;

+

+       In this case first[1] of r1 is A, even

+         though first[1] of r2 is {A B}.

+    */

+

+    if (p->is_predicate && p->ampersandPred != NULL) {

+

+      Predicate     *pred=p->ampersandPred;

+      Tree          *tAND;

+      Tree          *tset;

+

+      if (k <= pred->k) {

+        if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);

+        TRAV(p->guardNodes,k,rk,t);

+        if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);

+        return t;

+      } else {

+        require (k>1,"tAction for ampersandpred: k <= 1");

+        if (ConstrainSearch) {

+          if (MR_AmbSourceSearch) {

+    		require(constrain>=fset&&constrain<=&(fset[CLL_k]),

+                                "tToken: constrain is not a valid set");

+          } else {

+    		require(constrain>=fset&&constrain<=&(fset[LL_k]),

+                                "tToken: constrain is not a valid set");

+          };

+          save_fset=(set *) calloc (CLL_k+1,sizeof(set));

+          require (save_fset != NULL,"tAction save_fset alloc");

+          for (i=1; i <= CLL_k ; i++) {

+            save_fset[i]=set_dup(fset[i]);

+          };

+          if (pred->k == 1) {

+            constrain = &fset[maxk-k+1];

+            set_andin(constrain,pred->scontext[1]);

+            if (set_nil(*constrain)) {

+              t=NULL;

+              goto EXIT;

+            };

+          } else {

+            constrain = &fset[maxk-k+1];

+            if (! MR_tree_matches_constraints(pred->k,constrain,pred->tcontext)) {

+               t=NULL;

+               goto EXIT;

+            };  /* end loop on i          */

+          }; /* end loop on pred scontext/tcontext */

+        }; /* end if on k > pred->k     */

+      }; /* end if on constrain search  */

+

+      TRAV(p->next,k,rk,t);

+

+      if (t != NULL) {

+        t=tshrink(t);

+        t=tflatten(t);

+        t=tleft_factor(t);

+        if (pred->tcontext != NULL) {

+          tAND=MR_computeTreeAND(t,pred->tcontext);

+        } else {

+          tset=MR_make_tree_from_set(pred->scontext[1]);

+          tAND=MR_computeTreeAND(t,tset);

+          Tfree(tset);

+        };

+        Tfree(t);

+        t=tAND;

+      };

+      goto EXIT;

+

+    }; /* end if on ampersand predicate */

+

+    TRAV(p->next,k,rk,t);

+

+EXIT:

+    if (save_fset != NULL) {

+      for (i=1 ; i <= CLL_k ; i++) {

+        set_free(fset[i]);

+        fset[i]=save_fset[i];

+      };

+      free ( (char *) save_fset);

+    };

+	return t;

+}

+

+/* see if e exists in s as a possible input permutation (e is always a chain) */

+

+int

+#ifdef __USE_PROTOS

+tmember( Tree *e, Tree *s )

+#else

+tmember( e, s )

+Tree *e;

+Tree *s;

+#endif

+{

+	if ( e==NULL||s==NULL ) return 0;

+/** fprintf(stderr, "tmember(");

+***	preorder(e); fprintf(stderr, ",");

+***	preorder(s); fprintf(stderr, " )\n");

+*/

+	if ( s->token == ALT && s->right == NULL ) return tmember(e, s->down);

+	if ( e->token!=s->token )

+	{

+		if ( s->right==NULL ) return 0;

+		return tmember(e, s->right);

+	}

+	if ( e->down==NULL && s->down == NULL ) return 1;

+	if ( tmember(e->down, s->down) ) return 1;

+	if ( s->right==NULL ) return 0;

+	return tmember(e, s->right);

+}

+

+/* see if e exists in s as a possible input permutation (e is always a chain);

+ * Only check s to the depth of e.  In other words, 'e' can be a shorter

+ * sequence than s.

+ */

+int

+#ifdef __USE_PROTOS

+tmember_constrained( Tree *e, Tree *s)

+#else

+tmember_constrained( e, s )

+Tree *e;

+Tree *s;

+#endif

+{

+	if ( e==NULL||s==NULL ) return 0;

+/**	fprintf(stderr, "tmember_constrained(");

+***	preorder(e); fprintf(stderr, ",");

+***	preorder(s); fprintf(stderr, " )\n");

+**/

+	if ( s->token == ALT && s->right == NULL )

+		return tmember_constrained(e, s->down);

+	if ( e->token!=s->token )

+	{

+		if ( s->right==NULL ) return 0;

+		return tmember_constrained(e, s->right);

+	}

+	if ( e->down == NULL ) return 1; /* if s is matched to depth of e return */

+	if ( tmember_constrained(e->down, s->down) ) return 1;

+	if ( s->right==NULL ) return 0;

+	return tmember_constrained(e, s->right);

+}

+

+/* combine (? (A t) ... (A u) ...) into (? (A t u)) */

+Tree *

+#ifdef __USE_PROTOS

+tleft_factor( Tree *t )

+#else

+tleft_factor( t )

+Tree *t;

+#endif

+{

+	Tree *u, *v, *trail, *w;

+

+	/* left-factor what is at this level */

+	if ( t == NULL ) return NULL;

+	for (u=t; u!=NULL; u=u->right)

+	{

+		trail = u;

+		v=u->right;

+		while ( v!=NULL )

+		{

+			if ( u->token == v->token )

+			{

+				if ( u->down!=NULL )

+				{

+					for (w=u->down; w->right!=NULL; w=w->right) {;}

+					w->right = v->down;	/* link children together */

+				}

+				else u->down = v->down;

+				trail->right = v->right;		/* unlink factored node */

+				_Tfree( v );

+				v = trail->right;

+			}

+			else {trail = v; v=v->right;}

+		}

+	}

+	/* left-factor what is below */

+	for (u=t; u!=NULL; u=u->right) u->down = tleft_factor( u->down );

+	return t;

+}

+

+/* remove the permutation p from t if present */

+Tree *

+#ifdef __USE_PROTOS

+trm_perm( Tree *t, Tree *p )

+#else

+trm_perm( t, p )

+Tree *t;

+Tree *p;

+#endif

+{

+	/*

+	fprintf(stderr, "trm_perm(");

+	preorder(t); fprintf(stderr, ",");

+	preorder(p); fprintf(stderr, " )\n");

+	*/

+	if ( t == NULL || p == NULL ) return NULL;

+	if ( t->token == ALT )

+	{

+		t->down = trm_perm(t->down, p);

+		if ( t->down == NULL ) 				/* nothing left below, rm cur node */

+		{

+			Tree *u = t->right;

+			_Tfree( t );

+			return trm_perm(u, p);

+		}

+		t->right = trm_perm(t->right, p);	/* look for more instances of p */

+		return t;

+	}

+	if ( p->token != t->token )				/* not found, try a sibling */

+	{

+		t->right = trm_perm(t->right, p);

+		return t;

+	}

+	t->down = trm_perm(t->down, p->down);

+	if ( t->down == NULL ) 					/* nothing left below, rm cur node */

+	{

+		Tree *u = t->right;

+		_Tfree( t );

+		return trm_perm(u, p);

+	}

+	t->right = trm_perm(t->right, p);		/* look for more instances of p */

+	return t;

+}

+

+/* add the permutation 'perm' to the LL_k sets in 'fset' */

+void

+#ifdef __USE_PROTOS

+tcvt( set *fset, Tree *perm )

+#else

+tcvt( fset, perm )

+set *fset;

+Tree *perm;

+#endif

+{

+	if ( perm==NULL ) return;

+	set_orel(perm->token, fset);

+	tcvt(fset+1, perm->down);

+}

+

+/* for each element of ftbl[k], make it the root of a tree with permute(ftbl[k+1])

+ * as a child.

+ */

+Tree *

+#ifdef __USE_PROTOS

+permute( int k, int max_k )

+#else

+permute( k, max_k )

+int k, max_k;

+#endif

+{

+	Tree *t, *u;

+	

+	if ( k>max_k ) return NULL;

+	if ( ftbl[k][findex[k]] == nil ) return NULL;

+	t = permute(k+1, max_k);

+	if ( t==NULL&&k<max_k )		/* no permutation left below for k+1 tokens? */

+	{

+		findex[k+1] = 0;

+		(findex[k])++;			/* try next token at this k */

+		return permute(k, max_k);

+	}

+	

+	u = tmake(tnode(ftbl[k][findex[k]]), t, NULL);

+	if ( k == max_k ) (findex[k])++;

+	return u;

+}

+

+/* Compute LL(k) trees for alts alt1 and alt2 of p.

+ * function result is tree of ambiguous input permutations

+ *

+ * ALGORITHM may change to look for something other than LL_k size

+ * trees ==> maxk will have to change.

+ */

+Tree *

+#ifdef __USE_PROTOS

+VerifyAmbig( Junction *alt1, Junction *alt2, unsigned **ft, set *fs, Tree **t, Tree **u, int *numAmbig )

+#else

+VerifyAmbig( alt1, alt2, ft, fs, t, u, numAmbig )

+Junction *alt1;

+Junction *alt2;

+unsigned **ft;

+set *fs;

+Tree **t;

+Tree **u;

+int *numAmbig;

+#endif

+{

+	set rk;

+	Tree *perm, *ambig=NULL;

+	Junction *p;

+	int k;

+    int    tnodes_at_start=TnodesAllocated;

+    int    tnodes_at_end;

+    int    tnodes_used;

+    set    *save_fs;

+    int    j;

+

+    save_fs=(set *) calloc(CLL_k+1,sizeof(set));

+    require(save_fs != NULL,"save_fs calloc");

+

+    for (j=0; j <= CLL_k ; j++) save_fs[j]=set_dup(fs[j]);

+

+	maxk = LL_k;				/* NOTE: for now, we look for LL_k */

+	ftbl = ft;

+	fset = fs;

+	constrain = &(fset[1]);

+	findex = (int *) calloc(LL_k+1, sizeof(int));

+	if ( findex == NULL )

+	{

+		fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);

+		fprintf(stderr, " out of memory while analyzing alts %d and %d of %s\n",

+						CurAmbigAlt1,

+						CurAmbigAlt2,

+						CurAmbigbtype);

+		exit(PCCTS_EXIT_FAILURE);

+	}

+	for (k=1; k<=LL_k; k++) findex[k] = 0;

+

+	rk = empty;

+	ConstrainSearch = 1;	/* consider only tokens in ambig sets */

+

+	p = analysis_point((Junction *)alt1->p1);

+	TRAV(p, LL_k, &rk, *t);

+	*t = tshrink( *t );

+	*t = tflatten( *t );

+	*t = tleft_factor( *t );    /* MR10 */

+	*t = prune(*t, LL_k);

+	*t = tleft_factor( *t );

+

+/***	fprintf(stderr, "after shrink&flatten&prune&left_factor:"); preorder(*t); fprintf(stderr, "\n");*/

+	if ( *t == NULL )

+	{

+/***	fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/

+		Tfree( *t );	/* kill if impossible to have ambig */

+		*t = NULL;

+	}

+

+	p = analysis_point((Junction *)alt2->p1);

+

+	TRAV(p, LL_k, &rk, *u);

+	*u = tshrink( *u );

+	*u = tflatten( *u );

+	*t = tleft_factor( *t );    /* MR10 */

+	*u = prune(*u, LL_k);

+	*u = tleft_factor( *u );

+/*	fprintf(stderr, "after shrink&flatten&prune&lfactor:"); preorder(*u); fprintf(stderr, "\n");*/

+	if ( *u == NULL )

+	{

+/*		fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/

+		Tfree( *u );

+		*u = NULL;

+	}

+

+	for (k=1; k<=LL_k; k++) set_clr( fs[k] );

+

+	ambig = tnode(ALT);

+	k = 0;

+	if ( *t!=NULL && *u!=NULL )

+	{

+		while ( (perm=permute(1,LL_k))!=NULL )

+		{

+/*			fprintf(stderr, "chk perm:"); preorder(perm); fprintf(stderr, "\n");*/

+			if ( tmember(perm, *t) && tmember(perm, *u) )

+			{

+/*				fprintf(stderr, "ambig upon"); preorder(perm); fprintf(stderr, "\n");*/

+

+				k++;

+				perm->right = ambig->down;

+				ambig->down = perm;

+				tcvt(&(fs[1]), perm);

+			}

+			else Tfree( perm );

+		}

+	}

+

+    for (j=0; j <= CLL_k ; j++) fs[j]=save_fs[j];

+    free( (char *) save_fs);

+

+    tnodes_at_end=TnodesAllocated;

+    tnodes_used=tnodes_at_end - tnodes_at_start;

+

+    if (TnodesReportThreshold > 0 && tnodes_used > TnodesReportThreshold) {

+      fprintf(stdout,"There were %d tuples whose ambiguity could not be resolved by full lookahead\n",k);

+      fprintf(stdout,"There were %d tnodes created to resolve ambiguity between:\n\n",tnodes_used);

+      fprintf(stdout,"  Choice 1: %s  line %d  file %s\n",

+                                 MR_ruleNamePlusOffset( (Node *) alt1),alt1->line,FileStr[alt1->file]);

+      fprintf(stdout,"  Choice 2: %s  line %d  file %s\n",

+                                 MR_ruleNamePlusOffset( (Node *) alt2),alt2->line,FileStr[alt2->file]);

+      for (j=1; j <= CLL_k ; j++) {

+        fprintf(stdout,"\n    Intersection of lookahead[%d] sets:\n",j);

+        MR_dumpTokenSet(stdout,2,fs[j]);

+      };

+      fprintf(stdout,"\n");

+    };

+

+	*numAmbig = k;

+	if ( ambig->down == NULL ) {_Tfree(ambig); ambig = NULL;}

+	free( (char *)findex );

+/*	fprintf(stderr, "final ambig:"); preorder(ambig); fprintf(stderr, "\n");*/

+	return ambig;

+}

+

+static Tree *

+#ifdef __USE_PROTOS

+bottom_of_chain( Tree *t )

+#else

+bottom_of_chain( t )

+Tree *t;

+#endif

+{

+    if ( t==NULL ) return NULL;

+    for (; t->down != NULL; t=t->down) {;}

+    return t;

+}

+

+/*

+ * Make a tree from k sets where the degree of the first k-1 sets is 1.

+ */

+Tree *

+#ifdef __USE_PROTOS

+make_tree_from_sets( set *fset1, set *fset2 )

+#else

+make_tree_from_sets( fset1, fset2 )

+set *fset1;

+set *fset2;

+#endif

+{

+	set inter;

+	int i;

+	Tree *t=NULL, *n, *u;

+	unsigned *p,*q;

+	require(LL_k>1, "make_tree_from_sets: LL_k must be > 1");

+

+	/* do the degree 1 sets first */

+	for (i=1; i<=LL_k-1; i++)

+	{

+		inter = set_and(fset1[i], fset2[i]);

+		require(set_deg(inter)==1, "invalid set to tree conversion");

+		n = tnode(set_int(inter));

+		if (t==NULL) t=n; else tmake(t, n, NULL);

+		set_free(inter);

+	}

+

+	/* now add the chain of tokens at depth k */

+	u = bottom_of_chain(t);

+	inter = set_and(fset1[LL_k], fset2[LL_k]);

+	if ( (q=p=set_pdq(inter)) == NULL ) fatal_internal("Can't alloc space for set_pdq");

+	/* first one is linked to bottom, then others are sibling linked */

+	n = tnode(*p++);

+	u->down = n;

+	u = u->down;

+	while ( *p != nil )

+	{

+		n = tnode(*p);

+		u->right = n;

+		u = u->right;

+		p++;

+	}

+	free((char *)q);

+

+	return t;

+}

+

+/* create and return the tree of lookahead k-sequences that are in t, but not

+ * in the context of predicates in predicate list p.

+ */

+Tree *

+#ifdef __USE_PROTOS

+tdif( Tree *ambig_tuples, Predicate *p, set *fset1, set *fset2 )

+#else

+tdif( ambig_tuples, p, fset1, fset2 )

+Tree *ambig_tuples;

+Predicate *p;

+set *fset1;

+set *fset2;

+#endif

+{

+	unsigned **ft;

+	Tree *dif=NULL;

+	Tree *perm;

+	set b;

+	int i,k;

+

+	if ( p == NULL ) return tdup(ambig_tuples);

+

+	ft = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));

+	require(ft!=NULL, "cannot allocate ft");

+	for (i=1; i<=CLL_k; i++)

+	{

+		b = set_and(fset1[i], fset2[i]);

+		ft[i] = set_pdq(b);

+		set_free(b);

+	}

+	findex = (int *) calloc(LL_k+1, sizeof(int));

+	if ( findex == NULL )

+	{

+		fatal_internal("out of memory in tdif while checking predicates");

+	}

+	for (k=1; k<=LL_k; k++) findex[k] = 0;

+

+#ifdef DBG_TRAV

+	fprintf(stderr, "tdif_%d[", p->k);

+	preorder(ambig_tuples);

+	fprintf(stderr, ",");

+	preorder(p->tcontext);

+	fprintf(stderr, "] =");

+#endif

+

+	ftbl = ft;

+	while ( (perm=permute(1,p->k))!=NULL )

+	{

+#ifdef DBG_TRAV

+		fprintf(stderr, "test perm:"); preorder(perm); fprintf(stderr, "\n");

+#endif

+		if ( tmember_constrained(perm, ambig_tuples) &&

+			 !tmember_of_context(perm, p) )

+		{

+#ifdef DBG_TRAV

+			fprintf(stderr, "satisfied upon"); preorder(perm); fprintf(stderr, "\n");

+#endif

+			k++;

+			if ( dif==NULL ) dif = perm;

+			else

+			{

+				perm->right = dif;

+				dif = perm;

+			}

+		}

+		else Tfree( perm );

+	}

+

+#ifdef DBG_TRAV

+	preorder(dif);

+	fprintf(stderr, "\n");

+#endif

+

+	for (i=1; i<=CLL_k; i++) free( (char *)ft[i] );

+	free((char *)ft);

+	free((char *)findex);

+

+	return dif;

+}

+

+/* is lookahead sequence t a member of any context tree for any

+ * predicate in p?

+ */

+static int

+#ifdef __USE_PROTOS

+tmember_of_context( Tree *t, Predicate *p )

+#else

+tmember_of_context( t, p )

+Tree *t;

+Predicate *p;

+#endif

+{

+	for (; p!=NULL; p=p->right)

+	{

+		if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST )

+			return tmember_of_context(t, p->down);

+		if ( tmember_constrained(t, p->tcontext) ) return 1;

+		if ( tmember_of_context(t, p->down) ) return 1;

+	}

+	return 0;

+}

+

+int

+#ifdef __USE_PROTOS

+is_single_tuple( Tree *t )

+#else

+is_single_tuple( t )

+Tree *t;

+#endif

+{

+	if ( t == NULL ) return 0;

+	if ( t->right != NULL ) return 0;

+	if ( t->down == NULL ) return 1;

+	return is_single_tuple(t->down);

+}

+

+

+/* MR10 Check that a context guard contains only allowed things */

+/* MR10   (mainly token references).                            */

+

+#ifdef __USE_PROTOS

+int contextGuardOK(Node *p,int h,int *hmax)

+#else

+int contextGuardOK(p,h,hmax)

+  Node  *p;

+  int   h;

+  int   *hmax;

+#endif

+{

+    Junction     *j;

+    TokNode      *tn;

+

+    if (p == NULL) return 1;

+    if (p->ntype == nToken) {

+      h++;

+      if (h > *hmax) *hmax=h;

+      tn=(TokNode *)p;

+      if (tn->el_label != NULL) {

+        warnFL(eMsg1("a label (\"%s\") for a context guard element is meaningless",tn->el_label),

+                             FileStr[p->file],p->line);

+      };

+      return contextGuardOK( ( (TokNode *) p)->next,h,hmax);

+    } else if (p->ntype == nAction) {

+      goto Fail;

+    } else if (p->ntype == nRuleRef) {

+      goto Fail;

+    } else {

+      require (p->ntype == nJunction,"Unexpected ntype");

+      j=(Junction *) p;

+      if (j->jtype != Generic &&

+          j->jtype != aSubBlk &&        /* pretty sure this one is allowed */

+/****     j->jtype != aOptBlk && ****/  /* pretty sure this one is allowed */ /* MR11 not any more ! */

+          j->jtype != EndBlk) {

+        errFL("A context guard may not contain an option block: {...} or looping block: (...)* or (...)+",

+                  FileStr[p->file],p->line);

+        contextGuardOK(j->p1,h,hmax);

+        return 0;

+      };

+      /* do both p1 and p2 so use | rather than ||  */

+      return contextGuardOK(j->p2,h,hmax) | contextGuardOK(j->p1,h,hmax);

+    };

+Fail:

+    errFL("A context guard may contain only Token references - guard will be ignored",

+                             FileStr[p->file],p->line);

+    contextGuardOK( ( (ActionNode *) p)->next,h,hmax);

+    return 0;

+}

+

+/*

+ * Look at a (...)? generalized-predicate context-guard and compute

+ * either a lookahead set (k==1) or a lookahead tree for k>1.  The

+ * k level is determined by the guard itself rather than the LL_k

+ * variable.  For example, ( A B )? is an LL(2) guard and ( ID )?

+ * is an LL(1) guard.  For the moment, you can only have a single

+ * tuple in the guard.  Physically, the block must look like this

+ *   --o-->TOKEN-->o-->o-->TOKEN-->o-- ... -->o-->TOKEN-->o--

+ * An error is printed for any other type.

+ */

+Predicate *

+#ifdef __USE_PROTOS

+computePredFromContextGuard(Graph blk,int *msgDone)    /* MR10 */

+#else

+computePredFromContextGuard(blk,msgDone)               /* MR10 */

+  Graph     blk;

+  int       *msgDone;                                       /* MR10 */

+#endif

+{

+    Junction *junc = (Junction *)blk.left, *p;

+    Tree        *t=NULL;

+	Predicate   *pred = NULL;

+	set         scontext, rk;

+    int         ok;

+    int         hmax=0;

+

+    require(junc!=NULL && junc->ntype == nJunction, "bad context guard");

+

+/* MR10 Check for anything other than Tokens and generic junctions */

+

+    *msgDone=0;                                             /* MR10 */

+    ok=contextGuardOK( (Node *)junc,0,&hmax);               /* MR10 */

+    if (! ok) {                                             /* MR10 */

+      *msgDone=1;                                           /* MR10 */

+      return NULL;                                          /* MR10 */

+    };                                                      /* MR10 */

+    if (hmax == 0) {

+errFL("guard is 0 tokens long",FileStr[junc->file],junc->line);          /* MR11 */

+      *msgDone=1;

+      return NULL;

+    };

+    if (hmax > CLL_k) {                                     /* MR10 */

+errFL(eMsgd2("guard is %d tokens long - lookahead is limited to max(k,ck)==%d", /* MR10 */

+        hmax,CLL_k),                                        /* MR10 */

+        FileStr[junc->file],junc->line);                    /* MR10 */

+      *msgDone=1;                                           /* MR10 */

+      return NULL;                                          /* MR10 */

+    };                                                      /* MR10 */

+

+	rk = empty;

+	p = junc;

+	pred = new_pred();

+	pred->k = hmax;     /* MR10 should be CLL_k, not LLK ? */

+	if (hmax > 1 )      /* MR10 was LL_k                   */

+	{

+		ConstrainSearch = 0;

+		ContextGuardTRAV = 1;

+		TRAV(p, hmax, &rk, t);  /* MR10 was LL_k */

+		ContextGuardTRAV = 0;

+		set_free(rk);

+		t = tshrink( t );

+		t = tflatten( t );

+		t = tleft_factor( t );

+/*

+		fprintf(stderr, "ctx guard:");

+		preorder(t);

+		fprintf(stderr, "\n");

+*/

+		pred->tcontext = t;

+	}

+	else

+	{

+		REACH(p, 1, &rk, scontext);

+		require(set_nil(rk), "rk != nil");

+		set_free(rk);

+/*

+		fprintf(stderr, "LL(1) ctx guard is:");

+		s_fprT(stderr, scontext);

+		fprintf(stderr, "\n");

+*/

+		pred->scontext[1] = scontext;

+	}

+

+    list_add(&ContextGuardPredicateList,pred);     /* MR13 */

+

+	return pred;

+}

+

+/* MR13

+   When the context guard is originally computed the

+   meta-tokens are not known.

+*/

+

+#ifdef __USE_PROTOS

+void recomputeContextGuard(Predicate *pred)

+#else

+void recomputeContextGuard(pred)

+    Predicate   *pred;

+#endif

+{

+    Tree *          t=NULL;

+	set             scontext;

+    set             rk;

+    ActionNode *    actionNode;

+    Junction *      p;

+

+    actionNode=pred->source;

+    require (actionNode != NULL,"context predicate's source == NULL");

+

+    p=actionNode->guardNodes;

+    require (p != NULL,"context predicate's guardNodes == NULL");

+

+	rk = empty;

+	if (pred->k > 1 )

+	{

+		ConstrainSearch = 0;

+		ContextGuardTRAV = 1;

+		TRAV(p, pred->k, &rk, t);

+		ContextGuardTRAV = 0;

+		set_free(rk);

+		t = tshrink( t );

+		t = tflatten( t );

+		t = tleft_factor( t );

+        Tfree(pred->tcontext);

+		pred->tcontext = t;

+	}

+	else

+	{

+		REACH(p, 1, &rk, scontext);

+		require(set_nil(rk), "rk != nil");

+		set_free(rk);

+        set_free(pred->scontext[1]);

+		pred->scontext[1] = scontext;

+	}

+}

+

+/* MR11 - had enough of flags yet ? */

+

+int     MR_AmbSourceSearch=0;

+int     MR_AmbSourceSearchGroup=0;

+int     MR_AmbSourceSearchChoice=0;

+int     MR_AmbSourceSearchLimit=0;

+int     MR_matched_AmbAidRule=0;

+

+static    set         *matchSets[2]={NULL,NULL};

+static    int         *tokensInChain=NULL;

+static    Junction    *MR_AmbSourceSearchJ[2];

+

+void MR_traceAmbSourceKclient()

+{

+  int       i;

+  set       *save_fset;

+  int       save_ConstrainSearch;

+  set       incomplete;

+  Tree      *t;

+

+  if (matchSets[0] == NULL) {

+    matchSets[0]=(set *) calloc (CLL_k+1,sizeof(set));

+    require (matchSets[0] != NULL,"matchSets[0] alloc");

+    matchSets[1]=(set *) calloc (CLL_k+1,sizeof(set));

+    require (matchSets[1] != NULL,"matchSets[1] alloc");

+  };

+

+  for (i=1 ; i <= MR_AmbSourceSearchLimit ; i++) {

+    set_clr(matchSets[0][i]);

+    set_orel( (unsigned) tokensInChain[i],

+                              &matchSets[0][i]);

+    set_clr(matchSets[1][i]);

+    set_orel( (unsigned) tokensInChain[i],

+                              &matchSets[1][i]);

+  };

+

+  save_fset=fset;

+  save_ConstrainSearch=ConstrainSearch;

+

+

+

+  for (i=0 ; i < 2 ; i++) {

+

+#if 0

+**    fprintf(stdout,"  Choice:%d  Depth:%d  ",i+1,MR_AmbSourceSearchLimit);

+**    fprintf(stdout,"(");

+**    for (j=1 ; j <= MR_AmbSourceSearchLimit ; j++) {

+**      if (j != 1) fprintf(stdout," ");

+**      fprintf(stdout,"%s",TerminalString(tokensInChain[j]));

+**    };

+**    fprintf(stdout,")\n\n");

+#endif

+

+    fset=matchSets[i];

+

+    MR_AmbSourceSearch=1;

+    MR_MaintainBackTrace=1;

+    MR_AmbSourceSearchChoice=i;

+    ConstrainSearch=1;

+

+    maxk = MR_AmbSourceSearchLimit;

+

+    incomplete=empty;

+    t=NULL;

+

+    constrain = &(fset[1]);

+    MR_pointerStackReset(&MR_BackTraceStack);

+

+    TRAV(MR_AmbSourceSearchJ[i],maxk,&incomplete,t);

+

+    Tfree(t);

+

+    require (set_nil(incomplete),"MR_traceAmbSourceK TRAV incomplete");

+    require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");

+

+    set_free(incomplete);

+  };

+

+  ConstrainSearch=save_ConstrainSearch;

+  fset=save_fset;

+  MR_AmbSourceSearch=0;

+  MR_MaintainBackTrace=0;

+  MR_AmbSourceSearchChoice=0;

+}

+

+#ifdef __USE_PROTOS

+Tree *tTrunc(Tree *t,int depth)

+#else

+Tree *tTrunc(t,depth)

+  Tree  *t;

+#endif

+{

+    Tree    *u;

+

+    require ( ! (t == NULL && depth > 0),"tree too short");

+

+    if (depth == 0) return NULL;

+

+    if (t->token == ALT) {

+      u=tTrunc(t->down,depth);

+    } else {

+      u=tnode(t->token);

+      u->down=tTrunc(t->down,depth-1);

+    };

+    if (t->right != NULL) u->right=tTrunc(t->right,depth);

+    return u;

+}

+

+#ifdef __USE_PROTOS

+void MR_iterateOverTree(Tree *t,int chain[])

+#else

+void MR_iterateOverTree(t,chain)

+  Tree          *t;

+  int           chain[];

+#endif

+{

+  if (t == NULL) return;

+  chain[0]=t->token;

+  if (t->down != NULL) {

+    MR_iterateOverTree(t->down,&chain[1]);

+  } else {

+    MR_traceAmbSourceKclient();

+  };

+  MR_iterateOverTree(t->right,&chain[0]);

+  chain[0]=0;

+}

+

+#ifdef __USE_PROTOS

+void MR_traceAmbSourceK(Tree *t,Junction *alt1,Junction *alt2)

+#else

+void MR_traceAmbSourceK(t,alt1,alt2)

+  Tree      *t;

+  Junction  *alt1;

+  Junction  *alt2;

+#endif

+{

+    int         i;

+    int         depth;

+    int         maxDepth;

+    Tree        *truncatedTree;

+

+    if (MR_AmbAidRule == NULL) return;

+

+    if ( ! (

+            strcmp(MR_AmbAidRule,alt1->rname) == 0 ||

+            strcmp(MR_AmbAidRule,alt2->rname) == 0 ||

+            MR_AmbAidLine==alt1->line ||

+            MR_AmbAidLine==alt2->line

+           )

+       ) return;

+

+    MR_matched_AmbAidRule++;

+

+    /* there are no token sets in trees, only in TokNodes */

+

+    MR_AmbSourceSearchJ[0]=analysis_point( (Junction *) alt1->p1);

+    MR_AmbSourceSearchJ[1]=analysis_point( (Junction *) alt2->p1);

+

+    if (tokensInChain == NULL) {

+      tokensInChain=(int *) calloc (CLL_k+1,sizeof(int));

+      require (tokensInChain != NULL,"tokensInChain alloc");

+    };

+

+    MR_AmbSourceSearchGroup=0;

+

+    fprintf(stdout,"\n");

+    fprintf(stdout,"  Ambiguity Aid                 ");

+    fprintf(stdout,

+                (MR_AmbAidDepth <= LL_k ?

+                    "(-k %d  -aa %s  %s  -aad %d)\n\n" :

+                        "(-k %d  -aa %s  %s  [-k value limits -aad %d])\n\n"),

+                LL_k,

+                MR_AmbAidRule,

+                (MR_AmbAidMultiple ? "-aam" : ""),

+                MR_AmbAidDepth);

+

+    for (i=0 ; i < 2 ; i++) {

+      fprintf(stdout,"    Choice %d: %-25s  line %d  file %s\n",

+                  (i+1),

+                  MR_ruleNamePlusOffset( (Node *) MR_AmbSourceSearchJ[i]),

+                  MR_AmbSourceSearchJ[i]->line,

+                  FileStr[MR_AmbSourceSearchJ[i]->file]);

+    };

+

+    fprintf(stdout,"\n");

+

+    if (MR_AmbAidDepth < LL_k) {

+      maxDepth=MR_AmbAidDepth;

+    } else {

+      maxDepth=LL_k;

+    };

+

+    for (depth=1 ; depth <= maxDepth; depth++) {

+      MR_AmbSourceSearchLimit=depth;

+      if (depth < LL_k) {

+        truncatedTree=tTrunc(t,depth);

+        truncatedTree=tleft_factor(truncatedTree);

+        MR_iterateOverTree(truncatedTree,&tokensInChain[1]);    /* <===== */

+        Tfree(truncatedTree);

+      } else {

+        MR_iterateOverTree(t,tokensInChain);                /* <===== */

+      };

+      fflush(stdout);

+      fflush(stderr);

+    };

+

+    fprintf(stdout,"\n");

+    MR_AmbSourceSearch=0;

+    MR_MaintainBackTrace=0;

+    MR_AmbSourceSearchGroup=0;

+    MR_AmbSourceSearchChoice=0;

+    MR_AmbSourceSearchLimit=0;

+

+}

+

+

+/* this if for k=1 grammars only

+

+   this is approximate only because of the limitations of linear

+   approximation lookahead.  Don't want to do a k=3 search when

+   the user only specified a ck=3 grammar

+*/

+

+#ifdef __USE_PROTOS

+void MR_traceAmbSource(set *matchSets,Junction *alt1, Junction *alt2)

+#else

+void MR_traceAmbSource(matchSets,alt1,alt2)

+  set       *matchSets;

+  Junction  *alt1;

+  Junction  *alt2;

+#endif

+{

+    set         *save_fset;

+    Junction    *p[2];

+    int         i;

+    int         j;

+    set         *dup_matchSets;

+    set         intersection;

+    set         incomplete;

+    set         tokensUsed;

+    int         depth;

+

+    if (MR_AmbAidRule == NULL) return;

+    if ( ! (

+            strcmp(MR_AmbAidRule,alt1->rname) == 0 ||

+            strcmp(MR_AmbAidRule,alt2->rname) == 0 ||

+            MR_AmbAidLine==alt1->line ||

+            MR_AmbAidLine==alt2->line

+           )

+       ) return;

+

+    MR_matched_AmbAidRule++;

+

+    save_fset=fset;

+

+    dup_matchSets=(set *) calloc(CLL_k+1,sizeof(set));

+    require (dup_matchSets != NULL,"Can't allocate dup_matchSets");

+

+    p[0]=analysis_point( (Junction *) alt1->p1);

+    p[1]=analysis_point( (Junction *) alt2->p1);

+

+    fprintf(stdout,"\n");

+

+    fprintf(stdout,"  Ambiguity Aid                 ");

+    fprintf(stdout,

+                (MR_AmbAidDepth <= CLL_k ?

+                    "(-ck %d  -aa %s  %s  -aad %d)\n\n" :

+                        "(-ck %d  -aa %s  %s  [-ck value limits -aad %d])\n\n"),

+                CLL_k,

+                MR_AmbAidRule,

+                (MR_AmbAidMultiple ? "-aam" : ""),

+                MR_AmbAidDepth);

+

+    for (i=0 ; i < 2 ; i++) {

+      fprintf(stdout,"    Choice %d: %-25s  line %d  file %s\n",

+                            (i+1),

+                            MR_ruleNamePlusOffset( (Node *) p[i]),

+                            p[i]->line,FileStr[p[i]->file]);

+    };

+

+    for (j=1; j <= CLL_k ; j++) {

+      fprintf(stdout,"\n    Intersection of lookahead[%d] sets:\n",j);

+      intersection=set_and(alt1->fset[j],alt2->fset[j]);

+      MR_dumpTokenSet(stdout,2,intersection);

+      set_free(intersection);

+    };

+

+    fprintf(stdout,"\n");

+

+    require (1 <= MR_AmbAidDepth && MR_AmbAidDepth <= CLL_k,

+                "illegal MR_AmbAidDepth");

+

+    MR_AmbSourceSearchGroup=0;

+    for (depth=1; depth <= MR_AmbAidDepth; depth++) {

+        MR_AmbSourceSearchLimit=depth;

+        for (i=0 ; i < 2 ; i++) {

+

+/***        fprintf(stdout,"  Choice:%d  Depth:%d\n\n",i+1,depth);  ***/

+

+            for (j=0 ; j <= CLL_k ; j++) { dup_matchSets[j]=set_dup(matchSets[j]); };

+            fset=dup_matchSets;

+

+            fflush(output);

+            fflush(stdout);

+

+            MR_AmbSourceSearch=1;

+            MR_MaintainBackTrace=1;

+            MR_AmbSourceSearchChoice=i;

+

+            maxk = depth;

+            tokensUsed=empty;

+            incomplete=empty;

+

+            constrain = &(fset[1]);

+            MR_pointerStackReset(&MR_BackTraceStack);

+

+            REACH(p[i],depth,&incomplete,tokensUsed);

+

+            fflush(output);

+            fflush(stdout);

+

+            require (set_nil(incomplete),"MR_traceAmbSource REACH incomplete");

+            require (MR_BackTraceStack.count == 0,"1: MR_BackTraceStack.count != 0");

+

+            set_free(incomplete);

+            set_free(tokensUsed);

+

+            for (j=0 ; j <= CLL_k ; j++) { set_free(dup_matchSets[j]); };

+        };

+    };

+

+    fprintf(stdout,"\n");

+

+    MR_AmbSourceSearch=0;

+    MR_MaintainBackTrace=0;

+    MR_AmbSourceSearchGroup=0;

+    MR_AmbSourceSearchChoice=0;

+    MR_AmbSourceSearchLimit=0;

+

+    fset=save_fset;

+    free ( (char *) dup_matchSets);

+}

+

+static int itemCount;

+

+void MR_backTraceDumpItemReset() {

+  itemCount=0;

+}

+

+#ifdef __USE_PROTOS

+void MR_backTraceDumpItem(FILE *f,int skip,Node *n)

+#else

+void MR_backTraceDumpItem(f,skip,n)

+  FILE      *f;

+  int       skip;

+  Node      *n;

+#endif

+{

+  TokNode       *tn;

+  RuleRefNode   *rrn;

+  Junction      *j;

+  ActionNode    *a;

+

+  switch (n->ntype) {

+    case nToken:

+        itemCount++; if (skip) goto EXIT;

+        tn=(TokNode *)n;

+        if (set_nil(tn->tset)) {

+          fprintf(f,"  %2d #token %-23s",itemCount,TerminalString(tn->token));

+        } else {

+          fprintf(f,"  %2d #tokclass %-20s",itemCount,TerminalString(tn->token));

+        };

+        break;

+    case nRuleRef:

+        itemCount++; if (skip) goto EXIT;

+        rrn=(RuleRefNode *)n;

+        fprintf(f,"  %2d to %-27s",itemCount,rrn->text);

+        break;

+    case nAction:

+        a=(ActionNode *)n;

+        goto EXIT;

+    case nJunction:

+

+      j=(Junction *)n;

+

+      switch (j->jtype) {

+        case aSubBlk:

+            if (j->guess) {

+              itemCount++; if (skip) goto EXIT;

+              fprintf(f,"  %2d %-30s",itemCount,"in (...)? block at");

+              break;

+            };

+/******     fprintf(f,"  %2d %-32s",itemCount,"in (...) block at");  *******/

+/******     break;                                                          *******/

+            goto EXIT;

+        case aOptBlk:

+            itemCount++; if (skip) goto EXIT;

+            fprintf(f,"  %2d %-30s",itemCount,"in {...} block");

+            break;

+        case aLoopBlk:

+            itemCount++; if (skip) goto EXIT;

+            fprintf(f,"  %2d %-30s",itemCount,"in (...)* block");

+            break;

+        case EndBlk:

+            if (j->alpha_beta_guess_end) {

+              itemCount++; if (skip) goto EXIT;

+              fprintf(f,"  %2d %-30s",itemCount,"end (...)? block at");

+              break;

+            };

+            goto EXIT;

+/******     fprintf(f,"  %2d %-32s",itemCount,"end of a block at");     *****/

+/******     break;                                                             *****/

+        case RuleBlk:

+            itemCount++; if (skip) goto EXIT;

+            fprintf(f,"  %2d %-30s",itemCount,j->rname);

+            break;

+        case Generic:

+            goto EXIT;

+        case EndRule:

+            itemCount++; if (skip) goto EXIT;

+            fprintf (f,"  %2d end %-26s",itemCount,j->rname);

+            break;

+        case aPlusBlk:

+            itemCount++; if (skip) goto EXIT;

+            fprintf(f,"  %2d %-30s",itemCount,"in (...)+ block");

+            break;

+        case aLoopBegin:

+            goto EXIT;

+      };

+      break;

+  };

+  fprintf(f," %-23s line %-4d  %s\n",MR_ruleNamePlusOffset(n),n->line,FileStr[n->file]);

+EXIT:

+  return;

+}

+

+

+static PointerStack     previousBackTrace={0,0,NULL};

+

+#ifdef __USE_PROTOS

+void MR_backTraceReport(void)

+#else

+void MR_backTraceReport()

+#endif

+{

+  int       i;

+  int       match = 0;

+  int       limitMatch;

+

+  Node      *p;

+  TokNode   *tn;

+  set       remainder;

+  int       depth;

+

+  /* Even when doing a k=2 search this routine can get

+       called when there is only 1 token on the stack.

+     This is because something like rRuleRef can change

+       the search value of k from 2 to 1 temporarily.

+     It does this because the it wants to know the k=1

+       first set before it does a k=2 search

+  */

+

+  depth=0;

+  for (i=0; i < MR_BackTraceStack.count ; i++) {

+    p=(Node *) MR_BackTraceStack.data[i];

+    if (p->ntype == nToken) depth++;

+  };

+

+/* MR14 */  if (MR_AmbSourceSearch) {

+/* MR14 */     require (depth <= MR_AmbSourceSearchLimit,"depth > MR_AmbSourceSearchLimit");

+/* MR14 */  }

+

+  /* MR23 THM - Traceback report was being called at the wrong time for -alpha reports */

+  /*            Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu)                  */

+

+  if (MR_AmbSourceSearchLimit == 0 || depth < MR_AmbSourceSearchLimit) {

+    return;

+  };

+

+  MR_backTraceDumpItemReset();

+

+  limitMatch=MR_BackTraceStack.count;

+  if (limitMatch > previousBackTrace.count) {

+    limitMatch=previousBackTrace.count;

+  };

+

+  for (match=0; match < limitMatch; match++) {

+    if (MR_BackTraceStack.data[match] !=

+        previousBackTrace.data[match]) {

+      break;

+    };

+  };

+

+  /* not sure at the moment why there would be duplicates */

+

+  if (match != MR_BackTraceStack.count) {

+

+    fprintf(stdout,"     Choice:%d  Depth:%d  Group:%d",

+        (MR_AmbSourceSearchChoice+1),

+        MR_AmbSourceSearchLimit,

+        ++MR_AmbSourceSearchGroup);

+

+    depth=0;

+    fprintf(stdout,"  (");

+    for (i=0; i < MR_BackTraceStack.count ; i++) {

+      p=(Node *) MR_BackTraceStack.data[i];

+      if (p->ntype != nToken) continue;

+      tn=(TokNode *)p;

+      if (depth != 0) fprintf(stdout," ");

+      fprintf(stdout,TerminalString(tn->token));

+      depth++;

+      if (! MR_AmbAidMultiple) {

+        if (set_nil(tn->tset)) {

+          set_rm( (unsigned) tn->token,fset[depth]);

+        } else {

+          remainder=set_dif(fset[depth],tn->tset);

+          set_free(fset[depth]);

+          fset[depth]=remainder;

+        };

+      };

+    };

+    fprintf(stdout,")\n");

+

+    for (i=0; i < MR_BackTraceStack.count ; i++) {

+      MR_backTraceDumpItem(stdout, (i<match) ,(Node *) MR_BackTraceStack.data[i]);

+    };

+    fprintf(stdout,"\n");

+    fflush(stdout);

+

+    MR_pointerStackReset(&previousBackTrace);

+

+    for (i=0; i < MR_BackTraceStack.count ; i++) {

+      MR_pointerStackPush(&previousBackTrace,MR_BackTraceStack.data[i]);

+    };

+

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_setConstrainPointer(set * newConstrainValue)

+#else

+void MR_setConstrainPointer(newConstrainValue)

+  set * newConstrainValue;

+#endif

+{

+	constrain=newConstrainValue;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/gen.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/gen.c
new file mode 100644
index 0000000..368a96b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/gen.c
@@ -0,0 +1,4797 @@
+/*

+ * gen.c

+ *

+ * Generate C code (ANSI, K&R, C++)

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <ctype.h>

+#include "pcctscfg.h"

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+

+#define NumExprPerLine	4

+static int on1line=0;

+static set tokensRefdInBlock;

+

+					/* T r a n s l a t i o n  T a b l e s */

+

+/* C_Trans[node type] == pointer to function that knows how to translate that node. */

+#ifdef __cplusplus

+void (*C_Trans[NumNodeTypes+1])(...) = {

+	NULL,

+	NULL,					/* See next table.

+Junctions have many types */

+	(void (*)(...)) genRuleRef,

+	(void (*)(...)) genToken,

+	(void (*)(...)) genAction

+ };

+#else

+void (*C_Trans[NumNodeTypes+1])() = {

+	NULL,

+	NULL,					/* See next table.

+Junctions have many types */

+	genRuleRef,

+	genToken,

+	genAction

+ };

+#endif

+

+/* C_JTrans[Junction type] == pointer to function that knows how to translate that

+ * kind of junction node.

+ */

+#ifdef __cplusplus

+void (*C_JTrans[NumJuncTypes+1])(...) = {

+	NULL,

+	(void (*)(...)) genSubBlk,

+	(void (*)(...)) genOptBlk,

+	(void (*)(...)) genLoopBlk,

+	(void (*)(...)) genEndBlk,

+	(void (*)(...)) genRule,

+	(void (*)(...)) genJunction,

+	(void (*)(...)) genEndRule,

+	(void (*)(...)) genPlusBlk,

+	(void (*)(...)) genLoopBegin

+ };

+#else

+void (*C_JTrans[NumJuncTypes+1])() = {

+	NULL,

+	genSubBlk,

+	genOptBlk,

+	genLoopBlk,

+	genEndBlk,

+	genRule,

+	genJunction,

+	genEndRule,

+	genPlusBlk,

+	genLoopBegin

+ };

+#endif

+

+#define PastWhiteSpace(s)	while (*(s) == ' ' || *(s) == '\t') {s++;}

+

+static int tabs = 0;

+

+/* MR6	Got tired of text running off page when using standard tab stops */

+

+#define TAB { int i; 					                		\

+	      if (TabWidth==0) { 					                \

+	         for (i=0; i<tabs; i++) fputc('\t', output);		                \

+	      } else {           							\

+		 for (i=0; i<tabs*TabWidth; i++) fputc(' ',output);     	        \

+	      };	                						\

+	    }

+

+static void

+#ifdef __USE_PROTOS

+tab( void )

+#else

+tab( )

+#endif

+TAB

+

+#ifdef __USE_PROTOS

+static char *tokenFollowSet(TokNode *);

+static ActionNode *findImmedAction( Node * );

+static void dumpRetValAssign(char *, char *, RuleRefNode *);		/* MR30 */

+static void dumpAfterActions(FILE *output);

+static set ComputeErrorSet(Junction *, int, int);

+static void makeErrorClause(Junction *, set, int, int);

+static void DumpFuncHeader( Junction *, RuleEntry * );

+static int has_guess_block_as_first_item(Junction *);

+static int genExprSets(set *, int);

+static void genExprTree( Tree *t, int k );

+static void genExprTreeOriginal( Tree *t, int k );                  /* MR10 */

+static char * findOuterHandlerLabel(ExceptionGroup *eg);            /* MR7 */

+static void OutLineInfo(FILE *file,int line,char *fileName);        /* MR14 */

+#else

+static char *tokenFollowSet();

+static ActionNode *findImmedAction();

+static void dumpRetValAssign();

+static void dumpAfterActions();

+static set ComputeErrorSet();

+static void makeErrorClause();

+static void DumpFuncHeader();

+static int has_guess_block_as_first_item();

+static int genExprSets();

+static void genExprTree();

+static void genExprTreeOriginal();                                  /* MR10 */

+static char * findOuterHandlerLabel();                              /* MR7 */

+static void OutLineInfo();                                          /* MR14 */

+#endif

+

+#define gen(s)			{tab(); fprintf(output, s);}

+#define gen1(s,a)		{tab(); fprintf(output, s,a);}

+#define gen2(s,a,b)		{tab(); fprintf(output, s,a,b);}

+#define gen3(s,a,b,c)	{tab(); fprintf(output, s,a,b,c);}

+#define gen4(s,a,b,c,d)	{tab(); fprintf(output, s,a,b,c,d);}

+#define gen5(s,a,b,c,d,e)	{tab(); fprintf(output, s,a,b,c,d,e);}

+#define gen6(s,a,b,c,d,e,f)	{tab(); fprintf(output, s,a,b,c,d,e,f);}

+#define gen7(s,a,b,c,d,e,f,g)	{tab(); fprintf(output, s,a,b,c,d,e,f,g);}

+

+#define _gen(s)			{fprintf(output, s);}

+#define _gen1(s,a)		{fprintf(output, s,a);}

+#define _gen2(s,a,b)	{fprintf(output, s,a,b);}

+#define _gen3(s,a,b,c)	{fprintf(output, s,a,b,c);}

+#define _gen4(s,a,b,c,d){fprintf(output, s,a,b,c,d);}

+#define _gen5(s,a,b,c,d,e){fprintf(output, s,a,b,c,d,e);}

+#define _gen6(s,a,b,c,d,e,f){fprintf(output, s,a,b,c,d,e,f);}

+#define _gen7(s,a,b,c,d,e,f,g){fprintf(output, s,a,b,c,d,e,f,g);}

+

+

+/* MR11 a convenient place to set a break point */

+

+#ifdef __USE_PROTOS

+void MR_break(void) 

+#else

+void MR_break() 

+#endif

+{

+  return;

+}

+

+/* MR10 genTraceOut(Junction *)      */

+

+#ifdef __USE_PROTOS

+static void genTraceOut(Junction *q)

+#else

+static void genTraceOut(q)

+  Junction  *q;

+#endif

+{

+  if ( TraceGen ) {

+		if ( GenCC ) {gen1("zzTRACEOUT(\"%s\");\n", q->rname);}

+    		else gen1("zzTRACEOUT((ANTLRChar *)\"%s\");\n", q->rname);

+  }

+}

+

+static void

+#ifdef __USE_PROTOS

+warn_about_using_gk_option(void)

+#else

+warn_about_using_gk_option()

+#endif

+{

+	static int warned_already=0;

+

+	if ( !DemandLookahead || warned_already ) return;

+	warned_already = 1;

+	warnNoFL("-gk option could cause trouble for <<...>>? predicates");

+}

+

+void

+#ifdef __USE_PROTOS

+freeBlkFsets( Junction *q )

+#else

+freeBlkFsets( q )

+Junction *q;

+#endif

+{

+	int i;

+	Junction *alt;

+	require(q!=NULL, "freeBlkFsets: invalid node");

+

+	for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )

+	{

+		for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]);

+	}

+}

+

+/*

+ * Generate a local variable allocation for each token references

+ * in this block.

+ */

+static void

+#ifdef __USE_PROTOS

+genTokenPointers( Junction *q )

+#else

+genTokenPointers( q )

+Junction *q;

+#endif

+{

+	/* Rule refs are counted and can be referenced, but their

+	 * value is not set to anything useful ever.

+	 *

+     * The ptrs are to be named _tij where i is the current level

+	 * and j is the element number within an alternative.

+	 */

+	int first=1, t=0;

+	set a;

+	tokensRefdInBlock = q->tokrefs;

+

+	if ( set_deg(q->tokrefs) == 0 ) return;

+	a = set_dup(q->tokrefs);

+	gen("ANTLRTokenPtr ");

+	for (; !set_nil(a); set_rm(t, a))

+	{

+		t = set_int(a);

+		if ( first ) first = 0;

+		else _gen(",");

+		if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t);

+		_gen2("_t%d%d", BlkLevel, t);

+		if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);}

+		else _gen("=NULL");

+	}

+	_gen(";\n");

+	set_free(a);

+}

+

+static int

+#ifdef __USE_PROTOS

+hasDefaultException(ExceptionGroup *eg)

+#else

+hasDefaultException(eg)

+ExceptionGroup *eg;

+#endif

+{

+    ListNode *q;

+

+    for (q = eg->handlers->next; q!=NULL; q=q->next)

+    {

+        ExceptionHandler *eh = (ExceptionHandler *)q->elem;

+        if ( strcmp("default", eh->signalname)==0 ) {

+            return 1;

+        }

+    }

+    return 0;

+}

+static void

+#ifdef __USE_PROTOS

+dumpException(ExceptionGroup *eg, int no_default_case)

+#else

+dumpException(eg, no_default_case)

+ExceptionGroup *eg;

+int no_default_case;

+#endif

+{

+    char    *outerLabel;                                             /* MR7 */

+    int     altHandler=0;                                            /* MR7 */

+    int     namedHandler=0;                                          /* MR7 */

+

+    outerLabel=findOuterHandlerLabel(eg);                            /* MR7 */

+

+    if (eg->label != NULL) {                                         /* MR7 */

+      namedHandler=1;                                                /* MR7 */

+    } else if (eg->forRule) {                                        /* MR7 */

+      /* nothing */                                                  /* MR20 */

+    } else {                                                         /* MR7 */

+      altHandler=1;                                                  /* MR7 */

+    };                                                               /* MR7 */

+

+#if 0

+**     if (! eg->used) {                                             /* MR7 */

+**     	warnFL("exception group never used",                         /* MR7 */

+**             FileStr[eg->altstart->file],eg->altstart->line);      /* MR7 */

+**     };                                                            /* MR7 */

+#endif

+

+    if (namedHandler) {                                              /* MR7 */

+	  gen1("switch ( _signal ) {  /* [%s] */\n",eg->label);          /* MR7 */

+    } else {                                                         /* MR7 */

+	  gen("switch ( _signal ) {\n");                                 /* MR7 */

+      gen("case NoSignal: break;  /* MR7 */\n");                     /* MR7 */

+    };                                                               /* MR7 */

+	{

+		ListNode *q;

+		for (q = eg->handlers->next; q!=NULL; q=q->next)

+		{

+			ExceptionHandler *eh = (ExceptionHandler *)q->elem;

+			if ( strcmp("default", eh->signalname)==0 ) {

+				gen("default :\n");

+				tabs++;

+				dumpAction(eh->action, output, tabs, -1, 1, 1);

+                gen("_signal=NoSignal;  /* MR7 */\n");                  /* MR7 */

+                gen("break;  /* MR7 */\n");                             /* MR7 */

+				tabs--;

+				gen("}\n");

+

+                /* copied from later code in dumpException */        /* MR7 */

+

+                if (namedHandler) {                                  /* MR7 */

+                  gen("if (_signal != NoSignal)");                   /* MR7 */

+                  _gen1(" goto %s_handler;  /* MR7 */\n",outerLabel);/* MR7 */

+                } else if (altHandler) {                             /* MR7 */

+                  gen1("goto %s_handler;  /* MR7 */\n",outerLabel);  /* MR7 */

+                };

+				return;

+			}

+			gen1("case %s :\n", eh->signalname);

+			tabs++;

+			if ( eh->action != NULL )

+			{

+				dumpAction(eh->action, output, tabs, -1, 1, 1);

+                gen("break;  /* MR7 */\n");                          /* MR7 */

+			}

+			tabs--;

+		}

+	}

+	if ( no_default_case ) return;

+

+	gen("default :\n");

+    tabs++;                                                         /* MR7 */

+    gen("break;  /* MR7 */\n");                                     /* MR7 */

+    tabs--;                                                         /* MR7 */

+

+	tabs++;

+/*****	gen("*_retsignal = _signal;\n"); *****/

+

+	tabs--;

+	gen("}\n");

+

+    if (namedHandler) {                                             /* MR7 */

+      gen("if (_signal != NoSignal)");                              /* MR7 */

+      _gen1(" goto %s_handler;  /* MR7 */\n",outerLabel);           /* MR7 */

+    } else if (altHandler) {                                        /* MR7 */

+      gen1("goto %s_handler;  /* MR7 */\n",outerLabel);             /* MR7 */

+    };

+

+}

+

+static void

+#ifdef __USE_PROTOS

+dumpExceptions(ListNode *list)

+#else

+dumpExceptions(list)

+ListNode *list;

+#endif

+{

+	ListNode *p;

+

+	for (p = list->next; p!=NULL; p=p->next)

+	{

+		ExceptionGroup *eg = (ExceptionGroup *) p->elem;

+		_gen2("%s%s_handler:\n",

+			  eg->label==NULL?"":eg->label,

+			  eg->altID==NULL?"":eg->altID);

+		if ( eg->altID!=NULL ) dumpException(eg, 0);

+		else {

+			/* This must be the rule exception handler */

+			dumpException(eg, 1);

+			if ( !hasDefaultException(eg) )

+            {

+                gen("default :\n");

+                tabs++;

+                gen("zzdflthandlers(_signal,_retsignal);\n");

+                tabs--;

+                gen("}\n");

+            }

+		}

+	}

+}

+

+/* For each element label that is found in a rule, generate a unique

+ * Attribute (and AST pointer if GenAST) variable.

+ */

+void

+#ifdef __USE_PROTOS

+genElementLabels(ListNode *list)

+#else

+genElementLabels(list)

+ListNode *list;

+#endif

+{

+	int first=1;

+	ListNode *p;

+

+	if ( GenCC ) {gen("ANTLRTokenPtr");}

+	else {gen("Attrib");}

+	for (p = list->next; p!=NULL; p=p->next)

+	{

+		char *ep = (char *)p->elem;

+		if ( first ) first = 0;

+		else _gen(",");

+		if ( GenCC ) {_gen1(" %s=NULL",ep);}

+		else {_gen1(" %s",ep);}

+	}

+	_gen(";\n");

+

+	if ( !GenAST ) return;

+

+	first = 1;

+	gen("AST");

+	for (p = list->next; p!=NULL; p=p->next)

+	{

+		char *ep = (char *)p->elem;

+		if ( first ) first = 0;

+		else _gen(",");

+		_gen1(" *%s_ast=NULL",ep);

+	}

+	_gen(";\n");

+}

+

+/*

+ * Generate a local variable allocation for each token or rule reference

+ * in this block.

+ */

+static void

+#ifdef __USE_PROTOS

+genASTPointers( Junction *q )

+#else

+genASTPointers( q )

+Junction *q;

+#endif

+{

+	int first=1, t;

+	set a;

+

+	a = set_or(q->tokrefs, q->rulerefs);

+	if ( set_deg(a) > 0 )

+	{

+		gen("AST ");

+		for (; !set_nil(a); set_rm(t, a))

+		{

+			t = set_int(a);

+			if ( first ) first = 0;

+			else _gen(",");

+			_gen2("*_ast%d%d=NULL", BlkLevel, t);

+		}

+		set_free(a);

+	}

+	_gen(";\n");

+}

+

+static void

+#ifdef __USE_PROTOS

+BLOCK_Head( void )

+#else

+BLOCK_Head( )

+#endif

+{

+	gen("{\n");

+	tabs++;

+	if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel);

+}

+

+static void

+#ifdef __USE_PROTOS

+BLOCK_Tail( void )

+#else

+BLOCK_Tail( )

+#endif

+{

+	if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel);

+	if ( !GenCC ) gen("}\n");

+	tabs--;

+	gen("}\n");

+}

+

+static void

+#ifdef __USE_PROTOS

+BLOCK_Preamble( Junction *q )

+#else

+BLOCK_Preamble( q )

+Junction *q;

+#endif

+{

+	ActionNode *a;

+	Junction *begin;

+

+	BLOCK_Head();

+	if ( GenCC ) genTokenPointers(q);

+	if ( GenCC&&GenAST ) genASTPointers(q);

+	if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;\n");

+	if ( q->parm != NULL && !q->predparm ) gen1("zzaPush(%s);\n", q->parm)

+	else if ( !GenCC ) gen("zzMake0;\n");

+	if ( !GenCC ) gen("{\n");

+	if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1);

+	else begin = q;

+	if ( has_guess_block_as_first_item(begin) )

+	{

+		gen("zzGUESS_BLOCK\n");

+	}

+	if ( q->jtype == aLoopBegin )

+		a = findImmedAction( ((Junction *)q->p1)->p1 );	/* look at aLoopBlk */

+	else

+		a = findImmedAction( q->p1 );

+	if ( a!=NULL && !a->is_predicate) {

+/* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1);

+		   a->done = 1;	/* remove action. We have already handled it */

+	}

+}

+

+void

+#ifdef __USE_PROTOS

+genCombinedPredTreeContextOrig( Predicate *p )

+#else

+genCombinedPredTreeContextOrig( p )

+Predicate *p;

+#endif

+{

+	static set *ctx=NULL;		/* genExprSets() is destructive, make copy*/

+	require(p!=NULL, "can't make context tree for NULL pred tree");

+

+#ifdef DBG_PRED

+	fprintf(stderr, "enter genCombinedPredTreeContextOrig(%s,0x%x) with sets:\n", p->expr, p);

+	s_fprT(stderr, p->scontext[1]);

+	fprintf(stderr, "\n");

+#endif

+	if ( p->down == NULL )

+	{

+/***	if ( p->k>1 && p->tcontext!=NULL ) ***/

+		if ( p->tcontext!=NULL )

+		{

+			_gen("(");

+			genExprTree(p->tcontext, 1);

+			_gen(")");

+		}

+/***	else if ( p->k==1 && set_deg(p->scontext[1])>0 ) ***/

+		else if ( set_deg(p->scontext[1])>0 )

+		{

+			if ( ctx==NULL ) ctx = (set *)calloc(CLL_k+1, sizeof(set));

+			require(ctx!=NULL, "ctx cannot allocate");

+			ctx[0]=empty;

+			ctx[1]=set_dup(p->scontext[1]);

+			_gen("(");

+			genExprSets(&(ctx[0]), p->k);

+			_gen(")");

+			set_free(ctx[1]);

+		}

+		else if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) {

+			fatal_internal("pred tree is orphan OR or AND list");

+		}

+		else {

+            if (! HoistPredicateContext) {

+              _gen(" 1 /* no context: prc is off */ ");

+            } else {

+              fatal_internal("pred tree context is empty");

+            };

+		}

+		return;

+	}

+

+/* MR10 - make AND just like OR */

+

+	if ( p->expr == PRED_AND_LIST )

+	{

+        Predicate *list = p->down;

+        for (; list!=NULL; list=list->right)

+        {

+     	     genCombinedPredTreeContextOrig(list);

+       		 if ( list->right!=NULL ) _gen("|| /* MR10 was wrong */ ");

+        };

+		return;

+	}

+

+	if ( p->expr == PRED_OR_LIST )

+	{

+        Predicate *list = p->down;

+        for (; list!=NULL; list=list->right)

+        {

+           genCombinedPredTreeContextOrig(list);

+           if ( list->right!=NULL ) _gen("||");

+        };

+        return;

+     };

+

+	fatal("pred tree is really wacked");

+}

+

+/* [genCombinedPredTreeContext] */

+

+void

+#ifdef __USE_PROTOS

+genCombinedPredTreeContext( Predicate *p )

+#else

+genCombinedPredTreeContext( p )

+Predicate *p;

+#endif

+{

+  Tree  *t;

+  int   predDepth=0;

+

+  if (0 && ! MR_usingPredNames && ! MRhoisting) {

+    genCombinedPredTreeContextOrig(p);

+  } else {

+/* MR13 */    MR_pred_depth(p,&predDepth);

+/* MR13 */    if (predDepth == 1) {

+/* MR13 */

+/* MR13 */      set   scontext[2];

+/* MR13 */      scontext[0]=empty;

+/* MR13 */      scontext[1]=MR_compute_pred_set(p);

+/* MR13 */      if (set_nil(scontext[1])) {

+/* MR13 */        _gen(" 1 /* MR12 no context (-prc off) */ ");

+/* MR13 */      } else {

+/* MR13 */        _gen("(");

+/* MR13 */        genExprSets(&scontext[0], 1);

+/* MR13 */        set_free(scontext[1]);

+/* MR13 */        _gen(")");

+/* MR13 */      };

+

+    } else {

+      t=MR_compute_pred_tree_context(p);

+      if (t == NULL) {

+        _gen(" 1 /* MR12 no context (-prc off) */ ");

+      } else {

+        _gen("(");

+        genExprTree(t, 1);

+        Tfree(t);   /* MR10 */

+        _gen(")");

+      };

+    };

+  };

+}

+

+/* [genPredTreeGate] */

+

+void

+#ifdef __USE_PROTOS

+genPredTreeGate( Predicate *p, int in_and_expr )

+#else

+genPredTreeGate( p, in_and_expr )

+Predicate *p;

+int in_and_expr;

+#endif

+{

+	if ( in_and_expr )

+	{

+		_gen("!(");

+		genCombinedPredTreeContext(p);

+		_gen(")||");

+		if ( p->down!=NULL ) _gen("\n");

+	}

+	else

+	{

+		_gen("(");

+		genCombinedPredTreeContext(p);

+		_gen(")&&");

+		if ( p->down!=NULL ) _gen("\n");

+	}

+}

+

+#ifdef __USE_PROTOS

+void genPredEntry(Predicate *p,int outer)

+#else

+void genPredEntry(p,outer)

+  Predicate     *p;

+  int           outer;

+#endif

+{

+    int         inverted=0;

+    Predicate   *q;

+    int         localOuter=outer;

+    int         needRP=0;

+

+    if (p == NULL) return;

+

+    if (p->predEntry != NULL && p->predEntry->predLiteral != NULL) {

+      if (p->inverted != p->predEntry->pred->inverted) {

+        _gen("! /* inverted pred */ (");

+        needRP=1;

+      } else {

+        if (!localOuter) _gen("(");

+        needRP=1;

+      };

+      dumpAction(p->predEntry->predLiteral,output,0,p->source->file,p->source->line,0);

+      if (needRP) _gen(")");

+      return;

+    };

+

+    inverted=p->inverted;

+

+    if (inverted) {

+      _gen(" ! /* inverted pred */ (");

+      localOuter=1;

+    };

+

+    if (p->expr == PRED_OR_LIST) {

+      if (!localOuter) _gen("(");

+      for (q=p->down; q != NULL ; q=q->right) {

+        genPredEntry(q,0);

+        if (q->right != NULL) _gen(" || ");

+      };

+      if (!localOuter) _gen(")");

+    } else if (p->expr == PRED_AND_LIST) {

+      if (!localOuter) _gen("(");

+      for (q=p->down; q != NULL ; q=q->right) {

+        genPredEntry(q,0);

+        if (q->right != NULL) _gen(" && ");

+      };

+      if (!localOuter) _gen(")");

+    } else {

+      if (!localOuter) _gen("(");

+      require (p->source != NULL,"predEntry->source == NULL");

+      require (p->source->inverted == 0,"dumpPredEntry p->source->inverted != 0");

+      dumpAction(p->source->action,output,0,p->source->file,p->source->line,0);

+      if (!localOuter) _gen(")");

+    };

+

+    if (inverted) {

+        _gen(")");

+    }

+}

+

+void

+#ifdef __USE_PROTOS

+dumpPredAction(ActionNode *anode,

+                    char *s,FILE *output,int tabs,int file,int line,int final_newline)

+#else

+dumpPredAction(anode,

+                    s,output,tabs,file,line,final_newline)

+

+    ActionNode  *anode;

+    char        *s;

+    FILE        *output;

+    int         tabs;

+    int         file;

+    int         line;

+    int         final_newline;

+#endif

+{

+    PredEntry   *predEntry=anode->predEntry;

+    int         inverted=anode->inverted;

+    Predicate   *workPred;

+

+    if (predEntry == NULL) {

+

+      /* inline predicate literal */

+

+      require(inverted == 0,"dumpPredAction action->inverted");

+  	  dumpAction(s,output,tabs,file,line,final_newline);

+

+    } else {

+

+      /* a reference to a predicate - possibly with an inverted source */

+

+      if (predEntry->predLiteral != NULL) {

+        if (inverted) _gen("! /* inverted pred */ (");

+        dumpAction(predEntry->predLiteral,output,0,anode->file,anode->line,0);

+        if (inverted) _gen(")");

+      } else {

+        workPred=predicate_dup(predEntry->pred);

+        if (inverted) workPred->inverted=!workPred->inverted;

+        genPredEntry(workPred,1);

+        predicate_free(workPred);

+      };

+    };

+}

+

+/* [genPred] */

+

+void

+#ifdef __USE_PROTOS

+genPred(Predicate *p, Node *j,int suppress_sva)

+#else

+genPred(p,j,suppress_sva)

+    Predicate   *p;

+    Node        *j;

+    int         suppress_sva;

+#endif

+{

+	if ( FoundException && !suppress_sva) {_gen("(_sva=(");}    /* MR11 suppress_sva */

+	else {_gen("(");}

+	if ( GenLineInfo && j->file != -1 ) _gen("\n");

+    if (p->source != NULL && p->source->ampersandPred != NULL) {

+      if (p->source->ampersandPred->k == 1) {

+

+            set     ctx[2];

+

+			ctx[0]=empty;

+			ctx[1]=set_dup(p->source->ampersandPred->scontext[1]);

+

+			_gen("(");

+			genExprSets(&(ctx[0]), p->k);

+			_gen(") && ");

+			set_free(ctx[1]);

+      } else {

+        _gen("( ");

+        genExprTree(p->source->ampersandPred->tcontext,1);

+		_gen(" ) && ");

+      };

+    };

+

+    dumpPredAction((ActionNode *)p->source,

+                p->expr, output, 0, -1 /*indicates no line info*/, j->line, 0);

+

+	if ( FoundException && !suppress_sva)   /* MR11 suppress_sva */

+         {_gen("),_sva)");}    /* MR10 - get red of "meant ==" messages */

+	else {_gen(")");}

+}

+

+void

+#ifdef __USE_PROTOS

+MR_distinctORcontextOpt(Predicate *p,Node *j,int in_and_expr)

+#else

+MR_distinctORcontextOpt(p,j,in_and_expr)

+    Predicate   *p;

+    Node        *j;

+    int         in_and_expr;

+#endif

+{

+    Predicate   *q;

+

+    _gen(" /* MR10 Distinct OR context optimization */ \n");

+

+    if (in_and_expr) {

+      gen("zzpf=0,\n");

+      for (q=p->down; q != NULL; q=q->right) {

+        gen("(  ");

+        genCombinedPredTreeContext(q);

+        _gen(" && (zzpf=1, ");

+        genPred(q,j,0);

+        _gen("  )) ||\n");

+      };

+      gen("!zzpf)");

+    } else {

+      require (0,

+            "MR_distinctORcontextOpt: can't get here when using MR_predSimplify");

+#if 0

+**      for (q=p->down; q != NULL; q=q->right) {

+**        gen("(  ");

+**        genCombinedPredTreeContext(q);

+**        _gen(" && ");

+**        genPred(q,j);

+**        if (q->right != NULL) {

+**          _gen("  ) ||\n");

+**        };

+**      };

+**      gen(")");

+#endif

+   };

+}

+

+void

+#ifdef __USE_PROTOS

+genPredTreeOrig( Predicate *p, Node *j, int in_and_expr )

+#else

+genPredTreeOrig( p, j, in_and_expr )

+Predicate *p;

+Node *j;

+int in_and_expr;

+#endif

+{

+

+/* MR10 */  int     allHaveContext=1;

+/* MR10 */  int     noneHaveContext=1;

+

+/* MR10 */  MR_predContextPresent(p,&allHaveContext,&noneHaveContext);

+

+	if ( ! noneHaveContext )                  /* MR10 context guards ignored when -prc off */

+	{

+		_gen("(");

+		genPredTreeGate(p, in_and_expr);

+	}

+

+	/* if leaf node, just gen predicate */

+

+	if ( p->down==NULL )

+	{

+		genPred(p,j,0);

+		if ( ! noneHaveContext ) _gen(")");   /* MR10 context guards ignored when -prc off */

+		return;

+	}

+

+	/* if AND list, do both preds (only two possible) */

+	if ( p->expr == PRED_AND_LIST )

+	{

+#if 0

+**		_gen("(");

+**		genPredTreeOrig(p->down, j, 1);

+**		_gen("&&");

+**		genPredTreeOrig(p->down->right, j, 1);

+**		_gen(")");

+**		if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */

+**		return;

+#endif

+        /* MR11 - make it work with AND with more than two children - like OR */

+

+		Predicate *list;

+		_gen("(");

+		list = p->down;

+		for (; list!=NULL; list=list->right)

+		{

+			genPredTreeOrig(list, j, 1);

+			if ( list->right!=NULL ) _gen("&&");

+		}

+		_gen(")");

+		if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */

+		return;

+    };

+

+	if ( p->expr == PRED_OR_LIST )

+	{

+		Predicate *list;

+		_gen("(");

+		list = p->down;

+		for (; list!=NULL; list=list->right)

+		{

+			genPredTreeOrig(list, j, 0);

+			if ( list->right!=NULL ) _gen("||");

+		}

+		_gen(")");

+		if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */

+		return;

+	}

+

+	fatal_internal("genPredTreeOrig: predicate tree is wacked");

+}

+

+#if 0

+**   Predicate member dummyPredDepth is no longer used in MR10

+**     but we might need it again in the future

+**

+**   if (MRhoisting) {

+**     if ( !noneHaveContext &&

+**          ! in_and_expr &&

+**          p->source != NULL &&

+**          p->source->dummyPredicateDepth > 0 &&

+**          p->down == NULL) {

+** 		_gen("(");

+** 		genCombinedPredTreeContext(p);

+** 		_gen("  )\n");

+** 		return;

+**     };

+**   };

+#endif

+

+/* [genPredTree] */

+

+/* in_and_expr

+

+   what to do if the context is wrong

+   what to do if the context is correct but the predicate is false

+

+   remember: if the context is wrong it's the same as if the

+             predicate is true as far as enabling an alternative

+

+        Consider (AND p q r)

+

+        if in an ... && ... expression then you don't want

+        the entire predicate chain to fail just because the

+        context for one component is wrong: so return true

+

+        Consider (OR p q r)

+

+        if in an ... || ... expression then you don't want

+        the entire predicate chain to succeed just because

+        the context for one component is correct when the

+        corresponding test is false: so return false when

+        the context is correct but the test is false.

+*/

+

+void

+#ifdef __USE_PROTOS

+genPredTree( Predicate *p, Node *j, int in_and_expr, int suppress_sva )

+#else

+genPredTree( p, j, in_and_expr, suppress_sva)

+  Predicate     *p;

+  Node          *j;

+  int           in_and_expr;

+  int           suppress_sva;

+#endif

+{

+

+    int         allHaveContext=1;

+    int         noneHaveContext=1;

+    Tree        *groupTree;

+    Tree        *oneTree;

+    Predicate   *q;

+    int         identicalORcontextOptimization=0;

+    int         identicalANDcontextOptimization=0;

+

+    if (0 && !MR_usingPredNames && !MRhoisting) {

+      genPredTreeOrig(p,j,in_and_expr);

+      return;

+    };

+

+    MR_predContextPresent(p,&allHaveContext,&noneHaveContext);

+

+	if ( ! noneHaveContext ) {                 /* MR10 context guards ignored when -prc off */

+

+      _gen("(");

+

+            /* MR10 optimize OR predicates which are all leaves */

+

+      if (p->expr == PRED_OR_LIST && MR_allPredLeaves(p->down)) {

+        groupTree=MR_compute_pred_tree_context(p);

+        for (q=p->down ; q != NULL ; q=q->right) {

+          oneTree=MR_compute_pred_tree_context(q);

+          if (! MR_tree_equ(groupTree,oneTree)) {

+            Tfree(oneTree);

+            break;

+          };

+          Tfree(oneTree);

+        };

+        Tfree(groupTree);

+        if (q == NULL) {

+          _gen("/* MR10 individual OR gates suppressed when all predicates are leaves");

+          _gen(" with identical context */\n");

+          genPredTreeGate(p,in_and_expr);   /* use the parent's in_and_expr for this gate */

+          identicalORcontextOptimization=1;

+        } else {

+          MR_distinctORcontextOpt(p,j,in_and_expr);

+          return;

+        };

+      } else if (p->expr == PRED_AND_LIST && MR_allPredLeaves(p->down)) {

+

+            /* MR12 optimize AND predicates which are all leaves */

+

+        groupTree=MR_compute_pred_tree_context(p);

+        for (q=p->down ; q != NULL ; q=q->right) {

+          oneTree=MR_compute_pred_tree_context(q);

+          if (! MR_tree_equ(groupTree,oneTree)) {

+            Tfree(oneTree);

+            break;

+          };

+          Tfree(oneTree);

+        };

+        Tfree(groupTree);

+        if (q == NULL) {

+          _gen("/* MR12 individual AND gates suppressed when all predicates are leaves");

+          _gen(" with identical context */\n");

+          genPredTreeGate(p,in_and_expr);   /* use the parent's in_and_expr for this gate */

+          identicalANDcontextOptimization=1;

+        } else {

+          genPredTreeGate(p, in_and_expr);

+        };

+      } else {

+  	    genPredTreeGate(p, in_and_expr);

+      };

+	}

+

+	/* if leaf node, just gen predicate */

+

+	if ( p->down==NULL )

+	{

+		genPred(p,j,suppress_sva);

+		if ( ! noneHaveContext ) _gen(")");   /* MR10 context guards ignored when -prc off */

+		return;

+	}

+

+	/* if AND list, do both preds (only two possible) */

+    /* MR10    not any more ! */

+

+	if ( p->expr == PRED_AND_LIST )

+	{

+		Predicate *list;

+		_gen("(");

+		list = p->down;

+        for (; list != NULL; list=list->right) {

+          if (identicalANDcontextOptimization) {

+            genPred(list, j,suppress_sva);

+          } else {

+	   	    genPredTree(list, j, 1, suppress_sva);  /* in and context */

+          };

+          if ( list->right!=NULL ) _gen("&&");

+        };

+		_gen(")");

+		if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */

+		return;

+	}

+

+	if ( p->expr == PRED_OR_LIST )

+	{

+		Predicate *list;

+		_gen("(");

+		list = p->down;

+		for (; list!=NULL; list=list->right)

+		{

+            if (identicalORcontextOptimization) {

+	          genPred(list, j,suppress_sva);

+            } else {

+	   	      genPredTree(list, j, 0, suppress_sva);

+            };

+			if ( list->right!=NULL ) _gen("||");

+		}

+		_gen(")");

+		if ( ! noneHaveContext ) _gen(")");    /* MR10 context guards ignored when -prc off */

+		return;

+	}

+

+	fatal_internal("predicate tree is wacked");

+}

+

+/* [genPredTreeMainXX] */

+

+Predicate *     /* MR10 */

+#ifdef __USE_PROTOS

+genPredTreeMainXX( Predicate *p, Node *j ,int in_and_expr)

+#else

+genPredTreeMainXX( p, j ,in_and_expr)

+    Predicate   *p;

+    Node        *j;

+    int         in_and_expr;

+#endif

+{

+

+    int     allHaveContext=1;

+    int     noneHaveContext=1;

+

+#if 0

+    fprintf(stderr,"Pred before\n");

+    dumppred(p);

+    fprintf(stderr,"\n");

+    fprintf(stderr,"Pred after\n");

+    dumppred(p);

+    fprintf(stderr,"\n");

+#endif

+

+    p=MR_predSimplifyALL(p);    /* MR10 */

+

+    require (MR_predicate_context_completed(p),"predicate context is not complete");

+

+    MR_cleanup_pred_trees(p);   /* MR10 */

+

+    MR_predContextPresent(p,&allHaveContext,&noneHaveContext);

+    if (!noneHaveContext & !allHaveContext) {

+      warnFL("predicate contains elements both with and without context",

+                FileStr[j->file],j->line);

+    };

+

+    if (InfoP) {

+       _gen("\n#if 0\n\n");

+       MR_dumpPred(p,1);

+       _gen("#endif\n");

+    };

+	genPredTree(p,j,in_and_expr,0);

+    return p;

+}

+

+Predicate *     /* MR10 */

+#ifdef __USE_PROTOS

+genPredTreeMain( Predicate *p, Node *j)

+#else

+genPredTreeMain( p, j)

+    Predicate   *p;

+    Node        *j;

+#endif

+{

+  return genPredTreeMainXX(p,j,1);

+}

+

+static void

+#ifdef __USE_PROTOS

+genExprTreeOriginal( Tree *t, int k )

+#else

+genExprTreeOriginal( t, k )

+Tree *t;

+int k;

+#endif

+{

+	require(t!=NULL, "genExprTreeOriginal: NULL tree");

+	

+	if ( t->token == ALT )

+	{

+		_gen("("); genExprTreeOriginal(t->down, k); _gen(")");

+		if ( t->right!=NULL )

+		{

+			_gen("||");

+			on1line++;

+			if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }

+			_gen("("); genExprTreeOriginal(t->right, k); _gen(")");

+		}

+		return;

+	}

+	if ( t->down!=NULL ) _gen("(");

+	_gen1("LA(%d)==",k);

+	if ( TokenString(t->token) == NULL ) _gen1("%d", t->token)

+	else _gen1("%s", TokenString(t->token));

+	if ( t->down!=NULL )

+	{

+		_gen("&&");

+		on1line++;

+		if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }

+		_gen("("); genExprTreeOriginal(t->down, k+1); _gen(")");

+	}

+	if ( t->down!=NULL ) _gen(")");

+	if ( t->right!=NULL )

+	{

+		_gen("||");

+		on1line++;

+		if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }

+		_gen("("); genExprTreeOriginal(t->right, k); _gen(")");

+	}

+}

+

+#ifdef __USE_PROTOS

+static void MR_LAtokenString(int k,int token)

+#else

+static void MR_LAtokenString(k,token)

+  int   k;

+  int   token;

+#endif

+{

+    char    *ts;

+

+    ts=TokenString(token);

+    if (ts == NULL) {

+      _gen2(" LA(%d)==%d",k,token);

+    } else {

+      _gen2(" LA(%d)==%s",k,ts);

+    };

+}

+

+

+#ifdef __USE_PROTOS

+static int MR_countLeaves(Tree *t)

+#else

+static int MR_countLeaves(t)

+  Tree  *t;

+#endif

+{

+  if (t == NULL) return 0;

+  if (t->token == ALT) {

+    return MR_countLeaves(t->down)+MR_countLeaves(t->right);

+  } else {

+    return 1+MR_countLeaves(t->down)+MR_countLeaves(t->right);

+  };

+}

+

+#ifdef __USE_PROTOS

+static void MR_genOneLine(Tree *tree,int k)

+#else

+static void MR_genOneLine(tree,k)

+  Tree      *tree;

+  int       k;

+#endif

+{

+    if (tree == NULL) return;

+    if (tree->token == ALT) {

+       MR_genOneLine(tree->down,k);

+    } else {

+       MR_LAtokenString(k,tree->token);

+       if (tree->down != NULL &&

+           tree->down->right == NULL) {

+          _gen(" &&");

+          MR_genOneLine(tree->down,k+1);

+       } else if (tree->down != NULL) {

+         _gen(" && (");

+         MR_genOneLine(tree->down,k+1);

+         _gen(")");

+       };

+    };

+    if (tree->right != NULL) {

+      _gen(" ||");

+      MR_genOneLine(tree->right,k);

+    };

+}

+

+static int across;

+static int depth;

+static int lastkonline;

+

+#ifdef __USE_PROTOS

+static void MR_genMultiLine(Tree *tree,int k)

+#else

+static void MR_genMultiLine(tree,k)

+  Tree  *tree;

+  int   k;

+#endif

+{

+    int     i;

+

+    if (tree == NULL) return;

+    if (tree->token == ALT) {

+      MR_genMultiLine(tree,k);

+    } else {

+      MR_LAtokenString(k,tree->token);

+      lastkonline=k;

+      across++;

+      if (tree->down != NULL && tree->down->right == NULL) {

+        if (across > 3) {

+          _gen("\n");

+          across=0;

+          lastkonline=0;

+          for (i=0 ; i < depth+k ; i++) _gen("   ");

+          _gen("&&");

+        } else {

+          _gen(" &&");

+        };

+        MR_genMultiLine(tree->down,k+1);

+      } else if (tree->down != NULL) {

+        _gen("\n");

+        lastkonline=0;

+        across=0;

+        for (i=0 ; i < depth+k ; i++) _gen("   ");

+        _gen("&& (");

+        MR_genMultiLine(tree->down,k+1);

+        _gen(")");

+      };

+    };

+    if (tree->right != NULL) {

+      if (k < lastkonline) {

+        _gen("\n");

+        across=0;

+        lastkonline=0;

+        for (i=0; i < depth+k-1 ; i++) _gen("   ");

+        _gen("||");

+      } else if (across > 3 ) {

+        _gen("\n");

+        across=0;

+        lastkonline=0;

+        for (i=0; i < depth+k ; i++) _gen("   ");

+        _gen("||");

+      } else {

+        _gen(" ||");

+      };

+      MR_genMultiLine(tree->right,k);

+    };

+}

+

+#ifdef __USE_PROTOS

+static void genExprTree(Tree *tree,int k)

+#else

+static void genExprTree(tree,k)

+  Tree  *tree;

+  int   k;

+#endif

+{

+    int     count;

+

+#if 0

+    /* MR20 THM This was probably an error.

+            The routine should probably reference that static 

+            "across" and this declaration hides it.

+    */

+

+    int     across;

+#endif

+  

+    require (tree != NULL,"genExprTree: tree is NULL");

+    require (k > 0,"genExprTree: k <= 0");

+

+    if (0 && !MRhoisting) {   /* MR11 make new version standard */

+      genExprTreeOriginal(tree,k);

+    } else {

+      count=MR_countLeaves(tree);

+      if (count < 5) {

+        MR_genOneLine(tree,k);

+      } else {

+        _gen("\n");

+        across=0;

+        depth=0;

+        lastkonline=0;

+        MR_genMultiLine(tree,k);

+        _gen("\n");

+      };

+    };

+}

+

+

+/*

+ * Generate LL(k) type expressions of the form:

+ *

+ *		 (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) &&

+ *		 (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) &&

+ *			.....

+ *		 (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn)

+ *

+ * If GenExprSetsOpt generate:

+ *

+ *		(setwdi[LA(1)]&(1<<j)) && (setwdi[LA(2)]&(1<<j)) ...

+ *

+ * where n is set_deg(expr) and Ti is some random token and k is the last nonempty

+ * set in fset <=CLL_k.

+ * k=1..CLL_k where CLL_k >= 1.

+ *

+ * This routine is visible only to this file and cannot answer a TRANS message.

+ *

+ */

+

+/*  [genExpr] */

+

+static int

+#ifdef __USE_PROTOS

+genExpr( Junction *j )

+#else

+genExpr( j )

+Junction *j;

+#endif

+{

+	int max_k;

+

+	/* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead

+	 * from CLL_k..LL_k

+	 */

+	{

+		int limit;

+		if ( j->ftree!=NULL ) limit = LL_k;

+		else limit = CLL_k;

+		max_k = genExprSets(j->fset, limit);

+	}

+

+	/* Do tests for real tuples from other productions that conflict with

+	 * artificial tuples generated by compression (using sets of tokens

+	 * rather than k-trees).

+	 */

+	if ( j->ftree != NULL )

+	{

+		_gen(" && !("); genExprTree(j->ftree, 1); _gen(")");

+	}

+

+	if ( ParseWithPredicates && j->predicate!=NULL )

+	{

+		Predicate *p = j->predicate;

+		warn_about_using_gk_option();

+		_gen("&&");

+		j->predicate=genPredTreeMain(p, (Node *)j);     /* MR10 */

+	}

+

+	return max_k;

+}

+

+static int

+#ifdef __USE_PROTOS

+genExprSets( set *fset, int limit )

+#else

+genExprSets( fset, limit )

+set *fset;

+int limit;

+#endif

+{

+	int k = 1;

+	int max_k = 0;

+	unsigned *e, *g, firstTime=1;

+

+    if (set_nil(fset[1])) {

+      _gen(" 0 /* MR13 empty set expression  - undefined rule ? infinite left recursion ? */ ");

+      MR_BadExprSets++;

+    };

+

+	if ( GenExprSetsOpt )

+	{

+		while ( k <= limit && !set_nil(fset[k]) )   /* MR11 */

+		{

+			if ( set_deg(fset[k])==1 )	/* too simple for a set? */

+			{

+				int e;

+				_gen1("(LA(%d)==",k);

+				e = set_int(fset[k]);

+				if ( TokenString(e) == NULL ) _gen1("%d)", e)

+				else _gen1("%s)", TokenString(e));

+			}

+			else

+			{

+				NewSet();

+				FillSet( fset[k] );

+				_gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<<setnum);

+			}

+			if ( k>max_k ) max_k = k;

+			if ( k == CLL_k ) break;

+			k++;

+			if ( k<=limit && !set_nil(fset[k]) ) _gen(" && ");  /* MR11 */

+			on1line++;

+			if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }

+		}

+		return max_k;

+	}

+

+	while ( k<= limit &&  !set_nil(fset[k]) )       /* MR11 */

+	{

+		if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set");

+		for (; *e!=nil; e++)

+		{

+			if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; }

+			on1line++;

+			if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }

+			_gen1("LA(%d)==",k);

+			if ( TokenString(*e) == NULL ) _gen1("%d", *e)

+			else _gen1("%s", TokenString(*e));

+		}

+		free( (char *)g );

+		_gen(")");

+		if ( k>max_k ) max_k = k;

+		if ( k == CLL_k ) break;

+		k++;

+		if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); }   /* MR11 */

+		on1line++;

+		if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }

+	}

+	return max_k;

+}

+

+/*

+ * Generate code for any type of block.  If the last alternative in the block is

+ * empty (not even an action) don't bother doing it.  This permits us to handle

+ * optional and loop blocks as well.

+ *

+ * Only do this block, return after completing the block.

+ * This routine is visible only to this file and cannot answer a TRANS message.

+ */

+static set

+#ifdef __USE_PROTOS

+genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly, int * lastAltEmpty /* MR23 */)

+#else

+genBlk( q, jtype, max_k, need_right_curly, lastAltEmpty /* MR23 */)

+Junction *q;

+int jtype;

+int *max_k;

+int *need_right_curly;

+int *lastAltEmpty; /* MR23 */

+#endif

+{

+	set f;

+	Junction *alt;

+	int a_guess_in_block = 0;

+	require(q!=NULL,				"genBlk: invalid node");

+	require(q->ntype == nJunction,	"genBlk: not junction");

+	*need_right_curly=0;

+	*lastAltEmpty = 0;		/* MR23 */

+	if ( q->p2 == NULL )	/* only one alternative?  Then don't need if */

+	{	

+		if (first_item_is_guess_block((Junction *)q->p1)!=NULL )

+		{

+            if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) {

+  			  warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line);

+            };

+   	   	    gen("zzGUESS\n");	/* guess anyway to make output code consistent */

+/* MR10 disable */  /**** gen("if ( !zzrv )\n"); ****/

+/* MR10 */          gen("if ( !zzrv ) {\n"); tabs++; (*need_right_curly)++;

+        };

+		TRANS(q->p1);

+		return empty;		/* no decision to be made-->no error set */

+	}

+

+	f = First(q, 1, jtype, max_k);

+	for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )

+	{

+		if ( alt->p2 == NULL )					/* chk for empty alt */

+		{	

+			Node *p = alt->p1;

+			if ( p->ntype == nJunction )

+			{

+				/* we have empty alt */

+/* MR23

+   There is a conflict between giving good error information for non-exceptions

+   and making life easy for those using parser exception handling.  Consider:

+

+         r: { A } b;

+		 b: B;

+		 

+		   with input "C"

+

+   Before MR21 the error message would be "expecting B - found C".  After MR21

+   the error message would be "expcect A, B - found C".  This was good, but it

+   caused problems for those using parser exceptions because the reference to

+   B was generated inside the {...} where B really wasn't part of the block.

+

+   In MR23 this has been changed for the case where exceptions are in use to

+   not generate the extra check in the tail of the {A} block.

+*/

+

+

+/* MR23 */	if (isEmptyAlt( ((Junction *)p)->p1, (Node *)q->end)) {

+/* MR23 */      *lastAltEmpty = 1;

+/* MR23 */		if (FoundException) {

+/* MR23 */			/* code to restore state if a prev alt didn't follow guess */

+/* MR23 */			if ( a_guess_in_block && jtype != aPlusBlk) {

+/* MR23 */				gen("if ( !zzrv ) zzGUESS_DONE; /* MR28 */\n");

+/* MR23 */			}

+/* MR23 */			break;

+/* MR23 */		};

+/* MR28 */      if (jtype == aPlusBlk) {

+/* MR28 */          break;

+/* MR28 */      }

+/* MR23 */	}

+		}

+	} /* end of for loop on alt */

+

+/* MR10 */        if (alt->p2 == NULL &&

+/* MR10 */               ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) {

+/* MR10 */          if (first_item_is_guess_block(alt)) {

+/* MR10 */               warnFL("(...)? as last alternative of block is unnecessary",

+/* MR10 */                                FileStr[alt->file],alt->line);

+/* MR10 */          };

+/* MR10 */        };

+

+		if ( alt != q ) gen("else ")

+		else

+		{

+			if ( DemandLookahead ) {

+				if ( !GenCC ) {gen1("LOOK(%d);\n", *max_k);}

+				else gen1("look(%d);\n", *max_k);

+			}

+		}

+

+		if ( alt!=q )

+		{

+			_gen("{\n");

+			tabs++;

+			(*need_right_curly)++;

+			/* code to restore state if a prev alt didn't follow guess */

+			if ( a_guess_in_block )

+				gen("if ( !zzrv ) zzGUESS_DONE;\n");

+		}

+		if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL )

+		{

+			a_guess_in_block = 1;

+			gen("zzGUESS\n");

+		}

+		gen("if ( ");

+		if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && ");

+		genExpr(alt);

+		_gen(" ) ");

+		_gen("{\n");

+		tabs++;

+		TRANS(alt->p1);

+		--tabs;

+		gen("}\n");

+/* MR10 */        if (alt->p2 == NULL) {

+/* MR10 */          if (first_item_is_guess_block(alt)) {

+/* MR10 */            gen("/* MR10 */ else {\n");

+/* MR10 */            tabs++;

+/* MR10 */  		  (*need_right_curly)++;

+/* MR10 */  		  /* code to restore state if a prev alt didn't follow guess */

+/* MR10 */            gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;\n");

+/* MR10 */            gen("/* MR10 */ if (0) {}     /* last alternative of block is guess block */\n");

+/* MR10 */          };

+/* MR10 */        };

+	}

+	return f;

+}

+

+static int

+#ifdef __USE_PROTOS

+has_guess_block_as_first_item( Junction *q )

+#else

+has_guess_block_as_first_item( q )

+Junction *q;

+#endif

+{

+	Junction *alt;

+

+	for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )

+	{

+		if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1;

+	}

+	return 0;

+}

+

+static int

+#ifdef __USE_PROTOS

+has_guess_block_as_last_item( Junction *q )

+#else

+has_guess_block_as_last_item( q )

+Junction *q;

+#endif

+{

+	Junction *alt;

+

+    if (q == NULL) return 0;

+	for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {};

+    return first_item_is_guess_block( (Junction *) alt->p1) != NULL;

+}

+

+/* MR30 See description of first_item_is_guess_block for background */

+

+Junction *

+#ifdef __USE_PROTOS

+first_item_is_guess_block_extra(Junction *q )

+#else

+first_item_is_guess_block_extra(q)

+Junction *q;

+#endif

+{

+	while ( q!=NULL &&

+            (  ( q->ntype==nAction ) ||

+               ( q->ntype==nJunction &&

+                    (q->jtype==Generic || q->jtype == aLoopBlk) 

+               )

+            )

+          )

+	{

+		if ( q->ntype==nJunction ) q = (Junction *)q->p1;

+		else q = (Junction *) ((ActionNode *)q)->next;

+	}

+

+	if ( q==NULL ) return NULL;

+	if ( q->ntype!=nJunction ) return NULL;

+	if ( q->jtype!=aSubBlk ) return NULL;

+	if ( !q->guess ) return NULL;

+

+	return q;

+}

+

+/* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node

+ * of (...)?;  This function ignores actions and predicates.

+ */

+

+Junction *

+#ifdef __USE_PROTOS

+first_item_is_guess_block( Junction *q )

+#else

+first_item_is_guess_block( q )

+Junction *q;

+#endif

+{

+	Junction * qOriginal = q;	/* DEBUG */

+

+    /* MR14  Couldn't find aSubBlock which was a guess block when it lay

+             behind aLoopBlk.  The aLoopBlk only appear in conjunction with

+             aLoopBegin, but the routine didn't know that.  I think.

+

+       MR14a Added extra parentheses to clarify precedence

+

+	   MR30  This appears to have been a mistake.  The First set was then

+	         computed incorrectly for:

+

+					r : ( (A)? B

+					    | C

+						)*

+			 

+			 The routine analysis_point was seeing the guess block when

+			 it was still analyzing the loopBegin block.  As a consequence,

+			 when it looked for the analysis_point it was processing the B, but

+			 skipping over the C alternative altogether because it thought

+			 it was looking at a guess block, not realizing there was a loop

+			 block in front of the loopBegin.

+

+             loopBegin  loopBlk  subBlk/guess  A  G  EB  G  B EB EB  EB  ER

+			    |          |          |                     ^   ^

+				|		   |                                |   |

+                |          +-> G  C G ----------------------+   |

+                |                                               |

+				+--- G G G -------------------------------------+

+    

+			 Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu).

+

+		MR30  This is still more complicated.  This fix caused ambiguity messages

+		to be reported for "( (A B)? )* A B" but not for "( (A B)? )+".  Why is

+		there a difference when these are outwardly identical ?  It is because the

+		start of a (...)* block is represented by two nodes: a loopBegin block

+		followed by a loopBlock whereas the start of a (...)+ block is

+		represented as a single node: a plusBlock.  So if first_item_is_guess_block

+		is called when the current node is a loopBegin it starts with the

+		loop block rather than the the sub block which follows the loop block.

+		However, we can't just skip past the loop block because some routines

+		depend on the old implementation.  So, we provide a new implementation

+		which does skip the loopBlock.  However, which should be called when ?

+		I'm not sure, but my guess is that first_item_is_guess_block_extra (the

+		new one) should only be called for the ambiguity routines.

+

+    */

+

+	while ( q!=NULL &&

+            (  ( q->ntype==nAction ) ||

+               ( q->ntype==nJunction &&

+                    (q->jtype==Generic /*** || q->jtype == aLoopBlk ***/ ) /*** MR30 Undo MR14 change ***/

+               )

+            )

+          )

+	{

+		if ( q->ntype==nJunction ) q = (Junction *)q->p1;

+		else q = (Junction *) ((ActionNode *)q)->next;

+	}

+

+	if ( q==NULL ) return NULL;

+	if ( q->ntype!=nJunction ) return NULL;

+	if ( q->jtype!=aSubBlk ) return NULL;

+	if ( !q->guess ) return NULL;

+

+	return q;

+}

+

+/* MR1				                 					    */

+/* MR1  10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs  */

+/* MR1				                                                        */

+

+#define STRINGIZEBUFSIZE 1024

+

+static char stringizeBuf[STRINGIZEBUFSIZE];

+char *

+#ifdef __USE_PROTOS

+stringize(char * s)

+#else

+stringize(s)

+char *s;

+#endif

+

+{

+  char		*p;

+  char		*stop;

+

+  p=stringizeBuf;

+  stop=&stringizeBuf[1015];

+

+  if (s != 0) {

+    while (*s != 0) {

+      if (p >= stop) {

+	goto stringizeStop;

+      } else if (*s == '\n') {

+        *p++='\\';

+        *p++='n';

+        *p++='\\';

+	*p++=*s++;

+      } else if (*s == '\\') {

+	*p++=*s;

+	*p++=*s++;

+      } else if (*s == '\"') {

+        *p++='\\';

+	*p++=*s++;

+        while (*s != 0) {

+          if (p >= stop) {

+	     goto stringizeStop;

+	  } else if (*s == '\n') {

+	    *p++='\\';

+	    *p++=*s++;

+	  } else if (*s == '\\') {

+	    *p++=*s++;

+	    *p++=*s++;

+	  } else if (*s == '\"') {

+	    *p++='\\';

+	    *p++=*s++;

+	    break;

+	  } else {

+	    *p++=*s++;

+          };

+        };

+      } else if (*s == '\'') {

+	*p++=*s++;

+        while (*s != 0) {

+          if (p >= stop) {

+	     goto stringizeStop;

+	  } else if (*s == '\'') {

+	    *p++=*s++;

+	    break;

+	  } else if (*s == '\\') {

+	    *p++=*s++;

+	    *p++=*s++;

+	  } else if (*s == '\"') {

+	    *p++='\\';

+	    *p++=*s++;

+	    break;

+	  } else {

+	    *p++=*s++;

+          };

+        };

+      } else {

+        *p++=*s++;

+      };

+    };

+  };

+  goto stringizeExit;

+stringizeStop:

+  *p++='.';        	

+  *p++='.';        	

+  *p++='.';        	

+stringizeExit:

+  *p=0;

+  return stringizeBuf;

+}

+

+#ifdef __USE_PROTOS

+int isNullAction(char *s)

+#else

+int isNullAction(s)

+  char  *s;

+#endif

+{

+  char  *p;

+  for (p=s; *p != '\0' ; p++) {

+    if (*p != ';' && *p !=' ') return 0;

+  };

+  return 1;

+}

+/* MR1									                                    */

+/* MR1	End of Routine to stringize code for failed predicates msgs         */

+/* MR1				                                                        */

+

+/* Generate an action.  Don't if action is NULL which means that it was already

+ * handled as an init action.

+ */

+void

+#ifdef __USE_PROTOS

+genAction( ActionNode *p )

+#else

+genAction( p )

+ActionNode *p;

+#endif

+{

+	require(p!=NULL,			"genAction: invalid node and/or rule");

+	require(p->ntype==nAction,	"genAction: not action");

+

+	if ( !p->done )  /* MR10 */ /* MR11 */

+	{

+		if ( p->is_predicate)

+		{

+			if ( p->guardpred != NULL )

+			{

+                Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */

+                gen("if (!");

+       			guardDup=genPredTreeMain(guardDup, (Node *)p);

+                predicate_free(guardDup);

+			}

+/* MR10 */  else if (p->ampersandPred != NULL) {

+/* MR10 */      gen("if (!");

+/* MR10 */      p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p);

+/* MR10 */  }

+			else

+			{

+				gen("if (!(");

+				/* make sure that '#line n' is on front of line */

+				if ( GenLineInfo && p->file != -1 ) _gen("\n");

+				dumpPredAction(p,p->action, output, 0, p->file, p->line, 0);

+				_gen(")");

+			}

+

+/* MR23 Change failed predicate macro to have three arguments:

+

+        macro arg 1: The stringized predicate itself

+        macro arg 2: 0 => no user-defined error action

+                     1 => user-defined error action

+        macro arg 3: The user-defined error action

+

+   This gives the user more control of the error action.

+*/

+			tabs++;

+			gen3(") {zzfailed_pred(\"%s\",%s, { %s } );}\n",         /* MR23 */

+					stringize(p->action),	                         /* MR23 */

+                    (p->pred_fail == NULL ?                          /* MR23/MR27 */

+                       	"0 /* report */" : "1 /* user action */"),   /* MR23/MR27 */

+                    (p->pred_fail == NULL ?                          /* MR23 */

+                        "0; /* no user action */" : p->pred_fail));  /* MR23 */

+			tabs--;

+		}

+		else    /* not a predicate */

+		{

+            if (! isNullAction(p->action) && !p->noHoist) {

+  	  		  if ( FoundGuessBlk ) {

+				if ( GenCC ) {

+                  gen("if ( !guessing ) {\n");

+                } else {

+				  gen("zzNON_GUESS_MODE {\n");

+                };

+              };

+			  dumpActionPlus(p, p->action, output, tabs, p->file, p->line, 1); /* MR21 */

+			  if ( FoundGuessBlk ) gen("}\n");

+            };

+		}

+	}

+	TRANS(p->next)

+}

+

+/*

+ *		if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in

+ *		else pass addr of temp root ptr (&_ast) (don't zzlink it in).

+ *

+ *		if ! modifies rule-ref, then never link it in and never pass zzSTR.

+ *		Always pass address of temp root ptr.

+ */

+void

+#ifdef __USE_PROTOS

+genRuleRef( RuleRefNode *p )

+#else

+genRuleRef( p )

+RuleRefNode *p;

+#endif

+{

+	Junction *q;

+	char *handler_id = "";

+	RuleEntry *r, *r2;

+	char *parm = "", *exsig = "";

+

+    int     genRuleRef_emittedGuessGuard=0;     /* MR10 */

+

+	require(p!=NULL,			"genRuleRef: invalid node and/or rule");

+	require(p->ntype==nRuleRef, "genRuleRef: not rule reference");

+	

+	if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )

+		handler_id = p->altstart->exception_label;

+

+	r = (RuleEntry *) hash_get(Rname, p->text);

+	if ( r == NULL )

+	{

+		warnFL( eMsg1("rule %s not defined",

+					  p->text), FileStr[p->file], p->line );

+		return;

+	}

+

+/* MR8 5-Aug-97     Reported by S.Bochnak@microtool.com.pl                  */

+/*                  Don't do assign when no return values declared          */

+/*                  Move definition of q up and use it to guard p->assign   */

+

+	q = RulePtr[r->rulenum];	/* find definition of ref'd rule */  /* MR8 */

+

+	r2 = (RuleEntry *) hash_get(Rname, p->rname);

+	if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}

+

+    OutLineInfo(output,p->line,FileStr[p->file]);

+

+	if ( GenCC && GenAST ) {

+		gen("_ast = NULL;\n");

+	}

+

+	if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) {      /* MR8 */

+		if ( GenCC ) {

+          gen("if ( !guessing ) {\n");

+        } else {

+          gen("zzNON_GUESS_MODE {\n");

+        };

+        tabs++;                                                      /* MR11 */

+        genRuleRef_emittedGuessGuard=1;                              /* MR11 */

+    };

+

+	if ( FoundException ) exsig = "&_signal";

+

+	tab();

+	if ( GenAST )

+	{

+		if ( GenCC ) {

+/****			if ( r2->noAST || p->astnode==ASTexclude )

+****/

+			{

+/****				_gen("_ast = NULL;\n");

+****/

+				parm = "&_ast";

+			}

+/*** we always want to set just a pointer now, then set correct

+pointer after

+

+			else {

+				_gen("_astp =

+(_tail==NULL)?(&_sibling):(&(_tail->_right));\n");

+				parm = "_astp";

+			}

+****/

+		}

+		else {

+			if ( r2->noAST || p->astnode==ASTexclude )

+			{

+				_gen("_ast = NULL; ");

+				parm = "&_ast";

+			}

+			else parm = "zzSTR";

+		}

+		if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */

+		{

+			if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */

+			else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);

+		}

+		if ( FoundException ) {

+			_gen5("%s%s(%s,&_signal%s%s); ",

+				  RulePrefix,

+				  p->text,

+				  parm,

+				  (p->parms!=NULL)?",":"",

+				  (p->parms!=NULL)?p->parms:"");

+			if ( p->ex_group!=NULL ) {

+				_gen("\n");

+				gen("if (_signal) {\n");

+				tabs++;

+				dumpException(p->ex_group, 0);

+				tabs--;

+				gen("}");

+			}

+			else {

+				_gen1("if (_signal) goto %s_handler;", handler_id);

+			}

+		}

+		else {

+			_gen5("%s%s(%s%s%s);",

+				  RulePrefix,

+				  p->text,

+				  parm,

+				  (p->parms!=NULL)?",":"",

+				  (p->parms!=NULL)?p->parms:"");

+		}

+		if ( GenCC && (r2->noAST || p->astnode==ASTexclude) )

+		{

+			/* rule has a ! or element does */

+			/* still need to assign to #i so we can play with it */

+			_gen("\n");

+			gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum);

+		}

+		else if ( !r2->noAST && p->astnode == ASTinclude )

+		{

+			/* rule doesn't have a ! and neither does element */

+/* MR10 */  if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {

+/* MR10 */    _gen("\n");

+/* MR10 */    if (GenCC) gen ("if (!guessing) {    /* MR10 */")

+/* MR10 */          else gen ("if (!zzguessing) {    /* MR10 */\n");

+/* MR10 */    tabs++;

+/* MR10 */  };

+			if ( GenCC ) {

+				_gen("\n");

+				gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);\n");

+				gen2("_ast%d%d = (AST *)_ast;\n", BlkLevel-1, p->elnum);

+				tab();

+			}

+			else _gen(" ");

+            if ( GenCC ) {

+                _gen("ASTBase::"); }

+                else _gen("zz");

+			_gen("link(_root, &_sibling, &_tail);");

+

+/* MR10 */  if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {     /* MR10 */

+/* MR10 */    _gen("\n");

+/* MR10 */    tabs--;

+/* MR10 */    if (GenCC) gen ("};    /* MR10 */")

+/* MR10 */          else gen ("};    /* MR10 */");

+/* MR10 */  };

+		}

+	}

+	else

+	{

+		if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */

+		{

+			if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */

+			else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);

+		}

+		if ( FoundException ) {

+			_gen4("%s%s(&_signal%s%s); ",

+				  RulePrefix,

+				  p->text,

+				  (p->parms!=NULL)?",":"",

+				  (p->parms!=NULL)?p->parms:"");

+			if ( p->ex_group!=NULL ) {

+				_gen("\n");

+				gen("if (_signal) {\n");

+				tabs++;

+				dumpException(p->ex_group, 0);

+				tabs--;

+				gen("}");

+			}

+			else {

+				_gen1("if (_signal) goto %s_handler;", handler_id);

+			}

+		}

+		else {

+			_gen3("%s%s(%s);",

+				  RulePrefix,

+				  p->text,

+				  (p->parms!=NULL)?p->parms:"");

+		}

+		if ( p->assign!=NULL && q->ret!=NULL ) _gen("\n");           /* MR8 */

+	}

+

+	if ( p->assign!=NULL && q->ret!=NULL) {                          /* MR8 */

+		if ( hasMultipleOperands(p->assign) )                        /* MR23 */

+		{

+			_gen("\n");

+			dumpRetValAssign(p->assign, q->ret, p);                  /* MR30 */

+			_gen("}");

+		}

+	}

+	_gen("\n");

+

+	/* Handle element labels now */

+	if ( p->el_label!=NULL )

+	{

+		if ( GenAST )

+		{

+			if ( GenCC ) {

+				gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);

+			}

+			else {gen1("%s_ast = zzastCur;\n", p->el_label);}

+		}

+       	else if (!GenCC ) {

+			gen1("%s = zzaCur;\n", p->el_label);

+        }

+	}

+

+	if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) {       /* MR8 */

+		/* in guessing mode, don't branch to handler upon error */

+        tabs--;                                                     /* MR11 */

+		gen("} else {\n");

+        tabs++;                                                     /* MR11 */

+		if ( FoundException ) {

+			gen6("%s%s(%s%s&_signal%s%s);\n",

+				 RulePrefix,

+				 p->text,

+				 parm,

+                 (*parm!='\0')?",":"",

+                 (p->parms!=NULL)?",":"",

+				 (p->parms!=NULL)?p->parms:"");

+		}

+		else {

+			gen5("%s%s(%s%s%s);\n",

+				 RulePrefix,

+				 p->text,

+				 parm,

+				 (p->parms!=NULL && *parm!='\0')?",":"",

+				 (p->parms!=NULL)?p->parms:"");

+		}

+        tabs--;                                                     /* MR11 */

+		gen("}\n");

+	}

+	TRANS(p->next)

+}

+

+/*

+ * Generate code to match a token.

+ *

+ * Getting the next token is tricky.  We want to ensure that any action

+ * following a token is executed before the next GetToken();

+ */

+void

+#ifdef __USE_PROTOS

+genToken( TokNode *p )

+#else

+genToken( p )

+TokNode *p;

+#endif

+{

+	RuleEntry *r;

+	char *handler_id = "";

+	ActionNode *a;

+	char *set_name;

+	char *set_nameErrSet;

+	int complement;

+	int ast_label_in_action = 0;	/* MR27 */

+	int pushedCmodeAST = 0;			/* MR27 */

+

+	require(p!=NULL,			"genToken: invalid node and/or rule");

+	require(p->ntype==nToken,	"genToken: not token");

+	if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )

+		handler_id = p->altstart->exception_label;

+

+	r = (RuleEntry *) hash_get(Rname, p->rname);

+	if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}

+

+/*

+ * MR27 Has the element label been referenced as an AST (with the # operator) ?

+ *      If so, then we'll want to build the AST even though the user has used

+ *      the ! operator.

+ */

+/* MR27 */	if (GenAST && p->el_label != NULL) {

+/* MR27 */		ast_label_in_action = list_search_cstring(r->ast_labels_in_actions,

+/* MR27 */		                                          p->el_label);

+/* MR27 */	}

+	

+    OutLineInfo(output,p->line,FileStr[p->file]);

+

+	if ( !set_nil(p->tset) )	/* implies '.', ~Tok, or tokenclass */

+	{

+		unsigned e;

+		unsigned eErrSet = 0;

+		set b;

+		set bErrSet;					/* MR23 */

+		b = set_dup(p->tset);

+		bErrSet = set_dup(p->tset);	    /* MR23 */

+		complement = p->complement; /* MR23 */

+		if ( p->tclass!=NULL  && complement == 0 /* MR23 */) { /* token class not complemented*/

+			static char buf[MaxRuleName+20];	    /* MR23 */

+			static char bufErrSet[MaxRuleName+20];	/* MR23 */

+			if ( p->tclass->dumped ) {

+				e = p->tclass->setnum;

+				eErrSet = p->tclass->setnumErrSet;

+			}

+			else {

+				e = DefErrSet(&b, 0, TokenString(p->token));

+				eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errset");

+				p->tclass->dumped = 1;	/* indicate set has been created */

+				p->tclass->setnum = e;

+				p->tclass->setnumErrSet = eErrSet;					/* MR23 */

+			}

+			sprintf(buf, "%s_set", TokenString(p->token));

+			sprintf(bufErrSet, "%s_errset", TokenString(p->token));	/* MR23 */

+			set_name = buf;

+			set_nameErrSet = bufErrSet;								/* MR23 */

+		}

+

+		/* MR23 - Forgot about the case of ~TOKCLASS. */

+

+		else if ( p->tclass!=NULL  && complement != 0 /* MR23 */)

+		{

+			static char buf[MaxRuleName+20];	    /* MR23 */

+			static char bufErrSet[MaxRuleName+20];	/* MR23 */

+			if ( p->tclass->dumpedComplement ) {

+				e = p->tclass->setnumComplement;

+				eErrSet = p->tclass->setnumErrSetComplement;

+			}

+			else {

+				e = DefErrSetWithSuffix(0, &b, 0, TokenString(p->token), "_setbar");

+				eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errsetbar");

+				p->tclass->dumpedComplement = 1;	/* indicate set has been created */

+				p->tclass->setnumComplement = e;

+				p->tclass->setnumErrSetComplement = eErrSet;					/* MR23 */

+			}

+			sprintf(buf, "%s_setbar", TokenString(p->token));

+			sprintf(bufErrSet, "%s_errsetbar", TokenString(p->token));	/* MR23 */

+			set_name = buf;

+			set_nameErrSet = bufErrSet;								/* MR23 */

+		}

+		else {					/* wild card */

+			static char buf[sizeof("zzerr")+10];

+			static char bufErrSet[sizeof("zzerr")+10];

+			int n = DefErrSet( &b, 0, NULL );

+			int nErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, NULL, "_set");

+			if ( GenCC ) sprintf(buf, "err%d", n);

+			else sprintf(buf, "zzerr%d", n);

+			if ( GenCC ) sprintf(bufErrSet, "err%d", nErrSet);

+			else sprintf(bufErrSet, "zzerr%d", nErrSet);

+			set_name = buf;

+			set_nameErrSet = bufErrSet;

+		}

+

+		if ( !FoundException ) {

+/* MR23 */		gen2("zzsetmatch(%s, %s);", set_name, set_nameErrSet);

+		}

+		else if ( p->ex_group==NULL ) {

+            if ( p->use_def_MT_handler )

+                gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);",

+                     set_name,

+                     p->token,

+                     tokenFollowSet(p))

+            else

+                gen2("zzsetmatch_wsig(%s, %s_handler);",

+                     set_name,

+                     handler_id);

+		}

+		else

+		{

+			gen1("if ( !_setmatch_wsig(%s) ) {\n", set_name);

+			tabs++;

+/* MR6 */	if (FoundGuessBlk) {

+/* MR6 */	  if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}

+/* MR6 */	  else gen("if ( zzguessing ) goto fail;\n");

+/* MR6 */	};

+			gen("_signal=MismatchedToken;\n");

+			dumpException(p->ex_group, 0);

+			tabs--;

+			gen("}\n");

+		}

+		set_free(b);

+		set_free(bErrSet);

+	}

+	else if ( TokenString(p->token)!=NULL )

+	{

+		if ( FoundException ) {

+			if ( p->use_def_MT_handler )

+				gen2("zzmatch_wdfltsig(%s,%s);",TokenString(p->token),tokenFollowSet(p))

+			else if ( p->ex_group==NULL )

+			{

+				gen2("zzmatch_wsig(%s, %s_handler);",

+					 TokenString(p->token),

+					 handler_id);

+			}

+			else

+			{

+/* MR6 */		if (GenCC) {

+/* MR6 */		  gen1("if ( !_match_wsig(%s) ) {\n", TokenString(p->token));

+/* MR6 */		} else {

+/* MR6 */		  gen1("if ( !_zzmatch_wsig(%s) ) {\n", TokenString(p->token));

+/* MR6 */		};

+				tabs++;

+/* MR6 */		if (FoundGuessBlk) {

+/* MR6 */	  	  if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}

+/* MR6 */		  else gen("if ( zzguessing ) goto fail;\n");

+/* MR6 */		};

+				gen("_signal=MismatchedToken;\n");

+				dumpException(p->ex_group, 0);

+				tabs--;

+				gen("}\n");

+			}

+		}

+		else gen1("zzmatch(%s);", TokenString(p->token));

+	}

+	else {

+        if ( FoundException ) {

+            if ( p->use_def_MT_handler )

+				gen2("zzmatch_wdfltsig((ANTLRTokenType)%d,%s);",

+					 p->token,tokenFollowSet(p))

+            else

+                gen2("zzmatch_wsig(%d,%s_handler);",p->token,handler_id);

+        }

+		else {gen1("zzmatch(%d);", p->token);}

+	}

+

+	a = findImmedAction( p->next );

+	/* generate the token labels */

+	if ( GenCC && p->elnum>0 )

+	{

+		/* If building trees in C++, always gen the LT() assigns */

+		if ( set_el(p->elnum, tokensRefdInBlock) || GenAST )

+		{

+/* MR10 */	if ( FoundGuessBlk ) {

+/* MR10 */    gen("\n");

+/* MR10 */    if (p->label_used_in_semantic_pred) {

+/* MR10 */		gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);  /* MR10 */\n", BlkLevel-1, p->elnum);

+/* MR10 */    } else {

+/* MR10 */		gen("if ( !guessing ) {\n"); tab();

+/* MR10 */		_gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);\n", BlkLevel-1, p->elnum);

+/* MR10 */      gen("}\n");

+/* MR10 */    };

+/* MR10 */  } else {

+/* MR10 */	  _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);", BlkLevel-1, p->elnum);

+/* MR10 */  };

+/* MR10 */

+		}

+

+/*

+ *  MR23 labase is never used in the C++ runtime library.

+ *       and this code is generated only in C++ mode

+ */

+

+/***		if ( LL_k>1 )                                    / * MR23 disabled */

+/***			if ( !DemandLookahead ) _gen(" labase++;");  / * MR23 disabled */

+/***		_gen("\n");                                      / * MR23 disabled */

+/***		tab();                                           / * MR23 disabled */

+	}

+	if ( GenAST )

+	{

+		if ( FoundGuessBlk &&

+				(ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) )

+		{

+			if ( GenCC ) {_gen("if ( !guessing ) {\n"); tab();}

+			else {_gen("zzNON_GUESS_MODE {\n"); tab();}

+		}

+

+/* MR27 addition when labels referenced when operator ! used */

+

+		pushedCmodeAST = 0; /* MR27 */

+		if (ast_label_in_action && (p->astnode == ASTexclude || r->noAST)) {

+			_gen("\n");

+			if (GenCC) {

+/* MR13 */      if (NewAST) {

+/* MR13 */    	    gen4("_ast%d%d = newAST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);

+/* MR13 */      } else {

+/* MR13 */    	    gen4("_ast%d%d = new AST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);

+/* MR13 */      }

+			}

+			else {

+				pushedCmodeAST = 1;

+				gen("zzastPush(zzmk_ast(zzastnew(),zzaCur)); /* MR27 */");

+			}

+		}

+

+/* end MR27 addition for labels referenced when operator ! used */

+

+		if (!r->noAST )

+		{

+			if (GenCC && !(p->astnode == ASTexclude) ) {

+				_gen("\n");

+/* MR13 */      if (NewAST) {

+/* MR13 */    	    gen4("_ast%d%d = newAST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);

+/* MR13 */      } else {

+/* MR13 */    	    gen4("_ast%d%d = new AST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);

+/* MR13 */      }

+				tab();

+			}

+			if ( GenCC && !(p->astnode == ASTexclude) )

+				{_gen2("_ast%d%d->", BlkLevel-1, p->elnum);}

+			else _gen(" ");

+			if ( p->astnode==ASTchild ) {

+				if ( !GenCC ) _gen("zz");

+				_gen("subchild(_root, &_sibling, &_tail);");

+			}

+			else if ( p->astnode==ASTroot ) {

+				if ( !GenCC ) _gen("zz");

+				_gen("subroot(_root, &_sibling, &_tail);");

+			}

+			if ( GenCC && !(p->astnode == ASTexclude) ) {

+				_gen("\n");

+				tab();

+			}

+		}

+		else if ( !GenCC ) {

+			if (! pushedCmodeAST) _gen(" zzastDPush;");

+		}

+		if ( FoundGuessBlk &&

+				(ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) )

+			{gen("}\n"); tab();}

+	}

+

+	/* Handle element labels now */

+	if ( p->el_label!=NULL )

+	{

+        int     done_NON_GUESSMODE=0;

+

+		_gen("\n");

+

+/* MR10 */    /* do Attrib / Token ptr for token label used in semantic pred */

+/* MR10 */    /* for these cases do assign even in guess mode                */

+/* MR10 */

+/* MR10 */    if (p->label_used_in_semantic_pred) {

+/* MR10 */      if ( GenCC ) {

+/* MR10 */        if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {

+/* MR10 */          gen3("%s = _t%d%d;", p->el_label, BlkLevel-1, p->elnum);

+/* MR10 */        } else {

+/* MR10 */          gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label);

+/* MR10 */        };

+/* MR10 */      } else {

+/* MR10 */		  gen1("%s = zzaCur;", p->el_label);

+/* MR10 */      };

+/* MR10 */      if (FoundGuessBlk) _gen("  /* MR10 */");

+/* MR10 */      _gen("\n");

+/* MR10 */    };

+

+		/* Do Attrib / Token ptr */

+

+/* MR10 */  if (! p->label_used_in_semantic_pred) {

+/* MR10 */

+/* MR10 */      if ( FoundGuessBlk ) {

+/* MR10 */        if (! done_NON_GUESSMODE) {

+/* MR10 */          done_NON_GUESSMODE=1;

+/* MR10 */          if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();}

+/* MR10 */          else {gen("zzNON_GUESS_MODE {\n"); tab();}

+/* MR10 */        };

+/* MR10 */      };

+/* MR10 */

+/* MR10 */      if ( GenCC ) {

+/* MR10 */        if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {

+/* MR10 */          gen3("%s = _t%d%d;\n", p->el_label, BlkLevel-1, p->elnum);

+/* MR10 */        } else {

+/* MR10 */          gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label);

+/* MR10 */        };

+/* MR10 */      } else {

+/* MR10 */        gen1("%s = zzaCur;\n", p->el_label);

+/* MR10 */      };

+/* MR10 */  };

+

+		/* Do AST ptr */

+

+		if (GenAST && (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST) )) /* MR27 */

+		{

+

+/* MR10 */      if ( FoundGuessBlk ) {

+/* MR10 */        if (! done_NON_GUESSMODE) {

+/* MR10 */          done_NON_GUESSMODE=1;

+/* MR10 */          if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();}

+/* MR10 */          else {gen("zzNON_GUESS_MODE {\n"); tab();}

+/* MR10 */        };

+/* MR10 */      };

+

+			if ( GenCC ) {

+				gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);

+			}

+			else {gen1("%s_ast = zzastCur;\n", p->el_label);}

+		}

+

+/* MR10 */  if (done_NON_GUESSMODE) {

+/* MR10 */    gen("}\n"); tab();

+/* MR10 */  };

+

+	}

+

+	/* Handle any actions immediately following action */

+	if ( a != NULL )  /* MR10 */ /* MR11 */

+    {

+    	/* delay next token fetch until after action */

+		_gen("\n");

+		if ( a->is_predicate)

+		{

+#if 0

+/* Disabled in MR30 ************************************************************

+   And moved into genAction

+   *****************************************************************************

+*/

+ 

+    	    gen("if (!(");

+

+			/* make sure that '#line n' is on front of line */  /* MR14 */

+			if ( GenLineInfo && p->file != -1 ) _gen("\n");     /* MR14 */

+			dumpPredAction(a,a->action, output, 0, a->file, a->line, 0);

+

+/* MR23 Change failed predicate macro to have three arguments:

+

+        macro arg 1: The stringized predicate itself

+        macro arg 2: 0 => no user-defined error action

+                     1 => user-defined error action

+        macro arg 3: The user-defined error action

+

+   This gives the user more control of the error action.

+*/

+			_gen(")) \n");

+			tabs++;

+			gen3(" {zzfailed_pred(\"%s\",%s,{ %s } );}\n",           /* MR23 */

+					stringize(a->action),	                         /* MR23 */

+                    (a->pred_fail == NULL ?                          /* MR23/MR27 */

+                       	"0 /* report */" : "1 /* user action */"),   /* MR23/MR27 */

+                    (a->pred_fail == NULL ?                          /* MR23 */

+                        "0; /* no user action */" : a->pred_fail));  /* MR23 */

+			tabs--;

+/* Disabled in MR30 ************************************************************

+   And moved into genAction

+   *****************************************************************************

+*/

+#endif

+		}

+		else    /* MR9 a regular action - not a predicate action */

+		{

+

+/* MR23: Search an action which is not a predicate for LT(i),

+         LA(i), or LATEXT(i) in order to warn novice users that

+         it refers to the previous matched token, not the next

+         one.  This is different than the case for semantic

+         predicates.

+*/

+                                 

+/* MR23 */    if (GenCC) {

+/* MR23 */	    if (strstr(a->action, "LT(") != NULL) LTinTokenAction = 1;

+/* MR23 */    }

+/* MR23 */    else {

+/* MR23 */      if (strstr(a->action, "LA(") != NULL) LTinTokenAction = 1;            

+/* MR23 */      if (strstr(a->action, "LATEXT(") != NULL) LTinTokenAction = 1;

+/* MR23 */    }

+

+			if ( FoundGuessBlk ) {

+   				if ( GenCC ) {gen("if ( !guessing ) {\n");}

+   				else gen("zzNON_GUESS_MODE {\n");

+			}

+   			dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); /* MR21 */

+       		if ( FoundGuessBlk ) gen("}\n");

+			a->done = 1; /* MR30 */

+ 		}

+/***    a->done = 1;  MR30 Moved up into then branch for true actions, but not predicates ***/

+		if ( !DemandLookahead ) {

+			if ( GenCC ) {

+				if ( FoundException && p->use_def_MT_handler ) gen("if (!_signal)");

+				_gen(" consume();")

+                if ( FoundException && p->use_def_MT_handler )

+                    _gen(" _signal=NoSignal;");

+                _gen("\n");

+			}

+            else

+            {

+                if ( FoundException && p->use_def_MT_handler ) _gen("if (!_signal)");

+					_gen(" zzCONSUME;\n");

+                if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");

+                _gen("\n");

+            }

+		}

+		else gen("\n");

+		if (a->done) {			/* MR30 */

+			TRANS( a->next );   /* MR30 */

+		}						/* MR30 */

+		else {					/* MR30 */

+			TRANS( p->next );	/* MR30 */

+		}						/* MR30 */

+	}

+	else

+	{

+        if ( !DemandLookahead ) {

+			if ( GenCC ) {

+				if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");

+				_gen(" consume();")

+				if (FoundException&&p->use_def_MT_handler) _gen(" _signal=NoSignal;");

+				_gen("\n");

+			}

+			else {

+				if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");

+				_gen(" zzCONSUME;");

+				if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");

+				_gen("\n");

+			}

+		}

+		else _gen("\n");

+		TRANS(p->next);

+	}

+}

+

+/*  MR21

+ *

+ *  There was a bug in the code generation for {...} which causes it

+ *  to omit the optional tokens from the error messages.  The easiest

+ *  way to fix this was to make the opt block look like a sub block:

+ *

+ *          { a | b | c }

+ *

+ *  becomes (internally):

+ *

+ *          ( a | b | c | )

+ *

+ *  The code for genOptBlk is now identical to genSubBlk except for

+ *  cosmetic changes.

+ */

+

+void

+#ifdef __USE_PROTOS

+genOptBlk( Junction *q )

+#else

+genOptBlk( q )

+Junction *q;

+#endif

+{

+	int max_k;

+	set f;

+	int need_right_curly;

+	set savetkref;

+	int lastAltEmpty;			/* MR23 */

+	savetkref = tokensRefdInBlock;

+	require(q->ntype == nJunction,	"genOptBlk: not junction");

+	require(q->jtype == aOptBlk,	"genOptBlk: not opt block");

+

+    OutLineInfo(output,q->line,FileStr[q->file]);

+	BLOCK_Preamble(q);

+	BlkLevel++;

+    BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */

+	f = genBlk(q, aOptBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+/* MR23

+   Bypass error clause generation when exceptions are used in {...} block 

+   See multi-line note in genBlk near call to isEmptyAlt.

+*/

+	if (! FoundException) {

+	    if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}

+	}

+	else {

+		gen("/* MR23 skip error clause for {...} when exceptions in use */\n");

+	}

+	{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+	freeBlkFsets(q);

+	--BlkLevel;

+	BLOCK_Tail();

+

+	if ( q->guess )

+	{

+		gen("zzGUESS_DONE\n");

+	}

+

+	/* must duplicate if (alpha)?; one guesses (validates), the

+	 * second pass matches */

+	if ( q->guess && analysis_point(q)==q )

+	{

+        OutLineInfo(output,q->line,FileStr[q->file]);

+		BLOCK_Preamble(q);

+		BlkLevel++;

+		f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+		if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}

+		{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+		freeBlkFsets(q);

+		--BlkLevel;

+		BLOCK_Tail();

+	}

+

+	tokensRefdInBlock = savetkref;

+	if (q->end->p1 != NULL) TRANS(q->end->p1);

+}

+

+/*

+ * Generate code for a loop blk of form:

+ *

+ *				 |---|

+ *				 v   |

+ *			   --o-G-o-->o--

+ */

+void

+#ifdef __USE_PROTOS

+genLoopBlk( Junction *begin, Junction *q, Junction *start, int max_k )

+#else

+genLoopBlk( begin, q, start, max_k )

+Junction *begin;

+Junction *q;

+Junction *start;	/* where to start generating code from */

+int max_k;

+#endif

+{

+	set         f;

+	int         need_right_curly;

+	set         savetkref;

+    Junction    *guessBlock;    /* MR10 */

+    int         singleAlt;      /* MR10 */

+	int			lastAltEmpty;	/* MR23 */

+

+	savetkref = tokensRefdInBlock;

+	require(q->ntype == nJunction,	"genLoopBlk: not junction");

+	require(q->jtype == aLoopBlk,	"genLoopBlk: not loop block");

+

+	if ( q->visited ) return;

+	q->visited = TRUE;

+

+    /* first_item_is_guess_block doesn't care what kind of node it is */

+

+    guessBlock=first_item_is_guess_block( (Junction *) q->p1);  /* MR10 */

+    singleAlt=q->p2==NULL;                                      /* MR10 */

+

+	if (singleAlt && !guessBlock)	    /* MR10 */ /* only one alternative? */

+	{

+		if ( DemandLookahead ) {

+			if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}

+			else gen1("look(%d);\n", max_k);

+		}

+		gen("while ( ");

+		if ( begin!=NULL ) genExpr(begin);

+		else genExpr(q);

+		/* if no predicates have been hoisted for this single alt (..)*

+		 * do so now

+		 */

+        require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+		if ( ParseWithPredicates && begin->predicate==NULL )

+		{

+			Predicate *a = MR_find_predicates_and_supp((Node *)q->p1);

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+

+			if ( a!=NULL )

+			{

+				_gen("&&");

+				a=genPredTreeMain(a, (Node *)q);    /* MR10 */

+			}

+/* MR10 */  if (MRhoisting) {

+/* MR10 */    predicate_free(a);

+/* MR10 */  };

+		}

+		_gen(" ) {\n");

+		tabs++;

+		TRANS(q->p1);

+		if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);

+		if ( DemandLookahead ) {

+			if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}

+			else gen1("look(%d);\n", max_k);

+		}

+		--tabs;

+		gen("}\n");

+		freeBlkFsets(q);

+		q->visited = FALSE;

+		tokensRefdInBlock = savetkref;

+		return;

+	}

+	gen("for (;;) {\n");        /* MR20 G. Hobbelt */

+	tabs++;

+/* MR6				                					*/

+/* MR6 	   "begin" can never be null when called from genLoopBegin	*/

+/* MR6     because q==(Junction *)begin->p1 and we know q is valid	*/

+/* MR6								                            	*/

+/* MR6	   from genLoopBegin:						                */

+/* MR6			                						            */

+/* MR6		 if ( LL_k>1 && !set_nil(q->fset[2]) )			        */

+/* MR6	 	   genLoopBlk( q, (Junction *)q->p1, q, max_k );	    */

+/* MR6		else genLoopBlk( q, (Junction *)q->p1, NULL, max_k );	*/

+/* MR6				                				            	*/

+	if ( begin!=NULL )

+	{

+		if ( DemandLookahead )

+		{

+			if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}

+			else gen1("look(%d);\n", max_k);

+		}

+		/* The bypass arc of the (...)* predicts what to do when you fail, but

+		 * ONLY after having tested the loop start expression.  To avoid this,

+		 * we simply break out of the (...)* loop when we find something that

+		 * is not in the prediction of the loop (all alts thereof).

+		 */

+		gen("if ( !(");

+

+/***	TJP says: It used to use the prediction expression for the bypass arc

+     	of the (...)*.  HOWEVER, if a non LL^1(k) decision was found, this

+    	thing would miss the ftree stored in the aLoopBegin node and generate

+    	an LL^1(k) decision anyway.

+

+ ***		genExpr((Junction *)begin->p2);

+ ***/

+

+            genExpr((Junction *)begin);

+            _gen(")) break;\n");

+

+	}

+

+	/* generate code for terminating loop (this is optional branch) */

+

+	f = genBlk(q, aLoopBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+	set_free(f);

+	freeBlkFsets(q);

+

+	/* generate code for terminating loop (this is optional branch) */

+

+/* MR6 						                    			            */

+/* MR6  30-May-97 Bug reported by Manuel Ornato				            */

+/* MR6            A definite bug involving the exit from a loop block   */

+/* MR6 		  In 1.23 and later versions (including 1.33) Instead       */

+/* MR6              exiting the block and reporting a syntax error the  */

+/* MR6		    code loops forever.     				                */

+/* MR6	          Looking at 1.20 which generates proper code it is not */

+/* MR6		    clear which of two changes should be undone.            */

+/* MR6		  This is my best guess.                                    */

+/* MR6		  From earlier MR6 note we know that begin can never be     */

+/* MR6		    null when genLoopBlk called from genLoopBegin           */

+/* MR6 */

+/* MR6 */ if ( begin==NULL) {

+/* MR6 */   /* code for exiting loop "for sure" */

+/* MR6 */   gen("/* Suppressed by MR6 */ /*** else break; ***/\n");

+/* MR6 */ };

+

+/* MR10 */if (singleAlt && guessBlock) {

+/* MR10 */  tabs--;

+/* MR6 */   gen("} else break; /* MR6 code for exiting loop \"for sure\" */\n");

+/* MR10 */  need_right_curly--;

+/* MR10 */ } else {

+/* MR6 */   gen("else break; /* MR6 code for exiting loop \"for sure\" */\n");

+/* MR10 */ };

+

+	{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+	if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);

+	--tabs;

+	gen("}\n");

+	q->visited = FALSE;

+	tokensRefdInBlock = savetkref;

+}

+

+/*

+ * Generate code for a loop blk of form:

+ *

+ * 				         |---|

+ *					     v   |

+ *			   --o-->o-->o-G-o-->o--

+ *                   |           ^

+ *                   v           |

+ *					 o-----------o

+ *

+ * q->end points to the last node (far right) in the blk.

+ *

+ * Note that q->end->jtype must be 'EndBlk'.

+ *

+ * Generate code roughly of the following form:

+ *

+ *	do {

+ *		... code for alternatives ...

+ *  } while ( First Set of aLoopBlk );

+ *

+ *	OR if > 1 alternative

+ *

+ *	do {

+ *		... code for alternatives ...

+ *		else break;

+ *  } while ( 1 );

+ */

+void

+#ifdef __USE_PROTOS

+genLoopBegin( Junction *q )

+#else

+genLoopBegin( q )

+Junction *q;

+#endif

+{

+	set f;

+	int i;

+	int max_k;

+	set savetkref;

+	savetkref = tokensRefdInBlock;

+	require(q!=NULL,				"genLoopBegin: invalid node and/or rule");

+	require(q->ntype == nJunction,	"genLoopBegin: not junction");

+	require(q->jtype == aLoopBegin,	"genLoopBegin: not loop block");

+	require(q->p2!=NULL,			"genLoopBegin: invalid Loop Graph");

+

+    OutLineInfo(output,q->line,FileStr[q->file]);

+

+	BLOCK_Preamble(q);

+	BlkLevel++;

+    BlockPreambleOption(q,q->pFirstSetSymbol);       /* MR21 */

+	f = First(q, 1, aLoopBegin, &max_k);

+	/* If not simple LL(1), must specify to start at LoopBegin, not LoopBlk */

+	if ( LL_k>1 && !set_nil(q->fset[2]) )

+		genLoopBlk( q, (Junction *)q->p1, q, max_k );

+	else genLoopBlk( q, (Junction *)q->p1, NULL, max_k );

+

+	for (i=1; i<=CLL_k; i++) set_free(q->fset[i]);

+	for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]);

+	--BlkLevel;

+	BLOCK_Tail();

+	set_free(f);

+	tokensRefdInBlock = savetkref;

+/* MR21 */	if (MR_BlkErr) {

+/* MR21 */		set f, fArray[2];

+/* MR21 */		f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ );

+/* MR21 */      fArray[0]= empty;

+/* MR21 */		fArray[1]= set_dup(f);

+/* MR21 */      gen("if (");

+/* MR21 */      genExprSets(fArray,1);  /* note: destroys set arguments */

+/* MR21 */      _gen(") { /* MR21 option -mrblksynerr */\n");

+/* MR21 */      tabs++;

+/* MR21 */      tab();

+/* MR21 */      _gen("/* nothing */ }\n");

+/* MR21 */      tab();

+/* MR21 */      makeErrorClause(q,f,1,0 /* use plus block bypass ? */ );  /* frees set */

+/* MR21 */      tabs--;

+/* MR21 */	};

+	if (q->end->p1 != NULL) TRANS(q->end->p1);

+}

+

+/*

+ * Generate code for a loop blk of form:

+ *

+ * 					 |---|

+ *					 v   |

+ *			       --o-G-o-->o--

+ *

+ * q->end points to the last node (far right) in the blk.

+ * Note that q->end->jtype must be 'EndBlk'.

+ *

+ * Generate code roughly of the following form:

+ *

+ *	do {

+ *		... code for alternatives ...

+ *  } while ( First Set of aPlusBlk );

+ *

+ *	OR if > 1 alternative

+ *

+ *	do {

+ *		... code for alternatives ...

+ *		else if not 1st time through, break;

+ *  } while ( 1 );

+ */

+void

+#ifdef __USE_PROTOS

+genPlusBlk( Junction *q )

+#else

+genPlusBlk( q )

+Junction *q;

+#endif

+{

+	int         max_k;

+	set         f;

+	int         need_right_curly;

+	int			lastAltEmpty;	/* MR23 */

+	set         savetkref;

+    Junction    *guessBlock;    /* MR10 */

+    int         singleAlt;      /* MR10 */

+

+	savetkref = tokensRefdInBlock;

+	require(q!=NULL,				"genPlusBlk: invalid node and/or rule");

+	require(q->ntype == nJunction,	"genPlusBlk: not junction");

+	require(q->jtype == aPlusBlk,	"genPlusBlk: not Plus block");

+	require(q->p2 != NULL,			"genPlusBlk: not a valid Plus block");

+

+	if ( q->visited ) return;

+	q->visited = TRUE;

+    OutLineInfo(output,q->line,FileStr[q->file]);

+	BLOCK_Preamble(q);

+	BlkLevel++;

+

+    BlockPreambleOption((Junction *)q, q->pFirstSetSymbol);       /* MR21 */

+    

+    /* first_item_is_guess_block  doesn't care what kind of node it is */

+

+    guessBlock=first_item_is_guess_block( (Junction *)q->p1);   /* MR10 */

+

+	/* if the ignore flag is set on the 2nd alt and that alt is empty,

+	 * then it is the implied optional alternative that we added for (...)+

+	 * and, hence, only 1 alt.

+	 */

+

+/* MR10  Reported by Pulkkinen Esa (esap@cs.tut.fi)

+ *       Outer code for guess blocks ignored when there is only one alt

+ *         for a (...)+ block.

+ *       Force use of regular code rather than "optimized" code for that case

+ */

+

+    singleAlt=( ( (Junction *) q->p2)->p2 == NULL) &&

+        	  ( ( (Junction *) q->p2)->ignore );			/* only one alternative? */

+

+    if (singleAlt && !guessBlock)   /* MR10 */

+	{

+

+		Predicate *a=NULL;

+		/* if the only alt has a semantic predicate, hoist it; must test before

+		 * entering loop.

+		 */

+		if ( ParseWithPredicates )

+		{

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+			a = MR_find_predicates_and_supp((Node *)q);

+            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");

+

+			if ( a!=NULL ) {

+				gen("if (");

+				a=genPredTreeMain(a, (Node *)q);    /* MR10 */

+				_gen(") {\n");

+			}

+		}

+		gen("do {\n");

+		tabs++;

+		TRANS(q->p1);

+		if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);

+		f = First(q, 1, aPlusBlk, &max_k);

+		if ( DemandLookahead ) {

+			if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}

+			else gen1("look(%d);\n", max_k);

+		}

+		--tabs;

+		gen("} while ( ");

+		if ( q->parm!=NULL && q->predparm ) _gen1("(%s) && ", q->parm);

+		genExpr(q);

+		if ( ParseWithPredicates && a!=NULL )

+		{

+            if (! MR_comparePredicates(q->predicate,a)) {

+    			_gen("&&");

+    			a=genPredTreeMain(a, (Node *)q);    /* MR10 */

+            };

+		}

+		_gen(" );\n");

+		if ( ParseWithPredicates && a!=NULL ) gen("}\n");

+		--BlkLevel;

+		BLOCK_Tail();

+		q->visited = FALSE;

+		freeBlkFsets(q);

+		set_free(f);

+		tokensRefdInBlock = savetkref;

+/* MR21 */	if (MR_BlkErr) {

+/* MR21 */		set f, fArray[2];

+/* MR21 */		f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ );

+/* MR21 */      fArray[0]= empty;

+/* MR21 */		fArray[1]= set_dup(f);

+/* MR21 */      gen("if (");

+/* MR21 */      genExprSets(fArray,1);  /* note: destroys set arguments */

+/* MR21 */      _gen(") { /* MR21 option -mrblksynerr */\n");

+/* MR21 */      tabs++;

+/* MR21 */      tab();

+/* MR21 */      _gen("/* nothing */ }\n");

+/* MR21 */      tab();

+/* MR21 */      makeErrorClause(q,f,1,1 /* use plus block bypass ? */ );  /* frees set */

+/* MR21 */      tabs--;

+/* MR21 */	};

+		if (q->end->p1 != NULL) TRANS(q->end->p1);

+/* MR10 */  if (MRhoisting) {

+/* MR10 */    predicate_free(a);

+/* MR10 */  };

+		return;

+	}

+	gen("do {\n");

+	tabs++;

+	f = genBlk(q, aPlusBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+/* MR6              									        */

+/* MR6	Sinan Karasu	(sinan@tardis.ds.boeing.com)			*/

+/* MR6    Failed to turn off guess mode when leaving block		*/

+/* MR6				                           					*/

+/* MR6  */ if ( has_guess_block_as_last_item(q) ) {

+/* MR10 */   gen("/* MR10 ()+ */ else {\n");

+/* MR10 */   tabs++;

+/* MR10 */   need_right_curly++;

+/* MR10 */   gen("/* MR10 ()+ */ if ( !zzrv ) zzGUESS_DONE;\n");

+/* MR6  */   gen("/* MR10 ()+ */ if ( zzcnt > 1 ) break;\n");

+/* MR10 */ } else {

+/* MR10 */   gen("/* MR10 ()+ */ else {\n");

+/* MR10 */   tabs++;

+/* MR10 */   need_right_curly++;

+/* MR10 */   gen("if ( zzcnt > 1 ) break;\n");

+/* MR10 */ };

+

+/* MR21 */	if (MR_BlkErr && 1 >= max_k) {

+/* MR21 */		set f;

+/* MR21 */		f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ );

+/* MR21 */      tabs++;

+/* MR21 */      tab();

+/* MR21 */      makeErrorClause(q,f,1,0 /* use plus block bypass ? */ );  /* frees set */

+/* MR21 */      tabs--;

+/* MR21 */	}

+/* MR21 */  else {

+				tab();

+                makeErrorClause(q,f,max_k,1 /* use plus block bypass ? */);

+										    /* MR21 I think this generates the wrong set ? */

+                                            /* MR21 because it includes the plus block bypass ? */

+										    /* MR21 but I'm afraid to change it without additional checking */

+            }

+

+	{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+	freeBlkFsets(q);

+	gen("zzcnt++;");

+	if ( !GenCC ) _gen1(" zzLOOP(zztasp%d);", BlkLevel-1);

+	_gen("\n");

+	if ( DemandLookahead ) {

+		if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}

+		else gen1("look(%d);\n", max_k);

+	}

+	--tabs;

+	if ( q->parm!=NULL && q->predparm ) {gen1("} while (%s);\n", q->parm);}

+	else gen("} while ( 1 );\n");

+	--BlkLevel;

+	BLOCK_Tail();

+	q->visited = FALSE;

+	tokensRefdInBlock = savetkref;

+/* MR21 */	if (MR_BlkErr) {

+/* MR21 */		set f, fArray[2];

+/* MR21 */		f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ );

+/* MR21 */      fArray[0]= empty;

+/* MR21 */		fArray[1]= set_dup(f);

+/* MR21 */      gen("if (");

+/* MR21 */      genExprSets(fArray,1);  /* note: destroys set arguments */

+/* MR21 */      _gen(") { /* MR21 option -mrblksynerr */\n");

+/* MR21 */      tabs++;

+/* MR21 */      tab();

+/* MR21 */      _gen("/* nothing */ }\n");

+/* MR21 */      tab();

+/* MR21 */      makeErrorClause(q,f,1,1 /* use plus block bypass ? */ );  /* frees set */

+/* MR21 */      tabs--;

+/* MR21 */	};

+	if (q->end->p1 != NULL) TRANS(q->end->p1);

+}

+

+/*

+ * Generate code for a sub blk of alternatives of form:

+ *

+ *			       --o-G1--o--

+ *					 |     ^

+ *					 v    /|

+ *			         o-G2-o|

+ *					 |     ^

+ *					 v     |

+ *				   ..........

+ *					 |     ^

+ *					 v    /

+ *			         o-Gn-o

+ *

+ * q points to the 1st junction of blk (upper-left).

+ * q->end points to the last node (far right) in the blk.

+ * Note that q->end->jtype must be 'EndBlk'.

+ * The last node in every alt points to q->end.

+ *

+ * Generate code of the following form:

+ *	if ( First(G1) ) {

+ *		...code for G1...

+ *	}

+ *	else if ( First(G2) ) {

+ *		...code for G2...

+ *	}

+ *	...

+ *	else {

+ *		...code for Gn...

+ *	}

+ */

+

+void

+#ifdef __USE_PROTOS

+genSubBlk( Junction *q )

+#else

+genSubBlk( q )

+Junction *q;

+#endif

+{

+	int max_k;

+	set f;

+	int need_right_curly;

+	int lastAltEmpty;		/* MR23 */

+	set savetkref;

+	savetkref = tokensRefdInBlock;

+	require(q->ntype == nJunction,	"genSubBlk: not junction");

+	require(q->jtype == aSubBlk,	"genSubBlk: not subblock");

+

+    OutLineInfo(output,q->line,FileStr[q->file]);

+	BLOCK_Preamble(q);

+	BlkLevel++;

+    BlockPreambleOption(q,q->pFirstSetSymbol);       /* MR21 */

+	f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+

+/* MR23

+   Bypass error clause generation when exceptions are used in a sub block

+   in which the last alternative is epsilon.  Example: "(A | B | )". 

+   See multi-line note in genBlk near call to isEmptyAlt.

+*/

+	if (FoundException && lastAltEmpty) {

+		gen("/* MR23 skip error clause for (...| epsilon) when exceptions in use */\n");

+	}

+	else {

+		if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}

+	}

+    

+	{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+	freeBlkFsets(q);

+	--BlkLevel;

+	BLOCK_Tail();

+

+	if ( q->guess )

+	{

+		gen("zzGUESS_DONE\n");

+	}

+

+	/* must duplicate if (alpha)?; one guesses (validates), the

+	 * second pass matches */

+	if ( q->guess && analysis_point(q)==q )

+	{

+        OutLineInfo(output,q->line,FileStr[q->file]);

+		BLOCK_Preamble(q);

+		BlkLevel++;

+		f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+		if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */);}

+		{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+		freeBlkFsets(q);

+		--BlkLevel;

+		BLOCK_Tail();

+	}

+

+	tokensRefdInBlock = savetkref;

+	if (q->end->p1 != NULL) TRANS(q->end->p1);

+}

+

+static int TnodesAllocatedPrevRule=0;

+

+/*

+ * Generate code for a rule.

+ *

+ *		rule--> o-->o-Alternatives-o-->o

+ * Or,

+ *		rule--> o-->o-Alternative-o-->o

+ *

+ * The 1st junction is a RuleBlk.  The second can be a SubBlk or just a junction

+ * (one alternative--no block), the last is EndRule.

+ * The second to last is EndBlk if more than one alternative exists in the rule.

+ *

+ * To get to the init-action for a rule, we must bypass the RuleBlk,

+ * and possible SubBlk.

+ * Mark any init-action as generated so genBlk() does not regenerate it.

+ */

+void

+#ifdef __USE_PROTOS

+genRule( Junction *q )

+#else

+genRule( q )

+Junction *q;

+#endif

+{

+

+	const char * returnValueInitializer;

+

+do {    /* MR10     Change recursion into iteration         */

+

+	int max_k;

+	set follow, rk, f;

+	ActionNode *a;

+	RuleEntry *r;

+	int lastAltEmpty;		/* MR23 */

+	static int file = -1;

+	int need_right_curly;

+	require(q->ntype == nJunction,	"genRule: not junction");

+	require(q->jtype == RuleBlk,	"genRule: not rule");

+

+/* MR14 */    require (MR_BackTraceStack.count == 0,"-alpha MR_BackTraceStack.count != 0");

+/* MR14 */    MR_pointerStackReset(&MR_BackTraceStack);

+/* MR14 */    if (AlphaBetaTrace) MR_MaintainBackTrace=1;

+

+    CurRule=q->rname;                               /* MR11 */

+

+	r = (RuleEntry *) hash_get(Rname, q->rname);

+	if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief");

+	if ( q->file != file )		/* open new output file if need to */

+	{

+/* MR6              									*/

+/* MR6  Simpler to debug when output goes to stdout rather than a file 	*/

+/* MR6				                					*/

+/* MR6 */	if (UseStdout) {

+/* MR6 */	  output = stdout;

+/* MR6 */	} else {

+/* MR6 */  	  if ( output != NULL) fclose( output );

+/* MR6 */	  output = fopen(OutMetaName(outname(FileStr[q->file])), "w");

+/* MR6 */	};

+		require(output != NULL, "genRule: can't open output file");

+

+#ifdef SPECIAL_FOPEN

+       special_fopen_actions(OutMetaName(outname(FileStr[q->file]))); /* MR1 */

+#endif

+		if ( file == -1 ) genHdr1(q->file);

+		else genHdr(q->file);

+		file = q->file;

+	}

+

+    if (InfoM) {

+      fprintf(stderr,"    rule %s\n",q->rname);

+      fflush(output);

+    };

+

+#if 0

+    if (strcmp(q->rname,"***debug***") == 0) {

+      fprintf(stderr,"***debug*** %s reached\n",q->rname);

+      MR_break();

+    };

+#endif

+

+	DumpFuncHeader(q,r);

+	tabs++;

+

+	/* MR23 

+	   

+	   If there is a single return value then it can be initialized in 

+	   the declaration using assignment syntax.  If there are multiple

+	   return values then antlr creates a struct and initialization takes

+	   place element by element for each element of the struct.  For

+       multiple elements the initialization is by assignment so we have

+       to wait until all declarations are done before emitting that code -

+       because of restrictions in C which don't exist in C++.

+

+       In the past (before MR23) the only kind of initialization was

+	   the PURIFY macro which was just a memset() of 0.  Now we allow

+	   the user to specify an initial value.  PURIFY is still used in C

+	   mode because C does not have constructors.  However, PURIFY is

+	   not used in C++ mode because it might overwrite information created

+	   by elements which have their own ctor.

+       

+	*/

+

+	if ( q->ret!=NULL )

+	{

+		if ( hasMultipleOperands(q->ret) )                         /* MR23 */

+		{

+

+            /* Emit initialization code later. */

+

+			gen1("struct _rv%d _retv;\n",r->rulenum);

+		}

+		else

+		{

+            /* Emit initialization code now. */

+

+			tab();

+			DumpType(q->ret, output);

+            returnValueInitializer = getInitializer(q->ret);

+            if (returnValueInitializer == NULL) {                  /* MR23 */

+      			gen(" _retv;\n");                     		    /* MR1 MR3 */

+            }                                                      /* MR23 */

+            else {                                                 /* MR23 */

+                gen1(" _retv = %s;\n", returnValueInitializer);    /* MR23 */

+            }                                                      /* MR23 */

+		}

+	}

+

+    OutLineInfo(output,q->line,FileStr[q->file]);

+

+    if (InfoM) {

+      fflush(output);

+    };

+

+	gen("zzRULE;\n");

+	if ( FoundException )

+	{

+		gen("int _sva=1;\n");

+	}

+	if ( GenCC && GenAST )

+		gen("ASTBase *_ast = NULL, *_sibling = NULL, *_tail = NULL;\n");

+	if ( GenCC ) genTokenPointers(q);

+	if ( GenCC&&GenAST ) genASTPointers(q);

+	if ( q->el_labels!=NULL ) genElementLabels(q->el_labels);

+	if ( FoundException ) gen("int _signal=NoSignal;\n");

+

+	if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel);

+

+/* MR10 */  /* move zzTRACEIN to before init action */

+

+/* MR10 */	if ( TraceGen ) {

+/* MR10 */		if ( GenCC ) {gen1("zzTRACEIN(\"%s\");\n", q->rname);}

+/* MR10 */		else gen1("zzTRACEIN((ANTLRChar *)\"%s\");\n", q->rname);

+/* MR10 */	}

+

+/* MR7      Moved PURIFY() to after all local variables have been declared */

+/* MR7      so that the generated code is valid C as well as C++           */

+/* MR7        Jan Mikkelsen 10-June-1997                                   */

+

+

+     /*

+       MR23    Do the PURIFY macro only for C mode.

+               C++ users should use constructors or initialization expressions.

+     */

+

+	if ( q->ret != NULL )                                            /* MR7 */

+	{                                                                /* MR7 */

+		if (hasMultipleOperands(q->ret)) {                           /* MR23 */

+			if (PURIFY == TRUE) {

+                gen1("PCCTS_PURIFY(_retv,sizeof(struct _rv%d))\n",r->rulenum); /* MR23 */

+            }

+        }                                                            /* MR7 */

+		else {                                                       /* MR7 */

+

+			/* MR23

+			   If there were only one return value operand and

+			   it had an initializer then it would have been

+			   initiailized in the declaration.

+			*/

+

+			returnValueInitializer = getInitializer(q->ret);         /* MR23 */

+			if (returnValueInitializer == NULL) {                    /* MR23 */

+    			if (PURIFY == TRUE) {

+        			gen("PCCTS_PURIFY(_retv,sizeof(");               /* MR23 */

+	    			DumpType(q->ret, output);                        /* MR7 */

+					gen("))\n");                                     /* MR7 */

+				}

+			}                                                        /* MR23 */

+		}                                                            /* MR7 */

+

+        if (hasMultipleOperands(q->ret)) {                           /* MR23 */

+          DumpInitializers(output, r, q->ret);                       /* MR23 */

+        }

+

+	}

+	if ( !GenCC ) gen("zzMake0;\n");

+	if ( FoundException ) gen("*_retsignal = NoSignal;\n");

+

+	if ( !GenCC ) gen("{\n");

+

+	if ( has_guess_block_as_first_item((Junction *)q->p1) )

+	{

+		gen("zzGUESS_BLOCK\n");

+	}

+

+	/* L o o k  F o r  I n i t  A c t i o n */

+	if ( ((Junction *)q->p1)->jtype == aSubBlk )

+		a = findImmedAction( ((Junction *)q->p1)->p1 );

+	else

+		a = findImmedAction( q->p1 );	/* only one alternative in rule */

+	if ( a!=NULL && !a->is_predicate)

+	{

+ /* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1);

+  		    a->done = 1;	/* ignore action. We have already handled it */

+	}

+

+	BlkLevel++;

+	q->visited = TRUE;				/* mark RULE as visited for FIRST/FOLLOW */

+    BlockPreambleOption((Junction *)q->p1, NULL);   /* MR21 */

+	f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);

+	if ( q->p1 != NULL )

+		if ( ((Junction *)q->p1)->p2 != NULL )

+			{tab(); makeErrorClause((Junction *)q->p1,f,max_k,0 /* use plus block bypass ? */);}

+	{ int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }

+	freeBlkFsets((Junction *)q->p1);

+	q->visited = FALSE;

+	--BlkLevel;

+	if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel);

+

+    genTraceOut(q);

+

+	if ( q->ret!=NULL ) gen("return _retv;\n") else gen("return;\n");

+	/* E r r o r  R e c o v e r y */

+	NewSet();

+	rk = empty;

+

+/* MR14 */    if (r->dontComputeErrorSet) {

+/* MR14 */      follow=empty;

+              } else {

+                MR_pointerStackReset(&MR_BackTraceStack);   /* MR14 */

+                MR_ErrorSetComputationActive=1;

+                REACH(q->end, 1, &rk, follow);

+                MR_ErrorSetComputationActive=0;

+                require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");

+              }

+

+  FillSet( follow );

+	set_free( follow );

+

+  /* MR20 G. Hobbelt 

+     Isn't it so that "fail:" is ONLY referenced when:

+

+      	 !FoundException || FoundGuessBlk ?

+

+     Therefore add the "if" around this piece of code generation...

+

+     Should guessing mode also use _handler label instead of "fail"

+     when exception handling is active? gen can automatically put 

+     "if (guessing)" there so as to skip all kinds of user code.

+

+   */

+

+	if ( !FoundException || FoundGuessBlk )  /* MR20 G. Hobbelt */

+  {                                          /* MR20 G. Hobbelt */

+	_gen("fail:\n");

+	if ( !GenCC ) gen("zzEXIT(zztasp1);\n");

+	if ( FoundGuessBlk ) {

+	   	if ( !GenCC ) {gen("if ( zzguessing ) zzGUESS_FAIL;\n");}

+		else gen("if ( guessing ) zzGUESS_FAIL;\n");

+	}

+	if ( q->erraction!=NULL )

+		dumpAction(q->erraction, output, tabs, q->file, q->line, 1);

+	if ( GenCC )

+	{

+		gen1("syn(zzBadTok, %s, zzMissSet, zzMissTok, zzErrk);\n",

+			 r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup);

+	}

+	else

+	{

+		gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);\n",

+			 r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup);

+	}

+	gen3("%sresynch(setwd%d, 0x%x);\n", GenCC?"":"zz", wordnum, 1<<setnum);

+

+	if ( q->ret!=NULL ) {

+      genTraceOut(q);

+      gen("return _retv;\n");

+    } else if ( q->exceptions!=NULL ) {

+      genTraceOut(q);

+      gen("return;\n");

+    } else if (!FoundException) {       /* MR10 */

+      genTraceOut(q);                   /* MR10 */

+    };

+

+  }                                        /* MR20 G. Hobbelt */

+

+	if ( !GenCC ) gen("}\n");

+

+	/* Gen code for exception handlers */

+    /* make sure each path out contains genTraceOut() */

+

+	if ( q->exceptions!=NULL )

+	{

+

+		gen("/* exception handlers */\n");

+

+		dumpExceptions(q->exceptions);

+

+        if ( !r->has_rule_exception )

+        {

+            _gen("_handler:\n");

+            gen("zzdflthandlers(_signal,_retsignal);\n");

+        }

+/*  MR20 G. Gobbelt   The label "adios" is never referenced */

+

+#if 0

+	_gen("_adios:\n");

+#endif

+    if ( q->ret!=NULL ) {

+            genTraceOut(q);

+            gen("return _retv;\n");

+        }

+		else {

+            genTraceOut(q);

+            gen("return;\n");

+        }

+	}

+	else if ( FoundException )

+	{

+      _gen("_handler:\n");

+      gen("zzdflthandlers(_signal,_retsignal);\n");

+

+/* MR1                                                                      */

+/* MR1	 7-Apr-97 Fix suggested by: John Bair (jbair@iftime.com)            */

+/* MR1							                                            */

+

+   	  if ( q->ret != NULL) {			                             /* MR1 */

+            genTraceOut(q);                                          /* MR10 */

+            gen("return _retv;\n");			                         /* MR1 */

+      } else {					                                     /* MR1 */

+            genTraceOut(q);                                          /* MR10 */

+            gen("return;\n")    ;				                     /* MR1 */

+      };						                                     /* MR1 */

+	}

+

+	tabs--;

+	gen("}\n");

+

+/* MR10     Tired of looking at stacks that are as deep as the number of    */

+/* MR10       rules.  Changes recursion to iteration.                       */

+

+    MR_releaseResourcesUsedInRule( (Node *) q );      /* MR10 */

+

+    if (InfoT) {

+      fprintf(output,"\n/* tnodes created for rule %s:  %d */\n",

+                q->rname, (TnodesAllocated-TnodesAllocatedPrevRule) );

+    };

+

+    TnodesAllocatedPrevRule=TnodesAllocated;

+

+    if (q->p2 == NULL) dumpAfterActions( output );

+    q=(Junction *)q->p2;

+    require(q==NULL || q->jtype==RuleBlk,"RuleBlk p2 does not point to another RuleBlk");

+

+} while (q != NULL);

+

+/**** The old code                           ****/

+/****	if ( q->p2 != NULL ) {TRANS(q->p2);} ****/ /* generate code for next rule too */

+/****	else dumpAfterActions( output );     ****/

+

+}

+

+

+/* This is for the function definition, not the declaration. */

+

+static void

+#ifdef __USE_PROTOS

+DumpFuncHeader( Junction *q, RuleEntry *r )

+#else

+DumpFuncHeader( q, r )

+Junction *q;

+RuleEntry *r;

+#endif

+{

+/*								                                            */

+/*  MR1 10-Apr-97  MR1  Simplify insertion of commas in function header     */

+/*								                                            */

+	int	needComma;					                                 /* MR1 */

+

+

+	/* A N S I */

+	_gen("\n");

+	if ( q->ret!=NULL )

+	{

+		if ( hasMultipleOperands(q->ret) )                            /* MR23 */

+		{

+			if (GenCC) gen2("%s::_rv%d\n", CurrentClassName, r->rulenum)

+			else gen1("struct _rv%d\n",r->rulenum);

+		}

+		else

+		{

+			DumpType(q->ret, output);

+			gen("\n");

+		}

+	}

+	else

+	{

+		_gen("void\n");

+	}

+/*  MR1			                                                            */

+/*  MR1	10-Apr-97  133MR1	Replace __STDC__ with __USE_PROTOS              */

+/*  MR1								                                        */

+	if ( !GenCC ) _gen("#ifdef __USE_PROTOS\n");		     /* MR1 */

+	if ( !GenCC ) gen2("%s%s(", RulePrefix, q->rname)

+	else gen3("%s::%s%s(", CurrentClassName, RulePrefix,q->rname);

+

+    	/* If we generate C++ method names, we must hide default arguments */

+        /* which can appear in the parameter declaration list.             */

+        /* NOTICE: this is done only here, for the method definition, but  */

+        /*         not for the method declaration inside the class         */

+        /*         definition. This is exactly the behaviour defined in    */

+        /*         C++ standard for default paramters.                     */

+

+	DumpANSIFunctionArgDef(output,q, 0 /* emit initializers ? */);

+	_gen("\n");

+

+	if ( GenCC ) {

+      gen("{\n");

+      return;

+    }

+

+	/* K & R */

+	gen("#else\n");

+	gen2("%s%s(", RulePrefix, q->rname);

+	needComma=0;						                             /* MR1 */

+	if ( GenAST )						                             /* MR1 */

+	{							                                     /* MR1 */

+		_gen("_root");					                             /* MR1 */

+		needComma=1;					                             /* MR1 */

+	}							                                     /* MR1 */

+	if ( FoundException )					                         /* MR1 */

+	{							                                     /* MR1 */

+		if (needComma) {_gen(",");needComma=0;};	                 /* MR1 */

+		_gen("_retsignal");				                             /* MR1 */

+		needComma=1;					                             /* MR1 */

+	}							                                     /* MR1 */

+/* MR5	Change below by Jan Mikkelsen (janm@zeta.org.au) 26-May-97      MR5 */

+	DumpListOfParmNames( q->pdecl, output, needComma );	             /* MR5 */

+	gen(")\n");

+	if ( GenAST ) gen("AST **_root;\n");

+	if ( FoundException ) gen("int *_retsignal;\n");

+	DumpOldStyleParms( q->pdecl, output );

+	gen("#endif\n");

+    gen("{\n");

+}

+

+void

+#ifdef __USE_PROTOS

+DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInitializer)

+#else

+DumpANSIFunctionArgDef(f,q,bInitializer)

+FILE *f;

+Junction *q;

+int bInitializer;

+#endif

+{

+	if ( GenAST )

+	{

+		if ( GenCC ) {fprintf(f,"ASTBase **_root");}

+		else fprintf(f,"AST**_root");

+		if ( !FoundException && q->pdecl!=NULL ) fprintf(f,",");

+	}

+	if ( FoundException )

+	{

+		if ( GenAST ) fprintf(f,",");

+		fprintf(f,"int *_retsignal");

+		if ( q->pdecl!=NULL ) {

+            fprintf(f,",");

+        }

+	}

+	if ( q->pdecl!=NULL ) {

+        DumpFormals(f, q->pdecl, bInitializer);     /* MR23 */

+    }

+	else {

+        if ( !GenAST && !FoundException ) {

+            fprintf(f,"void");

+        }

+    }

+	fprintf(f,")");

+}

+

+void

+#ifdef __USE_PROTOS

+genJunction( Junction *q )

+#else

+genJunction( q )

+Junction *q;

+#endif

+{

+	require(q->ntype == nJunction,	"genJunction: not junction");

+	require(q->jtype == Generic,	"genJunction: not generic junction");

+

+	if ( q->p1 != NULL ) TRANS(q->p1);

+	if ( q->p2 != NULL ) TRANS(q->p2);

+}

+

+void

+#ifdef __USE_PROTOS

+genEndBlk( Junction *q )

+#else

+genEndBlk( q )

+Junction *q;

+#endif

+{

+}

+

+void

+#ifdef __USE_PROTOS

+genEndRule( Junction *q )

+#else

+genEndRule( q )

+Junction *q;

+#endif

+{

+}

+

+void

+#ifdef __USE_PROTOS

+genHdr( int file )

+#else

+genHdr( file )

+int file;

+#endif

+{

+    int     i;

+

+	_gen("/*\n");

+	_gen(" * A n t l r  T r a n s l a t i o n  H e a d e r\n");

+	_gen(" *\n");

+	_gen(" * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");

+	_gen(" * Purdue University Electrical Engineering\n");

+	_gen(" * With AHPCRC, University of Minnesota\n");

+	_gen1(" * ANTLR Version %s\n", Version);

+	_gen(" *\n");

+/* MR10 */    _gen(" *  ");

+/* MR10 */    for (i=0 ; i < Save_argc ; i++) {

+/* MR10 */      _gen(" ");

+/* MR10 */      _gen(Save_argv[i]);

+/* MR10 */    };

+	_gen("\n");

+	_gen(" *\n");

+    _gen(" */\n\n");

+	if (FirstAction != NULL ) dumpAction( FirstAction, output, 0, -1, 0, 1);    /* MR11 MR15b */

+	_gen1("#define ANTLR_VERSION	%s\n", VersionDef);

+	_gen("#include \"pcctscfg.h\"\n");

+	_gen("#include \"pccts_stdio.h\"\n");

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+		_gen2("#define %s %s\n", DefaultParserName, ParserName);

+   	if ( strcmp(ParserName, DefaultParserName)!=0 )

+		{_gen1("#include \"%s\"\n", RemapFileName);}

+    OutLineInfo(output,1,FileStr[file]);

+	if ( GenCC ) {

+		if ( UserTokenDefsFile != NULL )

+			fprintf(output, "#include %s\n", UserTokenDefsFile);

+		else

+			fprintf(output, "#include \"%s\"\n", DefFileName);

+	}

+

+	if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1);

+	if ( !GenCC && FoundGuessBlk )

+	{

+		_gen("#define ZZCAN_GUESS\n");

+		_gen("#include \"pccts_setjmp.h\"\n");  /* MR15 K.J. Cummings (cummings@peritus.com) */

+	}

+	if ( FoundException )

+	{

+		_gen("#define EXCEPTION_HANDLING\n");

+		_gen1("#define NUM_SIGNALS %d\n", NumSignals);

+	}

+	if ( !GenCC && OutputLL_k > 1 ) _gen1("#define LL_K %d\n", OutputLL_k);

+	if ( GenAST&&!GenCC ) _gen("#define GENAST\n\n");

+	if ( GenAST ) {

+		if ( GenCC ) {_gen1("#include \"%s\"\n\n", ASTBASE_H);}

+		else _gen("#include \"ast.h\"\n\n");

+	}

+	if ( !GenCC && DemandLookahead ) _gen("#define DEMAND_LOOK\n\n");

+#ifdef DUM

+	if ( !GenCC && LexGen ) {

+		_gen1("#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));

+	}

+#endif

+	/* ###WARNING: This will have to change when SetWordSize changes */

+	if ( !GenCC ) _gen1("#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));

+    if (TraceGen) {

+      _gen("#ifndef zzTRACE_RULES\n");  /* MR20 */

+      _gen("#define zzTRACE_RULES\n");  /* MR20 */

+      _gen("#endif\n");                 /* MR22 */

+    };

+	if ( !GenCC ) {_gen("#include \"antlr.h\"\n");}

+	else {

+		_gen1("#include \"%s\"\n", APARSER_H);

+		_gen1("#include \"%s.h\"\n", CurrentClassName);

+	}

+	if ( !GenCC ) {

+		if ( UserDefdTokens )

+			{_gen1("#include %s\n", UserTokenDefsFile);}

+		/* still need this one as it has the func prototypes */

+		_gen1("#include \"%s\"\n", DefFileName);

+	}

+	/* still need this one as it defines the DLG interface */

+	if ( !GenCC ) _gen("#include \"dlgdef.h\"\n");

+	if ( LexGen && GenCC ) _gen1("#include \"%s\"\n", DLEXERBASE_H);

+	if ( GenCC ) _gen1("#include \"%s\"\n", ATOKPTR_H);

+	if ( !GenCC && LexGen ) _gen1("#include \"%s\"\n", ModeFileName);

+

+/* MR10  Ofer Ben-Ami (gremlin@cs.huji.ac.il)           */

+/* MR10    Finally, a definition of the Purify macro    */

+

+    if (PURIFY == TRUE) {                                                   /* MR23 */

+        _gen("\n/* MR23 In order to remove calls to PURIFY use the antlr"); /* MR23 */

+        _gen(" -nopurify option */\n\n");                                   /* MR23 */

+    	_gen("#ifndef PCCTS_PURIFY\n");

+        _gen("#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\\0',(s));\n");

+        _gen("#endif\n\n");

+    }                                                                       /* MR23 */

+}

+

+void

+#ifdef __USE_PROTOS

+genHdr1( int file )

+#else

+genHdr1( file )

+int file;

+#endif

+{

+	ListNode *p;

+

+	genHdr(file);

+	if ( GenAST )

+	{

+		if ( !GenCC ) {

+			_gen("#include \"ast.c\"\n");

+			_gen("zzASTgvars\n\n");

+		}

+	}

+	if ( !GenCC ) _gen("ANTLR_INFO\n");

+	if ( BeforeActions != NULL )

+	{

+		for (p = BeforeActions->next; p!=NULL; p=p->next)

+		{

+			UserAction *ua = (UserAction *)p->elem;

+			dumpAction( ua->action, output, 0, ua->file, ua->line, 1);

+		}

+	}

+

+	if ( !FoundException ) return;

+

+	if ( GenCC )

+	{

+		_gen1("\nvoid %s::\n", CurrentClassName);

+		_gen("zzdflthandlers( int _signal, int *_retsignal )\n");

+		_gen("{\n");

+	}

+	else

+	{

+		_gen("\nvoid\n");

+/*  MR1				                                                        */

+/*  MR1	10-Apr-97  133MR1	Replace __STDC__ with __USE_PROTOS              */

+/*  MR1	                                                                    */

+	    _gen("#ifdef __USE_PROTOS\n");                               /* MR1 */

+		_gen("zzdflthandlers( int _signal, int *_retsignal )\n");

+		_gen("#else\n");

+		_gen("zzdflthandlers( _signal, _retsignal )\n");

+		_gen("int _signal;\n");

+		_gen("int *_retsignal;\n");

+		_gen("#endif\n");

+		_gen("{\n");

+	}

+	tabs++;

+	if ( DefaultExGroup!=NULL )

+	{

+		dumpException(DefaultExGroup, 1);

+		if ( !hasDefaultException(DefaultExGroup) )

+		{

+			gen("default :\n");

+			tabs++;

+			gen("*_retsignal = _signal;\n");

+			tabs--;

+			gen("}\n");

+		}

+	}

+	else {

+		gen("*_retsignal = _signal;\n");

+	}

+

+	tabs--;

+	_gen("}\n\n");

+}

+

+void

+#ifdef __USE_PROTOS

+genStdPCCTSIncludeFile( FILE *f,char *gate )    /* MR10 */

+#else

+genStdPCCTSIncludeFile( f , gate)               /* MR10 */

+FILE *f;

+char * gate;                                    /* MR10 */

+#endif

+{

+/* MR10 Ramanathan Santhanam (ps@kumaran.com)           */

+/* MR10 Same preprocessor symbol use to gate stdpccts.h */

+/* MR10   even when two grammars are in use.            */

+/* MR10 Derive gate symbol from -fh filename            */

+

+    if (gate == NULL) {

+      fprintf(f,"#ifndef STDPCCTS_H\n");          /* MR10 */

+      fprintf(f,"#define STDPCCTS_H\n");          /* MR10 */

+    } else {

+      fprintf(f,"#ifndef STDPCCTS_%s_H\n",gate);  /* MR10 */

+      fprintf(f,"#define STDPCCTS_%s_H\n",gate);  /* MR10 */

+    };

+	fprintf(f,"/*\n");

+    if (gate == NULL) {

+	  fprintf(f," * %s -- P C C T S  I n c l u d e\n", stdpccts);

+    } else {

+	  fprintf(f," * Standard PCCTS include file with -fh %s -- P C C T S  I n c l u d e\n", stdpccts);

+    }

+	fprintf(f," *\n");

+	fprintf(f," * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");

+	fprintf(f," * Purdue University Electrical Engineering\n");

+	fprintf(f," * With AHPCRC, University of Minnesota\n");

+	fprintf(f," * ANTLR Version %s\n", Version);

+	fprintf(f," */\n\n");

+

+    fprintf(f,"#ifndef ANTLR_VERSION\n");

+	fprintf(f,"#define ANTLR_VERSION	%s\n", VersionDef);

+    fprintf(f,"#endif\n\n");

+

+    if (FirstAction != NULL ) dumpAction(FirstAction, f, 0, -1, 0, 1);  /* MR11 */

+

+	fprintf(f,"#include \"pcctscfg.h\"\n");

+	fprintf(f,"#include \"pccts_stdio.h\"\n");

+	if ( GenCC )

+	{

+		if ( UserDefdTokens )

+			fprintf(f, "#include %s\n", UserTokenDefsFile);

+		else {

+			fprintf(f, "#include \"%s\"\n", DefFileName);

+		}

+

+		fprintf(f, "#include \"%s\"\n", ATOKEN_H);

+

+		if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);

+

+		fprintf(f, "#include \"%s\"\n", ATOKENBUFFER_H);

+

+		if ( OutputLL_k > 1 ) fprintf(f,"static const unsigned LL_K=%d;\n", OutputLL_k);

+		if ( GenAST ) {

+			fprintf(f, "#include \"%s\"\n", ASTBASE_H);

+		}

+

+        if (TraceGen) {

+          fprintf(f,"#ifndef zzTRACE_RULES\n");  /* MR20 */

+          fprintf(f,"#define zzTRACE_RULES\n");  /* MR20 */

+          fprintf(f,"#endif\n");                 /* MR22 */

+        };

+

+		fprintf(f,"#include \"%s\"\n", APARSER_H);

+		fprintf(f,"#include \"%s.h\"\n", CurrentClassName);

+		if ( LexGen ) fprintf(f,"#include \"%s\"\n", DLEXERBASE_H);

+		fprintf(f, "#endif\n");

+		return;

+	}

+

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+		fprintf(f, "#define %s %s\n", DefaultParserName, ParserName);

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+		fprintf(f, "#include \"%s\"\n", RemapFileName);

+	if ( UserTokenDefsFile != NULL )

+	   fprintf(f, "#include %s\n", UserTokenDefsFile);

+	if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);

+	if ( FoundGuessBlk )

+	{

+		fprintf(f,"#define ZZCAN_GUESS\n");

+		fprintf(f,"#include \"pccts_setjmp.h\"\n");

+	}

+    if (TraceGen) {

+      fprintf(f,"#ifndef zzTRACE_RULES\n");  /* MR20 */

+      fprintf(f,"#define zzTRACE_RULES\n");  /* MR20 */

+      fprintf(f,"#endif\n");                 /* MR22 */

+    };

+	if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %d\n", OutputLL_k);

+	if ( GenAST ) fprintf(f,"#define GENAST\n");

+	if ( FoundException )

+	{

+/* MR1	 7-Apr-97  1.33MR1					                           */

+/* MR1	 	   Fix suggested by:				                   */

+/* MR1		   Francois-Xavier Fontaine (fontaine_f@istvax.ist.lu)         */

+

+		fprintf(f,"#define EXCEPTION_HANDLING\n");	            /* MR1 */

+		fprintf(f,"#define NUM_SIGNALS %d\n", NumSignals);          /* MR1 */

+	}

+	if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOK\n");

+#ifdef DUM

+	if ( LexGen ) fprintf(f, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));

+#endif

+	/* ###WARNING: This will have to change when SetWordSize changes */

+	fprintf(f, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned));

+    if (TraceGen) {

+      fprintf(f,"#ifndef zzTRACE_RULES\n");  /* MR20 */

+      fprintf(f,"#define zzTRACE_RULES\n");  /* MR20 */

+      fprintf(f,"#endif\n");                 /* MR22 */

+    };

+	fprintf(f,"#include \"antlr.h\"\n");

+	if ( GenAST ) fprintf(f,"#include \"ast.h\"\n");

+	if ( UserDefdTokens )

+		fprintf(f, "#include %s\n", UserTokenDefsFile);

+	/* still need this one as it has the func prototypes */

+	fprintf(f, "#include \"%s\"\n", DefFileName);

+	/* still need this one as it defines the DLG interface */

+	fprintf(f,"#include \"dlgdef.h\"\n");

+	/* don't need this one unless DLG is used */

+	if ( LexGen ) fprintf(f,"#include \"%s\"\n", ModeFileName);

+	fprintf(f,"#endif\n");

+}

+

+/* dump action 's' to file 'output' starting at "local" tab 'tabs'

+   Dump line information in front of action if GenLineInfo is set

+   If file == -1 then GenLineInfo is ignored.

+   The user may redefine the LineInfoFormatStr to his/her liking

+   most compilers will like the default, however.

+

+   June '93; changed so that empty lines are left alone so that

+   line information is correct for the compiler/debuggers.

+*/

+void

+#ifdef __USE_PROTOS

+dumpAction( char *s, FILE *output, int tabs, int file, int line,

+int final_newline )

+#else

+dumpAction( s, output, tabs, file, line, final_newline )

+char *s;

+FILE *output;

+int tabs;

+int file;

+int line;

+int final_newline;

+#endif

+{

+    int inDQuote, inSQuote;

+    require(s!=NULL, 		"dumpAction: NULL action");

+    require(output!=NULL,	eMsg1("dumpAction: output FILE is NULL for %s",s));

+

+	if ( GenLineInfo && file != -1 )

+	{

+        OutLineInfo(output,line,FileStr[file]);

+	}

+    PastWhiteSpace( s );

+	/* don't print a tab if first non-white char is a # (preprocessor command) */

+	if ( *s!='#' ) {TAB;}

+    inDQuote = inSQuote = FALSE;

+    while ( *s != '\0' )

+    {

+        if ( *s == '\\' )

+        {

+            fputc( *s++, output ); /* Avoid '"' Case */

+            if ( *s == '\0' ) return;

+            if ( *s == '\'' ) fputc( *s++, output );

+            if ( *s == '\"' ) fputc( *s++, output );

+        }

+        if ( *s == '\'' )

+        {

+            if ( !inDQuote ) inSQuote = !inSQuote;

+        }

+        if ( *s == '"' )

+        {

+            if ( !inSQuote ) inDQuote = !inDQuote;

+        }

+        if ( *s == '\n' )

+        {

+            fputc('\n', output);

+			s++;

+            PastWhiteSpace( s );

+            if ( *s == '}' )

+            {

+                --tabs;

+				TAB;

+                fputc( *s++, output );

+                continue;

+            }

+            if ( *s == '\0' ) return;

+			if ( *s != '#' )	/* #define, #endif etc.. start at col 1 */

+            {

+				TAB;

+			}

+        }

+        if ( *s == '}' && !(inSQuote || inDQuote) )

+        {

+            --tabs;            /* Indent one fewer */

+        }

+        if ( *s == '{' && !(inSQuote || inDQuote) )

+        {

+            tabs++;            /* Indent one more */

+        }

+        fputc( *s, output );

+        s++;

+    }

+    if ( final_newline ) fputc('\n', output);

+}

+

+static void

+#ifdef __USE_PROTOS

+dumpAfterActions( FILE *output )

+#else

+dumpAfterActions( output )

+FILE *output;

+#endif

+{

+	ListNode *p;

+	require(output!=NULL, "dumpAfterActions: output file was NULL for some reason");

+	if ( AfterActions != NULL )

+	{

+		for (p = AfterActions->next; p!=NULL; p=p->next)

+		{

+			UserAction *ua = (UserAction *)p->elem;

+			dumpAction( ua->action, output, 0, ua->file, ua->line, 1);

+		}

+	}

+	fclose( output );

+}

+

+/*

+ * Find the next action in the stream of execution.  Do not pass

+ * junctions with more than one path leaving them.

+ * Only pass generic junctions.

+ *

+ *	Scan forward while (generic junction with p2==NULL)

+ *	If we stop on an action, return ptr to the action

+ *	else return NULL;

+ */

+static ActionNode *

+#ifdef __USE_PROTOS

+findImmedAction( Node *q )

+#else

+findImmedAction( q )

+Node *q;

+#endif

+{

+	Junction *j;

+	require(q!=NULL, "findImmedAction: NULL node");

+	require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node");

+	

+	while ( q->ntype == nJunction )

+	{

+		j = (Junction *)q;

+		if ( j->jtype != Generic || j->p2 != NULL ) return NULL;

+		q = j->p1;

+		if ( q == NULL ) return NULL;

+	}

+	if ( q->ntype == nAction ) return (ActionNode *)q;

+	return NULL;

+}

+

+static void

+#ifdef __USE_PROTOS

+dumpRetValAssign( char *retval, char *ret_def, RuleRefNode * ruleRef /* MR30 */)

+#else

+dumpRetValAssign( retval, ret_def, ruleRef /* MR30 */)

+char *retval;

+char *ret_def;

+RuleRefNode *ruleRefNode;

+#endif

+{

+	char *q = ret_def;

+	

+	tab();

+	while ( *retval != '\0' && *q != '\0')

+	{

+		while ( isspace((*retval)) ) retval++;

+		while ( *retval!=',' && *retval!='\0' ) fputc(*retval++, output);

+		fprintf(output, " = _trv.");

+		

+		DumpNextNameInDef(&q, output);

+		while ( isspace(*q) ) q++;

+		fputc(';', output); fputc(' ', output);

+		if ( *retval == ',' ) retval++;

+	}

+	if (*retval == '\0' && *q != '\0') {

+/* MR30 */    errFL("Fewer output values than output formals for rule reference",

+/* MR30 */                 FileStr[ruleRef->file],ruleRef->line);

+	}

+	if (*retval != '\0' && *q == '\0') {

+/* MR30 */    errFL("More output actuals than output formals for rule reference",

+/* MR30 */                 FileStr[ruleRef->file],ruleRef->line);

+	}

+}

+

+/* This function computes the set of tokens that can possibly be seen k

+ * tokens in the future from point j

+ */

+

+static set

+#ifdef __USE_PROTOS

+ComputeErrorSet( Junction *j, int k, int usePlusBlockBypass)

+#else

+ComputeErrorSet( j, k, usePlusBlockBypass )

+Junction *j;

+int k;

+int usePlusBlockBypass;

+#endif

+{

+	Junction *alt1;

+	set a, rk, f;

+	require(j->ntype==nJunction, "ComputeErrorSet: non junction passed");

+

+	f = rk = empty;

+	for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2)

+	{

+        if (alt1->ignore && ! usePlusBlockBypass) continue;     /* MR21 - Ignore aPlusBlk forward p2 */

+		REACH(alt1->p1, k, &rk, a);

+		require(set_nil(rk), "ComputeErrorSet: rk != nil");

+		set_free(rk);

+		set_orin(&f, a);

+		set_free(a);

+	}

+	return f;

+}

+

+static char *

+#ifdef __USE_PROTOS

+tokenFollowSet(TokNode *p)

+#else

+tokenFollowSet(p)

+TokNode *p;

+#endif

+{

+    static char buf[100];

+    set rk, a;

+    int n;

+    rk = empty;

+

+    REACH(p->next, 1, &rk, a);

+    require(set_nil(rk), "rk != nil");

+    set_free(rk);

+    n = DefErrSet( &a, 0, NULL );

+    set_free(a);

+    if ( GenCC )

+        sprintf(buf, "err%d", n);

+    else

+        sprintf(buf, "zzerr%d", n);

+    return buf;

+}

+

+static void

+#ifdef __USE_PROTOS

+makeErrorClause( Junction *q, set f, int max_k, int usePlusBlockBypass )

+#else

+makeErrorClause( q, f, max_k, usePlusBlockBypass )

+Junction *q;

+set f;

+int max_k;

+int usePlusBlockBypass;

+#endif

+{

+    char *  handler_id="";                                           /* MR7 */

+    int     nilf=0;                                                  /* MR13 */

+    RuleEntry *ruleEntry;                                            /* MR14 */

+

+	if ( FoundException )

+	{

+		_gen("else {\n");

+		tabs++;

+		if ( FoundGuessBlk )

+		{

+			if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}

+			else gen("if ( zzguessing ) goto fail;\n");

+		}

+		gen("if (_sva) _signal=NoViableAlt;\n");

+		gen("else _signal=NoSemViableAlt;\n");

+        if (q->outerEG != NULL) {

+          handler_id=q->outerEG->altID;

+#if 0

+        } else {

+          printf("q->curAltNum=%d q->exception_label=%s\n",q->curAltNum,q->exception_label);

+          gen("*** DEBUG *** outerEG==NULL\n");

+#endif

+        };

+		gen1("goto %s_handler;  /* MR7 */\n",handler_id);    /* MR7 */

+		tabs--;

+		gen("}\n");

+		return;

+	}

+

+	if ( max_k == 1 )

+	{

+/* MR13 */  nilf=set_nil(f);

+    	  	if ( GenCC ) {

+              _gen1("else {FAIL(1,err%d", DefErrSet1(1,&f,1,NULL));

+            } else {

+               _gen1("else {zzFAIL(1,zzerr%d", DefErrSet1(1,&f,1,NULL));

+            };

+    		set_free(f);

+	}

+	else

+	{

+		int i;

+		set_free(f);

+		if ( GenCC ) {_gen1("else {FAIL(%d", max_k);}

+		else _gen1("else {zzFAIL(%d", max_k);

+

+    ruleEntry = (RuleEntry *) hash_get(Rname,q->rname);

+

+		for (i=1; i<=max_k; i++)

+		{

+/* MR14 */  if (ruleEntry->dontComputeErrorSet) {

+/* MR14 */    f=empty;

+            } else {

+      	      f = ComputeErrorSet(q, i, usePlusBlockBypass /* use plus block bypass ? */ );

+            }

+

+      if ( GenCC ) {_gen1(",err%d", DefErrSet( &f, 1, NULL ));}

+			else _gen1(",zzerr%d", DefErrSet( &f, 1, NULL ));

+			

+			set_free(f);

+		}

+	}

+	_gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}\n");

+/* MR13 */  if (nilf) {

+/* MR13 */    errFL("empty error set for alt - probably because of undefined rule or infinite left recursion",

+/* MR13 */                 FileStr[q->file],q->line);

+/* MR13 */    gen(" /* MR13 empty error set for this alt - undef rule ? infinite left recursion ? */");

+/* MR13 */  };

+}

+

+static                                                               /* MR7 */

+#ifdef __USE_PROTOS

+char * findOuterHandlerLabel(ExceptionGroup *eg)                     /* MR7 */

+#else

+char * findOuterHandlerLabel(eg)                                     /* MR7 */

+ExceptionGroup *eg;                                                  /* MR7 */

+#endif

+{

+  char              *label=NULL;                                     /* MR7 */

+  ExceptionGroup    *outerEG;                                        /* MR7 */

+

+  if (eg->forRule == 0) {                                            /* MR7 */

+    if (eg->labelEntry != NULL) {                                    /* MR7 */

+      outerEG=eg->labelEntry->outerEG;                               /* MR7 */

+      if (outerEG != NULL) {                                         /* MR7 */

+        label=outerEG->altID;                                        /* MR7 */

+        outerEG->used=1;                                             /* MR7 */

+      };                                                             /* MR7 */

+    } else if (eg->outerEG != NULL) {                                /* MR7 */

+      outerEG=eg->outerEG;                                           /* MR7 */

+      label=outerEG->altID;                                          /* MR7 */

+      outerEG->used=1;                                               /* MR7 */

+    };                                                               /* MR7 */

+  };                                                                 /* MR7 */

+  return (label==NULL ? "" : label);                                 /* MR7 */

+}                                                                    /* MR7 */

+

+/*** debug ***/

+#if 0

+** static                                                               /* MR7 */

+** #ifdef __USE_PROTOS

+** char * findOuterAltHandlerLabel(Junction *startJ)                    /* MR7 */

+** #else

+** char * findOuterAltHandlerLabel(startJ)                              /* MR7 */

+** Junction *startJ;                                                    /* MR7 */

+** #endif

+** {                                                                    /* MR7 */

+**   char      *label=NULL;                                             /* MR7 */

+**   Junction  *alt;                                                    /* MR7 */

+**                                                                      /* MR7 */

+**   for (alt=startJ; alt != NULL; alt=alt->outerAltstart) {            /* MR7 */

+**     label=alt->exception_label;                                      /* MR7 */

+**     if (label != NULL) break;                                        /* MR7 */

+**   };                                                                 /* MR7 */

+**   return (label==NULL ? "" : label);                                 /* MR7 */

+** }                                                                    /* MR7 */

+#endif

+

+#ifdef __USE_PROTOS

+static void OutLineInfo(FILE *file,int line,char *fileName)

+#else

+static void OutLineInfo(file,line,fileName)

+  FILE *    file;

+  int       line;

+  char *    fileName;

+#endif

+{

+    static  char * prevFileName=NULL;

+    static  char * prevFileNameMS=NULL;

+

+    char *  p;

+    char *  q;

+

+    if (! GenLineInfo) return;

+

+    if (!GenLineInfoMS) {

+	    fprintf(file, LineInfoFormatStr,line,fileName);

+    } else {

+      if (fileName == prevFileName) {

+	    fprintf(file, LineInfoFormatStr,line,prevFileNameMS);

+      } else {

+        if (prevFileNameMS != NULL) free (prevFileNameMS);

+        prevFileNameMS=(char *)calloc(1,strlen(fileName)+1);

+        require(prevFileNameMS != NULL,"why not do this in calloc wrapper");

+        q=prevFileNameMS;

+        for (p=fileName; *p != 0; p++) {

+            *q=*p;

+            if (*q == '\\') *q='/';

+            q++;

+        }

+      }

+      prevFileName=fileName;

+    };

+}

+

+#if 0

+

+/* MR21 */

+

+#ifdef __USE_PROTOS

+void OutFirstSetSymbol(Junction *q, char * pSymbol)

+#else

+void OutFirstSetSymbol(q, pSymbol)

+    Junction* q;

+	char * pSymbol

+#endif

+{

+

+	set f;

+    if (pSymbol == NULL) return;

+	gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol);

+    f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */);

+    DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, "");

+    set_free(f);

+}

+#endif

+

+/* MR21 */

+

+#ifdef __USE_PROTOS

+void BlockPreambleOption(Junction *q, char * pSymbol)

+#else

+void BlockPreambleOption(q, pSymbol)

+    Junction* q;

+	char * pSymbol;

+#endif

+{

+	set f = empty;

+    if (pSymbol != NULL) {

+        f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */);

+    	gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol);

+        DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, "");

+    }

+    set_free(f);

+}

+

+/* MR21 */

+

+void

+#ifdef __USE_PROTOS

+dumpActionPlus(ActionNode *a, char *s, FILE *output, int tabs, int file, int line,

+int final_newline )

+#else

+dumpActionPlus(a, s, output, tabs, file, line, final_newline )

+ActionNode *a;

+char *s;

+FILE *output;

+int tabs;

+int file;

+int line;

+int final_newline;

+#endif

+{

+    dumpAction(s,output,tabs,file,line,final_newline);

+}

+

+

+#if 0

+** #ifdef __USE_PROTOS

+** void MR_ErrorSets(Junction *q, int max_k, int usePlusBlockBypass)

+** #else

+** void MR_ErrorSets(q, max_k, usePlusBlockBypass)

+** Junction *q;

+** int max_k;

+** int usePlusBlockBypass;

+** #endif

+** {

+**     int k;

+**     set setResult;

+** 	Junction* alt1;

+** 	Junction* p;

+** 	set rk;

+** 

+**     require (max_k <= CLL_k, "k > CLL_k");

+** 

+** 

+**     for (k = 1; k <= CLL_k; k++) {set_clr(q->fset[k]); }

+** 

+**     for (k = 1; k <= max_k; k++) {

+**         for (alt1=q; alt1 != NULL; alt1 = (Junction *)alt1->p2)

+**     	{

+**             if (alt1->ignore && ! usePlusBlockBypass) continue;

+**         	p = analysis_point((Junction *)alt1->p1);

+**     		REACH(p, k, &rk, setResult);

+**     		require(set_nil(rk), "rk != nil");

+**             set_orin(&q->fset[k], setResult);

+**     	}

+**     }

+** }

+#endif

+

+

+#ifdef __USE_PROTOS

+void DumpInitializers(FILE* output, RuleEntry *r, char * pReturn)

+#else

+void DumpInitializers(output, r, pReturn)

+FILE* output;

+RuleEntry *r;

+char * pReturn;

+#endif

+{

+	char *p = pReturn;

+	char *pDataType;

+	char *pSymbol;

+	char *pEqualSign;

+	char *pValue;

+	char *pSeparator;

+	int nest = 0;

+    char *q;

+

+	require(pReturn!=NULL, "DumpInitializer: invalid string"); 

+

+    while (*p != 0) {

+    	p = endFormal(p,

+    			      &pDataType,

+    				  &pSymbol,

+    				  &pEqualSign,

+    				  &pValue,

+    				  &pSeparator,

+    				  &nest);

+        if (nest != 0) return;

+        if (pValue != NULL) {

+			tab();

+            q = strBetween(pSymbol, pEqualSign, pSeparator);

+            fprintf(output, "_retv.%s", q);

+            q = strBetween(pValue, NULL, pSeparator);

+            fprintf(output, " = %s;\n", q);

+        }

+    }

+}

+

+#ifdef __USE_PROTOS

+void DumpFormals(FILE* output, char * pReturn, int bInitializer)

+#else

+void DumpFormals(output, pReturn, bInitializer)

+FILE* output;

+char * pReturn;

+int bInitializer;

+#endif

+{

+	char *p = pReturn;

+	char *pDataType;

+	char *pSymbol;

+	char *pEqualSign;

+	char *pValue;

+	char *pSeparator;

+	int nest = 0;

+    char *q;

+    int count = 0;

+

+	require(pReturn!=NULL, "DumpFormals: invalid string"); 

+

+    while (*p != 0) {

+    	p = endFormal(p,

+    			      &pDataType,

+    				  &pSymbol,

+    				  &pEqualSign,

+    				  &pValue,

+    				  &pSeparator,

+    				  &nest);

+        if (nest != 0) return;

+        if (count > 0) fprintf(output,",");

+        if (pDataType != NULL && pSymbol != NULL) {

+            q = strBetween(pDataType, pSymbol, pSeparator);

+            fprintf(output, "%s", q);

+            q = strBetween(pSymbol, pEqualSign, pSeparator);

+            fprintf(output," %s",q);

+            if (pValue != NULL) {

+                q = strBetween(pValue, NULL, pSeparator);

+                if (bInitializer != 0) {

+                    fprintf(output, " = %s", q);

+                }

+            }

+        }

+        count++;

+    }

+}

+

+/* MR23 Check for empty alt in a more intelligent way.

+        Previously, an empty alt for genBlk had to point directly

+		to the endBlock.  This did not work once I changed {...}

+		blocks to look like (...|...| epsilon) since there were

+		intervening generics.  This fixes the problem for this

+		particular case.  Things like actions or empty blocks of

+		various kinds will still cause problems, but I wasnt't

+		prepared to handle pathological cases like (A|()*). It

+		does handle (A | ()), which is a recommended idiom for

+		epsilon.

+

+        Actually, this isn't quite correct since it doesn't handle

+		the case of the ignore bit in the plus block bypass, but

+		I'm too tired to figure out the correct fix, and will just

+		work around it.

+*/

+

+#ifdef __USE_PROTOS

+int isEmptyAlt(Node * alt, Node * endBlock)

+#else

+int isEmptyAlt(alt, endBlock)

+Node * alt;

+Node * endBlock;

+#endif

+{

+	Node * n = alt;

+	Junction * j;

+	while (n != endBlock) {

+		switch (n->ntype) {

+

+			case nRuleRef:

+				return 0;

+

+			case nToken:

+				return 0;

+

+			case nAction:

+				return 0;

+

+			case nJunction:

+				goto JUNCTION;

+

+			default:

+				fatal_internal("Invalid node type");

+				return 0;

+		}

+JUNCTION:

+		j = (Junction *) n;

+

+		switch (j->jtype) {

+			case Generic:

+				{

+					n = j->p1;

+					goto NEXT;

+				}

+

+			case aSubBlk:

+				{

+					n = j->p1;	/* MR26 */

+					goto NEXT;	/* MR26 */

+				}

+

+			case EndBlk:

+					return 0;

+

+			case EndRule:

+					return 1;

+

+			default:

+					return 0;

+		}

+NEXT: continue;

+	}

+	return 1;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/generic.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/generic.h
new file mode 100644
index 0000000..8d736d5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/generic.h
@@ -0,0 +1,286 @@
+/*

+ * generic.h -- generic include stuff for new PCCTS ANTLR.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#define StrSame			0

+

+#define DefaultParserName	"zzparser"

+

+/* MR9  JVincent@novell.com     Allow user to override default ZZLEXBUFSIZE  */

+/* MR11 thm                     Raise antlr's own default ZZLEXBUFSIZE to 8k */

+/* MR22 thm                     Raise antlr's own default ZZLEXBUFSIZE to 32k */

+

+#ifndef ZZLEXBUFSIZE

+#define ZZLEXBUFSIZE 32000

+#endif

+

+/* Tree/FIRST/FOLLOW defines -- valid only after all grammar has been read */

+#define ALT			TokenNum+1

+#define SET			TokenNum+2

+#define TREE_REF	TokenNum+3

+

+					/* E r r o r  M a c r o s */

+

+#define fatal(err)	fatalFL(err, __FILE__, __LINE__)

+#define fatal_internal(err)	fatal_intern(err, __FILE__, __LINE__)

+

+

+#define eMsg1(s,a)	eMsg3(s,a,NULL,NULL)

+#define eMsg2(s,a,b)	eMsg3(s,a,b,NULL)

+

+				/* S a n i t y  C h e c k i n g */

+

+#ifndef require

+#define require(expr, err) {if ( !(expr) ) fatal_internal(err);}

+#endif

+

+					/* L i s t  N o d e s */

+

+typedef struct _ListNode {

+			void *elem;			/* pointer to any kind of element */

+			struct _ListNode *next;

+		} ListNode;

+

+/* Define a Cycle node which is used to track lists of cycles for later

+ * reconciliation by ResolveFoCycles().

+ */

+typedef struct _c {

+			int croot;			/* cycle root */

+			set cyclicDep;		/* cyclic dependents */

+			unsigned deg;		/* degree of FOLLOW set of croot */

+		} Cycle;

+

+typedef struct _e {

+			int tok;			/* error class name == TokenStr[tok] */

+			ListNode *elist;	/* linked list of elements in error set */

+			set eset;

+			int setdeg;			/* how big is the set */

+			int lexclass;		/* which lex class is it in? */

+		} ECnode;

+

+typedef struct _TCnode {

+			int tok;			/* token class name */

+			ListNode *tlist;	/* linked list of elements in token set */

+			set tset;

+			int lexclass;		/* which lex class is it in? */

+			unsigned char dumped; /* this def has been been dumped */

+			unsigned char dumpedComplement; /* this def has been been dumped */

+			unsigned setnum;	/* which set number is this guy? (if dumped) */

+			unsigned setnumComplement;		 /* MR23 */

+			unsigned setnumErrSet;			 /* MR23 which set is this #tokclass error set (if dumped) */

+			unsigned setnumErrSetComplement; /* MR23 */

+		} TCnode;

+

+typedef struct _ft {

+			char *token;		/* id of token type to remap */

+			int tnum;			/* move token type to which token position */

+		} ForcedToken;

+

+typedef struct _ContextGuardPredicates {    /* MR13 */

+            Predicate *pred;                /* MR13 */

+        } ContextGuardPredicates;           /* MR13 */

+

+#define newListNode	(ListNode *) calloc(1, sizeof(ListNode));

+#define newCycle	(Cycle *) calloc(1, sizeof(Cycle));

+#define newECnode	(ECnode *) calloc(1, sizeof(ECnode));

+#define newTCnode	(TCnode *) calloc(1, sizeof(TCnode));

+

+

+				/* H a s h  T a b l e  E n t r i e s */

+

+typedef struct _t {				/* Token name or expression */

+			char *str;

+			struct _t *next;

+			int token;			/* token number */

+			unsigned char classname;	/* is it a err/tok class name or token */

+			TCnode *tclass;		/* ptr to token class */

+			char *action;

+            char *akaString;

+		} TermEntry;

+

+typedef struct _r {				/* Rule name and ptr to start of rule */

+			char *str;

+			struct _t *next;

+			int rulenum;		/* RulePtr[rulenum]== ptr to RuleBlk junction */

+			unsigned char noAST;/* gen AST construction code? (def==gen code) */

+			char *egroup;		/* which error group (err reporting stuff) */

+#if 0

+			/* MR27  This appears to never be used.  Delete this code later. */

+

+			ListNode *el_labels;/* list of element labels ref in all of rule */

+#endif

+			ListNode *ast_labels_in_actions; /* MR27 */

+            unsigned char has_rule_exception;

+            char dontComputeErrorSet;    /* MR14 - don't compute error set

+                                          special for rule in alpha part of

+                                          (alpha)? beta block */

+		} RuleEntry;

+

+typedef struct _f {				/* cache Fi/Fo set */

+			char *str;			/* key == (rulename, computation, k) */

+			struct _f *next;

+			set fset;			/* First/Follow of rule */

+			set rk;				/* set of k's remaining to be done after ruleref */

+			int incomplete;		/* only w/FOLLOW sets.  Use only if complete */

+		} CacheEntry;

+

+typedef struct _LabelEntry {	/* element labels */

+			char *str;

+			struct _f *next;

+			Node *elem;			/* which element does it point to? */

+			ExceptionGroup *ex_group;

+								/* Is there an exception attached to label? */

+            ExceptionGroup *outerEG;                                 /* MR7 */

+                                /* next EG if ex_group doesn't catch it MR7 */

+            struct _LabelEntry  *pendingLink;                        /* MR7 */

+                                /* too lazy to use ListNode ?           MR7 */

+            int     curAltNum;                                       /* MR7 */

+		} LabelEntry;

+

+typedef struct _SignalEntry {

+			char *str;

+			struct _f *next;

+			int signum;			/* unique signal number */

+		} SignalEntry;

+

+typedef struct _PredEntry {				/* MR11 predicate name and ptr to string */

+			char              *str;

+            struct _PredEntry *next;

+            int               file;

+            int               line;

+            Predicate         *pred;

+            char              *predLiteral;

+		} PredEntry;

+

+typedef struct _PointerStack {      /* MR10 */

+        int     count;

+        int     size;

+        void    **data;

+        } PointerStack;

+

+#define newTermEntry(s)		(TermEntry *) newEntry(s, sizeof(TermEntry))

+#define newRuleEntry(s)		(RuleEntry *) newEntry(s, sizeof(RuleEntry))

+#define newCacheEntry(s)	(CacheEntry *) newEntry(s, sizeof(CacheEntry))

+#define newLabelEntry(s)	(LabelEntry *) newEntry(s, sizeof(LabelEntry))

+#define newSignalEntry(s)	(SignalEntry *) newEntry(s, sizeof(SignalEntry))

+#define newPredEntry(s)     (PredEntry *) newEntry(s,sizeof(PredEntry))

+

+typedef struct _UserAction {

+			char *action;

+			int file, line;

+		} UserAction;

+

+

+					/* L e x i c a l  C l a s s */

+

+/* to switch lex classes, switch ExprStr and Texpr (hash table) */

+typedef struct _lc {

+			char *classnum, **exprs;

+			Entry **htable;

+		} LClass;

+

+typedef struct _exprOrder {

+			char *expr;

+			int lclass;

+		} Expr;

+

+

+typedef Graph Attrib;

+

+						/* M a x i m u m s */

+

+/* MR20 Note G. Hobbelt These values are superceded by values in hash.h */

+

+#ifndef HashTableSize

+#define HashTableSize	253

+#endif

+#ifndef StrTableSize

+#define StrTableSize	15000	/* all tokens, nonterminals, rexprs stored here */

+#endif

+#define MaxLexClasses	50		/* how many automatons */

+/* TokenStart and EofToken are ignored if #tokdefs meta-op is used */

+#define TokenStart		2		/* MUST be in 1 + EofToken */

+#define EofToken		1		/* Always predefined to be 1 */

+

+#ifndef MaxNumFiles

+#define MaxNumFiles		99

+#endif

+

+/**** MR9 JVincent@novell.com  Move to pcctscfg.h */

+/**** #define MaxFileName		300	****/ /* MR9  Move to pcctscfg.h */ /* largest file name size */

+

+#define MaxRuleName		100		/* largest rule name size */

+#define TSChunk			100		/* how much to expand TokenStr/ExprStr each time */

+#define TIChunk			TSChunk	/* expand TokenInd by same as TokenStr to mirror them */

+#define FoStackSize		100		/* deepest FOLLOW recursion possible */

+

+#define MaxClassDeclStuff   256    /* MR10 */

+

+#define NumPredefinedSignals 3

+

+           /* S t a n d a r d  S i g n a l s */

+

+#define sigNoSignal				0

+#define sigMismatchedToken		1

+#define sigNoViableAlt			2

+#define sigNoSemViableAlt		3

+

+

+

+/* AST token types */

+#define ASTexclude		0

+#define ASTchild		1

+#define ASTroot			2

+#define ASTinclude		3		/* include subtree made by rule ref */

+

+

+#define PredictionVariable				"zzpr_expr"

+#define PredictionLexClassSuffix		"_zzpred"

+

+#define WildCardString					"WildCard"

+

+#if 0

+    /*  Removed in version 1.33MR19

+        Don't understand why this never caused problems before

+    */

+

+    /*********************************************************

+    #ifndef ANTLRm

+	#define ANTLRm(st, f, _m)	zzbufsize = ZZLEXBUFSIZE;\

+					zzmode(_m);					\

+					zzenterANTLR(f);			\

+					st; ++zzasp;				\

+					zzleaveANTLR(f);

+	#endif						

+    *********************************************************/

+#endif

+

+#include "proto.h"

+#include "pcctscfg.h"   /* MR14 */

+#include <string.h>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/globals.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/globals.c
new file mode 100644
index 0000000..59d0032
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/globals.c
@@ -0,0 +1,484 @@
+/*

+ * globals.c	--	File containing all variables/tables visible to all files.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+

+#include "pcctscfg.h"

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+

+char Version[] = "1.33MR33" ;	/* PCCTS version number */	                   /* MRXXX */

+char VersionDef[] = "13333";    /* same (except int equiv for preproc symbol) */ /* MRXXX */

+

+char LexStartSymbol[] = "START";/* Name of starting lexical class/automaton */

+char *RemapFileName = "remap.h";

+char *DlgFileName = "parser.dlg";

+char *DefFileName = "tokens.h";

+char *ErrFileName = "err.c";

+char *ModeFileName = "mode.h";

+char *StdMsgName = NULL;

+

+char *ParserName = DefaultParserName;

+

+/* list of PCCTS supplied support symbols; these are renamed when more than

+ * one ANTLR-generated parsers are linked together to avoid name conflicts.

+ * Can't use '##' ANSIC preprocessor concat operator with K&R and:

+ *		#define zzskip	zzparser ## skip

+ * will not work for ANSI/C++ as 'zzparserskip' is created w/o zzparser

+ * being substituted--ack!!!

+ */

+char *StandardSymbols[] = {

+/* ANTLR stuff */

+	"zzStackOvfMsg",

+	"zzasp",

+	"zzaStack",

+	"inf_tokens",

+	"inf_text",

+	"inf_text_buffer",

+	"inf_text_buffer_ptr",

+	"inf_text_buffer_size",

+ 	"inf_labase",

+	"inf_last",

+	"inf_lap",

+	"zztokenLA",

+	"zztextLA",

+	"zzlap",

+	"zzlabase",

+	"zztoktext",

+	"zztoken",

+	"zzdirty",

+	"zzguessing",

+	"zzguess_start",

+	"zzresynch",

+	"zzinf_tokens",

+	"zzinf_text",

+	"zzinf_text_buffer",

+	"zzinf_labase",

+	"zzinf_last",

+	"zzfill_inf_look",

+	"zzFAIL",

+	"zzsave_antlr_state",

+	"zzrestore_antlr_state",

+	"zzsyn",

+	"zzset_el",

+	"zzset_deg",

+	"zzedecode",

+	"_zzsetmatch",

+	"_zzmatch",

+	"_inf_zzgettok",

+    "zzconsumeUntil",

+    "zzconsumeUntilToken",

+    "_zzmatch_wsig",

+    "_zzsetmatch_wsig",

+    "_zzmatch_wdfltsig",

+    "_zzsetmatch_wdfltsig",

+	"zzdflthandlers",

+/* DLG stuff */

+	"zzreal_line",

+	"zzcharfull",

+	"zzerr",

+	"zzlextext",

+	"zzbegexpr",

+	"zzendexpr",

+	"zzbufsize",

+	"zzbegcol",

+	"zzendcol",

+	"zzline",

+	"zzchar",

+	"zzbufovf",

+	"zzrdstream",

+	"zzrdfunc",

+	"zzrdstr",

+	"zzclose_stream",

+	"zzsave_dlg_state",

+	"zzrestore_dlg_state",

+	"zzmode",

+	"zzskip",

+	"zzmore",

+	"zzreplchar",

+	"zzreplstr",

+	"zzgettok",

+	"zzadvance",

+	"zzerrstd",

+	"zzerr_in",

+	"zzconstr_attr",

+	"zzempty_attr",

+	"zzerraction",

+	"zztokens",			/* list of token regular expressions */

+	"dfa",

+	"accepts",

+	"actions",

+    "zzTraceOptionValue",       /* MR10 */

+    "zzTraceGuessOptionValue",  /* MR10 */

+    "zzTraceCurrentRuleName",   /* MR10 */

+    "zzTraceDepth",             /* MR10 */

+    "zzGuessSeq",               /* MR10 */

+    "zzSyntaxErrCount",         /* MR11 */

+    "zzLexErrCount",            /* MR11 */

+    "zzTraceGuessDone",         /* MR13 - BJS */

+    "zzTraceGuessFail",         /* MR13 - BJS */

+    "zzTraceGuessOption",       /* MR13 - BJS */

+    "zzTraceIn",                /* MR13 - BJS */

+    "zzTraceOption",            /* MR13 - BJS */

+    "zzTraceOut",               /* MR13 - BJS */

+    "zzTraceReset",             /* MR13 - BJS */

+	NULL		/* must be present */

+};

+

+/* list of PCCTS supplied support functions; these are renamed when more than

+ * one ANTLR-generated parsers are linked together to avoid name conflicts.

+ */

+char *ASTSymbols[] = {

+	"AST",

+	"zzast_sp",

+	"zzastStack",

+	"zzlink",

+	"zzastnew",

+	"zzsubchild",

+	"zzsubroot",

+	"zzpre_ast",

+	"zzfree_ast",

+	"zztmake",

+	"zzdup_ast",

+	"zztfree",

+	"zzdouble_link",

+	NULL		/* must be present */

+};

+

+/* Current ambiguity examination information */

+int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile;

+char *CurAmbigbtype;

+

+

+						/* M e t h o d  T a b l e s */

+/*

+ * The following tables are used to fill syntax diagram nodes with the correct

+ * function pointers for computing FIRST sets and printing themselves.

+ */

+

+/* fpTraverse[node type] == pointer to function that calculates trees

+ * representing the FIRST sets for that node (maintains spatial info).

+ * We use 'struct _tree' not 'tree' due to a g++ 2.4.3 bug.

+ */

+#ifdef __cplusplus

+struct _tree *(*fpTraverse[NumNodeTypes+1])(... /* Node *, int, set * */) = {

+	NULL,

+	(struct _tree *(*)(...)) tJunc,

+	(struct _tree *(*)(...)) tRuleRef,

+	(struct _tree *(*)(...)) tToken,

+	(struct _tree *(*)(...)) tAction

+};

+#else

+Tree *(*fpTraverse[NumNodeTypes+1])() = {

+	NULL,

+	tJunc,

+	tRuleRef,

+	tToken,

+	tAction

+};

+#endif

+

+/* fpReach[node type] == pointer to function that calculates FIRST set for

+ * that node. (r stands for reach).  We use 'struct _set' not 'set'

+ * due to a g++ 2.4.3 bug.

+ */

+#ifdef __cplusplus

+struct _set (*fpReach[NumNodeTypes+1])(... /* Node *, int, set * */) = {

+	NULL,

+	(struct _set (*)(...)) rJunc,

+	(struct _set (*)(...)) rRuleRef,

+	(struct _set (*)(...)) rToken,

+	(struct _set (*)(...)) rAction

+};

+#else

+set (*fpReach[NumNodeTypes+1])() = {

+	NULL,

+	rJunc,

+	rRuleRef,

+	rToken,

+	rAction

+};

+#endif

+

+/* fpPrint[node type] == pointer to function that knows how to print that node. */

+#ifdef __cplusplus

+void (*fpPrint[NumNodeTypes+1])(... /* Node * */) = {

+	NULL,

+	(void (*)(...)) pJunc,

+	(void (*)(...)) pRuleRef,

+	(void (*)(...)) pToken,

+	(void (*)(...)) pAction

+};

+#else

+void (*fpPrint[NumNodeTypes+1])() = {

+	NULL,

+	pJunc,

+	pRuleRef,

+	pToken,

+	pAction

+};

+#endif

+

+char *decodeJType[] = {

+	"invalid",

+	"aSubBlk",

+	"aOptBlk",

+	"aLoopBlk",

+	"EndBlk",

+	"RuleBlk",

+	"Generic",

+	"EndRule",

+	"aPlusBlk",

+	"aLoopBegin"

+};

+

+

+							/* H a s h  T a b l e s */

+

+Entry	**Tname,			/* Table of all token names (maps name to tok num)*/

+		**Texpr,			/* Table of all token expressions

+							   (maps expr to tok num) */

+		**Rname,			/* Table of all Rules (has ptr to start of rule) */

+		**Fcache,			/* Cache of First/Follow Computations */

+		**Tcache;			/* Tree cache; First/Follow for permute trees */

+Entry	**Elabel;			/* Table of all element label names */

+Entry	**Sname;			/* Signal names */

+Entry   **Pname;            /* symbolic predicate names MR11 */

+

+

+							/* V a r i a b l e s */

+

+int     Save_argc;          /* MR10 */

+char    **Save_argv;        /* MR10 */

+int		EpToken=0;			/* Imaginary Epsilon token number */

+int		WildCardToken=0;

+int		CurFile= -1;		/* Index into FileStr table */

+char    *CurPredName=NULL;  /* MR11 */

+char	*CurRule=NULL;		/* Pointer to current rule name */

+int     CurRuleDebug=0;     /* MR13 debug flag */

+RuleEntry *CurRuleNode=NULL;/* Pointer to current rule node in syntax tree */

+char	*CurRetDef=NULL;	/* Pointer to current return type definition */

+char	*CurParmDef=NULL;	/* Pointer to current parameter definition */

+Junction *CurRuleBlk=NULL;	/* Pointer to current block node for enclosing block */

+ListNode *CurExGroups=NULL;	/* Current list of exception groups for rule/alts */

+ListNode *CurElementLabels=NULL;

+ListNode *CurAstLabelsInActions=NULL; /* MR27 */

+

+/* MR10  used by <<>>? to set "label_used_in_semantic_pred"  */

+/* MR10  this will force LT(i) assignment even in guess mode */

+

+ListNode *CurActionLabels=NULL;     /* MR10 Element Labels appearing in last action */

+int      numericActionLabel=0 ;     /* MR10 << ... $1 ... >> or << ... $1 ... >>?   */

+ListNode *NumericPredLabels=NULL;   /* MR10 << ... $1 ... >>?  ONLY                 */

+ListNode *ContextGuardPredicateList=NULL;  /* MR13 for re-evaluating predicates

+                                                   after meta tokens are defined    */

+

+int		CurBlockID=0;		/* Unique int for each block */

+int		CurAltNum=0;

+Junction *CurAltStart = NULL;	/* Junction node that starts the alt */

+Junction *OuterAltStart = NULL; /* For chaining exception groups        MR7 */

+int		NumRules=0;			/* Rules are from 1 to n */

+FILE	*output=NULL;		/* current parser output file */

+FILE	*input=NULL;		/* current grammar input file */

+char	*FileStr[MaxNumFiles];/* Ptr to array of file names on command-line */

+int		NumFiles=0;			/* current grammar file number */

+#ifdef __cplusplus

+void	(**fpTrans)(...),	/* array of ptrs to funcs that translate nodes */

+	 	(**fpJTrans)(...);	/*  ... that translate junctions */

+#else

+void	(**fpTrans)(),		/* array of ptrs to funcs that translate nodes */

+	 	(**fpJTrans)();		/*  ... that translate junctions */

+#endif

+int		**FoStack;			/* Array of LL_k ptrs to stacks of rule numbers */

+int		**FoTOS;			/* FOLLOW stack top-of-stack pointers */

+Junction *SynDiag = NULL;	/* Pointer to start of syntax diagram */

+int		BlkLevel=1;			/* Current block level.  Set by antlr.g, used by

+							 * scanner to translate $i.j attributes */

+set		reserved_positions;	/* set of token positions reserved by '#token T=i' cmds */

+set		all_tokens;			/* set of all token types */

+set		imag_tokens;		/* set of all imaginary token types (EpToken, errclasses...) */

+set		tokclasses;			/* set of all token class token types */

+ListNode *ForcedTokens = 0;	/* list of token_id/token_num pairs to remap */

+ListNode *MetaTokenNodes=NULL; /* list of meta token refs such as token classes etc... */

+int		*TokenInd=NULL;		/* an indirection level between token num and position

+							 * of that token def in TokenStr and ExprStr */

+int		LastTokenCounted=0;	/* ==TokenNum if no token renumbering (same as old TokenNum) */

+int		TokenNum=TokenStart;

+char	**TokenStr=NULL;	/* map token # to token name */

+char	**ExprStr=NULL;		/* map token # to expr */

+Junction **RulePtr=NULL;	/* map rule # to RuleBlk node of rule */

+ListNode *ExprOrder=NULL;	/* list of exprs as they are found in grammar */

+ListNode *BeforeActions=NULL;/* list of grammar actions before rules */

+ListNode *AfterActions=NULL;/* list of grammar actions after rules */

+ListNode *LexActions=NULL;	/* list of lexical actions */

+

+/* MR1              									    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class     */

+/* MR1				via #lexmember <<....>>			            */

+/* MR1				via #lexprefix <<....>>			            */

+/* MR1				                					    */

+

+ListNode *LexMemberActions=NULL;/* list of lexical header member decl   MR1 */

+ListNode *LexPrefixActions=NULL;/* list of lexical header #include decl MR1 */

+ListNode **Cycles=NULL;		/* list of cycles (for each k) found when

+							   doing FOLLOWs */

+ListNode *eclasses=NULL;	/* list of error classes */

+ListNode *tclasses=NULL;	/* list of token classes */

+LClass	 lclass[MaxLexClasses]; /* array of lex class definitions */

+int		 CurrentLexClass;	/* index into lclass */

+int		 NumLexClasses=0;	/* in range 1..MaxLexClasses (init 0) */

+

+char	*HdrAction=NULL;	/* action defined with #header */

+char    *FirstAction=NULL;  /* action defined with #first MR11 */

+FILE	*ErrFile;			/* sets and error recovery stuff */

+FILE	*DefFile=NULL;		/* list of tokens, return value structs, setwd defs */

+FILE    *MRinfoFile=NULL;   /* MR10 information file */

+int     MRinfo=0;           /* MR10 */

+int     MRinfoSeq=0;        /* MR10 */

+int     InfoP=0;            /* MR10 predicates        */

+int     InfoT=0;            /* MR10 tnodes            */

+int     InfoF=0;            /* MR10 first/follow sets */

+int     InfoM=0;            /* MR10 monitor progress  */

+int     InfoO=0;            /* MR12 orphan rules      */

+int     TnodesInUse=0;      /* MR10 */

+int     TnodesPeak=0;       /* MR10 */

+int     TnodesAllocated=0;  /* MR10 */

+int     TnodesReportThreshold=0;    /* MR11 */

+int     PotentialSuppression=0; /* MR10 */

+int     PotentialDummy=0;       /* MR10 */

+int		CannotContinue=FALSE;

+int		OutputLL_k = 1;		/* LL_k for parsing must be power of 2 */

+int		action_file;		/* used to track start of action */

+int		action_line;

+int		FoundGuessBlk=0;	/* there is a (...)? block somewhere in grammar */

+int		FoundException=0;	/* there is an exception somewhere in grammar */

+/* MR6	Distinguish between @ operator and real exception 		    */

+/* MR6    by keeping separate flags for @ operator and real exceptions 	    */

+int		FoundAtOperator=0;					                     /* MR6 */

+int		FoundExceptionGroup=0;			                             /* MR6 */

+int		pLevel=0;			/* print Level */

+int		pAlt1,pAlt2;		/* print "==>" in front of these alts */

+

+/* C++ output stuff */

+FILE	*Parser_h,			/* where subclass of ANTLRParser goes */

+		*Parser_c;			/* where code for subclass of ANTLRParser goes */

+char	Parser_h_Name[MaxFileName+1] = "";

+char	Parser_c_Name[MaxFileName+1] = "";

+char    MRinfoFile_Name[MaxFileName+1] = "";                /* MR10 */

+char    *ClassDeclStuff=NULL;                               /* MR10 */

+char    *BaseClassName=NULL;                                /* MR22 */

+/* list of actions inside the #class {...} defs */

+ListNode *class_before_actions=NULL;

+ListNode *class_after_actions=NULL;

+

+char	CurrentClassName[MaxRuleName]="";

+int		no_classes_found=1;

+char	*UserTokenDefsFile;

+int		UserDefdTokens=0;	/* found #tokdefs? */

+char	*OutputDirectory=TopDirectory;

+ExceptionGroup *DefaultExGroup = NULL;

+int		NumSignals = NumPredefinedSignals;

+int		ContextGuardTRAV=0;

+

+char    *MR_AmbAidRule=NULL;        /* MR11 */

+int     MR_AmbAidLine=0;            /* MR11 */

+int     MR_AmbAidDepth=0;           /* MR11 */

+int     MR_AmbAidMultiple=0;        /* MR11 */

+int     MR_skipped_e3_report=0;     /* MR11 */

+int     MR_usingPredNames=0;        /* MR11 */

+int     MR_BadExprSets=0;           /* MR13 */

+int     MR_Inhibit_Tokens_h_Gen=0;  /* MR13 */

+int     NewAST=0;                   /* MR13 */

+int		tmakeInParser=0;            /* MR23 */

+int     AlphaBetaTrace=0;           /* MR14 */

+int		MR_BlkErr=0;				/* MR21 */

+int     MR_AlphaBetaMessageCount=0; /* MR14 */

+int     MR_AlphaBetaWarning=0;      /* MR14 */

+int     MR_ErrorSetComputationActive=0;     /* MR14 */

+int     MR_MaintainBackTrace=0;             /* MR14 */

+set     MR_CompromisedRules;        /* MR14 */

+

+Junction    *MR_RuleBlkWithHalt;    /* MR10 */

+

+					/* C m d - L i n e  O p t i o n s */

+

+int		LL_k=1;				/* how many tokens of full lookahead */

+int		CLL_k= -1;			/* how many tokens of compressed lookahead */

+int		PrintOut = FALSE;	/* print out the grammar */

+int		PrintAnnotate = FALSE;/* annotate printout with FIRST sets */

+int		CodeGen=TRUE;		/* Generate output code? */

+int		LexGen=TRUE;		/* Generate lexical files? (tokens.h, parser.dlg) */

+int		GenAST=FALSE;		/* Generate AST's? */

+int		GenANSI=FALSE;		/* Generate ANSI code where necessary */

+int		GenExprSetsOpt=TRUE;/* use sets not (LA(1)==tok) expression lists */

+int		GenCR=FALSE;		/* Generate cross reference? */

+int		GenLineInfo=FALSE;	/* Generate # line "file" stuff? */

+int		GenLineInfoMS=FALSE;/* Like -gl but replace "\" with "/" for MS C/C++ systems */

+int		TraceGen=FALSE;		/* Generate code to trace rule invocation */

+int		elevel=1;			/* error level for ambiguity messages */

+int		GenEClasseForRules=0;/* don't generate eclass for each rule */

+int		TreeResourceLimit= -1;/* don't limit tree resource */

+int		DemandLookahead = 0;/* demand/delayed lookahead or not */

+char	*RulePrefix = "";	/* prefix each generated rule with this */

+char	*stdpccts = "stdpccts.h";/* where to generate std pccts include file */

+int		GenStdPccts = 0;	/* don't gen stdpccts.h? */

+int		ParseWithPredicates = 1;

+int		WarningLevel = 1;

+int		UseStdout = 0;					/* MR6 */

+int		TabWidth = 2;					/* MR6 */ /* MR27 */

+int		HoistPredicateContext = 0;

+int     MRhoisting = 0;                 /* MR9 */

+int     MRhoistingk = 0;                /* MR13 */

+int     MR_debugGenRule=0;              /* MR11 */

+

+int		GenCC = 0;			/* Generate C++ output */

+

+PointerStack MR_BackTraceStack={0,0,NULL};            /* MR10 */

+PointerStack MR_PredRuleRefStack={0,0,NULL};          /* MR10 */

+PointerStack MR_RuleBlkWithHaltStack={0,0,NULL};      /* MR10 */

+

+/* DontCopyTokens and Pragma_DupLabeledTokens were a bad idea.  I've just

+   turned them off rather than backpatching the code.  Who knows?  We

+   may need them in the future.

+ */

+int		DontCopyTokens = 1;	/* in C++, don't copy ANTLRToken passed to ANTLR */

+

+/* Remember if LT(i), LA(i), or LATEXT(i) used in an action which is not

+   a predicate.  If so, give a warning for novice users.

+*/

+

+int     LTinTokenAction = 0; /* MR23 */

+int     PURIFY = 1;          /* MR23 */

+

+int     CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */

+int     CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/hash.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/hash.c
new file mode 100644
index 0000000..68fe8fd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/hash.c
@@ -0,0 +1,221 @@
+/*

+ * hash.c

+ *

+ * Manage hash tables.

+ *

+ * The following functions are visible:

+ *

+ *		char	*mystrdup(char *);		Make space and copy string

+ *		Entry 	**newHashTable();		Create and return initialized hash table

+ *		Entry	*hash_add(Entry **, char *, Entry *)

+ *		Entry	*hash_get(Entry **, char *)

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "pcctscfg.h"

+#include "hash.h"

+

+#ifdef __USE_PROTOS

+#include <stdlib.h>

+#else

+#ifdef VAXC

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif

+#endif

+#include <string.h>

+

+#define StrSame		0

+

+#define fatal(err)															\

+			{fprintf(stderr, "%s(%d):", __FILE__, __LINE__);				\

+			fprintf(stderr, " %s\n", err); exit(PCCTS_EXIT_FAILURE);}

+#define require(expr, err) {if ( !(expr) ) fatal(err);}

+

+static unsigned size = HashTableSize;

+static char *strings = NULL;

+static char *strp;

+static unsigned strsize = StrTableSize;

+

+/* create the hash table and string table for terminals (string table only once) */

+Entry **

+#ifdef __USE_PROTOS

+newHashTable( void )

+#else

+newHashTable( )

+#endif

+{

+	Entry **table;

+	

+	table = (Entry **) calloc(size, sizeof(Entry *));

+	require( table != NULL, "cannot allocate hash table");

+	if ( strings == NULL )

+	{

+		strings = (char *) calloc(strsize, sizeof(char));

+		require( strings != NULL, "cannot allocate string table");

+		strp = strings;

+	}

+	return table;

+}

+

+void

+#ifdef __USE_PROTOS

+killHashTable( Entry **table )

+#else

+killHashTable( table )

+Entry **table;

+#endif

+{

+	/* for now, just free table, forget entries */

+	free( (char *) table );     /* MR10 cast */

+}

+

+/* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */

+Entry *

+#ifdef __USE_PROTOS

+hash_add( Entry **table, char *key, Entry *rec )

+#else

+hash_add( table, key, rec )

+Entry **table;

+char *key;

+Entry *rec;

+#endif

+{

+	unsigned h=0;

+	char *p=key;

+	require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition");

+	

+	Hash(p,h,size);

+	rec->next = table[h];			/* Add to singly-linked list */

+	table[h] = rec;

+	return rec;

+}

+

+/* Return ptr to 1st entry found in table under key (return NULL if none found) */

+Entry *

+#ifdef __USE_PROTOS

+hash_get( Entry **table, char *key )

+#else

+hash_get( table, key )

+Entry **table;

+char *key;

+#endif

+{

+	unsigned h=0;

+	char *p=key;

+	Entry *q;

+/*	require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/

+	if ( !(table!=NULL && key!=NULL) ) *((char *) 34) = 3;

+	

+	Hash(p,h,size);

+	for (q = table[h]; q != NULL; q = q->next)

+	{

+		if ( strcmp(key, q->str) == StrSame ) return( q );

+	}

+	return( NULL );

+}

+

+#ifdef DEBUG_HASH

+void

+#ifdef __USE_PROTOS

+hashStat( Entry **table )

+#else

+hashStat( table )

+Entry **table;

+#endif

+{

+	static unsigned short count[20];

+	int i,n=0,low=0, hi=0;

+	Entry **p;

+	float avg=0.0;

+	

+	for (i=0; i<20; i++) count[i] = 0;

+	for (p=table; p<&(table[size]); p++)

+	{

+		Entry *q = *p;

+		int len;

+		

+		if ( q != NULL && low==0 ) low = p-table;

+		len = 0;

+		if ( q != NULL ) fprintf(stderr, "[%d]", p-table);

+		while ( q != NULL )

+		{

+			len++;

+			n++;

+			fprintf(stderr, " %s", q->str);

+			q = q->next;

+			if ( q == NULL ) fprintf(stderr, "\n");

+		}

+		count[len]++;

+		if ( *p != NULL ) hi = p-table;

+	}

+

+	fprintf(stderr, "Storing %d recs used %d hash positions out of %d\n",

+					n, size-count[0], size);

+	fprintf(stderr, "%f %% utilization\n",

+					((float)(size-count[0]))/((float)size));

+	for (i=0; i<20; i++)

+	{

+		if ( count[i] != 0 )

+		{

+			avg += (((float)(i*count[i]))/((float)n)) * i;

+			fprintf(stderr, "Bucket len %d == %d (%f %% of recs)\n",

+							i, count[i], ((float)(i*count[i]))/((float)n));

+		}

+	}

+	fprintf(stderr, "Avg bucket length %f\n", avg);

+	fprintf(stderr, "Range of hash function: %d..%d\n", low, hi);

+}

+#endif

+

+/* Add a string to the string table and return a pointer to it.

+ * Bump the pointer into the string table to next avail position.

+ */

+char *

+#ifdef __USE_PROTOS

+mystrdup( char *s )

+#else

+mystrdup( s )

+char *s;

+#endif

+{

+	char *start=strp;

+	require(s!=NULL, "mystrdup: NULL string");

+

+	while ( *s != '\0' )

+	{

+		require( strp <= &(strings[strsize-2]),

+				 "string table overflow\nIncrease StrTableSize in hash.h and recompile hash.c\n");

+		*strp++ = *s++;

+	}

+	*strp++ = '\0';

+

+	return( start );

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/hash.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/hash.h
new file mode 100644
index 0000000..3969c40
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/hash.h
@@ -0,0 +1,73 @@
+/*

+ * hash.h -- define hash table entries, sizes, hash function...

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+				/* H a s h  T a b l e  S t u f f */

+

+#ifndef HashTableSize

+#define HashTableSize	553

+#endif

+

+#ifndef StrTableSize

+#ifdef PC32

+#define StrTableSize	1000000

+#endif

+#endif

+

+#ifndef StrTableSize

+#ifdef PC

+#define StrTableSize 655200

+#endif

+#endif

+

+#ifndef StrTableSize

+#define StrTableSize 1000000

+#endif

+

+typedef struct _entry {		/* Minimum hash table entry -- superclass */

+			char *str;

+			struct _entry *next;

+		} Entry;

+

+/* Hash 's' using 'size', place into h (s is modified) */

+#define Hash(s,h,size)								\

+	{while ( *s != '\0' ) h = (h<<1) + *s++;		\

+	h %= size;}

+

+#ifdef __USE_PROTOS

+Entry	*hash_get(Entry **, char *),

+		**newHashTable(void),

+		*hash_add(Entry **, char *, Entry *);

+

+void	killHashTable(Entry **);

+

+#else

+Entry *hash_get(), **newHashTable(), *hash_add();

+void	killHashTable();        /* MR9 23-Sep-97 */

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/lex.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/lex.c
new file mode 100644
index 0000000..8c524fe
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/lex.c
@@ -0,0 +1,878 @@
+/*

+ * lex.c	--	Generate all of the lexical type files: parser.dlg tokens.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <ctype.h>

+/* MR1						                                                */

+/* MR1  10-Apr-97  MR1	Replace use of __STDC__ with __USE_PROTOS	    */

+/* MR1				                                                        */

+#include "pcctscfg.h"

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+

+#define DLGErrorString "invalid token"

+

+/* Generate a complete lexical description of the lexemes found in the grammar */

+void

+#ifdef __USE_PROTOS

+genLexDescr( void )

+#else

+genLexDescr( )

+#endif

+{

+	ListNode *p;

+	FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");

+	require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );

+#ifdef SPECIAL_FOPEN

+	special_fopen_actions(OutMetaName(DlgFileName));	             /* MR1 */

+#endif

+	fprintf(dlgFile, "<<\n");

+	fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName);

+	fprintf(dlgFile, " *\n");

+	fprintf(dlgFile, " * Generated from:");

+	{int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}

+	fprintf(dlgFile, "\n");

+	fprintf(dlgFile, " *\n");

+	fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");

+	fprintf(dlgFile, " * Purdue University Electrical Engineering\n");

+	fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");

+	fprintf(dlgFile, " * ANTLR Version %s\n", Version);

+	fprintf(dlgFile, " */\n\n");

+    if (FirstAction != NULL ) dumpAction( FirstAction, dlgFile, 0, -1, 0, 1 );  /* MR11 MR15b */

+    fprintf(dlgFile, "#define ANTLR_VERSION	%s\n", VersionDef);

+	if ( GenCC )

+	{

+		if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);

+		else fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);

+		fprintf(dlgFile, "#include \"%s\"\n", ATOKEN_H);

+		if ( GenAST ) fprintf(dlgFile, "#include \"%s\"\n", ASTBASE_H);

+		if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );

+	}

+	else

+	{

+		fprintf(dlgFile, "#include \"pcctscfg.h\"\n");

+		fprintf(dlgFile, "#include \"pccts_stdio.h\"\n");

+		if ( strcmp(ParserName, DefaultParserName)!=0 )

+			fprintf(dlgFile, "#define %s %s\n", DefaultParserName, ParserName);

+		if ( strcmp(ParserName, DefaultParserName)!=0 )

+			fprintf(dlgFile, "#include \"%s\"\n", RemapFileName);

+		if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );

+		if ( FoundGuessBlk )

+		{

+			fprintf(dlgFile, "#define ZZCAN_GUESS\n");

+			fprintf(dlgFile, "#include \"pccts_setjmp.h\"\n");

+		}

+		if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);

+		if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");

+        if (TraceGen) {

+          fprintf(dlgFile,"#ifndef zzTRACE_RULES\n");  /* MR20 */

+          fprintf(dlgFile,"#define zzTRACE_RULES\n");  /* MR20 */

+          fprintf(dlgFile,"#endif\n");  /* MR22 */

+        };

+		fprintf(dlgFile, "#include \"antlr.h\"\n");

+		if ( GenAST ) {

+			fprintf(dlgFile, "#include \"ast.h\"\n");

+		}

+		if ( UserDefdTokens )

+			fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);

+		/* still need this one as it has the func prototypes */

+		fprintf(dlgFile, "#include \"%s\"\n", DefFileName);

+		fprintf(dlgFile, "#include \"dlgdef.h\"\n");

+		fprintf(dlgFile, "LOOKAHEAD\n");

+		fprintf(dlgFile, "\n");

+		fprintf(dlgFile, "void\n");

+		fprintf(dlgFile, "#ifdef __USE_PROTOS\n");

+		fprintf(dlgFile, "zzerraction(void)\n");

+		fprintf(dlgFile, "#else\n");

+		fprintf(dlgFile, "zzerraction()\n");

+		fprintf(dlgFile, "#endif\n");

+		fprintf(dlgFile, "{\n");

+		fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);

+		fprintf(dlgFile, "\tzzadvance();\n");

+		fprintf(dlgFile, "\tzzskip();\n");

+		fprintf(dlgFile, "}\n");

+	}

+	fprintf(dlgFile, ">>\n\n");

+

+	/* dump all actions */

+

+/* MR1									                                    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class     */

+/* MR1	 	   	  via <<%%lexmember ....>> & <<%%lexprefix ...>>            */

+/* MR1				                					    */

+          if (LexActions != NULL) {

+            for (p = LexActions->next; p!=NULL; p=p->next)

+		{

+/* MR1 */	fprintf(dlgFile, "<<%%%%lexaction\n");

+			dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );

+			fprintf(dlgFile, ">>\n\n");

+		}

+	  };

+

+/* MR1 */ if (GenCC) {

+/* MR1 */   fprintf(dlgFile,"<<%%%%parserclass %s>>\n\n",CurrentClassName);

+/* MR1 */ };

+

+/* MR1 */ if (LexPrefixActions != NULL) {

+/* MR1 */   for (p = LexPrefixActions->next; p!=NULL; p=p->next)

+/* MR1 */       {

+/* MR1 */               fprintf(dlgFile, "<<%%%%lexprefix\n");

+/* MR1 */               dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );

+/* MR1 */               fprintf(dlgFile, ">>\n\n");

+/* MR1 */       }

+/* MR1 */ };

+

+/* MR1 */ if (LexMemberActions != NULL) {

+/* MR1 */   for (p = LexMemberActions->next; p!=NULL; p=p->next)

+/* MR1 */       {

+/* MR1 */               fprintf(dlgFile, "<<%%%%lexmember\n");

+/* MR1 */               dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );

+/* MR1 */               fprintf(dlgFile, ">>\n\n");

+/* MR1 */       }

+/* MR1 */ };

+

+	/* dump all regular expression rules/actions (skip sentinel node) */

+	if ( ExprOrder == NULL ) {

+		warnNoFL("no regular expressions found in grammar");

+	}

+	else dumpLexClasses(dlgFile);

+	fprintf(dlgFile, "%%%%\n");

+	fclose( dlgFile );

+}

+

+/* For each lexical class, scan ExprOrder looking for expressions

+ * in that lexical class.  Print out only those that match.

+ * Each element of the ExprOrder list has both an expr and an lclass

+ * field.

+ */

+void

+#ifdef __USE_PROTOS

+dumpLexClasses( FILE *dlgFile )

+#else

+dumpLexClasses( dlgFile )

+FILE *dlgFile;

+#endif

+{

+	int i;

+	TermEntry *t;

+	ListNode *p;

+	Expr *q;

+

+	for (i=0; i<NumLexClasses; i++)

+	{

+		fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);

+		for (p=ExprOrder->next; p!=NULL; p=p->next)

+		{

+			q = (Expr *) p->elem;

+			if ( q->lclass != i ) continue;

+			lexmode(i);

+			t = (TermEntry *) hash_get(Texpr, q->expr);

+			require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );

+			if ( t->token == EpToken ) continue;

+			fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));

+			/* replace " killed by StripQuotes() */

+			q->expr[ strlen(q->expr) ] = '"';

+			if ( !GenCC ) {

+				if ( TokenString(t->token) != NULL )

+					fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));

+				else

+					fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);

+			}

+			if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );

+			if ( GenCC ) {

+				if ( TokenString(t->token) != NULL )

+					fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));

+				else

+					fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token);

+			}

+			fprintf(dlgFile, "\t>>\n\n");

+		}

+	}

+}

+

+/* Strip the leading path (if any) from a filename */

+char *

+#ifdef __USE_PROTOS

+StripPath( char *fileName )

+#else

+StripPath( fileName )

+char *fileName;

+#endif

+{

+	char *p;

+	static char dirSym[2] = DirectorySymbol;

+

+	if(NULL != (p = strrchr(fileName, dirSym[0])))

+		p++;

+	else

+		p = fileName;

+

+	return(p);

+}

+

+/* Generate a list of #defines && list of struct definitions for

+ * aggregate retv's */

+void

+#ifdef __USE_PROTOS

+genDefFile( void )

+#else

+genDefFile( )

+#endif

+{

+	int i;

+

+	/* If C++ mode and #tokdef used, then don't need anything in here since

+	 * C++ puts all definitions in the class file name.

+	 */

+	if ( GenCC && UserTokenDefsFile ) return;

+    if ( MR_Inhibit_Tokens_h_Gen) return;

+

+	DefFile = fopen(OutMetaName(DefFileName), "w");

+	require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );

+#ifdef SPECIAL_FOPEN

+	special_fopen_actions(OutMetaName(DefFileName));	             /* MR1 */

+#endif

+	fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName)));

+	fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName)));

+

+	fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);

+	fprintf(DefFile, " *\n");

+	fprintf(DefFile, " * Generated from:");

+	for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);

+	fprintf(DefFile, "\n");

+	fprintf(DefFile, " *\n");

+	fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");

+	fprintf(DefFile, " * Purdue University Electrical Engineering\n");

+	fprintf(DefFile, " * ANTLR Version %s\n", Version);

+	fprintf(DefFile, " */\n");

+

+	if ( !GenCC && LexGen ) {

+		fprintf(DefFile,"#define zzEOF_TOKEN %d\n",

+				TokenInd!=NULL?TokenInd[EofToken]:EofToken);

+	}

+

+	if ( !UserDefdTokens )

+	{

+		int first=1;

+

+		if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {\n");

+		for (i=1; i<TokenNum; i++)

+		{

+			/* Don't do EpToken or expr w/o labels */

+			if ( TokenString(i)!=NULL && i != EpToken )

+			{

+				TermEntry *p;

+				

+				if ( WarningLevel>1 )

+				{

+					int j;

+					/* look in all lexclasses for the reg expr */

+

+/* MR10  Derek Pappas                                                */

+/* MR10     A #tokclass doesn't have associated regular expressiones */

+/* MR10        so don't warn user about it's omission                */

+

+                    p = (TermEntry *) hash_get(Tname, TokenString(i));

+

+                    if (p != NULL && ! p->classname) {

+    					for (j=0; j<NumLexClasses; j++)

+    					{

+    						lexmode(j);

+    						if ( ExprString(i)!=NULL ) break;

+    					}

+    					if ( j>=NumLexClasses )

+    					{

+    						warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));

+    					}

+                    };

+				}

+				require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,

+						"token not in sym tab when it should be");

+				if ( !p->classname )

+				{

+					if ( GenCC ) {

+						if ( !first ) fprintf(DefFile, ",\n");

+						first = 0;

+						fprintf(DefFile, "\t%s=%d", TokenString(i), i);

+					}

+					else

+						fprintf(DefFile, "#define %s %d\n", TokenString(i), i);

+				}

+			}

+		}

+/* MR1									                                    */

+/* MR1  10-Apr-97 133MR1	Prevent use of varying sizes of integer	    */

+/* MR1				for the enum ANTLRTokenType                             */

+/* MR1								           */

+		if ( GenCC ) {				                                 /* MR1 */

+ 		 	 if ( !first ) fprintf(DefFile, ",\n");                  /* MR14 */

+		     fprintf(DefFile, "\tDLGminToken=0");                 /* MR1 */

+		     fprintf(DefFile, ",\n\tDLGmaxToken=9999};\n");          /* MR1 */

+                };						                             /* MR1 */

+	}

+

+	if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);

+

+	fprintf(DefFile, "\n#endif\n");

+}

+

+void

+#ifdef __USE_PROTOS

+GenRemapFile( void )

+#else

+GenRemapFile( )

+#endif

+{

+	if ( strcmp(ParserName, DefaultParserName)!=0 )

+	{

+		FILE *f;

+		int i;

+

+		f = fopen(OutMetaName(RemapFileName), "w");

+		require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );

+#ifdef SPECIAL_FOPEN

+		special_fopen_actions(OutMetaName(RemapFileName));           /* MR1 */

+#endif

+		fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);

+		fprintf(f, " *\n");

+		fprintf(f, " * Generated from:");

+		for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);

+		fprintf(f, "\n");

+		fprintf(f, " *\n");

+		fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");

+		fprintf(f, " * Purdue University Electrical Engineering\n");

+		fprintf(f, " * ANTLR Version %s\n", Version);

+		fprintf(f, " */\n");

+

+		GenRuleFuncRedefs(f, SynDiag);

+		GenPredefinedSymbolRedefs(f);

+		if ( GenAST ) GenASTSymbolRedefs(f);

+		GenSetRedefs(f);

+

+		fclose(f);

+	}

+}

+

+/* Generate a bunch of #defines that rename all functions to be "ParserName_func" */

+void

+#ifdef __USE_PROTOS

+GenRuleFuncRedefs( FILE *f, Junction *p )

+#else

+GenRuleFuncRedefs( f, p )

+FILE *f;

+Junction *p;

+#endif

+{

+	fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");

+	while ( p!=NULL )

+	{

+		fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);

+		p = (Junction *)p->p2;

+	}

+}

+

+/* Generate a bunch of #defines that rename all standard symbols to be

+ * "ParserName_symbol".  The list of standard symbols to change is in

+ * globals.c.

+ */

+void

+#ifdef __USE_PROTOS

+GenPredefinedSymbolRedefs( FILE *f )

+#else

+GenPredefinedSymbolRedefs( f )

+FILE *f;

+#endif

+{

+	char **p;

+

+	fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");

+	for (p = &StandardSymbols[0]; *p!=NULL; p++)

+	{

+		fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);

+	}

+}

+

+/* Generate a bunch of #defines that rename all AST symbols to be

+ * "ParserName_symbol".  The list of AST symbols to change is in

+ * globals.c.

+ */

+void

+#ifdef __USE_PROTOS

+GenASTSymbolRedefs( FILE *f )

+#else

+GenASTSymbolRedefs( f )

+FILE *f;

+#endif

+{

+	char **p;

+

+	fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");

+	for (p = &ASTSymbols[0]; *p!=NULL; p++)

+	{

+		fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);

+	}

+}

+

+/* redefine all sets generated by ANTLR; WARNING:  'zzerr', 'setwd' must match

+ * use in bits.c (DumpSetWd() etc...)

+ */

+void

+#ifdef __USE_PROTOS

+GenSetRedefs( FILE *f )

+#else

+GenSetRedefs( f )

+FILE *f;

+#endif

+{

+	int i;

+

+	for (i=1; i<=wordnum; i++)

+	{

+		fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);

+	}

+	for (i=1; i<=esetnum; i++)

+	{

+		fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);

+	}

+}

+

+/* Find all return types/parameters that require structs and def

+ * all rules with ret types.

+ *

+ * This is for the declaration, not the definition.

+ */

+void

+#ifdef __USE_PROTOS

+GenRulePrototypes( FILE *f, Junction *p )

+#else

+GenRulePrototypes( f, p )

+FILE *f;

+Junction *p;

+#endif

+{

+	int i;

+

+	i = 1;

+	while ( p!=NULL )

+	{

+		if ( p->ret != NULL )

+		{

+/* MR23 */	if ( hasMultipleOperands(p->ret) )

+			{

+				DumpRetValStruct(f, p->ret, i);

+			}

+			fprintf(f, "\n#ifdef __USE_PROTOS\n");

+/* MR23 */	if ( hasMultipleOperands(p->ret) ) 

+			{

+				fprintf(f, "extern struct _rv%d", i);

+			}

+			else

+			{

+				fprintf(f, "extern ");

+				DumpType(p->ret, f);

+			}

+			fprintf(f, " %s%s(", RulePrefix, p->rname);

+			DumpANSIFunctionArgDef(f,p,1 /* emit initializers ? */);

+			fprintf(f, ";\n");

+			fprintf(f, "#else\n");

+/* MR23 */	if ( hasMultipleOperands(p->ret) )

+			{

+				fprintf(f, "extern struct _rv%d", i);

+			}

+			else

+			{

+				fprintf(f, "extern ");

+				DumpType(p->ret, f);

+			}

+			fprintf(f, " %s%s();\n", RulePrefix, p->rname);

+			fprintf(f, "#endif\n");

+		}

+		else

+		{

+			fprintf(f, "\n#ifdef __USE_PROTOS\n");

+			fprintf(f, "void %s%s(", RulePrefix, p->rname);

+			DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );

+			fprintf(f, ";\n");

+#ifdef OLD

+			if ( p->pdecl != NULL || GenAST )

+			{

+				if ( GenAST ) {

+					fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");

+				}

+				if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);

+			}

+			else fprintf(f, "void");

+			fprintf(f, ");\n");

+#endif

+			fprintf(f, "#else\n");

+			fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);

+			fprintf(f, "#endif\n");

+		}

+		i++;

+		p = (Junction *)p->p2;

+	}

+}

+

+/* Define all rules in the class.h file; generate any required

+ * struct definitions first, however.

+ */

+void

+#ifdef __USE_PROTOS

+GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )

+#else

+GenRuleMemberDeclarationsForCC( f, q )

+FILE *f;

+Junction *q;

+#endif

+{

+	Junction *p = q;

+	int i;

+

+	fprintf(f, "private:\n");

+

+	/* Dump dflt handler declaration */

+	fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");

+

+	fprintf(f, "public:\n");

+

+	/* Dump return value structs */

+	i = 1;

+	while ( p!=NULL )

+	{

+		if ( p->ret != NULL )

+		{

+/* MR23 */	if ( hasMultipleOperands(p->ret) )

+			{

+				DumpRetValStruct(f, p->ret, i);

+			}

+		}

+		i++;

+		p = (Junction *)p->p2;

+	}

+

+	/* Dump member func defs && CONSTRUCTOR */

+	fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);

+/*

+	fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n",

+			   CurrentClassName);

+*/

+

+	i = 1;

+	p = q;

+	while ( p!=NULL )

+	{

+		if ( p->ret != NULL )

+		{

+/* MR23 */	if ( hasMultipleOperands(p->ret) )

+			{

+				fprintf(f, "\tstruct _rv%d", i);

+			}

+			else

+			{

+				fprintf(f, "\t");

+				DumpType(p->ret, f);

+			}

+			fprintf(f, " %s%s(",RulePrefix,p->rname);

+			DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );

+			fprintf(f, ";\n");

+#ifdef OLD

+			if ( p->pdecl != NULL || GenAST )

+			{

+				if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");

+				if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);

+			}

+			fprintf(f, ");\n");

+#endif

+		}

+		else

+		{

+			fprintf(f, "\tvoid %s%s(",RulePrefix,p->rname);

+			DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */);

+			fprintf(f, ";\n");

+#ifdef OLD

+			if ( p->pdecl != NULL || GenAST )

+			{

+				if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");

+				if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);

+			}

+			fprintf(f, ");\n");

+#endif

+		}

+		i++;

+		p = (Junction *)p->p2;

+	}

+}

+

+/* Given a list of ANSI-style parameter declarations, print out a

+ * comma-separated list of the symbols (w/o types).

+ * Basically, we look for a comma, then work backwards until start of

+ * the symbol name.  Then print it out until 1st non-alnum char.  Now,

+ * move on to next parameter.

+ *

+ */

+

+/* MR5 	Jan Mikkelsen 26-May-97 - added initalComma parameter              */

+

+void

+#ifdef __USE_PROTOS

+DumpListOfParmNames(char *pdecl, FILE *output, int initialComma)    /* MR5 */

+#else

+DumpListOfParmNames(pdecl, output, initialComma)		            /* MR5 */

+char *pdecl;	             		 			  	                /* MR5 */

+FILE *output;							                            /* MR5 */

+int initialComma;			                                        /* MR5 */

+#endif

+{

+	int firstTime = 1, done = 0;

+	require(output!=NULL, "DumpListOfParmNames: NULL parm");

+

+	if ( pdecl == NULL ) return;

+	while ( !done )

+	{

+		if ( !firstTime || initialComma ) putc(',', output);        /* MR5 */

+		done = DumpNextNameInDef(&pdecl, output);

+		firstTime = 0;

+	}

+}

+

+/* given a list of parameters or return values, dump the next

+ * name to output.  Return 1 if last one just printed, 0 if more to go.

+ */

+

+/* MR23 Total rewrite */

+

+int

+#ifdef __USE_PROTOS

+DumpNextNameInDef( char **q, FILE *output )

+#else

+DumpNextNameInDef( q, output )

+char **q;

+FILE *output;

+#endif

+{

+	char *p;

+	char *t;

+	char *pDataType;

+	char *pSymbol;

+	char *pEqualSign;

+	char *pValue;

+	char *pSeparator;

+	int nest = 0;

+

+	p = endFormal(*q,

+			      &pDataType,

+				  &pSymbol,

+				  &pEqualSign,

+				  &pValue,

+				  &pSeparator,

+				  &nest);

+

+    /* MR26 Handle rule arguments such as: IIR_Bool (IIR_Decl::*contstraint)()

+       For this we need to strip off anything which follows the symbol.

+     */

+

+/* MR26 */  t = pSymbol;

+/* MR26 */	if (t != NULL) {

+/* MR26 */		for (t = pSymbol; *t != 0; t++) {

+/* MR26 */			if (! (isalpha(*t) || isdigit(*t) || *t == '_' || *t == '$')) break;

+/* MR26 */		}

+/* MR26 */	}

+/* MR26 */	fprintf(output,strBetween(pSymbol, t, pSeparator));

+

+    *q = p;

+    return (*pSeparator  == 0);

+}

+

+/* Given a list of ANSI-style parameter declarations, dump K&R-style

+ * declarations, one per line for each parameter.  Basically, convert

+ * comma to semi-colon, newline.

+ */

+void

+#ifdef __USE_PROTOS

+DumpOldStyleParms( char *pdecl, FILE *output )

+#else

+DumpOldStyleParms( pdecl, output )

+char *pdecl;

+FILE *output;

+#endif

+{

+	require(output!=NULL, "DumpOldStyleParms: NULL parm");

+

+	if ( pdecl == NULL ) return;

+	while ( *pdecl != '\0' )

+	{

+		if ( *pdecl == ',' )

+		{

+			pdecl++;

+			putc(';', output); putc('\n', output);

+			while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;

+		}

+		else {putc(*pdecl, output); pdecl++;}

+	}

+	putc(';', output);

+	putc('\n', output);

+}

+

+/* Take in a type definition (type + symbol) and print out type only */

+/* MR23 Total rewrite */

+

+void

+#ifdef __USE_PROTOS

+DumpType( char *s, FILE *f )

+#else

+DumpType( s, f )

+char *s;

+FILE *f;

+#endif

+{

+	char *p;

+	char *pDataType;

+	char *pSymbol;

+	char *pEqualSign;

+	char *pValue;

+	char *pSeparator;

+	int nest = 0;

+

+	require(s!=NULL, "DumpType: invalid type string"); 

+

+	p = endFormal(s,

+			      &pDataType,

+				  &pSymbol,

+				  &pEqualSign,

+				  &pValue,

+				  &pSeparator,

+				  &nest);

+	fprintf(f,strBetween(pDataType, pSymbol, pSeparator));

+}

+

+/* check to see if string e is a word in string s */

+int

+#ifdef __USE_PROTOS

+strmember( char *s, char *e )

+#else

+strmember( s, e )

+char *s;

+char *e;

+#endif

+{

+    register char *p;

+    require(s!=NULL&&e!=NULL, "strmember: NULL string");

+

+    if ( *e=='\0' ) return 1;   /* empty string is always member */

+    do {

+	while ( *s!='\0' && !isalnum(*s) && *s!='_' )

+	++s;

+	p = e;

+	while ( *p!='\0' && *p==*s ) {p++; s++;}

+	if ( *p=='\0' ) {

+	    if ( *s=='\0' ) return 1;

+	    if ( !isalnum (*s) && *s != '_' ) return 1;

+	}

+	while ( isalnum(*s) || *s == '_' )

+	++s;

+    } while ( *s!='\0' );

+    return 0;

+}

+

+#if 0

+

+/* MR23 Replaced by hasMultipleOperands() */

+

+int

+#ifdef __USE_PROTOS

+HasComma( char *s )

+#else

+HasComma( s )

+char *s;

+#endif

+{

+	while (*s!='\0')

+		if ( *s++ == ',' ) return 1;

+	return 0;

+}

+#endif

+

+

+/* MR23 Total rewrite */

+

+void

+#ifdef __USE_PROTOS

+DumpRetValStruct( FILE *f, char *ret, int i )

+#else

+DumpRetValStruct( f, ret, i )

+FILE *f;

+char *ret;

+int i;

+#endif

+{

+	char *p = ret;

+	char *pDataType;

+	char *pSymbol;

+	char *pEqualSign;

+	char *pValue;

+	char *pSeparator;

+    int nest = 0;

+

+	fprintf(f, "\nstruct _rv%d {\n", i);

+	while (*p != 0 && nest == 0) {

+		p = endFormal(p,

+			          &pDataType,

+					  &pSymbol,

+					  &pEqualSign,

+					  &pValue,

+					  &pSeparator,

+					  &nest);

+		fprintf(f,"\t");

+		fprintf(f,strBetween(pDataType, pSymbol, pSeparator));

+		fprintf(f," ");

+		fprintf(f,strBetween(pSymbol, pEqualSign, pSeparator));

+		fprintf(f,";\n");

+    }

+	fprintf(f,"};\n");

+}

+

+/* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */

+char *

+#ifdef __USE_PROTOS

+StripQuotes( char *s )

+#else

+StripQuotes( s )

+char *s;

+#endif

+{

+	if ( *s == '"' )

+	{

+		s[ strlen(s)-1 ] = '\0';    /* remove last quote */

+		return( s+1 );				/* return address past initial quote */

+	}

+	return( s );

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/main.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/main.c
new file mode 100644
index 0000000..051ee4e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/main.c
@@ -0,0 +1,1747 @@
+/*

+ * main.c -- main program for PCCTS ANTLR.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+/* To set a breakpoint just before exit look for "cleanUp".    */

+/* To set a breakpoint for fatal error look for "fatal_intern" */

+

+#include <stdio.h>

+

+#include "pcctscfg.h"

+#include "stdpccts.h"

+

+#define MAX_INT_STACK 50

+static int istack[MAX_INT_STACK];		/* Int stack */

+static int isp = MAX_INT_STACK;

+

+static int DontAcceptFiles = 0;			/* if stdin, don't read files */

+static int DontAcceptStdin = 0;			/* if files seen first, don't accept stdin */

+

+static int tnodes_used_in_guard_predicates_etc;     /* MR10 */

+

+		/* C m d - L i n e  O p t i o n  S t r u c t  &  F u n c s */

+

+typedef struct _Opt {

+			char *option;

+			int  arg;

+#ifdef __cplusplus

+			void (*process)(...);

+#else

+			void (*process)();

+#endif

+			char *descr;

+		} Opt;

+

+#ifdef __USE_PROTOS

+extern void ProcessArgs(int, char **, Opt *);

+#else

+extern void ProcessArgs();

+#endif

+

+#ifdef __USE_PROTOS

+int ci_strequ(char *a,char *b)

+#else

+int ci_strequ(a,b)

+  char  *a;

+  char  *b;

+#endif

+{

+  for ( ;*a != 0 && *b != 0; a++, b++) {

+    if (toupper(*a) != toupper(*b)) return 0;

+  }

+  return (*a == *b);

+}

+

+static void

+#ifdef __USE_PROTOS

+pStdin( void )

+#else

+pStdin( )

+#endif

+{

+	if ( DontAcceptStdin )

+	{

+		warnNoFL("'-' (stdin) ignored as files were specified first");

+		return;

+	}

+

+	require(NumFiles<MaxNumFiles,"exceeded max # of input files");

+	FileStr[NumFiles++] = "stdin";

+	DontAcceptFiles = 1;

+}

+

+static void

+#ifdef __USE_PROTOS

+pFile( char *s )

+#else

+pFile( s )

+char *s;

+#endif

+{

+	if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }

+	if ( DontAcceptFiles )

+	{

+		warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));

+		return;

+	}

+

+	require(NumFiles<MaxNumFiles,"exceeded max # of input files");

+	FileStr[NumFiles++] = s;

+	DontAcceptStdin = 1;

+}

+

+/* MR14

+        Allow input to be a file containing a list of files

+        Bernard Giroud (b_giroud@decus.ch)

+*/

+

+static void

+#ifdef __USE_PROTOS

+pFileList( char *s, char *t )

+#else

+pFileList( s, t )

+char *s;

+char *t;

+#endif

+{

+#define MaxFLArea 1024

+	FILE *fl;

+	static char Fn_in_Fl[MaxFLArea] = "";

+        char one_fn[MaxFileName];

+	char *flp = &Fn_in_Fl[0];

+	int fnl, left = MaxFLArea, i;

+

+	if ( *t=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",t) ); return; }

+	if ( DontAcceptFiles )

+	{

+		warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",t));

+		return;

+	}

+

+        if ((fl = fopen(t, "r")) == NULL)

+	{

+		warnNoFL(eMsg1("file '%s' can't be opened", t));

+		return;

+	}

+        for (;;)

+	{

+		if (fgets(one_fn, 128 - 1, fl) == NULL)

+			break;

+		fnl = strlen(one_fn);

+		require(fnl<=left, "no more room in File List Area");

+		/* drop the trailing LF */

+		if (one_fn[fnl - 1] == 0x0a) one_fn[fnl - 1] = ' ';

+		strcat(Fn_in_Fl, one_fn);

+		left = left - fnl;

+		require(NumFiles<MaxNumFiles,"exceeded max # of input files");

+		FileStr[NumFiles++] = flp;

+		flp = flp + fnl;

+	}

+	fclose(fl);

+	for (i=0;i < MaxFLArea;i++) if (Fn_in_Fl[i] == ' ') Fn_in_Fl[i] = '\0';

+	DontAcceptStdin = 1;

+}

+

+static void

+#ifdef __USE_PROTOS

+pLLK( char *s, char *t )

+#else

+pLLK( s, t )

+char *s;

+char *t;

+#endif

+{

+	LL_k = atoi(t);

+	if ( LL_k <= 0 ) {

+		warnNoFL("must have at least one token of lookahead (setting to 1)");

+		LL_k = 1;

+	}

+}

+

+static void

+#ifdef __USE_PROTOS

+pCk( char *s, char *t )

+#else

+pCk( s, t )

+char *s;

+char *t;

+#endif

+{

+	CLL_k = atoi(t);

+	if ( CLL_k <= 0 ) {

+		warnNoFL("must have at least one token of look-ahead (setting to 1)");

+		CLL_k = 1;

+	}

+}

+

+static void						                                     /* MR6 */

+#ifdef __USE_PROTOS

+pTab( char *s, char *t )			                        	     /* MR6 */

+#else

+pTab( s, t )				                    		             /* MR6 */

+char *s;							                                 /* MR6 */

+char *t;							                                 /* MR6 */

+#endif

+{								                                     /* MR6 */

+	TabWidth = atoi(t);					                             /* MR6 */

+	if ( TabWidth < 0 || TabWidth > 8 ) {	            		     /* MR6 */

+		warnNoFL("tab width must be between 1 and 8");               /* MR6 */

+	  TabWidth=0;						                             /* MR6 */

+	}							                                     /* MR6 */

+}							                                         /* MR6 */

+

+static int ambAidDepthSpecified=0;                                   /* MR11 */

+

+static void						                                     /* MR11 */

+#ifdef __USE_PROTOS

+pAAd( char *s, char *t )			                        	     /* MR11 */

+#else

+pAAd( s, t )				                    		             /* MR11 */

+char *s;							                                 /* MR11 */

+char *t;							                                 /* MR11 */

+#endif

+{								                                     /* MR11 */

+    ambAidDepthSpecified=1;                                          /* MR11 */

+	MR_AmbAidDepth = atoi(t);				                         /* MR11 */

+}							                                         /* MR11 */

+

+static void						                                     /* MR11 */

+#ifdef __USE_PROTOS

+pTreport( char *s, char *t )			                       	     /* MR11 */

+#else

+pTreport( s, t )				                  		             /* MR11 */

+    char *s;							                             /* MR11 */

+    char *t;							                             /* MR11 */

+#endif

+{								                                     /* MR11 */

+	TnodesReportThreshold = atoi(t);				                 /* MR11 */

+}							                                         /* MR11 */

+

+#ifdef __USE_PROTOS

+void chkGTFlag(void)	                                    /* 7-Apr-97 MR1 */

+#else

+void chkGTFlag()                                            /* 7-Apr-97 MR1 */

+#endif

+{

+	if ( !GenAST )

+		warn("#-variable or other AST item referenced w/o -gt option");

+}

+

+

+#ifdef __USE_PROTOS

+static void pInfo(char *s, char *t)                         /* MR10 */

+#else

+static void pInfo(s,t)                                      /* MR10 */

+  char  *s;

+  char  *t;

+#endif

+{

+  char  *p;

+  int   q;

+  for (p=t; *p != 0; p++) {

+    q=tolower(*p);

+    if (q=='t') {

+      InfoT=1;

+    } else if (q=='p') {

+      InfoP=1;

+    } else if (q=='m') {

+      InfoM=1;

+    } else if (q=='o') {

+      InfoO=1;

+    } else if (q=='0') {

+      ; /* nothing */

+    } else if (q=='f') {

+      InfoF=1;

+    } else {

+      warnNoFL(eMsgd("unrecognized -info option \"%c\"",(int)*p));

+    };

+  };

+}

+

+#ifdef __USE_PROTOS

+static void pCGen(void)	{ CodeGen = FALSE; LexGen = FALSE; }

+static void pLGen(void)	{ LexGen = FALSE; }

+static void pXTGen(void){ MR_Inhibit_Tokens_h_Gen = TRUE; }

+static void pTGen(void)	{ TraceGen = TRUE; }

+static void pSGen(void)	{ GenExprSetsOpt = FALSE; }

+static void pPrt(void)	{ PrintOut = TRUE; pCGen(); pLGen(); }

+static void pPrtA(void)	{ PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }

+static void pAst(void)	{ GenAST = TRUE; }

+static void pANSI(void)	{ GenANSI = TRUE; }

+static void pCr(void)	{ GenCR = TRUE; }

+static void pNOPURIFY(void)	{ PURIFY = FALSE; }

+/*static void pCt(void)	{ warnNoFL("-ct option is now the default"); }*/

+static void pLI(void)	{ GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */

+static void pLIms(void)	{ GenLineInfo = TRUE; GenLineInfoMS = TRUE; }  /* MR14 */

+static void pFr(char *s, char *t) {RemapFileName = t;}

+static void pFe(char *s, char *t) {ErrFileName = t;}

+static void pFl(char *s, char *t) {DlgFileName = t;}

+static void pFm(char *s, char *t) {ModeFileName = t;}

+static void pFt(char *s, char *t) {DefFileName = t;}

+

+static void pE1(void)	{ elevel = 1; }

+static void pE2(void)	{ elevel = 2; }

+static void pE3(void)	{ elevel = 3; }

+static void pEGen(void)	{ GenEClasseForRules = 1; }

+static void pDL(void)

+	{

+	    DemandLookahead = 1;

+	    if ( GenCC ) {

+			warnNoFL("-gk does not work currently in C++ mode; -gk turned off");

+			DemandLookahead = 0;

+	    }

+	}

+

+static void pAA(char *s,char *t) {MR_AmbAidRule = t;}               /* MR11 */

+static void pAAm(char *s){MR_AmbAidMultiple = 1;}                   /* MR11 */

+static void pGHdr(void)	{ GenStdPccts = 1; }

+static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }

+static void pW1(void) { WarningLevel = 1; }

+static void pNewAST(void) { NewAST = 1; }                           /* MR13 */

+static void ptmakeInParser(void) { tmakeInParser = 1; }             /* MR23 */

+static void pAlpha(void) { AlphaBetaTrace = 1; }                    /* MR14 */

+static void pMR_BlkErr(void) { MR_BlkErr = 1; }                     /* MR21 */

+static void pStdout(void) {UseStdout = 1; }		                    /* MR6 */

+static void pW2(void) { WarningLevel = 2; }

+static void pCC(void) { GenCC = TRUE; }

+#else

+static void pCGen()	{ CodeGen = FALSE; LexGen = FALSE; }

+static void pLGen()	{ LexGen = FALSE; }

+static void pXTGen(){ MR_Inhibit_Tokens_h_Gen = TRUE; }             /* MR14 */

+static void pTGen()	{ TraceGen = TRUE; }

+static void pSGen()	{ GenExprSetsOpt = FALSE; }

+static void pPrt()		{ PrintOut = TRUE; pCGen(); pLGen(); }

+static void pPrtA()	{ PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }

+static void pAst()		{ GenAST = TRUE; }

+static void pANSI()	{ GenANSI = TRUE; }

+static void pCr()		{ GenCR = TRUE; }

+static void pNOPURIFY()	{ PURIFY = FALSE; }

+

+/*static void pCt()		{ warnNoFL("-ct option is now the default"); }*/

+static void pLI()	    { GenLineInfo = TRUE; GenLineInfoMS = FALSE; }  /* MR14 */

+static void pLIms()	    { GenLineInfo = TRUE; GenLineInfoMS = TRUE; }   /* MR14 */

+static void pFr(s,t) char *s, *t; {RemapFileName = t;}

+static void pFe(s,t) char *s, *t; {ErrFileName = t;}

+static void pFl(s,t) char *s, *t; {DlgFileName = t;}

+static void pFm(s,t) char *s, *t; {ModeFileName = t;}

+static void pFt(s,t) char *s, *t; {DefFileName = t;}

+

+static void pE1()		{ elevel = 1; }

+static void pE2()		{ elevel = 2; }

+static void pE3()		{ elevel = 3; }

+static void pEGen()	{ GenEClasseForRules = 1; }

+static void pDL()

+	{

+	    DemandLookahead = 1;

+	    if ( GenCC ) {

+          warnNoFL("-gk does not work currently in C++ mode; -gk turned off");

+	      DemandLookahead = 0;

+	    }

+	}

+

+static void pAA(s,t) char *s; char *t; {MR_AmbAidRule = t;}          /* MR11 BJS 20-Mar-98 */

+static void pAAm(s) char *s; {MR_AmbAidMultiple = 1;}                /* MR11 BJS 20-Mar-98 */

+static void pGHdr()	{ GenStdPccts = 1; }

+static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }

+static void pW1() { WarningLevel = 1; }

+static void pNewAST() { NewAST = 1; }                                /* MR13 */

+static void ptmakeInParser() { tmakeInParser = 1; }                  /* MR23 */

+static void pAlpha() { AlphaBetaTrace = 1; }                         /* MR14 */

+static void pMR_BlkErr() { MR_BlkErr = 1; }                          /* MR21 */

+static void pStdout() {UseStdout = 1; }	                             /* MR6 */

+static void pW2() { WarningLevel = 2; }

+static void pCC() { GenCC = TRUE; }

+#endif

+

+static void

+#ifdef __USE_PROTOS

+pPre( char *s, char *t )

+#else

+pPre( s, t )

+char *s;

+char *t;

+#endif

+{

+	RulePrefix = t;

+}

+

+static void

+#ifdef __USE_PROTOS

+pOut( char *s, char *t )

+#else

+pOut( s, t )

+char *s;

+char *t;

+#endif

+{

+	OutputDirectory = t;

+}

+

+static void

+#ifdef __USE_PROTOS

+pPred( void )

+#else

+pPred( )

+#endif

+{

+	warnNoFL("-pr is no longer used (predicates employed if present); see -prc, -mrhoist, -mrhoistk");

+/*

+**	if ( DemandLookahead )

+**		warnNoFL("-gk conflicts with -pr; -gk turned off");

+**	DemandLookahead = 0;

+**	HoistPredicateContext = 0;

+*/

+}

+

+static void

+#ifdef __USE_PROTOS

+pPredCtx( char *s, char *t )

+#else

+pPredCtx(s,t)

+char *s;

+char *t;

+#endif

+{

+	if ( ci_strequ(t,"on")) HoistPredicateContext = 1;

+	else if ( ci_strequ(t,"off")) HoistPredicateContext = 0;

+	if ( DemandLookahead )

+	{

+		warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");

+		DemandLookahead = 0;

+	}

+}

+

+static void

+#ifdef __USE_PROTOS

+pMRhoist( char *s, char *t )

+#else

+pMRhoist(s,t)

+char *s;

+char *t;

+#endif

+{

+	if ( ci_strequ(t,"on")) MRhoisting = 1;

+	else if ( ci_strequ(t,"off")==0 ) MRhoisting = 0;

+    if (MRhoisting) {

+        fprintf(stderr,"Maintenance Release style hoisting enabled for predicates with lookahead depth = 1\n");

+        fprintf(stderr,"  No longer considered experimental\n");

+        fprintf(stderr,"  Can't consider suppression for predicates with lookahead depth > 1\n");

+        fprintf(stderr,"  Implies -prc on but does *not* imply -mrhoistk for k>1 predicates\n");

+        fprintf(stderr,"  This is a reminder, not a warning or error.\n");

+    };

+}

+

+static void

+#ifdef __USE_PROTOS

+pMRhoistk( char *s, char *t )

+#else

+pMRhoistk(s,t)

+char *s;

+char *t;

+#endif

+{

+	if ( ci_strequ(t,"on")) MRhoistingk = 1;

+	else if ( ci_strequ(t,"off")==0 ) MRhoistingk = 0;

+    if (MRhoistingk) {

+        fprintf(stderr,"EXPERIMENTAL Maintenance Release style hoisting enabled\n");

+        fprintf(stderr,"  Applies to predicates with lookahead depth > 1\n");

+        fprintf(stderr,"  Implies -prc on and -mrhoist on\n");

+    };

+}

+

+static void

+#ifdef __USE_PROTOS

+pTRes( char *s, char *t )

+#else

+pTRes( s, t )

+char *s;

+char *t;

+#endif

+{

+	TreeResourceLimit = atoi(t);

+	if ( TreeResourceLimit <= 0 )

+	{

+		warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");

+		TreeResourceLimit = -1; /* set to no limit */

+	}

+}

+

+Opt options[] = {

+#ifdef __cplusplus

+    { "-CC", 0, (void (*)(...)) pCC,	"Generate C++ output (default=FALSE)"},

+    { "-ck", 1, (void (*)(...)) pCk,	"Set compressed lookahead depth; fast approximate lookahead"},

+    { "-cr", 0, (void (*)(...)) pCr,	"Generate cross reference (default=FALSE)"},

+    { "-e1", 0, (void (*)(...)) pE1,	"Ambiguities/errors shown in low detail (default)"},

+    { "-e2", 0, (void (*)(...)) pE2,	"Ambiguities/errors shown in more detail"},

+    { "-e3", 0, (void (*)(...)) pE3,

+    	"Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},

+    { "-f",  1, (void (*)(...)) pFileList,"Read names of grammar files from specified file"}, /* MR14 */

+    { "-fe", 1, (void (*)(...)) pFe,	"Rename err.c"},

+    { "-fh", 1, (void (*)(...)) pFHdr,	"Rename stdpccts.h header (turns on -gh)"},

+    { "-fl", 1, (void (*)(...)) pFl,	"Rename lexical output--parser.dlg"},

+    { "-fm", 1, (void (*)(...)) pFm,	"Rename mode.h"},

+    { "-fr", 1, (void (*)(...)) pFr,	"Rename remap.h"},

+    { "-ft", 1, (void (*)(...)) pFt,	"Rename tokens.h"},

+    { "-ga", 0, (void (*)(...)) pANSI,	"Generate ANSI-compatible code (default=FALSE)"},

+    { "-gc", 0, (void (*)(...)) pCGen,	"Do not generate output parser code (default=FALSE)"},

+    { "-gd", 0, (void (*)(...)) pTGen,	"Generate code to trace rule invocation (default=FALSE)"},

+    { "-ge", 0, (void (*)(...)) pEGen,	"Generate an error class for each non-terminal (default=FALSE)"},

+    { "-gh", 0, (void (*)(...)) pGHdr,	"Generate stdpccts.h for non-ANTLR-generated-files to include"},

+    { "-gk", 0, (void (*)(...)) pDL,	"Generate parsers that delay lookahead fetches until needed"},

+    { "-gl", 0, (void (*)(...)) pLI,	"Generate line info about grammar actions in parser"},

+    { "-glms", 0, (void (*)(...)) pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"},

+    { "-gp", 1, (void (*)(...)) pPre,	"Prefix all generated rule functions with a string"},

+    { "-gs", 0, (void (*)(...)) pSGen,	"Do not generate sets for token expression lists (default=FALSE)"},

+    { "-gt", 0, (void (*)(...)) pAst,	"Generate code for Abstract-Syntax-Trees (default=FALSE)"},

+    { "-gx", 0, (void (*)(...)) pLGen,	"Do not generate lexical (dlg-related) files (default=FALSE)"},

+    { "-gxt",0, (void (*)(...)) pXTGen,	"Do not generate tokens.h (default=FALSE)"},

+    { "-k",  1, (void (*)(...)) pLLK,	"Set full LL(k) lookahead depth (default==1)"},

+    { "-o",  1, (void (*)(...)) pOut,	OutputDirectoryOption},

+    { "-p",  0, (void (*)(...)) pPrt,	"Print out the grammar w/o actions (default=no)"},

+    { "-pa", 0, (void (*)(...)) pPrtA,	"Print out the grammar w/o actions & w/FIRST sets (default=no)"},

+    { "-pr",0, (void (*)(...)) pPred,	"no longer used; predicates employed if present"},

+    { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},

+   	{ "-rl", 1, (void (*)(...)) pTRes,	"Limit max # of tree nodes used by grammar analysis"},

+    { "-stdout",0,  (void (*)(...)) pStdout,"Send grammar.c/grammar.cpp to stdout"},           /* MR6 */

+	{ "-tab", 1, (void (*)(...)) pTab,	"Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */

+	{ "-w1", 0, (void (*)(...)) pW1,	"Set the warning level to 1 (default)"},

+	{ "-w2", 0, (void (*)(...)) pW2,	"Ambiguities yield warnings even if predicates or (...)? block"},

+	{ "-",   0, (void (*)(...)) pStdin,	"Read grammar from stdin" },

+    { "-mrhoist",1, (void (*)(...)) pMRhoist,                                                  /* MR9 */

+                                        "Turn on/off k=1 Maintenance Release style hoisting"},  /* MR9 */

+    { "-mrhoistk",1, (void (*)(...)) pMRhoistk,                                                  /* MR9 */

+                                        "Turn on/off EXPERIMENTAL k>1 Maintenance Release style hoisting"},  /* MR13 */

+    { "-aa"  , 1, (void (*)(...)) pAA,  "Ambiguity aid for a rule (rule name or line number)"},          /* MR11 */

+    { "-aam" , 0, (void (*)(...)) pAAm,

+                                         "Lookahead token may appear multiple times in -aa listing"},    /* MR11 */

+    { "-aad" , 1, (void (*)(...)) pAAd,

+                                         "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */

+	{ "-info", 1, (void (*)(...)) pInfo,

+      "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"},                          /* MR12 */

+    { "-treport",1,(void (*)(...)) pTreport,

+                        "Report when tnode usage exceeds value during ambiguity resolution"},            /* MR11 */

+	{ "-newAST", 0, (void (*)(...)) pNewAST,

+                 "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""},                        /* MR13 */

+	{ "-tmake", 0, (void (*)(...)) ptmakeInParser,

+                 "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""},			 /* MR23 */

+    { "-alpha",0,(void (*)(...)) pAlpha,

+                 "Provide additional information for \"(alpha)? beta\" error messages"},                 /* MR14 */

+    { "-mrblkerr",0,(void (*)(...)) pMR_BlkErr,                                        /* MR21 */

+                 "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"},        /* MR21 */

+	{ "-nopurify",0,(void (*)(...)) pNOPURIFY,

+		"Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"},   /* MR23 */

+    { "*",   0, (void (*)(...)) pFile, 	"" },	/* anything else is a file */

+#else

+    { "-CC", 0, pCC,	"Generate C++ output (default=FALSE)"},

+    { "-cr", 0, pCr,	"Generate cross reference (default=FALSE)"},

+    { "-ck", 1, pCk,	"Set compressed lookahead depth; fast approximate lookahead"},

+    { "-e1", 0, pE1,	"Ambiguities/errors shown in low detail (default)"},

+    { "-e2", 0, pE2,	"Ambiguities/errors shown in more detail"},

+    { "-e3", 0, pE3,   	"Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},

+    { "-f",  1, pFileList,"Read names of grammar files from specified file"},   /* MR14 */

+    { "-fe", 1, pFe,	"Rename err.c"},

+    { "-fh", 1, pFHdr,	"Rename stdpccts.h header (turns on -gh)"},

+    { "-fl", 1, pFl,	"Rename lexical output--parser.dlg"},

+    { "-fm", 1, pFm,	"Rename mode.h"},

+    { "-fr", 1, pFr,	"Rename remap.h"},

+    { "-ft", 1, pFt,	"Rename tokens.h"},

+    { "-ga", 0, pANSI,	"Generate ANSI-compatible code (default=FALSE)"},

+    { "-gc", 0, pCGen,	"Do not generate output parser code (default=FALSE)"},

+    { "-gd", 0, pTGen,	"Generate code to trace rule invocation (default=FALSE)"},

+    { "-ge", 0, pEGen,	"Generate an error class for each non-terminal (default=FALSE)"},

+    { "-gh", 0, pGHdr,	"Generate stdpccts.h for non-ANTLR-generated-files to include"},

+    { "-gk", 0, pDL,	"Generate parsers that delay lookahead fetches until needed"},

+    { "-gl", 0, pLI,	"Generate line info about grammar actions in C parser"},

+    { "-glms", 0, pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"},

+    { "-gp", 1, pPre,	"Prefix all generated rule functions with a string"},

+    { "-gs", 0, pSGen,	"Do not generate sets for token expression lists (default=FALSE)"},

+    { "-gt", 0, pAst,	"Generate code for Abstract-Syntax-Trees (default=FALSE)"},

+    { "-gx", 0, pLGen,	"Do not generate lexical (dlg-related) files (default=FALSE)"},

+    { "-gxt",0, pXTGen,	"Do not generate tokens.h (default=FALSE)"},

+    { "-k",  1, pLLK,	"Set full LL(k) lookahead depth (default==1)"},

+    { "-o",  1, pOut,	OutputDirectoryOption},

+    { "-p",  0, pPrt,	"Print out the grammar w/o actions (default=no)"},

+    { "-pa", 0, pPrtA,	"Print out the grammar w/o actions & w/FIRST sets (default=no)"},

+    { "-pr",0, pPred,	"no longer used; predicates employed if present"},

+    { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},

+    { "-rl", 1, pTRes,	"Limit max # of tree nodes used by grammar analysis"},

+    { "-stdout",0, pStdout,	"Send grammar.c/grammar.cpp to stdout"},               /* MR6 */

+    { "-tab", 1, pTab,	"Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */

+	{ "-w1", 0, pW1,	"Set the warning level to 1 (default)"},

+	{ "-w2", 0, pW2,	"Ambiguities yield warnings even if predicates or (...)? block"},

+    { "-mrhoist",1,pMRhoist,                                                       /* MR9 */

+                         "Turn on/off k=1 Maintenance Release style hoisting"},  /* MR9 */

+    { "-mrhoistk",1,pMRhoistk,                                                       /* MR13 */

+                         "Turn on/off k>1 EXPERIMENTAL Maintenance Release style hoisting"},  /* MR13 */

+    { "-aa"  ,1,pAA,     "Ambiguity aid for a rule (rule name or line number)"},          /* MR11 */

+    { "-aam" ,0,pAAm,

+                         "Lookahead token may appear multiple times in -aa listing"},     /* MR11 */

+    { "-aad" ,1,pAAd,

+                         "Limits exp growth of -aa listing - default=1 (max=ck value)"},  /* MR11 */

+	{ "-info",1,pInfo,

+      "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"},           /* MR11 */

+    { "-treport",1,pTreport,

+                        "Report when tnode usage exceeds value during ambiguity resolution"},   /* MR11 */

+	{ "-newAST", 0, pNewAST,

+                 "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""},         /* MR13 */

+	{ "-tmake", 0, ptmakeInParser,

+                 "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""},   /* MR23 */

+    { "-alpha",0, pAlpha,

+                 "Provide additional information for \"(alpha)? beta\" error messages"},  /* MR14 */

+    { "-mrblkerr",0,pMR_BlkErr,                                                           /* MR21 */

+                 "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"},           /* MR21 */

+	{ "-nopurify",0,pNOPURIFY,

+		"Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"},   /* MR23 */

+	{ "-",   0, pStdin,	"Read grammar from stdin" },

+	{ "*",   0, pFile, 	"" },	/* anything else is a file */

+#endif

+	{ NULL,  0, NULL }

+ };

+

+void readDescr();

+void cleanUp();

+

+#ifdef __USE_PROTOS

+static void buildRulePtr( void );

+static void help( void );

+static void init( void );

+static void CompleteTokenSetRefs( void );

+static void ensure_no_C_file_collisions(char *);

+static void CompleteContextGuards(void);

+#else

+static void buildRulePtr( );

+static void help( );

+static void init( );

+static void CompleteTokenSetRefs( );

+static void ensure_no_C_file_collisions();

+static void CompleteContextGuards();

+#endif

+

+static void

+#ifdef __USE_PROTOS  /* <BJS> */

+report_numericPredLabels(ActionNode *a)

+#else

+report_numericPredLabels(a)

+ActionNode *a;

+#endif

+{                                                                           /* MR10 */

+  warnFL("numeric references to attributes (e.g. $i or $i.j) in semantic pred will be null during guess mode",  /* MR10 */

+            FileStr[a->file],a->line);                                      /* MR10 */

+}                                                                           /* MR10 */

+

+								/* M a i n */

+

+int

+#ifdef __USE_PROTOS

+main( int argc, char *argv[] )

+#else

+main( argc, argv )

+int argc;

+char *argv[];

+#endif

+{

+	int i;

+	static char EPSTR[] = "[Ep]";

+

+    Save_argc=argc;                                                  /* MR10 */

+    Save_argv=argv;                                                  /* MR10 */

+

+/*	malloc_debug(8);*/

+

+#ifdef SPECIAL_INITS

+    special_inits();                                                 /* MR1 */

+#endif

+	fprintf(stderr, "Antlr parser generator   Version %s   1989-2001\n", Version);

+	if ( argc == 1 ) { help(); zzDIE; }

+	ProcessArgs(argc-1, &(argv[1]), options);

+

+/* MR14 */    if (MR_AmbAidRule && AlphaBetaTrace) {

+/* MR14 */       fatal("Can't specify both -aa (ambiguity aid) and -alpha (\"(alpha)? beta\" aid)");

+/* MR14 */    }

+

+    if (MRhoistingk) {              /* MR13 */

+      HoistPredicateContext=1;      /* MR13 */

+      MRhoisting=1;                 /* MR13 */

+    };                              /* MR13 */

+    if (MRhoisting && ! HoistPredicateContext) {

+/***      warnNoFL("Using \"-mrhoist\" forces \"-prc on\"");    ***/

+      HoistPredicateContext=1;

+    };

+    if (HoistPredicateContext && ! MRhoisting) {

+        warnNoFL("When using predicate context (-prc on) -mrhoist on is recommended");

+    }

+	/* Fix lookahead depth */

+	/* Compressed lookahead must always be larger than or equal to full lookahead */

+	if ( CLL_k < LL_k  && CLL_k>0 )

+	{

+		warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");

+		CLL_k = LL_k;

+	}

+	if ( CLL_k == -1 ) CLL_k = LL_k;

+	OutputLL_k = CLL_k;

+	if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */

+		int n;

+		for(n=1; n<CLL_k; n<<=1) {;}

+		OutputLL_k = n;

+	};

+

+	if (MR_BlkErr) {

+		warnNoFL("The -mrblkerr option is EXPERIMENTAL");

+        if (LL_k > 1) {

+    		warnNoFL("The -mrblkerr option is designed only for k=1 ck=1 grammars");

+        }

+	};

+

+    if ( ! ambAidDepthSpecified) {

+      MR_AmbAidDepth=1;

+    } else {

+      if (MR_AmbAidDepth > CLL_k || MR_AmbAidDepth <= 0) {

+        warnNoFL(eMsgd(

+            "Ambiguity aid depth (\"-aad ...\") must be a number between 1 and max(k,ck)=%d",CLL_k));

+        MR_AmbAidDepth=1;

+      };

+      if (MR_AmbAidDepth == 0) {

+        MR_AmbAidDepth=2;

+      };

+    };

+

+    if (MR_AmbAidRule != NULL) MR_AmbAidLine=atoi(MR_AmbAidRule);

+

+	fpTrans = &(C_Trans[0]);		/* Translate to C Language */

+	fpJTrans = &(C_JTrans[0]);

+	init();

+	lexclass(LexStartSymbol);

+

+	readDescr();

+	LastTokenCounted = TokenNum;

+	RemapForcedTokens();

+	if ( CannotContinue ) {cleanUp(); zzDIE;}

+	if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");

+	if ( WarningLevel>1 && HdrAction == NULL )

+	   warnNoFL("no #header action was found");

+	if ( FoundAtOperator && ! FoundExceptionGroup) {

+	   warnNoFL("found the exception operator '@' - but no exception group was found");

+	};

+	EpToken = addTname(EPSTR);		/* add imaginary token epsilon */

+	set_orel(EpToken, &imag_tokens);

+

+	/* this won't work for hand-built scanners since EofToken is not

+	 * known.  Forces EOF to be token type 1.

+	 */

+	set_orel(EofToken, &imag_tokens);

+

+	set_size(NumWords(TokenNum-1));

+

+	/* compute the set of all known token types

+	 * It represents the set of tokens from 1 to last_token_num + the

+	 * reserved positions above that (if any).  Don't include the set of

+	 * imaginary tokens such as the token/error classes or EOF.

+	 */

+	{

+		set a;

+		a = set_dup(reserved_positions);

+		for (i=1; i<TokenNum; i++) { set_orel(i, &a); }

+		all_tokens = set_dif(a, imag_tokens);

+		set_free(a);

+	}

+

+	ComputeTokSets();				/* Compute #tokclass sets */

+	CompleteTokenSetRefs();			/* Change complex nodes in syn diag */

+    CompleteContextGuards();        /* MR13 */

+

+	if ( CodeGen ) genDefFile();	/* create tokens.h */

+	if ( LexGen ) genLexDescr();	/* create parser.dlg */

+

+	if ( GenStdPccts )

+	{

+		FILE *f = fopen(OutMetaName(stdpccts), "w");

+		if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}

+		else

+		{

+#ifdef SPECIAL_FOPEN

+			special_fopen_actions(OutMetaName(stdpccts));            /* MR1 */

+#endif

+            if (strcmp(stdpccts,"stdpccts.h") == 0) {                /* MR10 */

+ 	  	      genStdPCCTSIncludeFile(f,NULL);                        /* MR10 */

+            } else {                                                 /* MR10 */

+ 	  	      genStdPCCTSIncludeFile(f,pcctsBaseName(stdpccts));     /* MR32 */

+            };

+			fclose(f);

+		}

+	}

+

+	buildRulePtr();					/* create mapping from rule # to RuleBlk junction */

+	ComputeErrorSets();

+	FoLink( (Node *)SynDiag );		/* add follow links to end of all rules */

+	

+	if ( GenCR ) GenCrossRef( SynDiag );

+

+	if ( CodeGen )

+	{

+		if ( SynDiag == NULL )

+		{

+			warnNoFL("no grammar description recognized");

+			cleanUp();

+			zzDIE;

+		}

+		else if ( !GenCC ) {

+			ErrFile = fopen(OutMetaName(ErrFileName), "w");

+			require(ErrFile != NULL, "main: can't open err file");

+#ifdef SPECIAL_FOPEN

+	              special_fopen_actions(OutMetaName(ErrFileName));   /* MR1 */

+#endif

+			NewSetWd();

+			GenErrHdr();

+			TRANS(SynDiag);			/* Translate to the target language */

+			DumpSetWd();

+			DumpRemainingTokSets();

+			fclose( ErrFile );

+		}

+		else {

+			strcpy(Parser_h_Name, CurrentClassName);

+			strcat(Parser_h_Name, ".h");

+			strcpy(Parser_c_Name, CurrentClassName);

+			strcat(Parser_c_Name, CPP_FILE_SUFFIX);

+			ensure_no_C_file_collisions(Parser_c_Name);

+			Parser_h = fopen(OutMetaName(Parser_h_Name), "w");

+			require(Parser_h != NULL, "main: can't open class Parserx.h file");

+#ifdef SPECIAL_FOPEN

+		    special_fopen_actions(OutMetaName(Parser_h_Name));       /* MR1 */

+#endif

+			Parser_c = fopen(OutMetaName(Parser_c_Name), "w");

+			require(Parser_c != NULL, "main: can't open class Parserx.c file");

+#ifdef SPECIAL_FOPEN

+		    special_fopen_actions(OutMetaName(Parser_c_Name));       /* MR1 */

+#endif

+			GenParser_h_Hdr();

+			if ( class_before_actions != NULL )

+			{

+				ListNode *p;

+				for (p = class_before_actions->next; p!=NULL; p=p->next)

+				{

+					UserAction *ua = (UserAction *)p->elem;

+					dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);

+				}

+			}

+			GenParser_c_Hdr();

+			fprintf(Parser_h, "protected:\n");  /* MR20 */

+			NewSetWd();

+			TRANS(SynDiag);			/* Translate to the target language */

+			DumpSetWd();

+			GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);

+			if ( class_after_actions != NULL )

+			{

+				ListNode *p;

+				for (p = class_after_actions->next; p!=NULL; p=p->next)

+				{

+					UserAction *ua = (UserAction *)p->elem;

+					dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);

+				}

+			}

+			DumpRemainingTokSets();

+			fprintf(Parser_h, "};\n");

+			fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName);

+			fclose( Parser_h );

+			fclose( Parser_c );

+		}

+	}

+

+    MR_orphanRules(stderr);

+    if (LTinTokenAction && WarningLevel >= 2) {

+		if (GenCC) {

+			warnNoFL("At least one <<action>> following a token match contains a reference to LT(...)\n      this will reference the immediately preceding token,\n      not the one which follows as is the case with semantic predicates.");

+		}

+			warnNoFL("At least one <<action>> following a token match contains a reference to LA(...) or LATEXT(...)\n      this will reference the immediately preceding token,\n      not the one which follows as is the case with semantic predicates.");

+	}

+

+	if ( PrintOut )

+	{

+		if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}

+		else PRINT(SynDiag);

+	}

+

+#ifdef DBG_LL1

+#endif

+	GenRemapFile();					/* create remap.h */

+/* MR10 */    if (FoundGuessBlk) {

+#ifdef __cplusplus__

+/* MR10 */      list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);

+#else

+#ifdef __USE_PROTOS

+/* MR10 */      list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);

+#else

+/* MR10 */      list_apply(NumericPredLabels,report_numericPredLabels);

+#endif

+#endif

+/* MR10 */    };

+

+    if (InfoT && TnodesAllocated > 0) {

+      if (TnodesPeak > 10000) {

+        fprintf(stdout,"\nTree Nodes:  peak %dk  created %dk  lost %d\n",

+                        (TnodesPeak/1000),

+                        (TnodesAllocated/1000),

+                        TnodesInUse-tnodes_used_in_guard_predicates_etc);

+       } else {

+         fprintf(stdout,"\nTree Nodes:  peak %d  created %d  lost %d\n",

+                        TnodesPeak,

+                        TnodesAllocated,

+                        TnodesInUse-tnodes_used_in_guard_predicates_etc);

+       };

+    };

+    if (InfoF) {

+      DumpFcache();

+    };

+    if (MR_skipped_e3_report) {

+      fprintf(stderr,"note: use -e3 to get exact information on ambiguous tuples\n");

+    };

+    if (MR_BadExprSets != 0) {

+      fprintf(stderr,"note: Unreachable C or C++ code was generated for empty expression sets,\n");

+      fprintf(stderr,"        probably due to undefined rules or infinite left recursion.\n");

+      fprintf(stderr,"      To locate: search the generated code for \"empty set expression\"\n");

+    };

+    if (MR_AmbAidRule != NULL && MR_matched_AmbAidRule==0) {

+      RuleEntry *q = (RuleEntry *) hash_get(Rname,MR_AmbAidRule);

+      if (MR_AmbAidLine == 0 && q == NULL) {

+         warnNoFL(eMsg2("there is no rule \"%s\" so \"-aa %s\" will never match",

+                                                        MR_AmbAidRule,MR_AmbAidRule));

+      } else {

+        warnNoFL(eMsg1("there was no ambiguity that matched \"-aa %s\"",MR_AmbAidRule));

+      };

+    };

+    if (AlphaBetaTrace) {

+

+      if (MR_AlphaBetaMessageCount == 0) {

+         fprintf(stderr,"note: there were no messages about \"(alpha)? beta\" blocks added to the generated code\n");

+      } else {

+         fprintf(stderr,"note: there were %d messages about \"(alpha)? beta\" blocks added to the generated code\n",

+                    MR_AlphaBetaMessageCount);

+      }

+

+      if (set_null(MR_CompromisedRules)) {

+         fprintf(stderr,"note: the list of rules with compromised follow sets is empty\n");

+      } else {

+         fprintf(stderr,"note: the following is a list of rules which *may* have incorrect\n");

+         fprintf(stderr,"      follow sets computed as a result of an \"(alpha)? beta\" block\n");

+         fprintf(stderr,"\n");

+         MR_dumpRuleSet(MR_CompromisedRules);

+         fprintf(stderr,"\n");

+      }

+    }

+	cleanUp();

+	exit(PCCTS_EXIT_SUCCESS);

+    return 0;           /* MR11 make compilers happy */ 

+}

+

+static void 

+#ifdef __USE_PROTOS 

+init( void )

+#else

+init( )

+#endif

+{

+	SignalEntry *q;

+

+	Tname = newHashTable();

+	Rname = newHashTable();

+	Fcache = newHashTable();

+	Tcache = newHashTable();

+	Sname = newHashTable();

+    Pname = newHashTable();     /* MR11 */

+

+	/* Add default signal names */

+	q = (SignalEntry *)hash_add(Sname,

+							  "NoViableAlt",

+							  (Entry *)newSignalEntry("NoViableAlt"));

+	require(q!=NULL, "cannot alloc signal entry");

+	q->signum = sigNoViableAlt;

+	q = (SignalEntry *)hash_add(Sname,

+							  "MismatchedToken",

+							  (Entry *)newSignalEntry("MismatchedToken"));

+	require(q!=NULL, "cannot alloc signal entry");

+	q->signum = sigMismatchedToken;

+	q = (SignalEntry *)hash_add(Sname,

+							  "NoSemViableAlt",

+							  (Entry *)newSignalEntry("NoSemViableAlt"));

+	require(q!=NULL, "cannot alloc signal entry");

+	q->signum = sigNoSemViableAlt;

+	

+	reserved_positions = empty;

+	all_tokens = empty;

+	imag_tokens = empty;

+	tokclasses = empty;

+	TokenStr = (char **) calloc(TSChunk, sizeof(char *));

+	require(TokenStr!=NULL, "main: cannot allocate TokenStr");

+	FoStack = (int **) calloc(CLL_k+1, sizeof(int *));

+	require(FoStack!=NULL, "main: cannot allocate FoStack");

+	FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));

+	require(FoTOS!=NULL, "main: cannot allocate FoTOS");

+	Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));

+	require(Cycles!=NULL, "main: cannot allocate Cycles List");

+    MR_CompromisedRules=empty;  /* MR14 */

+}

+

+static void

+#ifdef __USE_PROTOS

+help( void )

+#else

+help( )

+#endif

+{

+	Opt *p = options;

+	fprintf(stderr, "antlr [options] f1 f2 ... fn\n");

+	while ( *(p->option) != '*' )

+	{

+		fprintf(stderr, "    %-9s%s   %s\n",

+						p->option,

+						(p->arg)?"___":"   ",

+						p->descr);

+		p++;

+	}

+}

+

+/* The RulePtr array is filled in here.  RulePtr exists primarily

+ * so that sets of rules can be maintained for the FOLLOW caching

+ * mechanism found in rJunc().  RulePtr maps a rule num from 1 to n

+ * to a pointer to its RuleBlk junction where n is the number of rules.

+ */

+static void

+#ifdef __USE_PROTOS

+buildRulePtr( void )

+#else

+buildRulePtr( )

+#endif

+{

+	int r=1;

+	Junction *p  = SynDiag;

+	RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));

+	require(RulePtr!=NULL, "cannot allocate RulePtr array");

+	

+	while ( p!=NULL )

+	{

+		require(r<=NumRules, "too many rules???");

+		RulePtr[r++] = p;

+		p = (Junction *)p->p2;

+	}

+}

+

+void

+#ifdef __USE_PROTOS

+dlgerror(const char *s)

+#else

+dlgerror(s)

+char *s;

+#endif

+{

+	fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);

+	fprintf(stderr, " lexical error: %s (text was '%s')\n",

+					((s == NULL) ? "Lexical error" : s), zzlextext);

+}

+

+void

+#ifdef __USE_PROTOS

+readDescr( void )

+#else

+readDescr( )

+#endif

+{

+	zzerr = dlgerror;

+	input = NextFile();

+	if ( input==NULL ) fatal("No grammar description found (exiting...)");

+	ANTLR(grammar(), input);

+    tnodes_used_in_guard_predicates_etc=TnodesInUse;    /* MR10 */

+}

+

+FILE *

+#ifdef __USE_PROTOS

+NextFile( void )

+#else

+NextFile( )

+#endif

+{

+	FILE *f;

+

+	for (;;)

+	{

+		CurFile++;

+		if ( CurFile >= NumFiles ) return(NULL);

+		if ( ci_strequ(FileStr[CurFile],"stdin")) return stdin;

+		f = fopen(FileStr[CurFile], "r");

+		if ( f == NULL )

+		{

+			warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );

+		}

+		else

+		{

+			return(f);

+		}

+	}

+}

+

+/*

+ * Return a string corresponding to the output file name associated

+ * with the input file name passed in.

+ *

+ * Observe the following rules:

+ *

+ *		f.e		--> f".c"

+ *		f		--> f".c"

+ *		f.		--> f".c"

+ *		f.e.g	--> f.e".c"

+ *

+ * Where f,e,g are arbitrarily long sequences of characters in a file

+ * name.

+ *

+ * In other words, if a ".x" appears on the end of a file name, make it

+ * ".c".  If no ".x" appears, append ".c" to the end of the file name.

+ *

+ * C++ mode using .cpp not .c.

+ *

+ * Use malloc() for new string.

+ */

+

+char *

+#ifdef __USE_PROTOS

+outname( char *fs )

+#else

+outname( fs )

+char *fs;

+#endif

+{

+    if ( GenCC) {

+      return outnameX(fs,CPP_FILE_SUFFIX);

+    } else {

+      return outnameX(fs,".c");

+    };

+}

+

+char *

+#ifdef __USE_PROTOS

+outnameX( char *fs ,char *suffix)

+#else

+outnameX( fs , suffix )

+char *fs;

+char *suffix;

+#endif

+{

+	static char buf[MaxFileName+1];

+	char *p;

+	require(fs!=NULL&&*fs!='\0', "outname: NULL filename");

+

+	p = buf;

+	strcpy(buf, fs);

+	while ( *p != '\0' )  {p++;}			/* Stop on '\0' */

+	while ( *p != '.' && p != buf ) {--p;}	/* Find '.' */

+	if ( p != buf ) *p = '\0';				/* Found '.' */

+	require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");

+    strcat(buf,suffix);

+	return( buf );

+}

+

+void

+#ifdef __USE_PROTOS

+fatalFL( char *err_, char *f, int l )

+#else

+fatalFL( err_, f, l )

+char *err_;

+char *f;

+int l;

+#endif

+{

+	fprintf(stderr, ErrHdr, f, l);

+	fprintf(stderr,	" %s\n", err_);

+	cleanUp();

+	exit(PCCTS_EXIT_FAILURE);

+}

+

+void

+#ifdef __USE_PROTOS

+fatal_intern( char *err_, char *f, int l )

+#else

+fatal_intern( err_, f, l )

+char *err_;

+char *f;

+int l;

+#endif

+{

+	fprintf(stderr, ErrHdr, f, l);

+	fprintf(stderr,	" #$%%*&@# internal error: %s\n", err_);

+	fprintf(stderr, ErrHdr, f, l);

+	fprintf(stderr, " [complain to nearest government official\n");

+	fprintf(stderr, ErrHdr, f, l);

+	fprintf(stderr, "  or send hate-mail to parrt@parr-research.com;\n");

+	fprintf(stderr, ErrHdr, f, l);

+	fprintf(stderr, "  please pray to the ``bug'' gods that there is a trival fix.]\n");

+	cleanUp();

+	exit(PCCTS_EXIT_FAILURE);

+}

+

+void

+#ifdef __USE_PROTOS

+cleanUp( void )

+#else

+cleanUp( )

+#endif

+{

+	if ( DefFile != NULL) fclose( DefFile );

+}

+

+/* sprintf up to 3 strings */

+char *

+#ifdef __USE_PROTOS

+eMsg3( char *s, char *a1, char *a2, char *a3 )

+#else

+eMsg3( s, a1, a2, a3 )

+char *s;

+char *a1;

+char *a2;

+char *a3;

+#endif

+{

+	static char buf[250];			/* DANGEROUS as hell !!!!!! */

+	

+	sprintf(buf, s, a1, a2, a3);

+	return( buf );

+}

+

+/* sprintf a decimal */

+char *

+#ifdef __USE_PROTOS

+eMsgd( char *s, int d )

+#else

+eMsgd( s, d )

+char *s;

+int d;

+#endif

+{

+	static char buf[250];			/* DANGEROUS as hell !!!!!! */

+	

+	sprintf(buf, s, d);

+	return( buf );

+}

+

+char *

+#ifdef __USE_PROTOS

+eMsgd2( char *s, int d1,int d2)

+#else

+eMsgd2( s, d1, d2 )

+char *s;

+int d1;

+int d2;

+#endif

+{

+	static char buf[250];			/* DANGEROUS as hell !!!!!! */

+	

+	sprintf(buf, s, d1, d2);

+	return( buf );

+}

+

+void

+#ifdef __USE_PROTOS

+s_fprT( FILE *f, set e )

+#else

+s_fprT( f, e )

+FILE *f;

+set e;

+#endif

+{

+	register unsigned *p;

+	unsigned *q;

+

+	if ( set_nil(e) ) return;

+	if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");

+	fprintf(f, "{");

+	while ( *p != nil )

+	{

+		fprintf(f, " %s", TerminalString(*p));

+		p++;

+	}

+	fprintf(f, " }");

+	free((char *)q);

+}

+

+/* Return the token name or regular expression for a token number. */

+char *

+#ifdef __USE_PROTOS

+TerminalString( int token )

+#else

+TerminalString( token )

+int token;

+#endif

+{

+	int     j;

+        static    char    imag_name[20];

+

+	/* look in all lexclasses for the token */

+	if ( TokenString(token) != NULL ) return TokenString(token);

+	for (j=0; j<NumLexClasses; j++)

+	{

+		lexmode(j);

+		if ( ExprString(token) != NULL ) return ExprString(token);

+	}

+

+    if (1) {

+      sprintf(imag_name,"UnknownToken#%d",token);           /* MR13 */

+      return imag_name;                                     /* MR13 */

+    }

+

+	require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));

+	return "invalid";

+}

+

+                    /* S i m p l e  I n t  S t a c k */

+

+void

+#ifdef __USE_PROTOS

+pushint( int i )

+#else

+pushint( i )

+int i;

+#endif

+{

+	require(isp>0, "pushint: stack overflow");

+	istack[--isp] = i;

+}

+

+int

+#ifdef __USE_PROTOS

+popint( void )

+#else

+popint( )

+#endif

+{

+	require(isp<MAX_INT_STACK, "popint: stack underflow");

+	return istack[isp++];

+}

+

+int

+#ifdef __USE_PROTOS

+istacksize( void )

+#else

+istacksize( )

+#endif

+{

+	return MAX_INT_STACK-isp;

+}

+

+void

+#ifdef __USE_PROTOS

+istackreset( void )

+#else

+istackreset( )

+#endif

+{

+	isp = MAX_INT_STACK;

+}

+

+int

+#ifdef __USE_PROTOS

+istackempty( void )

+#else

+istackempty( )

+#endif

+{

+	return isp==MAX_INT_STACK;

+}

+

+int

+#ifdef __USE_PROTOS

+topint( void )

+#else

+topint( )

+#endif

+{

+	require(isp<MAX_INT_STACK, "topint: stack underflow");

+	return istack[isp];

+}

+

+void

+#ifdef __USE_PROTOS

+ProcessArgs( int argc, char **argv, Opt *options )

+#else

+ProcessArgs( argc, argv, options )

+int argc;

+char **argv;

+Opt *options;

+#endif

+{

+	Opt *p;

+	require(argv!=NULL, "ProcessArgs: command line NULL");

+

+	while ( argc-- > 0 )

+	{

+		p = options;

+		while ( p->option != NULL )

+		{

+			if ( strcmp(p->option, "*") == 0 ||

+				 ci_strequ(p->option, *argv) == 1 )

+			{

+				if ( p->arg )

+				{

+/* MR9  26-Sep-97   Check for argv valid                */

+                    if (argc-- > 0) {

+  				     	(*p->process)( *argv, *(argv+1) );

+					    argv++;

+                    } else {

+fprintf(stderr,"error: required argument for option %s omitted\n",*argv);

+exit(PCCTS_EXIT_FAILURE);

+                    };

+				}

+				else

+					(*p->process)( *argv );

+				break;

+			}

+			p++;

+		}

+		argv++;

+	}

+}

+

+static void 

+#ifdef __USE_PROTOS

+CompleteContextGuards(void)

+#else

+CompleteContextGuards()

+#endif

+{

+    ListNode *      p;

+    Predicate *     pred;

+

+    if (ContextGuardPredicateList == NULL) return;

+

+    for (p=ContextGuardPredicateList->next; p != NULL; p=p->next) {

+      pred=(Predicate *)p->elem;

+      recomputeContextGuard(pred);

+    }

+}

+

+/* Go back into the syntax diagram and compute all meta tokens; i.e.

+ * turn all '.', ranges, token class refs etc... into actual token sets

+ */

+static void

+#ifdef __USE_PROTOS

+CompleteTokenSetRefs(void)

+#else

+CompleteTokenSetRefs()

+#endif

+{

+	ListNode *p;

+

+	if ( MetaTokenNodes==NULL ) return;

+	for (p = MetaTokenNodes->next; p!=NULL; p=p->next)

+	{

+		set a,b;

+

+		TokNode *q = (TokNode *)p->elem;

+		if ( q->wild_card )

+		{

+			q->tset = all_tokens;

+		}

+		else if ( q->tclass!=NULL )

+		{

+			if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);

+			else q->tset = q->tclass->tset;

+		}

+		else if ( q->upper_range!=0 )

+		{

+			/* we have a range on our hands: make a set from q->token .. q->upper_range */

+			int i;

+			a = empty;

+			for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); }   /* MR13 */

+

+/* MR13 */    if (q->complement) {

+/* MR13 */      q->tset = set_dif(all_tokens, a);

+/* MR13 */        set_free(a);

+/* MR13 */      } else {

+/* MR13 */	      q->tset = a;

+/* MR13 */      }

+

+        }

+

+		/* at this point, it can only be a complemented single token */

+		else if ( q->complement )

+		{

+			a = set_of(q->token);

+			b = set_dif(all_tokens, a);

+			set_free(a);

+			q->tset=b;

+		}

+		else fatal("invalid meta token");

+	}

+}

+

+/* MR10: Jeff Vincent

+   MR10: Changed to remove directory information from n only if

+   MR10: if OutputDirectory was changed by user (-o option)

+*/

+

+char *

+#ifdef __USE_PROTOS

+OutMetaName(char *n)

+#else

+OutMetaName(n)

+char *n;

+#endif

+{	

+    static char *dir_sym = DirectorySymbol;

+    static char newname[MaxFileName+1];

+    char *p;

+

+	/* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */

+    if (strcmp(OutputDirectory, TopDirectory) == 0)		/* TopDirectory is "." on Unix. */

+		return n;

+

+	/* p will point to filename without path information */

+	if ((p = strrchr(n, *dir_sym)) != NULL)				/* Directory symbol is "/" on Unix. */

+		p++;

+	else

+		p = n;

+

+	/* Copy new output directory into newname[] */

+	strcpy(newname, OutputDirectory);

+

+	/* if new output directory does not have trailing dir_sym, add it! */

+	if (newname[strlen(newname)-1] != *dir_sym) {

+		strcat(newname, dir_sym);

+	}

+	strcat(newname, p);

+	return newname;

+}

+

+char *

+#ifdef __USE_PROTOS

+pcctsBaseName(char *n) /* MR32 */

+#else

+pcctsBaseName(n)

+char *n;

+#endif

+{

+    static char newname[MaxFileName+1];

+    static char* dir_sym = DirectorySymbol;

+    int count = 0;

+    char *p;

+

+    p = n;

+

+    while ( *p != '\0' )  {p++;}                    /* go to end of string */

+    while ( (*p != *dir_sym) && (p != n) ) {--p;}   /* Find last DirectorySymbol */

+    while ( *p == *dir_sym) p++;                    /* step forward if we're on a dir symbol */

+    while ( *p != '\0' && *p != '.')

+    {

+        newname[count++] = *p;

+        p++;

+    }                                               /* create a new name */

+    newname[count] = '\0';

+    return newname;

+}

+

+static void

+#ifdef __USE_PROTOS

+ensure_no_C_file_collisions(char *class_c_file)

+#else

+ensure_no_C_file_collisions(class_c_file)

+char *class_c_file;

+#endif

+{

+	int i;

+

+	for (i=0; i<NumFiles; i++)

+	{

+

+#ifdef PCCTS_CASE_INSENSITIVE_FILE_NAME

+		/* assume that file names are case insensitive */

+		if ( STRICMP(outname(FileStr[i]), class_c_file)==0 )

+#else

+		if ( strcmp(outname(FileStr[i]), class_c_file)==0 )

+#endif

+		{

+			fatal(eMsg1("class def output file conflicts with parser output file: %s",

+						outname(FileStr[i])));

+		}

+	}

+}

+

+void

+#ifdef __USE_PROTOS

+warnNoFL(char *err)

+#else

+warnNoFL(err)

+char *err;

+#endif

+{

+	fprintf(stderr, "warning: %s\n", err);

+}

+

+void

+#ifdef __USE_PROTOS

+warnFL(char *err,char *f,int l)

+#else

+warnFL(err,f,l)

+char *f;

+int l;

+char *err;

+#endif

+{

+	fprintf(stderr, ErrHdr, f, l);						

+	fprintf(stderr, " warning: %s\n", err);

+}

+

+void

+#ifdef __USE_PROTOS

+warn(char *err)												

+#else

+warn(err)												

+char *err;

+#endif

+{

+	/* back up the file number if we hit an error at the end of the last file */

+	if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;

+	fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);

+	fprintf(stderr, " warning: %s\n", err);

+}

+

+void

+#ifdef __USE_PROTOS

+warnNoCR( char *err )

+#else

+warnNoCR( err )											

+char *err;

+#endif

+{

+	/* back up the file number if we hit an error at the end of the last file */

+	if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;

+	fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);

+	fprintf(stderr, " warning: %s", err);

+}

+

+void

+#ifdef __USE_PROTOS

+errNoFL(char *err)

+#else

+errNoFL(err)

+char *err;

+#endif

+{

+	fprintf(stderr, "error: %s\n", err);

+}

+

+void

+#ifdef __USE_PROTOS

+errFL(char *err,char *f,int l)

+#else

+errFL(err,f,l)

+char *err;

+char *f;

+int l;

+#endif

+{

+	fprintf(stderr, ErrHdr, f, l);						

+	fprintf(stderr, " error: %s\n", err);

+}

+

+void

+#ifdef __USE_PROTOS

+err(char *err)												

+#else

+err(err)												

+char *err;

+#endif

+{

+	/* back up the file number if we hit an error at the end of the last file */

+	if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;

+	fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);

+	fprintf(stderr, " error: %s\n", err);

+}

+

+void

+#ifdef __USE_PROTOS

+errNoCR( char *err )											

+#else

+errNoCR( err )											

+char *err;

+#endif

+{

+	/* back up the file number if we hit an error at the end of the last file */

+	if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;

+	fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);

+	fprintf(stderr, " error: %s", err);

+}

+

+UserAction *

+#ifdef __USE_PROTOS

+newUserAction(char *s)

+#else

+newUserAction(s)

+char *s;

+#endif

+{

+	UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));

+	require(ua!=NULL, "cannot allocate UserAction");

+

+	ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));

+	strcpy(ua->action, s);

+	return ua;

+}

+

+/* Added by TJP September 1994 */

+/* Take in file.h and return file_h; names w/o '.'s are left alone */

+char *

+#ifdef __USE_PROTOS

+gate_symbol(char *name)

+#else

+gate_symbol(name)

+char *name;

+#endif

+{

+	static char buf[100];

+	char *p;

+	sprintf(buf, "%s", name);

+

+	for (p=buf; *p!='\0'; p++)

+	{

+		if ( *p=='.' ) *p = '_';

+	}

+	return buf;

+}

+

+char *

+#ifdef __USE_PROTOS

+makeAltID(int blockid, int altnum)

+#else

+makeAltID(blockid, altnum)

+int blockid;

+int altnum;

+#endif

+{

+	static char buf[100];

+	char *p;

+	sprintf(buf, "_blk%d_alt%d", blockid, altnum);

+	p = (char *)malloc(strlen(buf)+1);

+	strcpy(p, buf);

+	return p;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/makefile b/edk2/Tools/Source/TianoTools/Pccts/antlr/makefile
new file mode 100644
index 0000000..a528001
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/makefile
@@ -0,0 +1,218 @@
+#

+# Makefile for ANTLR 1.33

+#

+# SOFTWARE RIGHTS

+#

+# We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+# Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+# company may do whatever they wish with source code distributed with

+# PCCTS or the code generated by PCCTS, including the incorporation of

+# PCCTS, or its output, into commerical software.

+# 

+# We encourage users to develop software with PCCTS.  However, we do ask

+# that credit is given to us for developing PCCTS.  By "credit",

+# we mean that if you incorporate our source code into one of your

+# programs (commercial product, research project, or otherwise) that you

+# acknowledge this fact somewhere in the documentation, research report,

+# etc...  If you like PCCTS and have developed a nice tool with the

+# output, please mention that you developed it using PCCTS.  In

+# addition, we ask that this header remain intact in our source code.

+# As long as these guidelines are kept, we expect to continue enhancing

+# this system and expect to make other tools available as they are

+# completed.

+#

+# ANTLR 1.33

+# Terence Parr

+# Parr Research Corporation

+# with Purdue University

+# and AHPCRC, University of Minnesota

+# 1989-1995

+#

+# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by

+# Ed Harfmann

+# Micro Data Base Systems

+# Lafayette, Indiana

+#

+SET=../support/set

+PCCTS_H=../h

+

+##

+## Uncomment the appropriate section to build

+## (both targets and 'make' variable definitions)

+## Note that UNIX is the default

+##

+

+#

+#   OS/2 & DOS 16 bit using MSC 6.0

+#

+#CC=cl

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN

+#OUT_OBJ = -Fo

+#LIBS=/NOD:LLIBCE LLIBCEP

+#OBJ_EXT = obj

+#

+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \

+#        fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \

+#        misc.obj set.obj pred.obj egamn.obj

+#       link @<<

+#$** /NOI

+#$@ /STACK:14336

+#

+#$(LIBS: = +^

+#)

+#$(DEF_FILE) $(LFLAGS) ;

+#<<

+#        bind $@ c:\os2\doscalls.lib

+#        copy *.exe ..\bin

+#

+

+#

+#   Borland C++ for DOS

+#

+#CC=bcc

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN

+#OUT_OBJ = -o

+#LIBS= emu mathl cl

+#OBJ_EXT = obj

+#

+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \

+#        fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \

+#        misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj

+#       tlink @&&|

+#C0L $**

+#$@ /Tde /c

+#

+#$(LIBS)

+#$(DEF_FILE) $(LFLAGS) ;

+#|

+#        copy *.exe ..\bin

+#

+

+#

+# C-Set/2 for OS/2

+#

+#CC=icc

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__

+#OUT_OBJ = -Fo

+#LIBS=

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#OBJ_EXT = obj

+#

+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \

+#        fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \

+#        misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj

+#        link386 @<<

+#$** /NOI

+#$@ /STACK:32768

+#

+#$(LIBS: = +^

+#)

+#$(DEF_FILE) $(LFLAGS) ;

+#<<

+#        copy *.exe ..\bin

+#

+

+#

+# Borland C++ for OS/2

+#

+#CC=bcc

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN

+#OUT_OBJ = -o

+#LIBS= c2 os2

+#

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#OBJ_EXT = obj

+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \

+#        fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \

+#        misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj

+#        tlink @&&|

+#c02 $** -c -v

+#antlr.exe

+#

+#C2 os2

+#

+#|

+#        copy *.exe ..\bin

+#

+

+# *********** Target list of PC machines ***********

+#

+# Don't worry about the ambiguity messages coming from antlr

+# for making antlr.c etc...  [should be 10 of them, I think]

+#

+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g

+#	$(ANTLR) antlr.g

+#

+#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h

+#

+#scan.$(OBJ_EXT): scan.c mode.h tokens.h

+#

+#scan.c mode.h: parser.dlg

+#	$(DLG) -C2 parser.dlg scan.c

+#

+#set.$(OBJ_EXT): $(SET)/set.c

+#	$(CC) $(CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c

+

+

+

+#

+#   UNIX  (default)

+#

+CC=gcc

+COPT=-O

+ANTLR=../bin/antlr

+DLG=../bin/dlg

+OBJ_EXT=o

+OUT_OBJ = -o

+CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536

+#

+# SGI Users, use this CFLAGS

+#

+#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262

+OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o  \

+        globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o

+

+antlr : $(OBJ) $(SRC)

+		$(CC) $(CFLAGS) -o ${WORKSPACE}/Tools/bin/antlr $(OBJ)

+

+# what files does PCCTS generate (both ANTLR and DLG)

+PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h

+

+SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \

+	hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c

+

+#

+# Don't worry about the ambiguity messages coming from antlr

+# for making antlr.c etc...  [should be 10 of them, I think]

+#

+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g

+#	$(ANTLR) -gh antlr.g

+

+antlr.o : antlr.c mode.h tokens.h

+

+scan.o : scan.c mode.h tokens.h

+

+#scan.c mode.h: parser.dlg

+#	$(DLG) -C2 parser.dlg scan.c

+

+set.o : $(SET)/set.c

+	$(CC) $(CFLAGS) -c -o set.o $(SET)/set.c

+

+

+#

+# ****** These next targets are common to UNIX and PC world ********

+#

+

+#clean up all the intermediate files

+clean:

+	rm -f *.$(OBJ_EXT) core

+

+#remove everything in clean plus the PCCTS files generated

+scrub:

+	rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/makefile1 b/edk2/Tools/Source/TianoTools/Pccts/antlr/makefile1
new file mode 100644
index 0000000..5c4a275
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/makefile1
@@ -0,0 +1,96 @@
+#

+# Makefile for ANTLR 1.33

+#

+# SOFTWARE RIGHTS

+#

+# We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+# Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+# company may do whatever they wish with source code distributed with

+# PCCTS or the code generated by PCCTS, including the incorporation of

+# PCCTS, or its output, into commerical software.

+# 

+# We encourage users to develop software with PCCTS.  However, we do ask

+# that credit is given to us for developing PCCTS.  By "credit",

+# we mean that if you incorporate our source code into one of your

+# programs (commercial product, research project, or otherwise) that you

+# acknowledge this fact somewhere in the documentation, research report,

+# etc...  If you like PCCTS and have developed a nice tool with the

+# output, please mention that you developed it using PCCTS.  In

+# addition, we ask that this header remain intact in our source code.

+# As long as these guidelines are kept, we expect to continue enhancing

+# this system and expect to make other tools available as they are

+# completed.

+#

+# ANTLR 1.33

+# Terence Parr

+# Parr Research Corporation

+# with Purdue University

+# and AHPCRC, University of Minnesota

+# 1989-1995

+#

+# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by

+# Ed Harfmann

+# Micro Data Base Systems

+# Lafayette, Indiana

+#

+SET=../support/set

+PCCTS_H=../h

+

+#

+#   UNIX  (default)

+#

+CC=cc

+ANTLR=../bin/antlr

+DLG=../bin/dlg

+OBJ_EXT=o

+OUT_OBJ = -o

+ANSI=-ansi

+AOTHER=

+CFLAGS= -O0 -g -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) $(ANSI) -DZZLEXBUFSIZE=32000

+#

+# SGI Users, use this CFLAGS

+#

+#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262

+

+OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \

+        globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o $(OBJOTHER)

+

+antlr : $(OBJ) $(SRC)

+		$(CC) $(CFLAGS) -o antlr $(OBJ)

+		mv antlr ../bin

+

+# what files does PCCTS generate (both ANTLR and DLG)

+PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h

+

+SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \

+	hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c

+

+#

+# Don't worry about the ambiguity messages coming from antlr

+# for making antlr.c etc...  [should be 10 of them, I think]

+#

+antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g

+	$(ANTLR) -gh antlr.g $(AOTHER)

+

+antlr.o : antlr.c mode.h tokens.h

+

+scan.o : scan.c mode.h tokens.h

+

+scan.c mode.h: parser.dlg

+	$(DLG) -C2 parser.dlg scan.c

+

+set.o : $(SET)/set.c

+	$(CC) $(CFLAGS) -c -o set.o $(SET)/set.c

+

+

+#

+# ****** These next targets are common to UNIX and PC world ********

+#

+

+#clean up all the intermediate files

+clean:

+	rm -f *.$(OBJ_EXT) core

+

+#remove everything in clean plus the PCCTS files generated

+scrub:

+	rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/misc.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/misc.c
new file mode 100644
index 0000000..3f58da3
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/misc.c
@@ -0,0 +1,1864 @@
+/*

+ * misc.c

+ *

+ * Manage tokens, regular expressions.

+ * Print methods for debugging

+ * Compute follow lists onto tail ends of rules.

+ *

+ * The following functions are visible:

+ *

+ *		int		addTname(char *);		Add token name

+ *		int		addTexpr(char *);		Add token expression

+ *		int		Tnum(char *);			Get number of expr/token

+ *		void	Tklink(char *, char *);	Link a name with an expression

+ *		int		hasAction(expr);		Does expr already have action assigned?

+ *		void	setHasAction(expr);		Indicate that expr now has an action

+ *		Entry	*newEntry(char *,int);	Create new table entry with certain size

+ *		void	list_add(ListNode **list, char *e)

+ *      void    list_free(ListNode **list, int freeData);   *** MR10 ***

+ *		void	list_apply(ListNode *list, void (*f)())

+ *		void	lexclass(char *m);		switch to new/old lexical class

+ *		void	lexmode(int i);			switch to old lexical class i

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "pcctscfg.h"

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+#include <ctype.h>

+

+static int tsize=TSChunk;		/* size of token str arrays */

+

+static void

+#ifdef __USE_PROTOS

+RemapForcedTokensInSyntaxDiagram(Node *);

+#else

+RemapForcedTokensInSyntaxDiagram();

+#endif

+

+				/* T o k e n  M a n i p u l a t i o n */

+

+/*

+ * add token 't' to the TokenStr/Expr array.  Make more room if necessary.

+ * 't' is either an expression or a token name.

+ *

+ * There is only one TokenStr array, but multiple ExprStr's.  Therefore,

+ * for each lex class (element of lclass) we must extend the ExprStr array.

+ * ExprStr's and TokenStr are always all the same size.

+ *

+ * Also, there is a Texpr hash table for each automaton.

+ */

+static void

+#ifdef __USE_PROTOS

+Ttrack( char *t )

+#else

+Ttrack( t )

+char *t;

+#endif

+{

+	if ( TokenNum >= tsize )	/* terminal table overflow? */

+	{

+		char **p;

+		int i, more, j;

+

+		more = TSChunk * (1 + ((TokenNum-tsize) / TSChunk));

+		tsize += more;

+		TokenStr = (char **) realloc((char *)TokenStr, tsize*sizeof(char *));

+		require(TokenStr != NULL, "Ttrack: can't extend TokenStr");

+		for (i=0; i<NumLexClasses; i++)

+		{

+			lclass[i].exprs = (char **)

+							  realloc((char *)lclass[i].exprs, tsize*sizeof(char *));

+			require(lclass[i].exprs != NULL, "Ttrack: can't extend ExprStr");

+			for (p= &lclass[i].exprs[tsize-more],j=1; j<=more; j++) *p++ = NULL;

+		}

+		for (p= &TokenStr[tsize-more],i=1; i<=more; i++) *p++ = NULL;

+		lexmode( CurrentLexClass ); /* reset ExprStr in case table moved */

+	}

+	/* note: we use the actual ExprStr/TokenStr array

+	 * here as TokenInd doesn't exist yet

+	 */

+	if ( *t == '"' ) ExprStr[TokenNum] = t;

+	else TokenStr[TokenNum] = t;

+}

+

+static Expr *

+#ifdef __USE_PROTOS

+newExpr( char *e )

+#else

+newExpr( e )

+char *e;

+#endif

+{

+	Expr *p = (Expr *) calloc(1, sizeof(Expr));

+	require(p!=NULL, "newExpr: cannot alloc Expr node");

+

+	p->expr = e;

+	p->lclass = CurrentLexClass;

+	return p;

+}

+

+/* switch to lexical class/mode m.  This amounts to creating a new

+ * lex mode if one does not already exist and making ExprStr point

+ * to the correct char string array.  We must also switch Texpr tables.

+ *

+ * BTW, we need multiple ExprStr arrays because more than one automaton

+ * may have the same label for a token, but with different expressions.

+ * We need to track an expr for each automaton.  If we disallowed this

+ * feature, only one ExprStr would be required.

+ */

+void

+#ifdef __USE_PROTOS

+lexclass( char *m )

+#else

+lexclass( m )

+char *m;

+#endif

+{

+	int i;

+	TermEntry *p;

+	static char EOFSTR[] = "\"@\"";

+

+	if ( hash_get(Tname, m) != NULL )

+	{

+		warn(eMsg1("lexclass name conflicts with token/errclass label '%s'",m));

+	}

+	/* does m already exist? */

+	i = LexClassIndex(m);

+	if ( i != -1 ) {lexmode(i); return;}

+	/* must make new one */

+	NumLexClasses++;

+	CurrentLexClass = NumLexClasses-1;

+	require(NumLexClasses<=MaxLexClasses, "number of allowable lexclasses exceeded\nIncrease MaxLexClasses in generic.h and recompile all C files");

+	lclass[CurrentLexClass].classnum = m;

+	lclass[CurrentLexClass].exprs = (char **) calloc(tsize, sizeof(char *));

+	require(lclass[CurrentLexClass].exprs!=NULL,

+			"lexclass: cannot allocate ExprStr");

+	lclass[CurrentLexClass].htable = newHashTable();

+	ExprStr = lclass[CurrentLexClass].exprs;

+	Texpr = lclass[CurrentLexClass].htable;

+	/* define EOF for each automaton */

+	p = newTermEntry( EOFSTR );

+	p->token = EofToken;	/* couldn't have remapped tokens yet, use EofToken */

+	hash_add(Texpr, EOFSTR, (Entry *)p);

+	list_add(&ExprOrder, (void *)newExpr(EOFSTR));

+	/* note: we use the actual ExprStr array

+	 * here as TokenInd doesn't exist yet

+	 */

+	ExprStr[EofToken] = EOFSTR;

+}

+

+void

+#ifdef __USE_PROTOS

+lexmode( int i )

+#else

+lexmode( i )

+int i;

+#endif

+{

+	require(i<NumLexClasses, "lexmode: invalid mode");

+	ExprStr = lclass[i].exprs;

+	Texpr = lclass[i].htable;

+	CurrentLexClass = i;

+}

+

+/* return index into lclass array of lexical class. return -1 if nonexistent */

+int

+#ifdef __USE_PROTOS

+LexClassIndex( char *cl )

+#else

+LexClassIndex( cl )

+char *cl;

+#endif

+{

+	int i;

+

+	for (i=0; i<NumLexClasses; i++)

+	{

+		if ( strcmp(lclass[i].classnum, cl) == 0 ) return i;

+	}

+	return -1;

+}

+

+int

+#ifdef __USE_PROTOS

+hasAction( char *expr )

+#else

+hasAction( expr )

+char *expr;

+#endif

+{

+	TermEntry *p;

+	require(expr!=NULL, "hasAction: invalid expr");

+

+	p = (TermEntry *) hash_get(Texpr, expr);

+	require(p!=NULL, eMsg1("hasAction: expr '%s' doesn't exist",expr));

+	return (p->action!=NULL);

+}

+

+void

+#ifdef __USE_PROTOS

+setHasAction( char *expr, char *action )

+#else

+setHasAction( expr, action )

+char *expr;

+char *action;

+#endif

+{

+	TermEntry *p;

+	require(expr!=NULL, "setHasAction: invalid expr");

+

+	p = (TermEntry *) hash_get(Texpr, expr);

+	require(p!=NULL, eMsg1("setHasAction: expr '%s' doesn't exist",expr));

+	p->action = action;

+}

+

+ForcedToken *

+#ifdef __USE_PROTOS

+newForcedToken(char *token, int tnum)

+#else

+newForcedToken(token, tnum)

+char *token;

+int tnum;

+#endif

+{

+	ForcedToken *ft = (ForcedToken *) calloc(1, sizeof(ForcedToken));

+	require(ft!=NULL, "out of memory");

+	ft->token = token;

+	ft->tnum = tnum;

+	return ft;

+}

+

+/*

+ * Make a token indirection array that remaps token numbers and then walk

+ * the appropriate symbol tables and SynDiag to change token numbers

+ */

+void

+#ifdef __USE_PROTOS

+RemapForcedTokens(void)

+#else

+RemapForcedTokens()

+#endif

+{

+	ListNode *p;

+	ForcedToken *q;

+	int max_token_number=0;     /* MR9 23-Sep-97 Removed "unsigned" */

+	int i;

+

+	if ( ForcedTokens == NULL ) return;

+

+	/* find max token num */

+	for (p = ForcedTokens->next; p!=NULL; p=p->next)

+	{

+		q = (ForcedToken *) p->elem;

+		if ( q->tnum > max_token_number ) max_token_number = q->tnum;

+	}

+	fprintf(stderr, "max token number is %d\n", max_token_number);

+

+	/* make token indirection array */

+	TokenInd = (int *) calloc(max_token_number+1, sizeof(int));

+	LastTokenCounted = TokenNum;

+	TokenNum = max_token_number+1;

+	require(TokenInd!=NULL, "RemapForcedTokens: cannot allocate TokenInd");

+

+	/* fill token indirection array and change token id htable ; swap token indices */

+	for (i=1; i<TokenNum; i++) TokenInd[i] = i;

+	for (p = ForcedTokens->next; p!=NULL; p=p->next)

+	{

+		TermEntry *te;

+		int old_pos, t;

+

+		q = (ForcedToken *) p->elem;

+		fprintf(stderr, "%s forced to %d\n", q->token, q->tnum);

+		te = (TermEntry *) hash_get(Tname, q->token);

+		require(te!=NULL, "RemapForcedTokens: token not in hash table");

+		old_pos = te->token;

+		fprintf(stderr, "Before: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);

+		fprintf(stderr, "Before: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);

+		q = (ForcedToken *) p->elem;

+		t = TokenInd[old_pos];

+		TokenInd[old_pos] = q->tnum;

+		TokenInd[q->tnum] = t;

+		te->token = q->tnum;		/* update token type id symbol table */

+		fprintf(stderr, "After: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);

+		fprintf(stderr, "After: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);

+

+		/* Change the token number in the sym tab entry for the exprs

+		 * at the old position of the token id and the target position

+		 */

+		/* update expr at target (if any) of forced token id */

+		if ( q->tnum < TokenNum )	/* is it a valid position? */

+		{

+			for (i=0; i<NumLexClasses; i++)

+			{

+				if ( lclass[i].exprs[q->tnum]!=NULL )

+				{

+					/* update the symbol table for this expr */

+					TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[q->tnum]);

+					require(e!=NULL, "RemapForcedTokens: expr not in hash table");

+					e->token = old_pos;

+					fprintf(stderr, "found expr '%s' at target %d in lclass[%d]; changed to %d\n",

+							lclass[i].exprs[q->tnum], q->tnum, i, old_pos);

+				}

+			}

+		}

+		/* update expr at old position (if any) of forced token id */

+		for (i=0; i<NumLexClasses; i++)

+		{

+			if ( lclass[i].exprs[old_pos]!=NULL )

+			{

+				/* update the symbol table for this expr */

+				TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[old_pos]);

+				require(e!=NULL, "RemapForcedTokens: expr not in hash table");

+				e->token = q->tnum;

+				fprintf(stderr, "found expr '%s' for id %s in lclass[%d]; changed to %d\n",

+						lclass[i].exprs[old_pos], q->token, i, q->tnum);

+			}

+		}

+	}

+

+	/* Update SynDiag */

+	RemapForcedTokensInSyntaxDiagram((Node *)SynDiag);

+}

+

+static void

+#ifdef __USE_PROTOS

+RemapForcedTokensInSyntaxDiagram(Node *p)

+#else

+RemapForcedTokensInSyntaxDiagram(p)

+Node *p;

+#endif

+{

+	Junction *j = (Junction *) p;

+	RuleRefNode *r = (RuleRefNode *) p;

+	TokNode *t = (TokNode *)p;

+

+	if ( p==NULL ) return;

+	require(p->ntype>=1 && p->ntype<=NumNodeTypes,	"Remap...: invalid diagram node");

+	switch ( p->ntype )

+	{

+		case nJunction :

+			if ( j->visited ) return;

+			if ( j->jtype == EndRule ) return;

+			j->visited = TRUE;

+			RemapForcedTokensInSyntaxDiagram( j->p1 );

+			RemapForcedTokensInSyntaxDiagram( j->p2 );

+			j->visited = FALSE;

+			return;

+		case nRuleRef :

+			RemapForcedTokensInSyntaxDiagram( r->next );

+			return;

+		case nToken :

+			if ( t->remapped ) return;	/* we've been here before */

+			t->remapped = 1;

+			fprintf(stderr, "remapping %d to %d\n", t->token, TokenInd[t->token]);

+			t->token = TokenInd[t->token];

+			RemapForcedTokensInSyntaxDiagram( t->next );

+			return;

+		case nAction :

+			RemapForcedTokensInSyntaxDiagram( ((ActionNode *)p)->next );

+			return;

+		default :

+			fatal_internal("invalid node type");

+	}

+}

+

+/*

+ * Add a token name.  Return the token number associated with it.  If it already

+ * exists, then return the token number assigned to it.

+ *

+ * Track the order in which tokens are found so that the DLG output maintains

+ * that order.  It also lets us map token numbers to strings.

+ */

+int

+#ifdef __USE_PROTOS

+addTname( char *token )

+#else

+addTname( token )

+char *token;

+#endif

+{

+	TermEntry *p;

+	require(token!=NULL, "addTname: invalid token name");

+

+	if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;

+	p = newTermEntry( token );

+	Ttrack( p->str );

+	p->token = TokenNum++;

+	hash_add(Tname, token, (Entry *)p);

+	return p->token;

+}

+

+/* This is the same as addTname except we force the TokenNum to be tnum.

+ * We don't have to use the Forced token stuff as no tokens will have

+ * been defined with #tokens when this is called.  This is only called

+ * when a #tokdefs meta-op is used.

+ */

+int

+#ifdef __USE_PROTOS

+addForcedTname( char *token, int tnum )

+#else

+addForcedTname( token, tnum )

+char *token;

+int tnum;

+#endif

+{

+	TermEntry *p;

+	require(token!=NULL, "addTname: invalid token name");

+

+	if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;

+	p = newTermEntry( token );

+	Ttrack( p->str );

+	p->token = tnum;

+	hash_add(Tname, token, (Entry *)p);

+	return p->token;

+}

+

+/*

+ * Add a token expr.  Return the token number associated with it.  If it already

+ * exists, then return the token number assigned to it.

+ */

+int

+#ifdef __USE_PROTOS

+addTexpr( char *expr )

+#else

+addTexpr( expr )

+char *expr;

+#endif

+{

+	TermEntry *p;

+	require(expr!=NULL, "addTexpr: invalid regular expression");

+

+	if ( (p=(TermEntry *)hash_get(Texpr, expr)) != NULL ) return p->token;

+	p = newTermEntry( expr );

+	Ttrack( p->str );

+	/* track the order in which they occur */

+	list_add(&ExprOrder, (void *)newExpr(p->str));

+	p->token = TokenNum++;

+	hash_add(Texpr, expr, (Entry *)p);

+	return p->token;

+}

+

+/* return the token number of 'term'.  Return 0 if no 'term' exists */

+int

+#ifdef __USE_PROTOS

+Tnum( char *term )

+#else

+Tnum( term )

+char *term;

+#endif

+{

+	TermEntry *p;

+	require(term!=NULL, "Tnum: invalid terminal");

+	

+	if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term);

+	else p = (TermEntry *) hash_get(Tname, term);

+	if ( p == NULL ) return 0;

+	else return p->token;

+}

+

+/* associate a Name with an expr.  If both have been already assigned

+ * token numbers, then an error is reported.  Add the token or expr

+ * that has not been added if no error.  This 'represents' the #token

+ * ANTLR pseudo-op.  If both have not been defined, define them both

+ * linked to same token number.

+ */

+void

+#ifdef __USE_PROTOS

+Tklink( char *token, char *expr )

+#else

+Tklink( token, expr )

+char *token;

+char *expr;

+#endif

+{

+	TermEntry *p, *q;

+	require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr");

+

+	p = (TermEntry *) hash_get(Tname, token);

+	q = (TermEntry *) hash_get(Texpr, expr);

+	if ( p != NULL && q != NULL )	/* both defined */

+	{

+		warn( eMsg2("token name %s and rexpr %s already defined; ignored",

+					token, expr) );

+		return;

+	}

+	if ( p==NULL && q==NULL )		/* both not defined */

+	{

+		int t = addTname( token );

+		q = newTermEntry( expr );

+		hash_add(Texpr, expr, (Entry *)q);

+		q->token = t;

+		/* note: we use the actual ExprStr array

+		 * here as TokenInd doesn't exist yet

+		 */

+		ExprStr[t] = q->str;

+		/* track the order in which they occur */

+		list_add(&ExprOrder, (void *)newExpr(q->str));

+		return;

+	}

+	if ( p != NULL )				/* one is defined, one is not */

+	{

+		q = newTermEntry( expr );

+		hash_add(Texpr, expr, (Entry *)q);

+		q->token = p->token;

+		ExprStr[p->token] = q->str;	/* both expr and token str defined now */

+		list_add(&ExprOrder, (void *)newExpr(q->str));

+	}

+	else							/* trying to associate name with expr here*/

+	{

+		p = newTermEntry( token );

+		hash_add(Tname, token, (Entry *)p);

+		p->token = q->token;

+		TokenStr[p->token] = p->str;/* both expr and token str defined now */

+	}

+}

+

+/*

+ * Given a string, this function allocates and returns a pointer to a

+ * hash table record of size 'sz' whose "str" pointer is reset to a position

+ * in the string table.

+ */

+Entry *

+#ifdef __USE_PROTOS

+newEntry( char *text, int sz )

+#else

+newEntry( text, sz )

+char *text;

+int sz;

+#endif

+{

+	Entry *p;

+	require(text!=NULL, "new: NULL terminal");

+	

+	if ( (p = (Entry *) calloc(1,sz)) == 0 )

+	{

+		fatal_internal("newEntry: out of memory for terminals\n");

+		exit(PCCTS_EXIT_FAILURE);

+	}

+	p->str = mystrdup(text);

+	

+	return(p);

+}

+

+/*

+ * add an element to a list.

+ *

+ * Any non-empty list has a sentinel node whose 'elem' pointer is really

+ * a pointer to the last element.  (i.e. length(list) = #elemIn(list)+1).

+ * Elements are appended to the list.

+ */

+void

+#ifdef __USE_PROTOS

+list_add( ListNode **list, void *e )

+#else

+list_add( list, e )

+ListNode **list;

+void *e;

+#endif

+{

+	ListNode *p, *tail;

+	require(e!=NULL, "list_add: attempting to add NULL list element");

+

+	p = newListNode;

+	require(p!=NULL, "list_add: cannot alloc new list node");

+	p->elem = e;

+	if ( *list == NULL )

+	{

+		ListNode *sentinel = newListNode;

+		require(sentinel!=NULL, "list_add: cannot alloc sentinel node");

+		*list=sentinel;

+		sentinel->next = p;

+		sentinel->elem = (char *)p;		/* set tail pointer */

+	}

+	else								/* find end of list */

+	{

+		tail = (ListNode *) (*list)->elem;	/* get tail pointer */

+		tail->next = p;

+		(*list)->elem = (char *) p;		/* reset tail */

+	}

+}

+

+/* MR10 list_free() frees the ListNode elements in the list       */

+/* MR10   if freeData then free the data elements of the list too */

+

+void

+#ifdef __USE_PROTOS

+list_free(ListNode **list,int freeData)

+#else

+list_free(list,freeData)

+  ListNode      **list;

+  int           freeData;

+#endif

+{

+	ListNode *p;

+    ListNode *next;

+

+	if (list == NULL) return;

+    if (*list == NULL) return;

+	for (p=*list; p != NULL; p=next) {

+      next=p->next;

+      if (freeData && p->elem != NULL) {

+        free( (char *) p->elem);

+      };

+      free( (char *) p);

+    };

+    *list=NULL;

+}

+

+void

+#ifdef __USE_PROTOS

+list_apply( ListNode *list, void (*f)(void *) )

+#else

+list_apply( list, f )

+ListNode *list;

+void (*f)();

+#endif

+{

+	ListNode *p;

+	require(f!=NULL, "list_apply: NULL function to apply");

+

+	if ( list == NULL ) return;

+	for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem );

+}

+

+/* MR27 */

+

+#ifdef __USE_PROTOS

+int list_search_cstring(ListNode *list, char * cstring)

+#else

+int list_search_cstring(list, cstring)

+  ListNode * list;

+  char * cstring;

+#endif

+{

+	ListNode *p;

+	if (list == NULL ) return 0;

+	for (p = list->next; p!=NULL; p=p->next) {

+		if (p->elem == NULL) continue;

+		if (0 == strcmp((char *) p->elem , cstring)) return 1;

+	}

+	return 0;

+}

+

+			/* F O L L O W  C y c l e  S t u f f */

+		

+/* make a key based upon (rulename, computation, k value).

+ * Computation values are 'i'==FIRST, 'o'==FOLLOW.

+ */

+

+/* MR10  Make the key all characters so it can be read easily   */

+/* MR10    by a simple dump program.  Also, separates           */

+/* MR10   'o' and 'i' from rule name                            */

+

+char *

+#ifdef __USE_PROTOS

+Fkey( char *rule, int computation, int k )

+#else

+Fkey( rule, computation, k )

+char *rule;

+int computation;

+int k;

+#endif

+{

+	static char key[MaxRuleName+2+2+1];                                 /* MR10 */

+	int i;

+	

+	if ( k > 99 )                                                       /* MR10 */

+		fatal("k>99 is too big for this implementation of ANTLR!\n");   /* MR10 */

+	if ( (i=strlen(rule)) > MaxRuleName )                               /* MR10 */

+		fatal( eMsgd("rule name > max of %d\n", MaxRuleName) );         /* MR10 */

+	strcpy(key,rule);

+

+/* MR10 */     key[i]='*';

+/* MR10 */     key[i+1] = (char) computation; /* MR20 G. Hobbelt */

+/* MR10 */     if (k < 10) {

+/* MR10 */       key[i+2] = (char) ( '0' + k);

+/* MR10 */  	 key[i+3] = '\0';

+/* MR10 */     } else {

+/* MR10 */       key[i+2] = (char) ( '0' + k/10);

+/* MR10 */       key[i+3] = (char) ( '0' + k % 10);

+/* MR10 */       key[i+4] = '\0';

+/* MR10 */     };

+

+	return key;

+}

+

+/* Push a rule onto the kth FOLLOW stack */

+void

+#ifdef __USE_PROTOS

+FoPush( char *rule, int k )

+#else

+FoPush( rule, k )

+char *rule;

+int k;

+#endif

+{

+	RuleEntry *r;

+	require(rule!=NULL, "FoPush: tried to push NULL rule");

+	require(k<=CLL_k,	"FoPush: tried to access non-existent stack");

+

+	/*fprintf(stderr, "FoPush(%s)\n", rule);*/

+	r = (RuleEntry *) hash_get(Rname, rule);

+	if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );}

+	if ( FoStack[k] == NULL )		/* Does the kth stack exist yet? */

+	{

+		/*fprintf(stderr, "allocating FoStack\n");*/

+		FoStack[k] = (int *) calloc(FoStackSize, sizeof(int));

+		require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n");

+	}

+	if ( FoTOS[k] == NULL )

+	{

+		FoTOS[k]=FoStack[k];

+		*(FoTOS[k]) = r->rulenum;

+	}

+	else

+	{

+#ifdef MEMCHK

+		require(valid(FoStack[k]), "FoPush: invalid FoStack");

+#endif

+		if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) )

+			fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n",

+						FoStackSize) );

+		require(FoTOS[k]>=FoStack[k],

+				eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox",

+					  rule));

+		++(FoTOS[k]);

+		*(FoTOS[k]) = r->rulenum;

+	}

+	{

+		/*

+****		int *p;

+****		fprintf(stderr, "FoStack[k=%d]:\n", k);

+****		for (p=FoStack[k]; p<=FoTOS[k]; p++)

+****		{

+****			fprintf(stderr, "\t%s\n", RulePtr[*p]->rname);

+****		}

+		*/

+	}

+}

+

+/* Pop one rule off of the FOLLOW stack.  TOS ptr is NULL if empty. */

+void

+#ifdef __USE_PROTOS

+FoPop( int k )

+#else

+FoPop( k )

+int k;

+#endif

+{

+	require(k<=CLL_k, "FoPop: tried to access non-existent stack");

+	/*fprintf(stderr, "FoPop\n");*/

+	require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),

+			"FoPop: FoStack stack-ptr is playing out of its sandbox");

+	if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL;

+	else (FoTOS[k])--;

+}

+

+/* Compute FOLLOW cycle.

+ * Mark all FOLLOW sets for rules in cycle as incomplete.

+ * Then, save cycle on the cycle list (Cycles) for later resolution.

+ * The Cycle is stored in the form:

+ *		(head of cycle==croot, rest of rules in cycle==cyclicDep)

+ *

+ * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on)

+ *

+ *		Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x)

+ *										   ^----Infinite recursion (cycle)

+ *

+ * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}).  Fo(x) depends

+ * on the FOLLOW of a,b, and c.  The root of a cycle is always complete after

+ * Fo(x) finishes.  Fo(a,b,c) however are not.  It turns out that all rules

+ * in a FOLLOW cycle have the same FOLLOW set.

+ */

+void

+#ifdef __USE_PROTOS

+RegisterCycle( char *rule, int k )

+#else

+RegisterCycle( rule, k )

+char *rule;

+int k;

+#endif

+{

+	CacheEntry *f;

+	Cycle *c;

+	int *p;

+	RuleEntry *r;

+	require(rule!=NULL, "RegisterCycle: tried to register NULL rule");

+	require(k<=CLL_k,	"RegisterCycle: tried to access non-existent stack");

+

+	/*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/

+	/* Find cycle start */

+	r = (RuleEntry *) hash_get(Rname, rule);

+	require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule));

+	require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),

+			eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox",

+				  rule));

+/***	if ( FoTOS[k]<FoStack[k]||FoTOS[k]>&(FoStack[k][FoStackSize-1]) )

+****	{

+****		fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n",

+****						rule);

+****		fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n",

+****						FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1]));

+****		exit(PCCTS_EXIT_FAILURE);

+****	}

+****/

+

+#ifdef MEMCHK

+	require(valid(FoStack[k]), "RegisterCycle: invalid FoStack");

+#endif

+	for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;}

+	require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief");

+	if ( p == FoTOS[k] ) return;	/* don't worry about cycles to oneself */

+	

+	/* compute cyclic dependents (rules in cycle except head) */

+	c = newCycle;

+	require(c!=NULL, "RegisterCycle: couldn't alloc new cycle");

+	c->cyclicDep = empty;

+	c->croot = *p++;		/* record root of cycle */

+	for (; p<=FoTOS[k]; p++)

+	{

+		/* Mark all dependent rules as incomplete */

+		f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k));

+		if ( f==NULL )

+		{

+			f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) );

+			hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f);

+		}

+		f->incomplete = TRUE;

+		

+		set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */

+	}

+	list_add(&(Cycles[k]), (void *)c);

+}

+

+/* make all rules in cycle complete

+ *

+ * while ( some set has changed ) do

+ *		for each cycle do

+ *			if degree of FOLLOW set for croot > old degree then

+ *				update all FOLLOW sets for rules in cyclic dependency

+ *				change = TRUE

+ *			endif

+ *		endfor

+ * endwhile

+ */

+void

+#ifdef __USE_PROTOS

+ResolveFoCycles( int k )

+#else

+ResolveFoCycles( k )

+int k;

+#endif

+{

+	ListNode *p, *q;

+	Cycle *c;

+	int changed = 1;

+	CacheEntry *f,*g;

+	int r;

+/*  int i;  */  /* MR10 not useful */

+	unsigned d;

+

+    unsigned    *cursor;        /* MR10 */

+    unsigned    *origin;        /* MR10 */

+	

+	/*fprintf(stderr, "Resolving following cycles for %d\n", k);*/

+	while ( changed )

+	{

+		changed = 0;

+/* MR10 i = 0;  */

+		for (p = Cycles[k]->next; p!=NULL; p=p->next)

+		{

+			c = (Cycle *) p->elem;

+			/*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/

+			/*s_fprT(stderr, c->cyclicDep);*/

+			/*fprintf(stderr, "\n");*/

+			f = (CacheEntry *)

+					hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k));

+			require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) );

+			if ( (d=set_deg(f->fset)) > c->deg )

+			{

+				/*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/

+				changed = 1;

+				c->deg = d;		/* update cycle FOLLOW set degree */

+

+/* MR10 */      origin=set_pdq(c->cyclicDep);

+/* MR10 */      for (cursor=origin; *cursor != nil; cursor++) {

+/* MR10 */         r=*cursor;

+

+/********		while ( !set_nil(c->cyclicDep) ) {      *****/

+/********					r = set_int(c->cyclicDep);  *****/

+/********					set_rm(r, c->cyclicDep);    *****/

+

+					/*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/

+					g = (CacheEntry *)

+							hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k));

+					require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) );

+					set_orin(&(g->fset), f->fset);

+					g->incomplete = FALSE;

+				}

+/* MR10 */      free( (char *) origin);

+/* MR10 */      origin=NULL;

+			}

+		}

+/* MR10 - this if statement appears to be meaningless since i is always 0 */

+/* MR10		if ( i == 1 ) changed = 0;	*/ /* if only 1 cycle, no need to repeat */

+	}

+	/* kill Cycle list */

+	for (q = Cycles[k]->next; q != NULL; q=p)

+	{

+		p = q->next;

+		set_free( ((Cycle *)q->elem)->cyclicDep );

+		free((char *)q);

+	}

+	free( (char *)Cycles[k] );

+	Cycles[k] = NULL;

+}

+

+

+			/* P r i n t i n g  S y n t a x  D i a g r a m s */

+

+static void

+#ifdef __USE_PROTOS

+pBlk( Junction *q, int btype )

+#else

+pBlk( q, btype )

+Junction *q;

+int btype;

+#endif

+{

+	int k,a;

+	Junction *alt, *p;

+

+	q->end->pvisited = TRUE;

+	if ( btype == aLoopBegin )

+	{

+		require(q->p2!=NULL, "pBlk: invalid ()* block");

+		PRINT(q->p1);

+		alt = (Junction *)q->p2;

+		PRINT(alt->p1);

+		if ( PrintAnnotate )

+		{

+			printf(" /* Opt ");

+			k = 1;

+			while ( !set_nil(alt->fset[k]) )

+			{

+				s_fprT(stdout, alt->fset[k]);

+				if ( k++ == CLL_k ) break;

+				if ( !set_nil(alt->fset[k]) ) printf(", ");

+			}

+			printf(" */\n");

+		}

+		return;

+	}

+	for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++)

+	{

+		if ( alt->p1 != NULL ) PRINT(alt->p1);

+		if ( PrintAnnotate )

+		{

+			printf( " /* [%d] ", alt->altnum);

+			k = 1;

+			while ( !set_nil(alt->fset[k]) )

+			{

+				s_fprT(stdout, alt->fset[k]);

+				if ( k++ == CLL_k ) break;

+				if ( !set_nil(alt->fset[k]) ) printf(", ");

+			}

+			if ( alt->p2 == NULL && btype == aOptBlk )

+				printf( " (optional branch) */\n");

+			else printf( " */\n");

+		}

+

+		/* ignore implied empty alt of Plus blocks */

+		if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break;

+

+		if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) )

+		{

+			if ( pLevel == 1 )

+			{

+				printf("\n");

+				if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>");

+				printf("\t");

+			}

+			else printf(" ");

+			printf("|");

+			if ( pLevel == 1 )

+			{

+				p = (Junction *) ((Junction *)alt->p2)->p1;

+				while ( p!=NULL )

+				{

+					if ( p->ntype==nAction )

+					{

+						p=(Junction *)((ActionNode *)p)->next;

+						continue;

+					}

+					if ( p->ntype!=nJunction )

+					{

+						break;

+					}

+					if ( p->jtype==EndBlk || p->jtype==EndRule )

+					{

+						p = NULL;

+						break;

+					}

+					p = (Junction *)p->p1;

+				}

+				if ( p==NULL ) printf("\n\t");	/* Empty alt? */

+			}

+		}

+	}

+	q->end->pvisited = FALSE;

+}

+

+/* How to print out a junction */

+void

+#ifdef __USE_PROTOS

+pJunc( Junction *q )

+#else

+pJunc( q )

+Junction *q;

+#endif

+{

+	int dum_k;

+	int doing_rule;

+	require(q!=NULL, "pJunc: NULL node");

+	require(q->ntype==nJunction, "pJunc: not junction");

+	

+	if ( q->pvisited == TRUE ) return;

+	q->pvisited = TRUE;

+	switch ( q->jtype )

+	{

+		case aSubBlk :

+			if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);

+			if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction &&

+				 ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1;

+			else doing_rule = 0;

+			pLevel++;

+			if ( pLevel==1 )

+			{

+				if ( pAlt1==1 ) printf("=>");

+				printf("\t");

+			}

+			else printf(" ");

+			if ( doing_rule )

+			{

+				if ( pLevel==1 ) printf(" ");

+				pBlk(q,q->jtype);

+			}

+			else {

+				printf("(");

+				if ( pLevel==1 ) printf(" ");

+				pBlk(q,q->jtype);

+				if ( pLevel>1 ) printf(" ");

+				printf(")");

+			}

+			if ( q->guess ) printf("?");

+			pLevel--;

+			if ( PrintAnnotate ) freeBlkFsets(q);

+			if ( q->end->p1 != NULL ) PRINT(q->end->p1);

+			break;

+		case aOptBlk :

+			if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);

+			pLevel++;

+			if ( pLevel==1 )

+			{

+				if ( pAlt1==1 ) printf("=>");

+				printf("\t");

+			}

+			else printf(" ");

+			printf("{");

+			if ( pLevel==1 ) printf(" ");

+			pBlk(q,q->jtype);

+			if ( pLevel>1 ) printf(" ");

+			else printf("\n\t");

+			printf("}");

+			pLevel--;

+			if ( PrintAnnotate ) freeBlkFsets(q);

+			if ( q->end->p1 != NULL ) PRINT(q->end->p1);

+			break;

+		case aLoopBegin :

+			if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);

+			pLevel++;

+			if ( pLevel==1 )

+			{

+				if ( pAlt1==1 ) printf("=>");

+				printf("\t");

+			}

+			else printf(" ");

+			printf("(");

+			if ( pLevel==1 ) printf(" ");

+			pBlk(q,q->jtype);

+			if ( pLevel>1 ) printf(" ");

+			else printf("\n\t");

+			printf(")*");

+			pLevel--;

+			if ( PrintAnnotate ) freeBlkFsets(q);

+			if ( q->end->p1 != NULL ) PRINT(q->end->p1);

+			break;

+		case aLoopBlk :

+			if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);

+			pBlk(q,q->jtype);

+			if ( PrintAnnotate ) freeBlkFsets(q);

+			break;

+		case aPlusBlk :

+			if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);

+			pLevel++;

+			if ( pLevel==1 )

+			{

+				if ( pAlt1==1 ) printf("=>");

+				printf("\t");

+			}

+			else printf(" ");

+			printf("(");

+			if ( pLevel==1 ) printf(" ");

+			pBlk(q,q->jtype);

+			if ( pLevel>1 ) printf(" ");

+			printf(")+");

+			pLevel--;

+			if ( PrintAnnotate ) freeBlkFsets(q);

+			if ( q->end->p1 != NULL ) PRINT(q->end->p1);

+			break;

+		case EndBlk :

+			break;

+		case RuleBlk :

+			printf( "\n%s :\n", q->rname);

+			PRINT(q->p1);

+			if ( q->p2 != NULL ) PRINT(q->p2);

+			break;

+		case Generic :

+			if ( q->p1 != NULL ) PRINT(q->p1);

+			q->pvisited = FALSE;

+			if ( q->p2 != NULL ) PRINT(q->p2);

+			break;

+		case EndRule :

+			printf( "\n\t;\n");

+			break;

+	}

+	q->pvisited = FALSE;

+}

+

+/* How to print out a rule reference node */

+void

+#ifdef __USE_PROTOS

+pRuleRef( RuleRefNode *p )

+#else

+pRuleRef( p )

+RuleRefNode *p;

+#endif

+{

+	require(p!=NULL, "pRuleRef: NULL node");

+	require(p->ntype==nRuleRef, "pRuleRef: not rule ref node");

+	

+	printf( " %s", p->text);

+	PRINT(p->next);

+}

+

+/* How to print out a terminal node */

+void

+#ifdef __USE_PROTOS

+pToken( TokNode *p )

+#else

+pToken( p )

+TokNode *p;

+#endif

+{

+	require(p!=NULL, "pToken: NULL node");

+	require(p->ntype==nToken, "pToken: not token node");

+

+	if ( p->wild_card ) printf(" .");

+	printf( " %s", TerminalString(p->token));

+	PRINT(p->next);

+}

+

+/* How to print out a terminal node */

+void

+#ifdef __USE_PROTOS

+pAction( ActionNode *p )

+#else

+pAction( p )

+ActionNode *p;

+#endif

+{

+	require(p!=NULL, "pAction: NULL node");

+	require(p->ntype==nAction, "pAction: not action node");

+	

+	PRINT(p->next);

+}

+

+					/* F i l l  F o l l o w  L i s t s */

+

+/*

+ * Search all rules for all rule reference nodes, q to rule, r.

+ * Add q->next to follow list dangling off of rule r.

+ * i.e.

+ *

+ *		r: -o-R-o-->o--> Ptr to node following rule r in another rule

+ *					|

+ *					o--> Ptr to node following another reference to r.

+ *

+ * This is the data structure employed to avoid FOLLOW set computation.  We

+ * simply compute the FIRST (reach) of the EndRule Node which follows the

+ * list found at the end of all rules which are referenced elsewhere.  Rules

+ * not invoked by other rules have no follow list (r->end->p1==NULL).

+ * Generally, only start symbols are not invoked by another rule.

+ *

+ * Note that this mechanism also gives a free cross-reference mechanism.

+ *

+ * The entire syntax diagram is layed out like this:

+ *

+ * SynDiag

+ *	|

+ *	v

+ *	o-->R1--o

+ *	|

+ *	o-->R2--o

+ *	|

+ *	...

+ *	|

+ *	o-->Rn--o

+ *

+ */

+void

+#ifdef __USE_PROTOS

+FoLink( Node *p )

+#else

+FoLink( p )

+Node *p;

+#endif

+{

+	RuleEntry *q;

+	Junction *j = (Junction *) p;

+	RuleRefNode *r = (RuleRefNode *) p;

+

+	if ( p==NULL ) return;

+	require(p->ntype>=1 && p->ntype<=NumNodeTypes,

+			eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype));

+	switch ( p->ntype )

+	{

+		case nJunction :

+			if ( j->fvisited ) return;

+			if ( j->jtype == EndRule ) return;

+			j->fvisited = TRUE;

+			FoLink( j->p1 );

+			FoLink( j->p2 );

+/* MR14 */

+/* MR14 */  /* Need to determine whether the guess block is an         */

+/* MR14 */  /* of the form (alpha)? beta before follow sets are        */

+/* MR14 */  /* computed.  This is necessary to solve problem           */

+/* MR14 */  /* of doing follow on the alpha of an (alpha)? beta block. */

+/* MR14 */

+/* MR14 */  /* This is performed by analysis_point as a side-effect.   */

+/* MR14 */

+/* MR14 */

+/* MR14 */  if (j->jtype == aSubBlk && j->guess) {

+/* MR14 */    Junction *ignore;

+/* MR14 */    ignore=analysis_point(j);

+/* MR14 */  }

+/* MR14 */

+			return;

+		case nRuleRef :

+			if ( r->linked ) return;

+			q = (RuleEntry *) hash_get(Rname, r->text);

+			if ( q == NULL )

+			{

+				warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line );

+			}

+			else

+			{

+				if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL )

+				{

+					warnFL( eMsg1("rule %s accepts no parameter(s)", r->text),

+							FileStr[r->file], r->line );

+				}

+				if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL )

+				{

+					warnFL( eMsg1("rule %s requires parameter(s)", r->text),

+							FileStr[r->file], r->line );

+				}

+				if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL )

+				{

+					warnFL( eMsg1("rule %s yields no return value(s)", r->text),

+							FileStr[r->file], r->line );

+				}

+				if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL )

+				{

+					warnFL( eMsg1("rule %s returns a value(s)", r->text),

+							FileStr[r->file], r->line );

+				}

+				if ( !r->linked )

+				{

+					addFoLink(	r->next, r->rname, RulePtr[q->rulenum] );

+					r->linked = TRUE;

+				}

+			}

+			FoLink( r->next );

+			return;

+		case nToken :

+			FoLink( ((TokNode *)p)->next );

+			return;

+		case nAction :

+			FoLink( ((ActionNode *)p)->next );

+			return;

+		default :

+			fatal_internal("invalid node type");

+	}

+}

+

+/*

+ * Add a reference to the end of a rule.

+ *

+ * 'r' points to the RuleBlk node in a rule.  r->end points to the last node

+ * (EndRule jtype) in a rule.

+ *

+ * Initial:

+ *		r->end --> 	o

+ *

+ * After:

+ *		r->end --> 	o-->o--> Ptr to node following rule r in another rule

+ *						|

+ *						o--> Ptr to node following another reference to r.

+ *

+ * Note that the links are added to the head of the list so that r->end->p1

+ * always points to the most recently added follow-link.  At the end, it should

+ * point to the last reference found in the grammar (starting from the 1st rule).

+ */

+void

+#ifdef __USE_PROTOS

+addFoLink( Node *p, char *rname, Junction *r )

+#else

+addFoLink( p, rname, r )

+Node *p;

+char *rname;

+Junction *r;

+#endif

+{

+	Junction *j;

+	require(r!=NULL,				"addFoLink: incorrect rule graph");

+	require(r->end!=NULL,			"addFoLink: incorrect rule graph");

+	require(r->end->jtype==EndRule,	"addFoLink: incorrect rule graph");

+	require(p!=NULL,				"addFoLink: NULL FOLLOW link");

+

+	j = newJunction();

+	j->rname = rname;			/* rname on follow links point to target rule */

+	j->p1 = p;					/* link to other rule */

+	j->p2 = (Node *) r->end->p1;/* point to head of list */

+	r->end->p1 = (Node *) j;	/* reset head to point to new node */

+}

+

+void

+#ifdef __USE_PROTOS

+GenCrossRef( Junction *p )

+#else

+GenCrossRef( p )

+Junction *p;

+#endif

+{

+	set a;

+	Junction *j;

+	RuleEntry *q;

+	unsigned e;

+	require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?");

+

+	printf("Cross Reference:\n\n");

+	a = empty;

+	for (; p!=NULL; p = (Junction *)p->p2)

+	{

+		printf("Rule %20s referenced by {", p->rname);

+		/* make a set of rules for uniqueness */

+		for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2)

+		{

+			q = (RuleEntry *) hash_get(Rname, j->rname);

+			require(q!=NULL, "GenCrossRef: FoLinks are screwed up");

+			set_orel(q->rulenum, &a);

+		}

+		for (; !set_nil(a); set_rm(e, a))

+		{

+			e = set_int(a);

+			printf(" %s", RulePtr[e]->rname);

+		}

+		printf(" }\n");

+	}

+	set_free( a );

+}

+

+/*

+   The single argument is a pointer to the start of an element of a

+   C++ style function prototypet list.  Given a pointer to the start of

+   an formal we must locate the comma (or the end of the string)

+   and locate the datatype, formal name, and initial value expression.

+

+   The function returns a pointer to the character following the comma

+   which terminates the formal declaration, or a pointer to the end of

+   the string if none was found.

+

+   I thought we were parsing specialists, how come I'm doing this by

+   hand written code ?

+

+   Examples of input:

+ 

+        Foo f,

+        Foo f = Foo(1),

+        Foo f = Foo(1,2),

+        Foo f = &farray[1,2],

+        Foo f = ",",

+        Foo f = ',',

+        TFoo<int,char> f = TFoo<int,char>(1,2),

+

+   A non-zero value for nesting indicates a problem matching '(' and ')',

+   '[' and ']', '<' and '>', '{' and '}', or improperly terminated string

+   or character literal.

+

+*/

+

+

+/*

+ *  Don't care if it is a valid string literal or not, just find the end

+ *  Start with pointer to leading "\""

+ */

+

+#ifdef __USE_PROTOS

+char * skipStringLiteral(char *pCurrent)

+#else

+char * skipStringLiteral(pCurrent)

+char *pCurrent;

+#endif

+{

+  char *p = pCurrent;

+  if (*p == 0) return p;

+  require (*p == '\"', "skipStringLiteral")

+  p++;

+  for (p = p; *p != 0; p++) {

+    if (*p == '\\') {

+      p++;

+      if (*p == 0) break;

+      p++;

+    }

+    if (*p == '\"') {

+      p++;

+      break;

+    }

+  }

+  return p;

+}

+

+/*

+ *  Don't care if it is a valid character literal or not, just find the end

+ *  Start with pointer to leading "'"

+ */

+

+#ifdef __USE_PROTOS

+char * skipCharLiteral(char *pStart)

+#else

+char * skipCharLiteral(pStart)

+ char *pStart;

+#endif

+{

+  char *p = pStart;

+  if (*p == 0) return p;

+  require (*p == '\'', "skipCharLiteral")

+  p++;

+  for (p = p; *p != 0; p++) {

+    if (*p == '\\') {

+      p++;

+      if (*p == 0) break;

+      p++;

+    }

+    if (*p == '\'') {

+      p++;

+      break;

+    }

+  }

+  return p;

+}

+

+#ifdef __USE_PROTOS

+char * skipSpaces(char *pStart)

+#else

+char * skipSpaces(pStart)

+char * pStart;

+#endif

+{

+  char *p = pStart;

+  while (*p != 0 && isspace(*p)) p++;

+  return p;

+}

+

+#ifdef __USE_PROTOS

+char * skipToSeparatorOrEqualSign(char *pStart, int *pNest)

+#else

+char * skipToSeparatorOrEqualSign(pStart, pNest)

+char *pStart;

+int *pNest;

+#endif

+{

+  char *p = pStart;

+  

+  int nest = 0;

+

+  *pNest = (-1);

+

+  while (*p != 0) {

+    switch (*p) {

+

+      case '(' :

+      case '[' :

+      case '<' :

+      case '{' :

+        nest++;

+        p++;

+        break;

+

+      case ')' :

+      case ']' :

+      case '>' :

+      case '}' :

+        nest--;

+        p++;

+        break;

+      

+      case '"' :

+        p = skipStringLiteral(p);

+        break;

+  

+      case '\'' :

+        p = skipCharLiteral(p);

+        break;

+

+      case '\\':

+        p++;

+        if (*p == 0) goto EXIT;

+        p++;

+        break;

+

+      case ',':

+      case '=':

+        if (nest == 0) goto EXIT;

+		p++;

+        break;

+

+      default:

+        p++;

+    }

+  }

+EXIT:

+  *pNest = nest;

+  return p;

+}

+

+#ifdef __USE_PROTOS

+char * skipToSeparator(char *pStart, int *pNest)

+#else

+char * skipToSeparator(pStart, pNest)

+char *pStart;

+int *pNest;

+#endif

+{

+  char * p = pStart;

+  for ( ; ; ) {

+    p = skipToSeparatorOrEqualSign(p, pNest);

+    if (*pNest != 0) return p;

+    if (*p == ',') return p;

+    if (*p == 0) return p;

+	p++;

+  }

+}

+

+/* skip to just past the "=" separating the declaration from the initialization value */

+

+#ifdef __USE_PROTOS

+char * getInitializer(char *pStart)

+#else

+char * getInitializer(pStart)

+char * pStart;

+#endif

+{

+	char *p;

+	char *pDataType;

+	char *pSymbol;

+	char *pEqualSign;

+	char *pValue;

+	char *pSeparator;

+	int nest = 0;

+

+	require(pStart!=NULL, "getInitializer: invalid string"); 

+

+	p = endFormal(pStart,

+			      &pDataType,

+				  &pSymbol,

+				  &pEqualSign,

+				  &pValue,

+				  &pSeparator,

+				  &nest);

+    if (nest != 0) return NULL;

+    if (pEqualSign == NULL) return NULL;

+    if (pValue == NULL) return NULL;

+	return strBetween(pValue, NULL, pSeparator);

+}

+

+/*

+   Examines the string from pStart to pEnd-1.

+   If the string has 0 length or is entirely white space

+   returns 1.  Otherwise 0.

+*/

+

+#ifdef __USE_PROTOS

+int isWhiteString(const char *pStart, const char *pEnd)

+#else

+int isWhiteString(pStart, pEnd)

+const char *pStart;

+const char *pEnd;

+#endif

+{

+  const char *p;

+  for (p = pStart; p < pEnd; p++) {

+    if (! isspace(*p)) return 0;

+  }

+  return 1;

+}

+

+/*

+   This replaces HasComma() which couldn't distinguish

+

+        foo ["a,b"]

+

+   from:

+

+        foo[a,b]

+

+*/

+

+#ifdef __USE_PROTOS

+int hasMultipleOperands(char *pStart)

+#else

+int hasMultipleOperands(pStart)

+char *pStart;

+#endif

+{

+  char *p = pStart;

+  int nest = 0;

+

+  p = skipSpaces(p);

+  if (*p == 0) return 0;

+  p = skipToSeparator(p, &nest);

+  if (nest == 0 && *p == ',') return 1;

+  return 0;

+}

+

+

+#define MAX_STR_BETWEEN_WORK_AREA 1000

+

+static char strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA];

+

+

+/*

+	strBetween(pStart, pNext, pStop)

+

+    Creates a null terminated string by copying the text between two pointers

+	to a work area.  The start of the string is pStart.  The end of the string

+	is the character before pNext, or if pNext is null then the character before

+	pStop.  Trailing spaces are not included in the copy operation.

+	

+	This is used when a string contains several parts.  The pNext part may be

+	optional.  The pStop will stop the scan when the optional part is not present

+	(is a null pointer).

+*/

+

+#ifdef __USE_PROTOS

+char *strBetween(char *pStart, char *pNext, char *pStop)

+#else

+char *strBetween(pStart, pNext, pStop)

+char *pStart;

+char *pNext;

+char *pStop;

+#endif

+{

+  char *p;

+  char *q = strBetweenWorkArea;

+  const char *pEnd;

+

+  pEnd = (pNext != NULL) ? pNext : pStop;

+

+  require (pEnd != NULL, "pEnd == NULL");

+  require (pEnd >= pStart, "pEnd < pStart");

+  for (pEnd--; pEnd >= pStart; pEnd--) { /* MR31 */

+	if (! isspace(*pEnd)) break;

+  }

+  for (p = pStart;

+       p <= pEnd && q < &strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA-2];

+	   p++, q++) {

+	 *q = *p;

+  }

+  *q = 0;

+  return strBetweenWorkArea;

+}

+

+/*

+   function     Returns pointer to character following separator at

+   value        which to continue search for next formal.  If at the

+                end of the string a pointer to the null byte at the

+                end of the string is returned.

+

+   pStart       Pointer to the starting position of the formal list

+

+                This may be the middle of a longer string, for example

+                when looking for the end of formal #3 starting from

+                the middle of the complete formal list.

+

+   ppDataType   Returns a pointer to the start of the data type in the

+                formal. Example: pointer to "Foo".

+

+   ppSymbol     Returns a pointer to the start of the formal symbol.

+                Example: pointer to "f".

+

+   ppEqualSign  Returns a pointer to the equal sign separating the

+                formal symbol from the initial value.  If there is 

+                no "=" then this will be NULL.

+

+   ppValue      Returns a pointer to the initial value part of the

+                formal declaration.  Example: pointer to "&farray[1,2]"

+

+   ppSeparator  Returns a pointer to the character which terminated the

+                scan.  This should be a pointer to a comma or a null

+                byte which terminates the string.

+

+   pNest        Returns the nesting level when a separator was found.

+                This is non-zero for any kind of error.  This is zero

+                for a successful parse of this portion of the formal

+                list.

+

+*/ 

+ 

+#ifdef __USE_PROTOS

+char * endFormal(char *pStart,

+                 char **ppDataType,

+                 char **ppSymbol,

+                 char **ppEqualSign,

+                 char **ppValue,

+                 char **ppSeparator,

+                 int *pNest)

+#else

+char * endFormal(pStart,

+			     ppDataType,

+				 ppSymbol,

+				 ppEqualSign,

+				 ppValue,

+				 ppSeparator,

+				 pNest)

+char *pStart;

+char **ppDataType;

+char **ppSymbol;

+char **ppEqualSign;

+char **ppValue;

+char **ppSeparator;

+int *pNest;

+

+#endif

+{

+  char *p = pStart;

+  char *q;

+

+  *ppDataType = NULL;

+  *ppSymbol = NULL;

+  *ppEqualSign = NULL;

+  *ppValue = NULL;

+  *ppSeparator = NULL;

+

+  *pNest = 0;

+

+  /* The first non-blank is the start of the datatype */

+

+  p = skipSpaces(p);

+  if (*p == 0) goto EXIT;

+  *ppDataType = p;

+

+  /* We are not looking for the symbol, we are looking

+     for the separator that follows the symbol.  Then

+     we'll back up.

+   

+     Search for the ',' or '=" or null terminator.

+   */

+

+  p = skipToSeparatorOrEqualSign(p, pNest);

+

+  if (*pNest != 0) goto EXIT;

+

+  /*

+     Work backwards to find start of symbol

+     Skip spaces between the end of symbol and separator

+     Assume that there are no spaces in the formal, but

+     there is a space preceding the formal

+  */

+

+  for (q = &p[-1]; q >= *ppDataType; q--) {

+    if (! isspace(*q)) break;

+  }

+  if (q < *ppDataType) goto EXIT;

+

+  /*

+     MR26 Handle things like: IIR_Bool (IIR_Decl::*constraint)()

+     Backup until we hit the end of a symbol string, then find the

+     start of the symbol string.  This wont' work for functions

+     with prototypes, but works for the most common cases.  For

+     others, use typedef names.

+   */

+

+/* MR26 */  for (q = q; q >= *ppDataType; q--) {

+/* MR26 */    if (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$') break;

+/* MR26 */  }

+/* MR26 */  if (q < *ppDataType) goto EXIT;

+

+  for (q = q; q >= *ppDataType; q--) {

+    if ( ! (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$')) break;

+  }

+

+  *ppSymbol = &q[1];

+

+  if (*p == ',' || *p == 0) {

+    *ppSeparator = p;

+    goto EXIT;

+  }

+

+  *ppEqualSign = p;

+  p = skipSpaces(++p);

+  *ppValue = p;

+  if (*p == 0) goto EXIT;

+

+

+  while (*p != 0 && *pNest == 0 && *p != ',') {

+      p = skipToSeparator(p, pNest);

+  }

+  if (*pNest == 0) *ppSeparator = p;

+

+EXIT:

+  if (*p == ',') p++;

+  return p;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/mode.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/mode.h
new file mode 100644
index 0000000..c08bf31
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/mode.h
@@ -0,0 +1,12 @@
+#define START 0

+#define STRINGS 1

+#define ACTION_STRINGS 2

+#define ACTION_CHARS 3

+#define ACTION_COMMENTS 4

+#define TOK_DEF_COMMENTS 5

+#define TOK_DEF_CPP_COMMENTS 6

+#define ACTION_CPP_COMMENTS 7

+#define CPP_COMMENTS 8

+#define COMMENTS 9

+#define ACTIONS 10

+#define PARSE_ENUM_FILE 11

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/mrhoist.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/mrhoist.c
new file mode 100644
index 0000000..110bf59
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/mrhoist.c
@@ -0,0 +1,3030 @@
+/*

+ * mrhoist.c

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33MR10

+ *

+ */

+

+#include <stdio.h>

+

+#include "pcctscfg.h"

+

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+#include <ctype.h>

+

+#ifdef __USE_PROTOS

+void dumppred(Predicate *);

+#else

+void dumppred();

+#endif

+

+/*

+  Try to determine whether predicate "first" is true for

+    all cases where "second" is true.  Comparison takes place

+    without regard to context.

+  Assumes that predicate symbols have been expanded.

+  Assumes that there are no NAND or NOR nodes

+

+*/

+

+#ifdef __USE_PROTOS

+int MR_secondPredicateUnreachable(Predicate *first,Predicate *second)

+#else

+int MR_secondPredicateUnreachable(first,second)

+  Predicate     *first;

+  Predicate     *second;

+#endif

+{

+  Predicate     *f;

+  Predicate     *s;

+

+  if (first == NULL) {

+    return 1;

+  } else if (second == NULL) {

+    return 0;

+  } else if (first->down == NULL && second->down == NULL) {

+    if (first->source == second->source &&

+        first->inverted == second->inverted) {

+      return 1; /* look identical - will never reach alt2 */

+    } else {

+      return 0; /* look different */

+    };

+  } else if (first->down == NULL && second->down != NULL) {

+

+    if (second->expr == PRED_AND_LIST) {

+

+      /* unreachable if first covers any child of second */

+

+      for (s=second->down; s != NULL; s=s->right) {

+        if (MR_secondPredicateUnreachable(first,s)) {

+          return 1;

+        };

+      };

+      return 0;

+    } else if (second->expr == PRED_OR_LIST) {

+

+      /* unreachable if first covers every child of second */

+

+      for (s=second->down; s != NULL; s=s->right) {

+        if (!MR_secondPredicateUnreachable(first,s)) {

+          return 0;

+        };

+      };

+      return 1;

+    } else {

+      require (0,"Illegal pred->expr");

+      return 0; /* MR20 Make compiler happy */

+    };

+  } else if (first->down != NULL && second->down == NULL) {

+    if (first->expr == PRED_AND_LIST) {

+

+      /* unreachable if every child of first covers second */

+

+      for (f=first->down; f != NULL; f=f->right) {

+        if (!MR_secondPredicateUnreachable(f,second)) {

+          return 0;

+        };

+      };

+      return 1;

+    } else if (first->expr == PRED_OR_LIST) {

+

+      /* unreachable if any child of first covers second */

+

+      for (f=first->down; f != NULL; f=f->right) {

+        if (MR_secondPredicateUnreachable(f,second)) {

+          return 1;

+        };

+      };

+      return 0;

+    } else {

+      require (0,"Illegal predicate->expr");

+      return 0; /* MR20 Make compiler happy */

+    };

+  } else {

+

+    if (first->expr == PRED_AND_LIST && second->expr == PRED_AND_LIST) {

+

+      /* unreachable if each child of first covers at least one child of second */

+

+      for (f=first->down; f != NULL ; f=f->right) {

+        for (s=second->down; s != NULL ; s=s->right) {

+          if (MR_secondPredicateUnreachable(f,s)) goto A_next_f;

+        };

+        return 0;

+A_next_f:

+        continue;

+      };

+      return 1;

+

+    } else if (first->expr == PRED_AND_LIST && second->expr == PRED_OR_LIST) {

+

+      /* unreachable if each child of first covers ALL of second's children */

+

+      for (f=first->down; f != NULL ; f=f->right) {

+        for (s=second->down; s != NULL ; s=s->right) {

+          if (!MR_secondPredicateUnreachable(f,s)) return 0;

+        };

+      };

+      return 1;

+

+    } else if (first->expr == PRED_OR_LIST && second->expr == PRED_AND_LIST) {

+

+      /* unreachable if any child of second is covered by any child of first */

+

+      for (f=first->down; f != NULL ; f=f->right) {

+        for (s=second->down; s != NULL ; s=s->right) {

+          if (MR_secondPredicateUnreachable(f,s)) return 1;

+        };

+      };

+      return 0;

+

+    } else if (first->expr == PRED_OR_LIST && second->expr == PRED_OR_LIST) {

+

+      /* unreachable if every child of second is covered by some child of first */

+

+      for (f=first->down; f != NULL ; f=f->right) {

+        for (s=second->down; s != NULL ; s=s->right) {

+          if (MR_secondPredicateUnreachable(f,s)) goto B_next_f;

+        };

+        return 0;

+B_next_f:

+       continue;

+      };

+      return 1;

+

+    } else {

+      require (0,"Illegal predicate->expr");

+      return 0; /* MR20 Make compiler happy */

+    };

+  };

+  return 0; /* MR20 MSVC 5.0 complains about missing return statement */

+}

+

+#ifdef __USE_PROTOS

+void MR_xxxIndent(FILE *f,int depth)

+#else

+void MR_xxxIndent(f,depth)

+  FILE  *f;

+  int   depth;

+#endif

+{

+  int   i;

+

+  for (i=0; i<depth ; i++) {

+    fprintf(f,"  ");

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_stderrIndent(int depth)

+#else

+void MR_stderrIndent(depth)

+  int   depth;

+#endif

+{

+  MR_xxxIndent(stderr,depth);

+}

+

+#ifdef __USE_PROTOS

+void MR_outputIndent(int depth)

+#else

+void MR_outputIndent(depth)

+  int   depth;

+#endif

+{

+  MR_xxxIndent(output,depth);

+}

+

+#ifdef __USE_PROTOS

+void MR_set_reuse(set *s)

+#else

+void MR_set_reuse(s)

+  set   *s;

+#endif

+{

+  set_free(*s);

+  *s=empty;

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpPredRuleRefStack(FILE *iounit,int indent)

+#else

+void MR_dumpPredRuleRefStack(iounit,indent)

+  FILE  *iounit;

+  int   indent;

+#endif

+{

+    int             i;

+    int             j;

+    int             count=MR_PredRuleRefStack.count;

+    RuleRefNode     *rrn=NULL;

+    Junction        *lastOne;

+

+    if (count == 0) {

+      fprintf(iounit,"empty\n");

+      return;

+    };

+    for (i=0; i < count; i++) {

+      rrn=(RuleRefNode *) MR_PredRuleRefStack.data[i];

+      for (j=0; j<indent; j++) fprintf(iounit," ");

+      fprintf(iounit,"#%-2d in rule %s (line %d %s) to rule %s\n",

+            i,rrn->rname,rrn->line,FileStr[rrn->file],rrn->text);

+    };

+    lastOne=MR_ruleReferenced(rrn);

+    if (lastOne != NULL) {

+      for (j=0; j<indent; j++) fprintf(iounit," ");

+      fprintf(iounit,"#%-2d in rule %s (line %d %s)\n",

+        count,lastOne->rname,lastOne->line,FileStr[lastOne->file]);

+    };

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpTreeF(FILE *f,int depth,Tree *tree,int across)

+#else

+void MR_dumpTreeF(f,depth,tree,across)

+  FILE  *f;

+  Tree  *tree;

+  int   depth;

+  int   across;

+#endif

+{

+    int     newAcross=across;

+

+	if (tree == NULL ) return;

+	if (tree->down != NULL ) {

+      fprintf(output,"\n");

+      MR_outputIndent(depth);

+      fprintf(output, "(root =");

+    };

+	if (tree->token == ALT ) {

+      fprintf(output," %-16s","Alt");

+	} else if (tree->token==EpToken ) {

+      fprintf(output,"(%d)%13s",tree->v.rk," ");

+	} else {

+      fprintf(output," %-16s",TerminalString(tree->token));

+    };

+    if (tree->down != NULL) {

+      fprintf(output,"\n");

+      MR_outputIndent(depth+1);

+      MR_dumpTreeF(f,depth+1,tree->down,1);

+      newAcross=0;

+      fprintf(output,"\n");

+      MR_outputIndent(depth);

+      fprintf(output,")");

+    };

+    if (newAcross > 3) {

+      fprintf(output,"\n");

+      MR_outputIndent(depth);

+      newAcross=0;

+    };

+    MR_dumpTreeF(f,depth,tree->right,newAcross+1);

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpTreeX(int depth,Tree *tree,int across)

+#else

+void MR_dumpTreeX(depth,tree,across)

+  Tree  *tree;

+  int   depth;

+  int   across;

+#endif

+{

+  MR_dumpTreeF(output,depth,tree,across);

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpTokenSet(FILE *f,int depth,set s)

+#else

+void MR_dumpTokenSet(f,depth,s)

+  FILE  *f;

+  int   depth;

+  set   s;

+#endif

+{

+    int     i;

+    int     j;

+

+    unsigned  *pdq;

+

+    if (set_nil(s)) {

+      fprintf(f,"\n");

+      MR_xxxIndent(f,depth+1);

+      fprintf(f,"nil\n");

+      return;

+    };

+

+    pdq=set_pdq(s);

+    require(pdq != NULL,"set_pdq failed");

+    i=0;

+    for (i=0 ; ; i=i+4) {

+      fprintf(f,"\n");

+      MR_xxxIndent(f,depth+1);

+      for (j=0; j < 4 ; j++) {

+        if (pdq[i+j] == nil) break;

+        fprintf(f," %-16s",TerminalString(pdq[i+j]));

+      };

+      if (pdq[i+j] == nil) break;

+    };

+    fprintf(f,"\n");

+    free( (char *) pdq);

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpPred1(int depth,Predicate *p,int withContext)

+#else

+void MR_dumpPred1(depth,p,withContext)

+  int           depth;

+  Predicate     *p;

+  int           withContext;

+#endif

+{

+  unsigned      k;

+

+  if (p == NULL) {

+    MR_outputIndent(depth);

+    fprintf(output,"The predicate is empty (or always true)\n\n");

+    return;

+  };

+  if (p->down != NULL) {

+    MR_outputIndent(depth);

+    if (p->inverted) {

+

+        /* MR14a Left out print expression in fprintf

+                 Reported by Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de)

+        */

+

+      if (p->expr == PRED_AND_LIST) fprintf(output,"%s NAND (not AND) expr\n\n",p->expr);

+      if (p->expr == PRED_OR_LIST) fprintf(output,"%s NOR (not OR) expr\n\n",p->expr);

+    } else {

+      fprintf(output,"%s expr\n\n",p->expr);

+    };

+  } else {

+    MR_outputIndent(depth);

+    fprintf(output,"pred %s <<%s>>?\n",

+            (p->inverted ? " *not*" : ""),

+            (p->expr == NULL ? "null expr" : p->expr));

+    MR_outputIndent(depth+1);

+    fprintf(output,"              ");

+    fprintf(output,"  depth=k=%d",p->k);

+    if (p->source != NULL && p->source->guardpred) {

+      fprintf(output,"  (\"=>\" guard)");

+    }

+    if (p->source != NULL && p->source->ampersandPred != NULL) {

+      fprintf(output,"  (\"&&\" guard)");

+    };

+    k=set_int(p->completionSet);

+    if (k != nil) {

+      fprintf(output," Incomplete Set at k=%d !",k);

+    };

+    k=set_int(p->completionTree);

+    if (k != nil) {

+      fprintf(output," Incomplete Tree at k=%d !",k);

+    };

+    if (p->source != NULL) {

+      fprintf(output,"  rule %s  line %d  %s",

+                    p->source->rname,p->source->line,FileStr[p->source->file]);

+    };

+    fprintf(output,"\n");

+    if (withContext &&

+            (HoistPredicateContext ||

+             ! set_nil(p->scontext[1]) ||

+             p->tcontext != NULL)) {

+      if (p->k == 1) {

+        MR_outputIndent(depth+1);

+        fprintf(output,"set context: ");

+        MR_dumpTokenSet(output,depth+1,p->scontext[1]);

+      }

+      if (p->k != 1) {

+        MR_outputIndent(depth+1);

+        fprintf(output,"tree context:");

+        if (p->tcontext == NULL) {

+          fprintf(output," null");

+        } else {

+          MR_dumpTreeX(depth+2,p->tcontext,0);

+        };

+        fprintf(output,"\n");

+      };

+    };

+    fprintf(output,"\n");

+  };

+  if (p->down != NULL) {

+    MR_dumpPred1(depth+1,p->down,withContext);

+  };

+  if (p->right != NULL) {

+    MR_dumpPred1(depth,p->right,withContext);

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpPred(Predicate *p,int withContext)

+#else

+void MR_dumpPred(p,withContext)

+  Predicate     *p;

+  int           withContext;

+#endif

+{

+  MR_dumpPred1(0,p,withContext);

+}

+

+#ifdef __USE_PROTOS

+Tree * MR_make_tree_from_set(set s)

+#else

+Tree * MR_make_tree_from_set(s)

+  set   s;

+#endif

+{

+  Tree  *t=NULL;

+  Tree  *node;

+  Tree  **tp=&t;

+  int   i;

+

+  unsigned *pdq=set_pdq(s);

+

+  if (pdq != NULL) {

+    for (i=0 ; pdq[i] != nil ; i++) {

+      node=tnode( (int) pdq[i]);

+      *tp=node;

+      tp=&(node->right);

+    };

+    *tp=NULL;

+    free ( (char *) pdq);

+  };

+  return t;

+}

+

+#ifdef __USE_PROTOS

+void MR_check_pred_too_long(Predicate *p,set completion)

+#else

+void MR_check_pred_too_long(p,completion)

+  Predicate     *p;

+  set           completion;

+#endif

+{

+  if (p != NULL &&

+      p->source != NULL &&

+      ! p->source->predTooLong) {

+    if ( !set_nil(completion)) {

+      p->source->predTooLong=1;

+warnFL("It is unusual (but ok) for a semantic predicate to test context past the end of its own rule",

+                                FileStr[p->source->file],p->source->line);

+    };

+  };

+}

+

+#ifdef __USE_PROTOS

+int MR_predicate_context_completed(Predicate *p)

+#else

+int MR_predicate_context_completed(p)

+  Predicate     *p;

+#endif

+{

+  if (p == NULL) return 1;

+  if (p->expr != PRED_AND_LIST &&

+      p->expr != PRED_OR_LIST) {

+    if ( ! set_nil(p->completionSet)) return 0;

+    if ( ! set_nil(p->completionTree)) return 0;

+  };

+  return MR_predicate_context_completed(p->down) &

+         MR_predicate_context_completed(p->right);

+}

+

+#ifdef __USE_PROTOS

+Node * MR_advance(Node *n)

+#else

+Node * MR_advance(n)

+  Node  *n;

+#endif

+{

+    if (n == NULL) return NULL;

+    switch (n->ntype) {

+      case nJunction:   return ((Junction *)n)->p1;

+      case nToken:      return ((TokNode *)n)->next;

+      case nRuleRef:    return ((RuleRefNode *)n)->next;

+      case nAction:     return ((ActionNode *)n)->next;

+      default:          return NULL;

+    };

+  return NULL; /* MSVC 5.0 complains about missing return statement */

+}

+

+#ifdef __USE_PROTOS

+Junction * MR_find_endRule(Node *n)

+#else

+Junction * MR_find_endRule(n)

+  Node  *n;

+#endif

+{

+    Node    *next;

+    if (n == NULL) return NULL;

+    for (next=n; next != NULL; next=MR_advance(next)) {

+      if (next->ntype == nJunction &&

+            ( (Junction *) next)->jtype == EndRule) {

+        break;

+      };

+    };

+    return (Junction *)next;

+}

+

+/*

+   Intersection:  a branch which is shorter is chosen

+   over one which is longer: (A B C) intersect (A B) yields (A B).

+

+   AND: a branch which is longer is chosen over the one

+   which is shorter: (A B C) AND (A B) yields (A B C)

+

+*/

+

+#ifdef __USE_PROTOS

+Tree *MR_computeTreeIntersection(Tree *l,Tree *r)

+#else

+Tree *MR_computeTreeIntersection(l,r)

+    Tree    *l;

+    Tree    *r;

+#endif

+{

+    Tree    *result=NULL;

+    Tree    **tail;

+    Tree    *p;

+    Tree    *q;

+    Tree    *match;

+

+    if (l == NULL || r == NULL) return NULL;

+    for (p=l; p != NULL; p=p->right) {

+      require(p->token != EpToken,"MR_computeTreeIntersection: p->EpToken unexpected\n");

+      require (p->token != ALT,"MR_computeTreeIntersection: p->ALT unexpected\n");

+    };

+    for (q=r; q != NULL; q=q->right) {

+      require(q->token != EpToken,"MR_computeTreeIntersection: q->EpToken unexpected\n");

+      require(q->token != ALT,"MR_computeTreeIntersection: q->ALT unexpected\n");

+    };

+

+    result=tnode(ALT);

+    tail=&(result->down);

+

+    for (p=l; p != NULL ; p=p->right) {

+      for (q=r; q != NULL ; q=q->right) {

+        if (p->token == q->token) {

+          match=tnode(p->token);

+          match->down=MR_computeTreeIntersection(p->down,q->down);

+          *tail=match;

+          tail=&(match->right);

+        };

+      };

+    };

+

+    *tail=NULL;

+    result=tshrink(result);

+    result=tflatten( result );

+    result=tleft_factor( result );

+    return result;

+}

+

+/* the predicates which are ANDed together have a common

+   context:  they must all have common roots.  Thus the

+   AND operation is more like an OR operation because

+   branches which are longer are grafted onto shorter

+   branches of the AND tree.  For instance combining

+   (A B C) with (A B C D) gives (A B C D).  There

+   should never be a case of (A B C) and (A B D) because

+   they have the same context.

+

+   Actually, this may not be true once one throws in

+   guard predicates which are defined by the user, not

+   the context.

+*/

+

+/* requires input trees to be in "canonical" format */

+

+#ifdef __USE_PROTOS

+Tree *MR_computeTreeAND(Tree *l,Tree *r)

+#else

+Tree *MR_computeTreeAND(l,r)

+    Tree    *l;

+    Tree    *r;

+#endif

+{

+    Tree    *result=NULL;

+    Tree    **tail;

+    Tree    *p;

+    Tree    *q;

+    Tree    *match;

+

+    if (l == NULL) return tdup(r);

+    if (r == NULL) return tdup(l);

+

+    for (p=l; p != NULL; p=p->right) {

+/**** require(p->token != EpToken,"MR_computeTreeAND: p->EpToken unexpected\n"); ****/

+      require (p->token != ALT,"MR_computeTreeAND: p->ALT unexpected\n");

+    };

+    for (q=r; q != NULL; q=q->right) {

+/**** require(q->token != EpToken,"MR_computeTreeAND: q->EpToken unexpected\n"); ****/

+      require(q->token != ALT,"MR_computeTreeAND: q->ALT unexpected\n");

+    };

+

+    result=tnode(ALT);

+    tail=&(result->down);

+

+    for (p=l; p != NULL ; p=p->right) {

+      for (q=r; q != NULL ; q=q->right) {

+        if (p->token == q->token) {

+          match=tnode(p->token);

+          match->down=MR_computeTreeAND(p->down,q->down);

+          *tail=match;

+          tail=&(match->right);

+        };

+      };

+    };

+

+    *tail=NULL;

+    result=tshrink(result);

+    result=tflatten( result );

+    result=tleft_factor( result );

+    return result;

+}

+

+#ifdef __USE_PROTOS

+void MR_union_plain_sets1(Predicate *p,set *theUnion)

+#else

+void MR_union_plain_sets1(p,theUnion)

+  Predicate     *p;

+  set           *theUnion;

+#endif

+{

+  if (p == NULL) return;

+  MR_union_plain_sets1(p->down,theUnion);

+  MR_union_plain_sets1(p->right,theUnion);

+  set_orin(theUnion,p->plainSet);

+  return;

+}

+

+#ifdef __USE_PROTOS

+set MR_union_plain_sets(Predicate *p)

+#else

+set MR_union_plain_sets(p)

+  Predicate     *p;

+#endif

+{

+  set   theUnion;

+

+  theUnion=empty;

+

+  MR_union_plain_sets1(p,&theUnion);

+  return theUnion;

+}

+

+/* does NOT left factor: do not want to merge

+     (A B) with (A) to get (A B)

+   in fact the opposite: (A B) with (A) gives (A)

+*/

+

+#ifdef __USE_PROTOS

+Tree *MR_compute_pred_tree_ctxXX(Predicate *p)

+#else

+Tree *MR_compute_pred_tree_ctxXX(p)

+  Predicate     *p;

+#endif

+{

+    Tree        *result=NULL;

+    Predicate   *q;

+    Tree        *t;

+

+    if (p == NULL) return NULL;

+

+/* this appears strange: why do we OR the context

+   of and AND predicate ?  It is because of the way

+   that predicates are evaluated: if the context is

+   wrong then it's the same as if the predicate was

+   true.  That means that even when one leg of an

+   AND has unmatched context, if the other leg has

+   matched context and is true then the predicate

+   succeeds.  It's only when all the legs have unmatched

+   context that this one can skip evaluation of the

+   predicates.

+*/

+    if (p->expr == PRED_OR_LIST ||

+        p->expr == PRED_AND_LIST) {

+      for (q=p->down; q != NULL ; q=q->right) {

+        t=MR_compute_pred_tree_ctxXX(q);

+        result=tappend(result,t);

+        t=NULL;

+      };

+

+      result=tshrink(result);

+      result=tflatten( result );

+

+/* does NOT left factor: do not want to merge

+     (A B) with (A) to get (A B)

+   in fact the opposite: (A B) with (A) gives (A)

+*/

+

+/**** result=tleft_factor( result ); ****/

+      return result;

+    };

+

+#if 0

+**    if (p->expr == PRED_AND_LIST) {

+**

+**      Predicate     *l;

+**      Predicate     *r;

+**      Tree          *l1;

+**      Tree          *r1;

+**      Tree          *prevl1;

+**

+**      l=p->down;

+**      require (l->right != NULL,"MR_compute_pred_tree - AND has only one child");

+**

+**/* l1 and r1 should already be in "canonical" format */

+**

+**      l1=MR_compute_pred_tree(l);

+**      for (r=l->right; r != NULL; r=r->right) {

+**        r1=MR_compute_pred_tree(r);

+**        prevl1=l1;

+**        l1=MR_computeTreeAND(l1,r1);

+**        Tfree(r1);

+**        Tfree(prevl1);

+**      };

+**

+**/* result from computeTreeAND should be in "canonical" format */

+**

+**      result=l1;

+**

+**/* result of MR_computeTreeAND should be in "canonical" format */

+**

+**      return result;

+**    };

+#endif

+

+    if (p->k == 1) {

+      result=MR_make_tree_from_set(p->scontext[1]);

+    } else {

+      result=tdup(p->tcontext);

+      result=MR_remove_epsilon_from_tree(result);

+      result=tshrink(result);

+      result=tflatten(result);

+      result=tleft_factor(result);

+    };

+    return result;

+}

+

+#ifdef __USE_PROTOS

+void MR_pred_depth(Predicate *p,int *maxDepth)

+#else

+void MR_pred_depth(p,maxDepth)

+  Predicate     *p;

+  int           *maxDepth;

+#endif

+{

+  if (p == NULL) return;

+  if (p->expr != PRED_OR_LIST &&

+      p->expr != PRED_AND_LIST) {

+    if (p->k > *maxDepth) *maxDepth=p->k;

+  };

+  MR_pred_depth(p->down,maxDepth);

+  MR_pred_depth(p->right,maxDepth);

+}

+

+/* this computes the OR of all the contexts */

+

+#ifdef __USE_PROTOS

+set MR_compute_pred_set(Predicate *p)

+#else

+set MR_compute_pred_set(p)

+  Predicate     *p;

+#endif

+{

+    set         result;

+    Predicate   *q;

+

+    result=empty;

+

+    if (p == NULL) return empty;

+

+    if (p->expr == PRED_OR_LIST ||

+        p->expr == PRED_AND_LIST) {         /* yes, I do mean PRED_AND_LIST !   */

+                                            /* remember: r1: (A)? => <<p>>? r2; */

+                                            /*           r2: (B)? => <<q>>? r3; */

+      set   t;

+

+      t=empty;

+      result=empty;

+

+      for (q=p->down; q != NULL; q=q->right) {

+        t=MR_compute_pred_set(q);

+        set_orin(&result,t);

+        set_free(t);

+      };

+      return result;

+    } else if (p->k > 1) {

+      return empty;

+    } else {

+      return set_dup(p->scontext[1]);

+    };

+}

+

+#ifdef __USE_PROTOS

+set MR_First(int ck,Junction *j,set *incomplete)

+#else

+set MR_First(ck,j,incomplete)

+  int       ck;

+  Junction  *j;

+  set       *incomplete;

+#endif

+{

+    Junction    *p;

+    set         tokensUsed;

+

+    tokensUsed=empty;

+

+	require(j->ntype==nJunction, "MR_First: non junction passed");

+

+	p = analysis_point((Junction *)j->p1);

+

+	REACH(p,ck,incomplete,tokensUsed);

+

+    return tokensUsed;

+}

+

+#ifdef __USE_PROTOS

+void MR_cleanup_pred_trees(Predicate *p)

+#else

+void MR_cleanup_pred_trees(p)

+  Predicate     *p;

+#endif

+{

+  Tree      *t;

+

+  if (p == NULL) return;

+  if (p->expr != PRED_OR_LIST &&

+      p->expr != PRED_AND_LIST) {

+    t=p->tcontext;

+    t=tshrink(t);

+    t=tflatten(t);

+    t=tleft_factor(t);

+    p->tcontext=t;

+  };

+  MR_cleanup_pred_trees(p->down);

+  MR_cleanup_pred_trees(p->right);

+}

+

+/* does NOT return canonical tree */

+

+#ifdef __USE_PROTOS

+Tree * MR_remove_epsilon_from_tree(Tree *t)

+#else

+Tree * MR_remove_epsilon_from_tree(t)

+  Tree  *t;

+#endif

+{

+  if (t == NULL) return NULL;

+

+  /* I think ALT can be ignored as a special case */

+

+  if (t->token != EpToken) {

+    t->down=MR_remove_epsilon_from_tree(t->down);

+    t->right=MR_remove_epsilon_from_tree(t->right);

+    return t;

+  } else {

+    Tree    *u;

+    u=MR_remove_epsilon_from_tree(t->right);

+    t->right=NULL;

+    Tfree(t);

+    return u;

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_complete_set(int predDepth,set *tokensUsed,set *incomplete)

+#else

+void MR_complete_set(predDepth,tokensUsed,incomplete)

+  int       predDepth;

+  set       *tokensUsed;

+  set       *incomplete;

+#endif

+{

+    int             i;

+    RuleRefNode     *ruleRef;

+	set             rk2;

+    set             b;

+	int             k2;

+    Junction        *save_MR_RuleBlkWithHalt;

+

+    if (set_int(*incomplete) > (unsigned) predDepth) {

+      return;

+    };

+

+    require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,

+                "RuleRefStack and RuleBlkWithHaltStack not same size");

+

+    require(MR_RuleBlkWithHalt == NULL ||

+         (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),

+                     "RuleBlkWithHalt has no halt set");

+

+    save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;

+

+    if (MR_RuleBlkWithHalt != NULL) {

+      MR_RuleBlkWithHalt->end->halt=FALSE;

+    };

+

+    for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {

+      ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];

+      if (ruleRef == NULL) continue;

+

+      MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];

+      if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;

+

+      rk2=empty;

+      b=empty;

+

+      while ( !set_nil(*incomplete) ) {

+		k2=set_int(*incomplete);

+        if (k2 > predDepth) break;                    /* <=== another exit from loop */

+		set_rm(k2,*incomplete);

+        REACH(ruleRef->next,k2,&rk2,b);

+		set_orin(tokensUsed,b);

+		set_free(b);

+      };

+

+      if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;

+

+	  set_orin(incomplete,rk2);                       /* remember what we couldn't do */

+      set_free(rk2);

+	  if (set_int(*incomplete) > (unsigned) predDepth) break;    /* <=== another exit from loop */

+    };

+

+    MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;

+    if (MR_RuleBlkWithHalt != NULL) {

+      MR_RuleBlkWithHalt->end->halt=TRUE;

+    };

+}

+

+#ifdef __USE_PROTOS

+void MR_complete_tree(int predDepth,Tree **t,set *incomplete)

+#else

+void MR_complete_tree(predDepth,t,incomplete)

+  int       predDepth;

+  Tree      **t;

+  set       *incomplete;

+#endif

+{

+    int             i;

+    RuleRefNode     *ruleRef;

+	set             rk2;

+    Tree            *u;

+	unsigned        k2;

+    Junction        *save_MR_RuleBlkWithHalt;

+    int             saveConstrainSearch;

+

+    if (set_int(*incomplete) > (unsigned) predDepth) {

+      return;

+    };

+

+    require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,

+                "RuleRefStack and RuleBlkWithHaltStack not same size");

+

+    require(MR_RuleBlkWithHalt == NULL ||

+         (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),

+                     "RuleBlkWithHalt has no halt set");

+

+    save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;

+    saveConstrainSearch=ConstrainSearch;

+    ConstrainSearch=0;

+

+    if (MR_RuleBlkWithHalt != NULL) {

+      MR_RuleBlkWithHalt->end->halt=FALSE;

+    };

+

+    for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {

+      ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];

+      if (ruleRef == NULL) continue;

+

+      MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];

+

+      if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;

+

+      rk2=empty;

+

+      while ( !set_nil(*incomplete) ) {	

+		k2 = set_int(*incomplete);

+        if (k2 > (unsigned) predDepth) break;       /* <=== another exit from loop */

+		set_rm(k2,*incomplete);

+		u = NULL;

+

+        TRAV(ruleRef->next,k2,&rk2,u);

+

+			/* any subtrees missing k2 tokens, add u onto end */

+

+		*t=tlink(*t,u,k2);

+        Tfree(u);

+      }

+

+	  set_orin(incomplete,rk2);         /* remember what we couldn't do */

+      set_free(rk2);

+

+      if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;

+

+	  if (set_int(*incomplete) > (unsigned) predDepth) break;    /* <=== another exit from loop */

+    };

+

+    MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;

+

+    if (MR_RuleBlkWithHalt != NULL) {

+      MR_RuleBlkWithHalt->end->halt=TRUE;

+    };

+    ConstrainSearch=saveConstrainSearch;

+}

+

+#ifdef __USE_PROTOS

+void MR_complete_predicates(int predDepth,Predicate *pred)

+#else

+void MR_complete_predicates(predDepth,pred)

+  int           predDepth;

+  Predicate     *pred;

+#endif

+{

+  if (pred == NULL) return;

+  if (pred->expr != PRED_AND_LIST &&

+      pred->expr != PRED_OR_LIST) {

+    MR_complete_set(predDepth,&(pred->scontext[1]),&(pred->completionSet));

+    MR_complete_tree(predDepth,&(pred->tcontext),&(pred->completionTree));

+  };

+  MR_complete_predicates(predDepth,pred->down);

+  MR_complete_predicates(predDepth,pred->right);

+}

+

+#ifdef __USE_PROTOS

+Junction * MR_junctionWithoutP2(Junction *j)

+#else

+Junction * MR_junctionWithoutP2(j)

+  Junction  *j;

+#endif

+{

+  Junction  *thisAlt;

+

+/* don't want to follow p2 to the next alternative of this rule */

+/* insert a generic node with null p2 if necessary              */

+/* however FIRST requires a junction                            */

+

+  thisAlt=j;

+  if (thisAlt->p2 != NULL) {

+    if (thisAlt->p1->ntype == nJunction) {

+      thisAlt=(Junction *) thisAlt->p1;

+    } else {

+      thisAlt=newJunction();

+      thisAlt->p1=j->p1;

+      thisAlt->rname=j->rname;

+      thisAlt->file=j->file;

+      thisAlt->line=j->line;

+      j->p1=(Node *)thisAlt;

+    };

+  };

+  return thisAlt;

+}

+

+#ifdef __USE_PROTOS

+int MR_tree_equ(Tree *big, Tree *small) {

+#else

+int MR_tree_equ(big,small)

+  Tree  *big;

+  Tree  *small;

+{

+#endif

+

+  Tree      *b;

+  Tree      *s;

+  int       bcount=0;

+  int       scount=0;

+

+  if (small == NULL && big == NULL) return 1;

+  if (small == NULL) return 0;

+  if (big == NULL) return 0;

+

+  if (small->token == ALT) {

+    require(small->right == NULL,

+                "MR_tree_equ: small: ALT node has siblings");

+    return MR_tree_equ(big,small->down);

+  };

+  if (big->token == ALT) {

+    require(big->right == NULL,

+                "MR_tree_equ: big: ALT node has siblings");

+    return MR_tree_equ(big->down,small);

+  };

+  for (s=small; s != NULL; s=s->right) {

+    scount++;

+    require(s->token != EpToken,"MR_tree_equ: s->EpToken unexpected\n");

+  };

+  for (b=big; b != NULL; b=b->right) {

+    bcount++;

+    require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpected\n");

+  };

+

+  if (bcount != scount) return 0;

+

+  for (s=small; s != NULL; s=s->right) {

+    for (b=big; b!= NULL; b=b->right) {

+      if (s->token == b->token) {

+        if (MR_tree_equ(b->down,s->down)) goto next_s;

+      };

+    };

+    return 0;

+next_s:

+    continue;

+  };

+  return 1;

+}

+

+/* this does not compare sources - only contexts ! */

+

+#ifdef __USE_PROTOS

+int MR_identicalContext(Predicate *p,Predicate *q)

+#else

+int MR_identicalContext(p,q)

+  Predicate     *p;

+  Predicate     *q;

+#endif

+{

+  if (p->k != q->k) return 0;

+  require ( (p->tcontext == NULL) == (q->tcontext == NULL),

+        "tcontext inconsistent");

+  if (p->k == 1) {

+    return set_equ(p->scontext[1],q->scontext[1]);

+  } else {

+    return MR_tree_equ(p->tcontext,q->tcontext);

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_reportSetSuppression(int predDepth,

+            set predSet,set plainSet,Junction *jPred,Junction *jPlain,Predicate *p)

+#else

+void MR_reportSetSuppression(predDepth,predSet,plainSet,jPred,jPlain,p)

+  int       predDepth;

+  set       predSet;

+  set       plainSet;

+  Junction  *jPred;

+  Junction  *jPlain;

+  Predicate *p;

+#endif

+{

+  if (InfoP) {

+    fprintf(output,"\n#if 0\n\n");

+    fprintf(output,"Hoisting of predicate suppressed by alternative without predicate.\n");

+    fprintf(output,"The alt without the predicate includes all cases where the predicate is false.\n\n");

+    fprintf(output,"   WITH predicate: line %d  %s\n",jPred->line,FileStr[jPred->file]);

+    if (jPlain != NULL) {

+      fprintf(output,"   WITHOUT predicate: line %d  %s\n",jPlain->line,FileStr[jPlain->file]);

+    } else {

+      fprintf(output,"   WITHOUT predicate: all alternatives without predicates (combined)\n");

+    };

+    if (predDepth == 1) {

+      fprintf(output,"\nThe context set for the predicate:\n");

+      MR_dumpTokenSet(output,1,predSet);

+    };

+    fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n");

+    MR_dumpTokenSet(output,1,plainSet);

+    fprintf(output,"\nThe predicate:\n\n");

+    MR_dumpPred1(1,p,1);

+    fprintf(output,"Chain of referenced rules:\n\n");

+    MR_dumpPredRuleRefStack(output,4);

+    fprintf(output,"\n#endif\n");

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_reportSetRestriction(int predDepth,set predSet,set plainSet,

+            Junction *jPred,Junction *jPlain,Predicate *origPred,Predicate *newPred)

+#else

+void MR_reportSetRestriction(predDepth,predSet,plainSet,jPred,jPlain,origPred,newPred)

+  int       predDepth;

+  set       predSet;

+  set       plainSet;

+  Junction  *jPred;

+  Junction  *jPlain;

+  Predicate *origPred;

+  Predicate *newPred;

+#endif

+{

+  set       intersect;

+

+  intersect=empty;

+

+  if (! InfoP) return;

+  fprintf(output,"\n#if 0\n\n");

+  fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead set\n");

+  fprintf(output,"  between the alternative with the semantic predicate and one without\n");

+  fprintf(output,"Without this restriction the alternative without the predicate could not\n");

+  fprintf(output,"  be reached when input matched the context of the predicate and the predicate\n");

+  fprintf(output,"  was false.\n\n");

+

+  fprintf(output,"   WITH predicate: line %d  %s\n",jPred->line,FileStr[jPred->file]);

+  if (jPlain != NULL) {

+    fprintf(output,"   WITHOUT predicate: line %d  %s\n",jPlain->line,FileStr[jPlain->file]);

+  } else {

+    fprintf(output,"   WITHOUT predicate: all alternatives without predicates (combined)\n");

+  };

+  if (predDepth == 1) {

+    fprintf(output,"\nThe original context set for the predicate:\n");

+    MR_dumpTokenSet(output,1,predSet);

+  };

+  fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n");

+  MR_dumpTokenSet(output,1,plainSet);

+  if (predDepth == 1) {

+    fprintf(output,"\nThe intersection of the two sets\n");

+    intersect=set_and(predSet,plainSet);

+    MR_dumpTokenSet(output,1,intersect);

+    set_free(intersect);

+  };

+  fprintf(output,"\nThe original predicate:\n\n");

+  MR_dumpPred1(1,origPred,1);

+  fprintf(output,"The new (modified) form of the predicate:\n\n");

+  MR_dumpPred1(1,newPred,1);

+  fprintf(output,"#endif\n");

+}

+

+/* don't use Pass3 by itself unless you know that inverted is not important */

+

+#ifdef __USE_PROTOS

+Predicate * MR_removeRedundantPredPass3(Predicate *p)

+#else

+Predicate * MR_removeRedundantPredPass3(p)

+  Predicate *p;

+#endif

+{

+  Predicate     *q;

+

+  if (p == NULL) return NULL;

+  p->right=MR_removeRedundantPredPass3(p->right);

+  p->down=MR_removeRedundantPredPass3(p->down);

+  if (p->redundant) {

+    q=p->right;

+    p->right=NULL;

+    predicate_free(p);

+    return q;

+  };

+  if (p->expr == PRED_AND_LIST ||

+      p->expr == PRED_OR_LIST) {

+    if (p->down == NULL) {

+      q=p->right;

+      p->right=NULL;

+      predicate_free(p);

+      return q;

+    };

+    if (p->down != NULL && p->down->right == NULL) {

+      q=p->down;

+      q->right=p->right;

+      p->right=NULL;

+      p->down=NULL;

+      return q;

+    };

+  };

+  return p;

+}

+

+#ifdef __USE_PROTOS

+void MR_removeRedundantPredPass2(Predicate *p)

+#else

+void MR_removeRedundantPredPass2(p)

+  Predicate *p;

+#endif

+{

+  Predicate     *q;

+

+  if (p == NULL) return;

+

+  if (p->expr == PRED_AND_LIST) {

+    for (q=p->down ; q != NULL ; q=q->right) {

+      MR_removeRedundantPredPass2(q);

+      if (q->isConst) {

+        if (q->constValue == 0) {

+          p->isConst=1;

+          p->constValue=0;

+          return;

+        } else {

+          q->redundant=1;

+        };

+      };

+    };

+  };

+

+  if (p->expr == PRED_OR_LIST) {

+    for (q=p->down ; q != NULL ; q=q->right) {

+      MR_removeRedundantPredPass2(q);

+      if (q->isConst) {

+        if (q->constValue == 0) {

+          q->redundant=1;

+        } else {

+          p->isConst=1;

+          p->constValue=1;

+          return;

+        };

+      };

+    };

+  };

+

+  return;

+}

+

+#if 0

+   this totally ignores the implications of guarded predicates

+     in which the part after the guard could possibly cover a predicate.

+   that would be much harder:

+

+        rule : (A)? => <<p>>? sub1;     /* 1 */

+             | (B)? => <<r>>? sub2      /* 2 */

+        sub1 : (A)? => <<q>>? A B       /* 3 */

+             | B                        /* 4 - suppresses line 2 */

+             ;

+#endif

+

+#ifdef __USE_PROTOS

+void MR_apply_restriction1(Predicate *pred,set *plainSet,int *changed)

+#else

+void MR_apply_restriction1(pred,plainSet,changed)

+  Predicate     *pred;

+  set           *plainSet;

+  int           *changed;

+#endif

+{

+  if (pred == NULL) return;

+  MR_apply_restriction1(pred->right,plainSet,changed);

+  if (pred->down != NULL) {

+    MR_apply_restriction1(pred->down,plainSet,changed);

+  } else {

+    set     t;

+    if (pred->k == 1) {

+      t=set_dif(pred->scontext[1],*plainSet);

+      if (*changed == 0 &&

+          !set_equ(t,pred->scontext[1])) {

+        *changed=1;

+      };

+      if (set_nil(t)) {

+        pred->redundant=1;

+      };

+      set_free(pred->scontext[1]);

+      pred->scontext[1]=t;

+    };

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_orin_plainSet(Predicate *p,set plainSet)

+#else

+void MR_orin_plainSet(p,plainSet)

+  Predicate     *p;

+  set           plainSet;

+#endif

+{

+  if (p == NULL) return;

+  MR_orin_plainSet(p->down,plainSet);

+  MR_orin_plainSet(p->right,plainSet);

+  set_orin(&p->plainSet,plainSet);

+}

+

+Predicate   *PRED_SUPPRESS;

+

+#ifdef __USE_PROTOS

+Predicate * MR_find_in_aSubBlk(Junction *alt)

+#else

+Predicate * MR_find_in_aSubBlk(alt)

+  Junction  *alt;

+#endif

+{

+    Predicate       *root=NULL;

+    Predicate       **tail=NULL;

+

+	Junction        *p;

+

+    int             nAlts=0;

+    Junction        **jList;

+    Predicate       **predList;

+    int             *matchList;

+    set             predSet;

+    int             i;

+    int             j;

+    int             m;

+    int             predDepth;

+    set             incomplete;

+    set             union_plainSet;

+    set             setChange;

+    int             changed;

+    Predicate       *newPred;

+    set             setDif;

+    Predicate       *origPred;

+    int             depth1=1;             /* const int */

+    set             *plainContext;

+    set             plainSet;

+

+    predSet=empty;

+    incomplete=empty;

+    union_plainSet=empty;

+    setChange=empty;

+    setDif=empty;

+    plainSet=empty;

+

+    if (PRED_SUPPRESS == NULL) {

+      PRED_SUPPRESS=new_pred();

+      PRED_SUPPRESS->expr="Predicate Suppressed";

+    };

+

+    /* this section just counts the number of "interesting" alternatives  */

+    /*   in order to allocate arrays                                      */

+

+	for (p=alt; p!=NULL; p=(Junction *)p->p2) {

+	  /* ignore empty alts */

+	  if ( p->p1->ntype != nJunction ||

+	        ((Junction *)p->p1)->jtype != EndBlk )	{

+        nAlts++;

+      };

+    };

+

+    /* if this is a (...)+ block then don't count the last alt because

+       it can't be taken until at least one time through the block.

+       In other words it isn't a real choice until the (...)+ is entered

+         at which point the hoisting issue is moot.

+       Maybe look at "ignore" instead ?

+    */

+

+    if (alt->jtype == aPlusBlk) {

+      nAlts--;

+    };

+

+    jList=(Junction **)calloc(nAlts,sizeof(Junction *));

+    require(jList!=NULL,"cannot allocate MR_find_in_aSubBlk jList");

+

+    plainContext=(set *)calloc(nAlts,sizeof(set));

+    require(plainContext!=NULL,"cannot allocate MR_find_in_aSubBlk plainContext");

+    for (m=0; m < nAlts; m++) plainContext[m]=empty;

+

+    predList=(Predicate **)calloc(nAlts,sizeof(Predicate *));

+    require(predList!=NULL,"cannot allocate MR_find_in_aSubBlk predList");

+

+    matchList=(int *)calloc(nAlts,sizeof(int));

+    require(matchList!=NULL,"cannot allocate MR_find_in_aSubBlk matchList");

+

+    /* this section just fills in the arrays previously allocated       */

+    /* the most interesting one is matchList[]                          */

+    /*                                                                  */

+    /*   bit 0 => this alt has a semantic pred which is "covered"       */

+    /*              by an alt without a semantic pred.  Don't hoist.    */

+

+	for (i=0,p=alt;

+         p!=NULL && i<nAlts;

+         i++,p=(Junction *)p->p2) {

+

+	  /* ignore empty alts */

+

+	  if ( p->p1->ntype != nJunction ||

+	        ((Junction *)p->p1)->jtype != EndBlk )	{

+        jList[i]=MR_junctionWithoutP2(p);

+        predList[i]=find_predicates(p->p1);      /* should be jList ????? */

+        if (predList[i] != NULL) {

+          MR_cleanup_pred_trees(predList[i]);    /* flatten & left factor */

+          plainContext[i]=MR_union_plain_sets(predList[i]);

+        } else {

+          MR_set_reuse(&plainSet);

+          MR_set_reuse(&incomplete);

+          plainSet=MR_First(depth1,jList[i],&incomplete);

+          MR_complete_set(depth1,&plainSet,&incomplete);

+          require(set_nil(incomplete),"couldn't complete k=1");

+          plainContext[i]=plainSet;

+          plainSet=empty;

+        };

+        set_orin(&union_plainSet,plainContext[i]);

+      };

+    };

+

+    if (nAlts == 1) {

+      goto EXIT_SIMPLE;

+    };

+

+/*

+ *  Looking for cases where alt i has a semantic pred and alt j does not.

+ *  Don't care about cases where lookahead for semantic predicates overlap

+ *    because normal predicate hoisting does the correct thing automatically.

+ *  Don't care about cases where lookahead for alts without semantic predicates

+ *    overlap because normal prediction does the correct thing automatically.

+ *

+ *  When we find such a case check for one of three subcases:

+ *

+ *      1.  if lookahead for alt i is contained in the lookahead for any

+ *          alt j then ignore semantic predicate of alt i

+ *      2.  if lookahead for alt i is not contained in the lookahead for

+ *          any alt j then add add predicate i to the OR list to be hoisted

+ *      3.  if lookahead for alt i overlaps the lookahead for some alt j then

+ *          add a dummy semantic predicate for alt j

+ *

+ *  There is an implicit assumption that the context of all alternatives following

+ *  the rule being processed here are identical (but may vary from hoist to

+ *  hoist depending on the place where the rule was invoked that led to hoisting

+ *  these predicates.  In othere words in the fragment:

+ *

+ *            ( <<a>>? a1 a2 a3 | <<b>>? b1 b2 b3 )

+ *

+ *  both a3 and b3 have the same follow sets  because they are both at the end of

+ *  alternatives in the same block.

+ */

+

+    for (i=0; i < nAlts; i++) {

+      if (jList[i] == NULL) continue;

+      if (predList[i] == NULL) continue;

+

+        /* if the predicate depth turns out to be one token only */

+        /*   then it is can be easily represented as a set and   */

+        /*   compared to the junction set create by MR_First()   */

+

+      predDepth=0;

+      MR_pred_depth(predList[i],&predDepth);

+      require (predDepth >= 1,"MR_find_in_aSubBlk: pred depth < 1");

+      require (predDepth <= CLL_k,"MR_find_in_aSubBlk: predDepth > CLL_k");

+

+        /* complete predicates to predDepth

+           If completed to depth=1 then the context would be incomplete.

+           The context would be truncated and the predicate simplify routine

+             would have incomplete information.  It would lead to

+             either false matches of failure to find true matches.

+        */

+

+      MR_complete_predicates(predDepth,predList[i]);

+

+      if (predList[i] != NULL) {

+        MR_cleanup_pred_trees(predList[i]);    /* flatten & left factor */

+      };

+

+      /* If the predicate depth is 1 then it is possible to suppress

+           a predicate completely using a single plain alt.  Check for suppression

+           by a single plain alt first because it gives better messages.  If that

+           fails try the union of all the plain alts.

+      */

+

+      if (predDepth == 1) {

+

+        MR_set_reuse(&predSet);

+        predSet=MR_compute_pred_set(predList[i]);   /* ignores k>1 predicates */

+

+        for (j=0; j < nAlts; j++) {

+          if (jList[j] == NULL) continue;

+          if (j == i) continue;

+

+          MR_set_reuse(&setDif);

+          setDif=set_dif(predSet,plainContext[j]);

+          if (set_nil(setDif)) {

+            matchList[i] |= 1;

+            MR_reportSetSuppression(predDepth,predSet,plainContext[j],jList[i],jList[j],predList[i]);

+            predicate_free(predList[i]);

+            predList[i]=PRED_SUPPRESS;

+            goto next_i;

+          };

+

+        }; /* end loop on j */

+

+        changed=0;

+

+        /* predicate_dup is only to give good error messages */

+        /* remember to do a predicate_free()                 */

+

+        origPred=predicate_dup(predList[i]);

+        MR_apply_restriction1(predList[i],&union_plainSet,&changed);

+        if (changed) {

+

+          /* don't use Pass3 by itself unless you know that inverted is not important */

+

+          newPred=MR_removeRedundantPredPass3(predList[i]);

+          newPred=MR_predSimplifyALL(newPred);

+          if (newPred == NULL) {

+            matchList[i] |= 1;

+            MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],

+                                                            NULL,origPred);

+            predList[i]=PRED_SUPPRESS;

+          } else {

+            MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],

+                                                    NULL,origPred,newPred);

+            predList[i]=newPred;

+          };

+        };

+        predicate_free(origPred);

+        origPred=NULL;

+      };

+

+      /*

+         If the predicate depth is > 1 then it can't be suppressed completely

+           because the code doesn't support inspection of such things.  They're

+           much messier than k=1 sets.

+      */

+

+      if (predDepth > 1 ) {

+

+        changed=0;

+

+        /* predicate_dup is only to give good error messages */

+        /* remember to do a predicate_free()                 */

+

+        origPred=predicate_dup(predList[i]);

+        MR_apply_restriction1(predList[i],&union_plainSet,&changed);

+        if (changed) {

+          newPred=MR_removeRedundantPredPass3(predList[i]);

+          newPred=MR_predSimplifyALL(newPred);

+          if (newPred == NULL) {

+            matchList[i] |= 1;

+            MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],

+                                                            NULL,origPred);

+            predList[i]=PRED_SUPPRESS;

+          } else {

+            MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],

+                                                    NULL,origPred,newPred);

+            predList[i]=newPred;

+          };

+        };

+        predicate_free(origPred);

+        origPred=NULL;

+      };

+next_i:

+      continue;

+    };

+

+EXIT_SIMPLE:

+

+    root = new_pred();

+    root->expr=PRED_OR_LIST;

+    tail = &(root->down);

+

+    for (i=0 ; i< nAlts ; i++) {

+      if (jList[i] == NULL) continue;

+

+      if (predList[i] == NULL) {

+        continue;

+      } else if ( (matchList[i] & 1) != 0) {

+        if (predList[i] != PRED_SUPPRESS) {

+          predicate_free(predList[i]);

+        };

+        continue;

+      };

+

+      /* make an OR list of predicates */

+

+      *tail=predList[i];

+      tail=&(predList[i]->right);

+    };

+

+	/* if just one pred, remove OR root */

+

+	if (root->down == NULL) {

+      predicate_free(root);

+      root=NULL;

+    } else if (root->down->right == NULL) {

+      Predicate     *p=root->down;

+      root->down=NULL;

+      predicate_free(root);

+      root=p;

+	}

+

+    root=MR_predSimplifyALL(root);

+

+    MR_orin_plainSet(root,union_plainSet);

+

+    set_free(predSet);

+    set_free(union_plainSet);

+    set_free(incomplete);

+    set_free(setChange);

+    set_free(setDif);

+

+    for (m=0; m < nAlts; m++) set_free(plainContext[m]);

+

+    free ( (char *) jList);

+    free ( (char *) predList);

+    free ( (char *) matchList);

+    free ( (char *) plainContext);

+

+	return root;

+}

+

+#ifdef __USE_PROTOS

+void MR_predContextPresent(Predicate *p,int *allHaveContext,int *noneHaveContext)

+#else

+void MR_predContextPresent(p,allHaveContext,noneHaveContext)

+  Predicate     *p;

+  int           *allHaveContext;

+  int           *noneHaveContext;

+#endif

+{

+  if (p == NULL) return;

+  MR_predContextPresent(p->right,allHaveContext,noneHaveContext);

+  if (p->expr != PRED_AND_LIST &&

+      p->expr != PRED_OR_LIST) {

+    if (set_nil(p->scontext[1]) == 0 ||

+            (p->tcontext != NULL)) {

+      *noneHaveContext=0;

+    } else {

+      *allHaveContext=0;

+    };

+  };

+  MR_predContextPresent(p->down,allHaveContext,noneHaveContext);

+}

+

+#ifdef __USE_PROTOS

+int MR_pointerStackPush(PointerStack *ps,void *dataPointer)

+#else

+int MR_pointerStackPush(ps,dataPointer)

+  PointerStack  *ps;

+  void          *dataPointer;

+#endif

+{

+  void             **newStack;

+  int              newSize;

+  int              i;

+

+  if (ps->count == ps->size) {

+    newSize=20+ps->size*2;

+    newStack=(void **)calloc(newSize,sizeof(void *));

+    require (newStack != NULL,"cannot allocate PointerStack");

+    for (i=0; i < ps->size; i++) {

+      newStack[i]=ps->data[i];

+    };

+    if (ps->data != NULL) free( (char *) ps->data);

+    ps->data=newStack;

+    ps->size=newSize;

+  };

+  ps->data[ps->count]=dataPointer;

+  ps->count++;

+  return ps->count-1;

+}

+

+#ifdef __USE_PROTOS

+void * MR_pointerStackPop(PointerStack *ps)

+#else

+void * MR_pointerStackPop(ps)

+  PointerStack  *ps;

+#endif

+{

+  void  *dataPointer;

+

+  require(ps->count > 0,"MR_pointerStackPop underflow");

+

+  dataPointer=ps->data[ps->count-1];

+  ps->data[ps->count-1]=NULL;

+  (ps->count)--;

+  return dataPointer;

+}

+

+#ifdef __USE_PROTOS

+void * MR_pointerStackTop(PointerStack *ps)

+#else

+void * MR_pointerStackTop(ps)

+  PointerStack  *ps;

+#endif

+{

+  require(ps->count > 0,"MR_pointerStackTop underflow");

+  return ps->data[ps->count-1];

+}

+

+#ifdef __USE_PROTOS

+void MR_pointerStackReset(PointerStack *ps)

+#else

+void MR_pointerStackReset(ps)

+  PointerStack  *ps;

+#endif

+{

+  int i;

+  if (ps->data != NULL) {

+    for (i=0; i < ps->count ; i++) {

+       ps->data[i]=NULL;

+    };

+  };

+  ps->count=0;

+}

+

+#ifdef __USE_PROTOS

+Junction *MR_nameToRuleBlk(char *name)

+#else

+Junction *MR_nameToRuleBlk(name)

+  char  *name;

+#endif

+{

+    RuleEntry *q;

+

+    require (RulePtr != NULL,"MR_nameToRule: RulePtr not initialized");

+

+    if (name == NULL) return NULL;

+

+    q = (RuleEntry *) hash_get(Rname,name);

+

+	if ( q == NULL ) {

+      return NULL;

+    } else {

+      return RulePtr[q->rulenum];

+    };

+}

+

+#ifdef __USE_PROTOS

+Junction * MR_ruleReferenced(RuleRefNode *rrn)

+#else

+Junction * MR_ruleReferenced(rrn)

+  RuleRefNode   *rrn;

+#endif

+{

+    return MR_nameToRuleBlk(rrn->text);

+}

+

+#ifdef __USE_PROTOS

+void MR_comparePredLeaves(Predicate *me,Predicate *myParent,Predicate *him,Predicate *hisParent)

+#else

+void MR_comparePredLeaves(me,myParent,him,hisParent)

+    Predicate *me;

+    Predicate *myParent;

+    Predicate *him;

+    Predicate *hisParent;

+#endif

+{

+    if (me == NULL) return;

+    if (me == him) {

+      MR_comparePredLeaves(me->right,myParent,him,hisParent);

+      return;

+    } else if (me->expr == PRED_AND_LIST ||

+               me->expr == PRED_OR_LIST) {

+      MR_comparePredLeaves(me->down,me,him,hisParent);

+      MR_comparePredLeaves(me->right,myParent,him,hisParent);

+      return;

+    } else {

+      if (me->source != NULL) {

+

+        /* predicate->invert can be set only in the predEntry predicates        */

+        /* thus they are only visible after the predEntry predicates have been "unfolded" */

+

+        int     sameSource=(me->source == him->source);

+        int     sameInvert=1 &

+                 (1 + me->inverted + him->inverted + me->source->inverted + him->source->inverted);

+        int     samePredEntry=(me->source->predEntry != NULL

+                                 && him->source->predEntry != NULL

+                                    && me->source->predEntry == him->source->predEntry);

+        if (sameInvert && (sameSource || samePredEntry)) {

+          if (MR_identicalContext(me,him)) {

+

+            /* identical predicates */

+

+            if (hisParent->expr == PRED_OR_LIST &&

+                myParent->expr == PRED_OR_LIST) {

+              me->redundant=1;

+            } else if (hisParent->expr == PRED_AND_LIST &&

+                       myParent->expr == PRED_AND_LIST) {

+              me->redundant=1;

+            } else if (  (hisParent->expr == PRED_OR_LIST &&

+                          myParent->expr == PRED_AND_LIST)

+                       ||

+                         (hisParent->expr == PRED_AND_LIST &&

+                          myParent->expr == PRED_OR_LIST)

+                      ) {

+              myParent->redundant=1;

+            } else {

+              require (0,"MR_comparePredLeaves: not both PRED_LIST");

+            };

+          };

+        };  /* end same source or same predEntrr with same invert sense */

+

+        /* same predEntry but opposite invert sense */

+

+        if (!sameInvert && (sameSource || samePredEntry)) {

+          if (MR_identicalContext(me,him)) {

+            if (hisParent->expr == PRED_OR_LIST &&

+                myParent->expr == PRED_OR_LIST) {

+              myParent->isConst=1;

+              myParent->constValue=1;

+            } else if (hisParent->expr == PRED_AND_LIST &&

+                       myParent->expr == PRED_AND_LIST) {

+              myParent->isConst=1;

+              myParent->constValue=0;

+            } else if (  (hisParent->expr == PRED_OR_LIST &&

+                          myParent->expr == PRED_AND_LIST)

+                       ||

+                         (hisParent->expr == PRED_AND_LIST &&

+                          myParent->expr == PRED_OR_LIST)

+                      ) {

+              me->redundant=1;

+            } else {

+              require (0,"MR_comparePredLeaves: not both PRED_LIST");

+            };

+          };

+        };  /* end same predEntry with opposite invert sense */

+      };

+

+      MR_comparePredLeaves(me->right,myParent,him,hisParent);

+      return;

+    };

+}

+

+#ifdef __USE_PROTOS

+void MR_removeRedundantPredPass1(Predicate *me,Predicate *myParent)

+#else

+void MR_removeRedundantPredPass1(me,myParent)

+  Predicate     *me;

+  Predicate     *myParent;

+#endif

+{

+    if (me == NULL) return;

+    if (me->redundant) {

+      MR_removeRedundantPredPass1(me->right,myParent);

+      return;

+    };

+    if (me->expr == PRED_AND_LIST ||

+        me->expr == PRED_OR_LIST) {

+      MR_removeRedundantPredPass1(me->down,me);

+      MR_removeRedundantPredPass1(me->right,myParent);

+    } else {

+      require (me->source != NULL,"me->source == NULL");

+      if (myParent != NULL) {

+        MR_comparePredLeaves(myParent->down,myParent,me,myParent);

+      };

+      MR_removeRedundantPredPass1(me->right,myParent);

+    };

+}

+

+/* pretty much ignores things with the inverted bit set */

+

+#ifdef __USE_PROTOS

+Predicate *MR_predFlatten(Predicate *p)

+#else

+Predicate *MR_predFlatten(p)

+  Predicate     *p;

+#endif

+{

+    if (p == NULL) return NULL;

+    if (p->expr == PRED_OR_LIST

+        || p->expr == PRED_AND_LIST) {

+

+      Predicate     *child;

+      Predicate     *gchild;

+      Predicate     **tail;

+      Predicate     *next;

+      char          *PRED_XXX_LIST=p->expr;

+

+      require (p->down != NULL,"MR_predFlatten AND/OR no child");

+

+

+      p->down=MR_predFlatten(p->down);

+      p->right=MR_predFlatten(p->right);

+      child=p->down;

+      if (child->right == NULL) {

+        child->right=p->right;

+        p->right=NULL;

+        p->down=NULL;

+        if (p->inverted) child->inverted=!child->inverted;

+        predicate_free(p);

+        return child;

+      };

+

+      /* make a single list of all children and grandchildren */

+

+      tail=&(p->down);

+      for (child=p->down; child != NULL; child=next) {

+        if (child->expr != PRED_XXX_LIST

+              || child->inverted

+                || child->predEntry != NULL) {

+          *tail=child;

+          tail=&(child->right);

+          next=child->right;

+        } else {

+          for (gchild=child->down;

+               gchild != NULL;

+               gchild=gchild->right) {

+            *tail=gchild;

+            tail=&(gchild->right);

+          };

+          next=child->right;

+          child->right=NULL;

+          child->down=NULL;

+          predicate_free(child);

+        };

+      };

+      *tail=NULL;

+      return p;

+    } else {

+      p->right=MR_predFlatten(p->right);

+      return p;

+    };

+}

+

+static char *alwaysFalseWarning=NULL;

+

+#ifdef __USE_PROTOS

+Predicate *checkPredicateConflict(Predicate *p)

+#else

+Predicate *checkPredicateConflict(p)

+  Predicate     *p;

+#endif

+{

+  if (p->isConst) {

+    if (p->constValue == 1) {

+      predicate_free(p);

+      return NULL;

+    } else {

+      if (InfoP && !p->conflictReported) {

+        p->conflictReported=1;

+        fprintf(output,"\n#if 0\n\n");

+        fprintf(output,"The following predicate expression will always be false:\n\n");

+        MR_dumpPred1(1,p,1);

+        fprintf(output,"\n#endif\n");

+      };

+

+      if (alwaysFalseWarning != CurRule) {

+        alwaysFalseWarning=CurRule;

+        if (InfoP) {

+          warnNoFL(eMsg1("one (or more) predicate expression hoisted into rule \"%s\" are always false \

+- see output file for more information",CurRule));

+        } else {

+          warnNoFL(eMsg1("one (or more) predicate expressions hoisted into rule \"%s\" are always false \

+- use \"-info p\" for more information",CurRule));

+        };

+      };

+    };

+  };

+  return p;

+}

+

+

+#ifdef __USE_PROTOS

+int MR_countPredNodes(Predicate *p)

+#else

+int MR_countPredNodes(p)

+  Predicate     *p;

+#endif

+{

+  if (p == NULL) return 0;

+  return 1 + MR_countPredNodes(p->down) + MR_countPredNodes(p->right);

+}

+

+#ifdef __USE_PROTOS

+Predicate *MR_predSimplifyALLX(Predicate *p,int skipPass3)

+#else

+Predicate *MR_predSimplifyALLX(p,skipPass3)

+  Predicate     *p;

+  int           skipPass3;

+#endif

+{

+  int       countBefore;

+  int       countAfter;

+

+  countAfter=MR_countPredNodes(p);

+

+  do {

+      if (p == NULL) return NULL;

+      if (p->right == NULL && p->down == NULL) return p;

+      countBefore=countAfter;

+      MR_simplifyInverted(p,0);

+      p=MR_predFlatten(p);

+      MR_removeRedundantPredPass1(p,NULL);

+      MR_removeRedundantPredPass2(p);

+      if (! skipPass3) {

+        p=checkPredicateConflict(p);

+        p=MR_removeRedundantPredPass3(p);

+      };

+      countAfter=MR_countPredNodes(p);

+  } while (countBefore != countAfter);

+

+  return p;

+}

+

+#ifdef __USE_PROTOS

+Predicate *MR_predSimplifyALL(Predicate *p)

+#else

+Predicate *MR_predSimplifyALL(p)

+  Predicate     *p;

+#endif

+{

+  return MR_predSimplifyALLX(p,0);

+}

+

+#ifdef __USE_PROTOS

+void MR_releaseResourcesUsedInRule(Node *n)

+#else

+void MR_releaseResourcesUsedInRule(n)

+  Node  *n;

+#endif

+{

+   Node         *next;

+   Junction     *j;

+   int          i;

+

+   if (n == NULL) return;

+   if (n->ntype == nJunction) {

+     j=(Junction *) n;

+

+     if (j->predicate != NULL) {

+       predicate_free(j->predicate);

+       j->predicate=NULL;

+     };

+     for (i=0; i< CLL_k; i++) {

+       set_free(j->fset[i]);

+       j->fset[i]=empty;

+     };

+     if (j->ftree != NULL) {

+       Tfree(j->ftree);

+       j->ftree=NULL;

+     };

+     if (j->jtype == EndRule) return;

+     if (j->jtype != RuleBlk && j->jtype != EndBlk) {

+       if (j->p2 != NULL && !j->ignore) {   /* MR11 */

+          MR_releaseResourcesUsedInRule(j->p2);

+       };

+     };

+   };

+   next=MR_advance(n);

+   MR_releaseResourcesUsedInRule(next);

+}

+

+#ifdef __USE_PROTOS

+int MR_allPredLeaves(Predicate *p)

+#else

+int MR_allPredLeaves(p)

+  Predicate *p;

+#endif

+{

+  Predicate     *q;

+

+  if (p == NULL) return 1;

+

+  for (q=p; q != NULL; q=q->right) {

+   if (q->down != NULL) return 0;

+  };

+  return 1;

+}

+

+/* make sure it works for the last rule in a file */

+

+#ifdef __USE_PROTOS

+int MR_offsetFromRule(Node *n)

+#else

+int MR_offsetFromRule(n)

+  Node      *n;

+#endif

+{

+  Junction  *j;

+  int       offset=(-1);

+

+  for (j=SynDiag; j != NULL; j=(Junction *)j->p2) {

+

+    require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block");

+

+    if (n->file < j->file) {

+      return offset;

+    };

+    if (n->file == j->file) {

+      if (n->line < j->line) {

+        return (offset < 0) ? 0 : offset;

+      } else {

+        offset=n->line - j->line;

+        if (offset == 0) return 0;

+      };

+    };

+  };

+  return offset;

+}

+

+#define ruleNameMax 50

+

+static char ruleNameStatic1[ruleNameMax];

+static char ruleNameStatic2[ruleNameMax+10];

+

+#ifdef __USE_PROTOS

+char * MR_ruleNamePlusOffset(Node *n)

+#else

+char * MR_ruleNamePlusOffset(n)

+  Node      *n;

+#endif

+{

+    int     offset=MR_offsetFromRule(n);

+

+    strncpy(ruleNameStatic1,n->rname,ruleNameMax);

+    if (offset < 0) {

+      sprintf(ruleNameStatic2,"%s/?",ruleNameStatic1);

+    } else {

+      sprintf(ruleNameStatic2,"%s/%d",ruleNameStatic1,offset+1);

+    };

+    return ruleNameStatic2;

+}

+

+#ifdef __USE_PROTOS

+int MR_max_height_of_tree(Tree *t)

+#else

+int MR_max_height_of_tree(t)

+  Tree  *t;

+#endif

+{

+  int       h;

+  int       height=0;

+  Tree      *u;

+

+  if (t == NULL) return 0;

+

+  require (t->token != ALT && t->token != EpToken,"MR_max_height_of_tree ALT or EpToken");

+

+  for (u=t; u != NULL; u=u->right) {

+    h=MR_max_height_of_tree(u->down)+1;

+    if (h > height) height=h;

+  };

+  return height;

+}

+

+#ifdef __USE_PROTOS

+int MR_all_leaves_same_height(Tree *t,int depth)

+#else

+int MR_all_leaves_same_height(t,depth)

+  Tree  *t;

+  int   depth;

+#endif

+{

+  if (t == NULL) {

+    return (depth==0);

+  };

+

+  require (t->token != ALT && t->token != EpToken,"MR_all_leaves_same_height ALT or EpToken");

+

+  if (depth == 0) {

+    return 0;

+  } else {

+    if ( ! MR_all_leaves_same_height(t->down,depth-1)) {

+      return 0;

+    };

+    if (t->right == NULL) {

+      return 1;

+    } else {

+      return MR_all_leaves_same_height(t->right,depth);

+    };

+  };

+}

+

+#ifdef __USE_PROTOS

+void MR_projectTreeOntoSet(Tree *tree,int ck,set *ckset)

+#else

+void MR_projectTreeOntoSet(tree,ck,ckset)

+  Tree  *tree;

+  int   ck;

+  set   *ckset;

+#endif

+{

+    if (tree == NULL) return;

+

+    require(tree->token != EpToken,"MR_projectTreeOntoSet: EpToken unexpected\n");

+

+    MR_projectTreeOntoSet(tree->right,ck,ckset);

+    if (tree->token == ALT) {

+      MR_projectTreeOntoSet(tree->down,ck,ckset);

+    } else {

+      if (ck > 1) {

+        MR_projectTreeOntoSet(tree->down,ck-1,ckset);

+      } else {

+        set_orel(tree->token,ckset);

+      };

+    };

+}

+

+#ifdef __USE_PROTOS

+int MR_comparePredicates(Predicate *a,Predicate *b)

+#else

+int MR_comparePredicates(a,b)

+  Predicate     *a;

+  Predicate     *b;

+#endif

+{

+  Predicate     *p;

+  Predicate     *q;

+

+  if (a == b) return 1;

+  if (a == NULL || b == NULL ) return 0;

+  if (a->down == NULL && b->down == NULL) {

+

+    /* predicate->invert can be set only in the predEntry predicates                  */

+    /* thus they are only visible after the predEntry predicates have been "unfolded" */

+

+    int     sameSource=(a->source == b->source);

+    int     sameInvert= 1 & (1 +a->inverted + b->inverted +

+                                a->source->inverted + b->source->inverted);

+    int     samePredEntry=(a->source->predEntry != NULL

+                                 && b->source->predEntry != NULL

+                                    && a->source->predEntry == b->source->predEntry);

+    if (sameInvert && (sameSource || samePredEntry)) {

+      if (MR_identicalContext(a,b)) {

+         return 1;

+      };

+    };

+    return 0;

+  };

+  if (a->down == NULL || b->down == NULL) return 0;

+  if (a->expr != b->expr) return 0;

+

+  for (p=a->down; p != NULL; p=p->right) {

+    for (q=b->down; q != NULL; q=q->right) {

+      if (MR_comparePredicates(p,q)) goto NEXT_P;

+    };

+    return 0;

+NEXT_P:

+    continue;

+  };

+  return 1;

+}

+

+/*

+ *  action->inverted can be set only when a predicate symbol appears in

+ *      a rule:  "rule : <<!XXX>>? X".  It cannot be set under any

+ *      other circumstances.  In particular it cannot be set by

+ *      "#pred NotA !A" or by "#pred Nota <<!A>>?".  The first case

+ *      creates a predEntry and the predicate expression of that predEntry

+ *      has inverted set.  In the second case, the code for handling "!"

+ *      is only present in buildAction, which is not called by the #pred

+ *      semantic routines, only when a <<...>>? is recognized as part of

+ *      a rule definition.

+ *

+ *  predicate->inverted can only be set by a predicate created by a #pred

+ *      expression, such as "#pred NotA !A" or "#pred NotXY ! (X && Y) or

+ *      "#pred XbarY !(X && Y)".  In particular, it cannot be set by any

+ *      predicate expression occurring under any other circumstances.

+ *      The #pred predicate expresssions are stored with in predEntry->pred

+ *      and do not normally appear anywhere else until the predicates are

+ *      "unfolded" in order to recognize redundancies, conflicts, and

+ *      tautologies.

+ *

+ *  The unfold routine expands all references to #pred expressions.

+ *

+ *  The simplifyInvert goes through and propagates the invert bit so that

+ *      all OR and AND nodes are un-inverted.

+ *

+ *  Note that !(A and B) => (!A or !B)

+ *            !(A or B)  => (!A and !B)

+ *

+ *  MR_unfold() is called to expand predicate symbols by replacing predicates

+ *    that reference predicate entries with the copies of the predicate entries.

+ *    Each reference receives a duplicate of the original.  This is necessary

+ *    because the next phase involves simplification and removal of redundant

+ *    predicate nodes.  Anyway, the point I'm making is that predicate->invert

+ *    should not be set in any predicate until it has been expanded.

+ *

+ *    This is a recursive structure, but there is no need for "recursive expansion"

+ *    by which I mean a predicate symbol refers to other predicate symbols which

+ *    must also be expanded.

+ *

+ *    Recursive expansion is *not* performed by this routine because it is not

+ *    necessary.  Expansion of references is performed by predPrimary when

+ *    a new predicate symbol is created by referring to others in the pred expr.

+ */

+

+#ifdef __USE_PROTOS

+Predicate *MR_unfold(Predicate *pred)

+#else

+Predicate *MR_unfold(pred)

+  Predicate     *pred;

+#endif

+{

+  Predicate     *result;

+

+  if (pred == NULL) return NULL;

+

+  pred->right=MR_unfold(pred->right);

+

+  if (pred->down == NULL) {

+    if (pred->source->predEntry != NULL) {

+      if (pred->source->predEntry->pred == NULL) {

+        ; /* do nothing */ /* a reference to a literal #pred (perhaps with "!" */

+      } else {

+        result=predicate_dup_without_context(pred->source->predEntry->pred);

+        if (pred->inverted) {

+          result->inverted=!result->inverted;

+        };

+        if (pred->source->inverted) {

+          result->inverted=!result->inverted;

+        };

+        result->right=pred->right;

+        pred->right=NULL;

+        predicate_free(pred);

+/***    result=MR_unfold(result); *** not necessary */    /* recursive expansion */

+        return result;

+      };

+    } else {

+      ; /* do nothing */ /* an inline literal predicate */

+    };

+  } else {

+    pred->down=MR_unfold(pred->down);

+  };

+  return pred;

+}

+

+/* this should be called immediately after MR_unfold() and

+   at no other times

+*/

+

+#ifdef __USE_PROTOS

+void MR_simplifyInverted(Predicate *pred,int inverted)

+#else

+void MR_simplifyInverted(pred,inverted)

+  Predicate     *pred;

+  int           inverted;

+#endif

+{

+  int       newInverted;

+

+  if (pred == NULL) return;

+

+  MR_simplifyInverted(pred->right,inverted);

+

+  newInverted= 1 & (inverted + pred->inverted);

+

+  if (pred->down == NULL) {

+    pred->inverted=newInverted;

+  } else {

+    if (newInverted != 0) {

+      if (pred->expr == PRED_AND_LIST) {

+        pred->expr=PRED_OR_LIST;

+      } else {

+        pred->expr=PRED_AND_LIST;

+      };

+    };

+    pred->inverted=0;

+    MR_simplifyInverted(pred->down,newInverted);

+  };

+}

+

+/* only remove it from AND and OR nodes, not leaves */

+

+#ifdef __USE_PROTOS

+void MR_clearPredEntry(Predicate *p)

+#else

+void MR_clearPredEntry(p)

+  Predicate     *p;

+#endif

+{

+   if (p == NULL) return;

+   MR_clearPredEntry(p->down);

+   MR_clearPredEntry(p->right);

+   if (p->down != NULL) p->predEntry=NULL;

+}

+

+

+#ifdef __USE_PROTOS

+void MR_orphanRules(FILE *f)

+#else

+void MR_orphanRules(f)

+  FILE      *f;

+#endif

+{

+	set         a;

+    Junction    *p;

+    unsigned    e;

+    RuleEntry   *re;

+

+	a=empty;

+

+    if (! InfoO) return;

+

+	for (p=SynDiag; p!=NULL; p = (Junction *)p->p2)	{

+      if ( (Junction *) (p->end)->p1 == NULL) {

+        re=(RuleEntry *) hash_get(Rname,p->rname);

+        require (re != NULL,"RuleEntry == NULL");

+		set_orel(re->rulenum, &a);

+      }

+  	}

+

+    if (set_deg(a) > 1) {

+      fprintf(f,"note: Start rules: {");

+      for (; !set_nil(a); set_rm(e,a)) {

+        e=set_int(a);

+        fprintf(f," %s",RulePtr[e]->rname);

+      };

+      fprintf(f," }\n");

+    };

+	set_free( a );

+}

+

+/*  merge (X Y) and (X) to create (X)  */

+

+static int      *mergeChain;

+static Tree     *mergeTree;

+

+#ifdef __USE_PROTOS

+Tree *MR_merge_tree_contexts_client(Tree *t,int chain[])

+#else

+Tree *MR_merge_tree_contexts_client(t,chain)

+  Tree  *t;

+  int   chain[];

+#endif

+{

+  if (t == NULL)  return NULL;

+  if (chain[0] == 0) {

+    Tree    *u=t->right;

+    t->right=NULL;

+    Tfree(t);

+    return MR_merge_tree_contexts_client(u,&chain[0]);

+  }

+  if (chain[0] == t->token) {

+    t->down=MR_merge_tree_contexts_client(t->down,&chain[1]);

+  };

+  t->right=MR_merge_tree_contexts_client(t->right,&chain[0]);

+  return t;

+}

+

+#ifdef __USE_PROTOS

+void MR_iterateOverTreeContexts(Tree *t,int chain[])

+#else

+void MR_iterateOverTreeContexts(t,chain)

+  Tree          *t;

+  int           chain[];

+#endif

+{

+  if (t == NULL) return;

+  chain[0]=t->token;

+  if (t->down != NULL) {

+    MR_iterateOverTreeContexts(t->down,&chain[1]);

+  } else {

+    MR_merge_tree_contexts_client(mergeTree,mergeChain);

+  };

+  MR_iterateOverTreeContexts(t->right,&chain[0]);

+  chain[0]=0;

+}

+

+#ifdef __USE_PROTOS

+Tree *MR_merge_tree_contexts(Tree *t)

+#else

+Tree *MR_merge_tree_contexts(t)

+  Tree  *t;

+#endif

+{

+    int     h=MR_max_height_of_tree(t);

+

+    mergeTree=t;

+    mergeChain=(int *) calloc(h+1,sizeof(int));

+    require (mergeChain != NULL,"MR_merge_tree_contexts: can't alloc chain");

+    MR_iterateOverTreeContexts(t,mergeChain);

+    t=tshrink(t);

+    t=tflatten(t);

+    t=tleft_factor(t);

+    free ( (char *) mergeChain);

+    mergeChain=NULL;

+    return t;

+}

+

+#ifdef __USE_PROTOS

+Tree *MR_compute_pred_tree_context(Predicate *p)

+#else

+Tree *MR_compute_pred_tree_context(p)

+  Predicate *p;

+#endif

+{

+  Tree  *t;

+

+  t=MR_compute_pred_tree_ctxXX(p);

+  MR_merge_tree_contexts(t);

+  return t;

+}

+

+#ifdef __USE_PROTOS

+void MR_guardPred_plainSet(ActionNode *anode,Predicate *pred)

+#else

+void MR_guardPred_plainSet(anode,pred)

+  ActionNode    *anode;

+  Predicate     *pred;

+#endif

+{

+  Junction      *j;

+  Predicate     *workPred;

+  set           maskSet;

+

+  maskSet=empty;

+

+  if (!MRhoisting) return;

+

+  /* it doesn't really matter whether the predicate has

+     depth k=1 or k>1 because we're not really looking

+     at the predicate itself, just the stuff "behind"

+     the predicate.

+  */

+

+  /* shouldn't have to worry about REACHing off the end

+     of the rule containing the predicate because the

+     Rule->end->halt should have been set already by the

+     the code which handles RuleRef nodes.

+

+     We don't want to REACH off the end of the rule because

+     this would give the "global" follow context rather than

+     the "local" context.

+

+         r1a : (A)? => <<p>>? r2 (A|B)

+         r1b : (A)? => <<p>>? r2 (A|C)

+         r2  : ();

+

+     For r1a we want follow of predicate = {A B}

+             we want plainSet = {B}

+     For r1b we want follow of predicate = {A C}

+             we want plainSet = {C}

+  */

+

+  require (anode->next->ntype == nJunction,"MR_guardpred_plainSet not Junction");

+  j=(Junction *)(anode->next);

+

+  workPred=predicate_dup_without_context(pred);

+  workPred->k=1;

+  workPred->scontext[1]=MR_First(1,j, &(workPred->completionSet) );

+  MR_complete_predicates(1,workPred);

+  if (pred->k == 1) {

+    maskSet=pred->scontext[1];

+  } else {

+    MR_projectTreeOntoSet(pred->tcontext,1,&maskSet);

+  }

+  pred->plainSet=set_dif(workPred->scontext[1],maskSet);

+  predicate_free(workPred);

+}

+

+/*******************************************************************************/

+

+static Tree *       suppressTree;

+static int *        suppressChain;  /* element 0 not used */

+static set *        suppressSets;

+static Node *       suppressNode;

+static int          suppressChainLength;

+int                 MR_SuppressSearch=0;

+static int          suppressSucceeded;

+static Predicate *  suppressPredicate;

+

+#ifdef __USE_PROTOS

+int MR_isChain(Tree *t)

+#else

+int MR_isChain(t)

+  Tree  *t;

+#endif

+{

+  Tree  *u;

+

+  for (u=t; u != NULL; u=u->down) {

+    if (u->right != NULL) return 0;

+  }

+  return 1;

+}

+

+#ifdef __USE_PROTOS

+int MR_suppressK_client(Tree *tree,int tokensInChain[])

+#else

+int MR_suppressK_client(tree,tokensInChain)

+  Tree      *tree;

+  int       tokensInChain[];

+#endif

+{

+  int       i;

+  set       *save_fset;

+  int       save_ConstrainSearch;

+  set       incomplete;

+  Tree      *t;

+

+  suppressSucceeded=0;  /* volatile */

+

+  if (suppressSets == NULL) {

+    suppressSets=(set *) calloc (CLL_k+1,sizeof(set));

+    require (suppressSets != NULL,"MR_suppressK_client: suppressSets alloc");

+  };

+

+  for (suppressChainLength=1;

+       tokensInChain[suppressChainLength+1] != 0;

+       suppressChainLength++) {};

+

+  require (suppressChainLength != 0,"MR_suppressK_client: chain empty");

+

+  for (i=1 ; i <= suppressChainLength ; i++) {

+    set_clr(suppressSets[i]);

+    set_orel( (unsigned) tokensInChain[i],

+                              &suppressSets[i]);

+  };

+

+  save_fset=fset;

+  save_ConstrainSearch=ConstrainSearch;

+

+  fset=suppressSets;

+

+  MR_SuppressSearch=1;

+  MR_AmbSourceSearch=1;

+  MR_MaintainBackTrace=1;

+  ConstrainSearch=1;

+

+  maxk = suppressChainLength;

+

+  incomplete=empty;

+  t=NULL;

+

+/***  constrain = &(fset[1]); ***/

+

+  MR_setConstrainPointer(&(fset[1]));	/* MR18 */

+  

+  MR_pointerStackReset(&MR_BackTraceStack);

+

+  TRAV(suppressNode,maxk,&incomplete,t);

+

+  Tfree(t);

+

+  require (set_nil(incomplete),"MR_suppressK_client TRAV incomplete");

+  require (MR_BackTraceStack.count == 0,

+            "MR_suppressK_client: MR_BackTraceStack.count != 0");

+  set_free(incomplete);

+

+  ConstrainSearch=save_ConstrainSearch;

+  fset=save_fset;

+

+  MR_AmbSourceSearch=0;

+  MR_MaintainBackTrace=0;

+  MR_SuppressSearch=0;

+  return suppressSucceeded;

+}

+

+#ifdef __USE_PROTOS

+Tree * MR_iterateOverTreeSuppressK(Tree *t,int chain[])

+#else

+Tree * MR_iterateOverTreeSuppressK(t,chain)

+  Tree          *t;

+  int           chain[];

+#endif

+{

+  if (t == NULL) return NULL;

+  t->right=MR_iterateOverTreeSuppressK(t->right,&chain[0]);

+  chain[0]=t->token;

+  if (t->down != NULL) {

+    t->down=MR_iterateOverTreeSuppressK(t->down,&chain[1]);

+    if (t->down == NULL) {

+      Tree *u=t->right;

+      t->right=NULL;

+      Tfree(t);

+      chain[0]=0;

+      return u;

+    };

+  } else {

+    MR_suppressK_client(suppressTree,suppressChain);

+    if (suppressSucceeded) {

+      Tree  *u=t->right;

+      t->right=NULL;

+      Tfree(t);

+      chain[0]=0;

+      return u;

+    };

+  };

+  chain[0]=0;

+  return t;

+}

+

+/* @@@ */

+

+#ifdef __USE_PROTOS

+Predicate * MR_suppressK(Node *j,Predicate *p)

+#else

+Predicate * MR_suppressK(j,p)

+  Node          *j;

+  Predicate     *p;

+#endif

+{

+  Predicate     *result;

+  int           guardPred=0;

+  int           ampersandPred=0;

+  Node          *nodePrime;

+

+  if (! MRhoistingk) {

+     return p;

+  }

+

+  if (! MRhoisting) return p;

+  if (CLL_k == 1) return p;

+

+  if (suppressChain == NULL) {

+    suppressChain=(int *) calloc(CLL_k+2,sizeof(int));

+    require (suppressChain != NULL,"MR_suppressK: can't allocate chain");

+  }

+

+  if (p == NULL) return NULL;

+

+  if (j->ntype == nJunction) {

+    nodePrime=(Node *) MR_junctionWithoutP2( (Junction *) j);

+  } else {

+    nodePrime=j;

+  };

+

+  p->down=MR_suppressK(j,p->down);

+  p->right=MR_suppressK(j,p->right);

+  if (p->down != NULL) {

+    result=p;

+    goto EXIT;

+  };

+  if (p->k == 1) {

+    result=p;

+    goto EXIT;

+  };

+

+  if (p->source != NULL) {

+    if (p->source->guardpred != NULL) guardPred=1;

+    if (p->source->ampersandPred != NULL) ampersandPred=1;

+  }

+

+  suppressPredicate=p;

+  suppressNode=nodePrime;   /* was j*/

+

+  suppressTree=p->tcontext;

+

+  if (guardPred || ampersandPred) {

+    p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);

+    if (p->tcontext == NULL) {

+      predicate_free(p);

+      result=NULL;

+      goto EXIT;

+    };

+  } else {

+    if (MR_isChain(p->tcontext)) {

+      p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);

+      if (p->tcontext == NULL) {

+        predicate_free(p);

+        result=NULL;

+        goto EXIT;

+      };

+    }

+  }

+  result=p;

+EXIT:

+  return result;

+}

+

+#ifdef __USE_PROTOS

+void MR_suppressSearchReport(void)

+#else

+void MR_suppressSearchReport()

+#endif

+{

+  int       i;

+  Node      *p;

+  TokNode   *tn;

+  int       depth;

+  set       setAnd;

+

+  /* number of tokens in back trace stack matches length of chain */

+

+  depth=0;

+  for (i=0; i < MR_BackTraceStack.count ; i++) {

+    p=(Node *) MR_BackTraceStack.data[i];

+    if (p->ntype == nToken) depth++;

+  };

+

+  require (depth == suppressChainLength,"depth > suppressChainLength");

+

+  /* token codes match chain */

+

+  depth=0;

+  for (i=0; i < MR_BackTraceStack.count ; i++) {

+    p=(Node *) MR_BackTraceStack.data[i];

+    if (p->ntype != nToken) continue;

+    tn=(TokNode *) p;

+    depth++;

+    if (set_nil(tn->tset)) {

+      require(set_el( (unsigned) tn->token,fset[depth]),

+        "MR_suppressSearchReport: no match to #token in chain");

+    } else {

+      setAnd=set_and(fset[depth],tn->tset);

+      require(!set_nil(setAnd),

+        "MR_suppressSearchReport: no match to #token set in chain");

+      set_free(setAnd);

+    };

+  };

+

+  /* have a match - now remove it from the predicate */

+

+  suppressSucceeded=1;

+

+  if (suppressSucceeded) {

+    fprintf(output,"\n");

+    fprintf(output,"#if 0\n");

+    fprintf(output,"\n");

+    fprintf(output,"Part (or all) of predicate with depth > 1 suppressed by ");

+        fprintf(output,"alternative without predicate\n\n");

+    MR_dumpPred(suppressPredicate,1);

+    fprintf(output,"The token sequence which is suppressed:");

+    fprintf(output," (");

+    for (i=1; i <= suppressChainLength; i++) {

+      fprintf(output," %s",TerminalString(suppressChain[i]));

+    };

+    fprintf(output," )\n");

+    fprintf(output,"The sequence of references which generate that sequence of tokens:\n\n");

+

+    MR_backTraceDumpItemReset();

+

+    for (i=0; i < MR_BackTraceStack.count ; i++) {

+       MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);

+    };

+    fprintf(output,"\n");

+    fprintf(output,"#endif\n");

+  }

+}

+

+#ifdef __USE_PROTOS

+void MR_markCompromisedRule(Node *n)

+#else

+void MR_markCompromisedRule(n)

+  Node *n;

+#endif

+{

+  RuleEntry     *q;

+  Node          *mark=NULL;

+  Junction      *j;

+

+  if (n->ntype == nRuleRef) {

+    mark=(Node *) MR_ruleReferenced( (RuleRefNode *) n);

+  } else if (n->ntype == nToken) {

+    mark=n;

+  } else if (n->ntype == nJunction) {

+    j=(Junction *)n;

+    switch (j->jtype) {

+      case aOptBlk:

+      case aLoopBlk:

+      case RuleBlk:

+      case EndRule:

+      case aPlusBlk:

+      case aLoopBegin:

+        mark=n;

+        break;

+      default:

+        break;

+    };

+  }

+

+  if (mark == NULL) return;

+

+  require (RulePtr != NULL,"RulePtr not initialized");

+

+  q = (RuleEntry *) hash_get(Rname,mark->rname);

+  require (q != NULL,"RuleEntry not found");

+  set_orel(q->rulenum,&MR_CompromisedRules);

+}

+

+#ifdef __USE_PROTOS

+void MR_alphaBetaTraceReport(void)

+#else

+void MR_alphaBetaTraceReport()

+#endif

+{

+  int       i;

+

+  if (! AlphaBetaTrace) return;

+

+  MR_AlphaBetaMessageCount++;

+

+  fprintf(output,"\n");

+  fprintf(output,"#if 0\n");

+  fprintf(output,"\n");

+  fprintf(output,"Trace of references leading to attempt to compute the follow set of\n");

+  fprintf(output,"alpha in an \"(alpha)? beta\" block. It is not possible for antlr to\n");

+  fprintf(output,"compute this follow set because it is not known what part of beta has\n");

+  fprintf(output,"already been matched by alpha and what part remains to be matched.\n");

+  fprintf(output,"\n");

+  fprintf(output,"Rules which make use of the incorrect follow set will also be incorrect\n");

+  fprintf(output,"\n");

+

+  MR_backTraceDumpItemReset();

+

+  for (i=0; i < MR_BackTraceStack.count ; i++) {

+     MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);

+     if (i < MR_BackTraceStack.count-1) {

+        MR_markCompromisedRule( (Node *) MR_BackTraceStack.data[i]);

+     };

+  };

+  fprintf(output,"\n");

+  fprintf(output,"#endif\n");

+}

+

+#ifdef __USE_PROTOS

+void MR_dumpRuleSet(set s)

+#else

+void MR_dumpRuleSet(s)

+  set   s;

+#endif

+{

+    unsigned    *cursor;

+    unsigned    *origin=set_pdq(s);

+

+    require(origin != NULL,"set_pdq failed");

+

+    if (RulePtr == NULL) {

+      fprintf(stderr,"RulePtr[] not yet initialized");

+    } else {

+      for (cursor=origin; *cursor != nil ; cursor++) {

+/****   if (cursor != origin) fprintf(stderr,","); ****/

+        fprintf(stderr,"    %s",RulePtr[*cursor]->rname);

+        fprintf(stderr,"\n");

+      };

+      free( (char *) origin);

+    };

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/parser.dlg b/edk2/Tools/Source/TianoTools/Pccts/antlr/parser.dlg
new file mode 100644
index 0000000..8c43dff
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/parser.dlg
@@ -0,0 +1,1387 @@
+<<

+/* parser.dlg -- DLG Description of scanner

+ *

+ * Generated from: antlr.g

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include "pcctscfg.h"

+#include "set.h"

+#include <ctype.h>

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#define zzcr_attr(attr,tok,t)

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+LOOKAHEAD

+

+void

+#ifdef __USE_PROTOS

+zzerraction(void)

+#else

+zzerraction()

+#endif

+{

+	(*zzerr)("invalid token");

+	zzadvance();

+	zzskip();

+}

+>>

+

+<<%%lexaction

+

+/* maintained, but not used for now */

+set AST_nodes_refd_in_actions = set_init;

+int inAlt = 0;

+set attribsRefdFromAction = set_init; /* MR20 */

+int UsedOldStyleAttrib = 0;

+int UsedNewStyleLabel = 0;

+#ifdef __USE_PROTOS

+char *inline_set(char *);

+#else

+char *inline_set();

+#endif

+

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	    */

+/* MR1					in DLG action			                    */

+

+int tokenActionActive=0;                                            /* MR1 */

+

+  

+>>

+

+<<%%lexaction

+

+

+static char *

+#ifdef __USE_PROTOS

+getFileNameFromTheLineInfo(char *toStr, char *fromStr)

+#else

+getFileNameFromTheLineInfo(toStr, fromStr)

+char *toStr, *fromStr;

+#endif

+{

+  int i, j, k;

+  

+  if (!fromStr || !toStr) return toStr;

+  

+  /* find the first " */

+  

+  for (i=0;

+  (i<MaxFileName) &&

+  (fromStr[i] != '\n') &&

+  (fromStr[i] != '\r') &&

+  (fromStr[i] != '\"');

+  i++) /* nothing */ ;

+  

+  if ( (i == MaxFileName) ||

+  (fromStr[i] == '\n') ||

+  (fromStr[i] == '\r') ) {

+  return toStr;

+}

+

+  /* find the second " */

+

+  for (j=i+1;

+(j<MaxFileName) &&

+(fromStr[j] != '\n') &&

+(fromStr[j] != '\r') &&

+(fromStr[j] != '\"');

+j++) /* nothing */ ;

+

+  if ((j == MaxFileName) ||

+(fromStr[j] == '\n') ||

+(fromStr[j] == '\r') ) {

+  return toStr;

+}

+

+  /* go back until the last / or \ */

+

+  for (k=j-1;

+(fromStr[k] != '\"') &&

+(fromStr[k] != '/') &&

+(fromStr[k] != '\\');

+k--) /* nothing */ ;

+

+  /* copy the string after " / or \ into toStr */

+

+  for (i=k+1; fromStr[i] != '\"'; i++) {

+toStr[i-k-1] = fromStr[i];

+}

+

+  toStr[i-k-1] = '\0';

+

+  return toStr;

+}

+

+/* MR14 end of a block to support #line in antlr source code */

+

+  

+>>

+

+<<%%lexaction

+

+#ifdef __USE_PROTOS

+void mark_label_used_in_sem_pred(LabelEntry *le)              /* MR10 */

+#else

+void mark_label_used_in_sem_pred(le)                          /* MR10 */

+LabelEntry    *le;

+#endif

+{

+  TokNode   *tn;

+  require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");

+  tn=(TokNode *)le->elem;

+  require (tn->label != 0,"mark_label_used... TokNode has no label");

+  tn->label_used_in_semantic_pred=1;

+}

+>>

+

+

+%%START

+

+@

+	<<

+		NLA = Eof;

+    /* L o o k  F o r  A n o t h e r  F i l e */

+    {

+      FILE *new_input;

+      new_input = NextFile();

+      if ( new_input == NULL ) { NLA=Eof; return; }

+      fclose( input );

+      input = new_input;

+      zzrdstream( input );

+      zzskip();	/* Skip the Eof (@) char i.e continue */

+    }

+	>>

+

+[\t\ ]+

+	<<

+		NLA = 76;

+    zzskip();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 77;

+    zzline++; zzskip();   

+	>>

+

+\[

+	<<

+		NLA = 78;

+    zzmode(ACTIONS); zzmore();

+    istackreset();

+    pushint(']');   

+	>>

+

+\<\<

+	<<

+		NLA = 79;

+    action_file=CurFile; action_line=zzline;

+    zzmode(ACTIONS); zzmore();

+    list_free(&CurActionLabels,0);       /* MR10 */

+    numericActionLabel=0;                /* MR10 */

+    istackreset();

+    pushint('>');   

+	>>

+

+\"

+	<<

+		NLA = 80;

+    zzmode(STRINGS); zzmore();   

+	>>

+

+/\*

+	<<

+		NLA = 81;

+    zzmode(COMMENTS); zzskip();   

+	>>

+

+\*/

+	<<

+		NLA = 82;

+    warn("Missing /*; found dangling */"); zzskip();   

+	>>

+

+//

+	<<

+		NLA = 83;

+    zzmode(CPP_COMMENTS); zzskip();   

+	>>

+

+#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)

+	<<

+		NLA = 84;

+    

+    zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();

+    getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);

+	>>

+

+#line ~[\n\r]* (\n|\r|\r\n)

+	<<

+		NLA = 85;

+    

+    zzline++; zzmore();

+	>>

+

+\>\>

+	<<

+		NLA = 86;

+    warn("Missing <<; found dangling \>\>"); zzskip();   

+	>>

+

+.

+	<<

+		NLA = WildCard;

+	>>

+

+\@

+	<<

+		NLA = 88;

+    FoundException = 1;		/* MR6 */

+    FoundAtOperator = 1;  

+	>>

+

+{\\}#pragma

+	<<

+		NLA = Pragma;

+	>>

+

+{\\}#FirstSetSymbol

+	<<

+		NLA = FirstSetSymbol;

+	>>

+

+{\\}#header

+	<<

+		NLA = 94;

+	>>

+

+{\\}#first

+	<<

+		NLA = 95;

+	>>

+

+{\\}#parser

+	<<

+		NLA = 96;

+	>>

+

+{\\}#tokdefs

+	<<

+		NLA = 97;

+	>>

+

+\}

+	<<

+		NLA = 98;

+	>>

+

+class

+	<<

+		NLA = 99;

+	>>

+

+\{

+	<<

+		NLA = 102;

+	>>

+

+!

+	<<

+		NLA = 103;

+	>>

+

+\<

+	<<

+		NLA = 104;

+	>>

+

+\>

+	<<

+		NLA = 105;

+	>>

+

+:

+	<<

+		NLA = 106;

+	>>

+

+;

+	<<

+		NLA = 107;

+	>>

+

+{\\}#lexaction

+	<<

+		NLA = 108;

+	>>

+

+{\\}#lexmember

+	<<

+		NLA = 109;

+	>>

+

+{\\}#lexprefix

+	<<

+		NLA = 110;

+	>>

+

+{\\}#pred

+	<<

+		NLA = 111;

+	>>

+

+\|\|

+	<<

+		NLA = 112;

+	>>

+

+&&

+	<<

+		NLA = 113;

+	>>

+

+\(

+	<<

+		NLA = 114;

+	>>

+

+\)

+	<<

+		NLA = 115;

+	>>

+

+{\\}#lexclass

+	<<

+		NLA = 116;

+	>>

+

+{\\}#errclass

+	<<

+		NLA = 117;

+	>>

+

+{\\}#tokclass

+	<<

+		NLA = 118;

+	>>

+

+..

+	<<

+		NLA = 119;

+	>>

+

+{\\}#token

+	<<

+		NLA = 120;

+	>>

+

+=

+	<<

+		NLA = 121;

+	>>

+

+[0-9]+

+	<<

+		NLA = 122;

+	>>

+

+\|

+	<<

+		NLA = 123;

+	>>

+

+\~

+	<<

+		NLA = 124;

+	>>

+

+^

+	<<

+		NLA = 125;

+	>>

+

+approx

+	<<

+		NLA = 126;

+	>>

+

+LL\(1\)

+	<<

+		NLA = 127;

+	>>

+

+LL\(2\)

+	<<

+		NLA = 128;

+	>>

+

+\*

+	<<

+		NLA = 129;

+	>>

+

+\+

+	<<

+		NLA = 130;

+	>>

+

+?

+	<<

+		NLA = 131;

+	>>

+

+=>

+	<<

+		NLA = 132;

+	>>

+

+exception

+	<<

+		NLA = 133;

+	>>

+

+default

+	<<

+		NLA = 134;

+	>>

+

+catch

+	<<

+		NLA = 135;

+	>>

+

+[a-z] [A-Za-z0-9_]*

+	<<

+		NLA = NonTerminal;

+    

+    while ( zzchar==' ' || zzchar=='\t' ) {

+      zzadvance();

+    }

+    if ( zzchar == ':' && inAlt ) NLA = LABEL;

+	>>

+

+[A-Z] [A-Za-z0-9_]*

+	<<

+		NLA = TokenTerm;

+    

+    while ( zzchar==' ' || zzchar=='\t' ) {

+      zzadvance();

+    }

+    if ( zzchar == ':' && inAlt ) NLA = LABEL;

+	>>

+

+{\\}#[A-Za-z0-9_]*

+	<<

+		NLA = 136;

+    warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip();   

+	>>

+

+

+%%STRINGS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\"

+	<<

+		NLA = QuotedTerm;

+    zzmode(START);   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 3;

+    

+    zzline++;

+    warn("eoln found in string");

+    zzskip();

+	>>

+

+\\(\n|\r|\r\n)

+	<<

+		NLA = 4;

+    zzline++; zzmore();   

+	>>

+

+\\~[]

+	<<

+		NLA = 5;

+    zzmore();   

+	>>

+

+~[\n\r\"\\]+

+	<<

+		NLA = 6;

+    zzmore();   

+	>>

+

+

+%%ACTION_STRINGS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\"

+	<<

+		NLA = 7;

+    zzmode(ACTIONS); zzmore();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 8;

+    

+    zzline++;

+    warn("eoln found in string (in user action)");

+    zzskip();

+	>>

+

+\\(\n|\r|\r\n)

+	<<

+		NLA = 9;

+    zzline++; zzmore();   

+	>>

+

+\\~[]

+	<<

+		NLA = 10;

+    zzmore();   

+	>>

+

+~[\n\r\"\\]+

+	<<

+		NLA = 11;

+    zzmore();   

+	>>

+

+

+%%ACTION_CHARS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+'

+	<<

+		NLA = 12;

+    zzmode(ACTIONS); zzmore();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 13;

+    

+    zzline++;

+    warn("eoln found in char literal (in user action)");

+    zzskip();

+	>>

+

+\\~[]

+	<<

+		NLA = 14;

+    zzmore();   

+	>>

+

+~[\n\r'\\]+

+	<<

+		NLA = 15;

+    zzmore();   

+	>>

+

+

+%%ACTION_COMMENTS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\*/

+	<<

+		NLA = 16;

+    zzmode(ACTIONS); zzmore();   

+	>>

+

+\*

+	<<

+		NLA = 17;

+    zzmore();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 18;

+    zzline++; zzmore(); DAWDLE;   

+	>>

+

+~[\n\r\*]+

+	<<

+		NLA = 19;

+    zzmore();   

+	>>

+

+

+%%TOK_DEF_COMMENTS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\*/

+	<<

+		NLA = 20;

+    zzmode(PARSE_ENUM_FILE);

+    zzmore();   

+	>>

+

+\*

+	<<

+		NLA = 21;

+    zzmore();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 22;

+    zzline++; zzmore(); DAWDLE;   

+	>>

+

+~[\n\r\*]+

+	<<

+		NLA = 23;

+    zzmore();   

+	>>

+

+

+%%TOK_DEF_CPP_COMMENTS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 24;

+    zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE;   

+	>>

+

+~[\n\r]+

+	<<

+		NLA = 25;

+    zzskip();   

+	>>

+

+

+%%ACTION_CPP_COMMENTS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 26;

+    zzline++; zzmode(ACTIONS); zzmore(); DAWDLE;   

+	>>

+

+~[\n\r]+

+	<<

+		NLA = 27;

+    zzmore();   

+	>>

+

+

+%%CPP_COMMENTS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 28;

+    zzline++; zzmode(START); zzskip(); DAWDLE;   

+	>>

+

+~[\n\r]+

+	<<

+		NLA = 29;

+    zzskip();   

+	>>

+

+

+%%COMMENTS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\*/

+	<<

+		NLA = 30;

+    zzmode(START); zzskip();   

+	>>

+

+\*

+	<<

+		NLA = 31;

+    zzskip();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 32;

+    zzline++; zzskip(); DAWDLE;   

+	>>

+

+~[\n\r\*]+

+	<<

+		NLA = 33;

+    zzskip();   

+	>>

+

+

+%%ACTIONS

+

+@

+	<<

+		NLA = Eof;

+	>>

+

+\>\>

+	<<

+		NLA = Action;

+    /* these do not nest */

+    zzmode(START);

+    NLATEXT[0] = ' ';

+    NLATEXT[1] = ' ';

+    zzbegexpr[0] = ' ';

+    zzbegexpr[1] = ' ';

+    if ( zzbufovf ) {

+      err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));

+    }

+    

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	*/

+    /* MR1					in DLG action			*/

+    /* MR1			Doesn't matter what kind of action it is - reset*/

+    

+			      tokenActionActive=0;		 /* MR1 */

+	>>

+

+\>\>?

+	<<

+		NLA = Pred;

+    /* these do not nest */

+    zzmode(START);

+    NLATEXT[0] = ' ';

+    NLATEXT[1] = ' ';

+    zzbegexpr[0] = '\0';

+    if ( zzbufovf ) {

+      err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));

+    };

+#ifdef __cplusplus__

+    /* MR10 */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+#ifdef __STDC__

+    /* MR10 */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+#ifdef __USE_PROTOS

+    /* MRxx */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+    /* MR10 */                    list_apply(CurActionLabels,mark_label_used_in_sem_pred);

+#endif

+#endif

+#endif

+	>>

+

+\]

+	<<

+		NLA = PassAction;

+    if ( topint() == ']' ) {

+      popint();

+      if ( istackempty() )	/* terminate action */

+      {

+        zzmode(START);

+        NLATEXT[0] = ' ';

+        zzbegexpr[0] = ' ';

+        if ( zzbufovf ) {

+          err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));

+        }

+      }

+      else {

+        /* terminate $[..] and #[..] */

+        if ( GenCC ) zzreplstr("))");

+        else zzreplstr(")");

+        zzmore();

+      }

+    }

+    else if ( topint() == '|' ) { /* end of simple [...] */

+      popint();

+      zzmore();

+    }

+    else zzmore();

+	>>

+

+consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)

+	<<

+		NLA = 37;

+    

+    zzmore();

+    zzreplstr(inline_set(zzbegexpr+

+    strlen("consumeUntil(")));

+	>>

+

+consumeUntil\( ~[\)]+ \)

+	<<

+		NLA = 38;

+    zzmore();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 39;

+    zzline++; zzmore(); DAWDLE;   

+	>>

+

+\>

+	<<

+		NLA = 40;

+    zzmore();   

+	>>

+

+$

+	<<

+		NLA = 41;

+    zzmore();   

+	>>

+

+$$

+	<<

+		NLA = 42;

+    if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}

+    else err("$$ use invalid in C++ mode");   

+	>>

+

+$\[\]

+	<<

+		NLA = 43;

+    if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}

+    else err("$[] use invalid in C++ mode");   

+	>>

+

+$\[

+	<<

+		NLA = 44;

+    

+    pushint(']');

+    if ( !GenCC ) zzreplstr("zzconstr_attr(");

+    else err("$[..] use invalid in C++ mode");

+    zzmore();

+	>>

+

+$[0-9]+

+	<<

+		NLA = 45;

+    {

+      static char buf[100];

+      numericActionLabel=1;       /* MR10 */

+      if ( strlen(zzbegexpr)>(size_t)85 )

+      fatal("$i attrib ref too big");

+      set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);

+      if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",

+      BlkLevel-1,zzbegexpr+1);

+      else sprintf(buf,"_t%d%s",

+      BlkLevel-1,zzbegexpr+1);

+      zzreplstr(buf);

+      zzmore();

+      UsedOldStyleAttrib = 1;

+      if ( UsedNewStyleLabel )

+      err("cannot mix old-style $i with new-style labels");

+    }

+	>>

+

+$[0-9]+.

+	<<

+		NLA = 46;

+    {

+      static char buf[100];

+      numericActionLabel=1;       /* MR10 */

+      if ( strlen(zzbegexpr)>(size_t)85 )

+      fatal("$i.field attrib ref too big");

+      zzbegexpr[strlen(zzbegexpr)-1] = ' ';

+      set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);

+      if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",

+      BlkLevel-1,zzbegexpr+1);

+      else sprintf(buf,"_t%d%s.",

+      BlkLevel-1,zzbegexpr+1);

+      zzreplstr(buf);

+      zzmore();

+      UsedOldStyleAttrib = 1;

+      if ( UsedNewStyleLabel )

+      err("cannot mix old-style $i with new-style labels");

+    }

+	>>

+

+$[0-9]+.[0-9]+

+	<<

+		NLA = 47;

+    {

+      static char buf[100];

+      static char i[20], j[20];

+      char *p,*q;

+      numericActionLabel=1;       /* MR10 */

+      if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");

+      for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {

+        if ( q == &i[20] )

+        fatalFL("i of $i.j attrib ref too big",

+        FileStr[CurFile], zzline );

+        *q++ = *p;

+      }

+      *q = '\0';

+      for (p++, q= &j[0]; *p!='\0'; p++) {

+        if ( q == &j[20] )

+        fatalFL("j of $i.j attrib ref too big",

+        FileStr[CurFile], zzline );

+        *q++ = *p;

+      }

+      *q = '\0';

+      if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);

+      else sprintf(buf,"_t%s%s",i,j);

+      zzreplstr(buf);

+      zzmore();

+      UsedOldStyleAttrib = 1;

+      if ( UsedNewStyleLabel )

+      err("cannot mix old-style $i with new-style labels");

+    }

+	>>

+

+$[_a-zA-Z][_a-zA-Z0-9]*

+	<<

+		NLA = 48;

+    { static char buf[300]; LabelEntry *el;

+      zzbegexpr[0] = ' ';

+      if ( CurRule != NULL &&

+      strcmp(CurRule, &zzbegexpr[1])==0 ) {

+        if ( !GenCC ) zzreplstr("zzaRet");

+      }

+      else if ( CurRetDef != NULL &&

+      strmember(CurRetDef, &zzbegexpr[1])) {

+        if ( hasMultipleOperands( CurRetDef ) ) {

+          require (strlen(zzbegexpr)<=(size_t)285,

+          "$retval attrib ref too big");

+          sprintf(buf,"_retv.%s",&zzbegexpr[1]);

+          zzreplstr(buf);

+        }

+        else zzreplstr("_retv");

+      }

+      else if ( CurParmDef != NULL &&

+      strmember(CurParmDef, &zzbegexpr[1])) {

+      ;

+    }

+    else if ( Elabel==NULL ) {

+    { err("$-variables in actions outside of rules are not allowed"); }

+  } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {

+  /* MR10 */

+  /* MR10 */                      /* element labels might exist without an elem when */

+  /* MR10 */                      /*  it is a forward reference (to a rule)          */

+  /* MR10 */

+  /* MR10 */						if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )

+  /* MR10 */							{ err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }

+  /* MR10 */

+  /* MR10 */						if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {

+  /* MR10 */                          err("You can no longer use attributes returned by rules when also using ASTs");

+  /* MR10 */                          err("   Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")");

+  /* MR10 */                      };

+  /* MR10 */

+  /* MR10 */                      /* keep track of <<... $label ...>> for semantic predicates in guess mode */

+  /* MR10 */                      /* element labels contain pointer to the owners node                      */

+  /* MR10 */

+  /* MR10 */                      if (el->elem != NULL && el->elem->ntype == nToken) {

+  /* MR10 */                        list_add(&CurActionLabels,el);

+  /* MR10 */                      };

+}

+else

+warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));

+}

+zzmore();

+	>>

+

+#0

+	<<

+		NLA = 49;

+    zzreplstr("(*_root)"); zzmore(); chkGTFlag();   

+	>>

+

+#\[\]

+	<<

+		NLA = 50;

+    if ( GenCC ) {

+      if (NewAST) zzreplstr("(newAST)");

+      else zzreplstr("(new AST)");}

+    else {zzreplstr("zzastnew()");} zzmore();

+    chkGTFlag();

+	>>

+

+#\(\)

+	<<

+		NLA = 51;

+    zzreplstr("NULL"); zzmore(); chkGTFlag();   

+	>>

+

+#[0-9]+

+	<<

+		NLA = 52;

+    {

+      static char buf[100];

+      if ( strlen(zzbegexpr)>(size_t)85 )

+      fatal("#i AST ref too big");

+      if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);

+      else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);

+      zzreplstr(buf);

+      zzmore();

+      set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);

+      chkGTFlag();

+    }

+	>>

+

+#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)

+	<<

+		NLA = 53;

+    

+    zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();

+    getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);

+	>>

+

+#line ~[\n\r]* (\n|\r|\r\n)

+	<<

+		NLA = 54;

+    

+    zzline++; zzmore();

+	>>

+

+#[_a-zA-Z][_a-zA-Z0-9]*

+	<<

+		NLA = 55;

+    

+    if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||

+    strcmp(zzbegexpr, "#if")==0 ||

+    strcmp(zzbegexpr, "#else")==0 ||

+    strcmp(zzbegexpr, "#endif")==0 ||

+    strcmp(zzbegexpr, "#ifndef")==0 ||

+    strcmp(zzbegexpr, "#define")==0 ||

+    strcmp(zzbegexpr, "#pragma")==0 ||

+    strcmp(zzbegexpr, "#undef")==0 ||

+    strcmp(zzbegexpr, "#import")==0 ||

+    strcmp(zzbegexpr, "#line")==0 ||

+    strcmp(zzbegexpr, "#include")==0 ||

+    strcmp(zzbegexpr, "#error")==0) )

+    {

+      static char buf[100];

+      sprintf(buf, "%s_ast", zzbegexpr+1);

+      /* MR27 */						list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));

+      zzreplstr(buf);

+      chkGTFlag();

+    }

+    zzmore();

+	>>

+

+#\[

+	<<

+		NLA = 56;

+    

+    pushint(']');

+    if ( GenCC ) {

+      if (NewAST) zzreplstr("(newAST(");

+      else zzreplstr("(new AST("); }

+    else zzreplstr("zzmk_ast(zzastnew(),");

+    zzmore();

+    chkGTFlag();

+	>>

+

+#\(

+	<<

+		NLA = 57;

+    

+    pushint('}');

+    if ( GenCC ) {

+      if (tmakeInParser) {

+        zzreplstr("tmake(");

+      }

+      else {

+        zzreplstr("ASTBase::tmake(");

+      }

+    }

+    else {

+      zzreplstr("zztmake(");

+    }

+    zzmore();

+    chkGTFlag();

+	>>

+

+#

+	<<

+		NLA = 58;

+    zzmore();   

+	>>

+

+\)

+	<<

+		NLA = 59;

+    

+    if ( istackempty() )

+    zzmore();

+    else if ( topint()==')' ) {

+      popint();

+    }

+    else if ( topint()=='}' ) {

+      popint();

+      /* terminate #(..) */

+      zzreplstr(", NULL)");

+    }

+    zzmore();

+	>>

+

+\[

+	<<

+		NLA = 60;

+    

+    pushint('|');	/* look for '|' to terminate simple [...] */

+    zzmore();

+	>>

+

+\(

+	<<

+		NLA = 61;

+    

+    pushint(')');

+    zzmore();

+	>>

+

+\\\]

+	<<

+		NLA = 62;

+    zzreplstr("]");  zzmore();   

+	>>

+

+\\\)

+	<<

+		NLA = 63;

+    zzreplstr(")");  zzmore();   

+	>>

+

+\\>

+	<<

+		NLA = 64;

+    if (! tokenActionActive) zzreplstr(">");	 /* MR1 */

+    zzmore();				         /* MR1 */

+	>>

+

+'

+	<<

+		NLA = 65;

+    zzmode(ACTION_CHARS); zzmore();  

+	>>

+

+\"

+	<<

+		NLA = 66;

+    zzmode(ACTION_STRINGS); zzmore();  

+	>>

+

+\\$

+	<<

+		NLA = 67;

+    zzreplstr("$");  zzmore();   

+	>>

+

+\\#

+	<<

+		NLA = 68;

+    zzreplstr("#");  zzmore();   

+	>>

+

+\\(\n|\r|\r\n)

+	<<

+		NLA = 69;

+    zzline++; zzmore();   

+	>>

+

+\\~[\]\)>$#]

+	<<

+		NLA = 70;

+    zzmore();   

+	>>

+

+/

+	<<

+		NLA = 71;

+    zzmore();   

+	>>

+

+/\*

+	<<

+		NLA = 72;

+    zzmode(ACTION_COMMENTS); zzmore();   

+	>>

+

+\*/

+	<<

+		NLA = 73;

+    warn("Missing /*; found dangling */ in action"); zzmore();   

+	>>

+

+//

+	<<

+		NLA = 74;

+    zzmode(ACTION_CPP_COMMENTS); zzmore();   

+	>>

+

+~[\n\r\)\(\\$#\>\]\[\"'/]+

+	<<

+		NLA = 75;

+    zzmore();   

+	>>

+

+

+%%PARSE_ENUM_FILE

+

+@

+	<<

+		NLA = Eof;

+    ;   

+	>>

+

+[\t\ ]+

+	<<

+		NLA = 137;

+    zzskip();   

+	>>

+

+\n|\r|\r\n

+	<<

+		NLA = 138;

+    zzline++; zzskip();   

+	>>

+

+//

+	<<

+		NLA = 139;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzmore();   

+	>>

+

+/\*

+	<<

+		NLA = 140;

+    zzmode(TOK_DEF_COMMENTS); zzskip();   

+	>>

+

+#ifdef

+	<<

+		NLA = 141;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	>>

+

+#if

+	<<

+		NLA = 142;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	>>

+

+#ifndef

+	<<

+		NLA = 143;

+    ;   

+	>>

+

+#else

+	<<

+		NLA = 144;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	>>

+

+#endif

+	<<

+		NLA = 145;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	>>

+

+#undef

+	<<

+		NLA = 146;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	>>

+

+#import

+	<<

+		NLA = 147;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	>>

+

+#define

+	<<

+		NLA = 149;

+	>>

+

+enum

+	<<

+		NLA = 151;

+	>>

+

+\{

+	<<

+		NLA = 152;

+	>>

+

+=

+	<<

+		NLA = 153;

+	>>

+

+,

+	<<

+		NLA = 154;

+	>>

+

+\}

+	<<

+		NLA = 155;

+	>>

+

+;

+	<<

+		NLA = 156;

+	>>

+

+[0-9]+

+	<<

+		NLA = INT;

+	>>

+

+[a-zA-Z_][_a-zA-Z0-9]*

+	<<

+		NLA = ID;

+	>>

+

+%%

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/pred.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/pred.c
new file mode 100644
index 0000000..eb11c4d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/pred.c
@@ -0,0 +1,821 @@
+/*

+ * pred.c -- source for predicate detection, manipulation

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "pcctscfg.h"

+#include "set.h"

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#include "dlgdef.h"

+#include <ctype.h>

+

+#ifdef __USE_PROTOS

+static void complete_context_sets(RuleRefNode *, Predicate *);

+static void complete_context_trees(RuleRefNode *, Predicate *);

+#else

+static void complete_context_sets();

+static void complete_context_trees();

+#endif

+

+char *PRED_AND_LIST = "AND";

+char *PRED_OR_LIST = "OR";

+

+/*

+ * In C mode, return the largest constant integer found as the

+ * sole argument to LATEXT(i).

+ *

+ * In C++ mode, return the largest constant integer found as the

+ * sole argument to LT(i) given that the char before is nonalpha.

+ */

+

+int

+#ifdef __USE_PROTOS

+predicateLookaheadDepth(ActionNode *a)

+#else

+predicateLookaheadDepth(a)

+ActionNode *a;

+#endif

+{

+	int     max_k=0;

+

+    if (a->predEntry != NULL) {

+       MR_pred_depth(a->predEntry->pred,&max_k);

+       goto PREDENTRY_EXIT;

+    }

+

+	if ( GenCC )

+	{

+		/* scan for LT(i) */

+		int k = 0;

+		char *p = a->action;

+		while ( p!=NULL )

+		{

+			p = strstr(p, "LT(");

+			if ( p!=NULL )

+			{

+				if ( p>=a->action && !isalpha(*(p-1)) )

+				{

+					k = atoi(p+strlen("LT("));

+					if ( k>max_k ) max_k=k;

+				}

+				p += strlen("LT(");

+			}

+		}

+	}

+	else {

+		/* scan for LATEXT(i) */

+		int k = 0;

+		char *p = a->action;

+		while ( p!=NULL )

+		{

+			p = strstr(p, "LATEXT(");

+			if ( p!=NULL )

+			{

+				p += strlen("LATEXT(");

+				k = atoi(p);

+				if ( k>max_k ) max_k=k;

+			}

+		}

+	}

+

+	if (max_k==0) {

+		max_k = 1;	   /* MR33 Badly designed if didn't set max_k when CLL_k = 1 */

+		if (CLL_k > 1) /* MR27 Don't warn if max(k,ck) == 1 */

+		{

+			if ( !a->frmwarned )

+			{

+				a->frmwarned = 1;

+				warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1",

+							 GenCC?"LT(i)":"LATEXT(i)"),

+					   FileStr[a->file], a->line);

+			}

+		}

+	}

+

+/* MR10 */    if ( max_k > CLL_k) {

+/* MR10 */		if ( !a->frmwarned )

+/* MR10 */        {

+/* MR10 */			a->frmwarned = 1;

+/* MR11 */ errFL(eMsgd2("predicate refers to lookahead token %d. Semantic lookahead is limited to max(k,ck)==%d",

+/* MR10 */                        max_k,CLL_k),

+/* MR10 */                        FileStr[a->file],a->line);

+/* MR10 */          if (max_k >= OutputLL_k) {

+/* MR10 */            if (!GenCC) {

+/* MR10 */              errFL(eMsgd("    the lookahead buffer size in C mode is %d token(s) (including the one just recognized)",

+/* MR10 */                        OutputLL_k),

+/* MR10 */                        FileStr[a->file],a->line);

+/* MR10 */            };

+/* MR10 */          };

+/* MR10 */        };

+/* MR10 */        max_k= CLL_k;

+/* MR10 */    };

+

+PREDENTRY_EXIT:

+	return max_k;

+}

+

+/* Find all predicates in a block of alternatives.  DO NOT find predicates

+ * behind the block because that predicate could depend on things set in

+ * one of the nonoptional blocks

+ */

+

+Predicate *

+#ifdef __USE_PROTOS

+find_in_aSubBlk( Junction *alt )

+#else

+find_in_aSubBlk( alt )

+Junction *alt;

+#endif

+{

+	Predicate *a, *head=NULL, *tail=NULL, *root=NULL;

+	Junction *p = alt;

+

+    if (MRhoisting) {

+      return MR_find_in_aSubBlk(alt);

+    };

+	for (; p!=NULL; p=(Junction *)p->p2)

+	{

+		/* ignore empty alts */

+		if ( p->p1->ntype != nJunction ||

+			 ((Junction *)p->p1)->jtype != EndBlk )

+		{

+			a = find_predicates(p->p1);	/* get preds for this alt */

+			if ( a==NULL ) continue;

+

+			/* make an OR list of predicates */

+			if ( head==NULL )

+			{

+				root = new_pred();

+				root->expr = PRED_OR_LIST;

+				head = tail = a;

+				root->down = head;

+			}

+			else {

+				tail->right = a;

+				a->left = tail;

+				a->up = tail->up;

+				tail = a;

+			}

+		}

+	}

+

+	/* if just one pred, remove OR root */

+	if ( root!=NULL && root->down->right == NULL )

+	{

+		Predicate *d = root->down;

+		free( (char *) root);

+		return d;

+	}

+

+	return root;

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+find_in_aOptBlk( Junction *alt )

+#else

+find_in_aOptBlk( alt )

+Junction *alt;

+#endif

+{

+	return find_in_aSubBlk( alt );

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+find_in_aLoopBegin( Junction *alt )

+#else

+find_in_aLoopBegin( alt )

+Junction *alt;

+#endif

+{

+	return find_in_aSubBlk( (Junction *) alt->p1 );	/* get preds in alts */

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+find_in_aPlusBlk( Junction *alt )

+#else

+find_in_aPlusBlk( alt )

+Junction *alt;

+#endif

+{

+	require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk");

+	return find_in_aSubBlk( alt );

+}

+

+/* Look for a predicate;

+ *

+ * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs.

+ * This means that a "hoisting distance" of zero is the only distance

+ * allowable.  Init actions are ignored.

+ *

+ * WARNING:

+ *		Assumes no (..)? block after predicate for the moment.

+ *		Does not check to see if pred is in production that can generate

+ *			a sequence contained in the set of ambiguous tuples.

+ *

+ * Return the predicate found if any.

+ */

+

+

+Predicate *

+#ifdef __USE_PROTOS

+find_predicates( Node *alt )

+#else

+find_predicates( alt )

+Node *alt;

+#endif

+{

+#ifdef DBG_PRED

+	Junction *j;

+	RuleRefNode *r;

+	TokNode *t;

+#endif

+	Predicate *pred;

+

+	if ( alt==NULL ) return NULL;

+

+#ifdef DBG_PRED

+	switch ( alt->ntype )

+	{

+		case nJunction :

+			j = (Junction *) alt;

+			fprintf(stderr, "Junction(in %s)", j->rname);

+			switch ( j->jtype )

+			{

+				case aSubBlk :

+					fprintf(stderr,"aSubBlk\n");

+					break;

+				case aOptBlk :

+					fprintf(stderr,"aOptBlk\n");

+					break;

+				case aLoopBegin :

+					fprintf(stderr,"aLoopBeginBlk\n");

+					break;

+				case aLoopBlk :

+					fprintf(stderr,"aLoopBlk\n");

+					break;

+				case aPlusBlk :

+					fprintf(stderr,"aPlusBlk\n");

+					break;

+				case EndBlk :

+					fprintf(stderr,"EndBlk\n");

+					break;

+				case RuleBlk :

+					fprintf(stderr,"RuleBlk\n");

+					break;

+				case Generic :

+					fprintf(stderr,"Generic\n");

+					break;

+				case EndRule :

+					fprintf(stderr,"EndRule\n");

+					break;

+			}

+			break;

+		case nRuleRef :

+			r = (RuleRefNode *) alt;

+			fprintf(stderr, "RuleRef(in %s)\n", r->rname);

+			break;

+		case nToken :

+			t = (TokNode *) alt;

+			fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token));

+			break;

+		case nAction :

+			fprintf(stderr, "Action\n");

+			break;

+	}

+#endif

+

+	switch ( alt->ntype )

+	{

+		case nJunction :

+		{

+			Predicate *a, *b;

+			Junction *p = (Junction *) alt;	

+

+			/* lock nodes */

+			if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||

+				 p->jtype==aPlusBlk || p->jtype==EndRule )

+			{

+				require(p->pred_lock!=NULL, "rJunc: lock array is NULL");

+				if ( p->pred_lock[1] )

+				{

+					return NULL;

+				}

+				p->pred_lock[1] = TRUE;

+			}

+

+			switch ( p->jtype )

+			{

+				case aSubBlk :

+					a = find_in_aSubBlk(p);

+					return a;	/* nothing is visible past this guy */

+				case aOptBlk :

+					a = find_in_aOptBlk(p);

+					return a;

+				case aLoopBegin :

+					a = find_in_aLoopBegin(p);

+					return a;

+				case aLoopBlk :

+					a = find_in_aSubBlk(p);

+					p->pred_lock[1] = FALSE;

+					return a;

+				case aPlusBlk :

+					a = find_in_aPlusBlk(p);

+					p->pred_lock[1] = FALSE;

+					return a;	/* nothing is visible past this guy */

+				case RuleBlk :

+					a = find_predicates(p->p1);

+					p->pred_lock[1] = FALSE;

+					return a;

+				case Generic :

+					a = find_predicates(p->p1);

+					b = find_predicates(p->p2);

+					if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE;

+					if ( a==NULL ) return b;

+					if ( b==NULL ) return a;

+					/* otherwise OR the two preds together */

+					{

+					fatal_internal("hit unknown situation during predicate hoisting");

+					}

+				case EndBlk :

+				case EndRule :	/* Find no predicates after a rule ref */

+					return NULL;

+				default:

+					fatal_internal("this cannot be printed\n");

+					break;

+			}

+		}

+		case nAction :

+		{

+			ActionNode *p = (ActionNode *) alt;

+            if ( p->noHoist) return NULL;                           /* MR12c */

+			if ( p->init_action ) return find_predicates(p->next);

+			if ( p->is_predicate )

+			{

+				Tree *t=NULL;

+#ifdef DBG_PRED

+				fprintf(stderr, "predicate: <<%s>>?\n", p->action);

+#endif

+				if ( p->guardpred!=NULL )

+				{

+					pred = predicate_dup(p->guardpred);

+                    MR_guardPred_plainSet(p,pred);                  /* MR12c */

+				}

+				else

+				{

+					pred = new_pred();

+					pred->k = predicateLookaheadDepth(p);

+					pred->source = p;

+					pred->expr = p->action;

+					if ( HoistPredicateContext && pred->k > 1 )

+					{

+						/* MR30 No need to use first_item_is_guess_block_extra

+						   since we know this is an action, not a (...)* or

+						   (...)+ block.

+						*/

+

+						if ( first_item_is_guess_block((Junction *)p->next) )

+						{

+                            warnFL("cannot compute context of predicate in front of (..)? block",

+                            FileStr[p->file], p->line);

+						}

+						else

+						{

+							ConstrainSearch = 0;

+/* MR11 */                  if (p->ampersandPred != NULL) {

+/* MR11 */  					TRAV(p,

+/* MR11 */							 pred->k,

+/* MR11 */  						 &(pred->completionTree), t);

+/* MR11 */                  } else {

+    							TRAV(p->next,

+    								 pred->k,

+    								 &(pred->completionTree), t);

+                            };

+							pred->tcontext = t;

+                            MR_check_pred_too_long(pred,pred->completionTree);

+#ifdef DBG_PRED

+							fprintf(stderr, "LL(%d) context:", pred->k);

+							preorder(t);

+							fprintf(stderr, "\n");

+#endif

+						}

+					}

+					else if ( HoistPredicateContext && pred->k == 1 )

+					{

+						pred->scontext[1] = empty;

+						/* MR30 No need to use first_item_is_guess_block_extra

+						   since we know this is an action.

+						*/

+						if ( first_item_is_guess_block((Junction *)p->next) )

+						{

+                        warnFL("cannot compute context of predicate in front of (..)? block",

+                                             FileStr[p->file], p->line);

+						}

+						else

+						{

+							REACH((Junction *)p->next,

+								  1,

+								  &(pred->completionSet),

+								  pred->scontext[1]);

+                            MR_check_pred_too_long(pred,pred->completionSet);

+#ifdef DBG_PRED

+							fprintf(stderr, "LL(1) context:");

+							s_fprT(stderr, pred->scontext[1]);

+							fprintf(stderr, "\n");

+#endif

+						}

+					}

+				}

+				{

+					Predicate  *d = find_predicates(p->next);

+                    Predicate  *root;

+

+/* Warning: Doesn't seem like the up pointers will all be set correctly;

+ * TJP: that's ok, we're not using them now.

+ */

+					if ( d!=NULL )

+					{

+						root = new_pred();

+						root->expr = PRED_AND_LIST;

+						root->down = pred;

+						pred->right = d;

+						pred->up = root;

+						d->left = pred;

+						d->up = pred->up;

+						return root;

+					}

+				}

+				return pred;

+			}

+			return NULL;

+		}

+		case nRuleRef :

+		{

+			Predicate   *a;

+			RuleRefNode *p = (RuleRefNode *) alt;

+			Junction    *r;

+            Junction    *save_MR_RuleBlkWithHalt;

+

+			RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);

+			if ( q == NULL )

+			{

+				warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );

+				return NULL;

+			}

+			r = RulePtr[q->rulenum];

+			if ( r->pred_lock[1] )

+			{

+				/* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis

+				 * must have seen it earlier.

+				 */

+				return NULL;

+			}

+

+            /* MR10 There should only be one halt set at a time.        */

+            /* MR10 Life would have been easier with a global variable  */

+            /* MR10    (at least for this particular need)              */

+            /* MR10 Unset the old one and set the new one, later undo.  */

+

+            require(r->end->halt == FALSE,"should only have one halt at a time");

+

+/* MR10 */  require(MR_RuleBlkWithHalt == NULL ||

+/* MR10 */          (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),

+/* MR10 */             "RuleBlkWithHalt->end not RuleBlk or does not have halt set");

+/* MR10 */  if (MR_RuleBlkWithHalt != NULL) {

+/* MR10 */    MR_RuleBlkWithHalt->end->halt=FALSE;

+/* MR10 */  };

+

+/***        fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq);     ***/

+

+            require(r->end->halt == FALSE,"rule->end->halt already set");

+

+            save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;

+

+/* MR10 */  MR_pointerStackPush(&MR_RuleBlkWithHaltStack,MR_RuleBlkWithHalt);

+/* MR10 */  MR_pointerStackPush(&MR_PredRuleRefStack,p);

+

+			r->end->halt = TRUE;

+/* MR10 */  MR_RuleBlkWithHalt=r;

+

+			a = find_predicates((Node *)r);

+

+            require(r->end->halt == TRUE,"rule->end->halt not set");

+            r->end->halt = FALSE;

+

+/* MR10 */  MR_pointerStackPop(&MR_PredRuleRefStack);

+/* MR10 */  MR_RuleBlkWithHalt=(Junction *) MR_pointerStackPop(&MR_RuleBlkWithHaltStack);

+

+            require (MR_RuleBlkWithHalt==save_MR_RuleBlkWithHalt,

+                    "RuleBlkWithHaltStack not consistent");

+

+/* MR10 */  require(MR_RuleBlkWithHalt == NULL ||

+/* MR10 */          (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == FALSE),

+/* MR10 */             "RuleBlkWithHalt->end not RuleBlk or has no halt set");

+/* MR10 */  if (MR_RuleBlkWithHalt != NULL) {

+/* MR10 */    MR_RuleBlkWithHalt->end->halt=TRUE;

+/* MR10 */  };

+

+/***        fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq);   ***/

+

+			if ( a==NULL ) return NULL;

+

+			/* attempt to compute the "local" FOLLOW just like in normal lookahead

+			 * computation if needed

+			 */

+

+			complete_context_sets(p,a);

+			complete_context_trees(p,a);

+

+/* MR10 */  MR_cleanup_pred_trees(a);

+

+			return a;

+		}

+		case nToken :

+			break;

+	}

+

+	return NULL;

+}

+

+#ifdef __USE_PROTOS

+Predicate *MR_find_predicates_and_supp(Node *alt)

+#else

+Predicate *MR_find_predicates_and_supp(alt)

+  Node      *alt;

+#endif

+{

+    Predicate   *p;

+

+    p=find_predicates(alt);

+    p=MR_suppressK(alt,p);

+    return p;

+}

+

+Predicate *

+#ifdef __USE_PROTOS

+new_pred( void )

+#else

+new_pred( )

+#endif

+{

+	Predicate *p = (Predicate *) calloc(1,sizeof(Predicate)); /* MR10 */

+	require(p!=NULL, "new_pred: cannot alloc predicate");

+    p->scontext[0]=empty;

+    p->scontext[1]=empty;

+    p->completionTree=empty;

+    p->completionSet=empty;

+    p->plainSet=empty;

+	return p;

+}

+

+static void

+#ifdef __USE_PROTOS

+complete_context_sets( RuleRefNode *p, Predicate *a )

+#else

+complete_context_sets( p, a )

+RuleRefNode *p;

+Predicate *a;

+#endif

+{

+	set rk2, b;

+	int k2;

+

+#ifdef DBG_PRED

+	fprintf(stderr, "enter complete_context_sets\n");

+#endif

+	for (; a!=NULL; a=a->right)

+	{

+		if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )

+		{

+			complete_context_sets(p,a->down);

+			continue;

+		}

+		rk2 = b = empty;

+		while ( !set_nil(a->completionSet) )

+		{

+			k2 = set_int(a->completionSet);

+			set_rm(k2, a->completionSet);

+

+            REACH(p->next, k2, &rk2, b);

+			set_orin(&(a->scontext[1]), b);

+			set_free(b);

+		}

+

+		set_orin(&(a->completionSet), rk2);/* remember what we couldn't do */

+		set_free(rk2);

+#ifdef DBG_PRED

+		fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a);

+		s_fprT(stderr, a->scontext[1]);

+		fprintf(stderr, "\n");

+#endif

+/*		complete_context_sets(p, a->down);*/

+	}

+#ifdef DBG_PRED

+	fprintf(stderr, "exit complete_context_sets\n");

+#endif

+}

+

+static void

+#ifdef __USE_PROTOS

+complete_context_trees( RuleRefNode *p, Predicate *a )

+#else

+complete_context_trees( p, a )

+RuleRefNode *p;

+Predicate *a;

+#endif

+{

+	set rk2;

+	int k2;

+	Tree *u;

+

+#ifdef DBG_PRED

+	fprintf(stderr, "enter complete_context_trees\n");

+#endif

+	for (; a!=NULL; a=a->right)

+	{

+		if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )

+		{

+			complete_context_trees(p, a->down);

+			continue;

+		}

+		rk2 = empty;

+

+		/* any k left to do? if so, link onto tree */

+		while ( !set_nil(a->completionTree) )

+		{	

+			k2 = set_int(a->completionTree);

+			set_rm(k2, a->completionTree);

+			u = NULL;

+

+            TRAV(p->next, k2, &rk2, u);

+

+			/* any subtrees missing k2 tokens, add u onto end */

+			a->tcontext = tlink(a->tcontext, u, k2);

+            Tfree(u);   /* MR10 */

+		}

+		set_orin(&(a->completionTree), rk2);/* remember what we couldn't do */

+		set_free(rk2);

+#ifdef DBG_PRED

+		fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k);

+		preorder(a->tcontext);

+		fprintf(stderr, "\n");

+#endif

+/*		complete_context_trees(p, a->down);*/

+	}

+#ifdef DBG_PRED

+	fprintf(stderr, "exit complete_context_trees\n");

+#endif

+}

+

+/* Walk a list of predicates and return the set of all tokens in scontext[1]'s */

+set

+#ifdef __USE_PROTOS

+covered_set( Predicate *p )

+#else

+covered_set( p )

+Predicate *p;

+#endif

+{

+	set a;

+

+	a = empty;

+	for (; p!=NULL; p=p->right)

+	{

+		if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST )

+		{

+			set_orin(&a, covered_set(p->down));

+			continue;

+		}

+		set_orin(&a, p->scontext[1]);

+		set_orin(&a, covered_set(p->down));

+	}

+	return a;

+}

+

+/* MR10 predicate_free()

+   MR10 Don't free the leaf nodes since they are part of the action node

+*/

+

+#ifdef __USE_PROTOS

+void predicate_free(Predicate *p)

+#else

+void predicate_free(p)

+  Predicate     *p;

+#endif

+{

+  if (p == NULL) return;

+  predicate_free(p->right);

+  predicate_free(p->down);

+  if (p->cloned ||

+      p->source == NULL ||

+      p->source->guardpred == NULL ||

+      p->expr == PRED_AND_LIST ||

+      p->expr == PRED_OR_LIST) {

+    set_free(p->scontext[1]);

+    set_free(p->completionSet);

+    set_free(p->completionTree);

+    set_free(p->plainSet);

+    Tfree(p->tcontext);

+    free( (char *) p);

+  } else {

+    p->right=NULL;

+    p->down=NULL;  /* MR13 *** debug */

+  };

+}

+

+/* MR10 predicate_dup() */

+

+#ifdef __USE_PROTOS

+Predicate * predicate_dup_xxx(Predicate *p,int contextToo)

+#else

+Predicate * predicate_dup_xxx(p,contextToo)

+  Predicate     *p;

+  int           contextToo;

+#endif

+{

+  Predicate     *q;

+

+  if (p == NULL) return NULL;

+  q=new_pred();

+  q->down=predicate_dup(p->down);

+  q->right=predicate_dup(p->right);

+

+  /*

+     don't replicate expr - it is read-only

+     and address comparison is used to look

+     for identical predicates.

+  */

+

+  q->expr=p->expr;

+  q->k=p->k;

+  q->source=p->source;

+  q->cloned=1;

+  q->ampersandStyle=p->ampersandStyle;

+  q->inverted=p->inverted;

+  q->predEntry=p->predEntry;

+  q->plainSet=set_dup(p->plainSet);

+

+  if (contextToo) {

+    q->tcontext=tdup(p->tcontext);

+    q->scontext[0]=set_dup(p->scontext[0]);

+    q->scontext[1]=set_dup(p->scontext[1]);

+    q->completionTree=set_dup(p->completionTree);

+    q->completionSet=set_dup(p->completionSet);

+  };

+

+  /* don't need to dup "redundant" */

+

+  return q;

+

+}

+

+#ifdef __USE_PROTOS

+Predicate * predicate_dup_without_context(Predicate *p)

+#else

+Predicate * predicate_dup_without_context(p)

+  Predicate     *p;

+#endif

+{

+  return predicate_dup_xxx(p,0);

+}

+

+#ifdef __USE_PROTOS

+Predicate * predicate_dup(Predicate *p)

+#else

+Predicate * predicate_dup(p)

+  Predicate     *p;

+#endif

+{

+  return predicate_dup_xxx(p,1);

+}

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/proto.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/proto.h
new file mode 100644
index 0000000..53035e7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/proto.h
@@ -0,0 +1,852 @@
+/*

+ * proto.h -- function prototypes

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+                           /* V a r i a b l e s */

+

+extern int tp;

+extern Junction *SynDiag;

+extern char Version[];

+extern char VersionDef[];

+#ifdef __cplusplus

+extern void (*fpPrint[])(...);

+#else

+extern void (*fpPrint[])();

+#endif

+#ifdef __cplusplus

+extern struct _set (*fpReach[])(...);

+#else

+extern struct _set (*fpReach[])();

+#endif

+#ifdef __cplusplus

+extern struct _tree *(*fpTraverse[])(...);

+#else

+extern struct _tree *(*fpTraverse[])();

+#endif

+#ifdef __cplusplus

+extern void (**fpTrans)(...);

+#else

+extern void (**fpTrans)();

+#endif

+#ifdef __cplusplus

+extern void (**fpJTrans)(...);

+#else

+extern void (**fpJTrans)();

+#endif

+#ifdef __cplusplus

+extern void (*C_Trans[NumNodeTypes+1])(...);

+#else

+extern void (*C_Trans[])();

+#endif

+#ifdef __cplusplus

+extern void (*C_JTrans[NumJuncTypes+1])(...);

+#else

+extern void (*C_JTrans[])();

+#endif

+extern int BlkLevel;

+extern int CurFile;

+extern char *CurPredName;

+extern char *CurRule;

+extern int  CurRuleDebug;                       /* MR13 */

+extern Junction *CurRuleBlk;

+extern RuleEntry *CurRuleNode;

+extern ListNode *CurElementLabels;

+extern ListNode *CurAstLabelsInActions;         /* MR27 */

+extern ListNode *ContextGuardPredicateList;     /* MR13 */

+extern ListNode *CurActionLabels;

+extern int numericActionLabel;        /* MR10 << ... $1 ... >> or << ... $1 ... >>?   */

+extern ListNode *NumericPredLabels;   /* MR10 << ... $1 ... >>?  ONLY                 */

+extern char *FileStr[];

+extern int NumFiles;

+extern int EpToken;

+extern int WildCardToken;

+extern Entry	**Tname,

+				**Texpr,

+				**Rname,

+				**Fcache,

+				**Tcache,

+				**Elabel,

+				**Sname,

+                **Pname;    /* MR11 */

+extern ListNode *ExprOrder;

+extern ListNode **Cycles;

+extern int TokenNum;

+extern int LastTokenCounted;

+extern ListNode *BeforeActions, *AfterActions, *LexActions;

+

+/* MR1							                        		    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class     */

+/* MR1			  via #lexmember <<....>> & #lexprefix <<...>>              */

+/* MR1									    */

+

+extern ListNode *LexMemberActions;			 	             /* MR1 */

+extern ListNode *LexPrefixActions;				             /* MR1 */

+

+extern set *fset;   /* for constrained search */             /* MR11 */

+extern int maxk;    /* for constrained search */             /* MR11 */

+extern int Save_argc;                                        /* MR10 */

+extern char **Save_argv;                                     /* MR10 */

+extern ListNode *eclasses, *tclasses;

+extern char	*HdrAction;

+extern char *FirstAction;                                    /* MR11 */

+extern FILE	*ErrFile;

+extern char *RemapFileName;

+extern char *ErrFileName;

+extern char *DlgFileName;

+extern char *DefFileName;

+extern char *ModeFileName;

+extern char *StdMsgName;

+extern int NumRules;

+extern Junction **RulePtr;

+extern int LL_k;

+extern int CLL_k;

+extern char *decodeJType[];

+extern int PrintOut;

+extern int PrintAnnotate;

+extern int CodeGen;

+extern int LexGen;

+extern int esetnum;

+extern int setnum;

+extern int wordnum;

+extern int GenAST;

+extern int GenANSI;

+extern int **FoStack;

+extern int **FoTOS;

+extern int GenExprSetsOpt;

+extern FILE *DefFile;

+extern int CannotContinue;

+extern int GenCR;

+extern int GenLineInfo;

+extern int GenLineInfoMS;

+extern int action_file, action_line;

+extern int TraceGen;

+extern int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile;

+extern char *CurAmbigbtype;

+extern int elevel;

+extern int GenEClasseForRules;

+extern FILE *input, *output;

+extern char **TokenStr, **ExprStr;

+extern int CurrentLexClass, NumLexClasses;

+extern LClass lclass[];

+extern char LexStartSymbol[];

+extern char	*CurRetDef;

+extern char	*CurParmDef;

+extern int OutputLL_k;

+extern int TreeResourceLimit;

+extern int DemandLookahead;

+extern char *RulePrefix;

+extern int GenStdPccts;

+extern char *stdpccts;

+extern int ParseWithPredicates;

+extern int ConstrainSearch;

+extern int PURIFY;													/* MR23 */

+

+extern set MR_CompromisedRules;                                     /* MR14 */

+extern int MR_AmbSourceSearch;                                      /* MR11 */

+extern int MR_SuppressSearch;                                       /* MR13 */

+extern int MR_AmbSourceSearchGroup;                                 /* MR11 */

+extern int MR_AmbSourceSearchChoice;                                /* MR11 */

+extern int MR_AmbSourceSearchLimit;                                 /* MR11 */

+extern int MR_usingPredNames;                                       /* MR11 */

+extern int MR_ErrorSetComputationActive;                            /* MR14 */

+extern char *MR_AmbAidRule;                                         /* MR11 */

+extern int   MR_AmbAidLine;                                         /* MR11 */

+extern int   MR_AmbAidMultiple;                                     /* MR11 */

+extern int MR_AmbAidDepth;                                          /* MR11 */

+extern int MR_skipped_e3_report;                                    /* MR11 */

+extern int MR_matched_AmbAidRule;                                   /* MR11 */

+extern int MR_Inhibit_Tokens_h_Gen;                                 /* MR13 */

+extern int NewAST;                                                  /* MR13 */

+extern int tmakeInParser;                                           /* MR23 */

+extern int AlphaBetaTrace;                                          /* MR14 */

+extern int MR_BlkErr;                                               /* MR21 */

+extern int MR_AlphaBetaWarning;                                     /* MR14 */

+extern int MR_AlphaBetaMessageCount;                                /* MR14 */

+extern int MR_MaintainBackTrace;                                    /* MR14 */

+extern int MR_BadExprSets;                                          /* MR13 */

+extern int FoundGuessBlk;

+extern int FoundException;

+extern int FoundAtOperator;				                             /* MR6 */

+extern int FoundExceptionGroup;                                      /* MR6 */

+extern int WarningLevel;

+extern int UseStdout;					                             /* MR6 */

+extern int TabWidth;					                             /* MR6 */

+extern int pLevel;

+extern int pAlt1;

+extern int pAlt2;

+extern int AImode;

+extern int HoistPredicateContext;

+extern int MRhoisting;                                               /* MR9 */

+extern int MRhoistingk;                                              /* MR13 */

+extern int MR_debugGenRule;                                          /* MR11 */

+extern int GenCC;

+extern char *ParserName;

+extern char *StandardSymbols[];

+extern char *ASTSymbols[];

+extern set reserved_positions;

+extern set all_tokens;

+extern set imag_tokens;

+extern set tokclasses;

+extern ListNode *ForcedTokens;

+extern int *TokenInd;

+extern FILE *Parser_h, *Parser_c;

+extern char CurrentClassName[];

+extern int no_classes_found;

+extern char Parser_h_Name[];

+extern char Parser_c_Name[];

+extern char MRinfoFile_Name[];                                      /* MR10 */

+extern FILE *MRinfoFile;                                            /* MR10 */

+extern int MRinfo;                                                  /* MR10 */

+extern int MRinfoSeq;                                               /* MR10 */

+extern int InfoP;                                                   /* MR10 */

+extern int InfoT;                                                   /* MR10 */

+extern int InfoF;                                                   /* MR10 */

+extern int InfoM;                                                   /* MR10 */

+extern int InfoO;                                                   /* MR12 */

+extern int PotentialSuppression;                                    /* MR10 */

+extern int PotentialDummy;                                          /* MR10 */

+extern int TnodesInUse;                                             /* MR10 */

+extern int TnodesPeak;                                              /* MR10 */

+extern int TnodesReportThreshold;                                   /* MR11 */

+extern int TnodesAllocated;                                         /* MR10 */

+extern char *ClassDeclStuff;                                        /* MR10 */

+extern char *BaseClassName;                                         /* MR22 */

+extern ListNode *class_before_actions, *class_after_actions;

+extern char *UserTokenDefsFile;

+extern int UserDefdTokens;

+extern ListNode *MetaTokenNodes;

+extern char *OutputDirectory;

+extern int DontCopyTokens;

+extern int LTinTokenAction;                                         /* MR23 */

+extern set AST_nodes_refd_in_actions;

+extern ListNode *CurExGroups;

+extern int CurBlockID;

+extern int CurAltNum;

+extern Junction *CurAltStart;

+extern Junction *OuterAltStart;               /* chain exception groups MR7 */

+extern ExceptionGroup *DefaultExGroup;

+extern int NumSignals;

+extern int ContextGuardTRAV;

+extern Junction *MR_RuleBlkWithHalt;            /* MR10 */

+extern PointerStack MR_BackTraceStack;          /* MR10 */

+extern PointerStack MR_PredRuleRefStack;        /* MR10 */

+extern PointerStack MR_RuleBlkWithHaltStack;    /* MR10 */

+

+/*									*/

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	    */

+/* MR1					in DLG action			                    */

+/*								                                            */

+extern int tokenActionActive;	                                     /* MR1 */

+

+extern char *PRED_OR_LIST;                                          /* MR10 */

+extern char *PRED_AND_LIST;                                         /* MR10 */

+

+#ifdef __VMS

+#define STRICMP strcasecmp /* MR21 */

+#else

+#define STRICMP stricmp /* MR21 */

+#endif

+

+/* MR26 */

+#ifdef PCCTS_USE_STDARG

+extern Tree *tmake(Tree *root, ...);

+#else

+extern Tree *tmake();

+#endif

+

+#ifdef __USE_PROTOS

+extern int STRICMP(const char*, const char*);

+extern void istackreset(void);

+extern int istacksize(void);

+extern void pushint(int);

+extern int popint( void );

+extern int istackempty( void );

+extern int topint( void );

+extern void NewSetWd( void );

+extern void DumpSetWd( void );

+extern void DumpSetWdForC( void );

+extern void DumpSetWdForCC( void );

+extern void NewSet( void );

+extern void FillSet( set );

+extern void ComputeErrorSets( void );

+extern void ComputeTokSets( void );

+extern void SubstErrorClass( set * );

+extern int DefErrSet( set *, int, char * );

+extern int DefErrSetForC( set *, int, char * );

+extern int DefErrSetForCC( set *, int, char * );

+extern int DefErrSet1(int, set *, int, char *);                         /* MR21 */

+extern int DefErrSetForC1(int, set *, int, char *, const char* );       /* MR21 */

+extern int DefErrSetForCC1(int, set *, int, char *, const char* );      /* MR21 */

+extern int DefErrSetWithSuffix(int, set *, int, char *, const char *);  /* MR21 */

+extern void GenErrHdr( void );

+extern void dumpExpr( FILE *, char * );

+extern void addParm( Node *, char * );

+extern Graph buildAction( char *, int, int, int );

+extern Graph buildToken( char * );

+extern Graph buildWildCard( char * );

+extern Graph buildRuleRef( char * );

+extern Graph Or( Graph, Graph );

+extern Graph Cat( Graph, Graph );

+extern Graph makeOpt( Graph, int, char *);

+extern Graph makeBlk( Graph, int, char *);

+extern Graph makeLoop( Graph, int, char *);

+extern Graph makePlus( Graph, int, char *);

+extern Graph emptyAlt( void );

+extern Graph emptyAlt3( void );

+extern TokNode * newTokNode( void );

+extern RuleRefNode * newRNode( void );

+extern Junction * newJunction( void );

+extern ActionNode * newActionNode( void );

+extern char * makelocks( void );

+extern void preorder( Tree * );

+extern Tree * tnode( int );

+extern void _Tfree( Tree * );

+extern Tree * tdup( Tree * );

+extern int is_single_tuple( Tree * );

+extern Tree * tappend( Tree *, Tree * );

+extern void Tfree( Tree * );

+extern Tree * tlink( Tree *, Tree *, int );

+extern Tree * tshrink( Tree * );

+extern Tree * tflatten( Tree * );

+extern Tree * tJunc( Junction *, int, set * );

+extern Tree * tRuleRef( RuleRefNode *, int, set * );

+extern Tree * tToken( TokNode *, int, set * );

+extern Tree * tAction( ActionNode *, int, set * );

+extern int tmember( Tree *, Tree * );

+extern int tmember_constrained( Tree *, Tree * );

+extern Tree * tleft_factor( Tree * );

+extern Tree * trm_perm( Tree *, Tree * );

+extern void tcvt( set *, Tree * );

+extern Tree * permute( int, int );

+extern Tree * VerifyAmbig( Junction *, Junction *, unsigned **, set *, Tree **, Tree **, int * );

+extern set rJunc( Junction *, int, set * );

+extern set rRuleRef( RuleRefNode *, int, set * );

+extern set rToken( TokNode *, int, set * );

+extern set rAction( ActionNode *, int, set * );

+extern void HandleAmbiguity( Junction *, Junction *, Junction *, int );

+extern set First( Junction *, int, int, int * );

+extern void freeBlkFsets( Junction * );

+extern void genAction( ActionNode * );

+extern void genRuleRef( RuleRefNode * );

+extern void genToken( TokNode * );

+extern void genOptBlk( Junction * );

+extern void genLoopBlk( Junction *, Junction *, Junction *, int );

+extern void genLoopBegin( Junction * );

+extern void genPlusBlk( Junction * );

+extern void genSubBlk( Junction * );

+extern void genRule( Junction * );

+extern void genJunction( Junction * );

+extern void genEndBlk( Junction * );

+extern void genEndRule( Junction * );

+extern void genHdr( int );

+extern void genHdr1( int );

+extern void dumpAction( char *, FILE *, int, int, int, int );

+extern void dumpActionPlus(ActionNode*, char *, FILE *, int, int, int, int );   /* MR21 */

+extern Entry ** newHashTable( void );

+extern Entry * hash_add( Entry **, char *, Entry * );

+extern Entry * hash_get( Entry **, char * );

+extern void hashStat( Entry ** );

+extern char * mystrdup( char * );

+extern void genLexDescr( void );

+extern void dumpLexClasses( FILE * );

+extern void genDefFile( void );

+extern void DumpListOfParmNames( char *, FILE *, int );	/* MR5 janm 26-May-97 */

+extern int DumpNextNameInDef( char **, FILE * );

+extern void DumpOldStyleParms( char *, FILE * );

+extern void DumpType( char *, FILE * );

+extern int strmember( char *, char * );

+/* extern int HasComma( char * ); MR23 Replaced by hasMultipleOperands() */

+extern void DumpRetValStruct( FILE *, char *, int );

+extern char * StripQuotes( char * );

+extern int main( int, char *[] );

+extern void readDescr( void );

+extern FILE * NextFile( void );

+extern char * outnameX( char *, char *);

+extern char * outname( char * );

+extern void fatalFL( char *, char *, int );

+extern void fatal_intern( char *, char *, int );

+extern void cleanUp( void );

+extern char * eMsg3( char *, char *, char *, char * );

+extern char * eMsgd( char *, int );

+extern char * eMsgd2( char *, int, int );

+extern void s_fprT( FILE *, set );

+extern char * TerminalString( int );

+extern void lexclass( char * );

+extern void lexmode( int );

+extern int LexClassIndex( char * );

+extern int hasAction( char * );

+extern void setHasAction( char *, char * );

+extern int addTname( char * );

+extern int addTexpr( char * );

+extern int Tnum( char * );

+extern void Tklink( char *, char * );

+extern Entry * newEntry( char *, int );

+extern void list_add( ListNode **, void * );

+extern void list_free( ListNode **, int freeData );     /* MR10 */

+extern void list_apply( ListNode *, void (*)(void *) );

+extern int list_search_cstring (ListNode *, char *);    /* MR27 */

+extern char * Fkey( char *, int, int );

+extern void FoPush( char *, int );

+extern void FoPop( int );

+extern void RegisterCycle( char *, int );

+extern void ResolveFoCycles( int );

+extern void pJunc( Junction * );

+extern void pRuleRef( RuleRefNode * );

+extern void pToken( TokNode * );

+extern void pAction( ActionNode * );

+extern void FoLink( Node * );

+extern void addFoLink( Node *, char *, Junction * );

+extern void GenCrossRef( Junction * );

+extern void defErr( char *, long, long, long, long, long, long );

+extern void genStdPCCTSIncludeFile(FILE *,char *);                  /* MR10 */

+extern char * pcctsBaseName(char *);                                /* MR32 */

+extern Predicate *find_predicates(Node *);                          /* MR10 */

+extern Predicate *MR_find_predicates_and_supp(Node *);              /* MR13 */

+extern int predicateLookaheadDepth(ActionNode *);                   /* MR10 */

+extern void predicate_free(Predicate *);                            /* MR10 */

+extern Predicate * predicate_dup(Predicate *);                      /* MR10 */

+extern Predicate * predicate_dup_without_context(Predicate *);      /* MR11 */

+extern void GenRulePrototypes(FILE *, Junction *);

+extern Junction *first_item_is_guess_block(Junction *);

+extern Junction *first_item_is_guess_block_extra(Junction * q);		/* MR30 */

+extern Junction *analysis_point(Junction *);

+extern Tree *make_tree_from_sets(set *, set *);

+extern Tree *tdup_chain(Tree *);

+extern Tree *tdif(Tree *, Predicate *, set *, set *);

+extern set covered_set(Predicate *);

+extern void AmbiguityDialog(Junction *, int, Junction *, Junction *, int *, int *);

+extern void dumpAmbigMsg(set *, FILE *, int);

+extern void GenRuleFuncRedefs(FILE *, Junction *);

+extern void GenPredefinedSymbolRedefs(FILE *);

+extern void GenASTSymbolRedefs(FILE *);

+extern void GenRemapFile(void);

+extern void GenSetRedefs(FILE *);

+extern ForcedToken *newForcedToken(char *, int);

+extern void RemapForcedTokens(void);

+extern char *TokenOrExpr(int);

+extern void setUpperRange(TokNode *, char *);

+extern void GenParser_c_Hdr(void);

+extern void GenParser_h_Hdr(void);

+extern void GenRuleMemberDeclarationsForCC(FILE *, Junction *);

+extern int addForcedTname( char *, int );

+extern char *OutMetaName(char *);

+extern void OutFirstSetSymbol(Junction *q, char *);                 /* MR21 */

+extern void warnNoFL(char *err);

+extern void warnFL(char *err,char *f,int l);

+extern void warn(char *err);

+extern void warnNoCR( char *err );

+extern void errNoFL(char *err);

+extern void errFL(char *err,char *f,int l);

+extern void err(char *err);

+extern void errNoCR( char *err );

+extern void genPredTree( Predicate *p, Node *j, int ,int);

+extern UserAction *newUserAction(char *);

+extern char *gate_symbol(char *name);

+extern char *makeAltID(int blockid, int altnum);

+extern void DumpRemainingTokSets(void);

+extern void DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInit);  /* MR23 */

+extern void DumpFormals(FILE *, char *, int bInit);                   /* MR23 */

+extern char* hideDefaultArgs(const char* pdecl);                      /* MR22 VHS */

+extern Predicate *computePredFromContextGuard(Graph,int *msgDone);    /* MR21 */

+extern void recomputeContextGuard(Predicate *);                       /* MR13 */

+extern Predicate *new_pred(void);

+extern void chkGTFlag(void);

+extern void leAdd(LabelEntry *);                                     /* MR7 */

+extern void leFixup(void);                                           /* MR7 */

+extern void egAdd(ExceptionGroup *);                                 /* MR7 */

+extern void egFixup(void);                                           /* MR7 */

+extern void altAdd(Junction *);                                      /* MR7 */

+extern void altFixup(void);                                          /* MR7 */

+extern Predicate * MR_find_in_aSubBlk(Junction *alt);                /* MR10 */

+extern Predicate * MR_predFlatten(Predicate *p);				     /* MR10 */

+extern Predicate * MR_predSimplifyALL(Predicate *p);	             /* MR10 */

+extern Predicate * MR_predSimplifyALLX(Predicate *p,int skipPass3);  /* MR10 */

+extern int MR_allPredLeaves(Predicate *p);                           /* MR10 */

+extern void MR_cleanup_pred_trees(Predicate *p);                     /* MR10 */

+extern int MR_predicate_context_completed(Predicate *p);             /* MR10 */

+extern void MR_check_pred_too_long(Predicate *p,set completion);     /* MR10 */

+extern Tree * MR_remove_epsilon_from_tree(Tree *t);                  /* MR10 */

+extern Tree * MR_computeTreeAND(Tree *l,Tree *r);					 /* MR10 */

+extern int MR_tree_equ(Tree *big, Tree *small);				         /* MR10 */

+extern set MR_First(int ck,Junction *j,set *incomplete);  		     /* MR10 */

+extern set MR_compute_pred_set(Predicate *p);                	     /* MR10 */

+extern Tree * MR_compute_pred_tree_context(Predicate *p);     	     /* MR10 */

+extern int MR_pointerStackPush(PointerStack *,void *);               /* MR10 */

+extern void * MR_pointerStackPop(PointerStack *);                    /* MR10 */

+extern void * MR_pointerStackTop(PointerStack *);                    /* MR10 */

+extern void MR_pointerStackReset(PointerStack *);                    /* MR10 */

+extern void MR_backTraceReport(void);                                /* MR10 */

+extern void MR_alphaBetaTraceReport(void);                           /* MR14 */

+extern void MR_dumpRuleSet(set);                                     /* MR14 */

+extern void MR_predContextPresent(Predicate *p,int *,int *);         /* MR10 */

+extern void MR_dumpPred(Predicate *p,int withContext);               /* MR10 */

+extern void MR_dumpPred1(int,Predicate *p,int withContext);          /* MR10 */

+extern void MR_xxxIndent(FILE *f,int depth);                         /* MR11 */

+extern void MR_outputIndent(int depth);                              /* MR11 */

+extern void MR_stderrIndent(int depth);                              /* MR11 */

+extern Junction * MR_ruleReferenced(RuleRefNode *rrn);               /* MR10 */

+extern Junction * MR_nameToRuleBlk(char *);                          /* MR10 */

+extern void MR_releaseResourcesUsedInRule(Node *);                   /* MR10 */

+extern void MR_dumpTreeX(int depth,Tree *t,int across);              /* MR10 */

+extern void MR_dumpTreeF(FILE *f,int depth,Tree *t,int across);      /* MR10 */

+extern void DumpFcache(void);                                        /* MR10 */

+extern void MR_dumpTokenSet(FILE *f,int depth,set s);                /* MR10 */

+extern void MR_traceAmbSource(set *,Junction *,Junction *);          /* MR11 */

+extern void MR_traceAmbSourceK(Tree *,Junction *a1,Junction *a2);    /* MR11 */

+extern void MR_traceAmbSourceKclient(void);                          /* MR20 */

+extern Node *MR_advance(Node *);                                     /* MR11 */

+extern int  MR_offsetFromRule(Node *);                               /* MR11 */

+extern char *MR_ruleNamePlusOffset(Node *);                          /* MR11 */

+extern int  MR_max_height_of_tree(Tree *);                           /* MR11 */

+extern int  MR_all_leaves_same_height(Tree *,int);                   /* MR11 */

+extern void MR_projectTreeOntoSet(Tree *t,int k,set *);              /* MR11 */

+extern Tree *MR_make_tree_from_set(set);                             /* MR11 */

+extern Predicate *MR_removeRedundantPredPass3(Predicate *);          /* MR11 */

+extern void MR_pred_depth(Predicate *,int *);                        /* MR11 */

+extern int  MR_comparePredicates(Predicate *,Predicate *);           /* MR11 */

+extern Predicate * MR_unfold(Predicate *);                           /* MR11 */

+extern void MR_simplifyInverted(Predicate *,int);                    /* MR11 */

+extern int  MR_secondPredicateUnreachable                            /* MR11 */

+            (Predicate *first,Predicate *second);                    /* MR11 */

+extern void MR_clearPredEntry(Predicate *);                          /* MR11 */

+extern void MR_orphanRules(FILE *);                                  /* MR12 */

+extern void MR_merge_contexts(Tree *);                               /* MR12 */

+extern int  ci_strequ(char *,char *);                                 /* MR12 */

+extern void MR_guardPred_plainSet(ActionNode *anode,Predicate *);    /* MR12c */

+extern void MR_suppressSearchReport(void);                           /* MR12c */

+extern Predicate * MR_suppressK(Node *,Predicate *);                 /* MR13 */

+extern void MR_backTraceDumpItem(FILE *,int skip,Node *n);           /* MR13 */

+extern void MR_backTraceDumpItemReset(void);                         /* MR13 */

+extern Junction * MR_junctionWithoutP2(Junction *);                  /* MR13 */

+extern void MR_setConstrainPointer(set *);							 /* MR18 */

+extern void BlockPreambleOption(Junction *q, char * pSymbol);        /* MR23 */

+extern char* getInitializer(char *);                                 /* MR23 */

+extern char *endFormal(char *pStart,                                 /* MR23 */

+					   char **ppDataType,                            /* MR23 */

+					   char **ppSymbol,                              /* MR23 */

+					   char **ppEqualSign,                           /* MR23 */

+					   char **ppValue,                               /* MR23 */

+					   char **ppSeparator,                           /* MR23 */

+					   int *pNext);                                  /* MR23 */

+extern char *strBetween(char *pStart,                                /* MR23 */

+						char *pNext,                                 /* MR23 */

+						char *pStop);                                /* MR23 */

+extern int hasMultipleOperands(char *);                              /* MR23 */

+extern void DumpInitializers(FILE*, RuleEntry*, char*);              /* MR23 */

+extern int isTermEntryTokClass(TermEntry *);						 /* MR23 */

+extern int isEmptyAlt(Node *, Node *);                               /* MR23 */

+#else

+extern int STRICMP();

+extern void istackreset();

+extern int istacksize();

+extern void pushint();

+extern int popint();

+extern int istackempty();

+extern int topint();

+extern void NewSetWd();

+extern void DumpSetWd();

+extern void DumpSetWdForC();

+extern void DumpSetWdForCC();

+extern void NewSet();

+extern void FillSet();

+extern void ComputeErrorSets();

+extern void ComputeTokSets();

+extern void SubstErrorClass();

+extern int DefErrSet();

+extern int DefErrSetForC();

+extern int DefErrSetForCC();

+extern int DefErrSet1();

+extern int DefErrSetForC1();

+extern int DefErrSetForCC1();

+extern int DefErrSetWithSuffix();                                   /* MR21 */

+extern void GenErrHdr();

+extern void dumpExpr();

+extern void addParm();

+extern Graph buildAction();

+extern Graph buildToken();

+extern Graph buildWildCard();

+extern Graph buildRuleRef();

+extern Graph Or();

+extern Graph Cat();

+extern Graph makeOpt();

+extern Graph makeBlk();

+extern Graph makeLoop();

+extern Graph makePlus();

+extern Graph emptyAlt();

+extern Graph emptyAlt3();

+extern TokNode * newTokNode();

+extern RuleRefNode * newRNode();

+extern Junction * newJunction();

+extern ActionNode * newActionNode();

+extern char * makelocks();

+extern void preorder();

+extern Tree * tnode();

+extern void _Tfree();

+extern Tree * tdup();

+extern int is_single_tuple();

+extern Tree * tappend();

+extern void Tfree();

+extern Tree * tlink();

+extern Tree * tshrink();

+extern Tree * tflatten();

+extern Tree * tJunc();

+extern Tree * tRuleRef();

+extern Tree * tToken();

+extern Tree * tAction();

+extern int tmember();

+extern int tmember_constrained();

+extern Tree * tleft_factor();

+extern Tree * trm_perm();

+extern void tcvt();

+extern Tree * permute();

+extern Tree * VerifyAmbig();

+extern set rJunc();

+extern set rRuleRef();

+extern set rToken();

+extern set rAction();

+extern void HandleAmbiguity();

+extern set First();

+extern void freeBlkFsets();

+extern void genAction();

+extern void genRuleRef();

+extern void genToken();

+extern void genOptBlk();

+extern void genLoopBlk();

+extern void genLoopBegin();

+extern void genPlusBlk();

+extern void genSubBlk();

+extern void genRule();

+extern void genJunction();

+extern void genEndBlk();

+extern void genEndRule();

+extern void genHdr();

+extern void genHdr1();

+extern void dumpAction();

+extern void dumpActionPlus();                           /* MR21 */

+extern Entry ** newHashTable();

+extern Entry * hash_add();

+extern Entry * hash_get();

+extern void hashStat();

+extern char * mystrdup();

+extern void genLexDescr();

+extern void dumpLexClasses();

+extern void genDefFile();

+extern void DumpListOfParmNames();                    /* MR5 janm 26-May-97 */

+extern int DumpNextNameInDef();

+extern void DumpOldStyleParms();

+extern void DumpType();

+extern int strmember();

+/* extern int HasComma(); MR23 Replaced by hasMultipleOperands() */

+extern void DumpRetValStruct();

+extern char * StripQuotes();

+extern int main();

+extern void readDescr();

+extern FILE * NextFile();

+extern char * outnameX();

+extern char * outname();

+extern void fatalFL();

+extern void fatal_intern();

+extern void cleanUp();

+extern char * eMsg3();

+extern char * eMsgd();

+extern char * eMsgd2();

+extern void s_fprT();

+extern char * TerminalString();

+extern void lexclass();

+extern void lexmode();

+extern int LexClassIndex();

+extern int hasAction();

+extern void setHasAction();

+extern int addTname();

+extern int addTexpr();

+extern int Tnum();

+extern void Tklink();

+extern Entry * newEntry();

+extern void list_add();

+extern void list_free();                /* MR10 */

+extern void list_apply();

+extern int list_search_cstring ();      /* MR27 */

+extern char * Fkey();

+extern void FoPush();

+extern void FoPop();

+extern void RegisterCycle();

+extern void ResolveFoCycles();

+extern void pJunc();

+extern void pRuleRef();

+extern void pToken();

+extern void pAction();

+extern void FoLink();

+extern void addFoLink();

+extern void GenCrossRef();

+extern void defErr();

+extern void genStdPCCTSIncludeFile();

+extern char * pcctsBaseName();                                /* MR32 */

+extern Predicate *find_predicates();

+extern Predicate *MR_find_predicates_and_supp();              /* MR13 */

+extern int predicateLookaheadDepth();                         /* MR10 */

+extern void predicate_free();                                 /* MR10 */

+extern Predicate * predicate_dup();                           /* MR10 */

+extern Predicate * predicate_dup_without_context();           /* MR11 */

+extern void GenRulePrototypes();

+extern Junction *first_item_is_guess_block();

+extern Junction *first_item_is_guess_block_extra();			  /* MR30 */

+extern Junction *analysis_point();

+extern Tree *make_tree_from_sets();

+extern Tree *tdup_chain();

+extern Tree *tdif();

+extern set covered_set();

+extern void AmbiguityDialog();

+extern void dumpAmbigMsg();

+extern void GenRuleFuncRedefs();

+extern void GenPredefinedSymbolRedefs();

+extern void GenASTSymbolRedefs();

+extern void GenRemapFile();

+extern void GenSetRedefs();

+extern ForcedToken *newForcedToken();

+extern void RemapForcedTokens();

+extern char *TokenOrExpr();

+extern void setUpperRange();

+extern void GenParser_c_Hdr();

+extern void GenParser_h_Hdr();

+extern void GenRuleMemberDeclarationsForCC();

+extern int addForcedTname();

+extern char *OutMetaName();

+extern void OutFirstSetSymbol();                            /* MR21 */

+extern void warnNoFL();

+extern void warnFL();

+extern void warn();

+extern void warnNoCR();

+extern void errNoFL();

+extern void errFL();

+extern void err();

+extern void errNoCR();

+extern void genPredTree();

+extern UserAction *newUserAction();

+extern char *gate_symbol();

+extern char *makeAltID();

+extern void DumpRemainingTokSets();

+extern void DumpANSIFunctionArgDef();

+extern void DumpFormals();                                           /* MR23 */

+extern char* hideDefaultArgs();                                      /* MR22 VHS */

+extern Predicate *computePredFromContextGuard();

+extern void recomputeContextGuard();                                 /* MR13 */

+extern Predicate *new_pred();

+extern void chkGTFlag();

+extern void leAdd();                                                 /* MR7 */

+extern void leFixup();                                               /* MR7 */

+extern void egAdd();                                                 /* MR7 */

+extern void egFixup();                                               /* MR7 */

+extern void altAdd();                                                /* MR7 */

+extern void altFixup();                                              /* MR7 */

+extern Predicate * MR_find_in_aSubBlk();       		                /* MR10 */

+extern Predicate * MR_predFlatten();						        /* MR10 */

+extern Predicate * MR_predSimplifyALL();                            /* MR10 */

+extern Predicate * MR_predSimplifyALLX();                           /* MR10 */

+extern void MR_cleanup_pred_trees();                                /* MR10 */

+extern int MR_allPredLeaves();                                      /* MR10 */

+extern int MR_predicate_context_completed();                        /* MR10 */

+extern void MR_check_pred_too_long();                               /* MR10 */

+extern Tree * MR_remove_epsilon_from_tree();				        /* MR10 */

+extern Tree * MR_computeTreeAND();					                /* MR10 */

+extern int MR_tree_equ();                   				        /* MR10 */

+extern set MR_First();				                                /* MR10 */

+extern set MR_compute_pred_set();				                    /* MR10 */

+extern Tree * MR_compute_pred_tree_context();				        /* MR10 */

+extern int MR_pointerStackPush();                                   /* MR10 */

+extern void * MR_pointerStackPop();                                 /* MR10 */

+extern void * MR_pointerStackTop();                                 /* MR10 */

+extern void MR_pointerStackReset();                                 /* MR10 */

+extern void MR_backTraceReport();                                   /* MR10 */

+extern void MR_alphaBetaTraceReport();                              /* MR14 */

+extern void MR_dumpRuleSet();                                       /* MR14 */

+extern void MR_predContextPresent();                                /* MR10 */

+extern void MR_dumpPred();                                          /* MR10 */

+extern void MR_dumpPred1();                                         /* MR10 */

+extern void MR_xxxIndent();                                         /* MR11 */

+extern void MR_stderrIndent();                                      /* MR11 */

+extern void MR_outputIndent();                                      /* MR11 */

+extern Junction * MR_ruleReferenced();                              /* MR10 */

+extern void MR_releaseResourcesUsedInRule();                        /* MR10 */

+extern void MR_dumpTreeX();                                         /* MR10 */

+extern void MR_dumpTreeF();                                         /* MR10 */

+extern void DumpFcache();                                           /* MR10 */

+extern void MR_dumpTokenSet();                                      /* MR10 */

+extern void MR_traceAmbSource();                                    /* MR11 */

+extern Node *MR_advance();                                          /* MR11 */

+extern int  MR_offsetFromRule();                                    /* MR11 */

+extern char *MR_ruleNamePlusOffset();                               /* MR11 */

+extern void MR_traceAmbSourceK();                                   /* MR11 */

+extern void MR_traceAmbSourceKclient();                             /* [i_a] added */

+extern int  MR_max_height_of_tree();                                /* MR11 */

+extern int  MR_all_leaves_same_height();                            /* MR11 */

+extern void MR_projectTreeOntoSet();                                /* MR11 */

+extern Tree *MR_make_tree_from_set();                               /* MR11 */

+extern Predicate *MR_removeRedundantPredPass3();                    /* MR11 */

+extern void MR_pred_depth();                                        /* MR11 */

+extern int  MR_comparePredicates();                                 /* MR11 */

+extern Predicate * MR_unfold();                                     /* MR11 */

+extern void MR_simplifyInverted();                                  /* MR11 */

+extern int  MR_secondPredicateUnreachable();                        /* MR11 */

+extern Junction * MR_nameToRuleBlk();                               /* MR10 */

+extern void MR_clearPredEntry();                                    /* MR11 */

+extern void MR_orphanRules();                                       /* MR12 */

+extern void MR_merge_contexts();                                    /* MR12 */

+extern int ci_strequ();                                             /* MR12 */

+extern void MR_guardPred_plainSet();                                /* MR12c */

+extern void MR_suppressSearchReport();                              /* MR12c */

+extern Predicate * MR_suppressK();                                  /* MR13 */

+extern void MR_backTraceDumpItem();                                 /* MR13 */

+extern void MR_backTraceDumpItemReset();                            /* MR13 */

+extern Junction * MR_junctionWithoutP2();                           /* MR13 */

+extern void MR_setConstrainPointer();					  		    /* MR18 */

+extern void BlockPreambleOption();                                  /* MR23 */

+extern char* getInitializer();                                      /* MR23 */

+extern int hasMultipleOperands();                                   /* MR23 */

+extern char *endFormal();                                           /* MR23 */

+extern char *strBetween();                                          /* MR23 */

+extern void DumpInitializers();                                     /* MR23 */

+extern int isTermEntryTokClass();							 	    /* MR23 */

+extern int isEmptyAlt();

+

+#endif

+

+#ifdef __USE_PROTOS

+#include <stdlib.h>

+#endif

+

+/* MR20 G. Hobbelt  Create proper externs for dlg variables */

+

+extern set attribsRefdFromAction;

+extern int inAlt;

+extern int UsedOldStyleAttrib;

+extern int UsedNewStyleLabel;

+

+#define MAX_BLK_LEVEL 100                       /* MR23 */

+extern int     CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */

+extern int     CurAltNum_array[MAX_BLK_LEVEL];  /* MR23 */

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/scan.c b/edk2/Tools/Source/TianoTools/Pccts/antlr/scan.c
new file mode 100644
index 0000000..9b4bde0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/scan.c
@@ -0,0 +1,5735 @@
+

+/* parser.dlg -- DLG Description of scanner

+ *

+ * Generated from: antlr.g

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include "pcctscfg.h"

+#include "set.h"

+#include <ctype.h>

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#define zzcr_attr(attr,tok,t)

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+LOOKAHEAD

+

+void

+#ifdef __USE_PROTOS

+zzerraction(void)

+#else

+zzerraction()

+#endif

+{

+	(*zzerr)("invalid token");

+	zzadvance();

+	zzskip();

+}

+/*

+ * D L G tables

+ *

+ * Generated from: parser.dlg

+ *

+ * 1989-2001 by  Will Cohen, Terence Parr, and Hank Dietz

+ * Purdue University Electrical Engineering

+ * DLG Version 1.33MR33

+ */

+

+#include "mode.h"

+

+

+

+

+/* maintained, but not used for now */

+set AST_nodes_refd_in_actions = set_init;

+int inAlt = 0;

+set attribsRefdFromAction = set_init; /* MR20 */

+int UsedOldStyleAttrib = 0;

+int UsedNewStyleLabel = 0;

+#ifdef __USE_PROTOS

+char *inline_set(char *);

+#else

+char *inline_set();

+#endif

+

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	    */

+/* MR1					in DLG action			                    */

+

+int tokenActionActive=0;                                            /* MR1 */

+

+  

+

+

+

+static char *

+#ifdef __USE_PROTOS

+getFileNameFromTheLineInfo(char *toStr, char *fromStr)

+#else

+getFileNameFromTheLineInfo(toStr, fromStr)

+char *toStr, *fromStr;

+#endif

+{

+  int i, j, k;

+  

+  if (!fromStr || !toStr) return toStr;

+  

+  /* find the first " */

+  

+  for (i=0;

+  (i<MaxFileName) &&

+  (fromStr[i] != '\n') &&

+  (fromStr[i] != '\r') &&

+  (fromStr[i] != '\"');

+  i++) /* nothing */ ;

+  

+  if ( (i == MaxFileName) ||

+  (fromStr[i] == '\n') ||

+  (fromStr[i] == '\r') ) {

+  return toStr;

+}

+

+  /* find the second " */

+

+  for (j=i+1;

+(j<MaxFileName) &&

+(fromStr[j] != '\n') &&

+(fromStr[j] != '\r') &&

+(fromStr[j] != '\"');

+j++) /* nothing */ ;

+

+  if ((j == MaxFileName) ||

+(fromStr[j] == '\n') ||

+(fromStr[j] == '\r') ) {

+  return toStr;

+}

+

+  /* go back until the last / or \ */

+

+  for (k=j-1;

+(fromStr[k] != '\"') &&

+(fromStr[k] != '/') &&

+(fromStr[k] != '\\');

+k--) /* nothing */ ;

+

+  /* copy the string after " / or \ into toStr */

+

+  for (i=k+1; fromStr[i] != '\"'; i++) {

+toStr[i-k-1] = fromStr[i];

+}

+

+  toStr[i-k-1] = '\0';

+

+  return toStr;

+}

+

+/* MR14 end of a block to support #line in antlr source code */

+

+  

+

+

+#ifdef __USE_PROTOS

+void mark_label_used_in_sem_pred(LabelEntry *le)              /* MR10 */

+#else

+void mark_label_used_in_sem_pred(le)                          /* MR10 */

+LabelEntry    *le;

+#endif

+{

+  TokNode   *tn;

+  require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");

+  tn=(TokNode *)le->elem;

+  require (tn->label != 0,"mark_label_used... TokNode has no label");

+  tn->label_used_in_semantic_pred=1;

+}

+

+static void act1()

+{ 

+		NLA = Eof;

+    /* L o o k  F o r  A n o t h e r  F i l e */

+    {

+      FILE *new_input;

+      new_input = NextFile();

+      if ( new_input == NULL ) { NLA=Eof; return; }

+      fclose( input );

+      input = new_input;

+      zzrdstream( input );

+      zzskip();	/* Skip the Eof (@) char i.e continue */

+    }

+	}

+

+

+static void act2()

+{ 

+		NLA = 76;

+    zzskip();   

+	}

+

+

+static void act3()

+{ 

+		NLA = 77;

+    zzline++; zzskip();   

+	}

+

+

+static void act4()

+{ 

+		NLA = 78;

+    zzmode(ACTIONS); zzmore();

+    istackreset();

+    pushint(']');   

+	}

+

+

+static void act5()

+{ 

+		NLA = 79;

+    action_file=CurFile; action_line=zzline;

+    zzmode(ACTIONS); zzmore();

+    list_free(&CurActionLabels,0);       /* MR10 */

+    numericActionLabel=0;                /* MR10 */

+    istackreset();

+    pushint('>');   

+	}

+

+

+static void act6()

+{ 

+		NLA = 80;

+    zzmode(STRINGS); zzmore();   

+	}

+

+

+static void act7()

+{ 

+		NLA = 81;

+    zzmode(COMMENTS); zzskip();   

+	}

+

+

+static void act8()

+{ 

+		NLA = 82;

+    warn("Missing /*; found dangling */"); zzskip();   

+	}

+

+

+static void act9()

+{ 

+		NLA = 83;

+    zzmode(CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act10()

+{ 

+		NLA = 84;

+    

+    zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();

+    getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);

+	}

+

+

+static void act11()

+{ 

+		NLA = 85;

+    

+    zzline++; zzmore();

+	}

+

+

+static void act12()

+{ 

+		NLA = 86;

+    warn("Missing <<; found dangling >>"); zzskip();   

+	}

+

+

+static void act13()

+{ 

+		NLA = WildCard;

+	}

+

+

+static void act14()

+{ 

+		NLA = 88;

+    FoundException = 1;		/* MR6 */

+    FoundAtOperator = 1;  

+	}

+

+

+static void act15()

+{ 

+		NLA = Pragma;

+	}

+

+

+static void act16()

+{ 

+		NLA = FirstSetSymbol;

+	}

+

+

+static void act17()

+{ 

+		NLA = 94;

+	}

+

+

+static void act18()

+{ 

+		NLA = 95;

+	}

+

+

+static void act19()

+{ 

+		NLA = 96;

+	}

+

+

+static void act20()

+{ 

+		NLA = 97;

+	}

+

+

+static void act21()

+{ 

+		NLA = 98;

+	}

+

+

+static void act22()

+{ 

+		NLA = 99;

+	}

+

+

+static void act23()

+{ 

+		NLA = 102;

+	}

+

+

+static void act24()

+{ 

+		NLA = 103;

+	}

+

+

+static void act25()

+{ 

+		NLA = 104;

+	}

+

+

+static void act26()

+{ 

+		NLA = 105;

+	}

+

+

+static void act27()

+{ 

+		NLA = 106;

+	}

+

+

+static void act28()

+{ 

+		NLA = 107;

+	}

+

+

+static void act29()

+{ 

+		NLA = 108;

+	}

+

+

+static void act30()

+{ 

+		NLA = 109;

+	}

+

+

+static void act31()

+{ 

+		NLA = 110;

+	}

+

+

+static void act32()

+{ 

+		NLA = 111;

+	}

+

+

+static void act33()

+{ 

+		NLA = 112;

+	}

+

+

+static void act34()

+{ 

+		NLA = 113;

+	}

+

+

+static void act35()

+{ 

+		NLA = 114;

+	}

+

+

+static void act36()

+{ 

+		NLA = 115;

+	}

+

+

+static void act37()

+{ 

+		NLA = 116;

+	}

+

+

+static void act38()

+{ 

+		NLA = 117;

+	}

+

+

+static void act39()

+{ 

+		NLA = 118;

+	}

+

+

+static void act40()

+{ 

+		NLA = 119;

+	}

+

+

+static void act41()

+{ 

+		NLA = 120;

+	}

+

+

+static void act42()

+{ 

+		NLA = 121;

+	}

+

+

+static void act43()

+{ 

+		NLA = 122;

+	}

+

+

+static void act44()

+{ 

+		NLA = 123;

+	}

+

+

+static void act45()

+{ 

+		NLA = 124;

+	}

+

+

+static void act46()

+{ 

+		NLA = 125;

+	}

+

+

+static void act47()

+{ 

+		NLA = 126;

+	}

+

+

+static void act48()

+{ 

+		NLA = 127;

+	}

+

+

+static void act49()

+{ 

+		NLA = 128;

+	}

+

+

+static void act50()

+{ 

+		NLA = 129;

+	}

+

+

+static void act51()

+{ 

+		NLA = 130;

+	}

+

+

+static void act52()

+{ 

+		NLA = 131;

+	}

+

+

+static void act53()

+{ 

+		NLA = 132;

+	}

+

+

+static void act54()

+{ 

+		NLA = 133;

+	}

+

+

+static void act55()

+{ 

+		NLA = 134;

+	}

+

+

+static void act56()

+{ 

+		NLA = 135;

+	}

+

+

+static void act57()

+{ 

+		NLA = NonTerminal;

+    

+    while ( zzchar==' ' || zzchar=='\t' ) {

+      zzadvance();

+    }

+    if ( zzchar == ':' && inAlt ) NLA = LABEL;

+	}

+

+

+static void act58()

+{ 

+		NLA = TokenTerm;

+    

+    while ( zzchar==' ' || zzchar=='\t' ) {

+      zzadvance();

+    }

+    if ( zzchar == ':' && inAlt ) NLA = LABEL;

+	}

+

+

+static void act59()

+{ 

+		NLA = 136;

+    warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip();   

+	}

+

+static unsigned char shift0[257] = {

+  0, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  1, 2, 58, 58, 3, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 1, 40, 6, 9, 58, 58, 45, 

+  58, 46, 47, 8, 52, 58, 58, 18, 7, 16, 

+  14, 15, 16, 16, 16, 16, 16, 16, 16, 41, 

+  42, 5, 48, 17, 53, 19, 56, 56, 56, 56, 

+  56, 26, 56, 56, 56, 56, 56, 51, 56, 56, 

+  56, 56, 56, 56, 29, 56, 56, 56, 56, 56, 

+  56, 56, 4, 20, 58, 50, 57, 58, 23, 31, 

+  38, 34, 13, 35, 24, 33, 11, 55, 36, 10, 

+  25, 12, 32, 21, 55, 22, 27, 28, 54, 55, 

+  55, 43, 30, 55, 39, 44, 37, 49, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 

+  58, 58, 58, 58, 58, 58, 58

+};

+

+

+static void act60()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act61()

+{ 

+		NLA = QuotedTerm;

+    zzmode(START);   

+	}

+

+

+static void act62()

+{ 

+		NLA = 3;

+    

+    zzline++;

+    warn("eoln found in string");

+    zzskip();

+	}

+

+

+static void act63()

+{ 

+		NLA = 4;

+    zzline++; zzmore();   

+	}

+

+

+static void act64()

+{ 

+		NLA = 5;

+    zzmore();   

+	}

+

+

+static void act65()

+{ 

+		NLA = 6;

+    zzmore();   

+	}

+

+static unsigned char shift1[257] = {

+  0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 2, 5, 5, 3, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 1, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5

+};

+

+

+static void act66()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act67()

+{ 

+		NLA = 7;

+    zzmode(ACTIONS); zzmore();   

+	}

+

+

+static void act68()

+{ 

+		NLA = 8;

+    

+    zzline++;

+    warn("eoln found in string (in user action)");

+    zzskip();

+	}

+

+

+static void act69()

+{ 

+		NLA = 9;

+    zzline++; zzmore();   

+	}

+

+

+static void act70()

+{ 

+		NLA = 10;

+    zzmore();   

+	}

+

+

+static void act71()

+{ 

+		NLA = 11;

+    zzmore();   

+	}

+

+static unsigned char shift2[257] = {

+  0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 2, 5, 5, 3, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 1, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5

+};

+

+

+static void act72()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act73()

+{ 

+		NLA = 12;

+    zzmode(ACTIONS); zzmore();   

+	}

+

+

+static void act74()

+{ 

+		NLA = 13;

+    

+    zzline++;

+    warn("eoln found in char literal (in user action)");

+    zzskip();

+	}

+

+

+static void act75()

+{ 

+		NLA = 14;

+    zzmore();   

+	}

+

+

+static void act76()

+{ 

+		NLA = 15;

+    zzmore();   

+	}

+

+static unsigned char shift3[257] = {

+  0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 2, 5, 5, 3, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5

+};

+

+

+static void act77()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act78()

+{ 

+		NLA = 16;

+    zzmode(ACTIONS); zzmore();   

+	}

+

+

+static void act79()

+{ 

+		NLA = 17;

+    zzmore();   

+	}

+

+

+static void act80()

+{ 

+		NLA = 18;

+    zzline++; zzmore(); DAWDLE;   

+	}

+

+

+static void act81()

+{ 

+		NLA = 19;

+    zzmore();   

+	}

+

+static unsigned char shift4[257] = {

+  0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 3, 5, 5, 4, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 1, 5, 5, 5, 5, 2, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5

+};

+

+

+static void act82()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act83()

+{ 

+		NLA = 20;

+    zzmode(PARSE_ENUM_FILE);

+    zzmore();   

+	}

+

+

+static void act84()

+{ 

+		NLA = 21;

+    zzmore();   

+	}

+

+

+static void act85()

+{ 

+		NLA = 22;

+    zzline++; zzmore(); DAWDLE;   

+	}

+

+

+static void act86()

+{ 

+		NLA = 23;

+    zzmore();   

+	}

+

+static unsigned char shift5[257] = {

+  0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 3, 5, 5, 4, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 1, 5, 5, 5, 5, 2, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5

+};

+

+

+static void act87()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act88()

+{ 

+		NLA = 24;

+    zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE;   

+	}

+

+

+static void act89()

+{ 

+		NLA = 25;

+    zzskip();   

+	}

+

+static unsigned char shift6[257] = {

+  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3

+};

+

+

+static void act90()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act91()

+{ 

+		NLA = 26;

+    zzline++; zzmode(ACTIONS); zzmore(); DAWDLE;   

+	}

+

+

+static void act92()

+{ 

+		NLA = 27;

+    zzmore();   

+	}

+

+static unsigned char shift7[257] = {

+  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3

+};

+

+

+static void act93()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act94()

+{ 

+		NLA = 28;

+    zzline++; zzmode(START); zzskip(); DAWDLE;   

+	}

+

+

+static void act95()

+{ 

+		NLA = 29;

+    zzskip();   

+	}

+

+static unsigned char shift8[257] = {

+  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 

+  3, 3, 3, 3, 3, 3, 3

+};

+

+

+static void act96()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act97()

+{ 

+		NLA = 30;

+    zzmode(START); zzskip();   

+	}

+

+

+static void act98()

+{ 

+		NLA = 31;

+    zzskip();   

+	}

+

+

+static void act99()

+{ 

+		NLA = 32;

+    zzline++; zzskip(); DAWDLE;   

+	}

+

+

+static void act100()

+{ 

+		NLA = 33;

+    zzskip();   

+	}

+

+static unsigned char shift9[257] = {

+  0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 3, 5, 5, 4, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 1, 5, 5, 5, 5, 2, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 

+  5, 5, 5, 5, 5, 5, 5

+};

+

+

+static void act101()

+{ 

+		NLA = Eof;

+	}

+

+

+static void act102()

+{ 

+		NLA = Action;

+    /* these do not nest */

+    zzmode(START);

+    NLATEXT[0] = ' ';

+    NLATEXT[1] = ' ';

+    zzbegexpr[0] = ' ';

+    zzbegexpr[1] = ' ';

+    if ( zzbufovf ) {

+      err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));

+    }

+    

+/* MR1	10-Apr-97  MR1  Previously unable to put right shift operator	*/

+    /* MR1					in DLG action			*/

+    /* MR1			Doesn't matter what kind of action it is - reset*/

+    

+			      tokenActionActive=0;		 /* MR1 */

+	}

+

+

+static void act103()

+{ 

+		NLA = Pred;

+    /* these do not nest */

+    zzmode(START);

+    NLATEXT[0] = ' ';

+    NLATEXT[1] = ' ';

+    zzbegexpr[0] = '\0';

+    if ( zzbufovf ) {

+      err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));

+    };

+#ifdef __cplusplus__

+    /* MR10 */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+#ifdef __STDC__

+    /* MR10 */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+#ifdef __USE_PROTOS

+    /* MRxx */                    list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);

+#else

+    /* MR10 */                    list_apply(CurActionLabels,mark_label_used_in_sem_pred);

+#endif

+#endif

+#endif

+	}

+

+

+static void act104()

+{ 

+		NLA = PassAction;

+    if ( topint() == ']' ) {

+      popint();

+      if ( istackempty() )	/* terminate action */

+      {

+        zzmode(START);

+        NLATEXT[0] = ' ';

+        zzbegexpr[0] = ' ';

+        if ( zzbufovf ) {

+          err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));

+        }

+      }

+      else {

+        /* terminate $[..] and #[..] */

+        if ( GenCC ) zzreplstr("))");

+        else zzreplstr(")");

+        zzmore();

+      }

+    }

+    else if ( topint() == '|' ) { /* end of simple [...] */

+      popint();

+      zzmore();

+    }

+    else zzmore();

+	}

+

+

+static void act105()

+{ 

+		NLA = 37;

+    

+    zzmore();

+    zzreplstr(inline_set(zzbegexpr+

+    strlen("consumeUntil(")));

+	}

+

+

+static void act106()

+{ 

+		NLA = 38;

+    zzmore();   

+	}

+

+

+static void act107()

+{ 

+		NLA = 39;

+    zzline++; zzmore(); DAWDLE;   

+	}

+

+

+static void act108()

+{ 

+		NLA = 40;

+    zzmore();   

+	}

+

+

+static void act109()

+{ 

+		NLA = 41;

+    zzmore();   

+	}

+

+

+static void act110()

+{ 

+		NLA = 42;

+    if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}

+    else err("$$ use invalid in C++ mode");   

+	}

+

+

+static void act111()

+{ 

+		NLA = 43;

+    if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}

+    else err("$[] use invalid in C++ mode");   

+	}

+

+

+static void act112()

+{ 

+		NLA = 44;

+    

+    pushint(']');

+    if ( !GenCC ) zzreplstr("zzconstr_attr(");

+    else err("$[..] use invalid in C++ mode");

+    zzmore();

+	}

+

+

+static void act113()

+{ 

+		NLA = 45;

+    {

+      static char buf[100];

+      numericActionLabel=1;       /* MR10 */

+      if ( strlen(zzbegexpr)>(size_t)85 )

+      fatal("$i attrib ref too big");

+      set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);

+      if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",

+      BlkLevel-1,zzbegexpr+1);

+      else sprintf(buf,"_t%d%s",

+      BlkLevel-1,zzbegexpr+1);

+      zzreplstr(buf);

+      zzmore();

+      UsedOldStyleAttrib = 1;

+      if ( UsedNewStyleLabel )

+      err("cannot mix old-style $i with new-style labels");

+    }

+	}

+

+

+static void act114()

+{ 

+		NLA = 46;

+    {

+      static char buf[100];

+      numericActionLabel=1;       /* MR10 */

+      if ( strlen(zzbegexpr)>(size_t)85 )

+      fatal("$i.field attrib ref too big");

+      zzbegexpr[strlen(zzbegexpr)-1] = ' ';

+      set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);

+      if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",

+      BlkLevel-1,zzbegexpr+1);

+      else sprintf(buf,"_t%d%s.",

+      BlkLevel-1,zzbegexpr+1);

+      zzreplstr(buf);

+      zzmore();

+      UsedOldStyleAttrib = 1;

+      if ( UsedNewStyleLabel )

+      err("cannot mix old-style $i with new-style labels");

+    }

+	}

+

+

+static void act115()

+{ 

+		NLA = 47;

+    {

+      static char buf[100];

+      static char i[20], j[20];

+      char *p,*q;

+      numericActionLabel=1;       /* MR10 */

+      if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");

+      for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {

+        if ( q == &i[20] )

+        fatalFL("i of $i.j attrib ref too big",

+        FileStr[CurFile], zzline );

+        *q++ = *p;

+      }

+      *q = '\0';

+      for (p++, q= &j[0]; *p!='\0'; p++) {

+        if ( q == &j[20] )

+        fatalFL("j of $i.j attrib ref too big",

+        FileStr[CurFile], zzline );

+        *q++ = *p;

+      }

+      *q = '\0';

+      if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);

+      else sprintf(buf,"_t%s%s",i,j);

+      zzreplstr(buf);

+      zzmore();

+      UsedOldStyleAttrib = 1;

+      if ( UsedNewStyleLabel )

+      err("cannot mix old-style $i with new-style labels");

+    }

+	}

+

+

+static void act116()

+{ 

+		NLA = 48;

+    { static char buf[300]; LabelEntry *el;

+      zzbegexpr[0] = ' ';

+      if ( CurRule != NULL &&

+      strcmp(CurRule, &zzbegexpr[1])==0 ) {

+        if ( !GenCC ) zzreplstr("zzaRet");

+      }

+      else if ( CurRetDef != NULL &&

+      strmember(CurRetDef, &zzbegexpr[1])) {

+        if ( hasMultipleOperands( CurRetDef ) ) {

+          require (strlen(zzbegexpr)<=(size_t)285,

+          "$retval attrib ref too big");

+          sprintf(buf,"_retv.%s",&zzbegexpr[1]);

+          zzreplstr(buf);

+        }

+        else zzreplstr("_retv");

+      }

+      else if ( CurParmDef != NULL &&

+      strmember(CurParmDef, &zzbegexpr[1])) {

+      ;

+    }

+    else if ( Elabel==NULL ) {

+    { err("$-variables in actions outside of rules are not allowed"); }

+  } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {

+  /* MR10 */

+  /* MR10 */                      /* element labels might exist without an elem when */

+  /* MR10 */                      /*  it is a forward reference (to a rule)          */

+  /* MR10 */

+  /* MR10 */						if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )

+  /* MR10 */							{ err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }

+  /* MR10 */

+  /* MR10 */						if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {

+  /* MR10 */                          err("You can no longer use attributes returned by rules when also using ASTs");

+  /* MR10 */                          err("   Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...>>\")");

+  /* MR10 */                      };

+  /* MR10 */

+  /* MR10 */                      /* keep track of <<... $label ...>> for semantic predicates in guess mode */

+  /* MR10 */                      /* element labels contain pointer to the owners node                      */

+  /* MR10 */

+  /* MR10 */                      if (el->elem != NULL && el->elem->ntype == nToken) {

+  /* MR10 */                        list_add(&CurActionLabels,el);

+  /* MR10 */                      };

+}

+else

+warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));

+}

+zzmore();

+	}

+

+

+static void act117()

+{ 

+		NLA = 49;

+    zzreplstr("(*_root)"); zzmore(); chkGTFlag();   

+	}

+

+

+static void act118()

+{ 

+		NLA = 50;

+    if ( GenCC ) {

+      if (NewAST) zzreplstr("(newAST)");

+      else zzreplstr("(new AST)");}

+    else {zzreplstr("zzastnew()");} zzmore();

+    chkGTFlag();

+	}

+

+

+static void act119()

+{ 

+		NLA = 51;

+    zzreplstr("NULL"); zzmore(); chkGTFlag();   

+	}

+

+

+static void act120()

+{ 

+		NLA = 52;

+    {

+      static char buf[100];

+      if ( strlen(zzbegexpr)>(size_t)85 )

+      fatal("#i AST ref too big");

+      if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);

+      else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);

+      zzreplstr(buf);

+      zzmore();

+      set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);

+      chkGTFlag();

+    }

+	}

+

+

+static void act121()

+{ 

+		NLA = 53;

+    

+    zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();

+    getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);

+	}

+

+

+static void act122()

+{ 

+		NLA = 54;

+    

+    zzline++; zzmore();

+	}

+

+

+static void act123()

+{ 

+		NLA = 55;

+    

+    if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||

+    strcmp(zzbegexpr, "#if")==0 ||

+    strcmp(zzbegexpr, "#else")==0 ||

+    strcmp(zzbegexpr, "#endif")==0 ||

+    strcmp(zzbegexpr, "#ifndef")==0 ||

+    strcmp(zzbegexpr, "#define")==0 ||

+    strcmp(zzbegexpr, "#pragma")==0 ||

+    strcmp(zzbegexpr, "#undef")==0 ||

+    strcmp(zzbegexpr, "#import")==0 ||

+    strcmp(zzbegexpr, "#line")==0 ||

+    strcmp(zzbegexpr, "#include")==0 ||

+    strcmp(zzbegexpr, "#error")==0) )

+    {

+      static char buf[100];

+      sprintf(buf, "%s_ast", zzbegexpr+1);

+      /* MR27 */						list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));

+      zzreplstr(buf);

+      chkGTFlag();

+    }

+    zzmore();

+	}

+

+

+static void act124()

+{ 

+		NLA = 56;

+    

+    pushint(']');

+    if ( GenCC ) {

+      if (NewAST) zzreplstr("(newAST(");

+      else zzreplstr("(new AST("); }

+    else zzreplstr("zzmk_ast(zzastnew(),");

+    zzmore();

+    chkGTFlag();

+	}

+

+

+static void act125()

+{ 

+		NLA = 57;

+    

+    pushint('}');

+    if ( GenCC ) {

+      if (tmakeInParser) {

+        zzreplstr("tmake(");

+      }

+      else {

+        zzreplstr("ASTBase::tmake(");

+      }

+    }

+    else {

+      zzreplstr("zztmake(");

+    }

+    zzmore();

+    chkGTFlag();

+	}

+

+

+static void act126()

+{ 

+		NLA = 58;

+    zzmore();   

+	}

+

+

+static void act127()

+{ 

+		NLA = 59;

+    

+    if ( istackempty() )

+    zzmore();

+    else if ( topint()==')' ) {

+      popint();

+    }

+    else if ( topint()=='}' ) {

+      popint();

+      /* terminate #(..) */

+      zzreplstr(", NULL)");

+    }

+    zzmore();

+	}

+

+

+static void act128()

+{ 

+		NLA = 60;

+    

+    pushint('|');	/* look for '|' to terminate simple [...] */

+    zzmore();

+	}

+

+

+static void act129()

+{ 

+		NLA = 61;

+    

+    pushint(')');

+    zzmore();

+	}

+

+

+static void act130()

+{ 

+		NLA = 62;

+    zzreplstr("]");  zzmore();   

+	}

+

+

+static void act131()

+{ 

+		NLA = 63;

+    zzreplstr(")");  zzmore();   

+	}

+

+

+static void act132()

+{ 

+		NLA = 64;

+    if (! tokenActionActive) zzreplstr(">");	 /* MR1 */

+    zzmore();				         /* MR1 */

+	}

+

+

+static void act133()

+{ 

+		NLA = 65;

+    zzmode(ACTION_CHARS); zzmore();  

+	}

+

+

+static void act134()

+{ 

+		NLA = 66;

+    zzmode(ACTION_STRINGS); zzmore();  

+	}

+

+

+static void act135()

+{ 

+		NLA = 67;

+    zzreplstr("$");  zzmore();   

+	}

+

+

+static void act136()

+{ 

+		NLA = 68;

+    zzreplstr("#");  zzmore();   

+	}

+

+

+static void act137()

+{ 

+		NLA = 69;

+    zzline++; zzmore();   

+	}

+

+

+static void act138()

+{ 

+		NLA = 70;

+    zzmore();   

+	}

+

+

+static void act139()

+{ 

+		NLA = 71;

+    zzmore();   

+	}

+

+

+static void act140()

+{ 

+		NLA = 72;

+    zzmode(ACTION_COMMENTS); zzmore();   

+	}

+

+

+static void act141()

+{ 

+		NLA = 73;

+    warn("Missing /*; found dangling */ in action"); zzmore();   

+	}

+

+

+static void act142()

+{ 

+		NLA = 74;

+    zzmode(ACTION_CPP_COMMENTS); zzmore();   

+	}

+

+

+static void act143()

+{ 

+		NLA = 75;

+    zzmore();   

+	}

+

+static unsigned char shift10[257] = {

+  0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  16, 19, 33, 33, 20, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 16, 33, 28, 27, 21, 33, 33, 

+  30, 15, 18, 32, 33, 33, 33, 25, 31, 23, 

+  24, 24, 24, 24, 24, 24, 24, 24, 24, 33, 

+  33, 33, 33, 1, 2, 33, 26, 26, 26, 26, 

+  26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 

+  26, 26, 26, 26, 26, 26, 11, 26, 26, 26, 

+  26, 26, 22, 29, 3, 33, 26, 33, 26, 26, 

+  4, 26, 10, 26, 26, 26, 13, 26, 26, 14, 

+  9, 6, 5, 26, 26, 26, 7, 12, 8, 26, 

+  26, 26, 26, 26, 17, 33, 34, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33

+};

+

+

+static void act144()

+{ 

+		NLA = Eof;

+    ;   

+	}

+

+

+static void act145()

+{ 

+		NLA = 137;

+    zzskip();   

+	}

+

+

+static void act146()

+{ 

+		NLA = 138;

+    zzline++; zzskip();   

+	}

+

+

+static void act147()

+{ 

+		NLA = 139;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzmore();   

+	}

+

+

+static void act148()

+{ 

+		NLA = 140;

+    zzmode(TOK_DEF_COMMENTS); zzskip();   

+	}

+

+

+static void act149()

+{ 

+		NLA = 141;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act150()

+{ 

+		NLA = 142;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act151()

+{ 

+		NLA = 143;

+    ;   

+	}

+

+

+static void act152()

+{ 

+		NLA = 144;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act153()

+{ 

+		NLA = 145;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act154()

+{ 

+		NLA = 146;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act155()

+{ 

+		NLA = 147;

+    zzmode(TOK_DEF_CPP_COMMENTS); zzskip();   

+	}

+

+

+static void act156()

+{ 

+		NLA = 149;

+	}

+

+

+static void act157()

+{ 

+		NLA = 151;

+	}

+

+

+static void act158()

+{ 

+		NLA = 152;

+	}

+

+

+static void act159()

+{ 

+		NLA = 153;

+	}

+

+

+static void act160()

+{ 

+		NLA = 154;

+	}

+

+

+static void act161()

+{ 

+		NLA = 155;

+	}

+

+

+static void act162()

+{ 

+		NLA = 156;

+	}

+

+

+static void act163()

+{ 

+		NLA = INT;

+	}

+

+

+static void act164()

+{ 

+		NLA = ID;

+	}

+

+static unsigned char shift11[257] = {

+  0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  1, 2, 27, 27, 3, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 1, 27, 27, 6, 27, 27, 27, 

+  27, 27, 27, 5, 27, 22, 27, 27, 4, 25, 

+  25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 

+  24, 27, 21, 27, 27, 27, 26, 26, 26, 26, 

+  26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 

+  26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 

+  26, 26, 27, 27, 27, 27, 26, 27, 26, 26, 

+  26, 9, 10, 8, 26, 26, 7, 26, 26, 12, 

+  15, 11, 17, 16, 26, 18, 13, 19, 14, 26, 

+  26, 26, 26, 26, 20, 27, 23, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 

+  27, 27, 27, 27, 27, 27, 27

+};

+

+#define DfaStates	436

+typedef unsigned short DfaState;

+

+static DfaState st0[60] = {

+  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 

+  11, 11, 11, 12, 13, 13, 13, 14, 15, 16, 

+  17, 11, 11, 18, 11, 11, 19, 11, 11, 19, 

+  11, 11, 11, 11, 20, 11, 11, 21, 22, 23, 

+  24, 25, 26, 11, 27, 28, 29, 30, 31, 32, 

+  33, 34, 35, 36, 11, 11, 19, 436, 436, 436

+};

+

+static DfaState st1[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st2[60] = {

+  436, 2, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st3[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st4[60] = {

+  436, 436, 37, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st5[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st6[60] = {

+  436, 436, 436, 436, 436, 38, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st7[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st8[60] = {

+  436, 436, 436, 436, 436, 436, 436, 39, 40, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st9[60] = {

+  436, 436, 436, 436, 436, 436, 436, 41, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st10[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  42, 43, 43, 44, 43, 43, 43, 436, 436, 436, 

+  436, 45, 43, 43, 43, 43, 46, 43, 47, 43, 

+  43, 43, 43, 48, 43, 49, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st11[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st12[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 51, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st13[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 13, 13, 13, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st14[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 52, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st15[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 53, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st16[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st17[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 54, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st18[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 55, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st19[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  56, 56, 56, 56, 56, 56, 56, 436, 436, 436, 

+  436, 56, 56, 56, 56, 56, 56, 56, 56, 56, 

+  56, 56, 56, 56, 56, 56, 56, 436, 56, 436, 

+  436, 436, 436, 56, 436, 436, 436, 436, 436, 436, 

+  436, 56, 436, 436, 56, 56, 56, 56, 436, 436

+};

+

+static DfaState st20[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 57, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st21[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st22[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  58, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 59, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st23[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st24[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st25[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st26[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st27[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 60, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st28[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 61, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st29[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st30[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st31[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 62, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st32[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st33[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st34[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  56, 56, 56, 56, 56, 56, 56, 436, 436, 436, 

+  436, 56, 56, 56, 56, 56, 56, 56, 56, 56, 

+  56, 56, 56, 56, 56, 56, 56, 436, 56, 436, 

+  436, 436, 436, 56, 436, 436, 436, 436, 436, 436, 

+  436, 63, 436, 436, 56, 56, 56, 56, 436, 436

+};

+

+static DfaState st35[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st36[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st37[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st38[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st39[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st40[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st41[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st42[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 64, 43, 65, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st43[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st44[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 66, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st45[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 67, 68, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st46[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 69, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st47[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 70, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st48[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 71, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st49[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 72, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st50[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st51[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 73, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st52[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st53[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st54[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  74, 43, 43, 44, 43, 43, 43, 436, 436, 436, 

+  436, 45, 43, 43, 43, 43, 46, 43, 47, 43, 

+  43, 43, 43, 48, 43, 49, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st55[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 75, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st56[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  56, 56, 56, 56, 56, 56, 56, 436, 436, 436, 

+  436, 56, 56, 56, 56, 56, 56, 56, 56, 56, 

+  56, 56, 56, 56, 56, 56, 56, 436, 56, 436, 

+  436, 436, 436, 56, 436, 436, 436, 436, 436, 436, 

+  436, 56, 436, 436, 56, 56, 56, 56, 436, 436

+};

+

+static DfaState st57[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 76, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st58[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 77, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st59[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 78, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st60[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st61[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st62[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st63[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  56, 56, 56, 56, 56, 56, 56, 436, 436, 436, 

+  436, 56, 56, 56, 56, 56, 56, 56, 56, 56, 

+  56, 56, 56, 56, 56, 56, 56, 436, 56, 436, 

+  436, 436, 436, 56, 436, 436, 79, 436, 436, 436, 

+  436, 56, 436, 436, 56, 56, 56, 56, 436, 436

+};

+

+static DfaState st64[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 80, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st65[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 81, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st66[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 82, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st67[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 83, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 84, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st68[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 85, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st69[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 86, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st70[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 87, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st71[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 88, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st72[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 89, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st73[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 90, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st74[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 65, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st75[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 91, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st76[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 92, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st77[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 93, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st78[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 94, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st79[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 95, 96, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st80[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 97, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st81[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 98, 43, 99, 43, 100, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 101, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st82[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 102, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st83[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 103, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st84[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 104, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st85[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 105, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st86[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 106, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st87[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 107, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 108, 43, 43, 436, 109, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st88[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 110, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st89[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 111, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st90[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 112, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st91[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 113, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st92[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 114, 50, 50, 50, 436, 436

+};

+

+static DfaState st93[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 115, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st94[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 116, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st95[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 117, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st96[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 118, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st97[60] = {

+  436, 119, 120, 121, 122, 122, 122, 122, 122, 122, 

+  123, 123, 123, 123, 124, 124, 124, 122, 122, 122, 

+  122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 

+  123, 123, 123, 123, 123, 123, 123, 122, 123, 122, 

+  122, 122, 122, 123, 122, 122, 122, 122, 122, 122, 

+  122, 123, 122, 122, 123, 123, 123, 123, 122, 436

+};

+

+static DfaState st98[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 125, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st99[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 126, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st100[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 127, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st101[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  128, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st102[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  129, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st103[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st104[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 130, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st105[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 131, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st106[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 132, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st107[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 133, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st108[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 134, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st109[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  135, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st110[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 136, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st111[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 137, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st112[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 138, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st113[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 139, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st114[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  140, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st115[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st116[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st117[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st118[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st119[60] = {

+  436, 119, 120, 121, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 141, 141, 141, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st120[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st121[60] = {

+  436, 436, 142, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st122[60] = {

+  436, 122, 120, 121, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st123[60] = {

+  436, 122, 120, 121, 122, 122, 122, 122, 122, 122, 

+  123, 123, 123, 123, 123, 123, 123, 122, 122, 122, 

+  122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 

+  123, 123, 123, 123, 123, 123, 123, 122, 123, 122, 

+  122, 122, 122, 123, 122, 122, 122, 122, 122, 122, 

+  122, 123, 122, 122, 123, 123, 123, 123, 122, 436

+};

+

+static DfaState st124[60] = {

+  436, 143, 144, 145, 122, 122, 146, 122, 122, 122, 

+  123, 123, 123, 123, 124, 124, 124, 122, 122, 122, 

+  122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 

+  123, 123, 123, 123, 123, 123, 123, 122, 123, 122, 

+  122, 122, 122, 123, 122, 122, 122, 122, 122, 122, 

+  122, 123, 122, 122, 123, 123, 123, 123, 122, 436

+};

+

+static DfaState st125[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 147, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st126[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 148, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st127[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 149, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st128[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 150, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st129[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 151, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st130[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 152, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st131[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 153, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st132[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 154, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st133[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st134[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 155, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st135[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 156, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st136[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 157, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st137[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st138[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 158, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st139[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st140[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 159, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st141[60] = {

+  436, 143, 144, 145, 122, 122, 146, 122, 122, 122, 

+  122, 122, 122, 122, 141, 141, 141, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st142[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st143[60] = {

+  436, 143, 120, 121, 122, 122, 146, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st144[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st145[60] = {

+  436, 436, 160, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st146[60] = {

+  436, 161, 162, 163, 161, 161, 122, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 436

+};

+

+static DfaState st147[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 164, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st148[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 165, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st149[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 166, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st150[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 167, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st151[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 168, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st152[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st153[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st154[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 169, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st155[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 170, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st156[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 171, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st157[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st158[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 172, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st159[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st160[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st161[60] = {

+  436, 161, 162, 163, 161, 161, 173, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 

+  161, 161, 161, 161, 161, 161, 161, 161, 161, 436

+};

+

+static DfaState st162[60] = {

+  436, 174, 174, 174, 174, 174, 175, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 436

+};

+

+static DfaState st163[60] = {

+  436, 174, 176, 174, 174, 174, 175, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 436

+};

+

+static DfaState st164[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 177, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st165[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 178, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st166[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 179, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st167[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 180, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st168[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 181, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st169[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 182, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st170[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st171[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 183, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st172[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 184, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st173[60] = {

+  436, 185, 144, 145, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 186, 186, 186, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st174[60] = {

+  436, 174, 174, 174, 174, 174, 175, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 436

+};

+

+static DfaState st175[60] = {

+  436, 187, 188, 189, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 190, 190, 190, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st176[60] = {

+  436, 174, 174, 174, 174, 174, 175, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 

+  174, 174, 174, 174, 174, 174, 174, 174, 174, 436

+};

+

+static DfaState st177[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 191, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st178[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 192, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st179[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 193, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st180[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st181[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st182[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 194, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st183[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st184[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  50, 50, 50, 50, 50, 50, 50, 436, 436, 436, 

+  436, 50, 50, 50, 50, 50, 50, 50, 50, 50, 

+  50, 50, 50, 50, 50, 50, 50, 436, 50, 436, 

+  436, 436, 436, 50, 436, 436, 436, 436, 436, 436, 

+  436, 50, 436, 436, 50, 50, 50, 50, 436, 436

+};

+

+static DfaState st185[60] = {

+  436, 185, 144, 145, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 186, 186, 186, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st186[60] = {

+  436, 185, 144, 145, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 186, 186, 186, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 

+  122, 122, 122, 122, 122, 122, 122, 122, 122, 436

+};

+

+static DfaState st187[60] = {

+  436, 187, 188, 189, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 190, 190, 190, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st188[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st189[60] = {

+  436, 436, 195, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st190[60] = {

+  436, 187, 188, 189, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 190, 190, 190, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st191[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st192[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st193[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st194[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  196, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st195[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st196[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 197, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st197[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 198, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st198[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 199, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st199[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  200, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st200[60] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  43, 43, 43, 43, 43, 43, 43, 436, 436, 436, 

+  436, 43, 43, 43, 43, 43, 43, 43, 43, 43, 

+  43, 43, 43, 43, 43, 43, 43, 436, 43, 436, 

+  436, 436, 436, 43, 436, 436, 436, 436, 436, 436, 

+  436, 43, 436, 436, 43, 43, 43, 43, 436, 436

+};

+

+static DfaState st201[7] = {

+  202, 203, 204, 205, 206, 207, 436

+};

+

+static DfaState st202[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st203[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st204[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st205[7] = {

+  436, 436, 208, 436, 436, 436, 436

+};

+

+static DfaState st206[7] = {

+  436, 209, 210, 211, 209, 209, 436

+};

+

+static DfaState st207[7] = {

+  436, 436, 436, 436, 436, 207, 436

+};

+

+static DfaState st208[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st209[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st210[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st211[7] = {

+  436, 436, 212, 436, 436, 436, 436

+};

+

+static DfaState st212[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st213[7] = {

+  214, 215, 216, 217, 218, 219, 436

+};

+

+static DfaState st214[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st215[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st216[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st217[7] = {

+  436, 436, 220, 436, 436, 436, 436

+};

+

+static DfaState st218[7] = {

+  436, 221, 222, 223, 221, 221, 436

+};

+

+static DfaState st219[7] = {

+  436, 436, 436, 436, 436, 219, 436

+};

+

+static DfaState st220[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st221[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st222[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st223[7] = {

+  436, 436, 224, 436, 436, 436, 436

+};

+

+static DfaState st224[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st225[7] = {

+  226, 227, 228, 229, 230, 231, 436

+};

+

+static DfaState st226[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st227[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st228[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st229[7] = {

+  436, 436, 232, 436, 436, 436, 436

+};

+

+static DfaState st230[7] = {

+  436, 233, 233, 233, 233, 233, 436

+};

+

+static DfaState st231[7] = {

+  436, 436, 436, 436, 436, 231, 436

+};

+

+static DfaState st232[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st233[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st234[7] = {

+  235, 236, 237, 238, 239, 237, 436

+};

+

+static DfaState st235[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st236[7] = {

+  436, 436, 240, 436, 436, 436, 436

+};

+

+static DfaState st237[7] = {

+  436, 436, 237, 436, 436, 237, 436

+};

+

+static DfaState st238[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st239[7] = {

+  436, 436, 436, 241, 436, 436, 436

+};

+

+static DfaState st240[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st241[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st242[7] = {

+  243, 244, 245, 246, 247, 245, 436

+};

+

+static DfaState st243[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st244[7] = {

+  436, 436, 248, 436, 436, 436, 436

+};

+

+static DfaState st245[7] = {

+  436, 436, 245, 436, 436, 245, 436

+};

+

+static DfaState st246[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st247[7] = {

+  436, 436, 436, 249, 436, 436, 436

+};

+

+static DfaState st248[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st249[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st250[5] = {

+  251, 252, 253, 254, 436

+};

+

+static DfaState st251[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st252[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st253[5] = {

+  436, 255, 436, 436, 436

+};

+

+static DfaState st254[5] = {

+  436, 436, 436, 254, 436

+};

+

+static DfaState st255[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st256[5] = {

+  257, 258, 259, 260, 436

+};

+

+static DfaState st257[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st258[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st259[5] = {

+  436, 261, 436, 436, 436

+};

+

+static DfaState st260[5] = {

+  436, 436, 436, 260, 436

+};

+

+static DfaState st261[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st262[5] = {

+  263, 264, 265, 266, 436

+};

+

+static DfaState st263[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st264[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st265[5] = {

+  436, 267, 436, 436, 436

+};

+

+static DfaState st266[5] = {

+  436, 436, 436, 266, 436

+};

+

+static DfaState st267[5] = {

+  436, 436, 436, 436, 436

+};

+

+static DfaState st268[7] = {

+  269, 270, 271, 272, 273, 271, 436

+};

+

+static DfaState st269[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st270[7] = {

+  436, 436, 274, 436, 436, 436, 436

+};

+

+static DfaState st271[7] = {

+  436, 436, 271, 436, 436, 271, 436

+};

+

+static DfaState st272[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st273[7] = {

+  436, 436, 436, 275, 436, 436, 436

+};

+

+static DfaState st274[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st275[7] = {

+  436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st276[36] = {

+  277, 278, 279, 280, 281, 279, 279, 279, 279, 279, 

+  279, 279, 279, 279, 279, 282, 279, 279, 283, 284, 

+  285, 286, 287, 279, 279, 279, 279, 288, 289, 290, 

+  291, 292, 293, 279, 279, 436

+};

+

+static DfaState st277[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st278[36] = {

+  436, 294, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st279[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st280[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st281[36] = {

+  436, 436, 279, 436, 279, 295, 279, 279, 279, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st282[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st283[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st284[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st285[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 296, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st286[36] = {

+  436, 436, 436, 436, 297, 297, 297, 297, 297, 297, 

+  297, 297, 297, 297, 297, 436, 436, 436, 436, 436, 

+  436, 298, 299, 300, 300, 436, 297, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st287[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st288[36] = {

+  436, 436, 436, 436, 301, 301, 301, 301, 301, 301, 

+  301, 301, 301, 301, 302, 303, 436, 436, 436, 436, 

+  436, 436, 304, 305, 306, 436, 301, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st289[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st290[36] = {

+  436, 307, 308, 309, 308, 308, 308, 308, 308, 308, 

+  308, 308, 308, 308, 308, 308, 308, 308, 310, 311, 

+  312, 313, 308, 308, 308, 308, 308, 314, 308, 308, 

+  308, 308, 308, 308, 308, 436

+};

+

+static DfaState st291[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st292[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 315, 316, 436, 436, 436

+};

+

+static DfaState st293[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 317, 279, 279, 279, 436

+};

+

+static DfaState st294[36] = {

+  436, 436, 318, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st295[36] = {

+  436, 436, 279, 436, 279, 279, 319, 279, 279, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st296[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st297[36] = {

+  436, 436, 436, 436, 320, 320, 320, 320, 320, 320, 

+  320, 320, 320, 320, 320, 436, 436, 436, 436, 436, 

+  436, 436, 436, 320, 320, 436, 320, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st298[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st299[36] = {

+  436, 436, 436, 321, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st300[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 300, 300, 322, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st301[36] = {

+  436, 436, 436, 436, 323, 323, 323, 323, 323, 323, 

+  323, 323, 323, 323, 323, 436, 436, 436, 436, 436, 

+  436, 436, 436, 323, 323, 436, 323, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st302[36] = {

+  436, 436, 436, 436, 323, 323, 323, 323, 323, 323, 

+  323, 323, 323, 324, 323, 436, 436, 436, 436, 436, 

+  436, 436, 436, 323, 323, 436, 323, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st303[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 325, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st304[36] = {

+  436, 436, 436, 326, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st305[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 306, 306, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st306[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 306, 306, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st307[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st308[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st309[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st310[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st311[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st312[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 327, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st313[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st314[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st315[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st316[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st317[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st318[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st319[36] = {

+  436, 436, 279, 436, 279, 279, 279, 328, 279, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st320[36] = {

+  436, 436, 436, 436, 320, 320, 320, 320, 320, 320, 

+  320, 320, 320, 320, 320, 436, 436, 436, 436, 436, 

+  436, 436, 436, 320, 320, 436, 320, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st321[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st322[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 329, 329, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st323[36] = {

+  436, 436, 436, 436, 323, 323, 323, 323, 323, 323, 

+  323, 323, 323, 323, 323, 436, 436, 436, 436, 436, 

+  436, 436, 436, 323, 323, 436, 323, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st324[36] = {

+  436, 436, 436, 436, 323, 323, 330, 323, 323, 323, 

+  323, 323, 323, 323, 323, 436, 436, 436, 436, 436, 

+  436, 436, 436, 323, 323, 436, 323, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st325[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st326[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st327[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st328[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 331, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st329[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 329, 329, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st330[36] = {

+  436, 436, 436, 436, 323, 323, 323, 323, 323, 323, 

+  332, 323, 323, 323, 323, 436, 436, 436, 436, 436, 

+  436, 436, 436, 323, 323, 436, 323, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st331[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 333, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st332[36] = {

+  436, 334, 334, 334, 335, 335, 335, 335, 335, 335, 

+  335, 335, 335, 335, 335, 334, 336, 334, 334, 337, 

+  338, 334, 334, 339, 339, 334, 335, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st333[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  340, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st334[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 334, 334, 334, 337, 

+  338, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st335[36] = {

+  436, 334, 334, 334, 335, 335, 335, 335, 335, 335, 

+  335, 335, 335, 335, 335, 334, 334, 334, 334, 337, 

+  338, 334, 334, 335, 335, 334, 335, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st336[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 336, 334, 334, 337, 

+  338, 334, 334, 341, 341, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st337[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st338[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 342, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st339[36] = {

+  436, 334, 334, 334, 335, 335, 335, 335, 335, 335, 

+  335, 335, 335, 335, 335, 334, 343, 334, 334, 344, 

+  345, 334, 334, 339, 339, 334, 335, 334, 346, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st340[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 347, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st341[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 343, 334, 334, 344, 

+  345, 334, 334, 341, 341, 334, 334, 334, 346, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st342[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st343[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 343, 334, 334, 337, 

+  338, 334, 334, 334, 334, 334, 334, 334, 346, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st344[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st345[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 348, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st346[36] = {

+  436, 349, 349, 349, 349, 349, 349, 349, 349, 349, 

+  349, 349, 349, 349, 349, 349, 349, 349, 349, 350, 

+  351, 349, 349, 349, 349, 349, 349, 349, 334, 349, 

+  349, 349, 349, 349, 349, 436

+};

+

+static DfaState st347[36] = {

+  436, 436, 279, 436, 279, 279, 352, 279, 279, 279, 

+  279, 279, 279, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st348[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st349[36] = {

+  436, 349, 349, 349, 349, 349, 349, 349, 349, 349, 

+  349, 349, 349, 349, 349, 349, 349, 349, 349, 350, 

+  351, 349, 349, 349, 349, 349, 349, 349, 353, 349, 

+  349, 349, 349, 349, 349, 436

+};

+

+static DfaState st350[36] = {

+  436, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 355, 354, 

+  354, 354, 354, 354, 354, 436

+};

+

+static DfaState st351[36] = {

+  436, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 354, 356, 

+  354, 354, 354, 354, 354, 354, 354, 354, 355, 354, 

+  354, 354, 354, 354, 354, 436

+};

+

+static DfaState st352[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 279, 357, 279, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st353[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 358, 334, 334, 344, 

+  345, 334, 334, 359, 359, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st354[36] = {

+  436, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 355, 354, 

+  354, 354, 354, 354, 354, 436

+};

+

+static DfaState st355[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 360, 436, 436, 361, 

+  362, 436, 436, 363, 363, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st356[36] = {

+  436, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 

+  354, 354, 354, 354, 354, 354, 354, 354, 355, 354, 

+  354, 354, 354, 354, 354, 436

+};

+

+static DfaState st357[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 279, 279, 364, 279, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st358[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 358, 334, 334, 344, 

+  345, 334, 334, 359, 359, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st359[36] = {

+  436, 334, 334, 334, 334, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 334, 358, 334, 334, 344, 

+  345, 334, 334, 359, 359, 334, 334, 334, 334, 334, 

+  334, 334, 334, 334, 334, 436

+};

+

+static DfaState st360[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 360, 436, 436, 361, 

+  362, 436, 436, 363, 363, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st361[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st362[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 365, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st363[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 360, 436, 436, 361, 

+  362, 436, 436, 363, 363, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st364[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 279, 279, 279, 366, 436, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st365[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st366[36] = {

+  436, 436, 279, 436, 279, 279, 279, 279, 279, 279, 

+  279, 279, 279, 279, 279, 367, 279, 279, 436, 436, 

+  436, 436, 436, 279, 279, 279, 279, 436, 436, 436, 

+  436, 436, 279, 279, 279, 436

+};

+

+static DfaState st367[36] = {

+  436, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 368, 369, 370, 436, 368, 

+  368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 436

+};

+

+static DfaState st368[36] = {

+  436, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 368, 368, 368, 371, 368, 

+  368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 436

+};

+

+static DfaState st369[36] = {

+  436, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 368, 369, 370, 371, 368, 

+  368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 436

+};

+

+static DfaState st370[36] = {

+  436, 372, 372, 372, 372, 372, 372, 372, 372, 372, 

+  372, 372, 372, 372, 372, 372, 372, 372, 373, 372, 

+  372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 

+  372, 372, 372, 372, 368, 436

+};

+

+static DfaState st371[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st372[36] = {

+  436, 372, 372, 372, 372, 372, 372, 372, 372, 372, 

+  372, 372, 372, 372, 372, 372, 372, 372, 373, 372, 

+  372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 

+  372, 372, 372, 372, 374, 436

+};

+

+static DfaState st373[36] = {

+  436, 375, 375, 375, 375, 375, 375, 375, 375, 375, 

+  375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 

+  375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 

+  375, 375, 375, 375, 376, 436

+};

+

+static DfaState st374[36] = {

+  436, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 368, 377, 368, 378, 368, 

+  368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 436

+};

+

+static DfaState st375[36] = {

+  436, 375, 375, 375, 375, 375, 375, 375, 375, 375, 

+  375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 

+  375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 

+  375, 375, 375, 375, 376, 436

+};

+

+static DfaState st376[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 379, 436, 380, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st377[36] = {

+  436, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 368, 377, 368, 378, 368, 

+  368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 

+  368, 368, 368, 368, 368, 436

+};

+

+static DfaState st378[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st379[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 379, 436, 380, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st380[36] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436

+};

+

+static DfaState st381[28] = {

+  382, 383, 384, 385, 386, 436, 387, 388, 388, 388, 

+  389, 388, 388, 388, 388, 388, 388, 388, 388, 388, 

+  390, 391, 392, 393, 394, 395, 388, 436

+};

+

+static DfaState st382[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st383[28] = {

+  436, 383, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st384[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st385[28] = {

+  436, 436, 396, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st386[28] = {

+  436, 436, 436, 436, 397, 398, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st387[28] = {

+  436, 436, 436, 436, 436, 436, 436, 399, 436, 400, 

+  401, 436, 436, 436, 402, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st388[28] = {

+  436, 436, 436, 436, 436, 436, 436, 403, 403, 403, 

+  403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 

+  436, 436, 436, 436, 436, 403, 403, 436

+};

+

+static DfaState st389[28] = {

+  436, 436, 436, 436, 436, 436, 436, 403, 403, 403, 

+  403, 404, 403, 403, 403, 403, 403, 403, 403, 403, 

+  436, 436, 436, 436, 436, 403, 403, 436

+};

+

+static DfaState st390[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st391[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st392[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st393[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st394[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st395[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 395, 436, 436

+};

+

+static DfaState st396[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st397[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st398[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st399[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 405, 436, 

+  436, 436, 436, 436, 436, 406, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st400[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  407, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st401[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 408, 409, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st402[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 410, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st403[28] = {

+  436, 436, 436, 436, 436, 436, 436, 403, 403, 403, 

+  403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 

+  436, 436, 436, 436, 436, 403, 403, 436

+};

+

+static DfaState st404[28] = {

+  436, 436, 436, 436, 436, 436, 436, 403, 403, 403, 

+  403, 403, 403, 403, 411, 403, 403, 403, 403, 403, 

+  436, 436, 436, 436, 436, 403, 403, 436

+};

+

+static DfaState st405[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 412, 

+  436, 413, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st406[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 414, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st407[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 415, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st408[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 416, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st409[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 417, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st410[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 418, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st411[28] = {

+  436, 436, 436, 436, 436, 436, 436, 403, 403, 403, 

+  403, 403, 403, 403, 403, 419, 403, 403, 403, 403, 

+  436, 436, 436, 436, 436, 403, 403, 436

+};

+

+static DfaState st412[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  420, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st413[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 421, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st414[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 422, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st415[28] = {

+  436, 436, 436, 436, 436, 436, 436, 423, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st416[28] = {

+  436, 436, 436, 436, 436, 436, 436, 424, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st417[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  425, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st418[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  426, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st419[28] = {

+  436, 436, 436, 436, 436, 436, 436, 403, 403, 403, 

+  403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 

+  436, 436, 436, 436, 436, 403, 403, 436

+};

+

+static DfaState st420[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 427, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st421[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  428, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st422[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 429, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st423[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 430, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st424[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 431, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st425[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st426[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 432, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st427[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st428[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 433, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st429[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 434, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st430[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  435, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st431[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st432[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st433[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st434[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+static DfaState st435[28] = {

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 

+  436, 436, 436, 436, 436, 436, 436, 436

+};

+

+

+DfaState *dfa[436] = {

+	st0,

+	st1,

+	st2,

+	st3,

+	st4,

+	st5,

+	st6,

+	st7,

+	st8,

+	st9,

+	st10,

+	st11,

+	st12,

+	st13,

+	st14,

+	st15,

+	st16,

+	st17,

+	st18,

+	st19,

+	st20,

+	st21,

+	st22,

+	st23,

+	st24,

+	st25,

+	st26,

+	st27,

+	st28,

+	st29,

+	st30,

+	st31,

+	st32,

+	st33,

+	st34,

+	st35,

+	st36,

+	st37,

+	st38,

+	st39,

+	st40,

+	st41,

+	st42,

+	st43,

+	st44,

+	st45,

+	st46,

+	st47,

+	st48,

+	st49,

+	st50,

+	st51,

+	st52,

+	st53,

+	st54,

+	st55,

+	st56,

+	st57,

+	st58,

+	st59,

+	st60,

+	st61,

+	st62,

+	st63,

+	st64,

+	st65,

+	st66,

+	st67,

+	st68,

+	st69,

+	st70,

+	st71,

+	st72,

+	st73,

+	st74,

+	st75,

+	st76,

+	st77,

+	st78,

+	st79,

+	st80,

+	st81,

+	st82,

+	st83,

+	st84,

+	st85,

+	st86,

+	st87,

+	st88,

+	st89,

+	st90,

+	st91,

+	st92,

+	st93,

+	st94,

+	st95,

+	st96,

+	st97,

+	st98,

+	st99,

+	st100,

+	st101,

+	st102,

+	st103,

+	st104,

+	st105,

+	st106,

+	st107,

+	st108,

+	st109,

+	st110,

+	st111,

+	st112,

+	st113,

+	st114,

+	st115,

+	st116,

+	st117,

+	st118,

+	st119,

+	st120,

+	st121,

+	st122,

+	st123,

+	st124,

+	st125,

+	st126,

+	st127,

+	st128,

+	st129,

+	st130,

+	st131,

+	st132,

+	st133,

+	st134,

+	st135,

+	st136,

+	st137,

+	st138,

+	st139,

+	st140,

+	st141,

+	st142,

+	st143,

+	st144,

+	st145,

+	st146,

+	st147,

+	st148,

+	st149,

+	st150,

+	st151,

+	st152,

+	st153,

+	st154,

+	st155,

+	st156,

+	st157,

+	st158,

+	st159,

+	st160,

+	st161,

+	st162,

+	st163,

+	st164,

+	st165,

+	st166,

+	st167,

+	st168,

+	st169,

+	st170,

+	st171,

+	st172,

+	st173,

+	st174,

+	st175,

+	st176,

+	st177,

+	st178,

+	st179,

+	st180,

+	st181,

+	st182,

+	st183,

+	st184,

+	st185,

+	st186,

+	st187,

+	st188,

+	st189,

+	st190,

+	st191,

+	st192,

+	st193,

+	st194,

+	st195,

+	st196,

+	st197,

+	st198,

+	st199,

+	st200,

+	st201,

+	st202,

+	st203,

+	st204,

+	st205,

+	st206,

+	st207,

+	st208,

+	st209,

+	st210,

+	st211,

+	st212,

+	st213,

+	st214,

+	st215,

+	st216,

+	st217,

+	st218,

+	st219,

+	st220,

+	st221,

+	st222,

+	st223,

+	st224,

+	st225,

+	st226,

+	st227,

+	st228,

+	st229,

+	st230,

+	st231,

+	st232,

+	st233,

+	st234,

+	st235,

+	st236,

+	st237,

+	st238,

+	st239,

+	st240,

+	st241,

+	st242,

+	st243,

+	st244,

+	st245,

+	st246,

+	st247,

+	st248,

+	st249,

+	st250,

+	st251,

+	st252,

+	st253,

+	st254,

+	st255,

+	st256,

+	st257,

+	st258,

+	st259,

+	st260,

+	st261,

+	st262,

+	st263,

+	st264,

+	st265,

+	st266,

+	st267,

+	st268,

+	st269,

+	st270,

+	st271,

+	st272,

+	st273,

+	st274,

+	st275,

+	st276,

+	st277,

+	st278,

+	st279,

+	st280,

+	st281,

+	st282,

+	st283,

+	st284,

+	st285,

+	st286,

+	st287,

+	st288,

+	st289,

+	st290,

+	st291,

+	st292,

+	st293,

+	st294,

+	st295,

+	st296,

+	st297,

+	st298,

+	st299,

+	st300,

+	st301,

+	st302,

+	st303,

+	st304,

+	st305,

+	st306,

+	st307,

+	st308,

+	st309,

+	st310,

+	st311,

+	st312,

+	st313,

+	st314,

+	st315,

+	st316,

+	st317,

+	st318,

+	st319,

+	st320,

+	st321,

+	st322,

+	st323,

+	st324,

+	st325,

+	st326,

+	st327,

+	st328,

+	st329,

+	st330,

+	st331,

+	st332,

+	st333,

+	st334,

+	st335,

+	st336,

+	st337,

+	st338,

+	st339,

+	st340,

+	st341,

+	st342,

+	st343,

+	st344,

+	st345,

+	st346,

+	st347,

+	st348,

+	st349,

+	st350,

+	st351,

+	st352,

+	st353,

+	st354,

+	st355,

+	st356,

+	st357,

+	st358,

+	st359,

+	st360,

+	st361,

+	st362,

+	st363,

+	st364,

+	st365,

+	st366,

+	st367,

+	st368,

+	st369,

+	st370,

+	st371,

+	st372,

+	st373,

+	st374,

+	st375,

+	st376,

+	st377,

+	st378,

+	st379,

+	st380,

+	st381,

+	st382,

+	st383,

+	st384,

+	st385,

+	st386,

+	st387,

+	st388,

+	st389,

+	st390,

+	st391,

+	st392,

+	st393,

+	st394,

+	st395,

+	st396,

+	st397,

+	st398,

+	st399,

+	st400,

+	st401,

+	st402,

+	st403,

+	st404,

+	st405,

+	st406,

+	st407,

+	st408,

+	st409,

+	st410,

+	st411,

+	st412,

+	st413,

+	st414,

+	st415,

+	st416,

+	st417,

+	st418,

+	st419,

+	st420,

+	st421,

+	st422,

+	st423,

+	st424,

+	st425,

+	st426,

+	st427,

+	st428,

+	st429,

+	st430,

+	st431,

+	st432,

+	st433,

+	st434,

+	st435

+};

+

+

+DfaState accepts[437] = {

+  0, 1, 2, 3, 3, 4, 25, 6, 0, 50, 

+  59, 57, 57, 43, 26, 13, 14, 0, 57, 58, 

+  57, 21, 57, 23, 24, 27, 28, 44, 0, 35, 

+  36, 42, 45, 46, 58, 51, 52, 3, 5, 9, 

+  7, 8, 59, 59, 59, 59, 59, 59, 59, 59, 

+  57, 57, 12, 40, 59, 57, 58, 57, 57, 57, 

+  33, 34, 53, 58, 59, 59, 59, 59, 59, 59, 

+  59, 59, 59, 57, 59, 57, 57, 57, 57, 0, 

+  59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 

+  57, 57, 57, 57, 57, 0, 0, 59, 59, 59, 

+  59, 59, 59, 32, 59, 59, 59, 59, 59, 59, 

+  59, 59, 57, 57, 57, 22, 56, 48, 49, 0, 

+  11, 11, 0, 59, 59, 59, 59, 59, 59, 59, 

+  59, 59, 59, 41, 59, 59, 59, 18, 57, 47, 

+  57, 0, 11, 0, 10, 10, 0, 59, 59, 59, 

+  59, 59, 15, 19, 59, 59, 59, 17, 57, 55, 

+  10, 0, 11, 11, 59, 59, 59, 59, 59, 59, 

+  20, 59, 57, 0, 0, 0, 11, 59, 59, 59, 

+  37, 38, 59, 39, 54, 0, 0, 0, 10, 10, 

+  0, 31, 29, 30, 59, 10, 59, 59, 59, 59, 

+  16, 0, 60, 61, 62, 62, 0, 65, 62, 64, 

+  63, 63, 63, 0, 66, 67, 68, 68, 0, 71, 

+  68, 70, 69, 69, 69, 0, 72, 73, 74, 74, 

+  0, 76, 74, 75, 0, 77, 79, 81, 80, 80, 

+  78, 80, 0, 82, 84, 86, 85, 85, 83, 85, 

+  0, 87, 88, 88, 89, 88, 0, 90, 91, 91, 

+  92, 91, 0, 93, 94, 94, 95, 94, 0, 96, 

+  98, 100, 99, 99, 97, 99, 0, 101, 108, 143, 

+  104, 143, 129, 127, 107, 107, 109, 128, 126, 134, 

+  0, 133, 139, 143, 102, 143, 107, 116, 110, 112, 

+  113, 123, 123, 125, 124, 117, 120, 132, 138, 130, 

+  131, 137, 137, 135, 136, 142, 140, 141, 103, 143, 

+  116, 111, 114, 123, 123, 119, 118, 137, 143, 115, 

+  123, 143, 123, 143, 0, 123, 0, 122, 122, 123, 

+  143, 0, 122, 0, 121, 121, 0, 143, 121, 0, 

+  122, 122, 143, 0, 0, 0, 122, 143, 0, 0, 

+  0, 121, 121, 0, 143, 121, 143, 0, 0, 0, 

+  0, 106, 0, 106, 0, 0, 0, 0, 105, 0, 

+  105, 0, 144, 145, 146, 146, 0, 0, 164, 164, 

+  158, 159, 160, 161, 162, 163, 146, 147, 148, 0, 

+  0, 0, 0, 164, 164, 150, 0, 0, 0, 0, 

+  0, 164, 0, 0, 0, 0, 0, 0, 0, 157, 

+  0, 0, 0, 0, 0, 152, 0, 149, 0, 0, 

+  0, 153, 154, 151, 155, 156, 0

+};

+

+void (*actions[165])() = {

+	zzerraction,

+	act1,

+	act2,

+	act3,

+	act4,

+	act5,

+	act6,

+	act7,

+	act8,

+	act9,

+	act10,

+	act11,

+	act12,

+	act13,

+	act14,

+	act15,

+	act16,

+	act17,

+	act18,

+	act19,

+	act20,

+	act21,

+	act22,

+	act23,

+	act24,

+	act25,

+	act26,

+	act27,

+	act28,

+	act29,

+	act30,

+	act31,

+	act32,

+	act33,

+	act34,

+	act35,

+	act36,

+	act37,

+	act38,

+	act39,

+	act40,

+	act41,

+	act42,

+	act43,

+	act44,

+	act45,

+	act46,

+	act47,

+	act48,

+	act49,

+	act50,

+	act51,

+	act52,

+	act53,

+	act54,

+	act55,

+	act56,

+	act57,

+	act58,

+	act59,

+	act60,

+	act61,

+	act62,

+	act63,

+	act64,

+	act65,

+	act66,

+	act67,

+	act68,

+	act69,

+	act70,

+	act71,

+	act72,

+	act73,

+	act74,

+	act75,

+	act76,

+	act77,

+	act78,

+	act79,

+	act80,

+	act81,

+	act82,

+	act83,

+	act84,

+	act85,

+	act86,

+	act87,

+	act88,

+	act89,

+	act90,

+	act91,

+	act92,

+	act93,

+	act94,

+	act95,

+	act96,

+	act97,

+	act98,

+	act99,

+	act100,

+	act101,

+	act102,

+	act103,

+	act104,

+	act105,

+	act106,

+	act107,

+	act108,

+	act109,

+	act110,

+	act111,

+	act112,

+	act113,

+	act114,

+	act115,

+	act116,

+	act117,

+	act118,

+	act119,

+	act120,

+	act121,

+	act122,

+	act123,

+	act124,

+	act125,

+	act126,

+	act127,

+	act128,

+	act129,

+	act130,

+	act131,

+	act132,

+	act133,

+	act134,

+	act135,

+	act136,

+	act137,

+	act138,

+	act139,

+	act140,

+	act141,

+	act142,

+	act143,

+	act144,

+	act145,

+	act146,

+	act147,

+	act148,

+	act149,

+	act150,

+	act151,

+	act152,

+	act153,

+	act154,

+	act155,

+	act156,

+	act157,

+	act158,

+	act159,

+	act160,

+	act161,

+	act162,

+	act163,

+	act164

+};

+

+static DfaState dfa_base[] = {

+	0,

+	201,

+	213,

+	225,

+	234,

+	242,

+	250,

+	256,

+	262,

+	268,

+	276,

+	381

+};

+

+static unsigned char *b_class_no[] = {

+	shift0,

+	shift1,

+	shift2,

+	shift3,

+	shift4,

+	shift5,

+	shift6,

+	shift7,

+	shift8,

+	shift9,

+	shift10,

+	shift11

+};

+

+

+

+#define ZZSHIFT(c) (b_class_no[zzauto][1+c])

+#define MAX_MODE 12

+#include "dlgauto.h"

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/stdpccts.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/stdpccts.h
new file mode 100644
index 0000000..ccdc21c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/stdpccts.h
@@ -0,0 +1,31 @@
+#ifndef STDPCCTS_H

+#define STDPCCTS_H

+/*

+ * stdpccts.h -- P C C T S  I n c l u d e

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#ifndef ANTLR_VERSION

+#define ANTLR_VERSION	13333

+#endif

+

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include "pcctscfg.h"

+#include "set.h"

+#include <ctype.h>

+#include "syn.h"

+#include "hash.h"

+#include "generic.h"

+#define zzcr_attr(attr,tok,t)

+#define zzSET_SIZE 20

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+#include "mode.h"

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/syn.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/syn.h
new file mode 100644
index 0000000..a23d196
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/syn.h
@@ -0,0 +1,390 @@
+/*

+ * syn.h

+ *

+ * This file includes definitions and macros associated with syntax diagrams

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include "set.h"

+

+#define NumNodeTypes	4

+#define NumJuncTypes	9

+

+/* List the different node types */

+#define nJunction		1

+#define nRuleRef		2

+#define nToken			3

+#define nAction			4

+

+/* Different types of junctions */

+#define aSubBlk			1

+#define aOptBlk			2

+#define aLoopBlk		3

+#define EndBlk			4

+#define RuleBlk			5

+#define Generic			6	/* just a junction--no unusual characteristics */

+#define EndRule			7

+#define aPlusBlk		8

+#define aLoopBegin		9

+

+typedef int NodeType;

+

+#define TreeBlockAllocSize		500

+#define JunctionBlockAllocSize	200

+#define ActionBlockAllocSize	50

+#define RRefBlockAllocSize		100

+#define TokenBlockAllocSize		100

+

+#ifdef __cplusplus

+class ActionNode;

+class Junction;

+#endif

+

+/* note that 'right' is used by the tree node allocator as a ptr for linked list */

+typedef struct _tree {

+			struct _tree *down, *right;

+			int token;

+			union {

+				int rk;	/* if token==EpToken, => how many more tokens req'd */

+				struct _tree *tref;	/* if token==TREE_REF */

+				set sref;			/* if token==SET */

+			} v;

+#ifdef TREE_DEBUG

+			int in_use;

+            int seq;

+#endif

+		} Tree;

+

+

+/* a predicate is defined to be a predicate action and a token tree with

+ * context info (if used); later, this struct may include the

+ * "hoisting distance" when we hoist past tokens.

+ *

+ * A tree is used to indicate && vs ||

+ *

+ *    p

+ *    |

+ *    q--r

+ *

+ * indicates p && (q||r).

+ *

+ * If expr is PRED_AND_LIST or PRED_OR_LIST, then it's an operation node

+ * and indicates the start of an && or || list.

+ */

+

+typedef struct _Predicate {

+	struct _Predicate *down, *right;	/* these have to be first */

+	struct _Predicate *up, *left;		/* doubly-link me */

+	char *expr;

+	Tree *tcontext;	/* used if lookahead depth of > one is needed (tree) */

+	int k;			/* lookahead depth for this tcontext */

+	set scontext[2];/* used if lookahead depth of one is needed (set) */

+					/* scontext[0] is not used; only needed so genExprSets()

+					   routine works (it expects an array)

+					 */

+	set completionTree;	/* which lookahead depths are required to complete tcontext? */

+    set completionSet;  /* MR10 separate completion set for sets and trees           */

+    struct _PredEntry *predEntry;         /* MR11 */

+

+#ifdef __cplusplus

+	ActionNode *source;	/* where did this predicate come from? */

+#else

+	struct _anode *source;	/* where did this predicate come from? */

+#endif

+

+    char             cloned;               /* MR10 don't want to free original guard pred */

+    char             redundant;            /* MR10 predicate tree simplification          */

+    char             ampersandStyle;       /* MR10  (g)? && <<p>>?                        */

+    char             inverted;             /* MR11 ! predName */

+    char             isConst;              /* MR11 */

+    char             constValue;           /* MR11 */

+    char             conflictReported;     /* MR11 */

+

+    set              plainSet;             /* MR12b */

+

+    /*** remember to change new_predicate() and predicate_dup() when changing this ***/

+

+} Predicate;

+

+typedef struct _ExceptionHandler {

+			char *signalname;

+			char *action;

+		} ExceptionHandler;

+

+typedef struct _ExceptionGroup {

+			struct _ListNode *handlers; /* list of ExceptionHandler's */

+			char *label;		/* label==""; implies not attached to any

+								 * particular rule ref.

+								 */

+			char *altID;		/* which alt did it come from (blk#:alt#) */

+

+            struct _ExceptionGroup  *pendingLink; /* for alternative EG MR7 */

+            struct _ExceptionGroup  *outerEG;     /* for alternative EG MR7 */

+            struct _LabelEntry      *labelEntry;  /* for alternative EG MR7 */

+            int                     forRule;                         /* MR7 */

+            int                     used;                            /* MR7 */

+		} ExceptionGroup ;

+

+

+#define TokenString(_i)			((TokenInd!=NULL)?TokenStr[TokenInd[_i]]:TokenStr[_i])

+#define ExprString(_i)			((TokenInd!=NULL)?ExprStr[TokenInd[_i]]:ExprStr[_i])

+

+

+				/* M e s s a g e  P a s s i n g  T o  N o d e s */

+

+/*

+ * assumes a 'Junction *r' exists.  This macro calls a function with

+ * the pointer to the node to operate on and a pointer to the rule

+ * in which it is enclosed.

+ */

+#define TRANS(p)	{if ( (p)==NULL ) fatal("TRANS: NULL object");		\

+					if ( (p)->ntype == nJunction ) (*(fpJTrans[((Junction *)(p))->jtype]))( p );\

+					else (*(fpTrans[(p)->ntype]))( p );}

+

+#define PRINT(p)	{if ( (p)==NULL ) fatal("PRINT: NULL object");\

+					(*(fpPrint[(p)->ntype]))( p );}

+

+#define REACH(p,k,rk,a) {if ( (p)==NULL ) fatal("REACH: NULL object");\

+					(a) = (*(fpReach[(p)->ntype]))( p, k, rk );}

+

+#define TRAV(p,k,rk,a) {if ( (p)==NULL ) {\

+					  if ( ContextGuardTRAV ) (a)=NULL; \

+					  else fatal("TRAV: NULL object");\

+				    } \

+					else (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );}

+

+/**

+*** #define TRAV(p,k,rk,a) {if ( (p)==NULL ) fatal("TRAV: NULL object");\

+***					(a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );}

+**/

+

+/* All syntax diagram nodes derive from Node -- superclass

+ */

+#ifdef __cplusplus

+class Node {

+public:

+			NodeType ntype;

+			char *rname;		/* what rule does this element live in? */

+			int file;			/* index in FileStr */

+			int line;			/* line number that element occurs on */

+		};

+#else

+typedef struct _node {

+			NodeType ntype;

+			char *rname;		/* what rule does this element live in? */

+			int file;			/* index in FileStr */

+			int line;			/* line number that element occurs on */

+		} Node;

+#endif

+

+#ifdef __cplusplus

+class ActionNode : public Node {

+public:

+#else

+typedef struct _anode {

+			NodeType ntype;

+			char *rname;		/* what rule does this action live in? */

+			int file;			/* index in FileStr (name of file with action) */

+			int line;			/* line number that action occurs on */

+#endif

+			Node *next;

+			char *action;

+			int is_predicate;	/* true if action is a <<...>>? predicate action */

+			int done;			/* don't dump if action dumped (used for predicates) */

+			int init_action;	/* is this the 1st action of 1st prod of block? */

+			char *pred_fail;	/* what to do/print when predicate fails */

+			Predicate  *guardpred;	/* if '(context)? =>' was present, already done */

+			unsigned char frmwarned;/* have we dumped a warning for pred yet? */

+			unsigned char ctxwarned;/* have we dumped a warning for pred yet? */

+            unsigned char predTooLong;     /* MR10 have we dumped warning for pred yet */

+            unsigned char noHoist;         /* MR12 literally "noHoist" */

+            Predicate         *ampersandPred;     /* MR10   (g)? && <<p>>? expr   */

+#ifdef __cplusplus

+            Junction          *guardNodes;        /* MR11 */

+#else

+            struct _junct     *guardNodes;        /* MR11 */

+#endif

+            struct _PredEntry *predEntry;         /* MR11 */

+            int               inverted;           /* MR11 <<!predSymbol>>? */

+#ifdef __cplusplus

+		};

+#else

+		} ActionNode;

+#endif

+

+#ifdef __cplusplus

+class TokNode : public Node {

+public:

+#else

+typedef struct _toknode {

+			NodeType ntype;

+			char *rname;		/* name of rule it's in */

+			int file;			/* index in FileStr (name of file with rule) */

+			int line;			/* line number that token occurs on */

+#endif

+			Node *next;

+			int token;

+			int astnode;		/* leaf/root/excluded (used to build AST's) */

+			unsigned char label;/* token label or expression ? */

+			unsigned char remapped;

+								/* used if token id's are forced to certain positions;

+								 * a function walks the tree reassigning token numbers */

+			int upper_range;    /* MR13 - was char */

+								/* used only if Token is of type T1..T2; in this case,

+								 * use token..upper_range as the range; else

+								 * upper_range must be 0 */

+			unsigned char wild_card;

+								/* indicates that the token is the "." wild-card;

+								 * field token is ignored if wild_card is set

+								 */

+			unsigned int elnum; /* element number within the alternative */

+#ifdef __cplusplus

+			Junction *altstart;	/* pointer to node that starts alt */

+#else

+			struct _junct *altstart;	/* pointer to node that starts alt */

+#endif

+			struct _TCnode *tclass;		/* token class if tokclass ref */

+			set tset;			/* set of tokens represented by meta token */

+			char *el_label;		/* el_label:toknode */

+			unsigned char complement;	/* complement the set? */

+			ExceptionGroup *ex_group;	/* any exception[el_label] attached? */

+            unsigned char use_def_MT_handler;

+            unsigned char label_used_in_semantic_pred;  /* MR10 */

+#ifdef __cplusplus

+		};

+#else

+		} TokNode;

+#endif

+

+#ifdef __cplusplus

+class RuleRefNode : public Node {

+public:

+#else

+typedef struct _rrnode {

+			NodeType ntype;

+			char *rname;		/* name of rule it's in */

+			int file;			/* index in FileStr (name of file with rule)

+								   it's in */

+			int line;			/* line number that rule ref occurs on */

+#endif

+			Node *next;

+			char *text;			/* reference to which rule */

+			char *parms;		/* point to parameters of rule invocation

+								   (if present) */

+			char *assign;		/* point to left-hand-side of assignment

+								   (if any) */

+			int linked;			/* Has a FoLink already been established? */

+			int astnode;		/* excluded? (used to build AST's) */

+			unsigned int elnum; /* element number within the alternative */

+#ifdef __cplusplus

+			Junction *altstart;

+#else

+			struct _junct *altstart;

+#endif

+			char *el_label;		/* el_label:rrnode */

+			ExceptionGroup *ex_group;	/* any exception[el_label] attached? */

+#ifdef __cplusplus

+		};

+#else

+		} RuleRefNode;

+#endif

+

+#ifdef __cplusplus

+class Junction : public Node {

+public:

+#else

+typedef struct _junct {

+			NodeType ntype;

+			char *rname;		/* name of rule junction is in */

+			int file;			/* index in FileStr (name of file with rule)

+								   if blk == RuleBlk */

+			int line;			/* line number that rule occurs on */

+#endif

+            int seq;            /* MR10 sequence number */

+			char ignore;		/* used by FIRST computation to ignore

+								   empty alt added for the (...)+ blks */

+			char visited;		/* used by recursive routines to avoid

+								   infinite recursion */

+			char pvisited;		/* used by print routines to avoid

+								   infinite recursion */

+			char fvisited;		/* used by FoLink() to avoid

+								   infinite recursion */

+			char *lock;			/* used by REACH to track infinite recursion */

+			char *pred_lock;	/* used by find_predicates to track infinite recursion */

+			int altnum;			/* used in subblocks. altnum==0 means not an

+								   alt of subrule */

+			int jtype;			/* annotation for code-gen/FIRST/FOLLOW.

+								   Junction type */

+#ifdef __cplusplus

+			Junction *end;		/* pointer to node with EndBlk in it

+								   if blk == a block type */

+#else

+			struct _junct *end;	/* pointer to node with EndBlk in it

+								   if blk == a block type */

+#endif

+			Node *p1, *p2;

+			char  halt;			/* never move past a junction with halt==TRUE */ /* MR10 was int */

+			char *pdecl;		/* point to declaration of parameters on rule

+								   (if present) */

+			char *parm;			/* point to parameter of block invocation

+								   (if present) */

+			char predparm;		/* indicates that the 'parm' is a predicate

+								 * to be used in the while loop generated

+								 * for blocks */ /* MR10 was int */

+			char *ret;			/* point to return type of rule (if present) */

+			char *erraction;	/* point to error action (if present) */

+			int blockid;		/* this is a unique ID */

+			char *exception_label;	/* goto label for this alt */

+			set *fset;			/* used for code generation */

+			Tree *ftree;		/* used for code generation */

+			Predicate *predicate;/* predicate that can be used to disambiguate */

+			char guess;			/* true if (...)? block */

+            char alpha_beta_guess_end;      /* MR14 1 => end block of guess sub block  */

+            Node *guess_analysis_point;     /* MR14 */

+			char approx;		/* limit block to use linear approx lookahead? */

+			set tokrefs;		/* if ith element of alt is tokref then i is member */

+			set rulerefs;		/* if ith element of alt is rule ref then i is member */

+			struct _ListNode *exceptions; /* list of exceptions groups for rule */

+			struct _ListNode *el_labels;  /* list of element labels for rule */

+            ExceptionGroup   *outerEG;                               /* MR7 */

+            int              curAltNum;                              /* MR7 */

+            char* pFirstSetSymbol;   /* #pragma FirstSetSymbol(Foo)     MR21 */

+#ifdef __cplusplus

+            Junction         *pendingLink;                           /* MR7 */

+#else

+            struct _junct    *pendingLink;                           /* MR7 */

+#endif

+            char             overlap_warning;                        /* MR10 */

+#ifdef __cplusplus

+		};

+#else

+		} Junction;

+#endif

+

+typedef struct { Node *left, *right;} Graph;

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/antlr/tokens.h b/edk2/Tools/Source/TianoTools/Pccts/antlr/tokens.h
new file mode 100644
index 0000000..91a53a8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/antlr/tokens.h
@@ -0,0 +1,246 @@
+#ifndef tokens_h

+#define tokens_h

+/* tokens.h -- List of labelled tokens and stuff

+ *

+ * Generated from: antlr.g

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * ANTLR Version 1.33MR33

+ */

+#define zzEOF_TOKEN 1

+#define Eof 1

+#define QuotedTerm 2

+#define Action 34

+#define Pred 35

+#define PassAction 36

+#define WildCard 87

+#define LABEL 89

+#define Pragma 92

+#define FirstSetSymbol 93

+#define NonTerminal 100

+#define TokenTerm 101

+#define ID 148

+#define INT 150

+

+#ifdef __USE_PROTOS

+void grammar(void);

+#else

+extern void grammar();

+#endif

+

+#ifdef __USE_PROTOS

+void class_def(void);

+#else

+extern void class_def();

+#endif

+

+#ifdef __USE_PROTOS

+void rule(void);

+#else

+extern void rule();

+#endif

+

+#ifdef __USE_PROTOS

+void laction(void);

+#else

+extern void laction();

+#endif

+

+#ifdef __USE_PROTOS

+void lmember(void);

+#else

+extern void lmember();

+#endif

+

+#ifdef __USE_PROTOS

+void lprefix(void);

+#else

+extern void lprefix();

+#endif

+

+#ifdef __USE_PROTOS

+void aPred(void);

+#else

+extern void aPred();

+#endif

+

+#ifdef __USE_PROTOS

+extern Predicate * predOrExpr(void);

+#else

+extern Predicate * predOrExpr();

+#endif

+

+#ifdef __USE_PROTOS

+extern Predicate * predAndExpr(void);

+#else

+extern Predicate * predAndExpr();

+#endif

+

+#ifdef __USE_PROTOS

+extern Predicate * predPrimary(void);

+#else

+extern Predicate * predPrimary();

+#endif

+

+#ifdef __USE_PROTOS

+void aLexclass(void);

+#else

+extern void aLexclass();

+#endif

+

+#ifdef __USE_PROTOS

+void error(void);

+#else

+extern void error();

+#endif

+

+#ifdef __USE_PROTOS

+void tclass(void);

+#else

+extern void tclass();

+#endif

+

+#ifdef __USE_PROTOS

+void token(void);

+#else

+extern void token();

+#endif

+

+#ifdef __USE_PROTOS

+void block(set * toksrefd,set * rulesrefd);

+#else

+extern void block();

+#endif

+

+#ifdef __USE_PROTOS

+void alt(set * toksrefd,set * rulesrefd);

+#else

+extern void alt();

+#endif

+

+#ifdef __USE_PROTOS

+extern LabelEntry * element_label(void);

+#else

+extern LabelEntry * element_label();

+#endif

+

+#ifdef __USE_PROTOS

+extern Node * element(int old_not,int first_on_line,int use_def_MT_handler);

+#else

+extern Node * element();

+#endif

+

+#ifdef __USE_PROTOS

+void default_exception_handler(void);

+#else

+extern void default_exception_handler();

+#endif

+

+#ifdef __USE_PROTOS

+extern ExceptionGroup * exception_group(void);

+#else

+extern ExceptionGroup * exception_group();

+#endif

+

+#ifdef __USE_PROTOS

+extern ExceptionHandler * exception_handler(void);

+#else

+extern ExceptionHandler * exception_handler();

+#endif

+

+#ifdef __USE_PROTOS

+void enum_file(char * fname);

+#else

+extern void enum_file();

+#endif

+

+#ifdef __USE_PROTOS

+void defines(char * fname);

+#else

+extern void defines();

+#endif

+

+#ifdef __USE_PROTOS

+void enum_def(char * fname);

+#else

+extern void enum_def();

+#endif

+

+#endif

+extern SetWordType zzerr1[];

+extern SetWordType zzerr2[];

+extern SetWordType zzerr3[];

+extern SetWordType zzerr4[];

+extern SetWordType setwd1[];

+extern SetWordType zzerr5[];

+extern SetWordType zzerr6[];

+extern SetWordType zzerr7[];

+extern SetWordType zzerr8[];

+extern SetWordType zzerr9[];

+extern SetWordType setwd2[];

+extern SetWordType zzerr10[];

+extern SetWordType zzerr11[];

+extern SetWordType zzerr12[];

+extern SetWordType zzerr13[];

+extern SetWordType setwd3[];

+extern SetWordType zzerr14[];

+extern SetWordType zzerr15[];

+extern SetWordType zzerr16[];

+extern SetWordType zzerr17[];

+extern SetWordType zzerr18[];

+extern SetWordType zzerr19[];

+extern SetWordType zzerr20[];

+extern SetWordType zzerr21[];

+extern SetWordType setwd4[];

+extern SetWordType zzerr22[];

+extern SetWordType zzerr23[];

+extern SetWordType zzerr24[];

+extern SetWordType zzerr25[];

+extern SetWordType zzerr26[];

+extern SetWordType setwd5[];

+extern SetWordType zzerr27[];

+extern SetWordType zzerr28[];

+extern SetWordType zzerr29[];

+extern SetWordType zzerr30[];

+extern SetWordType zzerr31[];

+extern SetWordType zzerr32[];

+extern SetWordType zzerr33[];

+extern SetWordType setwd6[];

+extern SetWordType zzerr34[];

+extern SetWordType zzerr35[];

+extern SetWordType zzerr36[];

+extern SetWordType zzerr37[];

+extern SetWordType zzerr38[];

+extern SetWordType zzerr39[];

+extern SetWordType zzerr40[];

+extern SetWordType zzerr41[];

+extern SetWordType zzerr42[];

+extern SetWordType setwd7[];

+extern SetWordType zzerr43[];

+extern SetWordType zzerr44[];

+extern SetWordType zzerr45[];

+extern SetWordType zzerr46[];

+extern SetWordType zzerr47[];

+extern SetWordType zzerr48[];

+extern SetWordType zzerr49[];

+extern SetWordType zzerr50[];

+extern SetWordType zzerr51[];

+extern SetWordType zzerr52[];

+extern SetWordType zzerr53[];

+extern SetWordType setwd8[];

+extern SetWordType zzerr54[];

+extern SetWordType zzerr55[];

+extern SetWordType zzerr56[];

+extern SetWordType zzerr57[];

+extern SetWordType setwd9[];

+extern SetWordType zzerr58[];

+extern SetWordType zzerr59[];

+extern SetWordType zzerr60[];

+extern SetWordType zzerr61[];

+extern SetWordType zzerr62[];

+extern SetWordType zzerr63[];

+extern SetWordType zzerr64[];

+extern SetWordType zzerr65[];

+extern SetWordType setwd10[];

+extern SetWordType setwd11[];

diff --git a/edk2/Tools/Source/TianoTools/Pccts/build.xml b/edk2/Tools/Source/TianoTools/Pccts/build.xml
new file mode 100644
index 0000000..12a3afa
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/build.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK Pccts Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="Pccts"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="GenTool" depends="init">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+    <ant dir="${PACKAGE_DIR}/Pccts/antlr" inheritAll="true"/>

+    <ant dir="${PACKAGE_DIR}/Pccts/dlg" inheritAll="true"/>

+  </target>

+

+  <target name="clean" depends="init">

+    <ant dir="${PACKAGE_DIR}/Pccts/antlr" target="clean" inheritAll="true"/>

+    <ant dir="${PACKAGE_DIR}/Pccts/dlg" target="clean" inheritAll="true"/>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <ant dir="${PACKAGE_DIR}/Pccts/antlr" target="cleanall" inheritAll="true"/>

+    <ant dir="${PACKAGE_DIR}/Pccts/dlg" target="cleanall" inheritAll="true"/>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/DlgMS.mak b/edk2/Tools/Source/TianoTools/Pccts/dlg/DlgMS.mak
new file mode 100644
index 0000000..4a9019b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/DlgMS.mak
@@ -0,0 +1,121 @@
+# PCCTS directory

+

+# You will need to set the LIB variable similar to this.

+# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib"

+

+# PCCTS_HOME=<your PCCTS_HOME>

+PCCTS_HOME=$(WORKSPACE)\Tools\Source\TianoTools\Pccts

+DLG_SRC=$(PCCTS_HOME)\dlg

+PCCTS_H=$(PCCTS_HOME)\h

+

+

+# Support directories

+SET=$(PCCTS_HOME)\support\set

+

+

+# Compiler stuff

+CC = cl

+CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \

+        -D "ZZLEXBUFSIZE=65536"  /D "LONGFILENAMES" /W3 /Zi

+

+DLG_OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \

+           output.obj relabel.obj automata.obj

+

+SUPPORT_OBJS = set.obj

+

+# Dependencies

+

+dlg.exe: $(DLG_OBJS) $(SUPPORT_OBJS)

+    $(CC) $(CFLAGS) -o dlg.exe $(DLG_OBJS) $(SUPPORT_OBJS)

+    del *.obj

+    del *.ilk

+    del *.pdb

+		move dlg.exe $(WORKSPACE)\Tools\bin\.

+

+dlg_p.obj: $(DLG_SRC)\dlg_p.c \

+					$(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+                	$(DLG_SRC)\mode.h \

+                	$(DLG_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_p.c

+

+dlg_a.obj: $(DLG_SRC)\dlg_a.c \

+					$(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgauto.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+                	$(DLG_SRC)\mode.h \

+                	$(DLG_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_a.c

+

+main.obj: $(DLG_SRC)\main.c \

+					$(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+                	$(DLG_SRC)\mode.h \

+                	$(DLG_SRC)\stdpccts.h \

+                	$(DLG_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\main.c

+

+err.obj: $(DLG_SRC)\err.c \

+					$(PCCTS_H)\antlr.h \

+					$(PCCTS_H)\config.h \

+					$(PCCTS_H)\dlgdef.h \

+					$(PCCTS_H)\err.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+                	$(DLG_SRC)\tokens.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\err.c

+

+support.obj: $(DLG_SRC)\support.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\support.c

+

+output.obj: $(DLG_SRC)\output.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\output.c

+

+relabel.obj: $(DLG_SRC)\relabel.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\relabel.c

+

+automata.obj: $(DLG_SRC)\automata.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+                	$(DLG_SRC)\dlg.h \

+

+    $(CC) -c $(CFLAGS) $(DLG_SRC)\automata.c

+

+

+set.obj: $(SET)\set.c \

+					$(PCCTS_H)\config.h \

+					$(SET)\set.h \

+

+    $(CC) -c $(CFLAGS) $(SET)\set.c

+

+clean:	

+    del *.obj

+

+distclean:

+    del *.obj

+    del $(WORKSPACE)\Tools\bin\dlg.exe

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/DlgPPC.mak b/edk2/Tools/Source/TianoTools/Pccts/dlg/DlgPPC.mak
new file mode 100644
index 0000000..55b643a
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/DlgPPC.mak
@@ -0,0 +1,84 @@
+#   File:       dlgPPC.make

+#   Target:     dlgPPC

+#   Sources:    automata.c

+#               dlg_a.c

+#               dlg_p.c

+#               err.c

+#               main.c

+#               output.c

+#               relabel.c

+#               support.c

+#               ::support:set:set.c

+#   Created:    Sunday, May 17, 1998 11:34:20 PM

+#	Author:		Kenji Tanaka

+

+

+MAKEFILE     = dlgPPC.make

+¥MondoBuild¥ = {MAKEFILE}  # Make blank to avoid rebuilds when makefile is modified

+Includes     = ¶

+		-i "::h:" ¶

+		-i "::support:set:"

+Sym¥PPC      = 

+ObjDir¥PPC   = ":Obj:"

+

+PPCCOptions  = {Includes} {Sym¥PPC}  -w off -d MPW -d __STDC__=1 -d USER_ZZSYN

+

+Objects¥PPC  = ¶

+		"{ObjDir¥PPC}automata.c.x" ¶

+		"{ObjDir¥PPC}dlg_a.c.x" ¶

+		"{ObjDir¥PPC}dlg_p.c.x" ¶

+		"{ObjDir¥PPC}err.c.x" ¶

+		"{ObjDir¥PPC}main.c.x" ¶

+		"{ObjDir¥PPC}output.c.x" ¶

+		"{ObjDir¥PPC}relabel.c.x" ¶

+		"{ObjDir¥PPC}support.c.x" ¶

+		"{ObjDir¥PPC}set.c.x"

+

+

+dlgPPC ÄÄ {¥MondoBuild¥} {Objects¥PPC}

+	PPCLink ¶

+		-o {Targ} {Sym¥PPC} ¶

+		{Objects¥PPC} ¶

+		-t 'MPST' ¶

+		-c 'MPS ' ¶

+		"{SharedLibraries}InterfaceLib" ¶

+		"{SharedLibraries}StdCLib" ¶

+		"{SharedLibraries}MathLib" ¶

+		"{PPCLibraries}StdCRuntime.o" ¶

+		"{PPCLibraries}PPCCRuntime.o" ¶

+		"{PPCLibraries}PPCToolLibs.o"

+

+

+"{ObjDir¥PPC}automata.c.x" Ä {¥MondoBuild¥} automata.c

+	{PPCC} automata.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}dlg_a.c.x" Ä {¥MondoBuild¥} dlg_a.c

+	{PPCC} dlg_a.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}dlg_p.c.x" Ä {¥MondoBuild¥} dlg_p.c

+	{PPCC} dlg_p.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}err.c.x" Ä {¥MondoBuild¥} err.c

+	{PPCC} err.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}main.c.x" Ä {¥MondoBuild¥} main.c

+	{PPCC} main.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}output.c.x" Ä {¥MondoBuild¥} output.c

+	{PPCC} output.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}relabel.c.x" Ä {¥MondoBuild¥} relabel.c

+	{PPCC} relabel.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}support.c.x" Ä {¥MondoBuild¥} support.c

+	{PPCC} support.c -o {Targ} {PPCCOptions}

+

+"{ObjDir¥PPC}set.c.x" Ä {¥MondoBuild¥} "::support:set:set.c"

+	{PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions}

+

+

+dlgPPC ÄÄ dlg.r

+	Rez dlg.r -o dlgPPC -a

+

+Install  Ä dlgPPC

+	Duplicate -y dlgPPC "{MPW}"Tools:dlg

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/automata.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/automata.c
new file mode 100644
index 0000000..d6d5d78
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/automata.c
@@ -0,0 +1,353 @@
+/* Automata conversion functions for DLG

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "pcctscfg.h"

+#include "dlg.h"

+#ifdef MEMCHK

+#include "trax.h"

+#else

+#ifdef __STDC__

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif /* __STDC__ */

+#endif

+

+#define hash_list struct _hash_list_

+hash_list{

+	hash_list *next;	/* next thing in list */

+	dfa_node *node;

+ };

+

+int	dfa_allocated = 0;	/* keeps track of number of dfa nodes */

+dfa_node	**dfa_array;	/* root of binary tree that stores dfa array */

+dfa_node	*dfa_model_node;

+hash_list 	*dfa_hash[HASH_SIZE];	/* used to quickly find */

+					/* desired dfa node */

+

+void 

+#ifdef __USE_PROTOS

+make_dfa_model_node(int width)

+#else

+make_dfa_model_node(width)

+int width;

+#endif

+{

+	register int i;

+	dfa_model_node = (dfa_node*) malloc(sizeof(dfa_node)

+			 + sizeof(int)*width);

+	dfa_model_node->node_no = -1; /* impossible value for real dfa node */

+	dfa_model_node->dfa_set = 0;

+	dfa_model_node->alternatives = FALSE;

+	dfa_model_node->done = FALSE;

+	dfa_model_node->nfa_states = empty;

+	for(i = 0; i<width; i++){

+		dfa_model_node->trans[i] = NIL_INDEX;

+	}

+}

+

+

+/* adds a new nfa to the binary tree and returns a pointer to it */

+dfa_node *

+#ifdef __USE_PROTOS

+new_dfa_node(set nfa_states)

+#else

+new_dfa_node(nfa_states)

+set nfa_states;

+#endif

+{

+	register int j;

+	register dfa_node *t;

+	static int dfa_size=0;	/* elements dfa_array[] can hold */

+

+	++dfa_allocated;

+	if (dfa_size<=dfa_allocated){

+		/* need to redo array */

+		if (!dfa_array){

+			/* need some to do inital allocation */

+			dfa_size=dfa_allocated+DFA_MIN;

+			dfa_array=(dfa_node **) malloc(sizeof(dfa_node*)*

+				dfa_size);

+		}else{

+			/* need more space */

+			dfa_size=2*(dfa_allocated+1);

+			dfa_array=(dfa_node **) realloc(dfa_array,

+				sizeof(dfa_node*)*dfa_size);

+		}

+	}

+	/* fill out entry in array */

+	t = (dfa_node*) malloc(sizeof(nfa_node)+sizeof(int)*class_no);

+	*t = *dfa_model_node;

+	for (j=0; j<class_no; ++j)

+		t->trans[j] = NIL_INDEX;

+	t->node_no = dfa_allocated;

+	t->nfa_states = set_dup(nfa_states);

+	dfa_array[dfa_allocated] = t;

+	return t;

+}

+

+

+/* past a pointer to the start start of the nfa graph

+ * nfa_to_dfa convers this graph to dfa.  The function returns

+ * a pointer to the first dfa state.

+ * NOTE:  The function that prints out the table will have to figure out how

+ * to find the other dfa states given the first dfa_state and the number of dfa

+ * nodes allocated

+ */

+dfa_node **

+#ifdef __USE_PROTOS

+nfa_to_dfa(nfa_node *start)

+#else

+nfa_to_dfa(start)

+nfa_node *start;

+#endif

+{

+	register dfa_node *d_state, *trans_d_state;

+	register int a;

+	set t;

+	int last_done;

+	unsigned *nfa_list;

+	unsigned *reach_list;

+

+	reach_list = (unsigned *) malloc((2+nfa_allocated)*sizeof(unsigned));

+	if (!start) return NULL;

+	t = set_of(NFA_NO(start));

+	_set_pdq(t,reach_list);

+	closure(&t,reach_list);

+	/* Make t a dfa state */

+	d_state = dfastate(t);

+	last_done = DFA_NO(d_state);

+	

+	do {

+		/* Mark dfa state x as "done" */

+		d_state->done = TRUE;

+		nfa_list = set_pdq(d_state->nfa_states);

+		for (a = 0; a<class_no; ++a) {

+			/* Add NFA states reached by a from d_state */

+			reach(nfa_list,a,reach_list);

+			/* Were any states found? */

+			if ((*reach_list)!=nil) {

+				/* was t=empty; */

+				set_free(t);

+				/* yes, compute closure */

+				closure(&t,reach_list);

+				/* Make DFA state of it ... */

+				trans_d_state = dfastate(t);

+				/* And make transition x->t, labeled with a */

+				d_state->trans[a] = DFA_NO(trans_d_state);

+				d_state->alternatives = TRUE;

+			}

+		}

+		free(nfa_list);

+		++last_done; /* move forward in queue */

+		/* And so forth until nothing isn't done */

+		d_state = DFA(last_done);

+	} while (last_done<=dfa_allocated);

+

+	free(reach_list);

+	set_free(t);

+

+	/* returns pointer to the array that holds the automaton */

+	return dfa_array;

+}

+

+void 

+#ifdef __USE_PROTOS

+clear_hash(void)

+#else

+clear_hash()

+#endif

+{

+	register int i;

+

+	for(i=0; i<HASH_SIZE; ++i)

+		dfa_hash[i] = 0;

+}

+

+#if HASH_STAT

+void

+#ifdef __USE_PROTOS

+fprint_hash_stats(FILE *f)

+#else

+fprint_hash_stats(f)

+FILE *f;

+#endif

+{

+	register hash_list *p;

+	register int i,j;

+	register total;

+

+	total=0;

+	for(i=0; i<HASH_SIZE; ++i){

+		j=0;

+		p = dfa_hash[i];

+		while(p){

+			++j;

+			p = p->next;

+		}

+		total+=j;

+		fprintf(f,"bin[%d] has %d\n",i,j);

+	}

+	fprintf(f,"total = %d\n",total);

+}

+#endif

+

+/* Returns a pointer to a dfa node that has the same nfa nodes in it.

+ * This may or maynot be a newly created node.

+ */

+dfa_node *

+#ifdef __USE_PROTOS

+dfastate(set nfa_states)

+#else

+dfastate(nfa_states)

+set nfa_states;

+#endif

+{

+	register hash_list *p;

+	int bin;

+

+	/* hash using set and see if it exists */

+	bin = set_hash(nfa_states,HASH_SIZE);

+	p = dfa_hash[bin];

+	while(p && !set_equ(nfa_states,(p->node)->nfa_states)){

+		p = p->next;

+	}

+	if(!p){

+		/* next state to add to hash table */

+		p = (hash_list*)malloc(sizeof(hash_list));

+		p->node = new_dfa_node(nfa_states);

+		p->next = dfa_hash[bin];

+		dfa_hash[bin] = p;

+	}

+	return (p->node);

+}

+

+

+/* this reach assumes the closure has been done already on set */

+int 

+#ifdef __USE_PROTOS

+reach(unsigned *nfa_list, register int a, unsigned *reach_list)

+#else

+reach(nfa_list, a, reach_list)

+unsigned *nfa_list;

+register int a;

+unsigned *reach_list;

+#endif

+{

+	register unsigned *e;

+	register nfa_node *node;

+	int t=0;

+

+	e = nfa_list;

+	if (e){

+		while (*e != nil){

+			node = NFA(*e);

+			if (set_el(a,node->label)){

+				t=1;

+				*reach_list=NFA_NO(node->trans[0]);

+				++reach_list;

+			}

+			++e;

+		}

+	}

+	*reach_list=nil;

+	return t;

+}

+

+/* finds all the nodes that can be reached by epsilon transitions

+   from the set of a nodes and returns puts them back in set b */

+set 

+#ifdef __USE_PROTOS

+closure(set *b, unsigned *reach_list)

+#else

+closure(b, reach_list)

+set *b;

+unsigned *reach_list;

+#endif

+{

+	register nfa_node *node,*n;	/* current node being examined */

+	register unsigned *e;

+

+	++operation_no;

+#if 0

+	t = e = set_pdq(*b);

+#else

+	e=reach_list;

+#endif

+	while (*e != nil){

+		node = NFA(*e);

+		set_orel(NFA_NO(node),b);

+		/* mark it done */

+		node->nfa_set = operation_no;

+		if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) &&

+		  (n->nfa_set != operation_no)){

+			/* put in b */

+			set_orel(NFA_NO(n),b);

+			close1(n,operation_no,b);

+		}

+		if ((n=node->trans[1]) != NIL_INDEX &&

+		  (n->nfa_set != operation_no)){

+			/* put in b */

+			set_orel(NFA_NO(node->trans[1]),b);

+			close1(n,operation_no,b);

+		}

+		++e;

+	}

+#if 0

+	free(t);

+#endif

+	return *b;

+}

+

+#ifdef __USE_PROTOS

+void close1(nfa_node *node, int o, set *b)

+#else

+void close1(node,o,b)

+nfa_node *node;

+int o;	/* marker to avoid cycles */

+set *b;

+#endif

+{

+	register nfa_node *n;	/* current node being examined */

+

+	/* mark it done */

+	node->nfa_set = o;

+	if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) &&

+	  (n->nfa_set != o)){

+		/* put in b */

+		set_orel(NFA_NO(n),b);

+		close1(n,o,b);

+	}

+	if ((n=node->trans[1]) != NIL_INDEX &&

+	  (n->nfa_set != o)){

+		/* put in b */

+		set_orel(NFA_NO(node->trans[1]),b);

+		close1(n,o,b);

+	}

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/build.xml b/edk2/Tools/Source/TianoTools/Pccts/dlg/build.xml
new file mode 100644
index 0000000..d926f25
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/build.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK dlg Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="dlg"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+  <property name="PACKAGE_DIR" value="${WORKSPACE}/Tools"/>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+		<condition property="CheckDepends">

+		  <uptodate targetfile="${WORKSPACE}/Tools/bin/dlg.exe">

+			  <srcfiles dir="." includes="*.c *.h *.g"/>

+			</uptodate>

+		</condition>

+		<if>

+		  <equals arg1="${CheckDepends}" arg2="true"/>

+			<then>

+				<echo message="Executable, dlg.exe, is up to date."/>

+			</then>

+		</if>

+  </target>

+

+  <target name="GenTool" depends="init" unless="CheckDepends">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="nmake" failonerror="TRUE">

+	    	  <arg line="-f DlgMS.mak"/>

+    		</exec>

+		  </then>

+		<elseif>

+      <equals arg1="${ToolChain}" arg2="gcc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="make" failonerror="TRUE">

+	    	  <arg line="-f makefile"/>

+    		</exec>

+		  </then>

+		</elseif>

+		</if>

+	</target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="nmake" failonerror="TRUE">

+	    	  <arg line="-f DlgMS.mak clean"/>

+    		</exec>

+		  </then>

+		<elseif>

+      <equals arg1="${ToolChain}" arg2="gcc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="make" failonerror="TRUE">

+	    	  <arg line="-f makefile clean"/>

+    		</exec>

+		  </then>

+		</elseif>

+		</if>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="nmake" failonerror="FALSE">

+	    	  <arg line="-f DlgMS.mak clean"/>

+    		</exec>

+		  </then>

+		<elseif>

+      <equals arg1="${ToolChain}" arg2="gcc"/>

+			<then>

+    	  <exec dir="${basedir}" executable="make" failonerror="FALSE">

+	    	  <arg line="-f makefile clean"/>

+    		</exec>

+		  </then>

+		</elseif>

+		</if>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.1 b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.1
new file mode 100644
index 0000000..f68e3ae
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.1
@@ -0,0 +1,79 @@
+.TH dlg 1 "April 1994" "DLG" "PCCTS Manual Pages"

+.SH NAME

+dlg \- DFA Lexical Analyzer Generator

+.SH SYNTAX

+.LP

+\fBdlg\fR [\fIoptions\fR] \fIlexical_spec\fR [\fIoutput_file\fR]

+.SH DESCRIPTION

+.B dlg

+is a tool that produces fast deterministic finite automata for recognizing

+regular expressions in input.

+.SH OPTIONS

+.IP "\fB-CC\fR"

+Generate C++ output.  The \fIoutput_file\fP is not specified in this

+case.

+.IP "\fB-C\fR[\fP level\fR]

+Where \fPlevel\fR is the compression level used.  0 indications no

+compression, 1 removes all unused characters from the transition from table,

+and 2 maps equivalent characters into the same character classes.  It is

+suggested that level -C2 is used, since it will significantly reduce the size

+of the dfa produced for lexical analyzer.

+.IP "\fB-m\fP

+Produces the header file for the lexical mode with a name other than

+the default name of "mode.h".

+.IP \fB-i\fP

+An interactive, or as interactive as possible, parser is produced.  A character

+is only obtained when required to decide which state to go to.  Some care

+must be taken to obtain accept states that do not require look ahead at the

+next character to determine if that is the stop state.  Any regular expression

+with a Kleene closure at the end is guaranteed to require another character

+of look ahead.

+.IP "\fB-cl\fP class

+Specify a class name for DLG to generate.  The default is DLGLexer.

+'class' will be a subclass of DLGLexerBase; only used for -CC.

+.IP \fB-ci\fP

+The automaton will treat upper and lower case characters identically.

+This is accomplished in the automaton; the characters in the lexical

+buffer are unmodified.

+.IP \fB-cs\fP

+Upper and lower case characters are treated as distinct.  This is the

+default.

+.IP "\fB-o\fP dir

+Directory where output files should go (default=".").  This is very

+nice for keeping the source directory clear of ANTLR and DLG spawn.

+.IP \fB-Wambiguity\fP

+Warns if more than one regular expression could match the same character

+sequence.  The warnings give the numbers of the expressions in the dlg

+lexical specification file.  The numbering of the expressions starts at one.

+Multiple warnings may be print for the same expressions.

+.IP \-

+Used in place of file names to get input from standard in or send output

+to standard out.

+.SH "SPECIAL CONSIDERATIONS"

+.PP

+\fIDlg\fP works...  we think.  There is no implicit guarantee of

+anything.  We reserve no \fBlegal\fP rights to the software known as

+the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the

+public domain.  An individual or company may do whatever they wish

+with source code distributed with PCCTS or the code generated by

+PCCTS, including the incorporation of PCCTS, or its output, into

+commercial software.  We encourage users to develop software with

+PCCTS.  However, we do ask that credit is given to us for developing

+PCCTS.  By "credit", we mean that if you incorporate our source code

+into one of your programs (commercial product, research project, or

+otherwise) that you acknowledge this fact somewhere in the

+documentation, research report, etc...  If you like PCCTS and have

+developed a nice tool with the output, please mention that you

+developed it using PCCTS.  As long as these guidelines are followed, we

+expect to continue enhancing this system and expect to make other

+tools available as they are completed.

+.SH FILES

+.B mode.h

+,

+.B dlgauto.h

+,

+.B dlgdef.h

+.SH SEE ALSO

+.BR antlr (1),

+.BR pccts (1)

+.SH BUGS

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.h b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.h
new file mode 100644
index 0000000..9f387c0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.h
@@ -0,0 +1,250 @@
+/* dlg header file

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+/* MR1 Move pcctscfg.h to top of file 					*/

+

+#include "pcctscfg.h"						

+

+/* turn off warnings for unreferenced labels */

+

+#ifdef _MSC_VER

+#pragma warning(disable:4102)

+#endif

+

+#include "set.h"

+

+#define TRUE	1

+#define FALSE	0

+

+/***** output related stuff *******************/

+#define IN	input_stream

+#define OUT	output_stream

+

+#define MAX_MODES	50	/* number of %%names allowed */

+#define MAX_ON_LINE	10

+

+#define NFA_MIN		64	/* minimum nfa_array size */

+#define DFA_MIN		64	/* minimum dfa_array size */

+

+#define DEFAULT_CLASSNAME "DLGLexer"

+

+/* these macros allow the size of the character set to be easily changed */

+/* NOTE: do NOT change MIN_CHAR since EOF is the lowest char, -1 */

+#define MIN_CHAR (-1)	/* lowest possible character possible on input */

+#define MAX_CHAR 255	/* highest possible character possible on input */

+#define CHAR_RANGE (1+(MAX_CHAR) - (MIN_CHAR))

+

+/* indicates that the not an "array" reference */

+#define NIL_INDEX 0

+

+/* size of hash table used to find dfa_states quickly */

+#define HASH_SIZE 211

+

+#define nfa_node struct _nfa_node

+nfa_node {

+	int		node_no;

+	int		nfa_set;

+	int		accept;	/* what case to use */

+	nfa_node	*trans[2];

+	set		label;	/* one arc always labelled with epsilon */

+};

+

+#define dfa_node struct _dfa_node

+dfa_node {

+	int		node_no;

+	int		dfa_set;

+	int		alternatives;	/* used for interactive mode */

+					/* are more characters needed */

+	int		done;

+	set		nfa_states;

+	int		trans[1];/* size of transition table depends on

+				  * number of classes required for automata.

+				  */

+

+

+};

+

+/******** macros for accessing the NFA and DFA nodes ****/

+#define NFA(x)	(nfa_array[x])

+#define DFA(x)	(dfa_array[x])

+#define DFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX)

+#define NFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX)

+

+/******** wrapper for memory checking ***/

+/*#define malloc(x)	dlg_malloc((x),__FILE__,__LINE__)*/

+

+/*#define calloc(x,y)	dlg_calloc((x),(y),__FILE__,__LINE__)*/

+

+/******** antlr attributes *************/

+typedef struct {

+	unsigned char letter;

+	nfa_node *l,*r;

+	set label;

+	} Attrib;

+

+#define zzcr_attr(attr, token, text) {					\

+	(attr)->letter = text[0]; (attr)->l = NULL;			\

+	(attr)->r = NULL; (attr)->label = empty;			\

+}

+#define zzd_attr(a)	set_free((a)->label);

+

+/******************** Variable ******************************/

+extern char	program[];	/* tells what program this is */

+extern char	version[];	/* tells what version this is */

+extern char	*file_str[];	/* file names being used */

+extern int	err_found;	/* flag to indicate error occured */

+extern int	action_no;	/* last action function printed */

+extern int	func_action;	/* should actions be turned into functions?*/

+extern set	used_chars;	/* used to label trans. arcs */

+extern set	used_classes;	/* classes or chars used to label trans. arcs */

+extern int	class_no;	/* number of classes used */

+extern set	class_sets[];	/* shows char. in each class */

+extern set	normal_chars;	/* mask off unused portion of set */

+extern int	comp_level;	/* what compression level to use */

+extern int	interactive;	/* interactive scanner (avoid lookahead)*/

+extern int	mode_counter;	/* keeps track of the number of %%name */

+extern int	dfa_basep[];	/* start of each group of dfa */

+extern int	dfa_class_nop[];/* number of transistion arcs in */

+				/* each dfa in each mode */

+extern int	nfa_allocated;

+extern int	dfa_allocated;

+extern nfa_node	**nfa_array;	/* start of nfa "array" */

+extern dfa_node	**dfa_array;	/* start of dfa "array" */

+extern int	operation_no;	/* unique number for each operation */

+extern FILE	*input_stream;	/* where description read from */

+extern FILE	*output_stream; /* where to put the output */

+extern FILE	*mode_stream;	/* where to put the mode output */

+extern FILE	*class_stream;

+extern char	*mode_file;	/* name of file for mode output */

+extern int	gen_ansi;	/* produce ansi compatible code */

+extern int	case_insensitive;/* ignore case of input spec. */

+extern int	warn_ambig;	/* show if regular expressions ambiguous */

+extern int	gen_cpp;

+extern char *cl_file_str;

+extern int	firstLexMember;	/* MR1 */

+extern char *OutputDirectory;

+extern char	*class_name;

+

+/******************** Functions ******************************/

+#ifdef __USE_PROTOS

+extern char 	*dlg_malloc(int, char *, int); /* wrapper malloc */

+extern char 	*dlg_calloc(int, int, char *, int); /* wrapper calloc */

+extern int	reach(unsigned *, register int, unsigned *);

+extern set	closure(set *, unsigned *);

+extern dfa_node *new_dfa_node(set);

+extern nfa_node *new_nfa_node(void);

+extern dfa_node *dfastate(set);

+extern dfa_node **nfa_to_dfa(nfa_node *);

+extern void	internal_error(char *, char *, int);    /* MR9 23-Sep-97 */

+extern FILE	*read_stream(char *);	/* opens file for reading */

+extern FILE	*write_stream(char *);	/* opens file for writing */

+extern void	make_nfa_model_node(void);

+extern void	make_dfa_model_node(int);

+extern char *ClassName(char *);

+extern char *OutMetaName(char *);

+extern void error(char*, int);

+extern void warning(char*, int);

+extern void p_head(void);

+extern void p_class_hdr(void);

+extern void p_includes(void);

+extern void p_tables(void);

+extern void p_tail(void);					/* MR1 */

+extern void p_class_def1(void);				/* MR1 */

+extern void new_automaton_mode(void);			/* MR1 */

+extern int  relabel(nfa_node *,int);			/* MR1 */

+extern void p_shift_table(int);				/* MR1 */

+extern void p_bshift_table(void);				/* MR1 */

+extern void p_class_table(void);				/* MR1 */

+extern void p_mode_def(char *,int);			/* MR1 */

+extern void init(void);					/* MR1 */

+extern void p_class_def2(void);				/* MR1 */

+extern void clear_hash(void);				/* MR1 */

+extern void p_alternative_table(void);			/* MR1 */

+extern void p_node_table(void);				/* MR1 */

+extern void p_dfa_table(void);				/* MR1 */

+extern void p_accept_table(void);				/* MR1 */

+extern void p_action_table(void);				/* MR1 */

+extern void p_base_table(void);				/* MR1 */

+extern void p_single_node(int,int);			/* MR1 */

+extern char * minsize(int);				/* MR1 */

+extern void close1(nfa_node *,int,set *);		/* MR1 */

+extern void partition(nfa_node *,int);			/* MR1 */

+extern void intersect_nfa_labels(nfa_node *,set *);	/* MR1 */

+extern void r_intersect(nfa_node *,set *);		/* MR1 */

+extern void label_node(nfa_node *);			/* MR1 */

+extern void label_with_classes(nfa_node *);		/* MR1 */

+

+#else

+extern char *dlg_malloc();	/* wrapper malloc */

+extern char *dlg_calloc();	/* wrapper calloc */

+extern int	reach();

+extern set	closure();

+extern dfa_node *new_dfa_node();

+extern nfa_node *new_nfa_node();

+extern dfa_node *dfastate();

+extern dfa_node **nfa_to_dfa();

+extern void	internal_error();   /* MR9 23-Sep-97 */

+extern FILE	*read_stream();		/* opens file for reading */

+extern FILE	*write_stream();	/* opens file for writing */

+extern void	make_nfa_model_node();

+extern void	make_dfa_model_node();

+extern char *ClassName();

+extern char *OutMetaName();

+extern void error();

+extern void warning();

+extern void p_head();                   /* MR9 */

+extern void p_class_hdr();              /* MR9 */

+extern void p_includes();               /* MR9 */

+extern void p_tables();                 /* MR9 */

+extern void p_tail();					/* MR1 */

+extern void p_class_def1();				/* MR1 */

+extern void new_automaton_mode();			/* MR1 */

+extern int  relabel();					/* MR1 */

+extern void p_shift_table();				/* MR1 */

+extern void p_bshift_table();				/* MR1 */

+extern void p_class_table();				/* MR1 */

+extern void p_mode_def();				/* MR1 */

+extern void init();					/* MR1 */

+extern void p_class_def2();				/* MR1 */

+extern void clear_hash();				/* MR1 */

+extern void p_alternative_table();			/* MR1 */

+extern void p_node_table();				/* MR1 */

+extern void p_dfa_table();				/* MR1 */

+extern void p_accept_table();				/* MR1 */

+extern void p_action_table();				/* MR1 */

+extern void p_base_table();				/* MR1 */

+extern void p_single_node();				/* MR1 */

+extern char * minsize();				/* MR1 */

+extern void close1();					/* MR1 */

+extern void partition();				/* MR1 */

+extern void intersect_nfa_labels();			/* MR1 */

+extern void r_intersect();				/* MR1 */

+extern void label_node();				/* MR1 */

+extern void label_with_classes();			/* MR1 */

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.r b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.r
new file mode 100644
index 0000000..c5311fa
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg.r
@@ -0,0 +1,275 @@
+/*

+	File:		dlgMPW.r

+	Target:		dlg 133MR

+	Created:    Monday, June 15, 1998 4:44:11 AM

+	Author:		Kenji Tanaka (kentar@osa.att.ne.jp)

+*/

+

+#include "cmdo.r"

+

+resource 'cmdo' (128, "Dlg") {

+	{	/* array dialogs: 1 elements */

+		/* [1] */

+		295,

+		"DLG -- Purdue Compiler Construction Tool"

+		" Set (PCCTS) lexical analyzer generator.",

+		{	/* array itemArray: 18 elements */

+			/* [1] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{35, 175, 50, 225},

+				"On",

+				"-CC",

+				"When this control is checked, DLG genera"

+				"tes a scanner using C++ classes rather t"

+				"han C functions."

+			},

+			/* [2] */

+			Or {

+				{	/* array OrArray: 1 elements */

+					/* [1] */

+					1

+				}

+			},

+			RegularEntry {

+				"Lexer Class Name:",

+				{35, 225, 50, 355},

+				{35, 355, 51, 450},

+				"DLGLexer",

+				keepCase,

+				"-cl",

+				"This entry specifies the name DLG uses f"

+				"or the C++ lexer class."

+			},

+			/* [3] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{25, 165, 60, 460},

+				"C++ Code Generation"

+			},

+			/* [4] */

+			NotDependent {

+

+			},

+			Files {

+				InputFile,

+				RequiredFile {

+					{37, 25, 56, 135},

+					"Input File",

+					"",

+					"Choose the lexical description file for "

+					"DLG to process."

+				},

+				Additional {

+					"",

+					"",

+					"",

+					"",

+					{	/* array TypesArray: 1 elements */

+						/* [1] */

+						text

+					}

+				}

+			},

+			/* [5] */

+			Or {

+				{	/* array OrArray: 1 elements */

+					/* [1] */

+					-1

+				}

+			},

+			Files {

+				OutputFile,

+				RequiredFile {

+					{66, 25, 85, 135},

+					"Output File",

+					"",

+					"Choose the name of the file that will ho"

+					"ld the DLG-produced scanner."

+				},

+				NoMore {

+

+				}

+			},

+			/* [6] */

+			Or {

+				{	/* array OrArray: 2 elements */

+					/* [1] */

+					1,

+					/* [2] */

+					5

+				}

+			},

+			Dummy {

+

+			},

+			/* [7] */

+			NotDependent {

+

+			},

+			Redirection {

+				DiagnosticOutput,

+				{90, 25}

+			},

+			/* [8] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{25, 20, 132, 145},

+				"Files"

+			},

+			/* [9] */

+			NotDependent {

+

+			},

+			Files {

+				DirOnly,

+				OptionalFile {

+					{68, 175, 84, 305},

+					{88, 175, 107, 305},

+					"Output Directory",

+					":",

+					"-o",

+					"",

+					"Choose the directory where DLG will put "

+					"its output.",

+					dim,

+					"Output DirectoryI",

+					"",

+					""

+				},

+				NoMore {

+

+				}

+			},

+			/* [10] */

+			NotDependent {

+

+			},

+			RegularEntry {

+				"Mode File Name:",

+				{68, 315, 83, 450},

+				{88, 315, 104, 450},

+				"mode.h",

+				keepCase,

+				"-m",

+				"This entry specifies the name DLG uses f"

+				"or its lexical mode output file."

+			},

+			/* [11] */

+			NotDependent {

+

+			},

+			RadioButtons {

+				{	/* array radioArray: 3 elements */

+					/* [1] */

+					{134, 175, 149, 255}, "None", "", Set, "When this option is selected, DLG will n"

+					"ot compress its tables.",

+					/* [2] */

+					{134, 265, 149, 345}, "Level 1", "-C1", NotSet, "When this option is selected, DLG will r"

+					"emove all unused characters from the tra"

+					"nsition-from table.",

+					/* [3] */

+					{134, 360, 149, 450}, "Level 2", "-C2", NotSet, "When this option is selected, DLG will p"

+					"erform level 1 compression plus it will "

+					"map equivalent characters into the same "

+					"character classes."

+				}

+			},

+			/* [12] */

+			NotDependent {

+

+			},

+			TextBox {

+				gray,

+				{124, 165, 156, 460},

+				"Table Compression"

+			},

+			/* [13] */

+			NotDependent {

+

+			},

+			CheckOption {

+				Set,

+				{165, 20, 180, 145},

+				"Case Sensitive",

+				"-ci",

+				"When this control is checked, the DLG au"

+				"tomaton will treat upper and lower case "

+				"characters identically."

+			},

+			/* [14] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{165, 150, 180, 300},

+				"Interactive Scanner",

+				"-i",

+				"When this control is checked, DLG will g"

+				"enerate as interactive a scanner as poss"

+				"ible."

+			},

+			/* [15] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{165, 310, 180, 460},

+				"Ambiguity Warnings",

+				"-Wambiguity",

+				"When this control is checked, DLG warns "

+				"if more than one regular expression coul"

+				"d match the same character sequence."

+			},

+			/* [16] */

+			NotDependent {

+

+			},

+			VersionDialog {

+				VersionString {

+					"1.33MR"

+				},

+				"PCCTS was written by Terence Parr, Russe"

+				"ll Quong, Will Cohen, and Hank Dietz: 19"

+				"89-1998. MPW port by Scott Haney.",

+				noDialog

+			},

+			/* [17] */

+			And {

+				{	/* array AndArray: 2 elements */

+					/* [1] */

+					4,

+					/* [2] */

+					6

+				}

+			},

+			DoItButton {

+

+			},

+			/* [18] */

+			NotDependent {

+

+			},

+			CheckOption {

+				NotSet,

+				{142, 20, 157, 148},

+				"Generate ANSI C",

+				"-ga",

+				"When this control is checked, DLG genera"

+				"tes ANSI C compatible code."

+			}

+		}

+	}

+};

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg1.txt b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg1.txt
new file mode 100644
index 0000000..06b320d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg1.txt
@@ -0,0 +1,132 @@
+

+

+

+dlg(1)                 PCCTS Manual Pages                  dlg(1)

+

+

+

+NAME

+     dlg - DFA Lexical Analyzer Generator

+

+SYNTAX

+     dlg [_o_p_t_i_o_n_s] _l_e_x_i_c_a_l__s_p_e_c [_o_u_t_p_u_t__f_i_l_e]

+

+DESCRIPTION

+     dlg is a tool that produces fast deterministic finite auto-

+     mata for recognizing regular expressions in input.

+

+OPTIONS

+     -CC  Generate C++ output.  The _o_u_t_p_u_t__f_i_l_e is not specified

+          in this case.

+

+     -C[ level]

+          Where level is the compression level used.  0 indica-

+          tions no compression, 1 removes all unused characters

+          from the transition from table, and 2 maps equivalent

+          characters into the same character classes.  It is sug-

+          gested that level -C2 is used, since it will signifi-

+          cantly reduce the size of the dfa produced for lexical

+          analyzer.

+

+     -m   Produces the header file for the lexical mode with a

+          name other than the default name of "mode.h".

+

+     -i   An interactive, or as interactive as possible, parser

+          is produced.  A character is only obtained when

+          required to decide which state to go to.  Some care

+          must be taken to obtain accept states that do not

+          require look ahead at the next character to determine

+          if that is the stop state.  Any regular expression with

+          a Kleene closure at the end is guaranteed to require

+          another character of look ahead.

+

+     -cl class

+          Specify a class name for DLG to generate.  The default

+          is DLGLexer.

+

+     -ci  The automaton will treat upper and lower case charac-

+          ters identically.  This is accomplished in the automa-

+          ton; the characters in the lexical buffer are unmodi-

+          fied.

+

+     -cs  Upper and lower case characters are treated as dis-

+          tinct.  This is the default.

+

+     -o dir

+          Directory where output files should go (default=".").

+          This is very nice for keeping the source directory

+          clear of ANTLR and DLG spawn.

+

+     -Wambiguity

+          Warns if more than one regular expression could match

+          the same character sequence.  The warnings give the

+          numbers of the expressions in the dlg lexical specifi-

+          cation file.  The numbering of the expressions starts

+          at one.  Multiple warnings may be print for the same

+          expressions.

+

+     -    Used in place of file names to get input from standard

+          in or send output to standard out.

+

+SPECIAL CONSIDERATIONS

+     _D_l_g works...  we think.  There is no implicit guarantee of

+     anything.  We reserve no legal rights to the software known

+     as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS

+     is in the public domain.  An individual or company may do

+     whatever they wish with source code distributed with PCCTS

+     or the code generated by PCCTS, including the incorporation

+     of PCCTS, or its output, into commercial software.  We

+     encourage users to develop software with PCCTS.  However, we

+     do ask that credit is given to us for developing PCCTS.  By

+     "credit", we mean that if you incorporate our source code

+     into one of your programs (commercial product, research pro-

+     ject, or otherwise) that you acknowledge this fact somewhere

+     in the documentation, research report, etc...  If you like

+     PCCTS and have developed a nice tool with the output, please

+     mention that you developed it using PCCTS.  As long as these

+     guidelines are followed, we expect to continue enhancing

+     this system and expect to make other tools available as they

+     are completed.

+

+FILES

+     mode.h , dlgauto.h , dlgdef.h

+

+SEE ALSO

+     antlr(1), pccts(1)

+

+BUGS

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_a.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_a.c
new file mode 100644
index 0000000..0b8982c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_a.c
@@ -0,0 +1,1414 @@
+

+/* parser.dlg -- DLG Description of scanner

+ *

+ * Generated from: dlg_p.g

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include <ctype.h>

+#include "dlg.h"

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+LOOKAHEAD

+

+void

+#ifdef __USE_PROTOS

+zzerraction(void)

+#else

+zzerraction()

+#endif

+{

+	(*zzerr)("invalid token");

+	zzadvance();

+	zzskip();

+}

+/*

+ * D L G tables

+ *

+ * Generated from: parser.dlg

+ *

+ * 1989-2001 by  Will Cohen, Terence Parr, and Hank Dietz

+ * Purdue University Electrical Engineering

+ * DLG Version 1.33MR33

+ */

+

+#include "mode.h"

+

+

+

+

+int	func_action;		/* should actions be turned into functions?*/

+int	lex_mode_counter = 0;	/* keeps track of the number of %%names */

+/* MR1									    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+/* MR1				via <<%%lexmember...>>			    */

+/* MR1									    */

+int	lexMember = 0;		/* <<%%lexmemeber ...>>	   		MR1 */

+int	lexAction = 0;		/* <<%%lexaction ...>>			MR1 */

+int	parserClass = 0;	/* <<%%parserclass ...>>        MR1 */

+int	lexPrefix = 0;		/* <<%%lexprefix ...>>			MR1 */

+char	theClassName[100];						     /* MR11 */

+char	*pClassName=theClassName;					 /* MR11 */

+int	firstLexMember=1;					             /* MR1 */

+

+#ifdef __USE_PROTOS

+void  xxputc(int c) {						/* MR1 */

+#else

+  void xxputc(c)							/* MR1 */

+  int	c;							/* MR1 */

+  {								/* MR1 */

+#endif

+    if (parserClass) {						/* MR1 */

+      *pClassName++=c;						/* MR1 */

+      *pClassName=0;						/* MR1 */

+    } else if (lexMember || lexPrefix) {				/* MR1 */

+      if (class_stream != NULL) fputc(c,class_stream);		/* MR1 */

+    } else {							/* MR1 */

+      fputc(c,OUT);						/* MR1 */

+    };								/* MR1 */

+  }  								/* MR1 */

+  

+#ifdef __USE_PROTOS

+  void xxprintf(char *format,char *string) {			/* MR1 */

+#else

+    void xxprintf(format,string) 					/* MR1 */

+    char *format;							/* MR1 */

+    char *string;							/* MR1 */

+    {								/* MR1 */

+#endif

+      if (lexMember || lexPrefix || parserClass) {			/* MR1 */

+        if (class_stream != NULL)					/* MR1 */

+        fprintf(class_stream,format,string);			/* MR1 */

+      } else {							/* MR1 */

+        fprintf(OUT,format,string);					/* MR1 */

+      };								/* MR1 */

+    }  								/* MR1 */

+

+static void act1()

+{ 

+		NLA = 1;

+	}

+

+

+static void act2()

+{ 

+		NLA = 2;

+    zzskip();   

+	}

+

+

+static void act3()

+{ 

+		NLA = 3;

+    zzline++; zzskip(); DAWDLE;   

+	}

+

+

+static void act4()

+{ 

+		NLA = L_EOF;

+	}

+

+

+static void act5()

+{ 

+		NLA = PER_PER;

+	}

+

+

+static void act6()

+{ 

+		NLA = NAME_PER_PER;

+    p_mode_def(&zzlextext[2],lex_mode_counter++);   

+	}

+

+

+static void act7()

+{ 

+		NLA = LEXMEMBER;

+    lexMember=1;					/* MR1 */

+    if (firstLexMember != 0) {			/* MR1 */

+      firstLexMember=0;				/* MR1 */

+      p_class_def1();				/* MR1 */

+    };						/* MR1 */

+    zzmode(ACT);					/* MR1 */

+	}

+

+

+static void act8()

+{ 

+		NLA = LEXACTION;

+    lexAction=1;zzmode(ACT);  

+	}

+

+

+static void act9()

+{ 

+		NLA = PARSERCLASS;

+    parserClass=1;				/* MR1 */

+    zzmode(ACT);					/* MR1 */

+	}

+

+

+static void act10()

+{ 

+		NLA = LEXPREFIX;

+    lexPrefix=1;zzmode(ACT);  

+	}

+

+

+static void act11()

+{ 

+		NLA = ACTION;

+    if (func_action)

+    fprintf(OUT,"\n%s %sact%d()\n{ ",

+    gen_cpp?"ANTLRTokenType":"static void",

+    gen_cpp?ClassName("::"):"", ++action_no);

+    zzmode(ACT); zzskip();

+	}

+

+

+static void act12()

+{ 

+		NLA = GREAT_GREAT;

+	}

+

+

+static void act13()

+{ 

+		NLA = L_BRACE;

+	}

+

+

+static void act14()

+{ 

+		NLA = R_BRACE;

+	}

+

+

+static void act15()

+{ 

+		NLA = L_PAR;

+	}

+

+

+static void act16()

+{ 

+		NLA = R_PAR;

+	}

+

+

+static void act17()

+{ 

+		NLA = L_BRACK;

+	}

+

+

+static void act18()

+{ 

+		NLA = R_BRACK;

+	}

+

+

+static void act19()

+{ 

+		NLA = ZERO_MORE;

+	}

+

+

+static void act20()

+{ 

+		NLA = ONE_MORE;

+	}

+

+

+static void act21()

+{ 

+		NLA = OR;

+	}

+

+

+static void act22()

+{ 

+		NLA = RANGE;

+	}

+

+

+static void act23()

+{ 

+		NLA = NOT;

+	}

+

+

+static void act24()

+{ 

+		NLA = OCTAL_VALUE;

+    {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}  

+	}

+

+

+static void act25()

+{ 

+		NLA = HEX_VALUE;

+    {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}  

+	}

+

+

+static void act26()

+{ 

+		NLA = DEC_VALUE;

+    {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}  

+	}

+

+

+static void act27()

+{ 

+		NLA = TAB;

+    zzlextext[0] = '\t';  

+	}

+

+

+static void act28()

+{ 

+		NLA = NL;

+    zzlextext[0] = '\n';  

+	}

+

+

+static void act29()

+{ 

+		NLA = CR;

+    zzlextext[0] = '\r';  

+	}

+

+

+static void act30()

+{ 

+		NLA = BS;

+    zzlextext[0] = '\b';  

+	}

+

+

+static void act31()

+{ 

+		NLA = CONTINUATION;

+    zzline++; zzskip();  

+	}

+

+

+static void act32()

+{ 

+		NLA = LIT;

+    zzlextext[0] = zzlextext[1];  

+	}

+

+

+static void act33()

+{ 

+		NLA = REGCHAR;

+	}

+

+static unsigned char shift0[257] = {

+  0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  1, 2, 40, 40, 1, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 1, 40, 40, 40, 40, 4, 40, 

+  40, 30, 31, 34, 35, 40, 37, 40, 40, 23, 

+  24, 24, 24, 24, 24, 24, 24, 25, 25, 40, 

+  40, 26, 40, 27, 40, 3, 21, 21, 21, 21, 

+  21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 

+  22, 22, 22, 22, 22, 22, 22, 22, 22, 20, 

+  22, 22, 32, 39, 33, 40, 22, 40, 11, 9, 

+  12, 21, 6, 19, 22, 22, 14, 22, 22, 5, 

+  8, 16, 15, 17, 22, 10, 18, 13, 22, 22, 

+  22, 7, 22, 22, 28, 36, 29, 38, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 

+  40, 40, 40, 40, 40, 40, 40

+};

+

+

+static void act34()

+{ 

+		NLA = 1;

+    error("unterminated action", zzline); zzmode(START);   

+	}

+

+

+static void act35()

+{ 

+		NLA = ACTION;

+    if (func_action) fprintf(OUT,"}\n\n");

+    zzmode(START);

+    /* MR1									    */

+    /* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+    /* MR1				via <<%%lexmember ...>>			    */

+    /* MR1			This is a consequence of not saving actions         */

+    /* MR1									    */

+    /* MR1 */	   parserClass=0;		

+    /* MR1 */	   lexPrefix=0;

+    /* MR1 */	   lexAction=0;

+    /* MR1 */	   lexMember=0;

+	}

+

+

+static void act36()

+{ 

+		NLA = 34;

+    xxputc(zzlextext[0]); zzskip();   

+	}

+

+

+static void act37()

+{ 

+		NLA = 35;

+    xxputc('>'); zzskip();   

+	}

+

+

+static void act38()

+{ 

+		NLA = 36;

+    xxputc('\\'); zzskip();   

+	}

+

+

+static void act39()

+{ 

+		NLA = 37;

+    xxputc(zzlextext[0]); ++zzline; zzskip();   

+	}

+

+

+static void act40()

+{ 

+		NLA = 38;

+    zzmode(ACTION_COMMENTS);			/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	}

+

+

+static void act41()

+{ 

+		NLA = 39;

+    zzmode(ACTION_CPP_COMMENTS);			/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	}

+

+

+static void act42()

+{ 

+		NLA = 40;

+    xxputc(zzlextext[0]); zzskip();   

+	}

+

+static unsigned char shift1[257] = {

+  0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 3, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 5, 6, 6, 6, 6, 4, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 1, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6

+};

+

+

+static void act43()

+{ 

+		NLA = 1;

+	}

+

+

+static void act44()

+{ 

+		NLA = 41;

+    zzmode(ACT);					/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	}

+

+

+static void act45()

+{ 

+		NLA = 42;

+    zzline++; xxputc(zzlextext[0]); zzskip();  

+	}

+

+

+static void act46()

+{ 

+		NLA = 43;

+    xxputc(zzlextext[0]); zzskip();  

+	}

+

+static unsigned char shift2[257] = {

+  0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 3, 4, 4, 3, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 1, 4, 4, 4, 4, 2, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 

+  4, 4, 4, 4, 4, 4, 4

+};

+

+

+static void act47()

+{ 

+		NLA = 1;

+	}

+

+

+static void act48()

+{ 

+		NLA = 44;

+    zzmode(ACT); zzline++;			/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	}

+

+

+static void act49()

+{ 

+		NLA = 45;

+    xxputc(zzlextext[0]); zzskip();  

+	}

+

+static unsigned char shift3[257] = {

+  0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 

+  2, 2, 2, 2, 2, 2, 2

+};

+

+#define DfaStates	94

+typedef unsigned char DfaState;

+

+static DfaState st0[42] = {

+  1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 

+  6, 6, 6, 6, 6, 6, 7, 8, 9, 10, 

+  11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 

+  6, 94

+};

+

+static DfaState st1[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st2[42] = {

+  94, 21, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st3[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st4[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st5[42] = {

+  94, 94, 94, 94, 22, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st6[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st7[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 23, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st8[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 24, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st9[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st10[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st11[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st12[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st13[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st14[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st15[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st16[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st17[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st18[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st19[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st20[42] = {

+  94, 25, 26, 25, 25, 25, 25, 25, 25, 27, 

+  28, 25, 25, 29, 25, 25, 30, 25, 25, 25, 

+  25, 25, 25, 31, 32, 32, 25, 25, 25, 25, 

+  25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 

+  25, 94

+};

+

+static DfaState st21[42] = {

+  94, 21, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st22[42] = {

+  94, 94, 94, 94, 94, 33, 33, 33, 33, 33, 

+  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 

+  33, 33, 33, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st23[42] = {

+  94, 94, 94, 94, 34, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st24[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st25[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st26[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st27[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st28[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st29[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st30[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st31[42] = {

+  94, 94, 94, 94, 94, 94, 94, 35, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  35, 94, 94, 36, 36, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st32[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 37, 37, 37, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st33[42] = {

+  94, 94, 94, 94, 94, 38, 38, 38, 38, 38, 

+  38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 

+  38, 38, 38, 38, 38, 38, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st34[42] = {

+  94, 94, 94, 94, 39, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st35[42] = {

+  94, 94, 94, 94, 94, 94, 40, 94, 94, 40, 

+  94, 40, 40, 94, 94, 94, 94, 94, 94, 40, 

+  94, 40, 94, 40, 40, 40, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st36[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 36, 36, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st37[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 37, 37, 37, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st38[42] = {

+  94, 94, 94, 94, 94, 38, 38, 38, 38, 38, 

+  38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 

+  38, 38, 38, 38, 38, 38, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st39[42] = {

+  94, 94, 94, 94, 94, 41, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 42, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st40[42] = {

+  94, 94, 94, 94, 94, 94, 40, 94, 94, 40, 

+  94, 40, 40, 94, 94, 94, 94, 94, 94, 40, 

+  94, 40, 94, 40, 40, 40, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st41[42] = {

+  94, 94, 94, 94, 94, 94, 43, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st42[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 44, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st43[42] = {

+  94, 94, 94, 94, 94, 94, 94, 45, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st44[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  46, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st45[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 47, 94, 

+  94, 48, 94, 94, 94, 94, 94, 49, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st46[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 50, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st47[42] = {

+  94, 94, 94, 94, 94, 94, 51, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st48[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 52, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st49[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  53, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st50[42] = {

+  94, 94, 94, 94, 94, 94, 54, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st51[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 55, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st52[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 56, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st53[42] = {

+  94, 94, 94, 94, 94, 94, 57, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st54[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  58, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st55[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 59, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st56[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 60, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st57[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 61, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st58[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 62, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st59[42] = {

+  94, 94, 94, 94, 94, 94, 63, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st60[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 64, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st61[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 65, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st62[42] = {

+  94, 94, 94, 94, 94, 66, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st63[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  67, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st64[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 68, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st65[42] = {

+  94, 94, 94, 94, 94, 94, 94, 69, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st66[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 70, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st67[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st68[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st69[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st70[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 71, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st71[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 72, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st72[42] = {

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 

+  94, 94

+};

+

+static DfaState st73[8] = {

+  74, 75, 76, 77, 78, 79, 79, 94

+};

+

+static DfaState st74[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st75[8] = {

+  94, 80, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st76[8] = {

+  94, 81, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st77[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st78[8] = {

+  94, 94, 94, 94, 82, 83, 94, 94

+};

+

+static DfaState st79[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st80[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st81[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st82[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st83[8] = {

+  94, 94, 94, 94, 94, 94, 94, 94

+};

+

+static DfaState st84[6] = {

+  85, 86, 87, 88, 87, 94

+};

+

+static DfaState st85[6] = {

+  94, 94, 94, 94, 94, 94

+};

+

+static DfaState st86[6] = {

+  94, 94, 89, 94, 94, 94

+};

+

+static DfaState st87[6] = {

+  94, 94, 94, 94, 94, 94

+};

+

+static DfaState st88[6] = {

+  94, 94, 94, 94, 94, 94

+};

+

+static DfaState st89[6] = {

+  94, 94, 94, 94, 94, 94

+};

+

+static DfaState st90[4] = {

+  91, 92, 93, 94

+};

+

+static DfaState st91[4] = {

+  94, 94, 94, 94

+};

+

+static DfaState st92[4] = {

+  94, 94, 94, 94

+};

+

+static DfaState st93[4] = {

+  94, 94, 94, 94

+};

+

+

+DfaState *dfa[94] = {

+	st0,

+	st1,

+	st2,

+	st3,

+	st4,

+	st5,

+	st6,

+	st7,

+	st8,

+	st9,

+	st10,

+	st11,

+	st12,

+	st13,

+	st14,

+	st15,

+	st16,

+	st17,

+	st18,

+	st19,

+	st20,

+	st21,

+	st22,

+	st23,

+	st24,

+	st25,

+	st26,

+	st27,

+	st28,

+	st29,

+	st30,

+	st31,

+	st32,

+	st33,

+	st34,

+	st35,

+	st36,

+	st37,

+	st38,

+	st39,

+	st40,

+	st41,

+	st42,

+	st43,

+	st44,

+	st45,

+	st46,

+	st47,

+	st48,

+	st49,

+	st50,

+	st51,

+	st52,

+	st53,

+	st54,

+	st55,

+	st56,

+	st57,

+	st58,

+	st59,

+	st60,

+	st61,

+	st62,

+	st63,

+	st64,

+	st65,

+	st66,

+	st67,

+	st68,

+	st69,

+	st70,

+	st71,

+	st72,

+	st73,

+	st74,

+	st75,

+	st76,

+	st77,

+	st78,

+	st79,

+	st80,

+	st81,

+	st82,

+	st83,

+	st84,

+	st85,

+	st86,

+	st87,

+	st88,

+	st89,

+	st90,

+	st91,

+	st92,

+	st93

+};

+

+

+DfaState accepts[95] = {

+  0, 1, 2, 3, 4, 33, 33, 33, 33, 13, 

+  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 

+  0, 2, 5, 11, 12, 32, 31, 30, 29, 27, 

+  28, 24, 26, 6, 0, 0, 24, 26, 6, 0, 

+  25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 

+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 

+  0, 0, 0, 0, 0, 0, 0, 7, 8, 10, 

+  0, 0, 9, 0, 34, 36, 38, 39, 42, 42, 

+  35, 37, 41, 40, 0, 43, 46, 46, 45, 44, 

+  0, 47, 48, 49, 0

+};

+

+void (*actions[50])() = {

+	zzerraction,

+	act1,

+	act2,

+	act3,

+	act4,

+	act5,

+	act6,

+	act7,

+	act8,

+	act9,

+	act10,

+	act11,

+	act12,

+	act13,

+	act14,

+	act15,

+	act16,

+	act17,

+	act18,

+	act19,

+	act20,

+	act21,

+	act22,

+	act23,

+	act24,

+	act25,

+	act26,

+	act27,

+	act28,

+	act29,

+	act30,

+	act31,

+	act32,

+	act33,

+	act34,

+	act35,

+	act36,

+	act37,

+	act38,

+	act39,

+	act40,

+	act41,

+	act42,

+	act43,

+	act44,

+	act45,

+	act46,

+	act47,

+	act48,

+	act49

+};

+

+static DfaState dfa_base[] = {

+	0,

+	73,

+	84,

+	90

+};

+

+static unsigned char *b_class_no[] = {

+	shift0,

+	shift1,

+	shift2,

+	shift3

+};

+

+

+

+#define ZZSHIFT(c) (b_class_no[zzauto][1+c])

+#define MAX_MODE 4

+#include "dlgauto.h"

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_p.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_p.c
new file mode 100644
index 0000000..e726ae3
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_p.c
@@ -0,0 +1,959 @@
+/*

+ * A n t l r  T r a n s l a t i o n  H e a d e r

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ *

+ *   ..\bin\antlr dlg_p.g -gh

+ *

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include <ctype.h>

+#include "dlg.h"

+#define zzSET_SIZE 8

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+#include "mode.h"

+

+/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */

+

+#ifndef PCCTS_PURIFY

+#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s));

+#endif

+

+ANTLR_INFO

+

+

+/* MR20 G. Hobbelt 

+Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled

+*/

+

+#ifdef __TURBOC__

+#pragma warn -aus  /* unused assignment of 'xxx' */

+#endif

+

+int	action_no = 0;	   /* keep track of actions outputed */

+int	nfa_allocated = 0; /* keeps track of number of nfa nodes */

+nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */

+nfa_node nfa_model_node;   /* model to initialize new nodes */

+set	used_chars;	   /* used to label trans. arcs */

+set	used_classes;	   /* classes or chars used to label trans. arcs */

+set	normal_chars;	   /* mask to get rid elements that aren't used

+in set */

+int	flag_paren = FALSE;

+int	flag_brace = FALSE;

+int	mode_counter = 0;  /* keep track of number of %%names */

+

+  

+

+void

+#ifdef __USE_PROTOS

+grammar(void)

+#else

+grammar()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  p_head(); p_class_hdr(); func_action = FALSE;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (setwd1[LA(1)]&0x1) ) {

+      {

+        zzBLOCK(zztasp3);

+        zzMake0;

+        {

+        if ( (LA(1)==LEXACTION) ) {

+          zzmatch(LEXACTION); zzCONSUME;

+        }

+        else {

+          if ( (LA(1)==LEXMEMBER) ) {

+            zzmatch(LEXMEMBER); zzCONSUME;

+          }

+          else {

+            if ( (LA(1)==LEXPREFIX) ) {

+              zzmatch(LEXPREFIX); zzCONSUME;

+            }

+            else {

+              if ( (LA(1)==PARSERCLASS) ) {

+                zzmatch(PARSERCLASS); zzCONSUME;

+              }

+              else {

+                if ( (LA(1)==ACTION) ) {

+                }

+                else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+              }

+            }

+          }

+        }

+        zzEXIT(zztasp3);

+        }

+      }

+      zzmatch(ACTION); zzCONSUME;

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  if ( gen_cpp ) p_includes();

+  start_states();

+  func_action = FALSE; p_tables(); p_tail();

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==ACTION) ) {

+      zzmatch(ACTION); zzCONSUME;

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(1);

+  if (firstLexMember != 0) p_class_def1();

+ zzCONSUME;

+

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd1, 0x2);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+start_states(void)

+#else

+start_states()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==PER_PER) ) {

+      zzmatch(PER_PER); zzCONSUME;

+      do_conversion();

+    }

+    else {

+      if ( (LA(1)==NAME_PER_PER) ) {

+        zzmatch(NAME_PER_PER); zzCONSUME;

+        do_conversion();

+        {

+          zzBLOCK(zztasp3);

+          zzMake0;

+          {

+          while ( (LA(1)==NAME_PER_PER) ) {

+            zzmatch(NAME_PER_PER); zzCONSUME;

+            do_conversion();

+            zzLOOP(zztasp3);

+          }

+          zzEXIT(zztasp3);

+          }

+        }

+      }

+      else {zzFAIL(1,zzerr2,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzmatch(PER_PER); zzCONSUME;

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd1, 0x4);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+do_conversion(void)

+#else

+do_conversion()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  new_automaton_mode(); func_action = TRUE;

+  rule_list();

+  

+  dfa_class_nop[mode_counter] =

+  relabel(zzaArg(zztasp1,1 ).l,comp_level);

+  if (comp_level)

+  p_shift_table(mode_counter);

+  dfa_basep[mode_counter] = dfa_allocated+1;

+  make_dfa_model_node(dfa_class_nop[mode_counter]);

+  nfa_to_dfa(zzaArg(zztasp1,1 ).l);

+  ++mode_counter;

+  func_action = FALSE;

+#ifdef HASH_STAT

+  fprint_hash_stats(stderr);

+#endif

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd1, 0x8);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+rule_list(void)

+#else

+rule_list()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  if ( (setwd1[LA(1)]&0x10) ) {

+    rule();

+    zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;

+    {

+      zzBLOCK(zztasp2);

+      zzMake0;

+      {

+      while ( (setwd1[LA(1)]&0x20) ) {

+        rule();

+        {nfa_node *t1;

+          t1 = new_nfa_node();

+          (t1)->trans[0]=zzaRet.l;

+          (t1)->trans[1]=zzaArg(zztasp2,1 ).l;

+          /* all accept nodes "dead ends" */

+          zzaRet.l=t1; zzaRet.r=NULL;

+        }

+        zzLOOP(zztasp2);

+      }

+      zzEXIT(zztasp2);

+      }

+    }

+  }

+  else {

+    if ( (setwd1[LA(1)]&0x40) ) {

+      zzaRet.l = new_nfa_node(); zzaRet.r = NULL;

+      warning("no regular expressions", zzline);

+    }

+    else {zzFAIL(1,zzerr3,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd1, 0x80);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+rule(void)

+#else

+rule()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  if ( (setwd2[LA(1)]&0x1) ) {

+    reg_expr();

+    zzmatch(ACTION);

+    if (zzaArg(zztasp1,1 ).r != NULL) {

+      zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; (zzaArg(zztasp1,1 ).r)->accept=action_no;

+    }

+ zzCONSUME;

+

+  }

+  else {

+    if ( (LA(1)==ACTION) ) {

+      zzmatch(ACTION);

+      zzaRet.l = NULL; zzaRet.r = NULL;

+      error("no expression for action  ", zzline);

+ zzCONSUME;

+

+    }

+    else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x2);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+reg_expr(void)

+#else

+reg_expr()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  and_expr();

+  zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (LA(1)==OR) ) {

+      zzmatch(OR); zzCONSUME;

+      and_expr();

+      {nfa_node *t1, *t2;

+        t1 = new_nfa_node(); t2 = new_nfa_node();

+        (t1)->trans[0]=zzaRet.l;

+        (t1)->trans[1]=zzaArg(zztasp2,2 ).l;

+        /* MR23 */		   if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2;

+        if (zzaArg(zztasp2,2 ).r) {

+          (zzaArg(zztasp2,2 ).r)->trans[1]=t2;     /* MR20 */

+        }

+        zzaRet.l=t1; zzaRet.r=t2;

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x4);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+and_expr(void)

+#else

+and_expr()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  repeat_expr();

+  

+  zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (setwd2[LA(1)]&0x8) ) {

+      repeat_expr();

+      if (zzaRet.r != NULL) {

+        (zzaRet.r)->trans[1]=zzaArg(zztasp2,1 ).l;

+        zzaRet.r=zzaArg(zztasp2,1 ).r;

+      }

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x10);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+repeat_expr(void)

+#else

+repeat_expr()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  if ( (setwd2[LA(1)]&0x20) ) {

+    expr();

+    zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;

+    {

+      zzBLOCK(zztasp2);

+      zzMake0;

+      {

+      if ( (LA(1)==ZERO_MORE) ) {

+        zzmatch(ZERO_MORE);

+        {	nfa_node *t1,*t2;

+          /* MR23 */		if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l;

+          t1 = new_nfa_node(); t2 = new_nfa_node();

+          t1->trans[0]=zzaRet.l;

+          t1->trans[1]=t2;

+          /* MR23 */		if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2;

+          zzaRet.l=t1;zzaRet.r=t2;

+        }

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==ONE_MORE) ) {

+          zzmatch(ONE_MORE);

+          if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l;

+ zzCONSUME;

+

+        }

+        else {

+          if ( (setwd2[LA(1)]&0x40) ) {

+          }

+          else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+      }

+      zzEXIT(zztasp2);

+      }

+    }

+  }

+  else {

+    if ( (LA(1)==ZERO_MORE) ) {

+      zzmatch(ZERO_MORE);

+      error("no expression for *", zzline);

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==ONE_MORE) ) {

+        zzmatch(ONE_MORE);

+        error("no expression for +", zzline);

+ zzCONSUME;

+

+      }

+      else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd2, 0x80);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+expr(void)

+#else

+expr()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  zzaRet.l = new_nfa_node();

+  zzaRet.r = new_nfa_node();

+  if ( (LA(1)==L_BRACK) ) {

+    zzmatch(L_BRACK); zzCONSUME;

+    atom_list();

+    zzmatch(R_BRACK);

+    

+    /* MR23 */		if (zzaRet.l != NULL) {

+      (zzaRet.l)->trans[0] = zzaRet.r;

+      (zzaRet.l)->label = set_dup(zzaArg(zztasp1,2 ).label);

+      set_orin(&used_chars,(zzaRet.l)->label);

+    }

+ zzCONSUME;

+

+  }

+  else {

+    if ( (LA(1)==NOT) ) {

+      zzmatch(NOT); zzCONSUME;

+      zzmatch(L_BRACK); zzCONSUME;

+      atom_list();

+      zzmatch(R_BRACK);

+      

+      /* MR23 */		if (zzaRet.l != NULL) {

+        (zzaRet.l)->trans[0] = zzaRet.r;

+        (zzaRet.l)->label = set_dif(normal_chars,zzaArg(zztasp1,3 ).label);

+        set_orin(&used_chars,(zzaRet.l)->label);

+      }

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==L_PAR) ) {

+        zzmatch(L_PAR); zzCONSUME;

+        reg_expr();

+        zzmatch(R_PAR);

+        

+        /* MR23 */		if (zzaRet.l != NULL) {				

+          (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l;

+          if (zzaArg(zztasp1,2 ).r) {

+            (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r;    /* MR20 */

+          }

+        }

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==L_BRACE) ) {

+          zzmatch(L_BRACE); zzCONSUME;

+          reg_expr();

+          zzmatch(R_BRACE);

+          

+          /* MR23 */		if (zzaRet.l != NULL) {

+            (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l;

+            (zzaRet.l)->trans[1] = zzaRet.r;

+            if (zzaArg(zztasp1,2 ).r) {

+              (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r;    /* MR20 */

+            }

+          }

+ zzCONSUME;

+

+        }

+        else {

+          if ( (setwd3[LA(1)]&0x1) ) {

+            atom();

+            

+            /* MR23 */		if (zzaRet.l != NULL) {

+              (zzaRet.l)->trans[0] = zzaRet.r;

+              (zzaRet.l)->label = set_dup(zzaArg(zztasp1,1 ).label);

+              set_orin(&used_chars,(zzaRet.l)->label);

+            }

+          }

+          else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+        }

+      }

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x2);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+atom_list(void)

+#else

+atom_list()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  set_free(zzaRet.label);

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    while ( (setwd3[LA(1)]&0x4) ) {

+      near_atom();

+      set_orin(&(zzaRet.label),zzaArg(zztasp2,1 ).label);

+      zzLOOP(zztasp2);

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x8);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+near_atom(void)

+#else

+near_atom()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  register int i;

+  register int i_prime;

+  anychar();

+  zzaRet.letter=zzaArg(zztasp1,1 ).letter; zzaRet.label=set_of(zzaArg(zztasp1,1 ).letter);

+  i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR;

+  if (case_insensitive && islower(i_prime))

+  set_orel(toupper(i_prime)-MIN_CHAR,

+  &(zzaRet.label));

+  if (case_insensitive && isupper(i_prime))

+  set_orel(tolower(i_prime)-MIN_CHAR,

+  &(zzaRet.label));

+  {

+    zzBLOCK(zztasp2);

+    zzMake0;

+    {

+    if ( (LA(1)==RANGE) ) {

+      zzmatch(RANGE); zzCONSUME;

+      anychar();

+      if (case_insensitive){

+        i_prime = zzaRet.letter+MIN_CHAR;

+        zzaRet.letter = (islower(i_prime) ?

+        toupper(i_prime) : i_prime)-MIN_CHAR;

+        i_prime = zzaArg(zztasp2,2 ).letter+MIN_CHAR;

+        zzaArg(zztasp2,2 ).letter = (islower(i_prime) ?

+        toupper(i_prime) : i_prime)-MIN_CHAR;

+      }

+      /* check to see if range okay */

+      {

+        int debugLetter1 = zzaRet.letter;

+        int debugLetter2 = zzaArg(zztasp2,2 ).letter;

+      }

+      if (zzaRet.letter > zzaArg(zztasp2,2 ).letter 

+      && zzaArg(zztasp2,2 ).letter != 0xff){       /* MR16 */

+        error("invalid range  ", zzline);

+      }

+      for (i=zzaRet.letter; i<= (int)zzaArg(zztasp2,2 ).letter; ++i){

+        set_orel(i,&(zzaRet.label));

+        i_prime = i+MIN_CHAR;

+        if (case_insensitive && islower(i_prime))

+        set_orel(toupper(i_prime)-MIN_CHAR,

+        &(zzaRet.label));

+        if (case_insensitive && isupper(i_prime))

+        set_orel(tolower(i_prime)-MIN_CHAR,

+        &(zzaRet.label));

+      }

+    }

+    else {

+      if ( (setwd3[LA(1)]&0x10) ) {

+      }

+      else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+    }

+    zzEXIT(zztasp2);

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x20);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+atom(void)

+#else

+atom()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  register int i_prime;

+  anychar();

+  zzaRet.label = set_of(zzaArg(zztasp1,1 ).letter);

+  i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR;

+  if (case_insensitive && islower(i_prime))

+  set_orel(toupper(i_prime)-MIN_CHAR,

+  &(zzaRet.label));

+  if (case_insensitive && isupper(i_prime))

+  set_orel(tolower(i_prime)-MIN_CHAR,

+  &(zzaRet.label));

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x40);

+  }

+}

+

+void

+#ifdef __USE_PROTOS

+anychar(void)

+#else

+anychar()

+#endif

+{

+  zzRULE;

+  zzBLOCK(zztasp1);

+  zzMake0;

+  {

+  if ( (LA(1)==REGCHAR) ) {

+    zzmatch(REGCHAR);

+    zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+  }

+  else {

+    if ( (LA(1)==OCTAL_VALUE) ) {

+      zzmatch(OCTAL_VALUE);

+      zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+    }

+    else {

+      if ( (LA(1)==HEX_VALUE) ) {

+        zzmatch(HEX_VALUE);

+        zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+      }

+      else {

+        if ( (LA(1)==DEC_VALUE) ) {

+          zzmatch(DEC_VALUE);

+          zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+        }

+        else {

+          if ( (LA(1)==TAB) ) {

+            zzmatch(TAB);

+            zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+          }

+          else {

+            if ( (LA(1)==NL) ) {

+              zzmatch(NL);

+              zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+            }

+            else {

+              if ( (LA(1)==CR) ) {

+                zzmatch(CR);

+                zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+              }

+              else {

+                if ( (LA(1)==BS) ) {

+                  zzmatch(BS);

+                  zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+                }

+                else {

+                  if ( (LA(1)==LIT) ) {

+                    zzmatch(LIT);

+                    zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;

+ zzCONSUME;

+

+                  }

+                  else {

+                    if ( (LA(1)==L_EOF) ) {

+                      zzmatch(L_EOF);

+                      zzaRet.letter = 0;

+ zzCONSUME;

+

+                    }

+                    else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}

+                  }

+                }

+              }

+            }

+          }

+        }

+      }

+    }

+  }

+  zzEXIT(zztasp1);

+  return;

+fail:

+  zzEXIT(zztasp1);

+  /* empty action */  

+  zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);

+  zzresynch(setwd3, 0x80);

+  }

+}

+

+/* adds a new nfa to the binary tree and returns a pointer to it */

+nfa_node *

+#ifdef __USE_PROTOS

+new_nfa_node(void)

+#else

+new_nfa_node()

+#endif

+{

+  register nfa_node *t;

+  static int nfa_size=0;	/* elements nfa_array[] can hold */

+  

+	++nfa_allocated;

+  if (nfa_size<=nfa_allocated){

+    /* need to redo array */

+    if (!nfa_array){

+      /* need some to do inital allocation */

+      nfa_size=nfa_allocated+NFA_MIN;

+      nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)*

+      nfa_size);

+    }else{

+      /* need more space */

+      nfa_size=2*(nfa_allocated+1);

+      nfa_array=(nfa_node **) realloc(nfa_array,

+      sizeof(nfa_node*)*nfa_size);

+    }

+  }

+  /* fill out entry in array */

+  t = (nfa_node*) malloc(sizeof(nfa_node));

+  nfa_array[nfa_allocated] = t;

+  *t = nfa_model_node;

+  t->node_no = nfa_allocated;

+  return t;

+}

+

+

+/* initialize the model node used to fill in newly made nfa_nodes */

+void

+#ifdef __USE_PROTOS

+make_nfa_model_node(void)

+#else

+make_nfa_model_node()

+#endif

+{

+  nfa_model_node.node_no = -1; /* impossible value for real nfa node */

+  nfa_model_node.nfa_set = 0;

+  nfa_model_node.accept = 0;   /* error state default*/

+  nfa_model_node.trans[0] = NULL;

+  nfa_model_node.trans[1] = NULL;

+  nfa_model_node.label = empty;

+}

+

+#if defined(DEBUG) || defined(_DEBUG)

+

+/* print out the pointer value and the node_number */

+void

+#ifdef __USE_PROTOS

+fprint_dfa_pair(FILE *f, nfa_node *p)

+#else

+fprint_dfa_pair(f, p)

+FILE *f;

+nfa_node *p;

+#endif

+{

+  if (p){

+    fprintf(f, "%x (%d)", p, p->node_no);

+  }else{

+    fprintf(f, "(nil)");

+  }

+}

+

+/* print out interest information on a set */

+void

+#ifdef __USE_PROTOS

+fprint_set(FILE *f, set s)

+#else

+fprint_set(f,s)

+FILE *f;

+set s;

+#endif

+{

+  unsigned int *x;

+  

+	fprintf(f, "n = %d,", s.n);

+  if (s.setword){

+    fprintf(f, "setword = %x,   ", s.setword);

+    /* print out all the elements in the set */

+    x = set_pdq(s);

+    while (*x!=nil){

+      fprintf(f, "%d ", *x);

+      ++x;

+    }

+  }else{

+    fprintf(f, "setword = (nil)");

+  }

+}

+

+/* code to be able to dump out the nfas

+return 0 if okay dump

+return 1 if screwed up

+*/

+int

+#ifdef __USE_PROTOS

+dump_nfas(int first_node, int last_node)

+#else

+dump_nfas(first_node, last_node)

+int first_node;

+int last_node;

+#endif

+{

+  register int i;

+  nfa_node *t;

+  

+	for (i=first_node; i<=last_node; ++i){

+    t = NFA(i);

+    if (!t) break;

+    fprintf(stderr, "nfa_node %d {\n", t->node_no);

+    fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set);

+    fprintf(stderr, "\taccept\t=\t%d\n", t->accept);

+    fprintf(stderr, "\ttrans\t=\t(");

+    fprint_dfa_pair(stderr, t->trans[0]);

+    fprintf(stderr, ",");

+    fprint_dfa_pair(stderr, t->trans[1]);

+    fprintf(stderr, ")\n");

+    fprintf(stderr, "\tlabel\t=\t{ ");

+    fprint_set(stderr, t->label);

+    fprintf(stderr, "\t}\n");

+    fprintf(stderr, "}\n\n");

+  }

+  return 0;

+}

+#endif

+

+/* DLG-specific syntax error message generator

+* (define USER_ZZSYN when compiling so don't get 2 definitions)

+*/

+void

+#ifdef __USE_PROTOS

+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)

+#else

+zzsyn(text, tok, egroup, eset, etok, k, bad_text)

+char *text, *egroup, *bad_text;

+int tok;

+int etok;

+int k;

+SetWordType *eset;

+#endif

+{

+fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline);

+fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);

+if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}

+if ( k==1 ) fprintf(stderr, " missing");

+else

+{

+fprintf(stderr, "; \"%s\" not", bad_text);

+if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");

+}

+if ( zzset_deg(eset)>0 ) zzedecode(eset);

+else fprintf(stderr, " %s", zztokens[etok]);

+if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);

+fprintf(stderr, "\n");

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_p.g b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_p.g
new file mode 100644
index 0000000..58ca110
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/dlg_p.g
@@ -0,0 +1,614 @@
+/*  This is the parser for the dlg

+ *  This is a part of the Purdue Compiler Construction Tool Set

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-1995

+ */

+

+#header	<<

+#include <ctype.h>

+#include "dlg.h"

+>>

+

+<<

+

+/* MR20 G. Hobbelt 

+   Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled

+*/

+

+#ifdef __TURBOC__

+#pragma warn -aus  /* unused assignment of 'xxx' */

+#endif

+

+int	action_no = 0;	   /* keep track of actions outputed */

+int	nfa_allocated = 0; /* keeps track of number of nfa nodes */

+nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */

+nfa_node nfa_model_node;   /* model to initialize new nodes */

+set	used_chars;	   /* used to label trans. arcs */

+set	used_classes;	   /* classes or chars used to label trans. arcs */

+set	normal_chars;	   /* mask to get rid elements that aren't used

+			      in set */

+int	flag_paren = FALSE;

+int	flag_brace = FALSE;

+int	mode_counter = 0;  /* keep track of number of %%names */

+

+>>

+

+#lexaction <<

+int	func_action;		/* should actions be turned into functions?*/

+int	lex_mode_counter = 0;	/* keeps track of the number of %%names */

+/* MR1									    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+/* MR1				via <<%%lexmember...>>			    */

+/* MR1									    */

+int	lexMember = 0;		/* <<%%lexmemeber ...>>	   		MR1 */

+int	lexAction = 0;		/* <<%%lexaction ...>>			MR1 */

+int	parserClass = 0;	/* <<%%parserclass ...>>        MR1 */

+int	lexPrefix = 0;		/* <<%%lexprefix ...>>			MR1 */

+char	theClassName[100];						     /* MR11 */

+char	*pClassName=theClassName;					 /* MR11 */

+int	firstLexMember=1;					             /* MR1 */

+

+#ifdef __USE_PROTOS

+void  xxputc(int c) {						/* MR1 */

+#else

+void xxputc(c)							/* MR1 */

+  int	c;							/* MR1 */

+{								/* MR1 */

+#endif

+  if (parserClass) {						/* MR1 */

+    *pClassName++=c;						/* MR1 */

+    *pClassName=0;						/* MR1 */

+  } else if (lexMember || lexPrefix) {				/* MR1 */

+    if (class_stream != NULL) fputc(c,class_stream);		/* MR1 */

+  } else {							/* MR1 */

+    fputc(c,OUT);						/* MR1 */

+  };								/* MR1 */

+}  								/* MR1 */

+

+#ifdef __USE_PROTOS

+void xxprintf(char *format,char *string) {			/* MR1 */

+#else

+void xxprintf(format,string) 					/* MR1 */

+  char *format;							/* MR1 */

+  char *string;							/* MR1 */

+{								/* MR1 */

+#endif

+  if (lexMember || lexPrefix || parserClass) {			/* MR1 */

+    if (class_stream != NULL)					/* MR1 */

+	 fprintf(class_stream,format,string);			/* MR1 */

+  } else {							/* MR1 */

+    fprintf(OUT,format,string);					/* MR1 */

+  };								/* MR1 */

+}  								/* MR1 */

+>>

+

+#token "[\r\t\ ]+"	<< zzskip(); >>						/* Ignore white */

+#token "\n"			<< zzline++; zzskip(); DAWDLE; >>	/* Track Line # */

+#token L_EOF		"\@"

+#token PER_PER		"\%\%"

+#token NAME_PER_PER	"\%\%[a-zA-Z_][a-zA-Z0-9_]*"

+		<< p_mode_def(&zzlextext[2],lex_mode_counter++); >>

+

+#token LEXMEMBER	"\<\<\%\%lexmember"			/* MR1 */

+		<<lexMember=1;					/* MR1 */

+	          if (firstLexMember != 0) {			/* MR1 */

+	            firstLexMember=0;				/* MR1 */

+	            p_class_def1();				/* MR1 */

+		  };						/* MR1 */

+	          zzmode(ACT);					/* MR1 */

+                >>						/* MR1 */

+#token LEXACTION	"\<\<\%\%lexaction"			/* MR1 */

+		<<lexAction=1;zzmode(ACT);>>			/* MR1 */

+#token PARSERCLASS	"\<\<\%\%parserclass"			/* MR1 */

+		<<parserClass=1;				/* MR1 */

+		  zzmode(ACT);					/* MR1 */

+		>>						/* MR1 */

+#token LEXPREFIX	"\<\<\%\%lexprefix"			/* MR1 */

+		<<lexPrefix=1;zzmode(ACT);>>			/* MR1 */

+

+#token ACTION		"\<\<"

+		<< if (func_action)

+			fprintf(OUT,"\n%s %sact%d()\n{ ",

+					gen_cpp?"ANTLRTokenType":"static void",

+					gen_cpp?ClassName("::"):"", ++action_no);

+		   zzmode(ACT); zzskip();

+		>>

+#token GREAT_GREAT	"\>\>"

+#token L_BRACE		"\{"

+#token R_BRACE		"\}"

+#token L_PAR		"\("

+#token R_PAR		"\)"

+#token L_BRACK		"\["

+#token R_BRACK		"\]"

+#token ZERO_MORE	"\*"

+#token ONE_MORE		"\+"

+#token OR		"\|"

+#token RANGE		"\-"

+#token NOT		"\~"

+#token OCTAL_VALUE "\\0[0-7]*"		

+	<< {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}>>

+#token HEX_VALUE   "\\0[Xx][0-9a-fA-F]+"

+	<< {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}>>

+#token DEC_VALUE   "\\[1-9][0-9]*"

+	<< {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}>>

+#token TAB		"\\t"		<< zzlextext[0] = '\t';>>

+#token NL		"\\n"		<< zzlextext[0] = '\n';>>

+#token CR		"\\r"		<< zzlextext[0] = '\r';>>

+#token BS		"\\b"		<< zzlextext[0] = '\b';>>

+

+/* MR1									*/

+/* MR1 10-Apr-97 MR1	Allow #token regular expressions to cross lines	*/

+/* MR1									*/

+#token CONTINUATION	"\\ \n"		<< zzline++; zzskip();>> /* MR1 */

+

+/* NOTE: this takes ANYTHING after the \ */

+#token LIT		"\\~[tnrb]"	<< zzlextext[0] = zzlextext[1];>>

+

+/* NOTE: this takes ANYTHING that doesn't match the other tokens */

+#token REGCHAR		"~[\\]"

+

+

+grammar		:   << p_head(); p_class_hdr(); func_action = FALSE;>>

+		 ( {LEXACTION | LEXMEMBER | LEXPREFIX | PARSERCLASS } ACTION)* /* MR1 */

+		    <<if ( gen_cpp ) p_includes();>>

+		    start_states

+		    << func_action = FALSE; p_tables(); p_tail(); >>

+		    (ACTION)* "@"

+			<< if (firstLexMember != 0) p_class_def1(); >> 		/* MR1 */

+		;

+

+start_states	: ( PER_PER do_conversion

+		  | NAME_PER_PER do_conversion (NAME_PER_PER do_conversion)*)

+		    PER_PER

+		;

+

+do_conversion	: <<new_automaton_mode(); func_action = TRUE;>>

+			rule_list

+			<<

+				dfa_class_nop[mode_counter] =

+					relabel($1.l,comp_level);

+				if (comp_level)

+					p_shift_table(mode_counter);

+				dfa_basep[mode_counter] = dfa_allocated+1;

+				make_dfa_model_node(dfa_class_nop[mode_counter]);

+				nfa_to_dfa($1.l);

+				++mode_counter;

+		    		func_action = FALSE;

+#ifdef HASH_STAT

+				fprint_hash_stats(stderr);

+#endif

+			>>

+		;

+

+rule_list	: rule <<$$.l=$1.l; $$.r=$1.r;>>

+			(rule

+				<<{nfa_node *t1;

+				   t1 = new_nfa_node();

+				   (t1)->trans[0]=$$.l;

+				   (t1)->trans[1]=$1.l;

+				   /* all accept nodes "dead ends" */

+				   $$.l=t1; $$.r=NULL;

+				   }

+				>>

+			)*

+		| /* empty */

+			<<$$.l = new_nfa_node(); $$.r = NULL;

+			   warning("no regular expressions", zzline);

+			>>

+		;

+

+rule	: reg_expr ACTION

+/* MR23 */		<< if ($1.r != NULL) {

+					$$.l=$1.l; $$.r=$1.r; ($1.r)->accept=action_no;

+				   }

+				>>

+		| ACTION

+			<<$$.l = NULL; $$.r = NULL;

+			  error("no expression for action  ", zzline);

+			>>

+		;

+

+reg_expr	: and_expr <<$$.l=$1.l; $$.r=$1.r;>>

+			(OR and_expr

+				<<{nfa_node *t1, *t2;

+				   t1 = new_nfa_node(); t2 = new_nfa_node();

+				   (t1)->trans[0]=$$.l;

+				   (t1)->trans[1]=$2.l;

+/* MR23 */		   if ($$.r != NULL) ($$.r)->trans[1]=t2;

+                   if ($2.r) {

+    				   ($2.r)->trans[1]=t2;     /* MR20 */

+                   }

+				   $$.l=t1; $$.r=t2;

+				  }

+				>>

+			)*

+		;

+

+and_expr	: repeat_expr

+					<<

+						$$.l=$1.l; $$.r=$1.r;

+				    >>

+			(repeat_expr 

+/* MR23 */				<< if ($$.r != NULL) {

+							($$.r)->trans[1]=$1.l;

+							$$.r=$1.r;

+						   }

+						>>

+			)*

+		;

+

+repeat_expr	: expr <<$$.l=$1.l; $$.r=$1.r;>>

+			{ ZERO_MORE

+			<<{	nfa_node *t1,*t2;

+/* MR23 */		if ($$.r != NULL) ($$.r)->trans[0] = $$.l;

+				t1 = new_nfa_node(); t2 = new_nfa_node();

+				t1->trans[0]=$$.l;

+				t1->trans[1]=t2;

+/* MR23 */		if ($$.r != NULL) ($$.r)->trans[1]=t2;

+				$$.l=t1;$$.r=t2;

+			  }

+			>>

+			| ONE_MORE

+/* MR23 */		<<if ($$.r != NULL) ($$.r)->trans[0] = $$.l;>>

+			}

+		| ZERO_MORE

+			<< error("no expression for *", zzline);>>

+		| ONE_MORE

+			<< error("no expression for +", zzline);>>

+		;

+

+expr	: << $$.l = new_nfa_node();

+			 $$.r = new_nfa_node();

+		  >>

+		  L_BRACK atom_list R_BRACK

+			<<

+/* MR23 */		if ($$.l != NULL) {

+					($$.l)->trans[0] = $$.r;

+					($$.l)->label = set_dup($2.label);

+					set_orin(&used_chars,($$.l)->label);

+				}

+			>>

+		| NOT L_BRACK atom_list R_BRACK

+			<<

+/* MR23 */		if ($$.l != NULL) {

+					($$.l)->trans[0] = $$.r;

+					($$.l)->label = set_dif(normal_chars,$3.label);

+					set_orin(&used_chars,($$.l)->label);

+				}

+			>>

+		| L_PAR reg_expr R_PAR

+			<<

+/* MR23 */		if ($$.l != NULL) {				

+					($$.l)->trans[0] = $2.l;

+					if ($2.r) {

+    					($2.r)->trans[1] = $$.r;    /* MR20 */

+					}

+				}

+			>>

+		| L_BRACE reg_expr R_BRACE

+			<<

+/* MR23 */		if ($$.l != NULL) {

+					($$.l)->trans[0] = $2.l;

+					($$.l)->trans[1] = $$.r;

+			        if ($2.r) {

+    					($2.r)->trans[1] = $$.r;    /* MR20 */

+					}

+				}

+			>>

+		| atom

+			<<

+/* MR23 */		if ($$.l != NULL) {

+					($$.l)->trans[0] = $$.r;

+					($$.l)->label = set_dup($1.label);

+					set_orin(&used_chars,($$.l)->label);

+				}

+			>>

+		;

+

+atom_list	: << set_free($$.label); >>

+				(near_atom <<set_orin(&($$.label),$1.label);>>)*

+		;

+

+near_atom	: << register int i;

+		     register int i_prime;

+		  >>

+		  anychar

+			<<$$.letter=$1.letter; $$.label=set_of($1.letter);

+			i_prime = $1.letter + MIN_CHAR;

+			if (case_insensitive && islower(i_prime))

+				set_orel(toupper(i_prime)-MIN_CHAR,

+					&($$.label));

+			if (case_insensitive && isupper(i_prime))

+	 			set_orel(tolower(i_prime)-MIN_CHAR,

+					&($$.label));

+			>>

+			{ RANGE anychar

+				<< if (case_insensitive){

+					i_prime = $$.letter+MIN_CHAR;

+					$$.letter = (islower(i_prime) ?

+						toupper(i_prime) : i_prime)-MIN_CHAR;

+					i_prime = $2.letter+MIN_CHAR;

+					$2.letter = (islower(i_prime) ?

+						toupper(i_prime) : i_prime)-MIN_CHAR;

+				   }

+				   /* check to see if range okay */

+					{

+					    int debugLetter1 = $$.letter;

+						int debugLetter2 = $2.letter;

+					}

+				   if ($$.letter > $2.letter 

+                                       && $2.letter != 0xff){       /* MR16 */

+					  error("invalid range  ", zzline);

+				   }

+				   for (i=$$.letter; i<= (int)$2.letter; ++i){

+					set_orel(i,&($$.label));

+					i_prime = i+MIN_CHAR;

+					if (case_insensitive && islower(i_prime))

+						set_orel(toupper(i_prime)-MIN_CHAR,

+							&($$.label));

+					if (case_insensitive && isupper(i_prime))

+		 				set_orel(tolower(i_prime)-MIN_CHAR,

+							&($$.label));

+					}

+				>>

+			}

+		;

+

+atom		: << register int i_prime;>>

+		  anychar

+		  <<$$.label = set_of($1.letter);

+		    i_prime = $1.letter + MIN_CHAR;

+		    if (case_insensitive && islower(i_prime))

+			set_orel(toupper(i_prime)-MIN_CHAR,

+				&($$.label));

+		    if (case_insensitive && isupper(i_prime))

+	 		set_orel(tolower(i_prime)-MIN_CHAR,

+				&($$.label));

+		  >>

+		;

+

+anychar		: REGCHAR	<<$$.letter = $1.letter - MIN_CHAR;>>

+		| OCTAL_VALUE	<<$$.letter = $1.letter - MIN_CHAR;>>

+		| HEX_VALUE	<<$$.letter = $1.letter - MIN_CHAR;>>

+		| DEC_VALUE	<<$$.letter = $1.letter - MIN_CHAR;>>

+		| TAB		<<$$.letter = $1.letter - MIN_CHAR;>>

+		| NL		<<$$.letter = $1.letter - MIN_CHAR;>>

+		| CR		<<$$.letter = $1.letter - MIN_CHAR;>>

+		| BS		<<$$.letter = $1.letter - MIN_CHAR;>>

+		| LIT		<<$$.letter = $1.letter - MIN_CHAR;>>

+		/* NOTE: LEX_EOF is ALWAYS shifted to 0 = MIN_CHAR - MIN_CHAR*/

+		| L_EOF		<<$$.letter = 0;>>

+		;

+

+<</* empty action */>>

+

+#lexclass ACT

+#token "@"	<< error("unterminated action", zzline); zzmode(START); >>

+#token ACTION "\>\>"

+		<< if (func_action) fprintf(OUT,"}\n\n");

+		   zzmode(START);

+/* MR1									    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+/* MR1				via <<%%lexmember ...>>			    */

+/* MR1			This is a consequence of not saving actions         */

+/* MR1									    */

+/* MR1 */	   parserClass=0;		

+/* MR1 */	   lexPrefix=0;

+/* MR1 */	   lexAction=0;

+/* MR1 */	   lexMember=0;

+		>>

+#token "\>"		<< xxputc(zzlextext[0]); zzskip(); >>		/* MR1 */

+#token "\\\>"		<< xxputc('>'); zzskip(); >>			/* MR1 */

+#token "\\"		<< xxputc('\\'); zzskip(); >>			/* MR1 */

+#token "\n"		<< xxputc(zzlextext[0]); ++zzline; zzskip(); >>	/* MR1 */

+#token "/\*"		<< zzmode(ACTION_COMMENTS);			/* MR1 */

+			   xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+			>>						/* MR1 */

+#token "//"		<< zzmode(ACTION_CPP_COMMENTS);			/* MR1 */

+			   xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+			>>						/* MR1 */

+#token "~[]"		<< xxputc(zzlextext[0]); zzskip(); >>		/* MR1 */

+									/* MR1 */

+#lexclass ACTION_COMMENTS						/* MR1 */

+#token "\*/"		<< zzmode(ACT);					/* MR1 */

+			   xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+			>>						/* MR1 */

+#token "[\n\r]"		<< zzline++; xxputc(zzlextext[0]); zzskip();>>	/* MR1 */

+#token "~[]"		<< xxputc(zzlextext[0]); zzskip();>>		/* MR1 */

+									/* MR1 */

+#lexclass ACTION_CPP_COMMENTS						/* MR1 */

+#token "[\n\r]"		<< zzmode(ACT); zzline++;			/* MR1 */

+			   xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+			>>						/* MR1 */

+#token "~[]"		<< xxputc(zzlextext[0]); zzskip();>>		/* MR1 */

+

+<<

+/* adds a new nfa to the binary tree and returns a pointer to it */

+nfa_node *

+#ifdef __USE_PROTOS

+new_nfa_node(void)

+#else

+new_nfa_node()

+#endif

+{

+	register nfa_node *t;

+	static int nfa_size=0;	/* elements nfa_array[] can hold */

+

+	++nfa_allocated;

+	if (nfa_size<=nfa_allocated){

+		/* need to redo array */

+		if (!nfa_array){

+			/* need some to do inital allocation */

+			nfa_size=nfa_allocated+NFA_MIN;

+			nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)*

+				nfa_size);

+		}else{

+			/* need more space */

+			nfa_size=2*(nfa_allocated+1);

+			nfa_array=(nfa_node **) realloc(nfa_array,

+				sizeof(nfa_node*)*nfa_size);

+		}

+	}

+	/* fill out entry in array */

+	t = (nfa_node*) malloc(sizeof(nfa_node));

+	nfa_array[nfa_allocated] = t;

+	*t = nfa_model_node;

+	t->node_no = nfa_allocated;

+	return t;

+}

+

+

+/* initialize the model node used to fill in newly made nfa_nodes */

+void

+#ifdef __USE_PROTOS

+make_nfa_model_node(void)

+#else

+make_nfa_model_node()

+#endif

+{

+	nfa_model_node.node_no = -1; /* impossible value for real nfa node */

+	nfa_model_node.nfa_set = 0;

+	nfa_model_node.accept = 0;   /* error state default*/

+	nfa_model_node.trans[0] = NULL;

+	nfa_model_node.trans[1] = NULL;

+	nfa_model_node.label = empty;

+}

+>>

+

+<<

+#if defined(DEBUG) || defined(_DEBUG)

+

+/* print out the pointer value and the node_number */

+void

+#ifdef __USE_PROTOS

+fprint_dfa_pair(FILE *f, nfa_node *p)

+#else

+fprint_dfa_pair(f, p)

+FILE *f;

+nfa_node *p;

+#endif

+{

+	if (p){

+		fprintf(f, "%x (%d)", p, p->node_no);

+	}else{

+		fprintf(f, "(nil)");

+	}

+}

+

+/* print out interest information on a set */

+void

+#ifdef __USE_PROTOS

+fprint_set(FILE *f, set s)

+#else

+fprint_set(f,s)

+FILE *f;

+set s;

+#endif

+{

+	unsigned int *x;

+

+	fprintf(f, "n = %d,", s.n);

+	if (s.setword){

+		fprintf(f, "setword = %x,   ", s.setword);

+		/* print out all the elements in the set */

+		x = set_pdq(s);

+		while (*x!=nil){

+			fprintf(f, "%d ", *x);

+			++x;

+		}

+	}else{

+		fprintf(f, "setword = (nil)");

+	}

+}

+

+/* code to be able to dump out the nfas

+	return 0 if okay dump

+	return 1 if screwed up

+ */

+int

+#ifdef __USE_PROTOS

+dump_nfas(int first_node, int last_node)

+#else

+dump_nfas(first_node, last_node)

+int first_node;

+int last_node;

+#endif

+{

+	register int i;

+	nfa_node *t;

+

+	for (i=first_node; i<=last_node; ++i){

+		t = NFA(i);

+		if (!t) break;

+		fprintf(stderr, "nfa_node %d {\n", t->node_no);

+		fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set);

+		fprintf(stderr, "\taccept\t=\t%d\n", t->accept);

+		fprintf(stderr, "\ttrans\t=\t(");

+		fprint_dfa_pair(stderr, t->trans[0]);

+		fprintf(stderr, ",");

+		fprint_dfa_pair(stderr, t->trans[1]);

+		fprintf(stderr, ")\n");

+		fprintf(stderr, "\tlabel\t=\t{ ");

+		fprint_set(stderr, t->label);

+		fprintf(stderr, "\t}\n");

+		fprintf(stderr, "}\n\n");

+	}

+	return 0;

+}

+#endif

+>>

+

+<<

+/* DLG-specific syntax error message generator

+ * (define USER_ZZSYN when compiling so don't get 2 definitions)

+ */

+void

+#ifdef __USE_PROTOS

+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)

+#else

+zzsyn(text, tok, egroup, eset, etok, k, bad_text)

+char *text, *egroup, *bad_text;

+int tok;

+int etok;

+int k;

+SetWordType *eset;

+#endif

+{

+	fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline);

+	fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);

+	if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}

+	if ( k==1 ) fprintf(stderr, " missing");

+	else

+	{

+		fprintf(stderr, "; \"%s\" not", bad_text);

+		if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");

+	}

+	if ( zzset_deg(eset)>0 ) zzedecode(eset);

+	else fprintf(stderr, " %s", zztokens[etok]);

+	if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);

+	fprintf(stderr, "\n");

+}

+>>

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/err.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/err.c
new file mode 100644
index 0000000..c3eaeae
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/err.c
@@ -0,0 +1,99 @@
+/*

+ * A n t l r  S e t s / E r r o r  F i l e  H e a d e r

+ *

+ * Generated from: dlg_p.g

+ *

+ * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001

+ * Parr Research Corporation

+ * with Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include <ctype.h>

+#include "dlg.h"

+#define zzSET_SIZE 8

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+#include "err.h"

+

+ANTLRChar *zztokens[46]={

+	/* 00 */	"Invalid",

+	/* 01 */	"@",

+	/* 02 */	"[\\r\\t\\ ]+",

+	/* 03 */	"\\n",

+	/* 04 */	"L_EOF",

+	/* 05 */	"PER_PER",

+	/* 06 */	"NAME_PER_PER",

+	/* 07 */	"LEXMEMBER",

+	/* 08 */	"LEXACTION",

+	/* 09 */	"PARSERCLASS",

+	/* 10 */	"LEXPREFIX",

+	/* 11 */	"ACTION",

+	/* 12 */	"GREAT_GREAT",

+	/* 13 */	"L_BRACE",

+	/* 14 */	"R_BRACE",

+	/* 15 */	"L_PAR",

+	/* 16 */	"R_PAR",

+	/* 17 */	"L_BRACK",

+	/* 18 */	"R_BRACK",

+	/* 19 */	"ZERO_MORE",

+	/* 20 */	"ONE_MORE",

+	/* 21 */	"OR",

+	/* 22 */	"RANGE",

+	/* 23 */	"NOT",

+	/* 24 */	"OCTAL_VALUE",

+	/* 25 */	"HEX_VALUE",

+	/* 26 */	"DEC_VALUE",

+	/* 27 */	"TAB",

+	/* 28 */	"NL",

+	/* 29 */	"CR",

+	/* 30 */	"BS",

+	/* 31 */	"CONTINUATION",

+	/* 32 */	"LIT",

+	/* 33 */	"REGCHAR",

+	/* 34 */	"\\>",

+	/* 35 */	"\\\\>",

+	/* 36 */	"\\",

+	/* 37 */	"\\n",

+	/* 38 */	"/\\*",

+	/* 39 */	"//",

+	/* 40 */	"~[]",

+	/* 41 */	"\\*/",

+	/* 42 */	"[\\n\\r]",

+	/* 43 */	"~[]",

+	/* 44 */	"[\\n\\r]",

+	/* 45 */	"~[]"

+};

+SetWordType zzerr1[8] = {0x80,0xf,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr2[8] = {0x60,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};

+SetWordType zzerr3[8] = {0x70,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType setwd1[46] = {0x0,0x6,0x0,0x0,0x30,0xc8,0xc8,

+	0x1,0x1,0x1,0x1,0x35,0x0,0x30,0x0,

+	0x30,0x0,0x30,0x0,0x30,0x30,0x0,0x0,

+	0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,

+	0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr4[8] = {0x10,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType zzerr5[8] = {0x10,0xe8,0xbb,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType zzerr6[8] = {0x10,0xa0,0x9a,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType setwd2[46] = {0x0,0x0,0x0,0x0,0xeb,0x2,0x2,

+	0x0,0x0,0x0,0x0,0xd6,0x0,0xeb,0xd4,

+	0xeb,0xd4,0xeb,0x0,0xcb,0xcb,0xd0,0x0,

+	0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,

+	0x0,0xeb,0xeb,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0};

+SetWordType zzerr7[8] = {0x10,0xa0,0x82,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType zzerr8[8] = {0x10,0x0,0x44,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType zzerr9[8] = {0x10,0x0,0x0,0x7f, 0x3,0x0,0x0,0x0};

+SetWordType setwd3[46] = {0x0,0x0,0x0,0x0,0xf7,0x0,0x0,

+	0x0,0x0,0x0,0x0,0xc2,0x0,0xc2,0xc2,

+	0xc2,0xc2,0xc2,0xb8,0xc2,0xc2,0xc2,0x80,

+	0xc2,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,

+	0x0,0xf7,0xf7,0x0,0x0,0x0,0x0,0x0,

+	0x0,0x0,0x0,0x0,0x0,0x0,0x0};

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/main.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/main.c
new file mode 100644
index 0000000..35bd827
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/main.c
@@ -0,0 +1,281 @@
+/* Main function for dlg version

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "stdpccts.h"

+

+char	program[] = "dlg";

+char	version[] = "1.33MR33";					/* MRXXX */

+int	numfiles = 0;

+char	*file_str[2] = {NULL, NULL};

+char	*mode_file = "mode.h";

+char	*class_name = DEFAULT_CLASSNAME;

+char	*OutputDirectory = TopDirectory;

+

+/* Option variables */

+int comp_level = 0;

+int interactive = FALSE;

+int case_insensitive = FALSE;

+int warn_ambig = FALSE;

+int gen_cpp = FALSE;

+

+#ifdef __USE_PROTOS

+static int ci_strequ(char *a,char *b)

+#else

+static int ci_strequ(a,b)

+  char  *a;

+  char  *b;

+#endif

+{

+  for ( ;*a != 0 && *b != 0; a++, b++) {

+    if (toupper(*a) != toupper(*b)) return 0;

+  }

+  return (*a == *b);

+}

+

+/* Option List Stuff */

+#ifdef __USE_PROTOS

+void p_comp0(void)		{comp_level = 0;}

+void p_comp1(void)		{comp_level = 1;}

+void p_comp2(void)		{comp_level = 2;}

+void p_stdio(void)		{ file_str[numfiles++] = NULL;}

+void p_file(char *s) 	{ file_str[numfiles++] = s;}

+void p_cl_name(char *s, char *t)

+	{

+		if ( gen_cpp ) {

+			class_name = t;

+		}

+		else {

+			warning("-cl only valid in C++ mode; -cl ignored...",0);

+		}

+	}

+void p_mode_file(char *s, char *t){mode_file=t;}

+void p_outdir(char *s,char *t) {OutputDirectory=t;}

+void p_ansi(void)		{gen_ansi = TRUE;}

+void p_interactive(void)	{interactive = TRUE;}

+void p_case_s(void)		{ case_insensitive = FALSE; }

+void p_case_i(void)		{ case_insensitive = TRUE; }

+void p_warn_ambig(void)	{ warn_ambig = TRUE; }

+void p_cpp(void)		{ gen_cpp = TRUE; }

+#else

+void p_comp0()		{comp_level = 0;}

+void p_comp1()		{comp_level = 1;}

+void p_comp2()		{comp_level = 2;}

+void p_stdio()		{ file_str[numfiles++] = NULL;}

+void p_file(s) char *s;	{ file_str[numfiles++] = s;}

+void p_cl_name(s,t)

+	char *s, *t;

+	{

+		if ( gen_cpp ) {

+			class_name = t;

+		}

+		else {

+			warning("-cl only valid in C++ mode; -cl ignored...",0);

+		}

+	}

+void p_mode_file(s,t) char *s,*t;{mode_file=t;}

+void p_outdir(s,t) char *s,*t;{OutputDirectory=t;}

+void p_ansi()		{gen_ansi = TRUE;}

+void p_interactive()	{interactive = TRUE;}

+void p_case_s()		{ case_insensitive = FALSE; }

+void p_case_i()		{ case_insensitive = TRUE; }

+void p_warn_ambig()	{ warn_ambig = TRUE; }

+void p_cpp()		{ gen_cpp = TRUE; }

+#endif

+

+#ifdef __cplusplus

+typedef void (*WildFunc)(...);

+#else

+typedef void (*WildFunc)();

+#endif

+

+typedef struct {

+			char *option;

+			int  arg;

+			WildFunc process;

+			char *descr;

+		} Opt;

+

+Opt options[] = {

+	{ "-CC", 0, (WildFunc)p_cpp, "Generate C++ output" },

+	{ "-C0", 0, (WildFunc)p_comp0, "No compression (default)" },

+	{ "-C1", 0, (WildFunc)p_comp1, "Compression level 1" },

+	{ "-C2", 0, (WildFunc)p_comp2, "Compression level 2" },

+	{ "-ga", 0, (WildFunc)p_ansi, "Generate ansi C"},

+	{ "-Wambiguity", 0, (WildFunc)p_warn_ambig, "Warn if expressions ambiguous"},

+	{ "-m", 1, (WildFunc)p_mode_file, "Rename lexical mode output file"},

+	{ "-i", 0, (WildFunc)p_interactive, "Build interactive scanner (not valid for C++ mode)"},

+	{ "-ci", 0, (WildFunc)p_case_i, "Make lexical analyzer case insensitive"},

+	{ "-cl", 1, (WildFunc)p_cl_name, "Rename lexer class (DLGLexer); only used for -CC"},

+	{ "-cs", 0, (WildFunc)p_case_s, "Make lexical analyzer case sensitive (default)"},

+	{ "-o",  1, (WildFunc)p_outdir, OutputDirectoryOption},

+	{ "-", 0, (WildFunc)p_stdio, "Use standard i/o rather than file"},

+	{ "*", 0, (WildFunc)p_file, ""}, /* anything else is a file */

+	{ NULL, 0, NULL }	

+ };

+

+#ifdef __USE_PROTOS

+void ProcessArgs(int argc, char **argv, Opt *options)

+#else

+void ProcessArgs(argc, argv, options)

+int argc;

+char **argv;

+Opt *options;

+#endif

+{

+	Opt *p;

+	

+	while ( argc-- > 0 )

+	{

+		p = options;

+		while ( p->option != NULL )

+		{

+			if ( strcmp(p->option, "*") == 0 ||

+				 ci_strequ(p->option,*argv) )

+			{

+				if ( p->arg )

+				{

+					(*p->process)( *argv, *(argv+1) );

+					argv++;

+					argc--;

+				}

+				else

+					(*p->process)( *argv );

+				break;

+			}

+			p++;

+		}

+		argv++;

+	}

+}

+

+#ifdef __USE_PROTOS

+int main(int argc, char *argv[])

+#else

+int main(argc, argv)

+int argc;

+char *argv[];

+#endif

+{

+	init();

+	fprintf(stderr, "%s  Version %s   1989-2001\n", &(program[0]),

+		&(version[0]));

+	if ( argc == 1 )

+	{

+		Opt *p = options;

+		fprintf(stderr, "%s [options] f1 f2 ... fn\n",argv[0]);

+		while ( *(p->option) != '*' )

+		{

+			fprintf(stderr, "\t%s %s\t%s\n",

+							p->option,

+							(p->arg)?"___":"   ",

+							p->descr);

+			p++;

+		}

+	}else{

+		ProcessArgs(argc-1, &(argv[1]), options);

+		if (interactive && gen_cpp) {

+			fprintf(stderr,"\n");

+/***  MR21a This statement is wrong ! ***/

+#if 0

+***			fprintf(stderr,"Interactive lexer option (\"-i\") has no effect when in C++ mode\n");

+***			fprintf(stderr,"because of extra buffering provided by ANTLRTokenBuffer class.\n");

+***			fprintf(stderr,"\n");

+#endif

+		}

+		input_stream = read_stream(file_str[0]);

+		if (input_stream) {

+			/* don't overwrite unless input okay */

+			if ( gen_cpp ) {

+				output_stream = write_stream(ClassName(CPP_FILE_SUFFIX));

+				if ( file_str[1]!=NULL ) {

+					warning("output file implicit in C++ mode; ignored...",0);

+				}

+				class_stream = write_stream(ClassName(".h"));

+				mode_stream = class_stream;

+			}

+			else {

+				output_stream = write_stream(file_str[1]);

+				mode_stream = write_stream(mode_file);

+			}

+		}

+		/* make sure that error reporting routines in grammar

+		   know what the file really is */

+		/* make sure that reading and writing somewhere */

+		if (input_stream && output_stream && mode_stream){

+			ANTLR(grammar(), input_stream);

+		}

+		p_class_def2();			/* MR1 */

+	}

+	if ( output_stream!=NULL ) fclose(output_stream);

+	if ( !gen_cpp && mode_stream!=NULL ) fclose(mode_stream);

+	if ( class_stream!=NULL ) fclose(class_stream);

+	exit(PCCTS_EXIT_SUCCESS);

+	return 0;		/* get rid of warning message MR1 */

+}

+

+/* initialize all the variables */

+void 

+#ifdef __USE_PROTOS

+init(void)

+#else

+init()

+#endif

+{

+	register int i;

+

+#ifdef SPECIAL_INITS

+	special_inits();					/* MR1 */

+#endif

+	used_chars = empty;

+	used_classes = empty;

+	/* make the valid character set */

+	normal_chars = empty;

+	/* NOTE: MIN_CHAR is EOF */

+	/* NOTE: EOF is not quite a valid char, it is special. Skip it*/

+	for (i = 1; i<CHAR_RANGE; ++i){

+		set_orel(i,&normal_chars);

+	}

+	make_nfa_model_node();

+	clear_hash();

+	/* NOTE: need to set this flag before the lexer starts getting */

+	/* tokens */

+   	func_action = FALSE;	

+}

+

+/* stuff that needs to be reset when a new automaton is being built */

+void 

+#ifdef __USE_PROTOS

+new_automaton_mode(void)					/* MR1 */

+#else

+new_automaton_mode()					/* MR1 */

+#endif

+{

+	set_free(used_chars);

+	clear_hash();

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/makefile b/edk2/Tools/Source/TianoTools/Pccts/dlg/makefile
new file mode 100644
index 0000000..1658394
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/makefile
@@ -0,0 +1,156 @@
+#

+# Makefile for DLG 1.33

+# Terence Parr

+# Purdue University, U of MN, Parr Research Corporation

+# 1989-1994

+#

+# Ported to IBM C-Set/2 and Microsoft 6.0 by

+# Ed Harfmann

+# Micro Data Base Systems

+# Lafayette, Indiana

+#

+SET=../support/set

+PCCTS_H=../h

+

+##

+## Uncomment the appropriate section to build

+##

+

+#

+#   OS/2 & DOS 16 bit using MSC 6.0

+#

+#CC=cl

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN

+#OUT_OBJ = -Fo

+#LIBS=/NOD:LLIBCE LLIBCEP

+#OBJ_EXT = obj

+#

+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \

+#        output.obj relabel.obj automata.obj

+#        link @<<

+#$** /NOI

+#$@ /STACK:16384

+#

+#$(LIBS: = +^

+#)

+#$(DEF_FILE) $(LFLAGS) ;

+#<<

+#        bind $@ c:\os2\doscalls.lib

+#        copy *.exe ..\bin

+#

+

+#

+#   Borland C++ for DOS

+#

+#CC=bcc

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN

+#OUT_OBJ = -o

+#LIBS= emu mathl cl

+#OBJ_EXT = obj

+#

+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \

+#        output.obj relabel.obj automata.obj

+#       tlink @&&|

+#C0L $**

+#$@ /Tde /c

+#

+#$(LIBS)

+#$(DEF_FILE) $(LFLAGS) ;

+#|

+#        copy *.exe ..\bin

+#

+

+#

+# C-Set/2 for OS/2

+#

+#CC=icc

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 /DUSER_ZZSYN

+#OUT_OBJ = -Fo

+#LIBS=

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#OBJ_EXT=obj

+#

+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \

+#        output.obj relabel.obj automata.obj

+#        link386 @<<

+#$** /NOI

+#$@ /STACK:32768

+#

+#$(LIBS: = +^

+#)

+#$(DEF_FILE) $(LFLAGS) ;

+#<<

+#        copy *.exe ..\bin

+#

+

+#

+# Borland C++ for OS/2

+#

+#CC=bcc

+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -DUSER_ZZSYN

+#OUT_OBJ = -o

+#LIBS= c2 os2

+#

+#ANTLR=..\bin\antlr

+#DLG=..\bin\dlg

+#OBJ_EXT = obj

+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \

+#        output.obj relabel.obj automata.obj

+#        tlink @&&|

+#c02 $** -c

+#dlg.exe

+#

+#C2 os2

+#

+#|

+#        copy *.exe ..\bin

+#

+

+#

+#   UNIX

+#

+CC=cc

+COPT=-O

+ANTLR=../bin/antlr

+DLG=../bin/dlg

+CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -DZZLEXBUFSIZE=65536

+OBJ_EXT=o

+OUT_OBJ = -o

+OBJ = dlg_p.o dlg_a.o main.o err.o set.o support.o output.o \

+        relabel.o automata.o

+

+dlg : $(OBJ) $(SRC)

+		$(CC) $(CFLAGS) -o ${WORKSPACE}/Tools/bin/dlg $(OBJ)

+

+SRC = dlg_p.c dlg_a.c main.c err.c $(SET)/set.c support.c output.c \

+        relabel.c automata.c

+

+#dlg_p.c parser.dlg err.c tokens.h : dlg_p.g

+#	$(ANTLR) dlg_p.g

+

+#dlg_a.c mode.h : parser.dlg

+#	$(DLG) -C2 parser.dlg dlg_a.c

+

+dlg_p.$(OBJ_EXT) : dlg_p.c dlg.h tokens.h mode.h

+	$(CC) $(CFLAGS) -c dlg_p.c

+

+dlg_a.$(OBJ_EXT) : dlg_a.c dlg.h tokens.h mode.h

+	$(CC) $(CFLAGS) -c dlg_a.c

+

+main.$(OBJ_EXT) : main.c dlg.h

+	$(CC) $(CFLAGS) -c main.c

+

+set.$(OBJ_EXT) : $(SET)/set.c

+	$(CC) -c $(CFLAGS) $(SET)/set.c

+

+lint:

+	lint *.c

+

+#clean up all the intermediate files

+clean:

+	rm -f *.$(OBJ_EXT) core

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/makefile1 b/edk2/Tools/Source/TianoTools/Pccts/dlg/makefile1
new file mode 100644
index 0000000..4d00f79
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/makefile1
@@ -0,0 +1,63 @@
+#

+# Makefile for DLG 1.33

+# Terence Parr

+# Purdue University, U of MN, Parr Research Corporation

+# 1989-1994

+#

+# Ported to IBM C-Set/2 and Microsoft 6.0 by

+# Ed Harfmann

+# Micro Data Base Systems

+# Lafayette, Indiana

+#

+SET=../support/set

+PCCTS_H=../h

+

+##

+## Uncomment the appropriate section to build

+##

+

+

+#

+#   UNIX

+#

+CC=cc

+ANTLR=../bin/antlr

+DLG=../bin/dlg

+ANSI=-ansi

+CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) $(ANSI) -DZZLEXBUFSIZE=32000

+OBJ_EXT=o

+OUT_OBJ = -o

+OBJ = dlg_p.o dlg_a.o main.o err.o set.o support.o output.o \

+        relabel.o automata.o

+

+dlg : $(OBJ) $(SRC)

+		$(CC) $(CFLAGS) -o dlg $(OBJ)

+		mv dlg ../bin

+

+SRC = dlg_p.c dlg_a.c main.c err.c $(SET)/set.c support.c output.c \

+        relabel.c automata.c

+

+dlg_p.c parser.dlg err.c tokens.h : dlg_p.g

+	$(ANTLR) dlg_p.g

+

+dlg_a.c mode.h : parser.dlg

+	$(DLG) -C2 parser.dlg dlg_a.c

+

+dlg_p.$(OBJ_EXT) : dlg_p.c dlg.h tokens.h mode.h

+	$(CC) $(CFLAGS) -c dlg_p.c

+

+dlg_a.$(OBJ_EXT) : dlg_a.c dlg.h tokens.h mode.h

+	$(CC) $(CFLAGS) -c dlg_a.c

+

+main.$(OBJ_EXT) : main.c dlg.h

+	$(CC) $(CFLAGS) -c main.c

+

+set.$(OBJ_EXT) : $(SET)/set.c

+	$(CC) -c $(CFLAGS) $(SET)/set.c

+

+lint:

+	lint *.c

+

+#clean up all the intermediate files

+clean:

+	rm -f *.$(OBJ_EXT) core

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/mode.h b/edk2/Tools/Source/TianoTools/Pccts/dlg/mode.h
new file mode 100644
index 0000000..3f3279e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/mode.h
@@ -0,0 +1,4 @@
+#define START 0

+#define ACT 1

+#define ACTION_COMMENTS 2

+#define ACTION_CPP_COMMENTS 3

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/output.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/output.c
new file mode 100644
index 0000000..2e56a6d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/output.c
@@ -0,0 +1,850 @@
+/* output.c, output generator for dlg

+ *

+ * Output Notes:

+ *

+ * DfaStates == number of dfa nodes in automaton (just a #define)

+ * DfaState == type large enough to index every node in automaton

+ *         <256 unsigned char, <65536 unsigned short, etc.

+ *

+ * Thus, the elements in each of the automaton states (st%d) are type DfaState

+ * and are size appropriately, since they must be able to index the next

+ * automaton state.

+ *

+ * dfa[] == a linear array that points to all the automaton states (st%d)

+ *         (dfa_base[] should be the same, but isn't right now)

+ *

+ * accepts[] == Taking a closer look at this one, it probably shouldn't be type

+ *         DfaState because there is no real requirement that the number of

+ *         accepts states is less than the number of dfa state.  However, if

+ *         the number of accept states was more than the number of DFA states

+ *         then the lexical specification would be really ambiguous.

+ *

+ *         Another note. Is that is should be possible to fold accepts[] and

+ *         actions[] together.  If this is done, I would suggest get rid of

+ *         accept[] and make actions[] have an entry for each state (st%d) in

+ *         the automaton.

+ *

+ * dfa_base[] == starting location for each lexical mode.  This should be

+ *         Dfastate type (but isn't right now), since it points to the states

+ *         in the automaton.

+ *

+ * dfa_class_no[] == indicates the number of columns each lexical mode has.

+ *

+ * b_class_no[] == pointer to the start of the translation array used to

+ *         convert from input character to character class.  This could cause

+ *         problems if there are more than 256 classes

+ *

+ * shift%d[] == the actual translation arrays that convert the input character

+ *         into the character class.  These will have to change if there are

+ *         more than 256 character classes.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <string.h>

+#include "dlg.h"

+#ifdef MEMCHK

+#include "trax.h"

+#else

+#ifdef __STDC__

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif /* __STDC__ */

+#endif

+

+static char *mode_name[MAX_MODES];

+static int mode_number[MAX_MODES];

+static int cur_mode=0;

+

+int operation_no = 0; /* used to mark nodes so that infinite loops avoided */

+int dfa_basep[MAX_MODES]; 	/* start of each group of states */

+int dfa_class_nop[MAX_MODES];	/* number of elements in each group of states*/

+

+int gen_ansi = FALSE;		/* allows ansi code to be generated */

+

+FILE *input_stream;	/* where to read description from */

+FILE *output_stream;	/* where to put the output	  */

+FILE *mode_stream;	/* where to put the mode.h stuff */

+FILE *class_stream;	/* where to put the scan.h stuff (if gen_cpp) */

+

+/* NOTE: This section is MACHINE DEPENDENT */

+#define DIF_SIZE 4

+#if defined(PC) && !defined(PC32)

+unsigned long typesize[DIF_SIZE]  = { 0x7f, 0x7fff, 0x7ffful, 0x7ffffffful }; /* MR20 */

+char t0[] = "unsigned char";

+char t1[] = "unsigned short";

+char t2[] = "unsigned int";

+char t3[] = "unsigned long";

+char *typevar[DIF_SIZE] = { t0, t1, t2, t3};

+#else

+unsigned long typesize[DIF_SIZE]  = { 0x7f, 0x7fff, 0x7ffffffful, 0x7ffffffful }; /* MR20 */

+char t0[] = "unsigned char";

+char t1[] = "unsigned short";

+char t2[] = "unsigned int";

+char t3[] = "unsigned long";

+char *typevar[DIF_SIZE] = { t0, t1, t2, t3};

+#endif

+

+/* Added by TJP August 1994 */

+/* Take in MyLexer and return MyLexer_h */

+

+static char *

+#ifdef __USE_PROTOS

+gate_symbol(char *name)

+#else

+gate_symbol(name)

+char *name;

+#endif

+{

+	static char buf[100];

+	sprintf(buf, "%s_h", name);

+	return buf;

+}

+

+/* Added by TJP August 1994 */

+static char *

+#ifdef __USE_PROTOS

+mystrdup(char *s)

+#else

+mystrdup(s)

+char *s;

+#endif

+{

+	char *p = (char *)malloc(strlen(s)+1);

+	strcpy(p, s);

+	return p;

+}

+

+#ifdef __USE_PROTOS

+void p_class_hdr(void)

+#else

+void p_class_hdr()						

+#endif

+{

+	if ( class_stream == NULL ) return;

+	fprintf(class_stream, "#ifndef %s\n", gate_symbol(ClassName("")));

+	fprintf(class_stream, "#define %s\n", gate_symbol(ClassName("")));

+	fprintf(class_stream, "/*\n");

+	fprintf(class_stream, " * D L G L e x e r  C l a s s  D e f i n i t i o n\n");

+	fprintf(class_stream, " *\n");

+	fprintf(class_stream, " * Generated from:");

+	fprintf(class_stream, " %s", file_str[0]);

+	fprintf(class_stream, "\n");

+	fprintf(class_stream, " *\n");

+	fprintf(class_stream, " * 1989-2001 by  Will Cohen, Terence Parr, and Hank Dietz\n");

+	fprintf(class_stream, " * Purdue University Electrical Engineering\n");

+	fprintf(class_stream, " * DLG Version %s\n", version);

+	fprintf(class_stream, " */\n\n");

+	fprintf(class_stream, "\n");

+	fprintf(class_stream, "#include \"%s\"\n", DLEXERBASE_H);

+}

+

+/* MR1									*/

+/* MR1 16-Apr-97  Split printing of class header up into several parts  */

+/* MR1		    so that #lexprefix <<...>>and #lexmember <<...>>	*/

+/* MR1		    can be inserted in the appropriate spots		*/

+/* MR1									*/

+

+#ifdef __USE_PROTOS

+void p_class_def1(void)

+#else

+void p_class_def1()

+#endif

+{

+	if ( class_stream == NULL ) return;

+	fprintf(class_stream, "\nclass %s : public DLGLexerBase {\n", ClassName(""));

+	fprintf(class_stream, "public:\n");

+}

+

+#ifdef __USE_PROTOS

+void p_class_def2(void)

+#else

+void p_class_def2()

+#endif

+{

+	int i, m;

+	if ( class_stream == NULL ) return;

+	fprintf(class_stream, "public:\n");

+	fprintf(class_stream, "\tstatic const int MAX_MODE;\n");

+	fprintf(class_stream, "\tstatic const int DfaStates;\n");

+	for (i=0; i<cur_mode; i++) {

+		fprintf(class_stream, "\tstatic const int %s;\n", mode_name[i]);

+	}

+

+	fprintf(class_stream, "\ttypedef %s DfaState;\n\n", minsize(dfa_allocated));

+	fprintf(class_stream, "\t%s(DLGInputStream *in,\n",ClassName(""));

+	fprintf(class_stream, "\t\tunsigned bufsize=2000)\n");

+	fprintf(class_stream, "\t\t: DLGLexerBase(in, bufsize, %d)\n", interactive);

+	fprintf(class_stream, "\t{\n");

+	fprintf(class_stream, "\t;\n");

+	fprintf(class_stream, "\t}\n");

+	fprintf(class_stream, "\tvoid	  mode(int);\n");

+	fprintf(class_stream, "\tANTLRTokenType nextTokenType(void);\n");

+	fprintf(class_stream, "\tvoid     advance(void);\n");

+	fprintf(class_stream, "protected:\n");

+	for (i=1; i<=action_no; ++i) {

+		fprintf(class_stream, "\tANTLRTokenType act%d();\n", i);

+	}

+

+	for(m=0; m<(mode_counter-1); ++m){

+		for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)

+			fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);

+	}

+	for(i=dfa_basep[m]; i<=dfa_allocated; ++i)

+		fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);

+

+	fprintf(class_stream, "\tstatic DfaState *dfa[%d];\n", dfa_allocated);

+	fprintf(class_stream, "\tstatic DfaState dfa_base[];\n");

+/*	fprintf(class_stream, "\tstatic int dfa_base_no[];\n"); */

+	fprintf(class_stream, "\tstatic unsigned char *b_class_no[];\n");

+	fprintf(class_stream, "\tstatic DfaState accepts[%d];\n",dfa_allocated+1);

+	fprintf(class_stream, "\tstatic DLGChar alternatives[%d];\n",dfa_allocated+1);

+	/* WARNING: should be ANTLRTokenType for action table, but g++ 2.5.6 is hosed */

+	fprintf(class_stream, "\tstatic ANTLRTokenType (%s::*actions[%d])();\n", ClassName(""), action_no+1);

+	for(m=0; m<mode_counter; ++m) {

+		fprintf(class_stream, "\tstatic unsigned char shift%d[%d];\n",

+			m, CHAR_RANGE);

+	}

+	if (comp_level)

+		fprintf(class_stream, "\tint ZZSHIFT(int c) { return b_class_no[automaton][1+c]; }\n");

+	else

+		fprintf(class_stream, "\tint ZZSHIFT(int c) { return 1+c; }\n");

+

+/* MR1									  */

+/* MR1 11-APr-97   Kludge to allow inclusion of user-defined code in	  */

+/* MR1			 DLGLexer class header				  */

+/* MR1		   Deprecated in favor of 133MR1 addition #lexmember <<>> */

+/* MR1									  */

+/* MR1 */	fprintf(class_stream,"//\n");

+/* MR1 */	fprintf(class_stream,

+/* MR1 */	   "// 133MR1 Deprecated feature to allow inclusion of ");

+/* MR1 */	fprintf(class_stream,

+/* MR1 */	   "user-defined code in DLG class header\n");

+/* MR1 */	fprintf(class_stream,"//\n");

+/* MR1 */

+/* MR1 */	fprintf(class_stream,"#ifdef DLGLexerIncludeFile\n");

+/* MR1 */	fprintf(class_stream,"#include DLGLexerIncludeFile\n");

+/* MR1 */	fprintf(class_stream,"#endif\n");

+

+	fprintf(class_stream, "};\n");

+

+	fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n",

+			ClassName(""), ClassName(""));

+

+	fprintf(class_stream, "#endif\n");

+}

+

+/* generate required header on output */

+

+#ifdef __USE_PROTOS

+void p_head(void)

+#else

+void p_head()

+#endif

+{

+	fprintf(OUT, "/*\n");

+	fprintf(OUT, " * D L G tables\n");

+	fprintf(OUT, " *\n");

+	fprintf(OUT, " * Generated from:");

+	fprintf(OUT, " %s", file_str[0]);

+	fprintf(OUT, "\n");

+	fprintf(OUT, " *\n");

+	fprintf(OUT, " * 1989-2001 by  Will Cohen, Terence Parr, and Hank Dietz\n");

+	fprintf(OUT, " * Purdue University Electrical Engineering\n");

+	fprintf(OUT, " * DLG Version %s\n", version);

+	fprintf(OUT, " */\n\n");

+	if ( gen_cpp)  fprintf(OUT, "#include \"pcctscfg.h\"\n");

+	if ( gen_cpp ) fprintf(OUT, "#include \"pccts_stdio.h\"\n");

+	if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file);

+	fprintf(OUT,"\n");

+}

+

+#ifdef __USE_PROTOS

+void p_includes(void)

+#else

+void p_includes()

+#endif

+{

+	fprintf(OUT, "#include \"%s\"\n", APARSER_H);

+	fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H);

+	fprintf(OUT, "#include \"%s\"\n", ClassName(".h"));

+}

+

+/* generate code to tie up any loose ends */

+

+#ifdef __USE_PROTOS

+void p_tail(void)   				/* MR1 */

+#else

+void p_tail()						/* MR1 */

+#endif

+{

+	if ( gen_cpp ) {

+		if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 )

+			fprintf(OUT, "#define DLGLexer %s\n", ClassName(""));

+		fprintf(OUT, "#include \"%s\"\n", DLEXER_H);  /* MR23 Rename DLexer.cpp to DLexer.h */

+		return;

+	}

+	fprintf(OUT, "\n");

+	fprintf(OUT, "\n");

+	if (comp_level)

+		fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n");

+	else

+		fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n");

+	if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter);

+	fprintf(OUT, "#include \"dlgauto.h\"\n");

+}

+

+

+/* output the table of DFA for general use */

+

+#ifdef __USE_PROTOS

+void p_tables()

+#else

+void p_tables()

+#endif

+{

+	if ( !gen_cpp ) {

+		fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated);

+		fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated));

+	}

+

+	if ( gen_cpp ) {

+		int i;

+		fprintf(OUT, "\n");

+		fprintf(OUT, "const int %s::MAX_MODE=%d;\n",

+				ClassName(""),

+				mode_counter);

+		fprintf(OUT, "const int %s::DfaStates=%d;\n",

+				ClassName(""),

+				dfa_allocated);

+		for (i=0; i<cur_mode; i++) {

+			fprintf(OUT, "const int %s::%s=%d;\n",

+					ClassName(""), mode_name[i], mode_number[i]);

+		}

+		fprintf(OUT, "\n");

+	}

+

+	p_node_table();

+	p_dfa_table();

+	p_accept_table();

+	p_action_table();

+	p_base_table();

+	p_class_table();

+	if (comp_level)

+		p_bshift_table();

+	if (interactive || gen_cpp )

+		p_alternative_table();

+}

+

+

+/* figures out the smallest variable type that will hold the transitions

+ */

+

+#ifdef __USE_PROTOS

+char *minsize(int elements)

+#else

+char *minsize(elements)

+int elements;

+#endif

+{

+	int i = 0;

+

+	while ((unsigned long) elements > typesize[i]) /* MR20 */

+		++i;

+	return typevar[i];

+}

+

+

+#ifdef __USE_PROTOS

+void p_node_table(void)

+#else

+void p_node_table()

+#endif

+{

+	register int	i;

+	register int	m = 0;

+

+	for(m=0; m<(mode_counter-1); ++m){

+		for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)

+			p_single_node(i,dfa_class_nop[m]);

+	}

+	for(i=dfa_basep[m]; i<=dfa_allocated; ++i)

+		p_single_node(i,dfa_class_nop[m]);

+}

+

+

+#ifdef __USE_PROTOS

+void p_single_node(int i,int classes)

+#else

+void p_single_node(i,classes)

+int i,classes;

+#endif

+{

+	register int	j;

+	register int	trans, items_on_line;

+

+#if 1

+	/* extra state (classes+1) for invalid characters */

+	fprintf(OUT, "%sDfaState %sst%d[%d] = {\n  ",

+		gen_cpp?ClassName("::"):"static ",

+		gen_cpp?ClassName("::"):"",(i-1), (classes+1));

+#else

+	fprintf(OUT, "static DfaState st%d[%d] = {\n  ", (i-1), classes);

+#endif

+	items_on_line = MAX_ON_LINE;

+	for(j=0; j<classes; ++j){

+		DAWDLE;

+		trans = DFA(i)->trans[j];

+		if (trans == NIL_INDEX)

+			trans = dfa_allocated+1;

+		/* all of DFA moved down one in array */

+		fprintf(OUT, "%d", trans-1);

+		fprintf(OUT, ", ");

+		if (!(--items_on_line)){

+			fprintf(OUT, "\n  ");

+			items_on_line = MAX_ON_LINE;

+		}

+	}

+#if 1

+	/* put in jump to error state */

+	fprintf(OUT, "%d\n};\n\n", dfa_allocated);

+#else

+	fprintf(OUT, "\n};\n\n");

+#endif

+}

+

+

+#ifdef __USE_PROTOS

+void p_dfa_table(void)

+#else

+void p_dfa_table()

+#endif

+{

+	register int	i;

+

+	fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n",

+		gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated);

+	for (i=0; i<(dfa_allocated-1); ++i){

+		fprintf(OUT, "\tst%d,\n", i);

+	}

+	fprintf(OUT, "\tst%d\n", i);

+	fprintf(OUT, "};\n\n");

+}

+

+

+#ifdef __USE_PROTOS

+void p_accept_table(void)

+#else

+void p_accept_table()

+#endif

+{

+	register int	i = 1;

+	register int	items_on_line = 0;

+	int		true_interactive = TRUE;

+

+	/* make sure element for one past (zzerraction) -WEC 12/16/92 */

+	fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n  ",

+			gen_cpp?ClassName("::"):"",

+			gen_cpp?ClassName("::"):"",

+			dfa_allocated+1);

+	/* don't do anything if no dfa nodes */

+	if (i>dfa_allocated) goto skip_accepts;

+	for (;;) {

+		int accept=0;   /* MR14a - Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) */

+		set accept_set;

+		set nfa_states;

+		unsigned int *t, *nfa_i;

+		unsigned int *q, *regular_expr;

+

+		accept_set = empty;

+		nfa_states = DFA(i)->nfa_states;

+		t = nfa_i = set_pdq(nfa_states);

+		/* NOTE: picks lowest accept because accepts monotonic	*/

+		/*	with respect to nfa node numbers and set_pdq	*/

+		/*	returns in that order				*/

+		while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){

+			nfa_i++;

+		}

+

+		/* figure out if more than one accept state there */

+		if (warn_ambig ){

+			set_orel(accept, &accept_set);

+			while(*nfa_i != nil){

+				set_orel(NFA(*nfa_i)->accept, &accept_set);

+				nfa_i++;

+			}

+			/* remove error action from consideration */

+			set_rm(0, accept_set);

+

+			if( set_deg(accept_set)>1){

+				fprintf(stderr, "dlg warning: ambiguous regular expression ");

+				q = regular_expr = set_pdq(accept_set);

+				while(*regular_expr != nil){

+					fprintf(stderr," %d ", *regular_expr);

+					++regular_expr;

+				}

+				fprintf(stderr, "\n");

+				free(q);

+			}

+		}

+

+		if ((DFA(i)->alternatives) && (accept != 0)){

+			true_interactive = FALSE;

+		}

+		fprintf(OUT, "%d, ", accept);

+

+		/* free up memory before we "break" below -ATG 4/6/95 */

+		free(t);

+		set_free(accept_set);

+

+		if ((++i)>dfa_allocated)

+			break;

+		if ((++items_on_line)>=MAX_ON_LINE){

+			fprintf(OUT,"\n  ");

+			items_on_line = 0;

+		}

+/*

+		free(t);

+		set_free(accept_set);

+*/

+	}

+	/* make sure element for one past (zzerraction) -WEC 12/16/92 */

+skip_accepts:

+	fprintf(OUT, "0\n};\n\n");

+}

+

+

+#ifdef __USE_PROTOS

+void p_action_table(void)

+#else

+void p_action_table()

+#endif

+{

+	register int	i;

+	char* theClassName = ClassName("");

+

+	if ( gen_cpp )

+		fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName,

+					theClassName, action_no+1);

+	else

+		fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1);

+	if ( gen_cpp )

+/*		fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/

+		fprintf(OUT, "\t&%s::erraction,\n", theClassName);

+	else

+		fprintf(OUT, "\tzzerraction,\n");

+	for (i=1; i<action_no; ++i) {

+		if ( gen_cpp )

+/*			fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d,\n", theClassName, theClassName, i);*/

+			fprintf(OUT,"\t&%s::act%d,\n", theClassName, i);

+		else

+			fprintf(OUT,"\tact%d,\n", i);

+		DAWDLE;

+	}

+	if ( gen_cpp )

+/*		fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d\n", theClassName, theClassName, i);*/

+		fprintf(OUT,"\t&%s::act%d\n", theClassName, i);

+	else

+		fprintf(OUT,"\tact%d\n", i);

+	fprintf(OUT, "};\n\n");

+}

+

+

+#ifdef __USE_PROTOS

+void p_shift_table(int m)  				    /* MR1 */

+#else

+void p_shift_table(m)						/* MR1 */

+int m;

+#endif

+{

+	register int	i = 0, j;

+	register int	items_on_line = 0;

+

+	fprintf(OUT, "%s unsigned char %sshift%d[%d] = {\n  ",

+		gen_cpp?"":"static",

+		gen_cpp?ClassName("::"):"", m, CHAR_RANGE);

+	for (;;) {

+		/* find which partition character i is in */

+		for (j=0; j<dfa_class_nop[mode_counter]; ++j){

+			if (set_el(i,class_sets[j]))

+				break;

+			}

+		fprintf(OUT,"%d",j);

+		if ((++i)>=CHAR_RANGE)

+			break;

+		fprintf(OUT,", ");

+		if ((++items_on_line)>=MAX_ON_LINE){

+			fprintf(OUT,"\n  ");

+			items_on_line = 0;

+			}

+		}

+	fprintf(OUT, "\n};\n\n");

+}

+

+

+#ifdef __USE_PROTOS

+void p_base_table(void)

+#else

+void p_base_table()

+#endif

+{

+	register int m;

+

+	fprintf(OUT, "%sDfaState %sdfa_base[] = {\n",

+			gen_cpp?ClassName("::"):"static ",

+			gen_cpp?ClassName("::"):"");

+	for(m=0; m<(mode_counter-1); ++m)

+		fprintf(OUT, "\t%d,\n", dfa_basep[m]-1);

+	fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1);

+}

+

+

+#ifdef __USE_PROTOS

+void p_class_table(void)    				/* MR1 */

+#else

+void p_class_table()						/* MR1 */

+#endif

+{

+#if 0

+	register int m;

+

+	fprintf(OUT,"%s int %sdfa_class_no[] = {\n",

+			gen_cpp?"":"static",

+			gen_cpp?ClassName("::"):"");

+	for(m=0; m<(mode_counter-1); ++m)

+		fprintf(OUT,"\t%d,\n", dfa_class_nop[m]);

+	fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]);

+#endif

+}

+

+

+#ifdef __USE_PROTOS

+void p_bshift_table(void)					/* MR1 */

+#else

+void p_bshift_table()						/* MR1 */

+#endif

+{

+	register int m;

+

+	fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n",

+		gen_cpp?"":"static",

+		gen_cpp?ClassName("::"):"");

+	for(m=0; m<(mode_counter-1); ++m)

+		fprintf(OUT, "\tshift%d,\n", m);

+	fprintf(OUT, "\tshift%d\n};\n\n", m);

+}

+

+

+#ifdef __USE_PROTOS

+void p_alternative_table(void)				/* MR1 */

+#else

+void p_alternative_table()					/* MR1 */

+#endif

+{

+	register int i;

+

+	if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n");

+	if ( gen_cpp )

+		fprintf(OUT, "DLGChar %salternatives[%d] = {\n",  /* mr23 vhs %sDfaStates+1 */

+				ClassName("::"),

+				dfa_allocated+1); /* vhs ClassName("::")); */

+	else

+		fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n",

+				minsize(dfa_allocated));

+

+	for(i=1; i<=dfa_allocated; ++i)

+		fprintf(OUT, "\t%d,\n", DFA(i)->alternatives);

+	fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n");

+	fprintf(OUT, "\t0\n};\n\n");

+}

+

+

+#ifdef __USE_PROTOS

+void p_mode_def(char *s,int m)			/* MR1 */

+#else

+void p_mode_def(s,m)					/* MR1 */

+char *s;

+int m;

+#endif

+{

+	if ( gen_cpp )

+	{

+		mode_name[cur_mode] = mystrdup(s);

+		mode_number[cur_mode] = m;

+		cur_mode++;

+	}

+	else

+		fprintf(mode_stream, "#define %s %d\n", s, m);

+}

+

+#ifdef __USE_PROTOS

+char * ClassName(char *suffix)

+#else

+char * ClassName(suffix)

+char *suffix;

+#endif

+{

+	static char buf[200];

+	extern char *class_name;

+

+	sprintf(buf, "%s%s", class_name, suffix);

+	return buf;

+}

+

+#ifdef DEBUG

+

+/* print out a particular nfa node that is pointed to by p */

+

+#ifdef __USE_PROTOS

+void p_nfa_node(nfa_node *p)

+#else

+void p_nfa_node(p)

+nfa_node *p;

+#endif

+{

+	 register nfa_node *t;

+

+	if (p != NIL_INDEX){

+		printf("NFA state : %d\naccept state : %d\n",

+			NFA_NO(p),p->accept);

+		if (p->trans[0] != NIL_INDEX){

+			printf("trans[0] => %d on ", NFA_NO(p->trans[0]));

+			p_set(p->label);

+			printf("\n");

+			}

+		else

+			printf("trans[0] => nil\n");

+		if (p->trans[1] != NIL_INDEX)

+			printf("trans[1] => %d on epsilon\n",

+				NFA_NO(p->trans[1]));

+		else

+			printf("trans[1] => nil\n");

+		printf("\n");

+		}

+}

+#endif

+

+#ifdef  DEBUG

+

+/* code to print out special structures when using a debugger */

+

+#ifdef __USE_PROTOS

+void p_nfa(p)

+#else

+void p_nfa(nfa_node *p)

+nfa_node *p;	/* state number also index into array */

+#endif

+{

+/* each node has a marker on it so it only gets printed once */

+

+	operation_no++; /* get new number */

+	s_p_nfa(p);

+}

+

+#ifdef __USE_PROTOS

+void s_p_nfa(nfa_node *p)

+#else

+void s_p_nfa(p)

+nfa_node *p;	/* state number also index into array */

+#endif

+{

+	if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){

+		/* so it is only printed once */

+		p->nfa_set = operation_no;

+		p_nfa_node(p);

+		s_p_nfa(p->trans[0]);

+		s_p_nfa(p->trans[1]);

+		}

+}

+

+#ifdef __USE_PROTOS

+void p_dfa_node(dfa_node *p)

+#else

+void p_dfa_node(p)

+dfa_node *p;

+#endif

+{

+	int i;

+

+	if (p != NIL_INDEX){

+		printf("DFA state :%d\n",NFA_NO(p));

+		if (p->done)

+			printf("done\n");

+		else

+			printf("undone\n");

+		printf("from nfa states : ");

+		p_set(p->nfa_states);

+		printf("\n");

+		/* NOTE: trans arcs stored as ints rather than pointer*/

+		for (i=0; i<class_no; i++){

+			printf("%d ",p->trans[i]);

+			}

+		printf("\n\n");

+		}

+}

+

+#ifdef __USE_PROTOS

+void p_dfa(void)

+#else

+void p_dfa()

+#endif

+{

+/* prints out all the dfa nodes actually allocated */

+

+	int i;

+

+	for (i = 1; i<=dfa_allocated; i++)

+		p_dfa_node(NFA(i));

+}

+

+

+/* print out numbers in the set label */

+

+#ifdef __USE_PROTOS

+void p_set(set label)

+#else

+void p_set(label)

+set label;

+#endif

+{

+	unsigned *t, *e;

+

+	if (set_nil(label)){

+		printf("epsilon\n");

+	}else{

+		t = e = set_pdq(label);

+		while(*e != nil){

+			printf("%d ", (*e+MIN_CHAR));

+			e++;

+		}

+		printf("\n");

+		free(t);

+	}

+	

+}

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/parser.dlg b/edk2/Tools/Source/TianoTools/Pccts/dlg/parser.dlg
new file mode 100644
index 0000000..df9a637
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/parser.dlg
@@ -0,0 +1,398 @@
+<<

+/* parser.dlg -- DLG Description of scanner

+ *

+ * Generated from: dlg_p.g

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#define ANTLR_VERSION	13333

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include <ctype.h>

+#include "dlg.h"

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+LOOKAHEAD

+

+void

+#ifdef __USE_PROTOS

+zzerraction(void)

+#else

+zzerraction()

+#endif

+{

+	(*zzerr)("invalid token");

+	zzadvance();

+	zzskip();

+}

+>>

+

+<<%%lexaction

+

+int	func_action;		/* should actions be turned into functions?*/

+int	lex_mode_counter = 0;	/* keeps track of the number of %%names */

+/* MR1									    */

+/* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+/* MR1				via <<%%lexmember...>>			    */

+/* MR1									    */

+int	lexMember = 0;		/* <<%%lexmemeber ...>>	   		MR1 */

+int	lexAction = 0;		/* <<%%lexaction ...>>			MR1 */

+int	parserClass = 0;	/* <<%%parserclass ...>>        MR1 */

+int	lexPrefix = 0;		/* <<%%lexprefix ...>>			MR1 */

+char	theClassName[100];						     /* MR11 */

+char	*pClassName=theClassName;					 /* MR11 */

+int	firstLexMember=1;					             /* MR1 */

+

+#ifdef __USE_PROTOS

+void  xxputc(int c) {						/* MR1 */

+#else

+  void xxputc(c)							/* MR1 */

+  int	c;							/* MR1 */

+  {								/* MR1 */

+#endif

+    if (parserClass) {						/* MR1 */

+      *pClassName++=c;						/* MR1 */

+      *pClassName=0;						/* MR1 */

+    } else if (lexMember || lexPrefix) {				/* MR1 */

+      if (class_stream != NULL) fputc(c,class_stream);		/* MR1 */

+    } else {							/* MR1 */

+      fputc(c,OUT);						/* MR1 */

+    };								/* MR1 */

+  }  								/* MR1 */

+  

+#ifdef __USE_PROTOS

+  void xxprintf(char *format,char *string) {			/* MR1 */

+#else

+    void xxprintf(format,string) 					/* MR1 */

+    char *format;							/* MR1 */

+    char *string;							/* MR1 */

+    {								/* MR1 */

+#endif

+      if (lexMember || lexPrefix || parserClass) {			/* MR1 */

+        if (class_stream != NULL)					/* MR1 */

+        fprintf(class_stream,format,string);			/* MR1 */

+      } else {							/* MR1 */

+        fprintf(OUT,format,string);					/* MR1 */

+      };								/* MR1 */

+    }  								/* MR1 */

+>>

+

+

+%%START

+

+@

+	<<

+		NLA = 1;

+	>>

+

+[\r\t\ ]+

+	<<

+		NLA = 2;

+    zzskip();   

+	>>

+

+\n

+	<<

+		NLA = 3;

+    zzline++; zzskip(); DAWDLE;   

+	>>

+

+\@

+	<<

+		NLA = L_EOF;

+	>>

+

+\%\%

+	<<

+		NLA = PER_PER;

+	>>

+

+\%\%[a-zA-Z_][a-zA-Z0-9_]*

+	<<

+		NLA = NAME_PER_PER;

+    p_mode_def(&zzlextext[2],lex_mode_counter++);   

+	>>

+

+\<\<\%\%lexmember

+	<<

+		NLA = LEXMEMBER;

+    lexMember=1;					/* MR1 */

+    if (firstLexMember != 0) {			/* MR1 */

+      firstLexMember=0;				/* MR1 */

+      p_class_def1();				/* MR1 */

+    };						/* MR1 */

+    zzmode(ACT);					/* MR1 */

+	>>

+

+\<\<\%\%lexaction

+	<<

+		NLA = LEXACTION;

+    lexAction=1;zzmode(ACT);  

+	>>

+

+\<\<\%\%parserclass

+	<<

+		NLA = PARSERCLASS;

+    parserClass=1;				/* MR1 */

+    zzmode(ACT);					/* MR1 */

+	>>

+

+\<\<\%\%lexprefix

+	<<

+		NLA = LEXPREFIX;

+    lexPrefix=1;zzmode(ACT);  

+	>>

+

+\<\<

+	<<

+		NLA = ACTION;

+    if (func_action)

+    fprintf(OUT,"\n%s %sact%d()\n{ ",

+    gen_cpp?"ANTLRTokenType":"static void",

+    gen_cpp?ClassName("::"):"", ++action_no);

+    zzmode(ACT); zzskip();

+	>>

+

+\>\>

+	<<

+		NLA = GREAT_GREAT;

+	>>

+

+\{

+	<<

+		NLA = L_BRACE;

+	>>

+

+\}

+	<<

+		NLA = R_BRACE;

+	>>

+

+\(

+	<<

+		NLA = L_PAR;

+	>>

+

+\)

+	<<

+		NLA = R_PAR;

+	>>

+

+\[

+	<<

+		NLA = L_BRACK;

+	>>

+

+\]

+	<<

+		NLA = R_BRACK;

+	>>

+

+\*

+	<<

+		NLA = ZERO_MORE;

+	>>

+

+\+

+	<<

+		NLA = ONE_MORE;

+	>>

+

+\|

+	<<

+		NLA = OR;

+	>>

+

+\-

+	<<

+		NLA = RANGE;

+	>>

+

+\~

+	<<

+		NLA = NOT;

+	>>

+

+\\0[0-7]*

+	<<

+		NLA = OCTAL_VALUE;

+    {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}  

+	>>

+

+\\0[Xx][0-9a-fA-F]+

+	<<

+		NLA = HEX_VALUE;

+    {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}  

+	>>

+

+\\[1-9][0-9]*

+	<<

+		NLA = DEC_VALUE;

+    {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}  

+	>>

+

+\\t

+	<<

+		NLA = TAB;

+    zzlextext[0] = '\t';  

+	>>

+

+\\n

+	<<

+		NLA = NL;

+    zzlextext[0] = '\n';  

+	>>

+

+\\r

+	<<

+		NLA = CR;

+    zzlextext[0] = '\r';  

+	>>

+

+\\b

+	<<

+		NLA = BS;

+    zzlextext[0] = '\b';  

+	>>

+

+\\ \n

+	<<

+		NLA = CONTINUATION;

+    zzline++; zzskip();  

+	>>

+

+\\~[tnrb]

+	<<

+		NLA = LIT;

+    zzlextext[0] = zzlextext[1];  

+	>>

+

+~[\\]

+	<<

+		NLA = REGCHAR;

+	>>

+

+

+%%ACT

+

+@

+	<<

+		NLA = 1;

+    error("unterminated action", zzline); zzmode(START);   

+	>>

+

+\>\>

+	<<

+		NLA = ACTION;

+    if (func_action) fprintf(OUT,"}\n\n");

+    zzmode(START);

+    /* MR1									    */

+    /* MR1  11-Apr-97	Provide mechanism for inserting code into DLG class */

+    /* MR1				via <<%%lexmember ...>>			    */

+    /* MR1			This is a consequence of not saving actions         */

+    /* MR1									    */

+    /* MR1 */	   parserClass=0;		

+    /* MR1 */	   lexPrefix=0;

+    /* MR1 */	   lexAction=0;

+    /* MR1 */	   lexMember=0;

+	>>

+

+\>

+	<<

+		NLA = 34;

+    xxputc(zzlextext[0]); zzskip();   

+	>>

+

+\\\>

+	<<

+		NLA = 35;

+    xxputc('>'); zzskip();   

+	>>

+

+\\

+	<<

+		NLA = 36;

+    xxputc('\\'); zzskip();   

+	>>

+

+\n

+	<<

+		NLA = 37;

+    xxputc(zzlextext[0]); ++zzline; zzskip();   

+	>>

+

+/\*

+	<<

+		NLA = 38;

+    zzmode(ACTION_COMMENTS);			/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	>>

+

+//

+	<<

+		NLA = 39;

+    zzmode(ACTION_CPP_COMMENTS);			/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	>>

+

+~[]

+	<<

+		NLA = 40;

+    xxputc(zzlextext[0]); zzskip();   

+	>>

+

+

+%%ACTION_COMMENTS

+

+@

+	<<

+		NLA = 1;

+	>>

+

+\*/

+	<<

+		NLA = 41;

+    zzmode(ACT);					/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	>>

+

+[\n\r]

+	<<

+		NLA = 42;

+    zzline++; xxputc(zzlextext[0]); zzskip();  

+	>>

+

+~[]

+	<<

+		NLA = 43;

+    xxputc(zzlextext[0]); zzskip();  

+	>>

+

+

+%%ACTION_CPP_COMMENTS

+

+@

+	<<

+		NLA = 1;

+	>>

+

+[\n\r]

+	<<

+		NLA = 44;

+    zzmode(ACT); zzline++;			/* MR1 */

+    xxprintf("%s", &(zzlextext[0])); zzskip();	/* MR1 */

+	>>

+

+~[]

+	<<

+		NLA = 45;

+    xxputc(zzlextext[0]); zzskip();  

+	>>

+

+%%

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/relabel.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/relabel.c
new file mode 100644
index 0000000..0b8bc16
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/relabel.c
@@ -0,0 +1,217 @@
+/* This group of functions does the character class compression.

+   It goes over the dfa and relabels the arcs with the partitions

+   of characters in the NFA.  The partitions are stored in the

+   array class.

+

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include "dlg.h"

+#ifdef MEMCHK

+#include "trax.h"

+#else

+#ifdef __STDC__

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif /* __STDC__ */

+#endif

+

+int	class_no = CHAR_RANGE;	/* number of classes for labels */

+int	first_el[CHAR_RANGE];	/* first element in each class partition */

+set	class_sets[CHAR_RANGE];	/* array holds partitions from class */

+				/* compression */

+

+/* goes through labels on NFA graph and partitions the characters into

+ * character classes.  This reduces the amount of space required for each

+ * dfa node, since only one arc is required each class instead of one arc

+ * for each character

+ * level:

+ * 0 no compression done

+ * 1 remove unused characters from classes

+ * 2 compress equivalent characters into same class

+ *

+ * returns the number of character classes required

+ */

+#ifdef __USE_PROTOS

+int relabel(nfa_node* start,int level)

+#else

+int relabel(start,level)

+int level;

+nfa_node *start;

+#endif

+{

+	if (level){

+		set_free(used_classes);	

+		partition(start,level);

+		label_with_classes(start);

+	}else{

+		/* classes equivalent to all characters in alphabet */

+		class_no = CHAR_RANGE;

+	}

+	return class_no;

+}

+

+/* makes character class sets for new labels */

+#ifdef __USE_PROTOS

+void partition(nfa_node* start,int level)

+#else

+void partition(start,level)

+nfa_node	*start;	/* beginning of nfa graph */

+int		level;	/* compression level to uses */

+#endif

+{

+	set current_class;

+	set unpart_chars;

+	set temp;

+

+	unpart_chars = set_dup(used_chars);

+#if 0

+	/* EOF (-1+1) alway in class 0 */

+	class_sets[0] = set_of(0);

+	first_el[0] = 0;

+	used_classes = set_of(0);

+	temp = set_dif(unpart_chars, class_sets[0]);

+	set_free(unpart_chars);

+	unpart_chars = temp;

+	class_no = 1;

+#else

+	class_no = 0;

+#endif

+	while (!set_nil(unpart_chars)){

+		/* don't look for equivalent labels if c <= 1 */

+		if (level <= 1){

+			current_class = set_of(set_int(unpart_chars));

+		}else{

+			current_class = set_dup(unpart_chars);

+			intersect_nfa_labels(start,&current_class);

+		}

+		set_orel(class_no,&used_classes);

+		first_el[class_no] = set_int(current_class);

+		class_sets[class_no] = current_class;

+		temp = set_dif(unpart_chars,current_class);

+		set_free(unpart_chars);

+		unpart_chars = temp;

+		++class_no;

+	}

+

+	/* free unpart_chars -ATG 5/6/95 */

+	set_free(unpart_chars);

+

+#if 0

+	/* group all the other unused characters into a class */

+	set_orel(class_no,&used_classes);

+	first_el[class_no] = set_int(current_class);

+	class_sets[class_no] = set_dif(normal_chars,used_chars);

+	++class_no;

+#endif

+}

+

+

+/* given pointer to beginning of graph and recursively walks it trying

+ * to find a maximal partition.  This partion in returned in maximal_class

+ */

+#ifdef __USE_PROTOS

+void intersect_nfa_labels(nfa_node* start,set* maximal_class)

+#else

+void intersect_nfa_labels(start,maximal_class)

+nfa_node *start;

+set *maximal_class;

+#endif

+{

+	/* pick a new operation number */

+	++operation_no;

+	r_intersect(start,maximal_class);	

+}

+

+#ifdef __USE_PROTOS

+void r_intersect(nfa_node* start,set* maximal_class)

+#else

+void r_intersect(start,maximal_class)

+nfa_node *start;

+set * maximal_class;

+#endif

+{

+	set temp;

+

+	if(start && start->nfa_set != operation_no)

+	{

+		start->nfa_set = operation_no;

+		temp = set_and(*maximal_class,start->label);

+		if (!set_nil(temp))

+		{

+			set_free(*maximal_class);

+			*maximal_class = temp;

+		}else{

+			set_free(temp);

+		}

+		r_intersect(start->trans[0],maximal_class);

+		r_intersect(start->trans[1],maximal_class);

+	}

+}

+

+

+/* puts class labels in place of old character labels */

+#ifdef __USE_PROTOS

+void label_with_classes(nfa_node* start)

+#else

+void label_with_classes(start)

+nfa_node *start;

+#endif

+{

+	++operation_no;

+	label_node(start);

+}

+

+#ifdef __USE_PROTOS

+void label_node(nfa_node *start)

+#else

+void label_node(start)

+nfa_node *start;

+#endif

+{

+	set new_label;

+	register int i;

+

+	/* only do node if it hasn't been done before */

+	if (start && start->nfa_set != operation_no){

+		start->nfa_set = operation_no;

+		new_label = empty;

+		for (i = 0; i<class_no; ++i){

+			/* if one element of class in old_label,

+			   all elements are. */

+			if (set_el(first_el[i],start->label))

+				set_orel(i,&new_label);

+		}

+		set_free(start->label);

+		start->label = new_label;

+		/* do any nodes that can be reached from this one */

+		label_node(start->trans[0]);

+		label_node(start->trans[1]);

+	}

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/stdpccts.h b/edk2/Tools/Source/TianoTools/Pccts/dlg/stdpccts.h
new file mode 100644
index 0000000..06ec67e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/stdpccts.h
@@ -0,0 +1,26 @@
+#ifndef STDPCCTS_H

+#define STDPCCTS_H

+/*

+ * stdpccts.h -- P C C T S  I n c l u d e

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * With AHPCRC, University of Minnesota

+ * ANTLR Version 1.33MR33

+ */

+

+#ifndef ANTLR_VERSION

+#define ANTLR_VERSION	13333

+#endif

+

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+#include <ctype.h>

+#include "dlg.h"

+#define zzSET_SIZE 8

+#include "antlr.h"

+#include "tokens.h"

+#include "dlgdef.h"

+#include "mode.h"

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/support.c b/edk2/Tools/Source/TianoTools/Pccts/dlg/support.c
new file mode 100644
index 0000000..84fe99d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/support.c
@@ -0,0 +1,240 @@
+/*

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * DLG 1.33

+ * Will Cohen

+ * With mods by Terence Parr; AHPCRC, University of Minnesota

+ * 1989-2001

+ */

+

+#include <stdio.h>

+#include <string.h>

+#include "dlg.h"

+#ifdef MEMCHK

+#include "trax.h"

+#else

+#ifdef __STDC__

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif /* __STDC__ */

+#endif

+

+int	err_found = 0;			/* indicates whether problem found */

+

+#ifdef __USE_PROTOS

+void internal_error(char *s, char *file,int line)    /* MR9 23-Sep-97 */

+#else

+void internal_error(s,file,line)    /* MR9 23-Sep-97 */

+char *s,*file;

+int line;

+#endif

+{

+	fprintf(stderr,s,file,line);

+	exit(PCCTS_EXIT_FAILURE);

+}

+

+#ifdef __USE_PROTOS

+char *dlg_malloc(int bytes,char *file,int line)

+#else

+char *dlg_malloc(bytes,file,line)

+int bytes;

+char *file;

+int line;

+#endif

+{

+	char *t;

+

+	t = (char *) malloc(bytes);

+	if (!t){

+		/* error */

+		internal_error("%s(%d): unable to allocate memory\n",

+			file,line);

+	}

+	return t;

+}

+

+

+#ifdef __USE_PROTOS

+char *dlg_calloc(int n,int bytes,char *file,int line)

+#else

+char *dlg_calloc(n,bytes,file,line)

+int n,bytes;

+char *file;

+int line;

+#endif

+{

+	char *t;

+

+	t = (char *) calloc(n,bytes);

+	if (!t){

+		/* error */

+		internal_error("%s(%d): unable to allocate memory\n",

+			file,line);

+	}

+	return t;

+}

+

+

+#ifdef __USE_PROTOS

+FILE *read_stream(char *name)

+#else

+FILE *read_stream(name)

+char *name;

+#endif

+{

+	FILE *f;

+

+	if (name){

+		if (name[0] == '-') {

+			fprintf(stderr, "dlg: invalid option: '%s'\n", name);

+			f = NULL;

+		}else{

+			f = fopen(name, "r");

+			if (f == NULL){

+				/* couldn't open file */

+				fprintf(stderr,

+					"dlg: Warning: Can't read file %s.\n",

+					name);

+			}

+		}

+	}else{

+		/* open stdin if nothing there */

+		f = stdin;

+	}

+	return f;

+}

+

+#ifdef __USE_PROTOS

+FILE *write_stream(char *name)

+#else

+FILE *write_stream(name)

+char *name;

+#endif

+{

+	FILE *f;

+

+	if (name){

+		if (name[0] == '-') {

+			fprintf(stderr, "dlg: invalid option: '%s'\n", name);

+			f = NULL;

+		}else{

+			f = fopen(OutMetaName(name), "w");

+			if (f == NULL){

+				/* couldn't open file */

+				fprintf(stderr,

+					"dlg: Warning: Can't write to file %s.\n",

+					name);

+			}

+			else

+#ifdef SPECIAL_FOPEN

+                special_fopen_actions(OutMetaName(name));	/* MR1 */

+#else

+		;						/* MR1 */

+#endif

+		}

+	}else{

+		/* open stdout if nothing there */

+		f = stdout;

+	}

+	return f;

+}

+

+

+#ifdef __USE_PROTOS

+void fatal(char *message,int line_no)

+#else

+void fatal(message,line_no)

+char *message;

+int line_no;

+#endif

+{

+	fprintf(stderr,ErrHdr,

+		(file_str[0] ? file_str[0] : "stdin"), line_no);

+	fprintf(stderr, " Fatal: %s\n", message);

+	exit(PCCTS_EXIT_FAILURE);

+}

+

+#ifdef __USE_PROTOS

+void error(char *message,int line_no)

+#else

+void error(message,line_no)

+char *message;

+int line_no;

+#endif

+{

+	fprintf(stderr,ErrHdr,

+		(file_str[0] ? file_str[0] : "stdin"), line_no);

+	fprintf(stderr, " Error: %s\n", message);

+	err_found = 1;

+}

+

+#ifdef __USE_PROTOS

+void warning(char *message,int line_no)

+#else

+void warning(message,line_no)

+char *message;

+int line_no;

+#endif

+{

+	fprintf(stderr,ErrHdr,

+		(file_str[0] ? file_str[0] : "stdin"), line_no);

+	fprintf(stderr, " Warning: %s\n", message);

+}

+

+/* MR10: Jeff Vincent

+   MR10: Changed to remove directory information from n only if

+   MR10: if OutputDirectory was changed by user (-o option)

+*/

+

+#ifdef __USE_PROTOS

+char *OutMetaName(char *n)

+#else

+char *OutMetaName(n)

+char *n;

+#endif

+{	

+    static char *dir_sym = DirectorySymbol;

+    static char newname[MaxFileName+1];

+    char *p;

+

+	/* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */

+    if (strcmp(OutputDirectory, TopDirectory) == 0)

+		return n;

+

+	/* p will point to filename without path information */

+	if ((p = strrchr(n, *dir_sym)) != NULL)

+		p++;

+	else

+		p = n;

+

+	/* Copy new output directory into newname[] */

+	strcpy(newname, OutputDirectory);

+

+	/* if new output directory does not have trailing dir_sym, add it! */

+	if (newname[strlen(newname)-1] != *dir_sym)

+		strcat(newname, dir_sym);

+

+	/* contatenate FILE NAME ONLY to new output directory */

+	strcat(newname, p);

+

+	return newname;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/dlg/tokens.h b/edk2/Tools/Source/TianoTools/Pccts/dlg/tokens.h
new file mode 100644
index 0000000..73e502b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/dlg/tokens.h
@@ -0,0 +1,133 @@
+#ifndef tokens_h

+#define tokens_h

+/* tokens.h -- List of labelled tokens and stuff

+ *

+ * Generated from: dlg_p.g

+ *

+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001

+ * Purdue University Electrical Engineering

+ * ANTLR Version 1.33MR33

+ */

+#define zzEOF_TOKEN 1

+#define L_EOF 4

+#define PER_PER 5

+#define NAME_PER_PER 6

+#define LEXMEMBER 7

+#define LEXACTION 8

+#define PARSERCLASS 9

+#define LEXPREFIX 10

+#define ACTION 11

+#define GREAT_GREAT 12

+#define L_BRACE 13

+#define R_BRACE 14

+#define L_PAR 15

+#define R_PAR 16

+#define L_BRACK 17

+#define R_BRACK 18

+#define ZERO_MORE 19

+#define ONE_MORE 20

+#define OR 21

+#define RANGE 22

+#define NOT 23

+#define OCTAL_VALUE 24

+#define HEX_VALUE 25

+#define DEC_VALUE 26

+#define TAB 27

+#define NL 28

+#define CR 29

+#define BS 30

+#define CONTINUATION 31

+#define LIT 32

+#define REGCHAR 33

+

+#ifdef __USE_PROTOS

+void grammar(void);

+#else

+extern void grammar();

+#endif

+

+#ifdef __USE_PROTOS

+void start_states(void);

+#else

+extern void start_states();

+#endif

+

+#ifdef __USE_PROTOS

+void do_conversion(void);

+#else

+extern void do_conversion();

+#endif

+

+#ifdef __USE_PROTOS

+void rule_list(void);

+#else

+extern void rule_list();

+#endif

+

+#ifdef __USE_PROTOS

+void rule(void);

+#else

+extern void rule();

+#endif

+

+#ifdef __USE_PROTOS

+void reg_expr(void);

+#else

+extern void reg_expr();

+#endif

+

+#ifdef __USE_PROTOS

+void and_expr(void);

+#else

+extern void and_expr();

+#endif

+

+#ifdef __USE_PROTOS

+void repeat_expr(void);

+#else

+extern void repeat_expr();

+#endif

+

+#ifdef __USE_PROTOS

+void expr(void);

+#else

+extern void expr();

+#endif

+

+#ifdef __USE_PROTOS

+void atom_list(void);

+#else

+extern void atom_list();

+#endif

+

+#ifdef __USE_PROTOS

+void near_atom(void);

+#else

+extern void near_atom();

+#endif

+

+#ifdef __USE_PROTOS

+void atom(void);

+#else

+extern void atom();

+#endif

+

+#ifdef __USE_PROTOS

+void anychar(void);

+#else

+extern void anychar();

+#endif

+

+#endif

+extern SetWordType zzerr1[];

+extern SetWordType zzerr2[];

+extern SetWordType zzerr3[];

+extern SetWordType setwd1[];

+extern SetWordType zzerr4[];

+extern SetWordType zzerr5[];

+extern SetWordType zzerr6[];

+extern SetWordType setwd2[];

+extern SetWordType zzerr7[];

+extern SetWordType zzerr8[];

+extern SetWordType zzerr9[];

+extern SetWordType setwd3[];

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/AParser.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/AParser.cpp
new file mode 100644
index 0000000..720fe75
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/AParser.cpp
@@ -0,0 +1,871 @@
+/* ANTLRParser.C

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#include "pcctscfg.h"

+

+#include "pccts_stdlib.h"

+#include "pccts_stdarg.h"

+#include "pccts_string.h"

+#include "pccts_stdio.h"

+

+PCCTS_NAMESPACE_STD

+

+/* I have to put this here due to C++ limitation

+ * that you can't have a 'forward' decl for enums.

+ * I hate C++!!!!!!!!!!!!!!!

+ * Of course, if I could use real templates, this would go away.

+ */

+// MR1

+// MR1  10-Apr-97  133MR1  Prevent use of varying sizes for the

+// MR1  			ANTLRTokenType enum

+// MR1

+

+enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999};	    // MR1

+

+#define ANTLR_SUPPORT_CODE

+

+#include ATOKEN_H

+#include ATOKENBUFFER_H

+#include APARSER_H

+

+static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000;    /* MR14 */

+static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000;  /* MR14 */

+

+                 /* L o o k a h e a d  M a c r o s */

+

+/* maximum of 32 bits/unsigned int and must be 8 bits/byte;

+ * we only use 8 bits of it.

+ */

+SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = {

+	0x00000001, 0x00000002, 0x00000004, 0x00000008,

+	0x00000010, 0x00000020, 0x00000040, 0x00000080

+};

+

+char ANTLRParser::eMsgBuffer[500] = "";

+

+ANTLRParser::

+~ANTLRParser()

+{

+	delete [] token_type;

+    delete [] zzFAILtext;       // MR16 Manfred Kogler

+}

+

+ANTLRParser::

+ANTLRParser(ANTLRTokenBuffer *_inputTokens,

+			int k,

+			int use_inf_look,

+			int dlook,

+			int ssize)

+{

+	LLk = k;

+	can_use_inf_look = use_inf_look;

+/* MR14 */    if (dlook != 0) {

+/* MR14 */      panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode");

+/* MR14 */

+/* MR14 */    };

+    demand_look = 0;    /* demand_look = dlook; */

+    bsetsize = ssize;

+	guessing = 0;

+	token_tbl = NULL;

+	eofToken = (ANTLRTokenType)1;

+

+	// allocate lookahead buffer

+	token_type = new ANTLRTokenType[LLk];

+	lap = 0;

+	labase = 0;

+#ifdef ZZDEFER_FETCH

+	stillToFetch = 0;                                                   // MR19

+#endif

+	dirty = 0;

+    inf_labase = 0;                                                     // MR7

+    inf_last = 0;                                                       // MR7

+	/* prime lookahead buffer, point to inputTokens */

+	this->inputTokens = _inputTokens;

+	this->inputTokens->setMinTokens(k);

+	_inputTokens->setParser(this);					                    // MR1

+    resynchConsumed=1;                                                  // MR8

+    zzFAILtext=NULL;                                                    // MR9

+    traceOptionValueDefault=0;                                          // MR10

+    traceReset();                                                       // MR10

+    zzGuessSeq=0;                                                       // MR10

+    syntaxErrCount=0;                                                   // MR11

+}

+

+void ANTLRParser::init()

+{

+   prime_lookahead();

+   resynchConsumed=1;                                                   // MR8

+   traceReset();                                                        // MR10

+}

+

+void ANTLRParser::traceReset()

+{

+   traceOptionValue=traceOptionValueDefault;

+   traceGuessOptionValue=1;

+   traceCurrentRuleName=NULL;

+   traceDepth=0;

+}

+

+

+#ifdef _MSC_VER  // MR23

+//Turn off warning:

+//interaction between '_setjmp' and C++ object destruction is non-portable

+#pragma warning(disable : 4611)

+#endif

+int ANTLRParser::

+guess(ANTLRParserState *st)

+{

+	saveState(st);

+	guessing = 1;

+	return setjmp(guess_start.state);

+}

+#ifdef _MSC_VER  // MR23

+#pragma warning(default: 4611)

+#endif

+

+void ANTLRParser::

+saveState(ANTLRParserState *buf)

+{

+	buf->guess_start = guess_start;

+	buf->guessing = guessing;

+	buf->inf_labase = inf_labase;

+	buf->inf_last = inf_last;

+	buf->dirty = dirty;

+    buf->traceOptionValue=traceOptionValue;            /* MR10 */

+    buf->traceGuessOptionValue=traceGuessOptionValue;  /* MR10 */

+    buf->traceCurrentRuleName=traceCurrentRuleName;    /* MR10 */

+    buf->traceDepth=traceDepth;                        /* MR10 */

+}

+

+void ANTLRParser::

+restoreState(ANTLRParserState *buf)

+{

+	int     i;

+    int     prevTraceOptionValue;

+

+	guess_start = buf->guess_start;

+	guessing = buf->guessing;

+	inf_labase = buf->inf_labase;

+	inf_last = buf->inf_last;

+	dirty = buf->dirty;

+

+	// restore lookahead buffer from k tokens before restored TokenBuffer position

+	// if demand_look, then I guess we don't look backwards for these tokens.

+	for (i=1; i<=LLk; i++) token_type[i-1] =

+		inputTokens->bufferedToken(i-LLk)->getType();

+	lap = 0;

+	labase = 0;

+

+    /* MR10 */

+

+    prevTraceOptionValue=traceOptionValue;

+    traceOptionValue=buf->traceOptionValue;

+    if ( (prevTraceOptionValue > 0) !=

+             (traceOptionValue > 0)) {

+      if (traceCurrentRuleName != NULL) {  /* MR21 */

+          if (traceOptionValue > 0) {

+            /* MR23 */ printMessage(stderr,

+                   "trace enable restored in rule %s depth %d\n",

+                   traceCurrentRuleName,

+                   traceDepth);

+          };

+          if (traceOptionValue <= 0) {

+            /* MR23 */ printMessage(stderr,

+            "trace disable restored in rule %s depth %d\n",

+            traceCurrentRuleName, /* MR21 */

+            traceDepth);

+          };

+       }

+    };

+    traceGuessOptionValue=buf->traceGuessOptionValue;

+    traceCurrentRuleName=buf->traceCurrentRuleName;

+    traceDepth=buf->traceDepth;

+    traceGuessDone(buf);

+}

+

+/* Get the next symbol from the input stream; put it into lookahead buffer;

+ * fill token_type[] fast reference cache also.  NLA is the next place where

+ * a lookahead ANTLRAbstractToken should go.

+ */

+void ANTLRParser::

+consume()

+{

+

+#ifdef ZZDEBUG_CONSUME_ACTION

+    zzdebug_consume_action();

+#endif

+

+// MR19 V.H. Simonis

+//      Defer Fetch feature

+//      Moves action of consume() into LA() function

+

+#ifdef ZZDEFER_FETCH

+      stillToFetch++;

+#else

+      NLA = inputTokens->getToken()->getType();

+      dirty--;

+      lap = (lap+1)&(LLk-1);

+#endif

+

+}

+

+_ANTLRTokenPtr ANTLRParser::

+LT(int i)

+{

+

+// MR19 V.H. Simonis

+//      Defer Fetch feature

+//      Moves action of consume() into LA() function

+

+#ifdef ZZDEFER_FETCH

+    undeferFetch();

+#endif

+

+#ifdef DEBUG_TOKENBUFFER

+	if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk )     /* MR20 Was "<=" */

+	{

+		char buf[2000];                 /* MR20 Was "static" */

+        sprintf(buf, "The minimum number of tokens you requested that the\nANTLRTokenBuffer buffer is not enough to satisfy your\nLT(%d) request; increase 'k' argument to constructor for ANTLRTokenBuffer\n", i);

+		panic(buf);

+	}

+#endif

+	return inputTokens->bufferedToken(i-LLk);

+}

+

+void

+ANTLRParser::

+look(int k)

+{

+	int i, c = k - (LLk-dirty);

+	for (i=1; i<=c; i++) consume();

+}

+

+/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK);

+ */

+void

+ANTLRParser::

+prime_lookahead()

+{

+	int i;

+	for(i=1;i<=LLk; i++) consume();

+	dirty=0;

+	// lap = 0;     // MR14 Sinan Karasu (sinan.karasu@boeing.com)

+	// labase = 0;  // MR14

+    labase=lap;     // MR14

+}

+

+/* check to see if the current input symbol matches '_t'.

+ * During NON demand lookahead mode, dirty will always be 0 and

+ * hence the extra code for consuming tokens in _match is never

+ * executed; the same routine can be used for both modes.

+ */

+int ANTLRParser::

+_match(ANTLRTokenType _t, ANTLRChar **MissText,

+	   ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,

+	   SetWordType **MissSet)

+{

+	if ( dirty==LLk ) {

+		consume();

+	}

+	if ( LA(1)!=_t ) {

+		*MissText=NULL;

+		*MissTok= _t;

+		*BadTok = LT(1);

+		*MissSet=NULL;

+		return 0;

+	}

+	dirty++;

+	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look

+	return 1;

+}

+

+/* check to see if the current input symbol matches '_t'.

+ * Used during exception handling.

+ */

+int ANTLRParser::

+_match_wsig(ANTLRTokenType _t)

+{

+	if ( dirty==LLk ) {

+		consume();

+	}

+	if ( LA(1)!=_t ) return 0;

+	dirty++;

+	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look

+	return 1;

+}

+

+/* check to see if the current input symbol matches any token in a set.

+ * During NON demand lookahead mode, dirty will always be 0 and

+ * hence the extra code for consuming tokens in _match is never

+ * executed; the same routine can be used for both modes.

+ */

+int ANTLRParser::

+_setmatch(SetWordType *tset, ANTLRChar **MissText,

+	   ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,

+	   SetWordType **MissSet, SetWordType *tokclassErrset)

+{

+	if ( dirty==LLk ) {

+		consume();

+	}

+	if ( !set_el(LA(1), tset) ) {

+		*MissText=NULL;										/* MR23 */

+		*MissTok=(ANTLRTokenType) 0;						/* MR23 */

+		*BadTok=LT(1);										/* MR23 */

+		*MissSet=tokclassErrset;							/* MR23 */

+		return 0;

+	}

+	dirty++;

+	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look

+	return 1;

+}

+

+int ANTLRParser::

+_setmatch_wsig(SetWordType *tset)

+{

+	if ( dirty==LLk ) {

+		consume();

+	}

+	if ( !set_el(LA(1), tset) ) return 0;

+	dirty++;

+	labase = (labase+1)&(LLk-1);	// labase maintained even if !demand look

+	return 1;

+}

+

+                   /* Exception handling routines */

+//

+//  7-Apr-97 133MR1

+//   	     Change suggested by Eli Sternheim (eli@interhdl.com)

+//

+void ANTLRParser::

+consumeUntil(SetWordType *st)

+{

+	ANTLRTokenType		tmp;	                        				// MR1

+	const			int Eof=1;                                          // MR1

+	while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); }       // MR1

+}

+

+//

+//  7-Apr-97 133MR1

+//   	     Change suggested by Eli Sternheim (eli@interhdl.com)

+//

+void ANTLRParser::

+consumeUntilToken(int t)

+{

+	int	tmp;                                                            // MR1

+	const	int Eof=1;                                                  // MR1

+	while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); }                 // MR1

+}

+

+

+                        /* Old error stuff */

+

+void ANTLRParser::

+resynch(SetWordType *wd,SetWordType mask)

+{

+

+/* MR8              S.Bochnak@microtool.com.pl                          */

+/* MR8              Change file scope static "consumed" to instance var */

+

+	/* if you enter here without having consumed a token from last resynch

+	 * force a token consumption.

+	 */

+/* MR8 */  	if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;}

+

+   	/* if current token is in resynch set, we've got what we wanted */

+

+/* MR8 */  	if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;}

+	

+   	/* scan until we find something in the resynch set */

+

+        	while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();}

+

+/* MR8 */	resynchConsumed=1;

+}

+

+/* standard error reporting function that assumes DLG-based scanners;

+ * you should redefine in subclass to change it or if you use your

+ * own scanner.

+ */

+

+/* MR23 THM There appears to be a parameter "badText" passed to syn()

+            which is not present in the parameter list.  This may be

+            because in C mode there is no attribute function which

+            returns the text, so the text representation of the token

+            must be passed explicitly.  I think.

+*/

+           

+void ANTLRParser::

+syn(_ANTLRTokenPtr /*tok MR23*/, ANTLRChar *egroup, SetWordType *eset,

+	ANTLRTokenType etok, int k)

+{

+	int line;

+

+	line = LT(1)->getLine();

+

+    syntaxErrCount++;                                   /* MR11 */

+

+    /* MR23  If the token is not an EOF token, then use the ->getText() value.

+

+             If the token is the EOF token the text returned by ->getText() 

+             may be garbage.  If the text from the token table is "@" use

+             "<eof>" instead, because end-users don't know what "@" means.

+             If the text is not "@" then use that text, which must have been

+             supplied by the grammar writer.

+     */

+	const char * errorAt = LT(1)->getText();

+	if (LA(1) == eofToken) {

+  	  errorAt = parserTokenName(LA(1));

+  	  if (errorAt[0] == '@') errorAt = "<eof>";

+	}

+	/* MR23 */ printMessage(stderr, "line %d: syntax error at \"%s\"",

+					line, errorAt);

+	if ( !etok && !eset ) {/* MR23 */ printMessage(stderr, "\n"); return;}

+	if ( k==1 ) /* MR23 */ printMessage(stderr, " missing");

+	else

+	{

+		/* MR23 */ printMessage(stderr, "; \"%s\" not", LT(k)->getText()); // MR23 use LT(k) since k>1

+		if ( set_deg(eset)>1 ) /* MR23 */ printMessage(stderr, " in");

+	}

+	if ( set_deg(eset)>0 ) edecode(eset);

+	else /* MR23 */ printMessage(stderr, " %s", token_tbl[etok]);

+	if ( strlen(egroup) > 0 ) /* MR23 */ printMessage(stderr, " in %s", egroup);

+	/* MR23 */ printMessage(stderr, "\n");

+}

+

+/* is b an element of set p? */

+int ANTLRParser::

+set_el(ANTLRTokenType b, SetWordType *p)

+{

+	return( p[DIVWORD(b)] & bitmask[MODWORD(b)] );

+}

+

+int ANTLRParser::

+set_deg(SetWordType *a)

+{

+	/* Fast compute degree of a set... the number

+	   of elements present in the set.  Assumes

+	   that all word bits are used in the set

+	*/

+	register SetWordType *p = a;

+	register SetWordType *endp = &(a[bsetsize]);

+	register int degree = 0;

+

+	if ( a == NULL ) return 0;

+	while ( p < endp )

+	{

+		register SetWordType t = *p;

+		register SetWordType *b = &(bitmask[0]);

+		do {

+			if (t & *b) ++degree;

+		} while (++b < &(bitmask[sizeof(SetWordType)*8]));

+		p++;

+	}

+

+	return(degree);

+}

+

+void ANTLRParser::

+edecode(SetWordType *a)

+{

+	register SetWordType *p = a;

+	register SetWordType *endp = &(p[bsetsize]);

+	register unsigned e = 0;

+

+	if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " {");

+	do {

+		register SetWordType t = *p;

+		register SetWordType *b = &(bitmask[0]);

+		do {

+			if ( t & *b ) /* MR23 */ printMessage(stderr, " %s", token_tbl[e]);

+			e++;

+		} while (++b < &(bitmask[sizeof(SetWordType)*8]));

+	} while (++p < endp);

+	if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " }");

+}

+

+/* input looks like:

+ *      zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk)

+ * where the zzMiss stuff is set here to the token that did not match

+ * (and which set wasn't it a member of).

+ */

+

+// MR9 29-Sep-97    Stan Bochnak (S.Bochnak@microTool.com.pl)

+// MR9              Original fix to static allocated text didn't

+// MR9                work because a pointer to it was passed back

+// MR9                to caller.  Replace with instance variable.

+

+const int   SETWORDCOUNT=20;

+

+void

+ANTLRParser::FAIL(int k, ...)

+{

+//

+//  MR1 10-Apr-97	

+//

+

+    if (zzFAILtext == NULL) zzFAILtext=new char [1000];          // MR9

+    SetWordType **f=new SetWordType *[SETWORDCOUNT];             // MR1 // MR9

+    SetWordType **miss_set;

+    ANTLRChar **miss_text;

+    _ANTLRTokenPtr *bad_tok;

+    ANTLRChar **bad_text;

+//

+//  7-Apr-97 133MR1

+//  		err_k is passed as a "int *", not "unsigned *"

+//

+    int	*err_k;                                                         // MR1

+    int i;

+    va_list ap;

+

+    va_start(ap, k);

+

+    zzFAILtext[0] = '\0';

+	if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer");

+    for (i=1; i<=k; i++)    /* collect all lookahead sets */

+    {

+        f[i-1] = va_arg(ap, SetWordType *);

+    }

+    for (i=1; i<=k; i++)    /* look for offending token */

+    {

+        if ( i>1 ) strcat(zzFAILtext, " ");

+        strcat(zzFAILtext, LT(i)->getText());

+        if ( !set_el(LA(i), f[i-1]) ) break;

+    }

+    miss_set = va_arg(ap, SetWordType **);

+    miss_text = va_arg(ap, ANTLRChar **);

+    bad_tok = va_arg(ap, _ANTLRTokenPtr *);

+    bad_text = va_arg(ap, ANTLRChar **);

+    err_k = va_arg(ap, int *);                      					// MR1

+    if ( i>k )

+    {

+        /* bad; lookahead is permutation that cannot be matched,

+         * but, the ith token of lookahead is valid at the ith position

+         * (The old LL sub 1 (k) versus LL(k) parsing technique)

+         */

+        *miss_set = NULL;

+        *miss_text = LT(1)->getText();

+        *bad_tok = LT(1);

+        *bad_text = (*bad_tok)->getText();

+        *err_k = k;

+//

+//  MR4 20-May-97	erroneously deleted contents of f[]

+//  MR4			        reported by Bruce Guenter (bruceg@qcc.sk.ca)

+//  MR1 10-Apr-97	release temporary storage

+//

+      delete [] f;                                                      // MR1

+      return;                                                           // MR1

+    }

+/*  MR23 printMessage(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/

+    *miss_set = f[i-1];

+    *miss_text = zzFAILtext;

+    *bad_tok = LT(i);

+    *bad_text = (*bad_tok)->getText();

+    if ( i==1 ) *err_k = 1;

+    else *err_k = k;

+//

+//  MR4 20-May-97	erroneously deleted contents of f[]

+//  MR4			      reported by Bruce Guenter (bruceg@qcc.sk.ca)

+//  MR1 10-Apr-97	release temporary storage

+//

+    delete [] f;                                                        // MR1

+    return;                                                             // MR1

+}

+

+int ANTLRParser::

+_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows)

+{

+	if ( dirty==LLk ) consume();

+

+	if ( LA(1)!=tokenWanted )

+	{

+        syntaxErrCount++;                                   /* MR11 */

+		/* MR23 */ printMessage(stderr,

+				"line %d: syntax error at \"%s\" missing %s\n",

+				LT(1)->getLine(),

+				(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */

+				token_tbl[tokenWanted]);

+		consumeUntil( whatFollows );

+		return 0;

+	}

+	else {

+		dirty++;

+		labase = (labase+1)&(LLk-1); // labase maintained even if !demand look

+/*		if ( !demand_look ) consume(); */

+		return 1;

+	}

+}

+

+

+int ANTLRParser::

+_setmatch_wdfltsig(SetWordType *tokensWanted,

+					ANTLRTokenType tokenTypeOfSet,

+					SetWordType *whatFollows)

+{

+	if ( dirty==LLk ) consume();

+	if ( !set_el(LA(1), tokensWanted) )

+	{

+        syntaxErrCount++;                                   /* MR11 */

+		/* MR23 */ printMessage(stderr,

+				"line %d: syntax error at \"%s\" missing %s\n",

+				LT(1)->getLine(),

+				(LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */

+				token_tbl[tokenTypeOfSet]);

+		consumeUntil( whatFollows );

+		return 0;

+	}

+	else {

+		dirty++;

+		labase = (labase+1)&(LLk-1); // labase maintained even if !demand look

+/*		if ( !demand_look ) consume(); */

+		return 1;

+	}

+}

+

+char *ANTLRParser::

+eMsgd(char *err,int d)

+{

+	sprintf(eMsgBuffer, err, d);	// dangerous, but I don't care

+	return eMsgBuffer;

+}

+

+char *ANTLRParser::

+eMsg(char *err, char *s)

+{

+	sprintf(eMsgBuffer, err, s);

+	return eMsgBuffer;

+}

+

+char *ANTLRParser::

+eMsg2(char *err,char *s, char *t)

+{

+	sprintf(eMsgBuffer, err, s, t);

+	return eMsgBuffer;

+}

+

+void ANTLRParser::

+panic(const char *msg)  // MR20 const

+{

+	/* MR23 */ printMessage(stderr, "ANTLR panic: %s\n", msg);

+	exit(PCCTS_EXIT_FAILURE);           // MR1

+}

+

+const ANTLRChar *ANTLRParser::          // MR1

+parserTokenName(int tok) {              // MR1

+	return token_tbl[tok];              // MR1

+}                                       // MR1

+

+void ANTLRParser::traceGuessDone(const ANTLRParserState *state) {

+

+  int   doIt=0;

+

+  if (traceCurrentRuleName == NULL) return;

+

+  if (traceOptionValue <= 0) {

+    doIt=0;

+  } else if (traceGuessOptionValue <= 0) {

+    doIt=0;

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    /* MR23 */ printMessage(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",

+        state->traceCurrentRuleName,

+        LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),

+        state->traceDepth);

+    if (state->guessing != 0) {

+      /* MR23 */ printMessage(stderr," (guess mode continues - an enclosing guess is still active)");

+    } else {

+      /* MR23 */ printMessage(stderr," (guess mode ends)");

+    };

+    /* MR23 */ printMessage(stderr,"\n");

+  };

+}

+

+void ANTLRParser::traceGuessFail() {

+

+  int   doIt=0;

+

+  if (traceCurrentRuleName == NULL) return;     /* MR21 */

+

+  if (traceOptionValue <= 0) {

+    doIt=0;

+  } else if (guessing && traceGuessOptionValue <= 0) {

+    doIt=0;

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    /* MR23 */ printMessage(stderr,"guess failed in %s\n",traceCurrentRuleName);

+  };

+}

+

+/* traceOption:

+     zero value turns off trace

+*/

+

+void ANTLRParser::tracein(const ANTLRChar * rule) {

+

+  int       doIt=0;

+

+  traceDepth++;

+  traceCurrentRuleName=rule;

+

+  if (traceOptionValue <= 0) {

+    doIt=0;

+  } else if (guessing && traceGuessOptionValue <= 0) {

+    doIt=0;

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    /* MR23 */ printMessage(stderr,"enter rule %s {\"%s\"} depth %d",

+            rule,

+            LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),

+            traceDepth);

+    if (guessing) /* MR23 */ printMessage(stderr," guessing");

+    /* MR23 */ printMessage(stderr,"\n");

+  };

+  return;

+}

+

+void ANTLRParser::traceout(const ANTLRChar * rule) {

+

+  int       doIt=0;

+

+  traceDepth--;

+

+  if (traceOptionValue <= 0) {

+    doIt=0;

+  } else if (guessing && traceGuessOptionValue <= 0) {

+    doIt=0;

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    /* MR23 */ printMessage(stderr,"exit rule %s {\"%s\"} depth %d",

+            rule,

+            LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),

+            traceDepth+1);

+    if (guessing) /* MR23 */ printMessage(stderr," guessing");

+    /* MR23 */ printMessage(stderr,"\n");

+  };

+}

+

+int ANTLRParser::traceOption(int delta) {

+

+    int     prevValue=traceOptionValue;

+

+    traceOptionValue=traceOptionValue+delta;

+

+    if (traceCurrentRuleName != NULL) {

+      if (prevValue <= 0 && traceOptionValue > 0) {

+        /* MR23 */ printMessage(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);

+      };

+      if (prevValue > 0 && traceOptionValue <= 0) {

+        /* MR23 */ printMessage(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);

+      };

+    };

+

+    return  prevValue;

+}

+

+int ANTLRParser::traceGuessOption(int delta) {

+

+    int     prevValue=traceGuessOptionValue;

+

+    traceGuessOptionValue=traceGuessOptionValue+delta;

+

+    if (traceCurrentRuleName != NULL) {

+      if (prevValue <= 0 && traceGuessOptionValue > 0) {

+        /* MR23 */ printMessage(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);

+      };

+      if (prevValue > 0 && traceGuessOptionValue <= 0) {

+        /* MR23 */ printMessage(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);

+      };

+    };

+    return prevValue;

+}

+

+// MR19 V.H. Simonis Defer Fetch feature

+

+void ANTLRParser::undeferFetch()

+{

+

+#ifdef ZZDEFER_FETCH

+    if (stillToFetch) {

+        for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) {

+    		NLA = inputTokens->getToken()->getType();

+    		dirty--;

+    		lap = (lap+1)&(LLk-1);

+        }

+        stillToFetch = 0;

+    }

+#else

+    return;

+#endif

+

+}

+

+int ANTLRParser::isDeferFetchEnabled()

+{

+#ifdef ZZDEFER_FETCH

+    return 1;

+#else

+    return 0;

+#endif

+}

+

+//MR23

+int ANTLRParser::printMessage(FILE* pFile, const char* pFormat, ...)

+{

+	va_list marker;

+	va_start( marker, pFormat );

+  	int iRet = printMessageV(pFile, pFormat, marker);

+	va_end( marker );

+	return iRet;

+}

+

+int ANTLRParser::printMessageV(FILE* pFile, const char* pFormat, va_list arglist) // MR23

+{

+  	return vfprintf(pFile, pFormat, arglist);

+}

+

+// MR23 Move semantic predicate error handling from macro to virtual function

+//

+// Called by the zzfailed_pred

+

+void ANTLRParser::failedSemanticPredicate(const char* predicate)

+{

+    printMessage(stdout,"line %d: semantic error; failed predicate: '%s'\n",

+    	LT(1)->getLine(), predicate);

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/AParser.h b/edk2/Tools/Source/TianoTools/Pccts/h/AParser.h
new file mode 100644
index 0000000..fe405f4
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/AParser.h
@@ -0,0 +1,376 @@
+/* ANTLRParser.h

+ *

+ * Define the generic ANTLRParser superclass, which is subclassed to

+ * define an actual parser.

+ *

+ * Before entry into this file: ANTLRTokenType must be set.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef APARSER_H_GATE

+#define APARSER_H_GATE

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+#include "pccts_setjmp.h"

+

+PCCTS_NAMESPACE_STD

+

+#include ATOKEN_H

+#include ATOKENBUFFER_H

+

+#ifdef ZZCAN_GUESS

+#ifndef ZZINF_LOOK

+#define ZZINF_LOOK

+#endif

+#endif

+

+

+#define NLA			(token_type[lap&(LLk-1)])/* --> next LA */

+

+typedef unsigned char SetWordType;

+

+/* Define external bit set stuff (for SetWordType) */

+#define EXT_WORDSIZE	(sizeof(char)*8)

+#define EXT_LOGWORDSIZE	3

+

+           /* s y n t a c t i c  p r e d i c a t e  s t u f f */

+

+#ifndef zzUSER_GUESS_HOOK

+#define zzUSER_GUESS_HOOK(seqFrozen,zzrv)

+#endif

+

+#ifndef zzUSER_GUESS_DONE_HOOK

+#define zzUSER_GUESS_DONE_HOOK(seqFrozen)

+#endif

+

+/* MR14 Add zzUSER_GUESS_FAIL_HOOK and related code */

+

+#define zzUSER_GUESS_FAIL_HOOK_INTERNAL zzUSER_GUESS_FAIL_HOOK(SeqFrozen)

+#ifndef zzUSER_GUESS_FAIL_HOOK

+#define zzUSER_GUESS_FAIL_HOOK(zzGuessSeq)

+#endif

+

+

+typedef struct _zzjmp_buf {

+			jmp_buf state;

+		} zzjmp_buf;

+

+/* these need to be macros not member functions */

+#define zzGUESS_BLOCK		ANTLRParserState zzst; int zzrv; int _marker; int zzGuessSeqFrozen;

+#define zzNON_GUESS_MODE	if ( !guessing )

+#define zzGUESS_FAIL		guess_fail();

+

+/*  Note:  zzGUESS_DONE does not execute longjmp() */

+

+#define zzGUESS_DONE		{zzrv=1; inputTokens->rewind(_marker); guess_done(&zzst);zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }

+#define zzGUESS				saveState(&zzst); \

+							guessing = 1; \

+                            zzGuessSeqFrozen = ++zzGuessSeq; \

+							_marker = inputTokens->mark(); \

+							zzrv = setjmp(guess_start.state); \

+                            zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \

+						    if ( zzrv ) zzGUESS_DONE

+

+#define zzTRACEdata     const ANTLRChar *zzTracePrevRuleName = NULL;

+

+#ifndef zzTRACEIN

+#define zzTRACEIN(r)	zzTracePrevRuleName=traceCurrentRuleName;tracein(r);

+#endif

+#ifndef zzTRACEOUT

+#define zzTRACEOUT(r)	traceout(r);traceCurrentRuleName=zzTracePrevRuleName;

+#endif

+

+                  /* a n t l r  p a r s e r  d e f */

+

+struct ANTLRParserState {

+	/* class variables */

+	zzjmp_buf guess_start;

+	int guessing;

+

+	int inf_labase;

+	int inf_last;

+

+	int dirty;

+

+    int             traceOptionValue;       // MR10

+    int             traceGuessOptionValue;  // MR10

+    const ANTLRChar *traceCurrentRuleName;  // MR10

+    int             traceDepth;             // MR10

+

+};

+

+/* notes:

+ *

+ * multiple inheritance is a cool way to include what stuff is needed

+ * in this structure (like guess stuff).  however, i'm not convinced that

+ * multiple inheritance works correctly on all platforms.  not that

+ * much space is used--just include all possibly useful members.

+ *

+ * the class should also be a template with arguments for the lookahead

+ * depth and so on.  that way, more than one parser can be defined (as

+ * each will probably have different lookahead requirements).  however,

+ * am i sure that templates work?  no, i'm not sure.

+ *

+ * no attributes are maintained and, hence, the 'asp' variable is not

+ * needed.  $i can still be referenced, but it refers to the token

+ * associated with that rule element.  question: where are the token's

+ * stored if not on the software stack?  in local variables created

+ * and assigned to by antlr.

+ */

+class ANTLRParser {

+protected:

+	/* class variables */

+	static SetWordType bitmask[sizeof(SetWordType)*8];

+	static char eMsgBuffer[500];

+

+protected:

+	int LLk;					// number of lookahead symbols (old LL_K)

+	int demand_look;

+	ANTLRTokenType eofToken;			// when do I stop during resynch()s

+	int bsetsize;           			// size of bitsets created by ANTLR in

+        								// units of SetWordType

+

+	ANTLRTokenBuffer *inputTokens;	//place to get input tokens

+

+	zzjmp_buf guess_start;		// where to jump back to upon failure

+	int guessing;				// if guessing (using (...)? predicate)

+

+	// infinite lookahead stuff

+	int can_use_inf_look;		// set by subclass (generated by ANTLR)

+	int inf_lap;

+	int inf_labase;

+	int inf_last;

+	int *_inf_line;

+

+	const ANTLRChar **token_tbl; // pointer to table of token type strings MR20 const

+

+	int dirty;					// used during demand lookahead

+

+	ANTLRTokenType *token_type;		// fast reference cache of token.getType()

+//	ANTLRLightweightToken **token;	// the token with all its attributes

+	int lap;

+	int labase;

+#ifdef ZZDEFER_FETCH

+	int stillToFetch;                               // MR19 V.H. Simonis

+#endif

+

+private:

+	void fill_inf_look();

+

+protected:

+	virtual void guess_fail() {                         // MR9 27-Sep-97 make virtual

+        traceGuessFail();                               // MR10

+        longjmp(guess_start.state, 1); }                // MR9

+	virtual void guess_done(ANTLRParserState *st) {     // MR9 27-Sep-97 make virtual

+         restoreState(st); }                            // MR9

+	virtual int guess(ANTLRParserState *);              // MR9 27-Sep-97 make virtual

+	void look(int);

+    int _match(ANTLRTokenType, ANTLRChar **, ANTLRTokenType *,

+			   _ANTLRTokenPtr *, SetWordType **);

+    int _setmatch(SetWordType *, ANTLRChar **, ANTLRTokenType *,

+			   _ANTLRTokenPtr *, SetWordType **,

+			   SetWordType * tokclassErrset /* MR23 */);

+    int _match_wsig(ANTLRTokenType);

+    int _setmatch_wsig(SetWordType *);

+    virtual void consume();

+    virtual void resynch(SetWordType *wd,SetWordType mask); // MR21

+	void prime_lookahead();

+	virtual void tracein(const ANTLRChar *r);              // MR10

+	virtual void traceout(const ANTLRChar *r);             // MR10

+	static unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);}	// x % EXT_WORDSIZE // MR9

+	static unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;}	// x / EXT_WORDSIZE // MR9

+	int set_deg(SetWordType *);

+	int set_el(ANTLRTokenType, SetWordType *);

+	virtual void edecode(SetWordType *);				// MR1

+	virtual void FAIL(int k, ...);					    // MR1

+    int                 traceOptionValue;                           // MR10

+    int                 traceGuessOptionValue;                      // MR10

+    const ANTLRChar     *traceCurrentRuleName;                      // MR10

+    int                 traceDepth;                                 // MR10

+    void                traceReset();                               // MR10

+    virtual void        traceGuessFail();                           // MR10

+    virtual void        traceGuessDone(const ANTLRParserState *);   // MR10

+    int                 zzGuessSeq;                                 // MR10

+

+public:

+	ANTLRParser(ANTLRTokenBuffer *,

+				int k=1,

+				int use_inf_look=0,

+				int demand_look=0,

+				int bsetsize=1);

+	virtual ~ANTLRParser();

+

+	virtual void init();

+	

+	ANTLRTokenType LA(int i)

+	{

+//

+//  MR14 demand look will always be 0 for C++ mode

+//

+////	return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] :

+////						token_type[(lap+(i)-1)&(LLk-1)];

+

+// MR19 V.H. Simonis Defer fetch feature

+

+#ifdef ZZDEFER_FETCH

+      undeferFetch();

+#endif

+	  return token_type[(lap+(i)-1)&(LLk-1)];

+	}

+	_ANTLRTokenPtr LT(int i);

+

+	void setEofToken(ANTLRTokenType t)	{ eofToken = t; }

+	ANTLRTokenType getEofToken() const  { return eofToken; }    // MR14

+

+	void noGarbageCollectTokens()	{ inputTokens->noGarbageCollectTokens(); }

+	void garbageCollectTokens()		{ inputTokens->garbageCollectTokens(); }

+

+    virtual void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup,

+					 SetWordType *eset, ANTLRTokenType etok, int k);

+	virtual void saveState(ANTLRParserState *);     // MR9 27-Sep-97 make virtual

+	virtual void restoreState(ANTLRParserState *);  // MR9 27-Sep-97 make virtual

+

+	virtual void panic(const char *msg); // MR20 const

+

+	static char *eMsgd(char *,int);

+	static char *eMsg(char *,char *);

+	static char *eMsg2(char *,char *,char *);

+

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23

+	virtual int printMessageV(FILE* pFile, const char* pFormat, va_list arglist); // MR23

+

+	void consumeUntil(SetWordType *st);

+	void consumeUntilToken(int t);

+

+	virtual int _setmatch_wdfltsig(SetWordType *tokensWanted,

+					 ANTLRTokenType tokenTypeOfSet,

+					 SetWordType *whatFollows);

+	virtual int _match_wdfltsig(ANTLRTokenType tokenWanted,

+					 SetWordType *whatFollows);

+	

+	const ANTLRChar * parserTokenName(int tok);			// MR1

+

+    int                 traceOptionValueDefault;        // MR11

+    int                 traceOption(int delta);         // MR11

+    int                 traceGuessOption(int delta);    // MR11

+

+//  MR8  5-Aug-97   S.Bochnak@microtool.com.pl

+//  MR8             Move resynch static local variable

+//  MR8               to class instance

+

+    int                 syntaxErrCount;                      // MR12

+    ANTLRTokenStream   *getLexer() const {                   // MR12

+      return inputTokens ? inputTokens->getLexer() : 0; }    // MR12

+protected:                                              // MR8

+    int     resynchConsumed;                            // MR8

+    char    *zzFAILtext; // workarea required by zzFAIL // MR9

+    void    undeferFetch();                             // MR19 V.H. Simonis

+    int     isDeferFetchEnabled();                      // MR19 V.H. Simonis

+    virtual void failedSemanticPredicate(const char* predicate); /* MR23 */

+};

+

+#define zzmatch(_t)							\

+	if ( !_match((ANTLRTokenType)_t, &zzMissText, &zzMissTok, \

+				 (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail;

+

+#define zzmatch_wsig(_t,handler)						\

+	if ( !_match_wsig((ANTLRTokenType)_t) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}

+

+#define zzsetmatch(_ts,_tokclassErrset)							\

+	if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \

+				 (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail;

+

+#define zzsetmatch_wsig(_ts, handler)				\

+	if ( !_setmatch_wsig(_ts) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}

+

+/* For the dflt signal matchers, a FALSE indicates that an error occurred

+ * just like the other matchers, but in this case, the routine has already

+ * recovered--we do NOT want to consume another token.  However, when

+ * the match was successful, we do want to consume hence _signal=0 so that

+ * a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;"

+ * preamble.

+ */

+#define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \

+	if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \

+		_signal = MismatchedToken;

+

+#define zzmatch_wdfltsig(tokenWanted, whatFollows) \

+	if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken;

+

+

+//  MR1  10-Apr-97 	zzfailed_pred() macro does not backtrack in guess mode.

+//  MR1	   		    Identification and correction due to J. Lilley

+//

+//  MR23            Call virtual method to report error.

+//  MR23            Provide more control over failed predicate action

+//                  without any need for user to worry about guessing internals.

+

+#ifndef zzfailed_pred

+#define zzfailed_pred(_p,_hasuseraction,_useraction) \

+  if (guessing) { \

+    zzGUESS_FAIL; \

+  } else { \

+    zzfailed_pred_action(_p,_hasuseraction,_useraction) \

+  }

+#endif

+

+//  MR23            Provide more control over failed predicate action

+//                  without any need for user to worry about guessing internals.

+//                  _hasuseraction == 0 => no user specified error action

+//                  _hasuseraction == 1 => user specified error action

+

+#ifndef zzfailed_pred_action

+#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \

+    if (_hasuseraction) { _useraction } else { failedSemanticPredicate(_p); }

+#endif

+

+#define zzRULE \

+		SetWordType *zzMissSet=NULL; ANTLRTokenType zzMissTok=(ANTLRTokenType)0;	\

+		_ANTLRTokenPtr zzBadTok=NULL; ANTLRChar *zzBadText=(ANTLRChar *)"";	\

+		int zzErrk=1,zzpf=0; \

+        zzTRACEdata \

+		ANTLRChar *zzMissText=(ANTLRChar *)"";

+

+#endif

+

+        /* S t a n d a r d  E x c e p t i o n  S i g n a l s */

+

+#define NoSignal			0

+#define MismatchedToken		1

+#define NoViableAlt			2

+#define NoSemViableAlt		3

+

+/* MR7  Allow more control over signalling                                  */

+/*        by adding "Unwind" and "SetSignal"                                */

+

+#define Unwind              4

+#define setSignal(newValue) *_retsignal=_signal=(newValue)

+#define suppressSignal       *_retsignal=_signal=0

+#define exportSignal        *_retsignal=_signal

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ASTBase.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/ASTBase.cpp
new file mode 100644
index 0000000..a94f080
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ASTBase.cpp
@@ -0,0 +1,256 @@
+/* Abstract syntax tree manipulation functions

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+#include "pccts_stdarg.h"

+

+PCCTS_NAMESPACE_STD

+

+#define ANTLR_SUPPORT_CODE

+

+#include "ASTBase.h"

+

+/* ensure that tree manipulation variables are current after a rule

+ * reference

+ */

+void

+ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)

+{

+	if ( *_sibling == NULL ) return;

+	if ( *_root == NULL ) *_root = *_sibling;

+	else if ( *_root != *_sibling ) (*_root)->_down = *_sibling;

+	if ( *_tail==NULL ) *_tail = *_sibling;

+	while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right;

+}

+

+/* add a child node to the current sibling list */

+void

+ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)

+{

+	if ( *_tail != NULL ) (*_tail)->_right = this;

+	else {

+		*_sibling = this;

+		if ( *_root != NULL ) (*_root)->_down = *_sibling;

+	}

+	*_tail = this;

+	if ( *_root == NULL ) *_root = *_sibling;

+}

+

+/* make a new AST node.  Make the newly-created

+ * node the root for the current sibling list.  If a root node already

+ * exists, make the newly-created node the root of the current root.

+ */

+void

+ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)

+{

+	if ( *_root != NULL )

+		if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root;

+	*_root = this;

+	(*_root)->_down = *_sibling;

+}

+

+/* Apply preorder_action(), etc.. to root then each sibling */

+//

+//  7-Apr-97 133MR1

+//	Fix suggested by Ron House (house@helios.usq.edu.au)

+//

+void

+ASTBase::preorder(void* pData /*= NULL*/ /* MR23 */)

+{

+	ASTBase *tree = this;

+

+	while ( tree!= NULL )

+	{

+		if ( tree->_down != NULL ) {

+			tree->preorder_before_action(pData); 		// MR1	

+		};

+		tree->preorder_action(pData);

+		if ( tree->_down!=NULL )

+		{

+			tree->_down->preorder(pData);

+			tree->preorder_after_action(pData);			// MR1

+		}

+		tree = tree->_right;

+	}

+}

+

+/* free all AST nodes in tree; apply func to each before freeing */

+void

+ASTBase::destroy()

+{

+   ASTBase* tree = this;

+   while (tree) {

+      if (tree->_down) tree->_down->destroy();

+

+      ASTBase* cur = tree;

+      tree = tree->_right;

+      delete cur;

+   }

+}

+

+/* build a tree (root child1 child2 ... NULL)

+ * If root is NULL, simply make the children siblings and return ptr

+ * to 1st sibling (child1).  If root is not single node, return NULL.

+ *

+ * Siblings that are actually siblins lists themselves are handled

+ * correctly.  For example #( NULL, #( NULL, A, B, C), D) results

+ * in the tree ( NULL A B C D ).

+ *

+ * Requires at least two parameters with the last one being NULL.  If

+ * both are NULL, return NULL.

+ */

+ASTBase *

+ASTBase::tmake(ASTBase *root, ...)

+{

+	va_list ap;

+	register ASTBase *child, *sibling=NULL, *tail=NULL /*MR23*/, *w;

+

+	va_start(ap, root);

+

+	if ( root != NULL )

+		if ( root->_down != NULL ) {  

+            root->reportOverwriteOfDownPointer();  /* MR21 Report problem which almost always an error */

+            return NULL;

+        }

+	child = va_arg(ap, ASTBase *);

+	while ( child != NULL )

+	{

+		for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */

+		if ( sibling == NULL ) {sibling = child; tail = w;}

+		else {tail->_right = child; tail = w;}

+		child = va_arg(ap, ASTBase *);

+	}

+	if ( root==NULL ) root = sibling;

+	else root->_down = sibling;

+	va_end(ap);

+	return root;

+}

+

+#ifndef PCCTS_NOT_USING_SOR

+

+/* tree duplicate */

+// forgot to check for NULL this (TJP July 23,1995)

+ASTBase *

+ASTBase::dup()

+{

+	ASTBase *u, *t=this;

+	

+	if ( t == NULL ) return NULL;

+/*

+	u = new ASTBase;

+	*u = *t;

+*/

+	u = (ASTBase *)this->shallowCopy();

+	if ( t->_right!=NULL ) u->_right = t->_right->dup();

+	else u->_right = NULL;

+	if ( t->_down!=NULL ) u->_down = t->_down->dup();

+	else u->_down = NULL;

+	return u;

+}

+#endif

+

+//

+//  7-Apr-97 133MR1

+//  	     Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com)

+//

+/* tree duplicate */

+

+#ifndef PCCTS_NOT_USING_SOR

+

+ASTBase *

+ASTDoublyLinkedBase::dup()

+{

+	ASTDoublyLinkedBase *u, *t=this;

+	

+	if ( t == NULL ) return NULL;

+	u = (ASTDoublyLinkedBase *)this->shallowCopy();

+	u->_up = NULL;		/* set by calling invocation */

+	u->_left = NULL;

+	if (t->_right!=NULL) {						// MR1

+          u->_right=t->_right->dup();					// MR1

+	  ((ASTDoublyLinkedBase *)u->_right)->_left = u;		// MR1

+        } else {							// MR1

+	  u->_right = NULL;						// MR1

+        };								// MR1

+	if (t->_down!=NULL) {						// MR1

+  	  u->_down = t->_down->dup();					// MR1

+          ((ASTDoublyLinkedBase *)u->_down)->_up = u;			// MR1

+        } else {							// MR1

+	  u->_down = NULL;						// MR1

+        };								// MR1

+	return u;

+}

+

+#endif

+

+/*

+ * Set the 'up', and 'left' pointers of all nodes in 't'.

+ * Initial call is double_link(your_tree, NULL, NULL).

+ */

+void

+ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up)

+{

+    ASTDoublyLinkedBase *t = this;

+

+    t->_left = (ASTDoublyLinkedBase *) left;

+    t->_up = (ASTDoublyLinkedBase *) up;

+    if (t->_down != NULL)

+		((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t);

+    if (t->_right != NULL)

+		((ASTDoublyLinkedBase *)t->_right)->double_link(t, up);

+}

+

+// MR21 ASTBase::reportOverwriteOfDownPointer

+

+void ASTBase::reportOverwriteOfDownPointer()

+{

+    panic("Attempt to overwrite down pointer in ASTBase::tmake");

+}

+

+// MR21 ASTBase::panic

+

+void ASTBase::panic(const char *msg)

+{

+	/* MR23 */ printMessage(stderr,"ASTBase panic: %s\n", msg);

+	exit(PCCTS_EXIT_FAILURE);

+}

+

+#ifdef PCCTS_NOT_USING_SOR

+//MR23

+int ASTBase::printMessage(FILE* pFile, const char* pFormat, ...)

+{

+	va_list marker;

+	va_start( marker, pFormat );

+  	int iRet = vfprintf(pFile, pFormat, marker);

+	va_end( marker );

+	return iRet;

+}

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ASTBase.h b/edk2/Tools/Source/TianoTools/Pccts/h/ASTBase.h
new file mode 100644
index 0000000..912f4b8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ASTBase.h
@@ -0,0 +1,122 @@
+/* Abstract syntax tree

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ASTBase_H

+#define ASTBase_H

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+#include "pccts_stdlib.h"

+

+PCCTS_NAMESPACE_STD

+

+#ifndef PCCTS_NOT_USING_SOR

+#include "PCCTSAST.h"

+#endif

+

+/*

+ * Notes:

+ *

+ * To specify a copy constructor, subclass one of these classes and

+ * give the copy constructor.  To use dup(), you must define shallowCopy().

+ * shallowCopy() can use either a copy constructor or just copy the node

+ * itself.

+ */

+

+#ifdef PCCTS_NOT_USING_SOR

+class DllExportPCCTS ASTBase {

+#else

+class DllExportPCCTS ASTBase : public PCCTS_AST {

+#endif

+

+protected:

+	ASTBase *_right, *_down;

+

+public:

+

+#ifdef PCCTS_NOT_USING_SOR

+	ASTBase *right()	{ return _right; }

+	ASTBase *down()	    { return _down; }

+	void setRight(ASTBase *t)	{ _right = (ASTBase *)t; }

+	void setDown(ASTBase *t)	{ _down = (ASTBase *)t; }

+#else

+	PCCTS_AST *right()	{ return _right; }	// define the SORCERER interface

+	PCCTS_AST *down()	{ return _down; }

+	void setRight(PCCTS_AST *t)	{ _right = (ASTBase *)t; }

+	void setDown(PCCTS_AST *t)	{ _down = (ASTBase *)t; }

+#endif

+	ASTBase() { _right = _down = NULL; }

+	virtual ~ASTBase() { ; }

+#ifndef PCCTS_NOT_USING_SOR

+	virtual ASTBase *dup();

+#endif

+	void destroy();

+	void preorder(void* pData = NULL /* MR23 */);

+	static ASTBase *tmake(ASTBase *, ...);

+	static void link(ASTBase **, ASTBase **, ASTBase **);

+	void subchild(ASTBase **, ASTBase **, ASTBase **);

+	void subroot(ASTBase **, ASTBase **, ASTBase **);

+	virtual void preorder_action(void* /*pData*/ = NULL /* MR23 */) { ; }

+	virtual void preorder_before_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " ("); }

+	virtual void preorder_after_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " )"); }

+    virtual void panic(const char *msg);         /* MR21 */

+    virtual void reportOverwriteOfDownPointer(); /* MR21 */

+#ifdef PCCTS_NOT_USING_SOR

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23

+#endif

+};

+

+class DllExportPCCTS ASTDoublyLinkedBase : public ASTBase {

+protected:

+    ASTDoublyLinkedBase *_left, *_up;

+

+public:

+  void double_link(ASTBase *left, ASTBase *up);

+

+#ifndef PCCTS_NOT_USING_SOR

+  virtual ASTBase *dup();

+#endif

+

+#ifdef PCCTS_NOT_USING_SOR

+  ASTBase *left() { return _left; }

+  ASTBase *up() { return _up; }

+  void setLeft(ASTBase *t) { _left = (ASTDoublyLinkedBase *)t; }    // MR6

+  void setUp(ASTBase *t)   { _up = (ASTDoublyLinkedBase *)t; }	    // MR6

+#else

+  PCCTS_AST *left() { return _left; }

+  PCCTS_AST *up() { return _up; }

+  void setLeft(PCCTS_AST *t) { _left = (ASTDoublyLinkedBase *)t; }  // MR6

+  void setUp(PCCTS_AST *t)   { _up = (ASTDoublyLinkedBase *)t; }	// MR6

+#endif

+

+};

+

+class AST;	// announce that this class will be coming along shortly

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ATokPtr.h b/edk2/Tools/Source/TianoTools/Pccts/h/ATokPtr.h
new file mode 100644
index 0000000..75b4c86
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ATokPtr.h
@@ -0,0 +1,88 @@
+/* ATokPtr.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Written by Russell Quong June 30, 1995

+ * Adapted by Terence Parr to ANTLR stuff

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ATokPtr_h

+#define ATokPtr_h

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+

+PCCTS_NAMESPACE_STD

+

+// pointer to a reference counted object

+// robust in that an unused ANTLRTokenPtr can point to NULL.

+

+class ANTLRAbstractToken;

+

+class DllExportPCCTS ANTLRTokenPtr {

+public:

+    ANTLRTokenPtr(ANTLRAbstractToken *addr=NULL){ptr_ = addr; ref();}

+    ANTLRTokenPtr(const ANTLRTokenPtr &lhs)	{ptr_ = lhs.ptr_; lhs.ref();}

+    ~ANTLRTokenPtr();

+

+    // use ANTLRTokenPtr as a pointer to ANTLRToken

+//

+//  8-Apr-97	MR1	Make operator -> a const member function

+//			  as well as some other member functions

+//

+    ANTLRAbstractToken *operator-> () const { return ptr_; }		// MR1

+//

+//  7-Apr-97 133MR1

+//	     Fix suggested by Andreas Magnusson

+//			(Andreas.Magnusson@mailbox.swipnet.se)

+    void operator = (const ANTLRTokenPtr & lhs);		    	// MR1

+    void operator = (ANTLRAbstractToken *addr);

+    int operator != (const ANTLRTokenPtr &q) const	    		// MR1 // MR11 unsigned -> int

+	{ return this->ptr_ != q.ptr_; }

+    int operator == (const ANTLRTokenPtr &q) const  			// MR1 // MR11 unsigned -> int

+	{ return this->ptr_ == q.ptr_; }

+    int operator == (const ANTLRAbstractToken *addr) const      // MR11

+    { return this->ptr_ == addr; }

+    int operator != (const ANTLRAbstractToken *addr) const      // MR11

+    { return this->ptr_ != addr; }

+

+    void ref() const;

+    void deref();

+

+protected:

+    ANTLRAbstractToken *ptr_;

+};

+

+//typedef ANTLRTokenPtr _ANTLRTokenPtr;

+

+/*

+ * Since you cannot redefine operator->() to return one of the user's

+ * token object types, we must down cast.  This is a drag.  Here's

+ * a macro that helps.  template: "mytoken(a-smart-ptr)->myfield".

+ */

+#define mytoken(tk) ((ANTLRToken *)(tk.operator->()))

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ATokPtrImpl.h b/edk2/Tools/Source/TianoTools/Pccts/h/ATokPtrImpl.h
new file mode 100644
index 0000000..9c07cf5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ATokPtrImpl.h
@@ -0,0 +1,88 @@
+/*

+ * ATokPtrImpl.h (formerly ATokPtr.cpp)

+ *

+ * This is #included in ATokBuffer.cpp for historical reasons.

+ * It has been renamed because of problems with the .cpp extension

+ * when used with IDE.

+ *

+ *

+ * ANTLRToken MUST be defined before entry to this file.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Written by Russell Quong June 30, 1995

+ * Adapted by Terence Parr to ANTLR stuff

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#include "pcctscfg.h"

+

+PCCTS_NAMESPACE_STD

+

+#include "ATokPtr.h"

+

+void ANTLRTokenPtr::ref() const

+{

+    if (ptr_ != NULL) {

+		ptr_->ref();

+	}

+}

+

+void ANTLRTokenPtr::deref()

+{

+    if (ptr_ != NULL)

+    {

+		ptr_->deref();

+		if ( ptr_->nref()==0 )

+		{

+		    delete ptr_;

+			ptr_ = NULL;

+		}

+    }

+}

+

+ANTLRTokenPtr::~ANTLRTokenPtr()

+{

+    deref();

+}

+

+//

+//  8-Apr-97	MR1	Make operator -> a const member function

+//			  as weall as some other member functions

+//

+void ANTLRTokenPtr::operator = (const ANTLRTokenPtr & lhs)	// MR1

+{

+    lhs.ref();	// protect against "xp = xp"; ie same underlying object

+    deref();

+    ptr_ = lhs.ptr_;

+}

+

+void ANTLRTokenPtr::operator = (ANTLRAbstractToken *addr)

+{

+    if (addr != NULL) {

+	addr->ref();

+    }

+    deref();

+    ptr_ = addr;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/AToken.h b/edk2/Tools/Source/TianoTools/Pccts/h/AToken.h
new file mode 100644
index 0000000..6167c21
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/AToken.h
@@ -0,0 +1,325 @@
+/* ANTLRToken.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ATOKEN_H_GATE

+#define ATOKEN_H_GATE

+

+#include "pcctscfg.h"

+

+#include "pccts_string.h"

+#include "pccts_stdio.h"

+#include "pccts_stdlib.h"

+#include "pccts_stdarg.h" // MR23

+

+PCCTS_NAMESPACE_STD

+

+// MR9      RJV (JVincent@novell.com) Not needed for variable length strings

+

+//// MR9 #ifndef ANTLRCommonTokenTEXTSIZE

+//// MR9 #define ANTLRCommonTokenTEXTSIZE        	100

+//// MR9 #endif

+

+

+/* must define what a char looks like; can make this a class too */

+typedef char ANTLRChar;

+

+/* D E F I N E  S M A R T  P O I N T E R S */

+

+//#include ATOKPTR_H   not tested yet, leave out

+class ANTLRAbstractToken;

+typedef ANTLRAbstractToken *_ANTLRTokenPtr;

+

+class ANTLRAbstractToken {

+public:

+    virtual ~ANTLRAbstractToken() {;}

+    virtual ANTLRTokenType getType() const = 0;

+    virtual void setType(ANTLRTokenType t) = 0;

+    virtual int getLine() const = 0;

+    virtual void setLine(int line) = 0;

+    virtual ANTLRChar *getText() const = 0;

+    virtual void setText(const ANTLRChar *) = 0;

+

+    /* This function will disappear when I can use templates */

+	virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,

+										  ANTLRChar *text,

+										  int line) = 0;

+

+	/* define to satisfy ANTLRTokenBuffer's need to determine whether or

+	   not a token object can be destroyed.  If nref()==0, no one has

+	   a reference, and the object may be destroyed.  This function defaults

+	   to 1, hence, if you use deleteTokens() message with a token object

+	   not derived from ANTLRCommonRefCountToken, the parser will compile

+	   but will not delete objects after they leave the token buffer.

+    */

+

+	virtual unsigned nref() const { return 1; }     // MR11

+	virtual void ref() {;}

+	virtual void deref() {;}

+

+	virtual void panic(const char *msg)             // MR20 const

+		{

+			/* MR23 */ printMessage(stderr, "ANTLRAbstractToken panic: %s\n", msg);

+			exit(PCCTS_EXIT_FAILURE);

+		}

+

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...) // MR23

+		{

+			va_list marker;

+			va_start( marker, pFormat );

+  			int iRet = vfprintf(pFile, pFormat, marker);

+			va_end( marker );

+			return iRet;

+		}

+};

+

+/* This class should be subclassed.  It cannot store token type or text */

+

+class ANTLRRefCountToken : public ANTLRAbstractToken {

+public:

+#ifdef DBG_REFCOUNTTOKEN

+	static int ctor;

+	static int dtor;

+#endif

+protected:

+    unsigned refcnt_;

+#ifdef DBG_REFCOUNTTOKEN

+	char object[200];

+#endif

+

+public:

+

+	// MR23 - No matter what you do, you're hammered.

+	//        Don't give names to formals something breaks.

+	//		  Give names to formals and don't use them it breaks.

+

+#ifndef DBG_REFCOUNTTOKEN

+	ANTLRRefCountToken(ANTLRTokenType /* t MR23 */, const ANTLRChar * /* s MR23 */)

+#else

+	ANTLRRefCountToken(ANTLRTokenType t, const ANTLRChar * s)

+#endif

+

+#ifndef DBG_REFCOUNTTOKEN

+		{

+			refcnt_ = 0;

+		}

+#else

+	{

+		ctor++;

+		refcnt_ = 0;

+		if ( t==1 ) sprintf(object,"tok_EOF");

+		else sprintf(object,"tok_%s",s);

+		/* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor);

+	}

+#endif

+	ANTLRRefCountToken()

+#ifndef DBG_REFCOUNTTOKEN

+		{ refcnt_ = 0; }

+#else

+		{

+			ctor++;

+			refcnt_ = 0;

+			sprintf(object,"tok_blank");

+			/* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor);

+		}

+	virtual ~ANTLRRefCountToken()

+		{

+			dtor++;

+			if ( dtor>ctor ) /* MR23 */ printMessage(stderr, "WARNING: dtor>ctor\n");

+			/* MR23 */ printMessage(stderr, "dtor %s #%d\n", object, dtor);

+			object[0]='\0';

+		}

+#endif

+

+	// reference counting stuff needed by ANTLRTokenPtr.

+	// User should not access these; for C++ language reasons, we had

+	// to make these public.  Yuck.

+

+	void ref()		      { refcnt_++; }

+	void deref()	      { refcnt_--; }

+	unsigned nref()	const { return refcnt_; }   // MR11

+

+	virtual ANTLRAbstractToken *makeToken(ANTLRTokenType /*tt MR23*/,

+										  ANTLRChar * /*txt MR23*/,

+										  int /*line MR23*/)

+	{

+		panic("call to ANTLRRefCountToken::makeToken()\n");

+		return NULL;

+	}

+};

+

+class ANTLRCommonNoRefCountToken : public ANTLRAbstractToken {

+protected:

+	ANTLRTokenType _type;

+	int _line;

+	ANTLRChar *_text;               // MR9 RJV

+

+public:

+	ANTLRCommonNoRefCountToken(ANTLRTokenType t, const ANTLRChar *s)

+	{ setType(t); _line = 0; _text = NULL; setText(s); }

+	ANTLRCommonNoRefCountToken()

+	{ setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); }

+

+	~ANTLRCommonNoRefCountToken() { if (_text) delete [] _text; }  // MR9 RJV: Added Destructor to remove string

+

+	ANTLRTokenType getType() const 	{ return _type; }

+	void setType(ANTLRTokenType t)	{ _type = t; }

+	virtual int getLine() const		{ return _line; }

+	void setLine(int line)	    	{ _line = line; }

+	ANTLRChar *getText() const   	{ return _text; }

+    int getLength() const           { return strlen(getText()); }       // MR11

+

+// MR9 RJV: Added code for variable length strings to setText()

+

+	void setText(const ANTLRChar *s)

+	{	if (s != _text) {

+          if (_text) delete [] _text;

+          if (s != NULL) {

+         	_text = new ANTLRChar[strlen(s)+1];

+            if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed");

+            strcpy(_text,s);

+    	  } else {

+            _text = new ANTLRChar[1];

+            if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed");

+            strcpy(_text,"");

+          };

+        };

+	}

+

+	virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,

+										  ANTLRChar *txt,

+										  int line)

+		{

+			ANTLRAbstractToken *t = new ANTLRCommonNoRefCountToken;

+			t->setType(tt); t->setText(txt); t->setLine(line);

+			return t;

+		}

+

+// MR9 THM Copy constructor required when heap allocated string is used with copy semantics

+

+   ANTLRCommonNoRefCountToken (const ANTLRCommonNoRefCountToken& from) :

+         ANTLRAbstractToken(from) {

+ 	 setType(from._type);

+	 setLine(from._line);

+     _text=NULL;

+     setText(from._text);

+  };

+

+// MR9 THM operator =() required when heap allocated string is used with copy semantics

+

+   virtual ANTLRCommonNoRefCountToken& operator =(const ANTLRCommonNoRefCountToken& rhs) {

+

+//////  MR15 WatCom can't hack use of operator =()

+//////  Use this:  *( (ANTRLAbstractToken *) this)=rhs;

+

+     *( (ANTLRAbstractToken *) this ) = rhs;

+

+  	 setType(rhs._type);

+ 	 setLine(rhs._line);

+     setText(rhs._text);

+     return *this;

+   };

+};

+

+class ANTLRCommonToken : public ANTLRRefCountToken {

+protected:

+	ANTLRTokenType       _type;

+	int                  _line;

+	ANTLRChar           *_text;               // MR9 RJV:Added

+

+public:

+	ANTLRCommonToken(ANTLRTokenType t, const ANTLRChar *s) : ANTLRRefCountToken(t,s)

+		{ setType(t); _line = 0; _text = NULL; setText(s); }                    // MR9

+	ANTLRCommonToken()

+		{ setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); }   // MR9

+

+	virtual ~ANTLRCommonToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string

+

+	ANTLRTokenType getType() const 	{ return _type; }

+	void setType(ANTLRTokenType t)	{ _type = t; }

+	virtual int getLine() const		{ return _line; }

+	void setLine(int line)	    	{ _line = line; }

+	ANTLRChar *getText() const		{ return _text; }

+    int getLength() const           { return strlen(getText()); }       // MR11

+

+// MR9 RJV: Added code for variable length strings to setText()

+

+	void setText(const ANTLRChar *s)

+	{	if (s != _text) {

+          if (_text) delete [] _text;

+          if (s != NULL) {

+         	_text = new ANTLRChar[strlen(s)+1];

+            if (_text == NULL) panic("ANTLRCommonToken::setText new failed");

+            strcpy(_text,s);

+    	  } else {

+            _text = new ANTLRChar[1];

+            if (_text == NULL) panic("ANTLRCommonToken::setText new failed");

+            strcpy(_text,"");

+          };

+        };

+	}

+

+	virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,

+										  ANTLRChar *txt,

+										  int line)

+	{

+		ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt);

+		t->setLine(line);

+		return t;

+	}

+

+// MR9 THM Copy constructor required when heap allocated string is used with copy semantics

+

+   ANTLRCommonToken (const ANTLRCommonToken& from) :

+         ANTLRRefCountToken(from) {

+ 	 setType(from._type);

+	 setLine(from._line);

+     _text=NULL;

+     setText(from._text);

+  };

+

+// MR9 THM operator =() required when heap allocated string is used with copy semantics

+

+   virtual ANTLRCommonToken& operator =(const ANTLRCommonToken& rhs) {

+

+//////  MR15 WatCom can't hack use of operator =()

+//////  Use this instead:   *( (ANTRLRRefCountToken *) this)=rhs;

+

+     *( (ANTLRRefCountToken *) this) = rhs;

+

+  	 setType(rhs._type);

+ 	 setLine(rhs._line);

+     setText(rhs._text);

+     return *this;

+   };

+};

+

+// used for backward compatibility

+typedef ANTLRCommonToken ANTLRCommonBacktrackingToken;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ATokenBuffer.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/ATokenBuffer.cpp
new file mode 100644
index 0000000..9a2f2fc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ATokenBuffer.cpp
@@ -0,0 +1,374 @@
+/* ANTLRTokenBuffer.cpp

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+typedef int ANTLRTokenType;	// fool AToken.h into compiling

+

+class ANTLRParser;					/* MR1 */

+

+#define ANTLR_SUPPORT_CODE

+

+#include "pcctscfg.h"

+

+#include ATOKENBUFFER_H

+#include APARSER_H		// MR23

+

+typedef ANTLRAbstractToken *_ANTLRTokenPtr;

+

+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)

+static unsigned char test[1000];

+#endif

+

+#ifdef DBG_REFCOUNTTOKEN

+int ANTLRRefCountToken::ctor = 0; /* MR23 */

+int ANTLRRefCountToken::dtor = 0; /* MR23 */

+#endif

+

+ANTLRTokenBuffer::

+ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */

+{

+	this->input = _input;

+	this->k = _k;

+	buffer_size = chunk_size = _chunk_size_formal;

+	buffer = (_ANTLRTokenPtr *)

+			 calloc(chunk_size+1,sizeof(_ANTLRTokenPtr ));

+	if ( buffer == NULL ) {

+		panic("cannot alloc token buffer");

+	}

+	buffer++;				// leave the first elem empty so tp-1 is valid ptr

+

+	tp = &buffer[0];

+	last = tp-1;

+	next = &buffer[0];

+	num_markers = 0;

+	end_of_buffer = &buffer[buffer_size-1];

+	threshold = &buffer[(int)(buffer_size/2)];	// MR23 - Used to be 1.0/2.0 !

+	_deleteTokens = 1; 	// assume we delete tokens

+	parser=NULL;				// MR5 - uninitialized reference

+}

+

+static void f() {;}

+ANTLRTokenBuffer::

+~ANTLRTokenBuffer()

+{

+	f();

+	// Delete all remaining tokens (from 0..last inclusive)

+	if ( _deleteTokens )

+	{

+		_ANTLRTokenPtr *z;

+		for (z=buffer; z<=last; z++)

+		{

+			(*z)->deref();

+//			z->deref();

+#ifdef DBG_REFCOUNTTOKEN

+					/* MR23 */ printMessage(stderr, "##########dtor: deleting token '%s' (ref %d)\n",

+							((ANTLRCommonToken *)*z)->getText(), (*z)->nref());

+#endif

+			if ( (*z)->nref()==0 )

+			{

+				delete (*z);

+			}

+		}

+	}

+

+	if ( buffer!=NULL ) free((char *)(buffer-1));

+}

+

+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)

+#include "pccts_stdio.h"

+PCCTS_NAMESPACE_STD

+#endif

+

+_ANTLRTokenPtr ANTLRTokenBuffer::

+getToken()

+{

+	if ( tp <= last )	// is there any buffered lookahead still to be read?

+	{

+		return *tp++;	// read buffered lookahead

+	}

+	// out of buffered lookahead, get some more "real"

+	// input from getANTLRToken()

+	if ( num_markers==0 )

+	{

+		if( next > threshold )

+		{

+#ifdef DBG_TBUF

+/* MR23 */ printMessage(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);

+#endif

+			makeRoom();

+		}

+	}

+	else {

+		if ( next > end_of_buffer )

+		{

+#ifdef DBG_TBUF

+/* MR23 */ printMessage(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);

+#endif

+			extendBuffer();

+		}

+	}

+	*next = getANTLRToken();

+	(*next)->ref();				// say we have a copy of this pointer in buffer

+	last = next;

+	next++;

+	tp = last;

+	return *tp++;

+}

+

+void ANTLRTokenBuffer::

+rewind(int pos)

+{

+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)

+	/* MR23 */ printMessage(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]);

+	test[pos]--;

+#endif

+	tp = &buffer[pos];

+	num_markers--;

+}

+

+/*

+ * This function is used to specify that the token pointers read

+ * by the ANTLRTokenBuffer should be buffered up (to be reused later).

+ */

+int ANTLRTokenBuffer::

+mark()

+{

+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)

+	test[tp-buffer]++;

+	/* MR23 */ printMessage(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]);

+#endif

+	num_markers++;

+	return tp - buffer;

+}

+

+/*

+ * returns the token pointer n positions ahead.

+ * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.

+ * This is used in conjunction with the ANTLRParser lookahead buffer.

+ *

+ * No markers are set or anything.  A bunch of input is buffered--that's all.

+ * The tp pointer is left alone as the lookahead has not been advanced

+ * with getToken().  The next call to getToken() will find a token

+ * in the buffer and won't have to call getANTLRToken().

+ *

+ * If this is called before a consume() is done, how_many_more_i_need is

+ * set to 'n'.

+ */

+_ANTLRTokenPtr ANTLRTokenBuffer::

+bufferedToken(int n)

+{

+//	int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;

+	int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1;

+	// Make sure that at least n tokens are available in the buffer

+#ifdef DBG_TBUF

+	/* MR23 */ printMessage(stderr, "bufferedToken(%d)\n", n);

+#endif

+	for (int i=1; i<=how_many_more_i_need; i++)

+	{

+		if ( next > end_of_buffer )	// buffer overflow?

+		{

+			extendBuffer();

+		}

+		*next = getANTLRToken();

+		(*next)->ref();		// say we have a copy of this pointer in buffer

+		last = next;

+		next++;

+	}

+	return tp[n - 1];

+}

+

+/* If no markers are set, the none of the input needs to be saved (except

+ * for the lookahead Token pointers).  We save only k-1 token pointers as

+ * we are guaranteed to do a getANTLRToken() right after this because otherwise

+ * we wouldn't have needed to extend the buffer.

+ *

+ * If there are markers in the buffer, we need to save things and so

+ * extendBuffer() is called.

+ */

+void ANTLRTokenBuffer::

+makeRoom()

+{

+#ifdef DBG_TBUF

+	/* MR23 */ printMessage(stderr, "in makeRoom.................\n");

+	/* MR23 */ printMessage(stderr, "num_markers==%d\n", num_markers);

+#endif

+/*

+	if ( num_markers == 0 )

+	{

+*/

+#ifdef DBG_TBUF

+		/* MR23 */ printMessage(stderr, "moving lookahead and resetting next\n");

+

+		_ANTLRTokenPtr *r;

+		/* MR23 */ printMessage(stderr, "tbuf = [");

+		for (r=buffer; r<=last; r++)

+		{

+			if ( *r==NULL ) /* MR23 */ printMessage(stderr, " xxx");

+			else /* MR23 */ printMessage(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText());

+		}

+		/* MR23 */ printMessage(stderr, " ]\n");

+

+		/* MR23 */ printMessage(stderr,

+		"before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer);

+#endif

+

+		// Delete all tokens from 0..last-(k-1) inclusive

+		if ( _deleteTokens )

+		{

+			_ANTLRTokenPtr *z;

+			for (z=buffer; z<=last-(k-1); z++)

+			{

+				(*z)->deref();

+//				z->deref();

+#ifdef DBG_REFCOUNTTOKEN

+					/* MR23 */ printMessage(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n",

+							((ANTLRCommonToken *)*z)->getText(), (*z)->nref());

+#endif

+				if ( (*z)->nref()==0 )

+				{

+					delete (*z);

+				}

+			}

+		}

+

+		// reset the buffer to initial conditions, but move k-1 symbols

+		// to the beginning of buffer and put new input symbol at k

+		_ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1;

+//		ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1;

+#ifdef DBG_TBUF

+		/* MR23 */ printMessage(stderr, "lookahead buffer = [");

+#endif

+		for (int i=1; i<=(k-1); i++)

+		{

+			*p++ = *q++;

+#ifdef DBG_TBUF

+			/* MR23 */ printMessage(stderr,

+			" '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());

+#endif

+		}

+#ifdef DBG_TBUF

+		/* MR23 */ printMessage(stderr, " ]\n");

+#endif

+		next = &buffer[k-1];

+		tp = &buffer[k-1];	// tp points to what will be filled in next

+		last = tp-1;

+#ifdef DBG_TBUF

+		/* MR23 */ printMessage(stderr,

+		"after: tp=%d, last=%d, next=%d\n",

+		tp-buffer, last-buffer, next-buffer);

+#endif

+/*

+	}

+	else {

+		extendBuffer();

+	}

+*/

+}

+

+/* This function extends 'buffer' by chunk_size and returns with all

+ * pointers at the same relative positions in the buffer (the buffer base

+ * address could have changed in realloc()) except that 'next' comes

+ * back set to where the next token should be stored.  All other pointers

+ * are untouched.

+ */

+void

+ANTLRTokenBuffer::

+extendBuffer()

+{

+	int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;

+#ifdef DBG_TBUF

+	/* MR23 */ printMessage(stderr, "extending physical buffer\n");

+#endif

+	buffer_size += chunk_size;

+	buffer = (_ANTLRTokenPtr *)

+		realloc((char *)(buffer-1),

+				(buffer_size+1)*sizeof(_ANTLRTokenPtr ));

+	if ( buffer == NULL ) {

+		panic("cannot alloc token buffer");

+	}

+	buffer++;				// leave the first elem empty so tp-1 is valid ptr

+

+	tp = buffer + save_tp;	// put the pointers back to same relative position

+	last = buffer + save_last;

+	next = buffer + save_next;

+	end_of_buffer = &buffer[buffer_size-1];

+	threshold = &buffer[(int)(buffer_size*(1.0/2.0))];

+

+/*

+	// zero out new token ptrs so we'll know if something to delete in buffer

+	ANTLRAbstractToken **p = end_of_buffer-chunk_size+1;

+	for (; p<=end_of_buffer; p++) *p = NULL;

+*/

+}

+

+ANTLRParser * ANTLRTokenBuffer::				// MR1

+setParser(ANTLRParser *p) {					// MR1

+  ANTLRParser	*old=parser;					// MR1

+  parser=p;							// MR1

+  input->setParser(p);						// MR1

+  return old;							// MR1

+}								// MR1

+								// MR1

+ANTLRParser * ANTLRTokenBuffer::				// MR1

+getParser() {							// MR1

+  return parser;						// MR1

+}								// MR1

+

+void ANTLRTokenBuffer::panic(const char *msg) // MR23

+{ 

+	if (parser)				//MR23

+		parser->panic(msg);	//MR23

+	else					//MR23

+		exit(PCCTS_EXIT_FAILURE); 

+} 

+

+//MR23

+int ANTLRTokenBuffer::printMessage(FILE* pFile, const char* pFormat, ...)

+{

+	va_list marker;

+	va_start( marker, pFormat );

+

+	int iRet = 0;

+	if (parser)

+		parser->printMessageV(pFile, pFormat, marker);

+	else

+  		iRet = vfprintf(pFile, pFormat, marker);

+

+	va_end( marker );

+	return iRet;

+}

+

+/* to avoid having to link in another file just for the smart token ptr

+ * stuff, we include it here.  Ugh.

+ *

+ * MR23 This causes nothing but problems for IDEs.

+ *      Change from .cpp to .h

+ *

+ */

+

+#include ATOKPTR_IMPL_H

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ATokenBuffer.h b/edk2/Tools/Source/TianoTools/Pccts/h/ATokenBuffer.h
new file mode 100644
index 0000000..1c008fd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ATokenBuffer.h
@@ -0,0 +1,109 @@
+/* ANTLRTokenBuffer.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ATOKENBUFFER_H_GATE

+#define ATOKENBUFFER_H_GATE

+

+#include "pcctscfg.h"

+

+#include "pccts_stdlib.h"

+

+PCCTS_NAMESPACE_STD

+

+#include ATOKEN_H

+#include ATOKENSTREAM_H

+

+/*

+ * The parser is "attached" to an ANTLRTokenBuffer via interface

+ * functions: getToken() and bufferedToken().  The object that actually

+ * consumes characters and constructs tokens is connected to the

+ * ANTLRTokenBuffer via interface function ANTLRTokenStream::getToken();

+ * where ANTLRTokenStream is really just a behavior (class with no data).

+ * C++ does not have this abstraction and hence we simply have come up

+ * with a fancy name for "void *".  See the note in ANTLRTokenStream.h on

+ * the "behavior" of ANTLRTokenStream.

+ */

+

+class ANTLRParser;					// MR1

+

+class DllExportPCCTS ANTLRTokenBuffer {

+protected:

+	ANTLRTokenStream *input;        // where do I get tokens

+	int buffer_size;

+	int chunk_size;

+	int num_markers;

+	int k;                          // Need at least this many tokens in buffer

+	_ANTLRTokenPtr *buffer;	// buffer used for arbitrary lookahead

+	_ANTLRTokenPtr *tp;        // pts into buffer; current token ptr

+	_ANTLRTokenPtr *last;      // pts to last valid token in buffer

+	_ANTLRTokenPtr *next;      // place to put token from getANTLRToken()

+	_ANTLRTokenPtr *end_of_buffer;

+	/* when you try to write a token past this and there are no markers

+	   set, then move k-1 tokens back to the beginning of the buffer.

+	   We want to stay away from the end of the buffer because we have

+	   to extend it if a marker is set and we reach the end (we cannot

+	   move tokens to the beginning of the buffer in this case).

+	 */

+	_ANTLRTokenPtr *threshold;

+	unsigned char _deleteTokens;

+

+	// This function is filled in by the subclass; it initiates fetch of input

+	virtual _ANTLRTokenPtr getANTLRToken() { return input->getToken(); }

+	void makeRoom();

+	void extendBuffer();

+

+public:

+	ANTLRTokenBuffer(ANTLRTokenStream *in, int k=1, int chksz=50);

+	virtual ~ANTLRTokenBuffer();

+	virtual _ANTLRTokenPtr getToken();

+	virtual void rewind(int pos);

+	virtual int mark();

+	virtual _ANTLRTokenPtr bufferedToken(int i);

+

+	void noGarbageCollectTokens()	{ _deleteTokens=0; }

+	void garbageCollectTokens()		{ _deleteTokens=1; }

+

+	virtual int bufferSize() { return buffer_size; }

+	virtual int minTokens() { return k; }

+	virtual void setMinTokens(int k_new) { k = k_new; }

+

+	virtual void panic(const char *msg); /* MR20 const */

+

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23

+

+protected:						// MR1

+	ANTLRParser	*parser;			// MR1

+public:							// MR1

+	ANTLRParser	*setParser(ANTLRParser *p);	// MR1

+	ANTLRParser	*getParser();			    // MR1

+    ANTLRTokenStream *getLexer() const {    // MR12

+      return input;}                        // MR12

+};

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ATokenStream.h b/edk2/Tools/Source/TianoTools/Pccts/h/ATokenStream.h
new file mode 100644
index 0000000..3dfea6e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ATokenStream.h
@@ -0,0 +1,51 @@
+/* ANTLRTokenStream.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ATOKENSTREAM_H_GATE

+#define ATOKENSTREAM_H_GATE

+

+#include "pcctscfg.h"

+

+/* This is really a behavior or protocol; it merely indicates the behavior

+ * required of the input and output of an ANTLRTokenBuffer.  You could

+ * subclass it, but you can also just pass any old pointer to ANTLRTokenBuffer

+ * with a type cast (in which case, your getANTLRToken() would have to

+ * explicitly cast the input pointer to your REAL type (typically your lexer)).

+ */

+

+class ANTLRParser;							// MR1

+

+class DllExportPCCTS ANTLRTokenStream {

+public:

+    virtual _ANTLRTokenPtr getToken() = 0;

+	virtual ANTLRParser * setParser(ANTLRParser * /*p MR23*/) {return 0; };   // MR12

+	virtual ANTLRParser * getParser() { return 0; };		        // MR12

+};

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/BufFileInput.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/BufFileInput.cpp
new file mode 100644
index 0000000..99d08a4
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/BufFileInput.cpp
@@ -0,0 +1,100 @@
+// FILE:        BufFileInput.cpp

+// AUTHOR:      Alexey Demakov (AVD) demakov@kazbek.ispras.ru

+// CREATION:    26-JAN-1998

+// DESCRIPTION: File Input Stream with lookahead for Scanner.

+//   See file BufFileInput.h for details

+

+// Change History:

+//

+//   22-Jun-1998    assert.h -> PCCTS_ASSERT_H

+//                  string.h -> PCCTS_STRING_H

+//

+//   28-May-1998    Add virtual destructor to release buffer.

+//

+//                  Add dummy definition for ANTLRTokenType

+//                  to allow compilation without knowing

+//                  token type codes.

+//

+//                  Manfred Kogler (km@cast.uni-linz.ac.at)

+//                  (1.33MR14)

+//

+//   20-Jul-1998    MR14a - Reorder initialization list for ctor.

+//

+

+enum ANTLRTokenType {TER_HATES_CPP=0, SO_DO_OTHERS=9999 };

+

+#include "pcctscfg.h"

+#include "pccts_assert.h"

+#include "pccts_string.h"

+

+PCCTS_NAMESPACE_STD

+

+#include "BufFileInput.h"

+

+BufFileInput::BufFileInput( FILE *f, int buf_size )

+: input( f ),

+  buf( new int[buf_size] ),

+  size( buf_size ),

+  start( 0 ),

+  len( 0 )

+{

+}

+

+BufFileInput::~BufFileInput()

+{

+  delete [] buf;

+}

+

+int BufFileInput::nextChar( void )

+{

+    if( len > 0 )

+    {

+        // get char from buffer

+        int c = buf[start];

+

+        if( c != EOF )

+        {

+            start++; start %= size;

+            len--;

+        }

+        return c;

+    } else {

+        // get char from file

+        int c = getc( input );

+

+        if( c == EOF )

+        {

+            // if EOF - put it in the buffer as indicator

+            buf[start] = EOF;

+            len++;

+        }

+        return c;

+    }

+}

+

+int BufFileInput::lookahead( char* s )

+{

+    int l = strlen( s );

+

+    assert( 0 < l && l <= size );

+

+    while( len < l )

+    {

+        int c = getc( input );

+

+        buf[ (start+len) % size ] = c;

+

+        len++;

+

+        if( c == EOF ) return 0;

+    }

+

+    for( int i = 0; i < l; i++ )

+    {

+        if( s[i] != buf[ (start+i) % size ] ) return 0;

+    }

+    return 1;

+}

+

+// End of file BufFileInput.cpp

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/BufFileInput.h b/edk2/Tools/Source/TianoTools/Pccts/h/BufFileInput.h
new file mode 100644
index 0000000..ea54c0e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/BufFileInput.h
@@ -0,0 +1,53 @@
+// FILE:        BufFileInput.h

+// AUTHOR:      Alexey Demakov (AVD) demakov@kazbek.ispras.ru

+// CREATION:    26-JAN-1998

+// DESCRIPTION: File Input Stream with lookahead for Scanner

+// Tested under Win32 with ANTLR 1.33 MR10 and MSVC 5.0

+

+// Change History:

+//

+//   28-May-1998    Add virtual destructor to release buffer

+//                  Manfred Kogler (km@cast.uni-linz.ac.at)

+//                  (1.33MR14)

+

+#ifndef BufFileInput_h

+#define BufFileInput_h

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+

+PCCTS_NAMESPACE_STD

+

+#include "DLexerBase.h"

+

+class DllExportPCCTS BufFileInput : public DLGInputStream

+{

+public:

+    // constructor

+    // f - input stream

+    // buf_size - size of buffer (maximal length for string in is_in)

+

+    BufFileInput(FILE *f, int buf_size = 8 );

+

+    virtual ~BufFileInput();

+

+    // gets next char from stream

+

+    virtual int nextChar( void );

+

+    // looks in stream and compares next l characters with s

+    // returns the result of comparision

+

+    int lookahead( char* s );

+

+private:

+    FILE *input; // input stream;

+    int* buf;    // buffer

+    int  size;   // size of buffer

+    int  start;  // position of the first symbol in buffer

+    int  len;    // count of characters in buffers

+};

+

+#endif

+// end of file BufFileInput.h

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/DLG_stream_input.h b/edk2/Tools/Source/TianoTools/Pccts/h/DLG_stream_input.h
new file mode 100644
index 0000000..d2147f5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/DLG_stream_input.h
@@ -0,0 +1,98 @@
+

+/************************************************************/

+/*															*/

+/*		Predefined char stream: Input from (c++) stream.	*/

+/*															*/

+/* By Hubert Holin (Hubert.Holin@Bigfoot.com), 1998.		*/

+/*															*/

+/* This is completely free stuff, do whatever you want with	*/

+/* it (but then, I will take no responsability for whatever	*/

+/* may happen if you do either... caveat emptor!).			*/

+/*															*/

+/************************************************************/

+

+#ifndef _DLG_STREAM_INPUT_H

+#define _DLG_STREAM_INPUT_H

+

+#include "pccts_istream.h"

+

+PCCTS_NAMESPACE_STD

+

+#ifndef DLGX_H

+#include "DLexerBase.h"

+#endif

+

+

+// NOTES:	The semantics of the copy constructor

+//			and the affectation operator may be unwaranted...

+//			and the stream may not be reset.

+//

+//			It would have been so much nicer for nextChar()

+//			to throw (of for the DLGInputStream to change status)

+//			upon hiting EOF than to return an "int"...

+

+template	<

+				class E,

+				class T = ::std::char_traits<E>

+			>

+class DLG_stream_input : public DLGInputStream

+{

+public:

+	

+						DLG_stream_input(::std::basic_istream<E,T> * p_input_stream)

+	:	input(p_input_stream)

+	{

+		// nothing to do!

+	};

+	

+						DLG_stream_input(const DLG_stream_input & a_recopier)

+	:	input(a_recopier.input)

+	{

+		// nothing to do!

+	};

+	

+	virtual				~DLG_stream_input()

+	{

+		this->purge();	// bloody templarized lookup...

+	};

+	

+	DLG_stream_input	operator = (const DLG_stream_input & a_affecter)

+	{

+		if (this != &a_affecter)

+		{

+			input = a_affecter.input;

+		}

+

+		return(*this);

+	};

+	

+	virtual int			nextChar()

+	{

+		E	extracted_stuff;

+		

+		input->get(extracted_stuff);

+		

+		if	(*input)

+		{

+			return(int(extracted_stuff));

+		}

+		else

+		{

+			return(EOF);

+		}

+	};

+	

+protected:

+	

+	::std::basic_istream<E,T> *	input;

+	

+private:

+	

+	void	purge()

+	{

+		// nothing to do!

+	};

+};

+

+#endif /* _DLG_STREAM_INPUT_H */

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/DLexer.h b/edk2/Tools/Source/TianoTools/Pccts/h/DLexer.h
new file mode 100644
index 0000000..37cac24
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/DLexer.h
@@ -0,0 +1,191 @@
+/* DLexer.h (formerly DLexer.cpp)

+ *

+ * This was renamed because the use of the .cpp extension caused problems

+ * with IDEs.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#define ZZINC {if ( track_columns ) (++_endcol);}

+

+#define ZZGETC {ch = input->nextChar(); cl = ZZSHIFT(ch);}

+

+#define ZZNEWSTATE	(newstate = dfa[state][cl])

+

+#ifndef ZZCOPY

+#define ZZCOPY	\

+	/* Truncate matching buffer to size (not an error) */	\

+	if (nextpos < lastpos){				\

+		*(nextpos++) = ch;			\

+	}else{							\

+		bufovf = 1;					\

+	}

+#endif

+

+void DLGLexer::

+mode( int m )

+{

+	/* points to base of dfa table */

+	if (m<MAX_MODE){

+		automaton = m;

+		/* have to redo class since using different compression */

+		cl = ZZSHIFT(ch);

+	}else{

+		sprintf((char *)ebuf,"Invalid automaton mode = %d ",m);

+		errstd(ebuf);

+	}

+}

+

+ANTLRTokenType DLGLexer::

+nextTokenType(void)

+{

+	register int state, newstate;

+	/* last space reserved for the null char */

+	register DLGChar *lastpos;

+	ANTLRTokenType tk;

+

+skip:

+	bufovf = 0;

+	lastpos = &_lextext[_bufsize-1];

+	nextpos = _lextext;

+	_begcol = _endcol+1;

+more:

+	_begexpr = nextpos;

+	if ( interactive ) {

+		/* interactive version of automaton */

+		/* if there is something in ch, process it */

+		state = newstate = dfa_base[automaton];

+		if (charfull){

+			ZZINC;

+			ZZCOPY;

+			ZZNEWSTATE;

+		}

+		while (alternatives[newstate]){

+			state = newstate;

+			ZZGETC;

+			ZZINC;

+			ZZCOPY;

+			ZZNEWSTATE;

+		}

+		/* figure out if last character really part of token */

+		if ((state != dfa_base[automaton]) && (newstate == DfaStates)){

+			charfull = 1;

+			--nextpos;

+		}else{

+			charfull = 0;

+			state = newstate;

+		}

+		*(nextpos) = '\0';

+		/* Able to transition out of start state to some non err state?*/

+		if ( state == dfa_base[automaton] ){

+			/* make sure doesn't get stuck */

+			advance();

+		}

+	}

+	else { /* non-interactive version of automaton */

+		if (!charfull)

+			advance();

+		else

+			ZZINC;

+		state = dfa_base[automaton];

+		while (ZZNEWSTATE != DfaStates) {

+			state = newstate;

+			ZZCOPY;

+			ZZGETC;

+			ZZINC;

+		}

+		charfull = 1;

+		if ( state == dfa_base[automaton] ){

+			if (nextpos < lastpos){

+				*(nextpos++) = ch;

+			}else{

+				bufovf = 1;

+			}

+			*nextpos = '\0';

+			/* make sure doesn't get stuck */

+			advance();

+		}else{

+			*nextpos = '\0';

+		}

+	}

+	if ( track_columns ) _endcol -= charfull;

+	_endexpr = nextpos -1;

+	add_erase = 0;

+#ifdef OLD

+	tk = (ANTLRTokenType)

+		 (*actions[accepts[state]])(this);	// must pass this manually

+											// actions is not a [] of pointers

+											// to member functions.

+#endif

+	tk = (this->*actions[accepts[state]])();

+

+// MR1

+// MR1 11-Apr-97  Help for tracking DLG results

+// MR1

+

+#ifdef DEBUG_LEXER

+

+/* MR1 */        if (debugLexerFlag) {

+/* MR1 */	   if (parser != NULL) {

+/* MR1 */	     /* MR23 */ printMessage(stdout, "\ntoken name=%s",parser->parserTokenName(tk));

+/* MR1 */	   } else {

+/* MR1 */	     /* MR23 */ printMessage(stdout, "\ntoken nnumber=%d",tk);

+/* MR1 */	   };

+/* MR1 */	   /* MR23 */ printMessage(stdout, " lextext=(%s) mode=%d",

+/* MR1 */		 (_lextext[0]=='\n' && _lextext[1]==0) ?

+/* MR1 */			"newline" : _lextext,

+/* MR1 */				automaton);

+/* MR1 */          if (interactive && !charfull) {

+/* MR1 */	     /* MR23 */ printMessage(stdout, " char=empty");

+/* MR1 */          } else {

+/* MR1 */	     if (ch=='\n') {

+/* MR1 */	       /* MR23 */ printMessage(stdout, " char=newline");

+/* MR1 */	     } else {

+/* MR1 */	       /* MR23 */ printMessage(stdout, " char=(%c)",ch);

+/* MR1 */	     };

+/* MR1 */	   };

+/* MR1 */	   /* MR23 */ printMessage(stdout, " %s\n",

+/* MR1 */		 (add_erase==1 ? "skip()" :

+/* MR1 */		  add_erase==2 ? "more()" :

+/* MR1 */		  ""));

+/* MR1 */        };

+

+#endif

+

+	switch (add_erase) {

+		case 1: goto skip;

+		case 2: goto more;

+	}

+	return tk;

+}

+

+void DLGLexer::

+advance()

+{

+	if ( input==NULL ) err_in();

+	ZZGETC; charfull = 1; ZZINC;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/DLexerBase.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/DLexerBase.cpp
new file mode 100644
index 0000000..b218afc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/DLexerBase.cpp
@@ -0,0 +1,302 @@
+/* DLGLexerBase.c

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+#include "pccts_stdlib.h"

+

+PCCTS_NAMESPACE_STD

+

+/* I have to put this here due to C++ limitation

+ * that you can't have a 'forward' decl for enums.

+ * I hate C++!!!!!!!!!!!!!!!

+ */

+

+// MR1

+// MR1  10-Apr-97  133MR1  Prevent use of varying sizes for the

+// MR1  			ANTLRTokenType enum

+// MR1

+

+enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE,		// MR1

+					 WITH_SOME_GOOD_IDEAS=9999};	// MR1

+

+#define ANTLR_SUPPORT_CODE

+

+#include "pcctscfg.h"

+#include DLEXERBASE_H

+#include APARSER_H		// MR23

+

+DLGLexerBase::

+DLGLexerBase(DLGInputStream *in,

+	     unsigned bufsize,

+	     int _interactive,

+	     int _track_columns)

+{

+	this->_bufsize = bufsize;

+	this->_lextext = new DLGChar[_bufsize];

+	if ( this->_lextext==NULL ) {

+	    panic("text buffer is NULL");

+	}

+	this->_begexpr = this->_endexpr = NULL;

+	this->ch = this->bufovf = 0;

+	this->nextpos = NULL;

+	this->cl = 0;

+	this->add_erase = 0;

+	this->input = in;

+	this->_begcol = 0;

+	this->_endcol = 0;

+	this->_line = 1;

+	this->charfull = 0;

+	this->automaton = 0;

+	this->token_to_fill = NULL;

+	this->interactive = _interactive;

+	this->track_columns = _track_columns;

+	this->debugLexerFlag = 0;					// MR1

+	this->parser = NULL;						// MR1

+    this->lexErrCount=0;                        // MR11

+}

+

+// MR19  THM 

+

+void DLGLexerBase::reset()

+{

+	this->charfull = 0;

+	this->_begcol = 0;

+	this->_endcol = 0;

+	this->automaton = 0;

+	this->_line=1;

+	this->lexErrCount=0;

+}

+

+void DLGLexerBase::

+setInputStream( DLGInputStream *in )

+{

+	this->input = in;

+	_line = 1;

+	charfull = 0;

+}

+

+/* saves dlg state, but not what feeds dlg (such as file position) */

+void DLGLexerBase::

+saveState(DLGState *state)

+{

+	state->input = input;

+	state->interactive = interactive;

+	state->track_columns = track_columns;

+	state->auto_num = automaton;

+	state->add_erase = add_erase;

+	state->lookc = ch;

+	state->char_full = charfull;

+	state->begcol = _begcol;

+	state->endcol = _endcol;

+	state->line = _line;

+	state->lextext = _lextext;

+	state->begexpr = _begexpr;

+	state->endexpr = _endexpr;

+	state->bufsize = _bufsize;

+	state->bufovf = bufovf;

+	state->nextpos = nextpos;

+	state->class_num = cl;

+	state->debugLexerFlag = debugLexerFlag;				// MR1

+	state->parser = parser;						// MR1

+}

+

+void DLGLexerBase::

+restoreState(DLGState *state)

+{

+	input = state->input;

+	interactive = state->interactive;

+	track_columns = state->track_columns;

+	automaton = state->auto_num;

+	add_erase = state->add_erase;

+	ch = state->lookc;

+	charfull = state->char_full;

+	_begcol = state->begcol;

+	_endcol = state->endcol;

+	_line = state->line;

+	_lextext = state->lextext;

+	_begexpr = state->begexpr;

+	_endexpr = state->endexpr;

+	_bufsize = state->bufsize;

+	bufovf = state->bufovf;

+	nextpos = state->nextpos;

+	cl = state->class_num;

+	debugLexerFlag = state->debugLexerFlag;				// MR1

+	parser = state->parser;						// MR1

+}

+

+/* erase what is currently in the buffer, and get a new reg. expr */

+void DLGLexerBase::

+skip()

+{

+	add_erase = 1;

+}

+

+/* don't erase what is in the lextext buffer, add on to it */

+void DLGLexerBase::

+more()

+{

+	add_erase = 2;

+}

+

+/* substitute c for the reg. expr last matched and is in the buffer */

+void DLGLexerBase::

+replchar(DLGChar c)

+{

+	/* can't allow overwriting null at end of string */

+	if (_begexpr < &_lextext[_bufsize-1]){

+		*_begexpr = c;

+		*(_begexpr+1) = '\0';

+	}

+	_endexpr = _begexpr;

+	if (c != '\0') {

+		nextpos = _begexpr + 1;

+	}

+	else {

+		nextpos = _begexpr;	/* MR30 Zero terminates string. */

+	}

+}

+

+/* replace the string s for the reg. expr last matched and in the buffer */

+

+#ifdef _MSC_VER  // MR23

+//Turn off "assignment within conditional expression" warning

+#pragma warning(disable : 4706)

+#endif

+void DLGLexerBase::

+replstr(const DLGChar *s) /* MR20 const */

+{

+	register DLGChar *l= &_lextext[_bufsize -1];

+

+	nextpos = _begexpr;

+	if (s){

+		while ((nextpos <= l) && (*(nextpos++) = *(s++))){

+			/* empty */

+		}

+		/* correct for NULL at end of string */

+		nextpos--;

+	}

+	if ((nextpos <= l) && (*(--s) == 0)){

+		bufovf = 0;

+	}else{

+		bufovf = 1;

+	}

+	*(nextpos) = '\0';

+	_endexpr = nextpos - 1;

+}

+#ifdef _MSC_VER  // MR23

+#pragma warning(default: 4706)

+#endif

+

+void DLGLexerBase::

+errstd(const char *s)                               /* MR20 const */

+{

+        lexErrCount++;                              /* MR11 */

+        /* MR23 */ printMessage(stderr,

+                "%s near line %d (text was '%s')\n",

+                ((s == NULL) ? "Lexical error" : s),

+                _line,_lextext);

+}

+

+int DLGLexerBase::

+err_in()

+{

+	/* MR23 */ printMessage(stderr,"No input stream, function, or string\n");

+	/* return eof to get out gracefully */

+	return EOF;

+}

+

+ANTLRTokenType DLGLexerBase::

+erraction()

+{

+	errstd("invalid token");

+	advance();

+	skip();

+	return (ANTLRTokenType) 0;	// bogus, but satisfies compiler

+}

+

+_ANTLRTokenPtr DLGLexerBase::

+getToken()

+{

+	if ( token_to_fill==NULL ) panic("NULL token_to_fill");

+	ANTLRTokenType tt = nextTokenType();

+	_ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line);

+	return tk;

+}

+

+void DLGLexerBase::

+panic(const char *msg)      /* MR20 const */

+{

+	if (parser)				//MR23

+		parser->panic(msg);	//MR23

+	else					//MR23

+	{

+		/* MR23 */ printMessage(stderr, "DLG panic: %s\n", msg);

+	//

+	//  7-Apr-97 133MR1

+	//

+		exit(PCCTS_EXIT_FAILURE);					// MR1

+	}

+}

+

+ANTLRParser * DLGLexerBase::						// MR1

+setParser(ANTLRParser *p) {						// MR1

+  ANTLRParser	*oldValue=parser;					// MR1

+  parser=p;								// MR1

+  return oldValue;							// MR1

+}									// MR1

+									// MR1

+ANTLRParser * DLGLexerBase::						// MR1

+getParser() {								// MR1

+  return parser;							// MR1

+}									// MR1

+									// MR1

+int DLGLexerBase::							// MR1

+debugLexer(int newValue) {						// MR1

+  int	oldValue=debugLexerFlag;					// MR1

+  debugLexerFlag=newValue;						// MR1

+  return oldValue;							// MR1

+}									// MR1

+

+//MR23

+int DLGLexerBase::printMessage(FILE* pFile, const char* pFormat, ...)

+{

+	va_list marker;

+	va_start( marker, pFormat );

+

+	int iRet = 0;

+	if (parser)

+		parser->printMessageV(pFile, pFormat, marker);

+	else

+  		iRet = vfprintf(pFile, pFormat, marker);

+

+	va_end( marker );

+	return iRet;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/DLexerBase.h b/edk2/Tools/Source/TianoTools/Pccts/h/DLexerBase.h
new file mode 100644
index 0000000..db6cc18
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/DLexerBase.h
@@ -0,0 +1,198 @@
+/* DLGLexerBase.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef DLGX_H

+#define DLGX_H

+

+#include "pcctscfg.h"

+#include "pccts_stdio.h"

+

+PCCTS_NAMESPACE_STD

+

+#include ATOKEN_H

+#include ATOKENSTREAM_H

+

+class ANTLRParser;							// MR1

+

+/* must define what a char looks like; can make this a class too */

+typedef char DLGChar;

+

+/*  Can have it as a class too: (ack this looks weird; is it right?)

+class DllExportPCCTS DLGChar {

+private:

+	int c;

+public:

+	DLGChar(int ch) { c = ch; }

+	int atom() { return c; }

+};

+*/

+

+/* user must subclass this */

+class DllExportPCCTS DLGInputStream {

+public:

+	virtual int nextChar() = 0;

+};

+

+/* Predefined char stream: Input from FILE */

+class DllExportPCCTS DLGFileInput : public DLGInputStream {

+private:

+	int found_eof;

+	FILE *input;

+public:

+	DLGFileInput(FILE *f) { input = f; found_eof = 0; }

+	int nextChar() {

+			int c;

+			if ( found_eof ) return EOF;

+			else {

+				c=getc(input);

+				if ( c==EOF ) found_eof = 1;

+				return c;

+			}

+	}

+    void DLGFileReset(FILE *f) {input=f; found_eof = 0; };              // MR11

+};

+

+// MR9  Suggested by Bruce Guenter (bruceg@qcc.sk.ca)

+// MR9  Make DLGStringInput const correct

+

+/* Predefined char stream: Input from string */

+class DllExportPCCTS DLGStringInput : public DLGInputStream {

+private:

+	const DLGChar *input;                                           // MR9

+	const DLGChar *p;                                               // MR9

+public:

+	DLGStringInput(const DLGChar *s) { input = s; p = &input[0];}   // MR9

+	int nextChar()

+		{

+			if (*p) return (int) (unsigned char) *p++;              // MR14

+			else return EOF;

+		}

+

+    void DLGStringReset(const DLGChar *s) {input=s; p= &input[0]; }; // MR11 // MR16

+};

+

+class DllExportPCCTS DLGState {

+public:

+	DLGInputStream *input;

+	int interactive;

+	int track_columns;

+	int auto_num;

+	int add_erase;

+	int lookc;

+	int char_full;

+	int begcol, endcol;

+	int line;

+	DLGChar *lextext, *begexpr, *endexpr;

+	int bufsize;

+	int bufovf;

+	DLGChar *nextpos;

+	int	class_num;

+	int	debugLexerFlag;						// MR1

+	ANTLRParser *parser;						// MR1

+};

+

+/* user must subclass this */

+class DllExportPCCTS DLGLexerBase : public ANTLRTokenStream {

+public:

+	virtual ANTLRTokenType erraction();

+

+protected:

+	DLGInputStream *input;

+	int interactive;

+	int track_columns;

+	DLGChar	*_lextext;	/* text of most recently matched token */

+	DLGChar	*_begexpr;	/* beginning of last reg expr recogn. */

+	DLGChar	*_endexpr;	/* beginning of last reg expr recogn. */

+	int	_bufsize;		/* number of characters in lextext */

+	int	_begcol;		/* column that first character of token is in*/

+	int	_endcol;		/* column that last character of token is in */

+	int	_line;			/* line current token is on */

+	int	ch;				/* character to determine next state */

+	int	bufovf;			/* indicates that buffer too small for text */

+	int	charfull;

+	DLGChar	*nextpos;	/* points to next available position in lextext*/

+	int	cl;

+	int automaton;

+	int	add_erase;

+	DLGChar ebuf[70];

+	_ANTLRTokenPtr token_to_fill;

+

+	int	debugLexerFlag;						// MR1

+	ANTLRParser	*parser;					// MR1

+public:

+	virtual _ANTLRTokenPtr getToken();      // MR12 public

+	virtual void advance(void) = 0;

+	void	skip(void);		/* erase lextext, look for antoher token */

+	void	more(void);		/* keep lextext, look for another token */

+	void	mode(int k);	/* switch to automaton 'k' */

+	void	saveState(DLGState *);

+	void	restoreState(DLGState *);

+	virtual ANTLRTokenType nextTokenType(void)=0;/* get next token */

+	void	replchar(DLGChar c);	/* replace last recognized reg. expr. with

+									 a character */

+	void	replstr(const DLGChar *s);	/* replace last recognized reg. expr. with

+    									 a string */ /* MR20 const */

+        virtual int err_in();						// MR1

+	virtual void errstd(const char *);				// MR1  MR20 const

+	int		line()		{ return _line; }

+	void	set_line(int newValue)	{ _line=newValue; };		// MR1

+	virtual void newline()	{ _line++; }

+	DLGChar	*lextext()	{ return _lextext; }

+

+	int		begcol()	{ return _begcol; }

+	int		endcol()	{ return _endcol; }

+	void	set_begcol(int a)	{ _begcol=a; }

+	void	set_endcol(int a)	{ _endcol=a; }

+	DLGChar	*begexpr()	{ return _begexpr; }

+	DLGChar	*endexpr()	{ return _endexpr; }

+	int		bufsize()	{ return _bufsize; }

+

+	void	setToken(ANTLRAbstractToken *t)	{ token_to_fill = t; }

+

+	void	setInputStream(DLGInputStream *);

+	DLGLexerBase(DLGInputStream *in,

+				 unsigned bufsize=2000,

+				 int interactive=0,

+				 int track_columns=0);

+	void reset();									// MR19

+	virtual ~DLGLexerBase() { delete [] _lextext; }

+	virtual void panic(const char *msg);			// MR1  MR20 const

+	void	trackColumns() {

+				track_columns = 1;

+				this->_begcol = 0;

+				this->_endcol = 0;

+			};

+	virtual ANTLRParser *setParser(ANTLRParser *p);			// MR1

+	virtual ANTLRParser *getParser();				// MR1

+	virtual int debugLexer(int value);				// MR1

+    int     lexErrCount;                            // MR12

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23

+};

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/PBlackBox.h b/edk2/Tools/Source/TianoTools/Pccts/h/PBlackBox.h
new file mode 100644
index 0000000..d25b8d6
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/PBlackBox.h
@@ -0,0 +1,134 @@
+#ifndef PBLACKBOX_H

+#define PBLACKBOX_H

+

+/*

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+/* Completely rewritten by Chris Uzdavinis (chris@atdesk.com) for MR23 */

+

+#include "pcctscfg.h"

+

+#include "pccts_iostream.h"

+

+PCCTS_NAMESPACE_STD

+

+//  MR20 Added #include for "DLexerBase.h"

+

+#include "DLexerBase.h"

+

+//

+//  The default buffer size of the lexer is given by the

+//   second argument of the lexer's ctor.  It is optional

+//   and defaults to 2000

+//

+

+template<class Lexer, class Parser, class Token>

+class DllExportPCCTS ParserBlackBox {

+private:

+  // no copy construction allowed

+  ParserBlackBox(ParserBlackBox const &);

+

+  // no copy assignment allowed

+  ParserBlackBox & operator=(ParserBlackBox const &);

+  

+protected:

+  DLGFileInput *in;

+  Lexer *scan;

+  _ANTLRTokenPtr tok;

+  ANTLRTokenBuffer *pipe;

+  Parser *_parser;

+  FILE *file;

+  int openByBlackBox;    /* MR21 Don't close what we haven't opened */

+public:

+	

+  ParserBlackBox(FILE *f)

+    : in(0)

+    , scan(0)

+    , tok(0)

+    , pipe(0)

+    , _parser(0)

+    , file(0)

+    , openByBlackBox(0)

+  {

+    if (f == NULL)

+    {

+      cerr << "invalid file pointer\n"; 

+    }

+    else

+    {

+      openByBlackBox = 0;     /* MR21a */

+      file = f;

+      in = new DLGFileInput(f);

+      scan = new Lexer(in);

+      pipe = new ANTLRTokenBuffer(scan);

+      tok = new Token;

+      scan->setToken(tok);

+      _parser = new Parser(pipe);

+      _parser->init();

+    }

+  }

+  ParserBlackBox(char *fname)

+    : in(0)

+    , scan(0)

+    , tok(0)

+    , pipe(0)

+    , _parser(0)

+    , file(0)

+    , openByBlackBox(0)

+  {

+    FILE *f = fopen(fname, "r");

+    if ( f==NULL ) {

+      openByBlackBox = 0;

+      cerr << "cannot open " << fname << "\n"; return;

+    }

+    else {

+      openByBlackBox = 1;

+      file = f;

+      in = new DLGFileInput(f);

+      scan = new Lexer(in);

+      pipe = new ANTLRTokenBuffer(scan);

+      tok = new Token;

+      scan->setToken(tok);

+      _parser = new Parser(pipe);

+      _parser->init();

+    }

+  }

+	

+  ~ParserBlackBox()

+  {

+    delete in; delete scan; delete pipe; delete _parser; delete tok;

+    if (1 == openByBlackBox) {

+      fclose(file);

+    }

+  }

+

+  Parser *parser()	   { return _parser; }

+  Lexer  *getLexer()     { return scan; }

+};

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/PCCTSAST.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/PCCTSAST.cpp
new file mode 100644
index 0000000..a8249cd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/PCCTSAST.cpp
@@ -0,0 +1,684 @@
+/*

+ * PCCTSAST.C

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public

+ * domain.  An individual or company may do whatever they wish with

+ * source code distributed with SORCERER or the code generated by

+ * SORCERER, including the incorporation of SORCERER, or its output, into

+ * commerical software.

+ *

+ * We encourage users to develop software with SORCERER.  However, we do

+ * ask that credit is given to us for developing SORCERER.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like SORCERER and have developed a nice tool with the

+ * output, please mention that you developed it using SORCERER.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * SORCERER 1.00B14 and ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * AHPCRC, University of Minnesota

+ * 1992-2000

+ */

+

+#define ANTLR_SUPPORT_CODE

+

+#include "pcctscfg.h"

+

+#include "PCCTSAST.h"

+#include "pccts_stdarg.h"

+

+PCCTS_NAMESPACE_STD

+

+#include <ctype.h>

+

+//#include "SList.h"

+

+               /* String Scanning/Parsing Stuff */

+

+const char *PCCTS_AST::scan_token_tbl[] = {     /* MR20 const */

+	"invalid",	/*	0 */

+	"LPAREN",	/*	1 */

+	"RPAREN",	/*	2 */

+	"PERCENT",	/*	3 */

+	"INT",		/*	4 */

+	"COLON",	/*	5 */

+	"POUND",	/*	6 */

+	"PERIOD",	/*	7 */

+};

+

+void PCCTS_AST::

+addChild(PCCTS_AST *t)

+{

+	if ( t==NULL ) return;

+	PCCTS_AST *s = down();

+	if ( s!=NULL )

+	{

+		while ( s->right()!=NULL ) s = s->right();

+		s->setRight(t);

+	}

+	else

+		this->setDown(t);

+}

+

+void PCCTS_AST::

+lisp(FILE *f)

+{

+	if ( down() != NULL ) /* MR23 */ printMessage(f," (");

+	lisp_action(f);

+	if ( down()!=NULL ) down()->lisp(f);

+	if ( down() != NULL ) /* MR23 */ printMessage(f," )");

+	if ( right()!=NULL ) right()->lisp(f);

+}

+

+/* build a tree (root child1 child2 ... NULL)

+ * If root is NULL, simply make the children siblings and return ptr

+ * to 1st sibling (child1).  If root is not single node, return NULL.

+ *

+ * Siblings that are actually sibling lists themselves are handled

+ * correctly.  For example #( NULL, #( NULL, A, B, C), D) results

+ * in the tree ( NULL A B C D ).

+ *

+ * Requires at least two parameters with the last one being NULL.  If

+ * both are NULL, return NULL.

+ *

+ * The down() and right() down/right pointers are used to make the tree.

+ */

+PCCTS_AST *PCCTS_AST::

+make(PCCTS_AST *rt, ...)

+{

+	va_list ap;

+	register PCCTS_AST *child, *sibling=NULL, *tail=NULL /*MR23*/, *w;

+	PCCTS_AST *root;

+

+	va_start(ap, rt);

+	root = rt;

+

+	if ( root != NULL )

+		if ( root->down() != NULL ) return NULL;

+	child = va_arg(ap, PCCTS_AST *);

+	while ( child != NULL )

+	{

+		/* find end of child */

+		for (w=child; w->right()!=NULL; w=w->right()) {;}

+		if ( sibling == NULL ) {sibling = child; tail = w;}

+		else {tail->setRight(child); tail = w;}

+		child = va_arg(ap, PCCTS_AST *);

+	}

+	if ( root==NULL ) root = sibling;

+	else root->setDown(sibling);

+	va_end(ap);

+	return root;

+}

+

+/* The following push and pop routines are only used by ast_find_all() */

+

+void PCCTS_AST::

+_push(PCCTS_AST **st, int *sp, PCCTS_AST *e)

+{

+	(*sp)--;

+	require((*sp)>=0, "stack overflow");

+	st[(*sp)] = e;

+}

+

+PCCTS_AST *PCCTS_AST::

+_pop(PCCTS_AST **st, int *sp)

+{

+	PCCTS_AST *e = st[*sp];

+	(*sp)++;

+	require((*sp)<=MaxTreeStackDepth, "stack underflow");

+	return e;

+}

+

+/* Find all occurrences of u in t.

+ * 'cursor' must be initialized to 't'.  It eventually

+ * returns NULL when no more occurrences of 'u' are found.

+ */

+PCCTS_AST *PCCTS_AST::

+ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor)

+{

+	PCCTS_AST *sib;

+	/*** static ***/ PCCTS_AST *template_stack[MaxTreeStackDepth];  /* MR23 Remove "static" */

+	/*** static ***/ int tsp = MaxTreeStackDepth;                   /* MR23 Remove "static" */

+

+////static int nesting = 0;                                         /* MR23 Not referenced */

+

+	if ( *cursor == NULL ) return NULL;

+	if ( *cursor!=this ) sib = *cursor;

+	else {

+		/* else, first time--start at top of template 't' */

+		tsp = MaxTreeStackDepth;

+		sib = this;

+		/* bottom of stack is always a NULL--"cookie" indicates "done" */

+		_push(template_stack, &tsp, NULL);

+	}

+

+keep_looking:

+	if ( sib==NULL )	/* hit end of sibling list */

+	{

+		sib = _pop(template_stack, &tsp);

+		if ( sib == NULL ) { *cursor = NULL; return NULL; }

+	}

+

+	if ( sib->type() != u->type() )

+	{

+		/* look for another match */

+		if ( sib->down()!=NULL )

+		{

+			if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());

+			sib=sib->down();

+			goto keep_looking;

+		}

+		/* nothing below to try, try next sibling */

+		sib=sib->right();

+		goto keep_looking;

+	}

+

+	/* found a matching root node, try to match what's below */

+	if ( match_partial(sib, u) )

+	{

+		/* record sibling cursor so we can pick up next from there */

+		if ( sib->down()!=NULL )

+		{

+			if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());

+			*cursor = sib->down();

+		}

+		else if ( sib->right()!=NULL ) *cursor = sib->right();

+		else *cursor = _pop(template_stack, &tsp);

+		return sib;

+	}

+

+	/* no match, keep searching */

+	if ( sib->down()!=NULL )

+	{

+		if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());

+		sib=sib->down();

+	}

+	else sib = sib->right();	/* else, try to right if zip below */

+	goto keep_looking;

+}

+

+/* are two trees exactly alike? */

+int PCCTS_AST::

+match(PCCTS_AST *u)

+{

+	PCCTS_AST *t = this;

+	PCCTS_AST *sib;

+

+	if ( u==NULL ) return 0;

+

+	for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())

+	{

+		if ( sib->type() != u->type() ) return 0;

+		if ( sib->down()!=NULL )

+			if ( !sib->down()->match(u->down()) ) return 0;

+	}

+	return 1;

+}

+

+/* Is 'u' a subtree of 't' beginning at the root? */

+int PCCTS_AST::

+match_partial(PCCTS_AST *t, PCCTS_AST *u)

+{

+	PCCTS_AST *sib;

+

+	if ( u==NULL ) return 1;

+	if ( t==NULL ) return 0; /* MR23 removed unreachable code */

+

+	for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())

+	{

+		if ( sib->type() != u->type() ) return 0;

+		if ( sib->down()!=NULL )

+			if ( !match_partial(sib->down(), u->down()) ) return 0;

+	}

+	return 1;

+}

+

+#ifdef _MSC_VER  // MR23

+//Turn off "unreachable code" warning

+#pragma warning(disable : 4702)

+#endif

+/* Walk the template tree 't' (matching against 'this'), filling in the

+ * 'labels' array, and setting 'n' according to how many labels were matched.

+ */

+int PCCTS_AST::

+scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n)

+{

+	ScanAST *sib;

+	PCCTS_AST *u = this;

+

+	if ( u==NULL ) return 0;

+

+	for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())

+	{

+		/* make sure tokens match; token of '0' means wildcard match */

+		if ( sib->type() != u->type() && sib->type()!=0 ) return 0;

+		/* we have a matched token here; set label pointers if exists */

+		if ( sib->label_num>0 )

+		{

+			require(labels!=NULL, "label found in template, but no array of labels");

+			(*n)++;

+			*(labels[sib->label_num-1]) = u;

+		}

+		/* match what's below if something there and current node is not wildcard */

+		if ( sib->down()!=NULL && sib->type()!=0 )

+		{

+			if ( sib->down()==NULL ) 

+			{

+				if ( u->down()!=NULL ) 

+					return 0; 

+				else 

+					return 1;

+			}

+			if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0;

+		}

+	}

+	return 1;

+}

+#ifdef _MSC_VER  // MR23

+#pragma warning(default : 4702)

+#endif

+

+void PCCTS_AST::

+insert_after(PCCTS_AST *b)

+{

+	PCCTS_AST *end;

+	if ( b==NULL ) return;

+	/* find end of b's child list */

+	for (end=b; end->right()!=NULL; end=end->right()) {;}

+	end->setRight(this->right());

+	this->setRight(b);

+}

+

+void PCCTS_AST::

+append(PCCTS_AST *b)

+{

+	PCCTS_AST *end;

+	require(b!=NULL, "append: NULL input tree");

+	/* find end of child list */

+	for (end=this; end->right()!=NULL; end=end->right()) {;}

+	end->setRight(b);

+}

+

+PCCTS_AST *PCCTS_AST::

+tail()

+{

+	PCCTS_AST *end;

+	/* find end of child list */

+	for (end=this; end->right()!=NULL; end=end->right()) {;}

+	return end;

+}

+

+PCCTS_AST *PCCTS_AST::

+bottom()

+{

+	PCCTS_AST *end;

+	/* find end of child list */

+	for (end=this; end->down()!=NULL; end=end->down()) {;}

+	return end;

+}

+

+PCCTS_AST *PCCTS_AST::

+cut_between(PCCTS_AST *a, PCCTS_AST *b)

+{

+	PCCTS_AST *end, *ret;

+	if (a==NULL||b==NULL) return NULL;

+	/* find node pointing to b */

+	for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right())

+		{;}

+	if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected

+	end->setRight(NULL);	/* don't want it point to 'b' anymore */

+	ret = a->right();

+	a->setRight(b);

+	return ret;

+}

+

+#ifdef NOT_YET

+SList *PCCTS_AST::

+to_slist()

+{

+	SList *list = new SList;

+	PCCTS_AST *p;

+

+	for (p=this; p!=NULL; p=p->right())

+	{

+		list->add(p);

+	}

+	return list;

+}

+#endif

+

+void PCCTS_AST::

+tfree()

+{

+	PCCTS_AST *t = this;

+    if ( t->down()!=NULL ) t->down()->tfree();

+    if ( t->right()!=NULL ) t->right()->tfree();

+    delete t;

+}

+

+int PCCTS_AST::

+nsiblings()

+{

+	PCCTS_AST *t = this;

+	int n=0;

+

+	while ( t!=NULL )

+	{

+		n++;

+		t = t->right();

+	}

+	return n;

+}

+

+PCCTS_AST *PCCTS_AST::

+sibling_index(int i)

+{

+	PCCTS_AST *t = this;

+	int j=1;

+	require(i>0, "sibling_index: i<=0");

+

+	while ( t!=NULL )

+	{

+		if ( j==i ) return t;

+		j++;

+		t = t->right();

+	}

+	return NULL;

+}

+

+/* Assume this is a root node of a tree--

+ * duplicate that node and what's below; ignore siblings of root node.

+ */

+

+// MR9 23-Sep-97 RJV

+// MR9

+// MR9 RJV: Original version only duplicated the node and down elements.

+// MR9      Made copies of the pointers to sibling.

+// MR9      Changed call "down()->deepCopy()" to "down()->deepCopyBushy()"

+// MR9

+

+PCCTS_AST *PCCTS_AST::

+deepCopy()

+{

+	PCCTS_AST *u = this->shallowCopy();

+	if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());

+    u->setRight(NULL);

+	return u;

+}

+

+/* Copy all nodes including siblings of root. */

+PCCTS_AST *PCCTS_AST::

+deepCopyBushy()

+{

+	PCCTS_AST *u = this->shallowCopy();

+	/* copy the rest of the tree */

+	if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());

+	if ( right()!=NULL ) u->setRight(right()->deepCopyBushy());

+	return u;

+}

+

+void PCCTS_AST::

+scanast_free(ScanAST *t)

+{

+    if ( t == NULL ) return;

+    scanast_free( t->down() );

+    scanast_free( t->right() );

+    free( (char *) t );							// MR1

+}

+

+/*

+ * scan

+ *

+ * This function is like scanf(): it attempts to match a template

+ * against an input tree.  A variable number of tree pointers

+ * may be set according to the '%i' labels in the template string.

+ * For example:

+ *

+ *   t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",

+ *            &w, &x, &y, &z);

+ *

+ * Naturally, you'd want this converted from

+ *

+ *	 t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )",

+ *			  &w, &x, &y, &z);

+ *

+ * by SORCERER.

+ *

+ * This function call must be done withing a SORCERER file because SORCERER

+ * must convert the token references to the associated token number.

+ *

+ * This functions parses the template and creates trees which are then

+ * matched against the input tree.  The labels are set as they are

+ * encountered; hence, partial matches may leave some pointers set

+ * and some NULL.  This routines initializes all argument pointers to NULL

+ * at the beginning.

+ *

+ * This function returns the number of labels matched.

+ */

+int PCCTS_AST::

+ast_scan(char *templ, ...)

+{

+	va_list ap;

+	ScanAST *tmpl;

+	int n, i, found=0;

+	PCCTS_AST ***label_ptrs=NULL;

+

+	va_start(ap, templ);

+

+	/* make a ScanAST tree out of the template */

+	tmpl = stringparser_parse_scanast(templ, &n);

+

+	/* make an array out of the labels */

+	if ( n>0 )

+	{

+		label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **));

+		require(label_ptrs!=NULL, "scan: out of memory");

+		for (i=1; i<=n; i++)

+		{

+			label_ptrs[i-1] = va_arg(ap, PCCTS_AST **);

+			*(label_ptrs[i-1]) = NULL;

+		}

+	}

+

+	/* match the input tree against the template */

+	scanmatch(tmpl, label_ptrs, &found);

+

+	scanast_free(tmpl);

+	free( (char *) label_ptrs);					// MR1

+

+	return found;

+}

+

+ScanAST *PCCTS_AST::

+new_scanast(int tok)

+{

+    ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST));

+//

+//  7-Apr-97 133MR1

+//

+    if ( p == NULL )

+        panic("out of memory\n");			// MR23

+	p->_token = tok;

+	return p;

+}

+

+ScanAST *PCCTS_AST::

+stringparser_parse_scanast(char *templ, int *num_labels)

+{

+	StringLexer lex;

+	StringParser parser;

+	ScanAST *t;

+

+	stringlexer_init(&lex, templ);

+	stringparser_init(&parser, &lex);

+	t = stringparser_parse_tree(&parser);

+	*num_labels = parser.num_labels;

+	return t;

+}

+

+void PCCTS_AST::

+stringparser_match(StringParser *parser, int token)

+{

+	if ( parser->token != token ) panic("bad tree in scan()");

+}

+

+/*

+ * Match a tree of the form:

+ *		(root child1 child2 ... childn)

+ * or,

+ *		node

+ *

+ * where the elements are integers or labeled integers.

+ */

+ScanAST *PCCTS_AST::

+stringparser_parse_tree(StringParser *parser)

+{

+	ScanAST *t=NULL, *root, *child, *last=NULL /*MR23*/;

+

+	if ( parser->token != __POUND )

+	{

+		return stringparser_parse_element(parser);

+	}

+	stringparser_match(parser,__POUND);

+	parser->token = stringscan_gettok(parser->lexer);

+	stringparser_match(parser,__LPAREN);

+	parser->token = stringscan_gettok(parser->lexer);

+	root = stringparser_parse_element(parser);

+	while ( parser->token != __RPAREN )

+	{

+		child = stringparser_parse_element(parser);

+		if ( t==NULL ) { t = child; last = t; }

+		else { last->_right = child; last = child; }

+	}

+	stringparser_match(parser,__RPAREN);

+	parser->token = stringscan_gettok(parser->lexer);

+	root->_down = t;

+	return root;

+}

+

+ScanAST *PCCTS_AST::

+stringparser_parse_element(StringParser *parser)

+{

+	char ebuf[100];

+	int label = 0;

+

+	if ( parser->token == __POUND )

+	{

+		return stringparser_parse_tree(parser);

+	}

+	if ( parser->token == __PERCENT )

+	{

+		parser->token = stringscan_gettok(parser->lexer);

+		stringparser_match(parser,__INT);

+		label = atoi(parser->lexer->text);

+		parser->num_labels++;

+		if ( label==0 ) panic("%%0 is an invalid label");

+		parser->token = stringscan_gettok(parser->lexer);

+		stringparser_match(parser,__COLON);

+		parser->token = stringscan_gettok(parser->lexer);

+		/* can label tokens and wildcards */

+		if ( parser->token != __INT && parser->token != __PERIOD )

+			panic("can only label tokens");

+	}

+	if ( parser->token == __INT )

+	{

+		ScanAST *p = new_scanast(atoi(parser->lexer->text));

+		parser->token = stringscan_gettok(parser->lexer);

+		p->label_num = label;

+		return p;

+	}

+	if ( parser->token == __PERIOD )

+	{

+		ScanAST *p = new_scanast(0);	/* token of 0 is wildcard */

+		parser->token = stringscan_gettok(parser->lexer);

+		p->label_num = label;

+		return p;

+	}

+	sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token));

+	panic(ebuf);

+	return NULL;

+}

+

+void PCCTS_AST::

+stringparser_init(StringParser *parser, StringLexer *input)

+{

+	parser->lexer = input;

+	parser->token = stringscan_gettok(parser->lexer);

+	parser->num_labels = 0;

+}

+

+void PCCTS_AST::

+stringlexer_init(StringLexer *scanner, char *input)

+{

+	scanner->text[0]='\0';

+	scanner->input = input;

+	scanner->p = input;

+	stringscan_advance(scanner);

+}

+

+void PCCTS_AST::

+stringscan_advance(StringLexer *scanner)

+{

+	if ( *(scanner->p) == '\0' ) scanner->c = __StringScanEOF;

+	scanner->c = *(scanner->p)++;

+}

+

+int PCCTS_AST::

+stringscan_gettok(StringLexer *scanner)

+{

+	char *index = &scanner->text[0];

+	char ebuf[100]; /* MR23 Remove static */

+

+	while ( isspace(scanner->c) ) { stringscan_advance(scanner); }

+	if ( isdigit(scanner->c) )

+	{

+		int tok = __INT;

+		while ( isdigit(scanner->c) ) {

+			*index++ = (char) /* static_cast<char> */ (scanner->c);     // MR23

+			stringscan_advance(scanner);

+		}

+		*index = '\0';

+		return tok;

+	}

+	switch ( scanner->c )

+	{

+		case '#' : stringscan_advance(scanner); return __POUND;

+		case '(' : stringscan_advance(scanner); return __LPAREN;

+		case ')' : stringscan_advance(scanner); return __RPAREN;

+		case '%' : stringscan_advance(scanner); return __PERCENT;

+		case ':' : stringscan_advance(scanner); return __COLON;

+		case '.' : stringscan_advance(scanner); return __PERIOD;

+		case '\0' : return __StringScanEOF;

+		case __StringScanEOF : return __StringScanEOF;

+		default  :

+			sprintf(ebuf, "invalid char in scan: '%c'", scanner->c);

+			panic(ebuf);

+	}

+	return __StringScanEOF;	// never reached

+}

+

+const char *PCCTS_AST:: /* MR20 const */

+scan_token_str(int t)

+{

+	if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t];

+	else if ( t==__StringScanEOF ) return "<end-of-string>";

+	else return "<invalid-token>";

+}

+

+//MR23

+int PCCTS_AST::printMessage(FILE* pFile, const char* pFormat, ...)

+{

+	va_list marker;

+	va_start( marker, pFormat );

+  	int iRet = vfprintf(pFile, pFormat, marker);

+	va_end( marker );

+	return iRet;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/PCCTSAST.h b/edk2/Tools/Source/TianoTools/Pccts/h/PCCTSAST.h
new file mode 100644
index 0000000..3485da7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/PCCTSAST.h
@@ -0,0 +1,143 @@
+/* Abstract syntax tree

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef PCCTSAST_H

+#define PCCTSAST_H

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+#include "pccts_stdlib.h"

+

+PCCTS_NAMESPACE_STD

+

+//class SList;

+

+#define StringScanMaxText	50

+#define MaxTreeStackDepth	400

+

+//

+//  7-Apr-97 133MR1	signed int not accepted by AT&T cfront

+//

+typedef struct stringlexer {

+			int c;						// MR1

+			char *input;

+			char *p;

+			char text[StringScanMaxText];

+		} StringLexer;

+

+/* Define the structures needed for ast_scan() */

+typedef struct stringparser {

+			int token;

+			StringLexer *lexer;

+			int num_labels;

+		} StringParser;

+

+typedef struct _scanast {

+            struct _scanast *_right, *_down;

+            int _token;

+			int label_num;

+			int type() { return _token; }

+			struct _scanast *right() { return _right; }

+			struct _scanast *down() { return _down; }

+        } ScanAST;

+

+#define VALID_SCAN_TOKEN(t)		(t>=__LPAREN && t<=__PERIOD)

+

+class DllExportPCCTS PCCTS_AST {

+protected:

+	static const char *scan_token_tbl[];    /* MR20 const */

+	enum {

+	__LPAREN=1,

+	__RPAREN=2,

+	__PERCENT=3,

+	__INT=4,

+	__COLON=5,

+	__POUND=6,

+	__PERIOD=7,

+	__StringScanEOF=-1};

+

+protected:

+	const char *scan_token_str(int t);  /* MR20 const */

+	void stringlexer_init(StringLexer *scanner, char *input);

+	void stringparser_init(StringParser *, StringLexer *);

+	ScanAST *stringparser_parse_scanast(char *templ, int *n);

+	ScanAST *stringparser_parse_tree(StringParser *parser);

+	ScanAST *stringparser_parse_element(StringParser *parser);

+	void stringscan_advance(StringLexer *scanner);

+	int stringscan_gettok(StringLexer *scanner);

+	void _push(PCCTS_AST **st, int *sp, PCCTS_AST *e);

+	PCCTS_AST *_pop(PCCTS_AST **st, int *sp);

+	int match_partial(PCCTS_AST *t, PCCTS_AST *u);

+	int scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n);

+	void scanast_free(ScanAST *t);

+	ScanAST *new_scanast(int tok);

+	void stringparser_match(StringParser *parser, int type);

+	virtual PCCTS_AST *deepCopyBushy();

+

+public:

+	PCCTS_AST()	{;}

+	virtual ~PCCTS_AST() {;}

+

+	/* This group must be defined for SORCERER to work correctly */

+	virtual PCCTS_AST *right() = 0;

+	virtual PCCTS_AST *down() = 0;

+	virtual void setRight(PCCTS_AST *t) = 0;

+	virtual void setDown(PCCTS_AST *t) = 0;

+// we define these so ANTLR doesn't have to

+	virtual int type() { return 0; }

+	virtual void setType(int /*t MR23 */) {;}

+	virtual PCCTS_AST *shallowCopy() {panic("no shallowCopy() defined"); return NULL;}

+

+	/* These are not needed by ANTLR, but are support functions */

+	virtual PCCTS_AST *deepCopy();	// used by SORCERER in transform mode

+	virtual void addChild(PCCTS_AST *t);

+	virtual void lisp_action(FILE * /*f MR23 */) {;}

+	virtual void lisp(FILE *f);

+	static PCCTS_AST *make(PCCTS_AST *rt, ...);

+	virtual PCCTS_AST *ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor);

+	virtual int match(PCCTS_AST *u);

+	virtual void insert_after(PCCTS_AST *b);

+	virtual void append(PCCTS_AST *b);

+	virtual PCCTS_AST *tail();

+	virtual PCCTS_AST *bottom();

+	static  PCCTS_AST *cut_between(PCCTS_AST *a, PCCTS_AST *b);

+//	virtual SList *to_slist();

+	virtual void tfree();

+	int ast_scan(char *templ, ...);

+	virtual int nsiblings();

+	virtual PCCTS_AST *sibling_index(int i);

+

+	void require(int e,const char *err){ if ( !e ) panic(err); } /* MR20 const */

+	virtual void panic(const char *err)     // MR20 const

+		{ /* MR23 */ printMessage(stderr, "PCCTS_AST: %s\n", err); exit(PCCTS_EXIT_FAILURE); }

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23

+};

+

+#endif /* PCCTSAST_H */

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/SList.h b/edk2/Tools/Source/TianoTools/Pccts/h/SList.h
new file mode 100644
index 0000000..5b8bf97
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/SList.h
@@ -0,0 +1,72 @@
+#ifndef SList_h

+#define SList_h

+

+/*

+ * SList.h

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public

+ * domain.  An individual or company may do whatever they wish with

+ * source code distributed with SORCERER or the code generated by

+ * SORCERER, including the incorporation of SORCERER, or its output, into

+ * commerical software.

+ *

+ * We encourage users to develop software with SORCERER.  However, we do

+ * ask that credit is given to us for developing SORCERER.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like SORCERER and have developed a nice tool with the

+ * output, please mention that you developed it using SORCERER.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * PCCTS 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1992-2000

+ */

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+#include "pccts_stdlib.h"

+

+PCCTS_NAMESPACE_STD

+

+#include "PCCTSAST.h"

+

+class PCCTS_AST;

+

+class SListNode {

+protected:

+	void *_elem;			/* pointer to any kind of element */

+	SListNode *_next;

+public:

+	SListNode()				{_elem=_next=NULL;}

+	virtual ~SListNode()	{_elem=_next=NULL;}

+	void *elem()			{ return _elem; }

+	void setElem(void *e)	{ _elem = e; }

+	void setNext(SListNode *t)	{ _next = t; }

+	SListNode *next()		{ return _next; }

+};

+

+class SList {

+	SListNode *head, *tail;

+public:

+	SList() {head=tail=NULL;}

+	virtual ~SList() {head=tail=NULL;}

+	virtual void *iterate(SListNode **);

+	virtual void add(void *e);

+	virtual void lfree();

+	virtual PCCTS_AST *to_ast(SList list);

+	virtual void require(int e,char *err){ if ( !e ) panic(err); }

+	virtual void panic(char *err){ /* MR23 */ printMessage(stderr, "SList panic: %s\n", err); exit(PCCTS_EXIT_FAILURE); }

+	virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23

+};

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/antlr.h b/edk2/Tools/Source/TianoTools/Pccts/h/antlr.h
new file mode 100644
index 0000000..8066453
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/antlr.h
@@ -0,0 +1,807 @@
+/* antlr.h 

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ANTLR_H

+#define ANTLR_H

+

+#include "pcctscfg.h"

+

+#include "pccts_stdio.h"

+

+/* turn off warnings for unreferenced labels */

+

+#ifdef _MSC_VER

+#pragma warning(disable:4102)

+#endif

+

+/*

+ * Define all of the stack setup and manipulation of $i, #i variables.

+ *

+ *	Notes:

+ *		The type 'Attrib' must be defined before entry into this .h file.

+ */

+

+

+#ifdef __USE_PROTOS

+#include "pccts_stdlib.h"

+#else

+#ifdef VAXC

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif

+#endif

+#include "pccts_string.h"

+

+#if 0

+#include "set.h"

+#endif

+

+

+typedef int ANTLRTokenType;

+typedef unsigned char SetWordType;

+

+typedef char ANTLRChar;

+

+						/* G u e s s  S t u f f */

+

+#ifdef ZZCAN_GUESS

+#ifndef ZZINF_LOOK

+#define ZZINF_LOOK

+#endif

+#endif

+

+#ifdef ZZCAN_GUESS

+typedef struct _zzjmp_buf {

+			jmp_buf state;

+		} zzjmp_buf;

+#endif

+

+

+/* can make this a power of 2 for more efficient lookup */

+

+#ifndef ZZLEXBUFSIZE

+#define ZZLEXBUFSIZE	8000 /* MR22 raise from 2k to 8k */

+#endif

+

+#define zzOvfChk														\

+            if ( zzasp <= 0 )                                           \

+            {                                                           \

+                fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__);		\

+                exit(PCCTS_EXIT_FAILURE);                                               \

+            }

+

+#ifndef ZZA_STACKSIZE

+#define ZZA_STACKSIZE	400

+#endif

+#ifndef ZZAST_STACKSIZE

+#define ZZAST_STACKSIZE	400

+#endif

+

+#ifndef zzfailed_pred

+#ifdef ZZCAN_GUESS

+#define zzfailed_pred(_p,_hasuseraction,_useraction) \

+  if (zzguessing) { \

+    zzGUESS_FAIL; \

+  } else { \

+    zzfailed_pred_action(_p,_hasuseraction,_useraction); \

+  }

+#else

+#define zzfailed_pred(_p,_hasuseraction,_useraction) \

+    zzfailed_pred_action(_p,_hasuseraction,_useraction);

+#endif

+#endif

+

+/*  MR23            Provide more control over failed predicate action

+                    without any need for user to worry about guessing internals.

+                    _hasuseraction == 0 => no user specified error action

+                    _hasuseraction == 1 => user specified error action

+*/

+

+#ifndef zzfailed_pred_action

+#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \

+    if (_hasuseraction) { _useraction } \

+    else { fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p); }

+#endif

+

+/* MR19 zzchar_t additions */

+

+#ifdef LL_K

+#define LOOKAHEAD \

+	int zztokenLA[LL_K]; \

+	zzchar_t zztextLA[LL_K][ZZLEXBUFSIZE]; \

+	int zzlap = 0, zzlabase=0; /* labase only used for DEMAND_LOOK */

+#else

+#define LOOKAHEAD												\

+	int zztoken;

+#endif

+

+#ifndef zzcr_ast

+#define zzcr_ast(ast,attr,tok,text)

+#endif

+

+#ifdef DEMAND_LOOK

+#define DemandLookData  int zzdirty=1;

+#else

+#define DemandLookData

+#endif

+

+#ifndef zzUSER_GUESS_HOOK

+#define zzUSER_GUESS_HOOK(seqFrozen,zzrv)

+#endif

+

+#ifndef zzUSER_GUESS_DONE_HOOK

+#define zzUSER_GUESS_DONE_HOOK(seqFrozen)

+#endif

+

+						/* S t a t e  S t u f f */

+

+#ifdef ZZCAN_GUESS

+#define zzGUESS_BLOCK		zzantlr_state zzst; int zzrv; int zzGuessSeqFrozen;

+

+/* MR10 change zzGUESS: do zzGUESS_DONE when zzrv==1 after longjmp as in C++ mode */

+

+#define zzGUESS				zzsave_antlr_state(&zzst); \

+							zzguessing = 1; \

+                            zzGuessSeqFrozen=++zzGuessSeq; \

+							zzrv = setjmp(zzguess_start.state); \

+                            zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \

+                            if (zzrv) zzGUESS_DONE;

+#ifdef zzTRACE_RULES

+#define zzGUESS_FAIL		{ zzTraceGuessFail(); longjmp(zzguess_start.state, 1); }

+#else

+#define zzGUESS_FAIL		longjmp(zzguess_start.state, 1)

+#endif

+

+/* MR10 change zzGUESS_DONE: zzrv=1 to simulate longjmp() return value as in C++ mode */

+

+#define zzGUESS_DONE		{ zzrestore_antlr_state(&zzst); zzrv=1; zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }

+#define zzNON_GUESS_MODE	if ( !zzguessing )

+#define zzGuessData                                     \

+            zzjmp_buf zzguess_start;                    \

+            int zzguessing;

+#else

+#define zzGUESS_BLOCK

+#define zzGUESS

+#define zzGUESS_FAIL

+#define zzGUESS_DONE

+#define zzNON_GUESS_MODE

+#define zzGuessData

+#endif

+

+typedef struct _zzantlr_state {

+#ifdef ZZCAN_GUESS

+			zzjmp_buf guess_start;

+			int guessing;

+#endif

+			int asp;

+			int ast_sp;

+#ifdef ZZINF_LOOK

+			int inf_lap;	/* not sure we need to save this one */

+			int inf_labase;

+			int inf_last;

+

+/* MR6 	Gunnar Rxnning (gunnar@candleweb.no)                                */

+/* MR6	  Additional state needs to be saved/restored                       */

+/* MR6    Matching changes in err.h                                         */

+

+			int *inf_tokens;	                                     /* MR6 */

+			char **inf_text;	                                     /* MR6 */

+			char *inf_text_buffer;		                             /* MR6 */

+			int *inf_line;		                                     /* MR6 */

+#endif

+#ifdef DEMAND_LOOK

+			int dirty;

+#endif

+

+#ifdef LL_K

+			int tokenLA[LL_K];

+			char textLA[LL_K][ZZLEXBUFSIZE];

+			int lap;

+			int labase;

+#else

+			int token;

+			char text[ZZLEXBUFSIZE];

+#endif

+#ifdef zzTRACE_RULES

+            int     traceOptionValue;       /* MR10 */

+            int     traceGuessOptionValue;  /* MR10 */

+            char    *traceCurrentRuleName;  /* MR10 */

+            int     traceDepth;             /* MR10 */

+#endif

+

+		} zzantlr_state;

+

+#ifdef zzTRACE_RULES

+extern int  zzTraceOptionValueDefault;

+extern int  zzTraceOptionValue;

+extern int  zzTraceGuessOptionValue;

+extern char *zzTraceCurrentRuleName;

+extern int  zzTraceDepth;

+#endif

+

+extern int zzGuessSeq;                      /* MR10 */

+extern int zzSyntaxErrCount;                /* MR11 */

+extern int zzLexErrCount;                   /* MR11 */

+

+                 /* I n f i n i t e  L o o k a h e a d */

+

+

+#ifdef ZZINF_LOOK

+#define InfLookData	\

+	int *zzinf_tokens;	\

+	char **zzinf_text;	\

+	char *zzinf_text_buffer;	\

+	int *zzinf_line;        \

+	int zzinf_labase;	\

+	int zzinf_last;

+#else

+#define InfLookData

+#endif

+

+#ifdef ZZINF_LOOK

+

+#ifndef ZZINF_DEF_TEXT_BUFFER_SIZE

+#define ZZINF_DEF_TEXT_BUFFER_SIZE	    20000

+#endif

+#ifndef ZZINF_DEF_TOKEN_BUFFER_SIZE

+#define ZZINF_DEF_TOKEN_BUFFER_SIZE	    2000

+#endif

+/* WARNING!!!!!!

+ * ZZINF_BUFFER_TEXT_CHUNK_SIZE must be > sizeof(text) largest possible token.

+ */

+#ifndef ZZINF_BUFFER_TEXT_CHUNK_SIZE

+#define ZZINF_BUFFER_TEXT_CHUNK_SIZE	5000

+#endif

+#ifndef ZZINF_BUFFER_TOKEN_CHUNK_SIZE

+#define ZZINF_BUFFER_TOKEN_CHUNK_SIZE	1000

+#endif

+

+#if ZZLEXBUFSIZE > ZZINF_BUFFER_TEXT_CHUNK_SIZE

+#define ZZINF_BUFFER_TEXT_CHUNK_SIZE	ZZLEXBUFSIZE+5

+#endif

+

+/* make inf_look user-access macros */

+#ifdef LL_K

+#define ZZINF_LA_VALID(i)	(((zzinf_labase+i-1)-LL_K+1) <= zzinf_last)

+#define ZZINF_LA(i)			zzinf_tokens[(zzinf_labase+i-1)-LL_K+1]

+#define ZZINF_LATEXT(i)		zzinf_text[(zzinf_labase+i-1)-LL_K+1]

+/* MR6	In 1.33 vanilla the #define ZZINF_LINE(i) is was commented out	*/

+#define ZZINF_LINE(i)       zzinf_line[(zzinf_labase+i-1)-LL_K+1]

+#else

+#define ZZINF_LA_VALID(i)	(((zzinf_labase+i-1)) <= zzinf_last)

+#define ZZINF_LA(i)			zzinf_tokens[(zzinf_labase+i-1)]

+#define ZZINF_LATEXT(i)		zzinf_text[(zzinf_labase+i-1)]

+#endif

+

+#define inf_zzgettok _inf_zzgettok()

+extern void _inf_zzgettok();

+

+#endif	/* ZZINF_LOOK */

+

+

+#ifdef LL_K

+

+#ifdef __USE_PROTOS

+#define ANTLR_INFO	\

+	Attrib zzempty_attr(void) {static Attrib a; return a;} \

+	Attrib zzconstr_attr(int _tok, char *_text) \

+		{Attrib a; zzcr_attr((&a),_tok,_text); return a;} \

+	int zzasp=ZZA_STACKSIZE; \

+	char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \

+	Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \

+	InfLookData \

+    zzGuessData

+#else

+#define ANTLR_INFO												\

+	Attrib zzempty_attr() {static Attrib a; return a;}		    \

+	Attrib zzconstr_attr(_tok, _text) int _tok; char *_text;    \

+		{Attrib a; zzcr_attr((&a),_tok,_text); return a;}	    \

+	int zzasp=ZZA_STACKSIZE;					    \

+	char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n";  \

+	Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData			    \

+	InfLookData                                                 \

+    zzGuessData

+#endif

+

+#else

+

+#ifdef __USE_PROTOS

+#define ANTLR_INFO												\

+	Attrib zzempty_attr(void) {static Attrib a; return a;}			\

+	Attrib zzconstr_attr(int _tok, char *_text)				\

+		{Attrib a; zzcr_attr((&a),_tok,_text); return a;}		\

+	int zzasp=ZZA_STACKSIZE;						\

+	char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n";      \

+	Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData				\

+	InfLookData                                                             \

+    zzGuessData

+#else

+#define ANTLR_INFO												\

+	Attrib zzempty_attr() {static Attrib a; return a;}			\

+	Attrib zzconstr_attr(_tok, _text) int _tok; char *_text;                \

+		{Attrib a; zzcr_attr((&a),_tok,_text); return a;}		\

+	int zzasp=ZZA_STACKSIZE;						\

+	char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n";      \

+	Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData				\

+	InfLookData                                                             \

+    zzGuessData

+#endif

+	

+#endif /* LL_k */

+

+

+#ifdef ZZINF_LOOK

+

+#ifdef LL_K

+#ifdef DEMAND_LOOK

+#define zzPrimeLookAhead  {zzdirty=LL_K; zzlap = zzlabase = 0;}

+#else

+#define zzPrimeLookAhead  {zzlap = zzlabase = 0; zzfill_inf_look();\

+						  {int _i;  for(_i=1;_i<=LL_K; _i++)		\

+										{zzCONSUME;} zzlap = zzlabase = 0;}}

+#endif

+

+#else /* LL_K */

+

+#ifdef DEMAND_LOOK

+#define zzPrimeLookAhead  zzfill_inf_look(); zzdirty=1

+#else

+#define zzPrimeLookAhead  zzfill_inf_look(); inf_zzgettok

+

+#endif

+#endif	/* LL_K */

+

+#else	/* ZZINF_LOOK */

+

+#ifdef LL_K

+#ifdef DEMAND_LOOK

+#define zzPrimeLookAhead  {zzdirty=LL_K; zzlap = zzlabase = 0;}

+#else

+#define zzPrimeLookAhead  {int _i; zzlap = 0; for(_i=1;_i<=LL_K; _i++)		\

+										{zzCONSUME;} zzlap = 0;}

+#endif

+

+#else

+

+#ifdef DEMAND_LOOK

+#define zzPrimeLookAhead  zzdirty=1

+#else

+#define zzPrimeLookAhead  zzgettok()

+#endif

+#endif	/* LL_K */

+

+#endif	/* ZZINF_LOOK */

+

+

+#ifdef LL_K

+#define zzenterANTLRs(s)                            \

+        zzlextext = &(zztextLA[0][0]); zzrdstr( s ); zzPrimeLookAhead;

+#define zzenterANTLRf(f)							\

+		zzlextext = &(zztextLA[0][0]); zzrdfunc( f ); zzPrimeLookAhead;

+#define zzenterANTLR(f)							\

+		zzlextext = &(zztextLA[0][0]); zzrdstream( f ); zzPrimeLookAhead;

+#ifdef ZZINF_LOOK

+#define zzleaveANTLR(f)			free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);

+#define zzleaveANTLRf(f)	   	free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);

+#define zzleaveANTLRs(f)		free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);

+#else

+#define zzleaveANTLR(f)

+#define zzleaveANTLRf(f)

+#define zzleaveANTLRs(f)

+#endif

+

+#else

+

+#define zzenterANTLRs(s)                            \

+        {static char zztoktext[ZZLEXBUFSIZE];   \

+        zzlextext = zztoktext; zzrdstr( s ); zzPrimeLookAhead;}

+#define zzenterANTLRf(f)							\

+		{static char zztoktext[ZZLEXBUFSIZE];	\

+		zzlextext = zztoktext; zzrdfunc( f ); zzPrimeLookAhead;}

+#define zzenterANTLR(f)							\

+		{static char zztoktext[ZZLEXBUFSIZE];	\

+		zzlextext = zztoktext; zzrdstream( f ); zzPrimeLookAhead;}

+#ifdef ZZINF_LOOK

+#define zzleaveANTLR(f)			free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);

+#define zzleaveANTLRf(f)	   	free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);

+#define zzleaveANTLRs(f)		free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);

+#else

+#define zzleaveANTLR(f)

+#define zzleaveANTLRf(f)

+#define zzleaveANTLRs(f)

+#endif

+

+#endif

+

+/* MR19 Paul D. Smith (psmith@baynetworks.com)

+   Need to adjust AST stack pointer at exit.

+   Referenced in ANTLRx macros.

+*/

+

+#ifdef GENAST

+#define ZZAST_ADJUST ++zzast_sp;

+#else

+#define ZZAST_ADJUST

+#endif

+

+#define ANTLR(st, f)	zzbufsize = ZZLEXBUFSIZE;	\

+						zzenterANTLR(f);			\

+            {                                            \

+              zzBLOCK(zztasp1);                          \

+						  st; /* ++zzasp; Removed MR20 G. Hobbelt */     \

+						      /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \

+              /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */  \

+              zzEXIT_ANTLR(zztasp1 + 1);                 \

+            }                                            \

+						zzleaveANTLR(f);

+						

+#define ANTLRm(st, f, _m)	zzbufsize = ZZLEXBUFSIZE;	\

+						zzmode(_m);				\

+						zzenterANTLR(f);			\

+            {                                            \

+              zzBLOCK(zztasp1);                          \

+						  st; /* ++zzasp; Removed MR20 G. Hobbelt */     \

+						      /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \

+              /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */  \

+              zzEXIT_ANTLR(zztasp1 + 1);                 \

+            }                                            \

+						zzleaveANTLR(f);

+						

+#define ANTLRf(st, f)	zzbufsize = ZZLEXBUFSIZE;	\

+						zzenterANTLRf(f);			\

+            {                                            \

+              zzBLOCK(zztasp1);                          \

+						  st; /* ++zzasp; Removed MR20 G. Hobbelt */     \

+						      /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \

+              /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */  \

+              zzEXIT_ANTLR(zztasp1 + 1);                 \

+            }                                            \

+						zzleaveANTLRf(f);

+

+#define ANTLRs(st, s)   zzbufsize = ZZLEXBUFSIZE;	\

+                        zzenterANTLRs(s);           \

+            {                                            \

+              zzBLOCK(zztasp1);                          \

+						  st; /* ++zzasp; Removed MR20 G. Hobbelt */     \

+						      /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \

+              /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */  \

+              zzEXIT_ANTLR(zztasp1 + 1);                 \

+            }                                            \

+                        zzleaveANTLRs(s);

+

+#ifdef LL_K

+#define zztext		(&(zztextLA[zzlap][0]))

+#else

+#define zztext		zzlextext

+#endif

+

+

+					/* A r g u m e n t  A c c e s s */

+

+#define zzaCur			(zzaStack[zzasp])

+#define zzaRet			(*zzaRetPtr)

+#define zzaArg(v,n)		zzaStack[v-n]

+#define zzMakeAttr		{ zzNON_GUESS_MODE {zzOvfChk; --zzasp; zzcr_attr(&(zzaStack[zzasp]),LA(1),LATEXT(1));}}

+#ifdef zzdef0

+#define zzMake0			{ zzOvfChk; --zzasp; zzdef0(&(zzaStack[zzasp]));}

+#else

+#define zzMake0			{ zzOvfChk; --zzasp;}

+#endif

+#define zzaPush(_v)		{ zzOvfChk; zzaStack[--zzasp] = _v;}

+#ifndef zzd_attr

+#define zzREL(t)		zzasp=(t);		/* Restore state of stack */

+#else

+#define zzREL(t)		for (; zzasp<(t); zzasp++)				\

+						{ zzd_attr(&(zzaStack[zzasp])); }

+#endif

+

+

+#define zzsetmatch(_es,_tokclassErrset)						\

+	if ( !_zzsetmatch(_es, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail; /* MR23 */

+

+#ifdef ZZCAN_GUESS

+#define zzsetmatch_wsig(_es, handler)		\

+	if ( !_zzsetmatch_wsig(_es) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;}

+#else

+#define zzsetmatch_wsig(_es, handler)		\

+	if ( !_zzsetmatch_wsig(_es) ) {_signal=MismatchedToken; goto handler;}

+#endif

+

+#ifdef __USE_PROTOS

+extern int _zzsetmatch(SetWordType *, char **, char **, int *, int *, SetWordType **, SetWordType * /* MR23 */); 

+extern int _zzsetmatch_wsig(SetWordType *);

+#else

+extern int _zzsetmatch();

+extern int _zzsetmatch_wsig();

+#endif

+

+#define zzmatch(_t)							\

+	if ( !_zzmatch(_t, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail;

+

+#ifdef ZZCAN_GUESS

+#define zzmatch_wsig(_t,handler)			\

+	if ( !_zzmatch_wsig(_t) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;}

+#else

+#define zzmatch_wsig(_t,handler)			\

+	if ( !_zzmatch_wsig(_t) ) {_signal=MismatchedToken; goto handler;}

+#endif

+

+#ifdef __USE_PROTOS

+extern int _zzmatch(int, char **, char **, int *, int *, SetWordType **);

+extern int _zzmatch_wsig(int);

+#else

+extern int _zzmatch();

+extern int _zzmatch_wsig();

+#endif

+

+#define zzmatch_wdfltsig(_t,_f)			\

+	if ( !_zzmatch_wdfltsig(_t,_f) ) _signal=MismatchedToken;

+#define zzsetmatch_wdfltsig(tw,tt,wf)		\

+	if ( !_zzsetmatch_wdfltsig(tw,tt,wf) ) _signal=MismatchedToken;

+

+#ifdef __USE_PROTOS

+extern int _zzmatch_wdfltsig(int, SetWordType *);

+extern int _zzsetmatch_wdfltsig(SetWordType *tokensWanted,

+								int tokenTypeOfSet,

+								SetWordType *whatFollows);

+#else

+extern int _zzmatch_wdfltsig();

+extern int _zzsetmatch_wdfltsig();

+#endif

+

+#ifdef GENAST

+#define zzRULE		Attrib *zzaRetPtr = &(zzaStack[zzasp-1]);	\

+					SetWordType *zzMissSet=NULL; int zzMissTok=0;		\

+					int zzBadTok=0; char *zzBadText="";		\

+					int zzErrk=1,zzpf=0;					\

+                    zzTRACEdata \

+					char *zzMissText=""; zzASTVars

+#else

+#define zzRULE		Attrib *zzaRetPtr = &(zzaStack[zzasp-1]);	\

+					int zzBadTok=0; char *zzBadText="";		\

+					int zzErrk=1,zzpf=0;								\

+                    zzTRACEdata \

+					SetWordType *zzMissSet=NULL; int zzMissTok=0; char *zzMissText=""

+#endif

+

+#ifdef GENAST

+#define zzBLOCK(i)	int i = zzasp - 1; int zztsp = zzast_sp

+#define zzEXIT(i)	zzREL(i); zzastREL; zzNON_GUESS_MODE { zzastPush(*_root); }

+#define zzEXIT_ANTLR(i)	zzREL(i); zzastREL /* [i_a] added as we want this for the ANTLRx() macros */

+#define zzLOOP(i)	zzREL(i); zzastREL

+#else

+#define zzBLOCK(i)	int i = zzasp - 1

+#define zzEXIT(i)	zzREL(i)

+#define zzEXIT_ANTLR(i)	zzREL(i)           /* [i_a] added as we want this for the ANTLRx() macros */

+#define zzLOOP(i)	zzREL(i)

+#endif

+

+#ifdef LL_K

+

+#ifdef DEMAND_LOOK

+#define LOOK(_k)	{int i,stop=_k-(LL_K-zzdirty); for (i=1; i<=stop; i++)	\

+					zzCONSUME;}

+#define zzCONSUME	{zzgettok(); zzdirty--;							\

+					zzlap = (zzlap+1)&(LL_K-1);						\

+					zzlextext = &(zztextLA[zzlap][0]);}

+#else

+#ifdef ZZINF_LOOK

+#define zzCONSUME	{inf_zzgettok; 									\

+					zzlap = (zzlap+1)&(LL_K-1);						\

+					zzlextext = &(zztextLA[zzlap][0]);				\

+					}

+#else

+#define zzCONSUME	{zzgettok(); 									\

+					zzlap = (zzlap+1)&(LL_K-1);						\

+					zzlextext = &(zztextLA[zzlap][0]);}

+#endif /* ZZINF_LOOK */

+#endif /* DEMAND_LOOK */

+

+#else /* LL_K */

+

+#ifdef DEMAND_LOOK

+#define LOOK(_k)	if ( zzdirty) zzCONSUME;

+#ifdef ZZINF_LOOK

+#define zzCONSUME	inf_zzgettok; zzdirty=0;

+#else

+#define zzCONSUME	zzgettok(); zzdirty=0;

+#endif /* ZZINF_LOOK */

+

+#else  /* DEMAND_LOOK */

+

+#ifdef ZZINF_LOOK

+#define zzCONSUME	inf_zzgettok

+#else

+#define zzCONSUME	zzgettok();

+#endif

+

+#endif /* DEMAND_LOOK */

+

+#endif /* LL_K */

+

+#ifdef LL_K

+#define NLA			zztokenLA[zzlap&(LL_K-1)]	/* --> next LA */

+#define NLATEXT		zztextLA[zzlap&(LL_K-1)]	/* --> next text of LA */

+#ifdef DEMAND_LOOK

+#define LA(i)       zztokenLA[(zzlabase+(i)-1)&(LL_K-1)]

+#define LATEXT(i)   (&(zztextLA[(zzlabase+(i)-1)&(LL_K-1)][0]))

+#else

+#define LA(i)       zztokenLA[(zzlap+(i)-1)&(LL_K-1)]

+#define LATEXT(i)   (&(zztextLA[(zzlap+(i)-1)&(LL_K-1)][0]))

+#endif

+#else

+#define NLA			zztoken

+#define NLATEXT		zztext

+#define LA(i)       zztoken

+#define LATEXT(i)   zztext

+#endif

+

+

+           /* S t a n d a r d  S i g n a l s */

+

+#define NoSignal			0

+#define MismatchedToken		1

+#define NoViableAlt			2

+#define NoSemViableAlt		3

+

+/* MR7  Allow more control over signalling                                  */

+/*        by adding "Unwind" and "zzsetSignal"                              */

+

+#define Unwind              4

+#define zzsetSignal(newValue) *_retsignal=_signal=(newValue)

+#define zzsuppressSignal *_retsignal=_signal=0

+#define zzexportSignal    *_retsignal=_signal

+

+           /* F u n c t i o n  T r a c i n g */

+

+#ifndef zzTRACE_RULES

+#define zzTRACEdata

+#else

+#ifndef zzTRACEdata

+#define zzTRACEdata     ANTLRChar *zzTracePrevRuleName = NULL;

+#endif

+#endif

+

+#ifndef zzTRACEIN

+#define zzTRACEIN(r)	zzTracePrevRuleName=zzTraceCurrentRuleName;zzTraceIn(r);

+#endif

+#ifndef zzTRACEOUT

+#define zzTRACEOUT(r)	zzTraceOut(r);zzTraceCurrentRuleName=zzTracePrevRuleName;

+#endif

+

+/* MR19 zzchar_t additions */

+

+#ifndef zzchar_t

+#ifdef ZZWCHAR_T

+#define zzchar_t wchar_t

+#else

+#define zzchar_t char

+#endif

+#endif

+

+

+/* MR26 */

+

+#ifdef PCCTS_USE_STDARG

+extern void zzFAIL(int k, ...);

+#else

+extern void zzFAIL();

+#endif

+				/* E x t e r n  D e f s */

+

+#ifdef __USE_PROTOS

+extern Attrib zzempty_attr(void);

+extern Attrib zzconstr_attr(int, char *);

+extern void zzsyn(char *, int, char *, SetWordType *, int, int, char *);

+extern int zzset_el(unsigned, SetWordType *);

+extern int zzset_deg(SetWordType *);

+extern void zzedecode(SetWordType *);

+

+extern void zzresynch(SetWordType *, SetWordType);

+extern void zzsave_antlr_state(zzantlr_state *);

+extern void zzrestore_antlr_state(zzantlr_state *);

+extern void zzfill_inf_look(void);

+extern void zzconsumeUntil(SetWordType *st);                         /* MR7 */

+extern void zzconsumeUntilToken(int t);                              /* MR7 */

+extern void zzTraceIn(char * ruleName);                              /* MR10 */

+extern void zzTraceOut(char * ruleName);                             /* MR10 */

+extern int  zzTraceOption(int delta);                                /* MR10 */

+extern int  zzTraceGuessOption(int delta);                           /* MR10 */

+extern void zzTraceReset(void);                                      /* MR10 */

+extern void zzTraceGuessFail(void);                                  /* MR10 */

+#ifdef EXCEPTION_HANDLING

+extern void zzdflthandlers(int, int *);

+#endif

+#else

+extern Attrib zzempty_attr();

+extern Attrib zzconstr_attr();

+extern void zzsyn();

+extern int zzset_el();

+extern int zzset_deg();

+extern void zzedecode();

+extern void zzresynch();

+extern void zzsave_antlr_state();

+extern void zzrestore_antlr_state();

+extern void zzfill_inf_look();

+extern void zzconsumeUntil();                                        /* MR7 */

+extern void zzconsumeUntilToken();                                   /* MR7 */

+extern void zzTraceIn();                                             /* MR10 */

+extern void zzTraceOut();                                            /* MR10 */

+extern int  zzTraceOption();                                         /* MR10 */

+extern int  zzTraceGuessOption();                                    /* MR10 */

+extern void zzTraceReset();                                          /* MR10 */

+extern void zzTraceGuessFail();                                      /* MR10 */

+#ifdef EXCEPTION_HANDLING

+extern void zzdflthandlers();

+#endif

+#endif

+

+				/* G l o b a l  V a r i a b l e s */

+

+/* Define a parser; user should do a "#parser myname" in their grammar file */

+/*extern struct pccts_parser zzparser;*/

+

+extern char *zztokens[];

+#ifdef LL_K

+extern int zztokenLA[];

+extern zzchar_t zztextLA[][ZZLEXBUFSIZE];

+extern int zzlap;

+extern int zzlabase;

+#else

+extern int zztoken;

+#endif

+

+extern char zzStackOvfMsg[];

+extern int zzasp;

+extern Attrib zzaStack[];

+#ifdef ZZINF_LOOK

+extern int *zzinf_tokens;

+extern char **zzinf_text;

+extern char *zzinf_text_buffer;

+extern int *zzinf_line;

+extern int zzinf_labase;

+extern int zzinf_last;

+#endif

+#ifdef DEMAND_LOOK

+extern int zzdirty;

+#endif

+#ifdef ZZCAN_GUESS

+extern int zzguessing;

+extern zzjmp_buf zzguess_start;

+#endif

+

+/* Define global veriables that refer to values exported by the scanner.

+ * These declarations duplicate those in dlgdef.h, but are needed

+ * if ANTLR is not to generate a .dlg file (-gx); PS, this is a hack.

+ */

+extern zzchar_t *zzlextext;     /* text of most recently matched token */

+extern int      zzbufsize;      /* how long zzlextext is */

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ast.c b/edk2/Tools/Source/TianoTools/Pccts/h/ast.c
new file mode 100644
index 0000000..9326ae1
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ast.c
@@ -0,0 +1,345 @@
+/* Abstract syntax tree manipulation functions

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed. 

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#include "pcctscfg.h"

+

+#ifdef PCCTS_USE_STDARG

+#include "pccts_stdarg.h"

+#else

+#include <varargs.h>

+#endif

+

+/* ensure that tree manipulation variables are current after a rule

+ * reference

+ */

+

+void

+#ifdef __USE_PROTOS

+zzlink(AST **_root, AST **_sibling, AST **_tail)

+#else

+zzlink(_root, _sibling, _tail)

+AST **_root, **_sibling, **_tail;

+#endif

+{

+	if ( *_sibling == NULL ) return;

+	if ( *_root == NULL ) *_root = *_sibling;

+	else if ( *_root != *_sibling ) (*_root)->down = *_sibling;

+	if ( *_tail==NULL ) *_tail = *_sibling;

+	while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right;

+}

+

+AST *

+#ifdef __USE_PROTOS

+zzastnew(void)

+#else

+zzastnew()

+#endif

+{

+	AST *p = (AST *) calloc(1, sizeof(AST));

+	if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__);

+	return p;

+}

+

+/* add a child node to the current sibling list */

+void

+#ifdef __USE_PROTOS

+zzsubchild(AST **_root, AST **_sibling, AST **_tail)

+#else

+zzsubchild(_root, _sibling, _tail)

+AST **_root, **_sibling, **_tail;

+#endif

+{

+	AST *n;

+	zzNON_GUESS_MODE {

+	n = zzastnew();

+#ifdef DEMAND_LOOK

+	zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));

+#else

+	zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));

+#endif

+	zzastPush( n );

+	if ( *_tail != NULL ) (*_tail)->right = n;

+	else {

+		*_sibling = n;

+		if ( *_root != NULL ) (*_root)->down = *_sibling;

+	}

+	*_tail = n;

+	if ( *_root == NULL ) *_root = *_sibling;

+	}

+}

+

+/* make a new AST node.  Make the newly-created

+ * node the root for the current sibling list.  If a root node already

+ * exists, make the newly-created node the root of the current root.

+ */

+void

+#ifdef __USE_PROTOS

+zzsubroot(AST **_root, AST **_sibling, AST **_tail)

+#else

+zzsubroot(_root, _sibling, _tail)

+AST **_root, **_sibling, **_tail;

+#endif

+{

+	AST *n;

+	zzNON_GUESS_MODE {

+	n = zzastnew();

+#ifdef DEMAND_LOOK

+	zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));

+#else

+	zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));

+#endif

+	zzastPush( n );

+	if ( *_root != NULL )

+		if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root;

+	*_root = n;

+	(*_root)->down = *_sibling;

+	}

+}

+

+/* Apply function to root then each sibling

+ * example: print tree in child-sibling LISP-format (AST has token field)

+ *

+ *	void show(tree)

+ *	AST *tree;

+ *	{

+ *		if ( tree == NULL ) return;

+ *		printf(" %s", zztokens[tree->token]);

+ *	}

+ *

+ *	void before() { printf(" ("); }

+ *	void after()  { printf(" )"); }

+ *

+ *	LISPdump() { zzpre_ast(tree, show, before, after); }

+ *

+ */

+void

+#ifdef __USE_PROTOS

+zzpre_ast(

+	  AST *tree,

+	  void (*func)(AST *),   /* apply this to each tree node */

+	  void (*before)(AST *), /* apply this to root of subtree before preordering it */

+	  void (*after)(AST *))  /* apply this to root of subtree after preordering it */

+#else

+zzpre_ast(tree, func, before, after)

+AST *tree;

+void (*func)(),   /* apply this to each tree node */

+	 (*before)(), /* apply this to root of subtree before preordering it */

+	 (*after)();  /* apply this to root of subtree after preordering it */

+#endif

+{

+	while ( tree!= NULL )

+	{

+		if ( tree->down != NULL ) (*before)(tree);

+		(*func)(tree);

+		zzpre_ast(tree->down, func, before, after);

+		if ( tree->down != NULL ) (*after)(tree);

+		tree = tree->right;

+	}

+}

+

+/* free all AST nodes in tree; apply func to each before freeing */

+

+#if 0

+////void

+////#ifdef __USE_PROTOS

+////zzfree_ast(AST *tree)

+////#else

+////zzfree_ast(tree)

+////AST *tree;

+////#endif

+////{

+////	if ( tree == NULL ) return;

+////	zzfree_ast( tree->down );

+////	zzfree_ast( tree->right );

+////	zztfree( tree );

+////}

+#endif

+

+/*

+   MR19 Optimize freeing of the following structure to limit recursion

+   SAKAI Kiyotaka (ksakai@isr.co.jp)

+*/

+

+/*

+         NULL o

+             / \

+           NULL o

+               / \

+            NULL NULL

+*/

+

+/*

+   MR21 Another refinement to replace recursion with iteration

+   NAKAJIMA Mutsuki (muc@isr.co.jp).

+*/

+

+void

+#ifdef __USE_PROTOS

+zzfree_ast(AST *tree)

+#else

+zzfree_ast(tree)

+AST *tree;

+#endif

+{

+

+    AST *otree;

+

+    if (tree == NULL) return;

+

+    while (tree->down == NULL || tree->right == NULL) {

+

+        if (tree->down == NULL && tree->right == NULL) {

+            zztfree(tree);

+            return;

+        }

+

+        otree = tree;

+        if (tree->down == NULL) {

+            tree = tree->right;

+        } else {

+            tree = tree->down;

+        }

+        zztfree( otree );

+    }

+

+    while (tree != NULL) {

+        zzfree_ast(tree->down);

+        otree = tree;

+        tree = otree->right;

+        zztfree(otree);

+    }

+}

+

+/* build a tree (root child1 child2 ... NULL)

+ * If root is NULL, simply make the children siblings and return ptr

+ * to 1st sibling (child1).  If root is not single node, return NULL.

+ *

+ * Siblings that are actually siblins lists themselves are handled

+ * correctly.  For example #( NULL, #( NULL, A, B, C), D) results

+ * in the tree ( NULL A B C D ).

+ *

+ * Requires at least two parameters with the last one being NULL.  If

+ * both are NULL, return NULL.

+ */

+#ifdef PCCTS_USE_STDARG

+AST *zztmake(AST *rt, ...)

+#else

+AST *zztmake(va_alist)

+va_dcl

+#endif

+{

+	va_list ap;

+	register AST *child, *sibling=NULL, *tail=NULL /* MR20 */, *w;

+	AST *root;

+

+#ifdef PCCTS_USE_STDARG

+	va_start(ap, rt);

+	root = rt;

+#else

+	va_start(ap);

+	root = va_arg(ap, AST *);

+#endif

+

+	if ( root != NULL )

+		if ( root->down != NULL ) return NULL;

+	child = va_arg(ap, AST *);

+	while ( child != NULL )

+	{

+		for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */

+		if ( sibling == NULL ) {sibling = child; tail = w;}

+		else {tail->right = child; tail = w;}

+		child = va_arg(ap, AST *);

+	}

+	if ( root==NULL ) root = sibling;

+	else root->down = sibling;

+	va_end(ap);

+	return root;

+}

+

+/* tree duplicate */

+AST *

+#ifdef __USE_PROTOS

+zzdup_ast(AST *t)

+#else

+zzdup_ast(t)

+AST *t;

+#endif

+{

+	AST *u;

+	

+	if ( t == NULL ) return NULL;

+	u = zzastnew();

+	*u = *t;

+#ifdef zzAST_DOUBLE

+	u->up = NULL;		/* set by calling invocation */

+	u->left = NULL;

+#endif

+	u->right = zzdup_ast(t->right);

+	u->down = zzdup_ast(t->down);

+#ifdef zzAST_DOUBLE

+	if ( u->right!=NULL ) u->right->left = u;

+	if ( u->down!=NULL ) u->down->up = u;

+#endif

+	return u;

+}

+

+void

+#ifdef __USE_PROTOS

+zztfree(AST *t)

+#else

+zztfree(t)

+AST *t;

+#endif

+{

+#ifdef zzd_ast

+	zzd_ast( t );

+#endif

+	free( t );

+}

+

+#ifdef zzAST_DOUBLE

+/*

+ * Set the 'up', and 'left' pointers of all nodes in 't'.

+ * Initial call is double_link(your_tree, NULL, NULL).

+ */

+void

+#ifdef __USE_PROTOS

+zzdouble_link(AST *t, AST *left, AST *up)

+#else

+zzdouble_link(t, left, up)

+AST *t, *left, *up;

+#endif

+{

+	if ( t==NULL ) return;

+	t->left = left;

+	t->up = up;

+	zzdouble_link(t->down, NULL, t);

+	zzdouble_link(t->right, t, up);

+}

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/ast.h b/edk2/Tools/Source/TianoTools/Pccts/h/ast.h
new file mode 100644
index 0000000..5ff84bd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/ast.h
@@ -0,0 +1,121 @@
+/* Abstract syntax tree

+ *

+ * Macros, definitions

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ZZAST_H

+#define ZZAST_H

+

+#define zzastOvfChk														\

+			if ( zzast_sp <= 0 )                                        \

+            {                                                           \

+                fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__);    	\

+                exit(PCCTS_EXIT_FAILURE);                                               \

+            }

+

+#ifndef USER_DEFINED_AST

+#ifndef AST_FIELDS

+#define AST_FIELDS

+#endif

+

+typedef struct _ast {

+            struct _ast *right, *down;

+#ifdef zzAST_DOUBLE

+            struct _ast *left, *up;

+#endif

+            AST_FIELDS

+} AST;

+

+#else

+

+#ifdef zzAST_DOUBLE

+#define AST_REQUIRED_FIELDS   struct _ast *right, *down, *left, *up;

+#else

+#define AST_REQUIRED_FIELDS   struct _ast *right, *down;

+#endif

+

+#endif

+

+

+/* N o d e  a c c e s s  m a c r o s */

+#define zzchild(t)		(((t)==NULL)? (AST *) NULL:(t->down))   /* MR19 */

+#define zzsibling(t)	(((t)==NULL)? (AST *) NULL:(t->right))  /* MR19 */

+

+

+/* define global variables needed by #i stack */

+#define zzASTgvars												\

+	AST *zzastStack[ZZAST_STACKSIZE];							\

+	int zzast_sp = ZZAST_STACKSIZE;

+

+#define zzASTVars	AST *_ast = NULL, *_sibling = NULL, *_tail = NULL

+#define zzSTR		( (_tail==NULL)?(&_sibling):(&(_tail->right)) )

+#define zzastCur	(zzastStack[zzast_sp])

+#define zzastArg(i)	(zzastStack[zztsp-i])

+#define zzastPush(p) zzastOvfChk; zzastStack[--zzast_sp] = p;

+#define zzastDPush	--zzast_sp

+#define zzastMARK	zztsp=zzast_sp;		/* Save state of stack */

+#define zzastREL	zzast_sp=zztsp;		/* Return state of stack */

+#define zzrm_ast	{zzfree_ast(*_root); _tail = _sibling = (*_root)=NULL;}

+

+extern int zzast_sp;

+extern AST *zzastStack[];

+

+/* MR26 */

+

+#ifdef PCCTS_USE_STDARG

+AST *zztmake(AST *, ...);

+#else

+AST *zztmake();

+#endif

+

+#ifdef __USE_PROTOS

+void zzlink(AST **, AST **, AST **);

+void zzsubchild(AST **, AST **, AST **);

+void zzsubroot(AST **, AST **, AST **);

+void zzpre_ast(AST *, void (*)(AST *), void (*)(AST *), void (*)(AST *));

+void zzfree_ast(AST *);

+AST *zzdup_ast(AST *);

+void zztfree(AST *);

+void zzdouble_link(AST *, AST *, AST *);

+AST *zzastnew(void);

+

+#else

+

+void zzlink();

+AST *zzastnew();

+void zzsubchild();

+void zzsubroot();

+void zzpre_ast();

+void zzfree_ast();

+AST *zzdup_ast();

+void zztfree();

+void zzdouble_link();

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/charbuf.h b/edk2/Tools/Source/TianoTools/Pccts/h/charbuf.h
new file mode 100644
index 0000000..5f01c8b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/charbuf.h
@@ -0,0 +1,46 @@
+/* ANTLR attribute definition -- constant width text

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ZZCHARBUF_H

+#define ZZCHARBUF_H

+

+#include "pcctscfg.h"

+

+#include "pccts_string.h"

+

+#ifndef D_TextSize

+#define D_TextSize	30

+#endif

+

+typedef struct { char text[D_TextSize]; } Attrib;

+

+#define zzcr_attr(a,tok,t)	strncpy((a)->text, t, D_TextSize-1); \

+							(a)->text[D_TextSize-1] = '\0';

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/charptr.c b/edk2/Tools/Source/TianoTools/Pccts/h/charptr.c
new file mode 100644
index 0000000..d3f80e6
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/charptr.c
@@ -0,0 +1,58 @@
+/*

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#include "pcctscfg.h"

+

+#ifdef __STDC__

+#include "pccts_stdlib.h"

+#else

+#include <malloc.h>

+#endif

+#include "pccts_string.h"

+

+/* 133MR1 include stdio.h for fprintf in charptr.c */

+

+#include "pccts_stdio.h"

+

+/* 133MR1 include charptr.h for Attrib in charptr.c */

+

+#include "charptr.h"

+

+#ifdef __USE_PROTOS

+zzcr_attr(Attrib *a,int token,char *text)

+#else

+zzcr_attr(a,token,text)

+Attrib *a;

+int token;

+char *text;

+#endif

+{

+	*a = (char *) malloc(strlen(text)+1);			/* MR6 */

+	if ( *a == NULL ) {fprintf(stderr, "zzcr_attr: out of memory!\n"); exit(-1);}

+	strcpy(*a, text);

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/charptr.h b/edk2/Tools/Source/TianoTools/Pccts/h/charptr.h
new file mode 100644
index 0000000..e73da68
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/charptr.h
@@ -0,0 +1,48 @@
+/*

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+/*

+ * WARNING!!!!: charptr.h does NOT make copies and the

+ * memory is freed after the attribute scope exits.

+ */

+

+#ifndef ZZCHARPTR_H

+#define ZZCHARPTR_H

+

+typedef char *Attrib;

+#define zzdef0(a)		{*(a)=NULL;}

+/* MR8  Jens Tingleff (jensting@imaginet.fr)                                */

+/*          Set memory pointer to null after free()                         */

+#define zzd_attr(a)		{if ( *(a)!=NULL ) {free(*(a)); *(a)=NULL; }; }

+

+#ifdef __STDC__

+extern zzcr_attr(Attrib *,int,char *);

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/config.h b/edk2/Tools/Source/TianoTools/Pccts/h/config.h
new file mode 100644
index 0000000..8aa50ad
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/config.h
@@ -0,0 +1 @@
+#include "pcctscfg.h"

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/dlgauto.h b/edk2/Tools/Source/TianoTools/Pccts/h/dlgauto.h
new file mode 100644
index 0000000..db94cef
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/dlgauto.h
@@ -0,0 +1,504 @@
+/* dlgauto.h automaton

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Will Cohen and Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ZZDEFAUTO_H

+#define ZZDEFAUTO_H

+

+/*  10-Apr-97 133MR1	Uses __USE_PROTOS show should #include pcctscfg.h */

+

+#include "pcctscfg.h"

+

+zzchar_t	*zzlextext;	/* text of most recently matched token */

+zzchar_t	*zzbegexpr;	/* beginning of last reg expr recogn. */

+zzchar_t	*zzendexpr;	/* beginning of last reg expr recogn. */

+int	zzbufsize = 0;	/* number of characters in zzlextext */          /* MR7 */

+int	zzbegcol = 0;	/* column that first character of token is in*/

+int	zzendcol = 0;	/* column that last character of token is in */

+int	zzline = 1;	/* line current token is on */

+int	zzreal_line=1;	/* line of 1st portion of token that is not skipped */

+int	zzchar;		/* character to determine next state */

+int	zzbufovf;	/* indicates that buffer too small for text */

+int	zzcharfull = 0;

+static zzchar_t	*zznextpos;/* points to next available position in zzlextext*/

+static int 	zzclass;

+

+#ifdef __USE_PROTOS

+void	zzerrstd(const char *);

+void	(*zzerr)(const char *)=zzerrstd;/* pointer to error reporting function */

+extern int	zzerr_in(void);

+static int	(*zzfunc_in)(void) = zzerr_in;  /* MR20 */

+#else

+void	zzerrstd();

+void	(*zzerr)()=zzerrstd;	/* pointer to error reporting function */

+extern int	zzerr_in();

+static int	(*zzfunc_in)() = zzerr_in;      /* MR20 */

+#endif

+

+static FILE	*zzstream_in=0;

+static zzchar_t	*zzstr_in=0;

+

+#ifdef USER_ZZMODE_STACK

+int 	          zzauto = 0;

+#else

+static int     zzauto = 0;

+#endif

+static int	zzadd_erase;

+static char 	zzebuf[70];

+

+#ifdef ZZCOL

+#define ZZINC (++zzendcol)

+#else

+#define ZZINC

+#endif

+

+

+#define ZZGETC_STREAM {zzchar = getc(zzstream_in); zzclass = ZZSHIFT(zzchar);}

+#define ZZGETC_FUNC {zzchar = (*zzfunc_in)(); zzclass = ZZSHIFT(zzchar);}

+#define ZZGETC_STR { 			\

+	if (*zzstr_in){				\

+		zzchar = *zzstr_in;		\

+		++zzstr_in;				\

+	}else{						\

+		zzchar = EOF;			\

+	}							\

+	zzclass = ZZSHIFT(zzchar);	\

+}

+

+#define ZZNEWSTATE	(newstate = dfa[state][zzclass])

+

+#ifndef ZZCOPY

+#define ZZCOPY	\

+	/* Truncate matching buffer to size (not an error) */	\

+	if (zznextpos < lastpos){				\

+		*(zznextpos++) = zzchar;			\

+	}else{							\

+		zzbufovf = 1;					\

+	}

+#endif

+

+void

+#ifdef __USE_PROTOS

+zzrdstream( FILE *f )

+#else

+zzrdstream( f )

+FILE *f;

+#endif

+{

+	/* make sure that it is really set to something, otherwise just

+	   leave it be.

+	*/

+	if (f){

+		/* make sure that there is always someplace to get input

+		   before closing zzstream_in

+		*/

+#if 0

+		if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );

+#endif

+		zzline = 1;

+		zzstream_in = f;

+		zzfunc_in = NULL;

+		zzstr_in = 0;

+		zzcharfull = 0;

+	}

+}

+

+void

+#ifdef __USE_PROTOS

+zzrdfunc( int (*f)(void) )

+#else

+zzrdfunc( f )

+int (*f)();

+#endif

+{

+	/* make sure that it is really set to something, otherwise just

+	   leave it be.

+	*/

+	if (f){

+		/* make sure that there is always someplace to get input

+		   before closing zzstream_in

+		*/

+#if 0

+		if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );

+#endif

+		zzline = 1;

+		zzstream_in = NULL;

+		zzfunc_in = f;

+		zzstr_in = 0;

+		zzcharfull = 0;

+	}

+}

+

+

+void

+#ifdef __USE_PROTOS

+zzrdstr( zzchar_t *s )

+#else

+zzrdstr( s )

+zzchar_t *s;

+#endif

+{

+	/* make sure that it is really set to something, otherwise just

+	   leave it be.

+	*/

+	if (s){

+		/* make sure that there is always someplace to get input

+		   before closing zzstream_in

+		*/

+#if 0

+		if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );

+#endif

+		zzline = 1;

+		zzstream_in = NULL;

+		zzfunc_in = 0;

+		zzstr_in = s;

+		zzcharfull = 0;

+	}

+}

+

+

+#ifdef __USE_PROTOS

+void zzclose_stream(void)

+#else

+void zzclose_stream()

+#endif

+{

+#if 0

+	fclose( zzstream_in );

+	zzstream_in = NULL;

+	zzfunc_in = NULL;

+#endif

+}

+

+/* saves dlg state, but not what feeds dlg (such as file position) */

+void

+#ifdef __USE_PROTOS

+zzsave_dlg_state(struct zzdlg_state *state)

+#else

+zzsave_dlg_state(state)

+struct zzdlg_state *state;

+#endif

+{

+	state->stream = zzstream_in;

+	state->func_ptr = zzfunc_in;

+	state->str = zzstr_in;

+	state->auto_num = zzauto;

+	state->add_erase = zzadd_erase;

+	state->lookc = zzchar;

+	state->char_full = zzcharfull;

+	state->begcol = zzbegcol;

+	state->endcol = zzendcol;

+	state->line = zzline;

+	state->lextext = zzlextext;

+	state->begexpr = zzbegexpr;

+	state->endexpr = zzendexpr;

+	state->bufsize = zzbufsize;

+	state->bufovf = zzbufovf;

+	state->nextpos = zznextpos;

+	state->class_num = zzclass;

+}

+

+void

+#ifdef __USE_PROTOS

+zzrestore_dlg_state(struct zzdlg_state *state)

+#else

+zzrestore_dlg_state(state)

+struct zzdlg_state *state;

+#endif

+{

+	zzstream_in = state->stream;

+	zzfunc_in = state->func_ptr;

+	zzstr_in = state->str;

+	zzauto = state->auto_num;

+	zzadd_erase = state->add_erase;

+	zzchar = state->lookc;

+	zzcharfull = state->char_full;

+	zzbegcol = state->begcol;

+	zzendcol = state->endcol;

+	zzline = state->line;

+	zzlextext = state->lextext;

+	zzbegexpr = state->begexpr;

+	zzendexpr = state->endexpr;

+	zzbufsize = state->bufsize;

+	zzbufovf = state->bufovf;

+	zznextpos = state->nextpos;

+	zzclass = state->class_num;

+}

+

+void

+#ifdef __USE_PROTOS

+zzmode( int m )

+#else

+zzmode( m )

+int m;

+#endif

+{

+	/* points to base of dfa table */

+	if (m<MAX_MODE){

+		zzauto = m;

+		/* have to redo class since using different compression */

+		zzclass = ZZSHIFT(zzchar);

+	}else{

+		sprintf(zzebuf,"Invalid automaton mode = %d ",m);

+		zzerr(zzebuf);

+	}

+}

+

+/* erase what is currently in the buffer, and get a new reg. expr */

+

+#ifdef __USE_PROTOS

+void zzskip(void)

+#else

+void zzskip()

+#endif

+{

+	zzadd_erase = 1;

+}

+

+/* don't erase what is in the zzlextext buffer, add on to it */

+#ifdef __USE_PROTOS

+void zzmore()

+#else

+void zzmore()

+#endif

+{

+	zzadd_erase = 2;

+}

+

+/* substitute c for the reg. expr last matched and is in the buffer */

+#ifdef __USE_PROTOS

+void

+zzreplchar(zzchar_t c)

+#else

+void

+zzreplchar(c)

+zzchar_t c;

+#endif

+{

+	/* can't allow overwriting null at end of string */

+	if (zzbegexpr < &zzlextext[zzbufsize-1]){

+		*zzbegexpr = c;

+		*(zzbegexpr+1) = '\0';

+	}

+	zzendexpr = zzbegexpr;

+	if (c != '\0') {

+		zznextpos = zzbegexpr + 1;

+	}

+	else {

+		zznextpos = zzbegexpr;	/* MR30 Zero terminates string. */

+	}

+}

+

+/* replace the string s for the reg. expr last matched and in the buffer */

+void

+#ifdef __USE_PROTOS

+zzreplstr(register zzchar_t *s)

+#else

+zzreplstr(s)

+register zzchar_t *s;

+#endif

+{

+	register zzchar_t *l= &zzlextext[zzbufsize -1];

+

+	zznextpos = zzbegexpr;

+	if (s){

+	 	while ((zznextpos <= l) && (*(zznextpos++) = *(s++))!=0){

+			/* empty */

+		}

+		/* correct for NULL at end of string */

+		zznextpos--;

+	}

+	if ((zznextpos <= l) && (*(--s) == 0)){

+		zzbufovf = 0;

+	}else{

+		zzbufovf = 1;

+	}

+	*(zznextpos) = '\0';

+	zzendexpr = zznextpos - 1;

+}

+

+#ifdef __USE_PROTOS

+void zzgettok(void)

+#else

+void zzgettok()

+#endif

+{

+	register int state, newstate;

+	/* last space reserved for the null char */

+	zzchar_t *lastpos;  /* MR27 Remove register since address operator used. */

+

+skip:

+	zzreal_line = zzline;

+	zzbufovf = 0;

+	lastpos = &zzlextext[zzbufsize-1];

+	zznextpos = zzlextext;

+	zzbegcol = zzendcol+1;

+more:

+	zzbegexpr = zznextpos;

+#ifdef ZZINTERACTIVE

+	/* interactive version of automaton */

+	/* if there is something in zzchar, process it */

+	state = newstate = dfa_base[zzauto];

+	if (zzcharfull){

+		ZZINC;

+		ZZCOPY;

+		ZZNEWSTATE;

+	}

+	if (zzstr_in)

+		while (zzalternatives[newstate]){

+			state = newstate;

+			ZZGETC_STR;

+			ZZINC;

+			ZZCOPY;

+			ZZNEWSTATE;

+		}

+	else if (zzstream_in)

+		while (zzalternatives[newstate]){

+			state = newstate;

+			ZZGETC_STREAM;

+			ZZINC;

+			ZZCOPY;

+			ZZNEWSTATE;

+		}

+	else if (zzfunc_in)

+		while (zzalternatives[newstate]){

+			state = newstate;

+			ZZGETC_FUNC;

+			ZZINC;

+			ZZCOPY;

+			ZZNEWSTATE;

+		}

+	/* figure out if last character really part of token */

+	if ((state != dfa_base[zzauto]) && (newstate == DfaStates)){

+		zzcharfull = 1;

+		--zznextpos;

+	}else{

+		zzcharfull = 0;

+		state = newstate;

+	}

+	*(zznextpos) = '\0';

+	/* Able to transition out of start state to some non err state?*/

+	if ( state == dfa_base[zzauto] ){

+		/* make sure doesn't get stuck */

+		zzadvance();

+	}

+#else

+	/* non-interactive version of automaton */

+	if (!zzcharfull)

+		zzadvance();

+	else

+		ZZINC;

+	state = dfa_base[zzauto];

+	if (zzstr_in)

+		while (ZZNEWSTATE != DfaStates){

+			state = newstate;

+			ZZCOPY;

+			ZZGETC_STR;

+			ZZINC;

+		}

+	else if (zzstream_in)

+		while (ZZNEWSTATE != DfaStates){

+			state = newstate;

+			ZZCOPY;

+			ZZGETC_STREAM;

+			ZZINC;

+		}

+	else if (zzfunc_in)

+		while (ZZNEWSTATE != DfaStates){

+			state = newstate;

+			ZZCOPY;

+			ZZGETC_FUNC;

+			ZZINC;

+		}

+	zzcharfull = 1;

+	if ( state == dfa_base[zzauto] ){

+		if (zznextpos < lastpos){

+			*(zznextpos++) = zzchar;

+		}else{

+			zzbufovf = 1;

+		}

+		*zznextpos = '\0';

+		/* make sure doesn't get stuck */

+		zzadvance();

+	}else{

+		*zznextpos = '\0';

+	}

+#endif

+#ifdef ZZCOL

+	zzendcol -= zzcharfull;

+#endif

+	zzendexpr = zznextpos -1;

+	zzadd_erase = 0;

+	(*actions[accepts[state]])();

+	switch (zzadd_erase) {

+		case 1: goto skip;

+		case 2: goto more;

+	}

+}

+

+#ifdef __USE_PROTOS

+void zzadvance(void)

+#else

+void zzadvance()

+#endif

+{

+	if (zzstream_in) { ZZGETC_STREAM; zzcharfull = 1; ZZINC;}

+	if (zzfunc_in) { ZZGETC_FUNC; zzcharfull = 1; ZZINC;}

+	if (zzstr_in) { ZZGETC_STR; zzcharfull = 1; ZZINC;}

+	if (!(zzstream_in || zzfunc_in || zzstr_in)){

+		zzerr_in();

+	}

+}

+

+void

+#ifdef __USE_PROTOS

+zzerrstd(const char *s)

+#else

+zzerrstd(s)

+char *s;

+#endif

+{

+        zzLexErrCount++;                /* MR11 */

+        fprintf(stderr,

+                "%s near line %d (text was '%s')\n",

+                ((s == NULL) ? "Lexical error" : s),

+                zzline,zzlextext);

+}

+

+#ifdef __USE_PROTOS

+int zzerr_in(void)

+#else

+int zzerr_in()

+#endif

+{

+	fprintf(stderr,"No input stream, function, or string\n");

+	/* return eof to get out gracefully */

+	return EOF;

+}

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/dlgdef.h b/edk2/Tools/Source/TianoTools/Pccts/h/dlgdef.h
new file mode 100644
index 0000000..733d256
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/dlgdef.h
@@ -0,0 +1,128 @@
+/* dlgdef.h

+ * Things in scanner produced by dlg that should be visible to the outside

+ * world

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ZZDLGDEF_H

+#define ZZDLGDEF_H

+

+#include "pcctscfg.h"

+

+#ifndef zzchar_t

+#ifdef ZZWCHAR_T

+#define zzchar_t wchar_t

+#else

+#define zzchar_t char

+#endif

+#endif

+

+struct zzdlg_state {

+	FILE *stream;

+#ifdef __USE_PROTOS

+	int (*func_ptr)(void);

+#else

+	int (*func_ptr)();

+#endif

+	zzchar_t *str;

+	int auto_num;

+	int add_erase;

+	int lookc;

+	int char_full;

+	int begcol, endcol;

+	int line;

+	zzchar_t *lextext, *begexpr, *endexpr;

+	int bufsize;

+	int bufovf;

+	zzchar_t *nextpos;

+	int	class_num;

+};

+

+extern zzchar_t	*zzlextext;  	/* text of most recently matched token */

+extern zzchar_t	*zzbegexpr;	/* beginning of last reg expr recogn. */

+extern zzchar_t	*zzendexpr;	/* beginning of last reg expr recogn. */

+extern int	zzbufsize;	/* how long zzlextext is */

+extern int	zzbegcol;	/* column that first character of token is in*/

+extern int	zzendcol;	/* column that last character of token is in */

+extern int	zzline;		/* line current token is on */

+extern int	zzreal_line;		/* line of 1st portion of token that is not skipped */

+extern int	zzchar;		/* character to determine next state */

+extern int	zzbufovf;	/* indicates that buffer too small for text */

+#ifdef __USE_PROTOS

+extern void	(*zzerr)(const char *);/* pointer to error reporting function */

+#else

+extern void	(*zzerr)();

+#endif

+

+#ifdef USER_ZZMODE_STACK

+extern int     zzauto;

+#endif

+

+#ifdef __USE_PROTOS

+extern void	zzadvance(void);

+extern void	zzskip(void);	/* erase zzlextext, look for antoher token */

+extern void	zzmore(void);	/* keep zzlextext, look for another token */

+extern void	zzmode(int k);	/* switch to automaton 'k' */

+extern void	zzrdstream(FILE *);/* what stream to read from */

+extern void	zzclose_stream(void);/* close the current input stream */

+extern void	zzrdfunc(int (*)(void));/* what function to get char from */

+extern void zzrdstr( zzchar_t * );

+extern void	zzgettok(void);	/* get next token */

+extern void	zzreplchar(zzchar_t c);/* replace last recognized reg. expr. with

+					a character */

+extern void	zzreplstr(zzchar_t *s);/* replace last recognized reg. expr. with

+					a string */

+extern void zzsave_dlg_state(struct zzdlg_state *);

+extern void zzrestore_dlg_state(struct zzdlg_state *);

+extern int zzerr_in(void);

+extern void	zzerrstd(const char *);

+extern void zzerraction(void);

+

+#else

+

+extern void	zzadvance();

+extern void	zzskip();	/* erase zzlextext, look for antoher token */

+extern void	zzmore();	/* keep zzlextext, look for another token */

+extern void	zzmode(/*k*/);	/* switch to automaton 'k' */

+extern void	zzrdstream();	/* what stream to read from */

+extern void	zzclose_stream();/* close the current input stream */

+extern void	zzrdfunc();	/* what function to get char from */

+extern void zzrdstr();

+extern void	zzgettok();	/* get next token */

+extern void	zzreplchar();	/* replace last recognized reg. expr. with

+					a character */

+extern void	zzreplstr();	/* replace last recognized reg. expr. with

+					a string */

+extern void zzsave_dlg_state();

+extern void zzrestore_dlg_state();

+extern int zzerr_in();

+extern void	zzerrstd();

+extern void zzerraction();

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/err.h b/edk2/Tools/Source/TianoTools/Pccts/h/err.h
new file mode 100644
index 0000000..b2b196b
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/err.h
@@ -0,0 +1,1170 @@
+/*

+ * err.h

+ *

+ * Standard error handling mechanism

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * Has grown to hold all kinds of stuff (err.h is increasingly misnamed)

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ERR_H

+#define ERR_H

+

+#include "pcctscfg.h"

+#include <stdlib.h>

+#include <assert.h>

+

+/*									      */

+/*  7-Apr-97  133MR1							      */

+/*		Proper choice of STDC and cplusplus pre-processor symbols (?) */

+/*									      */

+#include "pccts_string.h"

+

+#ifdef PCCTS_USE_STDARG

+#include "pccts_stdarg.h"

+#else

+#include <varargs.h>

+#endif

+

+#ifdef DUM

+/* Define usable bits per unsigned int word (used for set stuff) */

+#ifdef PC

+#define BSETWORDSIZE 16

+#define BSETLOGWORDSIZE	4

+#else

+#define	BSETWORDSIZE 32

+#define BSETLOGWORDSIZE 5

+#endif

+#endif

+

+#define	BSETWORDSIZE 8

+#define BSETLOGWORDSIZE 3		/* SetWordType is 8bits */

+

+#define	BSETMODWORD(x) ((x) & (BSETWORDSIZE-1))		/* x % BSETWORDSIZE */

+#define	BSETDIVWORD(x) ((x) >> BSETLOGWORDSIZE)		/* x / BSETWORDSIZE */

+

+/* This is not put into the global pccts_parser structure because it is

+ * hidden and does not need to be saved during a "save state" operation

+ */

+/* maximum of 32 bits/unsigned int and must be 8 bits/byte */

+static SetWordType bitmask[] = {

+	0x00000001, 0x00000002, 0x00000004, 0x00000008,

+	0x00000010, 0x00000020, 0x00000040, 0x00000080

+};

+

+#ifdef zzTRACE_RULES

+int  zzTraceOptionValueDefault=1;

+int  zzTraceOptionValue=1;

+int  zzTraceGuessOptionValue=1;

+char *zzTraceCurrentRuleName=NULL;

+int  zzTraceDepth=0;

+#endif

+

+int  zzGuessSeq=0;          /* MR10 */

+int  zzSyntaxErrCount=0;    /* MR11 */

+int  zzLexErrCount=0;       /* MR11 */

+

+void

+#ifdef __USE_PROTOS

+zzresynch(SetWordType *wd,SetWordType mask)

+#else

+zzresynch(wd,mask)

+SetWordType *wd, mask;

+#endif

+{

+	static int consumed = 1;

+

+	/* if you enter here without having consumed a token from last resynch

+	 * force a token consumption.

+	 */

+	if ( !consumed ) {zzCONSUME; consumed=1; return;}   /* MR10 */

+

+	/* if current token is in resynch set, we've got what we wanted */

+	if ( wd[LA(1)]&mask || LA(1) == zzEOF_TOKEN ) {consumed=0; return;}

+	

+	/* scan until we find something in the resynch set */

+	while ( !(wd[LA(1)]&mask) && LA(1) != zzEOF_TOKEN ) {zzCONSUME;}

+	consumed=1;

+}

+

+/*                                                                          */

+/*  7-Apr-97 133MR1 for C++ and MR7 for C                                   */

+/*   	     Change suggested by Eli Sternheim (eli@interhdl.com)           */

+/*                                                                          */

+

+void

+#ifdef __USE_PROTOS

+zzconsumeUntil(SetWordType *st)

+#else

+zzconsumeUntil(st)

+SetWordType *st;

+#endif

+{

+    int     tmp;                                                     /* MR7 */

+	while ( !zzset_el( (tmp=LA(1)), st) && tmp!=1 /* Eof */) {       /* MR7 */

+                                                      zzCONSUME; }   /* MR7 */

+}

+

+/*                                                                          */

+/*  7-Apr-97 133MR1 for C++ and MR7 for C                                   */

+/*   	     Change suggested by Eli Sternheim (eli@interhdl.com)           */

+/*                                                                          */

+

+void

+#ifdef __USE_PROTOS

+zzconsumeUntilToken(int t)

+#else

+zzconsumeUntilToken(t)

+int t;

+#endif

+{

+    int     tmp;                                                     /* MR7 */

+	while ( (tmp=LA(1)) !=t && tmp!=1 /* Eof */) { zzCONSUME; }      /* MR7 */

+}

+

+/* input looks like:

+ *		zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText)

+ * where the zzMiss stuff is set here to the token that did not match

+ * (and which set wasn't it a member of).

+ */

+

+#ifdef PCCTS_USE_STDARG

+void zzFAIL(int k, ...)

+#else

+void zzFAIL(va_alist)

+va_dcl

+#endif

+{

+#ifdef LL_K

+	static char text[LL_K*ZZLEXBUFSIZE+1];

+	SetWordType *f[LL_K];

+#else

+	static char text[ZZLEXBUFSIZE+1];

+	SetWordType *f[1];

+#endif

+	SetWordType **miss_set;

+	char **miss_text;

+	int *bad_tok;

+	char **bad_text;

+	int *err_k;

+	int i;

+	va_list ap;

+#ifndef PCCTS_USE_STDARG			/* MR20 */

+	int k;

+#endif

+#ifdef PCCTS_USE_STDARG         /* MR20 */

+	va_start(ap, k);

+#else

+	va_start(ap);

+	k = va_arg(ap, int);	/* how many lookahead sets? */

+#endif

+    assert(k <= sizeof(f)/sizeof(f[0]));    /* MR20 G. Hobbelt */

+	text[0] = '\0';

+	for (i=1; i<=k; i++)	/* collect all lookahead sets */

+	{

+		f[i-1] = va_arg(ap, SetWordType *);

+	}

+	for (i=1; i<=k; i++)	/* look for offending token */

+	{

+		if ( i>1 ) strcat(text, " ");

+		strcat(text, LATEXT(i));

+		if ( !zzset_el((unsigned)LA(i), f[i-1]) ) break;

+	}

+	miss_set = va_arg(ap, SetWordType **);

+	miss_text = va_arg(ap, char **);

+	bad_tok = va_arg(ap, int *);

+	bad_text = va_arg(ap, char **);

+	err_k = va_arg(ap, int *);

+	if ( i>k )

+	{

+		/* bad; lookahead is permutation that cannot be matched,

+		 * but, the ith token of lookahead is valid at the ith position

+		 * (The old LL sub 1 (k) versus LL(k) parsing technique)

+		 */

+		*miss_set = NULL;

+		*miss_text = zzlextext;

+		*bad_tok = LA(1);

+		*bad_text = LATEXT(1);

+		*err_k = k;

+		return;

+	}

+/*	fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/

+	*miss_set = f[i-1];

+	*miss_text = text;

+	*bad_tok = LA(i);

+	*bad_text = LATEXT(i);

+	if ( i==1 ) *err_k = 1;

+	else *err_k = k;

+}

+

+#ifdef __USE_PROTOS

+void zzTraceGuessDone(zzantlr_state *state)

+#else

+void zzTraceGuessDone(state)

+  zzantlr_state     *state;

+#endif

+{

+#ifdef zzTRACE_RULES

+#ifdef ZZCAN_GUESS

+

+  int   doIt=0;

+

+  if (zzTraceCurrentRuleName == NULL) return;

+

+  if (zzTraceOptionValue <= 0) {

+    doIt=0;

+  } else if (zzTraceGuessOptionValue <= 0) {

+    doIt=0;

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    fprintf(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",

+        state->traceCurrentRuleName,

+        LATEXT(1),

+        state->traceDepth);

+    if (state->guessing != 0) {

+      fprintf(stderr," (guess mode continues - an enclosing guess is still active)");

+    } else {

+      fprintf(stderr," (guess mode ends)");

+    };

+    fprintf(stderr,"\n");

+  };

+#endif

+#endif

+}

+

+void

+#ifdef __USE_PROTOS

+zzsave_antlr_state(zzantlr_state *buf)

+#else

+zzsave_antlr_state(buf)

+zzantlr_state *buf;

+#endif

+{

+#ifdef LL_K

+	int     i;

+#endif

+

+#ifdef ZZCAN_GUESS

+	buf->guess_start = zzguess_start;

+	buf->guessing = zzguessing;

+#endif

+	buf->asp = zzasp;

+#ifdef GENAST

+	buf->ast_sp = zzast_sp;

+#endif

+#ifdef ZZINF_LOOK

+	buf->inf_labase = zzinf_labase;

+	buf->inf_last = zzinf_last;

+

+/* MR6 	Gunnar Rxnning (gunnar@candleweb.no)                                */

+/* MR6	  Additional state needs to be saved/restored                       */

+

+  	buf->inf_tokens = zzinf_tokens;                                  /* MR6 */

+	buf->inf_text = zzinf_text;                                      /* MR6 */

+	buf->inf_text_buffer = zzinf_text_buffer;                        /* MR6 */

+	buf->inf_line = zzinf_line;			                             /* MR6 */

+

+#endif

+#ifdef DEMAND_LOOK

+	buf->dirty = zzdirty;

+#endif

+#ifdef LL_K

+	for (i=0; i<LL_K; i++) buf->tokenLA[i] = zztokenLA[i];

+	for (i=0; i<LL_K; i++) strcpy(buf->textLA[i], zztextLA[i]);

+	buf->lap = zzlap;

+	buf->labase = zzlabase;

+#else

+	buf->token = zztoken;

+	strcpy(buf->text, zzlextext);

+#endif

+#ifdef zzTRACE_RULES

+

+    /* MR10 */

+

+    buf->traceOptionValue=zzTraceOptionValue;

+    buf->traceGuessOptionValue=zzTraceGuessOptionValue;

+    buf->traceCurrentRuleName=zzTraceCurrentRuleName;

+    buf->traceDepth=zzTraceDepth;

+#endif

+}

+

+void

+#ifdef __USE_PROTOS

+zzrestore_antlr_state(zzantlr_state *buf)

+#else

+zzrestore_antlr_state(buf)

+zzantlr_state *buf;

+#endif

+{

+

+#ifdef zzTRACE_RULES

+    int     prevTraceOptionValue;

+#endif

+

+#ifdef LL_K

+	int     i;

+#endif

+

+#ifdef ZZCAN_GUESS

+	zzguess_start = buf->guess_start;

+	zzguessing = buf->guessing;

+#endif

+	zzasp = buf->asp;

+#ifdef GENAST

+	zzast_sp = buf->ast_sp;

+#endif

+#ifdef ZZINF_LOOK

+	zzinf_labase = buf->inf_labase;

+	zzinf_last = buf->inf_last;

+

+/* MR6 	Gunnar Rxnning (gunnar@candleweb.no)                                */

+/* MR6	  Additional state needs to be saved/restored                       */

+

+	zzinf_tokens = buf->inf_tokens;                                  /* MR6 */

+	zzinf_text = buf->inf_text;                                      /* MR6 */

+	zzinf_text_buffer = buf->inf_text_buffer;                        /* MR6 */

+	zzinf_line = buf->inf_line;			                             /* MR6 */

+#endif

+#ifdef DEMAND_LOOK

+	zzdirty = buf->dirty;

+#endif

+#ifdef LL_K

+	for (i=0; i<LL_K; i++) zztokenLA[i] = buf->tokenLA[i];

+	for (i=0; i<LL_K; i++) strcpy(zztextLA[i], buf->textLA[i]);

+	zzlap = buf->lap;

+	zzlabase = buf->labase;

+#else

+	zztoken = buf->token;

+	strcpy(zzlextext, buf->text);

+#endif

+#ifdef zzTRACE_RULES

+

+    prevTraceOptionValue=zzTraceOptionValue;

+    zzTraceOptionValue=buf->traceOptionValue;

+    if ( (prevTraceOptionValue > 0) !=

+             (zzTraceOptionValue > 0)) {

+      if (zzTraceOptionValue > 0) {

+        fprintf(stderr,"trace enable restored in rule %s depth %d\n",

+                        zzTraceCurrentRuleName,zzTraceDepth);

+      };

+      if (zzTraceOptionValue <= 0) {

+        fprintf(stderr,"trace disable restored in rule %s depth %d\n",

+                        zzTraceCurrentRuleName,zzTraceDepth);

+      };

+    };

+

+    zzTraceOptionValue=buf->traceOptionValue;            /* MR10 */

+    zzTraceGuessOptionValue=buf->traceGuessOptionValue;  /* MR10 */

+    zzTraceCurrentRuleName=buf->traceCurrentRuleName;    /* MR10 */

+    zzTraceDepth=buf->traceDepth;                        /* MR10 */

+    zzTraceGuessDone(buf);                               /* MR10 */

+#endif

+}

+

+void

+#ifdef __USE_PROTOS

+zzedecode(SetWordType *a)

+#else

+zzedecode(a)

+SetWordType *a;

+#endif

+{

+	register SetWordType *p = a;

+	register SetWordType *endp = &(p[zzSET_SIZE]);

+	register unsigned e = 0;

+

+	if ( zzset_deg(a)>1 ) fprintf(stderr, " {");

+	do {

+		register SetWordType t = *p;

+		register SetWordType *b = &(bitmask[0]);

+		do {

+			if ( t & *b ) fprintf(stderr, " %s", zztokens[e]);

+			e++;

+		} while (++b < &(bitmask[sizeof(SetWordType)*8]));

+	} while (++p < endp);

+	if ( zzset_deg(a)>1 ) fprintf(stderr, " }");

+}

+

+#ifndef USER_ZZSYN

+/* standard error reporting function */

+void

+#ifdef __USE_PROTOS

+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)

+#else

+zzsyn(text, tok, egroup, eset, etok, k, bad_text)

+char *text, *egroup, *bad_text;

+int tok;

+int etok;

+int k;

+SetWordType *eset;

+#endif

+{

+	

+    zzSyntaxErrCount++;                             /* MR11 */

+	fprintf(stderr, "line %d: syntax error at \"%s\"", zzline, (tok==zzEOF_TOKEN)?"EOF":bad_text);

+	if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}

+	if ( k==1 ) fprintf(stderr, " missing");

+	else

+	{

+		fprintf(stderr, "; \"%s\" not", bad_text);

+		if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");

+	}

+	if ( zzset_deg(eset)>0 ) zzedecode(eset);

+	else fprintf(stderr, " %s", zztokens[etok]);

+	if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup);

+	fprintf(stderr, "\n");

+}

+#endif

+

+/* is b an element of set p? */

+int

+#ifdef __USE_PROTOS

+zzset_el(unsigned b, SetWordType *p)

+#else

+zzset_el(b,p)

+unsigned b;

+SetWordType *p;

+#endif

+{

+	return( p[BSETDIVWORD(b)] & bitmask[BSETMODWORD(b)] );

+}

+

+int

+#ifdef __USE_PROTOS

+zzset_deg(SetWordType *a)

+#else

+zzset_deg(a)

+SetWordType *a;

+#endif

+{

+	/* Fast compute degree of a set... the number

+	   of elements present in the set.  Assumes

+	   that all word bits are used in the set

+	*/

+	register SetWordType *p = a;

+	register SetWordType *endp = &(a[zzSET_SIZE]);

+	register int degree = 0;

+

+	if ( a == NULL ) return 0;

+	while ( p < endp )

+	{

+		register SetWordType t = *p;

+		register SetWordType *b = &(bitmask[0]);

+		do {

+			if (t & *b) ++degree;

+		} while (++b < &(bitmask[sizeof(SetWordType)*8]));

+		p++;

+	}

+

+	return(degree);

+}

+

+#ifdef DEMAND_LOOK

+

+#ifdef LL_K

+int

+#ifdef __USE_PROTOS

+_zzmatch(int _t, char **zzBadText, char **zzMissText,

+		int *zzMissTok, int *zzBadTok,

+		SetWordType **zzMissSet)

+#else

+_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet)

+int _t;

+char **zzBadText;

+char **zzMissText;

+int *zzMissTok, *zzBadTok;

+SetWordType **zzMissSet;

+#endif

+{

+	if ( zzdirty==LL_K ) {

+		zzCONSUME;

+	}

+	if ( LA(1)!=_t ) {

+		*zzBadText = *zzMissText=LATEXT(1);	

+		*zzMissTok= _t; *zzBadTok=LA(1);

+		*zzMissSet=NULL;				

+		return 0;

+	}

+	zzMakeAttr						

+	zzdirty++;						

+	zzlabase++;						

+	return 1;

+}

+

+int

+#ifdef __USE_PROTOS

+_zzmatch_wsig(int _t)

+#else

+_zzmatch_wsig(_t)

+int _t;

+#endif

+{

+	if ( zzdirty==LL_K ) {

+		zzCONSUME;

+	}

+	if ( LA(1)!=_t ) {

+		return 0;

+	}

+	zzMakeAttr						

+	zzdirty++;						

+	zzlabase++;						

+	return 1;

+}

+

+#else

+

+int

+#ifdef __USE_PROTOS

+_zzmatch(int _t, char **zzBadText, char **zzMissText,

+		 int *zzMissTok, int *zzBadTok, SetWordType **zzMissSet)

+#else

+_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet)

+int _t;

+char **zzBadText;

+char **zzMissText;

+int *zzMissTok, *zzBadTok;

+SetWordType **zzMissSet;

+#endif

+{								

+	if ( zzdirty ) {zzCONSUME;}		

+	if ( LA(1)!=_t ) {

+		*zzBadText = *zzMissText=LATEXT(1);	

+		*zzMissTok= _t; *zzBadTok=LA(1);

+		*zzMissSet=NULL;				

+		return 0;

+	}								

+	zzdirty = 1;					

+	zzMakeAttr						

+	return 1;

+}

+

+int

+#ifdef __USE_PROTOS

+_zzmatch_wsig(int _t)

+#else

+_zzmatch_wsig(_t)

+int _t;

+#endif

+{

+	if ( zzdirty ) {zzCONSUME;}		

+	if ( LA(1)!=_t ) {

+		return 0;

+	}

+	zzdirty = 1;					

+	zzMakeAttr						

+	return 1;

+}

+

+#endif /*LL_K*/

+

+#else

+

+int

+#ifdef __USE_PROTOS

+_zzmatch(int _t, char **zzBadText, char **zzMissText,

+		int *zzMissTok, int *zzBadTok,

+		SetWordType **zzMissSet)

+#else

+_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet)

+int _t;

+char **zzBadText;

+char **zzMissText;

+int *zzMissTok, *zzBadTok;

+SetWordType **zzMissSet;

+#endif

+{

+	if ( LA(1)!=_t ) {				

+		*zzBadText = *zzMissText=LATEXT(1);	

+		*zzMissTok= _t; *zzBadTok=LA(1);

+		*zzMissSet=NULL;				

+		return 0;

+	}

+	zzMakeAttr

+	return 1;

+}

+

+int

+#ifdef __USE_PROTOS

+_zzmatch_wsig(int _t)

+#else

+_zzmatch_wsig(_t)

+int _t;

+#endif

+{

+	if ( LA(1)!=_t ) return 0;

+	zzMakeAttr						

+	return 1;

+}

+

+#endif /*DEMAND_LOOK*/

+

+#ifdef ZZINF_LOOK

+void

+#ifdef __USE_PROTOS

+_inf_zzgettok(void)

+#else

+_inf_zzgettok()

+#endif

+{

+	if ( zzinf_labase >= zzinf_last )					

+		{NLA = zzEOF_TOKEN; strcpy(NLATEXT, "");}	

+	else {											

+		NLA = zzinf_tokens[zzinf_labase];

+		zzline = zzinf_line[zzinf_labase];	/* wrong in 1.21 */

+		strcpy(NLATEXT, zzinf_text[zzinf_labase]);		

+		zzinf_labase++; 								

+	}												

+}

+#endif

+

+#ifdef ZZINF_LOOK

+/* allocate default size text,token and line arrays;

+ * then, read all of the input reallocing the arrays as needed.

+ * Once the number of total tokens is known, the LATEXT(i) array (zzinf_text)

+ * is allocated and it's pointers are set to the tokens in zzinf_text_buffer.

+ */

+void

+#ifdef __USE_PROTOS

+zzfill_inf_look(void)

+#else

+zzfill_inf_look()

+#endif

+{

+	int tok, line;

+	int zzinf_token_buffer_size = ZZINF_DEF_TOKEN_BUFFER_SIZE;

+	int zzinf_text_buffer_size = ZZINF_DEF_TEXT_BUFFER_SIZE;

+	int zzinf_text_buffer_index = 0;

+	int zzinf_lap = 0;

+

+	/* allocate text/token buffers */

+	zzinf_text_buffer = (char *) malloc(zzinf_text_buffer_size);

+	if ( zzinf_text_buffer == NULL )

+	{

+		fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n",

+		zzinf_text_buffer_size);

+		exit(PCCTS_EXIT_FAILURE);									

+	}

+	zzinf_tokens = (int *) calloc(zzinf_token_buffer_size,sizeof(int));

+	if ( zzinf_tokens == NULL )

+	{

+		fprintf(stderr,	"cannot allocate token buffer (%d tokens)\n",

+				zzinf_token_buffer_size);

+		exit(PCCTS_EXIT_FAILURE);									

+	}

+    zzinf_line = (int *) calloc(zzinf_token_buffer_size,sizeof(int));

+    if ( zzinf_line == NULL )

+    {

+        fprintf(stderr, "cannot allocate line buffer (%d ints)\n",

+                zzinf_token_buffer_size);

+        exit(PCCTS_EXIT_FAILURE);

+	}

+

+	/* get tokens, copying text to text buffer */

+	zzinf_text_buffer_index = 0;

+	do {

+		zzgettok();

+		line = zzreal_line;

+		while ( zzinf_lap>=zzinf_token_buffer_size )

+		{

+			zzinf_token_buffer_size += ZZINF_BUFFER_TOKEN_CHUNK_SIZE;

+			zzinf_tokens = (int *) realloc(zzinf_tokens,

+												 zzinf_token_buffer_size*sizeof(int));

+			if ( zzinf_tokens == NULL )

+			{

+				fprintf(stderr, "cannot allocate lookahead token buffer (%d tokens)\n",

+						zzinf_token_buffer_size);

+				exit(PCCTS_EXIT_FAILURE);

+			}

+            zzinf_line = (int *) realloc(zzinf_line,

+                                         zzinf_token_buffer_size*sizeof(int));

+            if ( zzinf_line == NULL )

+            {

+                fprintf(stderr, "cannot allocate lookahead line buffer (%d ints)\n",

+                        zzinf_token_buffer_size);

+                exit(PCCTS_EXIT_FAILURE);

+			}

+

+		}

+		while ( (zzinf_text_buffer_index+strlen(NLATEXT)+1) >= zzinf_text_buffer_size )

+		{

+			zzinf_text_buffer_size += ZZINF_BUFFER_TEXT_CHUNK_SIZE;

+			zzinf_text_buffer = (char *) realloc(zzinf_text_buffer,

+												 zzinf_text_buffer_size);

+			if ( zzinf_text_buffer == NULL )

+			{

+				fprintf(stderr,	"cannot allocate lookahead text buffer (%d bytes)\n",

+						zzinf_text_buffer_size);

+				exit(PCCTS_EXIT_FAILURE);

+			}

+		}

+		/* record token and text and line of input symbol */

+		tok = zzinf_tokens[zzinf_lap] = NLA;

+		strcpy(&zzinf_text_buffer[zzinf_text_buffer_index], NLATEXT);

+		zzinf_text_buffer_index += strlen(NLATEXT)+1;

+        zzinf_line[zzinf_lap] = line;

+		zzinf_lap++;

+	} while (tok!=zzEOF_TOKEN);

+	zzinf_labase = 0;

+	zzinf_last = zzinf_lap-1;

+

+	/* allocate ptrs to text of ith token */

+	zzinf_text = (char **) calloc(zzinf_last+1,sizeof(char *));

+	if ( zzinf_text == NULL )

+	{

+		fprintf(stderr,	"cannot allocate lookahead text buffer (%d)\n",

+				zzinf_text_buffer_size);

+		exit(PCCTS_EXIT_FAILURE);										

+	}													

+	zzinf_text_buffer_index = 0;

+	zzinf_lap = 0;

+	/* set ptrs so that zzinf_text[i] is the text of the ith token found on input */

+	while (zzinf_lap<=zzinf_last)

+	{

+	    zzinf_text[zzinf_lap++] = &zzinf_text_buffer[zzinf_text_buffer_index];

+		zzinf_text_buffer_index += strlen(&zzinf_text_buffer[zzinf_text_buffer_index])+1;

+	}

+}

+#endif

+

+int

+#ifdef __USE_PROTOS

+_zzsetmatch(SetWordType *e, char **zzBadText, char **zzMissText,

+			int *zzMissTok, int *zzBadTok,

+			SetWordType **zzMissSet,

+			SetWordType *zzTokclassErrset /* MR23 */)

+#else

+_zzsetmatch(e, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet, zzTokclassErrset /* MR23 */)

+SetWordType *e;

+char **zzBadText;

+char **zzMissText;

+int *zzMissTok, *zzBadTok;

+SetWordType **zzMissSet;

+SetWordType *zzTokclassErrset;

+#endif

+{

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+	if ( zzdirty==LL_K ) {zzCONSUME;}

+#else

+	if ( zzdirty ) {zzCONSUME;}

+#endif

+#endif

+	if ( !zzset_el((unsigned)LA(1), e) ) {

+		*zzBadText = LATEXT(1); *zzMissText=NULL;

+		*zzMissTok= 0; *zzBadTok=LA(1);

+		*zzMissSet=zzTokclassErrset; /* MR23 */

+		return 0;

+	}

+	zzMakeAttr           /* MR14 Ger Hobbelt (hobbelt@axa.nl) */

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+	zzdirty++;

+    zzlabase++;          /* MR14 Ger Hobbelt (hobbelt@axa.nl) */

+#else

+	zzdirty = 1;

+#endif

+#endif

+	return 1;

+}

+

+int

+#ifdef __USE_PROTOS

+_zzmatch_wdfltsig(int tokenWanted, SetWordType *whatFollows)

+#else

+_zzmatch_wdfltsig(tokenWanted, whatFollows)

+int tokenWanted;

+SetWordType *whatFollows;

+#endif

+{

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+	if ( zzdirty==LL_K ) {

+			zzCONSUME;

+	}

+#else

+	if ( zzdirty ) {zzCONSUME;}

+#endif

+#endif

+

+	if ( LA(1)!=tokenWanted )

+	{

+        zzSyntaxErrCount++;     /* MR11 */

+		fprintf(stderr,

+				"line %d: syntax error at \"%s\" missing %s\n",

+				zzline,

+				(LA(1)==zzEOF_TOKEN)?"<eof>":(char *)LATEXT(1),

+				zztokens[tokenWanted]);

+		zzconsumeUntil( whatFollows );

+		return 0;

+	}

+	else {

+		zzMakeAttr						

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+		zzdirty++;

+		zzlabase++;

+#else

+		zzdirty = 1;

+#endif

+#else

+/*		zzCONSUME;		 consume if not demand lookahead */

+#endif

+		return 1;

+	}

+}

+

+int

+#ifdef __USE_PROTOS

+_zzsetmatch_wdfltsig(SetWordType *tokensWanted,

+					 int tokenTypeOfSet,

+					 SetWordType *whatFollows)

+#else

+_zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows)

+SetWordType *tokensWanted;

+int tokenTypeOfSet;

+SetWordType *whatFollows;

+#endif

+{

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+	if ( zzdirty==LL_K ) {zzCONSUME;}

+#else

+	if ( zzdirty ) {zzCONSUME;}

+#endif

+#endif

+	if ( !zzset_el((unsigned)LA(1), tokensWanted) )

+	{

+        zzSyntaxErrCount++;     /* MR11 */

+		fprintf(stderr,

+				"line %d: syntax error at \"%s\" missing %s\n",

+				zzline,

+				(LA(1)==zzEOF_TOKEN)?"<eof>":(char *)LATEXT(1),

+				zztokens[tokenTypeOfSet]);

+		zzconsumeUntil( whatFollows );

+		return 0;

+	}

+	else {

+		zzMakeAttr

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+		zzdirty++;

+		zzlabase++;

+#else

+		zzdirty = 1;

+#endif

+#else

+/*		zzCONSUME;		consume if not demand lookahead */

+#endif

+		return 1;

+	}

+}

+

+int

+#ifdef __USE_PROTOS

+_zzsetmatch_wsig(SetWordType *e)

+#else

+_zzsetmatch_wsig(e)

+SetWordType *e;

+#endif

+{

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+	if ( zzdirty==LL_K ) {zzCONSUME;}

+#else

+	if ( zzdirty ) {zzCONSUME;}

+#endif

+#endif

+	if ( !zzset_el((unsigned)LA(1), e) ) return 0;

+	zzMakeAttr           /* MR14 Ger Hobbelt (hobbelt@axa.nl) */

+#ifdef DEMAND_LOOK

+#ifdef LL_K

+	zzdirty++;

+    zzlabase++;          /* MR14 Ger Hobbelt (hobbelt@axa.nl) */

+#else

+	zzdirty = 1;

+#endif

+#endif

+	return 1;

+}

+

+#ifdef USER_ZZMODE_STACK

+static int  zzmstk[ZZMAXSTK] = { -1 };

+static int  zzmdep = 0;

+static char zzmbuf[70];

+

+void

+#ifdef __USE_PROTOS

+zzmpush( int m )

+#else

+zzmpush( m )

+int m;

+#endif

+{

+   if(zzmdep == ZZMAXSTK - 1) {

+     sprintf(zzmbuf, "Mode stack overflow ");

+     zzerr(zzmbuf);

+   } else {

+     zzmstk[zzmdep++] = zzauto;

+     zzmode(m);

+   }

+}

+

+void

+#ifdef __USE_PROTOS

+zzmpop( void )

+#else

+zzmpop( )

+#endif

+{

+   if(zzmdep == 0)

+   {  sprintf(zzmbuf, "Mode stack underflow ");

+      zzerr(zzmbuf);

+   }

+   else

+   {  zzmdep--;

+      zzmode(zzmstk[zzmdep]);

+   }

+}

+

+void

+#ifdef __USE_PROTOS

+zzsave_mode_stack( int modeStack[], int *modeLevel )

+#else

+zzsave_mode_stack( modeStack, modeLevel )

+int modeStack[];

+int *modeLevel;

+#endif

+{

+  int i;

+  memcpy(modeStack, zzmstk, sizeof(zzmstk));

+  *modeLevel = zzmdep;

+  zzmdep = 0;

+

+  return;

+}

+

+void

+#ifdef __USE_PROTOS

+zzrestore_mode_stack( int modeStack[], int *modeLevel )

+#else

+zzrestore_mode_stack( modeStack, modeLevel )

+int modeStack[];

+int *modeLevel;

+#endif

+{

+  int i;

+

+  memcpy(zzmstk, modeStack, sizeof(zzmstk));

+  zzmdep = *modeLevel;

+

+  return;

+}

+#endif /* USER_ZZMODE_STACK */

+

+#ifdef __USE_PROTOS

+void zzTraceReset(void)

+#else

+void zzTraceReset()

+#endif

+{

+#ifdef zzTRACE_RULES

+  zzTraceOptionValue=zzTraceOptionValueDefault;

+  zzTraceGuessOptionValue=1;

+  zzTraceCurrentRuleName=NULL;

+  zzTraceDepth=0;

+#endif

+}

+

+#ifdef __USE_PROTOS

+void zzTraceGuessFail(void)

+#else

+void zzTraceGuessFail()

+#endif

+{

+

+#ifdef zzTRACE_RULES

+#ifdef ZZCAN_GUESS

+

+  int   doIt=0;

+

+  if (zzTraceOptionValue <= 0) {

+    doIt=0;

+  } else if (zzguessing && zzTraceGuessOptionValue <= 0) {

+    doIt=0;

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    fprintf(stderr,"guess failed\n");

+  };

+#endif

+#endif

+}

+

+/* zzTraceOption:

+     zero value turns off trace

+*/

+

+#ifdef __USE_PROTOS

+void zzTraceIn(char * rule)

+#else

+void zzTraceIn(rule)

+  char  *rule;

+#endif

+{

+#ifdef zzTRACE_RULES

+

+  int           doIt=0;

+

+  zzTraceDepth++;

+  zzTraceCurrentRuleName=rule;

+

+  if (zzTraceOptionValue <= 0) {

+    doIt=0;

+#ifdef ZZCAN_GUESS

+  } else if (zzguessing && zzTraceGuessOptionValue <= 0) {

+    doIt=0;

+#endif

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    fprintf(stderr,"enter rule %s {\"%s\"} depth %d",

+            rule,

+            LA(1)==1 ? "@" : (char *) LATEXT(1),    /* MR19 */

+            zzTraceDepth);

+#ifdef ZZCAN_GUESS

+    if (zzguessing) fprintf(stderr," guessing");

+#endif

+    fprintf(stderr,"\n");

+  };

+#endif

+  return;

+}

+

+#ifdef __USE_PROTOS

+void zzTraceOut(char * rule)

+#else

+void zzTraceOut(rule)

+  char  *rule;

+#endif

+{

+#ifdef zzTRACE_RULES

+  int       doIt=0;

+

+  zzTraceDepth--;

+

+  if (zzTraceOptionValue <= 0) {

+    doIt=0;

+#ifdef ZZCAN_GUESS

+  } else if (zzguessing && zzTraceGuessOptionValue <= 0) {

+    doIt=0;

+#endif

+  } else {

+    doIt=1;

+  };

+

+  if (doIt) {

+    fprintf(stderr,"exit rule %s {\"%s\"} depth %d",

+            rule,

+            LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */

+            zzTraceDepth+1);

+#ifdef ZZCAN_GUESS

+    if (zzguessing) fprintf(stderr," guessing");

+#endif

+    fprintf(stderr,"\n");

+  };

+#endif

+}

+

+#ifdef __USE_PROTOS

+int zzTraceOption(int delta)

+#else

+int zzTraceOption(delta)

+  int   delta;

+#endif

+{

+#ifdef zzTRACE_RULES

+    int     prevValue=zzTraceOptionValue;

+

+    zzTraceOptionValue=zzTraceOptionValue+delta;

+

+    if (zzTraceCurrentRuleName != NULL) {

+      if (prevValue <= 0 && zzTraceOptionValue > 0) {

+        fprintf(stderr,"trace enabled in rule %s depth %d\n",

+                                            zzTraceCurrentRuleName,zzTraceDepth);

+      };

+      if (prevValue > 0 && zzTraceOptionValue <= 0) {

+        fprintf(stderr,"trace disabled in rule %s depth %d\n",

+                                            zzTraceCurrentRuleName,zzTraceDepth);

+      };

+    };

+    return  prevValue;

+#else

+    return 0;

+#endif

+}

+

+#ifdef __USE_PROTOS

+int zzTraceGuessOption(int delta)

+#else

+int zzTraceGuessOption(delta)

+  int   delta;

+#endif

+{

+#ifdef zzTRACE_RULES

+#ifdef ZZCAN_GUESS

+    int     prevValue=zzTraceGuessOptionValue;

+

+    zzTraceGuessOptionValue=zzTraceGuessOptionValue+delta;

+

+    if (zzTraceCurrentRuleName != NULL) {

+      if (prevValue <= 0 && zzTraceGuessOptionValue > 0) {

+        fprintf(stderr,"guess trace enabled in rule %s depth %d\n",

+                                                zzTraceCurrentRuleName,zzTraceDepth);

+      };

+      if (prevValue > 0 && zzTraceGuessOptionValue <= 0) {

+        fprintf(stderr,"guess trace disabled in rule %s depth %d\n",

+                                                zzTraceCurrentRuleName,zzTraceDepth);

+      };

+    };

+    return prevValue;

+#else

+    return 0;

+#endif

+#else

+    return 0;

+#endif

+}

+

+#endif /* ERR_H */

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/int.h b/edk2/Tools/Source/TianoTools/Pccts/h/int.h
new file mode 100644
index 0000000..cdcaa92
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/int.h
@@ -0,0 +1,37 @@
+/* ANTLR attribute definition -- long integers

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * ANTLR 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+#ifndef ZZINT_H

+#define ZZINT_H

+

+typedef long Attrib;

+

+#define zzcr_attr(a,tok,t)	*(a) = atol(t);

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_assert.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_assert.h
new file mode 100644
index 0000000..ff0dfb5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_assert.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_ASSERT_H__

+#define __PCCTS_ASSERT_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <cassert>

+#else

+#include <assert.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_iostream.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_iostream.h
new file mode 100644
index 0000000..972b32c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_iostream.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_IOSTREAM_H__

+#define __PCCTS_IOSTREAM_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <iostream>

+#else

+#include <iostream.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_istream.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_istream.h
new file mode 100644
index 0000000..e25cb8c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_istream.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_ISTREAM_H__

+#define __PCCTS_ISTREAM_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <istream>

+#else

+#include <istream.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_setjmp.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_setjmp.h
new file mode 100644
index 0000000..9ea185c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_setjmp.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_SETJMP_H__

+#define __PCCTS_SETJMP_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <csetjmp>

+#else

+#include <setjmp.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdarg.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdarg.h
new file mode 100644
index 0000000..e957430
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdarg.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STDARG_H__

+#define __PCCTS_STDARG_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <cstdarg>

+#else

+#include <stdarg.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdio.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdio.h
new file mode 100644
index 0000000..ac34d10
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdio.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STDIO_H__

+#define __PCCTS_STDIO_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <cstdio>

+#else

+#include <stdio.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdlib.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdlib.h
new file mode 100644
index 0000000..f0b344e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_stdlib.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STDLIB_H__

+#define __PCCTS_STDLIB_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <cstdlib>

+#else

+#include <stdlib.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pccts_string.h b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_string.h
new file mode 100644
index 0000000..458a08a
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pccts_string.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STRING_H__

+#define __PCCTS_STRING_H__

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#include <cstring>

+#else

+#include <string.h>

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pcctscfg.h b/edk2/Tools/Source/TianoTools/Pccts/h/pcctscfg.h
new file mode 100644
index 0000000..0c3c5ba
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pcctscfg.h
@@ -0,0 +1,359 @@
+#ifndef PCCTS_CONFIG_H

+#define PCCTS_CONFIG_H

+/*

+ * pcctscfg.h (formerly config.h) (for ANTLR, DLG, and SORCERER)

+ *

+ * This is a simple configuration file that doesn't have config stuff

+ * in it, but it's a start.

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool

+ * Set (PCCTS) -- PCCTS is in the public domain.  An individual or

+ * company may do whatever they wish with source code distributed with

+ * PCCTS or the code generated by PCCTS, including the incorporation of

+ * PCCTS, or its output, into commerical software.

+ *

+ * We encourage users to develop software with PCCTS.  However, we do ask

+ * that credit is given to us for developing PCCTS.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like PCCTS and have developed a nice tool with the

+ * output, please mention that you developed it using PCCTS.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * Used by PCCTS 1.33 (SORCERER 1.00B11 and up)

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1989-2000

+ */

+

+/* This file knows about the following ``environments''

+	UNIX    (default)

+	DOS     (use #define PC)

+	MAC     (use #define MPW; has a few things for THINK C, Metrowerks)

+    MS/C++  (MR14 Microsoft Visual C++ environment uses symbol _MSC_VER)

+

+ */

+

+/* should test __STDC__ for 1, but some compilers don't set value, just def */

+

+#ifndef __USE_PROTOS

+#ifdef __STDC__

+#define __USE_PROTOS

+#endif

+#ifdef __cplusplus

+#define __USE_PROTOS

+#endif

+#endif

+

+#ifdef PCCTS_USE_NAMESPACE_STD

+#define PCCTS_NAMESPACE_STD     namespace std {}; using namespace std;

+#else

+#define PCCTS_NAMESPACE_STD

+#endif

+

+#include "pccts_stdio.h"

+#include "pccts_stdlib.h"

+

+/* largest file name size */

+

+#ifdef _MAX_PATH

+#define MaxFileName		_MAX_PATH /* MR9 RJV: MAX_PATH defined in stdlib.h (MSVC++ 5.0) */

+#else

+#define MaxFileName		300

+#endif

+

+/*

+*  Define PC32 if in a 32-bit PC environment (e.g. extended DOS or Win32).

+*  The macros tested here are defined by Watcom, Microsoft, Borland,

+*  and djgpp, respectively, when they are used as 32-bit compilers.

+*  Users of these compilers *must* be sure to define PC in their

+*  makefiles for this to work correctly.

+*/

+#ifdef PC

+# if (defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) || \

+   defined(__GNUC__) || defined(__GNUG__))

+#     ifndef PC32

+#        define PC32

+#     endif

+#  endif

+#endif

+

+/* MR1  10-Apr-97  Default for PC is short file names			            */

+/* MR1		   Default for non-PC is long file names                		*/

+/* MR1		   Can override via command line option LONGFILENAMES           */

+

+#ifndef LONGFILENAMES

+#ifndef PC

+#define LONGFILENAMES

+#endif

+#endif

+

+#ifndef LONGFILENAMES

+#define ATOKEN_H			"AToken.h"

+#define ATOKPTR_H			"ATokPtr.h"

+#define ATOKPTR_IMPL_H		"ATokPtrIm.h"

+#define ATOKENBUFFER_H		"ATokBuf.h"

+#define ATOKENBUFFER_C      "ATokBuf.cpp"

+#define ATOKENSTREAM_H		"ATokStr.h"

+#define APARSER_H			"AParser.h"

+#define APARSER_C           "AParser.cpp"

+#define ASTBASE_H			"ASTBase.h"

+#define ASTBASE_C           "ASTBase.cpp"

+#define PCCTSAST_C          "PCCTSAST.cpp"

+#define LIST_C              "List.cpp"

+#define DLEXERBASE_H		"DLexBase.h"

+#define DLEXERBASE_C        "DLexBase.cpp"

+#define DLEXER_H            "DLexer.h"

+#define STREESUPPORT_C		"STreeSup.C"

+#else

+#define ATOKEN_H			"AToken.h"

+#define ATOKPTR_H			"ATokPtr.h"

+#define ATOKPTR_IMPL_H		"ATokPtrImpl.h"

+#define ATOKENBUFFER_H		"ATokenBuffer.h"

+#define ATOKENBUFFER_C		"ATokenBuffer.cpp"

+#define ATOKENSTREAM_H		"ATokenStream.h"

+#define APARSER_H			"AParser.h"

+#define APARSER_C			"AParser.cpp"

+#define ASTBASE_H			"ASTBase.h"

+#define ASTBASE_C		    "ASTBase.cpp"

+#define PCCTSAST_C			"PCCTSAST.cpp"

+#define LIST_C				"List.cpp"

+#define DLEXERBASE_H		"DLexerBase.h"

+#define DLEXERBASE_C		"DLexerBase.cpp"

+#define DLEXER_H			"DLexer.h"

+#define STREESUPPORT_C		"STreeSupport.cpp"

+#endif

+

+/* SORCERER Stuff */

+

+/* MR8 6-Aug-97     Change from ifdef PC to ifndef LONGFILENAMES            */

+

+#ifndef LONGFILENAMES

+#define STPARSER_H			"STreePar.h"

+#define STPARSER_C			"STreePar.C"

+#else

+#define STPARSER_H			"STreeParser.h"

+#define STPARSER_C			"STreeParser.cpp"

+#endif

+

+#ifdef MPW

+#define CPP_FILE_SUFFIX		".cp"

+#define CPP_FILE_SUFFIX_NO_DOT	"cp"

+#define OBJ_FILE_SUFFIX		".o"

+#else

+#ifdef PC

+#define CPP_FILE_SUFFIX		".cpp"

+#define CPP_FILE_SUFFIX_NO_DOT	"cpp"

+#define OBJ_FILE_SUFFIX		".obj"

+#else

+#ifdef __VMS

+#define CPP_FILE_SUFFIX		".cpp"

+#define CPP_FILE_SUFFIX_NO_DOT	"cpp"

+#define OBJ_FILE_SUFFIX		".obj"

+#else

+#define CPP_FILE_SUFFIX		".cpp"

+#define CPP_FILE_SUFFIX_NO_DOT	"cpp"

+#define OBJ_FILE_SUFFIX		".o"

+#endif

+#endif

+#endif

+

+/* User may redefine how line information looks */     /* make it #line MR7 */

+/* MR21 Use #ifndef */

+

+#ifndef LineInfoFormatStr

+#define LineInfoFormatStr "#line %d \"%s\"\n"

+#endif

+

+#ifdef MPW	                    /* Macintosh Programmer's Workshop */

+#define ErrHdr "File \"%s\"; Line %d #"

+#else

+#ifdef _MSC_VER                 /* MR14 Microsoft Visual C++ environment */

+#define ErrHdr "%s(%d) :"

+#else

+#define ErrHdr "%s, line %d:"   /* default */

+#endif

+#endif

+

+/* must assume old K&R cpp here, can't use #if defined(..)... */

+

+#ifdef MPW

+#define TopDirectory	":"

+#define DirectorySymbol	":"

+#define OutputDirectoryOption "Directory where all output files should go (default=\":\")"

+#else

+#ifdef PC

+#define TopDirectory	"."

+#define DirectorySymbol	"\\"

+#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"

+#else

+#ifdef __VMS

+#define TopDirectory  "[000000]"

+#define DirectorySymbol       "]"

+#define OutputDirectoryOption "Directory where all output files should go (default=\"[]\")"

+#else

+#define TopDirectory	"."

+#define DirectorySymbol	"/"

+#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"

+#endif

+#endif

+#endif

+

+#ifdef MPW

+

+/* Make sure we have prototypes for all functions under MPW */

+

+#include "pccts_string.h"

+#include "pccts_stdlib.h"

+

+/* MR6 2-Jun-97	Fixes false dependency caused by VC++ #include scanner	*/

+/* MR6		   Reported by Brad Schick (schick@interaccess.com)	*/

+#define	MPW_CursorCtl_Header <CursorCtl.h>

+#include MPW_CursorCtl_Header

+#ifdef __cplusplus

+extern "C" {

+#endif

+extern void fsetfileinfo (const char *filename, unsigned long newcreator, unsigned long newtype);

+#ifdef __cplusplus

+}

+#endif

+

+/* File creators for various popular development environments */

+

+#define MAC_FILE_CREATOR 'MPS '   /* MPW Text files */

+#if 0

+#define MAC_FILE_CREATOR 'KAHL'   /* THINK C/Symantec C++ Text files */

+#endif

+#if 0

+#define MAC_FILE_CREATOR 'CWIE'   /* Metrowerks C/C++ Text files */

+#endif

+

+#endif

+

+#ifdef MPW

+#define DAWDLE	SpinCursor(1)

+#else

+#define DAWDLE

+#endif

+

+#ifdef MPW

+#define SPECIAL_INITS

+#define SPECIAL_FOPEN

+#endif

+

+#ifdef MPW

+#ifdef __cplusplus

+inline

+#else

+static

+#endif

+void special_inits()

+{

+  InitCursorCtl((acurHandle) 0);

+}

+#endif

+

+#ifdef MPW

+#ifdef __cplusplus

+inline

+#else

+static

+#endif

+void special_fopen_actions(char * s)

+{

+  fsetfileinfo (s, MAC_FILE_CREATOR, 'TEXT');

+}

+#endif

+

+/* Define usable bits for set.c stuff */

+#define BytesPerWord	sizeof(unsigned)

+#define	WORDSIZE		(sizeof(unsigned)*8)

+#define LogWordSize     (WORDSIZE==16?4:5)

+

+#ifndef TRUE

+#define TRUE 1

+#endif

+#ifndef FALSE

+#define FALSE 0

+#endif

+

+#if defined(VAXC) || defined(__VMS)

+#include <ssdef.h>

+#define PCCTS_EXIT_SUCCESS 1

+#define PCCTS_EXIT_FAILURE SS$_ABORT

+#define zzDIE		return SS$_ABORT;

+#define zzDONE	return 1;

+

+#else /* !VAXC and !__VMS */

+

+#define PCCTS_EXIT_SUCCESS 0

+#define PCCTS_EXIT_FAILURE 1

+#define zzDIE		return 1;

+#define zzDONE	return 0;

+

+#endif

+

+#ifdef USER_ZZMODE_STACK

+# ifndef ZZSTACK_MAX_MODE

+#  define  ZZSTACK_MAX_MODE 32

+# endif

+# define  ZZMAXSTK (ZZSTACK_MAX_MODE * 2)

+#endif

+

+#ifndef DllExportPCCTS

+#define DllExportPCCTS

+#endif

+

+#ifdef PC

+#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME

+#define PCCTS_CASE_INSENSITIVE_FILE_NAME

+#endif

+#endif

+

+#ifdef PC32

+#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME

+#define PCCTS_CASE_INSENSITIVE_FILE_NAME

+#endif

+#endif

+

+#ifdef __VMS

+#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME

+#define PCCTS_CASE_INSENSITIVE_FILE_NAME

+#endif

+#endif

+

+#ifdef __USE_PROTOS

+#ifndef PCCTS_USE_STDARG

+#define PCCTS_USE_STDARG

+#endif

+#endif

+

+#ifdef __STDC__

+#ifndef PCCTS_USE_STDARG

+#define PCCTS_USE_STDARG

+#endif

+#endif

+

+#ifdef __cplusplus

+#ifndef PCCTS_USE_STDARG

+#define PCCTS_USE_STDARG

+#endif

+#endif

+

+#ifdef _MSC_VER

+/*Turn off the warnings for:

+  unreferenced inline/local function has been removed

+*/

+#pragma warning(disable : 4514)

+/* function not expanded */

+#pragma warning(disable : 4710)

+#endif

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/pcnames.bat b/edk2/Tools/Source/TianoTools/Pccts/h/pcnames.bat
new file mode 100644
index 0000000..8784aee
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/pcnames.bat
@@ -0,0 +1,11 @@
+ren aparser.c aparser.cpp

+ren astbase.c astbase.cpp

+ren atokenbu.c atokbuf.cpp

+ren atokenbu.h atokbuf.h

+ren atokenst.h atokstr.h

+ren dlexerba.c dlexbase.cpp

+ren dlexerba.h dlexbase.h

+ren dlexer.c dlexer.cpp

+ren list.c list.cpp

+ren pblackbo.h pblckbox.h

+ren pcctsast.c pcctsast.cpp

diff --git a/edk2/Tools/Source/TianoTools/Pccts/h/slist.cpp b/edk2/Tools/Source/TianoTools/Pccts/h/slist.cpp
new file mode 100644
index 0000000..faf2fe4
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/h/slist.cpp
@@ -0,0 +1,116 @@
+/*

+ * SList.C

+ *

+ * SOFTWARE RIGHTS

+ *

+ * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public

+ * domain.  An individual or company may do whatever they wish with

+ * source code distributed with SORCERER or the code generated by

+ * SORCERER, including the incorporation of SORCERER, or its output, into

+ * commerical software.

+ *

+ * We encourage users to develop software with SORCERER.  However, we do

+ * ask that credit is given to us for developing SORCERER.  By "credit",

+ * we mean that if you incorporate our source code into one of your

+ * programs (commercial product, research project, or otherwise) that you

+ * acknowledge this fact somewhere in the documentation, research report,

+ * etc...  If you like SORCERER and have developed a nice tool with the

+ * output, please mention that you developed it using SORCERER.  In

+ * addition, we ask that this header remain intact in our source code.

+ * As long as these guidelines are kept, we expect to continue enhancing

+ * this system and expect to make other tools available as they are

+ * completed.

+ *

+ * PCCTS 1.33

+ * Terence Parr

+ * Parr Research Corporation

+ * with Purdue University and AHPCRC, University of Minnesota

+ * 1992-2000

+ */

+

+#define ANTLR_SUPPORT_CODE

+

+#include "SList.h"

+#include "pccts_stdarg.h" // MR23

+

+/* Iterate over a list of elements; returns ptr to a new element

+ * in list upon every call and NULL when no more are left.

+ * Very useful like this:

+ *

+ *		cursor = mylist;

+ *		while ( (p=mylist->iterate(&cursor)) ) {

+ *			// place with element p

+ *		}

+ *

+ * The cursor must be initialized to point to the list to iterate over.

+ */

+void *SList::

+iterate(SListNode **cursor)

+{

+	void *e;

+

+	if ( cursor == NULL || *cursor==NULL ) return NULL;

+	if ( head == *cursor ) { *cursor = (*cursor)->next(); }

+	e = (*cursor)->elem();

+	(*cursor) = (*cursor)->next();

+	return e;

+}

+

+/* add an element to end of list. */

+void SList::

+add(void *e)

+{

+	SListNode *p, *tail=NULL;

+	require(e!=NULL, "slist_add: attempting to add NULL list element");

+

+	p = new SListNode;

+	require(p!=NULL, "add: cannot alloc new list node");

+	p->setElem(e);

+	if ( head == NULL )

+	{

+		head = tail = p;

+	}

+	else								/* find end of list */

+	{

+		tail->setNext(p);

+		tail = p;

+	}

+}

+

+void SList::

+lfree()

+{

+	SListNode *p,*q;

+

+	if ( head==NULL ) return;	/* empty list */

+	for (p = head; p!=NULL; p=q)

+	{

+		q = p->next();

+		free(p);

+	}

+}

+

+PCCTS_AST *SList::

+to_ast(SList list)

+{

+	PCCTS_AST *t=NULL, *last=NULL;

+	SListNode *p;

+

+	for (p = head; p!=NULL; p=p->next())

+	{

+		PCCTS_AST *u = (PCCTS_AST *)p->elem();

+		if ( last==NULL ) last = t = u;

+		else { last->setRight(u); last = u; }

+	}

+	return t;

+}

+

+// MR23

+int SList::printMessage(FILE* pFile, const char* pFormat, ...)

+{

+	va_list marker;

+	va_start( marker, pFormat );

+  	int iRet = vfprintf(pFile, pFormat, marker);

+	va_end( marker );

+	return iRet;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/history.ps b/edk2/Tools/Source/TianoTools/Pccts/history.ps
new file mode 100644
index 0000000..e2600d5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/history.ps
@@ -0,0 +1,473 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.06
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Italic
+%%+ font Courier
+%%DocumentSuppliedResources: procset grops 1.06 0
+%%Pages: 3
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.06 0
+
+/setpacking where {
+	pop
+	currentpacking
+	true setpacking
+} if
+
+/grops 120 dict dup begin 
+
+% The ASCII code of the space character.
+/SC 32 def
+
+/A /show load def
+/B { 0 SC 3 -1 roll widthshow } bind def
+/C { 0 exch ashow } bind def
+/D { 0 exch 0 SC 5 2 roll awidthshow } bind def
+/E { 0 rmoveto show } bind def
+/F { 0 rmoveto 0 SC 3 -1 roll widthshow } bind def
+/G { 0 rmoveto 0 exch ashow } bind def
+/H { 0 rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+/I { 0 exch rmoveto show } bind def
+/J { 0 exch rmoveto 0 SC 3 -1 roll widthshow } bind def
+/K { 0 exch rmoveto 0 exch ashow } bind def
+/L { 0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+/M { rmoveto show } bind def
+/N { rmoveto 0 SC 3 -1 roll widthshow } bind def
+/O { rmoveto 0 exch ashow } bind def
+/P { rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+/Q { moveto show } bind def 
+/R { moveto 0 SC 3 -1 roll widthshow } bind def
+/S { moveto 0 exch ashow } bind def
+/T { moveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+
+% name size font SF -
+
+/SF {
+	findfont exch
+	[ exch dup 0 exch 0 exch neg 0 0 ] makefont
+	dup setfont
+	[ exch /setfont cvx ] cvx bind def
+} bind def
+
+% name a c d font MF -
+
+/MF {
+	findfont
+	[ 5 2 roll
+	0 3 1 roll % b
+	neg 0 0 ] makefont
+	dup setfont
+	[ exch /setfont cvx ] cvx bind def
+} bind def
+
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+
+% Guess the page length.
+% This assumes that the imageable area is vertically centered on the page.
+% PLG - length
+
+/PLG {
+	gsave newpath clippath pathbbox grestore
+	exch pop add exch pop
+} bind def
+
+% BP -
+
+/BP {
+	/level0 save def
+	1 setlinecap
+	1 setlinejoin
+	72 RES div dup scale
+	LS {
+		90 rotate
+	} {
+		0 PL translate
+	} ifelse
+	1 -1 scale
+} bind def
+
+/EP {
+	level0 restore
+	showpage
+} bind def
+
+
+% centerx centery radius startangle endangle DA -
+
+/DA {
+	newpath arcn stroke
+} bind def
+
+% x y SN - x' y'
+% round a position to nearest (pixel + (.25,.25))
+
+/SN {
+	transform 
+	.25 sub exch .25 sub exch
+	round .25 add exch round .25 add exch
+	itransform
+} bind def
+	
+% endx endy startx starty DL -
+% we round the endpoints of the line, so that parallel horizontal
+% and vertical lines will appear even
+
+/DL {
+	SN
+	moveto
+	SN
+	lineto stroke
+} bind def
+
+% centerx centery radius DC -
+
+/DC {
+	newpath 0 360 arc closepath
+} bind def
+
+
+/TM matrix def
+
+%  width height centerx centery DE -
+
+/DE {
+	TM currentmatrix pop
+	translate scale newpath 0 0 .5 0 360 arc closepath
+	TM setmatrix
+} bind def
+
+% these are for splines
+
+/RC /rcurveto load def
+/RL /rlineto load def
+/ST /stroke load def
+/MT /moveto load def
+/CL /closepath load def
+
+% fill the last path
+
+% amount FL -
+
+/FL {
+	currentgray exch setgray fill setgray
+} bind def
+
+% fill with the ``current color''
+
+/BL /fill load def
+
+/LW /setlinewidth load def
+% new_font_name encoding_vector old_font_name RE -
+
+/RE {
+	findfont
+	dup maxlength dict begin
+	{
+		1 index /FID ne { def } { pop pop } ifelse
+	} forall
+	/Encoding exch def
+	dup /FontName exch def
+	currentdict end definefont pop
+} bind def
+
+/DEFS 0 def
+
+% hpos vpos EBEGIN -
+
+/EBEGIN {
+	moveto
+	DEFS begin
+} bind def
+
+/EEND /end load def
+
+/CNT 0 def
+/level1 0 def
+
+% llx lly newwid wid newht ht newllx newlly PBEGIN -
+
+/PBEGIN {
+	/level1 save def
+	translate
+	div 3 1 roll div exch scale
+	neg exch neg exch translate
+	% set the graphics state to default values
+	0 setgray
+	0 setlinecap
+	1 setlinewidth
+	0 setlinejoin
+	10 setmiterlimit
+	[] 0 setdash
+	/setstrokeadjust where {
+		pop
+		false setstrokeadjust
+	} if
+	/setoverprint where {
+		pop
+		false setoverprint
+	} if
+	newpath
+	/CNT countdictstack def
+	userdict begin
+	/showpage {} def
+} bind def
+
+/PEND {
+	clear
+	countdictstack CNT sub { end } repeat
+	level1 restore
+} bind def
+
+end def
+
+/setpacking where {
+	pop
+	setpacking
+} if
+%%EndResource
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Courier
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
+792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
+/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
+/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
+/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
+/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
+/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
+/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
+/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
+/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
+/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
+/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
+/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
+/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
+/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE/Times-Italic@0
+ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 13/Times-Roman@0 SF(The History of PCCTS)228.232 84 Q/F1 11/Times-Roman@0
+SF(The Purdue Compiler)190.468 108 Q(-Construction T)-.22 E(ool Set)-.88 E/F2
+10/Times-Italic@0 SF -.92(Te)262.245 144 S -.37(re).92 G(nce P).37 E(arr)-.8 E
+/F3 10/Times-Roman@0 SF -.15(Pa)234.755 156 S(rr Research Corporation).15 E
+(Minneapolis, Minnesota)239.39 168 Q(and)280.78 180 Q(Uni)239.315 192 Q -.15
+(ve)-.25 G(rsity of Minnesota).15 E
+(Army High Performance Computing Research Center)180.38 204 Q F2
+([Updated 8-7-94])252.31 228 Q F1 .084(The PCCTS project be)97 259.6 R -.055
+(ga)-.165 G 2.834(na).055 G 2.833(sap)220.547 259.6 S(arser)240.876 259.6 Q
+.083(-generator project for a graduate course at Purdue Uni-)-.22 F -.165(ve)72
+275.6 S 1.085(rsity in the F).165 F 1.086
+(all of 1988 taught by Hank Dietz\212 translator)-.165 F 1.086
+(-writing systems.)-.22 F 1.086(Under the guid-)6.586 F .627
+(ance of Professor Dietz, the parser generator)72 291.6 R 3.377(,A)-.44 G .626
+(NTLR \(originally called YUCC\), continued after)285.18 291.6 R .253
+(the termination of the course and e)72 307.6 R -.165(ve)-.275 G .254
+(ntually became the subject of T).165 F .254(erence P)-.77 F(arr')-.165 E 3.004
+(sM)-.605 G(aster')445.083 307.6 Q 3.004(st)-.605 G(hesis.)479.25 307.6 Q
+(Originally)72 323.6 Q 4.092(,l)-.715 G -.165(ex)126.406 323.6 S 1.342
+(ical analysis w).165 F 1.342(as performed via ALX which w)-.11 F 1.342
+(as soon replaced by W)-.11 F 1.341(ill Cohen')-.44 F(s)-.605 E .594
+(DLG in the F)72 339.6 R .594(all of 1989 \(DF)-.165 F .595(A-based le)-.814 F
+.595(xical-analyzer generator)-.165 F 3.345(,a)-.44 G .595(lso an of)367.188
+339.6 R .595(fshoot of the graduate)-.275 F(translation course\).)72 355.6 Q
+.877(The alpha v)97 375.2 R .877(ersion of ANTLR w)-.165 F .877(as totally re)
+-.11 F .876(written resulting in 1.00B.)-.275 F -1.221(Ve)6.376 G .876
+(rsion 1.00B w)1.221 F(as)-.11 E 1.577(released via an internet ne)72 391.2 R
+1.577(wsgroup \(comp.compilers\) posting in February of 1990 and quickly)-.275
+F -.055(ga)72 407.2 S .356(thered a lar).055 F .356(ge follo)-.198 F 3.106
+(wing. 1.00B)-.275 F .356(generated only LL\(1\) parsers, b)3.106 F .356
+(ut allo)-.22 F .356(wed the mer)-.275 F .356(ged descrip-)-.198 F 1.859
+(tion of le)72 423.2 R 1.859(xical and syntactic analysis.)-.165 F 1.86
+(It had rudimentary attrib)7.359 F 1.86(ute handling similar to that of)-.22 F
+-.55 -1.32(YA C)72 439.2 T 3.549(Ca)1.32 G .799
+(nd did not incorporate rule parameters or return v)109.231 439.2 R .798
+(alues; do)-.275 F(wnw)-.275 E .798(ard inheritance w)-.11 F .798(as v)-.11 F
+(ery)-.165 E -.165(aw)72 455.2 S(kw).165 E 6.433(ard. 1.00B-generated)-.11 F
+3.684(parsers terminated upon the \214rst syntax error)6.433 F 9.184(.L)-.605 G
+-.165(ex)440.916 455.2 S 3.684(ical classes).165 F(\(modes\) were not allo)72
+471.2 Q(wed and DLG did not ha)-.275 E .33 -.165(ve a)-.22 H 2.75(ni).165 G
+(nteracti)305.959 471.2 Q .33 -.165(ve m)-.275 H(ode.).165 E .831
+(Upon starting his Ph.D. at Purdue in the F)97 490.8 R .83(all of 1990, T)-.165
+F .83(erence P)-.77 F .83(arr be)-.165 F -.055(ga)-.165 G 3.58(nt).055 G .83
+(he second total)436.351 490.8 R(re)72 506.8 Q 1.646(write of ANTLR.)-.275 F
+1.646(The method by which grammars may be practically analyzed to generate)
+7.146 F/F4 11/Times-Italic@0 SF(LL)72.638 522.8 Q F1(\().583 E F4(k).396 E F1
+3.849(\)l).737 G 1.099(ookahead information w)105.703 522.8 R 1.099(as disco)
+-.11 F -.165(ve)-.165 G 1.099(red in August of 1990 just before his return.)
+.165 F -1.221(Ve)6.598 G(rsion)1.221 E .626
+(1.00 incorporated this algorithm and included the AST mechanism, le)72 538.8 R
+.626(xical classes, error classes,)-.165 F .354(and automatic error reco)72
+554.8 R -.165(ve)-.165 G .353(ry; code quality and portability were higher).165
+F 5.853(.I)-.605 G 3.103(nF)395.965 554.8 S .353(ebruary of 1992 1.00)410.684
+554.8 R -.11(wa)72 570.8 S 2.76(sr).11 G .01
+(eleased via an article in SIGPLAN Notices.)95.418 570.8 R .01
+(Peter Dahl, Ph.D. candidate, and Professor Matt)5.51 F(O'K)72 586.8 Q 2.074
+(eefe \(both at the Uni)-.275 F -.165(ve)-.275 G 2.073
+(rsity of Minnesota\) tested this v).165 F 2.073(ersion e)-.165 F(xtensi)-.165
+E -.165(ve)-.275 G(ly).165 E 7.573(.D)-.715 G 2.073(ana Hogg)448.522 586.8 R
+(att)-.055 E .078(\(Micro Data Base Systems, Inc.\) came up with the idea of e\
+rror grouping \(strings attached to non-)72 602.8 R
+(terminals\) and tested 1.00 hea)72 618.8 Q(vily)-.22 E(.)-.715 E -1.221(Ve)97
+638.4 S .878(rsion 1.06 w)1.221 F .877
+(as released in December 1992 and represented a lar)-.11 F .877
+(ge feature enhancement)-.198 F -.165(ove)72 654.4 S 3.648(r1).165 G 3.648
+(.00. F)100.365 654.4 R .898(or e)-.165 F .899
+(xample, rudimentary semantic predicates were introduced, error messages were)
+-.165 F 2.281(signi\214cantly impro)72 670.4 R -.165(ve)-.165 G 5.031(df).165 G
+(or)181.953 670.4 Q F4(k)5.427 E F1 2.281
+(>1 lookahead and ANTLR parsers could indicate that lookahead).737 F 1.381
+(fetches were to occur only when necessary for the parse \(normally)72 686.4 R
+4.131(,t)-.715 G 1.381(he lookahead `)387.051 686.4 R(`pipe')-.814 E 4.132('w)
+-.814 G(as)494.837 686.4 Q 1.182(constantly full\).)72 702.4 R 1.182
+(Russell Quong joined the project in the Spring of 1992 to aid in the semantic)
+6.682 F .681(predicate design.)72 718.4 R(Be)6.181 E .681(ginning and adv)-.165
+F .682(anced tutorials were created and released as well.)-.275 F 3.432(Am)
+6.182 G(ak)485.179 718.4 Q(e-)-.11 E .993(\214le generator w)72 734.4 R .993
+(as included that sets up dependencies and such correctly for ANTLR and DLG.)
+-.11 F EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 11/Times-Roman@0 SF 2.75(-2-)278.837 52 S -1.221(Ve)72 88 S 1.414(ry fe)
+1.221 F 4.164(w1)-.275 G 1.414(.00 incompatibilities were introduced \(1.00 w)
+122.81 88 R 1.415(as quite dif)-.11 F 1.415(ferent from 1.00B in some)-.275 F
+(areas\).)72 104 Q 1.089(1.10 w)97 123.6 R 1.088
+(as released on August 31, 1993 and incorporated b)-.11 F 1.088(ug \214x)-.22 F
+1.088(es, a fe)-.165 F 3.838(wf)-.275 G 1.088(eature enhance-)433.59 123.6 R
+3.112(ments and a major ne)72 139.6 R 5.863(wc)-.275 G(apability \212)196.957
+139.6 Q 3.113(an arbitrary lookahead operator \(syntactic predicate\),)5.863 F
+/F1 11/Courier@0 SF(\(alpha\)?beta)72 155.6 Q F0 6.754(.T)C 1.254
+(his feature w)167.425 155.6 R 1.254
+(as co-designed with Professor Russell Quong also at Purdue.)-.11 F 3.297 -.88
+(To s)72 171.6 T 1.537
+(upport in\214nite lookahead, a preprocessor \215ag, ZZINF_LOOK, w).88 F 1.537
+(as created that forced the)-.11 F .21(ANTLR\(\) macro to tok)72 187.6 R .21
+(enize all input prior to parsing.)-.11 F .209(Hence, at an)5.709 F 2.959(ym)
+-.165 G .209(oment, an action or predi-)389.215 187.6 R .936
+(cate can see the entire input sentence.)72 203.6 R .936
+(The predicate mechanism of 1.06 w)6.436 F .937(as e)-.11 F .937
+(xtended to allo)-.165 F(w)-.275 E .55
+(multiple predicates to be hoisted; the syntactic conte)72 219.6 R .55
+(xt of a predicate w)-.165 F .55(as also mo)-.11 F -.165(ve)-.165 G 3.299(da)
+.165 G .549(long with)461.585 219.6 R(the predicate.)72 235.6 Q .754
+(In February of 1994, SORCERER \(a simple tree-parser generator\) w)97 255.2 R
+.755(as released.)-.11 F .755(This tool)6.255 F(allo)72 271.2 Q .6(ws the user\
+ to parse child-sibling trees by specifying a grammar rather than b)-.275 F
+.599(uilding a recur)-.22 F(-)-.22 E(si)72 287.2 Q -.165(ve)-.275 G 1.39
+(-descent tree w).165 F(alk)-.11 E 1.391(er by hand.)-.11 F -.88(Wo)6.891 G
+1.391(rk to).88 F -.11(wa)-.275 G 1.391
+(rds a library of tree transformations is underw).11 F(ay)-.11 E(.)-.715 E .581
+(Aaron Sa)72 303.2 R(wde)-.165 E 3.331(ya)-.165 G 3.331(tT)145.531 303.2 S .581
+(he Uni)158.641 303.2 R -.165(ve)-.275 G .58
+(rsity of Minnesota became a second author of SORCERER after the).165 F
+(initial release.)72 319.2 Q .627(On April 1, 1994, PCCTS 1.20 w)97 338.8 R
+.627(as released.)-.11 F .627(This w)6.127 F .627(as the \214rst v)-.11 F .627
+(ersion to acti)-.165 F -.165(ve)-.275 G .627(ly support).165 F 1.664
+(C++ output.)72 354.8 R 1.664(It also included important \214x)7.164 F 1.663
+(es re)-.165 F -.055(ga)-.165 G 1.663
+(rding semantic predicates and \(..\)+ subrules.).055 F(This v)72 370.8 Q
+(ersion also introduced tok)-.165 E(en classes, the `)-.11 E(`)-.814 E/F2 11
+/Times-Italic@0 SF(not)A F0 1.628 -.814('' o)D(perator).814 E 2.75(,a)-.44 G
+(nd tok)355.294 370.8 Q(en ranges.)-.11 E .764
+(On June 19, 1994, SORCERER 1.00B9 w)97 390.4 R .765(as released.)-.11 F .765
+(Gary Funck of Intrepid T)6.265 F(echnology)-.77 E .807
+(joined the SORCERER team and pro)72 406.4 R .807(vided v)-.165 F .807(ery v)
+-.165 F .807(aluable suggestions re)-.275 F -.055(ga)-.165 G .806(rding the `)
+.055 F(`transform')-.814 E(')-.814 E(mode of SORCERER.)72 422.4 Q 1.137
+(On August 8, 1994, PCCTS 1.21 w)97 442 R 1.137(as released.)-.11 F 1.138
+(It mainly cleaned up the C++ output and)6.637 F(included a number of b)72 458
+Q(ug \214x)-.22 E(es.)-.165 E .316(From the 1.21 release forw)97 477.6 R .316
+(ard, the maintenance and support of all PCCTS tools will be pri-)-.11 F 1.557
+(marily pro)72 493.6 R 1.557(vided by P)-.165 F 1.557
+(arr Research Corporation, Minneapolis MN---an or)-.165 F -.055(ga)-.198 G
+1.558(nization founded on).055 F 1.616(the principles of e)72 509.6 R 1.616
+(xcellence in research and inte)-.165 F 1.616(grity in b)-.165 F 1.616
+(usiness; we are de)-.22 F -.22(vo)-.275 G 1.616(ted to pro).22 F(viding)-.165
+E 1.202(really cool softw)72 525.6 R 1.202(are tools.)-.11 F 1.202
+(Please see \214le PCCTS.FUTURE for more information.)6.702 F 1.203(All PCCTS)
+6.703 F(tools currently in the public domain will continue to be in the public\
+ domain.)72 541.6 Q 1.198(Looking to)97 561.2 R -.11(wa)-.275 G 1.198
+(rds the future, a graphical user).11 F(-interf)-.22 E 1.197
+(ace is in the design phase.)-.11 F 1.197(This w)6.697 F(ould)-.11 E(allo)72
+577.2 Q 2.753(wu)-.275 G .003(sers to vie)104.42 577.2 R 2.753(wt)-.275 G .004
+(he syntax diagram representation of their grammars and w)162.509 577.2 R .004
+(ould highlight non-)-.11 F 1.181(deterministic productions.)72 593.2 R -.165
+(Pa)6.681 G 1.18(rsing can be traced graphically as well.).165 F 1.18
+(This system will be b)6.68 F(uilt)-.22 E .167(using a multiplatform windo)72
+609.2 R 2.917(wl)-.275 G(ibrary)211.73 609.2 Q 5.667(.W)-.715 G 2.917(ea)
+255.204 609.2 S .168(lso anticipate the introduction of a sophisticated error)
+267.889 609.2 R(handling mechanism called `)72 625.2 Q(`parser e)-.814 E
+(xception handling')-.165 E 2.75('i)-.814 G 2.75(nan)327.431 625.2 S
+(ear future release.)348.815 625.2 Q(Currently)97 644.8 Q 3.019(,P)-.715 G .269
+(CCTS is used at o)150.333 644.8 R -.165(ve)-.165 G 3.019(r1).165 G .269
+(000 kno)253.098 644.8 R .268(wn academic, go)-.275 F -.165(ve)-.165 G .268
+(rnment, and commercial sites).165 F .859(in 37 countries.)72 660.8 R .859
+(Of course, the true number of users is unkno)6.359 F .859(wn due to the lar)
+-.275 F .859(ge number of ftp)-.198 F(sites.)72 676.8 Q EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 11/Times-Roman@0 SF 2.75(-3-)278.837 52 S(Credits)272.11 88 Q .44 LW
+472.162 103.75 103.838 103.75 DL(Idea/T)134.236 117 Q 52.987(ool Coder)-.88 F
+(Co-designer\(s\))345.436 117 Q 281.334 103.75 281.334 124.75 DL 209.273 103.75
+209.273 124.75 DL 209.273 124.75 103.838 124.75 DL 103.838 126.75 209.273
+126.75 DL 281.334 124.75 209.273 124.75 DL 209.273 126.75 281.334 126.75 DL
+472.162 124.75 281.334 124.75 DL 281.334 126.75 472.162 126.75 DL(ANTLR 1.00A)
+109.338 140 Q -.77(Te)217.523 140 S(rence P).77 E 13.75(arr Hank)-.165 F(Dietz)
+2.75 E 82.83(ALX T)109.338 156 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz)
+2.75 E(ANTLR 1.00B)109.338 172 Q -.77(Te)217.523 172 S(rence P).77 E 13.75
+(arr Hank)-.165 F(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00B)109.338 188 Q -.44
+(Wi)217.523 188 S(ll Cohen).44 E -.77(Te)289.584 188 S(rence P).77 E(arr)-.165
+E 2.75(,H)-.44 G(ank Dietz)358.147 188 Q(NF)109.338 204 Q 2.75(AR)-.814 G
+30.778(elabelling W)140.611 204 R(ill Cohen)-.44 E/F1 11/Times-Italic@0 SF(LL)
+109.976 220 Q F0(\().583 E F1(k).396 E F0 2.75(\)a).737 G 40.447(nalysis T)
+143.768 220 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz)2.75 E(ANTLR 1.00)
+109.338 236 Q -.77(Te)217.523 236 S(rence P).77 E 13.75(arr Hank)-.165 F
+(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00)109.338 252 Q -.44(Wi)217.523 252 S
+(ll Cohen).44 E -.77(Te)289.584 252 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G
+(ank Dietz)358.147 252 Q(ANTLR 1.06)109.338 268 Q -.77(Te)217.523 268 S
+(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong, Hank Dietz)-.44 E
+(DLG 1.06)109.338 284 Q -.44(Wi)217.523 284 S(ll Cohen).44 E -.77(Te)289.584
+284 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G(ank Dietz)358.147 284 Q
+(ANTLR 1.10)109.338 300 Q -.77(Te)217.523 300 S(rence P).77 E 13.75(arr W)-.165
+F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.20)109.338 316 Q -.77(Te)217.523 316
+S(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.21)
+109.338 332 Q -.77(Te)217.523 332 S(rence P).77 E 13.75(arr Russell)-.165 F
+(Quong)2.75 E(DLG 1.10)109.338 348 Q -.44(Wi)217.523 348 S(ll Cohen).44 E -.77
+(Te)289.584 348 S(rence P).77 E(arr)-.165 E(DLG 1.20)109.338 364 Q -.44(Wi)
+217.523 364 S(ll Cohen).44 E -.77(Te)289.584 364 S(rence P).77 E(arr)-.165 E
+(DLG 1.21)109.338 380 Q -.77(Te)217.523 380 S(rence P).77 E(arr)-.165 E
+(Semantic predicates)109.338 396 Q -.77(Te)217.523 396 S(rence P).77 E 13.75
+(arr Russell)-.165 F(Quonq)2.75 E(Syntactic predicates)109.338 412 Q -.77(Te)
+217.523 412 S(rence P).77 E 13.75(arr Russell)-.165 F(Quonq)2.75 E
+(SORCERER 1.00A)109.338 428 Q -.77(Te)217.523 428 S(rence P).77 E(arr)-.165 E
+(SORCERER 1.00B)109.338 444 Q -.77(Te)217.523 444 S(rence P).77 E 13.75
+(arr Aaron)-.165 F(Sa)2.75 E(wde)-.165 E(y)-.165 E(SORCERER 1.00B9)109.338 460
+Q -.77(Te)217.523 460 S(rence P).77 E 13.75(arr Aaron)-.165 F(Sa)2.75 E(wde)
+-.165 E 1.43 -.715(y, G)-.165 H(ary Funck).715 E 472.162 467.75 103.838 467.75
+DL 472.162 103.75 472.162 467.75 DL 103.838 103.75 103.838 467.75 DL EP
+%%Trailer
+end
+%%EOF
diff --git a/edk2/Tools/Source/TianoTools/Pccts/history.txt b/edk2/Tools/Source/TianoTools/Pccts/history.txt
new file mode 100644
index 0000000..89ad840
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/history.txt
@@ -0,0 +1,186 @@
+

+

+

+                    The History of PCCTS

+

+         The Purdue Compiler-Construction Tool Set

+

+

+                        Terence Parr

+                 Parr Research Corporation

+                   Minneapolis, Minnesota

+                            and

+                  University of Minnesota

+      Army High Performance Computing Research Center

+

+                      [Updated 8-7-94]

+

+

+     The PCCTS project began as a parser-generator project for a  gra-

+duate  course  at Purdue University in the Fall of 1988 taught by Hank

+Dietz- translator-writing systems.  Under the  guidance  of  Professor

+Dietz, the parser generator, ANTLR (originally called YUCC), continued

+after the termination of the course and eventually became the  subject

+of  Terence  Parr's Master's thesis.  Originally, lexical analysis was

+performed via ALX which was soon replaced by Will Cohen's DLG  in  the

+Fall  of  1989 (DFA-based lexical-analyzer generator, also an offshoot

+of the graduate translation course).

+

+     The alpha version of ANTLR was  totally  rewritten  resulting  in

+1.00B.    Version   1.00B  was  released  via  an  internet  newsgroup

+(comp.compilers) posting in February of 1990 and  quickly  gathered  a

+large  following.  1.00B generated only LL(1) parsers, but allowed the

+merged description of lexical and syntactic analysis.  It had rudimen-

+tary  attribute  handling  similar  to that of YACC and did not incor-

+porate rule parameters or return values; downward inheritance was very

+awkward.   1.00B-generated  parsers  terminated  upon the first syntax

+error.  Lexical classes (modes) were not allowed and DLG did not  have

+an interactive mode.

+

+     Upon starting his Ph.D. at Purdue in the Fall  of  1990,  Terence

+Parr  began  the  second  total rewrite of ANTLR.  The method by which

+grammars may be  practically  analyzed  to  generate  LL(k)  lookahead

+information  was  discovered in August of 1990 just before his return.

+Version 1.00 incorporated this algorithm and included the AST  mechan-

+ism,  lexical  classes,  error  classes, and automatic error recovery;

+code quality and portability were higher.  In February  of  1992  1.00

+was  released  via  an  article in SIGPLAN Notices.  Peter Dahl, Ph.D.

+candidate, and Professor Matt O'Keefe (both at the University of  Min-

+nesota)  tested  this  version  extensively.  Dana Hoggatt (Micro Data

+Base Systems, Inc.) came up with the idea of error  grouping  (strings

+attached to non-terminals) and tested 1.00 heavily.

+

+     Version 1.06 was released in  December  1992  and  represented  a

+large  feature enhancement over 1.00.  For example, rudimentary seman-

+tic predicates were  introduced,  error  messages  were  significantly

+improved  for k>1 lookahead and ANTLR parsers could indicate that loo-

+kahead fetches were  to  occur  only  when  necessary  for  the  parse

+

+

+

+                                                                Page 1

+

+                                                                 PCCTS

+

+

+(normally,  the  lookahead "pipe" was constantly full).  Russell Quong

+joined the project in the Spring of 1992 to aid in the semantic predi-

+cate  design.   Beginning  and  advanced  tutorials  were  created and

+released as well.  A makefile generator  was  included  that  sets  up

+dependencies  and  such  correctly  for  ANTLR and DLG.  Very few 1.00

+incompatibilities were introduced (1.00 was quite different from 1.00B

+in some areas).

+

+     1.10 was released on August 31, 1993 and incorporated bug  fixes,

+a  few  feature enhancements and a major new capability - an arbitrary

+lookahead operator (syntactic predicate), (alpha)?beta.  This  feature

+was  co-designed with Professor Russell Quong also at Purdue.  To sup-

+port infinite lookahead, a preprocessor flag, ZZINF_LOOK, was  created

+that  forced the ANTLR() macro to tokenize all input prior to parsing.

+Hence, at any moment, an action or predicate can see the entire  input

+sentence.   The predicate mechanism of 1.06 was extended to allow mul-

+tiple predicates to be hoisted; the syntactic context of  a  predicate

+was also moved along with the predicate.

+

+     In February of 1994, SORCERER (a  simple  tree-parser  generator)

+was  released.  This tool allows the user to parse child-sibling trees

+by specifying a grammar rather than building a recursive-descent  tree

+walker  by  hand.   Work  towards a library of tree transformations is

+underway.  Aaron Sawdey at The University of Minnesota became a second

+author of SORCERER after the initial release.

+

+     On April 1, 1994, PCCTS 1.20 was released.  This  was  the  first

+version  to  actively  support C++ output.  It also included important

+fixes regarding semantic predicates and (..)+ subrules.  This  version

+also introduced token classes, the "not" operator, and token ranges.

+

+     On June 19, 1994, SORCERER 1.00B9 was released.   Gary  Funck  of

+Intrepid  Technology  joined the SORCERER team and provided very valu-

+able suggestions regarding the "transform" mode of SORCERER.

+

+     On August 8, 1994, PCCTS 1.21 was released.  It mainly cleaned up

+the C++ output and included a number of bug fixes.

+

+     From the 1.21 release forward, the maintenance and support of all

+PCCTS  tools  will be primarily provided by Parr Research Corporation,

+Minneapolis MN---an organization founded on the principles  of  excel-

+lence in research and integrity in business; we are devoted to provid-

+ing really cool software tools.  Please see file PCCTS.FUTURE for more

+information.  All PCCTS tools currently in the public domain will con-

+tinue to be in the public domain.

+

+     Looking towards the future, a graphical user-interface is in  the

+design  phase.   This  would  allow  users  to view the syntax diagram

+representation of their grammars and would highlight  nondeterministic

+productions.   Parsing can be traced graphically as well.  This system

+will be built using a multiplatform window library.  We  also  antici-

+pate  the  introduction  of  a  sophisticated error handling mechanism

+called "parser exception handling" in a near future release.

+

+

+

+

+                                                                Page 2

+

+                                                                 PCCTS

+

+

+     Currently, PCCTS is used at over 1000 known academic, government,

+and  commercial  sites in 37 countries.  Of course, the true number of

+users is unknown due to the large number of ftp sites.

+                               Credits

+

+_____________________________________________________________________________

+_____________________________________________________________________________

+|ANTLR 1.00A            Terence Parr   Hank Dietz                           |

+|ALX                    Terence Parr   Hank Dietz                           |

+|ANTLR 1.00B            Terence Parr   Hank Dietz, Will Cohen               |

+|DLG 1.00B              Will Cohen     Terence Parr, Hank Dietz             |

+|NFA Relabelling        Will Cohen                                          |

+|LL(k) analysis         Terence Parr   Hank Dietz                           |

+|ANTLR 1.00             Terence Parr   Hank Dietz, Will Cohen               |

+|DLG 1.00               Will Cohen     Terence Parr, Hank Dietz             |

+|ANTLR 1.06             Terence Parr   Will Cohen, Russell Quong, Hank Dietz|

+|DLG 1.06               Will Cohen     Terence Parr, Hank Dietz             |

+|ANTLR 1.10             Terence Parr   Will Cohen, Russell Quong            |

+|ANTLR 1.20             Terence Parr   Will Cohen, Russell Quong            |

+|ANTLR 1.21             Terence Parr   Russell Quong                        |

+|DLG 1.10               Will Cohen     Terence Parr                         |

+|DLG 1.20               Will Cohen     Terence Parr                         |

+|DLG 1.21               Terence Parr                                        |

+|Semantic predicates    Terence Parr   Russell Quonq                        |

+|Syntactic predicates   Terence Parr   Russell Quonq                        |

+|SORCERER 1.00A         Terence Parr                                        |

+|SORCERER 1.00B         Terence Parr   Aaron Sawdey                         |

+|SORCERER 1.00B9        Terence Parr   Aaron Sawdey, Gary Funck             |

+|___________________________________________________________________________|

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+                                                                Page 3

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/makefile b/edk2/Tools/Source/TianoTools/Pccts/makefile
new file mode 100644
index 0000000..f9b2dd2
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/makefile
@@ -0,0 +1,66 @@
+#

+# Main makefile for PCCTS 1.33MR33	/* MRXXX */

+#

+# Terence Parr

+# Parr Research Corporation

+#

+# verbosity versus silence...

+PSss=

+#

+# this can be set to /user/local/bin etc...

+BINDIR=bin

+# This part added by Thomas Herter, M"unchen, Germany. See also manpages

+# target.

+MANDIR=$(HOME)/man

+MANEXT=1

+MANFILES=dlg/dlg.1 antlr/antlr.1

+

+#CC=cc

+#CC=gcc

+#COPT=-O2

+

+pccts:

+	@echo " "

+	@echo "             Welcome to PCCTS 1.33MR33 installation"

+	@echo " "

+	@echo "             (Version 1.33 Maintenance Release #33)" # mrxxx

+	@echo " "

+	@echo "                  Released 19 April 2002"

+	@echo " "

+	@echo "                        Featuring"

+	@echo "         ANTLR     -- ANother Tool for Language Recognition"

+	@echo "         DLG       -- DFA-based Lexical Analyzer Generator"

+	@echo "         SORCERER  -- Source-to-source translator (tree walker)" 

+	@echo " "

+	@echo "                  http://www.antlr.org"	

+	@echo " "

+	@echo "             Trouble reports to tmoog@polhode.com"

+	@echo "             Additional PCCTS 1.33 information at"

+	@echo "                  http://www.polhode.com"

+	@echo

+	@echo

+	@echo "To substitute gcc for CC to invoke compiler: make CC=gcc"

+	@echo "If there are problems with cr and lf try: unzip -a ..."

+	@echo

+#

+	@if [ ! -d $(BINDIR) ] ; then mkdir $(BINDIR) ; fi

+	@echo Making executables...

+	(cd ./antlr; $(MAKE) CC="$(CC)" COPT="$(COPT)")

+	@echo antlr executable now in $(BINDIR)

+	(cd ./dlg; $(MAKE) CC="$(CC)" COPT="$(COPT)")

+	@echo dlg executable now in $(BINDIR)

+	@echo

+	@echo "       PCCTS 1.33MR33 installation complete"  # MRXXX

+

+clean:

+	(cd ./antlr; $(MAKE) -s clean)

+	(cd ./dlg; $(MAKE) -s clean)

+

+

+manpages:

+	# mkdir -p $(MANDIR)/man$(MANEXT)

+	if [ ! -d $(MANDIR) ] ; then \

+	  mkdir $(MANDIR) ; fi

+	if [ ! -d $(MANDIR)/man$(MANEXT) ] ; then \

+	  mkdir $(MANDIR)/man$(MANEXT); fi

+	cp -p $(MANFILES) $(MANDIR)/man$(MANEXT)

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/genmk/genmk.c b/edk2/Tools/Source/TianoTools/Pccts/support/genmk/genmk.c
new file mode 100644
index 0000000..4952a30
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/genmk/genmk.c
@@ -0,0 +1,1063 @@
+/*

+ * genmk -- a program to make makefiles for PCCTS

+ *

+ * ANTLR 1.33MR23

+ * Terence John Parr 1989 - 2000

+ * Purdue University

+ * U of MN

+ */

+

+#include <stdio.h>

+#include <string.h>

+#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */

+

+#ifdef VAXC

+#define DIE		return 0;

+#define DONE	return 1;

+#else

+#define DIE		return 1;

+#define DONE	return 0;

+#endif

+

+#ifndef require

+#define require(expr, err) {if ( !(expr) ) fatal(err);}

+#endif

+

+#define MAX_FILES	50

+#define MAX_CFILES	1600

+#define MAX_SFILES	50

+#define MAX_SORS	50

+#define MAX_CLASSES	50

+

+char *RENAME_OBJ_FLAG="-o",

+     *RENAME_EXE_FLAG="-o";

+

+char *dlg = "parser.dlg";

+char *err = "err.c";

+char *hdr = "stdpccts.h";

+char *tok = "tokens.h";

+char *mode = "mode.h";

+char *scan = "scan";

+

+char ATOKENBUFFER_O[100];

+char APARSER_O[100];

+char ASTBASE_O[100];

+char PCCTSAST_O[100];

+char LIST_O[100];

+char DLEXERBASE_O[100];

+

+/* Option flags */

+static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];

+static char *cfiles[MAX_CFILES];

+static char *sfiles[MAX_SORS][MAX_SFILES],*sclasses[MAX_SORS];

+static int  num_sfiles[MAX_SORS]; /*sorcerer files in group */

+static int  num_sors = 0; /*sorcerer groups */

+static int  num_files = 0; /* grammar files */

+static int  num_cfiles = 0; /* additional C/C++ files */

+static int  num_classes = 0; /* ANTLR classes */

+static int  user_lexer = 0;

+static char *user_token_types = NULL;

+static int  gen_CPP = 0;

+static char *outdir=".";

+static char *dlg_class = "DLGLexer";

+static int  gen_trees = 0;

+static int  gen_hoist = 0;

+static int  nondef_comp = 0; /* 1=compiler is non default */

+static char *compilerCCC="CC";

+static char *compilerCC="cc";

+static char *pccts_path="/usr/local/pccts";

+

+#ifdef __STDC__

+void help(void);

+void mk(char *project, char **files, int n, int argc, char **argv);

+void pfiles(char **files, int n, char *suffix);

+void fatal(char *msg);

+void warn(char *msg);

+#else

+void help();

+void mk();

+void pfiles();

+void fatal();

+void warn();

+#endif

+

+typedef struct _Opt {

+			char *option;

+			int arg;

+#ifdef __cplusplus

+			void (*process)(...);

+#else

+			void (*process)();

+#endif

+			char *descr;

+		} Opt;

+

+#ifdef __STDC__

+static void ProcessArgs(int, char **, Opt *);

+#else

+static void ProcessArgs();

+#endif

+

+static void

+#ifdef __STDC__

+pProj(char *s, char *t )

+#else

+pProj( s, t )

+char *s;

+char *t;

+#endif

+{

+	project = t;

+}

+

+static void

+#ifdef __STDC__

+pUL( char *s )

+#else

+pUL( s )

+char *s;

+#endif

+{

+	user_lexer = 1;

+}

+

+static void

+#ifdef __STDC__

+pCPP( char *s )

+#else

+pCPP( s )

+char *s;

+#endif

+{

+	gen_CPP = 1;

+}

+

+static void

+#ifdef __STDC__

+pUT( char *s, char *t )

+#else

+pUT( s, t )

+char *s;

+char *t;

+#endif

+{

+	user_token_types = t;

+}

+

+static void

+#ifdef __STDC__

+pTrees( char *s )

+#else

+pTrees( s )

+char *s;

+#endif

+{

+	gen_trees = 1;

+}

+

+static void

+#ifdef __STDC__

+pHoist( char *s )

+#else

+pHoist( s )

+char *s;

+#endif

+{

+	gen_hoist = 1;

+}

+

+static void

+#ifdef __STDC__

+pSor( char *s )

+#else

+pSor( s )

+char *s;

+#endif

+{

+	require(num_sors<MAX_SORS, "exceeded max # of sorcerer groups");

+	num_sors++;

+	pTrees(NULL); /* silently turn on tree generation */

+}

+

+static void

+#ifdef __STDC__

+pSFiles( char *s, char *t )

+#else

+pSFiles( s, t )

+char *s;

+char *t;

+#endif

+{

+	if (num_sors==0)

+	{

+		pSor(NULL);

+		warn("sorcerer input file before any '-sor' option");

+	}

+		

+	require(num_sfiles[num_sors-1]<MAX_SFILES,

+		 "exceeded max # of sorcerer input files");

+	sfiles[num_sors-1][num_sfiles[num_sors-1]++] = t;

+}

+

+static void

+#ifdef __STDC__

+pCFiles( char *s, char *t )

+#else

+pCFiles( s, t )

+char *s;

+char *t;

+#endif

+{

+	require(num_cfiles<MAX_CFILES, "exceeded max # of C/C++ input files");

+	cfiles[num_cfiles++] = t;

+}

+

+int

+#ifdef __STDC__

+isKnownSuffix( char *s )

+#else

+isKnownSuffix( s )

+	char *s;

+#endif

+{

+	if(s==NULL) return 0;

+	if (strcasecmp(s,".c")==0) return 1;

+	if (strcasecmp(s,".cc")==0) return 1;

+	if (strcasecmp(s,".cpp")==0) return 1;

+	if (strcasecmp(s,".cxx")==0) return 1;

+	if (strcasecmp(s,CPP_FILE_SUFFIX)==0) return 1;

+	if (strcasecmp(s,".sor")==0) return 2;

+	return 0;

+}

+

+static void

+#ifdef __STDC__

+pFile( char *s )

+#else

+pFile( s )

+char *s;

+#endif

+{

+	if ( *s=='-' )

+	{

+		fprintf(stderr, "invalid option: '%s'; ignored...",s);

+		return;

+	}

+	switch(isKnownSuffix(strrchr(s,'.')))

+	{

+	 case 1: /* c/c++ */

+		pCFiles("-cfiles",s);

+		return;

+	 case 2: /* sorcerer */

+		pSFiles("",s);

+		return;

+	 default: /* grammar (ANTLR) */

+		break;

+	}

+	require(num_files<MAX_FILES, "exceeded max # of input files");

+	files[num_files++] = s;

+}

+

+static void

+#ifdef __STDC__

+pClass( char *s, char *t )

+#else

+pClass( s, t )

+char *s;

+char *t;

+#endif

+{

+	if (num_sors==0)

+	{

+		require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");

+		classes[num_classes++] = t;

+	} else

+	{

+		sclasses[num_sors-1] = t; /* one class per sorcerer group (last valid) */

+	}

+}

+

+static void

+#ifdef __STDC__

+pDLGClass( char *s, char *t )

+#else

+pDLGClass( s, t )

+char *s;

+char *t;

+#endif

+{

+	if ( !gen_CPP ) {

+		fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");

+	}

+	else dlg_class = t;

+}

+

+static void

+#ifdef __STDC__

+pOdir( char *s, char *t )

+#else

+pOdir( s, t )

+char *s;

+char *t;

+#endif

+{

+	outdir = t;

+}

+

+static void

+#ifdef __STDC__

+pHdr( char *s, char *t )

+#else

+pHdr( s, t )

+char *s;

+char *t;

+#endif

+{

+	hdr = t;

+}

+

+static void

+#ifdef __STDC__

+pCompiler( char *s, char *t )

+#else

+pCompiler( s, t )

+char *s;

+char *t;

+#endif

+{

+	compilerCCC = t;

+	compilerCC = t;

+	nondef_comp = 1;

+}

+

+static void

+#ifdef __STDC__

+ppccts_path( char *s, char *t )

+#else

+ppccts_path( s, t )

+char *s;

+char *t;

+#endif

+{

+	pccts_path = t;

+}

+

+Opt options[] = {

+	{ "-CC", 0,	pCPP,			"Generate C++ output"},

+	{ "-class", 1,	pClass,		"Name of a grammar class defined in grammar (if C++)"},

+	{ "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},

+	{ "-header", 1,pHdr,		"Name of ANTLR standard header info (default=no file)"},

+	{ "-o", 1,	pOdir,			"Directory where output files should go (default=\".\")"},

+	{ "-project", 1,	pProj,	"Name of executable to create (default=t)"},

+	{ "-token-types", 1, pUT,	"Token types are in this file (don't use tokens.h)"},

+	{ "-trees", 0, pTrees,		"Generate ASTs"},

+	{ "-user-lexer", 0,	pUL,	"Do not create a DLG-based scanner"},

+	{ "-mrhoist",0,pHoist,      "Maintenance release style hoisting"},

+	{ "-cfiles",1,pCFiles,      "Additional files in C or C++ to compile"},

+	{ "-sor",0,pSor,           "Start of sorcerer group"},

+	{ "-pccts_path",1,ppccts_path,

+			"Path for $PCCTS directory (default is /usr/local/pccts)"},

+	{ "-compiler",1,pCompiler,

+			"Default compiler (default is CC/cc)"},

+	{ "*", 0,pFile, 	        "" },	/* anything else is a file */

+	{ NULL, 0, NULL, NULL }

+};

+

+#ifdef __STDC__

+extern char *DIR(void);

+#else

+extern char *DIR();

+#endif

+

+#ifdef __STDC__

+int main(int argc, char **argv)

+#else

+int main(argc, argv)

+int argc;

+char **argv;

+#endif

+{

+	int i;

+	

+	if ( argc == 1 ) { help(); DIE; }

+	for(i=0;i<MAX_SORS;i++) num_sfiles[i]=0;

+	

+	ProcessArgs(argc-1, &(argv[1]), options);

+

+	strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);

+	ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);

+	strcpy(APARSER_O, APARSER_C);

+	APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(APARSER_O, OBJ_FILE_SUFFIX);

+

+	strcpy(ASTBASE_O, ASTBASE_C);

+	ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(ASTBASE_O, OBJ_FILE_SUFFIX);

+

+	strcpy(PCCTSAST_O, PCCTSAST_C);

+	PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);

+

+	strcpy(LIST_O, LIST_C);

+	LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(LIST_O, OBJ_FILE_SUFFIX);

+

+	strcpy(DLEXERBASE_O, DLEXERBASE_C);

+	DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);

+

+	if ( num_files == 0 ) fatal("no grammar files specified; exiting...");

+	if ( !gen_CPP && num_classes>0 ) {

+		warn("can't define classes w/o C++ mode; turning on C++ mode...\n");

+		gen_CPP=1;

+	}

+	if (!gen_CPP && num_sors) {

+		warn("can't define sorcerer group in C mode (yet); turning on C++ mode...\n");

+		gen_CPP=1;

+	}

+	if ( gen_CPP && num_classes==0 ) {

+		fatal("must define classes >0 grammar classes in C++ mode\n");

+	}

+

+	mk(project, files, num_files, argc, argv);

+	DONE;

+}

+

+#ifdef __STDC__

+void help(void)

+#else

+void help()

+#endif

+{

+	Opt *p = options;

+	static char buf[1000+1];

+

+	fprintf(stderr, "genmk [options] f1.g ... fn.g\n");

+	while ( p->option!=NULL && *(p->option) != '*' )

+	{

+		buf[0]='\0';

+		if ( p->arg ) sprintf(buf, "%s ___", p->option);

+		else strcpy(buf, p->option);

+		fprintf(stderr, "\t%-16s   %s\n", buf, p->descr);

+		p++;

+	}

+}

+

+#ifdef __STDC__

+void mk(char *project, char **files, int n, int argc, char **argv)

+#else

+void mk(project, files, n, argc, argv)

+char *project;

+char **files;

+int n;

+int argc;

+char **argv;

+#endif

+{

+	int i,j;

+

+	printf("#\n");

+	printf("# PCCTS makefile for: ");

+	pfiles(files, n, NULL);

+	printf("\n");

+	printf("#\n");

+	printf("# Created from:");

+	for (i=0; i<argc; i++) printf(" %s", argv[i]);

+	printf("\n");

+	printf("#\n");

+	printf("# PCCTS release 1.33MR23\n");

+	printf("# Project: %s\n", project);

+	if ( gen_CPP ) printf("# C++ output\n");

+	else printf("# C output\n");

+	if ( user_lexer ) printf("# User-defined scanner\n");

+	else printf("# DLG scanner\n");

+	if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);

+	else printf("# ANTLR-defined token types\n");

+	printf("#\n");

+/***********

+	printf(".SUFFIXES:\n.SUFFIXES:\t.o .cpp .c .h .g .i .dlg .sor\n"); 

+ ***********/

+	if ( user_token_types!=NULL ) {

+		printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");

+		printf("TOKENS = %s", user_token_types);

+	}

+	else printf("TOKENS = %stokens.h", DIR());

+	printf("\n");

+	printf("#\n");

+	printf("# The following filenames must be consistent with ANTLR/DLG flags\n");

+	printf("DLG_FILE = %s%s\n", DIR(), dlg);

+	printf("ERR = %serr\n", DIR());

+	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);

+	else printf("HDR_FILE =\n");

+	if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);

+	if ( !gen_CPP ) printf("SCAN = %s\n", scan);

+	else printf("SCAN = %s%s\n", DIR(), dlg_class);

+

+	printf("PCCTS = %s\n",pccts_path);

+	printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);

+	if (num_sors>0) {

+		printf("SOR_H = $(PCCTS)%ssorcerer%sh\n", DirectorySymbol, DirectorySymbol);

+		printf("SOR_LIB = $(PCCTS)%ssorcerer%slib\n",

+			 	DirectorySymbol, DirectorySymbol);

+	}

+	printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);

+	printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);

+	printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);

+	if (num_sors>0) printf("SOR = $(BIN)%ssor\n", DirectorySymbol);

+	printf("CFLAGS = -I. -I$(ANTLR_H)");

+	if (num_sors>0) printf(" -I$(SOR_H)");

+	if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);

+	printf(" $(COTHER)");

+	printf("\n");

+	printf("AFLAGS =");

+	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);

+	if ( user_lexer ) printf(" -gx");

+	if ( gen_CPP ) printf(" -CC");

+	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);

+	if ( gen_trees ) printf(" -gt");

+	if ( gen_hoist ) {

+		printf(" -mrhoist on") ;

+	} else {

+		printf(" -mrhoist off");

+	};

+	printf(" $(AOTHER)");

+	printf("\n");

+	printf("DFLAGS = -C2 -i");

+	if ( gen_CPP ) printf(" -CC");

+	if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);

+	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);

+	printf(" $(DOTHER)");

+	printf("\n");

+	if (num_sors>0)

+	{

+		printf("SFLAGS = -CPP");

+		if ( strcmp(outdir,".")!=0 ) printf(" -out-dir %s", outdir);

+		printf(" $(SOTHER)\n");

+	}

+	printf("GRM = ");

+	pfiles(files, n, NULL);

+	printf("\n");

+	printf("SRC = ");

+	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);

+	else pfiles(files, n, "c");

+	if ( gen_CPP ) {

+		printf(" \\\n\t");

+		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" \\\n\t");

+		printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);

+		if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);

+		if ( gen_trees ) {

+			printf(" \\\n\t");

+			printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);

+			printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C);

+/*			printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */

+			printf(" \\\n\t");

+		}

+		printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);

+	}

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);

+		else printf(" %s$(SCAN).c", DIR());

+	}

+	if ( !gen_CPP ) printf(" $(ERR).c");

+	for (i=0;i<num_sors;i++)

+	{

+		printf(" \\\n\t");

+		pclasses(&sclasses[i],1,CPP_FILE_SUFFIX_NO_DOT);

+		printf(" ");

+		pfiles(&sfiles[i][0],num_sfiles[i],CPP_FILE_SUFFIX_NO_DOT);

+	}

+	if(num_sors>0)

+		printf(" \\\n\t$(SOR_LIB)%sSTreeParser.cpp", DirectorySymbol);

+	if (num_cfiles>0)

+	{

+		printf(" \\\n\t");

+		pfiles(cfiles,num_cfiles,NULL);

+	}

+	printf("\n\n");

+	printf("OBJ = ");

+	pfiles(files, n, "o");

+	if ( gen_CPP ) {

+		printf(" \\\n\t");

+		pclasses(classes, num_classes, "o");

+		printf(" \\\n\t");

+		printf("%s%s", DIR(), APARSER_O);

+		if ( !user_lexer ) {

+			printf(" %s%s", DIR(), DLEXERBASE_O);

+		}

+		if ( gen_trees ) {

+			printf(" \\\n\t");

+			printf("%s%s", DIR(), ASTBASE_O);

+			printf(" %s%s", DIR(), PCCTSAST_O);

+/*			printf(" %s%s", DIR(), LIST_O); */

+			printf(" \\\n\t");

+		}

+		printf(" %s%s", DIR(), ATOKENBUFFER_O);

+	}

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX);

+		else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX);

+	}

+	if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX);

+	for (i=0;i<num_sors;i++)

+	{

+		printf(" \\\n\t");

+		pclasses(&sclasses[i],1,"o");

+		printf(" ");

+		pfiles(&sfiles[i][0],num_sfiles[i],"o");

+	}

+	if(num_sors>0) printf(" \\\n\tSTreeParser.o");

+	if (num_cfiles>0)

+	{

+		printf(" \\\n\t");

+		pfiles(cfiles,num_cfiles,"o");

+	}

+	printf("\n\n");

+

+	printf("ANTLR_SPAWN = ");

+	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);

+	else pfiles(files, n, "c");

+	if ( gen_CPP ) {

+		printf(" ");

+		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" \\\n\t\t");

+		pclasses(classes, num_classes, "h");

+		if ( strcmp(hdr,"stdpccts.h")!=0 ) {

+			printf(" \\\n\t\t");

+			printf("$(HDR_FILE) stdpccts.h");

+		}

+	}

+	if ( user_lexer ) {

+		if ( !user_token_types ) printf(" $(TOKENS)");

+	}

+	else {

+		printf(" $(DLG_FILE)");

+		if ( !user_token_types ) printf(" $(TOKENS)");

+	}

+	if ( !gen_CPP ) printf(" $(ERR).c");

+	printf("\n");

+

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);

+		else printf("DLG_SPAWN = %s$(SCAN).c", DIR());

+		if ( gen_CPP ) printf(" $(SCAN).h");

+		if ( !gen_CPP ) printf(" $(MOD_FILE)");

+		printf("\n");

+	}

+

+	if ( gen_CPP ) {

+		if ( !nondef_comp )

+			printf("ifdef CXX\nCCC = $(CXX)\nendif\n\nifndef CCC\n");

+		printf("CCC = %s\n",compilerCCC);

+		if ( !nondef_comp ) printf("endif\n\n");

+	}

+	else

+	{

+		if ( !nondef_comp ) printf("ifndef CC\n");

+		printf("CC = %s\n",compilerCC);

+		if ( !nondef_comp ) printf("endif\n\n");

+	}

+

+	/* set up dependencies */

+	printf("\n%s : $(SRC) $(OBJ)\n", project);

+	printf("\t%s %s %s $(CFLAGS) $(OBJ)\n",

+		gen_CPP?"$(CCC)":"$(CC)",

+		RENAME_EXE_FLAG,

+		project);

+	printf("\n");

+

+	/* implicit rules */

+

+/*	if(gen_CPP)

+		printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n");

+

+	printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n",

+			gen_CPP?"$(CCC)":"$(CC)");

+*/

+	/* how to compile parser files */

+

+	for (i=0; i<num_files; i++)

+	{

+		pfiles(&files[i], 1, "o");

+		if ( user_lexer ) {

+			printf(" : $(TOKENS)");

+		}

+		else {

+			if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");

+			else printf(" : $(MOD_FILE) $(TOKENS)");

+		}

+		printf(" ");

+		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		else pfiles(&files[i], 1, "c");

+		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+		printf("\n");

+		printf("\t%s -c $(CFLAGS) %s ",

+			gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+		pfiles(&files[i], 1, "o");

+		printf(" ");

+		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		else pfiles(&files[i], 1, "c");

+		printf("\n\n");

+	}

+

+	for (i=0; i<num_cfiles; i++)

+	{

+		pfiles(&cfiles[i], 1, "o");

+		printf(" : ");

+		pfiles(&cfiles[i], 1, NULL);

+		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+/***	printf(" "); ***/

+/***	pfiles(&cfiles[i], 1, "h"); ***/

+		printf("\n");

+		printf("\t%s -c $(CFLAGS) %s ",

+			gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+		pfiles(&cfiles[i], 1, "o");

+		printf(" ");

+		pfiles(&cfiles[i], 1, NULL);

+		printf("\n\n");

+

+/*

+ *		pfiles(&cfiles[i], 1, "h");

+ *		printf(" :\ntouch ");

+ *		pfiles(&cfiles[i], 1, "h");

+ *		printf("\n\n");

+ */

+	}

+

+	/* how to compile err.c */

+	if ( !gen_CPP ) {

+		printf("$(ERR)%s : $(ERR).c", OBJ_FILE_SUFFIX);

+		if ( !user_lexer ) printf(" $(TOKENS)");

+		printf("\n");

+		printf("\t%s -c $(CFLAGS) %s $(ERR)%s $(ERR).c",

+			gen_CPP?"$(CCC)":"$(CC)",

+			RENAME_OBJ_FLAG,

+			OBJ_FILE_SUFFIX);

+		printf("\n\n");

+	}

+

+	/* how to compile Class.c */

+	for (i=0; i<num_classes; i++)

+	{

+		pclasses(&classes[i], 1, "o");

+		if ( user_lexer ) {

+			printf(" : $(TOKENS)");

+		}

+		else {

+			printf(" : $(TOKENS) $(SCAN).h");

+		}

+		printf(" ");

+		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" ");

+		pclasses(&classes[i], 1, "h");

+		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+		printf("\n");

+		printf("\t%s -c $(CFLAGS) %s ",

+			gen_CPP?"$(CCC)":"$(CC)",

+			RENAME_OBJ_FLAG);

+		pclasses(&classes[i], 1, "o");

+		printf(" ");

+		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		printf("\n\n");

+	}

+

+	/* how to compile scan.c */

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf("$(SCAN)%s : $(SCAN)%s", OBJ_FILE_SUFFIX, CPP_FILE_SUFFIX);

+		else printf("%s$(SCAN)%s : %s$(SCAN).c", DIR(), OBJ_FILE_SUFFIX, DIR());

+		if ( !user_lexer ) printf(" $(TOKENS)");

+		printf("\n");

+		if ( gen_CPP ) printf("\t$(CCC) -c $(CFLAGS) %s $(SCAN)%s $(SCAN)%s",

+							RENAME_OBJ_FLAG,

+							OBJ_FILE_SUFFIX,

+							CPP_FILE_SUFFIX);

+		else printf("\t$(CC) -c $(CFLAGS) %s %s$(SCAN)%s %s$(SCAN).c",

+					RENAME_OBJ_FLAG,

+					DIR(),

+					OBJ_FILE_SUFFIX,

+					DIR());

+		printf("\n\n");

+	}

+/* how to compile sorcerer classes */

+	for (i=0;i<num_sors;i++)

+	{

+		pclasses(&sclasses[i], 1, "o");

+		printf(" : ");

+		pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" ");

+		pclasses(&sclasses[i], 1, "h");

+		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+		printf("\n");

+		printf("\t%s -c $(CFLAGS) %s ",

+				gen_CPP?"$(CCC)":"$(CC)",

+				RENAME_OBJ_FLAG);

+		pclasses(&sclasses[i], 1, "o");

+		printf(" ");

+		pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		printf("\n\n");

+/* how to compile i-th sorcerer's files*/

+		for (j=0; j<num_sfiles[i]; j++)

+		{

+			pfiles(&sfiles[i][j], 1, "o");

+			printf(" : ");

+			if ( gen_CPP ) pfiles(&sfiles[i][j], 1, CPP_FILE_SUFFIX_NO_DOT);

+			else pfiles(&sfiles[i][j], 1, "c");

+			if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+			printf("\n");

+			printf("\t%s -c $(CFLAGS) %s ",

+					gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+			pfiles(&sfiles[i][j], 1, "o");

+			printf(" ");

+			if ( gen_CPP ) pfiles(&sfiles[i][j], 1, CPP_FILE_SUFFIX_NO_DOT);

+			else pfiles(&sfiles[i][j], 1, "c");

+			printf("\n\n");

+		}

+		if ( gen_CPP ) pfiles(&sfiles[i][0], num_sfiles[i], CPP_FILE_SUFFIX_NO_DOT);

+		else pfiles(&sfiles[i][0], num_sfiles[i], "c");

+		if ( gen_CPP )

+		{

+			printf(" ");

+			pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+			printf(" ");

+			pclasses(&sclasses[i], 1, "h");

+			if ( strcmp(hdr,"stdpccts.h")!=0 ) 

+			{

+				printf(" ");

+				printf("$(HDR_FILE) stdpccts.h");

+			}

+		}

+		printf(" : ");

+		pfiles(&sfiles[i][0],num_sfiles[i],NULL);

+		printf("\n\t$(SOR) $(SFLAGS) ");

+		pfiles(&sfiles[i][0],num_sfiles[i],NULL);

+		printf("\n\n");

+	}

+	if(num_sors>0)

+	{

+		printf("STreeParser%s : $(SOR_LIB)%sSTreeParser.cpp\n",

+				OBJ_FILE_SUFFIX,DirectorySymbol);

+		printf("\t%s -c $(CFLAGS) %s ",

+				gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+		printf("STreeParser%s ",OBJ_FILE_SUFFIX);

+		printf("$(SOR_LIB)%sSTreeParser.cpp\n\n",DirectorySymbol);

+	}

+	

+	printf("$(ANTLR_SPAWN) : $(GRM)\n");

+	printf("\t$(ANTLR) $(AFLAGS) $(GRM)\n");

+

+	if ( !user_lexer )

+	{

+		printf("\n");

+		printf("$(DLG_SPAWN) : $(DLG_FILE)\n");

+		if ( gen_CPP ) printf("\t$(DLG) $(DFLAGS) $(DLG_FILE)\n");

+		else printf("\t$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");

+	}

+

+	/* do the makes for ANTLR/DLG support */

+	if ( gen_CPP ) {

+		printf("\n");

+		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);

+		printf("\t%s -c $(CFLAGS) %s ",

+				gen_CPP?"$(CCC)":"$(CC)",

+				RENAME_OBJ_FLAG);

+		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);

+		printf("\n");

+		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);

+		printf("\t%s -c $(CFLAGS) %s ",

+				gen_CPP?"$(CCC)":"$(CC)",

+				RENAME_OBJ_FLAG);

+		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);

+		if ( !user_lexer ) {

+			printf("\n");

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);

+			printf("\t%s -c $(CFLAGS) %s ",

+					gen_CPP?"$(CCC)":"$(CC)",

+					RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);

+		}

+		if ( gen_trees ) {

+			printf("\n");

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);

+			printf("\t%s -c $(CFLAGS) %s ",

+					gen_CPP?"$(CCC)":"$(CC)",

+					RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);

+			printf("\n");

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);

+			printf("\t%s -c $(CFLAGS) %s ",

+					gen_CPP?"$(CCC)":"$(CC)",

+					RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);

+			printf("\n");

+/*

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);

+			printf("\t%s -c $(CFLAGS) %s ",

+					gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);

+*/

+		}

+	}

+

+	/* clean and scrub targets */

+

+	printf("\nclean:\n");

+	printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project);

+	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);

+	printf("\n");

+

+	printf("\nscrub: clean\n");

+/*	printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); */

+/*	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); */

+	printf("\trm -f $(ANTLR_SPAWN)");

+	if ( !user_lexer ) printf(" $(DLG_SPAWN)");

+	for (i=0;i<num_sors;i++)

+	{

+		printf(" ");

+		if ( gen_CPP ) pfiles(&sfiles[i][0], num_sfiles[i], CPP_FILE_SUFFIX_NO_DOT);

+		else pfiles(&sfiles[i][0], num_sfiles[i], "c");

+		if ( gen_CPP )

+		{

+			printf(" ");

+			pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+			printf(" ");

+			pclasses(&sclasses[i], 1, "h");

+		}

+	}

+	printf("\n\n");

+}

+

+#ifdef __STDC__

+void pfiles(char **files, int n, char *suffix)

+#else

+void pfiles(files, n, suffix)

+char **files;

+int n;

+char *suffix;

+#endif

+{

+	int first=1;

+

+	while ( n>0 )

+	{

+		char *p = &(*files)[strlen(*files)-1];

+		if ( !first ) putchar(' ');

+		first=0;

+		while ( p > *files && *p != '.' ) --p;

+		if ( p == *files )

+		{

+			fprintf(stderr,

+					"genmk: filenames must be file.suffix format: %s\n",

+					*files);

+			exit(-1);

+		}

+		if ( suffix == NULL ) printf("%s", *files);

+		else

+		{

+			*p = '\0';

+			printf("%s", DIR());

+			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX);

+			else printf("%s.%s", *files, suffix);

+			*p = '.';

+		}

+		files++;

+		--n;

+	}

+}

+

+#ifdef __STDC__

+pclasses(char **classes, int n, char *suffix)

+#else

+pclasses(classes, n, suffix)

+char **classes;

+int n;

+char *suffix;

+#endif

+{

+	int first=1;

+

+	while ( n>0 )

+	{

+		if ( !first ) putchar(' ');

+		first=0;

+		if ( suffix == NULL ) printf("%s", *classes);

+		else {

+			printf("%s", DIR());

+			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX);

+			else printf("%s.%s", *classes, suffix);

+		}

+		classes++;

+		--n;

+	}

+}

+

+static void

+#ifdef __STDC__

+ProcessArgs( int argc, char **argv, Opt *options )

+#else

+ProcessArgs( argc, argv, options )

+int argc;

+char **argv;

+Opt *options;

+#endif

+{

+	Opt *p;

+	require(argv!=NULL, "ProcessArgs: command line NULL");

+

+	while ( argc-- > 0 )

+	{

+		p = options;

+		while ( p->option != NULL )

+		{

+			if ( strcmp(p->option, "*") == 0 ||

+				 strcmp(p->option, *argv) == 0 )

+			{

+				if ( p->arg )

+				{

+					(*p->process)( *argv, *(argv+1) );

+					argv++;

+					argc--;

+				}

+				else

+					(*p->process)( *argv );

+				break;

+			}

+			p++;

+		}

+		argv++;

+	}

+}

+

+#ifdef __STDC__

+void fatal( char *err_)

+#else

+void fatal( err_)

+char *err_;

+#endif

+{

+	fprintf(stderr, "genmk: %s\n", err_);

+	exit(1);

+}

+

+#ifdef __STDC__

+void warn( char *err_)

+#else

+void warn( err_)

+char *err_;

+#endif

+{

+	fprintf(stderr, "genmk: %s\n", err_);

+}

+

+#ifdef __STDC__

+char *DIR(void)

+#else

+char *DIR()

+#endif

+{

+	static char buf[200+1];

+	

+	if ( strcmp(outdir,TopDirectory)==0 ) return "";

+	sprintf(buf, "%s%s", outdir, DirectorySymbol);

+	return buf;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/genmk/genmk_old.c b/edk2/Tools/Source/TianoTools/Pccts/support/genmk/genmk_old.c
new file mode 100644
index 0000000..2cf9fad
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/genmk/genmk_old.c
@@ -0,0 +1,762 @@
+/*

+ * genmk -- a program to make makefiles for PCCTS

+ *

+ * ANTLR 1.33MR10

+ * Terence John Parr 1989 - 1998

+ * Purdue University

+ * U of MN

+ */

+

+#include <stdio.h>

+#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */

+

+#ifdef VAXC

+#define DIE		return 0;

+#define DONE	return 1;

+#else

+#define DIE		return 1;

+#define DONE	return 0;

+#endif

+

+#ifndef require

+#define require(expr, err) {if ( !(expr) ) fatal(err);}

+#endif

+

+#define MAX_FILES	50

+#define MAX_CLASSES	50

+

+char *RENAME_OBJ_FLAG="-o",

+     *RENAME_EXE_FLAG="-o";

+

+char *dlg = "parser.dlg";

+char *err = "err.c";

+char *hdr = "stdpccts.h";

+char *tok = "tokens.h";

+char *mode = "mode.h";

+char *scan = "scan";

+

+char ATOKENBUFFER_O[100];

+char APARSER_O[100];

+char ASTBASE_O[100];

+char PCCTSAST_O[100];

+char LIST_O[100];

+char DLEXERBASE_O[100];

+

+/* Option flags */

+static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];

+static int	num_files = 0;

+static int	num_classes = 0;

+static int	user_lexer = 0;

+static char	*user_token_types = NULL;

+static int	gen_CPP = 0;

+static char *outdir=".";

+static char *dlg_class = "DLGLexer";

+static int	gen_trees = 0;

+static int  gen_hoist = 0;

+static char cfiles[1600]="";

+static char *compilerCCC="CC";

+static char *compilerCC="cc";

+static char *pccts_path="/usr/local/pccts";

+

+void help();

+void mk();

+void pfiles();

+void pclasses();

+void fatal();

+void warn();

+

+typedef struct _Opt {

+			char *option;

+			int  arg;

+#ifdef __cplusplus

+			void (*process)(...);

+#else

+			void (*process)();

+#endif

+			char *descr;

+		} Opt;

+

+#ifdef __STDC__

+static void ProcessArgs(int, char **, Opt *);

+#else

+static void ProcessArgs();

+#endif

+

+static void

+pProj( s, t )

+char *s;

+char *t;

+{

+	project = t;

+}

+

+static void

+pUL( s )

+char *s;

+{

+	user_lexer = 1;

+}

+

+static void

+pCPP( s )

+char *s;

+{

+	gen_CPP = 1;

+}

+

+static void

+pUT( s, t )

+char *s;

+char *t;

+{

+	user_token_types = t;

+}

+

+static void

+pTrees( s )

+char *s;

+{

+	gen_trees = 1;

+}

+

+static void

+pHoist( s )

+char *s;

+{

+	gen_hoist = 1;

+}

+

+static void

+#ifdef __STDC__

+pFile( char *s )

+#else

+pFile( s )

+char *s;

+#endif

+{

+	if ( *s=='-' )

+	{

+		fprintf(stderr, "invalid option: '%s'; ignored...",s);

+		return;

+	}

+

+	require(num_files<MAX_FILES, "exceeded max # of input files");

+	files[num_files++] = s;

+}

+

+static void

+#ifdef __STDC__

+pClass( char *s, char *t )

+#else

+pClass( s, t )

+char *s;

+char *t;

+#endif

+{

+	require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");

+	classes[num_classes++] = t;

+}

+

+static void

+#ifdef __STDC__

+pDLGClass( char *s, char *t )

+#else

+pDLGClass( s, t )

+char *s;

+char *t;

+#endif

+{

+	if ( !gen_CPP ) {

+		fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");

+	}

+	else dlg_class = t;

+}

+

+static void

+#ifdef __STDC__

+pOdir( char *s, char *t )

+#else

+pOdir( s, t )

+char *s;

+char *t;

+#endif

+{

+	outdir = t;

+}

+

+static void

+#ifdef __STDC__

+pHdr( char *s, char *t )

+#else

+pHdr( s, t )

+char *s;

+char *t;

+#endif

+{

+	hdr = t;

+}

+

+static void

+#ifdef __STDC__

+pCFiles( char *s, char *t )

+#else

+pCFiles( s, t )

+char *s;

+char *t;

+#endif

+{

+	strcat(strcat(cfiles," "), t);

+}

+

+static void

+#ifdef __STDC__

+pCompiler( char *s, char *t )

+#else

+pCompiler( s, t )

+char *s;

+char *t;

+#endif

+{

+        compilerCCC = t;

+	compilerCC = t;

+}

+

+static void

+#ifdef __STDC__

+ppccts_path( char *s, char *t )

+#else

+ppccts_path( s, t )

+char *s;

+char *t;

+#endif

+{

+        pccts_path = t;

+}

+

+Opt options[] = {

+    { "-CC", 0,	pCPP,			"Generate C++ output"},

+    { "-class", 1,	pClass,		"Name of a grammar class defined in grammar (if C++)"},

+    { "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},

+    { "-header", 1,pHdr,		"Name of ANTLR standard header info (default=no file)"},

+    { "-o", 1,	pOdir,			"Directory where output files should go (default=\".\")"},

+    { "-project", 1,	pProj,	"Name of executable to create (default=t)"},

+    { "-token-types", 1, pUT,	"Token types are in this file (don't use tokens.h)"},

+    { "-trees", 0, pTrees,		"Generate ASTs"},

+    { "-user-lexer", 0,	pUL,	"Do not create a DLG-based scanner"},

+    { "-mrhoist",0,pHoist,      "Maintenance release style hoisting"},

+    { "-cfiles",1,pCFiles,      "Additional files in C or C++ to compile"},

+    { "-pccts_path",1,ppccts_path,

+              "Path for $PCCTS directory (default is /usr/local/pccts)"},

+    { "-compiler",1,pCompiler,

+              "Default compiler (default is CC/cc)"},

+    { "*", 0,pFile, 	        "" },	/* anything else is a file */

+	{ NULL, 0, NULL, NULL }

+};

+

+extern char *DIR();

+

+int main(argc, argv)

+int argc;

+char **argv;

+{

+	if ( argc == 1 ) { help(); DIE; }

+	ProcessArgs(argc-1, &(argv[1]), options);

+

+	strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);

+	ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);

+	strcpy(APARSER_O, APARSER_C);

+	APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(APARSER_O, OBJ_FILE_SUFFIX);

+

+	strcpy(ASTBASE_O, ASTBASE_C);

+	ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(ASTBASE_O, OBJ_FILE_SUFFIX);

+

+	strcpy(PCCTSAST_O, PCCTSAST_C);

+	PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);

+

+	strcpy(LIST_O, LIST_C);

+	LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(LIST_O, OBJ_FILE_SUFFIX);

+

+	strcpy(DLEXERBASE_O, DLEXERBASE_C);

+	DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';

+	strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);

+

+	if ( num_files == 0 ) fatal("no grammar files specified; exiting...");

+	if ( !gen_CPP && num_classes>0 ) {

+		warn("can't define classes w/o C++ mode; turning on C++ mode...\n");

+		gen_CPP=1;

+	}

+	if ( gen_CPP && num_classes==0 ) {

+		fatal("must define classes >0 grammar classes in C++ mode\n");

+	}

+

+	mk(project, files, num_files, argc, argv);

+	DONE;

+}

+

+void help()

+{

+	Opt *p = options;

+	static char buf[1000+1];

+

+	fprintf(stderr, "genmk [options] f1.g ... fn.g\n");

+	while ( p->option!=NULL && *(p->option) != '*' )

+	{

+		buf[0]='\0';

+		if ( p->arg ) sprintf(buf, "%s ___", p->option);

+		else strcpy(buf, p->option);

+		fprintf(stderr, "\t%-16s   %s\n", buf, p->descr);

+		p++;

+	}

+}

+

+void mk(project, files, n, argc, argv)

+char *project;

+char **files;

+int n;

+int argc;

+char **argv;

+{

+	int i;

+

+	printf("#\n");

+	printf("# PCCTS makefile for: ");

+	pfiles(files, n, NULL);

+	printf("\n");

+	printf("#\n");

+	printf("# Created from:");

+	for (i=0; i<argc; i++) printf(" %s", argv[i]);

+	printf("\n");

+	printf("#\n");

+	printf("# PCCTS release 1.33MR21\n");

+	printf("# Project: %s\n", project);

+	if ( gen_CPP ) printf("# C++ output\n");

+	else printf("# C output\n");

+	if ( user_lexer ) printf("# User-defined scanner\n");

+	else printf("# DLG scanner\n");

+	if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);

+	else printf("# ANTLR-defined token types\n");

+	printf("#\n");

+	printf(".SUFFIXES:\n.SUFFIXES:      .o .cpp .c .h .g .i .dlg\n"); 

+	if ( user_token_types!=NULL ) {

+		printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");

+		printf("TOKENS = %s", user_token_types);

+	}

+	else printf("TOKENS = %stokens.h", DIR());

+	printf("\n");

+	printf("#\n");

+	printf("# The following filenames must be consistent with ANTLR/DLG flags\n");

+	printf("DLG_FILE = %s%s\n", DIR(), dlg);

+	printf("ERR = %serr\n", DIR());

+	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);

+	else printf("HDR_FILE =\n");

+	if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);

+	if ( !gen_CPP ) printf("SCAN = %s\n", scan);

+	else printf("SCAN = %s%s\n", DIR(), dlg_class);

+

+	printf("PCCTS = %s\n",pccts_path);

+	printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);

+	printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);

+	printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);

+	printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);

+	printf("CFLAGS = -I. -I$(ANTLR_H)");

+	if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);

+    printf(" $(COTHER)");

+	printf("\n");

+	printf("AFLAGS =");

+	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);

+	if ( user_lexer ) printf(" -gx");

+	if ( gen_CPP ) printf(" -CC");

+	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);

+	if ( gen_trees ) printf(" -gt");

+    if ( gen_hoist ) {

+      printf(" -mrhoist on") ;

+    } else {

+      printf(" -mrhoist off");

+    };

+    printf(" $(AOTHER)");

+	printf("\n");

+	printf("DFLAGS = -C2 -i");

+	if ( gen_CPP ) printf(" -CC");

+	if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);

+	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);

+    printf(" $(DOTHER)");

+	printf("\n");

+	printf("GRM = ");

+	pfiles(files, n, NULL);

+	printf("\n");

+	printf("MYFILES = %s\n",cfiles);

+	printf("SRC = ");

+	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);

+	else pfiles(files, n, "c");

+	if ( gen_CPP ) {

+		printf(" \\\n     ");

+		printf(" ");

+		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" \\\n      ");

+		printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);

+		if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);

+		if ( gen_trees ) {

+			printf(" \\\n      ");

+			printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);

+			printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C);

+/*			printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */

+			printf(" \\\n      ");

+		}

+		printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);

+	}

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);

+		else printf(" %s$(SCAN).c", DIR());

+	}

+	if ( !gen_CPP ) printf(" $(ERR).c");

+	printf("\\\n	$(MYFILES)\n");

+	printf("OBJ = ");

+	pfiles(files, n, "o");

+	if ( gen_CPP ) {

+		printf(" \\\n     ");

+		printf(" ");

+		pclasses(classes, num_classes, "o");

+		printf(" \\\n      ");

+		printf(" %s%s", DIR(), APARSER_O);

+		if ( !user_lexer ) {

+			printf(" %s%s", DIR(), DLEXERBASE_O);

+		}

+		if ( gen_trees ) {

+			printf(" \\\n      ");

+			printf("%s%s", DIR(), ASTBASE_O);

+			printf(" %s%s", DIR(), PCCTSAST_O);

+/*			printf(" %s%s", DIR(), LIST_O); */

+			printf(" \\\n      ");

+		}

+		printf(" %s%s", DIR(), ATOKENBUFFER_O);

+	}

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX);

+		else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX);

+	}

+	if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX);

+	printf("\\\n	$(MYFILES:.cpp=.o)\n");

+

+	printf("ANTLR_SPAWN = ");

+	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);

+	else pfiles(files, n, "c");

+	if ( gen_CPP ) {

+		printf(" ");

+		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" \\\n              ");

+		pclasses(classes, num_classes, "h");

+		if ( strcmp(hdr,"stdpccts.h")!=0 ) {

+			printf(" \\\n              ");

+			printf("$(HDR_FILE) stdpccts.h");

+		}

+	}

+	if ( user_lexer ) {

+		if ( !user_token_types ) printf(" $(TOKENS)");

+	}

+	else {

+		printf(" $(DLG_FILE)");

+		if ( !user_token_types ) printf(" $(TOKENS)");

+	}

+	if ( !gen_CPP ) printf(" $(ERR).c");

+	printf("\n");

+

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);

+		else printf("DLG_SPAWN = %s$(SCAN).c", DIR());

+		if ( gen_CPP ) printf(" $(SCAN).h");

+		if ( !gen_CPP ) printf(" $(MOD_FILE)");

+		printf("\n");

+	}

+

+	if ( gen_CPP ) {

+		printf("CCC = %s\n",compilerCCC);

+	}

+	else printf("CC = %s\n",compilerCC);

+

+	/* set up dependencies */

+	printf("\n%s : $(OBJ) $(SRC)\n", project);

+	printf("	%s %s %s $(CFLAGS) $(OBJ)\n",

+		   gen_CPP?"$(CCC)":"$(CC)",

+		   RENAME_EXE_FLAG,

+		   project);

+	printf("\n");

+

+	/* implicit rules */

+

+	if(gen_CPP)

+		printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n");

+

+	printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n",

+			gen_CPP?"$(CCC)":"$(CC)");

+

+	/* how to compile parser files */

+

+	for (i=0; i<num_files; i++)

+	{

+		pfiles(&files[i], 1, "o");

+		if ( user_lexer ) {

+			printf(" : $(TOKENS)");

+		}

+		else {

+			if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");

+			else printf(" : $(MOD_FILE) $(TOKENS)");

+		}

+		printf(" ");

+		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		else pfiles(&files[i], 1, "c");

+		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+		printf("\n");

+		printf("	%s -c $(CFLAGS) %s ",

+		       gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+		pfiles(&files[i], 1, "o");

+		printf(" ");

+		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		else pfiles(&files[i], 1, "c");

+		printf("\n\n");

+	}

+

+	/* how to compile err.c */

+	if ( !gen_CPP ) {

+		printf("$(ERR)%s : $(ERR).c", OBJ_FILE_SUFFIX);

+		if ( !user_lexer ) printf(" $(TOKENS)");

+		printf("\n");

+		printf("	%s -c $(CFLAGS) %s $(ERR)%s $(ERR).c",

+			   gen_CPP?"$(CCC)":"$(CC)",

+			   RENAME_OBJ_FLAG,

+			   OBJ_FILE_SUFFIX);

+		printf("\n\n");

+	}

+

+	/* how to compile Class.c */

+	for (i=0; i<num_classes; i++)

+	{

+		pclasses(&classes[i], 1, "o");

+		if ( user_lexer ) {

+			printf(" : $(TOKENS)");

+		}

+		else {

+			printf(" : $(TOKENS) $(SCAN).h");

+		}

+		printf(" ");

+		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		printf(" ");

+		pclasses(&classes[i], 1, "h");

+		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");

+		printf("\n");

+		printf("	%s -c $(CFLAGS) %s ",

+			   gen_CPP?"$(CCC)":"$(CC)",

+			   RENAME_OBJ_FLAG);

+		pclasses(&classes[i], 1, "o");

+		printf(" ");

+		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);

+		printf("\n\n");

+	}

+

+	/* how to compile scan.c */

+	if ( !user_lexer ) {

+		if ( gen_CPP ) printf("$(SCAN)%s : $(SCAN)%s", OBJ_FILE_SUFFIX, CPP_FILE_SUFFIX);

+		else printf("%s$(SCAN)%s : %s$(SCAN).c", DIR(), OBJ_FILE_SUFFIX, DIR());

+		if ( !user_lexer ) printf(" $(TOKENS)");

+		printf("\n");

+		if ( gen_CPP ) printf("	$(CCC) -c $(CFLAGS) %s $(SCAN)%s $(SCAN)%s",

+							  RENAME_OBJ_FLAG,

+							  OBJ_FILE_SUFFIX,

+							  CPP_FILE_SUFFIX);

+		else printf("	$(CC) -c $(CFLAGS) %s %s$(SCAN)%s %s$(SCAN).c",

+					RENAME_OBJ_FLAG,

+					DIR(),

+					OBJ_FILE_SUFFIX,

+					DIR());

+		printf("\n\n");

+	}

+

+	printf("$(ANTLR_SPAWN) : $(GRM)\n");

+	printf("	$(ANTLR) $(AFLAGS) $(GRM)\n");

+

+	if ( !user_lexer )

+	{

+		printf("\n");

+		printf("$(DLG_SPAWN) : $(DLG_FILE)\n");

+		if ( gen_CPP ) printf("	$(DLG) $(DFLAGS) $(DLG_FILE)\n");

+		else printf("	$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");

+	}

+

+	/* do the makes for ANTLR/DLG support */

+	if ( gen_CPP ) {

+		printf("\n");

+		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);

+		printf("	%s -c $(CFLAGS) %s ",

+			   gen_CPP?"$(CCC)":"$(CC)",

+			   RENAME_OBJ_FLAG);

+		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);

+		printf("\n");

+		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);

+		printf("	%s -c $(CFLAGS) %s ",

+			   gen_CPP?"$(CCC)":"$(CC)",

+			   RENAME_OBJ_FLAG);

+		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);

+		if ( !user_lexer ) {

+			printf("\n");

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);

+			printf("	%s -c $(CFLAGS) %s ",

+				   gen_CPP?"$(CCC)":"$(CC)",

+				   RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);

+		}

+		if ( gen_trees ) {

+			printf("\n");

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);

+			printf("	%s -c $(CFLAGS) %s ",

+				   gen_CPP?"$(CCC)":"$(CC)",

+				   RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);

+			printf("\n");

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);

+			printf("	%s -c $(CFLAGS) %s ",

+				   gen_CPP?"$(CCC)":"$(CC)",

+				   RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);

+			printf("\n");

+/*

+			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);

+			printf("	%s -c $(CFLAGS) %s ",

+			       gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);

+			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);

+*/

+		}

+	}

+

+	/* clean and scrub targets */

+

+	printf("\nclean:\n");

+	printf("	rm -f *%s core %s", OBJ_FILE_SUFFIX, project);

+	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);

+	printf("\n");

+

+	printf("\nscrub:\n");

+	printf("	rm -f *%s core %s", OBJ_FILE_SUFFIX, project);

+	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);

+	printf(" $(ANTLR_SPAWN)");

+	if ( !user_lexer ) printf(" $(DLG_SPAWN)");

+	printf("\n");

+}

+

+void pfiles(files, n, suffix)

+char **files;

+int n;

+char *suffix;

+{

+	int first=1;

+

+	while ( n>0 )

+	{

+		char *p = &(*files)[strlen(*files)-1];

+		if ( !first ) putchar(' ');

+		first=0;

+		while ( p > *files && *p != '.' ) --p;

+		if ( p == *files )

+		{

+			fprintf(stderr,

+					"genmk: filenames must be file.suffix format: %s\n",

+					*files);

+			exit(-1);

+		}

+		if ( suffix == NULL ) printf("%s", *files);

+		else

+		{

+			*p = '\0';

+			printf("%s", DIR());

+			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX);

+			else printf("%s.%s", *files, suffix);

+			*p = '.';

+		}

+		files++;

+		--n;

+	}

+}

+

+void pclasses(classes, n, suffix)

+char **classes;

+int n;

+char *suffix;

+{

+	int first=1;

+

+	while ( n>0 )

+	{

+		if ( !first ) putchar(' ');

+		first=0;

+		if ( suffix == NULL ) printf("%s", *classes);

+		else {

+			printf("%s", DIR());

+			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX);

+			else printf("%s.%s", *classes, suffix);

+		}

+		classes++;

+		--n;

+	}

+}

+

+static void

+#ifdef __STDC__

+ProcessArgs( int argc, char **argv, Opt *options )

+#else

+ProcessArgs( argc, argv, options )

+int argc;

+char **argv;

+Opt *options;

+#endif

+{

+	Opt *p;

+	require(argv!=NULL, "ProcessArgs: command line NULL");

+

+	while ( argc-- > 0 )

+	{

+		p = options;

+		while ( p->option != NULL )

+		{

+			if ( strcmp(p->option, "*") == 0 ||

+				 strcmp(p->option, *argv) == 0 )

+			{

+				if ( p->arg )

+				{

+					(*p->process)( *argv, *(argv+1) );

+					argv++;

+					argc--;

+				}

+				else

+					(*p->process)( *argv );

+				break;

+			}

+			p++;

+		}

+		argv++;

+	}

+}

+

+void fatal( err_)

+char *err_;

+{

+    fprintf(stderr, "genmk: %s\n", err_);

+    exit(1);

+}

+

+void warn( err_)

+char *err_;

+{

+    fprintf(stderr, "genmk: %s\n", err_);

+}

+

+char *DIR()

+{

+	static char buf[200+1];

+	

+	if ( strcmp(outdir,TopDirectory)==0 ) return "";

+	sprintf(buf, "%s%s", outdir, DirectorySymbol);

+	return buf;

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/genmk/makefile b/edk2/Tools/Source/TianoTools/Pccts/support/genmk/makefile
new file mode 100644
index 0000000..a003c2f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/genmk/makefile
@@ -0,0 +1,29 @@
+##

+##  7-Apr-97

+##  added support/genmk/makefile to pccts 1.33MR1 distribution kit

+##		(support/genmk/makefile" omitted from 1.33 distribution kit)

+##

+SRC=genmk.c

+OBJ=genmk.o

+# Define PC if you use a PC OS (changes directory symbol and object file extension)

+# see pccts/h/pcctscfg.h

+CC=cc

+COPT=-O

+#CFLAGS=-I../../h -DPC

+CFLAGS=$(COPT) -I../../h

+BAG=../../bin/bag

+

+genmk: $(OBJ) $(SRC) ../../h/pcctscfg.h

+	$(CC) -o genmk $(OBJ)

+

+clean:

+	rm -rf core *.o

+

+scrub:

+	rm -rf genmk core *.o

+

+shar:

+	shar genmk.c makefile > genmk.shar

+

+archive:

+	$(BAG) genmk.c makefile > genmk.bag

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/makefile b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/makefile
new file mode 100644
index 0000000..44caef1
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/makefile
@@ -0,0 +1,19 @@
+BAG=../../bin/bag

+SRC=test.c rexpr.c

+OBJ=test.o rexpr.o

+CFLAGS = -g

+

+test: $(OBJ) $(SRC)

+	cc -g -o texpr $(OBJ)

+

+shar:

+	shar makefile test.c rexpr.c rexpr.h > rexpr.shar

+

+archive:

+	$(BAG) makefile test.c rexpr.c rexpr.h > rexpr.bag

+

+clean:

+	rm -rf *.o core texpr

+

+scrub:

+	rm -rf *.o core texpr

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/rexpr.c b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/rexpr.c
new file mode 100644
index 0000000..805bf65
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/rexpr.c
@@ -0,0 +1,586 @@
+/*

+ * This file contains code for

+ *

+ *      int rexpr(char *expr, char *s);

+ *

+ * which answers

+ *

+ *      1 if 's' is in the language described by the regular expression 'expr'

+ *      0 if it is not

+ *     -1 if the regular expression is invalid

+ *

+ * Language membership is determined by constructing a non-deterministic

+ * finite automata (NFA) from the regular expression.  A depth-

+ * first-search is performed on the NFA (graph) to check for a match of 's'.

+ * Each non-epsilon arc consumes one character from 's'.  Backtracking is

+ * performed to check all possible paths through the NFA.

+ *

+ * Regular expressions follow the meta-language:

+ *

+ * <regExpr>        ::= <andExpr> ( '|' <andExpr> )*

+ *

+ * <andExpr>        ::= <expr> ( <expr> )*

+ *

+ * <expr>           ::= {'~'} '[' <atomList> ']' <repeatSymbol>

+ *                      | '(' <regExpr> ')' <repeatSymbol>

+ *                      | '{' <regExpr> '}' <repeatSymbol>

+ *                      | <atom> <repeatSymbol>

+ *

+ * <repeatSymbol>   ::= { '*' | '+' }

+ *

+ * <atomList>       ::= <atom> ( <atom> )*

+ *                      | { <atomList> } <atom> '-' <atom> { <atomList> }

+ *

+ * <atom>           ::= Token[Atom]

+ *

+ * Notes:

+ *		~	means complement the set in [..]. i.e. all characters not listed

+ *		*	means match 0 or more times (can be on expression or atom)

+ *		+	means match 1 or more times (can be on expression or atom)

+ *		{}	optional

+ *		()	grouping

+ *		[]	set of atoms

+ *		x-y	all characters from x to y (found only in [..])

+ *		\xx the character with value xx

+ *

+ * Examples:

+ *		[a-z]+

+ *			match 1 or more lower-case letters (e.g. variable)

+ *

+ *		0x[0-9A-Fa-f]+

+ *			match a hex number with 0x on front (e.g. 0xA1FF)

+ *

+ *		[0-9]+.[0-9]+{e[0-9]+}

+ *			match a floating point number (e.g. 3.14e21)

+ *

+ * Code example:

+ *		if ( rexpr("[a-zA-Z][a-zA-Z0-9]+", str) ) then str is keyword

+ *

+ * Terence Parr

+ * Purdue University

+ * April 1991

+ */

+

+#include <stdio.h>

+#include <ctype.h>

+#ifdef __STDC__

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif

+#include "rexpr.h"

+

+#ifdef __USE_PROTOS

+static int regExpr( GraphPtr g );

+static int andExpr( GraphPtr g );

+static int expr( GraphPtr g );

+static int repeatSymbol( GraphPtr g );

+static int atomList( char *p, int complement );

+static void next( void );

+static ArcPtr newGraphArc( void );

+static NodePtr newNode( void );

+static int ArcBetweenGraphNode( NodePtr i, NodePtr j, int label );

+static Graph BuildNFA_atom( int label );

+static Graph BuildNFA_AB( Graph A, Graph B );

+static Graph BuildNFA_AorB( Graph A, Graph B );

+static Graph BuildNFA_set( char *s );

+static Graph BuildNFA_Astar( Graph A );

+static Graph BuildNFA_Aplus( Graph A );

+static Graph BuildNFA_Aoptional( Graph A );

+#else

+static int regExpr();

+static int andExpr();

+static int expr();

+static int repeatSymbol();

+static int atomList();

+static void next();

+static ArcPtr newGraphArc();

+static NodePtr newNode();

+static int ArcBetweenGraphNode();

+static Graph BuildNFA_atom();

+static Graph BuildNFA_AB();

+static Graph BuildNFA_AorB();

+static Graph BuildNFA_set();

+static Graph BuildNFA_Astar();

+static Graph BuildNFA_Aplus();

+static Graph BuildNFA_Aoptional();

+#endif

+

+static char *_c;

+static int token, tokchar;

+static NodePtr accept;

+static NodePtr freelist = NULL;

+

+/*

+ * return 1 if s in language described by expr

+ *        0 if s is not

+ *       -1 if expr is an invalid regular expression

+ */

+#ifdef __USE_PROTOS

+static int rexpr(char *expr,char *s)

+#else

+static int rexpr(expr, s)

+char *expr, *s;

+#endif

+{

+	NodePtr p,q;

+	Graph nfa;

+	int result;

+

+	fprintf(stderr, "rexpr(%s,%s);\n", expr,s);

+	freelist = NULL;

+	_c = expr;

+	next();

+	if ( regExpr(&nfa) == -1 ) return -1;

+	accept = nfa.right;

+	result = match(nfa.left, s);

+	/* free all your memory */

+	p = q = freelist;

+	while ( p!=NULL ) { q = p->track; free(p); p = q; }

+	return result;

+}

+

+/*

+ * do a depth-first-search on the NFA looking for a path from start to

+ * accept state labelled with the characters of 's'.

+ */

+

+#ifdef __USE_PROTOS

+static int match(NodePtr automaton,char *s)

+#else

+static int match(automaton, s)

+NodePtr automaton;

+char *s;

+#endif

+{

+	ArcPtr p;

+	

+	if ( automaton == accept && *s == '\0' ) return 1;	/* match */

+

+	for (p=automaton->arcs; p!=NULL; p=p->next)			/* try all arcs */

+	{

+		if ( p->label == Epsilon )

+		{

+			if ( match(p->target, s) ) return 1;

+		}

+		else if ( p->label == *s )

+				if ( match(p->target, s+1) ) return 1;

+	}

+	return 0;

+}

+

+/*

+ * <regExpr>        ::= <andExpr> ( '|' {<andExpr>} )*

+ *

+ * Return -1 if syntax error

+ * Return  0 if none found

+ * Return  1 if a regExrp was found

+ */

+

+#ifdef __USE_PROTOS

+static int regExpr(GraphPtr g)

+#else

+static int regExpr(g)

+GraphPtr g;

+#endif

+{

+	Graph g1, g2;

+	

+	if ( andExpr(&g1) == -1 )

+	{

+		return -1;

+	}

+	

+	while ( token == '|' )

+	{

+		int a;

+		next();

+		a = andExpr(&g2);

+		if ( a == -1 ) return -1;	/* syntax error below */

+		else if ( !a ) return 1;	/* empty alternative */

+		g1 = BuildNFA_AorB(g1, g2);

+	}

+	

+	if ( token!='\0' ) return -1;

+

+	*g = g1;

+	return 1;

+}

+

+/*

+ * <andExpr>        ::= <expr> ( <expr> )*

+ */

+

+#ifdef __USE_PROTOS

+static int andExpr(GraphPtr g)

+#else

+static int andExpr(g)

+GraphPtr g;

+#endif

+{

+	Graph g1, g2;

+	

+	if ( expr(&g1) == -1 )

+	{

+		return -1;

+	}

+	

+	while ( token==Atom || token=='{' || token=='(' || token=='~' || token=='[' )

+	{

+		if (expr(&g2) == -1) return -1;

+		g1 = BuildNFA_AB(g1, g2);

+	}

+	

+	*g = g1;

+	return 1;

+}

+

+/*

+ * <expr>           ::=    {'~'} '[' <atomList> ']' <repeatSymbol>

+ *                      | '(' <regExpr> ')' <repeatSymbol>

+ *                      | '{' <regExpr> '}' <repeatSymbol>

+ *                      | <atom> <repeatSymbol>

+ */

+

+#ifdef __USE_PROTOS

+static int expr(GraphPtr g)

+#else

+static int expr(g)

+GraphPtr g;

+#endif

+{

+	int complement = 0;

+	char s[257];    /* alloc space for string of char in [] */

+	

+	if ( token == '~' || token == '[' )

+	{

+		if ( token == '~' ) {complement = 1; next();}

+		if ( token != '[' ) return -1;

+		next();

+		if ( atomList( s, complement ) == -1 ) return -1;

+		*g = BuildNFA_set( s );

+		if ( token != ']' ) return -1;

+		next();

+		repeatSymbol( g );

+		return 1;

+	}

+	if ( token == '(' )

+	{

+		next();

+		if ( regExpr( g ) == -1 ) return -1;

+		if ( token != ')' ) return -1;

+		next();

+		repeatSymbol( g );

+		return 1;

+	}

+	if ( token == '{' )

+	{

+		next();

+		if ( regExpr( g ) == -1 ) return -1;

+		if ( token != '}' ) return -1;

+		next();

+		/* S p e c i a l  C a s e   O p t i o n a l  {  } */

+		if ( token != '*' && token != '+' )

+		{

+			*g = BuildNFA_Aoptional( *g );

+		}

+		repeatSymbol( g );

+		return 1;

+	}

+	if ( token == Atom )

+	{

+		*g = BuildNFA_atom( tokchar );

+		next();

+		repeatSymbol( g );

+		return 1;

+	}

+	

+	return -1;

+}

+

+/*

+ * <repeatSymbol>   ::= { '*' | '+' }

+ */

+#ifdef __USE_PROTOS

+static int repeatSymbol(GraphPtr g)

+#else

+static int repeatSymbol(g)

+GraphPtr g;

+#endif

+{

+	switch ( token )

+	{

+		case '*' : *g = BuildNFA_Astar( *g ); next(); break;

+		case '+' : *g = BuildNFA_Aplus( *g ); next(); break;

+	}

+	return 1;

+}

+

+/*

+ * <atomList>       ::= <atom> { <atom> }*

+ *                      { <atomList> } <atom> '-' <atom> { <atomList> }

+ *

+ * a-b is same as ab

+ * q-a is same as q

+ */

+

+#ifdef __USE_PROTOS

+static int atomList(char *p, int complement)

+#else

+static int atomList(p, complement)

+char *p;

+int complement;

+#endif

+{

+	static unsigned char set[256];		/* no duplicates */

+	int first, last, i;

+	char *s = p;

+	

+	if ( token != Atom ) return -1;

+	

+	for (i=0; i<256; i++) set[i] = 0;

+	while ( token == Atom )

+	{

+		if ( !set[tokchar] ) *s++ = tokchar;

+		set[tokchar] = 1;    			/* Add atom to set */

+		next();

+		if ( token == '-' )         	/* have we found '-' */

+		{

+			first = *(s-1);             /* Get last char */

+			next();

+			if ( token != Atom ) return -1;

+			else

+			{

+				last = tokchar;

+			}

+			for (i = first+1; i <= last; i++)

+			{

+				if ( !set[tokchar] ) *s++ = i;

+				set[i] = 1;    			/* Add atom to set */

+			}

+			next();

+		}

+	}

+	*s = '\0';

+	if ( complement )

+	{

+		for (i=0; i<256; i++) set[i] = !set[i];

+		for (i=1,s=p; i<256; i++) if ( set[i] ) *s++ = i;

+		*s = '\0';

+	}

+	return 1;

+}

+

+/* a somewhat stupid lexical analyzer */

+

+#ifdef __USE_PROTOS

+static void next(void)

+#else

+static void next()

+#endif

+{

+	while ( *_c==' ' || *_c=='\t' || *_c=='\n' ) _c++;

+	if ( *_c=='\\' )

+	{

+		_c++;

+		if ( isdigit(*_c) )

+		{

+			int n=0;

+			while ( isdigit(*_c) )

+			{

+				n = n*10 + (*_c++ - '0');

+			}

+			if ( n>255 ) n=255;

+			tokchar = n;

+		}

+		else

+		{

+			switch (*_c)

+			{

+				case 'n' : tokchar = '\n'; break;

+				case 't' : tokchar = '\t'; break;

+				case 'r' : tokchar = '\r'; break;

+				default  : tokchar = *_c;

+			}

+			_c++;

+		}

+		token = Atom;

+	}

+	else if ( isgraph(*_c) && *_c!='[' && *_c!='(' && *_c!='{' &&

+			  *_c!='-' && *_c!='}' && *_c!=')' && *_c!=']' &&

+			  *_c!='+' && *_c!='*' && *_c!='~' && *_c!='|' )

+	{

+		token = Atom;

+		tokchar = *_c++;

+	}

+	else

+	{

+		token = tokchar = *_c++;

+	}

+}

+

+/* N F A  B u i l d i n g  R o u t i n e s */

+

+#ifdef __USE_PROTOS

+static ArcPtr newGraphArc(void)

+#else

+static ArcPtr newGraphArc()

+#endif

+{

+	ArcPtr p;

+	p = (ArcPtr) calloc(1, sizeof(Arc));

+	if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);}

+	if ( freelist != NULL ) p->track = (ArcPtr) freelist;

+	freelist = (NodePtr) p;

+	return p;

+}

+

+#ifdef __USE_PROTOS

+static NodePtr newNode(void)

+#else

+static NodePtr newNode()

+#endif

+{

+	NodePtr p;

+	p = (NodePtr) calloc(1, sizeof(Node));

+	if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);}

+	if ( freelist != NULL ) p->track = freelist;

+	freelist = p;

+	return p;

+}

+

+#ifdef __USE_PROTOS

+static void ArcBetweenGraphNodes(NodePtr i,NodePtr j,int label)

+#else

+static void ArcBetweenGraphNodes(i, j, label)

+NodePtr i, j;

+int label;

+#endif

+{

+	ArcPtr a;

+	

+	a = newGraphArc();

+	if ( i->arcs == NULL ) i->arctail = i->arcs = a;

+	else {(i->arctail)->next = a; i->arctail = a;}

+	a->label = label;

+	a->target = j;

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_atom(int label)

+#else

+static Graph BuildNFA_atom(label)

+int label;

+#endif

+{

+	Graph g;

+	

+	g.left = newNode();

+	g.right = newNode();

+	ArcBetweenGraphNodes(g.left, g.right, label);

+	return( g );

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_AB(Graph A,Graph B)

+#else

+static Graph BuildNFA_AB(A, B)

+Graph A, B;

+#endif

+{

+	Graph g;

+	

+	ArcBetweenGraphNodes(A.right, B.left, Epsilon);

+	g.left = A.left;

+	g.right = B.right;

+	return( g );

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_AorB(Graph A,Graph B)

+#else

+static Graph BuildNFA_AorB(A, B)

+Graph A, B;

+#endif

+{

+	Graph g;

+	

+	g.left = newNode();

+	ArcBetweenGraphNodes(g.left, A.left, Epsilon);

+	ArcBetweenGraphNodes(g.left, B.left, Epsilon);

+	g.right = newNode();

+	ArcBetweenGraphNodes(A.right, g.right, Epsilon);

+	ArcBetweenGraphNodes(B.right, g.right, Epsilon);

+	return( g );

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_set(char *s)

+#else

+static Graph BuildNFA_set( s )

+char *s;

+#endif

+{

+	Graph g;

+	

+	if ( s == NULL ) return g;

+	

+	g.left = newNode();

+	g.right = newNode();

+	while ( *s != '\0' )

+	{

+		ArcBetweenGraphNodes(g.left, g.right, *s++);

+	}

+	return g;

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_Astar(Graph A)

+#else

+static Graph BuildNFA_Astar( A )

+Graph A;

+#endif

+{

+	Graph g;

+

+	g.left = newNode();

+	g.right = newNode();

+	

+	ArcBetweenGraphNodes(g.left, A.left, Epsilon);

+	ArcBetweenGraphNodes(g.left, g.right, Epsilon);

+	ArcBetweenGraphNodes(A.right, g.right, Epsilon);

+	ArcBetweenGraphNodes(A.right, A.left, Epsilon);

+	

+	return( g );

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_Aplus(Graph A)

+#else

+static Graph BuildNFA_Aplus( A )

+Graph A;

+#endif

+{

+	ArcBetweenGraphNodes(A.right, A.left, Epsilon);

+	

+	return( A );

+}

+

+#ifdef __USE_PROTOS

+static Graph BuildNFA_Aoptional(Graph A)

+#else

+static Graph BuildNFA_Aoptional( A )

+Graph A;

+#endif

+{

+	Graph g;

+	

+	g.left = newNode();

+	g.right = newNode();

+	

+	ArcBetweenGraphNodes(g.left, A.left, Epsilon);

+	ArcBetweenGraphNodes(g.left, g.right, Epsilon);

+	ArcBetweenGraphNodes(A.right, g.right, Epsilon);

+	

+	return( g );

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/rexpr.h b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/rexpr.h
new file mode 100644
index 0000000..e67a965
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/rexpr.h
@@ -0,0 +1,30 @@
+#define Atom	256		/* token Atom (an impossible char value) */

+#define Epsilon	257		/* epsilon arc (an impossible char value) */

+

+/* track field must be same for all node types */

+typedef struct _a {

+					struct _a *track;	/* track mem allocation */

+					int label;

+					struct _a *next;

+					struct _n *target;

+				} Arc, *ArcPtr;

+

+typedef struct _n {

+					struct _n *track;

+					ArcPtr arcs, arctail;

+				} Node, *NodePtr;

+

+typedef struct	{

+					NodePtr left,

+						 	right;

+				} Graph, *GraphPtr;

+

+#ifdef __USE_PROTOS

+int rexpr( char *expr, char *s );

+int match( NodePtr automaton, char *s );

+#else

+int rexpr();

+int match();

+#endif

+

+

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/test.c b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/test.c
new file mode 100644
index 0000000..2619539
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/rexpr/test.c
@@ -0,0 +1,19 @@
+#include <stdio.h>

+#include "rexpr.h"

+

+/*

+ * test for rexpr().

+ * To make this test:

+ *	cc -o rexpr test.c rexpr.c

+ * Then from command line type:

+ *	rexpr r string

+ * where r is the regular expression that decribes a language

+ * and string is the string to verify.

+ */

+main(argc,argv)

+int argc;

+char *argv[];

+{

+	if ( argc!=3 ) fprintf(stderr,"rexpr: expr s\n");

+	else printf("%d\n", rexpr(argv[1], argv[2]));

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/set/set.c b/edk2/Tools/Source/TianoTools/Pccts/support/set/set.c
new file mode 100644
index 0000000..eb6fba7
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/set/set.c
@@ -0,0 +1,816 @@
+/*	set.c

+

+	The following is a general-purpose set library originally developed

+	by Hank Dietz and enhanced by Terence Parr to allow dynamic sets.

+	

+	Sets are now structs containing the #words in the set and

+	a pointer to the actual set words.

+	

+	Generally, sets need not be explicitly allocated.  They are

+	created/extended/shrunk when appropriate (e.g. in set_of()).

+	HOWEVER, sets need to be destroyed (free()ed) when they go out of scope

+	or are otherwise no longer needed.  A routine is provided to

+	free a set.

+	

+	Sets can be explicitly created with set_new(s, max_elem).

+	

+	Sets can be declared to have minimum size to reduce realloc traffic.

+	Default minimum size = 1.

+	

+	Sets can be explicitly initialized to have no elements (set.n == 0)

+	by using the 'empty' initializer:

+	

+	Examples:

+		set a = empty;	-- set_deg(a) == 0

+		

+		return( empty );

+	

+	Example set creation and destruction:

+	

+	set

+	set_of2(e,g)

+	unsigned e,g;

+	{

+		set a,b,c;

+		

+		b = set_of(e);		-- Creates space for b and sticks in e

+		set_new(c, g);		-- set_new(); set_orel() ==> set_of()

+		set_orel(g, &c);

+		a = set_or(b, c);

+		.

+		.

+		.

+		set_free(b);

+		set_free(c);

+		return( a );

+	}

+

+	1987 by Hank Dietz

+	

+	Modified by:

+		Terence Parr

+		Purdue University

+		October 1989

+

+	Made it smell less bad to C++ 7/31/93 -- TJP

+*/

+

+#include <stdio.h>

+#include "pcctscfg.h"

+#ifdef __STDC__

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif

+#include <string.h>

+

+#include "set.h"

+

+#define MIN(i,j) ( (i) > (j) ? (j) : (i))

+#define MAX(i,j) ( (i) < (j) ? (j) : (i))

+

+/* elems can be a maximum of 32 bits */

+static unsigned bitmask[] = {

+	0x00000001, 0x00000002, 0x00000004, 0x00000008,

+	0x00000010, 0x00000020, 0x00000040, 0x00000080,

+	0x00000100, 0x00000200, 0x00000400, 0x00000800,

+	0x00001000, 0x00002000, 0x00004000, 0x00008000,

+#if !defined(PC) || defined(PC32)

+	0x00010000, 0x00020000, 0x00040000, 0x00080000,

+	0x00100000, 0x00200000, 0x00400000, 0x00800000,

+	0x01000000, 0x02000000, 0x04000000, 0x08000000,

+	0x10000000, 0x20000000, 0x40000000, 0x80000000

+#endif

+};

+

+set empty = set_init;

+static unsigned min=1;

+

+#define StrSize		200

+

+#ifdef MEMCHK

+#define CHK(a)					\

+	if ( a.setword != NULL )	\

+	  if ( !valid(a.setword) )	\

+		{fprintf(stderr, "%s(%d): invalid set\n",__FILE__,__LINE__); exit(-1);}

+#else

+#define CHK(a)

+#endif

+

+/*

+ * Set the minimum size (in words) of a set to reduce realloc calls

+ */

+void

+#ifdef __USE_PROTOS

+set_size( unsigned n )

+#else

+set_size( n )

+unsigned n;

+#endif

+{

+	min = n;

+}

+

+unsigned int

+#ifdef __USE_PROTOS

+set_deg( set a )

+#else

+set_deg( a )

+set a;

+#endif

+{

+	/* Fast compute degree of a set... the number

+	   of elements present in the set.  Assumes

+	   that all word bits are used in the set

+	   and that SETSIZE(a) is a multiple of WORDSIZE.

+	*/

+	register unsigned *p = &(a.setword[0]);

+	register unsigned *endp = NULL; /* MR27 Avoid false memory check report */

+	register unsigned degree = 0;

+

+	CHK(a);

+	if ( a.n == 0 ) return(0);

+	endp = &(a.setword[a.n]);

+	while ( p < endp )

+	{

+		register unsigned t = *p;

+		register unsigned *b = &(bitmask[0]);

+		do {

+			if (t & *b) ++degree;

+		} while (++b < &(bitmask[WORDSIZE]));

+		p++;

+	}

+

+	return(degree);

+}

+

+set

+#ifdef __USE_PROTOS

+set_or( set b, set c )

+#else

+set_or( b, c )

+set b;

+set c;

+#endif

+{

+	/* Fast set union operation */

+	/* resultant set size is max(b, c); */

+	set *big;

+	set t;

+	unsigned int m,n;

+	register unsigned *r, *p, *q, *endp;

+

+	CHK(b); CHK(c);

+	t = empty;

+	if (b.n > c.n) {big= &b; m=b.n; n=c.n;} else {big= &c; m=c.n; n=b.n;}

+	set_ext(&t, m);

+	r = t.setword;

+

+	/* Or b,c until max of smaller set */

+	q = c.setword;

+	p = b.setword;

+	endp = &(b.setword[n]);

+	while ( p < endp ) *r++ = *p++ | *q++;	

+

+	/* Copy rest of bigger set into result */

+	p = &(big->setword[n]);

+	endp = &(big->setword[m]);

+	while ( p < endp ) *r++ = *p++;

+

+	return(t);

+}

+

+set

+#ifdef __USE_PROTOS

+set_and( set b, set c )

+#else

+set_and( b, c )

+set b;

+set c;

+#endif

+{

+	/* Fast set intersection operation */

+	/* resultant set size is min(b, c); */

+	set t;

+	unsigned int n;

+	register unsigned *r, *p, *q, *endp;

+

+	CHK(b); CHK(c);

+	t = empty;

+	n = (b.n > c.n) ? c.n : b.n;

+	if ( n == 0 ) return t;		/* TJP 4-27-92 fixed for empty set */

+	set_ext(&t, n);

+	r = t.setword;

+

+	/* & b,c until max of smaller set */

+	q = c.setword;

+	p = b.setword;

+	endp = &(b.setword[n]);

+	while ( p < endp ) *r++ = *p++ & *q++;	

+

+	return(t);

+}

+

+set

+#ifdef __USE_PROTOS

+set_dif( set b, set c )

+#else

+set_dif( b, c )

+set b;

+set c;

+#endif

+{

+	/* Fast set difference operation b - c */

+	/* resultant set size is size(b) */

+	set t;

+	unsigned int n;

+	register unsigned *r, *p, *q, *endp;

+

+	CHK(b); CHK(c);

+	t = empty;

+	n = (b.n <= c.n) ? b.n : c.n ;

+	if ( b.n == 0 ) return t;		/* TJP 4-27-92 fixed for empty set */

+									/* WEC 12-1-92 fixed for c.n = 0 */

+	set_ext(&t, b.n);

+	r = t.setword;

+

+	/* Dif b,c until smaller set size */

+	q = c.setword;

+	p = b.setword;

+	endp = &(b.setword[n]);

+	while ( p < endp ) *r++ = *p++ & (~ *q++);	

+

+	/* Copy rest of b into result if size(b) > c */

+	if ( b.n > n )

+	{

+		p = &(b.setword[n]);

+		endp = &(b.setword[b.n]);

+		while ( p < endp ) *r++ = *p++;

+	}

+

+	return(t);

+}

+

+set

+#ifdef __USE_PROTOS

+set_of( unsigned b )

+#else

+set_of( b )

+unsigned b;

+#endif

+{

+	/* Fast singleton set constructor operation */

+	static set a;

+

+	if ( b == nil ) return( empty );

+	set_new(a, b);

+	a.setword[DIVWORD(b)] = bitmask[MODWORD(b)];

+

+	return(a);

+}

+

+/*

+ * Extend (or shrink) the set passed in to have n words.

+ *

+ * if n is smaller than the minimum, boost n to have the minimum.

+ * if the new set size is the same as the old one, do nothing.

+ *

+ * TJP 4-27-92 Fixed so won't try to alloc 0 bytes

+ */

+void

+#ifdef __USE_PROTOS

+set_ext( set *a, unsigned int n )

+#else

+set_ext( a, n )

+set *a;

+unsigned int n;

+#endif

+{

+	register unsigned *p;

+	register unsigned *endp;

+	unsigned int size;

+	

+	CHK((*a));

+    if ( a->n == 0 )

+    {

+		if ( n == 0 ) return;

+		if (a->setword != NULL) {

+			free (a->setword);	/* MR20 */

+		}

+        a->setword = (unsigned *) calloc(n, BytesPerWord);

+        if ( a->setword == NULL )

+        {

+            fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n);

+            exit(-1);

+        }

+        a->n = n;

+        return;

+    }

+	if ( n < min ) n = min;

+	if ( a->n == n || n == 0 ) return;

+	size = a->n;

+	a->n = n;

+	a->setword = (unsigned *) realloc( (char *)a->setword, (n*BytesPerWord) );

+	if ( a->setword == NULL )

+	{

+		fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n);

+		exit(-1);

+	}

+

+	p    = &(a->setword[size]);		/* clear from old size to new size */

+	endp = &(a->setword[a->n]);

+	do {

+		*p++ = 0;

+	} while ( p < endp );

+}

+

+set

+#ifdef __USE_PROTOS

+set_not( set a )

+#else

+set_not( a )

+set a;

+#endif

+{

+	/* Fast not of set a (assumes all bits used) */

+	/* size of resultant set is size(a) */

+	/* ~empty = empty cause we don't know how bit to make set */

+	set t;

+	register unsigned *r;

+	register unsigned *p = a.setword;

+	register unsigned *endp = &(a.setword[a.n]);

+

+	CHK(a);

+	t = empty;

+	if ( a.n == 0 ) return( empty );

+	set_ext(&t, a.n);

+	r = t.setword;

+	

+	do {

+		*r++ = (~ *p++);

+	} while ( p < endp );

+

+	return(t);

+}

+

+int

+#ifdef __USE_PROTOS

+set_equ( set a, set b )

+#else

+set_equ( a, b )

+set a;

+set b;

+#endif

+{

+/* 8-Nov-97     Make it work with sets of different sizes       */

+/*              Easy to understand, too.  Probably faster.      */

+/*              Check for a equal to b                          */

+

+    unsigned int    count;      /* MR11 */

+    unsigned int    i;          /* MR11 */

+

+	CHK(a); CHK(b);

+

+    count=MIN(a.n,b.n);

+    if (count == 0) return 1;

+    for (i=0; i < count; i++) {

+      if (a.setword[i] != b.setword[i]) return 0;

+    };

+    if (a.n < b.n) {

+      for (i=count; i < b.n; i++) {

+        if (b.setword[i] != 0) return 0;

+      }

+      return 1;

+    } else if (a.n > b.n) {

+      for (i=count; i < a.n; i++) {

+        if (a.setword[i] != 0) return 0;

+      }

+      return 1;

+    } else {

+      return 1;

+    };

+}

+

+int

+#ifdef __USE_PROTOS

+set_sub( set a, set b )

+#else

+set_sub( a, b )

+set a;

+set b;

+#endif

+{

+

+/* 8-Nov-97     Make it work with sets of different sizes       */

+/*              Easy to understand, too.  Probably faster.      */

+/*              Check for a is a PROPER subset of b             */

+

+    unsigned int    count;

+    unsigned int    i;

+

+	CHK(a); CHK(b);

+

+    if (a.n == 0) return 1;

+    count=MIN(a.n,b.n);

+    for (i=0; i < count; i++) {

+      if (a.setword[i] & ~b.setword[i]) return 0;

+    };

+    if (a.n <= b.n) {

+      return 1;

+    } else {

+      for (i=count; i<a.n ; i++) {

+        if (a.setword[i]) return 0;

+      };

+    };

+    return 1;

+}

+

+unsigned

+#ifdef __USE_PROTOS

+set_int( set b )

+#else

+set_int( b )

+set b;

+#endif

+{

+	/* Fast pick any element of the set b */

+	register unsigned *p = b.setword;

+	register unsigned *endp = &(b.setword[b.n]);

+

+	CHK(b);

+	if ( b.n == 0 ) return( nil );

+

+	do {

+		if (*p) {

+			/* Found a non-empty word of the set */

+			register unsigned i = ((p - b.setword) << LogWordSize);

+			register unsigned t = *p;

+			p = &(bitmask[0]);

+			while (!(*p & t)) {

+				++i; ++p;

+			}

+			return(i);

+		}

+	} while (++p < endp);

+

+	/* Empty -- only element it contains is nil */

+	return(nil);

+}

+

+int

+#ifdef __USE_PROTOS

+set_el( unsigned b, set a )

+#else

+set_el( b, a )

+unsigned b;

+set a;

+#endif

+{

+	CHK(a);

+	/* nil is an element of every set */

+	if (b == nil) return(1);

+	if ( a.n == 0 || NumWords(b) > a.n ) return(0);

+	

+	/* Otherwise, we have to check */

+	return( a.setword[DIVWORD(b)] & bitmask[MODWORD(b)] );

+}

+

+int

+#ifdef __USE_PROTOS

+set_nil( set a )

+#else

+set_nil( a )

+set a;

+#endif

+{

+	/* Fast check for nil set */

+	register unsigned *p = a.setword;

+	register unsigned *endp;

+

+	CHK(a);

+	if ( a.n == 0 ) return(1);

+	endp = &(a.setword[a.n]);

+	

+	/* The set is not empty if any word used to store

+	   the set is non-zero.  This means one must be a

+	   bit careful about doing things like negation.

+	*/

+	do {

+		if (*p) return(0);

+	} while (++p < endp);

+	

+	return(1);

+}

+

+char *

+#ifdef __USE_PROTOS

+set_str( set a )

+#else

+set_str( a )

+set a;

+#endif

+{

+	/* Fast convert set a into ASCII char string...

+	   assumes that all word bits are used in the set

+	   and that SETSIZE is a multiple of WORDSIZE.

+	   Trailing 0 bits are removed from the string.

+	   if no bits are on or set is empty, "" is returned.

+	*/

+	register unsigned *p = a.setword;

+	register unsigned *endp = &(a.setword[a.n]);

+	static char str_tmp[StrSize+1];

+	register char *q = &(str_tmp[0]);

+

+	CHK(a);

+	if ( a.n==0 ) {*q=0; return( &(str_tmp[0]) );}

+	do {

+		register unsigned t = *p;

+		register unsigned *b = &(bitmask[0]);

+		do {

+			*(q++) = (char) ((t & *b) ? '1' : '0');

+		} while (++b < &(bitmask[WORDSIZE]));

+	} while (++p < endp);

+

+	/* Trim trailing 0s & NULL terminate the string */

+	while ((q > &(str_tmp[0])) && (*(q-1) != '1')) --q;

+	*q = 0;

+

+	return(&(str_tmp[0]));

+}

+

+set

+#ifdef __USE_PROTOS

+set_val( register char *s )

+#else

+set_val( s )

+register char *s;

+#endif

+{

+	/* Fast convert set ASCII char string into a set.

+	   If the string ends early, the remaining set bits

+	   are all made zero.

+	   The resulting set size is just big enough to hold all elements.

+	*/

+	static set a;

+	register unsigned *p, *endp;

+

+	set_new(a, strlen(s));

+	p = a.setword;

+	endp = &(a.setword[a.n]);

+	do {

+		register unsigned *b = &(bitmask[0]);

+		/* Start with a word with no bits on */

+		*p = 0;

+		do {

+			if (*s) {

+				if (*s == '1') {

+					/* Turn-on this bit */

+					*p |= *b;

+				}

+				++s;

+			}

+		} while (++b < &(bitmask[WORDSIZE]));

+	} while (++p < endp);

+

+	return(a);

+}

+

+/*

+ * Or element e into set a.  a can be empty.

+ */

+void

+#ifdef __USE_PROTOS

+set_orel( unsigned e, set *a )

+#else

+set_orel( e, a )

+unsigned e;

+set *a;

+#endif

+{

+	CHK((*a));

+	if ( e == nil ) return;

+	if ( NumWords(e) > a->n ) set_ext(a, NumWords(e));

+	a->setword[DIVWORD(e)] |= bitmask[MODWORD(e)];

+}

+

+/*

+ * Or set b into set a.  a can be empty. does nothing if b empty.

+ */

+void

+#ifdef __USE_PROTOS

+set_orin( set *a, set b )

+#else

+set_orin( a, b )

+set *a;

+set b;

+#endif

+{

+	/* Fast set union operation */

+	/* size(a) is max(a, b); */

+	unsigned int m;

+	register unsigned *p,

+					  *q    = b.setword,

+					  *endq; /* MR20 */

+

+	CHK((*a)); CHK(b);

+	if ( b.n == 0 ) return;

+	endq = &(b.setword[b.n]); /* MR20 */

+	m = (a->n > b.n) ? a->n : b.n;

+	set_ext(a, m);

+	p = a->setword;

+	do {

+		*p++ |= *q++;

+	} while ( q < endq );

+}

+

+/*

+ * And set b into set a.  a can be empty. does nothing if b empty.

+ */

+void

+#ifdef __USE_PROTOS

+set_andin( set *a, set b )

+#else

+set_andin( a, b )

+set *a;

+set b;

+#endif

+{

+	/* Fast set intersection operation */

+	/* size(a) is max(a, b); */

+	unsigned int m;

+	register unsigned *p,

+					  *q    = b.setword,

+					  *endq = &(b.setword[b.n]);

+

+	CHK((*a)); CHK(b);

+	if ( b.n == 0 ) return;

+	m = (a->n > b.n) ? a->n : b.n;

+	set_ext(a, m);

+	p = a->setword;

+	do {

+		*p++ &= *q++;

+	} while ( q < endq );

+}

+

+void

+#ifdef __USE_PROTOS

+set_rm( unsigned e, set a )

+#else

+set_rm( e, a )

+unsigned e;

+set a;

+#endif

+{

+	/* Does not effect size of set */

+	CHK(a);

+	if ( (e == nil) || (NumWords(e) > a.n) ) return;

+	a.setword[DIVWORD(e)] ^= (a.setword[DIVWORD(e)]&bitmask[MODWORD(e)]);

+}

+

+void

+#ifdef __USE_PROTOS

+set_clr( set a )

+#else

+set_clr( a )

+set a;

+#endif

+{

+	/* Does not effect size of set */

+	register unsigned *p = a.setword;

+	register unsigned *endp;

+	

+	CHK(a);

+	if ( a.n == 0 ) return;

+	endp = &(a.setword[a.n]);

+	do {

+		*p++ = 0;

+	} while ( p < endp );

+}

+

+set

+#ifdef __USE_PROTOS

+set_dup( set a )

+#else

+set_dup( a )

+set a;

+#endif

+{

+	set b;

+	register unsigned *p,

+					  *q    = a.setword,

+					  *endq; /* MR20 */

+	

+	CHK(a);

+	b = empty;

+	if ( a.n == 0 ) return( empty );

+	endq = &(a.setword[a.n]);	/* MR20 */

+	set_ext(&b, a.n);

+	p = b.setword;

+	do {

+		*p++ = *q++;

+	} while ( q < endq );

+	

+	return(b);

+}

+

+/*

+ * Return a nil terminated list of unsigned ints that represents all

+ * "on" bits in the bit set.

+ *

+ * e.g. {011011} --> {1, 2, 4, 5, nil}

+ *

+ * _set_pdq and set_pdq are useful when an operation is required on each element

+ * of a set.  Normally, the sequence is:

+ *

+ *		while ( set_deg(a) > 0 ) {

+ *			e = set_int(a);

+ *			set_rm(e, a);

+ *			...process e...

+ *		}

+ * Now,

+ *

+ *		t = e = set_pdq(a);

+ *		while ( *e != nil ) {

+ *			...process *e...

+ *			e++;

+ *		}

+ *		free( t );

+ *

+ * We have saved many set calls and have not destroyed set a.

+ */

+void

+#ifdef __USE_PROTOS

+_set_pdq( set a, register unsigned *q )

+#else

+_set_pdq( a, q )

+set a;

+register unsigned *q;

+#endif

+{

+	register unsigned *p = a.setword,

+					  *endp = &(a.setword[a.n]);

+	register unsigned e=0;

+

+	CHK(a);

+	/* are there any space (possibility of elements)? */

+	if ( a.n == 0 ) return;

+	do {

+		register unsigned t = *p;

+		register unsigned *b = &(bitmask[0]);

+		do {

+			if ( t & *b ) *q++ = e;

+			++e;

+		} while (++b < &(bitmask[WORDSIZE]));

+	} while (++p < endp);

+	*q = nil;

+}

+

+/*

+ * Same as _set_pdq except allocate memory.  set_pdq is the natural function

+ * to use.

+ */

+unsigned *

+#ifdef __USE_PROTOS

+set_pdq( set a )

+#else

+set_pdq( a )

+set a;

+#endif

+{

+	unsigned *q;

+	int max_deg;

+	

+	CHK(a);

+	max_deg = WORDSIZE*a.n;

+	/* assume a.n!=0 & no elements is rare, but still ok */

+	if ( a.n == 0 ) return(NULL);

+	q = (unsigned *) malloc((max_deg+1)*BytesPerWord);

+	if ( q == NULL ) return( NULL );

+	_set_pdq(a, q);

+	return( q );

+}

+

+/* a function that produces a hash number for the set

+ */

+unsigned int

+#ifdef __USE_PROTOS

+set_hash( set a, register unsigned int mod )

+#else

+set_hash( a, mod )

+set a;

+register unsigned int mod;

+#endif

+{

+	/* Fast hash of set a (assumes all bits used) */

+	register unsigned *p = &(a.setword[0]);

+	register unsigned *endp = &(a.setword[a.n]);

+	register unsigned i = 0;

+

+	CHK(a);

+	while (p<endp){

+		i += (*p);

+		++p;

+	}

+

+	return(i % mod);

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/set/set.h b/edk2/Tools/Source/TianoTools/Pccts/support/set/set.h
new file mode 100644
index 0000000..5d68152
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/set/set.h
@@ -0,0 +1,121 @@
+#ifndef __GATE_SET_H

+#define __GATE_SET_H

+

+/*	set.h

+

+	The following is a general-purpose set library originally developed

+	by Hank Dietz and enhanced by Terence Parr to allow dynamic sets.

+	

+	Sets are now structs containing the #words in the set and

+	a pointer to the actual set words.

+

+	1987 by Hank Dietz

+	

+	Modified by:

+		Terence Parr

+		Purdue University

+		October 1989

+

+		Added ANSI prototyping Dec. 1992 -- TJP

+*/

+

+#include "pcctscfg.h"

+

+#ifdef NOT_USED /* SEE config.h */

+/* Define usable bits per unsigned int word */

+#ifdef PC

+#define WORDSIZE 16

+#define LogWordSize	4

+#else

+#define	WORDSIZE 32

+#define LogWordSize 5

+#endif

+#define BytesPerWord	sizeof(unsigned)

+#endif

+

+#define	SETSIZE(a) ((a).n<<LogWordSize)		/* Maximum items per set */

+#define	MODWORD(x) ((x) & (WORDSIZE-1))		/* x % WORDSIZE */

+#define	DIVWORD(x) ((x) >> LogWordSize)		/* x / WORDSIZE */

+#define	nil	(~((unsigned) 0))	/* An impossible set member all bits on (big!) */

+

+typedef struct _set {

+			unsigned int n;		/* Number of words in set */

+			unsigned *setword;

+		} set;

+

+#define set_init	{0, NULL}

+#define set_null(a)	((a).setword==NULL)

+

+#define	NumBytes(x)		(((x)>>3)+1)						/* Num bytes to hold x */

+#define	NumWords(x)		((((unsigned)(x))>>LogWordSize)+1)	/* Num words to hold x */

+

+

+/* M a c r o s */

+

+/* make arg1 a set big enough to hold max elem # of arg2 */

+#define set_new(a,_max) \

+if (((a).setword=(unsigned *)calloc(NumWords(_max),BytesPerWord))==NULL) \

+        fprintf(stderr, "set_new: Cannot allocate set with max of %d\n", _max); \

+        (a).n = NumWords(_max);

+

+#define set_free(a)									\

+	{if ( (a).setword != NULL ) free((char *)((a).setword));	\

+	(a) = empty;}

+

+#ifdef __USE_PROTOS

+extern void set_size( unsigned );

+extern unsigned int set_deg( set );

+extern set set_or( set, set );

+extern set set_and( set, set );

+extern set set_dif( set, set );

+extern set set_of( unsigned );

+extern void set_ext( set *, unsigned int );

+extern set set_not( set );

+extern int set_equ( set, set );

+extern int set_sub( set, set );

+extern unsigned set_int( set );

+extern int set_el( unsigned, set );

+extern int set_nil( set );

+extern char * set_str( set );

+extern set set_val( register char * );

+extern void set_orel( unsigned, set * );

+extern void set_orin( set *, set );

+extern void set_andin( set *, set );

+extern void set_rm( unsigned, set );

+extern void set_clr( set );

+extern set set_dup( set );

+extern void set_PDQ( set, register unsigned * );

+extern unsigned *set_pdq( set );

+extern void _set_pdq( set a, register unsigned *q );

+extern unsigned int set_hash( set, register unsigned int );

+#else

+extern void set_size();

+extern unsigned int set_deg();

+extern set set_or();

+extern set set_and();

+extern set set_dif();

+extern set set_of();

+extern void set_ext();

+extern set set_not();

+extern int set_equ();

+extern int set_sub();

+extern unsigned set_int();

+extern int set_el();

+extern int set_nil();

+extern char * set_str();

+extern set set_val();

+extern void set_orel();

+extern void set_orin();

+extern void set_andin();

+extern void set_rm();

+extern void set_clr();

+extern set set_dup();

+extern void set_PDQ();

+extern unsigned *set_pdq();

+extern void _set_pdq();

+extern unsigned int set_hash();

+#endif

+

+extern set empty;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/sym/sym.c b/edk2/Tools/Source/TianoTools/Pccts/support/sym/sym.c
new file mode 100644
index 0000000..eccce05
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/sym/sym.c
@@ -0,0 +1,402 @@
+/*

+ * Simple symbol table manager using coalesced chaining to resolve collisions

+ *

+ * Doubly-linked lists are used for fast removal of entries.

+ *

+ * 'sym.h' must have a definition for typedef "Sym".  Sym must include at

+ * minimum the following fields:

+ *

+ *		...

+ *		char *symbol;

+ *		struct ... *next, *prev, **head, *scope;

+ *		unsigned int hash;

+ *		...

+ *

+ * 'template.h' can be used as a template to create a 'sym.h'.

+ *

+ * 'head' is &(table[hash(itself)]).

+ * The hash table is not resizable at run-time.

+ * The scope field is used to link all symbols of a current scope together.

+ * Scope() sets the current scope (linked list) to add symbols to.

+ * Any number of scopes can be handled.  The user passes the address of

+ * a pointer to a symbol table

+ * entry (INITIALIZED TO NULL first time).

+ *

+ * Available Functions:

+ *

+ *	zzs_init(s1,s2)	--	Create hash table with size s1, string table size s2.

+ *	zzs_done()		--	Free hash and string table created with zzs_init().

+ *	zzs_add(key,rec)--	Add 'rec' with key 'key' to the symbol table.

+ *	zzs_newadd(key)	--	create entry; add using 'key' to the symbol table.

+ *	zzs_get(key)	--	Return pointer to last record entered under 'key'

+ *						Else return NULL

+ *	zzs_del(p)		--	Unlink the entry associated with p.  This does

+ *						NOT free 'p' and DOES NOT remove it from a scope

+ *						list.  If it was a part of your intermediate code

+ *						tree or another structure.  It will still be there.

+ *			  			It is only removed from further consideration

+ *						by the symbol table.

+ *	zzs_keydel(s)	--	Unlink the entry associated with key s.

+ *						Calls zzs_del(p) to unlink.

+ *	zzs_scope(sc)	--	Specifies that everything added to the symbol

+ *			   			table with zzs_add() is added to the list (scope)

+ *						'sc'.  'sc' is of 'Sym **sc' type and must be

+ *						initialized to NULL before trying to add anything

+ *						to it (passing it to zzs_scope()).  Scopes can be

+ *					    switched at any time and merely links a set of

+ *						symbol table entries.  If a NULL pointer is

+ *						passed, the current scope is returned.

+ *	zzs_rmscope(sc)	--	Remove (zzs_del()) all elements of scope 'sc'

+ *						from the symbol table.  The entries are NOT

+ *						free()'d.  A pointer to the first

+ *			   			element in the "scope" is returned.  The user

+ *			   			can then manipulate the list as he/she chooses

+ *			   			(such as freeing them all). NOTE that this

+ *			   			function sets your scope pointer to NULL,

+ *			   			but returns a pointer to the list for you to use.

+ *	zzs_stat()		--	Print out the symbol table and some relevant stats.

+ *	zzs_new(key)	--	Create a new record with calloc() of type Sym.

+ *			   			Add 'key' to the string table and make the new

+ *			   			records 'symbol' pointer point to it.

+ *	zzs_strdup(s)	--	Add s to the string table and return a pointer

+ *			   			to it.  Very fast allocation routine

+ *						and does not require strlen() nor calloc().

+ *

+ * Example:

+ *

+ *	#include <stdio.h>

+ *	#include "sym.h"

+ *

+ *	main()

+ *	{

+ *	    Sym *scope1=NULL, *scope2=NULL, *a, *p;

+ *	

+ *	    zzs_init(101, 100);

+ *	

+ *	    a = zzs_new("Apple");	zzs_add(a->symbol, a);	-- No scope

+ *	    zzs_scope( &scope1 );	-- enter scope 1

+ *	    a = zzs_new("Plum");	zzs_add(a->symbol, a);

+ *	    zzs_scope( &scope2 );	-- enter scope 2

+ *	    a = zzs_new("Truck");	zzs_add(a->symbol, a);

+ *	

+ *    	p = zzs_get("Plum");

+ *    	if ( p == NULL ) fprintf(stderr, "Hmmm...Can't find 'Plum'\n");

+ *	

+ *    	p = zzs_rmscope(&scope1)

+ *    	for (; p!=NULL; p=p->scope) {printf("Scope1:  %s\n", p->symbol);}

+ *    	p = zzs_rmscope(&scope2)

+ *    	for (; p!=NULL; p=p->scope) {printf("Scope2:  %s\n", p->symbol);}

+ * }

+ *

+ * Terence Parr

+ * Purdue University

+ * February 1990

+ *

+ * CHANGES

+ *

+ *	Terence Parr

+ *	May 1991

+ *		Renamed functions to be consistent with ANTLR

+ *		Made HASH macro

+ *		Added zzs_keydel()

+ *		Added zzs_newadd()

+ *		Fixed up zzs_stat()

+ *

+ *	July 1991

+ *		Made symbol table entry save its hash code for fast comparison

+ *			during searching etc...

+ */

+

+#include <stdio.h>

+#if defined(__STDC__) || defined(__USE_PROTOS)

+#include <string.h>

+#include <stdlib.h>

+#else

+#include <malloc.h>

+#endif

+#include "sym.h"

+

+#define StrSame		0

+

+static Sym **CurScope = NULL;

+static unsigned size = 0;

+static Sym **table=NULL;

+static char *strings;

+static char *strp;

+static int strsize = 0;

+

+#ifdef __USE_PROTOS

+void zzs_init(int sz,int strs)

+#else

+void zzs_init(sz, strs)

+int sz, strs;

+#endif

+{

+	if ( sz <= 0 || strs <= 0 ) return;

+	table = (Sym **) calloc(sz, sizeof(Sym *));

+	if ( table == NULL )

+	{

+		fprintf(stderr, "Cannot allocate table of size %d\n", sz);

+		exit(1);

+	}

+	strings = (char *) calloc(strs, sizeof(char));

+	if ( strings == NULL )

+	{

+		fprintf(stderr, "Cannot allocate string table of size %d\n", strs);

+		exit(1);

+	}

+	size = sz;

+	strsize = strs;

+	strp = strings;

+}

+

+#ifdef __USE_PROTOS

+void zzs_done(void)

+#else

+void zzs_done()

+#endif

+{

+	if ( table != NULL ) free( table );

+	if ( strings != NULL ) free( strings );

+}

+

+#ifdef __USE_PROTOS

+void zzs_add(char *key,Sym rec)

+#else

+void zzs_add(key, rec)

+char *key;

+register Sym *rec;

+#endif

+{

+	register unsigned int h=0;

+	register char *p=key;

+	

+	HASH(p, h);

+	rec->hash = h;					/* save hash code for fast comp later */

+	h %= size;

+	

+	if ( CurScope != NULL ) {rec->scope = *CurScope; *CurScope = rec;}

+	rec->next = table[h];			/* Add to doubly-linked list */

+	rec->prev = NULL;

+	if ( rec->next != NULL ) (rec->next)->prev = rec;

+	table[h] = rec;

+	rec->head = &(table[h]);

+}

+

+#ifdef __USE_PROTOS

+Sym * zzs_get(char *key)

+#else

+Sym * zzs_get(key)

+char *key;

+#endif

+{

+	register unsigned int h=0;

+	register char *p=key;

+	register Sym *q;

+	

+	HASH(p, h);

+	

+	for (q = table[h%size]; q != NULL; q = q->next)

+	{

+		if ( q->hash == h )		/* do we even have a chance of matching? */

+			if ( strcmp(key, q->symbol) == StrSame ) return( q );

+	}

+	return( NULL );

+}

+

+/*

+ * Unlink p from the symbol table.  Hopefully, it's actually in the

+ * symbol table.

+ *

+ * If p is not part of a bucket chain of the symbol table, bad things

+ * will happen.

+ *

+ * Will do nothing if all list pointers are NULL

+ */

+#ifdef __USE_PROTOS

+void zzs_del(Sym *p)

+#else

+void zzs_del(p)

+register Sym *p;

+#endif

+{

+	if ( p == NULL ) {fprintf(stderr, "zzs_del(NULL)\n"); exit(1);}

+	if ( p->prev == NULL )	/* Head of list */

+	{

+		register Sym **t = p->head;

+		

+		if ( t == NULL ) return;	/* not part of symbol table */

+		(*t) = p->next;

+		if ( (*t) != NULL ) (*t)->prev = NULL;

+	}

+	else

+	{

+		(p->prev)->next = p->next;

+		if ( p->next != NULL ) (p->next)->prev = p->prev;

+	}

+	p->next = p->prev = NULL;	/* not part of symbol table anymore */

+	p->head = NULL;

+}

+

+#ifdef __USE_PROTOS

+void zzs_keydel(char *key)

+#else

+void zzs_keydel(key)

+char *key;

+#endif

+{

+	Sym *p = zzs_get(key);

+

+	if ( p != NULL ) zzs_del( p );

+}

+

+/* S c o p e  S t u f f */

+

+/* Set current scope to 'scope'; return current scope if 'scope' == NULL */

+

+#ifdef __USE_PROTOS

+Sym ** zzs_scope(Sym **scope)

+#else

+Sym ** zzs_scope(scope)

+Sym **scope;

+#endif

+{

+	if ( scope == NULL ) return( CurScope );

+	CurScope = scope;

+	return( scope );

+}

+

+/* Remove a scope described by 'scope'.  Return pointer to 1st element in scope */

+

+#ifdef __USE_PROTOS

+Sym * zzs_rmscope(Sym **scope)

+#else

+Sym * zzs_rmscope(scope)

+register Sym **scope;

+#endif

+{

+	register Sym *p;

+	Sym *start;

+

+	if ( scope == NULL ) return(NULL);

+	start = p = *scope;

+	for (; p != NULL; p=p->scope) { zzs_del( p ); }

+	*scope = NULL;

+	return( start );

+}

+

+#ifdef __USE_PROTOS

+void zzs_stat(void)

+#else

+void zzs_stat()

+#endif

+{

+	static unsigned short count[20];

+	unsigned int i,n=0,low=0, hi=0;

+	register Sym **p;

+	float avg=0.0;

+	

+	for (i=0; i<20; i++) count[i] = 0;

+	for (p=table; p<&(table[size]); p++)

+	{

+		register Sym *q = *p;

+		unsigned int len;

+		

+		if ( q != NULL && low==0 ) low = p-table;

+		len = 0;

+		if ( q != NULL ) printf("[%d]", p-table);

+		while ( q != NULL )

+		{

+			len++;

+			n++;

+			printf(" %s", q->symbol);

+			q = q->next;

+			if ( q == NULL ) printf("\n");

+		}

+		if ( len>=20 ) printf("zzs_stat: count table too small\n");

+		else count[len]++;

+		if ( *p != NULL ) hi = p-table;

+	}

+

+	printf("Storing %d recs used %d hash positions out of %d\n",

+			n, size-count[0], size);

+	printf("%f %% utilization\n",

+			((float)(size-count[0]))/((float)size));

+	for (i=0; i<20; i++)

+	{

+		if ( count[i] != 0 )

+		{

+			avg += (((float)(i*count[i]))/((float)n)) * i;

+			printf("Buckets of len %d == %d (%f %% of recs)\n",

+					i, count[i], 100.0*((float)(i*count[i]))/((float)n));

+		}

+	}

+	printf("Avg bucket length %f\n", avg);

+	printf("Range of hash function: %d..%d\n", low, hi);

+}

+

+/*

+ * Given a string, this function allocates and returns a pointer to a

+ * symbol table record whose "symbol" pointer is reset to a position

+ * in the string table.

+ */

+

+#ifdef __USE_PROTOS

+Sym * zzs_new(char *text)

+#else

+Sym * zzs_new(text)

+char *text;

+#endif

+{

+	Sym *p;

+	

+	if ( (p = (Sym *) calloc(1,sizeof(Sym))) == 0 )

+	{

+		fprintf(stderr,"Out of memory\n");

+		exit(1);

+	}

+	p->symbol = zzs_strdup(text);

+	

+	return p;

+}

+

+/* create a new symbol table entry and add it to the symbol table */

+

+#ifdef __USE_PROTOS

+Sym * zzs_newadd(char *text)

+#else

+Sym * zzs_newadd(text)

+char *text;

+#endif

+{

+	Sym *p = zzs_new(text);

+	if ( p != NULL ) zzs_add(text, p);

+	return p;

+}

+

+/* Add a string to the string table and return a pointer to it.

+ * Bump the pointer into the string table to next avail position.

+ */

+

+#ifdef __USE_PROTOS

+char * zzs_strdup(char *s)

+#else

+char * zzs_strdup(s)

+register char *s;

+#endif

+{

+	register char *start=strp;

+

+	while ( *s != '\0' )

+	{

+		if ( strp >= &(strings[strsize-2]) )

+		{

+			fprintf(stderr, "sym: string table overflow (%d chars)\n", strsize);

+			exit(-1);

+		}

+		*strp++ = *s++;

+	}

+	*strp++ = '\0';

+

+	return( start );

+}

diff --git a/edk2/Tools/Source/TianoTools/Pccts/support/sym/template.h b/edk2/Tools/Source/TianoTools/Pccts/support/sym/template.h
new file mode 100644
index 0000000..ee6e665
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Pccts/support/sym/template.h
@@ -0,0 +1,41 @@
+/* T e m p l a t e  F o r  S y m b o l  T a b l e  M a n a g e r */

+

+/* define some hash function */

+#ifndef HASH

+#define HASH(p, h) while ( *p != '\0' ) h = (h<<1) + *p++;

+#endif

+

+/* minimum symbol table record */

+typedef struct _sym {

+			char *symbol;

+			struct _sym *next, *prev, **head, *scope;

+			unsigned int hash;

+		} Sym, *SymPtr;

+

+#ifdef __USE_PROTOS

+void zzs_init(int, int);

+void zzs_done(void);

+void zzs_add(char *, Sym *);

+Sym *zzs_get(char *);

+void zzs_del(Sym *);

+void zzs_keydel(char *);

+Sym **zzs_scope(Sym **);

+Sym *zzs_rmscope(Sym **);

+void zzs_stat(void);

+Sym *zzs_new(char *);

+Sym *zzs_newadd(char *);

+char *zzs_strdup(char *);

+#else

+void zzs_init();

+void zzs_done();

+void zzs_add();

+Sym *zzs_get();

+void zzs_del();

+void zzs_keydel();

+Sym **zzs_scope();

+Sym *zzs_rmscope();

+void zzs_stat();

+Sym *zzs_new();

+Sym *zzs_newadd();

+char *zzs_strdup();

+#endif

diff --git a/edk2/Tools/Source/TianoTools/PeCoffLoader/BasePeCoff.c b/edk2/Tools/Source/TianoTools/PeCoffLoader/BasePeCoff.c
new file mode 100644
index 0000000..b41a3a0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeCoffLoader/BasePeCoff.c
@@ -0,0 +1,1062 @@
+/*++

+

+Copyright (c) 2004 - 2005, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  PeCoffLoader.c

+

+Abstract:

+

+  Tiano PE/COFF loader 

+

+Revision History

+

+--*/

+

+

+#define EFI_SPECIFICATION_VERSION    0x00000000

+#define EDK_RELEASE_VERSION          0x00020000

+#include <Base.h>

+#include <Library/PeCoffLib.h>

+#include <Library/BaseMemoryLib.h>

+

+STATIC

+RETURN_STATUS

+PeCoffLoaderGetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  OUT    EFI_IMAGE_NT_HEADERS          *PeHdr,

+  OUT    EFI_TE_IMAGE_HEADER           *TeHdr

+  );

+

+STATIC

+RETURN_STATUS

+PeCoffLoaderCheckImageType (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  IN     EFI_IMAGE_NT_HEADERS          *PeHdr,

+  IN     EFI_TE_IMAGE_HEADER           *TeHdr

+  );

+

+STATIC

+VOID                            *

+PeCoffLoaderImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  IN     UINTN                         Address

+  );

+

+

+STATIC

+RETURN_STATUS

+PeCoffLoaderGetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,

+  OUT    EFI_IMAGE_NT_HEADERS          *PeHdr,

+  OUT    EFI_TE_IMAGE_HEADER           *TeHdr

+  )

+/*++

+

+Routine Description:

+

+  Retrieves the PE or TE Header from a PE/COFF or TE image

+

+Arguments:

+

+  ImageContext  - The context of the image being loaded

+

+  PeHdr         - The buffer in which to return the PE header

+  

+  TeHdr         - The buffer in which to return the TE header

+

+Returns:

+

+  RETURN_SUCCESS if the PE or TE Header is read, 

+  Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.

+

+--*/

+{

+  RETURN_STATUS            Status;

+  EFI_IMAGE_DOS_HEADER  DosHdr;

+  UINTN                 Size;

+

+  ImageContext->IsTeImage = FALSE;

+  //

+  // Read the DOS image headers

+  //

+  Size = sizeof (EFI_IMAGE_DOS_HEADER);

+  Status = ImageContext->ImageRead (

+                          ImageContext->Handle,

+                          0,

+                          &Size,

+                          &DosHdr

+                          );

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return Status;

+  }

+

+  ImageContext->PeCoffHeaderOffset = 0;

+  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header

+    //

+    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;

+  }

+  //

+  // Read the PE/COFF Header

+  //

+  Size = sizeof (EFI_IMAGE_NT_HEADERS);

+  Status = ImageContext->ImageRead (

+                          ImageContext->Handle,

+                          ImageContext->PeCoffHeaderOffset,

+                          &Size,

+                          PeHdr

+                          );

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return Status;

+  }

+  //

+  // Check the PE/COFF Header Signature. If not, then try to read a TE header

+  //

+  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {

+    Size = sizeof (EFI_TE_IMAGE_HEADER);

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &Size,

+                            TeHdr

+                            );

+    if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {

+      return RETURN_UNSUPPORTED;

+    }

+

+    ImageContext->IsTeImage = TRUE;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+STATIC

+RETURN_STATUS

+PeCoffLoaderCheckImageType (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN     EFI_IMAGE_NT_HEADERS                  *PeHdr,

+  IN     EFI_TE_IMAGE_HEADER                   *TeHdr

+  )

+/*++

+

+Routine Description:

+

+  Checks the PE or TE header of a PE/COFF or TE image to determine if it supported

+

+Arguments:

+

+  ImageContext  - The context of the image being loaded

+

+  PeHdr         - The buffer in which to return the PE header

+  

+  TeHdr         - The buffer in which to return the TE header

+

+Returns:

+

+  RETURN_SUCCESS if the PE/COFF or TE image is supported

+  RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported.

+

+--*/

+{

+  //

+  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)

+  // and the machine type for the Virtual Machine.

+  //

+  if (ImageContext->IsTeImage == FALSE) {

+    ImageContext->Machine = PeHdr->FileHeader.Machine;

+  } else {

+    ImageContext->Machine = TeHdr->Machine;

+  }

+

+  if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;

+    return RETURN_UNSUPPORTED;

+  }

+

+  //

+  // See if the image type is supported.  We support EFI Applications,

+  // EFI Boot Service Drivers, and EFI Runtime Drivers.

+  //

+  if (ImageContext->IsTeImage == FALSE) {

+    ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;

+  } else {

+    ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);

+  }

+

+

+  return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetImageInfo (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT           *ImageContext

+  )

+/*++

+

+Routine Description:

+

+  Retrieves information on a PE/COFF image

+

+Arguments:

+

+  This         - Calling context

+  ImageContext - The context of the image being loaded

+

+Returns:

+

+  RETURN_SUCCESS           - The information on the PE/COFF image was collected.

+  RETURN_INVALID_PARAMETER - ImageContext is NULL.

+  RETURN_UNSUPPORTED       - The PE/COFF image is not supported.

+  Otherwise             - The error status from reading the PE/COFF image using the

+                          ImageContext->ImageRead() function

+

+--*/

+{

+  RETURN_STATUS                      Status;

+  EFI_IMAGE_NT_HEADERS            PeHdr;

+  EFI_TE_IMAGE_HEADER             TeHdr;

+  EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;

+  UINTN                           Size;

+  UINTN                           Index;

+  UINTN                           DebugDirectoryEntryRva;

+  UINTN                           DebugDirectoryEntryFileOffset;

+  UINTN                           SectionHeaderOffset;

+  EFI_IMAGE_SECTION_HEADER        SectionHeader;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;

+

+  if (NULL == ImageContext) {

+    return RETURN_INVALID_PARAMETER;

+  }

+  //

+  // Assume success

+  //

+  ImageContext->ImageError  = IMAGE_ERROR_SUCCESS;

+

+  Status                    = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Verify machine type

+  //

+  Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+  //

+  // Retrieve the base address of the image

+  //

+  if (!(ImageContext->IsTeImage)) {

+    ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;

+  } else {

+    ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase);

+  }

+  //

+  // Initialize the alternate destination address to 0 indicating that it

+  // should not be used.

+  //

+  ImageContext->DestinationAddress = 0;

+

+  //

+  // Initialize the codeview pointer.

+  //

+  ImageContext->CodeView    = NULL;

+  ImageContext->PdbPointer  = NULL;

+

+  //

+  // Three cases with regards to relocations:

+  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but

+  //   has no base relocs to apply

+  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.

+  //

+  // Look at the file header to determine if relocations have been stripped, and

+  // save this info in the image context for later use.

+  //

+  if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {

+    ImageContext->RelocationsStripped = TRUE;

+  } else {

+    ImageContext->RelocationsStripped = FALSE;

+  }

+

+  if (!(ImageContext->IsTeImage)) {

+    ImageContext->ImageSize         = (UINT64) PeHdr.OptionalHeader.SizeOfImage;

+    ImageContext->SectionAlignment  = PeHdr.OptionalHeader.SectionAlignment;

+    ImageContext->SizeOfHeaders     = PeHdr.OptionalHeader.SizeOfHeaders;

+

+    //

+    // Modify ImageSize to contain .PDB file name if required and initialize

+    // PdbRVA field...

+    //

+    if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+      DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+

+      DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;

+

+      //

+      // Determine the file offset of the debug directory...  This means we walk

+      // the sections to find which section contains the RVA of the debug

+      // directory

+      //

+      DebugDirectoryEntryFileOffset = 0;

+

+      SectionHeaderOffset = (UINTN)(

+                               ImageContext->PeCoffHeaderOffset +

+                               sizeof (UINT32) + 

+                               sizeof (EFI_IMAGE_FILE_HEADER) + 

+                               PeHdr.FileHeader.SizeOfOptionalHeader

+                               );

+

+      for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) {

+        //

+        // Read section header from file

+        //

+        Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle,

+                                 SectionHeaderOffset,

+                                 &Size,

+                                 &SectionHeader

+                                 );

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return Status;

+        }

+

+        if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+            DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+            DebugDirectoryEntryFileOffset =

+            DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;

+          break;

+        }

+

+        SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+      }

+

+      if (DebugDirectoryEntryFileOffset != 0) {

+        for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {

+          //

+          // Read next debug directory entry

+          //

+          Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+          Status = ImageContext->ImageRead (

+                                   ImageContext->Handle,

+                                   DebugDirectoryEntryFileOffset,

+                                   &Size,

+                                   &DebugEntry

+                                   );

+          if (RETURN_ERROR (Status)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            return Status;

+          }

+

+          if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+            ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));

+            if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {

+              ImageContext->ImageSize += DebugEntry.SizeOfData;

+            }

+

+            return RETURN_SUCCESS;

+          }

+        }

+      }

+    }

+  } else {

+    ImageContext->ImageSize         = 0;

+    ImageContext->SectionAlignment  = 4096;

+    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize;

+

+    DebugDirectoryEntry             = &TeHdr.DataDirectory[1];

+    DebugDirectoryEntryRva          = DebugDirectoryEntry->VirtualAddress;

+    SectionHeaderOffset             = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));

+

+    DebugDirectoryEntryFileOffset   = 0;

+

+    for (Index = 0; Index < TeHdr.NumberOfSections;) {

+      //

+      // Read section header from file

+      //

+      Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle,

+                               SectionHeaderOffset,

+                               &Size,

+                               &SectionHeader

+                               );

+      if (RETURN_ERROR (Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+

+      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -

+          SectionHeader.VirtualAddress +

+          SectionHeader.PointerToRawData +

+          sizeof (EFI_TE_IMAGE_HEADER) -

+          TeHdr.StrippedSize;

+

+        //

+        // File offset of the debug directory was found, if this is not the last

+        // section, then skip to the last section for calculating the image size.

+        //

+        if (Index < (UINTN) TeHdr.NumberOfSections - 1) {

+          SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);

+          Index = TeHdr.NumberOfSections - 1;

+          continue;

+        }

+      }

+

+      //

+      // In Te image header there is not a field to describe the ImageSize.

+      // Actually, the ImageSize equals the RVA plus the VirtualSize of 

+      // the last section mapped into memory (Must be rounded up to 

+      // a mulitple of Section Alignment). Per the PE/COFF specification, the

+      // section headers in the Section Table must appear in order of the RVA

+      // values for the corresponding sections. So the ImageSize can be determined

+      // by the RVA and the VirtualSize of the last section header in the

+      // Section Table.

+      //

+      if ((++Index) == (UINTN) TeHdr.NumberOfSections) {

+        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +

+                                   ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);

+      }

+

+      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+    }

+

+    if (DebugDirectoryEntryFileOffset != 0) {

+      for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {

+        //

+        // Read next debug directory entry

+        //

+        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle,

+                                 DebugDirectoryEntryFileOffset,

+                                 &Size,

+                                 &DebugEntry

+                                 );

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return Status;

+        }

+

+        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));

+          return RETURN_SUCCESS;

+        }

+      }

+    }

+  }

+

+  return RETURN_SUCCESS;

+}

+

+STATIC

+VOID *

+PeCoffLoaderImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN     UINTN                                 Address

+  )

+/*++

+

+Routine Description:

+

+  Converts an image address to the loaded address

+

+Arguments:

+

+  ImageContext  - The context of the image being loaded

+

+  Address       - The address to be converted to the loaded address

+

+Returns:

+

+  NULL if the address can not be converted, otherwise, the converted address

+

+--*/

+{

+  if (Address >= ImageContext->ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+    return NULL;

+  }

+

+  return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address);

+}

+

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderRelocateImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+/*++

+

+Routine Description:

+

+  Relocates a PE/COFF image in memory

+

+Arguments:

+

+  This         - Calling context

+

+  ImageContext - Contains information on the loaded image to relocate

+

+Returns:

+

+  RETURN_SUCCESS      if the PE/COFF image was relocated

+  RETURN_LOAD_ERROR   if the image is not a valid PE/COFF image

+  RETURN_UNSUPPORTED  not support

+

+--*/

+{

+  RETURN_STATUS                Status;

+  EFI_IMAGE_NT_HEADERS      *PeHdr;

+  EFI_TE_IMAGE_HEADER       *TeHdr;

+  EFI_IMAGE_DATA_DIRECTORY  *RelocDir;

+  UINT64                    Adjust;

+  EFI_IMAGE_BASE_RELOCATION *RelocBase;

+  EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;

+  UINT16                    *Reloc;

+  UINT16                    *RelocEnd;

+  CHAR8                     *Fixup;

+  CHAR8                     *FixupBase;

+  UINT16                    *F16;

+  UINT32                    *F32;

+  CHAR8                     *FixupData;

+  PHYSICAL_ADDRESS      BaseAddress;

+

+  PeHdr = NULL;

+  TeHdr = NULL;

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // If there are no relocation entries, then we are done

+  //

+  if (ImageContext->RelocationsStripped) {

+    return RETURN_SUCCESS;

+  }

+

+  //

+  // If the destination address is not 0, use that rather than the

+  // image address as the relocation target.

+  //

+  if (ImageContext->DestinationAddress) {

+    BaseAddress = ImageContext->DestinationAddress;

+  } else {

+    BaseAddress = ImageContext->ImageAddress;

+  }

+

+  if (!(ImageContext->IsTeImage)) {

+    PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + 

+                                            ImageContext->PeCoffHeaderOffset);

+    Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;

+    PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;

+

+    //

+    // Find the relocation block

+    //

+    // Per the PE/COFF spec, you can't assume that a given data directory

+    // is present in the image. You have to check the NumberOfRvaAndSizes in

+    // the optional header to verify a desired directory entry is there.

+    //

+    if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      RelocDir  = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+      RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);

+      RelocBaseEnd = PeCoffLoaderImageAddress (

+                      ImageContext,

+                      RelocDir->VirtualAddress + RelocDir->Size - 1

+                      );

+    } else {

+      //

+      // Set base and end to bypass processing below.

+      //

+      RelocBase = RelocBaseEnd = 0;

+    }

+  } else {

+    TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);

+    Adjust            = (UINT64) (BaseAddress - TeHdr->ImageBase);

+    TeHdr->ImageBase  = (UINT64) (BaseAddress);

+

+    //

+    // Find the relocation block

+    //

+    RelocDir = &TeHdr->DataDirectory[0];

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(

+		                                ImageContext->ImageAddress + 

+		                                RelocDir->VirtualAddress +

+		                                sizeof(EFI_TE_IMAGE_HEADER) - 

+		                                TeHdr->StrippedSize

+		                                );

+    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);

+  }

+  

+  //

+  // Run the relocation information and apply the fixups

+  //

+  FixupData = ImageContext->FixupData;

+  while (RelocBase < RelocBaseEnd) {

+

+    Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));

+    RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);

+    if (!(ImageContext->IsTeImage)) {

+      FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);

+    } else {

+      FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +

+	  	              RelocBase->VirtualAddress +

+	  	              sizeof(EFI_TE_IMAGE_HEADER) - 

+	  	              TeHdr->StrippedSize

+	  	              );

+    }

+

+    if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||

+        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + 

+          (UINTN)ImageContext->ImageSize)) {

+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+      return RETURN_LOAD_ERROR;

+    }

+

+    //

+    // Run this relocation record

+    //

+    while (Reloc < RelocEnd) {

+

+      Fixup = FixupBase + (*Reloc & 0xFFF);

+      switch ((*Reloc) >> 12) {

+      case EFI_IMAGE_REL_BASED_ABSOLUTE:

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGH:

+        F16   = (UINT16 *) Fixup;

+        *F16  = (UINT16) ((*F16 << 16) + (UINT16) Adjust);

+        if (FixupData != NULL) {

+          *(UINT16 *) FixupData = *F16;

+          FixupData             = FixupData + sizeof (UINT16);

+        }

+        break;

+

+      case EFI_IMAGE_REL_BASED_LOW:

+        F16   = (UINT16 *) Fixup;

+        *F16  = (UINT16) (*F16 + (UINT16) Adjust);

+        if (FixupData != NULL) {

+          *(UINT16 *) FixupData = *F16;

+          FixupData             = FixupData + sizeof (UINT16);

+        }

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHLOW:

+        F32   = (UINT32 *) Fixup;

+        *F32  = *F32 + (UINT32) Adjust;

+        if (FixupData != NULL) {

+          FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT32));

+          *(UINT32 *) FixupData = *F32;

+          FixupData             = FixupData + sizeof (UINT32);

+        }

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHADJ:

+        //

+        // Return the same EFI_UNSUPPORTED return code as

+        // PeCoffLoaderRelocateImageEx() returns if it does not recognize

+        // the relocation type.

+        //

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_UNSUPPORTED;

+

+      default:

+        Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+          return Status;

+        }

+      }

+

+      //

+      // Next relocation record

+      //

+      Reloc += 1;

+    }

+

+    //

+    // Next reloc block

+    //

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderLoadImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+/*++

+

+Routine Description:

+

+  Loads a PE/COFF image into memory

+

+Arguments:

+

+  This         - Calling context

+

+  ImageContext - Contains information on image to load into memory

+

+Returns:

+

+  RETURN_SUCCESS            if the PE/COFF image was loaded

+  RETURN_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer

+  RETURN_LOAD_ERROR         if the image is a runtime driver with no relocations

+  RETURN_INVALID_PARAMETER  if the image address is invalid

+

+--*/

+{

+  RETURN_STATUS                            Status;

+  EFI_IMAGE_NT_HEADERS                  *PeHdr;

+  EFI_TE_IMAGE_HEADER                   *TeHdr;

+  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;

+  EFI_IMAGE_SECTION_HEADER              *FirstSection;

+  EFI_IMAGE_SECTION_HEADER              *Section;

+  UINTN                                 NumberOfSections;

+  UINTN                                 Index;

+  CHAR8                                 *Base;

+  CHAR8                                 *End;

+  CHAR8                                 *MaxEnd;

+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;

+  UINTN                                 Size;

+  UINT32                                TempDebugEntryRva;

+

+  PeHdr = NULL;

+  TeHdr = NULL;

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // Copy the provided context info into our local version, get what we

+  // can from the original image, and then use that to make sure everything

+  // is legit.

+  //

+  CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));

+

+  Status = PeCoffLoaderGetImageInfo (&CheckContext);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure there is enough allocated space for the image being loaded

+  //

+  if (ImageContext->ImageSize < CheckContext.ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;

+    return RETURN_BUFFER_TOO_SMALL;

+  }

+

+  //

+  // If there's no relocations, then make sure it's not a runtime driver,

+  // and that it's being loaded at the linked address.

+  //

+  if (CheckContext.RelocationsStripped) {

+    //

+    // If the image does not contain relocations and it is a runtime driver

+    // then return an error.

+    //

+    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+      return RETURN_LOAD_ERROR;

+    }

+    //

+    // If the image does not contain relocations, and the requested load address

+    // is not the linked address, then return an error.

+    //

+    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+      return RETURN_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Make sure the allocated space has the proper section alignment

+  //

+  if (!(ImageContext->IsTeImage)) {

+    if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;

+      return RETURN_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Read the entire PE/COFF or TE header into memory

+  //

+  if (!(ImageContext->IsTeImage)) {

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &ImageContext->SizeOfHeaders,

+                            (VOID *) (UINTN) ImageContext->ImageAddress

+                            );

+

+    PeHdr = (EFI_IMAGE_NT_HEADERS *)

+      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);

+

+    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+                      (UINTN)ImageContext->ImageAddress +

+                      ImageContext->PeCoffHeaderOffset +

+                      sizeof(UINT32) + 

+                      sizeof(EFI_IMAGE_FILE_HEADER) + 

+                      PeHdr->FileHeader.SizeOfOptionalHeader

+      );

+    NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections);

+  } else {

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &ImageContext->SizeOfHeaders,

+                            (void *) (UINTN) ImageContext->ImageAddress

+                            );

+

+    TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);

+

+    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+		      (UINTN)ImageContext->ImageAddress +

+		      sizeof(EFI_TE_IMAGE_HEADER)

+		      );

+    NumberOfSections  = (UINTN) (TeHdr->NumberOfSections);

+

+  }

+

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return RETURN_LOAD_ERROR;

+  }

+

+  //

+  // Load each section of the image

+  //

+  Section = FirstSection;

+  for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {

+

+    //

+    // Compute sections address

+    //

+    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);

+    End = PeCoffLoaderImageAddress (

+            ImageContext,

+            Section->VirtualAddress + Section->Misc.VirtualSize - 1

+            );

+    if (ImageContext->IsTeImage) {

+      Base  = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);

+      End   = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);

+    }

+

+    if (End > MaxEnd) {

+      MaxEnd = End;

+    }

+    //

+    // If the base start or end address resolved to 0, then fail.

+    //

+    if ((Base == NULL) || (End == NULL)) {

+      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;

+      return RETURN_LOAD_ERROR;

+    }

+

+    //

+    // Read the section

+    //

+    Size = (UINTN) Section->Misc.VirtualSize;

+    if ((Size == 0) || (Size > Section->SizeOfRawData)) {

+      Size = (UINTN) Section->SizeOfRawData;

+    }

+

+    if (Section->SizeOfRawData) {

+      if (!(ImageContext->IsTeImage)) {

+        Status = ImageContext->ImageRead (

+                                ImageContext->Handle,

+                                Section->PointerToRawData,

+                                &Size,

+                                Base

+                                );

+      } else {

+        Status = ImageContext->ImageRead (

+                                ImageContext->Handle,

+                                Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,

+                                &Size,

+                                Base

+                                );

+      }

+

+      if (RETURN_ERROR (Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+    }

+

+    //

+    // If raw size is less then virt size, zero fill the remaining

+    //

+

+    if (Size < Section->Misc.VirtualSize) {

+      ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);

+    }

+

+    //

+    // Next Section

+    //

+    Section += 1;

+  }

+

+  //

+  // Get image's entry point

+  //

+  if (!(ImageContext->IsTeImage)) {

+    ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (

+                                                                ImageContext,

+                                                                PeHdr->OptionalHeader.AddressOfEntryPoint

+                                                                );

+  } else {

+    ImageContext->EntryPoint =  (PHYSICAL_ADDRESS) (

+		                   (UINTN)ImageContext->ImageAddress +

+		                   (UINTN)TeHdr->AddressOfEntryPoint +

+		                   (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -

+          (UINTN) TeHdr->StrippedSize

+      );

+  }

+

+  //

+  // Determine the size of the fixup data

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory

+  // is present in the image. You have to check the NumberOfRvaAndSizes in

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (!(ImageContext->IsTeImage)) {

+    if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)

+        &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);

+    } else {

+      ImageContext->FixupDataSize = 0;

+    }

+  } else {

+    DirectoryEntry              = &TeHdr->DataDirectory[0];

+    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);

+  }

+  //

+  // Consumer must allocate a buffer for the relocation fixup log.

+  // Only used for runtime drivers.

+  //

+  ImageContext->FixupData = NULL;

+

+  //

+  // Load the Codeview info if present

+  //

+  if (ImageContext->DebugDirectoryEntryRva != 0) {

+    if (!(ImageContext->IsTeImage)) {

+      DebugEntry = PeCoffLoaderImageAddress (

+                    ImageContext,

+                    ImageContext->DebugDirectoryEntryRva

+                    );

+    } else {

+      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(

+	  	                                         ImageContext->ImageAddress +

+	  	                                         ImageContext->DebugDirectoryEntryRva +

+	  	                                         sizeof(EFI_TE_IMAGE_HEADER) -

+	  	                                         TeHdr->StrippedSize

+	  	                                         );

+    }

+

+    if (DebugEntry != NULL) {

+      TempDebugEntryRva = DebugEntry->RVA;

+      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {

+        Section--;

+        if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {

+          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;

+        } else {

+          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;

+        }

+      }

+

+      if (TempDebugEntryRva != 0) {

+        if (!(ImageContext->IsTeImage)) {

+          ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);

+        } else {

+          ImageContext->CodeView = (VOID *)(

+		  	              (UINTN)ImageContext->ImageAddress +

+		  	              (UINTN)TempDebugEntryRva +

+		  	              (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -

+                (UINTN) TeHdr->StrippedSize

+            );

+        }

+

+        if (ImageContext->CodeView == NULL) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return RETURN_LOAD_ERROR;

+        }

+

+        if (DebugEntry->RVA == 0) {

+          Size = DebugEntry->SizeOfData;

+          if (!(ImageContext->IsTeImage)) {

+            Status = ImageContext->ImageRead (

+                                    ImageContext->Handle,

+                                    DebugEntry->FileOffset,

+                                    &Size,

+                                    ImageContext->CodeView

+                                    );

+          } else {

+            Status = ImageContext->ImageRead (

+                                    ImageContext->Handle,

+                                    DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,

+                                    &Size,

+                                    ImageContext->CodeView

+                                    );

+            //

+            // Should we apply fix up to this field according to the size difference between PE and TE?

+            // Because now we maintain TE header fields unfixed, this field will also remain as they are

+            // in original PE image.

+            //

+          }

+

+          if (RETURN_ERROR (Status)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            return RETURN_LOAD_ERROR;

+          }

+

+          DebugEntry->RVA = TempDebugEntryRva;

+        }

+

+        switch (*(UINT32 *) ImageContext->CodeView) {

+        case CODEVIEW_SIGNATURE_NB10:

+          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);

+          break;

+

+        case CODEVIEW_SIGNATURE_RSDS:

+          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);

+          break;

+

+        default:

+          break;

+        }

+      }

+    }

+  }

+

+  return Status;

+}

diff --git a/edk2/Tools/Source/TianoTools/PeCoffLoader/Common/EfiImage.h b/edk2/Tools/Source/TianoTools/PeCoffLoader/Common/EfiImage.h
new file mode 100644
index 0000000..0ad71d3
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeCoffLoader/Common/EfiImage.h
@@ -0,0 +1,701 @@
+/** @file

+	EFI image format for PE32+. Please note some data structures are different

+	for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64

+

+	@bug Fix text - doc as defined in MSFT EFI specification.

+

+	Copyright (c) 2006, Intel Corporation                                                         

+	All rights reserved. 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.             

+

+	Module Name:	EfiImage.h

+

+**/

+

+#ifndef __EFI_IMAGE_H__

+#define __EFI_IMAGE_H__

+

+//

+// PE32+ Subsystem type for EFI images

+//

+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION         10

+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11

+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      12

+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER      13

+

+//

+// BugBug: Need to get a real answer for this problem. This is not in the

+//         PE specification.

+//

+//         A SAL runtime driver does not get fixed up when a transition to

+//         virtual mode is made. In all other cases it should be treated

+//         like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image

+//

+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER  13

+

+//

+// PE32+ Machine type for EFI images

+//

+#define IMAGE_FILE_MACHINE_I386     0x014c

+#define IMAGE_FILE_MACHINE_IA64     0x0200

+#define IMAGE_FILE_MACHINE_EBC      0x0EBC

+#define IMAGE_FILE_MACHINE_X64      0x8664

+//

+// Support old names for backward compatible

+//

+#define EFI_IMAGE_MACHINE_IA32      IMAGE_FILE_MACHINE_I386 

+#define EFI_IMAGE_MACHINE_IA64      IMAGE_FILE_MACHINE_IA64  

+#define EFI_IMAGE_MACHINE_IPF       IMAGE_FILE_MACHINE_IA64  

+#define EFI_IMAGE_MACHINE_EBC       IMAGE_FILE_MACHINE_EBC  

+#define EFI_IMAGE_MACHINE_X64       IMAGE_FILE_MACHINE_X64

+

+#define EFI_IMAGE_DOS_SIGNATURE     0x5A4D      // MZ

+#define EFI_IMAGE_OS2_SIGNATURE     0x454E      // NE

+#define EFI_IMAGE_OS2_SIGNATURE_LE  0x454C      // LE

+#define EFI_IMAGE_NT_SIGNATURE      0x00004550  // PE00

+#define EFI_IMAGE_EDOS_SIGNATURE    0x44454550  // PEED

+

+///

+/// PE images can start with an optional DOS header, so if an image is run

+///  under DOS it can print an error message.

+///

+typedef struct {

+  UINT16  e_magic;    // Magic number

+  UINT16  e_cblp;     // Bytes on last page of file

+  UINT16  e_cp;       // Pages in file

+  UINT16  e_crlc;     // Relocations

+  UINT16  e_cparhdr;  // Size of header in paragraphs

+  UINT16  e_minalloc; // Minimum extra paragraphs needed

+  UINT16  e_maxalloc; // Maximum extra paragraphs needed

+  UINT16  e_ss;       // Initial (relative) SS value

+  UINT16  e_sp;       // Initial SP value

+  UINT16  e_csum;     // Checksum

+  UINT16  e_ip;       // Initial IP value

+  UINT16  e_cs;       // Initial (relative) CS value

+  UINT16  e_lfarlc;   // File address of relocation table

+  UINT16  e_ovno;     // Overlay number

+  UINT16  e_res[4];   // Reserved words

+  UINT16  e_oemid;    // OEM identifier (for e_oeminfo)

+  UINT16  e_oeminfo;  // OEM information; e_oemid specific

+  UINT16  e_res2[10]; // Reserved words

+  UINT32  e_lfanew;   // File address of new exe header

+} EFI_IMAGE_DOS_HEADER;

+

+///

+/// File header format.

+///

+typedef struct {

+  UINT16  Machine;

+  UINT16  NumberOfSections;

+  UINT32  TimeDateStamp;

+  UINT32  PointerToSymbolTable;

+  UINT32  NumberOfSymbols;

+  UINT16  SizeOfOptionalHeader;

+  UINT16  Characteristics;

+} EFI_IMAGE_FILE_HEADER;

+

+#define EFI_IMAGE_SIZEOF_FILE_HEADER        20

+

+#define EFI_IMAGE_FILE_RELOCS_STRIPPED      0x0001  // Relocation info stripped from file.

+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE     0x0002  // File is executable  (i.e. no unresolved externel references).

+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED   0x0004  // Line nunbers stripped from file.

+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED  0x0008  // Local symbols stripped from file.

+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO    0x0080  // Bytes of machine word are reversed.

+#define EFI_IMAGE_FILE_32BIT_MACHINE        0x0100  // 32 bit word machine.

+#define EFI_IMAGE_FILE_DEBUG_STRIPPED       0x0200  // Debugging info stripped from file in .DBG file

+#define EFI_IMAGE_FILE_SYSTEM               0x1000  // System File.

+#define EFI_IMAGE_FILE_DLL                  0x2000  // File is a DLL.

+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI    0x8000  // Bytes of machine word are reversed.

+#define EFI_IMAGE_FILE_MACHINE_UNKNOWN      0

+#define EFI_IMAGE_FILE_MACHINE_I386         0x14c   // Intel 386.

+#define EFI_IMAGE_FILE_MACHINE_R3000        0x162   // MIPS* little-endian, 0540 big-endian

+#define EFI_IMAGE_FILE_MACHINE_R4000        0x166   // MIPS* little-endian

+#define EFI_IMAGE_FILE_MACHINE_ALPHA        0x184   // Alpha_AXP*

+#define EFI_IMAGE_FILE_MACHINE_POWERPC      0x1F0   // IBM* PowerPC Little-Endian

+#define EFI_IMAGE_FILE_MACHINE_TAHOE        0x7cc   // Intel EM machine

+//

+// * Other names and brands may be claimed as the property of others.

+//

+

+///

+/// Directory format.

+///

+typedef struct {

+  UINT32  VirtualAddress;

+  UINT32  Size;

+} EFI_IMAGE_DATA_DIRECTORY;

+

+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16

+

+typedef struct {

+  UINT16  Magic;

+  UINT8   MajorLinkerVersion;

+  UINT8   MinorLinkerVersion;

+  UINT32  SizeOfCode;

+  UINT32  SizeOfInitializedData;

+  UINT32  SizeOfUninitializedData;

+  UINT32  AddressOfEntryPoint;

+  UINT32  BaseOfCode;

+  UINT32  BaseOfData;

+  UINT32  BaseOfBss;

+  UINT32  GprMask;

+  UINT32  CprMask[4];

+  UINT32  GpValue;

+} EFI_IMAGE_ROM_OPTIONAL_HEADER;

+

+#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC      0x107

+#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER  sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)

+

+typedef struct {

+  EFI_IMAGE_FILE_HEADER         FileHeader;

+  EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;

+} EFI_IMAGE_ROM_HEADERS;

+

+///

+/// @attention

+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64

+/// are for use ONLY by tools.  All proper EFI code MUST use

+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!

+///

+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b

+

+typedef struct {

+  //

+  // Standard fields.

+  //

+  UINT16                    Magic;

+  UINT8                     MajorLinkerVersion;

+  UINT8                     MinorLinkerVersion;

+  UINT32                    SizeOfCode;

+  UINT32                    SizeOfInitializedData;

+  UINT32                    SizeOfUninitializedData;

+  UINT32                    AddressOfEntryPoint;

+  UINT32                    BaseOfCode;

+  UINT32                    BaseOfData;

+  //

+  // NT additional fields.

+  //

+  UINT32                    ImageBase;

+  UINT32                    SectionAlignment;

+  UINT32                    FileAlignment;

+  UINT16                    MajorOperatingSystemVersion;

+  UINT16                    MinorOperatingSystemVersion;

+  UINT16                    MajorImageVersion;

+  UINT16                    MinorImageVersion;

+  UINT16                    MajorSubsystemVersion;

+  UINT16                    MinorSubsystemVersion;

+  UINT32                    Win32VersionValue;

+  UINT32                    SizeOfImage;

+  UINT32                    SizeOfHeaders;

+  UINT32                    CheckSum;

+  UINT16                    Subsystem;

+  UINT16                    DllCharacteristics;

+  UINT32                    SizeOfStackReserve;

+  UINT32                    SizeOfStackCommit;

+  UINT32                    SizeOfHeapReserve;

+  UINT32                    SizeOfHeapCommit;

+  UINT32                    LoaderFlags;

+  UINT32                    NumberOfRvaAndSizes;

+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];

+} EFI_IMAGE_OPTIONAL_HEADER32;

+

+///

+/// @attention

+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64

+/// are for use ONLY by tools.  All proper EFI code MUST use

+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!

+///

+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b

+

+typedef struct {

+  //

+  // Standard fields.

+  //

+  UINT16                    Magic;

+  UINT8                     MajorLinkerVersion;

+  UINT8                     MinorLinkerVersion;

+  UINT32                    SizeOfCode;

+  UINT32                    SizeOfInitializedData;

+  UINT32                    SizeOfUninitializedData;

+  UINT32                    AddressOfEntryPoint;

+  UINT32                    BaseOfCode;

+  //

+  // NT additional fields.

+  //

+  UINT64                    ImageBase;

+  UINT32                    SectionAlignment;

+  UINT32                    FileAlignment;

+  UINT16                    MajorOperatingSystemVersion;

+  UINT16                    MinorOperatingSystemVersion;

+  UINT16                    MajorImageVersion;

+  UINT16                    MinorImageVersion;

+  UINT16                    MajorSubsystemVersion;

+  UINT16                    MinorSubsystemVersion;

+  UINT32                    Win32VersionValue;

+  UINT32                    SizeOfImage;

+  UINT32                    SizeOfHeaders;

+  UINT32                    CheckSum;

+  UINT16                    Subsystem;

+  UINT16                    DllCharacteristics;

+  UINT64                    SizeOfStackReserve;

+  UINT64                    SizeOfStackCommit;

+  UINT64                    SizeOfHeapReserve;

+  UINT64                    SizeOfHeapCommit;

+  UINT32                    LoaderFlags;

+  UINT32                    NumberOfRvaAndSizes;

+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];

+} EFI_IMAGE_OPTIONAL_HEADER64;

+

+///

+/// @attention

+/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY

+/// by tools.  All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!

+///

+typedef struct {

+  UINT32                      Signature;

+  EFI_IMAGE_FILE_HEADER       FileHeader;

+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;

+} EFI_IMAGE_NT_HEADERS32;

+

+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)

+

+typedef struct {

+  UINT32                      Signature;

+  EFI_IMAGE_FILE_HEADER       FileHeader;

+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;

+} EFI_IMAGE_NT_HEADERS64;

+

+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)

+

+//

+// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the

+// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build.  Same for

+// EFI_IMAGE_NT_HEADERS.  These definitions MUST be used by ALL EFI code.

+//

+#if   defined (MDE_CPU_IA32) && !defined (BUILDING_TOOLS) || \

+      defined (BUILDING_TOOLS) && defined (TOOL_BUILD_IA32_TARGET)

+

+// typedef EFI_IMAGE_OPTIONAL_HEADER32     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS32          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \

+  (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))

+

+#elif defined (MDE_CPU_IPF) && !defined (BUILDING_TOOLS) || \

+      defined (BUILDING_TOOLS) && defined (TOOL_BUILD_IPF_TARGET)

+

+typedef EFI_IMAGE_OPTIONAL_HEADER64     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS64          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \

+  (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC))

+

+#elif defined (MDE_CPU_X64) && !defined (BUILDING_TOOLS) || \

+      defined (BUILDING_TOOLS) && defined (TOOL_BUILD_X64_TARGET)

+

+typedef EFI_IMAGE_OPTIONAL_HEADER64     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS64          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \

+  (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))

+

+#elif defined (MDE_CPU_EBC)

+

+//

+// This is just to make sure you can cross compile with the EBC compiiler.

+// It does not make sense to have a PE loader coded in EBC. You need to 

+// understand the basic 

+//

+typedef EFI_IMAGE_OPTIONAL_HEADER64     EFI_IMAGE_OPTIONAL_HEADER;

+typedef EFI_IMAGE_NT_HEADERS64          EFI_IMAGE_NT_HEADERS;

+

+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)

+

+#else

+#error Unknown Processor Type

+#endif

+

+

+#define EFI_IMAGE_FIRST_SECTION(ntheader) \

+    ( \

+      (EFI_IMAGE_SECTION_HEADER *) \

+        ( \

+          (UINT32) ntheader + \

+          FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \

+          ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \

+        ) \

+    )

+

+//

+// Subsystem Values

+//

+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN     0

+#define EFI_IMAGE_SUBSYSTEM_NATIVE      1

+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2

+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.

+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI     5

+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI   7

+

+//

+// Directory Entries

+//

+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT      0

+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT      1

+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE    2

+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION   3

+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY    4

+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC   5

+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG       6

+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT   7

+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR   8

+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS         9

+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10

+

+//

+// Section header format.

+//

+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8

+

+typedef struct {

+  UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];

+  union {

+    UINT32  PhysicalAddress;

+    UINT32  VirtualSize;

+  } Misc;

+  UINT32  VirtualAddress;

+  UINT32  SizeOfRawData;

+  UINT32  PointerToRawData;

+  UINT32  PointerToRelocations;

+  UINT32  PointerToLinenumbers;

+  UINT16  NumberOfRelocations;

+  UINT16  NumberOfLinenumbers;

+  UINT32  Characteristics;

+} EFI_IMAGE_SECTION_HEADER;

+

+#define EFI_IMAGE_SIZEOF_SECTION_HEADER       40

+

+#define EFI_IMAGE_SCN_TYPE_NO_PAD             0x00000008  // Reserved.

+#define EFI_IMAGE_SCN_CNT_CODE                0x00000020

+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA    0x00000040

+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA  0x00000080

+

+#define EFI_IMAGE_SCN_LNK_OTHER               0x00000100  // Reserved.

+#define EFI_IMAGE_SCN_LNK_INFO                0x00000200  // Section contains comments or some other type of information.

+#define EFI_IMAGE_SCN_LNK_REMOVE              0x00000800  // Section contents will not become part of image.

+#define EFI_IMAGE_SCN_LNK_COMDAT              0x00001000

+

+#define EFI_IMAGE_SCN_ALIGN_1BYTES            0x00100000

+#define EFI_IMAGE_SCN_ALIGN_2BYTES            0x00200000

+#define EFI_IMAGE_SCN_ALIGN_4BYTES            0x00300000

+#define EFI_IMAGE_SCN_ALIGN_8BYTES            0x00400000

+#define EFI_IMAGE_SCN_ALIGN_16BYTES           0x00500000

+#define EFI_IMAGE_SCN_ALIGN_32BYTES           0x00600000

+#define EFI_IMAGE_SCN_ALIGN_64BYTES           0x00700000

+

+#define EFI_IMAGE_SCN_MEM_DISCARDABLE         0x02000000

+#define EFI_IMAGE_SCN_MEM_NOT_CACHED          0x04000000

+#define EFI_IMAGE_SCN_MEM_NOT_PAGED           0x08000000

+#define EFI_IMAGE_SCN_MEM_SHARED              0x10000000

+#define EFI_IMAGE_SCN_MEM_EXECUTE             0x20000000

+#define EFI_IMAGE_SCN_MEM_READ                0x40000000

+#define EFI_IMAGE_SCN_MEM_WRITE               0x80000000

+

+///

+/// Symbol format.

+///

+#define EFI_IMAGE_SIZEOF_SYMBOL 18

+

+//

+// Section values.

+//

+// Symbols have a section number of the section in which they are

+// defined. Otherwise, section numbers have the following meanings:

+//

+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0  // Symbol is undefined or is common.

+#define EFI_IMAGE_SYM_ABSOLUTE  (UINT16) -1 // Symbol is an absolute value.

+#define EFI_IMAGE_SYM_DEBUG     (UINT16) -2 // Symbol is a special debug item.

+//

+// Type (fundamental) values.

+//

+#define EFI_IMAGE_SYM_TYPE_NULL   0   // no type.

+#define EFI_IMAGE_SYM_TYPE_VOID   1   //

+#define EFI_IMAGE_SYM_TYPE_CHAR   2   // type character.

+#define EFI_IMAGE_SYM_TYPE_SHORT  3   // type short integer.

+#define EFI_IMAGE_SYM_TYPE_INT    4

+#define EFI_IMAGE_SYM_TYPE_LONG   5

+#define EFI_IMAGE_SYM_TYPE_FLOAT  6

+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7

+#define EFI_IMAGE_SYM_TYPE_STRUCT 8

+#define EFI_IMAGE_SYM_TYPE_UNION  9

+#define EFI_IMAGE_SYM_TYPE_ENUM   10  // enumeration.

+#define EFI_IMAGE_SYM_TYPE_MOE    11  // member of enumeration.

+#define EFI_IMAGE_SYM_TYPE_BYTE   12

+#define EFI_IMAGE_SYM_TYPE_WORD   13

+#define EFI_IMAGE_SYM_TYPE_UINT   14

+#define EFI_IMAGE_SYM_TYPE_DWORD  15

+

+//

+// Type (derived) values.

+//

+#define EFI_IMAGE_SYM_DTYPE_NULL      0 // no derived type.

+#define EFI_IMAGE_SYM_DTYPE_POINTER   1

+#define EFI_IMAGE_SYM_DTYPE_FUNCTION  2

+#define EFI_IMAGE_SYM_DTYPE_ARRAY     3

+

+//

+// Storage classes.

+//

+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION   (UINT8) -1

+#define EFI_IMAGE_SYM_CLASS_NULL              0

+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC         1

+#define EFI_IMAGE_SYM_CLASS_EXTERNAL          2

+#define EFI_IMAGE_SYM_CLASS_STATIC            3

+#define EFI_IMAGE_SYM_CLASS_REGISTER          4

+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF      5

+#define EFI_IMAGE_SYM_CLASS_LABEL             6

+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL   7

+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT  8

+#define EFI_IMAGE_SYM_CLASS_ARGUMENT          9

+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG        10

+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION   11

+#define EFI_IMAGE_SYM_CLASS_UNION_TAG         12

+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION   13

+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC  14

+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG          15

+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM    16

+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM    17

+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD         18

+#define EFI_IMAGE_SYM_CLASS_BLOCK             100

+#define EFI_IMAGE_SYM_CLASS_FUNCTION          101

+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT     102

+#define EFI_IMAGE_SYM_CLASS_FILE              103

+#define EFI_IMAGE_SYM_CLASS_SECTION           104

+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL     105

+

+//

+// type packing constants

+//

+#define EFI_IMAGE_N_BTMASK  017

+#define EFI_IMAGE_N_TMASK   060

+#define EFI_IMAGE_N_TMASK1  0300

+#define EFI_IMAGE_N_TMASK2  0360

+#define EFI_IMAGE_N_BTSHFT  4

+#define EFI_IMAGE_N_TSHIFT  2

+

+//

+// Communal selection types.

+//

+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES    1

+#define EFI_IMAGE_COMDAT_SELECT_ANY             2

+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE       3

+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH     4

+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE     5

+

+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY  1

+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY    2

+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS      3

+

+///

+/// Relocation format.

+///

+typedef struct {

+  UINT32  VirtualAddress;

+  UINT32  SymbolTableIndex;

+  UINT16  Type;

+} EFI_IMAGE_RELOCATION;

+

+#define EFI_IMAGE_SIZEOF_RELOCATION 10

+

+//

+// I386 relocation types.

+//

+#define EFI_IMAGE_REL_I386_ABSOLUTE 0   // Reference is absolute, no relocation is necessary

+#define EFI_IMAGE_REL_I386_DIR16    01  // Direct 16-bit reference to the symbols virtual address

+#define EFI_IMAGE_REL_I386_REL16    02  // PC-relative 16-bit reference to the symbols virtual address

+#define EFI_IMAGE_REL_I386_DIR32    06  // Direct 32-bit reference to the symbols virtual address

+#define EFI_IMAGE_REL_I386_DIR32NB  07  // Direct 32-bit reference to the symbols virtual address, base not included

+#define EFI_IMAGE_REL_I386_SEG12    011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address

+#define EFI_IMAGE_REL_I386_SECTION  012

+#define EFI_IMAGE_REL_I386_SECREL   013

+#define EFI_IMAGE_REL_I386_REL32    024 // PC-relative 32-bit reference to the symbols virtual address

+

+///

+/// Based relocation format.

+///

+typedef struct {

+  UINT32  VirtualAddress;

+  UINT32  SizeOfBlock;

+} EFI_IMAGE_BASE_RELOCATION;

+

+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION  8

+

+//

+// Based relocation types.

+//

+#define EFI_IMAGE_REL_BASED_ABSOLUTE      0

+#define EFI_IMAGE_REL_BASED_HIGH          1

+#define EFI_IMAGE_REL_BASED_LOW           2

+#define EFI_IMAGE_REL_BASED_HIGHLOW       3

+#define EFI_IMAGE_REL_BASED_HIGHADJ       4

+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR  5

+#define EFI_IMAGE_REL_BASED_IA64_IMM64    9

+#define EFI_IMAGE_REL_BASED_DIR64         10

+

+///

+/// Line number format.

+///

+typedef struct {

+  union {

+    UINT32  SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.

+    UINT32  VirtualAddress;   // Virtual address of line number.

+  } Type;

+  UINT16  Linenumber;         // Line number.

+} EFI_IMAGE_LINENUMBER;

+

+#define EFI_IMAGE_SIZEOF_LINENUMBER 6

+

+//

+// Archive format.

+//

+#define EFI_IMAGE_ARCHIVE_START_SIZE        8

+#define EFI_IMAGE_ARCHIVE_START             "!<arch>\n"

+#define EFI_IMAGE_ARCHIVE_END               "`\n"

+#define EFI_IMAGE_ARCHIVE_PAD               "\n"

+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER     "/               "

+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER  "//              "

+

+typedef struct {

+  UINT8 Name[16];     // File member name - `/' terminated.

+  UINT8 Date[12];     // File member date - decimal.

+  UINT8 UserID[6];    // File member user id - decimal.

+  UINT8 GroupID[6];   // File member group id - decimal.

+  UINT8 Mode[8];      // File member mode - octal.

+  UINT8 Size[10];     // File member size - decimal.

+  UINT8 EndHeader[2]; // String to end header.

+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;

+

+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60

+

+//

+// DLL support.

+//

+

+///

+/// DLL Export Format

+///

+typedef struct {

+  UINT32  Characteristics;

+  UINT32  TimeDateStamp;

+  UINT16  MajorVersion;

+  UINT16  MinorVersion;

+  UINT32  Name;

+  UINT32  Base;

+  UINT32  NumberOfFunctions;

+  UINT32  NumberOfNames;

+  UINT32  AddressOfFunctions;

+  UINT32  AddressOfNames;

+  UINT32  AddressOfNameOrdinals;

+} EFI_IMAGE_EXPORT_DIRECTORY;

+

+///

+/// DLL support.

+/// Import Format

+///

+typedef struct {

+  UINT16  Hint;

+  UINT8   Name[1];

+} EFI_IMAGE_IMPORT_BY_NAME;

+

+typedef struct {

+  union {

+    UINT32                    Function;

+    UINT32                    Ordinal;

+    EFI_IMAGE_IMPORT_BY_NAME  *AddressOfData;

+  } u1;

+} EFI_IMAGE_THUNK_DATA;

+

+#define EFI_IMAGE_ORDINAL_FLAG              0x80000000

+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal)  ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)

+#define EFI_IMAGE_ORDINAL(Ordinal)          (Ordinal & 0xffff)

+

+typedef struct {

+  UINT32                Characteristics;

+  UINT32                TimeDateStamp;

+  UINT32                ForwarderChain;

+  UINT32                Name;

+  EFI_IMAGE_THUNK_DATA  *FirstThunk;

+} EFI_IMAGE_IMPORT_DESCRIPTOR;

+

+///

+/// Debug Format

+///

+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2

+

+typedef struct {

+  UINT32  Characteristics;

+  UINT32  TimeDateStamp;

+  UINT16  MajorVersion;

+  UINT16  MinorVersion;

+  UINT32  Type;

+  UINT32  SizeOfData;

+  UINT32  RVA;

+  UINT32  FileOffset;

+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;

+

+#define CODEVIEW_SIGNATURE_NB10 0x3031424E  // "NB10"

+typedef struct {

+  UINT32  Signature;                        // "NB10"

+  UINT32  Unknown;

+  UINT32  Unknown2;

+  UINT32  Unknown3;

+  //

+  // Filename of .PDB goes here

+  //

+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;

+

+#define CODEVIEW_SIGNATURE_RSDS 0x53445352  // "RSDS"

+typedef struct {

+  UINT32  Signature;                        // "RSDS"

+  UINT32  Unknown;

+  UINT32  Unknown2;

+  UINT32  Unknown3;

+  UINT32  Unknown4;

+  UINT32  Unknown5;

+  //

+  // Filename of .PDB goes here

+  //

+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;

+

+///

+/// Header format for TE images

+///

+typedef struct {

+  UINT16                    Signature;            // signature for TE format = "VZ"

+  UINT16                    Machine;              // from the original file header

+  UINT8                     NumberOfSections;     // from the original file header

+  UINT8                     Subsystem;            // from original optional header

+  UINT16                    StrippedSize;         // how many bytes we removed from the header

+  UINT32                    AddressOfEntryPoint;  // offset to entry point -- from original optional header

+  UINT32                    BaseOfCode;           // from original image -- required for ITP debug

+  UINT64                    ImageBase;            // from original file header

+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[2];     // only base relocation and debug directory

+} EFI_TE_IMAGE_HEADER;

+

+#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56      // "VZ"

+

+//

+// Data directory indexes in our TE image header

+//

+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC  0

+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG      1

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/PeCoffLoader/Ia32/PeCoffLoaderEx.c b/edk2/Tools/Source/TianoTools/PeCoffLoader/Ia32/PeCoffLoaderEx.c
new file mode 100644
index 0000000..0af4340
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeCoffLoader/Ia32/PeCoffLoaderEx.c
@@ -0,0 +1,64 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeCoffLoaderEx.c

+

+Abstract:

+

+    IA-32 Specific relocation fixups

+

+Revision History

+

+--*/

+

+

+#define EFI_SPECIFICATION_VERSION    0x00000000

+#define EDK_RELEASE_VERSION          0x00020000

+#include <Base.h>

+#include <Library/PeCoffLib.h>

+#include <Library/BaseMemoryLib.h>

+

+

+

+

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+

+  Performs an IA-32 specific relocation fixup

+

+Arguments:

+

+  Reloc      - Pointer to the relocation record

+

+  Fixup      - Pointer to the address to fix up

+

+  FixupData  - Pointer to a buffer to log the fixups

+

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+

+  EFI_UNSUPPORTED   - Unsupported now

+

+--*/

+{

+  return RETURN_UNSUPPORTED;

+}

diff --git a/edk2/Tools/Source/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c b/edk2/Tools/Source/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c
new file mode 100644
index 0000000..2a58a62
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c
@@ -0,0 +1,251 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+    PeCoffLoaderEx.c

+

+Abstract:

+

+    Fixes Intel Itanium(TM) specific relocation types

+

+

+Revision History

+

+--*/

+

+#define EFI_SPECIFICATION_VERSION    0x00000000

+#define EDK_RELEASE_VERSION          0x00020000

+#include <Base.h>

+#include <Library/PeCoffLib.h>

+#include <Library/BaseMemoryLib.h>

+

+

+

+

+

+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos)  \

+    Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)

+

+#define INS_IMM64(Value, Address, Size, InstPos, ValPos)  \

+    *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \

+          ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)

+

+#define IMM64_IMM7B_INST_WORD_X         3  

+#define IMM64_IMM7B_SIZE_X              7  

+#define IMM64_IMM7B_INST_WORD_POS_X     4  

+#define IMM64_IMM7B_VAL_POS_X           0  

+

+#define IMM64_IMM9D_INST_WORD_X         3  

+#define IMM64_IMM9D_SIZE_X              9  

+#define IMM64_IMM9D_INST_WORD_POS_X     18  

+#define IMM64_IMM9D_VAL_POS_X           7  

+

+#define IMM64_IMM5C_INST_WORD_X         3  

+#define IMM64_IMM5C_SIZE_X              5  

+#define IMM64_IMM5C_INST_WORD_POS_X     13  

+#define IMM64_IMM5C_VAL_POS_X           16  

+

+#define IMM64_IC_INST_WORD_X            3  

+#define IMM64_IC_SIZE_X                 1  

+#define IMM64_IC_INST_WORD_POS_X        12  

+#define IMM64_IC_VAL_POS_X              21  

+

+#define IMM64_IMM41a_INST_WORD_X        1  

+#define IMM64_IMM41a_SIZE_X             10  

+#define IMM64_IMM41a_INST_WORD_POS_X    14  

+#define IMM64_IMM41a_VAL_POS_X          22  

+

+#define IMM64_IMM41b_INST_WORD_X        1  

+#define IMM64_IMM41b_SIZE_X             8  

+#define IMM64_IMM41b_INST_WORD_POS_X    24  

+#define IMM64_IMM41b_VAL_POS_X          32  

+

+#define IMM64_IMM41c_INST_WORD_X        2  

+#define IMM64_IMM41c_SIZE_X             23  

+#define IMM64_IMM41c_INST_WORD_POS_X    0  

+#define IMM64_IMM41c_VAL_POS_X          40  

+

+#define IMM64_SIGN_INST_WORD_X          3  

+#define IMM64_SIGN_SIZE_X               1  

+#define IMM64_SIGN_INST_WORD_POS_X      27  

+#define IMM64_SIGN_VAL_POS_X            63  

+

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup, 

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+

+  Performs an Itanium-based specific relocation fixup

+

+Arguments:

+

+  Reloc      - Pointer to the relocation record

+

+  Fixup      - Pointer to the address to fix up

+

+  FixupData  - Pointer to a buffer to log the fixups

+

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+

+  Status code

+

+--*/

+{

+  UINT64      *F64;

+  UINT64      FixupVal;

+

+  switch ((*Reloc) >> 12) {

+

+    case EFI_IMAGE_REL_BASED_DIR64:

+      F64 = (UINT64 *) Fixup;

+      *F64 = *F64 + (UINT64) Adjust;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    case EFI_IMAGE_REL_BASED_IA64_IMM64:

+

+      //

+      // Align it to bundle address before fixing up the

+      // 64-bit immediate value of the movl instruction.

+      //

+

+      Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));

+      FixupVal = (UINT64)0;

+                       

+      // 

+      // Extract the lower 32 bits of IMM64 from bundle

+      //

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,

+                IMM64_IMM7B_SIZE_X,

+                IMM64_IMM7B_INST_WORD_POS_X,

+                IMM64_IMM7B_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,

+                IMM64_IMM9D_SIZE_X,

+                IMM64_IMM9D_INST_WORD_POS_X,

+                IMM64_IMM9D_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,

+                IMM64_IMM5C_SIZE_X,

+                IMM64_IMM5C_INST_WORD_POS_X,

+                IMM64_IMM5C_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,

+                IMM64_IC_SIZE_X,

+                IMM64_IC_INST_WORD_POS_X,

+                IMM64_IC_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,

+                IMM64_IMM41a_SIZE_X,

+                IMM64_IMM41a_INST_WORD_POS_X,

+                IMM64_IMM41a_VAL_POS_X

+                );

+                       

+      // 

+      // Update 64-bit address

+      //

+      FixupVal += Adjust;

+

+      // 

+      // Insert IMM64 into bundle

+      //

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),

+                IMM64_IMM7B_SIZE_X,

+                IMM64_IMM7B_INST_WORD_POS_X,

+                IMM64_IMM7B_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),

+                IMM64_IMM9D_SIZE_X,

+                IMM64_IMM9D_INST_WORD_POS_X,

+                IMM64_IMM9D_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),

+                IMM64_IMM5C_SIZE_X,

+                IMM64_IMM5C_INST_WORD_POS_X,

+                IMM64_IMM5C_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),

+                IMM64_IC_SIZE_X,

+                IMM64_IC_INST_WORD_POS_X,

+                IMM64_IC_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),

+                IMM64_IMM41a_SIZE_X,

+                IMM64_IMM41a_INST_WORD_POS_X,

+                IMM64_IMM41a_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),

+                IMM64_IMM41b_SIZE_X,

+                IMM64_IMM41b_INST_WORD_POS_X,

+                IMM64_IMM41b_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),

+                IMM64_IMM41c_SIZE_X,

+                IMM64_IMM41c_INST_WORD_POS_X,

+                IMM64_IMM41c_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),

+                IMM64_SIGN_SIZE_X,

+                IMM64_SIGN_INST_WORD_POS_X,

+                IMM64_SIGN_VAL_POS_X

+                );

+

+      F64 = (UINT64 *) Fixup;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/PeCoffLoader/X64/PeCoffLoaderEx.c b/edk2/Tools/Source/TianoTools/PeCoffLoader/X64/PeCoffLoaderEx.c
new file mode 100644
index 0000000..6bcae27
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeCoffLoader/X64/PeCoffLoaderEx.c
@@ -0,0 +1,76 @@
+/*++

+

+Copyright 2005, Intel Corporation                                                         

+All rights reserved. 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.             

+

+

+Module Name:

+

+  PeCoffLoaderEx.c

+

+Abstract:

+

+  x64 Specific relocation fixups

+

+Revision History

+

+--*/

+

+#define EFI_SPECIFICATION_VERSION    0x00000000

+#define EDK_RELEASE_VERSION          0x00020000

+#include <Base.h>

+#include <Library/PeCoffLib.h>

+#include <Library/BaseMemoryLib.h>

+

+

+

+

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup, 

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+/*++

+

+Routine Description:

+  Performs an x64 specific relocation fixup

+

+Arguments:

+  Reloc      - Pointer to the relocation record

+  Fixup      - Pointer to the address to fix up

+  FixupData  - Pointer to a buffer to log the fixups

+  Adjust     - The offset to adjust the fixup

+

+Returns:

+  None

+

+--*/

+{

+  UINT64      *F64;

+

+  switch ((*Reloc) >> 12) {

+

+    case EFI_IMAGE_REL_BASED_DIR64:

+      F64 = (UINT64 *) Fixup;

+      *F64 = *F64 + (UINT64) Adjust;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *F64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/PeCoffLoader/build.xml b/edk2/Tools/Source/TianoTools/PeCoffLoader/build.xml
new file mode 100644
index 0000000..7106bce
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeCoffLoader/build.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK PeCoffLoader

+  Copyright (c) 2006, Intel Corporation

+-->

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property name="LibName" value="PeCoffLoader"/>

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR_IA32" value="${PACKAGE_DIR}/${LibName}/tmp/Ia32"/>

+  <property name="BUILD_DIR_X64" value="${PACKAGE_DIR}/${LibName}/tmp/X64"/>

+  <property name="BUILD_DIR_IPF" value="${PACKAGE_DIR}/${LibName}/tmp/Ipf"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${LibName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Library: ${LibName}"/>

+    <mkdir dir="${BUILD_DIR_IA32}"/>

+    <mkdir dir="${BUILD_DIR_X64}"/>

+    <mkdir dir="${BUILD_DIR_IPF}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+        <property name="ToolChain" value="gcc"/>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+

+    <condition property="syslibdirs" value="">

+      <os family="mac"/>

+    </condition>

+    

+    <condition property="syslibs" value="">

+      <os family="mac"/>

+    </condition>

+    

+    <condition property="syslibdirs" value="${env.CYGWIN_HOME}/lib/e2fsprogs">

+      <os family="windows"/>

+    </condition>

+    

+    <condition property="syslibs" value="uuid">

+      <os family="windows"/>

+    </condition>

+    

+    <condition property="syslibdirs" value="/usr/lib">

+      <os name="Linux"/>

+    </condition>

+    

+    <condition property="syslibs" value="uuid">

+      <os name="Linux"/>

+    </condition>

+    

+  </target>

+

+  <target name="Tool" depends="init, PeCoffLoader_Ia32, PeCoffLoader_Ipf, PeCoffLoader_X64"/>

+

+  <target name="PeCoffLoader_Ia32" >

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_IA32}" 

+        outfile="${LIB_DIR}/${LibName}_Ia32"

+        outtype="static"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_IA32_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${LibName}" 

+        includes="BasePeCoff.c Ia32/PeCoffLoaderEx.c" />

+

+      <includepath path="${PACKAGE_DIR}/${LibName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+    </cc>

+  </target>

+

+  <target name="PeCoffLoader_Ipf" >

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_IPF}" 

+        outfile="${LIB_DIR}/${LibName}_Ipf"

+        outtype="static"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_IPF_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${LibName}" 

+        includes="BasePeCoff.c Ipf/PeCoffLoaderEx.c" />

+

+      <includepath path="${PACKAGE_DIR}/${LibName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+    </cc>

+  </target>

+

+  <target name="PeCoffLoader_X64" >

+    <cc name="${ToolChain}" objdir="${BUILD_DIR_X64}" 

+        outfile="${LIB_DIR}/${LibName}_X64"

+        outtype="static"

+        optimize="speed">

+

+      <defineset>

+        <define name="BUILDING_TOOLS"/>

+        <define name="TOOL_BUILD_X64_TARGET"/>

+      </defineset>

+    

+      <fileset dir="${basedir}/${LibName}" 

+        includes="BasePeCoff.c X64/PeCoffLoaderEx.c" />

+

+      <includepath path="${PACKAGE_DIR}/${LibName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+    </cc>

+  </target>

+

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR_IA32}" includes="*.obj"/>

+      <fileset dir="${BUILD_DIR_X64}" includes="*.obj"/>

+      <fileset dir="${BUILD_DIR_IPF}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${LibName}${ext_exe}"/>  

+    <delete dir="${PACKAGE_DIR}/${LibName}/tmp">

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c b/edk2/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
new file mode 100644
index 0000000..7dc95d6
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
@@ -0,0 +1,975 @@
+/*++

+

+Copyright (c)  1999 - 2005 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  PeiRebaseExe.c

+

+Abstract:

+

+  This contains all code necessary to build the PeiRebase.exe utility.

+  This utility relies heavily on the PeiRebase DLL.  Definitions for both

+  can be found in the PEI Rebase Utility Specification, review draft.

+

+--*/

+

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include <stdlib.h>

+#include <stdio.h>

+#include <string.h>

+#include "CommonLib.h"

+#include "ParseInf.h"

+#include "FvLib.h"

+

+#include "EfiUtilityMsgs.h"

+#include "FirmwareFileSystem.h"

+#include "PeCoffLib.h"

+

+#include "PeiRebaseExe.h"

+

+EFI_STATUS

+ReadHeader (

+  IN FILE       *InputFile,

+  OUT UINT32    *FvSize,

+  OUT BOOLEAN   *ErasePolarity

+  );

+

+int

+main (

+  int  argc,

+  char **argv

+  )

+/*++

+

+Routine Description:

+

+  This utility relocates PEI XIP PE32s in a FV.

+

+Arguments:

+

+  argc          - Number of command line arguments

+  argv[]:

+  BaseAddress     The base address to use for rebasing the FV.  The correct 

+                  format is a hex number preceded by 0x.

+  InputFileName   The name of the input FV file.

+  OutputFileName  The name of the output FV file.

+

+  Arguments come in pair in any order.

+    -I InputFileName 

+    -O OutputFileName

+    -B BaseAddress 

+

+Returns:

+

+  0   No error conditions detected.

+  1   One or more of the input parameters is invalid.

+  2   A resource required by the utility was unavailable.  

+      Most commonly this will be memory allocation or file creation.

+  3   PeiRebase.dll could not be loaded.

+  4   Error executing the PEI rebase.

+

+--*/

+{

+  UINT8                       Index;

+  CHAR8                       InputFileName[_MAX_PATH];

+  CHAR8                       OutputFileName[_MAX_PATH];

+  EFI_PHYSICAL_ADDRESS        BaseAddress;

+  BOOLEAN                     BaseAddressSet;

+  EFI_STATUS                  Status;

+  FILE                        *InputFile;

+  FILE                        *OutputFile;

+  UINT64                      FvOffset;

+  UINT32                      FileCount;

+  int                         BytesRead;

+  EFI_FIRMWARE_VOLUME_HEADER  *FvImage;

+  UINT32                      FvSize;

+  EFI_FFS_FILE_HEADER         *CurrentFile;

+  BOOLEAN                     ErasePolarity;

+  EFI_PHYSICAL_ADDRESS        CurrentFileBaseAddress;

+

+  ErasePolarity = FALSE;

+  //

+  // Set utility name for error/warning reporting purposes.

+  //

+  SetUtilityName (UTILITY_NAME);

+  //

+  // Verify the correct number of arguments

+  //

+  if (argc != MAX_ARGS) {

+    PrintUsage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Initialize variables

+  //

+  InputFileName[0]  = 0;

+  OutputFileName[0] = 0;

+  BaseAddress       = 0;

+  BaseAddressSet    = FALSE;

+  FvOffset          = 0;

+  FileCount         = 0;

+  ErasePolarity     = FALSE;

+  InputFile         = NULL;

+  OutputFile        = NULL;

+  FvImage           = NULL;

+  //

+  // Parse the command line arguments

+  //

+  for (Index = 1; Index < MAX_ARGS; Index += 2) {

+    //

+    // Make sure argument pair begin with - or /

+    //

+    if (argv[Index][0] != '-' && argv[Index][0] != '/') {

+      PrintUsage ();

+      Error (NULL, 0, 0, argv[Index], "unrecognized option");

+      return STATUS_ERROR;

+    }

+    //

+    // Make sure argument specifier is only one letter

+    //

+    if (argv[Index][2] != 0) {

+      PrintUsage ();

+      Error (NULL, 0, 0, argv[Index], "unrecognized option");

+      return STATUS_ERROR;

+    }    

+    //

+    // Determine argument to read

+    //

+    switch (argv[Index][1]) {

+    case 'I':

+    case 'i':

+      if (strlen (InputFileName) == 0) {

+        strcpy (InputFileName, argv[Index + 1]);

+      } else {

+        PrintUsage ();

+        Error (NULL, 0, 0, argv[Index + 1], "only one -i InputFileName may be specified");

+        return STATUS_ERROR;

+      }

+      break;

+

+    case 'O':

+    case 'o':

+      if (strlen (OutputFileName) == 0) {

+        strcpy (OutputFileName, argv[Index + 1]);

+      } else {

+        PrintUsage ();

+        Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");

+        return STATUS_ERROR;

+      }

+      break;

+

+    case 'B':

+    case 'b':

+      if (!BaseAddressSet) {

+        Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress);

+        if (EFI_ERROR (Status)) {

+          PrintUsage ();

+          Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address");

+          return STATUS_ERROR;

+        }

+

+        BaseAddressSet = TRUE;

+      } else {

+        PrintUsage ();

+        Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once");

+        return STATUS_ERROR;

+      }

+      break;

+

+    default:

+      PrintUsage ();

+      Error (NULL, 0, 0, argv[Index], "unrecognized argument");

+      return STATUS_ERROR;

+      break;

+    }

+  }

+  //

+  // Open the file containing the FV

+  //

+  InputFile = fopen (InputFileName, "rb");

+  if (InputFile == NULL) {

+    Error (NULL, 0, 0, InputFileName, "could not open input file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Determine size of FV

+  //

+  Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "could not parse the FV header", NULL);

+    goto Finish;

+  }

+  //

+  // Allocate a buffer for the FV image

+  //

+  FvImage = malloc (FvSize);

+  if (FvImage == NULL) {

+    Error (NULL, 0, 0, "application error", "memory allocation failed");

+    goto Finish;

+  }

+  //

+  // Read the entire FV to the buffer

+  //

+  BytesRead = fread (FvImage, 1, FvSize, InputFile);

+  fclose (InputFile);

+  InputFile = NULL;

+  if ((unsigned int) BytesRead != FvSize) {

+    Error (NULL, 0, 0, InputFileName, "failed to read from file");

+    goto Finish;

+  }

+  //

+  // Prepare to walk the FV image

+  //

+  InitializeFvLib (FvImage, FvSize);

+  //

+  // Get the first file

+  //

+  Status = GetNextFile (NULL, &CurrentFile);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "cannot find the first file in the FV image", NULL);

+    goto Finish;

+  }

+  //

+  // Check if each file should be rebased

+  //

+  while (CurrentFile != NULL) {

+    //

+    // Rebase this file

+    //

+    CurrentFileBaseAddress  = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);

+    Status                  = FfsRebase (CurrentFile, CurrentFileBaseAddress);

+

+    if (EFI_ERROR (Status)) {

+      switch (Status) {

+

+      case EFI_INVALID_PARAMETER:

+        Error (NULL, 0, 0, "invalid parameter passed to FfsRebase", NULL);

+        break;

+

+      case EFI_ABORTED:

+        Error (NULL, 0, 0, "error detected while rebasing -- aborted", NULL);

+        break;

+

+      case EFI_OUT_OF_RESOURCES:

+        Error (NULL, 0, 0, "FfsRebase could not allocate required resources", NULL);

+        break;

+

+      case EFI_NOT_FOUND:

+        Error (NULL, 0, 0, "FfsRebase could not locate a PE32 section", NULL);

+        break;

+

+      default:

+        Error (NULL, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status);

+        break;

+      }

+

+      goto Finish;

+    }

+    //

+    // Get the next file

+    //

+    Status = GetNextFile (CurrentFile, &CurrentFile);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "cannot find the next file in the FV image", NULL);

+      goto Finish;

+    }

+  }

+  //

+  // Open the output file

+  //

+  OutputFile = fopen (OutputFileName, "wb");

+  if (OutputFile == NULL) {

+    Error (NULL, 0, 0, OutputFileName, "failed to open output file");

+    goto Finish;

+  }

+

+  if (fwrite (FvImage, 1, FvSize, OutputFile) != FvSize) {

+    Error (NULL, 0, 0, "failed to write to output file", 0);

+    goto Finish;

+  }

+

+Finish:

+  if (InputFile != NULL) {

+    fclose (InputFile);

+  }

+  //

+  // If we created an output file, and there was an error, remove it so

+  // subsequent builds will rebuild it.

+  //

+  if (OutputFile != NULL) {

+    if (GetUtilityStatus () == STATUS_ERROR) {

+      remove (OutputFileName);

+    }

+

+    fclose (OutputFile);

+  }

+

+  if (FvImage != NULL) {

+    free (FvImage);

+  }

+

+  return GetUtilityStatus ();

+}

+

+EFI_STATUS

+ReadHeader (

+  IN FILE       *InputFile,

+  OUT UINT32    *FvSize,

+  OUT BOOLEAN   *ErasePolarity

+  )

+/*++

+

+Routine Description:

+

+  This function determines the size of the FV and the erase polarity.  The 

+  erase polarity is the FALSE value for file state.

+

+Arguments:

+

+  InputFile       The file that contains the FV image.

+  FvSize          The size of the FV.

+  ErasePolarity   The FV erase polarity.

+    

+Returns:

+ 

+  EFI_SUCCESS             Function completed successfully.

+  EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.

+  EFI_ABORTED             The function encountered an error.

+

+--*/

+{

+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;

+  EFI_FV_BLOCK_MAP_ENTRY      BlockMap;

+  UINTN                       Signature[2];

+  UINTN                       BytesRead;

+  UINT32                      Size;

+

+  BytesRead = 0;

+  Size      = 0;

+  //

+  // Check input parameters

+  //

+  if ((InputFile == NULL) || (FvSize == NULL) || (ErasePolarity == NULL)) {

+    Error (NULL, 0, 0, "ReadHeader()", "invalid input parameter");

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Read the header

+  //

+  fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);

+  BytesRead     = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);

+  Signature[0]  = VolumeHeader.Signature;

+  Signature[1]  = 0;

+

+  //

+  // Get erase polarity

+  //

+  if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {

+    *ErasePolarity = TRUE;

+  }

+

+  do {

+    fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);

+    BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);

+

+    if (BlockMap.NumBlocks != 0) {

+      Size += BlockMap.NumBlocks * BlockMap.BlockLength;

+    }

+

+  } while (!(BlockMap.NumBlocks == 0 && BlockMap.BlockLength == 0));

+

+  if (VolumeHeader.FvLength != Size) {

+    Error (NULL, 0, 0, "volume size not consistant with block maps", NULL);

+    return EFI_ABORTED;

+  }

+

+  *FvSize = Size;

+

+  rewind (InputFile);

+

+  return EFI_SUCCESS;

+}

+

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "%s, PEI Rebase Utility. Version %i.%i, %s.\n\n",

+    UTILITY_NAME,

+    UTILITY_MAJOR_VERSION,

+    UTILITY_MINOR_VERSION,

+    UTILITY_DATE

+    );

+}

+

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",

+    UTILITY_NAME

+    );

+  printf ("  Where:\n");

+  printf ("    InputFileName is the name of the EFI FV file to rebase.\n");

+  printf ("    OutputFileName is the desired output file name.\n");

+  printf ("    BaseAddress is the FV base address to rebase agains.\n");

+  printf ("  Argument pair may be in any order.\n\n");

+}

+

+EFI_STATUS

+FfsRebase (

+  IN OUT EFI_FFS_FILE_HEADER    *FfsFile,

+  IN EFI_PHYSICAL_ADDRESS       BaseAddress

+  )

+/*++

+

+Routine Description:

+

+  This function determines if a file is XIP and should be rebased.  It will 

+  rebase any PE32 sections found in the file using the base address.

+  

+Arguments:

+

+  FfsFile           A pointer to Ffs file image.

+  BaseAddress       The base address to use for rebasing the file image.

+

+Returns:

+

+  EFI_SUCCESS             The image was properly rebased.

+  EFI_INVALID_PARAMETER   An input parameter is invalid.

+  EFI_ABORTED             An error occurred while rebasing the input file image.

+  EFI_OUT_OF_RESOURCES    Could not allocate a required resource.

+  EFI_NOT_FOUND           No compressed sections could be found.

+

+--*/

+{

+  EFI_STATUS                            Status;

+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;

+  UINTN                                 MemoryImagePointer;

+  UINTN                                 MemoryImagePointerAligned;

+  EFI_PHYSICAL_ADDRESS                  ImageAddress;

+  UINT64                                ImageSize;

+  EFI_PHYSICAL_ADDRESS                  EntryPoint;

+  UINT32                                Pe32ImageSize;

+  UINT32                                NewPe32BaseAddress;

+  UINTN                                 Index;

+  EFI_FILE_SECTION_POINTER              CurrentPe32Section;

+  EFI_FFS_FILE_STATE                    SavedState;

+  EFI_IMAGE_NT_HEADERS                  *PeHdr;

+  UINT32                                *PeHdrSizeOfImage;

+  UINT32                                *PeHdrChecksum;

+  UINT32                                FoundCount;

+  EFI_TE_IMAGE_HEADER                   *TEImageHeader;

+  UINT8                                 *TEBuffer;

+  EFI_IMAGE_DOS_HEADER                  *DosHeader;

+  UINT8                                 FileGuidString[80];

+  UINT32                                TailSize;

+  EFI_FFS_FILE_TAIL                     TailValue;

+

+  //

+  // Verify input parameters

+  //

+  if (FfsFile == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Convert the GUID to a string so we can at least report which file

+  // if we find an error.

+  //

+  PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE);

+  if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+    TailSize = sizeof (EFI_FFS_FILE_TAIL);

+  } else {

+    TailSize = 0;

+  }

+  //

+  // Do some cursory checks on the FFS file contents

+  //

+  Status = VerifyFfsFile (FfsFile);

+  if (EFI_ERROR (Status)) {

+    Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString);

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Check if XIP file type. If not XIP, don't rebase.

+  //

+  if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&

+      FfsFile->Type != EFI_FV_FILETYPE_PEIM &&

+      FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&

+      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER

+      ) {

+    return EFI_SUCCESS;

+  }

+  //

+  // Rebase each PE32 section

+  //

+  Status      = EFI_SUCCESS;

+  FoundCount  = 0;

+  for (Index = 1;; Index++) {

+    Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    FoundCount++;

+

+    //

+    // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section

+    //

+    NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile);

+

+    //

+    // Initialize context

+    //

+    memset (&ImageContext, 0, sizeof (ImageContext));

+    ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));

+    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;

+

+    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);

+

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);

+      return Status;

+    }

+    //

+    // Allocate a buffer for the image to be loaded into.

+    //

+    Pe32ImageSize       = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);

+    MemoryImagePointer  = (UINTN) (malloc (Pe32ImageSize + 0x1000));

+    if (MemoryImagePointer == 0) {

+      Error (NULL, 0, 0, "memory allocation failure", NULL);

+      return EFI_OUT_OF_RESOURCES;

+    }

+    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);

+    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);

+    

+

+    ImageContext.ImageAddress = MemoryImagePointerAligned;

+

+    Status                    = PeCoffLoaderLoadImage (&ImageContext);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString);

+      free ((VOID *) MemoryImagePointer);

+      return Status;

+    }

+

+    ImageContext.DestinationAddress = NewPe32BaseAddress;

+    Status                          = PeCoffLoaderRelocateImage (&ImageContext);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);

+      free ((VOID *) MemoryImagePointer);

+      return Status;

+    }

+

+    ImageAddress  = ImageContext.ImageAddress;

+    ImageSize     = ImageContext.ImageSize;

+    EntryPoint    = ImageContext.EntryPoint;

+

+    if (ImageSize > Pe32ImageSize) {

+      Error (

+        NULL,

+        0,

+        0,

+        "rebased image is larger than original PE32 image",

+        "0x%X > 0x%X, file %s",

+        ImageSize,

+        Pe32ImageSize,

+        FileGuidString

+        );

+      free ((VOID *) MemoryImagePointer);

+      return EFI_ABORTED;

+    }

+    //

+    // Since we may have updated the Codeview RVA, we need to insure the PE

+    // header indicates the image is large enough to contain the Codeview data

+    // so it will be loaded properly later if the PEIM is reloaded into memory...

+    //

+    PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);

+    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {

+      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);

+      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);

+    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {

+      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);

+      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);

+    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {

+      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);

+      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);

+    } else {

+      Error (

+        NULL,

+        0,

+        0,

+        "unknown machine type in PE32 image",

+        "machine type=0x%X, file=%s",

+        (UINT32) PeHdr->FileHeader.Machine,

+        FileGuidString

+        );

+      free ((VOID *) MemoryImagePointer);

+      return EFI_ABORTED;

+    }

+

+    if (*PeHdrSizeOfImage != ImageContext.ImageSize) {

+      *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;

+      if (*PeHdrChecksum) {

+        *PeHdrChecksum = 0;

+      }

+    }

+

+    memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);

+

+    free ((VOID *) MemoryImagePointer);

+

+    //

+    // Now update file checksum

+    //

+    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+      TailSize = sizeof (EFI_FFS_FILE_TAIL);

+    } else {

+      TailSize = 0;

+    }

+

+    if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+      SavedState  = FfsFile->State;

+      FfsFile->IntegrityCheck.Checksum.File = 0;

+      FfsFile->State                        = 0;

+      if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+        FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (

+                                                  (UINT8 *) FfsFile,

+                                                  GetLength (FfsFile->Size) - TailSize

+                                                  );

+      } else {

+        FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+      }

+

+      FfsFile->State = SavedState;

+    }

+    //

+    // Update tail if present

+    //

+    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+      TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));

+      *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;

+    }

+  }

+  //

+  // Now process TE sections

+  //

+  for (Index = 1;; Index++) {

+    Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    FoundCount++;

+

+    //

+    // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off

+    // by GenTEImage

+    //

+    TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));

+

+    NewPe32BaseAddress = ((UINT32) BaseAddress) +

+      (

+        (UINTN) CurrentPe32Section.Pe32Section +

+        sizeof (EFI_COMMON_SECTION_HEADER) +

+        sizeof (EFI_TE_IMAGE_HEADER) -

+        TEImageHeader->StrippedSize -

+        (UINTN) FfsFile

+      );

+

+    //

+    // Allocate a buffer to unshrink the image into.

+    //

+    Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -

+    sizeof (EFI_TE_IMAGE_HEADER);

+    Pe32ImageSize += TEImageHeader->StrippedSize;

+    TEBuffer = (UINT8 *) malloc (Pe32ImageSize);

+    if (TEBuffer == NULL) {

+      Error (NULL, 0, 0, "failed to allocate memory", NULL);

+      return EFI_OUT_OF_RESOURCES;

+    }

+    //

+    // Expand the image into our buffer and fill in critical fields in the DOS header

+    // Fill in fields required by the loader.

+    // At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value

+    // itself.

+    //

+    memset (TEBuffer, 0, Pe32ImageSize);

+    DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer;

+    DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;

+    *(UINT32 *) (TEBuffer + 0x3C) = 0x40;

+    PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);

+    PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;

+    PeHdr->FileHeader.Machine = TEImageHeader->Machine;

+    PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;

+

+    //

+    // Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and

+    // the 0x40 bytes for our DOS header.

+    //

+    PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));

+    PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));

+    PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;

+    PeHdr->OptionalHeader.Subsystem   = TEImageHeader->Subsystem;

+    PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;

+    PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *

+    sizeof (EFI_IMAGE_SECTION_HEADER) - 12;

+

+    //

+    // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image

+    //

+    if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||

+        (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)

+        ) {

+      PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;

+      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;

+      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

+    }

+

+    if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||

+        (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)

+        ) {

+      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;

+      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;

+      if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {

+        PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;

+      }

+    }

+    //

+    // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility

+    //

+    PeHdr->OptionalHeader.SectionAlignment = 0x10;

+

+    //

+    // Copy the rest of the image to its original offset

+    //

+    memcpy (

+      TEBuffer + TEImageHeader->StrippedSize,

+      (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER),

+      GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -

+      sizeof (EFI_TE_IMAGE_HEADER)

+      );

+

+    //

+    // Initialize context

+    //

+    memset (&ImageContext, 0, sizeof (ImageContext));

+    ImageContext.Handle     = (VOID *) TEBuffer;

+    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;

+

+    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);

+

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);

+      free (TEBuffer);

+      return Status;

+    }

+    //

+    // Allocate a buffer for the image to be loaded into.

+    //

+    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));

+    if (MemoryImagePointer == 0) {

+      Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);

+      free (TEBuffer);

+      return EFI_OUT_OF_RESOURCES;

+    }

+    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);

+    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);

+    

+

+    ImageContext.ImageAddress = MemoryImagePointerAligned;

+    Status                    = PeCoffLoaderLoadImage (&ImageContext);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);

+      free (TEBuffer);

+      free ((VOID *) MemoryImagePointer);

+      return Status;

+    }

+

+    ImageContext.DestinationAddress = NewPe32BaseAddress;

+    Status                          = PeCoffLoaderRelocateImage (&ImageContext);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);

+      free ((VOID *) MemoryImagePointer);

+      free (TEBuffer);

+      return Status;

+    }

+

+    ImageAddress  = ImageContext.ImageAddress;

+    ImageSize     = ImageContext.ImageSize;

+    EntryPoint    = ImageContext.EntryPoint;

+

+    //

+    // Since we may have updated the Codeview RVA, we need to insure the PE

+    // header indicates the image is large enough to contain the Codeview data

+    // so it will be loaded properly later if the PEIM is reloaded into memory...

+    //

+    PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);

+    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {

+      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);

+      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);

+    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {

+      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);

+      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);

+    } else {

+      Error (

+        NULL,

+        0,

+        0,

+        "unknown machine type in TE image",

+        "machine type=0x%X, file=%s",

+        (UINT32) PeHdr->FileHeader.Machine,

+        FileGuidString

+        );

+      free ((VOID *) MemoryImagePointer);

+      free (TEBuffer);

+      return EFI_ABORTED;

+    }

+

+    if (*PeHdrSizeOfImage != ImageContext.ImageSize) {

+      *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;

+      if (*PeHdrChecksum) {

+        *PeHdrChecksum = 0;

+      }

+    }

+

+    TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));

+    memcpy (

+      (UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER),

+      (VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize),

+      GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -

+      sizeof (EFI_TE_IMAGE_HEADER)

+      );

+    free ((VOID *) MemoryImagePointer);

+    free (TEBuffer);

+    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+      TailSize = sizeof (EFI_FFS_FILE_TAIL);

+    } else {

+      TailSize = 0;

+    }

+    //

+    // Now update file checksum

+    //

+    if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+      SavedState  = FfsFile->State;

+      FfsFile->IntegrityCheck.Checksum.File = 0;

+      FfsFile->State                        = 0;

+      if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {

+        FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (

+                                                  (UINT8 *) FfsFile,

+                                                  GetLength (FfsFile->Size) - TailSize

+                                                  );

+      } else {

+        FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+      }

+

+      FfsFile->State = SavedState;

+    }

+    //

+    // Update tail if present

+    //

+    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {

+      TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));

+      *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;

+    }

+  }

+  //

+  // If we found no files, then emit an error if no compressed sections either

+  //

+  if (FoundCount == 0) {

+    Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section);

+    if (EFI_ERROR (Status)) {

+      Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString);

+      return EFI_NOT_FOUND;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+FfsRebaseImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINT32  *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

+

+Arguments:

+

+  FileHandle - The handle to the PE/COFF file

+

+  FileOffset - The offset, in bytes, into the file to read

+

+  ReadSize   - The number of bytes to read from the file starting at FileOffset

+

+  Buffer     - A pointer to the buffer to read the data into.

+

+Returns:

+

+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

+

+--*/

+{

+  CHAR8   *Destination8;

+  CHAR8   *Source8;

+  UINT32  Length;

+

+  Destination8  = Buffer;

+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);

+  Length        = *ReadSize;

+  while (Length--) {

+    *(Destination8++) = *(Source8++);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.h b/edk2/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.h
new file mode 100644
index 0000000..b9e71f4
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.h
@@ -0,0 +1,154 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  

+  PeiRebaseExe.h

+

+Abstract:

+

+  Definitions for the PeiRebase exe utility.

+

+--*/

+

+#ifndef _EFI_PEIM_FIXUP_EXE_H

+#define _EFI_PEIM_FIXUP_EXE_H

+

+// #include "Efi2WinNt.h"

+#include "FirmwareFileSystem.h"

+#include "FirmwareVolumeHeader.h"

+#include "MultiPhase.h"

+

+//

+// Utility Name

+//

+#define UTILITY_NAME  "PeiRebase"

+

+//

+// Utility version information

+//

+#define UTILITY_MAJOR_VERSION 0

+#define UTILITY_MINOR_VERSION 1

+#define UTILITY_DATE          __DATE__

+

+//

+// The maximum number of arguments accepted from the command line.

+//

+#define MAX_ARGS  7

+

+//

+// The file copy buffer size

+//

+#define FILE_COPY_BUFFER_SIZE 512

+

+//

+// The function that displays general utility information

+//

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+//

+// The function that displays the utility usage message.

+//

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+//

+// Internal function declarations

+//

+EFI_STATUS

+FfsRebaseImageRead (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINT32  *ReadSize,

+  OUT    VOID    *Buffer

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FileHandle  - GC_TODO: add argument description

+  FileOffset  - GC_TODO: add argument description

+  ReadSize    - GC_TODO: add argument description

+  Buffer      - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+EFI_STATUS

+FfsRebase (

+  IN OUT EFI_FFS_FILE_HEADER    *FfsFile,

+  IN EFI_PHYSICAL_ADDRESS       BaseAddress

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FfsFile     - GC_TODO: add argument description

+  BaseAddress - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/PeiRebase/build.xml b/edk2/Tools/Source/TianoTools/PeiRebase/build.xml
new file mode 100644
index 0000000..b49193c
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeiRebase/build.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK PeiRebase Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="PeiRebase"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="Tool" depends="init, PeiRebase_Ia32, PeiRebase_Ipf, PeiRebase_X64"/>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="PeiRebase_Ia32" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}_Ia32"

+        outtype="executable"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_Ia32"/>

+    </cc>

+  </target>

+

+  <target name="PeiRebase_Ipf" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}_Ipf"

+        outtype="executable"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_Ipf"/>

+    </cc>

+  </target>

+

+  <target name="PeiRebase_X64" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}_X64"

+        outtype="executable"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" />

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress PeCoffLoader_X64"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/PeiRebase/makefile b/edk2/Tools/Source/TianoTools/PeiRebase/makefile
new file mode 100644
index 0000000..4b19309
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/PeiRebase/makefile
@@ -0,0 +1,71 @@
+#/*++

+#  

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#  

+#  Module Name:

+#  

+#    makefile

+#    

+#  Abstract:

+#  

+#    makefile for building the PeiRebase utility.

+#  

+#  Revision History

+#  

+#--*/

+

+#

+# Make sure environmental variable EFI_SOURCE is set

+#

+!IFNDEF EFI_SOURCE

+!ERROR EFI_SOURCE environmental variable not set 

+!ENDIF

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = PeiRebase

+TARGET_SRC_DIR      = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\PeiRebase.exe

+TARGET_EXE_LIBS     = $(TIANO_TOOLS_OUTPUT)\Common.lib

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\PeiRebase.obj  

+

+#

+# Compile each source file

+#

+$(TIANO_TOOLS_OUTPUT)\PeiRebase.obj : $(TARGET_SRC_DIR)\PeiRebaseExe.c $(INC_DEPS) $(TARGET_EXE_LIBS)

+  $(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\PeiRebaseExe.c /Fo$@

+

+#

+# Link the object files together

+#

+$(TARGET_EXE) : $(OBJECTS) $(TARGET_EXE_LIBS)

+  @echo LINKING

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)  $(TARGET_EXE_LIBS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/Makefile b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/Makefile
new file mode 100644
index 0000000..53e6be5
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/Makefile
@@ -0,0 +1,58 @@
+#/*++

+#   

+#  Copyright (c) 2005 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = SecApResetVectorFixup

+TARGET_SOURCE_DIR   = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+TARGET_EXE_SOURCE   = $(TARGET_SOURCE_DIR)\$(TARGET_NAME).c

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj

+LIBS      = $(TIANO_TOOLS_OUTPUT)\Common.lib  

+

+#

+# Build EXE

+#

+

+$(OBJECTS) : $(TARGET_EXE_SOURCE) $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(TARGET_EXE_SOURCE) /Fo$@

+

+$(TARGET_EXE): $(OBJECTS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(OBJECTS) $(LIBS) /out:$(TARGET_EXE)

+

+clean:

+  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c
new file mode 100644
index 0000000..5cb03f0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c
@@ -0,0 +1,363 @@
+/*++

+

+Copyright (c)  2005 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+    SecApResetVectorFixup.c

+

+Abstract:

+

+    This utility is part of build process for IA32 Fvrecovery.fv whose total size

+    is larger than 128kB so that we cannot use GenFvImage utility to put Ap reset 

+    vector at the zero vector of Fv header.

+    

+      PEI FV after using the tool

+    

+    -------------------------

+    |zzz                    |

+    |                       |

+    |                       |

+    |      FFS              |

+    |                       |

+    |                       |

+    |                       |

+    |---------------------- |

+    |       PAD             |

+    |                       |

+    |.......................|  --- 

+    |                       |   |

+    |xxx                    |   | 128K    

+    |---------------------- |   | 

+    |       VTF (SEC)       |   |

+    -------------------------  ---

+    

+    1. zzz --> Zero vector, which is beyond the 128K limited address space

+    2. xxx --> AP reset vector at 4K alignment below 128K and it is in the PAD

+       file area.

+    3. After the build process ,the PAD guid is changed to a new GUID to avoid 

+       the PAD definition confusing. If there is some problem, try to disable

+       UpdatePadFileGuid

+    

+     

+    

+--*/

+

+#include "SecApResetVectorFixup.h"

+

+

+EFI_GUID  DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f };

+EFI_GUID  NewFvPadFileNameGuid     = { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0x21, 0x27, 0xc3, 0x76, 0xbb, 0x66 };

+

+//

+// jmp 0xf000:0xffd0 (0xFFFFFFD0)

+//

+UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};

+

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n",

+    UTILITY_NAME,

+    UTILITY_MAJOR_VERSION,

+    UTILITY_MINOR_VERSION

+    );

+}

+

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME);

+  printf ("  Where:\n");

+  printf ("\tInputFvrecoveryFile   - Name of the IA32 input Fvrecovery.fv file.\n");

+  printf ("\tOutputFvrecoveryFile  - Name of the IA32 output Fvrecovery.fv file.\n");

+}

+

+

+VOID 

+UpdatePadFileGuid (

+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FvHeader,

+  IN     EFI_FFS_FILE_HEADER         *FileHeader,

+  IN     UINT32                      FileLength,

+  IN OUT EFI_GUID                    *Guid

+  )

+/*++

+

+Routine Description:

+

+  Update the Pad File Guid to change it to other guid and update

+  the checksum

+

+Arguments:

+  FvHeader   - EFI_FIRMWARE_VOLUME_HEADER 

+  FileHeader - The FFS PAD file header.

+  FileLength - The FFS PAD file length.

+  Guid       - The Guid to compare and if it is PAD Guid, update it to new Guid

+Returns:

+  VOID

+--*/

+

+{

+  if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {

+    //

+    // Set new Pad file guid

+    // 

+    memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID));

+

+

+

+    FileHeader->Type       = EFI_FV_FILETYPE_FFS_PAD;

+    FileHeader->Attributes = 0;

+    //

+    // Fill in checksums and state, must be zero during checksum calculation.

+    //

+    FileHeader->IntegrityCheck.Checksum.Header = 0;

+    FileHeader->IntegrityCheck.Checksum.File   = 0;

+    FileHeader->State                          = 0;

+    FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));

+    if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {

+      FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, FileLength);

+    } else {

+      FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

+    }

+

+    FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

+

+    if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {

+      FileHeader->State = (UINT8)~(FileHeader->State);

+    }    

+  }

+  

+}

+

+

+STATUS

+main (

+  IN INTN   argc,

+  IN CHAR8  **argv

+  )

+/*++

+

+Routine Description:

+

+  Main function.

+

+Arguments:

+

+  argc - Number of command line parameters.

+  argv - Array of pointers to parameter strings.

+

+Returns:

+  STATUS_SUCCESS - Utility exits successfully.

+  STATUS_ERROR   - Some error occurred during execution.

+

+--*/

+{

+  FILE                        *FpIn;

+  FILE                        *FpOut;

+  UINT32                      FvrecoveryFileSize;

+  UINT8                       *FileBuffer;

+  UINT8                       *FileBufferRaw;

+  UINT64                      FvLength;

+  UINT32                      Offset;

+  UINT32                      FileLength;

+  UINT32                      FileOccupiedSize;

+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

+  EFI_FFS_FILE_HEADER         *FileHeader;

+  EFI_GUID                    *TempGuid;

+  UINT8                       *FixPoint;

+  UINT32                      TempResult;

+  UINT32                      Index;

+  UINT32                      IpiVector;

+

+  TempGuid = NULL;

+  SetUtilityName (UTILITY_NAME);

+

+  //

+  // Display utility information

+  //

+  PrintUtilityInfo ();

+

+  //

+  // Verify the correct number of arguments

+  //

+  if (argc != MAX_ARGS) {

+    Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);

+    PrintUsage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Open the Input Fvrecovery.fv file

+  //

+  if ((FpIn = fopen (argv[1], "rb")) == NULL) {

+    Error (NULL, 0, 0, "Unable to open file", argv[1]);

+    return STATUS_ERROR;

+  }

+  //

+  // Get the Input Fvrecovery.fv file size

+  //

+  fseek (FpIn, 0, SEEK_END);

+  FvrecoveryFileSize = ftell (FpIn);

+  //

+  // Read the contents of input file to memory buffer

+  //

+  FileBuffer    = NULL;

+  FileBufferRaw = NULL;

+  FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000);

+  if (NULL == FileBufferRaw) {

+    Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);

+    fclose (FpIn);

+    return STATUS_ERROR;

+  }

+  TempResult = 0x10000 - ((UINT32)FileBufferRaw & 0x0FFFF);

+  FileBuffer = (UINT8 *)((UINT32)FileBufferRaw + TempResult);

+  fseek (FpIn, 0, SEEK_SET);

+  TempResult = fread (FileBuffer, 1, FvrecoveryFileSize, FpIn);

+  if (TempResult != FvrecoveryFileSize) {

+    Error (NULL, 0, 0, "Read input file error!", NULL);

+    free ((VOID *)FileBufferRaw);

+    fclose (FpIn);

+    return STATUS_ERROR;

+  }

+  //

+  // Close the input Fvrecovery.fv file

+  //

+  fclose (FpIn);

+  //

+  // Find the pad FFS file

+  //

+  FvHeader         = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer;

+  FvLength         = FvHeader->FvLength;

+  FileHeader       = (EFI_FFS_FILE_HEADER *)(FileBuffer + FvHeader->HeaderLength);

+  FileLength       = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;

+  FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);

+  Offset           = (UINT32)FileHeader - (UINT32)FileBuffer;

+  

+  while (Offset < FvLength) {

+    TempGuid = (EFI_GUID *)&(FileHeader->Name);

+    FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;

+    FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);

+    if ((CompareGuid (TempGuid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {

+      break;

+    }

+    FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize);

+    Offset = (UINT32)FileHeader - (UINT32)FileBuffer;

+  }

+

+  if (Offset >= FvLength) {

+    Error (NULL, 0, 0, "No pad file found!", NULL);

+    free ((VOID *)FileBufferRaw);

+    return STATUS_ERROR;

+  }

+  //

+  // Find the position to place Ap reset vector, the offset

+  // between the position and the end of Fvrecovery.fv file

+  // should not exceed 128kB to prevent Ap reset vector from

+  // outside legacy E and F segment

+  //

+  FixPoint = (UINT8 *)(FileHeader + sizeof(EFI_FFS_FILE_HEADER));

+  TempResult = 0x1000 - ((UINT32)FixPoint & 0x0FFF);

+  FixPoint +=TempResult;

+  if (((UINT32)FixPoint - (UINT32)FileHeader + 5) > FileOccupiedSize) {

+    Error (NULL, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL);

+    free ((VOID *)FileBufferRaw);

+    return STATUS_ERROR;  

+  }

+  while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) {

+    FixPoint += 0x1000;

+  }

+  FixPoint -= 0x1000;

+  if ((UINT32)FvHeader + FvLength - (UINT32)FixPoint > 0x20000) {

+    Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL);

+    free ((VOID *)FileBufferRaw);

+    return STATUS_ERROR; 

+  }  	

+  //

+  // Fix up Ap reset vector and calculate the IPI vector

+  //

+  for (Index = 0; Index < 5; Index++) {

+    FixPoint[Index] = ApResetVector[Index];

+  } 

+  TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint);

+  TempResult >>= 12;

+  IpiVector = TempResult & 0x0FF;

+  

+  

+  UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);

+

+  //

+  // Open the output Fvrecovery.fv file

+  //

+  if ((FpOut = fopen (argv[2], "w+b")) == NULL) {

+    Error (NULL, 0, 0, "Unable to open file", argv[2]);

+    free ((VOID *)FileBufferRaw);

+    return STATUS_ERROR;

+  }

+  //

+  // Write the output Fvrecovery.fv file

+  //

+  if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) {

+    Error (NULL, 0, 0, "Write output file error!", NULL);

+    free ((VOID *)FileBufferRaw);

+    return STATUS_ERROR;   

+  }

+  //

+  //

+  //

+  fseek (FpOut, -8, SEEK_END);

+  if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) {

+    Error (NULL, 0, 0, "Write output file error!", NULL);

+    free ((VOID *)FileBufferRaw);

+    return STATUS_ERROR;

+  }  

+  //

+  // Close the output Fvrecovery.fv file

+  //

+  fclose (FpOut);

+  free ((VOID *)FileBufferRaw);

+  return STATUS_SUCCESS;

+}

+

diff --git a/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.h b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.h
new file mode 100644
index 0000000..a41fc3a
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.h
@@ -0,0 +1,103 @@
+/*++

+

+Copyright (c)  2005 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  

+  SecApResetVectorFixup.h

+

+Abstract:

+

+  Definitions for the SecApResetVectorFixup utility.

+

+--*/

+

+#ifndef _SEC_AP_RESET_VECTOR_FIXUP_H

+#define _SEC_AP_RESET_VECTOR_FIXUP_H

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include "EfiImage.h"

+#include <FirmwareVolumeImageFormat.h>

+#include "FirmwareFileSystem.h"

+#include "FirmwareVolumeHeader.h"

+#include "EfiUtilityMsgs.c"

+#include "CommonLib.h"

+

+

+//

+// Utility Name

+//

+#define UTILITY_NAME  "SecApResetVectorFixup"

+

+//

+// Utility version information

+//

+#define UTILITY_MAJOR_VERSION 0

+#define UTILITY_MINOR_VERSION 1

+#define UTILITY_DATE          __DATE__

+

+//

+// The maximum number of arguments accepted from the command line.

+//

+#define MAX_ARGS        3

+#define BUF_SIZE        (8 * 1024)

+

+#define GETOCCUPIEDSIZE(ActualSize, Alignment) \

+  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))

+

+

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+;

+

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+;

+

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/build.xml b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/build.xml
new file mode 100644
index 0000000..3df9dcc
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecApResetVectorFixup/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK SecApResetVectorFixup Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="SecApResetVectorFixup"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/SecFixup/Makefile b/edk2/Tools/Source/TianoTools/SecFixup/Makefile
new file mode 100644
index 0000000..6ae2ebd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecFixup/Makefile
@@ -0,0 +1,57 @@
+#/*++

+#   

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Target specific information

+#

+

+TARGET_NAME         = SecFixup

+TARGET_SOURCE_DIR   = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+TARGET_EXE          = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+TARGET_EXE_SOURCE   = $(TARGET_SOURCE_DIR)\$(TARGET_NAME).c

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+OBJECTS   = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj  

+

+#

+# Build EXE

+#

+

+$(OBJECTS) : $(TARGET_EXE_SOURCE) $(INC_DEPS)

+  $(CC) $(C_FLAGS) $(TARGET_EXE_SOURCE) /Fo$@

+

+$(TARGET_EXE): $(OBJECTS)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(OBJECTS) $(LIBS) /out:$(TARGET_EXE)

+

+clean:

+  @if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/SecFixup/SecFixup.c b/edk2/Tools/Source/TianoTools/SecFixup/SecFixup.c
new file mode 100644
index 0000000..96faaf0
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecFixup/SecFixup.c
@@ -0,0 +1,363 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+    SecFixup.c

+

+Abstract:

+

+    This utility is part of build process for IA32 SEC FFS file.

+    

+    It fixup the reset vector data. The reset vector data binary file

+    will be wrapped as a RAW section and be located immediately after

+    the PE/TE section.

+

+    The SEC EXE file can be either PE or TE file.

+    

+--*/

+

+#include <stdio.h>

+

+#include <UefiBaseTypes.h>

+#include <Base.h>

+#include "EfiImage.h"

+#include "FirmwareVolumeImageFormat.h"

+#include "EfiUtilityMsgs.c"

+

+#include "SecFixup.h"

+

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the standard utility information to SDTOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf (

+    "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",

+    UTILITY_NAME,

+    UTILITY_MAJOR_VERSION,

+    UTILITY_MINOR_VERSION

+    );

+}

+

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Displays the utility usage syntax to STDOUT

+

+Arguments:

+

+  None

+

+Returns:

+

+  None

+

+--*/

+{

+  printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME);

+  printf ("  Where:\n");

+  printf ("\tSecExeFile           - Name of the IA32 SEC EXE file.\n");

+  printf ("\tResetVectorDataFile  - Name of the reset vector data binary file.\n");

+  printf ("\tOutputFileName       - Name of the output file.\n\n");

+}

+

+STATUS

+main (

+  IN INTN   argc,

+  IN CHAR8  **argv

+  )

+/*++

+

+Routine Description:

+

+  Main function.

+

+Arguments:

+

+  argc - Number of command line parameters.

+  argv - Array of pointers to parameter strings.

+

+Returns:

+  STATUS_SUCCESS - Utility exits successfully.

+  STATUS_ERROR   - Some error occurred during execution.

+

+--*/

+{

+  FILE    *FpIn;

+

+  FILE    *FpOut;

+  UINT32  AddressOfEntryPoint;

+  INT32   DestRel;

+  STATUS  Status;

+  UINT32  SecFileSize;

+

+  SetUtilityName (UTILITY_NAME);

+

+  //

+  // Display utility information

+  //

+  PrintUtilityInfo ();

+

+  //

+  // Verify the correct number of arguments

+  //

+  if (argc != MAX_ARGS) {

+    Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);

+    PrintUsage ();

+    return STATUS_ERROR;

+  }

+  //

+  // Open the SEC exe file

+  //

+  if ((FpIn = fopen (argv[1], "rb")) == NULL) {

+    Error (NULL, 0, 0, "Unable to open file", argv[1]);

+    return STATUS_ERROR;

+  }

+  //

+  // Get the entry point of the EXE file

+  //

+  Status = GetEntryPoint (FpIn, &AddressOfEntryPoint);

+  if (Status != STATUS_SUCCESS) {

+    fclose (FpIn);

+    return STATUS_ERROR;

+  }

+  //

+  // Get the SEC file size

+  //

+  fseek (FpIn, 0, SEEK_END);

+  SecFileSize = ftell (FpIn);

+

+  //

+  // Close the SEC file

+  //

+  fclose (FpIn);

+

+  //

+  // Open the reset vector data file

+  //

+  if ((FpIn = fopen (argv[2], "rb")) == NULL) {

+    Error (NULL, 0, 0, "Unable to open file", argv[2]);

+    return STATUS_ERROR;

+  }

+  //

+  // Open the output file

+  //

+  if ((FpOut = fopen (argv[3], "w+b")) == NULL) {

+    Error (NULL, 0, 0, "Unable to open file", argv[3]);

+    fclose (FpIn);

+    return STATUS_ERROR;

+  }

+  //

+  // Copy the input file to the output file

+  //

+  if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) {

+    fclose (FpIn);

+    fclose (FpOut);

+    return STATUS_ERROR;

+  }

+  //

+  // Close the reset vector data file

+  //

+  fclose (FpIn);

+

+  //

+  // Fix the destination relative in the jmp instruction

+  // in the reset vector data structure

+  //

+  fseek (FpOut, -DEST_REL_OFFSET, SEEK_END);

+  DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2);

+  if (DestRel <= -65536) {

+    Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL);

+    fclose (FpOut);

+    return STATUS_ERROR;

+  }

+

+  if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) {

+    Error (NULL, 0, 0, "Failed to write to the output file", NULL);

+    fclose (FpOut);

+    return STATUS_ERROR;

+  }

+  //

+  // Close the output file

+  //

+  fclose (FpOut);

+

+  return STATUS_SUCCESS;

+}

+

+STATUS

+GetEntryPoint (

+  IN  FILE   *ExeFile,

+  OUT UINT32 *EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  Get the address of the entry point of a PE/TE file.

+

+Arguments:

+

+  PeFile     - File pointer to the specified PE/TE file.

+  EntryPoint - Buffer for the address of the entry point to be returned.

+

+Returns:

+  STATUS_SUCCESS - Function completed successfully.

+  STATUS_ERROR   - Error occured.

+

+--*/

+// GC_TODO:    ExeFile - add argument and description to function comment

+{

+  EFI_IMAGE_DOS_HEADER    DosHeader;

+  EFI_IMAGE_NT_HEADERS32  NtHeader;

+  EFI_TE_IMAGE_HEADER     TeHeader;

+

+  //

+  // Check if it is a TE file

+  //

+  fseek (ExeFile, 0, SEEK_SET);

+  //

+  // Attempt to read the TE header

+  //

+  if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) {

+    if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {

+      if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) {

+        Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);

+        return STATUS_ERROR;

+      }

+

+      *EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize;

+      return STATUS_SUCCESS;

+    }

+  }

+  //

+  // Check if it is a PE file

+  //

+  fseek (ExeFile, 0, SEEK_SET);

+  //

+  // Attempt to read the DOS header

+  //

+  if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) {

+    goto InvalidFile;

+  }

+  //

+  // Check the magic number

+  //

+  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {

+    goto InvalidFile;

+  }

+  //

+  // Position into the file and read the NT PE header

+  //

+  fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET);

+  if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) {

+    goto InvalidFile;

+  }

+  //

+  // Check the PE signature in the header

+  //

+  if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) {

+    goto InvalidFile;

+  }

+  //

+  // Make sure the PE file is PE32 for IA32

+  //

+  if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 ||

+      NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC

+      ) {

+    Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // Get the entry point from the optional header

+  //

+  *EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint;

+  return STATUS_SUCCESS;

+

+InvalidFile:

+  Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL);

+  return STATUS_ERROR;

+}

+

+STATUS

+CopyFile (

+  FILE    *FpIn,

+  FILE    *FpOut

+  )

+/*++

+

+Routine Description:

+

+  Copy file.

+

+Arguments:

+

+  FpIn  - File pointer to the source file.

+  FpOut - File pointer to the destination file.

+

+Returns:

+  STATUS_SUCCESS - Function completed successfully.

+  STATUS_ERROR   - Error occured.

+

+--*/

+{

+  INTN  FileSize;

+

+  INTN  Offset;

+

+  INTN  Length;

+  UINT8 Buffer[BUF_SIZE];

+

+  fseek (FpIn, 0, SEEK_END);

+  FileSize = ftell (FpIn);

+

+  fseek (FpIn, 0, SEEK_SET);

+  fseek (FpOut, 0, SEEK_SET);

+

+  Offset = 0;

+  while (Offset < FileSize) {

+    Length = sizeof (Buffer);

+    if (FileSize - Offset < Length) {

+      Length = FileSize - Offset;

+    }

+

+    if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) {

+      Error (NULL, 0, 0, "Copy file error", NULL);

+      return STATUS_ERROR;

+    }

+

+    Offset += Length;

+  }

+

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/SecFixup/SecFixup.h b/edk2/Tools/Source/TianoTools/SecFixup/SecFixup.h
new file mode 100644
index 0000000..5571dc3
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecFixup/SecFixup.h
@@ -0,0 +1,146 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  

+  SecFixup.h

+

+Abstract:

+

+  Definitions for the SecFixup utility.

+

+--*/

+

+#ifndef _SEC_FIXUP_H

+#define _SEC_FIXUP_H

+

+//

+// Utility Name

+//

+#define UTILITY_NAME  "SecFixup"

+

+//

+// Utility version information

+//

+#define UTILITY_MAJOR_VERSION 0

+#define UTILITY_MINOR_VERSION 1

+#define UTILITY_DATE          __DATE__

+

+//

+// The maximum number of arguments accepted from the command line.

+//

+#define MAX_ARGS        4

+

+#define DEST_REL_OFFSET 13

+#define BUF_SIZE        (8 * 1024)

+

+//

+// The function that displays general utility information

+//

+VOID

+PrintUtilityInfo (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+//

+// The function that displays the utility usage message.

+//

+VOID

+PrintUsage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  None

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+//

+// The function that gets the entry point of a PE/TE file.

+//

+STATUS

+GetEntryPoint (

+  IN  FILE   *ExeFile,

+  OUT UINT32 *EntryPoint

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  ExeFile     - GC_TODO: add argument description

+  EntryPoint  - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+//

+// The function that copies a file.

+//

+STATUS

+CopyFile (

+  FILE    *FpIn,

+  FILE    *FpOut

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  FpIn  - GC_TODO: add argument description

+  FpOut - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+;

+

+#endif

diff --git a/edk2/Tools/Source/TianoTools/SecFixup/build.xml b/edk2/Tools/Source/TianoTools/SecFixup/build.xml
new file mode 100644
index 0000000..2594fdd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SecFixup/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK SecFixup Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="SecFixup"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/SetStamp/SetStamp.c b/edk2/Tools/Source/TianoTools/SetStamp/SetStamp.c
new file mode 100644
index 0000000..539aced
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SetStamp/SetStamp.c
@@ -0,0 +1,475 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+  SetStamp.c

+

+Abstract:

+  Set Date/Time Stamp of Portable Executable (PE) format file

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <time.h>

+

+#define LINE_MAXLEN 80

+

+void

+PrintUsage (

+  void

+  )

+/*++

+Routine Description:

+  print usage of setstamp command

+

+Arguments:

+  void

+

+Returns:

+  None

+--*/

+{

+  //

+  // print usage of command

+  //

+  printf ("Usage: SetStamp <PE-File> <TIME-File>\n");

+}

+

+int

+GetDateTime (

+  FILE      *fp,

+  time_t    *ltime

+  )

+/*++

+Routine Description:

+  Read the date and time from TIME file. If the date/time string is

+"NOW NOW", write the current date and time to TIME file and set it to

+ltime. Else, set the date and time of TIME file to ltime.

+

+Arguments:

+  fp              - The pointer of TIME file

+  ltime           - Date and time

+

+Returns:

+  =  0            - Success

+  = -1            - Failed

+--*/

+{

+  char      buffer[LINE_MAXLEN];

+  struct tm stime;

+  struct tm *now;

+

+  if (fgets (buffer, LINE_MAXLEN, fp) == NULL) {

+    printf ("Error: Cannot read TIME file.\n");

+    return -1;

+  }

+  //

+  // compare the value with "NOW NOW", write TIME file if equal

+  //

+  if (strncmp (buffer, "NOW NOW", 7) == 0) {

+    //

+    // get system current time and date

+    //

+    time (ltime);

+

+    now = localtime (ltime);

+    if (now == NULL) {

+      printf ("Error: Cannot get local time.\n");

+      return -1;

+    }

+

+    if (strftime (buffer, LINE_MAXLEN, "%Y-%m-%d %H:%M:%S", now) == 0) {

+      printf ("Error: Cannot format time string.\n");

+      return -1;

+    }

+    //

+    // write TIME file

+    //

+    if (fseek (fp, 0, SEEK_SET) != 0) {

+      printf ("Error: Cannot move location of TIME file.\n");

+      return -1;

+    }

+

+    if (fputs (buffer, fp) == EOF) {

+      printf ("Error: Cannot write time string to TIME file.\n");

+      return -1;

+    }

+    //

+    // ltime has been set as current time and date, return

+    //

+    return 0;

+  }

+  //

+  // get the date and time from buffer

+  //

+  if (6 != sscanf (

+            buffer,

+            "%d-%d-%d %d:%d:%d",

+            &stime.tm_year,

+            &stime.tm_mon,

+            &stime.tm_mday,

+            &stime.tm_hour,

+            &stime.tm_min,

+            &stime.tm_sec

+            )) {

+    printf ("Error: Invaild date or time!\n");

+    return -1;

+  }

+  //

+  // in struct, Month (0 - 11; Jan = 0). So decrease 1 from it

+  //

+  stime.tm_mon -= 1;

+

+  //

+  // in struct, Year (current year minus 1900)

+  // and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038

+  //

+  //

+  // convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038)

+  //

+  if (stime.tm_year <= 38) {

+    stime.tm_year += 100;

+  }

+  //

+  // convert 1970 -> 70, 2000 -> 100, ...

+  //

+  else if (stime.tm_year >= 1970) {

+    stime.tm_year -= 1900;

+  }

+  //

+  // convert the date and time to time_t format

+  //

+  *ltime = mktime (&stime);

+  if (*ltime == (time_t) - 1) {

+    printf ("Error: Invalid date or time!\n");

+    return -1;

+  }

+

+  return 0;

+}

+

+int

+ReadFromFile (

+  FILE      *fp,

+  long      offset,

+  void      *buffer,

+  int       size

+  )

+/*++

+Routine Description:

+  read data from a specified location of file

+

+Arguments:

+  fp              - file pointer

+  offset          - number of bytes from beginning of file

+  buffer          - buffer used to store data

+  size            - size of buffer

+

+Returns:

+  =  0            - Success

+  = -1            - Failed

+--*/

+{

+  //

+  // set file pointer to the specified location of file

+  //

+  if (fseek (fp, offset, SEEK_SET) != 0) {

+    printf ("Error: Cannot move the current location of the file.\n");

+    return -1;

+  }

+  //

+  // read data from the file

+  //

+  if (fread (buffer, size, 1, fp) != 1) {

+    printf ("Error: Cannot read data from the file.\n");

+    return -1;

+  }

+

+  return 0;

+}

+

+int

+WriteToFile (

+  FILE      *fp,

+  long      offset,

+  void      *buffer,

+  int       size

+  )

+/*++

+Routine Description:

+  write data to a specified location of file

+

+Arguments:

+  fp              - file pointer

+  offset          - number of bytes from beginning of file

+  buffer          - buffer used to store data

+  size            - size of buffer

+

+Returns:

+  =  0            - Success

+  = -1            - Failed

+--*/

+{

+  //

+  // set file pointer to the specified location of file

+  //

+  if (fseek (fp, offset, SEEK_SET) != 0) {

+    printf ("Error: Cannot move the current location of the file.\n");

+    return -1;

+  }

+  //

+  // write data to the file

+  //

+  if (fwrite (buffer, size, 1, fp) != 1) {

+    perror ("Error: Cannot write data to the file.\n");

+    return -1;

+  }

+

+  return 0;

+}

+

+int

+SetStamp (

+  FILE      *fp,

+  time_t    ltime

+  )

+/*++

+Routine Description:

+  set Date/Time Stamp of the file

+

+Arguments:

+  fp              - file pointer

+  ltime           - time and date

+

+Returns:

+  =  0            - Success

+  = -1            - Failed

+--*/

+{

+  unsigned char header[4];

+  unsigned long offset;

+  unsigned long NumberOfRvaAndSizes;

+  unsigned int  nvalue;

+  unsigned long lvalue;

+

+  //

+  // read the header of file

+  //

+  if (ReadFromFile (fp, 0, header, 2) != 0) {

+    return -1;

+  }

+  //

+  // "MZ" -- the header of image file (PE)

+  //

+  if (strncmp ((char *) header, "MZ", 2) != 0) {

+    printf ("Error: Invalid Image file.\n");

+    return -1;

+  }

+  //

+  // At location 0x3C, the stub has the file offset to the

+  // PE signature.

+  //

+  if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) {

+    return -1;

+  }

+  //

+  // read the header of optional

+  //

+  if (ReadFromFile (fp, offset, header, 4) != 0) {

+    return -1;

+  }

+  //

+  // "PE\0\0" -- the signature of optional header

+  //

+  if (strncmp ((char *) header, "PE\0\0", 4) != 0) {

+    printf ("Error: Invalid PE format file.\n");

+    return -1;

+  }

+  //

+  // Add 8 to skip PE signature (4-byte), Machine (2-byte) and

+  // NumberOfSection (2-byte)

+  //

+  offset += 8;

+

+  if (WriteToFile (fp, offset, &ltime, 4) != 0) {

+    return -1;

+  }

+  //

+  // Add 16 to skip COFF file header, and get to optional header.

+  //

+  offset += 16;

+

+  //

+  // Check the magic field, 0x10B for PE32 and 0x20B for PE32+

+  //

+  if (ReadFromFile (fp, offset, &nvalue, 2) != 0) {

+    return -1;

+  }

+  //

+  // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92.

+  // Else it is 108.

+  //

+  switch (nvalue & 0xFFFF) {

+  case 0x10B:

+    offset += 92;

+    break;

+

+  case 0x20B:

+    offset += 108;

+    break;

+

+  default:

+    printf ("Error: Sorry! The Magic value is unknown.\n");

+    return -1;

+  }

+  //

+  // get the value of NumberOfRvaAndSizes

+  //

+  if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) {

+    return -1;

+  }

+  //

+  // Date/time stamp exists in Export Table, Import Table, Resource Table,

+  // Debug Table and Delay Import Table. And in Import Table and Delay Import

+  // Table, it will be set when bound. So here only set the date/time stamp

+  // of Export Table, Resource Table and Debug Table.

+  //

+  //

+  // change date/time stamp of Export Table, the offset of Export Table

+  // is 4 + 0 * 8 = 4. And the offset of stamp is 4.

+  //

+  if (NumberOfRvaAndSizes >= 1) {

+    if (ReadFromFile (fp, offset + 4, &lvalue, 4) != 0) {

+      return -1;

+    }

+

+    if (lvalue != 0) {

+      if (WriteToFile (fp, lvalue + 4, &ltime, 4) != 0) {

+        return -1;

+      }

+    }

+  }

+  //

+  // change date/time stamp of Resource Table, the offset of Resource Table

+  // is 4 + 2 * 8 = 20. And the offset of stamp is 4.

+  //

+  if (NumberOfRvaAndSizes >= 3) {

+    if (ReadFromFile (fp, offset + 20, &lvalue, 4) != 0) {

+      return -1;

+    }

+

+    if (lvalue != 0) {

+      if (WriteToFile (fp, lvalue + 4, &ltime, 4) != 0) {

+        return -1;

+      }

+    }

+  }

+  //

+  // change date/time stamp of Debug Table, offset of Debug Table

+  // is 4 + 6 * 8 = 52. And the offset of stamp is 4.

+  //

+  if (NumberOfRvaAndSizes >= 7) {

+    if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) {

+      return -1;

+    }

+

+    if (lvalue != 0) {

+      if (WriteToFile (fp, lvalue + 4, &ltime, 4) != 0) {

+        return -1;

+      }

+    }

+    //

+    // change the date/time stamp of Debug Data

+    //

+    if (ReadFromFile (fp, lvalue + 24, &lvalue, 4) != 0) {

+      return -1;

+    }

+    //

+    // get the signature of debug data

+    //

+    if (ReadFromFile (fp, lvalue, header, 2) != 0) {

+      return -1;

+    }

+    //

+    // "NB" - the signature of Debug Data

+    // Need Review: (From Spec. is "NB05", From .dll is "NB10")

+    //

+    if (strncmp ((char *) header, "NB", 2) == 0) {

+      if (WriteToFile (fp, lvalue + 8, &ltime, 4) != 0) {

+        return -1;

+      }

+    }

+  }

+

+  return 0;

+}

+

+int

+main (

+  int       argc,

+  char      *argv[]

+  )

+{

+  FILE    *fp;

+  time_t  ltime;

+

+  //

+  // check the number of parameters

+  //

+  if (argc != 3) {

+    PrintUsage ();

+    return -1;

+  }

+  //

+  // open the TIME file, if not exists, return

+  //

+  fp = fopen (argv[2], "r+");

+  if (fp == NULL) {

+    return 0;

+  }

+  //

+  // get time and date from file

+  //

+  if (GetDateTime (fp, &ltime) != 0) {

+    fclose (fp);

+    return -1;

+  }

+  //

+  // close the TIME file

+  //

+  fclose (fp);

+

+  //

+  // open the PE file

+  //

+  fp = fopen (argv[1], "r+b");

+  if (fp == NULL) {

+    printf ("Error: Cannot open the PE file!\n");

+    return -1;

+  }

+  //

+  // set time and date stamp to the PE file

+  //

+  if (SetStamp (fp, ltime) != 0) {

+    fclose (fp);

+    return -1;

+  }

+

+  printf ("Set Date/Time Stamp to %s", ctime (&ltime));

+

+  //

+  // close the PE file

+  //

+  fclose (fp);

+

+  return 0;

+}

diff --git a/edk2/Tools/Source/TianoTools/SetStamp/build.xml b/edk2/Tools/Source/TianoTools/SetStamp/build.xml
new file mode 100644
index 0000000..6e4aecb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SetStamp/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK SetStamp Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="SetStamp"/>

+  <property name="FileSet" value="SetStamp.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+		<if>

+		  <equals arg1="${ToolChain}" arg2="msvc"/>

+			<then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+			</then>

+			<elseif>

+			  <equals arg1="${ToolChain}" arg2="gcc"/>

+				<then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+				</then>

+			</elseif>

+		</if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+			<libset dir="${LIB_DIR}" libs="CommonTools"/>

+

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/SplitFile/Makefile b/edk2/Tools/Source/TianoTools/SplitFile/Makefile
new file mode 100644
index 0000000..3cd45f9
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SplitFile/Makefile
@@ -0,0 +1,70 @@
+#/*++

+#   

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Define some macros we use here. Should get rid of them someday and 

+# get rid of the extra level of indirection.

+#

+COMMON_SOURCE      = $(EDK_TOOLS_COMMON)

+

+#

+# Common information

+#

+

+INC=$(INC)

+

+#

+# Target specific information

+#

+

+TARGET_NAME=SplitFile

+TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+

+TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\SplitFile.c"

+TARGET_EXE_INCLUDE = 

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+#

+# Build EXE

+#

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj

+

+$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/SplitFile/SplitFile.c b/edk2/Tools/Source/TianoTools/SplitFile/SplitFile.c
new file mode 100644
index 0000000..b1af1a8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SplitFile/SplitFile.c
@@ -0,0 +1,131 @@
+/*

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+*/

+

+// GC_TODO: fix comment to start with /*++

+#include "stdio.h"

+#include "string.h"

+#include "stdlib.h"

+

+void

+helpmsg (

+  void

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  printf (

+    "SplitFile Filename Offset\n""   Filename = Input file to split\n""   Offset = offset at which to split file\n"

+    "\n\n""SplitFile will break a file in two pieces at the requested offset\n"

+    "  outputting Filename1 and Filename2\n"

+    );

+}

+

+int

+main (

+  int argc,

+  char*argv[]

+  )

+/*++

+

+Routine Description:

+

+  GC_TODO: Add function description

+

+Arguments:

+

+  argc  - GC_TODO: add argument description

+  ]     - GC_TODO: add argument description

+

+Returns:

+

+  GC_TODO: add return values

+

+--*/

+{

+  FILE          *In;

+

+  FILE          *Out1;

+

+  FILE          *Out2;

+  char          OutName1[512];

+  char          OutName2[512];

+  unsigned long Index;

+  unsigned long splitpoint;

+  char          CharC;

+

+  if (argc != 3) {

+    helpmsg ();

+    return -1;

+  }

+

+  In = fopen (argv[1], "rb");

+  if (In == NULL) {

+    printf ("Unable to open file \"%s\"\n", argv[1]);

+    return -1;

+  }

+

+  strncpy (OutName1, argv[1], 510);

+  strncpy (OutName2, argv[1], 510);

+  strcat (OutName1, "1");

+  strcat (OutName2, "2");

+

+  Out1 = fopen (OutName1, "wb");

+  if (Out1 == NULL) {

+    printf ("Unable to open file \"%s\"\n", OutName1);

+    return -1;

+  }

+

+  Out2 = fopen (OutName2, "wb");

+  if (Out2 == NULL) {

+    printf ("Unable to open file \"%s\"\n", OutName2);

+    return -1;

+  }

+

+  splitpoint = atoi (argv[2]);

+

+  for (Index = 0; Index < splitpoint; Index++) {

+    CharC = (char) fgetc (In);

+    if (feof (In)) {

+      break;

+    }

+

+    fputc (CharC, Out1);

+  }

+

+  for (;;) {

+    CharC = (char) fgetc (In);

+    if (feof (In)) {

+      break;

+    }

+

+    fputc (CharC, Out2);

+  }

+

+  fclose (In);

+  fclose (Out1);

+  fclose (Out2);

+

+  return 0;

+}

diff --git a/edk2/Tools/Source/TianoTools/SplitFile/build.xml b/edk2/Tools/Source/TianoTools/SplitFile/build.xml
new file mode 100644
index 0000000..51adc21
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/SplitFile/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK SplitFile Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="SplitFile"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/StrGather/StrGather.c b/edk2/Tools/Source/TianoTools/StrGather/StrGather.c
new file mode 100644
index 0000000..1fc204d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/StrGather/StrGather.c
@@ -0,0 +1,2531 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StrGather.c  

+

+Abstract:

+

+  Parse a strings file and create or add to a string database file.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <ctype.h>

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <CommonLib.h>

+#include "EfiUtilityMsgs.h"

+#include "StrGather.h"

+#include "StringDB.h"

+

+#define TOOL_VERSION  "0.31"

+

+#ifndef MAX_PATH

+#define MAX_PATH                    255

+#endif

+#define MAX_NEST_DEPTH              20  // just in case we get in an endless loop.

+#define MAX_STRING_IDENTIFIER_NAME  100 // number of wchars

+#define MAX_LINE_LEN                200

+#define STRING_TOKEN                "STRING_TOKEN"

+#define DEFAULT_BASE_NAME           "BaseName"

+//

+// Operational modes for this utility

+//

+#define MODE_UNKNOWN  0

+#define MODE_PARSE    1

+#define MODE_SCAN     2

+#define MODE_DUMP     3

+

+//

+// We keep a linked list of these for the source files we process

+//

+typedef struct _SOURCE_FILE {

+  FILE                *Fptr;

+  WCHAR               *FileBuffer;

+  WCHAR               *FileBufferPtr;

+  UINT32              FileSize;

+  INT8                FileName[MAX_PATH];

+  UINT32              LineNum;

+  BOOLEAN             EndOfFile;

+  BOOLEAN             SkipToHash;

+  struct _SOURCE_FILE *Previous;

+  struct _SOURCE_FILE *Next;

+  WCHAR               ControlCharacter;

+} SOURCE_FILE;

+

+#define DEFAULT_CONTROL_CHARACTER UNICODE_SLASH

+

+//

+// Here's all our globals. We need a linked list of include paths, a linked

+// list of source files, a linked list of subdirectories (appended to each

+// include path when searching), and a couple other fields.

+//

+static struct {

+  SOURCE_FILE                 SourceFiles;

+  TEXT_STRING_LIST            *IncludePaths;                    // all include paths to search

+  TEXT_STRING_LIST            *LastIncludePath;

+  TEXT_STRING_LIST            *ScanFileName;

+  TEXT_STRING_LIST            *LastScanFileName;

+  TEXT_STRING_LIST            *SkipExt;                         // if -skipext .uni

+  TEXT_STRING_LIST            *LastSkipExt;

+  TEXT_STRING_LIST            *IndirectionFileName;

+  TEXT_STRING_LIST            *LastIndirectionFileName;

+  TEXT_STRING_LIST            *DatabaseFileName;

+  TEXT_STRING_LIST            *LastDatabaseFileName;

+  WCHAR_STRING_LIST           *Language;

+  WCHAR_STRING_LIST           *LastLanguage;

+  WCHAR_MATCHING_STRING_LIST  *IndirectionList;                 // from indirection file(s)

+  WCHAR_MATCHING_STRING_LIST  *LastIndirectionList;

+  BOOLEAN                     Verbose;                          // for more detailed output

+  BOOLEAN                     VerboseDatabaseWrite;             // for more detailed output when writing database

+  BOOLEAN                     VerboseDatabaseRead;              // for more detailed output when reading database

+  BOOLEAN                     NewDatabase;                      // to start from scratch

+  BOOLEAN                     IgnoreNotFound;                   // when scanning

+  BOOLEAN                     VerboseScan;

+  BOOLEAN                     UnquotedStrings;                  // -uqs option

+  INT8                        OutputDatabaseFileName[MAX_PATH];

+  INT8                        StringHFileName[MAX_PATH];

+  INT8                        StringCFileName[MAX_PATH];        // output .C filename

+  INT8                        DumpUFileName[MAX_PATH];          // output unicode dump file name

+  INT8                        HiiExportPackFileName[MAX_PATH];  // HII export pack file name

+  INT8                        BaseName[MAX_PATH];               // base filename of the strings file

+  UINT32                      Mode;

+} mGlobals;

+

+static

+BOOLEAN

+IsValidIdentifierChar (

+  INT8      Char,

+  BOOLEAN   FirstChar

+  );

+

+static

+void

+RewindFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+SkipTo (

+  SOURCE_FILE *SourceFile,

+  WCHAR       WChar,

+  BOOLEAN     StopAfterNewline

+  );

+

+static

+UINT32

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+IsWhiteSpace (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+PreprocessFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+UINT32

+GetStringIdentifierName (

+  IN SOURCE_FILE  *SourceFile,

+  IN OUT WCHAR    *StringIdentifierName,

+  IN UINT32       StringIdentifierNameLen

+  );

+

+static

+UINT32

+GetLanguageIdentifierName (

+  IN SOURCE_FILE  *SourceFile,

+  IN OUT WCHAR    *LanguageIdentifierName,

+  IN UINT32       LanguageIdentifierNameLen,

+  IN BOOLEAN      Optional

+  );

+

+static

+WCHAR *

+GetPrintableLanguageName (

+  IN SOURCE_FILE  *SourceFile

+  );

+

+static

+STATUS

+AddCommandLineLanguage (

+  IN INT8          *Language

+  );

+

+static

+WCHAR *

+GetQuotedString (

+  SOURCE_FILE *SourceFile,

+  BOOLEAN     Optional

+  );

+

+static

+STATUS

+ProcessIncludeFile (

+  SOURCE_FILE *SourceFile,

+  SOURCE_FILE *ParentSourceFile

+  );

+

+static

+STATUS

+ParseFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+FILE  *

+FindFile (

+  IN INT8     *FileName,

+  OUT INT8    *FoundFileName,

+  IN UINT32   FoundFileNameLen

+  );

+

+static

+STATUS

+ProcessArgs (

+  int   Argc,

+  char  *Argv[]

+  );

+

+static

+STATUS

+ProcessFile (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+UINT32

+wstrcmp (

+  WCHAR *Buffer,

+  WCHAR *Str

+  );

+

+static

+void

+Usage (

+  VOID

+  );

+

+static

+void

+FreeLists (

+  VOID

+  );

+

+static

+void

+ProcessTokenString (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+ProcessTokenInclude (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+ProcessTokenScope (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+ProcessTokenLanguage (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+void

+ProcessTokenLangDef (

+  SOURCE_FILE *SourceFile

+  );

+

+static

+STATUS

+ScanFiles (

+  TEXT_STRING_LIST *ScanFiles

+  );

+

+static

+STATUS

+ParseIndirectionFiles (

+  TEXT_STRING_LIST    *Files

+  );

+

+STATUS

+StringDBCreateHiiExportPack (

+  INT8                *OutputFileName

+  );

+

+int

+main (

+  int   Argc,

+  char  *Argv[]

+  )

+/*++

+

+Routine Description:

+

+  Call the routine to parse the command-line options, then process the file.

+  

+Arguments:

+

+  Argc - Standard C main() argc and argv.

+  Argv - Standard C main() argc and argv.

+

+Returns:

+

+  0       if successful

+  nonzero otherwise

+  

+--*/

+{

+  STATUS  Status;

+

+  SetUtilityName (PROGRAM_NAME);

+  //

+  // Process the command-line arguments

+  //

+  Status = ProcessArgs (Argc, Argv);

+  if (Status != STATUS_SUCCESS) {

+    return Status;

+  }

+  //

+  // Initialize the database manager

+  //

+  StringDBConstructor ();

+  //

+  // We always try to read in an existing database file. It may not

+  // exist, which is ok usually.

+  //

+  if (mGlobals.NewDatabase == 0) {

+    //

+    // Read all databases specified.

+    //

+    for (mGlobals.LastDatabaseFileName = mGlobals.DatabaseFileName;

+         mGlobals.LastDatabaseFileName != NULL;

+         mGlobals.LastDatabaseFileName = mGlobals.LastDatabaseFileName->Next

+        ) {

+      Status = StringDBReadDatabase (mGlobals.LastDatabaseFileName->Str, TRUE, mGlobals.VerboseDatabaseRead);

+      if (Status != STATUS_SUCCESS) {

+        return Status;

+      }

+    }

+  }

+  //

+  // Read indirection file(s) if specified

+  //

+  if (ParseIndirectionFiles (mGlobals.IndirectionFileName) != STATUS_SUCCESS) {

+    goto Finish;

+  }

+  //

+  // If scanning source files, do that now

+  //

+  if (mGlobals.Mode == MODE_SCAN) {

+    ScanFiles (mGlobals.ScanFileName);

+  } else if (mGlobals.Mode == MODE_PARSE) {

+    //

+    // Parsing a unicode strings file

+    //

+    mGlobals.SourceFiles.ControlCharacter = DEFAULT_CONTROL_CHARACTER;

+    Status = ProcessIncludeFile (&mGlobals.SourceFiles, NULL);

+    if (Status != STATUS_SUCCESS) {

+      goto Finish;

+    }

+  }

+  //

+  // Create the string defines header file if there have been no errors.

+  //

+  ParserSetPosition (NULL, 0);

+  if ((mGlobals.StringHFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {

+    Status = StringDBDumpStringDefines (mGlobals.StringHFileName, mGlobals.BaseName);

+    if (Status != EFI_SUCCESS) {

+      goto Finish;

+    }

+  }

+  //

+  // Dump the strings to a .c file if there have still been no errors.

+  //

+  if ((mGlobals.StringCFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {

+    Status = StringDBDumpCStrings (

+              mGlobals.StringCFileName,

+              mGlobals.BaseName,

+              mGlobals.Language,

+              mGlobals.IndirectionList

+              );

+    if (Status != EFI_SUCCESS) {

+      goto Finish;

+    }

+  }

+  //

+  // Dump the database if requested

+  //

+  if ((mGlobals.DumpUFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {

+    StringDBDumpDatabase (NULL, mGlobals.DumpUFileName, FALSE);

+  }

+  //

+  // Dump the string data as HII binary string pack if requested

+  //

+  if ((mGlobals.HiiExportPackFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) {

+    StringDBCreateHiiExportPack (mGlobals.HiiExportPackFileName);

+  }

+  //

+  // Always update the database if no errors and not in dump mode. If they specified -od

+  // for an output database file name, then use that name. Otherwise use the name of

+  // the first database file specified with -db

+  //

+  if ((mGlobals.Mode != MODE_DUMP) && (GetUtilityStatus () < STATUS_ERROR)) {

+    if (mGlobals.OutputDatabaseFileName[0]) {

+      Status = StringDBWriteDatabase (mGlobals.OutputDatabaseFileName, mGlobals.VerboseDatabaseWrite);

+    } else {

+      Status = StringDBWriteDatabase (mGlobals.DatabaseFileName->Str, mGlobals.VerboseDatabaseWrite);

+    }

+

+    if (Status != EFI_SUCCESS) {

+      goto Finish;

+    }

+  }

+

+Finish:

+  //

+  // Free up memory

+  //

+  FreeLists ();

+  StringDBDestructor ();

+  return GetUtilityStatus ();

+}

+

+static

+STATUS

+ProcessIncludeFile (

+  SOURCE_FILE *SourceFile,

+  SOURCE_FILE *ParentSourceFile

+  )

+/*++

+

+Routine Description:

+

+  Given a source file, open the file and parse it

+  

+Arguments:

+

+  SourceFile        - name of file to parse

+  ParentSourceFile  - for error reporting purposes, the file that #included SourceFile.

+

+Returns:

+

+  Standard status.

+  

+--*/

+{

+  static UINT32 NestDepth = 0;

+  INT8          FoundFileName[MAX_PATH];

+  STATUS        Status;

+

+  Status = STATUS_SUCCESS;

+  NestDepth++;

+  //

+  // Print the file being processed. Indent so you can tell the include nesting

+  // depth.

+  //

+  if (mGlobals.Verbose) {

+    fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);

+  }

+

+  //

+  // Make sure we didn't exceed our maximum nesting depth

+  //

+  if (NestDepth > MAX_NEST_DEPTH) {

+    Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);

+    Status = STATUS_ERROR;

+    goto Finish;

+  }

+  //

+  // Try to open the file locally, and if that fails try along our include paths.

+  //

+  strcpy (FoundFileName, SourceFile->FileName);

+  if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) {

+    //

+    // Try to find it among the paths if it has a parent (that is, it is included

+    // by someone else).

+    //

+    if (ParentSourceFile == NULL) {

+      Error (NULL, 0, 0, SourceFile->FileName, "file not found");

+      return STATUS_ERROR;

+    }

+

+    SourceFile->Fptr = FindFile (SourceFile->FileName, FoundFileName, sizeof (FoundFileName));

+    if (SourceFile->Fptr == NULL) {

+      Error (ParentSourceFile->FileName, ParentSourceFile->LineNum, 0, SourceFile->FileName, "include file not found");

+      return STATUS_ERROR;

+    }

+  }

+  //

+  // Process the file found

+  //

+  ProcessFile (SourceFile);

+Finish:

+  //

+  // Close open files and return status

+  //

+  if (SourceFile->Fptr != NULL) {

+    fclose (SourceFile->Fptr);

+  }

+

+  return Status;

+}

+

+static

+STATUS

+ProcessFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  //

+  // Get the file size, and then read the entire thing into memory.

+  // Allocate space for a terminator character.

+  //

+  fseek (SourceFile->Fptr, 0, SEEK_END);

+  SourceFile->FileSize = ftell (SourceFile->Fptr);

+  fseek (SourceFile->Fptr, 0, SEEK_SET);

+  SourceFile->FileBuffer = (WCHAR *) malloc (SourceFile->FileSize + sizeof (WCHAR));

+  if (SourceFile->FileBuffer == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return STATUS_ERROR;

+  }

+

+  fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);

+  SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (WCHAR))] = UNICODE_NULL;

+  //

+  // Pre-process the file to replace comments with spaces

+  //

+  PreprocessFile (SourceFile);

+  //

+  // Parse the file

+  //

+  ParseFile (SourceFile);

+  free (SourceFile->FileBuffer);

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+ParseFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  BOOLEAN InComment;

+  UINT32  Len;

+

+  //

+  // First character of a unicode file is special. Make sure

+  //

+  if (SourceFile->FileBufferPtr[0] != UNICODE_FILE_START) {

+    Error (SourceFile->FileName, 1, 0, SourceFile->FileName, "file does not appear to be a unicode file");

+    return STATUS_ERROR;

+  }

+

+  SourceFile->FileBufferPtr++;

+  InComment = FALSE;

+  //

+  // Print the first line if in verbose mode

+  //

+  if (mGlobals.Verbose) {

+    printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);

+  }

+  //

+  // Since the syntax is relatively straightforward, just switch on the next char

+  //

+  while (!EndOfFile (SourceFile)) {

+    //

+    // Check for whitespace

+    //

+    if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) {

+      SourceFile->FileBufferPtr++;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_TAB) {

+      SourceFile->FileBufferPtr++;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {

+      SourceFile->FileBufferPtr++;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      if (mGlobals.Verbose) {

+        printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);

+      }

+

+      InComment = FALSE;

+    } else if (SourceFile->FileBufferPtr[0] == 0) {

+      SourceFile->FileBufferPtr++;

+    } else if (InComment) {

+      SourceFile->FileBufferPtr++;

+    } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) {

+      SourceFile->FileBufferPtr += 2;

+      InComment = TRUE;

+    } else if (SourceFile->SkipToHash && (SourceFile->FileBufferPtr[0] != SourceFile->ControlCharacter)) {

+      SourceFile->FileBufferPtr++;

+    } else {

+      SourceFile->SkipToHash = FALSE;

+      if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+          ((Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"include")) > 0)

+          ) {

+        SourceFile->FileBufferPtr += Len + 1;

+        ProcessTokenInclude (SourceFile);

+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"scope")) > 0

+              ) {

+        SourceFile->FileBufferPtr += Len + 1;

+        ProcessTokenScope (SourceFile);

+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"language")) > 0

+              ) {

+        SourceFile->FileBufferPtr += Len + 1;

+        ProcessTokenLanguage (SourceFile);

+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"langdef")) > 0

+              ) {

+        SourceFile->FileBufferPtr += Len + 1;

+        ProcessTokenLangDef (SourceFile);

+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"string")) > 0

+              ) {

+        SourceFile->FileBufferPtr += Len + 1;

+        ProcessTokenString (SourceFile);

+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+               (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"EFI_BREAKPOINT()")) > 0

+              ) {

+        SourceFile->FileBufferPtr += Len;

+        //

+        // BUGBUG: Caling EFI_BREAKOINT() is breaking the link.  What is the proper action for this tool

+        // in this condition?

+        //

+//        EFI_BREAKPOINT ();

+      } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) &&

+               (SourceFile->FileBufferPtr[1] == UNICODE_EQUAL_SIGN)

+              ) {

+        SourceFile->ControlCharacter = SourceFile->FileBufferPtr[2];

+        SourceFile->FileBufferPtr += 3;

+      } else {

+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "unrecognized token", "%S", SourceFile->FileBufferPtr);

+        //

+        // Treat rest of line as a comment.

+        //

+        InComment = TRUE;

+      }

+    }

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+void

+PreprocessFile (

+  SOURCE_FILE *SourceFile

+  )

+/*++

+

+Routine Description:

+  Preprocess a file to replace all carriage returns with NULLs so

+  we can print lines from the file to the screen.

+  

+Arguments:

+  SourceFile - structure that we use to keep track of an input file.

+

+Returns:

+  Nothing.

+  

+--*/

+{

+  BOOLEAN InComment;

+

+  RewindFile (SourceFile);

+  InComment = FALSE;

+  while (!EndOfFile (SourceFile)) {

+    //

+    // If a line-feed, then no longer in a comment

+    //

+    if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      InComment = 0;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {

+      //

+      // Replace all carriage returns with a NULL so we can print stuff

+      //

+      SourceFile->FileBufferPtr[0] = 0;

+      SourceFile->FileBufferPtr++;

+    } else if (InComment) {

+      SourceFile->FileBufferPtr[0] = UNICODE_SPACE;

+      SourceFile->FileBufferPtr++;

+    } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) {

+      SourceFile->FileBufferPtr += 2;

+      InComment = TRUE;

+    } else {

+      SourceFile->FileBufferPtr++;

+    }

+  }

+  //

+  // Could check for end-of-file and still in a comment, but

+  // should not be necessary. So just restore the file pointers.

+  //

+  RewindFile (SourceFile);

+}

+

+static

+WCHAR *

+GetPrintableLanguageName (

+  IN SOURCE_FILE  *SourceFile

+  )

+{

+  WCHAR   *String;

+  WCHAR   *Start;

+  WCHAR   *Ptr;

+  UINT32  Len;

+

+  SkipWhiteSpace (SourceFile);

+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      "expected quoted printable language name",

+      "%S",

+      SourceFile->FileBufferPtr

+      );

+    SourceFile->SkipToHash = TRUE;

+    return NULL;

+  }

+

+  Len = 0;

+  SourceFile->FileBufferPtr++;

+  Start = Ptr = SourceFile->FileBufferPtr;

+  while (!EndOfFile (SourceFile)) {

+    if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {

+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);

+      break;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {

+      break;

+    }

+

+    SourceFile->FileBufferPtr++;

+    Len++;

+  }

+

+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {

+    Warning (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      "missing closing quote on printable language name string",

+      "%S",

+      Start

+      );

+  } else {

+    SourceFile->FileBufferPtr++;

+  }

+  //

+  // Now allocate memory for the string and save it off

+  //

+  String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));

+  if (String == NULL) {

+    Error (NULL, 0, 0, "memory allocation failed", NULL);

+    return NULL;

+  }

+  //

+  // Copy the string from the file buffer to the local copy.

+  // We do no reformatting of it whatsoever at this point.

+  //

+  Ptr = String;

+  while (Len > 0) {

+    *Ptr = *Start;

+    Start++;

+    Ptr++;

+    Len--;

+  }

+

+  *Ptr = 0;

+  //

+  // Now format the string to convert \wide and \narrow controls

+  //

+  StringDBFormatString (String);

+  return String;

+}

+

+static

+WCHAR *

+GetQuotedString (

+  SOURCE_FILE *SourceFile,

+  BOOLEAN     Optional

+  )

+{

+  WCHAR   *String;

+  WCHAR   *Start;

+  WCHAR   *Ptr;

+  UINT32  Len;

+  BOOLEAN PreviousBackslash;

+

+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {

+    if (!Optional) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);

+    }

+

+    return NULL;

+  }

+

+  Len = 0;

+  SourceFile->FileBufferPtr++;

+  Start             = Ptr = SourceFile->FileBufferPtr;

+  PreviousBackslash = FALSE;

+  while (!EndOfFile (SourceFile)) {

+    if ((SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) && (!PreviousBackslash)) {

+      break;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) {

+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);

+      PreviousBackslash = FALSE;

+    } else if (SourceFile->FileBufferPtr[0] == UNICODE_BACKSLASH) {

+      PreviousBackslash = TRUE;

+    } else {

+      PreviousBackslash = FALSE;

+    }

+

+    SourceFile->FileBufferPtr++;

+    Len++;

+  }

+

+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {

+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);

+  } else {

+    SourceFile->FileBufferPtr++;

+  }

+  //

+  // Now allocate memory for the string and save it off

+  //

+  String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));

+  if (String == NULL) {

+    Error (NULL, 0, 0, "memory allocation failed", NULL);

+    return NULL;

+  }

+  //

+  // Copy the string from the file buffer to the local copy.

+  // We do no reformatting of it whatsoever at this point.

+  //

+  Ptr = String;

+  while (Len > 0) {

+    *Ptr = *Start;

+    Start++;

+    Ptr++;

+    Len--;

+  }

+

+  *Ptr = 0;

+  return String;

+}

+//

+// Parse:

+//    #string STR_ID_NAME

+//

+// All we can do is call the string database to add the string identifier. Unfortunately

+// he'll have to keep track of the last identifier we added.

+//

+static

+void

+ProcessTokenString (

+  SOURCE_FILE *SourceFile

+  )

+{

+  WCHAR   StringIdentifier[MAX_STRING_IDENTIFIER_NAME];

+  UINT16  StringId;

+  //

+  // Extract the string identifier name and add it to the database.

+  //

+  if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) {

+    StringId = STRING_ID_INVALID;

+    StringDBAddStringIdentifier (StringIdentifier, &StringId, 0);

+  } else {

+    //

+    // Error recovery -- skip to the next #

+    //

+    SourceFile->SkipToHash = TRUE;

+  }

+}

+

+static

+BOOLEAN

+EndOfFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  //

+  // The file buffer pointer will typically get updated before the End-of-file flag in the

+  // source file structure, so check it first.

+  //

+  if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (WCHAR)) {

+    SourceFile->EndOfFile = TRUE;

+    return TRUE;

+  }

+

+  if (SourceFile->EndOfFile) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+static

+UINT32

+GetStringIdentifierName (

+  IN SOURCE_FILE  *SourceFile,

+  IN OUT WCHAR    *StringIdentifierName,

+  IN UINT32       StringIdentifierNameLen

+  )

+{

+  UINT32  Len;

+  WCHAR   *From;

+  WCHAR   *Start;

+

+  //

+  // Skip whitespace

+  //

+  SkipWhiteSpace (SourceFile);

+  if (SourceFile->EndOfFile) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected string identifier");

+    return 0;

+  }

+  //

+  // Verify first character of name is [A-Za-z]

+  //

+  Len = 0;

+  StringIdentifierNameLen /= 2;

+  From  = SourceFile->FileBufferPtr;

+  Start = SourceFile->FileBufferPtr;

+  if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||

+      ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z))

+      ) {

+    //

+    // Do nothing

+    //

+  } else {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid character in string identifier name", "%S", Start);

+    return 0;

+  }

+

+  while (!EndOfFile (SourceFile)) {

+    if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) ||

+        ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) ||

+        ((SourceFile->FileBufferPtr[0] >= UNICODE_0) && (SourceFile->FileBufferPtr[0] <= UNICODE_9)) ||

+        (SourceFile->FileBufferPtr[0] == UNICODE_UNDERSCORE)

+        ) {

+      Len++;

+      if (Len >= StringIdentifierNameLen) {

+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "string identifier name too long", "%S", Start);

+        return 0;

+      }

+

+      *StringIdentifierName = SourceFile->FileBufferPtr[0];

+      StringIdentifierName++;

+      SourceFile->FileBufferPtr++;

+    } else if (SkipWhiteSpace (SourceFile) == 0) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid string identifier name", "%S", Start);

+      return 0;

+    } else {

+      break;

+    }

+  }

+  //

+  // Terminate the copy of the string.

+  //

+  *StringIdentifierName = 0;

+  return Len;

+}

+

+static

+UINT32

+GetLanguageIdentifierName (

+  IN SOURCE_FILE  *SourceFile,

+  IN OUT WCHAR    *LanguageIdentifierName,

+  IN UINT32       LanguageIdentifierNameLen,

+  IN BOOLEAN      Optional

+  )

+{

+  UINT32  Len;

+  WCHAR   *From;

+  WCHAR   *Start;

+  //

+  // Skip whitespace

+  //

+  SkipWhiteSpace (SourceFile);

+  if (SourceFile->EndOfFile) {

+    if (!Optional) {

+      Error (

+        SourceFile->FileName,

+        SourceFile->LineNum,

+        0,

+        "end-of-file encountered",

+        "expected language identifier"

+        );

+    }

+

+    return 0;

+  }

+  //

+  // This function is called to optionally get a language identifier name in:

+  //   #string STR_ID eng "the string"

+  // If it's optional, and we find a double-quote, then return now.

+  //

+  if (Optional) {

+    if (*SourceFile->FileBufferPtr == UNICODE_DOUBLE_QUOTE) {

+      return 0;

+    }

+  }

+

+  Len = 0;

+  LanguageIdentifierNameLen /= 2;

+  //

+  // Internal error if we weren't given at least 4 WCHAR's to work with.

+  //

+  if (LanguageIdentifierNameLen < LANGUAGE_IDENTIFIER_NAME_LEN + 1) {

+    Error (

+      SourceFile->FileName,

+      SourceFile->LineNum,

+      0,

+      "app error -- language identifier name length is invalid",

+      NULL

+      );

+  }

+

+  From  = SourceFile->FileBufferPtr;

+  Start = SourceFile->FileBufferPtr;

+  while (!EndOfFile (SourceFile)) {

+    if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z))) {

+      Len++;

+      if (Len > LANGUAGE_IDENTIFIER_NAME_LEN) {

+        Error (SourceFile->FileName, SourceFile->LineNum, 0, "language identifier name too long", "%S", Start);

+        return 0;

+      }

+

+      *LanguageIdentifierName = SourceFile->FileBufferPtr[0];

+      SourceFile->FileBufferPtr++;

+      LanguageIdentifierName++;

+    } else if (!IsWhiteSpace (SourceFile)) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid language identifier name", "%S", Start);

+      return 0;

+    } else {

+      break;

+    }

+  }

+  //

+  // Terminate the copy of the string.

+  //

+  *LanguageIdentifierName = 0;

+  return Len;

+}

+

+static

+void

+ProcessTokenInclude (

+  SOURCE_FILE *SourceFile

+  )

+{

+  INT8        IncludeFileName[MAX_PATH];

+  INT8        *To;

+  UINT32      Len;

+  BOOLEAN     ReportedError;

+  SOURCE_FILE IncludedSourceFile;

+

+  ReportedError = FALSE;

+  if (SkipWhiteSpace (SourceFile) == 0) {

+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);

+  }

+  //

+  // Should be quoted file name

+  //

+  if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);

+    goto FailDone;

+  }

+

+  SourceFile->FileBufferPtr++;

+  //

+  // Copy the filename as ascii to our local string

+  //

+  To  = IncludeFileName;

+  Len = 0;

+  while (!EndOfFile (SourceFile)) {

+    if ((SourceFile->FileBufferPtr[0] == UNICODE_CR) || (SourceFile->FileBufferPtr[0] == UNICODE_LF)) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);

+      goto FailDone;

+    }

+

+    if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {

+      SourceFile->FileBufferPtr++;

+      break;

+    }

+    //

+    // If too long, then report the error once and process until the closing quote

+    //

+    Len++;

+    if (!ReportedError && (Len >= sizeof (IncludeFileName))) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);

+      ReportedError = TRUE;

+    }

+

+    if (!ReportedError) {

+      *To = UNICODE_TO_ASCII (SourceFile->FileBufferPtr[0]);

+      To++;

+    }

+

+    SourceFile->FileBufferPtr++;

+  }

+

+  if (!ReportedError) {

+    *To = 0;

+    memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));

+    strcpy (IncludedSourceFile.FileName, IncludeFileName);

+    IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER;

+    ProcessIncludeFile (&IncludedSourceFile, SourceFile);

+    //

+    // printf ("including file '%s'\n", IncludeFileName);

+    //

+  }

+

+  return ;

+FailDone:

+  //

+  // Error recovery -- skip to next #

+  //

+  SourceFile->SkipToHash = TRUE;

+}

+

+static

+void

+ProcessTokenScope (

+  SOURCE_FILE *SourceFile

+  )

+{

+  WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME];

+  //

+  // Extract the scope name

+  //

+  if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) {

+    StringDBSetScope (StringIdentifier);

+  }

+}

+//

+// Parse:  #langdef eng "English"

+//         #langdef chn "\wideChinese"

+//

+static

+void

+ProcessTokenLangDef (

+  SOURCE_FILE *SourceFile

+  )

+{

+  WCHAR   LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME];

+  UINT32  Len;

+  WCHAR   *PrintableName;

+  //

+  // Extract the 3-character language identifier

+  //

+  Len = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE);

+  if (Len != LANGUAGE_IDENTIFIER_NAME_LEN) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid or missing language identifier", NULL);

+  } else {

+    //

+    // Extract the printable name

+    //

+    PrintableName = GetPrintableLanguageName (SourceFile);

+    if (PrintableName != NULL) {

+      ParserSetPosition (SourceFile->FileName, SourceFile->LineNum);

+      StringDBAddLanguage (LanguageIdentifier, PrintableName);

+      free (PrintableName);

+      return ;

+    }

+  }

+  //

+  // Error recovery -- skip to next #

+  //

+  SourceFile->SkipToHash = TRUE;

+}

+

+static

+BOOLEAN

+ApparentQuotedString (

+  SOURCE_FILE *SourceFile

+  )

+{

+  WCHAR *Ptr;

+  //

+  // See if the first and last nonblank characters on the line are double quotes

+  //

+  for (Ptr = SourceFile->FileBufferPtr; *Ptr && (*Ptr == UNICODE_SPACE); Ptr++)

+    ;

+  if (*Ptr != UNICODE_DOUBLE_QUOTE) {

+    return FALSE;

+  }

+

+  while (*Ptr) {

+    Ptr++;

+  }

+

+  Ptr--;

+  for (; *Ptr && (*Ptr == UNICODE_SPACE); Ptr--)

+    ;

+  if (*Ptr != UNICODE_DOUBLE_QUOTE) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+//

+// Parse:

+//   #language eng "some string " "more string"

+//

+static

+void

+ProcessTokenLanguage (

+  SOURCE_FILE *SourceFile

+  )

+{

+  WCHAR   *String;

+  WCHAR   *SecondString;

+  WCHAR   *TempString;

+  WCHAR   *From;

+  WCHAR   *To;

+  WCHAR   Language[LANGUAGE_IDENTIFIER_NAME_LEN + 1];

+  UINT32  Len;

+  BOOLEAN PreviousNewline;

+  //

+  // Get the language identifier

+  //

+  Language[0] = 0;

+  Len         = GetLanguageIdentifierName (SourceFile, Language, sizeof (Language), TRUE);

+  if (Len != LANGUAGE_IDENTIFIER_NAME_LEN) {

+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid or missing language identifier", "%S", Language);

+    SourceFile->SkipToHash = TRUE;

+    return ;

+  }

+  //

+  // Extract the string value. It's either a quoted string that starts on the current line, or

+  // an unquoted string that starts on the following line and continues until the next control

+  // character in column 1.

+  // Look ahead to find a quote or a newline

+  //

+  if (SkipTo (SourceFile, UNICODE_DOUBLE_QUOTE, TRUE)) {

+    String = GetQuotedString (SourceFile, FALSE);

+    if (String != NULL) {

+      //

+      // Set the position in the file of where we are parsing for error

+      // reporting purposes. Then start looking ahead for additional

+      // quoted strings, and concatenate them until we get a failure

+      // back from the string parser.

+      //

+      Len = StrLen (String) + 1;

+      ParserSetPosition (SourceFile->FileName, SourceFile->LineNum);

+      do {

+        SkipWhiteSpace (SourceFile);

+        SecondString = GetQuotedString (SourceFile, TRUE);

+        if (SecondString != NULL) {

+          Len += StrLen (SecondString);

+          TempString = (WCHAR *) malloc (Len * sizeof (WCHAR));

+          if (TempString == NULL) {

+            Error (NULL, 0, 0, "application error", "failed to allocate memory");

+            return ;

+          }

+

+          StrCpy (TempString, String);

+          StrCat (TempString, SecondString);

+          free (String);

+          free (SecondString);

+          String = TempString;

+        }

+      } while (SecondString != NULL);

+      StringDBAddString (Language, NULL, NULL, String, TRUE, 0);

+      free (String);

+    } else {

+      //

+      // Error was reported at lower level. Error recovery mode.

+      //

+      SourceFile->SkipToHash = TRUE;

+    }

+  } else {

+    if (!mGlobals.UnquotedStrings) {

+      //

+      // They're using unquoted strings. If the next non-blank character is a double quote, and the

+      // last non-blank character on the line is a double quote, then more than likely they're using

+      // quotes, so they need to put the quoted string on the end of the previous line

+      //

+      if (ApparentQuotedString (SourceFile)) {

+        Warning (

+          SourceFile->FileName,

+          SourceFile->LineNum,

+          0,

+          "unexpected quoted string on line",

+          "specify -uqs option if necessary"

+          );

+      }

+    }

+    //

+    // Found end-of-line (hopefully). Skip over it and start taking in characters

+    // until we find a control character at the start of a line.

+    //

+    Len             = 0;

+    From            = SourceFile->FileBufferPtr;

+    PreviousNewline = FALSE;

+    while (!EndOfFile (SourceFile)) {

+      if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {

+        PreviousNewline = TRUE;

+        SourceFile->LineNum++;

+      } else {

+        Len++;

+        if (PreviousNewline && (SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter)) {

+          break;

+        }

+

+        PreviousNewline = FALSE;

+      }

+

+      SourceFile->FileBufferPtr++;

+    }

+

+    if ((Len == 0) && EndOfFile (SourceFile)) {

+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "unexpected end of file", NULL);

+      SourceFile->SkipToHash = TRUE;

+      return ;

+    }

+    //

+    // Now allocate a buffer, copy the characters, and add the string.

+    //

+    String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR));

+    if (String == NULL) {

+      Error (NULL, 0, 0, "application error", "failed to allocate memory");

+      return ;

+    }

+

+    To = String;

+    while (From < SourceFile->FileBufferPtr) {

+      switch (*From) {

+      case UNICODE_LF:

+      case 0:

+        break;

+

+      default:

+        *To = *From;

+        To++;

+        break;

+      }

+

+      From++;

+    }

+

+    //

+    // String[Len] = 0;

+    //

+    *To = 0;

+    StringDBAddString (Language, NULL, NULL, String, TRUE, 0);

+  }

+}

+

+static

+BOOLEAN

+IsWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+{

+  switch (SourceFile->FileBufferPtr[0]) {

+  case UNICODE_NULL:

+  case UNICODE_CR:

+  case UNICODE_SPACE:

+  case UNICODE_TAB:

+  case UNICODE_LF:

+    return TRUE;

+

+  default:

+    return FALSE;

+  }

+}

+

+static

+UINT32

+SkipWhiteSpace (

+  SOURCE_FILE *SourceFile

+  )

+{

+  UINT32  Count;

+

+  Count = 0;

+  while (!EndOfFile (SourceFile)) {

+    Count++;

+    switch (*SourceFile->FileBufferPtr) {

+    case UNICODE_NULL:

+    case UNICODE_CR:

+    case UNICODE_SPACE:

+    case UNICODE_TAB:

+      SourceFile->FileBufferPtr++;

+      break;

+

+    case UNICODE_LF:

+      SourceFile->FileBufferPtr++;

+      SourceFile->LineNum++;

+      if (mGlobals.Verbose) {

+        printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr);

+      }

+      break;

+

+    default:

+      return Count - 1;

+    }

+  }

+  //

+  // Some tokens require trailing whitespace. If we're at the end of the

+  // file, then we count that as well.

+  //

+  if ((Count == 0) && (EndOfFile (SourceFile))) {

+    Count++;

+  }

+

+  return Count;

+}

+

+static

+UINT32

+wstrcmp (

+  WCHAR *Buffer,

+  WCHAR *Str

+  )

+{

+  UINT32  Len;

+

+  Len = 0;

+  while (*Str == *Buffer) {

+    Buffer++;

+    Str++;

+    Len++;

+  }

+

+  if (*Str) {

+    return 0;

+  }

+

+  return Len;

+}

+//

+// Given a filename, try to find it along the include paths.

+//

+static

+FILE *

+FindFile (

+  IN INT8    *FileName,

+  OUT INT8   *FoundFileName,

+  IN UINT32  FoundFileNameLen

+  )

+{

+  FILE              *Fptr;

+  TEXT_STRING_LIST  *List;

+

+  //

+  // Traverse the list of paths and try to find the file

+  //

+  List = mGlobals.IncludePaths;

+  while (List != NULL) {

+    //

+    // Put the path and filename together

+    //

+    if (strlen (List->Str) + strlen (FileName) + 1 > FoundFileNameLen) {

+      Error (PROGRAM_NAME, 0, 0, NULL, "internal error - cannot concatenate path+filename");

+      return NULL;

+    }

+    //

+    // Append the filename to this include path and try to open the file.

+    //

+    strcpy (FoundFileName, List->Str);

+    strcat (FoundFileName, FileName);

+    if ((Fptr = fopen (FoundFileName, "rb")) != NULL) {

+      //

+      // Return the file pointer

+      //

+      return Fptr;

+    }

+

+    List = List->Next;

+  }

+  //

+  // Not found

+  //

+  FoundFileName[0] = 0;

+  return NULL;

+}

+//

+// Process the command-line arguments

+//

+static

+STATUS

+ProcessArgs (

+  int   Argc,

+  char  *Argv[]

+  )

+{

+  TEXT_STRING_LIST  *NewList;

+  //

+  // Clear our globals

+  //

+  memset ((char *) &mGlobals, 0, sizeof (mGlobals));

+  strcpy (mGlobals.BaseName, DEFAULT_BASE_NAME);

+  //

+  // Skip program name

+  //

+  Argc--;

+  Argv++;

+

+  if (Argc == 0) {

+    Usage ();

+    return STATUS_ERROR;

+  }

+

+  mGlobals.Mode = MODE_UNKNOWN;

+  //

+  // Process until no more -args.

+  //

+  while ((Argc > 0) && (Argv[0][0] == '-')) {

+    //

+    // -parse option

+    //

+    if (stricmp (Argv[0], "-parse") == 0) {

+      if (mGlobals.Mode != MODE_UNKNOWN) {

+        Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL);

+        return STATUS_ERROR;

+      }

+

+      mGlobals.Mode = MODE_PARSE;

+      //

+      // -scan option

+      //

+    } else if (stricmp (Argv[0], "-scan") == 0) {

+      if (mGlobals.Mode != MODE_UNKNOWN) {

+        Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL);

+        return STATUS_ERROR;

+      }

+

+      mGlobals.Mode = MODE_SCAN;

+      //

+      // -vscan verbose scanning option

+      //

+    } else if (stricmp (Argv[0], "-vscan") == 0) {

+      mGlobals.VerboseScan = TRUE;

+      //

+      // -dump option

+      //

+    } else if (stricmp (Argv[0], "-dump") == 0) {

+      if (mGlobals.Mode != MODE_UNKNOWN) {

+        Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL);

+        return STATUS_ERROR;

+      }

+

+      mGlobals.Mode = MODE_DUMP;

+    } else if (stricmp (Argv[0], "-uqs") == 0) {

+      mGlobals.UnquotedStrings = TRUE;

+      //

+      // -i path    add include search path when parsing

+      //

+    } else if (stricmp (Argv[0], "-i") == 0) {

+      //

+      // check for one more arg

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing include path");

+        return STATUS_ERROR;

+      }

+      //

+      // Allocate memory for a new list element, fill it in, and

+      // add it to our list of include paths. Always make sure it

+      // has a "\" on the end of it.

+      //

+      NewList = malloc (sizeof (TEXT_STRING_LIST));

+      if (NewList == NULL) {

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));

+      NewList->Str = malloc (strlen (Argv[1]) + 2);

+      if (NewList->Str == NULL) {

+        free (NewList);

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      strcpy (NewList->Str, Argv[1]);

+      if (NewList->Str[strlen (NewList->Str) - 1] != '\\') {

+        strcat (NewList->Str, "\\");

+      }

+      //

+      // Add it to our linked list

+      //

+      if (mGlobals.IncludePaths == NULL) {

+        mGlobals.IncludePaths = NewList;

+      } else {

+        mGlobals.LastIncludePath->Next = NewList;

+      }

+

+      mGlobals.LastIncludePath = NewList;

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-if") == 0) {

+      //

+      // Indirection file -- check for one more arg

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing indirection file name");

+        return STATUS_ERROR;

+      }

+      //

+      // Allocate memory for a new list element, fill it in, and

+      // add it to our list of include paths. Always make sure it

+      // has a "\" on the end of it.

+      //

+      NewList = malloc (sizeof (TEXT_STRING_LIST));

+      if (NewList == NULL) {

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));

+      NewList->Str = malloc (strlen (Argv[1]) + 1);

+      if (NewList->Str == NULL) {

+        free (NewList);

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      strcpy (NewList->Str, Argv[1]);

+      //

+      // Add it to our linked list

+      //

+      if (mGlobals.IndirectionFileName == NULL) {

+        mGlobals.IndirectionFileName = NewList;

+      } else {

+        mGlobals.LastIndirectionFileName->Next = NewList;

+      }

+

+      mGlobals.LastIndirectionFileName = NewList;

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-db") == 0) {

+      //

+      // -db option to specify a database file.

+      // Check for one more arg (the database file name)

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database file name");

+        return STATUS_ERROR;

+      }

+

+      NewList = malloc (sizeof (TEXT_STRING_LIST));

+      if (NewList == NULL) {

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));

+      NewList->Str = malloc (strlen (Argv[1]) + 1);

+      if (NewList->Str == NULL) {

+        free (NewList);

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      strcpy (NewList->Str, Argv[1]);

+      //

+      // Add it to our linked list

+      //

+      if (mGlobals.DatabaseFileName == NULL) {

+        mGlobals.DatabaseFileName = NewList;

+      } else {

+        mGlobals.LastDatabaseFileName->Next = NewList;

+      }

+

+      mGlobals.LastDatabaseFileName = NewList;

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-ou") == 0) {

+      //

+      // -ou option to specify an output unicode file to

+      // which we can dump our database.

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database dump output file name");

+        return STATUS_ERROR;

+      }

+

+      if (mGlobals.DumpUFileName[0] == 0) {

+        strcpy (mGlobals.DumpUFileName, Argv[1]);

+      } else {

+        Error (PROGRAM_NAME, 0, 0, Argv[1], "-ou option already specified with '%s'", mGlobals.DumpUFileName);

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-hpk") == 0) {

+      //

+      // -hpk option to create an HII export pack of the input database file

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing raw string data dump output file name");

+        return STATUS_ERROR;

+      }

+

+      if (mGlobals.HiiExportPackFileName[0] == 0) {

+        strcpy (mGlobals.HiiExportPackFileName, Argv[1]);

+      } else {

+        Error (PROGRAM_NAME, 0, 0, Argv[1], "-or option already specified with '%s'", mGlobals.HiiExportPackFileName);

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if ((stricmp (Argv[0], "-?") == 0) || (stricmp (Argv[0], "-h") == 0)) {

+      Usage ();

+      return STATUS_ERROR;

+    } else if (stricmp (Argv[0], "-v") == 0) {

+      mGlobals.Verbose = 1;

+    } else if (stricmp (Argv[0], "-vdbw") == 0) {

+      mGlobals.VerboseDatabaseWrite = 1;

+    } else if (stricmp (Argv[0], "-vdbr") == 0) {

+      mGlobals.VerboseDatabaseRead = 1;

+    } else if (stricmp (Argv[0], "-newdb") == 0) {

+      mGlobals.NewDatabase = 1;

+    } else if (stricmp (Argv[0], "-ignorenotfound") == 0) {

+      mGlobals.IgnoreNotFound = 1;

+    } else if (stricmp (Argv[0], "-oc") == 0) {

+      //

+      // check for one more arg

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output C filename");

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.StringCFileName, Argv[1]);

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-bn") == 0) {

+      //

+      // check for one more arg

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing base name");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.BaseName, Argv[1]);

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-oh") == 0) {

+      //

+      // -oh to specify output .h defines file name

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output .h filename");

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.StringHFileName, Argv[1]);

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-skipext") == 0) {

+      //

+      // -skipext to skip scanning of files with certain filename extensions

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing filename extension");

+        return STATUS_ERROR;

+      }

+      //

+      // Allocate memory for a new list element, fill it in, and

+      // add it to our list of excluded extensions. Always make sure it

+      // has a "." as the first character.

+      //

+      NewList = malloc (sizeof (TEXT_STRING_LIST));

+      if (NewList == NULL) {

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST));

+      NewList->Str = malloc (strlen (Argv[1]) + 2);

+      if (NewList->Str == NULL) {

+        free (NewList);

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+

+      if (Argv[1][0] == '.') {

+        strcpy (NewList->Str, Argv[1]);

+      } else {

+        NewList->Str[0] = '.';

+        strcpy (NewList->Str + 1, Argv[1]);

+      }

+      //

+      // Add it to our linked list

+      //

+      if (mGlobals.SkipExt == NULL) {

+        mGlobals.SkipExt = NewList;

+      } else {

+        mGlobals.LastSkipExt->Next = NewList;

+      }

+

+      mGlobals.LastSkipExt = NewList;

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-lang") == 0) {

+      //

+      // "-lang eng" or "-lang spa+cat" to only output certain languages

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing language name");

+        Usage ();

+        return STATUS_ERROR;

+      }

+

+      if (AddCommandLineLanguage (Argv[1]) != STATUS_SUCCESS) {

+        return STATUS_ERROR;

+      }

+

+      Argc--;

+      Argv++;

+    } else if (stricmp (Argv[0], "-od") == 0) {

+      //

+      // Output database file name -- check for another arg

+      //

+      if ((Argc <= 1) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output database file name");

+        return STATUS_ERROR;

+      }

+

+      strcpy (mGlobals.OutputDatabaseFileName, Argv[1]);

+      Argv++;

+      Argc--;

+    } else {

+      //

+      // Unrecognized arg

+      //

+      Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option");

+      Usage ();

+      return STATUS_ERROR;

+    }

+

+    Argv++;

+    Argc--;

+  }

+  //

+  // Make sure they specified the mode parse/scan/dump

+  //

+  if (mGlobals.Mode == MODE_UNKNOWN) {

+    Error (NULL, 0, 0, "must specify one of -parse/-scan/-dump", NULL);

+    return STATUS_ERROR;

+  }

+  //

+  // All modes require a database filename

+  //

+  if (mGlobals.DatabaseFileName == 0) {

+    Error (NULL, 0, 0, "must specify a database filename using -db DbFileName", NULL);

+    Usage ();

+    return STATUS_ERROR;

+  }

+  //

+  // If dumping the database file, then return immediately if all

+  // parameters check out.

+  //

+  if (mGlobals.Mode == MODE_DUMP) {

+    //

+    // Not much use if they didn't specify -oh or -oc or -ou or -hpk

+    //

+    if ((mGlobals.DumpUFileName[0] == 0) &&

+        (mGlobals.StringHFileName[0] == 0) &&

+        (mGlobals.StringCFileName[0] == 0) &&

+        (mGlobals.HiiExportPackFileName[0] == 0)

+        ) {

+      Error (NULL, 0, 0, "-dump without -oc/-oh/-ou/-hpk is a NOP", NULL);

+      return STATUS_ERROR;

+    }

+

+    return STATUS_SUCCESS;

+  }

+  //

+  // Had to specify source string file and output string defines header filename.

+  //

+  if (mGlobals.Mode == MODE_SCAN) {

+    if (Argc < 1) {

+      Error (PROGRAM_NAME, 0, 0, NULL, "must specify at least one source file to scan with -scan");

+      Usage ();

+      return STATUS_ERROR;

+    }

+    //

+    // Get the list of filenames

+    //

+    while (Argc > 0) {

+      NewList = malloc (sizeof (TEXT_STRING_LIST));

+      if (NewList == NULL) {

+        Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL);

+        return STATUS_ERROR;

+      }

+

+      memset (NewList, 0, sizeof (TEXT_STRING_LIST));

+      NewList->Str = (UINT8 *) malloc (strlen (Argv[0]) + 1);

+      if (NewList->Str == NULL) {

+        Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL);

+        return STATUS_ERROR;

+      }

+

+      strcpy (NewList->Str, Argv[0]);

+      if (mGlobals.ScanFileName == NULL) {

+        mGlobals.ScanFileName = NewList;

+      } else {

+        mGlobals.LastScanFileName->Next = NewList;

+      }

+

+      mGlobals.LastScanFileName = NewList;

+      Argc--;

+      Argv++;

+    }

+  } else {

+    //

+    // Parse mode -- must specify an input unicode file name

+    //

+    if (Argc < 1) {

+      Error (PROGRAM_NAME, 0, 0, NULL, "must specify input unicode string file name with -parse");

+      Usage ();

+      return STATUS_ERROR;

+    }

+

+    strcpy (mGlobals.SourceFiles.FileName, Argv[0]);

+  }

+

+  return STATUS_SUCCESS;

+}

+//

+// Found "-lang eng,spa+cat" on the command line. Parse the

+// language list and save the setting for later processing.

+//

+static

+STATUS

+AddCommandLineLanguage (

+  IN INT8          *Language

+  )

+{

+  WCHAR_STRING_LIST *WNewList;

+  WCHAR             *From;

+  WCHAR             *To;

+  //

+  // Keep processing the input string until we find the end.

+  //

+  while (*Language) {

+    //

+    // Allocate memory for a new list element, fill it in, and

+    // add it to our list.

+    //

+    WNewList = MALLOC (sizeof (WCHAR_STRING_LIST));

+    if (WNewList == NULL) {

+      Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+      return STATUS_ERROR;

+    }

+

+    memset ((char *) WNewList, 0, sizeof (WCHAR_STRING_LIST));

+    WNewList->Str = malloc ((strlen (Language) + 1) * sizeof (WCHAR));

+    if (WNewList->Str == NULL) {

+      free (WNewList);

+      Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+      return STATUS_ERROR;

+    }

+    //

+    // Copy it as unicode to our new structure. Then remove the

+    // plus signs in it, and verify each language name is 3 characters

+    // long. If we find a comma, then we're done with this group, so

+    // break out.

+    //

+    UnicodeSPrint (WNewList->Str, (strlen (Language) + 1) * sizeof (WCHAR), L"%a", Language);

+    From = To = WNewList->Str;

+    while (*From) {

+      if (*From == L',') {

+        break;

+      }

+

+      if ((StrLen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) ||

+            (

+              (From[LANGUAGE_IDENTIFIER_NAME_LEN] != 0) &&

+              (From[LANGUAGE_IDENTIFIER_NAME_LEN] != UNICODE_PLUS_SIGN) &&

+              (From[LANGUAGE_IDENTIFIER_NAME_LEN] != L',')

+            )

+          ) {

+        Error (PROGRAM_NAME, 0, 0, Language, "invalid format for language name on command line");

+        FREE (WNewList->Str);

+        FREE (WNewList);

+        return STATUS_ERROR;

+      }

+

+      StrnCpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN);

+      To += LANGUAGE_IDENTIFIER_NAME_LEN;

+      From += LANGUAGE_IDENTIFIER_NAME_LEN;

+      if (*From == L'+') {

+        From++;

+      }

+    }

+

+    *To = 0;

+    //

+    // Add it to our linked list

+    //

+    if (mGlobals.Language == NULL) {

+      mGlobals.Language = WNewList;

+    } else {

+      mGlobals.LastLanguage->Next = WNewList;

+    }

+

+    mGlobals.LastLanguage = WNewList;

+    //

+    // Skip to next entry (comma-separated list)

+    //

+    while (*Language) {

+      if (*Language == L',') {

+        Language++;

+        break;

+      }

+

+      Language++;

+    }

+  }

+

+  return STATUS_SUCCESS;

+}

+//

+// The contents of the text file are expected to be (one per line)

+//   STRING_IDENTIFIER_NAME   ScopeName

+// For example:

+//   STR_ID_MY_FAVORITE_STRING   IBM

+//

+static

+STATUS

+ParseIndirectionFiles (

+  TEXT_STRING_LIST    *Files

+  )

+{

+  FILE                        *Fptr;

+  INT8                        Line[200];

+  INT8                        *StringName;

+  INT8                        *ScopeName;

+  INT8                        *End;

+  UINT32                      LineCount;

+  WCHAR_MATCHING_STRING_LIST  *NewList;

+

+  Line[sizeof (Line) - 1] = 0;

+  Fptr                    = NULL;

+  while (Files != NULL) {

+    Fptr      = fopen (Files->Str, "r");

+    LineCount = 0;

+    if (Fptr == NULL) {

+      Error (NULL, 0, 0, Files->Str, "failed to open input indirection file for reading");

+      return STATUS_ERROR;

+    }

+

+    while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+      //

+      // remove terminating newline for error printing purposes.

+      //

+      if (Line[strlen (Line) - 1] == '\n') {

+        Line[strlen (Line) - 1] = 0;

+      }

+

+      LineCount++;

+      if (Line[sizeof (Line) - 1] != 0) {

+        Error (Files->Str, LineCount, 0, "line length exceeds maximum supported", NULL);

+        goto Done;

+      }

+

+      StringName = Line;

+      while (*StringName && (isspace (*StringName))) {

+        StringName++;

+      }

+

+      if (*StringName) {

+        if ((*StringName == '_') || isalpha (*StringName)) {

+          End = StringName;

+          while ((*End) && (*End == '_') || (isalnum (*End))) {

+            End++;

+          }

+

+          if (isspace (*End)) {

+            *End = 0;

+            End++;

+            while (isspace (*End)) {

+              End++;

+            }

+

+            if (*End) {

+              ScopeName = End;

+              while (*End && !isspace (*End)) {

+                End++;

+              }

+

+              *End = 0;

+              //

+              // Add the string name/scope pair

+              //

+              NewList = malloc (sizeof (WCHAR_MATCHING_STRING_LIST));

+              if (NewList == NULL) {

+                Error (NULL, 0, 0, "memory allocation error", NULL);

+                goto Done;

+              }

+

+              memset (NewList, 0, sizeof (WCHAR_MATCHING_STRING_LIST));

+              NewList->Str1 = (WCHAR *) malloc ((strlen (StringName) + 1) * sizeof (WCHAR));

+              NewList->Str2 = (WCHAR *) malloc ((strlen (ScopeName) + 1) * sizeof (WCHAR));

+              if ((NewList->Str1 == NULL) || (NewList->Str2 == NULL)) {

+                Error (NULL, 0, 0, "memory allocation error", NULL);

+                goto Done;

+              }

+

+              UnicodeSPrint (NewList->Str1, strlen (StringName) + 1, L"%a", StringName);

+              UnicodeSPrint (NewList->Str2, strlen (ScopeName) + 1, L"%a", ScopeName);

+              if (mGlobals.IndirectionList == NULL) {

+                mGlobals.IndirectionList = NewList;

+              } else {

+                mGlobals.LastIndirectionList->Next = NewList;

+              }

+

+              mGlobals.LastIndirectionList = NewList;

+            } else {

+              Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'");

+              goto Done;

+            }

+          } else {

+            Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'");

+            goto Done;

+          }

+        } else {

+          Error (Files->Str, LineCount, 0, StringName, "invalid string identifier");

+          goto Done;

+        }

+      }

+    }

+

+    fclose (Fptr);

+    Fptr  = NULL;

+    Files = Files->Next;

+  }

+

+Done:

+  if (Fptr != NULL) {

+    fclose (Fptr);

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+ScanFiles (

+  TEXT_STRING_LIST *ScanFiles

+  )

+{

+  char              Line[MAX_LINE_LEN];

+  FILE              *Fptr;

+  UINT32            LineNum;

+  char              *Cptr;

+  char              *SavePtr;

+  char              *TermPtr;

+  char              *StringTokenPos;

+  TEXT_STRING_LIST  *SList;

+  BOOLEAN           SkipIt;

+

+  //

+  // Put a null-terminator at the end of the line. If we read in

+  // a line longer than we support, then we can catch it.

+  //

+  Line[MAX_LINE_LEN - 1] = 0;

+  //

+  // Process each file. If they gave us a skip extension list, then

+  // skip it if the extension matches.

+  //

+  while (ScanFiles != NULL) {

+    SkipIt = FALSE;

+    for (SList = mGlobals.SkipExt; SList != NULL; SList = SList->Next) {

+      if ((strlen (ScanFiles->Str) > strlen (SList->Str)) &&

+          (strcmp (ScanFiles->Str + strlen (ScanFiles->Str) - strlen (SList->Str), SList->Str) == 0)

+          ) {

+        SkipIt = TRUE;

+        //

+        // printf ("Match: %s : %s\n", ScanFiles->Str, SList->Str);

+        //

+        break;

+      }

+    }

+

+    if (!SkipIt) {

+      if (mGlobals.VerboseScan) {

+        printf ("Scanning %s\n", ScanFiles->Str);

+      }

+

+      Fptr = fopen (ScanFiles->Str, "r");

+      if (Fptr == NULL) {

+        Error (NULL, 0, 0, ScanFiles->Str, "failed to open input file for scanning");

+        return STATUS_ERROR;

+      }

+

+      LineNum = 0;

+      while (fgets (Line, sizeof (Line), Fptr) != NULL) {

+        LineNum++;

+        if (Line[MAX_LINE_LEN - 1] != 0) {

+          Error (ScanFiles->Str, LineNum, 0, "line length exceeds maximum supported by tool", NULL);

+          fclose (Fptr);

+          return STATUS_ERROR;

+        }

+        //

+        // Remove the newline from the input line so we can print a warning message

+        //

+        if (Line[strlen (Line) - 1] == '\n') {

+          Line[strlen (Line) - 1] = 0;

+        }

+        //

+        // Terminate the line at // comments

+        //

+        Cptr = strstr (Line, "//");

+        if (Cptr != NULL) {

+          *Cptr = 0;

+        }

+

+        Cptr = Line;

+        while ((Cptr = strstr (Cptr, STRING_TOKEN)) != NULL) {

+          //

+          // Found "STRING_TOKEN". Make sure we don't have NUM_STRING_TOKENS or

+          // something like that. Then make sure it's followed by

+          // an open parenthesis, a string identifier, and then a closing

+          // parenthesis.

+          //

+          if (mGlobals.VerboseScan) {

+            printf (" %d: %s", LineNum, Cptr);

+          }

+

+          if (((Cptr == Line) || (!IsValidIdentifierChar (*(Cptr - 1), FALSE))) &&

+              (!IsValidIdentifierChar (*(Cptr + sizeof (STRING_TOKEN) - 1), FALSE))

+              ) {

+            StringTokenPos  = Cptr;

+            SavePtr         = Cptr;

+            Cptr += strlen (STRING_TOKEN);

+            while (*Cptr && isspace (*Cptr) && (*Cptr != '(')) {

+              Cptr++;

+            }

+

+            if (*Cptr != '(') {

+              Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)");

+            } else {

+              //

+              // Skip over the open-parenthesis and find the next non-blank character

+              //

+              Cptr++;

+              while (isspace (*Cptr)) {

+                Cptr++;

+              }

+

+              SavePtr = Cptr;

+              if ((*Cptr == '_') || isalpha (*Cptr)) {

+                while ((*Cptr == '_') || (isalnum (*Cptr))) {

+                  Cptr++;

+                }

+

+                TermPtr = Cptr;

+                while (*Cptr && isspace (*Cptr)) {

+                  Cptr++;

+                }

+

+                if (*Cptr != ')') {

+                  Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)");

+                }

+

+                if (*TermPtr) {

+                  *TermPtr  = 0;

+                  Cptr      = TermPtr + 1;

+                } else {

+                  Cptr = TermPtr;

+                }

+                //

+                // Add the string identifier to the list of used strings

+                //

+                ParserSetPosition (ScanFiles->Str, LineNum);

+                StringDBSetStringReferenced (SavePtr, mGlobals.IgnoreNotFound);

+                if (mGlobals.VerboseScan) {

+                  printf ("...referenced %s", SavePtr);

+                }

+              } else {

+                Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected valid string identifier name");

+              }

+            }

+          } else {

+            //

+            // Found it, but it's a substring of something else. Advance our pointer.

+            //

+            Cptr++;

+          }

+

+          if (mGlobals.VerboseScan) {

+            printf ("\n");

+          }

+        }

+      }

+

+      fclose (Fptr);

+    } else {

+      //

+      // Skipping this file type

+      //

+      if (mGlobals.VerboseScan) {

+        printf ("Skip scanning of %s\n", ScanFiles->Str);

+      }

+    }

+

+    ScanFiles = ScanFiles->Next;

+  }

+

+  return STATUS_SUCCESS;

+}

+//

+// Free the global string lists we allocated memory for

+//

+static

+void

+FreeLists (

+  VOID

+  )

+{

+  TEXT_STRING_LIST  *Temp;

+  WCHAR_STRING_LIST *WTemp;

+

+  //

+  // Traverse the include paths, freeing each

+  //

+  while (mGlobals.IncludePaths != NULL) {

+    Temp = mGlobals.IncludePaths->Next;

+    free (mGlobals.IncludePaths->Str);

+    free (mGlobals.IncludePaths);

+    mGlobals.IncludePaths = Temp;

+  }

+  //

+  // If we did a scan, then free up our

+  // list of files to scan.

+  //

+  while (mGlobals.ScanFileName != NULL) {

+    Temp = mGlobals.ScanFileName->Next;

+    free (mGlobals.ScanFileName->Str);

+    free (mGlobals.ScanFileName);

+    mGlobals.ScanFileName = Temp;

+  }

+  //

+  // If they gave us a list of filename extensions to

+  // skip on scan, then free them up.

+  //

+  while (mGlobals.SkipExt != NULL) {

+    Temp = mGlobals.SkipExt->Next;

+    free (mGlobals.SkipExt->Str);

+    free (mGlobals.SkipExt);

+    mGlobals.SkipExt = Temp;

+  }

+  //

+  // Free up any languages specified

+  //

+  while (mGlobals.Language != NULL) {

+    WTemp = mGlobals.Language->Next;

+    free (mGlobals.Language->Str);

+    free (mGlobals.Language);

+    mGlobals.Language = WTemp;

+  }

+  //

+  // Free up our indirection list

+  //

+  while (mGlobals.IndirectionList != NULL) {

+    mGlobals.LastIndirectionList = mGlobals.IndirectionList->Next;

+    free (mGlobals.IndirectionList->Str1);

+    free (mGlobals.IndirectionList->Str2);

+    free (mGlobals.IndirectionList);

+    mGlobals.IndirectionList = mGlobals.LastIndirectionList;

+  }

+

+  while (mGlobals.IndirectionFileName != NULL) {

+    mGlobals.LastIndirectionFileName = mGlobals.IndirectionFileName->Next;

+    free (mGlobals.IndirectionFileName->Str);

+    free (mGlobals.IndirectionFileName);

+    mGlobals.IndirectionFileName = mGlobals.LastIndirectionFileName;

+  }

+}

+

+static

+BOOLEAN

+IsValidIdentifierChar (

+  INT8      Char,

+  BOOLEAN   FirstChar

+  )

+{

+  //

+  // If it's the first character of an identifier, then

+  // it must be one of [A-Za-z_].

+  //

+  if (FirstChar) {

+    if (isalpha (Char) || (Char == '_')) {

+      return TRUE;

+    }

+  } else {

+    //

+    // If it's not the first character, then it can

+    // be one of [A-Za-z_0-9]

+    //

+    if (isalnum (Char) || (Char == '_')) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+static

+void

+RewindFile (

+  SOURCE_FILE *SourceFile

+  )

+{

+  SourceFile->LineNum       = 1;

+  SourceFile->FileBufferPtr = SourceFile->FileBuffer;

+  SourceFile->EndOfFile     = 0;

+}

+

+static

+BOOLEAN

+SkipTo (

+  SOURCE_FILE *SourceFile,

+  WCHAR       WChar,

+  BOOLEAN     StopAfterNewline

+  )

+{

+  while (!EndOfFile (SourceFile)) {

+    //

+    // Check for the character of interest

+    //

+    if (SourceFile->FileBufferPtr[0] == WChar) {

+      return TRUE;

+    } else {

+      if (SourceFile->FileBufferPtr[0] == UNICODE_LF) {

+        SourceFile->LineNum++;

+        if (StopAfterNewline) {

+          SourceFile->FileBufferPtr++;

+          if (SourceFile->FileBufferPtr[0] == 0) {

+            SourceFile->FileBufferPtr++;

+          }

+

+          return FALSE;

+        }

+      }

+

+      SourceFile->FileBufferPtr++;

+    }

+  }

+

+  return FALSE;

+}

+

+static

+void

+Usage (

+  VOID

+  )

+/*++

+

+Routine Description:

+

+  Print usage information for this utility.

+  

+Arguments:

+

+  None.

+

+Returns:

+

+  Nothing.

+  

+--*/

+{

+  int               Index;

+  static const char *Str[] = {

+    "",

+    PROGRAM_NAME " version "TOOL_VERSION " -- process unicode strings file",

+    "  Usage: "PROGRAM_NAME " -parse {parse options} [FileNames]",

+    "         "PROGRAM_NAME " -scan {scan options} [FileName]",

+    "         "PROGRAM_NAME " -dump {dump options}",

+    "    Common options include:",

+    "      -h or -?         for this help information",

+    "      -db Database     required name of output/input database file",

+    "      -bn BaseName     for use in the .h and .c output files",

+    "                       Default = "DEFAULT_BASE_NAME,

+    "      -v               for verbose output",

+    "      -vdbw            for verbose output when writing database",

+    "      -vdbr            for verbose output when reading database",

+    "      -od FileName     to specify an output database file name",

+    "    Parse options include:",

+    "      -i IncludePath   add IncludePath to list of search paths",

+    "      -newdb           to not read in existing database file",

+    "      -uqs             to indicate that unquoted strings are used",

+    "      FileNames        name of one or more unicode files to parse",

+    "    Scan options include:",

+    "      -scan            scan text file(s) for STRING_TOKEN() usage",

+    "      -skipext .ext    to skip scan of files with .ext filename extension",

+    "      -ignorenotfound  ignore if a given STRING_TOKEN(STR) is not ",

+    "                       found in the database",

+    "      FileNames        one or more files to scan",

+    "    Dump options include:",

+    "      -oc FileName     write string data to FileName",

+    "      -oh FileName     write string defines to FileName",

+    "      -ou FileName     dump database to unicode file FileName",

+    "      -lang Lang       only dump for the language 'Lang'",

+    "      -if FileName     to specify an indirection file",

+    "      -hpk FileName    to create an HII export pack of the strings",

+    "",

+    "  The expected process is to parse a unicode string file to create an initial",

+    "  database of string identifier names and string definitions. Then text files",

+    "  should be scanned for STRING_TOKEN() usages, and the referenced",

+    "  strings will be tagged as used in the database. After all files have been",

+    "  scanned, then the database should be dumped to create the necessary output",

+    "  files.",

+    "",

+    NULL

+  };

+  for (Index = 0; Str[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Str[Index]);

+  }

+}

diff --git a/edk2/Tools/Source/TianoTools/StrGather/StrGather.h b/edk2/Tools/Source/TianoTools/StrGather/StrGather.h
new file mode 100644
index 0000000..df175c2
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/StrGather/StrGather.h
@@ -0,0 +1,84 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StrGather.h

+

+Abstract:

+

+  Common defines and prototypes for StrGather.

+  

+--*/

+

+#ifndef _STR_GATHER_H_

+#define _STR_GATHER_H_

+

+#define MALLOC(size)  malloc (size)

+#define FREE(ptr)     free (ptr)

+

+#define PROGRAM_NAME  "StrGather"

+

+typedef CHAR16  WCHAR;

+

+#define UNICODE_TO_ASCII(w)   (INT8) ((w) & 0xFF)

+#define ASCII_TO_UNICODE(a)   (WCHAR) ((UINT8) (a))

+

+#define UNICODE_HASH          L'#'

+#define UNICODE_BACKSLASH     L'\\'

+#define UNICODE_SLASH         L'/'

+#define UNICODE_EQUAL_SIGN    L'='

+#define UNICODE_PLUS_SIGN     L'+'

+

+#define UNICODE_FILE_START    0xFEFF

+#define UNICODE_CR            0x000D

+#define UNICODE_LF            0x000A

+#define UNICODE_NULL          0x0000

+#define UNICODE_SPACE         L' '

+#define UNICODE_SLASH         L'/'

+#define UNICODE_DOUBLE_QUOTE  L'"'

+#define UNICODE_Z             L'Z'

+#define UNICODE_z             L'z'

+#define UNICODE_A             L'A'

+#define UNICODE_a             L'a'

+#define UNICODE_F             L'F'

+#define UNICODE_f             L'f'

+#define UNICODE_UNDERSCORE    L'_'

+#define UNICODE_0             L'0'

+#define UNICODE_9             L'9'

+#define UNICODE_TAB           L'\t'

+#define UNICODE_NBR_STRING    L"\\nbr"

+#define UNICODE_BR_STRING     L"\\br"

+#define UNICODE_WIDE_STRING   L"\\wide"

+#define UNICODE_NARROW_STRING L"\\narrow"

+

+//

+// This is the length of a valid string identifier

+//

+#define LANGUAGE_IDENTIFIER_NAME_LEN  3

+

+typedef struct _TEXT_STRING_LIST {

+  struct _TEXT_STRING_LIST  *Next;

+  UINT8                     *Str;

+} TEXT_STRING_LIST;

+

+typedef struct _WCHAR_STRING_LIST {

+  struct _WCHAR_STRING_LIST *Next;

+  WCHAR                     *Str;

+} WCHAR_STRING_LIST;

+

+typedef struct _WCHAR_MATCHING_STRING_LIST {

+  struct _WCHAR_MATCHING_STRING_LIST  *Next;

+  WCHAR                               *Str1;

+  WCHAR                               *Str2;

+} WCHAR_MATCHING_STRING_LIST;

+

+#endif // #ifndef _STR_GATHER_H_

diff --git a/edk2/Tools/Source/TianoTools/StrGather/StringDB.c b/edk2/Tools/Source/TianoTools/StrGather/StringDB.c
new file mode 100644
index 0000000..353fabb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/StrGather/StringDB.c
@@ -0,0 +1,2760 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StringDB.c

+

+Abstract:

+

+  String database implementation

+  

+--*/

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <ctype.h>  // for tolower()

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <MultiPhase.h>

+#include <BaseLib.h>

+#include "EfiUtilityMsgs.h"

+#include "StrGather.h"

+#include "StringDB.h"

+#include "InternalFormRepresentation.h"

+

+// #include EFI_PROTOCOL_DEFINITION (Hii)

+#include <UgaDraw.h>

+#include <Hii.h>

+

+#define STRING_OFFSET RELOFST

+

+#define STRING_DB_KEY (('S' << 24) | ('D' << 16) | ('B' << 8) | 'K')

+//

+// Version supported by this tool

+//

+#define STRING_DB_VERSION             0x00010000

+

+#define STRING_DB_MAJOR_VERSION_MASK  0xFFFF0000

+#define STRING_DB_MINOR_VERSION_MASK  0x0000FFFF

+

+#define DEFINE_STR                    L"// #define"

+

+#define LANGUAGE_CODE_WIDTH           4

+//

+// This is the header that gets written to the top of the

+// output binary database file.

+//

+typedef struct {

+  UINT32  Key;

+  UINT32  HeaderSize;

+  UINT32  Version;

+  UINT32  NumStringIdenfiers;

+  UINT32  StringIdentifiersSize;

+  UINT32  NumLanguages;

+} STRING_DB_HEADER;

+

+//

+// When we write out data to the database, we have a UINT16 identifier, which

+// indicates what follows, followed by the data. Here's the structure.

+//

+typedef struct {

+  UINT16  DataType;

+  UINT16  Reserved;

+} DB_DATA_ITEM_HEADER;

+

+#define DB_DATA_TYPE_INVALID              0x0000

+#define DB_DATA_TYPE_STRING_IDENTIFIER    0x0001

+#define DB_DATA_TYPE_LANGUAGE_DEFINITION  0x0002

+#define DB_DATA_TYPE_STRING_DEFINITION    0x0003

+#define DB_DATA_TYPE_LAST                 DB_DATA_TYPE_STRING_DEFINITION

+

+//

+// We have to keep track of a list of languages, each of which has its own

+// list of strings. Define a structure to keep track of all languages and

+// their list of strings.

+//

+typedef struct _STRING_LIST {

+  struct _STRING_LIST *Next;

+  UINT32              Size;         // number of bytes in string, including null terminator

+  WCHAR               *LanguageName;

+  WCHAR               *StringName;  // for example STR_ID_TEXT1

+  WCHAR               *Scope;       //

+  WCHAR               *Str;         // the actual string

+  UINT16              Flags;        // properties of this string (used, undefined)

+} STRING_LIST;

+

+typedef struct _LANGUAGE_LIST {

+  struct _LANGUAGE_LIST *Next;

+  WCHAR                 LanguageName[4];

+  WCHAR                 *PrintableLanguageName;

+  STRING_LIST           *String;

+  STRING_LIST           *LastString;

+} LANGUAGE_LIST;

+

+//

+// We also keep track of all the string identifier names, which we assign unique

+// values to. Create a structure to keep track of them all.

+//

+typedef struct _STRING_IDENTIFIER {

+  struct _STRING_IDENTIFIER *Next;

+  UINT32                    Index;  // only need 16 bits, but makes it easier with UINT32

+  WCHAR                     *StringName;

+  UINT16                    Flags;  // if someone referenced it via STRING_TOKEN()

+} STRING_IDENTIFIER;

+//

+// Keep our globals in this structure to be as modular as possible.

+//

+typedef struct {

+  FILE              *StringDBFptr;

+  LANGUAGE_LIST     *LanguageList;

+  LANGUAGE_LIST     *LastLanguageList;

+  LANGUAGE_LIST     *CurrentLanguage;         // keep track of the last language they used

+  STRING_IDENTIFIER *StringIdentifier;

+  STRING_IDENTIFIER *LastStringIdentifier;

+  UINT8             *StringDBFileName;

+  UINT32            NumStringIdentifiers;

+  UINT32            NumStringIdentifiersReferenced;

+  STRING_IDENTIFIER *CurrentStringIdentifier; // keep track of the last string identifier they added

+  WCHAR             *CurrentScope;

+} STRING_DB_DATA;

+

+static STRING_DB_DATA mDBData;

+

+static const char     *mSourceFileHeader[] = {

+  "//",

+  "//  DO NOT EDIT -- auto-generated file",

+  "//",

+  "//  This file is generated by the string gather utility",

+  "//",

+  NULL

+};

+

+static

+STRING_LIST           *

+StringDBFindString (

+  WCHAR                       *LanguageName,

+  WCHAR                       *StringName,

+  WCHAR                       *Scope,

+  WCHAR_STRING_LIST           *LanguagesOfInterest,

+  WCHAR_MATCHING_STRING_LIST  *IndirectionList

+  );

+

+static

+STRING_IDENTIFIER     *

+StringDBFindStringIdentifierByName (

+  WCHAR *Name

+  );

+

+static

+STRING_IDENTIFIER     *

+StringDBFindStringIdentifierByIndex (

+  UINT32    Index

+  );

+

+static

+LANGUAGE_LIST         *

+StringDBFindLanguageList (

+  WCHAR *LanguageName

+  );

+

+static

+void

+StringDBWriteStandardFileHeader (

+  FILE *OutFptr

+  );

+

+static

+WCHAR                 *

+AsciiToWchar (

+  INT8 *Str

+  );

+

+static

+WCHAR                 *

+DuplicateString (

+  WCHAR   *Str

+  );

+

+static

+STATUS

+StringDBWriteStringIdentifier (

+  FILE                *DBFptr,

+  UINT16              StringId,

+  UINT16              Flags,

+  WCHAR               *IdentifierName

+  );

+

+static

+STATUS

+StringDBReadStringIdentifier (

+  FILE                *DBFptr

+  );

+

+static

+STATUS

+StringDBWriteLanguageDefinition (

+  FILE            *DBFptr,

+  WCHAR           *LanguageName,

+  WCHAR           *PrintableLanguageName

+  );

+

+static

+STATUS

+StringDBReadLanguageDefinition (

+  FILE            *DBFptr

+  );

+

+static

+STATUS

+StringDBWriteString (

+  FILE            *DBFptr,

+  UINT16          Flags,

+  WCHAR           *Language,

+  WCHAR           *StringName,

+  WCHAR           *Scope,

+  WCHAR           *Str

+  );

+

+static

+STATUS

+StringDBReadString (

+  FILE            *DBFptr

+  );

+

+static

+STATUS

+StringDBReadGenericString (

+  FILE      *DBFptr,

+  UINT16    *Size,

+  WCHAR     **Str

+  );

+

+static

+STATUS

+StringDBWriteGenericString (

+  FILE      *DBFptr,

+  WCHAR     *Str

+  );

+

+static

+void

+StringDBAssignStringIndexes (

+  VOID

+  );

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+  Constructor function for the string database handler.

+

+Arguments:

+  None.

+

+Returns:

+  None.

+

+--*/

+void

+StringDBConstructor (

+  VOID

+  )

+{

+  memset ((char *) &mDBData, 0, sizeof (STRING_DB_DATA));

+  mDBData.CurrentScope = DuplicateString (L"NULL");

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+  Destructor function for the string database handler.

+

+Arguments:

+  None.

+

+Returns:

+  None.

+

+--*/

+void

+StringDBDestructor (

+  VOID

+  )

+{

+  LANGUAGE_LIST     *NextLang;

+  STRING_LIST       *NextStr;

+  STRING_IDENTIFIER *NextIdentifier;

+  //

+  // Close the database file if it's open

+  //

+  if (mDBData.StringDBFptr != NULL) {

+    fclose (mDBData.StringDBFptr);

+    mDBData.StringDBFptr = NULL;

+  }

+  //

+  // If we've allocated any strings/languages, free them up

+  //

+  while (mDBData.LanguageList != NULL) {

+    NextLang = mDBData.LanguageList->Next;

+    //

+    // Free up all strings for this language

+    //

+    while (mDBData.LanguageList->String != NULL) {

+      NextStr = mDBData.LanguageList->String->Next;

+      FREE (mDBData.LanguageList->String->Str);

+      FREE (mDBData.LanguageList->String);

+      mDBData.LanguageList->String = NextStr;

+    }

+

+    FREE (mDBData.LanguageList->PrintableLanguageName);

+    FREE (mDBData.LanguageList);

+    mDBData.LanguageList = NextLang;

+  }

+  //

+  // Free up string identifiers

+  //

+  while (mDBData.StringIdentifier != NULL) {

+    NextIdentifier = mDBData.StringIdentifier->Next;

+    FREE (mDBData.StringIdentifier->StringName);

+    FREE (mDBData.StringIdentifier);

+    mDBData.StringIdentifier = NextIdentifier;

+  }

+  //

+  // Free the filename

+  //

+  if (mDBData.StringDBFileName != NULL) {

+    FREE (mDBData.StringDBFileName);

+    mDBData.StringDBFileName = NULL;

+  }

+  //

+  // We save a copy of the scope, so free it up if we

+  // have one.

+  //

+  if (mDBData.CurrentScope != NULL) {

+    FREE (mDBData.CurrentScope);

+    mDBData.CurrentScope = NULL;

+  }

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Dump the contents of a database to an output C file.

+

+Arguments:

+

+  FileName        - name of the output file to write 

+  BaseName        - used for the name of the C array defined

+  Languages       - list of languages of interest

+

+Returns:

+

+  STATUS

+

+Notes:

+

+  Languages is a pointer to a linked list of languages specified on

+  the command line. Format is "eng" and "spa+cat". For this, print

+  the strings for eng. Print the strings for spa too, but if one is

+  missing look for a cat string and print if it it exists.

+

+--*/

+STATUS

+StringDBDumpCStrings (

+  INT8                        *FileName,

+  INT8                        *BaseName,

+  WCHAR_STRING_LIST           *LanguagesOfInterest,

+  WCHAR_MATCHING_STRING_LIST  *IndirectionList

+  )

+{

+  FILE                        *Fptr;

+  LANGUAGE_LIST               *Lang;

+  STRING_LIST                 *CurrString;

+  STRING_LIST                 EmptyString;

+  UINT32                      Offset;

+  UINT32                      StringIndex;

+  UINT32                      TempIndex;

+  UINT32                      BytesThisLine;

+  EFI_HII_STRING_PACK         StringPack;

+  UINT8                       *Ptr;

+  UINT32                      Len;

+  WCHAR                       ZeroString[1];

+  WCHAR_STRING_LIST           *LOIPtr;

+  BOOLEAN                     LanguageOk;

+  WCHAR                       *TempStringPtr;

+  WCHAR                       *LangName;

+  STRING_IDENTIFIER           *StringIdentifier;

+  WCHAR                       Line[200];

+

+  if ((Fptr = fopen (FileName, "w")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output C string file");

+    return STATUS_ERROR;

+  }

+  //

+  // Assign index values to the string identifiers

+  //

+  StringDBAssignStringIndexes ();

+  //

+  // Write the standard header to the output file, then the structure

+  // definition header.

+  //

+  StringDBWriteStandardFileHeader (Fptr);

+  fprintf (Fptr, "\nunsigned char %s[] = {\n", BaseName);

+  //

+  // If a given string is not defined, then we'll use this one.

+  //

+  memset (&EmptyString, 0, sizeof (EmptyString));

+  EmptyString.Size  = sizeof (ZeroString);

+  EmptyString.Str   = ZeroString;

+  //

+  // Process each language, then each string for each langage

+  //

+  ZeroString[0] = 0;

+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {

+    //

+    // If we have a language list, then make sure this language is in that

+    // list.

+    //

+    LanguageOk  = TRUE;

+    LangName    = Lang->LanguageName;

+    if (LanguagesOfInterest != NULL) {

+      LanguageOk = FALSE;

+      for (LOIPtr = LanguagesOfInterest; LOIPtr != NULL; LOIPtr = LOIPtr->Next) {

+        if (StrnCmp (LOIPtr->Str, Lang->LanguageName, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {

+          LangName    = LOIPtr->Str;

+          LanguageOk  = TRUE;

+          break;

+        }

+      }

+    }

+

+    if (!LanguageOk) {

+      continue;

+    }

+    //

+    // Process each string for this language. We have to make 3 passes on the strings:

+    //   Pass1: computes sizes and fill in the string pack header

+    //   Pass2: write the array of offsets

+    //   Pass3: write the strings

+    //

+    //

+    // PASS 1: Fill in and print the HII string pack header

+    //

+    // Compute the size for this language package and write

+    // the header out. Each string package contains:

+    //   Header

+    //   Offset[]  -- an array of offsets to strings, of type RELOFST each

+    //   String[]  -- the actual strings themselves

+    //

+    AsciiSPrint ( Line, sizeof(Line),

+      "\n//******************************************************************************"

+      "\n// Start of string definitions for %s/%s",

+      Lang->LanguageName,

+      Lang->PrintableLanguageName

+      );

+    fprintf (Fptr, "%s", Line);

+    memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));

+    StringPack.Header.Type        = EFI_HII_STRING;

+    StringPack.NumStringPointers  = (UINT16) mDBData.NumStringIdentifiersReferenced;

+    //

+    // First string is the language name. If we're printing all languages, then

+    // it's just the "spa". If we were given a list of languages to print, then it's

+    // the "spacat" string. Compute its offset and fill in

+    // the info in the header. Since we know the language name string's length,

+    // and the printable language name follows it, use that info to fill in the

+    // entry for the printable language name as well.

+    //

+    StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));

+    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR));

+    //

+    // Add up the size of all strings so we can fill in our header.

+    //

+    Len = 0;

+    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {

+      //

+      // For the first string (language name), we print out the "spacat" if they

+      // requested it. We set LangName to point to the proper language name string above.

+      //

+      if (StringIndex == STRING_ID_LANGUAGE_NAME) {

+        Len += (StrLen (LangName) + 1) * sizeof (WCHAR);

+      } else {

+        //

+        // Find a string with this language.stringname

+        //

+        StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+        if (StringIdentifier == NULL) {

+          Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);

+          return STATUS_ERROR;

+        }

+        //

+        // Find a matching string if this string identifier was referenced

+        //

+        EmptyString.Flags = STRING_FLAGS_UNDEFINED;

+        CurrString        = NULL;

+        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {

+          CurrString = StringDBFindString (

+                        Lang->LanguageName,

+                        StringIdentifier->StringName,

+                        NULL,

+                        LanguagesOfInterest,

+                        IndirectionList

+                        );

+          if (NULL == CurrString) {

+            //

+            // If string for Lang->LanguageName is not found, try to get an English version

+            //

+            CurrString = StringDBFindString (

+                          L"eng",

+                          StringIdentifier->StringName,

+                          NULL,

+                          LanguagesOfInterest,

+                          IndirectionList

+                          );

+          }

+        }

+

+        if (CurrString == NULL) {

+          CurrString = &EmptyString;

+          EmptyString.Flags |= StringIdentifier->Flags;

+        }

+

+        Len += CurrString->Size;

+      }

+    }

+    StringPack.Header.Length =    sizeof (EFI_HII_STRING_PACK) 

+                                + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) 

+                                + Len;

+    //

+    // Write out the header one byte at a time

+    //

+    Ptr = (UINT8 *) &StringPack;

+    for (TempIndex = 0; TempIndex < sizeof (EFI_HII_STRING_PACK); TempIndex++, Ptr++) {

+      if ((TempIndex & 0x07) == 0) {

+        fprintf (Fptr, "\n  ");

+      }

+

+      fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr);

+    }

+

+    fprintf (Fptr, "\n  // offset 0x%X\n", sizeof (StringPack));

+    //

+    // PASS2 : write the offsets

+    //

+    // Traverse the list of strings again and write the array of offsets. The

+    // offset to the first string is the size of the string pack header

+    // plus the size of the offsets array. The other strings follow it.

+    //

+    StringIndex = 0;

+    Offset      = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);

+    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {

+      //

+      // Write the offset, followed by a useful comment

+      //

+      fprintf (Fptr, "  ");

+      Ptr = (UINT8 *) &Offset;

+      for (TempIndex = 0; TempIndex < sizeof (STRING_OFFSET); TempIndex++) {

+        fprintf (Fptr, "0x%02X, ", (UINT32) Ptr[TempIndex]);

+      }

+      //

+      // Find the string name

+      //

+      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+      if (StringIdentifier == NULL) {

+        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);

+        return STATUS_ERROR;

+      }

+

+      AsciiSPrint (Line, sizeof(Line) , " // offset to string %s (0x%04X)", StringIdentifier->StringName, StringIndex);

+      fprintf (Fptr, "%s", Line);

+      //

+      // For the first string (language name), we print out the "spacat" if they

+      // requested it. We set LangName to point to the proper language name string above.

+      //

+      if (StringIndex == STRING_ID_LANGUAGE_NAME) {

+        Offset += (StrLen (LangName) + 1) * sizeof (WCHAR);

+        CurrString = StringDBFindString (

+                      Lang->LanguageName,

+                      StringIdentifier->StringName,

+                      NULL, // scope

+                      NULL,

+                      NULL

+                      );

+      } else {

+        //

+        // Find a matching string

+        //

+        CurrString = StringDBFindString (

+                      Lang->LanguageName,

+                      StringIdentifier->StringName,

+                      NULL,   // scope

+                      LanguagesOfInterest,

+                      IndirectionList

+                      );

+

+        if (NULL == CurrString) {

+          CurrString = StringDBFindString (

+                        L"eng",

+                        StringIdentifier->StringName,

+                        NULL, // scope

+                        LanguagesOfInterest,

+                        IndirectionList

+                        );

+        }

+

+        EmptyString.LanguageName = Lang->LanguageName;

+        if (CurrString == NULL) {

+          CurrString        = &EmptyString;

+          EmptyString.Flags = STRING_FLAGS_UNDEFINED;

+        } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {

+          CurrString        = &EmptyString;

+          EmptyString.Flags = 0;

+        }

+

+        Offset += CurrString->Size;

+      }

+      //

+      // Print useful info about this string

+      //

+      if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {

+        fprintf (Fptr, " - not referenced");

+      }

+

+      if (CurrString->Flags & STRING_FLAGS_UNDEFINED) {

+        fprintf (Fptr, " - not defined for this language");

+      } else if (StrCmp (CurrString->LanguageName, Lang->LanguageName) != 0) {

+        AsciiSPrint (

+          Line, sizeof(Line),

+          " - not defined for this language -- using secondary language %s definition",

+          CurrString->LanguageName

+          );

+        fprintf ( Fptr, "%s", Line);

+      }

+

+      fprintf (Fptr, "\n");

+    }

+    //

+    // For unreferenced string identifiers, print a message that they are not referenced anywhere

+    //

+    while (StringIndex < mDBData.NumStringIdentifiers) {

+      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+      if (StringIdentifier != NULL) {

+        AsciiSPrint (Line, sizeof(Line), "  // %s not referenced\n", StringIdentifier->StringName);

+        fprintf (Fptr, "%s", Line);

+      }

+

+      StringIndex++;

+    }

+

+    //

+    // PASS 3: write the strings themselves.

+    // Keep track of how many bytes we write per line because some editors

+    // (Visual Studio for instance) can't handle too long of lines.

+    //

+    Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);

+    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {

+      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+      if (StringIdentifier == NULL) {

+        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);

+        return STATUS_ERROR;

+      }

+

+      AsciiSPrint (Line, sizeof(Line), "  // string %s offset 0x%08X\n  ", StringIdentifier->StringName, Offset);

+      fprintf (Fptr, "%s", Line);

+      //

+      // For the first string (language name), we print out the "spacat" if they

+      // requested it. We set LangName to point to the proper language name string above.

+      //

+      if (StringIndex == STRING_ID_LANGUAGE_NAME) {

+        TempStringPtr = LangName;

+      } else {

+        //

+        // Find a matching string if this string identifier was referenced

+        //

+        CurrString = NULL;

+        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {

+          CurrString = StringDBFindString (

+                        Lang->LanguageName,

+                        StringIdentifier->StringName,

+                        NULL,   // scope

+                        LanguagesOfInterest,

+                        IndirectionList

+                        );

+          if (NULL == CurrString) {

+            CurrString = StringDBFindString (

+                          L"eng",

+                          StringIdentifier->StringName,

+                          NULL, // scope

+                          LanguagesOfInterest,

+                          IndirectionList

+                          );

+          }

+        }

+

+        if (CurrString == NULL) {

+          CurrString = &EmptyString;

+        }

+

+        TempStringPtr = CurrString->Str;

+      }

+

+      BytesThisLine = 0;

+      for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) {

+        fprintf (

+          Fptr,

+          "0x%02X, 0x%02X, ",

+          (UINT32) TempStringPtr[TempIndex] & 0xFF,

+          (UINT32) ((TempStringPtr[TempIndex] >> 8) & 0xFF)

+          );

+        BytesThisLine += 2;

+        Offset += 2;

+        //

+        // Let's say we only allow 14 per line

+        //

+        if (BytesThisLine > 14) {

+          fprintf (Fptr, "\n  ");

+          BytesThisLine = 0;

+        }

+      }

+      //

+      // Print NULL WCHAR at the end of this string.

+      //

+      fprintf (Fptr, "0x00, 0x00,\n");

+      Offset += 2;

+    }

+    //

+    // Sanity check the offset. Make sure our running offset is what we put in the

+    // string pack header.

+    //

+    if (StringPack.Header.Length != Offset) {

+      Error (

+        __FILE__,

+        __LINE__,

+        0,

+        "application error",

+        "stringpack size 0x%X does not match final size 0x%X",

+        StringPack.Header.Length,

+        Offset

+        );

+    }

+  }

+  //

+  // Print terminator string pack, closing brace and close the file.

+  // The size of 0 triggers to the consumer that this is the end.

+  //

+  memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));

+  StringPack.Header.Type  = EFI_HII_STRING;

+  Ptr                     = (UINT8 *) &StringPack;

+  fprintf (Fptr, "\n  // strings terminator pack");

+  for (TempIndex = 0; TempIndex < sizeof (StringPack); TempIndex++, Ptr++) {

+    if ((TempIndex & 0x0F) == 0) {

+      fprintf (Fptr, "\n  ");

+    }

+

+    fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr);

+  }

+

+  fprintf (Fptr, "\n};\n");

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Dump the #define string names

+

+Arguments:

+

+  FileName        - name of the output file to write 

+  BaseName        - used for the protection #ifndef/#endif 

+

+Returns:

+

+  STATUS

+

+--*/

+STATUS

+StringDBDumpStringDefines (

+  INT8 *FileName,

+  INT8 *BaseName

+  )

+{

+  FILE              *Fptr;

+  STRING_IDENTIFIER *Identifier;

+  INT8              CopyBaseName[100];

+  WCHAR             Line[200];

+  UINT32            Index;

+  const INT8        *StrDefHeader[] = {

+    "#ifndef _%s_STRINGS_DEFINE_H_\n",

+    "#define _%s_STRINGS_DEFINE_H_\n\n",

+    NULL

+  };

+

+  if ((Fptr = fopen (FileName, "w")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output string defines file");

+    return STATUS_ERROR;

+  }

+  //

+  // Get the base source filename and convert to uppercase.

+  //

+  if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) {

+    Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient");

+    return STATUS_ERROR;

+  }

+

+  strcpy (CopyBaseName, BaseName);

+  for (Index = 0; CopyBaseName[Index] != 0; Index++) {

+    if (islower (CopyBaseName[Index])) {

+      CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]);

+    }

+  }

+  //

+  // Assign index values to the string identifiers

+  //

+  StringDBAssignStringIndexes ();

+  //

+  // Write the standard header to the output file, and then the

+  // protective #ifndef.

+  //

+  StringDBWriteStandardFileHeader (Fptr);

+  for (Index = 0; StrDefHeader[Index] != NULL; Index++) {

+    fprintf (Fptr, StrDefHeader[Index], CopyBaseName);

+  }

+  //

+  // Print all the #defines for the string identifiers. Print identifiers

+  // whose names start with '$' as comments. Add comments for string

+  // identifiers not used as well.

+  //

+  Identifier = mDBData.StringIdentifier;

+  while (Identifier != NULL) {

+    if (Identifier->StringName[0] == L'$') {

+      fprintf (Fptr, "// ");

+    }

+

+    if (Identifier->Flags & STRING_FLAGS_REFERENCED) {

+      AsciiSPrint (Line, sizeof(Line), "#define %-40s 0x%04X\n", Identifier->StringName, Identifier->Index);

+      fprintf (Fptr, "%s", Line);

+    } else {

+      AsciiSPrint (Line, sizeof(Line), "//#define %-40s 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);

+      fprintf (Fptr, "%s", Line);

+    }

+

+    Identifier = Identifier->Next;

+  }

+

+  fprintf (Fptr, "\n#endif\n");

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Add a string identifier to the database.

+

+Arguments:

+

+  StringName      - name of the string identifier. For example "STR_MY_STRING"

+  NewId           - if an ID has been assigned

+  Flags           - characteristics for the identifier

+

+Returns:

+

+  STATUS

+

+--*/

+STATUS

+StringDBAddStringIdentifier (

+  WCHAR     *StringName,

+  UINT16    *NewId,

+  UINT16    Flags

+  )

+{

+  STRING_IDENTIFIER *StringIdentifier;

+  STATUS            Status;

+  //

+  // If it was already used for some other language, then we don't

+  // need to add it. But set it to the current string identifier.

+  // The referenced bit is sticky.

+  //

+  Status            = STATUS_SUCCESS;

+  StringIdentifier  = StringDBFindStringIdentifierByName (StringName);

+  if (StringIdentifier != NULL) {

+    if (Flags & STRING_FLAGS_REFERENCED) {

+      StringIdentifier->Flags |= STRING_FLAGS_REFERENCED;

+    }

+

+    mDBData.CurrentStringIdentifier = StringIdentifier;

+    *NewId                          = (UINT16) StringIdentifier->Index;

+    return Status;

+  }

+

+  StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER));

+  if (StringIdentifier == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation error");

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER));

+  StringIdentifier->StringName = (WCHAR *) malloc ((StrLen (StringName) + 1) * sizeof (WCHAR));

+  if (StringIdentifier->StringName == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation error");

+    return STATUS_ERROR;

+  }

+

+  StrCpy (StringIdentifier->StringName, StringName);

+  if (*NewId != STRING_ID_INVALID) {

+    StringIdentifier->Index = *NewId;

+    StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED;

+    if (mDBData.NumStringIdentifiers <= StringIdentifier->Index) {

+      mDBData.NumStringIdentifiers = StringIdentifier->Index + 1;

+    }

+  } else {

+    StringIdentifier->Index = mDBData.NumStringIdentifiers++;

+  }

+

+  StringIdentifier->Flags |= Flags;

+  //

+  // Add it to our list of string identifiers

+  //

+  if (mDBData.StringIdentifier == NULL) {

+    mDBData.StringIdentifier = StringIdentifier;

+  } else {

+    mDBData.LastStringIdentifier->Next = StringIdentifier;

+  }

+

+  mDBData.LastStringIdentifier    = StringIdentifier;

+  mDBData.CurrentStringIdentifier = StringIdentifier;

+  *NewId                          = (UINT16) StringIdentifier->Index;

+  return Status;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Add a new string to the database.

+

+Arguments:

+

+  LanguageName    - "eng" or "spa" language name

+  StringName      - "STR_MY_TEXT" string name

+  Scope           - from the #scope statements in the string file

+  Format          - if we should format the string

+  Flags           - characteristic flags for the string

+

+Returns:

+

+  STATUS

+

+Notes:

+

+  Several of the fields can be "inherited" from the previous calls to

+  our database functions. For example, if scope is NULL here, then

+  we'll use the previous setting.

+

+--*/

+STATUS

+StringDBAddString (

+  WCHAR   *LanguageName,

+  WCHAR   *StringName,

+  WCHAR   *Scope,

+  WCHAR   *String,

+  BOOLEAN Format,

+  UINT16  Flags

+  )

+{

+  LANGUAGE_LIST     *Lang;

+  UINT32            Size;

+  STRING_LIST       *Str;

+  UINT16            StringIndex;

+  WCHAR             TempLangName[4];

+  STRING_IDENTIFIER *StringIdentifier;

+

+  //

+  // Check that language name is exactly 3 characters, or emit an error.

+  // Truncate at 3 if it's longer, or make it 3 if it's shorter.

+  //

+  if (LanguageName != NULL) {

+    Size = StrLen (LanguageName);

+    if (Size != 3) {

+      ParserError (0, "invalid length for language name", "%S", LanguageName);

+      if (Size > 3) {

+        LanguageName[3] = 0;

+      } else {

+        //

+        // Make a local copy of the language name string, and extend to

+        // 3 characters since we make assumptions elsewhere in this program

+        // on the length.

+        //

+        StrCpy (TempLangName, LanguageName);

+        for (; Size < 3; Size++) {

+          TempLangName[Size] = L'?';

+        }

+

+        TempLangName[4] = 0;

+        LanguageName    = TempLangName;

+      }

+    }

+  }

+  //

+  // If they specified a language, make sure they've defined it already

+  // via a #langdef statement. Otherwise use the current default language.

+  //

+  if (LanguageName != NULL) {

+    Lang = StringDBFindLanguageList (LanguageName);

+    if (Lang == NULL) {

+      ParserError (0, "language not defined", "%S", LanguageName);

+      return STATUS_ERROR;

+    } else {

+      StringDBSetCurrentLanguage (LanguageName);

+    }

+  } else {

+    Lang = mDBData.CurrentLanguage;

+    if (Lang == NULL) {

+      //

+      // Have to call SetLanguage() first

+      //

+      ParserError (0, "no language defined", "%S", StringName);

+      return STATUS_ERROR;

+    }

+  }

+  //

+  // If they didn't define a string identifier, use the last string identifier

+  // added.

+  //

+  if (StringName == NULL) {

+    StringName = mDBData.CurrentStringIdentifier->StringName;

+    if (StringName == NULL) {

+      ParserError (0, "no string identifier previously specified", NULL);

+      return STATUS_ERROR;

+    }

+  }

+  //

+  // If scope was not specified, use the default setting

+  //

+  if (Scope != NULL) {

+    Scope = DuplicateString (Scope);

+  } else {

+    Scope = DuplicateString (mDBData.CurrentScope);

+  }

+  //

+  // printf ("Adding string: %S.%S.%S\n", Lang->LanguageName, StringName, Scope);

+  //

+  // Check for duplicates for this Language.StringName.Scope. Allow multiple

+  // definitions of the language name and printable language name, since the

+  // user does not specifically define them.

+  //

+  if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) {

+    if ((StrCmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) &&

+        (StrCmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0)

+        ) {

+      ParserError (

+        0,

+        "string multiply defined",

+        "Language.Name.Scope = %S.%S.%S",

+        Lang->LanguageName,

+        StringName,

+        Scope

+        );

+      return STATUS_ERROR;

+    }

+  }

+

+  StringIndex = STRING_ID_INVALID;

+  if (StringDBAddStringIdentifier (StringName, &StringIndex, Flags) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  StringIdentifier = StringDBFindStringIdentifierByName (StringName);

+  //

+  // Add this string to the end of the strings for this language.

+  //

+  Str = (STRING_LIST *) malloc (sizeof (STRING_LIST));

+  if (Str == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation error");

+    return STATUS_ERROR;

+  }

+

+  memset ((char *) Str, 0, sizeof (STRING_LIST));

+  Size              = (StrLen (String) + 1) * sizeof (WCHAR);

+  Str->Flags        = Flags;

+  Str->Scope        = Scope;

+  Str->StringName   = StringIdentifier->StringName;

+  Str->LanguageName = DuplicateString (LanguageName);

+  Str->Str          = (WCHAR *) MALLOC (Size);

+  if (Str->Str == NULL) {

+    Error (NULL, 0, 0, NULL, "memory allocation error");

+    return STATUS_ERROR;

+  }

+  //

+  // If not formatting, just copy the string.

+  //

+  StrCpy (Str->Str, String);

+  if (Format) {

+    StringDBFormatString (Str->Str);

+  }

+  //

+  // Size may change after formatting. We set the size to

+  // the actual size of the string, including the null for

+  // easier processing later.

+  //

+  Str->Size = (StrLen (Str->Str) + 1) * sizeof (WCHAR);

+  if (Lang->String == NULL) {

+    Lang->String = Str;

+  } else {

+    Lang->LastString->Next = Str;

+  }

+

+  Lang->LastString = Str;

+  return STATUS_SUCCESS;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Given a language name, see if a language list for it has been defined

+

+Arguments:

+

+  LanguageName    - like "eng"

+

+Returns:

+

+  A pointer to the language list

+

+--*/

+static

+LANGUAGE_LIST *

+StringDBFindLanguageList (

+  WCHAR *LanguageName

+  )

+{

+  LANGUAGE_LIST *Lang;

+

+  Lang = mDBData.LanguageList;

+  while (Lang != NULL) {

+    if (StrCmp (LanguageName, Lang->LanguageName) == 0) {

+      break;

+    }

+

+    Lang = Lang->Next;

+  }

+

+  return Lang;

+}

+

+/*****************************************************************************/

+STATUS

+StringDBSetCurrentLanguage (

+  WCHAR *LanguageName

+  )

+{

+  LANGUAGE_LIST *Lang;

+

+  Lang = StringDBFindLanguageList (LanguageName);

+  if (Lang == NULL) {

+    ParserError (0, "language not previously defined", "%S", LanguageName);

+    return STATUS_ERROR;

+  }

+

+  mDBData.CurrentLanguage = Lang;

+  return STATUS_SUCCESS;

+}

+

+/*****************************************************************************/

+STATUS

+StringDBAddLanguage (

+  WCHAR *LanguageName,

+  WCHAR *PrintableLanguageName

+  )

+{

+  LANGUAGE_LIST *Lang;

+  //

+  // Check for redefinitions

+  //

+  Lang = StringDBFindLanguageList (LanguageName);

+  if (Lang != NULL) {

+    //

+    // Better be the same printable name

+    //

+    if (StrCmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) {

+      ParserError (

+        0,

+        "language redefinition",

+        "%S:%S != %S:%S",

+        Lang->LanguageName,

+        Lang->PrintableLanguageName,

+        LanguageName,

+        PrintableLanguageName

+        );

+      return STATUS_ERROR;

+      //

+      //    } else {

+      //      ParserWarning (0, "benign language redefinition", "%S", PrintableLanguageName);

+      //      return STATUS_WARNING;

+      //

+    }

+  } else {

+    //

+    // Allocate memory to keep track of this new language

+    //

+    Lang = (LANGUAGE_LIST *) malloc (sizeof (LANGUAGE_LIST));

+    if (Lang == NULL) {

+      Error (NULL, 0, 0, NULL, "memory allocation error");

+      return STATUS_ERROR;

+    }

+

+    memset ((char *) Lang, 0, sizeof (LANGUAGE_LIST));

+    //

+    // Save the language name, then allocate memory to save the

+    // printable language name

+    //

+    StrCpy (Lang->LanguageName, LanguageName);

+    Lang->PrintableLanguageName = (WCHAR *) malloc ((StrLen (PrintableLanguageName) + 1) * sizeof (WCHAR));

+    if (Lang->PrintableLanguageName == NULL) {

+      Error (NULL, 0, 0, NULL, "memory allocation error");

+      return STATUS_ERROR;

+    }

+

+    StrCpy (Lang->PrintableLanguageName, PrintableLanguageName);

+

+    if (mDBData.LanguageList == NULL) {

+      mDBData.LanguageList = Lang;

+    } else {

+      mDBData.LastLanguageList->Next = Lang;

+    }

+

+    mDBData.LastLanguageList = Lang;

+  }

+  //

+  // Default is to make our active language this new one

+  //

+  StringDBSetCurrentLanguage (LanguageName);

+  //

+  // The first two strings for any language are the language name,

+  // followed by the printable language name. Add them and set them

+  // to referenced so they never get stripped out.

+  //

+  StringDBAddString (

+    LanguageName,

+    LANGUAGE_NAME_STRING_NAME,

+    NULL,

+    LanguageName,

+    FALSE,

+    STRING_FLAGS_REFERENCED

+    );

+  StringDBAddString (

+    LanguageName,

+    PRINTABLE_LANGUAGE_NAME_STRING_NAME,

+    NULL,

+    PrintableLanguageName,

+    FALSE,

+    STRING_FLAGS_REFERENCED

+    );

+  return STATUS_SUCCESS;

+}

+

+/*****************************************************************************/

+static

+STRING_IDENTIFIER *

+StringDBFindStringIdentifierByName (

+  WCHAR *StringName

+  )

+{

+  STRING_IDENTIFIER *Identifier;

+

+  Identifier = mDBData.StringIdentifier;

+  while (Identifier != NULL) {

+    if (StrCmp (StringName, Identifier->StringName) == 0) {

+      return Identifier;

+    }

+

+    Identifier = Identifier->Next;

+  }

+

+  return NULL;

+}

+

+static

+STRING_IDENTIFIER *

+StringDBFindStringIdentifierByIndex (

+  UINT32    StringIndex

+  )

+{

+  STRING_IDENTIFIER *Identifier;

+

+  Identifier = mDBData.StringIdentifier;

+  while (Identifier != NULL) {

+    if (Identifier->Index == StringIndex) {

+      return Identifier;

+    }

+

+    Identifier = Identifier->Next;

+  }

+

+  return NULL;

+}

+

+/*****************************************************************************/

+static

+void

+StringDBWriteStandardFileHeader (

+  FILE *OutFptr

+  )

+{

+  UINT32  TempIndex;

+  for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) {

+    fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]);

+  }

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+  

+  Given a Unicode string from an input file, reformat the string to replace

+  backslash control sequences with the appropriate encoding.

+

+Arguments:

+

+  String        - pointer to string to reformat

+

+Returns:

+

+  Nothing

+

+--*/

+void

+StringDBFormatString (

+  WCHAR   *String

+  )

+{

+  WCHAR *From;

+  WCHAR *To;

+  int   HexNibbles;

+  WCHAR HexValue;

+  //

+  // Go through the string and process any formatting characters

+  //

+  From  = String;

+  To    = String;

+  while (*From) {

+    if (*From == UNICODE_BACKSLASH) {

+      //

+      // First look for \wide and replace with the appropriate control character. Note that

+      // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is

+      // counted. Make adjustments for this. We advance From below, so subtract 2 each time.

+      //

+      if (StrnCmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) {

+        *To = WIDE_CHAR;

+        From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2;

+      } else if (StrnCmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) {

+        //

+        // Found: \narrow

+        //

+        *To = NARROW_CHAR;

+        From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2;

+      } else if (StrnCmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) {

+        //

+        // Found: \nbr

+        //

+        *To = NON_BREAKING_CHAR;

+        From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2;

+      } else if (StrnCmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) {

+        //

+        // Found: \br -- pass through untouched

+        //

+        *To = *From;

+      } else {

+        //

+        // Standard one-character control sequences such as \n, \r, \\, or \x

+        //

+        From++;

+        switch (*From) {

+        case ASCII_TO_UNICODE ('n'):

+          *To = UNICODE_CR;

+          To++;

+          *To = UNICODE_LF;

+          break;

+

+        //

+        // carriage return

+        //

+        case ASCII_TO_UNICODE ('r'):

+          *To = UNICODE_CR;

+          break;

+

+        //

+        // backslash

+        //

+        case UNICODE_BACKSLASH:

+          *To = UNICODE_BACKSLASH;

+          break;

+

+        //

+        // Tab

+        //

+        case ASCII_TO_UNICODE ('t'):

+          *To = UNICODE_TAB;

+          break;

+

+        //

+        // embedded double-quote

+        //

+        case UNICODE_DOUBLE_QUOTE:

+          *To = UNICODE_DOUBLE_QUOTE;

+          break;

+

+        //

+        // Hex Unicode character \x1234. We'll process up to 4 hex characters

+        //

+        case ASCII_TO_UNICODE ('x'):

+          HexValue = 0;

+          for (HexNibbles = 0; HexNibbles < 4; HexNibbles++) {

+            if ((From[1] >= UNICODE_0) && (From[1] <= UNICODE_9)) {

+              HexValue = (HexValue << 4) | (From[1] - UNICODE_0);

+            } else if ((From[1] >= UNICODE_a) && (From[1] <= UNICODE_f)) {

+              HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_a);

+            } else if ((From[1] >= UNICODE_A) && (From[1] <= UNICODE_F)) {

+              HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_A);

+            } else {

+              break;

+            }

+

+            From++;

+          }

+

+          if (HexNibbles == 0) {

+            ParserWarning (

+              0,

+              "expected at least one valid hex digit with \\x escaped character in string",

+              "\\%C",

+              *From

+              );

+          } else {

+            *To = HexValue;

+          }

+          break;

+

+        default:

+          *To = UNICODE_SPACE;

+          ParserWarning (0, "invalid escaped character in string", "\\%C", *From);

+          break;

+        }

+      }

+    } else {

+      *To = *From;

+    }

+

+    From++;

+    To++;

+  }

+

+  *To = 0;

+}

+

+/*****************************************************************************/

+STATUS

+StringDBReadDatabase (

+  INT8    *DBFileName,

+  BOOLEAN IgnoreIfNotExist,

+  BOOLEAN Verbose

+  )

+{

+  STRING_DB_HEADER    DbHeader;

+  STATUS              Status;

+  FILE                *DBFptr;

+  DB_DATA_ITEM_HEADER DataItemHeader;

+

+  Status  = STATUS_SUCCESS;

+  DBFptr  = NULL;

+  //

+  //  if (Verbose) {

+  //    fprintf (stdout, "Reading database file %s\n", DBFileName);

+  //  }

+  //

+  // Try to open the input file

+  //

+  if ((DBFptr = fopen (DBFileName, "rb")) == NULL) {

+    if (IgnoreIfNotExist) {

+      return STATUS_SUCCESS;

+    }

+

+    Error (NULL, 0, 0, DBFileName, "failed to open input database file for reading");

+    return STATUS_ERROR;

+  }

+  //

+  // Read and verify the database header

+  //

+  if (fread ((void *) &DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, DBFileName, "failed to read header from database file");

+    Status = STATUS_ERROR;

+    goto Finish;

+  }

+

+  if (DbHeader.Key != STRING_DB_KEY) {

+    Error (NULL, 0, 0, DBFileName, "invalid header in database file");

+    Status = STATUS_ERROR;

+    goto Finish;

+  }

+

+  if ((DbHeader.Version & STRING_DB_MAJOR_VERSION_MASK) != (STRING_DB_VERSION & STRING_DB_MAJOR_VERSION_MASK)) {

+    Error (NULL, 0, 0, DBFileName, "incompatible database file version -- rebuild clean");

+    Status = STATUS_ERROR;

+    goto Finish;

+  }

+  //

+  // Read remaining items

+  //

+  while (fread (&DataItemHeader, sizeof (DataItemHeader), 1, DBFptr) == 1) {

+    switch (DataItemHeader.DataType) {

+    case DB_DATA_TYPE_STRING_IDENTIFIER:

+      StringDBReadStringIdentifier (DBFptr);

+      break;

+

+    case DB_DATA_TYPE_LANGUAGE_DEFINITION:

+      StringDBReadLanguageDefinition (DBFptr);

+      break;

+

+    case DB_DATA_TYPE_STRING_DEFINITION:

+      StringDBReadString (DBFptr);

+      break;

+

+    default:

+      Error (

+        NULL,

+        0,

+        0,

+        "database corrupted",

+        "invalid data item type 0x%X at offset 0x%X",

+        (UINT32) DataItemHeader.DataType,

+        ftell (DBFptr) - sizeof (DataItemHeader)

+        );

+      Status = STATUS_ERROR;

+      goto Finish;

+    }

+  }

+

+Finish:

+  if (DBFptr != NULL) {

+    fclose (DBFptr);

+  }

+

+  return Status;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+  

+  Write everything we know to the output database file. Write:

+

+  Database header

+  String identifiers[]

+  StringPacks[]

+

+Arguments:

+

+  DBFileName    - name of the file to write to

+  Verbose       - for debug purposes, print info messages along the way.

+

+Returns:

+

+  STATUS

+

+--*/

+STATUS

+StringDBWriteDatabase (

+  INT8    *DBFileName,

+  BOOLEAN Verbose

+  )

+{

+  STRING_DB_HEADER  DbHeader;

+  UINT32            Counter;

+  UINT32            StrLength;

+  LANGUAGE_LIST     *Lang;

+  STRING_IDENTIFIER *StringIdentifier;

+  STRING_LIST       *StrList;

+  FILE              *DBFptr;

+

+  if (Verbose) {

+    fprintf (stdout, "Writing database %s\n", DBFileName);

+  }

+

+  if ((DBFptr = fopen (DBFileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, DBFileName, "failed to open output database file for writing");

+    return STATUS_ERROR;

+  }

+  //

+  // Fill in and write the database header

+  //

+  memset (&DbHeader, 0, sizeof (STRING_DB_HEADER));

+  DbHeader.HeaderSize = sizeof (STRING_DB_HEADER);

+  DbHeader.Key        = STRING_DB_KEY;

+  DbHeader.Version    = STRING_DB_VERSION;

+  //

+  // Count the number of languages we have

+  //

+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {

+    DbHeader.NumLanguages++;

+  }

+  //

+  // Count up how many string identifiers we have, and total up the

+  // size of the names plus the size of the flags field we will

+  // write out too.

+  //

+  DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers;

+  StringIdentifier            = mDBData.StringIdentifier;

+  for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) {

+    StrLength = StrLen (StringIdentifier->StringName) + 1;

+    DbHeader.StringIdentifiersSize += StrLength * sizeof (WCHAR) + sizeof (StringIdentifier->Flags);

+    StringIdentifier = StringIdentifier->Next;

+  }

+

+  //

+  // Write the header

+  //

+  fwrite (&DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr);

+  if (Verbose) {

+    fprintf (stdout, "  Number of string identifiers  0x%04X\n", DbHeader.NumStringIdenfiers);

+    fprintf (stdout, "  Number of languages           %d\n", DbHeader.NumLanguages);

+  }

+  //

+  // Write the string identifiers

+  //

+  for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) {

+    StringDBWriteStringIdentifier (

+      DBFptr,

+      (UINT16) StringIdentifier->Index,

+      StringIdentifier->Flags,

+      StringIdentifier->StringName

+      );

+  }

+  //

+  // Now write all the strings for each language

+  //

+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {

+    StringDBWriteLanguageDefinition (DBFptr, Lang->LanguageName, Lang->PrintableLanguageName);

+    for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) {

+      StringDBWriteString (

+        DBFptr,

+        StrList->Flags,

+        Lang->LanguageName,

+        StrList->StringName,

+        StrList->Scope,

+        StrList->Str

+        );

+    }

+  }

+

+  fclose (DBFptr);

+  return STATUS_SUCCESS;

+}

+

+STATUS

+StringDBSetStringReferenced (

+  INT8      *StringIdentifierName,

+  BOOLEAN   IgnoreNotFound

+  )

+{

+  STRING_IDENTIFIER *Id;

+  WCHAR             *WName;

+  STATUS            Status;

+  //

+  // See if it's already been defined.

+  //

+  Status  = STATUS_SUCCESS;

+  WName   = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR));

+  UnicodeSPrint (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%a", StringIdentifierName);

+  Id = StringDBFindStringIdentifierByName (WName);

+  if (Id != NULL) {

+    Id->Flags |= STRING_FLAGS_REFERENCED;

+  } else {

+    if (IgnoreNotFound == 0) {

+      ParserWarning (0, StringIdentifierName, "string identifier not found in database");

+      Status = STATUS_WARNING;

+    }

+  }

+

+  free (WName);

+  return Status;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Dump the contents of a database to an output unicode file.

+

+Arguments:

+

+  DBFileName        - name of the pre-existing database file to read

+  OutputFileName    - name of the file to dump the database contents to

+  Verbose           - for printing of additional info useful for debugging

+

+Returns:

+

+  STATUS

+

+Notes:

+

+  There's some issue with the unicode printing routines. Therefore to 

+  write to the output file properly, open it as binary and use fwrite.

+  Ideally we could open it with just L"w" and use fwprintf().

+

+--*/

+STATUS

+StringDBDumpDatabase (

+  INT8                *DBFileName,

+  INT8                *OutputFileName,

+  BOOLEAN             Verbose

+  )

+{

+  LANGUAGE_LIST     *Lang;

+  STRING_IDENTIFIER *StringIdentifier;

+  STRING_LIST       *StrList;

+  FILE              *OutFptr;

+  WCHAR             WChar;

+  WCHAR             CrLf[2];

+  WCHAR             Line[200];

+  WCHAR             *Scope;

+  //

+  // This function assumes the database has already been read, and

+  // we're just dumping our internal data structures to a unicode file.

+  //

+  if (Verbose) {

+    fprintf (stdout, "Dumping database file %s\n", DBFileName);

+  }

+

+  OutFptr         = fopen (OutputFileName, "wb");

+  if (OutFptr == NULL) {

+    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");

+    return STATUS_ERROR;

+  }

+

+  WChar = UNICODE_FILE_START;

+  fwrite (&WChar, sizeof (WCHAR), 1, OutFptr);

+  CrLf[1] = UNICODE_LF;

+  CrLf[0] = UNICODE_CR;

+  //

+  // The default control character is '/'. Make it '#' by writing

+  // "/=#" to the output file.

+  //

+  UnicodeSPrint (Line, sizeof(Line), L"/=#");

+  fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+  //

+  // Dump all the string identifiers and their values

+  //

+  StringDBAssignStringIndexes ();

+  for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) {

+    //

+    // Write the "#define " string

+    //

+    if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {

+      UnicodeSPrint (

+        Line,

+        sizeof(Line), L"%s %-60.60s 0x%04X",

+        DEFINE_STR,

+        StringIdentifier->StringName,

+        StringIdentifier->Index

+        );

+    } else {

+      UnicodeSPrint (

+        Line,

+        sizeof(Line), L"%s %-60.60s 0x%04X  // NOT REFERENCED",

+        DEFINE_STR,

+        StringIdentifier->StringName,

+        StringIdentifier->Index

+        );

+    }

+

+    fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+  }

+

+  fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+  //

+  // Now write all the strings for each language.

+  //

+  WChar = UNICODE_DOUBLE_QUOTE;

+  Scope = NULL;

+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {

+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+    UnicodeSPrint (Line, sizeof(Line), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);

+    fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+    fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+    //

+    // Now the strings (in double-quotes) for this language. Write

+    // #string STR_NAME  #language eng "string"

+    //

+    for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) {

+      //

+      // Print the internal flags for debug

+      //

+      UnicodeSPrint (Line, sizeof(Line), L"// flags=0x%02X", (UINT32) StrList->Flags);

+      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+      //

+      // Print the scope if changed

+      //

+      if ((Scope == NULL) || (StrCmp (Scope, StrList->Scope) != 0)) {

+        UnicodeSPrint (Line, sizeof(Line), L"#scope %s", StrList->Scope);

+        fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+        fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+        Scope = StrList->Scope;

+      }

+

+      UnicodeSPrint (

+        Line,

+        sizeof(Line), L"#string %-50.50s #language %s \"",

+        StrList->StringName,

+        Lang->LanguageName

+        );

+      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+      fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr);

+      UnicodeSPrint (Line, sizeof(Line), L"\"");

+      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);

+      fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);

+    }

+  }

+

+  fclose (OutFptr);

+  return STATUS_SUCCESS;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Given a primary language, a string identifier number, and a list of

+  languages, find a secondary string.

+

+Arguments:

+

+  LanguageName      - primary language, like "spa"

+  StringId          - string index value

+  LanguageList      - linked list of "eng", "spa+cat",...

+

+Returns:

+

+  Pointer to a secondary string if found. NULL otherwise.

+

+Notes:

+ 

+  Given: LanguageName "spa"   and  LanguageList "spa+cat", match the

+  "spa" and extract the "cat" and see if there is a string defined

+  for "cat".StringId.

+

+--*/

+static

+STATUS

+StringDBWriteStringIdentifier (

+  FILE                *DBFptr,

+  UINT16              StringId,

+  UINT16              Flags,

+  WCHAR               *IdentifierName

+  )

+{

+  DB_DATA_ITEM_HEADER Hdr;

+  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));

+  Hdr.DataType = DB_DATA_TYPE_STRING_IDENTIFIER;

+  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write string to output database file", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fwrite (&StringId, sizeof (StringId), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write StringId to output database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write StringId flags to output database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, IdentifierName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+StringDBReadStringIdentifier (

+  FILE                *DBFptr

+  )

+{

+  WCHAR   *IdentifierName;

+  UINT16  Flags;

+  UINT16  StringId;

+  UINT16  Size;

+

+  if (fread (&StringId, sizeof (StringId), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to read StringId from database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to read StringId flags from database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (StringDBReadGenericString (DBFptr, &Size, &IdentifierName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  StringDBAddStringIdentifier (IdentifierName, &StringId, Flags);

+  //

+  // printf ("STRID:  0x%04X %S\n", (UINT32)StringId, IdentifierName);

+  //

+  FREE (IdentifierName);

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+StringDBWriteString (

+  FILE            *DBFptr,

+  UINT16          Flags,

+  WCHAR           *Language,

+  WCHAR           *StringName,

+  WCHAR           *Scope,

+  WCHAR           *Str

+  )

+{

+  DB_DATA_ITEM_HEADER Hdr;

+  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));

+  Hdr.DataType = DB_DATA_TYPE_STRING_DEFINITION;

+  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write string header to output database file", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write string flags to output database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, Language) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, StringName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, Scope) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, Str) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+  //

+  // printf ("DBWriteString: %S.%S.%S\n", Language, StringName, Scope);

+  //

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+StringDBReadString (

+  FILE            *DBFptr

+  )

+{

+  UINT16  Flags;

+  UINT16  Size;

+  WCHAR   *Language;

+  WCHAR   *StringName;

+  WCHAR   *Scope;

+  WCHAR   *Str;

+

+  if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to read string flags from database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (StringDBReadGenericString (DBFptr, &Size, &Language) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBReadGenericString (DBFptr, &Size, &StringName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBReadGenericString (DBFptr, &Size, &Scope) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBReadGenericString (DBFptr, &Size, &Str) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+  //

+  // If the first or second string (language name and printable language name),

+  // then skip them. They're added via language definitions data items in

+  // the database.

+  //

+  if (StringName[0] != L'$') {

+    StringDBAddString (Language, StringName, Scope, Str, FALSE, Flags);

+  }

+  //

+  // printf ("DBReadString: %S.%S.%S\n", Language, StringName, Scope);

+  //

+  FREE (Language);

+  FREE (StringName);

+  if (Str != NULL) {

+    FREE (Str);

+  }

+

+  if (Scope != NULL) {

+    FREE (Scope);

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+StringDBWriteLanguageDefinition (

+  FILE            *DBFptr,

+  WCHAR           *LanguageName,

+  WCHAR           *PrintableLanguageName

+  )

+{

+  DB_DATA_ITEM_HEADER Hdr;

+  memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER));

+  Hdr.DataType = DB_DATA_TYPE_LANGUAGE_DEFINITION;

+  if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write string to output database file", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, LanguageName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBWriteGenericString (DBFptr, PrintableLanguageName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+StringDBReadLanguageDefinition (

+  FILE            *DBFptr

+  )

+{

+  WCHAR   *LanguageName;

+  WCHAR   *PrintableLanguageName;

+  UINT16  Size;

+  STATUS  Status;

+

+  if (StringDBReadGenericString (DBFptr, &Size, &LanguageName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+

+  if (StringDBReadGenericString (DBFptr, &Size, &PrintableLanguageName) != STATUS_SUCCESS) {

+    return STATUS_ERROR;

+  }

+  //

+  // printf("LANG: %S %S\n", LanguageName, PrintableLanguageName);

+  //

+  Status = StringDBAddLanguage (LanguageName, PrintableLanguageName);

+  FREE (LanguageName);

+  FREE (PrintableLanguageName);

+  return Status;

+}

+//

+// All unicode strings in the database consist of a UINT16 length

+// field, followed by the string itself. This routine reads one

+// of those and returns the info.

+//

+static

+STATUS

+StringDBReadGenericString (

+  FILE      *DBFptr,

+  UINT16    *Size,

+  WCHAR     **Str

+  )

+{

+  UINT16  LSize;

+  UINT16  Flags;

+  WCHAR   *LStr;

+

+  if (fread (&LSize, sizeof (UINT16), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to read a string length field from the database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fread (&Flags, sizeof (UINT16), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to read a string flags field from the database", NULL);

+    return STATUS_ERROR;

+  }

+

+  LStr = MALLOC (LSize);

+  if (LStr == NULL) {

+    Error (__FILE__, __LINE__, 0, "memory allocation failed reading the database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fread (LStr, sizeof (WCHAR), (UINT32) LSize / sizeof (WCHAR), DBFptr) != (UINT32) LSize / sizeof (WCHAR)) {

+    Error (NULL, 0, 0, "failed to read string from database", NULL);

+    Error (NULL, 0, 0, "database read failure", "offset 0x%X", ftell (DBFptr));

+    free (LStr);

+    return STATUS_ERROR;

+  }

+  //

+  // printf ("DBR: %S\n", LStr);

+  //

+  // If the flags field indicated we were asked to write a NULL string, then

+  // return them a NULL pointer.

+  //

+  if (Flags & STRING_FLAGS_UNDEFINED) {

+    *Size = 0;

+    *Str  = NULL;

+  } else {

+    *Size = LSize;

+    *Str  = LStr;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STATUS

+StringDBWriteGenericString (

+  FILE      *DBFptr,

+  WCHAR     *Str

+  )

+{

+  UINT16  Size;

+  UINT16  Flags;

+  WCHAR   ZeroString[1];

+  //

+  // Strings in the database consist of a size UINT16 followed

+  // by the string itself.

+  //

+  if (Str == NULL) {

+    ZeroString[0] = 0;

+    Str           = ZeroString;

+    Size          = sizeof (ZeroString);

+    Flags         = STRING_FLAGS_UNDEFINED;

+  } else {

+    Flags = 0;

+    Size  = (UINT16) ((StrLen (Str) + 1) * sizeof (WCHAR));

+  }

+

+  if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write string size to database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fwrite (&Flags, sizeof (UINT16), 1, DBFptr) != 1) {

+    Error (NULL, 0, 0, "failed to write string flags to database", NULL);

+    return STATUS_ERROR;

+  }

+

+  if (fwrite (Str, sizeof (WCHAR), Size / sizeof (WCHAR), DBFptr) != Size / sizeof (WCHAR)) {

+    Error (NULL, 0, 0, "failed to write string to database", NULL);

+    return STATUS_ERROR;

+  }

+

+  return STATUS_SUCCESS;

+}

+

+static

+STRING_LIST *

+StringDBFindString (

+  WCHAR                       *LanguageName,

+  WCHAR                       *StringName,

+  WCHAR                       *Scope,

+  WCHAR_STRING_LIST           *LanguagesOfInterest,

+  WCHAR_MATCHING_STRING_LIST  *IndirectionList

+  )

+{

+  LANGUAGE_LIST               *Lang;

+  STRING_LIST                 *CurrString;

+  WCHAR_MATCHING_STRING_LIST  *IndListPtr;

+  WCHAR                       TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN + 1];

+  WCHAR                       *WCharPtr;

+

+  //

+  // If we were given an indirection list, then see if one was specified for this

+  // string identifier. That is to say, if the indirection says "STR_ID_MY_FAVORITE MyScope",

+  // then if this string name matches one in the list, then do a lookup with the

+  // specified scope and return that value.

+  //

+  if (IndirectionList != NULL) {

+    for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) {

+      if (StrCmp (StringName, IndListPtr->Str1) == 0) {

+        CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL);

+        if (CurrString != NULL) {

+          return CurrString;

+        }

+      }

+    }

+  }

+  //

+  // First look for exact match language.stringname

+  //

+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {

+    if (StrCmp (LanguageName, Lang->LanguageName) == 0) {

+      //

+      // Found language match. Try to find string name match

+      //

+      for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) {

+        if (StrCmp (StringName, CurrString->StringName) == 0) {

+          //

+          // Found a string name match. See if we're supposed to find

+          // a scope match.

+          //

+          if (Scope != NULL) {

+            if (StrCmp (CurrString->Scope, Scope) == 0) {

+              return CurrString;

+            }

+          } else {

+            return CurrString;

+          }

+        }

+      }

+    }

+  }

+  //

+  // If we got here, then we didn't find a match. Look for secondary string

+  // matches. That is to say, if we're processing "spa", and they requested

+  // "spa+cat", then recursively call with "cat"

+  //

+  while (LanguagesOfInterest != NULL) {

+    //

+    // If this is the language we're looking for, then process the

+    // languages of interest list for it.

+    //

+    if (StrnCmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {

+      WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN;

+      while (*WCharPtr) {

+        //

+        // Double-check the length, though it should have been checked on the

+        // command line.

+        //

+        if (StrLen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) {

+          Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str);

+          return NULL;

+        }

+

+        StrnCpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN);

+        TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN]  = 0;

+        CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList);

+        if (CurrString != NULL) {

+          return CurrString;

+        }

+

+        WCharPtr += LANGUAGE_IDENTIFIER_NAME_LEN;

+      }

+    }

+

+    LanguagesOfInterest = LanguagesOfInterest->Next;

+  }

+

+  return NULL;

+}

+

+STATUS

+StringDBSetScope (

+  WCHAR   *Scope

+  )

+{

+  //

+  // Free up existing scope memory.

+  //

+  if (mDBData.CurrentScope != NULL) {

+    FREE (mDBData.CurrentScope);

+  }

+

+  mDBData.CurrentScope = DuplicateString (Scope);

+  return STATUS_SUCCESS;

+}

+//

+// We typically don't assign index values to string identifiers

+// until we're ready to write out files. To reduce the size of

+// the output file, re-order the string identifiers to move any

+// unreferenced ones to the end. Then we'll walk the list

+// again to assign string indexes, keeping track of the last

+// one referenced.

+//

+static

+void

+StringDBAssignStringIndexes (

+  VOID

+  )

+{

+  STRING_IDENTIFIER *StrId;

+  STRING_IDENTIFIER *FirstUsed;

+  STRING_IDENTIFIER *LastUsed;

+  STRING_IDENTIFIER *FirstUnused;

+  STRING_IDENTIFIER *LastUnused;

+  UINT32            Index;

+  UINT32            MaxReferenced;

+

+  //

+  // Create two lists -- used and unused. Then put them together with

+  // the unused ones on the end.

+  //

+  FirstUsed   = NULL;

+  LastUsed    = NULL;

+  FirstUnused = NULL;

+  LastUnused  = NULL;

+  StrId       = mDBData.StringIdentifier;

+  while (StrId != NULL) {

+    if ((StrId->Flags & STRING_FLAGS_REFERENCED) == 0) {

+      //

+      // Put it on the unused list

+      //

+      if (FirstUnused == NULL) {

+        FirstUnused = StrId;

+      } else {

+        LastUnused->Next = StrId;

+      }

+

+      LastUnused        = StrId;

+      StrId             = StrId->Next;

+      LastUnused->Next  = NULL;

+    } else {

+      //

+      // Put it on the used list

+      //

+      if (FirstUsed == NULL) {

+        FirstUsed = StrId;

+      } else {

+        LastUsed->Next = StrId;

+      }

+

+      LastUsed        = StrId;

+      StrId           = StrId->Next;

+      LastUsed->Next  = NULL;

+    }

+  }

+  //

+  // Join the lists

+  //

+  if (FirstUsed != NULL) {

+    mDBData.StringIdentifier  = FirstUsed;

+    LastUsed->Next            = FirstUnused;

+  } else {

+    mDBData.StringIdentifier = FirstUnused;

+  }

+

+  MaxReferenced = 0;

+  Index         = 0;

+  for (StrId = mDBData.StringIdentifier; StrId != NULL; StrId = StrId->Next) {

+    StrId->Index = Index;

+    Index++;

+    if (StrId->Flags & STRING_FLAGS_REFERENCED) {

+      mDBData.NumStringIdentifiersReferenced = Index;

+    }

+  }

+

+  mDBData.NumStringIdentifiers = Index;

+}

+

+static

+WCHAR *

+DuplicateString (

+  WCHAR   *Str

+  )

+{

+  WCHAR *NewStr;

+  if (Str == NULL) {

+    return NULL;

+  }

+

+  NewStr = MALLOC ((StrLen (Str) + 1) * sizeof (WCHAR));

+  if (NewStr == NULL) {

+    Error (NULL, 0, 0, "memory allocation failure", NULL);

+    return NULL;

+  }

+

+  StrCpy (NewStr, Str);

+  return NewStr;

+}

+

+static

+WCHAR *

+AsciiToWchar (

+  INT8 *Str

+  )

+{

+  UINT32  Len;

+  WCHAR   *NewStr;

+  WCHAR   *Ptr;

+

+  Len     = strlen (Str) + 1;

+  NewStr  = (WCHAR *) malloc (Len * sizeof (WCHAR));

+  for (Ptr = NewStr; *Str != 0; Str++, Ptr++) {

+    *Ptr = (UINT16) (UINT8) *Str;

+  }

+

+  *Ptr = 0;

+  return NewStr;

+}

+

+/*****************************************************************************/

+

+/*++

+

+Routine Description:

+

+  Create an HII export string pack for the strings in our database.

+

+Arguments:

+

+  FileName        - name of the output file to write 

+

+Returns:

+

+  STATUS

+

+

+--*/

+STATUS

+StringDBCreateHiiExportPack (

+  INT8                        *FileName

+  )

+{

+  FILE                        *Fptr;

+  LANGUAGE_LIST               *Lang;

+  STRING_LIST                 *CurrString;

+  STRING_LIST                 EmptyString;

+  UINT32                      Offset;

+  UINT32                      StringIndex;

+  UINT32                      TempIndex;

+  EFI_HII_STRING_PACK         StringPack;

+  UINT32                      Len;

+  WCHAR                       ZeroString[1];

+  WCHAR                       *TempStringPtr;

+  WCHAR                       *LangName;

+  STRING_IDENTIFIER           *StringIdentifier;

+

+  if ((Fptr = fopen (FileName, "wb")) == NULL) {

+    Error (NULL, 0, 0, FileName, "failed to open output HII export file");

+    return STATUS_ERROR;

+  }

+  //

+  // Assign index values to the string identifiers

+  //

+  StringDBAssignStringIndexes ();

+  //

+  // If a given string is not defined, then we'll use this one.

+  //

+  memset (&EmptyString, 0, sizeof (EmptyString));

+  EmptyString.Size  = sizeof (ZeroString);

+  EmptyString.Str   = ZeroString;

+  //

+  // Process each language, then each string for each langage

+  //

+  ZeroString[0] = 0;

+  for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {

+    //

+    // Process each string for this language. We have to make 3 passes on the strings:

+    //   Pass1: computes sizes and fill in the string pack header

+    //   Pass2: write the array of offsets

+    //   Pass3: write the strings

+    //

+    //

+    // PASS 1: Fill in and print the HII string pack header

+    //

+    // Compute the size for this language package and write

+    // the header out. Each string package contains:

+    //   Header

+    //   Offset[]  -- an array of offsets to strings, of type RELOFST each

+    //   String[]  -- the actual strings themselves

+    //

+    memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));

+    StringPack.Header.Type        = EFI_HII_STRING;

+    StringPack.NumStringPointers  = (UINT16) mDBData.NumStringIdentifiersReferenced;

+    LangName                      = Lang->LanguageName;

+    //

+    // First string is the language name. If we're printing all languages, then

+    // it's just the "spa". If we were given a list of languages to print, then it's

+    // the "spacat" string. Compute its offset and fill in

+    // the info in the header. Since we know the language name string's length,

+    // and the printable language name follows it, use that info to fill in the

+    // entry for the printable language name as well.

+    //

+    StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));

+    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR));

+    //

+    // Add up the size of all strings so we can fill in our header.

+    //

+    Len = 0;

+    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {

+      //

+      // For the first string (language name), we print out the "spacat" if they

+      // requested it. We set LangName to point to the proper language name string above.

+      //

+      if (StringIndex == STRING_ID_LANGUAGE_NAME) {

+        Len += (StrLen (LangName) + 1) * sizeof (WCHAR);

+      } else {

+        //

+        // Find a string with this language.stringname

+        //

+        StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+        if (StringIdentifier == NULL) {

+          Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);

+          return STATUS_ERROR;

+        }

+        //

+        // Find a matching string if this string identifier was referenced

+        //

+        EmptyString.Flags = STRING_FLAGS_UNDEFINED;

+        CurrString        = NULL;

+        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {

+          CurrString = StringDBFindString (

+                        Lang->LanguageName,

+                        StringIdentifier->StringName,

+                        NULL,

+                        NULL, // LanguagesOfInterest,

+                        NULL

+                        );

+          //

+          // IndirectionList);

+          //

+          if (NULL == CurrString) {

+            //

+            // If string for Lang->LanguageName is not found, try to get an English version

+            //

+            CurrString = StringDBFindString (

+                          L"eng",

+                          StringIdentifier->StringName,

+                          NULL,

+                          NULL, // LanguagesOfInterest,

+                          NULL

+                          );

+            //

+            // IndirectionList);

+            //

+          }

+        }

+

+        if (CurrString == NULL) {

+          CurrString = &EmptyString;

+          EmptyString.Flags |= StringIdentifier->Flags;

+        }

+

+        Len += CurrString->Size;

+      }

+    }

+    StringPack.Header.Length =    sizeof (EFI_HII_STRING_PACK) 

+                                + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) 

+                                + Len;

+    //

+    // Write out the string pack header

+    //

+    fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr);

+    //

+    // PASS2 : write the offsets

+    //

+    // Traverse the list of strings again and write the array of offsets. The

+    // offset to the first string is the size of the string pack header

+    // plus the size of the offsets array. The other strings follow it.

+    //

+    StringIndex = 0;

+    Offset      = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);

+    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {

+      //

+      // Write the offset

+      //

+      fwrite (&Offset, sizeof (STRING_OFFSET), 1, Fptr);

+      //

+      // Find the string name

+      //

+      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+      if (StringIdentifier == NULL) {

+        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);

+        return STATUS_ERROR;

+      }

+      //

+      // For the first string (language name), we print out the "spacat" if they

+      // requested it. We set LangName to point to the proper language name string above.

+      //

+      if (StringIndex == STRING_ID_LANGUAGE_NAME) {

+        Offset += (StrLen (LangName) + 1) * sizeof (WCHAR);

+        CurrString = StringDBFindString (

+                      Lang->LanguageName,

+                      StringIdentifier->StringName,

+                      NULL, // scope

+                      NULL,

+                      NULL

+                      );

+      } else {

+        //

+        // Find a matching string

+        //

+        CurrString = StringDBFindString (

+                      Lang->LanguageName,

+                      StringIdentifier->StringName,

+                      NULL, // scope

+                      NULL, // LanguagesOfInterest,

+                      NULL

+                      );

+        //

+        // IndirectionList);

+        //

+        if (NULL == CurrString) {

+          CurrString = StringDBFindString (

+                        L"eng",

+                        StringIdentifier->StringName,

+                        NULL, // scope

+                        NULL, // LanguagesOfInterest,

+                        NULL

+                        );

+          //

+          // IndirectionList);

+          //

+        }

+

+        EmptyString.LanguageName = Lang->LanguageName;

+        if (CurrString == NULL) {

+          CurrString        = &EmptyString;

+          EmptyString.Flags = STRING_FLAGS_UNDEFINED;

+        } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {

+          CurrString        = &EmptyString;

+          EmptyString.Flags = 0;

+        }

+

+        Offset += CurrString->Size;

+      }

+    }

+

+    //

+    // PASS 3: write the strings themselves.

+    //

+    Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);

+    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {

+      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);

+      if (StringIdentifier == NULL) {

+        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);

+        return STATUS_ERROR;

+      }

+      //

+      // For the first string (language name), we print out the "spacat" if they

+      // requested it. We set LangName to point to the proper language name string above.

+      //

+      if (StringIndex == STRING_ID_LANGUAGE_NAME) {

+        TempStringPtr = LangName;

+      } else {

+        //

+        // Find a matching string if this string identifier was referenced

+        //

+        CurrString = NULL;

+        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {

+          CurrString = StringDBFindString (

+                        Lang->LanguageName,

+                        StringIdentifier->StringName,

+                        NULL, // scope

+                        NULL, // LanguagesOfInterest,

+                        NULL

+                        );

+          //

+          // IndirectionList);

+          //

+          if (NULL == CurrString) {

+            CurrString = StringDBFindString (

+                          L"eng",

+                          StringIdentifier->StringName,

+                          NULL, // scope

+                          NULL, // LanguagesOfInterest,

+                          NULL

+                          );

+            //

+            // IndirectionList);

+            //

+          }

+        }

+

+        if (CurrString == NULL) {

+          CurrString = &EmptyString;

+        }

+

+        TempStringPtr = CurrString->Str;

+      }

+

+      for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) {

+        fwrite (&TempStringPtr[TempIndex], sizeof (CHAR16), 1, Fptr);

+        Offset += 2;

+      }

+      //

+      // Print NULL WCHAR at the end of this string.

+      //

+      TempIndex = 0;

+      fwrite (&TempIndex, sizeof (CHAR16), 1, Fptr);

+      Offset += 2;

+    }

+    //

+    // Sanity check the offset. Make sure our running offset is what we put in the

+    // string pack header.

+    //

+    if (StringPack.Header.Length != Offset) {

+      Error (

+        __FILE__,

+        __LINE__,

+        0,

+        "application error",

+        "stringpack size 0x%X does not match final size 0x%X",

+        StringPack.Header.Length,

+        Offset

+        );

+    }

+  }

+  //

+  // Print terminator string pack, closing brace and close the file.

+  // The size of 0 triggers to the consumer that this is the end.

+  //

+  memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));

+  StringPack.Header.Type = EFI_HII_STRING;

+  fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr);

+  fclose (Fptr);

+  return STATUS_SUCCESS;

+}

diff --git a/edk2/Tools/Source/TianoTools/StrGather/StringDB.h b/edk2/Tools/Source/TianoTools/StrGather/StringDB.h
new file mode 100644
index 0000000..4dc05a3
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/StrGather/StringDB.h
@@ -0,0 +1,136 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  StringDB.h

+

+Abstract:

+

+  Common defines and prototypes for string database management

+  

+--*/

+

+#ifndef _STRING_DB_H_

+#define _STRING_DB_H_

+

+#define LANGUAGE_NAME_STRING_NAME           L"$LANGUAGE_NAME"

+#define PRINTABLE_LANGUAGE_NAME_STRING_NAME L"$PRINTABLE_LANGUAGE_NAME"

+

+void

+StringDBConstructor (

+  void

+  )

+;

+void

+StringDBDestructor (

+  void

+  )

+;

+

+STATUS

+StringDBAddString (

+  WCHAR   *LanguageName,

+  WCHAR   *StringIdentifier,

+  WCHAR   *Scope,

+  WCHAR   *String,

+  BOOLEAN Format,

+  UINT16  Flags

+  )

+;

+

+STATUS

+StringDBSetScope (

+  WCHAR   *Scope

+  )

+;

+

+#define STRING_FLAGS_REFERENCED           0x0001  // if referenced somewhere

+#define STRING_FLAGS_UNDEFINED            0x0002  // if we added it for padding purposes

+#define STRING_FLAGS_INDEX_ASSIGNED       0x0004  // so don't change the index value

+#define STRING_ID_INVALID                 0xFFFF

+#define STRING_ID_LANGUAGE_NAME           0x0000

+#define STRING_ID_PRINTABLE_LANGUAGE_NAME 0x0001

+

+STATUS

+StringDBAddStringIdentifier (

+  WCHAR     *StringIdentifier,

+  UINT16    *NewId,

+  UINT16    Flags

+  )

+;

+

+STATUS

+StringDBReadDatabase (

+  INT8    *DBFileName,

+  BOOLEAN IgnoreIfNotExist,

+  BOOLEAN Verbose

+  )

+;

+

+STATUS

+StringDBWriteDatabase (

+  INT8    *DBFileName,

+  BOOLEAN Verbose

+  )

+;

+

+STATUS

+StringDBDumpDatabase (

+  INT8                *DBFileName,

+  INT8                *OutputFileName,

+  BOOLEAN             Verbose

+  )

+;

+

+STATUS

+StringDBAddLanguage (

+  WCHAR *LanguageName,

+  WCHAR *PrintableLanguageName

+  )

+;

+

+STATUS

+StringDBDumpCStrings (

+  INT8                        *FileName,

+  INT8                        *BaseName,

+  WCHAR_STRING_LIST           *LanguagesOfInterest,

+  WCHAR_MATCHING_STRING_LIST  *IndirectionList

+  )

+;

+

+STATUS

+StringDBDumpStringDefines (

+  INT8                *FileName,

+  INT8                *BaseName

+  )

+;

+

+STATUS

+StringDBSetCurrentLanguage (

+  WCHAR *LanguageName

+  )

+;

+

+STATUS

+StringDBSetStringReferenced (

+  INT8      *StringIdentifierName,

+  BOOLEAN   IgnoreNotFound

+  )

+;

+

+void

+StringDBFormatString (

+  WCHAR   *String

+  )

+;

+

+#endif // #ifndef _STRING_DB_H_

diff --git a/edk2/Tools/Source/TianoTools/StrGather/build.xml b/edk2/Tools/Source/TianoTools/StrGather/build.xml
new file mode 100644
index 0000000..96658e8
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/StrGather/build.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK StrGather Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="StrGather"/>

+  <property name="FileSet" value="*.c *.h"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <compilerarg value="-fshort-wchar" if="gcc"/>

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress String"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/String/PrintLib.c b/edk2/Tools/Source/TianoTools/String/PrintLib.c
new file mode 100644
index 0000000..868a73e
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/String/PrintLib.c
@@ -0,0 +1,667 @@
+/** @file

+  Print Library.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PrintLib.c

+

+**/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <PrintLib.h>

+#include <CommonLib.h>

+#include "PrintLibInternal.h"

+

+typedef struct {

+  RETURN_STATUS  Status;

+  CHAR8          *String;

+} STATUS_LOOKUP_TABLE_ENTRY;

+

+static CONST STATUS_LOOKUP_TABLE_ENTRY  StatusString[] = {

+  { RETURN_SUCCESS,               "Success" },

+  { RETURN_LOAD_ERROR,            "Load Error" },

+  { RETURN_INVALID_PARAMETER,     "Invalid Parameter" },

+  { RETURN_UNSUPPORTED,           "Unsupported" },

+  { RETURN_BAD_BUFFER_SIZE,       "Bad Buffer Size" },

+  { RETURN_BUFFER_TOO_SMALL,      "Buffer Too Small" },

+  { RETURN_NOT_READY,             "Not Ready" },

+  { RETURN_DEVICE_ERROR,          "Device Error" },

+  { RETURN_WRITE_PROTECTED,       "Write Protected" },

+  { RETURN_OUT_OF_RESOURCES,      "Out of Resources" },

+  { RETURN_VOLUME_CORRUPTED,      "Volume Corrupt" },

+  { RETURN_VOLUME_FULL,           "Volume Full" },

+  { RETURN_NO_MEDIA,              "No Media" },

+  { RETURN_MEDIA_CHANGED,         "Media changed" },

+  { RETURN_NOT_FOUND,             "Not Found" },

+  { RETURN_ACCESS_DENIED,         "Access Denied" },

+  { RETURN_NO_RESPONSE,           "No Response" },

+  { RETURN_NO_MAPPING,            "No mapping" },

+  { RETURN_TIMEOUT,               "Time out" },

+  { RETURN_NOT_STARTED,           "Not started" },

+  { RETURN_ALREADY_STARTED,       "Already started" },

+  { RETURN_ABORTED,               "Aborted" },

+  { RETURN_ICMP_ERROR,            "ICMP Error" },

+  { RETURN_TFTP_ERROR,            "TFTP Error" },

+  { RETURN_PROTOCOL_ERROR,        "Protocol Error" },

+  { RETURN_WARN_UNKNOWN_GLYPH,    "Warning Unknown Glyph" },

+  { RETURN_WARN_DELETE_FAILURE,   "Warning Delete Failure" },

+  { RETURN_WARN_WRITE_FAILURE,    "Warning Write Failure" },

+  { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" },

+  { 0,                              NULL                     }

+};

+

+

+/**

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+  @param  StartOfBuffer Unicode buffer to print the results of the parsing of Format into.

+  

+  @param  BufferSize Maximum number of characters to put into buffer. Zero means

+  no limit.

+  

+  @param  Flags Intial flags value.  Can only have FORMAT_UNICODE and OUTPUT_UNICODE set

+  

+  @param  FormatString Unicode format string see file header for more details.

+  

+  @param  Marker Vararg list consumed by processing Format.

+

+  @return Number of characters printed.

+

+**/

+UINTN

+BasePrintLibVSPrint (

+  OUT CHAR8        *Buffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *Format,

+  IN  VA_LIST      Marker

+  )

+{

+  CHAR8           *OriginalBuffer;

+  CHAR8           ValueBuffer[MAXIMUM_VALUE_CHARACTERS];

+  UINTN           BytesPerOutputCharacter;

+  UINTN           BytesPerFormatCharacter;

+  UINTN           FormatMask;

+  UINTN           FormatCharacter;

+  UINTN           Width;

+  UINTN           Precision;

+  INT64           Value;

+  CHAR8           *ArgumentString;

+  UINTN           Character;

+  GUID            *TmpGuid;

+  TIME            *TmpTime;

+  UINTN           Count;

+  UINTN           ArgumentMask;

+  INTN            BytesPerArgumentCharacter;

+  UINTN           ArgumentCharacter;

+  BOOLEAN         Done;

+  UINTN           Index;

+  CHAR8           Prefix;

+  BOOLEAN         ZeroPad;

+  BOOLEAN         Comma;

+  UINTN           Digits;

+  UINTN           Radix;

+  RETURN_STATUS   Status;

+

+  OriginalBuffer = Buffer;

+

+  if ((Flags & OUTPUT_UNICODE) != 0) {

+    BytesPerOutputCharacter = 2;

+  } else {

+    BytesPerOutputCharacter = 1;

+  }

+  if ((Flags & FORMAT_UNICODE) != 0) {

+    BytesPerFormatCharacter = 2;

+    FormatMask = 0xffff;

+  } else {

+    BytesPerFormatCharacter = 1;

+    FormatMask = 0xff;

+  }

+

+  //

+  // Reserve space for the Null terminator.

+  // If BufferSize is 0, this will set BufferSize to the max unsigned value

+  //

+  BufferSize--;

+

+  //

+  // Get the first character from the format string

+  //

+  FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+

+  //

+  // Loop until the end of the format string is reached or the output buffer is full

+  //

+  while (FormatCharacter != 0 && BufferSize > 0) {

+    //

+    // Clear all the flag bits except those that may have been passed in

+    //

+    Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE);

+

+    //

+    // Set the default width to zero, and the default precision to 1

+    //

+    Width     = 0;

+    Precision = 1;

+    Prefix    = 0;

+    Comma     = FALSE;

+    ZeroPad   = FALSE;

+    Count     = 0;

+    Digits    = 0;

+

+    switch (FormatCharacter) {

+    case '%':

+      //

+      // Parse Flags and Width

+      //

+      for (Done = FALSE; !Done; ) {

+        Format += BytesPerFormatCharacter;

+        FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+        switch (FormatCharacter) {

+        case '.': 

+          Flags |= PRECISION; 

+          break;

+        case '-': 

+          Flags |= LEFT_JUSTIFY; 

+          break;

+        case '+': 

+          Flags |= PREFIX_SIGN;  

+          break;

+        case ' ': 

+          Flags |= PREFIX_BLANK; 

+          break;

+        case ',': 

+          Flags |= COMMA_TYPE; 

+          break;

+        case 'L':

+        case 'l': 

+          Flags |= LONG_TYPE;    

+          break;

+        case '*':

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PAD_TO_WIDTH;

+            Width = VA_ARG (Marker, UINTN);

+          } else {

+            Precision = VA_ARG (Marker, UINTN);

+          }

+          break;

+        case '0':

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PREFIX_ZERO;

+          }

+        case '1':

+        case '2':

+        case '3':

+        case '4':

+        case '5':

+        case '6':

+        case '7':

+        case '8':

+        case '9':

+          for (Count = 0; ((FormatCharacter >= '0') &&  (FormatCharacter <= '9')); ){

+            Count = (Count * 10) + FormatCharacter - '0';

+            Format += BytesPerFormatCharacter;

+            FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+          }

+          Format -= BytesPerFormatCharacter;

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PAD_TO_WIDTH;

+            Width = Count;

+          } else {

+            Precision = Count;

+          }

+          break;

+        default:

+          Done = TRUE;

+          break;

+        }

+      } 

+

+      //

+      // Limit the maximum field width to the remaining characters in the output buffer

+      //

+      if (Width > BufferSize) {

+        Width = BufferSize;

+      }

+

+      //

+      // Handle each argument type

+      //

+      switch (FormatCharacter) {

+      case 'X':

+        Flags |= PREFIX_ZERO;

+        //

+        // break skiped on purpose

+        //

+      case 'x':

+        Flags |= RADIX_HEX;

+        //

+        // break skiped on purpose

+        //

+      case 'd':

+        if ((Flags & LONG_TYPE) == 0) {

+          Value = (VA_ARG (Marker, INTN));

+        } else {

+          Value = VA_ARG (Marker, INT64);

+        }

+        if ((Flags & PREFIX_BLANK) != 0) {

+          Prefix = ' ';

+        }

+        if ((Flags & PREFIX_SIGN) != 0) {

+          Prefix = '+';

+        }

+        if ((Flags & COMMA_TYPE) != 0) {

+          Comma = TRUE;

+        }

+        if ((Flags & RADIX_HEX) == 0) {

+          Radix = 10;

+          if (Comma) {

+            Flags &= (~PREFIX_ZERO);

+            Precision = 1;

+          }

+          if (Value < 0) {

+            Flags |= PREFIX_SIGN;

+            Prefix = '-';

+            Value = -Value;

+          }

+        } else {

+          Radix = 16;

+          Comma = FALSE;

+          if ((Flags & LONG_TYPE) == 0 && Value < 0) {

+            Value = (UINTN)Value;

+          }

+        }

+        //

+        // Convert Value to a reversed string

+        //

+        Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);

+        if (Value == 0 && Precision == 0) {

+          Count = 0;

+        }

+        ArgumentString = (CHAR8 *)ValueBuffer + Count;

+        Digits = 3 - (Count % 3);

+        if (Comma && Count != 0) {

+          Count += ((Count - 1) / 3);

+        }

+        if (Prefix != 0) {

+          Count++;

+        }

+        Flags |= ARGUMENT_REVERSED;

+        ZeroPad = TRUE;

+        if ((Flags & PREFIX_ZERO) != 0) {

+          if ((Flags & PAD_TO_WIDTH) != 0) {

+            if ((Flags & PRECISION) == 0) {

+              Precision = Width;

+            }

+          }

+        }

+        break;

+

+      case 's':

+      case 'S':

+        Flags |= ARGUMENT_UNICODE;

+        //

+        // break skipped on purpose

+        //

+      case 'a':

+        ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);

+        if (ArgumentString == NULL) {

+          Flags &= (~ARGUMENT_UNICODE);

+          ArgumentString = "<null string>";

+        }

+        break;

+

+      case 'c':

+        Character = VA_ARG (Marker, UINTN) & 0xffff;

+        ArgumentString = (CHAR8 *)&Character;

+        Flags |= ARGUMENT_UNICODE;

+        break;

+

+      case 'g':

+        TmpGuid = VA_ARG (Marker, GUID *);

+        if (TmpGuid == NULL) {

+          ArgumentString = "<null guid>";

+        } else {

+          BasePrintLibSPrint (

+            ValueBuffer,

+            0, 

+            0,

+            "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",

+            TmpGuid->Data1,

+            TmpGuid->Data2,

+            TmpGuid->Data3,

+            TmpGuid->Data4[0],

+            TmpGuid->Data4[1],

+            TmpGuid->Data4[2],

+            TmpGuid->Data4[3],

+            TmpGuid->Data4[4],

+            TmpGuid->Data4[5],

+            TmpGuid->Data4[6],

+            TmpGuid->Data4[7]

+            );

+          ArgumentString = ValueBuffer;

+        }

+        break;

+

+      case 't':

+        TmpTime = VA_ARG (Marker, TIME *); 

+        if (TmpTime == NULL) {

+          ArgumentString = "<null time>";

+        } else {

+          BasePrintLibSPrint (

+            ValueBuffer,

+            0,

+            0,

+            "%02d/%02d/%04d  %02d:%02d",

+            TmpTime->Month,

+            TmpTime->Day,

+            TmpTime->Year,

+            TmpTime->Hour,

+            TmpTime->Minute

+            );

+          ArgumentString = ValueBuffer;

+        }

+        break;

+

+      case 'r':

+        Status = VA_ARG (Marker, RETURN_STATUS);

+        ArgumentString = ValueBuffer;

+        for (Index = 0; StatusString[Index].String != NULL; Index++) {

+          if (Status == StatusString[Index].Status) {

+            ArgumentString = StatusString[Index].String;

+          }

+        }

+        if (ArgumentString == ValueBuffer) {

+          BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status);

+        }

+        break;

+

+      case '%':

+      default:

+        //

+        // if the type is '%' or unknown, then print it to the screen

+        //

+        ArgumentString = (CHAR8 *)&FormatCharacter;

+        Flags |= ARGUMENT_UNICODE;

+        break;

+      }

+      break;

+    case '\n':

+      ArgumentString = "\r\n";

+      break;

+    default:

+      ArgumentString = (CHAR8 *)&FormatCharacter;

+      Flags |= ARGUMENT_UNICODE;

+      break;

+    }

+

+    //

+    // Retrieve the ArgumentString attriubutes

+    //

+    if ((Flags & ARGUMENT_UNICODE) != 0) {

+      ArgumentMask = 0xffff;

+      BytesPerArgumentCharacter = 2;

+    } else {

+      ArgumentMask = 0xff;

+      BytesPerArgumentCharacter = 1;

+    }

+    if ((Flags & ARGUMENT_REVERSED) != 0) {

+      BytesPerArgumentCharacter = -BytesPerArgumentCharacter;

+    } else {

+      //

+      // Compute the number of characters in ArgumentString and store it in Count

+      // ArgumentString is either null-terminated, or it contains Precision characters

+      //

+      for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {

+        ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;

+        if (ArgumentCharacter == 0) {

+          break;

+        }

+      }

+    }

+

+    //

+    // Limit the length of the string to append to the remaining characters in the output buffer

+    //

+    if (Count > BufferSize) {

+      Count = BufferSize;

+    }

+    if (Precision < Count) {

+      Precision = Count;

+    }

+

+    //

+    // Pad before the string

+    //

+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {

+      Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);

+    }

+

+    if (ZeroPad) {

+      if (Prefix != 0) {

+        Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);

+      }

+      Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter);

+    } else {

+      Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter);

+      if (Prefix != 0) {

+        Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);

+      }

+    }

+

+    //

+    // Output the Prefix character if it is present

+    //

+    Index = 0;

+    if (Prefix) {

+      Index++;

+    }

+

+    //

+    // Copy the string into the output buffer performing the required type conversions

+    //

+    while (Index < Count) {

+      ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;

+

+      Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter);

+      ArgumentString    += BytesPerArgumentCharacter;

+      Index++;

+      if (Comma) {

+        Digits++;

+        if (Digits == 3) {

+          Digits = 0;

+          Index++;

+          if (Index < Count) {

+            Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter);

+          }

+        }

+      }

+    }

+

+    //

+    // Pad after the string

+    //

+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {

+      Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);

+    }

+

+    //

+    // Reduce the number of characters

+    //

+    BufferSize -= Count;

+

+    //

+    // Get the next character from the format string

+    //

+    Format += BytesPerFormatCharacter;

+

+    //

+    // Get the next character from the format string

+    //

+    FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;

+  }

+

+  //

+  // Null terminate the Unicode or ASCII string

+  //

+  Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter);

+   

+  return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);

+}

+

+UINTN

+BasePrintLibSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST  Marker;

+

+  VA_START (Marker, FormatString);

+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+UnicodeVSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+UnicodeSPrint (

+  OUT CHAR16        *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+UnicodeVSPrintAsciiFormat (

+  OUT CHAR16       *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  IN  VA_LIST      Marker

+  )

+{

+  return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+UnicodeSPrintAsciiFormat (

+  OUT CHAR16       *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+AsciiVSPrint (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR8   *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+AsciiSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+AsciiVSPrintUnicodeFormat (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+AsciiSPrintUnicodeFormat (

+  OUT CHAR8         *StartOfBuffer,

+  IN  UINTN         BufferSize,

+  IN  CONST CHAR16  *FormatString,

+  ...

+  )

+{

+  VA_LIST Marker;

+

+  VA_START (Marker, FormatString);

+  return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);

+}

+

+UINTN

+EFIAPI

+UnicodeValueToString (

+  IN OUT CHAR16  *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width

+  )

+{

+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2);

+}

+

+UINTN

+EFIAPI

+AsciiValueToString (

+  IN OUT CHAR8  *Buffer,

+  IN UINTN      Flags,

+  IN INT64      Value,

+  IN UINTN      Width

+  )

+{

+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 1);

+}

diff --git a/edk2/Tools/Source/TianoTools/String/PrintLibInternal.c b/edk2/Tools/Source/TianoTools/String/PrintLibInternal.c
new file mode 100644
index 0000000..a475815
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/String/PrintLibInternal.c
@@ -0,0 +1,137 @@
+/** @file

+  Print Library worker functions.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  PrintLibInternal.c

+

+**/

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <PrintLib.h>

+#include <BaseLib.h>

+#include <CommonLib.h>

+#include "PrintLibInternal.h"

+

+static CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

+

+CHAR8 *

+BasePrintLibFillBuffer (

+  CHAR8   *Buffer,

+  INTN    Length,

+  UINTN   Character,

+  INTN    Increment

+  )

+{

+  INTN  Index;

+

+  for (Index = 0; Index < Length; Index++) {

+    *Buffer       =  (CHAR8) Character;

+    *(Buffer + 1) =  (CHAR8) (Character >> 8);

+    Buffer        += Increment;

+  }

+  return Buffer;

+}

+

+/**

+  Print worker function that prints a Value as a decimal number in Buffer.

+

+  @param  Buffer Location to place the Unicode or ASCII string of Value.

+  

+  @param  Value Value to convert to a Decimal or Hexidecimal string in Buffer.

+  

+  @param  Flags Flags to use in printing string, see file header for details.

+  

+  @param  Precision Minimum number of digits to return in the ASCII string

+

+  @return Number of characters printed.

+

+**/

+UINTN

+EFIAPI

+BasePrintLibValueToString (

+  IN OUT CHAR8  *Buffer,

+  IN INT64      Value,

+  IN UINTN      Radix

+  )

+{

+  UINTN   Digits;

+  UINT32  Remainder;

+

+  //

+  // Loop to convert one digit at a time in reverse order

+  //

+  *(Buffer++) = 0;

+  Digits = 0;

+  do {

+    // Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);

+    Remainder = (UINT64)Value % (UINT32)Radix;

+    Value = (UINT64)Value / (UINT32)Radix;

+    *(Buffer++) = mHexStr[Remainder];

+    Digits++;

+  } while (Value != 0);

+  return Digits;

+}

+

+UINTN

+BasePrintLibConvertValueToString (

+  IN OUT CHAR8   *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width,

+  IN UINTN       Increment

+  )

+{

+  CHAR8  *OriginalBuffer;

+  CHAR8  ValueBuffer[MAXIMUM_VALUE_CHARACTERS];

+  UINTN  Count;

+  UINTN  Digits;

+  UINTN  Index;

+

+  OriginalBuffer = Buffer;

+

+  if (Width == 0 || (Flags & COMMA_TYPE) != 0) {

+    Flags &= (~PREFIX_ZERO);

+  }

+

+  if (Width == 0 || Width > (MAXIMUM_VALUE_CHARACTERS - 1)) {

+    Width = MAXIMUM_VALUE_CHARACTERS - 1;

+  }

+

+  if (Value < 0) {

+    Value = -Value;

+    Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment);

+  }

+

+  Count = BasePrintLibValueToString (ValueBuffer, Value, 10);

+

+  if ((Flags & PREFIX_ZERO) != 0) {

+    Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment);

+  }

+

+  Digits = 3 - (Count % 3);

+  for (Index = 0; Index < Count; Index++) {

+    Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment);

+    if ((Flags & COMMA_TYPE) != 0) {

+      Digits++;

+      if (Digits == 3) {

+        Digits = 0;

+        if ((Index + 1) < Count) {

+          Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', Increment);

+        }

+      }

+    }

+  }

+

+  Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, Increment);

+

+  return ((Buffer - OriginalBuffer) / Increment);

+}

diff --git a/edk2/Tools/Source/TianoTools/String/PrintLibInternal.h b/edk2/Tools/Source/TianoTools/String/PrintLibInternal.h
new file mode 100644
index 0000000..c7fecfd
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/String/PrintLibInternal.h
@@ -0,0 +1,95 @@
+/** @file

+  Print Library.

+

+  Copyright (c) 2006, Intel Corporation

+  All rights reserved. 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.

+

+  Module Name:  PrintLibInternal.h

+

+**/

+

+

+

+//

+// Print primitives

+//

+//#define LEFT_JUSTIFY      0x01

+#define PREFIX_SIGN       0x02

+#define PREFIX_BLANK      0x04

+//#define COMMA_TYPE        0x08

+#define LONG_TYPE         0x10

+//#define PREFIX_ZERO       0x20

+#define OUTPUT_UNICODE    0x40

+#define RADIX_HEX         0x80

+#define FORMAT_UNICODE    0x100

+#define PAD_TO_WIDTH      0x200

+#define ARGUMENT_UNICODE  0x400

+#define PRECISION         0x800

+#define ARGUMENT_REVERSED 0x1000

+

+///

+/// Define the maximum number of characters that are required to encode

+/// a decimal, hexidecimal, GUID, or TIME value with a Nll terminator.

+///   Maximum Length Decimal String     = 28    "-9,223,372,036,854,775,808"

+///   Maximum Length Hexidecimal String = 17    "FFFFFFFFFFFFFFFF"

+///   Maximum Length GUID               = 37    "00000000-0000-0000-0000-000000000000"

+///   Maximum Length TIME               = 18    "12/12/2006  12:12"

+///

+#define MAXIMUM_VALUE_CHARACTERS  38

+

+//

+//

+//

+typedef struct {

+  UINT16  Year;

+  UINT8   Month;

+  UINT8   Day;

+  UINT8   Hour;

+  UINT8   Minute;

+  UINT8   Second;

+  UINT8   Pad1;

+  UINT32  Nanosecond;

+  INT16   TimeZone;

+  UINT8   Daylight;

+  UINT8   Pad2;

+} TIME;

+

+UINTN

+BasePrintLibSPrint (

+  OUT CHAR8        *Buffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  );

+

+CHAR8 *

+BasePrintLibFillBuffer (

+  CHAR8   *Buffer,

+  INTN    Length,

+  UINTN   Character,

+  INTN    Increment

+  );

+

+UINTN

+EFIAPI

+BasePrintLibValueToString (

+  IN OUT CHAR8  *Buffer, 

+  IN INT64      Value, 

+  IN UINTN      Radix

+  );

+

+UINTN

+BasePrintLibConvertValueToString (

+  IN OUT CHAR8   *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width,

+  IN UINTN       Increment

+  );

diff --git a/edk2/Tools/Source/TianoTools/String/String.c b/edk2/Tools/Source/TianoTools/String/String.c
new file mode 100644
index 0000000..1005180
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/String/String.c
@@ -0,0 +1,809 @@
+/** @file

+  Unicode string primatives.

+

+  Copyright (c) 2006, Intel Corporation<BR>

+  All rights reserved. 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.

+

+  Module Name:  String.c

+

+**/

+

+#include <assert.h>

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <BaseLib.h>

+#include <PcdLib.h>

+#include <CommonLib.h>

+#define _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength   0

+#define _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength   0

+

+/**

+  Copies one Null-terminated Unicode string to another Null-terminated Unicode

+  string and returns the new Unicode string.

+

+  This function copies the contents of the Unicode string Source to the Unicode

+  string Destination, and returns Destination. If Source and Destination

+  overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+

+  @return Destiantion

+

+**/

+CHAR16 *

+EFIAPI

+StrCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) > StrLen (Source));

+

+  ReturnValue = Destination;

+  while (*Source) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+  return ReturnValue;

+}

+

+/**

+  Copies one Null-terminated Unicode string with a maximum length to another

+  Null-terminated Unicode string with a maximum length and returns the new

+  Unicode string.

+

+  This function copies the contents of the Unicode string Source to the Unicode

+  string Destination, and returns Destination. At most, Length Unicode

+  characters are copied from Source to Destination. If Length is 0, then

+  Destination is returned unmodified. If Length is greater that the number of

+  Unicode characters in Source, then Destination is padded with Null Unicode

+  characters. If Source and Destination overlap, then the results are

+  undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+  @param  Length      Maximum number of Unicode characters to copy.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrnCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source,

+  IN      UINTN                     Length

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  if (Length == 0) {

+    return Destination;

+  }

+

+  //

+  // Destination cannot be NULL if Length is not zero

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  // Q: Does Source have to be NULL-terminated?

+  //

+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) >= Length);

+

+  ReturnValue = Destination;

+

+  while ((*Source != L'\0') && (Length > 0)) {

+    *(Destination++) = *(Source++);

+    Length--;

+  }

+

+  // ZeroMem (Destination, Length * sizeof (*Destination));

+  memset (Destination, 0, Length * sizeof (*Destination));

+  return ReturnValue;

+}

+

+/**

+  Returns the length of a Null-terminated Unicode string.

+

+  This function returns the number of Unicode characters in the Null-terminated

+  Unicode string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated Unicode string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+StrLen (

+  IN      CONST CHAR16              *String

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (String != NULL);

+

+  for (Length = 0; *String != L'\0'; String++, Length++) {

+    //

+    // If PcdMaximumUnicodeStringLength is not zero,

+    // length should not more than PcdMaximumUnicodeStringLength

+    //

+    if (FixedPcdGet32 (PcdMaximumUnicodeStringLength) != 0) {

+      ASSERT (Length < FixedPcdGet32 (PcdMaximumUnicodeStringLength));

+    }

+  }

+  return Length;

+}

+

+/**

+  Returns the size of a Null-terminated Unicode string in bytes, including the

+  Null terminator.

+

+  This function returns the size, in bytes, of the Null-terminated Unicode

+  string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated Unicode string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+StrSize (

+  IN      CONST CHAR16              *String

+  )

+{

+  return (StrLen (String) + 1) * sizeof (*String);

+}

+

+/**

+  Compares two Null-terminated Unicode strings, and returns the difference

+  between the first mismatched Unicode characters.

+

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. If FirstString is identical to

+  SecondString, then 0 is returned. Otherwise, the value returned is the first

+  mismatched Unicode character in SecondString subtracted from the first

+  mismatched Unicode character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated Unicode string.

+  @param  SecondString  Pointer to a Null-terminated Unicode string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+StrCmp (

+  IN      CONST CHAR16              *FirstString,

+  IN      CONST CHAR16              *SecondString

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength

+  //

+  ASSERT (StrSize (FirstString) != 0);

+  ASSERT (StrSize (SecondString) != 0);

+

+  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {

+    FirstString++;

+    SecondString++;

+  }

+  return *FirstString - *SecondString;

+}

+

+/**

+  Compares two Null-terminated Unicode strings with maximum lengths, and

+  returns the difference between the first mismatched Unicode characters.

+

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. At most, Length Unicode

+  characters will be compared. If Length is 0, then 0 is returned. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched Unicode character in SecondString

+  subtracted from the first mismatched Unicode character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated Unicode string.

+  @param  SecondString  Pointer to a Null-terminated Unicode string.

+  @param  Length        Maximum number of Unicode characters to compare.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+StrnCmp (

+  IN      CONST CHAR16              *FirstString,

+  IN      CONST CHAR16              *SecondString,

+  IN      UINTN                     Length

+  )

+{

+  if (Length == 0) {

+    return 0;

+  }

+

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (FirstString) != 0);

+  ASSERT (StrSize (SecondString) != 0);

+

+  while ((*FirstString != L'\0') &&

+         (*FirstString == *SecondString) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+

+  return *FirstString - *SecondString;

+}

+

+/**

+  Concatenates one Null-terminated Unicode string to another Null-terminated

+  Unicode string, and returns the concatenated Unicode string.

+

+  This function concatenates two Null-terminated Unicode strings. The contents

+  of Null-terminated Unicode string Source are concatenated to the end of

+  Null-terminated Unicode string Destination. The Null-terminated concatenated

+  Unicode String is returned. If Source and Destination overlap, then the

+  results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination

+  and Source results in a Unicode string with more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  )

+{

+  StrCpy (Destination + StrLen (Destination), Source);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (StrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  Concatenates one Null-terminated Unicode string with a maximum length to the

+  end of another Null-terminated Unicode string, and returns the concatenated

+  Unicode string.

+

+  This function concatenates two Null-terminated Unicode strings. The contents

+  of Null-terminated Unicode string Source are concatenated to the end of

+  Null-terminated Unicode string Destination, and Destination is returned. At

+  most, Length Unicode characters are concatenated from Source to the end of

+  Destination, and Destination is always Null-terminated. If Length is 0, then

+  Destination is returned unmodified. If Source and Destination overlap, then

+  the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more

+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination

+  and Source results in a Unicode string with more than

+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated Unicode string.

+  @param  Source      Pointer to a Null-terminated Unicode string.

+  @param  Length      Maximum number of Unicode characters to concatenate from

+                      Source.

+

+  @return Destination

+

+**/

+CHAR16 *

+EFIAPI

+StrnCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source,

+  IN      UINTN                     Length

+  )

+{

+  StrnCpy (Destination + StrLen (Destination), Source, Length);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (StrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  Copies one Null-terminated ASCII string to another Null-terminated ASCII

+  string and returns the new ASCII string.

+

+  This function copies the contents of the ASCII string Source to the ASCII

+  string Destination, and returns Destination. If Source and Destination

+  overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source

+  )

+{

+  CHAR8                             *ReturnValue;

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));

+

+  ReturnValue = Destination;

+  while (*Source) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+  return ReturnValue;

+}

+

+/**

+  Copies one Null-terminated ASCII string with a maximum length to another

+  Null-terminated ASCII string with a maximum length and returns the new ASCII

+  string.

+

+  This function copies the contents of the ASCII string Source to the ASCII

+  string Destination, and returns Destination. At most, Length ASCII characters

+  are copied from Source to Destination. If Length is 0, then Destination is

+  returned unmodified. If Length is greater that the number of ASCII characters

+  in Source, then Destination is padded with Null ASCII characters. If Source

+  and Destination overlap, then the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+  @param  Length      Maximum number of ASCII characters to copy.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrnCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source,

+  IN      UINTN                     Length

+  )

+{

+  CHAR8                             *ReturnValue;

+

+  if (Length == 0) {

+    return Destination;

+  }

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) >= Length);

+

+  ReturnValue = Destination;

+

+  while (*Source && Length > 0) {

+    *(Destination++) = *(Source++);

+    Length--;

+  }

+

+  // ZeroMem (Destination, Length * sizeof (*Destination));

+  memset (Destination, 0, Length * sizeof (*Destination));

+  return ReturnValue;

+}

+

+/**

+  Returns the length of a Null-terminated ASCII string.

+

+  This function returns the number of ASCII characters in the Null-terminated

+  ASCII string specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and String contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated ASCII string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrLen (

+  IN      CONST CHAR8               *String

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (String != NULL);

+

+  for (Length = 0; *String != '\0'; String++, Length++) {

+    //

+    // If PcdMaximumUnicodeStringLength is not zero,

+    // length should not more than PcdMaximumUnicodeStringLength

+    //

+    if (FixedPcdGet32 (PcdMaximumAsciiStringLength) != 0) {

+      ASSERT (Length < FixedPcdGet32 (PcdMaximumAsciiStringLength));

+    }

+  }

+  return Length;

+}

+

+/**

+  Returns the size of a Null-terminated ASCII string in bytes, including the

+  Null terminator.

+

+  This function returns the size, in bytes, of the Null-terminated ASCII string

+  specified by String.

+

+  If String is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and String contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  String  Pointer to a Null-terminated ASCII string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrSize (

+  IN      CONST CHAR8               *String

+  )

+{

+  return (AsciiStrLen (String) + 1) * sizeof (*String);

+}

+

+/**

+  Compares two Null-terminated ASCII strings, and returns the difference

+  between the first mismatched ASCII characters.

+

+  This function compares the Null-terminated ASCII string FirstString to the

+  Null-terminated ASCII string SecondString. If FirstString is identical to

+  SecondString, then 0 is returned. Otherwise, the value returned is the first

+  mismatched ASCII character in SecondString subtracted from the first

+  mismatched ASCII character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+AsciiStrCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') && (*FirstString == *SecondString)) {

+    FirstString++;

+    SecondString++;

+  }

+

+  return *FirstString - *SecondString;

+}

+

+STATIC

+CHAR8

+EFIAPI

+AsciiToUpper (

+  IN      CHAR8                     Chr

+  )

+{

+  return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr;

+}

+

+/**

+  Performs a case insensitive comparison of two Null-terminated ASCII strings,

+  and returns the difference between the first mismatched ASCII characters.

+

+  This function performs a case insensitive comparison of the Null-terminated

+  ASCII string FirstString to the Null-terminated ASCII string SecondString. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched lower case ASCII character in

+  SecondString subtracted from the first mismatched lower case ASCII character

+  in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString using case insensitive

+              comparisons.

+  @retval !=0 FirstString is not identical to SecondString using case

+              insensitive comparisons.

+

+**/

+INTN

+EFIAPI

+AsciiStriCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') &&

+         (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) {

+    FirstString++;

+    SecondString++;

+  }

+

+  return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);

+}

+

+/**

+  Compares two Null-terminated ASCII strings with maximum lengths, and returns

+  the difference between the first mismatched ASCII characters.

+

+  This function compares the Null-terminated ASCII string FirstString to the

+  Null-terminated ASCII  string SecondString. At most, Length ASCII characters

+  will be compared. If Length is 0, then 0 is returned. If FirstString is

+  identical to SecondString, then 0 is returned. Otherwise, the value returned

+  is the first mismatched ASCII character in SecondString subtracted from the

+  first mismatched ASCII character in FirstString.

+

+  If FirstString is NULL, then ASSERT().

+  If SecondString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+

+  @retval 0   FirstString is identical to SecondString.

+  @retval !=0 FirstString is not identical to SecondString.

+

+**/

+INTN

+EFIAPI

+AsciiStrnCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') &&

+         (*FirstString == *SecondString) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+  return *FirstString - *SecondString;

+}

+

+/**

+  Concatenates one Null-terminated ASCII string to another Null-terminated

+  ASCII string, and returns the concatenated ASCII string.

+

+  This function concatenates two Null-terminated ASCII strings. The contents of

+  Null-terminated ASCII string Source are concatenated to the end of Null-

+  terminated ASCII string Destination. The Null-terminated concatenated ASCII

+  String is returned.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Destination contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero and concatenating Destination and

+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength

+  ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCat (

+  IN OUT CHAR8    *Destination,

+  IN CONST CHAR8  *Source

+  )

+{

+  AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (AsciiStrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  Concatenates one Null-terminated ASCII string with a maximum length to the

+  end of another Null-terminated ASCII string, and returns the concatenated

+  ASCII string.

+

+  This function concatenates two Null-terminated ASCII strings. The contents

+  of Null-terminated ASCII string Source are concatenated to the end of Null-

+  terminated ASCII string Destination, and Destination is returned. At most,

+  Length ASCII characters are concatenated from Source to the end of

+  Destination, and Destination is always Null-terminated. If Length is 0, then

+  Destination is returned unmodified. If Source and Destination overlap, then

+  the results are undefined.

+

+  If Destination is NULL, then ASSERT().

+  If Source is NULL, then ASSERT().

+  If Source and Destination overlap, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Destination contains more

+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than

+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and

+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength

+  ASCII characters, then ASSERT().

+

+  @param  Destination Pointer to a Null-terminated ASCII string.

+  @param  Source      Pointer to a Null-terminated ASCII string.

+  @param  Length      Maximum number of ASCII characters to concatenate from

+                      Source.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrnCat (

+  IN OUT  CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source,

+  IN      UINTN                     Length

+  )

+{

+  AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (AsciiStrSize (Destination) != 0);

+  return Destination;

+}

diff --git a/edk2/Tools/Source/TianoTools/String/build.xml b/edk2/Tools/Source/TianoTools/String/build.xml
new file mode 100644
index 0000000..34f44eb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/String/build.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK String

+  Copyright (c) 2006, Intel Corporation

+-->

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property name="LibName" value="String"/>

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${LibName}/tmp"/>

+

+  <target name="GenTool" depends="init, String">

+    <echo message="Building the EDK Tool: ${LibName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Library: ${LibName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+        <property name="ToolChain" value="gcc"/>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+

+    <condition property="syslibdirs" value="">

+      <os family="mac"/>

+    </condition>

+    

+    <condition property="syslibs" value="">

+      <os family="mac"/>

+    </condition>

+    

+    <condition property="syslibdirs" value="${env.CYGWIN_HOME}/lib/e2fsprogs">

+      <os family="windows"/>

+    </condition>

+    

+    <condition property="syslibs" value="uuid">

+      <os family="windows"/>

+    </condition>

+    

+    <condition property="syslibdirs" value="/usr/lib">

+      <os name="Linux"/>

+    </condition>

+    

+    <condition property="syslibs" value="uuid">

+      <os name="Linux"/>

+    </condition>

+    

+  </target>

+

+  <target name="String" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${LIB_DIR}/${LibName}"

+        outtype="static"

+        optimize="speed">

+

+      <compilerarg value="-fshort-wchar" if="gcc"/>

+

+      <fileset dir="${basedir}/${LibName}" 

+        includes="*.c" />

+

+      <includepath path="${PACKAGE_DIR}/${LibName}"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+    </cc>

+  </target>

+

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${LibName}${ext_exe}"/>  

+    <delete dir="${PACKAGE_DIR}/${LibName}/tmp">

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/Strip/Makefile b/edk2/Tools/Source/TianoTools/Strip/Makefile
new file mode 100644
index 0000000..f47a68f
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Strip/Makefile
@@ -0,0 +1,70 @@
+#/*++

+#   

+#  Copyright (c) 2001 Intel Corporation.  All rights reserved.

+#

+#  This software and associated documentation (if any) is furnished under 

+#  a license and may only be used or copied in accordance with the terms 

+#  of the license.  Except as permitted by such license, no part of this 

+#  software or documentation may be reproduced, stored in a retrieval 

+#  system, or transmitted in any form or by any means without the express 

+#  written consent of Intel Corporation.

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Define some macros we use here. Should get rid of them someday and 

+# get rid of the extra level of indirection.

+#

+COMMON_SOURCE      = $(EDK_TOOLS_COMMON)

+

+#

+# Common information

+#

+

+INC=$(INC)

+

+#

+# Target specific information

+#

+

+TARGET_NAME=Strip

+TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+

+TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\Strip.c"

+TARGET_EXE_INCLUDE = 

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+#

+# Build EXE

+#

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj

+

+$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

diff --git a/edk2/Tools/Source/TianoTools/Strip/Strip.c b/edk2/Tools/Source/TianoTools/Strip/Strip.c
new file mode 100644
index 0000000..567b526
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Strip/Strip.c
@@ -0,0 +1,104 @@
+/*++

+

+Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+

+  Strip.c

+

+Abstract:

+

+  Quick Exe2Bin equivalent.

+

+--*/

+

+#include <stdio.h>

+#include <memory.h>

+#include <string.h>

+

+int

+main (

+  int  argc,

+  char *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Converts executable files to binary files.

+

+Arguments:

+

+  argc   - Number of command line arguments

+  argv[] - Array of pointers to the command line arguments

+

+Returns:

+

+  Zero     - Function completed successfully.

+  Non-zero - Function exited with errors. 

+

+--*/

+{

+  FILE  *InFile;

+  FILE  *OutFile;

+  int   Index;

+  int   FileSize;

+  char  *Buffer;

+  char  *Ptrx;

+

+  if (argc < 3) {

+    printf ("Need more args, such as file name to convert and output name\n");

+    return -1;

+  }

+

+  InFile  = fopen (argv[1], "rb");

+  OutFile = fopen (argv[2], "wb");

+

+  if (!InFile) {

+    printf ("no file, exit\n");

+    return -1;

+  }

+

+  if (OutFile == NULL) {

+    printf ("Unable to open output file.\n");

+    return -1;

+  }

+

+  fseek (InFile, 0, SEEK_END);

+  FileSize = ftell (InFile);

+

+  if (FileSize < 0x200) {

+    printf ("%d is not a legal size, exit\n", FileSize);

+    return -1;

+  }

+

+  fseek (InFile, 0, SEEK_SET);

+

+  Buffer = malloc (FileSize);

+  if (Buffer == NULL) {

+    printf ("Error: Out of resources.\n");

+    return -1;

+  }

+

+  fread (Buffer, 1, FileSize, InFile);

+

+  Ptrx  = Buffer + 0x200;

+

+  Index = FileSize - 0x200;

+

+  fwrite (Ptrx, Index, 1, OutFile);

+

+  fclose (InFile);

+  fclose (OutFile);

+  free (Buffer);

+

+  return 0;

+}

diff --git a/edk2/Tools/Source/TianoTools/Strip/build.xml b/edk2/Tools/Source/TianoTools/Strip/build.xml
new file mode 100644
index 0000000..d63faeb
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/Strip/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK Strip Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="Strip"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/VfrCompile/EfiVfr.h b/edk2/Tools/Source/TianoTools/VfrCompile/EfiVfr.h
new file mode 100644
index 0000000..f7c534d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/VfrCompile/EfiVfr.h
@@ -0,0 +1,181 @@
+/*++

+

+Copyright (c) 2004 - 2005, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  EfiVfr.h

+

+Abstract:

+

+  Defines and prototypes for the EFI internal forms representation

+  setup protocol and drivers

+  

+--*/

+

+#ifndef _EFI_VFR_H_

+#define _EFI_VFR_H_

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include "InternalFormRepresentation.h"

+#include <string.h>

+

+//

+// This number should be incremented with each change to the VFR compiler.

+// We write the version to the output list file for debug purposes.

+//

+#define VFR_COMPILER_VERSION  "1.88"

+

+//

+// Maximum file path for filenames

+//

+#ifndef MAX_PATH

+#define MAX_PATH        255

+#endif

+#define MAX_QUEUE_COUNT 255

+#define MAX_LINE_LEN    1024

+#define PROGRAM_NAME    "VfrCompile"

+

+//

+// We parse C-style structure definitions which can then be referenced

+// in VFR statements.

+// We need to define an internal structure that can be used to

+// track the fields in a structure definition, and another structure

+// to keep track of the structure name and subfields.

+//

+typedef struct _STRUCT_FIELD_DEFINITION {

+  struct _STRUCT_FIELD_DEFINITION *Next;

+  int                             DataSize;

+  int                             Offset;     // from the start of the structure

+  int                             ArrayLength;

+  char                            IsArray;

+  char                            *Name;

+} STRUCT_FIELD_DEFINITION;

+

+typedef struct _STRUCT_DEFINITION {

+  struct _STRUCT_DEFINITION *Next;

+  int                       Size;

+  int                       LineNum;          // line number where the structure was defined

+  int                       IsNonNV;          // if this is the non-NV data structure definition

+  int                       Referenced;       // if it's referenced anywhere in the VFR

+  int                       VarStoreIdValid;  // found a 'varstore' statement for it in the VFR

+  unsigned short            VarStoreId;       // key from a varstore IFR statement

+  int                       VarStoreLineNum;  // line number where VARSTORE was defined

+  char                      *Name;

+  STRUCT_FIELD_DEFINITION   *Field;

+  STRUCT_FIELD_DEFINITION   *LastField;

+} STRUCT_DEFINITION;

+

+//

+// For the IdEqValList variable list of UINT16's, keep track of them using

+// a linked list until we know how many there are.

+// We also use a linked list of these to keep track of labels used in

+// the VFR script so we can catch duplicates.

+// We'll also use it to keep track of defined varstore id's so we can

+// detect duplicate definitions.

+//

+typedef struct _UINT16_LIST {

+  struct _UINT16_LIST *Next;

+  UINT16              Value;

+  UINT32              LineNum;

+} UINT16_LIST;

+

+typedef struct _GOTO_REFERENCE {

+  struct _GOTO_REFERENCE  *Next;

+  UINT32                  RefLineNum; // line number of source file where referenced

+  UINT16                  Value;

+} GOTO_REFERENCE;

+

+typedef struct _FORM_ID_VALUE {

+  struct _FORM_ID_VALUE *Next;

+  UINT32                LineNum;

+  UINT16                Value;

+} FORM_ID_VALUE;

+

+//

+// We keep track in the parser of all "#line 4 "x.y"" strings so we

+// can cross-reference the line numbers in the preprocessor output .i file

+// to the original input files.

+//

+typedef struct _PARSER_LINE_DEFINITION {

+  struct _PARSER_LINE_DEFINITION  *Next;

+  UINT32                          HashLineNum;  // from the #line stmt

+  UINT32                          TokenLineNum; // line number in the .i file

+  CHAR8                           *FileName;    // from the #line stmt

+} PARSER_LINE_DEFINITION;

+

+extern PARSER_LINE_DEFINITION *gLineDefinition;

+extern PARSER_LINE_DEFINITION *gLastLineDefinition;

+

+extern

+char                          *

+ConvertLineNumber (

+  UINT32 *LineNum

+  )

+/*++

+

+Routine Description:

+  Given the line number in the preprocessor-output file, use the line number

+  information we've saved to determine the source file name and line number

+  where the code originally came from. This is required for error reporting.

+

+Arguments:

+  LineNum - the line number in the preprocessor-output file.

+

+Returns:

+  Returns a pointer to the source file name. Also returns the line number 

+  in the provided LineNum argument

+

+--*/

+;

+

+typedef struct _IFR_BYTE {

+  struct _IFR_BYTE  *Next;

+  UINT32            LineNum;

+  UINT8             OpcodeByte;

+  UINT8             KeyByte;

+} IFR_BYTE;

+

+typedef struct {

+  CHAR8 VfrFileName[MAX_PATH];

+  CHAR8 VfrListFileName[MAX_PATH];

+  INT8  CreateListFile;

+  INT8  CreateIfrBinFile;

+  CHAR8 IfrOutputFileName[MAX_PATH];

+  CHAR8 OutputDirectory[MAX_PATH];

+  CHAR8 PreprocessorOutputFileName[MAX_PATH];

+  CHAR8 VfrBaseFileName[MAX_PATH];  // name of input VFR file with no path or extension

+  CHAR8 *IncludePaths;

+  CHAR8 *CPreprocessorOptions;

+} OPTIONS;

+

+extern OPTIONS  gOptions;

+

+VOID

+WriteStandardFileHeader (

+  FILE *OutFptr

+  )

+/*++

+

+Routine Description:

+  This function is invoked to emit a standard header to an

+  output text file.

+  

+Arguments:

+  OutFptr - file to write the header to

+

+Returns:

+  None

+

+--*/

+;

+

+#endif // #ifndef _EFI_VFR_H_

diff --git a/edk2/Tools/Source/TianoTools/VfrCompile/VfrCompile.g b/edk2/Tools/Source/TianoTools/VfrCompile/VfrCompile.g
new file mode 100644
index 0000000..3646c5d
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/VfrCompile/VfrCompile.g
@@ -0,0 +1,3527 @@
+/*++

+

+Copyright (c) 2004 - 2005, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  VfrCompile.g

+

+Abstract:

+

+  PCCTS parser and lexer definitions for the EFI VFR forms compiler

+  

+--*/  

+

+#header<<

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <CommonLib.h>

+#include <MultiPhase.h>

+#include "EfiUtilityMsgs.h"

+#include "EfiVfr.h"

+#include "VfrServices.h"

+#include <UgaDraw.h>

+#include <Hii.h>

+

+#include <ctype.h>

+#ifndef __GNUC__

+#include <direct.h>

+#include <process.h> // for spawn functions

+#else

+#include <unistd.h>

+#endif

+

+>>

+

+<<

+

+//

+// Base info for DLG-generated scanner

+//

+#include "DLexerBase.h"    

+

+//

+// Include the scanner file generated by DLG

+//

+#include "DLGLexer.h"    

+

+class DLGLexerVfr : public DLGLexer

+{

+public:

+  DLGLexerVfr (DLGFileInput *F) : DLGLexer (F) {};

+  INT32 errstd (char *Text) 

+  { 

+    printf ("unrecognized input '%s'\n", Text); 

+  }

+};

+

+//

+// Base token definitions for ANTLR

+//

+#include "AToken.h"

+

+//

+// This is how we invoke the C preprocessor on the VFR source file

+// to resolve #defines, #includes, etc. To make C source files

+// shareable between VFR and drivers, define VFRCOMPILE so that

+// #ifdefs can be used in shared .h files.

+//

+#ifdef __GNUC__

+#define PREPROCESSOR_COMMAND        "gcc "

+#define PREPROCESSOR_OPTIONS        "-x c -E -P -DVFRCOMPILE "

+#define FILE_SEP_CHAR '/'

+#define FILE_SEP_STRING "/"

+#else

+#define PREPROCESSOR_COMMAND        "cl.exe "

+#define PREPROCESSOR_OPTIONS        "/nologo /P /TC /DVFRCOMPILE "

+#define FILE_SEP_CHAR '/'

+#define FILE_SEP_STRING "/"

+#endif

+

+typedef ANTLRCommonToken ANTLRToken;

+

+//

+// Specify the filename extensions for the files we generate.

+//

+#define VFR_BINARY_FILENAME_EXTENSION       ".c"

+#define VFR_LIST_FILENAME_EXTENSION         ".lst"

+

+static 

+VOID 

+Usage ();

+

+static 

+STATUS 

+ProcessArgs (

+  int         Argc, 

+  char        *Argv[]

+  );

+

+static 

+VOID 

+Cleanup ();

+

+//

+// Globals

+//

+OPTIONS gOptions;

+

+int 

+main (

+  int   argc, 

+  char  **argv

+  )

+/*++

+

+Routine Description:

+  Application entry point function. Parse command-line arguments, 

+  invoke the parser, clean up, and return.

+

+Arguments:

+  argc - standard argc passed to main() per C conventions

+  argv - standard argv passed to main() per C conventions

+

+Returns:

+  STATUS_SUCCESS - program executed with no errors or warnings

+  STATUS_WARNING - program executed with warnings

+  STATUS_ERROR   - non-recoverable errors encountered while processing

+

+--*/

+{

+  FILE      *VfrFptr;

+  char      *Cmd;

+  char      *Cptr;

+  int       Len;

+  STATUS    Status;

+    

+  //

+  // Set our program name for the error printing routines.

+  // Then set printing limits.

+  //

+  SetUtilityName (PROGRAM_NAME);

+  SetPrintLimits (20, 20, 30);

+  //

+  // Process the command-line arguments

+  //

+  if (ProcessArgs (argc, argv) != STATUS_SUCCESS) {

+    Usage ();

+    Cleanup();

+    return STATUS_ERROR;

+  }

+  VfrFptr = NULL;

+  //

+  // Verify the VFR script file exists

+  //

+  if ((VfrFptr = fopen (gOptions.VfrFileName, "r")) == NULL) {

+    Error (PROGRAM_NAME, 0, 0, gOptions.VfrFileName, "could not open input VFR file");

+    Cleanup();

+    return STATUS_ERROR;

+  }

+  //

+  // Now close the file and make a system call to run the preprocessor

+  // on it.

+  //

+  fclose (VfrFptr);

+  Len = strlen (PREPROCESSOR_OPTIONS) + strlen (gOptions.VfrFileName) + 10;

+  if (gOptions.CPreprocessorOptions != NULL) {

+    Len += strlen (gOptions.CPreprocessorOptions) + 1;

+  }

+  if (gOptions.IncludePaths != NULL) {

+    Len += strlen (gOptions.IncludePaths) + 1;

+  }

+  Cmd = (char *)malloc (Len);

+  if (Cmd == NULL) {

+    Error (PROGRAM_NAME, 0, 0, NULL, "could not allocate memory");

+    Cleanup();

+    return STATUS_ERROR;

+  }  

+  strcpy (Cmd, PREPROCESSOR_OPTIONS);

+  if (gOptions.IncludePaths != NULL) {

+    strcat (Cmd, gOptions.IncludePaths);

+    strcat (Cmd, " ");

+  }

+  if (gOptions.CPreprocessorOptions != NULL) {

+    strcat (Cmd, gOptions.CPreprocessorOptions);

+    strcat (Cmd, " ");

+  }

+  strcat (Cmd, gOptions.VfrFileName);

+#ifndef __GNUC__

+  Status = _spawnlp (_P_WAIT, PREPROCESSOR_COMMAND, Cmd, NULL);

+#else

+  {

+    char CommandLine[1000];

+    char *p;

+

+    //

+    // Lean the slashes forward.

+    //

+    for (p = gOptions.PreprocessorOutputFileName; *p; p++) {

+      if (*p=='\\') {

+        *p=FILE_SEP_CHAR;

+      }

+    }

+ 

+    //

+    // Lean the slashes forward.

+    //

+    for (p = Cmd; *p; p++) {

+      if (*p=='\\') {

+        *p=FILE_SEP_CHAR;

+      }

+    }

+ 

+    sprintf(CommandLine, "%s %s > %s", PREPROCESSOR_COMMAND, Cmd, gOptions.PreprocessorOutputFileName);

+    Status = system (CommandLine);

+  }

+#endif

+  if (Status != 0) {

+    Error (PROGRAM_NAME, 0, 0, gOptions.VfrFileName, "failed to spawn C preprocessor on VFR file");

+    printf ("Command: '%s %s'\n", PREPROCESSOR_COMMAND, Cmd);

+    Cleanup();

+    return STATUS_ERROR;

+  }

+  free (Cmd);

+  //

+  // Open the preprocessor output file

+  //

+  if ((VfrFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) {

+    Error (PROGRAM_NAME, 0, 0, "failed to open input VFR preprocessor output file", 

+      gOptions.PreprocessorOutputFileName);

+    Cleanup();

+    return STATUS_ERROR;

+  }

+  //

+  // Define input VFR file

+  //

+  DLGFileInput InputFile (VfrFptr);

+  //

+  // Define an instance of the scanner    

+  //

+  DLGLexerVfr Scanner (&InputFile);

+  //

+  // Define token buffer between scanner and parser

+  //

+  ANTLRTokenBuffer Pipe (&Scanner);    

+  //

+  // Create a token to use as a model

+  //

+  ANTLRToken Tok;     

+  //

+  // Tell the scanner what type the token is

+  //

+  Scanner.setToken (&Tok);    

+  //

+  // Create an instance of our parser

+  //

+  EfiVfrParser Parser (&Pipe);    

+  //

+  // Initialize the parser    

+  //

+  Parser.init ();

+  Status = GetUtilityStatus ();

+  if (Status != STATUS_SUCCESS) {

+    Cleanup();

+    return Status;

+  }  

+  //

+  // Start the first rule    

+  //

+  Parser.program ();

+  //

+  // Close the input script file

+  //

+  fclose (VfrFptr);

+  Parser.WriteIfrBytes ();

+  //

+  // Call cleanup, which does some extra checking of the script

+  //

+  Parser.Cleanup ();

+  Cleanup();

+  //

+  // If we had an error somewhere, delete our output files so that

+  // a subsequent build will rebuild them.

+  //

+  Status = GetUtilityStatus ();

+  if (Status == STATUS_ERROR) {

+    remove (gOptions.IfrOutputFileName);

+  }

+  return Status;

+}

+static

+VOID

+Cleanup ()

+/*++

+

+Routine Description:

+  Free up memory allocated during parsing.

+

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{

+  //

+  // Free up our string we allocated to track the include paths

+  //

+  if (gOptions.IncludePaths != NULL) {

+    free (gOptions.IncludePaths);

+    gOptions.IncludePaths = NULL;

+  }

+  //

+  // Free up our string we allocated to track preprocessor options

+  //

+  if (gOptions.CPreprocessorOptions != NULL) {

+    free (gOptions.CPreprocessorOptions);

+    gOptions.CPreprocessorOptions = NULL;

+  }

+}  

+

+static

+STATUS

+ProcessArgs (

+  int         Argc, 

+  char        *Argv[]

+  )

+/*++

+

+Routine Description:

+  Process the command-line arguments.

+

+Arguments:

+  Argc - standard argc passed to main()

+  Argv - standard argv passed to main()

+

+Returns:

+  STATUS_SUCCESS - program should continue (all args ok)

+

+--*/

+{

+  char    *IncludePaths;

+  char    *CPreprocessorOptions;

+  int     Len;  

+  char    CopyStr[MAX_PATH];

+  char    *Cptr;

+

+  //

+  // Put options in known state.

+  //

+  memset ((char *)&gOptions, 0, sizeof (OPTIONS));

+  //

+  // Go through all the arguments that start with '-'

+  //

+  Argc--;

+  Argv++;

+  while ((Argc > 0) && (Argv[0][0] == '-')) {

+    //

+    // -? or -h help option -- return an error for printing usage

+    //

+    if ((stricmp (Argv[0], "-?") == 0) || (stricmp (Argv[0], "-h") == 0)) {

+      return STATUS_ERROR;

+      break;

+    //

+    // -l to create a listing output file

+    //

+    } else if (stricmp (Argv[0], "-l") == 0) {

+      gOptions.CreateListFile = 1;

+    //

+    // -I include_path option for finding include files. We'll pass this

+    // to the preprocessor. Turn them all into a single include string.

+    //

+    } else if (stricmp (Argv[0], "-i") == 0) {

+      if ((Argc < 2) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing path argument");

+        return STATUS_ERROR;

+      }

+      Argc--;

+      Argv++;

+      Len = strlen (" -I ");

+      Len += strlen (Argv[0]) + 2;

+      if (gOptions.IncludePaths != NULL) {

+        Len += strlen (gOptions.IncludePaths);

+      }

+      IncludePaths = (CHAR8 *)malloc (Len);

+      if (IncludePaths == NULL) {

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+      IncludePaths[0] = 0;

+      if (gOptions.IncludePaths != NULL) {

+        strcpy (IncludePaths, gOptions.IncludePaths);

+        free (gOptions.IncludePaths);

+      }

+      strcat (IncludePaths, " -I ");

+      strcat (IncludePaths, Argv[0]);

+      gOptions.IncludePaths = IncludePaths;

+    //

+    // -od OutputDirectory to define a common directory for output files

+    //

+    } else if (stricmp (Argv[0], "-od") == 0) {

+      if ((Argc < 2) || (Argv[1][0] == '-')) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output directory name");

+        return STATUS_ERROR;

+      }

+      Argc--;

+      Argv++;

+      strcpy (gOptions.OutputDirectory, Argv[0]);

+    } else if (stricmp (Argv[0], "-ibin") == 0) {

+      gOptions.CreateIfrBinFile = 1;

+    } else if (stricmp (Argv[0], "-nostrings") == 0) {

+      // deprecated option

+    //

+    // -ppflag C-preprocessor-flag option for passing options to the C preprocessor.

+    // Turn them all into a single string.

+    //

+    } else if (stricmp (Argv[0], "-ppflag") == 0) {

+      if (Argc < 2) {

+        Error (PROGRAM_NAME, 0, 0, Argv[0], "missing C-preprocessor argument");

+        return STATUS_ERROR;

+      }

+      Argc--;

+      Argv++;

+      Len = strlen (Argv[0]) + 2;

+      if (gOptions.CPreprocessorOptions != NULL) {

+        Len += strlen (gOptions.CPreprocessorOptions);

+      }

+      CPreprocessorOptions = (CHAR8 *)malloc (Len);

+      if (CPreprocessorOptions == NULL) {

+        Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+        return STATUS_ERROR;

+      }

+      CPreprocessorOptions[0] = 0;

+      if (gOptions.CPreprocessorOptions != NULL) {

+        strcpy (CPreprocessorOptions, gOptions.CPreprocessorOptions);

+        free (gOptions.CPreprocessorOptions);

+      }

+      strcat (CPreprocessorOptions, " ");

+      strcat (CPreprocessorOptions, Argv[0]);

+      gOptions.CPreprocessorOptions = CPreprocessorOptions;

+    } else {

+      Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option");

+      return STATUS_ERROR;

+    }

+    Argc--;

+    Argv++;

+  }

+  //

+  // Must specify at least the vfr file name

+  //

+  if (Argc > 1) {

+    Error (PROGRAM_NAME, 0, 0, Argv[1], "unrecognized argument after VFR file name");

+    return STATUS_ERROR;

+  } else if (Argc < 1) {

+    Error (PROGRAM_NAME, 0, 0, NULL, "must specify VFR file name");

+    return STATUS_ERROR;

+  }

+  strcpy (gOptions.VfrFileName, Argv[0]);

+  //

+  // We run the preprocessor on the VFR file to manage #include statements.

+  // Unfortunately the preprocessor does not allow you to specify the

+  // output name or path of the resultant .i file, so we have to do

+  // some work. Here we'll extract the basename of the VFR file, then

+  // append .i on the end. 

+  //

+  strcpy (CopyStr, gOptions.VfrFileName);

+  Cptr = CopyStr + strlen (CopyStr) - 1;

+  for (;(Cptr > CopyStr) && (*Cptr != '\\') && (*Cptr != ':') && (*Cptr != '/'); Cptr--);

+  if (Cptr == CopyStr) {

+    strcpy (gOptions.PreprocessorOutputFileName, Cptr);

+    strcpy (gOptions.VfrBaseFileName, Cptr);

+  } else {

+    strcpy (gOptions.PreprocessorOutputFileName, Cptr+1);

+    strcpy (gOptions.VfrBaseFileName, Cptr+1);

+  }

+  for (Cptr = gOptions.PreprocessorOutputFileName; *Cptr && (*Cptr != '.'); Cptr++);

+  strcpy (Cptr, ".i");

+  //

+  // Terminate the vfr file basename at the extension

+  //

+  for (Cptr = gOptions.VfrBaseFileName; *Cptr && (*Cptr != '.'); Cptr++) {

+  }

+  *Cptr = 0; 

+  //

+  // If they defined an output directory, prepend all output files

+  // with the working directory. Output files of interest:

+  //    VfrListFileName             -- list file

+  //    IfrOutputFileName           -- IFR bytes 

+  //    StringOutputFileName        -- string bytes

+  //    StringListFileName          -- not used

+  //    StringDefineFileName        -- #defines of string identifiers

+  //

+  // We have two cases:

+  //   1. Output directory (-od) not specified, in which case output files

+  //      go to the current working directory.

+  //   2. Output directory specified, in which case the output files

+  //      go directly to the specified directory.

+  //

+  if (gOptions.OutputDirectory[0] == 0) {

+    CopyStr[0] = 0;

+#ifndef __GNUC__

+    _getcwd (CopyStr, sizeof (CopyStr));

+#else

+    getcwd (CopyStr, sizeof (CopyStr));

+#endif

+    strcpy (gOptions.OutputDirectory, CopyStr);

+  }

+  //

+  // Make sure output directory has a trailing backslash

+  //

+  if (gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '\\' ||

+      gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '/') {

+    strcat (gOptions.OutputDirectory, FILE_SEP_STRING);

+  }

+  //

+  // Create the base output file name as: path\base, copy it to all the output

+  // filenames, and then add the appropriate extension to each.

+  //

+  strcpy (gOptions.VfrListFileName, gOptions.OutputDirectory);

+  strcat (gOptions.VfrListFileName, gOptions.VfrBaseFileName);

+  strcpy (gOptions.IfrOutputFileName, gOptions.VfrListFileName);

+  strcat (gOptions.VfrListFileName, VFR_LIST_FILENAME_EXTENSION);

+  strcat (gOptions.IfrOutputFileName, VFR_BINARY_FILENAME_EXTENSION);

+  //

+  // We set a default list file name, so if they do not

+  // want a list file, null out the name now.

+  //

+  if (gOptions.CreateListFile == 0) {

+    gOptions.VfrListFileName[0] = 0;

+  }

+  return STATUS_SUCCESS;

+}

+static 

+VOID 

+Usage ()

+/*++

+

+Routine Description:

+  Print utility usage instructions

+

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{

+  int Index;

+  const char *Help[] = {

+    " ", 

+    "VfrCompile version " VFR_COMPILER_VERSION,

+    " ",

+    "  Usage: VfrCompile {options} [VfrFile]",

+    " ",

+    "    where options include:",

+    "      -? or -h       prints this help",

+    "      -l             create an output IFR listing file",

+    "      -i IncPath     add IncPath to the search path for VFR included files",

+    "      -od OutputDir  deposit all output files to directory OutputDir (default=cwd)",

+    "      -ibin          create an IFR HII pack file",

+    "    where parameters include:",

+    "      VfrFile        name of the input VFR script file",

+    " ",

+    NULL

+    };

+  for (Index = 0; Help[Index] != NULL; Index++) {

+    fprintf (stdout, "%s\n", Help[Index]);

+  }

+}

+    

+>>

+

+

+#lexaction

+<<

+

+#include "EfiVfr.h"

+

+PARSER_LINE_DEFINITION  *gLineDefinition = NULL;

+PARSER_LINE_DEFINITION  *gLastLineDefinition = NULL;

+

+VOID

+AddFileLine (

+  char      *TokenString,

+  UINT32    TokenLine

+  )

+/*++

+

+Routine Description:

+  During the lexer phase, if we encounter a #line statement output by

+  the preprocessor, this function gets called. We'll save off the info 

+  for error reporting purposes. The preprocessor line information has the

+  form:

+    

+    #line 3 "FileName.c"  

+

+Arguments:

+  TokenString - the parsed string as shown above

+  TokenLine   - the line number in the preprocessed output file 

+  

+Returns:

+  NA

+

+--*/

+{

+  PARSER_LINE_DEFINITION  *LineDef;

+  CHAR8                   *Cptr;

+  

+  //

+  // Allocate a structure in which we can keep track of this line information.

+  //

+  LineDef = (PARSER_LINE_DEFINITION *)malloc (sizeof (PARSER_LINE_DEFINITION));

+  memset ((char *)LineDef, 0, sizeof (PARSER_LINE_DEFINITION));

+  LineDef->TokenLineNum = TokenLine;

+  LineDef->HashLineNum = atoi (TokenString + 6);

+  //

+  // Find the quotes in the filename, then allocate space in the line

+  // def structure for a copy of the filename. Finally, copy it without

+  // quotes to the line def.

+  //

+  for (Cptr = TokenString + 7; *Cptr && (*Cptr != '"'); Cptr++);

+  if (*Cptr == '"') {

+    LineDef->FileName = (CHAR8 *)malloc (strlen (Cptr));

+    Cptr++;

+    strcpy (LineDef->FileName, Cptr);

+    for (Cptr = LineDef->FileName; *Cptr && (*Cptr != '"'); Cptr++);

+    *Cptr = 0;   

+    //

+    // Now add this new one to the list

+    //

+    if (gLineDefinition == NULL) {

+      gLineDefinition = LineDef;

+    } else {

+      gLastLineDefinition->Next = LineDef;

+    }

+    gLastLineDefinition = LineDef;

+  } else {

+    Error (PROGRAM_NAME, 0, 0, "invalid line definition in preprocessor output file", TokenString);

+    free (LineDef);

+    return;

+  }

+}

+char *

+ConvertLineNumber (

+  UINT32 *LineNum

+  )

+/*++

+

+Routine Description:

+  Given the line number in the preprocessor-output file, use the line number

+  information we've saved to determine the source file name and line number

+  where the code originally came from. This is required for error reporting.

+

+Arguments:

+  LineNum - the line number in the preprocessor-output file.

+

+Returns:

+  Returns a pointer to the source file name. Also returns the line number 

+  in the provided LineNum argument

+

+--*/

+{

+  PARSER_LINE_DEFINITION  *LineDef;

+  //

+  // Step through our linked list of #line information we saved off. 

+  // For each one, look at its line number, and the line number of the

+  // next record, and see if the passed-in line number is in the range.

+  // If it is, then convert the line number to the appropriate line number

+  // of the original source file.

+  //

+  for (LineDef = gLineDefinition; LineDef != NULL; LineDef = LineDef->Next) {

+    //

+    // The given LineNum is the line number from the .i file.

+    // Find a line definition whose range includes this line number,

+    // convert the line number, and return the filename.

+    //

+    if (LineDef->TokenLineNum <= *LineNum) {

+      if (LineDef->Next != NULL) {

+        if (LineDef->Next->TokenLineNum > *LineNum) {

+          *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum;

+          return LineDef->FileName;

+        }

+      } else {

+        //

+        // Last one in the list of line definitions, so has to be right

+        //

+        *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum;

+        return LineDef->FileName;

+      }

+    }

+  }

+  return NULL;

+}

+

+>>

+

+//

+// Define a lexical class for parsing quoted strings. Basically

+// starts with a double quote, and ends with a double quote that

+// is not preceeded with a backslash.

+//

+#lexclass QUOTED_STRING

+#token TheString            "~[\"]*\"" << mode (START); >>     

+

+//

+// Define a lexical class for parsing "#pragma pack" statements. 

+// We do this just for convenience (since we skip them here) so

+// that users can include some minimal .h files.

+//

+#lexclass PRAGMA_PACK

+#token "pack"     << skip (); >>

+#token "[\ \t]"   << skip (); >> 

+#token "\("       << skip (); >>

+#token "[0-9]*"   << skip (); >>

+#token "\)"       << skip (); mode (START); >>

+

+//

+// Define a lexclass for skipping over C++ style comments

+//

+#lexclass CPP_COMMENT

+#token "~[\n]*"       << skip (); >>

+#token "\n"           << skip (); mode (START); newline (); >>

+

+//

+// Standard lexclass is START

+//

+#lexclass START

+

+//

+// Find start of C++ style comments

+//

+#token "//"     << skip (); mode (CPP_COMMENT); >>

+

+//

+// Skip whitespace

+//

+#token "[\ \t]"   << skip (); >> 

+

+//

+// Skip over newlines, but count them

+//

+#token "\n"       << skip (); newline (); >>

+

+//

+// Skip pragma pack statements

+//

+#token "\#pragma" << skip (); mode(PRAGMA_PACK); >>

+

+//

+// Skip over 'extern' in any included .H file

+//

+#token "extern"   << skip (); >>

+

+//

+// Tokens for the different keywords. Syntax is:

+// TokenName("ErrorMessageText")    "TokenString"

+//   where:

+//     TokenName is the token name (must be capitalized) that is used in the rules

+//     ErrorMessageText is the string the compiler emits when it detects a syntax error

+//     TokenString is the actual matching string used in the user script

+//

+#token LineDefinition                           "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << AddFileLine (begexpr (), line ()); skip (); >>

+#token FormSet("formset")                       "formset"

+#token EndFormSet("endformset")                 "endformset"

+#token Title("title")                           "title"

+#token FormId("formid")                         "formid"

+#token OneOf("oneof")                           "oneof"

+#token Prompt("prompt")                         "prompt"

+#token OrderedList("orderedlist")               "orderedlist"

+#token EndList("endlist")                       "endlist"

+#token EndForm("endform")                       "endform"

+#token EndOneOf("endoneof")                     "endoneof"

+#token Form("form")                             "form"

+#token Subtitle("subtitle")                     "subtitle"

+#token Help("help")                             "help"

+#token VarId("varid")                           "varid"

+#token Text("text")                             "text"

+#token Option("option")                         "option"

+#token Value("value")                           "value"

+#token Flags("flags")                           "flags"

+#token Date("date")                             "date"

+#token EndDate("enddate")                       "enddate"

+#token Year("year")                             "year"

+#token Month("month")                           "month"

+#token Day("day")                               "day"

+#token Time("time")                             "time"

+#token EndTime("endtime")                       "endtime"

+#token Hour("hour")                             "hour"

+#token Minute("minute")                         "minute"

+#token Second("second")                         "second"

+#token AND("AND")                               "AND"

+#token OR("OR")                                 "OR"

+#token GrayOutIf("grayoutif")                   "grayoutif"

+#token NOT("NOT")                               "NOT"

+#token Label("label")                           "label"

+#token Timeout("timeout")                       "timeout"

+#token Inventory("inventory")                   "inventory"

+#token StringToken("STRING_TOKEN")              "STRING_TOKEN"

+#token NonNvDataMap("_NON_NV_DATA_MAP")         "_NON_NV_DATA_MAP"

+#token Struct("struct")                         "struct"

+#token Uint64("UINT64")                         "UINT64"

+#token Uint32("UINT32")                         "UINT32"

+#token Uint16("UINT16")                         "UINT16"

+#token Char16("CHAR16")                         "CHAR16"

+#token Uint8("UINT8")                           "UINT8"

+#token Guid("guid")                             "guid"

+#token CheckBox("checkbox")                     "checkbox"

+#token EndCheckBox("endcheckbox")               "endcheckbox"

+#token Numeric("numeric")                       "numeric"

+#token EndNumeric("endnumeric")                 "endnumeric"            

+#token Minimum("minimum")                       "minimum"         

+#token Maximum("maximum")                       "maximum"         

+#token Step("step")                             "step"      

+#token Default("default")                       "default"         

+#token Password("password")                     "password"          

+#token EndPassword("endpassword")               "endpassword"             

+#token String("string")                         "string"        

+#token EndString("endstring")                   "endstring"           

+#token MinSize("minsize")                       "minsize"         

+#token MaxSize("maxsize")                       "maxsize"         

+#token Encoding("encoding")                     "encoding"

+#token SuppressIf("suppressif")                 "suppressif"

+#token Hidden("hidden")                         "hidden"

+#token Goto("goto")                             "goto"

+#token InconsistentIf                           "inconsistentif"

+#token EndIf("endif")                           "endif"

+#token IdEqId("ideqid")                         "ideqid"

+#token IdEqVal("ideqval")                       "ideqval"

+#token VarEqVal("vareqval")                     "vareqval"

+#token Var("var")                               "var"

+#token IdEqValList("ideqvallist")               "ideqvallist"

+#token Length("length")                         "length"

+#token Values("values")                         "values"

+#token Key("key")                               "key"

+#token DefaultFlag("DEFAULT")                   "DEFAULT"

+#token ManufacturingFlag("MANUFACTURING")       "MANUFACTURING"

+#token InteractiveFlag("INTERACTIVE")           "INTERACTIVE"

+#token NVAccessFlag("NV_ACCESS")                "NV_ACCESS"

+#token ResetRequiredFlag("RESET_REQUIRED")      "RESET_REQUIRED"

+#token LateCheckFlag("LATE_CHECK")              "LATE_CHECK"

+#token Class("class")                           "class"

+#token Subclass("subclass")                     "subclass"

+#token TypeDef("typedef")                       "typedef"

+#token Restore("restore")                       "restore"

+#token Save("save")                             "save"

+#token Defaults("defaults")                     "defaults"

+#token Banner("banner")                         "banner"

+#token Align("align")                           "align"

+#token Left("left")                             "left"

+#token Right("right")                           "right"

+#token Center("center")                         "center"

+#token Line("line")                             "line"

+#token VarStore("varstore")                     "varstore"

+#token Name("name")                             "name"

+#token Oem("oem")                               "oem"

+#token True("TRUE")                             "TRUE"

+#token False("FALSE")                           "FALSE"

+#token GreaterThan(">")                         ">"

+#token GreaterEqual(">=")                       ">="

+#token LessThan("<")                          "<"

+#token LessEqual("<=")                        "<="

+

+//

+// Define the class and subclass tokens

+//

+#token ClassNonDevice("NONDEVICE")                        "NON_DEVICE"

+#token ClassDiskDevice("DISK_DEVICE")                     "DISK_DEVICE"

+#token ClassVideoDevice("VIDEO_DEVICE")                   "VIDEO_DEVICE"

+#token ClassNetworkDevice("NETWORK_DEVICE")               "NETWORK_DEVICE"

+#token ClassInputDevice("INPUT_DEVICE")                   "INPUT_DEVICE"

+#token ClassOnBoardDevice("ONBOARD_DEVICE")               "ONBOARD_DEVICE"

+#token ClassOtherDevice("OTHER_DEVICE")                   "OTHER_DEVICE"

+

+#token SubclassSetupApplication("SETUP_APPLICATION")      "SETUP_APPLICATION"

+#token SubclassGeneralApplication("GENERAL_APPLICATION")  "GENERAL_APPLICATION"

+#token SubclassFrontPage("FRONT_PAGE")                    "FRONT_PAGE"

+#token SubclassSingleUse("SINGLE_USE")                    "SINGLE_USE"

+

+#token LanguageIdentifier("language identifier") "[a-z][a-z][a-z]"   // 3 lowercase characters

+#token StringIdentifier("string identifier")    "[A-Za-z_][A-Za-z_0-9]*"

+#token Number("numeric value")                  "(0x[0-9A-Fa-f]+) | [0-9]+"

+#token OpenBrace("{")                           "\{"

+#token CloseBrace("}")                          "\}"

+#token OpenParen("(")                           "\("

+#token CloseParen(")")                          "\)"

+#token OpenBracket("[")                         "\["

+#token CloseBracket("]")                        "\]"

+

+//

+// Define all other invalid characters so that they get through the lexical phase

+// and we can catch them during the parse phase. We get much better error

+// messages then. 

+//

+#token InvalidCharacters("invalid characters")  "~[;:=,\.\|]"  

+

+//

+// This is the overall definition of a VFR form definition script.

+//

+program :

+  ( dataStructDefinition )*

+  formSetStatement   

+  ( vfrStatementVarStore )*

+  ( formDefinition )*

+  EFS:EndFormSet  ";"                   << WriteOpByte (EFS->getLine(), EFI_IFR_END_FORM_SET_OP); >>

+  "@" // end of file

+  ;

+    

+formSetStatement :

+  FS:FormSet                            << WriteOpByte (FS->getLine(), EFI_IFR_FORM_SET_OP); >>

+  Guid "=" 

+  OpenBrace 

+  G1:Number ","

+  G2:Number ","

+  G3:Number ","

+  OpenBrace

+  G4:Number ","

+  G5:Number ","

+  G6:Number ","

+  G7:Number ","

+  G8:Number ","

+  G9:Number ","

+  G10:Number ","

+  G11:Number 

+  CloseBrace

+  CloseBrace                            << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (),

+                                                           G4->getText (), G5->getText (), G6->getText (), G7->getText (),

+                                                           G8->getText (), G9->getText (), G10->getText (), G11->getText ()

+                                                          );

+                                         >>

+  ","

+  Title "=" getStringId ","

+  Help  "=" getStringId ","

+  //

+  // insert padding for an EFI_PHYSICAL_ADDRESS (UINT64)

+  //

+                                            << WriteDWord (0, 0); WriteDWord (0, 0); >>

+  Class "=" CVAL:classDefinition ","        << WriteClass (); >>

+  Subclass "=" SVAL:subclassDefinition ","  << WriteSubclass (); >>

+                                            << WriteWord (mNvDataStructSize); >>

+  ;  

+

+//

+// A form can be of multiple classes, thus allow CLASS_A | CLASS_B | CLASS_C

+//

+classDefinition :

+  validClassNames ( "\|" validClassNames )*

+  ;

+  

+validClassNames :

+    CND:ClassNonDevice          << SetClass (CND->getLine(), EFI_NON_DEVICE_CLASS); >>

+  | CDD:ClassDiskDevice         << SetClass (CDD->getLine(), EFI_DISK_DEVICE_CLASS); >>

+  | CVD:ClassVideoDevice        << SetClass (CVD->getLine(), EFI_VIDEO_DEVICE_CLASS); >>

+  | CNW:ClassNetworkDevice      << SetClass (CNW->getLine(), EFI_NETWORK_DEVICE_CLASS); >>

+  | CID:ClassInputDevice        << SetClass (CID->getLine(), EFI_INPUT_DEVICE_CLASS); >>

+  | COB:ClassOnBoardDevice      << SetClass (COB->getLine(), EFI_ON_BOARD_DEVICE_CLASS); >>

+  | COD:ClassOtherDevice        << SetClass (COD->getLine(), EFI_OTHER_DEVICE_CLASS); >>

+  | CNUM:Number                 << SetClass (CNUM->getLine(), GetNumber (CNUM->getText(), CNUM->getLine(), 4)); >>

+  ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid class"); >>

+

+//

+// A form can only be of one subclass type.

+//

+subclassDefinition :

+    SSA:SubclassSetupApplication    << SetSubclass (SSA->getLine(), EFI_SETUP_APPLICATION_SUBCLASS); >>

+  | SGA:SubclassGeneralApplication  << SetSubclass (SGA->getLine(), EFI_GENERAL_APPLICATION_SUBCLASS); >>

+  | SFP:SubclassFrontPage           << SetSubclass (SFP->getLine(), EFI_FRONT_PAGE_SUBCLASS); >>

+  | SSU:SubclassSingleUse           << SetSubclass (SSU->getLine(), EFI_SINGLE_USE_SUBCLASS); >>

+  | SNUM:Number                     << SetSubclass (SNUM->getLine(), GetNumber (SNUM->getText(), SNUM->getLine(), 4)); >>

+  ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid subclass"); >>

+

+//

+// Parse a C type data structure for storing VFR setup data. Allow:

+//  typedef struct _XXX_ {

+//     (fields)

+//  } MY_NV_DATA;

+//

+dataStructDefinition :

+  << int IsNonNV = 0; >>

+  { TypeDef } 

+  S:Struct                          

+  (

+    NonNvDataMap                    << IsNonNV = 1; >>

+  |

+    { StringIdentifier }

+  )                                 << StartStructDefinition (IsNonNV, S->getLine()); >>

+  OpenBrace 

+  dataStructFields 

+  CloseBrace NAME:StringIdentifier  << EndStructDefinition (NAME->getText(), NAME->getLine()); >>

+  ";"

+  ;

+

+//

+// Parse a C type data structure for defining data that is not stored in NV.

+//  typedef struct _NON_NV_DATA_MAP {

+//     (fields)

+//  } NON_NV_DATA_MAP;

+//

+nonNvDataStructDefinition :

+  { TypeDef } 

+  Struct NonNvDataMap

+  { StringIdentifier }

+  OpenBrace 

+  dataStructFields 

+  CloseBrace NAME:StringIdentifier        << AddStructField (NAME->getText(), NAME->getLine(), 0, 0, 0); >>

+  ";"                                             

+  ;

+

+dataStructFields :

+  ( dataStructField64 | dataStructField32 | dataStructField16 | dataStructField8 ) *

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   UINT64 Name[4];

+//   UINT64 Name;

+//

+// Used while parsing the NV data map structures.

+//

+dataStructField64 :

+  << int ArrayLength = 1; char IsArray = 0; >>

+  "UINT64" 

+  NAME:StringIdentifier 

+  ( ";" | OpenBracket IVal:Number CloseBracket ";"  << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) 

+                                                    << AddStructField (NAME->getText(), NAME->getLine(), 8, ArrayLength, IsArray); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   UINT32 Name[4];

+//   UINT32 Name;

+//

+// Used while parsing the NV data map structures.

+//

+dataStructField32 :

+  << int ArrayLength = 1; char IsArray = 0; >>

+  "UINT32" 

+  NAME:StringIdentifier 

+  ( ";" | OpenBracket IVal:Number CloseBracket ";"  << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> )  

+                                                    << AddStructField (NAME->getText(), NAME->getLine(), 4, ArrayLength, IsArray); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   UINT16 Name[4];

+//   UINT16 Name;

+//

+// Used while parsing the NV data map structures.

+//

+dataStructField16 :

+  << int ArrayLength = 1; char IsArray = 0; >>

+  ( "UINT16" | "CHAR16" )

+  NAME:StringIdentifier 

+  ( ";" | OpenBracket IVal:Number CloseBracket ";"  << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) 

+                                                    << AddStructField (NAME->getText(), NAME->getLine(), 2, ArrayLength, IsArray); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   UINT8 Name[4];

+//   UINT8 Name;

+//

+// Used while parsing the NV data map structures.

+//

+dataStructField8 :

+  << int ArrayLength = 1; char IsArray = 0; >>

+  "UINT8" 

+  NAME:StringIdentifier 

+  ( ";" | OpenBracket IVal:Number CloseBracket ";"  << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) 

+                                                    << AddStructField (NAME->getText(), NAME->getLine(), 1, ArrayLength, IsArray); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//    form formid = 1,

+//      title  = STRING_TOKEN(STR_FORM_TITLE);

+//      -- form statements --

+//    endform;

+//

+//  The Form ID cannot be 0

+//

+formDefinition :

+  FRM:Form FormId                << WriteOpByte (FRM->getLine(), EFI_IFR_FORM_OP); >> 

+  "=" 

+  VAL:Number                     << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); AddFormId (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); >>

+  ","

+  Title "=" getStringId ";"      // writes string identifier

+  ( vfrStatements )*

+  ENDF:EndForm  ";"              << WriteOpByte (ENDF->getLine(), EFI_IFR_END_FORM_OP); >>

+  ;

+

+//

+// VFR statements in a formset

+//

+vfrStatements :

+  vfrStatementSubTitle        | 

+  vfrStatementOneOf           |

+  vfrStatementTextText        |

+  vfrStatementCheckBox        |

+  vfrStatementNumeric         |

+  vfrStatementDate            |

+  vfrStatementTime            |

+  vfrStatementPassword        |

+  vfrStatementString          |

+  vfrStatementSuppressIf      |

+  vfrStatementHidden          |

+  vfrStatementGoto            | 

+  vfrStatementGrayOutIf       |

+  vfrStatementInconsistentIf  |

+  vfrStatementLabel           |

+  vfrStatementBanner          |

+  vfrStatementInventory       |

+  vfrStatementOrderedList     |

+  vfrStatementOem             |

+  vfrStatementSaveRestoreDefaults

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   label 100;

+//

+vfrStatementLabel :

+  OPID:Label                              << WriteOpByte (OPID->getLine(), EFI_IFR_LABEL_OP); >>

+  VAL:Number                              << 

+                                              WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); 

+                                              AddLabel (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine());

+                                          >>

+  ";"

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   oem 0x12, 0x34, 0x56;

+//

+vfrStatementOem :

+  OPID:Oem                              << WriteOpByte (OPID->getLine(), EFI_IFR_OEM_DEFINED_OP); >>

+  ( VAL1:Number << WriteByte (GetNumber (VAL1->getText(), VAL1->getLine(), 1), 0); >> )

+  ( "," VAL2:Number << WriteByte (GetNumber (VAL2->getText(), VAL2->getLine(), 1), 0); >> )*

+  ";"

+  ;

+  

+//*****************************************************************************

+//

+// PARSE:

+//   inconsistentif NOT .... AND NOT .... OR ... endif;

+//

+vfrStatementInconsistentIf : 

+  << ResetFlags (); >>

+  IIFOP:InconsistentIf                  << WriteOpByte (IIFOP->getLine(), EFI_IFR_INCONSISTENT_IF_OP); >>

+  Prompt "=" getStringId ","

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* "," 

+  }

+  << WriteFlags (); >> //  write the flags field

+  vfrBooleanExpression

+  EOP:EndIf ";"                         << WriteOpByte (EOP->getLine(), EFI_IFR_END_IF_OP); >>

+  ;

+

+//*****************************************************************************

+// 

+// PARSE:

+//   TRUE AND (ideqval SomeStruct.SomeMember >= 0x10 OR 

+//               ideqid SomeStruct.SomeMember < SomeStruct.SomeOtherMember) AND

+//            (ideqlist SomeStruct.SomeOtherMember == 0x10, 0x20, 0x30 OR

+//               vareqval var(VAR_EQ_TEST_NAME) == 0x1)

+//

+// For supporting complex express, divide the vfrBooleanExpression to two parts

+// so that pred-LL(k) parser can parse incrementally.

+//

+vfrBooleanExpression :

+  leftPartVfrBooleanExp { rightPartVfrBooleanExp }

+  ;

+  

+leftPartVfrBooleanExp :

+  OpenParen vfrBooleanExpression CloseParen                                                        |

+  (ideqval | ideqid | ideqvallist | vareqval | truefalse)                                          |

+  NOPID:NOT leftPartVfrBooleanExp           << WriteOpByte (NOPID->getLine(), EFI_IFR_NOT_OP); >>

+  ;

+

+rightPartVfrBooleanExp :

+  AOPID:AND vfrBooleanExpression            << WriteOpByte (AOPID->getLine(), EFI_IFR_AND_OP); >>  |

+  OOPID:OR vfrBooleanExpression             << WriteOpByte (OOPID->getLine(), EFI_IFR_OR_OP); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   TRUE

+//

+truefalse :

+  TOPID:True                                << WriteOpByte (TOPID->getLine(), EFI_IFR_TRUE_OP); >> |

+  FOPID:False                               << WriteOpByte (FOPID->getLine(), EFI_IFR_FALSE_OP); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   varstore MY_STRUCT_NAME, key = 0x1234, name = "MyVariableName", guid = {...};

+//

+vfrStatementVarStore : 

+  OP:VarStore                           << WriteOpByte (OP->getLine(), EFI_IFR_VARSTORE_OP); >>

+  STRUCT_NAME:StringIdentifier ","

+  Key   "=" KNUM:Number ","

+  Name  "=" VAR_NAME:StringIdentifier ","  

+  Guid "=" 

+  OpenBrace 

+  G1:Number ","

+  G2:Number ","

+  G3:Number ","

+  OpenBrace

+  G4:Number ","

+  G5:Number ","

+  G6:Number ","

+  G7:Number ","

+  G8:Number ","

+  G9:Number ","

+  G10:Number ","

+  G11:Number 

+  CloseBrace

+  CloseBrace                            << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (),

+                                                           G4->getText (), G5->getText (), G6->getText (), G7->getText (),

+                                                           G8->getText (), G9->getText (), G10->getText (), G11->getText ()

+                                                          );

+                                           WriteWord (GetNumber (KNUM->getText(), KNUM->getLine(), 2)); 

+                                           AddVarStore (STRUCT_NAME->getText(), VAR_NAME->getText(), GetNumber (KNUM->getText(), KNUM->getLine(), 2), STRUCT_NAME->getLine());

+                                         >>

+  

+  ";"

+  ;

+

+//*****************************************************************************

+//

+// PARSE:  

+//   vareqval var(0x100) == 0x20

+//

+vareqval : 

+  OPID:VarEqVal                           << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_VAR_VAL_OP); >>

+  Var OpenParen 

+  VAR:Number                              << WriteWord (GetNumber (VAR->getText(), VAR->getLine(), 2)); >>

+  CloseParen

+  compareNumber

+  ;

+

+ideqval : 

+  OPID:IdEqVal                            << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_VAL_OP); >>

+  vfrStructFieldName[0]

+  compareNumber

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   ideqid MyNVData3.Field16A == MyNVData3.Field16B

+//

+// NOTE: Before processing the second variable store in the ideqid statement, set a global flag

+//       so that when we parse the second variable we set the secondary variable store id.

+//

+ideqid : 

+  OPID:IdEqId                             << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_ID_OP);  >>

+  vfrStructFieldName[0]

+  compareVfrStructFieldNameNL0

+  ;

+

+//*****************************************************************************

+//

+// compareNumber is the combination of compare operation and Number

+//

+compareNumber :

+  (

+  "=="

+  VAL1:Number                             << WriteWord (GetNumber (VAL1->getText(), VAL1->getLine(), 2)); >>

+  ) |

+  (

+  GTOPID:GreaterThan

+  VAL2:Number                             << WriteWord (GetNumber (VAL2->getText(), VAL2->getLine(), 2));

+                                             WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >>

+  ) |

+  (

+  GEOPID:GreaterEqual

+  VAL3:Number                             << WriteWord (GetNumber (VAL3->getText(), VAL3->getLine(), 2));

+                                             WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >>

+  ) |

+  (

+  LTOPID:LessThan

+  VAL4:Number                             << WriteWord (GetNumber (VAL4->getText(), VAL4->getLine(), 2));

+                                             WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP);

+                                             WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >>

+  ) |

+  (

+  LEOPID:LessEqual

+  VAL5:Number                             << WriteWord (GetNumber (VAL5->getText(), VAL5->getLine(), 2));

+                                             WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP);

+                                             WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >>

+  )

+  ;

+

+//*****************************************************************************

+//

+// compareVfrStructFieldNameNL0 is the combination of compare operation and  vfrStructFieldNameNL[0]

+//

+compareVfrStructFieldNameNL0 :

+  (

+  "=="                                    << mIdEqIdStmt = 1; >>

+  vfrStructFieldNameNL[0]                 << mIdEqIdStmt = 0; >>

+  ) |

+  (

+  GTOPID:GreaterThan                      << mIdEqIdStmt = 1; >>

+  vfrStructFieldNameNL[0]                 << mIdEqIdStmt = 0;

+                                             WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >>

+  ) |

+  (

+  GEOPID:GreaterEqual                     << mIdEqIdStmt = 1; >>

+  vfrStructFieldNameNL[0]                 << mIdEqIdStmt = 0;

+                                             WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >>

+  ) |

+  (

+  LTOPID:LessThan                       << mIdEqIdStmt = 1; >>

+  vfrStructFieldNameNL[0]                 << mIdEqIdStmt = 0;

+                                             WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP);

+                                             WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >>

+  ) |

+  (

+  LEOPID:LessEqual                      << mIdEqIdStmt = 1; >>

+  vfrStructFieldNameNL[0]                 << mIdEqIdStmt = 0;

+                                             WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP);

+                                             WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >>

+  )

+  ;

+  

+

+ideqvallist : 

+  OPID:IdEqValList                        << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_LIST_OP); >>

+  vfrStructFieldName[0] 

+  "=="

+  ( VAL:Number                            << QueueIdEqValList (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> ) +

+                                          << FlushQueueIdEqValList(); >>

+  ;

+    

+vfrStatementGoto : 

+  << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>

+  IDG:Goto                          << WriteOpByte (IDG->getLine(), EFI_IFR_REF_OP); >>

+  VAL:Number  ","                   << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); 

+                                       AddGotoReference (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine());

+                                    >>

+  KP:Prompt   "=" getStringId ","   << LineNum = KP->getLine();  >>

+  Help        "=" getStringId

+  { 

+    "," 

+    FF:Flags  "=" flagsField ( "\|" flagsField )*  << LineNum = FF->getLine(); >>

+  }

+  {

+    "," Key   "=" KNUM:Number       << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>

+  }

+                                    << WriteFlagsKey (KeyValue, LineNum); >>

+  ";"

+  ;

+    

+vfrStatementHidden : 

+  IDH:Hidden                  << WriteOpByte (IDH->getLine(), EFI_IFR_HIDDEN_OP); >>

+  Value "="

+  VAL:Number ","              << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); >>

+  Key "="

+  KVAL:Number                 << WriteWord (GetNumber (KVAL->getText(), KVAL->getLine(), 2)); >>

+  ";"

+  ;    

+

+//*****************************************************************************

+//

+// PARSE:

+//   suppressif <boolean_expression> { grayoutif } <statements>+ endif;

+// Note:

+//   You can have: suppressif:grayoutif:statements:endif

+//                 suppressif:grayoutif:endif                  -- serves no purpose

+//                 suppressif:statements:endif

+//                 suppressif:endif                            -- serves no purpose

+//

+vfrStatementSuppressIf : 

+  << ResetFlags (); >>

+  OPID:SuppressIf                     << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* ","

+  }

+  << WriteFlags (); >> //  write the flags field 

+  vfrBooleanExpression

+  ";"

+  { suppressIfGrayOutIf } ( suppressIfAndGrayoutIfSubstatements )+

+  ENDOP:EndIf ";"                     << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>

+  ;

+

+//

+// This is the form for a grayoutif nested in a suppressif statement

+//

+suppressIfGrayOutIf :

+  << ResetFlags (); >>

+  OPID:GrayOutIf                      << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* "," 

+  }

+  << WriteFlags (); >> //  write the flags field

+  vfrBooleanExpression

+  ";"

+  ; 

+

+//*****************************************************************************

+//

+// PARSE:

+//   grayoutif { flags = n, } <boolean_expression> endif;

+// Note:

+//   You can have: grayoutif:suppressif:statements:endif

+//                 grayoutif:statements:endif

+//

+//

+vfrStatementGrayOutIf :

+  << ResetFlags (); >>

+  OPID:GrayOutIf                      << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* "," 

+  }

+  << WriteFlags (); >> //  write the flags field

+  vfrBooleanExpression

+  ";"

+  { grayoutIfSuppressIf } ( suppressIfAndGrayoutIfSubstatements )+ 

+  ENDOP:EndIf ";"                     << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>

+  ;

+

+//

+// This is the format for a suppressif nested in a grayoutif

+//

+grayoutIfSuppressIf : 

+  << ResetFlags (); >>

+  OPID:SuppressIf                     << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* ","

+  }

+  << WriteFlags (); >> //  write the flags field

+  vfrBooleanExpression

+  ";"

+  ;

+

+//

+// These are the VFR statements that are valid inside a suppressif or grayoutif statement.

+//

+suppressIfAndGrayoutIfSubstatements :

+  vfrStatementOneOf           |

+  vfrStatementTextText        |

+  vfrStatementCheckBox        |

+  vfrStatementNumeric         |

+  vfrStatementDate            |

+  vfrStatementTime            |

+  vfrStatementPassword        |

+  vfrStatementString          |

+  vfrStatementHidden          |

+  vfrStatementGoto            | 

+  vfrStatementLabel           |

+  vfrStatementInventory       |

+  vfrStatementOrderedList     |

+  vfrStatementSaveRestoreDefaults

+  ; 

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//    password  varid    = MyNvData.Password,

+//              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),

+//              help     = STRING_TOKEN(STR_PASSWORD_HELP),

+//              minsize  = 6,

+//              maxsize  = 20,

+//              encoding = 1,

+//    endpassword; 

+  

+vfrStatementPassword : 

+  << UINT32 KeyValue = 0; UINT32 LineNum; ResetFlags (); >>

+  IDPW:Password                       << WriteOpByte (IDPW->getLine(), EFI_IFR_PASSWORD_OP); >>

+  VarId       "=" vfrStructFieldNameArray[0] ","

+  Prompt      "=" getStringId ","

+  KH:Help     "=" getStringId ","    << LineNum = KH->getLine(); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* ","  << LineNum = FF->getLine(); >>

+  }

+  {

+    Key "=" KNUM:Number ","           << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>

+  }

+                                      << WriteFlagsKey (KeyValue, LineNum); >>

+  MinSize   "=" MIN:Number ","        << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >>

+  MaxSize   "=" MAX:Number ","        << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >>

+  Encoding  "=" ENC:Number ","        << WriteWord (GetNumber (ENC->getText(), ENC->getLine(), 2)); >>

+  EndPassword  ";"              

+  ;

+

+//*****************************************************************************

+//

+//  PARSE:

+//

+//    string    varid    = MyNv.String,

+//              prompt   = STRING_TOKEN(STR_STRING_PROMPT),

+//              help     = STRING_TOKEN(STR_STRING_HELP),

+//              flags    = INTERACTIVE,

+//              key      = 0x1234,

+//              minsize  = 6,

+//              maxsize  = 0x14,

+//    endstring; 

+//

+// Since flags and key are optional, we can't use Flags->getLine(). Therefore for error

+// reporting we save the line number of the "help" keyword.

+//

+vfrStatementString : 

+  << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >>

+  IDS:String                                << WriteOpByte (IDS->getLine(), EFI_IFR_STRING_OP); >>

+  VarId     "=" vfrStructFieldNameArray[0] ","

+  Prompt    "=" getStringId ","

+  KH:Help   "=" getStringId ","             << LineNum = KH->getLine(); >>

+  { 

+    FF:Flags "=" 

+    flagsField ( "\|" flagsField )*         << LineNum = FF->getLine(); >>

+    "," 

+  }

+  {

+    Key "=" KNUM:Number ","                 << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>

+  }

+                                            << WriteFlagsKey (KeyValue, LineNum); >>

+  MinSize   "=" MIN:Number ","              << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0);  >>

+  MaxSize   "=" MAX:Number ","              << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >>

+  EndString  ";"

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//    numeric varid   = MyIfrNVData.HowOldAreYouInYears, 

+//            prompt  = STRING_TOKEN(STR_NUMERIC_PROMPT),

+//            help    = STRING_TOKEN(STR_NUMERIC_HELP),

+//            flags   = INTERACTIVE,  // flags is optional

+//            key     = 0x1234,       // key is optional if (flags & INTERACTIVE = 0)

+//            minimum = 0x0,

+//            maximum = 0xf0,

+//            step    = 1,            // step is option, and step=1 if not specified

+//            default = 0;            // default is optional, and default=minimum if not specified

+//    endnumeric;

+//

+// Make flags and key optional. However if flags includes INTERACTIVE, then a key is required.

+// That check is done in WriteFlagsKey() function.

+//

+vfrStatementNumeric :  

+  << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>

+  IDN:Numeric                         << WriteOpByte (IDN->getLine(), EFI_IFR_NUMERIC_OP); >>

+  VarId     "=" vfrStructFieldName[2] ","

+  Prompt    "=" getStringId ","

+  KH:Help   "=" getStringId ","       << LineNum = KH->getLine(); >>

+  { 

+    FF:Flags "=" flagsField ( "\|" flagsField )* ","     << LineNum = FF->getLine (); >>

+  }

+  {

+    Key "=" KNUM:Number  ","          << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>

+  }

+                                      << WriteFlagsKey (KeyValue, LineNum); >>

+  minMaxStepDefault                   

+  EndNumeric ";"                      << WriteMinMaxStepDefault (); >>

+  ;

+

+//

+// Parse minimum/maximum/step/default statements. Special cases:

+//   - if step not specified, then the value is 1

+//   - if default not specified, then the value is the min value specified

+//   - if max < min, print a warning and swap the values (changes default too)

+//

+minMaxStepDefault :

+  << InitMinMaxStepDefault (); >>

+  Minimum   "=" MIN:Number ","        << SetMinMaxStepDefault (GetNumber (MIN->getText(),  MIN->getLine(), 2), 0, MIN->getLine()); >>

+  Maximum   "=" MAX:Number ","        << SetMinMaxStepDefault (GetNumber (MAX->getText(),  MAX->getLine(), 2), 1, MAX->getLine()); >>

+  { Step    "=" STEP:Number ","       << SetMinMaxStepDefault (GetNumber (STEP->getText(), STEP->getLine(), 2), 2, STEP->getLine()); >> }

+  { Default "=" DEF:Number ","        << SetMinMaxStepDefault (GetNumber (DEF->getText(),  DEF->getLine(), 2), 3, DEF->getLine()); >> }

+  ;

+

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//    date    year varid  = Date.Year,                        // "Date.Year" is a special case we recognize

+//            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+//            help        = STRING_TOKEN(STR_DATE_YEAR_HELP),

+//            minimum     = 1939,

+//            maximum     = 2101,

+//            step        = 1,

+//            default     = 1964,

+//

+//            month varid = Date.Month,    

+//            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+//            help        = STRING_TOKEN(STR_DATE_MONTH_HELP),

+//            minimum     = 1,

+//            maximum     = 12,

+//            step        = 1,

+//            default     = 1,

+//

+//            day varid   = Date.Day,

+//            prompt      = STRING_TOKEN(STR_DATE_PROMPT),

+//            help        = STRING_TOKEN(STR_DATE_DAY_HELP),

+//            minimum     = 1,

+//            maximum     = 31,

+//            step        = 0x1,

+//            default     = 1,

+//

+//    enddate;

+//  

+vfrStatementDate :  

+  Date                            

+  IDY:Year VarId "="                  << WriteOpByte (IDY->getLine(), EFI_IFR_DATE_OP); >>

+  vfrStructFieldName[2] "," 

+  dateTimeSubStatement                    

+  IDM:Month VarId "="                 << WriteOpByte (IDM->getLine(), EFI_IFR_DATE_OP); >>

+  vfrStructFieldName[2] "," 

+  dateTimeSubStatement                    

+  IDD:Day VarId "="                   << WriteOpByte (IDD->getLine(), EFI_IFR_DATE_OP); >> 

+  vfrStructFieldName[2] ","  

+  dateTimeSubStatement    

+  EndDate ";"

+  ;

+  

+vfrStatementTime :  

+  Time                            

+  IDH:Hour VarId "="                  << WriteOpByte (IDH->getLine(), EFI_IFR_TIME_OP); >>

+  vfrStructFieldName[2] ","  

+  dateTimeSubStatement                    

+  IDM:Minute VarId "="                << WriteOpByte (IDM->getLine(), EFI_IFR_TIME_OP); >>

+  vfrStructFieldName[2] "," 

+  dateTimeSubStatement                    

+  IDS:Second VarId "="                << WriteOpByte (IDS->getLine(), EFI_IFR_TIME_OP); >>

+  vfrStructFieldName[2] "," 

+  dateTimeSubStatement

+  EndTime ";"

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//   text  text = STRING_ID;

+//   text  text = STRING_ID, text = STRING_ID;

+//   text  text = STRING_ID, text = STRING_ID, flags = x, key = y;

+//

+vfrStatementTextText :

+  << ResetFlags (); >>

+  IDT:Text                            << WriteOpByte (IDT->getLine(), EFI_IFR_TEXT_OP); >>

+  Help "=" getStringId ","

+  Text "=" 

+  getStringId                         // writes string identifier

+  { "," Text "=" getStringId

+    "," Flags "=" flagsField ( "\|" flagsField )*  << WriteFlags (); >>

+    "," 

+    Key "=" KNUM:Number               << WriteWord (GetNumber(KNUM->getText(), KNUM->getLine(), 2)); >>

+  }

+  ";" 

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//   inventory help = ID, text = ID;

+//   inventory help = ID, text = id, text = ID;

+//

+vfrStatementInventory :

+  IDI:Inventory                        << WriteOpByte (IDI->getLine(), EFI_IFR_INVENTORY_OP); >>

+  Help        "=" getStringId ","

+  Text        "=" getStringId                 // writes string identifier

+  { "," Text  "=" getStringId

+  }

+  ";" 

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//    restore defaults,

+//      formid  = 4,

+//      prompt  = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT),

+//      help    = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP),

+//      flags   = 0,

+//      key     = 0;

+//

+//    save defaults,

+//      formid  = 4,

+//      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),

+//      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),

+//      flags   = 0,

+//      key     = 0;

+//

+vfrStatementSaveRestoreDefaults : 

+  << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >>

+  ( IDS:Save                            << WriteOpByte (IDS->getLine(), EFI_IFR_SAVE_DEFAULTS_OP); >>

+  | IDR:Restore                         << WriteOpByte (IDR->getLine(), EFI_IFR_RESTORE_DEFAULTS_OP); >>

+  )

+  Defaults ","

+  FormId    "=" FRMID:Number  ","       << WriteWord (GetNumber (FRMID->getText(), FRMID->getLine(), 2)); 

+                                           AddGotoReference (GetNumber (FRMID->getText(), FRMID->getLine(), 2), FRMID->getLine());

+                                        >>

+  Prompt    "=" getStringId ","

+  KH:Help   "=" getStringId             << LineNum = KH->getLine(); >>

+  { 

+    "," FF:Flags "=" flagsField ( "\|" flagsField )*  << LineNum = FF->getLine(); >>

+  }

+  {

+    "," Key "=" KNUM:Number             << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >>

+  }

+                                        << WriteFlagsKey (KeyValue, LineNum); >>

+  ";"

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//   flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK

+//

+// 

+flagsField :

+  VAL:Number                          << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >>

+  | IF:InteractiveFlag                << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine());    >>

+  | MF:ManufacturingFlag              << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine());  >>

+  | DF:DefaultFlag                    << SetFlags (EFI_IFR_FLAG_DEFAULT, DF->getLine());        >>

+  | NV:NVAccessFlag                   << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine());      >>

+  | RR:ResetRequiredFlag              << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >>

+  | LC:LateCheckFlag                  << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine());     >>

+  ;

+

+dateTimeSubStatement :

+  Prompt  "=" getStringId ","

+  Help    "=" getStringId ","

+                                      << WriteByte (0, 0); WriteWord (0); >> // bogus flags and key

+  minMaxStepDefault                   << WriteMinMaxStepDefault (); >>

+  ;

+  

+vfrStatementCheckBox :  

+  << UINT32 LineNum, KeyValue = 0; ResetFlags (); >>

+  IDCB:CheckBox                       << WriteOpByte (IDCB->getLine(), EFI_IFR_CHECKBOX_OP); >>

+  VarId     "=" vfrStructFieldName[1] ","

+  Prompt    "=" getStringId ","

+  Help      "=" getStringId ","

+  FF:Flags  "=" flagsField ( "\|" flagsField )*  "," << LineNum = FF->getLine(); >>

+  { 

+    Key "=" KV:Number  ","           << LineNum = KV->getLine(); KeyValue = GetNumber(KV->getText(), LineNum, 2); >>

+  }

+                                     << WriteFlagsKey (KeyValue, LineNum); >>

+  EndCheckBox ";"

+  ;

+     

+vfrStatementSubTitle :

+  IDS:Subtitle Text "="               << WriteOpByte (IDS->getLine(), EFI_IFR_SUBTITLE_OP); >>

+  getStringId                         // writes string indentifier

+  ";"

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//    banner 

+//      title = STRING_TOKEN(STR_BANNER_TITLE),

+//      line  1,

+//      align center;     // or left or right

+//

+//    banner, 

+//      title = STRING_TOKEN(STR_BANNER_TITLE), timeout = 100;

+//

+vfrStatementBanner :

+  IDB:Banner { "," }                    << WriteOpByte (IDB->getLine(), EFI_IFR_BANNER_OP); >>

+  Title "=" getStringId ","

+  ( 

+    Line VAL:Number ","                 << WriteWord (GetNumber(VAL->getText(), VAL->getLine(), 2)); >>

+    Align 

+    ( Left                              << WriteByte (EFI_IFR_BANNER_ALIGN_LEFT, 0); >>

+    | Center                            << WriteByte (EFI_IFR_BANNER_ALIGN_CENTER, 0); >>

+    | Right                             << WriteByte (EFI_IFR_BANNER_ALIGN_RIGHT, 0); >>

+    ) ";"

+  |

+    Timeout "=" TO:Number ";"           << WriteWord (GetNumber(TO->getText(), TO->getLine(), 2)); >>

+                                        << WriteByte (EFI_IFR_BANNER_TIMEOUT, 0); >>

+  )

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   oneof  varid       = MyNv.OneOfData,

+//          prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),

+//          help        = STRING_TOKEN(STR_ONE_OF_HELP),

+//          option text = STRING_TOKEN(STR_ONE_OF_TEXT), 

+//          value       = 0, 

+//          flags       = DEFAULT | INTERACTIVE;

+//

+// supressif/grayoutif are supported inside oneof stmt.

+// We do not restrict the number of oneOfOptionText to >=2, but >=1.

+// The situation that all oneOfOptionText are suppressed is also possiable.

+//

+vfrStatementOneOf :

+  << ResetFlags (); >>

+  IDOO:OneOf                              << WriteOpByte (IDOO->getLine(), EFI_IFR_ONE_OF_OP); >>

+  VarId   "=" vfrStructFieldName[2] ","       

+  Prompt  "=" getStringId  ","           // writes string identifier

+  Help    "=" getStringId  ","           // writes string identifier

+  ( oneOfOptionText )+                   // there must be at least 1 option to be choosed, not 2.

+  IDEOO:EndOneOf   ";"                    << TestOneOfFlags (IDEOO->getLine()); WriteOpByte (IDEOO->getLine(), EFI_IFR_END_ONE_OF_OP); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//  

+//   orderedlist  varid       = MyNv.OrderedListData,

+//                prompt      = STRING_TOKEN(STR_ORDERED_LIST_PROMPT),

+//                help        = STRING_TOKEN(STR_ORDERED_LIST_HELP),  

+//                option text = STRING_TOKEN(STR_ORDERED_LIST_TEXT), value = 0, flags = INTERACTIVE;

+//                -- additional option text -- 

+//   endlist;

+//

+vfrStatementOrderedList :

+  << ResetFlags (); InitOrderedList(); >>

+  IDOL:OrderedList                       << WriteOpByte (IDOL->getLine(), EFI_IFR_ORDERED_LIST_OP); >>

+  VarId   "=" vfrStructFieldNameArray[1] ","       

+  Prompt  "=" getStringId  ","           // writes string identifier

+  Help    "=" getStringId  ","           // writes string identifier

+  orderedListOptionText ( orderedListOptionText )+

+  IDEOL:EndList   ";"                    << WriteOpByte (IDEOL->getLine(), EFI_IFR_END_OP); EndOrderedList(IDEOL->getLine()); >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//   option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99;

+//

+// Differs from the oneOfOptionText in that we don't allow the DEFAULT flag to

+// be set, and value cannot be 0.

+//

+orderedListOptionText :

+  << UINT32 KeyValue = 0; >>

+  IDO:Option                          << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >>

+  Text      "=" getStringId ","       // writes string identifier

+  Value     "=" WVAL:Number ","       << 

+                                          if (GetNumber(WVAL->getText(), WVAL->getLine(), 2) == 0) {

+                                            PrintErrorMessage (WVAL->getLine(), "value=0 is invalid for ordered lists", NULL); 

+                                          } else {

+                                            WriteWord (GetNumber(WVAL->getText(), WVAL->getLine(), 2)); 

+                                          }

+                                      >>

+  FF:Flags  "=" orderedListFlagsField  

+                ("\|" orderedListFlagsField )*                   

+  { 

+    "," Key "=" KV:Number             << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> 

+  }

+                                      << WriteFlagsKey (KeyValue, FF->getLine()); >>

+  ";"                                 << mOptionCount++; >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//   flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK

+//

+// The ordered list flags field cannot have a default.

+//

+orderedListFlagsField :

+  VAL:Number                          << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >>

+  | IF:InteractiveFlag                << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine());    >>

+  | MF:ManufacturingFlag              << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine());  >>

+  | NV:NVAccessFlag                   << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine());      >>

+  | RR:ResetRequiredFlag              << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >>

+  | LC:LateCheckFlag                  << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine());     >>

+  | DF:DefaultFlag                    << PrintWarningMessage (DF->getLine(), "DEFAULT flag not valid for ordered lists", NULL); >>

+  ;

+

+//

+// Parse references to VFR structure field names of form "MyNvStructure.Field". 

+// This implementation is specific to strings, passwords, and references in an 

+// ordered list statement because we want to specify the size of the entire 

+// field, rather than just one element. Then call a function to write out its 

+// offset and length.

+//

+vfrStructFieldNameArray[int FieldWidth] :

+  << int ArrayIndex = 1; char IsArrayIndex = 0; >>

+  SName:StringIdentifier 

+  "." 

+  SFieldName:StringIdentifier 

+  { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }

+            << 

+                WriteFieldOffset (1, 

+                                  SName->getText(), 

+                                  SName->getLine(), 

+                                  SFieldName->getText(), 

+                                  SFieldName->getLine(),

+                                  ArrayIndex, 

+                                  IsArrayIndex,

+                                  FieldWidth,

+                                  1

+                                  ); 

+            >>

+  ;

+

+//

+// Parse references to VFR structure field names of form "MyNvStructure.Field",

+// then call a function to write out its offset and length.

+//

+vfrStructFieldName[int FieldWidth] :

+  << int ArrayIndex = 1; char IsArrayIndex = 0; >>

+  SName:StringIdentifier 

+  "." 

+  SFieldName:StringIdentifier 

+  { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }

+            << 

+                WriteFieldOffset (1, 

+                                  SName->getText(), 

+                                  SName->getLine(), 

+                                  SFieldName->getText(), 

+                                  SFieldName->getLine(),

+                                  ArrayIndex, 

+                                  IsArrayIndex,

+                                  FieldWidth,

+                                  0

+                                  ); 

+            >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//

+//   MyNvStructure.FieldName[4]

+//

+// Parse references to VFR structure field names of form "MyNvStructure.Field",

+// then call a function to write out the offset with no length.

+//

+vfrStructFieldNameNL[int FieldWidth] :

+  << int ArrayIndex = 1; char IsArrayIndex = 0; >>

+  SName:StringIdentifier 

+  "." 

+  SFieldName:StringIdentifier 

+  { OpenBracket AIndex:Number CloseBracket   << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> }

+            << 

+                WriteFieldOffset (0, 

+                                  SName->getText(), 

+                                  SName->getLine(), 

+                                  SFieldName->getText(), 

+                                  SFieldName->getLine(),

+                                  ArrayIndex, 

+                                  IsArrayIndex,

+                                  FieldWidth,

+                                  0

+                                  ); 

+            >>

+  ;

+

+//*****************************************************************************

+//

+// PARSE:

+//   suppressif TRUE OR FALSE;

+//   grayoutif FALSE OR TRUE;

+//     option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99;

+//     option text = STRING_TOKEN(STRING_ID2), value = 1 flags = 98;

+//   endif;

+//

+oneOfOptionText :

+  suppressIfOptionText    |

+  grayOutIfOptionText     |

+  commonOptionText

+  ;

+

+suppressIfOptionText : 

+  << ResetFlags (); >>

+  OPID:SuppressIf                     << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* ","

+  }

+  << WriteFlags (); >> //  write the flags field 

+  vfrBooleanExpression

+  ";"

+  { suppressIfGrayOutIf } ( commonOptionText )+

+  ENDOP:EndIf ";"                     << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>

+  ;

+

+grayOutIfOptionText :

+  << ResetFlags (); >>

+  OPID:GrayOutIf                      << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >>

+  { 

+    FF:Flags  "=" flagsField ( "\|" flagsField )* "," 

+  }

+  << WriteFlags (); >> //  write the flags field

+  vfrBooleanExpression

+  ";"

+  { grayoutIfSuppressIf } ( commonOptionText )+ 

+  ENDOP:EndIf ";"                     << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >>

+  ;

+

+commonOptionText : 

+  << UINT32 KeyValue = 0; >>

+  IDO:Option                      << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >>

+  Text      "=" getStringId ","   // writes string identifier

+  Value     "=" WVal:Number ","   << WriteWord (GetNumber(WVal->getText(), WVal->getLine(), 2)); >>

+  FF:Flags  "=" flagsField  ("\|" flagsField )*                   

+  { 

+    "," Key "=" KV:Number         << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> 

+  }

+                                  << WriteFlagsKey (KeyValue, FF->getLine()); >>

+  ";"                             << mOptionCount++; >>

+  ;

+

+//

+// Gets a string identifier. It must be a numeric value of form:

+// 

+//   STRING_TOKEN(100)

+//

+getStringId :

+  << unsigned short StrId; >>

+  StringToken OpenParen

+  IdVal:Number             << StrId = GetNumber (IdVal->getText(), IdVal->getLine(), 2); WriteStringIdWord (StrId); >> 

+  CloseParen

+  ;

+

+//******************************************************************************

+//

+// Parser class definition. 

+//  

+class EfiVfrParser {

+<<

+//

+// Parser definitions go here    

+//

+private:

+  STRUCT_DEFINITION   *mFirstStructDefinition;

+  STRUCT_DEFINITION   *mLastStructDefinition;

+  INT32               mNvDataStructSize;                    

+  INT32               mNonNvDataStructSize;

+  //

+  // Flag to indicate that we're processing a ideqid VFR statement so that

+  // we can do late checks on the statement.

+  //

+  INT32               mIdEqIdStmt;

+  INT32               mLastNVVariableDataSize;

+  GOTO_REFERENCE      *mGotoReferences;

+  FORM_ID_VALUE       *mFormIdValues;

+  VfrOpcodeHandler    mOpcodeHandler;

+  UINT16_LIST         *mUint16List;

+  UINT16_LIST         *mLastUint16;

+  UINT16_LIST         *mDefinedLabels;

+  UINT16_LIST         *mDefinedVarStoreId;

+  UINT16_LIST         *mLastDefinedVarStoreId;

+  UINT32              mMinimumValue, mMaximumValue, mStepValue, mDefaultValue;

+  UINT32              mStmtFlags;

+  UINT32              mSubStmtFlags;

+  UINT32              mSubStmtFlagsLineNum;

+  EFI_GUID            mFormSetGuid;

+  UINT8               mNvDataStructDefined;

+  UINT16              mClass, mSubclass;

+  UINT32              mIfStart;

+  UINT32              mOptionCount;  // how many "option" fields in a given statement

+  UINT32              mLastVarIdSize;

+  UINT8               mOutput;

+public:        

+

+VOID 

+EfiVfrParser::SetIfStart (

+  UINT32 LineNum

+  )

+/*++

+

+Routine Description:

+  Invoked during VFR parsing when an "if" is encountered. Save the

+  source line number so we can point to it if we don't find a 

+  corresponding endif later.

+

+Arguments:

+  LineNum - source line number where the "if" was parsed.

+

+Returns:

+  None

+

+--*/

+{

+  mIfStart = LineNum;

+}

+VOID 

+EfiVfrParser::SetClass (

+  UINT32 LineNum, 

+  UINT32 Value

+  ) 

+/*++

+

+Routine Description:

+  Invoked during VFR parsing when a "class" statement is found. Check the

+  range on the class value and save it for later.

+

+Arguments:

+  LineNum - source line number where the class statement was parsed.

+  Value   - the class value

+

+Returns:

+  None

+

+--*/

+{

+  if (Value & 0xFFFF0000) {

+    PrintWarningMessage (LineNum, NULL, "class value exceeds maximum allowed");

+  }

+  mClass |= (UINT16)Value;

+}

+VOID 

+EfiVfrParser::SetSubclass (

+  UINT32 LineNum, 

+  UINT32 Value

+  ) 

+/*++

+

+Routine Description:

+  Invoked during VFR parsing when a subclass statement is found. Check the

+  range on the value and save it for later.

+

+Arguments:

+  LineNum - source line number where the class statement was parsed.

+  Value   - the subclass value from the VFR statement

+

+Returns:

+  None

+

+--*/

+{

+  if (Value & 0xFFFF0000) {

+    PrintWarningMessage (LineNum, NULL, "subclass value exceeds maximum allowed");

+  }

+  mSubclass |= (UINT16)Value;

+}

+VOID EfiVfrParser::WriteClass ()

+{

+  WriteWord (mClass);

+  mClass = 0;

+}

+VOID EfiVfrParser::WriteSubclass ()

+{

+  WriteWord (mSubclass);

+  mSubclass = 0;

+}

+VOID EfiVfrParser::WriteIfrBytes ()

+{

+  mOpcodeHandler.WriteIfrBytes ();

+}

+VOID 

+EfiVfrParser::WriteFlagsKey (

+  UINT32 KeyValue, 

+  UINT32 LineNum

+  ) 

+/*++

+

+Routine Description:

+  Write out the flags and key values from the previous VFR statement.

+  Many statements take a flags/key pair. If not specified, then 0

+  values are written out. However do not allow an interactive flags field

+  to be specified if no key value is specified. Also, if NV_ACCESS flag

+  is set but INTERACTIVE is not, then set interactive and issue a warning.

+

+Arguments:

+  KeyValue  - the key value from the VFR statement

+  LineNum   - source line number where the statement was parsed

+

+Returns:

+  None

+

+--*/

+{

+  if ((mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE) && (KeyValue == 0)) {

+    PrintErrorMessage (LineNum, NULL, "invalid or missing key value - required with INTERACTIVE");

+  }

+  if ((mSubStmtFlags & EFI_IFR_FLAG_NV_ACCESS) && !(mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE)) {

+    PrintWarningMessage (LineNum, NULL, "NV_ACCESS without INTERACTIVE has no effect -- setting INTERACTIVE");

+    mSubStmtFlags |= EFI_IFR_FLAG_INTERACTIVE;

+  }

+  WriteFlags ();

+  WriteWord (KeyValue);

+}

+VOID 

+EfiVfrParser::InitOrderedList ()

+{

+  mOptionCount = 0;

+}  

+VOID 

+EfiVfrParser::EndOrderedList (

+  UINT32 LineNum

+  )

+{

+  if (mLastVarIdSize < mOptionCount) {

+    PrintErrorMessage (LineNum, NULL, "number of options exceeds the variable store size");

+  }

+}

+VOID 

+EfiVfrParser::ResetFlags ()

+/*++

+

+Routine Description:

+

+  Flags are set for each substatement in a given one-of statement.

+  To make sure there are no conflicts, for example setting DEFAULT on

+  more than one substatement, we keep track of the flags at a statement

+  level and a substatement level. This function resets the flags so 

+  we get a fresh start.

+

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{

+  mStmtFlags = 0;

+  mSubStmtFlagsLineNum = 0;

+  mSubStmtFlags = 0;

+}

+//

+// Test validity of flags value for a one-of statement.

+//

+VOID 

+EfiVfrParser::TestOneOfFlags (

+  UINT32 LineNum

+  ) 

+{

+  //

+  // One of the fields must have had the default bit set

+  //

+  if ((mStmtFlags & EFI_IFR_FLAG_DEFAULT) == 0) {

+    PrintWarningMessage (LineNum, "default value must be specified", NULL);

+  }

+}

+VOID 

+EfiVfrParser::SetFlags (

+  UINT32 Flags, 

+  UINT32 LineNum

+  ) 

+{

+  //

+  // Check for redefinitions and invalid combinations

+  //

+  if (mStmtFlags & Flags & EFI_IFR_FLAG_MANUFACTURING) {

+    PrintErrorMessage (LineNum, "MANUFACTURING", "a field with this flag already defined");

+  }

+  if (mStmtFlags & Flags & EFI_IFR_FLAG_DEFAULT) {

+    PrintErrorMessage (LineNum, "DEFAULT", "a field with this flag already defined");

+  }

+  mSubStmtFlags |= Flags;

+  mSubStmtFlagsLineNum = LineNum;

+}

+VOID 

+EfiVfrParser::WriteFlags ()

+{

+  //

+  // Check value for validity

+  //

+  if (mSubStmtFlags & ~(EFI_IFR_FLAG_DEFAULT | 

+                        EFI_IFR_FLAG_MANUFACTURING | 

+                        EFI_IFR_FLAG_INTERACTIVE | 

+                        EFI_IFR_FLAG_NV_ACCESS | 

+                        EFI_IFR_FLAG_RESET_REQUIRED | 

+                        EFI_IFR_FLAG_LATE_CHECK )) {

+    PrintWarningMessage (mSubStmtFlagsLineNum, "invalid bits defined in flag", NULL);

+  }

+  WriteByte ((UINT8)mSubStmtFlags, 'F');

+  //

+  // We can now clear the substatement flags

+  //

+  mStmtFlags |= mSubStmtFlags;

+  mSubStmtFlags = 0;

+}

+//

+// When we parse a min/max/step/default sequence, save off the values for

+// later use. Call this first to init the values.

+//

+VOID 

+EfiVfrParser::InitMinMaxStepDefault ()

+{

+  mMinimumValue         = 0;

+  mMaximumValue         = 0;

+  mStepValue            = 1;

+  mDefaultValue         = 0;

+}  

+VOID 

+EfiVfrParser::WriteMinMaxStepDefault ()

+{

+  WriteWord (mMinimumValue);

+  WriteWord (mMaximumValue);

+  WriteWord (mStepValue);

+  WriteWord (mDefaultValue);

+}  

+VOID 

+EfiVfrParser::SetMinMaxStepDefault (

+  UINT16  Value, 

+  INT32   MMSD, 

+  INT32   LineNum

+  ) 

+{

+  UINT16 TempValue;

+  //

+  // Min specified

+  //

+  if (MMSD == 0) {

+    mMinimumValue = Value;

+    mDefaultValue = Value;

+  //

+  // Max specified

+  //

+  } else if (MMSD == 1) {

+    mMaximumValue = Value;

+    //

+    // If min > max, then swap the values. That includes resetting the default

+    // value as well.

+    //

+    if (mMinimumValue > mMaximumValue) {

+      PrintWarningMessage (LineNum, NULL, "maximum < minimum");      

+      TempValue = Value;

+      mMaximumValue = mMinimumValue;

+      mMinimumValue = TempValue;

+      mDefaultValue = mMinimumValue;

+    }

+  //

+  // Step specified

+  //

+  } else if (MMSD == 2) { 

+    mStepValue = Value;

+  //

+  // Default specified. Make sure min <= default <= max.

+  //

+  } else if (MMSD == 3) {

+    mDefaultValue = Value;

+    if (mMinimumValue > Value) {

+      PrintErrorMessage (LineNum, NULL, "default value < minimum value");

+    } else if (Value > mMaximumValue) {

+      PrintErrorMessage (LineNum, NULL, "default value > maximum value");

+    }

+  } else {

+    PrintErrorMessage (LineNum, "application error", "internal MMSD error");    

+  }

+}

+VOID 

+EfiVfrParser::AddLabel (

+  UINT32 LabelNumber, 

+  UINT32 LineNum

+  ) 

+{

+  UINT16_LIST *Label;

+

+  //

+  // Added a label from the user VFR script. Make sure they haven't already 

+  // defined the same label elsewhere

+  //

+  for (Label = mDefinedLabels; Label != NULL; Label = Label->Next) {

+    if (Label->Value == LabelNumber) {

+      PrintErrorMessage (LineNum, NULL, "label already defined");

+      PrintErrorMessage (Label->LineNum, NULL, "previous definition of redefined label");

+      break;

+    }

+  }

+  Label = (UINT16_LIST *)malloc (sizeof (UINT16_LIST));

+  if (Label == NULL) {

+    PrintErrorMessage (0, NULL, "memory allocation error");

+    return;

+  }

+  memset ((char *)Label, 0, sizeof (UINT16_LIST));

+  Label->Value = LabelNumber;

+  Label->LineNum = LineNum;

+  Label->Next = mDefinedLabels;

+  mDefinedLabels = Label;

+}

+VOID 

+EfiVfrParser::QueueIdEqValList (

+  UINT16 Value

+  )

+{

+  UINT16_LIST   *U16;

+  

+  U16 = (UINT16_LIST *)malloc (sizeof (UINT16_LIST));

+  if (U16 == NULL) {

+    Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failed");

+  } else {

+    memset ((char *)U16, 0, sizeof (UINT16_LIST));

+    U16->Value = Value;

+    if (mUint16List == NULL) {

+      mUint16List = U16;

+    } else {

+      mLastUint16->Next = U16;

+    } 

+    mLastUint16 = U16;

+  }

+}    

+VOID 

+EfiVfrParser::FlushQueueIdEqValList ()

+{

+  UINT32 Count;

+  

+  //

+  // We queued up a list of IdEqValList items. The IFR requires a count

+  // followed by the actual values. Do it.

+  //

+  Count = 0;

+  mLastUint16 = mUint16List;

+  while (mLastUint16 != NULL) {

+    Count++;

+    mLastUint16 = mLastUint16->Next;

+  }

+  // BUGBUG -- check for more than 16K items?

+  WriteWord (Count);

+  //

+  // Now write the values.

+  //

+  mLastUint16 = mUint16List;

+  while (mLastUint16 != NULL) {

+    WriteWord ((UINT32)mLastUint16->Value);

+    mLastUint16 = mLastUint16->Next;

+  }

+  //

+  // Free up the list

+  //  

+  mLastUint16 = mUint16List;

+  while (mUint16List != NULL) {

+    mLastUint16 = mUint16List->Next;

+    free (mUint16List);

+    mUint16List = mLastUint16;

+  }

+}

+VOID 

+EfiVfrParser::PrintErrorMessage (

+  UINT32              LineNum,

+  CHAR8               *Msg1,

+  CHAR8               *Msg2

+  )

+{

+  char *FileName;

+  

+  if (LineNum != 0) {

+    FileName = ConvertLineNumber ((UINT32 *)&LineNum);

+    Error (FileName, LineNum, 0, Msg1, Msg2);

+  } else {

+    Error (PROGRAM_NAME, 0, 0, Msg1, Msg2);

+  }

+}

+VOID 

+EfiVfrParser::PrintWarningMessage (

+  UINT32              LineNum,

+  CHAR8               *Msg1,

+  CHAR8               *Msg2

+  )

+{

+  char *FileName;

+  

+  if (LineNum != 0) {

+    FileName = ConvertLineNumber ((UINT32 *)&LineNum);

+    Warning (FileName, LineNum, 0, Msg1, Msg2);

+  } else {

+    Warning (PROGRAM_NAME, 0, 0, Msg1, Msg2);

+  }

+}

+VOID 

+EfiVfrParser::syn (

+  ANTLRAbstractToken  *Tok, 

+  ANTLRChar           *Egroup, 

+  SetWordType         *Eset, 

+  ANTLRTokenType      ETok, 

+  INT32               Huh

+  )

+/*++

+

+Routine Description:

+  Called by the parser base class as a result of parse syntax errors.

+

+Arguments:

+  Tok     - token that caused the error

+  Egroup  - not sure

+  Eset    - index in token table of the expected token

+  Huh     - not sure

+

+Returns:

+  NA

+

+--*/

+{

+  char    *FileName;

+  UINT32  LineNum;

+  

+  LineNum = Tok->getLine ();

+  FileName = ConvertLineNumber ((UINT32 *)&LineNum);

+  //

+  // Sometimes the token number is 0, in which case I don't know what to

+  // print.

+  //

+  if (ETok == 0) {

+    Error (FileName, LineNum, 0, Tok->getText (), "unexpected token");

+  } else {

+    //

+    // If we were expecting an endif, then report the line where the corresponding

+    // IF began.

+    //

+    if ((strcmp (_token_tbl[ETok], "endif") == 0) && (mIfStart != 0)) {

+      LineNum = mIfStart;

+      FileName = ConvertLineNumber (&LineNum);

+      Error (FileName, LineNum, 0, "statement missing corresponding endif", NULL);

+    } else {

+      Error (FileName, LineNum, 0, Tok->getText (), "expected %s", _token_tbl[ETok]);

+    }

+  }

+}

+

+VOID 

+EfiVfrParser::init()        

+/*++

+

+Routine Description:

+  Initializations function for our parser.

+

+Arguments:

+  None.

+

+Returns:

+  None.

+

+--*/

+{

+  ANTLRParser::init();

+

+  //

+  // Used for queuing a variable list of UINT16's

+  //

+  mUint16List               = NULL;

+  mLastUint16               = NULL;

+  mFirstStructDefinition    = NULL;

+  mLastStructDefinition     = NULL;

+  mNvDataStructSize         = 0;

+  mNonNvDataStructSize      = 0;

+  mNvDataStructDefined      = 0;

+  mGotoReferences           = NULL;

+  mFormIdValues             = NULL;

+  mDefinedLabels            = NULL;

+  mClass                    = 0;

+  mSubclass                 = 0;

+  mIfStart                  = 0;

+  mDefinedVarStoreId        = NULL;

+  mLastDefinedVarStoreId    = NULL;

+  mIdEqIdStmt               = 0;

+  mLastNVVariableDataSize   = 0;

+    

+  memset ((char *)&mFormSetGuid, 0, sizeof (EFI_GUID));

+}

+//

+// Destructor for the parser.

+//

+EfiVfrParser::~EfiVfrParser(VOID)

+{

+  Cleanup();

+}

+VOID

+EfiVfrParser::Cleanup (VOID)

+/*++

+

+Routine Description:

+  Free memory allocated during parsing

+

+Arguments:

+  None.

+

+Returns:

+  None.

+

+--*/

+{

+  STRUCT_DEFINITION         *NextStruct;

+  STRUCT_FIELD_DEFINITION   *NextField;

+  UINT8                     Buff[6];

+  UINT16_LIST               *NextU16List;

+  

+  //

+  // Free up the structure definitions if any

+  //

+  while (mFirstStructDefinition != NULL) {

+    //

+    // Free up all the fields for this struct

+    //

+    while (mFirstStructDefinition->Field != NULL) {

+      NextField = mFirstStructDefinition->Field->Next;

+      free (mFirstStructDefinition->Field->Name);

+      free (mFirstStructDefinition->Field);

+      mFirstStructDefinition->Field = NextField;

+    }

+    NextStruct = mFirstStructDefinition->Next;

+    free (mFirstStructDefinition->Name);

+    free (mFirstStructDefinition);

+    mFirstStructDefinition = NextStruct;

+  }

+  //

+  // Free up the goto references and form id defines

+  //

+  FreeGotoReferences ();

+  //

+  // Free up label list

+  //

+  while (mDefinedLabels != NULL) {

+    NextU16List = mDefinedLabels->Next;

+    delete (mDefinedLabels);

+    mDefinedLabels = NextU16List;

+  }

+  //

+  // Free up the list of defined variable storage IDs

+  //

+  while (mDefinedVarStoreId != NULL) {

+    NextU16List = mDefinedVarStoreId->Next;

+    delete (mDefinedVarStoreId);

+    mDefinedVarStoreId = NextU16List;

+  }

+}

+

+INT32 

+EfiVfrParser::AtoX (

+  CHAR8   *HexString, 

+  INT32   NumBytes, 

+  UINT32  *HexValue

+  )

+/*++

+

+Routine Description:

+  Given a pointer to a ascii hex string, convert to a number with the given

+  number of bytes.

+

+Arguments:

+  HexString   - pointer to a string of format 30BCA

+  Size        - number of bytes to convert

+  HexValue    - return result

+

+Returns:

+  The number of bytes converted.

+

+--*/

+{

+  INT32 Count;

+  INT32 Value;

+

+  *HexValue = 0;

+  Count = 0;

+  while (Count < NumBytes) {

+    if ((*HexString >= '0') && (*HexString <= '9')) {

+      Value = *HexString - '0';

+    } else if ((*HexString >= 'a') && (*HexString <= 'f')) {

+      Value = *HexString - 'a' + 10;

+    } else if ((*HexString >= 'A') && (*HexString <= 'F')) {

+      Value = *HexString - 'A' + 10;

+    } else {

+      return Count;

+    }

+    HexString++;

+    *HexValue = (*HexValue << 4) | Value;

+    if ((*HexString >= '0') && (*HexString <= '9')) {

+      Value = *HexString - '0';

+    } else if ((*HexString >= 'a') && (*HexString <= 'f')) {

+      Value = *HexString - 'a' + 10;

+    } else if ((*HexString >= 'A') && (*HexString <= 'F')) {

+      Value = *HexString - 'A' + 10;

+    } else {

+      return Count;

+    }

+    *HexValue = (*HexValue << 4) | Value;

+    HexString++;

+    Count++;

+  }

+  return Count;

+}

+VOID 

+EfiVfrParser::WriteGuidValue (

+  UINT32       TokenLineNum,

+  CHAR8        *G1, 

+  CHAR8        *G2,

+  CHAR8        *G3,

+  CHAR8        *G4,

+  CHAR8        *G5,

+  CHAR8        *G6,

+  CHAR8        *G7,

+  CHAR8        *G8,

+  CHAR8        *G9,

+  CHAR8        *G10,

+  CHAR8        *G11

+  )

+/*++

+

+Routine Description:

+  A Guid was parsed, likely of format:

+  #define MY_GUID { 0x12345678, 0xAABB, 0xCCDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }

+

+  Write out the value.

+

+Arguments:

+  TokenLineNum   - line number where the guid was used

+  G1-G11         - the 11 fields of the guid value

+

+Returns:

+  None.

+

+--*/

+{

+  UINT32        Value;

+  INT32         Loop;

+

+  mFormSetGuid.Data1 = GetNumber (G1, TokenLineNum, 4);

+  mFormSetGuid.Data2 = (UINT16)GetNumber (G2, TokenLineNum, 2);

+  mFormSetGuid.Data3 = (UINT16)GetNumber (G3, TokenLineNum, 2);

+  mFormSetGuid.Data4[0] = (UINT8)GetNumber (G4, TokenLineNum, 1);

+  mFormSetGuid.Data4[1] = (UINT8)GetNumber (G5, TokenLineNum, 1);

+  mFormSetGuid.Data4[2] = (UINT8)GetNumber (G6, TokenLineNum, 1);

+  mFormSetGuid.Data4[3] = (UINT8)GetNumber (G7, TokenLineNum, 1);

+  mFormSetGuid.Data4[4] = (UINT8)GetNumber (G8, TokenLineNum, 1);

+  mFormSetGuid.Data4[5] = (UINT8)GetNumber (G9, TokenLineNum, 1);

+  mFormSetGuid.Data4[6] = (UINT8)GetNumber (G10, TokenLineNum, 1);

+  mFormSetGuid.Data4[7] = (UINT8)GetNumber (G11, TokenLineNum, 1);

+  

+  WriteDWord (mFormSetGuid.Data1, 'G');

+  WriteWord (mFormSetGuid.Data2);

+  WriteWord (mFormSetGuid.Data3);

+  WriteByte (mFormSetGuid.Data4[0], 0);

+  WriteByte (mFormSetGuid.Data4[1], 0);

+  WriteByte (mFormSetGuid.Data4[2], 0);

+  WriteByte (mFormSetGuid.Data4[3], 0);

+  WriteByte (mFormSetGuid.Data4[4], 0);

+  WriteByte (mFormSetGuid.Data4[5], 0);

+  WriteByte (mFormSetGuid.Data4[6], 0);

+  WriteByte (mFormSetGuid.Data4[7], 0);

+}

+VOID 

+EfiVfrParser::WriteFieldOffset (

+  INT8    WriteLength,

+  CHAR8   *StructName, 

+  INT32   LineNum1, 

+  CHAR8   *FieldName, 

+  INT32   LineNum2,

+  INT32   ArrayIndex,

+  INT8    IsArrayIndex,

+  INT32   FieldWidth,

+  INT8    WriteArraySize

+  ) 

+/*++

+

+Routine Description:

+  A VFR script referenced the NV store structure. Given the structure's name

+  and the field's name, write the offset of the field to the output file.

+

+Arguments:

+  WriteLength     - write the field length byte out

+  StructName      - name of the NV store structure

+  LineNum1        - line number in the VFR where we are (for error printing)

+  FieldName       - the name of the field within the NV store structure

+  LineNum2        - line number in the VFR where FieldName is referenced 

+  ArrayIndex      - the index specified, for example NV_DATA.Field[ArrayIndex]

+  IsArrayIndex    - non-zero if an array index was specified

+  FieldWidth      - expected size for the Field (1 byte? 2 bytes?)

+  WriteArraySize  - write the size of the entire field, not the size of a single element

+

+Returns:

+  None.

+

+--*/

+{

+  STRUCT_DEFINITION         *StructDef;

+  STRUCT_FIELD_DEFINITION   *FieldDef;

+  UINT32                    Offset;

+  UINT32                    VarSize;

+  CHAR8                     Msg[100];

+  //

+  // If we're writing an array size, then they better have referenced the field without an

+  // index. 

+  //

+  if (WriteArraySize && IsArrayIndex) {

+    sprintf (Msg, "array index specified where an array is required");

+    PrintErrorMessage (LineNum2, FieldName, Msg);

+    return;

+  }

+  //

+  // Look through our list of known structures for a match

+  //

+  for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {

+    //

+    // Check for matching structure name

+    //

+    if (strcmp (StructDef->Name, StructName) == 0) {

+      //

+      // Mark it as referenced (for debug purposes only). Check the

+      // flag that indicates that we have already found a varstore VFR

+      // statement for it.

+      //

+      StructDef->Referenced++;

+      if (StructDef->VarStoreIdValid == 0) {

+        //

+        // Set it valid so we don't flag it multiple times, then emit the error

+        //

+        StructDef->VarStoreIdValid = 1;

+        PrintErrorMessage (LineNum1, StructName, "varstore statement missing for this variable store");

+      }

+      //

+      // Let the opcode-handler know which variable storage we're now using

+      //

+      if (mIdEqIdStmt) {

+        mOpcodeHandler.SetSecondaryVarStoreId (StructDef->VarStoreId);

+      } else {

+        mOpcodeHandler.SetVarStoreId (StructDef->VarStoreId);

+      }

+      //

+      // Found matching structure name. Now find the matching field name

+      //

+      for (FieldDef = StructDef->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {

+        if (strcmp (FieldDef->Name, FieldName) == 0) {

+          //

+          // Make sure the variable size is valid

+          //

+          if ((FieldWidth != 0) && (FieldDef->DataSize > FieldWidth)) {

+            sprintf (Msg, "field width exceeds %d byte%c", FieldWidth, FieldWidth == 1 ? ' ' : 's');

+            PrintErrorMessage (LineNum2, FieldName, Msg);

+          }

+          //

+          // If they specified an index (MyVfrData.FieldX[10]), then make sure that the

+          // data structure was declared as an array, and that the index is in bounds.

+          // If they did not specify an index, then we'll assume 0. This is required for

+          // strings.

+          //

+          if (IsArrayIndex) {

+            VarSize = FieldDef->DataSize;

+            if (FieldDef->IsArray == 0) {

+              PrintErrorMessage (LineNum2, FieldName, "field is not declared as an array");

+              return;

+            }

+            if (FieldDef->ArrayLength < ArrayIndex) {

+              PrintErrorMessage (LineNum2, FieldName, "array index exceeds declared size of field");

+              return;

+            }

+          } else {

+            if (FieldDef->IsArray) {

+              VarSize = FieldDef->DataSize * FieldDef->ArrayLength;

+            } else {

+              VarSize = FieldDef->DataSize;

+            }

+          }

+          //

+          // If we're in the middle of a ideqid VFR statement, then this is the second

+          // variable ID that we're now processing. Make sure that its size is the same

+          // as the first variable.

+          // 

+          if (mIdEqIdStmt) {

+            if (mLastVarIdSize != VarSize) {

+              PrintErrorMessage (LineNum2, FieldName, "variables must have the same size");

+              return;

+            }

+          }

+          mLastVarIdSize = VarSize;

+          //

+          // If we're supposed to write an array size, then require it to be an array

+          //

+          if (WriteArraySize && !FieldDef->IsArray) {

+            PrintErrorMessage (LineNum2, FieldName, "array required");

+            return;

+          }

+          //

+          // Write the variable offset and size. If we're in the non-NV structure, then

+          // set the offset beyond the NV data structure size.

+          //

+          Offset = FieldDef->Offset + FieldDef->DataSize * (ArrayIndex - 1);

+          if (StructDef->IsNonNV) Offset += mNvDataStructSize; 

+          WriteWord (Offset);

+          if (WriteLength) {

+            if (WriteArraySize) {

+              if (FieldDef->DataSize * FieldDef->ArrayLength > 255) {

+                PrintErrorMessage (LineNum2, FieldName, "array size exceeds 255 maximum encoding limit");

+                return;

+              }

+              WriteByte (FieldDef->DataSize * FieldDef->ArrayLength, 0);

+            } else {

+              WriteByte (FieldDef->DataSize, 0);

+            }

+          }

+          return;

+        }

+      }

+      sprintf (Msg, "structure %s does not have a field named '%s'", StructName, FieldName);

+      PrintErrorMessage (LineNum2, Msg, NULL);

+      PrintErrorMessage (StructDef->LineNum, "see structure definition", NULL);

+      return;

+    }

+  }

+  //

+  // The structure was not found in the defined list. See if it's the "Date" structure

+  //

+  if (strcmp (StructName, "Date") == 0) {

+    //

+    // BUGBUG -- remove support for Date and Time as valid structure 

+    // names. They should use the NON_NV_DATA_MAP structure for this.

+    //

+    // Someone specified Date.Years|Months|Days

+    // BUGBUG -- define some constants for the IDs used here

+    // Length == 0 implies that this is not user NV data storage.

+    //

+    if (strcmp (FieldName, "Year") == 0) {

+      //

+      // Write ID (offset), ID, and size

+      //

+      WriteWord (mNvDataStructSize + mNonNvDataStructSize + 0);

+      if (WriteLength) {

+        WriteByte (0, 0);

+      }

+    } else if (strcmp (FieldName, "Month") == 0) {

+      //

+      // Write ID (offset), ID, and size

+      //

+      WriteWord (mNvDataStructSize + mNonNvDataStructSize + 2);

+      if (WriteLength) {

+        WriteByte (0, 0);

+      }

+    } else if (strcmp (FieldName, "Day") == 0) {

+      //

+      // Write ID (offset), ID, and size

+      //

+      WriteWord (mNvDataStructSize + mNonNvDataStructSize + 4);

+      if (WriteLength) {

+        WriteByte (0, 0);

+      }

+    } else {

+      PrintErrorMessage (LineNum1, FieldName, "expected valid field name TheYear/TheMonth/TheDay");

+    }

+    return;

+  } else if (strcmp (StructName, "Time") == 0) {

+    //

+    // Someone specified Time.Hours|Minutes|Seconds

+    // BUGBUG -- define some constants for the IDs used here

+    //

+    if (strcmp (FieldName, "Hours") == 0) {

+      //

+      // Write ID (offset), ID, and size

+      //

+      WriteWord (mNvDataStructSize + mNonNvDataStructSize + 6);

+      if (WriteLength) {

+        WriteByte (0, 0);

+      }

+    } else if (strcmp (FieldName, "Minutes") == 0) {

+      //

+      // Write ID (offset), ID, and size

+      //

+      WriteWord (mNvDataStructSize + mNonNvDataStructSize + 8);

+      if (WriteLength) {

+        WriteByte (0, 0);

+      }

+    } else if (strcmp (FieldName, "Seconds") == 0) {

+      //

+      // Write ID (offset), ID, and size

+      //

+      WriteWord (mNvDataStructSize + mNonNvDataStructSize + 10);

+      if (WriteLength) {

+        WriteByte (0, 0);

+      }

+    } else {

+      PrintErrorMessage (LineNum1, FieldName, "expected valid field name Hours/Minutes/Seconds");

+    }

+    return;

+  } else {

+    PrintErrorMessage (LineNum1, StructName, "undefined structure");

+    return;

+  }

+}

+VOID

+EfiVfrParser::StartStructDefinition (

+  INT32  IsNonNV,

+  INT32  LineNum

+  )

+/*++

+

+Routine Description:

+  Called when we encounter a new "struct _MY_STRUCT..." statement while parsing. 

+  Initialize internal data and structures for parsing the fields of the structure.

+

+Arguments:

+  LineNum  - line number in the source file (for error reporting purposes)

+  IsNonNv  - flag indicating (if nonzero) that the variable referred to is not in

+             the standard NV store.

+Returns:

+  None

+

+--*/

+{

+  STRUCT_DEFINITION *StructDef;

+  //

+  // Allocate memory for the structure record

+  //

+  StructDef = (STRUCT_DEFINITION *)malloc (sizeof (STRUCT_DEFINITION));

+  memset (StructDef, 0, sizeof (STRUCT_DEFINITION));

+  StructDef->LineNum = LineNum;

+  //

+  // Set flag indicating non-NV data structure or not

+  //

+  StructDef->IsNonNV = IsNonNV;

+  //

+  // Add it to the end of our linked list. If it's the first one

+  // defined, then it's the default varstore ID, so set it valid.

+  //

+  if (mFirstStructDefinition == NULL) {

+    mFirstStructDefinition = StructDef;

+    StructDef->VarStoreIdValid = 1;

+  } else {

+    mLastStructDefinition->Next = StructDef;

+  }

+  mLastStructDefinition = StructDef;

+}

+VOID

+EfiVfrParser::EndStructDefinition (

+  CHAR8  *StructName,

+  INT32  LineNum

+  )

+{

+  STRUCT_DEFINITION         *StructDef;

+  STRUCT_FIELD_DEFINITION   *FieldDef;

+  UINT32                    Offset;

+  //

+  // Make sure they have not already defined a structure with this name

+  //

+  for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {

+    if ((StructDef->Name != NULL) && (strcmp (StructDef->Name, StructName) == 0)) {

+      PrintErrorMessage (LineNum, StructName, "structure with this name already defined");

+      //

+      // Fall through and fill in the rest of the structure information. We do

+      // this because the structure has already been added to our global list,

+      // so will be used elsewhere, so we want it to contain valid fields.

+      //

+    }

+  }    

+  //

+  // Allocate memory for the structure name 

+  //

+  mLastStructDefinition->Name = (char *)malloc (strlen (StructName) + 1);

+  strcpy (mLastStructDefinition->Name, StructName);

+  //

+  // Compute the structure size, and the offsets to each field

+  //

+  Offset = 0;

+  for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {

+    FieldDef->Offset = Offset;

+    Offset += FieldDef->ArrayLength * FieldDef->DataSize;

+  }

+  mLastStructDefinition->Size = Offset;

+  //

+  // Go through all the structure we have so far and figure out (if we can)

+  // the size of the non-NV storage. We also assume that the first structure

+  // definition is the primary/default storage for the VFR form.

+  //

+  if (mNonNvDataStructSize == 0) {

+    for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {

+      if (StructDef->IsNonNV) {

+        mNonNvDataStructSize = StructDef->Size;

+        break;

+      }

+    }

+  }

+  if (mNvDataStructSize == 0) {

+    for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {

+      if (StructDef->IsNonNV == 0) {

+        mNvDataStructSize = StructDef->Size;

+        break;

+      }

+    }

+  }

+}

+VOID 

+EfiVfrParser::AddStructField (

+  CHAR8   *FieldName, 

+  INT32   LineNum, 

+  INT32   DataSize,

+  INT32   ArrayLength,

+  INT8    IsArray

+  ) 

+/*++

+

+Routine Description:

+  We're parsing the VFR structure definition. Add another defined field to 

+  our definition.

+

+Arguments:

+  FieldName   - name of the field in the structure.

+  LineNum     - the line number from the input (preprocessor output) file

+  DataSize    - the size of the field (1, 2, or 4 bytes)

+  ArrayLength - the number of elements (for array)

+  IsArray     - non-zero if the field is an array

+

+Returns:

+  None.

+

+--*/

+{

+  STRUCT_FIELD_DEFINITION *FieldDef;

+  STRUCT_FIELD_DEFINITION *Temp;

+  //

+  // Make sure we don't already have a field of this name in our structure

+  //

+  for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) {

+    if (strcmp (FieldDef->Name, FieldName) == 0) {

+      PrintErrorMessage (LineNum, FieldName, "field with this name already defined");

+      return;

+    }

+  } 

+  //

+  // If it's an array, then they better not have a size of 0. For example:

+  //   UINT8 MyBytes[0];

+  //

+  if (IsArray && (ArrayLength <= 0)) {

+    PrintErrorMessage (LineNum, FieldName, "invalid array size");

+    return;

+  }    

+  //

+  // Allocate memory for a new structure field definition

+  //    

+  FieldDef = (STRUCT_FIELD_DEFINITION *)malloc (sizeof (STRUCT_FIELD_DEFINITION));

+  memset ((char *)FieldDef, 0, sizeof (STRUCT_FIELD_DEFINITION));

+  FieldDef->ArrayLength  = ArrayLength;

+  FieldDef->DataSize     = DataSize;

+  FieldDef->IsArray      = IsArray;

+  FieldDef->Name = (char *)malloc (strlen (FieldName) + 1);

+  strcpy (FieldDef->Name, FieldName);

+  //

+  // Add it to the end of the field list for the currently active structure

+  //

+  if (mLastStructDefinition->Field == NULL) {

+    mLastStructDefinition->Field = FieldDef;

+  } else {

+    mLastStructDefinition->LastField->Next = FieldDef;

+  }

+  mLastStructDefinition->LastField = FieldDef;

+}

+VOID

+EfiVfrParser::AddVarStore (

+  CHAR8  *StructName,       // actual name of the structure

+  CHAR8  *VarName,          // actual NV variable name

+  UINT16 VarStoreId,        // key value

+  INT32  LineNum            // parse line number (for error reporting)

+  )

+/*++

+

+Routine Description:

+  Called while parsing a varstore statement. Add the variable store 

+  to our linked list.

+

+Arguments:

+  StructName    - the name of the typedef'ed structure to use

+  VarName       - the NV variable name as specified in the varstore statement

+  VarStoreId    - the variable store ID as specified in the varstore statememt

+  LineNum       - the line number from the input (preprocessor output) file

+

+Returns:

+  None.

+

+--*/

+{

+  STRUCT_DEFINITION *StructDef;

+  UINT16_LIST       *L16Ptr;

+  //

+  // Go through our list of previously-defined variable store IDs and

+  // make sure this one is not a duplicate in name or key value.

+  //

+  for (L16Ptr = mDefinedVarStoreId; L16Ptr != NULL; L16Ptr = L16Ptr->Next) {

+    if (L16Ptr->Value == VarStoreId) {

+      PrintErrorMessage (LineNum, "variable storage key already used", NULL);

+      PrintErrorMessage (L16Ptr->LineNum, "previous usage of storage key", NULL);

+    }

+  }

+  // 

+  // Key value of 0 is invalid since that's assigned by default to the default

+  // variable store (the first structure parsed).

+  //

+  if (VarStoreId == 0) {

+    PrintErrorMessage (LineNum, "variable storage key of 0 is invalid", NULL);

+  }

+  //

+  // Create a new element to add to the list

+  //

+  L16Ptr = (UINT16_LIST *)malloc(sizeof (UINT16_LIST));

+  memset (L16Ptr, 0, sizeof (UINT16_LIST));

+  L16Ptr->LineNum = LineNum;

+  L16Ptr->Value = VarStoreId;

+  if (mDefinedVarStoreId == NULL) {

+    mDefinedVarStoreId = L16Ptr;

+  } else {

+    mLastDefinedVarStoreId->Next = L16Ptr;

+  }

+  mLastDefinedVarStoreId = L16Ptr;

+  //

+  // Find the structure definition with this name

+  //

+  for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) {

+    if (strcmp (StructDef->Name, StructName) == 0) {

+      //

+      // Make sure they did not already define a variable storage ID 

+      // for this structure.

+      //

+      if (StructDef->VarStoreId != 0) {

+        PrintErrorMessage (LineNum, StructName, "variable storage already defined for this structure");

+        PrintErrorMessage (StructDef->VarStoreLineNum, StructName, "previous definition for variable storage");

+      }

+      StructDef->VarStoreId       = VarStoreId;

+      StructDef->VarStoreIdValid  = 1;

+      StructDef->VarStoreLineNum  = LineNum;

+      WriteWord (StructDef->Size);

+      while (*VarName) {

+        WriteByte(*VarName, 0);

+        VarName++;

+      }

+      WriteByte(0,0);

+      return;

+    }

+  }    

+  PrintErrorMessage (LineNum, StructName, "structure with this name not defined");

+}

+VOID 

+EfiVfrParser::WriteDWord (

+  UINT32    Value, 

+  UINT8     KeyByte

+  )

+/*++

+

+Routine Description:

+  During parsing, we came upon some code that requires a 32-bit value be

+  written to the VFR binary file. Queue up the 4 bytes.

+

+Arguments:

+  Value   - the 32-bit value to write

+  KeyByte - a single character which gets written out beside the first byte.

+            This is used to tag the data in the output file so that during 

+            debug you have an idea what the value is.

+

+Returns:

+  None.

+

+--*/

+{

+  //

+  // Write 4 bytes, little endian. Specify a key byte only on the first one

+  //

+  mOpcodeHandler.AddByte ((UINT8)Value, KeyByte);

+  Value \>>= 8;

+  mOpcodeHandler.AddByte ((UINT8)Value, 0);

+  Value \>>= 8;

+  mOpcodeHandler.AddByte ((UINT8)Value, 0);

+  Value \>>= 8;

+  mOpcodeHandler.AddByte ((UINT8)Value, 0);

+}

+VOID 

+EfiVfrParser::WriteOpByte (

+  UINT32    LineNum,

+  UINT8     ByteValue

+  )

+/*++

+

+Routine Description:

+  

+  During parsing, we came upon a new VFR opcode. At this point we flush

+  the output queue and then queue up this byte (with 'O' for opcode tag).

+

+Arguments:

+

+  ByteValue   - opcode value

+

+Returns:

+

+  None.

+

+--*/

+{

+  mOpcodeHandler.AddOpcodeByte (ByteValue, LineNum);

+}

+VOID 

+EfiVfrParser::WriteByte (

+  UINT8   ByteValue, 

+  UINT8   Key

+  )

+/*++

+

+Routine Description:

+  

+  During parsing of the VFR we spoonfeed this function with bytes to write to

+  the output VFR binary file. This function simply queues up the bytes, and

+  the queue gets flushed each time a new VFR opcode is encountered.

+

+Arguments:

+

+  ByteValue   - raw byte to write

+  Key         - character to tag the byte with when we write ByteValue to the

+                output file.

+

+Returns:

+

+  None.

+

+--*/

+{

+  mOpcodeHandler.AddByte (ByteValue, Key);

+}

+VOID 

+EfiVfrParser::WriteWord (

+  UINT32  Value

+  )

+/*++

+

+Routine Description:

+  During VFR parsing we came upon a case where we need to write out a 

+  16-bit value. Queue it up.

+

+Arguments:

+  Value - value to write.

+

+Returns:

+  None.

+

+--*/

+{

+  mOpcodeHandler.AddByte ((UINT8)Value, 0);

+  mOpcodeHandler.AddByte ((UINT8)((Value \>> 8) & 0xFF), 0);

+}

+VOID 

+EfiVfrParser::WriteStringIdWord (

+  UINT16 WordValue

+  )

+{

+  mOpcodeHandler.AddByte ((UINT8)WordValue, 'S');

+  mOpcodeHandler.AddByte ((UINT8)((WordValue \>> 8) & 0xFF), 0);

+}

+VOID

+EfiVfrParser::FreeGotoReferences ()

+/*++

+

+Routine Description:

+  Called during cleanup to free up the memory we allocated when

+  keeping track of VFR goto statements.

+

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{

+  GOTO_REFERENCE  *CurrRef;

+  GOTO_REFERENCE  *NextRef;

+  FORM_ID_VALUE   *CurrFormId;

+  FORM_ID_VALUE   *NextFormId;

+  UINT8           Found;

+  CHAR8           Name[20];

+

+  //

+  // Go through all the "goto" references and make sure there was a 

+  // form ID of that value defined.

+  //

+  for (CurrRef = mGotoReferences; CurrRef != NULL; CurrRef = CurrRef->Next) {

+    Found = 0;

+    for (CurrFormId = mFormIdValues; CurrFormId != NULL; CurrFormId = CurrFormId->Next) {

+      if (CurrRef->Value == CurrFormId->Value) {

+        Found = 1;

+        break;

+      }

+    }

+    if (!Found) {

+      sprintf (Name, "%d", (UINT32)CurrRef->Value);

+      PrintErrorMessage (CurrRef->RefLineNum, Name, "undefined form ID");

+    }  

+  }  

+  //

+  // Now free up the form id and goto references

+  //

+  CurrFormId = mFormIdValues;

+  while (CurrFormId != NULL) {

+    NextFormId = CurrFormId->Next;

+    free (CurrFormId);

+    CurrFormId = NextFormId;

+  }

+  mFormIdValues = NULL;

+  CurrRef = mGotoReferences;

+  while (CurrRef != NULL) {

+    NextRef = CurrRef->Next;

+    free (CurrRef);

+    CurrRef = NextRef;

+  }  

+  mGotoReferences = NULL;

+}

+VOID

+EfiVfrParser::AddGotoReference (

+  UINT32  GotoNumber,

+  UINT32  LineNum

+  )

+/*++

+

+Routine Description:

+  During VFR parsing we came upon a goto statement. Since we support

+  forward references, save the referenced label and at the end of parsing

+  we'll check that the label was actually defined somewhere.

+

+Arguments:

+  GotoNumber  - the label number referenced

+  LineNum     - the line number where the reference was made (used for

+                error reporting)

+

+Returns:

+  None

+

+--*/

+{

+  GOTO_REFERENCE *NewRef;

+  

+  NewRef = (GOTO_REFERENCE *)malloc (sizeof (GOTO_REFERENCE));

+  if (NewRef == NULL) {

+    Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+    return;

+  }

+  memset ((char *)NewRef, 0, sizeof (GOTO_REFERENCE));

+  NewRef->Value = (UINT16)GotoNumber;

+  NewRef->RefLineNum = LineNum;

+  NewRef->Next = mGotoReferences;

+  mGotoReferences = NewRef;

+}

+VOID

+EfiVfrParser::AddFormId (

+  INT32   FormIdValue,

+  UINT32  LineNum

+  )

+/*++

+

+Routine Description:

+  This function is called when we parse "form formid = 3" statements.

+  We save the form ID valud so we can verify that duplicates are not

+  defined. Also, these are the targets of goto statements, so when we're

+  done parsing the script we also go through all the goto statements to

+  check that there was a target FormId defined as referenced by each

+  goto statement.

+  

+  Note that formid = 0 is invalid.

+

+Arguments:

+  FormIdValue  - the parsed value for the Form ID

+  LineNum      - line number of the source file we're parsing

+

+Returns:

+  NA

+

+--*/

+{

+  FORM_ID_VALUE *NewFormId;

+  char          *FileName;

+  char          *FileName2;

+  UINT32        LineNum2;  

+  //

+  // Verify that FormId != 0

+  //

+  if (FormIdValue == 0) {

+    FileName = ConvertLineNumber (&LineNum);

+    Error (FileName, LineNum, 0, "form ID cannot be 0", NULL);

+    return;

+  }

+  //

+  // First go through all previously defined form IDs and make sure they have not defined

+  // duplicates.

+  //

+  for (NewFormId = mFormIdValues; NewFormId != NULL; NewFormId = NewFormId->Next) {

+    if ((UINT16)FormIdValue == NewFormId->Value) {

+      FileName = ConvertLineNumber (&LineNum);

+      LineNum2 = NewFormId->LineNum;

+      FileName2 = ConvertLineNumber (&LineNum2);

+      Error (FileName, LineNum, 0, NULL, "form ID %d already defined", FormIdValue);

+      Error (FileName2, LineNum2, 0, NULL, "form ID %d previous definition", FormIdValue);

+      return;

+    }

+  }

+  //

+  // Allocate memory for a new one 

+  //

+  NewFormId = (FORM_ID_VALUE *)malloc (sizeof (FORM_ID_VALUE));

+  if (NewFormId == NULL) {

+    Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure");

+    return;

+  }

+  memset ((char *)NewFormId, 0, sizeof (FORM_ID_VALUE));

+  NewFormId->LineNum = LineNum;

+  NewFormId->Next = mFormIdValues;

+  NewFormId->Value = (UINT16)FormIdValue;

+  mFormIdValues = NewFormId;

+}

+UINT32

+EfiVfrParser::GetNumber (

+  CHAR8   *NumStr,

+  UINT32  LineNum,

+  UINT32  NumBytes

+  )

+{

+  UINT32 Value;

+  

+  if ((NumStr[0] == '0') && (NumStr[1] == 'x')) {

+    AtoX (NumStr + 2, 4, &Value);

+  } else {

+    Value = (UINT32)atoi (NumStr);

+  }

+  //

+  // Check range

+  //

+  if ((NumBytes < 4) && (Value & ((UINT32)0xFFFFFFFF << (NumBytes * 8)))) {

+    PrintErrorMessage (LineNum, NumStr, "value out of range");

+    return 0;

+  }

+  return Value;

+}

+

+>>

+

+} // end grammar class

+

diff --git a/edk2/Tools/Source/TianoTools/VfrCompile/VfrServices.cpp b/edk2/Tools/Source/TianoTools/VfrCompile/VfrServices.cpp
new file mode 100644
index 0000000..c66d4df
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/VfrCompile/VfrServices.cpp
@@ -0,0 +1,757 @@
+/*++

+

+Copyright (c) 2004 - 2005, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  VfrServices.cpp

+

+Abstract:

+

+  Support routines for the VFR compiler

+  

+--*/  

+

+#include <stdio.h>    // for FILE routines

+#include <stdlib.h>   // for malloc() and free()

+

+#include <Base.h>

+#include <UefiBaseTypes.h>

+#include <MultiPhase.h>

+#include "EfiUtilityMsgs.h"

+#include "EfiVfr.h"

+#include "VfrServices.h"

+

+#include <UgaDraw.h>

+#include <Hii.h>

+

+static const char *mSourceFileHeader[] = {

+  "//",

+  "//  DO NOT EDIT -- auto-generated file",

+  "//",

+  "//  This file is generated by the VFR compiler.",

+  "//",

+  NULL

+};

+

+typedef struct {

+   CHAR8    *Name;

+   INT32    Size;

+} IFR_OPCODE_SIZES;

+

+//

+// Create a table that can be used to do internal checking on the IFR

+// bytes we emit.

+//

+static const IFR_OPCODE_SIZES mOpcodeSizes[] = {

+  { 0, 0 },     // invalid

+  { "EFI_IFR_FORM",                       sizeof (EFI_IFR_FORM) },

+  { "EFI_IFR_SUBTITLE",                   sizeof (EFI_IFR_SUBTITLE) }, 

+  { "EFI_IFR_TEXT",                       -6 }, //sizeof (EFI_IFR_TEXT) }, 

+  { "unused 0x04 opcode",                 0 }, // EFI_IFR_GRAPHIC_OP

+  { "EFI_IFR_ONE_OF",                     sizeof (EFI_IFR_ONE_OF) }, 

+  { "EFI_IFR_CHECKBOX",                   sizeof (EFI_IFR_CHECKBOX) }, 

+  { "EFI_IFR_NUMERIC",                    sizeof (EFI_IFR_NUMERIC) }, 

+  { "EFI_IFR_PASSWORD",                   sizeof (EFI_IFR_PASSWORD) }, 

+  { "EFI_IFR_ONE_OF_OPTION",              sizeof (EFI_IFR_ONE_OF_OPTION) }, 

+  { "EFI_IFR_SUPPRESS",                   sizeof (EFI_IFR_SUPPRESS) }, 

+  { "EFI_IFR_END_FORM",                   sizeof (EFI_IFR_END_FORM) }, 

+  { "EFI_IFR_HIDDEN",                     sizeof (EFI_IFR_HIDDEN) }, 

+  { "EFI_IFR_END_FORM_SET",               sizeof (EFI_IFR_END_FORM_SET) }, 

+  { "EFI_IFR_FORM_SET",                   sizeof (EFI_IFR_FORM_SET) }, 

+  { "EFI_IFR_REF",                        sizeof (EFI_IFR_REF) }, 

+  { "EFI_IFR_END_ONE_OF",                 sizeof (EFI_IFR_END_ONE_OF) }, 

+  { "EFI_IFR_INCONSISTENT",               sizeof (EFI_IFR_INCONSISTENT) }, 

+  { "EFI_IFR_EQ_ID_VAL",                  sizeof (EFI_IFR_EQ_ID_VAL) }, 

+  { "EFI_IFR_EQ_ID_ID",                   sizeof (EFI_IFR_EQ_ID_ID) }, 

+  { "EFI_IFR_EQ_ID_LIST",                 -sizeof (EFI_IFR_EQ_ID_LIST) }, 

+  { "EFI_IFR_AND",                        sizeof (EFI_IFR_AND) }, 

+  { "EFI_IFR_OR",                         sizeof (EFI_IFR_OR) }, 

+  { "EFI_IFR_NOT",                        sizeof (EFI_IFR_NOT) }, 

+  { "EFI_IFR_END_EXPR",                   sizeof (EFI_IFR_END_EXPR) }, 

+  { "EFI_IFR_GRAY_OUT",                   sizeof (EFI_IFR_GRAY_OUT) }, 

+  { "EFI_IFR_DATE",                       sizeof (EFI_IFR_DATE) / 3 }, 

+  { "EFI_IFR_TIME",                       sizeof (EFI_IFR_TIME) / 3 }, 

+  { "EFI_IFR_STRING",                     sizeof (EFI_IFR_STRING) }, 

+  { "EFI_IFR_LABEL",                      sizeof (EFI_IFR_LABEL) }, 

+  { "EFI_IFR_SAVE_DEFAULTS",              sizeof (EFI_IFR_SAVE_DEFAULTS) }, 

+  { "EFI_IFR_RESTORE_DEFAULTS",           sizeof (EFI_IFR_RESTORE_DEFAULTS) }, 

+  { "EFI_IFR_BANNER",                     sizeof (EFI_IFR_BANNER) },

+  { "EFI_IFR_INVENTORY",                  sizeof (EFI_IFR_INVENTORY) },

+  { "EFI_IFR_EQ_VAR_VAL_OP",              sizeof (EFI_IFR_EQ_VAR_VAL) },

+  { "EFI_IFR_ORDERED_LIST_OP",            sizeof (EFI_IFR_ORDERED_LIST) },

+  { "EFI_IFR_VARSTORE_OP",                -sizeof (EFI_IFR_VARSTORE) },

+  { "EFI_IFR_VARSTORE_SELECT_OP",         sizeof (EFI_IFR_VARSTORE_SELECT) },

+  { "EFI_IFR_VARSTORE_SELECT_PAIR_OP",    sizeof (EFI_IFR_VARSTORE_SELECT_PAIR) },

+  { "EFI_IFR_TRUE",                       sizeof (EFI_IFR_TRUE)},

+  { "EFI_IFR_FALSE",                      sizeof (EFI_IFR_FALSE)},

+  { "EFI_IFR_GT",                         sizeof (EFI_IFR_GT)},

+  { "EFI_IFR_GE",                         sizeof (EFI_IFR_GE)},

+  { "EFI_IFR_OEM_DEFINED_OP",             -2 },

+};

+

+

+VfrOpcodeHandler::VfrOpcodeHandler (

+  ) 

+/*++

+

+Routine Description:

+  Constructor for the VFR opcode handling class.

+  

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{ 

+  mIfrBytes                       = NULL; 

+  mLastIfrByte                    = NULL;

+  mBytesWritten                   = 0;

+  mQueuedByteCount                = 0;

+  mQueuedOpcodeByteValid          = 0;

+  mPrimaryVarStoreId              = 0;

+  mSecondaryVarStoreId            = 0;

+  mSecondaryVarStoreIdSet         = 0;

+  mPrimaryVarStoreIdSet           = 0;

+  mDefaultVarStoreId              = 0;

+}

+

+VOID 

+VfrOpcodeHandler::SetVarStoreId (

+  UINT16 VarStoreId

+  )

+/*++

+

+Routine Description:

+  This function is invoked by the parser when a variable is referenced in the 

+  VFR. Save the variable store (and set a flag) so that we can later determine 

+  if we need to emit a varstore-select or varstore-select-pair opcode.

+  

+Arguments:

+  VarStoreId - ID of the variable store referenced in the VFR

+

+Returns:

+  None

+

+--*/

+{

+  mPrimaryVarStoreId    = VarStoreId;

+  mPrimaryVarStoreIdSet = 1;

+}

+

+VOID 

+VfrOpcodeHandler::SetSecondaryVarStoreId (

+  UINT16 VarStoreId

+  )

+/*++

+

+Routine Description:

+  This function is invoked by the parser when a secondary variable is 

+  referenced in the VFR. Save the variable store (and set a flag) so 

+  that we can later determine if we need to emit a varstore-select or 

+  varstore-pair opcode.

+  

+Arguments:

+  VarStoreId - ID of the variable store referenced in the VFR

+

+Returns:

+  None

+

+--*/

+{

+  mSecondaryVarStoreId    = VarStoreId;

+  mSecondaryVarStoreIdSet = 1;

+}

+

+VOID 

+VfrOpcodeHandler::WriteIfrBytes (

+  ) 

+/*++

+

+Routine Description:

+  This function is invoked at the end of parsing. Its purpose

+  is to write out all the IFR bytes that were queued up while

+  parsing.

+  

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{ 

+  IFR_BYTE                  *Curr;

+  IFR_BYTE                  *Next;

+  UINT32                    Count;

+  UINT32                    LineCount;

+  UINT32                    PoundLines;

+  UINT32                    ByteCount;

+  CHAR8                     Line[MAX_LINE_LEN];

+  CHAR8                     *Cptr;

+  FILE                      *InFptr;

+  FILE                      *OutFptr;

+  UINT32                    ListFile;

+  EFI_HII_IFR_PACK_HEADER   IfrHeader;

+  UINT8                     *Ptr;

+  FILE                      *IfrBinFptr;

+  UINT32                    BytesLeftThisOpcode;

+  //

+  // If someone added a new opcode and didn't update our opcode sizes structure, error out.

+  //

+  if (sizeof(mOpcodeSizes) / sizeof (mOpcodeSizes[0]) != EFI_IFR_LAST_OPCODE + 1) {

+    Error (__FILE__, __LINE__, 0, "application error", "internal IFR binary table size is incorrect");

+    return;

+  }

+  //

+  // Flush the queue

+  //

+  FlushQueue ();    

+  //

+  // If there have been any errors to this point, then skip dumping the IFR

+  // binary data. This way doing an nmake again will try to build it again, and

+  // the build will fail if they did not fix the problem.

+  //

+  if (GetUtilityStatus () != STATUS_ERROR) {

+    if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "w")) == NULL) {

+      Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing");

+      return;

+    }

+    //

+    // Write the standard file header to the output file

+    //

+    WriteStandardFileHeader (IfrBinFptr);

+    //

+    // Write the structure header

+    //

+    fprintf (IfrBinFptr, "\nunsigned char %sBin[] = {", gOptions.VfrBaseFileName);

+    //

+    // Write the header

+    //

+    memset ((char *)&IfrHeader, 0, sizeof (IfrHeader));

+    IfrHeader.Header.Type = EFI_HII_IFR;

+    IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader);    

+    Ptr = (UINT8 *)&IfrHeader;

+    for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) {

+      if ((Count & 0x03) == 0) {

+        fprintf (IfrBinFptr, "\n  ");

+      }

+      fprintf (IfrBinFptr, "0x%02X, ", *Ptr);      

+    }

+    //

+    //

+    // Write all the IFR bytes

+    //

+    fprintf (IfrBinFptr, "\n  // start of IFR data");

+    Curr = mIfrBytes;

+    Count = 0;

+    while (Curr != NULL) {

+      if ((Count & 0x0F) == 0) {

+        fprintf (IfrBinFptr, "\n  ");

+      }

+      if (Curr->KeyByte != 0) {

+        fprintf (IfrBinFptr, "/*%c*/ ", Curr->KeyByte);

+      }

+      fprintf (IfrBinFptr, "0x%02X, ", Curr->OpcodeByte);

+      Count++;

+      Curr = Curr->Next;

+    }

+    fprintf (IfrBinFptr, "\n};\n\n");

+    //

+    //

+    // Close the file

+    //

+    fclose (IfrBinFptr); 

+    IfrBinFptr = NULL;

+  }

+  //

+  // Write the bytes as binary data if the user specified to do so

+  //

+  if ((GetUtilityStatus () != STATUS_ERROR) &&  (gOptions.CreateIfrBinFile != 0)) {

+    //

+    // Use the Ifr output file name with a ".hpk" extension.

+    //

+    for (Cptr = gOptions.IfrOutputFileName + strlen (gOptions.IfrOutputFileName) - 1;

+         (*Cptr != '.') && (Cptr > gOptions.IfrOutputFileName) && (*Cptr != '\\');

+         Cptr--) {

+      //

+      // do nothing

+      //

+    }

+    if (*Cptr == '.') {

+      strcpy (Cptr, ".hpk");

+    } else {

+      strcat (gOptions.IfrOutputFileName, ".hpk");

+    }

+    if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "wb")) == NULL) {

+      Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing");

+      return;

+    }

+    //

+    // Write the structure header

+    //

+    memset ((char *)&IfrHeader, 0, sizeof (IfrHeader));

+    IfrHeader.Header.Type = EFI_HII_IFR;

+    IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader);    

+    Ptr = (UINT8 *)&IfrHeader;

+    for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) {

+      fwrite (Ptr, 1, 1, IfrBinFptr);

+    }

+    //

+    //

+    // Write all the IFR bytes

+    //

+    Curr = mIfrBytes;

+    Count = 0;

+    while (Curr != NULL) {

+      fwrite (&Curr->OpcodeByte, 1, 1, IfrBinFptr);

+      Curr = Curr->Next;

+    }

+    //

+    //

+    // Close the file

+    //

+    fclose (IfrBinFptr); 

+    IfrBinFptr = NULL;

+  }

+  //

+  // If creating a listing file, then open the input and output files

+  //

+  ListFile = 0;

+  if (gOptions.CreateListFile) {

+    //

+    // Open the input VFR file and the output list file

+    //

+    if ((InFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) {

+      Warning (PROGRAM_NAME, 0, 0, gOptions.PreprocessorOutputFileName, "could not open file for creating a list file");

+    } else {

+      if ((OutFptr = fopen (gOptions.VfrListFileName, "w")) == NULL) {

+        Warning (PROGRAM_NAME, 0, 0, gOptions.VfrListFileName, "could not open output list file for writing");

+        fclose (InFptr);

+        InFptr = NULL;

+      } else {

+        LineCount   = 0;

+        ListFile    = 1;

+        PoundLines  = 0;

+        ByteCount   = 0;

+      }

+    }

+  }

+  //

+  // Write the list file

+  //

+  if (ListFile) {

+    //

+    // Write out the VFR compiler version

+    //

+    fprintf (OutFptr, "//\n//  VFR compiler version " VFR_COMPILER_VERSION "\n//\n");

+    Curr = mIfrBytes;

+    while (Curr != NULL) {

+      //

+      // Print lines until we reach the line of the current opcode

+      //

+      while (LineCount < PoundLines + Curr->LineNum) {

+        if (fgets (Line, sizeof (Line), InFptr) != NULL) {

+          //

+          // We should check for line length exceeded on the fgets(). Otherwise it

+          // throws the listing file output off. Future enhancement perhaps.

+          //

+          fprintf (OutFptr, "%s", Line);

+          if (strncmp (Line, "#line", 5) == 0) {

+            PoundLines++;

+          }

+        }

+        LineCount++;

+      }

+      //

+      // Print all opcodes with line numbers less than where we are now

+      //

+      BytesLeftThisOpcode = 0;

+      while ((Curr != NULL) && ((Curr->LineNum == 0) || (LineCount >= PoundLines + Curr->LineNum))) {

+        if (BytesLeftThisOpcode == 0) {

+          fprintf (OutFptr, ">%08X: ", ByteCount);

+          if (Curr->Next != NULL) {

+            BytesLeftThisOpcode = (UINT32)Curr->Next->OpcodeByte;

+          }

+        }

+        fprintf (OutFptr, "%02X ", (UINT32)Curr->OpcodeByte);

+        ByteCount++;

+        BytesLeftThisOpcode--;

+        if (BytesLeftThisOpcode == 0) {

+          fprintf (OutFptr, "\n");

+        }

+        Curr = Curr->Next;

+      }

+    }

+    //

+    // Dump any remaining lines from the input file

+    //

+    while (fgets (Line, sizeof (Line), InFptr) != NULL) {

+      fprintf (OutFptr, "%s", Line);

+    }

+    fclose (InFptr);

+    fclose (OutFptr);

+  }

+  //

+  // Debug code to make sure that each opcode we write out has as many

+  // bytes as the IFR structure requires. If there were errors, then

+  // don't do this step.

+  //

+  if (GetUtilityStatus () != STATUS_ERROR) {

+    Curr = mIfrBytes;

+    ByteCount = 0;

+    while (Curr != NULL) {

+      //

+      // First byte is the opcode, second byte is the length

+      //

+      if (Curr->Next == NULL) {

+        Error (__FILE__, __LINE__, 0, "application error", "last opcode written does not contain a length byte");

+        break;

+      }

+      Count = (UINT32)Curr->Next->OpcodeByte;

+      if (Count == 0) {

+        Error (

+          __FILE__, 

+          __LINE__, 

+          0, 

+          "application error", 

+          "opcode with 0 length specified in output at offset 0x%X", 

+          ByteCount

+          );

+        break;

+      }

+      //

+      // Check the length

+      //

+      if ((Curr->OpcodeByte > EFI_IFR_LAST_OPCODE) || (Curr->OpcodeByte == 0)) {

+        Error (

+          __FILE__, 

+          __LINE__, 

+          0, 

+          "application error", 

+          "invalid opcode 0x%X in output at offset 0x%X", 

+          (UINT32) Curr->OpcodeByte, ByteCount

+          );

+      } else if (mOpcodeSizes[Curr->OpcodeByte].Size < 0) {

+        //

+        // For those cases where the length is variable, the size is negative, and indicates

+        // the miniumum size.

+        //

+        if ((mOpcodeSizes[Curr->OpcodeByte].Size * -1) > Count) {

+          Error (

+            __FILE__, 

+            __LINE__, 

+            0, 

+            "application error", 

+            "insufficient number of bytes written for %s at offset 0x%X",

+            mOpcodeSizes[Curr->OpcodeByte].Name, 

+            ByteCount

+            );

+        }

+      } else {

+        //

+        // Check for gaps

+        //

+        if (mOpcodeSizes[Curr->OpcodeByte].Size == 0) {

+          Error (

+            __FILE__, 

+            __LINE__, 

+            0, 

+            "application error", 

+            "invalid opcode 0x%X in output at offset 0x%X", 

+            (UINT32)Curr->OpcodeByte, 

+            ByteCount

+            );

+        } else {

+          //

+          // Check size

+          //

+          if (mOpcodeSizes[Curr->OpcodeByte].Size != Count) {

+            Error (

+              __FILE__, 

+              __LINE__, 

+              0, 

+              "application error", 

+              "invalid number of bytes (%d written s/b %d) written for %s at offset 0x%X",

+              Count, 

+              mOpcodeSizes[Curr->OpcodeByte].Size, 

+              mOpcodeSizes[Curr->OpcodeByte].Name, 

+              ByteCount

+              );

+          }

+        }

+      }

+      //

+      // Skip to next opcode

+      //

+      while (Count > 0) {

+        ByteCount++;

+        if (Curr == NULL) {

+          Error (__FILE__, __LINE__, 0, "application error", "last opcode written has invalid length");

+          break;

+        }

+        Curr = Curr->Next;

+        Count--;

+      }

+    }

+  }

+}

+

+VfrOpcodeHandler::~VfrOpcodeHandler(

+  ) 

+/*++

+

+Routine Description:

+  Destructor for the VFR opcode handler. Free up memory allocated

+  while parsing the VFR script.

+  

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+{

+  IFR_BYTE    *Curr;

+  IFR_BYTE    *Next;

+  //

+  // Free up the IFR bytes

+  //

+  Curr = mIfrBytes;

+  while (Curr != NULL) {

+    Next = Curr->Next;

+    free (Curr);

+    Curr = Next;

+  }

+}

+

+int 

+VfrOpcodeHandler::AddOpcodeByte (

+  UINT8 OpcodeByte, 

+  UINT32 LineNum

+  ) 

+/*++

+

+Routine Description:

+  This function is invoked by the parser when a new IFR

+  opcode should be emitted.

+  

+Arguments:

+  OpcodeByte  - the IFR opcode

+  LineNum     - the line number from the source file that resulted

+                in the opcode being emitted.

+

+Returns:

+  0 always

+

+--*/

+{

+  UINT32 Count;

+

+  FlushQueue();

+  //

+  // Now add this new byte

+  //

+  mQueuedOpcodeByte       = OpcodeByte;

+  mQueuedLineNum          = LineNum;

+  mQueuedOpcodeByteValid  = 1;

+  return 0;

+}

+

+VOID 

+VfrOpcodeHandler::AddByte (

+  UINT8 ByteVal, 

+  UINT8 KeyByte

+  )

+/*++

+

+Routine Description:

+  This function is invoked by the parser when it determines

+  that more raw IFR bytes should be emitted to the output stream.

+  Here we just queue them up into an output buffer.

+  

+Arguments:

+  ByteVal   - the raw byte to emit to the output IFR stream

+  KeyByte   - a value that can be used for debug. 

+

+Returns:

+  None

+

+--*/

+{

+  //

+  // Check for buffer overflow

+  //

+  if (mQueuedByteCount > MAX_QUEUE_COUNT) {

+    Error (PROGRAM_NAME, 0, 0, NULL, "opcode queue overflow");

+  } else {

+    mQueuedBytes[mQueuedByteCount]    = ByteVal;

+    mQueuedKeyBytes[mQueuedByteCount] = KeyByte;

+    mQueuedByteCount++;

+  }

+}

+

+int 

+VfrOpcodeHandler::FlushQueue (

+  )

+/*++

+

+Routine Description:

+  This function is invoked to flush the internal IFR buffer.

+  

+Arguments:

+  None

+

+Returns:

+  0 always

+

+--*/

+{

+  UINT32 Count;

+  UINT32 EmitNoneOnePair;

+

+  EmitNoneOnePair = 0;

+  //

+  // If the secondary varstore was specified, then we have to emit

+  // a varstore-select-pair opcode, which only applies to the following

+  // statement. 

+  //

+  if (mSecondaryVarStoreIdSet) {

+    mSecondaryVarStoreIdSet = 0;

+    //

+    // If primary and secondary are the same as the current default

+    // varstore, then we don't have to do anything.

+    // Note that the varstore-select-pair only applies to the following

+    // opcode.

+    //

+    if ((mPrimaryVarStoreId != mSecondaryVarStoreId) || (mPrimaryVarStoreId != mDefaultVarStoreId)) {

+      IAddByte (EFI_IFR_VARSTORE_SELECT_PAIR_OP, 'O', mQueuedLineNum);

+      IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT_PAIR), 'L', 0);

+      IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0);

+      IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0);

+      IAddByte ((UINT8)mSecondaryVarStoreId, 0, 0);

+      IAddByte ((UINT8)(mSecondaryVarStoreId >> 8), 0, 0);

+    }

+  } else if (mPrimaryVarStoreIdSet != 0) {

+    mPrimaryVarStoreIdSet = 0;

+    if (mDefaultVarStoreId != mPrimaryVarStoreId) {

+      //

+      // The VFR statement referenced a different variable store 

+      // than the last one we reported. Insert a new varstore select 

+      // statement. 

+      //

+      IAddByte (EFI_IFR_VARSTORE_SELECT_OP, 'O', mQueuedLineNum);

+      IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT), 'L', 0);

+      IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0);

+      IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0);

+      mDefaultVarStoreId = mPrimaryVarStoreId;

+    }

+  }

+  //

+  // Likely a new opcode is being added. Since each opcode item in the IFR has 

+  // a header that specifies the size of the opcode item (which we don't

+  // know until we find the next opcode in the VFR), we queue up bytes

+  // until we know the size. Then we write them out. So flush the queue

+  // now.

+  //

+  if (mQueuedOpcodeByteValid != 0) {

+    // 

+    // Add the previous opcode byte, the length byte, and the binary

+    // data.

+    //

+    IAddByte (mQueuedOpcodeByte, 'O', mQueuedLineNum);

+    IAddByte ((UINT8)(mQueuedByteCount + 2), 'L', 0);

+    for (Count = 0; Count < mQueuedByteCount; Count++) {

+      IAddByte (mQueuedBytes[Count], mQueuedKeyBytes[Count], 0);          

+    }

+    mQueuedByteCount = 0;

+    mQueuedOpcodeByteValid = 0;

+  }    

+  return 0;

+}

+

+int 

+VfrOpcodeHandler::IAddByte (

+  UINT8   ByteVal, 

+  UINT8   KeyByte, 

+  UINT32  LineNum

+  )

+/*++

+

+Routine Description:

+  This internal function is used to add actual IFR bytes to

+  the output stream. Most other functions queue up the bytes

+  in an internal buffer. Once they come here, there's no

+  going back.

+

+  

+Arguments:

+  ByteVal   - value to write to output 

+  KeyByte   - key value tied to the byte -- useful for debug

+  LineNum   - line number from source file the byte resulted from

+

+Returns:

+  0 - if successful

+  1 - failed due to memory allocation failure

+

+--*/

+{

+  IFR_BYTE    *NewByte;

+  NewByte = (IFR_BYTE *)malloc (sizeof (IFR_BYTE));

+  if (NewByte == NULL) {

+    return 1;

+  }

+  memset ((char *)NewByte, 0, sizeof (IFR_BYTE));

+  NewByte->OpcodeByte = ByteVal;

+  NewByte->KeyByte = KeyByte;

+  NewByte->LineNum = LineNum;

+  //

+  // Add to the list

+  //

+  if (mIfrBytes == NULL) {

+    mIfrBytes = NewByte;

+  } else {

+    mLastIfrByte->Next = NewByte;

+  } 

+  mLastIfrByte = NewByte;

+  mBytesWritten++;

+  return 0;

+}

+

+VOID 

+WriteStandardFileHeader (

+  FILE *OutFptr

+  ) 

+/*++

+

+Routine Description:

+  This function is invoked to emit a standard header to an

+  output text file.

+  

+Arguments:

+  OutFptr - file to write the header to

+

+Returns:

+  None

+

+--*/

+{

+  UINT32 TempIndex;

+  for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) {

+    fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]);

+  }

+  //

+  // Write out the VFR compiler version

+  //

+  fprintf (OutFptr, "//  VFR compiler version " VFR_COMPILER_VERSION "\n//\n");

+}

diff --git a/edk2/Tools/Source/TianoTools/VfrCompile/VfrServices.h b/edk2/Tools/Source/TianoTools/VfrCompile/VfrServices.h
new file mode 100644
index 0000000..6b8c560
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/VfrCompile/VfrServices.h
@@ -0,0 +1,227 @@
+/*++

+

+Copyright (c) 2004, Intel Corporation                                                         

+All rights reserved. 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.             

+

+Module Name:

+

+  VfrServices.h

+

+Abstract:

+

+  Prototypes and defines for routines and classes used by the

+  EFI VFR compiler.

+  

+--*/

+

+#ifndef _VFR_SERVICES_H_

+#define _VFR_SERVICES_H_

+

+class VfrOpcodeHandler

+{

+public:

+  VfrOpcodeHandler (

+    VOID

+    )

+  /*++

+

+Routine Description:

+  Constructor for the VFR opcode handling class.

+  

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+  ;

+  ~VfrOpcodeHandler (

+    VOID

+    )

+  /*++

+

+Routine Description:

+  Destructor for the VFR opcode handler. Free up memory allocated

+  while parsing the VFR script.

+  

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+  ;

+  void

+  WriteIfrBytes (

+    VOID

+    )

+  /*++

+

+Routine Description:

+  This function is invoked at the end of parsing. Its purpose

+  is to write out all the IFR bytes that were queued up while

+  parsing.

+  

+Arguments:

+  None

+

+Returns:

+  None

+

+--*/

+  ;

+  int

+  AddOpcodeByte (

+    UINT8  OpcodeByte,

+    UINT32 LineNum

+    )

+  /*++

+

+Routine Description:

+  This function is invoked by the parser when a new IFR

+  opcode should be emitted.

+  

+Arguments:

+  OpcodeByte  - the IFR opcode

+  LineNum     - the line number from the source file that resulted

+                in the opcode being emitted.

+

+Returns:

+  0 always

+

+--*/

+  ;

+  void

+  AddByte (

+    UINT8 ByteVal,

+    UINT8 KeyByte

+    )

+  /*++

+

+Routine Description:

+  This function is invoked by the parser when it determines

+  that more raw IFR bytes should be emitted to the output stream.

+  Here we just queue them up into an output buffer.

+  

+Arguments:

+  ByteVal   - the raw byte to emit to the output IFR stream

+  KeyByte   - a value that can be used for debug. 

+

+Returns:

+  None

+

+--*/

+  ;

+  void

+  SetVarStoreId (

+    UINT16 VarStoreId

+    )

+  /*++

+

+Routine Description:

+  This function is invoked by the parser when a variable is referenced in the 

+  VFR. Save the variable store (and set a flag) so that we can later determine 

+  if we need to emit a varstore-select or varstore-select-pair opcode.

+  

+Arguments:

+  VarStoreId - ID of the variable store referenced in the VFR

+

+Returns:

+  None

+

+--*/

+  ;

+  void

+  SetSecondaryVarStoreId (

+    UINT16 VarStoreId

+    )

+  /*++

+

+Routine Description:

+  This function is invoked by the parser when a secondary variable is 

+  referenced in the VFR. Save the variable store (and set a flag) so 

+  that we can later determine if we need to emit a varstore-select or 

+  varstore-pair opcode.

+  

+Arguments:

+  VarStoreId - ID of the variable store referenced in the VFR

+

+Returns:

+  None

+

+--*/

+  ;

+

+/* */

+private:

+  int

+  FlushQueue (

+    VOID

+    )

+  /*++

+

+Routine Description:

+  This function is invoked to flush the internal IFR buffer.

+  

+Arguments:

+  None

+

+Returns:

+  0 always

+

+--*/

+  ;

+  int

+  IAddByte (

+    UINT8  ByteVal,

+    UINT8  KeyByte,

+    UINT32 LineNum

+    )

+  /*++

+

+Routine Description:

+  This internal function is used to add actual IFR bytes to

+  the output stream. Most other functions queue up the bytes

+  in an internal buffer. Once they come here, there's no

+  going back.

+

+  

+Arguments:

+  ByteVal   - value to write to output 

+  KeyByte   - key value tied to the byte -- useful for debug

+  LineNum   - line number from source file the byte resulted from

+

+Returns:

+  0 - if successful

+  1 - failed due to memory allocation failure

+

+--*/

+  ;

+

+/* */

+private:

+  IFR_BYTE  *mIfrBytes;

+  IFR_BYTE  *mLastIfrByte;

+  UINT32    mQueuedByteCount;

+  UINT32    mBytesWritten;

+  UINT32    mQueuedLineNum;

+  UINT8     mQueuedBytes[MAX_QUEUE_COUNT];

+  UINT8     mQueuedKeyBytes[MAX_QUEUE_COUNT];

+  UINT8     mQueuedOpcodeByte;

+  UINT32    mQueuedOpcodeByteValid;

+  UINT16    mPrimaryVarStoreId;

+  UINT8     mPrimaryVarStoreIdSet;

+  UINT16    mSecondaryVarStoreId;

+  UINT8     mSecondaryVarStoreIdSet;

+  UINT16    mDefaultVarStoreId;

+};

+

+#endif // #ifndef _VFR_SERVICES_H_

diff --git a/edk2/Tools/Source/TianoTools/VfrCompile/build.xml b/edk2/Tools/Source/TianoTools/VfrCompile/build.xml
new file mode 100644
index 0000000..8fb9d74
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/VfrCompile/build.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK VfrCompile Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="VfrCompile"/>

+  <property name="FileSet" value="*.cpp"/>

+  <property name="FileSetPccts" value="ATokenBuffer.cpp DLexerBase.cpp AParser.cpp"/>

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Antlr, Dlg, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+		<condition property="CheckDepends">

+		  <uptodate targetfile="${WORKSPACE}/Tools/bin/VfrCompile${ext_exe}">

+			  <srcfiles dir="${WORKSPACE}/Tools/Source/TianoTools/VfrCompile" 

+        includes="EfiVfrParser.cpp DLGLexer.cpp VfrCompile.cpp VfrCompile.g VfrServices.cpp parser.dlg"/>

+			</uptodate>

+		</condition>

+

+    <condition property="gxx_extra_libs" value="stdc++ System gcc_s.10.4 gcc">

+      <os family="mac"/>

+	</condition>

+		

+    <condition property="gxx_extra_libs" value="stdc++">

+      <os name="linux"/>

+	</condition>

+		

+    <condition property="gxx_extra_libs" value="stdc++">

+      <os family="windows"/>

+	</condition>

+		

+  </target>

+

+  <target name="Antlr" depends="init" unless="CheckDepends">

+    <exec dir="${basedir}/${ToolName}" executable="antlr" failonerror="TRUE">

+      <arg line="-CC -e3 -ck 3 -o . VfrCompile.g"/>

+    </exec>

+  </target>

+

+  <target name="Dlg" depends="Antlr" unless="CheckDepends">

+    <exec dir="${basedir}/${ToolName}" executable="dlg" failonerror="TRUE">

+      <arg line="-C2 -i -CC -o . parser.dlg"/>

+    </exec>

+  </target>

+

+  <target name="Tool" depends="init, Dlg">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        optimize="speed">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" />

+

+      <fileset dir="${basedir}/Pccts/h" 

+        includes="${FileSetPccts}" />

+

+      <includepath path="${env.WORKSPACE}/Tools/Source/TianoTools/Pccts/h"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools"/>

+      <syslibset libs="${gxx_extra_libs}" if="gcc"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/ZeroDebugData/Makefile b/edk2/Tools/Source/TianoTools/ZeroDebugData/Makefile
new file mode 100644
index 0000000..c20fd85
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/ZeroDebugData/Makefile
@@ -0,0 +1,63 @@
+#/*++

+#   

+#  Copyright (c) 2001 Intel Corporation

+#   

+#  Module Name:  makefile

+#   

+#  Abstract:

+#   

+#    This file is used to build the EFI utility.

+#   

+#--*/

+

+#

+# Do this if you want to compile from this directory

+#

+!IFNDEF TOOLCHAIN

+TOOLCHAIN = TOOLCHAIN_MSVC

+!ENDIF

+

+!INCLUDE PlatformTools.env

+

+#

+# Define some macros we use here. Should get rid of them someday and 

+# get rid of the extra level of indirection.

+#

+COMMON_SOURCE      = $(EDK_TOOLS_COMMON)

+

+#

+# Common information

+#

+

+INC=$(INC)

+

+#

+# Target specific information

+#

+

+TARGET_NAME=ZeroDebugData

+TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)

+

+TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe

+

+TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\ZeroDebugData.c"

+TARGET_EXE_INCLUDE =

+

+#

+# Build targets

+#

+

+all: $(TARGET_EXE)

+

+#

+# Build EXE

+#

+

+$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE)

+  $(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj

+

+$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)

+  $(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB)  $(TARGET_EXE_LIBS)

+

+clean:

+  @if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).*

diff --git a/edk2/Tools/Source/TianoTools/ZeroDebugData/ZeroDebugData.c b/edk2/Tools/Source/TianoTools/ZeroDebugData/ZeroDebugData.c
new file mode 100644
index 0000000..0a7ce85
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/ZeroDebugData/ZeroDebugData.c
@@ -0,0 +1,389 @@
+/*++

+

+Copyright (c)  2001 - 2002 Intel Corporation. All rights reserved

+This software and associated documentation (if any) is furnished

+under a license and may only be used or copied in accordance

+with the terms of the license. Except as permitted by such

+license, no part of this software or documentation may be

+reproduced, stored in a retrieval system, or transmitted in any

+form or by any means without the express written consent of

+Intel Corporation.

+

+

+Module Name:

+  ZeroDebugData.c

+

+Abstract:

+  Zero the Debug Data Fields of Portable Executable (PE) format file.

+

+--*/

+

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+

+void

+PrintUsage (

+  void

+  )

+/*++

+Routine Description:

+  print usage of ZeroDebugData command

+

+Arguments:

+  None

+

+Returns:

+  None

+--*/

+// GC_TODO:    void - add argument and description to function comment

+{

+  //

+  // print usage of command

+  //

+  printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");

+}

+

+int

+ReadFromFile (

+  FILE      *fp,

+  long      offset,

+  void      *buffer,

+  int       size

+  )

+/*++

+Routine Description:

+  read data from a specified location of file

+

+Arguments:

+  fp              - file pointer

+  offset          - number of bytes from beginning of file

+  buffer          - buffer used to store data

+  size            - size of buffer

+

+Returns:

+  =  0            - Success

+  = -1            - Failed

+--*/

+{

+  //

+  // set file pointer to the specified location of file

+  //

+  if (fseek (fp, offset, SEEK_SET) != 0) {

+    printf ("Error: Cannot move the current location of the file.\n");

+    return -1;

+  }

+  //

+  // read data from the file

+  //

+  if (fread (buffer, size, 1, fp) != 1) {

+    printf ("Error: Cannot read data from the file.\n");

+    return -1;

+  }

+

+  return 0;

+}

+

+int

+ZeroDebugData (

+  FILE      *fp,

+  FILE      *fpData

+  )

+/*++

+

+Routine Description:

+

+  Zero the debug data fields of the file

+

+Arguments:

+

+  fp              - file pointer

+  fpData          - pointer to output file that ZeroDebugData progress is written to

+

+Returns:

+

+  =  0            - Success

+  = -1            - Failed

+

+--*/

+{

+  unsigned char header[4];

+  unsigned long offset;

+  unsigned long NumberOfRvaAndSizes;

+  unsigned int  nvalue;

+  unsigned long lvalue;

+  unsigned long Size;

+  unsigned long Pointer;

+  unsigned char *Buffer;

+  unsigned long Index;

+

+  //

+  // read the header of file

+  //

+  if (ReadFromFile (fp, 0, header, 2) != 0) {

+    printf ("Error: open image file\n");

+    return -1;

+  }

+  //

+  // "MZ" -- the header of image file (PE)

+  //

+  if (strncmp ((char *) header, "MZ", 2) != 0) {

+    printf ("Error: Invalid Image file.\n");

+    return -1;

+  }

+  //

+  // At location 0x3C, the stub has the file offset to the

+  // PE signature.

+  //

+  if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) {

+    return -1;

+  }

+  //

+  // read the header of optional

+  //

+  if (ReadFromFile (fp, offset, header, 4) != 0) {

+    return -1;

+  }

+  //

+  // "PE\0\0" -- the signature of optional header

+  //

+  if (strncmp ((char *) header, "PE\0\0", 4) != 0) {

+    printf ("Error: Invalid PE format file.\n");

+    return -1;

+  }

+  //

+  // Add 16 to skip COFF file header, and get to optional header.

+  //

+  offset += 24;

+

+  //

+  // Check the magic field, 0x10B for PE32 and 0x20B for PE32+

+  //

+  if (ReadFromFile (fp, offset, &nvalue, 2) != 0) {

+    return -1;

+  }

+  //

+  // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92.

+  // Else it is 108.

+  //

+  switch (nvalue & 0xFFFF) {

+  case 0x10B:

+    offset += 92;

+    printf ("Info: Image is PE32. ");

+    break;

+

+  case 0x20B:

+    offset += 108;

+    printf ("Info: Image is PE32+. ");

+    break;

+

+  default:

+    printf ("Error: Magic value is unknown.\n");

+    return -1;

+  }

+  //

+  // get the value of NumberOfRvaAndSizes

+  //

+  if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) {

+    printf ("Error: read NumberOfRvaAndSizes error.\n");

+    return -1;

+  }

+  //

+  // printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes);

+  //

+  //

+  // Finding Debug Table, offset of Debug Table

+  // is 4 + 6 * 8 = 52.

+  //

+  if (NumberOfRvaAndSizes >= 7) {

+    if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) {

+      return -1;

+    }

+    //

+    // Read the SizeOfData(16) and PointerToRawData(24)

+    //

+    if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) {

+      printf ("error: Size = %d\n", Size);

+      return -1;

+    }

+

+    printf ("Debug data: size = %xh, ", Size);

+    fprintf (fpData, "Debug data: size = %xh, ", Size);

+

+    if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) {

+      printf ("error: LoadOffset = %xh\n", Pointer);

+      return -1;

+    }

+    //

+    // printf ("LoadOffset = %xh, ", Pointer);

+    //

+    fprintf (fpData, "LoadOffset = %xh, ", Pointer);

+

+    if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) {

+      printf ("error: FileOffset = %xh\n", Pointer);

+      return -1;

+    }

+

+    printf ("FileOffset = %xh, ", Pointer);

+    fprintf (fpData, "FileOffset = %xh, \n", Pointer);

+

+    if ((lvalue != 0) && (Pointer != 0)) {

+      //

+      // prepare buffer

+      //

+      Buffer = malloc (Size + 1);

+      if (Buffer == NULL) {

+        printf ("Error: Cannot allocate memory.\n");

+        return -1;

+      }

+      //

+      // set file pointer to the specified location of file

+      //

+      if (fseek (fp, Pointer, SEEK_SET) != 0) {

+        printf ("Error: Cannot move the current location of the file.\n");

+        free (Buffer);

+        return -1;

+      }

+      //

+      // read data from PE file

+      //

+      if (fread (Buffer, Size, 1, fp) != 1) {

+        printf ("Error: Cannot read data from the file.\n");

+        free (Buffer);

+        return -1;

+      }

+      //

+      // write to data file

+      //

+      for (Index = 0; Index < Size;) {

+        fprintf (fpData, "%02x ", Buffer[Index]);

+

+        Index++;

+        if (Index % 8 == 0) {

+          fprintf (fpData, "\n");

+        }

+      }

+

+      fprintf (fpData, "\n");

+

+      //

+      // zero buffer and write back to PE file

+      //

+      if (fseek (fp, Pointer, SEEK_SET) != 0) {

+        printf ("Error: Cannot move the current location of the file.\n");

+        free (Buffer);

+        return -1;

+      }

+

+      memset (Buffer, 0, Size);

+      if (fwrite (Buffer, Size, 1, fp) != 1) {

+        perror ("Error: Cannot write zero to the file.\n");

+        free (Buffer);

+        return -1;

+      }

+      //

+      // set file pointer to the specified location of file

+      //

+      if (fseek (fp, lvalue + 4, SEEK_SET) != 0) {

+        printf ("Error: Cannot move the current location of the file.\n");

+        free (Buffer);

+        return -1;

+      }

+

+      if (fwrite (Buffer, 4, 1, fp) != 1) {

+        perror ("Error: Cannot write zero to the file.\n");

+        free (Buffer);

+        return -1;

+      }

+

+      free (Buffer);

+    }

+  }

+

+  return 0;

+}

+

+int

+main (

+  int       argc,

+  char      *argv[]

+  )

+/*++

+

+Routine Description:

+

+  Prints the zero debug data of the PE file to the DebugData file.

+  Executes the ZeroDebugData function.

+

+Arguments:

+

+  argc   - Standard C argument, number of command line arguments.

+  argv[] - Standard C argument, array of pointers to the input files,

+           such as the PE and DebugData files.

+

+Returns:

+

+  zero    - success

+  nonzero - failure

+

+--*/

+{

+  FILE  *fp;

+  FILE  *fpData;

+  char  DataFile[1024] = "";

+

+  //

+  // check the number of parameters

+  //

+  if (argc < 2) {

+    printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");

+    return -1;

+  }

+  //

+  // open the DebugData file, if not exists, return

+  //

+  if (argc >= 3) {

+    strcpy (DataFile, argv[2]);

+  } else {

+    strcpy (DataFile, "DebugData.dat");

+  }

+

+  fpData = fopen (DataFile, "a+");

+  if (fpData == NULL) {

+    fpData = fopen (DataFile, "w");

+    if (fpData == NULL) {

+      printf ("Error: Cannot open the data file!\n");

+      return -1;

+    }

+  }

+  //

+  // open the PE file

+  //

+  fp = fopen (argv[1], "r+b");

+  if (fp == NULL) {

+    printf ("Error: Cannot open the PE file!\n");

+    return -1;

+  }

+  //

+  // Zero the Debug Data to the PE file

+  //

+  printf ("Zero Debug Data to file %s:\n", argv[1]);

+  fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]);

+  if ((int *) ZeroDebugData (fp, fpData) != 0) {

+    printf ("Error: Zero Debug Data PE file\n");

+    fclose (fp);

+    return -1;

+  }

+

+  printf (" success\n");

+

+  //

+  // close the PE file

+  //

+  fflush (fpData);

+  fflush (fp);

+  fclose (fpData);

+  fclose (fp);

+

+  return 0;

+}

diff --git a/edk2/Tools/Source/TianoTools/ZeroDebugData/build.xml b/edk2/Tools/Source/TianoTools/ZeroDebugData/build.xml
new file mode 100644
index 0000000..3e00f70
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/ZeroDebugData/build.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" ?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="GenTool" basedir=".">

+<!--

+    EDK ZeroDebugData Tool

+  Copyright (c) 2006, Intel Corporation

+-->

+  <property name="ToolName" value="ZeroDebugData"/>

+  <property name="FileSet" value="*.c"/>

+

+  <taskdef resource="cpptasks.tasks"/>

+  <typedef resource="cpptasks.types"/>

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+

+  <property environment="env"/>

+

+  <property name="LINK_OUTPUT_TYPE" value="static"/>

+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>

+

+  <target name="GenTool" depends="init, Tool">

+    <echo message="Building the EDK Tool: ${ToolName}"/>

+  </target>

+

+  <target name="init">

+    <echo message="The EDK Tool: ${ToolName}"/>

+    <mkdir dir="${BUILD_DIR}"/>

+    <if>

+      <equals arg1="${GCC}" arg2="cygwin"/>

+      <then>

+        <echo message="Cygwin Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    <elseif>

+      <os family="dos"/>

+      <then>

+        <echo message="Windows Family"/>

+        <property name="ToolChain" value="msvc"/>

+      </then>

+    </elseif>

+    <elseif>

+      <os family="unix"/>

+      <then>

+        <echo message="UNIX Family"/>

+        <property name="ToolChain" value="gcc"/>

+      </then>

+    </elseif>

+

+    <else>

+      <echo>

+        Unsupported Operating System

+        Please Contact Intel Corporation

+      </echo>

+    </else>

+    </if>

+    <if>

+      <equals arg1="${ToolChain}" arg2="msvc"/>

+      <then>

+        <property name="ext_static" value=".lib"/>

+        <property name="ext_dynamic" value=".dll"/>

+        <property name="ext_exe" value=".exe"/>

+      </then>

+      <elseif>

+        <equals arg1="${ToolChain}" arg2="gcc"/>

+        <then>

+          <property name="ext_static" value=".a"/>

+          <property name="ext_dynamic" value=".so"/>

+          <property name="ext_exe" value=""/>

+        </then>

+      </elseif>

+    </if>

+  </target>

+

+  <target name="Tool" depends="init">

+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" 

+        outfile="${BIN_DIR}/${ToolName}"

+        outtype="executable"

+        libtool="${haveLibtool}"

+        debug="false">

+

+      <fileset dir="${basedir}/${ToolName}" 

+        includes="${FileSet}" 

+        defaultexcludes="TRUE" 

+        excludes="*.xml *.inf"/>

+

+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>

+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>

+      <includepath path="${PACKAGE_DIR}/Common"/>

+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>

+    </cc>

+  </target>

+

+  <target name="clean" depends="init">

+    <echo message="Removing Intermediate Files Only"/>  

+    <delete>

+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>

+    </delete>

+  </target>

+

+  <target name="cleanall" depends="init">

+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>  

+    <delete dir="${BUILD_DIR}">

+      <fileset dir="${BIN_DIR}" includes="${ToolName}${ext_exe}"/>

+    </delete>

+  </target>

+

+</project>

diff --git a/edk2/Tools/Source/TianoTools/build.xml b/edk2/Tools/Source/TianoTools/build.xml
new file mode 100644
index 0000000..64c8fb9
--- /dev/null
+++ b/edk2/Tools/Source/TianoTools/build.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8" ?> 

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="all" basedir=".">

+<!-- Copyright (c) 2006, Intel Corporation -->

+<!-- Filename: Tools/Source/build.xml -->

+

+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

+  <property environment="env" />

+  <property name="WORKSPACE" value="${env.WORKSPACE}" />

+  <property name="WORKSPACE_DIR" value="${WORKSPACE}" />

+  <property name="PACKAGE" value="Tools" />

+  <property name="PACKAGE_DIR" value="${WORKSPACE}/Tools/Source/TianoTools" />

+  <property name="LIB_DIR" value="${PACKAGE_DIR}/Library" />

+  <property name="BIN_DIR" value="${WORKSPACE}/Tools/bin" />

+  <property name="BUILD_MODE" value="PACKAGE" />

+  <property name="Libs" 

+    value="String/build.xml Common/build.xml CustomizedCompress/build.xml PeCoffLoader/build.xml"/>

+

+  <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml" />

+

+  <path id="classpath">

+    <fileset dir="${WORKSPACE}/Tools/Jars" includes="*.jar"/>

+    <fileset dir="${env.XMLBEANS_HOME}/lib" includes="*.jar"/>

+  </path>

+

+  <target name="all" depends="init, Tools" />

+  

+  <target name="init">

+    <taskdef classpathref="classpath" resource="GenBuild.tasks" />

+    <taskdef classpathref="classpath" resource="net/sf/antcontrib/antlib.xml" />

+

+    <taskdef classpathref="classpath" resource="cpptasks.tasks"/>

+    <typedef classpathref="classpath" resource="cpptasks.types"/>

+

+    <mkdir dir="${BIN_DIR}" />

+    <mkdir dir="${LIB_DIR}" />

+    <if>

+      <os family="unix" />

+      <then>

+        <echo message="OS Family UNIX" />

+      </then>

+      <elseif>

+        <os family="dos" />

+        <then>

+          <echo message="OS Family DOS" />

+        </then>

+      </elseif>

+      <elseif>

+        <os family="mac" />

+        <then>

+          <echo message="OS Family OS X" />

+        </then>

+      </elseif>

+      <else>

+        <echo message="OS Family Unsupported" />

+      </else>

+    </if>

+

+    <ToolChainSetup confPath="${WORKSPACE_DIR}/Tools/Conf" />

+    

+    <if>

+        <isset property="env.TOOL_CHAIN" />

+      <then>

+        <property name="ToolChain" value="${env.TOOL_CHAIN}"/>

+        <condition property="gcc">

+          <equals arg1="${ToolChain}" arg2="gcc"/>

+        </condition>

+      </then>

+    </if>

+

+    <condition property="linux" value="true">

+      <os name="Linux"/>

+    </condition>

+    

+    <condition property="windows" value="true">

+      <os family="Windows"/>

+    </condition>

+    

+    <condition property="OSX" value="true">

+      <os family="Mac"/>

+    </condition>

+    

+  </target>

+  

+  <target name="Libraries">

+    <subant target="" inheritall="true">

+      <fileset dir="${PACKAGE_DIR}" 

+        includes="${Libs}"/>

+    </subant>

+  </target>

+

+  <target name="Tools" depends="Libraries">

+    <subant target="" inheritall="true">

+      <fileset dir="${PACKAGE_DIR}" includes="*/build.xml"

+        excludes="${Libs}"/>

+    </subant>

+  </target>

+

+  <target name="clean">

+    <subant target="clean" inheritall="true">

+      <fileset dir="${PACKAGE_DIR}" includes="*/build.xml"/>

+    </subant>

+  </target>

+

+  <target name="cleanall">

+    <subant target="cleanall" inheritall="true">

+      <fileset dir="${PACKAGE_DIR}" includes="*/build.xml"/>

+    </subant>

+    <delete dir="${LIB_DIR}"/>

+  </target>

+</project>

diff --git a/edk2/Tools/Source/Tools.msa b/edk2/Tools/Source/Tools.msa
new file mode 100644
index 0000000..b26aaf1
--- /dev/null
+++ b/edk2/Tools/Source/Tools.msa
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <ModuleName>Tools</ModuleName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>CUSTOM_BUILD</ComponentType>

+    <GuidValue>5d6c499e-53fd-430e-9285-2d7811b924e8</GuidValue>

+    <Version>2.0</Version>

+    <Abstract>This is the EFI/Tiano Tool Resources Module</Abstract>

+    <Description>

+      This Module provides the EFI/Tiano Tools that are used to create EFI/Tiano

+      Modules and Platform Binary Files (PBF)

+      These tools require compilation only once if the Developer Workstation and

+      the Developer's choice of HOST tool chain are stable.  If the developer

+      updates either the OS or the HOST tool chain, these tools should be rebuilt.

+    </Description>

+    <Copyright>Copyright 2005-2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved. 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.

+    </License>

+    <CreatedDate>2006-02-02 09:30</CreatedDate>

+    <ModifiedDate>2006-06-02 11:32</ModifiedDate>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="SOMETIMES_CONSUMED">SurfaceArea</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename Path="Common">FrameworkDatabase.db</Filename>

+    <Filename Path="Conf">cygwin_tools.txt</Filename>

+    <Filename Path="Conf">gcc_tools.txt</Filename>

+    <Filename Path="Conf">intel_tools.txt</Filename>

+    <Filename Path="Conf">msft_tools.txt</Filename>

+    <Filename Path="Conf">winddk_tools.txt</Filename>

+    <Filename Path="Conf">tools_def.template</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>MdePkg</PackageName>

+  </Includes>

+  <Externs>

+    <Extern>

+      <ModuleEntryPoint></ModuleEntryPoint>

+    </Extern>

+  </Externs>

+  <BuildOptions>

+    <Option>DO_NOT_COMPILE</Option>

+  </BuildOptions>

+</ModuleSurfaceArea>

diff --git a/edk2/Tools/ToolResources.msa b/edk2/Tools/ToolResources.msa
new file mode 100644
index 0000000..63e676b
--- /dev/null
+++ b/edk2/Tools/ToolResources.msa
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <MsaHeader>

+    <BaseName>ToolResources</BaseName>

+    <ModuleType>BASE</ModuleType>

+    <ComponentType>CUSTOM_BUILD</ComponentType>

+    <Guid>5d6c499e-53fd-430e-9285-2d7811b924e8</Guid>

+    <Version>2.0</Version>

+    <Abstract>This is the EFI/Tiano Tool Resources Module</Abstract>

+    <Description> This Module provides the EFI/Tiano Tools and resources that are used to create EFI/Tiano Modules and Platform Binary Files (PBF) These resources and tools do not require compilation. (The three JAR files are provided, Pre-compiled, and do not require additional compilation, the sources are provided, but will not be built under normal procedures. </Description>

+    <Copyright>Copyright 2005-2006, Intel Corporation</Copyright>

+    <License> All rights reserved. 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. </License>

+    <Created>2006-03-30 10:05</Created>

+    <Specification>EFI_SPECIFICATION_VERSION    0x00000000</Specification>

+  </MsaHeader>

+  <LibraryClassDefinitions>

+    <LibraryClass Usage="ALWAYS_CONSUMED">SurfaceArea</LibraryClass>

+  </LibraryClassDefinitions>

+  <SourceFiles>

+    <Filename Path="Conf" FileType="db">FrameworkDatabase.db</Filename>

+    <Filename Path="Conf" FileType="txt">cygwin_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">gcc_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">intel_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">msft_tools.txt</Filename>

+    <Filename Path="Conf" FileType="txt">tools_def.template</Filename>

+    <Filename Path="Conf" FileType="txt">winddk_tools.txt</Filename>

+  </SourceFiles>

+  <Includes>

+    <PackageName>Base</PackageName>

+  </Includes>

+  <BuildOptions>

+    <Option>DO_NOTHING</Option>

+  </BuildOptions>

+</ModuleSurfaceArea>

diff --git a/edk2/Tools/Tools.spd b/edk2/Tools/Tools.spd
new file mode 100644
index 0000000..1737d28
--- /dev/null
+++ b/edk2/Tools/Tools.spd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">

+  <SpdHeader>

+    <PackageName>Tools</PackageName>

+    <Guid>53f84ca0-53fe-4412-b4e7-dcec602e1d49</Guid>

+    <Version>0.3</Version>

+    <Abstract>TianoCore.org EFI Framework Tools</Abstract>

+    <Description> This package provides the tools needed to create EFI/Framework platform

+      binary files (PBF) and EFI/Framework Modules that can be incorporated into a PBF. 

+      Source Code is provided for all C and Java applications. This package also provides 

+      the directory structure and templates for configuration files.

+    </Description>

+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>

+    <License>

+      All rights reserved.

+      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.

+    </License>

+    <CreatedDate>2006-02-24 14:49</CreatedDate>

+    <ModifiedDate>2006-02-24 14:49</ModifiedDate>

+    <URL>http://www.TianoCore.org</URL>

+    <PackageType>MIXED</PackageType>

+    <ReadOnly>false</ReadOnly>

+    <RePackage>true</RePackage>

+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION     0x00000052</Specification>

+  </SpdHeader>

+  <MsaFiles>

+  <!--

+    <MsaFile>

+      <Filename>ToolResources.msa</Filename>

+    </MsaFile>

+    <MsaFile Guid="faf22a0f-10fc-428e-b311-fe506a9c0b2d">

+      <Filename>JavaResources.msa</Filename>

+    </MsaFile>

+    <MsaFile Guid="2a1b3a91-8d57-4fc3-a6c9-ae95bb699bac">

+      <Filename>Source/Tools.msa</Filename>

+    </MsaFile>

+    -->

+  </MsaFiles>

+</PackageSurfaceArea>

diff --git a/edk2/Tools/XMLSchema/FDPManifest.xsd b/edk2/Tools/XMLSchema/FDPManifest.xsd
new file mode 100644
index 0000000..7730742
--- /dev/null
+++ b/edk2/Tools/XMLSchema/FDPManifest.xsd
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Filename: SurfaceArea.xsd

+

+Copyright (c) 2006, Intel Corp.

+All rights reserved. This program and the accompanying materials

+are licensed and made available under the terms and conditions of the BSD License

+which 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.

+

+-->

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"

+    targetNamespace="http://www.TianoCore.org/2006/Edk2.0"

+    xmlns="http://www.TianoCore.org/2006/Edk2.0">

+    <xs:annotation>

+        <xs:documentation xml:lang="en"> This schema defines FDP Manifest </xs:documentation>

+    </xs:annotation>

+    <!--<xs:include schemaLocation="http://nwlxweb02.jf.intel.com/2006/Edk2.0/FrameworkHeaders.xsd"/>-->

+    <xs:include schemaLocation="FrameworkDataElements.xsd"/>

+    <xs:element name="FrameworkDevPkgManifest">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">At the top level of the Manifest we have four sections:

+                Header, Private, Public and Contents.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Header"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Private"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Public"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Contents"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Header">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> The Header contains some three elements that can

+                uniquely identify this package (PackageName, Guid, Version) as well as several

+                fields that identify the licensing and compyright status of the contents of the

+                package. The rest of the fields are there to idenify who created the package and

+                when it was made. The buid fields are here to identify when the package was created,

+                not when the package was compiled. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="PackageName"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:element minOccurs="1" maxOccurs="1" name="PackageType" type="PackageType"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Created"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Creator"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Vendor"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Updated"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Modifier"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="DefaultInstallDir"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildNumber"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="BuildTarget"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildSystem"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildType"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="ReleaseType"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="BuildNumber" type="xs:integer">

+        <xs:annotation>

+            <xs:documentation> The Build number is an integer that is meant to represent the exact

+                build of the package. </xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="Type">

+        <xs:annotation>

+            <xs:documentation> In the Type field we can record what kinds of modules are contained

+                in the package. The possibilities are source, binary and mixed (both source and

+                binary.) </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:attributeGroup ref="attlist.Type"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.Type">

+        <xs:attribute name="Value" use="required">

+            <xs:simpleType>

+                <xs:restriction base="xs:token">

+                    <xs:enumeration value="Source"/>

+                    <xs:enumeration value="Binary"/>

+                    <xs:enumeration value="Mixed"/>

+                </xs:restriction>

+            </xs:simpleType>

+        </xs:attribute>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="attlist.Guid">

+        <xs:attribute name="Value" use="required" type="xs:NMTOKEN"/>

+    </xs:attributeGroup>

+    <xs:element name="BuildTarget" type="SupportedArchitectures">

+        <xs:annotation>

+            <xs:documentation> The build target is used to record what target architecture the

+                modules within this package were compiled for. </xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="Creator">

+        <xs:annotation>

+            <xs:documentation> In the creator field, we can record the name, user id, and email

+                address of the person who created this package. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:attributeGroup ref="attlist.Creator"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.Creator">

+        <xs:attribute name="Name" use="required"/>

+        <xs:attribute name="UserId"/>

+        <xs:attribute name="Email"/>

+    </xs:attributeGroup>

+    <xs:element name="Modifier">

+        <xs:annotation>

+            <xs:documentation> In the Modifier field, we can record the name, user id, and email

+                address of the person who changed/updated or modified this package.

+            </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:attributeGroup ref="attlist.Modifier"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.Modifier">

+        <xs:attribute name="Name" use="required"/>

+        <xs:attribute name="UserId"/>

+        <xs:attribute name="Email"/>

+    </xs:attributeGroup>

+    <xs:element name="Vendor" type="xs:token">

+        <xs:annotation>

+            <xs:documentation> The name of the company, organization or individual that created or

+                distributes the package. </xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="BuildSystem">

+        <xs:annotation>

+            <xs:documentation>This is the place to record the name and DNS name of the computer on

+                which the package was created.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:attributeGroup ref="attlist.BuildSystem"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.BuildSystem">

+        <xs:attribute name="Name" use="required"/>

+        <xs:attribute name="NetAddr"/>

+    </xs:attributeGroup>

+    <xs:element name="BuildType">

+        <xs:annotation>

+            <xs:documentation> The package may be Debug or Production. </xs:documentation>

+        </xs:annotation>

+        <xs:simpleType>

+            <xs:restriction base="xs:token">

+                <xs:enumeration value="Debug"/>

+                <xs:enumeration value="Production"/>

+            </xs:restriction>

+        </xs:simpleType>

+    </xs:element>

+    <xs:element name="ReleaseType">

+        <xs:annotation>

+            <xs:documentation> We may identify the quality level of the package here.

+            </xs:documentation>

+        </xs:annotation>

+        <xs:simpleType>

+            <xs:restriction base="xs:token">

+                <xs:enumeration value="Developer Build"/>

+                <xs:enumeration value="Experimental Release"/>

+                <xs:enumeration value="Alpha Release"/>

+                <xs:enumeration value="Beta Release"/>

+                <xs:enumeration value="Release Canidate"/>

+                <xs:enumeration value="Official Release"/>

+                <xs:enumeration value="Patch Release"/>

+                <xs:enumeration value="Integration Build Release"/>

+            </xs:restriction>

+        </xs:simpleType>

+    </xs:element>

+    <xs:element name="DefaultInstallDir">

+        <xs:annotation>

+            <xs:documentation> This is the directory, relative to the root of the workspace, where

+                the package will be installed by default. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:attributeGroup ref="attlist.DefaultInstallDir"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.DefaultInstallDir">

+        <xs:attribute name="Name" use="required"/>

+    </xs:attributeGroup>

+    <xs:element name="Dependencies">

+        <xs:annotation>

+            <xs:documentation> We can track the pakages that this package provides (these are the

+                packages contained in this pacakge.) We also record which packages are required by

+                this package. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" ref="Requires"/>

+                <xs:element minOccurs="0" ref="Provides"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Requires">

+        <xs:annotation>

+            <xs:documentation> This is a list of the packages that this package requires to be

+                installed in the workspace for package to function and/or build correctly. In the

+                case of source packages, these are the necessary dependencies for successful

+                build-time operation of the package. For binary packages these dependencies are

+                necessary for successful runtime operation.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType mixed="true">

+            <xs:choice minOccurs="0" maxOccurs="unbounded">

+                <xs:element name="Package">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This tag is used in the Framework Package

+                            Database File to track individual package information. The Path is a

+                            relative path to the SPD File.</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence maxOccurs="unbounded">

+                            <xs:element minOccurs="0" maxOccurs="1" ref="PackageName"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Path"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="InstalledDate"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PackageAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element ref="Includes"/>

+                <xs:element name="Library">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="xs:NCName">

+                                <xs:attributeGroup ref="LibraryAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element name="Protocol">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="ProtocolAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element ref="Guid"/>

+                <xs:element ref="File"/>

+            </xs:choice>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Provides">

+        <xs:annotation>

+            <xs:documentation>The list of dependencies that the package fulfills.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:choice minOccurs="0" maxOccurs="unbounded">

+                <xs:element name="Package">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This tag is used in the Framework Package

+                            Database File to track individual package information. The Path is a

+                            relative path to the SPD File.</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence maxOccurs="unbounded">

+                            <xs:element minOccurs="0" maxOccurs="1" ref="PackageName"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Path"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="InstalledDate"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PackageAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element ref="Includes"/>

+                <xs:element name="Library">

+                    <xs:annotation><xs:documentation>

+                        A library. It can be provided by or required by this or other packages.

+                    </xs:documentation></xs:annotation>

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="xs:NCName">

+                                <xs:attributeGroup ref="LibraryAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element name="Protocol">

+                    <xs:annotation>

+                        <xs:documentation>

+                        A protocol. It can be provided by or required by this or other packages.

+                    </xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="ProtocolAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element ref="Guid"/>

+                <xs:element ref="File"/>

+            </xs:choice>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.Library">

+        <xs:attribute name="Name" use="required"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="attlist.Protocol">

+        <xs:attribute name="Name" use="required"/>

+        <xs:attribute name="Guid" use="required" type="xs:NMTOKEN"/>

+    </xs:attributeGroup>

+    <xs:element name="Private">

+        <xs:annotation>

+            <xs:documentation> The Private section is a place where the files are listed that should

+                not be seen by the users of this package. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType mixed="true">

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="File"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Public">

+        <xs:annotation>

+            <xs:documentation> The Public section is a list of files that are meant to be seen by

+                the users of the package. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType mixed="true">

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="File"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Contents">

+        <xs:annotation>

+            <xs:documentation>This is a list of all the files within this package. Each file is

+                identified by its path relative to the workspace root.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element maxOccurs="unbounded" ref="File"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="File">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Specify a filename including the path</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="xs:normalizedString">

+                    <xs:attributeGroup ref="attlist.File"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:attributeGroup name="attlist.File">

+        <xs:attribute name="Type"/>

+        <xs:attribute name="Desc"/>

+        <xs:attribute name="Size" type="xs:NMTOKEN"/>

+        <xs:attribute name="CDate" type="xs:NMTOKEN"/>

+        <xs:attribute name="CTime" type="xs:NMTOKEN"/>

+        <xs:attribute name="MDate" type="xs:NMTOKEN"/>

+        <xs:attribute name="MTime" type="xs:NMTOKEN"/>

+        <xs:attribute name="ADate" type="xs:NMTOKEN"/>

+        <xs:attribute name="ATime" type="xs:NMTOKEN"/>

+        <xs:attribute name="Checksum" type="xs:NMTOKEN"/>

+    </xs:attributeGroup>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/FrameworkDataAttributes.xsd b/edk2/Tools/XMLSchema/FrameworkDataAttributes.xsd
new file mode 100644
index 0000000..4ed390e
--- /dev/null
+++ b/edk2/Tools/XMLSchema/FrameworkDataAttributes.xsd
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://www.TianoCore.org/2006/Edk2.0" targetNamespace="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: FrameworkDataAttributes.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:annotation>

+        <xs:documentation xml:lang="en">This schema defines EFI and Framework Attribute. Only attributeGroups are specified in this file. </xs:documentation>

+    </xs:annotation>

+    <xs:include schemaLocation="NamingConvention.xsd"/>

+    <xs:include schemaLocation="FrameworkDataTypes.xsd"/>

+    <xs:attributeGroup name="BaseNameAttributes">

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="BootModeAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="BootModeName" type="BootModeNames" use="required"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="BootModeUsage" use="required"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="ConvertAttributeString">

+        <xs:attribute name="OutputFilename" type="FileNameConvention" use="optional"/>

+        <xs:attribute name="SourceString" type="xs:string" use="optional"/>

+        <xs:attribute default="Unicode" name="OutputFiletype" type="xs:string" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="DataHubAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="DataHubUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="DirectoryAttributes">

+        <xs:attribute name="Separator" type="ToothPick"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="EventAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="EventGroup" type="EventTypes" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="EventUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="ExternAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="ExternUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="FilenameAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <!-- LAH Does a Filename need to have FeatureFlag Attribute? -->

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="FileType" type="xs:string" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Path" type="DirectoryNamingConvention" use="optional"/>

+        <xs:attribute name="ToolChain" type="ToolChains" use="optional"/>

+        <xs:attribute name="Usage" type="FileNameUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="FormsetAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="FormSetUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="GuidAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Usage" type="GuidUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="HobAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="HobType" type="HobTypes" use="required"/>

+        <xs:attribute default="true" name="HobEnabled" type="xs:boolean" use="optional"/>

+        <xs:attribute name="Usage" type="HobUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="IncludeAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="Class" type="BaseNameConvention" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <!-- LAH Does a Include need to have FeatureFlag Attribute? -->

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="ModuleType" type="ModuleTypeDef" use="optional"/>

+        <xs:attribute name="Path" type="DirectoryNamingConvention" use="optional"/>

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="LibraryAttributes">

+        <!-- LibraryAttributes is used for Libraries -> Library elements in FPD files -->

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <!-- LAH Does a LibraryInstance need to have FeatureFlag Attribute? -->

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <!-- DO NOT USE remove Guid from use, Start using ModuleGuid instead -->

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <!-- DO NOT USE remove ClassGuid from use, Start using LibraryClassGuid instead -->

+        <xs:attribute name="ClassGuid" type="GuidType" use="optional"/>

+        <!-- DO NOT USE remove LibraryGuid from use, Start using ModuleGuid instead -->

+        <xs:attribute name="LibraryGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="LibraryClass" type="BaseNameConvention" use="optional"/>

+        <xs:attribute name="LibraryClassGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="ModuleGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="ModuleVersion" type="VersionDataType" use="optional"/>

+        <!-- DO NOT USE remove Package from use, Start using PackageName instead -->

+        <xs:attribute name="Package" type="xs:string" use="optional"/>

+        <xs:attribute name="PackageGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="PackageName" type="BaseNameConvention" use="optional"/>

+        <xs:attribute name="PackageVersion" type="VersionDataType" use="optional"/>

+        <xs:attribute name="Usage" type="LibraryUsage" use="optional"/>

+        <!-- DO NOT USE remove Version from use, Start using ModuleVersion instead -->

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="LibraryClassAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="RecommendedInstance" type="xs:NCName" use="optional"/>

+        <xs:attribute name="RecommendedInstanceGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="LibraryUsage" use="required"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="ModuleNameAttributes">

+        <xs:attribute name="Guid" type="GuidType" use="required"/>

+        <!-- DO NOT USE remove Guid from use, Start using ModuleGuid instead -->

+        <xs:attribute name="ModuleGuid" type="GuidType" use="required"/>

+        <xs:attribute name="ModuleVersion" type="VersionDataType" use="optional"/>

+        <!-- DO NOT USE remove Version from use, Start using ModuleVersion instead -->

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="ModuleNameSaAttributes">

+        <!-- DO NOT USE remove Guid from use, Start using ModuleGuid instead -->

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="ModuleGuid" type="GuidType" use="required"/>

+        <xs:attribute name="ModuleName" type="xs:NCName" use="required"/>

+        <xs:attribute name="ModuleVersion" type="VersionDataType" use="optional"/>

+        <!-- DO NOT USE remove Version from use, Start using ModuleVersion instead -->

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="MsaAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="BuildSequence" type="xs:int" use="optional"/>

+        <xs:attribute name="FvBinding" type="xs:string" use="optional"/>

+        <xs:attribute name="ModuleName" type="xs:NCName" use="optional"/>

+        <xs:attribute name="ModuleGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="PackageName" type="BaseNameConvention" use="optional"/>

+        <xs:attribute name="PackageGuid" type="GuidType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="OptionAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="BuildTarget" type="BuildTargets" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <!-- LAH Does an Option need to have FeatureFlag Attribute? -->

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Platform" type="PlatformNamingConvention" use="optional"/>

+        <xs:attribute name="ToolChain" type="ToolChains" use="optional"/>

+        <xs:attribute name="ToolChainTag" type="xs:NCName" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="PackageAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="PackageGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="PackageType" type="PackageType" use="optional"/>

+        <xs:attribute name="PackageVersion" type="xs:string" use="optional"/>

+        <xs:attribute name="UpdatedDate" type="DateType" use="optional"/>

+        <xs:attribute name="Usage" type="PackageUsage" use="optional"/>

+    </xs:attributeGroup>

+    <!-- PackageNameAttributres are only used in the Package Dependencies section of an SPD file. -->

+    <xs:attributeGroup name="PackageNameAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <!-- DO NOT USE remove Guid and start using PackageGuid instead -->

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="PackageGuid" type="GuidType" use="optional"/>

+        <!-- PackageTypeDepencency is used to identify if a SOURCE or BINARY PackageType is required, in case PackageGuid and/or PackageVersion are not tracked. -->

+        <xs:attribute name="PackageTypeDependency" type="PackageType" use="optional"/>

+        <xs:attribute name="PackageVersion" type="xs:string" use="optional"/>

+        <!-- DO NOT USE remove Version and start using PackageVersion instead -->

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="PcdAttributes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">These attributes are for the Pcds listed in PcdData, PcdEntry and/or PcdBuildData entries.</xs:documentation>

+            <xs:documentation xml:lang="en">PcdUsage is only valid for PcdItemTypes = FEATURE_FLAG</xs:documentation>

+            <xs:documentation xml:lang="en">Only NON FEATURE_FLAG PCDS should have the FeatureFlag attribute set.</xs:documentation>

+        </xs:annotation>

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="ItemType" type="PcdItemTypes" use="required"/>

+        <xs:attribute name="PcdUsage" type="PcdUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="PlatformAttributes">

+        <!-- DO NOT USE remove AlternateName from use -->

+        <xs:attribute name="AlternateName" type="FileNameConvention" use="optional"/>

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <!-- DO NOT USE remove Guid from use -->

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="PlatformName" type="PlatformNamingConvention" use="optional"/>

+        <xs:attribute name="PlatformGuid" type="GuidType" use="optional"/>

+        <xs:attribute name="PlatformVersion" type="xs:string" use="optional"/>

+        <!-- DO NOT USE remove Version and start using PlatformVersion instead -->

+        <xs:attribute name="Version" type="VersionDataType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="PpiAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="PpiUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="PpiNotifyAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="PpiNotifyUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="ProtocolAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="ProtocolUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="ProtocolNotifyAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="ProtocolNotifyUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="SectionAttributes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Attributes are either compressable and/or sequence order binding</xs:documentation>

+        </xs:annotation>

+        <xs:attribute name="BindingOrder" type="xs:int" use="optional"/>

+        <xs:attribute default="true" name="Compressible" type="xs:boolean" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <!-- LAH Does a Section need to have FeatureFlag Attribute? -->

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="SectionType" type="EfiSectionType" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="SectionsAttributes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Attributes for Sections, EncapsulationTag, EncapsulationType and FeatureFlag</xs:documentation>

+        </xs:annotation>

+        <xs:attribute name="EncapsulationType" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="EncapsulationTag" type="xs:string" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <!-- LAH Does a Filename need to have FeatureFlag Attribute? -->

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="SystemTableAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="SystemTableUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="UrlAttribute">

+        <xs:attribute name="Url" type="xs:anyURI"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="VariableAttributes">

+        <xs:attribute name="Arch" type="SupportedArchitectures" use="optional"/>

+        <xs:attribute name="ArchType" type="ArchList" use="optional"/>

+        <xs:attribute default="true" name="EnableFeature" type="xs:boolean" use="optional"/>

+        <xs:attribute name="FeatureFlag" type="xs:normalizedString" use="optional"/>

+        <xs:attribute name="Guid" type="GuidType" use="optional"/>

+        <xs:attribute name="Usage" type="VariableUsage" use="optional"/>

+        <!-- DO NOT USE remove OverrideID from use -->

+        <xs:attribute name="OverrideID" type="xs:int" use="optional"/>

+    </xs:attributeGroup>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/FrameworkDataElements.xsd b/edk2/Tools/XMLSchema/FrameworkDataElements.xsd
new file mode 100644
index 0000000..8136662
--- /dev/null
+++ b/edk2/Tools/XMLSchema/FrameworkDataElements.xsd
@@ -0,0 +1,1775 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://www.TianoCore.org/2006/Edk2.0" targetNamespace="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: FrameworkDataElements.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:annotation>

+        <xs:documentation xml:lang="en"> This schema defines EFI and Framework Data Elements </xs:documentation>

+    </xs:annotation>

+    <xs:include schemaLocation="NamingConvention.xsd"/>

+    <xs:include schemaLocation="FrameworkDataTypes.xsd"/>

+    <xs:include schemaLocation="FrameworkDataAttributes.xsd"/>

+    <xs:element name="Abstract">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Abstract is valid for all Description Files</xs:documentation>

+            <xs:documentation xml:lang="en">This section is required. This is a single sentence to describe the module and will be used in sample files as the abstract data in the header comment section.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="Sentence">

+                    <xs:attribute name="URL" type="xs:anyURI" use="optional"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="AntCmd">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a sub-element of AntTask</xs:documentation>

+            <xs:documentation xml:lang="en">This is an ant command that will be inserted into a biuld sequence. Since ant commands are valid XML statements, special care must be taken to use the correct tokens for reserved words and escape quote characters.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" name="Id" type="xs:int"/>

+                <xs:element name="ExecutionOrder">

+                    <xs:simpleType>

+                        <xs:list itemType="xs:normalizedString"/>

+                    </xs:simpleType>

+                </xs:element>

+            </xs:sequence>

+            <xs:attributeGroup ref="SectionAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="AntTask">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a sub-element of UserDefinedAntTasks</xs:documentation>

+            <xs:documentation xml:lang="en">Define a file that contains one or more ant tasks that are to be added into or replacing of sequences of build steps. These files will be called using the ant-call task on a file name. These files must be valid apache-ant formatted task files.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:choice>

+                <xs:element ref="AntCmd"/>

+                <xs:element ref="Filename"/>

+            </xs:choice>

+            <xs:attribute name="Id" type="xs:int" use="required"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="BaseName">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">BaseName is valid for all Description Files</xs:documentation>

+            <xs:documentation xml:lang="en"> We need to be able to permit different attributes for every basename </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="BaseNameConvention">

+                    <xs:attributeGroup ref="BaseNameAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="BootModes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">BootModes is valid for all Description Files</xs:documentation>

+            <xs:documentation xml:lang="en">This is a list of BootModes Supported by the Module</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="BootMode">

+                    <xs:complexType>

+                        <xs:attributeGroup ref="BootModeAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="BuildOptions">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">BuildOptions is valid for MBD and FPD files.</xs:documentation>

+            <xs:documentation xml:lang="en">Specific Build Options, by Tool Chain, than should be applied, overriding any global options</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" ref="UserDefinedAntTasks"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="ImageEntryPoint"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="OutputDirectory"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Ffs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Sections"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Filenames"/>

+                <xs:sequence minOccurs="0">

+                    <xs:element minOccurs="0" maxOccurs="unbounded" name="Option">

+                        <xs:complexType>

+                            <xs:simpleContent>

+                                <xs:extension base="xs:normalizedString">

+                                    <xs:attributeGroup ref="OptionAttributes"/>

+                                </xs:extension>

+                            </xs:simpleContent>

+                        </xs:complexType>

+                    </xs:element>

+                    <!-- Arch element should be removed - use Arch attributes to the above instead. -->

+                    <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                        <xs:complexType>

+                            <xs:sequence minOccurs="1">

+                                <xs:element maxOccurs="unbounded" name="Option">

+                                    <xs:complexType>

+                                        <xs:simpleContent>

+                                            <xs:extension base="xs:normalizedString">

+                                                <xs:attributeGroup ref="OptionAttributes"/>

+                                            </xs:extension>

+                                        </xs:simpleContent>

+                                    </xs:complexType>

+                                </xs:element>

+                            </xs:sequence>

+                            <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                        </xs:complexType>

+                    </xs:element>

+                </xs:sequence>

+            </xs:sequence>

+            <xs:attribute name="ToolChain" type="ToolChains"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="C_Name" type="C_Name">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">C_Name is valid for all Description Files</xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="ComponentName" type="C_Name">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">ComponentName is valid for all Description Files</xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="ComponentType" type="FrameworkComponentTypes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describe the valid Framework Component Type</xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="ConditionalExpression">

+        <!-- DO NOT USE remove and use FeatureFlag instead -->

+        <xs:annotation>

+            <xs:documentation xml:lang="en">A conditional expression that must be evaluated to determine whether a feature is implemented or not. The expression must be either numeric, string or boolean.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" name="Condition" type="xs:normalizedString"/>

+            </xs:sequence>

+            <xs:attribute name="ConditionalTarget" type="ConditionalTarget" use="optional"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Constructor" type="C_Name"/>

+    <xs:element name="Copyright" type="Sentence"/>

+    <xs:element name="Created" type="DateType"/>

+    <xs:element name="CreatedDate" type="DateType"/>

+    <xs:element name="CreatedBy" type="UserName"/>

+    <xs:element name="DataHubs">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a list of DataHubRecord elements.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="DataHubRecord">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="xs:normalizedString">

+                                <xs:attributeGroup ref="DataHubAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <!-- Remove Arch and use Arch Attribute for DataHubRecord instead. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element name="DataHubRecord">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="xs:normalizedString">

+                                            <xs:attributeGroup ref="DataHubAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="DatabaseName">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">The Name of the Database, "FrameworkDatabase"</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="BaseNameConvention">

+                    <xs:attributeGroup ref="BaseNameAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="DefaultValue">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">The default setting of a PCD entry.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="xs:normalizedString"/>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Description" type="Paragraph">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This section is required for new modules and libraries and must contain more information than the Abstract.</xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="Destructor" type="C_Name"/>

+    <xs:element name="DriverBinding" type="C_Name"/>

+    <xs:element name="DriverConfig" type="C_Name"/>

+    <xs:element name="DriverDiag" type="C_Name"/>

+    <xs:element name="E-Mail" type="E-Mail"/>

+    <xs:element name="Events">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a list of Events</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" name="CreateEvents">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                            <xs:element name="Event">

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                                        <xs:choice minOccurs="0">

+                                            <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                            <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                                        </xs:choice>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="EventAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                            <!-- Remove Arch Section and use Arch Attribute instead in Event. -->

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element name="Event">

+                                            <xs:complexType>

+                                                <xs:sequence>

+                                                    <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                                                    <xs:choice minOccurs="0">

+                                                        <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                                        <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                                                    </xs:choice>

+                                                </xs:sequence>

+                                                <xs:attributeGroup ref="EventAttributes"/>

+                                            </xs:complexType>

+                                        </xs:element>

+                                    </xs:sequence>

+                                    <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="1" name="SignalEvents">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Module has an event that is waiting to be signaled. Event is named by GUID.</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                            <xs:element name="Event">

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                                        <xs:choice minOccurs="0">

+                                            <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                            <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                                        </xs:choice>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="EventAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                            <!-- Remove Arch and use Arch attribute in Event above -->

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element name="Event">

+                                            <xs:complexType>

+                                                <xs:sequence>

+                                                    <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                                                </xs:sequence>

+                                                <xs:attributeGroup ref="EventAttributes"/>

+                                            </xs:complexType>

+                                        </xs:element>

+                                    </xs:sequence>

+                                    <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ExitBootServicesCallBack" type="C_Name"/>

+    <xs:element name="Externs">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a child of MSA files, both Library and Module.</xs:documentation>

+            <xs:documentation xml:lang="en">This is a list of Extern statements, right now, only Driver Binding information is provided.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="1" name="PcdIsDriver" type="PcdDriverTypes"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Extern">

+                    <xs:complexType>

+                        <xs:choice minOccurs="1">

+                            <xs:sequence minOccurs="0" maxOccurs="1">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Driver Module</xs:documentation>

+                                </xs:annotation>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="ModuleEntryPoint"/>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="ModuleUnloadImage"/>

+                            </xs:sequence>

+                            <xs:sequence minOccurs="0" maxOccurs="1">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Library Module</xs:documentation>

+                                </xs:annotation>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Constructor"/>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Destructor"/>

+                            </xs:sequence>

+                            <xs:sequence minOccurs="0" maxOccurs="1">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Allow multiple entries for DriverBinding, ComponentName, DriverConfig and DriverDiag elements. For ComponentName, DriverConfig and/or DriverDiag - you must have a 1:1 mapping to DriverBinding if the element is defined.</xs:documentation>

+                                    <xs:documentation xml:lang="en">Permit User Defined Extern Tags</xs:documentation>

+                                </xs:annotation>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="DriverBinding"/>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="ComponentName"/>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="DriverConfig"/>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="DriverDiag"/>

+                            </xs:sequence>

+                            <xs:sequence minOccurs="0" maxOccurs="1">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en"> Module Call Backs</xs:documentation>

+                                </xs:annotation>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="SetVirtualAddressMapCallBack"/>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" ref="ExitBootServicesCallBack"/>

+                            </xs:sequence>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="UserDefined" type="C_Name"/>

+                        </xs:choice>

+                        <xs:attributeGroup ref="ExternAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Specification"/>

+                <!-- Remove Arch and use Arch Attribute in above. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element name="Extern">

+                                <xs:complexType>

+                                    <xs:choice minOccurs="1">

+                                        <xs:sequence minOccurs="0" maxOccurs="1">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en">Driver Module</xs:documentation>

+                                            </xs:annotation>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="ModuleEntryPoint"/>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="ModuleUnloadImage"/>

+                                        </xs:sequence>

+                                        <xs:sequence minOccurs="0" maxOccurs="1">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en">Library Module</xs:documentation>

+                                            </xs:annotation>

+                                            <xs:element minOccurs="0" maxOccurs="1" ref="Constructor"/>

+                                            <xs:element minOccurs="0" maxOccurs="1" ref="Destructor"/>

+                                        </xs:sequence>

+                                        <xs:sequence minOccurs="0" maxOccurs="1">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en">Allow multiple entries for DriverBinding, ComponentName, DriverConfig and DriverDiag elements. For ComponentName, DriverConfig and/or DriverDiag - you must have a 1:1 mapping to DriverBinding if the element is defined.</xs:documentation>

+                                                <xs:documentation xml:lang="en">Permit User Defined Extern Tags</xs:documentation>

+                                            </xs:annotation>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="DriverBinding"/>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="ComponentName"/>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="DriverConfig"/>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="DriverDiag"/>

+                                        </xs:sequence>

+                                        <xs:sequence minOccurs="0" maxOccurs="1">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en"> Module Call Backs</xs:documentation>

+                                            </xs:annotation>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="SetVirtualAddressMapCallBack"/>

+                                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="ExitBootServicesCallBack"/>

+                                        </xs:sequence>

+                                        <xs:element minOccurs="0" maxOccurs="unbounded" name="UserDefined" type="C_Name"/>

+                                    </xs:choice>

+                                    <xs:attributeGroup ref="ExternAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Ffs">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define the FFS File attributes within a sections and containing sections information</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Attribute">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Name" type="C_Name"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Value" type="C_Name"/>

+                        </xs:sequence>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Sections"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Filename">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describe the valid content of a filename</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="VariableConvention">

+                    <xs:attributeGroup ref="FilenameAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Filenames">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a list of Filenames</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Filename"/>

+                <!-- DO NOT USE Arch remove it element and use Arch Attribute to Filename instead -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1">

+                            <xs:element maxOccurs="unbounded" ref="Filename"/>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Formsets">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describe the list of a Formset elements</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="Formset">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Describe the valid content of a Formset</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="FormsetAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE! removing Arch element, use Arch attribute in Formset instead. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element name="Formset">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Describe the valid content of a Formset</xs:documentation>

+                                </xs:annotation>

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="C_Name">

+                                            <xs:attributeGroup ref="FormsetAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Guid">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describe the valid content of a GUID</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="GuidType">

+                    <xs:attributeGroup ref="GuidAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="GuidDeclarations">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" name="Entry">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:choice minOccurs="1">

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                            </xs:choice>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="FeatureFlag" type="C_Name"/>

+                        </xs:sequence>

+                        <xs:attribute name="Name" type="xs:normalizedString" use="required"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Guids">

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="GuidEntry">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Describe the valid content of a PCD GUID element</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence minOccurs="0" maxOccurs="1">

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="FeatureFlag" type="C_Name"/>

+                            <!-- DO NOT USE remove ConditionalExpression and use FeatureFlag instead -->

+                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="ConditionalExpression"/>

+                            <xs:element minOccurs="0" maxOccurs="1" ref="DefaultValue"/>

+                            <xs:element minOccurs="0" maxOccurs="1" ref="HelpText"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="GuidAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE Arch, Arch should be removed and the attribute Arch should be used in the above. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element name="GuidEntry">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Describe the valid content of a PCD GUID element</xs:documentation>

+                                </xs:annotation>

+                                <xs:complexType>

+                                    <xs:sequence minOccurs="0" maxOccurs="1">

+                                        <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                                        <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                                        <xs:element minOccurs="0" maxOccurs="unbounded" name="FeatureFlag" type="C_Name"/>

+                                        <!-- DO NOT USE remove ConditionalExpression and use FeatureFlag instead -->

+                                        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ConditionalExpression"/>

+                                        <xs:element minOccurs="0" maxOccurs="1" ref="DefaultValue"/>

+                                        <xs:element minOccurs="0" maxOccurs="1" ref="HelpText"/>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="GuidAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="GuidValue" type="GuidType"/>

+    <xs:element name="HelpText" type="Paragraph">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This section is used to describe how a GUID, PPI or PROTOCOL is to be used within the context of PCDs.</xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="Hobs">

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="Hob">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:normalizedString"/>

+                            <xs:element minOccurs="0" maxOccurs="1" ref="C_Name"/>

+                            <xs:choice minOccurs="0">

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                            </xs:choice>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="HobAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE Arch, use attribute Arch for Hob in above -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element name="Hob">

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:normalizedString"/>

+                                        <xs:element minOccurs="0" maxOccurs="1" ref="C_Name"/>

+                                        <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="HobAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ImageEntryPoint" type="C_Name"/>

+    <xs:element name="IncludeHeader">

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="FileNameConvention">

+                    <xs:attributeGroup ref="IncludeAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Includes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">One or More Package Names or Arch sections is required. Includes are not files, but paths to where header files are located.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="PackageName"/>

+                <!-- remove Arch element, start using the Arch attribute for the PackageName element above. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1">

+                            <xs:element maxOccurs="unbounded" ref="PackageName"/>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="IndustryStdHeaders">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" ref="IncludeHeader"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="InstalledDate" type="DateType"/>

+    <xs:element name="Libraries">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Different (Module) Instances of Libraries used ONLY in FPD Files.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Library">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="xs:NCName">

+                                <xs:attributeGroup ref="LibraryAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <!-- remove Arch Element HERE, start using the Arch attribute in Library element above. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:choice minOccurs="1" maxOccurs="unbounded">

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="Library">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="BaseNameConvention">

+                                            <xs:attributeGroup ref="LibraryAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:choice>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+                <!-- /remove Arch Element -->

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="LibraryClass">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Used in MSA files. This defines what class of library is being supported = produced (library module) or consumed by a module.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="BaseNameConvention">

+                    <xs:attributeGroup ref="LibraryClassAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="LibraryClassDeclaration">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This element defines a class of library, along with the path to the Include Header for this library</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="0">

+                <xs:element minOccurs="1" maxOccurs="1" name="LibraryClass">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Used in MSA and SPD files. This defines what class of library is being supported = produced (library module) or consumed by a module.</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="BaseNameConvention">

+                                <xs:attribute name="RecommendedInstance" type="xs:NCName" use="optional"/>

+                                <xs:attribute name="RecommendedInstanceGuid" type="GuidType" use="optional"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="1" maxOccurs="1" ref="IncludeHeader"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="LibraryClassDeclarations">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This section defines what Classes of Libraries that this library belongs to. A Library may belong to multiple different library classes.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType mixed="true">

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element ref="LibraryClassDeclaration"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="LibraryClassDefinitions">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This section defines what Classes of Library that this library supports. A Library may belong to multiple different library classes.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType mixed="true">

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element ref="LibraryClass"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="License">

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="Paragraph">

+                    <xs:attribute name="URL" type="xs:anyURI" use="optional"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Modified" type="DateType"/>

+    <xs:element name="ModifiedDate" type="DateType"/>

+    <xs:element name="Module">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is record format for a Module entry in the Framework Database file.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:annotation>

+                <xs:documentation xml:lang="en">This describes the fields in an Module record in the Framework Database. The Path field is relative to the workspace to Module Surface Area (MSA) files.</xs:documentation>

+            </xs:annotation>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="ModuleName"/>

+                <xs:choice minOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                </xs:choice>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Path"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ModuleEntryPoint" type="xs:normalizedString"/>

+    <xs:element name="ModuleList">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This tag is used in the Framework Package Database File to track package installation</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence maxOccurs="unbounded">

+                <xs:element minOccurs="1" maxOccurs="unbounded" ref="Module"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ModuleName">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is the valid content of a Module Name</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="xs:NCName">

+                    <xs:attributeGroup ref="ModuleNameAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ModuleType" type="ModuleTypeDef">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describe the valid EFI Phase that the Module is designed to execute under.</xs:documentation>

+        </xs:annotation>

+    </xs:element>

+    <xs:element name="ModuleUnloadImage" type="xs:normalizedString"/>

+    <xs:element name="MsaFiles">

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="MsaFile">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Surface Area Package Description (SPD) list of Module Surface Area files</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence minOccurs="0" maxOccurs="1">

+                            <xs:element minOccurs="0" ref="Filename"/>

+                            <xs:element minOccurs="0" ref="BuildOptions"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="MsaAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE Arch element, use attribute Arch in above. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1">

+                            <xs:element maxOccurs="unbounded" name="MsaFile">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Describe the valid content of a Surface Area Package Description (SPD) file</xs:documentation>

+                                </xs:annotation>

+                                <xs:complexType>

+                                    <xs:sequence minOccurs="0" maxOccurs="1">

+                                        <xs:element minOccurs="0" ref="Filename"/>

+                                        <xs:element minOccurs="0" ref="BuildOptions"/>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="MsaAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="MsaFileList">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Surface Area Package Description (SPD) list of Module Surface Area files</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Filename">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="xs:anyURI">

+                                <xs:attributeGroup ref="ModuleNameSaAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="MsaPcdDeclarations">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Child of Module Surface Area Description (MSA)</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element maxOccurs="unbounded" name="PcdEntry">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This is the valid content of the PCD table of a Module. The contents may not be wired at build time, and these only refer to Platform Build values, not modules.</xs:documentation>

+                        <xs:documentation xml:lang="en">This element is valid for PcdInfo.xml and FPD files.</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DefaultValue" type="DefaultValue"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="HelpText" type="Paragraph"/>

+                        </xs:sequence>

+                        <!-- MSA file declares a single usage, and must match one of the entries in what the SPD file declares as the set of possible Item Types. -->

+                        <xs:attribute name="PcdItemType" type="PcdItemTypes" use="required"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="OutputDirectory">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define where we want our output to go. The Attribute, IntermediateDirectories, default MODULE, says that intermediate files will be local to the module, versus a unified directory structure.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="DirectoryNamingConvention">

+                    <xs:attribute default="MODULE" name="IntermediateDirectories">

+                        <xs:simpleType>

+                            <xs:restriction base="UCNameType">

+                                <xs:enumeration value="MODULE"/>

+                                <xs:enumeration value="UNIFIED"/>

+                            </xs:restriction>

+                        </xs:simpleType>

+                    </xs:attribute>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PCDs">

+        <!-- PCDs section is going away to be replaced by something else TB Named later -->

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Child of Module Surface Area documents, MSA and MBD files, Library Modules and Other Modules</xs:documentation>

+            <xs:documentation xml:lang="en">One or more PcdData or PcdBuildData Elements Only one type is permitted</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element maxOccurs="unbounded" name="PcdData">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This is a child of PCDs and can occur in the MSA and MBD files.</xs:documentation>

+                        <xs:documentation xml:lang="en">This is date element is used in the Module Surface Area (MSA) file and contains references to be used by a Platform Build</xs:documentation>

+                        <xs:documentation xml:lang="en">There is ONE required Attribute, ItemType</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Token" type="HexDoubleWordDataType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="TokenSpaceGuid" type="GuidType"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumType" type="PcdDataTypes"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="HiiEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="VpdEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="AlternateNameSpaceEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="SkuEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="SkuDataArrayEnable" type="xs:boolean"/>

+                            <xs:element default="0x00" minOccurs="0" maxOccurs="1" name="MaxSku" type="HexByteDataType"/>

+                            <xs:element default="0x00" minOccurs="0" maxOccurs="1" name="SkuId" type="HexByteDataType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DatumSize">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Max Number of Bytes of the data.</xs:documentation>

+                                </xs:annotation>

+                                <xs:simpleType>

+                                    <xs:restriction base="xs:int">

+                                        <xs:minInclusive value="1"/>

+                                        <xs:maxInclusive value="16777215"/>

+                                    </xs:restriction>

+                                </xs:simpleType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="VariableName" type="xs:normalizedString"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="VariableGuid" type="VariableGuidType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DataOffset" type="Hex64BitDataType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="GuidOffset" type="Hex64BitDataType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DefaultValue" type="xs:normalizedString"/>

+                            <xs:element minOccurs="0" maxOccurs="1" ref="HelpText"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PcdAttributes"/>

+                        <xs:attribute name="PcdIsDriver" use="optional"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PackageDependencies">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This tag is used in the Package Surface Area Description File to track package dependencies for a module</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence maxOccurs="unbounded">

+                <xs:element minOccurs="1" maxOccurs="unbounded" ref="PackageName"/>

+            </xs:sequence>

+            <xs:attributeGroup ref="PackageNameAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PackageHeaders">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This defines the minimum header file needed to support a given ModuleType.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" ref="IncludeHeader"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PackageList">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This tag is used in the Framework Package Database File to track all packages installed in a workspace. (Database)</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence maxOccurs="unbounded">

+                <xs:element minOccurs="1" name="Package">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This tag is used in the Framework Package Database File to track individual package information. The Path is a relative path to the SPD File.</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence maxOccurs="unbounded">

+                            <xs:element minOccurs="0" maxOccurs="1" ref="PackageName"/>

+                            <xs:choice minOccurs="0">

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                <!-- DO NOT USE Guid should be removed, use PackageGuid instead -->

+                                <xs:element minOccurs="0" maxOccurs="1" name="PackageGuid" type="GuidType"/>

+                            </xs:choice>

+                            <xs:choice minOccurs="0">

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Version"/>

+                                <xs:element minOccurs="0" maxOccurs="1" name="PackageVersion" type="VersionDataType"/>

+                            </xs:choice>

+                            <xs:choice minOccurs="1">

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Path"/>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Filename"/>

+                            </xs:choice>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="InstalledDate"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PackageAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PackageName">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This tag is used in the Package Surface Area Description File to track package dependencies for a module (SPD) </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="BaseNameConvention">

+                    <xs:attributeGroup ref="PackageAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PackageType" type="PackageType"/>

+    <xs:element name="Path">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describe the valid content of a filename</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="DirectoryNamingConvention">

+                    <xs:attributeGroup ref="DirectoryAttributes"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PcdBuildDeclarations">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">NEW: Will become a child of ModuleSA in the FPD</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:choice minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="1" ref="Filename"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="PcdBuildData">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Child of PcdBuildDeclarations</xs:documentation>

+                        <xs:documentation xml:lang="en">This is date element is used in the platform build description file and contains valid data for a Platform Build</xs:documentation>

+                        <xs:documentation xml:lang="en">There is ONE required Attribute, ItemType</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Token">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This as a unique identifier defined for either this name space.</xs:documentation>

+                                    <xs:documentation xml:lang="en">The Target Attribute may be used to define a Target name space, such as PCI.</xs:documentation>

+                                </xs:annotation>

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="HexDoubleWordDataType">

+                                            <xs:attribute name="Target" type="C_Name" use="optional"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="TokenSpaceGuid" type="GuidType"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumType" type="PcdDataTypes">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This specifies the size of the Pcd Datum. It is either 8, 16, 32 or 64 bits for values, 1 bit for BOOLEAN and variable length for elements defined as VOID*</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="HiiEnable" type="xs:boolean">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This Bit means that the Variable data is associated with HII</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="VpdEnable" type="xs:boolean">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This bit enables the Vital Product Data area within flash for maintaining PCD information</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="AlternateNameSpaceEnable" type="xs:boolean">

+                                <xs:annotation>

+                                    <xs:documentation>This is only applicable to ItemType DYNAMIC_EX</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="SkuEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="SkuDataArrayEnable" type="xs:boolean"/>

+                            <xs:choice minOccurs="0">

+                                <xs:element minOccurs="0" maxOccurs="1" name="SkuDataArray">

+                                    <xs:annotation>

+                                        <xs:documentation xml:lang="en">This element is a list of two entries per line, the first should be an integer, while the second entry should be a string value</xs:documentation>

+                                    </xs:annotation>

+                                    <xs:simpleType>

+                                        <xs:list itemType="xs:normalizedString"/>

+                                    </xs:simpleType>

+                                </xs:element>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" name="SkuData">

+                                    <xs:annotation>

+                                        <xs:documentation xml:lang="en">This section is for a list of SkuData Elements, ID and Value</xs:documentation>

+                                    </xs:annotation>

+                                    <xs:complexType>

+                                        <xs:sequence minOccurs="1">

+                                            <xs:element name="Id" type="xs:int"/>

+                                            <xs:element name="Value" type="xs:normalizedString"/>

+                                        </xs:sequence>

+                                    </xs:complexType>

+                                </xs:element>

+                            </xs:choice>

+                            <xs:element default="0x00" minOccurs="1" maxOccurs="1" name="MaxSku" type="HexByteDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This value comes from a production line database, and has nothing to do with the number of SkuData IDs that have been defined.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="0x00" minOccurs="1" maxOccurs="1" name="SkuId" type="HexByteDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is the specific Sku ID for this build.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumSize">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Max Number of Bytes of the data.</xs:documentation>

+                                </xs:annotation>

+                                <xs:simpleType>

+                                    <xs:restriction base="xs:int">

+                                        <xs:minInclusive value="1"/>

+                                        <xs:maxInclusive value="16777215"/>

+                                    </xs:restriction>

+                                </xs:simpleType>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="VariableGuid" type="VariableGuidType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is the Variable's GUID if and only if HII is enabled.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="VariableName" type="xs:normalizedString">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is the C Name for the Variable, and is valid if and only HII is enabled.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="VariableValueDefault" type="xs:normalizedString"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DataOffset" type="Hex64BitDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">If HII is enabled, This is the offset into the variable data entry, If Vpd is enabled, then it's the Offset into the VPD area of the image defined by platform manufacturer, if neither HII nor Vpd are enabled, it's the offset into the PCD Data Area. HII and VPD can never be enabled at the same time (as of the date of this document.)</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="GuidOffset" type="Hex64BitDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">FIELD IS NOT USED! REMOVE in FINAL!</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DefaultValue" type="xs:normalizedString"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PcdAttributes"/>

+                        <xs:attribute name="PcdIsDriver">

+                            <xs:simpleType>

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is an enumerated data type that will be used for DYNAMIC_EX, PEIM or DXE only</xs:documentation>

+                                </xs:annotation>

+                                <xs:restriction base="UCNameType">

+                                    <xs:enumeration value="PEI_PCD_DRIVER"/>

+                                    <xs:enumeration value="DXE_PCD_DRIVER"/>

+                                </xs:restriction>

+                            </xs:simpleType>

+                        </xs:attribute>

+                    </xs:complexType>

+                </xs:element>

+            </xs:choice>

+        </xs:complexType>

+    </xs:element>

+    <!-- PcdBuildDeclarations -->

+    <xs:element name="PcdDynamicBuildDeclarations">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Child of Framework Platform Description (FPD)</xs:documentation>

+            <xs:documentation xml:lang="en">We permit the FPD to use an external XML file for PCD information or else the information must be contained within the XML data element, PcdBuildData.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="PcdBuildData">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Child of PcdBuildDeclarations</xs:documentation>

+                        <xs:documentation xml:lang="en">This is date element is used in the platform build description file and contains valid data for a Platform Build</xs:documentation>

+                        <xs:documentation xml:lang="en">There is ONE required Attribute, ItemType</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="TokenSpaceGuid" type="GuidType"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Token">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This as a unique identifier defined for either this name space.</xs:documentation>

+                                    <xs:documentation xml:lang="en">The Target Attribute may be used to define a Target name space, such as PCI.</xs:documentation>

+                                </xs:annotation>

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="HexDoubleWordDataType">

+                                            <xs:attribute name="Target" type="C_Name" use="optional"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="TokenSpaceGuid" type="GuidType"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumType" type="PcdDataTypes">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This specifies the size of the Pcd Datum. It is either 8, 16, 32 or 64 bits for values, 1 bit for BOOLEAN and variable length for elements defined as VOID*</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="HiiEnable" type="xs:boolean">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This Bit means that the Variable data is associated with HII</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="VpdEnable" type="xs:boolean">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This bit enables the Vital Product Data area within flash for maintaining PCD information</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="AlternateNameSpaceEnable" type="xs:boolean">

+                                <xs:annotation>

+                                    <xs:documentation>This is only applicable to ItemType DYNAMIC_EX</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="SkuEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="1" maxOccurs="1" name="SkuDataArrayEnable" type="xs:boolean"/>

+                            <xs:choice minOccurs="0">

+                                <xs:element minOccurs="0" maxOccurs="1" name="SkuDataArray">

+                                    <xs:annotation>

+                                        <xs:documentation xml:lang="en">This element is a list of two entries per line, the first should be an integer, while the second entry should be a string value</xs:documentation>

+                                    </xs:annotation>

+                                    <xs:simpleType>

+                                        <xs:list itemType="xs:normalizedString"/>

+                                    </xs:simpleType>

+                                </xs:element>

+                                <xs:element minOccurs="0" maxOccurs="unbounded" name="SkuData">

+                                    <xs:annotation>

+                                        <xs:documentation xml:lang="en">This section is for a list of SkuData Elements, ID and Value</xs:documentation>

+                                    </xs:annotation>

+                                    <xs:complexType>

+                                        <xs:sequence minOccurs="1">

+                                            <xs:element name="Id" type="xs:int"/>

+                                            <xs:element name="Value" type="xs:normalizedString"/>

+                                        </xs:sequence>

+                                    </xs:complexType>

+                                </xs:element>

+                            </xs:choice>

+                            <xs:element default="0x00" minOccurs="1" maxOccurs="1" name="MaxSku" type="HexByteDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This value comes from a production line database, and has nothing to do with the number of SkuData IDs that have been defined.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element default="0x00" minOccurs="1" maxOccurs="1" name="SkuId" type="HexByteDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is the specific Sku ID for this build.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumSize">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Max Number of Bytes of the data.</xs:documentation>

+                                </xs:annotation>

+                                <xs:simpleType>

+                                    <xs:restriction base="xs:int">

+                                        <xs:minInclusive value="1"/>

+                                        <xs:maxInclusive value="16777215"/>

+                                    </xs:restriction>

+                                </xs:simpleType>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="VariableGuid" type="VariableGuidType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is the Variable's GUID if and only if HII is enabled.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="VariableName" type="xs:normalizedString">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is the C Name for the Variable, and is valid if and only HII is enabled.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="VariableValueDefault" type="xs:normalizedString"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DataOffset" type="Hex64BitDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">If HII is enabled, This is the offset into the variable data entry, If Vpd is enabled, then it's the Offset into the VPD area of the image defined by platform manufacturer, if neither HII nor Vpd are enabled, it's the offset into the PCD Data Area. HII and VPD can never be enabled at the same time (as of the date of this document.)</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="GuidOffset" type="Hex64BitDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">FIELD IS NOT USED! REMOVE in FINAL!</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DefaultValue" type="xs:normalizedString"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PcdAttributes"/>

+                        <xs:attribute name="PcdIsDriver">

+                            <xs:simpleType>

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is an enumerated data type that will be used for DYNAMIC_EX, PEIM or DXE only</xs:documentation>

+                                </xs:annotation>

+                                <xs:restriction base="UCNameType">

+                                    <xs:enumeration value="PEI_PCD_DRIVER"/>

+                                    <xs:enumeration value="DXE_PCD_DRIVER"/>

+                                </xs:restriction>

+                            </xs:simpleType>

+                        </xs:attribute>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PcdDeclarations">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Child of Package Surface Area Description (SPD)</xs:documentation>

+            <xs:documentation xml:lang="en">This permits entering information about a package's PCD information</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element maxOccurs="unbounded" name="PcdEntry">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This is the valid content of the PCD table of a Module. The contents may not be wired at build time, and these only refer to Platform Build values, not modules.</xs:documentation>

+                        <xs:documentation xml:lang="en">This element is valid for PcdInfo.xml and FPD files.</xs:documentation>

+                        <xs:documentation xml:lang="en">There is ONE required Attribute, ItemType</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Token" type="Token"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="TokenSpaceGuid" type="GuidType"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumType" type="PcdDataTypes"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="ValidUsage" type="PcdListType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DefaultValue" type="DefaultValue"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="HelpText" type="Paragraph"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PcdAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <!-- DO NOT USE removing PcdDefinitions, use PcdDeclarations for SPD entries  Use PcdBuildDeclarations for MSA Entires and PcdDynamicBuildDeclarations for FPD Entries -->

+    <xs:element name="PcdDefinitions">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Child of Package Surface Area Description (SPD)</xs:documentation>

+            <xs:documentation xml:lang="en">This permits entering information about a package's PCD information</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element maxOccurs="unbounded" name="PcdEntry">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This is the valid content of the PCD table of a Module. The contents may not be wired at build time, and these only refer to Platform Build values, not modules.</xs:documentation>

+                        <xs:documentation xml:lang="en">This element is valid for PcdInfo.xml and FPD files.</xs:documentation>

+                        <xs:documentation xml:lang="en">There is ONE required Attribute, ItemType</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="Token" type="Token"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="TokenSpaceGuid" type="GuidType"/>

+                            <xs:element minOccurs="1" maxOccurs="1" name="DatumType" type="PcdDataTypes"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="HiiEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="VpdEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="AlternateNameSpaceEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="SkuEnable" type="xs:boolean"/>

+                            <xs:element default="false" minOccurs="0" maxOccurs="1" name="SkuDataArrayEnable" type="xs:boolean"/>

+                            <xs:element default="0x00" minOccurs="0" maxOccurs="1" name="MaxSku" type="HexByteDataType"/>

+                            <xs:element default="0x00" minOccurs="0" maxOccurs="1" name="SkuId" type="HexByteDataType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DatumSize">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">Max Number of Bytes of the data.</xs:documentation>

+                                </xs:annotation>

+                                <xs:simpleType>

+                                    <xs:restriction base="xs:int">

+                                        <xs:minInclusive value="1"/>

+                                        <xs:maxInclusive value="16777215"/>

+                                    </xs:restriction>

+                                </xs:simpleType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="VariableName" type="xs:normalizedString"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="VariableGuid" type="VariableGuidType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DataOffset" type="Hex64BitDataType"/>

+                            <xs:element default="0" minOccurs="0" maxOccurs="1" name="GuidOffset" type="Hex64BitDataType"/>

+                            <xs:element minOccurs="0" maxOccurs="1" name="DefaultValue" type="DefaultValue"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="PcdAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Platform">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Database Entry to locate the Platform Build Tips - path to FPD file.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" name="PlatformName">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">Define the Name of a Platform</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="PlatformNamingConvention">

+                                <xs:attributeGroup ref="PlatformAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:choice minOccurs="0">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Path"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Filename"/>

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="InstalledDate"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="ModifiedDate"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="AlternatePcdFile" type="FileNameConvention"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="AlternateFdfFile" type="FileNameConvention"/>

+            </xs:sequence>

+            <xs:attributeGroup ref="PlatformAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PpiDeclarations">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" name="Entry">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:choice>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                            </xs:choice>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="FeatureFlag" type="xs:normalizedString"/>

+                        </xs:sequence>

+                        <xs:attribute name="Name" type="xs:normalizedString" use="required"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PPIs">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Provide for one or more Ppi or PpiNotify sections. </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Ppi">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="PpiAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="PpiNotify">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="PpiNotifyAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE Arch element, use Arch Attribute in above instead. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="Ppi">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="C_Name">

+                                            <xs:attributeGroup ref="PpiAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="PpiNotify">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="C_Name">

+                                            <xs:attributeGroup ref="PpiNotifyAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ProtocolDeclarations">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" name="Entry">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="C_Name"/>

+                            <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="FeatureFlag" type="C_Name"/>

+                        </xs:sequence>

+                        <xs:attribute name="Name" type="xs:normalizedString" use="required"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Protocols">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">If either Protocol or ProtocolNotify sections are needed, one or more of them should be specified within this section</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Protocol">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="ProtocolAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="ProtocolNotify">

+                    <xs:complexType>

+                        <xs:simpleContent>

+                            <xs:extension base="C_Name">

+                                <xs:attributeGroup ref="ProtocolNotifyAttributes"/>

+                            </xs:extension>

+                        </xs:simpleContent>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE! removing Arch element, use Arch attribute of Protocol or ProtocolNotify instead. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="Protocol">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="C_Name">

+                                            <xs:attributeGroup ref="ProtocolAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="unbounded" name="ProtocolNotify">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="C_Name">

+                                            <xs:attributeGroup ref="ProtocolNotifyAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element default="false" name="ReadOnly" type="xs:boolean"/>

+    <xs:element default="false" name="RePackage" type="xs:boolean"/>

+    <xs:element name="Sections">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Sections refers to the Firmware Filesystem sections, PE32, UI, VER, DXS, etc. and how they are made</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Section">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="0" ref="Filenames"/>

+                            <xs:element minOccurs="0" name="Args" type="ArgsType"/>

+                            <xs:element minOccurs="0" name="OutFile" type="FileNameConvention"/>

+                            <xs:element minOccurs="0" name="OutputFileExtension" type="xs:string"/>

+                            <xs:element minOccurs="0" name="ToolName" type="ToolType"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="SectionAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Sections">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                            <xs:element name="Section">

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element minOccurs="0" ref="Filenames"/>

+                                        <xs:element minOccurs="0" name="Args" type="ArgsType"/>

+                                        <xs:element minOccurs="0" name="OutFile" type="FileNameConvention"/>

+                                        <xs:element minOccurs="0" name="OutputFileExtension" type="xs:string"/>

+                                        <xs:element minOccurs="0" name="ToolName" type="ToolType"/>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="SectionAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="SectionsAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+            <xs:attributeGroup ref="SectionsAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="SetVirtualAddressMapCallBack" type="C_Name"/>

+    <xs:element name="SourceFiles">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Multiple Filenames may be specified, and they may also be scoped to a specific Architecture.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Filename"/>

+                <!-- DO NOT USE! removing Arch element, use Arch Attribute of Filename instead.  -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="1">

+                            <xs:element maxOccurs="unbounded" ref="Filename"/>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Specification">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This string is used to provide the name and version of the Specification that the component conforms to.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="xs:normalizedString">

+                    <xs:attribute name="Version" type="xs:normalizedString" use="optional"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="SystemTables">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is list of System Table elements.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="SystemTable">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="0" maxOccurs="1" name="Entry" type="xs:normalizedString"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="SystemTableAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Updated" type="DateType"/>

+    <xs:element name="UpdatedDate" type="DateType"/>

+    <xs:element name="URL" type="xs:anyURI"/>

+    <xs:element name="URI" type="xs:anyURI"/>

+    <xs:element name="UserDefinedAntTasks">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is a sub-element of BuildOptions</xs:documentation>

+            <xs:documentation xml:lang="en">Permit Users to define their own custom ANT tasks.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence maxOccurs="unbounded">

+                <xs:element minOccurs="1" ref="AntTask"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Variables">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">A list of EFI Variables described by GUID string pair.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element name="Variable">

+                    <xs:annotation>

+                        <xs:documentation xml:lang="en">This is an EFI Variable Entry</xs:documentation>

+                    </xs:annotation>

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="1" name="String" type="xs:normalizedString"/>

+                            <xs:choice minOccurs="1">

+                                <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                                <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                            </xs:choice>

+                            <xs:element minOccurs="0" maxOccurs="1" name="ByteOffset" type="HexWordDataType">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This entry represents the Hex Byte Offset {0x0, 0xn} to where the data starts.</xs:documentation>

+                                </xs:annotation>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="BitOffset">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This entry represents the Location of the Starting Bit {0,8} of the start of Data. A value of zero or 1 indicates that there is no BitOffset into the byte.</xs:documentation>

+                                </xs:annotation>

+                                <xs:simpleType>

+                                    <xs:restriction base="xs:int">

+                                        <xs:minInclusive value="0"/>

+                                        <xs:maxInclusive value="8"/>

+                                    </xs:restriction>

+                                </xs:simpleType>

+                            </xs:element>

+                            <xs:element minOccurs="0" maxOccurs="1" name="OffsetBitSize">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This number represents the number of bits to use {0, 7} starting at the BitOffset. A value of 0 indicates that the entire Byte should be used.</xs:documentation>

+                                </xs:annotation>

+                                <xs:simpleType>

+                                    <xs:restriction base="xs:int">

+                                        <xs:minInclusive value="0"/>

+                                        <xs:maxInclusive value="7"/>

+                                    </xs:restriction>

+                                </xs:simpleType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="VariableAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <!-- DO NOT USE Arch element, use attribute Arch in above. -->

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Arch">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element name="Variable">

+                                <xs:annotation>

+                                    <xs:documentation xml:lang="en">This is an EFI Variable Entry</xs:documentation>

+                                </xs:annotation>

+                                <xs:complexType>

+                                    <xs:sequence>

+                                        <xs:element minOccurs="1" maxOccurs="1" name="String" type="xs:normalizedString"/>

+                                        <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                                        <xs:element minOccurs="0" maxOccurs="1" name="ByteOffset" type="HexWordDataType">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en">This entry represents the Hex Byte Offset {0x0, 0xn} to where the data starts.</xs:documentation>

+                                            </xs:annotation>

+                                        </xs:element>

+                                        <xs:element minOccurs="0" maxOccurs="1" name="BitOffset">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en">This entry represents the Location of the Starting Bit {0,8} of the start of Data. A value of zero or 1 indicates that there is no BitOffset into the byte.</xs:documentation>

+                                            </xs:annotation>

+                                            <xs:simpleType>

+                                                <xs:restriction base="xs:int">

+                                                    <xs:minInclusive value="0"/>

+                                                    <xs:maxInclusive value="8"/>

+                                                </xs:restriction>

+                                            </xs:simpleType>

+                                        </xs:element>

+                                        <xs:element minOccurs="0" maxOccurs="1" name="OffsetBitSize">

+                                            <xs:annotation>

+                                                <xs:documentation xml:lang="en">This number represents the number of bits to use {0, 7} starting at the BitOffset. A value of 0 indicates that the entire Byte should be used.</xs:documentation>

+                                            </xs:annotation>

+                                            <xs:simpleType>

+                                                <xs:restriction base="xs:int">

+                                                    <xs:minInclusive value="0"/>

+                                                    <xs:maxInclusive value="7"/>

+                                                </xs:restriction>

+                                            </xs:simpleType>

+                                        </xs:element>

+                                    </xs:sequence>

+                                    <xs:attributeGroup ref="VariableAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                        <xs:attribute name="ArchType" type="SupportedArchitectures"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Version" type="xs:normalizedString"/>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/FrameworkDataTypes.xsd b/edk2/Tools/XMLSchema/FrameworkDataTypes.xsd
new file mode 100644
index 0000000..8199df0
--- /dev/null
+++ b/edk2/Tools/XMLSchema/FrameworkDataTypes.xsd
@@ -0,0 +1,1048 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://www.TianoCore.org/2006/Edk2.0" targetNamespace="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: FrameworkDataTypes.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:annotation>

+        <xs:documentation xml:lang="en">This schema defines EFI and Framework Data Types. Only simpleType are specified in this file. </xs:documentation>

+    </xs:annotation>

+    <xs:include schemaLocation="NamingConvention.xsd"/>

+    <xs:simpleType name="ArchList">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">A list of one or more: IA32, X64, IPF and/or EBC</xs:documentation>

+        </xs:annotation>

+        <xs:list itemType="SupportedArchitectures"/>

+    </xs:simpleType>

+    <xs:simpleType name="BlockNameType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">FIRMWARE: Define a block name to be BLOCK[A-F0-9]{2}</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:pattern value="BLOCK([A-F0-9]){2}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="BootModeNames">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes what boot modes can be set (produced) or what boot modes can be supported, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="FULL">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_WITH_FULL_CONFIGURATION</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="MINIMAL">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_WITH_MINIMAL_CONFIGURATION</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="NO_CHANGE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_ASSUMING_NO_CONFIGURATION_CHANGES</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DIAGNOSTICS">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_WITH_DEFAULT_SETTINGS</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="S2_RESUME">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_ON_S2_RESUME</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="S3_RESUME">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_ON_S3_RESUME</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="S4_RESUME">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_ON_S4_RESUME</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="S5_RESUME">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_ON_S5_RESUME</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="FLASH_UPDATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_ON_FLASH_UPDATE</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="RECOVERY">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">BOOT_IN_RECOVERY_MODE</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="BootModeUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Boot Mode Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Supports the Boot Mode</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Supports the Boot Mode on some execution path</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Always changes the Boot Mode</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Sometimes changes the Boot Mode</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="BuildTargets">

+        <xs:restriction base="xs:NCName">

+            <xs:enumeration value="DEBUG"/>

+            <xs:enumeration value="RELEASE"/>

+            <xs:enumeration value="BOTH"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ComponentExecutionPhase">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">These are the supported EFI/Framework Execution Phases</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="MDE"/>

+            <xs:enumeration value="SEC"/>

+            <xs:enumeration value="PEI_CORE"/>

+            <xs:enumeration value="PEIM"/>

+            <xs:enumeration value="DXE_CORE"/>

+            <xs:enumeration value="DXE_DRIVER"/>

+            <xs:enumeration value="DXE_RUNTIME_DRIVER"/>

+            <xs:enumeration value="DXE_SAL_DRIVER"/>

+            <xs:enumeration value="DXE_SMM_DRIVER"/>

+            <xs:enumeration value="UEFI"/>

+            <xs:enumeration value="UEFI_APPLICATION"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ConditionalTarget">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Conditional Targets are Other FeatureFlag Identifiers</xs:documentation>

+        </xs:annotation>

+        <xs:list itemType="C_Name"/>

+    </xs:simpleType>

+    <xs:simpleType name="DataHubUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Data Hub Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The module always consumes a data hub entry via registering a filter driver.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The module will use a data hub entry if it exists via registering a filter driver.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The module always logs data into the data hub.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The module will log data into the data hub under certain circumstances</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">DataHub is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="DateType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Date Format is YYYY-MM-DD HH:MM (24hr time format)</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:normalizedString">

+            <xs:pattern value="[1-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="DefaultValue">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> The DefaultValue is a union of a string and an integer. </xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="xs:normalizedString xs:int UnicodeString"/>

+    </xs:simpleType>

+    <xs:simpleType name="EfiSectionType">

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="EFI_SECTION_FREEFORM_SUBTYPE_GUID"/>

+            <xs:enumeration value="EFI_SECTION_VERSION"/>

+            <xs:enumeration value="EFI_SECTION_USER_INTERFACE"/>

+            <xs:enumeration value="EFI_SECTION_DXE_DEPEX"/>

+            <xs:enumeration value="EFI_SECTION_PEI_DEPEX"/>

+            <xs:enumeration value="EFI_SECTION_PE32"/>

+            <xs:enumeration value="EFI_SECTION_PIC"/>

+            <xs:enumeration value="EFI_SECTION_TE"/>

+            <xs:enumeration value="EFI_SECTION_RAW"/>

+            <xs:enumeration value="EFI_SECTION_COMPRESSION"/>

+            <xs:enumeration value="EFI_SECTION_GUID_DEFINED"/>

+            <xs:enumeration value="EFI_SECTION_COMPATIBILITY16"/>

+            <xs:enumeration value="EFI_SECTION_FIRMWARE_VOLUME_IMAGE"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="EventTypes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Supported Event Groups, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="EVENT_GROUP_EXIT_BOOT_SERVICES"/>

+            <xs:enumeration value="EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE"/>

+            <xs:enumeration value="EVENT_GROUP_MEMORY_MAP_CHANGE"/>

+            <xs:enumeration value="EVENT_GROUP_READY_TO_BOOT"/>

+            <xs:enumeration value="EVENT_GROUP_LEGACY_BOOT"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="EventUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Event Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">A module registers a notification function and requires it to be executed for the module to fully function.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">A module registers a notification function and utilizes it if it's signaled.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">A module will always signal the event.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">A module will sometimes signal the event.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Event is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ExecutionType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This defines the output types: Relocatable (REL,) Non-Relocatable (NREL,) Execute in Place (XIP) or Position Independent Code (PIC) </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="REL" id="Relocatable"/>

+            <xs:enumeration value="NREL" id="Non-Relocatable"/>

+            <xs:enumeration value="XIP" id="Execute_In_Place"/>

+            <xs:enumeration value="PIC" id="Position_Independent_Code"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ExternType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">C Identifier Name for the Extern data as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="(_*\w*\W*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ExternUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Extern Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The EXTERN is always imported by the module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The EXTERN is always exported by the module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FileNameUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the FileName Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module requires a file named GUID in an FV</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will use a file named GUID in an FV if it is present</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module Always produces a file named GUID in an FV</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module sometimes produces a file named GUID in an FV</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Filename is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FormSetUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Formset Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The Formset is always registered into HII by the module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Some execution paths through the modules register forms into HII</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Formset is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FrameworkComponentTypes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> These are the EFI/Framework Component Types defined in the EFI Development Kit (EDK) Getting Started Guide </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="APRIORI"/>

+            <xs:enumeration value="SEC"/>

+            <xs:enumeration value="LIBRARY"/>

+            <xs:enumeration value="FV_IMAGE_FILE"/>

+            <xs:enumeration value="BS_DRIVER"/>

+            <xs:enumeration value="RT_DRIVER"/>

+            <xs:enumeration value="SAL_RT_DRIVER"/>

+            <xs:enumeration value="PE32_PEIM"/>

+            <xs:enumeration value="PIC_PEIM"/>

+            <xs:enumeration value="COMBINED_PEIM_DRIVER"/>

+            <xs:enumeration value="PEI_CORE"/>

+            <xs:enumeration value="DXE_CORE"/>

+            <xs:enumeration value="APPLICATION"/>

+            <xs:enumeration value="BS_DRIVER_EFI"/>

+            <xs:enumeration value="SHELLAPP"/>

+            <xs:enumeration value="UEFI_APPLICATION"/>

+            <xs:enumeration value="BINARY"/>

+            <xs:enumeration value="LOGO"/>

+            <xs:enumeration value="CUSTOM_BUILD"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FvRegionTypes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">FIRMWARE: Pre-defined Firmware Volume Region Types</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="FV_MAIN"/>

+            <xs:enumeration value="FV_MAIN_COMPACT"/>

+            <xs:enumeration value="NV_STORAGE"/>

+            <xs:enumeration value="FV_RECOVERY"/>

+            <xs:enumeration value="FV_RECOVERY_FLOPPY"/>

+            <xs:enumeration value="FV_FILE"/>

+            <xs:enumeration value="CAPSULE_CARGO"/>

+            <xs:enumeration value="NULL"/>

+            <xs:enumeration value="USER_DEFINED"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="GuidUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Guid Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module always consumes the GUID</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will consume the GUID only if the GUID is present</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will always produce the GUID</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module sometimes produces the GUID</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The default is the GUID that specifies the instance of the package</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Guid is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HobTypes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Type of HOB that is being produced or consumed, as specified in the Module Surface Area Specification.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="PHIT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_HANDOFF</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="MEMORY_ALLOCATION">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_MEMORY_ALLOCATION Note: The BaseName of the GUID is also required</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="RESOURCE_DESCRIPTOR">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_RESOURCE_DESCRIPTOR</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="GUID_EXTENSION">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_GUID_EXTENSION Note: The BaseName of the GUID is also required.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="FIRMWARE_VOLUME">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_FV</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="CPU">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_CPU</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="POOL">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_PEI_MEMORY_POOL</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="CAPSULE_VOLUME">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">EFI_HOB_TYPE_CV</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HobUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Hob Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The HOB must be present in the system</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The HOB will be used if it's present in the system</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The HOB is always produced by the module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The HOB will sometimes be produced by the module.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">HOB is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="LibraryUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Library Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">A module always consumes the library. This Guid represents the class of the library.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED"/>

+            <xs:enumeration value="ALWAYS_PRODUCED"/>

+            <xs:enumeration value="SOMETIMES_PRODUCED"/>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The default is the GUID that specifies the instance of the library.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Library is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ModuleTypeDef">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> These are the supported Framework Module Types </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="BASE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module only depends on things in the MDE package and is environment neutral</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SEC">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is the Security Section and depends on catching the reset vectory</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PEI_CORE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is the PEI Core</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PEIM">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a PEIM and depends on the PEI Services Table</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DXE_CORE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is the DXE Core</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DXE_DRIVER">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a DXE Driver and depends on the EFI Boot Services, EFI Runtime Services and the DXE Service Table</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DXE_RUNTIME_DRIVER">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a DXE Driver and depends on the EFI Boot Services, EFI Runtime Services and the DXE Service Table. The module runs after ExitBootServices and produces CreateEvent EventGroupExitBootServices and EventGroupVirtualAddressChange. Code written in this module can run in physical or virtual mode.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DXE_SAL_DRIVER">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a DXE Driver and depends on the EFI Boot Services, EFI Runtime Services and the DXE Service Table. The module runs after ExitBootServices and produces CreateEvent EventGroupExitBootServices and EventGroupVirtualAddressChange. Code written in this module can run in physical AND in virtual mode.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DXE_SMM_DRIVER">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a DXE Driver and depends on the EFI Boot Services, EFI Runtime Services and the DXE Service Table. The module also runs in SMM mode and depends on the SMM Service Table. </xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="TOOLS">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The TOOLS ModuleType is to be used for Tiano Tools modules</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="UEFI_DRIVER">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a UEFI Driver and depends on the EFI and Service Tables.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="UEFI_APPLICATION">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module is a UEFI Applciation and depens on the EFI and Service Tables.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="USER_DEFINED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module does not fit into other classifications. The user must have an apriori knowledge of its Usage, and must provide that information to others using this module.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Module_Unified">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a flag to determine whether to put intermediate build files into a directory under the Module, or into a unified tree under the package or platform build trees</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="MODULE"/>

+            <xs:enumeration value="UNIFIED"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PackageType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Packages are either source, binary or mixed packages.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="SOURCE"/>

+            <xs:enumeration value="BINARY"/>

+            <xs:enumeration value="MIXED"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PackageUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Package Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">A module always consumes a package. This GUID represents the class of the package.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">This is the Package we are creating. This GUID represents the class of the package.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The default is the GUID that specifies the instance of the package.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PcdListType">

+        <xs:list itemType="PcdItemTypes"/>

+    </xs:simpleType>

+    <xs:simpleType name="PcdTypes">

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="FIXED_AT_BUILD">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is only a build time option and cannot be Dyanmic or Binary patched into the module.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="FEATURE_FLAG"/>

+            <xs:enumeration value="PATCHABLE_IN_MODULE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is set to a default value at build time and a binary of the module can be patched to update the value.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DYNAMIC">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is found via a PCD PPI in PEI or a PCD Protocol in DXE. The token that matches the PCD entry is either generated by the build (and is only unique to that build) or is from the default database. This form also implies a build option will be produced for this module that allows the user to pick FixedAtBuild, PatchableInModule or Dynamic. If no Type is specified, it defaults to Dynamic</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DYNAMIC_EX">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is found via a PCD PPI in PEI or a PCD Protocol in DXE. The token that matches the PCD entry is either generated by the build (and is only unique to that build) or is from the default database. This form also implies a build option will be produced for this module that allows the user to pick FixedAtBuild, PatchableInModule or Dynamic. If no Type is specified, it defaults to Dynamic</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PcdDriverTypes">

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="PEI_PCD_DRIVER"/>

+            <xs:enumeration value="DXE_PCD_DRIVER"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PcdDataTypes">

+        <xs:restriction base="xs:normalizedString">

+            <xs:enumeration value="UINT8"/>

+            <xs:enumeration value="UINT16"/>

+            <xs:enumeration value="UINT32"/>

+            <xs:enumeration value="UINT64"/>

+            <xs:enumeration value="VOID*"/>

+            <xs:enumeration value="BOOLEAN"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PcdFeatureFlagUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the PCD FEATURE_FLAG Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UsageTypes">

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Always produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is tagged as the default</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PcdItemTypes">

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="FEATURE_FLAG">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The PCD Item represents a feature flag for the module. Features can only be selected at build time. Items of type FeatureFlag are used to conditionally construct module surface area that is produced as a result of a buld.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="FIXED_AT_BUILD">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is only a build time option and cannot be Dyanmic or Binary patched into the module.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PATCHABLE_IN_MODULE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is set to a default value at build time and a binary of the module can be patched to update the value.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DYNAMIC">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is found via a PCD PPI in PEI or a PCD Protocol in DXE. The token that matches the PCD entry is either generated by the build (and is only unique to that build) or is from the default database. This form also implies a build option will be produced for this module that allows the user to pick FixedAtBuild, PatchableInModule or Dynamic. If no Type is specified, it defaults to Dynamic</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DYNAMIC_EX">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">PCD Item is found via a PCD PPI in PEI or a PCD Protocol in DXE. Any PCD token database is supported</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PcdUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">The PCD Usage is only relevant to Items tagged with FeatureFlag, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The PCD entry must always be provide as the build will include the code and the associated Surface Area.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">If the FEATURE_FLAG is TRUE the build will include the code and the associated Surface Area. If the FEATURE_FLAG is FALSE, the code and the associated surface area is not included.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">The PCD Entry is Always included in the build code</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">If the FEATURE_FLAG is TRUE the build will include the code and the associated Surface Area. If the FEATURE_FLAG is FALSE, the code and the associated surface area is not included.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">"true" or "false". Indicates the default value for the PCD entry. This is used by the platform wizard to suggest values for a given platform build.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PpiNotifyUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the PPI Notify Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will consume the PPI if it's produced. Consumption is defined by executing the PPI notify function.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="PpiUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the PPI Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Required for the driver to function. This is part of the dependency expression of a module if the item represents a PPI or Protocol</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Consumed by the driver if the Item exists</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Always produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Conditionally produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Ppi is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ProtocolNotifyUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the PROTOCOL Notify Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will Consume protocol if it's produced. Consumption is defined by executing the protocol notify function.</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ProtocolUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the PROTOCOL Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Required for the driver to function. This is part of the dependency expression of a module if the item represents a PPI or Protocol</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Consumed by the driver if the Item exists</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Always produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Conditionally produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="TO_START">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Protocol Only - Protocol is required by driver binding Start() function to make Start() succeed</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="BY_START">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Protocol Only - Protocol is produced by driver binding Start() function if and only if Start() succeeds</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Protocol is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="SupportedArchitectures">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> These are the currently Supportted Architectures type codes </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALL"/>

+            <xs:enumeration value="EBC"/>

+            <xs:enumeration value="ARM"/>

+            <xs:enumeration value="IA32"/>

+            <xs:enumeration value="X64"/>

+            <xs:enumeration value="IPF"/>

+            <xs:enumeration value="PPC"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="SystemTableUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the System Table Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module requires a GUIDed entry in the system table</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will use the GUIDed entry in the system table only if the GUID is present</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module Always produces a GUIDed entry in the system table</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module sometimes produces a GUIDed entry in the system table for some of its execution flow</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">SystemTable is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Token">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> The Token data is union of HexDoubleWordDataType, GuidNaming Convetion and GuidArrayType. </xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="GuidArrayType GuidNamingConvention HexDoubleWordDataType"/>

+    </xs:simpleType>

+    <xs:simpleType name="ToolChains">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Supported Tool Chains are MSFT, INTEL, GCC and CYGWIN</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="MSFT"/>

+            <xs:enumeration value="INTEL"/>

+            <xs:enumeration value="GCC"/>

+            <xs:enumeration value="CYGWIN"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ToothPick">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describes which way the directory separator is leaning, either \ for WINDOWS or / for UNIX</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:normalizedString">

+            <xs:enumeration value="UNIX"/>

+            <xs:enumeration value="WINDOWS"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="UnicodeString">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define how we specify unicode strings</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:normalizedString">

+            <xs:pattern value="L(:)?(&quot;)(\w+)*((\W*)*(\s*)*(\w*)*)*(&quot;)"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="UsageTypes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Generic Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Required for the driver to function. This is part of the dependency expression of a module if the item represents a PPI or Protocol</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Consumed by the driver if the Item exists</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Always produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Conditionally produced</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="TO_START">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Protocol Only - Protocol is required by driver binding Start() function to make Start() succeed</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="BY_START">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Protocol Only - Protocol is produced by driver binding Start() function if and only if Start() succeeds</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Item is Private to the module and cannot be used by other modules</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="DEFAULT">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">This is the default value for an Item</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="VariableOffsetValues">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Describes the available Variable Offset data types, Bytes:Bits or BitSize</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="\d+(:)?\d*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="VariableUsage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the Variable Usage Attributes, as defined in the Module Surface Area Specification</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="NameConvention">

+            <xs:enumeration value="ALWAYS_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module requires the variable entry to be set</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_CONSUMED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module will use the variable entry if it's set</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="ALWAYS_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module Always will write the variable</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="SOMETIMES_PRODUCED">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Module sometimes writes the variable</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+            <xs:enumeration value="PRIVATE">

+                <xs:annotation>

+                    <xs:documentation xml:lang="en">Variable is produced and consumed only by this module</xs:documentation>

+                </xs:annotation>

+            </xs:enumeration>

+        </xs:restriction>

+    </xs:simpleType>

+    <!-- Complex Data Types -->

+    <xs:complexType name="ArgsType">

+        <xs:sequence minOccurs="0" maxOccurs="unbounded">

+            <xs:element name="Arg" type="xs:string"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="ToolType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This type is to permit adding specific tools and tool arguments for User Defined tools, into the Module Build Description file.</xs:documentation>

+        </xs:annotation>

+        <xs:sequence>

+            <xs:element name="ToolName" type="xs:string"/>

+            <xs:element name="ToolArgs" type="xs:string"/>

+        </xs:sequence>

+    </xs:complexType>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/FrameworkHeaders.xsd b/edk2/Tools/XMLSchema/FrameworkHeaders.xsd
new file mode 100644
index 0000000..a34d7a0
--- /dev/null
+++ b/edk2/Tools/XMLSchema/FrameworkHeaders.xsd
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.TianoCore.org/2006/Edk2.0" xmlns="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: FrameworkHeaders.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:include schemaLocation="FrameworkDataElements.xsd"/>

+    <xs:element name="FdbHeader">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is the header for the Framework Package Database file.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="DatabaseName"/>

+                <!-- Value fixed during initialization: FrameworkDatabase -->

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                    <!-- Guid needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                    <!-- GuidValue needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <!-- Version is the version of this file -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Path"/>

+                <!-- Path needs to be removed -->

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <!-- Created needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                    <!-- CreatedDate needs to be required -->

+                </xs:choice>

+                <xs:choice minOccurs="0">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Updated"/>

+                    <!-- Updated needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="UpdatedDate"/>

+                </xs:choice>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Abstract"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Specification"/>

+                <!-- Specificatoin needs to be required - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00090000 -->

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="MbdHeader">

+        <!-- MbdHeader needs to be removed -->

+        <xs:annotation>

+            <xs:documentation xml:lang="en">DO NOT USE! This is the header for the Component Module Build Description (MBD) file. NOTE: The GUID may be different from the GUID in the MSA file, as the Guid is updated every time the file is changed, as the Guid may change if the contents of the file are changed.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="BaseName"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Specification"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                </xs:choice>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Modified"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="ModifiedDate"/>

+                </xs:choice>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="MbdLibHeader">

+        <!-- MbdLibHeader needs to be removed -->

+        <xs:annotation>

+            <xs:documentation xml:lang="en">DO NOT USE! This is the header for the Library Module Build Description (MBD) file. NOTE: The Guid may be different from the Guid in the MSA file, as the Guid may change when the contents of the file are changed..</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="BaseName"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Specification"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                </xs:choice>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Modified"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="ModifiedDate"/>

+                </xs:choice>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="MsaHeader">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is the Component Module Surface Area Description Header - a replacement for INF files. The GUID may change when the contents of the file are changed.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:choice>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="BaseName"/>

+                    <!-- BaseName needs to be removed  -->

+                    <xs:element minOccurs="0" maxOccurs="1" name="ModuleName" type="xs:NCName"/>

+                </xs:choice>

+                <xs:element minOccurs="1" maxOccurs="1" ref="ModuleType"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="ComponentType"/>

+                <xs:choice>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                    <!-- Guid needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                    <!-- GuidValue needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Abstract"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <!-- Created needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                    <!-- CreatedDate needs to be required -->

+                </xs:choice>

+                <xs:choice>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Updated"/>

+                    <!-- Updated needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="ModifiedDate"/>

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" name="SupportedArchitectures">

+                    <xs:simpleType>

+                        <xs:list itemType="SupportedArchitectures"/>

+                    </xs:simpleType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Specification"/>

+                <!-- Specification needs to be required - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00090000 -->

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="MsaLibHeader">

+        <!-- MsaLibHeader needs to be removed -->

+        <xs:annotation>

+            <xs:documentation xml:lang="en">DO NOT USE! This is the Library Module Surface Area Description Header - a replacement for INF files. The Guid may change when the contents of the file are changed.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="BaseName"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="ModuleType"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="ComponentType"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Guid"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Abstract"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Updated"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Specification"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PlatformHeader">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This head is for the Framework Platform Description file (FPD.)</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" name="PlatformName" type="PlatformNamingConvention"/>

+                <xs:choice>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                    <!-- DO NOT USE Guid needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                    <!-- GuidValue needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Abstract"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="License"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <!-- DO NOT USE Created needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                    <!-- CreatedDate needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="CreatedBy"/>

+                <!-- DO NOT USE CreatedBy needs to be removed -->

+                <xs:choice>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Updated"/>

+                    <!-- DO NOT USE Updated needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="ModifiedDate"/>

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PackageType"/>

+                <!-- DO NOT USE PackageType needs to be removed -->

+                <xs:element minOccurs="0" maxOccurs="1" name="BuildTarget" type="BuildTargets"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Specification"/>

+                <!-- Specification needs to be required - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00090000 -->

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="SpdHeader">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This head is for the Surface Area Package Description file (SPD) The Guid may change when the contents of the file are changed.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="PackageName"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Guid"/>

+                    <!-- Guid needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="GuidValue"/>

+                    <!-- GuidValue needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Version"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Abstract"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Description"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="Copyright"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="License"/>

+                <xs:choice minOccurs="1" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Created"/>

+                    <!-- Created needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="CreatedDate"/>

+                    <!-- CreatedDate needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="E-Mail"/>

+                <xs:choice minOccurs="0" maxOccurs="1">

+                    <xs:element minOccurs="0" maxOccurs="1" ref="Updated"/>

+                    <!-- Created needs to be removed -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="ModifiedDate"/>

+                    <!-- CreatedDate needs to be required -->

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="URL"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="PackageType"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="ReadOnly"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="RePackage"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Specification"/>

+                <!-- Specification needs to be required - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00090000 -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="OutputDirectory"/>

+                <!-- OutputDirectory needs to be removed -->

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/FrameworkPlatformDataElements.xsd b/edk2/Tools/XMLSchema/FrameworkPlatformDataElements.xsd
new file mode 100644
index 0000000..188ea90
--- /dev/null
+++ b/edk2/Tools/XMLSchema/FrameworkPlatformDataElements.xsd
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://www.TianoCore.org/2006/Edk2.0" targetNamespace="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: FrameworkPlatformDataElements.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:annotation>

+        <xs:documentation xml:lang="en"> This schema defines EFI and Framework Platform Data Elements that are specific to platform creation.</xs:documentation>

+    </xs:annotation>

+    <xs:include schemaLocation="NamingConvention.xsd"/>

+    <xs:include schemaLocation="FrameworkDataAttributes.xsd"/>

+    <xs:include schemaLocation="FrameworkDataTypes.xsd"/>

+    <xs:include schemaLocation="FrameworkDataElements.xsd"/>

+    <xs:element name="Capsule">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" name="CapsuleId" type="xs:string"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="CapsuleOptions"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="CapsuleAttributes"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="CapsuleAttributes">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This element is used specify different name value pairs.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="NameValue"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Enable"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Disable"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="CapsuleOptions">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This element is used specify different name value pairs.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="NameValue"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Enable"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Disable"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Capsules">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Permit multiple Capsule Sections</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1" maxOccurs="unbounded">

+                <xs:element ref="Capsule"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Disable" type="xs:string"/>

+    <xs:element name="Enable" type="xs:string"/>

+    <xs:element name="Flash">

+        <xs:complexType>

+            <xs:annotation>

+                <xs:documentation xml:lang="en">We allow specifying the Flash layout in this directory, or we allow specifying a flashmap filename</xs:documentation>

+            </xs:annotation>

+            <xs:sequence>

+                <xs:choice>

+                    <xs:element name="FlashDefinition" type="FlashData"/>

+                    <xs:element name="FlashDefinitionFile" type="FileNameConvention"/>

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="FvImages"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Capsules"/>

+            </xs:sequence>

+            <xs:attribute name="MicrocodeFile" type="FileNameConvention" use="optional"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FlashDeviceImage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define contents of the regions in flash. The files and data are placed in the output image in the order they are encountered in this definition. Multiple FlashDeviceImage sections may be defined. Which one the tool should use is specified by Name on the command line.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:all>

+                <xs:element minOccurs="0" maxOccurs="1" name="RawData">

+                    <xs:complexType>

+                        <xs:sequence minOccurs="0" maxOccurs="1">

+                            <xs:element name="Data" type="xs:string"/>

+                        </xs:sequence>

+                        <xs:attributeGroup ref="RawDataAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element minOccurs="0" maxOccurs="1" name="File">

+                    <xs:complexType>

+                        <xs:attributeGroup ref="FlashDeviceImageFileAttributes"/>

+                    </xs:complexType>

+                </xs:element>

+            </xs:all>

+            <xs:attributeGroup ref="FlashDeviceImageAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FlashDeviceInfo">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is the Flash Devcie definition List</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element name="Blocks">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="255" name="Block">

+                                <xs:complexType>

+                                    <xs:simpleContent>

+                                        <xs:extension base="BlockNameType">

+                                            <xs:attributeGroup ref="BlockAttributes"/>

+                                        </xs:extension>

+                                    </xs:simpleContent>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                    </xs:complexType>

+                </xs:element>

+                <xs:element name="Regions">

+                    <xs:complexType>

+                        <xs:sequence>

+                            <xs:element minOccurs="1" maxOccurs="unbounded" name="Region">

+                                <xs:complexType>

+                                    <xs:all>

+                                        <xs:element name="SubRegions">

+                                            <xs:complexType>

+                                                <xs:sequence minOccurs="0" maxOccurs="unbounded">

+                                                    <xs:element name="SubRegion">

+                                                        <xs:complexType>

+                                                            <xs:simpleContent>

+                                                                <xs:extension base="xs:string">

+                                                                    <xs:attributeGroup ref="SubRegionAttributes"/>

+                                                                </xs:extension>

+                                                            </xs:simpleContent>

+                                                        </xs:complexType>

+                                                    </xs:element>

+                                                </xs:sequence>

+                                            </xs:complexType>

+                                        </xs:element>

+                                    </xs:all>

+                                    <xs:attributeGroup ref="RegionAttributes"/>

+                                </xs:complexType>

+                            </xs:element>

+                        </xs:sequence>

+                    </xs:complexType>

+                </xs:element>

+            </xs:sequence>

+            <xs:attributeGroup ref="FlashDeviceInfoAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FlashDeviceOverrideImage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define OVERRIDE contents of the regions in flash. Only what is different here from what may defined in other areas (or files) is needed </xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" name="Name" type="NameConvention"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="File" type="FvImageOverrideFileType"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FlashDeviceOverrideInfo">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is the Flash Devcie Override Definition list. Only what is different from the previously defined stuff needs to be included.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" name="Name" type="UCNameType"/>

+                <xs:element default="512KB" minOccurs="0" maxOccurs="1" name="FlashSize" type="FlashSize"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="BaseAddress" type="HexAddressType"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="OutputDirectory" type="DirectoryNamingConvention"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="MicrocodeFile" type="FileNameConvention"/>

+                <xs:element minOccurs="0" maxOccurs="255" name="Block" type="BlockNameType"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" name="Region" type="RegionDataType"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FvImage">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="unbounded" ref="FvImageNames"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="FvImageOptions"/>

+            </xs:sequence>

+            <xs:attribute name="Type" type="FvImageTypes" use="optional"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FvImageName">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element ref="FvImageOptions"/>

+            </xs:sequence>

+            <xs:attribute name="Name" type="FvRegionTypes" use="required"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FvImageNames" type="xs:NCName"/>

+    <xs:element name="FvImageOptions">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This element is used specify different name value pairs.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="NameValue"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Enable"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="Disable"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FvImages">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This section allows the user to define specific information regarding the FvImage</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="NameValue"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="FvImage"/>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="FvImageName"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="ModuleSA">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This element is used to specify information in the Platform Description File.</xs:documentation>

+            <xs:documentation xml:lang="en">This is a mixed element, allowing the user to specify the name of the MSA file, as well as to optionally specify additional override information.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence minOccurs="1">

+                <xs:element minOccurs="0" maxOccurs="1" ref="SourceFiles"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Includes"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Libraries"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Protocols"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Events"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Hobs"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="PPIs"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Variables"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="BootModes"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="SystemTables"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="DataHubs"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Formsets"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Guids"/>  <!-- DO NOT USE! REMOVE in FINAL -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="Externs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PcdBuildDeclarations"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildOptions"/>

+            </xs:sequence>

+            <xs:attributeGroup ref="MsaAttributes"/>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="NameValue">

+        <xs:complexType>

+            <xs:simpleContent>

+                <xs:extension base="xs:string">

+                    <xs:attribute name="Name" type="xs:string" use="required"/>

+                    <xs:attribute name="Value" type="xs:string" use="required"/>

+                </xs:extension>

+            </xs:simpleContent>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="Overrides">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">DO NOT USE! - Removing this from Schema</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" ref="FlashDeviceOverrideInfo"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="FlashDeviceOverrideImage"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PlatformDescriptions">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">DO NOT USE! - Use PlatformList instead</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence maxOccurs="unbounded">

+                <xs:element ref="Platform"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="PlatformList">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is used in the Framework Database file</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence maxOccurs="unbounded">

+                <xs:element ref="Platform"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="FrameworkModules">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This is used in a Framework Platform Description (FPD) file</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" name="SEC" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="PEI_CORE" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="PEIM" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="DXE_CORE" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="DXE_DRIVERS" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="OTHER_COMPONENTS" type="Components"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="TianoImage">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">DO NOT USE - Use FrameworkModules Instead.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="1" name="SEC" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="PEI_CORE" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="PEIM" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="DXE_CORE" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="DXE_DRIVERS" type="Components"/>

+                <xs:element minOccurs="0" maxOccurs="1" name="OTHER_COMPONENTS" type="Components"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:simpleType name="EfiFvAttributeType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">The list of EFI_FLASH_AREA Attributes</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="EFI_FLASH_AREA_FV"/>

+            <xs:enumeration value="EFI_FLASH_AREA_MEMMAPPED_FV"/>

+            <xs:enumeration value="EFI_FLASH_AREA_SUBFV"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="EfiFvAreaType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">The list of valid EFI Area Types</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="EFI_FLASH_AREA_EFI_VARIABLES"/>

+            <xs:enumeration value="EFI_FLASH_AREA_UNUSED"/>

+            <xs:enumeration value="EFI_FLASH_AREA_MAIN_BIOS"/>

+            <xs:enumeration value="EFI_FLASH_AREA_GUID_DEFINED"/>

+            <xs:enumeration value="EFI_FLASH_AREA_FTW_STATE"/>

+            <xs:enumeration value="EFI_FLASH_AREA_FTW_BACKUP"/>

+            <xs:enumeration value="EFI_FLASH_AREA_RECOVERY_BIOS"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="EfiNameGuidType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Right now, only EFI_FLASH_MAP_HOB_GUID is defined</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="EFI_FLASH_MAP_HOB_GUID"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FlashSize">

+        <xs:restriction base="xs:string">

+            <xs:enumeration value="256KB"/>

+            <xs:enumeration value="512KB"/>

+            <xs:enumeration value="1MB"/>

+            <xs:enumeration value="2MB"/>

+            <xs:enumeration value="4MB"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FvImageTypes">

+        <xs:restriction base="xs:NCName">

+            <xs:enumeration value="Attributes"/>

+            <xs:enumeration value="Options"/>

+            <xs:enumeration value="Components"/>

+            <xs:enumeration value="ValidImageNames"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FvSubRegionTypes">

+        <xs:restriction base="UCNameType">

+            <xs:enumeration value="NV_VARIABLE_STORE"/>

+            <xs:enumeration value="MICROCODE"/>

+            <xs:enumeration value="NV_FTW_WORKING"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:complexType name="Components">

+        <xs:sequence minOccurs="1" maxOccurs="unbounded">

+            <xs:element ref="ModuleSA"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="FlashData">

+        <xs:sequence>

+            <xs:element minOccurs="0" maxOccurs="unbounded" name="UserDefinedFvRegion" type="NameConvention"/>

+            <xs:choice minOccurs="0" maxOccurs="1">

+                <xs:sequence>

+                    <xs:element minOccurs="1" maxOccurs="1" ref="FlashDeviceInfo"/>

+                    <xs:element minOccurs="1" maxOccurs="1" ref="FlashDeviceImage"/>

+                </xs:sequence>

+            </xs:choice>

+            <xs:element minOccurs="0" maxOccurs="1" ref="Overrides"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="FvImageFileType">

+        <xs:sequence>

+            <xs:element minOccurs="1" maxOccurs="1" name="Name" type="FileNameConvention"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="Region" type="FvRegionTypes"/>

+            <xs:element minOccurs="1" maxOccurs="unbounded" name="RawData" type="RawDataType"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="FvImageOverrideFileType">

+        <xs:sequence>

+            <xs:element minOccurs="0" maxOccurs="1" name="Name" type="FileNameConvention"/>

+            <xs:element minOccurs="0" maxOccurs="1" name="Region" type="FvRegionTypes"/>

+            <xs:element minOccurs="0" maxOccurs="1" name="UserDefinedFvRegion" type="NameConvention"/>

+            <xs:element minOccurs="0" maxOccurs="unbounded" name="RawData" type="RawDataType"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="RawDataType">

+        <xs:sequence>

+            <xs:element minOccurs="1" maxOccurs="1" name="Name" type="NameConvention"/>

+            <xs:element minOccurs="0" maxOccurs="1" name="Region" type="FvRegionTypes"/>

+            <xs:element minOccurs="0" maxOccurs="1" name="UserDefinedFvRegion" type="NameConvention"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="SubRegion" type="FvSubRegionTypes"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="Data" type="HexDataType"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="RegionDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define the regions and their uses for the device</xs:documentation>

+        </xs:annotation>

+        <xs:sequence>

+            <xs:element minOccurs="1" maxOccurs="1" name="Name" type="UCNameType"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="Size" type="HexAddressType"/>

+            <xs:element minOccurs="1" maxOccurs="unbounded" name="Attributes" type="EfiFvAttributeType"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="AreaType" type="EfiFvAreaType"/>

+            <xs:element minOccurs="0" maxOccurs="unbounded" name="SubRegion" type="SubRegionType"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:complexType name="SubRegionType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define the regions and their uses for the device</xs:documentation>

+        </xs:annotation>

+        <xs:sequence>

+            <xs:element default="true" minOccurs="1" maxOccurs="1" name="CreateHob" type="xs:boolean"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="Name" type="UCNameType"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="Size" type="HexAddressType"/>

+            <xs:element minOccurs="1" maxOccurs="unbounded" name="Attributes" type="EfiFvAttributeType"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="AreaType" type="EfiFvAreaType"/>

+            <xs:element minOccurs="1" maxOccurs="1" name="NameGuid" type="EfiNameGuidType"/>

+        </xs:sequence>

+    </xs:complexType>

+    <xs:attributeGroup name="BlockAttributes">

+        <xs:attribute name="Name" type="BlockNameType" use="required"/>

+        <xs:attribute name="Size" type="HexAddressType" use="required"/>

+        <xs:attribute name="Flags" type="HexAddressType" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="FlashDeviceImageAttributes">

+        <xs:attribute name="Name" type="xs:string" use="required"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="FlashDeviceImageFileAttributes">

+        <xs:attribute name="Name" type="xs:string" use="required"/>

+        <xs:attribute name="Region" type="xs:string" use="required"/>

+        <xs:attribute name="SubRegion" type="xs:string" use="optional"/>

+        <xs:attribute name="Optional" type="xs:boolean" use="optional"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="FlashDeviceInfoAttributes">

+        <xs:attribute name="Name" type="xs:string" use="required"/>

+        <xs:attribute name="Size" type="HexAddressType" use="required"/>

+        <xs:attribute name="BaseAddress" type="HexAddressType" use="required"/>

+        <xs:attribute name="ErasePolarity" type="Polarity" use="required"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="RawDataAttributes">

+        <xs:attribute name="Name" type="xs:string" use="required"/>

+        <xs:attribute name="Region" type="xs:string" use="required"/>

+        <xs:attribute name="SubRegion" type="xs:string" use="required"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="RegionAttributes">

+        <xs:attribute name="Name" type="xs:string" use="required"/>

+        <xs:attribute name="Size" type="HexAddressType" use="required"/>

+        <xs:attribute name="Flags" type="HexAddressType" use="optional"/>

+        <xs:attribute name="Alignment" type="HexAddressType" use="optional"/>

+        <xs:attribute name="Attributes" type="xs:string" use="required"/>

+        <xs:attribute name="AreaType" type="EfiFvAreaType" use="required"/>

+    </xs:attributeGroup>

+    <xs:attributeGroup name="SubRegionAttributes">

+        <xs:attribute name="CreateHob" type="xs:boolean" use="required"/>

+        <xs:attribute name="Name" type="xs:string" use="required"/>

+        <xs:attribute name="Size" type="HexAddressType" use="required"/>

+        <xs:attribute name="Attributes" type="xs:string" use="required"/>

+        <xs:attribute name="AreaType" type="EfiFvAreaType" use="required"/>

+        <xs:attribute name="NameGuid" type="xs:string" use="required"/>

+        <xs:attribute name="AreaTypeGuid" type="xs:string" use="optional"/>

+        <xs:attribute name="FileSystemGuid" type="xs:string" use="optional"/>

+    </xs:attributeGroup>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/NamingConvention.xsd b/edk2/Tools/XMLSchema/NamingConvention.xsd
new file mode 100644
index 0000000..ca19200
--- /dev/null
+++ b/edk2/Tools/XMLSchema/NamingConvention.xsd
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.TianoCore.org/2006/Edk2.0" xmlns="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: NamingConvention.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:annotation>

+        <xs:documentation xml:lang="en"> This schema defines various data types and naming conventions including: base name, filename and directory naming conventions. These are all simple data types.</xs:documentation>

+    </xs:annotation>

+    <xs:simpleType name="BaseNameConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Base Names must start with an upper case character, followed by one or more alphanumeric characters and/or an optional underscore (_) character followed by one or more alphanumeric characters. Examples: Base_name3, BASE_NAME3, BaseName3 </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[A-Z]([a-zA-Z0-9])*(_)?([a-zA-Z0-9])*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="C_Name">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> C_Names must start with either an underscore (_) character followed by one or more alpha characters, followed by any combination of underscore or alphanumeric characters.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="((_)*([a-zA-Z])+((_)*[a-zA-Z0-9]*))*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="DirectoryNamingConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Directory naming convention is a UNION of DOS an UNIX directory path names </xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="Directory_DOS Directory_UNIX"/>

+    </xs:simpleType>

+    <xs:simpleType name="Directory_DOS">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Directory naming convention for Windows backslash (\) directory path name </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="([a-zA-Z]:\\)?(((\\?_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\\)?)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Directory_UNIX">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Directory naming convention for UNIX forwardslash (/) directory path name </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="(\/)?(((_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\/)?)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="E-Mail">

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[a-zA-Z]+(( )*.?-?[a-zA-Z]*)*@[a-zA-Z]+(( )*.?-?[a-zA-Z]*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="FileNameConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This defines what a Filename is: Alphanumeric characters and optional underscore (_) or dash (-) characters, followed by a optional dot and more alphanumeric characters. </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[a-zA-Z][a-zA-Z0-9]*((_)*(-)*(.)*[a-zA-Z0-9]*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="GuidArrayType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This defines the minimum specification for a GUID Array which is 8 Hex Digits - 4 Hex Digits - 4 Hex Digits - 8 Hex Bytes, the last 16 Hex Digits can be enclosed in sqiggle {} brackets.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="GuidNamingConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> A GUID must contain five different Hexadecimal character sets that are separated by a dash (-) character. </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="GuidType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> The GUID data is union of GuidNaming Convetion and GuidArrayType. </xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="GuidArrayType GuidNamingConvention"/>

+    </xs:simpleType>

+    <xs:simpleType name="Hex64BitDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex 64 Bit Value to be 0x[a-f0-9]{16}</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="(0x)?[a-fA-F0-9]{1,16}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HexAddressType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex Address, 0x[a-fA-F0-9]{1,16}</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="0x[a-fA-F0-9]{1,16}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HexByteDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex Byte Value to be 0x[a-f0-9]{2}</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="(0x)?[a-fA-F0-9]{1,2}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HexDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex Value to be 0x[a-f0-9]+</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="0x[a-fA-F0-9]+"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HexDigitType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex Diget to be 0x[a-f0-9]</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[a-fA-F0-9]{1}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HexDoubleWordDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex Double Word Value to be 0x[a-f0-9]{8}</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="0x[a-fA-F0-9]{1,8}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="HexWordDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define a Hex Word Value to be 0x[a-f0-9]{4}</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="0x[a-fA-F0-9]{1,4}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="LibraryNameConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This defines what a Library name is: alphanumeric characters and optional underscore (_) characters. </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[A-Z][a-zA-Z0-9]*(_*[a-zA-Z0-9])*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="NameConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">What is a name, any series of alphanumeric characters and one or more underline characters that may occur in any position</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:normalizedString">

+            <xs:pattern value="(_*[a-zA-Z0-9]*_*)+"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Paragraph">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">This describes the normal text of a paragraph that can be used in a license or description tag.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:normalizedString"/>

+    </xs:simpleType>

+    <xs:simpleType name="PathAndFilename">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Naming convention for a path and file name</xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="Directory_DOS Directory_UNIX"/>

+    </xs:simpleType>

+    <xs:simpleType name="PlatformNamingConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This defines what a Platform Name is: Alphanumeric characters and optional underscore (_) or dash (-) characters, followed by a dot and more alphanumeric characters. </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="(([a-zA-Z][a-zA-Z0-9]*)(_)*(.)*)+"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Polarity">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Limit Polarity vaild values to -1, 0 and 1</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:int">

+            <xs:pattern value="-1|0|1"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Sentence">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This data type requires two or more words </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:normalizedString">

+            <xs:pattern value="(\w+\W*)+( )+(\W*\w*\W*\s*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="ToolNameConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> This defines what a Tool name is: Alphanumeric characters and optional underscore (_) or dash (-) characters, optionally followed by a dot and more alphanumeric characters. </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[a-zA-Z][a-zA-Z0-9]*(_*-*.*[a-zA-Z0-9])*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="UCLetterType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a UpperCase Letter type, which can be any combination of upper case characters followed by zero or more underscore and/or uppercase alphanumeric characters </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[A-Z]{1}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="UCNameType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a UpperCase Name, which can be any combination of upper case characters followed by zero or more underscore and/or uppercase alphanumeric characters </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[A-Z]+(_*[A-Z0-9]*( )*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="UserName">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Specify a User Name</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="[a-zA-Z]+(( )*.?-?[a-zA-Z]*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="V1">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">%VAR%(Directory)*(File_Names)*</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="((%[A-Z](_*[A-Z0-9]*)*%)+((((\\)?_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\\)?)*)"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="V2">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">($VAR | $( VAR) | ${VAR})(Directory)*(File_Names)</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="(($[A-Z](_*[A-Z0-9]*)*)+||($\([A-Z](_*[A-Z0-9]*)*\))+||($\{[A-Z](_*[A-Z0-9]*)*\})+)+(\/)?(((((_*-*.*[a-zA-Z0-9]*)*(_*-*.*[a-zA-Z0-9])*)+(\/)?)*)*)"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="VariableConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">VariableConvention is a UNION of: $VAR, $( VAR), ${VAR} and %VAR% and Directory and File Names</xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="V1 V2"/>

+    </xs:simpleType>

+    <xs:simpleType name="VariableGuidType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> The GUID data is union of GuidNaming Convetion and GuidArrayType. </xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="GuidArrayType GuidNamingConvention Zero"/>

+    </xs:simpleType>

+    <xs:simpleType name="VariableNamingConvention">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">VariableConvention is a UNION of: $VAR, $( VAR), ${VAR} and %VAR%</xs:documentation>

+        </xs:annotation>

+        <xs:union memberTypes="Variable_DOS Variable_UNIX Variable_UNIX_Scope1 Variable_UNIX_Scope2"/>

+    </xs:simpleType>

+    <xs:simpleType name="Variable_DOS">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a DOS Variable Name: %VAR% It must start with an Upper Case character.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="%[A-Z](_*[A-Z0-9]*)*%"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Variable_UNIX">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a UNIX Variable Name: $VAR It must start with an Upper Case character.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="$[A-Z](_*[A-Z0-9]*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Variable_UNIX_Scope1">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a UNIX Variable Name: $( VAR1) It must start with an Upper Case character.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="$\([A-Z](_*[A-Z0-9]*)*\)"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Variable_UNIX_Scope2">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a UNIX Variable Name: ${ VAR1} It must start with an Upper Case character.</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="$\{[A-Z](_*[A-Z0-9]*)*\}"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="VersionDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a Version Number, which can be any combination of a number followed by zero or more alphanumeric-dot-alphanumeric characters </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="xs:normalizedString"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="Zero">

+        <xs:annotation>

+            <xs:documentation xml:lang="en">Define Zero as a vaild value</xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:int">

+            <xs:pattern value="0"/>

+        </xs:restriction>

+    </xs:simpleType>

+    <xs:simpleType name="OldVersionDataType">

+        <xs:annotation>

+            <xs:documentation xml:lang="en"> Definition of a Version Number, which can be any combination of a number followed by zero or more alphanumeric-dot-alphanumeric characters </xs:documentation>

+        </xs:annotation>

+        <xs:restriction base="xs:string">

+            <xs:pattern value="([0-9])+[a-zA-Z0-9]*(-?.?([a-zA-Z0-9])*)*"/>

+        </xs:restriction>

+    </xs:simpleType>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/SurfaceArea.xsd b/edk2/Tools/XMLSchema/SurfaceArea.xsd
new file mode 100644
index 0000000..a0223cb
--- /dev/null
+++ b/edk2/Tools/XMLSchema/SurfaceArea.xsd
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.TianoCore.org/2006/Edk2.0" xmlns="http://www.TianoCore.org/2006/Edk2.0">

+    <!--

+    Filename: SurfaceArea.xsd

+    

+    Copyright (c) 2006, Intel Corp.

+    All rights reserved. This program and the accompanying materials

+    are licensed and made available under the terms and conditions of the BSD License

+    which 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.

+    

+  -->

+    <xs:include schemaLocation="FrameworkHeaders.xsd"/>

+    <xs:include schemaLocation="FrameworkDataElements.xsd"/>

+    <xs:include schemaLocation="FrameworkPlatformDataElements.xsd"/>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">The following defines the valid format for the Framework Database (DB) File.</xs:documentation>

+    </xs:annotation>

+    <xs:element name="FrameworkDatabase">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="FdbHeader"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="PackageList"/>

+                <xs:choice>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="PlatformList"/>

+                    <!-- DO NOT USE! removing PlatformDescriptions, use PlatformList instead. -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="PlatformDescriptions"/>

+                </xs:choice>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">The following describes the valid format for the Framework Platform Description (FPD) File.</xs:documentation>

+    </xs:annotation>

+    <xs:element name="FrameworkPlatformDescription">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="PlatformHeader"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Flash"/>

+                <!-- DO NOT USE! removing TianoImage, use FrameworkModules instead. -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="TianoImage"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="FrameworkModules"/>

+                <!-- DO NOT USE! removing PcdBuildDeclarations here, use PcdBuildDeclaratiion in ModuleSA instead. -->

+                <xs:element minOccurs="0" maxOccurs="1" ref="PcdBuildDeclarations"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PcdDynamicBuildDeclarations"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildOptions"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">DO NOT USE removing all Library Module files - PUT IN PLATFORM DESCRIPTION FILE, FPD</xs:documentation>

+    </xs:annotation>

+    <xs:element name="LibraryModuleBuildDescription">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="MbdLibHeader"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="SourceFiles"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Includes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Libraries"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Protocols"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Events"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Hobs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PPIs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Variables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BootModes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="SystemTables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="DataHubs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Formsets"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Guids"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Externs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PCDs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildOptions"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">DO NOT USE Removing all Library Module files - USE MODULE DESCRIPTION FILE, MSA</xs:documentation>

+    </xs:annotation>

+    <xs:element name="LibraryModuleSurfaceArea">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="MsaLibHeader"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="LibraryClassDefinitions"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="SourceFiles"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Includes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Protocols"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Events"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Hobs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PPIs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Variables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BootModes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="SystemTables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="DataHubs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Formsets"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Guids"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Externs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PCDs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildOptions"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">DO NOT USE Removing Build Description files - PUT IN PLATFORM DESCRIPTION FILE, FPD or RecommendedInstance Attribute in MSA LibraryClass</xs:documentation>

+    </xs:annotation>

+    <xs:element name="ModuleBuildDescription">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="MbdHeader"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="SourceFiles"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Includes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Libraries"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Protocols"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Events"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Hobs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PPIs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Variables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BootModes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="SystemTables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="DataHubs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Formsets"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Guids"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Externs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PCDs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildOptions"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">This is the Module Surface Area Description (MSA) that contains the list of the module's source files, library classes that can or must be used by the module, the Include Paths, Protocols and Ppi's that are either produced or consued.</xs:documentation>

+    </xs:annotation>

+    <xs:element name="ModuleSurfaceArea">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="MsaHeader"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="LibraryClassDefinitions"/>

+                <xs:element minOccurs="1" maxOccurs="1" ref="SourceFiles"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Includes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Protocols"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Events"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Hobs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PPIs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Variables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BootModes"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="SystemTables"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="DataHubs"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Formsets"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Guids"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="Externs"/>

+                <xs:choice minOccurs="0">

+                    <!-- DO NOT USE! removing PCDs, use MsaPcdDeclarations instead -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="PCDs"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="MsaPcdDeclarations"/>

+                </xs:choice>

+                <xs:element minOccurs="0" maxOccurs="1" ref="BuildOptions"/>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:annotation>

+        <xs:documentation xml:lang="en">This describes the valid content for a Package Surface Area Description (SPD) file.</xs:documentation>

+    </xs:annotation>

+    <xs:element name="PackageSurfaceArea">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="1" maxOccurs="1" ref="SpdHeader"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="LibraryClassDeclarations"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="IndustryStdHeaders"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PackageDependencies"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="MsaFiles"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PackageHeaders"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="GuidDeclarations"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="ProtocolDeclarations"/>

+                <xs:element minOccurs="0" maxOccurs="1" ref="PpiDeclarations"/>

+                <xs:choice minOccurs="0">

+                    <!-- DO NOT USE! removing PcdDefinitions, use PcdDeclarations instead. -->

+                    <xs:element minOccurs="0" maxOccurs="1" ref="PcdDefinitions"/>

+                    <xs:element minOccurs="0" maxOccurs="1" ref="PcdDeclarations"/>

+                </xs:choice>

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+</xs:schema>

diff --git a/edk2/Tools/XMLSchema/SurfaceArea.xsdconfig b/edk2/Tools/XMLSchema/SurfaceArea.xsdconfig
new file mode 100644
index 0000000..aa52361
--- /dev/null
+++ b/edk2/Tools/XMLSchema/SurfaceArea.xsdconfig
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+Copyright (c) 2006, Intel Corp.

+All rights reserved. This program and the accompanying materials

+are licensed and made available under the terms and conditions of the BSD License

+which 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.

+-->

+<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">

+  <xb:namespace uri="http://www.TianoCore.org/2006/Edk2.0">

+    <xb:package>org.tianocore</xb:package>

+  </xb:namespace>

+</xb:config>

+

diff --git a/edk2/Tools/bin/GenBuildFile.bat b/edk2/Tools/bin/GenBuildFile.bat
new file mode 100644
index 0000000..323969f
--- /dev/null
+++ b/edk2/Tools/bin/GenBuildFile.bat
@@ -0,0 +1,45 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@echo off

+

+@if "%JAVA_HOME%"=="" goto no_jdk

+@if "%WORKSPACE%"=="" goto no_wks

+

+@if "%1"=="-H" (goto usage)

+@if "%1"=="-h" (goto usage) else (goto all)

+

+:usage

+@echo.

+@echo Generate entrance build.xml for each module under current directory

+@echo.

+@echo Usage: GenBuildFile.bat - must be executed in the package level directory

+@echo.

+goto end

+

+:all

+  ant -q -f %WORKSPACE%\Tools\bin\GenBuildFile.xml

+  goto end

+

+:no_jdk

+  @echo.

+  @echo !!! Please set JAVA_HOME !!!

+  @echo.

+  @goto end

+

+:no_wks

+  @echo.

+  @echo !!! Please set WORKSPACE !!!

+  @echo.

+  @goto end

+

+:end

+@echo on

diff --git a/edk2/Tools/bin/GenBuildFile.xml b/edk2/Tools/bin/GenBuildFile.xml
new file mode 100644
index 0000000..81a2900
--- /dev/null
+++ b/edk2/Tools/bin/GenBuildFile.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?> 

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project default="workspace" basedir=".">

+  <taskdef resource="GenBuild.tasks" />

+  

+  <target name="workspace">

+    <bf recursive="true" />

+  </target>

+</project>

diff --git a/edk2/Tools/bin/PackageEditor.bat b/edk2/Tools/bin/PackageEditor.bat
new file mode 100644
index 0000000..cf2f909
--- /dev/null
+++ b/edk2/Tools/bin/PackageEditor.bat
@@ -0,0 +1,72 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@echo off

+

+:check_java

+if "%JAVA_HOME%"=="" goto no_jdk

+

+:check_wks

+if "%WORKSPACE%"=="" goto no_wks

+

+:check_ant

+if "%ANT_HOME%"=="" goto no_ant

+@REM set ANT_HOME=%WORKSPACE%\Tools\bin\apache-ant

+

+:check_xmlbeans

+if "%XMLBEANS_HOME"=="" goto no_xmlbeans

+@REM set XMLBEANS_HOME=%WORKSPACE%\Tools\bin\xmlbeans

+

+set Framework_Tools_Path=%WORKSPACE%\Tools\bin

+

+set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin;%WORKSPACE%\Tools\bin;%XMLBEANS_HOME%\bin;%PATH%

+

+set CLASSPATH=%WORKSPACE%\Tools\Jars\SurfaceArea.jar;%WORKSPACE%\Tools\Jars\GenBuild.jar

+set CLASSPATH=%CLASSPATH%;%WORKSPACE%\Tools\Jars\cpptasks.jar;%WORKSPACE%\Tools\Jars\frameworktasks.jar

+set CLASSPATH=%CLASSPATH%;%XMLBEANS_HOME%\lib\jsr173_1.0_api.jar;%XMLBEANS_HOME%\lib\xbean.jar

+set CLASSPATH=%CLASSPATH%;%XMLBEANS_HOME%\lib\xbean_xpath.jar;%XMLBEANS_HOME%\lib\xmlpublic.jar

+set CLASSPATH=%CLASSPATH%;%XMLBEANS_HOME%\lib\saxon8.jar;%XMLBEANS_HOME%\lib\saxon8-jdom.jar

+set CLASSPATH=%CLASSPATH%;%XMLBEANS_HOME%\lib\saxon8-sql.jar;%XMLBEANS_HOME%\lib\resolver.jar

+set CLASSPATH=%CLASSPATH%;%WORKSPACE%\Tools\bin\PackageEditor.jar

+

+call "ant" -f %WORKSPACE%\Tools\Source\PackageEditor\build.xml

+

+call "java" org.tianocore.packaging.PackagingMain

+

+goto end

+

+:no_jdk

+echo.

+echo !!! Please set JAVA_HOME !!!

+echo.

+goto check_wks

+

+:no_wks

+echo.

+echo !!! Please set WORKSPACE !!!

+echo.

+goto check_ant

+

+:no_ant

+echo.

+echo !!! Please set ANT_HOME !!!

+echo.

+goto check_xmlbeans

+

+:no_xmlbeans

+echo.

+echo !!! Please set XMLBEANS_HOME !!!

+echo.

+goto end

+

+:end

+@echo on

+

diff --git a/edk2/Tools/bin/SABeans.bat b/edk2/Tools/bin/SABeans.bat
new file mode 100644
index 0000000..4e49540
--- /dev/null
+++ b/edk2/Tools/bin/SABeans.bat
@@ -0,0 +1,54 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@echo off

+if "%JAVA_HOME%"=="" goto no_jdk

+if "%WORKSPACE%"=="" goto no_wks

+

+if "%1"=="" (goto usage)

+if "%1"=="-h" (goto usage)

+if "%1"=="-H" (goto usage) else (goto all)

+

+:usage

+echo.

+echo Generate SurfaceArea Java Beans from schema

+echo.

+echo Usage: 

+echo        SABeans.bat SurfaceArea.jar

+echo            generate compiled SurfaceArea Java Beans only

+echo.

+echo        SABeans.bat SurfaceArea.java

+echo            generate source code of SurfaceArea Java Beans only

+echo.

+echo        SABeans.bat SurfaceArea

+echo            generate both compiled and source code of SurfaceArea Java Beans

+echo.

+goto end

+

+:all

+  ant -f %WORKSPACE%\Tools\Source\SurfaceArea\build.xml %1

+  goto end

+

+:no_jdk

+  echo.

+  echo !!! Please set JAVA_HOME !!!

+  echo.

+  goto end

+

+:no_wks

+  echo.

+  echo !!! Please set WORKSPACE !!!

+  echo.

+  goto end

+

+:end

+@echo on

+

diff --git a/edk2/Tools/bin/SACreate.bat b/edk2/Tools/bin/SACreate.bat
new file mode 100644
index 0000000..5bcef42
--- /dev/null
+++ b/edk2/Tools/bin/SACreate.bat
@@ -0,0 +1,51 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@if "%JAVA_HOME%"=="" goto no_jdk

+@if "%WORKSPACE%"=="" goto no_wks

+

+@if "%1"=="" goto usage

+@if "%1"=="-H" (goto usage)

+@if "%1"=="-h" (goto usage) else (goto all)

+

+:usage

+@echo off

+@echo.

+@echo Create a empty SurfaceArea description file for specified SurfaceArea element

+@echo.

+@echo Usage: SACreate.bat "MSA_FILE" "SURFACE_AREA_ELEMENT" 

+@echo.

+@echo        Supported surface area top level element

+@echo                                 ModuleSurfaceArea

+@echo                                 ModuleBuildDescription

+@echo                                 LibraryModuleSurfaceArea

+@echo                                 LibraryModuleBuildDescription

+@echo                                 FrameworkPlatformDescription

+@echo                                 PackageSurfaceArea

+goto end

+

+:all

+@ant -q -f %WORKSPACE%\Tools\Source\SurfaceArea\build.xml generate -DSURFACE_AREA_FILE=%~f1 -DSURFACE_AREA_ELEMENT=%2

+@goto end

+

+:no_jdk

+  @echo.

+  @echo !!! Please set JAVA_HOME !!!

+  @echo.

+  @goto end

+

+:no_wks

+  @echo.

+  @echo !!! Please set WORKSPACE !!!

+  @echo.

+  @goto end

+

+:end

diff --git a/edk2/Tools/bin/SAPretty.bat b/edk2/Tools/bin/SAPretty.bat
new file mode 100644
index 0000000..a6e191c
--- /dev/null
+++ b/edk2/Tools/bin/SAPretty.bat
@@ -0,0 +1,45 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@if "%JAVA_HOME%"=="" goto no_jdk

+@if "%WORKSPACE%"=="" goto no_wks

+

+@if "%1"=="" goto usage

+@if "%1"=="-H" (goto usage)

+@if "%1"=="-h" (goto usage) else (goto all)

+

+:usage

+@echo off

+@echo.

+@echo Beautify XML file format

+@echo.

+@echo Usage: SAPretty.bat "XML_FILE" 

+@echo.

+goto end

+

+:all

+@ant -q -f %WORKSPACE%\Tools\Source\SurfaceArea\build.xml pretty -DSURFACE_AREA_FILE=%~f1

+@goto end

+

+:no_jdk

+  @echo.

+  @echo !!! Please set JAVA_HOME !!!

+  @echo.

+  @goto end

+

+:no_wks

+  @echo.

+  @echo !!! Please set WORKSPACE !!!

+  @echo.

+  @goto end

+

+:end

+

diff --git a/edk2/Tools/bin/SAVerify.bat b/edk2/Tools/bin/SAVerify.bat
new file mode 100644
index 0000000..1f4566a
--- /dev/null
+++ b/edk2/Tools/bin/SAVerify.bat
@@ -0,0 +1,55 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM 

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@if "%JAVA_HOME%"=="" goto no_jdk

+@if "%WORKSPACE%"=="" goto no_wks

+

+@if "%1"=="" (goto usage)

+@if "%1"=="-h" (goto usage)

+@if "%1"=="-H" (goto usage)

+@if "%1"=="all" (goto all)

+@if "%1"=="ALL" (goto all) else (goto standalone)

+

+:usage

+@echo off

+@echo.

+@echo Verify SurfaceArea file(s)

+@echo.

+@echo Usage: 

+@echo        SAVerify.bat "MSA_FILE"  - Verify SurfaceArea file named by MSA_FILE

+@echo        SAVerify.bat all         - Verify all SurfaceArea files under current directory and its sub-directories

+@echo        SAVerify.bat -h          - Print usage message

+@echo.

+goto end

+

+:all

+  @echo off

+  @for /R %%a in (*.msa *.mbd *.spd) do @ant -q -f %WORKSPACE%\Tools\Source\SurfaceArea\build.xml validate -DSURFACE_AREA_FILE=%%a

+  @echo on

+  @goto end

+

+:standalone

+  @ant -q -f %WORKSPACE%\Tools\Source\SurfaceArea\build.xml validate -DSURFACE_AREA_FILE=%~f1

+  @goto end

+

+:no_jdk

+  @echo.

+  @echo !!! Please set JAVA_HOME !!!

+  @echo.

+  @goto end

+

+:no_wks

+  @echo.

+  @echo !!! Please set WORKSPACE !!!

+  @echo.

+  @goto end

+

+:end

diff --git a/edk2/Tools/build.xml b/edk2/Tools/build.xml
new file mode 100644
index 0000000..2188431
--- /dev/null
+++ b/edk2/Tools/build.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="Tools" default="all" basedir=".">

+

+  <property environment="env"/>

+

+  <target name="JavaCode" depends="SurfaceArea">

+    <subant target="" verbose="true" inheritall="false">

+      <!-- Note: this is an ordered list. The projects have dependencies between them. -->

+      <filelist dir="."

+        files="

+          Source/GenBuild/build.xml

+          Source/FrameworkTasks/build.xml

+          Source/Cpptasks/build.xml

+          Source/ModuleEditor/build.xml

+          Source/PackageEditor/build.xml

+          "/>

+    </subant>

+  </target>

+

+  <target name="all" depends="C_Code"/>

+

+  <target name="SurfaceArea" depends="makeCatalog">

+    <subant target="" verbose="true" inheritall="false">

+      <filelist dir="."

+        files="

+          Source/SurfaceArea/build.xml

+          "/>

+    </subant>

+  </target>

+

+  <target name="C_Code" depends="JavaCode">

+    <subant target="" verbose="true" inheritall="false">

+      <filelist dir="."

+        files="

+          Source/TianoTools/build.xml

+          "/>

+    </subant>

+  </target>

+

+  <target name="makeCatalog">

+    <echo file="XMLSchema/catalog.xml">

+      <![CDATA[<?xml version="1.0"?>

+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.xsd">

+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">

+  <rewriteSystem systemIdStartString="http://www.TianoCore.org/2006/Edk2.0/"

+    rewritePrefix="file:/]]>${env.WORKSPACE}<![CDATA[/Tools/XMLSchema/"/>

+  <rewriteURI uriStartString="http://www.TianoCore.org/2006/Edk2.0/"

+    rewritePrefix="file:/]]>${env.WORKSPACE}<![CDATA[/Tools/XMLSchema/"/>

+</catalog>]]>

+    </echo>

+    <copy file="Conf/tools_def.template" tofile="Conf/tools_def.txt" overwrite="false"/>

+  </target>

+  <target name="clean">

+    <subant target="clean" inheritall="false">

+      <filelist dir="."

+        files="

+          Source/TianoTools/build.xml

+          Source/ModuleEditor/build.xml

+          Source/PackageEditor/build.xml

+          Source/FrameworkTasks/build.xml

+          Source/GenBuild/build.xml

+          Source/SurfaceArea/build.xml

+          Source/Cpptasks/build.xml

+          "/>

+    </subant>

+  </target>

+  <target name="cleanall">

+    <subant target="cleanall" verbose="true" inheritall="false">

+      <filelist dir="."

+        files="

+          Source/TianoTools/build.xml

+          Source/ModuleEditor/build.xml

+          Source/PackageEditor/build.xml

+          Source/FrameworkTasks/build.xml

+          Source/GenBuild/build.xml

+          Source/SurfaceArea/build.xml

+          Source/Cpptasks/build.xml

+          "/>

+    </subant>

+  </target>

+</project>

diff --git a/edk2/Tools/gcc/README.txt b/edk2/Tools/gcc/README.txt
new file mode 100644
index 0000000..9e581f2
--- /dev/null
+++ b/edk2/Tools/gcc/README.txt
@@ -0,0 +1,35 @@
+You may run these scripts to build a Tiano Cross compiler. They have been

+tested on Cygwin, OS X and Linux. You should expect to hack on these scripts to

+make them work on your system. You may need to install additional tools on your

+system to make the scripts work.

+

+You will need

+

+  A recent version (3.0 or later should be fine) of gcc that is able to produce

+    executables for the machine that you want to run this compiler on (the host

+    machine).

+  wget or curl

+  tar

+  bzip

+  gzip

+  bash

+  and possibly others

+

+CYGWIN Notes

+

+You should setup cygwin to use binmode on all mounts. When you initially

+install cygwin it gives you the choice of Unix file mode (recommended) or DOS

+file mode. Unix mode will cause all the cygwin directories to be mounted in

+binmode, while DOS will mount the dirs in textmode. Here is an example of a

+cygwin install where the dirs are (properly) mounted in binmode.

+

+C:\cygwin\bin on /usr/bin type user (binmode)

+C:\cygwin\lib on /usr/lib type user (binmode)

+c:\workspace on /workspace type system (binmode)

+C:\cygwin on / type user (binmode)

+

+If you use textmode, it is likely that the build will fail in a way that is

+hard to debug.

+

+Cygwin is pretty slow, so it is not recommended for large builds.

+

diff --git a/edk2/Tools/gcc/tianoCross-gcc-4.0 b/edk2/Tools/gcc/tianoCross-gcc-4.0
new file mode 100644
index 0000000..99fceb8
--- /dev/null
+++ b/edk2/Tools/gcc/tianoCross-gcc-4.0
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+#
+# Get, build and install the latest cross-development tools and libraries
+#
+
+#
+# Specify the architectures for which the tools are to be built
+# To build for single target: ARCHS="m68k"
+#
+ARCHS="${ARCHS:-i386}"
+
+# Let's be nice
+renice 10 -p $$
+
+# If any thing goes wrong, we'll bail out.
+set -ex
+
+#
+# Specify the versions
+#
+GCC=gcc-4.0.2
+BINUTILS=binutils-2.16.1
+CYGWIN_SNAP=20060120 # You may need to find a more recent one.
+export PATH=/bin:/usr/bin
+
+#
+# Where to install
+#
+PREFIX="${PREFIX:-/opt/tiano/}"
+
+#
+# Where to get the GNU tools
+#
+BINUTILS_URL=ftp://ftp.ibiblio.org/pub/mirrors/gnu/ftp/gnu/binutils/${BINUTILS}.tar.bz2
+GCC_URL=ftp://ftp.ibiblio.org/pub/mirrors/gnu/ftp/gnu/gcc/gcc-4.0.2/${GCC}.tar.bz2
+CYG_LOC=http://cygwin.com/snapshots/cygwin-src-${CYGWIN_SNAP}.tar.bz2
+export http_proxy=http://proxy.dp.intel.com:911
+export ftp_proxy=http://proxy.dp.intel.com:911
+
+#
+# Uncomment one of the following depending upon which your system provides
+#
+GET_COMMAND="curl --remote-name"
+#GET_COMMAND="wget -nc --no-directories --retr-symlinks "
+
+#
+# Allow environment to override some programs
+#
+MAKE="${MAKE:-make}"
+export MAKE
+SHELL="${SHELL:-/bin/sh}"
+export SHELL
+
+#
+# Get the source
+# If you don't have curl on your machine, try using
+#     wget --passive-ftp --no-directories --retr-symlinks <<url>>
+# If that doesn't work, try without the --passive-ftp option.
+#
+getSource() {
+    ${GET_COMMAND} "${BINUTILS_URL}" &
+    ${GET_COMMAND}  "${GCC_URL}" &
+    ${GET_COMMAND}  "${CYG_LOC}" &
+    wait
+}
+
+#
+# Unpack the source
+#
+unpackSource() {
+    (rm -rf "${BINUTILS}"
+    tar jxf "${BINUTILS}.tar.bz2"
+    ) &
+
+    (rm -rf "${GCC}"
+    tar jxf "${GCC}.tar.bz2"
+    ) &
+
+    (rm -rf cygwin-snapshot-${CYGWIN_SNAP}-1/
+    tar jxf cygwin-src-${CYGWIN_SNAP}.tar.bz2
+    ) &
+
+    wait
+
+    # (cd "${GCC}" ; ln -sf "../cygwin-snapshot-20060120-1/newlib" newlib)
+
+}
+
+CONF_SHELL="${CONF_SHELL:-/bin/bash}"
+# CONF_SHELL="${CONF_SHELL:-echo}"
+
+#
+# Build
+#
+build() {
+    for arch in $ARCHS
+    do (
+        export targ=${arch}-tiano-pe
+        export pref=${PREFIX}${targ}
+        export PATH="${pref}/bin:$PATH"
+
+        ( mkdir -p build-binutils-$targ
+        cd build-binutils-$targ
+        "${CONF_SHELL}" "../${BINUTILS}/configure" \
+            --disable-nls "--target=${targ}" "--prefix=${pref}"
+        ${MAKE} -j1 -w all
+        ${MAKE} -w install
+        ) >> ${targ}.log 2>&1
+
+        (
+            mkdir -p $pref/$targ/sys-include;
+            cp -fr cygwin-snapshot-${CYGWIN_SNAP}-1/newlib/libc/include/* $pref/$targ/sys-include
+            cp -fr cygwin-snapshot-${CYGWIN_SNAP}-1/winsup/cygwin/include/* $pref/$targ/sys-include
+        )
+
+        ( mkdir -p build-gcc-$targ
+        cd build-gcc-$targ
+        "${CONF_SHELL}" "../${GCC}/configure" "--target=${targ}" "--prefix=${pref}" \
+            --with-gnu-as --with-gnu-ld --with-newlib --verbose \
+            --disable-nls --enable-languages=c
+        ${MAKE} -j1 -w all
+        ${MAKE} -w install 
+        ) >> ${targ}.log 2>&1
+    ) &
+    done
+
+    wait
+}
+
+
+
+#
+# Do everything
+#
+# Comment out any activities you wish to omit
+#
+getSource
+unpackSource
+build
+
diff --git a/edk2/Tools/gcc/tianoCross-gcc-4.1 b/edk2/Tools/gcc/tianoCross-gcc-4.1
new file mode 100644
index 0000000..1a050e6
--- /dev/null
+++ b/edk2/Tools/gcc/tianoCross-gcc-4.1
@@ -0,0 +1,145 @@
+#!/bin/bash
+
+#
+# Get, build and install the latest cross-development tools and libraries
+#
+
+###
+### CYGWIN :: Make sure that cygwin is mouting its file systems in binmode.
+###
+
+#
+# Specify the architectures for which the tools are to be built
+# To build for single target: ARCHS="m68k"
+#
+ARCHS="${ARCHS:-i386}"
+
+# Let's be nice
+renice 10 -p $$
+
+# If any thing goes wrong, we'll bail out.
+set -e
+
+#
+# Specify the versions
+#
+GCC=gcc-4.1.0
+BINUTILS=binutils-2.16.1
+# BINUTILS=binutils-2.16.91-20060119-1
+CYGWIN_SNAP=20060403 # You may need to find a more recent one.
+export PATH=/bin:/usr/bin
+
+#
+# Where to install
+#
+PREFIX="${PREFIX:-/opt/tiano/}"
+
+#
+# Where to get the GNU tools
+#
+# BINUTILS_URL=http://superb.dl.sourceforge.net/sourceforge/mingw/${BINUTILS}-src.tar.gz
+BINUTILS_URL=ftp://ftp.ibiblio.org/pub/mirrors/gnu/ftp/gnu/binutils/${BINUTILS}.tar.bz2
+# GCC_URL=http://mirrors.ibiblio.org/pub/mirrors/gnu/ftp/gnu/gcc/gcc-${GCC}/${GCC}.tar.bz2
+GCC_URL=ftp://mirrors.kernel.org/gnu/gcc/$GCC/$GCC.tar.bz2
+CYG_LOC=http://cygwin.com/snapshots/cygwin-src-${CYGWIN_SNAP}.tar.bz2
+# export http_proxy=http://proxy.dp.intel.com:911
+# export ftp_proxy=http://proxy.dp.intel.com:911
+
+#
+# Uncomment one of the following depending upon which your system provides
+#
+#GET_COMMAND="curl --remote-name"
+GET_COMMAND="wget -nc --no-directories --retr-symlinks "
+
+#
+# Allow environment to override some programs
+#
+MAKE="${MAKE:-make}"
+export MAKE
+SHELL="${SHELL:-/bin/sh}"
+export SHELL
+
+#
+# Get the source
+# If you don't have curl on your machine, try using
+#     wget --passive-ftp --no-directories --retr-symlinks <<url>>
+# If that doesn't work, try without the --passive-ftp option.
+#
+getSource() {
+    ${GET_COMMAND} "${BINUTILS_URL}" &
+    ${GET_COMMAND}  "${GCC_URL}" &
+    ${GET_COMMAND}  "${CYG_LOC}" &
+    wait
+}
+
+#
+# Unpack the source
+#
+unpackSource() {
+    (rm -rf "${BINUTILS}"
+    tar jxf "${BINUTILS}.tar.bz2"
+    ) &
+
+    (rm -rf "${GCC}"
+    tar jxf "${GCC}.tar.bz2"
+    ) &
+
+    (rm -rf cygwin-snapshot-${CYGWIN_SNAP}-1/
+    tar jxf cygwin-src-${CYGWIN_SNAP}.tar.bz2
+    ) &
+
+    wait
+}
+
+CONF_SHELL="${CONF_SHELL:-/bin/bash}"
+# CONF_SHELL="${CONF_SHELL:-echo}"
+
+#
+# Build
+#
+build() {
+    for arch in $ARCHS
+    do (
+        export targ=${arch}-tiano-pe
+        export pref=${PREFIX}${targ}
+        export PATH="${pref}/bin:$PATH"
+
+        ( mkdir -p build-binutils-$targ
+        cd build-binutils-$targ
+        "${CONF_SHELL}" "../${BINUTILS}/configure" \
+            --disable-nls "--target=${targ}" "--prefix=${pref}"
+        ${MAKE} -j1 -w all
+        ${MAKE} -w install
+        ) >> ${targ}.log 2>&1 &&
+
+        (
+            mkdir -p $pref/$targ/sys-include;
+            cp -fr cygwin-snapshot-${CYGWIN_SNAP}-1/newlib/libc/include/* $pref/$targ/sys-include
+            cp -fr cygwin-snapshot-${CYGWIN_SNAP}-1/winsup/cygwin/include/* $pref/$targ/sys-include
+        ) &&
+
+        ( mkdir -p build-gcc-$targ
+        cd build-gcc-$targ
+        "${CONF_SHELL}" "../${GCC}/configure" "--target=${targ}" "--prefix=${pref}" \
+            --with-gnu-as --with-gnu-ld --with-newlib --verbose \
+            --disable-libssp \
+            --disable-nls --enable-languages=c
+        ${MAKE} -j1 -w all
+        ${MAKE} -w install 
+        ) >> ${targ}.log 2>&1
+    ) &
+    done
+
+    wait
+}
+
+
+
+#
+# Do everything
+#
+# Comment out any activities you wish to omit
+#
+getSource
+unpackSource
+build
diff --git a/edk2/build.xml b/edk2/build.xml
new file mode 100644
index 0000000..f4724fe
--- /dev/null
+++ b/edk2/build.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>

+<!--

+Copyright (c) 2006, Intel Corporation

+All rights reserved. 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.

+-->

+<project name="mdk" default="all" basedir=".">

+  <description>

+This is the highest-level build file.

+It can build all packages or clean up the build products.

+  </description>

+  <property environment="env"/>

+  <!-- Note: this is an ordered list. The projects have dependencies between them. -->

+  <filelist

+      id="Pkg.Dirs"

+      dir="."

+      files="Tools,MdePkg,EdkModulePkg,EdkNt32Pkg"/>

+

+  <target name="all" description="Issue a warning.">

+    <echo>

+Top-level builds may not be functional.

+Please build each package individually from its own directory.

+If you would like to try anyway, type

+ant All

+    </echo>

+  </target>

+  <target name="All" description="Build all packages.">

+    <subant target="" inheritall="false">

+      <filelist refid="Pkg.Dirs"/>

+    </subant>

+  </target>

+

+  <target name="clean" description="Remove compile and assembly artifacts.">

+    <subant target="clean" inheritall="false">

+      <filelist refid="Pkg.Dirs"/>

+    </subant>

+  </target>

+

+  <target name="cleanall" description="Remove everything not in the distribution.">

+    <subant target="cleanall" inheritall="false">

+      <filelist refid="Pkg.Dirs"/>

+    </subant>

+  </target>

+</project>

diff --git a/edk2/edksetup.bat b/edk2/edksetup.bat
new file mode 100644
index 0000000..99a33bc
--- /dev/null
+++ b/edk2/edksetup.bat
@@ -0,0 +1,150 @@
+@REM

+@REM Copyright (c) 2006, Intel Corporation

+@REM All rights reserved. This program and the accompanying materials

+@REM are licensed and made available under the terms and conditions of the BSD License

+@REM which accompanies this distribution.  The full text of the license may be found at

+@REM http://opensource.org/licenses/bsd-license.php

+@REM

+@REM THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+@REM WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+@REM

+

+@REM set following environment in this file or in command shell

+@REM set JAVA_HOME=C:\Java\jdk1.5.0_04

+@REM set ANT_HOME=C:\ANT

+@REM set XMLBEANS_HOME=C:\xmlbeans

+@REM set CYGWIN_HOME=C:\cygwin

+

+

+@REM ##############################################################

+@REM # You should not have to modify anything below this line

+@REM #

+

+@echo off

+

+@REM

+@REM Check the required system environment variables

+@REM

+

+:check_vc

+if defined VCINSTALLDIR goto check_cygwin

+if defined VS71COMNTOOLS (

+  call "%VS71COMNTOOLS%vsvars32.bat"

+) else (

+  echo.

+  echo !!! WARNING !!!! Cannot find Visual Studio !!!

+  echo.

+)

+

+:check_cygwin

+if defined CYGWIN_HOME goto check_java

+if exist c:\cygwin (

+  set CYGWIN_HOME=c:\cygwin

+) else (

+  echo.

+  echo !!! WARNING !!!! Not set CYGWIN_HOME, gcc build may not be used !!!

+  echo.

+)

+

+:check_java

+if "%JAVA_HOME%"=="" goto no_jdk

+

+:check_ant

+if "%ANT_HOME%"=="" goto no_ant

+if not exist %ANT_HOME%\lib\ant-contrib.jar goto no_antcontrib

+

+:check_xmlbeans

+if "%XMLBEANS_HOME%"=="" goto no_xmlbeans

+if not exist %XMLBEANS_HOME%\lib\saxon8.jar goto no_saxon8

+

+@REM

+@REM Set the WORKSPACE to the current working directory

+@REM

+set WORKSPACE=%CD%

+

+set Framework_Tools_Path=%WORKSPACE%\Tools\bin

+set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin;%XMLBEANS_HOME%\bin;%Framework_Tools_Path%;%PATH%

+

+echo.

+echo JAVA_HOME:     %JAVA_HOME%

+echo ANT_HOME:      %ANT_HOME%

+echo XMLBEANS_HOME: %XMLBEANS_HOME%

+echo CYGWIN_HOME:   %CYGWIN_HOME%

+echo WORKSPACE:     %WORKSPACE%

+echo PATH:          %PATH%

+echo.

+

+@REM

+@REM Start to build the Framework Tools

+@REM

+

+echo.

+echo Building the Framework Tools

+echo.

+

+@REM

+@REM We are going to create the SurfaceArea.jar file first so that the other

+@REM Java Programs can use it.

+@REM It needs the XMLBEANS libraries in order to compile.

+@REM

+set CLASSPATH=%XMLBEANS_HOME%\lib\jsr173_1.0_api.jar;%XMLBEANS_HOME%\lib\xbean.jar

+set CLASSPATH=%CLASSPATH%;%XMLBEANS_HOME%\lib\xbean_xpath.jar;%XMLBEANS_HOME%\lib\xmlpublic.jar

+set CLASSPATH=%CLASSPATH%;%XMLBEANS_HOME%\lib\saxon8.jar;%XMLBEANS_HOME%\lib\resolver.jar

+

+call ant -f %WORKSPACE%\Tools\build.xml SurfaceArea

+

+@REM

+@REM Now we can make the other Java Programs

+@REM All of the remaining Java Programs require the SurfaceArea library to compile

+@REM

+set CLASSPATH=%CLASSPATH%;%WORKSPACE\%Tools\Jars\SurfaceArea.jar

+

+call ant -f %WORKSPACE%\Tools\build.xml JavaCode

+

+@REM

+@REM We have all of the Java Programs and add-in classes created, so we can start

+@REM using the cpp-tasks to create our tools

+@REM

+set CLASSPATH=%CLASSPATH%;%WORKSPACE%\Tools\Jars\SurfaceArea.jar;%WORKSPACE%\Tools\Jars\GenBuild.jar

+set CLASSPATH=%CLASSPATH%;%WORKSPACE%\Tools\Jars\cpptasks.jar;%WORKSPACE%\Tools\Jars\frameworktasks.jar

+

+call ant -f %WORKSPACE%\Tools\build.xml C_Code

+

+@REM

+@REM Done!!!

+@REM

+goto end

+

+:no_jdk

+echo.

+echo !!! Please install Java, and set JAVA_HOME !!!

+echo.

+goto end

+

+:no_ant

+echo.

+echo !!! Please install Apache Ant, and set ANT_HOME !!!

+echo.

+goto end

+

+:no_antcontrib

+echo.

+echo !!! Please install Ant-contrib to ANT_HOME !!!

+echo.

+goto end

+

+:no_xmlbeans

+echo.

+echo !!! Please install XML Beans, and set XMLBEANS_HOME !!!

+echo.

+goto end

+

+:no_saxon8

+echo.

+echo !!! Please copy saxon8.jar file to XMLBEANS_HOME\lib !!!

+echo.

+goto end

+

+:end

+@echo on

+

diff --git a/edk2/edksetup.sh b/edk2/edksetup.sh
new file mode 100644
index 0000000..b191635
--- /dev/null
+++ b/edk2/edksetup.sh
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2006, Intel Corporation
+# All rights reserved. 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.
+
+# Setup the environment for unix-like systems running a bash-like shell.
+# This file must be "sourced" not executed. For example: ". edksetup.sh"
+
+if [ "$WORKSPACE" == "" ]
+then
+  echo "Please set WORKSPACE before sourcing this script."
+else
+if [ "$JAVA_HOME" == "" ]
+then
+  echo "Please set JAVA_HOME before sourcing this script."
+else
+if [ "$ANT_HOME" == "" ]
+then
+  echo "Please set ANT_HOME before sourcing this script."
+else
+
+# These should be ok as they are.
+export CLASSPATH=$WORKSPACE/Tools/Jars/SurfaceArea.jar:$WORKSPACE/Tools/Jars/frameworktasks.jar:$WORKSPACE/Tools/Jars/saxon8.jar:$WORKSPACE/Tools/Jars/cpptasks.jar:$WORKSPACE/Tools/Jars/GenBuild.jar:$XMLBEANS_HOME/lib/resolver.jar:$XMLBEANS_HOME/lib/xbean.jar:$XMLBEANS_HOME/lib/xmlpublic.jar:$XMLBEANS_HOME/lib/jsr173_1.0_api.jar:$XMLBEANS_HOME/lib/saxon8.jar:$XMLBEANS_HOME/lib/xbean_xpath.jar
+export Framework_Tools_Path=$WORKSPACE/Tools/bin
+export PATH=$Framework_Tools_Path:$ANT_HOME/bin:$JAVA_HOME/bin:$PATH
+
+# Handle any particulars down here.
+case "`uname`" in
+  CYGWIN*) 
+    # Convert paths to windows format.
+    export WORKSPACE=`cygpath -w $WORKSPACE`
+    export CLASSPATH=`cygpath -w -p $CLASSPATH`
+    ;;
+esac
+
+# Now we need to build the tools.
+echo "If you have not done so, please build the tools by issuing 'ant -f \$WORKSPACE/Tools/build.xml'."
+fi
+fi
+fi